From 2f63e90b8bfbbe2e4711325557bc14f97d51b666 Mon Sep 17 00:00:00 2001 From: byu343 Date: Mon, 23 Sep 2019 18:07:20 -0700 Subject: [PATCH 0001/1427] [device/arista] Add hwSku Arista-7280CR3-C40 for 7280 (#3477) * Add hwSku Arista-7280CR3-C40 * Clean empty lines * Fix violation to config_checker * Fix no new line at end --- .../jr2-a7280cr3-32p4-40x100G.config.bcm | 755 ++++++++++++++++++ .../Arista-7280CR3-C40/port_config.ini | 41 + .../Arista-7280CR3-C40/sai.profile | 1 + src/sonic-device-data/tests/config_checker | 8 + src/sonic-device-data/tests/permitted_list | 42 + 5 files changed, 847 insertions(+) create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/port_config.ini create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm new file mode 100644 index 000000000000..4787dc7db709 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm @@ -0,0 +1,755 @@ +soc_family.BCM8869X=BCM8869X + +custom_feature_ucode_path=u_code_db2pem.txt +system_headers_mode=1 +suppress_unknown_prop_warnings=1 +l4_protocols_load_balancing_enable=1 +fabric_logical_port_base=512 +trunk_group_max_members=128 +num_olp_tm_ports.BCM8869X=1 + +ucode_port_0.BCM8869X=CPU.0:core_0.0 +ucode_port_200.BCM8869X=CPU.8:core_1.200 +ucode_port_201.BCM8869X=CPU.16:core_0.201 +ucode_port_202.BCM8869X=CPU.24:core_1.202 +ucode_port_203.BCM8869X=CPU.32:core_0.203 + +port_init_speed_xe.BCM8869X=10000 +port_init_speed_xl.BCM8869X=40000 +port_init_speed_le.BCM8869X=50000 +port_init_speed_ce.BCM8869X=100000 +port_init_speed_cc.BCM8869X=200000 +port_init_speed_cd.BCM8869X=400000 +port_init_speed_il.BCM8869X=10312 + +port_init_cl72=0 + +serdes_tx_taps_1=pam4:-16:64:0:3:0:0 +serdes_tx_taps_2=pam4:-16:64:0:3:0:0 +serdes_tx_taps_3=pam4:-16:64:0:3:0:0 +serdes_tx_taps_4=pam4:-16:64:0:3:0:0 +serdes_tx_taps_5=pam4:-16:64:0:3:0:0 +serdes_tx_taps_6=pam4:-16:64:0:3:0:0 +serdes_tx_taps_7=pam4:-16:64:0:3:0:0 +serdes_tx_taps_8=pam4:-16:64:0:3:0:0 +serdes_tx_taps_9=pam4:-8:60:0:0:0:0 +serdes_tx_taps_10=pam4:-8:60:0:0:0:0 +serdes_tx_taps_11=pam4:-8:60:0:0:0:0 +serdes_tx_taps_12=pam4:-8:60:0:0:0:0 +serdes_tx_taps_13=pam4:-8:60:0:0:0:0 +serdes_tx_taps_14=pam4:-8:60:0:0:0:0 +serdes_tx_taps_15=pam4:-8:60:0:0:0:0 +serdes_tx_taps_16=pam4:-8:60:0:0:0:0 +serdes_tx_taps_17=pam4:-8:60:0:0:0:0 +serdes_tx_taps_18=pam4:-8:60:0:0:0:0 +serdes_tx_taps_19=pam4:-8:60:0:0:0:0 +serdes_tx_taps_20=pam4:-8:60:0:0:0:0 +serdes_tx_taps_21=pam4:-8:60:0:0:0:0 +serdes_tx_taps_22=pam4:-8:60:0:0:0:0 +serdes_tx_taps_23=pam4:-8:60:0:0:0:0 +serdes_tx_taps_24=pam4:-8:60:0:0:0:0 +serdes_tx_taps_25=pam4:-8:60:0:0:0:0 +serdes_tx_taps_26=pam4:-8:60:0:0:0:0 +serdes_tx_taps_27=pam4:-8:60:0:0:0:0 +serdes_tx_taps_28=pam4:-8:60:0:0:0:0 +serdes_tx_taps_29=pam4:-16:60:0:3:0:0 +serdes_tx_taps_30=pam4:-16:60:0:3:0:0 +serdes_tx_taps_31=pam4:-16:60:0:3:0:0 +serdes_tx_taps_32=pam4:-16:60:0:3:0:0 +serdes_tx_taps_33=nrz:0:71:-16:-5:0:0 +serdes_tx_taps_34=nrz:0:71:-16:-5:0:0 +serdes_tx_taps_35=nrz:0:78:-22:-4:0:0 +serdes_tx_taps_36=nrz:0:78:-22:-4:0:0 +serdes_tx_taps_37=nrz:0:72:-18:-5:0:0 +serdes_tx_taps_38=nrz:0:72:-18:-5:0:0 +serdes_tx_taps_39=nrz:0:68:-17:-6:0:0 +serdes_tx_taps_40=nrz:0:68:-17:-6:0:0 + +ucode_port_100.BCM8869X=RCY_MIRROR.0:core_0.100 +ucode_port_101.BCM8869X=RCY_MIRROR.1:core_0.101 +ucode_port_102.BCM8869X=RCY_MIRROR.2:core_0.102 +ucode_port_103.BCM8869X=RCY_MIRROR.3:core_0.103 +ucode_port_104.BCM8869X=RCY_MIRROR.4:core_0.104 +ucode_port_105.BCM8869X=RCY_MIRROR.5:core_0.105 +ucode_port_106.BCM8869X=RCY_MIRROR.6:core_0.106 +ucode_port_107.BCM8869X=RCY_MIRROR.7:core_0.107 +ucode_port_108.BCM8869X=RCY_MIRROR.8:core_0.108 +ucode_port_109.BCM8869X=RCY_MIRROR.9:core_0.109 +ucode_port_110.BCM8869X=RCY_MIRROR.10:core_0.110 +ucode_port_111.BCM8869X=RCY_MIRROR.11:core_0.111 +ucode_port_112.BCM8869X=RCY_MIRROR.12:core_0.112 +ucode_port_113.BCM8869X=RCY_MIRROR.13:core_0.113 +ucode_port_114.BCM8869X=RCY_MIRROR.14:core_0.114 +ucode_port_115.BCM8869X=RCY_MIRROR.15:core_0.115 +ucode_port_116.BCM8869X=RCY_MIRROR.16:core_0.116 +ucode_port_117.BCM8869X=RCY_MIRROR.17:core_0.117 +ucode_port_118.BCM8869X=RCY_MIRROR.18:core_0.118 +ucode_port_119.BCM8869X=RCY_MIRROR.19:core_0.119 +ucode_port_120.BCM8869X=RCY_MIRROR.0:core_1.120 +ucode_port_121.BCM8869X=RCY_MIRROR.1:core_1.121 +ucode_port_122.BCM8869X=RCY_MIRROR.2:core_1.122 +ucode_port_123.BCM8869X=RCY_MIRROR.3:core_1.123 +ucode_port_124.BCM8869X=RCY_MIRROR.4:core_1.124 +ucode_port_125.BCM8869X=RCY_MIRROR.5:core_1.125 +ucode_port_126.BCM8869X=RCY_MIRROR.6:core_1.126 +ucode_port_127.BCM8869X=RCY_MIRROR.7:core_1.127 +ucode_port_128.BCM8869X=RCY_MIRROR.8:core_1.128 +ucode_port_129.BCM8869X=RCY_MIRROR.9:core_1.129 +ucode_port_130.BCM8869X=RCY_MIRROR.10:core_1.130 +ucode_port_131.BCM8869X=RCY_MIRROR.11:core_1.131 +ucode_port_132.BCM8869X=RCY_MIRROR.12:core_1.132 +ucode_port_133.BCM8869X=RCY_MIRROR.13:core_1.133 +ucode_port_134.BCM8869X=RCY_MIRROR.14:core_1.134 +ucode_port_135.BCM8869X=RCY_MIRROR.15:core_1.135 +ucode_port_136.BCM8869X=RCY_MIRROR.16:core_1.136 +ucode_port_137.BCM8869X=RCY_MIRROR.17:core_1.137 +ucode_port_138.BCM8869X=RCY_MIRROR.18:core_1.138 +ucode_port_139.BCM8869X=RCY_MIRROR.19:core_1.139 + +port_priorities.BCM8869X=8 + +ucode_port_240.BCM8869X=OLP:core_0.240 + +sw_state_max_size.BCM8869X=750000000 + +stable_location.BCM8869X=4 +stable_location.BCM8869X_ADAPTER=3 + +stable_filename.BCM8869X_ADAPTER=warmboot_data_0 +stable_filename=/dev/shm/warmboot_data_0 +stable_filename.1=/dev/shm/warmboot_data_1 +stable_filename.2=/dev/shm/warmboot_data_2 + +stable_size.BCM8869X=800000000 + +tm_port_header_type_in_0.BCM8869X=INJECTED_2 +tm_port_header_type_out_0.BCM8869X=CPU + +tm_port_header_type_in_200.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_200.BCM8869X=ETH +tm_port_header_type_in_201.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_201.BCM8869X=ETH +tm_port_header_type_in_202.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_202.BCM8869X=ETH +tm_port_header_type_in_203.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_203.BCM8869X=ETH + +sat_enable.BCM8869X=1 +tm_port_header_type_out_218.BCM8869X=CPU +tm_port_header_type_in_218.BCM8869X=INJECTED_2 + +tm_port_header_type_in_232.BCM8869X=INJECTED_2 +tm_port_header_type_out_232.BCM8869X=CPU +tm_port_header_type_in_233.BCM8869X=INJECTED_2 +tm_port_header_type_out_233.BCM8869X=CPU + +tm_port_header_type_in_240.BCM8869X=INJECTED_2 +tm_port_header_type_out_240.BCM8869X=RAW + +dtm_flow_mapping_mode_region_64.BCM8869X=3 +dtm_flow_mapping_mode_region_65.BCM8869X=3 +dtm_flow_mapping_mode_region_66.BCM8869X=3 +dtm_flow_mapping_mode_region_67.BCM8869X=3 +dtm_flow_mapping_mode_region_68.BCM8869X=3 +dtm_flow_mapping_mode_region_69.BCM8869X=3 +dtm_flow_mapping_mode_region_70.BCM8869X=3 +dtm_flow_mapping_mode_region_71.BCM8869X=3 +dtm_flow_mapping_mode_region_72.BCM8869X=3 +dtm_flow_mapping_mode_region_73.BCM8869X=3 +dtm_flow_mapping_mode_region_74.BCM8869X=3 +dtm_flow_mapping_mode_region_75.BCM8869X=3 +dtm_flow_mapping_mode_region_76.BCM8869X=3 +dtm_flow_mapping_mode_region_77.BCM8869X=3 +dtm_flow_mapping_mode_region_78.BCM8869X=3 +dtm_flow_mapping_mode_region_79.BCM8869X=7 +dtm_flow_mapping_mode_region_80.BCM8869X=3 +dtm_flow_mapping_mode_region_81.BCM8869X=1 +dtm_flow_mapping_mode_region_82.BCM8869X=3 +dtm_flow_mapping_mode_region_83.BCM8869X=3 +dtm_flow_mapping_mode_region_84.BCM8869X=3 +dtm_flow_mapping_mode_region_85.BCM8869X=3 +dtm_flow_mapping_mode_region_86.BCM8869X=3 +dtm_flow_mapping_mode_region_87.BCM8869X=3 +dtm_flow_mapping_mode_region_88.BCM8869X=3 +dtm_flow_mapping_mode_region_89.BCM8869X=3 +dtm_flow_mapping_mode_region_90.BCM8869X=3 +dtm_flow_mapping_mode_region_91.BCM8869X=3 +dtm_flow_mapping_mode_region_92.BCM8869X=3 +dtm_flow_mapping_mode_region_93.BCM8869X=3 +dtm_flow_mapping_mode_region_94.BCM8869X=3 + +dtm_flow_nof_remote_cores_region_1.BCM8869X=2 +dtm_flow_nof_remote_cores_region_2.BCM8869X=2 +dtm_flow_nof_remote_cores_region_3.BCM8869X=2 +dtm_flow_nof_remote_cores_region_4.BCM8869X=2 +dtm_flow_nof_remote_cores_region_5.BCM8869X=2 +dtm_flow_nof_remote_cores_region_6.BCM8869X=2 +dtm_flow_nof_remote_cores_region_7.BCM8869X=2 +dtm_flow_nof_remote_cores_region_8.BCM8869X=2 +dtm_flow_nof_remote_cores_region_9.BCM8869X=2 +dtm_flow_nof_remote_cores_region_10.BCM8869X=2 +dtm_flow_nof_remote_cores_region_11.BCM8869X=2 +dtm_flow_nof_remote_cores_region_12.BCM8869X=2 +dtm_flow_nof_remote_cores_region_13.BCM8869X=2 +dtm_flow_nof_remote_cores_region_14.BCM8869X=2 +dtm_flow_nof_remote_cores_region_15.BCM8869X=2 +dtm_flow_nof_remote_cores_region_16.BCM8869X=2 +dtm_flow_nof_remote_cores_region_17.BCM8869X=2 +dtm_flow_nof_remote_cores_region_18.BCM8869X=2 +dtm_flow_nof_remote_cores_region_19.BCM8869X=2 +dtm_flow_nof_remote_cores_region_20.BCM8869X=2 +dtm_flow_nof_remote_cores_region_21.BCM8869X=2 +dtm_flow_nof_remote_cores_region_22.BCM8869X=2 +dtm_flow_nof_remote_cores_region_23.BCM8869X=2 +dtm_flow_nof_remote_cores_region_24.BCM8869X=2 +dtm_flow_nof_remote_cores_region_25.BCM8869X=2 +dtm_flow_nof_remote_cores_region_26.BCM8869X=2 +dtm_flow_nof_remote_cores_region_27.BCM8869X=2 +dtm_flow_nof_remote_cores_region_28.BCM8869X=2 +dtm_flow_nof_remote_cores_region_29.BCM8869X=2 +dtm_flow_nof_remote_cores_region_30.BCM8869X=2 +dtm_flow_nof_remote_cores_region_31.BCM8869X=2 +dtm_flow_nof_remote_cores_region_32.BCM8869X=2 +dtm_flow_nof_remote_cores_region_33.BCM8869X=2 +dtm_flow_nof_remote_cores_region_34.BCM8869X=2 +dtm_flow_nof_remote_cores_region_35.BCM8869X=2 +dtm_flow_nof_remote_cores_region_36.BCM8869X=2 +dtm_flow_nof_remote_cores_region_37.BCM8869X=2 +dtm_flow_nof_remote_cores_region_38.BCM8869X=2 +dtm_flow_nof_remote_cores_region_39.BCM8869X=2 +dtm_flow_nof_remote_cores_region_40.BCM8869X=2 +dtm_flow_nof_remote_cores_region_41.BCM8869X=2 +dtm_flow_nof_remote_cores_region_42.BCM8869X=2 +dtm_flow_nof_remote_cores_region_43.BCM8869X=2 +dtm_flow_nof_remote_cores_region_44.BCM8869X=2 +dtm_flow_nof_remote_cores_region_45.BCM8869X=2 +dtm_flow_nof_remote_cores_region_46.BCM8869X=2 +dtm_flow_nof_remote_cores_region_47.BCM8869X=2 +dtm_flow_nof_remote_cores_region_48.BCM8869X=2 +dtm_flow_nof_remote_cores_region_49.BCM8869X=2 +dtm_flow_nof_remote_cores_region_50.BCM8869X=2 +dtm_flow_nof_remote_cores_region_51.BCM8869X=2 +dtm_flow_nof_remote_cores_region_52.BCM8869X=2 +dtm_flow_nof_remote_cores_region_53.BCM8869X=2 +dtm_flow_nof_remote_cores_region_54.BCM8869X=2 +dtm_flow_nof_remote_cores_region_55.BCM8869X=2 +dtm_flow_nof_remote_cores_region_56.BCM8869X=2 +dtm_flow_nof_remote_cores_region_57.BCM8869X=2 +dtm_flow_nof_remote_cores_region_58.BCM8869X=2 +dtm_flow_nof_remote_cores_region_59.BCM8869X=2 +dtm_flow_nof_remote_cores_region_60.BCM8869X=2 + +mdb_profile.BCM8869X=l3-xl + +outlif_logical_to_physical_phase_map_1=S1 +outlif_logical_to_physical_phase_map_2=L1 +outlif_logical_to_physical_phase_map_3=XL +outlif_logical_to_physical_phase_map_4=L2 +outlif_logical_to_physical_phase_map_5=M1 +outlif_logical_to_physical_phase_map_6=M2 +outlif_logical_to_physical_phase_map_7=M3 +outlif_logical_to_physical_phase_map_8=S2 + +outlif_physical_phase_data_granularity_S1=60 +outlif_physical_phase_data_granularity_S2=60 +outlif_physical_phase_data_granularity_M1=60 +outlif_physical_phase_data_granularity_M2=60 +outlif_physical_phase_data_granularity_M3=60 +outlif_physical_phase_data_granularity_L1=60 +outlif_physical_phase_data_granularity_L2=60 +outlif_physical_phase_data_granularity_XL=60 + +port_init_speed_fabric.BCM8869X=53125 + +fabric_connect_mode.BCM8869X=SINGLE_FAP +protocol_traps_mode.BCM8869X=IN_LIF + +schan_intr_enable.BCM8869X=0 +tdma_intr_enable.BCM8869X=0 +tslam_intr_enable.BCM8869X=0 +miim_intr_enable.BCM8869X=0 +schan_timeout_usec.BCM8869X=300000 +tdma_timeout_usec.BCM8869X=1000000 +tslam_timeout_usec.BCM8869X=1000000 + +appl_enable_intr_init.BCM8869X=1 +polled_irq_mode.BCM8869X=1 +polled_irq_delay.BCM8869X=1000 + +bcm_stat_interval.BCM8869X=1000 + +mem_cache_enable_ecc.BCM8869X=1 +mem_cache_enable_parity.BCM8869X=1 + +serdes_nif_clk_freq_in.BCM8869X=2 +serdes_nif_clk_freq_out.BCM8869X=1 + +serdes_fabric_clk_freq_in.BCM8869X=2 +serdes_fabric_clk_freq_out.BCM8869X=1 + +dram_phy_tune_mode_on_init.BCM8869X=RUN_TUNE + +dport_map_direct.BCM8869X=1 + +pmf_sexem3_stage.BCM8869X=IPMF3 + +lane_to_serdes_map_fabric_lane0.0=rx0:tx0 +lane_to_serdes_map_fabric_lane1.0=rx1:tx1 +lane_to_serdes_map_fabric_lane2.0=rx2:tx2 +lane_to_serdes_map_fabric_lane3.0=rx3:tx3 +lane_to_serdes_map_fabric_lane4.0=rx4:tx4 +lane_to_serdes_map_fabric_lane5.0=rx5:tx5 +lane_to_serdes_map_fabric_lane6.0=rx6:tx6 +lane_to_serdes_map_fabric_lane7.0=rx7:tx7 +lane_to_serdes_map_fabric_lane8.0=rx8:tx8 +lane_to_serdes_map_fabric_lane9.0=rx9:tx9 +lane_to_serdes_map_fabric_lane10.0=rx10:tx10 +lane_to_serdes_map_fabric_lane11.0=rx11:tx11 +lane_to_serdes_map_fabric_lane12.0=rx12:tx12 +lane_to_serdes_map_fabric_lane13.0=rx13:tx13 +lane_to_serdes_map_fabric_lane14.0=rx14:tx14 +lane_to_serdes_map_fabric_lane15.0=rx15:tx15 +lane_to_serdes_map_fabric_lane16.0=rx16:tx16 +lane_to_serdes_map_fabric_lane17.0=rx17:tx17 +lane_to_serdes_map_fabric_lane18.0=rx18:tx18 +lane_to_serdes_map_fabric_lane19.0=rx19:tx19 +lane_to_serdes_map_fabric_lane20.0=rx20:tx20 +lane_to_serdes_map_fabric_lane21.0=rx21:tx21 +lane_to_serdes_map_fabric_lane22.0=rx22:tx22 +lane_to_serdes_map_fabric_lane23.0=rx23:tx23 +lane_to_serdes_map_fabric_lane24.0=rx24:tx24 +lane_to_serdes_map_fabric_lane25.0=rx25:tx25 +lane_to_serdes_map_fabric_lane26.0=rx26:tx26 +lane_to_serdes_map_fabric_lane27.0=rx27:tx27 +lane_to_serdes_map_fabric_lane28.0=rx28:tx28 +lane_to_serdes_map_fabric_lane29.0=rx29:tx29 +lane_to_serdes_map_fabric_lane30.0=rx30:tx30 +lane_to_serdes_map_fabric_lane31.0=rx31:tx31 +lane_to_serdes_map_fabric_lane32.0=rx32:tx32 +lane_to_serdes_map_fabric_lane33.0=rx33:tx33 +lane_to_serdes_map_fabric_lane34.0=rx34:tx34 +lane_to_serdes_map_fabric_lane35.0=rx35:tx35 +lane_to_serdes_map_fabric_lane36.0=rx36:tx36 +lane_to_serdes_map_fabric_lane37.0=rx37:tx37 +lane_to_serdes_map_fabric_lane38.0=rx38:tx38 +lane_to_serdes_map_fabric_lane39.0=rx39:tx39 +lane_to_serdes_map_fabric_lane40.0=rx40:tx40 +lane_to_serdes_map_fabric_lane41.0=rx41:tx41 +lane_to_serdes_map_fabric_lane42.0=rx42:tx42 +lane_to_serdes_map_fabric_lane43.0=rx43:tx43 +lane_to_serdes_map_fabric_lane44.0=rx44:tx44 +lane_to_serdes_map_fabric_lane45.0=rx45:tx45 +lane_to_serdes_map_fabric_lane46.0=rx46:tx46 +lane_to_serdes_map_fabric_lane47.0=rx47:tx47 +lane_to_serdes_map_fabric_lane48.0=rx48:tx48 +lane_to_serdes_map_fabric_lane49.0=rx49:tx49 +lane_to_serdes_map_fabric_lane50.0=rx50:tx50 +lane_to_serdes_map_fabric_lane51.0=rx51:tx51 +lane_to_serdes_map_fabric_lane52.0=rx52:tx52 +lane_to_serdes_map_fabric_lane53.0=rx53:tx53 +lane_to_serdes_map_fabric_lane54.0=rx54:tx54 +lane_to_serdes_map_fabric_lane55.0=rx55:tx55 +lane_to_serdes_map_fabric_lane56.0=rx56:tx56 +lane_to_serdes_map_fabric_lane57.0=rx57:tx57 +lane_to_serdes_map_fabric_lane58.0=rx58:tx58 +lane_to_serdes_map_fabric_lane59.0=rx59:tx59 +lane_to_serdes_map_fabric_lane60.0=rx60:tx60 +lane_to_serdes_map_fabric_lane61.0=rx61:tx61 +lane_to_serdes_map_fabric_lane62.0=rx62:tx62 +lane_to_serdes_map_fabric_lane63.0=rx63:tx63 +lane_to_serdes_map_fabric_lane64.0=rx64:tx64 +lane_to_serdes_map_fabric_lane65.0=rx65:tx65 +lane_to_serdes_map_fabric_lane66.0=rx66:tx66 +lane_to_serdes_map_fabric_lane67.0=rx67:tx67 +lane_to_serdes_map_fabric_lane68.0=rx68:tx68 +lane_to_serdes_map_fabric_lane69.0=rx69:tx69 +lane_to_serdes_map_fabric_lane70.0=rx70:tx70 +lane_to_serdes_map_fabric_lane71.0=rx71:tx71 +lane_to_serdes_map_fabric_lane72.0=rx72:tx72 +lane_to_serdes_map_fabric_lane73.0=rx73:tx73 +lane_to_serdes_map_fabric_lane74.0=rx74:tx74 +lane_to_serdes_map_fabric_lane75.0=rx75:tx75 +lane_to_serdes_map_fabric_lane76.0=rx76:tx76 +lane_to_serdes_map_fabric_lane77.0=rx77:tx77 +lane_to_serdes_map_fabric_lane78.0=rx78:tx78 +lane_to_serdes_map_fabric_lane79.0=rx79:tx79 +lane_to_serdes_map_fabric_lane80.0=rx80:tx80 +lane_to_serdes_map_fabric_lane81.0=rx81:tx81 +lane_to_serdes_map_fabric_lane82.0=rx82:tx82 +lane_to_serdes_map_fabric_lane83.0=rx83:tx83 +lane_to_serdes_map_fabric_lane84.0=rx84:tx84 +lane_to_serdes_map_fabric_lane85.0=rx85:tx85 +lane_to_serdes_map_fabric_lane86.0=rx86:tx86 +lane_to_serdes_map_fabric_lane87.0=rx87:tx87 +lane_to_serdes_map_fabric_lane88.0=rx88:tx88 +lane_to_serdes_map_fabric_lane89.0=rx89:tx89 +lane_to_serdes_map_fabric_lane90.0=rx90:tx90 +lane_to_serdes_map_fabric_lane91.0=rx91:tx91 +lane_to_serdes_map_fabric_lane92.0=rx92:tx92 +lane_to_serdes_map_fabric_lane93.0=rx93:tx93 +lane_to_serdes_map_fabric_lane94.0=rx94:tx94 +lane_to_serdes_map_fabric_lane95.0=rx95:tx95 +lane_to_serdes_map_fabric_lane96.0=rx96:tx96 +lane_to_serdes_map_fabric_lane97.0=rx97:tx97 +lane_to_serdes_map_fabric_lane98.0=rx98:tx98 +lane_to_serdes_map_fabric_lane99.0=rx99:tx99 +lane_to_serdes_map_fabric_lane100.0=rx100:tx100 +lane_to_serdes_map_fabric_lane101.0=rx101:tx101 +lane_to_serdes_map_fabric_lane102.0=rx102:tx102 +lane_to_serdes_map_fabric_lane103.0=rx103:tx103 +lane_to_serdes_map_fabric_lane104.0=rx104:tx104 +lane_to_serdes_map_fabric_lane105.0=rx105:tx105 +lane_to_serdes_map_fabric_lane106.0=rx106:tx106 +lane_to_serdes_map_fabric_lane107.0=rx107:tx107 +lane_to_serdes_map_fabric_lane108.0=rx108:tx108 +lane_to_serdes_map_fabric_lane109.0=rx109:tx109 +lane_to_serdes_map_fabric_lane110.0=rx110:tx110 +lane_to_serdes_map_fabric_lane111.0=rx111:tx111 + +lane_to_serdes_map_nif_lane0.0=rx5:tx7 +lane_to_serdes_map_nif_lane1.0=rx7:tx6 +lane_to_serdes_map_nif_lane2.0=rx4:tx5 +lane_to_serdes_map_nif_lane3.0=rx6:tx4 +lane_to_serdes_map_nif_lane4.0=rx0:tx0 +lane_to_serdes_map_nif_lane5.0=rx1:tx1 +lane_to_serdes_map_nif_lane6.0=rx2:tx3 +lane_to_serdes_map_nif_lane7.0=rx3:tx2 +lane_to_serdes_map_nif_lane8.0=rx13:tx15 +lane_to_serdes_map_nif_lane9.0=rx12:tx14 +lane_to_serdes_map_nif_lane10.0=rx15:tx13 +lane_to_serdes_map_nif_lane11.0=rx14:tx12 +lane_to_serdes_map_nif_lane12.0=rx10:tx10 +lane_to_serdes_map_nif_lane13.0=rx8:tx9 +lane_to_serdes_map_nif_lane14.0=rx9:tx11 +lane_to_serdes_map_nif_lane15.0=rx11:tx8 +lane_to_serdes_map_nif_lane16.0=rx23:tx23 +lane_to_serdes_map_nif_lane17.0=rx21:tx22 +lane_to_serdes_map_nif_lane18.0=rx22:tx21 +lane_to_serdes_map_nif_lane19.0=rx20:tx20 +lane_to_serdes_map_nif_lane20.0=rx16:tx18 +lane_to_serdes_map_nif_lane21.0=rx17:tx17 +lane_to_serdes_map_nif_lane22.0=rx18:tx16 +lane_to_serdes_map_nif_lane23.0=rx19:tx19 +lane_to_serdes_map_nif_lane24.0=rx31:tx31 +lane_to_serdes_map_nif_lane25.0=rx30:tx30 +lane_to_serdes_map_nif_lane26.0=rx29:tx29 +lane_to_serdes_map_nif_lane27.0=rx28:tx28 +lane_to_serdes_map_nif_lane28.0=rx24:tx26 +lane_to_serdes_map_nif_lane29.0=rx26:tx25 +lane_to_serdes_map_nif_lane30.0=rx25:tx24 +lane_to_serdes_map_nif_lane31.0=rx27:tx27 +lane_to_serdes_map_nif_lane32.0=rx39:tx35 +lane_to_serdes_map_nif_lane33.0=rx38:tx36 +lane_to_serdes_map_nif_lane34.0=rx32:tx32 +lane_to_serdes_map_nif_lane35.0=rx37:tx37 +lane_to_serdes_map_nif_lane36.0=rx33:tx34 +lane_to_serdes_map_nif_lane37.0=rx34:tx38 +lane_to_serdes_map_nif_lane38.0=rx35:tx33 +lane_to_serdes_map_nif_lane39.0=rx36:tx39 +lane_to_serdes_map_nif_lane40.0=rx44:tx47 +lane_to_serdes_map_nif_lane41.0=rx43:tx41 +lane_to_serdes_map_nif_lane42.0=rx47:tx46 +lane_to_serdes_map_nif_lane43.0=rx42:tx42 +lane_to_serdes_map_nif_lane44.0=rx45:tx45 +lane_to_serdes_map_nif_lane45.0=rx41:tx40 +lane_to_serdes_map_nif_lane46.0=rx46:tx44 +lane_to_serdes_map_nif_lane47.0=rx40:tx43 +lane_to_serdes_map_nif_lane48.0=rx55:tx55 +lane_to_serdes_map_nif_lane49.0=rx54:tx54 +lane_to_serdes_map_nif_lane50.0=rx53:tx53 +lane_to_serdes_map_nif_lane51.0=rx52:tx52 +lane_to_serdes_map_nif_lane52.0=rx48:tx48 +lane_to_serdes_map_nif_lane53.0=rx49:tx49 +lane_to_serdes_map_nif_lane54.0=rx50:tx50 +lane_to_serdes_map_nif_lane55.0=rx51:tx51 +lane_to_serdes_map_nif_lane56.0=rx60:tx60 +lane_to_serdes_map_nif_lane57.0=rx61:tx61 +lane_to_serdes_map_nif_lane58.0=rx62:tx63 +lane_to_serdes_map_nif_lane59.0=rx63:tx62 +lane_to_serdes_map_nif_lane60.0=rx58:tx59 +lane_to_serdes_map_nif_lane61.0=rx59:tx56 +lane_to_serdes_map_nif_lane62.0=rx57:tx58 +lane_to_serdes_map_nif_lane63.0=rx56:tx57 +lane_to_serdes_map_nif_lane64.0=rx68:tx69 +lane_to_serdes_map_nif_lane65.0=rx69:tx68 +lane_to_serdes_map_nif_lane66.0=rx70:tx71 +lane_to_serdes_map_nif_lane67.0=rx71:tx70 +lane_to_serdes_map_nif_lane68.0=rx67:tx64 +lane_to_serdes_map_nif_lane69.0=rx66:tx67 +lane_to_serdes_map_nif_lane70.0=rx65:tx65 +lane_to_serdes_map_nif_lane71.0=rx64:tx66 +lane_to_serdes_map_nif_lane72.0=rx78:tx76 +lane_to_serdes_map_nif_lane73.0=rx76:tx77 +lane_to_serdes_map_nif_lane74.0=rx79:tx78 +lane_to_serdes_map_nif_lane75.0=rx77:tx79 +lane_to_serdes_map_nif_lane76.0=rx75:tx72 +lane_to_serdes_map_nif_lane77.0=rx74:tx75 +lane_to_serdes_map_nif_lane78.0=rx73:tx73 +lane_to_serdes_map_nif_lane79.0=rx72:tx74 +lane_to_serdes_map_nif_lane80.0=rx81:tx83 +lane_to_serdes_map_nif_lane81.0=rx85:tx84 +lane_to_serdes_map_nif_lane82.0=rx80:tx80 +lane_to_serdes_map_nif_lane83.0=rx86:tx85 +lane_to_serdes_map_nif_lane84.0=rx82:tx82 +lane_to_serdes_map_nif_lane85.0=rx87:tx86 +lane_to_serdes_map_nif_lane86.0=rx83:tx81 +lane_to_serdes_map_nif_lane87.0=rx84:tx87 +lane_to_serdes_map_nif_lane88.0=rx91:tx95 +lane_to_serdes_map_nif_lane89.0=rx90:tx89 +lane_to_serdes_map_nif_lane90.0=rx95:tx94 +lane_to_serdes_map_nif_lane91.0=rx89:tx90 +lane_to_serdes_map_nif_lane92.0=rx93:tx93 +lane_to_serdes_map_nif_lane93.0=rx94:tx88 +lane_to_serdes_map_nif_lane94.0=rx92:tx92 +lane_to_serdes_map_nif_lane95.0=rx88:tx91 +phy_rx_polarity_flip_phy0=0 +phy_rx_polarity_flip_phy1=1 +phy_rx_polarity_flip_phy2=0 +phy_rx_polarity_flip_phy3=0 +phy_rx_polarity_flip_phy4=0 +phy_rx_polarity_flip_phy5=0 +phy_rx_polarity_flip_phy6=0 +phy_rx_polarity_flip_phy7=0 +phy_rx_polarity_flip_phy8=1 +phy_rx_polarity_flip_phy9=1 +phy_rx_polarity_flip_phy10=1 +phy_rx_polarity_flip_phy11=1 +phy_rx_polarity_flip_phy12=0 +phy_rx_polarity_flip_phy13=1 +phy_rx_polarity_flip_phy14=1 +phy_rx_polarity_flip_phy15=1 +phy_rx_polarity_flip_phy16=0 +phy_rx_polarity_flip_phy17=1 +phy_rx_polarity_flip_phy18=1 +phy_rx_polarity_flip_phy19=0 +phy_rx_polarity_flip_phy20=0 +phy_rx_polarity_flip_phy21=0 +phy_rx_polarity_flip_phy22=0 +phy_rx_polarity_flip_phy23=0 +phy_rx_polarity_flip_phy24=1 +phy_rx_polarity_flip_phy25=1 +phy_rx_polarity_flip_phy26=1 +phy_rx_polarity_flip_phy27=0 +phy_rx_polarity_flip_phy28=0 +phy_rx_polarity_flip_phy29=1 +phy_rx_polarity_flip_phy30=1 +phy_rx_polarity_flip_phy31=0 +phy_rx_polarity_flip_phy32=0 +phy_rx_polarity_flip_phy33=1 +phy_rx_polarity_flip_phy34=1 +phy_rx_polarity_flip_phy35=0 +phy_rx_polarity_flip_phy36=0 +phy_rx_polarity_flip_phy37=0 +phy_rx_polarity_flip_phy38=1 +phy_rx_polarity_flip_phy39=0 +phy_rx_polarity_flip_phy40=1 +phy_rx_polarity_flip_phy41=1 +phy_rx_polarity_flip_phy42=0 +phy_rx_polarity_flip_phy43=0 +phy_rx_polarity_flip_phy44=1 +phy_rx_polarity_flip_phy45=1 +phy_rx_polarity_flip_phy46=0 +phy_rx_polarity_flip_phy47=0 +phy_rx_polarity_flip_phy48=1 +phy_rx_polarity_flip_phy49=1 +phy_rx_polarity_flip_phy50=1 +phy_rx_polarity_flip_phy51=1 +phy_rx_polarity_flip_phy52=0 +phy_rx_polarity_flip_phy53=0 +phy_rx_polarity_flip_phy54=0 +phy_rx_polarity_flip_phy55=0 +phy_rx_polarity_flip_phy56=0 +phy_rx_polarity_flip_phy57=0 +phy_rx_polarity_flip_phy58=0 +phy_rx_polarity_flip_phy59=0 +phy_rx_polarity_flip_phy60=1 +phy_rx_polarity_flip_phy61=1 +phy_rx_polarity_flip_phy62=1 +phy_rx_polarity_flip_phy63=1 +phy_rx_polarity_flip_phy64=1 +phy_rx_polarity_flip_phy65=1 +phy_rx_polarity_flip_phy66=1 +phy_rx_polarity_flip_phy67=1 +phy_rx_polarity_flip_phy68=1 +phy_rx_polarity_flip_phy69=1 +phy_rx_polarity_flip_phy70=1 +phy_rx_polarity_flip_phy71=1 +phy_rx_polarity_flip_phy72=1 +phy_rx_polarity_flip_phy73=0 +phy_rx_polarity_flip_phy74=0 +phy_rx_polarity_flip_phy75=1 +phy_rx_polarity_flip_phy76=1 +phy_rx_polarity_flip_phy77=1 +phy_rx_polarity_flip_phy78=1 +phy_rx_polarity_flip_phy79=1 +phy_rx_polarity_flip_phy80=0 +phy_rx_polarity_flip_phy81=0 +phy_rx_polarity_flip_phy82=1 +phy_rx_polarity_flip_phy83=1 +phy_rx_polarity_flip_phy84=1 +phy_rx_polarity_flip_phy85=0 +phy_rx_polarity_flip_phy86=1 +phy_rx_polarity_flip_phy87=1 +phy_rx_polarity_flip_phy88=0 +phy_rx_polarity_flip_phy89=0 +phy_rx_polarity_flip_phy90=1 +phy_rx_polarity_flip_phy91=1 +phy_rx_polarity_flip_phy92=0 +phy_rx_polarity_flip_phy93=1 +phy_rx_polarity_flip_phy94=0 +phy_rx_polarity_flip_phy95=0 +phy_tx_polarity_flip_phy0=1 +phy_tx_polarity_flip_phy1=1 +phy_tx_polarity_flip_phy2=1 +phy_tx_polarity_flip_phy3=1 +phy_tx_polarity_flip_phy4=1 +phy_tx_polarity_flip_phy5=1 +phy_tx_polarity_flip_phy6=0 +phy_tx_polarity_flip_phy7=0 +phy_tx_polarity_flip_phy8=1 +phy_tx_polarity_flip_phy9=1 +phy_tx_polarity_flip_phy10=1 +phy_tx_polarity_flip_phy11=1 +phy_tx_polarity_flip_phy12=1 +phy_tx_polarity_flip_phy13=1 +phy_tx_polarity_flip_phy14=0 +phy_tx_polarity_flip_phy15=0 +phy_tx_polarity_flip_phy16=0 +phy_tx_polarity_flip_phy17=0 +phy_tx_polarity_flip_phy18=0 +phy_tx_polarity_flip_phy19=0 +phy_tx_polarity_flip_phy20=0 +phy_tx_polarity_flip_phy21=0 +phy_tx_polarity_flip_phy22=0 +phy_tx_polarity_flip_phy23=0 +phy_tx_polarity_flip_phy24=0 +phy_tx_polarity_flip_phy25=0 +phy_tx_polarity_flip_phy26=0 +phy_tx_polarity_flip_phy27=0 +phy_tx_polarity_flip_phy28=0 +phy_tx_polarity_flip_phy29=0 +phy_tx_polarity_flip_phy30=0 +phy_tx_polarity_flip_phy31=0 +phy_tx_polarity_flip_phy32=0 +phy_tx_polarity_flip_phy33=0 +phy_tx_polarity_flip_phy34=1 +phy_tx_polarity_flip_phy35=1 +phy_tx_polarity_flip_phy36=1 +phy_tx_polarity_flip_phy37=0 +phy_tx_polarity_flip_phy38=0 +phy_tx_polarity_flip_phy39=1 +phy_tx_polarity_flip_phy40=1 +phy_tx_polarity_flip_phy41=1 +phy_tx_polarity_flip_phy42=0 +phy_tx_polarity_flip_phy43=1 +phy_tx_polarity_flip_phy44=1 +phy_tx_polarity_flip_phy45=1 +phy_tx_polarity_flip_phy46=0 +phy_tx_polarity_flip_phy47=0 +phy_tx_polarity_flip_phy48=0 +phy_tx_polarity_flip_phy49=0 +phy_tx_polarity_flip_phy50=0 +phy_tx_polarity_flip_phy51=0 +phy_tx_polarity_flip_phy52=0 +phy_tx_polarity_flip_phy53=0 +phy_tx_polarity_flip_phy54=0 +phy_tx_polarity_flip_phy55=0 +phy_tx_polarity_flip_phy56=1 +phy_tx_polarity_flip_phy57=1 +phy_tx_polarity_flip_phy58=0 +phy_tx_polarity_flip_phy59=0 +phy_tx_polarity_flip_phy60=1 +phy_tx_polarity_flip_phy61=1 +phy_tx_polarity_flip_phy62=0 +phy_tx_polarity_flip_phy63=0 +phy_tx_polarity_flip_phy64=0 +phy_tx_polarity_flip_phy65=0 +phy_tx_polarity_flip_phy66=0 +phy_tx_polarity_flip_phy67=0 +phy_tx_polarity_flip_phy68=0 +phy_tx_polarity_flip_phy69=0 +phy_tx_polarity_flip_phy70=1 +phy_tx_polarity_flip_phy71=1 +phy_tx_polarity_flip_phy72=1 +phy_tx_polarity_flip_phy73=1 +phy_tx_polarity_flip_phy74=1 +phy_tx_polarity_flip_phy75=1 +phy_tx_polarity_flip_phy76=0 +phy_tx_polarity_flip_phy77=0 +phy_tx_polarity_flip_phy78=1 +phy_tx_polarity_flip_phy79=1 +phy_tx_polarity_flip_phy80=0 +phy_tx_polarity_flip_phy81=1 +phy_tx_polarity_flip_phy82=1 +phy_tx_polarity_flip_phy83=1 +phy_tx_polarity_flip_phy84=1 +phy_tx_polarity_flip_phy85=0 +phy_tx_polarity_flip_phy86=0 +phy_tx_polarity_flip_phy87=1 +phy_tx_polarity_flip_phy88=1 +phy_tx_polarity_flip_phy89=0 +phy_tx_polarity_flip_phy90=0 +phy_tx_polarity_flip_phy91=1 +phy_tx_polarity_flip_phy92=1 +phy_tx_polarity_flip_phy93=1 +phy_tx_polarity_flip_phy94=0 +phy_tx_polarity_flip_phy95=0 + +ucode_port_1=CGE2_0:core_0.1 +ucode_port_2=CGE2_1:core_0.2 +ucode_port_3=CGE2_2:core_0.3 +ucode_port_4=CGE2_3:core_0.4 +ucode_port_5=CGE2_4:core_0.5 +ucode_port_6=CGE2_5:core_0.6 +ucode_port_7=CGE2_6:core_0.7 +ucode_port_8=CGE2_7:core_0.8 +ucode_port_9=CGE2_8:core_0.9 +ucode_port_10=CGE2_9:core_0.10 +ucode_port_11=CGE2_10:core_0.11 +ucode_port_12=CGE2_11:core_0.12 +ucode_port_13=CGE2_12:core_0.13 +ucode_port_14=CGE2_13:core_0.14 +ucode_port_15=CGE2_14:core_0.15 +ucode_port_16=CGE2_15:core_0.16 +ucode_port_17=CGE2_36:core_1.17 +ucode_port_18=CGE2_37:core_1.18 +ucode_port_19=CGE2_38:core_1.19 +ucode_port_20=CGE2_39:core_1.20 +ucode_port_21=CGE2_32:core_1.21 +ucode_port_22=CGE2_33:core_1.22 +ucode_port_23=CGE2_34:core_1.23 +ucode_port_24=CGE2_35:core_1.24 +ucode_port_25=CGE2_28:core_1.25 +ucode_port_26=CGE2_29:core_1.26 +ucode_port_27=CGE2_30:core_1.27 +ucode_port_28=CGE2_31:core_1.28 +ucode_port_29=CGE2_24:core_1.29 +ucode_port_30=CGE2_25:core_1.30 +ucode_port_31=CGE2_26:core_1.31 +ucode_port_32=CGE2_27:core_1.32 + +port_fec_33=2 +port_fec_34=2 +port_fec_35=2 +port_fec_36=2 +port_fec_37=2 +port_fec_38=2 +port_fec_39=2 +port_fec_40=2 + +ucode_port_33=CGE8:core_0.33 +ucode_port_34=CGE9:core_0.34 +ucode_port_35=CGE10:core_0.35 +ucode_port_36=CGE11:core_0.36 +ucode_port_37=CGE22:core_1.37 +ucode_port_38=CGE23:core_1.38 +ucode_port_39=CGE20:core_1.39 +ucode_port_40=CGE21:core_1.40 + +rif_id_max=0x4000 + +dma_desc_aggregator_chain_length_max.BCM8869X=1000 +dma_desc_aggregator_buff_size_kb.BCM8869X=100 +dma_desc_aggregator_timeout_usec.BCM8869X=1000 +dma_desc_aggregator_enable_specific_MDB_LPM.BCM8869X=1 +dma_desc_aggregator_enable_specific_MDB_FEC.BCM8869X=1 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/port_config.ini b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/port_config.ini new file mode 100644 index 000000000000..2ba638aee50d --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/port_config.ini @@ -0,0 +1,41 @@ +# name lanes alias index speed +Ethernet0 0,1 Ethernet1/1 1 100000 +Ethernet4 2,3 Ethernet2/1 2 100000 +Ethernet8 4,5 Ethernet3/1 3 100000 +Ethernet12 6,7 Ethernet4/1 4 100000 +Ethernet16 8,9 Ethernet5/1 5 100000 +Ethernet20 10,11 Ethernet6/1 6 100000 +Ethernet24 12,13 Ethernet7/1 7 100000 +Ethernet28 14,15 Ethernet8/1 8 100000 +Ethernet32 16,17 Ethernet9/1 9 100000 +Ethernet36 18,19 Ethernet10/1 10 100000 +Ethernet40 20,21 Ethernet11/1 11 100000 +Ethernet44 22,23 Ethernet12/1 12 100000 +Ethernet48 24,25 Ethernet13/1 13 100000 +Ethernet52 26,27 Ethernet14/1 14 100000 +Ethernet56 28,29 Ethernet15/1 15 100000 +Ethernet60 30,31 Ethernet16/1 16 100000 +Ethernet64 72,73 Ethernet17/1 17 100000 +Ethernet68 74,75 Ethernet18/1 18 100000 +Ethernet72 76,77 Ethernet19/1 19 100000 +Ethernet76 78,79 Ethernet20/1 20 100000 +Ethernet80 64,65 Ethernet21/1 21 100000 +Ethernet84 66,67 Ethernet22/1 22 100000 +Ethernet88 68,69 Ethernet23/1 23 100000 +Ethernet92 70,71 Ethernet24/1 24 100000 +Ethernet96 56,57 Ethernet25/1 25 100000 +Ethernet100 58,59 Ethernet26/1 26 100000 +Ethernet104 60,61 Ethernet27/1 27 100000 +Ethernet108 62,63 Ethernet28/1 28 100000 +Ethernet112 48,49 Ethernet29/1 29 100000 +Ethernet116 50,51 Ethernet30/1 30 100000 +Ethernet120 52,53 Ethernet31/1 31 100000 +Ethernet124 54,55 Ethernet32/1 32 100000 +Ethernet128 32,33,34,35 Ethernet33/1 33 100000 +Ethernet132 36,37,38,39 Ethernet33/5 33 100000 +Ethernet136 40,41,42,43 Ethernet34/1 34 100000 +Ethernet140 44,45,46,47 Ethernet34/5 34 100000 +Ethernet144 88,89,90,91 Ethernet35/1 35 100000 +Ethernet148 92,93,94,95 Ethernet35/5 35 100000 +Ethernet152 80,81,82,83 Ethernet36/1 36 100000 +Ethernet156 84,85,86,87 Ethernet36/5 36 100000 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile new file mode 100644 index 000000000000..130a3f8c4cbd --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32p4-40x100G.config.bcm diff --git a/src/sonic-device-data/tests/config_checker b/src/sonic-device-data/tests/config_checker index a0e3b0cbd45c..6d95c13efc7c 100755 --- a/src/sonic-device-data/tests/config_checker +++ b/src/sonic-device-data/tests/config_checker @@ -30,6 +30,8 @@ def check_file(file_name): continue p = line.split("=", 1)[0] + # Remove trailing chip name "bcm8869x" + p = re.sub(r"\.bcm8869x(_adapter)?$", "", p) # Remove trailing unit ".$" p = re.sub(r"\.[0-9]+$", '', p) # Remove trailing port name @@ -47,6 +49,12 @@ def check_file(file_name): p = re.sub(r"_lane\d+$", '', p) # Remove trailing "{.}$" p = re.sub(r"{[0-9]+\.[0-9]+}$", '', p) + # Remove trailing phy with number + p = re.sub(r"_phy\d+$", '', p) + # Remove trailing phase of data granularity + p = re.sub(r"_data_granularity_\w\w$", '_data_granularity', p) + # Remove trailing type of port_init_speed + p = re.sub(r"^port_init_speed_\w+$", 'port_init_speed', p) if not check_property(p): file_ok = False diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index 31c424857445..bba14e99db3e 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -159,4 +159,46 @@ ccmdma_intr_enable phy_enable init_all_modules port_fec +appl_enable_intr_init +custom_feature_ucode_path +dma_desc_aggregator_buff_size_kb +dma_desc_aggregator_chain_length_max +dma_desc_aggregator_enable_specific_mdb_fec +dma_desc_aggregator_enable_specific_mdb_lpm +dma_desc_aggregator_timeout_usec +dram_phy_tune_mode_on_init +dtm_flow_mapping_mode_region +dtm_flow_nof_remote_cores_region +fabric_connect_mode +fabric_logical_port_base +l4_protocols_load_balancing_enable +lane_to_serdes_map_fabric +lane_to_serdes_map_nif +mdb_profile +mem_cache_enable_ecc +mem_cache_enable_parity +num_olp_tm_ports +outlif_logical_to_physical_phase_map +outlif_physical_phase_data_granularity +pmf_sexem3_stage +polled_irq_delay +polled_irq_mode +port_priorities +protocol_traps_mode +rif_id_max +sat_enable +serdes_fabric_clk_freq_in +serdes_fabric_clk_freq_out +serdes_nif_clk_freq_in +serdes_nif_clk_freq_out +soc_family +stable_filename +stable_location +suppress_unknown_prop_warnings +sw_state_max_size +system_headers_mode +tm_port_header_type_in +tm_port_header_type_out +trunk_group_max_members +ucode_port led_fw_path From bccf18620a52168843734832231d2a97b7c6050c Mon Sep 17 00:00:00 2001 From: kannankvs Date: Wed, 25 Sep 2019 00:34:17 +0530 Subject: [PATCH 0002/1427] [snmpd] mvrf snmp ipv6 prototype mismatch issue resolved (#3504) --- .../0007-Linux-VRF-5.7.3-Support.patch | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/snmpd/patch-5.7.3+dfsg/0007-Linux-VRF-5.7.3-Support.patch b/src/snmpd/patch-5.7.3+dfsg/0007-Linux-VRF-5.7.3-Support.patch index e16014aeaf6b..48d13d7f62d6 100755 --- a/src/snmpd/patch-5.7.3+dfsg/0007-Linux-VRF-5.7.3-Support.patch +++ b/src/snmpd/patch-5.7.3+dfsg/0007-Linux-VRF-5.7.3-Support.patch @@ -49,9 +49,9 @@ Testing done included VRFs as well as non-VRF functionality with traps snmplib/transports/snmpUDPBaseDomain.c | 39 ++++++++++++++++++------ snmplib/transports/snmpUDPDomain.c | 15 ++++----- snmplib/transports/snmpUDPIPv4BaseDomain.c | 4 +-- - snmplib/transports/snmpUDPIPv6Domain.c | 13 ++++---- + snmplib/transports/snmpUDPIPv6Domain.c | 19 ++++----- snmplib/transports/snmpUnixDomain.c | 5 +-- - 23 files changed, 141 insertions(+), 70 deletions(-) + 23 files changed, 141 insertions(+), 76 deletions(-) diff --git a/agent/agent_trap.c b/agent/agent_trap.c index 080b8bf..c488ac9 100644 @@ -706,6 +706,19 @@ diff --git a/snmplib/transports/snmpUDPIPv6Domain.c b/snmplib/transports/snmpUDP index 18de876..6b44b22 100644 --- a/snmplib/transports/snmpUDPIPv6Domain.c +++ b/snmplib/transports/snmpUDPIPv6Domain.c +@@ -74,12 +74,6 @@ oid netsnmp_UDPIPv6Domain[] = { TRANSPORT_DOMAIN_UDP_IPV6 }; + static netsnmp_tdomain udp6Domain; + + /* +- * from snmpUDPDomain. not static, but not public, either. +- * (ie don't put it in a public header.) +- */ +-extern void _netsnmp_udp_sockopt_set(int fd, int server); +- +-/* + * Return a string representing the address in data, or else the "far end" + * address if data is NULL. + */ @@ -186,7 +186,7 @@ netsnmp_udp6_send(netsnmp_transport *t, void *buf, int size, */ From 75907f10aa7f4aa102f4c0665f3ae953e60ce067 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Tue, 24 Sep 2019 15:13:18 -0700 Subject: [PATCH 0003/1427] [snmp] Build snmpd with ipv6 support and enable it (#3500) --- dockers/docker-snmp-sv2/snmpd.conf.j2 | 4 ++-- ..._BUILD_ARCH_OS-in-order-to-build-ipv.patch | 24 +++++++++++++++++++ src/snmpd/patch-5.7.3+dfsg/series | 1 + 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp-sv2/snmpd.conf.j2 index 76a462026e18..78cf34d9f7fe 100644 --- a/dockers/docker-snmp-sv2/snmpd.conf.j2 +++ b/dockers/docker-snmp-sv2/snmpd.conf.j2 @@ -27,10 +27,9 @@ agentAddress {{ snmp_agent_address_3 }} {% endif %} {% else %} agentAddress udp:161 +agentAddress udp6:161 {% endif %} -# TODO: only support ipv4 lo addresses, add ipv6 support later - ############################################################################### # # ACCESS CONTROL @@ -47,6 +46,7 @@ rocommunity {{ community }} {% endfor %} {% else %} rocommunity {{ snmp_rocommunity }} +rocommunity6 {{ snmp_rocommunity }} {% endif %} ############################################################################### diff --git a/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch b/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch new file mode 100644 index 000000000000..f3e878077ff5 --- /dev/null +++ b/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch @@ -0,0 +1,24 @@ +From 6e038423d7a3269dbfd85b3d7ada6015479f1559 Mon Sep 17 00:00:00 2001 +From: Qi Luo +Date: Fri, 20 Sep 2019 00:42:19 +0000 +Subject: [PATCH] Enable macro DEB_BUILD_ARCH_OS in order to build ipv6 feature + +--- + debian/rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/debian/rules b/debian/rules +index 4c3b5b6..1fab6a4 100755 +--- a/debian/rules ++++ b/debian/rules +@@ -5,6 +5,7 @@ + # without -pie build fails during perl module build somehow... + export DEB_BUILD_MAINT_OPTIONS := hardening=+all,-pie + DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) ++DEB_BUILD_ARCH_OS ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS) + + LIB_VERSION = 30 + UPSTREAM_VERSION = $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ':' | sed 's/ //' | sed 's/~dfsg.*$$//') +-- +2.18.0 + diff --git a/src/snmpd/patch-5.7.3+dfsg/series b/src/snmpd/patch-5.7.3+dfsg/series index a8741fb5bb9d..5cd0b06510f6 100644 --- a/src/snmpd/patch-5.7.3+dfsg/series +++ b/src/snmpd/patch-5.7.3+dfsg/series @@ -5,3 +5,4 @@ 0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch 0006-From-Jiri-Cervenka-snmpd-Fixed-agentx-crashing-and-or-freezing-on-timeout.patch 0007-Linux-VRF-5.7.3-Support.patch +0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch From 0e74e6d845058a3d9b5b66148b2a7289a48b21f0 Mon Sep 17 00:00:00 2001 From: "Sudharsan D.G" Date: Tue, 24 Sep 2019 15:16:21 -0700 Subject: [PATCH 0004/1427] Fixing orchagent crash in S6100,Z9100 (#3439) --- .../Force10-S6100/th-s6100-64x40G-t0.config.bcm | 6 ------ .../Force10-S6100/th-s6100-64x40G-t1.config.bcm | 6 ------ .../Force10-Z9100-C32/th-z9100-32x100G.config.bcm | 2 -- .../th-z9100-8x100G-48x50G.config.bcm | 12 ------------ 4 files changed, 26 deletions(-) diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm index 2820853905ec..adbef9387eda 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm @@ -27,8 +27,6 @@ os=unix parity_correction=1 parity_enable=1 -port_phy_addr_66=0x176 -port_phy_addr_100=0x177 xgxs_tx_lane_map_104=0x3210 xgxs_rx_lane_map_104=0x0312 phy_xaui_tx_polarity_flip_104=0x0 @@ -340,8 +338,6 @@ phy_xaui_rx_polarity_flip_79=0x3 dport_map_port_78=63 dport_map_port_79=64 pbmp_xport_xe=0x3fffd0000ffff40003fffc0001fffe -portmap_66=129:10 -portmap_100=131:10 portmap_33=132:10 portmap_67=133:10 portmap_101=134:10 @@ -410,7 +406,5 @@ portmap_114=121:40:2 portmap_115=123:40:2 portmap_116=125:40:2 portmap_117=127:40:2 -dport_map_port_66=65 -dport_map_port_100=66 mmu_init_config="MSFT-TH-Tier0" diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm index df22bcf23ed1..f9dc619849d0 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm @@ -27,8 +27,6 @@ os=unix parity_correction=1 parity_enable=1 -port_phy_addr_66=0x176 -port_phy_addr_100=0x177 xgxs_tx_lane_map_104=0x3210 xgxs_rx_lane_map_104=0x0312 phy_xaui_tx_polarity_flip_104=0x0 @@ -340,8 +338,6 @@ phy_xaui_rx_polarity_flip_79=0x3 dport_map_port_78=63 dport_map_port_79=64 pbmp_xport_xe=0x3fffd0000ffff40003fffc0001fffe -portmap_66=129:10 -portmap_100=131:10 portmap_33=132:10 portmap_67=133:10 portmap_101=134:10 @@ -410,7 +406,5 @@ portmap_114=121:40:2 portmap_115=123:40:2 portmap_116=125:40:2 portmap_117=127:40:2 -dport_map_port_66=65 -dport_map_port_100=66 mmu_init_config="MSFT-TH-Tier1" diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm index 25aefca2dafa..39a3695b4cdc 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm @@ -57,8 +57,6 @@ portmap_2=5:100 portmap_1=1:100 portmap_4=13:100 portmap_3=9:100 -portmap_66=129:10 -portmap_100=131:10 portmap_33=132:10 portmap_67=133:10 portmap_101=134:10 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm index 5dddf7d2a2d4..3dd7cc89456d 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm @@ -25,7 +25,6 @@ parity_correction=1 parity_enable=1 #Port configuration -dport_map_port_100.0=130 dport_map_port_10.0=126 dport_map_port_1.0=117 dport_map_port_102.0=65 @@ -67,7 +66,6 @@ dport_map_port_58.0=9 dport_map_port_59.0=10 dport_map_port_62.0=13 dport_map_port_63.0=14 -dport_map_port_66.0=129 dport_map_port_68.0=17 dport_map_port_69.0=18 dport_map_port_72.0=21 @@ -84,7 +82,6 @@ dport_map_port_93.0=58 dport_map_port_96.0=61 dport_map_port_97.0=62 -phy_xaui_rx_polarity_flip_100.0=0xf phy_xaui_rx_polarity_flip_10.0=0x2 phy_xaui_rx_polarity_flip_1.0=0x9 phy_xaui_rx_polarity_flip_102.0=0x2 @@ -126,7 +123,6 @@ phy_xaui_rx_polarity_flip_58.0=0x2 phy_xaui_rx_polarity_flip_59.0=0x0 phy_xaui_rx_polarity_flip_62.0=0x3 phy_xaui_rx_polarity_flip_63.0=0x3 -phy_xaui_rx_polarity_flip_66.0=0xf phy_xaui_rx_polarity_flip_68.0=0x0 phy_xaui_rx_polarity_flip_69.0=0x3 phy_xaui_rx_polarity_flip_72.0=0x2 @@ -143,7 +139,6 @@ phy_xaui_rx_polarity_flip_93.0=0x1 phy_xaui_rx_polarity_flip_96.0=0x3 phy_xaui_rx_polarity_flip_97.0=0x2 -phy_xaui_tx_polarity_flip_100.0=0x6 phy_xaui_tx_polarity_flip_10.0=0x0 phy_xaui_tx_polarity_flip_1.0=0x3 phy_xaui_tx_polarity_flip_102.0=0x3 @@ -185,7 +180,6 @@ phy_xaui_tx_polarity_flip_58.0=0x2 phy_xaui_tx_polarity_flip_59.0=0x2 phy_xaui_tx_polarity_flip_62.0=0x3 phy_xaui_tx_polarity_flip_63.0=0x2 -phy_xaui_tx_polarity_flip_66.0=0x6 phy_xaui_tx_polarity_flip_68.0=0x2 phy_xaui_tx_polarity_flip_69.0=0x0 phy_xaui_tx_polarity_flip_72.0=0x0 @@ -202,7 +196,6 @@ phy_xaui_tx_polarity_flip_93.0=0x1 phy_xaui_tx_polarity_flip_96.0=0x0 phy_xaui_tx_polarity_flip_97.0=0x2 -portmap_100.0=131:10 portmap_10.0=11:50:2 portmap_1.0=1:100 portmap_102.0=97:50:2 @@ -244,7 +237,6 @@ portmap_58.0=57:50:2 portmap_59.0=59:50:2 portmap_62.0=61:50:2 portmap_63.0=63:50:2 -portmap_66.0=129:10 portmap_68.0=65:50:2 portmap_69.0=67:50:2 portmap_72.0=69:50:2 @@ -261,7 +253,6 @@ portmap_93.0=91:50:2 portmap_96.0=93:50:2 portmap_97.0=95:50:2 -xgxs_rx_lane_map_100.0=0x3210 xgxs_rx_lane_map_10.0=0x213 xgxs_rx_lane_map_1.0=0x213 xgxs_rx_lane_map_102.0=0x3201 @@ -303,7 +294,6 @@ xgxs_rx_lane_map_58.0=0x1203 xgxs_rx_lane_map_59.0=0x1203 xgxs_rx_lane_map_62.0=0x1302 xgxs_rx_lane_map_63.0=0x1302 -xgxs_rx_lane_map_66.0=0x3210 xgxs_rx_lane_map_68.0=0x3201 xgxs_rx_lane_map_69.0=0x3201 xgxs_rx_lane_map_72.0=0x1302 @@ -319,7 +309,6 @@ xgxs_rx_lane_map_92.0=0x3210 xgxs_rx_lane_map_93.0=0x3210 xgxs_rx_lane_map_96.0=0x3210 xgxs_rx_lane_map_97.0=0x3210 -xgxs_tx_lane_map_100.0=0x132 xgxs_tx_lane_map_10.0=0x123 xgxs_tx_lane_map_1.0=0x123 xgxs_tx_lane_map_102.0=0x123 @@ -361,7 +350,6 @@ xgxs_tx_lane_map_58.0=0x123 xgxs_tx_lane_map_59.0=0x123 xgxs_tx_lane_map_62.0=0x3201 xgxs_tx_lane_map_63.0=0x3201 -xgxs_tx_lane_map_66.0=0x132 xgxs_tx_lane_map_68.0=0x3210 xgxs_tx_lane_map_69.0=0x3210 xgxs_tx_lane_map_72.0=0x2301 From 905d429022f20bf2c118d564f8c1c11c7491e340 Mon Sep 17 00:00:00 2001 From: John Cheung Date: Tue, 24 Sep 2019 16:59:25 -0700 Subject: [PATCH 0005/1427] [barefoot]: updated SDK to 9.0.0 released debian package (#3471) --- platform/barefoot/bfn-platform.mk | 4 ++-- platform/barefoot/bfn-sai.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 22fc9e6d7c46..15fbd80daafd 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ -BFN_PLATFORM = bfnplatform_9.0.0.cc6ccbe_pr_deb9.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_0/bfnplatform_9.0.0.cc6ccbe_pr_deb9.deb" +BFN_PLATFORM = bfnplatform_9.0.0.e658347_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_0/bfnplatform_9.0.0.e658347_deb9.deb" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 584c89157527..2e6b8f711fda 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,5 @@ -BFN_SAI = bfnsdk_9.0.0.cc6ccbe_pr_deb9.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_0/bfnsdk_9.0.0.cc6ccbe_pr_deb9.deb" +BFN_SAI = bfnsdk_9.0.0.e658347_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_0/bfnsdk_9.0.0.e658347_deb9.deb" SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) From b6a09999ded10cb5a66af3a93cfcc8c74d55d97b Mon Sep 17 00:00:00 2001 From: Long Ou Date: Wed, 25 Sep 2019 08:36:02 +0800 Subject: [PATCH 0006/1427] [hostcfgd] hostcfgd will exit when set hostname in DEVICE_METADATA (#3394) Signed-off-by: ouxiaolong --- files/image_config/hostcfgd/hostcfgd | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 4b37c64b9a68..b32e3d8cd668 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -24,10 +24,8 @@ TACPLUS_SERVER_TIMEOUT_DEFAULT = "5" TACPLUS_SERVER_AUTH_TYPE_DEFAULT = "pap" -def is_valid_hostname(name): - if hostname[-1] == ".": - hostname = hostname[:-1] # strip exactly one dot from the right, if present - if len(hostname) > 253: +def is_valid_hostname(hostname): + if hostname[-1] == "." or len(hostname) > 253: return False allowed = re.compile("(?!-)[A-Z\d-]{1,63}(? Date: Wed, 25 Sep 2019 19:29:44 +0300 Subject: [PATCH 0007/1427] [submodule update] update sonic-snmpagent pointer (#3495) [sonic-snmpagent] - Fix issue #104: lldpLocManAddrTable supports multiple IP addresses (#106) - Add mgmt port speed test (#107) - [rfc2737] fix typo in xcvr removal flow (#109) - Add signal handler to change debug level. (#96) - [LLDP MIB] fix lldp loc mgmt ip logic (#113) --- src/sonic-snmpagent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 70a6c7dad4fc..875831ecda26 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 70a6c7dad4fcfa750fb4d4efbf267842d19ca8ef +Subproject commit 875831ecda2601a88612c0185242d11e97eb6e82 From c34a4783e0c3fb5d2a1335d91d15564754cabafc Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 25 Sep 2019 21:00:24 +0300 Subject: [PATCH 0008/1427] [build] install new platform api on host (#3282) slave.mk: add SONIC_PLATFORM_API_PY2 as dependency of host sonic_debian_extension.j2: install sonic_daemon_base and Mellanox-specific sonic_platform on host mlnx-platform-api.mk: export mlnx_platform_api_py2_wheel_path for sonic_debian_extension.j2 sonic-daemon-base.mk: export daemon_base_py2_wheel_path for sonic_debian_extension.j2 daemon_base.py: hind unnecessary dependency of swss_common on host --- files/build_templates/sonic_debian_extension.j2 | 12 ++++++++++++ platform/mellanox/mlnx-platform-api.mk | 1 + rules/sonic-daemon-base.mk | 1 + slave.mk | 3 ++- .../sonic_daemon_base/daemon_base.py | 2 +- 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index bcdecaa71766..d08aa7b6f1cc 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -116,6 +116,12 @@ sudo cp {{platform_common_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $PLATFORM_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME +# Install sonic-daemon-base Python 2 package +DAEMON_BASE_PY2_WHEEL_NAME=$(basename {{daemon_base_py2_wheel_path}}) +sudo cp {{daemon_base_py2_wheel_path}} $FILESYSTEM_ROOT/$DAEMON_BASE_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $DAEMON_BASE_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$DAEMON_BASE_PY2_WHEEL_NAME + # Install built Python Click package (and its dependencies via 'apt-get -y install -f') # Do this before installing sonic-utilities so that it doesn't attempt to install # an older version as part of its dependencies @@ -377,6 +383,12 @@ sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh + +# Install mlnx-sonic-platform-common Python 2 package +MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME=$(basename {{mlnx_platform_api_py2_wheel_path}}) +sudo cp {{mlnx_platform_api_py2_wheel_path}} $FILESYSTEM_ROOT/$MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME {% endif %} {%- if SONIC_ROUTING_STACK == "frr" %} diff --git a/platform/mellanox/mlnx-platform-api.mk b/platform/mellanox/mlnx-platform-api.mk index 98a57d0090ed..4b70e59debc1 100644 --- a/platform/mellanox/mlnx-platform-api.mk +++ b/platform/mellanox/mlnx-platform-api.mk @@ -5,3 +5,4 @@ $(SONIC_PLATFORM_API_PY2)_SRC_PATH = $(PLATFORM_PATH)/mlnx-platform-api $(SONIC_PLATFORM_API_PY2)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) +export mlnx_platform_api_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2))" diff --git a/rules/sonic-daemon-base.mk b/rules/sonic-daemon-base.mk index dad0900e75ca..5385c18f1f12 100644 --- a/rules/sonic-daemon-base.mk +++ b/rules/sonic-daemon-base.mk @@ -5,3 +5,4 @@ $(SONIC_DAEMON_BASE_PY2)_SRC_PATH = $(SRC_PATH)/sonic-daemon-base $(SONIC_DAEMON_BASE_PY2)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_DAEMON_BASE_PY2) +export daemon_base_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_DAEMON_BASE_PY2))" diff --git a/slave.mk b/slave.mk index dc13e43f62b2..1f5f3de7b3b0 100644 --- a/slave.mk +++ b/slave.mk @@ -622,7 +622,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_DEBS_PATH)/,$(SONIC_UTILS)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) + $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) $(HEADER) # Pass initramfs and linux kernel explicitly. They are used for all platforms export debs_path="$(STRETCH_DEBS_PATH)" diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index e238c13c22be..afdb189de672 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -7,7 +7,6 @@ import os import sys import syslog - from swsscommon import swsscommon except ImportError, e: raise ImportError (str(e) + " - required module not found") @@ -38,6 +37,7 @@ # def db_connect(db): + from swsscommon import swsscommon return swsscommon.DBConnector(db, REDIS_HOSTNAME, REDIS_PORT, From 362a6855ec1659b67f9f7806024440a61186dee0 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 25 Sep 2019 21:41:07 +0300 Subject: [PATCH 0009/1427] [Mellanox] enhance the initialization flow of sfp part of new platform api (#3319) * [sonic_platform.sfp_event]enhance the initialization flow of sfp_event * [sonic_platform.sfp_event] replace "retry = retry + 1" with "retry += 1" * [sonic_platform] fix typo in sfp_event * [sfp_event] remove unused variables * [sonic_platform/sfp_event.py]remove unnecessary statements --- .../sonic_platform/sfp_event.py | 109 +++++++++++++----- 1 file changed, 78 insertions(+), 31 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py index 1e57603d38ad..439df785b24e 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py @@ -24,6 +24,14 @@ SDK_SFP_STATE_OUT: STATUS_PLUGOUT, } +# system level event/error +EVENT_ON_ALL_SFP = '-1' +SYSTEM_NOT_READY = 'system_not_ready' +SYSTEM_READY = 'system_become_ready' +SYSTEM_FAIL = 'system_fail' + +SDK_DAEMON_READY_FILE = '/tmp/sdk_ready' + PMPE_PACKET_SIZE = 2000 logger = Logger(SYSLOG_IDENTIFIER) @@ -31,47 +39,86 @@ class sfp_event: ''' Listen to plugin/plugout cable events ''' - SX_OPEN_RETRIES = 20 + SX_OPEN_RETRIES = 30 + SX_OPEN_TIMEOUT = 5 + SELECT_TIMEOUT = 1 def __init__(self): self.swid = 0 self.handle = None - def initialize(self): - # open SDK API handle. - # retry at most SX_OPEN_RETRIES times to wait until SDK is started during system startup - retry = 1 - while True: - rc, self.handle = sx_api_open(None) - if rc == SX_STATUS_SUCCESS: - break - - logger.log_info("failed to open SDK API handle... retrying {}".format(retry)) - - time.sleep(2 ** retry) - retry += 1 - - if retry > self.SX_OPEN_RETRIES: - raise RuntimeError("failed to open SDK API handle after {} retries".format(retry)) - # Allocate SDK fd and user channel structures self.rx_fd_p = new_sx_fd_t_p() self.user_channel_p = new_sx_user_channel_t_p() - rc = sx_api_host_ifc_open(self.handle, self.rx_fd_p) - if rc != SX_STATUS_SUCCESS: - raise RuntimeError("sx_api_host_ifc_open exited with error, rc {}".format(rc)) - - self.user_channel_p.type = SX_USER_CHANNEL_TYPE_FD - self.user_channel_p.channel.fd = self.rx_fd_p + def initialize(self): + swid_cnt_p = None - rc = sx_api_host_ifc_trap_id_register_set(self.handle, - SX_ACCESS_CMD_REGISTER, - self.swid, - SX_TRAP_ID_PMPE, - self.user_channel_p) - if rc != SX_STATUS_SUCCESS: - raise RuntimeError("sx_api_host_ifc_trap_id_register_set exited with error, rc {}".format(rc)) + try: + # Wait for SDK daemon to be started with detect the sdk_ready file + retry = 0 + while not os.path.exists(SDK_DAEMON_READY_FILE): + if retry >= self.SX_OPEN_RETRIES: + raise RuntimeError("SDK daemon failed to start after {} retries and {} seconds waiting, exiting..." + .format(retry, self.SX_OPEN_TIMEOUT * self.SX_OPEN_RETRIES)) + else: + logger.log_info("SDK daemon not started yet, retry {} times".format(retry)) + retry += 1 + time.sleep(self.SX_OPEN_TIMEOUT) + + # After SDK daemon started, sx_api_open and sx_api_host_ifc_open is ready for call + rc, self.handle = sx_api_open(None) + if rc != SX_STATUS_SUCCESS: + raise RuntimeError("failed to call sx_api_open with rc {}, exiting...".format(rc)) + + rc = sx_api_host_ifc_open(self.handle, self.rx_fd_p) + if rc != SX_STATUS_SUCCESS: + raise RuntimeError("failed to call sx_api_host_ifc_open with rc {}, exiting...".format(rc)) + + self.user_channel_p.type = SX_USER_CHANNEL_TYPE_FD + self.user_channel_p.channel.fd = self.rx_fd_p + + # Wait for switch to be created and initialized inside SDK + retry = 0 + swid_cnt_p = new_uint32_t_p() + uint32_t_p_assign(swid_cnt_p, 0) + swid_cnt = 0 + while True: + if retry >= self.SX_OPEN_RETRIES: + raise RuntimeError("switch not created after {} retries and {} seconds waiting, exiting..." + .format(retry, self.SX_OPEN_RETRIES * self.SX_OPEN_TIMEOUT)) + else: + rc = sx_api_port_swid_list_get(self.handle, None, swid_cnt_p) + if rc == SX_STATUS_SUCCESS: + swid_cnt = uint32_t_p_value(swid_cnt_p) + if swid_cnt > 0: + delete_uint32_t_p(swid_cnt_p) + swid_cnt_p = None + break + else: + logger.log_info("switch not created yet, swid_cnt {}, retry {} times and wait for {} seconds" + .format(swid_cnt, retry, self.SX_OPEN_TIMEOUT * retry)) + else: + raise RuntimeError("sx_api_port_swid_list_get fail with rc {}, retry {} times and wait for {} seconds". + format(rc, retry, self.SX_OPEN_TIMEOUT * retry)) + + retry += 1 + time.sleep(self.SX_OPEN_TIMEOUT) + + # After switch was created inside SDK, sx_api_host_ifc_trap_id_register_set is ready to call + rc = sx_api_host_ifc_trap_id_register_set(self.handle, + SX_ACCESS_CMD_REGISTER, + self.swid, + SX_TRAP_ID_PMPE, + self.user_channel_p) + + if rc != SX_STATUS_SUCCESS: + raise RuntimeError("sx_api_host_ifc_trap_id_register_set failed with rc {}, exiting...".format(rc)) + except Exception as e: + logger.log_error("sfp_event initialization failed due to {}, exiting...".format(repr(e))) + if swid_cnt_p is not None: + delete_uint32_t_p(swid_cnt_p) + self.deinitialize() def deinitialize(self): if self.handle is None: From d059bda21c56b57934d7cbe002a5575b73560886 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Thu, 26 Sep 2019 03:07:28 +0800 Subject: [PATCH 0010/1427] Update sonic-platform-daemons submodule to pick up recent fix: (#3509) [xcvrd] state machine enhancement [xcvrd] Fix transceiver tuning issue --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 88d6d5a13c12..a34ba131f618 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 88d6d5a13c12cc26458762ce3f54fd90dda7fe9f +Subproject commit a34ba131f618a8df6beec1f548aa08f9cedc48db From 7b0a5ba6ae14dc7596dec87c8f60dc827c29ee46 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Wed, 25 Sep 2019 15:57:07 -0700 Subject: [PATCH 0011/1427] Remove the divide by 4 operation to the under the hood SAI (#1532) * Remove the divide by 4 operation to the under the hood SAI This is to avoid the need and thus the confusion for application program to know the mmu internal architecture This change must have support from SAI change to reach the correct config Signed-off-by: Wenda * Relegate the divide by 4 operation to the under the hood SAI for egress lossless pool Extend to 7060 and 6100 Signed-off-by: Wenda * Add more TH/TH2 hwskus Signed-off-by: Wenda Ni * Update config test Signed-off-by: Wenda Ni * Add TH2 ingress lossy profile Signed-off-by: Wenda Ni * Move the divide by 4 operation to SAI internal Signed-off-by: Wenda Ni * [bcm SAI] Upgrade Broadcom SAI to version 3.5.3.1-15 - Broadcom SAI 3.5 GA release 20190924. Signed-off-by: Ying Xie --- .../Arista-7060CX-32S-C32/buffers_defaults_t0.j2 | 2 +- .../Arista-7060CX-32S-C32/buffers_defaults_t1.j2 | 2 +- .../Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 | 2 +- .../Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 | 2 +- .../Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 | 2 +- .../Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 | 2 +- .../Arista-7170-64C/buffers_defaults_t0.j2 | 4 ++-- .../Arista-7170-Q59S20/buffers_defaults_t0.j2 | 4 ++-- .../Arista-7260CX3-D108C8/buffers_defaults_t0.j2 | 4 ++-- .../Arista-7260CX3-Q64/buffers_defaults_t0.j2 | 4 ++-- .../Celestica-DX010-C32/buffers_defaults_t0.j2 | 2 +- .../Celestica-DX010-C32/buffers_defaults_t1.j2 | 2 +- .../Celestica-DX010-D48C8/buffers_defaults_t0.j2 | 2 +- .../Force10-S6100/buffers_defaults_t0.j2 | 2 +- .../Force10-S6100/buffers_defaults_t1.j2 | 2 +- .../Force10-Z9100-C32/buffers_defaults_t1.j2 | 2 +- .../Force10-Z9100-C8D48/buffers_defaults_t0.j2 | 2 +- platform/broadcom/sai.mk | 8 ++++---- .../tests/sample_output/buffers-dell6100.json | 2 +- 19 files changed, 26 insertions(+), 26 deletions(-) diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 index cb74cb75281b..0869e63968ac 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 index 0699433bffb4..80e96bdceca7 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 index 5d6e0cd61a7e..5add8968e621 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 @@ -50,7 +50,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 index 7463e20afabe..c0fa1ff0864e 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 @@ -50,7 +50,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 index cb74cb75281b..0869e63968ac 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 index 0699433bffb4..80e96bdceca7 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 index 62a6bac1c25f..3442612f70b2 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 @@ -30,12 +30,12 @@ "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"11075584" + "static_th":"44302336" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"10587408" + "static_th":"42349632" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 index 8ca15c1b0391..fabdac2df879 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 @@ -42,12 +42,12 @@ "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"11075584" + "static_th":"44302336" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"10587408" + "static_th":"42349632" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 index a5951e156b26..74579a022dcb 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 @@ -38,12 +38,12 @@ "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"11075584" + "static_th":"44302336" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"10587408" + "static_th":"42349632" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/buffers_defaults_t0.j2 index 62a6bac1c25f..3442612f70b2 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/buffers_defaults_t0.j2 @@ -30,12 +30,12 @@ "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"11075584" + "static_th":"44302336" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"10587408" + "static_th":"42349632" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t0.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t0.j2 index 43b7d7e31a9c..4dd6bd96ad96 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t0.j2 +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t0.j2 @@ -43,7 +43,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t1.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t1.j2 index 6ec383c77081..3c93fb8fe2e3 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t1.j2 +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t1.j2 @@ -43,7 +43,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/buffers_defaults_t0.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/buffers_defaults_t0.j2 index 766de07b4945..4e4489f84a87 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/buffers_defaults_t0.j2 +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/buffers_defaults_t0.j2 @@ -58,7 +58,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 index f949a31eab7b..8f55022973fb 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 index e56bbb65845f..47a9c81f0796 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 index e127362c091a..fa78303b2468 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 index f200b85b2027..fa5b0fc5a52b 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 @@ -50,7 +50,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 28fdf57577c9..d29e0907796d 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.5.2.3_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.2.3_amd64.deb?sv=2015-04-05&sr=b&sig=anY6TeLouYsw7L6hfpH%2BTHOkvF8M3WR%2B6P2C7Dh8sHg%3D&se=2033-02-20T17%3A19%3A46Z&sp=r" +BRCM_SAI = libsaibcm_3.5.3.1-15_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.3.1-15_amd64.deb?sv=2015-04-05&sr=b&sig=zXY%2FK%2FeGlxteIFlEkPdE%2FNDRet5T%2Fc1LgL0qyX9%2FmfQ%3D&se=2033-06-03T17%3A45%3A51Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.5.2.3_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.5.3.1-15_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm-dev_3.5.2.3_amd64.deb?sv=2015-04-05&sr=b&sig=o%2BVIKwVnlNv8LAvVzcS2kIXc0%2BIKaTzmA8LIkIfsh6c%3D&se=2033-02-20T17%3A20%3A03Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm-dev_3.5.3.1-15_amd64.deb?sv=2015-04-05&sr=b&sig=%2BYOVgRo6dLxv3sLb8JE1wLoD%2FneYDABadwFv5xH3XRE%3D&se=2033-06-03T17%3A46%3A14Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) diff --git a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json index 0b6c8cbe19a3..ce157b442614 100644 --- a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json +++ b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json @@ -96,7 +96,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", From a577a80b059ed40486e9585b0fd19c76f6796357 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 25 Sep 2019 16:08:44 -0700 Subject: [PATCH 0012/1427] Flush port in both worm-reboot and fast-reboot mode on exit. Otherwise teamd will stuck (#3512) --- src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch b/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch index d92ac6987e62..52a181d4da6f 100644 --- a/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch +++ b/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch @@ -108,7 +108,7 @@ index 9dc85b5..679da49 100644 + teamd_refresh_ports(ctx); + if (ctrl_byte == 'w') + teamd_ports_flush_data(ctx); -+ } else { ++ /* Flush ports to destroy port object */ + err = teamd_flush_ports(ctx); + if (err) + return err; From a8f10c7b646bb9c0ec7d223c7076358625b112a6 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 26 Sep 2019 10:57:16 -0700 Subject: [PATCH 0013/1427] [sonic-slave] Update linux-compiler-gcc package version to fix build (#3514) --- sonic-slave/Dockerfile.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic-slave/Dockerfile.j2 b/sonic-slave/Dockerfile.j2 index 42d4aa98f648..7ed7c4eb7096 100644 --- a/sonic-slave/Dockerfile.j2 +++ b/sonic-slave/Dockerfile.j2 @@ -150,7 +150,7 @@ RUN apt-get update && apt-get install -y \ zip \ {%- if CONFIGURED_ARCH == "amd64" %} # For broadcom sdk build - linux-compiler-gcc-4.8-x86 \ + linux-compiler-gcc-4.9-x86 \ {%- endif %} linux-kbuild-3.16 \ # teamd build From e9785d507d128666b937ecf14831dbec3a6d9b28 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Fri, 27 Sep 2019 01:25:35 +0300 Subject: [PATCH 0014/1427] [sonic-utilities] advance head to cbf19f6 (#3519) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index b19b125c5afa..cbf19f643a1a 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit b19b125c5afacea6c704d4003a12265cb94c8f8b +Subproject commit cbf19f643a1aa708eee6306814c0d52fd7535ec4 From 504cf62bfc476e22895747766f57f89db9fb51af Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 26 Sep 2019 16:39:48 -0700 Subject: [PATCH 0015/1427] [libteam]: Use last fixes from libteam master repo (#3513) --- src/libteam/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libteam/Makefile b/src/libteam/Makefile index cf8e382bb78c..b1ef12375416 100644 --- a/src/libteam/Makefile +++ b/src/libteam/Makefile @@ -15,7 +15,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf ./libteam git clone https://github.com/jpirko/libteam.git pushd ./libteam - git checkout -b teamd -f 5c5e498bff9 + git checkout -b teamd -f 8c7614abf5993d92e332a800f244bdebd7c9a2c8 # Apply patch series stg init From 8c4678718e9ff1bcc31d31501e70065c9d986e21 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 26 Sep 2019 18:23:12 -0700 Subject: [PATCH 0016/1427] [snmp] snmpd ipv6 supports multiple community strings (#3523) --- dockers/docker-snmp-sv2/snmpd.conf.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp-sv2/snmpd.conf.j2 index 78cf34d9f7fe..9784cc42e7f7 100644 --- a/dockers/docker-snmp-sv2/snmpd.conf.j2 +++ b/dockers/docker-snmp-sv2/snmpd.conf.j2 @@ -43,6 +43,7 @@ view systemonly included .1.3.6.1.2.1.25.1 {% if snmp_rocommunities %} {% for community in snmp_rocommunities %} rocommunity {{ community }} +rocommunity6 {{ community }} {% endfor %} {% else %} rocommunity {{ snmp_rocommunity }} From 7308d2eb97edc1e191ffcc9842c01bae747da7b4 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Fri, 27 Sep 2019 11:15:46 +0300 Subject: [PATCH 0017/1427] [Mellanox] Stop pmon ahead of syncd (#3505) Issue Overview shutdown flow For any shutdown flow, which means all dockers are stopped in order, pmon docker stops after syncd docker has stopped, causing pmon docker fail to release sx_core resources and leaving sx_core in a bad state. The related logs are like the following: INFO syncd.sh[23597]: modprobe: FATAL: Module sx_core is in use. INFO syncd.sh[23597]: Unloading sx_core[FAILED] INFO syncd.sh[23597]: rmmod: ERROR: Module sx_core is in use config reload & service swss.restart In the flows like "config reload" and "service swss restart", the failure cause further consequences: sx_core initialization error with error message like "sx_core: create EMAD sdq 0 failed. err: -16" syncd fails to execute the create switch api with error message "syncd_main: Runtime error: :- processEvent: failed to execute api: create, key: SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000, status: SAI_STATUS_FAILURE" swss fails to call SAI API "SAI_SWITCH_ATTR_INIT_SWITCH", which causes orchagent to restart. This will introduce an extra 1 or 2 minutes for the system to be available, failing related test cases. reboot, warm-reboot & fast-reboot In the reboot flows including "reboot", "fast-reboot" and "warm-reboot" this failure doesn't have further negative effects since the system has already rebooted. In addition, "warm-reboot" requires the system to be shutdown as soon as possible to meet the GR time restriction of both BGP and LACP. "fast-reboot" also requires to meet the GR time restriction of BGP which is longer than LACP. In this sense, any unnecessary steps should be avoided. It's better to keep those flows untouched. summary To summarize, we have to come up with a way to ensure: shutdown pmon docker ahead of syncd for "config reload" or "service swss restart" flow; don't shutdown pmon docker ahead of syncd for "fast-reboot" or "warm-reboot" flow in order to save time. for "reboot" flow, either order is acceptable. Solution To solve the issue, pmon shoud be stopped ahead of syncd stopped for all flows except for the warm-reboot. - How I did it To stop pmon ahead of syncd stopped. This is done in /usr/local/bin/syncd.sh::stop() and for all shutdown sequence. Now pmon stops ahead of syncd so there must be a way in which pmon can start after syncd started. Another point that should be taken consideration is that pmon starting should be deferred so that services which have the logic of graceful restart in fast-reboot and warm-reboot have sufficient CPU cycles to meet their deadline. This is done by add "syncd.service" as "After" to pmon.service and startin /usr/local/bin/syncd.sh::wait() To start pmon automatically after syncd started. --- files/build_templates/pmon.service.j2 | 3 +++ files/scripts/syncd.sh | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/files/build_templates/pmon.service.j2 b/files/build_templates/pmon.service.j2 index 33f3173b4887..9c4226256818 100644 --- a/files/build_templates/pmon.service.j2 +++ b/files/build_templates/pmon.service.j2 @@ -2,6 +2,9 @@ Description=Platform monitor container Requires=updategraph.service After=updategraph.service +{% if sonic_asic_platform == 'mellanox' %} +After=syncd.service +{% endif %} Before=ntp-config.service [Service] diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 0c3be805e7d6..2b7c76263d8a 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -104,11 +104,9 @@ start() { if [[ x"$WARM_BOOT" != x"true" ]]; then if [[ x"$(/bin/systemctl is-active pmon)" == x"active" ]]; then /bin/systemctl stop pmon - /usr/bin/hw-management.sh chipdown - /bin/systemctl restart pmon - else - /usr/bin/hw-management.sh chipdown + debug "pmon is active while syncd starting, stop it first" fi + /usr/bin/hw-management.sh chipdown fi if [[ x"$BOOT_TYPE" == x"fast" ]]; then @@ -134,6 +132,11 @@ start() { } wait() { + if [[ x"$sonic_asic_platform" == x"mellanox" ]]; then + debug "Starting pmon service..." + /bin/systemctl start pmon + debug "Started pmon service" + fi /usr/bin/${SERVICE}.sh wait } @@ -150,6 +153,12 @@ stop() { TYPE=cold fi + if [[ x$sonic_asic_platform == x"mellanox" ]] && [[ x$TYPE == x"cold" ]]; then + debug "Stopping pmon service ahead of syncd..." + /bin/systemctl stop pmon + debug "Stopped pmon service" + fi + if [[ x$sonic_asic_platform != x"mellanox" ]] || [[ x$TYPE != x"cold" ]]; then debug "${TYPE} shutdown syncd process ..." /usr/bin/docker exec -i syncd /usr/bin/syncd_request_shutdown --${TYPE} From 00ab25d4e346fb2f409d2d93d5d784e69eb3acd9 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Fri, 27 Sep 2019 13:50:07 +0530 Subject: [PATCH 0018/1427] [devices]: DellEMC-Z9264f: 10G_Port_addition (#3475) Added 10G ports for all the HWSKU(100G/40G/50G) --- .../DellEMC-Z9264f-C64/port_config.ini | 4 +++- .../DellEMC-Z9264f-C8D112/port_config.ini | 2 ++ .../th2-z9264f-8x100G-112x50G.config.bcm | 8 ++++++-- .../DellEMC-Z9264f-Q64/port_config.ini | 2 ++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini index 1dc88972d530..2bd5931d7866 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini @@ -62,4 +62,6 @@ Ethernet236 173,174,175,176 hundredGigE1/60 60 100000 Ethernet240 185,186,187,188 hundredGigE1/61 61 100000 Ethernet244 189,190,191,192 hundredGigE1/62 62 100000 Ethernet248 201,202,203,204 hundredGigE1/63 63 100000 -Ethernet252 205,206,207,208 hundredGigE1/64 64 100000 +Ethernet252 205,206,207,208 hundredGigE1/64 64 100000 +Ethernet256 257 tenGigE1/65 65 10000 +Ethernet257 259 tenGigE1/66 66 10000 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/port_config.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/port_config.ini index 5a2051c9d8dd..27c3906a9a49 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/port_config.ini +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/port_config.ini @@ -119,3 +119,5 @@ Ethernet248 201,202 fiftyGigE1/63/1 63 50000 Ethernet250 203,204 fiftyGigE1/63/2 63 50000 Ethernet252 205,206 fiftyGigE1/64/1 64 50000 Ethernet254 207,208 fiftyGigE1/64/2 64 50000 +Ethernet256 257 tenGigE1/65 65 10000 +Ethernet257 259 tenGigE1/66 66 10000 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm index 2329ecc6baee..f4b3addfb516 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm @@ -73,6 +73,10 @@ dport_map_port_92=49 dport_map_port_93=50 dport_map_port_90=51 dport_map_port_91=52 +dport_map_port_104=53 +dport_map_port_105=54 +dport_map_port_102=55 +dport_map_port_103=56 dport_map_port_29=57 dport_map_port_30=58 dport_map_port_27=59 @@ -1107,8 +1111,8 @@ phy_chain_rx_lane_map_physical{253.0}=0x2013 physical_ports=64 logical_ports=136 uplink_ports=2 -dport_map_port_66=65 -dport_map_port_100=66 +dport_map_port_66=121 +dport_map_port_100=122 module_64ports=1 mmu_init_config="MSFT-TH-Tier0" diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini index 646d91492beb..13c0d6600020 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini @@ -63,3 +63,5 @@ Ethernet240 185,186,187,188 fortyGigE1/61 61 40000 Ethernet244 189,190,191,192 fortyGigE1/62 62 40000 Ethernet248 201,202,203,204 fortyGigE1/63 63 40000 Ethernet252 205,206,207,208 fortyGigE1/64 64 40000 +Ethernet256 257 tenGigE1/65 65 10000 +Ethernet257 259 tenGigE1/66 66 10000 From d3d04dcc58a7744e18adfa41bc8a22387540c35c Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Fri, 27 Sep 2019 11:23:07 +0300 Subject: [PATCH 0019/1427] [bfn] Add missing port 65 for Mavericks board (#3461) Signed-off-by: Andriy Kokhan --- .../x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini index 7a3b600fe8de..def494da0081 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini @@ -62,4 +62,5 @@ Ethernet236 236,237,238,239 Ethernet236 60 100000 0 rs Ethernet240 240,241,242,243 Ethernet240 61 100000 0 rs Ethernet244 244,245,246,247 Ethernet244 62 100000 0 rs Ethernet248 248,249,250,251 Ethernet248 63 100000 0 rs -Ethernet252 252,253,254,255 Etherner252 64 100000 0 rs +Ethernet252 252,253,254,255 Ethernet252 64 100000 0 rs +Ethernet256 256,257,258,259 Ethernet256 65 100000 0 none From 500c20f3cd24b5777ad5afe85dc4cbd56d422f2a Mon Sep 17 00:00:00 2001 From: hans-tseng Date: Fri, 27 Sep 2019 16:26:09 +0800 Subject: [PATCH 0020/1427] [devics]: update the installer.conf and config.bcm for delta devices (#3482) 1. add the console port in install.conf 2. update the ag9032v2a configuration file 3. add the default_sku in ag9032v2a Signed-off-by: hans-tseng --- .../x86_64-delta_ag5648-r0/installer.conf | 1 + .../x86_64-delta_ag9032v1-r0/installer.conf | 1 + .../Delta-ag9032v2a/port_config.ini | 68 +++++++++---------- .../td3-ag9032v2a-32x100G+1x10G.config.bcm | 1 - .../x86_64-delta_ag9032v2a-r0/default_sku | 1 + .../x86_64-delta_ag9032v2a-r0/installer.conf | 1 + .../x86_64-delta_ag9064-r0/installer.conf | 1 + 7 files changed, 39 insertions(+), 35 deletions(-) create mode 100644 device/delta/x86_64-delta_ag9032v2a-r0/default_sku diff --git a/device/delta/x86_64-delta_ag5648-r0/installer.conf b/device/delta/x86_64-delta_ag5648-r0/installer.conf index fa2af8b7a007..85ed43ab48ed 100644 --- a/device/delta/x86_64-delta_ag5648-r0/installer.conf +++ b/device/delta/x86_64-delta_ag5648-r0/installer.conf @@ -1,2 +1,3 @@ CONSOLE_PORT=0x3f8 CONSOLE_SPEED=115200 +CONSOLE_DEV=0 diff --git a/device/delta/x86_64-delta_ag9032v1-r0/installer.conf b/device/delta/x86_64-delta_ag9032v1-r0/installer.conf index fa2af8b7a007..85ed43ab48ed 100644 --- a/device/delta/x86_64-delta_ag9032v1-r0/installer.conf +++ b/device/delta/x86_64-delta_ag9032v1-r0/installer.conf @@ -1,2 +1,3 @@ CONSOLE_PORT=0x3f8 CONSOLE_SPEED=115200 +CONSOLE_DEV=0 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini index ea064a708a3a..d7b858054ff9 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini +++ b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini @@ -1,34 +1,34 @@ -# name lanes alias -Ethernet0 41,42,43,44 hundredGigE1/1 -Ethernet4 45,46,47,48 hundredGigE1/2 -Ethernet8 49,50,51,52 hundredGigE1/3 -Ethernet12 37,38,39,40 hundredGigE1/4 -Ethernet16 33,34,35,36 hundredGigE1/5 -Ethernet20 53,54,55,56 hundredGigE1/6 -Ethernet24 57,58,59,60 hundredGigE1/7 -Ethernet28 61,62,63,64 hundredGigE1/8 -Ethernet32 65,66,67,68 hundredGigE1/9 -Ethernet36 69,70,71,72 hundredGigE1/10 -Ethernet40 73,74,75,76 hundredGigE1/11 -Ethernet44 77,78,79,80 hundredGigE1/12 -Ethernet48 81,82,83,84 hundredGigE1/13 -Ethernet52 85,86,87,88 hundredGigE1/14 -Ethernet56 89,90,91,92 hundredGigE1/15 -Ethernet60 93,94,95,96 hundredGigE1/16 -Ethernet64 97,98,99,100 hundredGigE1/17 -Ethernet68 101,102,103,104 hundredGigE1/18 -Ethernet72 105,106,107,108 hundredGigE1/19 -Ethernet76 109,110,111,112 hundredGigE1/20 -Ethernet80 121,122,123,124 hundredGigE1/21 -Ethernet84 113,114,115,116 hundredGigE1/22 -Ethernet88 1,2,3,4 hundredGigE1/23 -Ethernet92 117,118,119,120 hundredGigE1/24 -Ethernet96 5,6,7,8 hundredGigE1/25 -Ethernet100 125,126,127,128 hundredGigE1/26 -Ethernet104 29,30,31,32 hundredGigE1/27 -Ethernet108 9,10,11,12 hundredGigE1/28 -Ethernet112 13,14,15,16 hundredGigE1/29 -Ethernet116 25,26,27,28 hundredGigE1/30 -Ethernet120 17,18,19,20 hundredGigE1/31 -Ethernet124 21,22,23,24 hundredGigE1/32 -Ethernet128 129 hundredGigE1/33 +# name lanes alias index speed +Ethernet0 1,2,3,4 hundredGigE1/1 1 100000 +Ethernet4 5,6,7,8 hundredGigE1/2 2 100000 +Ethernet8 9,10,11,12 hundredGigE1/3 3 100000 +Ethernet12 13,14,15,16 hundredGigE1/4 4 100000 +Ethernet16 17,18,19,20 hundredGigE1/5 5 100000 +Ethernet20 21,22,23,24 hundredGigE1/6 6 100000 +Ethernet24 25,26,27,28 hundredGigE1/7 7 100000 +Ethernet28 29,30,31,32 hundredGigE1/8 8 100000 +Ethernet32 33,34,35,36 hundredGigE1/9 9 100000 +Ethernet36 37,38,39,40 hundredGigE1/10 10 100000 +Ethernet40 41,42,43,44 hundredGigE1/11 11 100000 +Ethernet44 45,46,47,48 hundredGigE1/12 12 100000 +Ethernet48 49,50,51,52 hundredGigE1/13 13 100000 +Ethernet52 53,54,55,56 hundredGigE1/14 14 100000 +Ethernet56 57,58,59,60 hundredGigE1/15 15 100000 +Ethernet60 61,62,63,64 hundredGigE1/16 16 100000 +Ethernet64 65,66,67,68 hundredGigE1/17 17 100000 +Ethernet68 69,70,71,72 hundredGigE1/18 18 100000 +Ethernet72 73,74,75,76 hundredGigE1/19 19 100000 +Ethernet76 77,78,79,80 hundredGigE1/20 20 100000 +Ethernet80 81,82,83,84 hundredGigE1/21 21 100000 +Ethernet84 85,86,87,88 hundredGigE1/22 22 100000 +Ethernet88 89,90,91,92 hundredGigE1/23 23 100000 +Ethernet92 93,94,95,96 hundredGigE1/24 24 100000 +Ethernet96 97,98,99,100 hundredGigE1/25 25 100000 +Ethernet100 101,102,103,104 hundredGigE1/26 26 100000 +Ethernet104 105,106,107,108 hundredGigE1/27 27 100000 +Ethernet108 109,110,111,112 hundredGigE1/28 28 100000 +Ethernet112 113,114,115,116 hundredGigE1/29 29 100000 +Ethernet116 117,118,119,120 hundredGigE1/30 30 100000 +Ethernet120 121,122,123,124 hundredGigE1/31 31 100000 +Ethernet124 125,126,127,128 hundredGigE1/32 32 100000 +Ethernet128 129 tenGigE1/33 33 10000 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm index f15efb4e2a10..4c6ceb075bf4 100755 --- a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm +++ b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm @@ -350,7 +350,6 @@ phy_chain_tx_polarity_flip_physical{97.0}=0x1 phy_chain_tx_polarity_flip_physical{98.0}=0x1 phy_chain_tx_polarity_flip_physical{99.0}=0x0 portmap_66.0=129:10:m -portmap_130.0=128:10:m portmap_103=101:100 portmap_107=105:100 portmap_111=109:100 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/default_sku b/device/delta/x86_64-delta_ag9032v2a-r0/default_sku new file mode 100644 index 000000000000..2e67043ab05a --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v2a-r0/default_sku @@ -0,0 +1 @@ +Delta-ag9032v2a t1 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/installer.conf b/device/delta/x86_64-delta_ag9032v2a-r0/installer.conf index fa2af8b7a007..85ed43ab48ed 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/installer.conf +++ b/device/delta/x86_64-delta_ag9032v2a-r0/installer.conf @@ -1,2 +1,3 @@ CONSOLE_PORT=0x3f8 CONSOLE_SPEED=115200 +CONSOLE_DEV=0 diff --git a/device/delta/x86_64-delta_ag9064-r0/installer.conf b/device/delta/x86_64-delta_ag9064-r0/installer.conf index fa2af8b7a007..85ed43ab48ed 100644 --- a/device/delta/x86_64-delta_ag9064-r0/installer.conf +++ b/device/delta/x86_64-delta_ag9064-r0/installer.conf @@ -1,2 +1,3 @@ CONSOLE_PORT=0x3f8 CONSOLE_SPEED=115200 +CONSOLE_DEV=0 From 59febed528782d14d40528e0b5e8bd9238f44cfc Mon Sep 17 00:00:00 2001 From: wangshengjun Date: Sat, 28 Sep 2019 03:43:44 +0800 Subject: [PATCH 0021/1427] [docker-fpm-frr]:filter out the file of 'Dockerfile.j2' from the 'docker-fpm-frr' image. (#3507) Signed-off-by: wangshengjun --- dockers/docker-fpm-frr/.dockerignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 dockers/docker-fpm-frr/.dockerignore diff --git a/dockers/docker-fpm-frr/.dockerignore b/dockers/docker-fpm-frr/.dockerignore new file mode 100644 index 000000000000..bd5eecc5d798 --- /dev/null +++ b/dockers/docker-fpm-frr/.dockerignore @@ -0,0 +1 @@ +Dockerfile.j2 From ecdd8667134f586750a7d7edc44cecd9bccaacbf Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Sat, 28 Sep 2019 02:44:16 +0700 Subject: [PATCH 0022/1427] [device/celestica]: Update Component APIs (#3510) * [platform/cel]: add bios upgrade tool * [device/celestica]: update Seastone/E1031 component api to support BIOS upgrade * [device/celestica]: add error handler for eeprom api * [device/celestica]: add component description --- .../sonic_platform/chassis.py | 40 +++--------------- .../sonic_platform/component.py | 35 +++++++++++---- .../sonic_platform/eeprom.py | 10 ++--- .../sonic_platform/chassis.py | 39 +++-------------- .../sonic_platform/component.py | 34 +++++++++++---- .../sonic_platform/eeprom.py | 10 ++--- .../debian/platform-modules-dx010.install | 1 + .../platform-modules-haliburton.install | 1 + .../tools/afulnx_64 | Bin 0 -> 828912 bytes 9 files changed, 74 insertions(+), 96 deletions(-) create mode 100755 platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py index 633af66dbaa8..291ece986222 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py @@ -31,10 +31,10 @@ NUM_PSU = 2 NUM_THERMAL = 7 NUM_SFP = 52 +NUM_COMPONENT = 3 RESET_REGISTER = "0x112" HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt" PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/previous-reboot-cause.txt" -COMPONENT_NAME_LIST = ["SMC_CPLD", "MMC_CPLD", "BIOS"] HOST_CHK_CMD = "docker > /dev/null 2>&1" @@ -56,10 +56,13 @@ def __init__(self): for index in range(0, NUM_SFP): sfp = Sfp(index) self._sfp_list.append(sfp) + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) ChassisBase.__init__(self) self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self.__is_host( ) else PMON_REBOOT_CAUSE_PATH - self._component_name_list = COMPONENT_NAME_LIST + self._watchdog = Watchdog() self._eeprom = Tlv() @@ -102,36 +105,6 @@ def get_system_eeprom_info(self): """ return self._eeprom.get_eeprom() - def get_firmware_version(self, component_name): - """ - Retrieves platform-specific hardware/firmware versions for chassis - componenets such as BIOS, CPLD, FPGA, etc. - Args: - type: A string, component name - - Returns: - A string containing platform-specific component versions - """ - self.component = Component(component_name) - if component_name not in self._component_name_list: - return None - return self.component.get_firmware_version() - - def install_component_firmware(self, component_name, image_path): - """ - Install firmware to module - Args: - type: A string, component name. - image_path: A string, path to firmware image. - - Returns: - A boolean, True if install successfully, False if not - """ - self.component = Component(component_name) - if component_name not in self._component_name_list: - return False - return self.component.upgrade_firmware(image_path) - def get_reboot_cause(self): """ Retrieves the cause of the previous reboot @@ -143,10 +116,9 @@ def get_reboot_cause(self): is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. """ - self.component = Component("SMC_CPLD") description = 'None' reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER - hw_reboot_cause = self.component.get_register_value(RESET_REGISTER) + hw_reboot_cause = self._component_list[0].get_register_value(RESET_REGISTER) sw_reboot_cause = self.__read_txt_file( self._reboot_cause_path) or "Unknown" diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py index b80deabb178d..ad6810b14c38 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py @@ -15,7 +15,7 @@ import subprocess try: - from sonic_platform_base.device_base import DeviceBase + from sonic_platform_base.component_base import ComponentBase except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -24,16 +24,20 @@ CONFIG_DB_PATH = "/etc/sonic/config_db.json" SMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/version" GETREG_PATH = "/sys/devices/platform/e1031.smc/getreg" +COMPONENT_NAME_LIST = ["SMC_CPLD", "MMC_CPLD", "BIOS"] +COMPONENT_DES_LIST = ["System Management Controller", + "Module Management CPLD", "Basic Input/Output System"] -class Component(DeviceBase): +class Component(ComponentBase): """Platform-specific Component class""" DEVICE_TYPE = "component" - def __init__(self, component_name): - DeviceBase.__init__(self) - self.name = component_name.upper() + def __init__(self, component_index): + ComponentBase.__init__(self) + self.index = component_index + self.name = self.get_name() def __run_command(self, command): # Run bash command and print output to stdout @@ -86,6 +90,22 @@ def __get_cpld_version(self): cpld_version["MMC_CPLD"] = mmc_cpld_version return cpld_version + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return COMPONENT_NAME_LIST[self.index] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return COMPONENT_DES_LIST[self.index] + def get_firmware_version(self): """ Retrieves the firmware version of module @@ -102,7 +122,7 @@ def get_firmware_version(self): return fw_version - def upgrade_firmware(self, image_path): + def install_firmware(self, image_path): """ Install firmware to module Args: @@ -121,7 +141,6 @@ def upgrade_firmware(self, image_path): shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path elif self.name == "BIOS": - print("Not supported") - return False + install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py index b6881620612d..20f3db111f66 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py @@ -57,17 +57,15 @@ def __parse_output(self, decode_output): def _load_eeprom(self): original_stdout = sys.stdout sys.stdout = StringIO() - err = self.read_eeprom_db() - if err: - # Failed to read EEPROM information from database. Read from cache file - pass - else: + try: + self.read_eeprom_db() + except: decode_output = sys.stdout.getvalue() sys.stdout = original_stdout return self.__parse_output(decode_output) status = self.check_status() - if status <> 'ok': + if 'ok' not in status: return False if not os.path.exists(CACHE_ROOT): diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index 7e597b7d08e7..768a15ce22ef 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -31,12 +31,12 @@ NUM_PSU = 2 NUM_THERMAL = 5 NUM_SFP = 32 +NUM_COMPONENT = 5 RESET_REGISTER = "0x103" HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/" PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" REBOOT_CAUSE_FILE = "reboot-cause.txt" PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" -COMPONENT_NAME_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "BIOS"] HOST_CHK_CMD = "docker > /dev/null 2>&1" @@ -58,9 +58,11 @@ def __init__(self): for index in range(0, NUM_SFP): sfp = Sfp(index) self._sfp_list.append(sfp) + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) ChassisBase.__init__(self) - self._component_name_list = COMPONENT_NAME_LIST self._watchdog = Watchdog() self._eeprom = Tlv() @@ -103,36 +105,6 @@ def get_system_eeprom_info(self): """ return self._eeprom.get_eeprom() - def get_firmware_version(self, component_name): - """ - Retrieves platform-specific hardware/firmware versions for chassis - componenets such as BIOS, CPLD, FPGA, etc. - Args: - type: A string, component name - - Returns: - A string containing platform-specific component versions - """ - self.component = Component(component_name) - if component_name not in self._component_name_list: - return None - return self.component.get_firmware_version() - - def install_component_firmware(self, component_name, image_path): - """ - Install firmware to module - Args: - type: A string, component name. - image_path: A string, path to firmware image. - - Returns: - A boolean, True if install successfully, False if not - """ - self.component = Component(component_name) - if component_name not in self._component_name_list: - return False - return self.component.upgrade_firmware(image_path) - def get_reboot_cause(self): """ Retrieves the cause of the previous reboot @@ -144,7 +116,6 @@ def get_reboot_cause(self): is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. """ - self.component = Component("CPLD1") description = 'None' reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER @@ -153,7 +124,7 @@ def get_reboot_cause(self): prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) if self.__is_host( ) else PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE - hw_reboot_cause = self.component.get_register_value(RESET_REGISTER) + hw_reboot_cause = self._component_list[0].get_register_value(RESET_REGISTER) sw_reboot_cause = self.__read_txt_file( reboot_cause_path) or "Unknown" diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py index d78adf738920..67c7a9c46341 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py @@ -15,7 +15,7 @@ import subprocess try: - from sonic_platform_base.device_base import DeviceBase + from sonic_platform_base.component_base import ComponentBase except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -28,16 +28,19 @@ } GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg" BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" +COMPONENT_NAME_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "BIOS"] +COMPONENT_DES_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "Basic Input/Output System"] -class Component(DeviceBase): +class Component(ComponentBase): """Platform-specific Component class""" DEVICE_TYPE = "component" - def __init__(self, component_name): - DeviceBase.__init__(self) - self.name = component_name.upper() + def __init__(self, component_index): + ComponentBase.__init__(self) + self.index = component_index + self.name = self.get_name() def __run_command(self, command): # Run bash command and print output to stdout @@ -88,6 +91,22 @@ def __get_cpld_version(self): cpld_version[cpld_name] = 'None' return cpld_version + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return COMPONENT_NAME_LIST[self.index] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return COMPONENT_DES_LIST[self.index] + def get_firmware_version(self): """ Retrieves the firmware version of module @@ -104,7 +123,7 @@ def get_firmware_version(self): return fw_version - def upgrade_firmware(self, image_path): + def install_firmware(self, image_path): """ Install firmware to module Args: @@ -123,7 +142,6 @@ def upgrade_firmware(self, image_path): shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path elif self.name == "BIOS": - print("Not supported") - return False + install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/eeprom.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/eeprom.py index 1e10848ca439..dffda1a3c050 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/eeprom.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/eeprom.py @@ -57,17 +57,15 @@ def __parse_output(self, decode_output): def _load_eeprom(self): original_stdout = sys.stdout sys.stdout = StringIO() - err = self.read_eeprom_db() - if err: - # Failed to read EEPROM information from database. Read from cache file - pass - else: + try: + self.read_eeprom_db() + except: decode_output = sys.stdout.getvalue() sys.stdout = original_stdout return self.__parse_output(decode_output) status = self.check_status() - if status <> 'ok': + if 'ok' not in status: return False if not os.path.exists(CACHE_ROOT): diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install index 8570fa1eae84..2ab53302a9bf 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install @@ -3,3 +3,4 @@ dx010/cfg/dx010-modules.conf etc/modules-load.d dx010/systemd/platform-modules-dx010.service lib/systemd/system dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin +tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install index df78b7a34ea4..d50306304cd5 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install @@ -5,3 +5,4 @@ services/fancontrol/fancontrol.service lib/systemd/system services/fancontrol/fancontrol usr/local/bin haliburton/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_e1031-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin +tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 b/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 new file mode 100755 index 0000000000000000000000000000000000000000..c32823393c0805484f1a5ef37375c0ca3384a72b GIT binary patch literal 828912 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

85zk~l~w4ssI#lf-PD znC&J4CW*s!;&3-{cnM1)wP^#5yaW;Pba)BsR~=r8zc8be&5P-G{k*mGH_U$}{(WC( z>9+eUo8H&)tj?6NvZ2EsON4nFBe0n~?BU43^+wp<7tM39pM!S2 zqLa^SiG;eBS?kOloJ+x*T3OE_mS~uSJ&u)LW?G9XoqylO#*0{6yRshyf*l#v!F8lX z#P~ykHJPyzd~+4*Le6)B#6Pj;VY{ZXE}BnAqQIU)7!kQ>3i3*zuqRa9_YY7;FudTV;~(W<8K&tti&OS!5`{8e4z z>@Ylo52rkmN32L3s~F{LaH)Rb0$k0cqO-|H?bz|?zfm#u7y@>}~QnF9n?FCn8x_q(y#;{}^+ zmWnuCekK}hu~rETcBo;L?8-Syk;uas7gXp#%R8`d)~wH3Z~yP_vDP$I4p}QTYOl5a zqt6~&>nOu8S?iX&+OSp%&)LqP#X+i4!KEyhzPdtwQ@vB?fvNTqBqjm5^p~H}yya1% zLUMTq=qwk%ojxgUY)|dZhVL4oVdZc_Q^|IJQUA_b#v%`z<*X!S6;Tpg~&YK<8 zoV*-@-v3iI4V{JutB8nRK!5Too?KiLejC6cYr=2gAF`v?3M#=_vV|)U4b!iZ%Cty$ zIX?7H^z(EKoF-X^sDd@!i0osEdaeZM^)F_M4)@bBSh?jS7NQj$l|9!<>7*D>qx%7WX(>xQyr1B&up9N+mg{d(53k-Xj+OkwNL z@++N>!58z46&^IW()HX@tXlkdgj}73`?CbBe|LOFO0Qgt4@ol=pebN*LrX;XH2%b!O2J z>sM03>~K>XB@9Vc!ao~)(xK-TEcs8jO89n%lK;1Dl(7D)BvLB$mk{%o(A6qowk{!# z5;9+B)zG_?+RUNvTq^9!nZ7*i5k(4er{)MXn2`% zIs@N^E!YP5U)e{BotOKR>}XfkbOidZ;uX|Gq!jk!!m99%y~DG)Ffu~ixJd3i#y1m% zoMBN;kxn2reqdR=OIbWn7T>qbzJ0NH1@{s3I-l+(9w1Jt0-3MRqa-d%mab0d!MzJZ z$X$k<|E96hJeP{(#?Mg;UR*=xNU4c$8Eng8Ov^xp-jkXh%D`FVG%Su?+e7vJviyEI z4+a)m-DDK!uF;hRmlI!f`g%@#-BM$8J>N|0=hBdqaXZ&87Mu?)v=%K7IUO025yjd| zaA_>KOv6tRI4LW*EEEeO^L3J$j$g2ps6>FP1k7wyMuU}}ouB)5VRitdkIs5`k zsP%ZO){se#{ItVX&lQ1vBwee6#CU*!R8aOsJLux;LoHqCPzEF8g)j!pCq>vNTdE;R zR*;{Lg+t&CXa0*=_-sJ}=}jiaw~Pu-N#)3p?(%PxO`_3qq8|%WpaVOP#mH99L%mC+ z-a365r&DaZToOoXVS<7pWez!UX@L;;SyASiP;}S-wIu4Gh}%*QvZ|mcR!$t}o)>af z-$Av=Xu8+iWIrubmGgS^5YGFt1;oN@nZq~gNk|!}XzoTKr|jd66xheALp=5& zYcsG9nb3rN(9DzHJ_r^I7qfo4-00eeK=zW!6ILZb#6AWw_L!qsuJy8WV8urugusFR z;lN=XKGrX$zZ-a}YW-qLit>b2B<%1vaTd$z9t$_)gN&=3NRyJg&SE7;nR&X8L|rUS z_BBG%n5h}b_%7idg{ijqgLv4>aM!RN;Pxn!7S;jD<-cuIqZl5kWpZf$6d2~Xz zSa^#RUN8U$E6~@Y(P2Uc)Igoy8lLcPhB12tw)WV*QN|KvDWU%+LU5ng-^Wm7z}~i{ zkMNIJIA185Js($3B|b6~AKBevAy^Gr3Z~_xJ#mFfMM;rx2ImKBL@4A;)$jm*Vy7Mc z_GO&va2md07Z@wi*APydIU-t46a+@st&v1TX2(g(qdVUygCt2Q2TBt96uj8Wsj2bj zfPgTP>MHtjy0Tx_@A1>zeliykniOC7D&#gxRv#O2Qvl8H=RpqLVu&jsZ=cVDMUf?lNT^>Xfp z4N^?vvK`90fx}JDInRO+10iR{ciimC+7O8p?D}qU6O_?+uHi zjzdzul@zgICR9>1L@Ce*R4A_aV*Hl@DdSMff{- z)pW+oR(PK%yr&s2oAH(i-XSPFznH7TOh2PgZ)McsjJni9<>y7Dezz%9n$wGx=P>Fr z8x_q}F%VLybgn-dZUIus+Em=ZO&_jW2ZZvsyMjIXVAczKe5TIQE+NanP(E#)Qg*og zF9}&N9qKD(P$-{#qssDLViq_UUzVYv{AxGL+{7$_ge=*ieA-E&O1U^OOIAXb;i3H3 z-7NhQvt%b^$qD5@=Vtl2o38$TBC(8O$q_B53Pm{{?^zQGcjsU9_pimsj_rg;N6Tk0 z5MCJOQ^;nKf<&dj`#up%qnpH{oWG<2mnKlYX`HWt^G%n0=_cQJmG5XPU%KR*%K0|h z`2r?i50!5#xqMY#mgFnse2sR#ER%0bjqph`FFIeg2|^pkC*0p28GynvsAj=x<8lr8qf9Kb=(CCSlMite!6%M8ds*AZgKZ z{vHvEq(?`LjpU?7M@)$1;QOLTPDXUZXztX6eGHFw;!|Uj zF6IN?6t4xS?NGdyhH^ad8UacwhfDaQhC$dN&fOve*jf<)f>ZhxusreFtI|w4f>{U@ z)Ww2Gymqe(AwAq7KlNA(@!BopRJ`^ZYyj~Z{loDZ4KZ+50e?5Ipg0R>74R3Xl>U}e zjESp-iE|2|NTMNUo=n=90j#*okW?U60?6v#*>yCJhv%jdaPeFEZh;F<_2yMn|UDxhDUgHwZRwblS3CZI%#_Or@Hd3!y zo{h3)O%!pR6|XVskMB#J>8jdj`EW)}jMo_T1BH4QqvkLw`Dsm+j&3PY%vY!va<@&v z!!F}B7VK^4z0q3tFka&?k&bL72 zn`D)@n;44oU9Ix<=6uCmKaQdJ>Mvgm)r5Zj|7Q&4iZ@9NC5dgsP?Fe23?+$e#8A{} zkvGpPMJN0GG`70kbo0_Ba5qoBANg8&PAH@4L)>CyP3RPMa0aK@9jv*H&+1sIr@+ly zPQ8?k{fF2<1&%=WO9o}&$|AafjS^ZU;fl+NPg$Z;cYQv}AZp3js3#PMT+g-P4LayT zul^64mQFp?oBFHV2*gG3dR8+Scv2XMmv}36d3&?_F&zx?wz_oZ`hRKqv{jAvzrnM} zZW~i?TAKWZ3Siltk%IznZl`yY;YJc_BorIbsGFDB$a<{W z$czEV;V#6BMflXgQ%egux66w>V2NK5`R8JpJL9`XC3fmA3w`KC-4{d#6{^X4(5YiO zXUZE65(ucrHC{%`L^gUsgbUNS7mVOZLhp`?q96m+j*G&{Br`R)_S7n+Lo8w|m}b9P z=FlKynx;^RYNR=xUtY!LA46y}c!eyRt|T*{;E+V-{48ro>XJ57qpG{zI*P0gSFab@ zZ)CVjWCK|aGo%PJeJRqpS!fxk(EC)qI#kEHdGKGDsC**Dov5Un0CuNat{n9mSg&Z* z)4M9@y-Y9hr4`VU!A8bs2U5gma!-;`iO}jV zv1tHbI8d#F! zZ{|AbHDSc1RSf^)7*ZDdSY9rMUM0g6%ngDr+rwH$E&RrX2+mx2iO`jwfd76cmj!9L zH<-GIm4(=mLd?iTa$cfyvRpp<8gkk6>+hFKD&#T|PlEX5vH%{Mc~FG!Hwgd^LKT)$&oIZ0(t`Pzj@u@i1*`hLk>GHdse`|c|y z=9Ao!Iwwo+k*^@Rg**S4lTzD5>8&=87#W8Gm)O5{SM@Aap4M|E{T^D-y9j zzu6VE6kB~8%g-;?8nIK4b`!t+*0pCL@p2AlGI-2OEj=cx%3la zKDkWMIaw}s8zGl(esbkf(u{+{>9d2)Yl5xV)fQ|X_B*`=La;K=Pevz$#u9c7FVNgJkGI@ULFL>=x zo#o8pYgpH+GfkVXSt}PZAbwBwz)w%qKylLN&v0^F5>EEz+sTu@iS)vcrq~=^Z0&4) zH!hti3$C@}`Mg@bi#9Dbs)jZ_w3l%gj*em60sjQh->jjSBg2uK%usA9Bv+$%tA@y@ z(NpYO0NsKP^iZZ#g{B%CwS~wpyo~J*CuZnYTdR5WJi3#k}*wHf#)?DEn z4ZVkU!dNi`Ysi0tfS6Y`?0uF&#H;WKtH^PA?2yRFqOC@bqU2hS93AGIUO^ABtEm@a zbno-bmXyrW`ABDBV03=|BoQ+meQvoCr@?DuAy|KnG>UUL6%xmCT7$A1Xc^+Xab!ub zIW8m?(2hs;Z~kDa+)bGqSX46>xHps| z;o!ECncLtpG4MC7MmeX%Oe>OQ!c8~S)Kn%kGP*p6h4}Df78DAF=S+9_V3v9r1~3cp zIxphwGJleU;+bB=V}u_@r@2qVd7j5UvGA$Vt)fj$#FXA^9J2 z>_$&>hn!2>ai>VWgEONXP8jDn);x*e_Wq~ar3&q;6BrV^y?aSKHEHR03I@}c(m&&avII>+?37<t{;nG7~ zdO>38oG{*L(Q_fFyWk$1Q2M&#c31a%6oy;(ZCrXjm)>lK`$q4aFy6VrDqV1weCDtF zxw|brBcb$Pxb$K!{o2IRIbpoB?IPt9PCl^cFLu zH+AQP@y>LsbirNvslV>IyDdGCPL-Lt^QiFy7gIp<8#sJt?8|S~bJcw$0Dg zb1=r{yKw1ix%6#jP;TnZ3FDnxtGhM=2lUx zq%9V~MAYV6sFvZHtKK-~$dfiE!#E*^t0TZuYSUzNA;l}m=cg1-l+19D`RvWhsb=VV ze_fz2@H5nDEuA(CIy1W~(daRDbFM2ZVe!@)hD5{EzeKY~stq`}D;bhuSPDJD%kRvf zv%&81LzYutLt}AllTh-_c}mt|SH;3hKnH2ytiv*mh%>W*sy)WU*yS?T*IUYoI`(KB zc8Ov4gLoRyuF>q$9`h7AbhRvmd z2{tFap%HNa7*LDN6~d5alcgq86J+ zd)ds2g%`VQ9_O;Tmu7R)<3^fm4V#BpY!cLB^H!0YmL^dLn*;r9mYl2khBOaMV6*fx zTbksh+R?T(^32*02E@WIxvWn&jk;iO&H93QhV^xZ^~tZf5+m^;<5| zoGJ;g9i;(a{X#h{Yb0!utJL$G#?z+x>o71De%Y@L9N33Ysq8d5*655K_o-YL)Uxx z4LNz5%?E{Utem<;P~UhmA4lRYS_C@uRPMfG^Qh0CwYpm>`u{L}4_=Lfym7jMVvO@H zPqPN%xDEquk!az4n{PT&=Z%e}R7i9b?mgPKD@2f4`Y3kvG?n2GJ?jGe7UpvQ_nAvf z4GNSh7jj^q;DeN#=fqey58rvF_TW=$8t5e4OG$ zBGbo`;+~{%k5af2M@~zM+fi`CKNcRdjE2sA>sB_ji*nsLZ)4&F* z7Jn{XgIVWmzB(X9Jt!m(mSHtk-pRw3h*}DI>Ev+@KJ**|-^nF&3|r<<%M75IV(c&H zj}Gn0a}2l-jPeE|d+gV~ma_SlZR>dE!vW@uWL0)m2BPM@g;n-FawT_p zm7p+RsZAG=yjkDKWR7Z99`E`_QSZH*w2Ncga9>z=m&t_wi9+8PpkyB{*_8o)wHgN4 zyh)Zl#QJ!$t21oGw_o}MO^1JPTM+4 z#%1M1E*5UaU(^u{4+ zf#Wz!fOiH5m=JuwWEvt#nXd=1#~(>JX*y^X-!@Zt8Ytwq@1QS@902q5TpIc9)TEb2 zzQ*7HE{#+Kv)gCBUT1!^%Y41X{7B7weY^aK;u`RxNxt0P z?lFTM9C%|1Y(HPy8>|zw5U=g$LIkJQ!lCl8%9225iNP5ka*jwyzTYI{#g?>$7%e(z3ZOyZ7$KNqmgI}-R= zDt4&+6HiD9JT`5B`nb89e4w(VR^(x|UY6miEWjo7oS-34$MA&Yb|x9>_-jJ)H{*3~ zsAI2$@qHAFC&<4_o>XU)SYer620=L_d@{ z3hC3oIIJxSAZ%8^*B#xOQy!eD7^fi+;b+=@(OpRLEJ+r6e2D_}sGthjJW8!qc`Jgd z4w?(PMHhsYz-i9i?{Gny5(diT#f6eQdn$g<-_i89D2d-6rYUh3X7we7{aj^y*{r_SzSeouU}cWHuFhjmk0 zt%FcmtMh8`rQ)4z+D2)M`Y_W*S}Q0=$XPem(&_i<`iD+lY?8U_wmS7QPE$If@>tsx zAJF6t`ic<+E}_fP^0G;NF*AM2K=k4%%m|WH^O7fJ=BC3#(TQHO{+&15=hH7&N)l zkh4aJQlxVidM>ND47C>wv%R8E@ z%I67(O{e20dTyzr30wE+<5%?;pJ`RIa9vm94_j}SGJRp|!;)R8@2EGSz7uQzsQO;L zBSC#m7j`O^JnPQjP&Gk)H4NXi`aTkzMD=|xM3boRkl|b$Rx~X2eY^|xos{NN-_xh~ z)pvqC7L-hVlZC@J)HkBHUwz#^-9z=g`v!C2Q{Vbe>^|Y@H=w@hpZ-zxZJn8*zP_FP z>dTbbp(vkUr%e>P8NznkbDBqm7M^N~z&k?l64jV1#FMCTp`>`#csw5hN#1{7*UqQL zO@sVuoccOLlBuzNC|ONL)3Btiu%wq?jpx2*Z7S=RY*E(Oq{{l|;eKT;{AdrAb&izjYjamfcBQPJUW2mQee6@#Ha+^G zc%FMa3iy-scz4{Ipsb4hSXoi?P~%zNS)41*QL>?R!r86r8b>`J^3#c&ia{<4j7^}Z z&Ht2eFPp$wegdz12@D_tzLy@q8DVj-m!Ck9mp~2?IM-W+r)&c6{pPE}K%0Q)E#e7Y zG8bwx7-*3N;SL`B2{|`jp!rk5)Yk)*P(lB@+j;OF948Vsr1Z%=)`puRh$XI((1{*?kxDZ(`rK(qi zFp@_YMoap|0Jhhm%2fOaIY(!zdSjHsko?P8U~@P%R_~@#X1H!n80U16X;p5qf_vU8 z3Kt;@Q*yqSX%D@ri3oJ}mcCd|jF{4|6wY8bHaG1T&4!Obiw^>iNEyg6>YV} zf=Z{24V*{#>z`2i^<4ULF8%(E33ca$@y4KY=Q2N$=C3oAUzoIZ`a|`p6e=C<> z%cXZoES(d^JC6)zH_Y`A+%I1C*S#pQbj+aHbw44Y^gFrqW-h&aLqgp-VZ3vQRl4Aw zpHTWwYI?(}yRY;LJpp3sKATHV2wlCe)o1#ydT%(gk;7Lg_m?x%_a8alSd6d9DuM4AJflPO8Jx@P!Y|gVWa# zPSIOysJRM!S6gcaGOLq?bTm8?Kh4$}Ny`+6 zlWeWQ5l9fG5ih%va>|NW>_yHiF_a=o-iK#Xj{e!_nIG-%3PcL(v)F}w>+>O{&d><|=AO2}R%WGOVnRS04MlJWs(k*Vkz zObAX(l9oskPeoIbe=2%G+f&gOk4rig-G{+E6)gm5D!L^W4oVFQvOKGUW2xJwB;CzP&d8cGukrP)48m;|qkg!>>p z7Cy_RcdknhZB^*q=F+>!&>Lja<9YO6Oe@Ew)y}1bJu*V8ze{Vfq18OsswJMl!xb`2 z>ui_S>;GpYhHXJY>zf&-o|hY1^KDu@q2HZpjc{odxU{enN@zXg(#kiq#@e*_hUL0g z_#Br|PnQs;a)i*iE}^N0P$wY-eYaK+)LKs{kdeRMkU-S2A)(h0)n+JwJ4jaUICmkX zJK@uHa%%;#i}8||4AmB7>h-u3<&qde&TaqG?G-NwF=Vhsi^Pb%=Tf+4iL?M(_gl0` zJ-E|Gud9K&(E2Xh_X0IURq?ep!M@$x6D3_ zx8+P1B7Egpw5UmhoUOuvt|PT5&{}M0Va|Vk0-60RGGm#{A}<+g;vh4{kipu(`3YpI zWiAu?RI%rjqZGr&E4_L=d&s8WFbjd3yg(M%nEHp?g;(f(pc|5k)!l_a3v1D_dDNZE zT3vO+^^bmU3jAeh2y)~C^7Y5)}Uvjg!G@eDn(DV z3iQ*bwWwsHgxJCDf~z-5?8+K;$jyFnd!vNd#Ix_RO{ihZ;HNQc8D5#VJhU)Xjax3q z`~Z(zCgVeoTdd`wcdjPitu{*30w?5bLu}3Sw_*1t-VCg`6^BA=i{c z7s0(taHC-=5OBPy(c=K3_f`mk4&^_L@GdtNTo`f|Wi#B$dz76wT09>a5J~O*)(glJ z@9@@2{DS~Uv5|}M5A#r11}ymP@zTnH`BpoX8H|xT-F7OgAjk88e(c-eSwZjQZf`m4Z!fP{c<$WbnSw_u z;H(z+7WLF-y`U$A<)3mc~B^?SlpBbiqD1Y-_PX?&`6X@3U{QY;((HukIhm&+35V*om zpwvqME;c>Czn8!(Hi2G#0%v#$kR!<-5Az(HZ4FbFX=~Wc1mQ42RC@n-9`yd@GN0au>u$D+EQ@x@RN^B^H#;6~ z%XG71ma*+_^A(42*-;WGYS%2+$Y7r~!!hzE&m?;v<;Eq*N#oohIDn|jn554LIWGxO zYPN47VB~fo#ibn0#UTsYI5mxs^Ya>IC}=!_v_Z1-&FQq)k@L%bfiG1O-M2(Z&Uyhv zcu5Hdd>B2w;DC_xY$;Wr4I|>!>v);kC5>Np_FmW!*t>_e)z%84fb*2cGDLMj%xJDN z+A%Jq927&&euhwM1+5@sKZ9vD%FOK|^W)uo#AnEPz_c|bxJxx@n1%4#@~GmK zWPzBBE}j|(Kq1?l78j~vcT z8Ydl)t7HZJO+mXybR>AZ;5&`dcuH@ah?gyspm;-zA-MZ;27Y2@i%|7;FyXEDBg~sl z8z>emTy~VSWfbX0_$qOQM#F%aT{zsQtA>j~HkU^NAsz`lHBgNNaN)#4v@EINIvJmm z4J~5ZCvkCyc=!P3L3sqm&UJ=08pD=eWzoS(is|`pdGmiQ^Pnm}^PcPc`i(FDR5$rLaZ{Ib(Z9;fgJmEiNzQB_|K&7zMgm2`l)=J7NUHGmKa|@k zGMV>Kgm^Y5;L?c9(goT(O3GYGiG)i*MOn;jrcVHvWXL&Ze`7I}Vq46#<2ebdHH@5I z&D6>+M+h>22!7#R;WuNI2Pt%|rn08y4fRE>8FhY|v@X;BXte)G?RYC}#B zKdt>-fX`qS9>g^h%_v_@I)DeQI7IZuc9GhY1!y!p7JtD)tengTNMqZ(ZdO|64-YC? z8UNH^LFOP^$oa^E5Fxz(^OAPXRD$K4-Cb=${sGBqoby7?KGO%4Vy^T-rKnj_lycc! z9)!z2>}A_!^Wts>J8d|-H1sFhS7S{#7S0CX?a2`ITXaeaSNCs14_217PgCb6B?2d?}(i8S%&)=fm@$aKd*&^pf@?!qeZ60F7LIyzI!iv zAo{!`*pY9H5mx=YZj>j?e>;SJ?UBCz{mo7Fb<;EI`Ik3+0@63VzkWqK1ejXP~XQO${LjL+N|4quHo&M)| zgg@dqzcS0uV;?_{`*?Zm!#wieq&(W`e~w4&c^4iB_<0=U=kbc39$gP$9{F!l9_{o$ z$77o2G272$j-SVsSsoq-F^~K=DUWvgpW>0O$HigA4%7^BJ?{B0nyJp!^5A#L%=FaE z@ZCtBH4~v-N=nh~=sWVASNf(qop!1oJuUz8`F+zFn4dK&Bi;G${rr$DVJ;)g9ke7# zv!Du-fcfvV?v?ITyO=eE+2q3{VE#V|bDm)8D~Nd*O$-&JI_E)LAg^!Np<&zx1OW|G;1R(VlzVJ=7BlI@| zPnhCc9zaE(k#ZmR5S-A96MBIYBy71?C7`zY&GtOb%E@!EJphst9&xpF8m<$f?3{Sv zGM8vKCQ7p?1Ltd;~E6h%v*|kuenP z0=m=-CD4-sQvKCsv4DF8Ey)1fke=vLH3%BNQ34GeQ9~YORY^j3PQWQ(N}#S3lBB$4 z^T8VB=Z|;~#SJK+=oXHe^rLFd991;whUHJf2U`C*T5tM-?>DBa0>I30#(8Adg(|U(w0T1%Q6o}JM|zJWjo%|l=l4i5_&t&Uzem!Q z-y`Y9?~!!Jdn7EtES6K2$f>j=vj~uGp0>$N*=6d%S}4$p#~?412G6Ap=h9Gf(#oS& zLWmO}C`z~^!(~Ia3nlu}D2v{0w^ozLsnAU#${gUON*7P%KllKvO^MuCIc>p@<)F~q zrA~5Y{KwjW|Ih|JAOnj8ev-hW2!G_pvQ8$Gc(in~{EU?iX|as=V8tnYS4P&R)=V_M z12$mtsx?#;sPp0o;VQ5n< zh8C2iwWx(IzPwjS7B|JYePG@~x?|3@5x4%AF$q$fn<|vr&@WozgVJT4x zO9eyYgrivaIv|FeYE7?j?`5grDlXSG7O!CDN;hD`_pMye&5VBg1a{=06ALp$QKL7{ zhe|{p3j?Q>-XX_G7+<G>GMbC87!F;yqcf)Ej$ofSsWy;Gwz^wv(`_Jp?UYt+mfHR{aLhtSw@p$zc(e%3d!1tlf& z#nuW zMxRPTtCs@1SrC!IGh$PSETcsj?VZS@z0vWU;uWeY((2E-Q@47>TY*qA4PWRlo56BX z4gWx7a(d2l$Bjv>EScTPox5VUJ4F*{BY)HDO!RZtDFvRT%{q?1kzem*;-VE%C;6Qb#@9Bc$a8!DJWwF zu2>|BFkvZ&2}@0w@QEZ*0``W&&mf7enlZr^#THA+je!&g7N6Y7#0Z)Pr=(Ih`a(RS zgpp+vHCI);K4Pd;y9c;-VbqT4g2mGni>qV7wOl#$3qyKw9~%p<(~u{%0BW=V-WAox za1XH((nJlZYb{#WT2#|oR2y>cmW-&vnAW1TtwnWC3KI`BMTH3*o)0dG4p6Ml{2#X| zs*`p5PS?E%2h~X%10S|t#H=e&EQc>6!9^sIX&B@!iB90ZgLM6q5l!9RTC`{!mi4O) zITChqae~~^=uEV*VQM~QpGW=ef`?QT^O2jKqiO1~k;gYDYc;mFe@?{jZwcj(*e$_B zQJXtLE8E*o{449xPiUkfYmcHvQwFW8qrWAo5qc7Avd!5R;jVzGH9o@Xnt!E zHmLQGa>eBbA3{r7&PIZy-1f|p@$|vvZ~)6f&YcX$dPmWz&>Dkol)~ZQgHPz}2MOgh z!H2}J7tN0a-@v`af|}sbXFim|G1|pUvl8*)3?BA@SF~>2^o;CvA?IYt9t%Dk%d5+6 zEn3F4I9tk!1|N=4?Z6aJ|1FJB)9X1?(G!*{#kRds*qQOuikT5{#_!C~&Y0-^pU~5u z7)&`I3XjSS-v@N((T6aQA*V@9NonG4XyQ2*C6ZpJ z(+*aj8+;C$fQIO0Rz#ad695ep`H&{=)7ifg%4>pmD@~Nef(t^<)bo<}tuyboHL(b5 z{TJ>I}umhCcI1ac&T}_$N&FM^W?4VM@;zD; z-K@ZkH9?GsCI;eJMcL3s^d<-aqY2PFMnFmv9f0lx{?DTcNW-4>Xp~Z+8Z##%<7_zE zHPe}29UFSu@9sRpzqJ6op>s+3@AU|O@14{moT3Qr(j%xC_aEYKr5>p19~cRooSciL z4@z~w#h#4>_D@b{s!Ip_{mGHQyDhsM38c7Xku4Z)KP*iqskW`wO0Jov589pqxk?Bz z3T8myfD=abb7ZlZo4uX^2}!mx&!~RP0}!y8<3VrN#{AG9)9ORADS|k)$9J3N?uk~B z$v*}Q>m9qv$6$BabS=rxx&Dv0vmcL4+B^;?w($EIgL!>3LN< zyGM4EXbUoZvf62);T}I?bCX1(WAvWnj$ zThO1G)A=d62mbb6Q_7xs@=ub}dCH~pr=-F5^}lb8;*v?`B)2TFe$@^qFlzzhH>)vj zF*DwKR=fVmYgZNfol@E-Ih`3Uoj)(7kDGQWrGQ(OM@nUOe+MpnQZnA_P8)B}q<0}_ zNocco&H0_uJ25$(Q(ZcLUV8UCyOiFiQHy8Gr!1GaakoC*>R}demISFxvrFiM3VB~) zBFC3PF9lH$-GZHMcc3fqqgHX3$p^WCar5lUYmrpm7Zv&isRraUJ1-BeHylf_tj|8F9#;4 z5<#0**d7q|s&rZutm1tYmAIT3Ed)0c=OL=bn|V$&8z$SV5T`LAP@K>Jp~QkP`CElQ z^7Lsm7j%RC*2(i!GEcYVQQRHPb7pVB=UpD&_&5>5?IWXSVop zaKP|FHX9Cg^Z;UvjdDkeEk%NL;0*~pRd$^QZp1WHgdV%A!#o&Ceq$>B01p!^l~jM4 zD6R@r2WzMaatdfprTIVfz@M@~$CNIte4< zxlmC^8HedSh-aIw9(a?CKamJfDCR1)0!fynrAA4j1exFj6KaA}(4}<7{Zt7WxOsRG zkn-f!uuf||B7p4Uv`q;Y(Y?Tqwq#~aN>PtQNzo+Sr9w2`Q!_h4I0An#{u;=`!Si>- zJ|jT5wSa}3pyYE-e69ng2b@hPNqLg?SECKvOUmu;N|+4@W?=RQDn$|L&SAP<9Q1kH zYG+AHXj$z{9)Fue#ffNtK}c+?UyHhsp!_GbPLaL4k}u_vlE?+5JL8p(l{cN6=uPkN zc+=LaTt5c-dao24F|+rq%>}@0wgKf3o;Hc((a0kVV2@DC9-+qL5o*~Z)GCkgESoxh z!6TsiQHjdd6xResI_;>ch4nB`HN5IDOV^SSrZEBX1dcZKGnLe}CpcAp>*TBCr`nV3 z;P~q$76O(vHg4uN+0=(x61J&npHSGKTdD`~*+ zYuPh2BJXLssJfD19Z8V$PE~o~8EP%haFC)vo}mt&p`FRBGoGL_!ZT<^YR`}*Nt7Vg z2`0odw7aVE#TQ<9f&4=)jbNx|=cD%a@Dz21sqk8lv8#e=TAI@A^?~vIFN%{Y=rL$h|+{9+LUZj@F zUTEGVCrL2-3gHgG@kf{Ql7h06vdfjbH4&i2sM^igS`@%tBjTlvo;|YU7jx~0gTX*7 z7=Yu!7~mo0`dG+pxh-JseugF}F>r@>1e1Xf3&gl9S*r-yHVTWe`om}Z7}Nv695b9% zq9>NXy@CZVpteu24=5I>!e1x9@U~7lFKMnpd*`HdXNAg6S4fbhzo&k$QCXkYgwn<_ z+pnnf_6on%m;W01t)>H-eb`%l*r$208#Fe}1%K+`gA9UyTmi}TFi5oU~%QO8TL^V(D7Q&%}TVEefg|>*M3R*_ym(4hEnyM z+#mN#7c+AS#2aq&wioS}{(S+9%pL=iwg1UIx&JodmGXnu{v)-&!io;9#KHII?XbQL zxs$}LKoPOfaCTn9p%?gvzgr0*P6$atj%dlZb-AC^msZypxf@&4FJk=~N(T0^yz-#j z-~AW6(Wdxm^lBI`0r9SgVi{f#)BuDR>?vH?E$ns=!E8-X{Hf1=@UD1UUNWX49+3j5)$6R%ZmDtAgq(Z1U>H^ljxUU6 zY{aw(E@Uk{uqOCTYIGD{;%=7sGB&XhW4(3fNp6`t!Pa&xcz=Ud?ZD;LI_WB&Ic80; z5hEHjZ5(B%-8r2kfzcZc`g(~5DEx98ZwDt0wTw>O>9!rc+aB8jRUZ!%<9&7LaS^qp z&&Cvk9x;#^kiwrap@z!iAF5=Z!$uCtcjCYYU$2dlFVroX=FjBrZcrffa(niHe{Cm$Uy{T(a4QKm5x-_ zONA~RtTi~QO_%`WMb3*P>|_%})g3oFpQ_&yfHXL-tKVqmPG}t3X`}PD0!a+g=zJ#a z(2%%E(p3ynsZup|wGaDj5B5@xjV_yG5KLrsMUA+Q?`XZ){qhmyKQ+cA!HDW4q6<^7o`rQP|c z{l109?WtbY6XPBwWy93mk(zG(-6c)>V4v?v2=08NszIDLA;7rfM!VH{`ZL?Ytr64} z$qAjL27q$9Z}Ij~(oC^mkiQNf#v-OlP+~f54yKql!}g^dM;r?CKkwA@VDkKkX+; z#u*M&zqLQ@rhZ%g^iT!T9`ZyrKSf@R{H=~?WFF{nm8!A(`mkSAj0^UG8atUk%`$bg zLM4wsRckj&Z%f9)qr83HAMvNhNKr~G4bI&%g_Gz{XRt8#*q{EiKEa>rF2v(czvGL_ zFgpC>qrO+ip!O@S-K9S*7FD8!*#6X>cbJ+S!dC0Y5UhKM0e(U77v^fcV zp}sk?hAwbuddfSkT|xD8=Bgawe8Uw5zMP16+j-YDO%CZZTD0<|W>O>JsmLQta~>jr zX=HWNCm(;p1>yjzLu8C^Zwr@HOn%KfBx#nOrBvKN&J8ueHV?wQD z8j^^;(IRx`kvTjJ`Wx6$j`YgW=m70252h55Q{8sqq>J4Vr|mV4>P*v9G%8hoWl!VS z?_?&x_+7+=L@3ek)-d88``s;HB>3HQ6?=R9?g>o_?~nW4Q_h9o4PLcNzgsKSbmfC~ ziXYl%u9jr>nE*$#yUIQ?U_rk$sH+zY%#!^Y1R zYQXaJRaQ@QSW*ll)qN#d_e3;n?9Q)m_j4osTGaoU6vI$|Pm+`A%v;jJq;%|={5z9k zn3AryO7g|zx}T(D!0Hq?CX3J9PMW0NLLK2gSr_1)yeXSvB5F$qI_z?%S)g(WuoIO&gK-BXe0VOP8)qEBIC)yj#i4 zjFiH&I5orBAgN%3r)9nrt5u0|EEbc3+qm*vOr>5S-4+RE#9x!~6WLz2+O6rdm<8#VGMLhkCo9veXQH>tBao0VZSucSX( z6aRxUI8yQ_X!UfLF4+JDeFl#ZIdXRTe0+ zPa-dmkXk2O3~8kGkf06; zw%pW3u`$_zZlw5|uto_ej+=5?tbtPpXa1$qNx6FkS<2KFSEl%!vk_vtgR6n4W5A5C zh%v*tPeb~yj@03hrIsJHBx zBpL)-$f+|(Jm;+^PsFaZO%P{>>}op)r?8`_7BI3@LmIoWP?mMN^I`%i&HF597c@;2 zw(D7g2F}w%xZv+j@@-jx+ngF=Mua5t0bCV=df-L5^XPX5bzI-XFPUGD# z=y4_r!`)NODcA(K^6NC(+QdhhyQHexEp^V8TW;K=%y+WUgBbKupg6LRGEb@FxWYQh zyp*RcP~RF|-?36(>nQUNa-s?+KCPq7Wg;jtJ9U)#-(q_4BI4e2j`_($xLNS1%5!-6 zLv5|X@*B(^y!9d?F%9#8{=>`T4JC78`DOu84zH+?-Fr;=(utli5bSX`J;YVQo@#H6 z&P???c@J^K@ur6u>&rM?{r2_{_sG2i-X7vFf@=2=UyBg~WO|5?1(euB+5f}KG+@W{Xg#BJ~uCz3Max;nsNsq~Oc8BVCsYVV4`L=CoGB~g`f#FyIJ0Honi&6V+?dZYigKm@S35a< zM0cqj^|@A?D_)&?M8-o6zi{Fl%Ff~PTq$}EZTd^rnuIe_Sh07{Cjo?X0=U!QBR`?0 zH13FO+&e&0N##r}n2awL$t4Jwv*h8P1upoW|FgkY$r>M>gN9xLMx zjbn0Zm2-t~J`dT!gGe`=;k68z6ER6_O+D+)W2Kw4SS1m-6PfIc(mOb9r6t?Z@hr74oT@2MYW_ zTOp@8sBjG%^^=VCv*%aqoMqo$G{R0k-Hb4r>RihfeNxM>N9rsBJm&n2ts2VyYg6A_ zD6jrcc$N=)TUsKpDwhtHtBdc~P^p=p(pU$pjm7kl?x@#3E@kC#fjuL(AAr6^YO)Nj zRfXsy&zS<&rP!3tb@bDBYHeu&h$Z6Qu~gVoq#SwGWpJ{-G7?DwWJMLW}fX% zLq)KMUhDKlvdmj7Hqquf-Ib|12)(yHn@Ce@JgbPiiMEB_ucqqWO81_EfInvaaEh~{CAG^2O>dZn% z4Rfjg@N0^6>@b>d6^Mmzt?)hE<4Z+p6i}Sj@Lgf5&Q9GzVx@YJ^a-cu2y6vv#6IR6 z)I&7x{5f3q<{qVd4UxRr-M0%9_AC3$7Sv|k@-{-iuk00~NaI&_RAEVho?rQ4OhhY= z@GFOPk}N{&`j!2>q`&A_ezS`-2K7Yvl^gNw8`dlONBWiC7=A?y{Z$M5ZXZUpjv^Y~us#m+*Novy#g&s$dZU-rA3{h6>4X zDam2HwT5DU5O-3!*!SBj4fY8_7~=WU$?33DtJ+@d7yfl$nt6&8CZ0-qy)3LlFHcBb zNXAo1Mxz(g*BXb#zPg)e`~N$O-45EU(_$YDng&|zJxz^K7W-**0y!LBuf={H#0|9A zkD97|7JI@K0gJsACt{tGFB6MhOZjTCcRjEki(NLeK8t;eO~F0QUj65)fIcgI-v?4> zl$E|5eZ#iWr+7(!(MrFM``t-4Sm}@P?6cAxPKdP9>>YTk3wo02N_R|jBXGDg>8C$= zGN%bYudF|R_n7r&il}%GL-#s z-UmTy$9Wghb}lK%j`Kc(q;Q<~?gAKB4#l`iqFul(B9OJy_pC|Loj#l-vEsNgh}<$$xbQVWyk!E4~U_r0aF(yk)PsP&fd9^UtyPqV9?(>y~=rN}^Ktq%WFMC#E4MzdM4^U2D+Nl7}wYPQ9JPYdZQmr?yoyQ^<&I zt${mOdFTy-*P>_-3YZefG<~3*o5Q`&)01M=(G=)uA|OdD|FbC+m{eshouEa9RFg{H z8430gxo2LKA)!TcN&dn?M~zHP@dY5$ZvYc4y;k zXJ720x-QGkcotCXvK)YNG8t=+m(ELKU1{`Bzx&~L+A*qovr!}UAEu}g+3GEcU>@l? z+u7?LX&!5IT1AdT5iisBV)v%~J)X&ZUhLE*QeD){e|vkZC#_h+a4*T4`Nw`Kb&zUQ z`P}~+?N6&pa8&ZH8~Mtn|6jwn+onS3AG7r4PRIlow(k5`Cgkxz|G z!R8J81~HK>7T=^@s+GPc%u(h~zfk$?D04ICrz7l<&w)5KLUd^|E6VLI{z%zabw=xo zlx+_L(qrq7l)ZMcawhLynn6? z>>DXxjq!tYWuE7$s_pc(DRtROXBzxPQZQC7T`<4-hVCW3)!QQ~_0f{=OS6f!q^{$e zN2rHI%_qmWoU|#2BEg%SFI z-PgfZFhUML#hlBK<=U7L`fS45XX2R+xr8<^RCZ0Z{HT;v?Uvsi^!je?MVf1;p2m{+S!oW7`88Wc9 zy)9yz-Vi)Kqs{V{dy8puv&vBM8|nr8uAzN;Pqy0i0(KCj_1cS5WTVgT1$@>%qqjYSthV$L1`>IZz(Ee&-#``>mKpZ#z9ciR6Me~SM7_Pw>lLq_$$%vc|25bT3s8-a796=G$fPuc?&4>}{ zt_kT`LpM+?8nYvOh%d)`TPs4M|c+!dYZuv-CS3bg%+}u^RT}S_Xg} z6JcuZIY@!A1<>G<{0v%{fv}Tm^n$tb+~cG?HjQLha?+YW4E%JL1~Uq=VcXq7hr=Dn z7R+V(J05G7S_j`Ab<%>cBbAG~YDKE4a2`j|QaY;rlgtBjpV8@(#^;evmll4}WhIa2 z;c+tAdGk$A@4fn;=#EFN5}wxJHgwMA!fsy3n5tC>ijW$WFYTrF8mcvm)*6c7US($^ zh)bG>Kv5E3L6A^B=@4|&DuLkcJVNl`KcWznfY3v5rq*mB01j$}ZJfXlLREobbZKPj zX-K91fj5VmIR`b_j-tiIMehRDnj$Swz{Xzc4nI2SD%fo-Wks-%&n-yXRD=m z#hfIv(rEuG(^*nucGl~rP{oWH|T|3RiOwawg zf)qx<9%8Wm2_c~qn!e+S^xRb|*$$PgjMoq=_WNln=3q>v^V(Ok(^*wSE~fN9u2aHC z?~3=8U3He^u0kKoBwkI#>E8=V z#C-5xOyud`g16B8K5ba1e~-x~pQ8VMe%ovOK;zl(^paFU6DVmo*ZI+$I&7e4?>Sm~ zzAP1)wS0_n)X7|gI=6W~{sIBa==qo;0KxB>@xC6WX0o>Q+w+A;l3WfZp5#gLmo5Zo zzELn5S0%6_=U(QUR*7vTcVFi$SSc6{wv^nNKf>8XUl{j+ec1Ki=Gmeg!^X3pS75ys zHCsFZ9ayu)Y}E?ccrw=uQPhlo%ofF;$uO>Cwm2V^c;nVJInz-#VzxLGV*6%`!~E=F zezFYv=-HxF>?vPU7nm)EBg367hTz$qEjE7&>ut{#Cz#4a8&7yXp*MGqL^0BaJ6l}x zr_@x>Y%xjsMa&jgYgTx+*h%_Hwr{p*9VOPMpJ*dR&lXD%n*pvAtS={7BtsDBS?`uTNG^e=_k!>aXAWxW{Wd4JuqARDgo5Av&Eh$6`U=4 z=l}h)#h+M-+q1>+*P)rvyCPS7?Nb@g79BTe%lVzL;B4_T8Y+6W=y6lsvqdM!-1)yjn9e1DBRQ2Jb=~>Q&Wg~4lUvJ82mqu6TULH5vE+{l>eqz{gXZ#yF+W9DCcKV}` z)C)|EG3FGTW308sV`?*s4yMZSeuo^7*xFnaZ4$Lx(H-E}-{mH1V=~$Cpg<3nh=Csa z!F;bDM@N6^T$jy-$?;~|X>d}aX4(m0WzDoNtrh0#Y4^hkSYtae)0UWpk>3O#2qE_+pdHH@ta=XpH4Gwqa* zAeueX>i(8$<4C_a(8egU0P<$q0U~^q`u}u=*OOEJ7Pene)jYWg62BY2;$AO9h>^}lV+xE0)C;H z_S+9cj#OZ#U5|a{bnCKml=9Cl&7604`}=3weXz8(XWA@iHM}nSmG&>m0Gb}oGwr?& zTbI41rwAg~Wp9kCd!}8i!Hab3vM09WWH|G7_0P1%l#&IN*+teXdP;)wqIR0yZBNRL zzQAk(*7DoDUeOat{`JcDdH~SgLI1w(Us|uM#z6C|XdAeZQC9R-G=*hFaYl*UeQ^bb z_&reAjrZS^Zd}KDWfZE7u%h3fY=jj(6=M6W=;!L@seQn(Jj1Y$wxSQ}oE2KHOw_|l z#)^){vuj2Bsc5zp9bzgIZ4B^>18uzauF;0OUK#X*B-OKC*?@vo5mxjS%?evloI&+l z(HG$#n~?~y4m4s#ThR}27|)w)j1^ssjEJV|qC(kL^ddC0_LhVFf}pt`S!49$u2*{2 z`1F&;iY`XMkQJS+=>aR6BZ8-0uUv^zK`UC;=I^(nkE{^OXj{>?D`6}{>y`GOg{)}N zJ4Ru3Mz?l=#fV<7Ot_|QE4l_E`n6%LS1$UEtmsvFek zrynmDF^rwZiYnXDH#^uV=k?c81J0bflDS4ISb{97KzA^Rhq?Pz-v=<#N)9&scG_g5 z^6z_)r^55DB@QW=CNyC+#AOwX(ouG{^G{?One|-(Vrm~umWobwD+Z0$863RyMOT&xwI_HExsaK2!daDlG`AQuh^WK zT0>OO_Cn&Gqp`~9BUHCR1n~=K9b2rA@mMY$p~}@GR1w;YIo+=?$lMk(QQ0CJSM(bC zOpw@X=t)S@h+3`ly&NmnHT1XU0ZZMJjGQE+wT4dhkVX(RvWC9!SrO8C{$N={pM8kC zh938Gj&(q`t-TyJACJWN9^0NYo=wWExz5vbrP|^vYBN*oMcYsj@9y!^IdqP0 z5yUs0hUQZqHA{S{;UPZX$~VI{Ots!naXTy=IB;MaX>m{QBoOaJbKyav&TLY*h9nNEwbdD;&k^tu1IVOL8-pY~Ylydh&HA~6j-_di?XHgs9Dbwfs8H*Xx)u;Ix0LAs5zzN?JG z36!tn@bQ}T<8b_cL` zlh+y^D9y$;J)K zOgJxEG&CN4r}Su41h*@xh6?9Q)Zja-x2vR)zJEsTQkIdVPpqhQbnpAoH|Z%|{V=wj^r~pd(vjQaS5-Mx ziJ#=_;fH*&oOYb~jZ7iVnQ*g9MJLdE$2X6>7&rna)4)6Ka)UGcw8a=` zX=nJ>UR>9+CJ)>trGnOE#74}t=8n6;cn(^VvvFo2WKE8e7qWaaeA}yqQ9VPxb}9Id zmi|nRL12b|XbC{7MT9k3Kcyj6|68k0V@<9{cF>wkZ{}GO8qD0jh<06hLH!ow@cL+A zLH5Dzgq{U4^Z0HpWa`HZADYLTAh*tWyagh%4V=fnM!Yn79>0q|*Fe5j!|qMF6E!t( z9>3D%YtQ5TI(f!P=JAzP(m9;g`-*W|O!;b@K6ld3<2zyVhg#0uzaxWG{b~BWt@HRq zZ0>mT_~-C*)6e7EVIg4VK={@#EDe{gBk$+Mf}x&4-CnCsGx9Q!9UOUkH1S5Bv{KYO?wnWuC@im!2BWZj zbKB4U|J%INP_N^{l(eYN>)1ikd|n3~!^Mt0ypA>~mDcO{`CHTqS7Jm*Z(xhpu~`T9 z;rTMKzodK}*s-t3>u8YQFjl}!^dd#A@TEcYh84EX#CyT~d^w(S{3PXXnTxvTvjz^&W#;Wu<#YomH ze~aVb$8~hL-{QzV-MQ~Rv9I2@IP#Qg6X_t~#J|YNaIc&a@u1w8GmXw>V@CD$VEO1D z2Q}=|Ic`8p9PMo9SuD=D#rgEhtIOdR@fWY_eGd$NsFC82XenaaZYqVesQ1R~^T;fYivTclbR|V zj8-Q9vdvnNSe(ak?bA{N^=volZS+*(H4=Bl8x*Ci{)FrvzYqw>_#fdj{r| zZaBv2e7(EODR)r5&MD=e(wy@0Z+TWg+vw=Tk8P|^LZEHJTB6RO{eId%B+ZBQRX^54 zQ7SFgU9?tU?Y>6Iv+ly zI&tR~GMSGCNBcsh!f3BrA2HfJ;eN+aN?2*0<*{!=a+2v;(o8>iO=5D~qIhXrWSnsW zEDU{&o|AbFdv3kxQq?trxSHEid?*UXvF+a>3JBHdH(TG+t*<=!0Z0cM2;2UJuk3tz zrsrjOm@cXdQ&m0)IA+4*PF}n8*;ByG|8kt*b5$LiuOG@E2LO)n?7lD3QrdE(Fk@RHA2{p{@ z_%o$tSCkx2)S1FlGLn*zIMW&SPazO~C{m6hk^&wD>r`UG0GTRj8tK@R5gB@tbXGLIt_=EgHqIG%JGmO<5QJ{eou=@HYwJ zx9EZYX`x>T{GjLdmkN?4lAbJ?3;Y8u{4E5(WO(?k)<%(X6cPO3QSf01zu8wN{E$1} zqEY-x6T)xG2JmNm%N_RH%n*Ky9{3jveh2tL&-kT+WQn9FODci?3=2QIJDTC)w^|!T z%27n{gGa#!A^db2!SsK~oo~@7ex(WFH)UP?82{aXKO=Mv-z95&Ym$@P1IH zO0%C!{U37YTQrJaX+ro-*#Q2@z`rHPYp_KR{C^1k(ZCOS#xE5lOC&v6G7k7pv+zG8 z_$9-`Z?!gxl%t5?2akgHf-+V9!%KnO`4)}hSDFxhQ`W@~`@aerlmmal!vC<~mkbZT)!Hahjv|5|JPO_o%2auvmjb!-EgHqIG$H(^ zYyf`^@Nf2NR{Rz{@b4q|*8xB18NXDJERl3FgTQ~Pg@3l-mkbZT)!Hahjv|5|JPOtX zWvZl2STp`1cfLiV_?0Gv-;@pD?~oGv|A$wz;!D zv45vn_#YAclHuXES{p^mQAF^AN5MNmnJUdDHI0ABoo~@7ex(WFH)R9(6Tts_kk?>~ z9{5id{Jnr5^xXbZL9#^B=?VDzTlgOp{F33}w^|!T%27n{gGa&JL76HK@KPXmzD1+> zl_rGWlnvk?2mHTzHEa7@^uT|<;4cJz&~y7s1<4XgPnJvo{(ctz#{|D*c=)Z>Mv-z9 z5&Ym$@K#W!N;->R`ak5(w`df<(uDAvvMzqie{+E!$7Y4Q;l_rGWly&jL{#OA1 zuU^fH-=YWpn+5+W;0Hb9mkN?4lAbK72L6*Q{ErKM$?))7t&Jk(C?fd5qu|Y;OqFII zn8rWk&bMe3ztV*8o3bu`w0~~3*uP(byarqJz<;;k-vs=iXZ%t@vP9C!Ed3<*??em# zJi#v+9)7E}QKTG21V4Bbyb+YCaz8Hxa_3t#ieG6$_)XaW{=UHfvsbgWzeNxHj|=`z zLca*~j9)59mPmTCI1OM?Be)?J}@stb?zt!3(QjQ{m zA3O?H1!bzF^C1R5(Y|#V% z_kw>R@PnT5O9f>3fxia$DNIHUh4{~6!7mveeyg=nq#Q*AKX??Z2+CB64PT*w-1!!b z;#Zmwep5DpKjS;Ge?J6y4YufkKXWVl{|@kjp7Bcsnw~7_SS$ALI1B$0!7mveeyg=n zq#Q*A8+a7F7L=)yP6e3$54rO#8pW?PA^fIn0Dm{&ukmWu{%_F(e=EV?R_GUjp7Bcs zwD9M2G6TSWtc8E6;Fk;!zt!3(QjQ{mA3O?{2W6_<%S(aW`4)}hSDFxhQ`W_g`F{xT zfA7_-_$_+i-(T>b0Q{h5{89m}|ABuJ@E>F0e^u~HhKJv3Z4@a-5y1~01^km67z<;EL zpYDq!o|56=w^|!T%27n{gGa&3L76JeMlRup-1!!b;#ZmwepA-P5C1;_{NDz74Yufk zf0p3y1^l4r_LmB1{SW+;fxnN1f2H7;3=hB6+9*W-_>ZvguM+%{;o-Mh8%4@dM6iKJ z!IGd%m2|4X*gwdfZ_y}zr3v9TWdr!<0>9(cENGp<7CrE<5&ScNAM}i0Dxmd0@NWYC z-WLAX1;1o?_^sAPk#ZCf{NPcrI4DykomVjUA$Pt-qxh93gx{16;I9DwZ@iinzeNxH zUkd(Jzz=%HFBQ=GANae_K`Yw-Jlw+nhTxYB55LvgC{m6hf*(8zUJS}q+15*e-1!!b z;#Zmwep5DpKlgjFe_wkwD}IX}_%{mvO~4Oçn`XBg*0RLeY{vQOtWO(?k)<%(X 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⪙C(Fd| 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

d`dw-^gY`%Y` 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%0AqB9aPU%OA*1um4>=htBCnItu`JHf11$5$ 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

HS%YvalAm+7;bTFJ_QA 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

H-+dG2meCmu+M{q4BR!KJ2nMlp*?9O1@ zSJ2zgK%;uKUfmWi-5#&r8g280>({H7>7|W0-GSv;kE6dCra}RCPZhUb>s?}mIVepg}>&DCsuA|UP;8eBfbc{z$66)hnyava?}j!!gKqG=?PS zp+NmZT%nL>FyAlLV$`pZ zcteLEOai2b*yX^d2Rf!U=dqf+zvH8#m*D`FmR|mh5AZ>;=>-RhxA6EnXZC$4U${AZ zG&-WcPC8*<#OiJ9v*dLD5t~_^6M=6#VSfGwph_pMF|i!LV%D3N+lv9f2>jqde_AoF+#w| zzTb0Z?w{RFAoSNh@AE!y+fVTBy)$RdIdkUBIcLty*rEEXNunH;LkMkG18sfZ0JU-} z_IT^2FPS6mFv7Jbw#~?pMoJsf8ut}N*d87 zMxZ{#kpL{!;NS28BpO{N&(feS3!pwJR zG@Wc`bLb-glza}1q_d(HTm+;8BcB_Z=vZ(8KW@O|!VzCDKuHPuO%7-(U#E< zAH(jE{85@i|HQ9q$%c~9r}Pbc6}!XtQ_uREs$4a1l6DS^w3Di?7K+i~^6YlL=U8ZC z*o8QIgaS&osuXamTG!OL5Fj+)><<-FX$tl@^aVqqx}@aM)blElB2>xz-w_hLUZ|Hh z);$;CQ_w{!$QF8th?L{D3*gckA{b|Zi^*w|$)fq>I!d^*yaBfdKIw2DkB4iNdlTPe zx%Cj|Na)wRek=4c(t2>>6E^HD(uORf87UK-3LPX2V%rOId+9`nuoJfd4j8YWww){Te3+m5u1&kPmWh%y)E# zp~3$Pz;lT|j|p$Oa2A@dFbnnxJsc_n1E6>tUC&}BZpT6k-Hrl;WmGQTday#mevA9| zN#MezstPwixO61e7H)7A-=qa1^>YR$K=eTBbvjYu%wGz?m#lLNkQpr6ZPE zWGlXjc>}?VRp2nPG0(-jIHdn>c9amLU09utEA=NZG^*SGic)m4ge^3lfPX|2FBoMD z<)aZH*)OAr=6@^6GW}z!V9P$#MwJ?2#=&~it)n9C*hg#~QR`Dy6l)(mr*A;P`6$=o zTjKtyhJR6hqynw8Pl4TGnQCDMPD$aLm9lVrl~P!P(@E9~3P8 zLyELz>ENB~@RFjiF4OV&8NTa|$8k(n&PR_`?16IjF;>R5@Am2wb z^UBan#hrvd*_vcPPJ#h>EgHp56l8My%T}af{z3^$13}jcivhWVI3dZe0yXWD{~($* z$p5}Lj)urzfy!7@#W}8QJ+8)1S}+`h(|KP~{|Wn%4#U*#$8wkogge`hk1}Ubh1_bI z_k1h-r-c3Zx?}zoc(KMR8i<@AC%Q<>N>mPt5ZHA*5S08o*;z$#}&$y+BoO&w+~VE zDL7eYkun7?WD~5-+6WFqTynf@1>Z_W++fG?HAiI^%p~*5R@-Rp2<_C^rovG-{Ks1M zAFB=f14qKZf1Hi!-|9bBTm47Jy27WYItv>d3m#|t5A3L6Cvp}2lzqAb%x!@OiHTEL22f360m9Yo8+D@E32GlVdtz^BksLE9zC}4x6Hp+MG$^Hhe3Y@YS zzGGFw^{T5@H%Icwajc81A=XLX@!eyrv^a)IqqJ-#nj%l_b@+}`nvggneMdfqi#5@J zT~n1*T!y53kE_{xtdQPgS(Sc^-VoO!+&w7uBZl6deZqS*t{#LdiZC!l!s0!$JkT+I zbSf9G9I-vN5=IhZ+=c&0qBgIr2IEkrVaLe5L8MJpk`4UWdzA7?65yyj&VC7W zMvd@Fst44QG;lk0(l6Oeo(RVO>yR7LT*5E8iNm3G!a7Dr4+mz*B8NqNn12x zR_D8p=Qi1!lRY((%fxkZW!$Jpqw81ruh3i4kC}rPy52f~=5@VAe#~9;O(@sCG-@~& z=XHa78$ks;1YI3e(m{UJ1b=`5AB%F(NVkz)EY}5&Sipz!P5$fsbA&ru_Ro(^KEZ#v zkJ>Z*7v>@PFEm~%o|FY8RzszI*Ws&Z`>}9P|xKd71?7z&@6$be))2Yv7zjx@r zkYga_b^aBEpwR2Gyly&Ho{LY?5EF~2XM)TAix>y<$w}z|?g=nghima)#H6qLC9L+e zWltEcNg||@?d;eXy9;u0At+*#65-~bL-u)nNRG$^?yoM$E^(zHd4`;h1Ng^~KRplR zcY43kboUxc=zNS`)1u&DWf!yu?fx2?8wP5m{g1%wV)z>Z^~$G&%Yi$XB;Hbf=2_bb zS=!N+G-uLUxltlP{u&M(IcjiBf`F>y*HJ%L-UG`wbWy8;AM$dQ!UoetfidK$JOol? zZ&V(WqiF>UYc|wYu}>0jt|c>2DG#y!7_Bx$8Ss-)n&^pgH}<0qy(Y-MQ9-_(VEB>mpQy zY8|_MJ%C_n6p#?|E!?72w$L4fc%iWGY`88sL_7417i=%#<$k;*JfqyX7a_9}&$pPo zZYVXNo@TuP$4Cc;o|ZhMld(TK}08=btU7BP`3{pJlOs_B35^Teuik zJS&*td@!u)z%t}AD}`0$lIiKrg@*=gb8C06#jesIENzQ-Hq3C%=)AxVU9(GIV~cg6 zX4psMnmwVrW@UAd?UQ&*Q+!vl#l=MQJ&SMlCrnD%SAu;fn8ImAXd(QQu~-p0iSl^O z%R#fL&{uh5;oA5y2}sN1a)K!J+zW(7doJ1Eg--(Y2kR2~bU!f7*CxiymqD#Gy4IR* z*&18ucQlK8vA<9HW6RxIs4z20x^Qc3?1mvI4;$=8^1CR4KZqaTfRW!cuWStr zzsvcR9=@kIAN*m{`$`7^hWE7wk5=!ik%*R*P6yWQQhI9)rCFu}_IuQa19kxkt)MkT zM>djOC3@ruVx^4RPr_U*P`(RqsRCcgtouKP-?hdupN@Vt{H{uZQP@C!*Msy(mc<%2 zT*%VY^)+>Zqv8R)iE_Q}zzfw^t4~L?%BEW}p?rMP^YMWjDU7Y7N zWf8kwOWEz(2*Yx~u37+#9H(o$SAjHkx@wUBgYKADwiaw}0AB!qoy}2M&2uLr7PMry zOwjKytAoE)42Q?+Z!NR>Te$U`y{&2F6%iBGvA0!DKV=`T2aDV7!}sw49<(m4IKLdV zOo^R@U$kU5lR>k?wHClh7gihv-qPp70;IlVx0K?*(Qa1~_&}jTbqX!nRVDPXxLxUR zyQVCs^}5oONNKV*1v^9_?c{T9BI~hmCAycqn>C$WuUi|nURU2WPJJuVEcyLQBR zTu(bH&w&_NJT8n!>w4Y!Br|M3GDh+1b?C$j$}{AJMCx}l`bpbSXna$r3y(ZdaI2;F z71uJhYvw(I#h-KGR25)&zY61p9x=eZs88!Y%XI$=Osj)`HRC$NzZ!=k+09rgGTbZY zlvR%TyLjZUP&OWa*YWCm&h5PLLvGbNdlPw8VnEUv?z&B_q1kph9D+cBjg!;7T0>4*K}j>*pEu;ZHpVz*0ZRb)YMOzVxU1@gw_F5dZ?y z3s=ddAXsnZ@hmc)`ym! z&cCX*`d4>?|GFOU$nLIKLZk^jH-7*j(Y}Ax8=rLJbSkRoaHZ`VzdrOj!4=$?pG1fV zxUshKm*BJx_Yo5=S%y=V>;4tiIc{EHI9IeJZOA9@Z;w76ALijVXpjv}#QJE02+fAj zTm7sy*1o!*bqaQ4$N`(WTA$FO{GKoHS*N$-_MoG&R41Avm)!KTmWy?r%twWjbu~L# zHCGX079qY}7a4Nt(tr%(Ypnm|f&wd7^!1-g!_E4Dyo`?exv~-vL*IunEb)r*a3~>K z_JiSBg8 zH(XLb>1+x;L5_rB^n@-1Orkc*fm#b(CADucPi|m58%Q9?l)=hWqvTSo2W9v@x}=SR z&k@(aMP>tnJ7Z7^qDBRy4*bVZc|3NgEJ0aO3%i@8J2e>Sh6Hek=DP#^rV&-Ybli$Pil?fN!0)cxMB+dGkQa)N6X&~ zf9mre{d@hXi(dM#KXoR5YEagH{VD4@)_?seBmeRLT7T-i5C1p$Q)wIi@9?KGvj6K( z@$%Gv{i&5B&%HsRO0|^{2>9`>#J`EL}M&{}1t} z#y%16PaRkro~=K1bPfEeXKpn7sSSwX;-J(D{A<~#RK@qH&1*MjP~WQ5^emhx z#HmNpZY48K5SzD>DNoEM(ga7e%H<#*GWoVdQnDoH3FeCpN((vqn~w#lgVC9SMHEggtW&r6R>suXRCGg2U^o2NCvEfY!^m{(Z!IK7NCPc)c9|&ZDgT6-wFDORyEs zhe-A^#j{j<_tq{FH|(YW-xep}SJ`5vS&yS*|3oeJZ)II-*nRh-NOmhFk8TVMJLx}x zO%z+5o>f@kaLgZsPAKi}bX7a%_oMzOTZ-2xs`{Q*zID91S7~y*+Gxk+dst1bw;%sh z`2cr9ZB+}G**``&a7p&Y-tRd-Ez+2o+Z&+kI9qty@mQDeam!Naa8=BH@JxHaeoI>5!~H=3LR+nH^nVi z6luv9#Uz6k>dBzW*H{h1ihI4-O;pdjiOMkOuqBH{lhW4mCSfhIiMpECBJa>Y>&c*W zmn%ezHWSs-W+FSp#T)+2|ru&u$+z!>?O0V5BT7JtAdeG?I!=l*!Zi;=X6=m-H2YmI;B zM`JN^n5d}d?+Z2Y3%sNSfsBaUM>H8P^tFmA?o!Az?IYr~OstzC_1TEZQM$uV5tjr$ zViB<(G)Au_(rtqX=!*2s#g_i%{LP0U5n?^D0_E~tiye>sk}9mP4~%MpI16!~D%5=`?t$+%|n@EJb^133@Ialec2YK=7oL&BExWd=a!0K>mkq&?n8IwU` zt1UPTWZ;!+o}Shz78&QAKCKg*0wb@+ImJlptiw>YEHa8Xx{=qJAjBnVo$)@r6M3DK zW;w5Hoy}WHN>*Tr#9|<5#dTh2EXr}5T$iaG=p(Uyh9OVqa?14pnaB7Cgx*8x5GlR9 zINXBP=R%Y5%~#-)G+9FpWrzOIBw`~GPdaejSW?kNl0*o7EMqm<>=W6(rG`-#JbywQrolok3qo=7&FgC!v8 zdhSJSA@8wp4?-k@u5{8Iye1R60EC+B-!6*;h4x{=L8n{J_i}v?;(@NkUh2vhX|<-7 z3bwxvc{%zwijJdL**N3=t(wpQEbxF_WB-;QanOCjHAM=Nq)*p=q0Qh=&_=9+V#L3X zgg(I=E1&cXO7}Fw6`g=0f=?aEOXUD`SmCW4Q zNa~1n-ZpyUeK%q6U2XVo=aTQ{N=K&NWw1xAu1NX?HD z{FXxakW=dQErs>GrSL`c8%~$tErrkGnYR?~0!M@wNq!N3CNJ_1Y$?1NvV+scx_R@;78uiTPOQ6(^x6 z^IFR>KnZd7BlB2j;73Y+Tl`2mGu7}Tb5M>lTC+%6%#79>b^Zc9N_nP(Q-!_AM^56R za=g%Ue-490-8v18zz6I6sLw5QP7vOUsLG{;whJD9Jt(z~W^RSet0*YaQCwvTctvp)>;@|$y;g?oauHWqhMSFca%5#=(%&R@n5a6m5)h(A>WbCo0Bs{B5Z1D`BT0l*{P+2%JWZ1uk`Lm9ovDE}*&x~?Pts~4b1zQX^y3cuL@0{corm(VxE|GKmt z|7$VjMMn8w(Ob_<|0~bzzYf#8DqbNHgoMxk61Hate$oeQ$cl3_eo4gDTtzydW4KoT z>tj>@NxR-KLxZM25;`mYYnO0H^!Rg>|K+RFzP;UWz77zDv3}Pl;7zpOMYJ3KoId79 zvK%4tJp*@N^?>cF(=Fxf5O^TQ8ykm?%8$waYCa49Yda*f6aLpap@$9s3nbRwDV(oq zIe7^aYv~j1Wx1Ze28Iaohhg6KG1Y+tQKLm zc2tsMC*1>K9A^q|>i|3w;m2A1t;cnL%O9U+$^O=Ty1xa?tS!NjnhyG9OK+jkNQllm zA*`@_j;N3V1@s-2;EP^1^tCM34Hj}SG9nH9X@eOV$dzqe+Tx-)P001c9~dPdHnhO- z!~C|;WN;BLqhqaab>xTDqK71|1ku119Q?g0hvHP|m2jOp;PzDzl_+QId2+a*&TOG# za;u`8vCDzXdgc^4cBaK6{jlyJfRh(LDV2+Di*@s`NW1UZD0gfuQg(GmOx{<)=Xplo zuT57UBq&|@=3%~XTebPM6nPOb9jMB6F5r8&tIgkCi&~+?BY-Du~{&a>v-GEPMa2q+GAz8qnco4Sn@8aX+ zGqe}mg`Zl5jcK4*?;H9r_;U`!KS#pHVay;kJ-dmhxE3v(&vlIXm-s}d5oc(ZpJQQ? zp|8pO!kM{McG(pAKZW@7a;7dnorS-td*|Ta!tif7Yxw`Glkh)3m*xM`v&Fwlr{I%( zlUU1Msn*{64Zyq($ld%e%9wbk_fHsgE1O}8Z^D5(;_c>GGyf+$qJ={l66 zQ%nOF5hOL;zbQrOt)yBdz%u?jrw`7gFU;?;@M3?ruW!uyXZkMTfq2#pl73=_^*5^; zi^%KWTVu;(vRz!iS?WtDCc$}(kI%bv|6i>4zpnpoX>o3SAPHh_Z-NFK2Njs{CTkE7ry zoZNK#R{trxw>O4iG3l#J?b&W}m?S98x81QB`Uyuar&V?JH;5O-K&<8sASP6_TRS<@ zir;vY7KdG5sOGm-*3Y>_wfpC^+2$q%hfz%1rgT+$+_u>m|G|8I8{Q`*lJMV_ObptV zK@3X4jTN|wA}ga<`#t77e?uB$rHe1qyM)Uxi7ihqa(wyr`4`Pk9M!2eAntD(%qWTp3lX8wpE75*)>PyP&z{`2quZALywI~yQb80oW9=ZqE36jQZ)02q3)4wO= zkES78WM&KTm?tdl9OhfP7}eAtPOjkO3aP+7vshcuoM1zHT!F3^$F*@tS ze@lut0A6G~kRmxu2iVl^1O^)^3?9CVg+GF48 zbbXxNjN|5IA+rh5KTk2drvQ&6W&}^zj(gu!;Sah#;H4F z`8gR#_!}(z3?&lvq27e8uj9(M1?3TEJlui2`siH)8ThJtP`Vzi1FtqgSYP%shKH+zSo z%W_pGMBVv5q%Y-x{^b9X!f>olxQ0YvnD*(nvY&jH;(&U(p<~uZ3>Tw;Ic1D@b9jhO z9Ix$9Aa?9e??@iw`1cZ5c!?`W{vG?G)BMw>bM@(5o$SL5$9m{TA^W$&XgB(b5R~Je zs|*%ZSiW%oj+zV6#eVvP%80K=lvpr-KDR?JK+y1y@_x97zTXcL<%)Qllr3Oj2^jbT zYB*PW;iN9;ACa&L1wsgn*WQHjRlfPnUY+KT!W9&*Ao;WBNay);3s=8|tH<)^;r98{ zi>vhFDs)j-E=GGE#Am3Qrxw7hC$09tHI-j@^OQZNee41GgN6M3@q|u(A1FSI&^Y;N z3b!cD;b!pT!_|GHVgSVZYPwFUqmPi{REAp>!%VPzvy)y zDE?@5Wf;It9NT))cE&YfCaSq}~6?XEQCW!Sw(!+Qnt#w1cr{D&%oK&5G`Y{bS@X_z)_=!iKj z>Z}&!g!7bRW>MSFK`zD z)LdUcokbRs3l`Elj)Jf7E(dpgcUR}OIFCC^K642XfyP5wxur!w@1Kr>Z~EiMkcV*D zL;?PBp2BrrBmW5$FSMd)jyK@h71v?_*L#lXEW$lm0#~|7a$pR)nLxML9S#XiE&gTx zUCsDj&G@E+cR6ZbwTw)NTy2KNlA<&^TXB8e$VQkXbQJ*&^Bj-%&u{dG9eTq$e&A~B zZQ0F&t7ePb-a42!<(t=CVC7F=^?I7xabra3?fvnuv(Zt|jP683dD^F+2`sian-RYr zxdnb_PstRGS}@~*61Ra}!O9ZtRs+9x4g9zZ$;jzzn7m0t^?qde)MFU9{6b4%R8xQ| zWQnevV|gNro8-xP94CT~+*!HJ=TMrn*_zSmKayZ?qC4Ag?atN~olE;kWaGrBYKY!E z`~ew%kq%q6_Kzy~b83%{{5|wm0`7R(s9nlqO!yDOlHsj9S5Nwaz6XcVjtcT7guj8` zWV!Qitq$TK~0wBm1La9pJK+62pq%r*Xz+Ew%_-)QSa_c zrQS_|;X!s{TKOr8>68{b8w17X&Au*>W`oO;e>6~harsFbqSdoAoy`wqlsD3I`6m$^ zLd~98_8w6YvVeLJha&Cs1;-<}R!SlzY}A1N?$5BCjuWS~Uph@@>hpa8V^qKxktsy; z*+A&oKEj6%%t5FpgN;#$l8Bd+Wd!umfw-Z!Si6#^lT`Rt$`%wy{S+@<7=oBeaZ!m@ ze3W}QoKRimNh$x1c<4p06|-6K*&0U-O0k8XC5B=Chi!%V-@(EU_~~?%v^D_^kmgbl zJd(C0^LM=VD3^cKD4$98O(qS%Ozo1`T7W;9%TG4STkWBLvQ=+|?v z%LV3gfrP+$%f8<$nXZO=1H6bdJ2sBOuZJ&!d&|CyIx0DEKdw(wW+p!pMt~9%$`X`= zu^>ty{>R|@F*uq}Q{@;Cq07KU41bsRsy8KkH*WiUif#(mLk+5<+CZ-|6NSS2v{!y&J^PFJ%ldaPV>FmC%7I-s z%)koyk3eEfe_Si0mf4_??affeBb1FW`4ZHER{R*{+*q2Vj%@>%C!;q54`p3iLeiM3 z*)YVx3f$9(Tg9M(DqaL3{)e(gAhW?1xCNK%U56OBIkHB%`GO&>^&3+V9+u;e9Ti~V z1UBAlp@l{fUYPGjAoeoCe!?EaSaej-y%Z!;<4SOU>z7!uCNq%aF))Z&8i2Lhj3Wh5 z3e__tZyl9%Hvn!-64EREEV>0Q8O`26jd4STRA~gR2BPau#{{7K?3=jNg|bypomQkd z1^Tl8L8)lk-Qqk-wEAWMN-~^Xd|`Ad=rRzzO9&Q-2ueXqV?q*^D)746v9^b(U)2l5 zgoe;NF~0cbv8w!(&_uj5{4c;s;h1x1K3>B=)aCVRQ(lmN@c0~jg~X6qkgh!?Ix6&2 zyd;4c7g5}8;l0`;KaLd_lHcyIgvvK}KiAaf-3*!aUaGp=DtA5HgOnI4%BAoqa8Daf z{HLQGNgl*FG{^UwFjk=d&LMC--f%r_5nwmReOqH z)cL4VtPw+0*aN9bFIM8#cn{f|RDT55AJK08^iI@I;Q9&e)~BRVZl6Mutx7M5m4SlZ zegiC#^34t1+r$6q)6@t56|SnFDkL4mq^jMR>2n12bOQu)oK{O>*-ia7n(L45sD2;4 zer#RpGUh)Rt|cj0XwqLZ_*7EPT-IFx97N)%$9sdhHX_0Bfyb05^h4l3VVpDbZG z_dM`DE0AB2=$Jr6ymVYqG3?uG^*NpVABOTEph)?dj>YZBtQOq+rd@)?$LRS}@Sm^p zgW#lVL%H@)!l4^hjFe5;+npyJ1s_1ET{zuVG_F{qd|{F$rUWM9Fj)K)y`=>#xAx%x z9Th<&>(kG^Cc-{TB9u~~PqRQS-RYaz-$%p3UhL5-02Nx$-YCZf`cf5)3`CJoN9Y@J#qljm+0#FFx@{cUwYgd^Y7Bu$j4Wt9 z8jSfo80|;R>H>W+A6(5XUd=6L0DrQNhM{U6=okt*2C9Xuwv|o&$F&3=1+1H}->Iv_zG9)oA}{N{B9hi65=rUIZ#Zj&X&#uJ1EFzKf;yz;4jP+rQp59>lp2=5 zdl=q5438r0nZP;=aQiye!wrIa-Za&>749MMg8sWaoTeX8{J|u81^sM ze^akdm&Z>K@j9>*U7ORt3z&LWd{qJ>;m#!b-$JQo5bxU8SQ1Fy}qcCrS>e3 z&}cvq$+3_!)SR12lL9&CIJMcA5R=`osEai^?H2nB0GPq@e6CJ!tNh}T1Ioticbz*+ zv;7gfcLV~D?!YZAFb&{iwf<0o?B-mSv$X3kImh+%V1w(k$ z5K4xQont`@_$Ulg0Z1dhzUKq77*pKTr5V~ph9zR_H2%5#By0IUMwRbtDG&Rfi}&N= z93Lf^4A;ixEZ&kXf5*QdB9Ge%BjHbyj+_8pNkh%K)3NYQ7?^L9WMu!<`MG0ZK7JyM zpI4e}-{?flW;Wyzw-~{go^C5C)~;q@hkyttiREz=4D3htL8$Y{TS}#J*;}+5kSwB} zPXh*B9!SWx?+m1*I(N=W_n(9{Om-<24}ONMP2JyewmvXa`7V2l|2w<)mxv`jqBPl0 z+P}=!uzv5Tc#JC4dv`*Z+;C%mA;N;lbt4m%W2yKg`N%_qx)_UTcR&=0{Uk10F!L_qKq&>>j zALZ&~FQ@bR9*-ifNr%=OHV^s#Tz;}FPs_!27&?f`LN`H-rsH~J?buhc4tPiQjj8e5 z`s%0)0<@*GDL!;Az@cp;K13lOmJh?ccaYQeQL z1}>BBIV8W;TLe81bevlq`5XP8r(|z+!~4CWq)6)tX;pi|7UN;5t8m}7fRmzh!@s)g z>6>i0odRF=78>U-h7U--1rj;lQ189!ZNQ{>22T`g$#)y4ee_SB*TOHF{@?UAEI=vw zZSeN%$0gZ3%Hi=^35>4t%_ZLvzY|nXvf4!*)#@D8GON2frES}0;ve9_+||D0p@6G_ z@R|qK7@PzT$<%h^zu|Xf|0OZJB!xkT!Jm#}mh;VOR`P9qMq9ol9g7C$dYlS1}ZcXxQCJU9n_F#1CtM z{oxznSbISg-Wrax?|LF#*csd(ME4u0)K_G1kV-B_u5Rm@GY?<1GJG{pNp;=tDgTRn=iv#Fim5d=th7IW42yi4s zo9?4|5qc1>1Up!o@4F&en~{86|0yx!`jfT7FKefcB4Mc7qc&kY63iEmMfZmrI6-EOXyA1ol-)L{5>9@ zwL(T|d~yKXt$7Z>42>4kjnQ2be$CP^doI)ah3rQP=%ANDNV>N45HW9QE2f)XH?V9L zwUiD)-pnPl5J>v*=Il*STQD95hFKHRE1rjxuYgQ;lVkl?@Jh8k%sHN%1O767Y2Z$@ zivH&ou15>#f4)*%Xb6#C6r&-8en{dfNumn%DES%`g=q;qXdg1C74c9q*B-tAqXp*N z3b@29+bE!fs!|ZJF-9-1H}Vh>{=3ekInZNyF_RMsA@}#fe-Kj^9%qz|_7MYX3Cyt% zd63$tX+&=yQ@EH;QGnX-65GD6axo9YwJ*Qv0|5D--1s@%xQN$L1bj|U87BXMzabgc zfS#{{UJyKWBfigFgzuL8Fe6?s?S+lHy}%nL!>?ofEct|}U2=@5O*10XB3@3B6`Fb6 zZBRSFB2zd^zFeMVjo|rkF&trsGCmw9AE(U}USaq>ypO`8%^u!h#iK2}N_*fIiiOJl zXN-~2a50-02vKjvC^bw2^owp+IV$Gk3kGSj|H}kDr0amm@HU03A#Z^(SyzlJ(i%Qx zW@8*BhktLO`wGmTbC7wh-Y8HBz$e4HCaF&n_-ca>*TH^kv!fXDf65u0sl z#QqUlmmJ#`m=;lf(H44$)U4Pihv>L}quu$rGOEo{LCa)_BM%;}$C06Lw;!bL+}^_K z(3p>f{}(gbh~LU#s08gvuJj~V%2Qn_sxR4k;fPw6>Q-F4wRg59*d|RD`Kwr?C~OMk zrzoBs;BHdaQ7s7OT@2DO(MEht5#Mh3uMo+JlQBfE6rzCSI^&8q-#O-%O3gPa$%gw( zy7{$~A+8~T{h#ZK$P{3C$OHnpTVR0QAP%qXR z6&$VPYQlg4j%1f3!33xN&&GZVr4@)e*0+`*UZ~LlUlS)Y&JQvPh)1fPLwEo1B3>M_ zqPo4nf@+gMbJ1iDg}o#AJBaZe#Q5UAm*j{q1w6H2TddIqvdpU!wAq6KqG}-! zI4=%?(Ix^yCkPyhbR6F3Z?a2_r*$6@x7HmcZjn8bi*bZ}2X7JS@KaitARdzA|a}%Z9M24Y{godOz zgviyRxL7hWU63jxLVxxqSXU=Y`%Smmx5II9P+({bjdOG^IVpzvq_thaTmRqS9hR8x z;oth4h-edC`tW9ZC-fl^9BL+lDPGD6{OHkCJzUz8Mm@zEZ{o%{e1z~NMN5+?C0dWI z&jWC>2gnwf06!O=m$rz3F9LATazAp$KufEmAjq`rnU!JR&RvoPQs}f1>I@>M3mFCh z#vWF*-oT}3Ag+J=aSQzz{kZ;>AdOXd^zTWSI*5OM+1dWxj$MQ?{k!mBhy6QVdxqgZ zW57=nGDnozH^Czy6PJD%I9Vye{kyMEMZ(BrROgZIKa!&s;@;g9#kE77l8XJ5%1-FX zC}rxPH1ea0Z?|LN5(KJL-|p-^&W{`gUn|G^m+e-*E#FLrm~%?HW8ppcj)b`GYT0i4 zPG{@vJSaqU%8rOH-CbM+Evw!BImuHdbf=-MkT+C03H79U7517ssjc$BBOBGS^gu=r zd(io@W5M6aP|fIR|BG|)tclrMySmaTM;M@sajXp*!LbQY;X|Mm;97cilfF!~Z?$jt zm!%_=wVI~M!gRV#bDMWQNuofjNL#|eztj*V5>^KaKUT|j0Maf>L3U*3^-iGL>*ALBQS_P^<&=A`m{WXSLPj$+eyqZ_6dQl zMOya9Jj6nuqls!bG(iy*6XP2$F;K4R652rsU@dl1M43p7_iIrd%nfiz-mNX~c_M;0 z#YOUkF4AKlU0QHBrT`pLcMyl$W5&|8uJEUj%X)owe2@faK5y%g=p5Sa;S21ClE;Yj11 z))$Q7SPhym*T2LdUjj%G-|bth9ov{-QxZft-$07acN6O@ro>}BPUq^=xjNC4NlOuW zB@7f}HRA7(Vt+%_Y6SU%{kVQVSsxC#4nw^FtBOTd2+zesV14}A2gH=m!bAbB=kPKP z*p=(ias(wF03Dj$?Cw9fxI~-CV8oIO(a*JC;@ae2(t3!orjmWMsMv}^2G^y=yRk0PKW>PG3^umT>quc)z65l zUyIQe(e7d(cQFuJB&QP}#QONl8`vDMH%q^ySj(g3QK>;=Bd+7MJ`AZ3L!$XRR{x$P z@2W%ni~0Y3V#odvu_JaqSsz=s8V&G%Ox5P>LK}=?e`EcV;XTUmDEMZH|7z#stW+cR zO9El6*H7SD6Hp85^}||JZ_-2H$k=%gXV|>obF3eEH8dp0kV`b@4m(^Ac9togkA#X| z1t)a}Hog30b5=@nEl$<3dH+Hbol_jyh2l8PE&P`D^VH}WRoHiz_h^ljH-4ZI3(_!+ z=L8l!2XjaHTD=C&x$-{iL)yK(08p1Mouq6p|H@{|w2k}i(n-G^u)X{f`r#WGc;(lq z6Exs;KMq=H}Ag)IbY+Ho_u^{_&hVd zJK?c5rD>yf$$(AMcHONc&9HA*(jJ4yReoY7w!Hg31~t0f7FHdnLbxVC#Sl`j^|TO@ z!i2PfO`^HI*5-C|a~~@H54kz|$;~}^8*zf0!{IW61>d-4AhB;ub2ZwFSLuA?wuY7y z(;BSp)Z+&b=6938pUCRnm~DwUKNEEWPf!u&%ml7pXRTfFUnQ#ZJEM9vRsZ5j#ys!@6+!ih0sk^QO`dLN|NmC|w-KPdoPdG#LRuoL zDcG-g_G+(k?cJ(pFX&baQiA?PRFVW0qPs&aNLAEo0_@tW7NiBv z4>Czim*P>1X`z72CDn(8m{NFIJCudt@&r|40bPiJH3#{PZ_UITlADsC--}10jlt7< z)wNgg&%uK>8;5S1(n+Vb0(mZPLB2vD-=NJwTWTSYPhsSn!HmFL519?kvo=KURo8CC zUqKDMjiYExxqKYxpdl_FNSp`w#&|vierXPB$a6>;ijh2UF0p8a74*IMf$IEjBDfJ* zy_}}{eOC}G=%bPbK8)dtcUddmDJt?iQIVGXwPjq9K61rHT=8~m#fhRKzY`U!F$}bO zxFUU|if@g=1BAj}qP>EX2!P=jf?<(Aa;g>2A?+H}6ZEMMr@*zS)h?ztg-uGzLcBqI zr(Qdk-y9TgCPjQT+6m|`weUmn2DR$6&-l#_<4ptWH)uk7Gn*i9)i!e(p%@qFt`_EV zp-n@7hRs9kOrjg0{-`HJ&p^9!Z#4o!t6 zD)`aNzcmWhV^Z|(RT{Mq(x8?GW@(XLI54m=;6H*Q_~_Qw%MYL8170YNCEB0ltM~9K z{B}4*V(Fw;Rfs4qT5OxPvo05aWaqbchI2+Ep4g8yul^%$9KV1sJ;dOM7O}E?bc2rEj z6sfwJ5adp<>(fLo57TQZ7O&dIJvM+XzKa5AJ#^P@RrvL^-exe3M7#O4ec9Hd~o z1Y92~30Ydo02(w+N`7*)KR>~$1lYR38U6j*gMK9wLpFv%OiDY%Air>&HhL18aM8#n zLk6~493iV{1fZ!6m$XC3o8yUZWM7=QsT;>zo3g=*iRD=**`qNE-jS!p4Q?=-V0@ z?AC5P0mq1~Pw)k&_*VQCct**TFg@zEfebN5rmg|Rz(r(S7+ukU2ycN1n|*#9RzYk> zq(~P0C4*3pX{d2ryzm|rW{4EtgCx9Te?aVOPk71ZAO`=uJ?QrmbhiCnJ1`<)hrm>b zmR=kwM1wKnYk&Z^-eo1GPdmgk$dP#Jd+iW&!fkDitdY|<=e)z(+yU4ivAj#==5}b0 z>&;aOs3feWO3Ilv~bECZ!sB ziHsNF-=jThDdYx@G=IgkulMYl-oy*EZ|&Jtw^IAk)C646t#=D(KvztbwoPe!wP#W7 zjl$kUamYIZ5XuSd*e6Lt$4RwgMPeYgZFD4N6{-#H@^}p8LKZlWL8tE%X`jTA`X6`izvYGt0_OGt~Ju&UG?sjwgLhnlgE&K(0 zcFW15S9`TDkhR&pjO!igPm)gB*NgCvnR<4QA=(XXAIsl!$@Y=*!X$2ly`w$e4@as& z#)T#G_j6(O49(JdQ&++Iu{&V29K=VgYrrV#B42-w%L2mN!ol#C@IS&E_4VJ4WX~La zpX`~TV!fKM*=jLh~<2}eaEDXToi*8rPEIjNM@4>0>- zH_neid`cZyTU?~QP%E}oM9#sjmIW}V?yc;oLMr&)8wf9 z1)=WRN;(8bv8AecC0ect*ayG>8+7fai9Pf<{?Yf#L1FEtT0>Jyv{Nq`sN8%eRPsAS zg|55?DrzCaWo(8fmuSzMz(3s!bbt#{ic%+Xz4vvT&a)5kN}Va7d5A%C#Z6E`(Fru6 z99=IVs8Fw#)q}DU?P{~-l{=Xc>J%tcnf&3q#Y{Y?jsZ6a;7BDPQ>h=eujJCY_~;!3 zA~XC}OxcH_L$tc9A=2k7!NBmAA+9E0cW!?$PFeN8wF;xp7P!C7o8jM1iKRV}n0K(K z2&oNNRjj}i3~q#XB4H1kyOjIe!Urj!jP>sgB--b^N1`p(vq@(;H+gBlUXd2Qg(nyo ziFcv+^?j^zGecws+zUqVL3C+o!Ly^74<<^RwkLgFc1ZQ#xp` zv-0x5>D#L?+w0Bk_3og(&dN*I)3=u<+vD}~7h%nmZ+>wHadfDmVRBf*xUqJXj5WlW zSXcK3M`UGSa!0&7fE|uS{14=Jj$`eFtU0uwYL4{}x@Jyf7L=h|TLWycY)A@%6Qm%? zNE5kSanS1I-9Nm6lG>DR3cP@3AI^>#N=u5o!}7q4tjq&tw(tkq|H`BuVSJCTBYcnl z`iLn zV!GMlY1Ok7NoL5mDNev^wo4-9A+yPH5EV@A9Dy%Jf7UAv^ z^6Uy12hysG5MU^9v~jlN;)t(W+ursqOr});J;b%hTL~k@t&PlQBPHa8Ii)SRBnc~b z4Pxomt@S(F3U}fl4hP&N(W2#TR4djZUChiynhaszV17EWhR6Rl>iy{aWN%g`Cm9&? zA?@iMMa%4?Xuq>~qFzqgI`jN%A`jFNUT)^!(f&fa>InZz`*lX#__&nGx|GTK_l}Q2@BCZF#~tzG!*vkD z=|_RWT4Z|#aA6|d+qw#2APi{xyILW90+{U)9}kU7`#{u8C{FRJ+ zj_S$)s`~!FvO{pf%Wy?4>qX%hxDXSN3a~_&@&g-BM@u6DEOE40UBLEfdHjnGX}RkZ zXxZ7@N(<{J5sx5cU-TOFN70tf_s6Q$78-626emOFDm|fTG1^Gc;=Zr$ZA1qKTXeS= ziQye~OT&>4Nm=q8NJ)^SnE3yC72*Hu2EyOylJj_?E<7|~+u8I-yR=;JFVoVBy9hfF zvA?!~mb`ScTV#A_%d14pmd!*A$A>(bY9XWy`KtPuz;YMeiRP&dAR>?ZjeYg%CCb%m0`bT?ZZOUA1l;#8r9{)cbH*f+<&cK8*d@9-v* zKI|&U;Cx&QeF0aK;;RD*bkh$4G+opp>=v@-B1<`2o7e{GGQS_Dm;?wU;y@SC8S!Pd zN8SXS1jUjWL!K#_(c~@e*&%t|E#$HP%d~Z8+7iUR93*t52K)#)Mk;r~su`K$9s4Hq zCq-4>eMfLurufyD{zL4`I|KW`xMHok%x@g;8RfN&m_iYk`?t-i{m3Rfx%o z@to=%+!-m|iGBA%gBbZR=J?pE%cqmubH=x~`)u30rslg&w6|>q(YLKGj=tqad&%CL z&Ol!vv7y@3SH;@Eqiwpf6#Ed3aad1u>i;MGJ(}Ae9pC=Uvugj)6V~=?zUp-Q+g@b) z--@Gu;#sx7BdYy@oo|0Mw?8_*{U&4n>J0zeqS~)%?mYc}WcuHXqrdH}+HZ;O|IW8R zn%f^8-+tX$@&Ci9_G`ZEJpC^){cpt4f7at|1D0@T7AhT}YZc4Pj+}QHxXHi(l(Ln@Wy!Cu8%ePFO9c-%Zc87wM?&Q|8)AaQ|)_@Putn{Cvp3e zMEh2I?X30bBhQ~=ekbLgj^Cj_5WS&was6x6F9m1dav(8UzfAZ-7-5U9(VLd*r3T+? zb$(Cd_NT?SZyjG}Za;c_?LH#fPdRh@q2Dw8Yvbs*+Q(;ZKh8eBzq^q3(LkjgyV#_k z+n*NSzIA>%bNkWr%kHqG{|9H}f9QFpe@z_yR{ehF_M`Rt1lj(g@1L>#Y25y_`1Y;- zz?s{R^9R0468zux`RVx|TE_I(#L;h^U(Vcq^!zdbjgqQclyheKx&3MJ?OXNxncI)n z@4G{?|Igfh=sBi;HPbKj-G9jcnMoV9q=P8$(=_cn)Bj<7CRy?M&)EA1;g59!pKZS* z{%m{Q!k_<)Ka_i4r|@wyK29q>{~7!%#=5INZUNssyd!*lxuUcXCw$PO-r#i?~y&3a$*ecF3dB zf&~+@Z`(!7&IF8F6c`!74yiq}CisE=J9WJ57h$c&UV1t3y51 zg`gtHU5_dZFFy_NhTtmA2h%0MJL3SRW9N8aB+&FpfI%eCFqVrMo&Yx3rp(DuW@ZX_ z64-?jn34JDOP2BG%~}bL>&Bg&-NGmF@5Km^4)N5b1#YQqNi{)Pp7)*d_hfA z7a<#|AqD3SVMAVd#Ad6%)Uj|kge8#nHpvVK$3FcUEkQO4hGX9gv;4J#SeWzFpcm1F z!4bXq5Hm`;&rjETGEFl7H&?}q25s!8c1!K$r>N1=`vVDUWP{joRjWO5v7oY1mzaEN zPPWxew1o@9XJ#mKqC2{uY|HHE9!5vM^9p8x#&D{3cb6oaR*zrd=D02o;V>Cc#9jW^ zPoulMnl^-EzbQ^C#&&S)AL4?@W6nX&l=c5-T^{lTlY8nC5~rzuCUF9F*hzt)v5b|s z4A>SZ{16E6iiLYzq$oulnGRk?$ALW`s)Yy5)t9tGdVD#6EkPsELmwIgw>3-jj;lq# ztRN|HHx3G$vRS*qP9sD0d>C*YGE&60it@~$m50sPu^bP;|Bp`-{(oHguj3EQDO!yc z<`0e4ikV-2E2GGu0X-B$#(<8=m~Cr^47-Jl!-oVJ`glJ46cKRvPsVtTI!s5E+O~(O zZ7-0InMy%UM*}-pkVO*SSa7pl*+|N_uzqs!I8wfdqr2+p=pb!rA0hTGXiAEU)0VQ@ z@31Bc4eX(T)|h}jJO!8lb|@t{#%Q_kGeuCuZ?iUUDY1iIU3et29MB`SN ze$YSzts01JKB;0_=ms)=9aN1|kcvUduZn2VR|S0oJx} z0lq4Xgc$kJ&5Ih{ym$!aO_X`DN_*iV(I}f2HQZ{^UNSFMsV-6?rg>4Pv>e^<5uu&}Zk_^VR`wV!#@v|=I{1T;XmG(wj z9IaD3Y%`ZN9NNs08tzAWo6!=gmenZ*d2vb(Yt#BpAD?Lk1z%t@sF!xfiEcLS4g3l> zYp>IPu-#J{z_r|7k#-=1v1Q5K@V97d2=PJP{;ei?U9y4 zWi{H255VEVSP0iNTnh3m|UG5hJ}2d zB-T~qY?TW2q%ajMiqZ@W+}Ogic>=UzPk;eD1JY)_nh9x@c*UZ(c(34$)Q?Z9#E&PR z6Z}B35Li-}MY%E}Rhg2~z>9#Z2FwVgJj$#ghR}_vd56A@OjPl;aK~gEMebUL`BCyD z;#+PwfYDrG2dar2C^OybnompziuRw!FsE6}{FreK=KM{6Wy~Tbb1wV3L+1QZuVzAe zLcC(;lzyO#4g6!;bCbdTG%i6bO2tu?79YA3-=#k;{BLVrvdK;VyMynX|9xX4Vs;yk z|CV|u<8GCAvruB{fL)Y`J`qRz(%vCDWql0t%iYLapWy%eu6ZXfax6T8x!tjLSJy?q zO4X1Q@^>{A6apwh19w{g+~XrfxJ-bKj>3K!k^i;VQTb<72gNcyo$`cEQy;v^!KE=` zef%`#5Ddr(|K`l)a7$)R=x0cCIzzi@RPJU`PV4_wH%=549*@YMKh;3|TetLo#J_w0 z|G~fTm(l#wc42x=eDGQ0e9tjzVUAihP@U3Oajit&DyAl+52}T^N?9!u3auIg*I-Ur z&8PjAfZmGhoa(02}PyMQ;~7qZY6e-={vr$Cql?cplr9=2MR_& z3c9dC4m&8yRw!jV0%i5%8eO|791-!YiiTej8IMpzz3PEajeP>J*6R>0ROu3$LC8!- zc#t*F5Z4Oq6L3^ezCOl>I%TC>n=j0Y(49iC^z{!o_`}js{alnoq){d{B2dgq{^n%N z6kV0Q+K6{419v52B7u37HHn~O_%ZFVf09Z<*&&`4UWaI@NJ|$jiJ!&ViCwz(A^TM; z>H+?rTw>urm=A6P5f?FE_4S1wR;T2|a2^2}R~Gg|=*%BafoKcsiCu#EJ}6Hf@!(Dz z_mLu9hJCHnf0FCiRLjgST%n!=e?jy>#J3{0fs)8LEALmRT@}wta1Npa)K;jTl}cCk z9#$#i!F!+1`&zfw4Kzdlhkio57y86iW955|;5+E{G^xJYKmktcQJDqbxI955a7Iax3*wIE8@^(1)kK~Ez<56?J}ckinXF9VwAKW zJbt$So+1r9hU60QNIf8o436{i^kiCmIv*1;;w4CbCXGWRI1)(*c)50k)-y>YF;&L-=S&)3f zo}^g7q@u#LTGQvTfk<4+QgA$G zzv-tUtMee^k<}CMPqB8%?`Y|plHDCR;Q#IxK53HA5h#yj;gU8-#Tdj0$|LFg+zh6b zM>6>tQCB?Y@bf5s?#s`M_&JxKoA`MkKX1UPDCLn1etrde{fV!%;wCl77z z#}Q+kN+6E5NYZY37tUBgvN(`QDaEpbqv9kmldvgCfnom^um!w(wQdB@JOwCoKF)>{ zXFLUmb0Tr$@Kl`o#H*A@s16PnX~n}icBR;Z!!rqy#^G7`yApqQ*_6UVIM;_NXfK^} z9J}@zRqT^bd>VPsbYva!vT5@Wv7qkgQq{s3RlAt@_r+g}Sb)?}ADFwL4 z3mdL~|4TB>Qo*J7uydta=6gc)rl)Avp-BsWIMo3~OZh;TB+(G@1t z@XP~nQmOy)>5LFtFkkdveyXi8zXu&F*O-3+-f~weU4r?dC-X%VGCxz)$rAtJbn#%m zh)L$>0>S|NU5mdT;%^}S2I22I{0+w6&Dbhvbb3v4RHq-LPNzj7&c{!}(g+`-sQno? z^~Lr(4$ROyh4L0+`~AUk9B9#%_gN9?KSDzm(Y3WJx{bpH>BB*~kYW;As}M^O4nlVQ>3C`|BUQT@tyqRUXSeAp zaqy0Km3WB>o$}_GIgg$Y&{DK-5~HATu3mcsv<*{=#F4W97|I9(%B#^(IODB7C>u;D zltaf*PPOW|OpAuXc~k8{nQua&Oe}^{E1}HPt{^C8Unl=N`dX@nAXEeX7lcN@{~Gi2 z@aM$e_4pftzoGcM0e?5*?oIKZll?3I~XZ?tIPL@OOj8mBDJQtJO5oG9-a#fcQkf0p{v%85tE#dBf_ z_%1m?sa3Ihqt`-kqKQO-IPquwAxY=Wt@^`zG@Pi+BK^%rm~HsYFGz9Fr=RF$?$$rq zNF&jw8}x?<^@smOdYV4{6!skkDxF{%+Q>#8ewAn!Q(qwMFmVgk+&&KfEqnm4Bc&*( z743%%$BFs+rraHJ(P(Zq8&@FWE0qF)HdpELldUb#kA9#hOMh3ICQaAT-9{f9RCiY6YD zrMf}aL$QUD@mXJr7XQWh_oZYS_fg3-P77SL(hK#7h#SuHqg#to-P-7NWX9vv8a_XC zMpi;{c$>N31eb)W$z6xH;CiZr@N1M0zHK%E-1aB|#6CC%hznuJ;2N2N3qIZ2@wI}Y z=eiJNN^msb`5FEj#&4ivf&V<6|HI&?GkD-z7l-c>KtCINdo#e^I=&1r8s7qm@0a$o z##dke@)1wgD9mJeo_aw7-51wQ9hSUZ4j4t^jeWdI6P@TS}DQVr*f^-ztoffr(4wJ@i-l7)KfLpt4lijBK zi&ru}S28|yEJWa842C;j!*P}V#TcH!kq;3zjSJ?9|G?ydeq8{C#{W~g`Rmhy3##PL z;DSZQQ?-0TS4)!US}OqmdKr!d@XrA7$&-L50H6qe*+*XzcRWq%2G?E!>41BnzdjSC zl;RYfAjNe^$P&mBqJ;Z5YmP@IMtp~~ksI}(0o_hbwYiFa)X`n6LlFhfLq`r%$0i`oo~E3S+bz{!Br7@H)cgeHePv{V z+NJBgEx7M@T8rEM4c{564JY`4!Womtd9?SJg5@}10zfj#3u!cXH3M^VQEA}$xQXunKT(GV`nPG=(}Qc+*of_iMQ%jJQe%!%U4z6tGd;v zdJ<^+d|`s(PM}UwG`f~n%GY4VXRyR)2JoTP8V?p)2_anhtEP5+u*LpQ+|_dg#OU}` zKV#xkf#g5jRhqd(aZ084iojE@wGCqlnkD+gd{fYF=&=bb|5ESzRB&bo$4W`^mv5ub@f(sVY zsKfu_rU)Cb4*1gmKX!`vbU7&n@rflIh#o_SX0}t@DG2@$oP|Mt@bm^dIXlnhD1Jp`Grc4|(*VQ@zF3 zn`MglXr=5eAMV8=9V_%n=?vm_={%uN{?+;6vOfd3oF5L;blu+kppK%sVNTG+29Q$d zt#Zxz*QW;~KELK?M8TRzhyv~(IX`^yqMRR2H>zUHEsPtUB2GWHVy1{JaMqk6J|&AJ zW{OY?yox?U%rOUY6_0G|3_-*2v@=B15TqF*35tVei09Us6Tg^2<@`ULxbxJ*qJK|2 zUyLCM(dP?LVayjqQOtay-s)9L{vYzb1iq;%`#&jx2FUn|Rw!Du3{|LBZMAAci_*Qa zNN8ybDB`#vAfpHgEl8my3GjGEanwB*~xbmu{6;(^GuIkELX#OIW z>50|oIi|mO6RhdBL-ly&R16&K8)kLqb6)iuHL+kJ$)Rrf zYl|_6r1M{=QvE&iMg4r#k6VpVw{(8)!ES(*g(1_Bb**FW!0!{Ny9%rr4?qI)*^Y+JTJIREt);;-#aoxc-+f6K|hf0*Gv zY`~8{7X5S;ZKB$*Q}}csT7oRN(#4DR8Ord7YVft|T2q?pTVe>&MG#bPAqbwgMC!&t z2P-D3fA}myNJhRNXZVatj+1fmg>nAx6mI`{y8h65orDvBfAI;zpU3d$oizOS_njF1 zXE6LTP8$BK6M|3rO=_)a^m4V^kB36tpPw6#Y+?&${|rqREw)_!q8Z;6<2wv3fso_0 zf^=K1O+Ac4wHv0O6!i_<_5nyrf_sBa?k{TtSq)ye|DTvW2$%2NUWC85hu8k^?gq2F&f?2{9j|Qi+riU}d?bDGTi_Y5w%>l#cXbE{ z;C)Lx$nnXTKu?j;9m#}3MDZ2s?c@2>e$a*2P8(K?#3u*W@p=Lx>uqh6N_kbLDli6A z>#8Mwm#XuAN8+F768cHL*%X?2klKK-B&u}HuvDT zwWkr6_;N#tkm95w{1g1ml;u80$bRj;7Uw5≤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ℑE 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%0D8a#hmr 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"y_{7))wrZfYiC%SS(gG&C?zq>efP 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 z zjh74`)ypcra`pud8W5!k7yFyk)A(O2cI9!_#~Ws{5ArO1bx`etMVJocWi4B~ zug=F|$ok=N1Rk$6Y}9?M;@hnM;LtVo z_~gIEz;*+ZvnoPYpmS>Wk9giG({*Toa%<~Jb9r*XY#B?zW)z;I3um1B1*I{WJGi-v z={dHS-)?Zm!Fii$`(Qrk_Bi9-)8zLyDQ5;`9wh2MG{sFKaqEX+>!FucO1XN!r`hjK zTPOES{@2ycR}2yziU%|FW(SU|7DB%0_(%^UyH2Kte5Sv{`2D4s!0z-U^DnY3J;vPK z?QMF7WzDGrU%%77Kor+x~+Nv}33GSWLE|9k*y+2Z67r2{pgQ)Vn#@U%dQO7KA(SG@%61No2rAwWY{HF?7KI0&@3+?`DdHSIyBT(8cQ#U%j4S4Yd*bzMR50tP zJ2h%4)3Wb!f6m+IvhS1n#ESZ~^!caa%xl{dkEv}aR}K+&2YCy4^Cb`<*i~G?&#!fB`%U9C7 z*L<_ZY6nlAC1c$oI^2-^Eht zL8gs=v_$o$l_=+!V$>e!AUNlKeMZHojCBO-QEp9T&GX(D(MXx(W;QwBdiFUjZ(fAY zu2;-tM*`Ui9jf)0xXIC(HYe|J-a2G$lzFK3L?U+Lw`Q^pJjrJgDO4tyoR^0P zIyhdV7M)l9|&x{faxS zo=acV$BqaohKrKe67;G&n#eK}4}GS|l@P_|loQ?b+#UPx_;0+9xm((c8TnCUyi8I~ zBeW>Lrxf3ZUyuAL`QcCW8a2R%fNgR6jnU0}UvbJ+0)9O!1e(f z1?J)%1~wkTn*z2o1Umz4cL+8IY+ndg{&(2Rfw^gA2trG5}2Jwq`Z^B7KLE@fh`QdjsU9wmNscr(pOFZ>j1XDm|V^1VG7pc za))vv|Gai&l{|S#B?Yk)=hqOkG;lPOI$iEBhO%CY1Y77EIS6~3g?-)O&Z}Y z3smVDV5{2o;it9EW>E$$!z*tGQBNqo=&X!d?mDleO&l+s9(7d7@51-dM>iOKuG$B( z25i#us(fGg1J>6f-$nmc!}p7P|23XP*5*cfX4?j3&$oAz$`}@2{ou}k`%4;E#)G}U zJ|W+?neVcvfS36WJ4E*$Kzq#hJBrPX;;evkLBU*y_DysyG6lNguIQSU!FLY6W$BsV z{zuo&a*N#(v($;PArM_T*{J6KQ;es#%?0O8WtFVxw`-DKF4y=KnEJIfhAP7J#^S`% z#cg>2QEC!rlQvBVzj62-Z=4DIHiLaG0<>uNG#3sbY7+!f5zjgqo?YLd_GB&mPQdRX z{9fX&!PYk1RN^d9oGG4i-pM^i9e{{}d-xK)qJGSM}qD>S~=X`MdL6@7-Z_#c8 z@T*)sljSx~BeS4nHv40>&*iv6i{4MO$2Q(Evc0eO`x^ZI2IURbpuE8v{E>QpwB8?U zV$0g;cXwK{s4#0p_={QvTas(72M*-gXJ>VwOYjGp{J|!b7}>hX@^8=27D|P*KajTG zW@$HD=nZtXcz|9f&|@_ZR6#Yr(I3(Ow#^0oFW2U`+f5V4h3Fwl3#-?b{m`V>%w%6H zgGKFObMk6D=GJ^masrf7;9q!rPRq#(KUD8XbC0U!tX-B=<8IZaTq`>9=(G@)JS@K8 za2{ECUC1J+4ki~&ON>TqyJ_^7XhO9(%2*%zG5%C{7<&_A9krPj+8FE7Zzs(6CYd}` zew$uc+M#_O;$L?~C(exAQIhL;pi93!4*iL{W-jH+fyAvOYNmgENw)X?h`ED~yNiBX zd7Aa>Zg+p6>d%$s4VRk~yLJM5TE2Z2(qkW(juHBM2`6h6I(ky>RkJfHfSZ+zvj%dN zH~W2L8D5F9*=rXHW^*J#vJO6pKBl(&n=J$liuuOroEl8$S{UNITUrT299%^YruAm@ zU{;-|VbhS*F5EgNwnRnQ)vIx;v~1OQ7%ih}H6<%(&HXdlE{uIt?ZtY`e6Lmq zruXgKaX{Yof!ho2-uyDN@EHA7i(h?*tt~vq3PxtV_^(GmDT}V+SZoKpD}IW7hI9sl zxj!^#H2d2Y;F~$IV70$<0gA%~%l+{ME&h%LXb2aifpzm<&wHBpMuW4KXB3SJKfbuc zc@teqxN$_!C+)GDyo`^{WRDjsGuxb?lPN8h_=?c^7#yh1YS5nPcd8yuSi2f5QBg-3 z?;>-SpJBX{p1ONk>VjViSjD3=+1E)P_^abr1FRNUlK_~fg1LKqwR8LMcL@~g4+kK zwQD`;wc_iwKn}EIlIj8htrs~CUJrQV!jpWt{tdK539-NPt*gzrVda@ywam8ge<0t$ z=LX@Ub*aYlSAVZD-yN9^$wZ?JL(*fuSDA72w1-N_^WN+4#mKx5UyA*-&H)8PHN;5O z&zQUQhc3Z>2<(Os_8ks3+9pLwdeT3Rk!J7Xv|TZoUt$v-QWGIg5Dk7eu~hF@ul4Fc zefye#U+kywDhP=RDac$?4fBS*j_?N`-kMP+9lV*+W|ubv}2HbdHgZ-OC%h zK<+#zvWWK-F&vO9I#Ee4;YI}>i38m2FJa4$+`;p$RwPk-i^K5T^<<#)H+yaRA?24k zIAy-SnrG1^iUwZ^(YmX$>Crx|iL>-~`22SM9wRrm$|`a^VxkfcC-EcG8h}1Lo&%3& z*=LB%(+}_Ar_5Y|%&wBI!1PG`3HiQ_?|b;(EP3R+GFq7LGXL!1`xM_r)g*sXu7kji z1CwW=A$tXFtI7}F3GiN#!()?%BE;FG30~qKk@x4puL`^~m*JK($mJ z+3`N=Fh8HUIZo`Xr_?;AeN7S4y?=}t@6Bem(^3U;95L$)q!;Z@EaI|erd$N_UR|Aj zf`L7Lj`rI%lfC{oblVizO!491)W~5}^+#AF4|wra(e4}Zuf!v28%;>G(BmEU53nzr4)|MWF})Wvq7@>fXN0CP07wNihrEn zl&-}fZ>}qe2L&4@I@-hv9%oHw@G3>PJK(w z+-%s?!zM%a+6zb?hKh zZsLETFNG&AGp@XnlmBGzP-Gn=c&WRNdFP8SV;H}jb&Mdg0impMea<@8WbV_iD|Mh=reGG)cqwJ(H`2`N+NeRBaU znqbjn3L;u(la_!aeL?JVU^e}G9GJz6zlA!;=ZLt(x|R=PU9;3~DeniZnapHJnSeTF z8zhTkCL0<54B0tL@z3#_(N+E$DV08 z>CVdyg=Hf!yo7UAB5f|bIWTF+1yz_6U%$-T9f8^}W#~w9!Z$zLYJqy*KzOCkgI9ye zpF5;jbml?n{TM8%%vQ?VNqN^(-c7)y3T;P}I$&7~v+FXX&5#mIMpe}iuvSPVCw9QE zGk7lSUSQJKr40p7lGx(FWXMQ^L?p{<7tYCACk5Lh9tI|baO>oDlY-k1QcQ_sbLfBn z?$Ybs9&oC`dA`=WInuoV&pvp5;!^7!hrA24#Y}CX^)BkjClS@^BZ%8MuvW+tUK!VRck|SRDgC-X6)Kt#x)G+niV12=Ng~jO7vX zT-C5Vs_d~mlBKglERTvU%Om~Z1kbthusrfz!)*1kJPxruQa|V5ql+cWBZxX7mPcLI zhiqAG^2~%o-ff^tCy+X`O`}d$oEXx}p2~r3U+Ix7dy2xc5t#Q3KwEw(u;TrV2%s!* z!kL*xQ?OX83J^9d)_DyL-V7kA14&Kt$CN%KYqd(v?a#6@%nu~laEHI%=Z$1JPx>Fl*FEu5odjneI5w7<>z{+E z6Uj2qa3w);#7@zm=6p`mVN1d4hd&;?&cN#wyms>J>_hVQccYP$WutN+Y*2?qIBTL@ zIqH-j?Xp;DY*BV5`%%O5YV#*$9f#Ktybc*&+v&d*x2nxAb~Ww&^PqagjYt_0jj2N$ z6mQXnjy#CW|#XpHPDhvV8Mq? z-YiVYwK0UpE=XlHhZAOg1|`l}P6g=lX*yR8NM&$ zyX|A_bkk3J>8Ik}xH*BVeRzh!+XG(6b}Wa+m8Vaeb4PL=eD{EV1pKw8Z@?G5wPwA1 zdtw1c?C)SG_~pS#U-5Fzy$O#q@Hkb3M~~*Q`BFS;;jtuM8k>U$S9h2(l(R>AUvdnP zA|pDl90gbYc7xC#E1lK0b#wu`9GJ#+Q8L?0+nywBvWg%;7yx}}nWP5!?S=L@v?9AY z<2R?j$9CB3++K`5Y#{%2lQnx`QWRgOh+c-lZi4YsfkM9jy4mdS2jwKEPs_O$<7a^b z2O+GPUht$zs}p5>*Sg#N*Ab~ zVCLql)$iccoURaj_H2dZfSkM2KsOi27P`HhZFY+lw!*dv1xd zaqjCa`LC>a1^XKOKg379{JPTE8PY1fMBB3?37VM}A$EB1%AEi~hoHivTD>)SZ+=Av z?XBxsw|7v@>|oql->P19Bk3-t>y^Z4uOJ^}E8`G~k&Il^oB?0)bZ{B#RtY+TTPT=m z-T^V&EH^1SA+M2{s-n&MuV=nnFq{2&(0Fx1H7JTa&{8ySeHua1+vdA4hGLP;A zKb5@nJX!f+?4nO15gNq`&hQJ1@&)3#~dlB5_f-8OtZGNJU#}42%<+Isu2R<8xb4Qo)E~)c= z7TFQw9}pF2*xS1)nS%d*`0w>+t=~0Xzzgwbz@1t}Bh$9vDRB0HQwhGLl@5|K(ZWvrhjKi1~v~)ZX1g&Np23EWNxjxB6?!=1B&RDH) zt;sC}b1*NYBXvJcTE|IC`B*jjBTdS~S1vjuG9=GX%;JSl^!?w2w}CuM{-nfm z%#V;?;qvzxl(bVR83U8Ehq!~Oqk>UNCnO@+$@xiP-c2RRm_L*(jg7u|Ht@k$vGwiU zKCS@Lj1xo7Q&?Qmm0u43IkAso68k7-V;{-w`6V1O(mtz$wg=wfSFzin`{K(;SO7J;I2s{9 zf@R*L9FBscN!}At*quuD30RZI48H{Bnp-%V{eR{8i%$6(B#ex=YH0;GXW`keqh{X~ zJl7}F!L#@{RY0G9VQFmtOU(G?eSlvtu#>=!^DN_3&PW*Nrkj+<5^?-+ma=)TL@Hy` zgT+sKx9Cj|TXq%Zq%le81@$CBjbul}(LUXdM@Xmcmu4f+m(-E;Im#*De^uJ?8K<1K zuWYp?eNL4%lXP#ls#me9t7*&1U!KjrM0k8Rf=B<-3W-G#9E4~g+`jw9A(G&m$QtBp z9G++4d6)3~aRg8IMlFsJFD3d!jtPghoi~xO)9@5u!Nf~vv+oz4=OcIyJ4ET^L*)7i z2ht#8L;A+T7nR2Peq}cMWuB$&Tt8A=%w@&V?b9xYWAOe^0XJGWHR-%^R%RRI{qUNC z*9QzQv#w&|E|JTx8@NlAz$y&wSj zSWjOzoBgaQV_tm`peNYGcUq@lx_VyS(ZQXntAo#8@-zoeb^l;_yNSK#%s=jl+f%oLF)s#VlTWR|=GcyhGA7Kby0pLV~d(Yl)J(|cT)g1v5w^r%)E@gXZKx`eV()(pcrM z&pP)4(bw)({Yq|uB2SEO&TU9t_Ji9G?h8%-%B3NpzXC~Eq|aQFkYLa}K?LYEcGh)+ zVYM?-gPclwQ=}Jr#ccNa!t^?drq|`9*KU*HBz(ZRiDb;2&vjLHZtWqxx|guuAiWbj z7ws!Lpb@>EEEIH%*5s(udsd^gt%B7ge3$&jY_`SlRefTe4RJ|Bpu^EsomBY8z|Vl6 zcJVg_eTdo(nlP3EXAb;9@EZbrE<2Q+Myu*lu{z+Dzf>CA1*uH$eo&@wXLD#%B=27Oyz2FZmHuE0uef$mq z+X3u@hDSk6CcW8VLvx2y=Qb`=b89)q((pQ)kH_6!%6D+ys6X_*?ki#CN6=OojgmmuXEB8VNLLGcPx>jwDL__Zh|K6ekuC8>e=k?gy)|W3iZXD39VOKn?}|B z^r;b|fD%+O7(wW-oj2J`R=`_2EG^SO!5`auyLDAx4 z^%`#Td)ghe$ouOWiAYn>+YgeDN%B$l+SzQkk==50&t|6@=yiW6fp>GK#6|Oxs}>f~ zpvoi$^}-GZbzMH?AQ^GKa)*ffdY78j5SwnvhwE!4lsFaJLB6|R#(MC(v%!6Yt}MJs z?e2p0yG^zW%|W=netEUg`{a%tnMRrDyYp9ln7H{G^eZ{4+^D*izAm{{L_4+io+2;l zn%V55`EAK!9q96_y~+IZOGsV83YD8J2|ew~H(n4L41JP1&Z*}54xAo)es4C2ktzA; z2Q~~$R7dhBun}NGz+}HAeM02>7MMFG%H-FidC_^|5V1nAOd8d1RE5Q<7y>ugu~ zDcnp{oK#zZO`>%RK?tJ5#2VDGN;mearLhB~`{C$x@6As)u(0aIqQg(E38j*rXS$=L zd-6ZIydt~JkZ$UAvqAi$JiXCvxh1R@+{#~LzX9&!`TZx)78HNA=xf94RXT~E@5$Ha*7Q1HlN`7_2<$(2PE;4JxgOzFgEh7#wCBq#t&qL!DR>MoGke*$ zIz04VmO%!G2&InfWhD=l1kg*p!Q^4NLvQsZm&wBsc=Ws+eJMQNTCCohSwLD@K!}ve zj{i98_7tnz34SM8g!Gk;tN6xA2VlqeUoSYDdFKQ}u-FOxZRWf1kau)O1p}DDU^oay zr&;bS*OkCln_S3uWv^V6V*mNZoSoJkk6dMe-d)dQ%zP`{F*PRThjs{BE8i8YA)KKm z2I2%}=$-s_@ted7zMJ13t}@t$ReT&P`VM{*{B~kuAIH0G2S5A1O&yOz5YO9_q6m_{ zb%OMFlRl!G`m5vL3k&IAz$E^9;^v5U?On?4+PUu4me;+s9&Fi5DBGK6v!9|}6L&`N z=v->n?V!W9CEe@9<&3w;vD<#VH1^ehIhB>TJ+baUKFrP0oYGl<h!7CF|eqiVdHSY7eE-E*|{N!eRhyn^}q zEwe%FZnf{|QVnjMFDmN5TL#`Jcp@`|=j(NTB{QRr8-=)oV8VWoI|y@AZ*#I5vN3oZ zg@=q=;i1wZBx|4oW%Xk{SF(vHu2Y~LfMyDs-wbHh!I*uEY&(I;9CreoQ{bp`?1ryg zCKTxHHfWwT!s9neV>93m$+N{J>`Z{mUS4Tl>yzBbqZ8=|bs2O^-a4E8nV~b|gLd1V z;0)_VWq-GYF9_?MNg@mqRVzT)s+83FRS9q1@ZCoss)MA_MB61ED(r9K4Vdd+a>1Yb zhEmoIPD2IO(#K}V_ksG^?7zz3pu7=dldy&oT+)Uwln9Lyl~LX$D5ZT~&T|Vkj5OcH zt`XoztOqU0hYf}pbR?3Z#g4zAB*a7bdRBwdQvD#z*sP5G!B$>>_=C)_`Auab5Khb+MxA zEW4=Y0cdtZ^P*r3hU}slf0An5O|c}-=gyLiyl2dNy96#kR4-U#ab>;T-$kIzN$50f zMsNoK)*GON`dk6Pt?L?^99Sv|Nv1ONfIt`FjCr&(sp;N7DK? zS)ZcwUhTchiPnPxMMX-m>yg!e)?>NKrA??HoG@zZl`go;Zid-Sa0e7BWDOThNSIA? zG6+Vu!r~2(wPWNn(>`1LZau0M`68DCiIEajN8AwZBx|=o>i#k57uBz1;_R5suHsqh zL-iZ6)5&OWC7y^`BNp?y58N7Xm7j#d#fBw;HM`|MLYMIGIC$gW^?~;{`E{I=0q7r( zS%)sl!FGp@ZBR8fkD@AAqQgeu5OJR(AUK0sep8&D4UCN`4rXP>a|9f*pN7YUH*A%pjrmgp69)n#@`F}Gcjmix#yViN1HPln zbL+4>?{KZ;Z8pB1HJEDqk=^a3ljx%YOPq|!lkl5_pU6PEod|a^pbH{(KF9Zcd>8v; zxEw?vqsEb0HrVp$D;>2?nwjrTrvO~rlXqE;==qJl9y!_7H>}Cuxubt4>20sVAE#?J z`=Nx+N5OiGz9ssUeXF`Uu^lT_L|;JB*J3^Jv`$7}3#uZ`^=52Twv~QwgL+;srmCJm zjkBEl9Di;jwt4?<5^z^o68K(3y5fi2M=UIS|M-^xb>zLr2~^+YyeV7jwyM%t^{UzI zHi{pNr?vSNhpJ0;K&4yOrVx6Rs|7)pg#0+X2H^Fbh&JW$n=@-mNPv6}#3iJ25}@#| z{Ioabqm8N_q2d_kXF&RJ$L}zHdS(<`8Ch@4ko@Yfdg#dvx67HajX6Y@GxG z!Ygl`U$;2LjQVyw<<2LTQ>~!E3`%)K&KO>b{$Y(7 z=e&!aVI0^Pu%a>ZnX9oeYSjpHJFH!b4{f4TiU^ZmNmh?`;ySsN*$8zGmo8JXs zeZamE(NCz`TbwX9I6=j4C{a_Vc8Lz%`D!hvg zcNkd3I)kU?SfmNYzRXh-d|S-7A)bS=zyMO6U*fqtHXP|6hru5Jf3=H$tLmX9`o6Zq zNnXx^I|;76!zu&pBCvzNPPz0Rnj4j1W6~;!8KaczT8~m zt|1-n@Mi_Kb2QEkZe!}0rEruwt9%XXH~b_-zx=87A6PZ8*9*X|k=pibrzvseRQlIG zaMR#^)!;_V?J15TEYZq))@&VlnO&fk0dewB-P)aZ+bMLxRsjBz-{YjWi}YS3>G3D) z^=V)`fxSxrF__}qC$yU$OgamYIw}l;a z&|Zt78-qvs=2?9o6K#q4B8XXp)Y2^DA`RYN@H)V|)1(#H0;;$?h7rn~>gfEn794PU z4yx!>GTP}m@lEEr;%fOl3 znA2<50_y;_3)nc%wr_|(1AP>K1{qD#ZIwT$QYlzlDY0@D&k5+yKrj7A{%ZK`0d^Xg zj91|qlpW#3+;^yr!GWElAt`hxp__wF>MzKP=rZic$;~Ah4b)|?sG&ak(Om{~#x9Ie zh2~JcZ8hLjfzwxPKijAli9r3!TEc;6ae-l3AO@)SHs|tFnY+X4V@6OvY3(MR#kb66 zTl3enoc@{UnOFjd4@xkUoQEKtBIJ(i;m=U8Kr|&~K92n!<=s51z89UT>&VCYJm#SHp2vN@lMm9pLF0)8ACF@{4PC63e*!xN>?klh9|&v)*b!i_79{>;-ATNT`4-p?0p$9ay3kSC9fF+!Rt3zpLCpbM62dEgJ^c-sbZhw&ekow75MB+i z$`HQ{utmVi6s4x^1GW&D)k6!vVPF-&8XdfGU>(3@+{&NeO#&MQ_HqT$V{<>SabR5n zQ)>^7z7j}pgC3jGepBEa0Ou0++iGlO1)~9pm`J^JTSm`nyG^G0b*Oh@@oMi|efUAk zd)y$7%SIF{^0A*^-!kUI+p#qj?-O<6OOQc(=SI0pvpjdKR>2|l=?a}*ujnXpktJnT z!PO4W4eNzp7vCo-^?$9S8X%COtC!v!Q36rLt3F!$M%F8Mqo!7WlDBSP zGr(RY5YyAxP!3wD2jDEckZ$J>%Ux{ogd zd=Q)}aMU`h?p00apHaillyln!eY^+S8ECgb`|>jp`QZ@Jc1(zuL!U z-h};nD0fcL$XU6yg0-s8uhZwubbn5(4L8SXiSf>?$HFLOjcgc3|Pr&8Q@FE%e27BOHNMnja4EtAK*7bdevL?d4M8ymLe9H)c#sIW>7^X zwfZS`p#{T<3)g^#M+CEjtV6wTDUF>aos2BHC=essrY^oW>a3TvP6ui&PIMwM7JDG> zrMk(ACCUaR4#@8FJ5XRjPtr2x&ybh>_u~IvykAy(e;H9ixxc8e+-m+4zO`>T6dDI=jhq7vKiGvdriBdMLGCP=&bf z_P&$A#Dh-kE~Re_?zBKB+3pW>O@w!V`y{*kel_6DgXMxBWB8MW zU^J1$yZvqgwT6(WI=Qd&bRFaCQTkz7k-B8BqN1u4bmYb)mjiU*!@oS~J*Up;a?DpB zQ^jFHgbt!;>(B`Lo(>U6jw+NDJbm4a4R;OUoYX@Fl(eE8QT>#nlrY@?pg7CZHorsN z!BN+5L2M!=OKk*I7wuYPCbn1{dd6juS11(bJnE{vf%){w+3dvyd3EK=@Wb(sd8S}) zhrt%P-5+bkxYq3t6T)(&Ssh`l2fz`=_?M%6grNDSNLCyCkrtP{Q*(xq1fd@5f+<4O zq(3G`z)tBu_Q_+;G~X$E!4sBZ3(Jw*8$8~opQHr+!DByFvA7X`<#*3!|5oOYwqPzx z2jdYJIPdQxh9OGwAuzKZN#Any}@fDNy>3|Pl~GV1Pf zhVnfTrQlwRh`!s7jyAU&Apn7nM}P^3%yc`SI5)(=ZkHjS!;kfox1CMstN(B|`|tVn znj3>i2JvlC6odM(LIo89mjE zzr%;jd2xB?R|9M}u)BDc@$eKr5arwB-p!`t30*HZXTez`IQ)scGz6?>_iXlQ0nnkh zd)|O_Zg~=#3BK>;`^)4zf8G4{06PGzUdA5%%#o{}bUL@(c4eJ*D2uzeieHS9(^krI zTFvhQJokTiHhU<{(>O+R=cdEDJ}GkAk{0w2AI;gppJwlAWpeM!uC&eE^cgE_*SjCY zKASW7kjuQU4atXfHrtX_q&G==$M(!--_A2~rX1zMyv(MRf05wzUP?;JoNyYHW8g3O zBhDEV@6*-ZCnEZ6Q<7^_7&W*1)pzNB(nA7fK*>N13wYv8SQA`%KzEEnY9Y{rXcHLB zD;zl#sgi-H;UYYSx6H!Zes&UB=U!uPn$IL`tcPrduNhkz|VoR z>yzlUFI88EBQhohmzrXuh>rg5yqza%c6TExuT8d!xVJ(p6Z8cU>*tNRx&YJJ>s~5} zHTi@z>O2W?zaiU!yTsb!rN~^>Cz*GL+L`}8<(|1>U~e$fZYQ@+srgsW(Uaizg4+UJ z{=7%e3D)#hb%(}LaL2%1A-MGS&CC*Q$v&m87v1a`z8~iM?V`ZXt<||T1)BIoJfh)| z(LM?o-G82Dt3KIj`@87S(;dXG_^h#s!3+H&5{vdH>*w1H-!_65YtHv46U|OwNJYeP zU&WuSACf)LSA1?ZTUUHutBaH~$og080&JvqqyjAuGr0AG&SRpJ_3%$-v)`9IM%Pcb z_vh3@cn~5)?Smu@{ltOU>^q8&_kNB{4AiTO^_oRu9pLIbF4+q`-{beMw3q#HfF^|I zk~cf#!E;aHgvz$d%9_Y*#gO2mE zgWm)ncHVG5!1!1R5FG1nz(J4SE`F0>>;|?+kv#wv&UXq&sM6r14NjB6!9fo?%^9b? z8*tiF?>6~9-X(P${rKtBo8i+8pEPNu;gk0F^4mw+`}zOC4eb#v1shutLncctB-a9~ z7Lz4mC8cdQ*|vpU4NS>RRb7nVgR|LNOg~X^>M)tAVcW*7)#^Bv){XXpI|}Zv3NC*# zPKJPu15@%1iU1r=R>>e0*=UF0|I(auwj0&KM$KB*zI}Wjg!WZD%U=h-!-n6V>wXuj zzpBVkZ!CSL{>JN`t-ta5=fD9aK!BH| zQQnO{_KRj58(0ch>PyBS+`wvp)dEvCa9|>@WPl9 z!9NCmt-%lEI+4Lv*| z%aIwB!#eZ;WiAkq!~sKg720e;95W(jX*;X-xcNWqy$zUERrUD4@45F3BX_utIwB_N zsAHj$jfF);H7|Ew8DM|`Mj2&*5fMij6%!2$9RzHsFws!S2+=69ut-Ua_`Nb?q<9SL$5U@5o{|3IPsU9g*uZs;{;LCP1U3kmJ6?-`w*rd; z`>E3hy00tehr>S%#axGXG9H$Ix9g|)qDt*6zbw7TdM3l$ac{hY^4lq&_sm;~pJiL) zaEq90UFrB+AMW{02Y4w!97E>fw~_zFMf~pE@SAen3ic%X%Xr80x*u8lN(k-~NDNoY z`;TS)_!;-+5gsz{Gi@BlW>>`K#Esm*7v!00M9X5iqZbfs2Ygx28_8Qo-Z_$2 zc|sq4Io8-sWpt0GH=F#;beGfq#yL$BP6peL7VF4G!JX zsLbb;)Rnj8t;E^c>MD;l&(Q2uwT@eiNEoxRma5qFni$T5;iH-v;2A3|kF}P^+UjD> zndg`FPhTlllU=TE^fw$f0eQu5lJi5xL_M$#z~np2H(X#L6J|{4{hz#9FTo3Y>tFct z5Sh}S3&~rz^{6`iqV0sH8G&6nv0`9_1j0#)Hh8e>DxzX39AMlX{YUB=_;S);Plog9 zV2+j4RT~>rrYp2oxm7hJE1Q| zi4~3wzBoeC&Z&c-Om`L9nYb~Dta3~sWu4kddj|Z);YX^HGAhvnbZ+8||C>vhFW@~d ziWYpY6nj`4Qh4TjrBUM$%=j20%vaIrDY@a*cFObQl&A42PgEssoI~B)LkALlM1duI zQb-oUQ7l?S9}(HuN_YKQ3EuiX2aJvqsBMg&b->mE`<1jC@tq8`7Z^*t>H^sH$focj zE2emiEC^Y5c&RmB>VILrewjeGgzvSbv#yY2L0I?Oc(=FAd>=d!eVz{`zk}FpmH^8K z_Jl0H<~vl%p4HcS%4|WKs-k_Ze?$I#M>aMQ`LJT`XCX>`gQ+5o;9bs*6p6@~|Z?{M(e z%}&cqJNAM%ee?lOH{Z|aTdRF?2*@-;Yry5`PlErLI8B=%^Rb5Mc)cVvPeOARMEZtv zL$N$z7oM-+D=+q?8-3}OzBKNGJpBKKn|^z*{jki}hvS^IFnguZzICaO=*{Tfc5>gx z$J_jrWmJTxSkeT&a(9L96&6&h`Xxf3q?XrnZ(Ecqy-XYk>z_%u9XWOFiqQI^5KaZekjV zwY*YOGyH7Zfy8iOez3D;YQo-g-n*cH8FK?up6*(JXuwIZd^#yv7j)imH!<2xjB^ts z+=Q3qL6EAL;*;IPJRrcB7*Zm*v`WUp~v zme)8h%Y%3cY4=W=I&3QZ+xHJ7wmavN1y;B@?6tX8e9q$crU#|BGuzm(j*f-tv z9^}7}80l7uj|JKPTCit&{6ONP@=bJOh$rPf z0W9)lb>w`_h!o99zTGVnkKtMJ-{f3 zs0T>H_`d+ma66{OO$e8yzr}Pn5qA^+%@Kn7lhckH+{72$#B4W_KCItO6TON3Zje13 zhG;RrEz^*PJaNEhn~X|{(^6bVI4Rs;noiU*Idv8KkUu)0{ah<_lQ~B5F`Z#uWrj8T znJK|AcXIfwG6T{EyoX9r2i2PA3=;2Kxx?uOC&OEqMcSmluZ!W1o>DT5Zr~c)+xFuF z38tqrFT(?1JWR1EZX$i4U`^p5c?r7n*5UA=_I26&L; zOL#r4<-|v(BaeLQKq4;dH>(aGU-kh`CJQWY@`a}-m-Or07T)A0yj9cN6Vpeq2WfCi zr8nMN1mzgHo<5K`McT!mz*Yfkd={9TbNFlI?71FT%g+xa{vm6$76F9!$XJl} z%RrR>uX6sE5h2gG2Qi5+IsXe6BN;b4|GS8?M+#gGQQ$Q#lJBmY z<`$jh0HnVpLw3#o=Kr#m47i5#-*X3oe!Hz(UHOri$0kKd+GkcBWm+~K@ccda&zN8G zUv6t}MV`9?{e2fwb~a@{ARm`MX~QyL^MGxTgRb?Gbb&s5mc{bJ<>zoA=A3ZDkAz}U zrkdYY%H;q3fVpo6Ax#cviQB=H+x#kVM3Le?2Rbt52DV}k1ueHt8-Nu9D+X39f^g2o zcUsmfp78~468eTuKM(ROk5s;iOP0vSxL`Gt(C)2Rqc$?b?zG-hLdNmN8Y#y3DUGR( zq9yKC!}7S1QiFser9)44hU=muo7T5^x=Un z=fL=yv-K>XqYBz>cE0>h=1{?WyCIhUJS$sXC*REIk}t6FLC~Iq##%uqu}$--RDU^m zC(-D`QC4So7i)^}Qh0PmPR(z~b*xY4btnELfJ|dde64h4ko2N+bx{a-ZD0hJMz73( z%?%qmVnZslYjO1aB??ONiK^%D+dx~Ef4DngiA>!c0}H|o4o6oW)wU+B$%&FR3YT21 zngmLj1Yp98fk|NfmUbtBS)!{mkkRORC{>osWIhb)PP`@c(-+P?HWuV!+Tz_=*F?j& zh4h87xfs^-YYt_5&hIv{cqlGoXE8AKgI!0{<14}EWLjJ4tbb<&LsQ1iUg&P7F72bp zfgJ(1-3O}^cpLiiz#b*-dmqBTJBuC0L~b%Ju`rA@eRxXJ0ZP5i&?~v1+q*Xt*eqa8 zz(mbl{sguVSfdYC2y7X!24Kyk{cUOT(cb{hVqZBK6Wf6;l5);B@vpq@Mq zO?zq6VcPU)YMYXG>a>ZiA)PLb!m&YXX{;@!Ri!xAl2)N4qg|Ha`**ZfT|%o#RF|TY zp%rXRrM9OD-XWDnZ}OF-txM&11MMB$owz&o8`9qP2s76Df;MfbatqS?Wp1a*jXBdC zWA}!#SR?jz;+I$)lBRskYWz`2j-N!ez9;AU-64VXj~)})aOe;p^rmdZLvG|g`6J!N zHyC<67)lY%C9YK@b^MwLI>z8Nffu=`J8@^~I+^Tq?no_e@%G~I(u9qy6M#Ha6GO5p z*27ukFiZCl{+}DhD`psVsxV#7|BJ&lf}F`5bvV&c%vGJ=_@qo+0-0(uQRZW&QYI9o z35Y3yA|=qJzLHDEj&wl2Xp#bv_imWQ{`%4G#I?tK?{fcpOFdOt-W%_qsjZuyVW`HV zVoe+zbQJ`hcn`0Qk;rkpw!XWlyNUaui@Otd&X z__M%YB=X-(`=~e~5C1lt@m0gW&3uk zM4msykoaSj`=|Vy(N`VQow%B`d=qCsN7G({x_kS%_VFV7bqV;zW4jaAr{dSLkZR>H zqZ4N0aIp1bUW@IYpEJ<=jOV^Y)7=lPrO<7J?#Yg9F>MdgYsaryJKT`7W1Zz9?kpFq z&@34X`7PqNnCZiE@ngnPaQ%(bTfR`X;{vnArROd`E_sC zmd)b(ESk-EXIyvU^*lO&UD|X$jPsxS8g^LD6!SHI%w?(Y$4LM;si^>b+NS~t4RZ`Y zT9Gusv1xFdnOaL44Nfts7->Y)ilhP3Xrxuk!6CI44qvGNp6S3sx;k$>TYE$lTu_R1h$-ZA#xV|e&MALMbTZe6L%%lf*Uyh8FGN#!My=Q~U`!tcnTGN@6e?RV3lV!SQ&9ER@f>$*K( zYu-9P@Y-16<*|G|1O#;k&>f@;i>Ve^t@uxxp!^PUz zPy@%DJ`Q{Wmt)%mb7d=ka9;EK&l)YFXhv?(&P+ZO|pQ@j7{i!FwjUj(Pi;puT5nwVf~av~t>$~q2OGhQQ)V#j$no~rw00EF zar=g&7PiaA^NQA4F3#j7Mel=h4p@&EAA5bb(dXCWp2L9N@U_vdmI*e4vl|@O z_rL<|6!Wq4)8`2e?fC7$r!v7laQ_BpfZt#eM0ae1{xZrwcSE;{zfk3g|ICdWv&gfZ z5oZqrM{BoyvwSM)5E~aOBz{PhtHn+Y&8}^tB@@vjA@;z+(&f)ZAO6N}6N`+|jaWP) z^JNh50kgV|JtFVwoT z!J-rkJ7bpT*=3;tm~u*&Hy0&HBN<|f;lu;iZ`kFfg!-tCu4nx0qwcjgbthJ4vu}r| z3f&mnhqvhc9BTLR+fO{(-61(n1(%mvT)6LrpElU&iQ|cTAJ6;Yx_5^fVtb%s@?99} z;^glIz7Jp42JgB6jS(KbbX=5Zb&D95JrFp|?+B{lb2%(Z<$HKeZIHE_5}YJ;i$t|u zHwkTZ{en`8!>4)R;2D~jfkagX7zfsr_vS3Vk8o6`npUTP)Dm~Ao()jmT!7N2Qd?67 z#O4ezYqZluX>YYJeVH$9-Q_&gg495IlvB0;`;7BZmoF>?YaN&$Z!EC!w6@7tf!j~I z(@K09SNYP!22Jl`&fNN)#|4@%qlMEh9?SU*@*o|f$)jg$x=R`*gGc7(Jm${ocJz&J z>rV7bT?@5loEG(ZzIR86M~;ROI{Fea4!of>y207C7Z361VPdC`iPeXvW!gT)#xHHq z!(Y&jA@f-8zucYZ6}~FD7y8>#Xx$qd+@ifRa;BGXy(~{?Iu1f-8QRpJk@E3KEOSUrzqn+17Y`VOMF#n5<-kLV%qnA%}z@ zgCZ7+;!6R)1e4s;2Zs@hqloLElx!!BW3dr#TAxH5xD;5boj+>Es<le;t1h$v02@i?9#t>`qiT{i)B91ktURn1KwxdkW1=D?x@l0AxmURTftop?j3@g+@F(Uk~h3HHk2vE zI3~@4lh(mic-u<@LQZ5M#b4!o1byw#;Ko>P*$H85oKyb*^6SYjey%%l9%(anrLE?U zvz5F!c^{KJ{^Wh<0&4@7ry)i*u>@Evu-^$xze93O5nnT&O;UAKtpVjZ@CR<}PK

Yq#}#9y6-5?z@mip-I-AA3SP1z2fWf}lOfUlc;pG*v&JH|WoQ1XX5`7NZ)cgBve zB{nPW_gqFN>NTq}igc6p8RCVY&!TJ{b$`e!n<^6%oTcD29s_4RI4wuPk^a~XP8&Gq zN?rWPeCh$V2-v3upx0N{N7pxaE%CvfwhC_HV&)ULiyd5VT`a_3lqVvqjBaO*sRK9i zVt3+`*~Vcd26{7zZ&=Eir;hX(hEQkO*)pY6%K z9jc{Jt@cs6#(_yY<4!kB^1-BQrt*dy>UV|8ohl{%S88;~YQiA-UNr7dlfJ2QGMa_T zb$%>=5veoSUpEHYA)iRbK+!i?k6t{@^_N2*RKrg z%|a(%$1Eg&y2BR8dNhRJD)J9g{u89lo}gu{$$f2VET8KS&p2))XmNhKDW`UHdpe0} zdxKmIq^#j(azC8{sfW&>CD@BY$GzuFqa!+BndUQklIgSAtkrX%IRu*S+9Z3xVqo>a zg5N{(R+HC~A#XZ)o5`C^-c6*XfBf=ELP~NO>-q68(Wo*$!raM7^rWIy(OO?wa`oN8 zkb7A_sY}MTZ~PHn_;Nks(As8IGj|8WKxqMg8Td!>2R6|9QHDhiUUwzsS4w@q<=*=! zd>pEJLvhhg1T|zWBYZB`@P;_i5sMbjj18%Dj{?ZIGp)1YE7}NAizjDjk!XLVFTLDH z$XKhp5B}zN-HA%lzHh)7ZI3j%AAnB87@BG7=+tmo=<9HOueby{b-XKp_X5uX+Y9V4Fjtp#9_p|da*FG^%dW!mAdv*e(RsQy?ECd=CPb9 zX}NKYP2viDLsH=$2*$e!cxaB7AY>Xxa?d7nws|S*&!4-EA0*_HNF!16HhFW%i)6@? z@3oY?T=FC>f3gOycJO5n@Xfn&LJ7H}i#48uqSt3t(Lzx7P;MZ!#z?tan3y2I_|6Yk zw_EWA5q<9=S)p6UsL-6;&>4A=$ih&cT&Y{u?lQ`{dXw_KhTM<68nBB=2giA{W7EL} z?j|YU4DMoZUA|S;j9I{z0lOtbc_N?srbAUU?mSg+SubVRPJw+lIZI(dEe!f-A~!$dEZ@>9rD`ol^yUP`^j;Z zZJ_LW${tT&EvBsc%ki~&3uWWSSvGf>tri|f*+RZioU&Ue>)si={2hFR-UJ0_Iyi@q zf+K6wB5;acPs(7@)+W{T~0#x$P#P zxo)@2-@dh5S}QuW?UzLe^BdPsKNx;c3i~RIiU)z?t{ULtY#ohX>L+v)prw z@|p0!zV*e(8zK*}K0^D95VZCC)Ux%w$P2OhpsGPQ4OG{RtW5f32>5w#I5JG0WlgLG zHVBy8Cn?w-wwSq@}(T+;98#tcvJx-%}Y|idxQZtp6XG;PkbI6O~bY93vUi(Q7Po^dSY|I)IaXuySD6@*Hb{Lq9ci%gqI>ksJ zIv)LjE`xViMUrQDqQ#W^%gwu7ACb<)V?2?+n!G*G{FTt0oMBC&pG0_4WPIMTcvMG4 z%oh}~l%jo^#4+{eu3&xnyR(KjiH!9cEw7UIDJ{NTL^5v0NnA}j@`{5 zu6v1NB=@pqE++=>f@slwU7l)CzBf0yg%sb#Zz1$HLvN#WtTyxt%xT26;eH_UtZrBJ4#BJ5*+KX zR-1)DvtG9e=ZvOJn6`Fqe16kFUTONn$UFBr=UV0yZbRt>R29jSdya+VZzf;PCDNbH zegUQz^Fw6yFx*_9k8`)bdaa$rhR7Bd{K`i5vKzYU&F;ii4qg8}iA1B;D?k;Wq#`(#q&p#gvwZ!Sw1?rIVw5%?;*@xucIa2;SROT7H|P|e`Yv}d5ay-vb@~pm z9`ZY>YbSLDY!s98iA8|uF;v7`hgXE$B<)WliWo-AF$aGa`BTENKXBJP*UG;{CKLLU z`s7k6>aE^nDx^KrDZ7xeBS@>!vcA$3*Y`IHKC(tE0%t8a1%hLo{2L`)9wmRZlYge< z6I7ZD2`_&Zpe;`RVaX4)4|O&y0QQHGT!$?*BvW^PBGMb{D0lt~)4Vr~zLr<0Cboy? zy*%#=qdgTyFHWYF%(M6^`~j;T!*^Du%HGhv5JuJWz?&jot465rOmUgRi=ZnBQ`3~K^ZGgwV5 zHdLY*f~;KJY6fpzQN?vRb5HP58yixs?-IEjFVobR+E}MSK{OfsavnrUp43Oy``O<^ zzLC?DxPr8AE+oe%YM|qsJu)q*2Tu6iw$%FeQR&02(9MUgE3aq)wg=deCl4i_O0CPk zeieQ}>t&%iMJ!-Mxp?kJ(SUzRvy97B3+^v048FC!7}|B;$6oWPLxvCHTRH1F62F`D zXXaFaTMXzJ(WsWC&ZW#;%8Zq^@%H0=QROc4rOVkVhk>#N{Cc}5@j1ay*1>Gya@ibF zhy~?UB7C0rApNu7DW4=G31TVbYUgH1^}xD)<)V_5AVW|#WN-WeMkE0DZ_ie z=*2tMy~aMG2^zDYF|n_qq0c#v?NRvZKE9(3dT;Oe9$9b}Qe+wBmz>z+#pX#nL$a3+ z_pGC1#h5szeWhCV;-t|uoC3i;jYYMQ-HmqT!NNpjC@+lZR@yRXHT*1XxhnO{l^n0y zs#=zQ;g@6^lz6|G*;d7>D}^g6nU;ZiRdk$hGhv5nbRW&;H^JR3$r|NL6K2O_vVb#( z4LFG;>oWX}a&UyDIhZ1@% zHnBG~GdGXC2J*H*cV{-b^!2FNP%qSpSStU5Omq+Vi*>U_~Rj6x^tPDZv?uN&*A=P>nD$R?!sg_?eL zrLpUSQ%VXP5JXE~>;-?ofS$w)9==a*KGgCRz^Wbm0Y8LaKcgq{W70z3ab2fnDX^o- z4UO9*@1k#bRAL}`@=IA;nxRuXu*ZvW8ew0W1#B3wYrM9k@ul?^=b5xY0jnmViPGTJ z(Hb4tuSV;55LFKijSB7JJ8oQwGbgP$1%sPfDIwW~2cjU+B}_qMN1ZH~X;mnViV;gX zHCWV!ilohT;IYD&xrM%&vj+bE%$~%!i0R|B^-c6vP%lh-Um13-See(wW|hWfSD7<> z85ZefSfpd0$Zs+C`5Bd1F!^{R)>@+rV`T3XcFoy+g~P>Yue4NXeHQA{e6atq&X>t} z;k(v7!FlPNp2Xcp`>tG3r@arc&zfQlHCkQU1Z=dvnh}l9jB58$KQpQVX&~P*393)P2#%T)v8b02MuU(k~{KbwAz%(u+r^Z4gmZ8SVJSPE}-L{+ateKB~p^Yy2n3&x?B!mw0?$ z+IpV3Uqxs0c-JxZg4@&k)fw6xldbu&*4ktAD{D!33LA>Qb2yi_nBYX-$4U|n7pGtk zkB0Z90MJNp(Z#*b#QI!n_8|F8OH=E5A3wxI-%AYUo9uiNdC<_F#Qh?`*8D-*H)*pL zW|&_xFXu>Dj5_uc+-)E+U&Ow$nBNk9OW9kN@mtRR(w2E^3=a**<_vcz$d2SvsDMI+ zj{=)e_!2gmSw;}8V{t^o?co#%-tl+P$37f7`5OVi4S{DmHnjlmW>Nr5pk$@{=%U

h7khE|TcLNi8DAXOjNwB4qxKjh$%o79iS6NG-gjwDPh!u}*1|a% z#)mNG$2(_P3tu?eoSpIR`r^WH>J&{~3R%GYJ;MRW|9JF{y6(LoSNI4k8AEkX!~fLx zB#QpaV`%=n97BTxV<^xUaH~h_DPN{DhK4=E`M#ki@u&at7<%S?7(>luiE)l^j#U#)+{Ed+JVUd^ ztR$_Pp^#le9s8-{k6s-~d8oDCcZ?k#tw|n&jcxxv$}U-XC{ZD0k=%^ahUeyrg{>?i zx_@GR&LLmKZCW-~_%rMsCnaTLn<+X3SQD@W>!>*!v$r~OaA)&`qq|;jF>LiLa9OXt6PC8pEU4xm1xAXi#MoVTn&jx|d>ep^;A;cQ|7y zgA8CujVt3s*43)h$lFPe)M+COGihcPmTc%-qA5fgXB%J6(ACCISWtQ)4&g+yMtF7{ zc6b4ftF;cOr~NqGmA(n@R}oljgr6TeLWkw0dE5?oB7fbVt-s)VT-lS5zLow&Vy$PJ z^ry&*7CHGRNj`rv-Ylq*F<&O)8Nn^RlF-FE%Vw%*&@mYbTc@cwnxVL z%Od2JJEy!~ay|rqveZTU#2a!U$s*v(fV+1U?F3w9l$1suukx=?J@qz z+__cn6P=<7kF1buJ8#W(<^}GX*tldI$UWW?=nRI=zes27OYYqp-5ASANeRZQt>O#k zxFS{aDB_ghD6fcKmA*+*jf}~>=eU2Q-Y-kN><_o>>kpb7}JIkx|yAC0LF8L+oyZW8Zol#vZ|LRx)j)=@1 z=d9!<4rS!qtfSmQ%FQG#edLuJaJ8;sW>QG4+p!n?&EQWGe6&=q(HaWZ=yu3F%iYL* z+)U)dlAme(TFV&oDXfLKWzc#Iamp^EY)96z5;`=cY&_Z=1XV<RXvMzPC0*YwI z7TU4>3q9se23Cg4@v@)~2l>`L;B5hK7-{*|tf;Jsbb$$1Tg@fKosr98+MZ@3`Qkcy z6R3h;yb1kz%If&1W4@ne*It1i!}IMTM{M-}9D7rG2x6{&#v3 zE6z^Gx8Crz2wTYSr98qTP-HFTxBQZO2Jig>vMu}=m0FWxdrIqKdrNUQREp+DDViUp zBYtl-$tcqe|QBeGYma(nW=rF#ea>xO(#64(;mN$*>!wc z-))&T{lQ|`aidE|z6~T@6kTIOhrufAXFi zfaUK+-$ek-LCw!wvmK6GyyVNxt#(SLb$IuKzXp6+s^w2&7e%(9zX~i*jGdv8fp^5z^Q09hJj4E(R@6x=zQjY^Y0@p3TJ&lrV5_gxmmpc{kdzm@p0wMzI$tBC zaig8aRr}zhq!}+{s%344)lCixsr8KyJdeyk3Q?Y3C;iSAjFbG$`lAfjRQ;ca$nSk2 zEFdzINgNTSRzHg8xbOAD`=zf9l)$t&m4x+V0DvKuTebCaAdi5~fzlPu3;RF9 z6%GNn4c3(a{LLIop?Co4>cI2mfin0$OdrS7GQbE&n=&Lu2A&%N6(Mji?~BNOiVV|W z%WBE@w?0VFVwH6%cps|*KXZnZzh}7RbuldzYo22|m? zO_t%FT!yso%GuPh>OV)(ZDKpHUdT9gaLy52Opv?K?k&)aAL&W#BAsy^6W%#f-1t&) z_>oRic*??;;rF1a^*~sc<&HWcq9ot@6oOX`-t@P8(iMla8!nO%6|oWcnUISPEXM-z*b;GEOipQP&IrjUm5d6>s7MxRkesU2B9%hyQm=v} zb|%(~&cmoZIARNVhpoIr{>WZe#*{V=g^%a~Cl8#Dkd{B`?%eI@vjH0~0Qx@VTq8!A z?$joG4!@z`H-e98ZML~qh@y>1PmLvj^>5c}AHxlPWLAdFtP&BNcw#Z)3(;f=o)fix zx3qU1_0JyL>z#K}=F%7+Kj^e~FZip#M@*Hqz2QkAe}iYGHn=TggR#;(W{X9pGkpjA zU1M+JAEbT#t7UOmDUFQH9&SX_m9e%No{*Y=6y^fmm2L+_&^1x?b5f+-70hxi0Y|7V zXTjan+jeQMXN&5c@A9v5_W<$F;A7G0c5gS(=Kh|7pS~YJbR`B?vfft1bS{DRR(R~l zSBIa^K|0lz4*_NQ^Q9(Y`fzm2lT(m8>~$CATaWobWzi+jT>M+cZ&Pn#X6hXD>(dl7 zsfHlqH7=^O4(t%*uExJICiY`p5iJ{I+5jq#&T#GZOSQLPeDS9t!BnAF>$$)ZS^1#f z;eUvBokJS_TvmU?3+eWJtzqE7%4cz{uTQ8P5rkJj!Vih=5SU6V2 zws3E^75|p*9fkDu257fI`zU?gOkcND$EF)uQDv+-TVJn7v{mADA&5<-ur+g1(*Hd;CY2Wxv z884T)!w$I*QMl4ZOl8#ghZrsAb-6adTmWNiRLjk1Wm@VpYxD0}a3}XBJ}GtaH-O(P zV1t3(Eda(tHF4t?5Q`v}v*=>-){r+-7I{5ZxE6Drnujkx4G%Z$z&exx?rs=Ll9>V0 zkcNX>E1c&$F#@ENZ0ps~3m1hX*+lZ%APyn8Qw!lfA{B635HKwWm>dMO1OcrrVNIjDbyrjCRTqQ_v6~?x0C<(-44M??SG16CMuN0R}l8XQrFwg_-amM9eg$yy9{j z9?M@43D@K@sA!?rLB0?c-aGOl4gqntZb+%NT=@S#a-Y=Eo0uj{n;z`$-5;dqMuNd0 z+*&7Q%b1ca1E(bnY9~a6nN;QlQo>RAGqRS*T1VDaWzBf+bzGC}J+94`fiyhxn`bSN zHDhWvQvZ$jXv;%x!Sbls+3f`` zz~%zm@7=3v8L3~kQ5b#zMe8)_WNEaC@@R-wPDX5)S-0g%SG^C{ zmQ!6L*&5E9B9qz*{i~s0o+>{|(&t_w`~lIg2+BZ8qvO+oY9};{{)Vjc!QRAQBRnL> zb@H9Xud($V$3?H-19A8v)XR`sB>fV{aTFZKQ7}PX`Rylu4@K{B{1FqP5wQq>Oi^74 z5k{-4J5#SwOQT$$B1cKqFhU5t0+8!TsxV%HGgYe!c^!q)&XjL^a;y-7){y<+%>{3i;PEZ>efd;JJW?ISCsQty8&znsMdnrb4_hq&cXo-|T!Gv(Gg<3`Vxr0U7RhQ_XkNKu|@dRZZF1ls(TWYho0b`di3b zM4qd+F%X>Dz*Yg1Fhb0!M#5ARnQ4TlkGRyy|Bge?Y0HRM$&6UM)#v_TqOTViwT0ks zr|iIodri!BJ;qc0%TEXAFgSz2xxt~IwpXK+)8f0@(8`9+#S9nSX(L3gMAJ4vXczKp z`5)}vsjI@N%Xt@zA*{P_9`J?WOb6$Cvc@FW*yI>Cn$@VIA!y{fEvZ_KfO5F|h!;r4 zdXxKTB>d=dh=7u?CdNr5Qqr{M>-j#Ls`LMeJ;2J|#J5u0k=#GHy0R9f>e;fhrxC0o zpriO$L#4^wW?hr|I5G869j3lT)V=l*zKIOxOnrc6Rtfg9`$|xF*^dVN?h+!7l@M92 z1SK!@^!DQ<1B}N2py9=De+isN$xM*gb3B+7v~~hO!;6xJ64B8-N<^pA)QNfqj!B~{ zx`zit#Vtg{q+}_npV(_qOr;#|9|~aUR?Y-et=Rtg~)a(eIn0N<#4BE1liMF;P#tzGGPHq zCOdSzZn-fCSQ?<*N=fN2X_wYdUicRL?hkv7p9t@M$@qsWU^uLD@=qi!`eBk2C%FN5 zG36c=c&0IfLY;L(h5=fR&ciTcM+ay(_|=*%N7k+(;I?LI ztMGUYPX0mCzBcJOq$*%*ODJ|28r4tqCVorW*T&>}!#tnpo4%P?QMnJ5**!j1 z=s7bnlO5Hkv=sp*n7*;W@Tqt}aSGyY2`yJtbGh?|-4)(waX0G^?Q(r3r|}K6tKMBx z+;Dh>rX9FzA}|$<#aPkwEyf9-*|+yVb3HWI3&WttNK&UGe8{gSfwkOUef`I6yYMna zJ*?kP!moLE=RUoR*Zt+uc}~6MRl;+%P=3xc@K7>%1NB?~@zsY$c>^d*z+e6A-o)di z#U{(?gCxI=VU|V55uMMxIIoPyz#v19ii`KjmF#)@pc{E1dGD0A=kX12cFxuEX!*A| zo+XW~k;g)z=M!A3bPTA*Ugk4()uo=3lH*IyOKoRFz+ZWA6(ao1SRC$NIJV1ldoV>J zJyxf2_irxR*zc_8G7dMbo4cEKs26(^(QNw}_sgEMde5;LBQ>o%wQ-ZFlfk9Utnhc4 zjB-rjsoE?HS7&sghbg!9=1|Axt=97$W*uZa(54aG_xa{ta*xGy>oV=t3BNUXewwJA zs)_%?d$oVfa@XC{EpB3xYfCvQR@b1*OwdZ}#xWGGsnD#6$2CdZv&r*9P04c{b%RSu z?mB}Xv@|+7R#zt;rRucLk0FOxf424}evz$D`JC6f?wW3MFVh7#aJ6> zI3ml!5v*QrbA^EsMkm8}L6zbwZa%sjqOo5a8zwA-%-!9zwfJS`o;MDwytOjbe;!H? z5BugK=a7|@DLjn5!nWSTjy@^hDmjih`$o9c+8N=f8Nq;xE7h$LiO&<9j;swe4oYck z52$F_}5DDW3rsO_fz*)F~^8WZg*pAEcN zVV7duei;aF8r?Bmo5&$4C~K-@I=Z@LR)?ls4k0n$E-@ZYNQyRvc-0!^DFM{Kp>_1;9^ zzHWc{c%5N>US)W+1Qhi)@|`z(6Awum)gr%4`3pXY7H^2vtT;$VG011bENg5W8b_e9 zRA|88IOkhz81eNDzlLTG;dz`CTdOC?g5Oz9k$IGF`k&rJEc<>)bWS&vjRrRSg@cmSR+9*eZ6V?}N?qG0BNlSmX;|sok5HN(4gy%ErjIQL-m6Mf#x{q>k$~8IVobLqRF_pd8rveGH z?|mcD4VStxewTI@V>#0d4Of2Xyn9?m2XTK`0$6Ci5E~|Au?gIH;O_kZ4=&&9+JzNH zQZ`!|M~lFZ=N(Lp^7dNa*!^hOhmTFsYkr@F<%n2GT9=DXo-Pc}!Lv!1#-5|#X5d@+ zZRNL}-%beb%4Ltttp=}*io{>6siwjyDa~o7-SbqAIzqeKNlQQZ#}i_x%YD)oW)l-A z#p^;9vSvAj8KqDR^=o7eF2u<=Kn_;MHefGx3@SM2*=;)C9*IimCdBa)Sf0(1|97Kk zxGz*gT4KpxrO<#}b-4ER>^`Ky$d$?zFQS`@-nhu!*q}2{{%x@lr;{$XsYF zhemOxvsr%Z%@xd5wXA6~;&`}k}kx7+bsyg1w!R<{-2WsJUK8w9) zQYRdethTPR4snC!bJj7Cb_}(0)GFF>4r!4`)aiMSP7{xk-$?$tqvX#fe>3^oe=6l` zba@>bO50Q~b@Cg9K4Zf9UR6G?@P4PHGGkGP*WyIs9z4Nt5ykgFYZrA*PNl_m?3Cb~ zE8ik7oTG|PKbUyfKmXkM`c?mYGd@CxfxoiwU?L{GH75LN=hX7pknjVc^l#5W&OMpR zyqyP~)^iRfCOY%h8ULJj+hKr~7ZO8kbzxa-4NKed!l|T*)`4^Arxi(7qx;V;l@P*z8Xb?2qqaiRhh?Ef`0V7t@f>o@7tNE=d)Uu~xksMWU z?m;hZhn5-PgG65)VWepm?~3S`w4aMwJSMxAh|^powM^b0I?JF_?442conrEg!MPlc zby$ODu8ebzWI(k{cV!}d6`gPnPAtdleK)$Snc3LP;dGJ?rOj?SQDis{6UJ6LRU_BM zWKEV|k)5LkpXaPkDRxxYDS8`)YypHNNo5c8xN4#N94YU;AM3g+ulkK|Sw{*zi~5#; zzw5&X6BneeBz~XvR{3#%#bLZzVWUi2NgbvA~8HTzj z$8()3m+2z`Ti`vI1%B2~uX81RSdXEt*Rc{t12cyS9~*#uP6N$rCjTMwUm~r_bUsu( zdkbWLNb^R=irBHRgdTwzbo&WhQ7`C=;mrK#n111!=gT*Z>KBQ3BDlaw?95oMmg}s8 z?tsr7One|)-@`FkKcshM-|@>(<57-VDZ5emM)Bn$BA?)wNJ9M-gd0mkm3dN^%X&zg z_WR|8-uUtFWjKyJ!@r)EMh8-U5#<}=2aR14vS;`?ct`Yw$rJjk$!{Tl25I^39{(o6 z;k|iS9v!Krsjv!{xe0TZyN~iqDDUd0`0ueXYc!mCsh>}+&^il6C*-L0lshw9UvuhX zeX28_&!r=Sn|(Y=s1JOSm&F>&w3lD35Qxe_xh7s^9`xr_986qvH2T*cjedFbRxJU8 ze%z&xe=+FGeAxs2y2^uzYUwxjS}snx;AY1*Z|o(?>1p{61%26%z?U@m14ilZVD2L1 zK6QwbFW*J}1Xc~Ki87~Yh`IM`0yYVlu)lIA&#KP!Kwpb*hbF!%1UwgOI@@<)`0@TNHNav!-T64CLRK1;(#Y@Or%^<)V$ke zQjT54$UgC$&;AaN$zh-Q1IVGvQF; zgU-12<||Pi#OVX-Ab5k4IZo=!I;?`Yp7Xt)>`?M;026kBA~+*5eY+0YL#Z!Q-^w{{ zC;8LKpDK-^V5`1lG1nvbOCo`D{|e*RDAF%Stp?ZOWe0H7Gb{|BO1@JO`RmD-?MD6t zHWb)8V7jm5nO_~SJ-{kRyW=Y#-v?Tw1U^i!`y5P7n2M1G4r&{}g_J!^**hc%1>Y@$ zjH%gLAWcQ(SF20lT@9sIvp^74YN2s%4gvW!+OQ-qE*&w*F9F+&29=Ms? zRv-RoNUuGFP%$3NYf~TPQa89NmPSQR7KC!PJvozp7Ve0CmjS&r+7@f5jx~A}*STvT z?LcTx`Q2iYn8moGIqxd()lBCm84D-+vfWpq{$3px25NLHW7 z_k;e)+17B85xTy${Upn^>R@o^t&Yyj@U9g&Mb!P}Ct&;vZKnREqYozjm92h^4J}Ty zY2A&pfRLNLp&tyGH8<*T>ns9HE(`ox|;ACxUg;oQ!E^X#Pk0akb z;<{9RAbg3RUnq?hQe-vdXZ_gOPuR!Gd>+DNcNz%JR&d(D`3!0H6Pe5Ga;zU5O*a7A zPyS-^-*WoNf7W7|80+4}QV7P(ycxd2Sms%R#ib;})jL~NqbpTpoD^|HF@c~FKFFS_!*-M$tl=-xjq3<;hY&LfIUXInQODwbq-O4Fubj#*~T6l7f+Df@E zruG*d+Rnv=)4iw%Ox1x6SwWDEvd{sk@-tGy3BBhaQ^gnDMcu@0HtQjgf8c;k8^*Zr zq1W1#v|&-7T?rBC%Ab7ab->pBB=edr`8&zqO#T2Vz$QY=*lL8sG5hRcC;w8D&+w3C znGRuGu>jh3@AXp109FwDZW_?fQ=3nM`U(Rv&WZ! zw;R02oPO}j?)c26!Hxc*5QkOrMyZn+m5Kl@*<+VMd&pAV(IsHN!s=q^;9qSi^=9llrjCFRfkeIGwQ{cB^O*0lvGbcT^73<_+Jd{WGp$G(#*||gNqd*HB56jeX#gtmtWQ0wOV9e$vq$xeG(Cui;}!Q3N5L88 z_JLQI2T4y@Nh{VBZn?>B;z~C$!A*D&4+kHu#$?n>90g~Ri#*j$%uGvo#a(;SaDAE; z>nyhvTGp=Z>P=oMX~ha}n~VO>0Ob3BKA3p)M0YN564d^pv19$xd$(hqoXv(MtL4)F zV|J|X-6$<lmJG z_+-tnd+(C0FPOEC_whac8+NQ&-y`d2&pN2H z+L&fF+RSR3`99j1{x|B#`hr>eDr<@3uw(suw#CGHC|eFJMj^kQg~$iH4kpec&G|1M zKHYc|*N4rBzVA8$P8^&M3l2Q`d=5c*?O|~zt1ptvB#N_RZ;;2UWz>2;_wBw^Tft_84;8~h}260oKKqMSEmOnYe%>uR_*lYpleup1y4%A?m@4=eDb?j{qnl%XjAGnthSMB zrTlYm9yIaIskhz2Q6F*ydDn&HZ6@!Bq*KO3QKh!R;8F(p*LAMA&5_4x;|XLLCKsJW z?+c4xbditkhHl~iASV*xJ$3s1QHJOH+idP2^UnkS-v>?16WvA@kBMet$apR$znFaY zoBSUiD#ksH6x`x(e%+I(d;?*|8TfkonzPkqM`%MJ1i1v^W zqIMv6u*^7_7l*;!4DRQhGkMCqIIXX5_Etxm!5=gzhdZ@H+Hak&Uz2MkE4FpFzJxAy zFS!X;#3l6bSjkNpUXk0XdHTDXkm0S=v4}bfVuupF+2#>;A=YMGX?1l6OoxrS-e6K-&EzLL!4BhHp9y&Skon&j$+Qb4}vZ0f1bKNQsQNsd#|d1}!{+lX6*VF=PJkKU46 z@i@KygKcbs^cGqy_mX?4EAOO3iHl_X)&|zV*`cJqOr_sS&a9t>7jPkY%ArJuH};dd zOW|Gq^|M;XHmC=``P4&+7U|T$dTYJy8&<@-`kC)h9J|VTv6%9U2OLTivM+e$T^*9o z2kwY+{q>h}k(PWF*eShd?UwcoJmmScOpRlI3z4T&zKG_?Jp!9hn$u6o zs|If&c;_VX((Y0PuMND#?}FY^@RlBfULo{0fVUhxNeiEg_Oll?NAAP~z6YFT;JCV$ z;FvH(nlCaqxr0r8f}f4fU~rZkgHAm-@_vq8dp@g9N_(myKMR~i;K-bpZ>;a4rpWS? zqKc7zM}cOQ7i)cNY@qb#257B;mX_V~EnD?|U@Rfc4Zpcd*bClH@Z5b{?of^Z+Yan3 zX$O6W+*0o`1s_5G4!C{?w|x`L+9|x|5GQ|{lymaY%M=q%t_@q<1Q%)SClPa>GMzF5 zKInWWrwr;|aHmL9QB_ zx#}RiMyVT1#pp?!<*HO$!I_&Sb@LS4n8NcQH zR`OfLZ#BO){MPa_XAiW_Nk7MLGe6_Z6=iYKN#`XPRPnr*-#!j9`}y_oJIwD0zqzn1 z^DJv3ohtWw>n}oIm-p6ZJl&^_$e`J)$lFQYQ1YfopXfZX%fZ>N-T{fVWD*)T@=^4! zz^(P+%JppkRrAip;4TN({q{-y9AR5LPFr+ry@w&told!(l$-C=;gu`4I0|^EHU4t) z9?L0LeCDy+wieti;5LAJUADbT+f~M^e7shslW1jhir!1vB`1q+YzlLBlgs8*3cFTa z=CVAQwQwcWQ;??;Wnv*|_I;U8^NQJ@&N^i7v)#Ed5>0=t1&T%%yQ;p&*B`{}OY10; zOPS04`%<}yxns@oZ3INAkv(uP_(RV=l=voT84u2xhgmOr^MkA}=vm7JJP>wT@Ah1H z&Z3K1KPf9b1M7rbl_N#qqPsj683rg${vz^cWbgN4>|)ZlaP)np{5;C9Kj%>5+0^p1 z#N$~@GM2}FsFCu|QGQs_p~PLJ%~&UdPLq3(OI|BWN>-#=4Eo#~SZ9=D1K@$2nPJZA zg&%`|hjzf9Qj+fz`{PWZyUL^1mh_LW*3raS&}=>LP~tZ4+XeV(;*w`NE>)wDldgFx zr)CN8I+8*<0o&Q46A}fTV3|a9HIXziYa1=6Yl%1SB_u5QRXUz>nM0SwD@ET* z)TSU0Rq0-Wp5~ole^Pyfjbt=Gp3jK!{{{A{kQ!!xBcw*!b5xT(P5nG%vI|Q2zvYR@ z&uz8BCi$xTL$Sio+P@2_8}06p`gX{kZ>b-I?E5YCZ0Hl5ax7ojTNYbC4y*gZfL@e; zDBBadh(wG1$CK0-?O&gyz8;d~7OC+_$o|I3YMEspIZ6H4l60^2@uyE!Z$#{0oUHD& z?Z?QqC4I=Y_n)l3nPdO{Wc7m_NxzzFgL&5p_P0+_-#fv+>lF2@PXFx$d*!KWUf)~R zouclEo<{nWsJ-VD_0OpN@+oR=o}^dj*9H%zm^${XAyhQ=opM z)AyZdzf_FD+Sd5-)T}{@H#i|M23u z1MN#xU3xn2e7j5y1%9cMS8Ug)W|Qta@#1;XyKDte=vRbGxoZ15b*J-v(g1lU*%zon z%F2gJsMA9yj<#&ZszB z2uOToY4u;zS1k@7%;DjlzQA|OKh&y+-NYxtPe#=J5kOnzAK<4J;oj(u&i zSnZPG)Zt|0_Om~vK5LLt(pkDZ@F~2qu|{Z2mzl6I^dVg(m`BMyaV+?YLmzl8r1nbh zN*hnIN2+t}7IlezEB&F=-A)Ew_YpFbsxpYFpVr@^w6A(>z|m^;4T$s)m^Sz_^_Z+3 zM;}XREzI=|V*fx3_Ch}y_(vVm`DTcXR2SJp)s?3299Xlu=(JjOvw@vj#{c()?g?$P z)RQvW-gJiCNgrk`kLrJmnh9{R^EEO8OF#Q6N56+712!UHkfGHRvHzW;zGh#zCr3SR zOZxA!0?yCre}5nKy&RH%mVcJ?;h!JNKQegB?d2iWXn!@Nu9DPKPL0{%Ctt{}DbD?xVhM*>B{i*Q{lsm3`FLBKFt%s2@b^ z|KzA=b^4{qMZmvdm;JGi`ipJHE!;Ga z+~&XynXylY)Cxg=*&%a^CUfKNklHMeLk`$bxi55=rQQOv=zJaF7ITX zFHA1QF`2_NCjK>~-V`#@_l)&?DRqfm7Mj>^y1I$9@HdjjI_?c^bxG)g;j9zi3VrA= z5%prIN#5m4??giX3V%|me@PcTW>;WR^0su8LqXFxaU1})&Yy+U4(EORvn2N%d$1}8 zh3b6kgw(H24dq>6mxjjoo2uH9RHe`Z?PJ!~zr*|JWbPaxcgP5OY0fhV150`sNR`S!=v z2vexvurse`jgU??0K;y5C-OtvOs!uz1*4UltaV|v-fiB;J}cYcX`4doVJZ11w|IrU zKcp_V{}@u&OKO2LBR=(rAiNQ>e;!eZ(1qWNsHZGRzirw7h^TLdFWeDPFNG!j@34J4 z{{E!V4?1<%mhy0W$o_XkJs7%hPeg6g>H97FQ5z=h!o{}whfY5cwqLQ;3*igb+p0Yx zX;z%Qw%Q=nSYC8Li+^j$^q$CPRho&I2s`d;Yi(49HzU)B}4lRFR| zK(LSRL_W}oJIaVn`u7nV_*)ShocnE?0*^^6S*bK}-F-7}4?n=GNms3vnyJ9Qw+2UF za1p&=FlDMH{>)O(OQ-D$*{@mZK*;`$CEZE-K8qvSVW(%4OM%{5Q`VUbyg}M#7o6Ki z<=2ijH}!ILu02{^Y=1^wV_tip**J*^_A&c`5WL8|5N!8#YLmPe-C{=DV(X!>x?Q?! zoin`jM*2|b4*S zQ=>J*>EpQyW%$k5YP}&t^um`SYC+^o(m&Fl*7?49!te@rFoyr-#ftbu{|Oa7X{kq~ zAul>#D@a@8^@a-9SnAt?vdP5@aB3HQn#?KoeKF?24|C?m)U$p582NiYjtz4|JZ(Y-e%B+1Vr2g&nWZpU8 ze8!%@G}gEb(iGP5RP$wTX?j zIVpC8CVwle?y$~Y5au9x2I)UqHt>H+uem443ohoN>;tUMSJ(gDQZI$h<`(?z&>5uR zdjRW>b{FllO5v}rwf`AX^F#KlA+mu6#|?6RNh5fj*ikDl2hb^A^Wdq$mH94hD>SFtjYHd zl!J5P47E|GzZtfl8>m>Be=tyW>h!%4yL+JeVZ{F9K=liqzQ?v#d{8}Z+lxM^ey-DS zfiHhhJ(goX^Fi6QNq@bMJ@-uYy*~EeKd7G3X;{J^o~gc@Yu|sS`l(KLoM8XqO!deK z_Qo^SQ#yTDUwgq>>fyfjTW6}D==7_7?Ine3ZPY$;7S?`6ThCIr=M9x~UjM(IrMmOF z`|;5I0YO@NhW(2|wOaOzKgj%MR_U|j+R%SO+al`uaQ|l`>Tlr-NH3Q``=&E;VY9iR zdLY6s^ljN3e(UUGrwaU@&{LrvzKnd1uQ|)pg|fojFy^ta`a{T0zzKxTCe6ZeZ84_fDw{)5$@4fP$J{#m#`8|rJ}GlA=^6v2gA6{P4j z*DndH?oj`CWGnd`>DPq%4;<=ey-SptH!TaZ#Py#aRu5U9BmFm_@}!?i>&!dCvUBaT z)I95Rq+b%0We$p7{3pL`?Fy@(3+SK&e>POk(>LHuPgSc!_Nr6W&vbgRWxsiYS{1hE_g7ErG%x!?fAwg@{z-qePN%=ZnW?{8Y1@1H3l~IsVUGRiX=+7| zz4$b2;Uzu4kNwJNYIz@f{b}k)I{n)|_MZo+Cvxpg1JsMTMGp>8@8o`z^m8Zle`0{@ zI^lPHd3d2fkoFhYi%wVbM8fju>HNbeiAxt=YyS&IA!L6&M}5ose(2>K^{4QKkL0NP zB4?BSP2|F7;7aW?Nk3uRT{)`Lw%^WCJLE%s(>cfKPjU2q)}1(YgY_bdmGobi(}{!i zSDg8$KB_CU-`dsq`f{M%)mJSF z{XQ4DNcRcyaA#kEf3vTkd{2ZVD`ffPWsl0*1msE=e2y|x#(pCV6G-Yo%Z8_X+Oi)B zs~tMsWqnSmSDbf9V~jpenW;Cf4XdRxj^H5w7*?-Z_NK5pq|NS;5uLrdcL z&w#Nhko=;3r=r&A#P4dZZ+Fb=oDH(aH@FQ1bfx+}?n z>hsi5&#?uUfWACr|HzV^L#bb7tulo$6}{V%a-RE5Xer(HKjG2u*rD!7Ic#Rmgs=Be z%Vg*$`!oGD{j9bB6dIG0^KBpY9h@_qrTb2_U9qX|hYyAdPN7)MZT}2~=2`vN+#iyc zb?aBh$WMe$@QbLt)A_Ob_}FwkQuJyx^~?7wqJ{oy(@qa*1&$>hPNR?p@O2z5@*PjK z{BHpAg#{ryC}7Z-UWdPja#>{=$M_yclVKdI&yQA?_0%U5XO0h1HGBl#C<#AW`Qy#= z(`Oo+37)(w@Uo$k``jvT?+mSg{Dlxpu|e`SuHbCTwZC1j+E1_#fq8=c+9=g|g8jlMwL_=7G`yp);B4z_ zFB+}dx%jD%zO zy<=79Np=EEo$k``j*|sv+sXEZ2GxFwy|h8CIK{rBL3N&D?;ERj=yaEccN7TDwgUU{ zajN}P`_6G{#i{l`!93M|wL$IB=`IcL=r1_i`r8kTSM8_S2f#ed-Zf5jo@PHkPVLa? zE)DM(AUN9w*b648_S5Y@k5?;Bw|_NWb)Ihjc)Z%7(_I?g@d3fv_5r&G%ropQ6V!?` z>?bFv&NJ-g6Vwi!?$Yp%fr7Jbp#55-YX6}9(?+%8gZ9IXs`G>PR~yw1o$k``jxz;k z+nM%nE>-Pk*^geTR-9!ozEpLdW&ayYo$k``jzYoNR%kzSnQA}VzUMNv;%xhEFweHT zE>$~px=X`5&Jmn#=h&+zs`hj3xf9ijbM3!hraI5Hw_m1q=yaEccN7WEwj%r9Ce?nP z{U(^_*}t2pI?uCzF;VT%=`IcL_>kai`;dLd<*NO|_V1h2iVxe*HL1=I+dpVhJ9N5B z!#f5E&bC4JKfyfT-gLQIalZY;<*M_1`@zfA4xR4O@Qw=vXWIq#t}9ggh4$Jj)QSu3 zhptea7upN2P&;(GOT#+`3(mH|_OB+X_K(=#nWR>H#O|1+IzM9ff~nJ88s2e{;B33d zezIA$f7Je3vs&>{`!JXvwf{0n?a=8i4euxxoNdMS!;@9}#rA)|yx4xDS#@4)ztpUD z=yaEccYI86wtdWAJVmvC+}=A`t@yb8%4F5~aeMt_wL_=7G`wSo;A|UWzYXRk_KqoP z#U=L7r>M?L?C(ucJ9N5B!#h49INLs9|9z@z|D^rPscOY1?bTCN=O^v^rm7t}-KF6j zLj`BsQ2Tc+s{K>;4_nlVPucgksLoH>?Ja7DPIqZ|$EO8n+o$d4u2k)xv6o$`R(!^u zf2HdDjJ+RBo$k``j$wkcZJ7PUG}ZoD`>ttf#b@nqFh6Vm@k+Hrr@J(~<8y+u?Q`}+ zSE=^T+Xun?yuEvx>ioR@>uG9-PIqZ|M~UEUE3rGKtM*d+^{dp1Qv1cLRA;IE)KzMS zPIqZ|N15PkE3*%SS#EEgu2z)WPfu5!<@UU5WecT@|`wrYF* zHLAVFUUH3EQDeUYW{tgfhT5UiT^im|D>y$Le)6JLb!a$y#e!D;c}D(WtC+}6VRK&D zVXM1BlH|_jfgIHvvghT9yp%Mj&i}*Sn}AnQWR2g|-M4N!H`~olSTCDE;*uHnR~)0_ zxX)xp9hXrjIpr5fCLJZipBb5f$YBJ9WF0 zCInez=6m1onfpBF_Nh~+PVLoIr%qMR3#-kxt_-UO9l=rKYznK5j$RcOMKSnKAw8Q7 zCz)cuBJ;ux@`rd&L3p(~HuLvpcMMu~%h62R*yY+`$%38DH*eb7P`me|eV%?No5a10 zS%4)diR+ppiTf&B5(iG=Dsv=p!*V2X;3RH!jwJ5Q97!DbTkM$Ss&7JiTMjxe!BNY< zlB>SfdP1(+X>fMQ*5|6P!g^V*+F|gy37U25mkIj8ChA9nvrDmn)vK$gHBsLi{Ix{= zeG~O*qW+|b`p)35M)bry(UuL&6KxszD@pqOJoRysel1UJHuy`)x<^yBI$77|sf`Ao znWCR>sysdUiAQepF9s zroJ@zGwFI`GkGh0&`j}G0)IL~k8Cb)rJl{zrv{&zso!j_mSpPZnyXI?{&7~uV=dGO zS%MF0!QXuOqoOWr$@3Du&`~$)nGOpbuxC)OIWn90!cp%SyuYm{heZ84B&41)_*z@9 z2&t_!n~>BA_$RWc94Pu7G*(=L;%R#FPrz~MSsO)V1J(l>=rV2H-K=WC-?TX;;%in~ z#@CJ$Y_(Ll*ID`nn}sl%;zeEq+GS1H*fuzs+Q0Q{!&S|Jt`!5}*nlznj7#nN%e3`_ z>@)r-`f29kiCa5REEx{K_lR?oMF%in)2&tvQ{_J)vJB1!Hg@1*}=%;n)#u6k9rvbTEs*}=x}Td$s< zj7Vv}n<%9XPHBIcXzCdU^}I7t>KUARel$Wo_i%7bPekfm&%!Dw)l~Etdr0mld1{_0 zQFnNn)F9KpuZdOKFXs(zuD%yde`Rz28WgulUZp+A+Tf@q(w2HP(w01?H(HF2sqV5} z@RGM@5X{40;tg(f=G(2+fE@j1Oud|QB6xXj=hZQ_BKIX5$LOZ|+n8G1^hof>nsx5m zTCHhjJSMl)qg$)xEsw!tT&vD6v{oBh;s3rO8&3<}6jJX=LG){+g?c?} zN7~!X)RYW8x|v#;aU%FrnVnx~roPK8OTf`x3Y?|de>B~%r9Ygdwumn7$*lim%wz0N zlb%UcgJk3MEpL-H*fcVvXt)ypL=#>}mz z7jH7X7@S_*D?%@xYvEv`ISPj^0NZxpm2?6fb_$GrpfFgjj@mT(N-VHWZ_Y7vJh;aCQ0M%kAJoiA0`cJyxlkX z{ivFis-KLi^{E}fpG+%wEvi0AYY9F;rVkq%nL~J)9^!nW#ne$gF2Y}9?R&hvqY2|j z<(|fm0k))Lj6K@jdZ?;q$G4OEDbf-Am862Hoz%BUvn?ERQuMq|YEz1MJd;|mx|8}c z)p*Rnl)97pEGi!3(hDBWS0APuk13gYa=u!bDISky6}+CWmShcvGsL8Fw zghpGW>j|cy#ZRcr+stN68iN~fx^nycGMF;Vy?a;aAP&Kn- zzTh1xgmT%?X;6m$me<1RQsiB2y(~*TV(XtW)ob=T2gi)C9+ag%3vae?eCF!OS!z(? zi-|ZsK-HL~dS{*u{;>?mY^Cm&)*HQ{>f0Qda4gT32?sbs)y8aws#hEw--mV295o?f zvxQ?qq8^!p0@gUtu0F>qI(caVK5JPl=BR;L9l@7m6|k`Go!t_Ank*b2lHsI5IeD#l zzC9~JmN)}3xYb94f2%uBOi;7J`GU*5ba^9P_}@~8~2 zoUF%Zs~yQ5!Cy`(Ktr=7<#~-`dZs99)@BxfkIyRjB3pfw)e^k7w34AYyG#9dX8PgW zkMqnK1@`J;ZOXK$8Y1v7T3}vB;KW=bucO*D9Ly57W;09Z3_dlhbH5z5H7j3mk@s>VBZyZG zwL(@@<&8{yyqD47SpW9w%{KbucIvw}$AHgi+xfe8s(-tD!P^mdLi;@@yI-yp*t8re zFmRH+Actfxjp8WJ(lt41R@N!tL$W(>%~3Vk`GQM|$9u2GOwlmieCq)3#KS~SacRi6 z-1?9)R90$|N6r%N8`fK09ljz2I^3IA8ulA*?d6@yKx1kO+N=AW32#NzQ!*la>J1AG z73;~rZh4h4*uN(puw4<)5;2z(!f;DJ<*4T@P%Oo<4jO9DMJbZZ6K|x;Z5&zfjpQ>saz^pmrW{N&R`>HHp(L*LWt<7%*u)zl%xPLb6H?0!US`Wj z-9Hv_FzsehRCjbie1F&eGGof$1Di9E%Grp=IdCKBTb7;?Rv!xbm8G#d>m!9OmTB8j zt~q*LSbgLC9ei786Y)Lb^}0+kWWM`?VYXT;L7(wzD!mns!`uH;{e|ZM@%g#Z-D9!; zsS_bjIC~CjDr=1O6rI-ALtWL|IkGB2z3DUuFAwSUa&o98%O&~-cu%dn(XsV?_`V+2 zgxV6;h!`zN_RnB6ET>)Eq!zoNW{+66pnkAVsSH_5#LQ|%=(JHfZqM&4u*p@uofUYU zofc~Qh&`Y9Po10oE&|_dQq!y9dU4S5RX?v$H9cf0cXR!SIY6nzeo(& z<-QmeGtaSMHOszWKv+$7^fs+tb8Y~i6%snl2%aALWDaq9fxDbQ#D6(^Sc07E>YgA5 zmK(yVubsa<%znd9*6gqp6pkGs@ffXzX|6tw0Fy<;G_PuZdx9jQ87+-GNrl(vO5>-GMpmclKe7qp!(O!#NF>fnFyx11Mty7p&D5+*q(luf+4kDo1#85cz^o}vqGMfD!Ib${uM`q zuXRpRYC%YUkg7fj>G`R0@CMur0S}A5=XLq}*3b?)kcBOS266Pl^D1_YkDd@dbPpJ`U4Lk8~B>Nl>DVv4{PuJ=wbLDNn!5jxF^{iuWEJuq~}C zEz=aUZum*w_%q0yI}sXll3b-$Wo{2u9iAqFy65yKN$s_A^V#yx71w_ zCe%@n;9V~#aqoaS)}vl$@K zUke9^*j8z^*qlG3?GtQkNF(7v>FHCv{+(6uHwHXQGv8sOo3p`n$!IKb?S6Hd9DCCr zS(w{nxjDnw{k|b#Fj3$rj#nkkkHm4Ne!^0Jmi+xqFv;YLp7g!>C!VaY=Tn`8pl`O9 zsn#inG9~1^`d8+33dfTMvT0~DE5)yFl4uzJh?(tp3Ce89gwH&VlwK`K=qnU6xj`(| zf&u$fYqF8WQrJtoIl6n^wQH^T{SH6*QiT1AYnke-6iPpjyJ6!?7VX(@^hGoQ6ZtM~ z)7Mfgx062ID&{Lx{}KXIw3McCd&bM+Vd@4n!@sX>7`|UInHy!jZuNFJ9*V5tPRc|_ zJufe|gV@%ew*R6ZYc8+WXR)WS^jpnkO0u>&Gb6pDxthc)t_AY|{WK?Zc(1h(JCu)G z$f1QFTByxhKf=kHu%6UXeHYfRauO#&zt>XiO}=WWUU7BTR(zjLFKVUcCF;*xsa_FX z7E=o%`mvbmm!zMKsYOZpt(Yq35{#I7Ct2@^sX-iOYb}>xJl$FiP1W;TtCgwxqte{eUzsAv{4mNUC~B1qNle}%hUCUcIx#E-MyVyh-_%9dS>e7ZPlBZt3$Kfs#lxn zvbJhTlS9ED%4<5ft(u-E_?En;Q`)NGOFxN9n0%LlDc(c|TWqo2l8Isfa?90j@9?fpy`MR;m|G?5C%)AWy zd=9}G?>6ROH*e6{3`X{7dkRO(v7OTDA<5nXwsbfQoN4Wz+EIgWS<5-?O(89qC8IPA8WgOf8Q@6H_3vI?g zdl<)qPm*)Ozk_MGmlm`Bk8!;A_g=^bcficFuhM;+tK0OpX7WA*<=~jPr(tq)Ojmli zi(~4`h+f@XJ(wiMV4Lfrf6^moe3>eZHj)lh3b|n_@vaMp$|*b z%UY;s({xn}HOJr>ut8@x^TC#)b^WG=T4wMa(aWF@&d}3Zs;4sasFteA;NN8&2mPx| z{YgvpK$d>HrFt|=@P%1IugcZ~TdC#QdV5Q?&fueSgg!D?&uXQf%hgY|QnL;IO>Qyt zZB1k_eJD>aZKX!#3BDmum&eotP4$jeYG6~r*EH2LW9qx6dVEavXeRh`%_Pk$Wi%Vt zoZJ7t^b8bYqNVxc=iw2q9HQ;viY*TKH!`W3?kUR5g8#^zzp3*ecJ-K>KRiKMc z7Dq+O3)Xa0@~Prjl=gzPFk1~w7svMW7pyhesw%T3j@nGUEn9WV(%^%#G?LliCz{1s znkYAmMsHmXe>C4iCE>?jGRffrjIP#TM?Gx}rDoY0{2f-2oR5_8uF4x_V}^e{Z({YV zowL;z9`MhEr^4eo)a33*Ye7gYvvWp;xI*Ae@TE@9G}fe!1~=pETCepNbRh6CdP0Ia zTP(6J>uQ63V-I%*u^bPdgJYdc>SlS1(U^JVOtrspR6k4-S!p}D;Ik$6-k!+T#~&pJ zCudl59JSIeKnXUG6Ss~UD@-4G={&3@(=FA@If?b=M^4T}t-6LT0q6AUEUk8iWF7jj z4C5Q*kHX4oaw{7jR%h;&Mbl9~SK1RjrwR8iVG!AIxL8$w2Od8vZ%&8pa`I#MB|<}k zwwp|$-u!4YR`@*~K83nIw8Qzbsd_9j#Co@>>X!V1^<$oTE9H9!*NXJV^eYf^n?BrB zP0DQv{z0yufJJKVpTXa6qG8(5L=%2so<`X8JdNa)va|BE^a?V2SOL!yN7*A1#qzUv zq8jArt*)Fg1+R8?gz#7;ed4*qcmT7iJoa1t9wu*6U+cY@c)U}s4~=Hcu618DIa-5n zkwP_$M0W2V^yV~PUEDR+-@5s;beRQLr>hC}0Q<#sxxQmtR8+y$QB|e&#Ha)w7*(86 z0e?CybWWS*pnElctgVRGP%|PFfLaC^_Ck{Cn)G z#pfT1_JCW_LJXu_E5h`6Aeu35MGL7{>=^hun_2i^C-w|F3gU+q(Wj&E-|gk9$%*(IErv7}_n9@#;ZuWNSDsw3Kdo@?jOW z`qzp5ZMDE^1G-ge1J$Fc_1@MsXUfF$D)vU7xA{iJM*FHaqiT)wC<9VIea#n9RDOa_ zO1P$Hx*FjMJ}>c_@#$)21a;=8k!$9rtK~^T-kE&O+H?#>1b-~;ng=pezbLVo-PTV8 z>z2;nX!)y>zt!^hll+bJdfIuie&nF*XUtu>E+M2A8Qd%uP?HWvhh^&r*;z2SdF^a6 zDr8<6sFS%~fZkOm-N_tL@cYzc`&IiA1~2C+Yf}f5fKOSgI;a=IgROZT)F%mpt;!DS zp~S(~uny{_$Y85`2laWXDSe*78HRTyU^8`w)!r2U}APQA5%PTZ0c_AvM`5 zJ4Efw{KpgR)V8d{z+cGz$IN!BGUp-jSdx3rV%A4ZvcTVNa@MEq)aX3H-^e@b$9Alz zB*4n1mkwyJs+tMDv)R?7+p7)D1)tjDnrZFT$d-byYI)5Y?bX6og7=DDv$DO~78Cr1 z*4KR9UQKAD!DqG6q^P=$CV6YxXwtf+jV9qe+G=t!w5=vfliO9 zrWiK0)s#v1c9dB^862dyU&-^Hpi1f$`*28?{AFwb8$bE4cEE(cuZ3f>lmA`^UXRAn zP3M2rfy)DoV`VtMYezL8!8o3E^M`cAsKq$?MDnM0#45u$)+FV>-cb!sHjWol@>g_Z zx7;`ersaRrQO!#;j&;%e2Ro@z>BccTBY$`&wKc;yhGpeH(+L|m-^>UYHMrb7}PfZt9&)Tt#N$TF8`-|HLSgH%s3?f;R3b(koHKfkeSO% z(gUST59N7!mq%?*Wper+N^o%Bzd<}0a`$5co>EuV%4m*ERE?hk-}{);$mm*kGJqU3 zJSXt8cOuoV!+vgAw98t@r2Rm2jICtP=~m5MmxHVmxa^Yo7u?d#tI_Bsw33n$s-oiR6$I<-)34^*UQr01r9bYjf=mTU1M9xah}b2Xv-4 zAw6BX;Hi3Uh-*7Pan#jKz)82+%w2}%_I`sY*Mqc7;mq;rPL@$?mM4Lcg*zmQIBy?WKqQ2a}4*3&XNK% zdQ!66aAL8GB7%qmdl_r?@1DMTy+iO_xo>*xQ)SU`zNYw|WhXc!w*r0Upmym5PQ&<~ zBDT*5-)`%EP@EVzSG>W$NGfNc|MqR51>Jqt#BID&Y;{FbZYO)l%6-e0ZAI`wHY)lb z{Q^B1k$*0HUhY2vTP%N+98;>@$U^6puaul6?-J+Rb?PF0ygeSjXFtcPuu@Ra8&w%^ zX!#L7>nOa>)TlN3S^7CE-oE2<1B;O1>6V+V+gJsuMt^(Mq_}Q%=kOL*#tv%`n+;5~ ze@e1GN?eI(Pdf7P&pJ(?W!=-3xucl|&ar+4>c>C)57tS)nWC zX*Ky2T5El{b!?D!fz{>M!?|dOEq~Wxn+rYcRA-8_D1nP^onZ;in+du)LDk60@(Y7L zY*sX`hJ(|A>)p70OdtX6O#J6szc~gQ15~3X1?i>*RG8c{{C(xbx@rR5d~CFH$85ebUsxV|w8!38Js@Nzi^@;pFn8x1(`CBM|8|Cj2ncF=te>;a~Taj~59&BNzfU~|G zu!y<@LO=Uydr3&WDjmi*)kwU7wZaf#m+;419S?ENcTUB5n;vP!Z$m)o4$Ah%Om6{V z6s2{!Vi`4F!X9lMa-TEWa$aM@#ERc-`i()iSaRhteT`+m{MCiL&4fGND!7-aA(t=X z$Bgp_EB>zd$)FFQ?Xcr}JfnkwkMqM`?+mvbD%&ij&~kq$=vPMJ%`1m1Rgr`BM=$}1+qqw3Q^ebWJ#<^6VOehr;Rl27 zG$$(k%ncnUWpbi*n1p@Ta{AZ~<-iT#<|Q}V)*CQZv4yb7;LNGF+x11GE;8XMQyJBY z+pH4_@-TKAjR?G260*Y99|Z!&Ot=#*a~Iz$R>!9joQIsrAs$~P=uxg3#EDv0 zjdKN`D;;W)tKW6&Bd!@M=|0&yQeLYAEN778prstnO2VCj6$M%+;X0A97ZWFV%lJz1-{CW_rexQ2Ul2vJ{}TJ7Whxqrz6Xk zaSUvOjSLph`zNFN39meUfsB5>49UwN%Ngr9yy>_w?KAr{aIO?x@5JxKsx>G_c<~$& z(xdD1a)vKM>Sd^rF@1k!gnSuZIwqNPR7yI|0>_vJ8<_P{rdS4n4hd;IM~C$I`gBx{ zG5sTQvurK10rE@6joU=l0gM}+O}GOaH3V~6y8ESC6UKu_BlVmq(cdZisdDa#2M&@x9n`#3Un^+z7Qp=QGG z|Jbp%A|CJIM-%Tn>(G8-=W%DJ%>xUzZ^LqKe{_P{Zg6ui)wl#^4D}I@HQ~>-PCP^R zvUwG><)8(x0Q0>9P|O7&zs%fT7N`9|KE*75NvzVp8A zJc%8E?41k#j-AYZH;f&bAxg+63_8~l7CP0^V41iFQP#_kOF5A)=|`h1=X2XZU&4Ss z#uj{yoyC(^cxrlJVs+BMXDM1C!P6Aj(=kDv-xVEGchn zH4d!o`}wk@9*0=YYTLn#go|E>*@CaMlli9+PcT=kVi0OjZkT|DR}C+m`nFx<%aXGH zh3VQdl033r`HOuG)13zR@J?3jPrBB&%>D@rGtlp))pE9WwWHQa#ac>D6dA+wxNF?` zjdhm(gL4UUT&}2BfuGEYL&xafTky-TZf@bvF?M|>p3vcD`5J^_Ov1$O4J?o)X2PY3 zi5pX~SFO5z>7>!tm4j@#&eU+|0baJ=eYK8R)33AS(mE!MsCrCR z{FdX6Fo}~gOh1-{{E=^WT&3@*8^+VitPZb`eO5wN-Fi9QsEsfSx>(;(cXx2~t`1BT zse_j+EU@EwZYm@!zevX;ca$0#o(2Yx-(BYt%VKgJA; zt&6yNW1Uw3jS{_hnKBdaPZIA1+tK=aK|Eh-9A9Rd!>r3FZU5^6neoh#-HR`uW668Q zl+Yf?J?@juue?v-kuWL+Mp=4c}{(k_gZ)`bDaMv4E1_CO)} z?Iu;WPH&RI$KOLUl%tOuZK>Q0D)qQfO`9e!S<5(N4Q@e#M=2K5Q*6WV`$x+|SE4X_|SmG~MirPIvpKT011pgm> z7T=eNm*|Q5Ti%u?{tLS-+(DsqfJ)Un>UFgMsoIV3Bay%`8 zG)8}~t0m5+OD&A}y*U4{JB>>Dv%203f0n+4nn%{~)>h7S`bCRt>qU`)Le1!Xc{O;m zj(B_p`XqI3JZ#cH?B^_1UWI+E%!y)q2u;#@vvsY^1uxb;!`9#RHwg}} zzF}d9nr5-VlHm#0Aq|g&9X^sa(RJRnQCBdvzJG}8d=RoXCpeo!_CVL^t8D~~&`qIl z()v5?{G>US;7m-=uV9%X$~Q7^Oy_qFA8J|sEQu9;*3LwW)$?OX&H_vKjyN3Tcs}C1 zVCyLn=Ped05r+>~yyQ9<`3_2Qo@Ox|5skwO5oagYc1D~>LVfLLB4|hLkCL2s!}ii7 zXKlC@21^MxlBXruSQRALE0UaH+`Q>J<6Zrv>pbh~7hLDVMEzr;niB~mjq>>4oHlHH zPt)5iYlX}(EHh2$XX^^WNR>*DKKe91(7MAKV=qhOM9>)Ln?yyPaV&8)_$D_4 zd~~AV>k@@NTuMR04*xgDLEAo_wJmUq@@C{%0%T&F?&ya>UBb5m_9>{zE4-(PxG~qzCJ1J9b4D-1T4#BS# zM^~StL+6&L46VnLe#lTgQYeHCsSfBnX&i7+uVx$pK1?n-Kv>QxnE#_0Ueb(L=EA)9 znyIeM_vVxIx9(O?8)L>eWAqfB-KAjIlV^G|*0E zK1ZgWW5ZPfV3in%6&0lkhmP*Zzhj?iIUiUK(J^Wm{r8h*0AX-{-HwMecMJN7zSM+0 z%{uxw$h^z>7$uKLpJWS)(&%OHGXhKlK<7KUhHp|x5u!c~CL+s|bBxGYX*u6GR0k;9 z8BlZA+)O7A^yyGK=8sjJN940jvODsH{Q1dI3;RnMoM;^(WpD=t;23*xmUkPh_=!^% zFQDI9nl;jc5{0Q6UqHWL_`jo1kMCFTw)@^v>!lKQ7?fPHY~>3QSmDT@AO0Layqs{k zb^qf}4u&s1ew8J!J)@O-(!1at%Tmy|s==)8-U-IPu%G1rWUKH5Muf2zTWYe&Lvfoe zd9&Iiy{yhD-5H)H;`N{a#@b%KjAM~eZlN%97%C3ZRMg%HZ>c_ z=wf704;}G5(-~noWg-IY#+R0SflBN-1*J9~G)H!bDJUXj!qX;26Y;3!&>83mY!Q7g zVS8d-Yl{&f-N`JN_>twXp2vWSO;bBwUGxJ`^f2>mu9d;h92WB{ zkuvD+%Qz7k=&ZH zHl=?bK-;YCBjM?568?VYEz3duDB52Q$~GFkyuT!YuVDOaho5+mveGQRe6x)Tz8P<#14|2gYoi+LuEv8KC~QORFk~Xnc)ePMZjE} z+b1ZJ>flf{)P((&)%r+m2e4U^4e+PzRHh4j6=|`jFI*W6!MCnW7~V6Y0({AG`a8~c zDeLjJpc{pGrjtI)Q41WshA*DU+a3edUB<_lk-_{+WNfg0yHmD`K-byqWI60C@HHOp z$G}#@pkMMKM=Xnk@bE70{N)e&dB08+?#^>E1=GwsjV%?6Q_x=6!OGXE2s}QRlM!`c zFE;zmPgu_DmV9XP6Uhx`0HC~b`k7B9dgg5YYof%2}H?Y^fa6<%UM*Q%j?d=hbSaM4-Ij zrh3M1GlFGyoe6v3@Ai&<+z0S(U;lvQnRfRJ-t7~88NcA&ewE0;6s1UyW)H)9k&YAZ ze~11#(2n>hAEl~T%F4I;P)+x>WfBiZusoZX^qd**2lsKVhrI{qeT^#RFm{DP%|Kra zIrBr#Poa*(w3?<7FjLFn?e&71Dm97|(y*|bq~n**5xO5FIh_xZoGo1sPQIobBso_d zBst9wlANVw2d8}c9V9tj4w9Vh?9LvH_B>7G@Xf2=pd>dd5gbRA>W9PZw8=5GFD$)9 zE7tszxE#mPPjdeasu}J#GKbh6*S|5^99RfP!(w)8YD8iC%N>E>g@A&!Kx%OPwjM>z7q z)Z6PeGllqb;A!SxusN#7ups5u$!dL$e%3*a!qGj{AYC16wsp!*+Zy8N$(|h(u?g>g z_3{5l^zm0)e~#|Q%5bD@=Y2|`M*BH zL^xyUp`-2~?mZ7)u6`e81dptkO+gYRxxcS}TEJTlO=Shx>KLYtt!jX2B; zP_nb)e=FjkJ6N6Q)G|+uIGk^MH_>^_;l?dz9_n~D037{(A_|-^G8}Clc(1NuqpToT%2zK}cGqw-@lgB^^fZz16aqT5hwfweni$ zRnFUgiuAU4FEah8?VmEmes_n}C&KM2{X#t=>Ie5|9Iqv|0e{74(mg%;!IDS!%{b3! z&A(?;sZMJyV}MEb9Lqu{I?uA6m2@w)H20LSKG-GQM&JCt^qv4w;O{sZWKTOdOb@HttHD$~o8Fd3U3pfht#h zMl;%;sg|TI^yHo<)DJ@oBP+QCIPJwa)z^7%7oGR~JPztlZlLqt-KTM#_sa*O^WHx@ zp~$JleB5%1lsHwDcwD<16h_R(k^F0(Mf!Ypyp20@#l4sslu4t4HTg|zqlIT12` z-JBO3H?i589TP@R2Khw^~uHul(hpu|rZ`f32E#F?U9n7&e zWANvw;eNyZ0R=sk<;XRD<)J{so@aDGzJXBmKC#DT^N`IHv!x+TLK-&4Y@C5(bR1{& zsf_TOyfnAqRf}0A3iJhh@yXWn9SKRP8e>?(o0eUUp)bW1(j%Er`fY-IZItT~^w;J> z$S<`T>6hV7`>ypNx%0-9OH$VaN3I0$GTNZjOw)cz6u$8fL`l=WgVPRjWP{#Fy&56S zWcLG|Hy$Y18NcyHZT-3D-TWT?zS%)~-F#R6HPawI;7#T?1!H|-CZ(^1bboFV^Rw{; zN_)PD=IBqg8pY*++%xEBW21f7M&0x0;&6S^_Ye*F> zVzHJh4d3N6>RzgIsh6(Yhe%^Fmnwa))l@%2`(7`c<%ybEz%qtd+gfX<#_#Sjb8!4V zm!Y1`lEJq1_%42&wfdvJ(z+qY53PuEVCOZUU7)YF{@#Gr2wx~I)MOXiRn`Da|N1*~ z;^rsInP;_O5@t93R?Jj6Ddnq!RFUj_bAIZilPOkux${`q8LgeS!_Iu|Fid@HaNaIU zpoHZz&@ZH%Y7NSj^*?a`tIQvLfnB%>bth-mPCf(T_fCt6+A-HFEe$!K<{Hi3Iv13? zEWXfcn>4Vpu%J(hTrL3PmeK`+`VxukW|4`WL`;zG*IZSx!0yEUoBp3kVdpFDFxwp) z*3-jko`mBgP@sI^sh{^{W+TYglZ-X8{$QP2bh_Nr>U^o4hqXCLr=2mJMKky^?No%F zL1E3kspjO_%Le^a#QzYMdq2(jF+YXHMke~qQ}KT|)M5%MoKOc0X>~5>Vy#zbwN^6v zr9sWHHZE`-9>z=osxL;lB8ON1A=n`ukH?ijBW`2OQyllJ$L0LqCHgPcbzWN`V8%FW zZK!uxzEIB^E_xM{O~`N-O_`EAZJ+gfiq>uqL8x|<`W zHsy}f*NMu+krj3QPvoT+PqU{x7M*S}*TqQJi_eO84!^>>fbBj^9BikjYpt-Ik*>Aa zVWwg|BI5-wl{a0>d^>Dug0lvytGBt%BvquSCXv-7isXaCM(Vr>hJqLlVj0 zu8EK{lsTVT&UQ!j7qKsg^j9J4vrzN8-YEIL-MVRpb@U6ZtcM*vD&|aZ{t7-mq#ueo zvqKu34;C}5@p5}XblNf{HQTo)FT2yk2CG zY^`+lz+`JkqFx)Z=1PlsEa|eXNvdn|uIW0EaHNZE6IaCiapg@;aD86q#t#~UW|L`nD=>~G4neT;{SKr zx-u?bRD2UvZx6F)rE<^nsL+#XeCXs(9DH{Rd|Z;An`+HW)^DU*Z%NO2C#8o4{fpEr zczUD>&k*i`N>k(cIC!f1E)AZZQU1Kl?;L)y^#?zWMSKQ?INnQ@IB*aLIB`rgag6uk z_$v7>$Qx2R!7@5kSU6R^Bvthm;l$<(r(Dy|9clGo{c7Fc&8eHd9#jL~{WHRCPvU;5 z$t`W|Wb3$dk+h77etXr`9@lztd-YsfU4Do)x1Anvh_zCBL$CHHK<<4A==ekQ%tO>1 zLF>x>Ajn{yeRIEEj0DdhhMv|qiKIMC|aF}&L;VDcUu!RIEOB~I_GH6ak<+_ z3w6}u)K!MzJGU2KWfO*Pa*hUlzK)@22@K1UzjJ@6lkjWMF>(j0k+3(0j%V|dP?fIU z&{VCH7te;Y55nLpa*6GgCP#xlkVjuO!p`8!b81$~hlvZDs?UUBZj+-yd*xw>)NmN^ z-Kl3H^hy~Hj1C08;fGmm&X+Iz-XeGBRmu5YYcrP0lTfic`aN#S3%-Iy&i~RefOc{N znR|c*RVOZp?%KAjlls2BeyO9?r-Po^(HheM->MGBL4LoZ{<@=@(+L9Kc;B_H{Zbiw zYHQo9eysUqib9#+Wc~GGuvhF=){n_*U8s9#E}s#?OgmY1jcD+(k@n#4M)b?c79W^q z8o&pp(P1ZxC$|BAnyj`a3w!Srp;V>d`B6$1gzbjVCl!L%h5qyLi4u3DwaLLe<6-$U zDDM)}BL7bhXtex{qAe^rHblR3_)hrNEbioy{?PG43=q|#^lFFRH$9v6$MhUQSIH33 zCs)wda%XzHf0_jEfb{pBZFxvw<+?Rn&=JD>c8;K%b1*qJa`%Hb<7{>SRgcVJq5jR( z^juaBA|c}pJ}a!|W$bX?V+_fe7*{xp&+Z_4;KTI^fi-vJcP+3(LQ`U7MNVto!{X#| z+{G{6} zjiCo=y)a#E7m2Jr7hu^QhIw;>o}VrU0r(`dtLLS20zjDgs?sy*>c^zFpc6y#RF-&y zv>Gd+aYwJwv=iEL-yPE@{y7^Sr=8xG?amRF=HD1I zio6p#jNt4g2CJ6bGUV}f;7kf-%Kt3CWG_61!ecwea6~RRmcw1|c&>)^)GnV5+<)YL z!>Lq@I-YCg@-gdvHt1kG=Sy?2-AF0SKbccBxw9Q&!Si#g3A?A$g>Si?Q{||s++}2R zi{SqKr>Vcj`_#Ng>JO*IDJ_P13k33XM8|WPistb#k+((eN-K{=+7lwT($4E8SG$7t zaPqp#2JnR@DF+bb^n51oU9H?Q9gk+K)#OX=XcE~Q>?SCxUvWU!I8DBj6=F7qRUr+- zrjUk!z8#JcUZoyHQK_O-{hfm${z$KOcBf>X1kYs-CVGF*d&i0!AyI6Zr$YX#th8=x zvD%7%#07F%3E8N!?q!#Om2bR(Tn6c7tE*Mb^<^F{RgOyE?{KW@1M5`7m3A!@zSluV z{=_=LkVaU>W|rH>c4oz|YoN1C%jT7HC4D2LpUx6>_*+@(+fYxU7{weTTTaP*o2_cx zA@q*NBKpZJwJ@STz2_TiC;T9TprWvT9&`k5@g6gUYAnKf6-U7+u*J7ylavlWL}-}A~cC9e9v zL(UBw{>VRDvN`8>3pqH(+^CONB!0ixUFbcn=swH$DD>`@m^d*XHBpE)C3bQB8VL1; z@A5S7?Y)eVi6=I{tIo_}w;}TO#T3N*w(c2HpEze3d8b)N%3WBD1nhaURfg(l9XD5^ z0OYnOZjYK6&SE(HD%{b0cWQouT2rT+^mH*}FEcsulbW1I&Q8{UFrS~I&?Dz|dCih7 zu6U82ehMXSY{>D8p3sV~ba0l0|H&RlqqNgoRakQ4IR8dbAYmJ!`DyT<&9Bk(IR?u9 zl`U3?pV(%rA+RyE7k@L>-IDvd+zd*KeUt0c15 z7>8&zL-;=S~1Z|A-i=5DyI;1tXO1u}yaG4a*ZHzlTTttQVWun7XX*>3U_-}{sC z?n|f1xCAv##=D9H4LT`7<5!uWVO}B)gZK}kD07+J*$#*GKl01y1R~jmk||^2MGmJA zu1}lInF_Bb?SUM%(;IOw%7S}lr=o2B$Y>i9X zct03)Zb}ZdOt`1=vdgMuXC(Vop!!Zqldg)l49$Mu=TCY zK5uN&*Sg2G?&Sq+*>I3AogclKs#OS38_)j2?q#;LFeF~69dN!x`w*6o5|W)z(Ak1649jO6 z&FzSF^6nLRJClAloPK#CfJp@90?;+lh4A+oa0+02I#M%rKF4?t+2o)qkJ=ErI`*z<*2Nza{YB68Qgd2~>^lgUtOdRR)&sS` zLO}RqD&H;Yoah9V-rH6Je>!;n?N40zAnPK-I7bdvVCnUHlrY5-0RVKJsuT6B1TbJm*v?I}7Yen2v zDG~Q~O(X6}r$yY)E{eG6w?*7eREo*}myDDK4*DDE9{%P51|2Sctj zk=Rw8%yUo8fPVtrfQNulfXJyG)X6Peo8?B=Wx2)g zX1UexXBm3*(N1pVC(ysZy)4TuTotDmLN8vE?Yvvae6uQihpLiwfAPb71w0DRX0PwHtttAoG|wwt1R2CMpjk#IK3Ep z8M12b!;PGhf5hpf(4%)En=sYLD!V1yE%aoSOBno0kW~V$3MjmeIDzQ(@B)(OO5r2@ zC8WO`o?7T7e?uNnbVIgV2?$^CcN>o14v)FasOz4-{}mwRBV(>i!u{u?xY=M;R|1cN zvjVGoj>Vmf8}mQ)40saH&J{8Dw>*8n>%m{~_`2iwE8Gikr||p-u-x;T;rV^)`CWzI zW)EMFA76}B)~I;eK==5I!jlQe>Ovp~d@;as!npIm|At)Ozd7z3aErgd3c)x6pnIekS0j=N$0g15)PV ze=+!_fRwZFoN-ti_jcUkCr~>&=3bARJtyP78T>ZDm-kQbH6!ZdzZ-Xx!&}#-=RVwJ z0saTTdjKL^Wb^{>8}RRccpEqI@p}0K@VkokB)k&lVcgpQKl~u@w*WsqL%@dt(*A_@ z{BK*k!vp@yUT56EEp16;-1)~g?&N^~*q$->N!-5tso<3X|L4G`2i!BkUk7~tm%;t= zllWi7Jsa@TKNoyHAZsW|;~muhBF|rV<`lN6lP5C!lfD&z-~vnFT?$B8f#u*I1j2s= z{&B$F?pJNxHMsrstp)!);C~_Y`)$B~9r)LPUw#|Gw*Y?nN4l-+_(f*Nq}J|tp1<(? z0KNkdKasIh`~vlya15;6ZbX9KNh#& zK2HJj=RTuJ7T^zoS3{3oQqM26DDF}~@>N5;@{C;+PuIQp z$DYAY;AzSQr~s+~RhjHYf#PY%`rL5%1uRGz330nmeLn{GFfeN4+r~!(e zr%re(_gFukx^GRL!>6JLP!55_YVS}_TH`69b`wUnh$ z@=ihi;t*QVJ=7QZ^WzX&F|=Z6lBV-uoOtXr9RCi#9cO$vL8{OKB1{mv^8jc zyO4J3%lF$wkaiI=W57|sjesBSMr73>r)+qAdlFg+aYpw;{!lOSV4kj{d}0 z5=_z}brGcbVS}`zZlxYb`$XVnpbQuUYy;K;m*Rg0;Ky+%`G`GEIZh(rXITaH4fx|=@fhM5PZ{!zGJche zBMqa81E>NDaVz{Kd@12;2^)i6EWALCgqr{#PZ>1Jzh+E!OmEf^wDJQ~Jm&D&E zHQuwg8v;(yg%{O@hVe{CRqMI-*}1No@IzoVD`&|hQjATJ;7 zz;E;L5^%qaDgt;-0FPaTe&~*P*_DAe%+ta^oK^Ur0k4!}=<1j|&5NfwxF1jF0Dh^5 zi%hAXqK~L!pl}WC>J!@ayYV)lkW&R+t=`=)89xaxzY69-`vVe2>bLke8E!RD`wnps zXU$5|@gYw@c#eZ73cYYS?j=xgwl-kj>z+@9*z{tM_0Jd)~GKc4EUCsW;$ zjj3+=rc}3TGx#8A{E7)%M%YTi7N3*q7N3n@ajIK+K4C9RW!?dQ2>?y_FNMDn{#y9O zeI4#1%BB(!x72T0VTN1ws|+_rdJBOv@>H^laRi8wuOev0Kq(+$q;YKqu+(Phjp2dLhD%w}M#Q#2V?qfQW2~$OwBEsxzc{CwR*;3L&n2Kf8 z-}~{hZwI{+dKL8Y)2OG@<8Yxn2GUBK}juc%#+={eUd+wpQYj7*tk@VTM z^v6&i!hox5;^Sx$&+hle>$3CRr2X4ew-iu7*}u|UwUx5DKg})fn&#H>lz2MASAl;u zQ1wGRKSv3T{werGHD>x`WR^hVT#NS%ciFA4$th^rt{2PzBVs zW1hbq`ZKg|p29ETir}pUO8U{h`qQ=sWVoe3N#6{&9H;@J_*Fxz1qvU^aH{|bKZo$; zgpDC@f5S`K=aY7S%~r;ot|FY~Rs&^#l*30}IW%0escYlqBXobwwwCbQ0FyAG%N#L* z@&{x-Bp|dR+!a6;b=MK_`DI>J30=AM{6edRRt!zjdmQohBaGlB;C1y6Ep{t>fC5bY z-$q^<)PEs-W%ySDHNuCSa^#4-DLjj4V}e(CvISSy)yFfG@WtH-2b3dQ;;Aj$J)W`f z)za=_@Kyc{pPzoIOKF25Po53aEqRXNR}9oJ4x0R5U;pkZ1@C-cJng*#^r7JAd-SRR zUHz>-Z07)ek%yZ;050hY_JQC$q5EF^M>OIeoF`N@;vbwRs2gH#b8nu|4*X>=A6>vl zcz7AO|NgED;OfSDdJ*_V_s8c672pl?6r3m2;9m-_lyAG6V(uz0p3dNYJeLOWdp%sr zYY=!t+5Y@Z=u$rw4^w}DdX#oC80Zlnm(IX1HZaXC0UG*A{gs_SfA7q@2L2MDtQi0 zx{6WH(I4^O9xn^&14YzH8Ff;;I!?O^S}C-u08QF|1vEvuR!Ex~9(5~5&_0^-96-JQ zEgnxfeAVz3?S*fI@JYQ>b`9%bB7QZ*p~!=j-89@K{;nz{u4=1$JP4sJMMV|biUaJb(0zuj|WZnyu1M>ktTrXrrYpH)^ z`Qe0C4y|m%zRN$Ok$lb|4FbV@`g~FsUJxZ|k$FUr=7$Z^%DZ=R4+TO%6JQnjs0Gdk zF9K!&V*x*oLFA)&Gx=B_&xgbzv>Iqp^6SSTv|4B}Xp*K1;i0}Osc+GBl>U)1;p}v` z^4xTz^R1$Ojm}rSz)LuiH2N}$Pju#mp)&zCEaS2miu21)?&FDi}un{mX$B_GxBmW)Yv ztAH3Fv{lf`1%D#lE#fJ2(S?MOu&cbVX1#N>w@<-S!b$vvlZY261%%cFS`l~+Q0~#% zK@&gu$#^KwLmSW}t`g+>dFqaT`7@*w5ZU5if&Yy>CHz?YYw?RcOFUWey(53WspQ3U zxA3`iw-`SOS9(j#UFd~dC30sW7bpe9e<=QbyxZ}QzDhX&wVwZ2{N)`jyj9@-x?Sdk zMZ9+_fxW(q;jMwMcq!%kGwXLL=W}k2m#@t8s@|jj0+Q!F{hH5Wj<}d|;n{?z%QMEa z9nV8~#&~w*c_`1Lcy{Dj$TP&VInUc(!G>%ReVXSCo+Ui1c;3r%Ak=Te?! zJga$L%JXHOe!9Ns4L?u?j0MVos{rwrc!Ios7C4G`MNteVa@kv|~kMKlEtK=z} z=XJy@>AQ-j_(`56-3G@$3y|_C#s5Y?@+N+R#EoA$&+B;J2EEktle#_Qj`}`x5xA`L zg??iI?;gO12Jk81(uPbM0r%H$)d761hf7*Sb}j3tiX&N9^AuVXS~YHUR6VUZv_jk^ z0a{0B<+!T?w4+2G?%2`wVI>X4xYaTBv~xrr?veoQB9Vu?DnPqRx$qysSy8meW?q0OZLKBj(;({QeKtdT|9hY09W_b)7ycUdOSq|yd;2k2lw^46#=}; z!=;QRee#rFV{dCJeHH}({NNx!-Vod{5ICuMmx>xp~NmGGUnFr;pg$*3vUTB%YoW|#(B%{t>>+}uU>8iyfw&-UYFq(-R|)Q z*W>&czeNHCGi6#*T?0me~?cvZ_(2FG)#fFi1y<-!APv<4-a+uj$XhWGBhOO4Do_sPf%2UJZw2vJ1L~GI zZ%J8w8ma=ktKcmr{xV6!t#RJ+`|EjYJzi<29q*61qF0kTY&SsGHiQB8reBk=rT?m5 zw^x9d5Z;Ux0eTJiozSKK#L9N>YeAhy(O&#Z8u9ma9ujXE{*`_jz{@>cb*)cliHA#i zs=y`RK^;s`UlHrZTIHd5p31dK$*~h zNK{)GSgwEq>PbuqM^ao!?$i{VvLmwVwo2i|JRK~dkqvXFMS>Vf+9 zrMk!5>mH7`nHadQ*D3-pgD&l^3|#6Y*zSV;pkgonRgL%u`#}xNdNZm5^z5~ zRUU5oWslv{6YK|N_;(x_&r=Qfa^y++C7-3eGSPcwxcM#Z+=gE*^upe| z`$;*d2xShGz+VbPAId~Og)Bg1_k*VldSy@Od*G3LRsT81t+|x8**(*(0IK_Ey0HPs z1gd~aXjMQBAabQ#qLzqi@XqJSxA^#!ju!H0@z!+qlBp?Od;h_yO6jR#naXtdJH+GLjRC*tcla5 zzKWsOLa!v8YMSMiHp8a=d-D1tw6AzJkK5Lt0dE<+g;JM$;XNN-)dyZ6SQchH?N#57 zq>iP17Y^o`9N+g*z3cs@?KJc+3iwOiHuNtG_)9%D^sfr|OL^7#Q;U*5)u%pwDYu6H zMFD@Q^E&@%JbYQeU&it}e=mPk0e^W%H1t<}>*JR(yrF+lz+cAehW=#%e;F6+{Js2D z1^i`vZ0N80)yFSmd!0Y|lQr6L_)9sJ1o)&K)$w`pR0RBGybbzGe<>ZrT!nKQ6{|U; zL3=6%8ussUc*;3PQuYyNNjMu46_!WMg<;H3_2eOa-qna?$^~fR4eeH+E zkJ5MKY|6)+E0K2z(C~d+3Qv?XDz%(LDJPv3D|x~v=`6>uf;cNl=f1wrDhX3X-inBG zU*DU@(T6JK+zn@9$~p5=E9YMplWw4>n)m^~FJA<2p`4%LEKU`Cu_fSudWZfG)By7S zlX`xSdX%~o5Z$0WMOSHi^;{G17hRJ0i|$GML*ViY>NdBd=Mf0f=o;o1)IDy2M<7UB zjvjIlFcG*BC3mk3C!;|FocdFMlNgf7u6W7``IlFZLoqf2sFs+C;6K zO}j07kNc3d@YHbLt>kvv8t2i9O0kiUJs^J3Vf2*;ID5v~w|(6QD8nO4zfiQY@} z#iAz@9ir%ZMfWK>G0|;_txXwYvb0mtDT=;Pp@$YdsOS|%pC~%g&cr9WP|*uYpOAT( z%&n?kitANH4>|}w(V>fuTXbZihZDOdnWKsRRraSv7ccrp(KU-MS#+49hZLQr^i|RQ zsb%P&af^;p^mMW>EjmrnPm2Cl=2W7Om9b08t0luI+%jhreW}b{N8A_JO^e=F z=6a%MmN~1;dqsaLIzidrka0}ria*!>DthE`J|GW$RG!Nfw{A61uA8~B2`${>o_W|3 z-j2c{=E zd+(g{opaAUbMKwmneMIJhw=cp3)}<#3{1MiV4CZd7LqO(IrW zvx#uYw`e=&Gx08)$)0ueTPT%9CORRssyvyRnJ@ch<;&pge3`l@U;4r1yZyd=IRFmc zj}ok9q0ELZmM6t}a3oKb;y2slOdo^-nv`@If5=~Vke4n66PDfVX_deW)( zKRfh)I`lK(PmP~!3B&Qvb?6u1SoOcmp(h<-*nX8mzaGb`eVs#3I>NC1W`~~EsL`mi z6MrvfGeJFIDz&ck+CcTL((Jds@7*)|>khLz7hCFnu%mMIoo%kr1Jf$6WH;AuTiBXY z_t6`5ttD5VJon7D)~snKZ!Xz=b7zmM`Mc*)T-v+uFO*QWG8Saz%8;)I&pp5=z`;*F((glALV1ix@^JGR{@Fx{wu*HD8Y^y)|? zU~G&SO=bW+h(TgnzI8L)(jxSxgh7!8LWxA^g>=+hr%gg9b=p&>47?P$rNFhLPBaHhI2wS(V49<}zs?!p&fs7k>P+m< z2La>67MG+z{Uor7?skZlff?uD>XLp;)C*;9OGh7!Tdv@=FFaCv!Y!`P$iOnVDiwDU zxToD>$_VYo6rA^zM|#(|Mb?nJOkVIWWv%!q&wk+i!1?h%oS8Jc@*+xVhBT>qJU_em zkf0neabDUWU|c6~oxrhc8}Y*sW9vg7s~EaUa@otmWl5)WE2nK27wy{P8$Jt9x^(IwEi-VV6TQVoyHQ=rRM{*{v(*=id zB8qFpw_dTUlu<%xb~RhU?Rp2#SMQ!Lf<6tH%Bh8a5Qh3xW8p~yF50@Uk!s$LTzz{ bjbqh$;CL>QjBrF$QjVDhfqR~n5OVcz5?9k+ literal 0 HcmV?d00001 diff --git a/dockers/docker-platform-monitor/ssd_tools/iSmart b/dockers/docker-platform-monitor/ssd_tools/iSmart new file mode 100755 index 0000000000000000000000000000000000000000..c6bba0046024ea421f2ca88fc8800a536d6d9930 GIT binary patch literal 120064 zcmdRX31AdO)_(^WE`f;%ipnvdDCmMA5afy`z{r505e(u95rPCcVwgct5pXh^aU8(| zW${=%!5ifeks}-?psYq0U0l(P2s-1SM(~J=>K&fj&I9HpPqOvzC?DeaZUfO6oU1}9TF@?I;^ z)O%CF(qBXTYlMIO8c>ezIds$R?K!7_gZNXq)1CO~e>pNK?$_iCNcFBLF0Q9il2y4* z)GOB&aJhP~9wxGRBgI|CBk>5Yoy2P=@zi^@B&Xh0{YW?Zce&K>@&-A`Q9g%m%22-Q zcY>wAyo26JlwLYm5MDYsm&?`rgJd}Tsdp9cGT^a(qWZYkbO|w9@=InHMar+b2i%xp;mtQ};@ZB!qx7HARH~b?StQR4rwc#?Plx`jFX}|i(pIcMf>hEO~ zT2+n!L96mfN#GYJDLTcp_-FpRGzpy;0Ik~Bo20x+ z5;~VBDGw!~b9a*Rz9@I$pZU+7g#H}>w32@W%3Wq6$bW=?R`9y2 z{Y(K;ilX|@R)DASh^btG-np$B&k9L#7qXnpHSUpj#rB%=FEeM2sd1Mw2H`^Ua!~ z%<`5@ES{^(DlRFS;hn5Zo>^Qtg9>L*X|c}>lEiT0jpHXyxpDmDf}&|uI&n%tiE=}s zx43AMGP!Uj@Q|5Bc+-GBy>R-hLNDd;KW>v|`n<~IiPL7zDpaNyOq(`yqEb>gedcV^ zXrgy+apCyu$5Y{~SrZFpOjc$VL%|!AqL~xD)0A0rVTS2|FPH?Me4{d1zE2qZ54BqZ{MV4LB29VvuaUf~dG#I-Mc$rj=<1LdM3wwM{ii52pSbYPcUn<1nmK$_ zh`%(Xr{b>8XD1aEwWJ7PA?m5D4d)vvA((qN_ixeVo`pZeF$P%fu*uF5c!)0C(F^)r+kB-~n`@zPs{^l6UTWO_=vcOR8G?bSa z%GI`|>cxig6Akc74dq6^wA@gBk^z3Dp`2n7^>3A-yscV@`+7t9$%gWBL-{F&@|}kA zc82mQL-}cj^1X)g(+%a-hH^C)rs{~Hyn_M0#!%kTP+n^&?_?-f3iN*KGL$zply@g<$*6y>K-Wwg2ue_cmVo`ztwit~dhPeU(S&iMh9ry&qrw}x{fb*wOo`zbqnDebEPeUv^f%DBNPeUu3$N2`7ry&*1;ry?o zk*A>)&EWiD%F_^vx;XzecGN@-$?k3g`btc^WFwnqw&F`T^x>h(xP7|2E}m zXhf?xzm4)VB%qi%J{z=MHmya&s{4&Z@SC1BR z{(j0+7mrTh{N0o%R~pUZ{2i31t{%$S5cn2aJ1%k(tkANU6ilp{0Pc-rhFCW2UDK9aI~EB4KC}fOkRvU|MmK2c<}w} zJi+}Q|ACsk%ZFE%=d{mNJe6CkPN!St0ras*B^duO+1Y6*{J>WTNb)^BXnyecYg>7O z2WOwYo=8!5J@MKtR8dzA;8Lc4?RM&=lY6T9%~YT7S@(NTvHIiyv}FJi&@BM5i`?xW$nv|#>G&r(mQ(Oa(TAv#3Z zhI*Deax6K}`x?;4$$_dhpf$;XzSDpfB?mgD0ZmN~)Y7F2?oJNWUITI^2Rc^+`t7%* zb{e1oeFUH_!;y`Qq|}v^8ceBTO7)}EW0dMisW&KfCZ#^4)M=FZo>J+QYS|g7#+2$# zsiVIl<)+kOq!#bmZtOZ9|GbFeEPal8KRSwYol;uvEL|qEo?vC;N7#I(gk%77f$P2OE2C-Rb$nA&8 zjxYCiCOgnw>pdMQG6{4aRV$diOZ+||e&8)-TzF_X$rao*1;f@8TuXDzBn+0W6qJ%Y zy~;hI0F`?D<&98Kwxs~AC5F$IU+U^A12jzmSc!G^g!0QmocAnsu4~i)#s$YWYU}F! zT$<+JM8Id?{?Qhiup)m$&6XJ&x#DBn-a{GsZ-latER*jzPIP@|E zy;IHfPEzUB{miy1JK{{w@l1Apx69dc>+FuOo+vruysCUlh}cm$5P21JV$HWaih@X2 zq*b_~4EMYS7nF6OoRM%w8#QrnqVlkN@dk=EHsc@cUm3ZPp_g#;pwbikh)UN=$vk0C z2H~J_ayHN;>j`oz`%qu$j(mwN3$e5>kwE9-pA>wHV=e2XJ@6o9yYM{zLVMH7a?blvdkFZZkt z?)>@daHHm1YnukQ1$S<(?bLl+uqqgslLAyx`E*#W`_|yjVBj`}r|X7bSy`DzwULpk zdqF6C9FT3{My-KTwY9oY_bMjsF7~SiRB4TH=qEJd z=n&WWYk&7<;4;67zxJp%Gd9p)d(3;1zqZcXAa>rChF#Fk*#v&ZmiCnHMd?$vbfC?+fPru6SE)8BTm&{SiEyZ@Grj&mgU$tn?V^9a}K(n1S9eag}uo=G76sVxmzX z=-ox>e59T0+>=VnQTsP486s*|Q~G?QrR&bUB6n_${!OEvt`H7C)8kD!} z1fxh(PSH>}_B{_%VB}>03lT|93$kLxmKsf>t4Jc$0j8gXX(?dR&s2v?UmYe#!n6`F z85#`nmvlT5#wlR(G?;ItJR!tD&cI0+ZbJ64DBn^Hu*gVC@h~1tsfAS552;G`4>Uw$ z7ZK@D{tupsA9(!RntMVm5F6#AxqqOLU}%GM?%&8zKt7>B1mw#!0j7hL-~9szY@wV+ z1KmH&e_62mM-AAmA$Gec#UgB>6pOGHDOH4FaU!I9LL;lN~M&22zS;=!KLjL%bQ8q876my4uUIAGAy|ycBJvb%`Owl)FTKO0gj4QHllWij*oyye*E?C8`r_ zaTQ4Eau~Zr`L|%lU1A-jScDfT#Ueb3lqy2JEsobE5@q-Zv`jL{E-{GsahJ%X6wA0XyyzuTY9bc!p9e!XrqjBE*~FcwHh zn}2est}b%TRTSB7kKBQWy`JE|Xc6z}sye^^r0a5IBd-9~&jK`<-yX{rlED)KMrC9w zdJ%^f(WBUV^MqKwP=JKZYc*hR-Q%M6NV?zo>jtR`yaWQLIGi`2;WnvNF>dn1~XA4M~+KJ?I0#BqM1uI+M;8 zmBUoh&Hz0(6|I7V5^XO4&XNE{-qxViPUeO?0}W8Wg&-pzj{*1*q(rNwK}*_a+>nDJ z%?i&#Syk#dnX3H4>j<>o&gbJgsgk>J~@0fYRdV z8+={O*O&OZg07Ojv+Og78CpVIJ>hUM-^4OnEYKERs_UapIU;whL(Qo>BzNw)8gXj`nM8%AL@ zmLv^JdN3Zy8Rw#F(R$I>(8m^R;$i9?;R!F{CJl!d08Zo23(1V zET999!NGO=5s(~@GFqLsYRIe8z-~rhkKsKfw1g6pw9u^e07da{qAp$M?I;ooR!o@G z;=pbmM68y?Nyba)s|WM4$Rydv)bXvr-zERcoe|F9T83h?kky94R$$7ljO^a8kPQZ= zKs4cvPl-^wad(b%j^B$sLu=y_0HNa%RtWKmNaQtAQ#no1Bl>92Lp74l&G8CoWGyWt8S3MGjpEmll{rrnZwLw3a}`(s`67(yK%=hcIjI#l z^dZH96`tVxM?BArgw(H7A78kGA@xo*1EHiuA=NHL&*s7830)h(LcBfiaA6_-HW;F; zR@)F;1^U5F(;%JP4-1Ojmtc4t%7(%(;bxrLXpan*Md^ldz}39oDxw^AS8Z?^OP8Tk zY?{GylB*G;)m;XQgG3qcoS>MPd4kySV18nQq>}d~=rIM+MeX8>z+B{9mF}fvYV=$Z zBNQO%HwU^vkxJn~hO(BUXbYl+s(IBxZ3|-Ip+8OQ4WLTW#cTaEO8+yh(exHtPa+#8 z)%p^W1^b^yt^ajE(^@{EklV~jHfWat9+s~0@D5D!4ch(83$dl`#`5tuXa_JI!v<{z z9Aj|PKIk8;DGThyJ+brE(7>Pr4qE5yO=5=w)l@-G@3e~3P*K6mm7WfD6<7v062musHxZo1iim%AhbgmM6DTOnFRztB68ljfx0VgxBxHu z5;D$pj{Z=DwsRgww$gn7S0x(2HRL`Zp8nME<|9DMvuWaWmTttAlk;0-uRz-Cisk_! zJIb{MV4wXpCut23&62d1;)x9=f7pcfGKm~3PHa%+X(Fn2#@WiKoC?@D4lvOODxAX# zF1i9Dg&euJQR6l9o)B{MjhVm`4piYDKcDaUl*V^QQ1aI{q%Lw2Cmp_1B!LO&-H2j{R&*~OLtzm8 zFjowsLFnw2fgIEzp+rxizRy`6NB2p36q1)z}wtg@+70u+eQE9Y(r=1Ok^tqLm@96+rerL zDI}EGxX=>PBE)rQKY9*q5FevAw1j|ZGc+6~BYM)_htCUVHNyhh6MRp^W@WIYU(mpc z3s4RGn}}Pp+y7=_K<)v1qXr&>(wu<^WD#wZ7Tt$*5#n_s8hmu}0MA(IIP4ynzm2YGKWgPpBscYOv1}UvUm9B5VIe z6Yxl2VI_&HB!QMFRY-mrB_CrVVIpE=BB#L#Ac9jk&ay{gM#+no7IT<*9uW`FHORup z&Xw(eeeY5SksNfMw~JaevbDrHGSOK6mc!9@hs!S&)XQd$nK zbI~}WH>HU&hQXBs;6}H<3e^}*_&2#Dbv5LGLqQxLAT43E3An{hL4FSBDATx!UHk|d? zQ88Q^ljT6*GQH|fSw-?vRbRbormU)xRXBR15-gBaYekh;otk)d3`*NpM0A6E^fXYMnbPzw1saa1pi+sALJ;OJKc7ItjyGr0-gu)1 z!L1&ChF9ZRTGpZgAi|zBhU+Wf9#G*b2+lKcYff3827Y%9f#UhuZ7=9&%Sfu*ZiGfVtix`$@8FPox4*ot z5bbIftqshy8dH-vF zb(*KyHnn)$5$Cva>}-<116ne zaz?77Zs8%?WWy;)i`}(K-tK`?=mWgJw4o7T)h-r!r%K&-I#dxjf*3Uo?wiPLrgzP> z$kO{hx#>eF_lP~R5N9@b!mh2_8<&GrkhzIU^vTCiBuqVXg6NqSpi81> zHu*{InLPj>>m&uGE+e;bDgbp8x=p101@zQ}30m~L&F^VF4<@09X)wue2^(-Q2?~>% zWId>et+-WU4{oop49(X>E#5L$vDSxBu3LtHjF!0*6k!<@!!o$SGJX_65o8o^FG-jz zbBnM{pP$(>-{4e=7_%ngyUNg_BvM?9KFKoK%l+=V339)KA}hJ? z7INQ)rbJt1X>wl;cp>*Wy4(fC}{f$ z7>FSURyYn!A@MUqj(;HGuWjx-J2LiXCRYV%5dUT6OPpOvgI7uj2>BvV#9sXDa2Wfy%de9i3PZY=v+d-pzFdCFpH){tC_l*$+4@i_uAI*t? zcu*_A$fSZLvY@xmB?=yr1$}X-!LjEC=tCoOJUzl<1WgKO;7+n67wVEo(R9XAG@Y>& zO=a9i6-{R>MUz|1gT|?%EtR5OPNMaPXw=rx9n^8-MN{peizS)L-Rwb{J#;xGQ&rAB zDpOTXw#N<(XKYs~(MwgP{_?Y^O%D1lW*PkDnUszA2FdINl#Tj&$m|Hpe(j@^>U+`T zV<{UWb*6$cXe!Ykp(JXtE1A=6&vj#4?R<{eHH3PAx=8{Y52g-k@W(~r-&2k`j4J#twU?sxDYU^f{v)}EqX zj-K|)=;?c3BLJi!zC~cPn**ay7R-AGN2@CxUt-`jCbZ_2j(;Ide<8;nq;Rs_H$Kt5 z6z#NiFLzgJ?#1;j6oPws7#MIbCsjBWfNWZ&qXaj4#Vj{Nr<~)5)%AYf%^w3nYvW$LxHA&IWvZ!9z$ zgGoe0I}whVCJ^jy54)b$c;)`;rZ9bTF=cnhdz1(|Pnp*8svgl2)S%@pbZ30vhVqR%@ZG|Ft5x@J(8`6cjWL-!a zXOd7OyoiBiCs%obc^Q7TG%bs$-_WUUE^scIiw!-!eN;m=3UXsa=l)5JlE6-N(km7^NK&{iZZEMsh}oTQC)lWk-D zStF`lk`dJo$87)5hyp>&5oJX%rG`qKU@FaIq$XbQNElHhY5a)lXKtjX|GOiqW3my2 zfb$QID3G)sQI;fAYN+~V3-Unm7>GGcn6Wo{}OiNW5dL35EL%el%KJ zb%(IF=lIsnsh5Je2meEBuY5B>!B(nPByWAJz2?AwD9q`J!Z=l7!XC|z{_<8vYrlBJ zIJM(p8~0+0y|bAKno(SVmaNa9kR3aFgETcZ<(F`H!m$aS zgp6#EZXUT>;4+AJOVn^iVtT?Qd0KKrI))0itDeS7cY26pw8Jabc90Q7eGKvbezPI! z(_f__`n-|c5O`2Xv8_b}H_+M;ua&WKY*0LiIz`xG>G#QOk)%(EIl4ZksQBD$iu(8_ zX^QUalbfQW*%aE;8`mcgZc61}D~~fpM`4O^O)^s?=@xPttdA`=RGV#4AI~9e(c$&v zw&U>W`9blt7lKhaCGyli-b8LWY8SR;lwIM;bmxltDDWTOYT!?Zw*+Amd_8FNGMgb09hT+f@)AUsE;%7Pm!gw|ASgP z13N{Q-T@diN1Q+hFg>9iG}alQ&FPTiI(QU36ZiE-OMC^jwRa51*SR{)R>@!0JR*pgBlcF)brxD#bRu~+RqC9mPp?a7-T6Xj27yFP05&eRE?v{zgS~SdRj| z@Dd^|kK9E-6MKj)1oO1$c62#EQ^4^r!t&Q%J9|BiCZyvJca9=)P=PrlzM>B*B3mFz zFt8q2p(S*cBrtaG{fOk1r#_p)!t|&SM2t-2!eJ_iATV{7{greSyl9jC4ko^lhzIBz zWKrqVCo5_?^(o5qQ=gQ_sZYB7p;Mog%Ji8%y*TdKXpXlcr?DnjIIH|aRxQ$+OcM<3 z1PAmPx+&giF%L{%MMVg~=@!l!V>CreQdTxj+_A`^s6ZRxr6B4cX|a=30Z=~Zvt~Km9NCDU-!>wS&D@1aq zKDc%VhK6|pkc&icEvc)kqdD~?a&)3NelmCi0>|yFJ4@m6+2SA^|JK!}m+Rx*7csQK zg{p5M`8Scw^n9D&$x4fzDoPrtB@O7UEP7oFj+J)z2iwd5%f*{Y0kfO6d^xKYd;j89 zADE^SVU9qScx^y0E6zBVYk+CUL~G}anrO@~Q|z(w!33lCM()12U@Zb#9L@B-hN zxSM-pIFN(V4a?C5HBVdeA`eBXK({1p=`NpyL)Jc5o~aR|Wp{`(6E1p|XX z0N+Ny6;Iag1#HMM0ZQ;$5ef)BR>8`*FVv?ymov0QcV4iGl;&3osn6D^o%egud2{1B z@1^23yKUk%JK1?xnL95jk`TTO+=0mJH5d`+ywDg}7B~Z+2;JC>I1dGfcLQDqqCVA` z3{2m-SwJJ-O8xJirzWt7eLg}(TTC*}j!>bsF6uteqGL?*fQrGps^| zWiP?ZNK%)vHMO2WTV&P3S0{7=itZA+`^c@N5xH>@{=s_F!BRfDozp}dsB-Y)#5@b{ zSz&EavuBbMV%*8Mm0*(Gl2KvF<}e{FISsyr1&G`aj+~0VlgyIy0b*&%$*734Wc*s= z#6NDsV_2@4Y}g&lR2$+uO=5jf=WDWl66B7ZC`+&mjybSX1c^<@cjrEH-|&yA{|1pfWPyLke=rgYKh#`Uqh64L9K7 zI(aZ*+x0kmEo|EtNCbjuCweZt8D^uu<#bjC<@!!QatSBBG;b{#Op9w@v&dK2pvA}h z(kmR-qA0DxaRuFCJt`cdkRSp-<}xT@MUfPz?Rrrq{D7kyfva-9qsa;2R;U5x=8>B| zMhG6ln-r06-@|2o6)x@G$E6DnTC1q-KcKYZ8*rcjM%wMlre$_zWC-@cQ1t<-utF)O zBJXD`HMaX5Z=$#&X9~UT7jnETGHE#fh!j4X?8E1O97~aQu50@e)OW7?z`uW7-~;E9 zZDo0vS1_2coffcU(8r2#{-rvYzYo$;V_g9PLQu!$NX9kR8IUsa?$f#^tD#j~W4$CA z>ut0W2EqyG^`fzYKvElv&UC_Nhtcw~u_B!0#)?32Zma=^)y7(dA~e?Xbfd;vjsy|# z2vBOQK}d?mDy2$ltXq-L8mr?Tlbmk}IlBls{co#se*Tm$=N)L8$k{jx8d*=5%cw!G zMq8@Qn2*K<@762^+TMrvT_TJ4T^7fQC=9`-;jHflik7W@kz2O*LcL{|?bBNJa};YW zyGLZw*mT+yFo9y7;HLF(eV*XjReW2r5;wE^3OjCPp1hZX=tzJ%ZYR#6fWUXm5xFYh z$4B$uJqh|&fx$;q5eg7Ts5NUBNmChd!C(|mbVQ@7)Wca<$lBLXi*Un7ZwE2sa8{12 zdRSC>aX4)!nxFonOGG#)Av;OP={n@&fJDoQuVU&ne??TlqbHHwSF);`PUK1u;iHCU z#j$%!LLMVM5i>)u^8ne5*d2}2?nw!`M~8H%DtthY;p{~KiL`k_J-YO(;3REVD)A4X z9*j=Yt=dV}yv;RqaPLJ7Ir`(HAv)j?3HU?;iD;#;#a$YSB9LIC(MGFIqJboFT>^>6 zB#EIKiL+EG=%ZIUiLDawbU}g+I!P6ulQn4x#2=D1UoGdwHB{U+NVdmAam2k6a5DoM zt#pm7d0LRb`NBIvf*L9|Ru^HAgt|Qe|An`Ni6&|I7XhFCVke{R{!xLp8}~Q0?Ji)e zEfJlPCq_@W<>!FGDEOLg>Xyn{kdq^aI^&(70FbW4ES$ZHh|VGi5k;t5TF%n7;9JQt z8A~uyuF~m%pBTY(Yzo^GH16b?8+Rk0FT$pQ)l9w!B|e}V#$?nwJLF>&9yBF5^zp>GpL z|4?XnHbfH6{!swi#bF~+|3}=~(|t)!lUrLc!06VV5V=IR){d32*qg3?V~%O z5_BI9aB^#}k%cthwLsQ>Lc}m~Ppx#c07Lq#WcyP}ex^?KcUMZB6*|t|{$fB19BPDU zF0MMC_7Z27j`K8d=uhClohZ?kgcHs_6Tp$@9#y+*n>bfAedjK%<+9Rsk9oT@TQ96)_g|mhVnxb<$A);ZFR)YdS=5J+NHYcKg2kV4U z`Up!vqlsjRWv4VsPcSlm7Mv`G<+=*Tdl-K-CimeUT0(;i620DA49b;Ha}(^PQgqCk zWmKD8unmGfh%_q|>#|{y7>mPEj_OBn6Y8d`7BWZdl|a@8VO}Gk;gIid#AIzbZowrR zaW#b&{!LVfZ`tviV|d(4@Q4-o)-s!UXXVgM^@&eBqC-IX5|%#e#B!Fh1t25i2?EC- ziH3g@-LO~lB3d&xL~W*U*6-9jz`ve=(P8Kv;Tma?v(^%3xs&Rkf|ibnP%l3kLp z{OYfw{w=uS%D_I-lRDCTl@b`8Ngz0-O*`h)(bTGNRvT4+7KL95lahNvo~GEl1UY)^ zbO|MrsY2gL#9=6c5c`j#5Mn2hw!e_p8MqeH39#6R5b>s^$cD2=qX8prkrr;g`-XQ! z_j`K_H*9-Ui|%(H!LXv%OY&UQYrU`>t&U#kIhN4zF#qMD6oOEt6#w4uF`#PFuv1y7$5gO6&$4<@Z-NM29*fG-~gLPJ!5E^z#5)e|2cTH*jP5B>L7rK+cK>X`+D? zl`jT03Ds<&d*2LXV@;5tA0hCA7ue972>0Q24vpRJe*==~j3b=uII33xm- z)KQJ~Vw!uO#(U>&2k<>}l+dfUruXX4ct~v!`qVD{;FQtO_`0r#zPZ;H_R@BcGk}6| zlfm5tZ-CBAk4*kf_7gnApz$9H^x;}HkQgL#>|ya)8*<(!exI$S@-S1y}`hXf*L=TCPJ%_7jHN-&Dr>H z@M09<|GFr>i|^k=7|L8(4mx#Faz11O5<=Qwb}tEddpGfx^f{8#l~UyE82SjE{bUBQ z*`VNjmZVBhGVV<6Oy-;;nZTwq+*6UPrHO2Q~`)u)I4?=DI6U zcOA!!I^TtxNWGN>c*VS@P?gfLE+P%ZuwD^q^acD3hDaj`6BDNStDk%BN7=$1G>)#; zotSY*(N{g!k1Ck!%FJ?QdV=mMjNgo2{ph8rYT`#pbpH< z@em5k$E~*Ar#cw=)&ji<<_YHG$S|B0-kZW5c|42@<>Md!)&{cT(JlS3(%C44ZumM? z5N}ZtPpX;=9BXNs5SgnX3%n^f;P^?XweZ|3ICJ1R?cYrjSgkek*|0hesRv*+_P|A?P4O2 zHxv28fqc*{9+bXlxut$K6HEa)qX2`m!3 zm&)@0yv-nPe8(rr%sp@g+QFMHJK_V#M92MC^*d~%Q@?NVI3- zy*N8YxB32BhcmDWNo#rHhEKdEs>(5+ifS|R;(NP>IzUBjBu0akp{=(GQ|qoj4K zCZ%N4Kjf@w;h7U=J(9^rJL~R}RHi?NlDWTeN8`8V#V{M5{RDSCM2>%aphcS+d}+O> zpy=EG5$}5p*bQJ!Il~T`#w5z3B#XASv7-C^D#CZ*?LI) zq0#k!(*OS4F(Flu&RCt2EC*seKp36%_uBoxSF-qs)OKvfH{MC2}A_81XZ}P{)fDCbyO+9J3WM$4ceA^bmc!y7@0^bqBEtE43@2M1((*p_G*Id7V z_LGK8K=oRN%9*f%>%v(besVF0<6FG6A@;Rm_+FbM%y6CwbPftrUHq@DVoRnnCmn3D zYhFzc>&6SF1Krj0w}T4y)Rd^BF~uK@txe%{Oqq@cn#%|M9bf22IeuAzs77B)guyUz z)SgZ%7DFhWe@#Nw;0?BZTb+TM5|MF2O8r@e6|jl;S%!}O+7`}Idf!q6>!s~bMZb4& zZnP&za5UvC{T#|<9|DlG^jWNW=(!$}BTyQpZ`(ks>scx?m6cT3{>y6@8dXhkjCc`U z`39{Ka-3_27H*#w!j2)~@NZSMC7j@p^yq`U@^XB88d)NBp7$JLp0C@XnR&(thj_{# zRlCIw8C}AxXFI`jh#i`l=TdqKM?7C_$hK{4hit*~Y5tu#$9t!0=Hc(pS~QHAa|>x< zw9I`vwq@TpD|((_dX*iTnO!G5hhasxqbEh$y+se?aQp=s2#{_^$wKRwzvkBcxSghT zqTFTyo*|*h(z$}?qjty^JO>D#g*sZQmfj^*hoWce*ohKbFnue^iq@Q>DVi!%H=d7@ zx?uX6j-3+IJi+u<9W7O+r|C?yb?lUweiC6#8{46ooAk#Tp<}EBTJAnsvr$S6rwWEk z?9j{%-&Gm%&ydhWFc#>TeFnM@I2R546^|O-)p(t{`Z{=4=e^(lLMQwEJKD(yF6xwa zD)AIk+Q~@jQ(99N#*rq7#!YDl=d!L7z;l0F(o~<)ntv~*w9K#Kr?d?Wm+F*u51?6- z|Jf<6D+~4CHl;0UQ@_sB<4f+X=p820f3q*7Qu({q&dG0(-NLosu`W zMlik04$Z9SNb(@mpgg6yH^)tB*>;pHwEpA^*1EABnpuDkNNB^9w(CUAWGN|qgW!3; zj+UyWf0C-h(wFPlDKR~~pB3$(qovBUgl1qdrTsg-ewxk`Ojqh?sWKg=Go7kqr=)39 z!L+v>nz>24NOnA>{o<^jmJffG80B>PEDb^vzt1*+P{dHQK*PR>6)`&lme zg6OZ{R|^|a%{*5V4mr$!^hI`yIR1y7G1vIWmCKVdyjv_muV{7B`=QOA2Y z|7=)DS2nY;n1uj^LV(3~Xl4PfAw!YUav?p&4%vd|_y1z0+v{kl&czEb3lL{`rO%qy zPtn^1(-k^es!Wg4q$-#e>DcCptRc?zBy0#Z5ll06v{aeCuQUCjN&Pgv|6?}qCOb59 zlfEd~an#|r!?e({vtT&V4$aIkpfc2=j+Q`IqmJb`LKe4>9)kj_g>)4@v*Qs_$KR1e z)WPRwLmjqIMaZ!pHxP|)Ecpd&It{S3+Cc$Ga4I)31t51aA_5Q>jp%UJj4wn0@)2I| zG;SAP$8f2xtuuriaofdrVhXSdK&D!hQvfm=%3YkW(Fwiqlwe8{7-la7|EOSlF-Q2L?I z8`e+J`GV>5c4%frXVR!91+%nxmto%5(|M#DZx99Xlna%m2aFeJ4#b zP^wI)>P*8rc1ldo6->w4p_!Z1E!puj)7}o#q7QBOfVDiRXj&%9X=d0_WvERv&jMYY zW;Xn4nr5b>z&y=#L%%H|o?@Drj3lO+li?7txE;sBI4%=JdB3)p<_*j#S(CUuX->&x zD9kBb7tR_`E#{Ov-lsWb4@fEe2(mfDkRdvTJ@g224?MCG z?FZ%(JMIx=dz9laKXHow4oDLW%^hKo6LZJjM7yS`j~X{7B5RKtaW+-V1CwYT*o%w! zZASAcx5+{L3eW5AD*0TQe!fxs&bxkMH?4|*RP^|V$f)@M=pV$Pn-2yN5R_VfjFcja zS}7$1wmtfj%CY#U1JD-gXgrcEknuVl>EHDtzZ?2Au@g*n3Wf%I2H)lYTGde- zGw_>_^t#F5bbL2;FO8k$fM+kT*SV+$ZwmR{d+^j|k9cbHCJM+4bTd4)@fhEep;yna z?@2s^?wu9x)d&>v$`&cEy@~ehcoyt@0t$Qn!T?PHAm8b#ybjg$&Q>^U6@FKW9L64C z&`ak;0_1=H%|(u;Bj-ANha3tcxKTVyXB}42(i(WXiIX_%u#2JKXt*w%_5D_00p!%b zlcQM!Qo_+Z!EiJz)>w8|?X1HZGS)1?bfA09{O!n2l1y+idZ%aMw%^ea@x}{2H-mR$ z)1xh@Ukb&l?-K(423_%*;x#Z7kvkLkP^^}00qa0(u**j}mF5wej`tmaoJLQlN7 zE}XUZEumP>ZoK5hU#Z0NKfr))2SIl;V>n*NO*L4Vr2B|Ycd1I3>%v*Cje>6Eop^&4 zGhC_$8!VWz!C-dw%o*&N+1%n?BAnfzb$c83%=}_h^hb8CaWLeWkNiT)Q&hj+qP0}d zOl)L(Y78i!ig$`L9D`sH$Z~^@#-7mv zncc@4cIxClc4{xYki*_eBEsJnlTSw#Ne?O0cH-6RrP9?k)OlFwn<&~7Z?kB-YspNk zQ3|5Lu*pQDBYQ^CG{L6o98wajsSvEUj+TO84Uj5fR!`7f zUg_SbdE|1w`l0M8z|+&_IIJn}~2k$pdFW=%=ylXh`yTwsSLJaW18$m_`~ zv;sVPu z8fE>{$2k@SlAhAszRj#kHYUjWQYY;3E`N zeZO9f!G>5z6hEvN^P&Qsl_MpIwN$TWtO&5;A^v(?h-DTK)p#E@GP^CT_{0%1X3hjm z;ng&2)3=Qs_vnTAC|n+ewR6>?a2^_mG+M0F6_M{)9VAbH+@pc8!xx2Ntq?9ob@Zp{ zxN`*9y&9MScac`8;#&2bw+>Si^SIxJBzn#%qUWrkijdhx^8AJ?379 zLXY9PaMoBk?myce-(w~-T&g{$pJ2*8=1*9oMd_dqM*>zOSB(VzKU<@8RY2M$; z3LgDVQ!r6p4zk3``G0+lHqlNn3w_drK7X-8vzR}Qeyh(Psjbm4%C`UsUZ5PwjYz@^ z;2}2pNr#uIBIH;hh{6SJt!_kL9N4!IEB#5Rb!cdg4^&3)_qKu6eLaBb@J(xy{tuaO{-eU(S`)fNp?|K;k!E*ctZh)BK z;|!;k0;5p_q8WCyKnBv*RfAz3GbAfmF_dF?J$!t*SWSGp8DFV@#VEj`s8*^C?&SBk z$tn+Yp{n>d+jfFq^&wJ_`SIYl;3|3)b{Ker<`o^m!Xk+Rjxq>HuTLfskb*Ny0WY-U zXAmtq0#9uYuAUztx&IZcNaP%&r z1)Ss3nARYP_BHBz72-MQ+sO{zLf=gr|GV@Z|8xMGOccLX8)M=%iIL#3OLzCiR)E4X-{VT4Qlr^HTlSK~({N72Qx zb^-sW*w({Nl&T8VcgRJckQ&0<4LK_~t05=gQdfv|87FjrDE0c;K{A8*Z8SCk2JiJ> z*>nbr&aAw_0nNE~Xz&rRw!3<=v!`Rkd_|eng0uK}&A*h#&Jbz*uIG8EI_$h=E0=rT zpm_;@3p~Bp(PMjeBW)&Z{ZfVw8=Z?j<+B9qv6--5Y$hz0X9Y>9ds=)eJ5KR&~Tr@%p9fmNx9y+}9HW99jJn(va=x{p2r5ZYXb5QDJ2pvLA5@&D< z9cEgTQ|NF7%GJ=JUm{FXXn7~t96xmU`FNqjN9NFB@@`lHHR2ULJ`NI{VD1zLyV1f@D}=BwMK7`{|0@Jex9Pf zGQ`+z2XCS8)Ybo8`nIr>-`Jly#Av-JKE#lbxK$60j~o!%V*d%@#eYwTF?x76=KwVX4CmCI`dxChXzk>UNnXYt6|d{mGEjJqw$DZnT}xq3!%Od<^W zw4*Bvb-Xi*trL;8b0*Hx0_@+4Gm4jrFYuMl#~!hGZQ>MuN8&C-g?w`HFcQ%nh;_1G zK+0Kq0oErXxo8C?S8yr4LJ@tOpdy^7-#g_b-kW%nORguD+c^0SlF^$8_M$rvY>fkgCTKtbnT`>4UFAyRvV;=Px+H~;#H4Vw9=(*eQ>;<(&DAp>}BvO`u! zP&GLXu_bf0;CZJVnwjSYm8X1FWVju&1<$WuWIbEkp_zH+zby5XuZn#5FB>CS@SG)h zK5mC*<~fnP3)xn_DpFvFY{9ec1=jN%J2W%T9#}0fPx-3IHy_te&ye7`&JNAYv!TjU zzA7@;4%tG_Qv}b!c4%gvP2jXxPx-2d!w%Vk=TpzKZQtE%V;(clLaZT}=L;Chk$XzT z+1AI9!N4iCqhujK7a_nXJ2bNZr;?$lLv!I``i07H-I`}>4 z`KTST1 z*eNm16HIT_(Nbl4n$9#^$4-gqCo5Rf#&&3C!~Up_oi8xuK+#PULp!(2MBc zJE*v+kDyo5AOv13;K7^|P<;YJA*|!NaMnrkFxu76P*_(EQsR-*7ylq?6it*{wzBrf zshsx0)&iQtx^h0f_bemlfS=XrJvzCIA3mrWG{za&Lb8*Rkg}{Vq{MGi&?o$>23_I| zJV})y$2d@fn(aB)VFc553=tf$%ql9MfGCIvoJ|%JYMv=2*uZu8{h_y^4nVw5$E$gi zp17r~=DUDa)vR!DNmEY+u0uH_Y%L^Q$uu2L2w;{_Jp&XV6@`R%Fcca>o&g%MNl5s? zQ}GgB#c-)M#9su{fo?PeniK7>M3v?W;%jb3KH5dgSBkF>;K-J_oZ{=$lz~vr&A#!=iVn&;F(*B6EEGJSaO$6$*bTIe%RCQ(V#!;&O7ni{tCF&`~(P zrV}vqncLFkfQz;TSs7B(fpq@jx3e@Glbnpx`7=`AA-I>Z^cQ&i#mV_+WxvRrqQsk% z_e`Z^IhPItT=aFqi*bI68fec?&pyZ{r=cXegdjvz{xk*Xhqn0`ojurS>W- z^T-E*<+Lp&!s4M%qFaOzT;CYSUd6ylUndh4-&yIrU2s>m8o)P*%w2Gtd31o_z(+>+O&&cq)SDxprt~o;C0_+@9Oe^I@cK|6V^m@A(_s z_H{cnGtVrNllsslg6A!E$QF9G6Fi65p_zH6Q>+D^3+8Qs<9Qz=-jCmdfx^G zJkAPN*rA!3pGF}qDSRdPf@jbU*+Sv71<%oTXl9=ID$gjqB6zm7L$=_#`Z3n?vv+LF zW9E6T%F`!!K4FJ!!Sh1FbE+Mhndei8TG+N};2G(5vshyt!K?tKU3Qc#1las2D;=d! zfkOfd=WP~XEeTDHJ74g8(GJ;y=LqnO4i&h?^~7x@~zP<`8%n4Y0%Ydd5MMOQ6jML*eT zV;?imowV{mZ;1K8@CiFi3x*d8hEwg(%nZL*88%uRqm>IgwQiumQR)uoqMV;-mWgK~9Kxosj01-(@jr1kMOmG?ADWK6HfyueXndrW$qoPQ%nwwGe) zBS8T#!rLo3&c)Yvc5ouiS^6%pq6J5=Q%rFoC`88-#0t(|Nf6I-av&z0 z=uoN>(QB5PoS!WtULT254q%Xbk#W8woOA-*#`#Kuc!!hOjZyVuQ{-cue-?R80y)Yh zmw|Wm9|R%7>gXc0 zqo5ASYJI!<#fO;jKX=&3%R^G&a9o~CUYTYD{=LGGW0@VY10eHS3e4$Z7*70m;r=S;!#0y|_2 zp8FnTJ)78}nR$*-_597jdcM8Q#z+=CrwE=8*rAzuj)Oa7J?|1c$J!xV@ciKc*0Ylx zn*D%jB^ZCYwSLOpDi}X&hh|oGmO5bQVHP@4ksY#yvP}ffOgl6)&n$|msUw{wc>Y*k zKRq9ypSi>LAMMc0JWo)0zSfZSTxf@Ep=T$-bA%n5nWvv(3exie@QgH_CgNjyO%&2A zc9bjxc>F$Ade;^kTbTt|LPC=O^u7pq-eZSs!Sfu!Gv5x)z9-Az`XoCF7K~qA%*yWD ztSOu7_Ixinc%kj%I(B@Jl;p!6g9OtXbhK2NHrAPT*RfM#TDgcdJxu$L$tGoUvwlu9 zGBxX$3ODOoJ7f#%juAX>w?i}Yyiq!T4z7pVVOlWUe=jT9(hkkc@IjTK46YB*j=?+F zFX!MIj|KK3mX7;^REUG?#7{Bb%bV={+E@rl1k$b8ZXM=PMaVH*5aq4n3>qj1iLY|8 zi6@}?3Wh?|%yr?cPA>rqAS=T0QS*5Wmul3UCYZ)W&2NCYRn+{LML9*y0hFsz^W;Pr zikg?bNh%&MYVMkdOk2eqBbUKe*k9?XT^mTD)Op?@c;0V^X69L;@@y%1=G!4#boV16*0ZA>n!#<#-+fY#z0(&s z9^?+{*!M>Ll)XhTe#Q>Xz?jaCVR0rI(~(cSyU$U4v5eyBSpqr&bmSL0vBu?LI1~)j zVR+Z?reQb$1?H!7w4QB3Qi=6!BP8`FHb1Q=Egj$CM(bI6rldZx`A2(g7*;Wq{={a^ z%|xy;;<`J27_MZvREOa$f@$0^ya4Mjt6|v1qMU|dbCj#YFova$373Z9Ni5XyhT-#x z$c862zanmke`3=P!`Ar3#)a<6V>ZMIENPdaA4TbumRz2`OBm1bV5ZMm%4IE0($O9S zwT-JLApDGfVlx?mntWpO72%aL+zymRf238WSdu9Mq{*G70+re zLuqs~E-=im>!|HhAI?k5cxY|6Lo*NO9yI%q3mGAJ-f4$yF`Um7JTJ9FGxO|EIK-1q z$wSZ9cE}bySKY;WenLAm$;@Ns=~Q`MFL*v~hit)fkl=ZP9h#ZvMofaN=eJ_Xa*iFc z1<###vYtoQ)I-m{s-Cw9p6l$8EqGooc+R&&GwV4NUWWB-EO-vKL$=^q9bi3AutPKR z43eDGhwc~4q<2@_7|DX?G{N&>J2W%TN$ObXD0p6Fhit*K76+}+-OsQ?GxI!);%?IO zd9gD3^0oTuSt@wGVuxntd6Yt6;@Ma5EU`nj&@)}|9B7AT=IK?#if!<>kzcMA%R&06 z4=ncmtMyZQk)I8{!4AzVz?~#CDV-yD&a*?dQ2KPi^CBHB)dkWca`-^eraE>?3#4c7 zU`5|wrP(J{ro}qb2XyR|nD!D(udzcjTlZqsMSOu75Q=uPL$&!$*#?N8RR;BPNONf8UyB8gb= z6gFCiuc;#B_yRXI7F*$@k!PSF%SW|-g4U)#i4 zx&<~ug1+b5z&poZ+t6A155$1c5AiI85A!s@w8f#}bR?piQ7mJYk>frONa%yCJl}n~eo9XR&nSgKu=)M<#LW=$Uah00+ElA(wiW%OgN~h2E4}GsBYpXl zre~^513J@{I(AA-FA_{|($P|7dX;3#i;rG9eoAcL^RlkLQska2UNm=z-YP?F@$n|m z)y2nsKbRIDLs4M05q&%H6pN2rk;LMoJ>pn=Kx{e-Izm+^Q4Mm4-1C z79aBEhM9jQa+Q&XXT>i*Ix$?Ti;wT0keV1?&7IrIdhv0sML8`#+$dKUA7>@P(Bk86 zusQzopo1+F8Ph4M=Q-ZLw+TXjPA&?dfEOUc8i@r+Z!AFYjxg^(H<;hbUyD;zF#tvH z2T5L+Y-m6UdYhmjif=`+JWBP6Lnh~o_j|u!lK3@iI;tEUO@PlZ|Faq+xq_36kc^&B zRqt^A^=2|Tzn45wHK-{{_;A%dn@H|*hFeCZ+c?<}DA6BUAWw2SOP_2mlUNWPuI@7H>c1ldg3#NDLXsI&o zuZ9}$q48<_>m*X*d~hbKo35j!%DI`Y?gx))#!884v0(a$j+QFZXJj}Rtwy(py5n>b zDRKU32CLiI4$bV?Lo^xCOi%ADf#-oo>!Jh&mK`{N_^Q}==CY~sy!Xl4_yBpfnvGr@DA9kPX|=p=ZKutPKRyj|tF1fCaq zwzNaG;Q7Kd*7KufHs&$&JQuSt>)BcG{HqEZlSJMEe_UtcszG{bT!ShnV^A`D{WKa(`}R^B8(Hw2B6vPvhi2yakjnEjL?GZf)(+W%=MP1!XD2%}GtX%% zPkJE|Joi6bKRp)+o-f#;nR#ZYTLwQN5{ncK5evKsG7zA^j*^AabyHaBbL`N}0{lcm zQ{#FC&u<>8pVA@0bDbTUeb{sq!6=mV+EK7jwlx?>>GfXV_NyoEM>nvc((KUeg&rmt zZ&^}5Yh5cCm+5G!&R3t(Oow)Ywj*@xlqSi@WY+d19W7O+ujx!be6W6+&Js)?*U?gC zdY5Dx{Q@yP)V*3Kk&?Q<6tcQ!+M$_8!HFfpy1b13`hohXS|%8-wnH;B9H27PmeF3I ztIO!h?@i0-TTozJMtl5+T%O>(T2Ihd6U;w^Gh|3Qda(rV8YDY%($NVwtgT^4#Xs+m zGN&=F4Q}tWVG0Ex;jC`w(k*-2If}BLU?RhQI#w6!8gd`PqS2d953*Y0CxzNXc6?D+ z7i$?AP=j0J$Xjrfi+63$_XH1)fh7GP$zDiO6|5?ATKRb&U*lO`QRHRWow)eW<@t)E~Idg@=3#8bKWTM8F3y3%I?DQdP!Q z&btN!Htv(%%erH=u70vRj0}HwbHTjbinn=W3U&^orDR_UvSafi=it$HYjNgtq1CRn(AM8 z5EX4ABbMRTGE%Y!x5kmf|3te*?-Z`95irmOP=xgRX)zin+_p(6Zo#|>#?PC5LRB0R zrSf^RmjKP(*szDv031yR^4PXtVv9oEE2%`<1Veiz*D>?sJ*d4i5t$y;^26336qMTx z-yw-7v0g_s9|)kXXsR7Z$+bLQz^-N2BGn=mXy%c=ns8`>{ajf39y?@2{bF4Bwc*N*=hk9!jo~4AsM_D}byzv$KwwoZ0ukqc`%2a=dZb55Ftq z>@-wSa<9l8n;Wdl&Ck7jWVma`!7e4=6YfFxF~fsD4G(@evim_eo2H(vzc-95sySBY z34G&q_4>rwiAI*9j0}D~GWgR_P^fFO&*R^o=II~veGLvxuf8_-n%rx1uge|3eevX; zD*Tb{=mJC!5J)Ecr77sOHh=v_DSbvMz3_i#zl)W=eJ)mdXI`xI>U*(*EOIFBImbmc zeCwUbw_bhuCaOeD2A5psE1Gzt%Ux11t5C@wliMTrB3JH3W5x`3Wo2Y$C_`rsb!BB{ zX7tR=>@kY!U6&Nhp6j|KckGx;U3opSGJE&$k=a+d1QnwSX7~!Gxq9`^=#eQXl}w-O z>fJA+N3Z_MCBw($T{>z^ex7T{l!9VczrVP~6i)Q^boJ|zmC?(H-oHn$OlA1!;lo_L zGWse*3uhNiEL4heXB14EdrM)7a&t+Mx6oBwGSdrmW%A6DiG{AB88c>1Dw=hpYm$H- zJL-ypl0rqOH0BD|=-lCGX6I-E3yd?EE%lc4~`pL5Xi6r&2 zW&O$|^@Xzj!GvMQTf)x&6LAns2vkE8r&~N6t z3aOVgK4eNw@s=}?vb zpu}u|-B9RtjUDBhJ*Id{VM(ED%FJ0_*O*bcqc3+Ac)cY>*ZaJMvy3zfeBPN-QE@Zq z*?W{bu1dp$(!Gbfd&gC(c(A~5jI@z70M$RW4(8}RYFK8EJlAQic>17feLE10ZvSg>W`-K9gsaH1?LckW~L&E8E@W8eLd0$#s@XSW@zgzfu1fQ+SiFaE6yU9wWH2(NDT|ZRYCM zb=suv&7tayNi(O*Izl(q8}J1uQ@zC3r7+bS@R`3drs$SJS2I^$Atpb#@*4`9xrWU2 z&G0H+XEl?esamjz(APji@QIUJ&B!WJ8h_2t`5*iP{d3rzOrnXqNOX_5##dEHU__fXM@94=5Z^GGN32g~AJ$2vmgIXf8qz7x^(NnFafM3rf6{ z&d8iJK)aw}I7msXpbpkjX)bDq&YV#QhoWXL63#~H(m4m(D$3d}Ids$RF_*}9>mu%N zCV?~K{n31h-Cq1(!^^^rlN6W$=*PUbrAs96TiR za$I`jl9`*S4DL-8nRLmZ+Kdd8WpI{iGje;=1q3oFm5Eg5MX1FkQ^_QvxFB^Aa5IVg z7@~qprZR?z;(`?M7?VLMqJm2w%Jx!5W#l1t9fGpagoaBdE~vl-DI$OirvO4|qlwgL zVl^wl8J-QtkPa?Z+3Y?N2EZ zgEYF5G`f;Bx{@^-1A(q0wQ@<8{{37-d%ODgaShIO_3h)z$Z++}$PmR@viSeC_bu>o zRAt}Oq?A%hTJEJ(ooWjy&@}fZw8Cy~Bqf)cq~*?ZvpY%FZg%7D=29$Dp+HqYK!E~9 z3luESSIb4^{Y0!%D_5qiZ38a)dDX!<;{Hm=bY!v&P;YQ@%vTu{h9f7`=9fF zo^yN7InOzBW-`;@rlDP|2bFduw59rDy}E)@X{d6gQcLP375d^zqBH6unbOKpe1%?D zqG#n%$g)z_w+kt9B|7NJwVnzynud0kMCxQ4OhpZMLK z@b!AIBvVAm*Vj^Ol)%1~+!`6aLa!(hys&SEFC!kct?=-*ln(Kt`7-*8^$N5T3@`MB zAt~Dmy#$>Abf&erH064*!r3>ZHWDG)n+Qx(TCJD46Io2j6YbU(W?x*&CA3RYPufJg zwJY?hazPi{Elnkni70b<5(#<}Da(}zDvus2ZDl6{o1n`gkueT zyey+iMdF4f$&hw66%*Q3E^R7exn7PURyegu z33QDf6eU+_2SHcpwO*R)BNB0I+qA5vN`%rzBFZX?mR**N z=%ciA(QwnyMknTVfJ__O)j{VtCtA#oL}$^ib7_~u5y|22nly>dGR1^DR@DK+S~O} zG+m2pi?B@_UNk?l$Q(Acq&EL--TN;VnWka?2fubLTH8>L6!qn?ffNO*DS0~1o1ePi zy!nv}68&bJ_6K<5MeVsv)0$da+g8@M7h^$Qf(3ACwT8ViBg9+A2JO%YCY?x!Vn$ai z5nio*0$V*D;ZzhmIkkztK3u}fO`K`Aq+^ssY)8m#uCtbFv1peOP4(frt|;s(C+*Z3 z(TI^28<&}4s(J{yh&W26Si{borgqsh+KK~nMrmo?atcU97{QKUXRxlVrL?Z4*&q|H zh_8+(hT_UPxLhpJO0_brTqLki#s^eT7+9&9so`i*dN?f#kN*Z!(Nr&On4dYbG}Tb5>eP6+ z)D@eWB15^oxv-8}Q$%eKMI(F(O`B|*+~CtFS8ZikQFRe6SD=eFn;+5U7nesC(KWRA zPZLcW=AAyOi_`on>@c^G%j#shh9hjm2hyQiWewuII!8;CC( zhy@3FI?VpIaJn@ySZB%(p{;9`*SU1PtB!L5nx^9h#Jbb*6SpOru`8I=YeErid144> zZE?LZF_27gP;6K722UsTU{cj~V$bMBC}KVvXhOG7M#E`+T;yH1=H zZCs5a#dgyuR%EWpnl{%2Q(}8AZN{CHNKR~qiT~=8$wX3bhaEM9V=xU)F}_h^@Ul*# z+zVmbUa~EdqES}F!--@Px?;TIUI9f4(}tQp)C-rBMA;V&(IzbSOFhx8qx+-FV%r$j zlpe()jK-s4yD%D;YEnT~38um=2$8&ohAZNG5==znZURl|CaA3)Nl;NzXc^SIFBFZ7 zHr5N#9=tP%=K(a;z+yPcdO>q2kxXF|JIeRTr1#4rm8BlSrnnw62eB_NOWF?eMEmI8 zo1=;>lTqOOMZd~q%PlC2@1WfcV2Z|+xp1R(ckAtDIvEP5x!r29F`rDtVrb+}NB3(C zB_l)BBK5Vkh!IW<;!a5fw&6ZOce?5av1jURet1r2`#Z9Sal04BqH)|8jUjivt|h3~ zw%1~8QFp5qTdu)D3>(pLl4iA>hmg=M8JH4B^q(RrDU)|xSlzg`o= z8utl8I)<2u!GT7?jh!@lVQL_j)(iVm3$&Ife3Y5eQ_*~O;Wdv_6_v8dJi05V)Z}T%MSc}GfG~>c%vd@kZbs^8G4vwbGe~18 zOw+b(%BDEl9IINron4KP2{$aJr<80Sx-*=SB+)`nK}{&Ux(EFq3*Pp#n&H2ZCS15) z*s?$)VtFEk$qSBBv;+EwCqe^S0CRj6X-9i|N^hqAuY_WH)x@Z2!(hYephquczr02l z1y6tKIzyN*nQSk=0&=6h@)7WKpE`ZZIY^0+fpY@jvDb{%aJx7bil1y zPXRg41*4WIqJFYRXIz9{NT!B2rh(ZNiY#ziPS{47MYwm_!O<_N)4|>vrAKSK+|A>N zCrdz!0XcxeJQ=BlpA3)knWE-$PzKq|E_}zxz7X0qR?*aU7 z`gP{_BEpt~n}P=>xtogXmCPd^-piBy)HFEu)=oM;f5}(#HSIG9&3bag+Kcnvr$?;q zzzd%lv8GPew3~l6Vif|7-FS=*nE&$;s~33XFGs8mz|LQdSX+U0&yQHo1DpSI#Ci{S z)XO85jz7Yf_R5GA0BWy}SgU|rfa`!a{BFeB3~c%Rh_wUw;y&aLG~OPuH2jUq+dv)o z6+Gq}0B(I3@qu@|hxoul{(|_xIe$fb;Jg2W_`v5!5FdZbGb7)!bYRhB%L)MRInuIL z0bf4avep4#pJiE_f$NU9tR28@z`eldff^n;4txahf#(7Pz%+0b@Fw6o;6Wcnd|(8) z1NhKf#0O6K1mYi}X`y+D4?Oe)#0P%&M8pSPa|+@Ek1R%f;LW9o4?Lj^@qtT$8tzOt z0nr__@0KGzkiH5>pGlZiZCM+Dp95|M{sj0q@bFVD>owqcz^V8%(|dr0Kz#`wkpxct zB;o__0B!)DaXR7yO9O}xtO_DN@KWGZ{B`Klz(U|LHHZ&f1?&ah3)}!KsY86=jljo& zdx5V3PpU_J{Do~ASP1+&uo3tquooC%NKh1>W{B$_JeNW6RnP4B`3aSx0EvAAnWBDvaq>z^%Zo zKst_+piR1{U7IvKbJFqC51xAMq=RP?KL@|$KBnFFC1f-p9cTojPFa6C>6V(hC;MydtmmuqpYKdB|GGBcP*Cjaa*Y zwmk2LBo^}Zpl85$Y;noIZp(@P3gqkITkQDxm*lJTcY=NwzUCQM{KrN7Q^389-xm0w z{m$~Wd^!J`$yXnA)s)K)&i{=lD#aG%IcgI6+OzOs@F|)6@(-c}=YcARycs_0arg{d z-gsGl{`aPcJi&@|&WGN<-;7xA5TWdn_lD3R+pdNDM=$1$UkdqI ze;%=Jbmf1Yo&WieKLh#KT=JW3`C7=Rl}yUI7yF5f1|18DYVjby{7ufO-An*L|5$gqDrhd=a{dNxQG6QqRORoI)*!eGod^hBa zCp+VpP9_Di@A;7b4s*=MT=~zo^Ir@3s~?P5pM?*}^8L%tO9-H`XX>KC@_ zcRu8^FlWworoSSS{#wY77(>1Z^68L&!WsX=7T z^B`}m7^D7>C&!RSAm22Gd_Cm5#*lA;eE%5oosiG2w5%&#<-gP}|I3hnez9eluKKUa z)E{f-U6AK&f5`WbA+Ljcc2(~95y;G=PDoWyJ`)%rpP5<5BUzrbJ=GLmZ+sYo%q*^z$`#;Y4i}Z>!>vhU^C-iC~{^i>Ty}9^%`Xyewl(_A36ehHCT+4;Mdgr+H zmO?KvY*}kDzFhT99wG-f*Ea&a$8hcUQ{?Z`+d18(cNO%a*I=Hac2V;L)%Wy6U3w2e z?~6CX-#O<^(!1E*9($nod;GaAy-LcJUfwiUdXsVO`^?>zb+Na6DR=o!f!@a-w5&6n z>s8A4lVZt=Oyqps3BBNtEb9wIsCwkB7kN^9r6Io;@+NP8I$bPnD3(@--zMno-o<{q zreNlm^J)raU6Ws5pkFq2##5mZ0#)ya0hlOMW`G zPYDR5OA0!6i2+TXC$CfBlmgD5@dU<7 z#s{B+j`5?6pI|IxT*z3;xR`M%W00|d z@l3|$j4K$=Wi%Kgj8VooV~TN@@nXhH8Lwo#it#$e8yRn9+{}0vWqsSTNzEpwTxe7+{U<*aS!8vGfqEQ zraO;u31d5BlyM#7O^n}U{4wJm#F#cT)0(->DW_A#z!yp{1m#wQtn%lJOy%n~jy z<7td57-Ni=G2X&>KjY(!FEYN%I72*@hi8o#Kgrn1xSH`&#+wm7G0tk#vwE63JT>$!7%^rmydQ6IfKS?{wxdUvtjbv}CEV7=RY^zLE3`+fB8WxenF z=-tP9Kl9Ps#(KZ?(c8g#Z~5r`i1lVH9=qLMVZGyh^j>GZdE?Zp9;aTLkDhq826>x4 zdT(<1hJEx{&4x*Qw!tT!8V9%e=&5n=9Ur~%j)ToyzTH0Q-OhS{_0dz~YF5?Q{bCEJ zSLLIp#@{j@y}LQR^L+HwIF0$}ZRPYX_R&-0`34`oZ*h9tee|}o-fkbg`&sW#K6($Z z-a*x4x5u|xZ?2EtcUbRKAHDCf-lu%@cCg-RA3f!7F7wfQjMKZtM{g(V-S4Bfi}iN< z=>3HC-ty6Vjr9&Yb?o*~e(3}sJ>{29_tE2QbHYlW_>(y1gdcO8aKewd?V&;weoR@y zjT3&%Z4VXt|Mg=Neo0x-jsL2CDdsbesdd<;bmei?T_5f#eUK!-#b|EIUhZB9ru!tp1O{E+ec4b#~rd{>~*y2hkpAM>UzMh zzE5#|KjM?`)2w%*kKXTD&#xYTU_HO`seP0sKKbtB^v?9rQ}gR8A3fDiC-yJcunel- zf7tsMJ2?M;*6Zr=UN3)G*TH_{PmP0qpK*}KcE8d`j~{c;?()%7`TC7NmG2LI(o^|9 z@1r-~@q94X_Z6S?)bkl{`{=28%x`~l8s~fH(y{%&+6SHEqo?MRavwdlFJJGY_itRj z3&yDz_t8`9)=PZ!9^!m&^3mJDdIxHs|Hqu(cAtFJeD^aSJvHC`!AEaD=R4(-WA_8) zM-KPVQ|q&NK6;$3ruyrFT6d}b<#%7|K=-flu9L>QzEFCVK6X@k!Ex%f_~?yyT{F>s zV~-crF8^xncRP0szjgKz`E{^m12<5}r_ z-bYVeH(%$Y_Y@aky!%v}ebRe{)AM`2N!44Ss@K12{SWl~Ki>ITUC;XMYuv{T^^i~d zZ)3fm_~?yyzE;nNJnxg8bhEZ{4BvKJ4|cx=uaN&!hQ0-!aiomB(`9 zL_c-gLxuic{Zyr|@E|_%8?Oht|ElL0{q|v$Kc09#ShbkM@%nAGuJ~7fKG^U2>|bph zsQrQe?a#lfb@+_a#@=rm?>P894>P~NA5iO;|LxDyE5AP1$A0QQkKf;Y+{gAiP=7D+ zO-`@ar+oLbUbBy$dJfyKeCj!DzrW{rmGiy8C*R+(UcyID^}jVfdTPJRPfx8QzT}gh zx-WB=j~-XU2GxHK)cu+9&TFawd3^GyPq~%e{~f2^pMCVyecr=PAKULJz2b4|MaHRj zv5(%tY?rT$Q*Y}y^&a=pQ~km3{<88Xe)o;lJmt4eRC;gvluunhAE^7rJJ`+#>OSvy z=P5P+eAw5|L*+oT%~nj~d4de9EWBanMIktt0*Z-cpUvvwhN2dTV_2 z4)nPDTd&W)=u^ILaEG|XM^BAozjdk7yVoZ@wH`T8`)>z&yg$Wu+2K=<@%ja|ei-li z^~3fbYCUqG{_g6G+S*g~!WCWk!r6dcQB+=3ys&aWgi1bFQdv}7UR1q6@_K1;No8?m zakX+yIWZqzt12%rN}jLfX`Na5d@Y@opKQP1$C+3@-uAO2tNs-G{XcH~gSBk$&B@2x zgw*?X-1_hahXkCIIM2shgw*?eoWgwVQ2RYcZhpG9o!^J!<`2{M7X+M?IM3G#@Ivuy z{0vRKH^~_(Uz@3|nlpM{$j8SWHr8b0kI;%6vhhdaqbVV0(p;XS?DsD@h52|}(#)*- z$7tE!7nH9ZtG#DrOCN7P;`b}L(?3oNgtF<+*7n|&jaP4v%A_(0r<1ie?C;7b39XwZ zWhpNPo7rpUX+*prZr7Nq8HmdY_db@!v)GQTn?* z>0crAN4Lve;Iq|ho6tWF=9Km+MwpIA@SCI^r)_4wP_TGkGV^kQFk&XSUQA-^2i42|k-0YQayUw};&w5-HD`EI?bv{H%K=ub%hpWM231=P_T% zJc8or#R-*v+X(>?en-;U5c7AO=;p6req*8Jx3K|0scYe-(4*E8^O`>Bj&HJ3W%`yHU`dq&iu*Ml0O<@ zI`%RjI5i-`e-Z!VyB^@FKU`Z86wG1FTdaTTl7L{uw=r-w4GUB%|Lsd9ec0sdO>VqAF2a|iRgnTMwn$3vXXO9KHBj&r^bv%bdf zwU{r}wI>8WTPx;%cqsF~0H3Y@zbN$K&7vWpxf@|R{>1#=)sm<0U(rD?B_{u{u3z%o znLiHWmH5Db-e4&!@@zsAk~Sn*$$ysGc7 zm|u0h z`E|ET{Z$Clq5NUMvu4pW?tnRVZPu?QeW}?%x`60)oUH|&wBXl znIG}+cQU`=Dw%$fCXYv$Kg+}ag89ptSNZN^emnEaI30`mzj*kguu(z%t?p`>ulU9S z;>=_I*sr?zYUclNi{!<(7NFnC{Hi-8FTSk+zKi*v+#`AMEd}s{%s=yQk{91j0DmR( zsRt$hD36zo%$Iyy^5WYF(7%WI)!&u8O8>jef989V7vDaB{tubo_L$_ww+_HR#r%w? zB`>~h0R9E$zw|4~i*Ff#|1C$8-jKZbHUao~ z%vbzX^5Ra)7mBlzss zQ`zSC6!h^0#!=T1>qR=FufMKleed<%X2FlXPJB?LgVl=Xy6g$?N5Gx|zTV_%O8d3o zRc$i(ryTr2hfq4Bk6AhRg*o`3;0v@jjetmOHYeE$UgvWs^n*Vf*9GeO5ycb7zaL8a zqpvsVn>g9Zxsme?t_+Cy>U!ty9QqHle%p}L7vGvf%pd2_e}VPyOG-x5PwH|Nm*b`JihIr#0kFv-@AzvX<}J}vVV-#A0QZ!!Nh zQ}T2jNXKF5C)v`On}e?qe1Z1pKtRMlM*I)|kwbrOj`E+ILw`*U{wmJ*{bQt``2y#A zC-eQ>j&vPM$9KU~|MBj(?97q=^WbS5y>?ef#8=~JAE#e(L_qMn#Q&Q1W{z|wV$QZ^LCw_u7?yeBcuVw84me;L zr?d9#fMCTp4RJ=-@09PmT(2!0XBF$;eUa3k#`z|g-+g>gXqv2l3G>@OEA_jX|B~Q2 z;DE2^;2#8kINEC+@6YUKNBq4U`j?=-Gtpkld7ZDa_&&Fn+HX9G1wRw%6lfptxE9|g zgzR_BUwW*pm-u!L_;y<+shvdh?K>*N^zE#V>})!_yXnNFn# zy1R?Qnqe%fZ8w^mIywzQi2wr|4yG@ZOgqA=09q{CWkgdXMX{nCEy4CqEfP(wmbyI#oohWtcOn@!!Nn6=M>rMj zFw?b(zP?aAB7$dRg0XZm+NVL@V208INmGNYuDOYd)*TC_dJS2Za00h+#3$6nSJ{m? zEGUBALu8XwG!YlUl$ng8h2jH!A{Y+!hr-b`nYm#_Yi(y!TdQFd;a*Rf5cis)Sh`o7 z!XD{RSIqQkR+Y+hg*~!sRBN@pW_WeOSrTg#XyimJW+t^HN*ysmv1pGhT~wJ-S}RP^ zjJ|{sLvQnBTv}N=imBF8s8=7-?-d3}6;+m1mTO%D-E>l+Wxg(twn59RtZ!~Mf@xT| zOY3N9DlILqtZyAnG}UJGjFlx0Rkx&6O3ErdNu1ru#6a346{D@QvA$g?Eo-T)T&x03 zt*vcY&W-wxv!j|2Ru-4K6mVBgg&WH3vvT{at-Z6UwO*A#Yfxcl(KD>0(yLgco(LJ^}YmIz}cBE57XjUnOY zlBP>#C>c$gjwo`_Ws(?(r$pa3WTi4?PljU12bo5Ulo=L&F(XX%hmy`zyOX9f819Y6 zB1V5Gnv}*#CVJo)jqXr1=CF<|iib>^{fQ)HIuH*hl1b$3hyi1U;b`IN3|WGtNp93( zi&$4EWr#X^NwSOJQpqF+DU3N7iU}e)6hrM((KK9*5oTvZB)NC^DMeAlSac8#%sNE4 z&if*ESj`^>d|i($OSI2S45TwecmVZ_qi>nv1U%guBituT2=ADMrS2yi(&$en$V$pJ zIwYz%vNdCgREo_<4qJHhkn|d!uwkZ#qnb^Ymckc!HE95k=BgE!>Wh*eGUFa%81tUY z6BfnPqiV*{)s>DrY{W6%F(Wy3WK~ia?{cc*m~iuhW-O)> z;t?-}0)x*?Lqj7`qnzECgjpWox3LZh-TEC(;94Ps)d$Ag0YsQ z`QVJ!6-Ip{r`A~4t{G=Ex77rjjkbn{4*0yzU`=y9<$y^!Y=lz-qAzOw1L<&YC>aQx z(cDy1Ym^q17FA#&5XM}G&gG`X4CSV0>Z*SJXxA@n{sN4~|L&`@TW$7t$oF*56? z&X!tQJ#~tSHI@ef0M6y0EVxclAcO1$#7VS1Mw&NO&*H|>ZdbCPv z2<}*|auBCK8gVNbrf}6!_5?Is(&R`|1N}5?v~H~YQl2V9IWvbVMJkYk6^6iy%4-|c zHD<=$WuT~oeM96X#hS{1vp{>om{=Hudsho*n2AzOE&{7LgO+s}n%XzD1`F0cH|I@V zIyMs?1xq5HI;h|Zw$ckReVj)g0P9&~T|LN;@=MMXXk{;_M#VWJgOn9ne7(G}{ z$;8B1jieGrFPs7vf@D2f?ZWAzAWoy9o3|lO1atC0%9P$1ZmGLmO||ya+ciK_912Y9 zN_&*jP#0d*fZ5UiwLUS6x~tLM9UDmXy1AA%agCy-va}4@N>1Z;M;1Mis*y1*iqQpc zFRh2%vyW=ov~rP3@f~5iZMqZv-rj618#LPa(y12HQwrBj7%>?i!6S>3%vRJ;IuUhO zxS=`N(a3e~PhvhE)qZd>%F&YVQCDs*&qJe@u0+sV@XwutVT99b`mrp*mD0-yEA(pr(|M@2X->PaA&Hiz*)Ek~e~5YDa0?B(mr z-Ut#=AsJO(Xv!Gs{L^8mA)8QNG>ifz(v&eSI^&da(vyXjB~Y5rsxu!IOD75^wJ!Eo>FA=#;*ha z4!&Kd%D*u$AT&2JQ7A&0@As+wM5eV?oM5ZUF8_|a07CR#KLOf)-eJ+JD%CGbku7;ex?We+#x;Zi)n^CEc8b9}Nd{s@g zAH9m>SDj!-6(_nosNIh+<)q@P=Q=mm$o#*`?WdwqTRV>*AmEIzp8qUvknvApJE%Bb zdp-dHncB`qJ@N(c;jIryl()qI|zI|VHm5g7^`9n<{DxSjkz>>tsCjzphRgM}U-;im&#Y_woZX{hkh^b36t4$cAz%Rs^GpU+&>$sbm}y9gd&M z+o@XiwA7rgBCyaC6nU$@?~Fg|ZmIbi-+2Ehg!kg7?56x5jn8cPYmdtKW$Z^(+TQ&C E9}TO>QUCw| literal 0 HcmV?d00001 diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index 617cf39e8b87..5eb26fec2f82 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -40,5 +40,7 @@ $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista:/usr/lib/python2.7/dist-packages/arista:ro $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista/utils/sonic_platform:/usr/lib/python2.7/dist-packages/sonic_platform:ro -$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += sensors:/usr/bin/sensors -$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += smartctl:/usr/sbin/smartctl +$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/bin/sensors +$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/sbin/smartctl +$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/sbin/iSmart +$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/sbin/SmartCmd diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 33b037d38f1c..cc2dac5963a1 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 33b037d38f1c96264729b966e777efed143ed01d +Subproject commit cc2dac5963a14d04dd15735de35df9b30cff1e41 From 8861cbe98edbe513aac5d1ee2c5943bf6179c905 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Fri, 4 Oct 2019 11:20:57 -0700 Subject: [PATCH 0036/1427] Configure buffer profile to all ports (#3561) Signed-off-by: Wenda Ni --- files/build_templates/buffers_config.j2 | 8 +- .../tests/sample_output/buffers-dell6100.json | 240 ++++++++++++++++++ 2 files changed, 244 insertions(+), 4 deletions(-) diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index a5212d979fcb..bf74b2dcf52c 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -131,7 +131,7 @@ def {{ defs.generate_pg_profils(port_names_active) }} {% else %} "BUFFER_PG": { -{% for port in PORT_ACTIVE %} +{% for port in PORT_ALL %} "{{ port }}|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }{% if not loop.last %},{% endif %} @@ -144,17 +144,17 @@ def {{ defs.generate_queue_buffers(port_names_active) }} {% else %} "BUFFER_QUEUE": { -{% for port in PORT_ACTIVE %} +{% for port in PORT_ALL %} "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, {% endfor %} -{% for port in PORT_ACTIVE %} +{% for port in PORT_ALL %} "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, {% endfor %} -{% for port in PORT_ACTIVE %} +{% for port in PORT_ALL %} "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }{% if not loop.last %},{% endif %} diff --git a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json index 5cf0472f3f11..38e2b8313eb4 100644 --- a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json +++ b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json @@ -111,6 +111,12 @@ "Ethernet1|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, + "Ethernet2|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet3|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, "Ethernet4|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, @@ -153,6 +159,12 @@ "Ethernet17|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, + "Ethernet18|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet19|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, "Ethernet20|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, @@ -192,6 +204,15 @@ "Ethernet32|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, + "Ethernet33|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet34|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet35|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, "Ethernet36|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, @@ -213,9 +234,33 @@ "Ethernet42|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, + "Ethernet43|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet44|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet45|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet46|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet47|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, "Ethernet48|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, + "Ethernet49|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet50|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet51|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, "Ethernet52|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, @@ -236,6 +281,21 @@ }, "Ethernet58|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet59|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet60|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet61|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet62|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet63|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, @@ -246,6 +306,12 @@ "Ethernet1|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, + "Ethernet2|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet3|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, "Ethernet4|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, @@ -288,6 +354,12 @@ "Ethernet17|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, + "Ethernet18|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet19|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, "Ethernet20|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, @@ -327,6 +399,15 @@ "Ethernet32|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, + "Ethernet33|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet34|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet35|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, "Ethernet36|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, @@ -348,9 +429,33 @@ "Ethernet42|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, + "Ethernet43|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet44|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet45|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet46|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet47|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, "Ethernet48|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, + "Ethernet49|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet50|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet51|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, "Ethernet52|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, @@ -372,12 +477,33 @@ "Ethernet58|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, + "Ethernet59|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet60|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet61|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet62|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet63|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, "Ethernet0|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet1|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, + "Ethernet2|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet3|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, "Ethernet4|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -420,6 +546,12 @@ "Ethernet17|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, + "Ethernet18|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet19|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, "Ethernet20|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -459,6 +591,15 @@ "Ethernet32|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, + "Ethernet33|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet34|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet35|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, "Ethernet36|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -480,9 +621,33 @@ "Ethernet42|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, + "Ethernet43|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet44|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet45|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet46|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet47|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, "Ethernet48|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, + "Ethernet49|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet50|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet51|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, "Ethernet52|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -504,12 +669,33 @@ "Ethernet58|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, + "Ethernet59|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet60|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet61|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet62|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet63|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, "Ethernet0|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet1|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, + "Ethernet2|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet3|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, "Ethernet4|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -552,6 +738,12 @@ "Ethernet17|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, + "Ethernet18|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet19|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, "Ethernet20|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -591,6 +783,15 @@ "Ethernet32|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, + "Ethernet33|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet34|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet35|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, "Ethernet36|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -612,9 +813,33 @@ "Ethernet42|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, + "Ethernet43|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet44|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet45|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet46|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet47|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, "Ethernet48|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, + "Ethernet49|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet50|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet51|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, "Ethernet52|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -635,6 +860,21 @@ }, "Ethernet58|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet59|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet60|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet61|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet62|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet63|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } } From c16f12b082090fe1316e5ad79700818e3e926503 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 4 Oct 2019 12:47:56 -0700 Subject: [PATCH 0037/1427] Update sonic-utilities (#3563) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index cbf19f643a1a..02375e195394 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit cbf19f643a1aa708eee6306814c0d52fd7535ec4 +Subproject commit 02375e195394cd84fb2e7639f953a72b894ed000 From d316bcb53761172cc657f7a17e4da11e60445589 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Mon, 7 Oct 2019 22:13:47 +0800 Subject: [PATCH 0038/1427] [Mellanox]Upload the SDK makefile modification (#3555) Adjust the SDK makefiles so that it reflects the dependencies among libraries in SDK 4.3.2104. This is a supplement of PR [Mellanox]Update SDK(4.3.2104), SAI-Implementation(1.15) and firmware 2162. It doesn't impact the sonic-mellanox.bin image but makes the future SDK-integration easier. --- .../mellanox/sdk-src/sx-acl-helper/Makefile | 29 ++++++++++++++++ platform/mellanox/sdk.mk | 33 ++++++++++++------- 2 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 platform/mellanox/sdk-src/sx-acl-helper/Makefile diff --git a/platform/mellanox/sdk-src/sx-acl-helper/Makefile b/platform/mellanox/sdk-src/sx-acl-helper/Makefile new file mode 100644 index 000000000000..d9d0aef8775b --- /dev/null +++ b/platform/mellanox/sdk-src/sx-acl-helper/Makefile @@ -0,0 +1,29 @@ +.ONESHELL: +SHELL = /bin/bash + +MAIN_TARGET = sx-acl-helper_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb +DERIVED_TARGETS = sx-acl-helper-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb \ + sx-acl-helper-dev-static_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb \ + sx-acl-helper-dbgsym_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb +PACKAGE_NAME = sx_acl_helper + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # get sources + rm -rf $(PACKAGE_NAME)-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) + + wget -c $(MLNX_SDK_SOURCE_BASE_URL)/$(PACKAGE_NAME)-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION).tar.gz -O - | tar -xz + + # build + pushd $(PACKAGE_NAME)-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) + + if [ -f autogen.sh ]; then + ./autogen.sh + fi + + debuild -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + + popd + + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 7a832b2502d1..3cf3ee3ff976 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -15,17 +15,17 @@ endif export MLNX_SDK_SOURCE_BASE_URL MLNX_SDK_VERSION MLNX_SDK_ISSU_VERSION MLNX_SDK_DEB_VERSION -MLNX_SDK_RDEBS += $(APPLIBS) $(IPROUTE2_MLNX) $(SX_COMPLIB) \ - $(SX_EXAMPLES) $(SX_GEN_UTILS) $(SX_SCEW) $(SXD_LIBS) $(WJH_LIBS) +MLNX_SDK_RDEBS += $(APPLIBS) $(IPROUTE2_MLNX) $(SX_COMPLIB) $(SX_EXAMPLES) \ + $(SX_GEN_UTILS) $(SX_SCEW) $(SXD_LIBS) $(WJH_LIBS) $(SX_ACL_HELPER) -MLNX_SDK_DEBS += $(APPLIBS_DEV) $(IPROUTE2_MLNX_DEV) \ - $(SX_COMPLIB_DEV) $(SX_COMPLIB_DEV_STATIC) $(SX_EXAMPLES_DEV) \ - $(SX_GEN_UTILS_DEV) $(SX_SCEW_DEV) $(SX_SCEW_DEV_STATIC) \ - $(SXD_LIBS_DEV) $(SXD_LIBS_DEV_STATIC) $(WJH_LIBS_DEV) +MLNX_SDK_DEBS += $(APPLIBS_DEV) $(IPROUTE2_MLNX_DEV) $(SX_COMPLIB_DEV) \ + $(SX_COMPLIB_DEV_STATIC) $(SX_EXAMPLES_DEV) $(SX_GEN_UTILS_DEV) \ + $(SX_SCEW_DEV) $(SX_SCEW_DEV_STATIC) $(SXD_LIBS_DEV)\ + $(SXD_LIBS_DEV_STATIC) $(WJH_LIBS_DEV) $(SX_ACL_HELPER_DEV) MLNX_SDK_DBG_DEBS += $(APPLIBS_DBGSYM) $(IPROUTE2_MLNX_DBGSYM) $(SX_COMPLIB_DBGSYM) \ $(SX_EXAMPLES_DBGSYM) $(SX_GEN_UTILS_DBGSYM) $(SX_SCEW_DBGSYM) \ - $(SXD_LIBS_DBGSYM) $(WJH_LIBS_DBGSYM) + $(SXD_LIBS_DBGSYM) $(WJH_LIBS_DBGSYM) $(SX_ACL_HELPER_DBGSYM) APPLIBS = applibs_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(APPLIBS)_SRC_PATH = $(PLATFORM_PATH)/sdk-src/applibs @@ -69,7 +69,7 @@ endif SX_GEN_UTILS = sx-gen-utils_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(SX_GEN_UTILS)_SRC_PATH += $(PLATFORM_PATH)/sdk-src/sx-gen-utils -$(SX_GEN_UTILS)_DEPENDS += $(SX_COMPLIB_DEV) $(SXD_LIBS_DEV) +$(SX_GEN_UTILS)_DEPENDS += $(SX_COMPLIB_DEV) $(SX_GEN_UTILS)_RDEPENDS += $(SX_COMPLIB) SX_GEN_UTILS_DEV = sx-gen-utils-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(eval $(call add_derived_package,$(SX_GEN_UTILS),$(SX_GEN_UTILS_DEV))) @@ -89,7 +89,7 @@ endif SXD_LIBS = sxd-libs_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(SXD_LIBS)_SRC_PATH = $(PLATFORM_PATH)/sdk-src/sxd-libs -$(SXD_LIBS)_DEPENDS += $(SX_COMPLIB_DEV) +$(SXD_LIBS)_DEPENDS += $(SX_COMPLIB_DEV) $(SX_GEN_UTILS_DEV) SXD_LIBS_DEV = sxd-libs-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(eval $(call add_derived_package,$(SXD_LIBS),$(SXD_LIBS_DEV))) SXD_LIBS_DBGSYM = sxd-libs-dbgsym_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb @@ -107,10 +107,21 @@ ifeq ($(SDK_FROM_SRC),y) $(eval $(call add_derived_package,$(PYTHON_SDK_API),$(PYTHON_SDK_API_DBGSYM))) endif +SX_ACL_HELPER = sx-acl-helper_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb +$(SX_ACL_HELPER)_SRC_PATH = $(PLATFORM_PATH)/sdk-src/sx-acl-helper +$(SX_ACL_HELPER)_DEPENDS += $(SX_COMPLIB_DEV) $(SXD_LIBS_DEV) $(APPLIBS_DEV) +$(SX_ACL_HELPER)_RDEPENDS += $(SX_COMPLIB) $(PYTHON_SDK_API) +SX_ACL_HELPER_DEV = sx-acl-helper-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb +$(eval $(call add_derived_package,$(SX_ACL_HELPER),$(SX_ACL_HELPER_DEV))) +SX_ACL_HELPER_DBGSYM = sx-acl-helper-dbgsym_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb +ifeq ($(SDK_FROM_SRC),y) +$(eval $(call add_derived_package,$(SX_ACL_HELPER),$(SX_ACL_HELPER_DBGSYM))) +endif + WJH_LIBS = wjh-libs_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(WJH_LIBS)_SRC_PATH = $(PLATFORM_PATH)/sdk-src/wjh-libs -$(WJH_LIBS)_DEPENDS += $(SX_COMPLIB_DEV) $(SXD_LIBS_DEV) $(APPLIBS_DEV) -$(WJH_LIBS)_RDEPENDS += $(SX_COMPLIB) $(PYTHON_SDK_API) +$(WJH_LIBS)_DEPENDS += $(SX_COMPLIB_DEV) $(SXD_LIBS_DEV) $(APPLIBS_DEV) $(SX_ACL_HELPER_DEV) $(SX_SCEW_DEV) +$(WJH_LIBS)_RDEPENDS += $(SX_COMPLIB) $(PYTHON_SDK_API) $(SX_ACL_HELPER) WJH_LIBS_DEV = wjh-libs-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(eval $(call add_derived_package,$(WJH_LIBS),$(WJH_LIBS_DEV))) WJH_LIBS_DBGSYM = wjh-libs-dbgsym_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb From e9a0c5771465ec31d5ee83a9be3a2f86ad9cb374 Mon Sep 17 00:00:00 2001 From: Mike Lazar Date: Mon, 7 Oct 2019 10:16:11 -0400 Subject: [PATCH 0039/1427] [vsimage]: Support for the creation of a GNS3 appliance file (#3553) The script sonic-gns3a.sh creates a GNS3 appliance flle, that points to a sonin-vs.img (SONiC Virtual Switch). The appliance file (and sonic-vs.img file) can subsequently be imported into a GNS3 simulation environment. --- platform/vs/README.gns3.md | 17 ++++++++ platform/vs/sonic-gns3a.sh | 81 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 platform/vs/README.gns3.md create mode 100644 platform/vs/sonic-gns3a.sh diff --git a/platform/vs/README.gns3.md b/platform/vs/README.gns3.md new file mode 100644 index 000000000000..c434d5e9b405 --- /dev/null +++ b/platform/vs/README.gns3.md @@ -0,0 +1,17 @@ +HOWTO Create a GNS3 Appliance File (.gns3a) + + +Execute the command sonic-gns3.sh + + +For instance: + +./sonic-gns3a.sh -h + +sonic-gns3a.sh [ -r ] -b +e.g.: sonic-gns3a.sh -r 1.1 -b /sonic-vs.img + +For more information about GNS3, please refer to: + +https://gns3.com/ + diff --git a/platform/vs/sonic-gns3a.sh b/platform/vs/sonic-gns3a.sh new file mode 100644 index 000000000000..57c63fb75f32 --- /dev/null +++ b/platform/vs/sonic-gns3a.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +# This script creates a .gns3a SONiC appliance file +IMGFILE="sonic-vs.image" +RELEASE="latest" + +usage() { + echo "`basename $0` [ -r ] -b " + echo "e.g.: `basename $0` -r 1.1 -b /sonic-vs.image" + exit 0 +} + +while getopts "r:b:h" arg; do + case $arg in + h) + usage + ;; + r) + RELEASE=$OPTARG + ;; + b) + IMGFILE=$OPTARG + ;; + esac +done + +if [ ! -e ${IMGFILE} ]; then + echo "ERROR: ${IMGFILE} not found" + exit 2 +fi + + +MD5SUMIMGFILE=`md5sum ${IMGFILE} | cut -f 1 -d " "` +LENIMGFILE=`stat -c %s ${IMGFILE}` +GNS3APPNAME="SONiC-${RELEASE}.gns3a" +NAMEIMGFILE=`basename $IMGFILE` + +echo " +{ + \"name\": \"SONiC\", + \"category\": \"router\", + \"description\": \"SONiC Virtual Switch/Router\n\", + \"vendor_name\": \"SONiC\", + \"vendor_url\": \"https://azure.github.io/SONiC/\", + \"product_name\": \"SONiC\", + \"product_url\": \"https://azure.github.io/SONiC/\", + \"registry_version\": 3, + \"status\": \"experimental\", + \"maintainer\": \"SONiC\", + \"maintainer_email\": \"sonicproject@googlegroups.com\", + \"usage\": \"Supports SONiC release: ${RELEASE}\", + \"qemu\": { + \"adapter_type\": \"e1000\", + \"adapters\": 10, + \"ram\": 2048, + \"hda_disk_interface\": \"virtio\", + \"arch\": \"x86_64\", + \"console_type\": \"telnet\", + \"boot_priority\": \"d\", + \"kvm\": \"require\" + }, + \"images\": [ + { + \"filename\": \"${NAMEIMGFILE}\", + \"version\": \"${RELEASE}\", + \"md5sum\": \"${MD5SUMIMGFILE}\", + \"filesize\": ${LENIMGFILE} + } + ], + \"versions\": [ + { + \"name\": \"${RELEASE}\", + \"images\": { + \"hda_disk_image\": \"${NAMEIMGFILE}\" + } + } + ] +} + +" > ${GNS3APPNAME} + From 50cfa7724327cc9e3446bdf17dd01717bff3a507 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Mon, 7 Oct 2019 21:17:46 +0700 Subject: [PATCH 0040/1427] [device/celestica]: update psuutil follow new platform api (#3537) Fixes #3518 Update psuutil API to detect PSU GPIO base from label --- .../x86_64-cel_seastone-r0/plugins/psuutil.py | 77 ++++++++----------- 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py index 510c03a43ff1..b2764b5b6ae0 100644 --- a/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py +++ b/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py @@ -12,49 +12,51 @@ raise ImportError(str(e) + "- required module not found") +GPIO_DIR = "/sys/class/gpio" +GPIO_LABEL = "pca9505" +DX010_MAX_PSUS = 2 + + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" def __init__(self): PsuBase.__init__(self) # DX010 PSU pin mapping - self.psu = [ - {'base': self.get_gpio_base()}, - {'abs':27, 'power':22}, - {'abs':28, 'power':25} + self.dx010_psu_gpio = [ + {'base': self.__get_gpio_base()}, + {'prs': 27, 'status': 22}, + {'prs': 28, 'status': 25} ] - def get_gpio_base(self): - sys_gpio_dir = "/sys/class/gpio" - for r in os.listdir(sys_gpio_dir): - if "gpiochip" in r: - return int(r[8:],10) - return 216 #Reserve - - - # Get a psu status and presence - def read_psu_statuses(self, pinnum): - sys_gpio_dir = "/sys/class/gpio" - gpio_base = self.psu[0]['base'] - - gpio_dir = sys_gpio_dir + '/gpio' + str(gpio_base+pinnum) - gpio_file = gpio_dir + "/value" - + def __read_txt_file(self, file_path): try: - with open(gpio_file, 'r') as fd: - retval = fd.read() + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() except IOError: - raise IOError("Unable to open " + gpio_file + "file !") - - retval = retval.rstrip('\r\n') - return retval + pass + return "" + + def __get_gpio_base(self): + for r in os.listdir(GPIO_DIR): + label_path = os.path.join(GPIO_DIR, r, "label") + if "gpiochip" in r and GPIO_LABEL in self.__read_txt_file(label_path): + return int(r[8:], 10) + return 216 # Reserve + + def __get_gpio_value(self, pinnum): + gpio_base = self.dx010_psu_gpio[0]['base'] + gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum) + gpio_file = gpio_dir + "/value" + retval = self.__read_txt_file(gpio_file) + return retval.rstrip('\r\n') def get_num_psus(self): """ Retrieves the number of PSUs available on the device :return: An integer, the number of PSUs available on the device """ - DX010_MAX_PSUS = 2 return DX010_MAX_PSUS def get_psu_status(self, index): @@ -65,14 +67,9 @@ def get_psu_status(self, index): :return: Boolean, True if PSU is operating properly, False if PSU is\ faulty """ - status = 0 - psu_status = self.read_psu_statuses(self.psu[index]['power']) - psu_status = int(psu_status, 10) - # Check for PSU status - if (psu_status == 1): - status = 1 - - return status + raw = self.__get_gpio_value( + self.dx010_psu_gpio[index]['status']) + return int(raw, 10) == 1 def get_psu_presence(self, index): """ @@ -81,11 +78,5 @@ def get_psu_presence(self, index): :param index: An integer, index of the PSU of which to query status :return: Boolean, True if PSU is plugged, False if not """ - status = 0 - psu_absence = self.read_psu_statuses(self.psu[index]['abs']) - psu_absence = (int(psu_absence, 10)) - # Check for PSU presence - if (psu_absence == 0): - status = 1 - - return status + raw = self.__get_gpio_value(self.dx010_psu_gpio[index]['prs']) + return int(raw, 10) == 0 From 9b8f5c9c9ad757f7504dc5e1afa95a4556655684 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Mon, 7 Oct 2019 07:49:25 -0700 Subject: [PATCH 0041/1427] [ntp]: Use loopback address when we don't have MGMT interface (#3566) Added configuration to use Loopback ip if a switch doesn't have MGMT_PORT. --- files/image_config/ntp/ntp.conf.j2 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index 1255369773f0..cef6527fc28f 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -27,12 +27,19 @@ filegen clockstats file clockstats type day enable server {{ ntp_server }} iburst {% endfor %} -#only listen on localhost and eth0 ips (default is to listen on all ip addresses) +#only listen on MGMT_INTERFACE, LOOPBACK_INTERFACE ip when MGMT_INTERFACE is not defined, or eth0 +# if we don't have both of them (default is to listen on all ip addresses) interface ignore wildcard {% if MGMT_INTERFACE %} {% for (mgmt_intf, mgmt_prefix) in MGMT_INTERFACE|pfx_filter %} interface listen {{ mgmt_prefix | ip }} {% endfor %} +{% elif LOOPBACK_INTERFACE %} +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name == 'Loopback0' %} +interface listen {{ prefix | ip }} +{% endif %} +{% endfor %} {% else %} interface listen eth0 {% endif %} From e69cb73fc77132c93d4df6e67d3a1791ac6a80a8 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Mon, 7 Oct 2019 16:05:07 -0700 Subject: [PATCH 0042/1427] [frr]: Implement BGP_MONITORS support (#3545) Implement support of BGP Monitors Add changes into minigraph to extract BGP Monitors information. Add new templates for FRR. --- dockers/docker-fpm-frr/bgpd.conf.default.j2 | 26 +++++++++++++++++++ src/sonic-config-engine/minigraph.py | 9 +++++-- .../tests/sample_output/bgpd_frr.conf | 14 ++++++++++ .../tests/simple-sample-graph.xml | 24 +++++++++++++++++ .../tests/t0-sample-graph.xml | 24 +++++++++++++++++ src/sonic-config-engine/tests/test_cfggen.py | 6 +++++ .../tests/test_minigraph_case.py | 6 +++++ 7 files changed, 107 insertions(+), 2 deletions(-) diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index 371f1fe3dd36..72779ac53d52 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -22,6 +22,12 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! +{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} +route-map FROM_BGPMON_V4 deny 10 +! +route-map TO_BGPMON_V4 permit 10 +! +{% endif %} router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -153,4 +159,24 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endfor %} {% endif %} {% endblock bgp_peers_with_range %} +{% block bgp_monitors %} +{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} + neighbor BGPMON_V4 peer-group +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name == 'Loopback0' %} + neighbor BGPMON_V4 update-source {{ prefix | ip }} +{% endif %} +{% endfor %} + neighbor BGPMON_V4 route-map FROM_BGPMON_V4 in + neighbor BGPMON_V4 route-map TO_BGPMON_V4 out + neighbor BGPMON_V4 send-community + neighbor BGPMON_V4 maximum-prefix 1 +{% for neighbor_addr, bgp_session in BGP_MONITORS.items() %} + neighbor {{ neighbor_addr }} remote-as {{ DEVICE_METADATA['localhost']['bgp_asn'] }} + neighbor {{ neighbor_addr }} peer-group BGPMON_V4 + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} + neighbor {{ neighbor_addr }} activate +{% endfor %} +{% endif %} +{% endblock bgp_monitors %} ! diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index bea5f31eeaa3..f64cbefafbd5 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -383,8 +383,11 @@ def parse_cpg(cpg, hname): bgp_session = bgp_sessions[peer] if hostname.lower() == bgp_session['name'].lower(): bgp_session['asn'] = asn + + bgp_monitors = { key: bgp_sessions[key] for key in bgp_sessions if bgp_sessions[key].has_key('asn') and bgp_sessions[key]['name'] == 'BGPMonitor' } bgp_sessions = { key: bgp_sessions[key] for key in bgp_sessions if bgp_sessions[key].has_key('asn') and int(bgp_sessions[key]['asn']) != 0 } - return bgp_sessions, myasn, bgp_peers_with_range + + return bgp_sessions, myasn, bgp_peers_with_range, bgp_monitors def parse_meta(meta, hname): @@ -516,6 +519,7 @@ def parse_xml(filename, platform=None, port_config_file=None): u_devices = None hwsku = None bgp_sessions = None + bgp_monitors = [] bgp_asn = None intfs = None vlan_intfs = None @@ -559,7 +563,7 @@ def parse_xml(filename, platform=None, port_config_file=None): if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): - (bgp_sessions, bgp_asn, bgp_peers_with_range) = parse_cpg(child, hostname) + (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): @@ -580,6 +584,7 @@ def parse_xml(filename, platform=None, port_config_file=None): 'type': current_device['type'] }} results['BGP_NEIGHBOR'] = bgp_sessions + results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range if mgmt_routes: # TODO: differentiate v4 and v6 diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf index b65cad324d27..c796ef8c164b 100644 --- a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf @@ -25,6 +25,10 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! +route-map FROM_BGPMON_V4 deny 10 +! +route-map TO_BGPMON_V4 permit 10 +! router bgp 65100 bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -114,6 +118,16 @@ router bgp 65100 neighbor fc00::76 route-map TO_BGP_PEER_V6 out maximum-paths 64 exit-address-family + neighbor BGPMON_V4 peer-group + neighbor BGPMON_V4 update-source 10.1.0.32 + neighbor BGPMON_V4 route-map FROM_BGPMON_V4 in + neighbor BGPMON_V4 route-map TO_BGPMON_V4 out + neighbor BGPMON_V4 send-community + neighbor BGPMON_V4 maximum-prefix 1 + neighbor 10.20.30.40 remote-as 65100 + neighbor 10.20.30.40 peer-group BGPMON_V4 + neighbor 10.20.30.40 description BGPMonitor + neighbor 10.20.30.40 activate !! maximum-paths 64 ! diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index e04f692729f0..5ebbaafd9671 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -2,6 +2,15 @@ + + switch-t0 + 10.1.0.32 + BGPMonitor + 10.20.30.40 + 30 + 10 + 3 + false switch-t0 @@ -42,6 +51,21 @@ + + 0 + + BGPMonitor + + + BGPPeer +

10.1.0.32
+ + + + + + + 65100 switch-t0 diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index bb1a4a4a22f6..180895928fbd 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -2,6 +2,15 @@ + + switch-t0 + 10.1.0.32 + BGPMonitor + 10.20.30.40 + 30 + 10 + 3 + false switch-t0 @@ -80,6 +89,21 @@ + + 0 + + BGPMonitor + + + BGPPeer +
10.1.0.32
+ + + +
+
+ +
65100 switch-t0 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index d6544dc063e4..fb85c54cfc90 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -260,3 +260,9 @@ def test_minigraph_vxlan(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VXLAN_TUNNEL"' output = self.run_script(argument) self.assertEqual(output.strip(), "") + + def test_minigraph_bgp_mon(self): + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "BGP_MONITORS"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") + diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 71d0c3d7db57..b77f0859584a 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -135,3 +135,9 @@ def test_minigraph_vxlan(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VXLAN_TUNNEL"' output = self.run_script(argument) self.assertEqual(output.strip(), "") + + def test_minigraph_bgp_mon(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "BGP_MONITORS"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{}") + From 9726f6c00312dd6d3ab4f5960a95a5017f1f139b Mon Sep 17 00:00:00 2001 From: "Sudharsan D.G" Date: Mon, 7 Oct 2019 16:35:22 -0700 Subject: [PATCH 0043/1427] [devices]: Adding pre-emphasis for s6000 (#3571) --- .../media_settings.json | 1348 +++++++++++++++++ 1 file changed, 1348 insertions(+) create mode 100644 device/dell/x86_64-dell_s6000_s1220-r0/media_settings.json diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/media_settings.json b/device/dell/x86_64-dell_s6000_s1220-r0/media_settings.json new file mode 100644 index 000000000000..9032a2e53b26 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/media_settings.json @@ -0,0 +1,1348 @@ +{ + "PORT_MEDIA_SETTINGS": { + "0": { + "Default": { + "preemphasis": { + "lane0":"0xcad0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xd2b0" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + } + }, + "1": { + "Default": { + "preemphasis": { + "lane0":"0xc2f0", + "lane1":"0xd2b0", + "lane2":"0xc6e0", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x6", + "lane1":"0x7", + "lane2":"0x6", + "lane3":"0x6" + }, + "ipredriver": { + "lane0":"0x6", + "lane1":"0x7", + "lane2":"0x6", + "lane3":"0x6" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x6", + "lane1":"0x7", + "lane2":"0x6", + "lane3":"0x6" + }, + "ipredriver": { + "lane0":"0x6", + "lane1":"0x7", + "lane2":"0x6", + "lane3":"0x6" + } + } + }, + "2": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "3": { + "Default": { + "preemphasis": { + "lane0":"0xcad0", + "lane1":"0xcad0", + "lane2":"0xc2f0", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "4": { + "Default": { + "preemphasis": { + "lane0":"0xc2f0", + "lane1":"0xc2f0", + "lane2":"0xc2f0", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "5": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc2f0", + "lane2":"0xc2f0", + "lane3":"0xcad0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "6": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xcad0", + "lane2":"0xc6e0", + "lane3":"0xcad0" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + } + }, + "7": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "8": { + "Default": { + "preemphasis": { + "lane0":"0xb270", + "lane1":"0xbb10", + "lane2":"0xb720", + "lane3":"0xb720" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x3", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x3", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xea05", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x3", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x3", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "9": { + "Default": { + "preemphasis": { + "lane0":"0xc2f0", + "lane1":"0xc6e0", + "lane2":"0xbf00", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x3", + "lane1":"0x3", + "lane2":"0x3", + "lane3":"0x3" + }, + "ipredriver": { + "lane0":"0x3", + "lane1":"0x3", + "lane2":"0x3", + "lane3":"0x3" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x3", + "lane1":"0x3", + "lane2":"0x3", + "lane3":"0x3" + }, + "ipredriver": { + "lane0":"0x3", + "lane1":"0x3", + "lane2":"0x3", + "lane3":"0x3" + } + } + }, + "10": { + "Default": { + "preemphasis": { + "lane0":"0xb330", + "lane1":"0xbb10", + "lane2":"0xbb10", + "lane3":"0xbb10" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "11": { + "Default": { + "preemphasis": { + "lane0":"0xb330", + "lane1":"0xb330", + "lane2":"0xb330", + "lane3":"0xb330" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "12": { + "Default": { + "preemphasis": { + "lane0":"0xaf40", + "lane1":"0xaf40", + "lane2":"0xaf40", + "lane3":"0xaf40" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "13": { + "Default": { + "preemphasis": { + "lane0":"0xa760", + "lane1":"0xa760", + "lane2":"0xa760", + "lane3":"0xa760" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "14": { + "Default": { + "preemphasis": { + "lane0":"0xa760", + "lane1":"0xa760", + "lane2":"0xa760", + "lane3":"0xa760" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + } + }, + "15": { + "Default": { + "preemphasis": { + "lane0":"0xa760", + "lane1":"0xa760", + "lane2":"0xa760", + "lane3":"0xa760" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "16": { + "Default": { + "preemphasis": { + "lane0":"0xa760", + "lane1":"0xa760", + "lane2":"0xa760", + "lane3":"0xa760" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + } + }, + "17": { + "Default": { + "preemphasis": { + "lane0":"0xa370", + "lane1":"0xa370", + "lane2":"0xa370", + "lane3":"0xa370" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0":"0xa760", + "lane1":"0xa760", + "lane2":"0xa760", + "lane3":"0xa760" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "19": { + "Default": { + "preemphasis": { + "lane0":"0xaf40", + "lane1":"0xaf40", + "lane2":"0xaf40", + "lane3":"0xaf40" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "20": { + "Default": { + "preemphasis": { + "lane0":"0xb330", + "lane1":"0xb330", + "lane2":"0xb330", + "lane3":"0xbff0" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x2" + } + } + }, + "21": { + "Default": { + "preemphasis": { + "lane0":"0xb330", + "lane1":"0xb330", + "lane2":"0xb330", + "lane3":"0xb330" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + } + }, + "22": { + "Default": { + "preemphasis": { + "lane0":"0xbb10", + "lane1":"0xbb10", + "lane2":"0xbb10", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + } + }, + "23": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x3", + "lane1":"0x5", + "lane2":"0x3", + "lane3":"0x3" + }, + "ipredriver": { + "lane0":"0x3", + "lane1":"0x5", + "lane2":"0x3", + "lane3":"0x3" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x3", + "lane1":"0x5", + "lane2":"0x3", + "lane3":"0x3" + }, + "ipredriver": { + "lane0":"0x3", + "lane1":"0x5", + "lane2":"0x3", + "lane3":"0x3" + } + } + }, + "24": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xcec0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "25": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6c0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "26": { + "Default": { + "preemphasis": { + "lane0":"0xbb10", + "lane1":"0xbb10", + "lane2":"0xbf00", + "lane3":"0xbb10" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0":"0xc2f0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x5", + "lane2":"0x4", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x5", + "lane2":"0x4", + "lane3":"0x5" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x5", + "lane2":"0x4", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x5", + "lane2":"0x4", + "lane3":"0x5" + } + } + }, + "28": { + "Default": { + "preemphasis": { + "lane0":"0xc2f0", + "lane1":"0xc2f0", + "lane2":"0xc2f0", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "29": { + "Default": { + "preemphasis": { + "lane0":"0xcad0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "30": { + "Default": { + "preemphasis": { + "lane0":"0xcec0", + "lane1":"0xcec0", + "lane2":"0xcad0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x6", + "lane1":"0x6", + "lane2":"0x6", + "lane3":"0x7" + }, + "ipredriver": { + "lane0":"0x6", + "lane1":"0x6", + "lane2":"0x6", + "lane3":"0x7" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x6", + "lane1":"0x6", + "lane2":"0x6", + "lane3":"0x7" + }, + "ipredriver": { + "lane0":"0x6", + "lane1":"0x6", + "lane2":"0x6", + "lane3":"0x7" + } + } + }, + "31": { + "Default": { + "preemphasis": { + "lane0":"0xcad0", + "lane1":"0xcad0", + "lane2":"0xcad0", + "lane3":"0xcad0" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + } + } + } +} From ce2ecf26805d7b7314393cd59823fb131df3e059 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 8 Oct 2019 07:30:27 -0700 Subject: [PATCH 0044/1427] [frr]: Update frr version to 7.1 (#3575) * Build 7.1 without patches * Port patches --- .gitmodules | 2 +- rules/frr.mk | 2 +- src/sonic-frr/Makefile | 4 +- src/sonic-frr/frr | 2 +- ...01-Add-support-of-bgp-tcp-DSCP-value.patch | 28 ++-- ...verity-of-Vty-connected-from-message.patch | 10 +- ...xthop-attribute-when-NLRI-is-present.patch | 156 ------------------ ...EXT_HOP-to-be-0.0.0.0-due-to-allevia.patch | 12 +- src/sonic-frr/patch/0005-Support-VRF.patch | 12 +- src/sonic-frr/patch/series | 1 - 10 files changed, 36 insertions(+), 193 deletions(-) delete mode 100644 src/sonic-frr/patch/0003-ignore-nexthop-attribute-when-NLRI-is-present.patch diff --git a/.gitmodules b/.gitmodules index 3d2a8e3f7a1d..d02ee6fb942b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -47,7 +47,7 @@ [submodule "src/sonic-frr/frr"] path = src/sonic-frr/frr url = https://github.com/Azure/sonic-frr.git - branch = frr/7.0 + branch = frr/7.1 [submodule "platform/p4/p4-hlir/p4-hlir-v1.1"] path = platform/p4/p4-hlir/p4-hlir-v1.1 url = https://github.com/p4lang/p4-hlir.git diff --git a/rules/frr.mk b/rules/frr.mk index a14d398f89a1..83c359992ac3 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -1,6 +1,6 @@ # FRRouting (frr) package -FRR_VERSION = 7.0.1 +FRR_VERSION = 7.1 FRR_SUBVERSION = 0 export FRR_VERSION FRR_SUBVERSION diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index e7c13a1f8b6f..4a31f23436ec 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -9,14 +9,14 @@ BRANCH = $(shell date +%Y%m%d\.%H%M%S) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Build the package pushd ./frr - git checkout -b $(BRANCH) origin/frr/7.0 + git checkout -b $(BRANCH) origin/frr/7.1 stg init stg import -s ../patch/series tools/tarsource.sh -V -e '-sonic' dpkg-buildpackage -rfakeroot -b -us -uc -Ppkg.frr.nortrlib -j$(SONIC_CONFIG_MAKE_JOBS) stg undo git clean -xfdf - git checkout frr/7.0 + git checkout frr/7.1 git branch -D $(BRANCH) popd mv $(DERIVED_TARGET) $* $(DEST)/ diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index cd305c0973be..8c5e037c4960 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit cd305c0973be0baa1173e09f9d72e096c03e7e7e +Subproject commit 8c5e037c496025597406f496010d6ef6b1d2e73d diff --git a/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch b/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch index e9f496d7af62..c7676fd65cb4 100644 --- a/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch +++ b/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch @@ -1,7 +1,7 @@ -From ef017a613691a40f32cdaa5396bbd4889b1cb647 Mon Sep 17 00:00:00 2001 +From ab8ae984def8ee5cea22f802b2a60a05214c11d2 Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Fri, 14 Jun 2019 17:45:31 -0700 -Subject: [PATCH] Add support of bgp tcp DSCP value +Date: Mon, 7 Oct 2019 17:00:15 -0700 +Subject: [PATCH 1/1] Add support of bgp tcp DSCP value --- bgpd/bgp_network.c | 11 ++++------- @@ -11,10 +11,10 @@ Subject: [PATCH] Add support of bgp tcp DSCP value 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c -index 4153da5a6..fed133eb7 100644 +index 6a5c2c4b3..9ec162aa4 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c -@@ -569,11 +569,9 @@ int bgp_connect(struct peer *peer) +@@ -627,11 +627,9 @@ int bgp_connect(struct peer *peer) #ifdef IPTOS_PREC_INTERNETCONTROL frr_elevate_privs(&bgpd_privs) { if (sockunion_family(&peer->su) == AF_INET) @@ -28,7 +28,7 @@ index 4153da5a6..fed133eb7 100644 } #endif -@@ -643,10 +641,9 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen, +@@ -707,10 +705,9 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen, #ifdef IPTOS_PREC_INTERNETCONTROL if (sa->sa_family == AF_INET) @@ -42,10 +42,10 @@ index 4153da5a6..fed133eb7 100644 sockopt_v6only(sa->sa_family, sock); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c -index 7445df883..f91b908a4 100644 +index d05432327..a15a0f526 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c -@@ -1113,6 +1113,42 @@ DEFUN (no_router_bgp, +@@ -1139,6 +1139,42 @@ DEFUN (no_router_bgp, return CMD_SUCCESS; } @@ -88,7 +88,7 @@ index 7445df883..f91b908a4 100644 /* BGP router-id. */ -@@ -12798,6 +12834,10 @@ void bgp_vty_init(void) +@@ -12929,6 +12965,10 @@ void bgp_vty_init(void) /* "no router bgp" commands. */ install_element(CONFIG_NODE, &no_router_bgp_cmd); @@ -100,10 +100,10 @@ index 7445df883..f91b908a4 100644 install_element(BGP_NODE, &bgp_router_id_cmd); install_element(BGP_NODE, &no_bgp_router_id_cmd); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c -index 6fb3a70c7..503e6b4ed 100644 +index 8c0b5336e..55aeb2dd8 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c -@@ -2995,7 +2995,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, +@@ -3040,7 +3040,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->evpn_info = XCALLOC(MTYPE_BGP_EVPN_INFO, sizeof(struct bgp_evpn_info)); @@ -112,7 +112,7 @@ index 6fb3a70c7..503e6b4ed 100644 bgp_evpn_init(bgp); bgp_pbr_init(bgp); return bgp; -@@ -7516,6 +7516,9 @@ int bgp_config_write(struct vty *vty) +@@ -7629,6 +7629,9 @@ int bgp_config_write(struct vty *vty) if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) vty_out(vty, " no bgp fast-external-failover\n"); @@ -123,10 +123,10 @@ index 6fb3a70c7..503e6b4ed 100644 if (bgp->router_id_static.s_addr != 0) vty_out(vty, " bgp router-id %s\n", diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h -index df3fde840..a6546457c 100644 +index b0f656753..32983a0a9 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h -@@ -553,6 +553,9 @@ struct bgp { +@@ -569,6 +569,9 @@ struct bgp { /* Count of peers in established state */ uint32_t established_peers; diff --git a/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch b/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch index ae2b3ba91223..9ec7b980ae84 100644 --- a/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch +++ b/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch @@ -1,17 +1,17 @@ -From 87760a6a04d6ffbcc7a1093549bfb76656002b61 Mon Sep 17 00:00:00 2001 +From 5a30a4e91a91f8e19c69ef219cd6d8b19e9b6fae Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Fri, 14 Jun 2019 17:48:50 -0700 -Subject: [PATCH] Reduce severity of 'Vty connected from' message +Date: Mon, 7 Oct 2019 17:06:27 -0700 +Subject: [PATCH 1/1] Reduce severity of 'Vty connected from' message --- lib/vty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vty.c b/lib/vty.c -index 8450922c2..f159d1b4b 100644 +index b1ed3d63c..5aa4b56cb 100644 --- a/lib/vty.c +++ b/lib/vty.c -@@ -1875,7 +1875,7 @@ static int vty_accept(struct thread *thread) +@@ -1870,7 +1870,7 @@ static int vty_accept(struct thread *thread) zlog_info("can't set sockopt to vty_sock : %s", safe_strerror(errno)); diff --git a/src/sonic-frr/patch/0003-ignore-nexthop-attribute-when-NLRI-is-present.patch b/src/sonic-frr/patch/0003-ignore-nexthop-attribute-when-NLRI-is-present.patch deleted file mode 100644 index 5d55ce547fd1..000000000000 --- a/src/sonic-frr/patch/0003-ignore-nexthop-attribute-when-NLRI-is-present.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 7c31178d8f1b8cc3a9627dc7c7bd1d2a51fe54ce Mon Sep 17 00:00:00 2001 -From: Pavel Shirshov -Date: Tue, 18 Jun 2019 15:27:19 -0700 -Subject: [PATCH] ignore nexthop attribute when NLRI is present - -Backport of https://github.com/FRRouting/frr/pull/4258 ---- - bgpd/bgp_attr.c | 73 ++++++++++++++++++++++++++++++----------------- - bgpd/bgp_attr.h | 3 ++ - bgpd/bgp_packet.c | 11 +++++++ - 3 files changed, 61 insertions(+), 26 deletions(-) - -diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c -index 05e103142..ea7f761ab 100644 ---- a/bgpd/bgp_attr.c -+++ b/bgpd/bgp_attr.c -@@ -1257,6 +1257,32 @@ static int bgp_attr_as4_path(struct bgp_attr_parser_args *args, - return BGP_ATTR_PARSE_PROCEED; - } - -+/* -+ * Check that the nexthop attribute is valid. -+ */ -+bgp_attr_parse_ret_t -+bgp_attr_nexthop_valid(struct peer *peer, struct attr *attr) -+{ -+ in_addr_t nexthop_h; -+ -+ nexthop_h = ntohl(attr->nexthop.s_addr); -+ if ((IPV4_NET0(nexthop_h) || IPV4_NET127(nexthop_h) -+ || IPV4_CLASS_DE(nexthop_h)) -+ && !BGP_DEBUG(allow_martians, ALLOW_MARTIANS)) { -+ char buf[INET_ADDRSTRLEN]; -+ -+ inet_ntop(AF_INET, &attr->nexthop.s_addr, buf, -+ INET_ADDRSTRLEN); -+ flog_err(EC_BGP_ATTR_MARTIAN_NH, "Martian nexthop %s", -+ buf); -+ bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, -+ BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP); -+ return BGP_ATTR_PARSE_ERROR; -+ } -+ -+ return BGP_ATTR_PARSE_PROCEED; -+} -+ - /* Nexthop attribute. */ - static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) - { -@@ -1264,8 +1290,6 @@ static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) - struct attr *const attr = args->attr; - const bgp_size_t length = args->length; - -- in_addr_t nexthop_h, nexthop_n; -- - /* Check nexthop attribute length. */ - if (length != 4) { - flog_err(EC_BGP_ATTR_LEN, -@@ -1275,30 +1299,7 @@ static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) - args->total); - } - -- /* According to section 6.3 of RFC4271, syntactically incorrect NEXT_HOP -- attribute must result in a NOTIFICATION message (this is implemented -- below). -- At the same time, semantically incorrect NEXT_HOP is more likely to -- be just -- logged locally (this is implemented somewhere else). The UPDATE -- message -- gets ignored in any of these cases. */ -- nexthop_n = stream_get_ipv4(peer->curr); -- nexthop_h = ntohl(nexthop_n); -- if ((IPV4_NET0(nexthop_h) || IPV4_NET127(nexthop_h) -- || IPV4_CLASS_DE(nexthop_h)) -- && !BGP_DEBUG( -- allow_martians, -- ALLOW_MARTIANS)) /* loopbacks may be used in testing */ -- { -- char buf[INET_ADDRSTRLEN]; -- inet_ntop(AF_INET, &nexthop_n, buf, INET_ADDRSTRLEN); -- flog_err(EC_BGP_ATTR_MARTIAN_NH, "Martian nexthop %s", buf); -- return bgp_attr_malformed( -- args, BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP, args->total); -- } -- -- attr->nexthop.s_addr = nexthop_n; -+ attr->nexthop.s_addr = stream_get_ipv4(peer->curr); - attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); - - return BGP_ATTR_PARSE_PROCEED; -@@ -2669,6 +2670,26 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, - return BGP_ATTR_PARSE_ERROR; - } - -+ /* -+ * RFC4271: If the NEXT_HOP attribute field is syntactically incorrect, -+ * then the Error Subcode MUST be set to Invalid NEXT_HOP Attribute. -+ * This is implemented below and will result in a NOTIFICATION. If the -+ * NEXT_HOP attribute is semantically incorrect, the error SHOULD be -+ * logged, and the route SHOULD be ignored. In this case, a NOTIFICATION -+ * message SHOULD NOT be sent. This is implemented elsewhere. -+ * -+ * RFC4760: An UPDATE message that carries no NLRI, other than the one -+ * encoded in the MP_REACH_NLRI attribute, SHOULD NOT carry the NEXT_HOP -+ * attribute. If such a message contains the NEXT_HOP attribute, the BGP -+ * speaker that receives the message SHOULD ignore this attribute. -+ */ -+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) -+ && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) { -+ if (bgp_attr_nexthop_valid(peer, attr) < 0) { -+ return BGP_ATTR_PARSE_ERROR; -+ } -+ } -+ - /* Check all mandatory well-known attributes are present */ - if ((ret = bgp_attr_check(peer, attr)) < 0) { - if (as4_path) -diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h -index 47a4182fe..a86684583 100644 ---- a/bgpd/bgp_attr.h -+++ b/bgpd/bgp_attr.h -@@ -350,6 +350,9 @@ extern void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p, - uint32_t, int, uint32_t, struct attr *); - extern void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt); - -+extern bgp_attr_parse_ret_t bgp_attr_nexthop_valid(struct peer *peer, -+ struct attr *attr); -+ - static inline int bgp_rmap_nhop_changed(uint32_t out_rmap_flags, - uint32_t in_rmap_flags) - { -diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c -index fe8a1a256..13f4cf436 100644 ---- a/bgpd/bgp_packet.c -+++ b/bgpd/bgp_packet.c -@@ -1533,6 +1533,17 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) - nlris[NLRI_UPDATE].nlri = stream_pnt(s); - nlris[NLRI_UPDATE].length = update_len; - stream_forward_getp(s, update_len); -+ -+ if (CHECK_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) { -+ /* -+ * We skipped nexthop attribute validation earlier so -+ * validate the nexthop now. -+ */ -+ if (bgp_attr_nexthop_valid(peer, &attr) < 0) { -+ bgp_attr_unintern_sub(&attr); -+ return BGP_Stop; -+ } -+ } - } - - if (BGP_DEBUG(update, UPDATE_IN)) --- -2.17.1.windows.2 - diff --git a/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch b/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch index 22cf08b82cd4..cb3c30c781d2 100644 --- a/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch +++ b/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch @@ -1,18 +1,18 @@ -From 4cd83e56e4f67fdc06325d92a82534fb4cb69952 Mon Sep 17 00:00:00 2001 +From 9fa0ffcc8f9ec987af527e911cd748014aeacffe Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Thu, 20 Jun 2019 15:35:50 -0700 -Subject: [PATCH] Allow BGP attr NEXT_HOP to be 0.0.0.0 due to alleviate the - vendor bug +Date: Mon, 7 Oct 2019 17:15:15 -0700 +Subject: [PATCH 1/1] Allow BGP attr NEXT_HOP to be 0.0.0.0 due to alleviate + the vendor bug --- bgpd/bgp_route.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c -index 38f3cad5a..55240eab8 100644 +index f8eae135e..732115756 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c -@@ -2873,8 +2873,7 @@ static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, +@@ -2904,8 +2904,7 @@ static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, /* If NEXT_HOP is present, validate it. */ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) { diff --git a/src/sonic-frr/patch/0005-Support-VRF.patch b/src/sonic-frr/patch/0005-Support-VRF.patch index c6de0e5ecf0e..8d6689e5240a 100644 --- a/src/sonic-frr/patch/0005-Support-VRF.patch +++ b/src/sonic-frr/patch/0005-Support-VRF.patch @@ -1,14 +1,14 @@ -From 81990d9aafdfd459c0caa6cf07501fa628ada454 Mon Sep 17 00:00:00 2001 -From: Tyler Li -Date: Mon, 3 Jun 2019 01:48:11 -0700 -Subject: [PATCH] Support VRF +From b7ae4e11c2dc14f9208b62ea060bb5ecbf4cddb2 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Mon, 7 Oct 2019 17:17:54 -0700 +Subject: [PATCH 1/1] Support VRF --- zebra/zebra_fpm_netlink.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c -index 207cbc099..b98c6886b 100644 +index 88f0c3250..29f07f801 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -327,7 +327,12 @@ static int netlink_route_info_encode(netlink_route_info_t *ri, char *in_buf, @@ -26,5 +26,5 @@ index 207cbc099..b98c6886b 100644 req->r.rtm_protocol = ri->rtm_protocol; req->r.rtm_scope = RT_SCOPE_UNIVERSE; -- -2.11.0 +2.17.1.windows.2 diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 4033e555fe7f..dc5eaa2fcd36 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -1,5 +1,4 @@ 0001-Add-support-of-bgp-tcp-DSCP-value.patch 0002-Reduce-severity-of-Vty-connected-from-message.patch -0003-ignore-nexthop-attribute-when-NLRI-is-present.patch 0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch 0005-Support-VRF.patch From aec24770602477102e737ea5fa8192e00a7d6961 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Tue, 8 Oct 2019 17:57:13 +0300 Subject: [PATCH 0045/1427] [mellanox] build SDK driver from open source (#3580) * build SDK driver package sx-kernel from open sourced repository Mellanox/Switch-SDK-driver * copy SDK packages and FW binaries from Mellanox/Switch-SDK-driver Signed-off-by: Stepan Blyschak --- .gitmodules | 3 +++ platform/mellanox/.gitignore | 1 + platform/mellanox/fw.mk | 22 ++++++++++++++++--- platform/mellanox/sdk-src/sx-kernel/Makefile | 12 +++++++--- .../sdk-src/sx-kernel/Switch-SDK-drivers | 1 + platform/mellanox/sdk.mk | 18 ++++++++------- 6 files changed, 43 insertions(+), 14 deletions(-) create mode 160000 platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers diff --git a/.gitmodules b/.gitmodules index d02ee6fb942b..08546d46073a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -66,3 +66,6 @@ [submodule "platform/mellanox/mlnx-sai/SAI-Implementation"] path = platform/mellanox/mlnx-sai/SAI-Implementation url = https://github.com/Mellanox/SAI-Implementation +[submodule "Switch-SDK-drivers"] + path = platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers + url = https://github.com/Mellanox/Switch-SDK-drivers diff --git a/platform/mellanox/.gitignore b/platform/mellanox/.gitignore index 74751518db24..1f3d15d640d4 100644 --- a/platform/mellanox/.gitignore +++ b/platform/mellanox/.gitignore @@ -8,6 +8,7 @@ mft/* !mft/Makefile sdk-src/*/* !sdk-src/*/Makefile +!sdk-src/sx-kernel/Switch-SDK-drivers/ !sdk-src/*/*.patch */build */deb_dist diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 6e9a285cc1ce..0ad1b05137ae 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -1,16 +1,32 @@ # mellanox firmware -MLNX_FW_BASE_URL = $(MLNX_SDK_BASE_URL) +MLNX_FW_BASE_PATH = $(MLNX_SDK_BASE_PATH) + +# Place an URL here to FW if you want to download FW instead +MLNX_FW_BASE_URL = + +ifneq ($(MLNX_FW_BASE_URL), ) +FW_FROM_URL = y +else +FW_FROM_URL = n +endif + MLNX_SPC_FW_VERSION = 13.2000.2162 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa +$(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -SONIC_ONLINE_FILES += $(MLNX_SPC_FW_FILE) MLNX_SPC2_FW_VERSION = 29.2000.2162 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa +$(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -SONIC_ONLINE_FILES += $(MLNX_SPC2_FW_FILE) + +ifeq ($(FW_FROM_URL),n) +SONIC_COPY_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) +else +SONIC_ONLINE_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) +endif export MLNX_SPC_FW_VERSION export MLNX_SPC_FW_FILE diff --git a/platform/mellanox/sdk-src/sx-kernel/Makefile b/platform/mellanox/sdk-src/sx-kernel/Makefile index 35ce9432a37c..9e979879fef8 100644 --- a/platform/mellanox/sdk-src/sx-kernel/Makefile +++ b/platform/mellanox/sdk-src/sx-kernel/Makefile @@ -7,12 +7,18 @@ PACKAGE_NAME = sx_kernel $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # get sources - rm -rf sx_kernel-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) - wget -c $(MLNX_SDK_SOURCE_BASE_URL)/$(PACKAGE_NAME)-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION).tar.gz -O - | tar -xz + if [ ! -z "$(MLNX_SDK_SOURCE_BASE_URL)" ]; then + rm -rf sx_kernel-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) + wget -c $(MLNX_SDK_SOURCE_BASE_URL)/$(PACKAGE_NAME)-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION).tar.gz -O - | tar -xz + pushd sx_kernel-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) + else + pushd Switch-SDK-drivers + git reset --hard + git clean -xfd + fi # build - pushd sx_kernel-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) patch -p1 < ../sx_kernel_makefile_sonic_build.patch debuild -e KVERSION=$(KVERSION) -e KSRC_EXT=/lib/modules/$(KVERSION)/source/ -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers new file mode 160000 index 000000000000..3acd88b3e04e --- /dev/null +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -0,0 +1 @@ +Subproject commit 3acd88b3e04ec09e5fb7e2b74ed94540a9fea21e diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 3cf3ee3ff976..779e072e3613 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,4 +1,4 @@ -MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/350187a41e408daaf03380401a0a2351b6cb0f9e/sdk +MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ MLNX_SDK_VERSION = 4.3.2104 MLNX_SDK_ISSU_VERSION = 101 @@ -135,19 +135,21 @@ $(SX_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel SX_KERNEL_DEV = sx-kernel-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(eval $(call add_derived_package,$(SX_KERNEL),$(SX_KERNEL_DEV))) -define make_url - $(1)_URL = $(MLNX_SDK_BASE_URL)/$(1) +define make_path + $(1)_PATH = $(MLNX_SDK_BASE_PATH) endef -$(eval $(foreach deb,$(MLNX_SDK_DEBS),$(call make_url,$(deb)))) -$(eval $(foreach deb,$(MLNX_SDK_RDEBS),$(call make_url,$(deb)))) -$(eval $(foreach deb,$(PYTHON_SDK_API) $(SX_KERNEL) $(SX_KERNEL_DEV),$(call make_url,$(deb)))) +$(eval $(foreach deb,$(MLNX_SDK_DEBS),$(call make_path,$(deb)))) +$(eval $(foreach deb,$(MLNX_SDK_RDEBS),$(call make_path,$(deb)))) +$(eval $(foreach deb,$(PYTHON_SDK_API) $(SX_KERNEL) $(SX_KERNEL_DEV),$(call make_path,$(deb)))) + +SONIC_MAKE_DEBS += $(SX_KERNEL) ifeq ($(SDK_FROM_SRC), y) -SONIC_MAKE_DEBS += $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) $(SX_KERNEL) +SONIC_MAKE_DEBS += $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) else -SONIC_ONLINE_DEBS += $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) $(SX_KERNEL) +SONIC_COPY_DEBS += $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) endif SONIC_STRETCH_DEBS += $(SX_KERNEL) From 350d2c5d2b5171e61ba1c1f96d3dfe7c0039a496 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 9 Oct 2019 00:26:35 +0800 Subject: [PATCH 0046/1427] [chassis.py] Fix issue in get_change_event: the returned dictionary doesn't contain 'sfp' key. (#3568) --- platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 814c7aca8178..02d898822817 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -523,4 +523,4 @@ def get_change_event(self, timeout=0): i = i + 1 return True, {'sfp':port_dict} else: - return True, {} + return True, {'sfp':{}} From 28c358b4915177dbd6de4bc21e8e9757d08be0a3 Mon Sep 17 00:00:00 2001 From: byu343 Date: Tue, 8 Oct 2019 12:05:24 -0700 Subject: [PATCH 0047/1427] Add hwSku Arista-7280CR3-C28S8 (#3574) --- ...jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm | 737 ++++++++++++++++++ .../Arista-7280CR3-C28S8/port_config.ini | 37 + .../Arista-7280CR3-C28S8/sai.profile | 1 + 3 files changed, 775 insertions(+) create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/port_config.ini create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm new file mode 100644 index 000000000000..3c0a0ee443a4 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm @@ -0,0 +1,737 @@ +soc_family.BCM8869X=BCM8869X + +custom_feature_ucode_path=u_code_db2pem.txt +system_headers_mode=1 +suppress_unknown_prop_warnings=1 +l4_protocols_load_balancing_enable=1 +fabric_logical_port_base=512 +trunk_group_max_members=128 +num_olp_tm_ports.BCM8869X=1 + +ucode_port_0.BCM8869X=CPU.0:core_0.0 +ucode_port_200.BCM8869X=CPU.8:core_1.200 +ucode_port_201.BCM8869X=CPU.16:core_0.201 +ucode_port_202.BCM8869X=CPU.24:core_1.202 +ucode_port_203.BCM8869X=CPU.32:core_0.203 + +port_init_speed_xe.BCM8869X=10000 +port_init_speed_xl.BCM8869X=40000 +port_init_speed_le.BCM8869X=50000 +port_init_speed_ce.BCM8869X=100000 +port_init_speed_cc.BCM8869X=200000 +port_init_speed_cd.BCM8869X=400000 +port_init_speed_il.BCM8869X=10312 + +port_init_cl72=0 + +serdes_tx_taps_1=pam4:-16:64:0:3:0:0 +serdes_tx_taps_2=pam4:-16:64:0:3:0:0 +serdes_tx_taps_3=pam4:-16:64:0:3:0:0 +serdes_tx_taps_4=pam4:-16:64:0:3:0:0 +serdes_tx_taps_5=pam4:-16:64:0:3:0:0 +serdes_tx_taps_6=pam4:-16:64:0:3:0:0 +serdes_tx_taps_7=pam4:-16:64:0:3:0:0 +serdes_tx_taps_8=pam4:-16:64:0:3:0:0 +serdes_tx_taps_9=pam4:-8:60:0:0:0:0 +serdes_tx_taps_10=pam4:-8:60:0:0:0:0 +serdes_tx_taps_11=pam4:-8:60:0:0:0:0 +serdes_tx_taps_12=pam4:-8:60:0:0:0:0 +serdes_tx_taps_13=pam4:-8:60:0:0:0:0 +serdes_tx_taps_14=pam4:-8:60:0:0:0:0 +serdes_tx_taps_15=pam4:-8:60:0:0:0:0 +serdes_tx_taps_16=pam4:-8:60:0:0:0:0 +serdes_tx_taps_17=pam4:-8:60:0:0:0:0 +serdes_tx_taps_18=pam4:-8:60:0:0:0:0 +serdes_tx_taps_19=pam4:-8:60:0:0:0:0 +serdes_tx_taps_20=pam4:-8:60:0:0:0:0 +serdes_tx_taps_21=pam4:-8:60:0:0:0:0 +serdes_tx_taps_22=pam4:-8:60:0:0:0:0 +serdes_tx_taps_23=pam4:-8:60:0:0:0:0 +serdes_tx_taps_24=pam4:-8:60:0:0:0:0 +serdes_tx_taps_25=pam4:-8:60:0:0:0:0 +serdes_tx_taps_26=pam4:-8:60:0:0:0:0 +serdes_tx_taps_27=pam4:-8:60:0:0:0:0 +serdes_tx_taps_28=pam4:-8:60:0:0:0:0 +serdes_tx_taps_29=nrz:0:127:0:0:0:0 +serdes_tx_taps_30=nrz:0:127:0:0:0:0 +serdes_tx_taps_31=nrz:0:127:0:0:0:0 +serdes_tx_taps_32=nrz:0:127:0:0:0:0 +serdes_tx_taps_33=nrz:0:127:0:0:0:0 +serdes_tx_taps_34=nrz:0:127:0:0:0:0 +serdes_tx_taps_35=nrz:0:127:0:0:0:0 +serdes_tx_taps_36=nrz:0:127:0:0:0:0 + +ucode_port_100.BCM8869X=RCY_MIRROR.0:core_0.100 +ucode_port_101.BCM8869X=RCY_MIRROR.1:core_0.101 +ucode_port_102.BCM8869X=RCY_MIRROR.2:core_0.102 +ucode_port_103.BCM8869X=RCY_MIRROR.3:core_0.103 +ucode_port_104.BCM8869X=RCY_MIRROR.4:core_0.104 +ucode_port_105.BCM8869X=RCY_MIRROR.5:core_0.105 +ucode_port_106.BCM8869X=RCY_MIRROR.6:core_0.106 +ucode_port_107.BCM8869X=RCY_MIRROR.7:core_0.107 +ucode_port_108.BCM8869X=RCY_MIRROR.8:core_0.108 +ucode_port_109.BCM8869X=RCY_MIRROR.9:core_0.109 +ucode_port_110.BCM8869X=RCY_MIRROR.10:core_0.110 +ucode_port_111.BCM8869X=RCY_MIRROR.11:core_0.111 +ucode_port_112.BCM8869X=RCY_MIRROR.12:core_0.112 +ucode_port_113.BCM8869X=RCY_MIRROR.13:core_0.113 +ucode_port_114.BCM8869X=RCY_MIRROR.14:core_0.114 +ucode_port_115.BCM8869X=RCY_MIRROR.15:core_0.115 +ucode_port_116.BCM8869X=RCY_MIRROR.16:core_0.116 +ucode_port_117.BCM8869X=RCY_MIRROR.17:core_0.117 +ucode_port_118.BCM8869X=RCY_MIRROR.18:core_0.118 +ucode_port_119.BCM8869X=RCY_MIRROR.19:core_0.119 +ucode_port_120.BCM8869X=RCY_MIRROR.0:core_1.120 +ucode_port_121.BCM8869X=RCY_MIRROR.1:core_1.121 +ucode_port_122.BCM8869X=RCY_MIRROR.2:core_1.122 +ucode_port_123.BCM8869X=RCY_MIRROR.3:core_1.123 +ucode_port_124.BCM8869X=RCY_MIRROR.4:core_1.124 +ucode_port_125.BCM8869X=RCY_MIRROR.5:core_1.125 +ucode_port_126.BCM8869X=RCY_MIRROR.6:core_1.126 +ucode_port_127.BCM8869X=RCY_MIRROR.7:core_1.127 +ucode_port_128.BCM8869X=RCY_MIRROR.8:core_1.128 +ucode_port_129.BCM8869X=RCY_MIRROR.9:core_1.129 +ucode_port_130.BCM8869X=RCY_MIRROR.10:core_1.130 +ucode_port_131.BCM8869X=RCY_MIRROR.11:core_1.131 +ucode_port_132.BCM8869X=RCY_MIRROR.12:core_1.132 +ucode_port_133.BCM8869X=RCY_MIRROR.13:core_1.133 +ucode_port_134.BCM8869X=RCY_MIRROR.14:core_1.134 +ucode_port_135.BCM8869X=RCY_MIRROR.15:core_1.135 +ucode_port_136.BCM8869X=RCY_MIRROR.16:core_1.136 +ucode_port_137.BCM8869X=RCY_MIRROR.17:core_1.137 +ucode_port_138.BCM8869X=RCY_MIRROR.18:core_1.138 +ucode_port_139.BCM8869X=RCY_MIRROR.19:core_1.139 + +port_priorities.BCM8869X=8 + +ucode_port_240.BCM8869X=OLP:core_0.240 + +sw_state_max_size.BCM8869X=750000000 + +stable_location.BCM8869X=4 +stable_location.BCM8869X_ADAPTER=3 + +stable_filename.BCM8869X_ADAPTER=warmboot_data_0 +stable_filename=/dev/shm/warmboot_data_0 +stable_filename.1=/dev/shm/warmboot_data_1 +stable_filename.2=/dev/shm/warmboot_data_2 + +stable_size.BCM8869X=800000000 + +tm_port_header_type_in_0.BCM8869X=INJECTED_2 +tm_port_header_type_out_0.BCM8869X=CPU + +tm_port_header_type_in_200.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_200.BCM8869X=ETH +tm_port_header_type_in_201.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_201.BCM8869X=ETH +tm_port_header_type_in_202.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_202.BCM8869X=ETH +tm_port_header_type_in_203.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_203.BCM8869X=ETH + +sat_enable.BCM8869X=1 +tm_port_header_type_out_218.BCM8869X=CPU +tm_port_header_type_in_218.BCM8869X=INJECTED_2 + +tm_port_header_type_in_232.BCM8869X=INJECTED_2 +tm_port_header_type_out_232.BCM8869X=CPU +tm_port_header_type_in_233.BCM8869X=INJECTED_2 +tm_port_header_type_out_233.BCM8869X=CPU + +tm_port_header_type_in_240.BCM8869X=INJECTED_2 +tm_port_header_type_out_240.BCM8869X=RAW + +dtm_flow_mapping_mode_region_64.BCM8869X=3 +dtm_flow_mapping_mode_region_65.BCM8869X=3 +dtm_flow_mapping_mode_region_66.BCM8869X=3 +dtm_flow_mapping_mode_region_67.BCM8869X=3 +dtm_flow_mapping_mode_region_68.BCM8869X=3 +dtm_flow_mapping_mode_region_69.BCM8869X=3 +dtm_flow_mapping_mode_region_70.BCM8869X=3 +dtm_flow_mapping_mode_region_71.BCM8869X=3 +dtm_flow_mapping_mode_region_72.BCM8869X=3 +dtm_flow_mapping_mode_region_73.BCM8869X=3 +dtm_flow_mapping_mode_region_74.BCM8869X=3 +dtm_flow_mapping_mode_region_75.BCM8869X=3 +dtm_flow_mapping_mode_region_76.BCM8869X=3 +dtm_flow_mapping_mode_region_77.BCM8869X=3 +dtm_flow_mapping_mode_region_78.BCM8869X=3 +dtm_flow_mapping_mode_region_79.BCM8869X=7 +dtm_flow_mapping_mode_region_80.BCM8869X=3 +dtm_flow_mapping_mode_region_81.BCM8869X=1 +dtm_flow_mapping_mode_region_82.BCM8869X=3 +dtm_flow_mapping_mode_region_83.BCM8869X=3 +dtm_flow_mapping_mode_region_84.BCM8869X=3 +dtm_flow_mapping_mode_region_85.BCM8869X=3 +dtm_flow_mapping_mode_region_86.BCM8869X=3 +dtm_flow_mapping_mode_region_87.BCM8869X=3 +dtm_flow_mapping_mode_region_88.BCM8869X=3 +dtm_flow_mapping_mode_region_89.BCM8869X=3 +dtm_flow_mapping_mode_region_90.BCM8869X=3 +dtm_flow_mapping_mode_region_91.BCM8869X=3 +dtm_flow_mapping_mode_region_92.BCM8869X=3 +dtm_flow_mapping_mode_region_93.BCM8869X=3 +dtm_flow_mapping_mode_region_94.BCM8869X=3 + +dtm_flow_nof_remote_cores_region_1.BCM8869X=2 +dtm_flow_nof_remote_cores_region_2.BCM8869X=2 +dtm_flow_nof_remote_cores_region_3.BCM8869X=2 +dtm_flow_nof_remote_cores_region_4.BCM8869X=2 +dtm_flow_nof_remote_cores_region_5.BCM8869X=2 +dtm_flow_nof_remote_cores_region_6.BCM8869X=2 +dtm_flow_nof_remote_cores_region_7.BCM8869X=2 +dtm_flow_nof_remote_cores_region_8.BCM8869X=2 +dtm_flow_nof_remote_cores_region_9.BCM8869X=2 +dtm_flow_nof_remote_cores_region_10.BCM8869X=2 +dtm_flow_nof_remote_cores_region_11.BCM8869X=2 +dtm_flow_nof_remote_cores_region_12.BCM8869X=2 +dtm_flow_nof_remote_cores_region_13.BCM8869X=2 +dtm_flow_nof_remote_cores_region_14.BCM8869X=2 +dtm_flow_nof_remote_cores_region_15.BCM8869X=2 +dtm_flow_nof_remote_cores_region_16.BCM8869X=2 +dtm_flow_nof_remote_cores_region_17.BCM8869X=2 +dtm_flow_nof_remote_cores_region_18.BCM8869X=2 +dtm_flow_nof_remote_cores_region_19.BCM8869X=2 +dtm_flow_nof_remote_cores_region_20.BCM8869X=2 +dtm_flow_nof_remote_cores_region_21.BCM8869X=2 +dtm_flow_nof_remote_cores_region_22.BCM8869X=2 +dtm_flow_nof_remote_cores_region_23.BCM8869X=2 +dtm_flow_nof_remote_cores_region_24.BCM8869X=2 +dtm_flow_nof_remote_cores_region_25.BCM8869X=2 +dtm_flow_nof_remote_cores_region_26.BCM8869X=2 +dtm_flow_nof_remote_cores_region_27.BCM8869X=2 +dtm_flow_nof_remote_cores_region_28.BCM8869X=2 +dtm_flow_nof_remote_cores_region_29.BCM8869X=2 +dtm_flow_nof_remote_cores_region_30.BCM8869X=2 +dtm_flow_nof_remote_cores_region_31.BCM8869X=2 +dtm_flow_nof_remote_cores_region_32.BCM8869X=2 +dtm_flow_nof_remote_cores_region_33.BCM8869X=2 +dtm_flow_nof_remote_cores_region_34.BCM8869X=2 +dtm_flow_nof_remote_cores_region_35.BCM8869X=2 +dtm_flow_nof_remote_cores_region_36.BCM8869X=2 +dtm_flow_nof_remote_cores_region_37.BCM8869X=2 +dtm_flow_nof_remote_cores_region_38.BCM8869X=2 +dtm_flow_nof_remote_cores_region_39.BCM8869X=2 +dtm_flow_nof_remote_cores_region_40.BCM8869X=2 +dtm_flow_nof_remote_cores_region_41.BCM8869X=2 +dtm_flow_nof_remote_cores_region_42.BCM8869X=2 +dtm_flow_nof_remote_cores_region_43.BCM8869X=2 +dtm_flow_nof_remote_cores_region_44.BCM8869X=2 +dtm_flow_nof_remote_cores_region_45.BCM8869X=2 +dtm_flow_nof_remote_cores_region_46.BCM8869X=2 +dtm_flow_nof_remote_cores_region_47.BCM8869X=2 +dtm_flow_nof_remote_cores_region_48.BCM8869X=2 +dtm_flow_nof_remote_cores_region_49.BCM8869X=2 +dtm_flow_nof_remote_cores_region_50.BCM8869X=2 +dtm_flow_nof_remote_cores_region_51.BCM8869X=2 +dtm_flow_nof_remote_cores_region_52.BCM8869X=2 +dtm_flow_nof_remote_cores_region_53.BCM8869X=2 +dtm_flow_nof_remote_cores_region_54.BCM8869X=2 +dtm_flow_nof_remote_cores_region_55.BCM8869X=2 +dtm_flow_nof_remote_cores_region_56.BCM8869X=2 +dtm_flow_nof_remote_cores_region_57.BCM8869X=2 +dtm_flow_nof_remote_cores_region_58.BCM8869X=2 +dtm_flow_nof_remote_cores_region_59.BCM8869X=2 +dtm_flow_nof_remote_cores_region_60.BCM8869X=2 + +mdb_profile.BCM8869X=l3-xl + +outlif_logical_to_physical_phase_map_1=S1 +outlif_logical_to_physical_phase_map_2=L1 +outlif_logical_to_physical_phase_map_3=XL +outlif_logical_to_physical_phase_map_4=L2 +outlif_logical_to_physical_phase_map_5=M1 +outlif_logical_to_physical_phase_map_6=M2 +outlif_logical_to_physical_phase_map_7=M3 +outlif_logical_to_physical_phase_map_8=S2 + +outlif_physical_phase_data_granularity_S1=60 +outlif_physical_phase_data_granularity_S2=60 +outlif_physical_phase_data_granularity_M1=60 +outlif_physical_phase_data_granularity_M2=60 +outlif_physical_phase_data_granularity_M3=60 +outlif_physical_phase_data_granularity_L1=60 +outlif_physical_phase_data_granularity_L2=60 +outlif_physical_phase_data_granularity_XL=60 + +port_init_speed_fabric.BCM8869X=53125 + +fabric_connect_mode.BCM8869X=SINGLE_FAP +protocol_traps_mode.BCM8869X=IN_LIF + +schan_intr_enable.BCM8869X=0 +tdma_intr_enable.BCM8869X=0 +tslam_intr_enable.BCM8869X=0 +miim_intr_enable.BCM8869X=0 +schan_timeout_usec.BCM8869X=300000 +tdma_timeout_usec.BCM8869X=1000000 +tslam_timeout_usec.BCM8869X=1000000 + +appl_enable_intr_init.BCM8869X=1 +polled_irq_mode.BCM8869X=1 +polled_irq_delay.BCM8869X=1000 + +bcm_stat_interval.BCM8869X=1000 + +mem_cache_enable_ecc.BCM8869X=1 +mem_cache_enable_parity.BCM8869X=1 + +serdes_nif_clk_freq_in.BCM8869X=2 +serdes_nif_clk_freq_out.BCM8869X=1 + +serdes_fabric_clk_freq_in.BCM8869X=2 +serdes_fabric_clk_freq_out.BCM8869X=1 + +dram_phy_tune_mode_on_init.BCM8869X=RUN_TUNE + +dport_map_direct.BCM8869X=1 + +pmf_sexem3_stage.BCM8869X=IPMF3 + +lane_to_serdes_map_fabric_lane0.0=rx0:tx0 +lane_to_serdes_map_fabric_lane1.0=rx1:tx1 +lane_to_serdes_map_fabric_lane2.0=rx2:tx2 +lane_to_serdes_map_fabric_lane3.0=rx3:tx3 +lane_to_serdes_map_fabric_lane4.0=rx4:tx4 +lane_to_serdes_map_fabric_lane5.0=rx5:tx5 +lane_to_serdes_map_fabric_lane6.0=rx6:tx6 +lane_to_serdes_map_fabric_lane7.0=rx7:tx7 +lane_to_serdes_map_fabric_lane8.0=rx8:tx8 +lane_to_serdes_map_fabric_lane9.0=rx9:tx9 +lane_to_serdes_map_fabric_lane10.0=rx10:tx10 +lane_to_serdes_map_fabric_lane11.0=rx11:tx11 +lane_to_serdes_map_fabric_lane12.0=rx12:tx12 +lane_to_serdes_map_fabric_lane13.0=rx13:tx13 +lane_to_serdes_map_fabric_lane14.0=rx14:tx14 +lane_to_serdes_map_fabric_lane15.0=rx15:tx15 +lane_to_serdes_map_fabric_lane16.0=rx16:tx16 +lane_to_serdes_map_fabric_lane17.0=rx17:tx17 +lane_to_serdes_map_fabric_lane18.0=rx18:tx18 +lane_to_serdes_map_fabric_lane19.0=rx19:tx19 +lane_to_serdes_map_fabric_lane20.0=rx20:tx20 +lane_to_serdes_map_fabric_lane21.0=rx21:tx21 +lane_to_serdes_map_fabric_lane22.0=rx22:tx22 +lane_to_serdes_map_fabric_lane23.0=rx23:tx23 +lane_to_serdes_map_fabric_lane24.0=rx24:tx24 +lane_to_serdes_map_fabric_lane25.0=rx25:tx25 +lane_to_serdes_map_fabric_lane26.0=rx26:tx26 +lane_to_serdes_map_fabric_lane27.0=rx27:tx27 +lane_to_serdes_map_fabric_lane28.0=rx28:tx28 +lane_to_serdes_map_fabric_lane29.0=rx29:tx29 +lane_to_serdes_map_fabric_lane30.0=rx30:tx30 +lane_to_serdes_map_fabric_lane31.0=rx31:tx31 +lane_to_serdes_map_fabric_lane32.0=rx32:tx32 +lane_to_serdes_map_fabric_lane33.0=rx33:tx33 +lane_to_serdes_map_fabric_lane34.0=rx34:tx34 +lane_to_serdes_map_fabric_lane35.0=rx35:tx35 +lane_to_serdes_map_fabric_lane36.0=rx36:tx36 +lane_to_serdes_map_fabric_lane37.0=rx37:tx37 +lane_to_serdes_map_fabric_lane38.0=rx38:tx38 +lane_to_serdes_map_fabric_lane39.0=rx39:tx39 +lane_to_serdes_map_fabric_lane40.0=rx40:tx40 +lane_to_serdes_map_fabric_lane41.0=rx41:tx41 +lane_to_serdes_map_fabric_lane42.0=rx42:tx42 +lane_to_serdes_map_fabric_lane43.0=rx43:tx43 +lane_to_serdes_map_fabric_lane44.0=rx44:tx44 +lane_to_serdes_map_fabric_lane45.0=rx45:tx45 +lane_to_serdes_map_fabric_lane46.0=rx46:tx46 +lane_to_serdes_map_fabric_lane47.0=rx47:tx47 +lane_to_serdes_map_fabric_lane48.0=rx48:tx48 +lane_to_serdes_map_fabric_lane49.0=rx49:tx49 +lane_to_serdes_map_fabric_lane50.0=rx50:tx50 +lane_to_serdes_map_fabric_lane51.0=rx51:tx51 +lane_to_serdes_map_fabric_lane52.0=rx52:tx52 +lane_to_serdes_map_fabric_lane53.0=rx53:tx53 +lane_to_serdes_map_fabric_lane54.0=rx54:tx54 +lane_to_serdes_map_fabric_lane55.0=rx55:tx55 +lane_to_serdes_map_fabric_lane56.0=rx56:tx56 +lane_to_serdes_map_fabric_lane57.0=rx57:tx57 +lane_to_serdes_map_fabric_lane58.0=rx58:tx58 +lane_to_serdes_map_fabric_lane59.0=rx59:tx59 +lane_to_serdes_map_fabric_lane60.0=rx60:tx60 +lane_to_serdes_map_fabric_lane61.0=rx61:tx61 +lane_to_serdes_map_fabric_lane62.0=rx62:tx62 +lane_to_serdes_map_fabric_lane63.0=rx63:tx63 +lane_to_serdes_map_fabric_lane64.0=rx64:tx64 +lane_to_serdes_map_fabric_lane65.0=rx65:tx65 +lane_to_serdes_map_fabric_lane66.0=rx66:tx66 +lane_to_serdes_map_fabric_lane67.0=rx67:tx67 +lane_to_serdes_map_fabric_lane68.0=rx68:tx68 +lane_to_serdes_map_fabric_lane69.0=rx69:tx69 +lane_to_serdes_map_fabric_lane70.0=rx70:tx70 +lane_to_serdes_map_fabric_lane71.0=rx71:tx71 +lane_to_serdes_map_fabric_lane72.0=rx72:tx72 +lane_to_serdes_map_fabric_lane73.0=rx73:tx73 +lane_to_serdes_map_fabric_lane74.0=rx74:tx74 +lane_to_serdes_map_fabric_lane75.0=rx75:tx75 +lane_to_serdes_map_fabric_lane76.0=rx76:tx76 +lane_to_serdes_map_fabric_lane77.0=rx77:tx77 +lane_to_serdes_map_fabric_lane78.0=rx78:tx78 +lane_to_serdes_map_fabric_lane79.0=rx79:tx79 +lane_to_serdes_map_fabric_lane80.0=rx80:tx80 +lane_to_serdes_map_fabric_lane81.0=rx81:tx81 +lane_to_serdes_map_fabric_lane82.0=rx82:tx82 +lane_to_serdes_map_fabric_lane83.0=rx83:tx83 +lane_to_serdes_map_fabric_lane84.0=rx84:tx84 +lane_to_serdes_map_fabric_lane85.0=rx85:tx85 +lane_to_serdes_map_fabric_lane86.0=rx86:tx86 +lane_to_serdes_map_fabric_lane87.0=rx87:tx87 +lane_to_serdes_map_fabric_lane88.0=rx88:tx88 +lane_to_serdes_map_fabric_lane89.0=rx89:tx89 +lane_to_serdes_map_fabric_lane90.0=rx90:tx90 +lane_to_serdes_map_fabric_lane91.0=rx91:tx91 +lane_to_serdes_map_fabric_lane92.0=rx92:tx92 +lane_to_serdes_map_fabric_lane93.0=rx93:tx93 +lane_to_serdes_map_fabric_lane94.0=rx94:tx94 +lane_to_serdes_map_fabric_lane95.0=rx95:tx95 +lane_to_serdes_map_fabric_lane96.0=rx96:tx96 +lane_to_serdes_map_fabric_lane97.0=rx97:tx97 +lane_to_serdes_map_fabric_lane98.0=rx98:tx98 +lane_to_serdes_map_fabric_lane99.0=rx99:tx99 +lane_to_serdes_map_fabric_lane100.0=rx100:tx100 +lane_to_serdes_map_fabric_lane101.0=rx101:tx101 +lane_to_serdes_map_fabric_lane102.0=rx102:tx102 +lane_to_serdes_map_fabric_lane103.0=rx103:tx103 +lane_to_serdes_map_fabric_lane104.0=rx104:tx104 +lane_to_serdes_map_fabric_lane105.0=rx105:tx105 +lane_to_serdes_map_fabric_lane106.0=rx106:tx106 +lane_to_serdes_map_fabric_lane107.0=rx107:tx107 +lane_to_serdes_map_fabric_lane108.0=rx108:tx108 +lane_to_serdes_map_fabric_lane109.0=rx109:tx109 +lane_to_serdes_map_fabric_lane110.0=rx110:tx110 +lane_to_serdes_map_fabric_lane111.0=rx111:tx111 + +lane_to_serdes_map_nif_lane0.0=rx5:tx7 +lane_to_serdes_map_nif_lane1.0=rx7:tx6 +lane_to_serdes_map_nif_lane2.0=rx4:tx5 +lane_to_serdes_map_nif_lane3.0=rx6:tx4 +lane_to_serdes_map_nif_lane4.0=rx0:tx0 +lane_to_serdes_map_nif_lane5.0=rx1:tx1 +lane_to_serdes_map_nif_lane6.0=rx2:tx3 +lane_to_serdes_map_nif_lane7.0=rx3:tx2 +lane_to_serdes_map_nif_lane8.0=rx13:tx15 +lane_to_serdes_map_nif_lane9.0=rx12:tx14 +lane_to_serdes_map_nif_lane10.0=rx15:tx13 +lane_to_serdes_map_nif_lane11.0=rx14:tx12 +lane_to_serdes_map_nif_lane12.0=rx10:tx10 +lane_to_serdes_map_nif_lane13.0=rx8:tx9 +lane_to_serdes_map_nif_lane14.0=rx9:tx11 +lane_to_serdes_map_nif_lane15.0=rx11:tx8 +lane_to_serdes_map_nif_lane16.0=rx23:tx23 +lane_to_serdes_map_nif_lane17.0=rx21:tx22 +lane_to_serdes_map_nif_lane18.0=rx22:tx21 +lane_to_serdes_map_nif_lane19.0=rx20:tx20 +lane_to_serdes_map_nif_lane20.0=rx16:tx18 +lane_to_serdes_map_nif_lane21.0=rx17:tx17 +lane_to_serdes_map_nif_lane22.0=rx18:tx16 +lane_to_serdes_map_nif_lane23.0=rx19:tx19 +lane_to_serdes_map_nif_lane24.0=rx31:tx31 +lane_to_serdes_map_nif_lane25.0=rx30:tx30 +lane_to_serdes_map_nif_lane26.0=rx29:tx29 +lane_to_serdes_map_nif_lane27.0=rx28:tx28 +lane_to_serdes_map_nif_lane28.0=rx24:tx26 +lane_to_serdes_map_nif_lane29.0=rx26:tx25 +lane_to_serdes_map_nif_lane30.0=rx25:tx24 +lane_to_serdes_map_nif_lane31.0=rx27:tx27 +lane_to_serdes_map_nif_lane32.0=rx39:tx35 +lane_to_serdes_map_nif_lane33.0=rx38:tx36 +lane_to_serdes_map_nif_lane34.0=rx32:tx32 +lane_to_serdes_map_nif_lane35.0=rx37:tx37 +lane_to_serdes_map_nif_lane36.0=rx33:tx34 +lane_to_serdes_map_nif_lane37.0=rx34:tx38 +lane_to_serdes_map_nif_lane38.0=rx35:tx33 +lane_to_serdes_map_nif_lane39.0=rx36:tx39 +lane_to_serdes_map_nif_lane40.0=rx44:tx47 +lane_to_serdes_map_nif_lane41.0=rx43:tx41 +lane_to_serdes_map_nif_lane42.0=rx47:tx46 +lane_to_serdes_map_nif_lane43.0=rx42:tx42 +lane_to_serdes_map_nif_lane44.0=rx45:tx45 +lane_to_serdes_map_nif_lane45.0=rx41:tx40 +lane_to_serdes_map_nif_lane46.0=rx46:tx44 +lane_to_serdes_map_nif_lane47.0=rx40:tx43 +lane_to_serdes_map_nif_lane48.0=rx55:tx55 +lane_to_serdes_map_nif_lane49.0=rx54:tx54 +lane_to_serdes_map_nif_lane50.0=rx53:tx53 +lane_to_serdes_map_nif_lane51.0=rx52:tx52 +lane_to_serdes_map_nif_lane52.0=rx48:tx48 +lane_to_serdes_map_nif_lane53.0=rx49:tx49 +lane_to_serdes_map_nif_lane54.0=rx50:tx50 +lane_to_serdes_map_nif_lane55.0=rx51:tx51 +lane_to_serdes_map_nif_lane56.0=rx60:tx60 +lane_to_serdes_map_nif_lane57.0=rx61:tx61 +lane_to_serdes_map_nif_lane58.0=rx62:tx63 +lane_to_serdes_map_nif_lane59.0=rx63:tx62 +lane_to_serdes_map_nif_lane60.0=rx58:tx59 +lane_to_serdes_map_nif_lane61.0=rx59:tx56 +lane_to_serdes_map_nif_lane62.0=rx57:tx58 +lane_to_serdes_map_nif_lane63.0=rx56:tx57 +lane_to_serdes_map_nif_lane64.0=rx68:tx69 +lane_to_serdes_map_nif_lane65.0=rx69:tx68 +lane_to_serdes_map_nif_lane66.0=rx70:tx71 +lane_to_serdes_map_nif_lane67.0=rx71:tx70 +lane_to_serdes_map_nif_lane68.0=rx67:tx64 +lane_to_serdes_map_nif_lane69.0=rx66:tx67 +lane_to_serdes_map_nif_lane70.0=rx65:tx65 +lane_to_serdes_map_nif_lane71.0=rx64:tx66 +lane_to_serdes_map_nif_lane72.0=rx78:tx76 +lane_to_serdes_map_nif_lane73.0=rx76:tx77 +lane_to_serdes_map_nif_lane74.0=rx79:tx78 +lane_to_serdes_map_nif_lane75.0=rx77:tx79 +lane_to_serdes_map_nif_lane76.0=rx75:tx72 +lane_to_serdes_map_nif_lane77.0=rx74:tx75 +lane_to_serdes_map_nif_lane78.0=rx73:tx73 +lane_to_serdes_map_nif_lane79.0=rx72:tx74 +lane_to_serdes_map_nif_lane80.0=rx81:tx83 +lane_to_serdes_map_nif_lane81.0=rx85:tx84 +lane_to_serdes_map_nif_lane82.0=rx80:tx80 +lane_to_serdes_map_nif_lane83.0=rx86:tx85 +lane_to_serdes_map_nif_lane84.0=rx82:tx82 +lane_to_serdes_map_nif_lane85.0=rx87:tx86 +lane_to_serdes_map_nif_lane86.0=rx83:tx81 +lane_to_serdes_map_nif_lane87.0=rx84:tx87 +lane_to_serdes_map_nif_lane88.0=rx91:tx95 +lane_to_serdes_map_nif_lane89.0=rx90:tx89 +lane_to_serdes_map_nif_lane90.0=rx95:tx94 +lane_to_serdes_map_nif_lane91.0=rx89:tx90 +lane_to_serdes_map_nif_lane92.0=rx93:tx93 +lane_to_serdes_map_nif_lane93.0=rx94:tx88 +lane_to_serdes_map_nif_lane94.0=rx92:tx92 +lane_to_serdes_map_nif_lane95.0=rx88:tx91 +phy_rx_polarity_flip_phy0=0 +phy_rx_polarity_flip_phy1=1 +phy_rx_polarity_flip_phy2=0 +phy_rx_polarity_flip_phy3=0 +phy_rx_polarity_flip_phy4=0 +phy_rx_polarity_flip_phy5=0 +phy_rx_polarity_flip_phy6=0 +phy_rx_polarity_flip_phy7=0 +phy_rx_polarity_flip_phy8=1 +phy_rx_polarity_flip_phy9=1 +phy_rx_polarity_flip_phy10=1 +phy_rx_polarity_flip_phy11=1 +phy_rx_polarity_flip_phy12=0 +phy_rx_polarity_flip_phy13=1 +phy_rx_polarity_flip_phy14=1 +phy_rx_polarity_flip_phy15=1 +phy_rx_polarity_flip_phy16=0 +phy_rx_polarity_flip_phy17=1 +phy_rx_polarity_flip_phy18=1 +phy_rx_polarity_flip_phy19=0 +phy_rx_polarity_flip_phy20=0 +phy_rx_polarity_flip_phy21=0 +phy_rx_polarity_flip_phy22=0 +phy_rx_polarity_flip_phy23=0 +phy_rx_polarity_flip_phy24=1 +phy_rx_polarity_flip_phy25=1 +phy_rx_polarity_flip_phy26=1 +phy_rx_polarity_flip_phy27=0 +phy_rx_polarity_flip_phy28=0 +phy_rx_polarity_flip_phy29=1 +phy_rx_polarity_flip_phy30=1 +phy_rx_polarity_flip_phy31=0 +phy_rx_polarity_flip_phy32=0 +phy_rx_polarity_flip_phy33=1 +phy_rx_polarity_flip_phy34=1 +phy_rx_polarity_flip_phy35=0 +phy_rx_polarity_flip_phy36=0 +phy_rx_polarity_flip_phy37=0 +phy_rx_polarity_flip_phy38=1 +phy_rx_polarity_flip_phy39=0 +phy_rx_polarity_flip_phy40=1 +phy_rx_polarity_flip_phy41=1 +phy_rx_polarity_flip_phy42=0 +phy_rx_polarity_flip_phy43=0 +phy_rx_polarity_flip_phy44=1 +phy_rx_polarity_flip_phy45=1 +phy_rx_polarity_flip_phy46=0 +phy_rx_polarity_flip_phy47=0 +phy_rx_polarity_flip_phy48=1 +phy_rx_polarity_flip_phy49=1 +phy_rx_polarity_flip_phy50=1 +phy_rx_polarity_flip_phy51=1 +phy_rx_polarity_flip_phy52=0 +phy_rx_polarity_flip_phy53=0 +phy_rx_polarity_flip_phy54=0 +phy_rx_polarity_flip_phy55=0 +phy_rx_polarity_flip_phy56=0 +phy_rx_polarity_flip_phy57=0 +phy_rx_polarity_flip_phy58=0 +phy_rx_polarity_flip_phy59=0 +phy_rx_polarity_flip_phy60=1 +phy_rx_polarity_flip_phy61=1 +phy_rx_polarity_flip_phy62=1 +phy_rx_polarity_flip_phy63=1 +phy_rx_polarity_flip_phy64=1 +phy_rx_polarity_flip_phy65=1 +phy_rx_polarity_flip_phy66=1 +phy_rx_polarity_flip_phy67=1 +phy_rx_polarity_flip_phy68=1 +phy_rx_polarity_flip_phy69=1 +phy_rx_polarity_flip_phy70=1 +phy_rx_polarity_flip_phy71=1 +phy_rx_polarity_flip_phy72=1 +phy_rx_polarity_flip_phy73=0 +phy_rx_polarity_flip_phy74=0 +phy_rx_polarity_flip_phy75=1 +phy_rx_polarity_flip_phy76=1 +phy_rx_polarity_flip_phy77=1 +phy_rx_polarity_flip_phy78=1 +phy_rx_polarity_flip_phy79=1 +phy_rx_polarity_flip_phy80=0 +phy_rx_polarity_flip_phy81=0 +phy_rx_polarity_flip_phy82=1 +phy_rx_polarity_flip_phy83=1 +phy_rx_polarity_flip_phy84=1 +phy_rx_polarity_flip_phy85=0 +phy_rx_polarity_flip_phy86=1 +phy_rx_polarity_flip_phy87=1 +phy_rx_polarity_flip_phy88=0 +phy_rx_polarity_flip_phy89=0 +phy_rx_polarity_flip_phy90=1 +phy_rx_polarity_flip_phy91=1 +phy_rx_polarity_flip_phy92=0 +phy_rx_polarity_flip_phy93=1 +phy_rx_polarity_flip_phy94=0 +phy_rx_polarity_flip_phy95=0 +phy_tx_polarity_flip_phy0=1 +phy_tx_polarity_flip_phy1=1 +phy_tx_polarity_flip_phy2=1 +phy_tx_polarity_flip_phy3=1 +phy_tx_polarity_flip_phy4=1 +phy_tx_polarity_flip_phy5=1 +phy_tx_polarity_flip_phy6=0 +phy_tx_polarity_flip_phy7=0 +phy_tx_polarity_flip_phy8=1 +phy_tx_polarity_flip_phy9=1 +phy_tx_polarity_flip_phy10=1 +phy_tx_polarity_flip_phy11=1 +phy_tx_polarity_flip_phy12=1 +phy_tx_polarity_flip_phy13=1 +phy_tx_polarity_flip_phy14=0 +phy_tx_polarity_flip_phy15=0 +phy_tx_polarity_flip_phy16=0 +phy_tx_polarity_flip_phy17=0 +phy_tx_polarity_flip_phy18=0 +phy_tx_polarity_flip_phy19=0 +phy_tx_polarity_flip_phy20=0 +phy_tx_polarity_flip_phy21=0 +phy_tx_polarity_flip_phy22=0 +phy_tx_polarity_flip_phy23=0 +phy_tx_polarity_flip_phy24=0 +phy_tx_polarity_flip_phy25=0 +phy_tx_polarity_flip_phy26=0 +phy_tx_polarity_flip_phy27=0 +phy_tx_polarity_flip_phy28=0 +phy_tx_polarity_flip_phy29=0 +phy_tx_polarity_flip_phy30=0 +phy_tx_polarity_flip_phy31=0 +phy_tx_polarity_flip_phy32=0 +phy_tx_polarity_flip_phy33=0 +phy_tx_polarity_flip_phy34=1 +phy_tx_polarity_flip_phy35=1 +phy_tx_polarity_flip_phy36=1 +phy_tx_polarity_flip_phy37=0 +phy_tx_polarity_flip_phy38=0 +phy_tx_polarity_flip_phy39=1 +phy_tx_polarity_flip_phy40=1 +phy_tx_polarity_flip_phy41=1 +phy_tx_polarity_flip_phy42=0 +phy_tx_polarity_flip_phy43=1 +phy_tx_polarity_flip_phy44=1 +phy_tx_polarity_flip_phy45=1 +phy_tx_polarity_flip_phy46=0 +phy_tx_polarity_flip_phy47=0 +phy_tx_polarity_flip_phy48=0 +phy_tx_polarity_flip_phy49=0 +phy_tx_polarity_flip_phy50=0 +phy_tx_polarity_flip_phy51=0 +phy_tx_polarity_flip_phy52=0 +phy_tx_polarity_flip_phy53=0 +phy_tx_polarity_flip_phy54=0 +phy_tx_polarity_flip_phy55=0 +phy_tx_polarity_flip_phy56=1 +phy_tx_polarity_flip_phy57=1 +phy_tx_polarity_flip_phy58=0 +phy_tx_polarity_flip_phy59=0 +phy_tx_polarity_flip_phy60=1 +phy_tx_polarity_flip_phy61=1 +phy_tx_polarity_flip_phy62=0 +phy_tx_polarity_flip_phy63=0 +phy_tx_polarity_flip_phy64=0 +phy_tx_polarity_flip_phy65=0 +phy_tx_polarity_flip_phy66=0 +phy_tx_polarity_flip_phy67=0 +phy_tx_polarity_flip_phy68=0 +phy_tx_polarity_flip_phy69=0 +phy_tx_polarity_flip_phy70=1 +phy_tx_polarity_flip_phy71=1 +phy_tx_polarity_flip_phy72=1 +phy_tx_polarity_flip_phy73=1 +phy_tx_polarity_flip_phy74=1 +phy_tx_polarity_flip_phy75=1 +phy_tx_polarity_flip_phy76=0 +phy_tx_polarity_flip_phy77=0 +phy_tx_polarity_flip_phy78=1 +phy_tx_polarity_flip_phy79=1 +phy_tx_polarity_flip_phy80=0 +phy_tx_polarity_flip_phy81=1 +phy_tx_polarity_flip_phy82=1 +phy_tx_polarity_flip_phy83=1 +phy_tx_polarity_flip_phy84=1 +phy_tx_polarity_flip_phy85=0 +phy_tx_polarity_flip_phy86=0 +phy_tx_polarity_flip_phy87=1 +phy_tx_polarity_flip_phy88=1 +phy_tx_polarity_flip_phy89=0 +phy_tx_polarity_flip_phy90=0 +phy_tx_polarity_flip_phy91=1 +phy_tx_polarity_flip_phy92=1 +phy_tx_polarity_flip_phy93=1 +phy_tx_polarity_flip_phy94=0 +phy_tx_polarity_flip_phy95=0 + +ucode_port_1=CGE2_0:core_0.1 +ucode_port_2=CGE2_1:core_0.2 +ucode_port_3=CGE2_2:core_0.3 +ucode_port_4=CGE2_3:core_0.4 +ucode_port_5=CGE2_4:core_0.5 +ucode_port_6=CGE2_5:core_0.6 +ucode_port_7=CGE2_6:core_0.7 +ucode_port_8=CGE2_7:core_0.8 +ucode_port_9=CGE2_8:core_0.9 +ucode_port_10=CGE2_9:core_0.10 +ucode_port_11=CGE2_10:core_0.11 +ucode_port_12=CGE2_11:core_0.12 +ucode_port_13=CGE2_12:core_0.13 +ucode_port_14=CGE2_13:core_0.14 +ucode_port_15=CGE2_14:core_0.15 +ucode_port_16=CGE2_15:core_0.16 +ucode_port_17=CGE2_36:core_1.17 +ucode_port_18=CGE2_37:core_1.18 +ucode_port_19=CGE2_38:core_1.19 +ucode_port_20=CGE2_39:core_1.20 +ucode_port_21=CGE2_32:core_1.21 +ucode_port_22=CGE2_33:core_1.22 +ucode_port_23=CGE2_34:core_1.23 +ucode_port_24=CGE2_35:core_1.24 +ucode_port_25=CGE2_28:core_1.25 +ucode_port_26=CGE2_29:core_1.26 +ucode_port_27=CGE2_30:core_1.27 +ucode_port_28=CGE2_31:core_1.28 +ucode_port_29=XE48:core_1.29 +ucode_port_30=XE49:core_1.30 +ucode_port_31=XE50:core_1.31 +ucode_port_32=XE51:core_1.32 +ucode_port_33=XE52:core_1.33 +ucode_port_34=XE53:core_1.34 +ucode_port_35=XE54:core_1.35 +ucode_port_36=XE55:core_1.36 + +rif_id_max=0x4000 + +dma_desc_aggregator_chain_length_max.BCM8869X=1000 +dma_desc_aggregator_buff_size_kb.BCM8869X=100 +dma_desc_aggregator_timeout_usec.BCM8869X=1000 +dma_desc_aggregator_enable_specific_MDB_LPM.BCM8869X=1 +dma_desc_aggregator_enable_specific_MDB_FEC.BCM8869X=1 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/port_config.ini b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/port_config.ini new file mode 100644 index 000000000000..cb1c2a4663e8 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/port_config.ini @@ -0,0 +1,37 @@ +# name lanes alias index speed +Ethernet0 0,1 Ethernet1/1 1 100000 +Ethernet4 2,3 Ethernet2/1 2 100000 +Ethernet8 4,5 Ethernet3/1 3 100000 +Ethernet12 6,7 Ethernet4/1 4 100000 +Ethernet16 8,9 Ethernet5/1 5 100000 +Ethernet20 10,11 Ethernet6/1 6 100000 +Ethernet24 12,13 Ethernet7/1 7 100000 +Ethernet28 14,15 Ethernet8/1 8 100000 +Ethernet32 16,17 Ethernet9/1 9 100000 +Ethernet36 18,19 Ethernet10/1 10 100000 +Ethernet40 20,21 Ethernet11/1 11 100000 +Ethernet44 22,23 Ethernet12/1 12 100000 +Ethernet48 24,25 Ethernet13/1 13 100000 +Ethernet52 26,27 Ethernet14/1 14 100000 +Ethernet56 28,29 Ethernet15/1 15 100000 +Ethernet60 30,31 Ethernet16/1 16 100000 +Ethernet64 72,73 Ethernet17/1 17 100000 +Ethernet68 74,75 Ethernet18/1 18 100000 +Ethernet72 76,77 Ethernet19/1 19 100000 +Ethernet76 78,79 Ethernet20/1 20 100000 +Ethernet80 64,65 Ethernet21/1 21 100000 +Ethernet84 66,67 Ethernet22/1 22 100000 +Ethernet88 68,69 Ethernet23/1 23 100000 +Ethernet92 70,71 Ethernet24/1 24 100000 +Ethernet96 56,57 Ethernet25/1 25 100000 +Ethernet100 58,59 Ethernet26/1 26 100000 +Ethernet104 60,61 Ethernet27/1 27 100000 +Ethernet108 62,63 Ethernet28/1 28 100000 +Ethernet112 48 Ethernet29/1 29 10000 +Ethernet113 49 Ethernet29/2 29 10000 +Ethernet114 50 Ethernet29/3 29 10000 +Ethernet115 51 Ethernet29/4 29 10000 +Ethernet120 52 Ethernet31/1 31 10000 +Ethernet121 53 Ethernet31/2 31 10000 +Ethernet122 54 Ethernet31/3 31 10000 +Ethernet123 55 Ethernet31/4 31 10000 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile new file mode 100644 index 000000000000..7e699b10430e --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm From 1e7c458454bae653627b796d1723eb317878ff63 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Tue, 8 Oct 2019 18:10:38 -0700 Subject: [PATCH 0048/1427] Add separator field to database_config.json (#3581) --- dockers/docker-database/database_config.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dockers/docker-database/database_config.json b/dockers/docker-database/database_config.json index d5d951bead5d..b86ae11bba98 100644 --- a/dockers/docker-database/database_config.json +++ b/dockers/docker-database/database_config.json @@ -9,38 +9,47 @@ "DATABASES" : { "APPL_DB" : { "id" : 0, + "separator": ":", "instance" : "redis" }, "ASIC_DB" : { "id" : 1, + "separator": ":", "instance" : "redis" }, "COUNTERS_DB" : { "id" : 2, + "separator": ":", "instance" : "redis" }, "LOGLEVEL_DB" : { "id" : 3, + "separator": ":", "instance" : "redis" }, "CONFIG_DB" : { "id" : 4, + "separator": "|", "instance" : "redis" }, "PFC_WD_DB" : { "id" : 5, + "separator": ":", "instance" : "redis" }, "FLEX_COUNTER_DB" : { "id" : 5, + "separator": ":", "instance" : "redis" }, "STATE_DB" : { "id" : 6, + "separator": "|", "instance" : "redis" }, "SNMP_OVERLAY_DB" : { "id" : 7, + "separator": "|", "instance" : "redis" } }, From 0d8895b35494b9d7a7780e3b96f8890000d20280 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 9 Oct 2019 04:57:00 +0000 Subject: [PATCH 0049/1427] [submodule]: update sonic-sairedis * 1f4a1d7 2019-09-24 | Add warm boot support with removed/created port (#515) (HEAD, origin/master, origin/HEAD) [Kamil Cudnik] * 59e530a 2019-09-20 | Add support for debug counters (#517) [Danny Allen] * 1ed09e0 2019-09-20 | fully support bulk_remove in sairedis (#516) [Dong Zhang] * 6cb1b31 2019-09-17 | Add support for port remove and port create (no warm boot) (#500) [Kamil Cudnik] * 83d86ed 2019-09-17 | Fix c_str() in printf for string (#514) [Kamil Cudnik] * 11b44b5 2019-09-16 | Advance SAI reference pointer to v1.5.0 (#509) [Wenda Ni] * 38c6945 2019-09-14 | support sflow on virtual switch (#498) [Rakesh Datta] * e7d766e 2019-09-09 | Add acl counter match logic based on acl entry field (#511) [Kamil Cudnik] * 58845ce 2019-09-06 | Add extra check for warm boot discovered RIDs (#502) [Kamil Cudnik] * b4893ef 2019-09-05 | [flex counter]: Lower the severity of log during rif counter support check (#504) [shikenghua] * b859344 2019-09-03 | fix found typo in new added syncMode related codes (#506) [Dong Zhang] Signed-off-by: Guohan Lu --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 5fc89b569c98..1f4a1d76bd9c 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 5fc89b569c98ca1be51f0069c59465abd5873b19 +Subproject commit 1f4a1d76bd9cd3e8865911840ab8e47c0ba221f1 From 8d2f67ef00ec079364936a0fb4ddaefb79dce00d Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 9 Oct 2019 07:40:01 -0700 Subject: [PATCH 0050/1427] [baseimage]: incrase docker ramfs from 800MB to 900MB (#3582) --- onie-image.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onie-image.conf b/onie-image.conf index db99c867de04..2ca0a68484e2 100644 --- a/onie-image.conf +++ b/onie-image.conf @@ -25,7 +25,7 @@ FILESYSTEM_DOCKERFS=dockerfs.tar.gz DOCKERFS_DIR=docker ## docker ramfs disk space -DOCKER_RAMFS_SIZE=800M +DOCKER_RAMFS_SIZE=900M ## Output file name for onie installer OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin From 576f0982d2551c6c56a075b87b7bf046dabfec75 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Thu, 10 Oct 2019 02:07:30 +0800 Subject: [PATCH 0051/1427] [Mellanox]Resolve chassis broken due to inconsistent with latest sonic_platform_common (#3569) *Currently get_firmware_version implementated by using chassis.get_firmware_version and chassis._component_name_list which are not supported in the latest sonic_platform_common, causing chassis broken. Update this part so that it aligns to the latest sonic_platform_common *Support component API --- .../sonic_platform/chassis.py | 143 ++++------------- .../sonic_platform/component.py | 148 ++++++++++++++++++ .../sonic_platform/platform.py | 2 +- 3 files changed, 176 insertions(+), 117 deletions(-) create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/component.py diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 02d898822817..f5c7c04a4204 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -10,6 +10,7 @@ try: from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform_base.component_base import ComponentBase from sonic_daemon_base.daemon_base import Logger from os import listdir from os.path import isfile, join @@ -37,22 +38,6 @@ REBOOT_CAUSE_FILE_LENGTH = 1 -#version retrieving related definitions -CPLD_VERSION_ROOT = HWMGMT_SYSTEM_ROOT - -CPLD1_VERSION_FILE = 'cpld1_version' -CPLD2_VERSION_FILE = 'cpld2_version' -CPLD_VERSION_MAX_LENGTH = 4 - -FW_QUERY_VERSION_COMMAND = 'mlxfwmanager --query' -BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' - -#components definitions -COMPONENT_BIOS = "BIOS" -COMPONENT_FIRMWARE = "ASIC-FIRMWARE" -COMPONENT_CPLD1 = "CPLD1" -COMPONENT_CPLD2 = "CPLD2" - # Global logger class instance SYSLOG_IDENTIFIER = "mlnx-chassis-api" logger = Logger(SYSLOG_IDENTIFIER) @@ -78,10 +63,12 @@ def __init__(self): self.reboot_cause_initialized = False logger.log_info("Chassis loaded successfully") + def __del__(self): if self.sfp_event_initialized: self.sfp_event.deinitialize() + def initialize_psu(self): from sonic_platform.psu import Psu # Initialize PSU list @@ -90,6 +77,7 @@ def initialize_psu(self): psu = Psu(index, self.sku_name) self._psu_list.append(psu) + def initialize_fan(self): from sonic_platform.fan import Fan from sonic_platform.fan import FAN_PATH @@ -107,6 +95,7 @@ def initialize_fan(self): fan = Fan(index, index) self._fan_list.append(fan) + def initialize_sfp(self): from sonic_platform.sfp import SFP @@ -128,22 +117,25 @@ def initialize_sfp(self): self.sfp_module_initialized = True + def initialize_thermals(self): from sonic_platform.thermal import initialize_thermals # Initialize thermals initialize_thermals(self.sku_name, self._thermal_list, self._psu_list) + def initialize_eeprom(self): from eeprom import Eeprom # Initialize EEPROM self._eeprom = Eeprom() - def initialize_components_list(self): + + def initialize_components(self): # Initialize component list - self._component_name_list.append(COMPONENT_BIOS) - self._component_name_list.append(COMPONENT_FIRMWARE) - self._component_name_list.append(COMPONENT_CPLD1) - self._component_name_list.append(COMPONENT_CPLD2) + from sonic_platform.component import ComponentBIOS, ComponentCPLD + self._component_list.append(ComponentBIOS()) + self._component_list.append(ComponentCPLD()) + ############################################## # SFP methods @@ -159,6 +151,7 @@ def get_num_sfps(self): self.initialize_sfp() return len(self._sfp_list) + def get_all_sfps(self): """ Retrieves all sfps available on this chassis @@ -171,6 +164,7 @@ def get_all_sfps(self): self.initialize_sfp() return self._sfp_list + def get_sfp(self, index): """ Retrieves sfp represented by (0-based) index @@ -197,6 +191,7 @@ def get_sfp(self, index): return sfp + def _extract_num_of_fans_and_fan_drawers(self): num_of_fan = 0 num_of_drawer = 0 @@ -213,15 +208,18 @@ def _extract_num_of_fans_and_fan_drawers(self): return num_of_fan, num_of_drawer + def _get_sku_name(self): p = subprocess.Popen(GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) out, err = p.communicate() return out.rstrip('\n') + def _get_port_position_tuple_by_sku_name(self): position_tuple = port_position_tuple_list[hwsku_dict_port[self.sku_name]] return position_tuple + def get_watchdog(self): """ Retrieves hardware watchdog device on this chassis @@ -246,6 +244,7 @@ def get_watchdog(self): return self._watchdog + def get_base_mac(self): """ Retrieves the base MAC address for the chassis @@ -256,6 +255,7 @@ def get_base_mac(self): """ return self._eeprom.get_base_mac() + def get_serial_number(self): """ Retrieves the hardware serial number for the chassis @@ -265,6 +265,7 @@ def get_serial_number(self): """ return self._eeprom.get_serial_number() + def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis @@ -276,6 +277,7 @@ def get_system_eeprom_info(self): """ return self._eeprom.get_system_eeprom_info() + def _read_generic_file(self, filename, len): """ Read a generic file, returns the contents of the file @@ -290,6 +292,7 @@ def _read_generic_file(self, filename, len): logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) return '0' + def _verify_reboot_cause(self, filename): ''' Open and read the reboot cause file in @@ -298,6 +301,7 @@ def _verify_reboot_cause(self, filename): ''' return bool(int(self._read_generic_file(join(REBOOT_CAUSE_ROOT, filename), REBOOT_CAUSE_FILE_LENGTH).rstrip('\n'))) + def initialize_reboot_cause(self): self.reboot_major_cause_dict = { 'reset_main_pwr_fail' : self.REBOOT_CAUSE_POWER_LOSS, @@ -323,6 +327,7 @@ def initialize_reboot_cause(self): } self.reboot_cause_initialized = True + def get_reboot_cause(self): """ Retrieves the cause of the previous reboot @@ -348,101 +353,6 @@ def get_reboot_cause(self): return self.REBOOT_CAUSE_NON_HARDWARE, '' - def _get_cpld_version(self, version_file): - cpld_version = self._read_generic_file(join(CPLD_VERSION_ROOT, version_file), CPLD_VERSION_MAX_LENGTH) - return cpld_version.rstrip('\n') - - def _get_command_result(self, cmdline): - try: - proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) - stdout = proc.communicate()[0] - proc.wait() - result = stdout.rstrip('\n') - - except OSError, e: - result = '' - - return result - - def _get_firmware_version(self): - """ - firmware version is retrieved via command 'mlxfwmanager --query' - which should return result in the following convention - admin@mtbc-sonic-01-2410:~$ sudo mlxfwmanager --query - Querying Mellanox devices firmware ... - - Device #1: - ---------- - - Device Type: Spectrum - Part Number: MSN2410-CxxxO_Ax_Bx - Description: Spectrum based 25GbE/100GbE 1U Open Ethernet switch with ONIE; 48 SFP28 ports; 8 QSFP28 ports; x86 dual core; RoHS6 - PSID: MT_2860111033 - PCI Device Name: /dev/mst/mt52100_pci_cr0 - Base MAC: 98039bf3f500 - Versions: Current Available - FW ***13.2000.1140***N/A - - Status: No matching image found - - By using regular expression '(Versions:.*\n[\s]+FW[\s]+)([\S]+)', - we can extrace the version which is marked with *** in the above context - """ - fw_ver_str = self._get_command_result(FW_QUERY_VERSION_COMMAND) - try: - m = re.search('(Versions:.*\n[\s]+FW[\s]+)([\S]+)', fw_ver_str) - result = m.group(2) - except : - result = '' - - return result - - def _get_bios_version(self): - """ - BIOS version is retrieved via command 'dmidecode -t 11' - which should return result in the following convention - # dmidecode 3.0 - Getting SMBIOS data from sysfs. - SMBIOS 2.7 present. - - Handle 0x0022, DMI type 11, 5 bytes - OEM Strings - String 1:*0ABZS017_02.02.002* - String 2: To Be Filled By O.E.M. - - By using regular expression 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' - we can extrace the version string which is marked with * in the above context - """ - bios_ver_str = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) - try: - m = re.search('OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)', bios_ver_str) - result = m.group(1) - except: - result = '' - - return result - - def get_firmware_version(self, component_name): - """ - Retrieves platform-specific hardware/firmware versions for chassis - componenets such as BIOS, CPLD, FPGA, etc. - Args: - component_name: A string, the component name. - - Returns: - A string containing platform-specific component versions - """ - if component_name in self._component_name_list : - if component_name == COMPONENT_BIOS: - return self._get_bios_version() - elif component_name == COMPONENT_CPLD1: - return self._get_cpld_version(CPLD1_VERSION_FILE) - elif component_name == COMPONENT_CPLD2: - return self._get_cpld_version(CPLD2_VERSION_FILE) - elif component_name == COMPONENT_FIRMWARE: - return self._get_firmware_version() - - return None def _show_capabilities(self): """ @@ -465,6 +375,7 @@ def _show_capabilities(self): except: print "fail to retrieve capabilities for module index {}".format(s.index) + def get_change_event(self, timeout=0): """ Returns a nested dictionary containing all devices which have diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py new file mode 100644 index 000000000000..fd593f7bbe45 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# implementation of new platform api +############################################################################# + +try: + from sonic_platform_base.component_base import ComponentBase + from glob import glob + import subprocess + import io + import re +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +#components definitions +COMPONENT_BIOS = "BIOS" +COMPONENT_CPLD = "CPLD" + +BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' +CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' +CPLD_VERSION_MAX_LENGTH = 4 + +class Component(ComponentBase): + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + + + def _read_generic_file(self, filename, len): + """ + Read a generic file, returns the contents of the file + """ + result = '' + try: + with io.open(filename, 'r') as fileobj: + result = fileobj.read(len) + return result + except IOError as e: + raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) + + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + + except OSError as e: + raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + + return result + + +class ComponentBIOS(Component): + BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' + + + def __init__(self): + self.name = COMPONENT_BIOS + + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return "BIOS - Basic Input/Output System" + + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + + BIOS version is retrieved via command 'dmidecode -t 11' + which should return result in the following convention + # dmidecode 3.0 + Getting SMBIOS data from sysfs. + SMBIOS 2.7 present. + + Handle 0x0022, DMI type 11, 5 bytes + OEM Strings + String 1:*0ABZS017_02.02.002* + String 2: To Be Filled By O.E.M. + + By using regular expression 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' + we can extrace the version string which is marked with * in the above context + """ + bios_ver_str = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) + try: + m = re.search(self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str) + result = m.group(1) + except AttributeError as e: + raise RuntimeError("Failed to parse BIOS version by {} from {} due to {}".format( + self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str, repr(e))) + + return result + + +class ComponentCPLD(Component): + def __init__(self): + self.name = COMPONENT_CPLD + + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return "CPLD - includes all CPLDs in the switch" + + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + cpld_version_file_list = glob(CPLD_VERSION_FILE_PATTERN) + cpld_version = '' + if cpld_version_file_list is not None and cpld_version_file_list: + cpld_version_file_list.sort() + for version_file in cpld_version_file_list: + version = self._read_generic_file(version_file, CPLD_VERSION_MAX_LENGTH) + if not cpld_version == '': + cpld_version += '.' + cpld_version += version.rstrip('\n') + else: + raise RuntimeError("Failed to get CPLD version files by matching {}".format(CPLD_VERSION_FILE_PATTERN)) + + return cpld_version + diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py index fc555bc479a3..25461986f37a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -18,12 +18,12 @@ def __init__(self): PlatformBase.__init__(self) if self._is_host(): self._chassis = Chassis() + self._chassis.initialize_components() else: self._chassis = Chassis() self._chassis.initialize_psu() self._chassis.initialize_fan() self._chassis.initialize_eeprom() - self._chassis.initialize_components_list() def _is_host(self): """ From 41e855c2112326949f68ff4098282bdbb2a24587 Mon Sep 17 00:00:00 2001 From: JohnsonYJLu <31528297+JohnsonYJLu@users.noreply.github.com> Date: Thu, 10 Oct 2019 04:53:07 +0800 Subject: [PATCH 0052/1427] [devices]: fixed sfputil error on ag9032 (#3579) Signed-off-by: johnson --- .../Delta-ag9032v2a/port_config.ini | 66 ++++---- .../plugins/sfputil.py | 8 +- .../modules/delta_ag9032v2a_platform.c | 151 +++++++++++------- 3 files changed, 134 insertions(+), 91 deletions(-) diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini index d7b858054ff9..9eb4ac0c8a0c 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini +++ b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini @@ -1,34 +1,34 @@ # name lanes alias index speed -Ethernet0 1,2,3,4 hundredGigE1/1 1 100000 -Ethernet4 5,6,7,8 hundredGigE1/2 2 100000 -Ethernet8 9,10,11,12 hundredGigE1/3 3 100000 -Ethernet12 13,14,15,16 hundredGigE1/4 4 100000 -Ethernet16 17,18,19,20 hundredGigE1/5 5 100000 -Ethernet20 21,22,23,24 hundredGigE1/6 6 100000 -Ethernet24 25,26,27,28 hundredGigE1/7 7 100000 -Ethernet28 29,30,31,32 hundredGigE1/8 8 100000 -Ethernet32 33,34,35,36 hundredGigE1/9 9 100000 -Ethernet36 37,38,39,40 hundredGigE1/10 10 100000 -Ethernet40 41,42,43,44 hundredGigE1/11 11 100000 -Ethernet44 45,46,47,48 hundredGigE1/12 12 100000 -Ethernet48 49,50,51,52 hundredGigE1/13 13 100000 -Ethernet52 53,54,55,56 hundredGigE1/14 14 100000 -Ethernet56 57,58,59,60 hundredGigE1/15 15 100000 -Ethernet60 61,62,63,64 hundredGigE1/16 16 100000 -Ethernet64 65,66,67,68 hundredGigE1/17 17 100000 -Ethernet68 69,70,71,72 hundredGigE1/18 18 100000 -Ethernet72 73,74,75,76 hundredGigE1/19 19 100000 -Ethernet76 77,78,79,80 hundredGigE1/20 20 100000 -Ethernet80 81,82,83,84 hundredGigE1/21 21 100000 -Ethernet84 85,86,87,88 hundredGigE1/22 22 100000 -Ethernet88 89,90,91,92 hundredGigE1/23 23 100000 -Ethernet92 93,94,95,96 hundredGigE1/24 24 100000 -Ethernet96 97,98,99,100 hundredGigE1/25 25 100000 -Ethernet100 101,102,103,104 hundredGigE1/26 26 100000 -Ethernet104 105,106,107,108 hundredGigE1/27 27 100000 -Ethernet108 109,110,111,112 hundredGigE1/28 28 100000 -Ethernet112 113,114,115,116 hundredGigE1/29 29 100000 -Ethernet116 117,118,119,120 hundredGigE1/30 30 100000 -Ethernet120 121,122,123,124 hundredGigE1/31 31 100000 -Ethernet124 125,126,127,128 hundredGigE1/32 32 100000 -Ethernet128 129 tenGigE1/33 33 10000 +Ethernet0 1,2,3,4 hundredGigE1/1 0 100000 +Ethernet4 5,6,7,8 hundredGigE1/2 1 100000 +Ethernet8 9,10,11,12 hundredGigE1/3 2 100000 +Ethernet12 13,14,15,16 hundredGigE1/4 3 100000 +Ethernet16 17,18,19,20 hundredGigE1/5 4 100000 +Ethernet20 21,22,23,24 hundredGigE1/6 5 100000 +Ethernet24 25,26,27,28 hundredGigE1/7 6 100000 +Ethernet28 29,30,31,32 hundredGigE1/8 7 100000 +Ethernet32 33,34,35,36 hundredGigE1/9 8 100000 +Ethernet36 37,38,39,40 hundredGigE1/10 9 100000 +Ethernet40 41,42,43,44 hundredGigE1/11 10 100000 +Ethernet44 45,46,47,48 hundredGigE1/12 11 100000 +Ethernet48 49,50,51,52 hundredGigE1/13 12 100000 +Ethernet52 53,54,55,56 hundredGigE1/14 13 100000 +Ethernet56 57,58,59,60 hundredGigE1/15 14 100000 +Ethernet60 61,62,63,64 hundredGigE1/16 15 100000 +Ethernet64 65,66,67,68 hundredGigE1/17 16 100000 +Ethernet68 69,70,71,72 hundredGigE1/18 17 100000 +Ethernet72 73,74,75,76 hundredGigE1/19 18 100000 +Ethernet76 77,78,79,80 hundredGigE1/20 19 100000 +Ethernet80 81,82,83,84 hundredGigE1/21 20 100000 +Ethernet84 85,86,87,88 hundredGigE1/22 21 100000 +Ethernet88 89,90,91,92 hundredGigE1/23 22 100000 +Ethernet92 93,94,95,96 hundredGigE1/24 23 100000 +Ethernet96 97,98,99,100 hundredGigE1/25 24 100000 +Ethernet100 101,102,103,104 hundredGigE1/26 25 100000 +Ethernet104 105,106,107,108 hundredGigE1/27 26 100000 +Ethernet108 109,110,111,112 hundredGigE1/28 27 100000 +Ethernet112 113,114,115,116 hundredGigE1/29 28 100000 +Ethernet116 117,118,119,120 hundredGigE1/30 29 100000 +Ethernet120 121,122,123,124 hundredGigE1/31 30 100000 +Ethernet124 125,126,127,128 hundredGigE1/32 31 100000 +Ethernet128 129 tenGigE1/33 32 10000 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py b/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py index 2cffa8807c0a..9abaa8cf01c1 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py +++ b/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py @@ -62,7 +62,7 @@ def get_presence(self, port_num): reg_value = int(content, 16) # Mask off the bit corresponding to our port - mask = (1 << port_num) + mask = (1 << (self.port_end - port_num + 7)) # ModPrsL is active low if reg_value & mask == 0: @@ -86,7 +86,7 @@ def get_low_power_mode(self, port_num): reg_value = int(content, 16) # Mask off the bit corresponding to our port - mask = (1 << port_num) + mask = (1 << (self.port_end - port_num) - 1) # LPMode is active high if reg_value & mask == 0: @@ -111,7 +111,7 @@ def set_low_power_mode(self, port_num, lpmode): reg_value = int(content, 16) # Mask off the bit corresponding to our port - mask = (1 << port_num) + mask = (1 << (self.port_end - port_num) - 1) # LPMode is active high; set or clear the bit accordingly if lpmode is True: @@ -147,7 +147,7 @@ def reset(self, port_num): reg_value = int(content, 16) # Mask off the bit corresponding to our port - mask = (1 << port_num) + mask = (1 << (self.port_end - port_num) - 1) # ResetL is active low reg_value = reg_value & ~mask diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c index e9baeb928faf..85719af7ea94 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c @@ -566,53 +566,53 @@ static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, mutex_lock(&dni_lock); switch (attr->index) { case SFP_IS_PRESENT: - /*QSFP1~8*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_1); - data = (u32)(reverse_8bits(ret) & 0xff); - /*QSFP9~16*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_2); - data |= (u32)(reverse_8bits(ret) & 0xff) << 8; - /*QSFP17~24*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_3); - data |= (u32)(reverse_8bits(ret) & 0xff) << 16; /*QSFP25~32*/ ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_4); - data |= (u32)(reverse_8bits(ret) & 0xff) << 24; + data = (u32)ret & 0xff; + /*QSFP17~24*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_3); + data |= ((u32)ret & 0xff) << 8; + /*QSFP9~16*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_2); + data |= (u32)(ret & 0xff) << 16; + /*QSFP1~8*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_1); + data |= (u32)(ret & 0xff) << 24; ret = i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_PRESENCE_5); - ret_sfp = (ret & (0x80)) >> 7; + ret_sfp = (ret & (0x80)); mutex_unlock(&dni_lock); - return sprintf(buf, "0x%x%x\n", ret_sfp, data); + return sprintf(buf, "0x%x%02x\n", data, ret_sfp); case QSFP_LPMODE: - /*QSFP1~8*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_1); - data = (u32)(reverse_8bits(ret) & 0xff); - /*QSFP9~16*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_2); - data |= (u32)(reverse_8bits(ret) & 0xff) << 8; - /*QSFP17~24*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_3); - data |= (u32)(reverse_8bits(ret) & 0xff) << 16; /*QSFP25~32*/ ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_4); - data |= (u32)(reverse_8bits(ret) & 0xff) << 24; + data = (u32)(ret & 0xff); + /*QSFP17~24*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_3); + data |= (u32)(ret & 0xff) << 8; + /*QSFP9~16*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_2); + data |= (u32)(ret & 0xff) << 16; + /*QSFP1~8*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_1); + data |= (u32)(ret & 0xff) << 24; mutex_unlock(&dni_lock); return sprintf(buf, "0x%x\n", data); case QSFP_RESET: - /*QSFP1~8*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_1); - data = (u32)(reverse_8bits(ret) & 0xff); - /*QSFP9~16*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_2); - data |= (u32)(reverse_8bits(ret) & 0xff) << 8; - /*QSFP17~24*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_3); - data |= (u32)(reverse_8bits(ret) & 0xff) << 16; /*QSFP25~32*/ ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_4); - data |= (u32)(reverse_8bits(ret) & 0xff) << 24; + data = (u32)(ret & 0xff); + /*QSFP17~24*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_3); + data |= (u32)(ret & 0xff) << 8; + /*QSFP9~16*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_2); + data |= (u32)(ret & 0xff) << 16; + /*QSFP1~8*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_1); + data |= (u32)(ret & 0xff) << 24; mutex_unlock(&dni_lock); return sprintf(buf, "0x%x\n", data); @@ -628,6 +628,7 @@ static ssize_t set_lpmode_data(struct device *dev, struct device_attribute *dev_ struct cpld_platform_data *pdata = i2cdev->platform_data; unsigned long long set_data; int err; + int status = 0; unsigned char set_bytes; @@ -636,24 +637,45 @@ static ssize_t set_lpmode_data(struct device *dev, struct device_attribute *dev_ return err; } mutex_lock(&dni_lock); - /*QSFP1~8*/ - set_bytes = reverse_8bits(set_data & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_1, set_bytes); + /*QSFP25~32*/ + set_bytes = set_data & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_4, set_bytes); + if(status < 0) + { + goto ERROR; + } + + /*QSFP17~24*/ + set_bytes = (set_data >> 8 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_3, set_bytes); + if(status < 0) + { + goto ERROR; + } /*QSFP9~16*/ - set_bytes = reverse_8bits((set_data >> 8 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_2, set_bytes); + set_bytes = (set_data >> 16 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_2, set_bytes); + if(status < 0) + { + goto ERROR; + } - /*QSFP17~24*/ - set_bytes = reverse_8bits((set_data >> 16 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_3, set_bytes); + /*QSFP1~8*/ + set_bytes = (set_data >> 24 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_1, set_bytes); + if(status < 0) + { + goto ERROR; + } - /*QSFP25~32*/ - set_bytes = reverse_8bits((set_data >> 24 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_4, set_bytes); mutex_unlock(&dni_lock); return count; +ERROR: + mutex_unlock(&dni_lock); + return status; + } static ssize_t set_reset_data(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) @@ -662,6 +684,7 @@ static ssize_t set_reset_data(struct device *dev, struct device_attribute *dev_a struct cpld_platform_data *pdata = i2cdev->platform_data; unsigned long long set_data; int err; + int status = 0; unsigned char set_bytes; err = kstrtoull(buf, 16, &set_data); @@ -670,23 +693,43 @@ static ssize_t set_reset_data(struct device *dev, struct device_attribute *dev_a } mutex_lock(&dni_lock); - /*QSFP1~8*/ - set_bytes = reverse_8bits(set_data & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_1, set_bytes); + /*QSFP25~32*/ + set_bytes = set_data & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_4, set_bytes); + if(status < 0) + { + goto ERROR; + } + + /*QSFP17~24*/ + set_bytes = (set_data >> 8 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_3, set_bytes); + if(status < 0) + { + goto ERROR; + } /*QSFP9~16*/ - set_bytes = reverse_8bits((set_data >> 8 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_2, set_bytes); + set_bytes = (set_data >> 16 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_2, set_bytes); + if(status < 0) + { + goto ERROR; + } - /*QSFP17~24*/ - set_bytes = reverse_8bits((set_data >> 16 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_3, set_bytes); + /*QSFP1~8*/ + set_bytes = (set_data >> 24 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_1, set_bytes); + if(status < 0) + { + goto ERROR; + } - /*QSFP25~32*/ - set_bytes = reverse_8bits((set_data >> 24 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_4, set_bytes); mutex_unlock(&dni_lock); return count; +ERROR: + mutex_unlock(&dni_lock); + return status; } From 110bff9b47f5bcfa76638ac52f862dd83ba113b7 Mon Sep 17 00:00:00 2001 From: David Xiao <53024022+david-xk@users.noreply.github.com> Date: Wed, 9 Oct 2019 16:16:05 -0700 Subject: [PATCH 0053/1427] [Inventec][D6356] Update driver and Add new platform API implementation (#3521) * Update driver and Add new platform API implementation for Inventec D6356 * Update Platform API (SFP) * Update Platform API (QSFP) * Update Platform API (FAN, THERMAL) Signed-off-by: David Xiao --- .../INVENTEC-D6356/buffers.json.j2 | 2 + .../INVENTEC-D6356/buffers_defaults_t0.j2 | 50 + .../INVENTEC-D6356/buffers_defaults_t1.j2 | 50 + .../INVENTEC-D6356/pg_profile_lookup.ini | 17 + .../INVENTEC-D6356/port_config.ini | 114 +- .../INVENTEC-D6356/qos.json.j2 | 155 +++ .../td3-d6356-48x25G-8x100G.config.bcm | 248 ++-- .../x86_64-inventec_d6356-r0/custom_led.bin | Bin 0 -> 552 bytes .../led_proc_init.soc | 4 +- .../linkscan_led_fw.bin | Bin 0 -> 4744 bytes .../plugins/psuutil.py | 12 +- .../plugins/sfputil.py | 170 ++- .../x86_64-inventec_d6356-r0/sensors.conf | 7 +- .../d6356/modules/Makefile | 4 + .../d6356/modules/gpio-ich.c | 513 ++++++++ .../d6356/modules/i2c-mux-pca9541.c | 573 +++++++++ .../d6356/modules/inv_cpld.c | 165 ++- .../d6356/modules/inv_mux.c | 364 +++++- .../d6356/modules/inv_mux.h | 46 +- .../d6356/modules/inv_platform.c | 92 +- .../d6356/modules/inv_swps.c | 331 ++++- .../d6356/modules/inv_swps.h | 621 +++++++-- .../d6356/modules/io_expander.c | 630 ++++++++- .../d6356/modules/io_expander.h | 52 +- .../d6356/modules/lpc_ich.c | 1131 +++++++++++++++++ .../d6356/modules/pmbus.h | 425 +++++++ .../d6356/modules/transceiver.c | 35 +- .../d6356/modules/transceiver.h | 8 +- .../d6356/modules/ucd9000.c | 247 ++++ .../d6356/setup.py | 15 + .../d6356/sonic_platform/__init__.py | 3 + .../d6356/sonic_platform/chassis.py | 149 +++ .../d6356/sonic_platform/eeprom.py | 110 ++ .../d6356/sonic_platform/fan.py | 204 +++ .../d6356/sonic_platform/platform.py | 20 + .../d6356/sonic_platform/psu.py | 202 +++ .../d6356/sonic_platform/qsfp.py | 925 ++++++++++++++ .../d6356/sonic_platform/sfp.py | 739 +++++++++++ .../d6356/sonic_platform/thermal.py | 170 +++ .../d6356/utils/inventec_d6356_util.py | 33 +- .../debian/control | 2 +- .../debian/platform-modules-d6356.install | 4 +- .../debian/rules | 18 +- .../systemd/platform-modules-d6356.service | 13 + 44 files changed, 8074 insertions(+), 599 deletions(-) create mode 100644 device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers.json.j2 create mode 100644 device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t0.j2 create mode 100644 device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t1.j2 create mode 100644 device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/pg_profile_lookup.ini create mode 100644 device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/qos.json.j2 create mode 100644 device/inventec/x86_64-inventec_d6356-r0/custom_led.bin create mode 100644 device/inventec/x86_64-inventec_d6356-r0/linkscan_led_fw.bin create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/modules/gpio-ich.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/modules/lpc_ich.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/modules/pmbus.h create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/platform.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/thermal.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6356.service diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers.json.j2 b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t0.j2 b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..1587625a294e --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t0.j2 @@ -0,0 +1,50 @@ +{%- set default_cable = '40m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,47) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} + {% for port_idx in range(12,19) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10443264", + "type": "ingress", + "mode": "dynamic", + "xoff": "7335744" + }, + "egress_lossy_pool": { + "size": "8877440", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} + diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t1.j2 b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..1587625a294e --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t1.j2 @@ -0,0 +1,50 @@ +{%- set default_cable = '40m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,47) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} + {% for port_idx in range(12,19) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10443264", + "type": "ingress", + "mode": "dynamic", + "xoff": "7335744" + }, + "egress_lossy_pool": { + "size": "8877440", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} + diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/pg_profile_lookup.ini b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/pg_profile_lookup.ini new file mode 100644 index 000000000000..7222f8014925 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -4 2288 + 25000 5m 1248 2288 53248 -4 2288 + 40000 5m 1248 2288 66560 -4 2288 + 50000 5m 1248 2288 79872 -4 2288 + 100000 5m 1248 2288 165568 -4 2288 + 10000 40m 1248 2288 37024 -4 2288 + 25000 40m 1248 2288 56160 -4 2288 + 40000 40m 1248 2288 71552 -4 2288 + 50000 40m 1248 2288 85696 -4 2288 + 100000 40m 1248 2288 177632 -4 2288 + 10000 300m 1248 2288 46176 -4 2288 + 25000 300m 1248 2288 79040 -4 2288 + 40000 300m 1248 2288 108160 -4 2288 + 50000 300m 1248 2288 131456 -4 2288 + 100000 300m 1248 2288 268736 -4 2288 diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/port_config.ini b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/port_config.ini index ba13dd5743bc..aaac478ab8fd 100755 --- a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/port_config.ini +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/port_config.ini @@ -1,57 +1,57 @@ -# name lanes alias index -Ethernet0 1 Ethernet0 0 -Ethernet1 2 Ethernet1 1 -Ethernet2 3 Ethernet2 2 -Ethernet3 4 Ethernet3 3 -Ethernet4 5 Ethernet4 4 -Ethernet5 6 Ethernet5 5 -Ethernet6 7 Ethernet6 6 -Ethernet7 8 Ethernet7 7 -Ethernet8 13 Ethernet8 8 -Ethernet9 14 Ethernet9 9 -Ethernet10 15 Ethernet10 10 -Ethernet11 16 Ethernet11 11 -Ethernet12 21 Ethernet12 12 -Ethernet13 22 Ethernet13 13 -Ethernet14 23 Ethernet14 14 -Ethernet15 24 Ethernet15 15 -Ethernet16 29 Ethernet16 16 -Ethernet17 30 Ethernet17 17 -Ethernet18 31 Ethernet18 18 -Ethernet19 32 Ethernet19 19 -Ethernet20 33 Ethernet20 20 -Ethernet21 34 Ethernet21 21 -Ethernet22 35 Ethernet22 22 -Ethernet23 36 Ethernet23 23 -Ethernet24 41 Ethernet24 24 -Ethernet25 42 Ethernet25 25 -Ethernet26 43 Ethernet26 26 -Ethernet27 44 Ethernet27 27 -Ethernet28 49 Ethernet28 28 -Ethernet29 50 Ethernet29 29 -Ethernet30 51 Ethernet30 30 -Ethernet31 52 Ethernet31 31 -Ethernet32 57 Ethernet32 32 -Ethernet33 58 Ethernet33 33 -Ethernet34 59 Ethernet34 34 -Ethernet35 60 Ethernet35 35 -Ethernet36 61 Ethernet36 36 -Ethernet37 62 Ethernet37 37 -Ethernet38 63 Ethernet38 38 -Ethernet39 64 Ethernet39 39 -Ethernet40 65 Ethernet40 40 -Ethernet41 66 Ethernet41 41 -Ethernet42 67 Ethernet42 42 -Ethernet43 68 Ethernet43 43 -Ethernet44 69 Ethernet44 44 -Ethernet45 70 Ethernet45 45 -Ethernet46 71 Ethernet46 46 -Ethernet47 72 Ethernet47 47 -Ethernet48 85,86,87,88 Ethernet48 48 -Ethernet52 77,78,79,80 Ethernet52 49 -Ethernet56 93,94,95,96 Ethernet56 50 -Ethernet60 97,98,99,100 Ethernet60 51 -Ethernet64 113,114,115,116 Ethernet64 52 -Ethernet68 105,106,107,108 Ethernet68 53 -Ethernet72 121,122,123,124 Ethernet72 54 -Ethernet76 125,126,127,128 Ethernet76 55 +# name lanes alias index speed +Ethernet0 1 Ethernet0 0 25000 +Ethernet1 2 Ethernet1 1 25000 +Ethernet2 3 Ethernet2 2 25000 +Ethernet3 4 Ethernet3 3 25000 +Ethernet4 5 Ethernet4 4 25000 +Ethernet5 6 Ethernet5 5 25000 +Ethernet6 7 Ethernet6 6 25000 +Ethernet7 8 Ethernet7 7 25000 +Ethernet8 13 Ethernet8 8 25000 +Ethernet9 14 Ethernet9 9 25000 +Ethernet10 15 Ethernet10 10 25000 +Ethernet11 16 Ethernet11 11 25000 +Ethernet12 21 Ethernet12 12 25000 +Ethernet13 22 Ethernet13 13 25000 +Ethernet14 23 Ethernet14 14 25000 +Ethernet15 24 Ethernet15 15 25000 +Ethernet16 29 Ethernet16 16 25000 +Ethernet17 30 Ethernet17 17 25000 +Ethernet18 31 Ethernet18 18 25000 +Ethernet19 32 Ethernet19 19 25000 +Ethernet20 33 Ethernet20 20 25000 +Ethernet21 34 Ethernet21 21 25000 +Ethernet22 35 Ethernet22 22 25000 +Ethernet23 36 Ethernet23 23 25000 +Ethernet24 41 Ethernet24 24 25000 +Ethernet25 42 Ethernet25 25 25000 +Ethernet26 43 Ethernet26 26 25000 +Ethernet27 44 Ethernet27 27 25000 +Ethernet28 49 Ethernet28 28 25000 +Ethernet29 50 Ethernet29 29 25000 +Ethernet30 51 Ethernet30 30 25000 +Ethernet31 52 Ethernet31 31 25000 +Ethernet32 57 Ethernet32 32 25000 +Ethernet33 58 Ethernet33 33 25000 +Ethernet34 59 Ethernet34 34 25000 +Ethernet35 60 Ethernet35 35 25000 +Ethernet36 61 Ethernet36 36 25000 +Ethernet37 62 Ethernet37 37 25000 +Ethernet38 63 Ethernet38 38 25000 +Ethernet39 64 Ethernet39 39 25000 +Ethernet40 65 Ethernet40 40 25000 +Ethernet41 66 Ethernet41 41 25000 +Ethernet42 67 Ethernet42 42 25000 +Ethernet43 68 Ethernet43 43 25000 +Ethernet44 69 Ethernet44 44 25000 +Ethernet45 70 Ethernet45 45 25000 +Ethernet46 71 Ethernet46 46 25000 +Ethernet47 72 Ethernet47 47 25000 +Ethernet48 85,86,87,88 Ethernet48 48 100000 +Ethernet52 77,78,79,80 Ethernet52 49 100000 +Ethernet56 93,94,95,96 Ethernet56 50 100000 +Ethernet60 97,98,99,100 Ethernet60 51 100000 +Ethernet64 113,114,115,116 Ethernet64 52 100000 +Ethernet68 105,106,107,108 Ethernet68 53 100000 +Ethernet72 121,122,123,124 Ethernet72 54 100000 +Ethernet76 125,126,127,128 Ethernet76 55 100000 diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/qos.json.j2 b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/qos.json.j2 new file mode 100644 index 000000000000..d3cac04f662a --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/qos.json.j2 @@ -0,0 +1,155 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"312000", + "red_min_threshold":"104000", + "yellow_max_threshold":"312000", + "yellow_min_threshold":"104000", + "green_max_threshold": "312000", + "green_min_threshold": "104000" + } + }, + "QUEUE": { + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|3-4" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|0" : { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|1" : { + "scheduler" : "[SCHEDULER|scheduler.2]" + } + } +} diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/td3-d6356-48x25G-8x100G.config.bcm b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/td3-d6356-48x25G-8x100G.config.bcm index f6fc4f02f1ef..57fd5cd57164 100644 --- a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/td3-d6356-48x25G-8x100G.config.bcm +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/td3-d6356-48x25G-8x100G.config.bcm @@ -2,8 +2,10 @@ ptp_ts_pll_fref=50000000 ptp_bs_fref_0=50000000 ptp_bs_fref_1=50000000 +ifp_inports_support_enable=1 ### end fix +stable_size=0x5500000 core_clock_frequency=1525 dpp_clock_ratio=2:3 @@ -12,7 +14,7 @@ oversubscribe_mode=1 pbmp_xport_xe=0x488787878808787fdfe1e1e1fe1e1e1fe -portmap_65=130:10 +#portmap_65=130:10 ### Pipeline0, halfpipe 0 (12x25G + 2x100G) portmap_1=1:25 @@ -60,11 +62,11 @@ portmap_64=64:25 ### Pipeline 1 ### First management port -portmap_66=129:10:m +#portmap_66=129:10:m ### Second management port -portmap_130=128:10:m +#portmap_130=128:10:m ### Loopback port -portmap_131=131:10 +#portmap_131=131:10 ### Pipeline 1, halfpipe 0 (12x25G + 2x100G) portmap_67=65:25 @@ -92,6 +94,11 @@ fpem_mem_entries=16384 l2xmsg_mode=1 + +pdma_descriptor_prefetch_enable=1 + +port_flex_enable=1 + #dport part dport_map_port_79=87 dport_map_port_87=79 @@ -281,118 +288,125 @@ phy_chain_tx_polarity_flip_physical{132.0}=0x0 phy_chain_rx_polarity_flip_physical{132.0}=0x0 # EQ/IDriver -serdes_preemphasis_1=0x13460B -serdes_preemphasis_2=0x13460B -serdes_preemphasis_3=0x14450B -serdes_preemphasis_4=0x13460B -serdes_preemphasis_5=0x11480B -serdes_preemphasis_6=0x13470A -serdes_preemphasis_7=0x14460A -serdes_preemphasis_8=0x11490A -serdes_preemphasis_13=0x10490B -serdes_preemphasis_14=0x104A0A -serdes_preemphasis_15=0x0F4B0A -serdes_preemphasis_16=0x0F4B0A -serdes_preemphasis_21=0x0D4D0A -serdes_preemphasis_22=0x0D4D0A -serdes_preemphasis_23=0x0D4D0A -serdes_preemphasis_24=0x0D4D0A -serdes_preemphasis_29=0x0B4F0A -serdes_preemphasis_30=0x0D4E09 -serdes_preemphasis_31=0x0B4F0A -serdes_preemphasis_32=0x0C4F09 -serdes_preemphasis_33=0x0B4F0A -serdes_preemphasis_34=0x0A5109 -serdes_preemphasis_35=0x09510A -serdes_preemphasis_36=0x0B5009 -serdes_preemphasis_41=0x09510A -serdes_preemphasis_42=0x0B5009 -serdes_preemphasis_43=0x09510A -serdes_preemphasis_44=0x0A5109 -serdes_preemphasis_49=0x0A500A -serdes_preemphasis_50=0x0B4F0A -serdes_preemphasis_51=0x09510A -serdes_preemphasis_52=0x0E4C0A -serdes_preemphasis_57=0x0D4D0A -serdes_preemphasis_58=0x0E4D09 -serdes_preemphasis_59=0x0C4E0A -serdes_preemphasis_60=0x0E4D09 -serdes_preemphasis_61=0x0B4F0A -serdes_preemphasis_62=0x0D4E09 -serdes_preemphasis_63=0x0D4D0A -serdes_preemphasis_64=0x0D4D0A -serdes_preemphasis_67=0x0B4F0A -serdes_preemphasis_68=0x0C4E0A -serdes_preemphasis_69=0x0B4F0A -serdes_preemphasis_70=0x0B4F0A -serdes_preemphasis_71=0x0B4F0A -serdes_preemphasis_72=0x0F4B0A -serdes_preemphasis_73=0x0E4C0A -serdes_preemphasis_74=0x0F4B0A -serdes_preemphasis_87=0x0E4C0A -serdes_preemphasis_79=0x0F4B0A -serdes_preemphasis_95=0x0F4B0A -serdes_preemphasis_99=0x0F4B0A -serdes_preemphasis_115=0x13470A -serdes_preemphasis_107=0x12480A -serdes_preemphasis_123=0x154609 -serdes_preemphasis_127=0x13470A +# 25G +serdes_preemphasis_1=0x0F4B0A +serdes_preemphasis_2=0x104A0A +serdes_preemphasis_3=0x0E4C0A +serdes_preemphasis_4=0x0E4C0A +serdes_preemphasis_5=0x0D4D0A +serdes_preemphasis_6=0x0D4D0A +serdes_preemphasis_7=0x0D4D0A +serdes_preemphasis_8=0x0D4D0A +serdes_preemphasis_13=0x0C4E0A +serdes_preemphasis_14=0x0D4D0A +serdes_preemphasis_15=0x0B4F0A +serdes_preemphasis_16=0x0C4E0A +serdes_preemphasis_21=0x0A500A +serdes_preemphasis_22=0x0A500A +serdes_preemphasis_23=0x09510A +serdes_preemphasis_24=0x09510A +serdes_preemphasis_29=0x08520A +serdes_preemphasis_30=0x08520A +serdes_preemphasis_31=0x07530A +serdes_preemphasis_32=0x07530A +serdes_preemphasis_33=0x06540A +serdes_preemphasis_34=0x07530A +serdes_preemphasis_35=0x05550A +serdes_preemphasis_36=0x06540A +serdes_preemphasis_41=0x05550A +serdes_preemphasis_42=0x06540A +serdes_preemphasis_43=0x05550A +serdes_preemphasis_44=0x05550A +serdes_preemphasis_49=0x04560A +serdes_preemphasis_50=0x05550A +serdes_preemphasis_51=0x05550A +serdes_preemphasis_52=0x06540A +serdes_preemphasis_57=0x06540A +serdes_preemphasis_58=0x07530A +serdes_preemphasis_59=0x06540A +serdes_preemphasis_60=0x07530A +serdes_preemphasis_61=0x06540A +serdes_preemphasis_62=0x08520A +serdes_preemphasis_63=0x08520A +serdes_preemphasis_64=0x09510A +serdes_preemphasis_67=0x06540A +serdes_preemphasis_68=0x06540A +serdes_preemphasis_69=0x06540A +serdes_preemphasis_70=0x08520A +serdes_preemphasis_71=0x09510A +serdes_preemphasis_72=0x09510A +serdes_preemphasis_73=0x09510A +serdes_preemphasis_74=0x0A500A +serdes_preemphasis_lane0_87=0x07530A +serdes_preemphasis_lane1_87=0x05550A +serdes_preemphasis_lane2_87=0x07530A +serdes_preemphasis_lane3_87=0x05550A +serdes_preemphasis_79=0x05550A +serdes_preemphasis_95=0x07530A +serdes_preemphasis_lane0_99=0x085309 +serdes_preemphasis_lane1_99=0x0B4F0A +serdes_preemphasis_lane2_99=0x085309 +serdes_preemphasis_lane3_99=0x0B4F0A +serdes_preemphasis_115=0x0B4F0A +serdes_preemphasis_107=0x0B4F0A +serdes_preemphasis_123=0x0B4F0A +serdes_preemphasis_127=0x0D4E09 +# 10G # interface type -serdes_if_type_1=13 -serdes_if_type_2=13 -serdes_if_type_3=13 -serdes_if_type_4=13 -serdes_if_type_5=13 -serdes_if_type_6=13 -serdes_if_type_7=13 -serdes_if_type_8=13 -serdes_if_type_13=13 -serdes_if_type_14=13 -serdes_if_type_15=13 -serdes_if_type_16=13 -serdes_if_type_21=13 -serdes_if_type_22=13 -serdes_if_type_23=13 -serdes_if_type_24=13 -serdes_if_type_29=13 -serdes_if_type_30=13 -serdes_if_type_31=13 -serdes_if_type_32=13 -serdes_if_type_33=13 -serdes_if_type_34=13 -serdes_if_type_35=13 -serdes_if_type_36=13 -serdes_if_type_41=13 -serdes_if_type_42=13 -serdes_if_type_43=13 -serdes_if_type_44=13 -serdes_if_type_49=13 -serdes_if_type_50=13 -serdes_if_type_51=13 -serdes_if_type_52=13 -serdes_if_type_57=13 -serdes_if_type_58=13 -serdes_if_type_59=13 -serdes_if_type_60=13 -serdes_if_type_61=13 -serdes_if_type_62=13 -serdes_if_type_63=13 -serdes_if_type_64=13 -serdes_if_type_67=13 -serdes_if_type_68=13 -serdes_if_type_69=13 -serdes_if_type_70=13 -serdes_if_type_71=13 -serdes_if_type_72=13 -serdes_if_type_73=13 -serdes_if_type_74=13 -serdes_if_type_87=14 -serdes_if_type_79=14 -serdes_if_type_95=14 -serdes_if_type_99=14 -serdes_if_type_115=14 -serdes_if_type_107=14 -serdes_if_type_123=14 -serdes_if_type_127=14 - +serdes_if_type_1=16 +serdes_if_type_2=16 +serdes_if_type_3=16 +serdes_if_type_4=16 +serdes_if_type_5=16 +serdes_if_type_6=16 +serdes_if_type_7=16 +serdes_if_type_8=16 +serdes_if_type_13=16 +serdes_if_type_14=16 +serdes_if_type_15=16 +serdes_if_type_16=16 +serdes_if_type_21=16 +serdes_if_type_22=16 +serdes_if_type_23=16 +serdes_if_type_24=16 +serdes_if_type_29=16 +serdes_if_type_30=16 +serdes_if_type_31=16 +serdes_if_type_32=16 +serdes_if_type_33=16 +serdes_if_type_34=16 +serdes_if_type_35=16 +serdes_if_type_36=16 +serdes_if_type_41=16 +serdes_if_type_42=16 +serdes_if_type_43=16 +serdes_if_type_44=16 +serdes_if_type_49=16 +serdes_if_type_50=16 +serdes_if_type_51=16 +serdes_if_type_52=16 +serdes_if_type_57=16 +serdes_if_type_58=16 +serdes_if_type_59=16 +serdes_if_type_60=16 +serdes_if_type_61=16 +serdes_if_type_62=16 +serdes_if_type_63=16 +serdes_if_type_64=16 +serdes_if_type_67=16 +serdes_if_type_68=16 +serdes_if_type_69=16 +serdes_if_type_70=16 +serdes_if_type_71=16 +serdes_if_type_72=16 +serdes_if_type_73=16 +serdes_if_type_74=16 +serdes_if_type_87=28 +serdes_if_type_79=28 +serdes_if_type_95=28 +serdes_if_type_99=28 +serdes_if_type_115=28 +serdes_if_type_107=28 +serdes_if_type_123=28 +serdes_if_type_127=28 diff --git a/device/inventec/x86_64-inventec_d6356-r0/custom_led.bin b/device/inventec/x86_64-inventec_d6356-r0/custom_led.bin new file mode 100644 index 0000000000000000000000000000000000000000..237c2a1a4c32e9774997a42e36661528a0b42a79 GIT binary patch literal 552 zcmeycHQp`E&DYJv?ZXxZWp*XUj8j1@#uD1UF5Ut1TrwU3d0&9MS|0|*T7O0*X4RE$ zY-$_an3QL^F{-X{>vm&*z^=o1gUNcK zaUjbC%o4iU%fObgKDt5G)`{Ul_k&oswv6%^R(+<6>29{pYd5hPO=57%m>N7wX3{2i z&4m|z6dP2T)pxkDDbI0ZQd#K6sK%ha%dLA;6i{A9#>ZyKCT1O`8&WdjK=;VVgn;>s zH&np97$6VicL*;7MXmtKGXSfsfU1P>0>E+_H)UiZz$|4TD+SDw1F~|!EXkWC*0VP; zYm46OW?;{_6Rql`b1~ShJ)y|**U2xi9z{r(&6O8DLfBc-Td6_fFYFsJk%}sd9s_k jo4V8ai{5T$pWE!2;5O53k=tsw4|@-|{ru0s@B@eeGVH;d literal 0 HcmV?d00001 diff --git a/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc b/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc index d4c2fde64f9c..01b49772c0ba 100644 --- a/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc +++ b/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc @@ -1,5 +1,5 @@ -led auto off -led stop +#led auto off +#led stop m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin led auto on diff --git a/device/inventec/x86_64-inventec_d6356-r0/linkscan_led_fw.bin b/device/inventec/x86_64-inventec_d6356-r0/linkscan_led_fw.bin new file mode 100644 index 0000000000000000000000000000000000000000..e9d763ad98b22a06834cb2d6874287d36b122931 GIT binary patch literal 4744 zcmaJ_4|o&Dm4CY{$t(Yrjg!bmHY?fKD~BX9arv7jYb}f=V>`m-%PD`jZ)KdYGLR~5 z;?nCMY)HWlNn;W&C)1>DDBp!ENzQOlueqW_CRdKoTyJeRUjyph>8`zqYf@Nhf`lw< z@2%vJw3n;=&CJ`G`Mr5F@6Wt3gaEn$Ab@2HmOu4-_)~*hksihp{8V8)-y)RiOM?eG zHd8o&ymQHq{{U8cz&(jTquhB6|nr< z4uAwCJV#aUc5_#+7HeJT{?ZvWJe#&i7hPQ*0QexXjI{IyvWgo_`dWK{zwNuk2xDvV2 zy?cU}fu|JUa#5q*On=}3Rn|WA0w?&p9nTpqN*f16I4_JAjaCFDi<3HUu?M9XRQsXM z;)esEIy7joCx+RliLr?uk9V)29}~N4e0Ff$FFtCmBz*H%#m9Zk*2k>(O7u(5NI#Pv zCS?Iw`b?m#ueGvhzS*0Fr;B7Az0Q-8W zJ)os(wWZQ4Nt&?45}EXRQUCOe0kvSs%ik&f#M^82+1tf0Snm&llU9uRF>p|gynUm1 zzqQxa6`)(vaZA(^Io{bTANT~{*hov_u`X~xjju5vE+T?e$Fw76LmmU1jsj;z{BT#l z{Ia`b+L*_Dx2u27(Bm$=;9?q{(I&ExNO#8*>H-IB%^)=it3fA5Ir~54= z)S=G}br>C0v`^gMIb`)YHsa{VJ^OC-@UBqDY{Ue6CiZ%$u?pp*pdoyRyj^BpFm}>i zISuMx<)B8W`?1?NLvezg?>{e&~CkbIt z|0363X9%~DCkb%Hi9N8D%=uq|nT>Y_`)z{l2X2_68%Nx~pOIz3+8Wf)9Mq+`5t}Sg zVag6ND^laE1l*bAY-Hbr5m@C?uuTrhPr6N06s~MWIdpk4Nn>*m*DxJC3@7}1;GC}| zDA@XKhx04^*gZQ#hlilr1?snR>^SOQGAq>%M5u-w8>SCYvXT2`O=*HgUcX5Ge>_~W zGZ?EWNI5+}VslBRa5R~Y6hSpHD{zn{WrTI*f}rN++v|WU&7V~|x+cHdf-Jk?hyEYH z?|maE6NH`e5VZP$OGi_Y=APZS!z$%+kQx8Fyh>(Usj(;BaDXMc4&I%I8fsjq8*v*@ z3rwE#+N7?7vb+vHhdOv`o*EC->RRCQTDZKRg}R^lsug>d%I#`_84O_?|ltVu! zT@wY_;Lw=+%FI{glEfyA8>LvX_W(SDF?8&fMrLFYz=+kkpru~i|4!7B;m{B;iPe5@ z5%Y_|dbs`ilpz7P(+b$BaN#^JzP|_N{7=K8jkgB9xYizBCmeid9Q6*|`S;a`fs9V9 zLjR1-8)1z?)ftiAI`1SFY`0*`wz5e5`8;qGd6eu1!FJro@|id%-$^Db1fU!+HU`c9 zUfV9H5SREk|6~Q*^3e=5ejnOvs#{%tQ16-Vx3SBv#sACWB!IDMZ_Yq?)c-^C9MP>v z_vcK~5{YjB&PHg$wGG1qKEc+9D_uvgo{hXb!8F>#zY&2qC{PD#={&{L3P&0cZ4aZj zsLVXa)8}=2yo#FHK}=*AWqmX+D}#LQ;m{&2M?w9E zEPD*S{q82|AuFI$6lGYkVbqafp}J;1%%&8--Q zVxld7V)+mKTX1ZV@MT>8Y8)EEaHP{fz^=7D(RP#n2zj}yj~wxTuk#MVEwA!73pbP7 zg@44@eyC@Yz^yneF86tD%bg#@U+`LA<66!B2W?Itduu#SaRHnpV}sDq#kKYOZDND)xKH%4EtlfZ_%hDH*+=zx#Q!3>XM;rQ z{4x>!F0zEI6nJ5un^86kUnIxGulagy%UgaImxTQjNGg z&f(=jJHBM4|a|h2bj|17EEy>eA!< zn}|wB?ZkzMfm~UlK$$gmfojp11!_IYHl_RqbB#ufFPqi_2A5WfLz>5u)iiAxwxLL) z7n(wT{iX)H&UJa#P;a=Pdub?2**{8B`L)Kfi@WWFm-HFWXBi?(*3QD(f0i}Y8!r^- z6G=uXw49cDbxupYgR)djaTr_n%$dEwk4VLe*=xpJjm>8U?E%K#E@`P! z+?^$=$3k7^17-jlwrjBsMe@}$>I^oW*TK$auc zinISZqvJq5j2wnftkG9jr_zYQ_V5B~6j32uui90Hkqy+RaRpG%rVCO%n{lEHT53?! zcWEL;MBgDa>O1^OhO&>+57)!kh#O{>5q*z4GD2s&cTeq@`wpe#SH=7irJv`NZ#br5 zsFqXKVs=tGwIs2oGi-GzL)Hf6bDh2JA*5I0h(lRMTJt;Jv~U)fy+-jC2vZ3N(+>Bh z%Si^mGD!p0siYC>t4R~qSCU0oUrMrAe~>g|eGwxP*x^7BW&f8sLw!Y@X@ZxoiEx`) z;Ze?-30qc@H4G}GM zNgFkoON9p@s(&T(U+!Lr+B~o`)KTkYLwX%6GRx=WUbYuv6|{Ix3U%Cs9v+ipMX`!d zN0m2bGRsc|d(FL6teh5~!dFn4ryp}J*rw0G?0w2xKQ|TXD9ZN=f7FZb3JqZ0!amf< zOPx!Wo{`5l9O`<_ctD2RYn1zTQq6aZ_l1grBzSG{pzRIv^WZ6Cy|An7ZgDHwWo!~o z72hrXJg_hLx~Q3UnRWV1uz;is$N@4?K$Z{uUu1dTzJZUC<$Y%c3P?i%xs7ZqAbUOo z+0(ag+sDYBzBAhjNH&k`*lyZ>YVj`HN%HK#kBm!%!LpU&BV^FnEc~c=rTA>$-tB)Y zUNa4vb^6Tq0@6}ga|hXRl3ZK-uLFa&wZc|%%DAg+tseJ{M~WN7pY;vxI3~tSf|)_O zccgd2S@}7mRj4Ynh-W1=n!~8n)dOSHn1Q%LS}L3C?B*p3BULIVOCHZr$O3a@~M&6X~#)I&_^Qx#)!4+&L+)7Au7>jXY

u_quO?Wpl+sVg~YruZ;-_w%+>d)1i*(6I6o6FZ2xj z0>?GX7!CMltkg3`^#045E*;b{cA=ixSw+{1-umnB>aQ_|Fb+24wLx)jedb*&_L%T3 zYU(j2IPz<`=5}MhUq%8W%GmZYpd&| zwF6^E1o#G}Y6C0*M~%!RhTY72#l$Ov^ZFFD6f2A5Cu?7H8>T?ES}l@=&jCPo@b_3Exh>EsHxNBu}G%Qs@iFG8rH=qZk6=Qq!0P) zYZ!cx|DOz0Gf9BxVKePAKo&O7828b;H literal 0 HcmV?d00001 diff --git a/device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py b/device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py index 8ed0bce72979..732650ffe638 100755 --- a/device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py +++ b/device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py @@ -15,7 +15,7 @@ class PsuUtil(PsuBase): """Platform-specific PSUutil class""" - PSU_DIR = "/sys/class/hwmon/hwmon1" + PSU_DIR = "/sys/class/hwmon/hwmon2/device/" def __init__(self): PsuBase.__init__(self) @@ -53,9 +53,12 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psoc_psu'+ str(index) + '_iout' - attr_path = self.PSU_DIR +'/' + attr_file + if index == 1 : + attr_path = "/sys/class/hwmon/hwmon7/in1_input" + else : + attr_path = "/sys/class/hwmon/hwmon8/in1_input" + attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU status @@ -75,10 +78,11 @@ def get_psu_presence(self, index): ind = index attr_file ='psu'+ str(ind) attr_path = self.PSU_DIR +'/' + attr_file - normal_attr_value = '0 : normal' + normal_attr_value = '1:normal' attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU presence if (attr_value == normal_attr_value): status = 1 return status + diff --git a/device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py b/device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py index 5ea81ffcfc16..116a3d9acbc9 100755 --- a/device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py +++ b/device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py @@ -3,12 +3,78 @@ # Platform-specific SFP transceiver interface for SONiC # +# +# INV_FIX-4037 +# (1) Support get_transceiver_change_event. +# Create the SWPSEventMonitor class to handle any kobject event from the SWPS driver. +# (2) Integrated with the optoe driver +# Due to installing the optoe driver to create the i2c topology, +# it needs to overwrite the followings functions which are declared in the sfputilbase.py. +# First, it needs to impore some SFP-related class object +# try: import time + import socket, re,os + from collections import OrderedDict from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_sfp.sff8472 import sff8472Dom except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VLOT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 + +NETLINK_KOBJECT_UEVENT = 15 +monitor = None + +class SWPSEventMonitor(object): + + def __init__(self): + self.recieved_events = OrderedDict() + self.socket = socket.socket( + socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT) + + def start(self): + self.socket.bind((os.getpid(), -1)) + + def stop(self): + self.socket.close() + + def __enter__(self): + self.start() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.stop() + + def __iter__(self): + global monitor + while True: + for item in monitor.next_events(): + yield item + + def next_events(self): + data = self.socket.recv(16384) + event = {} + for item in data.split(b'\x00'): + if not item: + # check if we have an event and if we already received it + if event and event['SEQNUM'] not in self.recieved_events: + self.recieved_events[event['SEQNUM']] = None + if (len(self.recieved_events) > 100): + self.recieved_events.popitem(last=False) + yield event + event = {} + else: + try: + k, v = item.split(b'=', 1) + event[k.decode('ascii')] = v.decode('ascii') + except ValueError: + pass class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -210,8 +276,104 @@ def reset(self, port_num): return True +# +# INV_FIX-4037 +# (1) Support get_transceiver_change_event. +# Modify get_transceiver_change_event() to listen the SWPS kobject event. +# (2) Integrated with the optoe driver +# Due to installing the optoe driver to create the i2c topology, +# it needs to overwrite the followings functions which are declared in the sfputilbase.py. +# It modified the get_eeprom_dom_raw() and get_transceiver_dom_info_dict(). +# def get_transceiver_change_event(self): - """ - TODO: This function need to be implemented - """ - raise NotImplementedError + global monitor + port_dict = {} + with SWPSEventMonitor() as monitor: + for event in monitor: + if event['SUBSYSTEM'] == 'swps': + #print('SWPS event. From %s, ACTION %s, IF_TYPE %s, IF_LANE %s' % (event['DEVPATH'], event['ACTION'], event['IF_TYPE'], event['IF_LANE'])) + portname = event['DEVPATH'].split("/")[-1] + rc = re.match(r"port(?P\d+)",portname) + if rc is not None: + if event['ACTION'] == "remove": + remove_num = int(rc.group("num")) + port_dict[remove_num] = "0" + #port_dict[rc.group("num")] = "0" + if event['ACTION'] == "add": + add_num = int(rc.group("num")) + port_dict[add_num] = "1" + #port_dict[rc.group("num")] = "1" + return True, port_dict + return False, {} + + def get_eeprom_dom_raw(self, port_num): + if port_num in self.qsfp_ports: + # QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw + return None + else: + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.DOM_EEPROM_ADDR, 256) + + def get_transceiver_dom_info_dict(self, port_num): + if port_num in self.qsfp_ports: + return SfpUtilBase.get_transceiver_dom_info_dict(self, port_num) + else: + transceiver_dom_info_dict = {} + + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = open(file_path, "rb") + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None, 1) + if sfpd_obj is None: + return None + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return None + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + + diff --git a/device/inventec/x86_64-inventec_d6356-r0/sensors.conf b/device/inventec/x86_64-inventec_d6356-r0/sensors.conf index 6f7318168ee6..3a056f7ca99f 100644 --- a/device/inventec/x86_64-inventec_d6356-r0/sensors.conf +++ b/device/inventec/x86_64-inventec_d6356-r0/sensors.conf @@ -2,6 +2,9 @@ chip "ucd90160-*" ignore temp1 +chip "pch_haswell-*" + label temp1 "PCH Temperature" + chip "tmp75-i2c-*-0048" label temp1 "CPU Board Temperature" @@ -31,7 +34,7 @@ chip "inv_cpld-i2c-*-77" label pwm4 "FanModule4 PWM (0-255)" label pwm5 "FanModule5 PWM (0-255)" -chip "pmbus-i2c-*-005a" +chip "pmbus-i2c-*-005b" ignore power3 ignore curr3 label fan1 "PSU1 Fan RPM" @@ -46,7 +49,7 @@ chip "pmbus-i2c-*-005a" label power2 "PSU1 Output Power" label pwm1 "PSU1 PWM (0-100)" -chip "pmbus-i2c-*-005b" +chip "pmbus-i2c-*-005a" ignore power3 ignore curr3 label fan1 "PSU2 Fan RPM" diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/Makefile b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/Makefile index 23e8295b9026..6c1acbc88a71 100755 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/Makefile @@ -1,3 +1,7 @@ +obj-m += ucd9000.o +obj-m += i2c-mux-pca9541.o +obj-m += gpio-ich.o +obj-m += lpc_ich.o obj-m += inv_cpld.o obj-m += inv_platform.o obj-m += inv_eeprom.o diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/gpio-ich.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/gpio-ich.c new file mode 100644 index 000000000000..4f6d643516b7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/gpio-ich.c @@ -0,0 +1,513 @@ +/* + * Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver + * + * Copyright (C) 2010 Extreme Engineering Solutions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "gpio_ich" + +/* + * GPIO register offsets in GPIO I/O space. + * Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and + * LVLx registers. Logic in the read/write functions takes a register and + * an absolute bit number and determines the proper register offset and bit + * number in that register. For example, to read the value of GPIO bit 50 + * the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)], + * bit 18 (50%32). + */ +enum GPIO_REG { + GPIO_USE_SEL = 0, + GPIO_IO_SEL, + GPIO_LVL, + GPO_BLINK +}; + +static const u8 ichx_regs[4][3] = { + {0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */ + {0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */ + {0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */ + {0x18, 0x18, 0x18}, /* BLINK offset */ +}; + +static const u8 ichx_reglen[3] = { + 0x30, 0x10, 0x10, +}; + +static const u8 avoton_regs[4][3] = { + {0x00, 0x80, 0x00}, + {0x04, 0x84, 0x00}, + {0x08, 0x88, 0x00}, +}; + +static const u8 avoton_reglen[3] = { + 0x10, 0x10, 0x00, +}; + +#define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start) +#define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start) + +struct ichx_desc { + /* Max GPIO pins the chipset can have */ + uint ngpio; + + /* chipset registers */ + const u8 (*regs)[3]; + const u8 *reglen; + + /* GPO_BLINK is available on this chipset */ + bool have_blink; + + /* Whether the chipset has GPIO in GPE0_STS in the PM IO region */ + bool uses_gpe0; + + /* USE_SEL is bogus on some chipsets, eg 3100 */ + u32 use_sel_ignore[3]; + + /* Some chipsets have quirks, let these use their own request/get */ + int (*request)(struct gpio_chip *chip, unsigned offset); + int (*get)(struct gpio_chip *chip, unsigned offset); + + /* + * Some chipsets don't let reading output values on GPIO_LVL register + * this option allows driver caching written output values + */ + bool use_outlvl_cache; +}; + +static struct { + spinlock_t lock; + struct platform_device *dev; + struct gpio_chip chip; + struct resource *gpio_base; /* GPIO IO base */ + struct resource *pm_base; /* Power Mangagment IO base */ + struct ichx_desc *desc; /* Pointer to chipset-specific description */ + u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */ + u8 use_gpio; /* Which GPIO groups are usable */ + int outlvl_cache[3]; /* cached output values */ +} ichx_priv; + +static int modparam_gpiobase = -1; /* dynamic */ +module_param_named(gpiobase, modparam_gpiobase, int, 0444); +MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, " + "which is the default."); + +static int ichx_write_bit(int reg, unsigned nr, int val, int verify) +{ + unsigned long flags; + u32 data, tmp; + int reg_nr = nr / 32; + int bit = nr & 0x1f; + int ret = 0; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + data = ichx_priv.outlvl_cache[reg_nr]; + else + data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + + if (val) + data |= 1 << bit; + else + data &= ~(1 << bit); + ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + ichx_priv.outlvl_cache[reg_nr] = data; + + tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + if (verify && data != tmp) + ret = -EPERM; + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return ret; +} + +static int ichx_read_bit(int reg, unsigned nr) +{ + unsigned long flags; + u32 data; + int reg_nr = nr / 32; + int bit = nr & 0x1f; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + data = ichx_priv.outlvl_cache[reg_nr] | data; + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return data & (1 << bit) ? 1 : 0; +} + +static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr) +{ + return !!(ichx_priv.use_gpio & (1 << (nr / 32))); +} + +static int ichx_gpio_get_direction(struct gpio_chip *gpio, unsigned nr) +{ + return ichx_read_bit(GPIO_IO_SEL, nr) ? GPIOF_DIR_IN : GPIOF_DIR_OUT; +} + +static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) +{ + /* + * Try setting pin as an input and verify it worked since many pins + * are output-only. + */ + if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1)) + return -EINVAL; + + return 0; +} + +static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, + int val) +{ + /* Disable blink hardware which is available for GPIOs from 0 to 31. */ + if (nr < 32 && ichx_priv.desc->have_blink) + ichx_write_bit(GPO_BLINK, nr, 0, 0); + + /* Set GPIO output value. */ + ichx_write_bit(GPIO_LVL, nr, val, 0); + + /* + * Try setting pin as an output and verify it worked since many pins + * are input-only. + */ + if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1)) + return -EINVAL; + + return 0; +} + +static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr) +{ + return ichx_read_bit(GPIO_LVL, nr); +} + +static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr) +{ + unsigned long flags; + u32 data; + + /* + * GPI 0 - 15 need to be read from the power management registers on + * a ICH6/3100 bridge. + */ + if (nr < 16) { + if (!ichx_priv.pm_base) + return -ENXIO; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + /* GPI 0 - 15 are latched, write 1 to clear*/ + ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base); + data = ICHX_READ(0, ichx_priv.pm_base); + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return (data >> 16) & (1 << nr) ? 1 : 0; + } else { + return ichx_gpio_get(chip, nr); + } +} + +static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr) +{ + if (!ichx_gpio_check_available(chip, nr)) + return -ENXIO; + + /* + * Note we assume the BIOS properly set a bridge's USE value. Some + * chips (eg Intel 3100) have bogus USE values though, so first see if + * the chipset's USE value can be trusted for this specific bit. + * If it can't be trusted, assume that the pin can be used as a GPIO. + */ + if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f))) + return 0; + + return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; +} + +static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr) +{ + /* + * Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100 + * bridge as they are controlled by USE register bits 0 and 1. See + * "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for + * additional info. + */ + if (nr == 16 || nr == 17) + nr -= 16; + + return ichx_gpio_request(chip, nr); +} + +static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val) +{ + ichx_write_bit(GPIO_LVL, nr, val, 0); +} + +static void ichx_gpiolib_setup(struct gpio_chip *chip) +{ + chip->owner = THIS_MODULE; + chip->label = DRV_NAME; + chip->parent = &ichx_priv.dev->dev; + + /* Allow chip-specific overrides of request()/get() */ + chip->request = ichx_priv.desc->request ? + ichx_priv.desc->request : ichx_gpio_request; + chip->get = ichx_priv.desc->get ? + ichx_priv.desc->get : ichx_gpio_get; + + chip->set = ichx_gpio_set; + chip->get_direction = ichx_gpio_get_direction; + chip->direction_input = ichx_gpio_direction_input; + chip->direction_output = ichx_gpio_direction_output; + chip->base = modparam_gpiobase; + chip->ngpio = ichx_priv.desc->ngpio; + chip->can_sleep = false; + chip->dbg_show = NULL; +} + +/* ICH6-based, 631xesb-based */ +static struct ichx_desc ich6_desc = { + /* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */ + .request = ich6_gpio_request, + .get = ich6_gpio_get, + + /* GPIO 0-15 are read in the GPE0_STS PM register */ + .uses_gpe0 = true, + + .ngpio = 50, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Intel 3100 */ +static struct ichx_desc i3100_desc = { + /* + * Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on + * the Intel 3100. See "Table 712. GPIO Summary Table" of 3100 + * Datasheet for more info. + */ + .use_sel_ignore = {0x00130000, 0x00010000, 0x0}, + + /* The 3100 needs fixups for GPIO 0 - 17 */ + .request = ich6_gpio_request, + .get = ich6_gpio_get, + + /* GPIO 0-15 are read in the GPE0_STS PM register */ + .uses_gpe0 = true, + + .ngpio = 50, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH7 and ICH8-based */ +static struct ichx_desc ich7_desc = { + .ngpio = 50, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH9-based */ +static struct ichx_desc ich9_desc = { + .ngpio = 61, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH10-based - Consumer/corporate versions have different amount of GPIO */ +static struct ichx_desc ich10_cons_desc = { + .ngpio = 61, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; +static struct ichx_desc ich10_corp_desc = { + .ngpio = 72, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Intel 5 series, 6 series, 3400 series, and C200 series */ +static struct ichx_desc intel5_desc = { + .ngpio = 76, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Avoton */ +static struct ichx_desc avoton_desc = { + /* Avoton has only 59 GPIOs, but we assume the first set of register + * (Core) has 32 instead of 31 to keep gpio-ich compliance + */ + .ngpio = 60, + .regs = avoton_regs, + .reglen = avoton_reglen, + .use_outlvl_cache = true, +}; + +static int ichx_gpio_request_regions(struct device *dev, + struct resource *res_base, const char *name, u8 use_gpio) +{ + int i; + + if (!res_base || !res_base->start || !res_base->end) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) { + if (!(use_gpio & (1 << i))) + continue; + if (!devm_request_region(dev, + res_base->start + ichx_priv.desc->regs[0][i], + ichx_priv.desc->reglen[i], name)) + return -EBUSY; + } + return 0; +} + +static int ichx_gpio_probe(struct platform_device *pdev) +{ + struct resource *res_base, *res_pm; + int err; + struct lpc_ich_info *ich_info = dev_get_platdata(&pdev->dev); + + if (!ich_info) + return -ENODEV; + + ichx_priv.dev = pdev; + + switch (ich_info->gpio_version) { + case ICH_I3100_GPIO: + ichx_priv.desc = &i3100_desc; + break; + case ICH_V5_GPIO: + ichx_priv.desc = &intel5_desc; + break; + case ICH_V6_GPIO: + ichx_priv.desc = &ich6_desc; + break; + case ICH_V7_GPIO: + ichx_priv.desc = &ich7_desc; + break; + case ICH_V9_GPIO: + ichx_priv.desc = &ich9_desc; + break; + case ICH_V10CORP_GPIO: + ichx_priv.desc = &ich10_corp_desc; + break; + case ICH_V10CONS_GPIO: + ichx_priv.desc = &ich10_cons_desc; + break; + case AVOTON_GPIO: + ichx_priv.desc = &avoton_desc; + break; + default: + return -ENODEV; + } + + spin_lock_init(&ichx_priv.lock); + res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); + ichx_priv.use_gpio = ich_info->use_gpio; + err = ichx_gpio_request_regions(&pdev->dev, res_base, pdev->name, + ichx_priv.use_gpio); + if (err) + return err; + + ichx_priv.gpio_base = res_base; + + /* + * If necessary, determine the I/O address of ACPI/power management + * registers which are needed to read the the GPE0 register for GPI pins + * 0 - 15 on some chipsets. + */ + if (!ichx_priv.desc->uses_gpe0) + goto init; + + res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0); + if (!res_pm) { + pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); + goto init; + } + + if (!devm_request_region(&pdev->dev, res_pm->start, + resource_size(res_pm), pdev->name)) { + pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n"); + goto init; + } + + ichx_priv.pm_base = res_pm; + +init: + ichx_gpiolib_setup(&ichx_priv.chip); + err = gpiochip_add_data(&ichx_priv.chip, NULL); + if (err) { + pr_err("Failed to register GPIOs\n"); + return err; + } + + pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base, + ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME); + + return 0; +} + +static int ichx_gpio_remove(struct platform_device *pdev) +{ + gpiochip_remove(&ichx_priv.chip); + + return 0; +} + +static struct platform_driver ichx_gpio_driver = { + .driver = { + .name = DRV_NAME, + }, + .probe = ichx_gpio_probe, + .remove = ichx_gpio_remove, +}; + +module_platform_driver(ichx_gpio_driver); + +MODULE_AUTHOR("Peter Tyser "); +MODULE_DESCRIPTION("GPIO interface for Intel ICH series"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:"DRV_NAME); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c new file mode 100644 index 000000000000..68c44dbc533f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c @@ -0,0 +1,573 @@ +/* + * I2C multiplexer driver for PCA9541 bus master selector + * + * Copyright (c) 2010 Ericsson AB. + * + * Author: Guenter Roeck + * + * Derived from: + * pca954x.c + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * The PCA9541 is a bus master selector. It supports two I2C masters connected + * to a single slave bus. + * + * Before each bus transaction, a master has to acquire bus ownership. After the + * transaction is complete, bus ownership has to be released. This fits well + * into the I2C multiplexer framework, which provides select and release + * functions for this purpose. For this reason, this driver is modeled as + * single-channel I2C bus multiplexer. + * + * This driver assumes that the two bus masters are controlled by two different + * hosts. If a single host controls both masters, platform code has to ensure + * that only one of the masters is instantiated at any given time. + */ + +#define PCA9541_CONTROL 0x01 +#define PCA9541_ISTAT 0x02 + +#define PCA9541_CTL_MYBUS (1 << 0) +#define PCA9541_CTL_NMYBUS (1 << 1) +#define PCA9541_CTL_BUSON (1 << 2) +#define PCA9541_CTL_NBUSON (1 << 3) +#define PCA9541_CTL_BUSINIT (1 << 4) +#define PCA9541_CTL_TESTON (1 << 6) +#define PCA9541_CTL_NTESTON (1 << 7) + +#define PCA9541_ISTAT_INTIN (1 << 0) +#define PCA9541_ISTAT_BUSINIT (1 << 1) +#define PCA9541_ISTAT_BUSOK (1 << 2) +#define PCA9541_ISTAT_BUSLOST (1 << 3) +#define PCA9541_ISTAT_MYTEST (1 << 6) +#define PCA9541_ISTAT_NMYTEST (1 << 7) + +#define PCA9641_ID 0x00 +#define PCA9641_ID_MAGIC 0x38 + +#define PCA9641_CONTROL 0x01 +#define PCA9641_STATUS 0x02 +#define PCA9641_TIME 0x03 + +#define PCA9641_CTL_LOCK_REQ BIT(0) +#define PCA9641_CTL_LOCK_GRANT BIT(1) +#define PCA9641_CTL_BUS_CONNECT BIT(2) +#define PCA9641_CTL_BUS_INIT BIT(3) +#define PCA9641_CTL_SMBUS_SWRST BIT(4) +#define PCA9641_CTL_IDLE_TIMER_DIS BIT(5) +#define PCA9641_CTL_SMBUS_DIS BIT(6) +#define PCA9641_CTL_PRIORITY BIT(7) + +#define PCA9641_STS_OTHER_LOCK BIT(0) +#define PCA9641_STS_BUS_INIT_FAIL BIT(1) +#define PCA9641_STS_BUS_HUNG BIT(2) +#define PCA9641_STS_MBOX_EMPTY BIT(3) +#define PCA9641_STS_MBOX_FULL BIT(4) +#define PCA9641_STS_TEST_INT BIT(5) +#define PCA9641_STS_SCL_IO BIT(6) +#define PCA9641_STS_SDA_IO BIT(7) + +#define PCA9641_RES_TIME 0x03 + + +#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) +#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) +#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS) +#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON) + +#define BUSOFF(x, y) (!((x) & PCA9641_CTL_LOCK_GRANT) && \ + !((y) & PCA9641_STS_OTHER_LOCK)) +#define other_lock(x) ((x) & PCA9641_STS_OTHER_LOCK) +#define lock_grant(x) ((x) & PCA9641_CTL_LOCK_GRANT) + +/* arbitration timeouts, in jiffies */ +#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */ +#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */ + +/* arbitration retry delays, in us */ +#define SELECT_DELAY_SHORT 50 +#define SELECT_DELAY_LONG 1000 + +struct pca9541 { + struct i2c_client *client; + unsigned long select_timeout; + unsigned long arb_timeout; +}; + +static const struct i2c_device_id pca9541_id[] = { + {"pca9541", 0}, + {"pca9641", 1}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, pca9541_id); + +#ifdef CONFIG_OF +static const struct of_device_id pca9541_of_match[] = { + { .compatible = "nxp,pca9541" }, + { .compatible = "nxp,pca9641" }, + {} +}; +#endif + +/* + * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock the adapter a second time. + */ +static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val) +{ + struct i2c_adapter *adap = client->adapter; + int ret; + + if (adap->algo->master_xfer) { + struct i2c_msg msg; + char buf[2]; + + msg.addr = client->addr; + msg.flags = 0; + msg.len = 2; + buf[0] = command; + buf[1] = val; + msg.buf = buf; + ret = __i2c_transfer(adap, &msg, 1); + } else { + union i2c_smbus_data data; + + data.byte = val; + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_WRITE, + command, + I2C_SMBUS_BYTE_DATA, &data); + } + + return ret; +} + +/* + * Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock adapter a second time. + */ +static int pca9541_reg_read(struct i2c_client *client, u8 command) +{ + struct i2c_adapter *adap = client->adapter; + int ret; + u8 val; + + if (adap->algo->master_xfer) { + struct i2c_msg msg[2] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &command + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = 1, + .buf = &val + } + }; + ret = __i2c_transfer(adap, msg, 2); + if (ret == 2) + ret = val; + else if (ret >= 0) + ret = -EIO; + } else { + union i2c_smbus_data data; + + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_READ, + command, + I2C_SMBUS_BYTE_DATA, &data); + if (!ret) + ret = data.byte; + } + return ret; +} + +/* + * Arbitration management functions + */ + +/* Release bus. Also reset NTESTON and BUSINIT if it was set. */ +static void pca9541_release_bus(struct i2c_client *client) +{ + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg >= 0 && !busoff(reg) && mybus(reg)) + pca9541_reg_write(client, PCA9541_CONTROL, + (reg & PCA9541_CTL_NBUSON) >> 1); +} + +/* + * Arbitration is defined as a two-step process. A bus master can only activate + * the slave bus if it owns it; otherwise it has to request ownership first. + * This multi-step process ensures that access contention is resolved + * gracefully. + * + * Bus Ownership Other master Action + * state requested access + * ---------------------------------------------------- + * off - yes wait for arbitration timeout or + * for other master to drop request + * off no no take ownership + * off yes no turn on bus + * on yes - done + * on no - wait for arbitration timeout or + * for other master to release bus + * + * The main contention point occurs if the slave bus is off and both masters + * request ownership at the same time. In this case, one master will turn on + * the slave bus, believing that it owns it. The other master will request + * bus ownership. Result is that the bus is turned on, and master which did + * _not_ own the slave bus before ends up owning it. + */ + +/* Control commands per PCA9541 datasheet */ +static const u8 pca9541_control[16] = { + 4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1 +}; + +/* + * Channel arbitration + * + * Return values: + * <0: error + * 0 : bus not acquired + * 1 : bus acquired + */ +static int pca9541_arbitrate(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca9541 *data = i2c_mux_priv(muxc); + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg < 0) + return reg; + + if (busoff(reg)) { + int istat; + /* + * Bus is off. Request ownership or turn it on unless + * other master requested ownership. + */ + istat = pca9541_reg_read(client, PCA9541_ISTAT); + if (!(istat & PCA9541_ISTAT_NMYTEST) + || time_is_before_eq_jiffies(data->arb_timeout)) { + /* + * Other master did not request ownership, + * or arbitration timeout expired. Take the bus. + */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_NTESTON); + data->select_timeout = SELECT_DELAY_SHORT; + } else { + /* + * Other master requested ownership. + * Set extra long timeout to give it time to acquire it. + */ + data->select_timeout = SELECT_DELAY_LONG * 2; + } + } else if (mybus(reg)) { + /* + * Bus is on, and we own it. We are done with acquisition. + * Reset NTESTON and BUSINIT, then return success. + */ + if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg & ~(PCA9541_CTL_NTESTON + | PCA9541_CTL_BUSINIT)); + return 1; + } else { + /* + * Other master owns the bus. + * If arbitration timeout has expired, force ownership. + * Otherwise request it. + */ + data->select_timeout = SELECT_DELAY_LONG; + if (time_is_before_eq_jiffies(data->arb_timeout)) { + /* Time is up, take the bus and reset it. */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_BUSINIT + | PCA9541_CTL_NTESTON); + } else { + /* Request bus ownership if needed */ + if (!(reg & PCA9541_CTL_NTESTON)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg | PCA9541_CTL_NTESTON); + } + } + return 0; +} + +static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret; + unsigned long timeout = jiffies + ARB2_TIMEOUT; + /* give up after this time */ + + data->arb_timeout = jiffies + ARB_TIMEOUT; + /* force bus ownership after this time */ + + do { + ret = pca9541_arbitrate(client); + if (ret) + return ret < 0 ? ret : 0; + + if (data->select_timeout == SELECT_DELAY_SHORT) + udelay(data->select_timeout); + else + msleep(data->select_timeout / 1000); + } while (time_is_after_eq_jiffies(timeout)); + + return -ETIMEDOUT; +} + +static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + + pca9541_release_bus(client); + return 0; +} + +/* + * Arbitration management functions + */ +static void pca9641_release_bus(struct i2c_client *client) +{ + pca9541_reg_write(client, PCA9641_CONTROL, 0); +} + +/* + * Channel arbitration + * + * Return values: + * <0: error + * 0 : bus not acquired + * 1 : bus acquired + */ +static int pca9641_arbitrate(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca9541 *data = i2c_mux_priv(muxc); + int reg_ctl, reg_sts; + + reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL); + if (reg_ctl < 0) + return reg_ctl; + reg_sts = pca9541_reg_read(client, PCA9641_STATUS); + + if (BUSOFF(reg_ctl, reg_sts)) { + /* + * Bus is off. Request ownership or turn it on unless + * other master requested ownership. + */ + reg_ctl |= PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL); + + if (lock_grant(reg_ctl)) { + /* + * Other master did not request ownership, + * or arbitration timeout expired. Take the bus. + */ + reg_ctl |= PCA9641_CTL_BUS_CONNECT + | PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + data->select_timeout = SELECT_DELAY_SHORT; + + return 1; + } else { + /* + * Other master requested ownership. + * Set extra long timeout to give it time to acquire it. + */ + data->select_timeout = SELECT_DELAY_LONG * 2; + } + } else if (lock_grant(reg_ctl)) { + /* + * Bus is on, and we own it. We are done with acquisition. + */ + reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + + return 1; + } else if (other_lock(reg_sts)) { + /* + * Other master owns the bus. + * If arbitration timeout has expired, force ownership. + * Otherwise request it. + */ + data->select_timeout = SELECT_DELAY_LONG; + reg_ctl |= PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + } + return 0; +} + +static int pca9641_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret; + unsigned long timeout = jiffies + ARB2_TIMEOUT; + /* give up after this time */ + + data->arb_timeout = jiffies + ARB_TIMEOUT; + /* force bus ownership after this time */ + + do { + ret = pca9641_arbitrate(client); + if (ret) + return ret < 0 ? ret : 0; + + if (data->select_timeout == SELECT_DELAY_SHORT) + udelay(data->select_timeout); + else + msleep(data->select_timeout / 1000); + } while (time_is_after_eq_jiffies(timeout)); + + return -ETIMEDOUT; +} + +static int pca9641_release_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + + pca9641_release_bus(client); + return 0; +} + +static int pca9641_detect_id(struct i2c_client *client) +{ + int reg; + + reg = pca9541_reg_read(client, PCA9641_ID); + if (reg == PCA9641_ID_MAGIC) + return 1; + else + return 0; +} + +/* + * I2C init/probing/exit functions + */ +static int pca9541_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = client->adapter; + struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); + struct i2c_mux_core *muxc; + struct pca9541 *data; + int force; + int ret; + int detect_id; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + detect_id = pca9641_detect_id(client); + /* + * I2C accesses are unprotected here. + * We have to lock the adapter before releasing the bus. + */ + if (detect_id == 0) { + i2c_lock_adapter(adap); + pca9541_release_bus(client); + i2c_unlock_adapter(adap); + } else { + i2c_lock_adapter(adap); + pca9641_release_bus(client); + i2c_unlock_adapter(adap); + } + + /* Create mux adapter */ + + force = 0; + if (pdata) + force = pdata->modes[0].adap_id; + if (detect_id == 0) { + muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), + I2C_MUX_ARBITRATOR, + pca9541_select_chan, pca9541_release_chan); + } else { + muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), + I2C_MUX_ARBITRATOR, + pca9641_select_chan, pca9641_release_chan); + } + if (!muxc) + return -ENOMEM; + + data = i2c_mux_priv(muxc); + data->client = client; + + i2c_set_clientdata(client, muxc); + + ret = i2c_mux_add_adapter(muxc, force, 0, 0); + if (ret) { + dev_err(&client->dev, "failed to register master selector\n"); + return ret; + } + + dev_info(&client->dev, "registered master selector for I2C %s\n", + client->name); + + return 0; +} + +static int pca9541_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + i2c_mux_del_adapters(muxc); + return 0; +} + +static struct i2c_driver pca9541_driver = { + .driver = { + .name = "pca9541", + .of_match_table = of_match_ptr(pca9541_of_match), + }, + .probe = pca9541_probe, + .remove = pca9541_remove, + .id_table = pca9541_id, +}; + +module_i2c_driver(pca9541_driver); + +MODULE_AUTHOR("Guenter Roeck "); +MODULE_DESCRIPTION("PCA9541 I2C master selector driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_cpld.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_cpld.c index 8ccaf617b3c4..8e2693d2e251 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_cpld.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_cpld.c @@ -30,6 +30,7 @@ #define CPLD_INFO_OFFSET 0x00 #define CPLD_BIOSCS_OFFSET 0x04 #define CPLD_CTL_OFFSET 0x0C +#define CPLD_SYSLED_OFFSET 0x0E #define CPLD_LED_OFFSET 0x2E #define CPLD_INT_OFFSET 0x30 #define CPLD_INTMASK_OFFSET 0x31 @@ -58,6 +59,7 @@ struct cpld_data { struct device *hwmon_dev; struct mutex update_lock; u8 diag; + struct task_struct *tsk; }; /*-----------------------------------------------------------------------*/ @@ -97,6 +99,7 @@ static ssize_t cpld_i2c_write(struct i2c_client *client, char *buf, unsigned off #define CMD_GETDATA 0x31 #define CMD_SETDATA 0x32 #define IPMI_DIAGFLAG_OFFSET 0x00 +#define IPMI_SWITCHTEMP_OFFSET 0x02 struct ipmi_result{ char result[MAX_IPMI_RECV_LENGTH]; @@ -203,6 +206,30 @@ int start_ipmi_command(char NetFn, char cmd,char *data,int data_length, char* re } EXPORT_SYMBOL(start_ipmi_command); +static int cpld_thread(void *p) +{ +#ifndef XORP + struct i2c_client *client = p; + + u8 byte[9]; + uint8_t result[MAX_IPMI_RECV_LENGTH]; + int result_len=0; + + //Handle LED control by the driver + byte[0]=0x01; + cpld_i2c_write(client, byte, CPLD_CTL_OFFSET, 1); + + //Disable BMC Watchdog + byte[0]=0x04; + byte[1]=0x00; + byte[2]=0x00; + byte[3]=0x00; + byte[4]=0x2C; + byte[5]=0x01; + start_ipmi_command(0x06, 0x24, byte, 6, result, &result_len); +#endif + return 0; +} /*-----------------------------------------------------------------------*/ /* sysfs attributes for hwmon */ static ssize_t show_info(struct device *dev, struct device_attribute *da, @@ -231,7 +258,7 @@ static ssize_t show_info(struct device *dev, struct device_attribute *da, sprintf (buf, "%s\nThe CPLD2 release date is %02d/%02d/%d.\n", buf, byte[2] & 0xf, (byte[3] & 0x1f), 2014+(byte[2] >> 4)); /* mm/dd/yyyy*/ - sprintf (buf, "%sThe CPLD version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf); + sprintf (buf, "%sThe CPLD2 version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf); } return strlen(buf); @@ -251,7 +278,7 @@ static ssize_t show_powerstatus(struct device *dev, struct device_attribute *da, u8 byte[2] = {0,0}; mutex_lock(&data->update_lock); - len = cpld_i2c_read(client, byte, CPLD_POWERSTATUS_OFFSET, 2); + len = cpld_i2c_read(client2, byte, CPLD_POWERSTATUS_OFFSET, 2); mutex_unlock(&data->update_lock); if (len==0) return 0; @@ -265,8 +292,7 @@ static ssize_t show_powerstatus(struct device *dev, struct device_attribute *da, sprintf (buf, "%sPGD_P0V8_A: %s\n", buf,powerstatus_str[(byte[1]>>7) & 0x01]); sprintf (buf, "%sPGD_P0V89_ROV: %s\n", buf, powerstatus_str[(byte[1]>>6) & 0x01]); sprintf (buf, "%sSW_PWR_READY: %s\n", buf, powerstatus_str[(byte[1]>>3) & 0x01]); - sprintf (buf, "%sCORE_PWRGD_TO_CPLD: %s\n", buf, powerstatus_str[(byte[1]>>2) & 0x01]); - sprintf (buf, "%sCPU_STBY_PWROK: %s\n", buf, powerstatus_str[(byte[1]>>1) & 0x01]); + sprintf (buf, "%sCPU_STBY_PWROK: %s\n", buf, powerstatus_str[(byte[1]>>0) & 0x01]); return strlen(buf); } @@ -302,44 +328,27 @@ static ssize_t set_diag(struct device *dev, return count; } -static char* resetbutton_str[] = { - "No press", //0 - "Reserved", //1 - "Press and hold <5s", //2 - "Press and hold >5s", //3 -}; - -static ssize_t show_resetbuttonstatus(struct device *dev, struct device_attribute *da, +static ssize_t show_thermal(struct device *dev, struct device_attribute *da, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - ssize_t len = 0; - u8 byte = 0; - - mutex_lock(&data->update_lock); - len = cpld_i2c_read(client, &byte, CPLD_RESETBUTTONSTATUS_OFFSET, 1); - mutex_unlock(&data->update_lock); - if (len==0) return 0; - - byte &=0x03; - - return sprintf (buf, "0x%02X:%s\n", byte,resetbutton_str[byte]); + uint8_t ipmisend[]= { IPMI_SWITCHTEMP_OFFSET, 1}; + uint8_t result[MAX_IPMI_RECV_LENGTH]; + int result_len=0; + start_ipmi_command(NETFN_OEM, CMD_GETDATA,ipmisend, 2, result, &result_len); + return sprintf(buf, "%d\n", result[0] * 1000 ); } static char* interrupt_str[] = { "CPU_SEN_ALERT_N", //0 "EXT_USB_OC_N", //1 - "PS2_ALERT_N", //2 - "PS1_ALERT_N", //3 + "", //2 + "", //3 "PLD_SEN5_ALERT_N", //4 "PLD_SEN4_ALERT_N", //5 "PLD_SEN3_ALERT_N", //6 "UCD90160_TEMP_INT_N", //7 "RSTBTN_INT_N", //8 - "WDT_IRQ_N", //9 - "RSTBTN_5s_INT_N", //10 - "Reserved" //11 + "WDT_IRQ_N", //9 }; static ssize_t show_interrupt(struct device *dev, struct device_attribute *da, @@ -359,15 +368,12 @@ static ssize_t show_interrupt(struct device *dev, struct device_attribute *da, if(byte[0]==0xff && byte[2]==0x07) sprintf (buf, "%sNone",buf); if(!(byte[0]&0x01)) sprintf (buf, "%s%s ",buf,interrupt_str[0]); if(!(byte[0]&0x02)) sprintf (buf, "%s%s ",buf,interrupt_str[1]); - if(!(byte[0]&0x04)) sprintf (buf, "%s%s ",buf,interrupt_str[2]); - if(!(byte[0]&0x08)) sprintf (buf, "%s%s ",buf,interrupt_str[3]); if(!(byte[0]&0x10)) sprintf (buf, "%s%s ",buf,interrupt_str[4]); if(!(byte[0]&0x20)) sprintf (buf, "%s%s ",buf,interrupt_str[5]); if(!(byte[0]&0x40)) sprintf (buf, "%s%s ",buf,interrupt_str[6]); if(!(byte[0]&0x80)) sprintf (buf, "%s%s ",buf,interrupt_str[7]); if(!(byte[2]&0x01)) sprintf (buf, "%s%s%s ",buf,interrupt_str[8] ,(byte[3]&0x01)?"(Blocked)":""); if(!(byte[2]&0x02)) sprintf (buf, "%s%s%s ",buf,interrupt_str[9] ,(byte[3]&0x02)?"(Blocked)":""); - if(!(byte[2]&0x04)) sprintf (buf, "%s%s%s ",buf,interrupt_str[10],(byte[3]&0x04)?"(Blocked)":""); return sprintf (buf, "%s\n", buf); } @@ -414,10 +420,10 @@ static ssize_t set_bios_cs(struct device *dev, } static char* led_str[] = { - "OFF", //000 - "ON", //001 - "1 Hz", //010 - "2 Hz", //011 + "OFF", //00 + "Green/Blue", //01 + "Yellow/Orange", //10 + "Red", //11 }; static ssize_t show_led(struct device *dev, struct device_attribute *da, @@ -437,7 +443,7 @@ static ssize_t show_led(struct device *dev, struct device_attribute *da, byte = (byte >> shift) & 0x3; - return sprintf (buf, "%d: %s\n", byte, led_str[byte]); + return sprintf (buf, "%d:%s\n", byte, led_str[byte]); } static ssize_t set_led(struct device *dev, struct device_attribute *da, @@ -462,6 +468,61 @@ static ssize_t set_led(struct device *dev, struct device_attribute *da, return count; } +static char* sysled_str[] = { + "OFF", //000 + "0.5 Hz", //001 + "1 Hz", //010 + "2 Hz", //011 + "4 Hz", //100 + "NA", //101 + "NA", //110 + "ON", //111 +}; + +static ssize_t show_sysled(struct device *dev, struct device_attribute *da, + char *buf) +{ + u32 status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte; + int shift = (attr->index == 0)?3:0; + + mutex_lock(&data->update_lock); + status = cpld_i2c_read(client, &byte, CPLD_SYSLED_OFFSET, 1); + mutex_unlock(&data->update_lock); + + byte = (byte >> shift) & 0x7; + status = sprintf (buf, "%d:%s\n", byte, sysled_str[byte]); + + return strlen(buf); +} + +static ssize_t set_sysled(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + + u8 temp = simple_strtol(buf, NULL, 16); + u8 byte; + int shift = (attr->index == 0)?3:0; + + temp &= 0x7; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_SYSLED_OFFSET, 1); + byte &= ~(0x7<update_lock); + + return count; +} + static char* psu_str[] = { "unpowered", //00 "normal", //01 @@ -714,12 +775,15 @@ static ssize_t show_watchdog_counter(struct device *dev, struct device_attribute static SENSOR_DEVICE_ATTR(info, S_IRUGO, show_info, 0, 0); static SENSOR_DEVICE_ATTR(diag, S_IWUSR|S_IRUGO, show_diag, set_diag, 0); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_thermal, 0, 0); static SENSOR_DEVICE_ATTR(interrupt, S_IRUGO, show_interrupt, 0, 0); -static SENSOR_DEVICE_ATTR(stacking_led, S_IWUSR|S_IRUGO, show_led, set_led, 0); -static SENSOR_DEVICE_ATTR(fan_led, S_IWUSR|S_IRUGO, show_led, set_led, 2); -static SENSOR_DEVICE_ATTR(power_led, S_IWUSR|S_IRUGO, show_led, set_led, 4); -static SENSOR_DEVICE_ATTR(service_led, S_IWUSR|S_IRUGO, show_led, set_led, 6); +static SENSOR_DEVICE_ATTR(fan_led, S_IWUSR|S_IRUGO, show_led, set_led, 2); +static SENSOR_DEVICE_ATTR(power_led, S_IWUSR|S_IRUGO, show_led, set_led, 4); +static SENSOR_DEVICE_ATTR(location_led, S_IWUSR|S_IRUGO, show_led, set_led, 6); + +static SENSOR_DEVICE_ATTR(grn_led, S_IWUSR|S_IRUGO, show_sysled, set_sysled, 0); +static SENSOR_DEVICE_ATTR(red_led, S_IWUSR|S_IRUGO, show_sysled, set_sysled, 1); static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 0); static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 1); @@ -761,7 +825,6 @@ static SENSOR_DEVICE_ATTR(fan10_input,S_IRUGO, show_rpm, 0, 9); static SENSOR_DEVICE_ATTR(psu1, S_IRUGO, show_psu, 0, 0); static SENSOR_DEVICE_ATTR(psu2, S_IRUGO, show_psu, 0, 1); static SENSOR_DEVICE_ATTR(power_status, S_IRUGO, show_powerstatus, 0, 0); -static SENSOR_DEVICE_ATTR(resetbutton_status, S_IRUGO, show_resetbuttonstatus, 0, 0); static SENSOR_DEVICE_ATTR(watchdog_feed, S_IWUSR, 0, set_watchdog_feed, 0); static SENSOR_DEVICE_ATTR(watchdog_enable, S_IWUSR|S_IRUGO, show_watchdog_enable, set_watchdog_enable, 0); @@ -773,18 +836,20 @@ static SENSOR_DEVICE_ATTR(bios_cs, S_IWUSR|S_IRUGO, show_bios_cs, set_b static struct attribute *cpld_attributes[] = { &sensor_dev_attr_info.dev_attr.attr, &sensor_dev_attr_diag.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_stacking_led.dev_attr.attr, &sensor_dev_attr_fan_led.dev_attr.attr, &sensor_dev_attr_power_led.dev_attr.attr, - &sensor_dev_attr_service_led.dev_attr.attr, + &sensor_dev_attr_location_led.dev_attr.attr, + + &sensor_dev_attr_grn_led.dev_attr.attr, + &sensor_dev_attr_red_led.dev_attr.attr, &sensor_dev_attr_interrupt.dev_attr.attr, &sensor_dev_attr_psu1.dev_attr.attr, &sensor_dev_attr_psu2.dev_attr.attr, &sensor_dev_attr_power_status.dev_attr.attr, - &sensor_dev_attr_resetbutton_status.dev_attr.attr, &sensor_dev_attr_pwm1.dev_attr.attr, &sensor_dev_attr_pwm2.dev_attr.attr, @@ -839,7 +904,6 @@ cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct cpld_data *data; int status; - u8 byte[5]; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) @@ -879,11 +943,7 @@ cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) } } - //Handle LED control by the driver - byte[0]=0x01; - cpld_i2c_write(client, byte, CPLD_CTL_OFFSET, 1); - cpld_i2c_write(client2, byte, CPLD_CTL_OFFSET, 1); - + data->tsk = kthread_run(cpld_thread,client,"%s",dev_name(data->hwmon_dev)); dev_info(&client->dev, "%s: sensor '%s'\n", dev_name(data->hwmon_dev), client->name); @@ -908,6 +968,7 @@ static int cpld_remove(struct i2c_client *client) i2c_unregister_device(client2); i2c_set_clientdata(client2, NULL); } + kfree(data); return 0; } diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.c index a303527bec46..143aee309dba 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.c @@ -1,22 +1,55 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ #include #include #include #include #include +#include #include "io_expander.h" #include "inv_mux.h" -static struct mux_obj_s *mux_head_p = NULL; +/* For build single module using (Ex: ONL platform) */ +#include +//#include +//#include +static struct mux_obj_s *mux_head_p = NULL; + /* ========== MUX object functions ========== */ +static int +_setup_i2c_value(struct mux_obj_s *self, int offset, int value){ + + return i2c_smbus_write_byte_data(self->i2c_client_p, offset, value); +} + + +static int +_setup_i2c_client(struct mux_obj_s *self, int chan_id, int addr){ + + struct i2c_adapter *adap = NULL; + char *emsg = "ERR"; + + adap = i2c_get_adapter(chan_id); + if (!adap){ + emsg = "can't get adapter"; + goto err_setup_i2c_client; + } + self->i2c_client_p = kzalloc(sizeof(*self->i2c_client_p), GFP_KERNEL); + if (!self->i2c_client_p){ + emsg = "can't kzalloc client"; + goto err_setup_i2c_client; + } + self->i2c_client_p->adapter = adap; + self->i2c_client_p->addr = addr; + return 0; + +err_setup_i2c_client: + SWPS_ERR("%s: %s\n", __func__, emsg); + return ERR_MUX_UNEXCPT; +} + + int _common_force_pull_gpio(int mem_addr, int input, @@ -93,6 +126,78 @@ normal_gpio_pull_low(struct mux_obj_s *self){ } +int +cpld_rst_all_4_pull_low(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto setlow_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_rst_all_4_pull_low; + +setlow_cpld_rst_all_4_c0_a77_70_74_rst_all: + err = _setup_i2c_value(self, 0x70, 0x0); + if (err < 0) { + emsg = "setup 0x70 fail"; + goto err_cpld_rst_all_4_pull_low; + } + err = _setup_i2c_value(self, 0x74, 0x01); + if (err < 0) { + emsg = "setup 0x74 fail"; + goto err_cpld_rst_all_4_pull_low; + } + return 0; + +err_cpld_rst_all_4_pull_low: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +cpld_rst_all_4_pull_high(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_rst_all_4_pull_high; + +sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all: + err = _setup_i2c_value(self, 0x70, 0xfe); + if (err < 0) { + emsg = "setup 0x70 fail"; + goto err_cpld_rst_all_4_pull_high; + } + err = _setup_i2c_value(self, 0x74, 0x03); + if (err < 0) { + emsg = "setup 0x74 fail"; + goto err_cpld_rst_all_4_pull_high; + } + return 0; + +err_cpld_rst_all_4_pull_high: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + int pca9548_reset_mux_all(struct mux_obj_s *self){ /* [Note] Power-on reset (PCA9548A-NXP) @@ -108,13 +213,44 @@ pca9548_reset_mux_all(struct mux_obj_s *self){ SWPS_ERR("%s: _pull_low fail!\n", __func__); return -1; } - mdelay(MUX_RST_WAIT_MS); + mdelay(MUX_RST_WAIT_MS_PCA9548); if (self->_pull_high(self) < 0) { SWPS_ERR("%s: _pull_high fail!\n", __func__); return -1; } - mdelay(MUX_RST_WAIT_MS); + mdelay(MUX_RST_WAIT_MS_PCA9548); + return 0; +} + + +int +cpld_reset_mux_all(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto reset_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_reset_mux_all; + +reset_cpld_rst_all_4_c0_a77_70_74_rst_all: + if (self->_pull_low(self) < 0) { + emsg = "_pull_low fail"; + goto err_cpld_reset_mux_all; + } + mdelay(MUX_RST_WAIT_MS_CPLD); return 0; + +err_cpld_reset_mux_all: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; } @@ -127,6 +263,11 @@ common_reset_mux_all(struct mux_obj_s *self){ int init_gpio_4_force(struct mux_obj_s *self){ + + if (self->_pull_high(self) < 0) { + SWPS_ERR("%s: setup default fail!\n", __func__); + return -1; + } return 0; } @@ -134,20 +275,95 @@ init_gpio_4_force(struct mux_obj_s *self){ int init_gpio_4_normal(struct mux_obj_s *self){ - int err = 0; + int err = 0; + char *emsg = "ERR"; if (!gpio_is_valid(self->gpio_num)) { - SWPS_ERR("%s: GIPO:%d isn't valid\n", __func__, self->gpio_num); - return -1; + emsg = "GPIO invalid"; + goto err_init_gpio_4_normal; } err = gpio_request(self->gpio_num, MUX_GPIO_LABEL); if (err < 0) { - SWPS_ERR("%s: gpio_request fail :%d :%d\n", - __func__, err, self->gpio_num); - return -1; + emsg = "gpio_request fail"; + goto err_init_gpio_4_normal; + } + err = self->_pull_high(self); + if (err < 0) { + emsg = "setup default fail"; + goto err_init_gpio_4_normal; } SWPS_DEBUG("%s: gpio_request:%d ok.\n", __func__, self->gpio_num); return 0; + +err_init_gpio_4_normal: + SWPS_ERR("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return -1; +} + + +int +init_cpld_4_rst_all(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + int chan = ERR_MUX_UNEXCPT; + int addr = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto init_cpld_i2c_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_init_cpld_4_rst_all; + +init_cpld_i2c_c0_a77_70_74_rst_all: + chan = 0; + addr = 0x77; + err = _setup_i2c_client(self, chan, addr); + if (err < 0) { + emsg = "_setup_i2c_client fail"; + goto err_init_cpld_4_rst_all; + } + err = self->_pull_high(self); + if (err < 0) { + emsg = "setup default value fail"; + goto err_init_cpld_4_rst_all; + } + SWPS_DEBUG("%s: init_cpld_i2c_c0_a77_70_74_rst_all ok", __func__); + return 0; + +err_init_cpld_4_rst_all: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +clean_gpio_4_common(struct mux_obj_s *self){ + + if (!self) return 0; + if (!gpio_is_valid(self->gpio_num)) return 0; + self->_pull_high(self); + gpio_free(mux_head_p->gpio_num); + return 0; +} + + +int +clean_cpld_4_rst_all(struct mux_obj_s *self){ + + if (!self) return 0; + self->_pull_high(self); + if (self->i2c_client_p) { + i2c_put_adapter(self->i2c_client_p->adapter); + kfree(self->i2c_client_p); + } + return 0; } @@ -163,6 +379,7 @@ _setup_muxctl_cb(struct mux_obj_s *self, self->_pull_low = rangeley_force_pull_low; self->_pull_high = rangeley_force_pull_high; self->_init = init_gpio_4_force; + self->_clean = clean_gpio_4_common; self->reset = pca9548_reset_mux_all; memset(mod_dsc, 0, 32); snprintf(mod_dsc, 31, "Rangeley force mode"); @@ -173,25 +390,38 @@ _setup_muxctl_cb(struct mux_obj_s *self, self->_pull_low = hedera_force_pull_low; self->_pull_high = hedera_force_pull_high; self->_init = init_gpio_4_force; + self->_clean = clean_gpio_4_common; self->reset = pca9548_reset_mux_all; memset(mod_dsc, 0, 32); snprintf(mod_dsc, 31, "Hedera force mode"); goto ok_setup_muxctl_cb; - case MUX_RST_GPIO_48_PAC9548: - case MUX_RST_GPIO_69_PAC9548: + case MUX_RST_GPIO_48_PCA9548: + case MUX_RST_GPIO_69_PCA9548: case MUX_RST_GPIO_249_PCA9548: - case MUX_RST_GPIO_500_PAC9548: + case MUX_RST_GPIO_500_PCA9548: case MUX_RST_GPIO_505_PCA9548: self->gpio_num = gpio; self->_pull_low = normal_gpio_pull_low; self->_pull_high = normal_gpio_pull_high; self->_init = init_gpio_4_normal; + self->_clean = clean_gpio_4_common; self->reset = pca9548_reset_mux_all; memset(mod_dsc, 0, 32); snprintf(mod_dsc, 31, "Normal mode :%d", (int)gpio); goto ok_setup_muxctl_cb; + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + self->gpio_num = gpio; + self->_pull_low = cpld_rst_all_4_pull_low; + self->_pull_high = cpld_rst_all_4_pull_high; + self->_init = init_cpld_4_rst_all; + self->_clean = clean_cpld_4_rst_all; + self->reset = cpld_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "CPLD mode :%d", (int)gpio); + goto ok_setup_muxctl_cb; + default: break; } @@ -207,23 +437,28 @@ _setup_muxctl_cb(struct mux_obj_s *self, /* ========== MUX public functions ========== */ void -clean_mux_gpio(void){ +clean_mux_objs(void){ - if (!mux_head_p) { + struct mux_obj_s *curr_p = mux_head_p; + struct mux_obj_s *next_p = NULL; + + if (!curr_p) { SWPS_DEBUG("%s: mux_head_p is NULL\n", __func__); return; } - if (gpio_is_valid(mux_head_p->gpio_num)) { - gpio_free(mux_head_p->gpio_num); + while (curr_p) { + next_p = curr_p->next; + curr_p->_clean(curr_p); + kfree(curr_p); + curr_p = next_p; } - kfree(mux_head_p); - mux_head_p = NULL; SWPS_DEBUG("%s: done.\n", __func__); } +EXPORT_SYMBOL(clean_mux_objs); int -reset_mux_gpio(void){ +reset_mux_objs(void){ if (!mux_head_p) { SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__); @@ -235,47 +470,78 @@ reset_mux_gpio(void){ } return 0; } +EXPORT_SYMBOL(reset_mux_objs); + + +struct mux_obj_s * +_create_mux_obj(unsigned gpio){ + + char *emsg = "ERR"; + struct mux_obj_s *obj_p = NULL; + + obj_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL); + if (!obj_p) { + emsg = "kzalloc fail!"; + goto err_create_mux_obj_1; + } + if (_setup_muxctl_cb(obj_p, gpio) < 0){ + emsg = "_setup_muxctl_cb fail!"; + goto err_create_mux_obj_2; + } + if (obj_p->_init(obj_p) < 0) { + emsg = "_init() fail!"; + goto err_create_mux_obj_2; + } + SWPS_DEBUG("%s: created MUX object :%d\n", __func__, gpio); + return obj_p; + +err_create_mux_obj_2: + kfree(obj_p); +err_create_mux_obj_1: + SWPS_ERR("%s: %s :%d\n", __func__, emsg, gpio); + return NULL; +} int -init_mux_gpio(unsigned gpio){ +init_mux_objs(unsigned gpio){ + + struct mux_obj_s *curr_p = NULL; + char *emsg = "ERR"; /* Create MUX control object */ if (mux_head_p) { SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__); - clean_mux_gpio(); + clean_mux_objs(); } /* Currently, it is using single muxctl architecture. - * In the future, it may use the multi-muxctl if HW add new features. - * (Ex: Port power-status control) + * In the future, it may use the multi-muxctl. + * (Ex: Gulmohar's advance I2C control / Peony's reset single mux) */ - mux_head_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL); - if (!mux_head_p) { - SWPS_ERR("%s: kzalloc fail!\n", __func__); - return -1; - } - /* Initial MUX controller */ - if (_setup_muxctl_cb(mux_head_p, gpio) < 0){ - SWPS_ERR("%s: _setup_muxctl_cb fail!\n", __func__); - return -1; - } - if (mux_head_p->_init(mux_head_p) < 0) { - SWPS_ERR("%s: init() fail\n", __func__); - goto err_init_mux_gpio; - } - /* Setup default value */ - if (mux_head_p->_pull_high(mux_head_p) < 0) { - SWPS_ERR("%s: setup default fail!\n", __func__); - goto err_init_mux_gpio; + curr_p = _create_mux_obj(gpio); + if (!curr_p) { + emsg = "_create_mux_obj fail"; + goto err_init_mux_objs; } + curr_p->next = NULL; + mux_head_p = curr_p; + SWPS_DEBUG("%s: all done. :%d\n", __func__, gpio); return 0; -err_init_mux_gpio: - clean_mux_gpio(); +err_init_mux_objs: + clean_mux_objs(); + SWPS_ERR("%s: %s\n", __func__, emsg); return -1; } +EXPORT_SYMBOL(init_mux_objs); +/* For single ko module + * => You need to declare MODULE_LICENSE If you want to build single module along. + * => Ex: For ONL platform + */ +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.h b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.h index f981a304644a..a913b24c6053 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.h +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.h @@ -1,47 +1,51 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - #ifndef INV_MUX_H #define INV_MUX_H +#include /* MUX basic information */ #define MUX_GPIO_LABEL "SWPS_RST_MUX" /* MUX reset GPIO define */ -#define MUX_RST_GPIO_FORCE (30100) -#define MUX_RST_GPIO_FORCE_RANGELEY (30101) -#define MUX_RST_GPIO_FORCE_HEDERA (30102) -#define MUX_RST_GPIO_48_PAC9548 (48) -#define MUX_RST_GPIO_69_PAC9548 (69) -#define MUX_RST_GPIO_249_PCA9548 (249) -#define MUX_RST_GPIO_500_PAC9548 (500) -#define MUX_RST_GPIO_505_PCA9548 (505) +#define MUX_RST_GPIO_FORCE (30100) +#define MUX_RST_GPIO_FORCE_RANGELEY (30101) +#define MUX_RST_GPIO_FORCE_HEDERA (30102) +#define MUX_RST_GPIO_48_PCA9548 (48) +#define MUX_RST_GPIO_69_PCA9548 (69) +#define MUX_RST_GPIO_249_PCA9548 (249) +#define MUX_RST_GPIO_500_PCA9548 (500) +#define MUX_RST_GPIO_505_PCA9548 (505) +#define MUX_RST_CPLD_C0_A77_70_74_RST_ALL (30201) /* MUX relate value define */ -#define MUX_RST_WAIT_MS (1) -#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD -#define MUX_RST_MEM_ADDR_HEDERA (0x548) +#define MUX_RST_WAIT_MS_PCA9548 (1) +#define MUX_RST_WAIT_MS_CPLD (10) +#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD +#define MUX_RST_MEM_ADDR_HEDERA (0x548) + +/* MUX error code define */ +#define ERR_MUX_UNEXCPT (-399) struct mux_obj_s { + struct i2c_client *i2c_client_p; + struct mux_obj_s *next; unsigned gpio_num; int (*_pull_high)(struct mux_obj_s *self); int (*_pull_low)(struct mux_obj_s *self); int (*_init)(struct mux_obj_s *self); + int (*_clean)(struct mux_obj_s *self); int (*reset)(struct mux_obj_s *self); }; -void clean_mux_gpio(void); -int reset_mux_gpio(void); -int init_mux_gpio(unsigned gpio); +void clean_mux_objs(void); +int reset_mux_objs(void); +int init_mux_objs(unsigned gpio); #endif /* INV_MUX_H */ + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c index 42900232dca8..212388c8e98d 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c @@ -137,49 +137,49 @@ static struct pca954x_platform_data mux_data_0_6 = { }; static struct i2c_board_info i2c_device_info0[] __initdata = { - {"pca9641", 0, 0x76, &pca9641_data_1, 0, 0}, //PCA9641-1 - {"pca9641", 0, 0x73, &pca9641_data_3, 0, 0}, //PCA9641-3 - {"pca9641", 0, 0x09, &pca9641_data_4, 0, 0}, //PCA9641-4 + {"pca9641", 0, 0x76, &pca9641_data_1, 0, 0}, //PCA9641-1 + {"pca9641", 0, 0x73, &pca9641_data_3, 0, 0}, //PCA9641-3 + {"pca9641", 0, 0x09, &pca9641_data_4, 0, 0}, //PCA9641-4 }; static struct i2c_board_info i2c_device_info1[] __initdata = { - {"pca9641", 0, 0x0A, &pca9641_data_2, 0, 0}, //PCA9641-2 + {"pca9641", 0, 0x0A, &pca9641_data_2, 0, 0}, //PCA9641-2 }; static struct i2c_board_info i2c_device_info2[] __initdata = { - {"inv_cpld", 0, 0x77, 0, 0, 0}, //CPLD + {"inv_cpld", 0, 0x77, 0, 0, 0}, //CPLD }; static struct i2c_board_info i2c_device_info3[] __initdata = { - {"tmp75", 0, 0x48, 0, 0, 0}, //CPU Board Temp - {"tmp75", 0, 0x4A, 0, 0, 0}, //Temp - {"tmp75", 0, 0x4D, 0, 0, 0}, //Temp - {"tmp75", 0, 0x4E, 0, 0, 0}, //Temp + {"tmp75", 0, 0x48, 0, 0, 0}, //CPU Board Temp + {"tmp75", 0, 0x4A, 0, 0, 0}, //Temp + {"tmp75", 0, 0x4D, 0, 0, 0}, //Temp + {"tmp75", 0, 0x4E, 0, 0, 0}, //Temp }; static struct i2c_board_info i2c_device_info4[] __initdata = { - {"pmbus", 0, 0x5A, 0, 0, 0}, //PSU1 - {"pmbus", 0, 0x5B, 0, 0, 0}, //PSU2 + {"pmbus", 0, 0x5B, 0, 0, 0}, //PSU1 + {"pmbus", 0, 0x5A, 0, 0, 0}, //PSU2 }; static struct i2c_board_info i2c_device_info5[] __initdata = { - {"pca9548", 0, 0x70, &mux_data_0, 0, 0}, //mux root + {"pca9548", 0, 0x70, &mux_data_0, 0, 0}, //mux root }; static struct i2c_board_info i2c_device_info6[] __initdata = { - {"pca9548", 0, 0x72, &mux_data_0_0, 0, 0}, + {"pca9548", 0, 0x72, &mux_data_0_0, 0, 0}, }; static struct i2c_board_info i2c_device_info7[] __initdata = { - {"pca9548", 0, 0x72, &mux_data_0_1, 0, 0}, + {"pca9548", 0, 0x72, &mux_data_0_1, 0, 0}, }; static struct i2c_board_info i2c_device_info8[] __initdata = { - {"pca9548", 0, 0x72, &mux_data_0_2, 0, 0}, + {"pca9548", 0, 0x72, &mux_data_0_2, 0, 0}, }; static struct i2c_board_info i2c_device_info9[] __initdata = { - {"pca9548", 0, 0x72, &mux_data_0_3, 0, 0}, + {"pca9548", 0, 0x72, &mux_data_0_3, 0, 0}, }; static struct i2c_board_info i2c_device_info10[] __initdata = { - {"pca9548", 0, 0x72, &mux_data_0_4, 0, 0}, + {"pca9548", 0, 0x72, &mux_data_0_4, 0, 0}, }; static struct i2c_board_info i2c_device_info11[] __initdata = { - {"pca9548", 0, 0x72, &mux_data_0_5, 0, 0}, + {"pca9548", 0, 0x72, &mux_data_0_5, 0, 0}, }; static struct i2c_board_info i2c_device_info12[] __initdata = { - {"pca9548", 0, 0x72, &mux_data_0_6, 0, 0}, + {"pca9548", 0, 0x72, &mux_data_0_6, 0, 0}, }; @@ -196,19 +196,23 @@ static struct inv_i2c_board_info i2cdev_list[] = { {bus_id(9), ARRAY_SIZE(i2c_device_info9), i2c_device_info9 }, //mux CH3 {bus_id(10),ARRAY_SIZE(i2c_device_info10), i2c_device_info10}, //mux CH4 {bus_id(11),ARRAY_SIZE(i2c_device_info11), i2c_device_info11}, //mux CH5 - {bus_id(12),ARRAY_SIZE(i2c_device_info12), i2c_device_info12}, //mux CH6 + {bus_id(12),ARRAY_SIZE(i2c_device_info12), i2c_device_info12}, //mux CH6 }; +#define INV_PLATFORM_CLIENT_MAX_NUM 50 /*A big enough number for sum of i2cdev_list[i].size */ +static int client_list_index = 0; +static struct i2c_client *client_list[INV_PLATFORM_CLIENT_MAX_NUM] = {0}; + ///////////////////////////////////////////////////////////////////////////////////////// static struct platform_device *device_i2c_gpio0; -static struct i2c_gpio_platform_data i2c_gpio_platdata0 = { - .scl_pin = 58, //494, - .sda_pin = 75, //511, - - .udelay = 5, //5:100kHz - .sda_is_open_drain = 0, - .scl_is_open_drain = 0, - .scl_is_output_only = 0 +static struct i2c_gpio_platform_data i2c_gpio_platdata0 = { + .scl_pin = 58, //494, + .sda_pin = 75, //511, + + .udelay = 5, //5:100kHz + .sda_is_open_drain = 0, + .scl_is_open_drain = 0, + .scl_is_output_only = 0 }; static int __init inv_platform_init(void) @@ -220,7 +224,7 @@ static int __init inv_platform_init(void) //printk("%s \n", __func__); - //use i2c-gpio + //use i2c-gpio //register i2c gpio //config gpio58,75 to gpio function 58=32+3*8+2 75=32*2+8*1+3 gpio69=32*2+8*0+5 outl( inl(0x533) | (1<<2), 0x533); //i2c-gpio sdl (GPIO58) @@ -229,7 +233,7 @@ static int __init inv_platform_init(void) outl( inl(0x500) | (1<<7), 0x500); //SYS_RDY_N (GPIO7) outl( inl(0x501) | (1<<7), 0x501); //BMC_HEART_BEAT (GPIO15) outl( inl(0x503) | (1<<2)|(1<<3), 0x503); //PSOC_HEART_BEAT(26),CPLD_HEART_BEAT(27) - + device_i2c_gpio0 = platform_device_alloc("i2c-gpio", 1); if (!device_i2c_gpio0) { printk(KERN_ERR "i2c-gpio: platform_device_alloc fail\n"); @@ -243,7 +247,8 @@ static int __init inv_platform_init(void) if (ret) { printk(KERN_ERR "i2c-gpio: platform_device_add fail %d\n", ret); } - msleep(10); + msleep(10); + for(i=0; idev.platform_data = NULL; - platform_device_unregister(device_i2c_gpio0); + int i; + + for(i=client_list_index-1; i>=0; i--) { + i2c_unregister_device(client_list[i]); + } + device_i2c_gpio0->dev.platform_data = NULL; + platform_device_unregister(device_i2c_gpio0); + printk("inv_platform_exit done\n"); } module_init(inv_platform_init); @@ -273,3 +294,4 @@ module_exit(inv_platform_exit); MODULE_AUTHOR("Inventec"); MODULE_DESCRIPTION("Platform devices"); MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.c index cbb22fba2979..11b60f78ae90 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.c @@ -1,9 +1,3 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ #include #include #include @@ -15,12 +9,14 @@ #include #include #include +#include #include "inv_swps.h" static int ctl_major; static int port_major; static int ioexp_total; static int port_total; +static int block_polling; static int auto_config; static int flag_i2c_reset; static int flag_mod_state; @@ -29,7 +25,8 @@ static struct class *swp_class_p = NULL; static struct inv_platform_s *platform_p = NULL; static struct inv_ioexp_layout_s *ioexp_layout = NULL; static struct inv_port_layout_s *port_layout = NULL; - +int io_no_init = 0; +module_param(io_no_init, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); static void swp_polling_worker(struct work_struct *work); static DECLARE_DELAYED_WORK(swp_polling, swp_polling_worker); @@ -140,6 +137,47 @@ _get_transvr_obj(char *dev_name) { } +static int +_is_i2c_target_exist(int chan, int addr) { + /* retval: Exist = 1 / Not exist = 0 / Error < 0 + */ + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + int retval = -1; + int err = -1; + int d_offs = 0; + + adap = i2c_get_adapter(chan); + if (!adap) { + SWPS_DEBUG("%s: can't get adapter\n", __func__); + retval = 0; + goto out_is_i2c_target_exist_1; + } + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client) { + SWPS_ERR("%s: kzalloc fail\n", __func__); + retval = -1; + goto out_is_i2c_target_exist_2; + } + client->adapter = adap; + client->addr = addr; + err = i2c_smbus_read_byte_data(client, d_offs); + if (err < 0) { + retval = 0; + } else { + retval = 1; + } + i2c_put_adapter(adap); + kfree(client); + return retval; + +out_is_i2c_target_exist_2: + i2c_put_adapter(adap); +out_is_i2c_target_exist_1: + return retval; +} + + static void unlock_tobj_all(void) { @@ -254,6 +292,22 @@ show_attr_auto_config(struct device *dev_p, } +static ssize_t +show_attr_block_poll(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", block_polling); +} +static ssize_t +show_attr_io_no_init(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", io_no_init); +} + + static int _check_reset_pwd(const char *buf_p, size_t count) { @@ -360,6 +414,53 @@ store_attr_auto_config(struct device *dev_p, } +static ssize_t +store_attr_block_poll( struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + int input_val = sscanf_2_int(buf_p); + + if (input_val < 0){ + return -EBFONT; + } + if ((input_val != 0) && (input_val != 1)) { + return -EBFONT; + } + + if(input_val != block_polling){ + block_polling = input_val; + if(block_polling){ + cancel_delayed_work_sync(&swp_polling); + } + else{ + schedule_delayed_work(&swp_polling, _get_polling_period()); + } + } + + return count; +} + +static ssize_t +store_attr_io_no_init( struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + int input_val = sscanf_2_int(buf_p); + + if ((input_val != 0) && (input_val != 1)) { + return -EBFONT; + } + + if(input_val != io_no_init){ + io_no_init = input_val; + } + + return count; +} + /* ========== Show functions: For transceiver attribute ========== */ static ssize_t @@ -1604,6 +1705,9 @@ static DEVICE_ATTR(status, S_IRUGO, show_attr_status, static DEVICE_ATTR(reset_i2c, S_IWUSR, NULL, store_attr_reset_i2c); static DEVICE_ATTR(reset_swps, S_IWUSR, NULL, store_attr_reset_swps); static DEVICE_ATTR(auto_config, S_IRUGO|S_IWUSR, show_attr_auto_config, store_attr_auto_config); +static DEVICE_ATTR(block_poll, S_IRUGO|S_IWUSR, show_attr_block_poll, store_attr_block_poll); +static DEVICE_ATTR(io_no_init, S_IRUGO|S_IWUSR, show_attr_io_no_init, store_attr_io_no_init); + /* ========== Transceiver attribute: from eeprom ========== */ @@ -1666,12 +1770,12 @@ static DEVICE_ATTR(hard_rs1, S_IRUGO|S_IWUSR, show_attr_hard_rs1, /* ========== Functions for module handling ========== */ static void -clean_port_obj(void){ +clean_port_objs(void){ dev_t dev_num; char dev_name[32]; struct device *device_p; - struct transvr_obj_s *transvr_obj_p; + struct transvr_obj_s *tobj_p; int minor_curr, port_id; for (minor_curr=0; minor_curri2c_client_p); - kfree(transvr_obj_p->vendor_name); - kfree(transvr_obj_p->vendor_pn); - kfree(transvr_obj_p->vendor_rev); - kfree(transvr_obj_p->vendor_sn); - kfree(transvr_obj_p->worker_p); - kfree(transvr_obj_p); + tobj_p = dev_get_drvdata(device_p); + if (tobj_p){ + if (tobj_p->i2c_client_p) { + i2c_put_adapter(tobj_p->i2c_client_p->adapter); + kfree(tobj_p->i2c_client_p); + } + kfree(tobj_p->vendor_name); + kfree(tobj_p->vendor_pn); + kfree(tobj_p->vendor_rev); + kfree(tobj_p->vendor_sn); + kfree(tobj_p->worker_p); + kfree(tobj_p); } dev_num = MKDEV(port_major, minor_curr); device_unregister(device_p); @@ -1713,6 +1820,9 @@ clean_swps_common(void){ device_destroy(swp_class_p, dev_num); } cancel_delayed_work_sync(&swp_polling); + if (platform_p) { + kfree(platform_p); + } SWPS_DEBUG("%s: done.\n", __func__); } @@ -1720,8 +1830,10 @@ clean_swps_common(void){ static int get_platform_type(void){ - int i; - int pf_total = ARRAY_SIZE(platform_map); + int i, tmp; + int auto_chan = -1; + int auto_addr = -1; + int pf_total = ARRAY_SIZE(platform_map); char log_msg[64] = "ERROR"; platform_p = kzalloc(sizeof(struct inv_platform_s), GFP_KERNEL); @@ -1749,6 +1861,30 @@ get_platform_type(void){ platform_p->name); goto err_get_platform_type_2; + case PLATFORM_TYPE_PEONY_AUTO: +#ifdef SWPS_PEONY_SFP + auto_chan = peony_sfp_ioexp_layout[0].addr[0].chan_id; + auto_addr = peony_sfp_ioexp_layout[0].addr[0].chip_addr; +#endif + tmp = _is_i2c_target_exist(auto_chan, auto_addr); + switch (tmp) { + case 0: /* Copper SKU */ + SWPS_INFO("Auto-detected :Peony :Copper\n"); + platform_p->id = PLATFORM_TYPE_PEONY_COPPER_GA; + goto map_platform_name; + + case 1: /* SFP SKU */ + SWPS_INFO("Auto-detected :Peony :SFP\n"); + platform_p->id = PLATFORM_TYPE_PEONY_SFP_GA; + goto map_platform_name; + + default: + break; + } + snprintf(log_msg, sizeof(log_msg), + "Auto detect Peony SKU fail! :%d", tmp); + goto err_get_platform_type_2; + case PLATFORM_TYPE_MAGNOLIA: case PLATFORM_TYPE_MAGNOLIA_FNC: case PLATFORM_TYPE_REDWOOD: @@ -1763,22 +1899,14 @@ get_platform_type(void){ case PLATFORM_TYPE_LAVENDER_GA: case PLATFORM_TYPE_LAVENDER_ONL: case PLATFORM_TYPE_COTTONWOOD_RANGELEY: - case PLATFORM_TYPE_MAPLE: + case PLATFORM_TYPE_MAPLE_GA: + case PLATFORM_TYPE_MAPLE_B: + case PLATFORM_TYPE_GULMOHAR_GA: + case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA: + case PLATFORM_TYPE_PEONY_SFP_GA: + case PLATFORM_TYPE_PEONY_COPPER_GA: platform_p->id = PLATFORM_SETTINGS; - for (i=0; iname, (sizeof(platform_p->name) - 1), - "%s", platform_map[i].name); - snprintf(log_msg, sizeof(log_msg), - "User setup platform: %d (%s)", - platform_p->id, platform_p->name); - goto ok_get_platform_type_1; - } - } - snprintf(log_msg, sizeof(log_msg), - "Internal error, can not map id:%d", - PLATFORM_SETTINGS); - goto err_get_platform_type_2; + goto map_platform_name; default: break; @@ -1787,6 +1915,22 @@ get_platform_type(void){ "PLATFORM_SETTINGS:%d undefined", PLATFORM_SETTINGS); goto err_get_platform_type_2; +map_platform_name: + for (i=0; iid == platform_map[i].id) { + snprintf(platform_p->name, (sizeof(platform_p->name) - 1), + "%s", platform_map[i].name); + snprintf(log_msg, sizeof(log_msg), + "User setup platform: %d (%s)", + platform_p->id, platform_p->name); + goto ok_get_platform_type_1; + } + } + snprintf(log_msg, sizeof(log_msg), + "Internal error, can not map id:%d", + platform_p->id ); + goto err_get_platform_type_2; + ok_get_platform_type_1: SWPS_DEBUG("%s: %s, :%d\n", __func__, log_msg, PLATFORM_SETTINGS); return 0; @@ -1913,15 +2057,61 @@ get_layout_info(void){ port_total = ARRAY_SIZE(cottonwood_rangeley_port_layout); break; #endif -#ifdef SWPS_MAPLE - case PLATFORM_TYPE_MAPLE: - gpio_rest_mux = maple_gpio_rest_mux; - ioexp_layout = maple_ioexp_layout; - port_layout = maple_port_layout; - ioexp_total = ARRAY_SIZE(maple_ioexp_layout); - port_total = ARRAY_SIZE(maple_port_layout); +#ifdef SWPS_MAPLE_GA + case PLATFORM_TYPE_MAPLE_GA: + gpio_rest_mux = maple_ga_gpio_rest_mux; + ioexp_layout = maple_ga_ioexp_layout; + port_layout = maple_ga_port_layout; + ioexp_total = ARRAY_SIZE(maple_ga_ioexp_layout); + port_total = ARRAY_SIZE(maple_ga_port_layout); + break; +#endif +#ifdef SWPS_MAPLE_B + case PLATFORM_TYPE_MAPLE_B: + gpio_rest_mux = maple_b_gpio_rest_mux; + ioexp_layout = maple_b_ioexp_layout; + port_layout = maple_b_port_layout; + ioexp_total = ARRAY_SIZE(maple_b_ioexp_layout); + port_total = ARRAY_SIZE(maple_b_port_layout); + break; +#endif +#ifdef SWPS_GULMOHAR + case PLATFORM_TYPE_GULMOHAR_GA: + gpio_rest_mux = gulmohar_gpio_rest_mux; + ioexp_layout = gulmohar_ioexp_layout; + port_layout = gulmohar_port_layout; + ioexp_total = ARRAY_SIZE(gulmohar_ioexp_layout); + port_total = ARRAY_SIZE(gulmohar_port_layout); + break; +#endif +#ifdef SWPS_GULMOHAR_2T_EVT1 + case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA: + gpio_rest_mux = gulmohar_2t_evt1_gpio_rest_mux; + ioexp_layout = gulmohar_2t_evt1_ioexp_layout; + port_layout = gulmohar_2t_evt1_port_layout; + ioexp_total = ARRAY_SIZE(gulmohar_2t_evt1_ioexp_layout); + port_total = ARRAY_SIZE(gulmohar_2t_evt1_port_layout); + break; +#endif +#ifdef SWPS_PEONY_SFP + case PLATFORM_TYPE_PEONY_SFP_GA: + gpio_rest_mux = peony_sfp_gpio_rest_mux; + ioexp_layout = peony_sfp_ioexp_layout; + port_layout = peony_sfp_port_layout; + ioexp_total = ARRAY_SIZE(peony_sfp_ioexp_layout); + port_total = ARRAY_SIZE(peony_sfp_port_layout); + break; +#endif +#ifdef SWPS_PEONY_COPPER + case PLATFORM_TYPE_PEONY_COPPER_GA: + gpio_rest_mux = peony_copper_gpio_rest_mux; + ioexp_layout = peony_copper_ioexp_layout; + port_layout = peony_copper_port_layout; + ioexp_total = ARRAY_SIZE(peony_copper_ioexp_layout); + port_total = ARRAY_SIZE(peony_copper_port_layout); break; #endif + default: SWPS_ERR(" Invalid platform: %d (%s)\n", platform_p->id, platform_p->name); @@ -1952,11 +2142,18 @@ __detect_issues_port(int minor_num) { } if (resync_channel_tier_2(tobj_p) < 0) { if (check_channel_tier_1() < 0) { - alarm_msg_2_user(tobj_p, i2c_emsg); - return -2;; + goto get_target_issues_port; } } + /* Re-check again for i2c-gpio special case */ + if (check_channel_tier_1() < 0) { + goto get_target_issues_port; + } return 0; + +get_target_issues_port: + alarm_msg_2_user(tobj_p, i2c_emsg); + return -2; } @@ -2015,11 +2212,11 @@ _isolate_issues_port(int minor_num) { static int _reset_i2c_topology_tier_1(void) { - if (reset_mux_gpio() < 0) { + if (reset_mux_objs() < 0) { SWPS_ERR("%s: reset MUX GPIO fail!\n", __func__); return -1; } - SWPS_DEBUG("%s: reset_mux_gpio OK.\n", __func__); + SWPS_DEBUG("%s: reset_mux_objs OK.\n", __func__); if (resync_channel_tier_1() < 0) { SWPS_ERR("%s: resync tier-1 channel fail!\n", __func__); return -1; @@ -2596,6 +2793,15 @@ register_modctl_attr(struct device *device_p){ err_msg = "dev_attr_auto_config"; goto err_reg_modctl_attr; } + if (device_create_file(device_p, &dev_attr_block_poll) < 0) { + err_msg = "dev_attr_block_poll"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_io_no_init) < 0) { + err_msg = "dev_attr_io_no_init"; + goto err_reg_modctl_attr; + } + return 0; err_reg_modctl_attr: @@ -2619,13 +2825,19 @@ register_ioexp_attr(struct device *device_p, goto err_reg_ioexp_attr; } break; - case IOEXP_TYPE_CYPRESS_NABC: + case IOEXP_TYPE_MAPLE_NABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: if (register_ioexp_attr_sfp_2(device_p) < 0){ err_msg = "register_ioexp_attr_sfp_2 fail"; goto err_reg_ioexp_attr; } break; + case IOEXP_TYPE_MAGINOLIA_7AB: case IOEXP_TYPE_SPRUCE_7AB: case IOEXP_TYPE_CYPRESS_7ABC: @@ -2638,6 +2850,9 @@ register_ioexp_attr(struct device *device_p, case IOEXP_TYPE_SEQUOIA_NABC: case IOEXP_TYPE_LAVENDER_P65: case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: if (register_ioexp_attr_qsfp_1(device_p) < 0){ err_msg = "register_ioexp_attr_qsfp_1 fail"; goto err_reg_ioexp_attr; @@ -2732,7 +2947,7 @@ register_swp_module(void){ SWPS_WARN("Allocate CTL MAJOR failure! \n"); goto err_register_swp_module_1; } - if (alloc_chrdev_region(&port_devt, 0, dev_total, SWP_CLS_NAME) < 0){ + if (alloc_chrdev_region(&port_devt, 0, port_total, SWP_CLS_NAME) < 0){ SWPS_WARN("Allocate PORT MAJOR failure! \n"); goto err_register_swp_module_2; } @@ -2863,13 +3078,13 @@ create_port_objs(void) { /* Success */ ok_count++; } - SWPS_INFO("%s: initialed %d port-dev",__func__, ok_count); + SWPS_INFO("%s: initialed %d port-dev\n",__func__, ok_count); return 0; err_initport_reg_device: kfree(transvr_obj_p); err_initport_create_tranobj: - clean_port_obj(); + clean_port_objs(); SWPS_ERR("%s: %s", __func__, err_msg); SWPS_ERR("Dump: :%d :%d :%d :%d :%d :%d\n", port_id, chan_id, ioexp_id, ioexp_virt_offset, transvr_type, run_mod); @@ -2942,6 +3157,7 @@ init_swps_common(void){ char *err_msg = "ERR"; + block_polling = 0; auto_config = 0; if ((SWP_AUTOCONFIG_ENABLE) && (SWP_POLLING_ENABLE)){ auto_config = 1; @@ -2985,7 +3201,7 @@ swp_module_init(void){ if (create_port_objs() < 0){ goto err_init_portobj; } - if (init_mux_gpio(gpio_rest_mux) < 0){ + if (init_mux_objs(gpio_rest_mux) < 0){ goto err_init_mux; } if (init_dev_topology() < 0){ @@ -2999,13 +3215,12 @@ swp_module_init(void){ err_init_topology: - clean_mux_gpio(); + clean_mux_objs(); err_init_mux: - clean_port_obj(); + clean_port_objs(); err_init_portobj: clean_ioexp_objs(); err_init_ioexp: - class_unregister(swp_class_p); class_destroy(swp_class_p); unregister_chrdev_region(MKDEV(ctl_major, 0), 1); unregister_chrdev_region(MKDEV(port_major, 0), port_total); @@ -3019,10 +3234,9 @@ static void __exit swp_module_exit(void){ clean_swps_common(); - clean_port_obj(); + clean_port_objs(); clean_ioexp_objs(); - clean_mux_gpio(); - class_unregister(swp_class_p); + clean_mux_objs(); class_destroy(swp_class_p); unregister_chrdev_region(MKDEV(ctl_major, 0), 1); unregister_chrdev_region(MKDEV(port_major, 0), port_total); @@ -3035,6 +3249,7 @@ MODULE_AUTHOR(SWP_AUTHOR); MODULE_DESCRIPTION(SWP_DESC); MODULE_VERSION(SWP_VERSION); MODULE_LICENSE(SWP_LICENSE); +MODULE_SOFTDEP("pre: inv_platform"); module_init(swp_module_init); module_exit(swp_module_exit); @@ -3047,3 +3262,5 @@ module_exit(swp_module_exit); + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.h b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.h index d28a0a3c968e..ad1f337b0c06 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.h +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.h @@ -1,10 +1,3 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - #ifndef INV_SWPS_H #define INV_SWPS_H @@ -24,7 +17,7 @@ /* Module information */ #define SWP_AUTHOR "Neil " #define SWP_DESC "Inventec port and transceiver driver" -#define SWP_VERSION "4.2.9" +#define SWP_VERSION "C1-4.3.5" #define SWP_LICENSE "GPL" /* Module status define */ @@ -52,9 +45,15 @@ #define PLATFORM_TYPE_LAVENDER_GA (181) #define PLATFORM_TYPE_LAVENDER_ONL (182) #define PLATFORM_TYPE_COTTONWOOD_RANGELEY (191) -#define PLATFORM_TYPE_MAPLE (201) +#define PLATFORM_TYPE_MAPLE_GA (201) +#define PLATFORM_TYPE_GULMOHAR_GA (202) +#define PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA (203) +#define PLATFORM_TYPE_PEONY_SFP_GA (204) +#define PLATFORM_TYPE_PEONY_COPPER_GA (205) +#define PLATFORM_TYPE_PEONY_AUTO (206) +#define PLATFORM_TYPE_MAPLE_B (207) /* Current running platfrom */ -#define PLATFORM_SETTINGS PLATFORM_TYPE_MAPLE +#define PLATFORM_SETTINGS PLATFORM_TYPE_MAPLE_B /* Define platform flag and kernel version */ #if (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA) @@ -99,12 +98,30 @@ #elif (PLATFORM_SETTINGS == PLATFORM_TYPE_COTTONWOOD_RANGELEY) #define SWPS_COTTONWOOD_RANGELEY (1) #define SWPS_KERN_VER_AF_3_10 (1) -#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE) - #define SWPS_MAPLE (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_GA) + #define SWPS_MAPLE_GA (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_B) + #define SWPS_MAPLE_B (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_GA) + #define SWPS_GULMOHAR (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA) + #define SWPS_GULMOHAR_2T_EVT1 (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_SFP_GA) + #define SWPS_PEONY_SFP (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_COPPER_GA) + #define SWPS_PEONY_COPPER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_AUTO) + #define SWPS_PEONY_SFP (1) + #define SWPS_PEONY_COPPER (1) #define SWPS_KERN_VER_AF_3_10 (1) #endif - struct inv_platform_s { int id; char name[64]; @@ -147,7 +164,13 @@ struct inv_platform_s platform_map[] = { {PLATFORM_TYPE_LAVENDER_GA, "Lavender_GA" }, {PLATFORM_TYPE_LAVENDER_ONL, "Lavender_ONL" }, {PLATFORM_TYPE_COTTONWOOD_RANGELEY, "Cottonwood_RANGELEY" }, - {PLATFORM_TYPE_MAPLE, "Maple" }, + {PLATFORM_TYPE_MAPLE_GA, "Maple_GA" }, + {PLATFORM_TYPE_MAPLE_B, "Maple_B" }, + {PLATFORM_TYPE_GULMOHAR_GA, "Gulmohar_GA" }, + {PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA, "Gulmohar_2T_EVT1_GA" }, + {PLATFORM_TYPE_PEONY_SFP_GA, "Peony_SFP_GA" }, + {PLATFORM_TYPE_PEONY_COPPER_GA, "Peony_Copper_GA" }, + {PLATFORM_TYPE_PEONY_AUTO, "Peony_Auto_Detect" }, }; @@ -156,7 +179,7 @@ struct inv_platform_s platform_map[] = { * ========================================== */ #ifdef SWPS_MAGNOLIA -unsigned magnolia_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548; +unsigned magnolia_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; struct inv_ioexp_layout_s magnolia_ioexp_layout[] = { /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ @@ -248,7 +271,7 @@ struct inv_port_layout_s magnolia_port_layout[] = { * ========================================== */ #ifdef SWPS_REDWOOD -unsigned redwood_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548; +unsigned redwood_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; struct inv_ioexp_layout_s redwood_ioexp_layout[] = { /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ @@ -313,7 +336,7 @@ struct inv_port_layout_s redwood_port_layout[] = { * ========================================== */ #ifdef SWPS_HUDSON32I_GA -unsigned hudsin32iga_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548; +unsigned hudsin32iga_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; struct inv_ioexp_layout_s hudson32iga_ioexp_layout[] = { /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ @@ -378,7 +401,7 @@ struct inv_port_layout_s hudson32iga_port_layout[] = { * ========================================== */ #ifdef SWPS_SPRUCE -unsigned spruce_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548; +unsigned spruce_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; struct inv_ioexp_layout_s spruce_ioexp_layout[] = { /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ @@ -404,33 +427,33 @@ struct inv_port_layout_s spruce_port_layout[] = { * ========================================== */ #ifdef SWPS_CYPRESS_GA1 -unsigned cypress_ga1_gpio_rest_mux = MUX_RST_GPIO_69_PAC9548; +unsigned cypress_ga1_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; struct inv_ioexp_layout_s cypress_ga1_ioexp_layout[] = { /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ - {0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ @@ -507,29 +530,29 @@ unsigned cypress_ga2_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA; struct inv_ioexp_layout_s cypress_ga2_ioexp_layout[] = { /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ - {0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ @@ -606,29 +629,29 @@ unsigned cypress_b_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA; struct inv_ioexp_layout_s cypress_b_ioexp_layout[] = { /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ - {0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, - {5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ - {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ - {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ }, {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ @@ -701,7 +724,7 @@ struct inv_port_layout_s cypress_b_port_layout[] = { * ========================================== */ #ifdef SWPS_REDWOOD_FSL -unsigned redwood_fsl_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548; +unsigned redwood_fsl_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; struct inv_ioexp_layout_s redwood_fsl_ioexp_layout[] = { /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ @@ -801,7 +824,7 @@ struct inv_port_layout_s tahoe_port_layout[] = { * ========================================== */ #ifdef SWPS_SEQUOIA -unsigned sequoia_gpio_rest_mux = MUX_RST_GPIO_69_PAC9548; +unsigned sequoia_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; struct inv_ioexp_layout_s sequoia_ioexp_layout[] = { /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ @@ -917,7 +940,7 @@ struct inv_port_layout_s sequoia_port_layout[] = { #if (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_GA) unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; #elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_ONL) -unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_69_PAC9548; +unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; #endif #ifdef SWPS_LAVENDER @@ -1035,7 +1058,7 @@ struct inv_port_layout_s lavender_port_layout[] = { * =========================================================== */ #ifdef SWPS_COTTONWOOD_RANGELEY -unsigned cottonwood_rangeley_gpio_rest_mux = MUX_RST_GPIO_500_PAC9548; +unsigned cottonwood_rangeley_gpio_rest_mux = MUX_RST_GPIO_500_PCA9548; struct inv_ioexp_layout_s cottonwood_rangeley_ioexp_layout[] = { /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ @@ -1055,13 +1078,13 @@ struct inv_port_layout_s cottonwood_rangeley_port_layout[] = { #endif /* =========================================================== - * Maple Layout configuration + * Maple Layout configuration (Old) * =========================================================== */ -#ifdef SWPS_MAPLE -unsigned maple_gpio_rest_mux = 249; +#ifdef SWPS_MAPLE_GA +unsigned maple_ga_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; -struct inv_ioexp_layout_s maple_ioexp_layout[] = { +struct inv_ioexp_layout_s maple_ga_ioexp_layout[] = { /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ {0, IOEXP_TYPE_MAPLE_0ABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ @@ -1093,7 +1116,7 @@ struct inv_ioexp_layout_s maple_ioexp_layout[] = { }, }; -struct inv_port_layout_s maple_port_layout[] = { +struct inv_port_layout_s maple_ga_port_layout[] = { /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ { 0, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} }, { 1, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} }, @@ -1154,6 +1177,438 @@ struct inv_port_layout_s maple_port_layout[] = { }; #endif +/* =========================================================== + * Maple Layout configuration (B version) + * =========================================================== + */ +#ifdef SWPS_MAPLE_B +unsigned maple_b_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s maple_b_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAPLE_0ABC, { { 6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + { 6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_MAPLE_NABC, { { 7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_MAPLE_NABC, { { 8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_MAPLE_NABC, { { 9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_MAPLE_NABC, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_MAPLE_NABC, { {11, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {11, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {11, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_MAPLE_NABC, { {12, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {12, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {12, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s maple_b_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 1, 23, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} }, + { 0, 22, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} }, + { 3, 25, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 4} }, + { 2, 24, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 3} }, + { 5, 27, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 6} }, + { 4, 26, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 5} }, + { 7, 29, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 8} }, + { 6, 28, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 7} }, + { 9, 31, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 14} }, + { 8, 30, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 13} }, + {11, 33, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 16} }, + {10, 32, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 15} }, + {13, 35, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 22} }, + {12, 34, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 21} }, + {15, 37, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 24} }, + {14, 36, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 23} }, + {17, 39, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 30} }, + {16, 38, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 29} }, + {19, 41, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 32} }, + {18, 40, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 31} }, + {21, 43, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 34} }, + {20, 42, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 33} }, + {23, 45, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 36} }, + {22, 44, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 35} }, + {25, 47, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 42} }, + {24, 46, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 41} }, + {27, 49, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 44} }, + {26, 48, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 43} }, + {29, 51, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 50} }, + {28, 50, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 49} }, + {31, 53, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 52} }, + {30, 52, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 51} }, + {33, 55, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 58} }, + {32, 54, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 57} }, + {35, 57, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 60} }, + {34, 56, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 59} }, + {37, 59, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 62} }, + {36, 58, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 61} }, + {39, 61, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 64} }, + {38, 60, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 63} }, + {41, 63, 6, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 66} }, + {40, 62, 6, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 65} }, + {43, 65, 6, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 68} }, + {42, 64, 6, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 67} }, + {45, 67, 6, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 70} }, + {44, 66, 6, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 69} }, + {47, 69, 6, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 72} }, + {46, 68, 6, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 71} }, + {49, 15, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} }, + {48, 14, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} }, + {51, 17, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 97, 98, 99,100} }, + {50, 16, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} }, + {53, 19, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {105,106,107,108} }, + {52, 18, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {113,114,115,116} }, + {55, 21, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {125,126,127,128} }, + {54, 20, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {121,122,123,124} }, +}; +#endif + + +/* ========================================== + * Gulmohar Layout configuration + * ========================================== + */ +#ifdef SWPS_GULMOHAR +unsigned gulmohar_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; + +struct inv_ioexp_layout_s gulmohar_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_GULMOHAR_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_GULMOHAR_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_GULMOHAR_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_GULMOHAR_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_GULMOHAR_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_GULMOHAR_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_GULMOHAR_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + + + +struct inv_port_layout_s gulmohar_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 1} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 2} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 3} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 4} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 5} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 6} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 7} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 8} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 9} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 10} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 11} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 12} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 21} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 22} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 23} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 24} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 33} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 34} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 35} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 36} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 37} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 38} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 39} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 40} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 41} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 42} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 43} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 44} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 49} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 50} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 51} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 52} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 53} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 54} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 55} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 56} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 65} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 66} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 67} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 68} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 69} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 70} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 71} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 72} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 81} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 82} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 83} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 84} }, + {48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 97, 98, 99,100} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 85, 86, 87, 88} }, + {50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {101,102,103,104} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {105,106,107,108} }, + {52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {109,110,111,112} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Gulmohar_2T EVT1 Layout configuration + * ========================================== + */ +#ifdef SWPS_GULMOHAR_2T_EVT1 +unsigned gulmohar_2t_evt1_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; + +struct inv_ioexp_layout_s gulmohar_2t_evt1_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC,{ {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC,{ {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC,{ {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xff}, {0x18, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + + + +struct inv_port_layout_s gulmohar_2t_evt1_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {54, 65, 6, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {55, 64, 6, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, +}; +#endif + + +/* =========================================================== + * Peony-SFP Layout configuration + * =========================================================== + */ +#ifdef SWPS_PEONY_SFP +unsigned peony_sfp_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL; + +struct inv_ioexp_layout_s peony_sfp_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s peony_sfp_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 20, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} }, + { 1, 21, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} }, + { 2, 22, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 3} }, + { 3, 23, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 4} }, + { 4, 24, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 5} }, + { 5, 25, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 6} }, + { 6, 26, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 7} }, + { 7, 27, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 8} }, + { 8, 28, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 13} }, + { 9, 29, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 14} }, + {10, 30, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 15} }, + {11, 31, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 16} }, + {12, 32, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 21} }, + {13, 33, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 22} }, + {14, 34, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 23} }, + {15, 35, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 24} }, + {16, 36, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 29} }, + {17, 37, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 30} }, + {18, 38, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 31} }, + {19, 39, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 32} }, + {20, 40, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 33} }, + {21, 41, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 34} }, + {22, 42, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 35} }, + {23, 43, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 36} }, + {24, 44, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 65} }, + {25, 45, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 66} }, + {26, 46, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 67} }, + {27, 47, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 68} }, + {28, 48, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 69} }, + {29, 49, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 70} }, + {30, 50, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 71} }, + {31, 51, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 72} }, + {32, 52, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 97} }, + {33, 53, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 98} }, + {34, 54, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 99} }, + {35, 55, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {100} }, + {36, 56, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {105} }, + {37, 57, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {106} }, + {38, 58, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {107} }, + {39, 59, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {108} }, + {40, 60, 6, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {113} }, + {41, 61, 6, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {114} }, + {42, 62, 6, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {115} }, + {43, 63, 6, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {116} }, + {44, 64, 6, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {121} }, + {45, 65, 6, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {122} }, + {46, 66, 6, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {123} }, + {47, 67, 6, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {124} }, + {48, 12, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 49, 50, 51, 52} }, + {49, 13, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 57, 58, 59, 60} }, + {50, 14, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 61, 62, 63, 64} }, + {51, 15, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} }, + {52, 16, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} }, + {53, 17, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} }, +}; +#endif + + +/* =========================================================== + * Peony-Copper Layout configuration + * =========================================================== + */ +#ifdef SWPS_PEONY_COPPER +unsigned peony_copper_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL; + +struct inv_ioexp_layout_s peony_copper_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, +}; + +struct inv_port_layout_s peony_copper_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + {48, 4, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 49, 50, 51, 52} }, + {49, 5, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 57, 58, 59, 60} }, + {50, 6, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 61, 62, 63, 64} }, + {51, 7, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} }, + {52, 8, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} }, + {53, 9, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} }, +}; +#endif + + + #endif /* INV_SWPS_H */ @@ -1162,3 +1617,5 @@ struct inv_port_layout_s maple_port_layout[] = { + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.c index 4564b5855fd8..985bfbb45eb8 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.c @@ -2,9 +2,14 @@ #include #include "io_expander.h" +/* For build single module using (Ex: ONL platform) */ +#include +//#include + + static struct ioexp_obj_s *ioexp_head_p = NULL; static struct ioexp_obj_s *ioexp_tail_p = NULL; - +extern int io_no_init; /* ========== Register IOEXP layout ========== */ @@ -571,6 +576,7 @@ struct ioexp_map_s cpld_map_cottonwood = { }, }; + struct ioexp_map_s ioexp_map_maple_0abc = { .chip_amount = 3, @@ -614,6 +620,7 @@ struct ioexp_map_s ioexp_map_maple_0abc = { }, }; + struct ioexp_map_s ioexp_map_maple_nabc = { .chip_amount = 3, @@ -675,6 +682,440 @@ struct ioexp_map_s ioexp_map_maple_nabc = { }, }; + +struct ioexp_map_s ioexp_map_gulmohar_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_7abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_1abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_3abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_7abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {1, 0, 4}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 1, 1}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 1, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 0, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 1}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 6}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 3}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {1, 0, 1}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {1, 0, 6}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {1, 1, 3}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + {2, 0, 1}, /* map_reset[6] = QRESET_QSFP_N_P(X+6) */ + {2, 0, 6}, /* map_reset[7] = QRESET_QSFP_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 2}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 7}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 1, 4}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + {2, 0, 2}, /* map_lpmod[6] = LPMODE_QSFP_P(X+6) */ + {2, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP_P(X+7) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {1, 0, 0}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {1, 0, 5}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {1, 1, 2}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + {2, 0, 0}, /* map_modsel[6] = MODSEL_QSFP_N_P(X+6) */ + {2, 0, 5}, /* map_modsel[7] = MODSEL_QSFP_N_P(X+7) */ + }, +}; + + +/* PortType: SFP / 8 port + * Platform: Cypress, Peony_SFP + */ +struct ioexp_map_s ioexp_map_sfp_8p_layout_1 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +/* PortType: QSFP / 6 port + * Platform: Gulmohar, Peony_SFP, Peony_Copper + */ +struct ioexp_map_s ioexp_map_6p_qsfp_type_1 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + /* ========== Private functions ========== */ int check_channel_tier_1(void); @@ -1125,32 +1566,35 @@ common_ioexp_init(struct ioexp_obj_s *self) { if (self->mode == IOEXP_MODE_DIRECT) { goto update_common_ioexp_init; } - /* Setup default value to each physical IO Expander */ - for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ - /* Get address mapping */ - addr_p = &(self->ioexp_map_p->map_addr[chip_id]); - if (!addr_p){ - SWPS_ERR("%s: IOEXP config incorrect! :%d \n", - __func__, chip_id); - return -1; - } - /* Setup default value */ - for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){ - - /* [Desc] Skip the setup default value behavior - [Note] Setup default value = -1 if you don't want to write the value to IOEXP or CPLD - */ - if(addr_p->write_offset[offset] < 0){ - SWPS_DEBUG("skip a write_offset <%d>\n", addr_p->conf_offset[offset]); - continue; + if (!io_no_init) { /*normal init*/ + + /* Setup default value to each physical IO Expander */ + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ + /* Get address mapping */ + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + if (!addr_p){ + SWPS_ERR("%s: IOEXP config incorrect! :%d \n", + __func__, chip_id); + return -1; } - err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id), - addr_p->write_offset[offset], - addr_p->data_default[offset]); - if (err_code < 0){ - SWPS_ERR("%s: set default fail! :%d \n", - __func__, err_code); - return ERR_IOEXP_UNEXCPT; + /* Setup default value */ + for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){ + + /* [Desc] Skip the setup default value behavior + [Note] Setup default value = -1 if you don't want to write the value to IOEXP or CPLD + */ + if(addr_p->write_offset[offset] < 0){ + SWPS_DEBUG("skip a write_offset <%d>\n", addr_p->conf_offset[offset]); + continue; + } + err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id), + addr_p->write_offset[offset], + addr_p->data_default[offset]); + if (err_code < 0){ + SWPS_ERR("%s: set default fail! :%d \n", + __func__, err_code); + return ERR_IOEXP_UNEXCPT; + } } } } @@ -1171,24 +1615,56 @@ common_ioexp_init(struct ioexp_obj_s *self) { int _is_channel_ready(struct ioexp_obj_s *self){ - int buf = 0; - int chip_id = 0; /* Use first chip which be registered */ - int data_id = 0; /* Use first byte which be registered */ - struct ioexp_addr_s *ioexp_addr = NULL; + int chip_id = 0; + int byte_id = 0; + int getval = ERR_IOEXP_UNEXCPT; + int chkval = ERR_IOEXP_UNEXCPT; + char *emsg = "ERR"; + struct ioexp_addr_s *addr_p = NULL; - ioexp_addr = &(self->ioexp_map_p->map_addr[chip_id]); - if (!ioexp_addr){ - SWPS_ERR("%s: config incorrect!\n", __func__); - return ERR_IOEXP_UNEXCPT; + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++) { + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + if (!addr_p){ + emsg = "IOEXP config incorrect"; + goto err_is_channel_ready; + } + for (byte_id=0; byte_id<(self->ioexp_map_p->data_width); byte_id++) { + if (addr_p->conf_offset[byte_id] < 0) { + continue; + } + if ((addr_p->conf_default[byte_id]) != 0) { + goto go_is_channel_ready; + } + } + if (chip_id == ((self->ioexp_map_p->chip_amount) - 1)) { + SWPS_DEBUG("%s: no non-zero config", __func__); + break; + } } - buf = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id), - ioexp_addr->read_offset[data_id]); - if (buf >= 0){ + chip_id = 0; + byte_id = 0; + +go_is_channel_ready: + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + chkval = addr_p->conf_default[byte_id]; + getval = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id), + addr_p->conf_offset[byte_id]); + + SWPS_DEBUG("%s: target info :%d :%d :%d :%d :%d\n", + __func__, self->ioexp_id, chip_id, byte_id, chkval, getval); + + if ((getval >= 0) && (getval == chkval)) { return 1; } return 0; + +err_is_channel_ready: + SWPS_ERR("%s: %s :%d :%d :%d :%d :%d\n", + __func__, emsg, self->ioexp_id, chip_id, byte_id, chkval, getval); + return ERR_IOEXP_UNEXCPT; } + int _ioexp_init_handler(struct ioexp_obj_s *self){ @@ -1395,8 +1871,6 @@ get_ioexp_map(int ioexp_type){ return &ioexp_map_hudson32iga_p01p08_p17p24; case IOEXP_TYPE_HUDSON32IGA_P09P16: return &ioexp_map_hudson32iga_p09p16_p25p32; - case IOEXP_TYPE_CYPRESS_NABC: - return &ioexp_map_cypress_nabc; case IOEXP_TYPE_CYPRESS_7ABC: return &ioexp_map_cypress_7abc; case IOEXP_TYPE_TAHOE_5A: @@ -1413,6 +1887,22 @@ get_ioexp_map(int ioexp_type){ return &ioexp_map_maple_0abc; case IOEXP_TYPE_MAPLE_NABC: return &ioexp_map_maple_nabc; + case IOEXP_TYPE_GULMOHAR_NABC: + return &ioexp_map_gulmohar_nabc; + case IOEXP_TYPE_GULMOHAR_7ABC: + return &ioexp_map_gulmohar_7abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + return &ioexp_map_gulmohar_2t_evt1_nabc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + return &ioexp_map_gulmohar_2t_evt1_1abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + return &ioexp_map_gulmohar_2t_evt1_3abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + return &ioexp_map_gulmohar_2t_evt1_7abc; + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + return &ioexp_map_sfp_8p_layout_1; + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + return &ioexp_map_6p_qsfp_type_1; default: return NULL; } @@ -1497,8 +1987,13 @@ setup_ioexp_public_cb(struct ioexp_obj_s *self, self->set_hard_rs0 = ioexp_set_not_support; self->set_hard_rs1 = ioexp_set_not_support; return 0; - case IOEXP_TYPE_CYPRESS_NABC: + case IOEXP_TYPE_MAPLE_NABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: self->get_present = common_get_present; self->get_tx_fault = common_get_tx_fault; self->get_rxlos = common_get_rxlos; @@ -1515,6 +2010,7 @@ setup_ioexp_public_cb(struct ioexp_obj_s *self, self->set_hard_rs0 = common_set_hard_rs0; self->set_hard_rs1 = common_set_hard_rs1; return 0; + case IOEXP_TYPE_MAGINOLIA_7AB: case IOEXP_TYPE_SPRUCE_7AB: case IOEXP_TYPE_REDWOOD_P01P08: @@ -1527,6 +2023,9 @@ setup_ioexp_public_cb(struct ioexp_obj_s *self, case IOEXP_TYPE_SEQUOIA_NABC: case IOEXP_TYPE_LAVENDER_P65: case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: self->get_present = common_get_present; self->get_tx_fault = ioexp_get_not_support; self->get_rxlos = ioexp_get_not_support; @@ -1565,7 +2064,6 @@ setup_ioexp_private_cb(struct ioexp_obj_s *self, case IOEXP_TYPE_REDWOOD_P09P16: case IOEXP_TYPE_HUDSON32IGA_P01P08: case IOEXP_TYPE_HUDSON32IGA_P09P16: - case IOEXP_TYPE_CYPRESS_NABC: case IOEXP_TYPE_CYPRESS_7ABC: case IOEXP_TYPE_TAHOE_5A: case IOEXP_TYPE_TAHOE_6ABC: @@ -1574,6 +2072,14 @@ setup_ioexp_private_cb(struct ioexp_obj_s *self, case CPLD_TYPE_COTTONWOOD: case IOEXP_TYPE_MAPLE_NABC: case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: self->init = common_ioexp_init; self->check = common_ioexp_check; self->update_all = common_ioexp_update_all; @@ -1600,11 +2106,6 @@ setup_i2c_client_one(struct ioexp_obj_s *self, struct ioexp_i2c_s *i2c_curr_p = NULL; int chan_id = self->ioexp_map_p->map_addr[chip_id].chan_id; - adap = i2c_get_adapter(chan_id); - if(!adap){ - err_msg = "Can not get adap!"; - goto err_ioexp_setup_i2c_1; - } client = kzalloc(sizeof(*client), GFP_KERNEL); if (!client){ err_msg = "Can not kzalloc client!"; @@ -1615,6 +2116,11 @@ setup_i2c_client_one(struct ioexp_obj_s *self, err_msg = "Can not kzalloc i2c_obj_p!"; goto err_ioexp_setup_i2c_2; } + adap = i2c_get_adapter(chan_id); + if(!adap){ + err_msg = "Can not get adap!"; + goto err_ioexp_setup_i2c_3; + } client->adapter = adap; client->addr = self->ioexp_map_p->map_addr[chip_id].chip_addr; i2c_obj_p->i2c_client_p = client; @@ -1631,6 +2137,8 @@ setup_i2c_client_one(struct ioexp_obj_s *self, } return 0; +err_ioexp_setup_i2c_3: + kfree(i2c_obj_p); err_ioexp_setup_i2c_2: kfree(client); err_ioexp_setup_i2c_1: @@ -1661,6 +2169,11 @@ setup_ioexp_config(struct ioexp_obj_s *self) { int chip_id, offset, err_code; struct ioexp_addr_s *addr_p; + if (io_no_init) { + + SWPS_INFO("io_no_init:%d \n", io_no_init); + return 0; + } for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ addr_p = &(self->ioexp_map_p->map_addr[chip_id]); @@ -1743,7 +2256,10 @@ _create_ioexp_obj(int ioexp_id, i2c_next_p = result_p->i2c_head_p; while (i2c_curr_p){ i2c_next_p = i2c_curr_p->next; - kfree(i2c_curr_p->i2c_client_p); + if (i2c_curr_p->i2c_client_p) { + i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter); + kfree(i2c_curr_p->i2c_client_p); + } kfree(i2c_curr_p); i2c_curr_p = i2c_next_p; } @@ -1778,6 +2294,7 @@ create_ioexp_obj(int ioexp_id, ioexp_tail_p = ioexp_p; return 0; } +EXPORT_SYMBOL(create_ioexp_obj); static int @@ -1818,7 +2335,6 @@ init_ioexp_objs(void){ * -1: Detect topology error * -2: SWPS internal error */ - struct ioexp_obj_s *curr_p = ioexp_head_p; if (!curr_p) { @@ -1835,6 +2351,7 @@ init_ioexp_objs(void){ SWPS_DEBUG("%s: done.\n", __func__); return 0; } +EXPORT_SYMBOL(init_ioexp_objs); void @@ -1861,7 +2378,10 @@ clean_ioexp_objs(void){ i2c_curr_p = ioexp_curr_p->i2c_head_p; while (i2c_curr_p) { i2c_next_p = i2c_curr_p->next; - kfree(i2c_curr_p->i2c_client_p); + if (i2c_curr_p->i2c_client_p) { + i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter); + kfree(i2c_curr_p->i2c_client_p); + } kfree(i2c_curr_p); i2c_curr_p = i2c_next_p; } @@ -1871,6 +2391,7 @@ clean_ioexp_objs(void){ ioexp_tail_p = NULL; SWPS_DEBUG("%s: done.\n", __func__); } +EXPORT_SYMBOL(clean_ioexp_objs); int @@ -1888,6 +2409,7 @@ check_ioexp_objs(void){ } return 0; } +EXPORT_SYMBOL(check_ioexp_objs); struct ioexp_obj_s * @@ -1905,6 +2427,7 @@ get_ioexp_obj(int ioexp_id){ } return result_p; } +EXPORT_SYMBOL(get_ioexp_obj); void @@ -1917,7 +2440,7 @@ unlock_ioexp_all(void) { ioexp_curr_p = ioexp_curr_p->next; } } - +EXPORT_SYMBOL(unlock_ioexp_all); int lock_ioexp_all(void) { @@ -1930,6 +2453,7 @@ lock_ioexp_all(void) { } return 0; } +EXPORT_SYMBOL(lock_ioexp_all); int @@ -1941,6 +2465,7 @@ check_channel_tier_1(void) { } return 0; } +EXPORT_SYMBOL(check_channel_tier_1); static int @@ -2037,10 +2562,11 @@ resync_channel_tier_1(void) { SWPS_ERR("%s: %s\n", __func__, emsg); return -1; } +EXPORT_SYMBOL(resync_channel_tier_1); - - +/* For build single module using (Ex: ONL platform) */ +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.h b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.h index 1af909e2466a..6f9f7b46291e 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.h +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.h @@ -1,10 +1,3 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - #ifndef IO_EXPANDER_H #define IO_EXPANDER_H @@ -12,24 +5,31 @@ /* IOEXP type define (SFP series) */ -#define IOEXP_TYPE_MAGINOLIA_NAB (10101) -#define IOEXP_TYPE_MAGINOLIA_4AB (10102) -#define IOEXP_TYPE_CYPRESS_NABC (10103) -#define IOEXP_TYPE_MAPLE_NABC (10104) +#define IOEXP_TYPE_MAGINOLIA_NAB (10101) +#define IOEXP_TYPE_MAGINOLIA_4AB (10102) +#define IOEXP_TYPE_MAPLE_NABC (10104) +#define IOEXP_TYPE_GULMOHAR_NABC (10105) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC (10106) +#define IOEXP_TYPE_SFP_8P_LAYOUT_1 (10107) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC (10108) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC (10109) /* IOEXP type define (QSFP series) */ -#define IOEXP_TYPE_MAGINOLIA_7AB (10201) -#define IOEXP_TYPE_REDWOOD_P01P08 (10202) -#define IOEXP_TYPE_REDWOOD_P09P16 (10203) -#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204) -#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205) -#define IOEXP_TYPE_SPRUCE_7AB (10206) -#define IOEXP_TYPE_CYPRESS_7ABC (10207) -#define IOEXP_TYPE_TAHOE_5A (10208) -#define IOEXP_TYPE_TAHOE_6ABC (10209) -#define IOEXP_TYPE_SEQUOIA_NABC (10210) -#define IOEXP_TYPE_LAVENDER_P65 (10211) -#define IOEXP_TYPE_MAPLE_0ABC (10212) +#define IOEXP_TYPE_MAGINOLIA_7AB (10201) +#define IOEXP_TYPE_REDWOOD_P01P08 (10202) +#define IOEXP_TYPE_REDWOOD_P09P16 (10203) +#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204) +#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205) +#define IOEXP_TYPE_SPRUCE_7AB (10206) +#define IOEXP_TYPE_CYPRESS_7ABC (10207) +#define IOEXP_TYPE_TAHOE_5A (10208) +#define IOEXP_TYPE_TAHOE_6ABC (10209) +#define IOEXP_TYPE_SEQUOIA_NABC (10210) +#define IOEXP_TYPE_LAVENDER_P65 (10211) +#define IOEXP_TYPE_MAPLE_0ABC (10212) +#define IOEXP_TYPE_GULMOHAR_7ABC (10213) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC (10214) +#define IOEXP_TYPE_QSFP_6P_LAYOUT_1 (10215) /* CPLD type define */ #define CPLD_TYPE_COTTONWOOD (10301) @@ -87,8 +87,8 @@ struct ioexp_bitmap_s { }; struct ioexp_map_s { - int chip_amount; /* Number of chips that IOEXP object content */ - int data_width; /* Number of (Read/Write/Config) bytes */ + int chip_amount; /* Number of chips that IOEXP object content */ + int data_width; /* Number of (Read/Write/Config) bytes */ struct ioexp_addr_s *map_addr; /* Chip address info */ struct ioexp_bitmap_s map_present[10]; /* IOEXP for SFP / QSFP */ struct ioexp_bitmap_s map_tx_disable[10]; /* IOEXP for SFP */ @@ -185,3 +185,5 @@ int resync_channel_tier_1(void); + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/lpc_ich.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/lpc_ich.c new file mode 100644 index 000000000000..66ff6e694d6f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/lpc_ich.c @@ -0,0 +1,1131 @@ +/* + * lpc_ich.c - LPC interface for Intel ICH + * + * LPC bridge function of the Intel ICH contains many other + * functional units, such as Interrupt controllers, Timers, + * Power Management, System Management, GPIO, RTC, and LPC + * Configuration Registers. + * + * This driver is derived from lpc_sch. + + * Copyright (c) 2011 Extreme Engineering Solution, Inc. + * Author: Aaron Sierra + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This driver supports the following I/O Controller hubs: + * (See the intel documentation on http://developer.intel.com.) + * document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO) + * document number 290687-002, 298242-027: 82801BA (ICH2) + * document number 290733-003, 290739-013: 82801CA (ICH3-S) + * document number 290716-001, 290718-007: 82801CAM (ICH3-M) + * document number 290744-001, 290745-025: 82801DB (ICH4) + * document number 252337-001, 252663-008: 82801DBM (ICH4-M) + * document number 273599-001, 273645-002: 82801E (C-ICH) + * document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R) + * document number 300641-004, 300884-013: 6300ESB + * document number 301473-002, 301474-026: 82801F (ICH6) + * document number 313082-001, 313075-006: 631xESB, 632xESB + * document number 307013-003, 307014-024: 82801G (ICH7) + * document number 322896-001, 322897-001: NM10 + * document number 313056-003, 313057-017: 82801H (ICH8) + * document number 316972-004, 316973-012: 82801I (ICH9) + * document number 319973-002, 319974-002: 82801J (ICH10) + * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) + * document number 320066-003, 320257-008: EP80597 (IICH) + * document number 324645-001, 324646-001: Cougar Point (CPT) + * document number TBD : Patsburg (PBG) + * document number TBD : DH89xxCC + * document number TBD : Panther Point + * document number TBD : Lynx Point + * document number TBD : Lynx Point-LP + * document number TBD : Wellsburg + * document number TBD : Avoton SoC + * document number TBD : Coleto Creek + * document number TBD : Wildcat Point-LP + * document number TBD : 9 Series + * document number TBD : Lewisburg + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACPIBASE 0x40 +#define ACPIBASE_GPE_OFF 0x28 +#define ACPIBASE_GPE_END 0x2f +#define ACPIBASE_SMI_OFF 0x30 +#define ACPIBASE_SMI_END 0x33 +#define ACPIBASE_PMC_OFF 0x08 +#define ACPIBASE_PMC_END 0x0c +#define ACPIBASE_TCO_OFF 0x60 +#define ACPIBASE_TCO_END 0x7f +#define ACPICTRL_PMCBASE 0x44 + +#define ACPIBASE_GCS_OFF 0x3410 +#define ACPIBASE_GCS_END 0x3414 + +#define GPIOBASE_ICH0 0x58 +#define GPIOCTRL_ICH0 0x5C +#define GPIOBASE_ICH6 0x48 +#define GPIOCTRL_ICH6 0x4C + +#define RCBABASE 0xf0 + +#define wdt_io_res(i) wdt_res(0, i) +#define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) +#define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) + +struct lpc_ich_priv { + int chipset; + + int abase; /* ACPI base */ + int actrl_pbase; /* ACPI control or PMC base */ + int gbase; /* GPIO base */ + int gctrl; /* GPIO control */ + + int abase_save; /* Cached ACPI base value */ + int actrl_pbase_save; /* Cached ACPI control or PMC base value */ + int gctrl_save; /* Cached GPIO control value */ +}; + +static struct resource wdt_ich_res[] = { + /* ACPI - TCO */ + { + .flags = IORESOURCE_IO, + }, + /* ACPI - SMI */ + { + .flags = IORESOURCE_IO, + }, + /* GCS or PMC */ + { + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource gpio_ich_res[] = { + /* GPIO */ + { + .flags = IORESOURCE_IO, + }, + /* ACPI - GPE0 */ + { + .flags = IORESOURCE_IO, + }, +}; + +static struct mfd_cell lpc_ich_wdt_cell = { + .name = "iTCO_wdt", + .num_resources = ARRAY_SIZE(wdt_ich_res), + .resources = wdt_ich_res, + .ignore_resource_conflicts = true, +}; + +static struct mfd_cell lpc_ich_gpio_cell = { + .name = "gpio_ich", + .num_resources = ARRAY_SIZE(gpio_ich_res), + .resources = gpio_ich_res, + .ignore_resource_conflicts = true, +}; + +/* chipset related info */ +enum lpc_chipsets { + LPC_ICH = 0, /* ICH */ + LPC_ICH0, /* ICH0 */ + LPC_ICH2, /* ICH2 */ + LPC_ICH2M, /* ICH2-M */ + LPC_ICH3, /* ICH3-S */ + LPC_ICH3M, /* ICH3-M */ + LPC_ICH4, /* ICH4 */ + LPC_ICH4M, /* ICH4-M */ + LPC_CICH, /* C-ICH */ + LPC_ICH5, /* ICH5 & ICH5R */ + LPC_6300ESB, /* 6300ESB */ + LPC_ICH6, /* ICH6 & ICH6R */ + LPC_ICH6M, /* ICH6-M */ + LPC_ICH6W, /* ICH6W & ICH6RW */ + LPC_631XESB, /* 631xESB/632xESB */ + LPC_ICH7, /* ICH7 & ICH7R */ + LPC_ICH7DH, /* ICH7DH */ + LPC_ICH7M, /* ICH7-M & ICH7-U */ + LPC_ICH7MDH, /* ICH7-M DH */ + LPC_NM10, /* NM10 */ + LPC_ICH8, /* ICH8 & ICH8R */ + LPC_ICH8DH, /* ICH8DH */ + LPC_ICH8DO, /* ICH8DO */ + LPC_ICH8M, /* ICH8M */ + LPC_ICH8ME, /* ICH8M-E */ + LPC_ICH9, /* ICH9 */ + LPC_ICH9R, /* ICH9R */ + LPC_ICH9DH, /* ICH9DH */ + LPC_ICH9DO, /* ICH9DO */ + LPC_ICH9M, /* ICH9M */ + LPC_ICH9ME, /* ICH9M-E */ + LPC_ICH10, /* ICH10 */ + LPC_ICH10R, /* ICH10R */ + LPC_ICH10D, /* ICH10D */ + LPC_ICH10DO, /* ICH10DO */ + LPC_PCH, /* PCH Desktop Full Featured */ + LPC_PCHM, /* PCH Mobile Full Featured */ + LPC_P55, /* P55 */ + LPC_PM55, /* PM55 */ + LPC_H55, /* H55 */ + LPC_QM57, /* QM57 */ + LPC_H57, /* H57 */ + LPC_HM55, /* HM55 */ + LPC_Q57, /* Q57 */ + LPC_HM57, /* HM57 */ + LPC_PCHMSFF, /* PCH Mobile SFF Full Featured */ + LPC_QS57, /* QS57 */ + LPC_3400, /* 3400 */ + LPC_3420, /* 3420 */ + LPC_3450, /* 3450 */ + LPC_EP80579, /* EP80579 */ + LPC_CPT, /* Cougar Point */ + LPC_CPTD, /* Cougar Point Desktop */ + LPC_CPTM, /* Cougar Point Mobile */ + LPC_PBG, /* Patsburg */ + LPC_DH89XXCC, /* DH89xxCC */ + LPC_PPT, /* Panther Point */ + LPC_LPT, /* Lynx Point */ + LPC_LPT_LP, /* Lynx Point-LP */ + LPC_WBG, /* Wellsburg */ + LPC_AVN, /* Avoton SoC */ + LPC_BAYTRAIL, /* Bay Trail SoC */ + LPC_COLETO, /* Coleto Creek */ + LPC_WPT_LP, /* Wildcat Point-LP */ + LPC_BRASWELL, /* Braswell SoC */ + LPC_LEWISBURG, /* Lewisburg */ + LPC_9S, /* 9 Series */ +}; + +static struct lpc_ich_info lpc_chipset_info[] = { + [LPC_ICH] = { + .name = "ICH", + .iTCO_version = 1, + }, + [LPC_ICH0] = { + .name = "ICH0", + .iTCO_version = 1, + }, + [LPC_ICH2] = { + .name = "ICH2", + .iTCO_version = 1, + }, + [LPC_ICH2M] = { + .name = "ICH2-M", + .iTCO_version = 1, + }, + [LPC_ICH3] = { + .name = "ICH3-S", + .iTCO_version = 1, + }, + [LPC_ICH3M] = { + .name = "ICH3-M", + .iTCO_version = 1, + }, + [LPC_ICH4] = { + .name = "ICH4", + .iTCO_version = 1, + }, + [LPC_ICH4M] = { + .name = "ICH4-M", + .iTCO_version = 1, + }, + [LPC_CICH] = { + .name = "C-ICH", + .iTCO_version = 1, + }, + [LPC_ICH5] = { + .name = "ICH5 or ICH5R", + .iTCO_version = 1, + }, + [LPC_6300ESB] = { + .name = "6300ESB", + .iTCO_version = 1, + }, + [LPC_ICH6] = { + .name = "ICH6 or ICH6R", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH6M] = { + .name = "ICH6-M", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH6W] = { + .name = "ICH6W or ICH6RW", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_631XESB] = { + .name = "631xESB/632xESB", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH7] = { + .name = "ICH7 or ICH7R", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7DH] = { + .name = "ICH7DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7M] = { + .name = "ICH7-M or ICH7-U", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7MDH] = { + .name = "ICH7-M DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_NM10] = { + .name = "NM10", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8] = { + .name = "ICH8 or ICH8R", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8DH] = { + .name = "ICH8DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8DO] = { + .name = "ICH8DO", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8M] = { + .name = "ICH8M", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8ME] = { + .name = "ICH8M-E", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH9] = { + .name = "ICH9", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9R] = { + .name = "ICH9R", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9DH] = { + .name = "ICH9DH", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9DO] = { + .name = "ICH9DO", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9M] = { + .name = "ICH9M", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9ME] = { + .name = "ICH9M-E", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH10] = { + .name = "ICH10", + .iTCO_version = 2, + .gpio_version = ICH_V10CONS_GPIO, + }, + [LPC_ICH10R] = { + .name = "ICH10R", + .iTCO_version = 2, + .gpio_version = ICH_V10CONS_GPIO, + }, + [LPC_ICH10D] = { + .name = "ICH10D", + .iTCO_version = 2, + .gpio_version = ICH_V10CORP_GPIO, + }, + [LPC_ICH10DO] = { + .name = "ICH10DO", + .iTCO_version = 2, + .gpio_version = ICH_V10CORP_GPIO, + }, + [LPC_PCH] = { + .name = "PCH Desktop Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PCHM] = { + .name = "PCH Mobile Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_P55] = { + .name = "P55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PM55] = { + .name = "PM55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_H55] = { + .name = "H55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_QM57] = { + .name = "QM57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_H57] = { + .name = "H57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_HM55] = { + .name = "HM55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_Q57] = { + .name = "Q57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_HM57] = { + .name = "HM57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PCHMSFF] = { + .name = "PCH Mobile SFF Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_QS57] = { + .name = "QS57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3400] = { + .name = "3400", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3420] = { + .name = "3420", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3450] = { + .name = "3450", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_EP80579] = { + .name = "EP80579", + .iTCO_version = 2, + }, + [LPC_CPT] = { + .name = "Cougar Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_CPTD] = { + .name = "Cougar Point Desktop", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_CPTM] = { + .name = "Cougar Point Mobile", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PBG] = { + .name = "Patsburg", + .iTCO_version = 2, + }, + [LPC_DH89XXCC] = { + .name = "DH89xxCC", + .iTCO_version = 2, + }, + [LPC_PPT] = { + .name = "Panther Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_LPT] = { + .name = "Lynx Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_LPT_LP] = { + .name = "Lynx Point_LP", + .iTCO_version = 2, + }, + [LPC_WBG] = { + .name = "Wellsburg", + .iTCO_version = 2, + }, + [LPC_AVN] = { + .name = "Avoton SoC", + .iTCO_version = 3, + .gpio_version = AVOTON_GPIO, + }, + [LPC_BAYTRAIL] = { + .name = "Bay Trail SoC", + .iTCO_version = 3, + }, + [LPC_COLETO] = { + .name = "Coleto Creek", + .iTCO_version = 2, + }, + [LPC_WPT_LP] = { + .name = "Wildcat Point_LP", + .iTCO_version = 2, + }, + [LPC_BRASWELL] = { + .name = "Braswell SoC", + .iTCO_version = 3, + }, + [LPC_LEWISBURG] = { + .name = "Lewisburg", + .iTCO_version = 2, + }, + [LPC_9S] = { + .name = "9 Series", + .iTCO_version = 2, + }, +}; + +/* + * This data only exists for exporting the supported PCI ids + * via MODULE_DEVICE_TABLE. We do not actually register a + * pci_driver, because the I/O Controller Hub has also other + * functions that probably will be registered by other drivers. + */ +static const struct pci_device_id lpc_ich_ids[] = { + { PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL}, + { PCI_VDEVICE(INTEL, 0x1c41), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c42), LPC_CPTD}, + { PCI_VDEVICE(INTEL, 0x1c43), LPC_CPTM}, + { PCI_VDEVICE(INTEL, 0x1c44), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c45), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c46), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c47), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c48), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c49), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4a), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4b), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4c), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4d), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4e), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4f), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c50), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c51), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c52), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c53), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c54), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c55), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c56), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c57), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c58), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c59), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5a), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5b), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5c), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5d), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5e), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5f), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1d40), LPC_PBG}, + { PCI_VDEVICE(INTEL, 0x1d41), LPC_PBG}, + { PCI_VDEVICE(INTEL, 0x1e40), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e41), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e42), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e43), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e44), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e45), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e46), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e47), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e48), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e49), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4a), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4b), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4c), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4d), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4e), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4f), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e50), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e51), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e52), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e53), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e54), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e55), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e56), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e57), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e58), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e59), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5a), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5b), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5c), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5d), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5e), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5f), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1f38), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x229c), LPC_BRASWELL}, + { PCI_VDEVICE(INTEL, 0x2310), LPC_DH89XXCC}, + { PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO}, + { PCI_VDEVICE(INTEL, 0x2410), LPC_ICH}, + { PCI_VDEVICE(INTEL, 0x2420), LPC_ICH0}, + { PCI_VDEVICE(INTEL, 0x2440), LPC_ICH2}, + { PCI_VDEVICE(INTEL, 0x244c), LPC_ICH2M}, + { PCI_VDEVICE(INTEL, 0x2450), LPC_CICH}, + { PCI_VDEVICE(INTEL, 0x2480), LPC_ICH3}, + { PCI_VDEVICE(INTEL, 0x248c), LPC_ICH3M}, + { PCI_VDEVICE(INTEL, 0x24c0), LPC_ICH4}, + { PCI_VDEVICE(INTEL, 0x24cc), LPC_ICH4M}, + { PCI_VDEVICE(INTEL, 0x24d0), LPC_ICH5}, + { PCI_VDEVICE(INTEL, 0x25a1), LPC_6300ESB}, + { PCI_VDEVICE(INTEL, 0x2640), LPC_ICH6}, + { PCI_VDEVICE(INTEL, 0x2641), LPC_ICH6M}, + { PCI_VDEVICE(INTEL, 0x2642), LPC_ICH6W}, + { PCI_VDEVICE(INTEL, 0x2670), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2671), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2672), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2673), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2674), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2675), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2676), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2677), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2678), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2679), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267a), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267b), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267c), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267d), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267e), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267f), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x27b0), LPC_ICH7DH}, + { PCI_VDEVICE(INTEL, 0x27b8), LPC_ICH7}, + { PCI_VDEVICE(INTEL, 0x27b9), LPC_ICH7M}, + { PCI_VDEVICE(INTEL, 0x27bc), LPC_NM10}, + { PCI_VDEVICE(INTEL, 0x27bd), LPC_ICH7MDH}, + { PCI_VDEVICE(INTEL, 0x2810), LPC_ICH8}, + { PCI_VDEVICE(INTEL, 0x2811), LPC_ICH8ME}, + { PCI_VDEVICE(INTEL, 0x2812), LPC_ICH8DH}, + { PCI_VDEVICE(INTEL, 0x2814), LPC_ICH8DO}, + { PCI_VDEVICE(INTEL, 0x2815), LPC_ICH8M}, + { PCI_VDEVICE(INTEL, 0x2912), LPC_ICH9DH}, + { PCI_VDEVICE(INTEL, 0x2914), LPC_ICH9DO}, + { PCI_VDEVICE(INTEL, 0x2916), LPC_ICH9R}, + { PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME}, + { PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9}, + { PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M}, + { PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO}, + { PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R}, + { PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10}, + { PCI_VDEVICE(INTEL, 0x3a1a), LPC_ICH10D}, + { PCI_VDEVICE(INTEL, 0x3b00), LPC_PCH}, + { PCI_VDEVICE(INTEL, 0x3b01), LPC_PCHM}, + { PCI_VDEVICE(INTEL, 0x3b02), LPC_P55}, + { PCI_VDEVICE(INTEL, 0x3b03), LPC_PM55}, + { PCI_VDEVICE(INTEL, 0x3b06), LPC_H55}, + { PCI_VDEVICE(INTEL, 0x3b07), LPC_QM57}, + { PCI_VDEVICE(INTEL, 0x3b08), LPC_H57}, + { PCI_VDEVICE(INTEL, 0x3b09), LPC_HM55}, + { PCI_VDEVICE(INTEL, 0x3b0a), LPC_Q57}, + { PCI_VDEVICE(INTEL, 0x3b0b), LPC_HM57}, + { PCI_VDEVICE(INTEL, 0x3b0d), LPC_PCHMSFF}, + { PCI_VDEVICE(INTEL, 0x3b0f), LPC_QS57}, + { PCI_VDEVICE(INTEL, 0x3b12), LPC_3400}, + { PCI_VDEVICE(INTEL, 0x3b14), LPC_3420}, + { PCI_VDEVICE(INTEL, 0x3b16), LPC_3450}, + { PCI_VDEVICE(INTEL, 0x5031), LPC_EP80579}, + { PCI_VDEVICE(INTEL, 0x8c40), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c41), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c42), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c43), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c44), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c45), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c46), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c47), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c48), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c49), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4a), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4b), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4c), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4d), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4e), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4f), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c50), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c51), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c52), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c53), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c54), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c55), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c56), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c57), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c58), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c59), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5a), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5b), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5c), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5d), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5e), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5f), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8cc1), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc2), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc3), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc4), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc6), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8d40), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d41), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d42), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d43), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d44), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d45), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d46), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d47), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d48), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d49), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4a), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4b), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4c), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4d), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4e), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4f), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d50), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d51), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d52), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d53), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d54), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d55), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d56), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d57), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d58), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d59), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5a), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5b), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5c), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5d), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5e), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5f), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x9c40), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c41), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c42), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c43), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c44), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c45), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c46), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c47), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc3), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc5), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc6), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc7), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc9), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0xa1c1), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c2), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c3), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c4), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c5), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c6), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c7), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa242), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa243), LPC_LEWISBURG}, + { 0, }, /* End of list */ +}; +MODULE_DEVICE_TABLE(pci, lpc_ich_ids); + +static void lpc_ich_restore_config_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + + if (priv->abase_save >= 0) { + pci_write_config_byte(dev, priv->abase, priv->abase_save); + priv->abase_save = -1; + } + + if (priv->actrl_pbase_save >= 0) { + pci_write_config_byte(dev, priv->actrl_pbase, + priv->actrl_pbase_save); + priv->actrl_pbase_save = -1; + } + + if (priv->gctrl_save >= 0) { + pci_write_config_byte(dev, priv->gctrl, priv->gctrl_save); + priv->gctrl_save = -1; + } +} + +static void lpc_ich_enable_acpi_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + switch (lpc_chipset_info[priv->chipset].iTCO_version) { + case 3: + /* + * Some chipsets (eg Avoton) enable the ACPI space in the + * ACPI BASE register. + */ + pci_read_config_byte(dev, priv->abase, ®_save); + pci_write_config_byte(dev, priv->abase, reg_save | 0x2); + priv->abase_save = reg_save; + break; + default: + /* + * Most chipsets enable the ACPI space in the ACPI control + * register. + */ + pci_read_config_byte(dev, priv->actrl_pbase, ®_save); + pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x80); + priv->actrl_pbase_save = reg_save; + break; + } +} + +static void lpc_ich_enable_gpio_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + pci_read_config_byte(dev, priv->gctrl, ®_save); + pci_write_config_byte(dev, priv->gctrl, reg_save | 0x10); + priv->gctrl_save = reg_save; +} + +static void lpc_ich_enable_pmc_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + pci_read_config_byte(dev, priv->actrl_pbase, ®_save); + pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x2); + + priv->actrl_pbase_save = reg_save; +} + +static int lpc_ich_finalize_wdt_cell(struct pci_dev *dev) +{ + struct itco_wdt_platform_data *pdata; + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + struct lpc_ich_info *info; + struct mfd_cell *cell = &lpc_ich_wdt_cell; + + pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + info = &lpc_chipset_info[priv->chipset]; + + pdata->version = info->iTCO_version; + strlcpy(pdata->name, info->name, sizeof(pdata->name)); + + cell->platform_data = pdata; + cell->pdata_size = sizeof(*pdata); + return 0; +} + +static void lpc_ich_finalize_gpio_cell(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + struct mfd_cell *cell = &lpc_ich_gpio_cell; + + cell->platform_data = &lpc_chipset_info[priv->chipset]; + cell->pdata_size = sizeof(struct lpc_ich_info); +} + +/* + * We don't check for resource conflict globally. There are 2 or 3 independent + * GPIO groups and it's enough to have access to one of these to instantiate + * the device. + */ +static int lpc_ich_check_conflict_gpio(struct resource *res) +{ + int ret; + u8 use_gpio = 0; + + if (resource_size(res) >= 0x50 && + !acpi_check_region(res->start + 0x40, 0x10, "LPC ICH GPIO3")) + use_gpio |= 1 << 2; + + if (!acpi_check_region(res->start + 0x30, 0x10, "LPC ICH GPIO2")) + use_gpio |= 1 << 1; + + ret = acpi_check_region(res->start + 0x00, 0x30, "LPC ICH GPIO1"); + if (!ret) + use_gpio |= 1 << 0; + + return use_gpio ? use_gpio : ret; +} + +static int lpc_ich_init_gpio(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u32 base_addr_cfg; + u32 base_addr; + int ret; + bool acpi_conflict = false; + struct resource *res; + + /* Setup power management base register */ + pci_read_config_dword(dev, priv->abase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); + lpc_ich_gpio_cell.num_resources--; + goto gpe0_done; + } + + res = &gpio_ich_res[ICH_RES_GPE0]; + res->start = base_addr + ACPIBASE_GPE_OFF; + res->end = base_addr + ACPIBASE_GPE_END; + ret = acpi_check_resource_conflict(res); + if (ret) { + /* + * This isn't fatal for the GPIO, but we have to make sure that + * the platform_device subsystem doesn't see this resource + * or it will register an invalid region. + */ + lpc_ich_gpio_cell.num_resources--; + acpi_conflict = true; + } else { + lpc_ich_enable_acpi_space(dev); + } + +gpe0_done: + /* Setup GPIO base register */ + pci_read_config_dword(dev, priv->gbase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); + ret = -ENODEV; + goto gpio_done; + } + + /* Older devices provide fewer GPIO and have a smaller resource size. */ + res = &gpio_ich_res[ICH_RES_GPIO]; + res->start = base_addr; + switch (lpc_chipset_info[priv->chipset].gpio_version) { + case ICH_V5_GPIO: + case ICH_V10CORP_GPIO: + res->end = res->start + 128 - 1; + break; + default: + res->end = res->start + 64 - 1; + break; + } + + ret = lpc_ich_check_conflict_gpio(res); + if (ret < 0) { + /* this isn't necessarily fatal for the GPIO */ + acpi_conflict = true; + goto gpio_done; + } + lpc_chipset_info[priv->chipset].use_gpio = ret; + lpc_ich_enable_gpio_space(dev); + + lpc_ich_finalize_gpio_cell(dev); + ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, + &lpc_ich_gpio_cell, 1, NULL, 0, NULL); + +gpio_done: + if (acpi_conflict) + pr_warn("Resource conflict(s) found affecting %s\n", + lpc_ich_gpio_cell.name); + return ret; +} + +static int lpc_ich_init_wdt(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u32 base_addr_cfg; + u32 base_addr; + int ret; + struct resource *res; + + /* If we have ACPI based watchdog use that instead */ + if (acpi_has_watchdog()) + return -ENODEV; + + /* Setup power management base register */ + pci_read_config_dword(dev, priv->abase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); + ret = -ENODEV; + goto wdt_done; + } + + res = wdt_io_res(ICH_RES_IO_TCO); + res->start = base_addr + ACPIBASE_TCO_OFF; + res->end = base_addr + ACPIBASE_TCO_END; + + res = wdt_io_res(ICH_RES_IO_SMI); + res->start = base_addr + ACPIBASE_SMI_OFF; + res->end = base_addr + ACPIBASE_SMI_END; + + lpc_ich_enable_acpi_space(dev); + + /* + * iTCO v2: + * Get the Memory-Mapped GCS register. To get access to it + * we have to read RCBA from PCI Config space 0xf0 and use + * it as base. GCS = RCBA + ICH6_GCS(0x3410). + * + * iTCO v3: + * Get the Power Management Configuration register. To get access + * to it we have to read the PMC BASE from config space and address + * the register at offset 0x8. + */ + if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { + /* Don't register iomem for TCO ver 1 */ + lpc_ich_wdt_cell.num_resources--; + } else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) { + pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); + base_addr = base_addr_cfg & 0xffffc000; + if (!(base_addr_cfg & 1)) { + dev_notice(&dev->dev, "RCBA is disabled by " + "hardware/BIOS, device disabled\n"); + ret = -ENODEV; + goto wdt_done; + } + res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); + res->start = base_addr + ACPIBASE_GCS_OFF; + res->end = base_addr + ACPIBASE_GCS_END; + } else if (lpc_chipset_info[priv->chipset].iTCO_version == 3) { + lpc_ich_enable_pmc_space(dev); + pci_read_config_dword(dev, ACPICTRL_PMCBASE, &base_addr_cfg); + base_addr = base_addr_cfg & 0xfffffe00; + + res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); + res->start = base_addr + ACPIBASE_PMC_OFF; + res->end = base_addr + ACPIBASE_PMC_END; + } + + ret = lpc_ich_finalize_wdt_cell(dev); + if (ret) + goto wdt_done; + + ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, + &lpc_ich_wdt_cell, 1, NULL, 0, NULL); + +wdt_done: + return ret; +} + +static int lpc_ich_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + struct lpc_ich_priv *priv; + int ret; + bool cell_added = false; + + priv = devm_kzalloc(&dev->dev, + sizeof(struct lpc_ich_priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->chipset = id->driver_data; + + priv->actrl_pbase_save = -1; + priv->abase_save = -1; + + priv->abase = ACPIBASE; + priv->actrl_pbase = ACPICTRL_PMCBASE; + + priv->gctrl_save = -1; + if (priv->chipset <= LPC_ICH5) { + priv->gbase = GPIOBASE_ICH0; + priv->gctrl = GPIOCTRL_ICH0; + } else { + priv->gbase = GPIOBASE_ICH6; + priv->gctrl = GPIOCTRL_ICH6; + } + + pci_set_drvdata(dev, priv); + + if (lpc_chipset_info[priv->chipset].iTCO_version) { + ret = lpc_ich_init_wdt(dev); + if (!ret) + cell_added = true; + } + + if (lpc_chipset_info[priv->chipset].gpio_version) { + ret = lpc_ich_init_gpio(dev); + if (!ret) + cell_added = true; + } + + /* + * We only care if at least one or none of the cells registered + * successfully. + */ + if (!cell_added) { + dev_warn(&dev->dev, "No MFD cells added\n"); + lpc_ich_restore_config_space(dev); + return -ENODEV; + } + + return 0; +} + +static void lpc_ich_remove(struct pci_dev *dev) +{ + mfd_remove_devices(&dev->dev); + lpc_ich_restore_config_space(dev); +} + +static struct pci_driver lpc_ich_driver = { + .name = "lpc_ich", + .id_table = lpc_ich_ids, + .probe = lpc_ich_probe, + .remove = lpc_ich_remove, +}; + +module_pci_driver(lpc_ich_driver); + +MODULE_AUTHOR("Aaron Sierra "); +MODULE_DESCRIPTION("LPC interface for Intel ICH"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/pmbus.h new file mode 100644 index 000000000000..4efa2bd4f6d8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/pmbus.h @@ -0,0 +1,425 @@ +/* + * pmbus.h - Common defines and structures for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (c) 2012 Guenter Roeck + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PMBUS_H +#define PMBUS_H + +#include +#include + +/* + * Registers + */ +enum pmbus_regs { + PMBUS_PAGE = 0x00, + PMBUS_OPERATION = 0x01, + PMBUS_ON_OFF_CONFIG = 0x02, + PMBUS_CLEAR_FAULTS = 0x03, + PMBUS_PHASE = 0x04, + + PMBUS_CAPABILITY = 0x19, + PMBUS_QUERY = 0x1A, + + PMBUS_VOUT_MODE = 0x20, + PMBUS_VOUT_COMMAND = 0x21, + PMBUS_VOUT_TRIM = 0x22, + PMBUS_VOUT_CAL_OFFSET = 0x23, + PMBUS_VOUT_MAX = 0x24, + PMBUS_VOUT_MARGIN_HIGH = 0x25, + PMBUS_VOUT_MARGIN_LOW = 0x26, + PMBUS_VOUT_TRANSITION_RATE = 0x27, + PMBUS_VOUT_DROOP = 0x28, + PMBUS_VOUT_SCALE_LOOP = 0x29, + PMBUS_VOUT_SCALE_MONITOR = 0x2A, + + PMBUS_COEFFICIENTS = 0x30, + PMBUS_POUT_MAX = 0x31, + + PMBUS_FAN_CONFIG_12 = 0x3A, + PMBUS_FAN_COMMAND_1 = 0x3B, + PMBUS_FAN_COMMAND_2 = 0x3C, + PMBUS_FAN_CONFIG_34 = 0x3D, + PMBUS_FAN_COMMAND_3 = 0x3E, + PMBUS_FAN_COMMAND_4 = 0x3F, + + PMBUS_VOUT_OV_FAULT_LIMIT = 0x40, + PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41, + PMBUS_VOUT_OV_WARN_LIMIT = 0x42, + PMBUS_VOUT_UV_WARN_LIMIT = 0x43, + PMBUS_VOUT_UV_FAULT_LIMIT = 0x44, + PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45, + PMBUS_IOUT_OC_FAULT_LIMIT = 0x46, + PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47, + PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48, + PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49, + PMBUS_IOUT_OC_WARN_LIMIT = 0x4A, + PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B, + PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C, + + PMBUS_OT_FAULT_LIMIT = 0x4F, + PMBUS_OT_FAULT_RESPONSE = 0x50, + PMBUS_OT_WARN_LIMIT = 0x51, + PMBUS_UT_WARN_LIMIT = 0x52, + PMBUS_UT_FAULT_LIMIT = 0x53, + PMBUS_UT_FAULT_RESPONSE = 0x54, + PMBUS_VIN_OV_FAULT_LIMIT = 0x55, + PMBUS_VIN_OV_FAULT_RESPONSE = 0x56, + PMBUS_VIN_OV_WARN_LIMIT = 0x57, + PMBUS_VIN_UV_WARN_LIMIT = 0x58, + PMBUS_VIN_UV_FAULT_LIMIT = 0x59, + + PMBUS_IIN_OC_FAULT_LIMIT = 0x5B, + PMBUS_IIN_OC_WARN_LIMIT = 0x5D, + + PMBUS_POUT_OP_FAULT_LIMIT = 0x68, + PMBUS_POUT_OP_WARN_LIMIT = 0x6A, + PMBUS_PIN_OP_WARN_LIMIT = 0x6B, + + PMBUS_STATUS_BYTE = 0x78, + PMBUS_STATUS_WORD = 0x79, + PMBUS_STATUS_VOUT = 0x7A, + PMBUS_STATUS_IOUT = 0x7B, + PMBUS_STATUS_INPUT = 0x7C, + PMBUS_STATUS_TEMPERATURE = 0x7D, + PMBUS_STATUS_CML = 0x7E, + PMBUS_STATUS_OTHER = 0x7F, + PMBUS_STATUS_MFR_SPECIFIC = 0x80, + PMBUS_STATUS_FAN_12 = 0x81, + PMBUS_STATUS_FAN_34 = 0x82, + + PMBUS_READ_VIN = 0x88, + PMBUS_READ_IIN = 0x89, + PMBUS_READ_VCAP = 0x8A, + PMBUS_READ_VOUT = 0x8B, + PMBUS_READ_IOUT = 0x8C, + PMBUS_READ_TEMPERATURE_1 = 0x8D, + PMBUS_READ_TEMPERATURE_2 = 0x8E, + PMBUS_READ_TEMPERATURE_3 = 0x8F, + PMBUS_READ_FAN_SPEED_1 = 0x90, + PMBUS_READ_FAN_SPEED_2 = 0x91, + PMBUS_READ_FAN_SPEED_3 = 0x92, + PMBUS_READ_FAN_SPEED_4 = 0x93, + PMBUS_READ_DUTY_CYCLE = 0x94, + PMBUS_READ_FREQUENCY = 0x95, + PMBUS_READ_POUT = 0x96, + PMBUS_READ_PIN = 0x97, + + PMBUS_REVISION = 0x98, + PMBUS_MFR_ID = 0x99, + PMBUS_MFR_MODEL = 0x9A, + PMBUS_MFR_REVISION = 0x9B, + PMBUS_MFR_LOCATION = 0x9C, + PMBUS_MFR_DATE = 0x9D, + PMBUS_MFR_SERIAL = 0x9E, + +/* + * Virtual registers. + * Useful to support attributes which are not supported by standard PMBus + * registers but exist as manufacturer specific registers on individual chips. + * Must be mapped to real registers in device specific code. + * + * Semantics: + * Virtual registers are all word size. + * READ registers are read-only; writes are either ignored or return an error. + * RESET registers are read/write. Reading reset registers returns zero + * (used for detection), writing any value causes the associated history to be + * reset. + * Virtual registers have to be handled in device specific driver code. Chip + * driver code returns non-negative register values if a virtual register is + * supported, or a negative error code if not. The chip driver may return + * -ENODATA or any other error code in this case, though an error code other + * than -ENODATA is handled more efficiently and thus preferred. Either case, + * the calling PMBus core code will abort if the chip driver returns an error + * code when reading or writing virtual registers. + */ + PMBUS_VIRT_BASE = 0x100, + PMBUS_VIRT_READ_TEMP_AVG, + PMBUS_VIRT_READ_TEMP_MIN, + PMBUS_VIRT_READ_TEMP_MAX, + PMBUS_VIRT_RESET_TEMP_HISTORY, + PMBUS_VIRT_READ_VIN_AVG, + PMBUS_VIRT_READ_VIN_MIN, + PMBUS_VIRT_READ_VIN_MAX, + PMBUS_VIRT_RESET_VIN_HISTORY, + PMBUS_VIRT_READ_IIN_AVG, + PMBUS_VIRT_READ_IIN_MIN, + PMBUS_VIRT_READ_IIN_MAX, + PMBUS_VIRT_RESET_IIN_HISTORY, + PMBUS_VIRT_READ_PIN_AVG, + PMBUS_VIRT_READ_PIN_MIN, + PMBUS_VIRT_READ_PIN_MAX, + PMBUS_VIRT_RESET_PIN_HISTORY, + PMBUS_VIRT_READ_POUT_AVG, + PMBUS_VIRT_READ_POUT_MIN, + PMBUS_VIRT_READ_POUT_MAX, + PMBUS_VIRT_RESET_POUT_HISTORY, + PMBUS_VIRT_READ_VOUT_AVG, + PMBUS_VIRT_READ_VOUT_MIN, + PMBUS_VIRT_READ_VOUT_MAX, + PMBUS_VIRT_RESET_VOUT_HISTORY, + PMBUS_VIRT_READ_IOUT_AVG, + PMBUS_VIRT_READ_IOUT_MIN, + PMBUS_VIRT_READ_IOUT_MAX, + PMBUS_VIRT_RESET_IOUT_HISTORY, + PMBUS_VIRT_READ_TEMP2_AVG, + PMBUS_VIRT_READ_TEMP2_MIN, + PMBUS_VIRT_READ_TEMP2_MAX, + PMBUS_VIRT_RESET_TEMP2_HISTORY, + + PMBUS_VIRT_READ_VMON, + PMBUS_VIRT_VMON_UV_WARN_LIMIT, + PMBUS_VIRT_VMON_OV_WARN_LIMIT, + PMBUS_VIRT_VMON_UV_FAULT_LIMIT, + PMBUS_VIRT_VMON_OV_FAULT_LIMIT, + PMBUS_VIRT_STATUS_VMON, +}; + +/* + * OPERATION + */ +#define PB_OPERATION_CONTROL_ON BIT(7) + +/* + * CAPABILITY + */ +#define PB_CAPABILITY_SMBALERT BIT(4) +#define PB_CAPABILITY_ERROR_CHECK BIT(7) + +/* + * VOUT_MODE + */ +#define PB_VOUT_MODE_MODE_MASK 0xe0 +#define PB_VOUT_MODE_PARAM_MASK 0x1f + +#define PB_VOUT_MODE_LINEAR 0x00 +#define PB_VOUT_MODE_VID 0x20 +#define PB_VOUT_MODE_DIRECT 0x40 + +/* + * Fan configuration + */ +#define PB_FAN_2_PULSE_MASK (BIT(0) | BIT(1)) +#define PB_FAN_2_RPM BIT(2) +#define PB_FAN_2_INSTALLED BIT(3) +#define PB_FAN_1_PULSE_MASK (BIT(4) | BIT(5)) +#define PB_FAN_1_RPM BIT(6) +#define PB_FAN_1_INSTALLED BIT(7) + +/* + * STATUS_BYTE, STATUS_WORD (lower) + */ +#define PB_STATUS_NONE_ABOVE BIT(0) +#define PB_STATUS_CML BIT(1) +#define PB_STATUS_TEMPERATURE BIT(2) +#define PB_STATUS_VIN_UV BIT(3) +#define PB_STATUS_IOUT_OC BIT(4) +#define PB_STATUS_VOUT_OV BIT(5) +#define PB_STATUS_OFF BIT(6) +#define PB_STATUS_BUSY BIT(7) + +/* + * STATUS_WORD (upper) + */ +#define PB_STATUS_UNKNOWN BIT(8) +#define PB_STATUS_OTHER BIT(9) +#define PB_STATUS_FANS BIT(10) +#define PB_STATUS_POWER_GOOD_N BIT(11) +#define PB_STATUS_WORD_MFR BIT(12) +#define PB_STATUS_INPUT BIT(13) +#define PB_STATUS_IOUT_POUT BIT(14) +#define PB_STATUS_VOUT BIT(15) + +/* + * STATUS_IOUT + */ +#define PB_POUT_OP_WARNING BIT(0) +#define PB_POUT_OP_FAULT BIT(1) +#define PB_POWER_LIMITING BIT(2) +#define PB_CURRENT_SHARE_FAULT BIT(3) +#define PB_IOUT_UC_FAULT BIT(4) +#define PB_IOUT_OC_WARNING BIT(5) +#define PB_IOUT_OC_LV_FAULT BIT(6) +#define PB_IOUT_OC_FAULT BIT(7) + +/* + * STATUS_VOUT, STATUS_INPUT + */ +#define PB_VOLTAGE_UV_FAULT BIT(4) +#define PB_VOLTAGE_UV_WARNING BIT(5) +#define PB_VOLTAGE_OV_WARNING BIT(6) +#define PB_VOLTAGE_OV_FAULT BIT(7) + +/* + * STATUS_INPUT + */ +#define PB_PIN_OP_WARNING BIT(0) +#define PB_IIN_OC_WARNING BIT(1) +#define PB_IIN_OC_FAULT BIT(2) + +/* + * STATUS_TEMPERATURE + */ +#define PB_TEMP_UT_FAULT BIT(4) +#define PB_TEMP_UT_WARNING BIT(5) +#define PB_TEMP_OT_WARNING BIT(6) +#define PB_TEMP_OT_FAULT BIT(7) + +/* + * STATUS_FAN + */ +#define PB_FAN_AIRFLOW_WARNING BIT(0) +#define PB_FAN_AIRFLOW_FAULT BIT(1) +#define PB_FAN_FAN2_SPEED_OVERRIDE BIT(2) +#define PB_FAN_FAN1_SPEED_OVERRIDE BIT(3) +#define PB_FAN_FAN2_WARNING BIT(4) +#define PB_FAN_FAN1_WARNING BIT(5) +#define PB_FAN_FAN2_FAULT BIT(6) +#define PB_FAN_FAN1_FAULT BIT(7) + +/* + * CML_FAULT_STATUS + */ +#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0) +#define PB_CML_FAULT_OTHER_COMM BIT(1) +#define PB_CML_FAULT_PROCESSOR BIT(3) +#define PB_CML_FAULT_MEMORY BIT(4) +#define PB_CML_FAULT_PACKET_ERROR BIT(5) +#define PB_CML_FAULT_INVALID_DATA BIT(6) +#define PB_CML_FAULT_INVALID_COMMAND BIT(7) + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_FAN, + PSC_NUM_CLASSES /* Number of power sensor classes */ +}; + +#define PMBUS_PAGES 32 /* Per PMBus specification */ + +/* Functionality bit mask */ +#define PMBUS_HAVE_VIN BIT(0) +#define PMBUS_HAVE_VCAP BIT(1) +#define PMBUS_HAVE_VOUT BIT(2) +#define PMBUS_HAVE_IIN BIT(3) +#define PMBUS_HAVE_IOUT BIT(4) +#define PMBUS_HAVE_PIN BIT(5) +#define PMBUS_HAVE_POUT BIT(6) +#define PMBUS_HAVE_FAN12 BIT(7) +#define PMBUS_HAVE_FAN34 BIT(8) +#define PMBUS_HAVE_TEMP BIT(9) +#define PMBUS_HAVE_TEMP2 BIT(10) +#define PMBUS_HAVE_TEMP3 BIT(11) +#define PMBUS_HAVE_STATUS_VOUT BIT(12) +#define PMBUS_HAVE_STATUS_IOUT BIT(13) +#define PMBUS_HAVE_STATUS_INPUT BIT(14) +#define PMBUS_HAVE_STATUS_TEMP BIT(15) +#define PMBUS_HAVE_STATUS_FAN12 BIT(16) +#define PMBUS_HAVE_STATUS_FAN34 BIT(17) +#define PMBUS_HAVE_VMON BIT(18) +#define PMBUS_HAVE_STATUS_VMON BIT(19) + +enum pmbus_data_format { linear = 0, direct, vid }; +enum vrm_version { vr11 = 0, vr12, vr13 }; + +struct pmbus_driver_info { + int pages; /* Total number of pages */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; + enum vrm_version vrm_version; + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ + int b[PSC_NUM_CLASSES]; /* offset */ + int R[PSC_NUM_CLASSES]; /* exponent */ + + u32 func[PMBUS_PAGES]; /* Functionality, per page */ + /* + * The following functions map manufacturing specific register values + * to PMBus standard register values. Specify only if mapping is + * necessary. + * Functions return the register value (read) or zero (write) if + * successful. A return value of -ENODATA indicates that there is no + * manufacturer specific register, but that a standard PMBus register + * may exist. Any other negative return value indicates that the + * register does not exist, and that no attempt should be made to read + * the standard register. + */ + int (*read_byte_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int reg); + int (*write_word_data)(struct i2c_client *client, int page, int reg, + u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); + /* + * The identify function determines supported PMBus functionality. + * This function is only necessary if a chip driver supports multiple + * chips, and the chip functionality is not pre-determined. + */ + int (*identify)(struct i2c_client *client, + struct pmbus_driver_info *info); + + /* Regulator functionality, if supported by this chip driver. */ + int num_regulators; + const struct regulator_desc *reg_desc; +}; + +/* Regulator ops */ + +extern const struct regulator_ops pmbus_regulator_ops; + +/* Macro for filling in array of struct regulator_desc */ +#define PMBUS_REGULATOR(_name, _id) \ + [_id] = { \ + .name = (_name # _id), \ + .id = (_id), \ + .of_match = of_match_ptr(_name # _id), \ + .regulators_node = of_match_ptr("regulators"), \ + .ops = &pmbus_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } + +/* Function declarations */ + +void pmbus_clear_cache(struct i2c_client *client); +int pmbus_set_page(struct i2c_client *client, u8 page); +int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); +int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); +int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); +int pmbus_write_byte(struct i2c_client *client, int page, u8 value); +int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, + u8 value); +int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, + u8 mask, u8 value); +void pmbus_clear_faults(struct i2c_client *client); +bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); +bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); +int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + struct pmbus_driver_info *info); +int pmbus_do_remove(struct i2c_client *client); +const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client + *client); + +#endif /* PMBUS_H */ diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.c index 6fe8f599fb48..27c45173eef5 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.c @@ -1,10 +1,3 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - #include #include #include @@ -12,7 +5,12 @@ #include "io_expander.h" #include "transceiver.h" +/* For build single module using (Ex: ONL platform) */ +#include +//#include +//#include +extern int io_no_init; /* ========== Register EEPROM address mapping ========== */ struct eeprom_map_s eeprom_map_sfp = { @@ -152,7 +150,7 @@ alarm_msg_2_user(struct transvr_obj_s *self, SWPS_ERR("%s on %s.\n", emsg, self->swp_name); } - +EXPORT_SYMBOL(alarm_msg_2_user); /* ========== Private functions ========== */ @@ -181,6 +179,7 @@ lock_transvr_obj(struct transvr_obj_s *self) { mutex_lock(&self->lock); self->curr_page = VAL_TRANSVR_PAGE_FREE; } +EXPORT_SYMBOL(lock_transvr_obj); void @@ -189,6 +188,7 @@ unlock_transvr_obj(struct transvr_obj_s *self) { self->curr_page = VAL_TRANSVR_PAGE_FREE; mutex_unlock(&self->lock); } +EXPORT_SYMBOL(unlock_transvr_obj); static int @@ -4833,6 +4833,11 @@ _taskfunc_qsfp_setup_power_mod(struct transvr_obj_s *self, int curr_val = DEBUG_TRANSVR_INT_VAL; int err_val = DEBUG_TRANSVR_INT_VAL; char *err_msg = DEBUG_TRANSVR_STR_VAL; + if (io_no_init) { + + SWPS_INFO("%s no_io_init\n",__func__); + return EVENT_TRANSVR_TASK_DONE; + } curr_val = self->ioexp_obj_p->get_lpmod(self->ioexp_obj_p, self->ioexp_virt_offset); @@ -8259,6 +8264,7 @@ create_transvr_obj(char *swp_name, __func__, err_msg, chan_id, ioexp_virt_offset, transvr_type); return NULL; } +EXPORT_SYMBOL(create_transvr_obj); static int @@ -8290,11 +8296,17 @@ _reload_transvr_obj(struct transvr_obj_s *self, if (setup_transvr_private_cb(self, new_type) < 0){ goto err_private_reload_func_3; } + if(old_i2c_p){ + i2c_put_adapter(old_i2c_p->adapter); + } kfree(old_i2c_p); return 0; err_private_reload_func_3: SWPS_INFO("%s: init() fail!\n", __func__); + if(old_i2c_p){ + i2c_put_adapter(old_i2c_p->adapter); + } kfree(old_i2c_p); self->state = STATE_TRANSVR_UNEXCEPTED; self->type = TRANSVR_TYPE_ERROR; @@ -8341,6 +8353,7 @@ isolate_transvr_obj(struct transvr_obj_s *self) { SWPS_INFO("%s: %s be isolated\n", __func__, self->swp_name); return 0; } +EXPORT_SYMBOL(isolate_transvr_obj); int @@ -8359,6 +8372,10 @@ resync_channel_tier_2(struct transvr_obj_s *self) { } return 0; } +EXPORT_SYMBOL(resync_channel_tier_2); + +/* For build single module using (Ex: ONL platform) */ +MODULE_LICENSE("GPL"); /* ----------------------------------------- @@ -8387,3 +8404,5 @@ resync_channel_tier_2(struct transvr_obj_s *self) { + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.h b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.h index f17b7fde71b1..0438a351271a 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.h +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.h @@ -1,10 +1,3 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - #ifndef TRANSCEIVER_H #define TRANSCEIVER_H @@ -813,3 +806,4 @@ void alarm_msg_2_user(struct transvr_obj_s *self, char *emsg); + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c new file mode 100644 index 000000000000..3e3aa950277f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c @@ -0,0 +1,247 @@ +/* + * Hardware monitoring driver for UCD90xxx Sequencer and System Health + * Controller series + * + * Copyright (C) 2011 Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "pmbus.h" + +enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 }; + +#define UCD9000_MONITOR_CONFIG 0xd5 +#define UCD9000_NUM_PAGES 0xd6 +#define UCD9000_FAN_CONFIG_INDEX 0xe7 +#define UCD9000_FAN_CONFIG 0xe8 +#define UCD9000_DEVICE_ID 0xfd + +#define UCD9000_MON_TYPE(x) (((x) >> 5) & 0x07) +#define UCD9000_MON_PAGE(x) ((x) & 0x0f) + +#define UCD9000_MON_VOLTAGE 1 +#define UCD9000_MON_TEMPERATURE 2 +#define UCD9000_MON_CURRENT 3 +#define UCD9000_MON_VOLTAGE_HW 4 + +#define UCD9000_NUM_FAN 4 + +struct ucd9000_data { + u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX]; + struct pmbus_driver_info info; +}; +#define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info) + +static int ucd9000_get_fan_config(struct i2c_client *client, int fan) +{ + int fan_config = 0; + struct ucd9000_data *data + = to_ucd9000_data(pmbus_get_driver_info(client)); + + if (data->fan_data[fan][3] & 1) + fan_config |= PB_FAN_2_INSTALLED; /* Use lower bit position */ + + /* Pulses/revolution */ + fan_config |= (data->fan_data[fan][3] & 0x06) >> 1; + + return fan_config; +} + +static int ucd9000_read_byte_data(struct i2c_client *client, int page, int reg) +{ + int ret = 0; + int fan_config; + + switch (reg) { + case PMBUS_FAN_CONFIG_12: + if (page > 0) + return -ENXIO; + + ret = ucd9000_get_fan_config(client, 0); + if (ret < 0) + return ret; + fan_config = ret << 4; + ret = ucd9000_get_fan_config(client, 1); + if (ret < 0) + return ret; + fan_config |= ret; + ret = fan_config; + break; + case PMBUS_FAN_CONFIG_34: + if (page > 0) + return -ENXIO; + + ret = ucd9000_get_fan_config(client, 2); + if (ret < 0) + return ret; + fan_config = ret << 4; + ret = ucd9000_get_fan_config(client, 3); + if (ret < 0) + return ret; + fan_config |= ret; + ret = fan_config; + break; + default: + ret = -ENODATA; + break; + } + return ret; +} + +static const struct i2c_device_id ucd9000_id[] = { + {"ucd9000", ucd9000}, + {"ucd90120", ucd90120}, + {"ucd90124", ucd90124}, + {"ucd90160", ucd90160}, + {"ucd9090", ucd9090}, + {"ucd90910", ucd90910}, + {} +}; +MODULE_DEVICE_TABLE(i2c, ucd9000_id); + +static int ucd9000_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; + struct ucd9000_data *data; + struct pmbus_driver_info *info; + const struct i2c_device_id *mid; + int i, ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA)) + return -ENODEV; + + ret = i2c_smbus_read_block_data(client, UCD9000_DEVICE_ID, + block_buffer); + if (ret < 0) { + dev_err(&client->dev, "Failed to read device ID\n"); + return ret; + } + block_buffer[ret] = '\0'; + dev_info(&client->dev, "Device ID %s\n", block_buffer); + + for (mid = ucd9000_id; mid->name[0]; mid++) { + if (!strncasecmp(mid->name, block_buffer, strlen(mid->name))) + break; + } + if (!mid->name[0]) { + dev_err(&client->dev, "Unsupported device\n"); + return -ENODEV; + } + + if (id->driver_data != ucd9000 && id->driver_data != mid->driver_data) + dev_notice(&client->dev, + "Device mismatch: Configured %s, detected %s\n", + id->name, mid->name); + + data = devm_kzalloc(&client->dev, sizeof(struct ucd9000_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + info = &data->info; + + ret = i2c_smbus_read_byte_data(client, UCD9000_NUM_PAGES); + if (ret < 0) { + dev_err(&client->dev, + "Failed to read number of active pages\n"); + return ret; + } + info->pages = ret; + if (!info->pages) { + dev_err(&client->dev, "No pages configured\n"); + return -ENODEV; + } + + /* The internal temperature sensor is always active */ + info->func[0] = PMBUS_HAVE_TEMP; + + /* Everything else is configurable */ + ret = i2c_smbus_read_block_data(client, UCD9000_MONITOR_CONFIG, + block_buffer); + if (ret <= 0) { + dev_err(&client->dev, "Failed to read configuration data\n"); + return -ENODEV; + } + for (i = 0; i < ret; i++) { + int page = UCD9000_MON_PAGE(block_buffer[i]); + + if (page >= info->pages) + continue; + + switch (UCD9000_MON_TYPE(block_buffer[i])) { + case UCD9000_MON_VOLTAGE: + case UCD9000_MON_VOLTAGE_HW: + info->func[page] |= PMBUS_HAVE_VOUT + | PMBUS_HAVE_STATUS_VOUT; + break; + case UCD9000_MON_TEMPERATURE: + info->func[page] |= PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_STATUS_TEMP; + break; + case UCD9000_MON_CURRENT: + info->func[page] |= PMBUS_HAVE_IOUT + | PMBUS_HAVE_STATUS_IOUT; + break; + default: + break; + } + } + + /* Fan configuration */ + if (mid->driver_data == ucd90124) { + for (i = 0; i < UCD9000_NUM_FAN; i++) { + i2c_smbus_write_byte_data(client, + UCD9000_FAN_CONFIG_INDEX, i); + ret = i2c_smbus_read_block_data(client, + UCD9000_FAN_CONFIG, + data->fan_data[i]); + if (ret < 0) + return ret; + } + i2c_smbus_write_byte_data(client, UCD9000_FAN_CONFIG_INDEX, 0); + + info->read_byte_data = ucd9000_read_byte_data; + info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 + | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34; + } + + return pmbus_do_probe(client, mid, info); +} + +/* This is the driver that will be inserted */ +static struct i2c_driver ucd9000_driver = { + .driver = { + .name = "ucd9000", + }, + .probe = ucd9000_probe, + .remove = pmbus_do_remove, + .id_table = ucd9000_id, +}; + +module_i2c_driver(ucd9000_driver); + +MODULE_AUTHOR("Guenter Roeck"); +MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/setup.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/setup.py new file mode 100644 index 000000000000..8b45987a54ec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Ivnetec D6356 platforms', + + packages=['sonic_platform'], +) + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/__init__.py new file mode 100644 index 000000000000..4bfefa0fb636 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py new file mode 100644 index 000000000000..761d21cf46ce --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan + from sonic_platform.psu import Psu + from sonic_platform.sfp import Sfp + from sonic_platform.qsfp import QSfp + from sonic_platform.thermal import Thermal +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Chassis(ChassisBase): + + def __init__(self): + ChassisBase.__init__(self) + self.__num_of_fans = 8 + self.__num_of_psus = 2 + self.__num_of_sfps = 56 + self.__start_of_qsfp = 48 + self.__num_of_thermals = 5 + + # Initialize EEPROM + self._eeprom = Eeprom() + + # Initialize FAN + for index in range(1, self.__num_of_fans + 1): + fan = Fan(index, False, 0) + self._fan_list.append(fan) + + # Initialize PSU + for index in range(1, self.__num_of_psus + 1): + psu = Psu(index) + self._psu_list.append(psu) + + # Initialize SFP + for index in range(0, self.__num_of_sfps): + if index < self.__start_of_qsfp: + sfp = Sfp(index) + else: + sfp = QSfp(index) + self._sfp_list.append(sfp) + + # Initialize THERMAL + for index in range(0, self.__num_of_thermals): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_number_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + +############################################## +# Chassis methods +############################################## + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_address() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + """ + return self._eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/eeprom.py new file mode 100644 index 000000000000..5840246fddc2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/eeprom.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# +# Name: eeprom.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + from sonic_eeprom import eeprom_tlvinfo + import binascii +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self): + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0055/eeprom" + super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True) + self.__eeprom_tlv_dict = dict() + try: + self.__eeprom_data = self.read_eeprom() + except: + self.__eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.__eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + ord(eeprom[tlv_index + 1])] + code = "0x%02X" % (ord(tlv[0])) + + if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | + (ord(tlv[4]) << 8) | ord(tlv[5])) + value += str(tlv[6:6 + ord(tlv[1])]) + else: + name, value = self.decoder(None, tlv) + + self.__eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+1]) + 2 + + def serial_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2] + + def base_mac_address(self): + (is_valid, t) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(self.__eeprom_data) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def serial_tag_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2] + + def revision_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2] + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.__eeprom_tlv_dict + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/fan.py new file mode 100644 index 000000000000..b9423e43dcb1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/fan.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python +# +# Name: fan.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import math + import os + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Fan(FanBase): + + def __init__(self, index, is_psu_fan=False, psu_index=0): + self.__index = index + self.__is_psu_fan = is_psu_fan + + if self.__is_psu_fan: + self.__psu_index = psu_index + self.__presence_attr = "/sys/class/hwmon/hwmon{}/fan{}_input".format((self.__psu_index + 6), self.__index) + self.__speed_rpm_attr = "/sys/class/hwmon/hwmon{}/fan{}_input".format((self.__psu_index + 6), self.__index) + self.__pwm_attr = None + else: + self.__presence_attr = "/sys/class/hwmon/hwmon2/device/fan{}_input".format(self.__index) + self.__speed_rpm_attr = "/sys/class/hwmon/hwmon2/device/fan{}_input".format(self.__index) + self.__pwm_attr = "/sys/class/hwmon/hwmon2/device/pwm{}".format((self.__index + 1)/2) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + if self.__is_psu_fan: + return "PSU{}-FAN{}".format(self.__psu_index, self.__index) + else: + return "FAN{}".format(self.__index) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) != 0): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return "N/A" + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + return "N/A" + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() + +############################################## +# FAN methods +############################################## + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + raise NotImplementedError + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + + if self.__is_psu_fan: + attr_path = self.__speed_rpm_attr + else: + attr_path = self.__pwm_attr + + if self.get_presence() and None != attr_path: + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if self.__is_psu_fan: + fan_speed_rpm = int(attr_rv) + speed = math.ceil(float(fan_speed_rpm) * 100 / 11000) + else: + pwm = int(attr_rv) + speed = math.ceil(float(pwm * 100 / 255)) + + return speed + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + raise NotImplementedError + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + raise NotImplementedError + + def set_speed(self, speed): + """ + Sets the fan speed + + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + + Returns: + A boolean, True if speed is set successfully, False if not + """ + raise NotImplementedError + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + + Args: + color: A string representing the color with which to set the + fan module status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + raise NotImplementedError + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if self.get_status() and self.get_speed() > 0: + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/platform.py new file mode 100644 index 000000000000..7d6bda4502de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/platform.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/psu.py new file mode 100644 index 000000000000..3798ef9e5b80 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/psu.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python +# +# Name: psu.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Psu(PsuBase): + + def __init__(self, index): + self.__num_of_fans = 1 + self.__index = index + self.__psu_presence_attr = "/sys/class/hwmon/hwmon2/device/psu{}".format(self.__index) + self.__psu_power_in_attr = "/sys/class/hwmon/hwmon{}/power1_input".format(self.__index + 6) + self.__psu_power_out_attr = "/sys/class/hwmon/hwmon{}/power2_input".format(self.__index + 6) + self.__psu_voltage_out_attr = "/sys/class/hwmon/hwmon{}/in2_input".format(self.__index + 6) + self.__psu_current_out_attr = "/sys/class/hwmon/hwmon{}/curr2_input".format(self.__index + 6) + + # Overriding _fan_list class variable defined in PsuBase, to make it unique per Psu object + self._fan_list = [] + + # Initialize FAN + for x in range(1, self.__num_of_fans + 1): + fan = Fan(x, True, self.__index) + self._fan_list.append(fan) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.__index) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_normal = "1:normal" + attr_path = self.__psu_presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == attr_normal): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return "N/A" + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + return "N/A" + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + attr_path = self.__psu_power_in_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) != 0): + status = True + + return status + +############################################## +# PSU methods +############################################## + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + voltage_out = 0.0 + attr_path = self.__psu_voltage_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + voltage_out = float(attr_rv) / 1000 + + return voltage_out + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + current_out = 0.0 + attr_path = self.__psu_current_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + current_out = float(attr_rv) / 1000 + + return current_out + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, e.g. 302.6 + """ + power_out = 0.0 + attr_path = self.__psu_power_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + power_out = float(attr_rv) / 1000000 + + return power_out + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + + Args: + color: A string representing the color with which to set the + PSU status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + raise NotImplementedError + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py new file mode 100644 index 000000000000..f3f873be08ce --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py @@ -0,0 +1,925 @@ +#!/usr/bin/env python +# +# Name: qsfp.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import sys + import time + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 128 +DOM_OFFSET = 0 + +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# Offset for values in QSFP eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + +class QSfp(SfpBase): + + def __init__(self, index): + self.__index = index + + self.__platform = "x86_64-inventec_d6356-r0" + self.__hwsku = "INVENTEC-D6356" + + self.__port_to_i2c_mapping = { + 0:22, 1:23, 2:24, 3:25, 4:26, 5:27, 6:28, 7:29, + 8:30, 9:31, 10:32, 11:33, 12:34, 13:35, 14:36, 15:37, + 16:38, 17:39, 18:40, 19:41, 20:42, 21:43, 22:44, 23:45, + 24:46, 25:47, 26:48, 27:49, 28:50, 29:51, 30:52, 31:53, + 32:54, 33:55, 34:56, 35:57, 36:58, 37:59, 38:60, 39:61, + 40:62, 41:63, 42:64, 43:65, 44:66, 45:67, 46:68, 47:69, + 48:14, 49:15, 50:16, 51:17, 52:18, 53:19, 54:20, 55:21 + } + self.__port_end = len(self.__port_to_i2c_mapping) - 1; + + self.__presence_attr = None + self.__eeprom_path = None + if self.__index in range(0, self.__port_end + 1): + self.__presence_attr = "/sys/class/swps/port{}/present".format(self.__index) + self.__lpmode_attr = "/sys/class/swps/port{}/lpmod".format(self.__index) + self.__reset_attr = "/sys/class/swps/port{}/reset".format(self.__index) + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom".format(self.__port_to_i2c_mapping[self.__index]) + + #print(self.__eeprom_path) + + SfpBase.__init__(self) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def __is_host(self): + return os.system("docker > /dev/null 2>&1") == 0 + + def __get_path_to_port_config_file(self): + host_platform_root_path = '/usr/share/sonic/device' + docker_hwsku_path = '/usr/share/sonic/hwsku' + + host_platform_path = "/".join([host_platform_root_path, self.__platform]) + hwsku_path = "/".join([host_platform_path, self.__hwsku]) if self.__is_host() else docker_hwsku_path + + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_eeprom_path = self.__eeprom_path + try: + sysfsfile_eeprom = open(sysfs_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + raw_len = len(raw) + for n in range(0, raw_len): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def __convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + name = None + + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings(self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.__index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + transceiver_info_dict = self.get_transceiver_info() + return transceiver_info_dict.get("modelname", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + transceiver_info_dict = self.get_transceiver_info() + return transceiver_info_dict.get("serialnum", "N/A") + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and not self.get_reset_status() + +############################################## +# SFP methods +############################################## + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + mominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + + transceiver_info_dict_keys = ['type', 'hardwarerev', + 'serialnum', 'manufacturename', + 'modelname', 'Connector', + 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', + 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'vendor_date', + 'vendor_oui'] + + qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') + + qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', 'Fibre Channel transmission media', + 'Fibre Channel Speed') + + sfpi_obj = sff8436InterfaceId() + if not self.get_presence() or not sfpi_obj: + return {} + + offset = INFO_OFFSET + + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP) + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(transceiver_info_dict_keys, 'N/A') + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + compliance_code_dict = dict() + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + transceiver_dom_info_dict_keys = ['rx_los', 'tx_fault', + 'reset_status', 'power_lpmode', + 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', + 'rx1power', 'rx2power', + 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', + 'tx1power', 'tx2power', + 'tx3power', 'tx4power'] + + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not self.get_presence() or not sfpi_obj or not sfpd_obj: + return {} + + transceiver_dom_info_dict = dict.fromkeys(transceiver_dom_info_dict_keys, 'N/A') + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes((offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self.__convert_string_to_num(transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable() + transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + sfpd_obj = sff8436Dom() + if not self.get_presence() or not sfpd_obj: + return {} + + transceiver_dom_threshold_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A') + offset = DOM_OFFSET + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_channel_thres_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNEL_THRESHOLD_OFFSET), QSFP_CHANNEL_THRESHOLD_WIDTH) + channel_threshold_values = sfpd_obj.parse_channel_threshold_values(dom_channel_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + for key in transceiver_dom_threshold_dict: + transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key]) + + return transceiver_dom_threshold_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + + Returns: + A Boolean, True if reset enabled, False if disabled + """ + reset_status = False + attr_path = self.__reset_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + reset_status = True + + return reset_status + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = False + rx_los_list = [] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3] + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = False + tx_fault_list = [] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3] + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable = False + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return tx_disable + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value']) + tx_disable = tx_disable_list[0] and tx_disable_list[1] and tx_disable_list[2] and tx_disable_list[3] + + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_channel = 0 + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return tx_disable_channel + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value']) + + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disable_channel |= 1 << i + + return tx_disable_channel + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + lpmode = False + attr_path = self.__lpmode_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 1): + lpmode = True + + return lpmode + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + power_override = False + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return power_override + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + power_override = ('On' == dom_control_data['data']['PowerOverride']['value']) + + return power_override + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + + Returns: + An integer number of current temperature in Celsius + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("temperature", "N/A") + + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + + Returns: + An integer number of supply voltage in mV + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") + tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A") + tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A") + tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A") + return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else [] + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") + rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A") + rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A") + rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A") + return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else [] + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") + tx2_pw = transceiver_dom_info_dict.get("tx2power", "N/A") + tx3_pw = transceiver_dom_info_dict.get("tx3power", "N/A") + tx4_pw = transceiver_dom_info_dict.get("tx4power", "N/A") + return [tx1_pw, tx2_pw, tx3_pw, tx4_pw] + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + + Returns: + A boolean, True if successful, False if not + """ + + try: + reg_file = open(self.__reset_attr, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 0 + reg_file.write(hex(reg_value)) + reg_file.close() + + # Sleep 2 second to allow it to settle + time.sleep(2) + + try: + reg_file = open(self.__reset_attr, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 1 + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + sysfs_eeprom_path = self.__eeprom_path + sysfsfile_eeprom = None + try: + tx_disable_ctl = 0xf if tx_disable else 0x0 + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open(sysfs_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + + Returns: + A boolean, True if successful, False if not + """ + sysfs_eeprom_path = self.__eeprom_path + sysfsfile_eeprom = None + try: + channel_state = self.get_tx_disable_channel() + tx_enable_mask = [0xe, 0xd, 0xb, 0x7] + tx_disable_mask = [0x1, 0x3, 0x7, 0xf] + tx_disable_ctl = channel_state | tx_disable_mask[channel] if disable else channel_state & tx_enable_mask[channel] + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open(sysfs_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + try: + reg_file = open(self.__lpmode_attr, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = int(reg_file.readline().rstrip()) + + if lpmode is True: + reg_value = 1 + else: + reg_value = 0 + + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + sysfs_eeprom_path = self.__eeprom_path + sysfsfile_eeprom = None + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + sysfsfile_eeprom = open(sysfs_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py new file mode 100644 index 000000000000..d8d88a2df2b0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py @@ -0,0 +1,739 @@ +#!/usr/bin/env python +# +# Name: sfp.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import sys + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 0 +DOM_OFFSET = 256 + +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# Offset for values in SFP eeprom +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + +class Sfp(SfpBase): + + def __init__(self, index): + self.__index = index + + self.__platform = "x86_64-inventec_d6356-r0" + self.__hwsku = "INVENTEC-D6356" + + self.__port_to_i2c_mapping = { + 0:22, 1:23, 2:24, 3:25, 4:26, 5:27, 6:28, 7:29, + 8:30, 9:31, 10:32, 11:33, 12:34, 13:35, 14:36, 15:37, + 16:38, 17:39, 18:40, 19:41, 20:42, 21:43, 22:44, 23:45, + 24:46, 25:47, 26:48, 27:49, 28:50, 29:51, 30:52, 31:53, + 32:54, 33:55, 34:56, 35:57, 36:58, 37:59, 38:60, 39:61, + 40:62, 41:63, 42:64, 43:65, 44:66, 45:67, 46:68, 47:69, + 48:14, 49:15, 50:16, 51:17, 52:18, 53:19, 54:20, 55:21 + } + self.__port_end = len(self.__port_to_i2c_mapping) - 1; + + self.__presence_attr = None + self.__eeprom_path = None + if self.__index in range(0, self.__port_end + 1): + self.__presence_attr = "/sys/class/swps/port{}/present".format(self.__index) + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom".format(self.__port_to_i2c_mapping[self.__index]) + + SfpBase.__init__(self) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def __is_host(self): + return os.system("docker > /dev/null 2>&1") == 0 + + def __get_path_to_port_config_file(self): + host_platform_root_path = '/usr/share/sonic/device' + docker_hwsku_path = '/usr/share/sonic/hwsku' + + host_platform_path = "/".join([host_platform_root_path, self.__platform]) + hwsku_path = "/".join([host_platform_path, self.__hwsku]) if self.__is_host() else docker_hwsku_path + + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_eeprom_path = self.__eeprom_path + try: + sysfsfile_eeprom = open(sysfs_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + raw_len = len(raw) + for n in range(0, raw_len): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def __convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + name = None + + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings(self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.__index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + transceiver_info_dict = self.get_transceiver_info() + return transceiver_info_dict.get("modelname", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + transceiver_info_dict = self.get_transceiver_info() + return transceiver_info_dict.get("serialnum", "N/A") + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and not self.get_reset_status() + +############################################## +# SFP methods +############################################## + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + mominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + + transceiver_info_dict_keys = ['type', 'hardwarerev', + 'serialnum', 'manufacturename', + 'modelname', 'Connector', + 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', + 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'vendor_date', + 'vendor_oui'] + + sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + + sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + + sfpi_obj = sff8472InterfaceId() + if not self.get_presence() or not sfpi_obj: + return {} + + offset = INFO_OFFSET + + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_SFP) + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_SFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(transceiver_info_dict_keys, 'N/A') + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + compliance_code_dict = dict() + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + transceiver_dom_info_dict_keys = ['rx_los', 'tx_fault', + 'reset_status', 'power_lpmode', + 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', + 'rx1power', 'rx2power', + 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', + 'tx1power', 'tx2power', + 'tx3power', 'tx4power'] + + sfpd_obj = sff8472Dom() + if not self.get_presence() or not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_info_dict = dict.fromkeys(transceiver_dom_info_dict_keys, 'N/A') + + dom_temperature_raw = self.__read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes((offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_voltage_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value'] + transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self.__convert_string_to_num(transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable() + transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + sfpd_obj = sff8472Dom() + + if not self.get_presence() and not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_threshold_info_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A') + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + + Returns: + A Boolean, True if reset enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = False + status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = False + status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable = False + tx_fault = False + status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_disable_hard = (sffbase().test_bit(data, SFP_TX_DISABLE_HARD_BIT) != 0) + tx_disable_soft = (sffbase().test_bit(data, SFP_TX_DISABLE_SOFT_BIT) != 0) + tx_disable = tx_disable_hard | tx_disable_soft + + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + # SFP doesn't support this feature + return 0 + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + + Returns: + An integer number of current temperature in Celsius + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("temperature", "N/A") + + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + + Returns: + An integer number of supply voltage in mV + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") + return [tx1_bs, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") + return [rx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") + return [tx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + + Returns: + A boolean, True if successful, False if not + """ + # SFP doesn't support this feature + return False + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + sysfs_eeprom_path = self.__eeprom_path + status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw is not None: + # Set bit 6 for Soft TX Disable Select + # 01000000 = 64 and 10111111 = 191 + tx_disable_bit = 64 if tx_disable else 191 + status_control = int(status_control_raw[0], 16) + tx_disable_ctl = (status_control | tx_disable_bit) if tx_disable else (status_control & tx_disable_bit) + try: + sysfsfile_eeprom = open(sysfs_eeprom_path, mode="r+b", buffering=0) + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom.seek(SFP_STATUS_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except: + #print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + + Returns: + A boolean, True if successful, False if not + """ + # SFP doesn't support this feature + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + # SFP doesn't support this feature + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + # SFP doesn't support this feature + return False + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/thermal.py new file mode 100644 index 000000000000..eba7ba728de9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/thermal.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python +# +# Name: thermal.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Thermal(ThermalBase): + + def __init__(self, index): + self.__index = index + + #thermal name list + self.__thermal_name_list = [ "PCH Temperature Sensor", + "CPU Board Temperature Sensor", + "FrontSide Temperature Sensor", + "NearASIC Temperature Sensor", + "RearSide Temperature Sensor" ] + + offset = 0 + if 0 != self.__index: + offset = 2 + self.__presence_attr = "/sys/class/hwmon/hwmon{}/temp1_input".format(self.__index + offset) + self.__temperature_attr = "/sys/class/hwmon/hwmon{}/temp1_input".format(self.__index + offset) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.__thermal_name_list[self.__index] or "Unknown" + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) != 0): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return "N/A" + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + return "N/A" + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() + +############################################## +# THERMAL methods +############################################## + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temperature = 0.0 + attr_path = self.__temperature_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + temperature = float(attr_rv) / 1000 + + return temperature + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + raise NotImplementedError + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + raise NotImplementedError + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + raise NotImplementedError + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + raise NotImplementedError + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py index e3e696c088cd..890973cb8356 100755 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py @@ -126,7 +126,7 @@ def exec_cmd(cmd, show): 'inv_eeprom', 'inv_cpld', 'inv_platform', -'monitor', +#'monitor', 'swps'] @@ -141,7 +141,7 @@ def system_install(): status, output = exec_cmd("rmmod lpc_ich ", 1) #insert extra module - status, output = exec_cmd("insmod /lib/modules/3.16.0-5-amd64/extra/gpio-ich.ko gpiobase=0",1) + status, output = exec_cmd("insmod /lib/modules/4.9.0-9-2-amd64/kernel/drivers/gpio/gpio-ich.ko gpiobase=0",1) #install drivers for i in range(0,len(drivers)): @@ -159,52 +159,49 @@ def system_install(): print output if FORCE == 0: return status - - #swps map to i2c-bus +# +# INV_FIX-4037 +# It replaces the original sff8436 driver with the optoe driver +# + #optoe map to i2c-bus for i in range(14,22): - status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-6/i2c-"+str(i)+"/new_device", 1) + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-6/i2c-"+str(i)+"/new_device", 1) if status: print output if FORCE == 0: return status for i in range(22,30): - status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1) - status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1) + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1) if status: print output if FORCE == 0: return status for i in range(30,38): - status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1) - status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1) + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1) if status: print output if FORCE == 0: return status for i in range(38,46): - status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1) - status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1) + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1) if status: print output if FORCE == 0: return status for i in range(46,54): - status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1) - status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1) + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1) if status: print output if FORCE == 0: return status for i in range(54,62): - status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1) - status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1) + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1) if status: print output if FORCE == 0: return status for i in range(62,70): - status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1) - status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1) + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1) if status: print output if FORCE == 0: @@ -243,7 +240,7 @@ def uninstall(): def device_found(): ret1, log = exec_cmd("ls "+i2c_prefix+"*0072", 0) ret2, log = exec_cmd("ls "+i2c_prefix+"i2c-5", 0) - return not(ret1 or ret2) + return not(ret1 or ret2) if __name__ == "__main__": main() diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index b3af29108f5f..6cb61630823f 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -27,7 +27,7 @@ Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6356 Architecture: amd64 -Depends: linux-image-4.9.0-8-2-amd64 +Depends: linux-image-4.9.0-9-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7264q28b diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.install b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.install index 4c668b9816c4..6f03ede72e05 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.install +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.install @@ -1 +1,3 @@ -d6356/utils/inventec_d6356_util.py /usr/local/bin +d6356/utils/inventec_d6356_util.py usr/local/bin +d6356/utils/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-inventec_d6356-r0 +systemd/platform-modules-d6356.service lib/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/rules b/platform/broadcom/sonic-platform-modules-inventec/debian/rules index 8bfe6e6582d9..6340540f0354 100755 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/rules +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/rules @@ -17,11 +17,17 @@ MOD_SRC_DIR:= $(shell pwd) MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b %: - dh $@ --with=systemd + dh $@ --with python2,systemd override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + if [ $$mod = "d6356" ]; then \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python2 setup.py build; \ + python2 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/utils; \ + cd $(MOD_SRC_DIR); \ + fi \ done) override_dh_auto_install: @@ -30,11 +36,13 @@ override_dh_auto_install: $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - dh_installdirs -pplatform-modules-$${mod} usr/local/bin; \ - cp $(MOD_SRC_DIR)/$${mod}/utils/* \ - debian/platform-modules-$${mod}/usr/local/bin; \ + if [ $$mod = "d6356" ]; then \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python2 setup.py install --root=$(MOD_SRC_DIR)/debian/platform-modules-$${mod} --install-layout=deb; \ + cd $(MOD_SRC_DIR); \ + fi \ done) - + override_dh_usrlocal: override_dh_pysupport: diff --git a/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6356.service b/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6356.service new file mode 100644 index 000000000000..85fa47a72611 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6356.service @@ -0,0 +1,13 @@ +[Unit] +Description=Inventec d6356 Platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-d6356 start +ExecStop=-/etc/init.d/platform-modules-d6356 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target From 9bdd693e810b3b0fa75f3754b6ac37e86ede0314 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Wed, 9 Oct 2019 17:28:33 -0700 Subject: [PATCH 0054/1427] [bcm SAI] upgrade Broadcom SAI to version 3.5.3.1m-25 (#48) - Built with SAI header version v1.5.0. Signed-off-by: Ying Xie --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index d29e0907796d..6ef784e21ced 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.5.3.1-15_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.3.1-15_amd64.deb?sv=2015-04-05&sr=b&sig=zXY%2FK%2FeGlxteIFlEkPdE%2FNDRet5T%2Fc1LgL0qyX9%2FmfQ%3D&se=2033-06-03T17%3A45%3A51Z&sp=r" +BRCM_SAI = libsaibcm_3.5.3.1m-25_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.3.1m-25_amd64.deb?sv=2015-04-05&sr=b&sig=kLfhfLeBmENmTXVa%2BZ90k2Fq8ZOQ84kxn5%2FzY3KLV2s%3D&se=2033-06-17T23%3A45%3A50Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.5.3.1-15_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.5.3.1m-25_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm-dev_3.5.3.1-15_amd64.deb?sv=2015-04-05&sr=b&sig=%2BYOVgRo6dLxv3sLb8JE1wLoD%2FneYDABadwFv5xH3XRE%3D&se=2033-06-03T17%3A46%3A14Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm-dev_3.5.3.1m-25_amd64.deb?sv=2015-04-05&sr=b&sig=a%2BvxIrNcVwnp0CBXS%2BTGiGl%2F%2Fl8mo9ZKPkZyroPY0bI%3D&se=2033-06-17T23%3A45%3A21Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 1b5c65fcf15b8359ff0ee387529e9de7e650f5a4 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 9 Oct 2019 17:38:53 -0700 Subject: [PATCH 0055/1427] [build]: Update comments on build_debian.sh (#3533) --- build_debian.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 5c7a9344f43c..34bf6eba6ab1 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -170,7 +170,7 @@ sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/resize- ## Hook into initramfs: after partition mount and loop file mount ## 1. Prepare layered file system -## 2. Bind-mount docker working directory (docker aufs cannot work over aufs rootfs) +## 2. Bind-mount docker working directory (docker overlay storage cannot work over overlay rootfs) sudo cp files/initramfs-tools/union-mount $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/union-mount sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/union-mount sudo cp files/initramfs-tools/varlog $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/varlog @@ -206,7 +206,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 -## Add docker config drop-in to select aufs, otherwise it may select other storage driver +## Add docker config drop-in to specify dockerd command line sudo mkdir -p $FILESYSTEM_ROOT/etc/systemd/system/docker.service.d/ ## Note: $_ means last argument of last command sudo cp files/docker/docker.service.conf $_ From 368c4fa9fe1cbf7e8eb7ab74c9556ee13e34093f Mon Sep 17 00:00:00 2001 From: tiantianlv <38775940+tiantianlv@users.noreply.github.com> Date: Thu, 10 Oct 2019 08:47:46 +0800 Subject: [PATCH 0056/1427] [devices]: support Silverstone platform (#3474) * [device/celestica] Add silverstone device plugins and configs * add port led fireware of PAM4! * [platform/broadcom] Add Celestica silverstone platform module. * Add switch configuration Silverstone! * Add 128x100 configuration! * Delete serdes copper parameter! * [device/celestica] Fix incorrect index in Silverstone 128x100G port cfg * [platform/broadcom] Remove unrelated platform other than Silverstone * [device/celestica] Silverstone remove minigraphs * [device/celestica] Silverstone update sai.profile to use hwsku path * [device/celestica] Silverstone format sfputil codes * [device/celestica] Add speed column to Silverstone 32x400G port conf * [device/celestica] Silverstone disable 10G ports prevent orchagent crash *These ports will be added later after BRCM SAI support SFP. * Remove LED redundancy configuration and add comments! * [plugins/sfputil] update Silverstone ports to QSFP-DD type * [plugins/sfputil] Silverstone fix return NotImplementedError with raise --- .../Silverstone-128x100/port_config.ini | 129 + .../Silverstone-128x100/sai.profile | 1 + .../th3-128x100G.config.bcm | 441 ++++ .../Silverstone/port_config.ini | 33 + .../Silverstone/sai.profile | 1 + .../Silverstone/th3-32x400G.config.bcm | 231 ++ .../x86_64-cel_silverstone-r0/custom.bin | Bin 0 -> 1216 bytes .../x86_64-cel_silverstone-r0/default_sku | 1 + .../x86_64-cel_silverstone-r0/installer.conf | 1 + .../led_proc_init.soc | 2 + .../x86_64-cel_silverstone-r0/linkscan_fw.bin | Bin 0 -> 6100 bytes .../plugins/eeprom.py | 23 + .../plugins/psuutil.py | 91 + .../plugins/sfputil.py | 186 ++ platform/broadcom/one-image.mk | 3 +- platform/broadcom/platform-modules-cel.mk | 6 + .../sonic-platform-modules-cel/debian/control | 5 + .../debian/platform-modules-silverstone.init | 49 + .../platform-modules-silverstone.install | 2 + .../platform-modules-silverstone.postinst | 3 + .../sonic-platform-modules-cel/debian/rules | 2 +- .../silverstone/cfg/silverstone-modules.conf | 15 + .../silverstone/modules/Makefile | 1 + .../silverstone/modules/baseboard-lpc.c | 433 ++++ .../silverstone/modules/mc24lc64t.c | 174 ++ .../silverstone/modules/switchboard.c | 2106 +++++++++++++++++ .../platform-modules-silverstone.service | 13 + 27 files changed, 3950 insertions(+), 2 deletions(-) create mode 100644 device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/port_config.ini create mode 100644 device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile create mode 100644 device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/th3-128x100G.config.bcm create mode 100644 device/celestica/x86_64-cel_silverstone-r0/Silverstone/port_config.ini create mode 100644 device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile create mode 100644 device/celestica/x86_64-cel_silverstone-r0/Silverstone/th3-32x400G.config.bcm create mode 100644 device/celestica/x86_64-cel_silverstone-r0/custom.bin create mode 100644 device/celestica/x86_64-cel_silverstone-r0/default_sku create mode 100644 device/celestica/x86_64-cel_silverstone-r0/installer.conf create mode 100644 device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc create mode 100644 device/celestica/x86_64-cel_silverstone-r0/linkscan_fw.bin create mode 100644 device/celestica/x86_64-cel_silverstone-r0/plugins/eeprom.py create mode 100644 device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py create mode 100755 device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/cfg/silverstone-modules.conf create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/modules/baseboard-lpc.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/modules/mc24lc64t.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switchboard.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/systemd/platform-modules-silverstone.service diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/port_config.ini b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/port_config.ini new file mode 100644 index 000000000000..238c9fa4be79 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/port_config.ini @@ -0,0 +1,129 @@ +# name lanes alias index speed +Ethernet0 33,34 QSFP1/1 1 100000 +Ethernet1 35,36 QSFP1/2 1 100000 +Ethernet2 37,38 QSFP1/3 1 100000 +Ethernet3 39,40 QSFP1/4 1 100000 +Ethernet4 41,42 QSFP2/1 2 100000 +Ethernet5 43,44 QSFP2/2 2 100000 +Ethernet6 45,46 QSFP2/3 2 100000 +Ethernet7 47,48 QSFP2/4 2 100000 +Ethernet8 49,50 QSFP3/1 3 100000 +Ethernet9 51,52 QSFP3/2 3 100000 +Ethernet10 53,54 QSFP3/3 3 100000 +Ethernet11 55,56 QSFP3/4 3 100000 +Ethernet12 57,58 QSFP4/1 4 100000 +Ethernet13 59,60 QSFP4/2 4 100000 +Ethernet14 61,62 QSFP4/3 4 100000 +Ethernet15 63,64 QSFP4/4 4 100000 +Ethernet16 65,66 QSFP5/1 5 100000 +Ethernet17 67,68 QSFP5/2 5 100000 +Ethernet18 69,70 QSFP5/3 5 100000 +Ethernet19 71,72 QSFP5/4 5 100000 +Ethernet20 73,74 QSFP6/1 6 100000 +Ethernet21 75,76 QSFP6/2 6 100000 +Ethernet22 77,78 QSFP6/3 6 100000 +Ethernet23 79,80 QSFP6/4 6 100000 +Ethernet24 81,82 QSFP7/1 7 100000 +Ethernet25 83,84 QSFP7/2 7 100000 +Ethernet26 85,86 QSFP7/3 7 100000 +Ethernet27 87,88 QSFP7/4 7 100000 +Ethernet28 89,90 QSFP8/1 8 100000 +Ethernet29 91,92 QSFP8/2 8 100000 +Ethernet30 93,94 QSFP8/3 8 100000 +Ethernet31 95,96 QSFP8/4 8 100000 +Ethernet32 1,2 QSFP9/1 9 100000 +Ethernet33 3,4 QSFP9/2 9 100000 +Ethernet34 5,6 QSFP9/3 9 100000 +Ethernet35 7,8 QSFP9/4 9 100000 +Ethernet36 9,10 QSFP10/1 10 100000 +Ethernet37 11,12 QSFP10/2 10 100000 +Ethernet38 13,14 QSFP10/3 10 100000 +Ethernet39 15,16 QSFP10/4 10 100000 +Ethernet40 17,18 QSFP11/1 11 100000 +Ethernet41 19,20 QSFP11/2 11 100000 +Ethernet42 21,22 QSFP11/3 11 100000 +Ethernet43 23,24 QSFP11/4 11 100000 +Ethernet44 25,26 QSFP12/1 12 100000 +Ethernet45 27,28 QSFP12/2 12 100000 +Ethernet46 29,30 QSFP12/3 12 100000 +Ethernet47 31,32 QSFP12/4 12 100000 +Ethernet48 97,98 QSFP13/1 13 100000 +Ethernet49 99,100 QSFP13/2 13 100000 +Ethernet50 101,102 QSFP13/3 13 100000 +Ethernet51 103,104 QSFP13/4 13 100000 +Ethernet52 105,106 QSFP14/1 14 100000 +Ethernet53 107,108 QSFP14/2 14 100000 +Ethernet54 109,110 QSFP14/3 14 100000 +Ethernet55 111,112 QSFP14/4 14 100000 +Ethernet56 113,114 QSFP15/1 15 100000 +Ethernet57 115,116 QSFP15/2 15 100000 +Ethernet58 117,118 QSFP15/3 15 100000 +Ethernet59 119,120 QSFP15/4 15 100000 +Ethernet60 121,122 QSFP16/1 16 100000 +Ethernet61 123,124 QSFP16/2 16 100000 +Ethernet62 125,126 QSFP16/3 16 100000 +Ethernet63 127,128 QSFP16/4 16 100000 +Ethernet64 129,130 QSFP17/1 17 100000 +Ethernet65 131,132 QSFP17/2 17 100000 +Ethernet66 133,134 QSFP17/3 17 100000 +Ethernet67 135,136 QSFP17/4 17 100000 +Ethernet68 137,138 QSFP18/1 18 100000 +Ethernet69 139,140 QSFP18/2 18 100000 +Ethernet70 141,142 QSFP18/3 18 100000 +Ethernet71 143,144 QSFP18/4 18 100000 +Ethernet72 145,146 QSFP19/1 19 100000 +Ethernet73 147,148 QSFP19/2 19 100000 +Ethernet74 149,150 QSFP19/3 19 100000 +Ethernet75 151,152 QSFP19/4 19 100000 +Ethernet76 153,154 QSFP20/1 20 100000 +Ethernet77 155,156 QSFP20/2 20 100000 +Ethernet78 157,158 QSFP20/3 20 100000 +Ethernet79 159,160 QSFP20/4 20 100000 +Ethernet80 225,226 QSFP21/1 21 100000 +Ethernet81 227,228 QSFP21/2 21 100000 +Ethernet82 229,230 QSFP21/3 21 100000 +Ethernet83 231,232 QSFP21/4 21 100000 +Ethernet84 233,234 QSFP22/1 22 100000 +Ethernet85 235,236 QSFP22/2 22 100000 +Ethernet86 237,238 QSFP22/3 22 100000 +Ethernet87 239,240 QSFP22/4 22 100000 +Ethernet88 241,242 QSFP23/1 23 100000 +Ethernet89 243,244 QSFP23/2 23 100000 +Ethernet90 245,246 QSFP23/3 23 100000 +Ethernet91 247,248 QSFP23/4 23 100000 +Ethernet92 249,250 QSFP24/1 24 100000 +Ethernet93 251,252 QSFP24/2 24 100000 +Ethernet94 253,254 QSFP24/3 24 100000 +Ethernet95 255,256 QSFP24/4 24 100000 +Ethernet96 161,162 QSFP25/1 25 100000 +Ethernet97 163,164 QSFP25/2 25 100000 +Ethernet98 165,166 QSFP25/3 25 100000 +Ethernet99 167,168 QSFP25/4 25 100000 +Ethernet100 169,170 QSFP26/1 26 100000 +Ethernet101 171,172 QSFP26/2 26 100000 +Ethernet102 173,174 QSFP26/3 26 100000 +Ethernet103 175,176 QSFP26/4 26 100000 +Ethernet104 177,178 QSFP27/1 27 100000 +Ethernet105 179,180 QSFP27/2 27 100000 +Ethernet106 181,182 QSFP27/3 27 100000 +Ethernet107 183,184 QSFP27/4 27 100000 +Ethernet108 185,186 QSFP28/1 28 100000 +Ethernet109 187,188 QSFP28/2 28 100000 +Ethernet110 189,190 QSFP28/3 28 100000 +Ethernet111 191,192 QSFP28/4 28 100000 +Ethernet112 193,194 QSFP29/1 29 100000 +Ethernet113 195,196 QSFP29/2 29 100000 +Ethernet114 197,198 QSFP29/3 29 100000 +Ethernet115 199,200 QSFP29/4 29 100000 +Ethernet116 201,202 QSFP30/1 30 100000 +Ethernet117 203,204 QSFP30/2 30 100000 +Ethernet118 205,206 QSFP30/3 30 100000 +Ethernet119 207,208 QSFP30/4 30 100000 +Ethernet120 209,210 QSFP31/1 31 100000 +Ethernet121 211,212 QSFP31/2 31 100000 +Ethernet122 213,214 QSFP31/3 31 100000 +Ethernet123 215,216 QSFP31/4 31 100000 +Ethernet124 217,218 QSFP32/1 32 100000 +Ethernet125 219,220 QSFP32/2 32 100000 +Ethernet126 221,222 QSFP32/3 32 100000 +Ethernet127 223,224 QSFP32/4 32 100000 \ No newline at end of file diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile new file mode 100644 index 000000000000..bc7681f0272f --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-128x100G.config.bcm diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/th3-128x100G.config.bcm b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/th3-128x100G.config.bcm new file mode 100644 index 000000000000..0b66c8b53814 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/th3-128x100G.config.bcm @@ -0,0 +1,441 @@ +pbmp_xport_xe.0=0x8ffff8ffffcffff8ffff8ffff8ffffcffff9fffe +ccm_dma_enable=0 +ccmdma_intr_enable=0 +ctr_evict_enable=0 +mem_cache_enable=0 +parity_correction=0 +parity_enable=0 +phy_enable=0 +phy_null=1 +pll_bypass=1 + +init_all_modules=0 + +portmap_20=33:100:2 +portmap_21=35:100:2 +portmap_22=37:100:2 +portmap_23=39:100:2 + +portmap_24=41:100:2 +portmap_25=43:100:2 +portmap_26=45:100:2 +portmap_27=47:100:2 + +portmap_28=49:100:2 +portmap_29=51:100:2 +portmap_30=53:100:2 +portmap_31=55:100:2 + +portmap_32=57:100:2 +portmap_33=59:100:2 +portmap_34=61:100:2 +portmap_35=63:100:2 + +portmap_40=65:100:2 +portmap_41=67:100:2 +portmap_42=69:100:2 +portmap_43=71:100:2 + +portmap_44=73:100:2 +portmap_45=75:100:2 +portmap_46=77:100:2 +portmap_47=79:100:2 + +portmap_48=81:100:2 +portmap_49=83:100:2 +portmap_50=85:100:2 +portmap_51=87:100:2 + +portmap_52=89:100:2 +portmap_53=91:100:2 +portmap_54=93:100:2 +portmap_55=95:100:2 + +portmap_1=1:100:2 +portmap_2=3:100:2 +portmap_3=5:100:2 +portmap_4=7:100:2 + +portmap_5=9:100:2 +portmap_6=11:100:2 +portmap_7=13:100:2 +portmap_8=15:100:2 + +portmap_9=17:100:2 +portmap_10=19:100:2 +portmap_11=21:100:2 +portmap_12=23:100:2 + +portmap_13=25:100:2 +portmap_14=27:100:2 +portmap_15=29:100:2 +portmap_16=31:100:2 + +portmap_60=97:100:2 +portmap_61=99:100:2 +portmap_62=101:100:2 +portmap_63=103:100:2 + +portmap_64=105:100:2 +portmap_65=107:100:2 +portmap_66=109:100:2 +portmap_67=111:100:2 + +portmap_68=113:100:2 +portmap_69=115:100:2 +portmap_70=117:100:2 +portmap_71=119:100:2 + +portmap_72=121:100:2 +portmap_73=123:100:2 +portmap_74=125:100:2 +portmap_75=127:100:2 + +portmap_80=129:100:2 +portmap_81=131:100:2 +portmap_82=133:100:2 +portmap_83=135:100:2 + +portmap_84=137:100:2 +portmap_85=139:100:2 +portmap_86=141:100:2 +portmap_87=143:100:2 + +portmap_88=145:100:2 +portmap_89=147:100:2 +portmap_90=149:100:2 +portmap_91=151:100:2 + +portmap_92=153:100:2 +portmap_93=155:100:2 +portmap_94=157:100:2 +portmap_95=159:100:2 + +portmap_140=225:100:2 +portmap_141=227:100:2 +portmap_142=229:100:2 +portmap_143=231:100:2 + +portmap_144=233:100:2 +portmap_145=235:100:2 +portmap_146=237:100:2 +portmap_147=239:100:2 + +portmap_148=241:100:2 +portmap_149=243:100:2 +portmap_150=245:100:2 +portmap_151=247:100:2 + +portmap_152=249:100:2 +portmap_153=251:100:2 +portmap_154=253:100:2 +portmap_155=255:100:2 + +portmap_100=161:100:2 +portmap_101=163:100:2 +portmap_102=165:100:2 +portmap_103=167:100:2 + +portmap_104=169:100:2 +portmap_105=171:100:2 +portmap_106=173:100:2 +portmap_107=175:100:2 + +portmap_108=177:100:2 +portmap_109=179:100:2 +portmap_110=181:100:2 +portmap_111=183:100:2 + +portmap_112=185:100:2 +portmap_113=187:100:2 +portmap_114=189:100:2 +portmap_115=191:100:2 + +portmap_120=193:100:2 +portmap_121=195:100:2 +portmap_122=197:100:2 +portmap_123=199:100:2 + +portmap_124=201:100:2 +portmap_125=203:100:2 +portmap_126=205:100:2 +portmap_127=207:100:2 + +portmap_128=209:100:2 +portmap_129=211:100:2 +portmap_130=213:100:2 +portmap_131=215:100:2 + +portmap_132=217:100:2 +portmap_133=219:100:2 +portmap_134=221:100:2 +portmap_135=223:100:2 + +phy_chain_rx_lane_map_physical{33.0}=0x65732041 +phy_chain_tx_lane_map_physical{33.0}=0x47206531 +phy_chain_rx_lane_map_physical{41.0}=0x07561243 +phy_chain_tx_lane_map_physical{41.0}=0x36207514 +phy_chain_rx_lane_map_physical{49.0}=0x54632071 +phy_chain_tx_lane_map_physical{49.0}=0x06241735 +phy_chain_rx_lane_map_physical{57.0}=0x07561243 +phy_chain_tx_lane_map_physical{57.0}=0x35207614 +phy_chain_rx_lane_map_physical{65.0}=0x45623170 +phy_chain_tx_lane_map_physical{65.0}=0x51260734 +phy_chain_rx_lane_map_physical{73.0}=0x07561243 +phy_chain_tx_lane_map_physical{73.0}=0x37245610 +phy_chain_rx_lane_map_physical{81.0}=0x45632071 +phy_chain_tx_lane_map_physical{81.0}=0x51260734 +phy_chain_rx_lane_map_physical{89.0}=0x07561243 +phy_chain_tx_lane_map_physical{89.0}=0x26437510 +phy_chain_rx_lane_map_physical{1.0}=0x30176524 +phy_chain_tx_lane_map_physical{1.0}=0x20615374 +phy_chain_rx_lane_map_physical{9.0}=0x37562041 +phy_chain_tx_lane_map_physical{9.0}=0x05176432 +phy_chain_rx_lane_map_physical{17.0}=0x43607251 +phy_chain_tx_lane_map_physical{17.0}=0x70261435 +phy_chain_rx_lane_map_physical{25.0}=0x60347125 +phy_chain_tx_lane_map_physical{25.0}=0x46357120 +phy_chain_rx_lane_map_physical{97.0}=0x47601352 +phy_chain_tx_lane_map_physical{97.0}=0x04265137 +phy_chain_rx_lane_map_physical{105.0}=0x73206415 +phy_chain_tx_lane_map_physical{105.0}=0x26374150 +phy_chain_rx_lane_map_physical{113.0}=0x47632051 +phy_chain_tx_lane_map_physical{113.0}=0x03254617 +phy_chain_rx_lane_map_physical{121.0}=0x63027415 +phy_chain_tx_lane_map_physical{121.0}=0x63721045 +phy_chain_rx_lane_map_physical{129.0}=0x30154627 +phy_chain_tx_lane_map_physical{129.0}=0x04735261 +phy_chain_rx_lane_map_physical{137.0}=0x24753061 +phy_chain_tx_lane_map_physical{137.0}=0x37614520 +phy_chain_rx_lane_map_physical{145.0}=0x47601352 +phy_chain_tx_lane_map_physical{145.0}=0x63274510 +phy_chain_rx_lane_map_physical{153.0}=0x07361524 +phy_chain_tx_lane_map_physical{153.0}=0x36527104 +phy_chain_rx_lane_map_physical{225.0}=0x56410273 +phy_chain_tx_lane_map_physical{225.0}=0x10274635 +phy_chain_rx_lane_map_physical{233.0}=0x15740263 +phy_chain_tx_lane_map_physical{233.0}=0x24351607 +phy_chain_rx_lane_map_physical{241.0}=0x74015263 +phy_chain_tx_lane_map_physical{241.0}=0x04152637 +phy_chain_rx_lane_map_physical{249.0}=0x62037514 +phy_chain_tx_lane_map_physical{249.0}=0x72453160 +phy_chain_rx_lane_map_physical{161.0}=0x46510273 +phy_chain_tx_lane_map_physical{161.0}=0x01653724 +phy_chain_rx_lane_map_physical{169.0}=0x25743160 +phy_chain_tx_lane_map_physical{169.0}=0x07216435 +phy_chain_rx_lane_map_physical{177.0}=0x46510273 +phy_chain_tx_lane_map_physical{177.0}=0x01652734 +phy_chain_rx_lane_map_physical{185.0}=0x25743160 +phy_chain_tx_lane_map_physical{185.0}=0x37016425 +phy_chain_rx_lane_map_physical{193.0}=0x46510372 +phy_chain_tx_lane_map_physical{193.0}=0x06153724 +phy_chain_rx_lane_map_physical{201.0}=0x25743160 +phy_chain_tx_lane_map_physical{201.0}=0x36017524 +phy_chain_rx_lane_map_physical{209.0}=0x47601352 +phy_chain_tx_lane_map_physical{209.0}=0x04152736 +phy_chain_rx_lane_map_physical{217.0}=0x26453170 +phy_chain_tx_lane_map_physical{217.0}=0x36027415 + +serdes_core_rx_polarity_flip_physical{33}=0x29 +serdes_core_tx_polarity_flip_physical{33}=0xfe +serdes_core_rx_polarity_flip_physical{41}=0xb1 +serdes_core_tx_polarity_flip_physical{41}=0xe8 +serdes_core_rx_polarity_flip_physical{49}=0xca +serdes_core_tx_polarity_flip_physical{49}=0xb6 +serdes_core_rx_polarity_flip_physical{57}=0x9b +serdes_core_tx_polarity_flip_physical{57}=0xdc +serdes_core_rx_polarity_flip_physical{65}=0x17 +serdes_core_tx_polarity_flip_physical{65}=0x86 +serdes_core_rx_polarity_flip_physical{73}=0x9b +serdes_core_tx_polarity_flip_physical{73}=0x55 +serdes_core_rx_polarity_flip_physical{81}=0xa +serdes_core_tx_polarity_flip_physical{81}=0x6 +serdes_core_rx_polarity_flip_physical{89}=0x9b +serdes_core_tx_polarity_flip_physical{89}=0x48 +serdes_core_rx_polarity_flip_physical{1}=0xec +serdes_core_tx_polarity_flip_physical{1}=0x56 +serdes_core_rx_polarity_flip_physical{9}=0x13 +serdes_core_tx_polarity_flip_physical{9}=0xa6 +serdes_core_rx_polarity_flip_physical{17}=0x5a +serdes_core_tx_polarity_flip_physical{17}=0xc6 +serdes_core_rx_polarity_flip_physical{25}=0xf +serdes_core_tx_polarity_flip_physical{25}=0x4e +serdes_core_rx_polarity_flip_physical{97}=0x17 +serdes_core_tx_polarity_flip_physical{97}=0x2e +serdes_core_rx_polarity_flip_physical{105}=0xce +serdes_core_tx_polarity_flip_physical{105}=0x7c +serdes_core_rx_polarity_flip_physical{113}=0xa +serdes_core_tx_polarity_flip_physical{113}=0x35 + +serdes_core_rx_polarity_flip_physical{121}=0xb9 +serdes_core_tx_polarity_flip_physical{121}=0xef +serdes_core_rx_polarity_flip_physical{129}=0xe8 +serdes_core_tx_polarity_flip_physical{129}=0xac +serdes_core_rx_polarity_flip_physical{137}=0xcb +serdes_core_tx_polarity_flip_physical{137}=0x9c +serdes_core_rx_polarity_flip_physical{145}=0x17 +serdes_core_tx_polarity_flip_physical{145}=0x32 +serdes_core_rx_polarity_flip_physical{153}=0xb9 +serdes_core_tx_polarity_flip_physical{153}=0xaf +serdes_core_rx_polarity_flip_physical{225}=0xaa +serdes_core_tx_polarity_flip_physical{225}=0x7 +serdes_core_rx_polarity_flip_physical{233}=0x31 +serdes_core_tx_polarity_flip_physical{233}=0x47 +serdes_core_rx_polarity_flip_physical{241}=0xe8 +serdes_core_tx_polarity_flip_physical{241}=0x9e +serdes_core_rx_polarity_flip_physical{249}=0xec +serdes_core_tx_polarity_flip_physical{249}=0x1f +serdes_core_rx_polarity_flip_physical{161}=0x6a +serdes_core_tx_polarity_flip_physical{161}=0xd4 +serdes_core_rx_polarity_flip_physical{169}=0x9e +serdes_core_tx_polarity_flip_physical{169}=0x7b +serdes_core_rx_polarity_flip_physical{177}=0x6a +serdes_core_tx_polarity_flip_physical{177}=0xcc +serdes_core_rx_polarity_flip_physical{185}=0x9e +serdes_core_tx_polarity_flip_physical{185}=0x58 +serdes_core_rx_polarity_flip_physical{193}=0x6f +serdes_core_tx_polarity_flip_physical{193}=0x24 +serdes_core_rx_polarity_flip_physical{201}=0x9e +serdes_core_tx_polarity_flip_physical{201}=0xdf +serdes_core_rx_polarity_flip_physical{209}=0x17 +serdes_core_tx_polarity_flip_physical{209}=0xe9 +serdes_core_rx_polarity_flip_physical{217}=0xec +serdes_core_tx_polarity_flip_physical{217}=0x68 + + +dport_map_port_20=1 +dport_map_port_21=2 +dport_map_port_22=3 +dport_map_port_23=4 +dport_map_port_24=5 +dport_map_port_25=6 +dport_map_port_26=7 +dport_map_port_27=8 +dport_map_port_28=9 +dport_map_port_29=10 +dport_map_port_30=11 +dport_map_port_31=12 +dport_map_port_32=13 +dport_map_port_33=14 +dport_map_port_34=15 +dport_map_port_35=16 +dport_map_port_40=17 +dport_map_port_41=18 +dport_map_port_42=19 +dport_map_port_43=20 +dport_map_port_44=21 +dport_map_port_45=22 +dport_map_port_46=23 +dport_map_port_47=24 +dport_map_port_48=25 +dport_map_port_49=26 +dport_map_port_50=27 +dport_map_port_51=28 +dport_map_port_52=29 +dport_map_port_53=30 +dport_map_port_54=31 +dport_map_port_55=32 +dport_map_port_1=33 +dport_map_port_2=34 +dport_map_port_3=35 +dport_map_port_4=36 +dport_map_port_5=37 +dport_map_port_6=38 +dport_map_port_7=39 +dport_map_port_8=40 +dport_map_port_9=41 +dport_map_port_10=42 +dport_map_port_11=43 +dport_map_port_12=44 +dport_map_port_13=45 +dport_map_port_14=46 +dport_map_port_15=47 +dport_map_port_16=48 +dport_map_port_60=49 +dport_map_port_61=50 +dport_map_port_62=51 +dport_map_port_63=52 +dport_map_port_64=53 +dport_map_port_65=54 +dport_map_port_66=55 +dport_map_port_67=56 +dport_map_port_68=57 +dport_map_port_69=58 +dport_map_port_70=59 +dport_map_port_71=60 +dport_map_port_72=61 +dport_map_port_73=62 +dport_map_port_74=63 +dport_map_port_75=64 +dport_map_port_80=65 +dport_map_port_81=66 +dport_map_port_82=67 +dport_map_port_83=68 +dport_map_port_84=69 +dport_map_port_85=70 +dport_map_port_86=71 +dport_map_port_87=72 +dport_map_port_88=73 +dport_map_port_89=74 +dport_map_port_90=75 +dport_map_port_91=76 +dport_map_port_92=77 +dport_map_port_93=78 +dport_map_port_94=79 +dport_map_port_95=80 +dport_map_port_140=81 +dport_map_port_141=82 +dport_map_port_142=83 +dport_map_port_143=84 +dport_map_port_144=85 +dport_map_port_145=86 +dport_map_port_146=87 +dport_map_port_147=88 +dport_map_port_148=89 +dport_map_port_149=90 +dport_map_port_150=91 +dport_map_port_151=92 +dport_map_port_152=93 +dport_map_port_153=94 +dport_map_port_154=95 +dport_map_port_155=96 +dport_map_port_100=97 +dport_map_port_101=98 +dport_map_port_102=99 +dport_map_port_103=100 +dport_map_port_104=101 +dport_map_port_105=102 +dport_map_port_106=103 +dport_map_port_107=104 +dport_map_port_108=105 +dport_map_port_109=106 +dport_map_port_110=107 +dport_map_port_111=108 +dport_map_port_112=109 +dport_map_port_113=110 +dport_map_port_114=111 +dport_map_port_115=112 +dport_map_port_120=113 +dport_map_port_121=114 +dport_map_port_122=115 +dport_map_port_123=116 +dport_map_port_124=117 +dport_map_port_125=118 +dport_map_port_126=119 +dport_map_port_127=120 +dport_map_port_128=121 +dport_map_port_129=122 +dport_map_port_130=123 +dport_map_port_131=124 +dport_map_port_132=125 +dport_map_port_133=126 +dport_map_port_134=127 +dport_map_port_135=128 + +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 + +#firmware load method, use fast load +load_firmware=0x2 diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/port_config.ini b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/port_config.ini new file mode 100644 index 000000000000..9cd85ee34798 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 33,34,35,36,37,38,39,40 QSFPDD1 1 400000 +Ethernet4 41,42,43,44,45,46,47,48 QSFPDD2 2 400000 +Ethernet8 49,50,51,52,53,54,55,56 QSFPDD3 3 400000 +Ethernet12 57,58,59,60,61,62,63,64 QSFPDD4 4 400000 +Ethernet16 65,66,67,68,69,70,71,72 QSFPDD5 5 400000 +Ethernet20 73,74,75,76,77,78,79,80 QSFPDD6 6 400000 +Ethernet24 81,82,83,84,85,86,87,88 QSFPDD7 7 400000 +Ethernet28 89,90,91,92,93,94,95,96 QSFPDD8 8 400000 +Ethernet32 1,2,3,4,5,6,7,8 QSFPDD9 9 400000 +Ethernet36 9,10,11,12,13,14,15,16 QSFPDD10 10 400000 +Ethernet40 17,18,19,20,21,22,23,24 QSFPDD11 11 400000 +Ethernet44 25,26,27,28,29,30,31,32 QSFPDD12 12 400000 +Ethernet48 97,98,99,100,101,102,103,104 QSFPDD13 13 400000 +Ethernet52 105,106,107,108,109,110,111,112 QSFPDD14 14 400000 +Ethernet56 113,114,115,116,117,118,119,120 QSFPDD15 15 400000 +Ethernet60 121,122,123,124,125,126,127,128 QSFPDD16 16 400000 +Ethernet64 129,130,131,132,133,134,135,136 QSFPDD17 17 400000 +Ethernet68 137,138,139,140,141,142,143,144 QSFPDD18 18 400000 +Ethernet72 145,146,147,148,149,150,151,152 QSFPDD19 19 400000 +Ethernet76 153,154,155,156,157,158,159,160 QSFPDD20 20 400000 +Ethernet80 225,226,227,228,229,230,231,232 QSFPDD21 21 400000 +Ethernet84 233,234,235,236,237,238,239,240 QSFPDD22 22 400000 +Ethernet88 241,242,243,244,245,246,247,248 QSFPDD23 23 400000 +Ethernet92 249,250,251,252,253,254,255,256 QSFPDD24 24 400000 +Ethernet96 161,162,163,164,165,166,167,168 QSFPDD25 25 400000 +Ethernet100 169,170,171,172,173,174,175,176 QSFPDD26 26 400000 +Ethernet104 177,178,179,180,181,182,183,184 QSFPDD27 27 400000 +Ethernet108 185,186,187,188,189,190,191,192 QSFPDD28 28 400000 +Ethernet112 193,194,195,196,197,198,199,200 QSFPDD29 29 400000 +Ethernet116 201,202,203,204,205,206,207,208 QSFPDD30 30 400000 +Ethernet120 209,210,211,212,213,214,215,216 QSFPDD31 31 400000 +Ethernet124 217,218,219,220,221,222,223,224 QSFPDD32 32 400000 \ No newline at end of file diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile new file mode 100644 index 000000000000..1915eb9b35a1 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-32x400G.config.bcm diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/th3-32x400G.config.bcm b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/th3-32x400G.config.bcm new file mode 100644 index 000000000000..5e5fc82aeace --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/th3-32x400G.config.bcm @@ -0,0 +1,231 @@ + +pbmp_xport_xe.0=0x8111181111c1111811118111181111c111182222 +ccm_dma_enable=0 +ccmdma_intr_enable=0 +ctr_evict_enable=0 +mem_cache_enable=0 +parity_correction=0 +parity_enable=0 +phy_enable=0 +phy_null=1 +pll_bypass=1 + +init_all_modules=0 + + + +#portmap_38=257:10 +#portmap_118=258:10 + + +portmap_20=33:400 +portmap_24=41:400 +portmap_28=49:400 +portmap_32=57:400 +portmap_40=65:400 +portmap_44=73:400 +portmap_48=81:400 +portmap_52=89:400 +portmap_1=1:400 +portmap_5=9:400 +portmap_9=17:400 +portmap_13=25:400 +portmap_60=97:400 +portmap_64=105:400 +portmap_68=113:400 +portmap_72=121:400 +portmap_80=129:400 +portmap_84=137:400 +portmap_88=145:400 +portmap_92=153:400 +portmap_140=225:400 +portmap_144=233:400 +portmap_148=241:400 +portmap_152=249:400 +portmap_100=161:400 +portmap_104=169:400 +portmap_108=177:400 +portmap_112=185:400 +portmap_120=193:400 +portmap_124=201:400 +portmap_128=209:400 +portmap_132=217:400 + +phy_chain_rx_lane_map_physical{33.0}=0x65732041 +phy_chain_tx_lane_map_physical{33.0}=0x47206531 +phy_chain_rx_lane_map_physical{41.0}=0x07561243 +phy_chain_tx_lane_map_physical{41.0}=0x36207514 +phy_chain_rx_lane_map_physical{49.0}=0x54632071 +phy_chain_tx_lane_map_physical{49.0}=0x06241735 +phy_chain_rx_lane_map_physical{57.0}=0x07561243 +phy_chain_tx_lane_map_physical{57.0}=0x35207614 +phy_chain_rx_lane_map_physical{65.0}=0x45623170 +phy_chain_tx_lane_map_physical{65.0}=0x51260734 +phy_chain_rx_lane_map_physical{73.0}=0x07561243 +phy_chain_tx_lane_map_physical{73.0}=0x37245610 +phy_chain_rx_lane_map_physical{81.0}=0x45632071 +phy_chain_tx_lane_map_physical{81.0}=0x51260734 +phy_chain_rx_lane_map_physical{89.0}=0x07561243 +phy_chain_tx_lane_map_physical{89.0}=0x26437510 +phy_chain_rx_lane_map_physical{1.0}=0x30176524 +phy_chain_tx_lane_map_physical{1.0}=0x20615374 +phy_chain_rx_lane_map_physical{9.0}=0x37562041 +phy_chain_tx_lane_map_physical{9.0}=0x05176432 +phy_chain_rx_lane_map_physical{17.0}=0x43607251 +phy_chain_tx_lane_map_physical{17.0}=0x70261435 +phy_chain_rx_lane_map_physical{25.0}=0x60347125 +phy_chain_tx_lane_map_physical{25.0}=0x46357120 +phy_chain_rx_lane_map_physical{97.0}=0x47601352 +phy_chain_tx_lane_map_physical{97.0}=0x04265137 +phy_chain_rx_lane_map_physical{105.0}=0x73206415 +phy_chain_tx_lane_map_physical{105.0}=0x26374150 +phy_chain_rx_lane_map_physical{113.0}=0x47632051 +phy_chain_tx_lane_map_physical{113.0}=0x03254617 +phy_chain_rx_lane_map_physical{121.0}=0x63027415 +phy_chain_tx_lane_map_physical{121.0}=0x63721045 +phy_chain_rx_lane_map_physical{129.0}=0x30154627 +phy_chain_tx_lane_map_physical{129.0}=0x04735261 +phy_chain_rx_lane_map_physical{137.0}=0x24753061 +phy_chain_tx_lane_map_physical{137.0}=0x37614520 +phy_chain_rx_lane_map_physical{145.0}=0x47601352 +phy_chain_tx_lane_map_physical{145.0}=0x63274510 +phy_chain_rx_lane_map_physical{153.0}=0x07361524 +phy_chain_tx_lane_map_physical{153.0}=0x36527104 +phy_chain_rx_lane_map_physical{225.0}=0x56410273 +phy_chain_tx_lane_map_physical{225.0}=0x10274635 +phy_chain_rx_lane_map_physical{233.0}=0x15740263 +phy_chain_tx_lane_map_physical{233.0}=0x24351607 +phy_chain_rx_lane_map_physical{241.0}=0x74015263 +phy_chain_tx_lane_map_physical{241.0}=0x04152637 +phy_chain_rx_lane_map_physical{249.0}=0x62037514 +phy_chain_tx_lane_map_physical{249.0}=0x72453160 +phy_chain_rx_lane_map_physical{161.0}=0x46510273 +phy_chain_tx_lane_map_physical{161.0}=0x01653724 +phy_chain_rx_lane_map_physical{169.0}=0x25743160 +phy_chain_tx_lane_map_physical{169.0}=0x07216435 +phy_chain_rx_lane_map_physical{177.0}=0x46510273 +phy_chain_tx_lane_map_physical{177.0}=0x01652734 +phy_chain_rx_lane_map_physical{185.0}=0x25743160 +phy_chain_tx_lane_map_physical{185.0}=0x37016425 +phy_chain_rx_lane_map_physical{193.0}=0x46510372 +phy_chain_tx_lane_map_physical{193.0}=0x06153724 +phy_chain_rx_lane_map_physical{201.0}=0x25743160 +phy_chain_tx_lane_map_physical{201.0}=0x36017524 +phy_chain_rx_lane_map_physical{209.0}=0x47601352 +phy_chain_tx_lane_map_physical{209.0}=0x04152736 +phy_chain_rx_lane_map_physical{217.0}=0x26453170 +phy_chain_tx_lane_map_physical{217.0}=0x36027415 + +serdes_core_rx_polarity_flip_physical{33}=0x29 +serdes_core_tx_polarity_flip_physical{33}=0xfe +serdes_core_rx_polarity_flip_physical{41}=0xb1 +serdes_core_tx_polarity_flip_physical{41}=0xe8 +serdes_core_rx_polarity_flip_physical{49}=0xca +serdes_core_tx_polarity_flip_physical{49}=0xb6 +serdes_core_rx_polarity_flip_physical{57}=0x9b +serdes_core_tx_polarity_flip_physical{57}=0xdc +serdes_core_rx_polarity_flip_physical{65}=0x17 +serdes_core_tx_polarity_flip_physical{65}=0x86 +serdes_core_rx_polarity_flip_physical{73}=0x9b +serdes_core_tx_polarity_flip_physical{73}=0x55 +serdes_core_rx_polarity_flip_physical{81}=0xa +serdes_core_tx_polarity_flip_physical{81}=0x6 +serdes_core_rx_polarity_flip_physical{89}=0x9b +serdes_core_tx_polarity_flip_physical{89}=0x48 +serdes_core_rx_polarity_flip_physical{1}=0xec +serdes_core_tx_polarity_flip_physical{1}=0x56 +serdes_core_rx_polarity_flip_physical{9}=0x13 +serdes_core_tx_polarity_flip_physical{9}=0xa6 +serdes_core_rx_polarity_flip_physical{17}=0x5a +serdes_core_tx_polarity_flip_physical{17}=0xc6 +serdes_core_rx_polarity_flip_physical{25}=0xf +serdes_core_tx_polarity_flip_physical{25}=0x4e +serdes_core_rx_polarity_flip_physical{97}=0x17 +serdes_core_tx_polarity_flip_physical{97}=0x2e +serdes_core_rx_polarity_flip_physical{105}=0xce +serdes_core_tx_polarity_flip_physical{105}=0x7c +serdes_core_rx_polarity_flip_physical{113}=0xa +serdes_core_tx_polarity_flip_physical{113}=0x35 + +serdes_core_rx_polarity_flip_physical{121}=0xb9 +serdes_core_tx_polarity_flip_physical{121}=0xef +serdes_core_rx_polarity_flip_physical{129}=0xe8 +serdes_core_tx_polarity_flip_physical{129}=0xac +serdes_core_rx_polarity_flip_physical{137}=0xcb +serdes_core_tx_polarity_flip_physical{137}=0x9c +serdes_core_rx_polarity_flip_physical{145}=0x17 +serdes_core_tx_polarity_flip_physical{145}=0x32 +serdes_core_rx_polarity_flip_physical{153}=0xb9 +serdes_core_tx_polarity_flip_physical{153}=0xaf +serdes_core_rx_polarity_flip_physical{225}=0xaa +serdes_core_tx_polarity_flip_physical{225}=0x7 +serdes_core_rx_polarity_flip_physical{233}=0x31 +serdes_core_tx_polarity_flip_physical{233}=0x47 +serdes_core_rx_polarity_flip_physical{241}=0xe8 +serdes_core_tx_polarity_flip_physical{241}=0x9e +serdes_core_rx_polarity_flip_physical{249}=0xec +serdes_core_tx_polarity_flip_physical{249}=0x1f +serdes_core_rx_polarity_flip_physical{161}=0x6a +serdes_core_tx_polarity_flip_physical{161}=0xd4 +serdes_core_rx_polarity_flip_physical{169}=0x9e +serdes_core_tx_polarity_flip_physical{169}=0x7b +serdes_core_rx_polarity_flip_physical{177}=0x6a +serdes_core_tx_polarity_flip_physical{177}=0xcc +serdes_core_rx_polarity_flip_physical{185}=0x9e +serdes_core_tx_polarity_flip_physical{185}=0x58 +serdes_core_rx_polarity_flip_physical{193}=0x6f +serdes_core_tx_polarity_flip_physical{193}=0x24 +serdes_core_rx_polarity_flip_physical{201}=0x9e +serdes_core_tx_polarity_flip_physical{201}=0xdf +serdes_core_rx_polarity_flip_physical{209}=0x17 +serdes_core_tx_polarity_flip_physical{209}=0xe9 +serdes_core_rx_polarity_flip_physical{217}=0xec +serdes_core_tx_polarity_flip_physical{217}=0x68 + +dport_map_port_20=1 +dport_map_port_24=2 +dport_map_port_28=3 +dport_map_port_32=4 +dport_map_port_40=5 +dport_map_port_44=6 +dport_map_port_48=7 +dport_map_port_52=8 +dport_map_port_1=9 +dport_map_port_5=10 +dport_map_port_9=11 +dport_map_port_13=12 +dport_map_port_60=13 +dport_map_port_64=14 +dport_map_port_68=15 +dport_map_port_72=16 +dport_map_port_80=17 +dport_map_port_84=18 +dport_map_port_88=19 +dport_map_port_92=20 +dport_map_port_140=21 +dport_map_port_144=22 +dport_map_port_148=23 +dport_map_port_152=24 +dport_map_port_100=25 +dport_map_port_104=26 +dport_map_port_108=27 +dport_map_port_112=28 +dport_map_port_120=29 +dport_map_port_124=30 +dport_map_port_128=31 +dport_map_port_132=32 + +#dport_map_port_38=33 +#dport_map_port_118=34 + + + +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 + +#firmware load method, use fast load +load_firmware=0x2 + + diff --git a/device/celestica/x86_64-cel_silverstone-r0/custom.bin b/device/celestica/x86_64-cel_silverstone-r0/custom.bin new file mode 100644 index 0000000000000000000000000000000000000000..a08ba6c06661ed90e3aa17c0239615b96259b509 GIT binary patch literal 1216 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 literal 0 HcmV?d00001 diff --git a/device/celestica/x86_64-cel_silverstone-r0/plugins/eeprom.py b/device/celestica/x86_64-cel_silverstone-r0/plugins/eeprom.py new file mode 100644 index 000000000000..34c50a6ce31f --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/plugins/eeprom.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica Silverstone +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) + diff --git a/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py new file mode 100644 index 000000000000..d5e197e82d2b --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python + +import os.path +import subprocess +import sys +import re + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + self.ipmi_raw = "docker exec -ti pmon ipmitool raw 0x4 0x2d" + self.psu1_id = "0x2f" + self.psu2_id = "0x39" + PsuBase.__init__(self) + + def run_command(self, command): + proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + (out, err) = proc.communicate() + + if proc.returncode != 0: + sys.exit(proc.returncode) + + return out + + def find_value(self, in_string): + result = re.search("^.+ ([0-9a-f]{2}) .+$", in_string) + if result: + return result.group(1) + else: + return result + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + psu_id = self.psu1_id if index == 1 else self.psu2_id + res_string = self.run_command(self.ipmi_raw + ' ' + psu_id) + status_byte = self.find_value(res_string) + + if status_byte is None: + return False + + failure_detected = (int(status_byte, 16) >> 1) & 1 + input_lost = (int(status_byte, 16) >> 3) & 1 + if failure_detected or input_lost: + return False + else: + return True + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + psu_id = self.psu1_id if index == 1 else self.psu2_id + res_string = self.run_command(self.ipmi_raw + ' ' + psu_id) + status_byte = self.find_value(res_string) + + if status_byte is None: + return False + + presence = ( int(status_byte, 16) >> 0 ) & 1 + if presence: + return True + else: + return False \ No newline at end of file diff --git a/device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py new file mode 100755 index 000000000000..33b761b9397a --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python +# +# Platform-specific SFP transceiver interface for SONiC +# This plugin supports QSFP-DD, QSFP and SFP. + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 34 + OSFP_PORT_START = 1 + OSFP_PORT_END = 32 + SFP_PORT_START = 33 + SFP_PORT_END = 34 + + EEPROM_OFFSET = 9 + PORT_INFO_PATH = '/sys/class/silverstone_fpga' + + _port_name = "" + _port_to_eeprom_mapping = {} + _port_to_i2cbus_mapping = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return [] + + @property + def osfp_ports(self): + return range(self.OSFP_PORT_START, self.OSFP_PORT_END + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + @property + def port_to_i2cbus_mapping(self): + return self._port_to_i2cbus_mapping + + def get_port_name(self, port_num): + if port_num in self.osfp_ports: + self._port_name = "QSFP" + str(port_num - self.OSFP_PORT_START + 1) + else: + self._port_name = "SFP" + str(port_num - self.SFP_PORT_START + 1) + return self._port_name + + def get_eeprom_dom_raw(self, port_num): + if port_num in self.osfp_ports: + # QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw + return None + else: + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.DOM_EEPROM_ADDR, 256) + + def __init__(self): + # Override port_to_eeprom_mapping for class initialization + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' + + for x in range(self.PORT_START, self.PORT_END+1): + self.port_to_i2cbus_mapping[x] = (x + self.EEPROM_OFFSET) + self.port_to_eeprom_mapping[x] = eeprom_path.format( + x + self.EEPROM_OFFSET) + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num not in range(self.port_start, self.port_end + 1): + return False + + # Get path for access port presence status + port_name = self.get_port_name(port_num) + sysfs_filename = "qsfp_modprs" if port_num in self.osfp_ports else "sfp_modabs" + reg_path = "/".join([self.PORT_INFO_PATH, port_name, sysfs_filename]) + + # Read status + try: + reg_file = open(reg_path) + content = reg_file.readline().rstrip() + reg_value = int(content) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Module present is active low + if reg_value == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid QSFP port_num + if port_num not in self.osfp_ports: + return False + + try: + port_name = self.get_port_name(port_num) + reg_file = open("/".join([self.PORT_INFO_PATH, + port_name, "qsfp_lpmode"])) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Read status + content = reg_file.readline().rstrip() + reg_value = int(content) + # low power mode is active high + if reg_value == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid QSFP port_num + if port_num not in self.osfp_ports: + return False + + try: + port_name = self.get_port_name(port_num) + reg_file = open("/".join([self.PORT_INFO_PATH, + port_name, "qsfp_lpmode"]), "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = hex(lpmode) + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + def reset(self, port_num): + # Check for invalid QSFP port_num + if port_num not in self.osfp_ports: + return False + + try: + port_name = self.get_port_name(port_num) + reg_file = open("/".join([self.PORT_INFO_PATH, + port_name, "qsfp_reset"]), "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(0)) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + reg_file = open( + "/".join([self.PORT_INFO_PATH, port_name, "qsfp_reset"]), "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + reg_file.write(hex(1)) + reg_file.close() + + return True + + def get_transceiver_change_event(self, timeout=0): + """ + TBD + """ + raise NotImplementedError diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 7d50b133ac6f..3582116932b1 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -53,7 +53,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \ $(BRCM_XLR_GTS_PLATFORM_MODULE) \ $(DELTA_AG9032V2A_PLATFORM_MODULE) \ - $(JUNIPER_QFX5210_PLATFORM_MODULE) + $(JUNIPER_QFX5210_PLATFORM_MODULE) \ + $(CEL_SILVERSTONE_PLATFORM_MODULE) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index 1224faaa6750..b7371e3282de 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -2,9 +2,11 @@ CEL_DX010_PLATFORM_MODULE_VERSION = 0.9 CEL_HALIBURTON_PLATFORM_MODULE_VERSION = 0.9 +CEL_SILVERSTONE_PLATFORM_MODULE_VERSION = 0.9 export CEL_DX010_PLATFORM_MODULE_VERSION export CEL_HALIBURTON_PLATFORM_MODULE_VERSION +export CEL_SILVERSTONE_PLATFORM_MODULE_VERSION CEL_DX010_PLATFORM_MODULE = platform-modules-dx010_$(CEL_DX010_PLATFORM_MODULE_VERSION)_amd64.deb $(CEL_DX010_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cel @@ -16,4 +18,8 @@ CEL_HALIBURTON_PLATFORM_MODULE = platform-modules-haliburton_$(CEL_HALIBURTON_PL $(CEL_HALIBURTON_PLATFORM_MODULE)_PLATFORM = x86_64-cel_e1031-r0 $(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_HALIBURTON_PLATFORM_MODULE))) +CEL_SILVERSTONE_PLATFORM_MODULE = platform-modules-silverstone_$(CEL_SILVERSTONE_PLATFORM_MODULE_VERSION)_amd64.deb +$(CEL_SILVERSTONE_PLATFORM_MODULE)_PLATFORM = x86_64-cel_silverstone-r0 +$(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_SILVERSTONE_PLATFORM_MODULE))) + SONIC_STRETCH_DEBS += $(CEL_DX010_PLATFORM_MODULE) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 445189822039..2e9b578872fa 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -15,3 +15,8 @@ Package: platform-modules-haliburton Architecture: amd64 Depends: linux-image-4.9.0-9-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-silverstone +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel modules for platform devices such as led, sfp. diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init new file mode 100644 index 000000000000..c1d4c10b48fc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init @@ -0,0 +1,49 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: $portmap +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup SilverStone board. +### END INIT INFO + + +case "$1" in +start) + echo -n "Setting up board... " + + modprobe i2c-dev + modprobe baseboard-lpc + modprobe switchboard + modprobe mc24lc64t + modprobe ipmi_devintf + + # Instantiate TLV EEPROM device on I801 bus + devname=`cat /sys/bus/i2c/devices/i2c-0/name` + if [[ $devname == 'SMBus I801 adapter at '* ]]; then + echo 24lc64t 0x56 > /sys/bus/i2c/devices/i2c-0/new_device + fi + decode-syseeprom --init 2> /dev/null & + + echo "done." + ;; + +stop) + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-silverstone.init {start|stop}" + exit 1 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install new file mode 100644 index 000000000000..a3a8b3d424a1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install @@ -0,0 +1,2 @@ +silverstone/cfg/silverstone-modules.conf etc/modules-load.d +silverstone/systemd/platform-modules-silverstone.service lib/systemd/system \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst new file mode 100644 index 000000000000..771057bed0dc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst @@ -0,0 +1,3 @@ +depmod -a +systemctl enable platform-modules-silverstone.service +systemctl start platform-modules-silverstone.service \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/rules b/platform/broadcom/sonic-platform-modules-cel/debian/rules index 6f35290bce26..dd5452ccaa11 100755 --- a/platform/broadcom/sonic-platform-modules-cel/debian/rules +++ b/platform/broadcom/sonic-platform-modules-cel/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= dx010 haliburton +MODULE_DIRS:= dx010 haliburton silverstone %: dh $@ diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/cfg/silverstone-modules.conf b/platform/broadcom/sonic-platform-modules-cel/silverstone/cfg/silverstone-modules.conf new file mode 100644 index 000000000000..cb8dcf640ba3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/cfg/silverstone-modules.conf @@ -0,0 +1,15 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-pca954x +ipmi_devintf +ipmi_si \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/Makefile new file mode 100644 index 000000000000..f6ad4d9ba4d1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/Makefile @@ -0,0 +1 @@ +obj-m := baseboard-lpc.o mc24lc64t.o switchboard.o \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/baseboard-lpc.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/baseboard-lpc.c new file mode 100644 index 000000000000..b6291f7d3ce4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/baseboard-lpc.c @@ -0,0 +1,433 @@ +/* + * baseboard-lpc.c - The CPLD driver for the Base Board of Silverstone + * The driver implement sysfs to access CPLD register on the baseboard of Silverstone via LPC bus. + * Copyright (C) 2018 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "baseboard-lpc" +/** + * CPLD register address for read and write. + */ +#define VERSION_ADDR 0xA100 +#define SCRATCH_ADDR 0xA101 +#define BLT_MONTH_ADDR 0xA102 +#define BLT_DATE_ADDR 0xA103 +#define REBOOT_CAUSE 0xA106 +#define SYS_LED_ADDR 0xA162 +#define CPLD_REGISTER_SIZE 0x93 + +/* System reboot cause recorded in CPLD */ +static const struct { + const char *reason; + u8 reset_code; +} reboot_causes[] = { + {"POR", 0x11}, + {"soft-warm-rst", 0x22}, + {"soft-cold-rst", 0x33}, + {"warm-rst", 0x44}, + {"cold-rst", 0x55}, + {"wdt-rst", 0x66}, + {"power-cycle", 0x77} +}; + +struct cpld_b_data { + struct mutex cpld_lock; + uint16_t read_addr; +}; + +struct cpld_b_data *cpld_data; + +static ssize_t scratch_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SCRATCH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf,"0x%2.2x\n", data); +} + +static ssize_t scratch_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned long data; + char *last; + + mutex_lock(&cpld_data->cpld_lock); + data = (uint16_t)strtoul(buf,&last,16); + if(data == 0 && buf == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + outb(data, SCRATCH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(scratch); + + +/* CPLD version attributes */ +static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 version; + mutex_lock(&cpld_data->cpld_lock); + version = inb(VERSION_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%d.%d\n", version >> 4, version & 0x0F); +} +static DEVICE_ATTR_RO(version); + +/* CPLD version attributes */ +static ssize_t build_date_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 month, day_of_month; + mutex_lock(&cpld_data->cpld_lock); + day_of_month = inb(BLT_DATE_ADDR); + month = inb(BLT_MONTH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%x/%x\n", day_of_month, month); +} +static DEVICE_ATTR_RO(build_date); + + +static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint16_t addr; + char *last; + + addr = (uint16_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + cpld_data->read_addr = addr; + return count; +} + +static ssize_t getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len = 0; + + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n",inb(cpld_data->read_addr)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RW(getreg); + +static ssize_t setreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint16_t addr; + uint8_t value; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + + strcpy(clone, buf); + + mutex_lock(&cpld_data->cpld_lock); + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + addr = (uint16_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + value = (uint8_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + outb(value,addr); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_WO(setreg); + +/** + * Read all CPLD register in binary mode. + */ +static ssize_t dump_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + unsigned long i=0; + ssize_t status; + + mutex_lock(&cpld_data->cpld_lock); +begin: + if(i < count){ + buf[i++] = inb(VERSION_ADDR + off); + off++; + msleep(1); + goto begin; + } + status = count; + + mutex_unlock(&cpld_data->cpld_lock); + return status; +} +static BIN_ATTR_RO(dump, CPLD_REGISTER_SIZE); + +/** + * Show system led status - on/off/1hz/4hz + * @return Hex string read from scratch register. + */ +static ssize_t sys_led_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + data = data & 0x3; + return sprintf(buf, "%s\n", + data == 0x03 ? "off" : data == 0x02 ? "4hz" : data ==0x01 ? "1hz": "on"); +} + +/** + * Set the status of system led - on/off/1hz/4hz + */ +static ssize_t sys_led_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status,data; + if(sysfs_streq(buf, "off")){ + led_status = 0x03; + }else if(sysfs_streq(buf, "4hz")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "1hz")){ + led_status = 0x01; + }else if(sysfs_streq(buf, "on")){ + led_status = 0x00; + }else{ + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + data = data & ~(0x3); + data = data | led_status; + outb(data, SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(sys_led); + +/** + * Show system led color - both/green/yellow/none + * @return Current led color. + */ +static ssize_t sys_led_color_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + data = (data >> 4) & 0x3; + return sprintf(buf, "%s\n", + data == 0x03 ? "off" : data == 0x02 ? "yellow" : data ==0x01 ? "green": "both"); +} + +/** + * Set the color of system led - both/green/yellow/none + */ +static ssize_t sys_led_color_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status,data; + if(sysfs_streq(buf, "off")){ + led_status = 0x03; + }else if(sysfs_streq(buf, "yellow")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "green")){ + led_status = 0x01; + }else if(sysfs_streq(buf, "both")){ + led_status = 0x00; + }else{ + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + data = data & ~( 0x3 << 4); + data = data | (led_status << 4); + outb(data, SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(sys_led_color); + +static ssize_t reboot_cause_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t status; + u8 reg; + int i; + + mutex_lock(&cpld_data->cpld_lock); + reg = inb(REBOOT_CAUSE); + mutex_unlock(&cpld_data->cpld_lock); + + status = 0; + dev_dbg(dev,"reboot: 0x%x\n", (u8)reg); + for(i = 0; i < ARRAY_SIZE(reboot_causes); i++){ + if((u8)reg == reboot_causes[i].reset_code){ + status = sprintf(buf, "%s\n", + reboot_causes[i].reason); + break; + } + } + return status; +} +DEVICE_ATTR_RO(reboot_cause); + +static struct attribute *cpld_b_attrs[] = { + &dev_attr_version.attr, + &dev_attr_build_date.attr, + &dev_attr_scratch.attr, + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, + &dev_attr_sys_led.attr, + &dev_attr_sys_led_color.attr, + &dev_attr_reboot_cause.attr, + NULL, +}; + +static struct bin_attribute *cpld_b_bin_attrs[] = { + &bin_attr_dump, + NULL, +}; + +static struct attribute_group cpld_b_attrs_grp = { + .attrs = cpld_b_attrs, + .bin_attrs = cpld_b_bin_attrs, +}; + +static struct resource cpld_b_resources[] = { + { + .start = 0xA100, + .end = 0xA192, + .flags = IORESOURCE_IO, + }, +}; + +static void cpld_b_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device cpld_b_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(cpld_b_resources), + .resource = cpld_b_resources, + .dev = { + .release = cpld_b_dev_release, + } +}; + +static int cpld_b_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int err = 0; + + cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct cpld_b_data), + GFP_KERNEL); + if (!cpld_data) + return -ENOMEM; + + mutex_init(&cpld_data->cpld_lock); + + cpld_data->read_addr = VERSION_ADDR; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (unlikely(!res)) { + printk(KERN_ERR "Specified Resource Not Available...\n"); + return -ENODEV; + } + + err = sysfs_create_group(&pdev->dev.kobj, &cpld_b_attrs_grp); + if (err) { + printk(KERN_ERR "Cannot create sysfs for baseboard CPLD\n"); + return err; + } + return 0; +} + +static int cpld_b_drv_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &cpld_b_attrs_grp); + return 0; +} + +static struct platform_driver cpld_b_drv = { + .probe = cpld_b_drv_probe, + .remove = __exit_p(cpld_b_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +int cpld_b_init(void) +{ + // Register platform device and platform driver + platform_device_register(&cpld_b_dev); + platform_driver_register(&cpld_b_drv); + return 0; +} + +void cpld_b_exit(void) +{ + // Unregister platform device and platform driver + platform_driver_unregister(&cpld_b_drv); + platform_device_unregister(&cpld_b_dev); +} + +module_init(cpld_b_init); +module_exit(cpld_b_exit); + + +MODULE_AUTHOR("Celestica Inc."); +MODULE_DESCRIPTION("Celestica Silverstone CPLD baseboard driver"); +MODULE_VERSION("0.2.0"); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/mc24lc64t.c new file mode 100644 index 000000000000..fc15bb74b68d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/mc24lc64t.c @@ -0,0 +1,174 @@ +/* + * mc24lc64t.c - driver for Microchip 24LC64T + * + * Copyright (C) 2017 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define EEPROM_SIZE 8192 //mc24lt64t eeprom size in bytes. + +struct mc24lc64t_data { + struct mutex update_lock; +}; + +static ssize_t mc24lc64t_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, read_time, i = 0; + int status; + + mutex_lock(&drvdata->update_lock); + + if (i2c_smbus_write_byte_data(client, off>>8, off)) + { + status = -EIO; + goto exit; + } + + msleep(1); + +begin: + + if (i < count) + { + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + do { + read_time = jiffies; + + status = i2c_smbus_read_byte(client); + if (status >= 0) + { + buf[i++] = status; + goto begin; + } + } while (time_before(read_time, timeout)); + + status = -ETIMEDOUT; + goto exit; + } + + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + + return status; +} + + +static ssize_t mc24lc64t_write (struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count){ + + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, write_time, i = 0; + int status; + u16 value; + + mutex_lock(&drvdata->update_lock); + +begin: + if (i < count){ + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + value = (buf[i] << 8 | ( off &0xff)); + do { + write_time = jiffies; + status = i2c_smbus_write_word_data(client, off>>8, value); + if (status >= 0) + { + // increase offset + off++; + // increase buffer index + i++; + goto begin; + } + } while (time_before(write_time, timeout)); + status = -ETIMEDOUT; + goto exit; + } + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + return status; +} + + +static struct bin_attribute mc24lc64t_bit_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO | S_IWUGO, + }, + .size = EEPROM_SIZE, + .read = mc24lc64t_read, + .write = mc24lc64t_write, +}; + +static int mc24lc64t_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct mc24lc64t_data *drvdata; + int err; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA + | I2C_FUNC_SMBUS_READ_BYTE)) + return -EPFNOSUPPORT; + + if (!(drvdata = devm_kzalloc(&client->dev, + sizeof(struct mc24lc64t_data), GFP_KERNEL))) + return -ENOMEM; + + i2c_set_clientdata(client, drvdata); + mutex_init(&drvdata->update_lock); + + err = sysfs_create_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + return err; +} + +static int mc24lc64t_remove(struct i2c_client *client) +{ + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + sysfs_remove_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + + return 0; +} + +static const struct i2c_device_id mc24lc64t_id[] = { + { "24lc64t", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mc24lc64t_id); + +static struct i2c_driver mc24lc64t_driver = { + .driver = { + .name = "mc24lc64t", + .owner = THIS_MODULE, + }, + .probe = mc24lc64t_probe, + .remove = mc24lc64t_remove, + .id_table = mc24lc64t_id, +}; + +module_i2c_driver(mc24lc64t_driver); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_DESCRIPTION("Microchip 24LC64T Driver"); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switchboard.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switchboard.c new file mode 100644 index 000000000000..2ee6c858a8b6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switchboard.c @@ -0,0 +1,2106 @@ +/* + * switchboard.c - driver for Silverstone Switch board FPGA/CPLD. + * + * Author: Pradchaya Phucharoen + * + * Copyright (C) 2018 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * / + * \--sys + * \--devices + * \--platform + * \--silverstone + * |--FPGA + * |--CPLD1 + * |--CPLD2 + * \--SFF + * |--QSFP[1..32] + * \--SFP[1..2] + * + */ + +#ifndef TEST_MODE +#define MOD_VERSION "1.2.0" +#else +#define MOD_VERSION "TEST" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int majorNumber; + +#define CLASS_NAME "silverstone_fpga" +#define DRIVER_NAME "switchboard" +#define FPGA_PCI_NAME "Silverstone_fpga_pci" +#define DEVICE_NAME "fwupgrade" + + +static int smbus_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); + +static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); + +static int fpgafw_init(void); +static void fpgafw_exit(void); + + +/* +======================================== +FPGA PCIe BAR 0 Registers +======================================== +Misc Control 0x00000000 – 0x000000FF. +I2C_CH1 0x00000100 - 0x00000110 +I2C_CH2 0x00000200 - 0x00000210. +I2C_CH3 0x00000300 - 0x00000310. +I2C_CH4 0x00000400 - 0x00000410. +I2C_CH5 0x00000500 - 0x00000510. +I2C_CH6 0x00000600 - 0x00000610. +I2C_CH7 0x00000700 - 0x00000710. +I2C_CH8 0x00000800 - 0x00000810. +I2C_CH9 0x00000900 - 0x00000910. +I2C_CH10 0x00000A00 - 0x00000A10. +I2C_CH11 0x00000B00 - 0x00000B10. +I2C_CH12 0x00000C00 - 0x00000C10. +I2C_CH13 0x00000D00 - 0x00000D10. +SPI Master 0x00001200 - 0x00001300. +DPLL SPI Master 0x00001320 - 0x0000132F. +PORT XCVR 0x00004000 - 0x00004FFF. +*/ + +/* MISC */ +#define FPGA_VERSION 0x0000 +#define FPGA_VERSION_MJ_MSK 0xff00 +#define FPGA_VERSION_MN_MSK 0x00ff +#define FPGA_SCRATCH 0x0004 +#define FPGA_BROAD_TYPE 0x0008 +#define FPGA_BROAD_REV_MSK 0x0038 +#define FPGA_BROAD_ID_MSK 0x0007 +#define FPGA_PLL_STATUS 0x0014 +#define BMC_I2C_SCRATCH 0x0020 +#define FPGA_SLAVE_CPLD_REST 0x0030 +#define FPGA_PERIPH_RESET_CTRL 0x0034 +#define FPGA_INT_STATUS 0x0040 +#define FPGA_INT_SRC_STATUS 0x0044 +#define FPGA_INT_FLAG 0x0048 +#define FPGA_INT_MASK 0x004c +#define FPGA_MISC_CTRL 0x0050 +#define FPGA_MISC_STATUS 0x0054 +#define FPGA_AVS_VID_STATUS 0x0068 +#define FPGA_PORT_XCVR_READY 0x000c + +/* I2C_MASTER BASE ADDR */ +#define I2C_MASTER_FREQ_1 0x0100 +#define I2C_MASTER_CTRL_1 0x0104 +#define I2C_MASTER_STATUS_1 0x0108 +#define I2C_MASTER_DATA_1 0x010c +#define I2C_MASTER_PORT_ID_1 0x0110 +#define I2C_MASTER_CH_1 1 +#define I2C_MASTER_CH_2 2 +#define I2C_MASTER_CH_3 3 +#define I2C_MASTER_CH_4 4 +#define I2C_MASTER_CH_5 5 +#define I2C_MASTER_CH_6 6 +#define I2C_MASTER_CH_7 7 +#define I2C_MASTER_CH_8 8 +#define I2C_MASTER_CH_9 9 +#define I2C_MASTER_CH_10 10 +#define I2C_MASTER_CH_11 11 +#define I2C_MASTER_CH_12 12 +#define I2C_MASTER_CH_13 13 + +#define I2C_MASTER_CH_TOTAL I2C_MASTER_CH_5 + +/* SPI_MASTER */ +#define SPI_MASTER_WR_EN 0x1200 /* one bit */ +#define SPI_MASTER_WR_DATA 0x1204 /* 32 bits */ +#define SPI_MASTER_CHK_ID 0x1208 /* one bit */ +#define SPI_MASTER_VERIFY 0x120c /* one bit */ +#define SPI_MASTER_STATUS 0x1210 /* 15 bits */ +#define SPI_MASTER_MODULE_RST 0x1214 /* one bit */ + +/* FPGA FRONT PANEL PORT MGMT */ +#define SFF_PORT_CTRL_BASE 0x4000 +#define SFF_PORT_STATUS_BASE 0x4004 +#define SFF_PORT_INT_STATUS_BASE 0x4008 +#define SFF_PORT_INT_MASK_BASE 0x400c + +#define PORT_XCVR_REGISTER_SIZE 0x1000 + +/* PORT CTRL REGISTER +[31:7] RSVD +[6] LPMOD 6 +[5] RSVD +[4] RST 4 +[3:1] RSVD +[0] TXDIS 0 +*/ +#define CTRL_LPMOD 6 +#define CTRL_RST 4 +#define CTRL_TXDIS 0 + +/* PORT STATUS REGISTER +[31:6] RSVD +[5] IRQ 5 +[4] PRESENT 4 +[3] RSVD +[2] TXFAULT 2 +[1] RXLOS 1 +[0] MODABS 0 +*/ +#define STAT_IRQ 5 +#define STAT_PRESENT 4 +#define STAT_TXFAULT 2 +#define STAT_RXLOS 1 +#define STAT_MODABS 0 + +/* PORT INTRPT REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS 1 +[0] MODABS 0 +*/ +#define INTR_INT_N 5 +#define INTR_PRESENT 4 +#define INTR_TXFAULT 2 +#define INTR_RXLOS 1 +#define INTR_MODABS 0 + +/* PORT INT MASK REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS_INT 1 +[0] MODABS 0 +*/ +#define MASK_INT_N 5 +#define MASK_PRESENT 4 +#define MASK_TXFAULT 2 +#define MASK_RXLOS 1 +#define MASK_MODABS 0 + +enum { + I2C_SR_BIT_RXAK = 0, + I2C_SR_BIT_MIF, + I2C_SR_BIT_SRW, + I2C_SR_BIT_BCSTM, + I2C_SR_BIT_MAL, + I2C_SR_BIT_MBB, + I2C_SR_BIT_MAAS, + I2C_SR_BIT_MCF +}; + +enum { + I2C_CR_BIT_BCST = 0, + I2C_CR_BIT_RSTA = 2, + I2C_CR_BIT_TXAK, + I2C_CR_BIT_MTX, + I2C_CR_BIT_MSTA, + I2C_CR_BIT_MIEN, + I2C_CR_BIT_MEN, +}; + +/** + * + * The function is i2c algorithm implement to allow master access to + * correct endpoint devices trough the PCA9548 switch devices. + * + * FPGA I2C Master [mutex resource] + * | + * | + * --------------------------- + * | PCA9548(s) | + * ---1--2--3--4--5--6--7--8-- + * | | | | | | | | + * EEPROM ... EEPROM + * + */ + +#define VIRTUAL_I2C_QSFP_PORT 32 +#define VIRTUAL_I2C_SFP_PORT 2 + +#define SFF_PORT_TOTAL VIRTUAL_I2C_QSFP_PORT + VIRTUAL_I2C_SFP_PORT + +#define VIRTUAL_I2C_BUS_OFFSET 10 +#define CPLD1_SLAVE_ADDR 0x30 +#define CPLD2_SLAVE_ADDR 0x31 + +static struct class* fpgafwclass = NULL; // < The device-driver class struct pointer +static struct device* fpgafwdev = NULL; // < The device-driver device struct pointer + +#define PCI_VENDOR_ID_TEST 0x1af4 + +#ifndef PCI_VENDOR_ID_XILINX +#define PCI_VENDOR_ID_XILINX 0x10EE +#endif + +#define FPGA_PCIE_DEVICE_ID 0x7021 +#define TEST_PCIE_DEVICE_ID 0x1110 + + +#ifdef DEBUG_KERN +#define info(fmt,args...) printk(KERN_INFO "line %3d : "fmt,__LINE__,##args) +#define check(REG) printk(KERN_INFO "line %3d : %-8s = %2.2X",__LINE__,#REG,ioread8(REG)); +#else +#define info(fmt,args...) +#define check(REG) +#endif + +#define GET_REG_BIT(REG,BIT) ((ioread8(REG) >> BIT) & 0x01) +#define SET_REG_BIT_H(REG,BIT) iowrite8(ioread8(REG) | (0x01 << BIT),REG) +#define SET_REG_BIT_L(REG,BIT) iowrite8(ioread8(REG) & ~(0x01 << BIT),REG) + +static struct mutex fpga_i2c_master_locks[I2C_MASTER_CH_TOTAL]; +/* Store lasted switch address and channel */ +static uint16_t fpga_i2c_lasted_access_port[I2C_MASTER_CH_TOTAL]; + +enum PORT_TYPE { + NONE, + QSFP, + SFP +}; + +struct i2c_switch { + unsigned char master_bus; // I2C bus number + unsigned char switch_addr; // PCA9548 device address, 0xFF if directly connect to a bus. + unsigned char channel; // PCA9548 channel number. If the switch_addr is 0xFF, this value is ignored. + enum PORT_TYPE port_type; // QSFP/SFP tranceiver port type. + char calling_name[20]; // Calling name. +}; + +struct i2c_dev_data { + int portid; + struct i2c_switch pca9548; +}; + +/* PREDEFINED I2C SWITCH DEVICE TOPOLOGY */ +static struct i2c_switch fpga_i2c_bus_dev[] = { + /* BUS3 QSFP Exported as virtual bus */ + {I2C_MASTER_CH_3, 0x71, 2, QSFP, "QSFP1"}, {I2C_MASTER_CH_3, 0x71, 3, QSFP, "QSFP2"}, + {I2C_MASTER_CH_3, 0x71, 0, QSFP, "QSFP3"}, {I2C_MASTER_CH_3, 0x71, 1, QSFP, "QSFP4"}, + {I2C_MASTER_CH_3, 0x71, 6, QSFP, "QSFP5"}, {I2C_MASTER_CH_3, 0x71, 5, QSFP, "QSFP6"}, + {I2C_MASTER_CH_3, 0x73, 7, QSFP, "QSFP7"}, {I2C_MASTER_CH_3, 0x71, 4, QSFP, "QSFP8"}, + + {I2C_MASTER_CH_3, 0x73, 4, QSFP, "QSFP9"}, {I2C_MASTER_CH_3, 0x73, 3, QSFP, "QSFP10"}, + {I2C_MASTER_CH_3, 0x73, 6, QSFP, "QSFP11"}, {I2C_MASTER_CH_3, 0x73, 2, QSFP, "QSFP12"}, + {I2C_MASTER_CH_3, 0x73, 1, QSFP, "QSFP13"}, {I2C_MASTER_CH_3, 0x73, 5, QSFP, "QSFP14"}, + {I2C_MASTER_CH_3, 0x71, 7, QSFP, "QSFP15"}, {I2C_MASTER_CH_3, 0x73, 0, QSFP, "QSFP16"}, + + {I2C_MASTER_CH_3, 0x72, 1, QSFP, "QSFP17"}, {I2C_MASTER_CH_3, 0x72, 7, QSFP, "QSFP18"}, + {I2C_MASTER_CH_3, 0x72, 4, QSFP, "QSFP19"}, {I2C_MASTER_CH_3, 0x72, 0, QSFP, "QSFP20"}, + {I2C_MASTER_CH_3, 0x72, 5, QSFP, "QSFP21"}, {I2C_MASTER_CH_3, 0x72, 2, QSFP, "QSFP22"}, + {I2C_MASTER_CH_3, 0x70, 5, QSFP, "QSFP23"}, {I2C_MASTER_CH_3, 0x72, 6, QSFP, "QSFP24"}, + + {I2C_MASTER_CH_3, 0x72, 3, QSFP, "QSFP25"}, {I2C_MASTER_CH_3, 0x70, 6, QSFP, "QSFP26"}, + {I2C_MASTER_CH_3, 0x70, 0, QSFP, "QSFP27"}, {I2C_MASTER_CH_3, 0x70, 7, QSFP, "QSFP28"}, + {I2C_MASTER_CH_3, 0x70, 2, QSFP, "QSFP29"}, {I2C_MASTER_CH_3, 0x70, 4, QSFP, "QSFP30"}, + {I2C_MASTER_CH_3, 0x70, 3, QSFP, "QSFP31"}, {I2C_MASTER_CH_3, 0x70, 1, QSFP, "QSFP32"}, + /* BUS1 SFP+ Exported as virtual bus */ + {I2C_MASTER_CH_1, 0xFF, 0, SFP, "SFP1"}, + /* BUS2 SFP+ Exported as virtual bus */ + {I2C_MASTER_CH_2, 0xFF, 0, SFP, "SFP2"}, + /* BUS4 CPLD Access via I2C */ + {I2C_MASTER_CH_4, 0xFF, 0, NONE, "CPLD_S"}, + /* BUS5 CPLD_B */ + {I2C_MASTER_CH_5, 0xFF, 0, NONE, "CPLD_B"}, +}; + +#define VIRTUAL_I2C_PORT_LENGTH ARRAY_SIZE(fpga_i2c_bus_dev) +#define SW_I2C_CPLD_INDEX SFF_PORT_TOTAL + +struct fpga_device { + /* data mmio region */ + void __iomem *data_base_addr; + resource_size_t data_mmio_start; + resource_size_t data_mmio_len; +}; + +static struct fpga_device fpga_dev = { + .data_base_addr = 0, + .data_mmio_start = 0, + .data_mmio_len = 0, +}; + +struct silverstone_fpga_data { + struct device *sff_devices[SFF_PORT_TOTAL]; + struct i2c_client *sff_i2c_clients[SFF_PORT_TOTAL]; + struct i2c_adapter *i2c_adapter[VIRTUAL_I2C_PORT_LENGTH]; + struct mutex fpga_lock; // For FPGA internal lock + void __iomem * fpga_read_addr; + uint8_t cpld1_read_addr; + uint8_t cpld2_read_addr; +}; + +struct sff_device_data { + int portid; + enum PORT_TYPE port_type; +}; + +struct silverstone_fpga_data *fpga_data; + +/* + * Kernel object for other module drivers. + * Other module can use these kobject as a parent. + */ + +static struct kobject *fpga = NULL; +static struct kobject *cpld1 = NULL; +static struct kobject *cpld2 = NULL; + +/** + * Device node in sysfs tree. + */ +static struct device *sff_dev = NULL; + + +static ssize_t version_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + u32 version; + + mutex_lock(&fpga_data->fpga_lock); + version = ioread32(fpga_dev.data_base_addr + FPGA_VERSION); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d.%d\n", version >> 16, version & 0xFFFF); +} + +/** + * Show the value of the register set by 'set_fpga_reg_address' + * If the address is not set by 'set_fpga_reg_address' first, + * The version register is selected by default. + * @param buf register value in hextring + * @return number of bytes read, or an error code + */ +static ssize_t get_fpga_reg_value(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + // read data from the address + uint32_t data; + data = ioread32(fpga_data->fpga_read_addr); + return sprintf(buf, "0x%8.8x\n", data); +} +/** + * Store the register address + * @param buf address wanted to be read value of + * @return number of bytes stored, or an error code + */ +static ssize_t set_fpga_reg_address(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint32_t addr; + char *last; + + addr = (uint32_t)strtoul(buf, &last, 16); + if (addr == 0 && buf == last) { + return -EINVAL; + } + fpga_data->fpga_read_addr = fpga_dev.data_base_addr + addr; + return count; +} +/** + * Show value of fpga scratch register + * @param buf register value in hexstring + * @return number of bytes read, or an error code + */ +static ssize_t get_fpga_scratch(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + return sprintf(buf, "0x%8.8x\n", ioread32(fpga_dev.data_base_addr + FPGA_SCRATCH) & 0xffffffff); +} +/** + * Store value of fpga scratch register + * @param buf scratch register value passing from user space + * @return number of bytes stored, or an error code + */ +static ssize_t set_fpga_scratch(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint32_t data; + char *last; + data = (uint32_t)strtoul(buf, &last, 16); + if (data == 0 && buf == last) { + return -EINVAL; + } + iowrite32(data, fpga_dev.data_base_addr + FPGA_SCRATCH); + return count; +} +/** + * Store a value in a specific register address + * @param buf the value and address in format '0xhhhh 0xhhhhhhhh' + * @return number of bytes sent by user space, or an error code + */ +static ssize_t set_fpga_reg_value(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + // register are 4 bytes + uint32_t addr; + uint32_t value; + uint32_t mode = 8; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + + strcpy(clone, buf); + + mutex_lock(&fpga_data->fpga_lock); + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + addr = (uint32_t)strtoul(tok, &last, 16); + if (addr == 0 && tok == last) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + value = (uint32_t)strtoul(tok, &last, 16); + if (value == 0 && tok == last) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mode = 32; + } else { + mode = (uint32_t)strtoul(tok, &last, 10); + if (mode == 0 && tok == last) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + } + if (mode == 32) { + iowrite32(value, fpga_dev.data_base_addr + addr); + } else if (mode == 8) { + iowrite8(value, fpga_dev.data_base_addr + addr); + } else { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + mutex_unlock(&fpga_data->fpga_lock); + return count; +} + +/** + * Show FPGA port XCVR ready status + * @param buf 1 if the functin is ready, 0 if not. + * @return number of bytes read, or an error code + */ +static ssize_t ready_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + unsigned int REGISTER = FPGA_PORT_XCVR_READY; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> 0) & 1U); +} + +/* FPGA attributes */ +static DEVICE_ATTR( getreg, 0600, get_fpga_reg_value, set_fpga_reg_address); +static DEVICE_ATTR( scratch, 0600, get_fpga_scratch, set_fpga_scratch); +static DEVICE_ATTR( setreg, 0200, NULL , set_fpga_reg_value); +static DEVICE_ATTR_RO(ready); +static DEVICE_ATTR_RO(version); + +static struct attribute *fpga_attrs[] = { + &dev_attr_getreg.attr, + &dev_attr_scratch.attr, + &dev_attr_setreg.attr, + &dev_attr_ready.attr, + &dev_attr_version.attr, + NULL, +}; + +static struct attribute_group fpga_attr_grp = { + .attrs = fpga_attrs, +}; + +static ssize_t cpld1_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 version; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x00, + I2C_SMBUS_BYTE_DATA, + (union i2c_smbus_data *)&version); + if (err < 0) + return err; + return sprintf(buf, "%d.%d\n", version >> 4, version & 0x0F); +} +struct device_attribute dev_attr_cpld1_version = __ATTR(version, 0444, cpld1_version_show , NULL); + +/* SW CPLDs attributes */ +static ssize_t cpld1_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld1_read_addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + return sprintf(buf, "0x%2.2x\n", data); +} +static ssize_t cpld1_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + uint8_t addr; + char *last; + addr = (uint8_t)strtoul(buf, &last, 16); + if (addr == 0 && buf == last) { + return -EINVAL; + } + fpga_data->cpld1_read_addr = addr; + return size; +} +struct device_attribute dev_attr_cpld1_getreg = __ATTR(getreg, 0600, cpld1_getreg_show, cpld1_getreg_store); + +static ssize_t cpld1_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + __u8 data; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + return sprintf(buf, "0x%2.2x\n", data); +} +static ssize_t cpld1_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + __u8 data; + char *last; + int err; + data = (uint8_t)strtoul(buf, &last, 16); + if (data == 0 && buf == last) { + return -EINVAL; + } + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + return size; +} +struct device_attribute dev_attr_cpld1_scratch = __ATTR(scratch, 0600, cpld1_scratch_show, cpld1_scratch_store); + +static ssize_t cpld1_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + + uint8_t addr, value; + char *tok; + char clone[size]; + char *pclone = clone; + int err; + char *last; + + strcpy(clone, buf); + + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + addr = (uint8_t)strtoul(tok, &last, 16); + if (addr == 0 && tok == last) { + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + value = (uint8_t)strtoul(tok, &last, 16); + if (value == 0 && tok == last) { + return -EINVAL; + } + + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); + if (err < 0) + return err; + + return size; +} +struct device_attribute dev_attr_cpld1_setreg = __ATTR(setreg, 0200, NULL, cpld1_setreg_store); + +static struct attribute *cpld1_attrs[] = { + &dev_attr_cpld1_version.attr, + &dev_attr_cpld1_getreg.attr, + &dev_attr_cpld1_scratch.attr, + &dev_attr_cpld1_setreg.attr, + NULL, +}; + +static struct attribute_group cpld1_attr_grp = { + .attrs = cpld1_attrs, +}; + +static ssize_t cpld2_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 version; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x00, + I2C_SMBUS_BYTE_DATA, + (union i2c_smbus_data *)&version); + if (err < 0) + return err; + return sprintf(buf, "%d.%d\n", version >> 4, version & 0x0F); +} +struct device_attribute dev_attr_cpld2_version = __ATTR(version, 0444, cpld2_version_show , NULL); + +static ssize_t cpld2_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld2_read_addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld2_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + uint32_t addr; + char *last; + addr = (uint8_t)strtoul(buf, &last, 16); + if (addr == 0 && buf == last) { + return -EINVAL; + } + fpga_data->cpld2_read_addr = addr; + return size; +} +struct device_attribute dev_attr_cpld2_getreg = __ATTR(getreg, 0600, cpld2_getreg_show, cpld2_getreg_store); + +static ssize_t cpld2_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + __u8 data; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld2_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + __u8 data; + char *last; + int err; + + data = (uint8_t)strtoul(buf, &last, 16); + if (data == 0 && buf == last) { + return -EINVAL; + } + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + return size; +} +struct device_attribute dev_attr_cpld2_scratch = __ATTR(scratch, 0600, cpld2_scratch_show, cpld2_scratch_store); + +static ssize_t cpld2_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + uint8_t addr, value; + char *tok; + char clone[size]; + char *pclone = clone; + int err; + char *last; + + strcpy(clone, buf); + + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + addr = (uint8_t)strtoul(tok, &last, 16); + if (addr == 0 && tok == last) { + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + value = (uint8_t)strtoul(tok, &last, 16); + if (value == 0 && tok == last) { + return -EINVAL; + } + + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); + if (err < 0) + return err; + + return size; +} +struct device_attribute dev_attr_cpld2_setreg = __ATTR(setreg, 0200, NULL, cpld2_setreg_store); + +static struct attribute *cpld2_attrs[] = { + &dev_attr_cpld2_version.attr, + &dev_attr_cpld2_getreg.attr, + &dev_attr_cpld2_scratch.attr, + &dev_attr_cpld2_setreg.attr, + NULL, +}; + +static struct attribute_group cpld2_attr_grp = { + .attrs = cpld2_attrs, +}; + +/* QSFP/SFP+ attributes */ +static ssize_t qsfp_modirq_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_IRQ) & 1U); +} +DEVICE_ATTR_RO(qsfp_modirq); + +static ssize_t qsfp_modprs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_PRESENT) & 1U); +} +DEVICE_ATTR_RO(qsfp_modprs); + +static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_TXFAULT) & 1U); +} +DEVICE_ATTR_RO(sfp_txfault); + +static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_RXLOS) & 1U); +} +DEVICE_ATTR_RO(sfp_rxlos); + +static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_MODABS) & 1U); +} +DEVICE_ATTR_RO(sfp_modabs); + +static ssize_t qsfp_lpmode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_LPMOD) & 1U); +} +static ssize_t qsfp_lpmode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // if value is 0, disable the lpmode + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) + data = data & ~( (u32)0x1 << CTRL_LPMOD); + else + data = data | ((u32)0x1 << CTRL_LPMOD); + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_lpmode); + +static ssize_t qsfp_reset_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_RST) & 1U); +} + +static ssize_t qsfp_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // if value is 0, reset signal is low + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) + data = data & ~( (u32)0x1 << CTRL_RST); + else + data = data | ((u32)0x1 << CTRL_RST); + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_reset); + +static ssize_t sfp_txdisable_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_TXDIS) & 1U); +} +static ssize_t sfp_txdisable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) + data = data & ~( (u32)0x1 << CTRL_TXDIS); + else + data = data | ((u32)0x1 << CTRL_TXDIS); + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(sfp_txdisable); + +static struct attribute *sff_attrs[] = { + &dev_attr_qsfp_modirq.attr, + &dev_attr_qsfp_modprs.attr, + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_sfp_txfault.attr, + &dev_attr_sfp_rxlos.attr, + &dev_attr_sfp_modabs.attr, + &dev_attr_sfp_txdisable.attr, + NULL, +}; + +static struct attribute_group sff_attr_grp = { + .attrs = sff_attrs, +}; + +static const struct attribute_group *sff_attr_grps[] = { + &sff_attr_grp, + NULL +}; + + +static ssize_t port_led_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // value can be "nomal", "test" + __u8 led_mode_1, led_mode_2; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + if (err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_2); + if (err < 0) + return err; + return sprintf(buf, "%s %s\n", + led_mode_1 ? "test" : "normal", + led_mode_2 ? "test" : "normal"); +} +static ssize_t port_led_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int status; + __u8 led_mode_1; + if (sysfs_streq(buf, "test")) { + led_mode_1 = 0x01; + } else if (sysfs_streq(buf, "normal")) { + led_mode_1 = 0x00; + } else { + return -EINVAL; + } + status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + return size; +} +DEVICE_ATTR_RW(port_led_mode); + +// Only work when port_led_mode set to 1 +static ssize_t port_led_color_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // value can be R/G/B/C/M/Y/W/OFF + __u8 led_color1, led_color2; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color1); + if (err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color2); + if (err < 0) + return err; + return sprintf(buf, "%s %s\n", + led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? "red" : led_color1 == 0x04 ? + "yellow" : led_color1 == 0x03 ? "blue" : led_color1 == 0x02 ? "cyan" : led_color1 == 0x01 ? "magenta" : "white", + led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? "red" : led_color1 == 0x04 ? + "yellow" : led_color1 == 0x03 ? "blue" : led_color1 == 0x02 ? "cyan" : led_color1 == 0x01 ? "magenta" : "white"); +} + +static ssize_t port_led_color_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int status; + __u8 led_color; + if (sysfs_streq(buf, "off")) { + led_color = 0x07; + } else if (sysfs_streq(buf, "green")) { + led_color = 0x06; + } else if (sysfs_streq(buf, "red")) { + led_color = 0x05; + } else if (sysfs_streq(buf, "yellow")) { + led_color = 0x04; + } else if (sysfs_streq(buf, "blue")) { + led_color = 0x03; + } else if (sysfs_streq(buf, "cyan")) { + led_color = 0x02; + } else if (sysfs_streq(buf, "magenta")) { + led_color = 0x01; + } else if (sysfs_streq(buf, "white")) { + led_color = 0x00; + } else { + status = -EINVAL; + return status; + } + status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color); + status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color); + return size; +} +DEVICE_ATTR_RW(port_led_color); + +static struct attribute *sff_led_test[] = { + &dev_attr_port_led_mode.attr, + &dev_attr_port_led_color.attr, + NULL, +}; + +static struct attribute_group sff_led_test_grp = { + .attrs = sff_led_test, +}; + +static struct device * silverstone_sff_init(int portid) { + struct sff_device_data *new_data; + struct device *new_device; + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) { + printk(KERN_ALERT "Cannot alloc sff device data @port%d", portid); + return NULL; + } + /* The QSFP port ID start from 1 */ + new_data->portid = portid + 1; + new_data->port_type = fpga_i2c_bus_dev[portid].port_type; + new_device = device_create_with_groups(fpgafwclass, sff_dev, MKDEV(0, 0), new_data, sff_attr_grps, "%s", fpga_i2c_bus_dev[portid].calling_name); + if (IS_ERR(new_device)) { + printk(KERN_ALERT "Cannot create sff device @port%d", portid); + kfree(new_data); + return NULL; + } + return new_device; +} + +static int i2c_wait_ack(struct i2c_adapter *a, unsigned long timeout, int writing) { + int error = 0; + int Status; + + struct i2c_dev_data *new_data = i2c_get_adapdata(a); + void __iomem *pci_bar = fpga_dev.data_base_addr; + + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + unsigned int master_bus = new_data->pca9548.master_bus; + + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { + error = -EINVAL; + return error; + } + + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; + + check(pci_bar + REG_SR0); + check(pci_bar + REG_CR0); + + timeout = jiffies + msecs_to_jiffies(timeout); + while (1) { + Status = ioread8(pci_bar + REG_SR0); + if (jiffies > timeout) { + info("Status %2.2X", Status); + info("Error Timeout"); + error = -ETIMEDOUT; + break; + } + + + if (Status & (1 << I2C_SR_BIT_MIF)) { + break; + } + + if (writing == 0 && (Status & (1 << I2C_SR_BIT_MCF))) { + break; + } + } + Status = ioread8(pci_bar + REG_SR0); + iowrite8(0, pci_bar + REG_SR0); + + if (error < 0) { + info("Status %2.2X", Status); + return error; + } + + if (!(Status & (1 << I2C_SR_BIT_MCF))) { + info("Error Unfinish"); + return -EIO; + } + + if (Status & (1 << I2C_SR_BIT_MAL)) { + info("Error MAL"); + return -EAGAIN; + } + + if (Status & (1 << I2C_SR_BIT_RXAK)) { + info( "SL No Acknowlege"); + if (writing) { + info("Error No Acknowlege"); + iowrite8(1 << I2C_CR_BIT_MEN, pci_bar + REG_CR0); + return -ENXIO; + } + } else { + info( "SL Acknowlege"); + } + + return 0; +} + +static int smbus_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data) +{ + int error = 0; + int cnt = 0; + int bid = 0; + struct i2c_dev_data *dev_data; + void __iomem *pci_bar; + unsigned int portid, master_bus; + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + /* Write the command register */ + dev_data = i2c_get_adapdata(adapter); + portid = dev_data->portid; + pci_bar = fpga_dev.data_base_addr; + master_bus = dev_data->pca9548.master_bus; + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; + + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { + error = -EINVAL; + goto Done; + } + +#ifdef DEBUG_KERN + printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " + , portid, addr, flags, rw, rw == 1 ? "READ " : "WRITE" + , size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : "ERROR" + , cmd); +#endif + /* Map the size to what the chip understands */ + switch (size) { + case I2C_SMBUS_QUICK: + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_BLOCK_DATA: + break; + default: + printk(KERN_INFO "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; + } + + iowrite8(portid, pci_bar + REG_ID0); + + ////[S][ADDR/R] + //Clear status register + iowrite8(0, pci_bar + REG_SR0); + iowrite8(1 << I2C_CR_BIT_MIEN | 1 << I2C_CR_BIT_MTX | 1 << I2C_CR_BIT_MSTA , pci_bar + REG_CR0); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + + if (rw == I2C_SMBUS_READ && + (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)) { + // sent device address with Read mode + iowrite8(addr << 1 | 0x01, pci_bar + REG_DR0); + } else { + // sent device address with Write mode + iowrite8(addr << 1 | 0x00, pci_bar + REG_DR0); + } + + + + info( "MS Start"); + + //// Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; + } + + //// [CMD]{A} + if (size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)) { + + //sent command code to data register + iowrite8(cmd, pci_bar + REG_DR0); + info( "MS Send CMD 0x%2.2X", cmd); + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; + } + } + + switch (size) { + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + // in block data mode keep number of byte in block[0] + cnt = data->block[0]; + break; + default: + cnt = 0; break; + } + + // [CNT] used only bloack data write + if (size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE) { + + iowrite8(cnt, pci_bar + REG_DR0); + info( "MS Send CNT 0x%2.2X", cnt); + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; + } + } + + // [DATA]{A} + if ( rw == I2C_SMBUS_WRITE && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA + )) { + int bid = 0; + info( "MS prepare to sent [%d bytes]", cnt); + if (size == I2C_SMBUS_BLOCK_DATA ) { + bid = 1; // block[0] is cnt; + cnt += 1; // offset from block[0] + } + for (; bid < cnt; bid++) { + + iowrite8(data->block[bid], pci_bar + REG_DR0); + info( " Data > %2.2X", data->block[bid]); + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + goto Done; + } + } + } + + //REPEATE START + if ( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA + )) { + info( "MS Repeated Start"); + + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + iowrite8(1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MTX | + 1 << I2C_CR_BIT_MSTA | + 1 << I2C_CR_BIT_RSTA , pci_bar + REG_CR0); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + + // sent Address with Read mode + iowrite8( addr << 1 | 0x1 , pci_bar + REG_DR0); + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + goto Done; + } + + } + + if ( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA + )) { + + switch (size) { + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + //will be changed after recived first data + cnt = 3; break; + default: + cnt = 0; break; + } + + info( "MS Receive"); + + //set to Receive mode + iowrite8(1 << I2C_CR_BIT_MEN | + 1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MSTA , pci_bar + REG_CR0); + + for (bid = -1; bid < cnt; bid++) { + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 0); + if (error < 0) { + goto Done; + } + + if (bid == cnt - 2) { + info( "SET NAK"); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_TXAK); + } + + if (bid < 0) { + ioread8(pci_bar + REG_DR0); + info( "READ Dummy Byte" ); + } else { + + if (bid == cnt - 1) { + info ( "SET STOP in read loop"); + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); + } + data->block[bid] = ioread8(pci_bar + REG_DR0); + + info( "DATA IN [%d] %2.2X", bid, data->block[bid]); + + if (size == I2C_SMBUS_BLOCK_DATA && bid == 0) { + cnt = data->block[0] + 1; + } + } + } + } + + //[P] + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); + i2c_wait_ack(adapter, 12, 0); + info( "MS STOP"); + +Done: + iowrite8(1 << I2C_CR_BIT_MEN, pci_bar + REG_CR0); + check(pci_bar + REG_CR0); + check(pci_bar + REG_SR0); +#ifdef DEBUG_KERN + printk(KERN_INFO "END --- Error code %d", error); +#endif + + return error; +} + +/** + * Wrapper of smbus_access access with PCA9548 I2C switch management. + * This function set PCA9548 switches to the proper slave channel. + * Only one channel among switches chip is selected during communication time. + * + * Note: If the bus does not have any PCA9548 on it, the switch_addr must be + * set to 0xFF, it will use normal smbus_access function. + */ +static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data) +{ + int error = 0; + struct i2c_dev_data *dev_data; + unsigned char master_bus; + unsigned char switch_addr; + unsigned char channel; + uint16_t prev_port = 0; + unsigned char prev_switch; + unsigned char prev_ch; + int retry; + + dev_data = i2c_get_adapdata(adapter); + master_bus = dev_data->pca9548.master_bus; + switch_addr = dev_data->pca9548.switch_addr; + channel = dev_data->pca9548.channel; + + // Acquire the master resource. + mutex_lock(&fpga_i2c_master_locks[master_bus - 1]); + prev_port = fpga_i2c_lasted_access_port[master_bus - 1]; + prev_switch = (unsigned char)(prev_port >> 8) & 0xFF; + prev_ch = (unsigned char)(prev_port & 0xFF); + + if (switch_addr != 0xFF) { + + // Check lasted access switch address on a master + if ( prev_switch != switch_addr && prev_switch != 0 ) { + // reset prev_port PCA9548 chip + retry = 3; + while(retry--){ + error = smbus_access(adapter, (u16)(prev_switch), flags, I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); + if(error >= 0){ + break; + }else{ + dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); + } + } + if(retry == 0) + goto release_unlock; + // set PCA9548 to current channel + retry = 3; + while(retry--){ + error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); + if(error >= 0){ + break; + }else{ + dev_dbg(&adapter->dev,"Failed to select ch %d of 0x%x, CODE %d\n", channel, switch_addr, error); + } + } + if(retry == 0) + goto release_unlock; + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + + } else { + // check if channel is also changes + if ( prev_ch != channel || prev_switch == 0 ) { + // set new PCA9548 at switch_addr to current + retry = 3; + while(retry--){ + error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); + if(error >= 0){ + break; + }else{ + dev_dbg(&adapter->dev,"Failed to select ch %d of 0x%x, CODE %d\n", channel, switch_addr, error); + } + } + if(retry == 0) + goto release_unlock; + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + } + } + } + + // Do SMBus communication + error = smbus_access(adapter, addr, flags, rw, cmd, size, data); + if(error < 0){ + dev_dbg( &adapter->dev,"smbus_xfer failed (%d) @ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " + , error, addr, flags, rw, rw == 1 ? "READ " : "WRITE" + , size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + , cmd); + } + +release_unlock: + mutex_unlock(&fpga_i2c_master_locks[master_bus - 1]); + dev_dbg(&adapter->dev,"switch ch %d of 0x%x -> ch %d of 0x%x\n", prev_ch, prev_switch, channel, switch_addr); + return error; +} + + + +/** + * A callback function show available smbus functions. + */ +static u32 fpga_i2c_func(struct i2c_adapter *a) +{ + return I2C_FUNC_SMBUS_QUICK | + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static const struct i2c_algorithm silverstone_i2c_algorithm = { + .smbus_xfer = fpga_i2c_access, + .functionality = fpga_i2c_func, +}; + +/** + * Create virtual I2C bus adapter for switch devices + * @param pdev platform device pointer + * @param portid virtual i2c port id for switch device mapping + * @param bus_number_offset bus offset for virtual i2c adapter in system + * @return i2c adapter. + * + * When bus_number_offset is -1, created adapter with dynamic bus number. + * Otherwise create adapter at i2c bus = bus_number_offset + portid. + */ +static struct i2c_adapter * silverstone_i2c_init(struct platform_device *pdev, int portid, int bus_number_offset) +{ + int error; + + struct i2c_adapter *new_adapter; + struct i2c_dev_data *new_data; + void __iomem *i2c_freq_base_reg; + + new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL); + if (!new_adapter) { + printk(KERN_ALERT "Cannot alloc i2c adapter for %s", fpga_i2c_bus_dev[portid].calling_name); + return NULL; + } + + new_adapter->owner = THIS_MODULE; + new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + new_adapter->algo = &silverstone_i2c_algorithm; + /* If the bus offset is -1, use dynamic bus number */ + if (bus_number_offset == -1) { + new_adapter->nr = -1; + } else { + new_adapter->nr = bus_number_offset + portid; + } + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) { + printk(KERN_ALERT "Cannot alloc i2c data for %s", fpga_i2c_bus_dev[portid].calling_name); + kzfree(new_adapter); + return NULL; + } + + new_data->portid = portid; + new_data->pca9548.master_bus = fpga_i2c_bus_dev[portid].master_bus; + new_data->pca9548.switch_addr = fpga_i2c_bus_dev[portid].switch_addr; + new_data->pca9548.channel = fpga_i2c_bus_dev[portid].channel; + strcpy(new_data->pca9548.calling_name, fpga_i2c_bus_dev[portid].calling_name); + + snprintf(new_adapter->name, sizeof(new_adapter->name), + "SMBus I2C Adapter PortID: %s", new_data->pca9548.calling_name); + + i2c_freq_base_reg = fpga_dev.data_base_addr + I2C_MASTER_FREQ_1; + iowrite8(0x07, i2c_freq_base_reg + (new_data->pca9548.master_bus - 1) * 0x100); // 0x07 400kHz + i2c_set_adapdata(new_adapter, new_data); + error = i2c_add_numbered_adapter(new_adapter); + if (error < 0) { + printk(KERN_ALERT "Cannot add i2c adapter %s", new_data->pca9548.calling_name); + kzfree(new_adapter); + kzfree(new_data); + return NULL; + } + + return new_adapter; +}; + +static void silverstone_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device silverstone_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = 0, + .resource = NULL, + .dev = { + .release = silverstone_dev_release, + } +}; + +/** + * Board info for QSFP/SFP+ eeprom. + * Note: Using OOM optoe as I2C eeprom driver. + * https://www.opencompute.org/wiki/Networking/SpecsAndDesigns#Open_Optical_Monitoring + */ +static struct i2c_board_info sff8436_eeprom_info[] = { + { I2C_BOARD_INFO("optoe1", 0x50) }, //For QSFP w/ sff8436 + { I2C_BOARD_INFO("optoe2", 0x50) }, //For SFP+ w/ sff8472 +}; + +static int silverstone_drv_probe(struct platform_device *pdev) +{ + int ret = 0; + int portid_count; + uint8_t cpld1_version, cpld2_version; + uint16_t prev_i2c_switch = 0; + struct sff_device_data *sff_data; + + /* The device class need to be instantiated before this function called */ + BUG_ON(fpgafwclass == NULL); + + fpga_data = devm_kzalloc(&pdev->dev, sizeof(struct silverstone_fpga_data), + GFP_KERNEL); + + if (!fpga_data) + return -ENOMEM; + + // Set default read address to VERSION + fpga_data->fpga_read_addr = fpga_dev.data_base_addr + FPGA_VERSION; + fpga_data->cpld1_read_addr = 0x00; + fpga_data->cpld2_read_addr = 0x00; + + mutex_init(&fpga_data->fpga_lock); + for (ret = I2C_MASTER_CH_1 ; ret <= I2C_MASTER_CH_TOTAL; ret++) { + mutex_init(&fpga_i2c_master_locks[ret - 1]); + } + + fpga = kobject_create_and_add("FPGA", &pdev->dev.kobj); + if (!fpga) { + kzfree(fpga_data); + return -ENOMEM; + } + + ret = sysfs_create_group(fpga, &fpga_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create FPGA sysfs attributes\n"); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + cpld1 = kobject_create_and_add("CPLD1", &pdev->dev.kobj); + if (!cpld1) { + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return -ENOMEM; + } + ret = sysfs_create_group(cpld1, &cpld1_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD1 sysfs attributes\n"); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + cpld2 = kobject_create_and_add("CPLD2", &pdev->dev.kobj); + if (!cpld2) { + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return -ENOMEM; + } + ret = sysfs_create_group(cpld2, &cpld2_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD2 sysfs attributes\n"); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + sff_dev = device_create(fpgafwclass, NULL, MKDEV(0, 0), NULL, "sff_device"); + if (IS_ERR(sff_dev)) { + printk(KERN_ERR "Failed to create sff device\n"); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return PTR_ERR(sff_dev); + } + + ret = sysfs_create_group(&sff_dev->kobj, &sff_led_test_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create SFF attributes\n"); + device_destroy(fpgafwclass, MKDEV(0, 0)); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + ret = sysfs_create_link(&pdev->dev.kobj, &sff_dev->kobj, "SFF"); + if (ret != 0) { + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + device_destroy(fpgafwclass, MKDEV(0, 0)); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { + fpga_data->i2c_adapter[portid_count] = silverstone_i2c_init(pdev, portid_count, VIRTUAL_I2C_BUS_OFFSET); + } + + /* Init SFF devices */ + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + struct i2c_adapter *i2c_adap = fpga_data->i2c_adapter[portid_count]; + if (i2c_adap) { + fpga_data->sff_devices[portid_count] = silverstone_sff_init(portid_count); + sff_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); + BUG_ON(sff_data == NULL); + if ( sff_data->port_type == QSFP ) { + fpga_data->sff_i2c_clients[portid_count] = i2c_new_device(i2c_adap, &sff8436_eeprom_info[0]); + } else { + fpga_data->sff_i2c_clients[portid_count] = i2c_new_device(i2c_adap, &sff8436_eeprom_info[1]); + } + sff_data = NULL; + sysfs_create_link(&fpga_data->sff_devices[portid_count]->kobj, + &fpga_data->sff_i2c_clients[portid_count]->dev.kobj, + "i2c"); + } + } + +#ifdef TEST_MODE + return 0; +#endif + fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld1_version); + fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld2_version); + + printk(KERN_INFO "Switch CPLD1 VERSION: %2.2x\n", cpld1_version); + printk(KERN_INFO "Switch CPLD2 VERSION: %2.2x\n", cpld2_version); + + + /* Init I2C buses that has PCA9548 switch device. */ + for (portid_count = 0; portid_count < VIRTUAL_I2C_PORT_LENGTH; portid_count++) { + + struct i2c_dev_data *dev_data; + unsigned char master_bus; + unsigned char switch_addr; + + dev_data = i2c_get_adapdata(fpga_data->i2c_adapter[portid_count]); + master_bus = dev_data->pca9548.master_bus; + switch_addr = dev_data->pca9548.switch_addr; + + if (switch_addr != 0xFF) { + + if (prev_i2c_switch != ( (master_bus << 8) | switch_addr) ) { + // Found the bus with PCA9548, trying to clear all switch in it. + smbus_access(fpga_data->i2c_adapter[portid_count], switch_addr, 0x00, I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); + prev_i2c_switch = ( master_bus << 8 ) | switch_addr; + } + } + } + return 0; +} + +static int silverstone_drv_remove(struct platform_device *pdev) +{ + int portid_count; + struct sff_device_data *rem_data; + + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + sysfs_remove_link(&fpga_data->sff_devices[portid_count]->kobj, "i2c"); + i2c_unregister_device(fpga_data->sff_i2c_clients[portid_count]); + } + + for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { + if (fpga_data->i2c_adapter[portid_count] != NULL) { + info(KERN_INFO "<%x>", fpga_data->i2c_adapter[portid_count]); + i2c_del_adapter(fpga_data->i2c_adapter[portid_count]); + } + } + + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + if (fpga_data->sff_devices[portid_count] != NULL) { + rem_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); + device_unregister(fpga_data->sff_devices[portid_count]); + put_device(fpga_data->sff_devices[portid_count]); + kfree(rem_data); + } + } + + sysfs_remove_group(fpga, &fpga_attr_grp); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + kobject_put(fpga); + kobject_put(cpld1); + kobject_put(cpld2); + device_destroy(fpgafwclass, MKDEV(0, 0)); + devm_kfree(&pdev->dev, fpga_data); + return 0; +} + +#ifdef TEST_MODE +#define FPGA_PCI_BAR_NUM 2 +#else +#define FPGA_PCI_BAR_NUM 0 +#endif + +static struct platform_driver silverstone_drv = { + .probe = silverstone_drv_probe, + .remove = __exit_p(silverstone_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +static const struct pci_device_id fpga_id_table[] = { + { PCI_VDEVICE(XILINX, FPGA_PCIE_DEVICE_ID) }, + { PCI_VDEVICE(TEST, TEST_PCIE_DEVICE_ID) }, + {0, } +}; + +MODULE_DEVICE_TABLE(pci, fpga_id_table); + +static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int err; + struct device *dev = &pdev->dev; + uint32_t fpga_version; + + if ((err = pci_enable_device(pdev))) { + dev_err(dev, "pci_enable_device probe error %d for device %s\n", + err, pci_name(pdev)); + return err; + } + + if ((err = pci_request_regions(pdev, FPGA_PCI_NAME)) < 0) { + dev_err(dev, "pci_request_regions error %d\n", err); + goto pci_disable; + } + + /* bar0: data mmio region */ + fpga_dev.data_mmio_start = pci_resource_start(pdev, FPGA_PCI_BAR_NUM); + fpga_dev.data_mmio_len = pci_resource_len(pdev, FPGA_PCI_BAR_NUM); + fpga_dev.data_base_addr = pci_iomap(pdev, FPGA_PCI_BAR_NUM, 0); + if (!fpga_dev.data_base_addr) { + dev_err(dev, "cannot iomap region of size %lu\n", + (unsigned long)fpga_dev.data_mmio_len); + goto pci_release; + } + dev_info(dev, "data_mmio iomap base = 0x%lx \n", + (unsigned long)fpga_dev.data_base_addr); + dev_info(dev, "data_mmio_start = 0x%lx data_mmio_len = %lu\n", + (unsigned long)fpga_dev.data_mmio_start, + (unsigned long)fpga_dev.data_mmio_len); + + printk(KERN_INFO "FPGA PCIe driver probe OK.\n"); + printk(KERN_INFO "FPGA ioremap registers of size %lu\n", (unsigned long)fpga_dev.data_mmio_len); + printk(KERN_INFO "FPGA Virtual BAR %d at %8.8lx - %8.8lx\n", FPGA_PCI_BAR_NUM, + (unsigned long)fpga_dev.data_base_addr, + (unsigned long)(fpga_dev.data_base_addr + fpga_dev.data_mmio_len)); + printk(KERN_INFO ""); + fpga_version = ioread32(fpga_dev.data_base_addr); + printk(KERN_INFO "FPGA VERSION : %8.8x\n", fpga_version); + fpgafw_init(); + platform_device_register(&silverstone_dev); + platform_driver_register(&silverstone_drv); + return 0; + +pci_release: + pci_release_regions(pdev); +pci_disable: + pci_disable_device(pdev); + return -EBUSY; +} + +static void fpga_pci_remove(struct pci_dev *pdev) +{ + platform_driver_unregister(&silverstone_drv); + platform_device_unregister(&silverstone_dev); + fpgafw_exit(); + pci_iounmap(pdev, fpga_dev.data_base_addr); + pci_release_regions(pdev); + pci_disable_device(pdev); + printk(KERN_INFO "FPGA PCIe driver remove OK.\n"); +}; + +static struct pci_driver pci_dev_ops = { + .name = FPGA_PCI_NAME, + .probe = fpga_pci_probe, + .remove = fpga_pci_remove, + .id_table = fpga_id_table, +}; + +enum { + READREG, + WRITEREG +}; + +struct fpga_reg_data { + uint32_t addr; + uint32_t value; +}; + +static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + int ret = 0; + struct fpga_reg_data data; + mutex_lock(&fpga_data->fpga_lock); + +#ifdef TEST_MODE + static uint32_t status_reg; +#endif + // Switch function to read and write. + switch (cmd) { + case READREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + data.value = ioread32(fpga_dev.data_base_addr + data.addr); + if (copy_to_user((void __user*)arg , &data, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } +#ifdef TEST_MODE + if (data.addr == 0x1210) { + switch (status_reg) { + case 0x0000 : status_reg = 0x8000; + break; + + case 0x8080 : status_reg = 0x80C0; + break; + case 0x80C0 : status_reg = 0x80F0; + break; + case 0x80F0 : status_reg = 0x80F8; + break; + + } + iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); + } +#endif + + + break; + case WRITEREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + iowrite32(data.value, fpga_dev.data_base_addr + data.addr); + +#ifdef TEST_MODE + if (data.addr == 0x1204) { + status_reg = 0x8080; + iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); + } +#endif + + break; + default: + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + mutex_unlock(&fpga_data->fpga_lock); + return ret; +} + + +const struct file_operations fpgafw_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = fpgafw_unlocked_ioctl, +}; + + +static int fpgafw_init(void) { + printk(KERN_INFO "Initializing the switchboard driver\n"); + // Try to dynamically allocate a major number for the device -- more difficult but worth it + majorNumber = register_chrdev(0, DEVICE_NAME, &fpgafw_fops); + if (majorNumber < 0) { + printk(KERN_ALERT "Failed to register a major number\n"); + return majorNumber; + } + printk(KERN_INFO "Device registered correctly with major number %d\n", majorNumber); + + // Register the device class + fpgafwclass = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(fpgafwclass)) { // Check for error and clean up if there is + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to register device class\n"); + return PTR_ERR(fpgafwclass); + } + printk(KERN_INFO "Device class registered correctly\n"); + + // Register the device driver + fpgafwdev = device_create(fpgafwclass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME); + if (IS_ERR(fpgafwdev)) { // Clean up if there is an error + class_destroy(fpgafwclass); // Repeated code but the alternative is goto statements + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to create the FW upgrade device node\n"); + return PTR_ERR(fpgafwdev); + } + printk(KERN_INFO "FPGA fw upgrade device node created correctly\n"); + return 0; +} + +static void fpgafw_exit(void) { + device_destroy(fpgafwclass, MKDEV(majorNumber, 0)); // remove the device + class_unregister(fpgafwclass); // unregister the device class + class_destroy(fpgafwclass); // remove the device class + unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number + printk(KERN_INFO "Goodbye!\n"); +} + +int silverstone_init(void) +{ + int rc; + rc = pci_register_driver(&pci_dev_ops); + if (rc) + return rc; + return 0; +} + +void silverstone_exit(void) +{ + pci_unregister_driver(&pci_dev_ops); +} + +module_init(silverstone_init); +module_exit(silverstone_exit); + +MODULE_AUTHOR("Celestica Inc."); +MODULE_DESCRIPTION("Celestica Silverstone platform driver"); +MODULE_VERSION(MOD_VERSION); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/systemd/platform-modules-silverstone.service b/platform/broadcom/sonic-platform-modules-cel/silverstone/systemd/platform-modules-silverstone.service new file mode 100644 index 000000000000..907764153a27 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/systemd/platform-modules-silverstone.service @@ -0,0 +1,13 @@ +[Unit] +Description=Celestica Silverstone platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-silverstone start +ExecStop=-/etc/init.d/platform-modules-silverstone stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target \ No newline at end of file From 150ed36be2dd5c11e69934c78983c48e984afa8e Mon Sep 17 00:00:00 2001 From: kannankvs Date: Thu, 10 Oct 2019 21:54:18 +0530 Subject: [PATCH 0057/1427] [snmp]: changes to handle snmp configuration as per the modified CLI (#3586) While doing CLI changes for SNMP configuration, few changes are made in backend to handle the modified CLI. ** Changes** - "community" for "snmp trap" is also made as "configurable". snmpd_conf.j2 is modified to handle the same. - Changed the snmp.yml file generation from postStartAction to preStartAction in docker_image_ctl.j2 specific to SNMP docker, to ensure that the snmp.yml is generated before sonic-cfggen generates the snmpd.conf. - Changed to make the code common for management vrf and default vrf. Users can configure snmp trap and snmp listening IP for both management vrf and default vrf. --- dockers/docker-snmp-sv2/snmpd.conf.j2 | 6 +- files/build_templates/docker_image_ctl.j2 | 108 ++++++++++++++-------- 2 files changed, 72 insertions(+), 42 deletions(-) diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp-sv2/snmpd.conf.j2 index 9784cc42e7f7..16d7e5bff79c 100644 --- a/dockers/docker-snmp-sv2/snmpd.conf.j2 +++ b/dockers/docker-snmp-sv2/snmpd.conf.j2 @@ -106,19 +106,19 @@ load 12 10 5 # # send SNMPv1 traps {%if v1_trap_dest and v1_trap_dest != 'NotConfigured' %} -trapsink {{ v1_trap_dest }} public +trapsink {{ v1_trap_dest }} {% else %} #trapsink localhost public {% endif %} # send SNMPv2c traps {%if v2_trap_dest and v2_trap_dest != 'NotConfigured' %} -trap2sink {{ v2_trap_dest }} public +trap2sink {{ v2_trap_dest }} {% else %} #trap2sink localhost public {% endif %} # send SNMPv2c INFORMs {%if v3_trap_dest and v3_trap_dest != 'NotConfigured' %} -informsink {{ v3_trap_dest }} public +informsink {{ v3_trap_dest }} {% else %} #informsink localhost public {% endif %} diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 8bf0f2c6d4b0..c485254647b8 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -62,6 +62,75 @@ function preStartAction() echo -n > /tmp/dump.rdb docker cp /tmp/dump.rdb database:/var/lib/redis/ fi +{%- elif docker_container_name == "snmp" %} + docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + vrfenabled=`/usr/bin/redis-cli -n 4 hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` + v1SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` + v1SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` + v1Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` + v1Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` + v2SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` + v2SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` + v2Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` + v2Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` + v3SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` + v3SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` + v3Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` + v3Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` + + if [ "${v1SnmpTrapIp}" != "" ] + then + if [ "${v1Vrf}" != "None" ] + then + sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort}%${v1Vrf} ${v1Comm}/" "/etc/sonic/snmp.yml" + else + sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort} ${v1Comm}/" "/etc/sonic/snmp.yml" + fi + else + sed -i "s/v1_trap_dest:.*/v1_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" + fi + if [ "${v2SnmpTrapIp}" != "" ] + then + if [ "${v2Vrf}" != "None" ] + then + sed -i "s/v2_trap_dest:.*/v2_trap_dest: ${v2SnmpTrapIp}:${v2SnmpTrapPort}%${v2Vrf} ${v2Comm}/" "/etc/sonic/snmp.yml" + else + sed -i "s/v2_trap_dest:.*/v2_trap_dest: ${v2SnmpTrapIp}:${v2SnmpTrapPort} ${v2Comm}/" "/etc/sonic/snmp.yml" + fi + else + sed -i "s/v2_trap_dest:.*/v2_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" + fi + if [ "${v3SnmpTrapIp}" != "" ] + then + if [ "${v3Vrf}" != "None" ] + then + sed -i "s/v3_trap_dest:.*/v3_trap_dest: ${v3SnmpTrapIp}:${v3SnmpTrapPort}%${v3Vrf} ${v3Comm}/" "/etc/sonic/snmp.yml" + else + sed -i "s/v3_trap_dest:.*/v3_trap_dest: ${v3SnmpTrapIp}:${v3SnmpTrapPort} ${v3Comm}/" "/etc/sonic/snmp.yml" + fi + else + sed -i "s/v3_trap_dest:.*/v3_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" + fi + + echo -n "" > /tmp/snmpagentaddr.yml + keys=`/usr/bin/redis-cli -n 4 keys "SNMP_AGENT_ADDRESS_CONFIG|*"` + count=1 + for key in $keys;do + ip=`echo $key|cut -d "|" -f2` + echo -n "snmp_agent_address_$count: $ip" >> /tmp/snmpagentaddr.yml + port=`echo $key|cut -d "|" -f3` + if [ -n "$port" ]; then + echo -n ":$port" >> /tmp/snmpagentaddr.yml + fi + vrf=`echo $key|cut -d "|" -f4` + if [ -n "$vrf" ]; then + echo -n "%$vrf" >> /tmp/snmpagentaddr.yml + fi + echo "" >> /tmp/snmpagentaddr.yml + count=$((count+1)) + done + sed -i '/snmp_agent_address_*/d' /etc/sonic/snmp.yml + cat /tmp/snmpagentaddr.yml >> /etc/sonic/snmp.yml {%- else %} : # nothing {%- endif %} @@ -107,45 +176,6 @@ function postStartAction() docker cp $PSENSOR pmon:/usr/bin/ fi fi -{%- elif docker_container_name == "snmp" %} - docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) - vrfenabled=`/usr/bin/redis-cli -n 4 hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` - v1SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` - v1SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` - v1MgmtVrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` - v2SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` - v2SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` - v2MgmtVrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` - v3SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` - v3SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` - v3MgmtVrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` - - if [ "${v1SnmpTrapIp}" != "" ] - then - sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort}%${v1MgmtVrf}/" "/etc/sonic/snmp.yml" - fi - if [ "${v2SnmpTrapIp}" != "" ] - then - sed -i "s/v2_trap_dest:.*/v2_trap_dest: ${v2SnmpTrapIp}:${v2SnmpTrapPort}%${v2MgmtVrf}/" "/etc/sonic/snmp.yml" - fi - if [ "${v3SnmpTrapIp}" != "" ] - then - sed -i "s/v3_trap_dest:.*/v3_trap_dest: ${v3SnmpTrapIp}:${v3SnmpTrapPort}%${v3MgmtVrf}/" "/etc/sonic/snmp.yml" - fi - - if [ "${vrfenabled}" == "true" ] - then - keys=`/usr/bin/redis-cli -n 4 keys "SNMP_AGENT_ADDRESS_CONFIG|*"` - count=1 - for key in $keys;do - ip=`echo $key|cut -d "|" -f2` - vrf=`echo $key|cut -d "|" -f3` - echo "snmp_agent_address_$count: $ip%$vrf" >> /tmp/snmpagentaddr.yml - count=$((count+1)) - done - sed -i '/snmp_agent_address_*/d' /etc/sonic/snmp.yml - cat /tmp/snmpagentaddr.yml >> /etc/sonic/snmp.yml - fi {%- else %} : # nothing {%- endif %} From 2694e66074efd5661ef4dbdd50beec6a6bbc96ef Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Fri, 11 Oct 2019 03:41:26 +0530 Subject: [PATCH 0058/1427] [build]: build ARM kernel support from sonic-linux-kernel (#3556) * Makefile: ARM kernel support from sonic-linux-kernel * Fix for multiarch build docker spawn Platform: Install the DTB deb for the platform Signed-off-by: Antony Rheneus --- Makefile.work | 4 +++- build_debian.sh | 7 +------ platform/marvell-armhf/linux-kernel-armhf.mk | 13 +++++-------- platform/marvell-armhf/linux/Makefile | 6 +++--- platform/marvell-armhf/platform.conf | 2 +- rules/linux-kernel.mk | 4 ++++ sonic-slave-stretch/Dockerfile.j2 | 3 +++ 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/Makefile.work b/Makefile.work index cc433ca98e0c..e18cabeda9ca 100644 --- a/Makefile.work +++ b/Makefile.work @@ -126,7 +126,7 @@ ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) DOCKER_MULTIARCH_CHECK := docker inspect --type image multiarch/qemu-user-static:register &> /dev/null || (echo "multiarch docker not found ..."; docker run --rm --privileged multiarch/qemu-user-static:register --reset --credential yes) - DOCKER_SERVICE_MULTIARCH_CHECK := docker -H unix:///var/run/march/docker.sock info &> /dev/null || (echo "Docker march service not running..."; sudo rm -fr /var/run/march/*; (sudo $(SONIC_NATIVE_DOCKERD_FOR_MUTLIARCH) &) &>/dev/null ; sleep 1; sudo $(SONIC_USERFACL_DOCKERD_FOR_MUTLIARCH);) + DOCKER_SERVICE_MULTIARCH_CHECK := docker -H unix:///var/run/march/docker.sock info &> /dev/null || (echo "Docker march service not running..."; sudo rm -fr /var/run/march/; (sudo $(SONIC_NATIVE_DOCKERD_FOR_MUTLIARCH) &) &>/dev/null ; sleep 1; sudo $(SONIC_USERFACL_DOCKERD_FOR_MUTLIARCH);) # Docker service to load the compiled dockers-*.gz SONIC_NATIVE_DOCKERD_FOR_DOCKERFS := rm -fr $(PWD)/dockerfs/; mkdir -p $(PWD)/dockerfs/; sudo dockerd --storage-driver=overlay2 --iptables=false \ @@ -184,8 +184,10 @@ SONIC_BUILD_INSTRUCTION := make \ %:: ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) @$(DOCKER_MULTIARCH_CHECK) +ifneq ($(BLDENV), ) @$(DOCKER_SERVICE_MULTIARCH_CHECK) @$(DOCKER_SERVICE_DOCKERFS_CHECK) +endif endif @$(OVERLAY_MODULE_CHECK) diff --git a/build_debian.sh b/build_debian.sh index 34bf6eba6ab1..c1a13d1ae7d3 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -132,16 +132,11 @@ fi sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install busybox echo '[INFO] Install SONiC linux kernel image' ## Note: duplicate apt-get command to ensure every line return zero -if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install cpio klibc-utils kmod libklibc udev linux-base - sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/linux-image-*${CONFIGURED_ARCH}*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -fi sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/initramfs-tools-core_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/initramfs-tools_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/linux-image-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH}_*.deb || \ +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/linux-image-${LINUX_KERNEL_VERSION}-*_${CONFIGURED_ARCH}.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install acl [[ $CONFIGURED_ARCH == amd64 ]] && sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install dmidecode diff --git a/platform/marvell-armhf/linux-kernel-armhf.mk b/platform/marvell-armhf/linux-kernel-armhf.mk index dc5b489635c8..32e8ea3c604a 100644 --- a/platform/marvell-armhf/linux-kernel-armhf.mk +++ b/platform/marvell-armhf/linux-kernel-armhf.mk @@ -1,10 +1,7 @@ # linux kernel package for marvell armhf -KVERSION = 4.9.168 - - -LINUX_KERNEL = linux-image-4.9.168-armhf.deb -export LINUX_KERNEL - -$(LINUX_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/linux -SONIC_MAKE_DEBS += $(LINUX_KERNEL) +# Add platform specific DTB +LINUX_KERNEL_DTB = linux-image-4.9.168-armhf.deb +$(LINUX_KERNEL_DTB)_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/armhf/kernel/$(LINUX_KERNEL_DTB) +SONIC_ONLINE_DEBS += $(LINUX_KERNEL_DTB) +SONIC_STRETCH_DEBS += $(LINUX_KERNEL_DTB) diff --git a/platform/marvell-armhf/linux/Makefile b/platform/marvell-armhf/linux/Makefile index 0a616fa758d9..dba660649abf 100644 --- a/platform/marvell-armhf/linux/Makefile +++ b/platform/marvell-armhf/linux/Makefile @@ -2,9 +2,9 @@ SHELL = /bin/bash .SHELLFLAGS += -e -LINUX_KERNEL_MRVL_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/armhf/kernel/$(LINUX_KERNEL) +LINUX_KERNEL_MRVL_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/armhf/kernel/$(LINUX_KERNEL_DTB) -$(addprefix $(DEST)/, $(LINUX_KERNEL)): $(DEST)/% : +$(addprefix $(DEST)/, $(LINUX_KERNEL_DTB)): $(DEST)/% : # get deb package - wget -O $(DEST)/$(LINUX_KERNEL) $(LINUX_KERNEL_MRVL_URL) + wget -O $(DEST)/$(LINUX_KERNEL_DTB) $(LINUX_KERNEL_MRVL_URL) diff --git a/platform/marvell-armhf/platform.conf b/platform/marvell-armhf/platform.conf index 51a4dc315acc..e574a8d1a0cd 100644 --- a/platform/marvell-armhf/platform.conf +++ b/platform/marvell-armhf/platform.conf @@ -8,7 +8,7 @@ echo "Preparing for installation ... " kernel_addr=0x1100000 fdt_addr=0x1000000 -image_name="/boot/zImage" +image_name="/vmlinuz" fdt_name="/boot/armada-385-ET6448M_4G_Nand.dtb" # global mount defines diff --git a/rules/linux-kernel.mk b/rules/linux-kernel.mk index bc95255e0dff..5250f8b97e8f 100644 --- a/rules/linux-kernel.mk +++ b/rules/linux-kernel.mk @@ -4,6 +4,10 @@ KVERSION_SHORT = 4.9.0-9-2 KVERSION = $(KVERSION_SHORT)-$(CONFIGURED_ARCH) KERNEL_VERSION = 4.9.168 KERNEL_SUBVERSION = 1+deb9u5 +ifeq ($(CONFIGURED_ARCH), armhf) +# Override kernel version for ARMHF as it uses arm MP (multi-platform) for short version +KVERSION = $(KVERSION_SHORT)-armmp +endif export KVERSION_SHORT KVERSION KERNEL_VERSION KERNEL_SUBVERSION diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index e468cdf354a8..af6e7deadc31 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -156,6 +156,9 @@ RUN apt-get update && apt-get install -y \ # For broadcom sdk build {%- if CONFIGURED_ARCH == "amd64" %} linux-compiler-gcc-6-x86 \ +{%- endif %} +{%- if CONFIGURED_ARCH == "armhf" %} + linux-compiler-gcc-6-arm \ {%- endif %} linux-kbuild-4.9 \ # teamd build From 7988deb2884f0719b70cab89c375367160c233b4 Mon Sep 17 00:00:00 2001 From: Haiyang Zheng Date: Fri, 11 Oct 2019 08:15:12 -0700 Subject: [PATCH 0059/1427] [teamd] fix lacp fallback mode in teamd v1.28 (#3572) In teamd v1.28, the port can only be enabled if sync bit is set in recveived LACPDU from partner by the following commit "teamd: lacp: update port state according to partner's sync bit" (https://github.com/jpirko/libteam/commit/54f137c10579bf97800c61ebb13e732aa1d843e6) However, lacp fallback feature needs to enable port even if partner LACPDU is not received within a given period and fallback cfg is enabled. To fix the lacp fallback breakage, we have to bypass the sync bit check in lacp fallback mode. Signed-off-by: Haiyang Zheng --- ...back-support-for-single-member-port-.patch | 48 ++++++++++++------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch b/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch index 8559e476aec1..e1234c294fd8 100644 --- a/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch +++ b/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch @@ -1,17 +1,16 @@ -From 9b40af58575a89d06be51cfbb5a2265a59826110 Mon Sep 17 00:00:00 2001 -From: yorke -Date: Mon, 3 Jun 2019 12:02:36 +0800 -Subject: [PATCH 3/8] [libteam] Add fallback support for single-member-port LAG - From: Haiyang Zheng Date: Fri, 15 Dec - 2017 21:07:53 -0800 +commit f475746f56602a40861b8d94eac5f0979c4703f3 +Author: yorke +Date: Mon Jun 3 12:02:36 2019 +0800 -Signed-off-by: yorke ---- - teamd/teamd_runner_lacp.c | 42 ++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 40 insertions(+), 2 deletions(-) + From 9b40af58575a89d06be51cfbb5a2265a59826110 Mon Sep 17 00:00:00 2001 + Subject: [PATCH 3/8] [libteam] Add fallback support for single-member-port LAG + From: Haiyang Zheng Date: Fri, 15 Dec + 2017 21:07:53 -0800 + + Signed-off-by: yorke diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c -index 4dbd015..9836824 100644 +index 4dbd015..f8a9e16 100644 --- a/teamd/teamd_runner_lacp.c +++ b/teamd/teamd_runner_lacp.c @@ -138,6 +138,8 @@ struct lacp { @@ -71,7 +70,27 @@ index 4dbd015..9836824 100644 return false; return true; } -@@ -1502,6 +1525,16 @@ static int lacp_state_fast_rate_get(struct teamd_context *ctx, +@@ -334,7 +357,8 @@ static int lacp_port_should_be_enabled(struct lacp_port *lacp_port) + + if (lacp_port_selected(lacp_port) && + lacp_port->agg_lead == lacp->selected_agg_lead && +- lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION) ++ (lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION || ++ is_lacp_fallback_eligible(lacp_port))) + return true; + return false; + } +@@ -345,7 +369,8 @@ static int lacp_port_should_be_disabled(struct lacp_port *lacp_port) + + if (!lacp_port_selected(lacp_port) || + lacp_port->agg_lead != lacp->selected_agg_lead || +- !(lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION)) ++ (!(lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION) && ++ !is_lacp_fallback_eligible(lacp_port))) + return true; + return false; + } +@@ -1502,6 +1527,16 @@ static int lacp_state_fast_rate_get(struct teamd_context *ctx, return 0; } @@ -88,7 +107,7 @@ index 4dbd015..9836824 100644 static int lacp_state_select_policy_get(struct teamd_context *ctx, struct team_state_gsc *gsc, void *priv) -@@ -1529,6 +1562,11 @@ static const struct teamd_state_val lacp_state_vals[] = { +@@ -1529,6 +1564,11 @@ static const struct teamd_state_val lacp_state_vals[] = { .getter = lacp_state_fast_rate_get, }, { @@ -100,6 +119,3 @@ index 4dbd015..9836824 100644 .subpath = "select_policy", .type = TEAMD_STATE_ITEM_TYPE_STRING, .getter = lacp_state_select_policy_get, --- -2.7.4 - From bdf7d24962b85e8c830cb9fb12f8c4fdfd99cff2 Mon Sep 17 00:00:00 2001 From: fk410167 <51665572+fk410167@users.noreply.github.com> Date: Sat, 12 Oct 2019 01:55:45 +0530 Subject: [PATCH 0060/1427] [sonic-cfggen]: yaml.load() is deprecated in latest versions of PyYAML module (#3526) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 5.1 version of PyYAML python module, yaml.load() API is deprecated. Code should be compatible to support both the versions, else error/warning messages are seen like below, 2019-07-02 08:25:35,284 – INFO: [D1] /usr/local/lib/python2.7/dist-packages/sonic_device_util.py:44: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details. --- src/sonic-config-engine/sonic-cfggen | 5 ++++- src/sonic-config-engine/sonic_device_util.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index b07172b17e75..2f4e9c5eb89b 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -229,7 +229,10 @@ def main(): for yaml_file in args.yaml: with open(yaml_file, 'r') as stream: - additional_data = yaml.load(stream) + if yaml.__version__ >= "5.1": + additional_data = yaml.full_load(stream) + else: + additional_data = yaml.load(stream) deep_update(data, FormatConverter.to_deserialized(additional_data)) for json_file in args.json: diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index c7b2528194fc..34877600fd13 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -42,7 +42,10 @@ def get_sonic_version_info(): return None data = {} with open('/etc/sonic/sonic_version.yml') as stream: - data = yaml.load(stream) + if yaml.__version__ >= "5.1": + data = yaml.full_load(stream) + else: + data = yaml.load(stream) return data def valid_mac_address(mac): From 0d2aa7fb5b383d87cefe52779f9a6dc9b45efc83 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Tue, 15 Oct 2019 06:03:48 -0700 Subject: [PATCH 0061/1427] [devices]: PG headroom change for Arista 7260 (#3600) Signed-off-by: Wenda Ni --- .../pg_profile_lookup.ini | 14 ++++++------- .../Arista-7260CX3-Q64/pg_profile_lookup.ini | 20 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/pg_profile_lookup.ini b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/pg_profile_lookup.ini index c2bf04950b80..ed0005610b71 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/pg_profile_lookup.ini @@ -1,8 +1,8 @@ # PG lossless profiles. -# speed cable size xon xoff threshold xon_offset - 50000 5m 1248 1248 56160 -3 2496 - 100000 5m 1248 1248 96928 -3 2496 - 50000 40m 1248 1248 56160 -3 2496 - 100000 40m 1248 1248 96928 -3 2496 - 50000 300m 1248 1248 56160 -3 2496 - 100000 300m 1248 1248 96928 -3 2496 +# speed cable size xon xoff threshold xon_offset + 50000 5m 1248 1248 56160 -3 2496 + 100000 5m 1248 1248 96928 -3 2496 + 50000 40m 1248 1248 96096 -3 2496 + 100000 40m 1248 1248 177632 -3 2496 + 50000 300m 1248 1248 141856 -3 2496 + 100000 300m 1248 1248 268736 -3 2496 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/pg_profile_lookup.ini b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/pg_profile_lookup.ini index 34ac8b2ca700..ac33b4f961fb 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/pg_profile_lookup.ini @@ -1,11 +1,11 @@ # PG lossless profiles. -# speed cable size xon xoff threshold xon_offset - 40000 5m 1248 1248 56160 -3 2496 - 50000 5m 1248 1248 56160 -3 2496 - 100000 5m 1248 1248 96928 -3 2496 - 40000 40m 1248 1248 56160 -3 2496 - 50000 40m 1248 1248 56160 -3 2496 - 100000 40m 1248 1248 96928 -3 2496 - 40000 300m 1248 1248 56160 -3 2496 - 50000 300m 1248 1248 56160 -3 2496 - 100000 300m 1248 1248 96928 -3 2496 +# speed cable size xon xoff threshold xon_offset + 40000 5m 1248 1248 56160 -3 2496 + 50000 5m 1248 1248 56160 -3 2496 + 100000 5m 1248 1248 96928 -3 2496 + 40000 40m 1248 1248 71552 -3 2496 + 50000 40m 1248 1248 96096 -3 2496 + 100000 40m 1248 1248 177632 -3 2496 + 40000 300m 1248 1248 108160 -3 2496 + 50000 300m 1248 1248 141856 -3 2496 + 100000 300m 1248 1248 268736 -3 2496 From 34d8842fbdee1fbd0139ade7279ad0111749322d Mon Sep 17 00:00:00 2001 From: wangshengjun Date: Wed, 16 Oct 2019 02:13:48 +0800 Subject: [PATCH 0062/1427] [FRR]: Use stg in a proper way. (#3589) * [FRR]: Use stg in a proper way. Signed-off-by: wangshengjun * [FRR]restore the detach status for frr submodule after finish patching Signed-off-by: wangshengjun * [FRR]use the 'FRR_VERSION' exported from 'rule/frr.mk'. Signed-off-by: wangshengjun --- src/sonic-frr/Makefile | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index 4a31f23436ec..233696de804a 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -4,20 +4,23 @@ SHELL = /bin/bash MAIN_TARGET = $(FRR) DERIVED_TARGET = $(FRR_PYTHONTOOLS) $(FRR_DBG) $(FRR_SNMP) $(FRR_SNMP_DBG) -BRANCH = $(shell date +%Y%m%d\.%H%M%S) +FRR_BRANCH = frr/$(FRR_VERSION) +STG_BRANCH = stg_temp $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Build the package - pushd ./frr - git checkout -b $(BRANCH) origin/frr/7.1 - stg init + pushd ./frr + git checkout -b $(FRR_BRANCH) origin/$(FRR_BRANCH) + stg branch --create $(STG_BRANCH) $(FRR_BRANCH) stg import -s ../patch/series tools/tarsource.sh -V -e '-sonic' dpkg-buildpackage -rfakeroot -b -us -uc -Ppkg.frr.nortrlib -j$(SONIC_CONFIG_MAKE_JOBS) stg undo git clean -xfdf - git checkout frr/7.1 - git branch -D $(BRANCH) + git checkout $(FRR_BRANCH) + stg branch --delete $(STG_BRANCH) + git rev-parse --short HEAD | xargs git checkout + git branch -D $(FRR_BRANCH) popd mv $(DERIVED_TARGET) $* $(DEST)/ From aea09ba1da612710e725692a097b807aaca95007 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 16 Oct 2019 02:29:45 +0800 Subject: [PATCH 0063/1427] [sonic_platform] Correct the wrong log identifiers (#3596) --- .../mellanox/mlnx-platform-api/sonic_platform/chassis.py | 3 +-- platform/mellanox/mlnx-platform-api/sonic_platform/psu.py | 3 +-- platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py | 3 +-- .../mellanox/mlnx-platform-api/sonic_platform/sfp_event.py | 4 +--- .../mellanox/mlnx-platform-api/sonic_platform/thermal.py | 3 +-- src/sonic-daemon-base/sonic_daemon_base/daemon_base.py | 7 +++++-- 6 files changed, 10 insertions(+), 13 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index f5c7c04a4204..f964bf46fe88 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -39,8 +39,7 @@ REBOOT_CAUSE_FILE_LENGTH = 1 # Global logger class instance -SYSLOG_IDENTIFIER = "mlnx-chassis-api" -logger = Logger(SYSLOG_IDENTIFIER) +logger = Logger() # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index a6f217d82bd3..0789f67e4f09 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -17,8 +17,7 @@ raise ImportError (str(e) + "- required module not found") # Global logger class instance -SYSLOG_IDENTIFIER = "mlnx-psu-api" -logger = Logger(SYSLOG_IDENTIFIER) +logger = Logger() psu_list = [] diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index be59451a8cb7..dac6a8e4d4d6 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -188,8 +188,7 @@ NVE_MASK = PORT_TYPE_MASK & (PORT_TYPE_NVE << PORT_TYPE_OFFSET) # Global logger class instance -SYSLOG_IDENTIFIER = "mlnx-sfp" -logger = Logger(SYSLOG_IDENTIFIER) +logger = Logger() class SFP(SfpBase): """Platform-specific SFP class""" diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py index 439df785b24e..e92884fc3f33 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py @@ -11,8 +11,6 @@ from python_sdk_api.sx_api import * from sonic_daemon_base.daemon_base import Logger -SYSLOG_IDENTIFIER = "sfp-event" - SDK_SFP_STATE_IN = 0x1 SDK_SFP_STATE_OUT = 0x2 STATUS_PLUGIN = '1' @@ -34,7 +32,7 @@ PMPE_PACKET_SIZE = 2000 -logger = Logger(SYSLOG_IDENTIFIER) +logger = Logger() class sfp_event: ''' Listen to plugin/plugout cable events ''' diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 6614e368e547..6862b3fb258b 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -19,8 +19,7 @@ raise ImportError (str(e) + "- required module not found") # Global logger class instance -SYSLOG_IDENTIFIER = "mlnx-thermal-api" -logger = Logger(SYSLOG_IDENTIFIER) +logger = Logger() THERMAL_DEV_CATEGORY_CPU_CORE = "cpu_core" THERMAL_DEV_CATEGORY_CPU_PACK = "cpu_pack" diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index afdb189de672..a0a5bff0a297 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -48,9 +48,12 @@ def db_connect(db): # class Logger(object): - def __init__(self, syslog_identifier): + def __init__(self, syslog_identifier = None): self.syslog = syslog - self.syslog.openlog(ident=syslog_identifier, logoption=self.syslog.LOG_NDELAY, facility=self.syslog.LOG_DAEMON) + if syslog_identifier is None: + self.syslog.openlog() + else: + self.syslog.openlog(ident=syslog_identifier, logoption=self.syslog.LOG_NDELAY, facility=self.syslog.LOG_DAEMON) def __del__(self): self.syslog.closelog() From 17c21acacfae212cb24c2fd599d81318bd328aab Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Tue, 15 Oct 2019 21:32:02 +0300 Subject: [PATCH 0064/1427] [platform] Fixed return code processing in set_low_power_mode() for BFN platform (#3610) Signed-off-by: Andriy Kokhan --- .../barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py index 5e75376baa27..1daee453573e 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py @@ -135,7 +135,7 @@ def set_low_power_mode(self, port_num, lpmode): self.thrift_setup() status = pltfm_mgr.pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) self.thrift_teardown() - return status + return (status == 0) def reset(self, port_num): # Check for invalid port_num From 9032ad8b121fcee5e4afdd16a7f6c9f7790a38c0 Mon Sep 17 00:00:00 2001 From: shikenghua Date: Wed, 16 Oct 2019 02:45:09 +0800 Subject: [PATCH 0065/1427] [docker-fpm-frr] Change the ownership of files within /etc/frr/ to frr (#3388) The owner of the generated files (/etc/frr/*.conf) by start.sh is root if it is a new file. This will cause error when executing "copy running-config startup-config" in vtysh because of privilege issue. --- dockers/docker-fpm-frr/start.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/start.sh index fd092919e000..3c732fece943 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/start.sh @@ -16,6 +16,8 @@ elif [ "$CONFIG_TYPE" == "unified" ]; then rm -f /etc/frr/bgpd.conf /etc/frr/zebra.conf /etc/frr/staticd.conf fi +chown -R frr:frr /etc/frr/ + sonic-cfggen -d -t /usr/share/sonic/templates/isolate.j2 > /usr/sbin/bgp-isolate chown root:root /usr/sbin/bgp-isolate chmod 0755 /usr/sbin/bgp-isolate From 2e3fb905a388e9421074bb6057f4eb7c1107eebe Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 16 Oct 2019 02:46:09 +0800 Subject: [PATCH 0066/1427] [Mellanox]Correct reboot cause when reboot via power cycle (#3597) * [sonic_platform]remove the handling of reset_sw_reset which indicates rebooted by software. * [sonic_platform]Check "reset_sw_reset" Also check reboot cause file "reset_sw_reset" which indicates the system was rebooted due to software requesting. --- .../mellanox/mlnx-platform-api/sonic_platform/chassis.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index f964bf46fe88..fe4f7d452def 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -319,11 +319,11 @@ def initialize_reboot_cause(self): 'reset_comex_wd' : "Reset requested from ComEx", 'reset_from_asic' : "Reset requested from ASIC", 'reset_reload_bios' : "Reset caused by BIOS reload", - 'reset_sw_reset' : "Software reset", 'reset_hotswap_or_halt' : "Reset caused by hotswap or halt", 'reset_from_comex' : "Reset from ComEx", 'reset_voltmon_upgrade_fail': "Reset due to voltage monitor devices upgrade failure" } + self.reboot_by_software = 'reset_sw_reset' self.reboot_cause_initialized = True @@ -350,6 +350,11 @@ def get_reboot_cause(self): if self._verify_reboot_cause(reset_file): return self.REBOOT_CAUSE_HARDWARE_OTHER, reset_cause + if self._verify_reboot_cause(self.reboot_by_software): + logger.log_info("Hardware reboot cause: the system was rebooted due to software requesting") + else: + logger.log_info("Hardware reboot cause: no hardware reboot cause found") + return self.REBOOT_CAUSE_NON_HARDWARE, '' From 91e785279abd96714902b4b24194c1ca3387e21b Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 16 Oct 2019 04:40:53 +0800 Subject: [PATCH 0067/1427] [Mellanox] remove mlnx-sfpd (#3609) * [platform/mellanox] remove mlnx-sfpd * [platform/mellanox] remove mlnx-sfpd source files --- platform/mellanox/docker-syncd-mlnx.mk | 1 - platform/mellanox/docker-syncd-mlnx/start.sh | 2 - .../docker-syncd-mlnx/supervisord.conf | 8 - platform/mellanox/mlnx-sfpd.mk | 5 - platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd | 305 ------------------ platform/mellanox/mlnx-sfpd/setup.py | 28 -- platform/mellanox/rules.mk | 1 - 7 files changed, 350 deletions(-) delete mode 100644 platform/mellanox/mlnx-sfpd.mk delete mode 100644 platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd delete mode 100644 platform/mellanox/mlnx-sfpd/setup.py diff --git a/platform/mellanox/docker-syncd-mlnx.mk b/platform/mellanox/docker-syncd-mlnx.mk index b46c6478cf0e..db582e517bff 100644 --- a/platform/mellanox/docker-syncd-mlnx.mk +++ b/platform/mellanox/docker-syncd-mlnx.mk @@ -4,7 +4,6 @@ DOCKER_SYNCD_PLATFORM_CODE = mlnx include $(PLATFORM_PATH)/../template/docker-syncd-base.mk $(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API) -$(DOCKER_SYNCD_BASE)_PYTHON_DEBS += $(MLNX_SFPD) $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/mellanox/docker-syncd-mlnx/start.sh b/platform/mellanox/docker-syncd-mlnx/start.sh index 61ccd2db8933..96e2a9128081 100755 --- a/platform/mellanox/docker-syncd-mlnx/start.sh +++ b/platform/mellanox/docker-syncd-mlnx/start.sh @@ -6,5 +6,3 @@ supervisorctl start rsyslogd supervisorctl start syncd -supervisorctl start mlnx-sfpd - diff --git a/platform/mellanox/docker-syncd-mlnx/supervisord.conf b/platform/mellanox/docker-syncd-mlnx/supervisord.conf index 8860bd6c0205..1af5d70a1d0c 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -26,11 +26,3 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - -[program:mlnx-sfpd] -command=/usr/bin/mlnx-sfpd -priority=4 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog diff --git a/platform/mellanox/mlnx-sfpd.mk b/platform/mellanox/mlnx-sfpd.mk deleted file mode 100644 index 416dd7d0f2cd..000000000000 --- a/platform/mellanox/mlnx-sfpd.mk +++ /dev/null @@ -1,5 +0,0 @@ -# mlnx-sfpd (SONiC MLNX platform sfp event monitoring daemon) Debian package - -MLNX_SFPD = python-mlnx-sfpd_1.0-1_all.deb -$(MLNX_SFPD)_SRC_PATH = $(PLATFORM_PATH)/mlnx-sfpd -SONIC_PYTHON_STDEB_DEBS += $(MLNX_SFPD) diff --git a/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd b/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd deleted file mode 100644 index b11403b31514..000000000000 --- a/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd +++ /dev/null @@ -1,305 +0,0 @@ -#!/usr/bin/env python -''' -This code is for a mlnx platform specific daemon, mlnx-sfpd. -Which listen to the SDK for the SFP change event and post the event to DB. -''' - -from __future__ import print_function -import sys, errno -import os -import time -import syslog -import signal -import select -import json -import threading -from python_sdk_api.sx_api import * -from swsssdk import SonicV2Connector - -VERSION = '1.0' - -SYSLOG_IDENTIFIER = "mlnx-sfpd" - -REDIS_HOSTIP = "127.0.0.1" - -SDK_SFP_STATE_IN = 0x1 -SDK_SFP_STATE_OUT = 0x2 -STATUS_PLUGIN = '1' -STATUS_PLUGOUT = '0' -STATUS_UNKNOWN = '2' - -SFPD_LIVENESS_EXPIRE_SECS = 30 - -SDK_DAEMON_READY_FILE = '/tmp/sdk_ready' - -sfp_value_status_dict = { - SDK_SFP_STATE_IN: STATUS_PLUGIN, - SDK_SFP_STATE_OUT: STATUS_PLUGOUT, -} - -# ========================== Syslog wrappers ========================== -def log_info(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - - if also_print_to_console: - print(msg) - -def log_warning(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_WARNING, msg) - syslog.closelog() - - if also_print_to_console: - print(msg) - -def log_error(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() - - if also_print_to_console: - print(msg) - -# ========================== MlnxSfpd class ========================== -class MlnxSfpd: - ''' Listen to plugin/plugout cable events ''' - - SX_OPEN_RETRIES = 30 - SX_OPEN_TIMEOUT = 5 - SELECT_TIMEOUT = 1 - - def __init__(self): - self.swid = 0 - self.running = False - self.handle = None - - # Allocate SDK fd and user channel structures - self.rx_fd_p = new_sx_fd_t_p() - self.user_channel_p = new_sx_user_channel_t_p() - self.state_db = SonicV2Connector(host=REDIS_HOSTIP) - - # Register our signal handlers - signal.signal(signal.SIGHUP, self.signal_handler) - signal.signal(signal.SIGINT, self.signal_handler) - signal.signal(signal.SIGTERM, self.signal_handler) - - def signal_handler(self, signum, frame): - if signum == signal.SIGHUP: - log_info("Caught SIGHUP - ignoring...") - elif signum == signal.SIGINT: - log_info("Caught SIGINT - exiting...") - self.running = False - elif signum == signal.SIGTERM: - log_info("Caught SIGINT - exiting...") - self.running = False - else: - log_warning("Caught unhandled signal '{}'".format(signum)) - - def initialize(self): - self.state_db.connect("STATE_DB") - - swid_cnt_p = None - - try: - # Wait for SDK daemon to be started with detect the sdk_ready file - retry = 0 - while not os.path.exists(SDK_DAEMON_READY_FILE): - if retry >= self.SX_OPEN_RETRIES: - raise RuntimeError("SDK daemon failed to start after {} retries and {} seconds waiting, exiting..." - .format(retry, self.SX_OPEN_TIMEOUT * self.SX_OPEN_RETRIES)) - else: - log_info("SDK daemon not started yet, retry {} times".format(retry)) - retry = retry + 1 - time.sleep(self.SX_OPEN_TIMEOUT) - - # to make sure SDK daemon has started - time.sleep(self.SX_OPEN_TIMEOUT) - - # After SDK daemon started, sx_api_open and sx_api_host_ifc_open is ready for call - rc, self.handle = sx_api_open(None) - if rc != SX_STATUS_SUCCESS: - raise RuntimeError("failed to call sx_api_open with rc {}, exiting...".format(rc)) - - rc = sx_api_host_ifc_open(self.handle, self.rx_fd_p) - if rc != SX_STATUS_SUCCESS: - raise RuntimeError("failed to call sx_api_host_ifc_open with rc {}, exiting...".format(rc)) - - self.user_channel_p.type = SX_USER_CHANNEL_TYPE_FD - self.user_channel_p.channel.fd = self.rx_fd_p - - # Wait for switch to be created and initialized inside SDK - retry = 0 - swid_cnt_p = new_uint32_t_p() - uint32_t_p_assign(swid_cnt_p, 0) - swid_cnt = 0 - while True: - if retry >= self.SX_OPEN_RETRIES: - raise RuntimeError("switch not created after {} retries and {} seconds waiting, exiting..." - .format(retry, self.SX_OPEN_RETRIES * self.SX_OPEN_TIMEOUT)) - else: - rc = sx_api_port_swid_list_get(self.handle, None, swid_cnt_p) - if rc == SX_STATUS_SUCCESS: - swid_cnt = uint32_t_p_value(swid_cnt_p) - if swid_cnt > 0: - delete_uint32_t_p(swid_cnt_p) - swid_cnt_p = None - break - else: - log_info("switch not created yet, swid_cnt {}, retry {} times and wait for {} seconds" - .format(swid_cnt, retry, self.SX_OPEN_TIMEOUT * retry)) - else: - raise RuntimeError("sx_api_port_swid_list_get fail with rc {}, retry {} times and wait for {} seconds". - format(rc, retry, self.SX_OPEN_TIMEOUT * retry)) - - retry = retry + 1 - time.sleep(self.SX_OPEN_TIMEOUT) - - # After switch was created inside SDK, sx_api_host_ifc_trap_id_register_set is ready to call - rc = sx_api_host_ifc_trap_id_register_set(self.handle, - SX_ACCESS_CMD_REGISTER, - self.swid, - SX_TRAP_ID_PMPE, - self.user_channel_p) - - if rc != SX_STATUS_SUCCESS: - raise RuntimeError("sx_api_host_ifc_trap_id_register_set failed with rc {}, exiting...".format(rc)) - - self.running = True - except Exception as e: - log_error("mlnx-sfpd initialization failed due to {}, exiting...".format(repr(e))) - if swid_cnt_p is not None: - delete_uint32_t_p(swid_cnt_p) - self.deinitialize() - - def deinitialize(self): - # remove mlnx-sfpd liveness key in DB if not expired yet - if self.state_db.exists("STATE_DB", "MLNX_SFPD_TASK|LIVENESS"): - self.state_db.delete("STATE_DB", "MLNX_SFPD_TASK|LIVENESS") - - if self.handle is None: - return - - # unregister trap id - rc = sx_api_host_ifc_trap_id_register_set(self.handle, - SX_ACCESS_CMD_DEREGISTER, - self.swid, - SX_TRAP_ID_PMPE, - self.user_channel_p) - if rc != SX_STATUS_SUCCESS: - log_error("sx_api_host_ifc_trap_id_register_set exited with error, rc {}".format(rc)) - - rc = sx_api_host_ifc_close(self.handle, self.rx_fd_p) - if rc != SX_STATUS_SUCCESS: - log_error("sx_api_host_ifc_close exited with error, rc {}".format(rc)) - - rc = sx_api_close(self.handle) - if rc != SX_STATUS_SUCCESS: - log_error("sx_api_close exited with error, rc {}".format(rc)) - - def run(self): - - while self.running: - try: - read, _, _ = select.select([self.rx_fd_p.fd], [], [], self.SELECT_TIMEOUT) - except select.error as err: - rc, msg = err - if rc == errno.EAGAIN or rc == errno.EINTR: - continue - else: - raise - - for fd in read: - if fd == self.rx_fd_p.fd: - success, port_list, module_state = self.on_pmpe(self.rx_fd_p) - if not success: - raise RuntimeError("failed to read from {}".format(fd)) - - sfp_state = sfp_value_status_dict.get(module_state, STATUS_UNKNOWN) - if sfp_state == STATUS_UNKNOWN: - log_error("unknown module state {} on port {}".format(module_state, port)) - continue - - for port in port_list: - log_info("SFP on port {} state {}".format(port, sfp_state)) - self.send_sfp_notification(str(port), sfp_state) - - self.update_sfpd_liveness_key(SFPD_LIVENESS_EXPIRE_SECS) - - def send_sfp_notification(self, port, state): - sfp_notify = [port, state] - msg = json.dumps(sfp_notify, separators=(',', ':')) - self.state_db.publish('STATE_DB', 'TRANSCEIVER_NOTIFY', msg) - - def update_sfpd_liveness_key(self, timeout_secs): - if not self.state_db.exists('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS'): - self.state_db.set('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS', 'value', 'ok') - self.state_db.expire('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS', timeout_secs) - - def on_pmpe(self, fd_p): - ''' on port module plug event handler ''' - - # recv parameters - pkt_size = 2000 - pkt_size_p = new_uint32_t_p() - uint32_t_p_assign(pkt_size_p, pkt_size) - pkt = new_uint8_t_arr(pkt_size) - recv_info_p = new_sx_receive_info_t_p() - pmpe_t = sx_event_pmpe_t() - port_attributes_list = new_sx_port_attributes_t_arr(64) - port_cnt_p = new_uint32_t_p() - uint32_t_p_assign(port_cnt_p,64) - label_port_list = [] - module_state = 0 - - rc = sx_lib_host_ifc_recv(fd_p, pkt, pkt_size_p, recv_info_p) - if rc != 0: - log_error("sx_lib_host_ifc_recv exited with error, rc %d" % rc) - status = False - else: - status = True - pmpe_t = recv_info_p.event_info.pmpe - port_list_size = pmpe_t.list_size - logical_port_list = pmpe_t.log_port_list - module_state = pmpe_t.module_state - - for i in xrange(port_list_size): - logical_port = sx_port_log_id_t_arr_getitem(logical_port_list, i) - rc = sx_api_port_device_get(self.handle, 1 , 0, port_attributes_list, port_cnt_p) - port_cnt = uint32_t_p_value(port_cnt_p) - - for i in xrange(port_cnt): - port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list,i) - if port_attributes.log_port == logical_port: - lable_port = port_attributes.port_mapping.module_port - break - label_port_list.append(lable_port) - - delete_uint32_t_p(pkt_size_p) - delete_uint8_t_arr(pkt) - delete_sx_receive_info_t_p(recv_info_p) - delete_sx_port_attributes_t_arr(port_attributes_list) - delete_uint32_t_p(port_cnt_p) - - return status, label_port_list, module_state, - - -# main start -def main(): - log_info("mlnx-sfpd daemon started") - - sfpd = MlnxSfpd() - try: - sfpd.initialize() - sfpd.run() - except (RuntimeError, select.error) as err: - log_error("error: {}".format(err)) - finally: - sfpd.deinitialize() - - log_info("mlnx-sfpd daemon exited") - - -if __name__ == '__main__': - main() diff --git a/platform/mellanox/mlnx-sfpd/setup.py b/platform/mellanox/mlnx-sfpd/setup.py deleted file mode 100644 index ea9b895cb1f4..000000000000 --- a/platform/mellanox/mlnx-sfpd/setup.py +++ /dev/null @@ -1,28 +0,0 @@ -from setuptools import setup - -setup( - name='mlnx-sfpd', - version='1.0', - description='SFP event mmonitoring daemon for SONiC on mellanox platform', - license='Apache 2.0', - author='SONiC Community', - url='https://github.com/Azure/sonic-buildimage/', - maintainer='Kebo Liu', - maintainer_email='kebol@mellanox.com', - scripts=[ - 'scripts/mlnx-sfpd', - ], - classifiers=[ - 'Development Status :: 4 - Beta', - 'Environment :: No Input/Output (Daemon)', - 'Intended Audience :: Developers', - 'Intended Audience :: Information Technology', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: Apache Software License', - 'Natural Language :: English', - 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python :: 2.7', - 'Topic :: System :: Hardware', - ], - keywords='sonic SONiC SFP sfp MELLANOX mellanox daemon SFPD sfpd', -) diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index c869bfc6cd3d..dd10cefda571 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -10,7 +10,6 @@ include $(PLATFORM_PATH)/docker-saiserver-mlnx.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-mlnx.mk -include $(PLATFORM_PATH)/mlnx-sfpd.mk include $(PLATFORM_PATH)/mlnx-ffb.mk include $(PLATFORM_PATH)/issu-version.mk From 249e858926b974c0b7a3fcc198676d2734aad1e4 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 16 Oct 2019 23:31:27 +0800 Subject: [PATCH 0068/1427] [Mellanox] Support SN3800 in platform api (#3593) * [sonic_platform]Support 3800 1. add port position tuple for 3800 * [sonic_platform/chassis] address comments --- platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index fe4f7d452def..44ef8981281f 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -43,8 +43,8 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2700': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0} -port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1),(0, 18, 21, 22, 1)] +hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4} +port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] class Chassis(ChassisBase): """Platform-specific Chassis class""" From 48e4cf6971bec1fa8ca3b85f9cf989753104e770 Mon Sep 17 00:00:00 2001 From: sudhanshukumar22 <51457531+sudhanshukumar22@users.noreply.github.com> Date: Thu, 17 Oct 2019 01:32:20 +0530 Subject: [PATCH 0069/1427] commit 4ea6cafbcad4c72186587b45fa5e2f6c6dbec893 (HEAD -> bgp-snmp-socket-issue, origin/bgp-snmp-socket-issue) (#3604) Author: sudhanshukumar22 Date: Tue Oct 15 02:31:20 2019 -0700 lib: changes for making snmp socket non-blocking Description: The changes have been done to make the snmp socket non-blocking before calling snmp_read() FRR Pull request: https://github.com/FRRouting/frr/pull/5134 Problem Description/Summary : vtysh hangs on first try to enter after a reboot with BGP dynamic peers Expected Behavior : VTYSH should not hang. When we debug more into bgpd docker by doing gdb on its threads, we find the below thread of bgpd, which is causing the issue. Thread 1 (Thread 0x7f1e1ec46d40 (LWP 47)): 0x00007f1e1d762593 in recvfrom () from /lib/x86_64-linux-gnu/libpthread.so.0 0x00007f1e1aadd09b in netsnmp_tcpbase_recv () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 0x00007f1e1aad9617 in netsnmp_transport_recv () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 0x00007f1e1aab2c07 in _sess_read () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 0x00007f1e1aab3a29 in snmp_sess_read2 () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 0x00007f1e1aab3a7b in snmp_read2 () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 0x00007f1e1aab3acf in snmp_read () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 0x00007f1e1b44d7ec in agentx_read (t=0x7fffa75f0080) at lib/agentx.c:63 0x00007f1e1e7d6451 in thread_call (thread=0x7fffa75f0080) at lib/thread.c:1620 0x00007f1e1e770699 in frr_run (master=0x559396ea60f0) at lib/libfrr.c:1011 0x0000559395b4d953 in main (argc=5, argv=0x7fffa75f02b8) at bgpd/bgp_main.c:492 (gdb) bt 0x00007f830c89d210 in __read_nocancel () from /lib/x86_64-linux-gnu/libpthread.so.0 0x000056450e1e8238 in vtysh_client_run (vclient=0x56450e4a8b40 , line=0x56450e21add0 enable, callback=0x0, cbarg=0x0) at vtysh/vtysh.c:216 0x000056450e1e8c6b in vtysh_client_run_all (head_client=0x56450e4a8b40 , line=0x56450e21add0 enable, continue_on_err=0, callback=0x0, cbarg=0x0) at vtysh/vtysh.c:356 0x000056450e1e8ddb in vtysh_client_execute (head_client=0x56450e4a8b40 , line=0x56450e21add0 enable) at vtysh/vtysh.c:393 0x000056450e1e9c82 in vtysh_execute_func (line=0x56450e21add0 enable, pager=0) at vtysh/vtysh.c:598 0x000056450e1e9dee in vtysh_execute_no_pager (line=0x56450e21add0 enable) at vtysh/vtysh.c:619 0x000056450e1f7d48 in vtysh_read_file (confp=0x56451000a9d0, top_cfg=1) at vtysh/vtysh_config.c:494 0x000056450e1f7ef2 in vtysh_read_config (config_default_dir=0x56450e4edc20 /etc/frr/frr.conf, top_cfg=1) at vtysh/vtysh_config.c:522 0x000056450e1e5de4 in vtysh_apply_top_level_config () at vtysh/vtysh_main.c:301 0x000056450e1e7842 in main (argc=2, argv=0x7ffc81e6f598, env=0x7ffc81e6f5b0) at vtysh/vtysh_main.c:692 The fix has been taken from the following link. https://sourceforge.net/p/net-snmp/patches/1348/ --- ...-for-making-snmp-socket-non-blocking.patch | 85 +++++++++++++++++++ src/sonic-frr/patch/series | 1 + 2 files changed, 86 insertions(+) create mode 100644 src/sonic-frr/patch/0006-changes-for-making-snmp-socket-non-blocking.patch diff --git a/src/sonic-frr/patch/0006-changes-for-making-snmp-socket-non-blocking.patch b/src/sonic-frr/patch/0006-changes-for-making-snmp-socket-non-blocking.patch new file mode 100644 index 000000000000..a106eca3d831 --- /dev/null +++ b/src/sonic-frr/patch/0006-changes-for-making-snmp-socket-non-blocking.patch @@ -0,0 +1,85 @@ +From 6d43b90540c6aeda0fff001de93c88e01aacadab Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Tue, 15 Oct 2019 02:11:01 -0700 +Subject: [PATCH] lib: changes for making snmp socket non-blocking + +Description: The changes have been done to make the snmp socket +non-blocking before calling snmp_read() +FRR Pull request: https://github.com/FRRouting/frr/pull/5134 + +Problem Description/Summary : +vtysh hangs on first try to enter after a reboot with BGP dynamic peers + +Expected Behavior : +VTYSH should not hang. +When we debug more into bgpd docker by doing gdb on its threads, we find the below thread of bgpd, which is causing the issue. +Thread 1 (Thread 0x7f1e1ec46d40 (LWP 47)): + +0x00007f1e1d762593 in recvfrom () from /lib/x86_64-linux-gnu/libpthread.so.0 +0x00007f1e1aadd09b in netsnmp_tcpbase_recv () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1aad9617 in netsnmp_transport_recv () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1aab2c07 in _sess_read () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1aab3a29 in snmp_sess_read2 () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1aab3a7b in snmp_read2 () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1aab3acf in snmp_read () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1b44d7ec in agentx_read (t=0x7fffa75f0080) at lib/agentx.c:63 +0x00007f1e1e7d6451 in thread_call (thread=0x7fffa75f0080) at lib/thread.c:1620 +0x00007f1e1e770699 in frr_run (master=0x559396ea60f0) at lib/libfrr.c:1011 +0x0000559395b4d953 in main (argc=5, argv=0x7fffa75f02b8) at bgpd/bgp_main.c:492 + +(gdb) bt + +0x00007f830c89d210 in __read_nocancel () from /lib/x86_64-linux-gnu/libpthread.so.0 +0x000056450e1e8238 in vtysh_client_run (vclient=0x56450e4a8b40 , line=0x56450e21add0 enable, callback=0x0, cbarg=0x0) at vtysh/vtysh.c:216 +0x000056450e1e8c6b in vtysh_client_run_all (head_client=0x56450e4a8b40 , line=0x56450e21add0 enable, continue_on_err=0, callback=0x0, cbarg=0x0) at vtysh/vtysh.c:356 +0x000056450e1e8ddb in vtysh_client_execute (head_client=0x56450e4a8b40 , line=0x56450e21add0 enable) at vtysh/vtysh.c:393 +0x000056450e1e9c82 in vtysh_execute_func (line=0x56450e21add0 enable, pager=0) at vtysh/vtysh.c:598 +0x000056450e1e9dee in vtysh_execute_no_pager (line=0x56450e21add0 enable) at vtysh/vtysh.c:619 +0x000056450e1f7d48 in vtysh_read_file (confp=0x56451000a9d0, top_cfg=1) at vtysh/vtysh_config.c:494 +0x000056450e1f7ef2 in vtysh_read_config (config_default_dir=0x56450e4edc20 /etc/frr/frr.conf, top_cfg=1) at vtysh/vtysh_config.c:522 +0x000056450e1e5de4 in vtysh_apply_top_level_config () at vtysh/vtysh_main.c:301 +0x000056450e1e7842 in main (argc=2, argv=0x7ffc81e6f598, env=0x7ffc81e6f5b0) at vtysh/vtysh_main.c:692 + +The fix has been taken from the following link. +https://sourceforge.net/p/net-snmp/patches/1348/ +--- + lib/agentx.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/lib/agentx.c b/lib/agentx.c +index 40cac722a..2c6a43d1a 100644 +--- a/lib/agentx.c ++++ b/lib/agentx.c +@@ -55,13 +55,29 @@ static int agentx_timeout(struct thread *t) + static int agentx_read(struct thread *t) + { + fd_set fds; ++ int flags; ++ int nonblock = false; + struct listnode *ln = THREAD_ARG(t); + list_delete_node(events, ln); + ++ /* fix for non blocking socket */ ++ flags = fcntl(THREAD_FD(t), F_GETFL, 0); ++ if (-1 == flags) ++ return -1; ++ ++ if (flags & O_NONBLOCK) ++ nonblock = true; ++ else ++ fcntl(THREAD_FD(t), F_SETFL, flags | O_NONBLOCK); ++ + FD_ZERO(&fds); + FD_SET(THREAD_FD(t), &fds); + snmp_read(&fds); + ++ /* Reset the flag */ ++ if (!nonblock) ++ fcntl(THREAD_FD(t), F_SETFL, flags); ++ + netsnmp_check_outstanding_agent_requests(); + agentx_events_update(); + return 0; +-- +2.18.0 + diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index dc5eaa2fcd36..1acf6d94f435 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -2,3 +2,4 @@ 0002-Reduce-severity-of-Vty-connected-from-message.patch 0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch 0005-Support-VRF.patch +0006-changes-for-making-snmp-socket-non-blocking.patch From 0a39ee417173fc0cbb3996f6a74400a341126275 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 16 Oct 2019 23:44:18 +0300 Subject: [PATCH 0070/1427] [mellanox] Update HW-MGMT: V.7.0000.2300. (#3617) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/hw-management.mk | 2 +- platform/mellanox/hw-management/hw-mgmt | 2 +- src/sonic-linux-kernel | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index 21a16d29dbb2..3e7749e11c4e 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 2.0.0191 +MLNX_HW_MANAGEMENT_VERSION = 7.0000.2300 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 93076e83b083..a72ba6371380 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 93076e83b08322207f7b860d34c6c3c2bd655aa0 +Subproject commit a72ba6371380b6d97cadf9f57f11b05dd9ae576c diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index f8bbe29ff896..6d55e9a84c6d 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit f8bbe29ff89611d190658118e2c191943dabe3e0 +Subproject commit 6d55e9a84c6d0693fa5532bea2d2ddfa5c501eb6 From 7a7e5c377b454caffc98740bc6039a781b706b26 Mon Sep 17 00:00:00 2001 From: hans-tseng Date: Thu, 17 Oct 2019 04:56:34 +0800 Subject: [PATCH 0071/1427] [devices/delta]: Update the port_config.ini & th2-ag9064-64x100G.config.bcm (#3615) 1. add the speed and index in port_config.ini 2. rmove the unuse port in the config.bcm file Signed-off-by: hans-tseng --- .../Delta-ag9064/port_config.ini | 130 +++++++++--------- .../th2-ag9064-64x100G.config.bcm | 6 - 2 files changed, 65 insertions(+), 71 deletions(-) diff --git a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini index be43857f82b1..ee425d4ad4f6 100644 --- a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini +++ b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini @@ -1,65 +1,65 @@ -# name lanes alias -Ethernet0 49,50,51,52 Ethernet1/1 -Ethernet4 53,54,55,56 Ethernet2/1 -Ethernet8 65,66,67,68 Ethernet3/1 -Ethernet12 69,70,71,72 Ethernet4/1 -Ethernet16 81,82,83,84 Ethernet5/1 -Ethernet20 85,86,87,88 Ethernet6/1 -Ethernet24 1,2,3,4 Ethernet7/1 -Ethernet28 101,102,103,104 Ethernet8/1 -Ethernet32 5,6,7,8 Ethernet9/1 -Ethernet36 17,18,19,20 Ethernet10/1 -Ethernet40 21,22,23,24 Ethernet11/1 -Ethernet44 33,34,35,36 Ethernet12/1 -Ethernet48 37,38,39,40 Ethernet13/1 -Ethernet52 97,98,99,100 Ethernet14/1 -Ethernet56 113,114,115,116 Ethernet15/1 -Ethernet60 117,118,119,120 Ethernet16/1 -Ethernet64 129,130,131,132 Ethernet17/1 -Ethernet68 133,134,135,136 Ethernet18/1 -Ethernet72 145,146,147,148 Ethernet19/1 -Ethernet76 209,210,211,212 Ethernet20/1 -Ethernet80 213,214,215,216 Ethernet21/1 -Ethernet84 225,226,227,228 Ethernet22/1 -Ethernet88 229,230,231,232 Ethernet23/1 -Ethernet92 241,242,243,244 Ethernet24/1 -Ethernet96 245,246,247,248 Ethernet25/1 -Ethernet100 157,158,159,160 Ethernet26/1 -Ethernet104 161,162,163,164 Ethernet27/1 -Ethernet108 165,166,167,168 Ethernet28/1 -Ethernet112 177,178,179,180 Ethernet29/1 -Ethernet116 181,182,183,184 Ethernet30/1 -Ethernet120 193,194,195,196 Ethernet31/1 -Ethernet124 197,198,199,200 Ethernet32/1 -Ethernet128 61,62,63,64 Ethernet33/1 -Ethernet132 57,58,59,60 Ethernet34/1 -Ethernet136 77,78,79,80 Ethernet35/1 -Ethernet140 73,74,75,76 Ethernet36/1 -Ethernet144 93,94,95,96 Ethernet37/1 -Ethernet148 89,90,91,92 Ethernet38/1 -Ethernet152 105,106,107,108 Ethernet39/1 -Ethernet156 9,10,11,12 Ethernet40/1 -Ethernet160 25,26,27,28 Ethernet41/1 -Ethernet164 13,14,15,16 Ethernet42/1 -Ethernet168 41,42,43,44 Ethernet43/1 -Ethernet172 29,30,31,32 Ethernet44/1 -Ethernet176 45,46,47,48 Ethernet45/1 -Ethernet180 109,110,111,112 Ethernet46/1 -Ethernet184 125,126,127,128 Ethernet47/1 -Ethernet188 121,122,123,124 Ethernet48/1 -Ethernet192 141,142,143,144 Ethernet49/1 -Ethernet196 137,138,139,140 Ethernet50/1 -Ethernet200 217,218,219,220 Ethernet51/1 -Ethernet204 149,150,151,152 Ethernet52/1 -Ethernet208 233,234,235,236 Ethernet53/1 -Ethernet212 221,222,223,224 Ethernet54/1 -Ethernet216 249,250,251,252 Ethernet55/1 -Ethernet220 237,238,239,240 Ethernet56/1 -Ethernet224 153,154,155,156 Ethernet57/1 -Ethernet228 253,254,255,256 Ethernet58/1 -Ethernet232 173,174,175,176 Ethernet59/1 -Ethernet236 169,170,171,172 Ethernet60/1 -Ethernet240 189,190,191,192 Ethernet61/1 -Ethernet244 185,186,187,188 Ethernet62/1 -Ethernet248 205,206,207,208 Ethernet63/1 -Ethernet252 201,202,203,204 Ethernet64/1 +# name lanes alias index speed +Ethernet0 49,50,51,52 hundredGigE1/1 0 100000 +Ethernet4 53,54,55,56 hundredGigE1/2 1 100000 +Ethernet8 65,66,67,68 hundredGigE1/3 2 100000 +Ethernet12 69,70,71,72 hundredGigE1/4 3 100000 +Ethernet16 81,82,83,84 hundredGigE1/5 4 100000 +Ethernet20 85,86,87,88 hundredGigE1/6 5 100000 +Ethernet24 1,2,3,4 hundredGigE1/7 6 100000 +Ethernet28 101,102,103,104 hundredGigE1/8 7 100000 +Ethernet32 5,6,7,8 hundredGigE1/9 8 100000 +Ethernet36 17,18,19,20 hundredGigE1/10 9 100000 +Ethernet40 21,22,23,24 hundredGigE1/11 10 100000 +Ethernet44 33,34,35,36 hundredGigE1/12 11 100000 +Ethernet48 37,38,39,40 hundredGigE1/13 12 100000 +Ethernet52 97,98,99,100 hundredGigE1/14 13 100000 +Ethernet56 113,114,115,116 hundredGigE1/15 14 100000 +Ethernet60 117,118,119,120 hundredGigE1/16 15 100000 +Ethernet64 129,130,131,132 hundredGigE1/17 16 100000 +Ethernet68 133,134,135,136 hundredGigE1/18 17 100000 +Ethernet72 145,146,147,148 hundredGigE1/19 18 100000 +Ethernet76 209,210,211,212 hundredGigE1/20 19 100000 +Ethernet80 213,214,215,216 hundredGigE1/21 20 100000 +Ethernet84 225,226,227,228 hundredGigE1/22 21 100000 +Ethernet88 229,230,231,232 hundredGigE1/23 22 100000 +Ethernet92 241,242,243,244 hundredGigE1/24 23 100000 +Ethernet96 245,246,247,248 hundredGigE1/25 24 100000 +Ethernet100 157,158,159,160 hundredGigE1/26 25 100000 +Ethernet104 161,162,163,164 hundredGigE1/27 26 100000 +Ethernet108 165,166,167,168 hundredGigE1/28 27 100000 +Ethernet112 177,178,179,180 hundredGigE1/29 28 100000 +Ethernet116 181,182,183,184 hundredGigE1/30 29 100000 +Ethernet120 193,194,195,196 hundredGigE1/31 30 100000 +Ethernet124 197,198,199,200 hundredGigE1/32 31 100000 +Ethernet128 61,62,63,64 hundredGigE1/33 32 100000 +Ethernet132 57,58,59,60 hundredGigE1/34 33 100000 +Ethernet136 77,78,79,80 hundredGigE1/35 34 100000 +Ethernet140 73,74,75,76 hundredGigE1/36 35 100000 +Ethernet144 93,94,95,96 hundredGigE1/37 36 100000 +Ethernet148 89,90,91,92 hundredGigE1/38 37 100000 +Ethernet152 105,106,107,108 hundredGigE1/39 38 100000 +Ethernet156 9,10,11,12 hundredGigE1/40 39 100000 +Ethernet160 25,26,27,28 hundredGigE1/41 40 100000 +Ethernet164 13,14,15,16 hundredGigE1/42 41 100000 +Ethernet168 41,42,43,44 hundredGigE1/43 42 100000 +Ethernet172 29,30,31,32 hundredGigE1/44 43 100000 +Ethernet176 45,46,47,48 hundredGigE1/45 44 100000 +Ethernet180 109,110,111,112 hundredGigE1/46 45 100000 +Ethernet184 125,126,127,128 hundredGigE1/47 46 100000 +Ethernet188 121,122,123,124 hundredGigE1/48 47 100000 +Ethernet192 141,142,143,144 hundredGigE1/49 48 100000 +Ethernet196 137,138,139,140 hundredGigE1/50 49 100000 +Ethernet200 217,218,219,220 hundredGigE1/51 50 100000 +Ethernet204 149,150,151,152 hundredGigE1/52 51 100000 +Ethernet208 233,234,235,236 hundredGigE1/53 52 100000 +Ethernet212 221,222,223,224 hundredGigE1/54 53 100000 +Ethernet216 249,250,251,252 hundredGigE1/55 54 100000 +Ethernet220 237,238,239,240 hundredGigE1/56 55 100000 +Ethernet224 153,154,155,156 hundredGigE1/57 56 100000 +Ethernet228 253,254,255,256 hundredGigE1/58 57 100000 +Ethernet232 173,174,175,176 hundredGigE1/59 58 100000 +Ethernet236 169,170,171,172 hundredGigE1/60 59 100000 +Ethernet240 189,190,191,192 hundredGigE1/61 60 100000 +Ethernet244 185,186,187,188 hundredGigE1/62 61 100000 +Ethernet248 205,206,207,208 hundredGigE1/63 62 100000 +Ethernet252 201,202,203,204 hundredGigE1/64 63 100000 diff --git a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm index 3914599abf7c..eae7278a3ab2 100644 --- a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm +++ b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm @@ -715,8 +715,6 @@ phy_chain_tx_polarity_flip_physical{96.0}=0x0 phy_chain_tx_polarity_flip_physical{97.0}=0x1 phy_chain_tx_polarity_flip_physical{98.0}=0x0 phy_chain_tx_polarity_flip_physical{99.0}=0x1 -portmap_100=259:10 -portmap_101=262:10 portmap_102=193:100 portmap_103=197:100 portmap_104=201:100 @@ -736,14 +734,12 @@ portmap_116=249:100 portmap_117=253:100 portmap_11=41:100 portmap_12=45:100 -portmap_135=263:10 portmap_13=49:100 portmap_14=53:100 portmap_15=57:100 portmap_16=61:100 portmap_1=1:100 portmap_2=5:100 -portmap_33=260:10 portmap_34=65:100 portmap_35=69:100 portmap_36=73:100 @@ -763,8 +759,6 @@ portmap_48=121:100 portmap_49=125:100 portmap_4=13:100 portmap_5=17:100 -portmap_66=257:10 -portmap_67=261:10 portmap_68=129:100 portmap_69=133:100 portmap_6=21:100 From 2d87ca4a18ef912a989ef984ba0e6e3032f2ef15 Mon Sep 17 00:00:00 2001 From: habeebmohammed Date: Wed, 16 Oct 2019 16:49:39 -0700 Subject: [PATCH 0072/1427] [inventec/d7054q28b] Add new platform APIs chassis, eeprom,fan, psu, thermal, sfp (#3577) --- .../d7054q28b/setup.py | 15 + .../d7054q28b/sonic_platform/__init__.py | 3 + .../d7054q28b/sonic_platform/chassis.py | 155 ++ .../d7054q28b/sonic_platform/eeprom.py | 110 ++ .../d7054q28b/sonic_platform/fan.py | 213 +++ .../d7054q28b/sonic_platform/platform.py | 20 + .../d7054q28b/sonic_platform/psu.py | 196 +++ .../d7054q28b/sonic_platform/sfp.py | 1285 +++++++++++++++++ .../d7054q28b/sonic_platform/thermal.py | 100 ++ .../debian/platform-modules-d7054q28b.install | 1 + .../debian/rules | 4 +- 11 files changed, 2100 insertions(+), 2 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d7054q28b/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/platform.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/thermal.py diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/setup.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/setup.py new file mode 100644 index 000000000000..3bd7b4825f43 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Inventec D7054Q28B platforms', + + packages=['sonic_platform'], +) + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/__init__.py new file mode 100644 index 000000000000..4bfefa0fb636 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py new file mode 100644 index 000000000000..b5053cf4e2b4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.eeprom import Eeprom + from sonic_platform.psu import Psu + from sonic_platform.sfp import Sfp + from sonic_platform.fan import Fan + from sonic_platform.watchdog import Watchdog + from sonic_platform.thermal import Thermal + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Chassis(ChassisBase): + + def __init__(self): + ChassisBase.__init__(self) + self.__num_of_psus = 2 + self.__num_of_ports = 54 + self.__num_of_sfps = 48 + self.__num_of_fans = 4 + self.__num_of_thermals = 6 + + # Initialize EEPROM + self._eeprom = Eeprom() + + # Initialize watchdog + #self._watchdog = Watchdog() + + # Initialize FAN + for index in range(1, self.__num_of_fans + 1): + fan = Fan(index) + self._fan_list.append(fan) + + # Initialize thermal + for index in range(1, self.__num_of_thermals + 1): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + # Initialize PSU and PSU_FAN + for index in range(1, self.__num_of_psus + 1): + psu = Psu(index) + self._psu_list.append(psu) + fan = Fan(index, True) + self._fan_list.append(fan) + + # Initialize SFP + for index in range(0, self.__num_of_ports): + if index in range(0,self.__num_of_sfps): + sfp = Sfp(index, 'SFP') + else: + sfp = Sfp(index, 'QSFP') + + self._sfp_list.append(sfp) + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_number_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + +############################################## +# Chassis methods +############################################## + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + """ + return self._eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/eeprom.py new file mode 100644 index 000000000000..b0ebee54ee24 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/eeprom.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# +# Name: eeprom.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + from sonic_eeprom import eeprom_tlvinfo + import binascii +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self): + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0053/eeprom" + super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True) + self.__eeprom_tlv_dict = dict() + try: + self.__eeprom_data = self.read_eeprom() + except: + self.__eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.__eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + ord(eeprom[tlv_index + 1])] + code = "0x%02X" % (ord(tlv[0])) + + if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | + (ord(tlv[4]) << 8) | ord(tlv[5])) + value += str(tlv[6:6 + ord(tlv[1])]) + else: + name, value = self.decoder(None, tlv) + + self.__eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+1]) + 2 + + def serial_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2] + + def base_mac_addr(self): + (is_valid, t) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(TlvInfoDecoder, self).switchaddrstr(e) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def serial_tag_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2] + + def revision_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2] + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.__eeprom_tlv_dict + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/fan.py new file mode 100644 index 000000000000..ecfbfe2d8763 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/fan.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python + +############################################################################# +# Inventec d7264 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the FAN information +# +############################################################################# + +try: + import os + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +############### +# Global +############### +FAN_DIR = "/sys/bus/i2c/devices/0-0066/" +MAX_PWM = 255 +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, index, is_psu_fan=False): + self.is_psu_fan = is_psu_fan + + self.fan_gpi = "fan_gpi" + self.fan_index = index + if self.is_psu_fan: + self.fan_pwm = "pwm_psu{}".format(self.fan_index) + self.psu_fan_rpm = "rpm_psu{}".format(self.fan_index) + else: + self.fan_pwm = "pwm{}".format(self.fan_index) + self.fan_status_led_green_color = "fan_led_grn{}".format(self.fan_index) + self.fan_status_led_red_color = "fan_led_red{}".format(self.fan_index) + self.fan_front_rpm = "fan{}_input".format(self.fan_index * 2 - 1) + self.fan_rear_rpm = "fan{}_input".format(self.fan_index * 2) + + +####################### +# private function +####################### + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + + #################### + # Device base + #################### + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + if self.is_psu_fan: + return "PSU-{}_FAN".format(self.fan_index) + else: + return "FAN-{}".format(self.fan_index) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + + Note: + fan_gpi define 8 bits + low byte means fan presense + high byte means fan direction + """ + presence = False + attr_path = FAN_DIR + self.fan_gpi + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + not_presence_bit = 1 << (self.fan_index - 1) + if not (int(attr_rv,16) and not_presence_bit): + presence = True + + return presence + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + if not self.is_psu_fan: + status = False + attr_grn_path = FAN_DIR + self.fan_status_led_green_color + + attr_grn_rv = self.__get_attr_value(attr_grn_path) + if (attr_grn_rv != 'ERR' and attr_grn_rv == '1'): + status = True + return status + + ################# + # fan base + ################# + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + + Note: + fan_gpi define 8 bits + low byte means fan presense + high byte means fan direction + """ + direction = self.FAN_DIRECTION_INTAKE + attr_path = FAN_DIR + self.fan_gpi + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + #attr_rv = attr_rv >> 4 + direction_bit = 1 << ((self.fan_index - 1)+4) + if not (int(attr_rv,16) and direction_bit): + direction = self.FAN_DIRECTION_EXHAUST + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + attr_path = FAN_DIR + self.fan_pwm + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + pwm = int(attr_rv,10)if attr_rv else 0 + speed = float(pwm*100/MAX_PWM) + + return int(speed) + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + attr_path = FAN_DIR + self.fan_pwm + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + pwm = int(attr_rv,10)if attr_rv else 0 + speed = float(pwm*100/MAX_PWM) + + return int(speed) + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return 20 + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if self.is_psu_fan: + return self.STATUS_LED_COLOR_OFF + + attr_grn_path = FAN_DIR + self.fan_status_led_green_color + attr_red_path = FAN_DIR + self.fan_status_led_red_color + + attr_grn_rv = self.__get_attr_value(attr_grn_path) + attr_red_rv = self.__get_attr_value(attr_red_path) + if (attr_grn_rv != 'ERR' and attr_red_rv != 'ERR'): + if (attr_grn_rv == '1'): + return self.STATUS_LED_COLOR_GREEN + elif (attr_red_rv == '1'): + return self.STATUS_LED_COLOR_RED + else: + return self.STATUS_LED_COLOR_OFF diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/platform.py new file mode 100644 index 000000000000..ddad8c4c5788 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/platform.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/psu.py new file mode 100644 index 000000000000..52dd2b12fb20 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/psu.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python +# +# Name: psu.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_platform_base.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PSU_DIR = "/sys/bus/i2c/devices/0-0066/" + +class Psu(PsuBase): + def __init__(self, index): + self.index = index + self.psu_presence_attr = "psu{}".format(self.index-1) + self.psu_status_attr = "psoc_psu{}_iout".format(self.index) + self.psu_power_in_attr = "power{}_input".format(self.index) + self.psu_power_out_attr = "power{}_input".format(self.index) + self.psu_voltage_out_attr = "psoc_psu{}_vin".format(self.index) + self.psu_current_out_attr = "psoc_psu{}_iout".format(self.index) + self.psu_serial_attr = "psoc_psu{}_serial".format(self.index) + self.psu_model_attr = "psoc_psu{}_vender".format(self.index) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = PSU_DIR+self.psu_presence_attr + attr_normal = "0 : normal" + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == attr_normal): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + model = "N/A" + attr_path = PSU_DIR+self.psu_model_attr + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + model = attr_rv + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + serial = "N/A" + attr_path = PSU_DIR+self.psu_serial_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + serial = attr_rv + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + attr_path = PSU_DIR+self.psu_status_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) != 0): + status = True + + return status + +############################################## +# PSU methods +############################################## + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + voltage_out = 0.0 + attr_path = PSU_DIR+self.psu_voltage_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + voltage_out = float(attr_rv) / 1000 + + return voltage_out + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + current_out = 0.0 + attr_path = PSU_DIR+self.psu_current_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + current_out = float(attr_rv) / 1000 + + return current_out + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, e.g. 302.6 + """ + power_out = 0.0 + attr_path = PSU_DIR+self.psu_power_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + power_out = float(attr_rv) / 1000000 + + return power_out + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py new file mode 100644 index 000000000000..47d88afa13a4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py @@ -0,0 +1,1285 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +# +############################################################################# + +import os +import time +import subprocess +import sonic_device_util +from ctypes import create_string_buffer + +try: + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_eeprom import eeprom_dts + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 128 +DOM_OFFSET = 0 + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 2 + +XCVR_INTERFACE_DATA_START = 0 +XCVR_INTERFACE_DATA_SIZE = 92 + +QSFP_DOM_BULK_DATA_START = 22 +QSFP_DOM_BULK_DATA_SIZE = 36 +SFP_DOM_BULK_DATA_START = 96 +SFP_DOM_BULK_DATA_SIZE = 10 + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 + +# Offset for values in QSFP eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_VERSION_COMPLIANCE_OFFSET = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 1 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_MODULE_MONITOR_OFFSET = 0 +QSFP_MODULE_MONITOR_WIDTH = 9 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_POWEROVERRIDE_BIT = 0 +QSFP_POWERSET_BIT = 1 +QSFP_OPTION_VALUE_OFFSET = 192 +QSFP_OPTION_VALUE_WIDTH = 4 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_CHANNL_STATUS_OFFSET = 110 +SFP_CHANNL_STATUS_WIDTH = 1 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes','FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia','FibreChannelSpeed') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +SFP_TYPE = "SFP" +QSFP_TYPE = "QSFP" +OSFP_TYPE = "OSFP" + + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + # Port number + PORT_START = 0 + PORT_END = 53 + + # Path to QSFP sysfs + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + HOST_CHK_CMD = "docker > /dev/null 2>&1" + + PLATFORM = "x86_64-inventec_d7054q28b-r0" + HWSKU = "INVENTEC-D7054Q28B-S48-Q6" + + def __init__(self, sfp_index, sfp_type): + # Init index + self.index = sfp_index + self.port_num = self.index + self.dom_supported = False + self.sfp_type = sfp_type + self.__sfp_presence_attr = "/sys/class/swps/port{}/present".format(self.index) + self.__sfp_lpmode_attr = "/sys/class/swps/port{}/lpmod".format(self.index) + self.__sfp_reset_attr = "/sys/class/swps/port{}/reset".format(self.index) + # Init eeprom path + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' + self.port_to_eeprom_mapping = {} + self.port_to_i2c_mapping = { + 0: 10, + 1: 11, + 2: 12, + 3: 13, + 4: 14, + 5: 15, + 6: 16, + 7: 17, + 8: 18, + 9: 19, + 10: 20, + 11: 21, + 12: 22, + 13: 23, + 14: 24, + 15: 25, + 16: 26, + 17: 27, + 18: 28, + 19: 29, + 20: 30, + 21: 31, + 22: 32, + 23: 33, + 24: 34, + 25: 35, + 26: 36, + 27: 37, + 28: 38, + 29: 39, + 30: 40, + 31: 41, + 32: 42, + 33: 43, + 34: 44, + 35: 45, + 36: 46, + 37: 47, + 38: 48, + 39: 49, + 40: 50, + 41: 51, + 42: 52, + 43: 53, + 44: 54, + 45: 55, + 46: 56, + 47: 57, + 48: 58, + 49: 59, + 50: 60, + 51: 61, + 52: 62, + 53: 63 + } + + for x in range(self.PORT_START, self.PORT_END + 1): + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path + + self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + SfpBase.__init__(self) + + def __get_attr_value(self, attr_path): + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return "" + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + presence = False + attr_path = self.__sfp_presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + presence = True + + return presence + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def _dom_capability_detect(self): + if not self.get_presence(): + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + return + + if self.sfp_type == "QSFP": + self.calibration = 1 + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + offset = 128 + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qsfp_version_compliance_raw = self.__read_eeprom_specific_bytes(QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_OFFSET) + qsfp_version_compliance = int(qsfp_version_compliance_raw[0], 16) + qspf_dom_capability = int(qsfp_dom_capability_raw[0], 16) + if qsfp_version_compliance >= 0x08: + self.dom_temp_supported = (qspf_dom_capability & 0x20 != 0) + self.dom_volt_supported = (qspf_dom_capability & 0x10 != 0) + self.dom_rx_power_supported = (qspf_dom_capability & 0x08 != 0) + self.dom_tx_power_supported = (qspf_dom_capability & 0x04 != 0) + else: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = (qspf_dom_capability & 0x08 != 0) + self.dom_tx_power_supported = True + self.dom_supported = True + self.calibration = 1 + qsfp_option_value_raw = self.__read_eeprom_specific_bytes(QSFP_OPTION_VALUE_OFFSET, QSFP_OPTION_VALUE_WIDTH) + if qsfp_option_value_raw is not None: + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + self.optional_capability = sfpd_obj.parse_option_params(qsfp_option_value_raw, 0) + self.dom_tx_disable_supported = self.optional_capability['data']['TxDisable']['value'] == 'On' + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + elif self.sfp_type == "SFP": + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + return None + sfp_dom_capability_raw = self.__read_eeprom_specific_bytes(XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) + self.dom_supported = (sfp_dom_capability & 0x40 != 0) + if self.dom_supported: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + if sfp_dom_capability & 0x20 != 0: + self.calibration = 1 + elif sfp_dom_capability & 0x10 != 0: + self.calibration = 2 + else: + self.calibration = 0 + else: + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.dom_tx_disable_supported = (int(sfp_dom_capability_raw[1], 16) & 0x40 != 0) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + transceiver_info_dict = {} + compliance_code_dict = {} + + # ToDo: OSFP tranceiver info parsing not fully supported. + # in inf8628.py lack of some memory map definition + # will be implemented when the inf8628 memory map ready + if self.sfp_type == OSFP_TYPE: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + + sfpi_obj = inf8628InterfaceId() + if sfpi_obj is None: + return None + + sfp_type_raw = self.__read_eeprom_specific_bytes((offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes((offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes((offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes((offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + else: + return None + + transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = 'N/A' + transceiver_info_dict['vendor_date'] = 'N/A' + transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['encoding'] = 'N/A' + transceiver_info_dict['ext_identifier'] = 'N/A' + transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' + transceiver_info_dict['cable_type'] = 'N/A' + transceiver_info_dict['cable_length'] = 'N/A' + transceiver_info_dict['specification_compliance'] = 'N/A' + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + + else: + if self.sfp_type == QSFP_TYPE: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes(offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) + if sfp_interface_bulk_raw is None: + return None + + start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START + end = start + interface_info_bulk_width + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_NAME_WIDTH + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_PN_WIDTH + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START + end = start + vendor_rev_width + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_SN_WIDTH + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_OUI_WIDTH + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_interface_bulk_raw[start : end], 0) + + start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_DATE_WIDTH + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_interface_bulk_raw[start : end], 0) + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + if self.sfp_type == QSFP_TYPE: + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + # check present status + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not self.get_presence() or not sfpi_obj or not sfpd_obj: + return {} + + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability( + qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self._convert_string_to_num( + transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + if not self.dom_supported: + return False + + if self.sfp_type == OSFP_TYPE: + return False + elif self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + dom_module_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_MODULE_MONITOR_OFFSET), QSFP_MODULE_MONITOR_WIDTH) + + if dom_module_monitor_raw is not None: + return True + else: + return False + elif self.sfp_type == SFP_TYPE: + offset = 0 + sfpd_obj = sff8472Dom() + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + + if dom_channel_monitor_raw is not None: + return True + else: + return False + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + if not self.dom_supported: + return None + + rx_los_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x02 != 0) + else: + return None + return rx_los_list + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + if not self.dom_supported: + return None + + tx_fault_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + else: + return None + return tx_fault_list + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + if not self.dom_supported: + return None + + tx_disable_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0xC0 != 0) + else: + return None + return tx_disable_list + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + return tx_disabled + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + lpmode = False + attr_path = self.__sfp_lpmode_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + lpmode = True + + return lpmode + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + if self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self._read_eeprom_specific_bytes((offset + QSFP_CONTROL_OFFSET), QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + return ('On' == dom_control_data['data']['PowerOverride']) + else: + return NotImplementedError + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self._read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + else: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = 1 + + dom_temperature_raw = self._read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_volt_supported: + dom_voltage_raw = self._read_eeprom_specific_bytes((offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + sfpd_obj._calibration_type = self.calibration + + dom_voltage_raw = self._read_eeprom_specific_bytes((offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + tx_bias_list = [] + if self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Bias']['value'])) + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = self.calibration + + if self.dom_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TXBias']['value'])) + else: + return None + else: + return None + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX1Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX2Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX3Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX4Power']['value'])) + else: + return None + else: + return None + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RXPower']['value'])) + else: + return None + else: + return None + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Power']['value'])) + else: + return None + else: + return None + else: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TXPower']['value'])) + else: + return None + else: + return None + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + try: + reg_file = open(self.__sfp_reset_attr, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 0 + reg_file.write(hex(reg_value)) + reg_file.close() + + # Sleep 2 seconds to allow it to settle + time.sleep(2) + + # Flip the value back write back to the register to take port out of reset + try: + reg_file = open(self.__sfp_reset_attr, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 1 + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + if self.sfp_type == SFP_TYPE: + if self.dom_tx_disable_supported: + handle = self._open_sdk() + if handle is None: + return False + + tx_disable_mask = 1 << MCIA_ADDR_TX_DISABLE_BIT + if tx_disable: + tx_disable_bit = tx_disable_mask + else: + tx_disable_bit = 0 + + return self._write_i2c_via_mcia(2, 0x51, MCIA_ADDR_TX_DISABLE, tx_disable_bit, tx_disable_mask) + else: + return False + elif self.sfp_type == QSFP_TYPE: + if self.dom_tx_disable_supported: + channel_mask = 0x0f + if tx_disable: + disable_flag = channel_mask + else: + disable_flag = 0 + + return self._write_i2c_via_mcia(0, 0x50, MCIA_ADDR_TX_CHANNEL_DISABLE, disable_flag, channel_mask) + else: + return False + else: + return NotImplementedError + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + sysfsfile_eeprom = None + try: + channel_state = self.get_tx_disable_channel() + tx_enable_mask = [0xe, 0xd, 0xb, 0x7] + tx_disable_mask = [0x1, 0x3, 0x7, 0xf] + tx_disable_ctl = channel_state | tx_disable_mask[ + channel] if disable else channel_state & tx_enable_mask[channel] + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + return True + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + #print "self.index{}".format(self.index) + name = sfputil_helper.logical[self.index] or "Unknown" + return name + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/thermal.py new file mode 100644 index 000000000000..039067428321 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/thermal.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python + +############################################################################# +# Inventec d7264 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermal information +# +############################################################################# + +import os + +try: + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +THERMAL_PATH = "/sys/bus/i2c/devices/0-0066/" + +thermal_name_tup = ( + "FrontSide Temperature", + "FanBoard Temperature", + "NearASIC Temperature", + "Center(U10) Temperature", + "CPU Board Temperature", + "ASIC Temperature" +) + +class Thermal(ThermalBase): + """Platform-specific Thermal class""" + + def __init__(self, thermal_index): + self.index = thermal_index-1 + self.thermal_tmp = "temp{}_input".format(self.index) + + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return thermal_name_tup[self.index] + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + attr_path = THERMAL_PATH + self.thermal_tmp + return os.path.isfile(attr_path) + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + if (self.get_temperature() > 0): + status = True + + return status + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temperature = 0.0 + attr_path = THERMAL_PATH + self.thermal_tmp + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + temperature = float(attr_rv) / 1000 + + return temperature + diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d7054q28b.install b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d7054q28b.install index 0ffc0a4f92a3..a83009858d6d 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d7054q28b.install +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d7054q28b.install @@ -1,4 +1,5 @@ d7054q28b/utils/inventec_d7054_util.py usr/local/bin +d7054q28b/utils/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-inventec_d7054q28b-r0 common/utils/transceiver_monitor.py usr/share/sonic/device/x86_64-inventec_d7054q28b-r0/plugins common/utils/led_proc.py usr/share/sonic/device/x86_64-inventec_d7054q28b-r0/plugins common/utils/asic_monitor.py usr/share/sonic/device/x86_64-inventec_d7054q28b-r0/plugins diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/rules b/platform/broadcom/sonic-platform-modules-inventec/debian/rules index 6340540f0354..f6c1aa1b2e70 100755 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/rules +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/rules @@ -22,7 +22,7 @@ MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ - if [ $$mod = "d6356" ]; then \ + if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ]; then \ cd $(MOD_SRC_DIR)/$${mod}; \ python2 setup.py build; \ python2 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/utils; \ @@ -36,7 +36,7 @@ override_dh_auto_install: $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - if [ $$mod = "d6356" ]; then \ + if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ]; then \ cd $(MOD_SRC_DIR)/$${mod}; \ python2 setup.py install --root=$(MOD_SRC_DIR)/debian/platform-modules-$${mod} --install-layout=deb; \ cd $(MOD_SRC_DIR); \ From ee4ca2c0c5a37ccfab200645a6d66e6fe6a77d6a Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Thu, 17 Oct 2019 06:27:32 +0530 Subject: [PATCH 0073/1427] DellEMC : Platform2.0 API Implementation for Component [S6000, S6100, Z9100] (#3588) --- .../s6000/sonic_platform/chassis.py | 63 +------ .../s6000/sonic_platform/component.py | 130 +++++++++++++ .../s6100/sonic_platform/chassis.py | 177 +----------------- .../s6100/sonic_platform/component.py | 177 ++++++++++++++++++ .../s6100/sonic_platform/module.py | 47 +---- .../z9100/sonic_platform/chassis.py | 100 +--------- .../z9100/sonic_platform/component.py | 164 ++++++++++++++++ 7 files changed, 495 insertions(+), 363 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index 452598773651..005fdd15b269 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -18,6 +18,7 @@ from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal + from sonic_platform.component import Component except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -25,17 +26,7 @@ MAX_S6000_FAN = 3 MAX_S6000_PSU = 2 MAX_S6000_THERMAL = 10 - -BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version" -#components definitions -COMPONENT_BIOS = "BIOS" -COMPONENT_CPLD1 = "CPLD1" -COMPONENT_CPLD2 = "CPLD2" -COMPONENT_CPLD3 = "CPLD3" - -CPLD1_VERSION = 'system_cpld_ver' -CPLD2_VERSION = 'master_cpld_ver' -CPLD3_VERSION = 'slave_cpld_ver' +MAX_S6000_COMPONENT = 4 class Chassis(ChassisBase): @@ -87,11 +78,9 @@ def __init__(self): thermal = Thermal(i) self._thermal_list.append(thermal) - # Initialize component list - self._component_name_list.append(COMPONENT_BIOS) - self._component_name_list.append(COMPONENT_CPLD1) - self._component_name_list.append(COMPONENT_CPLD2) - self._component_name_list.append(COMPONENT_CPLD3) + for i in range(MAX_S6000_COMPONENT): + component = Component(i) + self._component_list.append(component) def _get_cpld_register(self, reg_name): rv = 'ERR' @@ -178,7 +167,7 @@ def get_system_eeprom_info(self): Returns: A dictionary where keys are the type code defined in - OCP ONIE TlvInfo EEPROM format and values are their + OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ return self.sys_eeprom.system_eeprom_info() @@ -200,46 +189,6 @@ def get_reboot_cause(self): return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) - def _get_command_result(self, cmdline): - try: - proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, - shell=True, stderr=subprocess.STDOUT) - stdout = proc.communicate()[0] - proc.wait() - result = stdout.rstrip('\n') - except OSError: - result = '' - - return result - - def _get_cpld_version(self,cpld_name): - """ - Cpld Version - """ - cpld_ver = int(self._get_cpld_register(cpld_name),16) - return cpld_ver - - def get_firmware_version(self, component_name): - """ - Retrieves platform-specific hardware/firmware versions for - chassis componenets such as BIOS, CPLD, FPGA, etc. - Args: - component_name: A string, the component name. - Returns: - A string containing platform-specific component versions - """ - if component_name in self._component_name_list : - if component_name == COMPONENT_BIOS: - return self._get_command_result(BIOS_QUERY_VERSION_COMMAND) - elif component_name == COMPONENT_CPLD1: - return self._get_cpld_version(CPLD1_VERSION) - elif component_name == COMPONENT_CPLD2: - return self._get_cpld_version(CPLD2_VERSION) - elif component_name == COMPONENT_CPLD3: - return self._get_cpld_version(CPLD3_VERSION) - - return None - def _get_transceiver_status(self): presence_ctrl = self.sfp_control + 'qsfp_modprs' try: diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py new file mode 100644 index 000000000000..daa30eaafa3b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python + +######################################################################## +# DELLEMC S6000 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import os + import subprocess + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version" + + +class Component(ComponentBase): + """DellEMC Platform-specific Component class""" + + CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0" + + CHASSIS_COMPONENTS = [ + ["BIOS", ("Performs initialization of hardware components during " + "booting")], + ["System-CPLD", "Used for managing CPU board devices and power"], + ["Master-CPLD", ("Used for managing Fan, PSU, system LEDs, QSFP " + "modules (1-16)")], + ["Slave-CPLD", "Used for managing QSFP modules (17-32)"] + ] + + def __init__(self, component_index): + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + + def _get_cpld_register(self, reg_name): + rv = 'ERR' + mb_reg_file = self.CPLD_DIR+'/'+reg_name + + if (not os.path.isfile(mb_reg_file)): + return rv + + try: + with open(mb_reg_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_cpld_version(self, cpld_number): + cpld_version_reg = { + 1: "system_cpld_ver", + 2: "master_cpld_ver", + 3: "slave_cpld_ver" + } + + cpld_version = self._get_cpld_register(cpld_version_reg[cpld_number]) + + if cpld_version != 'ERR': + return str(int(cpld_version, 16)) + else: + return 'NA' + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + if self.index == 0: + bios_ver = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) + + if not bios_ver: + return 'NA' + else: + return bios_ver + + elif self.index <= 3: + return self._get_cpld_version(self.index) + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py index fd9816d6ed32..e39e8480e2c7 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py @@ -10,11 +10,6 @@ try: import os - import sys - import click - import subprocess - import glob - import sonic_device_util from sonic_platform_base.platform_base import PlatformBase from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp @@ -22,6 +17,7 @@ from sonic_platform.fan import Fan from sonic_platform.module import Module from sonic_platform.thermal import Thermal + from sonic_platform.component import Component from eeprom import Eeprom except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -30,12 +26,7 @@ MAX_S6100_FAN = 4 MAX_S6100_PSU = 2 MAX_S6100_THERMAL = 10 - -BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version" -#components definitions -COMPONENT_BIOS = "BIOS" -SWITCH_CPLD = "CPLD" -SMF_FPGA = "FPGA1" +MAX_S6100_COMPONENT = 3 class Chassis(ChassisBase): @@ -80,10 +71,9 @@ def __init__(self): thermal = Thermal(i) self._thermal_list.append(thermal) - # Initialize component list - self._component_name_list.append(COMPONENT_BIOS) - self._component_name_list.append(SWITCH_CPLD) - self._component_name_list.append(SMF_FPGA) + for i in range(MAX_S6100_COMPONENT): + component = Component(i) + self._component_list.append(component) def _get_reboot_reason_smf_register(self): # Returns 0xAA on software reload @@ -111,19 +101,6 @@ def _get_pmc_register(self, reg_name): rv = rv.lstrip(" ") return rv - # Run bash command and print output to stdout - def run_command(self, command): - click.echo(click.style("Command: ", fg='cyan') + - click.style(command, fg='green')) - - proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) - (out, err) = proc.communicate() - - click.echo(out) - - if proc.returncode != 0: - sys.exit(proc.returncode) - def get_name(self): """ Retrieves the name of the chassis @@ -234,147 +211,3 @@ def get_reboot_cause(self): return (self.reset_reason_dict[reset_reason], None) return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") - - def _get_command_result(self, cmdline): - try: - proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, - shell=True, stderr=subprocess.STDOUT) - stdout = proc.communicate()[0] - proc.wait() - result = stdout.rstrip('\n') - except OSError: - result = '' - - return result - - def _get_cpld_version(self): - io_resource = "/dev/port" - CPLD1_VERSION_ADDR = 0x100 - - fd = os.open(io_resource, os.O_RDONLY) - if (fd < 0): - return 'NA' - if (os.lseek(fd, CPLD1_VERSION_ADDR, os.SEEK_SET) - != CPLD1_VERSION_ADDR): - return 'NA' - - buf = os.read(fd, 1) - cpld_version = ord(buf) - os.close(fd) - - return "%d.%d" % (((cpld_version & 0xF0) >> 4), cpld_version & 0xF) - - def _get_fpga_version(self): - fpga_ver = float(self._get_pmc_register('smf_firmware_ver')) - return fpga_ver - - def get_firmware_version(self, component_name): - """ - Retrieves platform-specific hardware/firmware versions for - chassis componenets such as BIOS, CPLD, FPGA, etc. - Args: - component_name: A string, the component name. - Returns: - A string containing platform-specific component versions - """ - if component_name in self._component_name_list : - if component_name == COMPONENT_BIOS: - return self._get_command_result(BIOS_QUERY_VERSION_COMMAND) - elif component_name == SWITCH_CPLD: - return self._get_cpld_version() - elif component_name == SMF_FPGA: - return self._get_fpga_version() - - return None - - def install_component_firmware(self, component_name, image_path): - - bios_image = None - bios_version = "3.25.0." - bios_file_name = "S6100*BIOS*" - flashrom = "/usr/local/bin/flashrom" - PLATFORM_ROOT_PATH = '/usr/share/sonic/device' - machine_info = sonic_device_util.get_machine_info() - platform = sonic_device_util.get_platform_info(machine_info) - platform_path = "/".join([PLATFORM_ROOT_PATH, platform, "bin"]) - - warning = """ - ******************************************************************** - * Warning - Upgrading BIOS is inherently risky and should only be * - * attempted when necessary. A failure at this upgrade may cause * - * a board RMA. Proceed with caution ! * - ******************************************************************** - """ - - if component_name in self._component_name_list: - if component_name == COMPONENT_BIOS: # BIOS - - # current BIOS version - current_bios_version = self.get_firmware_version("BIOS") - - # Construct BIOS image path - if image_path is not None: - image_path = image_path + platform_path - for name in glob.glob( - os.path.join(image_path, bios_file_name)): - bios_image = image_path = name - - if not bios_image: - print "BIOS image file not found:", image_path - return False - - # Extract BIOS image version - bios_image = os.path.basename(bios_image) - bios_image = bios_image.strip('S6100-BIOS-') - bios_image_version = bios_image.strip('.bin') - - if bios_image_version.startswith(bios_version): - bios_image_minor = bios_image_version.replace( - bios_image_version[:7], '') - if bios_image_minor.startswith("2"): - bios_image_minor = bios_image_minor.split("-")[1] - - if current_bios_version.startswith(bios_version): - current_bios_minor = current_bios_version.replace( - current_bios_version[:7], '') - if current_bios_minor.startswith("2"): - current_bios_minor = current_bios_minor.split("-")[1] - - # BIOS version check - if bios_image_minor > current_bios_minor: - - print warning - prompt_text = "New BIOS image " + bios_image_version + \ - " available to install, continue?" - yes = click.confirm(prompt_text) - - elif current_bios_minor > bios_image_minor: - - print warning - prompt_text = "Do you want to downgrade BIOS image from " \ - + current_bios_version + " to " + \ - bios_image_version + " continue?" - - yes = click.confirm(prompt_text) - - else: - print("BIOS is already with {} latest version".format( - current_bios_version)) - return True - - if yes: - command = flashrom + " -p" + " internal" + " -w " + \ - image_path - self.run_command(command) - - elif component_name == SWITCH_CPLD: # CPLD - return False - - elif component_name == SMF_FPGA: # SMF - return False - else: - print "Invalid component Name:", component_name - - return True - - diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py new file mode 100644 index 000000000000..a92ab5c85db2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python + +######################################################################## +# DELLEMC S6100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import os + import subprocess + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version" + + +class Component(ComponentBase): + """DellEMC Platform-specific Component class""" + + HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" + HWMON_NODE = os.listdir(HWMON_DIR)[0] + MAILBOX_DIR = HWMON_DIR + HWMON_NODE + + CHASSIS_COMPONENTS = [ + ["BIOS", ("Performs initialization of hardware components during " + "booting")], + ["CPLD", "Used for managing IO modules, SFP+ modules and system LEDs"], + ["FPGA", ("Platform management controller for on-board temperature " + "monitoring, in-chassis power, Fan and LED control")] + ] + MODULE_COMPONENT = [ + "IOM{}-CPLD", + "Used for managing QSFP+ modules ({0}-{1})" + ] + + def __init__(self, component_index=0, + is_module=False, iom_index=0, i2c_line=0): + + self.is_module_component = is_module + + if self.is_module_component: + self.index = iom_index + self.name = self.MODULE_COMPONENT[0].format(self.index) + self.description = self.MODULE_COMPONENT[1].format( + ((self.index - 1) * 16) + 1, self.index * 16) + self.cpld_version_file = ("/sys/class/i2c-adapter/i2c-{0}/{0}-003e" + "/iom_cpld_vers").format(i2c_line) + else: + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # sysfs_file and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_cpld_version(self): + io_resource = "/dev/port" + CPLD_VERSION_ADDR = 0x100 + + fd = os.open(io_resource, os.O_RDONLY) + if (fd < 0): + return 'NA' + + if (os.lseek(fd, CPLD_VERSION_ADDR, os.SEEK_SET) != CPLD_VERSION_ADDR): + os.close(fd) + return 'NA' + + buf = os.read(fd, 1) + cpld_version = str(ord(buf)) + os.close(fd) + + return cpld_version + + def _get_iom_cpld_version(self): + ver_str = self._read_sysfs_file(self.cpld_version_file) + if (ver_str != 'ERR'): + if ver_str == 'read error': + return 'NA' + + ver_str = ver_str.rstrip('\r\n') + cpld_version = str(int(ver_str.split(':')[1], 16)) + return cpld_version + else: + return 'NA' + + def _get_fpga_version(self): + fpga_ver_file = self.MAILBOX_DIR + '/smf_firmware_ver' + fpga_ver = self._read_sysfs_file(fpga_ver_file) + if (fpga_ver != 'ERR'): + return fpga_ver + else: + return 'NA' + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + if self.is_module_component: # IOM CPLD + return self._get_iom_cpld_version() + else: + if self.index == 0: # BIOS + bios_ver = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) + + if not bios_ver: + return 'NA' + else: + return bios_ver + + elif self.index == 1: # SwitchCard CPLD + return self._get_cpld_version() + elif self.index == 2: # FPGA + return self._get_fpga_version() + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py index 6b950c4e8366..265dc206ad0c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py @@ -13,6 +13,7 @@ import os from sonic_platform_base.module_base import ModuleBase from sonic_platform.sfp import Sfp + from sonic_platform.component import Component except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -54,16 +55,20 @@ def __init__(self, module_index): self.port_start = (self.index - 1) * 16 self.port_end = (self.index * 16) - 1 self.port_i2c_line = self.IOM_I2C_MAPPING[self.index] - self._component_name_list = ['CPLD'] self.eeprom_tlv_dict = dict() self.iom_status_reg = "iom_status" self.iom_presence_reg = "iom_presence" - # Overriding _sfp_list class variable defined in ModuleBase, to - # make it unique per Module object + # Overriding _component_list and _sfp_list class variables defined in + # ModuleBase, to make them unique per Module object + self._component_list = [] self._sfp_list = [] + component = Component(is_module=True, iom_index=self.index, + i2c_line=self.port_i2c_line) + self._component_list.append(component) + eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/i2c-{1}/{1}-0050/eeprom" sfp_ctrl_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-003e/" @@ -188,39 +193,3 @@ def get_system_eeprom_info(self): ‘0x26’:’01’, ‘0x27’:’REV01’, ‘0x28’:’AG9064-C2358-16G’} """ return self.eeprom_tlv_dict - - def get_firmware_version(self, component_name): - """ - Retrieves platform-specific hardware/firmware versions for module - componenets such as BIOS, CPLD, FPGA, etc. - - Args: - component_name: A string, the component name. - - Returns: - A string containing platform-specific component versions - """ - if component_name == 'CPLD': - cpld_version_file = ("/sys/class/i2c-adapter/i2c-{0}/{0}-003e/" - "iom_cpld_vers").format(self.port_i2c_line) - - if (not os.path.isfile(cpld_version_file)): - return 'NA' - - try: - with open(cpld_version_file, 'r') as fd: - ver_str = fd.read() - except Exception as error: - return 'NA' - - if ver_str == 'read error': - return 'NA' - - ver_str = ver_str.rstrip('\r\n') - cpld_version = int(ver_str.split(':')[1], 16) - major_version = (cpld_version & 0xF0) >> 4 - minor_version = cpld_version & 0xF - - return "%d.%d" % (major_version, minor_version) - else: - return 'NA' diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index c3568b3b1e4c..3472bb3e7fb0 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py @@ -17,6 +17,7 @@ from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal + from sonic_platform.component import Component from eeprom import Eeprom except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -26,15 +27,7 @@ MAX_Z9100_FAN = 2 MAX_Z9100_PSU = 2 MAX_Z9100_THERMAL = 8 - -BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version" -#components definitions -COMPONENT_BIOS = "BIOS" -SWITCH_CPLD1 = "CPLD1" -SWITCH_CPLD2 = "CPLD2" -SWITCH_CPLD3 = "CPLD3" -SWITCH_CPLD4 = "CPLD4" -SMF_FPGA = "FPGA1" +MAX_Z9100_COMPONENT = 6 class Chassis(ChassisBase): @@ -115,13 +108,9 @@ def __init__(self): thermal = Thermal(i) self._thermal_list.append(thermal) - # Initialize component list - self._component_name_list.append(COMPONENT_BIOS) - self._component_name_list.append(SWITCH_CPLD1) - self._component_name_list.append(SWITCH_CPLD2) - self._component_name_list.append(SWITCH_CPLD3) - self._component_name_list.append(SWITCH_CPLD4) - self._component_name_list.append(SMF_FPGA) + for i in range(MAX_Z9100_COMPONENT): + component = Component(i) + self._component_list.append(component) def _get_pmc_register(self, reg_name): # On successful read, returns the value read from given @@ -241,82 +230,3 @@ def get_reboot_cause(self): return (self.reset_reason_dict[reset_reason], None) return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") - - def _get_command_result(self, cmdline): - try: - proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, - shell=True, stderr=subprocess.STDOUT) - stdout = proc.communicate()[0] - proc.wait() - result = stdout.rstrip('\n') - except OSError: - result = '' - - return result - - def _get_cpld_version(self,cpld_number): - io_resource = "/dev/port" - CPLD1_VERSION_ADDR = 0x100 - - if (cpld_number == 1): - fd = os.open(io_resource, os.O_RDONLY) - if (fd < 0): - return 'NA' - if (os.lseek(fd, CPLD1_VERSION_ADDR, os.SEEK_SET) - != CPLD1_VERSION_ADDR): - return 'NA' - - buf = os.read(fd, 1) - cpld_version = ord(buf) - os.close(fd) - - return "%d.%d" % (((cpld_version & 0xF0) >> 4), cpld_version & 0xF) - else: - cpld_version_file = ("/sys/class/i2c-adapter/i2c-{0}/{0}-003e" - "/iom_cpld_vers").format(12 + cpld_number) - - if (not os.path.isfile(cpld_version_file)): - return 'NA' - - try: - with open(cpld_version_file, 'r') as fd: - ver_str = fd.read() - except Exception as error: - return 'NA' - - if ver_str == "read error": - return 'NA' - else: - ver_str = ver_str.rstrip("\r\n") - cpld_version = int(ver_str.split(":")[1], 16) - - return "%d.%d" % (((cpld_version & 0xF0) >> 4), cpld_version & 0xF) - - def _get_fpga_version(self): - fpga_ver = float(self._get_pmc_register('smf_firmware_ver')) - return fpga_ver - - def get_firmware_version(self, component_name): - """ - Retrieves platform-specific hardware/firmware versions for chassis - componenets such as BIOS, CPLD, FPGA, etc. - Args: - component_name: A string, the component name. - Returns: - A string containing platform-specific component versions - """ - if component_name in self._component_name_list : - if component_name == COMPONENT_BIOS: - return self._get_command_result(BIOS_QUERY_VERSION_COMMAND) - elif component_name == SWITCH_CPLD1: - return self._get_cpld_version(1) - elif component_name == SWITCH_CPLD2: - return self._get_cpld_version(2) - elif component_name == SWITCH_CPLD3: - return self._get_cpld_version(3) - elif component_name == SWITCH_CPLD4: - return self._get_cpld_version(4) - elif component_name == SMF_FPGA: - return self._get_fpga_version() - - return None diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py new file mode 100644 index 000000000000..dccb8f6ac2dc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python + +######################################################################## +# DELLEMC Z9100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import os + import subprocess + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version" + + +class Component(ComponentBase): + """DellEMC Platform-specific Component class""" + + HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" + HWMON_NODE = os.listdir(HWMON_DIR)[0] + MAILBOX_DIR = HWMON_DIR + HWMON_NODE + + CHASSIS_COMPONENTS = [ + ["BIOS", ("Performs initialization of hardware components during " + "booting")], + ["CPLD1", "Used for managing the system LEDs"], + ["CPLD2", "Used for managing QSFP28 modules (1-12)"], + ["CPLD3", "Used for managing QSFP28 modules (13-22)"], + ["CPLD4", ("Used for managing QSFP28 modules (23-32) and SFP+ " + "modules")], + ["FPGA", ("Platform management controller for on-board temperature " + "monitoring, in-chassis power, Fan and LED control")] + ] + + def __init__(self, component_index=0): + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # sysfs_file and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_cpld_version(self, cpld_number): + io_resource = "/dev/port" + CPLD1_VERSION_ADDR = 0x100 + + if (cpld_number == 1): + fd = os.open(io_resource, os.O_RDONLY) + if (fd < 0): + return 'NA' + + if (os.lseek(fd, CPLD1_VERSION_ADDR, os.SEEK_SET) + != CPLD1_VERSION_ADDR): + os.close(fd) + return 'NA' + + buf = os.read(fd, 1) + cpld_version = str(ord(buf)) + os.close(fd) + + return cpld_version + else: + cpld_version_file = ("/sys/class/i2c-adapter/i2c-{0}/{0}-003e" + "/iom_cpld_vers").format(12 + cpld_number) + ver_str = self._read_sysfs_file(cpld_version_file) + + if (ver_str == "read error") or (ver_str == 'ERR'): + return 'NA' + + ver_str = ver_str.rstrip("\r\n") + cpld_version = str(int(ver_str.split(":")[1], 16)) + + return cpld_version + + def _get_fpga_version(self): + fpga_ver_file = self.MAILBOX_DIR + '/smf_firmware_ver' + fpga_ver = self._read_sysfs_file(fpga_ver_file) + if (fpga_ver != 'ERR'): + return fpga_ver + else: + return 'NA' + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + if self.index == 0: # BIOS + bios_ver = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) + + if not bios_ver: + return 'NA' + else: + return bios_ver + + elif self.index < 5: # CPLD + return self._get_cpld_version(self.index) + elif self.index == 5: # FPGA + return self._get_fpga_version() + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + return False From 4d8a01c26c6e19773e4e551d1316562ef30900e8 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 17 Oct 2019 09:01:38 +0800 Subject: [PATCH 0074/1427] [device] as4630-54pe: update sfputil for get_transceiver_change_event. (#3315) Signed-off-by: roy_lee --- .../Accton-AS4630-54PE/port_config.ini | 110 ++++++------ .../plugins/sfputil.py | 163 ++++++++++++++---- .../as4630-54pe/classes/fanutil.py | 30 +--- .../as4630-54pe/classes/thermalutil.py | 10 +- .../as4630-54pe-platform-monitor.service | 1 - .../as4630-54pe/utils/README | 78 ++------- 6 files changed, 200 insertions(+), 192 deletions(-) diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini index d008d016ef5c..aabb372bf649 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini +++ b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini @@ -1,55 +1,55 @@ -# name lanes alias index -Ethernet0 26 thousandE1 0 -Ethernet1 25 thousandE2 1 -Ethernet2 28 thousandE3 2 -Ethernet3 27 thousandE4 3 -Ethernet4 30 thousandE5 4 -Ethernet5 29 thousandE6 5 -Ethernet6 32 thousandE7 6 -Ethernet7 31 thousandE8 7 -Ethernet8 38 thousandE9 8 -Ethernet9 37 thousandE10 9 -Ethernet10 40 thousandE11 10 -Ethernet11 39 thousandE12 11 -Ethernet12 34 thousandE13 12 -Ethernet13 33 thousandE14 13 -Ethernet14 36 thousandE15 14 -Ethernet15 35 thousandE16 15 -Ethernet16 46 thousandE17 16 -Ethernet17 45 thousandE18 17 -Ethernet18 48 thousandE19 18 -Ethernet19 47 thousandE20 19 -Ethernet20 42 thousandE21 20 -Ethernet21 41 thousandE22 21 -Ethernet22 44 thousandE23 22 -Ethernet23 43 thousandE24 23 -Ethernet24 2 thousandE25 24 -Ethernet25 1 thousandE26 25 -Ethernet26 4 thousandE27 26 -Ethernet27 3 thousandE28 27 -Ethernet28 6 thousandE29 28 -Ethernet29 5 thousandE30 29 -Ethernet30 8 thousandE31 30 -Ethernet31 7 thousandE32 31 -Ethernet32 10 thousandE33 32 -Ethernet33 9 thousandE34 33 -Ethernet34 12 thousandE35 34 -Ethernet35 11 thousandE36 35 -Ethernet36 14 thousandE37 36 -Ethernet37 13 thousandE38 37 -Ethernet38 16 thousandE39 38 -Ethernet39 15 thousandE40 39 -Ethernet40 18 thousandE41 40 -Ethernet41 17 thousandE42 41 -Ethernet42 20 thousandE43 42 -Ethernet43 19 thousandE44 43 -Ethernet44 22 thousandE45 44 -Ethernet45 21 thousandE46 45 -Ethernet46 24 thousandE47 46 -Ethernet47 23 thousandE48 47 -Ethernet48 67 twentyfiveGigE49 48 -Ethernet49 66 twentyfiveGigE50 49 -Ethernet50 65 twentyfiveGigE51 50 -Ethernet51 68 twentyfiveGigE52 51 -Ethernet52 73,74,75,76 hundredGigE53 52 -Ethernet56 69,70,71,72 hundredGigE54 56 +# name lanes alias index speed +Ethernet0 26 thousandE1 1 1000 +Ethernet1 25 thousandE2 2 1000 +Ethernet2 28 thousandE3 3 1000 +Ethernet3 27 thousandE4 4 1000 +Ethernet4 30 thousandE5 5 1000 +Ethernet5 29 thousandE6 6 1000 +Ethernet6 32 thousandE7 7 1000 +Ethernet7 31 thousandE8 8 1000 +Ethernet8 38 thousandE9 9 1000 +Ethernet9 37 thousandE10 10 1000 +Ethernet10 40 thousandE11 11 1000 +Ethernet11 39 thousandE12 12 1000 +Ethernet12 34 thousandE13 13 1000 +Ethernet13 33 thousandE14 14 1000 +Ethernet14 36 thousandE15 15 1000 +Ethernet15 35 thousandE16 16 1000 +Ethernet16 46 thousandE17 17 1000 +Ethernet17 45 thousandE18 18 1000 +Ethernet18 48 thousandE19 19 1000 +Ethernet19 47 thousandE20 20 1000 +Ethernet20 42 thousandE21 21 1000 +Ethernet21 41 thousandE22 22 1000 +Ethernet22 44 thousandE23 23 1000 +Ethernet23 43 thousandE24 24 1000 +Ethernet24 2 thousandE25 25 1000 +Ethernet25 1 thousandE26 26 1000 +Ethernet26 4 thousandE27 27 1000 +Ethernet27 3 thousandE28 28 1000 +Ethernet28 6 thousandE29 29 1000 +Ethernet29 5 thousandE30 30 1000 +Ethernet30 8 thousandE31 31 1000 +Ethernet31 7 thousandE32 32 1000 +Ethernet32 10 thousandE33 33 1000 +Ethernet33 9 thousandE34 34 1000 +Ethernet34 12 thousandE35 35 1000 +Ethernet35 11 thousandE36 36 1000 +Ethernet36 14 thousandE37 37 1000 +Ethernet37 13 thousandE38 38 1000 +Ethernet38 16 thousandE39 39 1000 +Ethernet39 15 thousandE40 40 1000 +Ethernet40 18 thousandE41 41 1000 +Ethernet41 17 thousandE42 42 1000 +Ethernet42 20 thousandE43 43 1000 +Ethernet43 19 thousandE44 44 1000 +Ethernet44 22 thousandE45 45 1000 +Ethernet45 21 thousandE46 46 1000 +Ethernet46 24 thousandE47 47 1000 +Ethernet47 23 thousandE48 48 1000 +Ethernet48 67 twentyfiveGigE49 49 25000 +Ethernet49 66 twentyfiveGigE50 50 25000 +Ethernet50 65 twentyfiveGigE51 51 25000 +Ethernet51 68 twentyfiveGigE52 52 25000 +Ethernet52 73,74,75,76 hundredGigE53 53 100000 +Ethernet56 69,70,71,72 hundredGigE54 54 100000 diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py index 69c2870669e7..cb18eb0d540c 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py @@ -4,34 +4,39 @@ # try: + import sys import time + import string + from ctypes import create_string_buffer from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +SFP_STATUS_INSERTED = '1' +SFP_STATUS_REMOVED = '0' class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" - - PORT_START = 48 - PORT_END = 53 + PORT_START = 49 + PORT_END = 54 PORTS_IN_BLOCK = 54 - + QSFP_START = 53 + BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" BASE_CPLD_PATH = "/sys/bus/i2c/devices/3-0060/" - + _port_to_is_present = {} _port_to_lp_mode = {} _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 48: [18], - 49: [19], - 50: [20], - 51: [21], - 52: [22], - 53: [23], + 49: [18], + 50: [19], + 51: [20], + 52: [21], + 53: [22], + 54: [23], } @property @@ -41,7 +46,7 @@ def port_start(self): @property def port_end(self): return self.PORT_END - + @property def qsfp_ports(self): return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) @@ -52,28 +57,23 @@ def port_to_eeprom_mapping(self): def __init__(self): eeprom_path = self.BASE_OOM_PATH + "eeprom" - - for x in range(0, self.port_end+1): - if x < 48: - self.port_to_eeprom_mapping[x] = eeprom_path.format(0) - else: - self.port_to_eeprom_mapping[x] = eeprom_path.format( - self._port_to_i2c_mapping[x][0]) - + for x in range(self.port_start, self.port_end+1): + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x][0]) SfpUtilBase.__init__(self) def get_presence(self, port_num): # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False - - present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num+1) + + present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num) self.__port_to_is_present = present_path try: val_file = open(self.__port_to_is_present) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to open file: %s" % str(e) return False content = val_file.readline().rstrip() @@ -84,20 +84,113 @@ def get_presence(self, port_num): return True return False - - def get_low_power_mode(self, port_num): - raise NotImplementedError - def set_low_power_mode(self, port_num, lpmode): - raise NotImplementedError + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.QSFP_START or port_num > self.port_end: + return False + + try: + eeprom = None + if not self.get_presence(port_num): + return False + eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") + eeprom.seek(93) + lpmode = ord(eeprom.read(1)) + + # if "Power override" bit is 1 and "Power set" bit is 1 + if ((lpmode & 0x3) == 0x3): + return True + + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + else: + return False + + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.QSFP_START or port_num > self.port_end: + return False + + try: + eeprom = None + if not self.get_presence(port_num): + return False # Port is not present, unable to set the eeprom + + # Fill in write buffer + # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 + + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") + eeprom.seek(93) + eeprom.write(buffer[0]) + return True + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) def reset(self, port_num): raise NotImplementedError - def get_transceiver_change_event(self): - """ - TODO: This function need to be implemented - when decide to support monitoring SFP(Xcvrd) - on this platform. - """ - raise NotImplementedError + @property + def _get_presence_bitmap(self): + + bits = [] + for x in range(self.port_start, self.port_end+1): + bits.append(str(int(self.get_presence(x)))) + + rev = "".join(bits[::-1]) + return int(rev,2) + + data = {'present':0} + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + + if timeout == 0: + cd_ms = sys.maxint + else: + cd_ms = timeout + + #poll per second + while cd_ms > 0: + reg_value = self._get_presence_bitmap + changed_ports = self.data['present'] ^ reg_value + if changed_ports != 0: + break + time.sleep(1) + cd_ms = cd_ms - 1000 + + if changed_ports != 0: + for port in range (self.port_start, self.port_end+1): + # Mask off the bit corresponding to our port + mask = (1 << (port - self.port_start)) + if changed_ports & mask: + if (reg_value & mask) == 0: + port_dict[port] = SFP_STATUS_REMOVED + else: + port_dict[port] = SFP_STATUS_INSERTED + + # Update cache + self.data['present'] = reg_value + return True, port_dict + else: + return True, {} + return False, {} + diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py index ca0f3f9da1e3..b6752783dc03 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py @@ -180,8 +180,6 @@ def get_fan_to_device_path(self, fan_num, node_num): def get_fan_fault(self, fan_num): return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) - #def get_fan_speed(self, fan_num): - # return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) def get_fan_dir(self, fan_num): return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) @@ -196,17 +194,9 @@ def get_fan_duty_cycle(self): content = val_file.readline().rstrip() val_file.close() - return int(content) - #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) -#static u32 reg_val_to_duty_cycle(u8 reg_val) -#{ -# reg_val &= FAN_DUTY_CYCLE_REG_MASK; -# return ((u32)(reg_val+1) * 625 + 75)/ 100; -#} -# + def set_fan_duty_cycle(self, val): - try: fan_file = open(self.FAN_DUTY_PATH, 'r+') except IOError as e: @@ -217,9 +207,6 @@ def set_fan_duty_cycle(self, val): fan_file.close() return True - #def get_fanr_fault(self, fan_num): - # return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) - def get_fanr_speed(self, fan_num): return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) @@ -232,20 +219,5 @@ def get_fan_status(self, fan_num): logging.debug('GET. FAN fault. fan_num, %d', fan_num) return False - #if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: - # logging.debug('GET. FANR fault. fan_num, %d', fan_num) - # return False - return True -#def main(): -# fan = FanUtil() -# -# print 'get_size_node_map : %d' % fan.get_size_node_map() -# print 'get_size_path_map : %d' % fan.get_size_path_map() -# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): -# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): -# print fan.get_fan_to_device_path(x, y) -# -#if __name__ == '__main__': -# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py index 96163f1d63ab..3af7b3d7df5f 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py @@ -45,7 +45,6 @@ class ThermalUtil(object): """ Dictionary where key1 = thermal id index (integer) starting from 1 value = path to fan device file (string) """ - #_thermal_to_device_path_mapping = {} _thermal_to_device_node_mapping = { THERMAL_NUM_1_IDX: ['55', '48'], @@ -121,11 +120,6 @@ def main(): print "termal3=%d" %thermal._get_thermal_val(3) print "termal4=%d" %thermal._get_thermal_val(4) print "termal5=%d" %thermal._get_thermal_val(5) -# -# print 'get_size_node_map : %d' % thermal.get_size_node_map() -# print 'get_size_path_map : %d' % thermal.get_size_path_map() -# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): -# print thermal.get_thermal_to_device_path(x) -# + if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service index 47bf4e81d82e..8ed60fca95f3 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service @@ -9,7 +9,6 @@ ExecStartPre=/usr/local/bin/accton_as4630_54pe_util.py install ExecStart=/usr/local/bin/accton_as4630_54pe_monitor.py KillSignal=SIGKILL SuccessExitStatus=SIGKILL -#StandardOutput=tty # Resource Limitations LimitCORE=infinity diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README index 44e03cab5f52..f656d2b0a855 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README @@ -1,4 +1,4 @@ -Copyright (C) 2016 Accton Networks, Inc. +Copyright (C) 2019 Accton Networks, Inc. This program is free software: you can redistribute it and/or modify It under the terms of the GNU General Public License as published by @@ -13,79 +13,29 @@ See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . -Contents of this package: - patch - files under patch/ is for kernel and ONIE installer - for the kernel: - config-accton-as5712_54x.patch - for kernel configuration. - driver-i2c-muxes-pca954x-always-deselect.patch - for i2c_mux deselects after transaction. - driver-patches-for-accton-as5712-fan-psu-cpld.patch - for as5712's fan/psu/cpld/led/sfp drivers. - for ONIE: - onie_installer-accton-AS5712-54X.patch - for console port setting and copy util script o rootfs. - module - Contains source code of as5712 kernel driver modules. - -The late Sonic building scripts, pushed @Dec 5 2016, will automatically -create a docker container and run building process under it. -User is not necessary to handle docker environment creation. - -1. Download sonic-buildimage environment. - - Run "git clone https://github.com/Azure/sonic-buildimage". - - cd to sonic-buildimage and run "git submodule update --init --recursive". -2. Build kernel - - cd ./src/sonic-linux-kernel - - Copy patches and series from patch/kernel of this release to - sonic-linux-kernel/patch. - - Build kernel by "make". - - The built kernel package, linux-image-3.16.0-5-amd64_3.16.51-3+deb8u1_amd64.deb - , is generated. -3. Build installer - - Change directory back to sonic-buildimage/. - - Get onie_installer-accton-AS5712-54X.patch" from patch/installer. - - Change setting for AS5712-54X by patching build_image.sh. - "patch -p1 < onie_installer-accton-AS5712-54X.patch" - !!NOTICE, patching onie_installer-accton-AS5712-54X.patch comments out the - "git status" checking at build_image.sh. - - The account and password of installed OS can be given at rules/config. - The default user and password are "admin" & "YourPaSsWoRd" respectively. - - Run "make configure PLATFORM=broadcom" - - Copy the built kernel debian package to target/debs/. - The file is linux-image-3.16.0-5-amd64_*_amd64.deb under directory - src/sonic-linux-kernel/. - - Run "make target/sonic-generic.bin" - - Get the installer, target/sonic-generic.bin, to target machine and install. - All Linux kernel code is licensed under the GPLv1. All other code is licensed under the GPLv3. Please see the LICENSE file for copies of both licenses. -The code for integacting with Accton AS5712-54X has 2 parts, +The code for integacting with Accton AS4630-54pe has 2 parts, kernel drivers and operational script. The kernel drivers of peripherals are under module/ directory. -1. These drivers are patched into kernel by - driver-patches-for-accton-as5712-fan-psu-cpld.patch - Or you can build the driver under module/ by setting environment variable, - KERNEL_SRC, to proper linux built directory and run make. - It may be sonic-linux-kernel/linux-3.*/debian/build/build_amd64_none_amd64/. -2. A operational script, accton_as5712_util.py, for device initializatian and +1. These drivers are at module dir. +2. A operational script, accton_as4630_util.py, for device initializatian and peripheral accessing should be installed at /usr/bin. - This script is generated by onie_installer-accton-AS5712-54X.patch. - It's done by patching onie_installer-accton-AS5712-54X.patch at build-image. - Run "accton_as5712_util.py install" to install drivers. + Run "accton_as4630_util.py install" to install drivers. -To initialize the system, run "accton_as5712_util.py install". -To clean up the drivers & devices, run "accton_as5712_util.py clean". -To dump information of sensors, run "accton_as5712_util.py show". -To dump SFP EEPROM, run "accton_as5712_util.py sff". -To set fan speed, run "accton_as5712_util.py set fan". -To enable/disable SFP emission, run "accton_as5712_util.py set sfp". -To set system LEDs' color, run "accton_as5712_util.py set led" -For more information, run "accton_as5712_util.py --help". +To initialize the system, run "accton_as4630_util.py install". +To clean up the drivers & devices, run "accton_as4630_util.py clean". +To dump information of sensors, run "accton_as4630_util.py show". +To dump SFP EEPROM, run "accton_as4630_util.py sff". +To set fan speed, run "accton_as4630_util.py set fan". +To enable/disable SFP emission, run "accton_as4630_util.py set sfp". +To set system LEDs' color, run "accton_as4630_util.py set led" +For more information, run "accton_as4630_util.py --help". ==================================================================== -Besides applying accton_as5712_util.py to access peripherals, you can +Besides applying accton_as4630_util.py to access peripherals, you can access peripherals by sysfs nodes directly after the installation is run. System LED: From 6ecec007e35d841612163a2aaeb2defc98e6a43d Mon Sep 17 00:00:00 2001 From: zzhiyuan Date: Wed, 16 Oct 2019 18:38:13 -0700 Subject: [PATCH 0075/1427] [arista]: Update arista drivers submodule (#3618) Fixed variable name causing problems for sonic-platform-commons for arista. --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 73dd2e0fe144..10750325b6cf 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 73dd2e0fe144e2bb6778d39d3e051c597bb1c9d8 +Subproject commit 10750325b6cfc7a1dc1a8b0734008bde1bb3ac06 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 73dd2e0fe144..10750325b6cf 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 73dd2e0fe144e2bb6778d39d3e051c597bb1c9d8 +Subproject commit 10750325b6cfc7a1dc1a8b0734008bde1bb3ac06 From 5d9bd9c1ad31987d10ac2ad127580b157107ea70 Mon Sep 17 00:00:00 2001 From: sudhanshukumar22 <51457531+sudhanshukumar22@users.noreply.github.com> Date: Thu, 17 Oct 2019 12:50:36 +0530 Subject: [PATCH 0076/1427] Port a fix from FRR community (#3614) Author: sudhanshukumar22 Date: Tue Oct 16 12:33:20 2019 -0700 https://github.com/donaldsharp/frr/commit/39c93f379a5b57c56739a339ad75ec06e30daef3 If we have a case where have created a fd for i/o and we have removed the handling thread but still have the fd in the poll data structure, there existed a case where we would get the handle this fd return from poll but we would immediately do nothing with it because we didn't have a thread to hand the event to. This leads to an infinite loop. Prevent the infinite loop from happening and log the problem. Signed-off-by: Preetham Singh (preetham.singh@broadcom.com) --- ...-dead-fd-poll-data-port-fix-from-frr.patch | 107 ++++++++++++++++++ src/sonic-frr/patch/series | 1 + 2 files changed, 108 insertions(+) create mode 100644 src/sonic-frr/patch/0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch diff --git a/src/sonic-frr/patch/0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch b/src/sonic-frr/patch/0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch new file mode 100644 index 000000000000..5954e5c7c53d --- /dev/null +++ b/src/sonic-frr/patch/0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch @@ -0,0 +1,107 @@ +From e4225086634fb7ae7fa762f3a45af6ad39e78641 Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Tue, 15 Oct 2019 02:17:00 -0700 +Subject: [PATCH] Port a fix from FRR community + https://github.com/donaldsharp/frr/commit/39c93f379a5b57c56739a339ad75ec06e30daef3 + If we have a case where have created a fd for i/o and we have removed the + handling thread but still have the fd in the poll data structure, there + existed a case where we would get the handle this fd return from poll but we + would immediately do nothing with it because we didn't have a thread to hand + the event to. + +This leads to an infinite loop. Prevent the infinite loop +from happening and log the problem. +--- + lib/lib_errors.c | 6 ++++++ + lib/lib_errors.h | 1 + + lib/thread.c | 25 ++++++++++++++++++------- + 3 files changed, 25 insertions(+), 7 deletions(-) + +diff --git a/lib/lib_errors.c b/lib/lib_errors.c +index b6c764d87..033f27e58 100644 +--- a/lib/lib_errors.c ++++ b/lib/lib_errors.c +@@ -50,6 +50,12 @@ static struct log_ref ferr_lib_warn[] = { + .description = "The Event subsystem has detected a slow process, this typically indicates that FRR is having trouble completing work in a timely manner. This can be either a misconfiguration, bug, or some combination therof.", + .suggestion = "Gather log data and open an Issue", + }, ++ { ++ .code = EC_LIB_NO_THREAD, ++ .title = "The Event subsystem has detected an internal FD problem", ++ .description = "The Event subsystem has detected a file descriptor read/write event without an associated handling function. This is a bug, please collect log data and open an issue.", ++ .suggestion = "Gather log data and open an Issue", ++ }, + { + .code = EC_LIB_RMAP_RECURSION_LIMIT, + .title = "Reached the Route-Map Recursion Limit", +diff --git a/lib/lib_errors.h b/lib/lib_errors.h +index 39b39fb06..996a16ba9 100644 +--- a/lib/lib_errors.h ++++ b/lib/lib_errors.h +@@ -45,6 +45,7 @@ enum lib_log_refs { + EC_LIB_STREAM, + EC_LIB_LINUX_NS, + EC_LIB_SLOW_THREAD, ++ EC_LIB_NO_THREAD, + EC_LIB_RMAP_RECURSION_LIMIT, + EC_LIB_BACKUP_CONFIG, + EC_LIB_VRF_LENGTH, +diff --git a/lib/thread.c b/lib/thread.c +index 5ca859a74..82708557d 100644 +--- a/lib/thread.c ++++ b/lib/thread.c +@@ -1235,12 +1235,26 @@ static struct thread *thread_run(struct thread_master *m, struct thread *thread, + } + + static int thread_process_io_helper(struct thread_master *m, +- struct thread *thread, short state, int pos) ++ struct thread *thread, short state, short actual_state, int pos) + { + struct thread **thread_array; + +- if (!thread) ++ /* ++ * If another pthread scheduled this file descriptor for this event ++ * we're responding to, no problem, we're getting to it now. ++ * Additionally if !thread if we don't clear this now we'll ++ * infinaloop( which sucks ) ++ */ ++ m->handler.pfds[pos].events &= ~(state); ++ ++ if (!thread) { ++ if ((actual_state & (POLLHUP | POLLIN)) != POLLHUP) ++ flog_err( EC_LIB_NO_THREAD, ++ "Attempting to process an I/O event but for fd: %d(%d) no thread to handle this!\n", ++ m->handler.pfds[pos].fd, actual_state); + return 0; ++ } ++ + + if (thread->type == THREAD_READ) + thread_array = m->read; +@@ -1250,9 +1264,6 @@ static int thread_process_io_helper(struct thread_master *m, + thread_array[thread->u.fd] = NULL; + thread_list_add_tail(&m->ready, thread); + thread->type = THREAD_READY; +- /* if another pthread scheduled this file descriptor for the event we're +- * responding to, no problem; we're getting to it now */ +- thread->master->handler.pfds[pos].events &= ~(state); + return 1; + } + +@@ -1290,10 +1301,10 @@ static void thread_process_io(struct thread_master *m, unsigned int num) + * should still be a valid index into the master's pfds. */ + if (pfds[i].revents & (POLLIN | POLLHUP)) + thread_process_io_helper(m, m->read[pfds[i].fd], POLLIN, +- i); ++ pfds[i].revents,i); + if (pfds[i].revents & POLLOUT) + thread_process_io_helper(m, m->write[pfds[i].fd], +- POLLOUT, i); ++ POLLOUT, pfds[i].revents, i); + + /* if one of our file descriptors is garbage, remove the same + * from +-- +2.18.0 + diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 1acf6d94f435..edeb30ce1e71 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -3,3 +3,4 @@ 0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch 0005-Support-VRF.patch 0006-changes-for-making-snmp-socket-non-blocking.patch +0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch From 423d4812848375a9556cc9024db42e2d843a47e9 Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Thu, 17 Oct 2019 07:08:13 -0700 Subject: [PATCH 0077/1427] [FRR]: Patch for kernel level graceful restart. (#3621) * [FRR]: Patch for kernel level graceful restart. Original Patch in FRR master: https://github.com/FRRouting/frr/pull/4301 * Rename 0007-zebra-kernel-level-graceful-restart.patch to 0008-zebra-kernel-level-graceful-restart.patch --- ...-zebra-kernel-level-graceful-restart.patch | 227 ++++++++++++++++++ src/sonic-frr/patch/series | 1 + 2 files changed, 228 insertions(+) create mode 100644 src/sonic-frr/patch/0008-zebra-kernel-level-graceful-restart.patch diff --git a/src/sonic-frr/patch/0008-zebra-kernel-level-graceful-restart.patch b/src/sonic-frr/patch/0008-zebra-kernel-level-graceful-restart.patch new file mode 100644 index 000000000000..e2a68a3507b4 --- /dev/null +++ b/src/sonic-frr/patch/0008-zebra-kernel-level-graceful-restart.patch @@ -0,0 +1,227 @@ + + zebra: Add kernel level graceful restart + + + + Add the a `--graceful_restart X` flag to zebra start that + now creates a timer that pops in X seconds and will go + through and remove all routes that are older than startup. + + If graceful_restart is not specified then we will just pop + a timer that cleans everything up immediately. + + Signed-off-by: Praveen Chaudhary + Signed-off-by: Donald Sharp + +diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst +index f38db9d24..40d894929 100644 +--- a/doc/user/zebra.rst ++++ b/doc/user/zebra.rst +@@ -23,9 +23,12 @@ Besides the common invocation options (:ref:`common-invocation-options`), the + Runs in batch mode. *zebra* parses configuration file and terminates + immediately. + +-.. option:: -k, --keep_kernel ++.. option:: -K TIME, --graceful_restart TIME + +- When zebra starts up, don't delete old self inserted routes. ++ If this option is specified, the graceful restart time is TIME seconds. ++ Zebra, when started, will read in routes. Those routes that Zebra ++ identifies that it was the originator of will be swept in TIME seconds. ++ If no time is specified then we will sweep those routes immediately. + + .. option:: -r, --retain + +diff --git a/zebra/main.c b/zebra/main.c +index 184e798bd..3d1d156ad 100644 +--- a/zebra/main.c ++++ b/zebra/main.c +@@ -74,8 +74,7 @@ int retain_mode = 0; + /* Allow non-quagga entities to delete quagga routes */ + int allow_delete = 0; + +-/* Don't delete kernel route. */ +-int keep_kernel_mode = 0; ++int graceful_restart; + + bool v6_rr_semantics = false; + +@@ -89,12 +88,12 @@ uint32_t nl_rcvbufsize = 4194304; + struct option longopts[] = { + {"batch", no_argument, NULL, 'b'}, + {"allow_delete", no_argument, NULL, 'a'}, +- {"keep_kernel", no_argument, NULL, 'k'}, + {"socket", required_argument, NULL, 'z'}, + {"ecmp", required_argument, NULL, 'e'}, + {"label_socket", no_argument, NULL, 'l'}, + {"retain", no_argument, NULL, 'r'}, + {"vrfdefaultname", required_argument, NULL, 'o'}, ++ {"graceful_restart", required_argument, NULL, 'K'}, + #ifdef HAVE_NETLINK + {"vrfwnetns", no_argument, NULL, 'n'}, + {"nl-bufsize", required_argument, NULL, 's'}, +@@ -264,13 +263,14 @@ int main(int argc, char **argv) + char *netlink_fuzzing = NULL; + #endif /* HANDLE_NETLINK_FUZZING */ + ++ graceful_restart = 0; + vrf_configure_backend(VRF_BACKEND_VRF_LITE); + logicalrouter_configure_backend(LOGICALROUTER_BACKEND_NETNS); + + frr_preinit(&zebra_di, argc, argv); + + frr_opt_add( +- "bakz:e:l:o:r" ++ "baz:e:l:o:rK:" + #ifdef HAVE_NETLINK + "s:n" + #endif +@@ -282,24 +282,24 @@ int main(int argc, char **argv) + #endif /* HANDLE_NETLINK_FUZZING */ + , + longopts, +- " -b, --batch Runs in batch mode\n" +- " -a, --allow_delete Allow other processes to delete zebra routes\n" +- " -z, --socket Set path of zebra socket\n" +- " -e, --ecmp Specify ECMP to use.\n" +- " -l, --label_socket Socket to external label manager\n" +- " -k, --keep_kernel Don't delete old routes which were installed by zebra.\n" +- " -r, --retain When program terminates, retain added route by zebra.\n" +- " -o, --vrfdefaultname Set default VRF name.\n" ++ " -b, --batch Runs in batch mode\n" ++ " -a, --allow_delete Allow other processes to delete zebra routes\n" ++ " -z, --socket Set path of zebra socket\n" ++ " -e, --ecmp Specify ECMP to use.\n" ++ " -l, --label_socket Socket to external label manager\n" ++ " -r, --retain When program terminates, retain added route by zebra.\n" ++ " -o, --vrfdefaultname Set default VRF name.\n" ++ " -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n" + #ifdef HAVE_NETLINK +- " -n, --vrfwnetns Use NetNS as VRF backend\n" +- " -s, --nl-bufsize Set netlink receive buffer size\n" +- " --v6-rr-semantics Use v6 RR semantics\n" ++ " -n, --vrfwnetns Use NetNS as VRF backend\n" ++ " -s, --nl-bufsize Set netlink receive buffer size\n" ++ " --v6-rr-semantics Use v6 RR semantics\n" + #endif /* HAVE_NETLINK */ + #if defined(HANDLE_ZAPI_FUZZING) +- " -c Bypass normal startup and use this file for testing of zapi\n" ++ " -c Bypass normal startup and use this file for testing of zapi\n" + #endif /* HANDLE_ZAPI_FUZZING */ + #if defined(HANDLE_NETLINK_FUZZING) +- " -w Bypass normal startup and use this file for testing of netlink input\n" ++ " -w Bypass normal startup and use this file for testing of netlink input\n" + #endif /* HANDLE_NETLINK_FUZZING */ + ); + +@@ -318,9 +318,6 @@ int main(int argc, char **argv) + case 'a': + allow_delete = 1; + break; +- case 'k': +- keep_kernel_mode = 1; +- break; + case 'e': + multipath_num = atoi(optarg); + if (multipath_num > MULTIPATH_NUM +@@ -350,6 +347,9 @@ int main(int argc, char **argv) + case 'r': + retain_mode = 1; + break; ++ case 'K': ++ graceful_restart = atoi(optarg); ++ break; + #ifdef HAVE_NETLINK + case 's': + nl_rcvbufsize = atoi(optarg); +@@ -437,9 +437,9 @@ int main(int argc, char **argv) + * will be equal to the current getpid(). To know about such routes, + * we have to have route_read() called before. + */ +- if (!keep_kernel_mode) +- rib_sweep_route(); +- ++ zrouter.startup_time = monotime(NULL); ++ thread_add_timer(zrouter.master, rib_sweep_route, ++ NULL, graceful_restart, NULL); + /* Needed for BSD routing socket. */ + pid = getpid(); + +diff --git a/zebra/rib.h b/zebra/rib.h +index 9fe42aef3..69850f3a0 100644 +--- a/zebra/rib.h ++++ b/zebra/rib.h +@@ -351,7 +351,7 @@ extern struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, + extern void rib_update(vrf_id_t vrf_id, rib_update_event_t event); + extern void rib_update_table(struct route_table *table, + rib_update_event_t event); +-extern void rib_sweep_route(void); ++extern int rib_sweep_route(struct thread *t); + extern void rib_sweep_table(struct route_table *table); + extern void rib_close_table(struct route_table *table); + extern void rib_init(void); +diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c +index 555127b09..b6afcdc8c 100644 +--- a/zebra/zebra_rib.c ++++ b/zebra/zebra_rib.c +@@ -3145,6 +3145,7 @@ void rib_sweep_table(struct route_table *table) + + for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) { + RNODE_FOREACH_RE_SAFE (rn, re, next) { ++ + if (IS_ZEBRA_DEBUG_RIB) + route_entry_dump(&rn->p, NULL, re); + +@@ -3154,6 +3155,14 @@ void rib_sweep_table(struct route_table *table) + if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELFROUTE)) + continue; + ++ /* ++ * If routes are older than startup_time then ++ * we know we read them in from the kernel. ++ * As such we can safely remove them. ++ */ ++ if (zrouter.startup_time < re->uptime) ++ continue; ++ + /* + * So we are starting up and have received + * routes from the kernel that we have installed +@@ -3183,7 +3192,7 @@ void rib_sweep_table(struct route_table *table) + } + + /* Sweep all RIB tables. */ +-void rib_sweep_route(void) ++int rib_sweep_route(struct thread *t) + { + struct vrf *vrf; + struct zebra_vrf *zvrf; +@@ -3197,6 +3206,8 @@ void rib_sweep_route(void) + } + + zebra_router_sweep_route(); ++ ++ return 0; + } + + /* Remove specific by protocol routes from 'table'. */ +diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h +index b316b91d0..b2e92bad0 100644 +--- a/zebra/zebra_router.h ++++ b/zebra/zebra_router.h +@@ -110,8 +110,15 @@ struct zebra_router { + * The EVPN instance, if any + */ + struct zebra_vrf *evpn_vrf; ++ ++ /* ++ * Time for when we sweep the rib from old routes ++ */ ++ time_t startup_time; + }; + ++#define GRACEFUL_RESTART_TIME 60 ++ + extern struct zebra_router zrouter; + + extern void zebra_router_init(void); diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index edeb30ce1e71..da0ab7ba47c5 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -4,3 +4,4 @@ 0005-Support-VRF.patch 0006-changes-for-making-snmp-socket-non-blocking.patch 0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch +0008-zebra-kernel-level-graceful-restart.patch \ No newline at end of file From d1c4deb8113eeefb3dd8007c95f42412a18e4714 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Thu, 17 Oct 2019 09:47:46 -0700 Subject: [PATCH 0078/1427] [minigraph]; Parse backend switches to vlan sub port interface (#3413) * Parse backend switches to vlan sub port interface Signed-off-by: Wenda Ni --- src/sonic-config-engine/minigraph.py | 31 ++++++++++ src/sonic-config-engine/tests/test_cfggen.py | 63 +++++++++++++++++++- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index f64cbefafbd5..3ee60706d7e2 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -30,6 +30,10 @@ spine_chassis_frontend_role = 'SpineChassisFrontendRouter' chassis_backend_role = 'ChassisBackendRouter' +backend_device_types = ['BackEndToRRouter', 'BackEndLeafRouter'] +VLAN_SUB_INTERFACE_SEPARATOR = '.' +VLAN_SUB_INTERFACE_VLAN_ID = '10' + # Default Virtual Network Index (VNI) vni_default = 8000 @@ -612,6 +616,7 @@ def parse_xml(filename, platform=None, port_config_file=None): vlan_intfs = {} pc_intfs = {} vlan_invert_mapping = { v['alias']:k for k,v in vlans.items() if v.has_key('alias') } + vlan_sub_intfs = {} for intf in intfs: if intf[0][0:4] == 'Vlan': @@ -713,6 +718,32 @@ def parse_xml(filename, platform=None, port_config_file=None): results['PORTCHANNEL_INTERFACE'] = pc_intfs + if current_device['type'] in backend_device_types: + del results['INTERFACE'] + del results['PORTCHANNEL_INTERFACE'] + + for intf in phyport_intfs.keys(): + if isinstance(intf, tuple): + intf_info = list(intf) + intf_info[0] = intf_info[0] + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + sub_intf = tuple(intf_info) + vlan_sub_intfs[sub_intf] = {} + else: + sub_intf = intf + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + vlan_sub_intfs[sub_intf] = {"admin_status" : "up"} + + for pc_intf in pc_intfs.keys(): + if isinstance(pc_intf, tuple): + pc_intf_info = list(pc_intf) + pc_intf_info[0] = pc_intf_info[0] + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + sub_intf = tuple(pc_intf_info) + vlan_sub_intfs[sub_intf] = {} + else: + sub_intf = pc_intf + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + vlan_sub_intfs[sub_intf] = {"admin_status" : "up"} + + results['VLAN_SUB_INTERFACE'] = vlan_sub_intfs + results['VLAN'] = vlans results['VLAN_MEMBER'] = vlan_members diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index fb85c54cfc90..00c5bfa65ea0 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -2,6 +2,9 @@ import subprocess import os +TOR_ROUTER = 'ToRRouter' +BACKEND_TOR_ROUTER = 'BackEndToRRouter' + class TestCfgGen(TestCase): def setUp(self): @@ -55,10 +58,12 @@ def test_print_data(self): output = self.run_script(argument) self.assertTrue(len(output.strip()) > 0) - def test_jinja_expression(self): - argument = '-m "' + self.sample_graph + '" -v "DEVICE_METADATA[\'localhost\'][\'type\']"' + def test_jinja_expression(self, graph=None, expected_router_type='LeafRouter'): + if graph is None: + graph = self.sample_graph + argument = '-m "' + graph + '" -v "DEVICE_METADATA[\'localhost\'][\'type\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), 'LeafRouter') + self.assertEqual(output.strip(), expected_router_type) def test_additional_json_data(self): argument = '-a \'{"key1":"value1"}\' -v key1' @@ -266,3 +271,55 @@ def test_minigraph_bgp_mon(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") + def test_minigraph_sub_port_interfaces(self, check_stderr=True): + try: + print '\n Change device type to %s' % (BACKEND_TOR_ROUTER) + if check_stderr: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (TOR_ROUTER, BACKEND_TOR_ROUTER, self.sample_graph_simple), stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (TOR_ROUTER, BACKEND_TOR_ROUTER, self.sample_graph_simple), shell=True) + + self.test_jinja_expression(self.sample_graph_simple, BACKEND_TOR_ROUTER) + + + # INTERFACE table does not exist + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "INTERFACE"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "") + + # PORTCHANNEL_INTERFACE table does not exist + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "") + + # All the other tables stay unchanged + self.test_var_json_data() + self.test_minigraph_vlans() + self.test_minigraph_vlan_members() + self.test_minigraph_vlan_interfaces() + self.test_minigraph_portchannels() + self.test_minigraph_ethernet_interfaces() + self.test_minigraph_extra_ethernet_interfaces() + self.test_minigraph_vnet() + self.test_minigraph_vxlan() + + # VLAN_SUB_INTERFACE + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN_SUB_INTERFACE' + output = self.run_script(argument) + print output.strip() + self.assertEqual(output.strip(), \ + "{('PortChannel01.10', '10.0.0.56/31'): {}, " + "'Ethernet0.10': {'admin_status': 'up'}, " + "('Ethernet0.10', '10.0.0.58/31'): {}, " + "('PortChannel01.10', 'FC00::71/126'): {}, " + "'PortChannel01.10': {'admin_status': 'up'}, " + "('Ethernet0.10', 'FC00::75/126'): {}}") + + finally: + print '\n Change device type back to %s' % (TOR_ROUTER) + if check_stderr: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (BACKEND_TOR_ROUTER, TOR_ROUTER, self.sample_graph_simple), stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (BACKEND_TOR_ROUTER, TOR_ROUTER, self.sample_graph_simple), shell=True) + + self.test_jinja_expression(self.sample_graph_simple, TOR_ROUTER) From 41ac24d65832a2cc3053d66c72165a814da720a5 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Fri, 18 Oct 2019 02:10:00 +0300 Subject: [PATCH 0079/1427] [submodule] Advance SONiC kernel. (#3625) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. IPv6 host and subnet anycast route in VRF to be configured with nhop (#… 5786674 2. Unregister_netdev VRF obsreved and kernel hangs during vrf delete (#109) 5dbf6d5 3. [mellanox] Extend size of QSFP EEPROM for the cable type SSF8436 and … feb42b0 Signed-off-by: Nazarii Hnydyn --- src/sonic-linux-kernel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 6d55e9a84c6d..feb42b05eb91 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 6d55e9a84c6d0693fa5532bea2d2ddfa5c501eb6 +Subproject commit feb42b05eb912ea64f0b4ce17f4bc890929eb57e From c1848153c30a25f6df257337ec9e335e8f8426d3 Mon Sep 17 00:00:00 2001 From: Danny Allen <52468448+daall@users.noreply.github.com> Date: Thu, 17 Oct 2019 16:29:07 -0700 Subject: [PATCH 0080/1427] [minigraph.py] Update minigraph parsing logic to include only active ports for mirror tables (#3592) * Update minigraph.py to filter out front-panel ports that are not active * Update cfggen tests to reflect new behavior Signed-off-by: Danny Allen * Incorporate PR comments - Update t0 tests to include additional device neighbors - Refactor xml parsing logic --- src/sonic-config-engine/minigraph.py | 53 ++++++++++++++++--- .../tests/t0-sample-graph.xml | 7 +++ src/sonic-config-engine/tests/test_cfggen.py | 11 +++- 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 3ee60706d7e2..37d68bdbfb0c 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -37,6 +37,12 @@ # Default Virtual Network Index (VNI) vni_default = 8000 +############################################################################### +# +# Minigraph parsing functions +# +############################################################################### + class minigraph_encoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, ( @@ -278,15 +284,17 @@ def parse_dpg(dpg, hname): if member.lower().startswith('erspanv6'): is_mirror_v6 = True else: - is_mirror = True; - # Erspan session will be attached to all front panel ports, - # if panel ports is a member port of LAG, should add the LAG - # to acl table instead of the panel ports + is_mirror = True + # Erspan session will be attached to all front panel ports + # initially. If panel ports is a member port of LAG, then + # the LAG will be added to acl table instead of the panel + # ports. Non-active ports will be removed from this list + # later after the rest of the minigraph has been parsed. acl_intfs = pc_intfs[:] for panel_port in port_alias_map.values(): if panel_port not in intfs_inpc: acl_intfs.append(panel_port) - break; + break if acl_intfs: acls[aclname] = {'policy_desc': aclname, 'ports': acl_intfs} @@ -514,6 +522,39 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m # Enslave the port channel interface to a Vnet pc_intfs[pc_intf] = {'vnet_name': chassis_vnet} +############################################################################### +# +# Post-processing functions +# +############################################################################### + +def filter_acl_mirror_table_bindings(acls, neighbors, port_channels): + """ + Filters out inactive front-panel ports from the binding list for mirror + ACL tables. We define an "active" port as one that is a member of a + port channel or one that is connected to a neighboring device. + """ + + for acl_table, group_params in acls.iteritems(): + group_type = group_params.get('type', None) + + if group_type != 'MIRROR' and group_type != 'MIRRORV6': + continue + + active_ports = [ port for port in group_params.get('ports', []) if port in neighbors.keys() or port in port_channels ] + + if not active_ports: + print >> sys.stderr, 'Warning: mirror table {} in ACL_TABLE does not have any ports bound to it'.format(acl_table) + + acls[acl_table]['ports'] = active_ports + + return acls + +############################################################################### +# +# Main functions +# +############################################################################### def parse_xml(filename, platform=None, port_config_file=None): root = ET.parse(filename).getroot() @@ -760,7 +801,7 @@ def parse_xml(filename, platform=None, port_config_file=None): results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers) results['TACPLUS_SERVER'] = dict((item, {'priority': '1', 'tcp_port': '49'}) for item in tacacs_servers) - results['ACL_TABLE'] = acls + results['ACL_TABLE'] = filter_acl_mirror_table_bindings(acls, neighbors, pcs) # Do not configure the minigraph's mirror session, which is currently unused # mirror_sessions = {} diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index 180895928fbd..0c641107da06 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -383,6 +383,13 @@ Ethernet1/33 true + + DeviceInterfaceLink + Servers0 + eth0 + switch-t0 + fortyGigE0/4 + diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 00c5bfa65ea0..6c9574af3514 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -95,6 +95,9 @@ def test_render_template(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'value1\nvalue2') + # FIXME: This test depends heavily on the ordering of the interfaces and + # it is not at all intuitive what that ordering should be. Could make it + # more robust by adding better parsing logic. def test_minigraph_acl(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE' output = self.run_script(argument, True) @@ -103,11 +106,11 @@ def test_minigraph_acl(self): "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" "{'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04']}, " "'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL'}, " - "'EVERFLOW': {'type': 'MIRROR', 'policy_desc': 'EVERFLOW', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100']}, " + "'EVERFLOW': {'type': 'MIRROR', 'policy_desc': 'EVERFLOW', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4']}, " "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT'}, " "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL'}, " "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL'}, " - "'EVERFLOWV6': {'type': 'MIRRORV6', 'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100']}}") + "'EVERFLOWV6': {'type': 'MIRRORV6', 'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4']}}") # everflow portion is not used # def test_minigraph_everflow(self): @@ -165,6 +168,9 @@ def test_minigraph_neighbors(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}") + # FIXME: This test depends heavily on the ordering of the interfaces and + # it is not at all intuitive what that ordering should be. Could make it + # more robust by adding better parsing logic. def test_minigraph_extra_neighbors(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v DEVICE_NEIGHBOR' output = self.run_script(argument) @@ -172,6 +178,7 @@ def test_minigraph_extra_neighbors(self): "{'Ethernet116': {'name': 'ARISTA02T1', 'port': 'Ethernet1/1'}, " "'Ethernet124': {'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}, " "'Ethernet112': {'name': 'ARISTA01T1', 'port': 'Ethernet1/1'}, " + "'Ethernet4': {'name': 'Servers0', 'port': 'eth0'}, " "'Ethernet120': {'name': 'ARISTA03T1', 'port': 'Ethernet1/1'}}") def test_minigraph_port_description(self): From 0f87d1fd6b48db0e392e9379af0e1ec6dd8657b4 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Fri, 18 Oct 2019 07:51:58 +0800 Subject: [PATCH 0081/1427] [Mellanox] Support SAI 1.5 (#49) --- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index cd736ba256c4..2bf37a7600bb 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.15.0-master +MLNX_SAI_VERSION = SAIRel1.15.1-ptf-rif-vlan-fix export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 350187a41e40..d93eaed7ba8b 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 350187a41e408daaf03380401a0a2351b6cb0f9e +Subproject commit d93eaed7ba8b996fb70e000af468c485bbfbbfae From e6fc1e7bf093697273118f47741c15e98f9d12ae Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Fri, 18 Oct 2019 06:46:57 +0530 Subject: [PATCH 0082/1427] [Platform] Updated Marvell x86 platform makefiles (#3606) Signed-off-by: Antony Rheneus --- platform/marvell/docker-syncd-mrvl.mk | 23 +++++++------------ .../marvell/docker-syncd-mrvl/Dockerfile.j2 | 2 +- platform/marvell/rules.mk | 1 - platform/marvell/sai.mk | 5 +--- platform/marvell/sai/Makefile | 2 +- platform/marvell/sdk.mk | 8 ------- platform/marvell/sdk/Makefile | 9 -------- 7 files changed, 11 insertions(+), 39 deletions(-) delete mode 100644 platform/marvell/sdk.mk delete mode 100644 platform/marvell/sdk/Makefile diff --git a/platform/marvell/docker-syncd-mrvl.mk b/platform/marvell/docker-syncd-mrvl.mk index 85c1bf108f69..5257bf5e68e7 100644 --- a/platform/marvell/docker-syncd-mrvl.mk +++ b/platform/marvell/docker-syncd-mrvl.mk @@ -1,21 +1,14 @@ # docker image for mrvl syncd -DOCKER_SYNCD_MRVL = docker-syncd-mrvl.gz -$(DOCKER_SYNCD_MRVL)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl -$(DOCKER_SYNCD_MRVL)_DEPENDS += $(SYNCD) $(MRVL_FPA) $(REDIS_TOOLS) -ifeq ($(INSTALL_DEBUG_TOOLS), y) -$(DOCKER_SYNCD_MRVL)_DEPENDS += $(SYNCD_DBG) \ +DOCKER_SYNCD_PLATFORM_CODE = mrvl +include $(PLATFORM_PATH)/../template/docker-syncd-base.mk + +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) + +$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) -endif -$(DOCKER_SYNCD_MRVL)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) -SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL) -ifneq ($(ENABLE_SYNCD_RPC),y) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL) -endif -$(DOCKER_SYNCD_MRVL)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_MRVL)_RUN_OPT += --net=host --privileged -t -$(DOCKER_SYNCD_MRVL)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf -$(DOCKER_SYNCD_MRVL)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd diff --git a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 index 5017b305f151..889971652c61 100755 --- a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine +FROM docker-config-engine-stretch ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/platform/marvell/rules.mk b/platform/marvell/rules.mk index 93fe18eef86d..d819cfb67dae 100644 --- a/platform/marvell/rules.mk +++ b/platform/marvell/rules.mk @@ -1,4 +1,3 @@ -include $(PLATFORM_PATH)/sdk.mk include $(PLATFORM_PATH)/sai.mk include $(PLATFORM_PATH)/docker-syncd-mrvl.mk include $(PLATFORM_PATH)/docker-syncd-mrvl-rpc.mk diff --git a/platform/marvell/sai.mk b/platform/marvell/sai.mk index 5016b47f19a9..7953ad5dd82f 100644 --- a/platform/marvell/sai.mk +++ b/platform/marvell/sai.mk @@ -1,9 +1,6 @@ # Marvell SAI -export MRVL_SAI_VERSION = 1.2.1 -export MRVL_SAI_TAG = SONiC.201803 -export MRVL_SAI = mrvllibsai_$(MRVL_SAI_VERSION).deb +export MRVL_SAI = mrvllibsai_amd64_1.4.1.deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai -$(MRVL_SAI)_DEPENDS += $(MRVL_FPA) SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/marvell/sai/Makefile b/platform/marvell/sai/Makefile index 1fad592a79ee..1cd6d0267fa2 100644 --- a/platform/marvell/sai/Makefile +++ b/platform/marvell/sai/Makefile @@ -2,7 +2,7 @@ SHELL = /bin/bash .SHELLFLAGS += -e -MRVL_SAI_URL = https://github.com/Marvell-switching/SAI-plugin/raw/$(MRVL_SAI_TAG)/sai_deb/$(MRVL_SAI) +MRVL_SAI_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/amd64/sai-plugin/$(MRVL_SAI) $(addprefix $(DEST)/, $(MRVL_SAI)): $(DEST)/% : # get deb package diff --git a/platform/marvell/sdk.mk b/platform/marvell/sdk.mk deleted file mode 100644 index 3d1ce8e04c88..000000000000 --- a/platform/marvell/sdk.mk +++ /dev/null @@ -1,8 +0,0 @@ -# Marvell FPA - -export MRVL_FPA_VERSION = 1.2.1 -export MRVL_FPA_TAG = SONiC.201803 -export MRVL_FPA = mrvllibfpa_$(MRVL_FPA_VERSION).deb - -$(MRVL_FPA)_SRC_PATH = $(PLATFORM_PATH)/sdk -SONIC_MAKE_DEBS += $(MRVL_FPA) diff --git a/platform/marvell/sdk/Makefile b/platform/marvell/sdk/Makefile deleted file mode 100644 index 6822c7d7d274..000000000000 --- a/platform/marvell/sdk/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -.ONESHELL: -SHELL = /bin/bash -.SHELLFLAGS += -e - -MRVL_FPA_URL = https://github.com/Marvell-switching/SAI-plugin/raw/$(MRVL_FPA_TAG)/sdk_deb/$(MRVL_FPA) - -$(addprefix $(DEST)/, $(MRVL_FPA)): $(DEST)/% : - # get deb package - wget -O $(DEST)/$(MRVL_FPA) $(MRVL_FPA_URL) From 60a7f4d653ed3077fc657e239309aec4dda650f3 Mon Sep 17 00:00:00 2001 From: srideepDell Date: Thu, 17 Oct 2019 18:43:59 -0700 Subject: [PATCH 0083/1427] [device]: Add a new supported device DellEMC s5248f (#3547) * Switch Vendor: DellEMC * Switch SKU: s5248F * ASIC Vendor: Broadcom * Swich ASIC: Trident3 * Port Configuration: 48x25G,4x100G,2x200G * SONiC Image: sonic-broadcom.bin * Changes Include ipmitool implementation for platform_sensors script is inclued in pmon startup * Added 25G,10G configruation(25G is default) 1-48FP. 4x100G,2x200G (49-54 FP) * LED support for s5248f --- .../DellEMC-S5248f-P-10G/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 46 + .../buffers_defaults_t1.j2 | 46 + .../DellEMC-S5248f-P-10G/custom_led.bin | Bin 0 -> 372 bytes .../DellEMC-S5248f-P-10G/linkscan_led_fw.bin | Bin 0 -> 4752 bytes .../DellEMC-S5248f-P-10G/port_config.ini | 57 + .../DellEMC-S5248f-P-10G/qos.json.j2 | 226 +++ .../DellEMC-S5248f-P-10G/sai.profile | 1 + .../DellEMC-S5248f-P-10G/sai_preinit_cmd.soc | 2 + .../td3-s5248f-10g.config.bcm | 353 ++++ .../DellEMC-S5248f-P-25G/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 46 + .../buffers_defaults_t1.j2 | 46 + .../DellEMC-S5248f-P-25G/custom_led.bin | Bin 0 -> 372 bytes .../DellEMC-S5248f-P-25G/linkscan_led_fw.bin | Bin 0 -> 4752 bytes .../DellEMC-S5248f-P-25G/port_config.ini | 57 + .../DellEMC-S5248f-P-25G/qos.json.j2 | 226 +++ .../DellEMC-S5248f-P-25G/sai.profile | 1 + .../DellEMC-S5248f-P-25G/sai_preinit_cmd.soc | 2 + .../td3-s5248f-25g.config.bcm | 355 ++++ .../default_sku | 1 + .../installer.conf | 3 + .../led_proc_init.soc | 6 + .../media_settings.json | 442 +++++ .../plugins/eeprom.py | 22 + .../plugins/psuutil.py | 107 ++ .../plugins/sfputil.py | 289 +++ platform/broadcom/one-image.mk | 1 + .../debian/control | 5 + .../debian/platform-modules-s5248f.init | 40 + .../debian/platform-modules-s5248f.install | 9 + .../debian/platform-modules-s5248f.postinst | 10 + .../sonic-platform-modules-dell/debian/rules | 2 +- .../s5248f/cfg/s5248f-modules.conf | 19 + .../s5248f/modules/Makefile | 2 + .../s5248f/modules/dell_s5248f_fpga_ocores.c | 1626 +++++++++++++++++ .../s5248f/scripts/check_qsfp.sh | 3 + .../s5248f/scripts/pcisysfs.py | 102 ++ .../s5248f/scripts/platform_sensors.py | 277 +++ .../s5248f/scripts/qsfp_irq_enable.py | 32 + .../s5248f/scripts/s5248f_platform.sh | 161 ++ .../s5248f/scripts/sensors | 8 + .../systemd/platform-modules-s5248f.service | 13 + src/sonic-device-data/tests/permitted_list | 7 + 44 files changed, 4654 insertions(+), 1 deletion(-) create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t0.j2 create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/custom_led.bin create mode 100755 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/linkscan_led_fw.bin create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/port_config.ini create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/qos.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/td3-s5248f-10g.config.bcm create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t0.j2 create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/custom_led.bin create mode 100755 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/linkscan_led_fw.bin create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/port_config.ini create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/qos.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/td3-s5248f-25g.config.bcm create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/default_sku create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/installer.conf create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/led_proc_init.soc create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/media_settings.json create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/psuutil.py create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.init create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.postinst create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5248f/cfg/s5248f-modules.conf create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5248f/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5248f/modules/dell_s5248f_fpga_ocores.c create mode 100755 platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/check_qsfp.sh create mode 100755 platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/qsfp_irq_enable.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh create mode 100755 platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/sensors create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5248f/systemd/platform-modules-s5248f.service diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers.json.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t0.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/custom_led.bin b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..b3966e520c51dd288e36859523157396cb587911 GIT binary patch literal 372 zcmeycHQp`E&DYJv?ZcMl4GumGN)Fz0+!&M_R9Cq%t8H*&ROfeKoNnXU>Bjm%L7V9! zi}D;724zMQMkCdVl?-edosxVV4AU4DXF8<2*=O)Ov0ZQknx>n1GElYl=hC!kkjVADCy0h6qO*I!Jy4_LCjk!f$0IGk_eC%_KwP6 zG>S@KR6d-*oG78>l*pvilz2E%Qkgj^K-oE|DTzV(aMI!A!zru}m=xXJ80P9boxFJF zIr9daJrmq!x-D{B?e<}>j3ooZiVX}5IY8RL(8$=r(#qP#*3RC?*UvvBG%P$OHZGor zmycgWR7_k(R!%-4F)2ACGb_8Gu&9`Uk%?JBQAwGFm5p6PQ%k#|vZ}hKwyxgA)y>_( J(aD(s3IM|vYpehO literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/linkscan_led_fw.bin new file mode 100755 index 0000000000000000000000000000000000000000..c2fa94a2d8cb11161cc337d00971e7267f08d32e GIT binary patch literal 4752 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 X`cUsHXR!vGk^Z4y?GFw9z}SBSTZoUr literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/port_config.ini b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/port_config.ini new file mode 100644 index 000000000000..3827e7acbe28 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 49 tenGigE1/1/1 1 10000 +Ethernet1 50 tenGigE1/1/2 2 10000 +Ethernet2 51 tenGigE1/1/3 3 10000 +Ethernet3 52 tenGigE1/1/4 4 10000 +Ethernet4 57 tenGigE1/2/1 5 10000 +Ethernet5 58 tenGigE1/2/2 6 10000 +Ethernet6 59 tenGigE1/2/3 7 10000 +Ethernet7 60 tenGigE1/2/4 8 10000 +Ethernet8 61 tenGigE1/3/1 9 10000 +Ethernet9 62 tenGigE1/3/2 10 10000 +Ethernet10 63 tenGigE1/3/3 11 10000 +Ethernet11 64 tenGigE1/3/4 12 10000 +Ethernet12 77 tenGigE1/4/1 13 10000 +Ethernet13 78 tenGigE1/4/2 14 10000 +Ethernet14 79 tenGigE1/4/3 15 10000 +Ethernet15 80 tenGigE1/4/4 16 10000 +Ethernet16 85 tenGigE1/5/1 17 10000 +Ethernet17 86 tenGigE1/5/2 18 10000 +Ethernet18 87 tenGigE1/5/3 19 10000 +Ethernet19 88 tenGigE1/5/4 20 10000 +Ethernet20 93 tenGigE1/6/1 21 10000 +Ethernet21 94 tenGigE1/6/2 22 10000 +Ethernet22 95 tenGigE1/6/3 23 10000 +Ethernet23 96 tenGigE1/6/4 24 10000 +Ethernet24 13 tenGigE1/7/1 25 10000 +Ethernet25 14 tenGigE1/7/2 26 10000 +Ethernet26 15 tenGigE1/7/3 27 10000 +Ethernet27 16 tenGigE1/7/4 28 10000 +Ethernet28 21 tenGigE1/8/1 29 10000 +Ethernet29 22 tenGigE1/8/2 30 10000 +Ethernet30 23 tenGigE1/8/3 31 10000 +Ethernet31 24 tenGigE1/8/4 32 10000 +Ethernet32 29 tenGigE1/9/1 33 10000 +Ethernet33 30 tenGigE1/9/2 34 10000 +Ethernet34 31 tenGigE1/9/3 35 10000 +Ethernet35 32 tenGigE1/9/4 36 10000 +Ethernet36 97 tenGigE1/10/1 37 10000 +Ethernet37 98 tenGigE1/10/2 38 10000 +Ethernet38 99 tenGigE1/10/3 39 10000 +Ethernet39 100 tenGigE1/10/4 40 10000 +Ethernet40 105 tenGigE1/11/1 41 10000 +Ethernet41 106 tenGigE1/11/2 42 10000 +Ethernet42 107 tenGigE1/11/3 43 10000 +Ethernet43 108 tenGigE1/11/4 44 10000 +Ethernet44 113 tenGigE1/12/1 45 10000 +Ethernet45 114 tenGigE1/12/2 46 10000 +Ethernet46 115 tenGigE1/12/3 47 10000 +Ethernet47 116 tenGigE1/12/4 48 10000 +Ethernet48 121,122,123,124 hundredGigE1/49 49 100000 +Ethernet49 125,126,127,128 hundredGigE1/50 50 100000 +Ethernet50 69,70,71,72 hundredGigE1/51 51 100000 +Ethernet51 65,66,67,68 hundredGigE1/52 52 100000 +Ethernet52 1,2,3,4 hundredGigE1/53 53 100000 +Ethernet53 33,34,35,36 hundredGigE1/54 54 100000 +Ethernet54 5,6,7,8 hundredGigE1/55 55 100000 +Ethernet55 41,42,43,44 hundredGigE1/56 56 100000 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/qos.json.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/qos.json.j2 new file mode 100644 index 000000000000..d2b3d2b0131c --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/qos.json.j2 @@ -0,0 +1,226 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "0", + "4": "0", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "DWRR", + "weight": "50" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile new file mode 100644 index 000000000000..52afc687173c --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5248f-10g.config.bcm diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/td3-s5248f-10g.config.bcm b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/td3-s5248f-10g.config.bcm new file mode 100644 index 000000000000..2369f4590795 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/td3-s5248f-10g.config.bcm @@ -0,0 +1,353 @@ +os=unix +dpp_clock_ratio=2:3 +oversubscribe_mode=1 +core_clock_frequency=1525 +l2xmsg_mode=1 +pbmp_oversubscribe=0x7f878787f878787f9fe1e1e1fe1e1e1fe +pbmp_xport_xe=0x7f878787f878787f9fe1e1e1fe1e1e1fe +ifp_inports_support_enable=1 +port_flex_enable=1 +phy_an_c73=3 +l2xmsg_hostbuf_size=8192 +module_64ports=0 +tdma_intr_enable=1 +ipv6_lpm_128b_enable=1 +stat_if_parity_enable=1 +bcm_tunnel_term_compatible_mode=1 +table_dma_enable=1 +schan_intr_enable=0 +parity_enable=1 +parity_correction=1 +miim_intr_enable=1 +max_vp_lags=0 +tdma_intr_enable=1 +tdma_timeout_usec=5000000 +mmu_lossless=0 +pdma_descriptor_prefetch_enable=1 +pktdma_poll_mode_channel_bitmap=1 + +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 +l3_max_ecmp_mode=1 + +stable_size=0x5500000 + +portmap_1.0=1:100 +portmap_5.0=5:100 +portmap_13.0=13:10 +portmap_14.0=14:10 +portmap_15.0=15:10 +portmap_16.0=16:10 +portmap_21.0=21:10 +portmap_22.0=22:10 +portmap_23.0=23:10 +portmap_24.0=24:10 +portmap_29.0=29:10 +portmap_30.0=30:10 +portmap_31.0=31:10 +portmap_32.0=32:10 +portmap_33.0=33:100 +portmap_41.0=41:100 +portmap_49.0=49:10 +portmap_50.0=50:10 +portmap_51.0=51:10 +portmap_52.0=52:10 +portmap_57.0=57:10 +portmap_58.0=58:10 +portmap_59.0=59:10 +portmap_60.0=60:10 +portmap_61.0=61:10 +portmap_62.0=62:10 +portmap_63.0=63:10 +portmap_64.0=64:10 +portmap_67.0=65:100 +portmap_71.0=69:100 +portmap_79.0=77:10 +portmap_80.0=78:10 +portmap_81.0=79:10 +portmap_82.0=80:10 +portmap_87.0=85:10 +portmap_88.0=86:10 +portmap_89.0=87:10 +portmap_90.0=88:10 +portmap_95.0=93:10 +portmap_96.0=94:10 +portmap_97.0=95:10 +portmap_98.0=96:10 +portmap_99.0=97:10 +portmap_100.0=98:10 +portmap_101.0=99:10 +portmap_102.0=100:10 +portmap_107.0=105:10 +portmap_108.0=106:10 +portmap_109.0=107:10 +portmap_110.0=108:10 +portmap_115.0=113:10 +portmap_116.0=114:10 +portmap_117.0=115:10 +portmap_118.0=116:10 +portmap_123.0=121:100 +portmap_127.0=125:100 +phy_chain_tx_lane_map_physical{1.0}=0x0123 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_tx_lane_map_physical{5.0}=0x1032 +phy_chain_rx_lane_map_physical{5.0}=0x1302 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x1032 +phy_chain_tx_lane_map_physical{21.0}=0x0123 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x1302 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x3120 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_tx_lane_map_physical{49.0}=0x0123 +phy_chain_rx_lane_map_physical{49.0}=0x1032 +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x1032 +phy_chain_tx_lane_map_physical{61.0}=0x0123 +phy_chain_rx_lane_map_physical{61.0}=0x1032 +phy_chain_tx_lane_map_physical{65.0}=0x0123 +phy_chain_rx_lane_map_physical{65.0}=0x2031 +phy_chain_tx_lane_map_physical{69.0}=0x3021 +phy_chain_rx_lane_map_physical{69.0}=0x2130 +phy_chain_tx_lane_map_physical{77.0}=0x3210 +phy_chain_rx_lane_map_physical{77.0}=0x2301 +phy_chain_tx_lane_map_physical{85.0}=0x3210 +phy_chain_rx_lane_map_physical{85.0}=0x2301 +phy_chain_tx_lane_map_physical{93.0}=0x3210 +phy_chain_rx_lane_map_physical{93.0}=0x2301 +phy_chain_tx_lane_map_physical{97.0}=0x3210 +phy_chain_rx_lane_map_physical{97.0}=0x2301 +phy_chain_tx_lane_map_physical{105.0}=0x3210 +phy_chain_rx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{113.0}=0x3210 +phy_chain_rx_lane_map_physical{113.0}=0x2301 +phy_chain_tx_lane_map_physical{121.0}=0x0312 +phy_chain_rx_lane_map_physical{121.0}=0x1023 +phy_chain_tx_lane_map_physical{125.0}=0x2301 +phy_chain_rx_lane_map_physical{125.0}=0x3120 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x1 +phy_chain_tx_polarity_flip_physical{121.0}=0x0 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_rx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 +dport_map_enable=1 +dport_map_port_49=1 +dport_map_port_50=2 +dport_map_port_51=3 +dport_map_port_52=4 +dport_map_port_57=5 +dport_map_port_58=6 +dport_map_port_59=7 +dport_map_port_60=8 +dport_map_port_61=9 +dport_map_port_62=10 +dport_map_port_63=11 +dport_map_port_64=12 +dport_map_port_79=13 +dport_map_port_80=14 +dport_map_port_81=15 +dport_map_port_82=16 +dport_map_port_87=17 +dport_map_port_88=18 +dport_map_port_89=19 +dport_map_port_90=20 +dport_map_port_95=21 +dport_map_port_96=22 +dport_map_port_97=23 +dport_map_port_98=24 +dport_map_port_13=25 +dport_map_port_14=26 +dport_map_port_15=27 +dport_map_port_16=28 +dport_map_port_21=29 +dport_map_port_22=30 +dport_map_port_23=31 +dport_map_port_24=32 +dport_map_port_29=33 +dport_map_port_30=34 +dport_map_port_31=35 +dport_map_port_32=36 +dport_map_port_99=37 +dport_map_port_100=38 +dport_map_port_101=39 +dport_map_port_102=40 +dport_map_port_107=41 +dport_map_port_108=42 +dport_map_port_109=43 +dport_map_port_110=44 +dport_map_port_115=45 +dport_map_port_116=46 +dport_map_port_117=47 +dport_map_port_118=48 +dport_map_port_123=49 +dport_map_port_127=50 +dport_map_port_71=51 +dport_map_port_67=52 +dport_map_port_1=53 +dport_map_port_33=54 +dport_map_port_5=55 +dport_map_port_41=56 + +mmu_init_config="TD3-DELL-lossless" +#sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers.json.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t0.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/custom_led.bin b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..b3966e520c51dd288e36859523157396cb587911 GIT binary patch literal 372 zcmeycHQp`E&DYJv?ZcMl4GumGN)Fz0+!&M_R9Cq%t8H*&ROfeKoNnXU>Bjm%L7V9! zi}D;724zMQMkCdVl?-edosxVV4AU4DXF8<2*=O)Ov0ZQknx>n1GElYl=hC!kkjVADCy0h6qO*I!Jy4_LCjk!f$0IGk_eC%_KwP6 zG>S@KR6d-*oG78>l*pvilz2E%Qkgj^K-oE|DTzV(aMI!A!zru}m=xXJ80P9boxFJF zIr9daJrmq!x-D{B?e<}>j3ooZiVX}5IY8RL(8$=r(#qP#*3RC?*UvvBG%P$OHZGor zmycgWR7_k(R!%-4F)2ACGb_8Gu&9`Uk%?JBQAwGFm5p6PQ%k#|vZ}hKwyxgA)y>_( J(aD(s3IM|vYpehO literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/linkscan_led_fw.bin new file mode 100755 index 0000000000000000000000000000000000000000..c2fa94a2d8cb11161cc337d00971e7267f08d32e GIT binary patch literal 4752 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 X`cUsHXR!vGk^Z4y?GFw9z}SBSTZoUr literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/port_config.ini b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/port_config.ini new file mode 100644 index 000000000000..3dc16e2eb9b9 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 49 twentyfiveGigE1/1/1 1 25000 +Ethernet1 50 twentyfiveGigE1/1/2 2 25000 +Ethernet2 51 twentyfiveGigE1/1/3 3 25000 +Ethernet3 52 twentyfiveGigE1/1/4 4 25000 +Ethernet4 57 twentyfiveGigE1/2/1 5 25000 +Ethernet5 58 twentyfiveGigE1/2/2 6 25000 +Ethernet6 59 twentyfiveGigE1/2/3 7 25000 +Ethernet7 60 twentyfiveGigE1/2/4 8 25000 +Ethernet8 61 twentyfiveGigE1/3/1 9 25000 +Ethernet9 62 twentyfiveGigE1/3/2 10 25000 +Ethernet10 63 twentyfiveGigE1/3/3 11 25000 +Ethernet11 64 twentyfiveGigE1/3/4 12 25000 +Ethernet12 77 twentyfiveGigE1/4/1 13 25000 +Ethernet13 78 twentyfiveGigE1/4/2 14 25000 +Ethernet14 79 twentyfiveGigE1/4/3 15 25000 +Ethernet15 80 twentyfiveGigE1/4/4 16 25000 +Ethernet16 85 twentyfiveGigE1/5/1 17 25000 +Ethernet17 86 twentyfiveGigE1/5/2 18 25000 +Ethernet18 87 twentyfiveGigE1/5/3 19 25000 +Ethernet19 88 twentyfiveGigE1/5/4 20 25000 +Ethernet20 93 twentyfiveGigE1/6/1 21 25000 +Ethernet21 94 twentyfiveGigE1/6/2 22 25000 +Ethernet22 95 twentyfiveGigE1/6/3 23 25000 +Ethernet23 96 twentyfiveGigE1/6/4 24 25000 +Ethernet24 13 twentyfiveGigE1/7/1 25 25000 +Ethernet25 14 twentyfiveGigE1/7/2 26 25000 +Ethernet26 15 twentyfiveGigE1/7/3 27 25000 +Ethernet27 16 twentyfiveGigE1/7/4 28 25000 +Ethernet28 21 twentyfiveGigE1/8/1 29 25000 +Ethernet29 22 twentyfiveGigE1/8/2 30 25000 +Ethernet30 23 twentyfiveGigE1/8/3 31 25000 +Ethernet31 24 twentyfiveGigE1/8/4 32 25000 +Ethernet32 29 twentyfiveGigE1/9/1 33 25000 +Ethernet33 30 twentyfiveGigE1/9/2 34 25000 +Ethernet34 31 twentyfiveGigE1/9/3 35 25000 +Ethernet35 32 twentyfiveGigE1/9/4 36 25000 +Ethernet36 97 twentyfiveGigE1/10/1 37 25000 +Ethernet37 98 twentyfiveGigE1/10/2 38 25000 +Ethernet38 99 twentyfiveGigE1/10/3 39 25000 +Ethernet39 100 twentyfiveGigE1/10/4 40 25000 +Ethernet40 105 twentyfiveGigE1/11/1 41 25000 +Ethernet41 106 twentyfiveGigE1/11/2 42 25000 +Ethernet42 107 twentyfiveGigE1/11/3 43 25000 +Ethernet43 108 twentyfiveGigE1/11/4 44 25000 +Ethernet44 113 twentyfiveGigE1/12/1 45 25000 +Ethernet45 114 twentyfiveGigE1/12/2 46 25000 +Ethernet46 115 twentyfiveGigE1/12/3 47 25000 +Ethernet47 116 twentyfiveGigE1/12/4 48 25000 +Ethernet48 121,122,123,124 hundredGigE1/49 49 100000 +Ethernet49 125,126,127,128 hundredGigE1/50 50 100000 +Ethernet50 69,70,71,72 hundredGigE1/51 51 100000 +Ethernet51 65,66,67,68 hundredGigE1/52 52 100000 +Ethernet52 1,2,3,4 hundredGigE1/53 53 100000 +Ethernet53 33,34,35,36 hundredGigE1/54 54 100000 +Ethernet54 5,6,7,8 hundredGigE1/55 55 100000 +Ethernet55 41,42,43,44 hundredGigE1/56 56 100000 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/qos.json.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/qos.json.j2 new file mode 100644 index 000000000000..d2b3d2b0131c --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/qos.json.j2 @@ -0,0 +1,226 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "0", + "4": "0", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "DWRR", + "weight": "50" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile new file mode 100644 index 000000000000..4753ec3886c4 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5248f-25g.config.bcm diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/td3-s5248f-25g.config.bcm b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/td3-s5248f-25g.config.bcm new file mode 100644 index 000000000000..4095c2d0a4f4 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/td3-s5248f-25g.config.bcm @@ -0,0 +1,355 @@ +os=unix + +dpp_clock_ratio=2:3 +oversubscribe_mode=1 +core_clock_frequency=1525 +l2xmsg_mode=1 +pbmp_oversubscribe=0x7f878787f878787f9fe1e1e1fe1e1e1fe +pbmp_xport_xe=0x7f878787f878787f9fe1e1e1fe1e1e1fe +ifp_inports_support_enable=1 +port_flex_enable=1 +phy_an_c73=3 +l2xmsg_hostbuf_size=8192 +module_64ports=0 +tdma_intr_enable=1 +ipv6_lpm_128b_enable=1 +stat_if_parity_enable=1 +bcm_tunnel_term_compatible_mode=1 +table_dma_enable=1 +schan_intr_enable=0 +parity_enable=1 +parity_correction=1 +miim_intr_enable=1 +max_vp_lags=0 +tdma_intr_enable=1 +tdma_timeout_usec=5000000 +mmu_lossless=0 +pdma_descriptor_prefetch_enable=1 +pktdma_poll_mode_channel_bitmap=1 + +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 +l3_max_ecmp_mode=1 + + +stable_size=0x5500000 + +portmap_1.0=1:100 +portmap_5.0=5:100 +portmap_13.0=13:25 +portmap_14.0=14:25 +portmap_15.0=15:25 +portmap_16.0=16:25 +portmap_21.0=21:25 +portmap_22.0=22:25 +portmap_23.0=23:25 +portmap_24.0=24:25 +portmap_29.0=29:25 +portmap_30.0=30:25 +portmap_31.0=31:25 +portmap_32.0=32:25 +portmap_33.0=33:100 +portmap_41.0=41:100 +portmap_49.0=49:25 +portmap_50.0=50:25 +portmap_51.0=51:25 +portmap_52.0=52:25 +portmap_57.0=57:25 +portmap_58.0=58:25 +portmap_59.0=59:25 +portmap_60.0=60:25 +portmap_61.0=61:25 +portmap_62.0=62:25 +portmap_63.0=63:25 +portmap_64.0=64:25 +portmap_67.0=65:100 +portmap_71.0=69:100 +portmap_79.0=77:25 +portmap_80.0=78:25 +portmap_81.0=79:25 +portmap_82.0=80:25 +portmap_87.0=85:25 +portmap_88.0=86:25 +portmap_89.0=87:25 +portmap_90.0=88:25 +portmap_95.0=93:25 +portmap_96.0=94:25 +portmap_97.0=95:25 +portmap_98.0=96:25 +portmap_99.0=97:25 +portmap_100.0=98:25 +portmap_101.0=99:25 +portmap_102.0=100:25 +portmap_107.0=105:25 +portmap_108.0=106:25 +portmap_109.0=107:25 +portmap_110.0=108:25 +portmap_115.0=113:25 +portmap_116.0=114:25 +portmap_117.0=115:25 +portmap_118.0=116:25 +portmap_123.0=121:100 +portmap_127.0=125:100 +phy_chain_tx_lane_map_physical{1.0}=0x0123 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_tx_lane_map_physical{5.0}=0x1032 +phy_chain_rx_lane_map_physical{5.0}=0x1302 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x1032 +phy_chain_tx_lane_map_physical{21.0}=0x0123 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x1302 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x3120 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_tx_lane_map_physical{49.0}=0x0123 +phy_chain_rx_lane_map_physical{49.0}=0x1032 +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x1032 +phy_chain_tx_lane_map_physical{61.0}=0x0123 +phy_chain_rx_lane_map_physical{61.0}=0x1032 +phy_chain_tx_lane_map_physical{65.0}=0x0123 +phy_chain_rx_lane_map_physical{65.0}=0x2031 +phy_chain_tx_lane_map_physical{69.0}=0x3021 +phy_chain_rx_lane_map_physical{69.0}=0x2130 +phy_chain_tx_lane_map_physical{77.0}=0x3210 +phy_chain_rx_lane_map_physical{77.0}=0x2301 +phy_chain_tx_lane_map_physical{85.0}=0x3210 +phy_chain_rx_lane_map_physical{85.0}=0x2301 +phy_chain_tx_lane_map_physical{93.0}=0x3210 +phy_chain_rx_lane_map_physical{93.0}=0x2301 +phy_chain_tx_lane_map_physical{97.0}=0x3210 +phy_chain_rx_lane_map_physical{97.0}=0x2301 +phy_chain_tx_lane_map_physical{105.0}=0x3210 +phy_chain_rx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{113.0}=0x3210 +phy_chain_rx_lane_map_physical{113.0}=0x2301 +phy_chain_tx_lane_map_physical{121.0}=0x0312 +phy_chain_rx_lane_map_physical{121.0}=0x1023 +phy_chain_tx_lane_map_physical{125.0}=0x2301 +phy_chain_rx_lane_map_physical{125.0}=0x3120 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x1 +phy_chain_tx_polarity_flip_physical{121.0}=0x0 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_rx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 +dport_map_enable=1 +dport_map_port_49=1 +dport_map_port_50=2 +dport_map_port_51=3 +dport_map_port_52=4 +dport_map_port_57=5 +dport_map_port_58=6 +dport_map_port_59=7 +dport_map_port_60=8 +dport_map_port_61=9 +dport_map_port_62=10 +dport_map_port_63=11 +dport_map_port_64=12 +dport_map_port_79=13 +dport_map_port_80=14 +dport_map_port_81=15 +dport_map_port_82=16 +dport_map_port_87=17 +dport_map_port_88=18 +dport_map_port_89=19 +dport_map_port_90=20 +dport_map_port_95=21 +dport_map_port_96=22 +dport_map_port_97=23 +dport_map_port_98=24 +dport_map_port_13=25 +dport_map_port_14=26 +dport_map_port_15=27 +dport_map_port_16=28 +dport_map_port_21=29 +dport_map_port_22=30 +dport_map_port_23=31 +dport_map_port_24=32 +dport_map_port_29=33 +dport_map_port_30=34 +dport_map_port_31=35 +dport_map_port_32=36 +dport_map_port_99=37 +dport_map_port_100=38 +dport_map_port_101=39 +dport_map_port_102=40 +dport_map_port_107=41 +dport_map_port_108=42 +dport_map_port_109=43 +dport_map_port_110=44 +dport_map_port_115=45 +dport_map_port_116=46 +dport_map_port_117=47 +dport_map_port_118=48 +dport_map_port_123=49 +dport_map_port_127=50 +dport_map_port_71=51 +dport_map_port_67=52 +dport_map_port_1=53 +dport_map_port_33=54 +dport_map_port_5=55 +dport_map_port_41=56 + +mmu_init_config="TD3-DELL-lossless" +#sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/default_sku b/device/dell/x86_64-dellemc_s5248f_c3538-r0/default_sku new file mode 100644 index 000000000000..618471d5629d --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/default_sku @@ -0,0 +1 @@ +DellEMC-S5248f-P-25G t1 \ No newline at end of file diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/installer.conf b/device/dell/x86_64-dellemc_s5248f_c3538-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/led_proc_init.soc b/device/dell/x86_64-dellemc_s5248f_c3538-r0/led_proc_init.soc new file mode 100644 index 000000000000..69072c369a64 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/led_proc_init.soc @@ -0,0 +1,6 @@ +# LED microprocessor initialization for Dell S5232 +# +# +#Led0 +led auto on +led start diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/media_settings.json b/device/dell/x86_64-dellemc_s5248f_c3538-r0/media_settings.json new file mode 100644 index 000000000000..8bdc0e7aa984 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/media_settings.json @@ -0,0 +1,442 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "1-32": { + "QSFP28-40GBASE-CR4-1M":{ + "preemphasis": { + "lane0":"0x16440A", + "lane1":"0x16440A", + "lane2":"0x16440A", + "lane3":"0x16440A" + } + }, + "QSFP28-40GBASE-CR4-2M":{ + "preemphasis": { + "lane0":"0x18420A", + "lane1":"0x18420A", + "lane2":"0x18420A", + "lane3":"0x18420A" + } + }, + "QSFP28-40GBASE-CR4-3M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-4M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-5M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-7M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-10M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-1M":{ + "preemphasis": { + "lane0":"0x16440A", + "lane1":"0x16440A", + "lane2":"0x16440A", + "lane3":"0x16440A" + } + }, + "QSFP+-40GBASE-CR4-2M":{ + "preemphasis": { + "lane0":"0x18420A", + "lane1":"0x18420A", + "lane2":"0x18420A", + "lane3":"0x18420A" + } + }, + "QSFP+-40GBASE-CR4-3M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-4M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-5M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-7M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-10M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + } + } + }, + + "PORT_MEDIA_SETTINGS": { + "1": { + "Default": { + "preemphasis": { + "lane0":"0x164509", + "lane1":"0x164509", + "lane2":"0x164509", + "lane3":"0x164509" + } + } + }, + "2": { + "Default": { + "preemphasis": { + "lane0":"0x164509", + "lane1":"0x164509", + "lane2":"0x164509", + "lane3":"0x164509" + } + } + }, + "3": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "4": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "5": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "6": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "7": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "8": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "9": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "10": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "11": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "12": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "13": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "14": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "15": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "16": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "17": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "19": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "20": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "21": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "22": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "23": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "24": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "25": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "26": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "28": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "29": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "30": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "31": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "32": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + } + } +} + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py new file mode 100644 index 000000000000..5b044d0ee30a --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# DellEMC S5248f +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0050/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/psuutil.py new file mode 100644 index 000000000000..8004697d7c0a --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/psuutil.py @@ -0,0 +1,107 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path +import logging +import commands +import sys + + +S5248F_MAX_PSUS = 2 +IPMI_PSU_DATA = "docker exec -it pmon ipmitool sdr list" +IPMI_PSU_DATA_DOCKER = "ipmitool sdr list" +PSU_PRESENCE = "PSU{0}_stat" +# Use this for older firmware +# PSU_PRESENCE="PSU{0}_prsnt" +ipmi_sdr_list = "" + + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + def isDockerEnv(self): + num_docker = open('/proc/self/cgroup', 'r').read().count(":/docker") + if num_docker > 0: + return True + else: + return False + + # Fetch a BMC register + def get_pmc_register(self, reg_name): + + status = 1 + global ipmi_sdr_list + ipmi_dev_node = "/dev/pmi0" + ipmi_cmd = IPMI_PSU_DATA + dockerenv = self.isDockerEnv() + if dockerenv == True: + ipmi_cmd = IPMI_PSU_DATA_DOCKER + + status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + + if status: + logging.error('Failed to execute:' + ipmi_sdr_list) + sys.exit(0) + + for item in ipmi_sdr_list.split("\n"): + if reg_name in item: + output = item.strip() + + if not output: + print('\nFailed to fetch: ' + reg_name + ' sensor ') + sys.exit(0) + + output = output.split('|')[1] + + logging.basicConfig(level=logging.DEBUG) + return output + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + S5248F_MAX_PSUS = 2 + return S5248F_MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + # Until psu_status is implemented this is hardcoded temporarily + + status = 1 + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_reg_name = PSU_PRESENCE.format(index) + psu_status = int(self.get_pmc_register(psu_reg_name), 16) + if (psu_status != 'ERR'): + # Check for PSU presence + if (psu_status == 0x00): + status = 1 + return status + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py new file mode 100644 index 000000000000..e6680dc8d919 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py @@ -0,0 +1,289 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# +# For S5248F-ON, hardware version X01 + +try: + import struct + import sys + import getopt + import time + from sonic_sfp.sfputilbase import SfpUtilBase + from os import * + from mmap import * + +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 56 + PORTS_IN_BLOCK = 56 + + BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" + + _port_to_i2c_mapping = { + 1: 2, + 2: 3, + 3: 4, + 4: 5, + 5: 6, + 6: 7, + 7: 8, + 8: 9, + 9: 10, + 10: 11, + 11: 12, + 12: 13, + 13: 14, + 14: 15, + 15: 16, + 16: 17, + 17: 18, + 18: 19, + 19: 20, + 20: 21, + 21: 22, + 22: 23, + 23: 24, + 24: 25, + 25: 26, + 26: 27, + 27: 28, + 28: 29, + 29: 30, + 30: 31, + 31: 32, + 32: 33, + 33: 34, + 34: 35, + 35: 36, + 36: 37, + 37: 38, + 38: 39, + 39: 40, + 40: 41, + 41: 42, + 42: 43, + 43: 44, + 44: 45, + 45: 46, + 46: 47, + 47: 48, + 48: 49, + # DD + QSFP28 + 49: 50, + 50: 50, + 51: 51, + 52: 51, + 53: 52, + 54: 53, + 55: 54, + 56: 55, + } + + _port_to_eeprom_mapping = {} + + + _global_port_pres_dict = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(49, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def pci_mem_read(self, mm, offset): + mm.seek(offset) + read_data_stream=mm.read(4) + reg_val=struct.unpack('I',read_data_stream) + mem_val = str(reg_val)[1:-2] + # print "reg_val read:%x"%reg_val + return mem_val + + def pci_mem_write(self, mm, offset, data): + mm.seek(offset) + # print "data to write:%x"%data + mm.write(struct.pack('I',data)) + + def pci_set_value(self, resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + + def pci_get_value(self, resource, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_read(mm, offset) + mm.close() + close(fd) + return val + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + else: + self._global_port_pres_dict[port_num] = '0' + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for x in range(self.port_start, self.port_end + 1): + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x]) + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4004 + port_offset = 16388 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off bit for presence + mask = (1 << 1) + if (port_num > 48): + mask = (1 << 4) + + + # ModPrsL is active low + if reg_value & mask == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high + if reg_value & mask == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + def reset(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + # Sleep 1 second to allow it to settle + time.sleep(1) + + reg_value = reg_value | mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 3582116932b1..8cbf72695920 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -8,6 +8,7 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(DELL_Z9264F_PLATFORM_MODULE) \ $(DELL_S5232F_PLATFORM_MODULE) \ + $(DELL_S5248F_PLATFORM_MODULE) \ $(DELL_Z9100_PLATFORM_MODULE) \ $(DELL_S6100_PLATFORM_MODULE) \ $(INGRASYS_S8900_54XC_PLATFORM_MODULE) \ diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index d714de5ab2ad..f32fa7244acc 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -29,3 +29,8 @@ Package: platform-modules-s5232f Architecture: amd64 Depends: linux-image-4.9.0-9-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-s5248f +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.init b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.init new file mode 100755 index 000000000000..0e02b00bc38a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.init @@ -0,0 +1,40 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup S5248f board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + # /usr/local/bin/iom_power_on.sh + /usr/local/bin/s5248f_platform.sh init + + echo "done." + ;; + +stop) + /usr/local/bin/s5248f_platform.sh deinit + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-s5248f.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install new file mode 100644 index 000000000000..084208955317 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install @@ -0,0 +1,9 @@ +s5248f/scripts/s5248f_platform.sh usr/local/bin +s5248f/scripts/check_qsfp.sh usr/local/bin +s5248f/scripts/platform_sensors.py usr/local/bin +s5248f/scripts/sensors usr/bin +s5248f/scripts/pcisysfs.py usr/bin +s5248f/scripts/qsfp_irq_enable.py usr/bin +s5248f/cfg/s5248f-modules.conf etc/modules-load.d +s5248f/systemd/platform-modules-s5248f.service etc/systemd/system +common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5248f_c3538-r0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.postinst new file mode 100644 index 000000000000..f13e2f703130 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.postinst @@ -0,0 +1,10 @@ +# postinst script for S5248f + +# Enable Dell-S5248f-platform-service +depmod -a +systemctl enable platform-modules-s5248f.service +systemctl start platform-modules-s5248f.service + + +#DEBHELPER# + diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index 0a30bebfa301..a7f68a21f55a 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f +MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f COMMON_DIR := common %: diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/cfg/s5248f-modules.conf b/platform/broadcom/sonic-platform-modules-dell/s5248f/cfg/s5248f-modules.conf new file mode 100644 index 000000000000..94639bd3f6e5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/cfg/s5248f-modules.conf @@ -0,0 +1,19 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x + +ipmi_devintf +ipmi_si +dell_s5248f_fpga_ocores +i2c_ocores diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/Makefile b/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/Makefile new file mode 100644 index 000000000000..c179aa5dc931 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := dell_s5248f_fpga_ocores.o + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/dell_s5248f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/dell_s5248f_fpga_ocores.c new file mode 100644 index 000000000000..b9a50c69b225 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/dell_s5248f_fpga_ocores.c @@ -0,0 +1,1626 @@ +/* +* Copyright (C) 2018 Dell Inc +* +* Licensed under the GNU General Public License Version 2 +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +*/ + +/** +* @file fpga_i2ccore.c +* @brief This is a driver to interface with Linux Open Cores drivber for FPGA i2c access +* +************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include //siginfo +#include //rcu_read_lock +#include //kernel_version +#include +#include +#include +#include +#include + + +void __iomem * fpga_base_addr = NULL; +void __iomem * fpga_ctl_addr = NULL; + +#define DRIVER_NAME "fpgapci" +#define PCI_NUM_BARS 4 + +#ifdef DEBUG +# define PRINT(fmt, ...) printk(fmt, ##__VA_ARGS__) +#else +# define PRINT(fmt, ...) +#endif + +/* Maximum size of driver buffer (allocated with kalloc()). + * Needed to copy data from user to kernel space, among other + * things. */ +static const size_t BUF_SIZE = PAGE_SIZE; + +/* Device data used by this driver. */ +struct fpgapci_dev { + /* the kernel pci device data structure */ + struct pci_dev *pci_dev; + + /* upstream root node */ + struct pci_dev *upstream; + + /* kernels virtual addr. for the mapped BARs */ + void * __iomem bar[PCI_NUM_BARS]; + + /* length of each memory region. Used for error checking. */ + size_t bar_length[PCI_NUM_BARS]; + + /* Debug data */ + /* number of hw interrupts handled. */ + int num_handled_interrupts; + int num_undelivered_signals; + int pci_gen; + int pci_num_lanes; + + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + unsigned int xcvr_intr_count; +}; + +static int use_irq = 1; +module_param(use_irq, int, 0644); +MODULE_PARM_DESC(use_irq, "Get an use_irq value from user...\n"); + +static uint32_t num_bus = 0; +module_param(num_bus, int, 0); +MODULE_PARM_DESC(num_bus, + "Number of i2c busses supported by the FPGA on this platform."); + + +/* Xilinx FPGA PCIE info: */ +/* Non-VGA unclassified device: Xilinx Corporation Device 7021*/ +/* Subsystem: Xilinx Corporation Device 0007 */ +//#define VENDOR 0x10EE +#define DEVICE 0x7021 +static phys_addr_t fpga_phys_addr; + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + + +/* struct to hold data related to the pcie device */ +struct pci_data_struct{ + struct pci_dev* dev; + unsigned long long phy_addr_bar0; + unsigned long long phy_len_bar0; + unsigned long long phy_flags_bar0; + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + void * kvirt_addr_bar0; +}; + +/* global variable declarations */ + +/* Static function declarations */ +static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id); +static void fpgapci_remove(struct pci_dev *dev); + +static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); +static int map_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); +static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); + + +struct fpgalogic_i2c { + void __iomem *base; + u32 reg_shift; + u32 reg_io_width; + wait_queue_head_t wait; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; /* see STATE_ */ + int ip_clock_khz; + int bus_clock_khz; + void (*reg_set)(struct fpgalogic_i2c *i2c, int reg, u8 value); + u8 (*reg_get)(struct fpgalogic_i2c *i2c, int reg); + u32 timeout; + struct mutex lock; +}; +/* registers */ +#define FPGAI2C_REG_PRELOW 0 +#define FPGAI2C_REG_PREHIGH 1 +#define FPGAI2C_REG_CONTROL 2 +#define FPGAI2C_REG_DATA 3 +#define FPGAI2C_REG_CMD 4 /* write only */ +#define FPGAI2C_REG_STATUS 4 /* read only, same address as FPGAI2C_REG_CMD */ +#define FPGAI2C_REG_VER 5 + + + +#define FPGAI2C_REG_CTRL_IEN 0x40 +#define FPGAI2C_REG_CTRL_EN 0x80 + +#define FPGAI2C_REG_CMD_START 0x91 +#define FPGAI2C_REG_CMD_STOP 0x41 +#define FPGAI2C_REG_CMD_READ 0x21 +#define FPGAI2C_REG_CMD_WRITE 0x11 +#define FPGAI2C_REG_CMD_READ_ACK 0x21 +#define FPGAI2C_REG_CMD_READ_NACK 0x29 +#define FPGAI2C_REG_CMD_IACK 0x01 + +#define FPGAI2C_REG_STAT_IF 0x01 +#define FPGAI2C_REG_STAT_TIP 0x02 +#define FPGAI2C_REG_STAT_ARBLOST 0x20 +#define FPGAI2C_REG_STAT_BUSY 0x40 +#define FPGAI2C_REG_STAT_NACK 0x80 + +/* SR[7:0] - Status register */ +#define FPGAI2C_REG_SR_RXACK (1 << 7) /* Receive acknowledge from slave ‘1’ = No acknowledge received*/ +#define FPGAI2C_REG_SR_BUSY (1 << 6) /* Busy, I2C bus busy (as defined by start / stop bits) */ +#define FPGAI2C_REG_SR_AL (1 << 5) /* Arbitration lost - fpga i2c logic lost arbitration */ +#define FPGAI2C_REG_SR_TIP (1 << 1) /* Transfer in progress */ +#define FPGAI2C_REG_SR_IF (1 << 0) /* Interrupt flag */ + +enum { + STATE_DONE = 0, + STATE_INIT, + STATE_ADDR, + STATE_ADDR10, + STATE_START, + STATE_WRITE, + STATE_READ, + STATE_STOP, + STATE_ERROR, +}; + +#define TYPE_FPGALOGIC 0 +#define TYPE_GRLIB 1 + +/*I2C_CH1 Offset address from PCIE BAR 0*/ +#define FPGALOGIC_I2C_BASE 0x00006000 +#define FPGALOGIC_CH_OFFSET 0x10 + +#define i2c_bus_controller_numb 1 +#define I2C_PCI_MAX_BUS (16) +#define I2C_PCI_MAX_BUS_REV00 (7) +#define DELL_I2C_CLOCK_LEGACY 0 +#define DELL_I2C_CLOCK_PRESERVE (~0U) +#define I2C_PCI_BUS_NUM_5 5 +#define I2C_PCI_BUS_NUM_7 7 +#define I2C_PCI_BUS_NUM_8 8 +#define I2C_PCI_BUS_NUM_10 10 +#define I2C_PCI_BUS_NUM_12 12 +#define I2C_PCI_BUS_NUM_16 16 + +#define IRQ_LTCH_STS 0x20 +#define PRSNT_LTCH_STS 0x10 + +#define PORT_CTRL_OFFSET 0x4000 +#define PORT_STS_OFFSET 0x4004 +#define PORT_IRQ_STS_OFFSET 0x4008 +#define PORT_IRQ_EN_OFFSET 0x400C +#define MB_BRD_REV_TYPE 0x0008 +#define MB_BRD_REV_MASK 0x00f0 +#define MB_BRD_REV_00 0x0000 +#define MB_BRD_REV_01 0x0010 +#define MB_BRD_REV_02 0x0020 +#define MB_BRD_REV_03 0x0030 +#define MB_BRD_TYPE_MASK 0x000f +#define BRD_TYPE_Z9232_NON_NEBS 0x0 +#define BRD_TYPE_Z9232_NEBS 0x1 +#define BRD_TYPE_Z9264_NON_NEBS 0x2 +#define BRD_TYPE_Z9264_NEBS 0x3 +#define BRD_TYPE_S5212_NON_NEBS 0x4 +#define BRD_TYPE_S5212_NEBS 0x5 +#define BRD_TYPE_S5224_NON_NEBS 0x6 +#define BRD_TYPE_S5224_NEBS 0x7 +#define BRD_TYPE_S5248_NON_NEBS 0x8 +#define BRD_TYPE_S5248_NEBS 0x9 +#define BRD_TYPE_S5296_NON_NEBS 0xa +#define BRD_TYPE_S5296_NEBS 0xb +#define BRD_TYPE_S5232_NON_NEBS 0xc +#define BRD_TYPE_S5232_NEBS 0xd + +#define FPGA_CTL_REG_SIZE 0x6000 +#define MSI_VECTOR_MAP_MASK 0x1f +#define MSI_VECTOR_MAP1 0x58 +#define I2C_CH1_MSI_MAP_VECT_8 0x00000008 +#define I2C_CH2_MSI_MAP_VECT_9 0x00000120 +#define I2C_CH3_MSI_MAP_VECT_10 0x00002800 +#define I2C_CH4_MSI_MAP_VECT_11 0x00058000 +#define I2C_CH5_MSI_MAP_VECT_12 0x00c00000 +#define I2C_CH6_MSI_MAP_VECT_13 0x15000000 +#define MSI_VECTOR_MAP2 0x5c +#define I2C_CH7_MSI_MAP_VECT_14 0x0000000e +#define MSI_VECTOR_MAP3 0x9c +#define I2C_CH8_MSI_MAP_VECT_8 0x00800000 +#define I2C_CH8_MSI_MAP_VECT_16 0x01100000 +#define I2C_CH9_MSI_MAP_VECT_9 0x12000000 +#define I2C_CH9_MSI_MAP_VECT_17 0x24000000 +#define MSI_VECTOR_MAP4 0xa0 +#define I2C_CH10_MSI_MAP_VECT_10 0x0000000a +#define I2C_CH10_MSI_MAP_VECT_18 0x00000012 +#define I2C_CH11_MSI_MAP_VECT_11 0x00000120 +#define I2C_CH11_MSI_MAP_VECT_19 0x00000260 +#define I2C_CH12_MSI_MAP_VECT_12 0x00002800 +#define I2C_CH12_MSI_MAP_VECT_20 0x00005000 +#define I2C_CH13_MSI_MAP_VECT_13 0x00058000 +#define I2C_CH13_MSI_MAP_VECT_21 0x000a8000 +#define I2C_CH14_MSI_MAP_VECT_14 0x00c00000 +#define I2C_CH14_MSI_MAP_VECT_22 0x01600000 +#define I2C_CH15_MSI_MAP_VECT_8 0x10000000 +#define I2C_CH15_MSI_MAP_VECT_23 0x2e000000 +#define MSI_VECTOR_MAP5 0xa4 +#define I2C_CH16_MSI_MAP_VECT_9 0x00000009 +#define I2C_CH16_MSI_MAP_VECT_24 0x00000018 + +#define MSI_VECTOR_REV_00 16 +#define MSI_VECTOR_REV_01 32 + +#define FPGA_MSI_VECTOR_ID_4 4 +#define FPGA_MSI_VECTOR_ID_5 5 +#define FPGA_MSI_VECTOR_ID_8 8 +#define FPGA_MSI_VECTOR_ID_9 9 +#define FPGA_MSI_VECTOR_ID_10 10 +#define FPGA_MSI_VECTOR_ID_11 11 +#define FPGA_MSI_VECTOR_ID_12 12 +#define FPGA_MSI_VECTOR_ID_13 13 +#define FPGA_MSI_VECTOR_ID_14 14 +#define FPGA_MSI_VECTOR_ID_15 15 /*Note: this is external MSI vector id */ +#define FPGA_MSI_VECTOR_ID_16 16 +#define FPGA_MSI_VECTOR_ID_17 17 +#define FPGA_MSI_VECTOR_ID_18 18 +#define FPGA_MSI_VECTOR_ID_19 19 +#define FPGA_MSI_VECTOR_ID_20 20 +#define FPGA_MSI_VECTOR_ID_21 21 +#define FPGA_MSI_VECTOR_ID_22 22 +#define FPGA_MSI_VECTOR_ID_23 23 +#define FPGA_MSI_VECTOR_ID_24 24 + + + +static int total_i2c_pci_bus = 0; +static uint32_t board_rev_type = 0; +static struct fpgalogic_i2c fpgalogic_i2c[I2C_PCI_MAX_BUS]; +static struct i2c_adapter i2c_pci_adap[I2C_PCI_MAX_BUS]; +static struct mutex i2c_xfer_lock[I2C_PCI_MAX_BUS]; + +static void fpgai2c_reg_set_8(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite8(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_16(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite16(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_32(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite32(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_16be(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_32be(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_8(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread8(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_16(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread16(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_32(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread32(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_16be(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread16be(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_32be(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread32be(i2c->base + (reg << i2c->reg_shift)); +} + +static inline void fpgai2c_reg_set(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + i2c->reg_set(i2c, reg, value); + udelay(100); +} + +static inline u8 fpgai2c_reg_get(struct fpgalogic_i2c *i2c, int reg) +{ + udelay(100); + return i2c->reg_get(i2c, reg); +} + +static void fpgai2c_dump(struct fpgalogic_i2c *i2c) +{ + u8 tmp; + + PRINT("Logic register dump:\n"); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PRELOW); + PRINT("FPGAI2C_REG_PRELOW (%d) = 0x%x\n",FPGAI2C_REG_PRELOW,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PREHIGH); + PRINT("FPGAI2C_REG_PREHIGH(%d) = 0x%x\n",FPGAI2C_REG_PREHIGH,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + PRINT("FPGAI2C_REG_CONTROL(%d) = 0x%x\n",FPGAI2C_REG_CONTROL,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + PRINT("FPGAI2C_REG_DATA (%d) = 0x%x\n",FPGAI2C_REG_DATA,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CMD); + PRINT("FPGAI2C_REG_CMD (%d) = 0x%x\n",FPGAI2C_REG_CMD,tmp); +} + +static void fpgai2c_stop(struct fpgalogic_i2c *i2c) +{ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); +} + +/* + * dell_get_mutex must be called prior to calling this function. + */ +static int fpgai2c_poll(struct fpgalogic_i2c *i2c) +{ + u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + struct i2c_msg *msg = i2c->msg; + u8 addr; + + /* Ready? */ + if (stat & FPGAI2C_REG_STAT_TIP) + return -EBUSY; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* Stop has been sent */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (i2c->state == STATE_ERROR) + return -EIO; + return 0; + } + + /* Error? */ + if (stat & FPGAI2C_REG_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -EAGAIN; + } + + if (i2c->state == STATE_INIT) { + if (stat & FPGAI2C_REG_STAT_BUSY) + return -EBUSY; + + i2c->state = STATE_ADDR; + } + + if (i2c->state == STATE_ADDR) { + /* 10 bit address? */ + if (i2c->msg->flags & I2C_M_TEN) { + addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6); + i2c->state = STATE_ADDR10; + } else { + addr = (i2c->msg->addr << 1); + i2c->state = STATE_START; + } + + /* Set read bit if necessary */ + addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0; + + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + + return 0; + } + + /* Second part of 10 bit addressing */ + if (i2c->state == STATE_ADDR10) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, i2c->msg->addr & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + + i2c->state = STATE_START; + return 0; + } + + if (i2c->state == STATE_START || i2c->state == STATE_WRITE) { + i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & FPGAI2C_REG_STAT_NACK) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -ENXIO; + } + } else { + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + } + + if (i2c->pos >= msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { + if (!(msg->flags & I2C_M_NOSTART)) { + i2c->state = STATE_ADDR; + return 0; + } else { + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } + } else { + i2c->state = STATE_DONE; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return 0; + } + } + + if (i2c->state == STATE_READ) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len - 1) ? + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + } else { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + } + + return 0; +} + +static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ind = 0, port_status=0, port_irq_status=0; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); + PRINT("%s:xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + for(ind=0;ind<64;ind++) + { + port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + } + return sprintf(buf,"0x%04x\n",fpgapci->xcvr_intr_count); +} +static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL); + +static struct attribute *port_attrs[] = { + &dev_attr_port_msi.attr, + NULL, +}; + +static struct attribute_group port_attr_grp = { + .attrs = port_attrs, +}; + + +static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) +{ + struct pci_dev *pdev = dev; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + int ind = 0, port_status=0, port_irq_status=0; + for(ind=0;ind<32;ind++) + { + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + if(port_irq_status&(IRQ_LTCH_STS|PRSNT_LTCH_STS)) + { + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + //write on clear + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + } + } + fpgapci->xcvr_intr_count++; + PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); + return IRQ_HANDLED; +} + +static irqreturn_t fpgaport_33_64_isr(int irq, void *dev) +{ + struct pci_dev *pdev = dev; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + int ind = 0, port_status=0, port_irq_status=0; + for(ind=32;ind<64;ind++) + { + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + if(port_irq_status| (IRQ_LTCH_STS|PRSNT_LTCH_STS)) + { + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + } + } + fpgapci->xcvr_intr_count++; + PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); + return IRQ_HANDLED; +} + +static void fpgai2c_process(struct fpgalogic_i2c *i2c) +{ + struct i2c_msg *msg = i2c->msg; + u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + + PRINT("fpgai2c_process in. status reg :0x%x\n", stat); + + if ((i2c->state == STATE_STOP) || (i2c->state == STATE_ERROR)) { + /* stop has been sent */ + PRINT("fpgai2c_process FPGAI2C_REG_CMD_IACK stat = 0x%x Set FPGAI2C_REG_CMD(0%x) FPGAI2C_REG_CMD_IACK = 0x%x\n" \ + ,stat, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if(i2c->state == STATE_STOP) { + i2c->state = STATE_DONE; + } + wake_up(&i2c->wait); + return; + } + + + /* error? */ + if (stat & FPGAI2C_REG_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + PRINT("fpgai2c_process FPGAI2C_REG_STAT_ARBLOST FPGAI2C_REG_CMD_STOP\n"); + fpgai2c_stop(i2c); + return; + } + + if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { + i2c->state = + (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & FPGAI2C_REG_STAT_NACK) { + i2c->state = STATE_ERROR; + fpgai2c_stop(i2c); + return; + } + } else + { + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + } + + /* end of msg? */ + if (i2c->pos == msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { /* end? */ + /* send start? */ + if (!(msg->flags & I2C_M_NOSTART)) { + + u8 addr = (msg->addr << 1); + + if (msg->flags & I2C_M_RD) + addr |= 1; + + i2c->state = STATE_START; + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + return; + } else + { + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } + } else { + i2c->state = STATE_STOP; + fpgai2c_stop(i2c); + return; + } + } + + if (i2c->state == STATE_READ) { + PRINT("fpgai2c_poll STATE_READ i2c->pos=%d msg->len-1 = 0x%x set FPGAI2C_REG_CMD = 0x%x\n",i2c->pos, msg->len-1, + i2c->pos == (msg->len-1) ? FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len-1) ? + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + } else { + PRINT("fpgai2c_process set FPGAI2C_REG_DATA(0x%x)\n",FPGAI2C_REG_DATA); + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + } +} + +static irqreturn_t fpgai2c_isr(int irq, void *dev_id) +{ + struct fpgalogic_i2c *i2c = dev_id; + fpgai2c_process(i2c); + + return IRQ_HANDLED; +} +void dell_get_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_lock(&i2c->lock); +} + +/** + * dell_release_mutex - release mutex + */ +void dell_release_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_unlock(&i2c->lock); +} + +static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + struct fpgalogic_i2c *i2c = i2c_get_adapdata(adap); + int ret; + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + + i2c->msg = msgs; + i2c->pos = 0; + i2c->nmsgs = num; + i2c->state = (use_irq == 1) ? STATE_START : STATE_INIT; + + PRINT("i2c->msg->addr = 0x%x i2c->msg->flags = 0x%x\n",i2c->msg->addr,i2c->msg->flags); + PRINT("I2C_M_RD = 0x%x i2c->msg->addr << 1 = 0x%x\n",I2C_M_RD,i2c->msg->addr << 1); + + if (!use_irq) { + /* Handle the transfer */ + while (time_before(jiffies, timeout)) { + dell_get_mutex(i2c); + ret = fpgai2c_poll(i2c); + dell_release_mutex(i2c); + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) + return (i2c->state == STATE_DONE) ? num : ret; + + if (ret == 0) + timeout = jiffies + HZ; + + usleep_range(5, 15); + } + + i2c->state = STATE_ERROR; + + return -ETIMEDOUT; + + + } else { + ret = -ETIMEDOUT; + PRINT("Set FPGAI2C_REG_DATA(0%x) val = 0x%x\n",FPGAI2C_REG_DATA, + (i2c->msg->addr << 1) | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); + + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, + (i2c->msg->addr << 1) | + ((i2c->msg->flags & I2C_M_RD) ? 1:0)); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + + /* Interrupt mode */ + if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || + (i2c->state == STATE_DONE), HZ)) + ret = (i2c->state == STATE_DONE) ? num : -EIO; + return ret; + } +} + +static int fpgai2c_init(struct fpgalogic_i2c *i2c) +{ + int prescale; + int diff; + u8 ctrl; + + if (i2c->reg_io_width == 0) + i2c->reg_io_width = 1; /* Set to default value */ + + if (!i2c->reg_set || !i2c->reg_get) { + bool be = 0; //1:big_endian 0:little_endian + + switch (i2c->reg_io_width) { + case 1: + i2c->reg_set = fpgai2c_reg_set_8; + i2c->reg_get = fpgai2c_reg_get_8; + break; + + case 2: + i2c->reg_set = be ? fpgai2c_reg_set_16be : fpgai2c_reg_set_16; + i2c->reg_get = be ? fpgai2c_reg_get_16be : fpgai2c_reg_get_16; + break; + + case 4: + i2c->reg_set = be ? fpgai2c_reg_set_32be : fpgai2c_reg_set_32; + i2c->reg_get = be ? fpgai2c_reg_get_32be : fpgai2c_reg_get_32; + break; + + default: + PRINT("Unsupported I/O width (%d)\n", + i2c->reg_io_width); + return -EINVAL; + } + } + + ctrl = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + + PRINT("%s(), line:%d\n", __func__, __LINE__); + PRINT("i2c->base = 0x%p\n",i2c->base); + + PRINT("ctrl = 0x%x\n",ctrl); + PRINT("set ctrl = 0x%x\n",ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); + + /* make sure the device is disabled */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); + + /* + * I2C Frequency depends on host clock + * input clock of 100MHz + * prescale to 100MHz / ( 5*100kHz) -1 = 199 = 0x4F 100000/(5*100)-1=199=0xc7 + */ + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); + + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + PRINT("Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } + + fpgai2c_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); + + /* Init the device */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (!use_irq) + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); + else + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); + + fpgai2c_dump(i2c); + + /* Initialize interrupt handlers if not already done */ + init_waitqueue_head(&i2c->wait); + + return 0; +} + + +static u32 fpgai2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm fpgai2c_algorithm = { + .master_xfer = fpgai2c_xfer, + .functionality = fpgai2c_func, +}; + +static int i2c_pci_add_bus (struct i2c_adapter *adap) +{ + int ret = 0; + /* Register new adapter */ + adap->algo = &fpgai2c_algorithm; + ret = i2c_add_numbered_adapter(adap); + return ret; +} + +static int i2c_init_internal_data(void) +{ + int i; + PRINT("%s(), line:%d\n", __func__, __LINE__); + + for( i = 0; i < total_i2c_pci_bus; i++ ) + { + fpgalogic_i2c[i].reg_shift = 0; /* 8 bit registers */ + fpgalogic_i2c[i].reg_io_width = 1; /* 8 bit read/write */ + fpgalogic_i2c[i].timeout = 500;//1000;//1ms + fpgalogic_i2c[i].ip_clock_khz = 100000;//100000;/* input clock of 100MHz */ + fpgalogic_i2c[i].bus_clock_khz = 100; + fpgalogic_i2c[i].base = fpga_base_addr + i*FPGALOGIC_CH_OFFSET; + mutex_init(&fpgalogic_i2c[i].lock); + fpgai2c_init(&fpgalogic_i2c[i]); + } + + return 0; +} + + +static int i2c_pci_init (void) +{ + int i; + + if (num_bus == 0) { + board_rev_type = ioread32(fpga_ctl_addr + MB_BRD_REV_TYPE); + + if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { + num_bus = I2C_PCI_MAX_BUS_REV00; + } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + switch (board_rev_type & MB_BRD_TYPE_MASK){ + case BRD_TYPE_S5212_NON_NEBS: + case BRD_TYPE_S5212_NEBS: + num_bus = I2C_PCI_BUS_NUM_5; + break; + case BRD_TYPE_S5224_NON_NEBS: + case BRD_TYPE_S5224_NEBS: + num_bus = I2C_PCI_BUS_NUM_7; + break; + case BRD_TYPE_Z9232_NON_NEBS: + case BRD_TYPE_Z9232_NEBS: + case BRD_TYPE_S5232_NON_NEBS: + case BRD_TYPE_S5232_NEBS: + num_bus = I2C_PCI_BUS_NUM_8; + break; + case BRD_TYPE_S5248_NON_NEBS: + case BRD_TYPE_S5248_NEBS: + num_bus = I2C_PCI_BUS_NUM_10; + break; + case BRD_TYPE_Z9264_NON_NEBS: + case BRD_TYPE_Z9264_NEBS: + num_bus = I2C_PCI_BUS_NUM_12; + break; + case BRD_TYPE_S5296_NON_NEBS: + case BRD_TYPE_S5296_NEBS: + num_bus = I2C_PCI_BUS_NUM_16; + break; + default: + num_bus = I2C_PCI_BUS_NUM_16; + printk("Wrong BRD_TYPE: 0x%x\n", board_rev_type); + break; + } + } else { + printk("Wrong board_rev_type 0x%x\n", board_rev_type); + } + } + + printk("board_rev_type 0x%x, num_bus 0x%x\n", board_rev_type, num_bus); + total_i2c_pci_bus = num_bus; + + memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); + memset (&fpgalogic_i2c, 0, sizeof(fpgalogic_i2c)); + for(i=0; i < i2c_bus_controller_numb; i++) + mutex_init(&i2c_xfer_lock[i]); + + /* Initialize driver's itnernal data structures */ + i2c_init_internal_data(); + + for (i = 0 ; i < total_i2c_pci_bus; i ++) { + + i2c_pci_adap[i].owner = THIS_MODULE; + i2c_pci_adap[i].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + + i2c_pci_adap[i].algo_data = &fpgalogic_i2c[i]; + /* /dev/i2c-600 ~ /dev/i2c-615 for FPGA LOGIC I2C channel controller 1-7 */ + i2c_pci_adap[i].nr = i+600; + sprintf( i2c_pci_adap[ i ].name, "i2c-pci-%d", i ); + /* Add the bus via the algorithm code */ + if( i2c_pci_add_bus( &i2c_pci_adap[ i ] ) != 0 ) + { + PRINT("Cannot add bus %d to algorithm layer\n", i ); + return( -ENODEV ); + } + i2c_set_adapdata(&i2c_pci_adap[i], &fpgalogic_i2c[i]); + + PRINT( "Registered bus id: %s\n", kobject_name(&i2c_pci_adap[ i ].dev.kobj)); + } + + return 0; +} + +static void i2c_pci_deinit(void) +{ + int i; + for( i = 0; i < total_i2c_pci_bus; i++ ){ + i2c_del_adapter(&i2c_pci_adap[i]); + } + +} + +/* Find upstream PCIe root node. + * Used for re-training and disabling AER. */ +static struct pci_dev* find_upstream_dev (struct pci_dev *dev) +{ + struct pci_bus *bus = 0; + struct pci_dev *bridge = 0; + struct pci_dev *cur = 0; + int found_dev = 0; + + bus = dev->bus; + if (bus == 0) { + PRINT ( "Device doesn't have an associated bus!\n"); + return 0; + } + + bridge = bus->self; + if (bridge == 0) { + PRINT ( "Can't get the bridge for the bus!\n"); + return 0; + } + + PRINT ( "Upstream device %x/%x, bus:slot.func %02x:%02x.%02x\n", + bridge->vendor, bridge->device, + bridge->bus->number, PCI_SLOT(bridge->devfn), PCI_FUNC(bridge->devfn)); + + PRINT ( "List of downstream devices:"); + list_for_each_entry (cur, &bus->devices, bus_list) { + if (cur != 0) { + PRINT ( " %x/%x", cur->vendor, cur->device); + if (cur == dev) { + found_dev = 1; + } + } + } + PRINT ( "\n"); + if (found_dev) { + return bridge; + } else { + PRINT ( "Couldn't find upstream device!\n"); + return 0; + } +} + + +static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) +{ + int i; + + for (i = 0; i < PCI_NUM_BARS; i++) { + unsigned long bar_start = pci_resource_start(dev, i); + if (bar_start) { + unsigned long bar_end = pci_resource_end(dev, i); + unsigned long bar_flags = pci_resource_flags(dev, i); + PRINT ( "BAR[%d] 0x%08lx-0x%08lx flags 0x%08lx", + i, bar_start, bar_end, bar_flags); + } + } + + return 0; +} + + +/** + * Map the device memory regions into kernel virtual address space + * after verifying their sizes respect the minimum sizes needed, given + * by the bar_min_len[] array. + */ +static int map_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) +{ + int i; + + for (i = 0; i < PCI_NUM_BARS; i++){ + phys_addr_t bar_start = pci_resource_start(dev, i); + phys_addr_t bar_end = pci_resource_end(dev, i); + unsigned long bar_length = bar_end - bar_start + 1; + fpgapci->bar_length[i] = bar_length; + + + if (!bar_start || !bar_end) { + fpgapci->bar_length[i] = 0; + continue; + } + + if (bar_length < 1) { + PRINT ( "BAR #%d length is less than 1 byte\n", i); + continue; + } + + PRINT ( "bar_start=%llx, bar_end=%llx, bar_length=%lx, flag=%lx\n", bar_start, + bar_end, bar_length, pci_resource_flags(dev, i)); + + /* map the device memory or IO region into kernel virtual + * address space */ + fpgapci->bar[i] = ioremap_nocache (bar_start + FPGALOGIC_I2C_BASE, I2C_PCI_MAX_BUS * FPGALOGIC_CH_OFFSET); + + if (!fpgapci->bar[i]) { + PRINT ( "Could not map BAR #%d.\n", i); + return -1; + } + + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.", i, + fpgapci->bar[i], bar_length); + + if(i == 0) //FPGA register is in the BAR[0] + { + + fpga_phys_addr = bar_start; + fpga_ctl_addr = ioremap_nocache (bar_start, FPGA_CTL_REG_SIZE); + fpga_base_addr = fpgapci->bar[i]; + } + + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.\n", i, + fpgapci->bar[i], bar_length); + } + return 0; +} + +static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) +{ + int i; + + for (i = 0; i < PCI_NUM_BARS; i++) { + if (fpgapci->bar[i]) { + pci_iounmap(dev, fpgapci->bar[i]); + fpgapci->bar[i] = NULL; + } + } +} + +#define FPGA_PCI_NAME "FPGA_PCI" + +/** + * @brief Register specific function with msi interrupt line + * @param dev Pointer to pci-device, which should be allocated + * @param int interrupt number relative to global interrupt number + * @return Returns error code or zero if success + * */ +static int register_intr_handler(struct pci_dev *dev, int irq_num_id) +{ + int err = 0; + struct fpgapci_dev *fpgapci = 0; + + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return err; + } + + if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { + /* Request interrupt line for unique function + * alternatively function will be called from free_irq as well + * with flag IRQF_SHARED */ + switch(irq_num_id) { + /* Currently we only support test vector 2 for FPGA Logic I2C channel + * controller 1-7 interrupt*/ + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_14: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; + } + } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ + switch (irq_num_id) { + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_14: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_15: + /*it is an external interrupt number. Ignore this case */ + break; + case FPGA_MSI_VECTOR_ID_16: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_7) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[7]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_17: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[8]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_18: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[9]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_19: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[10]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_20: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[11]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_21: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[12]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_22: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[13]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_23: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[14]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_24: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[15]); + fpgapci->irq_assigned++; + } + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; + } + } + + return err; +} +/* Mask for MSI Multi message enable bits */ +#define MSI_MME 0x70 +/** + * These enums define the type of interrupt scheme that the overall + * system uses. + */ +enum fpga_irq_type { + INT_MSI_SINGLE, + INT_MSI_MULTI, + INT_MSIX, + INT_NONE, + INT_FENCE /* Last item to guard from loop run-overs */ +}; +/** + * @def PCI_DEVICE_STATUS + * define the offset for STS register + * from the start of PCI config space as specified in the + * NVME_Comliance 1.0b. offset 06h:STS - Device status. + * This register has error status for NVME PCI Exress + * Card. After reading data from this reagister, the driver + * will identify if any error is set during the operation and + * report as kernel alert message. + */ +#define PCI_DEVICE_STATUS 0x6 +/** + * @def NEXT_MASK + * This indicates the location of the next capability item + * in the list. + */ +#define NEXT_MASK 0xFF00 +/** + * @def MSIXCAP_ID + * This bit indicates if the pointer leading to this position + * is a capability. + */ +#define MSIXCAP_ID 0x11 +/** + * @def MSICAP_ID + * This bit indicates if the pointer leading to this position + * is a capability. + */ +#define MSICAP_ID 0x5 + +/** + * @def CL_MASK + * This bit position indicates Capabilities List of the controller + * The controller should support the PCI Power Management cap as a + * minimum. + */ +#define CL_MASK 0x0010 + +/** + * @def CAP_REG + * Set to offset defined in NVME Spec 1.0b. + */ +#define CAP_REG 0x34 +static void msi_set_enable(struct pci_dev *dev, int enable) +{ + int pos,maxvec; + u16 control; + int request_private_bits = 4; + + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + + if (pos) { + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); + maxvec = 1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1); + PRINT("control = 0x%x maxvec = 0x%x\n", control, maxvec); + control &= ~PCI_MSI_FLAGS_ENABLE; + + + /* + * The PCI 2.3 spec mandates that there are at most 32 + * interrupts. If this device asks for more, only give it one. + */ + if (request_private_bits > 5) { + request_private_bits = 0; + } + + /* Update the number of IRQs the device has available to it */ + control &= ~PCI_MSI_FLAGS_QSIZE; + control |= (request_private_bits << 4); + + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); + } +} +/** + * @brief Enables pcie-device and claims/remaps neccessary bar resources + * @param dev Pointer to pci-device, which should be allocated + * @return Returns error code or zero if success + * */ +static int fpgapci_setup_device(struct fpgapci_dev *fpgapci,struct pci_dev *dev) +{ + int err = 0; + + /* wake up the pci device */ + err = pci_enable_device(dev); + if(err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_en; + } + + /* on platforms with buggy ACPI, pdev->msi_enabled may be set to + * allow pci_enable_device to work. This indicates INTx was not routed + * and only MSI should be used + */ + + pci_set_master(dev); + + /* Setup the BAR memory regions */ + err = pci_request_regions(dev, DRIVER_NAME); + if (err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_req; + } + + scan_bars(fpgapci, dev); + + if (map_bars(fpgapci, dev)) { + goto fail_map_bars; + } + + i2c_pci_init(); + + return 0; + /* ERROR HANDLING */ +fail_map_bars: + pci_release_regions(dev); +error_pci_req: + pci_disable_device(dev); +error_pci_en: + return -ENODEV; +} + +static int fpgapci_configure_msi(struct fpgapci_dev *fpgapci,struct pci_dev *dev) +{ + int err = 0, i; + int request_vec; + + msi_set_enable(dev,1); + PRINT("Check MSI capability after msi_set_enable\n"); + + + /*Above 4.1.12*/ + request_vec = total_i2c_pci_bus; + err = pci_alloc_irq_vectors(dev, request_vec, pci_msi_vec_count(dev), + PCI_IRQ_MSI);//PCI_IRQ_AFFINITY | PCI_IRQ_MSI); + + if (err <= 0) { + PRINT("Cannot set MSI vector (%d)\n", err); + goto error_no_msi; + } else { + PRINT("Got %d MSI vectors starting at %d\n", err, dev->irq); + if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { + if (err < MSI_VECTOR_REV_00) { + goto error_disable_msi; + } + } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + if (err < MSI_VECTOR_REV_01) { + goto error_disable_msi; + } + } + } + fpgapci->irq_first = dev->irq; + fpgapci->irq_length = err; + fpgapci->irq_assigned = 0; + + + for(i = 0; i < fpgapci->irq_length; i++) { + err = register_intr_handler(dev, i); + if (err) { + PRINT("Cannot request Interrupt number %d\n", i); + goto error_pci_req_irq; + } + } + + return 0; + +error_pci_req_irq: + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + if (i < 7) + free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); + else + free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); + } +error_disable_msi: + pci_disable_msi(fpgapci->pci_dev); +error_no_msi: + return -ENOSPC; +} + +static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + struct fpgapci_dev *fpgapci = 0; + int status = 0; + +#ifdef TEST + PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", + dev->vendor, dev->device, dev->class, + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); +#endif + fpgapci = kzalloc(sizeof(struct fpgapci_dev), GFP_KERNEL); + + if (!fpgapci) { + PRINT( "Couldn't allocate memory!\n"); + goto fail_kzalloc; + } + + fpgapci->pci_dev = dev; + dev_set_drvdata(&dev->dev, (void*)fpgapci); + + status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); + if (status) { + printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); + } + + fpgapci->upstream = find_upstream_dev (dev); + + if(fpgapci_setup_device(fpgapci,dev)) { + goto error_no_device; + } + + if (use_irq) { + if(fpgapci_configure_msi(fpgapci,dev)) { + goto error_cannot_configure; + } + } + + + return 0; + /* ERROR HANDLING */ +error_cannot_configure: + printk("error_cannot_configure\n"); + free_bars (fpgapci, dev); + pci_release_regions(dev); + pci_disable_device(dev); +error_no_device: + i2c_pci_deinit(); + printk("error_no_device\n"); +fail_kzalloc: + return -1; + + +} + +static void fpgapci_remove(struct pci_dev *dev) +{ + struct fpgapci_dev *fpgapci = 0; + int i; + PRINT (": dev is %p\n", dev); + + if (dev == 0) { + PRINT ( ": dev is 0\n"); + return; + } + + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return; + } + i2c_pci_deinit(); + // + if (use_irq) + { + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + if (i < 7) + free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); + else + free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); + } + } + pci_disable_msi(fpgapci->pci_dev); + free_bars (fpgapci, dev); + pci_disable_device(dev); + pci_release_regions(dev); + + kfree (fpgapci); +} + +static const struct pci_device_id fpgapci_ids[] = { + {PCI_DEVICE(PCI_VENDOR_ID_XILINX, DEVICE)}, + {0, }, +}; + +MODULE_DEVICE_TABLE(pci, fpgapci_ids); + +static struct pci_driver fpgapci_driver = { + .name = DRIVER_NAME, + .id_table = fpgapci_ids, + .probe = fpgapci_probe, + .remove = fpgapci_remove, + /* resume, suspend are optional */ +}; + +/* Initialize the driver module (but not any device) and register + * the module with the kernel PCI subsystem. */ +static int __init fpgapci_init(void) +{ + + if (pci_register_driver(&fpgapci_driver)) { + PRINT("pci_unregister_driver\n"); + pci_unregister_driver(&fpgapci_driver); + return -ENODEV; + } + + return 0; +} + +static void __exit fpgapci_exit(void) +{ + PRINT ("fpgapci_exit"); + + /* unregister this driver from the PCI bus driver */ + pci_unregister_driver(&fpgapci_driver); + +} + + +module_init (fpgapci_init); +module_exit (fpgapci_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("joyce_yu@dell.com"); +MODULE_DESCRIPTION ("Driver for FPGA Logic I2C bus"); +MODULE_SUPPORTED_DEVICE ("FPGA Logic I2C bus"); diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/check_qsfp.sh b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/check_qsfp.sh new file mode 100755 index 000000000000..2028b8e65946 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/check_qsfp.sh @@ -0,0 +1,3 @@ +# Temporary dummy file for s5248f. +# Will be updated soon. + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py new file mode 100755 index 000000000000..047618e057c8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py @@ -0,0 +1,102 @@ +#!/usr/bin/python +# Copyright (c) 2015 Dell Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. + +import struct +import sys +import getopt +from os import * +from mmap import * + +def usage(): + ''' This is the Usage Method ''' + + print '\t\t pcisysfs.py --get --offset --res ' + print '\t\t pcisysfs.py --set --val --offset --res ' + sys.exit(1) + +def pci_mem_read(mm,offset): + mm.seek(offset) + read_data_stream=mm.read(4) + print "" + reg_val=struct.unpack('I',read_data_stream) + print "reg_val read:%x"%reg_val + return reg_val + +def pci_mem_write(mm,offset,data): + mm.seek(offset) + print "data to write:%x"%data + mm.write(struct.pack('I',data)) + +def pci_set_value(resource,val,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_write(mm,offset,val) + +def pci_get_value(resource,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_read(mm,offset) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resource = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgsv:" , \ + ["val=","res=","offset=","help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt,arg in opts: + + if opt in ('-h','--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--res': + resource = arg + + elif opt == '--val': + val = int(arg,16) + + elif opt == '--offset': + offset = int(arg,16) + + if choice == 'set' and val != '' and offset !='' and resource !='': + pci_set_value(resource,val,offset) + + elif choice == 'get' and offset != '' and resource !='': + pci_get_value(resource,offset) + + else: + usage() + +#Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py new file mode 100755 index 000000000000..6f7ba9b55b09 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py @@ -0,0 +1,277 @@ +#!/usr/bin/python +# On S5248F, the BaseBoard Management Controller is an +# autonomous subsystem provides monitoring and management +# facility independent of the host CPU. IPMI standard +# protocol is used with ipmitool to fetch sensor details. +# Current script support X00 board only. X01 support will +# be added soon. This provies support for the +# following objects: +# * Onboard temperature sensors +# * FAN trays +# * PSU + + +import os +import sys +import logging +import subprocess +import commands + +S5248F_MAX_FAN_TRAYS = 4 +S5248F_MAX_PSUS = 2 +IPMI_SENSOR_DATA = "ipmitool sdr list" +IPMI_SENSOR_DUMP = "/tmp/sdr" + +FAN_PRESENCE = "FAN{0}_prsnt" +PSU_PRESENCE = "PSU{0}_stat" +# Use this for older firmware +# PSU_PRESENCE="PSU{0}_prsnt" + +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" +ipmi_sdr_list = "" + +# Dump sensor registers + + +def ipmi_sensor_dump(): + + status = 1 + global ipmi_sdr_list + ipmi_cmd = IPMI_SENSOR_DATA + status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + + if status: + logging.error('Failed to execute:' + ipmi_sdr_list) + sys.exit(0) + +# Fetch a BMC register + + +def get_pmc_register(reg_name): + + output = None + for item in ipmi_sdr_list.split("\n"): + if reg_name in item: + output = item.strip() + + if output is None: + print('\nFailed to fetch: ' + reg_name + ' sensor ') + sys.exit(0) + + output = output.split('|')[1] + + logging.basicConfig(level=logging.DEBUG) + return output + + +# Print the information for temperature sensors + + +def print_temperature_sensors(): + + print("\nOnboard Temperature Sensors:") + + print ' PT_Left_temp: ',\ + (get_pmc_register('PT_Left_temp')) + print ' PT_Mid_temp: ',\ + (get_pmc_register('PT_Mid_temp')) + print ' PT_Right_temp: ',\ + (get_pmc_register('PT_Right_temp')) + print ' Broadcom Temp: ',\ + (get_pmc_register('NPU_Near_temp')) + print ' Inlet Airflow Temp: ',\ + (get_pmc_register('ILET_AF_temp')) + print ' CPU Temp: ',\ + (get_pmc_register('CPU_temp')) + +ipmi_sensor_dump() + +print_temperature_sensors() + +# Print the information for 1 Fan Tray + + +def print_fan_tray(tray): + + Fan_Status = [' Normal', ' Abnormal'] + Airflow_Direction = ['B2F', 'F2B'] + + print ' Fan Tray ' + str(tray) + ':' + + if (tray == 1): + + fan1_status = int(get_pmc_register('FAN1_Front_stat'), 16) + fan2_status = int(get_pmc_register('FAN1_Rear_stat'), 16) + + print ' Fan1 Speed: ',\ + get_pmc_register('FAN1_Front_rpm') + print ' Fan2 Speed: ',\ + get_pmc_register('FAN1_Rear_rpm') + print ' Fan1 State: ',\ + Fan_Status[fan1_status] + print ' Fan2 State: ',\ + Fan_Status[fan2_status] + + elif (tray == 2): + + fan1_status = int(get_pmc_register('FAN2_Front_stat'), 16) + fan2_status = int(get_pmc_register('FAN2_Rear_stat'), 16) + + print ' Fan1 Speed: ',\ + get_pmc_register('FAN2_Front_rpm') + print ' Fan2 Speed: ',\ + get_pmc_register('FAN2_Rear_rpm') + print ' Fan1 State: ',\ + Fan_Status[fan1_status] + print ' Fan2 State: ',\ + Fan_Status[fan2_status] + + elif (tray == 3): + + fan1_status = int(get_pmc_register('FAN3_Front_stat'), 16) + fan2_status = int(get_pmc_register('FAN3_Rear_stat'), 16) + + print ' Fan1 Speed: ',\ + get_pmc_register('FAN3_Front_rpm') + print ' Fan2 Speed: ',\ + get_pmc_register('FAN3_Rear_rpm') + print ' Fan1 State: ',\ + Fan_Status[fan1_status] + print ' Fan2 State: ',\ + Fan_Status[fan2_status] + + elif (tray == 4): + + fan1_status = int(get_pmc_register('FAN4_Front_stat'), 16) + fan2_status = int(get_pmc_register('FAN4_Rear_stat'), 16) + + print ' Fan1 Speed: ',\ + get_pmc_register('FAN4_Front_rpm') + print ' Fan2 Speed: ',\ + get_pmc_register('FAN4_Rear_rpm') + print ' Fan1 State: ',\ + Fan_Status[fan1_status] + print ' Fan2 State: ',\ + Fan_Status[fan2_status] + + +print('\nFan Trays:') + +for tray in range(1, S5248F_MAX_FAN_TRAYS + 1): + fan_presence = FAN_PRESENCE.format(tray) + if (get_pmc_register(fan_presence)): + print_fan_tray(tray) + else: + print '\n Fan Tray ' + str(tray + 1) + ': Not present' + + def get_psu_presence(index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + ret_status = 1 + + if index == 1: + status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + + #if ret_status: + # print ipmi_cmd_ret + # logging.error('Failed to execute ipmitool') + # sys.exit(0) + + psu_status = ipmi_cmd_ret + + if psu_status == '1': + status = 1 + + return status + + +# Print the information for PSU1, PSU2 +def print_psu(psu): + Psu_Type = ['Normal', 'Mismatch'] + Psu_Input_Type = ['AC', 'DC'] + PSU_STATUS_TYPE_BIT = 4 + PSU_STATUS_INPUT_TYPE_BIT = 1 + PSU_FAN_PRESENT_BIT = 2 + PSU_FAN_STATUS_BIT = 1 + PSU_FAN_AIR_FLOW_BIT = 0 + Psu_Fan_Presence = ['Present', 'Absent'] + Psu_Fan_Status = ['Normal', 'Abnormal'] + Psu_Fan_Airflow = ['B2F', 'F2B'] + + # print ' Input: ', Psu_Input_Type[psu_input_type] + # print ' Type: ', Psu_Type[psu_type] + + # PSU FAN details + if (psu == 1): + + # psu1_fan_status = int(get_pmc_register('PSU1_status'),16) + + print ' PSU1:' + print ' FAN Normal Temperature: ',\ + get_pmc_register('PSU1_temp') + print ' FAN AirFlow Temperature: ',\ + get_pmc_register('PSU1_AF_temp') + print ' FAN RPM: ',\ + get_pmc_register('PSU1_rpm') + # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] + + # PSU input & output monitors + print ' Input Voltage: ',\ + get_pmc_register('PSU1_In_volt') + print ' Output Voltage: ',\ + get_pmc_register('PSU1_Out_volt') + print ' Input Power: ',\ + get_pmc_register('PSU1_In_watt') + print ' Output Power: ',\ + get_pmc_register('PSU1_Out_watt') + print ' Input Current: ',\ + get_pmc_register('PSU1_In_amp') + print ' Output Current: ',\ + get_pmc_register('PSU1_Out_amp') + + else: + + # psu2_fan_status = int(get_pmc_register('PSU1_status'),16) + print ' PSU2:' + print ' FAN Normal Temperature: ',\ + get_pmc_register('PSU2_temp') + print ' FAN AirFlow Temperature: ',\ + get_pmc_register('PSU2_AF_temp') + print ' FAN RPM: ',\ + get_pmc_register('PSU2_rpm') + # print ' FAN Status: ', Psu_Fan_Status[psu2_fan_status] + + # PSU input & output monitors + print ' Input Voltage: ',\ + get_pmc_register('PSU2_In_volt') + print ' Output Voltage: ',\ + get_pmc_register('PSU2_Out_volt') + print ' Input Power: ',\ + get_pmc_register('PSU2_In_watt') + print ' Output Power: ',\ + get_pmc_register('PSU2_Out_watt') + print ' Input Current: ',\ + get_pmc_register('PSU2_In_amp') + print ' Output Current: ',\ + get_pmc_register('PSU2_Out_amp') + + +print('\nPSUs:') +for psu in range(1, S5248F_MAX_PSUS + 1): + #psu_presence = PSU_PRESENCE.format(psu) + if (get_psu_presence(psu)): + print_psu(psu) + else: + print '\n PSU ', psu, 'Not present' + +print '\n Total Power: ',\ + get_pmc_register('PSU_Total_watt') + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/qsfp_irq_enable.py b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/qsfp_irq_enable.py new file mode 100755 index 000000000000..5050475f987e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/qsfp_irq_enable.py @@ -0,0 +1,32 @@ +#!/usr/bin/python + +try: + import struct + import sys + from os import * + from mmap import * + +except ImportError as e: + raise ImportError("%s - required module no found" % str(e)) + +BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" +PORT_START = 0 +PORT_END = 32 + + +def pci_mem_write(mm, offset, data): + mm.seek(offset) + mm.write(struct.pack('I', data)) + + +def pci_set_value(resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + +for port_num in range(PORT_START, PORT_END+1): + port_offset = 0x400c + ((port_num) * 16) + pci_set_value(BASE_RES_PATH, 0x30, port_offset) diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh new file mode 100755 index 000000000000..e74a3d6c40de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh @@ -0,0 +1,161 @@ +#!/bin/bash + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # iSMT adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus iSMT adapter at '* ]]; then + found=1 + break + fi + done + + [ $found -eq 0 ] && echo "cannot find iSMT" && exit 1 +} + +# Attach/Detach syseeprom on CPU board +sys_eeprom() { + case $1 in + "new_device") echo 24c16 0x50 > /sys/bus/i2c/devices/i2c-0/$1 + ;; + "delete_device") echo 0x50 > /sys/bus/i2c/devices/i2c-0/$1 + ;; + *) echo "s5248f_platform: sys_eeprom : invalid command !" + ;; + esac +} + +#Attach/Detach the MUX connecting all QSFPs +switch_board_qsfp_mux() { + case $1 in + "new_device") + for ((i=603;i<=610;i++)); + do + echo "Attaching PCA9548 @ 0x74" + echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + + ;; + "delete_device") + for ((i=603;i<=610;i++)); + do + echo "Detaching PCA9548 @ 0x74" + echo 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + + ;; + *) echo "s5248f_platform: switch_board_qsfp_mux: invalid command !" + ;; + esac + sleep 2 +} + +#Attach/Detach 64 instances of EEPROM driver QSFP ports +#eeprom can dump data using below command +switch_board_qsfp() { + case $1 in + "new_device") + for ((i=2;i<=57;i++)); + do + echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=2;i<=57;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "s5248f_platform: switch_board_qsfp: invalid command !" + ;; + esac +} + +#Modsel 64 ports to applicable QSFP type modules +#This enables the adapter to respond for i2c commands +switch_board_modsel() { + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + for ((i=1;i<=64;i++)); + do + port_addr=$(( 16384 + ((i - 1) * 16))) + hex=$( printf "0x%x" $port_addr ) + python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + done +} + +platform_firmware_versions() { + FIRMWARE_VERSION_FILE=/var/log/firmware_versions + rm -rf ${FIRMWARE_VERSION_FILE} + echo "BIOS: `dmidecode -s system-version `" > $FIRMWARE_VERSION_FILE + ## Get FPGA version + r=`/usr/bin/pcisysfs.py --get --offset 0x00 --res /sys/bus/pci/devices/0000\:04\:00.0/resource0 | sed '1d; s/.*\(....\)$/\1/; s/\(..\{1\}\)/\1./'` + r_min=$(echo $r | sed 's/.*\(..\)$/0x\1/') + r_maj=$(echo $r | sed 's/^\(..\).*/0x\1/') + echo "FPGA: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + ## Get BMC Firmware Revision + r=`cat /sys/class/ipmi/ipmi0/device/bmc/firmware_revision` + echo "BMC: $r" >> $FIRMWARE_VERSION_FILE + + #System CPLD 0x31 on i2c bus 601 ( physical FPGA I2C-2) + r_min=`/usr/sbin/i2cget -y 601 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 601 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "System CPLD: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 1 0x30 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x30 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x30 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 1: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 2 0x31 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 2: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x32 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x32 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 3: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x33 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x33 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE +} + +#This enables the led control for CPU and default states +switch_board_led_default() { + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + python /usr/bin/pcisysfs.py --set --offset 0x24 --val 0x194 --res $resource > /dev/null 2>&1 +} +init_devnum + +if [ "$1" == "init" ]; then + modprobe i2c-dev + modprobe i2c-mux-pca954x force_deselect_on_exit=1 + modprobe ipmi_devintf + modprobe ipmi_si + modprobe i2c_ocores + modprobe dell_s5248f_fpga_ocores + sys_eeprom "new_device" + switch_board_qsfp_mux "new_device" + switch_board_qsfp "new_device" + switch_board_modsel + switch_board_led_default + #python /usr/bin/qsfp_irq_enable.py + platform_firmware_versions + +elif [ "$1" == "deinit" ]; then + sys_eeprom "delete_device" + switch_board_qsfp "delete_device" + switch_board_qsfp_mux "delete_device" + + modprobe -r i2c-mux-pca954x + modprobe -r i2c-dev +else + echo "s5248f_platform : Invalid option !" +fi + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/sensors b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/sensors new file mode 100755 index 000000000000..ee53f2b0f325 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/sensors @@ -0,0 +1,8 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" +docker exec -i pmon /usr/bin/platform_sensors.py "$@" + +#To probe sensors not part of lm-sensors +#if [ -r /usr/local/bin/platform_sensors.py ]; then +# python /usr/local/bin/platform_sensors.py +#fi diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/systemd/platform-modules-s5248f.service b/platform/broadcom/sonic-platform-modules-dell/s5248f/systemd/platform-modules-s5248f.service new file mode 100644 index 000000000000..ec3ea09f00ae --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/systemd/platform-modules-s5248f.service @@ -0,0 +1,13 @@ +[Unit] +Description=Dell S5248f Platform modules +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/s5248f_platform.sh init +ExecStop=/usr/local/bin/s5248f_platform.sh deinit +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index bba14e99db3e..370a920d2187 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -202,3 +202,10 @@ tm_port_header_type_out trunk_group_max_members ucode_port led_fw_path +l2xlrn_thread_interval +l2xlrn_intr_en +serdes_lane_config_media_type +sai_preinit_cmd_file +sai_preinit_warmboot_cmd_file +sai_postinit_cmd_file +sai_postinit_warmboot_cmd_file From be52977aca8e8c318c972cbe92d5de8bcfaf2c32 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Fri, 18 Oct 2019 09:14:39 -0700 Subject: [PATCH 0084/1427] Revert "Configure buffer profile to all ports (#3561)" (#3628) This reverts commit 8861cbe98edbe513aac5d1ee2c5943bf6179c905. --- files/build_templates/buffers_config.j2 | 8 +- .../tests/sample_output/buffers-dell6100.json | 240 ------------------ 2 files changed, 4 insertions(+), 244 deletions(-) diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index bf74b2dcf52c..a5212d979fcb 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -131,7 +131,7 @@ def {{ defs.generate_pg_profils(port_names_active) }} {% else %} "BUFFER_PG": { -{% for port in PORT_ALL %} +{% for port in PORT_ACTIVE %} "{{ port }}|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }{% if not loop.last %},{% endif %} @@ -144,17 +144,17 @@ def {{ defs.generate_queue_buffers(port_names_active) }} {% else %} "BUFFER_QUEUE": { -{% for port in PORT_ALL %} +{% for port in PORT_ACTIVE %} "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, {% endfor %} -{% for port in PORT_ALL %} +{% for port in PORT_ACTIVE %} "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, {% endfor %} -{% for port in PORT_ALL %} +{% for port in PORT_ACTIVE %} "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }{% if not loop.last %},{% endif %} diff --git a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json index 38e2b8313eb4..5cf0472f3f11 100644 --- a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json +++ b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json @@ -111,12 +111,6 @@ "Ethernet1|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet2|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet3|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, "Ethernet4|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, @@ -159,12 +153,6 @@ "Ethernet17|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet18|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet19|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, "Ethernet20|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, @@ -204,15 +192,6 @@ "Ethernet32|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet33|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet34|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet35|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, "Ethernet36|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, @@ -234,33 +213,9 @@ "Ethernet42|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet43|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet44|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet45|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet46|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet47|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, "Ethernet48|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet49|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet50|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet51|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, "Ethernet52|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, @@ -281,21 +236,6 @@ }, "Ethernet58|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet59|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet60|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet61|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet62|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet63|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, @@ -306,12 +246,6 @@ "Ethernet1|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet2|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet3|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, "Ethernet4|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, @@ -354,12 +288,6 @@ "Ethernet17|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet18|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet19|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, "Ethernet20|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, @@ -399,15 +327,6 @@ "Ethernet32|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet33|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet34|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet35|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, "Ethernet36|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, @@ -429,33 +348,9 @@ "Ethernet42|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet43|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet44|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet45|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet46|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet47|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, "Ethernet48|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet49|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet50|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet51|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, "Ethernet52|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, @@ -477,33 +372,12 @@ "Ethernet58|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet59|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet60|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet61|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet62|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet63|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, "Ethernet0|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet1|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet2|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet3|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, "Ethernet4|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -546,12 +420,6 @@ "Ethernet17|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet18|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet19|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, "Ethernet20|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -591,15 +459,6 @@ "Ethernet32|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet33|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet34|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet35|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, "Ethernet36|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -621,33 +480,9 @@ "Ethernet42|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet43|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet44|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet45|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet46|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet47|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, "Ethernet48|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet49|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet50|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet51|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, "Ethernet52|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -669,33 +504,12 @@ "Ethernet58|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet59|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet60|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet61|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet62|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet63|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, "Ethernet0|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet1|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet2|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet3|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, "Ethernet4|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -738,12 +552,6 @@ "Ethernet17|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet18|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet19|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, "Ethernet20|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -783,15 +591,6 @@ "Ethernet32|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet33|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet34|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet35|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, "Ethernet36|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -813,33 +612,9 @@ "Ethernet42|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet43|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet44|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet45|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet46|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet47|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, "Ethernet48|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet49|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet50|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet51|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, "Ethernet52|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, @@ -860,21 +635,6 @@ }, "Ethernet58|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet59|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet60|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet61|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet62|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet63|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } } From 37ba921449166a5bb27d2067d1af1b9f563ead6e Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Sat, 19 Oct 2019 12:11:58 +0300 Subject: [PATCH 0085/1427] [mellanox] Update SN3800 device configs. (#3633) Signed-off-by: Nazarii Hnydyn --- device/mellanox/x86_64-mlnx_msn3800-r0/pmon_daemon_control.json | 1 + 1 file changed, 1 insertion(+) create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/pmon_daemon_control.json diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn3800-r0/pmon_daemon_control.json new file mode 120000 index 000000000000..435a2ce7c0ba --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pmon_daemon_control.json \ No newline at end of file From 9d7199ac936a001867ac9aeea698e4348d3b2c20 Mon Sep 17 00:00:00 2001 From: Wei Bai Date: Sat, 19 Oct 2019 11:00:37 -0700 Subject: [PATCH 0086/1427] [dox]: Add SONiC management docker image (#3636) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 315652e81af3..08375dce678b 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,7 @@ This may take a while, but it is a one-time action, so please be patient. - docker-syncd-nephos.gz: docker image for the daemon to sync database and Nephos switch ASIC (gzip tar archive) - docker-sonic-p4.gz: docker image for all-in-one for p4 software switch (gzip tar archive) - docker-sonic-vs.gz: docker image for all-in-one for software virtual switch (gzip tar archive) + - docker-sonic-mgmt.gz: docker image for [managing, configuring and monitoring SONiC](https://github.com/Azure/sonic-mgmt) (gzip tar archive) ## Contribution Guide From 3b63f6f9d7b618eb890f71dc9cdbe4fdb53802fa Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 19 Oct 2019 20:43:03 -0700 Subject: [PATCH 0087/1427] [kvm]: add eeprom.py for kvm image (#3637) --- .../x86_64-kvm_x86_64-r0/plugins/eeprom.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/plugins/eeprom.py diff --git a/device/virtual/x86_64-kvm_x86_64-r0/plugins/eeprom.py b/device/virtual/x86_64-kvm_x86_64-r0/plugins/eeprom.py new file mode 100644 index 000000000000..5cc8cb68018f --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/plugins/eeprom.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +############################################################################# +# SONiC Virtual switch platform +# +############################################################################# + +class board(): + + def __init__(self, name, path, cpld_root, ro): + return + + def check_status(self): + return "ok" + + def is_checksum_valid(self, e): + return (True, 0) + + def read_eeprom(self): + return \ +""" +TLV Name Code Len Value +-------------------- ---- --- ----- +Product Name 0x21 5 SONiC +Part Number 0x22 6 000000 +Serial Number 0x23 20 0000000000000000000 +Base MAC Address 0x24 6 00:00:00:00:00:01 +Manufacture Date 0x25 19 10/19/2019 00:00:03 +Device Version 0x26 1 1 +Label Revision 0x27 3 A01 +Platform Name 0x28 20 x86_64-kvm_x86_64-r0 +ONIE Version 0x29 19 master-201811170418 +MAC Addresses 0x2A 2 16 +Vendor Name 0x2D 5 SONiC +""" + + def decode_eeprom(self, e): + print e + + def serial_number_str(self, e): + """Return service tag instead of serial number""" + return "000000" From 07235d01d90d4bf54126c60ad5f478567dadface Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Sat, 19 Oct 2019 20:44:17 -0700 Subject: [PATCH 0088/1427] [Submodule] Update sonic-swss-common and sonic-swss (#3626) Sonic-swss-common: aaa8133 - 2019-10-12 : Add VRF object table in state_db (#312) [Tyler Li] 91aceb1 - 2019-10-11 : [schema] Update schema to support debug counters (#308) [Danny Allen] 9bcd5ca - 2019-09-28 : [multi-DB] fix vs test, should NOT replace old DBConnector API with new DBConnector API since vs test docker has no database_config.josn (#311) [Dong Zhang] 599155a - 2019-09-25 : [multi-DB] Part 2: C++ interface API changes / swsscommon unit test / LOGLEVEL_DB apply new API (#301) [Dong Zhang] 379ac73 - 2019-09-20 : add bulkremove for consumer_table_pops.lua (#306) [Dong Zhang] 6b805d3 - 2019-09-19 : timerfd return 0 with errno =0 - handle as False alarm. (#302) [Renuka Manavalan] e455891 - 2019-09-03 : Add VLAN_SUB_INTERFACE in CONFIG_DB schema (#284) [Wenda Ni] Sonic-swss 731a8f5 - 2019-10-17 : [copporch]: fix the endless loop problem when removing copp table group. (#1038) [wangshengjun] 1623219 - 2019-10-14 : Enable C++ unit test during build (#1092) [Qi Luo] 629c9d3 - 2019-10-14 : [vstest]: Revert back to 2 sec, and check if we got more than expected number of syslogs (#1091) [Prince Sunny] 80b2ace - 2019-10-11 : sonic-swss/orchagent: Add new protocol trap name support (#1087) [jpxjlrldgit] 9f765f7 - 2019-10-11 : [aclorch]: Check for existing mirror table only when creating a new table (#1089) [Danny Allen] 4c10260 - 2019-10-11 : [vstest]: Update Route test to check for added entry (#1088) [Prince Sunny] e658b64 - 2019-10-11 : [chassisorch]: Add everflow feature for chassis (#1024) [Ze Gan] 5b13387 - 2019-10-10 : [changelog]: Revert changelog that was done for passing VS test. (#1080) [Prince Sunny] 90a690d - 2019-10-10 : [aclorch]: Simplify the TCP flags matching code and support exact value match (#1072) [Shuotian Cheng] 3461710 - 2019-10-09 : Single VRF for ingress and egress flows, skip route replication (#1045) [Prince Sunny] 953474a - 2019-10-03 : [swss]: Do not use namespace in header files (#1081) [Wenda Ni] bd36751 - 2019-10-03 : Change nexthop key to ip & ifname (#977) [tylerlinp] fee1aaa - 2019-10-02 : [teamsyncd]: Check if LAG exists before removing (#1069) [Shuotian Cheng] 175f3de - 2019-09-30 : Update ECMP NHopGroup for Port Channel oper down (#1030) [Sumukha Tumkur Vani] 182940d - 2019-09-26 : [mirrororch]: Remove mirror session state after it is remvoed (#1066) [Shuotian Cheng] d823dd1 - 2019-09-20 : [MirrorOrch]: Mirror Session Retention across Warm Reboot (#1054) [Shuotian Cheng] a5b6e7c - 2019-09-19 : Ignore link local neighbors (#1065) [Prince Sunny] 0ddaba3 - 2019-09-19 : Adopt to signature change of Selectable::readData, which switched (#1061) [Renuka Manavalan] 543bd98 - 2019-09-18 : [aclorch]: Fix table name in counter table for mirror rules (#1060) [Shuotian Cheng] 12c29b4 - 2019-09-19 : Cannot ping to link-local ipv6 interface address of the switch. (#774) [Kiran Kumar Kella] 4d8e08d - 2019-09-18 : change in fpmsyncd to skip the lookup for the Master device name if the route object table value is zero (#1048) [Arvindsrinivasan Lakshmi narasimhan] da514f5 - 2019-09-18 : Do not update lag mtu from teamsyncd (netlink) (#1053) [Prince Sunny] 3fb22e1 - 2019-09-16 : Check warmboot flag during initialization (#1057) [Prince Sunny] d98d1e9 - 2019-09-16 : [aclorch]: Egress mirror action support and action ASIC support check (#963) [Stepan Blyshchak] 313ef5c - 2019-09-09 : Warmboot Vlan neigh restore fix (#1040) [Prince Sunny] 5841e06 - 2019-09-06 : Add dot1p to tc mapping support (#871) [Wenda Ni] 39fe568 - 2019-08-30 : [aclorch]: Revise ACL rule creation/removal logs (#1042) [Shuotian Cheng] c461911 - 2019-08-27 : [copporch]: Fix the typo - mld_v1_done (#1037) [wangshengjun] 34915de - 2019-08-22 : [portsyncd]: Add default catch block in portsyncd (#1033) [SuvarnaMeenakshi] dc81a21 - 2019-08-20 : [vnet]: Fix FDB related failure in "vnet_bitmap" virtual switch test (#1034) [Volodymyr Samotiy] 5ae4226 - 2019-08-19 : [test]: Adjust stale timer for warm-reboot neighborsync test cases (#1031) [zhenggen-xu] 65cbd55 - 2019-08-16 : [build]: Fix compiling warnings using ARM 32 bit compiler (#1015) [arheneus@marvell.com] b611808 - 2019-08-16 : [Orchagent]: Fixbug segmentfault at routeorch (#1025) [Ze Gan] --- src/sonic-swss | 2 +- src/sonic-swss-common | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-swss b/src/sonic-swss index 252e12cf3a59..731a8f57119d 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 252e12cf3a592a287a102a3b74ad2152b36781f6 +Subproject commit 731a8f57119d79e6d7ba6196f026a9e24664e074 diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 036a5d36ad30..aaa8133e8be9 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 036a5d36ad307303fdd9315bb06f2240842e5999 +Subproject commit aaa8133e8be9eb2a2f924c9eec997a502b795544 From 6cb445cb9e6fbcc7382d57b507183849e3ce7c2c Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Sun, 20 Oct 2019 09:16:32 +0530 Subject: [PATCH 0089/1427] [Juniper][QFX5210]Adding the system reboot handler (#3599) The following changes are done as part of this commit: - Adding the system reboot handler - Adding swizzle reset case for the reboot reason - Workaround for the boot problem from Golden bios - Adding the logging messages for platform scripts - EEPROM parsing and library routines --- .../sonic-platform-juniper-qfx5210.postinst | 20 +++ .../modules/x86-64-juniper-qfx5210-64x-psu.c | 84 +++++++-- .../service/qfx5210-platform-init.service | 2 + .../qfx5210/sonic_platform/chassis.py | 138 +++++++++++++- .../qfx5210/utils/juniper_qfx5210_monitor.py | 54 +++++- .../qfx5210/utils/juniper_qfx5210_util.py | 170 ++++++++++++++++-- 6 files changed, 429 insertions(+), 39 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst index 1b00ceb568e6..dcff39f53799 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst @@ -1,2 +1,22 @@ systemctl enable qfx5210-platform-init.service systemctl start qfx5210-platform-init.service + +# There are primary and secondary bios in qfx5210 platform. +# There is a problem with bios which prevents the OS booting from the +# secondary bios when the OS was installed using primary bios. +# Secondary bios fails to detect the UEFI partition. Right now +# the workaround is to have a folder structure /EFI/BOOT/BOOT64x.efi + +SONIC_VERSION=$(sonic-cfggen -y /etc/sonic/sonic_version.yml -v build_version) +FIRST_BOOT_FILE="/host/image-${SONIC_VERSION}/platform/firsttime" + +if [ -f $FIRST_BOOT_FILE ]; then + mkdir /tmp/sda1 + mount /dev/sda1 /tmp/sda1 + cd /tmp/sda1/EFI + mkdir BOOT > /dev/null 2>&1 + cp SONiC-OS/grubx64.efi BOOT/BOOTX64.EFI + cd /tmp + umount sda1 + efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /dev/null 2>&1 +fi diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c index d42e61b3c51b..cb283d2d4a1c 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #define PSU_STATUS_I2C_ADDR 0x60 #define PSU_STATUS_I2C_REG_OFFSET 0x03 @@ -46,6 +48,10 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); static struct qfx5210_64x_psu_data *qfx5210_64x_psu_update_device(struct device *dev); extern int juniper_i2c_cpld_read (u8 cpld_addr, u8 reg); +/* + * This function is defined in juniper_i2c_cpld.c + */ +extern int juniper_i2c_cpld_write(unsigned short, u8, u8); /* Addresses scanned */ @@ -78,6 +84,36 @@ static struct attribute *qfx5210_64x_psu_attributes[] = { NULL }; +static int qfx5210_cpld_soft_reset(struct notifier_block *nb, + unsigned long action, + void *data) +{ + int ret = 0; + + switch (action) { + case SYS_POWER_OFF: + case SYS_HALT: + printk(KERN_CRIT "System halt/power_off\n"); + break; + case SYS_RESTART: + printk(KERN_CRIT "System restart: qfx5210_cpld_soft_reset\n"); + ret = juniper_i2c_cpld_write(0x65, 0x04, 0x01); + if (ret) { + printk(KERN_CRIT "qfx5210_cpld_soft_reset failed\n"); + } + msleep(100); + break; + default: + /* Do Nothing */ + break; + } + return NOTIFY_DONE; +} + +static struct notifier_block qfx5210_nb = { + .notifier_call = qfx5210_cpld_soft_reset, +}; + static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf) { @@ -103,11 +139,6 @@ static const struct attribute_group qfx5210_64x_psu_group = { .attrs = qfx5210_64x_psu_attributes, }; -/* - * This function is defined in juniper_i2c_cpld.c - */ -extern int juniper_i2c_cpld_write(unsigned short, u8, u8); - /* * QFX5210 power off sequence */ @@ -126,7 +157,6 @@ static void qfx5210_cpld_power_off(void) */ static void (*default_pm_power_off)(void); - static int qfx5210_64x_psu_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) { @@ -165,12 +195,7 @@ static int qfx5210_64x_psu_probe(struct i2c_client *client, dev_info(&client->dev, "%s: psu '%s'\n", dev_name(data->hwmon_dev), client->name); - /* - * Store the default poweroff handler for later usage - */ - default_pm_power_off = pm_power_off; - pm_power_off = qfx5210_cpld_power_off; - + return 0; exit_remove: @@ -189,19 +214,14 @@ static int qfx5210_64x_psu_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &qfx5210_64x_psu_group); kfree(data); - - /* - * Restore the poweroff handler - */ - pm_power_off = default_pm_power_off; - + return 0; } enum psu_index { qfx5210_64x_psu1, - qfx5210_64x_psu2 + qfx5210_64x_psu2 }; static const struct i2c_device_id qfx5210_64x_psu_id[] = { @@ -259,11 +279,37 @@ static struct qfx5210_64x_psu_data *qfx5210_64x_psu_update_device(struct device static int __init qfx5210_64x_psu_init(void) { + /* + * Store the default poweroff handler for later usage + */ + default_pm_power_off = pm_power_off; + /* + * Register the cpld poweroff handler + */ + pm_power_off = qfx5210_cpld_power_off; + /* + * Register the cpld soft reset handler + */ + if(register_reboot_notifier(&qfx5210_nb)) { + printk(KERN_ALERT "Restart handler registration failed\n"); + } + return i2c_add_driver(&qfx5210_64x_psu_driver); } static void __exit qfx5210_64x_psu_exit(void) { + /* + * Restore the poweroff handler + */ + pm_power_off = default_pm_power_off; + /* + * Unregister the cpld soft reset handler + */ + if (!unregister_restart_handler(&qfx5210_nb)) { + printk(KERN_CRIT "Failed to uregister restart handler\n"); + } + i2c_del_driver(&qfx5210_64x_psu_driver); } diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/service/qfx5210-platform-init.service b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/service/qfx5210-platform-init.service index b6a446ec1752..46377aa9fdc8 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/service/qfx5210-platform-init.service +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/service/qfx5210-platform-init.service @@ -8,6 +8,8 @@ DefaultDependencies=no ExecStartPre=/usr/local/bin/juniper_qfx5210_util.py install ExecStart=/usr/local/bin/juniper_qfx5210_monitor.py RemainAfterExit=yes +StandardOutput=syslog+console +StandardError=syslog+console [Install] WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py index 5d56ef3a0cde..674d9184df3c 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py @@ -60,7 +60,7 @@ def __init__(self): def get_qfx5210_parameter_value(self,parameter_name): try: - with open("/var/run/qfx5210_eeprom", "r") as file: + with open("/var/run/eeprom", "r") as file: for item in file: content = item.split('=') if content[0] == parameter_name: @@ -71,29 +71,32 @@ def get_qfx5210_parameter_value(self,parameter_name): return "False" def get_product_name(self): - product_name_list = self.get_qfx5210_parameter_value('ProductName') + product_name_list = self.get_qfx5210_parameter_value('Product Name') if product_name_list: product_name = ''.join(product_name_list) return product_name else: return False + def get_part_number(self): - part_number_list = self.get_qfx5210_parameter_value('PartNumber') + part_number_list = self.get_qfx5210_parameter_value('Part Number') if part_number_list: part_number = ''.join(part_number_list) return part_number else: return False + def get_serial_number(self): - serial_number_list = self.get_qfx5210_parameter_value('SerialNumber') + serial_number_list = self.get_qfx5210_parameter_value('Serial Number') if serial_number_list: serial_number = ''.join(serial_number_list) return serial_number else: return False + def get_base_mac(self): mac_list = self.get_qfx5210_parameter_value('MAC') if mac_list: @@ -102,13 +105,134 @@ def get_base_mac(self): else: return False + + def get_mfg_date(self): + mfgdate_list = self.get_qfx5210_parameter_value('Manufacture Date') + if mfgdate_list: + mfgdate = ''.join(mfgdate_list) + return mfgdate + else: + return False + + def get_deviceversion_name(self): + device_version_list = self.get_qfx5210_parameter_value('Device Version') + if device_version_list: + deviceversion_name = ''.join(device_version_list) + return deviceversion_name + else: + return False + def get_platform_name(self): - platform_name_list = self.get_qfx5210_parameter_value('PlatformName') + platform_name_list = self.get_qfx5210_parameter_value('Platform Name') if platform_name_list: platform_name = ''.join(platform_name_list) return platform_name else: return False + + def get_MACnumber_name(self): + MACnumber_name_list = self.get_qfx5210_parameter_value('Number of MAC Addresses') + if MACnumber_name_list: + MACnumber_name = ''.join(MACnumber_name_list) + return MACnumber_name + else: + return False + + def get_vendor_name(self): + vendor_name_list = self.get_qfx5210_parameter_value('Vendor Name') + if vendor_name_list: + vendor_name = ''.join(vendor_name_list) + return vendor_name + else: + return False + + def get_mfg_name(self): + mfg_name_list = self.get_qfx5210_parameter_value('Manufacture Name') + if mfg_name_list: + mfg_name = ''.join(mfg_name_list) + return mfg_name + else: + return False + + def get_vendorext_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Vendor Extension') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextIANA_name(self): + vendorext_list = self.get_qfx5210_parameter_value('IANA') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMREV_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Assembly Part Number Rev') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMPartNum_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Assembly Part Number') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMID_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Assembly ID') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMMajNum_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Assembly Major Revision') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMMinNum_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Assembly Minor Revision') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextCLEI_name(self): + vendorext_list = self.get_qfx5210_parameter_value('CLEI code') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_onieversion_name(self): + onieversion_name_list = self.get_qfx5210_parameter_value('ONIE Version') + if onieversion_name_list: + onieversion_name = ''.join(onieversion_name_list) + return onieversion_name + else: + return False + + def get_crc_name(self): + crc_list = self.get_qfx5210_parameter_value('CRC') + if crc_list: + crc_name = ''.join(crc_list) + return crc_name + else: + return False def get_fan_type(self, fantype_path): try: @@ -134,6 +258,8 @@ def get_reboot_cause(self): return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) elif last_reboot_reason == "0x20": return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") else: return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") else: @@ -145,5 +271,7 @@ def get_reboot_cause(self): return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) elif last_reboot_reason == "0x20": return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") else: return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py index a74bce042ac3..d225400121b8 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py @@ -53,10 +53,16 @@ # Deafults VERSION = '1.0' -FUNCTION_NAME = '/usr/local/bin/juniper_qfx5210_monitor' +FUNCTION_NAME = '/var/log/juniper_qfx5210_monitor' + + +global log_file +global log_level global isPlatformAFI +global isFireThresholdReached +FireThresholdSecsRemaining = 120 temp_policy_AFI = { 0: [[70, 0, 48000], [70, 48000, 53000], [80, 53000, 0], [80, 53000, 58000], [100, 58000, 0], ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 75000], ['Fire Shut Alarm', 75000, 0]], @@ -268,6 +274,8 @@ def set_alarm_led_brightness(self, val): def getSensorTemp(self): sum = 0 global isPlatformAFI + global isFireThresholdReached + global FireThresholdSecsRemaining #AFI if (isPlatformAFI == True): temp_policy = temp_policy_AFI @@ -287,6 +295,17 @@ def getSensorTemp(self): 5: [0,0,0,0,0,0,0,0], 6: [0,0,0,0,0,0,0,0], } + # if the Firethreshold Flag is set and 120 seconds have elapsed, invoking the "poweroff" to shutdown the box + if (isFireThresholdReached == True): + firethr = FireThresholdSecsRemaining - 20 + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds', firethr) + print "Fire Threshold reached: System is going to shutdown in %s seconds\n" % firethr + FireThresholdSecsRemaining = FireThresholdSecsRemaining - 20 + if (FireThresholdSecsRemaining == 20): + isFireThresholdReached == False + time.sleep(20) + cmd = "poweroff" + returned_value = os.system(cmd) for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): if x < self.SENSOR_NUM_ON_MAIN_BOARD: @@ -332,6 +351,9 @@ def getSensorTemp(self): fan = QFX5210_FanUtil() # CHECK IF ANY TEMPERATURE SENSORS HAS SET FIRE SHUTDOWN FLAG if SensorFlag[0][7] or SensorFlag[1][7] or SensorFlag[2][7] or SensorFlag[3][7] or SensorFlag[4][7] or SensorFlag[5][7] or SensorFlag[6][7]: + isFireThresholdReached = True + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds') + print "CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds\n" value = self.get_alarm_led_brightness() if ( value > 0): self.set_alarm_led_brightness(0) @@ -399,12 +421,32 @@ def getSensorTemp(self): class device_monitor(object): - def __init__(self): + def __init__(self, log_file, log_level): + global isPlatformAFI + global isFireThresholdReached MASTER_LED_PATH = '/sys/class/leds/master/brightness' SYSTEM_LED_PATH = '/sys/class/leds/system/brightness' FANTYPE_PATH = '/sys/bus/i2c/devices/17-0068/fan1_direction' + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + import sonic_platform platform = sonic_platform.platform.Platform() chassis = platform.get_chassis() @@ -418,7 +460,8 @@ def __init__(self): isPlatformAFI = False else: isPlatformAFI = True - + + isFireThresholdReached = False master_led_value = 1 try: @@ -444,7 +487,10 @@ def manage_device(self): thermal.getSensorTemp() def main(): - monitor = device_monitor() + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.DEBUG + + monitor = device_monitor(log_file, log_level) while True: monitor.manage_device() time.sleep(20) diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py index ccb32a3a894a..b3f130af41c0 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py @@ -56,7 +56,7 @@ ALL_DEVICE = {} DEVICE_NO = {'led':4, 'fan':4,'thermal':6, 'psu':2, 'sfp':64} FORCE = 0 - +FUNCTION_NAME = '/var/log/juniper_qfx5210_util' if DEBUG == True: print sys.argv[0] @@ -67,6 +67,9 @@ def main(): global DEBUG global args global FORCE + + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.DEBUG if len(sys.argv)<2: show_help() @@ -75,11 +78,25 @@ def main(): 'debug', 'force', ]) + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S') + if DEBUG == True: print options print args print len(sys.argv) - + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + for opt, arg in options: if opt in ('-h', '--help'): show_help() @@ -114,7 +131,7 @@ def main(): else: show_help() - DisableWatchDogCmd = '/usr/sbin/i2cset -y 0 0x65 0x3 0x04' + DisableWatchDogCmd = '/usr/sbin/i2cset -f -y 0 0x65 0x3 0x04' # Disable watchdog try: os.system(DisableWatchDogCmd) @@ -131,6 +148,135 @@ def main(): print 'Error: Execution of "%s" failed', CPUeepromFileCmd return False + eeprom_ascii = '/etc/init.d/eeprom_qfx5210_ascii' + # Read file contents in Hex format + with open(eeprom_ascii, 'rb') as Hexformat: + content = Hexformat.read() + Hexformatoutput = binascii.hexlify(content) + + eeprom_hex = '/etc/init.d/eeprom_qfx5210_hex' + #Write contents of CPU EEPROM to new file in hexa format + with open(eeprom_hex, 'wb+') as Hexfile: + Hexfile.write(Hexformatoutput) + + # Read from EEPROM Hex file and extract the different fields like Product name, + # Part Number, Serial Number MAC Address, Mfg Date ... etc and store in /var/run/eeprom file + with open(eeprom_hex, 'rb') as eeprom_hexfile: + # moving the file pointer to required position where product name is stored in EEPROM file and reading the required bytes from this position + + product_position = eeprom_hexfile.seek(26, 0) + product_read = eeprom_hexfile.read(36) + product_name = binascii.unhexlify(product_read) + + # creating the "/var/run/eeprom" file and storing all the values of different fields in this file. + eeprom_file = open ("/var/run/eeprom", "a+") + eeprom_file.write("Product Name=%s\r\n" % str(product_name)) + + # like wise we are moving the file pointer to respective position where other fields are stored and extract these fields and store in /var/run/eeprom file + partnumber_position = eeprom_hexfile.seek(66, 0) + partnumber_read = eeprom_hexfile.read(20) + partnumber_name = binascii.unhexlify(partnumber_read) + eeprom_file.write("Part Number=%s\r\n" % str(partnumber_name)) + + serialnumber_position = eeprom_hexfile.seek(90, 0) + serialnumber_read = eeprom_hexfile.read(24) + serialnumber_name = binascii.unhexlify(serialnumber_read) + eeprom_file.write("Serial Number=%s\r\n" % str(serialnumber_name)) + + macaddress_position = eeprom_hexfile.seek(118, 0) + macaddress_read = eeprom_hexfile.read(12) + macaddress_name="" + for i in range(0,12,2): + macaddress_name += macaddress_read[i:i+2] + ":" + macaddress_name=macaddress_name[:-1] + eeprom_file.write("MAC Address=%s\r\n" % str(macaddress_name)) + + mfgdate_position = eeprom_hexfile.seek(132, 0) + mfgdate_read = eeprom_hexfile.read(40) + mfgdate_name = binascii.unhexlify(mfgdate_read) + eeprom_file.write("Manufacture Date=%s\r\n" % str(mfgdate_name)) + + devversion_position = eeprom_hexfile.seek(176, 0) + devversion_read = eeprom_hexfile.read(2) + eeprom_file.write("Device Version=%s\r\n" % str(devversion_read)) + + platform_position = eeprom_hexfile.seek(182, 0) + platform_read = eeprom_hexfile.read(68) + platform_name = binascii.unhexlify(platform_read) + eeprom_file.write("Platform Name=%s\r\n" % str(platform_name)) + + MACnumber_position = eeprom_hexfile.seek(254, 0) + MACnumber_read = eeprom_hexfile.read(4) + MACnumber = int(MACnumber_read, 16) + eeprom_file.write("Number of MAC Addresses=%s\r\n" % str(MACnumber)) + + vendorName_position = eeprom_hexfile.seek(262, 0) + vendorName_read = eeprom_hexfile.read(40) + vendorName = binascii.unhexlify(vendorName_read) + eeprom_file.write("Vendor Name=%s\r\n" % str(vendorName)) + + mfgname_position = eeprom_hexfile.seek(306, 0) + mfgname_read = eeprom_hexfile.read(40) + mfgname = binascii.unhexlify(mfgname_read) + eeprom_file.write("Manufacture Name=%s\r\n" % str(mfgname)) + + vendorext_position = eeprom_hexfile.seek(350, 0) + vendorext_read = eeprom_hexfile.read(124) + vendorext="" + vendorext += "0x" + vendorext_read[0:2] + for i in range(2,124,2): + vendorext += " 0x" + vendorext_read[i:i+2] + eeprom_file.write("Vendor Extension=%s\r\n" % str(vendorext)) + + IANA_position = eeprom_hexfile.seek(350, 0) + IANA_read = eeprom_hexfile.read(8) + IANAName = binascii.unhexlify(IANA_read) + eeprom_file.write("IANA=%s\r\n" % str(IANAName)) + + ASMpartrev_position = eeprom_hexfile.seek(358, 0) + ASMpartrev_read = eeprom_hexfile.read(4) + ASMpartrev = binascii.unhexlify(ASMpartrev_read) + eeprom_file.write("Assembly Part Number Rev=%s\r\n" % str(ASMpartrev)) + + ASMpartnum_position = eeprom_hexfile.seek(374, 0) + ASMpartnum_read = eeprom_hexfile.read(20) + ASMpartnum_read = binascii.unhexlify(ASMpartnum_read) + eeprom_file.write("Assembly Part Number=%s\r\n" % str(ASMpartnum_read)) + + ASMID_position = eeprom_hexfile.seek(402, 0) + ASMID_read = eeprom_hexfile.read(4) + ASMID_read_upper = ASMID_read.upper() + eeprom_file.write("Assembly ID=0x%s\r\n" % str(ASMID_read_upper)) + + ASMHWMajRev_position = eeprom_hexfile.seek(410, 0) + ASMHWMajRev_read = eeprom_hexfile.read(2) + eeprom_file.write("Assembly Major Revision=0x%s\r\n" % str(ASMHWMajRev_read)) + + ASMHWMinRev_position = eeprom_hexfile.seek(416, 0) + ASMHWMinRev_read = eeprom_hexfile.read(2) + eeprom_file.write("Assembly Minor Revision=0x%s\r\n" % str(ASMHWMinRev_read)) + + Deviation_position = eeprom_hexfile.seek(422, 0) + Deviation_read = eeprom_hexfile.read(28) + Deviation_read_upper = Deviation_read.upper() + eeprom_file.write("Deviation=0x%s\r\n" % str(Deviation_read_upper)) + + CLEI_position = eeprom_hexfile.seek(450, 0) + CLEI_read = eeprom_hexfile.read(20) + CLEI_name = binascii.unhexlify(CLEI_read) + eeprom_file.write("CLEI code=%s\r\n" % str(CLEI_name)) + + ONIEversion_position = eeprom_hexfile.seek(478, 0) + ONIEversion_read = eeprom_hexfile.read(22) + ONIEversion = binascii.unhexlify(ONIEversion_read) + eeprom_file.write("ONIE Version=%s\r\n" % str(ONIEversion)) + + CRC_position = eeprom_hexfile.seek(504, 0) + CRC = eeprom_hexfile.read(8) + eeprom_file.write("CRC=%s\r\n" % str(CRC)) + + eeprom_file.close() + return True def show_help(): @@ -152,7 +298,7 @@ def show_eeprom_help(): def my_log(txt): if DEBUG == True: - print "[ROY]"+txt + print txt return def log_os_system(cmd, show): @@ -253,7 +399,9 @@ def driver_uninstall(): 'echo cpld_qfx5210 0x60 > /sys/bus/i2c/devices/i2c-19/new_device', 'echo cpld_plain 0x62 > /sys/bus/i2c/devices/i2c-20/new_device', 'echo cpld_plain 0x64 > /sys/bus/i2c/devices/i2c-21/new_device', -'echo cpld_plain 0x66 > /sys/bus/i2c/devices/i2c-22/new_device'] +'echo cpld_plain 0x66 > /sys/bus/i2c/devices/i2c-22/new_device', +'echo cpld_plain 0x65 > /sys/bus/i2c/devices/i2c-0/new_device 2>/dev/null' +] def i2c_order_check(): return 0 @@ -322,9 +470,9 @@ def system_ready(): return True def do_install(): - print "Checking system...." + logging.info('Checking system....') if driver_check() == False: - print "No driver, installing...." + logging.info('No driver, installing....') status = driver_install() if status: if FORCE == 0: @@ -332,7 +480,7 @@ def do_install(): else: print PROJECT_NAME.upper()+" drivers detected...." if not device_exist(): - print "No device, installing...." + logging.info('No device, installing....') status = device_install() if status: if FORCE == 0: @@ -342,11 +490,11 @@ def do_install(): return def do_uninstall(): - print "Checking system...." + logging.info('Checking system....') if not device_exist(): print PROJECT_NAME.upper() +" has no device installed...." else: - print "Removing device...." + logging.info('Removing device....') status = device_uninstall() if status: if FORCE == 0: @@ -355,7 +503,7 @@ def do_uninstall(): if driver_check()== False : print PROJECT_NAME.upper() +" has no driver installed...." else: - print "Removing installed driver...." + logging.info('Removing installed driver....') status = driver_uninstall() if status: if FORCE == 0: From 206df4327f07faeff97fd432d5c8e3228ca48a31 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Tue, 22 Oct 2019 09:37:45 -0700 Subject: [PATCH 0090/1427] Adopt per-port buffer & qos profile apply on mellanox (#3543) Signed-off-by: Wenda Ni --- .../ACS-MSN2700/buffers_defaults_t0.j2 | 29 ++++++++++++++----- .../ACS-MSN2700/buffers_defaults_t1.j2 | 29 ++++++++++++++----- .../ACS-MSN3700/buffers_defaults_t0.j2 | 29 ++++++++++++++----- .../ACS-MSN3700/buffers_defaults_t1.j2 | 29 ++++++++++++++----- 4 files changed, 84 insertions(+), 32 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 index 018c2f96bc1b..8c3cac4b80b8 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 @@ -65,28 +65,41 @@ {%- macro generate_profile_lists(port_names) %} "BUFFER_PORT_INGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, "BUFFER_PORT_EGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { - "{{ port_names }}|3-4": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names }}|0-1": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" }, - "{{ port_names }}|5": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 index c315ccf59547..45433b1b2641 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 @@ -65,28 +65,41 @@ {%- macro generate_profile_lists(port_names) %} "BUFFER_PORT_INGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, "BUFFER_PORT_EGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { - "{{ port_names }}|3-4": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names }}|0-1": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" }, - "{{ port_names }}|5": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 index 89b269456458..d40bc03fbb59 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 @@ -65,27 +65,40 @@ {%- macro generate_profile_lists(port_names) %} "BUFFER_PORT_INGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, "BUFFER_PORT_EGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { - "{{ port_names }}|3-4": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names }}|0-1": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" }, - "{{ port_names }}|5": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 index d9db9c2d255e..fe8c27b9d364 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 @@ -65,27 +65,40 @@ {%- macro generate_profile_lists(port_names) %} "BUFFER_PORT_INGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, "BUFFER_PORT_EGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { - "{{ port_names }}|3-4": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names }}|0-1": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" }, - "{{ port_names }}|5": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} From a0fbeeaca5e8e1d8d0f1a3e2e33001cf52863783 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Tue, 22 Oct 2019 14:41:12 -0700 Subject: [PATCH 0091/1427] [Services] Restart SNMP service upon unexpected critical process exit. (#3650) Signed-off-by: Yong Zhao --- dockers/docker-snmp-sv2/Dockerfile.j2 | 2 ++ dockers/docker-snmp-sv2/critical_processes | 2 ++ dockers/docker-snmp-sv2/supervisord.conf | 8 +++++++- files/build_templates/snmp.service.j2 | 4 ++++ rules/docker-snmp-sv2.mk | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 dockers/docker-snmp-sv2/critical_processes diff --git a/dockers/docker-snmp-sv2/Dockerfile.j2 b/dockers/docker-snmp-sv2/Dockerfile.j2 index 9905e7eee2de..b62ff61eaf95 100644 --- a/dockers/docker-snmp-sv2/Dockerfile.j2 +++ b/dockers/docker-snmp-sv2/Dockerfile.j2 @@ -84,6 +84,8 @@ RUN apt-get -y purge \ COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["*.j2", "/usr/share/sonic/templates/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] # Although exposing ports is not needed for host net mode, keep it for possible bridge mode EXPOSE 161/udp 162/udp diff --git a/dockers/docker-snmp-sv2/critical_processes b/dockers/docker-snmp-sv2/critical_processes new file mode 100644 index 000000000000..e6039c5b9840 --- /dev/null +++ b/dockers/docker-snmp-sv2/critical_processes @@ -0,0 +1,2 @@ +snmpd +snmp-subagent diff --git a/dockers/docker-snmp-sv2/supervisord.conf b/dockers/docker-snmp-sv2/supervisord.conf index d80579506100..7fd16eec5bbe 100644 --- a/dockers/docker-snmp-sv2/supervisord.conf +++ b/dockers/docker-snmp-sv2/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index 43f46bd2b9c0..a05c5fbe1d09 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -4,11 +4,15 @@ Requires=updategraph.service Requisite=swss.service After=updategraph.service swss.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target swss.service diff --git a/rules/docker-snmp-sv2.mk b/rules/docker-snmp-sv2.mk index 2a533b436191..bd34f271b861 100644 --- a/rules/docker-snmp-sv2.mk +++ b/rules/docker-snmp-sv2.mk @@ -30,3 +30,4 @@ $(DOCKER_SNMP_SV2)_RUN_OPT += --net=host --privileged -t $(DOCKER_SNMP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # mount Arista platform python libraries to support corresponding platforms SNMP power status query $(DOCKER_SNMP_SV2)_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro +$(DOCKER_SNMP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From 9fb18604251551aa60310122060a7ac029bc5fb0 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Tue, 22 Oct 2019 19:02:08 -0700 Subject: [PATCH 0092/1427] [file permission] explicitly set file permission on passwd, group, shadow (#3652) Signed-off-by: Ying Xie --- build_debian.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build_debian.sh b/build_debian.sh index c1a13d1ae7d3..d1e5273b1c71 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -282,6 +282,13 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in mcelog fi +## Set /etc/shadow permissions to -rw-------. +sudo LANG=c chroot $FILESYSTEM_ROOT chmod 600 /etc/shadow + +## Set /etc/passwd, /etc/group permissions to -rw-r--r--. +sudo LANG=c chroot $FILESYSTEM_ROOT chmod 644 /etc/passwd +sudo LANG=c chroot $FILESYSTEM_ROOT chmod 644 /etc/group + #Adds a locale to a debian system in non-interactive mode sudo sed -i '/^#.* en_US.* /s/^#//' $FILESYSTEM_ROOT/etc/locale.gen && \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT locale-gen "en_US.UTF-8" From 8d162ae70a6df3feb61b63e4d421eb4e22494ef7 Mon Sep 17 00:00:00 2001 From: Michel Moriniaux Date: Wed, 23 Oct 2019 09:36:10 -0700 Subject: [PATCH 0093/1427] [doc]: Added branch 201904 to the build status icons (#3642) Somehow this was missed in april, I added the icons for 201904 so that the branch is not forgotten Signed-off-by: Michel Moriniaux --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 08375dce678b..129af89f05d4 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,15 @@ Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/j P4: [![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all) VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all) +*201904*: +Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201904/) +Barefoot: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201904/) +Centec: [![Centec](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201904/) +Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201904/) +Marvell: [![Marvell](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201904/) +Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201904/) +VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201904) + *201811*: Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/) Barefoot: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201811/) From 63328814fc786d04eddabb544edad60235867977 Mon Sep 17 00:00:00 2001 From: Danny Allen <52468448+daall@users.noreply.github.com> Date: Wed, 23 Oct 2019 15:55:47 -0700 Subject: [PATCH 0094/1427] [core_cleanup] Fix issue where core_cleanup job runs too frequently (#3659) Signed-off-by: Danny Allen --- files/image_config/cron.d/core_cleanup | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/cron.d/core_cleanup b/files/image_config/cron.d/core_cleanup index b1c379da9ebb..8db064ea57d6 100644 --- a/files/image_config/cron.d/core_cleanup +++ b/files/image_config/cron.d/core_cleanup @@ -1,3 +1,3 @@ # Attempts to clean up core files every 2 hours -* */2 * * * root /usr/bin/core_cleanup.py > /dev/null 2>&1 +0 */2 * * * root /usr/bin/core_cleanup.py > /dev/null 2>&1 From 74a28bf062321bf23c9d42286acb9aa32c8e31ac Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Wed, 23 Oct 2019 21:39:48 -0700 Subject: [PATCH 0095/1427] [Submodule] Update sonic-utilities (#3660) c12c443 - 2019-10-22 : [command reference] add warm reboot command document (#704) [Ying Xie] e25cf29 - 2019-10-22 : [PR template] Add reminder to add/modify/remove unit tests as appropriate (#708) [Joe LeVeque] 66eafce - 2019-10-19 : [Command Reference] Unify style and formatting; Fix organization; Other fixes (#707) [Joe LeVeque] f32a450 - 2019-10-19 : [generate_dump] Make regex more specific for disabling/enabling logrotate (#701) [Kalimuthu-Velappan] d77c411 - 2019-10-18 : [netstat]: Fix for negative output values of counters after clear counters operation (#697) [lyndonsiao] fc324f2 - 2019-10-18 : [neighbor_advertiser]: Adapt to different mirror ACL table names (#703) [Shuotian Cheng] 342f3a1 - 2019-10-08 : [intfstat,portstat] fix table_as_json (#691) [Mykola F] 5564d87 - 2019-10-07 : [acl-loader] egress mirror action support and action ASIC support check (#575) [Stepan Blyshchak] --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 02375e195394..c12c4434fa24 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 02375e195394cd84fb2e7639f953a72b894ed000 +Subproject commit c12c4434fa2440914a705b9b15d142012eac4ce0 From e883d35ce1eb00aa1ee1dd99b28ef29e7fb23abe Mon Sep 17 00:00:00 2001 From: InventecJamesHuang <45092023+InventecJamesHuang@users.noreply.github.com> Date: Thu, 24 Oct 2019 12:40:43 +0800 Subject: [PATCH 0096/1427] [devices]: Adding pre-emphasis for Inventec d6356 platform (#3643) Added pre-emphasis values for the Inventec d6356 platform using media_settings.json. --- .../media_settings.json | 707 ++++++++++++++++++ 1 file changed, 707 insertions(+) create mode 100644 device/inventec/x86_64-inventec_d6356-r0/media_settings.json diff --git a/device/inventec/x86_64-inventec_d6356-r0/media_settings.json b/device/inventec/x86_64-inventec_d6356-r0/media_settings.json new file mode 100644 index 000000000000..f688fcb48a08 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/media_settings.json @@ -0,0 +1,707 @@ +{ + "PORT_MEDIA_SETTINGS": { + "0": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x0B3D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0F4B0A" + } + } + }, + "1": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x0A3C01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x104A0A" + } + } + }, + "2": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x0B3D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0E4C0A" + } + } + }, + "3": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083200" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0E4C0A" + } + } + }, + "4": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x0A3D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4D0A" + } + } + }, + "5": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083400" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4D0A" + } + } + }, + "6": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x0A3801" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4D0A" + } + } + }, + "7": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083400" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4D0A" + } + } + }, + "8": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x093801" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0C4E0A" + } + } + }, + "9": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083400" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4D0A" + } + } + }, + "10": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083601" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0B4F0A" + } + } + }, + "11": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083400" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0C4E0A" + } + } + }, + "12": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083401" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0A500A" + } + } + }, + "13": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x073200" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0A500A" + } + } + }, + "14": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083401" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "15": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063101" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "16": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063401" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x08520A" + } + } + }, + "17": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063201" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x08520A" + } + } + }, + "18": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063001" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "19": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052E00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "20": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063001" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "21": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052E00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "22": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052E01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "23": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x062D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "24": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063000" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "25": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x062D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "26": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "27": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "28": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x04560A" + } + } + }, + "29": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "30": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "31": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x062E01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "32": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "33": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x062E01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "34": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "35": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "36": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052E00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "37": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x08520A" + } + } + }, + "38": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x082E00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x08520A" + } + } + }, + "39": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x062D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "40": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x072C01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "41": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "42": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063001" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "43": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x08520A" + } + } + }, + "44": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083401" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "45": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "46": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x093901" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "47": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x072D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0A500A" + } + } + }, + "48": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x083101", + "lane1":"0x083201", + "lane2":"0x083001", + "lane3":"0x093001" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A", + "lane1":"0x05550A", + "lane2":"0x07530A", + "lane3":"0x05550A" + } + } + }, + "49": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x082E01", + "lane1":"0x083301", + "lane2":"0x083101", + "lane3":"0x093102" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "50": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x082F01", + "lane1":"0x083001", + "lane2":"0x083201", + "lane3":"0x093202" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "51": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x083001", + "lane1":"0x0A3101", + "lane2":"0x083301", + "lane3":"0x093302" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x085309", + "lane1":"0x0B4F0A", + "lane2":"0x085309", + "lane3":"0x0B4F0A" + } + } + }, + "52": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x093101", + "lane1":"0x0A3201", + "lane2":"0x0A3402", + "lane3":"0x093402" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0B4F0A" + } + } + }, + "53": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x093201", + "lane1":"0x0A3301", + "lane2":"0x093401", + "lane3":"0x093502" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0B4F0A" + } + } + }, + "54": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x093101", + "lane1":"0x0A3401", + "lane2":"0x0A3501", + "lane3":"0x093602" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0B4F0A" + } + } + }, + "55": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x093201", + "lane1":"0x0A3501", + "lane2":"0x0A3601", + "lane3":"0x093701" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4E09" + } + } + } + } +} + From 8457248d01e21662821bf3e8268a6335032052b7 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 24 Oct 2019 07:35:14 -0700 Subject: [PATCH 0097/1427] [bgpcfgd]: Split default bgp config into main config and peer template (#3627) Now it's possible to add and remove peers based on ConfigDB - What I did Fixed functionality for dynamically adding/removing static bgp peers. - How I did it Split the bgp default template on bgp part and bgp peer part Changed bgpcfgd to use 1. - How to verify it Build an image and run on your DUT --- dockers/docker-fpm-frr/bgpcfgd | 252 +++++++++++++----- dockers/docker-fpm-frr/bgpd.conf.default.j2 | 79 ++---- dockers/docker-fpm-frr/bgpd.conf.j2 | 21 +- ...bgpd.conf.spine_chassis_frontend_router.j2 | 67 +---- dockers/docker-fpm-frr/bgpd.peer.conf.j2 | 30 +++ dockers/docker-fpm-frr/daemons.common.conf.j2 | 12 + dockers/docker-fpm-frr/frr.conf.j2 | 202 +------------- dockers/docker-fpm-frr/start.sh | 4 +- dockers/docker-fpm-frr/staticd.conf.j2 | 21 +- .../staticd.default_route.conf.j2 | 10 + dockers/docker-fpm-frr/zebra.conf.j2 | 71 +---- .../docker-fpm-frr/zebra.interfaces.conf.j2 | 60 +++++ src/sonic-config-engine/sonic-cfggen | 9 + .../tests/sample_output/bgpd_frr.conf | 101 ++----- .../tests/sample_output/frr.conf | 125 ++++----- .../tests/sample_output/staticd_frr.conf | 9 +- .../sample_output/t2-chassis-fe-bgpd.conf | 67 ++--- .../t2-chassis-fe-vni-zebra.conf | 11 +- .../sample_output/t2-chassis-fe-zebra.conf | 11 +- .../tests/sample_output/zebra_frr.conf | 11 +- src/sonic-config-engine/tests/test_frr.py | 62 +++++ src/sonic-config-engine/tests/test_j2files.py | 28 -- .../tests/test_j2files_t2_chassis_fe.py | 49 ++-- 23 files changed, 572 insertions(+), 740 deletions(-) create mode 100644 dockers/docker-fpm-frr/bgpd.peer.conf.j2 create mode 100644 dockers/docker-fpm-frr/daemons.common.conf.j2 create mode 100644 dockers/docker-fpm-frr/staticd.default_route.conf.j2 create mode 100644 dockers/docker-fpm-frr/zebra.interfaces.conf.j2 create mode 100644 src/sonic-config-engine/tests/test_frr.py diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index f6d0b86385b5..4ba8977fddfa 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -1,124 +1,250 @@ #!/usr/bin/env python import sys -import copy -import Queue -import redis import subprocess +import datetime +import time import syslog +import signal +import traceback import os +import shutil +import tempfile +import json +from collections import defaultdict +from pprint import pprint + +import jinja2 +import netaddr from swsscommon import swsscommon -def run_command(command): - syslog.syslog(syslog.LOG_DEBUG, "execute command {}.".format(command)) - p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) - stdout = p.communicate()[0] - p.wait() +g_run = True +g_debug = False + + +def run_command(command, shell=False): + str_cmd = " ".join(command) + if g_debug: + syslog.syslog(syslog.LOG_DEBUG, "execute command {}.".format(str_cmd)) + p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() if p.returncode != 0: - syslog.syslog(syslog.LOG_ERR, 'command execution returned {}. Command: "{}", stdout: "{}"'.format(p.returncode, command, stdout)) + syslog.syslog(syslog.LOG_ERR, 'command execution returned {}. Command: "{}", stdout: "{}", stderr: "{}"'.format(p.returncode, str_cmd, stdout, stderr)) + + return p.returncode, stdout, stderr + +class TemplateFabric(object): + def __init__(self): + j2_template_paths = ['/usr/share/sonic/templates'] + j2_loader = jinja2.FileSystemLoader(j2_template_paths) + j2_env = jinja2.Environment(loader=j2_loader, trim_blocks=True) + j2_env.filters['ipv4'] = self.is_ipv4 + j2_env.filters['ipv6'] = self.is_ipv6 + self.env = j2_env + + def from_file(self, filename): + return self.env.get_template(filename) + + def from_string(self, tmpl): + return self.env.from_string(tmpl) + + @staticmethod + def is_ipv4(value): + if not value: + return False + if isinstance(value, netaddr.IPNetwork): + addr = value + else: + try: + addr = netaddr.IPNetwork(str(value)) + except: + return False + return addr.version == 4 + + @staticmethod + def is_ipv6(value): + if not value: + return False + if isinstance(value, netaddr.IPNetwork): + addr = value + else: + try: + addr = netaddr.IPNetwork(str(value)) + except: + return False + return addr.version == 6 class BGPConfigManager(object): def __init__(self, daemon): - self.daemon = daemon self.bgp_asn = None - self.bgp_message = Queue.Queue(0) + self.meta = None + self.bgp_messages = [] + self.peers = self.load_peers() # we can have bgp monitors peers here. it could be fixed by adding support for it here + fabric = TemplateFabric() + self.bgp_peer_add_template = fabric.from_file('bgpd.peer.conf.j2') + self.bgp_peer_del_template = fabric.from_string('no neighbor {{ neighbor_addr }}') + self.bgp_peer_shutdown = fabric.from_string('neighbor {{ neighbor_addr }} shutdown') + self.bgp_peer_no_shutdown = fabric.from_string('no neighbor {{ neighbor_addr }} shutdown') daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, self.__metadata_handler) daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, self.__bgp_handler) + def load_peers(self): + peers = set() + command = ["vtysh", "-c", "show bgp neighbors json"] + rc, out, err = run_command(command) + if rc == 0: + js_bgp = json.loads(out) + peers = set(js_bgp.keys()) + return peers + def __metadata_handler(self, key, op, data): if key != "localhost" \ or "bgp_asn" not in data \ or self.bgp_asn == data["bgp_asn"]: return - # TODO add ASN update commands + # TODO add ASN update commands + self.meta = { 'localhost': data } self.bgp_asn = data["bgp_asn"] self.__update_bgp() def __update_bgp(self): - while not self.bgp_message.empty(): - key, op, data = self.bgp_message.get() - syslog.syslog(syslog.LOG_INFO, 'value for {} changed to {}'.format(key, data)) + cmds = [] + for key, op, data in self.bgp_messages: if op == swsscommon.SET_COMMAND: - command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} remote-as {}'".format(self.bgp_asn, key, data['asn']) - run_command(command) - if "name" in data: - command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} description {}'".format(self.bgp_asn, key, data['name']) - run_command(command) - if "admin_status" in data: - command_mod = "no " if data["admin_status"] == "up" else "" - command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c '{}neighbor {} shutdown'".format(self.bgp_asn, command_mod, key) - run_command(command) + if key not in self.peers: + cmds.append(self.bgp_peer_add_template.render(DEVICE_METADATA=self.meta, neighbor_addr=key, bgp_session=data)) + syslog.syslog(syslog.LOG_INFO, 'Peer {} added with attributes {}'.format(key, data)) + self.peers.add(key) + else: + # when the peer is already configured we support "shutdown/no shutdown" + # commands for the peers only + if "admin_status" in data: + if data['admin_status'] == 'up': + cmds.append(self.bgp_peer_no_shutdown.render(neighbor_addr=key)) + syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "up"'.format(key)) + elif data['admin_status'] == 'down': + cmds.append(self.bgp_peer_shutdown.render(neighbor_addr=key)) + syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "down"'.format(key)) + else: + syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. has wrong attribute value attr['admin_status'] = '{}'".format(key, data['admin_status'])) + else: + syslog.syslog(syslog.LOG_INFO, "Peer {}: Can't update the peer. No 'admin_status' attribute in the request".format(key)) elif op == swsscommon.DEL_COMMAND: - # Neighbor is deleted - command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'no neighbor {}'".format(self.bgp_asn, key) - run_command(command) + if key in self.peers: + cmds.append(self.bgp_peer_del_template.render(neighbor_addr=key)) + syslog.syslog(syslog.LOG_INFO, 'Peer {} has been removed'.format(key)) + self.peers.remove(key) + else: + syslog.syslog(syslog.LOG_WARNING, 'Peer {} is not found'.format(key)) + self.bgp_messages = [] + + if len(cmds) == 0: + return + + fd, tmp_filename = tempfile.mkstemp(dir='/tmp') + os.close(fd) + with open (tmp_filename, 'w') as fp: + fp.write('router bgp %s\n' % self.bgp_asn) + for cmd in cmds: + fp.write("%s\n" % cmd) + + command = ["vtysh", "-f", tmp_filename] + run_command(command) #FIXME + os.remove(tmp_filename) def __bgp_handler(self, key, op, data): - self.bgp_message.put((key, op, data)) + self.bgp_messages.append((key, op, data)) # If ASN is not set, we just cache this message until the ASN is set. - if self.bgp_asn == None: - return - self.__update_bgp() + if self.bgp_asn is not None: + self.__update_bgp() class Daemon(object): - SELECT_TIMEOUT = 1000 - SUPPORT_DATABASE_LIST = (swsscommon.APPL_DB, swsscommon.CONFIG_DB) + DATABASE_LIST = [ swsscommon.CONFIG_DB ] def __init__(self): - self.appl_db = swsscommon.DBConnector(swsscommon.APPL_DB, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) - self.conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) + self.db_connectors = { db : swsscommon.DBConnector(db, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) for db in Daemon.DATABASE_LIST } self.selector = swsscommon.Select() - self.db_connectors = {} - self.callbacks = {} + self.callbacks = defaultdict(lambda : defaultdict(list)) # db -> table -> [] self.subscribers = set() - def get_db_connector(self, db): - if db not in Daemon.SUPPORT_DATABASE_LIST: - raise ValueError("database {} not Daemon support list {}.".format(db, SUPPORT_DATABASE_LIST)) - # if this database connector has been initialized - if db not in self.db_connectors: - self.db_connectors[db] = swsscommon.DBConnector(db, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) - return self.db_connectors[db] - def add_manager(self, db, table_name, callback): - if db not in self.callbacks: - self.callbacks[db] = {} + if db not in Daemon.DATABASE_LIST: + raise ValueError("database {} isn't supported. Supported '{}' only.".format(db, ",".join(Daemon.DATABASE_LIST))) + if table_name not in self.callbacks[db]: - self.callbacks[db][table_name] = [] - conn = self.get_db_connector(db) + conn = self.db_connectors[db] subscriber = swsscommon.SubscriberStateTable(conn, table_name) self.subscribers.add(subscriber) self.selector.addSelectable(subscriber) self.callbacks[db][table_name].append(callback) - def start(self): - while True: - state, selectable = self.selector.select(Daemon.SELECT_TIMEOUT) - if not selectable: + def run(self): + while g_run: + state, _ = self.selector.select(Daemon.SELECT_TIMEOUT) + if state == self.selector.TIMEOUT: continue + elif state == self.selector.ERROR: + raise Exception("Received error from select") + for subscriber in self.subscribers: key, op, fvs = subscriber.pop() - # if no new message if not key: continue - data = dict(fvs) - syslog.syslog(syslog.LOG_DEBUG, "Receive message : {}".format((key, op, fvs))) + if g_debug: + syslog.syslog(syslog.LOG_DEBUG, "Received message : {}".format((key, op, fvs))) for callback in self.callbacks[subscriber.getDbConnector().getDbId()][subscriber.getTableName()]: - callback(key, op, data) + callback(key, op, dict(fvs)) + + +def wait_for_bgpd(): + # wait for 20 seconds + stop_time = datetime.datetime.now() + datetime.timedelta(seconds=20) + syslog.syslog(syslog.LOG_INFO, "Start waiting for bgpd: %s" % str(datetime.datetime.now())) + while datetime.datetime.now() < stop_time: + rc, out, err = run_command(["vtysh", "-c", "show daemons"]) + if rc == 0 and "bgpd" in out: + syslog.syslog(syslog.LOG_INFO, "bgpd connected to vtysh: %s" % str(datetime.datetime.now())) + return + time.sleep(0.1) # sleep 100 ms + raise RuntimeError("bgpd hasn't been started in 20 seconds") def main(): - syslog.openlog("bgpcfgd") + wait_for_bgpd() daemon = Daemon() bgp_manager = BGPConfigManager(daemon) - daemon.start() - syslog.closelog() - -if __name__ == "__main__": - main() + daemon.run() + + +def signal_handler(signum, frame): + global g_run + g_run = False + + +if __name__ == '__main__': + rc = 0 + try: + syslog.openlog('bgpcfgd') + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) + main() + except KeyboardInterrupt: + syslog.syslog(syslog.LOG_NOTICE, "Keyboard interrupt") + except RuntimeError as e: + syslog.syslog(syslog.LOG_CRIT, "%s" % str(e)) + rc = -2 + except Exception as e: + syslog.syslog(syslog.LOG_CRIT, "Got an exception %s: Traceback: %s" % (str(e), traceback.format_exc())) + rc = -1 + finally: + syslog.closelog() + try: + sys.exit(rc) + except SystemExit: + os._exit(rc) diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index 72779ac53d52..957c2792435f 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -1,3 +1,4 @@ +! {% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} {% block bgp_init %} ! @@ -12,7 +13,7 @@ route-map TO_BGP_SPEAKER_V4 deny 10 {% if prefix | ipv4 and name == 'Loopback0' %} ip prefix-list PL_LoopbackV4 permit {{ prefix | ip }}/32 {% elif prefix | ipv6 and name == 'Loopback0' %} -ipv6 prefix-list PL_LoopbackV6 permit {{ prefix | ip }}/64 +ipv6 prefix-list PL_LoopbackV6 permit {{ prefix | replace('/128', '/64') | ip_network }}/64 {% endif %} {% endfor %} ! @@ -28,6 +29,13 @@ route-map FROM_BGPMON_V4 deny 10 route-map TO_BGPMON_V4 permit 10 ! {% endif %} +! +route-map ISOLATE permit 10 + set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }} +! +route-map set-next-hop-global-v6 permit 10 + set ipv6 next-hop prefer-global +! router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -65,63 +73,32 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} {% endfor %} {% endblock vlan_advertisement %} -{% block bgp_sessions %} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} -{% if bgp_session['asn'] | int != 0 %} - neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} - neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} -{# set the bgp neighbor timers if they have not default values #} -{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) - or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} - neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} -{% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} - neighbor {{ neighbor_addr }} shutdown -{% endif %} -{# Apply default route-map for v4 peers #} -{% if neighbor_addr | ipv4 %} - neighbor {{ neighbor_addr }} route-map TO_BGP_PEER_V4 out -{% endif %} -{% if neighbor_addr | ipv4 %} +{% block maximum_paths %} address-family ipv4 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor {{ neighbor_addr }} allowas-in 1 -{% endif %} - neighbor {{ neighbor_addr }} activate - neighbor {{ neighbor_addr }} soft-reconfiguration inbound -{% if bgp_session['rrclient'] | int != 0 %} - neighbor {{ neighbor_addr }} route-reflector-client -{% endif %} -{% if bgp_session['nhopself'] | int != 0 %} - neighbor {{ neighbor_addr }} next-hop-self -{% endif %} maximum-paths 64 exit-address-family -{% endif %} -{% if neighbor_addr | ipv6 %} address-family ipv6 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor {{ neighbor_addr }} allowas-in 1 -{% endif %} - neighbor {{ neighbor_addr }} activate - neighbor {{ neighbor_addr }} soft-reconfiguration inbound -{% if bgp_session['rrclient'] | int != 0 %} - neighbor {{ neighbor_addr }} route-reflector-client -{% endif %} -{% if bgp_session['nhopself'] | int != 0 %} - neighbor {{ neighbor_addr }} next-hop-self -{% endif %} -{% if bgp_session['asn'] != DEVICE_METADATA['localhost']['bgp_asn'] %} - neighbor {{ neighbor_addr }} route-map set-next-hop-global-v6 in -{% endif %} -{# Apply default route-map for v6 peers #} - neighbor {{ neighbor_addr }} route-map TO_BGP_PEER_V6 out maximum-paths 64 exit-address-family +{% endblock maximum_paths %} +{% block peers_peer_group %} + neighbor PEER_V4 peer-group + neighbor PEER_V6 peer-group + address-family ipv4 +{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor PEER_V4 allowas-in 1 {% endif %} + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out + exit-address-family + address-family ipv6 +{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor PEER_V6 allowas-in 1 {% endif %} -{% endfor %} -{% endblock bgp_sessions %} + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out + exit-address-family +{% endblock peers_peer_group %} {% block bgp_peers_with_range %} {% if BGP_PEER_RANGE %} {% for bgp_peer in BGP_PEER_RANGE.values() %} @@ -150,11 +127,9 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endfor %} address-family ipv4 neighbor {{ bgp_peer['name'] }} activate - maximum-paths 64 exit-address-family address-family ipv6 neighbor {{ bgp_peer['name'] }} activate - maximum-paths 64 exit-address-family {% endfor %} {% endif %} diff --git a/dockers/docker-fpm-frr/bgpd.conf.j2 b/dockers/docker-fpm-frr/bgpd.conf.j2 index e9554806b64a..b4b2cd59c9b9 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.j2 @@ -6,28 +6,13 @@ ! {% endblock banner %} ! -{% block system_init %} -hostname {{ DEVICE_METADATA['localhost']['hostname'] }} -password zebra -log syslog informational -log facility local4 +{% include "daemons.common.conf.j2" %} +! agentx -! enable password {# {{ en_passwd }} TODO: param needed #} -{% endblock system_init %} ! {% if DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} {% include "bgpd.conf.spine_chassis_frontend_router.j2" %} -{% else%} -{% include "bgpd.conf.default.j2" %} -{% endif %} -! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} -maximum-paths 64 -! -route-map ISOLATE permit 10 -set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} ! -route-map set-next-hop-global-v6 permit 10 -set ipv6 next-hop prefer-global +{% include "bgpd.conf.default.j2" %} ! diff --git a/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 b/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 index 9bd5ef1947c3..afb621b0bf61 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 @@ -1,3 +1,4 @@ +! {# VNET BGP Instance #} ! Vnet BGP instance {% set interfaces_in_vnets = [] %} @@ -59,70 +60,4 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} {% endfor %} {% endfor %} {% endblock vnet_bgp_instance %} - -{# default bgp #} -{% block default_bgp_instance %} -{% block bgp_init %} -! -! bgp multiple-instance -! -route-map FROM_BGP_SPEAKER_V4 permit 10 -! -route-map TO_BGP_SPEAKER_V4 deny 10 ! -router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - bgp graceful-restart restart-time 240 - bgp graceful-restart -{% for (name, prefix) in LOOPBACK_INTERFACE | pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - bgp router-id {{ prefix | ip }} -{% endif %} -{% endfor %} -{# advertise loopback #} -{% for (name, prefix) in LOOPBACK_INTERFACE | pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - network {{ prefix | ip }}/32 -{% elif prefix | ipv6 and name == 'Loopback0' %} - address-family ipv6 - network {{ prefix | ip }}/64 - exit-address-family -{% endif %} -{% endfor %} -{% endblock bgp_init %} -{% block bgp_sessions %} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} -{% if not bgp_session.has_key("local_addr") or bgp_session["local_addr"] not in interfaces_in_vnets %} -{% if bgp_session['asn'] | int != 0 %} - neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} - neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} -{# set the bgp neighbor timers if they have not default values #} -{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) - or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} - neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} -{% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} - neighbor {{ neighbor_addr }} shutdown -{% endif %} -{% if bgp_session["asn"] != DEVICE_METADATA['localhost']['bgp_asn'] %} -{% if neighbor_addr | ipv4 %} - address-family ipv4 unicast - neighbor {{ neighbor_addr }} allowas-in 1 - neighbor {{ neighbor_addr }} activate - neighbor {{ neighbor_addr }} soft-reconfiguration inbound - maximum-paths 64 - exit-address-family -{% endif %} -{% else %} - address-family l2vpn evpn - neighbor {{ neighbor_addr }} activate - advertise-all-vni - exit-address-family -{% endif %} -{% endif %} -{% endif %} -{% endfor %} -{% endblock bgp_sessions %} -{% endblock default_bgp_instance %} diff --git a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 new file mode 100644 index 000000000000..7dfdd50ea2c0 --- /dev/null +++ b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 @@ -0,0 +1,30 @@ +{% block bgp_peer %} + neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} +{# set the bgp neighbor timers if they have not default values #} +{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) + or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} + neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} +{% endif %} +{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} + neighbor {{ neighbor_addr }} shutdown +{% endif %} +{% if neighbor_addr | ipv4 %} + address-family ipv4 + neighbor {{ neighbor_addr }} peer-group PEER_V4 +{% elif neighbor_addr | ipv6 %} + address-family ipv6 +{% if bgp_session['asn'] != DEVICE_METADATA['localhost']['bgp_asn'] %} + neighbor {{ neighbor_addr }} route-map set-next-hop-global-v6 in +{% endif %} + neighbor {{ neighbor_addr }} peer-group PEER_V6 +{% endif %} +{% if bgp_session['rrclient'] | int != 0 %} + neighbor {{ neighbor_addr }} route-reflector-client +{% endif %} +{% if bgp_session['nhopself'] | int != 0 %} + neighbor {{ neighbor_addr }} next-hop-self +{% endif %} + neighbor {{ neighbor_addr }} activate + exit-address-family +{% endblock bgp_peer %} diff --git a/dockers/docker-fpm-frr/daemons.common.conf.j2 b/dockers/docker-fpm-frr/daemons.common.conf.j2 new file mode 100644 index 000000000000..23eb5184f5e0 --- /dev/null +++ b/dockers/docker-fpm-frr/daemons.common.conf.j2 @@ -0,0 +1,12 @@ +! +{% block sys_init %} +hostname {{ DEVICE_METADATA['localhost']['hostname'] }} +password zebra +enable password zebra +{% endblock sys_init %} +! +{% block logging %} +log syslog informational +log facility local4 +{% endblock logging %} +! diff --git a/dockers/docker-fpm-frr/frr.conf.j2 b/dockers/docker-fpm-frr/frr.conf.j2 index d9dd6bf05633..afa40ad8ba75 100644 --- a/dockers/docker-fpm-frr/frr.conf.j2 +++ b/dockers/docker-fpm-frr/frr.conf.j2 @@ -6,205 +6,13 @@ ! {% endblock banner %} ! -{% block system_init %} -hostname {{ DEVICE_METADATA['localhost']['hostname'] }} -password zebra -log syslog informational -log facility local4 -agentx -! enable password {# {{ en_passwd }} TODO: param needed #} -{% endblock system_init %} -! -{% block interfaces %} -! Enable link-detect (default disabled) -{% for (name, prefix) in INTERFACE|pfx_filter %} -interface {{ name }} -link-detect -! -{% endfor %} -{% for pc in PORTCHANNEL %} -interface {{ pc }} -link-detect -! -{% endfor %} -{% endblock interfaces %} -! -{% block default_route %} -! set static default route to mgmt gateway as a backup to learned default -{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} -{% if prefix | ipv4 %} -ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200 -{% endif %} -{% endfor %} -{% endblock default_route %} -! -{% block source_loopback %} -{% set lo_ipv4_addrs = [] %} -{% set lo_ipv6_addrs = [] %} -{% if LOOPBACK_INTERFACE %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if name == 'Loopback0' %} -{% if prefix | ipv6 %} -{% if lo_ipv6_addrs.append(prefix) %} -{% endif %} -{% else %} -{% if lo_ipv4_addrs.append(prefix) %} -{% endif %} -{% endif %} -{% endif %} -{% endfor %} -{% endif %} -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src {{ lo_ipv4_addrs[0] | ip }} -! -{% if lo_ipv6_addrs|length > 0 %} -route-map RM_SET_SRC6 permit 10 - set src {{ lo_ipv6_addrs[0] | ip }} -! -{% endif %} -ip protocol bgp route-map RM_SET_SRC +{% include "daemons.common.conf.j2" %} ! -{% if lo_ipv6_addrs|length > 0 %} -ipv6 protocol bgp route-map RM_SET_SRC6 -! -{% endif %} -{% endblock source_loopback %} -! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} -{% block bgp_init %} -! -! bgp multiple-instance -! -route-map FROM_BGP_SPEAKER_V4 permit 10 -! -route-map TO_BGP_SPEAKER_V4 deny 10 -! -router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast -{# Advertise graceful restart capability for ToR #} -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - bgp graceful-restart -{% endif %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - bgp router-id {{ prefix | ip }} -{% endif %} -{% endfor %} -{# advertise loopback #} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - network {{ prefix | ip }}/32 -{% elif prefix | ipv6 and name == 'Loopback0' %} - address-family ipv6 - network {{ prefix | ip }}/64 - exit-address-family -{% endif %} -{% endfor %} -{% endblock bgp_init %} -{% endif %} -{% block vlan_advertisement %} -{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} -{% if prefix | ipv4 %} - network {{ prefix }} -{% elif prefix | ipv6 %} - address-family ipv6 - network {{ prefix }} - exit-address-family -{% endif %} -{% endfor %} -{% endblock vlan_advertisement %} -{% block bgp_sessions %} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} -{% if bgp_session['asn'] | int != 0 %} - neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} - neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} -{# set the bgp neighbor timers if they have not default values #} -{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) - or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} - neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} -{% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} - neighbor {{ neighbor_addr }} shutdown -{% endif %} -{% if neighbor_addr | ipv4 %} - address-family ipv4 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor {{ neighbor_addr }} allowas-in 1 -{% endif %} - neighbor {{ neighbor_addr }} activate - neighbor {{ neighbor_addr }} soft-reconfiguration inbound -{% if bgp_session['rrclient'] | int != 0 %} - neighbor {{ neighbor_addr }} route-reflector-client -{% endif %} -{% if bgp_session['nhopself'] | int != 0 %} - neighbor {{ neighbor_addr }} next-hop-self -{% endif %} - maximum-paths 64 - exit-address-family -{% endif %} -{% if neighbor_addr | ipv6 %} - address-family ipv6 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor {{ neighbor_addr }} allowas-in 1 -{% endif %} - neighbor {{ neighbor_addr }} activate - neighbor {{ neighbor_addr }} soft-reconfiguration inbound -{% if bgp_session['rrclient'] | int != 0 %} - neighbor {{ neighbor_addr }} route-reflector-client -{% endif %} -{% if bgp_session['nhopself'] | int != 0 %} - neighbor {{ neighbor_addr }} next-hop-self -{% endif %} -{% if bgp_session['asn'] != DEVICE_METADATA['localhost']['bgp_asn'] %} - neighbor {{ neighbor_addr }} route-map set-next-hop-global-v6 in -{% endif %} - maximum-paths 64 - exit-address-family -{% endif %} -{% endif %} -{% endfor %} -{% endblock bgp_sessions %} -{% block bgp_peers_with_range %} -{% if BGP_PEER_RANGE %} -{% for bgp_peer in BGP_PEER_RANGE.values() %} - neighbor {{ bgp_peer['name'] }} peer-group - neighbor {{ bgp_peer['name'] }} passive - neighbor {{ bgp_peer['name'] }} remote-as {{ deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} - neighbor {{ bgp_peer['name'] }} ebgp-multihop 255 -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if name == 'Loopback1' %} - neighbor {{ bgp_peer['name'] }} update-source {{ prefix | ip }} -{% endif %} -{% endfor %} -{% for ip_range in bgp_peer['ip_range'] %} - bgp listen range {{ip_range}} peer-group {{ bgp_peer['name'] }} -{% endfor %} - address-family ipv4 - neighbor {{ bgp_peer['name'] }} activate - neighbor {{ bgp_peer['name'] }} soft-reconfiguration inbound - neighbor {{ bgp_peer['name'] }} route-map FROM_BGP_SPEAKER_V4 in - neighbor {{ bgp_peer['name'] }} route-map TO_BGP_SPEAKER_V4 out - maximum-paths 64 - exit-address-family - address-family ipv6 - neighbor {{ bgp_peer['name'] }} activate - neighbor {{ bgp_peer['name'] }} soft-reconfiguration inbound - maximum-paths 64 - exit-address-family -{% endfor %} -{% endif %} -{% endblock bgp_peers_with_range %} +agentx ! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} -maximum-paths 64 +{% include "zebra.interfaces.conf.j2" %} ! -route-map ISOLATE permit 10 -set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }} -{% endif %} +{% include "staticd.default_route.conf.j2" %} ! -route-map set-next-hop-global-v6 permit 10 -set ipv6 next-hop prefer-global +{% include "bgpd.conf.default.j2" %} ! diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/start.sh index 3c732fece943..a1b0c0ea0b08 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/start.sh @@ -33,8 +33,6 @@ rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd -supervisorctl start bgpcfgd - # Start Quagga processes supervisorctl start zebra supervisorctl start staticd @@ -45,3 +43,5 @@ if [ "$CONFIG_TYPE" == "unified" ]; then fi supervisorctl start fpmsyncd + +supervisorctl start bgpcfgd diff --git a/dockers/docker-fpm-frr/staticd.conf.j2 b/dockers/docker-fpm-frr/staticd.conf.j2 index b3de8c424f12..4e39e17d7dbf 100644 --- a/dockers/docker-fpm-frr/staticd.conf.j2 +++ b/dockers/docker-fpm-frr/staticd.conf.j2 @@ -6,24 +6,7 @@ ! {% endblock banner %} ! -{% block sys_init %} -hostname {{ DEVICE_METADATA['localhost']['hostname'] }} -password zebra -enable password zebra -{% endblock sys_init %} +{% include "daemons.common.conf.j2" %} ! -{% block default_route %} -! set static default route to mgmt gateway as a backup to learned default -{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} -{% if prefix | ipv4 %} -ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200 -{% endif %} -{% endfor %} -{% endblock default_route %} +{% include "staticd.default_route.conf.j2" %} ! -{% block logging %} -log syslog informational -log facility local4 -{% endblock logging %} -! - diff --git a/dockers/docker-fpm-frr/staticd.default_route.conf.j2 b/dockers/docker-fpm-frr/staticd.default_route.conf.j2 new file mode 100644 index 000000000000..22d61ebbd0ff --- /dev/null +++ b/dockers/docker-fpm-frr/staticd.default_route.conf.j2 @@ -0,0 +1,10 @@ +! +{% block default_route %} +! set static default route to mgmt gateway as a backup to learned default +{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} +ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200 +{% endif %} +{% endfor %} +{% endblock default_route %} +! diff --git a/dockers/docker-fpm-frr/zebra.conf.j2 b/dockers/docker-fpm-frr/zebra.conf.j2 index 3135a056a656..8c1c6f96484b 100644 --- a/dockers/docker-fpm-frr/zebra.conf.j2 +++ b/dockers/docker-fpm-frr/zebra.conf.j2 @@ -6,74 +6,7 @@ ! {% endblock banner %} ! -{% block sys_init %} -hostname {{ DEVICE_METADATA['localhost']['hostname'] }} -password zebra -enable password zebra -{% endblock sys_init %} +{% include "daemons.common.conf.j2" %} ! -{% block vrf %} -{% if VNET is defined %} -{% for vnet_name, vnet_metadata in VNET.iteritems() %} -vrf {{ vnet_name }} -vni {{ vnet_metadata['vni'] }} +{% include "zebra.interfaces.conf.j2" %} ! -{% endfor %} -{% endif %} -{% endblock vrf %} -! -{% block interfaces %} -! Enable link-detect (default disabled) -{% for (name, prefix) in INTERFACE|pfx_filter %} -interface {{ name }} -link-detect -! -{% endfor %} -{% for pc in PORTCHANNEL %} -interface {{ pc }} -link-detect -! -{% endfor %} -{% endblock interfaces %} -! -{% block source_loopback %} -{% set lo_ipv4_addrs = [] %} -{% set lo_ipv6_addrs = [] %} -{% if LOOPBACK_INTERFACE %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if name == 'Loopback0' %} -{% if prefix | ipv6 %} -{% if lo_ipv6_addrs.append(prefix) %} -{% endif %} -{% else %} -{% if lo_ipv4_addrs.append(prefix) %} -{% endif %} -{% endif %} -{% endif %} -{% endfor %} -{% endif %} -! Set ip source to loopback for bgp learned routes -{% if lo_ipv4_addrs|length > 0 -%} -route-map RM_SET_SRC permit 10 - set src {{ lo_ipv4_addrs[0] | ip }} -! -{% endif %} -{% if lo_ipv6_addrs|length > 0 %} -route-map RM_SET_SRC6 permit 10 - set src {{ lo_ipv6_addrs[0] | ip }} -! -{% endif %} -ip protocol bgp route-map RM_SET_SRC -! -{% if lo_ipv6_addrs|length > 0 %} -ipv6 protocol bgp route-map RM_SET_SRC6 -! -{% endif %} -{% endblock source_loopback %} -! -{% block logging %} -log syslog informational -log facility local4 -{% endblock logging %} -! - diff --git a/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 new file mode 100644 index 000000000000..4a089e4dc726 --- /dev/null +++ b/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 @@ -0,0 +1,60 @@ +! +{% block vrf %} +{% if VNET is defined %} +{% for vnet_name, vnet_metadata in VNET.iteritems() %} +vrf {{ vnet_name }} +vni {{ vnet_metadata['vni'] }} +! +{% endfor %} +{% endif %} +{% endblock vrf %} +! +{% block interfaces %} +! Enable link-detect (default disabled) +{% for (name, prefix) in INTERFACE|pfx_filter %} +interface {{ name }} +link-detect +! +{% endfor %} +{% for pc in PORTCHANNEL %} +interface {{ pc }} +link-detect +! +{% endfor %} +{% endblock interfaces %} +! +{% block source_loopback %} +{% set lo_ipv4_addrs = [] %} +{% set lo_ipv6_addrs = [] %} +{% if LOOPBACK_INTERFACE %} +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if name == 'Loopback0' %} +{% if prefix | ipv6 %} +{% if lo_ipv6_addrs.append(prefix) %} +{% endif %} +{% else %} +{% if lo_ipv4_addrs.append(prefix) %} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +! Set ip source to loopback for bgp learned routes +{% if lo_ipv4_addrs|length > 0 -%} +route-map RM_SET_SRC permit 10 + set src {{ lo_ipv4_addrs[0] | ip }} +! +{% endif %} +{% if lo_ipv6_addrs|length > 0 %} +route-map RM_SET_SRC6 permit 10 + set src {{ lo_ipv6_addrs[0] | ip }} +! +{% endif %} +ip protocol bgp route-map RM_SET_SRC +! +{% if lo_ipv6_addrs|length > 0 %} +ipv6 protocol bgp route-map RM_SET_SRC6 +! +{% endif %} +{% endblock source_loopback %} +! diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 2f4e9c5eb89b..ca550b49e4bc 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -103,6 +103,14 @@ def pfx_filter(value): table[key] = val return table +def ip_network(value): + """ Extract network for network prefix """ + try: + r_v = netaddr.IPNetwork(value) + except: + return "Invalid ip address %s" % value + return r_v.network + class FormatConverter: """Convert config DB based schema to legacy minigraph based schema for backward capability. We will move to DB schema and remove this class when the config templates are modified. @@ -265,6 +273,7 @@ def main(): env.filters['ipv6'] = is_ipv6 env.filters['unique_name'] = unique_name env.filters['pfx_filter'] = pfx_filter + env.filters['ip_network'] = ip_network for attr in ['ip', 'network', 'prefixlen', 'netmask']: env.filters[attr] = partial(prefix_attr, attr) template = env.get_template(template_file) diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf index c796ef8c164b..3a8abf050b45 100644 --- a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf @@ -4,12 +4,18 @@ ! file: bgpd.conf ! ! +! hostname switch-t0 password zebra +enable password zebra +! log syslog informational log facility local4 +!! agentx -! enable password ! +! +! +! ! ! bgp multiple-instance ! @@ -18,7 +24,7 @@ route-map FROM_BGP_SPEAKER_V4 permit 10 route-map TO_BGP_SPEAKER_V4 deny 10 ! ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 -ipv6 prefix-list PL_LoopbackV6 permit fc00:1::32/64 +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! ! route-map TO_BGP_PEER_V4 permit 100 @@ -29,6 +35,13 @@ route-map FROM_BGPMON_V4 deny 10 ! route-map TO_BGPMON_V4 permit 10 ! +! +route-map ISOLATE permit 10 + set as-path prepend 65100 +! +route-map set-next-hop-global-v6 permit 10 + set ipv6 next-hop prefer-global +! router bgp 65100 bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -42,81 +55,23 @@ router bgp 65100 network fc00:1::32/64 exit-address-family network 192.168.0.1/27 - neighbor 10.0.0.57 remote-as 64600 - neighbor 10.0.0.57 description ARISTA01T1 - neighbor 10.0.0.57 route-map TO_BGP_PEER_V4 out - address-family ipv4 - neighbor 10.0.0.57 allowas-in 1 - neighbor 10.0.0.57 activate - neighbor 10.0.0.57 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.59 remote-as 64600 - neighbor 10.0.0.59 description ARISTA02T1 - neighbor 10.0.0.59 route-map TO_BGP_PEER_V4 out - address-family ipv4 - neighbor 10.0.0.59 allowas-in 1 - neighbor 10.0.0.59 activate - neighbor 10.0.0.59 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.61 remote-as 64600 - neighbor 10.0.0.61 description ARISTA03T1 - neighbor 10.0.0.61 route-map TO_BGP_PEER_V4 out - address-family ipv4 - neighbor 10.0.0.61 allowas-in 1 - neighbor 10.0.0.61 activate - neighbor 10.0.0.61 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.63 remote-as 64600 - neighbor 10.0.0.63 description ARISTA04T1 - neighbor 10.0.0.63 route-map TO_BGP_PEER_V4 out address-family ipv4 - neighbor 10.0.0.63 allowas-in 1 - neighbor 10.0.0.63 activate - neighbor 10.0.0.63 soft-reconfiguration inbound maximum-paths 64 exit-address-family - neighbor fc00::7a remote-as 64600 - neighbor fc00::7a description ARISTA03T1 address-family ipv6 - neighbor fc00::7a allowas-in 1 - neighbor fc00::7a activate - neighbor fc00::7a soft-reconfiguration inbound - neighbor fc00::7a route-map set-next-hop-global-v6 in - neighbor fc00::7a route-map TO_BGP_PEER_V6 out maximum-paths 64 exit-address-family - neighbor fc00::7e remote-as 64600 - neighbor fc00::7e description ARISTA04T1 - address-family ipv6 - neighbor fc00::7e allowas-in 1 - neighbor fc00::7e activate - neighbor fc00::7e soft-reconfiguration inbound - neighbor fc00::7e route-map set-next-hop-global-v6 in - neighbor fc00::7e route-map TO_BGP_PEER_V6 out - maximum-paths 64 - exit-address-family - neighbor fc00::72 remote-as 64600 - neighbor fc00::72 description ARISTA01T1 - address-family ipv6 - neighbor fc00::72 allowas-in 1 - neighbor fc00::72 activate - neighbor fc00::72 soft-reconfiguration inbound - neighbor fc00::72 route-map set-next-hop-global-v6 in - neighbor fc00::72 route-map TO_BGP_PEER_V6 out - maximum-paths 64 + neighbor PEER_V4 peer-group + neighbor PEER_V6 peer-group + address-family ipv4 + neighbor PEER_V4 allowas-in 1 + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out exit-address-family - neighbor fc00::76 remote-as 64600 - neighbor fc00::76 description ARISTA02T1 address-family ipv6 - neighbor fc00::76 allowas-in 1 - neighbor fc00::76 activate - neighbor fc00::76 soft-reconfiguration inbound - neighbor fc00::76 route-map set-next-hop-global-v6 in - neighbor fc00::76 route-map TO_BGP_PEER_V6 out - maximum-paths 64 + neighbor PEER_V6 allowas-in 1 + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out exit-address-family neighbor BGPMON_V4 peer-group neighbor BGPMON_V4 update-source 10.1.0.32 @@ -129,11 +84,3 @@ router bgp 65100 neighbor 10.20.30.40 description BGPMonitor neighbor 10.20.30.40 activate !! -maximum-paths 64 -! -route-map ISOLATE permit 10 -set as-path prepend 65100 -! -route-map set-next-hop-global-v6 permit 10 -set ipv6 next-hop prefer-global -! diff --git a/src/sonic-config-engine/tests/sample_output/frr.conf b/src/sonic-config-engine/tests/sample_output/frr.conf index 8e7f97cf8c55..edcf0939a03f 100644 --- a/src/sonic-config-engine/tests/sample_output/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/frr.conf @@ -4,12 +4,18 @@ ! file: frr.conf ! ! +! hostname switch-t0 password zebra +enable password zebra +! log syslog informational log facility local4 +!! agentx -! enable password ! +! +! +! ! Enable link-detect (default disabled) interface PortChannel01 link-detect @@ -24,9 +30,6 @@ interface PortChannel04 link-detect ! ! -! set static default route to mgmt gateway as a backup to learned default -ip route 0.0.0.0/0 10.0.0.1 200 -! ! Set ip source to loopback for bgp learned routes route-map RM_SET_SRC permit 10 set src 10.1.0.32 @@ -39,6 +42,11 @@ ip protocol bgp route-map RM_SET_SRC ! ipv6 protocol bgp route-map RM_SET_SRC6 ! +!! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +!! ! ! ! bgp multiple-instance @@ -47,91 +55,64 @@ route-map FROM_BGP_SPEAKER_V4 permit 10 ! route-map TO_BGP_SPEAKER_V4 deny 10 ! +ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 +! +! +route-map TO_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +route-map FROM_BGPMON_V4 deny 10 +! +route-map TO_BGPMON_V4 permit 10 +! +! +route-map ISOLATE permit 10 + set as-path prepend 65100 +! +route-map set-next-hop-global-v6 permit 10 + set ipv6 next-hop prefer-global +! router bgp 65100 bgp log-neighbor-changes bgp bestpath as-path multipath-relax no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 bgp graceful-restart + bgp graceful-restart preserve-fw-state bgp router-id 10.1.0.32 network 10.1.0.32/32 address-family ipv6 network fc00:1::32/64 exit-address-family network 192.168.0.1/27 - neighbor 10.0.0.57 remote-as 64600 - neighbor 10.0.0.57 description ARISTA01T1 address-family ipv4 - neighbor 10.0.0.57 allowas-in 1 - neighbor 10.0.0.57 activate - neighbor 10.0.0.57 soft-reconfiguration inbound maximum-paths 64 exit-address-family - neighbor 10.0.0.59 remote-as 64600 - neighbor 10.0.0.59 description ARISTA02T1 - address-family ipv4 - neighbor 10.0.0.59 allowas-in 1 - neighbor 10.0.0.59 activate - neighbor 10.0.0.59 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.61 remote-as 64600 - neighbor 10.0.0.61 description ARISTA03T1 - address-family ipv4 - neighbor 10.0.0.61 allowas-in 1 - neighbor 10.0.0.61 activate - neighbor 10.0.0.61 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.63 remote-as 64600 - neighbor 10.0.0.63 description ARISTA04T1 - address-family ipv4 - neighbor 10.0.0.63 allowas-in 1 - neighbor 10.0.0.63 activate - neighbor 10.0.0.63 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor fc00::7a remote-as 64600 - neighbor fc00::7a description ARISTA03T1 - address-family ipv6 - neighbor fc00::7a allowas-in 1 - neighbor fc00::7a activate - neighbor fc00::7a soft-reconfiguration inbound - neighbor fc00::7a route-map set-next-hop-global-v6 in - maximum-paths 64 - exit-address-family - neighbor fc00::7e remote-as 64600 - neighbor fc00::7e description ARISTA04T1 address-family ipv6 - neighbor fc00::7e allowas-in 1 - neighbor fc00::7e activate - neighbor fc00::7e soft-reconfiguration inbound - neighbor fc00::7e route-map set-next-hop-global-v6 in maximum-paths 64 exit-address-family - neighbor fc00::72 remote-as 64600 - neighbor fc00::72 description ARISTA01T1 - address-family ipv6 - neighbor fc00::72 allowas-in 1 - neighbor fc00::72 activate - neighbor fc00::72 soft-reconfiguration inbound - neighbor fc00::72 route-map set-next-hop-global-v6 in - maximum-paths 64 + neighbor PEER_V4 peer-group + neighbor PEER_V6 peer-group + address-family ipv4 + neighbor PEER_V4 allowas-in 1 + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out exit-address-family - neighbor fc00::76 remote-as 64600 - neighbor fc00::76 description ARISTA02T1 address-family ipv6 - neighbor fc00::76 allowas-in 1 - neighbor fc00::76 activate - neighbor fc00::76 soft-reconfiguration inbound - neighbor fc00::76 route-map set-next-hop-global-v6 in - maximum-paths 64 + neighbor PEER_V6 allowas-in 1 + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out exit-address-family -! -maximum-paths 64 -! -route-map ISOLATE permit 10 -set as-path prepend 65100 -! -route-map set-next-hop-global-v6 permit 10 -set ipv6 next-hop prefer-global -! + neighbor BGPMON_V4 peer-group + neighbor BGPMON_V4 update-source 10.1.0.32 + neighbor BGPMON_V4 route-map FROM_BGPMON_V4 in + neighbor BGPMON_V4 route-map TO_BGPMON_V4 out + neighbor BGPMON_V4 send-community + neighbor BGPMON_V4 maximum-prefix 1 + neighbor 10.20.30.40 remote-as 65100 + neighbor 10.20.30.40 peer-group BGPMON_V4 + neighbor 10.20.30.40 description BGPMonitor + neighbor 10.20.30.40 activate +!! diff --git a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/staticd_frr.conf index a1a5fddf322b..12a81de82125 100644 --- a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/staticd_frr.conf @@ -4,14 +4,15 @@ ! file: staticd.conf ! ! +! hostname switch-t0 password zebra enable password zebra ! -! set static default route to mgmt gateway as a backup to learned default -ip route 0.0.0.0/0 10.0.0.1 200 -! log syslog informational log facility local4 +!! ! - +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +!! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf index 515e0aba8df2..b0b5e2cb1192 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf @@ -4,12 +4,17 @@ ! file: bgpd.conf ! ! +! hostname SpineFront01 password zebra +enable password zebra +! log syslog informational log facility local4 +!! agentx -! enable password ! +! +! ! Vnet BGP instance router bgp 4000 vrf VnetFE no bgp default ipv4-unicast @@ -30,7 +35,8 @@ router bgp 4000 vrf VnetFE address-family l2vpn evpn advertise ipv4 unicast exit-address-family - +!! +! ! ! bgp multiple-instance ! @@ -38,6 +44,20 @@ route-map FROM_BGP_SPEAKER_V4 permit 10 ! route-map TO_BGP_SPEAKER_V4 deny 10 ! +ip prefix-list PL_LoopbackV4 permit 4.0.0.0/32 +! +! +route-map TO_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +! +route-map ISOLATE permit 10 + set as-path prepend 4000 +! +route-map set-next-hop-global-v6 permit 10 + set ipv6 next-hop prefer-global +! router bgp 4000 bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -46,37 +66,20 @@ router bgp 4000 bgp graceful-restart bgp router-id 4.0.0.0 network 4.0.0.0/32 - neighbor 4.0.0.1 remote-as 4000 - neighbor 4.0.0.1 description SpineFront02 - neighbor 4.0.0.1 timers 3 10 - address-family l2vpn evpn - neighbor 4.0.0.1 activate - advertise-all-vni - exit-address-family - neighbor 172.16.0.2 remote-as 5000 - neighbor 172.16.0.2 description SpineBack01 - neighbor 172.16.0.2 timers 3 10 - address-family ipv4 unicast - neighbor 172.16.0.2 allowas-in 1 - neighbor 172.16.0.2 activate - neighbor 172.16.0.2 soft-reconfiguration inbound + address-family ipv4 maximum-paths 64 exit-address-family - neighbor 172.16.0.10 remote-as 5000 - neighbor 172.16.0.10 description SpineBack02 - neighbor 172.16.0.10 timers 3 10 - address-family ipv4 unicast - neighbor 172.16.0.10 allowas-in 1 - neighbor 172.16.0.10 activate - neighbor 172.16.0.10 soft-reconfiguration inbound + address-family ipv6 maximum-paths 64 exit-address-family -! -maximum-paths 64 -! -route-map ISOLATE permit 10 -set as-path prepend 4000 -! -route-map set-next-hop-global-v6 permit 10 -set ipv6 next-hop prefer-global -! + neighbor PEER_V4 peer-group + neighbor PEER_V6 peer-group + address-family ipv4 + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out + exit-address-family + address-family ipv6 + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out + exit-address-family +!! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf index 30571f2082ae..bd2b5c84f471 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf @@ -4,10 +4,15 @@ ! file: zebra.conf ! ! +! hostname SpineFront01 password zebra enable password zebra ! +log syslog informational +log facility local4 +!! +! vrf VnetFE vni 9000 ! @@ -29,8 +34,4 @@ route-map RM_SET_SRC permit 10 ! ip protocol bgp route-map RM_SET_SRC ! -! -log syslog informational -log facility local4 -! - +!! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf index c8157b0519a4..e047fcd64f29 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf @@ -4,10 +4,15 @@ ! file: zebra.conf ! ! +! hostname SpineFront01 password zebra enable password zebra ! +log syslog informational +log facility local4 +!! +! vrf VnetFE vni 8000 ! @@ -29,8 +34,4 @@ route-map RM_SET_SRC permit 10 ! ip protocol bgp route-map RM_SET_SRC ! -! -log syslog informational -log facility local4 -! - +!! diff --git a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf index 2b21ea523f7a..690f609dafcf 100644 --- a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf @@ -4,10 +4,15 @@ ! file: zebra.conf ! ! +! hostname switch-t0 password zebra enable password zebra ! +log syslog informational +log facility local4 +!! +! ! ! Enable link-detect (default disabled) interface PortChannel01 @@ -35,8 +40,4 @@ ip protocol bgp route-map RM_SET_SRC ! ipv6 protocol bgp route-map RM_SET_SRC6 ! -! -log syslog informational -log facility local4 -! - +!! diff --git a/src/sonic-config-engine/tests/test_frr.py b/src/sonic-config-engine/tests/test_frr.py new file mode 100644 index 000000000000..fcbff063b13b --- /dev/null +++ b/src/sonic-config-engine/tests/test_frr.py @@ -0,0 +1,62 @@ +from unittest import TestCase +import subprocess +import os +import filecmp + + +class TestCfgGen(TestCase): + def setUp(self): + self.test_dir = os.path.dirname(os.path.realpath(__file__)) + self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml') + self.t0_port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') + self.output_file = os.path.join(self.test_dir, 'output') + + def tearDown(self): + try: + os.remove(self.output_file) + except OSError: + pass + + + def run_script(self, argument, check_stderr=False): +# print '\n Running sonic-cfggen ' + argument + if check_stderr: + output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + linecount = output.strip().count('\n') + if linecount <= 0: + print ' Output: ' + output.strip() + else: + print ' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output)) + return output + + def run_diff(self, file1, file2): + return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) + + def run_case(self, template, target): + conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', template) + cmd = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file + self.run_script(cmd) + + original_filename = os.path.join(self.test_dir, 'sample_output', target) + r = filecmp.cmp(original_filename, self.output_file) + diff_output = self.run_diff(original_filename, self.output_file) if not r else "" + + return r, "Diff:\n" + diff_output + + + def test_config_frr(self): + self.assertTrue(*self.run_case('frr.conf.j2', 'frr.conf')) + + def test_bgpd_frr(self): + self.assertTrue(*self.run_case('bgpd.conf.j2', 'bgpd_frr.conf')) + + def test_zebra_frr(self): + self.assertTrue(*self.run_case('zebra.conf.j2', 'zebra_frr.conf')) + + def test_staticd_frr(self): + self.assertTrue(*self.run_case('staticd.conf.j2', 'staticd_frr.conf')) + diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 1fd9df37e984..c3585a41d44e 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -77,34 +77,6 @@ def test_zebra_quagga(self): self.run_script(argument) self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'zebra_quagga.conf'), self.output_file)) - def test_config_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'frr.conf.j2') - argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'frr.conf'), self.output_file)) - - - def test_bgpd_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'bgpd.conf.j2') - argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - original_filename = os.path.join(self.test_dir, 'sample_output', 'bgpd_frr.conf') - r = filecmp.cmp(original_filename, self.output_file) - diff_output = self.run_diff(original_filename, self.output_file) if not r else "" - self.assertTrue(r, "Diff:\n" + diff_output) - - def test_zebra_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'zebra.conf.j2') - argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'zebra_frr.conf'), self.output_file)) - - def test_staticd_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'staticd.conf.j2') - argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'staticd_frr.conf'), self.output_file)) - def test_ipinip(self): ipinip_file = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ipinip.json.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ipinip_file + ' > ' + self.output_file diff --git a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py index 531a9d477a66..41ac347e2b18 100644 --- a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py +++ b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py @@ -16,42 +16,39 @@ def setUp(self): self.t2_chassis_fe_port_config = os.path.join(self.test_dir, 't2-chassis-fe-port-config.ini') self.output_file = os.path.join(self.test_dir, 'output') + def tearDown(self): + try: + os.remove(self.output_file) + except OSError: + pass + def run_script(self, argument): print 'CMD: sonic-cfggen ' + argument return subprocess.check_output(self.script_file + ' ' + argument, shell=True) + def run_diff(self, file1, file2): + return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) + + def run_case(self, minigraph, template, target): + conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', template) + cmd = '-m ' + minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file + self.run_script(cmd) + + original_filename = os.path.join(self.test_dir, 'sample_output', target) + r = filecmp.cmp(original_filename, self.output_file) + diff_output = self.run_diff(original_filename, self.output_file) if not r else "" + + return r, "Diff:\n" + diff_output + # Test zebra.conf in FRR docker for a T2 chassis frontend (fe) def test_t2_chassis_fe_zebra_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'zebra.conf.j2') - argument = '-m ' + self.t2_chassis_fe_minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 't2-chassis-fe-zebra.conf'), self.output_file)) - - # Test zebra.conf in FRR docker for a T2 chassis frontend (fe) switch with port channel interfaces - def test_t2_chassis_fe_pc_zebra_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'zebra.conf.j2') - argument = '-m ' + self.t2_chassis_fe_pc_minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 't2-chassis-fe-pc-zebra.conf'), self.output_file)) + self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'zebra.conf.j2', 't2-chassis-fe-zebra.conf')) # Test zebra.conf in FRR docker for a T2 chassis frontend (fe) switch with specified VNI def test_t2_chassis_fe_vni_zebra_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'zebra.conf.j2') - argument = '-m ' + self.t2_chassis_fe_vni_minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 't2-chassis-fe-vni-zebra.conf'), self.output_file)) + self.assertTrue(*self.run_case(self.t2_chassis_fe_vni_minigraph, 'zebra.conf.j2', 't2-chassis-fe-vni-zebra.conf')) # Test bgpd.conf in FRR docker for a T2 chassis frontend (fe) def test_t2_chassis_frontend_bgpd_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'bgpd.conf.j2') - argument = '-m ' + self.t2_chassis_fe_minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 't2-chassis-fe-bgpd.conf'), self.output_file)) - - def tearDown(self): - try: - os.remove(self.output_file) - except OSError: - pass - + self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'bgpd.conf.j2', 't2-chassis-fe-bgpd.conf')) From 4d29e611a13f86f877586115c268c0769749db03 Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Fri, 25 Oct 2019 02:20:45 +0530 Subject: [PATCH 0098/1427] [build]: Kill arm march docker service before every run to avoid stale entries (#3644) [Makefile] Kill arm march docker service before every run to avoid stale entries [Platform] Marvell - add dtb deb pkg Signed-off-by: Antony Rheneus --- Makefile.work | 3 ++- platform/marvell-armhf/one-image.mk | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.work b/Makefile.work index e18cabeda9ca..37ee2e11529d 100644 --- a/Makefile.work +++ b/Makefile.work @@ -126,7 +126,8 @@ ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) DOCKER_MULTIARCH_CHECK := docker inspect --type image multiarch/qemu-user-static:register &> /dev/null || (echo "multiarch docker not found ..."; docker run --rm --privileged multiarch/qemu-user-static:register --reset --credential yes) - DOCKER_SERVICE_MULTIARCH_CHECK := docker -H unix:///var/run/march/docker.sock info &> /dev/null || (echo "Docker march service not running..."; sudo rm -fr /var/run/march/; (sudo $(SONIC_NATIVE_DOCKERD_FOR_MUTLIARCH) &) &>/dev/null ; sleep 1; sudo $(SONIC_USERFACL_DOCKERD_FOR_MUTLIARCH);) + DOCKER_SERVICE_SAFE_KILLER := (MARCH_PID=`ps -eo pid,cmd | grep "[0-9] dockerd.*march" | awk '{print $$1}'`; echo "Killing march docker $$MARCH_PID"; [ -z "$$MARCH_PID" ] || sudo kill -9 "$$MARCH_PID";) + DOCKER_SERVICE_MULTIARCH_CHECK := ($(DOCKER_SERVICE_SAFE_KILLER); sudo rm -fr /var/run/march/; (echo "Starting docker march service..."; sudo $(SONIC_NATIVE_DOCKERD_FOR_MUTLIARCH) &) &>/dev/null ; sleep 2; sudo $(SONIC_USERFACL_DOCKERD_FOR_MUTLIARCH);) # Docker service to load the compiled dockers-*.gz SONIC_NATIVE_DOCKERD_FOR_DOCKERFS := rm -fr $(PWD)/dockerfs/; mkdir -p $(PWD)/dockerfs/; sudo dockerd --storage-driver=overlay2 --iptables=false \ diff --git a/platform/marvell-armhf/one-image.mk b/platform/marvell-armhf/one-image.mk index 26ab6fb886a7..bed895d84d86 100644 --- a/platform/marvell-armhf/one-image.mk +++ b/platform/marvell-armhf/one-image.mk @@ -4,6 +4,7 @@ SONIC_ONE_IMAGE = sonic-marvell-armhf.bin $(SONIC_ONE_IMAGE)_MACHINE = marvell-armhf $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +$(SONIC_ONE_IMAGE)_INSTALLS += $(LINUX_KERNEL_DTB) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) From 4026a8bc8d918cd27a079a37527f9242596d8c64 Mon Sep 17 00:00:00 2001 From: zzhiyuan Date: Thu, 24 Oct 2019 16:48:46 -0700 Subject: [PATCH 0099/1427] Remove macro generate_pg_profils for 7170 buffer (#3635) --- .../Arista-7170-64C/buffers_defaults_t0.j2 | 8 -------- .../Arista-7170-64C/buffers_defaults_t1.j2 | 8 -------- .../Arista-7170-Q59S20/buffers_defaults_t0.j2 | 8 -------- .../Arista-7170-Q59S20/buffers_defaults_t1.j2 | 8 -------- 4 files changed, 32 deletions(-) diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 index e880e6bc3a9c..35188dbeb382 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 @@ -59,14 +59,6 @@ }, {%- endmacro %} -{%- macro generate_pg_profils(port_names) %} - "BUFFER_PG": { - "{{ port_names }}|3-4": { - "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" - } - }, -{%- endmacro %} - {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { "{{ port_names }}|3-4": { diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t1.j2 index e115dc9f0a1d..eb945c25e636 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t1.j2 +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t1.j2 @@ -59,14 +59,6 @@ }, {%- endmacro %} -{%- macro generate_pg_profils(port_names) %} - "BUFFER_PG": { - "{{ port_names }}|3-4": { - "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" - } - }, -{%- endmacro %} - {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { "{{ port_names }}|3-4": { diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 index 1f6e3f5ed35d..8cd886c14ffd 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 @@ -71,14 +71,6 @@ }, {%- endmacro %} -{%- macro generate_pg_profils(port_names) %} - "BUFFER_PG": { - "{{ port_names }}|3-4": { - "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" - } - }, -{%- endmacro %} - {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { "{{ port_names }}|3-4": { diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t1.j2 index 7487a1db19ba..e14ad9214743 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t1.j2 +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t1.j2 @@ -71,14 +71,6 @@ }, {%- endmacro %} -{%- macro generate_pg_profils(port_names) %} - "BUFFER_PG": { - "{{ port_names }}|3-4": { - "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" - } - }, -{%- endmacro %} - {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { "{{ port_names }}|3-4": { From 040672c93fc9f6c110800f08562938d2ce1a46ec Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Thu, 24 Oct 2019 18:16:06 -0700 Subject: [PATCH 0100/1427] [minigraph.py] Enable telemetry service by default (#3611) --- src/sonic-config-engine/minigraph.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 37d68bdbfb0c..33736383506b 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -800,8 +800,12 @@ def parse_xml(filename, platform=None, port_config_file=None): results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers) results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers) results['TACPLUS_SERVER'] = dict((item, {'priority': '1', 'tcp_port': '49'}) for item in tacacs_servers) - results['ACL_TABLE'] = filter_acl_mirror_table_bindings(acls, neighbors, pcs) + results['FEATURE'] = { + 'telemetry': { + 'status': 'enabled' + } + } # Do not configure the minigraph's mirror session, which is currently unused # mirror_sessions = {} From c23aac1581d4cd59e87294d36854d92e3f98bfbc Mon Sep 17 00:00:00 2001 From: zhenggen-xu Date: Sun, 27 Oct 2019 21:15:39 -0700 Subject: [PATCH 0101/1427] [swss] Remove "-p port_config.ini" option from the portsyncd (#3671) * [portsyncd] Remove "-p port_config.ini" option from the portsyncd Signed-off-by: Zhenggen Xu --- dockers/docker-orchagent/supervisord.conf | 2 +- platform/p4/docker-sonic-p4/supervisord.conf | 2 +- platform/vs/docker-sonic-vs/supervisord.conf | 2 +- src/sonic-swss | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 46b37e77c0e4..9ae2776f6d26 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -34,7 +34,7 @@ stdout_logfile=syslog stderr_logfile=syslog [program:portsyncd] -command=/usr/bin/portsyncd -p /usr/share/sonic/hwsku/port_config.ini +command=/usr/bin/portsyncd priority=4 autostart=false autorestart=false diff --git a/platform/p4/docker-sonic-p4/supervisord.conf b/platform/p4/docker-sonic-p4/supervisord.conf index 008f4c82d2c9..946e4cb36e3a 100644 --- a/platform/p4/docker-sonic-p4/supervisord.conf +++ b/platform/p4/docker-sonic-p4/supervisord.conf @@ -61,7 +61,7 @@ stdout_logfile=syslog stderr_logfile=syslog [program:portsyncd] -command=/usr/bin/portsyncd -p /port_config.ini +command=/usr/bin/portsyncd priority=6 autostart=false autorestart=false diff --git a/platform/vs/docker-sonic-vs/supervisord.conf b/platform/vs/docker-sonic-vs/supervisord.conf index 2010dc918e0a..65812d81fc93 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -44,7 +44,7 @@ stdout_logfile=syslog stderr_logfile=syslog [program:portsyncd] -command=/usr/bin/portsyncd -p /usr/share/sonic/hwsku/port_config.ini +command=/usr/bin/portsyncd priority=6 autostart=false autorestart=false diff --git a/src/sonic-swss b/src/sonic-swss index 731a8f57119d..2a1ffe8135c6 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 731a8f57119d79e6d7ba6196f026a9e24664e074 +Subproject commit 2a1ffe8135c618d40dce9e4462a0a5ff604751d8 From dc6625c63f677dbfcba3c44271cbd0d7dd63db22 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Mon, 28 Oct 2019 18:26:22 -0700 Subject: [PATCH 0102/1427] [submodule] update sonic-swss (#3675) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 2a1ffe8135c6..09171575324e 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 2a1ffe8135c618d40dce9e4462a0a5ff604751d8 +Subproject commit 09171575324ea56f42f18e5203f501f9ccb92309 From 5961e031e11880c2a8ff34ec6c5ec0940e66a8e9 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Tue, 29 Oct 2019 08:30:27 -0700 Subject: [PATCH 0103/1427] [hostname-config] improve hostname-config process (#3676) We noticed in tests/production that there is a low probability failure where /etc/hosts could have some garbage characters before the entry for local host name. The consequence is that all sudo command would be very slow. In extreme cases it would prevent some services from starting properly. I suspect that the /etc/hosts file might be opened by some process causing the issue. Editing contents with new file level and replace the whole file should be safer. Signed-off-by: Ying Xie --- files/image_config/hostname/hostname-config.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/files/image_config/hostname/hostname-config.sh b/files/image_config/hostname/hostname-config.sh index 6cb8f73cf4af..e9f7fc122709 100755 --- a/files/image_config/hostname/hostname-config.sh +++ b/files/image_config/hostname/hostname-config.sh @@ -8,9 +8,15 @@ hostname -F /etc/hostname # Remove the old hostname entry from hosts file. # But, 'localhost' entry is used by multiple applications. Don't remove it altogether. +# Edit contents of /etc/hosts and put in /etc/hosts.new if [ $CURRENT_HOSTNAME != "localhost" ] || [ $CURRENT_HOSTNAME == $HOSTNAME ] ; then - sed -i "/\s$CURRENT_HOSTNAME$/d" /etc/hosts + sed "/\s$CURRENT_HOSTNAME$/d" /etc/hosts > /etc/hosts.new +else + cp -f /etc/hosts /etc/hosts.new fi -echo "127.0.0.1 $HOSTNAME" >> /etc/hosts +echo "127.0.0.1 $HOSTNAME" >> /etc/hosts.new +# Swap file: hosts.new and hosts +mv -f /etc/hosts /etc/hosts.old +mv -f /etc/hosts.new /etc/hosts From 3a7870955a94146fe04edbd26222ed3739217c19 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 29 Oct 2019 09:07:50 -0700 Subject: [PATCH 0104/1427] [bgpd]: Avoid crashing bgpcfgd when render of bgpd.peer.conf.j2 has issues (#3668) --- dockers/docker-fpm-frr/bgpcfgd | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 4ba8977fddfa..aad3c0c6d627 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -116,9 +116,14 @@ class BGPConfigManager(object): for key, op, data in self.bgp_messages: if op == swsscommon.SET_COMMAND: if key not in self.peers: - cmds.append(self.bgp_peer_add_template.render(DEVICE_METADATA=self.meta, neighbor_addr=key, bgp_session=data)) - syslog.syslog(syslog.LOG_INFO, 'Peer {} added with attributes {}'.format(key, data)) - self.peers.add(key) + try: + txt = self.bgp_peer_add_template.render(DEVICE_METADATA=self.meta, neighbor_addr=key, bgp_session=data) + cmds.append(txt) + except: + syslog.syslog(syslog.LOG_ERR, 'Peer {}. Error in rendering the template for "SET" command {}'.format(key, data)) + else: + syslog.syslog(syslog.LOG_INFO, 'Peer {} added with attributes {}'.format(key, data)) + self.peers.add(key) else: # when the peer is already configured we support "shutdown/no shutdown" # commands for the peers only From 0f88137b6d87418a7677360b8650ff988e608ebe Mon Sep 17 00:00:00 2001 From: "Sudharsan D.G" Date: Tue, 29 Oct 2019 16:15:43 -0500 Subject: [PATCH 0105/1427] Updating the sonic-swss submodule pointer (#3680) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 09171575324e..20747fa63d59 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 09171575324ea56f42f18e5203f501f9ccb92309 +Subproject commit 20747fa63d59f4aadaa06da282e23d8e1e0b9fdf From 1942e3363bcb841ab0db4f87cdee028e8fad30d4 Mon Sep 17 00:00:00 2001 From: "Sudharsan D.G" Date: Tue, 29 Oct 2019 20:05:55 -0500 Subject: [PATCH 0106/1427] Enable sflowmgrd in docker-sonic-vs (#3595) --- platform/vs/docker-sonic-vs/start.sh | 2 ++ platform/vs/docker-sonic-vs/supervisord.conf | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index d99047b7bb25..8770d304fcd8 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -67,6 +67,8 @@ supervisorctl start nbrmgrd supervisorctl start vxlanmgrd +supervisorctl start sflowmgrd + # Start arp_update when VLAN exists VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` if [ "$VLAN" != "" ]; then diff --git a/platform/vs/docker-sonic-vs/supervisord.conf b/platform/vs/docker-sonic-vs/supervisord.conf index 65812d81fc93..143fe49d44a9 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -180,3 +180,11 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog + +[program:sflowmgrd] +command=/usr/bin/sflowmgrd +priority=22 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog From 8db6df508bd7d856393d98547a8d17be171dbbd5 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 30 Oct 2019 16:33:58 +0200 Subject: [PATCH 0107/1427] [mellanox] Update FW/SDK: 13/29.2000.2308 and 4.3.2308 (#3666) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/fw.mk | 5 ++--- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 0ad1b05137ae..2df1fd11cd75 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,13 +11,12 @@ else FW_FROM_URL = n endif - -MLNX_SPC_FW_VERSION = 13.2000.2162 +MLNX_SPC_FW_VERSION = 13.2000.2308 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.2162 +MLNX_SPC2_FW_VERSION = 29.2000.2308 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 3acd88b3e04e..f4df2ccaa534 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 3acd88b3e04ec09e5fb7e2b74ed94540a9fea21e +Subproject commit f4df2ccaa5342e7f3fa5a45a851ef32ea59c0654 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 779e072e3613..dee478e7d52c 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.3.2104 +MLNX_SDK_VERSION = 4.3.2308 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From cff30c59d005416b2159b7c2d9197ce89876819b Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Wed, 30 Oct 2019 16:41:55 -0700 Subject: [PATCH 0108/1427] [Services] Restart Router-advertiser service upon unexpected critical process exit (#3681) Signed-off-by: Yong Zhao --- dockers/docker-router-advertiser/Dockerfile.j2 | 2 ++ dockers/docker-router-advertiser/critical_processes | 1 + .../docker-router-advertiser.supervisord.conf | 6 ++++++ files/build_templates/radv.service.j2 | 4 ++++ rules/docker-router-advertiser.mk | 1 + 5 files changed, 14 insertions(+) create mode 100644 dockers/docker-router-advertiser/critical_processes diff --git a/dockers/docker-router-advertiser/Dockerfile.j2 b/dockers/docker-router-advertiser/Dockerfile.j2 index 1594a59c5e8a..39e7b28effc1 100644 --- a/dockers/docker-router-advertiser/Dockerfile.j2 +++ b/dockers/docker-router-advertiser/Dockerfile.j2 @@ -27,5 +27,7 @@ RUN apt-get clean -y && \ COPY ["start.sh", "/usr/bin/"] COPY ["docker-router-advertiser.supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["radvd.conf.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-router-advertiser/critical_processes b/dockers/docker-router-advertiser/critical_processes new file mode 100644 index 000000000000..238a0346ac9f --- /dev/null +++ b/dockers/docker-router-advertiser/critical_processes @@ -0,0 +1 @@ +radvd diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf index f0bb4d5b3bbd..4ea84ab11c92 100644 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-script] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/files/build_templates/radv.service.j2 b/files/build_templates/radv.service.j2 index 3dadc56e46ab..54440241d5f6 100644 --- a/files/build_templates/radv.service.j2 +++ b/files/build_templates/radv.service.j2 @@ -3,12 +3,16 @@ Description=Router advertiser container Requires=updategraph.service After=updategraph.service swss.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{ docker_container_name }}.sh start ExecStart=/usr/bin/{{ docker_container_name }}.sh wait ExecStop=/usr/bin/{{ docker_container_name }}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk index 93dc0285585c..53e0d7600ec9 100644 --- a/rules/docker-router-advertiser.mk +++ b/rules/docker-router-advertiser.mk @@ -25,3 +25,4 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ROUTER_ADVERTISER_DBG) $(DOCKER_ROUTER_ADVERTISER)_CONTAINER_NAME = radv $(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += --net=host --privileged -t $(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_ROUTER_ADVERTISER)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From f3c92e7779a1b5db72656358db71409a07543ca2 Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Fri, 1 Nov 2019 00:13:35 +0800 Subject: [PATCH 0109/1427] [nephos] support SAI 1.5.0 and fix docker syncd related makefile error (#3684) - support SAI 1.5.0 - fix docker syncd related makefile error --- platform/nephos/docker-syncd-nephos-rpc.mk | 4 ++- platform/nephos/docker-syncd-nephos.mk | 7 ++++- .../nephos/docker-syncd-nephos/Dockerfile.j2 | 4 ++- platform/nephos/nephos-modules.mk | 16 ++++++++++ platform/nephos/rules.mk | 3 +- platform/nephos/sai.mk | 29 +++++++++++++++++-- 6 files changed, 56 insertions(+), 7 deletions(-) diff --git a/platform/nephos/docker-syncd-nephos-rpc.mk b/platform/nephos/docker-syncd-nephos-rpc.mk index 9ee1aeab090c..dafc43b3e7e3 100644 --- a/platform/nephos/docker-syncd-nephos-rpc.mk +++ b/platform/nephos/docker-syncd-nephos-rpc.mk @@ -10,8 +10,9 @@ $(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSAIREDIS_DBG) endif $(DOCKER_SYNCD_NEPHOS_RPC)_FILES += $(DSSERVE) $(NPX_DIAG) -$(DOCKER_SYNCD_NEPHOS_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_NEPHOS) +$(DOCKER_SYNCD_NEPHOS_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_NEPHOS_RPC) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_NEPHOS_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_NEPHOS_RPC) endif @@ -19,5 +20,6 @@ endif $(DOCKER_SYNCD_NEPHOS_RPC)_CONTAINER_NAME = syncd $(DOCKER_SYNCD_NEPHOS_RPC)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_NEPHOS_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_SYNCD_NEPHOS_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_NEPHOS_RPC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_NEPHOS_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/platform/nephos/docker-syncd-nephos.mk b/platform/nephos/docker-syncd-nephos.mk index 4acd688de865..6829c91c67aa 100644 --- a/platform/nephos/docker-syncd-nephos.mk +++ b/platform/nephos/docker-syncd-nephos.mk @@ -3,7 +3,8 @@ DOCKER_SYNCD_PLATFORM_CODE = nephos include $(PLATFORM_PATH)/../template/docker-syncd-base.mk -$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API) +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) +$(DOCKER_SYNCD_BASE)_FILES += $(DSSERVE) $(NPX_DIAG) $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ @@ -11,3 +12,7 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd + +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += npx_diag:/usr/bin/npx_diag + diff --git a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 index bb15fdd63bbb..b889200f6ca4 100755 --- a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 @@ -32,7 +32,9 @@ debs/{{ deb }}{{' '}} ##debs/{{ deb }}{{' '}} ##{%- endfor %} -COPY ["start.sh", "/usr/bin/"] +COPY ["files/dsserve", "files/npx_diag", "start.sh", "/usr/bin/"] +RUN chmod +x /usr/bin/npx_diag /usr/bin/dsserve + COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] ## Clean up diff --git a/platform/nephos/nephos-modules.mk b/platform/nephos/nephos-modules.mk index 565e975e0a08..b76141b40663 100644 --- a/platform/nephos/nephos-modules.mk +++ b/platform/nephos/nephos-modules.mk @@ -2,9 +2,25 @@ VERSION = 1.0.0 +ifneq ($(NEPHOS_SAI_DEB_LOCAL_URL), ) +SDK_FROM_LOCAL = y +else +SDK_FROM_LOCAL = n +endif + +SDK_VERSION = 3.0.0 +LINUX_VER = 4.9.0-9-2 +SDK_COMMIT_ID = 529202 + +ifeq ($(SAI_FROM_LOCAL), y) +NEPHOS_MODULE = nps-modules-$(LINUX_VER)_$(SDK_VERSION)_$(SDK_COMMIT_ID)_amd64.deb +$(NEPHOS_MODULE)_PATH = $(NEPHOS_SAI_DEB_LOCAL_URL) +SONIC_COPY_DEBS += $(NEPHOS_MODULE) +else NEPHOS_MODULE = nephos-modules_$(VERSION)_amd64.deb $(NEPHOS_MODULE)_SRC_PATH = $(PLATFORM_PATH)/nephos-modules $(NEPHOS_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_DPKG_DEBS += $(NEPHOS_MODULE) +endif SONIC_STRETCH_DEBS += $(NEPHOS_MODULE) diff --git a/platform/nephos/rules.mk b/platform/nephos/rules.mk index 797e2def91ce..5c115eeaf8d0 100644 --- a/platform/nephos/rules.mk +++ b/platform/nephos/rules.mk @@ -14,8 +14,9 @@ $(NPX_DIAG)_URL = "https://github.com/NephosInc/SONiC/raw/master/sdk/npx_diag" WARM_VERIFIER = warm-verifier $(WARM_VERIFIER)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/warm-verifier" + DSSERVE = dsserve -$(DSSERVE)_URL = "https://sonicstorage.blob.core.windows.net/packages/20170518/dsserve?sv=2015-04-05&sr=b&sig=gyNbgSL%2FvpMXDdpboVkIJcTKMRdGgEaOR9OukHhEsu8%3D&se=2030-03-31T23%3A06%3A35Z&sp=r" +$(DSSERVE)_URL = "https://sonicstorage.blob.core.windows.net/packages/20190307/dsserve?sv=2015-04-05&sr=b&sig=lk7BH3DtW%2F5ehc0Rkqfga%2BUCABI0UzQmDamBsZH9K6w%3D&se=2038-05-06T22%3A34%3A45Z&sp=r" SONIC_ONLINE_FILES += $(NPX_DIAG) $(WARM_VERIFIER) $(DSSERVE) diff --git a/platform/nephos/sai.mk b/platform/nephos/sai.mk index 93265dc74c56..edaa245cf5ad 100644 --- a/platform/nephos/sai.mk +++ b/platform/nephos/sai.mk @@ -1,12 +1,35 @@ -SDK_VERSION = 2.0.8 -SAI_VERSION = 1.4.1 -SAI_COMMIT_ID = cbb99f +SDK_VERSION = 3.0.0 +SAI_VERSION = 1.5.0 +SAI_COMMIT_ID = 426624 + +# Place here URL where SAI deb exist +NEPHOS_SAI_DEB_LOCAL_URL = +export NEPHOS_SAI_DEB_LOCAL_URL +# +ifneq ($(NEPHOS_SAI_DEB_LOCAL_URL), ) +SAI_FROM_LOCAL = y +else +SAI_FROM_LOCAL = n +endif + NEPHOS_SAI = libsainps_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb +ifeq ($(SAI_FROM_LOCAL), y) +$(NEPHOS_SAI)_PATH = $(NEPHOS_SAI_DEB_LOCAL_URL) +else $(NEPHOS_SAI)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb" +endif NEPHOS_SAI_DEV = libsainps-dev_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb $(eval $(call add_derived_package,$(NEPHOS_SAI),$(NEPHOS_SAI_DEV))) +ifeq ($(SAI_FROM_LOCAL), y) +$(NEPHOS_SAI_DEV)_PATH = $(NEPHOS_SAI_DEB_LOCAL_URL) +else $(NEPHOS_SAI_DEV)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps-dev_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb" +endif +ifeq ($(SAI_FROM_LOCAL), y) +SONIC_COPY_DEBS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) +else SONIC_ONLINE_DEBS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) +endif $(NEPHOS_SAI_DEV)_DEPENDS += $(NEPHOS_SAI) From 841949f0994c4a845919e256bbb2989fb3219ff5 Mon Sep 17 00:00:00 2001 From: padmanarayana Date: Thu, 31 Oct 2019 09:15:30 -0700 Subject: [PATCH 0110/1427] [hsflowd]: Update hsflowd to 2.0.25-4 to take care of admin_state changes (#3683) --- rules/sflow.mk | 4 ++-- src/sflow/hsflowd/Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rules/sflow.mk b/rules/sflow.mk index b03e08446370..4366e3479734 100644 --- a/rules/sflow.mk +++ b/rules/sflow.mk @@ -1,7 +1,7 @@ # host-sflow package -HSFLOWD_VERSION = 2.0.21 -HSFLOWD_SUBVERSION = 8 +HSFLOWD_VERSION = 2.0.25 +HSFLOWD_SUBVERSION = 4 export HSFLOWD_VERSION HSFLOWD_SUBVERSION HSFLOWD = hsflowd_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb diff --git a/src/sflow/hsflowd/Makefile b/src/sflow/hsflowd/Makefile index 526e30e0490c..f0ff92a7af62 100644 --- a/src/sflow/hsflowd/Makefile +++ b/src/sflow/hsflowd/Makefile @@ -10,7 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git clone https://github.com/sflow/host-sflow pushd ./host-sflow - git checkout -b sflow -f 996f5ec + git checkout -b sflow tags/v2.0.25-4 # Apply patch series stg init From 064689d44221452f434d0c7ea5e2ee752999fe83 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Thu, 31 Oct 2019 18:17:29 +0200 Subject: [PATCH 0111/1427] [sonic-cfggen] optimize sonic-cfggen startup (#3658) * [sonic-cfggen] optimize execution time a lot of template rendering causes switch to start longer because jinja2 needs to parse them. Introducing RedisBytecodeCache to store parsed buckets of internal template bytecode to speedup same template rendering during start * [sonic-cfggen] do lazy regexp compilation to speedup sonic-cfggen * [sonic-cfggen] address pep8 related comments Signed-off-by: Stepan Blyschak --- src/sonic-config-engine/lazy_re.py | 22 ++++++++++++++++++++++ src/sonic-config-engine/redis_bcc.py | 26 ++++++++++++++++++++++++++ src/sonic-config-engine/setup.py | 2 +- src/sonic-config-engine/sonic-cfggen | 16 ++++++++++++++-- 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 src/sonic-config-engine/lazy_re.py create mode 100644 src/sonic-config-engine/redis_bcc.py diff --git a/src/sonic-config-engine/lazy_re.py b/src/sonic-config-engine/lazy_re.py new file mode 100644 index 000000000000..b51c385c1cc6 --- /dev/null +++ b/src/sonic-config-engine/lazy_re.py @@ -0,0 +1,22 @@ +# monkey patch re.compile to improve import time of some packages + +import re + +_orig_re_compile = re.compile + + +def __re_compile(*args, **kwargs): + class __LazyReCompile(object): + def __init__(self, *args, **kwargs): + self.args = args + self.kwargs = kwargs + self.pattern_obj = None + + def __getattr__(self, name): + if self.pattern_obj is None: + self.pattern_obj = _orig_re_compile(*self.args, **self.kwargs) + return getattr(self.pattern_obj, name) + return __LazyReCompile(*args, **kwargs) + +re.compile = __re_compile + diff --git a/src/sonic-config-engine/redis_bcc.py b/src/sonic-config-engine/redis_bcc.py new file mode 100644 index 000000000000..5ab59b6a6959 --- /dev/null +++ b/src/sonic-config-engine/redis_bcc.py @@ -0,0 +1,26 @@ +import jinja2 + +class RedisBytecodeCache(jinja2.BytecodeCache): + """ A bytecode cache for jinja2 template that stores bytecode in Redis """ + + REDIS_HASH = 'JINJA2_CACHE' + + def __init__(self, client): + self._client = client + try: + self._client.connect(self._client.STATE_DB, retry_on=False) + except Exception: + self._client = None + + def load_bytecode(self, bucket): + if self._client is None: + return + code = self._client.get(self._client.STATE_DB, self.REDIS_HASH, bucket.key) + if code is not None: + bucket.bytecode_from_string(code) + + def dump_bytecode(self, bucket): + if self._client is None: + return + self._client.set(self._client.STATE_DB, self.REDIS_HASH, bucket.key, bucket.bytecode_to_string()) + diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py index 7ca810ce6a54..c75a5b5a03a6 100755 --- a/src/sonic-config-engine/setup.py +++ b/src/sonic-config-engine/setup.py @@ -16,7 +16,7 @@ def get_test_suite(): author='Taoyu Li', author_email='taoyl@microsoft.com', url='https://github.com/Azure/sonic-buildimage', - py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_device_util', 'config_samples'], + py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_device_util', 'config_samples', 'redis_bcc', 'lazy_re'], scripts=['sonic-cfggen'], install_requires=['lxml', 'jinja2>=2.10', 'netaddr', 'ipaddr', 'pyyaml', 'pyangbind==0.6.0'], test_suite='setup.get_test_suite', diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index ca550b49e4bc..7cff6c9fb384 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -16,6 +16,16 @@ See usage string for detail description for arguments. """ from __future__ import print_function + +# monkey patch re.compile to do lazy regular expression compilation. +# This is done to improve import time of jinja2, yaml, natsort modules, because they +# do many regexp compilation at import time, so it will speed up sonic-cfggen invocations +# that do not require template generation or yaml loading. sonic-cfggen is used in so many places +# during system boot up that importing jinja2, yaml, natsort every time +# without lazy regular expression compilation affect boot up time. +# FIXME: remove this once sonic-cfggen and templates dependencies are replaced with a faster approach +import lazy_re + import sys import os.path import argparse @@ -33,7 +43,8 @@ from sonic_device_util import get_platform_info from sonic_device_util import get_system_mac from config_samples import generate_sample_config from config_samples import get_available_config -from swsssdk import ConfigDBConnector +from swsssdk import SonicV2Connector, ConfigDBConnector +from redis_bcc import RedisBytecodeCache from collections import OrderedDict from natsort import natsorted @@ -267,7 +278,8 @@ def main(): paths = ['/', '/usr/share/sonic/templates', os.path.dirname(template_file)] loader = jinja2.FileSystemLoader(paths) - env = jinja2.Environment(loader=loader, trim_blocks=True) + redis_bcc = RedisBytecodeCache(SonicV2Connector(host='127.0.0.1')) + env = jinja2.Environment(loader=loader, trim_blocks=True, bytecode_cache=redis_bcc) env.filters['sort_by_port_index'] = sort_by_port_index env.filters['ipv4'] = is_ipv4 env.filters['ipv6'] = is_ipv6 From 8dbe13c4cccb548903684b13c72847c0e094fd0b Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Thu, 31 Oct 2019 18:18:26 +0200 Subject: [PATCH 0112/1427] [services] improve startup time by changing startup order (#3656) * [services] improve startup time by given precedence to critical services (syncd.service) Signed-off-by: Stepan Blyschak --- files/build_templates/dhcp_relay.service.j2 | 2 +- files/build_templates/lldp.service.j2 | 2 +- files/build_templates/radv.service.j2 | 2 +- files/build_templates/sflow.service.j2 | 2 +- files/build_templates/snmp.service.j2 | 2 +- files/build_templates/telemetry.service.j2 | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/files/build_templates/dhcp_relay.service.j2 b/files/build_templates/dhcp_relay.service.j2 index 7ec133c87af7..f48217d55567 100644 --- a/files/build_templates/dhcp_relay.service.j2 +++ b/files/build_templates/dhcp_relay.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=DHCP relay container Requires=updategraph.service swss.service teamd.service -After=updategraph.service swss.service teamd.service +After=updategraph.service swss.service syncd.service teamd.service Before=ntp-config.service [Service] diff --git a/files/build_templates/lldp.service.j2 b/files/build_templates/lldp.service.j2 index c317e18efc5c..6f8fc902befc 100644 --- a/files/build_templates/lldp.service.j2 +++ b/files/build_templates/lldp.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=LLDP container Requires=updategraph.service -After=updategraph.service +After=updategraph.service swss.service syncd.service Before=ntp-config.service [Service] diff --git a/files/build_templates/radv.service.j2 b/files/build_templates/radv.service.j2 index 54440241d5f6..b3dd3a8d8bcb 100644 --- a/files/build_templates/radv.service.j2 +++ b/files/build_templates/radv.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=Router advertiser container Requires=updategraph.service -After=updategraph.service swss.service +After=updategraph.service swss.service syncd.service Before=ntp-config.service StartLimitIntervalSec=1200 StartLimitBurst=3 diff --git a/files/build_templates/sflow.service.j2 b/files/build_templates/sflow.service.j2 index d77979bb338d..3a5752412b98 100644 --- a/files/build_templates/sflow.service.j2 +++ b/files/build_templates/sflow.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=sFlow container Requires=swss.service -After=swss.service +After=swss.service syncd.service Before=ntp-config.service [Service] diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index a05c5fbe1d09..310048e68beb 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -2,7 +2,7 @@ Description=SNMP container Requires=updategraph.service Requisite=swss.service -After=updategraph.service swss.service +After=updategraph.service swss.service syncd.service Before=ntp-config.service StartLimitIntervalSec=1200 StartLimitBurst=3 diff --git a/files/build_templates/telemetry.service.j2 b/files/build_templates/telemetry.service.j2 index 8781ce7afb47..2e7e45218df2 100644 --- a/files/build_templates/telemetry.service.j2 +++ b/files/build_templates/telemetry.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=Telemetry container Requires=database.service -After=database.service +After=database.service swss.service syncd.service Before=ntp-config.service [Service] From 6cc1f999759cdddc5af03922834bace17a37f732 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 31 Oct 2019 18:22:58 -0700 Subject: [PATCH 0113/1427] Return evpn configuration into bgp templates (#3693) --- dockers/docker-fpm-frr/bgpd.peer.conf.j2 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 index 7dfdd50ea2c0..c3dc50449d35 100644 --- a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 +++ b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 @@ -24,6 +24,14 @@ {% endif %} {% if bgp_session['nhopself'] | int != 0 %} neighbor {{ neighbor_addr }} next-hop-self +{% endif %} +{% if bgp_session["asn"] == DEVICE_METADATA['localhost']['bgp_asn'] + and DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" + and (not bgp_session.has_key("local_addr") or bgp_session["local_addr"] not in interfaces_in_vnets) %} + address-family l2vpn evpn + neighbor {{ neighbor_addr }} activate + advertise-all-vni + exit-address-family {% endif %} neighbor {{ neighbor_addr }} activate exit-address-family From 815e2ef6f47284bff872ca369a229fd8a0d90086 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 1 Nov 2019 07:36:19 -0700 Subject: [PATCH 0114/1427] [minigraph.py]: Use default namespace for

(#3695) * [minigraph.py]: Use default namespace for
--- src/sonic-config-engine/minigraph.py | 4 ++-- src/sonic-config-engine/tests/test_cfggen.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 33736383506b..7799f3367d95 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -386,8 +386,8 @@ def parse_cpg(cpg, hname): 'name': name, 'ip_range': ip_range_group } - if bgpPeer.find(str(QName(ns1, "Address"))) is not None: - bgp_peers_with_range[name]['src_address'] = bgpPeer.find(str(QName(ns1, "Address"))).text + if bgpPeer.find(str(QName(ns, "Address"))) is not None: + bgp_peers_with_range[name]['src_address'] = bgpPeer.find(str(QName(ns, "Address"))).text if bgpPeer.find(str(QName(ns1, "PeerAsn"))) is not None: bgp_peers_with_range[name]['peer_asn'] = bgpPeer.find(str(QName(ns1, "PeerAsn"))).text else: diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 6c9574af3514..8288b729584c 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -194,7 +194,7 @@ def test_minigraph_bgp(self): def test_minigraph_peers_with_range(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v BGP_PEER_RANGE.values\(\)' output = self.run_script(argument) - self.assertEqual(output.strip(), "[{'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]") + self.assertEqual(output.strip(), "[{'src_address': '10.1.0.32', 'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]") def test_minigraph_deployment_id(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'deployment_id\']"' From 4b59a430f1a277378d265f58cbb1dea5457d0fe2 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Mon, 4 Nov 2019 09:30:18 -0800 Subject: [PATCH 0115/1427] [docker-fpm-frr]: Add DEVICE_NEIGHBOR_METADATA into bgpcfgd (#3694) --- dockers/docker-fpm-frr/bgpcfgd | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index aad3c0c6d627..b98a3f7ad45a 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -80,6 +80,7 @@ class BGPConfigManager(object): def __init__(self, daemon): self.bgp_asn = None self.meta = None + self.neig_meta = {} self.bgp_messages = [] self.peers = self.load_peers() # we can have bgp monitors peers here. it could be fixed by adding support for it here fabric = TemplateFabric() @@ -88,6 +89,7 @@ class BGPConfigManager(object): self.bgp_peer_shutdown = fabric.from_string('neighbor {{ neighbor_addr }} shutdown') self.bgp_peer_no_shutdown = fabric.from_string('no neighbor {{ neighbor_addr }} shutdown') daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, self.__metadata_handler) + daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME, self.__neighbor_metadata_handler) daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, self.__bgp_handler) def load_peers(self): @@ -111,13 +113,30 @@ class BGPConfigManager(object): self.bgp_asn = data["bgp_asn"] self.__update_bgp() + def __neighbor_metadata_handler(self, key, op, data): + if op == swsscommon.SET_COMMAND: + self.neig_meta[key] = data + elif op == swsscommon.DEL_COMMAND: + if key in self.neig_meta: + del self.neig_meta[key] + else: + syslog.syslog(syslog.LOG_ERR,"Can't remove key '%s' from neighbor metadata handler. The key doesn't exist" % key) + else: + syslog.syslog(syslog.LOG_ERR,"Wrong operation '%s' for neighbor metadata handler" % op) + self.__update_bgp() + def __update_bgp(self): cmds = [] + new_bgp_messages = [] for key, op, data in self.bgp_messages: if op == swsscommon.SET_COMMAND: if key not in self.peers: + if 'name' in data and data['name'] not in self.neig_meta: + # DEVICE_NEIGHBOR_METADATA should be populated before the rendering + new_bgp_messages.append((key, op, data)) + continue try: - txt = self.bgp_peer_add_template.render(DEVICE_METADATA=self.meta, neighbor_addr=key, bgp_session=data) + txt = self.bgp_peer_add_template.render(DEVICE_METADATA=self.meta, DEVICE_NEIGHBOR_METADATA=self.neig_meta, neighbor_addr=key, bgp_session=data) cmds.append(txt) except: syslog.syslog(syslog.LOG_ERR, 'Peer {}. Error in rendering the template for "SET" command {}'.format(key, data)) @@ -145,7 +164,7 @@ class BGPConfigManager(object): self.peers.remove(key) else: syslog.syslog(syslog.LOG_WARNING, 'Peer {} is not found'.format(key)) - self.bgp_messages = [] + self.bgp_messages = new_bgp_messages if len(cmds) == 0: return From d85777bb1135290721e297a37cafef362dc75d92 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Mon, 4 Nov 2019 09:36:15 -0800 Subject: [PATCH 0116/1427] [frr]: Fix the issue 'branch already exist' in frr package rebuilds (#3692) Fixed Makefile of FRR. Before we had issues after #3589: - When you want to rebuild frr with new changes you get error "branch frr/7.1 is already exist". - When your patch list is empty stg undo gives an error --- src/sonic-frr/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index 233696de804a..abd9adc3fc67 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -4,8 +4,9 @@ SHELL = /bin/bash MAIN_TARGET = $(FRR) DERIVED_TARGET = $(FRR_PYTHONTOOLS) $(FRR_DBG) $(FRR_SNMP) $(FRR_SNMP_DBG) +SUFFIX = $(shell date +%Y%m%d\.%H%M%S) FRR_BRANCH = frr/$(FRR_VERSION) -STG_BRANCH = stg_temp +STG_BRANCH = stg_temp.$(SUFFIX) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Build the package @@ -15,11 +16,12 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : stg import -s ../patch/series tools/tarsource.sh -V -e '-sonic' dpkg-buildpackage -rfakeroot -b -us -uc -Ppkg.frr.nortrlib -j$(SONIC_CONFIG_MAKE_JOBS) - stg undo + stg undo || true git clean -xfdf git checkout $(FRR_BRANCH) stg branch --delete $(STG_BRANCH) git rev-parse --short HEAD | xargs git checkout + git checkout master git branch -D $(FRR_BRANCH) popd mv $(DERIVED_TARGET) $* $(DEST)/ From 4fa3a1e27ec55829197cebe634864be7b1768d7d Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Mon, 4 Nov 2019 17:44:01 -0800 Subject: [PATCH 0117/1427] [Services] Restart Platform-monitor service upon unexpected critical process exit. (#3689) Signed-off-by: Yong Zhao --- dockers/docker-platform-monitor/Dockerfile.j2 | 2 ++ dockers/docker-platform-monitor/critical_processes | 5 +++++ .../docker-platform-monitor/docker-pmon.supervisord.conf.j2 | 6 ++++++ files/build_templates/pmon.service.j2 | 4 ++++ rules/docker-platform-monitor.mk | 1 + 5 files changed, 18 insertions(+) create mode 100644 dockers/docker-platform-monitor/critical_processes diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index c2e142727b80..fd11f628559c 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -57,5 +57,7 @@ RUN apt-get purge -y \ COPY ["docker_init.sh", "lm-sensors.sh", "/usr/bin/"] COPY ["docker-pmon.supervisord.conf.j2", "start.sh.j2", "/usr/share/sonic/templates/"] COPY ["ssd_tools/*", "/usr/bin/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/dockers/docker-platform-monitor/critical_processes b/dockers/docker-platform-monitor/critical_processes new file mode 100644 index 000000000000..4233cda34982 --- /dev/null +++ b/dockers/docker-platform-monitor/critical_processes @@ -0,0 +1,5 @@ +fancontrol +ledd +xcvrd +psud +syseepromd diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index c6a571da9335..9a2414c30d05 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/files/build_templates/pmon.service.j2 b/files/build_templates/pmon.service.j2 index 9c4226256818..11dea5d12783 100644 --- a/files/build_templates/pmon.service.j2 +++ b/files/build_templates/pmon.service.j2 @@ -6,12 +6,16 @@ After=updategraph.service After=syncd.service {% endif %} Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index 5eb26fec2f82..7a319e4bf120 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -44,3 +44,4 @@ $(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/bin/sensors $(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/sbin/smartctl $(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/sbin/iSmart $(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/sbin/SmartCmd +$(DOCKER_PLATFORM_MONITOR)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From 4c31ef3cd217bc71071eba3b244829a1e72d1234 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Mon, 4 Nov 2019 17:45:41 -0800 Subject: [PATCH 0118/1427] [Services] Restart Teamd service upon unexpected critical process exit. (#3703) Signed-off-by: Yong Zhao --- dockers/docker-teamd/Dockerfile.j2 | 2 ++ dockers/docker-teamd/critical_processes | 2 ++ dockers/docker-teamd/supervisord.conf | 8 +++++++- files/build_templates/teamd.service.j2 | 4 ++++ rules/docker-teamd.mk | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 dockers/docker-teamd/critical_processes diff --git a/dockers/docker-teamd/Dockerfile.j2 b/dockers/docker-teamd/Dockerfile.j2 index 9188b7aaf735..fc8626e77229 100644 --- a/dockers/docker-teamd/Dockerfile.j2 +++ b/dockers/docker-teamd/Dockerfile.j2 @@ -36,5 +36,7 @@ RUN apt-get clean -y && \ COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-teamd/critical_processes b/dockers/docker-teamd/critical_processes new file mode 100644 index 000000000000..b5c543df050d --- /dev/null +++ b/dockers/docker-teamd/critical_processes @@ -0,0 +1,2 @@ +teammgrd +teamsyncd diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index 738751d0a59f..3a420e0fcdcf 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/files/build_templates/teamd.service.j2 b/files/build_templates/teamd.service.j2 index 8034698ecc07..be0521a4fbec 100644 --- a/files/build_templates/teamd.service.j2 +++ b/files/build_templates/teamd.service.j2 @@ -3,12 +3,16 @@ Description=TEAMD container Requires=updategraph.service After=updategraph.service swss.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk index a697ce6b8891..598eff97e8f1 100644 --- a/rules/docker-teamd.mk +++ b/rules/docker-teamd.mk @@ -29,3 +29,4 @@ $(DOCKER_TEAMD)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TEAMD)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_TEAMD)_BASE_IMAGE_FILES += teamdctl:/usr/bin/teamdctl +$(DOCKER_TEAMD)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From d6f3fde8849cb4e8145c83ac27d8a18c82c9e9ff Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Tue, 5 Nov 2019 11:40:20 +0530 Subject: [PATCH 0119/1427] [devices]: support SFP+ for Z9264F (#3700) - Changed sff8436 to optoe driver for both QSFP and SFP+ - Used optoe1 for QSFP and optoe2 for SFP. --- .../plugins/sfputil.py | 322 +++++++++++++++++- .../z9264f/scripts/z9264f_platform.sh | 28 +- 2 files changed, 346 insertions(+), 4 deletions(-) diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py index 24938a122c0e..df841bf88355 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py @@ -4,6 +4,7 @@ # try: + import io import struct import sys import getopt @@ -12,16 +13,46 @@ from sonic_sfp.sfputilbase import SfpUtilBase from os import * from mmap import * + from sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_sfp.sff8436 import sff8436Dom + from sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_sfp.sff8472 import sff8472Dom except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +#definitions of the offset and width for values in DOM info eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_MON_MASK_OFFSET = 242 +QSFP_CHANNL_MON_MASK_WIDTH = 4 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 + +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" PORT_START = 1 - PORT_END = 64 + PORT_END = 66 PORTS_IN_BLOCK = 64 BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" @@ -115,6 +146,9 @@ def get_presence(self, port_num): # Mask off 4th bit for presence mask = (1 << 4) + # Mask off 1st bit for presence 65,66 + if (port_num > 64): + mask = (1 << 0) # ModPrsL is active low if reg_value & mask == 0: return True @@ -300,4 +334,288 @@ def get_transceiver_change_event(self, timeout=0): self.oir_fd = -1 self.epoll = -1 - return False, {} \ No newline at end of file + return False, {} + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power', + ] + transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + offset = 0 + offset_xcvr = 128 + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return None + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return None + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + else: + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return None + + transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + offset = 0 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return None + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), + SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return None + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), + SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + + def get_transceiver_dom_threshold_info_dict(self, port_num): + transceiver_dom_threshold_info_dict = {} + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 0 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return None + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + offset = 0 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return None + + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + #Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh index 7a7040cacb6c..3435704a65cb 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh @@ -58,7 +58,7 @@ switch_board_qsfp() { "new_device") for ((i=2;i<=65;i++)); do - echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 done ;; @@ -74,6 +74,29 @@ switch_board_qsfp() { esac } +#Attach/Detach 2 instances of EEPROM driver SFP+ ports +#eeprom can dump data using below command +switch_board_sfp() { + case $1 in + "new_device") + for ((i=66;i<=67;i++)); + do + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=66;i<=67;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "z9264f_platform: switch_board_sfp: invalid command !" + ;; + esac +} + #Modsel 64 ports to applicable QSFP type modules #This enables the adapter to respond for i2c commands switch_board_modsel() { @@ -114,6 +137,7 @@ if [ "$1" == "init" ]; then sys_eeprom "new_device" switch_board_qsfp_mux "new_device" switch_board_qsfp "new_device" + switch_board_sfp "new_device" switch_board_modsel init_switch_port_led python /usr/bin/qsfp_irq_enable.py @@ -122,7 +146,7 @@ elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" switch_board_qsfp "delete_device" switch_board_qsfp_mux "delete_device" - + switch_board_sfp "delete_device" modprobe -r i2c-mux-pca954x modprobe -r i2c-dev else From ebcd2d5252996bbc23ed6fa61945e0f284c3e69f Mon Sep 17 00:00:00 2001 From: rkdevi27 <54701695+rkdevi27@users.noreply.github.com> Date: Wed, 6 Nov 2019 00:56:34 +0530 Subject: [PATCH 0120/1427] [devices]: Fixed Fpga crash on dell z9264 (#3672) Fixed the fpga crash issue which we see in 15-20 mins time frame after onie-install. Accessing stale i2c transfer message buffer causes this crash. Te message buffer becomes stale due to race between i2c transfer and fpga interrupt handler. This new state STATE_STOP will not be exposed for the wake up call till all the ISR of previous transfer is completed successfully. --- .../z9264f/modules/dell_z9264f_fpga_ocores.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c index d3a4a51ead72..c1644ecf705d 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c @@ -205,6 +205,7 @@ enum { STATE_START, STATE_WRITE, STATE_READ, + STATE_STOP, STATE_ERROR, }; @@ -591,10 +592,13 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) PRINT("fpgai2c_process in. status reg :0x%x\n", stat); - if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { + if ((i2c->state == STATE_STOP) || (i2c->state == STATE_ERROR)) { /* stop has been sent */ PRINT("fpgai2c_process FPGAI2C_REG_CMD_IACK stat = 0x%x Set FPGAI2C_REG_CMD(0%x) FPGAI2C_REG_CMD_IACK = 0x%x\n",stat, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if(i2c->state == STATE_STOP) { + i2c->state = STATE_DONE; + } wake_up(&i2c->wait); return; } @@ -648,7 +652,7 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) ? STATE_READ : STATE_WRITE; } } else { - i2c->state = STATE_DONE; + i2c->state = STATE_STOP; fpgai2c_stop(i2c); return; } @@ -722,6 +726,7 @@ static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) } else { + ret = -ETIMEDOUT; PRINT("Set FPGAI2C_REG_DATA(0%x) val = 0x%x\n",FPGAI2C_REG_DATA, (i2c->msg->addr << 1) | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); @@ -733,9 +738,8 @@ static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) /* Interrupt mode */ if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || (i2c->state == STATE_DONE), HZ)) - return (i2c->state == STATE_DONE) ? num : -EIO; - else - return -ETIMEDOUT; + ret = (i2c->state == STATE_DONE) ? num : -EIO; + return ret; } } From a4c35b72d8d3ac5ba9cb6375ab2ecf6b54fb400b Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Wed, 6 Nov 2019 01:25:58 +0530 Subject: [PATCH 0121/1427] [Juniper][QFX5210] Updating preemphasis values for supported optics (#3686) * Preemphasis values for various optics This patch adds the preemphasis values for the various supported optics for qfx5210 platform Signed-off-by: Ciju Rajan K --- .../media_settings.json | 19033 +++++++++++++++- .../qfx5210/utils/README | 34 +- 2 files changed, 18060 insertions(+), 1007 deletions(-) diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json b/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json index d2b28c0aea8b..22788f3a6f23 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json +++ b/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json @@ -31,12 +31,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-1F3-1F3QAA": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0x103f02", - "lane2":"0xd3a02", - "lane3":"0xd3a02" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -44,15 +44,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "1": { - "Default": { + }, + "JUNIPER-INNO-TF-FC030-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -61,7 +59,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC020-NJC": { "preemphasis": { "lane0":"0x1c4503", "lane1":"0x1c4503", @@ -75,12 +73,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TF-FC010-NJC": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0x113f02", - "lane2":"0xd3a02", - "lane3":"0xd3a02" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -88,15 +86,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "2": { - "Default": { + }, + "JUNIPER-INNO-TF-FC001-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -105,7 +101,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC003-NJC": { "preemphasis": { "lane0":"0x1c4503", "lane1":"0x1c4503", @@ -119,12 +115,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TR-FC13R-NJ3": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0xf3f02", - "lane2":"0xd3a02", - "lane3":"0xd3a02" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -132,15 +128,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "3": { - "Default": { + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -149,7 +143,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTLC9551REPM-J1": { "preemphasis": { "lane0":"0x1c4503", "lane1":"0x1c4503", @@ -163,12 +157,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0xf3f02", - "lane2":"0xd3a02", - "lane3":"0xd3a02" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -176,15 +170,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "4": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -193,12 +185,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { "preemphasis": { - "lane0":"0x1b4603", - "lane1":"0x1b4603", - "lane2":"0x1b4603", - "lane3":"0x1b4603" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -207,12 +199,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0xd3a02", - "lane2":"0xd3a02", - "lane3":"0xd3a02" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -220,15 +212,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "5": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -237,7 +227,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { "preemphasis": { "lane0":"0x1c4503", "lane1":"0x1c4503", @@ -251,10 +241,10 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "AVAGO-AFBR-79EQDZ-JU1": { "preemphasis": { "lane0":"0xd3a02", - "lane1":"0xd3a02", + "lane1":"0x103f02", "lane2":"0xd3a02", "lane3":"0xd3a02" }, @@ -264,15 +254,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "6": { - "Default": { + }, + "FINISAR CORP-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0xd3a02", + "lane1":"0x103f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -281,12 +269,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x174a03", - "lane1":"0x174a03", - "lane2":"0x174a03", - "lane3":"0x174a03" + "lane0":"0xd3a02", + "lane1":"0x103f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -298,7 +286,21 @@ "JUNIPER-INNO-TR-IQ13L-NJ3": { "preemphasis": { "lane0":"0xd3a02", - "lane1":"0xd3a02", + "lane1":"0x103f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x103f02", "lane2":"0xd3a02", "lane3":"0xd3a02" }, @@ -310,7 +312,7 @@ } } }, - "7": { + "1": { "Default": { "preemphasis": { "lane0":"0x14410a", @@ -327,10 +329,10 @@ }, "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { "preemphasis": { - "lane0":"0x194803", - "lane1":"0x1b4603", - "lane2":"0x174a03", - "lane3":"0x174a03" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -339,12 +341,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-1F3-1F3QAA": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0xd3a02", - "lane2":"0xd3a02", - "lane3":"0xd3a02" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -352,15 +354,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "8": { - "Default": { + }, + "JUNIPER-INNO-TF-FC030-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -369,7 +369,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC020-NJC": { "preemphasis": { "lane0":"0x1c4503", "lane1":"0x1c4503", @@ -383,12 +383,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TF-FC010-NJC": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0xd3a02", - "lane2":"0xd3a02", - "lane3":"0xd3a02" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -396,15 +396,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "9": { - "Default": { + }, + "JUNIPER-INNO-TF-FC001-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -413,12 +411,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC003-NJC": { "preemphasis": { "lane0":"0x1c4503", "lane1":"0x1c4503", "lane2":"0x1c4503", - "lane3":"0x1d4403" + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -427,12 +425,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TR-FC13R-NJ3": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0xf3f02", - "lane2":"0xd3a02", - "lane3":"0xf3a04" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -440,15 +438,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "10": { - "Default": { + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -457,12 +453,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTLC9551REPM-J1": { "preemphasis": { - "lane0":"0x1a4703", - "lane1":"0x1a4703", - "lane2":"0x1a4703", - "lane3":"0x1a4703" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -471,12 +467,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0xd3a02", - "lane2":"0xd3a02", - "lane3":"0xd3a02" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -484,15 +480,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "11": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -501,12 +495,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { "preemphasis": { - "lane0":"0x1b4603", - "lane1":"0x1b4603", - "lane2":"0x1a4703", - "lane3":"0x1b4603" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -515,12 +509,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0xd3a02", - "lane2":"0xd3a02", - "lane3":"0xd3a02" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -528,15 +522,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "12": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -545,12 +537,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { "preemphasis": { - "lane0":"0x154c03", - "lane1":"0x154c03", - "lane2":"0x154c03", - "lane3":"0x154c03" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -559,12 +551,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "AVAGO-AFBR-79EQDZ-JU1": { "preemphasis": { - "lane0":"0xa3402", - "lane1":"0xa3402", - "lane2":"0xa3402", - "lane3":"0xa3202" + "lane0":"0xd3a02", + "lane1":"0x113f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -572,15 +564,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "13": { - "Default": { + }, + "FINISAR CORP-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0xd3a02", + "lane1":"0x113f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -589,12 +579,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x154c03", - "lane1":"0x154c03", - "lane2":"0x154c03", - "lane3":"0x154c03" + "lane0":"0xd3a02", + "lane1":"0x113f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -605,10 +595,24 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ3": { "preemphasis": { - "lane0":"0xa3402", - "lane1":"0xb3402", - "lane2":"0xa3402", - "lane3":"0xa3202" + "lane0":"0xd3a02", + "lane1":"0x113f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x113f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -618,7 +622,7 @@ } } }, - "14": { + "2": { "Default": { "preemphasis": { "lane0":"0x14410a", @@ -635,10 +639,10 @@ }, "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { "preemphasis": { - "lane0":"0x154c03", - "lane1":"0x154c03", - "lane2":"0x154c03", - "lane3":"0x154c03" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -647,12 +651,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-1F3-1F3QAA": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0x93002" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -660,15 +664,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "15": { - "Default": { + }, + "JUNIPER-INNO-TF-FC030-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -677,12 +679,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC020-NJC": { "preemphasis": { - "lane0":"0x154c03", - "lane1":"0x154c03", - "lane2":"0x154c03", - "lane3":"0x154c03" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -691,12 +693,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TF-FC010-NJC": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0xa3002" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -704,15 +706,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "16": { - "Default": { + }, + "JUNIPER-INNO-TF-FC001-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -721,12 +721,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC003-NJC": { "preemphasis": { - "lane0":"0x154901", - "lane1":"0x124901", - "lane2":"0x124903", - "lane3":"0x144900" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -735,12 +735,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TR-FC13R-NJ3": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0x82d02" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -748,15 +748,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "17": { - "Default": { + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -765,12 +763,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTLC9551REPM-J1": { "preemphasis": { - "lane0":"0x154900", - "lane1":"0x124904", - "lane2":"0x124901", - "lane3":"0x144902" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -779,12 +777,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0xa3002" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -792,15 +790,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "18": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -809,12 +805,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { "preemphasis": { - "lane0":"0x154900", - "lane1":"0x124900", - "lane2":"0x124903", - "lane3":"0x144902" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -823,12 +819,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0xa3002" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -836,15 +832,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "19": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -853,12 +847,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { "preemphasis": { - "lane0":"0x154903", - "lane1":"0x124904", - "lane2":"0x124904", - "lane3":"0x144904" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -867,12 +861,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "AVAGO-AFBR-79EQDZ-JU1": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0xa3002" + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -880,15 +874,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "20": { - "Default": { + }, + "FINISAR CORP-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -897,12 +889,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x194803", - "lane1":"0x194803", - "lane2":"0x194803", - "lane3":"0x194803" + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -913,10 +905,24 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ3": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0xc3002" + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -926,7 +932,7 @@ } } }, - "21": { + "3": { "Default": { "preemphasis": { "lane0":"0x14410a", @@ -943,10 +949,10 @@ }, "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { "preemphasis": { - "lane0":"0x194803", - "lane1":"0x194803", - "lane2":"0x194803", - "lane3":"0x194803" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -955,12 +961,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-1F3-1F3QAA": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0xa3002" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -968,15 +974,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "22": { - "Default": { + }, + "JUNIPER-INNO-TF-FC030-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -985,7 +989,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC020-NJC": { "preemphasis": { "lane0":"0x1c4503", "lane1":"0x1c4503", @@ -999,12 +1003,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TF-FC010-NJC": { "preemphasis": { - "lane0":"0xd3402", - "lane1":"0xd3402", - "lane2":"0xd3402", - "lane3":"0xd3402" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1012,15 +1016,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "23": { - "Default": { + }, + "JUNIPER-INNO-TF-FC001-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1029,12 +1031,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC003-NJC": { "preemphasis": { - "lane0":"0x1e4303", - "lane1":"0x1e4303", - "lane2":"0x1d4403", - "lane3":"0x1e4303" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1043,12 +1045,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TR-FC13R-NJ3": { "preemphasis": { - "lane0":"0xe3602", - "lane1":"0xf3a03", - "lane2":"0xf3d03", - "lane3":"0xf3d03" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1056,15 +1058,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "24": { - "Default": { + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1073,12 +1073,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTLC9551REPM-J1": { "preemphasis": { - "lane0":"0x154906", - "lane1":"0x154904", - "lane2":"0x154903", - "lane3":"0x154903" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1087,12 +1087,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0xa3002" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1100,15 +1100,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "25": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1117,12 +1115,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { "preemphasis": { - "lane0":"0x174902", - "lane1":"0x174902", - "lane2":"0x174902", - "lane3":"0x174904" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1131,12 +1129,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0xa3002" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1144,15 +1142,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "26": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1161,12 +1157,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { "preemphasis": { - "lane0":"0x1a4703", - "lane1":"0x184903", - "lane2":"0x184903", - "lane3":"0x1a4703" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1175,12 +1171,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "AVAGO-AFBR-79EQDZ-JU1": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0xa3002" + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -1188,15 +1184,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "27": { - "Default": { + }, + "FINISAR CORP-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -1205,14 +1199,14 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x1a4703", - "lane1":"0x1a4703", - "lane2":"0x1a4703", - "lane3":"0x1a4703" - }, - "idriver": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { "lane0":"0x8", "lane1":"0x8", "lane2":"0x8", @@ -1221,10 +1215,24 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ3": { "preemphasis": { - "lane0":"0xb3203", - "lane1":"0xc3403", - "lane2":"0xc3403", - "lane3":"0xd3403" + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -1234,7 +1242,7 @@ } } }, - "28": { + "4": { "Default": { "preemphasis": { "lane0":"0x14410a", @@ -1251,10 +1259,10 @@ }, "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { "preemphasis": { - "lane0":"0x1a4505", - "lane1":"0x1a4505", - "lane2":"0x1a4505", - "lane3":"0x1a4505" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1263,12 +1271,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-1F3-1F3QAA": { "preemphasis": { - "lane0":"0xc3402", - "lane1":"0xd3402", - "lane2":"0xc3402", - "lane3":"0xc3402" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1276,15 +1284,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "29": { - "Default": { + }, + "JUNIPER-INNO-TF-FC030-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1293,7 +1299,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC020-NJC": { "preemphasis": { "lane0":"0x1b4603", "lane1":"0x1b4603", @@ -1307,12 +1313,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TF-FC010-NJC": { "preemphasis": { - "lane0":"0xc3402", - "lane1":"0xc3402", - "lane2":"0xc3402", - "lane3":"0xc3402" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1320,15 +1326,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "30": { - "Default": { + }, + "JUNIPER-INNO-TF-FC001-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1337,12 +1341,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC003-NJC": { "preemphasis": { - "lane0":"0x1a4604", - "lane1":"0x1a4604", - "lane2":"0x1a4604", - "lane3":"0x1a4604" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1351,12 +1355,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TR-FC13R-NJ3": { "preemphasis": { - "lane0":"0xc3402", - "lane1":"0xd3402", - "lane2":"0xc3402", - "lane3":"0xc3402" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1364,15 +1368,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "31": { - "Default": { + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1381,12 +1383,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTLC9551REPM-J1": { "preemphasis": { - "lane0":"0x1b4504", - "lane1":"0x1b4504", - "lane2":"0x1a4703", - "lane3":"0x1b4504" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1395,12 +1397,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { "preemphasis": { - "lane0":"0xd3602", - "lane1":"0xd3602", - "lane2":"0xd3602", - "lane3":"0xd3602" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1408,15 +1410,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "32": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1425,12 +1425,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { "preemphasis": { - "lane0":"0x1c4503", - "lane1":"0x1c4404", - "lane2":"0x1c4503", - "lane3":"0x1c4404" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1439,12 +1439,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { "preemphasis": { - "lane0":"0xf3a02", - "lane1":"0x113c03", - "lane2":"0xf3a03", - "lane3":"0xf3a03" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1452,15 +1452,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "33": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1469,12 +1467,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { "preemphasis": { - "lane0":"0x1c4503", - "lane1":"0x1c4503", - "lane2":"0x1c4503", - "lane3":"0x1c4503" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -1483,12 +1481,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "AVAGO-AFBR-79EQDZ-JU1": { "preemphasis": { - "lane0":"0xf3a03", - "lane1":"0xf3a03", - "lane2":"0xf3a03", - "lane3":"0xf3a03" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -1496,15 +1494,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "34": { - "Default": { + }, + "FINISAR CORP-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -1513,12 +1509,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x1a4703", - "lane1":"0x1a4604", - "lane2":"0x1a4703", - "lane3":"0x1a4703" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -1529,10 +1525,24 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ3": { "preemphasis": { - "lane0":"0xd3803", - "lane1":"0xe3803", - "lane2":"0xd3803", - "lane3":"0xc3403" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -1542,7 +1552,7 @@ } } }, - "35": { + "5": { "Default": { "preemphasis": { "lane0":"0x14410a", @@ -1560,9 +1570,9 @@ "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { "preemphasis": { "lane0":"0x1c4503", - "lane1":"0x1b4603", - "lane2":"0x1b4603", - "lane3":"0x1b4603" + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1571,12 +1581,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-1F3-1F3QAA": { "preemphasis": { - "lane0":"0xe3804", - "lane1":"0xe3803", - "lane2":"0xe3804", - "lane3":"0xe3804" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1584,15 +1594,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "36": { - "Default": { + }, + "JUNIPER-INNO-TF-FC030-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1601,12 +1609,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC020-NJC": { "preemphasis": { - "lane0":"0x1b4603", - "lane1":"0x1b4603", - "lane2":"0x1a4703", - "lane3":"0x1b4603" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1615,12 +1623,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TF-FC010-NJC": { "preemphasis": { - "lane0":"0xd3803", - "lane1":"0xd3803", - "lane2":"0xb3203", - "lane3":"0xc3403" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1628,15 +1636,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "37": { - "Default": { + }, + "JUNIPER-INNO-TF-FC001-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1645,12 +1651,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC003-NJC": { "preemphasis": { - "lane0":"0x194803", - "lane1":"0x194803", - "lane2":"0x194803", - "lane3":"0x194803" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1659,12 +1665,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TR-FC13R-NJ3": { "preemphasis": { - "lane0":"0xb3202", - "lane1":"0xb3202", - "lane2":"0xa3003", - "lane3":"0xb3003" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1672,15 +1678,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "38": { - "Default": { + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1689,12 +1693,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTLC9551REPM-J1": { "preemphasis": { - "lane0":"0x164903", - "lane1":"0x164903", - "lane2":"0x164903", - "lane3":"0x164903" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1703,12 +1707,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { "preemphasis": { - "lane0":"0xa3203", - "lane1":"0xa3203", - "lane2":"0xa3203", - "lane3":"0xa3203" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1716,15 +1720,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "39": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1733,12 +1735,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { "preemphasis": { - "lane0":"0x164901", - "lane1":"0x184901", - "lane2":"0x184901", - "lane3":"0x184901" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1747,12 +1749,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { "preemphasis": { - "lane0":"0xa3202", - "lane1":"0xa3202", - "lane2":"0xa3003", - "lane3":"0xa3003" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1760,15 +1762,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "40": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1777,12 +1777,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { "preemphasis": { "lane0":"0x1c4503", "lane1":"0x1c4503", "lane2":"0x1c4503", - "lane3":"0x1c4404" + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -1791,12 +1791,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "AVAGO-AFBR-79EQDZ-JU1": { "preemphasis": { - "lane0":"0xd3a03", - "lane1":"0xd3a03", - "lane2":"0xd3a03", - "lane3":"0xd3a03" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -1804,15 +1804,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "41": { - "Default": { + }, + "FINISAR CORP-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -1821,12 +1819,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x1b4603", - "lane1":"0x1a4703", - "lane2":"0x1b4603", - "lane3":"0x1c4503" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -1838,7 +1836,21 @@ "JUNIPER-INNO-TR-IQ13L-NJ3": { "preemphasis": { "lane0":"0xd3a02", - "lane1":"0xd3a03", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", "lane2":"0xd3a02", "lane3":"0xd3a02" }, @@ -1850,7 +1862,7 @@ } } }, - "42": { + "6": { "Default": { "preemphasis": { "lane0":"0x14410a", @@ -1867,10 +1879,10 @@ }, "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { "preemphasis": { - "lane0":"0x1a4703", - "lane1":"0x1a4703", - "lane2":"0x1a4703", - "lane3":"0x1a4703" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -1879,12 +1891,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-1F3-1F3QAA": { "preemphasis": { - "lane0":"0xd3a03", - "lane1":"0xd3a03", - "lane2":"0xb3a03", - "lane3":"0xa3803" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -1892,15 +1904,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "43": { - "Default": { + }, + "JUNIPER-INNO-TF-FC030-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -1909,12 +1919,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC020-NJC": { "preemphasis": { - "lane0":"0x1b4603", - "lane1":"0x1b4603", - "lane2":"0x1a4703", - "lane3":"0x1b4603" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -1923,12 +1933,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TF-FC010-NJC": { "preemphasis": { - "lane0":"0xd3a03", - "lane1":"0xd3a03", - "lane2":"0xd3a03", - "lane3":"0xd3a03" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -1936,15 +1946,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "44": { - "Default": { + }, + "JUNIPER-INNO-TF-FC001-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -1953,12 +1961,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC003-NJC": { "preemphasis": { - "lane0":"0x184902", - "lane1":"0x184902", - "lane2":"0x154902", - "lane3":"0x184902" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -1967,12 +1975,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TR-FC13R-NJ3": { "preemphasis": { - "lane0":"0x93003", - "lane1":"0x93003", - "lane2":"0x93003", - "lane3":"0x82f03" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -1980,15 +1988,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "45": { - "Default": { + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -1997,12 +2003,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTLC9551REPM-J1": { "preemphasis": { - "lane0":"0x154900", - "lane1":"0x154900", - "lane2":"0x154900", - "lane3":"0x154900" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2011,12 +2017,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { "preemphasis": { - "lane0":"0x72d03", - "lane1":"0x93003", - "lane2":"0x93003", - "lane3":"0x83003" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2024,15 +2030,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "46": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2041,12 +2045,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { "preemphasis": { - "lane0":"0x174900", - "lane1":"0x174900", - "lane2":"0x154900", - "lane3":"0x174904" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2055,12 +2059,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { "preemphasis": { - "lane0":"0x93003", - "lane1":"0x93003", - "lane2":"0x93003", - "lane3":"0x93003" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2068,15 +2072,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "47": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2085,12 +2087,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { "preemphasis": { - "lane0":"0x154903", - "lane1":"0x154903", - "lane2":"0x154903", - "lane3":"0x154903" + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2099,12 +2101,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "AVAGO-AFBR-79EQDZ-JU1": { "preemphasis": { - "lane0":"0x93003", - "lane1":"0x93003", - "lane2":"0x82e03", - "lane3":"0x83003" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -2112,15 +2114,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "48": { - "Default": { + }, + "FINISAR CORP-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -2129,12 +2129,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x184902", - "lane1":"0x164902", - "lane2":"0x164902", - "lane3":"0x144900" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -2145,10 +2145,24 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ3": { "preemphasis": { - "lane0":"0x93003", - "lane1":"0x93003", - "lane2":"0x93003", - "lane3":"0x93003" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -2158,7 +2172,7 @@ } } }, - "49": { + "7": { "Default": { "preemphasis": { "lane0":"0x14410a", @@ -2175,10 +2189,10 @@ }, "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { "preemphasis": { - "lane0":"0x174901", - "lane1":"0x144902", - "lane2":"0x144902", - "lane3":"0x144903" + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2187,12 +2201,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-1F3-1F3QAA": { "preemphasis": { - "lane0":"0x93003", - "lane1":"0x93003", - "lane2":"0x93003", - "lane3":"0x93003" + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2200,15 +2214,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "50": { - "Default": { + }, + "JUNIPER-INNO-TF-FC030-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2217,12 +2229,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC020-NJC": { "preemphasis": { - "lane0":"0x184901", - "lane1":"0x174901", - "lane2":"0x164903", - "lane3":"0x154904" + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2231,12 +2243,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TF-FC010-NJC": { "preemphasis": { - "lane0":"0x93003", - "lane1":"0x93003", - "lane2":"0x83003", - "lane3":"0x93003" + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2244,15 +2256,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "51": { - "Default": { + }, + "JUNIPER-INNO-TF-FC001-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2261,12 +2271,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC003-NJC": { "preemphasis": { - "lane0":"0x154903", - "lane1":"0x154903", - "lane2":"0x134903", - "lane3":"0x144904" + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2275,12 +2285,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TR-FC13R-NJ3": { "preemphasis": { - "lane0":"0x93003", - "lane1":"0x93002", - "lane2":"0x82f03", - "lane3":"0x82f03" + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2288,15 +2298,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "52": { - "Default": { + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2305,12 +2313,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTLC9551REPM-J1": { "preemphasis": { "lane0":"0x194803", - "lane1":"0x194803", - "lane2":"0x194803", - "lane3":"0x194803" + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2319,12 +2327,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0x103f02", - "lane2":"0xd3a02", - "lane3":"0xd3a02" + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2332,15 +2340,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "53": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" }, "idriver": { "lane0":"0x8", @@ -2349,12 +2355,96 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { "preemphasis": { "lane0":"0x194803", - "lane1":"0x194803", - "lane2":"0x184803", - "lane3":"0x194803" + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -2365,10 +2455,24 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ3": { "preemphasis": { - "lane0":"0xa3403", - "lane1":"0xa3403", - "lane2":"0xa3403", - "lane3":"0xa3403" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -2378,7 +2482,7 @@ } } }, - "54": { + "8": { "Default": { "preemphasis": { "lane0":"0x14410a", @@ -2396,9 +2500,9 @@ "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { "preemphasis": { "lane0":"0x1c4503", - "lane1":"0x1e4204", + "lane1":"0x1c4503", "lane2":"0x1c4503", - "lane3":"0x1d4304" + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -2407,12 +2511,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-1F3-1F3QAA": { "preemphasis": { - "lane0":"0xd3a02", - "lane1":"0xf3d02", - "lane2":"0xd3a03", - "lane3":"0xf3c03" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" }, "idriver": { "lane0":"0x8", @@ -2420,15 +2524,16935 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "55": { - "Default": { + }, + "JUNIPER-INNO-TF-FC030-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "9": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xf3a04" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xf3a04" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xf3a04" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xf3a04" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xf3a04" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "10": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "11": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "12": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xa3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xa3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xa3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xa3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xa3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "13": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xb3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xb3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xb3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xb3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xb3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "14": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x93002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x93002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x93002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x93002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x93002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "15": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "16": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x82d02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x82d02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x82d02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x82d02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x82d02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "17": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "19": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "20": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xc3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xc3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xc3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xc3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xc3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "21": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "22": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3402", + "lane1":"0xd3402", + "lane2":"0xd3403", + "lane3":"0xd3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3402", + "lane1":"0xd3402", + "lane2":"0xd3403", + "lane3":"0xd3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3402", + "lane1":"0xd3402", + "lane2":"0xd3403", + "lane3":"0xd3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3402", + "lane1":"0xd3402", + "lane2":"0xd3403", + "lane3":"0xd3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3402", + "lane1":"0xd3402", + "lane2":"0xd3403", + "lane3":"0xd3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "23": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xe3602", + "lane1":"0xf3a03", + "lane2":"0xf3d03", + "lane3":"0xf3d03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xe3602", + "lane1":"0xf3a03", + "lane2":"0xf3d03", + "lane3":"0xf3d03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xe3602", + "lane1":"0xf3a03", + "lane2":"0xf3d03", + "lane3":"0xf3d03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xe3602", + "lane1":"0xf3a03", + "lane2":"0xf3d03", + "lane3":"0xf3d03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xe3602", + "lane1":"0xf3a03", + "lane2":"0xf3d03", + "lane3":"0xf3d03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "24": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "25": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "26": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3203", + "lane1":"0xc3403", + "lane2":"0xc3403", + "lane3":"0xd3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3203", + "lane1":"0xc3403", + "lane2":"0xc3403", + "lane3":"0xd3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3203", + "lane1":"0xc3403", + "lane2":"0xc3403", + "lane3":"0xd3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3203", + "lane1":"0xc3403", + "lane2":"0xc3403", + "lane3":"0xd3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3203", + "lane1":"0xc3403", + "lane2":"0xc3403", + "lane3":"0xd3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "28": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "29": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xc3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xc3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xc3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xc3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xc3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "30": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "31": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3602", + "lane1":"0xd3602", + "lane2":"0xd3602", + "lane3":"0xd3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3602", + "lane1":"0xd3602", + "lane2":"0xd3602", + "lane3":"0xd3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3602", + "lane1":"0xd3602", + "lane2":"0xd3602", + "lane3":"0xd3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3602", + "lane1":"0xd3602", + "lane2":"0xd3602", + "lane3":"0xd3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3602", + "lane1":"0xd3602", + "lane2":"0xd3602", + "lane3":"0xd3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "32": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xf3a02", + "lane1":"0x113c03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xf3a02", + "lane1":"0x113c03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xf3a02", + "lane1":"0x113c03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xf3a02", + "lane1":"0x113c03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xf3a02", + "lane1":"0x113c03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "33": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xf3a03", + "lane1":"0xf3a03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xf3a03", + "lane1":"0xf3a03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xf3a03", + "lane1":"0xf3a03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xf3a03", + "lane1":"0xf3a03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xf3a03", + "lane1":"0xf3a03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "34": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xe3803", + "lane2":"0xd3803", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xe3803", + "lane2":"0xd3803", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xe3803", + "lane2":"0xd3803", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xe3803", + "lane2":"0xd3803", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xe3803", + "lane2":"0xd3803", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "35": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "36": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xd3803", + "lane2":"0xb3203", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xd3803", + "lane2":"0xb3203", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xd3803", + "lane2":"0xb3203", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xd3803", + "lane2":"0xb3203", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xd3803", + "lane2":"0xb3203", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "37": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3202", + "lane1":"0xb3202", + "lane2":"0xa3003", + "lane3":"0xb3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3202", + "lane1":"0xb3202", + "lane2":"0xa3003", + "lane3":"0xb3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3202", + "lane1":"0xb3202", + "lane2":"0xa3003", + "lane3":"0xb3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3202", + "lane1":"0xb3202", + "lane2":"0xa3003", + "lane3":"0xb3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3202", + "lane1":"0xb3202", + "lane2":"0xa3003", + "lane3":"0xb3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "38": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3203", + "lane1":"0xa3203", + "lane2":"0xa3203", + "lane3":"0xa3203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3203", + "lane1":"0xa3203", + "lane2":"0xa3203", + "lane3":"0xa3203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3203", + "lane1":"0xa3203", + "lane2":"0xa3203", + "lane3":"0xa3203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3203", + "lane1":"0xa3203", + "lane2":"0xa3203", + "lane3":"0xa3203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3203", + "lane1":"0xa3203", + "lane2":"0xa3203", + "lane3":"0xa3203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "39": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3202", + "lane1":"0xa3202", + "lane2":"0xa3003", + "lane3":"0xa3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3202", + "lane1":"0xa3202", + "lane2":"0xa3003", + "lane3":"0xa3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3202", + "lane1":"0xa3202", + "lane2":"0xa3003", + "lane3":"0xa3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3202", + "lane1":"0xa3202", + "lane2":"0xa3003", + "lane3":"0xa3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3202", + "lane1":"0xa3202", + "lane2":"0xa3003", + "lane3":"0xa3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "40": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "41": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "42": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xb3a03", + "lane3":"0xa3803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xb3a03", + "lane3":"0xa3803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xb3a03", + "lane3":"0xa3803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xb3a03", + "lane3":"0xa3803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xb3a03", + "lane3":"0xa3803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "43": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "44": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "45": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x72d03", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x72d03", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x72d03", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x72d03", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x72d03", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "46": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "47": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x82e03", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x82e03", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x82e03", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x82e03", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x82e03", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "48": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "49": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "50": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x83003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x83003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x83003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x83003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x83003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "51": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93002", + "lane2":"0x82f03", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93002", + "lane2":"0x82f03", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93002", + "lane2":"0x82f03", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93002", + "lane2":"0x82f03", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93002", + "lane2":"0x82f03", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "52": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "53": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "54": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xf3d02", + "lane2":"0xd3a03", + "lane3":"0xf3c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xf3d02", + "lane2":"0xd3a03", + "lane3":"0xf3c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xf3d02", + "lane2":"0xd3a03", + "lane3":"0xf3c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xf3d02", + "lane2":"0xd3a03", + "lane3":"0xf3c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xf3d02", + "lane2":"0xd3a03", + "lane3":"0xf3c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "55": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3a03", + "lane1":"0xc3a03", + "lane2":"0xa3403", + "lane3":"0xb3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3a03", + "lane1":"0xc3a03", + "lane2":"0xa3403", + "lane3":"0xb3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3a03", + "lane1":"0xc3a03", + "lane2":"0xa3403", + "lane3":"0xb3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3a03", + "lane1":"0xc3a03", + "lane2":"0xa3403", + "lane3":"0xb3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3a03", + "lane1":"0xc3a03", + "lane2":"0xa3403", + "lane3":"0xb3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "56": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "57": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93203", + "lane1":"0xa3603", + "lane2":"0x93203", + "lane3":"0x93203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93203", + "lane1":"0xa3603", + "lane2":"0x93203", + "lane3":"0x93203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93203", + "lane1":"0xa3603", + "lane2":"0x93203", + "lane3":"0x93203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93203", + "lane1":"0xa3603", + "lane2":"0x93203", + "lane3":"0x93203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93203", + "lane1":"0xa3603", + "lane2":"0x93203", + "lane3":"0x93203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "58": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "59": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "60": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xc3603", + "lane3":"0xc3603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xc3603", + "lane3":"0xc3603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xc3603", + "lane3":"0xc3603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xc3603", + "lane3":"0xc3603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xc3603", + "lane3":"0xc3603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "61": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xc3603", + "lane1":"0xd3a03", + "lane2":"0xc3603", + "lane3":"0xc3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3603", + "lane1":"0xd3a03", + "lane2":"0xc3603", + "lane3":"0xc3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3603", + "lane1":"0xd3a03", + "lane2":"0xc3603", + "lane3":"0xc3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xc3603", + "lane1":"0xd3a03", + "lane2":"0xc3603", + "lane3":"0xc3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xc3603", + "lane1":"0xd3a03", + "lane2":"0xc3603", + "lane3":"0xc3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "62": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" }, "idriver": { "lane0":"0x8", @@ -2437,12 +19461,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "AVAGO-AFBR-79EQDZ-JU1": { "preemphasis": { - "lane0":"0x1a4703", - "lane1":"0x1a4703", - "lane2":"0x1a4703", - "lane3":"0x1a4703" + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" }, "idriver": { "lane0":"0x8", @@ -2451,28 +19475,27 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "FINISAR CORP-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0xb3a03", - "lane1":"0xc3a03", - "lane2":"0xa3403", - "lane3":"0xb3a03" + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" }, "idriver": { "lane0":"0x8", "lane1":"0x8", + "lane1":"0x8", "lane2":"0x8", "lane3":"0x8" } - } - }, - "56": { - "Default": { + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" }, "idriver": { "lane0":"0x8", @@ -2481,12 +19504,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TR-IQ13L-NJ3": { "preemphasis": { - "lane0":"0x184903", - "lane1":"0x184903", - "lane2":"0x184903", - "lane3":"0x184903" + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" }, "idriver": { "lane0":"0x8", @@ -2495,12 +19518,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TR-IQ13L-NJ5": { "preemphasis": { - "lane0":"0xa3403", - "lane1":"0xa3403", - "lane2":"0xa3403", - "lane3":"0xa3403" + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" }, "idriver": { "lane0":"0x8", @@ -2510,7 +19533,7 @@ } } }, - "57": { + "63": { "Default": { "preemphasis": { "lane0":"0x14410a", @@ -2527,10 +19550,10 @@ }, "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { "preemphasis": { - "lane0":"0x194803", - "lane1":"0x194803", - "lane2":"0x194903", - "lane3":"0x194803" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2539,12 +19562,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-1F3-1F3QAA": { "preemphasis": { - "lane0":"0x93203", - "lane1":"0xa3603", - "lane2":"0x93203", - "lane3":"0x93203" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2552,15 +19575,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "58": { - "Default": { + }, + "JUNIPER-INNO-TF-FC030-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2569,12 +19590,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC020-NJC": { "preemphasis": { - "lane0":"0x1a4703", - "lane1":"0x1a4703", + "lane0":"0x1b4504", + "lane1":"0x1b4504", "lane2":"0x1a4703", - "lane3":"0x1a4703" + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2583,12 +19604,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TF-FC010-NJC": { "preemphasis": { - "lane0":"0xb3403", - "lane1":"0xc3603", - "lane2":"0xb3403", - "lane3":"0xb3403" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2596,15 +19617,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "59": { - "Default": { + }, + "JUNIPER-INNO-TF-FC001-NJC": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2613,12 +19632,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-INNO-TF-FC003-NJC": { "preemphasis": { - "lane0":"0x1a4703", - "lane1":"0x1a4703", + "lane0":"0x1b4504", + "lane1":"0x1b4504", "lane2":"0x1a4703", - "lane3":"0x1a4703" + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2627,12 +19646,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-INNO-TR-FC13R-NJ3": { "preemphasis": { - "lane0":"0xb3403", - "lane1":"0xc3603", - "lane2":"0xb3403", - "lane3":"0xb3403" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2640,15 +19659,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "60": { - "Default": { + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2657,12 +19674,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTLC9551REPM-J1": { "preemphasis": { - "lane0":"0x1a4703", - "lane1":"0x1a4703", + "lane0":"0x1b4504", + "lane1":"0x1b4504", "lane2":"0x1a4703", - "lane3":"0x1a4505" + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2671,12 +19688,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { "preemphasis": { - "lane0":"0xb3403", - "lane1":"0xc3603", - "lane2":"0xc3603", - "lane3":"0xc3603" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2684,15 +19701,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "61": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2701,12 +19716,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { "preemphasis": { - "lane0":"0x1b4603", - "lane1":"0x1b4603", - "lane2":"0x1b4603", - "lane3":"0x1b4603" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2715,12 +19730,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { "preemphasis": { - "lane0":"0xc3603", - "lane1":"0xd3a03", - "lane2":"0xc3603", - "lane3":"0xc3602" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2728,15 +19743,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "62": { - "Default": { + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2745,12 +19758,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { "preemphasis": { - "lane0":"0x1c4404", - "lane1":"0x1c4404", - "lane2":"0x1b4504", - "lane3":"0x1c4404" + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" }, "idriver": { "lane0":"0x8", @@ -2759,12 +19772,12 @@ "lane3":"0x8" } }, - "JUNIPER-INNO-TR-IQ13L-NJ3": { + "AVAGO-AFBR-79EQDZ-JU1": { "preemphasis": { - "lane0":"0xd3a03", - "lane1":"0xd3a03", + "lane0":"0xd3a02", + "lane1":"0xd3a02", "lane2":"0xd3a03", - "lane3":"0xd3a03" + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -2772,15 +19785,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "63": { - "Default": { + }, + "FINISAR CORP-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a03", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -2789,12 +19800,12 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-FINISAR-FTL410QE3C-J1": { "preemphasis": { - "lane0":"0x1b4504", - "lane1":"0x1b4504", - "lane2":"0x1a4703", - "lane3":"0x1b4504" + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a03", + "lane3":"0xd3a02" }, "idriver": { "lane0":"0x8", @@ -2816,6 +19827,20 @@ "lane2":"0x8", "lane3":"0x8" } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a03", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } } } } diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README index 490844f2137d..a69ac017c6f2 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README @@ -62,7 +62,23 @@ The status registers are mapped under /sys/bus/i2c/devices/9-0050 and SFPs ==== There are 64 QSFP+ modules supported in qfx5210 platform. EEPORMs will be -mapped under /sys/bus/i2c/devices/[25-88]-0050/ sysfs directory +mapped under /sys/bus/i2c/devices/[25-88]-0050/ sysfs directory. + +FEC should be turned on for SR4 optics and should be turned off for LR4 +optics. + +As an example, see this configuration for FEC for 100G SR4 optics in +/etc/sonic/config_db.json + +"Ethernet4": { + "admin_status": "up", + "alias": "Ethernet4", + "fec": "rs", + "index": "1", + "lanes": "65,66,67,68", + "mtu": "9100", + "speed": "100000" + } Sensor details ============== @@ -74,8 +90,20 @@ Platform poweroff ================= Linux poweroff commands such as 'poweroff', 'shutdown', 'halt', etc. will not power off qfx5210 platform as there are custom CPLDs control the power off -sequences. Use the command 'sudo platform_poweroff' to power off qfx5210 -platform +sequences. So acpi poweroff hooks are added for powering off the qfx5210. The +following messages are displayed in the console towards end of poweroff +sequence: + + [ 52.500807] System halt/power_off + [ 52.866331] reboot: Power down + [ 52.903257] pm_power_off: qfx5210_cpld_power_off + +Once the above messages are seen, you can safely remove the power to the system. + +Similarly platform reboot sequences are in place for system reboot. The following +messages are displayed in the console when the system is rebooted: + + [ 6053.163363] System restart: qfx5210_cpld_soft_reset Platform monitoring daemon ========================== From 7c5fb775d9d90c8140c8ca8b15ae841546a1ea30 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 6 Nov 2019 00:27:18 +0200 Subject: [PATCH 0122/1427] [mellanox] Upgrade HW-MGMT to V.7.0000.2303 (#3707) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/hw-management.mk | 2 +- platform/mellanox/hw-management/hw-mgmt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index 3e7749e11c4e..f41c2b9a25ce 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0000.2300 +MLNX_HW_MANAGEMENT_VERSION = 7.0000.2303 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index a72ba6371380..7c26a8f6a520 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit a72ba6371380b6d97cadf9f57f11b05dd9ae576c +Subproject commit 7c26a8f6a520b06663992afe874bc56b1fcd9311 From ed79f545692d0cab53ef68c40098c6a654eb000f Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Tue, 5 Nov 2019 18:32:14 -0800 Subject: [PATCH 0123/1427] [Services] Restart DHCP-Relay service upon unexpected critical process exit. (#3667) Signed-off-by: Yong Zhao --- dockers/docker-dhcp-relay/Dockerfile.j2 | 2 ++ dockers/docker-dhcp-relay/critical_processes | 1 + .../docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 | 6 ++++++ files/build_templates/dhcp_relay.service.j2 | 4 ++++ files/scripts/supervisor-proc-exit-listener | 3 ++- rules/docker-dhcp-relay.mk | 1 + .../tests/sample_output/docker-dhcp-relay.supervisord.conf | 6 ++++++ 7 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 dockers/docker-dhcp-relay/critical_processes diff --git a/dockers/docker-dhcp-relay/Dockerfile.j2 b/dockers/docker-dhcp-relay/Dockerfile.j2 index e365adab1716..d3c09f9ba260 100644 --- a/dockers/docker-dhcp-relay/Dockerfile.j2 +++ b/dockers/docker-dhcp-relay/Dockerfile.j2 @@ -26,5 +26,7 @@ RUN apt-get clean -y && \ COPY ["docker_init.sh", "start.sh", "/usr/bin/"] COPY ["docker-dhcp-relay.supervisord.conf.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/dockers/docker-dhcp-relay/critical_processes b/dockers/docker-dhcp-relay/critical_processes new file mode 100644 index 000000000000..ddb183963a67 --- /dev/null +++ b/dockers/docker-dhcp-relay/critical_processes @@ -0,0 +1 @@ +isc-dhcp-relay diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index 4462ff3d7fdc..e738e8699e6c 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/files/build_templates/dhcp_relay.service.j2 b/files/build_templates/dhcp_relay.service.j2 index f48217d55567..9106e29a41e2 100644 --- a/files/build_templates/dhcp_relay.service.j2 +++ b/files/build_templates/dhcp_relay.service.j2 @@ -3,12 +3,16 @@ Description=DHCP relay container Requires=updategraph.service swss.service teamd.service After=updategraph.service swss.service syncd.service teamd.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{ docker_container_name }}.sh start ExecStart=/usr/bin/{{ docker_container_name }}.sh wait ExecStop=/usr/bin/{{ docker_container_name }}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target swss.service teamd.service diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index 6bc62fc400c8..8d1735cd2b0c 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -33,9 +33,10 @@ def main(): expected = int(payload_headers['expected']) processname = payload_headers['processname'] + groupname = payload_headers['groupname'] # If a critical process exited unexpectedly, terminate supervisor - if expected == 0 and processname in critical_processes: + if expected == 0 and processname in critical_processes or groupname in critical_processes: MSG_FORMAT_STR = "Process {} exited unxepectedly. Terminating supervisor..." msg = MSG_FORMAT_STR.format(payload_headers['processname']) syslog.syslog(syslog.LOG_INFO, msg) diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 6fad19cc1998..5aae24ee33b5 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -25,3 +25,4 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DHCP_RELAY_DBG) $(DOCKER_DHCP_RELAY)_CONTAINER_NAME = dhcp_relay $(DOCKER_DHCP_RELAY)_RUN_OPT += --net=host --privileged -t $(DOCKER_DHCP_RELAY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_DHCP_RELAY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index d285fbfc788c..bae273eeaf81 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 From 9f1f61c8214a3a922bf972b6e27122df8e435d20 Mon Sep 17 00:00:00 2001 From: "Sudharsan D.G" Date: Wed, 6 Nov 2019 08:25:47 -0800 Subject: [PATCH 0124/1427] [submodule]: Updated sonic-utilities pointer (#3715) - [warm/fast reboot] continue executing when killing docker failed (#713) [Ying Xie] - [neighbor_advertiser]: Add sleep in setting mirror session and ACL rules(#714)[Shuotian Cheng] - [config]: Flush the neighbor table when removing the router interface(#606) [Shuotian Cheng] - Add a generic configlet application script (#716) [Renuka Manavalan] - Management vrf snmp cli support (#472) [Harish Venkatraman] - show subinterfaces status (#642) [Wenda Ni] - sonic-utilities: Add support for sFlow (#592) [Garrick He] --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index c12c4434fa24..0e23e1cd0a3b 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit c12c4434fa2440914a705b9b15d142012eac4ce0 +Subproject commit 0e23e1cd0a3b3538061c8f971acd579bf2a9e151 From 997ea59ba4ac90981013a16dad1c48a8c14f286f Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 6 Nov 2019 09:24:54 -0800 Subject: [PATCH 0125/1427] Fix typos and comment alignment in supervisor.conf files (#3714) --- .../etc/supervisor/supervisord.conf | 12 ++++++------ dockers/docker-base/etc/supervisor/supervisord.conf | 12 ++++++------ dockers/docker-ptf/supervisord.conf | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/dockers/docker-base-stretch/etc/supervisor/supervisord.conf b/dockers/docker-base-stretch/etc/supervisor/supervisord.conf index 351cc06fc048..5d1010e8fa4e 100644 --- a/dockers/docker-base-stretch/etc/supervisor/supervisord.conf +++ b/dockers/docker-base-stretch/etc/supervisor/supervisord.conf @@ -1,15 +1,15 @@ ; supervisor config file [unix_http_server] -file=/var/run/supervisor.sock ; (the path to the socket file) -chmod=0700 ; sockef file mode (default 0700) +file=/var/run/supervisor.sock ; (the path to the socket file) +chmod=0700 ; socket file mode (default 0700) username=dummy password=dummy [supervisord] -logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) -pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) -childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) +logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) +pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) user=root ; the below section must remain in the config file for RPC @@ -19,7 +19,7 @@ user=root supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] -serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket +serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket username=dummy password=dummy diff --git a/dockers/docker-base/etc/supervisor/supervisord.conf b/dockers/docker-base/etc/supervisor/supervisord.conf index 351cc06fc048..5d1010e8fa4e 100644 --- a/dockers/docker-base/etc/supervisor/supervisord.conf +++ b/dockers/docker-base/etc/supervisor/supervisord.conf @@ -1,15 +1,15 @@ ; supervisor config file [unix_http_server] -file=/var/run/supervisor.sock ; (the path to the socket file) -chmod=0700 ; sockef file mode (default 0700) +file=/var/run/supervisor.sock ; (the path to the socket file) +chmod=0700 ; socket file mode (default 0700) username=dummy password=dummy [supervisord] -logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) -pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) -childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) +logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) +pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) user=root ; the below section must remain in the config file for RPC @@ -19,7 +19,7 @@ user=root supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] -serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket +serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket username=dummy password=dummy diff --git a/dockers/docker-ptf/supervisord.conf b/dockers/docker-ptf/supervisord.conf index 9c236612d25c..be71d20a42d9 100644 --- a/dockers/docker-ptf/supervisord.conf +++ b/dockers/docker-ptf/supervisord.conf @@ -1,13 +1,13 @@ ; supervisor config file [unix_http_server] -file=/var/run/supervisor.sock ; (the path to the socket file) -chmod=0700 ; sockef file mode (default 0700) +file=/var/run/supervisor.sock ; (the path to the socket file) +chmod=0700 ; socket file mode (default 0700) [supervisord] -logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) -pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) -childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) +logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) +pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) ; the below section must remain in the config file for RPC ; (supervisorctl/web interface) to work, additional interfaces may be @@ -16,7 +16,7 @@ childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TE supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] -serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket +serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket ; The [include] section can just contain the "files" setting. This ; setting can list multiple files (separated by whitespace or From 05e659901fa48c0691a97a48180d113a2d85e258 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Wed, 6 Nov 2019 10:11:38 -0800 Subject: [PATCH 0126/1427] [arista] Add support for more 7280CR3 variants (#3711) * Add extra Smartsville hwskus --- device/arista/x86_64-arista_7280cr3k_32p4 | 1 + files/Aboot/boot0.j2 | 10 +++++++++- platform/broadcom/sonic-platform-modules-arista | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 120000 device/arista/x86_64-arista_7280cr3k_32p4 diff --git a/device/arista/x86_64-arista_7280cr3k_32p4 b/device/arista/x86_64-arista_7280cr3k_32p4 new file mode 120000 index 000000000000..d6e2ddbb64bd --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3k_32p4 @@ -0,0 +1 @@ +x86_64-arista_7280cr3_32p4 \ No newline at end of file diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 1d8d3547d7ab..2f861bbbd405 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -258,10 +258,18 @@ platform_specific() { aboot_machine=arista_7060dx4_32 flash_size=28000 fi - if [ "$sid" = "Smartsville" ]; then + if [ "$sid" = "Smartsville" ] || [ "$sid" = "SmartsvilleSsd" ]; then aboot_machine=arista_7280cr3_32p4 flash_size=7382 fi + if [ "$sid" = "SmartsvilleBK" ] || [ "$sid" = "SmartsvilleBKSsd" ]; then + aboot_machine=arista_7280cr3k_32p4 + flash_size=7382 + fi + if [ "$sid" = "SmartsvilleDD" ] || [ "$sid" = "SmartsvilleDDSsd" ]; then + aboot_machine=arista_7280cr3_32d4 + flash_size=7382 + fi if [ "$platform" = "rook" ] || [ "$platform" = "magpie" ] || [ "$platform" = "woodpecker" ]; then echo "tsc=reliable pcie_ports=native" >>/tmp/append diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 10750325b6cf..390d5e22f9c6 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 10750325b6cfc7a1dc1a8b0734008bde1bb3ac06 +Subproject commit 390d5e22f9c6c1a007ed325f6b0bd050a79aa5b1 From a117b25446a97477486143c4a9780d0163c207d7 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Wed, 6 Nov 2019 11:02:57 -0800 Subject: [PATCH 0127/1427] [Services] Restart LLDP service upon unexpected critical process exit. (#3713) Signed-off-by: Yong Zhao --- dockers/docker-lldp-sv2/Dockerfile.j2 | 2 ++ dockers/docker-lldp-sv2/critical_processes | 3 +++ dockers/docker-lldp-sv2/supervisord.conf | 6 ++++++ files/build_templates/lldp.service.j2 | 4 ++++ rules/docker-lldp-sv2.mk | 1 + 5 files changed, 16 insertions(+) create mode 100644 dockers/docker-lldp-sv2/critical_processes diff --git a/dockers/docker-lldp-sv2/Dockerfile.j2 b/dockers/docker-lldp-sv2/Dockerfile.j2 index 2a76c2cc6f0b..6a720514ef9b 100644 --- a/dockers/docker-lldp-sv2/Dockerfile.j2 +++ b/dockers/docker-lldp-sv2/Dockerfile.j2 @@ -40,5 +40,7 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["lldpd.conf.j2", "/usr/share/sonic/templates/"] COPY ["lldpd", "/etc/default/"] COPY ["lldpmgrd", "/usr/bin/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-lldp-sv2/critical_processes b/dockers/docker-lldp-sv2/critical_processes new file mode 100644 index 000000000000..b845b70bb3f7 --- /dev/null +++ b/dockers/docker-lldp-sv2/critical_processes @@ -0,0 +1,3 @@ +lldpd +lldp-syncd +lldpmgrd diff --git a/dockers/docker-lldp-sv2/supervisord.conf b/dockers/docker-lldp-sv2/supervisord.conf index 5feb3543f1bc..3f3f5beabc8d 100644 --- a/dockers/docker-lldp-sv2/supervisord.conf +++ b/dockers/docker-lldp-sv2/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/files/build_templates/lldp.service.j2 b/files/build_templates/lldp.service.j2 index 6f8fc902befc..2599fc5c5bdc 100644 --- a/files/build_templates/lldp.service.j2 +++ b/files/build_templates/lldp.service.j2 @@ -3,12 +3,16 @@ Description=LLDP container Requires=updategraph.service After=updategraph.service swss.service syncd.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/rules/docker-lldp-sv2.mk b/rules/docker-lldp-sv2.mk index 104576f78891..91acbe58ad82 100644 --- a/rules/docker-lldp-sv2.mk +++ b/rules/docker-lldp-sv2.mk @@ -30,3 +30,4 @@ $(DOCKER_LLDP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpctl:/usr/bin/lldpctl $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpcli:/usr/bin/lldpcli +$(DOCKER_LLDP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From aa1a13677d071184abd254be5e63f227a053b713 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 6 Nov 2019 11:57:23 -0800 Subject: [PATCH 0128/1427] [frr]: Move to version 7.2 (#3704) * Use 7.2 tree to generate frr packages * Adapt patches for frr/7.2 * Use vrf_id --- rules/frr.mk | 2 +- src/sonic-frr/frr | 2 +- ...01-Add-support-of-bgp-tcp-DSCP-value.patch | 26 +- ...verity-of-Vty-connected-from-message.patch | 8 +- ...003-Use-vrf_id-for-vrf-not-tabled_id.patch | 35 +++ ...EXT_HOP-to-be-0.0.0.0-due-to-allevia.patch | 8 +- src/sonic-frr/patch/0005-Support-VRF.patch | 30 --- ...-dead-fd-poll-data-port-fix-from-frr.patch | 107 --------- ...-zebra-kernel-level-graceful-restart.patch | 227 ------------------ src/sonic-frr/patch/series | 4 +- 10 files changed, 59 insertions(+), 390 deletions(-) create mode 100644 src/sonic-frr/patch/0003-Use-vrf_id-for-vrf-not-tabled_id.patch delete mode 100644 src/sonic-frr/patch/0005-Support-VRF.patch delete mode 100644 src/sonic-frr/patch/0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch delete mode 100644 src/sonic-frr/patch/0008-zebra-kernel-level-graceful-restart.patch diff --git a/rules/frr.mk b/rules/frr.mk index 83c359992ac3..27391ce0cf73 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -1,6 +1,6 @@ # FRRouting (frr) package -FRR_VERSION = 7.1 +FRR_VERSION = 7.2 FRR_SUBVERSION = 0 export FRR_VERSION FRR_SUBVERSION diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index 8c5e037c4960..514f508fc60e 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit 8c5e037c496025597406f496010d6ef6b1d2e73d +Subproject commit 514f508fc60e0573d9863beaad8924927d373954 diff --git a/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch b/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch index c7676fd65cb4..9587231d8870 100644 --- a/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch +++ b/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch @@ -1,6 +1,6 @@ -From ab8ae984def8ee5cea22f802b2a60a05214c11d2 Mon Sep 17 00:00:00 2001 +From 3ec4fa4c8377330d4e3bdbdfc453a79a7827d84d Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Mon, 7 Oct 2019 17:00:15 -0700 +Date: Mon, 4 Nov 2019 18:09:51 -0800 Subject: [PATCH 1/1] Add support of bgp tcp DSCP value --- @@ -11,12 +11,12 @@ Subject: [PATCH 1/1] Add support of bgp tcp DSCP value 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c -index 6a5c2c4b3..9ec162aa4 100644 +index 1394c60b2..a70268b05 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c -@@ -627,11 +627,9 @@ int bgp_connect(struct peer *peer) +@@ -633,11 +633,9 @@ int bgp_connect(struct peer *peer) #ifdef IPTOS_PREC_INTERNETCONTROL - frr_elevate_privs(&bgpd_privs) { + frr_with_privs(&bgpd_privs) { if (sockunion_family(&peer->su) == AF_INET) - setsockopt_ipv4_tos(peer->fd, - IPTOS_PREC_INTERNETCONTROL); @@ -28,7 +28,7 @@ index 6a5c2c4b3..9ec162aa4 100644 } #endif -@@ -707,10 +705,9 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen, +@@ -713,10 +711,9 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen, #ifdef IPTOS_PREC_INTERNETCONTROL if (sa->sa_family == AF_INET) @@ -42,10 +42,10 @@ index 6a5c2c4b3..9ec162aa4 100644 sockopt_v6only(sa->sa_family, sock); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c -index d05432327..a15a0f526 100644 +index 141d5cf30..8faa918d0 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c -@@ -1139,6 +1139,42 @@ DEFUN (no_router_bgp, +@@ -1182,6 +1182,42 @@ DEFUN (no_router_bgp, return CMD_SUCCESS; } @@ -88,7 +88,7 @@ index d05432327..a15a0f526 100644 /* BGP router-id. */ -@@ -12929,6 +12965,10 @@ void bgp_vty_init(void) +@@ -13035,6 +13071,10 @@ void bgp_vty_init(void) /* "no router bgp" commands. */ install_element(CONFIG_NODE, &no_router_bgp_cmd); @@ -100,10 +100,10 @@ index d05432327..a15a0f526 100644 install_element(BGP_NODE, &bgp_router_id_cmd); install_element(BGP_NODE, &no_bgp_router_id_cmd); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c -index 8c0b5336e..55aeb2dd8 100644 +index 80c6dd613..87a8ef34f 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c -@@ -3040,7 +3040,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, +@@ -3050,7 +3050,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->evpn_info = XCALLOC(MTYPE_BGP_EVPN_INFO, sizeof(struct bgp_evpn_info)); @@ -112,7 +112,7 @@ index 8c0b5336e..55aeb2dd8 100644 bgp_evpn_init(bgp); bgp_pbr_init(bgp); return bgp; -@@ -7629,6 +7629,9 @@ int bgp_config_write(struct vty *vty) +@@ -7564,6 +7564,9 @@ int bgp_config_write(struct vty *vty) if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) vty_out(vty, " no bgp fast-external-failover\n"); @@ -123,7 +123,7 @@ index 8c0b5336e..55aeb2dd8 100644 if (bgp->router_id_static.s_addr != 0) vty_out(vty, " bgp router-id %s\n", diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h -index b0f656753..32983a0a9 100644 +index e4f4dc0b5..4d372c562 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -569,6 +569,9 @@ struct bgp { diff --git a/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch b/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch index 9ec7b980ae84..e47544f79384 100644 --- a/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch +++ b/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch @@ -1,6 +1,6 @@ -From 5a30a4e91a91f8e19c69ef219cd6d8b19e9b6fae Mon Sep 17 00:00:00 2001 +From 63b5b14ad289f18928beac65754e7bb13183b5dc Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Mon, 7 Oct 2019 17:06:27 -0700 +Date: Mon, 4 Nov 2019 18:12:54 -0800 Subject: [PATCH 1/1] Reduce severity of 'Vty connected from' message --- @@ -8,10 +8,10 @@ Subject: [PATCH 1/1] Reduce severity of 'Vty connected from' message 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vty.c b/lib/vty.c -index b1ed3d63c..5aa4b56cb 100644 +index deb9391bd..743ff1c17 100644 --- a/lib/vty.c +++ b/lib/vty.c -@@ -1870,7 +1870,7 @@ static int vty_accept(struct thread *thread) +@@ -1853,7 +1853,7 @@ static int vty_accept(struct thread *thread) zlog_info("can't set sockopt to vty_sock : %s", safe_strerror(errno)); diff --git a/src/sonic-frr/patch/0003-Use-vrf_id-for-vrf-not-tabled_id.patch b/src/sonic-frr/patch/0003-Use-vrf_id-for-vrf-not-tabled_id.patch new file mode 100644 index 000000000000..c9a8c0081994 --- /dev/null +++ b/src/sonic-frr/patch/0003-Use-vrf_id-for-vrf-not-tabled_id.patch @@ -0,0 +1,35 @@ +From 9e7f1de3b79ca6ada8a3124f4cdc35530284832e Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 5 Nov 2019 06:16:51 -0800 +Subject: [PATCH 1/1] Use vrf_id for vrf, not tabled_id + +--- + zebra/zebra_fpm_netlink.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c +index f347d3955..74aab8228 100644 +--- a/zebra/zebra_fpm_netlink.c ++++ b/zebra/zebra_fpm_netlink.c +@@ -284,7 +284,6 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd, + rib_dest_t *dest, struct route_entry *re) + { + struct nexthop *nexthop; +- struct zebra_vrf *zvrf; + + memset(ri, 0, sizeof(*ri)); + +@@ -292,9 +291,7 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd, + ri->af = rib_dest_af(dest); + + ri->nlmsg_type = cmd; +- zvrf = rib_dest_vrf(dest); +- if (zvrf) +- ri->rtm_table = zvrf->table_id; ++ ri->rtm_table = zvrf_id(rib_dest_vrf(dest)); + ri->rtm_protocol = RTPROT_UNSPEC; + + /* +-- +2.17.1.windows.2 + diff --git a/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch b/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch index cb3c30c781d2..b31da0651ae1 100644 --- a/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch +++ b/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch @@ -1,6 +1,6 @@ -From 9fa0ffcc8f9ec987af527e911cd748014aeacffe Mon Sep 17 00:00:00 2001 +From fe1e544d46d721798594fcec175665e3754500a6 Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Mon, 7 Oct 2019 17:15:15 -0700 +Date: Mon, 4 Nov 2019 18:14:12 -0800 Subject: [PATCH 1/1] Allow BGP attr NEXT_HOP to be 0.0.0.0 due to alleviate the vendor bug @@ -9,10 +9,10 @@ Subject: [PATCH 1/1] Allow BGP attr NEXT_HOP to be 0.0.0.0 due to alleviate 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c -index f8eae135e..732115756 100644 +index c122df498..3c7aa3075 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c -@@ -2904,8 +2904,7 @@ static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, +@@ -2983,8 +2983,7 @@ static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, /* If NEXT_HOP is present, validate it. */ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) { diff --git a/src/sonic-frr/patch/0005-Support-VRF.patch b/src/sonic-frr/patch/0005-Support-VRF.patch deleted file mode 100644 index 8d6689e5240a..000000000000 --- a/src/sonic-frr/patch/0005-Support-VRF.patch +++ /dev/null @@ -1,30 +0,0 @@ -From b7ae4e11c2dc14f9208b62ea060bb5ecbf4cddb2 Mon Sep 17 00:00:00 2001 -From: Pavel Shirshov -Date: Mon, 7 Oct 2019 17:17:54 -0700 -Subject: [PATCH 1/1] Support VRF - ---- - zebra/zebra_fpm_netlink.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c -index 88f0c3250..29f07f801 100644 ---- a/zebra/zebra_fpm_netlink.c -+++ b/zebra/zebra_fpm_netlink.c -@@ -327,7 +327,12 @@ static int netlink_route_info_encode(netlink_route_info_t *ri, char *in_buf, - req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; - req->n.nlmsg_type = ri->nlmsg_type; - req->r.rtm_family = ri->af; -- req->r.rtm_table = ri->rtm_table; -+ if (ri->rtm_table < 256) -+ req->r.rtm_table = ri->rtm_table; -+ else { -+ req->r.rtm_table = RT_TABLE_COMPAT; -+ addattr32(&req->n, in_buf_len, RTA_TABLE, ri->rtm_table); -+ } - req->r.rtm_dst_len = ri->prefix->prefixlen; - req->r.rtm_protocol = ri->rtm_protocol; - req->r.rtm_scope = RT_SCOPE_UNIVERSE; --- -2.17.1.windows.2 - diff --git a/src/sonic-frr/patch/0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch b/src/sonic-frr/patch/0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch deleted file mode 100644 index 5954e5c7c53d..000000000000 --- a/src/sonic-frr/patch/0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch +++ /dev/null @@ -1,107 +0,0 @@ -From e4225086634fb7ae7fa762f3a45af6ad39e78641 Mon Sep 17 00:00:00 2001 -From: sudhanshukumar22 -Date: Tue, 15 Oct 2019 02:17:00 -0700 -Subject: [PATCH] Port a fix from FRR community - https://github.com/donaldsharp/frr/commit/39c93f379a5b57c56739a339ad75ec06e30daef3 - If we have a case where have created a fd for i/o and we have removed the - handling thread but still have the fd in the poll data structure, there - existed a case where we would get the handle this fd return from poll but we - would immediately do nothing with it because we didn't have a thread to hand - the event to. - -This leads to an infinite loop. Prevent the infinite loop -from happening and log the problem. ---- - lib/lib_errors.c | 6 ++++++ - lib/lib_errors.h | 1 + - lib/thread.c | 25 ++++++++++++++++++------- - 3 files changed, 25 insertions(+), 7 deletions(-) - -diff --git a/lib/lib_errors.c b/lib/lib_errors.c -index b6c764d87..033f27e58 100644 ---- a/lib/lib_errors.c -+++ b/lib/lib_errors.c -@@ -50,6 +50,12 @@ static struct log_ref ferr_lib_warn[] = { - .description = "The Event subsystem has detected a slow process, this typically indicates that FRR is having trouble completing work in a timely manner. This can be either a misconfiguration, bug, or some combination therof.", - .suggestion = "Gather log data and open an Issue", - }, -+ { -+ .code = EC_LIB_NO_THREAD, -+ .title = "The Event subsystem has detected an internal FD problem", -+ .description = "The Event subsystem has detected a file descriptor read/write event without an associated handling function. This is a bug, please collect log data and open an issue.", -+ .suggestion = "Gather log data and open an Issue", -+ }, - { - .code = EC_LIB_RMAP_RECURSION_LIMIT, - .title = "Reached the Route-Map Recursion Limit", -diff --git a/lib/lib_errors.h b/lib/lib_errors.h -index 39b39fb06..996a16ba9 100644 ---- a/lib/lib_errors.h -+++ b/lib/lib_errors.h -@@ -45,6 +45,7 @@ enum lib_log_refs { - EC_LIB_STREAM, - EC_LIB_LINUX_NS, - EC_LIB_SLOW_THREAD, -+ EC_LIB_NO_THREAD, - EC_LIB_RMAP_RECURSION_LIMIT, - EC_LIB_BACKUP_CONFIG, - EC_LIB_VRF_LENGTH, -diff --git a/lib/thread.c b/lib/thread.c -index 5ca859a74..82708557d 100644 ---- a/lib/thread.c -+++ b/lib/thread.c -@@ -1235,12 +1235,26 @@ static struct thread *thread_run(struct thread_master *m, struct thread *thread, - } - - static int thread_process_io_helper(struct thread_master *m, -- struct thread *thread, short state, int pos) -+ struct thread *thread, short state, short actual_state, int pos) - { - struct thread **thread_array; - -- if (!thread) -+ /* -+ * If another pthread scheduled this file descriptor for this event -+ * we're responding to, no problem, we're getting to it now. -+ * Additionally if !thread if we don't clear this now we'll -+ * infinaloop( which sucks ) -+ */ -+ m->handler.pfds[pos].events &= ~(state); -+ -+ if (!thread) { -+ if ((actual_state & (POLLHUP | POLLIN)) != POLLHUP) -+ flog_err( EC_LIB_NO_THREAD, -+ "Attempting to process an I/O event but for fd: %d(%d) no thread to handle this!\n", -+ m->handler.pfds[pos].fd, actual_state); - return 0; -+ } -+ - - if (thread->type == THREAD_READ) - thread_array = m->read; -@@ -1250,9 +1264,6 @@ static int thread_process_io_helper(struct thread_master *m, - thread_array[thread->u.fd] = NULL; - thread_list_add_tail(&m->ready, thread); - thread->type = THREAD_READY; -- /* if another pthread scheduled this file descriptor for the event we're -- * responding to, no problem; we're getting to it now */ -- thread->master->handler.pfds[pos].events &= ~(state); - return 1; - } - -@@ -1290,10 +1301,10 @@ static void thread_process_io(struct thread_master *m, unsigned int num) - * should still be a valid index into the master's pfds. */ - if (pfds[i].revents & (POLLIN | POLLHUP)) - thread_process_io_helper(m, m->read[pfds[i].fd], POLLIN, -- i); -+ pfds[i].revents,i); - if (pfds[i].revents & POLLOUT) - thread_process_io_helper(m, m->write[pfds[i].fd], -- POLLOUT, i); -+ POLLOUT, pfds[i].revents, i); - - /* if one of our file descriptors is garbage, remove the same - * from --- -2.18.0 - diff --git a/src/sonic-frr/patch/0008-zebra-kernel-level-graceful-restart.patch b/src/sonic-frr/patch/0008-zebra-kernel-level-graceful-restart.patch deleted file mode 100644 index e2a68a3507b4..000000000000 --- a/src/sonic-frr/patch/0008-zebra-kernel-level-graceful-restart.patch +++ /dev/null @@ -1,227 +0,0 @@ - - zebra: Add kernel level graceful restart - - - - Add the a `--graceful_restart X` flag to zebra start that - now creates a timer that pops in X seconds and will go - through and remove all routes that are older than startup. - - If graceful_restart is not specified then we will just pop - a timer that cleans everything up immediately. - - Signed-off-by: Praveen Chaudhary - Signed-off-by: Donald Sharp - -diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst -index f38db9d24..40d894929 100644 ---- a/doc/user/zebra.rst -+++ b/doc/user/zebra.rst -@@ -23,9 +23,12 @@ Besides the common invocation options (:ref:`common-invocation-options`), the - Runs in batch mode. *zebra* parses configuration file and terminates - immediately. - --.. option:: -k, --keep_kernel -+.. option:: -K TIME, --graceful_restart TIME - -- When zebra starts up, don't delete old self inserted routes. -+ If this option is specified, the graceful restart time is TIME seconds. -+ Zebra, when started, will read in routes. Those routes that Zebra -+ identifies that it was the originator of will be swept in TIME seconds. -+ If no time is specified then we will sweep those routes immediately. - - .. option:: -r, --retain - -diff --git a/zebra/main.c b/zebra/main.c -index 184e798bd..3d1d156ad 100644 ---- a/zebra/main.c -+++ b/zebra/main.c -@@ -74,8 +74,7 @@ int retain_mode = 0; - /* Allow non-quagga entities to delete quagga routes */ - int allow_delete = 0; - --/* Don't delete kernel route. */ --int keep_kernel_mode = 0; -+int graceful_restart; - - bool v6_rr_semantics = false; - -@@ -89,12 +88,12 @@ uint32_t nl_rcvbufsize = 4194304; - struct option longopts[] = { - {"batch", no_argument, NULL, 'b'}, - {"allow_delete", no_argument, NULL, 'a'}, -- {"keep_kernel", no_argument, NULL, 'k'}, - {"socket", required_argument, NULL, 'z'}, - {"ecmp", required_argument, NULL, 'e'}, - {"label_socket", no_argument, NULL, 'l'}, - {"retain", no_argument, NULL, 'r'}, - {"vrfdefaultname", required_argument, NULL, 'o'}, -+ {"graceful_restart", required_argument, NULL, 'K'}, - #ifdef HAVE_NETLINK - {"vrfwnetns", no_argument, NULL, 'n'}, - {"nl-bufsize", required_argument, NULL, 's'}, -@@ -264,13 +263,14 @@ int main(int argc, char **argv) - char *netlink_fuzzing = NULL; - #endif /* HANDLE_NETLINK_FUZZING */ - -+ graceful_restart = 0; - vrf_configure_backend(VRF_BACKEND_VRF_LITE); - logicalrouter_configure_backend(LOGICALROUTER_BACKEND_NETNS); - - frr_preinit(&zebra_di, argc, argv); - - frr_opt_add( -- "bakz:e:l:o:r" -+ "baz:e:l:o:rK:" - #ifdef HAVE_NETLINK - "s:n" - #endif -@@ -282,24 +282,24 @@ int main(int argc, char **argv) - #endif /* HANDLE_NETLINK_FUZZING */ - , - longopts, -- " -b, --batch Runs in batch mode\n" -- " -a, --allow_delete Allow other processes to delete zebra routes\n" -- " -z, --socket Set path of zebra socket\n" -- " -e, --ecmp Specify ECMP to use.\n" -- " -l, --label_socket Socket to external label manager\n" -- " -k, --keep_kernel Don't delete old routes which were installed by zebra.\n" -- " -r, --retain When program terminates, retain added route by zebra.\n" -- " -o, --vrfdefaultname Set default VRF name.\n" -+ " -b, --batch Runs in batch mode\n" -+ " -a, --allow_delete Allow other processes to delete zebra routes\n" -+ " -z, --socket Set path of zebra socket\n" -+ " -e, --ecmp Specify ECMP to use.\n" -+ " -l, --label_socket Socket to external label manager\n" -+ " -r, --retain When program terminates, retain added route by zebra.\n" -+ " -o, --vrfdefaultname Set default VRF name.\n" -+ " -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n" - #ifdef HAVE_NETLINK -- " -n, --vrfwnetns Use NetNS as VRF backend\n" -- " -s, --nl-bufsize Set netlink receive buffer size\n" -- " --v6-rr-semantics Use v6 RR semantics\n" -+ " -n, --vrfwnetns Use NetNS as VRF backend\n" -+ " -s, --nl-bufsize Set netlink receive buffer size\n" -+ " --v6-rr-semantics Use v6 RR semantics\n" - #endif /* HAVE_NETLINK */ - #if defined(HANDLE_ZAPI_FUZZING) -- " -c Bypass normal startup and use this file for testing of zapi\n" -+ " -c Bypass normal startup and use this file for testing of zapi\n" - #endif /* HANDLE_ZAPI_FUZZING */ - #if defined(HANDLE_NETLINK_FUZZING) -- " -w Bypass normal startup and use this file for testing of netlink input\n" -+ " -w Bypass normal startup and use this file for testing of netlink input\n" - #endif /* HANDLE_NETLINK_FUZZING */ - ); - -@@ -318,9 +318,6 @@ int main(int argc, char **argv) - case 'a': - allow_delete = 1; - break; -- case 'k': -- keep_kernel_mode = 1; -- break; - case 'e': - multipath_num = atoi(optarg); - if (multipath_num > MULTIPATH_NUM -@@ -350,6 +347,9 @@ int main(int argc, char **argv) - case 'r': - retain_mode = 1; - break; -+ case 'K': -+ graceful_restart = atoi(optarg); -+ break; - #ifdef HAVE_NETLINK - case 's': - nl_rcvbufsize = atoi(optarg); -@@ -437,9 +437,9 @@ int main(int argc, char **argv) - * will be equal to the current getpid(). To know about such routes, - * we have to have route_read() called before. - */ -- if (!keep_kernel_mode) -- rib_sweep_route(); -- -+ zrouter.startup_time = monotime(NULL); -+ thread_add_timer(zrouter.master, rib_sweep_route, -+ NULL, graceful_restart, NULL); - /* Needed for BSD routing socket. */ - pid = getpid(); - -diff --git a/zebra/rib.h b/zebra/rib.h -index 9fe42aef3..69850f3a0 100644 ---- a/zebra/rib.h -+++ b/zebra/rib.h -@@ -351,7 +351,7 @@ extern struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, - extern void rib_update(vrf_id_t vrf_id, rib_update_event_t event); - extern void rib_update_table(struct route_table *table, - rib_update_event_t event); --extern void rib_sweep_route(void); -+extern int rib_sweep_route(struct thread *t); - extern void rib_sweep_table(struct route_table *table); - extern void rib_close_table(struct route_table *table); - extern void rib_init(void); -diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index 555127b09..b6afcdc8c 100644 ---- a/zebra/zebra_rib.c -+++ b/zebra/zebra_rib.c -@@ -3145,6 +3145,7 @@ void rib_sweep_table(struct route_table *table) - - for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) { - RNODE_FOREACH_RE_SAFE (rn, re, next) { -+ - if (IS_ZEBRA_DEBUG_RIB) - route_entry_dump(&rn->p, NULL, re); - -@@ -3154,6 +3155,14 @@ void rib_sweep_table(struct route_table *table) - if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELFROUTE)) - continue; - -+ /* -+ * If routes are older than startup_time then -+ * we know we read them in from the kernel. -+ * As such we can safely remove them. -+ */ -+ if (zrouter.startup_time < re->uptime) -+ continue; -+ - /* - * So we are starting up and have received - * routes from the kernel that we have installed -@@ -3183,7 +3192,7 @@ void rib_sweep_table(struct route_table *table) - } - - /* Sweep all RIB tables. */ --void rib_sweep_route(void) -+int rib_sweep_route(struct thread *t) - { - struct vrf *vrf; - struct zebra_vrf *zvrf; -@@ -3197,6 +3206,8 @@ void rib_sweep_route(void) - } - - zebra_router_sweep_route(); -+ -+ return 0; - } - - /* Remove specific by protocol routes from 'table'. */ -diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h -index b316b91d0..b2e92bad0 100644 ---- a/zebra/zebra_router.h -+++ b/zebra/zebra_router.h -@@ -110,8 +110,15 @@ struct zebra_router { - * The EVPN instance, if any - */ - struct zebra_vrf *evpn_vrf; -+ -+ /* -+ * Time for when we sweep the rib from old routes -+ */ -+ time_t startup_time; - }; - -+#define GRACEFUL_RESTART_TIME 60 -+ - extern struct zebra_router zrouter; - - extern void zebra_router_init(void); diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index da0ab7ba47c5..233021ace50b 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -1,7 +1,5 @@ 0001-Add-support-of-bgp-tcp-DSCP-value.patch 0002-Reduce-severity-of-Vty-connected-from-message.patch +0003-Use-vrf_id-for-vrf-not-tabled_id.patch 0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch -0005-Support-VRF.patch 0006-changes-for-making-snmp-socket-non-blocking.patch -0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch -0008-zebra-kernel-level-graceful-restart.patch \ No newline at end of file From d346cb3898d58aeb16c22a66a79b117ab267d4b8 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Wed, 6 Nov 2019 22:12:31 +0200 Subject: [PATCH 0129/1427] [services] make snmp.timer work again and delay telemetry.service (#3657) Signed-off-by: Stepan Blyschak --- files/build_templates/snmp.service.j2 | 2 -- files/build_templates/sonic_debian_extension.j2 | 6 ++++-- files/build_templates/telemetry.service.j2 | 2 -- files/build_templates/telemetry.timer | 9 +++++++++ 4 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 files/build_templates/telemetry.timer diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index 310048e68beb..9d419b8e0dfd 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -14,5 +14,3 @@ ExecStop=/usr/bin/{{docker_container_name}}.sh stop Restart=always RestartSec=30 -[Install] -WantedBy=multi-user.target swss.service diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index d08aa7b6f1cc..9e8d4eb16a3e 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -317,7 +317,7 @@ EOF ## Bind docker path if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then sudo mkdir -p $FILESYSTEM_ROOT/dockerfs - sudo mount --bind dockerfs $FILESYSTEM_ROOT/dockerfs + sudo mount --bind dockerfs $FILESYSTEM_ROOT/dockerfs fi {% if installer_images.strip() -%} @@ -334,7 +334,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta {% endif %} {% endfor %} if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then - sudo umount $FILESYSTEM_ROOT/dockerfs + sudo umount $FILESYSTEM_ROOT/dockerfs sudo rm -fr $FILESYSTEM_ROOT/dockerfs sudo kill -9 `sudo $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS_PID` || true else @@ -362,6 +362,8 @@ sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer +sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable telemetry.timer sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-dev sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get clean -y diff --git a/files/build_templates/telemetry.service.j2 b/files/build_templates/telemetry.service.j2 index 2e7e45218df2..4d653e42327d 100644 --- a/files/build_templates/telemetry.service.j2 +++ b/files/build_templates/telemetry.service.j2 @@ -10,5 +10,3 @@ ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/telemetry.timer b/files/build_templates/telemetry.timer new file mode 100644 index 000000000000..e08f1c09eac6 --- /dev/null +++ b/files/build_templates/telemetry.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays telemetry container until SONiC has started + +[Timer] +OnBootSec=3min 30 sec +Unit=telemetry.service + +[Install] +WantedBy=timers.target From d5af096f417a1111bdfce09f939e0c00cfe43558 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 6 Nov 2019 16:07:28 -0800 Subject: [PATCH 0130/1427] [TSA]: Add community to the loopback prefix, when isolated (#3708) * Rename asn/deployment_id_asn_map.yaml to constants/constants.yaml * Fix bgp templates * Add community for loopback when bgpd is isolated * Use correct community value --- dockers/docker-fpm-frr/TSA | 16 ++++++++-------- dockers/docker-fpm-frr/TSB | 17 ++++++++--------- dockers/docker-fpm-frr/TSC | 8 ++++---- dockers/docker-fpm-frr/bgpd.conf.default.j2 | 2 +- dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 | 10 ++++++++++ .../docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 | 6 ++++++ dockers/docker-fpm-frr/start.sh | 4 ++-- dockers/docker-fpm-quagga/bgpd.conf.j2 | 2 +- dockers/docker-fpm-quagga/start.sh | 2 +- files/build_templates/sonic_debian_extension.j2 | 2 +- .../image_config/asn/deployment_id_asn_map.yml | 2 -- files/image_config/constants/constants.yml | 4 ++++ 12 files changed, 46 insertions(+), 29 deletions(-) create mode 100644 dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 create mode 100644 dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 delete mode 100644 files/image_config/asn/deployment_id_asn_map.yml create mode 100644 files/image_config/constants/constants.yml diff --git a/dockers/docker-fpm-frr/TSA b/dockers/docker-fpm-frr/TSA index abd629157901..1d74757b2d5f 100755 --- a/dockers/docker-fpm-frr/TSA +++ b/dockers/docker-fpm-frr/TSA @@ -3,20 +3,20 @@ c=0 config=$(vtysh -c "show run") echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$(($c+$?)) +c=$((c+$?)) if [[ $c -eq 4 ]]; then - vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V4 permit 2" -c "match ip address prefix-list PL_LoopbackV4" - vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V4 deny 3" - vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V6 permit 2" -c "match ipv6 address prefix-list PL_LoopbackV6" - vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V6 deny 3" + TSA_FILE=$(mktemp) + sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.tsa.isolate.conf.j2 > "$TSA_FILE" + vtysh -f "$TSA_FILE" + rm -f "$TSA_FILE" echo "System Mode: Normal -> Maintenance" else echo "System is already in Maintenance mode" diff --git a/dockers/docker-fpm-frr/TSB b/dockers/docker-fpm-frr/TSB index beb246bfc7f1..83ead86952c3 100755 --- a/dockers/docker-fpm-frr/TSB +++ b/dockers/docker-fpm-frr/TSB @@ -3,21 +3,20 @@ c=0 config=$(vtysh -c "show run") echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$(($c+$?)) +c=$((c+$?)) if [[ $c -eq 0 ]]; then - vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V4 deny 3" - vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V4 permit 2" - vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V6 deny 3" - vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V6 permit 2" - + TSB_FILE=$(mktemp) + sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.tsa.unisolate.conf.j2 > "$TSB_FILE" + vtysh -f "$TSB_FILE" + rm -f "$TSB_FILE" echo "System Mode: Maintenance -> Normal" else echo "System is already in Normal mode" diff --git a/dockers/docker-fpm-frr/TSC b/dockers/docker-fpm-frr/TSC index 7d0fb1004a7d..c79f4bb2a41b 100755 --- a/dockers/docker-fpm-frr/TSC +++ b/dockers/docker-fpm-frr/TSC @@ -4,13 +4,13 @@ echo "Traffic Shift Check:" c=0 config=$(vtysh -c "show run") echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$(($c+$?)) +c=$((c+$?)) if [[ $c -eq 4 ]]; then diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index 957c2792435f..b53e5dff6762 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -107,7 +107,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% if bgp_peer['peer_asn'] is defined %} neighbor {{ bgp_peer['name'] }} remote-as {{ bgp_peer['peer_asn'] }} {% else %} - neighbor {{ bgp_peer['name'] }} remote-as {{ deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} + neighbor {{ bgp_peer['name'] }} remote-as {{ constants.deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} {% endif %} neighbor {{ bgp_peer['name'] }} ebgp-multihop 255 neighbor {{ bgp_peer['name'] }} soft-reconfiguration inbound diff --git a/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 b/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 new file mode 100644 index 000000000000..9cd61b899071 --- /dev/null +++ b/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 @@ -0,0 +1,10 @@ +route-map TO_BGP_PEER_V4 permit 2 + match ip address prefix-list PL_LoopbackV4 + set community {{ constants.traffic_shift_community }} +route-map TO_BGP_PEER_V4 deny 3 +! +route-map TO_BGP_PEER_V6 permit 2 + match ipv6 address prefix-list PL_LoopbackV6 + set community {{ constants.traffic_shift_community }} +route-map TO_BGP_PEER_V6 deny 3 +! diff --git a/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 b/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 new file mode 100644 index 000000000000..25d7c49125e1 --- /dev/null +++ b/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 @@ -0,0 +1,6 @@ +no route-map TO_BGP_PEER_V4 permit 2 +no route-map TO_BGP_PEER_V4 deny 3 +! +no route-map TO_BGP_PEER_V6 permit 2 +no route-map TO_BGP_PEER_V6 deny 3 +! diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/start.sh index a1b0c0ea0b08..ad9beec766d3 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/start.sh @@ -5,13 +5,13 @@ mkdir -p /etc/frr CONFIG_TYPE=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["docker_routing_config_mode"]'` if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then - sonic-cfggen -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/frr/bgpd.conf + sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/frr/bgpd.conf sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/frr/zebra.conf sonic-cfggen -d -t /usr/share/sonic/templates/staticd.conf.j2 > /etc/frr/staticd.conf echo "no service integrated-vtysh-config" > /etc/frr/vtysh.conf rm -f /etc/frr/frr.conf elif [ "$CONFIG_TYPE" == "unified" ]; then - sonic-cfggen -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/frr.conf.j2 >/etc/frr/frr.conf + sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/frr.conf.j2 >/etc/frr/frr.conf echo "service integrated-vtysh-config" > /etc/frr/vtysh.conf rm -f /etc/frr/bgpd.conf /etc/frr/zebra.conf /etc/frr/staticd.conf fi diff --git a/dockers/docker-fpm-quagga/bgpd.conf.j2 b/dockers/docker-fpm-quagga/bgpd.conf.j2 index b69f895ccbed..2f4c741303a4 100644 --- a/dockers/docker-fpm-quagga/bgpd.conf.j2 +++ b/dockers/docker-fpm-quagga/bgpd.conf.j2 @@ -101,7 +101,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% if bgp_peer['peer_asn'] is defined %} neighbor {{ bgp_peer['name'] }} remote-as {{ bgp_peer['peer_asn'] }} {% else %} - neighbor {{ bgp_peer['name'] }} remote-as {{ deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} + neighbor {{ bgp_peer['name'] }} remote-as {{ constants.deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} {% endif %} neighbor {{ bgp_peer['name'] }} ebgp-multihop 255 neighbor {{ bgp_peer['name'] }} soft-reconfiguration inbound diff --git a/dockers/docker-fpm-quagga/start.sh b/dockers/docker-fpm-quagga/start.sh index 06fdd3bb3961..1ffda3d17732 100755 --- a/dockers/docker-fpm-quagga/start.sh +++ b/dockers/docker-fpm-quagga/start.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash mkdir -p /etc/quagga -sonic-cfggen -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/quagga/bgpd.conf +sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/quagga/bgpd.conf sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/quagga/zebra.conf diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 9e8d4eb16a3e..bd1dfccd28dc 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -235,7 +235,7 @@ sudo bash -c "echo '{ \"DEVICE_METADATA\": { \"localhost\": { \"default_bgp_stat sudo cp $IMAGE_CONFIGS/snmp/snmp.yml $FILESYSTEM_ROOT/etc/sonic/ # Copy ASN configuration files -sudo cp $IMAGE_CONFIGS/asn/deployment_id_asn_map.yml $FILESYSTEM_ROOT/etc/sonic/ +sudo cp $IMAGE_CONFIGS/constants/constants.yml $FILESYSTEM_ROOT/etc/sonic/ # Copy sudoers configuration file sudo cp $IMAGE_CONFIGS/sudoers/sudoers $FILESYSTEM_ROOT/etc/ diff --git a/files/image_config/asn/deployment_id_asn_map.yml b/files/image_config/asn/deployment_id_asn_map.yml deleted file mode 100644 index 36168f828954..000000000000 --- a/files/image_config/asn/deployment_id_asn_map.yml +++ /dev/null @@ -1,2 +0,0 @@ -deployment_id_asn_map: - "1" : 65432 diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml new file mode 100644 index 000000000000..3834717a8bfc --- /dev/null +++ b/files/image_config/constants/constants.yml @@ -0,0 +1,4 @@ +constants: + deployment_id_asn_map: + "1" : 65432 + traffic_shift_community: 12345:12345 From 95466c3ab74784f62e42a83ea7157c7957347b72 Mon Sep 17 00:00:00 2001 From: Neetha John Date: Wed, 6 Nov 2019 18:51:02 -0800 Subject: [PATCH 0131/1427] [pfcwd]: Do not start pfc watchdog on Management Tor (#3719) Signed-off-by: Neetha John --- files/image_config/updategraph/updategraph | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index dd8314b01221..2eb510afa4e1 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -15,7 +15,10 @@ reload_minigraph() acl-loader update full /etc/sonic/acl.json fi config qos reload - pfcwd start_default + DEVICE_TYPE=`sonic-cfggen -m -v DEVICE_METADATA.localhost.type` + if [ "${DEVICE_TYPE}" != "MgmtToRRouter" ]; then + pfcwd start_default + fi if [[ -x /usr/bin/db_migrator.py ]]; then # Set latest version number From 3b51cec9a38d964b1c9fbd67d44932f2714fd98f Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Thu, 7 Nov 2019 04:54:05 +0200 Subject: [PATCH 0132/1427] [barefoot] Added Newport platform support (#3709) [barefoot] Added Newport platform support Signed-off-by: Andriy Kokhan --- .../x86_64-accton_as9516bf_32d-r0/default_sku | 1 + .../installer.conf | 1 + .../newport/buffers.json.j2 | 2 + .../newport/buffers_defaults_t0.j2 | 71 + .../newport/buffers_defaults_t1.j2 | 71 + .../newport/pg_profile_lookup.ini | 20 + .../newport/port_config.ini | 33 + .../newport/qos.json.j2 | 10 + .../newport/sai.profile | 3 + .../newport/switch-tna-sai.conf | 40 + .../x86_64-accton_as9516bf_32d-r0/plugins | 1 + .../pmon_daemon_control.json | 6 + platform/barefoot/one-image.mk | 1 + .../barefoot/platform-modules-bfn-newport.mk | 13 + platform/barefoot/rules.mk | 1 + .../LICENSE | 15 + .../MAINTAINERS | 3 + .../README.md | 2 + .../configs/network/interfaces.d/usb0 | 5 + .../debian/changelog | 5 + .../debian/compat | 1 + .../debian/control | 12 + .../debian/copyright | 15 + .../debian/rules | 35 + .../modules/Makefile | 2 + .../modules/bf_fpga_ioctl.c | 196 +++ .../modules/bf_fpga_ioctl.h | 131 ++ .../modules/bf_fpga_main.c | 1294 +++++++++++++++++ .../modules/bf_fpga_priv.h | 141 ++ .../modules/bf_fpga_sysfs.c | 335 +++++ .../modules/i2c/bf_fpga_i2c.c | 516 +++++++ .../modules/i2c/bf_fpga_i2c.h | 55 + .../modules/i2c/bf_fpga_i2c_ctrl.c | 397 +++++ .../modules/i2c/bf_fpga_i2c_porting.c | 150 ++ .../modules/i2c/bf_fpga_i2c_priv.h | 104 ++ .../modules/i2c/bf_fpga_i2c_priv_porting.h | 93 ++ .../modules/i2c/bf_fpga_i2c_reg.h | 116 ++ .../scripts/bf-sfputil | 10 + .../scripts/eeprom | 10 + .../scripts/fancontrol | 11 + .../scripts/ps_info | 10 + .../scripts/sensors | 12 + .../scripts/test | 1 + 43 files changed, 3951 insertions(+) create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/default_sku create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/installer.conf create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers.json.j2 create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/pg_profile_lookup.ini create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/port_config.ini create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/qos.json.j2 create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/sai.profile create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf create mode 120000 device/barefoot/x86_64-accton_as9516bf_32d-r0/plugins create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json create mode 100644 platform/barefoot/platform-modules-bfn-newport.mk create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/LICENSE create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/MAINTAINERS create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/README.md create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/configs/network/interfaces.d/usb0 create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/debian/changelog create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/debian/control create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/debian/copyright create mode 100755 platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/Makefile create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.c create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.h create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_main.c create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_priv.h create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_sysfs.c create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.c create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.h create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_ctrl.c create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_porting.c create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv.h create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv_porting.h create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_reg.h create mode 100755 platform/barefoot/sonic-platform-modules-bfn-newport/scripts/bf-sfputil create mode 100755 platform/barefoot/sonic-platform-modules-bfn-newport/scripts/eeprom create mode 100755 platform/barefoot/sonic-platform-modules-bfn-newport/scripts/fancontrol create mode 100755 platform/barefoot/sonic-platform-modules-bfn-newport/scripts/ps_info create mode 100755 platform/barefoot/sonic-platform-modules-bfn-newport/scripts/sensors create mode 100755 platform/barefoot/sonic-platform-modules-bfn-newport/scripts/test diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/default_sku b/device/barefoot/x86_64-accton_as9516bf_32d-r0/default_sku new file mode 100644 index 000000000000..517fa893ae11 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/default_sku @@ -0,0 +1 @@ +newport t1 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/installer.conf b/device/barefoot/x86_64-accton_as9516bf_32d-r0/installer.conf new file mode 100644 index 000000000000..3714ff053bb0 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/installer.conf @@ -0,0 +1 @@ +CONSOLE_SPEED=57600 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers.json.j2 b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers.json.j2 new file mode 100644 index 000000000000..1083a6210fc9 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..199f4ad135fb --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 @@ -0,0 +1,71 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '4194304' %} +{% set ingress_lossy_pool_size = '7340032' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '7340032' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic", + "xoff": "2867200" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..01f50a4419e9 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 @@ -0,0 +1,71 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '2097152' %} +{% set ingress_lossy_pool_size = '5242880' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '5242880' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic", + "xoff": "2867200" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/pg_profile_lookup.ini b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/pg_profile_lookup.ini new file mode 100644 index 000000000000..602400325be0 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/pg_profile_lookup.ini @@ -0,0 +1,20 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 34816 18432 16384 7 + 25000 5m 34816 18432 16384 7 + 40000 5m 34816 18432 16384 7 + 50000 5m 34816 18432 16384 7 + 100000 5m 36864 18432 18432 7 + 400000 5m 36864 18432 18432 7 + 10000 40m 36864 18432 18432 7 + 25000 40m 39936 18432 21504 7 + 40000 40m 41984 18432 23552 7 + 50000 40m 41984 18432 23552 7 + 100000 40m 54272 18432 35840 7 + 400000 40m 54272 18432 35840 7 + 10000 300m 49152 18432 30720 7 + 25000 300m 71680 18432 53248 7 + 40000 300m 94208 18432 75776 7 + 50000 300m 94208 18432 75776 7 + 100000 300m 184320 18432 165888 7 + 400000 300m 184320 18432 165888 7 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/port_config.ini b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/port_config.ini new file mode 100644 index 000000000000..3a3be79dc675 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed autoneg fec +Ethernet0 0,1,2,3,4,5,6,7 Ethernet0 1 400000 0 rs +Ethernet8 8,9,10,11,12,13,14,15 Ethernet8 2 400000 0 rs +Ethernet16 16,17,18,19,20,21,22,23 Ethernet16 3 400000 0 rs +Ethernet24 24,25,26,27,28,29,30,31 Ethernet24 4 400000 0 rs +Ethernet32 32,33,34,35,36,37,38,39 Ethernet32 5 400000 0 rs +Ethernet40 40,41,42,43,44,45,46,47 Ethernet40 6 400000 0 rs +Ethernet48 48,49,50,51,52,53,54,55 Ethernet48 7 400000 0 rs +Ethernet56 56,57,58,59,60,61,62,63 Ethernet56 8 400000 0 rs +Ethernet64 64,65,66,67,68,69,70,71 Ethernet64 9 400000 0 rs +Ethernet72 72,73,74,75,76,77,78,79 Ethernet72 10 400000 0 rs +Ethernet80 80,81,82,83,84,85,86,87 Ethernet80 11 400000 0 rs +Ethernet88 88,89,90,91,92,93,94,95 Ethernet88 12 400000 0 rs +Ethernet96 96,97,98,99,100,101,102,103 Ethernet96 13 400000 0 rs +Ethernet104 104,105,106,107,108,109,110,111 Ethernet104 14 400000 0 rs +Ethernet112 112,113,114,115,116,117,118,119 Ethernet112 15 400000 0 rs +Ethernet120 120,121,122,123,124,125,126,127 Ethernet120 16 400000 0 rs +Ethernet128 128,129,130,131,132,133,134,135 Ethernet128 17 400000 0 rs +Ethernet136 136,137,138,139,140,141,142,143 Ethernet136 18 400000 0 rs +Ethernet144 144,145,146,147,148,149,150,151 Ethernet144 19 400000 0 rs +Ethernet152 152,153,154,155,156,157,158,159 Ethernet152 20 400000 0 rs +Ethernet160 160,161,162,163,164,165,166,167 Ethernet160 21 400000 0 rs +Ethernet168 168,169,170,171,172,173,174,175 Ethernet168 22 400000 0 rs +Ethernet176 176,177,178,179,180,181,182,183 Ethernet176 23 400000 0 rs +Ethernet184 184,185,186,187,188,189,190,191 Ethernet184 24 400000 0 rs +Ethernet192 192,193,194,195,196,197,198,199 Ethernet192 25 400000 0 rs +Ethernet200 200,201,202,203,204,205,206,207 Ethernet200 26 400000 0 rs +Ethernet208 208,209,210,211,212,213,214,215 Ethernet208 27 400000 0 rs +Ethernet216 216,217,218,219,220,221,222,223 Ethernet216 28 400000 0 rs +Ethernet224 224,225,226,227,228,229,230,231 Ethernet224 29 400000 0 rs +Ethernet232 232,233,234,235,236,237,238,239 Ethernet232 30 400000 0 rs +Ethernet240 240,241,242,243,244,245,246,247 Ethernet240 31 400000 0 rs +Ethernet248 248,249,250,251,252,253,254,255 Ethernet248 32 400000 0 rs diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/qos.json.j2 b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/qos.json.j2 new file mode 100644 index 000000000000..a685277448f1 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/qos.json.j2 @@ -0,0 +1,10 @@ +{%- macro generate_tc_to_pg_map() %} + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "3": "3", + "4": "4" + } + }, +{%- endmacro %} + +{%- include 'qos_config.j2' %} diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/sai.profile b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/sai.profile new file mode 100644 index 000000000000..037b5c135370 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/sai.profile @@ -0,0 +1,3 @@ +SAI_KEY_WARM_BOOT_WRITE_FILE=/var/warmboot/sai-warmboot.bin +SAI_KEY_WARM_BOOT_READ_FILE=/var/warmboot/sai-warmboot.bin + diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf new file mode 100644 index 000000000000..a1ee06da879c --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf @@ -0,0 +1,40 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino2", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "agent0": "lib/platform/x86_64-accton_as9516bf_32d-r0/libpltfm_mgr.so", + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/switch/pipe/tofino2.bin", + "context": "share/switch/pipe/context.json" + } + ], + "program-name": "switch", + "switchsai": "lib/libswitchsai.so", + "bfrt-config": "share/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/plugins b/device/barefoot/x86_64-accton_as9516bf_32d-r0/plugins new file mode 120000 index 000000000000..a8464d1ec2b6 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/plugins @@ -0,0 +1 @@ +../x86_64-accton_wedge100bf_32x-r0/plugins/ \ No newline at end of file diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..3a76f2fdd0e4 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json @@ -0,0 +1,6 @@ +{ + "skip_ledd": true, + "skip_xcvrd": false, + "skip_psud": false, + "skip_syseepromd": false +} diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index 36823baa8781..0147b62d00a1 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -7,6 +7,7 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MODULE) $(PYTHON_THRIFT) $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_NEWPORT_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9280_64X_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-bfn-newport.mk b/platform/barefoot/platform-modules-bfn-newport.mk new file mode 100644 index 000000000000..ff251ed1ddd7 --- /dev/null +++ b/platform/barefoot/platform-modules-bfn-newport.mk @@ -0,0 +1,13 @@ +# BFN Platform modules + +BFN_NEWPORT_PLATFORM_MODULE_VERSION = 1.0 + +export BFN_NEWPORT_PLATFORM_MODULE_VERSION + +BFN_NEWPORT_PLATFORM_MODULE = sonic-platform-modules-bfn-newport_$(BFN_NEWPORT_PLATFORM_MODULE_VERSION)_amd64.deb +$(BFN_NEWPORT_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-bfn-newport +$(BFN_NEWPORT_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(BFN_NEWPORT_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9516bf_32d-r0 +SONIC_DPKG_DEBS += $(BFN_NEWPORT_PLATFORM_MODULE) + +SONIC_STRETCH_DEBS += $(BFN_NEWPORT_PLATFORM_MODULE) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index ea718d10fc96..8a218b3ff169 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -1,6 +1,7 @@ include $(PLATFORM_PATH)/platform-modules-arista.mk include $(PLATFORM_PATH)/platform-modules-bfn.mk include $(PLATFORM_PATH)/platform-modules-bfn-montara.mk +include $(PLATFORM_PATH)/platform-modules-bfn-newport.mk include $(PLATFORM_PATH)/platform-modules-wnc-osw1800.mk include $(PLATFORM_PATH)/platform-modules-ingrasys.mk include $(PLATFORM_PATH)/bfn-sai.mk diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/LICENSE b/platform/barefoot/sonic-platform-modules-bfn-newport/LICENSE new file mode 100644 index 000000000000..676cdeec726b --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2016 Microsoft, Inc + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/MAINTAINERS b/platform/barefoot/sonic-platform-modules-bfn-newport/MAINTAINERS new file mode 100644 index 000000000000..85aa0cd77d72 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/MAINTAINERS @@ -0,0 +1,3 @@ +# This file describes the maintainers for sonic-platform-modules-bfn-newport +# See the SONiC project governance document for more information +Mailinglist = sonicproject@googlegroups.com diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/README.md b/platform/barefoot/sonic-platform-modules-bfn-newport/README.md new file mode 100644 index 000000000000..028adef715f3 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/README.md @@ -0,0 +1,2 @@ +# sonic-platform-modules-bfn-newport +Device drivers for support of BFN platform for the SONiC project diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/configs/network/interfaces.d/usb0 b/platform/barefoot/sonic-platform-modules-bfn-newport/configs/network/interfaces.d/usb0 new file mode 100644 index 000000000000..f1dd054cc6f6 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/configs/network/interfaces.d/usb0 @@ -0,0 +1,5 @@ +# BMC interface +auto usb0 +allow-hotplug usb0 +iface usb0 inet6 +up ifconfig usb0 txqueuelen 64 diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/changelog b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/changelog new file mode 100644 index 000000000000..98ecad42ac90 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/changelog @@ -0,0 +1,5 @@ +sonic-platform-modules-bfn-newport (1.0) unstable; urgency=low + + * Initial release + + -- Support Mon, 27 Sep 2019 18:00:00 -0800 diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat new file mode 100644 index 000000000000..45a4fb75db86 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat @@ -0,0 +1 @@ +8 diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control new file mode 100644 index 000000000000..edbc5b890c58 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -0,0 +1,12 @@ +Source: sonic-platform-modules-bfn-newport +Section: main +Priority: extra +Maintainer: Support +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: sonic-platform-modules-bfn-newport +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp + diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/copyright b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/copyright new file mode 100644 index 000000000000..ade42b7aa75a --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/copyright @@ -0,0 +1,15 @@ +Provides linux kernel driver for BF PCIe devices + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules new file mode 100755 index 000000000000..951069a6016a --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules @@ -0,0 +1,35 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +PACKAGE_NAME := sonic-platform-modules-bfn-newport +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MODULE_SRC := $(shell pwd)/modules +SCRIPT_SRC := $(shell pwd)/scripts +CONFIGS_SRC := $(shell pwd)/configs + +%: + dh $@ + +override_dh_auto_build: + make -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + +override_dh_auto_install: + dh_installdirs -p$(PACKAGE_NAME) $(KERNEL_SRC)/$(INSTALL_MOD_DIR) + cp $(MODULE_SRC)/*.ko debian/$(PACKAGE_NAME)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) + dh_installdirs -p$(PACKAGE_NAME) usr/local/bin + cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin + dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ + cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ + +override_dh_usrlocal: + +override_dh_pysupport: + +override_dh_clean: + dh_clean + rm -f $(MODULE_SRC)/*.o $(MODULE_SRC)/*.ko $(MODULE_SRC)/*.mod.c $(MODULE_SRC)/.*.cmd + rm -f $(MODULE_SRC)/Module.markers $(MODULE_SRC)/Module.symvers $(MODULE_SRC)/modules.order + rm -rf $(MODULE_SRC)/.tmp_versions + diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/Makefile b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/Makefile new file mode 100644 index 000000000000..732ffb1f3f6c --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := bf_fpga.o +bf_fpga-y := bf_fpga_main.o bf_fpga_ioctl.o bf_fpga_sysfs.o i2c/bf_fpga_i2c.o i2c/bf_fpga_i2c_ctrl.o i2c/bf_fpga_i2c_porting.o diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.c new file mode 100644 index 000000000000..b0792556caf6 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.c @@ -0,0 +1,196 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "bf_fpga_priv.h" +#include "bf_fpga_ioctl.h" +#include "i2c/bf_fpga_i2c.h" + +int bf_fpga_ioctl(struct bf_pci_dev *bfdev, + unsigned int cmd, + unsigned long arg) { + void *addr = (void __user *)arg; + int ret = -1; + + if (!bfdev || !addr) { + return -EFAULT; + } + + switch (cmd) { + case BF_FPGA_IOCTL_I2C_CTL: { + bf_fpga_i2c_ctl_t i2c_ctl; + bool busy; + + if (copy_from_user(&i2c_ctl, addr, sizeof(bf_fpga_i2c_ctl_t))) { + return -EFAULT; + } + switch (i2c_ctl.control_type) { + case BF_FPGA_I2C_START: + ret = fpga_i2c_start(i2c_ctl.inst_hndl.bus_id); + break; + case BF_FPGA_I2C_STOP: + ret = fpga_i2c_stop(i2c_ctl.inst_hndl.bus_id); + break; + case BF_FPGA_I2C_RESET: + ret = fpga_i2c_reset(i2c_ctl.inst_hndl.bus_id); + break; + case BF_FPGA_I2C_BUSY: + ret = fpga_i2c_is_busy(i2c_ctl.inst_hndl.bus_id, &busy); + if (ret == 0) { + if (copy_to_user(&(((bf_fpga_i2c_ctl_t *)addr)->is_busy), + &busy, + sizeof(busy))) { + return -EFAULT; + } + } + break; + case BF_FPGA_I2C_INST_EN: + ret = fpga_i2c_inst_en( + i2c_ctl.inst_hndl.bus_id, i2c_ctl.inst_hndl.inst_id, true); + break; + case BF_FPGA_I2C_INST_DIS: + ret = fpga_i2c_inst_en( + i2c_ctl.inst_hndl.bus_id, i2c_ctl.inst_hndl.inst_id, false); + break; + case BF_FPGA_I2C_INST_PMT: + break; + case BF_FPGA_I2C_INST_STOP_ON_ERR: + break; + case BF_FPGA_I2C_INST_INT_EN: + break; + default: + break; + } + break; + } + case BF_FPGA_IOCTL_I2C_SET_CLK: { + bf_fpga_i2c_set_clk_t i2c_clk; + if (copy_from_user(&i2c_clk, addr, sizeof(bf_fpga_i2c_set_clk_t))) { + return -EFAULT; + } + ret = fpga_i2c_set_clk(i2c_clk.bus_id, i2c_clk.clock_div); + break; + } + case BF_FPGA_IOCTL_I2C_ONETIME: { + bf_fpga_i2c_t i2c_op; + int i; + + if (copy_from_user(&i2c_op, addr, sizeof(bf_fpga_i2c_t))) { + return -EFAULT; + } + ret = fpga_i2c_oneshot(&i2c_op); + if (ret == 0) { + /* copy read data to user area */ + for (i = 0; i < i2c_op.num_i2c; i++) { + if (i2c_op.i2c_inst[i].rd_cnt) { + if (copy_to_user(&(((bf_fpga_i2c_t *)addr)->i2c_inst[i].rd_buf), + &i2c_op.i2c_inst[i].rd_buf, + i2c_op.i2c_inst[i].rd_cnt)) { + return -EFAULT; + } + } + } + } else { + printk(KERN_ERR + "fpga i2c ioctl oneshot bus %d error %d i2c_addr 0x%hhx:0x%hhx " + "i2c_status 0x%hhx:0x%hhx\n", + i2c_op.inst_hndl.bus_id, + ret, + i2c_op.i2c_inst[0].i2c_addr, + i2c_op.i2c_inst[1].i2c_addr, + i2c_op.i2c_inst[0].status, + i2c_op.i2c_inst[1].status); + } + break; + } + case BF_FPGA_IOCTL_I2C_ADD_PR: { + bf_fpga_i2c_t i2c_op; + if (copy_from_user(&i2c_op, addr, sizeof(bf_fpga_i2c_t))) { + return -EFAULT; + } + ret = fpga_i2c_pr_add(&i2c_op); + if (ret == 0) { + /* copy read data to user area */ + if (copy_to_user(&((bf_fpga_i2c_t *)addr)->inst_hndl.inst_id, + &i2c_op.inst_hndl.inst_id, + sizeof(i2c_op.inst_hndl.inst_id))) { + return -EFAULT; + } + } else { + printk(KERN_ERR "fpga i2c ioctl add-pr error %d on bus %d\n", + ret, + i2c_op.inst_hndl.bus_id); + } + break; + } + case BF_FPGA_IOCTL_I2C_DEL_PR: { + bf_fpga_i2c_t i2c_op; + if (copy_from_user(&i2c_op, addr, sizeof(bf_fpga_i2c_t))) { + return -EFAULT; + } + ret = fpga_i2c_del(&i2c_op); + if (ret != 0) { + printk(KERN_ERR "fpga i2c ioctl del-pr error %d on bus %d\n", + ret, + i2c_op.inst_hndl.bus_id); + } + break; + } + case BF_FPGA_IOCTL_I2C_RD_DATA: { + bf_fpga_i2c_rd_data_t i2c_rd_data; + /* get user supplied offset and rd_cnt */ + if (copy_from_user( + &i2c_rd_data, addr, offsetof(bf_fpga_i2c_rd_data_t, rd_buf))) { + return -EFAULT; + } + ret = fpga_i2c_data_read(i2c_rd_data.inst_hndl.bus_id, + i2c_rd_data.inst_hndl.inst_id, + i2c_rd_data.offset, + i2c_rd_data.rd_cnt, + i2c_rd_data.rd_buf); + if (ret == 0) { + if (copy_to_user(&(((bf_fpga_i2c_rd_data_t *)addr)->rd_buf), + &i2c_rd_data.rd_buf, + i2c_rd_data.rd_cnt)) { + return -EFAULT; + } + } else { + printk(KERN_ERR "fpga i2c ioctl rd-data error %d on bus %d inst %d\n", + ret, + i2c_rd_data.inst_hndl.bus_id, + i2c_rd_data.inst_hndl.inst_id); + } + break; + } + default: + return -EINVAL; + } + return ret; +} diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.h new file mode 100644 index 000000000000..4c5eb7bf0386 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.h @@ -0,0 +1,131 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#ifndef _BF_FPGA_IOCTL_H_ +#define _BF_FPGA_IOCTL_H_ + +#ifdef __KERNEL__ +#include +#else +#include + +#endif /* __KERNEL__ */ + +#define BF_FPGA_IOC_MAGIC 'f' +#define BF_I2C_FPGA_NUM_CTRL 34 +#define BF_FPGA_MAX_I2C_RD_DATA 128 +#define BF_FPGA_MAX_I2C_WR_DATA 129 + +/* i2c control types */ +#define BF_FPGA_I2C_START 1 +#define BF_FPGA_I2C_STOP 2 +#define BF_FPGA_I2C_BUSY 3 +#define BF_FPGA_I2C_INST_EN 4 +#define BF_FPGA_I2C_INST_DIS 5 +#define BF_FPGA_I2C_INST_PMT 6 +#define BF_FPGA_I2C_INST_STOP_ON_ERR 7 +#define BF_FPGA_I2C_INST_INT_EN 8 +#define BF_FPGA_I2C_RESET 9 + +/* i2c operation types */ +#define BF_FPGA_I2C_NOP 0 +#define BF_FPGA_I2C_WRITE \ + 1 /* / ..[max 129 bytes] */ +#define BF_FPGA_I2C_READ \ + 2 /* / ..[max 128 bytes] */ +#define BF_FPGA_I2C_ADDR_READ \ + 3 /* / / \ + */ + +#define FPGA_I2c_ONESHOT_BEGIN_INDEX 0 +#define FPGA_I2C_ONESHOT_NUM_INST 15 +#define FPGA_I2C_PERIODIC_BEGIN_INDEX (FPGA_I2C_ONESHOT_NUM_INST) +#define FPGA_I2C_PERIODIC_NUM_INST 16 +#define FPGA_I2C_NUM_INST \ + (FPGA_I2C_ONESHOT_NUM_INST + FPGA_I2C_PERIODIC_NUM_INST) +/* maximum i2c instructions that can be handled in one system call */ +#define BF_FPGA_I2C_MAX_NUM_INST 3 + +typedef struct bf_fpga_i2c_set_clk_s { + /* 0:100k, 1:400k, 2:1M, or: 125e6//3 */ + int clock_div; /* clock divider */ + unsigned char bus_id; /* controller index */ +} bf_fpga_i2c_set_clk_t; + +typedef struct bf_fpga_inst_hndl_s { + int inst_id; /* instruction index within the controller memory space */ + unsigned char bus_id; /* controller index */ + unsigned char status; +} bf_fpga_inst_hndl_t; + +typedef struct bf_fpga_i2c_inst_s { + bool preemt; + bool en; + unsigned char i2c_addr; /* i2c device address in 7 bit format */ + unsigned char i2c_type; /* type of i2c cycle */ + unsigned char delay; /* delay in TBD - microseconds before i2c transaction */ + unsigned char ctrl; + unsigned char wr_cnt; /* number of bytes to write (after i2c address) */ + unsigned char rd_cnt; /* number of bytes to read */ + union { + unsigned char + wr_buf[BF_FPGA_MAX_I2C_WR_DATA]; /* write data source buffer */ + unsigned char rd_buf[BF_FPGA_MAX_I2C_RD_DATA]; /* read data dest buffer */ + }; + unsigned char status; + unsigned char retry_cnt; /* if fpga maintains retry count */ + unsigned char mux; /* if fpga maintains internal MUX */ +} bf_fpga_i2c_inst_t; + +typedef struct bf_fpga_i2c_s { + unsigned char num_i2c; /* number of i2c operations */ + unsigned char one_time; /* one time or periodic */ + bf_fpga_inst_hndl_t inst_hndl; + bf_fpga_i2c_inst_t i2c_inst[BF_FPGA_I2C_MAX_NUM_INST]; +} bf_fpga_i2c_t; + +typedef struct bf_fpga_i2c_rd_data_s { + bf_fpga_inst_hndl_t inst_hndl; + unsigned char offset; + unsigned char rd_cnt; + unsigned char rd_buf[BF_FPGA_MAX_I2C_RD_DATA]; +} bf_fpga_i2c_rd_data_t; + +typedef struct bf_fpga_i2c_ctl_s { + bf_fpga_inst_hndl_t inst_hndl; + unsigned char control_type; /* start, stop, reset, enable, disable or busy */ + bool is_busy; +} bf_fpga_i2c_ctl_t; + +#define BF_FPGA_IOCTL_I2C_CTL _IOWR(BF_FPGA_IOC_MAGIC, 0, bf_fpga_i2c_ctl_t) +#define BF_FPGA_IOCTL_I2C_ONETIME _IOWR(BF_FPGA_IOC_MAGIC, 1, bf_fpga_i2c_t) +#define BF_FPGA_IOCTL_I2C_ADD_PR _IOWR(BF_FPGA_IOC_MAGIC, 2, bf_fpga_i2c_t) +#define BF_FPGA_IOCTL_I2C_DEL_PR _IOWR(BF_FPGA_IOC_MAGIC, 3, bf_fpga_i2c_t) +#define BF_FPGA_IOCTL_I2C_RD_DATA \ + _IOWR(BF_FPGA_IOC_MAGIC, 4, bf_fpga_i2c_rd_data_t) +#define BF_FPGA_IOCTL_I2C_SET_CLK \ + _IOW(BF_FPGA_IOC_MAGIC, 5, bf_fpga_i2c_set_clk_t) + +#endif /* _BF_FPGA_IOCTL_H_ */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_main.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_main.c new file mode 100644 index 000000000000..563cc5120df1 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_main.c @@ -0,0 +1,1294 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +/* bf_fpga kernel module + * + * This is kernel mode driver for BF FPGA chip. + * Provides user space mmap service and user space "wait for interrupt", + * "enable interrupt" and i2c services + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bf_fpga_ioctl.h" + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +#include +#else +#include +#endif +#include +#include +#include +#include "bf_fpga_priv.h" +#include "i2c/bf_fpga_i2c_reg.h" +#include "i2c/bf_fpga_i2c.h" + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0) +//#error unsupported linux kernel version +#endif + +/* TBD: Need to build with CONFIG_PCI_MSI */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) +#if defined(RHEL_RELEASE_CODE) +#else +extern int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); +#endif /* defined(RHEL_RELEASE_CODE) */ +extern int pci_enable_msix(struct pci_dev *dev, + struct msix_entry *entries, + int nvec); +#else +extern int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); +extern int pci_enable_msix_range(struct pci_dev *dev, + struct msix_entry *entries, + int minvec, + int maxvec); +#endif + +/* Keep any global information here that must survive even after the + * bf_pci_dev is free-ed up. + */ +struct bf_global { + struct bf_pci_dev *bfdev; + struct cdev *bf_cdev; + struct fasync_struct *async_queue; +}; + +static int bf_major; +static int bf_minor[BF_FPGA_MAX_DEVICE_CNT] = {0}; +static struct class *bf_class = NULL; +static char *intr_mode = NULL; + +static enum bf_intr_mode bf_intr_mode_default = BF_INTR_MODE_NONE; +static spinlock_t bf_nonisr_lock; + +/* dev->minor should index into this array */ +static struct bf_global bf_global[BF_FPGA_MAX_DEVICE_CNT]; + +static void bf_add_listener(struct bf_pci_dev *bfdev, + struct bf_listener *listener) { + struct bf_listener **cur_listener = &bfdev->listener_head; + + if (!listener) { + return; + } + spin_lock(&bf_nonisr_lock); + + while (*cur_listener) { + cur_listener = &((*cur_listener)->next); + } + *cur_listener = listener; + listener->next = NULL; + + spin_unlock(&bf_nonisr_lock); +} + +static void bf_remove_listener(struct bf_pci_dev *bfdev, + struct bf_listener *listener) { + struct bf_listener **cur_listener = &bfdev->listener_head; + + /* in case of certain error conditions, this function might be called after + * bf_pci_remove() + */ + if (!bfdev || !listener) { + return; + } + spin_lock(&bf_nonisr_lock); + + if (*cur_listener == listener) { + *cur_listener = listener->next; + } else { + while (*cur_listener) { + if ((*cur_listener)->next == listener) { + (*cur_listener)->next = listener->next; + break; + } + cur_listener = &((*cur_listener)->next); + } + listener->next = NULL; + } + + spin_unlock(&bf_nonisr_lock); +} + +/* a pool of minor numbers is maintained */ +/* return the first available minor number */ +static int bf_get_next_minor_no(int *minor) { + int i; + + spin_lock(&bf_nonisr_lock); + for (i = 0; i < BF_FPGA_MAX_DEVICE_CNT; i++) { + if (bf_minor[i] == 0) { + *minor = i; + bf_minor[i] = 1; /* mark it as taken */ + spin_unlock(&bf_nonisr_lock); + return 0; + } + } + *minor = -1; + spin_unlock(&bf_nonisr_lock); + return -1; +} + +/* return a minor number back to the pool for recycling */ +static int bf_return_minor_no(int minor) { + int err; + + spin_lock(&bf_nonisr_lock); + if (bf_minor[minor] == 0) { /* was already returned */ + err = -1; /* don't change anything, but return error */ + } else { + bf_minor[minor] = 0; /* mark it as available */ + err = 0; + } + spin_unlock(&bf_nonisr_lock); + return err; +} + +static inline struct bf_pci_dev *bf_get_pci_dev(struct bf_dev_info *info) { + return container_of(info, struct bf_pci_dev, info); +} + +/* + * It masks the msix on/off of generating MSI-X messages. + */ +static void bf_msix_mask_irq(struct msi_desc *desc, int32_t state) { + u32 mask_bits = desc->masked; + unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL; + + if (state != 0) { + mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; + } else { + mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; + } + + if (mask_bits != desc->masked) { + writel(mask_bits, desc->mask_base + offset); + readl(desc->mask_base); + desc->masked = mask_bits; + } +} + +/** + * irqcontrol can be used to disable/enable interrupt from user space processes. + * + * @param bf_dev + * pointer to bf_pci_dev + * @param irq_state + * state value. 1 to enable interrupt, 0 to disable interrupt. + * + * @return + * - On success, 0. + * - On failure, a negative value. + */ +static int bf_pci_irqcontrol(struct bf_pci_dev *bfdev, s32 irq_state) { + struct pci_dev *pdev = bfdev->pdev; + + pci_cfg_access_lock(pdev); + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + pci_intx(pdev, !!irq_state); + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + struct msi_desc *desc; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) + list_for_each_entry(desc, &pdev->msi_list, list) + bf_msix_mask_irq(desc, irq_state); +#else + for_each_pci_msi_entry(desc, pdev) bf_msix_mask_irq(desc, irq_state); +#endif + } + pci_cfg_access_unlock(pdev); + + return 0; +} + +/** + * interrupt handler which will check if the interrupt is from the right + * device. If so, disable it here and will be enabled later. + */ +static irqreturn_t bf_pci_irqhandler(int irq, struct bf_pci_dev *bfdev) { + /* Legacy mode need to mask in hardware */ + if (bfdev->mode == BF_INTR_MODE_LEGACY && + !pci_check_and_mask_intx(bfdev->pdev)) { + return IRQ_NONE; + } + + /* NOTE : if bfdev->info.pci_error_state == 1, then do not access the + * device and return IRQ_NOTHANDLED. + */ + return IRQ_HANDLED; +} + +/* Remap pci resources described by bar #pci_bar */ +static int bf_pci_setup_iomem(struct pci_dev *dev, + struct bf_dev_info *info, + int n, + int pci_bar, + const char *name) { + unsigned long addr, len; + void *internal_addr; + + if (sizeof(info->mem) / sizeof(info->mem[0]) <= n) { + return -EINVAL; + } + + addr = pci_resource_start(dev, pci_bar); + len = pci_resource_len(dev, pci_bar); + if (addr == 0 || len == 0) { + return -1; + } + internal_addr = pci_ioremap_bar(dev, pci_bar); + if (internal_addr == NULL) { + return -1; + } + info->mem[n].name = name; + info->mem[n].addr = addr; + info->mem[n].internal_addr = internal_addr; + info->mem[n].size = len; + return 0; +} + +/* Unmap previously ioremap'd resources */ +static void bf_pci_release_iomem(struct bf_dev_info *info) { + int i; + + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (info->mem[i].internal_addr) { + iounmap(info->mem[i].internal_addr); + } + } +} + +static int bf_setup_bars(struct pci_dev *dev, struct bf_dev_info *info) { + int i, iom, ret; + unsigned long flags; + static const char *bar_names[BF_MAX_BAR_MAPS] = { + "BAR0", "BAR1", "BAR2", "BAR3", "BAR4", "BAR5", + }; + + iom = 0; + + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (pci_resource_len(dev, i) != 0 && pci_resource_start(dev, i) != 0) { + flags = pci_resource_flags(dev, i); + if (flags & IORESOURCE_MEM) { + ret = bf_pci_setup_iomem(dev, info, iom, i, bar_names[i]); + if (ret != 0) { + return ret; + } + iom++; + } + } + } + return (iom != 0) ? ret : -ENOENT; +} + +static irqreturn_t bf_interrupt(int irq, void *bfdev_id) { + struct bf_pci_dev *bfdev = ((struct bf_int_vector *)bfdev_id)->bf_dev; + int vect_off = ((struct bf_int_vector *)bfdev_id)->int_vec_offset; + + irqreturn_t ret = bf_pci_irqhandler(irq, bfdev); + + if (ret == IRQ_HANDLED) { + atomic_inc(&(bfdev->info.event[vect_off])); + } + return ret; +} + +static unsigned int bf_poll(struct file *filep, poll_table *wait) { + struct bf_listener *listener = (struct bf_listener *)filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + int i; + + if (!bfdev) { + return -ENODEV; + } + if (!bfdev->info.irq) { + return -EIO; + } + + poll_wait(filep, &bfdev->info.wait, wait); + + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + if (listener->event_count[i] != atomic_read(&bfdev->info.event[i])) { + return POLLIN | POLLRDNORM; + } + } + return 0; +} + +static int bf_find_mem_index(struct vm_area_struct *vma) { + struct bf_pci_dev *bfdev = vma->vm_private_data; + if (vma->vm_pgoff < BF_MAX_BAR_MAPS) { + if (bfdev->info.mem[vma->vm_pgoff].size == 0) { + return -1; + } + return (int)vma->vm_pgoff; + } + return -1; +} + +static const struct vm_operations_struct bf_physical_vm_ops = { +#ifdef CONFIG_HAVE_IOREMAP_PROT + .access = generic_access_phys, +#endif +}; + +static int bf_mmap_physical(struct vm_area_struct *vma) { + struct bf_pci_dev *bfdev = vma->vm_private_data; + int bar = bf_find_mem_index(vma); + struct bf_dev_mem *mem; + if (bar < 0) { + return -EINVAL; + } + + mem = bfdev->info.mem + bar; + + if (mem->addr & ~PAGE_MASK) { + return -ENODEV; + } + if (vma->vm_end - vma->vm_start > mem->size) { + return -EINVAL; + } + + vma->vm_ops = &bf_physical_vm_ops; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + /* + * We cannot use the vm_iomap_memory() helper here, + * because vma->vm_pgoff is the map index we looked + * up above in bf_find_mem_index(), rather than an + * actual page offset into the mmap. + * + * So we just do the physical mmap without a page + * offset. + */ + return remap_pfn_range(vma, + vma->vm_start, + mem->addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); +} + +static int bf_mmap(struct file *filep, struct vm_area_struct *vma) { + struct bf_listener *listener = filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + int bar; + unsigned long requested_pages, actual_pages; + + if (!bfdev) { + return -ENODEV; + } + if (vma->vm_end < vma->vm_start) { + return -EINVAL; + } + + vma->vm_private_data = bfdev; + + bar = bf_find_mem_index(vma); + if (bar < 0) { + return -EINVAL; + } + + requested_pages = vma_pages(vma); + actual_pages = ((bfdev->info.mem[bar].addr & ~PAGE_MASK) + + bfdev->info.mem[bar].size + PAGE_SIZE - 1) >> + PAGE_SHIFT; + if (requested_pages > actual_pages) { + return -EINVAL; + } + + return bf_mmap_physical(vma); +} + +static int bf_fasync(int fd, struct file *filep, int mode) { + int minor; + + if (!filep->private_data) { + return (-EINVAL); + } + minor = ((struct bf_listener *)filep->private_data)->minor; + if (minor >= BF_FPGA_MAX_DEVICE_CNT) { + return (-EINVAL); + } + if (mode == 0 && &bf_global[minor].async_queue == NULL) { + return 0; /* nothing to do */ + } + return (fasync_helper(fd, filep, mode, &bf_global[minor].async_queue)); +} + +static int bf_open(struct inode *inode, struct file *filep) { + struct bf_pci_dev *bfdev; + struct bf_listener *listener; + int i; + + bfdev = bf_global[iminor(inode)].bfdev; + listener = kmalloc(sizeof(*listener), GFP_KERNEL); + if (listener) { + listener->bfdev = bfdev; + listener->minor = bfdev->info.minor; + listener->next = NULL; + bf_add_listener(bfdev, listener); + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + listener->event_count[i] = atomic_read(&bfdev->info.event[i]); + } + filep->private_data = listener; + return 0; + } else { + return (-ENOMEM); + } +} + +static int bf_release(struct inode *inode, struct file *filep) { + struct bf_listener *listener = filep->private_data; + + bf_fasync(-1, filep, 0); /* empty any process id in the notification list */ + if (listener->bfdev) { + bf_remove_listener(listener->bfdev, listener); + } + kfree(listener); + return 0; +} + +/* user space support: make read() system call after poll() of select() */ +static ssize_t bf_read(struct file *filep, + char __user *buf, + size_t count, + loff_t *ppos) { + struct bf_listener *listener = filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + int retval, event_count[BF_MSIX_ENTRY_CNT]; + int i, mismatch_found = 0; /* OR of per vector mismatch */ + unsigned char cnt_match[BF_MSIX_ENTRY_CNT]; /* per vector mismatch */ + + if (!bfdev) { + return -ENODEV; + } + /* irq must be setup for read() to work */ + if (!bfdev->info.irq) { + return -EIO; + } + + /* ensure that there is enough space on user buffer for the given interrupt + * mode */ + if (bfdev->mode == BF_INTR_MODE_MSIX) { + if (count < sizeof(s32) * BF_MSIX_ENTRY_CNT) { + return -EINVAL; + } + count = sizeof(s32) * BF_MSIX_ENTRY_CNT; + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + if (count < sizeof(s32) * BF_MSI_ENTRY_CNT) { + return -EINVAL; + } + count = sizeof(s32) * BF_MSI_ENTRY_CNT; + } else { + if (count < sizeof(s32)) { + return -EINVAL; + } + count = sizeof(s32); + } + + do { + set_current_state(TASK_INTERRUPTIBLE); + + for (i = 0; i < (count / sizeof(s32)); i++) { + event_count[i] = atomic_read(&(bfdev->info.event[i])); + if (event_count[i] != listener->event_count[i]) { + mismatch_found |= 1; + cnt_match[i] = 1; + } else { + event_count[i] = 0; + cnt_match[i] = 0; + } + } + if (mismatch_found) { + __set_current_state(TASK_RUNNING); + if (copy_to_user(buf, &event_count, count)) { + retval = -EFAULT; + } else { /* adjust the listener->event_count; */ + for (i = 0; i < (count / sizeof(s32)); i++) { + if (cnt_match[i]) { + listener->event_count[i] = event_count[i]; + } + } + retval = count; + } + break; + } + + if (filep->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + break; + } + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + schedule(); + } while (1); + + __set_current_state(TASK_RUNNING); + + return retval; +} + +/* user space is supposed to call this after it is done with interrupt + * processing + */ +static ssize_t bf_write(struct file *filep, + const char __user *buf, + size_t count, + loff_t *ppos) { + struct bf_listener *listener = filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + ssize_t ret; + s32 int_en; + + if (!bfdev || !bfdev->info.irq) { + return -EIO; + } + + if (count != sizeof(s32)) { + return -EINVAL; + } + + if (copy_from_user(&int_en, buf, count)) { + return -EFAULT; + } + + /* clear pci_error_state */ + bfdev->info.pci_error_state = 0; + + ret = bf_pci_irqcontrol(bfdev, int_en); + + return ret ? ret : sizeof(s32); +} + +static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { + struct bf_listener *listener = filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + + return (bf_fpga_ioctl(bfdev, cmd, arg)); +} + +static const struct file_operations bf_fops = { + .owner = THIS_MODULE, + .open = bf_open, + .release = bf_release, + .unlocked_ioctl = bf_ioctl, + .read = bf_read, + .write = bf_write, + .mmap = bf_mmap, + .poll = bf_poll, + .fasync = bf_fasync, +}; + +static int bf_major_init(struct bf_pci_dev *bfdev, int minor) { + struct cdev *cdev; + static const char name[] = "bf_fpga"; + dev_t bf_dev = 0; + int result; + + result = alloc_chrdev_region(&bf_dev, 0, BF_FPGA_MAX_DEVICE_CNT, name); + if (result) { + return result; + } + + result = -ENOMEM; + cdev = cdev_alloc(); + if (!cdev) { + goto fail_dev_add; + } + cdev->ops = &bf_fops; + cdev->owner = THIS_MODULE; + kobject_set_name(&cdev->kobj, "%s", name); + result = cdev_add(cdev, bf_dev, BF_FPGA_MAX_DEVICE_CNT); + + if (result) { + goto fail_dev_add; + } + + bf_major = MAJOR(bf_dev); + bf_global[minor].bf_cdev = cdev; + return 0; + +fail_dev_add: + unregister_chrdev_region(bf_dev, BF_FPGA_MAX_DEVICE_CNT); + return result; +} + +static void bf_major_cleanup(struct bf_pci_dev *bfdev, int minor) { + unregister_chrdev_region(MKDEV(bf_major, 0), BF_FPGA_MAX_DEVICE_CNT); + cdev_del(bf_global[minor].bf_cdev); +} + +static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) { + int ret; + ret = bf_major_init(bfdev, minor); + if (ret) return ret; + + bf_class = class_create(THIS_MODULE, BF_CLASS_NAME); + if (!bf_class) { + printk(KERN_ERR "create_class failed for bf_fpga_dev\n"); + ret = -ENODEV; + goto err_class_register; + } + return 0; + +err_class_register: + bf_major_cleanup(bfdev, minor); + return ret; +} + +static void bf_remove_cdev(struct bf_pci_dev *bfdev) { + class_destroy(bf_class); + bf_major_cleanup(bfdev, bfdev->info.minor); +} + +/** + * bf_register_device - register a new userspace mem device + * @parent: parent device + * @bfdev: bf pci device + * + * returns zero on success or a negative error code. + */ +int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) { + struct bf_dev_info *info = &bfdev->info; + int i, j, ret = 0; + int minor; + + if (!parent || !info || !info->version) { + return -EINVAL; + } + + init_waitqueue_head(&info->wait); + + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + atomic_set(&info->event[i], 0); + } + + if (bf_get_next_minor_no(&minor)) { + return -EINVAL; + } + + ret = bf_init_cdev(bfdev, minor); + if (ret) { + printk(KERN_ERR "BFi_FPGA: device cdev creation failed\n"); + return ret; + } + + info->dev = device_create( + bf_class, parent, MKDEV(bf_major, minor), bfdev, "bf_fpga_%d", minor); + if (!info->dev) { + printk(KERN_ERR "BF_FPGA: device creation failed\n"); + return -ENODEV; + } + + info->minor = minor; + + /* bind ISRs and request interrupts */ + if (info->irq && (bfdev->mode != BF_INTR_MODE_NONE)) { + /* + * Note that we deliberately don't use devm_request_irq + * here. The parent module can unregister the UIO device + * and call pci_disable_msi, which requires that this + * irq has been freed. However, the device may have open + * FDs at the time of unregister and therefore may not be + * freed until they are released. + */ + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + ret = request_irq(info->irq, + bf_interrupt, + info->irq_flags, + bfdev->name, + (void *)&(bfdev->bf_int_vec[0])); + if (ret) { + printk(KERN_ERR "bf_fpga failed to request legacy irq %ld error %d\n", + info->irq, + ret); + return ret; + } + printk(KERN_NOTICE "BF_FPGA allocating legacy int vector %ld\n", + info->irq); + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + for (i = 0; i < info->num_irq; i++) { + ret = request_irq(info->msix_entries[i].vector, + bf_interrupt, + info->irq_flags, + bfdev->name, + (void *)&(bfdev->bf_int_vec[i])); + if (ret) { + /* undo all other previous bindings */ + printk(KERN_ERR "bf_fpga failed to request MSIX ret %d itr %d\n", + ret, + i); + for (j = i - 1; j >= 0; j--) { + free_irq(info->msix_entries[j].vector, + (void *)&(bfdev->bf_int_vec[j])); + } + return ret; + } + } + printk(KERN_NOTICE "BF_FPGA allocating %d MSIx vectors from %ld\n", + info->num_irq, + info->irq); + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + for (i = 0; i < info->num_irq; i++) { + ret = request_irq(info->irq + i, + bf_interrupt, + info->irq_flags, + bfdev->name, + (void *)&(bfdev->bf_int_vec[i])); + if (ret) { + /* undo all other previous bindings */ + printk( + KERN_ERR "bf_fpga failed to request MSI ret %d itr %d\n", ret, i); + for (j = i - 1; j >= 0; j--) { + free_irq(info->irq + j, (void *)&(bfdev->bf_int_vec[j])); + } + return ret; + } + } + printk(KERN_NOTICE "BF_FPGA allocating %d MSI vectors from %ld\n", + info->num_irq, + info->irq); + } + } + return 0; +} + +/** + * bf_unregister_device - register a new userspace mem device + * @bfdev: bf pci device + * + * returns none + */ +void bf_unregister_device(struct bf_pci_dev *bfdev) { + struct bf_dev_info *info = &bfdev->info; + int i; + + if (info->irq) { + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + free_irq(info->irq, (void *)&(bfdev->bf_int_vec[0])); + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + for (i = 0; i < info->num_irq; i++) { + free_irq(info->msix_entries[i].vector, (void *)&(bfdev->bf_int_vec[i])); + } + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + for (i = 0; i < info->num_irq; i++) { + free_irq(info->irq + i, (void *)&(bfdev->bf_int_vec[i])); + } + } + } + device_destroy(bf_class, MKDEV(bf_major, info->minor)); + bf_remove_cdev(bfdev); + bf_return_minor_no(info->minor); + return; +} + +static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) { + return &pdev->dev; +} + +static void bf_fpga_disable_int_dma(struct bf_pci_dev *bfdev) { + u8 *bf_base_addr; + + /* maskinterrupts and DMA */ + bf_base_addr = (bfdev->info.mem[0].internal_addr); + /* return if called before mmap */ + if (!bf_base_addr) { + return; + } + /* mask interrupt at shadow level */ + /* TBD */ +} + +static void fpga_print_build_date(u32 build_date) { + char day, month, year, hr, min, sec; + + sec = (char)(build_date & 0x3f); + build_date >>= 6; + min = (char)(build_date & 0x3f); + build_date >>= 6; + hr = (char)(build_date & 0x1f); + build_date >>= 5; + year = (char)(build_date & 0x3f); + build_date >>= 6; + month = (char)(build_date & 0x0f); + build_date >>= 4; + day = (char)(build_date & 0x1f); + printk(KERN_ALERT "fpga version %02d/%02d/%2d %02d:%02d:%02d", + month, + day, + year, + hr, + min, + sec); +} + +static int bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct bf_pci_dev *bfdev; + int err, pci_use_highmem; + int i, num_irq; + u32 build_date, build_ver; + + memset(bf_global, 0, sizeof(bf_global)); + + bfdev = kzalloc(sizeof(struct bf_pci_dev), GFP_KERNEL); + if (!bfdev) { + return -ENOMEM; + } + + /* init the cookies to be passed to ISRs */ + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + bfdev->bf_int_vec[i].int_vec_offset = i; + bfdev->bf_int_vec[i].bf_dev = bfdev; + } + + /* initialize intr_mode to none */ + bfdev->mode = BF_INTR_MODE_NONE; + + /* clear pci_error_state */ + bfdev->info.pci_error_state = 0; + + /* + * enable device + */ + err = pci_enable_device(pdev); + if (err != 0) { + printk(KERN_ERR "bf_fpga cannot enable PCI device\n"); + goto fail_free; + } + + /* + * reserve device's PCI memory regions for use by this + * module + */ + err = pci_request_regions(pdev, "bf_fpga_umem"); + if (err != 0) { + printk(KERN_ERR "bf_fpga Cannot request regions\n"); + goto fail_pci_disable; + } + /* remap IO memory */ + err = bf_setup_bars(pdev, &bfdev->info); + if (err != 0) { + printk(KERN_ERR "bf_fpga Cannot setup BARs\n"); + goto fail_release_iomem; + } + + if (!dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64)) && + !dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64))) { + pci_use_highmem = 1; + } else { + err = dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32)); + if (err) { + err = dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32)); + if (err) { + printk(KERN_ERR "bf_fpga no usable DMA configuration, aborting\n"); + goto fail_release_iomem; + } + } + pci_use_highmem = 0; + } + + /* enable pci error reporting */ + /* for the current kernel version, kernel config must have set the followings: + * CONFIG_PCIEPORTBUS=y and CONFIG_PCIEAER = y + * we have pci_error_handlers defined that gets invoked by kernel AER module + * upon detecting the pcie error on this device's addresses. + * However, there seems no way that AER would pass the offending addresses + * to the callback functions. AER logs the error messages on the console. + * This driver's calback function send the SIGIO signal to the user space + * to indicate the error condition. + */ + pci_enable_pcie_error_reporting(pdev); + + bf_fpga_disable_int_dma(bfdev); + + /* enable bus mastering on the device */ + pci_set_master(pdev); + + /* fill in bfdev info */ + bfdev->info.version = "0.1"; + bfdev->info.owner = THIS_MODULE; + bfdev->pdev = pdev; + + switch (bf_intr_mode_default) { +#ifdef CONFIG_PCI_MSI + case BF_INTR_MODE_MSIX: + /* Only 1 msi-x vector needed */ + bfdev->info.msix_entries = + kcalloc(BF_MSIX_ENTRY_CNT, sizeof(struct msix_entry), GFP_KERNEL); + if (!bfdev->info.msix_entries) { + err = -ENOMEM; + goto fail_clear_pci_master; + } + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + bfdev->info.msix_entries[i].entry = i; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) + num_irq = + pci_enable_msix(pdev, bfdev->info.msix_entries, BF_MSIX_ENTRY_CNT); + if (num_irq == 0) { + bfdev->info.num_irq = BF_MSIX_ENTRY_CNT; + bfdev->info.irq = bfdev->info.msix_entries[0].vector; + bfdev->mode = BF_INTR_MODE_MSIX; + printk(KERN_DEBUG "bf_fpga using %d MSIX irq from %ld\n", + num_irq, + bfdev->info.irq); + break; + } +#else + num_irq = pci_enable_msix_range( + pdev, bfdev->info.msix_entries, BF_MSIX_ENTRY_CNT, BF_MSIX_ENTRY_CNT); + if (num_irq == BF_MSIX_ENTRY_CNT) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = bfdev->info.msix_entries[0].vector; + bfdev->mode = BF_INTR_MODE_MSIX; + printk(KERN_DEBUG "bf_fpga using %d MSIX irq from %ld\n", + num_irq, + bfdev->info.irq); + break; + } else { + if (num_irq) pci_disable_msix(pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + printk(KERN_ERR + "bf_fpga error allocating MSIX vectors. Trying MSI...\n"); + /* and, fall back to MSI */ + } +#endif /* LINUX_VERSION_CODE */ + /* ** intentional no-break */ + case BF_INTR_MODE_MSI: +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) + num_irq = pci_enable_msi_block(pdev, BF_MSI_ENTRY_CNT); + /* we must get requested number of MSI vectors enabled */ + if (num_irq == 0) { + bfdev->info.num_irq = BF_MSI_ENTRY_CNT; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf_fpga using %d MSI irq from %ld\n", + bfdev->info.num_irq, + bfdev->info.irq); + break; + } +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) + num_irq = pci_enable_msi_range(pdev, BF_MSI_ENTRY_CNT, BF_MSI_ENTRY_CNT); + if (num_irq > 0) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf_fpga using %d MSI irq from %ld\n", + bfdev->info.num_irq, + bfdev->info.irq); + break; + } +#else + num_irq = pci_alloc_irq_vectors_affinity(pdev, + BF_MSI_ENTRY_CNT, + BF_MSI_ENTRY_CNT, + PCI_IRQ_MSI | PCI_IRQ_AFFINITY, + NULL); + if (num_irq > 0) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pci_irq_vector(pdev, 0); + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf_fpga using %d MSI irq from %ld\n", + bfdev->info.num_irq, + bfdev->info.irq); + break; + } +#endif /* LINUX_VERSION_CODE */ +#endif /* CONFIG_PCI_MSI */ + /* fall back to Legacy Interrupt, intentional no-break */ + + case BF_INTR_MODE_LEGACY: + if (pci_intx_mask_supported(pdev)) { + bfdev->info.irq_flags = IRQF_SHARED; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_LEGACY; + printk(KERN_DEBUG "bf_fpga using LEGACY irq %ld\n", bfdev->info.irq); + break; + } + printk(KERN_NOTICE "bf_fpga PCI INTx mask not supported\n"); + /* fall back to no Interrupt, intentional no-break */ + case BF_INTR_MODE_NONE: + bfdev->info.irq = 0; + bfdev->info.num_irq = 0; + bfdev->mode = BF_INTR_MODE_NONE; + break; + + default: + printk(KERN_DEBUG "bf_fpga invalid IRQ mode %u", bf_intr_mode_default); + err = -EINVAL; + goto fail_clear_pci_master; + } + + pci_set_drvdata(pdev, bfdev); + sprintf(bfdev->name, "bf_fpga%d", bfdev->info.minor); + /* register bf driver */ + err = bf_register_device(&pdev->dev, bfdev); + if (err != 0) { + goto fail_release_irq; + } + + bf_global[bfdev->info.minor].async_queue = NULL; + bf_global[bfdev->info.minor].bfdev = bfdev; + + dev_info(&pdev->dev, + "bf_fpga device %d registered with irq %ld\n", + bfdev->instance, + bfdev->info.irq); + if (fpga_i2c_init(bfdev->info.mem[0].internal_addr)) { + printk(KERN_ERR "bf_fpga i2c initialization failed\n"); + goto fail_register_device; + } + if (bf_fpga_sysfs_add(bfdev)) { + printk(KERN_ERR "bf_fpga stsfs initialization failed\n"); + goto fail_i2c_init; + } + build_ver = + *((u32 *)(bfdev->info.mem[0].internal_addr) + (BF_FPGA_VER_REG / 4)); + build_date = + *((u32 *)(bfdev->info.mem[0].internal_addr) + (BF_FPGA_BUILD_DATE / 4)); + fpga_print_build_date(build_date); + printk(KERN_ALERT "bf_fpga version %hu:%hu probe ok\n", + (u16)(build_ver >> 16), + (u16)(build_ver)); + return 0; + +fail_i2c_init: + fpga_i2c_deinit(); +fail_register_device: + bf_unregister_device(bfdev); +fail_release_irq: + pci_set_drvdata(pdev, NULL); + if (bfdev->mode == BF_INTR_MODE_MSIX) { + pci_disable_msix(bfdev->pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + pci_disable_msi(bfdev->pdev); + } +fail_clear_pci_master: + pci_clear_master(pdev); +fail_release_iomem: + bf_pci_release_iomem(&bfdev->info); + pci_release_regions(pdev); +fail_pci_disable: + pci_disable_device(pdev); +fail_free: + kfree(bfdev); + + printk(KERN_ERR "bf_fpga probe failed\n"); + return err; +} + +static void bf_pci_remove(struct pci_dev *pdev) { + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + struct bf_listener *cur_listener; + + bf_fpga_disable_int_dma(bfdev); + bf_fpga_sysfs_del(bfdev); + fpga_i2c_deinit(); + bf_unregister_device(bfdev); + if (bfdev->mode == BF_INTR_MODE_MSIX) { + pci_disable_msix(pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + pci_disable_msi(pdev); + } + pci_clear_master(pdev); + bf_pci_release_iomem(&bfdev->info); + pci_release_regions(pdev); + pci_disable_pcie_error_reporting(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + bf_global[bfdev->info.minor].bfdev = NULL; + /* existing filep structures in open file(s) must be informed that + * bf_pci_dev is no longer valid */ + spin_lock(&bf_nonisr_lock); + cur_listener = bfdev->listener_head; + while (cur_listener) { + cur_listener->bfdev = NULL; + cur_listener = cur_listener->next; + } + spin_unlock(&bf_nonisr_lock); + kfree(bfdev); + printk(KERN_ALERT "bf_fpga removed\n"); +} + +/** + * bf_pci_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device + * @state: The current pci connection state + * + * called when root complex detects pci error associated with the device + */ +static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) { + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + int minor; + + if (!bfdev) { + return PCI_ERS_RESULT_NONE; + } + printk(KERN_ERR "bf_fpga pci_err_detected state %d\n", state); + if (state == pci_channel_io_perm_failure || state == pci_channel_io_frozen) { + bfdev->info.pci_error_state = 1; + /* send a signal to the user space program of the error */ + minor = bfdev->info.minor; + if (minor < BF_FPGA_MAX_DEVICE_CNT && bf_global[minor].async_queue) { + kill_fasync(&bf_global[minor].async_queue, SIGIO, POLL_ERR); + } + return PCI_ERS_RESULT_DISCONNECT; + } else { + return PCI_ERS_RESULT_NONE; + } +} + +/** + * bf_pci_slot_reset - called after the pci bus has been reset. + * @pdev: Pointer to PCI device + * + * Restart the card from scratch, as if from a cold-boot. + */ +static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) { + /* nothing to do for now as we do not expect to get backto normal after + * a pcie link reset + * TBD: fill in this function if tofino can recover after an error + */ + return PCI_ERS_RESULT_DISCONNECT; +} + +/** + * bf_pci_resume - called when kernel thinks the device is up on PCIe. + * @pdev: Pointer to PCI device + * + * This callback is called when the error recovery driver tells us that + * its OK to resume normal operation. + */ +static void bf_pci_resume(struct pci_dev *pdev) { + /* this function should never be called for BF FPGA */ + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + + printk(KERN_ERR "BF_FPGA io_resume invoked after pci error\n"); + if (bfdev) { + bfdev->info.pci_error_state = 0; + } +} + +static int bf_config_intr_mode(char *intr_str) { + if (!intr_str) { + pr_info("BF_FPGA Use MSI interrupt by default\n"); + return 0; + } + + if (!strcmp(intr_str, BF_INTR_MODE_MSIX_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_MSIX; + pr_info("BF_FPGA Use MSIX interrupt\n"); + } else if (!strcmp(intr_str, BF_INTR_MODE_MSI_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_MSI; + pr_info("BF_FPGA Use MSI interrupt\n"); + } else if (!strcmp(intr_str, BF_INTR_MODE_LEGACY_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_LEGACY; + pr_info("BF_FPGA Use legacy interrupt\n"); + } else if (!strcmp(intr_str, BF_INTR_MODE_NONE_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_NONE; + pr_info("BF_FPGA interrupt disabled\n"); + } else { + pr_info("Error: BF_FPGA bad intr_mode parameter - %s\n", intr_str); + return -EINVAL; + } + + return 0; +} + +static const struct pci_device_id bf_pci_tbl[] = { + {PCI_VDEVICE(BF, BF_FPGA_DEV_ID_JBAY_0), 0}, + /* required last entry */ + {.device = 0}}; + +/* PCI bus error handlers */ +static struct pci_error_handlers bf_pci_err_handler = { + .error_detected = bf_pci_error_detected, + .slot_reset = bf_pci_slot_reset, + .resume = bf_pci_resume, +}; + +static struct pci_driver bf_pci_driver = {.name = "bf_fpga", + .id_table = bf_pci_tbl, + .probe = bf_pci_probe, + .remove = bf_pci_remove, + .err_handler = &bf_pci_err_handler}; + +static int __init bfdrv_init(void) { + int ret; + + ret = bf_config_intr_mode(intr_mode); + if (ret < 0) { + return ret; + } + spin_lock_init(&bf_nonisr_lock); + return pci_register_driver(&bf_pci_driver); +} + +static void __exit bfdrv_exit(void) { + pci_unregister_driver(&bf_pci_driver); + intr_mode = NULL; +} + +module_init(bfdrv_init); +module_exit(bfdrv_exit); + +module_param(intr_mode, charp, S_IRUGO); +MODULE_PARM_DESC(intr_mode, + "bf-fpga interrupt mode (default=none):\n" + " " BF_INTR_MODE_MSIX_NAME + " Use MSIX interrupt\n" + " " BF_INTR_MODE_MSI_NAME + " Use MSI interrupt\n" + " " BF_INTR_MODE_LEGACY_NAME + " Use Legacy interrupt\n" + " " BF_INTR_MODE_NONE_NAME + " Use no interrupt\n" + "\n"); + +MODULE_DEVICE_TABLE(pci, bf_pci_tbl); +MODULE_DESCRIPTION("Barefoot FPGA PCI-I2C device"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0.1"); +MODULE_AUTHOR("Barefoot Networks"); diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_priv.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_priv.h new file mode 100644 index 000000000000..7515bde7458d --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_priv.h @@ -0,0 +1,141 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#ifndef _BF_FPGA_H_ +#define _BF_FPGA_H_ + +#define PCI_VENDOR_ID_BF 0x1d1c +#define BF_FPGA_DEV_ID_JBAY_0 0x01F0 + +#ifndef PCI_MSIX_ENTRY_SIZE +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR 4 +#define PCI_MSIX_ENTRY_DATA 8 +#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#endif + +#define BF_CLASS_NAME "bf_fpga" +#define BF_FPGA_MAX_DEVICE_CNT 1 +#define BF_INTR_MODE_NONE_NAME "none" +#define BF_INTR_MODE_LEGACY_NAME "legacy" +#define BF_INTR_MODE_MSI_NAME "msi" +#define BF_INTR_MODE_MSIX_NAME "msix" +#define BF_MAX_BAR_MAPS 6 +#define BF_MSIX_ENTRY_CNT 1 +#define BF_MSI_ENTRY_CNT 1 + +/* sysfs codes */ +#define BF_SYSFS_NEW_DEVICE 1 +#define BF_SYSFS_RM_DEVICE 0 +#define BF_SYSFS_I2C_START 2 + +/* interrupt mode */ +enum bf_intr_mode { + BF_INTR_MODE_NONE = 0, + BF_INTR_MODE_LEGACY, + BF_INTR_MODE_MSI, + BF_INTR_MODE_MSIX +}; + +/* device memory */ +struct bf_dev_mem { + const char *name; + phys_addr_t addr; + resource_size_t size; + void __iomem *internal_addr; +}; + +struct bf_listener { + struct bf_pci_dev *bfdev; + s32 event_count[BF_MSIX_ENTRY_CNT]; + int minor; + struct bf_listener *next; +}; + +/* device information */ +struct bf_dev_info { + struct module *owner; + struct device *dev; + int minor; + atomic_t event[BF_MSIX_ENTRY_CNT]; + wait_queue_head_t wait; + const char *version; + struct bf_dev_mem mem[BF_MAX_BAR_MAPS]; + struct msix_entry *msix_entries; + long irq; /* first irq vector */ + int num_irq; /* number of irq vectors */ + unsigned long irq_flags; /* sharable ?? */ + int pci_error_state; /* was there a pci bus error */ +}; + +/* cookie to be passed to IRQ handler, useful especially with MSIX */ +struct bf_int_vector { + struct bf_pci_dev *bf_dev; + int int_vec_offset; +}; + +/* sysfs related structs */ +#define BF_FPGA_SYSFS_CNT 64 +#define BF_FPGA_SYSFS_NAME_SIZE 32 + +struct bf_fpga_sysfs_buff { + struct device_attribute dev_attr; + char name[BF_FPGA_SYSFS_NAME_SIZE]; + int bus_id; + unsigned char i2c_addr; + size_t i2c_rd_size; /* bytes to read from the device */ + int sysfs_code; /* unique code for each sysfs file */ + struct bf_pci_dev *fpgadev; /* back pointer */ + bool in_use; +}; + +/** + * structure describing the private information for a BF pcie device. + */ +struct bf_pci_dev { + struct bf_dev_info info; + struct pci_dev *pdev; + enum bf_intr_mode mode; + u8 instance; + char name[16]; + struct bf_int_vector bf_int_vec[BF_MSIX_ENTRY_CNT]; + struct bf_listener * + listener_head; /* head of a singly linked list of listeners */ + struct bf_fpga_sysfs_buff fpga_sysfs_buff[BF_FPGA_SYSFS_CNT]; + struct bf_fpga_sysfs_buff fpga_sysfs_new_device; + struct bf_fpga_sysfs_buff fpga_sysfs_rm_device; + struct bf_fpga_sysfs_buff fpga_sysfs_st_i2c; + spinlock_t sysfs_slock; +}; + +int bf_fpga_ioctl(struct bf_pci_dev *bfdev, + unsigned int cmd, + unsigned long arg); +int bf_fpga_sysfs_add(struct bf_pci_dev *fpgadev); +void bf_fpga_sysfs_del(struct bf_pci_dev *fpgadev); + +#endif /* _BF_FPGA_H_ */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_sysfs.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_sysfs.c new file mode 100644 index 000000000000..6970a7a95985 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_sysfs.c @@ -0,0 +1,335 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#include +#include +#include +#include +#include +#include "bf_fpga_priv.h" +#include "bf_fpga_ioctl.h" +#include "i2c/bf_fpga_i2c.h" + +/* reads 1 byte from the i2c device */ +static ssize_t bf_fpga_sysfs_i2c_get(struct device *dev, + struct device_attribute *attr, + char *buf) { + bf_fpga_i2c_t i2c_op; + ssize_t size, cur_size; + struct bf_fpga_sysfs_buff *sysfs_buf = + container_of(attr, struct bf_fpga_sysfs_buff, dev_attr); + + if (!sysfs_buf) { + printk(KERN_ERR "fpga-i2c bad attr pointer in sysfs_read\n"); + return -ENXIO; /* something not quite right here; but, don't panic */ + } + i2c_op.num_i2c = 1; + i2c_op.one_time = 1; + i2c_op.inst_hndl.bus_id = sysfs_buf->bus_id; + i2c_op.i2c_inst[0].preemt = false; + i2c_op.i2c_inst[0].en = true; + i2c_op.i2c_inst[0].i2c_addr = sysfs_buf->i2c_addr; + i2c_op.i2c_inst[0].i2c_type = BF_FPGA_I2C_READ; + i2c_op.i2c_inst[0].delay = 0; + i2c_op.i2c_inst[0].wr_cnt = 0; + cur_size = sysfs_buf->i2c_rd_size; + /* limit to PAGE_SIZE per the sysfs contract */ + if (cur_size >= PAGE_SIZE) { + cur_size = PAGE_SIZE; + } + size = 0; + while (cur_size > 0) { + unsigned char cur_cnt; + if (cur_size > 64) { + cur_cnt = 64; + } else { + cur_cnt = (unsigned char)cur_size; + } + i2c_op.i2c_inst[0].rd_cnt = cur_cnt; + if (fpga_i2c_oneshot(&i2c_op)) { + printk(KERN_ERR + "fpga-i2c read one-shot error bus %d addr 0x%hhx status 0x%hhx\n", + i2c_op.inst_hndl.bus_id, + i2c_op.i2c_inst[0].i2c_addr, + i2c_op.i2c_inst[0].status); + return -EIO; + } + memcpy(buf, i2c_op.i2c_inst[0].rd_buf, cur_cnt); + buf += cur_cnt; + size += cur_cnt; + cur_size -= cur_cnt; + } + return size; +} + +/* write the number of bytes supplied to the i2c device, 1st byte has to be + the count(max 8) */ +static ssize_t bf_fpga_sysfs_i2c_set(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) { + bf_fpga_i2c_t i2c_op; + size_t size, cur_cnt; + struct bf_fpga_sysfs_buff *sysfs_buf = + container_of(attr, struct bf_fpga_sysfs_buff, dev_attr); + + if (!sysfs_buf || (count == 0)) { + printk(KERN_ERR "fpga-i2c bad attr pointer in sysfs_write\n"); + return -ENXIO; /* something not quite right here; but, don't panic */ + } + size = 0; + while (count > 0) { + if (count > 64) { + cur_cnt = 64; + } else { + cur_cnt = count; + } + i2c_op.i2c_inst[0].wr_cnt = cur_cnt; + i2c_op.i2c_inst[0].rd_cnt = 0; + memcpy(i2c_op.i2c_inst[0].wr_buf, buf, cur_cnt); + i2c_op.num_i2c = 1; + i2c_op.one_time = 1; + i2c_op.inst_hndl.bus_id = sysfs_buf->bus_id; + i2c_op.i2c_inst[0].preemt = false; + i2c_op.i2c_inst[0].en = true; + i2c_op.i2c_inst[0].i2c_addr = sysfs_buf->i2c_addr; + i2c_op.i2c_inst[0].i2c_type = BF_FPGA_I2C_WRITE; + i2c_op.i2c_inst[0].delay = 0; + if (fpga_i2c_oneshot(&i2c_op)) { + printk( + KERN_ERR + "fpga-i2c write one-shot error bus %d addr 0x%hhx status 0x%hhx\n", + i2c_op.inst_hndl.bus_id, + i2c_op.i2c_inst[0].i2c_addr, + i2c_op.i2c_inst[0].status); + return -EIO; + } + buf += cur_cnt; + size += cur_cnt; + count -= cur_cnt; + } + return size; +} + +static int find_matching_sysfs_buf(struct bf_pci_dev *fpgadev, + int bus_id, + unsigned char i2c_addr) { + int i; + + /* check if a sysfs entry already exists */ + for (i = 0; i < BF_FPGA_SYSFS_CNT; i++) { + if (fpgadev->fpga_sysfs_buff[i].bus_id == bus_id && + fpgadev->fpga_sysfs_buff[i].i2c_addr == i2c_addr) { + return i; + } + } + /* could not find a matching sysfs buffer */ + return -1; +} + +static ssize_t bf_fpga_sysfs_fixed_get(struct device *dev, + struct device_attribute *attr, + char *buf) { + (void)dev; + (void)attr; + (void)buf; + return -ENOSYS; +} + +static ssize_t bf_fpga_sysfs_fixed_set(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) { + struct bf_pci_dev *fpgadev; + int i, en, bus_id, ret, rd_size; + char fname[BF_FPGA_SYSFS_NAME_SIZE]; + unsigned char i2c_addr; + struct bf_fpga_sysfs_buff *new_buf; + struct bf_fpga_sysfs_buff *sysfs_buf = + container_of(attr, struct bf_fpga_sysfs_buff, dev_attr); + + if (!sysfs_buf || (count == 0)) { + printk(KERN_ERR "fpga i2c bad attr pointer in fixed_sysfs_write\n"); + return -ENXIO; /* something not quite right here; but, don't panic */ + } + fpgadev = sysfs_buf->fpgadev; + + switch (sysfs_buf->sysfs_code) { + case BF_SYSFS_NEW_DEVICE: /* new_device request */ + ret = sscanf(buf, "%s %d %hhx %d", fname, &bus_id, &i2c_addr, &rd_size); + /* default rd_size to 1 if not supplied or invalid */ + if (ret < 3) { + return -EINVAL; + } + if (ret < 4 || rd_size > PAGE_SIZE) { + rd_size = 1; + } + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || i2c_addr >= 0x80) { + return -EINVAL; + } + /* find out the free sysfs_buffer to use */ + spin_lock(&fpgadev->sysfs_slock); + if (find_matching_sysfs_buf(fpgadev, bus_id, i2c_addr) != -1) { + /* there is already an matching entry */ + spin_unlock(&fpgadev->sysfs_slock); + return -ENOSPC; + } + for (i = 0; i < BF_FPGA_SYSFS_CNT; i++) { + if (!fpgadev->fpga_sysfs_buff[i].in_use) { + fpgadev->fpga_sysfs_buff[i].in_use = true; + new_buf = &fpgadev->fpga_sysfs_buff[i]; + new_buf->i2c_addr = i2c_addr; + new_buf->i2c_rd_size = (size_t)rd_size; + new_buf->bus_id = bus_id; + break; + } + } + spin_unlock(&fpgadev->sysfs_slock); + if (i >= BF_FPGA_SYSFS_CNT) { + /* no free buffer available, return with ERROR */ + return -ENOSPC; + } + /* create a new sysfs entry now */ + new_buf->dev_attr.show = bf_fpga_sysfs_i2c_get; + new_buf->dev_attr.store = bf_fpga_sysfs_i2c_set; + new_buf->fpgadev = fpgadev; + new_buf->dev_attr.attr.mode = S_IWUSR | S_IRUGO; + new_buf->sysfs_code = 0; + snprintf(new_buf->name, BF_FPGA_SYSFS_NAME_SIZE, "%s", fname); + new_buf->dev_attr.attr.name = new_buf->name; + ret = device_create_file(&(fpgadev->pdev->dev), &new_buf->dev_attr); + break; + + case BF_SYSFS_RM_DEVICE: /* remove device request */ + ret = sscanf(buf, "%d %hhx", &bus_id, &i2c_addr); + if (ret < 2) { + return -EINVAL; + } + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || i2c_addr >= 0x80) { + return -EINVAL; + } + /* delete the sysfs file corresponding to the i2c address */ + spin_lock(&fpgadev->sysfs_slock); + i = find_matching_sysfs_buf(fpgadev, bus_id, i2c_addr); + if (i == -1) { + /* there is no matching entry */ + spin_unlock(&fpgadev->sysfs_slock); + return -EINVAL; + } + /* must invalidate bus_id and i2c_addr when marking the buffer + * not-in-use + */ + new_buf = &fpgadev->fpga_sysfs_buff[i]; + new_buf->i2c_addr = 0xff; + new_buf->bus_id = -1; + fpgadev->fpga_sysfs_buff[i].in_use = false; + spin_unlock(&fpgadev->sysfs_slock); + device_remove_file(&fpgadev->pdev->dev, &new_buf->dev_attr); + new_buf->name[0] = 0; /* nullify the name */ + ret = 0; + break; + + case BF_SYSFS_I2C_START: /* start-stop i2c request */ + ret = sscanf(buf, "%d %d", &bus_id, &en); + if (ret < 2) { + return -EINVAL; + } + if (bus_id >= BF_I2C_FPGA_NUM_CTRL) { + return -EINVAL; + } + if (en) { + ret = fpga_i2c_start(bus_id); + } else { + ret = fpga_i2c_stop(bus_id); + } + break; + + default: + ret = -EINVAL; + } + return ((ret == 0) ? count : ret); +} + +int bf_fpga_sysfs_add(struct bf_pci_dev *fpgadev) { + int rc = 0; + u8 *name; + + spin_lock_init(&fpgadev->sysfs_slock); + /* Add two sysfs files statically, new_device and remove_device. + * Handlers of these two fles can dynamically add more sysfs + * files (or remove files) based on the platform. + */ + fpgadev->fpga_sysfs_new_device.dev_attr.show = bf_fpga_sysfs_fixed_get; + fpgadev->fpga_sysfs_new_device.dev_attr.store = bf_fpga_sysfs_fixed_set; + fpgadev->fpga_sysfs_new_device.fpgadev = fpgadev; + fpgadev->fpga_sysfs_new_device.dev_attr.attr.mode = S_IWUSR | S_IRUGO; + fpgadev->fpga_sysfs_new_device.sysfs_code = BF_SYSFS_NEW_DEVICE; + name = fpgadev->fpga_sysfs_new_device.name; + snprintf(name, BF_FPGA_SYSFS_NAME_SIZE, "new_device"); + fpgadev->fpga_sysfs_new_device.dev_attr.attr.name = name; + rc |= device_create_file(&(fpgadev->pdev->dev), + &fpgadev->fpga_sysfs_new_device.dev_attr); + + fpgadev->fpga_sysfs_rm_device.dev_attr.show = bf_fpga_sysfs_fixed_get; + fpgadev->fpga_sysfs_rm_device.dev_attr.store = bf_fpga_sysfs_fixed_set; + fpgadev->fpga_sysfs_rm_device.fpgadev = fpgadev; + fpgadev->fpga_sysfs_rm_device.dev_attr.attr.mode = S_IWUSR | S_IRUGO; + fpgadev->fpga_sysfs_rm_device.sysfs_code = BF_SYSFS_RM_DEVICE; + name = fpgadev->fpga_sysfs_rm_device.name; + snprintf(name, BF_FPGA_SYSFS_NAME_SIZE, "remove_device"); + fpgadev->fpga_sysfs_rm_device.dev_attr.attr.name = name; + rc |= device_create_file(&(fpgadev->pdev->dev), + &fpgadev->fpga_sysfs_rm_device.dev_attr); + + /* sysfs for i2c start-stop control */ + fpgadev->fpga_sysfs_st_i2c.dev_attr.show = bf_fpga_sysfs_fixed_get; + fpgadev->fpga_sysfs_st_i2c.dev_attr.store = bf_fpga_sysfs_fixed_set; + fpgadev->fpga_sysfs_st_i2c.fpgadev = fpgadev; + fpgadev->fpga_sysfs_st_i2c.dev_attr.attr.mode = S_IWUSR | S_IRUGO; + fpgadev->fpga_sysfs_st_i2c.sysfs_code = BF_SYSFS_I2C_START; + name = fpgadev->fpga_sysfs_st_i2c.name; + snprintf(name, BF_FPGA_SYSFS_NAME_SIZE, "i2c_start"); + fpgadev->fpga_sysfs_st_i2c.dev_attr.attr.name = name; + rc |= device_create_file(&(fpgadev->pdev->dev), + &fpgadev->fpga_sysfs_st_i2c.dev_attr); + + return rc; +} + +void bf_fpga_sysfs_del(struct bf_pci_dev *fpgadev) { + int i; + + device_remove_file(&fpgadev->pdev->dev, + &fpgadev->fpga_sysfs_new_device.dev_attr); + device_remove_file(&fpgadev->pdev->dev, + &fpgadev->fpga_sysfs_rm_device.dev_attr); + device_remove_file(&fpgadev->pdev->dev, &fpgadev->fpga_sysfs_st_i2c.dev_attr); + for (i = 0; i < BF_FPGA_SYSFS_CNT; i++) { + if (fpgadev->fpga_sysfs_buff[i].in_use) { + device_remove_file(&fpgadev->pdev->dev, + &fpgadev->fpga_sysfs_buff[i].dev_attr); + } + } +} diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.c new file mode 100644 index 000000000000..1a622e5392d6 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.c @@ -0,0 +1,516 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#include +#include "bf_fpga_i2c_priv_porting.h" +#include +#include "bf_fpga_i2c_priv.h" +#include "bf_fpga_i2c.h" +#include "bf_fpga_i2c_reg.h" + +/* allocate find physically contiguous free blocks of instructions in one time + * or periodic area and mark them "in-use" */ +static int get_next_free_index(fpga_i2c_controller_t *i2c_ctrl, + int cnt, + bool pr) { + int i, j, begin, end; + + if (pr) { + begin = FPGA_I2C_PERIODIC_BEGIN_INDEX; + end = FPGA_I2C_NUM_INST; + } else { + begin = FPGA_I2c_ONESHOT_BEGIN_INDEX; + end = FPGA_I2C_ONESHOT_NUM_INST; + } + + bf_fpga_fast_lock(&i2c_ctrl->spinlock); + for (i = begin; i < end;) { + /* check if there are cnt number of free slots here */ + for (j = 0; j < cnt; j++) { + if (i2c_ctrl->i2c_inst[i + j].in_use) { + break; + } + } + if (j == cnt) { + /* we found enough free slots, so, return i */ + break; + } else { + /* we did not find enough free slots, continue searching */ + i += (j + 1); + continue; + } + } + if (i < end) { + for (j = 0; j < cnt; j++) { + i2c_ctrl->i2c_inst[i + j].in_use = true; + } + } else { + i = -1; + } + bf_fpga_fast_unlock(&i2c_ctrl->spinlock); + return i; +} + +/* free physically contiguous in-use blocks of instructions */ +static void release_index(fpga_i2c_controller_t *i2c_ctrl, + int inst_id, + int cnt) { + int i; + + if (inst_id < 0 || (inst_id + cnt) >= FPGA_I2C_NUM_INST) { + return; /* invalid id */ + } + bf_fpga_fast_lock(&i2c_ctrl->spinlock); + for (i = inst_id; i < (inst_id + cnt); i++) { + i2c_ctrl->i2c_inst[i].in_use = false; + } + bf_fpga_fast_unlock(&i2c_ctrl->spinlock); +} + +/* convert miroseconds to i2c-instruction delay parameter */ +static int us_to_fpga_delay(int microsec) { + int delay; + + if (microsec < 10) { + delay = 0; + } else if (microsec < 100) { + delay = 1; + } else if (microsec < 1000) { + delay = 2; + } else if (microsec < 10000) { + delay = 3; + } else if (microsec < 100000) { + delay = 4; + } else if (microsec < 1000000) { + delay = 5; + } else { + delay = 6; + } + return delay; +} + +/* populate single i2c_instruction at the given instruction slot */ +static int fpga_i2c_enqueue(int bus_id, + int inst_id, + bf_fpga_i2c_inst_t *i2c_inst) { + fpga_i2c_controller_t *i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + int delay = us_to_fpga_delay(i2c_inst->delay); + uint32_t wd0 = 0, wd1 = 0; + uint32_t i2c_data[2]; + uint8_t i2c_addr, num_wr, num_rd; + + i2c_addr = i2c_inst->i2c_addr; + num_wr = i2c_inst->wr_cnt; + num_rd = i2c_inst->rd_cnt; + if (i2c_addr > 0x7F || num_wr > 129 || num_rd > 128) { + return BF_FPGA_EINVAL; + } + if (i2c_inst->preemt) { + wd0 |= I2C_INST_PMT; + } + if (i2c_inst->en) { + wd0 |= I2C_INST_EN; + } + i2c_data[0] = i2c_data[1] = 0; /* clear on init */ + switch (i2c_inst->i2c_type) { + case BF_FPGA_I2C_NOP: + /* add delay + enable */ + wd0 |= (I2C_NOP | (delay << I2C_DELAY_SHF)); + break; + case BF_FPGA_I2C_WRITE: + if (num_wr == 0) { + return BF_FPGA_EINVAL; + } + wd0 |= (I2C_WR_ADDR_DATA | (delay << I2C_DELAY_SHF)); + wd1 |= (i2c_inst->i2c_addr << I2C_DEV_ADDR_SHF); + /* copy the first byte into register address */ + wd1 |= ((i2c_inst->wr_buf[0]) << I2C_CMD_OFFSET); + wd1 |= ((num_wr - 1) << I2C_WR_CNT_SHF); + if (num_wr <= 9) { + /* copy data into instruction area */ + memcpy(i2c_data, &i2c_inst->wr_buf[1], (num_wr - 1)); + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_LO(inst_id), i2c_data[0]); + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_HI(inst_id), i2c_data[1]); + } else { + /* copy the data in data area */ + int len = num_wr - 1; + uint32_t addr; + uint8_t *val = (uint8_t *)(&i2c_inst->wr_buf[1]); + /* store the data pointer Note the indexing required by FPGA specs */ + i2c_data[0] = BF_FPGA_I2C_DATA_AREA(inst_id); + addr = i2c_data[0]; + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_LO(inst_id), i2c_data[0] / 4); + /* do byte write to avoid endianness mismatch */ + while (len--) { + bf_fpga_i2c_reg_write8(i2c_ctrl, addr, *val); + addr++; + val++; + } + } + break; + case BF_FPGA_I2C_READ: + if (num_rd == 0) { + return BF_FPGA_EINVAL; + } + wd0 |= (I2C_RD_DATA | (delay << I2C_DELAY_SHF)); + wd1 |= (i2c_inst->i2c_addr << I2C_DEV_ADDR_SHF); + wd1 |= ((num_rd) << I2C_RD_CNT_SHF); + if (num_rd > 8) { + /* store the data area pointer */ + i2c_data[0] = BF_FPGA_I2C_DATA_AREA(inst_id); + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_LO(inst_id), i2c_data[0] / 4); + } + break; + case BF_FPGA_I2C_ADDR_READ: + if (num_wr == 0 || num_rd == 0) { + return BF_FPGA_EINVAL; + } + wd0 |= (I2C_RD_ADDR_DATA_BURST | (delay << I2C_DELAY_SHF)); + wd1 |= (i2c_inst->i2c_addr << I2C_DEV_ADDR_SHF); + /* 1st byte of the write buf goes into "register address" field */ + wd1 |= ((num_wr - 1) << I2C_WR_CNT_SHF); + wd1 |= ((i2c_inst->wr_buf[0]) << I2C_CMD_OFFSET); + wd1 |= ((num_rd) << I2C_RD_CNT_SHF); + /* less than 8 bytes data goes to the instruction area */ + if ((num_wr - 1 + num_rd) <= 8) { + memcpy(i2c_data, &i2c_inst->wr_buf[1], (num_wr - 1)); + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_LO(inst_id), i2c_data[0]); + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_HI(inst_id), i2c_data[1]); + } else { + int len = num_wr - 1; + uint32_t addr; + uint8_t *val = (uint8_t *)(&i2c_inst->wr_buf[1]); + /* store the data area pointer */ + i2c_data[0] = BF_FPGA_I2C_DATA_AREA(inst_id); + addr = i2c_data[0]; + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_LO(inst_id), i2c_data[0] / 4); + /* copy the data in data area */ + while (len--) { + bf_fpga_i2c_reg_write8(i2c_ctrl, addr, *val); + addr++; + val++; + } + } + break; + default: + return BF_FPGA_EINVAL; + } + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_PARAM(inst_id), wd1); + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(inst_id), wd0); + return BF_FPGA_OK; +} + +/* get the i2c completion status of a particular instruction */ +static uint32_t fpga_i2c_get_status(int bus_id, int inst_id) { + fpga_i2c_controller_t *i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + uint32_t addr = Bf_FPGA_I2C_INST_CTRL(inst_id); + return (bf_fpga_i2c_reg_read32(i2c_ctrl, addr) & I2C_STATUS_MASK); +} + +/** FPGA I2C data read (assumes locked by caller and no need to stop i2c) + * + * read the data following a read type i2c operation + * + * @param bus_id + * i2c controller id + * @param inst_id + * instruction id within this controller space + * @param offset + * offset in the data-area where read-data is available + * @param num_rd + * number of bytes to read + * @param rd_buf + * buffer to read into + * @return + * 0 on success and <0 on error + */ +static int fpga_i2c_data_read_locked(fpga_i2c_controller_t *i2c_ctrl, + int inst_id, + uint8_t offset, + uint8_t num_rd, + uint8_t *rd_buf) { + uint8_t i; + uint32_t addr, data_cnt; + + if (!i2c_ctrl || !rd_buf || !num_rd || inst_id < 0 || + inst_id >= FPGA_I2C_NUM_INST) { + return BF_FPGA_EINVAL; + } + /* find out the wr_cnt + rd_cnt from the already executed instruction field */ + data_cnt = bf_fpga_i2c_reg_read32(i2c_ctrl, Bf_FPGA_I2C_INST_PARAM(inst_id)); + /* point to data area if the (wr_cnt + rd_cnt) > 8 */ + data_cnt &= 0xffff; /* retain only the length fields */ + if (((data_cnt & 0xff) + (data_cnt >> 8)) <= 8) { + addr = Bf_FPGA_I2C_INST_DATA_LO(inst_id) + offset; + } else { + addr = BF_FPGA_I2C_DATA_AREA(inst_id) + offset; + } + for (i = 0; i < num_rd; i++) { + *rd_buf = bf_fpga_i2c_reg_read8(i2c_ctrl, addr); + addr++; + rd_buf++; + } + return BF_FPGA_OK; +} + +/** FPGA I2C data read + * + * read the data following a read type i2c operation + * + * @param bus_id + * i2c controller id + * @param inst_id + * instruction id within this controller space + * @param offset + * offset in the data-area where read-data is available + * @param num_rd + * number of bytes to read + * @param rd_buf + * buffer to read into + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_data_read( + int bus_id, int inst_id, uint8_t offset, uint8_t num_rd, uint8_t *rd_buf) { + fpga_i2c_controller_t *i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + int ret; + bool i2c_running; + uint8_t val; + + if (!i2c_ctrl || !rd_buf || !num_rd || inst_id < 0 || + inst_id >= FPGA_I2C_NUM_INST) { + return BF_FPGA_EINVAL; + } + + /* aligned (upto) 4 bytes can be read without stopping the ongoing i2c, + * this is guaranteed by FPGA design. i2c has to be stopped, in all other + * cases, to read a consistent set of read-data. + */ + if ((offset % 4 == 0) && (num_rd <= 4)) { + return ( + fpga_i2c_data_read_locked(i2c_ctrl, inst_id, offset, num_rd, rd_buf)); + } + + /* non-aligned case; stop i2c if running, read data and restart i2c */ + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + /* check if i2c_controller is running */ + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_TOP_I2C_STATUS); + i2c_running = ((val & I2C_STS_BUSY) ? true : false); + if (i2c_running) { + /* stop ongoing i2c operations */ + fpga_i2c_stop_locked(i2c_ctrl); + } + ret = fpga_i2c_data_read_locked(i2c_ctrl, inst_id, offset, num_rd, rd_buf); + if (i2c_running) { + /* restart ongoing i2c operations */ + fpga_i2c_start_locked(i2c_ctrl); + } + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; +} + +/** FPGA I2C onetime i2c operation + * + * @param i2c_op + * bf_fpga_i2c_t parameters * + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_oneshot(bf_fpga_i2c_t *i2c_op) { + int i, ret; + uint32_t val; + int bus_id; + fpga_i2c_controller_t *i2c_ctrl; + + if (!i2c_op) { + return BF_FPGA_EINVAL; + } + + bus_id = i2c_op->inst_hndl.bus_id; + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + + if (i2c_op->num_i2c == 0 || i2c_op->num_i2c >= FPGA_I2C_ONESHOT_NUM_INST || + i2c_op->one_time == 0 || bus_id >= BF_I2C_FPGA_NUM_CTRL || !i2c_ctrl) { + return BF_FPGA_EINVAL; + } + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + /* stop ongoing i2c operations */ + ret = fpga_i2c_stop_locked(i2c_ctrl); + if (ret) { + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; + } + /* populate one time i2c operation instruction(s) from offset zero */ + for (i = 0; i < i2c_op->num_i2c; i++) { + ret = fpga_i2c_enqueue(bus_id, i, &i2c_op->i2c_inst[i]); + if (ret) { + goto oneshot_error_exit; + } + } + /* start i2c operations */ + ret = fpga_i2c_start_locked(i2c_ctrl); + if (ret) { + goto oneshot_error_exit; + } + + /* wait until complete and read the data if necessary */ + for (i = 0; i < i2c_op->num_i2c; i++) { + int cnt; + val = 0; + /* cnt is roughly the number of bytes of this i2c cycle + * overhead of 100 bytes for for worst case timeout, one + * should not hit that in normal working case + */ + cnt = i2c_op->i2c_inst[i].wr_cnt + i2c_op->i2c_inst[i].rd_cnt; + /* bump up the cnt for an i2c transaction containing some data + * for computing worst case timeout */ + if (cnt > 0) { + cnt = cnt + 100; + } + while (!(val & I2C_STATUS_COMPLETED) && (cnt-- > 0)) { + /* 1 byte ~= 10 bits takes 25 microsec on i2c cycle at 400khz */ + bf_fpga_us_delay(50); + val = fpga_i2c_get_status(bus_id, i); + } + i2c_op->i2c_inst[i].status = val; /* store the h/w status */ + if (val & I2C_STATUS_ERR_MASK) { + ret = BF_FPGA_EIO; + goto oneshot_error_exit; + } + if (i2c_op->i2c_inst[i].rd_cnt) { + uint8_t offset = 0; + if (i2c_op->i2c_inst[i].wr_cnt > 1) { + offset = i2c_op->i2c_inst[i].wr_cnt - 1; + } + if (fpga_i2c_data_read_locked(i2c_ctrl, + i, + offset, + i2c_op->i2c_inst[i].rd_cnt, + i2c_op->i2c_inst[i].rd_buf)) { + ret = BF_FPGA_EIO; + goto oneshot_error_exit; + } + } + } + ret = BF_FPGA_OK; + +oneshot_error_exit: + for (i = 0; i < i2c_op->num_i2c; i++) { + /* cleanup the enable bit */ + val = bf_fpga_i2c_reg_read32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(i)); + val &= (~I2C_INST_EN); + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(i), val); + } + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; +} + +/** FPGA I2C insert periodic i2c operation + * + * @param i2c_op + * bf_fpga_i2c_t parameters * + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_pr_add(bf_fpga_i2c_t *i2c_op) { + fpga_i2c_controller_t *i2c_ctrl; + int i, ret, next_id; + bool preemt; + + if (!i2c_op) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(i2c_op->inst_hndl.bus_id); + if (!i2c_ctrl) { + return BF_FPGA_EINVAL; + } + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + /* get the next available free slot */ + next_id = get_next_free_index(i2c_ctrl, i2c_op->num_i2c, true); + if (next_id < 0) { + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_EBUSY; + } + /* populate periodic i2c operation instruction(s) */ + for (i = 0; i < i2c_op->num_i2c; i++) { + preemt = ((i == (i2c_op->num_i2c - 1)) ? false : true); + i2c_op->i2c_inst[i].preemt = preemt; + ret = fpga_i2c_enqueue( + i2c_op->inst_hndl.bus_id, next_id + i, &i2c_op->i2c_inst[i]); + + if (ret) { + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; + } + } + bf_fpga_i2c_unlock(i2c_ctrl); + i2c_op->inst_hndl.inst_id = next_id; + return BF_FPGA_OK; +} + +/** FPGA I2C remove periodic i2c operation(s) from instruction memory + * + * @param i2c_op + * bf_fpga_i2c_t parameters * + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_del(bf_fpga_i2c_t *i2c_op) { + fpga_i2c_controller_t *i2c_ctrl; + int i, inst_id; + + if (!i2c_op) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(i2c_op->inst_hndl.bus_id); + if (!i2c_ctrl) { + return BF_FPGA_EINVAL; + } + inst_id = i2c_op->inst_hndl.inst_id; + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + for (i = 0; i < i2c_op->num_i2c; i++) { + /* nullify the instruction */ + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(inst_id + i), 0); + } + /* reset the in_use flag */ + release_index(i2c_ctrl, inst_id, i2c_op->num_i2c); + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_OK; +} diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.h new file mode 100644 index 000000000000..6f56ed270bdd --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.h @@ -0,0 +1,55 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#ifndef _BF_FPGA_I2C_H +#define _BF_FPGA_I2C_H + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +int fpga_i2c_start(int bus_id); +int fpga_i2c_stop(int bus_id); +int fpga_i2c_reset(int bus_id); +int fpga_i2c_is_busy(int bus_id, bool *is_busy); +int fpga_i2c_inst_en(int bus_id, int inst_id, bool en); +int fpga_i2c_set_clk(int bus_id, int clock_div); +int fpga_i2c_controller_init(int bus_id); +int fpga_i2c_controller_cleanup(int bus_id); +int fpga_i2c_init(uint8_t *base_addr); +void fpga_i2c_deinit(void); +int fpga_i2c_oneshot(bf_fpga_i2c_t *i2c_op); +int fpga_i2c_pr_add(bf_fpga_i2c_t *i2c_op); +int fpga_i2c_del(bf_fpga_i2c_t *i2c_op); +int fpga_i2c_data_read( + int bus_id, int inst_id, uint8_t offset, uint8_t len, uint8_t *buf); +bool fpga_i2c_is_inited(void); + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* _BF_FPGA_I2C_H */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_ctrl.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_ctrl.c new file mode 100644 index 000000000000..a8837ba3b60c --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_ctrl.c @@ -0,0 +1,397 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#include +#include "bf_fpga_i2c_priv_porting.h" +#include +#include "bf_fpga_i2c.h" +#include "bf_fpga_i2c_priv.h" +#include "bf_fpga_i2c_reg.h" + +/* static i2c controller contents */ +static fpga_i2c_controller_t fpga_i2c_ctrl[BF_I2C_FPGA_NUM_CTRL]; +static bool fpga_i2c_inited = false; + +/* fpga memory space access APIs */ +/* 32 bit write into fpga BAR0 */ +void bf_fpga_reg_write(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint32_t val) { + uint8_t *ptr = i2c_ctrl->fpga_base_addr + offset; + bf_fpga_write32(ptr, val); +} + +/* 32 bit read into fpga BAR0 */ +uint32_t bf_fpga_reg_read(fpga_i2c_controller_t *i2c_ctrl, uint32_t offset) { + uint8_t *ptr = i2c_ctrl->fpga_base_addr + offset; + return (bf_fpga_read32(ptr)); +} + +/* 32 bit write into fpga i2c space */ +void bf_fpga_i2c_reg_write32(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint32_t val) { + uint8_t *ptr = i2c_ctrl->i2c_base_addr + offset; + bf_fpga_write32(ptr, val); +} + +/* 32 bit read into fpga i2c space */ +uint32_t bf_fpga_i2c_reg_read32(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset) { + uint8_t *ptr = i2c_ctrl->i2c_base_addr + offset; + return (bf_fpga_read32(ptr)); +} + +/* 8 bit write into fpga i2c space */ +void bf_fpga_i2c_reg_write8(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint8_t val) { + uint8_t *ptr = i2c_ctrl->i2c_base_addr + offset; + bf_fpga_write8(ptr, val); +} + +/* 8 bit read into fpga i2c space */ +uint8_t bf_fpga_i2c_reg_read8(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset) { + uint8_t *ptr = i2c_ctrl->i2c_base_addr + offset; + return (bf_fpga_read8(ptr)); +} + +int bf_fpga_i2c_lock(fpga_i2c_controller_t *i2c_ctrl) { + return (bf_fpga_cr_enter(&i2c_ctrl->fpga_ctrl_lock)); +} + +void bf_fpga_i2c_unlock(fpga_i2c_controller_t *i2c_ctrl) { + return (bf_fpga_cr_leave(&i2c_ctrl->fpga_ctrl_lock)); +} + +/** FPGA return pointer to i2c_controller struct + * + * @param bus_id + * i2c controller id + * @return + * pointer to i2c_controller struct of + */ +fpga_i2c_controller_t *fpga_i2c_ctrl_get(int bus_id) { + if (bus_id >= BF_I2C_FPGA_NUM_CTRL) { + return NULL; + } else { + return &fpga_i2c_ctrl[bus_id]; + } +} + +/* is fpga module is soft inited */ +bool fpga_i2c_is_inited() { return fpga_i2c_inited; } + +/** FPGA I2C set clock: sets clock of i2c operations + * + * controller must be stopped before, if applicable. + * + * @param bus_id + * i2c controller id + * @param clk_div + * clock divider value as per fpga specs + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_set_clk(int bus_id, int clk_div) { + uint32_t val; + fpga_i2c_controller_t *i2c_ctrl; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + clk_div = (clk_div & I2C_CTRL_CLK_DIV_MASK) << I2C_CTRL_CLK_DIV_SHF; + val = bf_fpga_i2c_reg_read32(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP); + val &= ~(I2C_CTRL_CLK_DIV_MASK << I2C_CTRL_CLK_DIV_SHF); + val |= clk_div; + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP, val); + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_OK; +} + +/** FPGA I2C stop : stops ongoing i2c operations without mutex locking + * + * internal function + * + * @param bus_id + * i2c controller struct + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_stop_locked(fpga_i2c_controller_t *i2c_ctrl) { + int to_ms, ret; + uint8_t val; + + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP); + val &= ~I2C_CTRL_START; + bf_fpga_i2c_reg_write8(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP, val); + + to_ms = 100; /* 5 msec converted to multiple of 50 micro sec */ + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_TOP_I2C_STATUS); + while ((val & I2C_STS_BUSY) && to_ms) { + bf_fpga_us_delay(50); + to_ms--; + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_TOP_I2C_STATUS); + } + if (to_ms > 0) { + ret = BF_FPGA_OK; + } else { + ret = BF_FPGA_EIO; + } + return ret; +} + +/** FPGA I2C start : starts i2c operations without mutex locking + * + * internal function + * + * @param bus_id + * i2c controller struct + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_start_locked(fpga_i2c_controller_t *i2c_ctrl) { + uint8_t val; + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP); + bf_fpga_i2c_reg_write8(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP, val | I2C_CTRL_START); + return BF_FPGA_OK; +} + +/** FPGA I2C stop : stops ongoing i2c operations + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_stop(int bus_id) { + fpga_i2c_controller_t *i2c_ctrl; + int ret; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || !fpga_i2c_is_inited()) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + ret = fpga_i2c_stop_locked(i2c_ctrl); + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; +} + +/** FPGA I2C start : starts i2c operations + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_start(int bus_id) { + fpga_i2c_controller_t *i2c_ctrl; + int ret; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || !fpga_i2c_is_inited()) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + ret = fpga_i2c_start_locked(i2c_ctrl); + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; +} + +/** FPGA I2C reset: reset i2c by issuing 9 clocks in a specific way + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_reset(int bus_id) { + fpga_i2c_controller_t *i2c_ctrl; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || !fpga_i2c_is_inited()) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + bf_fpga_i2c_reg_write8(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP, I2C_CTRL_RESET); + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_OK; +} + +/** FPGA I2C is running? + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_is_busy(int bus_id, bool *busy) { + uint8_t val; + fpga_i2c_controller_t *i2c_ctrl; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || !fpga_i2c_is_inited()) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_TOP_I2C_STATUS); + *busy = ((val & I2C_STS_BUSY) ? true : false); + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_OK; +} + +/** FPGA I2C instruction enable/disable + * + * enable or disable a particular instruction in i2c instruction memory + * @param bus_id + * i2c controller id + * @param inst_id + * instruction id within this controller space + * @param en + * true for enable, false for disable + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_inst_en(int bus_id, int inst_id, bool en) { + uint32_t val; + fpga_i2c_controller_t *i2c_ctrl; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || !fpga_i2c_is_inited()) { + return BF_FPGA_EINVAL; + } + if (inst_id < 0 || inst_id >= FPGA_I2C_NUM_INST) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + val = bf_fpga_i2c_reg_read32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(inst_id)); + if (en) { + val |= I2C_INST_EN; + } else { + val &= ~I2C_INST_EN; + } + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(inst_id), val); + fpga_i2c_ctrl[bus_id].i2c_inst[inst_id].en = en; + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_OK; +} + +/** FPGA I2C controller initialization + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_controller_init(int bus_id) { + fpga_i2c_controller_t *i2c_ctrl; + int i, ret; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (!i2c_ctrl) { + return BF_FPGA_EINVAL; + } + bf_fpga_fast_lock_init(&i2c_ctrl->spinlock, 0); + bf_fpga_cr_init(&i2c_ctrl->fpga_ctrl_lock); + bf_fpga_cr_enter(&i2c_ctrl->fpga_ctrl_lock); + for (i = 0; i < FPGA_I2C_NUM_INST; i++) { + fpga_i2c_ctrl[bus_id].i2c_inst[i].inst = (uint32_t)i; + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(i), 0); + } + bf_fpga_cr_leave(&i2c_ctrl->fpga_ctrl_lock); + ret = fpga_i2c_set_clk(bus_id, 1); /* 400 khz default */ + ret |= fpga_i2c_stop(bus_id); /* just in case */ + return ret; +} + +/** FPGA I2C controller de initialization + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_controller_cleanup(int bus_id) { + int i; + + fpga_i2c_stop(bus_id); + for (i = 0; i < FPGA_I2C_NUM_INST; i++) { + fpga_i2c_ctrl[bus_id].i2c_inst[i].en = false; + } + bf_fpga_cr_destroy(&fpga_i2c_ctrl[bus_id].fpga_ctrl_lock); + bf_fpga_fast_lock_destroy(&fpga_i2c_ctrl[bus_id].spinlock); + return BF_FPGA_OK; +} + +/** FPGA I2C global initialization + * + * @param base_addr + * virtual address of i2c memory relative to BAR0 base + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_init(uint8_t *base_addr) { + int i; + + memset(fpga_i2c_ctrl, 0, sizeof(fpga_i2c_ctrl)); + for (i = 0; i < BF_I2C_FPGA_NUM_CTRL; i++) { + fpga_i2c_ctrl[i].i2c_base_addr = base_addr + BF_FPGA_I2C_CTRL_BASE_ADDR(i); + fpga_i2c_ctrl[i].fpga_base_addr = base_addr; + fpga_i2c_controller_init(i); + } + fpga_i2c_inited = true; + return BF_FPGA_OK; +} + +/** FPGA I2C global de initialization + * + */ +void fpga_i2c_deinit(void) { + int i; + + for (i = 0; i < BF_I2C_FPGA_NUM_CTRL; i++) { + fpga_i2c_controller_cleanup(i); + } + fpga_i2c_inited = false; +} diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_porting.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_porting.c new file mode 100644 index 000000000000..8b126c2e6dce --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_porting.c @@ -0,0 +1,150 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#include +#include +#include +#include +#include +#include "bf_fpga_i2c_priv_porting.h" +#include +#include "bf_fpga_i2c.h" +#include "bf_fpga_i2c_priv.h" + +/* This file contains OS and system specific porting functions for i2c APIs. + * Implementation in this file is for porting to linux kernel. + */ +/* mutex APIs are for mutual exclusion with capability to sleep while in + * exclusion mode + */ + +/* sleepable virtual exclusion region */ +typedef struct { + atomic_t lock_state; /* 1: in exclusion mode, 0: not in exclusion mode */ +} sleepable_v_mutex_t; + +int bf_fpga_cr_init(bf_fpga_mutex_t *lock) { + sleepable_v_mutex_t *mtx; + + if (!lock) { + return -1; + } + mtx = vzalloc(sizeof(sleepable_v_mutex_t)); + + if (mtx) { + atomic_set(&mtx->lock_state, 0); + *lock = (bf_fpga_mutex_t *)mtx; + return 0; + } else { + *lock = NULL; + return -1; + } +} + +void bf_fpga_cr_destroy(bf_fpga_mutex_t *lock) { + if (lock && *lock) { + vfree(*lock); + *lock = NULL; + } +} + +void bf_fpga_cr_leave(bf_fpga_mutex_t *lock) { + sleepable_v_mutex_t *mtx; + + if (lock && *lock) { + mtx = (sleepable_v_mutex_t *)*lock; + atomic_xchg(&mtx->lock_state, 0); + } +} + +int bf_fpga_cr_enter(bf_fpga_mutex_t *lock) { + sleepable_v_mutex_t *mtx; + + /* All we do here is: test and set */ + if (lock && *lock) { + int cnt = 10000; /* This will provide maximum of 500-1000 ms timeout */ + mtx = (sleepable_v_mutex_t *)*lock; + while (atomic_cmpxchg(&mtx->lock_state, 0, 1) != 0) { + if (cnt-- <= 0) { + return -1; /* this is a worst case timeout situation */ + } + usleep_range(50, 100); /* 50 us = about 2 bytes at 400Kbs i2c */ + } + return 0; + } else { + return -1; + } +} + +/* **** not implemented in current mode of locking */ +int bf_fpga_mutex_trylock(bf_fpga_mutex_t *lock) { + if (lock && *lock) { + return -1; + } else { + return -1; + } +} + +/* fast lock is a non-blocking busy lock, implemented with spinlock */ +int bf_fpga_fast_lock_init(bf_fpga_fast_lock_t *sl, unsigned int initial) { + spinlock_t *slock; + + (void)initial; + if (!sl) { + return -1; + } + slock = vzalloc(sizeof(spinlock_t)); + + if (slock) { + spin_lock_init(slock); + *sl = (bf_fpga_fast_lock_t *)slock; + return 0; + } else { + *sl = NULL; + return -1; + } +} + +void bf_fpga_fast_lock_destroy(bf_fpga_fast_lock_t *sl) { + if (sl && *sl) { + vfree(*sl); + *sl = NULL; + } +} + +int bf_fpga_fast_lock(bf_fpga_fast_lock_t *sl) { + if (sl && *sl) { + spin_lock(*sl); + return 0; + } else { + return -1; + } +} + +void bf_fpga_fast_unlock(bf_fpga_fast_lock_t *sl) { + if (sl && *sl) { + spin_unlock(*sl); + } +} diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv.h new file mode 100644 index 000000000000..0b3b1e47b015 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv.h @@ -0,0 +1,104 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#ifndef _BF_FPGA_I2C_PRIV_H +#define _BF_FPGA_I2C_PRIV_H + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +#define FPGA_I2C_INST_OFFSET(idx) (0x10 + (16 * idx)) + +typedef enum { + FGPA_I2C_NOP = 0x0, + FGPA_I2C_WR_ADDR_DATA = 0x1, /* wr: reg_addr, wr: data */ + FGPA_I2C_WR_ADDR_RD_DATA = 0x2, /* wr: reg_addrss, r/s, rd: data */ + FGPA_I2C_WR_ADDR = 0x3, /* wr: reg_addr */ + FGPA_I2C_RD_DATA = 0x4, /* rd: data */ + FGPA_I2C_MULTI_WR_RD = 0x5 /* wr: n bytes, r/s, rd: m bytes */ +} i2c_cmd_type; + +/* contents of each instruction instance */ +typedef struct i2c_inst_cmd_s { + i2c_cmd_type i2c_cmd; /* i2x cycle type */ + uint32_t data_lo; /* lower 4 bytes of data associated with this inst */ + uint32_t data_hi; /* upper 4 bytes of data associated with this inst */ + uint32_t us_delay; /* delay before i2c cycle */ + uint8_t i2c_addr; /* i2c device address, in 7 bit format */ + uint8_t reg_addr; /* 1st write byte, if present in i2c cycle */ + uint8_t num_read; /* number of bytes to write excluding reg_addr */ + uint8_t num_write; /* number of bytes to read */ +} i2c_inst_cmd_t; + +/* attributes of each instruction instance */ +typedef struct i2c_inst_s { + uint32_t inst; /* index of the instruction within the controller memory */ + bool en; /* is instruction enabled */ + bool preemt; /* atomically execute next instruction */ + bool int_en; /* enable interrupt after execution */ + bool in_use; /* is this instruction currently used */ +} i2c_inst_t; + +typedef struct fpga_i2c_controller_s { + bf_fpga_mutex_t fpga_ctrl_lock; + bf_fpga_fast_lock_t spinlock; + uint8_t *fpga_base_addr; /* virtual address of start of fpga memory */ + uint8_t *i2c_base_addr; /* virtual address of i2c controller memory */ + uint32_t start; /* offset of start of i2c instruction memory */ + uint32_t len; /* number of i2c instructions belonging to this i2c engine */ + uint32_t clk_div; /* clock divider used by this i2c engine */ + bool int_en; + i2c_inst_t i2c_inst[FPGA_I2C_NUM_INST]; +} fpga_i2c_controller_t; + +fpga_i2c_controller_t *fpga_i2c_ctrl_get(int bus_id); +void bf_fpga_reg_write(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint32_t val); +uint32_t bf_fpga_reg_read(fpga_i2c_controller_t *i2c_ctrl, uint32_t offset); +void bf_fpga_i2c_reg_write32(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint32_t val); +uint32_t bf_fpga_i2c_reg_read32(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset); +void bf_fpga_i2c_reg_write8(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint8_t val); +uint8_t bf_fpga_i2c_reg_read8(fpga_i2c_controller_t *i2c_ctrl, uint32_t offset); + +int bf_fpga_i2c_lock(fpga_i2c_controller_t *i2c_ctrl); + +void bf_fpga_i2c_unlock(fpga_i2c_controller_t *i2c_ctrl); + +int fpga_i2c_start_locked(fpga_i2c_controller_t *i2c_ctrl); +int fpga_i2c_stop_locked(fpga_i2c_controller_t *i2c_ctrl); + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* _BF_FPGA_I2C_PRIV_H */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv_porting.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv_porting.h new file mode 100644 index 000000000000..adea5c9311fa --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv_porting.h @@ -0,0 +1,93 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#ifndef _BF_FPGA_I2C_PRIV_PORTING_H +#define _BF_FPGA_I2C_PRIV_PORTING_H + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* This file contains OS and system specific porting functions declarations. + */ +/* return status compliant with linux system calls */ +#define BF_FPGA_OK 0 +#define BF_FPGA_EINVAL (-EINVAL) +#define BF_FPGA_EIO (-EIO) +#define BF_FPGA_EBUSY (-EBUSY) +#define BF_FPGA_EAGAIN (-EAGAIN) + +/* pci memory access functions */ +static inline void bf_fpga_write32(uint8_t *addr, uint32_t val) { + u8 __iomem *reg_addr = addr; + writel(val, reg_addr); +} + +static inline uint32_t bf_fpga_read32(uint8_t *addr) { + u8 __iomem *reg_addr = addr; + return (readl(reg_addr)); +} + +static inline void bf_fpga_write8(uint8_t *addr, uint8_t val) { + u8 __iomem *reg_addr = addr; + writeb(val, reg_addr); +} + +static inline uint8_t bf_fpga_read8(uint8_t *addr) { + u8 __iomem *reg_addr = addr; + return (readb(reg_addr)); +} + +static inline void bf_fpga_us_delay(unsigned long usecs) { + usleep_range(usecs, usecs + 10); +} + +/* general purpose mutual exclusion lock */ +typedef void *bf_fpga_mutex_t; + +/* fast_lock for locking only non-blocking and quick operations */ +typedef void *bf_fpga_fast_lock_t; + +/* APIs to init/enter/leave critical (exclusive access) regions */ +int bf_fpga_cr_init(bf_fpga_mutex_t *lock); +void bf_fpga_cr_destroy(bf_fpga_mutex_t *lock); +int bf_fpga_cr_enter(bf_fpga_mutex_t *lock); +void bf_fpga_cr_leave(bf_fpga_mutex_t *lock); + +int bf_fpga_fast_lock_init(bf_fpga_fast_lock_t *sl, unsigned int initial); +void bf_fpga_fast_lock_destroy(bf_fpga_fast_lock_t *sl); +int bf_fpga_fast_lock(bf_fpga_fast_lock_t *sl); +void bf_fpga_fast_unlock(bf_fpga_fast_lock_t *sl); + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* _BF_FPGA_I2C_PRIV_PORTING_H */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_reg.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_reg.h new file mode 100644 index 000000000000..9ad9b31b3b3f --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_reg.h @@ -0,0 +1,116 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#ifndef _BF_FPGA_I2C_REG_H +#define _BF_FPGA_I2C_REG_H + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* registers outsize of all i2c controller register space */ +#define BF_FPGA_I2C_BASE_ADDR 0x0 +#define BF_FPGA_I2C_CTRL_BASE_ADDR(i) (BF_FPGA_I2C_BASE_ADDR + (i * 4096)) + +/* per i2c controller register offset relative to BF_FPGA_I2C_CTRL_BASE_ADDR */ +#define Bf_FPGA_I2C_CTRL_TOP 0 +#define I2C_CTRL_START (1 << 0) +#define I2C_CTRL_RESET (1 << 1) +#define I2C_CTRL_CLK_DIV_SHF (8) +#define I2C_CTRL_CLK_DIV_MASK (0x1FF) + +#define Bf_FPGA_TOP_I2C_STATUS 4 +#define I2C_STS_BUSY (1 << 0) +#define I2C_STS_ERR (1 << 3) + +#define Bf_FPGA_I2C_INST_CTRL(i) (0x10 + (16 * i)) +#define I2C_INST_EN (1 << 31) +#define I2C_INST_PMT (1 << 30) +#define I2C_TYPE_SHF (26) +#define I2C_DELAY_SHF (23) +#define I2C_STOP_ON_ERROR (22) +/* various status values */ +#define I2C_STATUS_MASK 0x3F +#define I2C_STATUS_ERR_MASK 0x3C +#define I2C_STATUS_RUNNING 0x1 +#define I2C_STATUS_COMPLETED 0x2 +#define I2C_STATUS_NACK_ADDR 0x4 +#define I2C_STATUS_NACK_CMD 0x8 +#define I2C_STATUS_NACK_WR_DATA 0x10 +#define I2C_STATUS_TOUT 0x20 + +/* i2c instruction types */ +#define I2C_WR_ADDR_DATA (0 << I2C_TYPE_SHF) +#define I2C_RD_DATA (3 << I2C_TYPE_SHF) +#define I2C_WR_ADDR (2 << I2C_TYPE_SHF) +#define I2C_RD_ADDR_DATA (1 << I2C_TYPE_SHF) +#define I2C_RD_ADDR_DATA_BURST (4 << I2C_TYPE_SHF) +#define I2C_NOP (6 << I2C_TYPE_SHF) + +#define Bf_FPGA_I2C_INST_PARAM(i) (0x14 + (16 * i)) +#define I2C_DEV_ADDR_SHF (24) +#define I2C_CMD_OFFSET (16) +#define I2C_WR_CNT_SHF (8) +#define I2C_RD_CNT_SHF (0) + +#define Bf_FPGA_I2C_INST_DATA_LO(i) (0x18 + (16 * i)) +#define Bf_FPGA_I2C_INST_DATA_HI(i) (0x1C + (16 * i)) +/****************** +#define Bf_FPGA_I2C_PR_CTRL(i) (0x100 + (16 * i)) +#define Bf_FPGA_I2C_PR_PARM(i) (0x104 + (16 * i)) +#define Bf_FPGA_I2C_PR_LO(i) (0x108 + (16 * i)) +#define Bf_FPGA_I2C_PR_HI(i) (0x10C + (16 * i)) +******************/ + +/* data area pointers */ +/* the driver makes fixed static allocation of the available memory + * on per instruction basis + * allocate 128 bytes per one time instruction = total 0x780 bytes + * allocate 64 bytes per one periodic instruction = total 0x400 bytes + * FPGA_I2C_ONESHOT_NUM_INST -> comes from a header file that must be included + * before this file. + */ +#define BF_FPGA_ONE_MAX_BURST 128 +#define BF_FPGA_PR_MAX_BURST 64 +#define BF_FPGA_I2C_DATA_AREA(i) \ + ((i < FPGA_I2C_ONESHOT_NUM_INST) \ + ? (0x200 + (i * BF_FPGA_ONE_MAX_BURST)) \ + : (0x980 + ((i - FPGA_I2C_ONESHOT_NUM_INST) * BF_FPGA_PR_MAX_BURST))) + +#if BF_FPGA_I2C_DATA_AREA(FPGA_I2C_PERIODIC_NUM_INST) > 0x1000 +#error erroneous allocation of FPGA memory to i2c data area. Fix it! +#endif + +#define BF_FPGA_VER_REG 0x3F000 +#define BF_FPGA_BUILD_DATE 0x3F004 +#define BF_FPGA_RESET_CTRL_1 0x3F008 +#define BF_FPGA_RESET_CTRL_2 0x3F00C + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* _BF_FPGA_I2C_REG_H */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/bf-sfputil b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/bf-sfputil new file mode 100755 index 000000000000..3df67614e499 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/bf-sfputil @@ -0,0 +1,10 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS syncd sfputil "$@" diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/eeprom b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/eeprom new file mode 100755 index 000000000000..07d98556cbbf --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/eeprom @@ -0,0 +1,10 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS syncd eeprom "$@" diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/fancontrol b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/fancontrol new file mode 100755 index 000000000000..515fcbdd69da --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/fancontrol @@ -0,0 +1,11 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS syncd fancontrol "$@" + diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/ps_info b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/ps_info new file mode 100755 index 000000000000..38c9d3330414 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/ps_info @@ -0,0 +1,10 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS syncd ps_info "$@" diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/sensors b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/sensors new file mode 100755 index 000000000000..07af6955321e --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/sensors @@ -0,0 +1,12 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS syncd sensors "$@" + + diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/test b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/test new file mode 100755 index 000000000000..38327722c91f --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/test @@ -0,0 +1 @@ +echo "test" From 65fc916dcfcd01ed0f16025de1730f46b8329984 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 7 Nov 2019 09:56:17 +0700 Subject: [PATCH 0133/1427] [platform/device] - Implement Silverstone platform API [Chassis/Fan] (#3706) Implement part of the Chassis and Fan related APIs. - Chassis APIs get_base_mac() get_serial_number() get_serial_number() get_system_eeprom_info() get_reboot_cause() - Fan APIs get_direction() get_speed() get_target_speed() get_speed_tolerance() set_speed() set_status_led() get_target_speed() - Fan APIs base on Device API get_name() get_presence() get_model() get_serial() get_status() Signed-off-by: Wirut Getbamrung wgetbumr@celestica.com --- .../sonic_platform/__init__.py | 2 + .../sonic_platform/chassis.py | 114 ++++++++ .../sonic_platform/eeprom.py | 113 +++++++ .../sonic_platform/fan.py | 276 ++++++++++++++++++ .../sonic_platform/helper.py | 56 ++++ .../sonic_platform/platform.py | 23 ++ .../debian/platform-modules-silverstone.init | 2 + .../platform-modules-silverstone.install | 4 +- .../platform-modules-silverstone.postinst | 4 +- .../silverstone/setup.py | 34 +++ 10 files changed, 626 insertions(+), 2 deletions(-) create mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py create mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py create mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py create mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py create mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py create mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/setup.py diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py new file mode 100644 index 000000000000..d82f3749319c --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py new file mode 100644 index 000000000000..dc622016cbb2 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import sys +import re +import os +import subprocess +import json + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.eeprom import Tlv + from sonic_platform.fan import Fan + from helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN_TRAY = 7 +NUM_FAN = 2 +NUM_PSU = 2 +NUM_THERMAL = 5 +NUM_SFP = 32 +NUM_COMPONENT = 5 + +IPMI_OEM_NETFN = "0x3A" +IPMI_GET_REBOOT_CAUSE = "0x03 0x00 0x01 0x06" + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + self.config_data = {} + ChassisBase.__init__(self) + self._eeprom = Tlv() + self._api_helper = APIHelper() + + for fant_index in range(0, NUM_FAN_TRAY): + for fan_index in range(0, NUM_FAN): + fan = Fan(fant_index, fan_index) + self._fan_list.append(fan) + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.get_mac() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.get_serial() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.get_eeprom() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + + status, raw_cause = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_GET_REBOOT_CAUSE) + hx_cause = raw_cause.split()[0] if status else 00 + reboot_cause = { + "00": self.REBOOT_CAUSE_HARDWARE_OTHER, + "11": self.REBOOT_CAUSE_POWER_LOSS, + "22": self.REBOOT_CAUSE_NON_HARDWARE, + "33": self.REBOOT_CAUSE_HARDWARE_OTHER, + "44": self.REBOOT_CAUSE_NON_HARDWARE, + "55": self.REBOOT_CAUSE_NON_HARDWARE, + "66": self.REBOOT_CAUSE_WATCHDOG, + "77": self.REBOOT_CAUSE_NON_HARDWARE + }.get(hx_cause, self.REBOOT_CAUSE_HARDWARE_OTHER) + + description = { + "00": "Unknown reason", + "11": "The last reset is Power on reset", + "22": "The last reset is soft-set CPU warm reset", + "33": "The last reset is soft-set CPU cold reset", + "44": "The last reset is CPU warm reset", + "55": "The last reset is CPU cold reset", + "66": "The last reset is watchdog reset", + "77": "The last reset is power cycle reset" + }.get(hx_cause, "Unknown reason") + + return (reboot_cause, description) diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py new file mode 100644 index 000000000000..dd0c9332b54e --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica Silverstone +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import glob + import os + import sys + import imp + import re + from array import array + from cStringIO import StringIO + from sonic_platform_base.sonic_eeprom import eeprom_dts + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + +CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' +CACHE_FILE = 'syseeprom_cache' +TLV_EEPROM_I2C_BUS = 0 +TLV_EEPROM_I2C_ADDR = 56 + +class Tlv(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + + def __init__(self): + self._eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-00{1}/eeprom".format(TLV_EEPROM_I2C_BUS, TLV_EEPROM_I2C_ADDR) + super(Tlv, self).__init__(self._eeprom_path, 0, '', True) + self._eeprom = self._load_eeprom() + + def __parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search( + '(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + if match is not None: + idx = match.group(1) + value = match.group(3).rstrip('\0') + + _eeprom_info_dict[idx] = value + except: + pass + return _eeprom_info_dict + + def _load_eeprom(self): + original_stdout = sys.stdout + sys.stdout = StringIO() + try: + self.read_eeprom_db() + except: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + return self.__parse_output(decode_output) + + status = self.check_status() + if 'ok' not in status: + return False + + if not os.path.exists(CACHE_ROOT): + try: + os.makedirs(CACHE_ROOT) + except: + pass + + # + # only the eeprom classes that inherit from eeprom_base + # support caching. Others will work normally + # + try: + self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) + except: + pass + + e = self.read_eeprom() + if e is None: + return 0 + + try: + self.update_cache(e) + except: + pass + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + (is_valid, valid_crc) = self.is_checksum_valid(e) + if not is_valid: + return False + + return self.__parse_output(decode_output) + + def get_eeprom(self): + return self._eeprom + + def get_serial(self): + return self._eeprom.get('0x23', "Undefined.") + + def get_mac(self): + return self._eeprom.get('0x24', "Undefined.") diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py new file mode 100644 index 000000000000..902de261f8cb --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py @@ -0,0 +1,276 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +import json +import math +import os.path + +try: + from sonic_platform_base.fan_base import FanBase + from helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +FAN_NAME_LIST = ["FAN-1F", "FAN-1R", "FAN-2F", "FAN-2R", "FAN-3F", "FAN-3R", + "FAN-4F", "FAN-4R", "FAN-5F", "FAN-5R", "FAN-6F", "FAN-6R", "FAN-7F", "FAN-7R"] + +IPMI_OEM_NETFN = "0x3A" +IPMI_SENSOR_NETFN = "0x04" +IPMI_FAN_SPEED_CMD = "0x2D {}" +IPMI_AIR_FLOW_CMD = "0x0A {}" +IPMI_FAN_PRESENT_CMD = "0x06 0x03 {}" +IPMI_SET_FAN_LED_CMD = "0x07 {} {}" +IPMI_GET_FAN_LED_CMD = "0x08 {}" +IPMI_SET_PWM = "0x03 0x01 0x02 {} {}" +IPMI_FRU_PRINT_ID = "ipmitool fru print {}" +IPMI_FRU_MODEL_KEY = "Board Part Number" +IPMI_FRU_SERIAL_KEY = "Board Serial" + +MAX_OUTLET = 24700 +MAX_INLET = 29700 +SPEED_TOLERANCE = 10 + +FAN1_FRONT_SS_ID = "0x0D" +FAN1_REAR_SS_ID = "0x45" +FAN_LED_OFF_CMD = "0x00" +FAN_LED_GREEN_CMD = "0x01" +FAN_LED_RED_CMD = "0x02" +FAN1_LED_CMD = "0x04" +FAN_PWM_REGISTER_START = 0x22 +FAN_PWM_REGISTER_STEP = 0x10 +FAN1_FRU_ID = 6 + + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + self.is_psu_fan = is_psu_fan + if self.is_psu_fan: + self.psu_index = psu_index + self._api_helper = APIHelper() + self.index = self.fan_tray_index * 2 + self.fan_index + + def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = self.FAN_DIRECTION_EXHAUST + status, raw_flow = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_AIR_FLOW_CMD.format(hex(self.fan_tray_index))) + if status and raw_flow == "01": + direction = self.FAN_DIRECTION_INTAKE + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + M = 150 + Max F2B = 24700 RPM + Max B2F = 29700 RPM + """ + # ipmitool raw 0x3a 0x03 0x01 0x01 {register} + # register = 22 32 42 52 62 72 82 + + max_rpm = MAX_OUTLET if self.fan_index % 2 == 0 else MAX_INLET + fan1_ss_start = FAN1_FRONT_SS_ID if self.fan_index % 2 == 0 else FAN1_REAR_SS_ID + + ss_id = hex(int(fan1_ss_start, 16) + self.fan_tray_index) + status, raw_ss_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_FAN_SPEED_CMD.format(ss_id)) + + ss_read = raw_ss_read.split()[0] + rpm_speed = int(ss_read, 16)*150 + speed = int(float(rpm_speed)/max_rpm * 100) + + return speed + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + speed_pc = pwm_target/255*100 + + 0 : when PWM mode is use + pwm : when pwm mode is not use + """ + target = 0 + return target + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return SPEED_TOLERANCE + + def set_speed(self, speed): + """ + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + Notes: + pwm setting mode must set as Manual + manual: ipmitool raw 0x3a 0x06 0x01 0x0 + auto: ipmitool raw 0x3a 0x06 0x01 0x1 + """ + # ipmitool raw 0x3a 0x03 0x01 0x02 {register} {pwm_speed} + # register = 22 32 42 52 62 72 82 + + speed_hex = hex(int(float(speed)/100 * 255)) + fan_register_hex = hex(FAN_PWM_REGISTER_START + + (self.fan_tray_index*FAN_PWM_REGISTER_STEP)) + + set_speed_cmd = IPMI_SET_PWM.format(fan_register_hex, speed_hex) + status, set_speed_res = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, set_speed_cmd) + + set_speed = False if not status else True + + return set_speed + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + + Note: + LED setting mode must set as Manual + manual: ipmitool raw 0x3A 0x09 0x02 0x00 + auto: ipmitool raw 0x3A 0x09 0x02 0x01 + """ + led_cmd = { + self.STATUS_LED_COLOR_GREEN: FAN_LED_GREEN_CMD, + self.STATUS_LED_COLOR_RED: FAN_LED_RED_CMD, + self.STATUS_LED_COLOR_OFF: FAN_LED_OFF_CMD + }.get(color) + + fan_selector = hex(int(FAN1_LED_CMD, 16) + self.fan_tray_index) + status, set_led = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_SET_FAN_LED_CMD.format(fan_selector, led_cmd)) + set_status_led = False if not status else True + + return set_status_led + + def get_status_led(self): + """ + Gets the state of the fan status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + + Note: + STATUS_LED_COLOR_GREEN = "green" + STATUS_LED_COLOR_AMBER = "amber" + STATUS_LED_COLOR_RED = "red" + STATUS_LED_COLOR_OFF = "off" + """ + fan_selector = hex(int(FAN1_LED_CMD, 16) + self.fan_tray_index) + status, hx_color = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_GET_FAN_LED_CMD.format(fan_selector)) + + status_led = { + "00": self.STATUS_LED_COLOR_OFF, + "01": self.STATUS_LED_COLOR_GREEN, + "02": self.STATUS_LED_COLOR_RED, + }.get(hx_color, self.STATUS_LED_COLOR_OFF) + + return status_led + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + fan_name = FAN_NAME_LIST[self.fan_tray_index*2 + self.fan_index] if not self.is_psu_fan else "PSU-{} FAN-{}".format( + self.psu_index+1, self.fan_index+1) + + return fan_name + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + presence = False + status, raw_present = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_FAN_PRESENT_CMD.format(hex(self.index))) + if status and raw_present == "00": + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + model = "Unknown" + ipmi_fru_idx = self.fan_tray_index + FAN1_FRU_ID + status, raw_model = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_MODEL_KEY) + + fru_pn_list = raw_model.split() + if len(fru_pn_list) > 4: + model = fru_pn_list[4] + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + serial = "Unknown" + ipmi_fru_idx = self.fan_tray_index + FAN1_FRU_ID + status, raw_model = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_SERIAL_KEY) + + fru_sr_list = raw_model.split() + if len(fru_sr_list) > 3: + serial = fru_sr_list[3] + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and self.get_speed() > 0 diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py new file mode 100644 index 000000000000..1132b5b06785 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +import os +import subprocess + + +HOST_CHK_CMD = "docker > /dev/null 2>&1" +EMPTY_STRING = "" + + +class APIHelper(): + + def __init__(self): + pass + + def is_host(self): + return os.system(HOST_CHK_CMD) == 0 + + def read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + def ipmi_raw(self, netfn, cmd): + status = True + result = "" + try: + cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd)) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + except: + status = False + return status, result + + def ipmi_fru_id(self, id, key=None): + status = True + result = "" + try: + cmd = "ipmitool fru print {}".format(str( + id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key)) + + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + except: + status = False + return status, result diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py new file mode 100644 index 000000000000..a632de87e742 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init index c1d4c10b48fc..eb003599ec61 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init @@ -29,6 +29,8 @@ start) fi decode-syseeprom --init 2> /dev/null & + /bin/sh /usr/local/bin/platform_api_mgnt.sh init + echo "done." ;; diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install index a3a8b3d424a1..03e13544b8b1 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install @@ -1,2 +1,4 @@ silverstone/cfg/silverstone-modules.conf etc/modules-load.d -silverstone/systemd/platform-modules-silverstone.service lib/systemd/system \ No newline at end of file +silverstone/systemd/platform-modules-silverstone.service lib/systemd/system +silverstone/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_silverstone-r0 +services/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst index 771057bed0dc..feb9cf45c219 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst @@ -1,3 +1,5 @@ depmod -a systemctl enable platform-modules-silverstone.service -systemctl start platform-modules-silverstone.service \ No newline at end of file +systemctl start platform-modules-silverstone.service + +/usr/local/bin/platform_api_mgnt.sh install diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/setup.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/setup.py new file mode 100644 index 000000000000..20a2b6d1063a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/setup.py @@ -0,0 +1,34 @@ +from setuptools import setup + +DEVICE_NAME = 'celestica' +HW_SKU = 'x86_64-cel_silverstone-r0' + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Celestica Platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Wirut Getbamrung', + maintainer_email='wgetbumr@celestica.com', + packages=[ + 'sonic_platform', + ], + package_dir={ + 'sonic_platform': '../../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)}, + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) From 7d4093d6edcb7eea637b920fa96752ac3d1e07e3 Mon Sep 17 00:00:00 2001 From: brandonchuang Date: Thu, 7 Nov 2019 10:57:08 +0800 Subject: [PATCH 0134/1427] [device/platform] Add reset in sfputil.py for Accton AS7326-56X (#3685) Add reset in sfputil.py for as7326-56x. Signed-off-by: brandon_chuang --- .../plugins/sfputil.py | 24 ++++- .../as7326-56x/modules/accton_i2c_cpld.c | 87 ++++++++++++++++++- 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py index 330d30b879d7..0292e2d52e1a 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py @@ -219,8 +219,30 @@ def set_low_power_mode(self, port_num, lpmode): time.sleep(0.01) def reset(self, port_num): - raise NotImplementedError + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + cpld_i = self.get_cpld_num(port_num) + cpld_ps = self._cpld_mapping[cpld_i] + path = "/sys/bus/i2c/devices/{0}/module_reset_{1}" + port_ps = path.format(cpld_ps, port_num) + + self.__port_to_mod_rst = port_ps + try: + reg_file = open(self.__port_to_mod_rst, 'r+', buffering=0) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + + return True @property def _get_present_bitmap(self): nodes = [] diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c index a4ff19fea546..70d9a66affdb 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c @@ -285,6 +285,14 @@ enum as7326_56x_cpld_sysfs_attributes { TRANSCEIVER_TXFAULT_ATTR_ID(48), TRANSCEIVER_TXFAULT_ATTR_ID(57), TRANSCEIVER_TXFAULT_ATTR_ID(58), + TRANSCEIVER_RESET_ATTR_ID(49), + TRANSCEIVER_RESET_ATTR_ID(50), + TRANSCEIVER_RESET_ATTR_ID(51), + TRANSCEIVER_RESET_ATTR_ID(52), + TRANSCEIVER_RESET_ATTR_ID(53), + TRANSCEIVER_RESET_ATTR_ID(54), + TRANSCEIVER_RESET_ATTR_ID(55), + TRANSCEIVER_RESET_ATTR_ID(56), }; /* sysfs attributes for hwmon @@ -297,6 +305,8 @@ static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, char *buf); static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t set_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); static ssize_t access(struct device *dev, struct device_attribute *da, const char *buf, size_t count); static ssize_t show_version(struct device *dev, struct device_attribute *da, @@ -437,6 +447,15 @@ DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(57); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(58); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(49); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(50); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(51); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(52); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(53); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(54); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(55); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(56); + static struct attribute *as7326_56x_cpld3_attributes[] = { &sensor_dev_attr_version.dev_attr.attr, &sensor_dev_attr_access.dev_attr.attr, @@ -507,7 +526,7 @@ static struct attribute *as7326_56x_cpld2_attributes[] = { DECLARE_SFP_TRANSCEIVER_ATTR(22), DECLARE_SFP_TRANSCEIVER_ATTR(23), DECLARE_SFP_TRANSCEIVER_ATTR(24), - DECLARE_SFP_TRANSCEIVER_ATTR(25), + DECLARE_SFP_TRANSCEIVER_ATTR(25), DECLARE_SFP_TRANSCEIVER_ATTR(26), DECLARE_SFP_TRANSCEIVER_ATTR(27), DECLARE_SFP_TRANSCEIVER_ATTR(28), @@ -574,6 +593,14 @@ static struct attribute *as7326_56x_cpld1_attributes[] = { DECLARE_SFP_TRANSCEIVER_ATTR(48), DECLARE_SFP_TRANSCEIVER_ATTR(57), DECLARE_SFP_TRANSCEIVER_ATTR(58), + DECLARE_TRANSCEIVER_RESET_ATTR(49), + DECLARE_TRANSCEIVER_RESET_ATTR(50), + DECLARE_TRANSCEIVER_RESET_ATTR(51), + DECLARE_TRANSCEIVER_RESET_ATTR(52), + DECLARE_TRANSCEIVER_RESET_ATTR(53), + DECLARE_TRANSCEIVER_RESET_ATTR(54), + DECLARE_TRANSCEIVER_RESET_ATTR(55), + DECLARE_TRANSCEIVER_RESET_ATTR(56), NULL }; @@ -724,6 +751,11 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, reg = 0x19; mask = 0x1 << (( attr->index - MODULE_RXLOS_57)+2); break; + case MODULE_RESET_49 ... MODULE_RESET_56: + reg = 0x4; + mask = 0x1 << (attr->index - MODULE_RESET_49); + revert = 1; + break; default: return 0; } @@ -806,6 +838,59 @@ static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, return status; } +static ssize_t set_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7326_56x_cpld_data *data = i2c_get_clientdata(client); + long reset; + int status; + u8 reg = 0, mask = 0; + + status = kstrtol(buf, 10, &reset); + if (status) { + return status; + } + + switch (attr->index) + { + case MODULE_RESET_49 ... MODULE_RESET_56: + reg = 0x4; + mask = 0x1 << (attr->index - MODULE_RESET_49); + break; + default: + return 0; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as7326_56x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + /* Update reset status */ + if (!reset) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as7326_56x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + static ssize_t access(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { From 6d46badbdc6a72e0c923fdae2ab2258011c8bed2 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 6 Nov 2019 20:18:31 -0800 Subject: [PATCH 0135/1427] [aboot]: preserve snmp.yml and acl.json for eos to sonic fast reboot (#3716) --- files/Aboot/boot0.j2 | 4 +++- files/image_config/platform/rc.local | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 2f861bbbd405..66e86774e766 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -94,7 +94,9 @@ clean_flash() { [ $f != "$cmdline_base" ] && [ $f != "aquota.user" ] && [ $f != "old_config" ] && - [ $f != "minigraph.xml" ] + [ $f != "minigraph.xml" ] && + [ $f != "snmp.yml" ] && + [ $f != "acl.json" ] then rm -rf "$target_path/$f" fi diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index 190743285644..b74e9f40c4b0 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -223,6 +223,8 @@ if [ -f $FIRST_BOOT_FILE ]; then elif [ -f /host/minigraph.xml ]; then mkdir -p /etc/sonic/old_config mv /host/minigraph.xml /etc/sonic/old_config/ + [ -f /host/acl.json ] && mv /host/acl.json /etc/sonic/old_config/ + [ -f /host/snmp.yml ] && mv /host/snmp.yml /etc/sonic/old_config/ touch /tmp/pending_config_migration elif [ -n "$migration" ] && [ -f /host/migration/minigraph.xml ]; then mkdir -p /etc/sonic/old_config From 6a76cd2bb68e8ca4b61667e834e6dfed099eb76e Mon Sep 17 00:00:00 2001 From: Vitaliy Senchyshyn <43479243+vsenchyshyn@users.noreply.github.com> Date: Thu, 7 Nov 2019 11:01:54 -0800 Subject: [PATCH 0136/1427] [build]: Fixed BFN target build (#3721) Signed-off-by: Vitaliy Senchyshyn --- platform/barefoot/bfn-platform.mk | 4 ++-- platform/barefoot/bfn-sai.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 15fbd80daafd..32ba62e3feb2 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ -BFN_PLATFORM = bfnplatform_9.0.0.e658347_deb9.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_0/bfnplatform_9.0.0.e658347_deb9.deb" +BFN_PLATFORM = bfnplatform_20191107_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnplatform_20191107_deb9.deb" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 2e6b8f711fda..366a7487deb8 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,5 @@ -BFN_SAI = bfnsdk_9.0.0.e658347_deb9.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_0/bfnsdk_9.0.0.e658347_deb9.deb" +BFN_SAI = bfnsdk_20191107_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnsdk_20191107_deb9.deb" SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) From a5e2799b338df79f38798eef608ad92367efeec0 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar T <53558409+santhosh-kt@users.noreply.github.com> Date: Fri, 8 Nov 2019 02:57:02 +0530 Subject: [PATCH 0137/1427] [DellEMC] S6100 Watchdog Support (#3698) Implement Watchdog platform2.0 API for DellEMC S6100 platform. - Added new file watchdog.py in sonic_platform directory. - Enabled API support to Enable/disable watchdog. --- .../s6100/sonic_platform/watchdog.py | 227 ++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/watchdog.py diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/watchdog.py new file mode 100644 index 000000000000..207ccb8971bc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/watchdog.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python + +######################################################################## +# +# DELLEMC S6100 +# +# Abstract base class for implementing a platform-specific class with +# which to interact with a hardware watchdog module in SONiC +# +######################################################################## + +try: + import os + import struct + import ctypes + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class _timespec(ctypes.Structure): + _fields_ = [ + ('tv_sec', ctypes.c_long), + ('tv_nsec', ctypes.c_long) + ] + +class Watchdog(WatchdogBase): + """ + Abstract base class for interfacing with a hardware watchdog module + """ + + io_resource = '/dev/port' + + WD_STATUS_OFFSET = 0x207 + WD_TIMER_OFFSET = 0x206 + WD_ENABLE = 0 + WD_DISABLE = 1 + + armed_time = 0 + timeout = 0 + CLOCK_MONOTONIC = 1 + + def __init__(self): + self._librt = ctypes.CDLL('librt.so.1', use_errno=True) + self._clock_gettime = self._librt.clock_gettime + self._clock_gettime.argtypes=[ctypes.c_int, ctypes.POINTER(_timespec)] + + def _io_reg_read(self, offset): + """ + Read the resource file + """ + fd = os.open(self.io_resource, os.O_RDONLY) + if fd < 0: + return -1 + + if os.lseek(fd, offset, os.SEEK_SET) != offset: + os.close(fd) + return -1 + + buf = os.read(fd, 1) + reg_value = ord(buf) + + os.close(fd) + return reg_value + + def _io_reg_write(self, offset, val): + """ + Write in the resource file + """ + fd = os.open(self.io_resource, os.O_RDWR) + if fd < 0: + return -1 + + if os.lseek(fd, offset, os.SEEK_SET) != offset: + os.close(fd) + return -1 + + ret = os.write(fd, struct.pack('B', val)) + if ret != 1: + os.close(fd) + return -1 + + os.close(fd) + return ret + + def _read_gpio_file(self, file_path): + """ + Read the GPIO values + """ + fd = os.open(file_path, os.O_RDONLY) + read_str = os.read(fd, os.path.getsize(file_path)) + gpio_val = int(read_str, 16) + os.close(fd) + return gpio_val + + def _write_gpio_file(self, file_path, val): + """ + Write the GPIO values + """ + fd = os.open(file_path, os.O_RDWR) + ret = os.write(fd, val) + if ret < 0: + os.close(fd) + return -1 + + os.close(fd) + return 1 + + def _get_time(self): + """ + To get clock monotonic time + """ + ts = _timespec() + if self._clock_gettime(self.CLOCK_MONOTONIC, ctypes.pointer(ts)) != 0: + errno_ = ctypes.get_errno() + return 0 + return ts.tv_sec + ts.tv_nsec * 1e-9 + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* + available value. + + Returns: + An integer specifying the *actual* number of seconds the + watchdog was armed with. On failure returns -1. + """ + gpio = "/sys/devices/platform/dell_ich.0/sc_gp_lvl" + timer_offset = -1 + if seconds <= 30: + timer_offset = 1 + seconds = 30 + elif seconds > 30 and seconds <= 60: + timer_offset = 2 + seconds = 60 + elif seconds > 60 and seconds <= 180: + timer_offset = 3 + seconds = 180 + + if timer_offset == -1: + return -1 + if self._io_reg_read(self.WD_TIMER_OFFSET) != timer_offset: + if self._io_reg_write(self.WD_TIMER_OFFSET, timer_offset) == -1: + return -1 + self.disarm() + + if self.is_armed(): + gpio_val = self._read_gpio_file(gpio) + high_val = gpio_val | (1 << 15) + if self._write_gpio_file(gpio, hex(high_val)) != -1: + low_val = high_val & 0xFFFF7FFF + if self._write_gpio_file(gpio, hex(low_val)) != -1: + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + elif self._io_reg_write(self.WD_STATUS_OFFSET, self.WD_ENABLE) != -1: + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + + return -1 + + def disarm(self): + """ + Disarm the hardware watchdog + + Returns: + A boolean, True if watchdog is disarmed successfully, False + if not + """ + if self._io_reg_write(self.WD_STATUS_OFFSET, self.WD_DISABLE) != -1: + self.armed_time = 0 + self.timeout = 0 + return True + + return False + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + + Returns: + A boolean, True if watchdog is armed, False if not + """ + wd_status = self.WD_DISABLE + wd_status = self._io_reg_read(self.WD_STATUS_OFFSET) + if wd_status == self.WD_ENABLE: + return True + + return False + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds + remaining on the watchdog timer + + Returns: + An integer specifying the number of seconds remaining on + their watchdog timer. If the watchdog is not armed, returns + -1. + + S6100 doesnot have hardware support to show remaining time. + Due to this limitation, this API is implemented in software. + This API would return correct software time difference if it + is called from the process which armed the watchdog timer. + If this API called from any other process, it would return + 0. If the watchdog is not armed, this API would return -1. + """ + if not self.is_armed(): + return -1 + + if self.armed_time > 0 and self.timeout != 0: + cur_time = self._get_time() + if cur_time <= 0: + return 0 + diff_time = int(cur_time - self.armed_time) + if diff_time > self.timeout: + return self.timeout + else: + return self.timeout - diff_time + + return 0 + From bdf1b7c6074e5e0f34b25786298a5124088db594 Mon Sep 17 00:00:00 2001 From: Ping Mao <41933969+li-pingmao@users.noreply.github.com> Date: Thu, 7 Nov 2019 13:45:39 -0800 Subject: [PATCH 0138/1427] libyang 1.0.73 (#3710) - build libyang1.0.73 debian pacakge from libyang github source - build libyang python2 and python3 debian packages --- rules/libyang.mk | 21 +++-- src/libyang/Makefile | 25 +++--- src/libyang/patch/libyang.patch | 134 +++++++++++++++++++++++++++++++ src/libyang/patch/series | 2 + src/libyang/patch/swig.patch | 136 ++++++++++++++++++++++++++++++++ 5 files changed, 303 insertions(+), 15 deletions(-) create mode 100644 src/libyang/patch/libyang.patch create mode 100644 src/libyang/patch/series create mode 100644 src/libyang/patch/swig.patch diff --git a/rules/libyang.mk b/rules/libyang.mk index 2561be6b7122..d10c2ea2cc66 100644 --- a/rules/libyang.mk +++ b/rules/libyang.mk @@ -1,23 +1,32 @@ # libyang -LIBYANG_VERSION_BASE = 0.16 -LIBYANG_VERSION = $(LIBYANG_VERSION_BASE).105 +LIBYANG_VERSION_BASE = 1.0 +LIBYANG_VERSION = $(LIBYANG_VERSION_BASE).73 LIBYANG_SUBVERSION = 1 export LIBYANG_VERSION_BASE export LIBYANG_VERSION export LIBYANG_SUBVERSION -LIBYANG = libyang$(LIBYANG_VERSION_BASE)_$(LIBYANG_VERSION)-$(LIBYANG_SUBVERSION)_$(CONFIGURED_ARCH).deb +LIBYANG = libyang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(LIBYANG)_SRC_PATH = $(SRC_PATH)/libyang $(LIBYANG)_DEPENDS += $(SWIG_BASE) $(SWIG) SONIC_MAKE_DEBS += $(LIBYANG) SONIC_STRETCH_DEBS += $(LIBYANG) -LIBYANG_DEV = libyang-dev_$(LIBYANG_VERSION)-$(LIBYANG_SUBVERSION)_$(CONFIGURED_ARCH).deb +LIBYANG_DEV = libyang-dev_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_DEV))) -LIBYANG_DBG = libyang$(LIBYANG_VERSION_BASE)-dbgsym_$(LIBYANG_VERSION)-$(LIBYANG_SUBVERSION)_$(CONFIGURED_ARCH).deb +LIBYANG_DBG = libyang-dbg_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_DBG))) -export LIBYANG LIBYANG_DEV LIBYANG_DBG +LIBYANG_CPP = libyang-cpp_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_CPP))) + +LIBYANG_PY3 = python3-yang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_PY3))) + +LIBYANG_PY2 = python2-yang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_PY2))) + +export LIBYANG LIBYANG_DBG LIBYANG_DEV LIBYANG_CPP LIBYANG_PY3 LIBYANG_PY2 diff --git a/src/libyang/Makefile b/src/libyang/Makefile index cb58f7c5128b..32cabdf13bdf 100644 --- a/src/libyang/Makefile +++ b/src/libyang/Makefile @@ -3,19 +3,26 @@ SHELL = /bin/bash .SHELLFLAGS += -e MAIN_TARGET = $(LIBYANG) -DERIVED_TARGETS = $(LIBYANG_DEV) $(LIBYANG_DBG) +DERIVED_TARGETS = $(LIBYANG_DEV) $(LIBYANG_DBG) $(LIBYANG_PY2) $(LIBYANG_PY3) $(LIBYANG_CPP) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Obtaining the libyang rm -fr ./libyang-$(LIBYANG_VERSION) - wget -O libyang_$(LIBYANG_VERSION).orig.tar.gz 'https://sonicstorage.blob.core.windows.net/packages/libyang_0.16.105.orig.tar.gz?sv=2015-04-05&sr=b&sig=yTWDhl6B9TTXWAQ46zpLiNxUib61W7U0%2F%2FGvhRibKOc%3D&se=2046-09-30T22%3A10%3A27Z&sp=r' - wget -O libyang_$(LIBYANG_VERSION).dsc 'https://sonicstorage.blob.core.windows.net/packages/libyang_0.16.105-1.dsc?sv=2015-04-05&sr=b&sig=eLkO5wzB1C5oKNIaUPro4gwrgEC3EygIO6eCyTzHmeI%3D&se=2046-09-30T22%3A10%3A12Z&sp=r' - wget -O libyang_$(LIBYANG_VERSION)-$(LIBYANG_SUBVERSION).debian.tar.xz 'https://sonicstorage.blob.core.windows.net/packages/libyang_0.16.105-1.debian.tar.xz?sv=2015-04-05&sr=b&sig=AH18p7pKK0xIBVxZuA8EMv9%2FhXbCFKmbWAn7Za8%2BZW4%3D&se=2046-09-30T22%3A09%3A36Z&sp=r' - dpkg-source -x libyang_$(LIBYANG_VERSION).dsc + git clone https://github.com/CESNET/libyang.git libyang-$(LIBYANG_VERSION) + pushd libyang-$(LIBYANG_VERSION) + git checkout tags/v1.0-r4 -b libyang + # Apply patch series + stg init + stg import -s ../patch/series - pushd ./libyang-$(LIBYANG_VERSION) - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) - popd + mkdir build + pushd build + cmake .. + make build-deb - mv $(DERIVED_TARGETS) $* $(DEST)/ + pushd debs + mv $* $(DEST)/ + mv $(DERIVED_TARGETS) $(DEST)/ + popd $(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/libyang/patch/libyang.patch b/src/libyang/patch/libyang.patch new file mode 100644 index 000000000000..a950d85086ab --- /dev/null +++ b/src/libyang/patch/libyang.patch @@ -0,0 +1,134 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index fa562dd3..8635ba15 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -33,6 +33,7 @@ set(LIBYANG_MICRO_SOVERSION 2) + set(LIBYANG_SOVERSION_FULL ${LIBYANG_MAJOR_SOVERSION}.${LIBYANG_MINOR_SOVERSION}.${LIBYANG_MICRO_SOVERSION}) + set(LIBYANG_SOVERSION ${LIBYANG_MAJOR_SOVERSION}) + ++set(CMAKE_INSTALL_PREFIX /usr) + # set default build type if not specified by user + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE debug) +diff --git a/packages/debian.control.in b/packages/debian.control.in +index da6588b9..fb3ede48 100644 +--- a/packages/debian.control.in ++++ b/packages/debian.control.in +@@ -53,3 +53,15 @@ Depends: python3-yang@PACKAGE_PART_NAME@ (=@LIBYANG_VERSION@) + Section: debug + Architecture: any + Description: Debug symbols of python3 bidings of libyang library. ++ ++Package: python2-yang@PACKAGE_PART_NAME@ ++Depends: @PACKAGE_NAME@ (=@LIBYANG_VERSION@), libyang-cpp@PACKAGE_PART_NAME@ (=@LIBYANG_VERSION@) ++Section: libs ++Architecture: any ++Description: Bindings of libyang library to python2 language. ++ ++Package: python2-yang@PACKAGE_PART_NAME@-dbg ++Depends: python2-yang@PACKAGE_PART_NAME@ (=@LIBYANG_VERSION@) ++Section: debug ++Architecture: any ++Description: Debug symbols of python2 bidings of libyang library. +diff --git a/packages/debian.python2-yang.install b/packages/debian.python2-yang.install +new file mode 100644 +index 00000000..14ce2f3c +--- /dev/null ++++ b/packages/debian.python2-yang.install +@@ -0,0 +1 @@ ++usr/lib/python2.7/dist-packages/* +diff --git a/packages/debian.rules.in b/packages/debian.rules.in +index d565819e..e92fe4a1 100644 +--- a/packages/debian.rules.in ++++ b/packages/debian.rules.in +@@ -9,10 +9,14 @@ export DH_VERBOSE=1 + override_dh_strip: + dh_strip -plibyang@PACKAGE_PART_NAME@ --dbg-package=libyang@PACKAGE_PART_NAME@-dbg + dh_strip -plibyang-cpp@PACKAGE_PART_NAME@ --dbg-package=libyang-cpp@PACKAGE_PART_NAME@-dbg ++ dh_strip -ppython2-yang@PACKAGE_PART_NAME@ --dbg-package=python2-yang@PACKAGE_PART_NAME@-dbg + dh_strip -ppython3-yang@PACKAGE_PART_NAME@ --dbg-package=python3-yang@PACKAGE_PART_NAME@-dbg + + override_dh_auto_configure: +- cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_BUILD_TYPE:String="@BUILD_TYPE@" -DGEN_LANGUAGE_BINDINGS=ON . ++ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_BUILD_TYPE:String="@BUILD_TYPE@" -DENABLE_LYD_PRIV=ON -DGEN_LANGUAGE_BINDINGS=ON -DGEN_PYTHON_VERSION=2 . ++ ++override_dh_makeshlibs: ++ dh_makeshlibs -Xextensions -Xuser_types + + override_dh_auto_test: + ctest --output-on-failure +diff --git a/packages/libyang.dsc.in b/packages/libyang.dsc.in +index fdfa402b..f75ba184 100644 +--- a/packages/libyang.dsc.in ++++ b/packages/libyang.dsc.in +@@ -1,10 +1,10 @@ + Format: 3.0 (quilt) + Source: @PACKAGE_NAME@ +-Binary: @PACKAGE_NAME@, @PACKAGE_NAME@-dbg, @PACKAGE_NAME@-dev, libyang-cpp@PACKAGE_PART_NAME@, libyang-cpp@PACKAGE_PART_NAME@-dev, libyang-cpp@PACKAGE_PART_NAME@-dbg, python3-yang@PACKAGE_PART_NAME@, python3-yang@PACKAGE_PART_NAME@-dbg ++Binary: @PACKAGE_NAME@, @PACKAGE_NAME@-dbg, @PACKAGE_NAME@-dev, libyang-cpp@PACKAGE_PART_NAME@, libyang-cpp@PACKAGE_PART_NAME@-dev, libyang-cpp@PACKAGE_PART_NAME@-dbg, python3-yang@PACKAGE_PART_NAME@, python3-yang@PACKAGE_PART_NAME@-dbg python2-yang@PACKAGE_PART_NAME@, python2-yang@PACKAGE_PART_NAME@-dbg + Maintainer: CESNET + Version: @LIBYANG_VERSION@ + Architecture: any + Standards-Version: 3.8.2 + Homepage: https://github.com/CESNET/libyang + Vcs-Git: https://github.com/CESNET/libyang +-Build-Depends: debhelper (>= 9), make, gcc, doxygen, cmake, pkg-config, libpcre3-dev, libcmocka-dev, python3-dev, g++, swig (>= 3.0.12) ++Build-Depends: debhelper (>= 9), make, gcc, doxygen, cmake, pkg-config, libpcre3-dev, libcmocka-dev, python3-dev, python2-dev, g++, swig (>= 3.0.12) +diff --git a/packages/libyang.spec.in b/packages/libyang.spec.in +index 6a4ac615..6939f028 100644 +--- a/packages/libyang.spec.in ++++ b/packages/libyang.spec.in +@@ -46,6 +46,8 @@ BuildRequires: python3-devel + %else + BuildRequires: python34-devel + %endif ++ ++BuildRequires: python2-devel + %endif + + Conflicts: @CONFLICT_PACKAGE_NAME@ = @LIBYANG_MAJOR_VERSION@.@LIBYANG_MINOR_VERSION@ +@@ -70,6 +72,11 @@ Summary: Binding to python + Requires: libyang-cpp@PACKAGE_PART_NAME@ = %{version}-%{release} + Requires: %{name} = %{version}-%{release} + ++%package -n python2-yang@PACKAGE_PART_NAME@ ++Summary: Binding to python ++Requires: libyang-cpp@PACKAGE_PART_NAME@ = %{version}-%{release} ++Requires: %{name} = %{version}-%{release} ++ + %description -n libyang-cpp@PACKAGE_PART_NAME@ + Bindings of libyang library to C++ language. + +@@ -80,6 +87,10 @@ Headers of bindings to c++ language. + Bindings of libyang library to python language. + %endif + ++%description -n python2-yang@PACKAGE_PART_NAME@ ++Bindings of libyang library to python language. ++%endif ++ + %description devel + Headers of libyang library. + +@@ -167,4 +178,9 @@ make DESTDIR=%{buildroot} install + %{_libdir}/python* + %endif + ++%files -n python2-yang@PACKAGE_PART_NAME@ ++%defattr(-,root,root) ++%{_libdir}/python* ++%endif ++ + %changelog +diff --git a/packages/local-deb.sh.in b/packages/local-deb.sh.in +index 057bbc67..4318a49d 100755 +--- a/packages/local-deb.sh.in ++++ b/packages/local-deb.sh.in +@@ -18,6 +18,7 @@ fi + cp "@PROJECT_SOURCE_DIR@/packages/debian.libyang-dev.install" debian/@PACKAGE_NAME@-dev.install + cp "@PROJECT_SOURCE_DIR@/packages/debian.libyang-cpp.install" debian/libyang-cpp@PACKAGE_PART_NAME@.install + cp "@PROJECT_SOURCE_DIR@/packages/debian.libyang-cpp-dev.install" debian/libyang-cpp@PACKAGE_PART_NAME@-dev.install ++cp "@PROJECT_SOURCE_DIR@/packages/debian.python2-yang.install" debian/python2-yang@PACKAGE_PART_NAME@.install + cp "@PROJECT_SOURCE_DIR@/packages/debian.python3-yang.install" debian/python3-yang@PACKAGE_PART_NAME@.install + echo -e "@PACKAGE_NAME@ (@LIBYANG_VERSION@) stable; urgency=low\n" >debian/changelog + git log -10 --pretty=format:' * %s (%aN)%n' 2>/dev/null >>debian/changelog || echo -e " * unknown changes \n" >>debian/changelog diff --git a/src/libyang/patch/series b/src/libyang/patch/series new file mode 100644 index 000000000000..773245e4eed5 --- /dev/null +++ b/src/libyang/patch/series @@ -0,0 +1,2 @@ +libyang.patch +swig.patch diff --git a/src/libyang/patch/swig.patch b/src/libyang/patch/swig.patch new file mode 100644 index 000000000000..a6f798c18224 --- /dev/null +++ b/src/libyang/patch/swig.patch @@ -0,0 +1,136 @@ +diff --git a/swig/CMakeLists.txt b/swig/CMakeLists.txt +index 4cee36ec..0baa69ab 100644 +--- a/swig/CMakeLists.txt ++++ b/swig/CMakeLists.txt +@@ -20,27 +20,34 @@ endif() + + # find Python package + if(GEN_PYTHON_BINDINGS AND SWIG_FOUND) +- message(STATUS "Python version ${GEN_PYTHON_VERSION} was selected") +- unset(PYTHON_LIBRARY CACHE) +- unset(PYTHON_EXECUTABLE CACHE) +- unset(PYTHON_INCLUDE_DIR CACHE) +- unset(PYTHON_LIBRARY_DEBUG CACHE) +- if(${GEN_PYTHON_VERSION} STREQUAL "2") +- find_package(PythonLibs 2 REQUIRED) +- find_package(PythonInterp 2 REQUIRED) +- if(NOT PYTHONLIBS_FOUND) +- message(WARNING "Did not found Python version 2.x") +- message(STATUS "Sysrepo supports Python 2.x and Python 3.x") +- endif() +- elseif(${GEN_PYTHON_VERSION} STREQUAL "3") +- find_package(PythonLibs 3 REQUIRED) +- find_package(PythonInterp 3 REQUIRED) +- if(NOT PYTHONLIBS_FOUND) +- message(WARNING "Did not found Python version 3.x") +- message(STATUS "Sysrepo supports Python 2.x and Python 3.x") +- endif() ++ if(ENABLE_STATIC) ++ message(WARNING "Can't create a static Python module") + else() +- message(WARNING "Sysrepo supports Python 2.x and Python 3.x") ++ set(GEN_PYTHON_VERSION 2 3) ++ foreach(CUR_PYTHON_VERSION ${GEN_PYTHON_VERSION}) ++ message(STATUS "Python version ${CUR_PYTHON_VERSION} was selected") ++ ++ unset(PYTHON_EXECUTABLE CACHE) ++ unset(PYTHON_INCLUDE_PATH CACHE) ++ unset(PYTHON_EXT_SUFFIX CACHE) ++ unset(PYTHON_MODULE_PATH CACHE) ++ set(PYTHON_EXT_SUFFIX ".so") ++ ++ find_program(PYTHON_EXECUTABLE NAMES python${CUR_PYTHON_VERSION}) ++ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c ++ "from distutils.sysconfig import get_config_var; print(get_config_var('INCLUDEPY'))" ++ OUTPUT_VARIABLE PYTHON_INCLUDE_PATH ++ OUTPUT_STRIP_TRAILING_WHITESPACE ) ++ #execute_process(COMMAND ${PYTHON_EXECUTABLE} -c ++ # "from distutils.sysconfig import get_config_var; print(get_config_var('EXT_SUFFIX'))" ++ # OUTPUT_VARIABLE PYTHON_EXT_SUFFIX ++ # OUTPUT_STRIP_TRAILING_WHITESPACE ) ++ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c ++ "from distutils.sysconfig import get_python_lib; print(get_python_lib(plat_specific=True))" ++ OUTPUT_VARIABLE PYTHON_MODULE_PATH ++ OUTPUT_STRIP_TRAILING_WHITESPACE ) ++ add_subdirectory(python python${CUR_PYTHON_VERSION}) ++ endforeach(CUR_PYTHON_VERSION) + endif() + endif() + +@@ -99,12 +106,6 @@ if (GEN_CPP_BINDINGS) + endif() + endif() + +-if(ENABLE_STATIC AND PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND AND (${GEN_PYTHON_VERSION} STREQUAL "2" OR ${GEN_PYTHON_VERSION} STREQUAL "3")) +- message(WARNING "Can't create a static Python module") +-elseif(PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND AND (${GEN_PYTHON_VERSION} STREQUAL "2" OR ${GEN_PYTHON_VERSION} STREQUAL "3")) +- add_subdirectory(python) +-endif() +- + if(NOT ENABLE_STATIC AND GEN_JAVASCRIPT_BINDINGS) + message(WARNING "Can't create Javascript bindings with a shared library, please use -DENABLE_STATIC") + elseif(ENABLE_STATIC AND GEN_JAVASCRIPT_BINDINGS) +diff --git a/swig/python/CMakeLists.txt b/swig/python/CMakeLists.txt +index 994b1234..5d18b8bf 100644 +--- a/swig/python/CMakeLists.txt ++++ b/swig/python/CMakeLists.txt +@@ -1,30 +1,38 @@ + set(PYTHON_SWIG_BINDING yang) ++set(PYTHON_SWIG_TARGET yang${CUR_PYTHON_VERSION}) + include_directories(${PYTHON_INCLUDE_PATH}) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) ++include_directories(${PROJECT_SOURCE_DIR}/cpp/src) + + set(CMAKE_SWIG_FLAGS "-c++") +-set(CMAKE_SWIG_FLAGS "-I${PROJECT_SOURCE_DIR}") ++set(CMAKE_SWIG_FLAGS "-I${PROJECT_SOURCE_DIR}" "-I${PROJECT_SOURCE_DIR}/cpp/src") + set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}) + +-set_source_files_properties(${PYTHON_SWIG_BINDING}.i PROPERTIES CPLUSPLUS ON PREFIX "") ++set_source_files_properties(${PYTHON_SWIG_BINDING}.i PROPERTIES CPLUSPLUS ON PREFIX "" SWIG_MODULE_NAME ${PYTHON_SWIG_BINDING}) + + if(${CMAKE_VERSION} VERSION_LESS "3.8.0") +- swig_add_module(${PYTHON_SWIG_BINDING} python ${PYTHON_SWIG_BINDING}.i) ++ swig_add_module(${PYTHON_SWIG_TARGET} python ${PYTHON_SWIG_BINDING}.i) + else() +- swig_add_library(${PYTHON_SWIG_BINDING} LANGUAGE python SOURCES ${PYTHON_SWIG_BINDING}.i) ++ swig_add_library(${PYTHON_SWIG_TARGET} LANGUAGE python SOURCES ${PYTHON_SWIG_BINDING}.i) + endif() +-swig_link_libraries(${PYTHON_SWIG_BINDING} ${PYTHON_LIBRARIES} libyang-cpp) ++swig_link_libraries(${PYTHON_SWIG_TARGET} ${PYTHON_LIBRARIES} libyang-cpp) ++ ++set_target_properties(_${PYTHON_SWIG_TARGET} PROPERTIES OUTPUT_NAME "_yang${PYTHON_EXT_SUFFIX}" SUFFIX "") + + # Generate header with SWIG run-time functions + execute_process(COMMAND ${SWIG_EXECUTABLE} -python -external-runtime ${CMAKE_CURRENT_BINARY_DIR}/swigpyrun.h) + +-file(COPY "examples" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) ++add_custom_command(TARGET ${PYTHON_SWIG_TARGET}_swig_compilation POST_BUILD ++ COMMAND sed -e "'s/\\(inst =.*tp_new.*\\)Py_None, Py_None);/PyObject *tup = PyTuple_New(0); \\1tup, Py_None); Py_DECREF(tup);/'" < swigpyrun.h > swigpyrun.h.new ++ COMMAND sed -e "'s/\\(inst =.*tp_new.*\\)Py_None, Py_None);/PyObject *tup = PyTuple_New(0); \\1tup, Py_None); Py_DECREF(tup);/'" < yangPYTHON_wrap.cxx > yangPYTHON_wrap.cxx.new ++ COMMAND diff -q swigpyrun.h swigpyrun.h.new || mv swigpyrun.h.new swigpyrun.h ++ COMMAND diff -q yangPYTHON_wrap.cxx yangPYTHON_wrap.cxx.new || mv yangPYTHON_wrap.cxx.new yangPYTHON_wrap.cxx ++ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ++ ) + +-execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(plat_specific=True))" +- OUTPUT_VARIABLE PYTHON_MODULE_PATH +- OUTPUT_STRIP_TRAILING_WHITESPACE ) ++file(COPY "examples" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + +-install( TARGETS _${PYTHON_SWIG_BINDING} DESTINATION ${PYTHON_MODULE_PATH}) ++install( TARGETS _${PYTHON_SWIG_TARGET} DESTINATION ${PYTHON_MODULE_PATH}) + install( FILES "${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_SWIG_BINDING}.py" DESTINATION ${PYTHON_MODULE_PATH}) + install( FILES "${CMAKE_CURRENT_BINARY_DIR}/swigpyrun.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libyang) + +@@ -51,8 +59,8 @@ if(ENABLE_BUILD_TESTS) + ADD_PYTHON_TEST(test_tree_data) + ADD_PYTHON_TEST(test_tree_schema) + +- add_custom_command(TARGET ${SWIG_MODULE_${PYTHON_SWIG_BINDING}_REAL_NAME} POST_BUILD +- COMMAND cp "${CMAKE_CURRENT_BINARY_DIR}/_${PYTHON_SWIG_BINDING}.so" ${PY2_SWIG_DIR}/tests ++ add_custom_command(TARGET ${SWIG_MODULE_${PYTHON_SWIG_TARGET}_REAL_NAME} POST_BUILD ++ COMMAND cp "${CMAKE_CURRENT_BINARY_DIR}/_yang${PYTHON_EXT_SUFFIX}" ${PY2_SWIG_DIR}/tests/_yang.so + COMMAND cp "${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_SWIG_BINDING}.py" ${PY2_SWIG_DIR}/tests + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) From 6c0ab4b9261e5f3ce7b7a575e79a2b13c5021ea9 Mon Sep 17 00:00:00 2001 From: dereksun01 <52683998+dereksun01@users.noreply.github.com> Date: Fri, 8 Nov 2019 08:24:42 +0800 Subject: [PATCH 0139/1427] [device] accton device of as5812_54t supports SAI and modify as5812_54t periphery (#3663) - Support as5812_54t SAI. - Modify as5812_54t periphery. Signed-off-by: derek_sun --- .../Accton-AS5812-54T/port_config.ini | 146 +++++------ .../Accton-AS5812-54T/sai.profile | 2 +- .../td2-as5812-72x10G.config.bcm | 148 ------------ .../td2-as5812t-72x10G.config.bcm | 194 +++++++++++++++ .../led_proc_init.soc | 226 ++++++------------ .../as5812-54t/modules/Makefile | 2 +- .../modules/x86-64-accton-as5812-54t-leds.c | 18 +- .../as5812-54t/utils/accton_as5812_util.py | 1 - .../debian/rules | 2 +- 9 files changed, 353 insertions(+), 386 deletions(-) mode change 100755 => 100644 device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/port_config.ini mode change 100755 => 100644 device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile delete mode 100644 device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812-72x10G.config.bcm create mode 100644 device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/port_config.ini b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/port_config.ini old mode 100755 new mode 100644 index ee60c526227d..857a8987bc13 --- a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/port_config.ini +++ b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/port_config.ini @@ -1,73 +1,73 @@ -# name lanes alias index speed -Ethernet0 13 tenGigE0 1 10000 -Ethernet1 14 tenGigE1 2 10000 -Ethernet2 15 tenGigE2 3 10000 -Ethernet3 16 tenGigE3 4 10000 -Ethernet4 21 tenGigE4 5 10000 -Ethernet5 22 tenGigE5 6 10000 -Ethernet6 23 tenGigE6 7 10000 -Ethernet7 24 tenGigE7 8 10000 -Ethernet8 25 tenGigE8 9 10000 -Ethernet9 26 tenGigE9 10 10000 -Ethernet10 27 tenGigE10 11 10000 -Ethernet11 28 tenGigE11 12 10000 -Ethernet12 29 tenGigE12 13 10000 -Ethernet13 30 tenGigE13 14 10000 -Ethernet14 31 tenGigE14 15 10000 -Ethernet15 32 tenGigE15 16 10000 -Ethernet16 45 tenGigE16 17 10000 -Ethernet17 46 tenGigE17 18 10000 -Ethernet18 47 tenGigE18 19 10000 -Ethernet19 48 tenGigE19 20 10000 -Ethernet20 49 tenGigE20 21 10000 -Ethernet21 50 tenGigE21 22 10000 -Ethernet22 51 tenGigE22 23 10000 -Ethernet23 52 tenGigE23 24 10000 -Ethernet24 53 tenGigE24 25 10000 -Ethernet25 54 tenGigE25 26 10000 -Ethernet26 55 tenGigE26 27 10000 -Ethernet27 56 tenGigE27 28 10000 -Ethernet28 57 tenGigE28 29 10000 -Ethernet29 58 tenGigE29 30 10000 -Ethernet30 59 tenGigE30 31 10000 -Ethernet31 60 tenGigE31 32 10000 -Ethernet32 61 tenGigE32 33 10000 -Ethernet33 62 tenGigE33 34 10000 -Ethernet34 63 tenGigE34 35 10000 -Ethernet35 64 tenGigE35 36 10000 -Ethernet36 65 tenGigE36 37 10000 -Ethernet37 66 tenGigE37 38 10000 -Ethernet38 67 tenGigE38 39 10000 -Ethernet39 68 tenGigE39 40 10000 -Ethernet40 69 tenGigE40 41 10000 -Ethernet41 70 tenGigE41 42 10000 -Ethernet42 71 tenGigE42 43 10000 -Ethernet43 72 tenGigE43 44 10000 -Ethernet44 73 tenGigE44 45 10000 -Ethernet45 74 tenGigE45 46 10000 -Ethernet46 75 tenGigE46 47 10000 -Ethernet47 76 tenGigE47 48 10000 -Ethernet48 97 tenGigE48 49 10000 -Ethernet49 98 tenGigE49 49 10000 -Ethernet50 99 tenGigE50 49 10000 -Ethernet51 100 tenGigE51 49 10000 -Ethernet52 101 tenGigE52 50 10000 -Ethernet53 102 tenGigE53 50 10000 -Ethernet54 103 tenGigE54 50 10000 -Ethernet55 104 tenGigE55 50 10000 -Ethernet56 81 tenGigE56 51 10000 -Ethernet57 82 tenGigE57 51 10000 -Ethernet58 83 tenGigE58 51 10000 -Ethernet59 84 tenGigE59 51 10000 -Ethernet60 105 tenGigE60 52 10000 -Ethernet61 106 tenGigE61 52 10000 -Ethernet62 107 tenGigE62 52 10000 -Ethernet63 108 tenGigE63 52 10000 -Ethernet64 109 tenGigE64 53 10000 -Ethernet65 110 tenGigE65 53 10000 -Ethernet66 111 tenGigE66 53 10000 -Ethernet67 112 tenGigE67 53 10000 -Ethernet68 77 tenGigE68 54 10000 -Ethernet69 78 tenGigE69 54 10000 -Ethernet70 79 tenGigE70 54 10000 -Ethernet71 80 tenGigE71 54 10000 +# name lanes alias index speed autoneg +Ethernet0 14 tenGigE0 1 10000 1 +Ethernet1 13 tenGigE1 2 10000 1 +Ethernet2 16 tenGigE2 3 10000 1 +Ethernet3 15 tenGigE3 4 10000 1 +Ethernet4 22 tenGigE4 5 10000 1 +Ethernet5 21 tenGigE5 6 10000 1 +Ethernet6 24 tenGigE6 7 10000 1 +Ethernet7 23 tenGigE7 8 10000 1 +Ethernet8 26 tenGigE8 9 10000 1 +Ethernet9 25 tenGigE9 10 10000 1 +Ethernet10 28 tenGigE10 11 10000 1 +Ethernet11 27 tenGigE11 12 10000 1 +Ethernet12 30 tenGigE12 13 10000 1 +Ethernet13 29 tenGigE13 14 10000 1 +Ethernet14 32 tenGigE14 15 10000 1 +Ethernet15 31 tenGigE15 16 10000 1 +Ethernet16 46 tenGigE16 17 10000 1 +Ethernet17 45 tenGigE17 18 10000 1 +Ethernet18 48 tenGigE18 19 10000 1 +Ethernet19 47 tenGigE19 20 10000 1 +Ethernet20 50 tenGigE20 21 10000 1 +Ethernet21 49 tenGigE21 22 10000 1 +Ethernet22 52 tenGigE22 23 10000 1 +Ethernet23 51 tenGigE23 24 10000 1 +Ethernet24 54 tenGigE24 25 10000 1 +Ethernet25 53 tenGigE25 26 10000 1 +Ethernet26 56 tenGigE26 27 10000 1 +Ethernet27 55 tenGigE27 28 10000 1 +Ethernet28 58 tenGigE28 29 10000 1 +Ethernet29 57 tenGigE29 30 10000 1 +Ethernet30 60 tenGigE30 31 10000 1 +Ethernet31 59 tenGigE31 32 10000 1 +Ethernet32 62 tenGigE32 33 10000 1 +Ethernet33 61 tenGigE33 34 10000 1 +Ethernet34 64 tenGigE34 35 10000 1 +Ethernet35 63 tenGigE35 36 10000 1 +Ethernet36 66 tenGigE36 37 10000 1 +Ethernet37 65 tenGigE37 38 10000 1 +Ethernet38 68 tenGigE38 39 10000 1 +Ethernet39 67 tenGigE39 40 10000 1 +Ethernet40 70 tenGigE40 41 10000 1 +Ethernet41 69 tenGigE41 42 10000 1 +Ethernet42 72 tenGigE42 43 10000 1 +Ethernet43 71 tenGigE43 44 10000 1 +Ethernet44 74 tenGigE44 45 10000 1 +Ethernet45 73 tenGigE45 46 10000 1 +Ethernet46 76 tenGigE46 47 10000 1 +Ethernet47 75 tenGigE47 48 10000 1 +Ethernet48 97 tenGigE48 49 10000 0 +Ethernet49 98 tenGigE49 49 10000 0 +Ethernet50 99 tenGigE50 49 10000 0 +Ethernet51 100 tenGigE51 49 10000 0 +Ethernet52 101 tenGigE52 50 10000 0 +Ethernet53 102 tenGigE53 50 10000 0 +Ethernet54 103 tenGigE54 50 10000 0 +Ethernet55 104 tenGigE55 50 10000 0 +Ethernet56 77 tenGigE56 51 10000 0 +Ethernet57 78 tenGigE57 51 10000 0 +Ethernet58 79 tenGigE58 51 10000 0 +Ethernet59 80 tenGigE59 51 10000 0 +Ethernet60 105 tenGigE60 52 10000 0 +Ethernet61 106 tenGigE61 52 10000 0 +Ethernet62 107 tenGigE62 52 10000 0 +Ethernet63 108 tenGigE63 52 10000 0 +Ethernet64 109 tenGigE64 53 10000 0 +Ethernet65 110 tenGigE65 53 10000 0 +Ethernet66 111 tenGigE66 53 10000 0 +Ethernet67 112 tenGigE67 53 10000 0 +Ethernet68 81 tenGigE68 54 10000 0 +Ethernet69 82 tenGigE69 54 10000 0 +Ethernet70 83 tenGigE70 54 10000 0 +Ethernet71 84 tenGigE71 54 10000 0 diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile old mode 100755 new mode 100644 index 063814c1fcb3..dc4f243953bf --- a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile +++ b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5812-72x10G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5812t-72x10G.config.bcm diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812-72x10G.config.bcm b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812-72x10G.config.bcm deleted file mode 100644 index 4844616d0382..000000000000 --- a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812-72x10G.config.bcm +++ /dev/null @@ -1,148 +0,0 @@ -os=unix -bcm_stat_flags=0 -parity_enable=0 -parity_correction=0 - -bcm_num_cos=8 -l2_mem_entries=32768 -l3_mem_entries=16384 -l3_alpm_enable=2 -ipv6_lpm_128b_enable=1 - -mmu_lossless=0 -lls_num_l2uc=12 -module_64ports=0 - -#SFI -serdes_if_type=9 - -port_init_cl72=0 -phy_an_c73=5 # TSCMOD_CL73_CL37 - -#sdk6.5.5 only supports 156(default) or 125 -#xgxs_lcpll_xtal_refclk=1 -tslam_dma_enable=1 -table_dma_enable=1 - -#for 72 ports with 48 10G ports and 6 40G ports for breakout mode -pbmp_oversubscribe=0x1fffffffffffffffffe -pbmp_xport_xe=0x1fffffffffffffffffe - -rate_ext_mdio_divisor=96 - -#SFP+ 1-4 from WC3 -portmap_1=13:10 -portmap_2=14:10 -portmap_3=15:10 -portmap_4=16:10 - -#SFP+ 5-8 from WC5 -portmap_5=21:10 -portmap_6=22:10 -portmap_7=23:10 -portmap_8=24:10 - -#SFP+ 9-12 from WC6 -portmap_9=25:10 -portmap_10=26:10 -portmap_11=27:10 -portmap_12=28:10 - -#SFP+ 13-16 from WC7 -portmap_13=29:10 -portmap_14=30:10 -portmap_15=31:10 -portmap_16=32:10 - -#SFP+ 17-20 from WC11 -portmap_17=45:10 -portmap_18=46:10 -portmap_19=47:10 -portmap_20=48:10 - -#SFP+ 21-24 from WC12 -portmap_21=49:10 -portmap_22=50:10 -portmap_23=51:10 -portmap_24=52:10 - -#SFP+ 25-28 from WC13 -portmap_25=53:10 -portmap_26=54:10 -portmap_27=55:10 -portmap_28=56:10 - -#SFP+ 29-32 from WC14 -portmap_29=57:10 -portmap_30=58:10 -portmap_31=59:10 -portmap_32=60:10 - -#SFP+ 33-36 from WC15 -portmap_33=61:10 -portmap_34=62:10 -portmap_35=63:10 -portmap_36=64:10 - -#SFP+ 37-40 from WC16 -portmap_37=65:10 -portmap_38=66:10 -portmap_39=67:10 -portmap_40=68:10 - -#SFP+ 41-44 from WC17 -portmap_41=69:10 -portmap_42=70:10 -portmap_43=71:10 -portmap_44=72:10 - -#SFP+ 45-48 from WC18 -portmap_45=73:10 -portmap_46=74:10 -portmap_47=75:10 -portmap_48=76:10 - -# QSFP+ 49/WC24/port 49 -portmap_49=97:10 -portmap_50=98:10 -portmap_51=99:10 -portmap_52=100:10 - -# QSFP+ 51/WC25/port 50 -portmap_53=101:10 -portmap_54=102:10 -portmap_55=103:10 -portmap_56=104:10 - -# QSFP+ 53/WC20/port 51 -portmap_57=81:10 -portmap_58=82:10 -portmap_59=83:10 -portmap_60=84:10 - -# QSFP+ 50/WC26/port 52 -portmap_61=105:10 -portmap_62=106:10 -portmap_63=107:10 -portmap_64=108:10 - -# QSFP+ 52/WC27/port 53 -portmap_65=109:10 -portmap_66=110:10 -portmap_67=111:10 -portmap_68=112:10 - -# QSFP+ 54/WC19/port 54 -portmap_69=77:10 -portmap_70=78:10 -portmap_71=79:10 -portmap_72=80:10 - -# L3 ECMP -# - In Trident2, VP LAGs share the same table as ECMP group table. -# The first N entries are reserved for VP LAGs, where N is the value of the -# config property "max_vp_lags". By default this was set to 256 -l3_max_ecmp_mode=1 -max_vp_lags=0 - -stable_size=0x2000000 diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm new file mode 100644 index 000000000000..b55558521094 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm @@ -0,0 +1,194 @@ +bcm_num_cos=8 +bcm_stat_flags=0 +bcm_stat_interval=2000000 +bcm_tunnel_term_compatible_mode=1 + +cdma_timeout_usec=3000000 + +fpem_mem_entries=16384 + +ipv6_lpm_128b_enable=0x1 +ifp_inports_support_enable=1 + +l2xmsg_mode=1 +l2_mem_entries=32768 + +l3_alpm_enable=2 +l3_max_ecmp_mode=1 +l3_mem_entries=16384 +l3_alpm_ipv6_128b_bkt_rsvd=1 + +load_firmware=0x101 + +max_vp_lags=0 +module_64ports=1 +miim_intr_enable=0 +mem_cache_enable=0 +mdio_output_delay=15 + +os=unix +oversubscribe_mode=1 + +parity_enable=0 +port_flex_enable=1 +parity_correction=0 +phy_ext_rom_boot_xe=0 +phy_aux_voltage_enable=1 + +#for 72 ports with 48 10G ports and 6 40G ports for breakout mode +pbmp_xport_xe=0x7fffffffffffffffffe +pbmp_oversubscribe=0x7fffffffffffffffffe + +rate_ext_mdio_divisor=96 + +schan_intr_enable=0 +skip_L2_USER_ENTRY=0 +stable_size=0x2000000 +stable_size=0x5500000 ;Specify the stable cache size in bytes used for Warm boot operations + +tdma_timeout_usec=3000000 + +#port-lanes configuration +portmap_1=14:10 +portmap_2=13:10 +portmap_3=16:10 +portmap_4=15:10 +port_phy_addr_1=0x1 +port_phy_addr_2=0x0 +port_phy_addr_3=0x3 +port_phy_addr_4=0x2 + +portmap_5=22:10 +portmap_6=21:10 +portmap_7=24:10 +portmap_8=23:10 +port_phy_addr_5=0x5 +port_phy_addr_6=0x4 +port_phy_addr_7=0x7 +port_phy_addr_8=0x6 + +portmap_9=26:10 +portmap_10=25:10 +portmap_11=28:10 +portmap_12=27:10 +port_phy_addr_9=0x9 +port_phy_addr_10=0x8 +port_phy_addr_11=0xb +port_phy_addr_12=0xa + +portmap_13=30:10 +portmap_14=29:10 +portmap_15=32:10 +portmap_16=31:10 +port_phy_addr_13=0x21 +port_phy_addr_14=0x20 +port_phy_addr_15=0x23 +port_phy_addr_16=0x22 + +portmap_17=46:10 +portmap_18=45:10 +portmap_19=48:10 +portmap_20=47:10 +port_phy_addr_17=0x25 +port_phy_addr_18=0x24 +port_phy_addr_19=0x27 +port_phy_addr_20=0x26 + +portmap_21=50:10 +portmap_22=49:10 +portmap_23=52:10 +portmap_24=51:10 +port_phy_addr_21=0x29 +port_phy_addr_22=0x28 +port_phy_addr_23=0x2b +port_phy_addr_24=0x2a + +portmap_25=54:10 +portmap_26=53:10 +portmap_27=56:10 +portmap_28=55:10 +port_phy_addr_25=0x41 +port_phy_addr_26=0x40 +port_phy_addr_27=0x43 +port_phy_addr_28=0x42 + +portmap_29=58:10 +portmap_30=57:10 +portmap_31=60:10 +portmap_32=59:10 +port_phy_addr_29=0x45 +port_phy_addr_30=0x44 +port_phy_addr_31=0x47 +port_phy_addr_32=0x46 + +portmap_33=62:10 +portmap_34=61:10 +portmap_35=64:10 +portmap_36=63:10 +port_phy_addr_33=0x49 +port_phy_addr_34=0x48 +port_phy_addr_35=0x4b +port_phy_addr_36=0x4a + +portmap_37=66:10 +portmap_38=65:10 +portmap_39=68:10 +portmap_40=67:10 +port_phy_addr_37=0x61 +port_phy_addr_38=0x60 +port_phy_addr_39=0x63 +port_phy_addr_40=0x62 + +portmap_41=70:10 +portmap_42=69:10 +portmap_43=72:10 +portmap_44=71:10 +port_phy_addr_41=0x65 +port_phy_addr_42=0x64 +port_phy_addr_43=0x67 +port_phy_addr_44=0x66 + +portmap_45=74:10 +portmap_46=73:10 +portmap_47=76:10 +portmap_48=75:10 +port_phy_addr_45=0x69 +port_phy_addr_46=0x68 +port_phy_addr_47=0x6b +port_phy_addr_48=0x6a + +#port_49 +portmap_49=97:10 +portmap_50=98:10 +portmap_51=99:10 +portmap_52=100:10 + +#port_50 +portmap_53=101:10 +portmap_54=102:10 +portmap_55=103:10 +portmap_56=104:10 + +#port_51 +portmap_57=77:10 +portmap_58=78:10 +portmap_59=79:10 +portmap_60=80:10 + +#port_52 +portmap_61=105:10 +portmap_62=106:10 +portmap_63=107:10 +portmap_64=108:10 + +#port_53 +portmap_65=109:10 +portmap_66=110:10 +portmap_67=111:10 +portmap_68=112:10 + +#port_54 +portmap_69=81:10 +portmap_70=82:10 +portmap_71=83:10 +portmap_72=84:10 \ No newline at end of file diff --git a/device/accton/x86_64-accton_as5812_54t-r0/led_proc_init.soc b/device/accton/x86_64-accton_as5812_54t-r0/led_proc_init.soc index d93e373d0567..954446d4a8ba 100644 --- a/device/accton/x86_64-accton_as5812_54t-r0/led_proc_init.soc +++ b/device/accton/x86_64-accton_as5812_54t-r0/led_proc_init.soc @@ -1,162 +1,94 @@ # LED setting for active # ----------------------------------------------------------------------------- -# for as5812_54x (48xg+6qxg) +# for as5812_54t (48xg+6qxg) # # on green - if link up # off - if link down # blink - if active # ----------------------------------------------------------------------------- -m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=0 -m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_62=1 -m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_61=2 -m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 -m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=4 -m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_58=5 -m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_57=6 -m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 -m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=8 -m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_54=9 -m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_53=10 -m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 -m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=12 -m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_50=13 -m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_49=14 -m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 -m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=16 -m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_34=17 -m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_33=18 -m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=19 -m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=20 -m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_38=21 -m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_37=22 -m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=23 -m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=24 -m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_42=25 -m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_41=26 -m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=27 -m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=28 -m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_46=29 -m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_45=30 -m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=31 -m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=32 -m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_30=33 -m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_29=34 -m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=35 -m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=36 -m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_26=37 -m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_25=38 -m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=39 -m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=40 -m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_22=41 -m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_21=42 -m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=43 -m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=44 -m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_18=45 -m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_17=46 -m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=47 -m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=48 -m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_2=49 -m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_1=50 -m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=51 -m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=52 -m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_6=53 -m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_5=54 -m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=55 -m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=56 -m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_10=57 -m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_9=58 -m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=59 -m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=60 -m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_14=61 -m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_13=62 -m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=63 -m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=0 -m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_62=1 -m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_61=2 -m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 -m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=4 -m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_58=5 -m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_57=6 -m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 -m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=8 -m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_54=9 -m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_53=10 -m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 -m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=12 -m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_50=13 -m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_49=14 -m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 -m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=16 -m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_34=17 -m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_33=18 -m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=19 -m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=20 -m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_38=21 -m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_37=22 -m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=23 -m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=24 -m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_42=25 -m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_41=26 -m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=27 -m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=28 -m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_46=29 -m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_45=30 -m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=31 -m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=32 -m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_30=33 -m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_29=34 -m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=35 -m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=36 -m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_26=37 -m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_25=38 -m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=39 -m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=40 -m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_22=41 -m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_21=42 -m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=43 -m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=44 -m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_18=45 -m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_17=46 -m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=47 -m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=48 -m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_2=49 -m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_1=50 -m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=51 -m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=52 -m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_6=53 -m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_5=54 -m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=55 -m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=56 -m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_10=57 -m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_9=58 -m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=59 -m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=60 -m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_14=61 -m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_13=62 -m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=63 +m xlmac_rx_ctrl.xe0-xe47 STRICT_PREAMBLE=0 + +link on +link off + +m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=12 REMAP_PORT_1=13 REMAP_PORT_2=14 REMAP_PORT_3=15 +m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=8 REMAP_PORT_5=9 REMAP_PORT_6=10 REMAP_PORT_7=11 +m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=4 REMAP_PORT_9=5 REMAP_PORT_10=6 REMAP_PORT_11=7 +m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=0 REMAP_PORT_13=1 REMAP_PORT_14=2 REMAP_PORT_15=3 +m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=16 REMAP_PORT_17=17 REMAP_PORT_18=18 REMAP_PORT_19=19 +m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=63 REMAP_PORT_21=62 REMAP_PORT_22=61 REMAP_PORT_23=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=63 REMAP_PORT_25=62 REMAP_PORT_26=61 REMAP_PORT_27=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=63 REMAP_PORT_29=62 REMAP_PORT_30=61 REMAP_PORT_31=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=63 REMAP_PORT_33=62 REMAP_PORT_34=61 REMAP_PORT_35=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=28 REMAP_PORT_37=29 REMAP_PORT_38=30 REMAP_PORT_39=31 +m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=24 REMAP_PORT_41=25 REMAP_PORT_42=26 REMAP_PORT_43=27 +m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=20 REMAP_PORT_45=21 REMAP_PORT_46=22 REMAP_PORT_47=23 +m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=32 REMAP_PORT_49=33 REMAP_PORT_50=34 REMAP_PORT_51=35 +m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=63 REMAP_PORT_53=62 REMAP_PORT_54=61 REMAP_PORT_55=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=63 REMAP_PORT_57=62 REMAP_PORT_58=61 REMAP_PORT_59=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=63 REMAP_PORT_61=62 REMAP_PORT_62=61 REMAP_PORT_63=60 + +m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=63 REMAP_PORT_1=63 REMAP_PORT_2=63 REMAP_PORT_3=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=63 REMAP_PORT_5=63 REMAP_PORT_6=63 REMAP_PORT_7=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=63 REMAP_PORT_9=63 REMAP_PORT_10=63 REMAP_PORT_11=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=63 REMAP_PORT_13=63 REMAP_PORT_14=63 REMAP_PORT_15=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=19 REMAP_PORT_17=18 REMAP_PORT_18=17 REMAP_PORT_19=16 +m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=15 REMAP_PORT_21=14 REMAP_PORT_22=13 REMAP_PORT_23=12 +m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=7 REMAP_PORT_25=6 REMAP_PORT_26=5 REMAP_PORT_27=4 +m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=3 REMAP_PORT_29=2 REMAP_PORT_30=1 REMAP_PORT_31=0 +m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=23 REMAP_PORT_33=22 REMAP_PORT_34=21 REMAP_PORT_35=20 +m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=63 REMAP_PORT_37=63 REMAP_PORT_38=63 REMAP_PORT_39=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=63 REMAP_PORT_41=63 REMAP_PORT_42=63 REMAP_PORT_43=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=63 REMAP_PORT_45=63 REMAP_PORT_46=63 REMAP_PORT_47=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=11 REMAP_PORT_49=10 REMAP_PORT_50=9 REMAP_PORT_51=8 +m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=24 REMAP_PORT_53=25 REMAP_PORT_54=26 REMAP_PORT_55=27 +m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=28 REMAP_PORT_57=29 REMAP_PORT_58=30 REMAP_PORT_59=31 +m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=32 REMAP_PORT_61=33 REMAP_PORT_62=34 REMAP_PORT_63=35 led 0 stop led 0 prog \ - 06 FE 80 D2 19 71 08 E0 60 FE E9 D2 0F 75 10 81 \ - 61 FD 02 3F 60 FF 28 32 0F 87 67 4A 96 FF 06 FF \ - D2 2B 74 16 02 1F 60 FF 28 32 0F 87 67 4A 96 FF \ - 06 FF D2 13 74 28 02 0F 60 FF 28 32 0F 87 67 4A \ - 96 FF 06 FF D2 0B 74 3A 3A 48 32 07 32 08 C7 32 \ - 04 C7 97 71 57 77 69 32 00 32 01 B7 97 71 63 32 \ - 0E 77 6B 26 FD 97 27 77 6B 32 0F 87 57 00 00 00 +02 F9 42 80 02 F7 42 00 02 F8 42 00 02 F4 42 48 \ +02 F3 42 24 06 F5 D2 00 74 1E 02 F5 42 05 67 4B \ +86 F8 06 F3 D6 F8 74 1E 86 F0 3E F4 06 F8 88 4A \ +03 75 3C 4A 04 71 41 67 7D 67 91 57 67 7D 67 91 \ +57 67 91 67 7D 57 67 7D 67 7D 57 06 F8 88 80 4A \ +00 27 97 75 46 90 4A 00 27 4A 01 27 B7 97 71 62 \ +77 2C 06 F5 D6 F0 74 75 02 F5 4A 07 37 4E 07 02 \ +F0 42 00 4E 07 06 F5 0A 07 71 46 77 2C 16 F7 06 \ +F9 17 4D DA 07 74 8E 12 F7 52 00 86 F9 57 86 F7 \ +57 16 F7 06 F9 07 4D DA 07 74 A2 12 F7 52 00 86 \ +F9 57 86 F7 57 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + led 0 start led 1 stop led 1 prog \ - 06 FE 80 D2 19 71 08 E0 60 FE E9 D2 0F 75 10 81 \ - 61 FD 02 20 67 89 02 24 67 89 02 10 67 89 02 28 \ - 67 89 02 2C 67 89 02 0C 67 89 02 2C 67 79 02 28 \ - 67 79 02 24 67 79 02 20 67 79 02 10 67 79 02 0C \ - 67 79 02 0B 60 FF 28 32 0F 87 67 56 96 FF 06 FF \ - D2 FF 74 46 3A 36 32 07 32 08 C7 32 04 C7 97 71 \ - 63 77 75 32 00 32 01 B7 97 71 6F 32 0E 77 77 26 \ - FD 97 27 77 77 32 0F 87 57 12 A0 F8 15 1A 01 75 \ - 85 28 67 56 57 32 0F 87 57 12 A0 F8 15 1A 01 71 \ - A1 28 67 56 80 28 67 56 80 28 67 56 80 28 67 56 \ - 57 32 0F 87 32 0F 87 32 0F 87 32 0F 87 57 00 00 +02 F9 42 80 02 F7 42 00 02 F8 42 00 02 F4 42 36 \ +02 F3 42 24 02 F6 17 4E 01 67 AD 86 F8 67 AD 86 \ +F8 67 AD 86 F8 67 AD 86 F8 06 F8 D2 18 74 19 12 \ +01 02 10 60 F8 67 7E 12 01 02 0C 60 F8 67 7E 12 \ +01 02 04 60 F8 67 7E 12 01 02 00 60 F8 67 7E 12 \ +01 02 08 60 F8 67 7E 12 01 02 14 60 F8 67 7E 02 \ +F6 07 4E 01 02 18 60 F8 67 AD 86 F8 06 F3 D6 F8 \ +74 68 86 F0 3E F4 16 E0 5A 00 71 AD 77 A2 1A 00 \ +75 AD 77 A2 02 F6 4A 01 71 9F 06 F8 88 4A 03 75 \ +95 4A 04 71 9A 67 DF 67 E3 57 67 E3 67 DF 57 67 \ +E3 57 02 F6 4A 01 71 AA 67 DF 67 DF 57 06 F8 88 \ +80 4A 00 27 97 75 A2 90 4A 00 27 4A 01 27 B7 97 \ +71 C4 77 84 06 F5 D6 F0 74 D7 02 F5 4A 07 37 4E \ +07 02 F0 42 00 4E 07 06 F5 0A 07 71 A2 77 84 22 \ +01 77 E5 22 00 16 F7 06 F9 97 4D DA 07 74 F6 12 \ +F7 52 00 86 F9 57 86 F7 57 00 00 00 00 00 00 00 + + led 1 start + +link on +led auto on +set RCError=off + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile index 9e338c01f23e..db535d8d6771 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile @@ -1,4 +1,4 @@ obj-m:= x86-64-accton-as5812-54t-cpld.o x86-64-accton-as5812-54t-fan.o \ - x86-64-accton-as5812-54t-leds.o x86-64-accton-as5812-54t-sfp.o \ + x86-64-accton-as5812-54t-leds.o \ x86-64-accton-as5812-54t-psu.o ym2651y.o cpr_4011_4mxx.o diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c index 011f62e76c06..39e553d2f544 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c @@ -29,13 +29,8 @@ #include #include -extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); -extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); - -extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); -extern void led_classdev_resume(struct led_classdev *led_cdev); -extern void led_classdev_suspend(struct led_classdev *led_cdev); +extern int as5812_54t_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5812_54t_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); #define DRVNAME "as5812_54t_led" @@ -223,12 +218,12 @@ static u8 led_light_mode_to_reg_val(enum led_type type, static int accton_as5812_54t_led_read_value(u8 reg) { - return accton_i2c_cpld_read(0x60, reg); + return as5812_54t_cpld_read(0x60, reg); } static int accton_as5812_54t_led_write_value(u8 reg, u8 value) { - return accton_i2c_cpld_write(0x60, reg, value); + return as5812_54t_cpld_write(0x60, reg, value); } static void accton_as5812_54t_led_update(void) @@ -555,11 +550,6 @@ static int __init accton_as5812_54t_led_init(void) { int ret; - extern int platform_accton_as5812_54t(void); - if (!platform_accton_as5812_54t()) { - return -ENODEV; - } - ret = platform_driver_register(&accton_as5812_54t_led_driver); if (ret < 0) { goto exit; diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py index 7a2bec3a0199..cad526e17af5 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py @@ -159,7 +159,6 @@ def driver_check(): 'modprobe x86-64-accton-as5812-54t-cpld' , 'modprobe cpr_4011_4mxx' , 'modprobe ym2651y' , -'modprobe x86-64-accton-as5812-54t-sfp' , 'modprobe x86-64-accton-as5812-54t-psu' , 'modprobe x86-64-accton-as5812-54t-fan' , 'modprobe x86-64-accton-as5812-54t-leds' ] diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/rules b/platform/broadcom/sonic-platform-modules-accton/debian/rules index f1d730b577fa..722d4126ad0e 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/rules +++ b/platform/broadcom/sonic-platform-modules-accton/debian/rules @@ -21,7 +21,7 @@ KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) MODULE_DIRS := as7712-32x as5712-54x as7816-64x as7716-32x as7716-32xb as7312-54x MODULE_DIRS += as7326-56x as6712-32x as7726-32x as4630-54pe minipack as5812-54x -MODULE_DIRS += as5835-54x as9716-32d as5835-54t as7312-54xs as7315-27xb as5812-54x +MODULE_DIRS += as5835-54x as9716-32d as5835-54t as7312-54xs as7315-27xb as5812-54t MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service From ac2908ef035f2dfc278a61d7bb4c631b92c1aa67 Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Fri, 8 Nov 2019 13:53:21 +0800 Subject: [PATCH 0140/1427] [devices]: Add thermal plan to as4630_54pe (#3665) --- .../as4630-54pe/classes/fanutil.py | 257 ++++----------- .../as4630-54pe/classes/thermalutil.py | 105 +++---- .../utils/accton_as4630_54pe_monitor.py | 294 +++++++----------- .../debian/control | 1 - 4 files changed, 206 insertions(+), 451 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py index b6752783dc03..df2e511adef7 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py @@ -1,223 +1,90 @@ #!/usr/bin/env python +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - # ------------------------------------------------------------------ # HISTORY: # mm/dd/yyyy (A.D.) -# 11/13/2017: Polly Hsu, Create -# 1/10/2018: Jostar modify for as7716_32 -# 12/03/2018: Jostar modify for as7726_32 +# 10/24/2019:Jostar craete for as4630_54pe # ------------------------------------------------------------------ try: + import os import time import logging + import glob + import commands from collections import namedtuple except ImportError as e: raise ImportError('%s - required module not found' % str(e)) - -class FanUtil(object): - """Platform-specific FanUtil class""" - - FAN_NUM_ON_MAIN_BROAD = 6 - FAN_NUM_1_IDX = 1 - FAN_NUM_2_IDX = 2 - FAN_NUM_3_IDX = 3 - FAN_NUM_4_IDX = 4 - FAN_NUM_5_IDX = 5 - FAN_NUM_6_IDX = 6 - - FAN_NODE_NUM_OF_MAP = 2 - FAN_NODE_FAULT_IDX_OF_MAP = 1 - FAN_NODE_DIR_IDX_OF_MAP = 2 +class ThermalUtil(object): + """Platform-specific ThermalUtil class""" + THERMAL_NUM_MAX = 4 + THERMAL_NUM_1_IDX = 1 + THERMAL_NUM_2_IDX = 2 + THERMAL_NUM_3_IDX = 3 + THERMAL_NUM_4_IDX = 4 - BASE_VAL_PATH = '/sys/bus/i2c/devices/54-0066/{0}' - FAN_DUTY_PATH = '/sys/bus/i2c/devices/54-0066/fan_duty_cycle_percentage' - - #logfile = '' - #loglevel = logging.INFO - """ Dictionary where - key1 = fan id index (integer) starting from 1 - key2 = fan node index (interger) starting from 1 + key1 = thermal id index (integer) starting from 1 value = path to fan device file (string) """ - _fan_to_device_path_mapping = {} - -#fan1_direction -#fan1_fault -#fan1_present - - #(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', - _fan_to_device_node_mapping = { - (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', - (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', - - (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault', - (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction', - - (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault', - (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction', - - (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault', - (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction', - - (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault', - (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction', + + thermal_sysfspath ={ + THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/24-004b/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/25-004a/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_4_IDX: ["/sys/class/hwmon/hwmon1/temp1_input"], + } - (FAN_NUM_6_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan6_fault', - (FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction', - } - - def _get_fan_to_device_node(self, fan_num, node_num): - return self._fan_to_device_node_mapping[(fan_num, node_num)] - - def _get_fan_node_val(self, fan_num, node_num): - if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: - logging.debug('GET. Parameter error. fan_num:%d', fan_num) - return None - - if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: - logging.debug('GET. Parameter error. node_num:%d', node_num) + def _get_thermal_val(self, thermal_num): + if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_MAX: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) return None - - device_path = self.get_fan_to_device_path(fan_num, node_num) - try: - val_file = open(device_path, 'r') - except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) - return None - - content = val_file.readline().rstrip() - - if content == '': - logging.debug('GET. content is NULL. device_path:%s', device_path) - return None - - try: - val_file.close() - except: - logging.debug('GET. unable to close file. device_path:%s', device_path) - return None - - return int(content) - - def _set_fan_node_val(self, fan_num, node_num, val): - if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: - logging.debug('GET. Parameter error. fan_num:%d', fan_num) - return None - - if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: - logging.debug('GET. Parameter error. node_num:%d', node_num) - return None - - content = str(val) - if content == '': - logging.debug('GET. content is NULL. device_path:%s', device_path) - return None - - device_path = self.get_fan_to_device_path(fan_num, node_num) - try: - val_file = open(device_path, 'w') - except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) - return None - - val_file.write(content) - - try: - val_file.close() - except: - logging.debug('GET. unable to close file. device_path:%s', device_path) - return None - - return True - - def __init__(self): - fan_path = self.BASE_VAL_PATH - - for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): - for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): - self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( - self._fan_to_device_node_mapping[(fan_num, node_num)]) - - def get_num_fans(self): - return self.FAN_NUM_ON_MAIN_BROAD - - def get_idx_fan_start(self): - return self.FAN_NUM_1_IDX - - def get_num_nodes(self): - return self.FAN_NODE_NUM_OF_MAP - - def get_idx_node_start(self): - return self.FAN_NODE_FAULT_IDX_OF_MAP + device_path = self.get_thermal_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + content = val_file.readline().rstrip() + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + return 0 - def get_size_node_map(self): - return len(self._fan_to_device_node_mapping) + def get_num_thermals(self): + return self.THERMAL_NUM_MAX def get_size_path_map(self): - return len(self._fan_to_device_path_mapping) - - def get_fan_to_device_path(self, fan_num, node_num): - return self._fan_to_device_path_mapping[(fan_num, node_num)] - - def get_fan_fault(self, fan_num): - return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) - - - def get_fan_dir(self, fan_num): - return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) - - def get_fan_duty_cycle(self): - #duty_path = self.FAN_DUTY_PATH - try: - val_file = open(self.FAN_DUTY_PATH) - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return False - - content = val_file.readline().rstrip() - val_file.close() - return int(content) + return len(self.thermal_sysfspath) - def set_fan_duty_cycle(self, val): - try: - fan_file = open(self.FAN_DUTY_PATH, 'r+') - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return False - #val = ((val + 1 ) * 625 +75 ) / 100 - fan_file.write(str(val)) - fan_file.close() - return True - - def get_fanr_speed(self, fan_num): - return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) - - def get_fan_status(self, fan_num): - if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: - logging.debug('GET. Parameter error. fan_num, %d', fan_num) - return None - - if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0: - logging.debug('GET. FAN fault. fan_num, %d', fan_num) - return False - - return True + def get_thermal_path(self, thermal_num): + return self.thermal_sysfspath[thermal_num][0] +def main(): + thermal = ThermalUtil() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py index 3af7b3d7df5f..bd5530fd9035 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py @@ -1,26 +1,22 @@ #!/usr/bin/env python +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - # ------------------------------------------------------------------ # HISTORY: # mm/dd/yyyy (A.D.) -# 11/13/2017: Polly Hsu, Create -# 1/10/2018:Jostar modify for as7716_32x -# 12/03/2018:Jostar modify for as7726_32x thermal plan +# 10/24/2019:Jostar craete for as4630_54pe # ------------------------------------------------------------------ try: @@ -35,91 +31,60 @@ class ThermalUtil(object): """Platform-specific ThermalUtil class""" - THERMAL_NUM_MAX = 5 - THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD. LM75 - THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD. LM75 - THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD. LM75 - THERMAL_NUM_4_IDX = 4 # 4_ON_MAIN_BROAD. LM75 - THERMAL_NUM_5_IDX = 5 # 5_ON_MAIN_BROAD. LM75 + THERMAL_NUM_MAX = 4 + THERMAL_NUM_1_IDX = 1 + THERMAL_NUM_2_IDX = 2 + THERMAL_NUM_3_IDX = 3 + THERMAL_NUM_4_IDX = 4 """ Dictionary where key1 = thermal id index (integer) starting from 1 value = path to fan device file (string) """ - - _thermal_to_device_node_mapping = { - THERMAL_NUM_1_IDX: ['55', '48'], - THERMAL_NUM_2_IDX: ['55', '49'], - THERMAL_NUM_3_IDX: ['55', '4a'], - THERMAL_NUM_4_IDX: ['55', '4b'], - THERMAL_NUM_5_IDX: ['54', '4c'], - } + thermal_sysfspath ={ - THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/55-0048/hwmon/hwmon4/temp1_input"], - THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/55-0049/hwmon/hwmon5/temp1_input"], - THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/55-004a/hwmon/hwmon6/temp1_input"], - THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/55-004b/hwmon/hwmon7/temp1_input"], - THERMAL_NUM_5_IDX: ["/sys/bus/i2c/devices/54-004c/hwmon/hwmon3/temp1_input"], + THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/24-004b/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/25-004a/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_4_IDX: ["/sys/class/hwmon/hwmon1/temp1_input"], } - - #def __init__(self): + def _get_thermal_val(self, thermal_num): if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_MAX: logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) return None - device_path = self.get_thermal_to_device_path(thermal_num) - if(os.path.isfile(device_path)): - for filename in glob.glob(device_path): - try: - val_file = open(filename, 'r') - except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) - return None + device_path = self.get_thermal_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None content = val_file.readline().rstrip() if content == '': logging.debug('GET. content is NULL. device_path:%s', device_path) return None try: - val_file.close() + val_file.close() except: logging.debug('GET. unable to close file. device_path:%s', device_path) return None + return int(content) - else: - print "No such device_path=%s"%device_path - return 0 + return 0 def get_num_thermals(self): return self.THERMAL_NUM_MAX - def get_idx_thermal_start(self): - return self.THERMAL_NUM_1_IDX - - def get_size_node_map(self): - return len(self._thermal_to_device_node_mapping) - def get_size_path_map(self): return len(self.thermal_sysfspath) - def get_thermal_to_device_path(self, thermal_num): + def get_thermal_path(self, thermal_num): return self.thermal_sysfspath[thermal_num][0] - def get_thermal_1_val(self): - return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) - - def get_thermal_2_val(self): - return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) - def get_thermal_temp(self): - return (self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_node_val(self.THERMAL_NUM_3_IDX)) - def main(): thermal = ThermalUtil() - print "termal1=%d" %thermal._get_thermal_val(1) - print "termal2=%d" %thermal._get_thermal_val(2) - print "termal3=%d" %thermal._get_thermal_val(3) - print "termal4=%d" %thermal._get_thermal_val(4) - print "termal5=%d" %thermal._get_thermal_val(5) - + if __name__ == '__main__': - main() + main() \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py index eca1eac6b216..6dbf5c2cc720 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py @@ -1,25 +1,22 @@ #!/usr/bin/env python +# -*- coding: utf-8 -* +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# ------------------------------------------------------------------ +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# # HISTORY: # mm/dd/yyyy (A.D.)# -# 4/20/2018: Jostar modify for as7726_32x -# 12/03/2018:Jostar modify for as7726_32x thermal plan +# 10/24/2019:Jostar create for as4630_54pe thermal plan # ------------------------------------------------------------------ try: @@ -32,11 +29,12 @@ import logging.config import logging.handlers import types - import time # this is only being used as part of the example - import traceback + import time + import traceback + import commands from tabulate import tabulate - from as7726_32x.fanutil import FanUtil - from as7726_32x.thermalutil import ThermalUtil + from as4630_54pe.fanutil import FanUtil + from as4630_54pe.thermalutil import ThermalUtil except ImportError as e: raise ImportError('%s - required module not found' % str(e)) @@ -48,25 +46,20 @@ global log_level -# Air Flow Front to Back : -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=38C : Keep 37.5%(0x04) Fan speed -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 38C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 46C : Change Fan speed from 62.5%(0x08) to 100%(0x0E) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 58C : Send alarm message -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 66C : Shut down system -# One Fan fail : Change Fan speed to 100%(0x0E) -# Air Flow Back to Front : -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=34C : Keep 37.5%(0x04) Fan speed -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 34C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 44C : Change Fan speed from 62.5%(0x08) to 100%(0x0E) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 59C : Send alarm message -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 67C : Shut down system -# One Fan fail: Change Fan speed to 100%(0x0E) -# sensor_LM75_CPU == sensor_LM75_4B - - + +# Temperature Policy +# If any fan fail , please set fan speed register to 16 +# The max value of fan speed register is 14 +# LM77(48)+LM75(4B)+LM75(4A) > 140, Set 10 +# LM77(48)+LM75(4B)+LM75(4A) > 150, Set 12 +# LM77(48)+LM75(4B)+LM75(4A) > 160, Set 14 +# LM77(48)+LM75(4B)+LM75(4A) < 140, Set 8 +# LM77(48)+LM75(4B)+LM75(4A) < 150, Set 10 +# LM77(48)+LM75(4B)+LM75(4A) < 160, Set 12 +# Reset DUT:LM77(48)>=70C +# class switch(object): def __init__(self, value): self.value = value @@ -87,13 +80,13 @@ def match(self, *args): else: return False - -fan_policy_state=1 +fan_policy_state=0 fan_fail=0 alarm_state = 0 #0->default or clear, 1-->alarm detect test_temp = 0 -test_temp_list = [0, 0, 0, 0, 0, 0] +test_temp_list = [0, 0, 0] temp_test_data=0 +test_temp_revert=0 # Make a class we can use to capture stdout and sterr in the log class device_monitor(object): # static temp var @@ -124,119 +117,71 @@ def __init__(self, log_file, log_level): sys_handler = handler = logging.handlers.SysLogHandler(address = '/dev/log') sys_handler.setLevel(logging.WARNING) logging.getLogger('').addHandler(sys_handler) - - #logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) def get_state_from_fan_policy(self, temp, policy): state=0 - - logging.debug('temp=%d', temp) for i in range(0, len(policy)): - #logging.debug('policy[%d][0]=%d, policy[%d][1]=%d, policy[%d][2]=%d', i,policy[i][0],i, policy[i][1], i, policy[i][2]) - if temp > policy[i][2]: - if temp <= policy[i][3]: + if (temp > policy[i][2]): #temp_down + if temp <= policy[i][3]: #temp_up state =i - logging.debug ('temp=%d >= policy[%d][2]=%d, temp=%d < policy[%d][3]=%d' , temp, i, policy[i][2], temp, i, policy[i][3]) - logging.debug ('fan_state=%d', state) - break - + return state - def manage_fans(self): - global fan_policy_state global fan_fail global test_temp global test_temp_list global alarm_state - global temp_test_data - - LEVEL_FAN_DEF=0 - LEVEL_FAN_MID=1 - LEVEL_FAN_MAX=2 - LEVEL_TEMP_HIGH=3 - LEVEL_TEMP_CRITICAL=4 - - - fan_policy_f2b = { - LEVEL_FAN_DEF: [38, 0x4, 0, 38000], - LEVEL_FAN_MID: [63, 0x6, 38000, 46000], - LEVEL_FAN_MAX: [100, 0xE, 46000, 58000], - LEVEL_TEMP_HIGH: [100, 0xE, 58000, 66000], - LEVEL_TEMP_CRITICAL: [100, 0xE, 58000, 200000], - } - fan_policy_b2f = { - LEVEL_FAN_DEF: [38, 0x4, 0, 34000], - LEVEL_FAN_MID: [63, 0x8, 34000, 44000], - LEVEL_FAN_MAX: [100, 0xE, 44000, 59000], - LEVEL_TEMP_HIGH: [100, 0xE, 59000, 67000], - LEVEL_TEMP_CRITICAL: [100, 0xE, 59000, 200000], + global temp_test_data + global test_temp_revert + LEVEL_FAN_MIN=0 + LEVEL_FAN_NORMAL=1 + LEVEL_FAN_MID=2 + LEVEL_FAN_HIGH=3 + LEVEL_TEMP_CRITICAL=4 + fan_policy = { + LEVEL_FAN_MIN: [50, 8, 0, 140000], + LEVEL_FAN_NORMAL: [62, 10, 140000, 150000], + LEVEL_FAN_MID: [75, 12, 150000, 160000], + LEVEL_FAN_HIGH: [88, 14, 160000, 240000], + LEVEL_TEMP_CRITICAL: [100, 16, 240000, 300000], } - - fan_policy = fan_policy_f2b - + temp = [0, 0 , 0] + temp_fail=0 thermal = ThermalUtil() fan = FanUtil() - fan_dir=fan.get_fan_dir(1) - if fan_dir == 1: - fan_dri=1 #something wrong, set fan_dir to default val - else: - fan_policy = fan_policy_b2f + ori_duty_cycle=fan.get_fan_duty_cycle() + new_duty_cycle=0 - ori_pwm=fan.get_fan_duty_cycle() - new_pwm=0 - logging.debug('fan_dir=%d, ori_pwm=%d', fan_dir, ori_pwm) - logging.debug('test_temp=%d', test_temp) - if test_temp==0: - temp1 = thermal._get_thermal_val(1) - temp2 = thermal._get_thermal_val(2) - temp3 = thermal._get_thermal_val(3) - temp4 = thermal._get_thermal_val(4) - temp5 = thermal._get_thermal_val(5) + if test_temp==0: + for i in range(0,3): + temp[i]=thermal._get_thermal_val(i+1) + if temp[i]==0 or temp[i]==None: + temp_fail=1 + logging.warning("Get temp-%d fail", i); + return False else: - temp1 = test_temp_list[0] - temp2 = test_temp_list[1] - temp3 = test_temp_list[2] - temp4 = test_temp_list[3] - temp5 = test_temp_list[4] + if test_temp_revert==0: + temp_test_data=temp_test_data+2000 + else: + temp_test_data=temp_test_data-2000 + + for i in range(0,3): + temp[i]=test_temp_list[i]+temp_test_data fan_fail=0 - - if temp3==0: - temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75% - logging.debug('lm75_49 detect fail, so set temp_get=50000, let fan to 75%') - elif temp4==0: - temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75% - logging.debug('lm75_4b detect fail, so set temp_get=50000, let fan to 75%') - else: - temp_get= (temp3 + temp4)/2 # Use (sensor_LM75_4a + sensor_LM75_4b) /2 - ori_state=fan_policy_state - - #temp_test_data=temp_test_data+1000 - #temp_get = temp_get + temp_test_data - #print "Unit test:temp_get=%d"%temp_get - - fan_policy_state=self.get_state_from_fan_policy(temp_get, fan_policy) - #print "temp3=%d"%temp3 - #print "temp4=%d"%temp4 - #print "temp_get=%d"%temp_get - - logging.debug('lm75_48=%d, lm75_49=%d, lm75_4a=%d, lm_4b=%d, lm_4b=%d', temp1,temp2,temp3,temp4,temp5) - logging.debug('ori_state=%d, fan_policy_state=%d', ori_state, fan_policy_state) - new_pwm = fan_policy[fan_policy_state][0] - if fan_fail==0: - logging.debug('new_fan_cycle=%d', new_pwm) - - if fan_fail==0: - if new_pwm!=ori_pwm: - fan.set_fan_duty_cycle(new_pwm) - logging.info('Set fan speed from %d to %d', ori_pwm, new_pwm) + + temp_val=0 + for i in range(0,3): + if temp[i]==None: + break + temp_val+=temp[i] #Check Fan status for i in range (fan.FAN_NUM_1_IDX, fan.FAN_NUM_ON_MAIN_BROAD+1): if fan.get_fan_status(i)==0: new_pwm=100 - logging.debug('fan_%d fail, set pwm to 100',i) + logging.warning('Fan_%d fail, set pwm to 100',i) if test_temp==0: fan_fail=1 fan.set_fan_duty_cycle(new_pwm) @@ -244,59 +189,38 @@ def manage_fans(self): else: fan_fail=0 - #if fan_policy_state == ori_state: - # return True - #else: - new_state = fan_policy_state + ori_state=fan_policy_state + fan_policy_state=self.get_state_from_fan_policy(temp_val, fan_policy) - #logging.warning('Temperature high alarm testing') - if ori_state==LEVEL_FAN_DEF: - if new_state==LEVEL_TEMP_HIGH: + if fan_policy_state > LEVEL_TEMP_CRITICAL or fan_policy_state < LEVEL_FAN_MIN: + logging.error("Get error fan current_state\n"); + return 0 + + #Decision : Decide new fan pwm percent. + if fan_fail==0 and ori_duty_cycle!=fan_policy[fan_policy_state][0]: + new_duty_cycle = fan_policy[fan_policy_state][0]; + fan.set_fan_duty_cycle(new_duty_cycle) + + if temp[0] >= 70000: #LM75-48 + #critical case*/ + logging.critical('Alarm-Critical for temperature critical is detected, reset DUT') + cmd_str="i2cset -y -f 3 0x60 0x4 0xE4" + time.sleep(2); + status, output = commands.getstatusoutput(cmd_str) + + #logging.debug('ori_state=%d, current_state=%d, temp_val=%d\n\n',ori_state, fan_policy_state, temp_val) + + if ori_state < LEVEL_FAN_HIGH: + if fan_policy_state >= LEVEL_FAN_HIGH: if alarm_state==0: logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected, reboot DUT') - time.sleep(2) - os.system('reboot') - if ori_state==LEVEL_FAN_MID: - if new_state==LEVEL_TEMP_HIGH: - if alarm_state==0: - logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') - if ori_state==LEVEL_FAN_MAX: - if new_state==LEVEL_TEMP_HIGH: - if alarm_state==0: - logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') + alarm_state=1 + + if fan_policy_state < LEVEL_FAN_MID: if alarm_state==1: - if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm - logging.warning('Alarm for temperature high is cleared') - alarm_state=0 - if ori_state==LEVEL_TEMP_HIGH: - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') - if new_state <= LEVEL_FAN_MID: - logging.warning('Alarm for temperature high is cleared') + logging.info('Alarm for temperature high is cleared') alarm_state=0 - if new_state <= LEVEL_FAN_MAX: - if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm - logging.warning('Alarm for temperature high is cleared') - alarm_state=0 - if ori_state==LEVEL_TEMP_CRITICAL: - if new_state <= LEVEL_FAN_MAX: - logging.warning('Alarm for temperature critical is cleared') - + return True def main(argv): @@ -319,12 +243,12 @@ def main(argv): log_file = arg if sys.argv[1]== '-t': - if len(sys.argv)!=7: - print "temp test, need input six temp" + if len(sys.argv)!=5: + print "temp test, need input three temp" return 0 i=0 - for x in range(2, 7): + for x in range(2, 5): test_temp_list[i]= int(sys.argv[x])*1000 i=i+1 test_temp = 1 @@ -332,14 +256,14 @@ def main(argv): print test_temp_list fan = FanUtil() - fan.set_fan_duty_cycle(38) - print "set default fan speed to 37.5%" + fan.set_fan_duty_cycle(50) + print "set default fan speed to 50%" monitor = device_monitor(log_file, log_level) # Loop forever, doing something useful hopefully: while True: - #monitor.manage_fans() - time.sleep(5) + monitor.manage_fans() + time.sleep(10) #10sec if __name__ == '__main__': main(sys.argv[1:]) - + diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/control b/platform/broadcom/sonic-platform-modules-accton/debian/control index 2b3c1af3d80f..0d333691c017 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/control +++ b/platform/broadcom/sonic-platform-modules-accton/debian/control @@ -68,7 +68,6 @@ Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as5835-54t Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp - Package: sonic-platform-accton-as7312-54xs Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp From 2e61e14bb3f39f5d2e58137f697c7a8d55593a16 Mon Sep 17 00:00:00 2001 From: Pradchaya Phucharoen Date: Fri, 8 Nov 2019 13:02:53 +0700 Subject: [PATCH 0141/1427] [devices] Celeatica Silverstone add IPMI platform sensor read. (#3591) * [platform/broadcom] Celeatica Silverstone add IPMI platform sensor read. * [platform_sensors] Silverstone update temperature sensor description --- .../platform-modules-silverstone.install | 2 + .../silverstone/scripts/platform_sensors.py | 173 ++++++++++++++++++ .../silverstone/scripts/sensors | 11 ++ 3 files changed, 186 insertions(+) create mode 100755 platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/platform_sensors.py create mode 100755 platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/sensors diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install index 03e13544b8b1..67b433ced85f 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install @@ -1,3 +1,5 @@ +silverstone/scripts/sensors usr/bin +silverstone/scripts/platform_sensors.py usr/local/bin silverstone/cfg/silverstone-modules.conf etc/modules-load.d silverstone/systemd/platform-modules-silverstone.service lib/systemd/system silverstone/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_silverstone-r0 diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/platform_sensors.py new file mode 100755 index 000000000000..186ee6c5450e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/platform_sensors.py @@ -0,0 +1,173 @@ +#!/usr/bin/python +# +# Silverstone platform sensors. This script get the sensor data from BMC +# using ipmitool and display them in lm-sensor alike format. +# +# The following data is support: +# 1. Temperature sensors +# 2. PSUs +# 3. Fan trays + +import sys +import logging +import subprocess + +IPMI_SDR_CMD = "ipmitool sdr elist" +MAX_NUM_FANS = 7 +MAX_NUM_PSUS = 2 + + +def ipmi_sensor_dump(cmd): + ''' Execute ipmitool command return dump output + exit if any error occur. + ''' + sensor_dump = '' + try: + sensor_dump = subprocess.check_output(cmd, shell=True) + except subprocess.CalledProcessError as e: + logging.error('Error! Failed to execute: {}'.format(cmd)) + sys.exit(1) + return sensor_dump + +def get_reading_by_name(sensor_name, sdr_elist_dump): + ''' + Search for the match sensor name, return sensor + reading value and unit, return object epmtry string + if search not match. + + The output of sensor dump: + TEMP_FAN_U52 | 00h | ok | 7.1 | 31 degrees C + TEMP_FAN_U17 | 01h | ok | 7.1 | 27 degrees C + TEMP_SW_U52 | 02h | ok | 7.1 | 30 degrees C + Fan2_Status | 07h | ok | 29.2 | Present + Fan2_Front | 0Eh | ok | 29.2 | 12000 RPM + Fan2_Rear | 46h | ok | 29.2 | 14700 RPM + PSU2_Status | 39h | ok | 10.2 | Presence detected + PSU2_Fan | 3Dh | ok | 10.2 | 16000 RPM + PSU2_VIn | 3Ah | ok | 10.2 | 234.30 Volts + PSU2_CIn | 3Bh | ok | 10.2 | 0.80 Amps + ''' + found = '' + + for line in sdr_elist_dump.split("\n"): + if sensor_name in line: + found = line.strip() + break + + if not found: + logging.error('Cannot find sensor name:' + sensor_name) + + else: + try: + found = found.split('|')[4] + except IndexError: + logging.error('Cannot get sensor data of:' + sensor_name) + + logging.basicConfig(level=logging.DEBUG) + return found + + +def read_temperature_sensors(ipmi_sdr_elist): + + sensor_list = [ + ('TEMP_FAN_U52', 'Fan Tray Middle Temp'), + ('TEMP_FAN_U17', 'Fan Tray Right Temp'), + ('TEMP_SW_U52', 'Switchboard Left Inlet Temp'), + ('TEMP_SW_U16', 'Switchboard Right Inlet Temp'), + ('TEMP_BB_U3', 'Baseboard Temp'), + ('TEMP_CPU', 'CPU Internal Temp'), + ('TEMP_SW_Internal', 'ASIC Internal Temp'), + ('SW_U04_Temp', 'IR3595 Chip Left Temp'), + ('SW_U14_Temp', 'IR3595 Chip Right Temp'), + ('SW_U4403_Temp', 'IR3584 Chip Temp'), + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "Temperature Sensors\n" + output += "Adapter: IPMI adapter\n" + for sensor in sensor_list: + reading = get_reading_by_name(sensor[0],ipmi_sdr_elist) + output += sensor_format.format('{}:'.format(sensor[1]), + reading, + width=str(max_name_width+1)) + output += '\n' + return output + + +def read_fan_sensors(num_fans, ipmi_sdr_elist): + + sensor_list = [ + ('Fan{}_Status', 'Status'), + ('Fan{}_Front', 'Fan {} front'), + ('Fan{}_Rear', 'Fan {} rear'), + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "Fan Trays\n" + output += "Adapter: IPMI adapter\n" + for fan_num in range(1, num_fans+1): + for sensor in sensor_list: + ipmi_sensor_name = sensor[0].format(fan_num) + display_sensor_name = sensor[1].format(fan_num) + reading = get_reading_by_name(ipmi_sensor_name, ipmi_sdr_elist) + output += sensor_format.format('{}:'.format(display_sensor_name), + reading, + width=str(max_name_width+1)) + output += '\n' + return output + + +def read_psu_sensors(num_psus, ipmi_sdr_elist): + + sensor_list = [ + ('PSU{}_Status', 'PSU {} Status'), + ('PSU{}_Fan', 'PSU {} Fan'), + ('PSU{}_VIn', 'PSU {} Input Voltag'), + ('PSU{}_CIn', 'PSU {} Input Current'), + ('PSU{}_PIn', 'PSU {} Input Power'), + ('PSU{}_Temp1', 'PSU {} Temp1'), + ('PSU{}_Temp2', 'PSU {} Temp2'), + ('PSU{}_VOut', 'PSU {} Output Voltag'), + ('PSU{}_COut', 'PSU {} Output Current'), + ('PSU{}_POut', 'PSU {} Output Power'), + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "PSU\n" + output += "Adapter: IPMI adapter\n" + for psu_num in range(1, num_psus+1): + for sensor in sensor_list: + ipmi_sensor_name = sensor[0].format(psu_num) + display_sensor_name = sensor[1].format(psu_num) + reading = get_reading_by_name(ipmi_sensor_name, ipmi_sdr_elist) + output += sensor_format.format('{}:'.format(display_sensor_name), + reading, + width=str(max_name_width+1)) + output += '\n' + return output + + +def main(): + output_string = '' + + ipmi_sdr_elist = ipmi_sensor_dump(IPMI_SDR_CMD) + output_string += read_temperature_sensors(ipmi_sdr_elist) + output_string += read_psu_sensors(MAX_NUM_PSUS, ipmi_sdr_elist) + output_string += read_fan_sensors(MAX_NUM_FANS, ipmi_sdr_elist) + print(output_string) + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/sensors b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/sensors new file mode 100755 index 000000000000..405d92c2b3cc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/sensors @@ -0,0 +1,11 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS pmon sensors "$@" +docker exec -$DOCKER_EXEC_FLAGS pmon platform_sensors.py "$@" From e877e471c0ff4145ead779ab0be85ca10b9f3242 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 9 Nov 2019 05:03:07 +0000 Subject: [PATCH 0142/1427] [devices]: fix debian/control for accton platform modules the bug was introduced by commit ac2908ef035f2dfc278a61d7bb4c631b92c1aa67 Signed-off-by: Guohan Lu --- platform/broadcom/sonic-platform-modules-accton/debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/control b/platform/broadcom/sonic-platform-modules-accton/debian/control index 0d333691c017..2b3c1af3d80f 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/control +++ b/platform/broadcom/sonic-platform-modules-accton/debian/control @@ -68,6 +68,7 @@ Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as5835-54t Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp + Package: sonic-platform-accton-as7312-54xs Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp From bec60d1506020d4b943ac629beb81e91bbf6efbf Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Sat, 9 Nov 2019 07:43:18 +0200 Subject: [PATCH 0143/1427] [pmon][barefoot] Added pmon daemons control file (#3728) Signed-off-by: Andriy Kokhan --- .../pmon_daemon_control.json | 6 ++++++ .../pmon_daemon_control.json | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json create mode 100644 device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..3a76f2fdd0e4 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json @@ -0,0 +1,6 @@ +{ + "skip_ledd": true, + "skip_xcvrd": false, + "skip_psud": false, + "skip_syseepromd": false +} diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..3a76f2fdd0e4 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json @@ -0,0 +1,6 @@ +{ + "skip_ledd": true, + "skip_xcvrd": false, + "skip_psud": false, + "skip_syseepromd": false +} From 96fffd883d2ecb489fd360e3ff78cd7832b01cab Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 8 Nov 2019 21:44:25 -0800 Subject: [PATCH 0144/1427] Revert "[services] make snmp.timer work again and delay telemetry.service (#3657)" (#3729) This reverts commit d346cb3898d58aeb16c22a66a79b117ab267d4b8. --- files/build_templates/snmp.service.j2 | 2 ++ files/build_templates/sonic_debian_extension.j2 | 6 ++---- files/build_templates/telemetry.service.j2 | 2 ++ files/build_templates/telemetry.timer | 9 --------- 4 files changed, 6 insertions(+), 13 deletions(-) delete mode 100644 files/build_templates/telemetry.timer diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index 9d419b8e0dfd..310048e68beb 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -14,3 +14,5 @@ ExecStop=/usr/bin/{{docker_container_name}}.sh stop Restart=always RestartSec=30 +[Install] +WantedBy=multi-user.target swss.service diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index bd1dfccd28dc..f5a734b3a273 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -317,7 +317,7 @@ EOF ## Bind docker path if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then sudo mkdir -p $FILESYSTEM_ROOT/dockerfs - sudo mount --bind dockerfs $FILESYSTEM_ROOT/dockerfs + sudo mount --bind dockerfs $FILESYSTEM_ROOT/dockerfs fi {% if installer_images.strip() -%} @@ -334,7 +334,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta {% endif %} {% endfor %} if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then - sudo umount $FILESYSTEM_ROOT/dockerfs + sudo umount $FILESYSTEM_ROOT/dockerfs sudo rm -fr $FILESYSTEM_ROOT/dockerfs sudo kill -9 `sudo $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS_PID` || true else @@ -362,8 +362,6 @@ sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer -sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT/etc/systemd/system/ -sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable telemetry.timer sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-dev sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get clean -y diff --git a/files/build_templates/telemetry.service.j2 b/files/build_templates/telemetry.service.j2 index 4d653e42327d..2e7e45218df2 100644 --- a/files/build_templates/telemetry.service.j2 +++ b/files/build_templates/telemetry.service.j2 @@ -10,3 +10,5 @@ ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/telemetry.timer b/files/build_templates/telemetry.timer deleted file mode 100644 index e08f1c09eac6..000000000000 --- a/files/build_templates/telemetry.timer +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Delays telemetry container until SONiC has started - -[Timer] -OnBootSec=3min 30 sec -Unit=telemetry.service - -[Install] -WantedBy=timers.target From b2e15f2318d2cb26bfc166bcf62e73614720597a Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Sat, 9 Nov 2019 13:49:46 +0800 Subject: [PATCH 0145/1427] [device/accton] Platform2.0 API Implementation for accton as7116-54x (#3622) Implement Component platform2.0 API for accton as7116-54x platform --- .../buffers.json.j2 | 0 .../buffers_defaults_t0.j2 | 142 +-- .../buffers_defaults_t1.j2 | 142 +-- .../Accton-AS7116-54X-R0/led.bin | Bin 0 -> 748 bytes .../Accton-AS7116-54X-R0/nephos_dac.dsh | 414 ++++++ .../nephos_opt.dsh | 187 +-- .../pg_profile_lookup.ini | 0 .../port_config.ini | 0 .../port_config.nps | 1 + .../proc_init.nps | 0 .../qos.json.j2 | 0 .../Accton-AS7116-54X-R0/sai.profile | 2 + .../Accton-AS7116-54X/nephos_dac.dsh | 404 ------ .../Accton-AS7116-54X/sai.profile | 2 - .../x86_64-accton_as7116_54x-r0/default_sku | 2 +- .../x86_64-accton_as7116_54x-r0/fancontrol | 2 +- .../plugins/eeprom.py | 2 +- .../plugins/sfputil.py | 3 +- .../x86_64-accton_as7116_54x-r0/sensors.conf | 2 +- .../sonic_platform/__init__.py | 2 + .../sonic_platform/chassis.py | 174 +++ .../sonic_platform/component.py | 83 ++ .../sonic_platform/eeprom.py | 112 ++ .../sonic_platform/fan.py | 165 +++ .../sonic_platform/platform.py | 20 + .../sonic_platform/psu.py | 102 ++ .../sonic_platform/sfp.py | 1133 +++++++++++++++++ .../as7116-54x/classes/__init__.py | 0 .../as7116-54x/classes/fanutil.py | 0 .../as7116-54x/classes/thermalutil.py | 0 .../service/as7116-platform-init.service | 3 +- .../service/platform_api/platform_api_mgnt.sh | 41 + .../as7116-54x/setup.py | 43 +- .../as7116-54x/utils/accton_as7116_util.py | 309 ++--- .../debian/rules | 74 +- .../sonic-platform-accton-as7116-54x.install | 4 + .../sonic-platform-accton-as7116-54x.postinst | 5 + 37 files changed, 2710 insertions(+), 865 deletions(-) rename device/accton/x86_64-accton_as7116_54x-r0/{Accton-AS7116-54X => Accton-AS7116-54X-R0}/buffers.json.j2 (100%) rename device/accton/x86_64-accton_as7116_54x-r0/{Accton-AS7116-54X => Accton-AS7116-54X-R0}/buffers_defaults_t0.j2 (96%) rename device/accton/x86_64-accton_as7116_54x-r0/{Accton-AS7116-54X => Accton-AS7116-54X-R0}/buffers_defaults_t1.j2 (96%) create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/led.bin create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_dac.dsh rename device/accton/x86_64-accton_as7116_54x-r0/{Accton-AS7116-54X => Accton-AS7116-54X-R0}/nephos_opt.dsh (77%) rename device/accton/x86_64-accton_as7116_54x-r0/{Accton-AS7116-54X => Accton-AS7116-54X-R0}/pg_profile_lookup.ini (100%) rename device/accton/x86_64-accton_as7116_54x-r0/{Accton-AS7116-54X => Accton-AS7116-54X-R0}/port_config.ini (100%) rename device/accton/x86_64-accton_as7116_54x-r0/{Accton-AS7116-54X => Accton-AS7116-54X-R0}/port_config.nps (99%) rename device/accton/x86_64-accton_as7116_54x-r0/{Accton-AS7116-54X => Accton-AS7116-54X-R0}/proc_init.nps (100%) rename device/accton/x86_64-accton_as7116_54x-r0/{Accton-AS7116-54X => Accton-AS7116-54X-R0}/qos.json.j2 (100%) create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/sai.profile delete mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_dac.dsh delete mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/__init__.py create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/component.py create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/eeprom.py create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/fan.py create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/platform.py create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/psu.py create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py delete mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/__init__.py delete mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/fanutil.py delete mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/thermalutil.py create mode 100755 platform/nephos/sonic-platform-modules-accton/as7116-54x/service/platform_api/platform_api_mgnt.sh create mode 100644 platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.install create mode 100644 platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.postinst diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers.json.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers.json.j2 similarity index 100% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers.json.j2 rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers.json.j2 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t0.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t0.j2 similarity index 96% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t0.j2 rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t0.j2 index 300fecdb3555..a47675b8dfa4 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t0.j2 +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t0.j2 @@ -1,72 +1,72 @@ -{% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '20971328' %} -{% set ingress_lossy_pool_size = '20971328' %} -{% set egress_lossless_pool_size = '20971328' %} -{% set egress_lossy_pool_size = '20971328' %} - -{%- macro generate_port_lists(PORT_ALL) %} - {# Generate list of ports #} - {%- for port_idx in range(0, 48) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(48, 54) %} - {%- if PORT_ALL.append("Ethernet%d" % (48 + (port_idx-48) * 4)) %}{%- endif %} - {%- endfor %} -{%- endmacro %} - -{%- macro generate_buffer_pool_and_profiles() %} - "BUFFER_POOL": { - "ingress_lossless_pool": { - "size": "{{ ingress_lossless_pool_size }}", - "type": "ingress", - "mode": "static" - }, - "ingress_lossy_pool": { - "size": "{{ ingress_lossy_pool_size }}", - "type": "ingress", - "mode": "dynamic" - }, - "egress_lossless_pool": { - "size": "{{ egress_lossless_pool_size }}", - "type": "egress", - "mode": "static" - }, - "egress_lossy_pool": { - "size": "{{ egress_lossy_pool_size }}", - "type": "egress", - "mode": "dynamic" - } - }, - "BUFFER_PROFILE": { - "ingress_lossless_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "xon":"78400", - "xoff":"132160", - "size":"3584", - "static_th":"82880" - }, - "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"3584", - "dynamic_th":"-1" - }, - "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"3584", - "dynamic_th":"-4" - } - }, -{%- endmacro %} - -{# the typo of generate_pg_profils dued to buffers_config.j2 #} -{# Default, we do not bind any buffer profiles. #} -{%- macro generate_pg_profils(port_names) %} - "BUFFER_PG": { - } -{%- endmacro %} - -{# Default, we do not bind any buffer profiles. #} -{%- macro generate_queue_buffers(port_names) %} - "BUFFER_QUEUE": { - } +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '20971328' %} +{% set ingress_lossy_pool_size = '20971328' %} +{% set egress_lossless_pool_size = '20971328' %} +{% set egress_lossy_pool_size = '20971328' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 48) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(48, 54) %} + {%- if PORT_ALL.append("Ethernet%d" % (48 + (port_idx-48) * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"3584", + "dynamic_th":"-4" + } + }, +{%- endmacro %} + +{# the typo of generate_pg_profils dued to buffers_config.j2 #} +{# Default, we do not bind any buffer profiles. #} +{%- macro generate_pg_profils(port_names) %} + "BUFFER_PG": { + } +{%- endmacro %} + +{# Default, we do not bind any buffer profiles. #} +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + } {%- endmacro %} \ No newline at end of file diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t1.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t1.j2 similarity index 96% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t1.j2 rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t1.j2 index 300fecdb3555..a47675b8dfa4 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t1.j2 +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t1.j2 @@ -1,72 +1,72 @@ -{% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '20971328' %} -{% set ingress_lossy_pool_size = '20971328' %} -{% set egress_lossless_pool_size = '20971328' %} -{% set egress_lossy_pool_size = '20971328' %} - -{%- macro generate_port_lists(PORT_ALL) %} - {# Generate list of ports #} - {%- for port_idx in range(0, 48) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(48, 54) %} - {%- if PORT_ALL.append("Ethernet%d" % (48 + (port_idx-48) * 4)) %}{%- endif %} - {%- endfor %} -{%- endmacro %} - -{%- macro generate_buffer_pool_and_profiles() %} - "BUFFER_POOL": { - "ingress_lossless_pool": { - "size": "{{ ingress_lossless_pool_size }}", - "type": "ingress", - "mode": "static" - }, - "ingress_lossy_pool": { - "size": "{{ ingress_lossy_pool_size }}", - "type": "ingress", - "mode": "dynamic" - }, - "egress_lossless_pool": { - "size": "{{ egress_lossless_pool_size }}", - "type": "egress", - "mode": "static" - }, - "egress_lossy_pool": { - "size": "{{ egress_lossy_pool_size }}", - "type": "egress", - "mode": "dynamic" - } - }, - "BUFFER_PROFILE": { - "ingress_lossless_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "xon":"78400", - "xoff":"132160", - "size":"3584", - "static_th":"82880" - }, - "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"3584", - "dynamic_th":"-1" - }, - "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"3584", - "dynamic_th":"-4" - } - }, -{%- endmacro %} - -{# the typo of generate_pg_profils dued to buffers_config.j2 #} -{# Default, we do not bind any buffer profiles. #} -{%- macro generate_pg_profils(port_names) %} - "BUFFER_PG": { - } -{%- endmacro %} - -{# Default, we do not bind any buffer profiles. #} -{%- macro generate_queue_buffers(port_names) %} - "BUFFER_QUEUE": { - } +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '20971328' %} +{% set ingress_lossy_pool_size = '20971328' %} +{% set egress_lossless_pool_size = '20971328' %} +{% set egress_lossy_pool_size = '20971328' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 48) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(48, 54) %} + {%- if PORT_ALL.append("Ethernet%d" % (48 + (port_idx-48) * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"3584", + "dynamic_th":"-4" + } + }, +{%- endmacro %} + +{# the typo of generate_pg_profils dued to buffers_config.j2 #} +{# Default, we do not bind any buffer profiles. #} +{%- macro generate_pg_profils(port_names) %} + "BUFFER_PG": { + } +{%- endmacro %} + +{# Default, we do not bind any buffer profiles. #} +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + } {%- endmacro %} \ No newline at end of file diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/led.bin b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/led.bin new file mode 100644 index 0000000000000000000000000000000000000000..bb4426fb59f43f29173af5c0cd272234cb0abe21 GIT binary patch literal 748 zcmZ9}xlRIM6oAp+M2*FO0}L?06POGzfIIHC?mODLG%k%xBNE@-Q+tz}^HsOGVIhPt z8^TI#=R#QKGMBi-MJ{s4A=kOiHLh`$tK8-`x46YkZgPVg+~+>`xW`@Ya)&#daKaz{ zaLh5k`OPnW@spqY;0NFN&NsgCm9Ko^3!nMSCqD6!k9^<*?|IKV-tm^V9C5@O-td~& zyy6uvdC3c2@SNv7;~7tR$`hXOn8!Tg5f6FD10L{q#vlGoG!;TL9YV~Q2@|GFnKNg` zjPt2=Yu?SGF6yE#=z=cjNJl!-6VY2Uf$r7LGYu5;bhUES3k-O(N0)@|L^ Jna*^k{{TSXGe`gc literal 0 HcmV?d00001 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_dac.dsh b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_dac.dsh new file mode 100644 index 000000000000..42102053c3fb --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_dac.dsh @@ -0,0 +1,414 @@ +init start stage unit=0 low-level +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true +init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true +init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true +init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true +init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true +init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true +init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true +init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true +init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true +init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true +init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true +init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true +init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true +init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true +init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true +init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true +init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true +init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true +init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true +init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true +init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true +init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true +init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true +init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true +init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true +init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true +init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true +init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true +init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true +init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true +init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true +init start stage unit=0 task-rsrc +init start stage unit=0 module +init start stage unit=0 task +phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1 +phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3 +phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2 +phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1 +phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0 +phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1 +phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0 +phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set mdio portlist=0 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=1 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=2 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=3 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=4 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=5 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=6 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=7 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=8 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=9 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=10 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=11 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=12 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=13 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=14 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=15 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=16 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=17 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=18 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=19 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=20 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=21 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=22 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=23 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=24 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=25 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=26 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=27 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=28 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=29 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=30 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=31 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=32 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=33 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=34 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=35 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=36 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=37 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=38 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=39 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=40 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=41 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=42 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=43 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=44 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=45 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=46 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=47 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=48 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=49 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=50 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=51 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=52 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=53 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=129 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=130 devad=0x1E addr=0x2 data=0x0000 +port set property unit=0 portlist=0-47 speed=25g +port set property unit=0 portlist=48-53 speed=100g +port set property unit=0 portlist=129-130 speed=10g +port set property unit=0 portlist=0-47 medium-type=cr +port set property unit=0 portlist=48-53 medium-type=cr4 +port set property unit=0 portlist=129-130 medium-type=kr +port set adver unit=0 portlist=129-130 speed-10g-kr +port set property unit=0 portlist=129-130 an=enable +port set property unit=0 portlist=129-130 admin=enable +port set property unit=0 portlist=0-53 admin=disable diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_opt.dsh b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_opt.dsh similarity index 77% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_opt.dsh rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_opt.dsh index 06bda1dc76a4..ca2bc6497685 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_opt.dsh +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_opt.dsh @@ -1,63 +1,63 @@ -init start stage low-level -init set port-map port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map port=19 eth-macro=8 lane=3 max-speed=25g active=true -init set port-map port=20 eth-macro=10 lane=0 max-speed=25g active=true -init set port-map port=21 eth-macro=10 lane=1 max-speed=25g active=true -init set port-map port=22 eth-macro=10 lane=2 max-speed=25g active=true -init set port-map port=23 eth-macro=10 lane=3 max-speed=25g active=true -init set port-map port=24 eth-macro=12 lane=0 max-speed=25g active=true -init set port-map port=25 eth-macro=12 lane=1 max-speed=25g active=true -init set port-map port=26 eth-macro=12 lane=2 max-speed=25g active=true -init set port-map port=27 eth-macro=12 lane=3 max-speed=25g active=true -init set port-map port=28 eth-macro=14 lane=0 max-speed=25g active=true -init set port-map port=29 eth-macro=14 lane=1 max-speed=25g active=true -init set port-map port=30 eth-macro=14 lane=2 max-speed=25g active=true -init set port-map port=31 eth-macro=14 lane=3 max-speed=25g active=true -init set port-map port=32 eth-macro=16 lane=0 max-speed=25g active=true -init set port-map port=33 eth-macro=16 lane=1 max-speed=25g active=true -init set port-map port=34 eth-macro=16 lane=2 max-speed=25g active=true -init set port-map port=35 eth-macro=16 lane=3 max-speed=25g active=true -init set port-map port=36 eth-macro=17 lane=0 max-speed=25g active=true -init set port-map port=37 eth-macro=17 lane=1 max-speed=25g active=true -init set port-map port=38 eth-macro=17 lane=2 max-speed=25g active=true -init set port-map port=39 eth-macro=17 lane=3 max-speed=25g active=true -init set port-map port=40 eth-macro=18 lane=0 max-speed=25g active=true -init set port-map port=41 eth-macro=18 lane=1 max-speed=25g active=true -init set port-map port=42 eth-macro=18 lane=2 max-speed=25g active=true -init set port-map port=43 eth-macro=18 lane=3 max-speed=25g active=true -init set port-map port=44 eth-macro=19 lane=0 max-speed=25g active=true -init set port-map port=45 eth-macro=19 lane=1 max-speed=25g active=true -init set port-map port=46 eth-macro=19 lane=2 max-speed=25g active=true -init set port-map port=47 eth-macro=19 lane=3 max-speed=25g active=true -init set port-map port=48 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map port=49 eth-macro=21 lane=0 max-speed=100g active=true -init set port-map port=50 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map port=51 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map port=52 eth-macro=28 lane=0 max-speed=100g active=true -init set port-map port=53 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true -init set port-map port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true -init start stage task-rsrc -init start stage module -init start stage task +init start stage unit=0 low-level +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true +init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true +init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true +init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true +init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true +init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true +init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true +init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true +init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true +init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true +init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true +init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true +init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true +init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true +init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true +init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true +init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true +init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true +init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true +init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true +init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true +init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true +init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true +init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true +init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true +init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true +init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true +init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true +init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true +init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true +init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true +init start stage unit=0 task-rsrc +init start stage unit=0 module +init start stage unit=0 task phy set lane-swap portlist=0 lane-cnt=1 property=tx data=0x0 phy set lane-swap portlist=1 lane-cnt=1 property=tx data=0x1 phy set lane-swap portlist=2 lane-cnt=1 property=tx data=0x2 @@ -106,7 +106,12 @@ phy set lane-swap portlist=44 lane-cnt=1 property=tx data=0x0 phy set lane-swap portlist=45 lane-cnt=1 property=tx data=0x1 phy set lane-swap portlist=46 lane-cnt=1 property=tx data=0x2 phy set lane-swap portlist=47 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=48-53 lane-cnt=4 property=tx data=0x03.02.01.00 +phy set lane-swap portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2 +phy set lane-swap portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1 +phy set lane-swap portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap portlist=0 lane-cnt=1 property=rx data=0x0 phy set lane-swap portlist=1 lane-cnt=1 property=rx data=0x1 phy set lane-swap portlist=2 lane-cnt=1 property=rx data=0x2 @@ -155,7 +160,12 @@ phy set lane-swap portlist=44 lane-cnt=1 property=rx data=0x1 phy set lane-swap portlist=45 lane-cnt=1 property=rx data=0x2 phy set lane-swap portlist=46 lane-cnt=1 property=rx data=0x3 phy set lane-swap portlist=47 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=48-53 lane-cnt=4 property=rx data=0x03.02.01.00 +phy set lane-swap portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3 +phy set lane-swap portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2 +phy set lane-swap portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2 +phy set lane-swap portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2 +phy set lane-swap portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0 phy set polarity-rev portlist=0 lane-cnt=1 property=tx data=0x0 phy set polarity-rev portlist=1 lane-cnt=1 property=tx data=0x0 phy set polarity-rev portlist=2 lane-cnt=1 property=tx data=0x0 @@ -204,9 +214,9 @@ phy set polarity-rev portlist=44 lane-cnt=1 property=tx data=0x0 phy set polarity-rev portlist=45 lane-cnt=1 property=tx data=0x0 phy set polarity-rev portlist=46 lane-cnt=1 property=tx data=0x0 phy set polarity-rev portlist=47 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1 phy set polarity-rev portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0 phy set polarity-rev portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 @@ -258,83 +268,83 @@ phy set polarity-rev portlist=44 lane-cnt=1 property=rx data=0x0 phy set polarity-rev portlist=45 lane-cnt=1 property=rx data=0x0 phy set polarity-rev portlist=46 lane-cnt=1 property=rx data=0x0 phy set polarity-rev portlist=47 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1 +phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0 +phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0 +phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1 phy set polarity-rev portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 phy set pre-emphasis portlist=0 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=0 lane-cnt=4 property=cn1 data=0x1.1.1.1 -phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x1A.1A.1A.1A +phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a phy set pre-emphasis portlist=0 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set pre-emphasis portlist=4 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=4 lane-cnt=4 property=cn1 data=0x1.1.1.1 -phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x1A.1A.1A.1A +phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a phy set pre-emphasis portlist=4 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set pre-emphasis portlist=8 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=8 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=8 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=12 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=12 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B +phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis portlist=12 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set pre-emphasis portlist=16 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=16 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=16 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=20 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=20 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=20 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=24 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=24 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=24 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=28 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=28 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=28 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=32 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=32 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=32 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=36 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=36 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=36 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=40 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=40 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=40 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=44 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=44 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=44 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=48 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=48 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B +phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis portlist=48 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=49 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=49 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B +phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis portlist=49 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=50 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=50 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B +phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis portlist=50 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set pre-emphasis portlist=51 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=51 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B +phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis portlist=51 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set pre-emphasis portlist=52 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=52 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1A.1A.1A.1A +phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a phy set pre-emphasis portlist=52 lane-cnt=4 property=c1 data=0x8.8.8.8 phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x1.1.1.1 -phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1A.1A.1A.1A +phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set mdio portlist=0 devad=0x1E addr=0x2 data=0x8000 phy set mdio portlist=1 devad=0x1E addr=0x2 data=0x8000 @@ -400,5 +410,6 @@ port set property portlist=48-53 medium-type=sr4 port set property portlist=129-130 medium-type=kr port set adver portlist=129-130 speed-10g-kr port set property portlist=129-130 an=enable -port set property portlist=129-130 admin=enable -port set property portlist=0-53 admin=disable +port set property unit=0 portlist=129-130 admin=enable +port set property unit=0 portlist=0-53 admin=disable + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/pg_profile_lookup.ini b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/pg_profile_lookup.ini similarity index 100% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/pg_profile_lookup.ini rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/pg_profile_lookup.ini diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.ini b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/port_config.ini similarity index 100% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.ini rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/port_config.ini diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/port_config.nps similarity index 99% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/port_config.nps index a4270503f34b..ca2bc6497685 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/port_config.nps @@ -412,3 +412,4 @@ port set adver portlist=129-130 speed-10g-kr port set property portlist=129-130 an=enable port set property unit=0 portlist=129-130 admin=enable port set property unit=0 portlist=0-53 admin=disable + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/proc_init.nps b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/proc_init.nps similarity index 100% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/proc_init.nps rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/proc_init.nps diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/qos.json.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/qos.json.j2 similarity index 100% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/qos.json.j2 rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/qos.json.j2 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/sai.profile b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/sai.profile new file mode 100644 index 000000000000..5e4ff9064d5b --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps +SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_dac.dsh b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_dac.dsh deleted file mode 100644 index 10a7b7a9df0e..000000000000 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_dac.dsh +++ /dev/null @@ -1,404 +0,0 @@ -init start stage low-level -init set port-map port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map port=19 eth-macro=8 lane=3 max-speed=25g active=true -init set port-map port=20 eth-macro=10 lane=0 max-speed=25g active=true -init set port-map port=21 eth-macro=10 lane=1 max-speed=25g active=true -init set port-map port=22 eth-macro=10 lane=2 max-speed=25g active=true -init set port-map port=23 eth-macro=10 lane=3 max-speed=25g active=true -init set port-map port=24 eth-macro=12 lane=0 max-speed=25g active=true -init set port-map port=25 eth-macro=12 lane=1 max-speed=25g active=true -init set port-map port=26 eth-macro=12 lane=2 max-speed=25g active=true -init set port-map port=27 eth-macro=12 lane=3 max-speed=25g active=true -init set port-map port=28 eth-macro=14 lane=0 max-speed=25g active=true -init set port-map port=29 eth-macro=14 lane=1 max-speed=25g active=true -init set port-map port=30 eth-macro=14 lane=2 max-speed=25g active=true -init set port-map port=31 eth-macro=14 lane=3 max-speed=25g active=true -init set port-map port=32 eth-macro=16 lane=0 max-speed=25g active=true -init set port-map port=33 eth-macro=16 lane=1 max-speed=25g active=true -init set port-map port=34 eth-macro=16 lane=2 max-speed=25g active=true -init set port-map port=35 eth-macro=16 lane=3 max-speed=25g active=true -init set port-map port=36 eth-macro=17 lane=0 max-speed=25g active=true -init set port-map port=37 eth-macro=17 lane=1 max-speed=25g active=true -init set port-map port=38 eth-macro=17 lane=2 max-speed=25g active=true -init set port-map port=39 eth-macro=17 lane=3 max-speed=25g active=true -init set port-map port=40 eth-macro=18 lane=0 max-speed=25g active=true -init set port-map port=41 eth-macro=18 lane=1 max-speed=25g active=true -init set port-map port=42 eth-macro=18 lane=2 max-speed=25g active=true -init set port-map port=43 eth-macro=18 lane=3 max-speed=25g active=true -init set port-map port=44 eth-macro=19 lane=0 max-speed=25g active=true -init set port-map port=45 eth-macro=19 lane=1 max-speed=25g active=true -init set port-map port=46 eth-macro=19 lane=2 max-speed=25g active=true -init set port-map port=47 eth-macro=19 lane=3 max-speed=25g active=true -init set port-map port=48 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map port=49 eth-macro=21 lane=0 max-speed=100g active=true -init set port-map port=50 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map port=51 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map port=52 eth-macro=28 lane=0 max-speed=100g active=true -init set port-map port=53 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true -init set port-map port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true -init start stage task-rsrc -init start stage module -init start stage task -phy set lane-swap portlist=0 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=1 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=2 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=3 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=4 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=5 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=6 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=7 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=8 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=9 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=10 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=11 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=12 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=13 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=14 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=15 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=16 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=17 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=18 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=19 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=20 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=21 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=22 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=23 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=24 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=25 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=26 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=27 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=28 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=29 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=30 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=31 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=32 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=33 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=34 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=35 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=36 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=37 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=38 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=39 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=40 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=41 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=42 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=43 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=44 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=45 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=46 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=47 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=48-53 lane-cnt=4 property=tx data=0x03.02.01.00 -phy set lane-swap portlist=0 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=1 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=2 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=3 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=4 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=5 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=6 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=7 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=8 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=9 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=10 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=11 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=12 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=13 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=14 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=15 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=16 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=17 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=18 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=19 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=20 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=21 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=22 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=23 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=24 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=25 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=26 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=27 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=28 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=29 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=30 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=31 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=32 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=33 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=34 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=35 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=36 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=37 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=38 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=39 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=40 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=41 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=42 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=43 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=44 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=45 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=46 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=47 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=48-53 lane-cnt=4 property=rx data=0x03.02.01.00 -phy set polarity-rev portlist=0 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=1 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=2 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=3 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=4 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=5 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=6 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=7 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=8 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=9 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=10 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=11 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=12 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=13 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=14 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=15 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=16 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=17 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=18 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=19 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=20 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=21 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=22 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=23 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=24 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=25 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=26 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=27 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=28 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=29 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=30 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=31 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=32 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=33 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=34 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=35 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=36 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=37 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=38 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=39 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=40 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=41 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=42 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=43 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=44 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=45 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=46 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=47 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=0 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=1 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=2 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=3 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=4 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=5 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=6 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=7 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=8 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=9 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=10 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=11 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=12 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=13 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=14 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=15 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=16 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=17 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=18 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=19 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=20 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=21 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=22 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=23 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=24 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=25 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=26 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=27 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=28 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=29 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=30 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=31 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=32 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=33 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=34 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=35 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=36 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=37 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=38 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=39 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=40 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=41 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=42 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=43 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=44 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=45 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=46 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=47 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set pre-emphasis portlist=0 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=0 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=0 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=4 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=4 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=4 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=8 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=8 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=8 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=12 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=12 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=12 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=16 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=16 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=16 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=20 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=20 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=20 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=24 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=24 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=24 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=28 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=28 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=28 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=32 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=32 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=32 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=36 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=36 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=36 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=40 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=40 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=40 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=44 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=44 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=44 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=48 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=48 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=48 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=49 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=49 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=49 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=50 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=50 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=50 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=51 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=51 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=51 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=52 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=52 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=52 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set mdio portlist=0 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=1 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=2 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=3 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=4 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=5 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=6 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=7 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=8 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=9 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=10 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=11 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=12 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=13 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=14 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=15 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=16 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=17 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=18 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=19 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=20 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=21 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=22 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=23 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=24 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=25 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=26 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=27 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=28 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=29 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=30 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=31 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=32 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=33 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=34 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=35 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=36 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=37 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=38 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=39 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=40 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=41 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=42 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=43 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=44 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=45 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=46 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=47 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=48 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=49 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=50 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=51 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=52 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=53 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=129 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=130 devad=0x1E addr=0x2 data=0x0000 -port set property portlist=0-47 speed=25g -port set property portlist=48-53 speed=100g -port set property portlist=129-130 speed=10g -port set property portlist=0-47 medium-type=cr -port set property portlist=48-53 medium-type=cr4 -port set property portlist=129-130 medium-type=kr -port set adver portlist=129-130 speed-10g-kr -port set property portlist=129-130 an=enable -port set property portlist=129-130 admin=enable -port set property portlist=0-53 admin=disable diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile deleted file mode 100644 index 02d31ffb2d54..000000000000 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile +++ /dev/null @@ -1,2 +0,0 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps -SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps \ No newline at end of file diff --git a/device/accton/x86_64-accton_as7116_54x-r0/default_sku b/device/accton/x86_64-accton_as7116_54x-r0/default_sku index 623c20034d36..146edca52638 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/default_sku +++ b/device/accton/x86_64-accton_as7116_54x-r0/default_sku @@ -1 +1 @@ -Accton-AS7116-54X t1 \ No newline at end of file +Accton-AS7116-54X-R0 t1 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/fancontrol b/device/accton/x86_64-accton_as7116_54x-r0/fancontrol index 8b1798edcc00..e16d8f936f85 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/fancontrol +++ b/device/accton/x86_64-accton_as7116_54x-r0/fancontrol @@ -7,4 +7,4 @@ MAXTEMP=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=58 MINSTART=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=100 MINSTOP=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=40 MINPWM=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=40 -MAXPWM=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=100 \ No newline at end of file +MAXPWM=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=100 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py index f5637458720e..1e7d1046d93d 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py @@ -18,4 +18,4 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) \ No newline at end of file + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py index 2faf4d5dfacf..4f0e4ef8273c 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py @@ -168,4 +168,5 @@ def get_transceiver_change_event(self, timeout=0): time.sleep(2) - return True, ret_present \ No newline at end of file + return True, ret_present + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf b/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf index ba976ef14536..9edb51a9e72d 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf +++ b/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf @@ -10,4 +10,4 @@ chip "as7116_54x_fan-*" label fan7 "rear fan 2" label fan8 "rear fan 3" label fan9 "rear fan 4" - label fan10 "rear fan 5" \ No newline at end of file + label fan10 "rear fan 5" diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/__init__.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/__init__.py new file mode 100644 index 000000000000..d82f3749319c --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py new file mode 100644 index 000000000000..6d5ed915812e --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# +try: + import sys + import re + import os + import subprocess + import json + import syslog + from sonic_platform_base.chassis_base import ChassisBase + from sonic_daemon_base.daemon_base import Logger + from sonic_platform.fan import Fan + from sonic_platform.psu import Psu + from sonic_platform.component import Component + from sonic_platform.thermal import Thermal + from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Tlv +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN_TRAY = 5 +NUM_FAN = 2 +NUM_PSU = 2 +NUM_THERMAL = 4 +NUM_SFP = 54 +SFP_PORT_START = 0 +QSFP_PORT_START = 48 +SFP_PORT_END = 47 +QSFP_PORT_END=53 +HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/" +PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" +REBOOT_CAUSE_FILE = "reboot-cause.txt" +PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" +COMPONENT_NAME_LIST = ["BIOS"] +HOST_CHK_CMD = "docker > /dev/null 2>&1" + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + super(Chassis, self).__init__() + + for fantray_index in range(0, NUM_FAN_TRAY): + for fan_index in range(0, NUM_FAN): + fan = Fan(fantray_index, fan_index) + self._fan_list.append(fan) + for index in range(0, NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) + for index in range(0, NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + self.PORT_START = SFP_PORT_START + self.QSFP_PORT_START = QSFP_PORT_START + self.PORT_END = QSFP_PORT_END + for index in range(0, NUM_SFP): + if index in range(self.QSFP_PORT_START, self.QSPORT_END + 1): + sfp_module = Sfp(index, 'QSFP') + else: + sfp_module = Sfp(index, 'SFP') + self._sfp_list.append(sfp_module) + self._component_name_list = COMPONENT_NAME_LIST + self._watchdog = Watchdog() + self._eeprom = Tlv() + logger.log_info("Chassis loaded successfully") + + def __is_host(self): + return os.system(HOST_CHK_CMD) == 0 + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.get_mac() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.get_serial() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.get_eeprom() + + def get_firmware_version(self, component_name): + """ + Retrieves platform-specific hardware/firmware versions for chassis + componenets such as BIOS, CPLD, FPGA, etc. + Args: + type: A string, component name + + Returns: + A string containing platform-specific component versions + """ + self.component = Component(component_name) + if component_name not in self._component_name_list: + return None + return self.component.get_firmware_version() + + def install_component_firmware(self, component_name, image_path): + """ + Install firmware to module + Args: + type: A string, component name. + image_path: A string, path to firmware image. + + Returns: + A boolean, True if install successfully, False if not + """ + self.component = Component(component_name) + if component_name not in self._component_name_list: + return False + return self.component.upgrade_firmware(image_path) + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + description = 'None' + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + + reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) if self.__is_host( + ) else PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE + prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) if self.__is_host( + ) else PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE + sw_reboot_cause = self.__read_txt_file( + reboot_cause_path) or "Unknown" + prev_sw_reboot_cause = self.__read_txt_file( + prev_reboot_cause_path) or "Unknown" + + if sw_reboot_cause != "Unknown": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = sw_reboot_cause + else: + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'Unknown reason' + + return (reboot_cause, description) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/component.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/component.py new file mode 100644 index 000000000000..c8f109aa4db9 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/component.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python + +############################################################################# +# Component contains an implementation of SONiC Platform Base API and +# provides the components firmware management function +############################################################################# + +import json +import os.path +import shutil +import shlex +import subprocess + +try: + from sonic_platform_base.device_base import DeviceBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" + +class Component(DeviceBase): + """Platform-specific Component class""" + + DEVICE_TYPE = "component" + + def __init__(self, component_name): + DeviceBase.__init__(self) + self.name = component_name.upper() + + def __run_command(self, command): + # Run bash command and print output to stdout + try: + process = subprocess.Popen( + shlex.split(command), stdout=subprocess.PIPE) + while True: + output = process.stdout.readline() + if output == '' and process.poll() is not None: + break + rc = process.poll() + if rc != 0: + return False + except: + return False + return True + + def __get_bios_version(self): + # Retrieves the BIOS firmware version + try: + with open(BIOS_VERSION_PATH, 'r') as fd: + bios_version = fd.read() + return bios_version.strip() + except Exception as e: + return None + + def get_firmware_version(self): + """ + Retrieves the firmware version of module + Returns: + string: The firmware versions of the module + """ + fw_version = None + + if self.name == "BIOS": + fw_version = self.__get_bios_version() + + return fw_version + + def upgrade_firmware(self, image_path): + """ + Install firmware to module + Args: + image_path: A string, path to firmware image + Returns: + A boolean, True if install successfully, False if not + """ + if not os.path.isfile(image_path): + return False + + if self.name == "BIOS": + print("Not supported") + return False + + return self.__run_command(install_command) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/eeprom.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/eeprom.py new file mode 100644 index 000000000000..714ac8153e0e --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/eeprom.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python + +############################################################################# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import glob + import os + import sys + import imp + import re + from array import array + from cStringIO import StringIO + from sonic_platform_base.sonic_eeprom import eeprom_dts + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' +CACHE_FILE = 'syseeprom_cache' + + +class Tlv(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + + def __init__(self): + self._eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" + super(Tlv, self).__init__(self._eeprom_path, 0, '', True) + self._eeprom = self._load_eeprom() + + def __parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search( + '(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + if match is not None: + idx = match.group(1) + value = match.group(3).rstrip('\0') + + _eeprom_info_dict[idx] = value + except: + pass + return _eeprom_info_dict + + def _load_eeprom(self): + original_stdout = sys.stdout + sys.stdout = StringIO() + err = self.read_eeprom_db() + if err: + # Failed to read EEPROM information from database. Read from cache file + pass + else: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + return self.__parse_output(decode_output) + + status = self.check_status() + if status < 'ok': + return False + + if not os.path.exists(CACHE_ROOT): + try: + os.makedirs(CACHE_ROOT) + except: + pass + + # + # only the eeprom classes that inherit from eeprom_base + # support caching. Others will work normally + # + try: + self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) + except: + pass + + e = self.read_eeprom() + if e is None: + return 0 + + try: + self.update_cache(e) + except: + pass + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + (is_valid, valid_crc) = self.is_checksum_valid(e) + if not is_valid: + return False + + return self.__parse_output(decode_output) + + def get_eeprom(self): + return self._eeprom + + def get_serial(self): + return self._eeprom.get('0x23', "Undefined.") + + def get_mac(self): + return self._eeprom.get('0x24', "Undefined.") diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/fan.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/fan.py new file mode 100644 index 000000000000..54878e3e1baa --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/fan.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +import json +import math +import os.path + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +FAN_PATH = "/sys/bus/i2c/devices/1-0063/" +FANTRAY_NAME_LIST = ["FANTRAY-1", "FANTRAY-2", + "FANTRAY-3", "FANTRAY-4", "FANTRAY-5"] +FAN_NAME_LIST = ["front", "rear"] + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_tray_index, fan_index=0): + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + self.fan_presence = "fan{}_present" + self.fan_direction = "fan{}_direction" + self.fan_fault = "fan{}_{}_fault" + self.fan_speed_rpm = "fan{}_{}_speed_rpm" + FanBase.__init__(self) + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return "" + + def __write_txt_file(self, file_path, value): + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except: + return False + return True + + def __search_file_by_name(self, directory, file_name): + for dirpath, dirnames, files in os.walk(directory): + for name in files: + file_path = os.path.join(dirpath, name) + if name in file_name: + return file_path + return None + + def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = self.FAN_DIRECTION_EXHAUST + fan_direction_file = (FAN_PATH + + self.fan_direction.format(self.fan_tray_index+1)) + raw = self.__read_txt_file(fan_direction_file).strip('\r\n') + direction = self.FAN_DIRECTION_INTAKE if str( + raw).upper() == "1" else self.FAN_DIRECTION_EXHAUST + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 12000 (full speed) + """ + speed = 0 + if self.get_presence(): + fan_speed_file = (FAN_PATH + + self.fan_speed_rpm.format(self.fan_tray_index+1,FAN_NAME_LIST[self.fan_index])) + speed = self.__read_txt_file(fan_speed_file).strip('\r\n') + + return int(speed) + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + target = 0 + if self.get_presence(): + fan_speed_file=(FAN_PATH + + self.fan_speed_rpm.format(self.fan_tray_index+1, FAN_NAME_LIST[self.fan_index])) + target=self.__read_txt_file(fan_speed_file).strip('\r\n') + + return target + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return 10 + + def set_speed(self, speed): + """ + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + + Note: + Depends on pwm or target mode is selected: + 1) pwm = speed_pc * 255 <-- Currently use this mode. + 2) target_pwm = speed_pc * 100 / 255 + 2.1) set pwm{}_enable to 3 + + """ + return False + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + return False + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + fan_name = FAN_NAME_LIST[self.fan_tray_index] + + return fan_name + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + fan_direction_file = (FAN_PATH + + self.fan_presence.format(self.fan_tray_index+1)) + present_str = self.__read_txt_file(fan_direction_file) or '1' + + return int(present_str) == 0 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/platform.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/platform.py new file mode 100644 index 000000000000..44e03cdadbb3 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/platform.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python + +############################################################################# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/psu.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/psu.py new file mode 100644 index 000000000000..b1c8029dced9 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/psu.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python + +############################################################################# +# psuutil.py +# Platform-specific PSU status interface for SONiC +############################################################################# + +import os.path +import sonic_platform + +try: + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +FAN_MAX_RPM = 9600 +PSU_NAME_LIST = ["PSU-0", "PSU-1"] + +class Psu(PsuBase): + """Platform-specific Psu class""" + + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/10-0050", + "/sys/bus/i2c/devices/11-0053"] + + def __init__(self): + self.index = psu_index + PsuBase.__init__(self) + + + def get_fan(self): + """ + Retrieves object representing the fan module contained in this PSU + Returns: + An object dervied from FanBase representing the fan module + contained in this PSU + """ + # Hardware not supported + return False + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the PSU status LED + Note: Only support green and off + Returns: + bool: True if status LED state is set successfully, False if not + """ + # Hardware not supported + return False + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return PSU_NAME_LIST[self.index] + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + attr_file ='psu_present' + attr_path = self.SYSFS_PSU_DIR[self.index-1] +'/' + attr_file + status = 0 + try: + with open(attr_path, 'r') as psu_prs: + status = int(psu_prs.read()) + except IOError: + return False + + return status == 1 + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + attr_file = 'psu_power_good' + attr_path = self.SYSFS_PSU_DIR[self.index-1] +'/' + attr_file + status = 0 + try: + with open(attr_path, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py new file mode 100644 index 000000000000..07e0649579ac --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py @@ -0,0 +1,1133 @@ +#!/usr/bin/env python + +############################################################################# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +############################################################################# +try: + import os + import time + import subprocess + import sonic_device_util + import syslog + from ctypes import create_string_buffer + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from sonic_daemon_base.daemon_base import Logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 0 +DOM_OFFSET = 256 + +QSFP_INFO_OFFSET = 128 +QSFP_DOM_OFFSET = 0 + +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# Offset for values in SFP eeprom +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +# Offset for values in QSFP eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + # Port number + PORT_START = 0 + PORT_END = 53 + + port_to_i2c_mapping = { + 0: 37, + 1: 38, + 2: 39, + 3: 40, + 4: 41, + 5: 42, + 6: 43, + 7: 44, + 8: 45, + 9: 46, + 10: 47, + 11: 48, + 12: 49, + 13: 50, + 14: 51, + 15: 52, + 16: 53, + 17: 54, + 18: 55, + 19: 56, + 20: 57, + 21: 58, + 22: 59, + 23: 60, + 24: 61, + 25: 62, + 26: 63, + 27: 64, + 28: 65, + 29: 66, + 30: 67, + 31: 68, + 32: 69, + 33: 70, + 34: 71, + 35: 72, + 36: 73, + 37: 74, + 38: 75, + 39: 76, + 40: 77, + 41: 78, + 42: 79, + 43: 80, + 44: 81, + 45: 82, + 46: 83, + 47: 84, + 48: 21, + 49: 22, + 50: 23, + 51: 24, + 52: 25, + 53: 26, + } + _sfp_port = range(48, PORT_END + 1) + RESET_PATH = "/sys/bus/i2c/devices/{}-0050/sfp_port_reset" + PRS_PATH = "/sys/bus/i2c/devices/{}-0050/sfp_is_present" + + PLATFORM_ROOT_PATH = '/usr/share/sonic/device' + PMON_HWSKU_PATH = '/usr/share/sonic/hwsku' + HOST_CHK_CMD = "docker > /dev/null 2>&1" + + PLATFORM = "x86_64-accton_as7116_54x-r0" + HWSKU = "Accton-AS7116-54X-R0" + + def __init__(self, sfp_index, sfp_type): + # Init index + self.index = sfp_index + self.port_num = self.index + 1 + self.sfp_type = sfp_type + + # Init eeprom path + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' + self.port_to_eeprom_mapping = {} + for x in range(self.PORT_START, self.PORT_END + 1): + p_num = x - 1 if self.PORT_START == 1 else x + self.port_to_eeprom_mapping[p_num] = eeprom_path.format( + self.port_to_i2c_mapping[p_num]) + + self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + SfpBase.__init__(self) + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return "" + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.sfp_index] + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + """ + if self.sfp_type == "SFP": + get_sfp_transceiver_info + else: + get_qsfp_transceiver_info + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + """ + if self.sfp_type == "SFP": + get_sfp_transceiver_bulk_status + else: + get_qsfp_transceiver_bulk_status + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + """ + if self.sfp_type == "SFP": + get_sfp_transceiver_threshold_info + else: + get_qsfp_transceiver_threshold_info + + def get_sfp_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + # check present status + sfpi_obj = sff8472InterfaceId() + if not self.get_presence() or not sfpi_obj: + return {} + + offset = INFO_OFFSET + + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_SFP) + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw, 0) + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_SFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + compliance_code_dict = dict() + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[ + 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" + + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_sfp_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + # check present status + sfpd_obj = sff8472Dom() + if not self.get_presence() or not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_voltage_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value'] + transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self._convert_string_to_num( + transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_sfp_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + # check present status + sfpd_obj = sff8472Dom() + + if not self.get_presence() and not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_threshold_info_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') + dom_module_threshold_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) + + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[ + 'data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num( + transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict + + def get_qsfp_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + # check present status + sfpi_obj = sff8436InterfaceId() + if not self.get_presence() or not sfpi_obj: + return {} + + offset = INFO_OFFSET + + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP) + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw, 0) + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + compliance_code_dict = dict() + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[ + 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" + + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + + return transceiver_info_dict + + def get_qsfp_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + # check present status + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not self.get_presence() or not sfpi_obj or not sfpd_obj: + return {} + + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability( + qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self._convert_string_to_num( + transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_qsfp_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + # check present status + sfpd_obj = sff8436Dom() + + if not self.get_presence() or not sfpd_obj: + return {} + + transceiver_dom_threshold_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') + dom_thres_raw = self.__read_eeprom_specific_bytes( + QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None + + if dom_thres_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values( + dom_thres_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_thres_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None + channel_threshold_values = sfpd_obj.parse_channel_threshold_values( + dom_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + for key in transceiver_dom_threshold_dict: + transceiver_dom_threshold_dict[key] = self._convert_string_to_num( + transceiver_dom_threshold_dict[key]) + + return transceiver_dom_threshold_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = False + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = False + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable = False + tx_fault = False + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_disable_hard = (sffbase().test_bit( + data, SFP_TX_DISABLE_HARD_BIT) != 0) + tx_disable_soft = (sffbase().test_bit( + data, SFP_TX_DISABLE_SOFT_BIT) != 0) + tx_disable = tx_disable_hard | tx_disable_soft + + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + # SFP doesn't support this feature + return 0 + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("temperature", "N/A") + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") + return [tx1_bs, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") + return [rx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") + return [tx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + # SFP doesn't support this feature + return False + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.index] + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw is not None: + # Set bit 6 for Soft TX Disable Select + # 01000000 = 64 and 10111111 = 191 + tx_disable_bit = 64 if tx_disable else 191 + status_control = int(status_control_raw[0], 16) + tx_disable_ctl = (status_control | tx_disable_bit) if tx_disable else ( + status_control & tx_disable_bit) + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0) + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom.seek(SFP_STATUS_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except: + #print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + # SFP doesn't support this feature + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + # SFP doesn't support this feature + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + # SFP doesn't support this feature + return False + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the SFP + Returns: + bool: True if SFP is present, False if not + """ + presence = False + + try: + with open(self.PRS_PATH.format(self.index), 'r') as sfp_presence: + presence = int(sfp_presence.read(), 16) + except IOError: + return False + logger.log_info("debug:port_ %s sfp presence is %s" % (str(self.index)), % (str(presence)) + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("modelname", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("serialnum", "N/A") diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/__init__.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/fanutil.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/fanutil.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/thermalutil.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/thermalutil.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service b/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service index 4331c8828eea..6eaf4745210c 100755 --- a/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service @@ -1,6 +1,7 @@ [Unit] Description=Accton AS7116-54X Platform initialization service Before=pmon.service +After=sysinit.target DefaultDependencies=no [Service] @@ -10,4 +11,4 @@ ExecStop=/usr/local/bin/accton_as7116_util.py clean RemainAfterExit=yes [Install] -WantedBy=multi-user.target \ No newline at end of file +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/platform_api/platform_api_mgnt.sh b/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/platform_api/platform_api_mgnt.sh new file mode 100755 index 000000000000..e1d330357894 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/platform_api/platform_api_mgnt.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +PREV_REBOOT_CAUSE="/host/reboot-cause/" +DEVICE="/usr/share/sonic/device" +PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) +FILES=$DEVICE/$PLATFORM/api_files + +install() { + # Install sonic-platform package + if [ -e $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl ]; then + pip install $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl + fi +} + +init() { + # mount needed files for sonic-platform package + mkdir -p $FILES + + mkdir -p $FILES/reboot-cause + mount -B $PREV_REBOOT_CAUSE $FILES/reboot-cause +} + +deinit() { + # deinit sonic-platform package + umount -f $PREV_REBOOT_CAUSE $FILES/reboot-cause >/dev/null 2>/dev/null +} + +uninstall() { + # Uninstall sonic-platform package + pip uninstall -y sonic-platform >/dev/null 2>/dev/null +} + +case "$1" in +install | uninstall | init | deinit) + $1 + ;; +*) + echo "Usage: $0 {install|uninstall|init|deinit}" + exit 1 + ;; +esac diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py index bb740409e310..088e1f30355a 100644 --- a/platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py @@ -1,15 +1,34 @@ -#!/usr/bin/env python - -import os -import sys from setuptools import setup -os.listdir -setup( - name='as7116-54x', - version='1.0.0', - description='Module to initialize Accton AS7116-54X platforms', +DEVICE_NAME = 'accton' +HW_SKU = 'x86_64-accton_as7116_54x-r0' - packages=['as7116-54x'], - package_dir={'as7116-54x': 'as7116-54x/classes'}, - ) +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Accton Platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Simon Ji', + maintainer_email='Simon.Ji@mediatek.com', + packages=[ + 'sonic_platform', + ], + package_dir={ + 'sonic_platform': '../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)}, + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py index 26a8a3cc8f84..2d9ea128f976 100755 --- a/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py @@ -21,13 +21,13 @@ options: -h | --help : this help message -d | --debug : run with debug mode - -f | --force : ignore error during installation or clean + -f | --force : ignore error during installation or clean command: install : install drivers and generate related sysfs nodes clean : uninstall drivers and remove related sysfs nodes show : show all systen status sff : dump SFP eeprom - set : change board setting with fan|led|sfp + set : change board setting with fan|led|sfp """ import os @@ -46,7 +46,7 @@ verbose = False DEBUG = False args = [] -ALL_DEVICE = {} +ALL_DEVICE = {} DEVICE_NO = {'led':5, 'fan':1, 'thermal':3, 'psu':2, 'sfp':54} FORCE = 0 #logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) @@ -55,37 +55,37 @@ if DEBUG == True: print sys.argv[0] - print 'ARGV :', sys.argv[1:] + print 'ARGV :', sys.argv[1:] def main(): global DEBUG global args global FORCE - + if len(sys.argv)<2: show_help() - + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', 'debug', 'force', ]) - if DEBUG == True: + if DEBUG == True: print options print args print len(sys.argv) - + for opt, arg in options: if opt in ('-h', '--help'): show_help() - elif opt in ('-d', '--debug'): + elif opt in ('-d', '--debug'): DEBUG = True logging.basicConfig(level=logging.INFO) - elif opt in ('-f', '--force'): + elif opt in ('-f', '--force'): FORCE = 1 else: - logging.info('no option') - for arg in args: + logging.info('no option') + for arg in args: if arg == 'install': do_install() elif arg == 'clean': @@ -95,23 +95,23 @@ def main(): elif arg == 'sff': if len(args)!=2: show_eeprom_help() - elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: show_eeprom_help() else: - show_eeprom(args[1]) - return + show_eeprom(args[1]) + return elif arg == 'set': if len(args)<3: show_set_help() else: - set_device(args[1:]) - return + set_device(args[1:]) + return else: show_help() - - - return 0 - + + + return 0 + def show_help(): print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} sys.exit(0) @@ -120,36 +120,36 @@ def show_set_help(): cmd = sys.argv[0].split("/")[-1]+ " " + args[0] print cmd +" [led|sfp|fan]" print " use \""+ cmd + " led 0-4 \" to set led color" - print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" - print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" - sys.exit(0) - + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + def show_eeprom_help(): cmd = sys.argv[0].split("/")[-1]+ " " + args[0] - print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" - sys.exit(0) - + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + def my_log(txt): if DEBUG == True: - print "[ROY]"+txt + print "[ROY]"+txt return - + def log_os_system(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) my_log (cmd +"with result:" + str(status)) - my_log (" output:"+output) + my_log (" output:"+output) if status: logging.info('Failed :'+cmd) if show: print('Failed :'+cmd) return status, output - + def driver_check(): ret, lsmod = log_os_system("lsmod| grep accton", 0) logging.info('mods:'+lsmod) if len(lsmod) ==0: - return False + return False return True @@ -169,19 +169,19 @@ def driver_install(): for i in range(0,len(kos)): status, output = log_os_system(kos[i], 1) if status: - if FORCE == 0: - return status + if FORCE == 0: + return status return 0 - + def driver_uninstall(): global FORCE for i in range(0,len(kos)): rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") - rm = rm.replace("insmod", "rmmod") + rm = rm.replace("insmod", "rmmod") status, output = log_os_system(rm, 1) if status: - if FORCE == 0: - return status + if FORCE == 0: + return status return 0 led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' @@ -192,13 +192,13 @@ def driver_uninstall(): i2c_prefix = '/sys/bus/i2c/devices/' i2c_bus = {'fan': ['1-0063'] , 'thermal': ['17-004b','19-0049', '20-004a'] , - 'psu': ['10-0050','11-0058'], + 'psu': ['10-0050','11-0058'], 'sfp': ['-0050']} i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] , 'thermal': ['hwmon/hwmon*/temp1_input'] , 'psu': ['psu_present ', 'psu_power_good'] , 'sfp': ['sfp_is_present ', 'sfp_tx_disable_all']} - + sfp_map = [37,38,39,40, 41,42,43,44,45,46,47,48,49,50, 51,52,53,54,55,56,57,58,59,60, @@ -234,23 +234,23 @@ def driver_uninstall(): def device_install(): global FORCE - + for i in range(0,len(mknod)): - #for pca954x need times to built new i2c buses + #for pca954x need times to built new i2c buses if mknod[i].find('pca954') != -1: time.sleep(1) - + status, output = log_os_system(mknod[i], 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status - + for i in range(0,len(sfp_map)): status, output =log_os_system("echo as7116_54x_sfp"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status if i <= 47: @@ -260,11 +260,11 @@ def device_install(): if FORCE == 0: return status - return - + return + def device_uninstall(): global FORCE - + status, output =log_os_system("ls /sys/bus/i2c/devices/1-0077", 0) for i in range(0,len(sfp_map)): @@ -272,11 +272,11 @@ def device_uninstall(): status, output =log_os_system("echo 0x50 > "+ target, 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status - + nodelist = mknod - + for i in range(len(nodelist)): target = nodelist[-(i+1)] temp = target.split() @@ -285,72 +285,79 @@ def device_uninstall(): status, output = log_os_system(" ".join(temp), 1) if status: print output - if FORCE == 0: - return status - - return - + if FORCE == 0: + return status + + return + def system_ready(): if driver_check() == False: return False - if not device_exist(): + if not device_exist(): return False return True - + def do_install(): print "Checking system...." if driver_check() == False: - print "No driver, installing...." + print "No driver, installing...." status = driver_install() if status: - if FORCE == 0: + if FORCE == 0: return status else: - print PROJECT_NAME.upper()+" drivers detected...." + print PROJECT_NAME.upper()+" drivers detected...." if not device_exist(): - print "No device, installing...." - status = device_install() + print "No device, installing...." + status = device_install() if status: - if FORCE == 0: - return status + if FORCE == 0: + return status else: - print PROJECT_NAME.upper()+" devices detected...." + print PROJECT_NAME.upper()+" devices detected...." + + status, output = log_os_system( + "/bin/sh /usr/local/bin/platform_api_mgnt.sh init", 1) + if status: + print output + if FORCE == 0: + return status return - + def do_uninstall(): print "Checking system...." if not device_exist(): - print PROJECT_NAME.upper() +" has no device installed...." + print PROJECT_NAME.upper() +" has no device installed...." else: - print "Removing device...." - status = device_uninstall() + print "Removing device...." + status = device_uninstall() if status: - if FORCE == 0: - return status - + if FORCE == 0: + return status + if driver_check()== False : print PROJECT_NAME.upper() +" has no driver installed...." else: print "Removing installed driver...." status = driver_uninstall() if status: - if FORCE == 0: - return status - - return + if FORCE == 0: + return status + + return def devices_info(): global DEVICE_NO global ALL_DEVICE global i2c_bus, hwmon_types - for key in DEVICE_NO: - ALL_DEVICE[key]= {} + for key in DEVICE_NO: + ALL_DEVICE[key]= {} for i in range(0,DEVICE_NO[key]): ALL_DEVICE[key][key+str(i+1)] = [] - + for key in i2c_bus: buses = i2c_bus[key] - nodes = i2c_nodes[key] + nodes = i2c_nodes[key] for i in range(0,len(buses)): for j in range(0,len(nodes)): if 'fan' == key: @@ -358,52 +365,52 @@ def devices_info(): node = key+str(k+1) path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) + ALL_DEVICE[key][node].append(path) elif 'sfp' == key: for k in range(0,DEVICE_NO[key]): node = key+str(k+1) - path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) + ALL_DEVICE[key][node].append(path) else: node = key+str(i+1) - path = i2c_prefix+ buses[i]+"/"+ nodes[j] + path = i2c_prefix+ buses[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) - + ALL_DEVICE[key][node].append(path) + for key in hwmon_types: itypes = hwmon_types[key] - nodes = hwmon_nodes[key] + nodes = hwmon_nodes[key] for i in range(0,len(itypes)): - for j in range(0,len(nodes)): + for j in range(0,len(nodes)): node = key+"_"+itypes[i] - path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][ key+str(i+1)].append(path) - + ALL_DEVICE[key][ key+str(i+1)].append(path) + #show dict all in the order if DEBUG == True: for i in sorted(ALL_DEVICE.keys()): print(i+": ") - for j in sorted(ALL_DEVICE[i].keys()): + for j in sorted(ALL_DEVICE[i].keys()): print(" "+j) - for k in (ALL_DEVICE[i][j]): + for k in (ALL_DEVICE[i][j]): print(" "+" "+k) - return - + return + def show_eeprom(index): if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: - devices_info() + devices_info() node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] node = node.replace(node.split("/")[-1], 'sfp_eeprom') # check if got hexdump command in current environment ret, log = log_os_system("which hexdump", 0) - ret, log2 = log_os_system("which busybox hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) if len(log): hex_cmd = 'hexdump' elif len(log2): @@ -412,111 +419,111 @@ def show_eeprom(index): log = 'Failed : no hexdump cmd!!' logging.info(log) print log - return 1 - + return 1 + print node + ":" ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) - if ret==0: - print log + if ret==0: + print log else: - print "**********device no found**********" - return - + print "**********device no found**********" + return + def set_device(args): global DEVICE_NO global ALL_DEVICE if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: - devices_info() - + devices_info() + if args[0]=='led': if int(args[1])>4: show_set_help() return #print ALL_DEVICE['led'] - for i in range(0,len(ALL_DEVICE['led'])): - for k in (ALL_DEVICE['led']['led'+str(i+1)]): + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): ret, log = log_os_system("echo "+args[1]+" >"+k, 1) if ret: - return ret + return ret elif args[0]=='fan': if int(args[1])>100: show_set_help() return #print ALL_DEVICE['fan'] - #fan1~6 is all fine, all fan share same setting - node = ALL_DEVICE['fan'] ['fan1'][0] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') - ret, log = log_os_system("cat "+ node, 1) + ret, log = log_os_system("cat "+ node, 1) if ret==0: - print ("Previous fan duty: " + log.strip() +"%") + print ("Previous fan duty: " + log.strip() +"%") ret, log = log_os_system("echo "+args[1]+" >"+node, 1) if ret==0: - print ("Current fan duty: " + args[1] +"%") + print ("Current fan duty: " + args[1] +"%") return ret elif args[0]=='sfp': if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: show_set_help() - return + return if len(args)<2: show_set_help() - return - + return + if int(args[2])>1: show_set_help() return - - #print ALL_DEVICE[args[0]] - for i in range(0,len(ALL_DEVICE[args[0]])): - for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: - if j.find('tx_disable')!= -1: + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) if ret: - return ret - + return ret + return - -#get digits inside a string. -#Ex: 31 for "sfp31" + +#get digits inside a string. +#Ex: 31 for "sfp31" def get_value(input): digit = re.findall('\d+', input) return int(digit[0]) - + def device_traversal(): if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: devices_info() for i in sorted(ALL_DEVICE.keys()): - print("============================================") + print("============================================") print(i.upper()+": ") print("============================================") - - for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): print " "+j+":", for k in (ALL_DEVICE[i][j]): ret, log = log_os_system("cat "+k, 0) func = k.split("/")[-1].strip() func = re.sub(j+'_','',func,1) - func = re.sub(i.lower()+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) if ret==0: - print func+"="+log+" ", + print func+"="+log+" ", else: print func+"="+"X"+" ", - print + print print("----------------------------------------------------------------") - - + + print return - + def device_exist(): ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) diff --git a/platform/nephos/sonic-platform-modules-accton/debian/rules b/platform/nephos/sonic-platform-modules-accton/debian/rules index 44caba25cfa2..de84b23d55ae 100755 --- a/platform/nephos/sonic-platform-modules-accton/debian/rules +++ b/platform/nephos/sonic-platform-modules-accton/debian/rules @@ -1,19 +1,8 @@ #!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -include /usr/share/dpkg/pkg-info.mk - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 export INSTALL_MOD_DIR:=extra -PYTHON ?= python2 +PYTHON ?= python2.7 PACKAGE_PRE_NAME := sonic-platform-accton KVERSION ?= $(shell uname -r) @@ -27,60 +16,25 @@ CLASSES_DIR := classes CONF_DIR := conf %: - dh $@ --with systemd,python2,python3 --buildsystem=pybuild - -clean: - dh_testdir - dh_testroot - dh_clean + dh $@ -build: - #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) +override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ - $(PYTHON) $${mod}/setup.py build; \ + $(PYTHON) $${mod}/setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ done) -binary: binary-arch binary-indep - # Nothing to do - -binary-arch: - # Nothing to do - -#install: build - #dh_testdir - #dh_testroot - #dh_clean -k - #dh_installdirs +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko \ + debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) -binary-indep: - dh_testdir - dh_installdirs +override_dh_usrlocal: - # Custom package commands +override_dh_clean: + dh_clean (for mod in $(MODULE_DIRS); do \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /usr/local/bin; \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /lib/systemd/system; \ - cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ - cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ - $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ done) - # Resuming debhelper scripts - dh_testroot - dh_install - dh_installchangelogs - dh_installdocs - dh_systemd_enable - dh_installinit - dh_systemd_start - dh_link - dh_fixperms - dh_compress - dh_strip - dh_installdeb - dh_gencontrol - dh_md5sums - dh_builddeb -.PHONY: build binary binary-arch binary-indep clean \ No newline at end of file diff --git a/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.install b/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.install new file mode 100644 index 000000000000..61423affe7ac --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.install @@ -0,0 +1,4 @@ +as7116-54x/utils/* usr/local/bin +as7116-54x/service/*.service lib/systemd/system +as7116-54x/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-accton_as7116_54x-r0 +as7116-54x/service/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.postinst b/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.postinst new file mode 100644 index 000000000000..a9947af877b6 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.postinst @@ -0,0 +1,5 @@ +depmod -a +systemctl enable as7116-platform-init.service +systemctl start as7116-platform-init.service + +/usr/local/bin/platform_api_mgnt.sh install From be3421c352c1a16c8efaa95b3ee39b2ede24306f Mon Sep 17 00:00:00 2001 From: "Sudharsan D.G" Date: Fri, 8 Nov 2019 22:57:05 -0800 Subject: [PATCH 0146/1427] [docker-ptf]: Added python-libpcap for the updated arp responder (#3731) Added python-libpcap to be used by arp_responder.py utility. This is needed to set conf.use_pcap which will make sure that L2pcapListenSocket uses libpcap instead of Linux PF_PACKET sockets. By using libpcap the vlan field will not be removed when the application receives the packet. --- dockers/docker-ptf/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index 79c2802c0429..dcf67aeff5f9 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -53,6 +53,7 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / tcpdump \ python \ python-dev \ + python-libpcap \ python-scapy \ python-six From c70d8bca9fcf97388c34d9a40bfc25aba496bc7f Mon Sep 17 00:00:00 2001 From: Olivier Singla <47356901+olivier-singla@users.noreply.github.com> Date: Sat, 9 Nov 2019 02:08:42 -0500 Subject: [PATCH 0147/1427] [baseimage]: kdump support (#3722) * In the event of a kernel crash, we need to gather as much information as possible to understand and identify the root cause of the crash. Currently, the kernel does not provide much information, which make kernel crash investigation difficult and time consuming. Fortunately, there is a way in the kernel to provide more information in the case of a kernel crash. kdump is a feature of the Linux kernel that creates crash dumps in the event of a kernel crash. This PR will add kermel kdump support. An extension to the CLI utilities config and show is provided to configure and manage kdump: - enable / disable kdump functionality - configure kdump (how many kernel crash logs can be saved, memory allocated for capture kernel) - view kernel crash logs --- build_debian.sh | 7 +++- .../build_templates/sonic_debian_extension.j2 | 4 ++ rules/kdump-tools.mk | 13 ++++++ slave.mk | 1 + sonic-slave-stretch/Dockerfile.j2 | 4 +- src/kdump-tools/Makefile | 32 +++++++++++++++ ...amfs-for-installed-kernels-in-chroot.patch | 41 +++++++++++++++++++ .../0002-core-file-prefixed-by-kdump.patch | 24 +++++++++++ src/kdump-tools/patch/series | 2 + 9 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 rules/kdump-tools.mk create mode 100644 src/kdump-tools/Makefile create mode 100644 src/kdump-tools/patch/0001-Generate-initramfs-for-installed-kernels-in-chroot.patch create mode 100644 src/kdump-tools/patch/0002-core-file-prefixed-by-kdump.patch create mode 100644 src/kdump-tools/patch/series diff --git a/build_debian.sh b/build_debian.sh index d1e5273b1c71..fb3ecfef6ce6 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -272,7 +272,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in locales \ cgroup-tools \ ipmitool \ - ndisc6 + ndisc6 \ + makedumpfile if [[ $CONFIGURED_ARCH == amd64 ]]; then @@ -289,6 +290,10 @@ sudo LANG=c chroot $FILESYSTEM_ROOT chmod 600 /etc/shadow sudo LANG=c chroot $FILESYSTEM_ROOT chmod 644 /etc/passwd sudo LANG=c chroot $FILESYSTEM_ROOT chmod 644 /etc/group +# Needed to install kdump-tools +sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "mkdir -p /etc/initramfs-tools/conf.d" +sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo 'MODULES=most' >> /etc/initramfs-tools/conf.d/driver-policy" + #Adds a locale to a debian system in non-interactive mode sudo sed -i '/^#.* en_US.* /s/^#//' $FILESYSTEM_ROOT/etc/locale.gen && \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT locale-gen "en_US.UTF-8" diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index f5a734b3a273..d81815284a34 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -160,6 +160,10 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libnss-tacplus_*.deb || \ sudo LANG=C chroot $FILESYSTEM_ROOT pam-auth-update --remove tacplus sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf +# Install a custom version of kdump-tools (and its dependencies via 'apt-get -y install -f') +sudo DEBIAN_FRONTEND=noninteractive dpkg --root=$FILESYSTEM_ROOT -i $debs_path/kdump-tools_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=truechroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install + # Copy crontabs sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ diff --git a/rules/kdump-tools.mk b/rules/kdump-tools.mk new file mode 100644 index 000000000000..d5d2630389f3 --- /dev/null +++ b/rules/kdump-tools.mk @@ -0,0 +1,13 @@ +# kdump-tools package + +KDUMP_TOOLS_VERSION_BASE = 1.6.1 +KDUMP_TOOLS_VERSION = $(KDUMP_TOOLS_VERSION_BASE)-1 +export KDUMP_TOOLS_VERSION_BASE +export KDUMP_TOOLS_VERSION + +KDUMP_TOOLS = kdump-tools_$(KDUMP_TOOLS_VERSION)_all.deb +$(KDUMP_TOOLS)_SRC_PATH = $(SRC_PATH)/kdump-tools +SONIC_MAKE_DEBS += $(KDUMP_TOOLS) +SONIC_STRETCH_DEBS += $(KDUMP_TOOLS) + +export KDUMP_TOOLS diff --git a/slave.mk b/slave.mk index 1f5f3de7b3b0..f81895f74dd2 100644 --- a/slave.mk +++ b/slave.mk @@ -614,6 +614,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(SONIC_DEVICE_DATA) \ $(PYTHON_CLICK) \ $(IFUPDOWN2) \ + $(KDUMP_TOOLS) \ $(LIBPAM_TACPLUS) \ $(LIBNSS_TACPLUS)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index af6e7deadc31..f52bd943b0a7 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -289,7 +289,9 @@ RUN apt-get update && apt-get install -y \ rrdtool \ # For smartmontools 6.6-1 automake1.11 \ - libselinux1-dev + libselinux1-dev \ +# For kdump-tools + liblzo2-dev # For smartmontools 6.6-1 RUN apt-get -t stretch-backports install -y debhelper diff --git a/src/kdump-tools/Makefile b/src/kdump-tools/Makefile new file mode 100644 index 000000000000..18c2a369b5d7 --- /dev/null +++ b/src/kdump-tools/Makefile @@ -0,0 +1,32 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = $(KDUMP_TOOLS) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Remove any stale files + rm -rf ./makedumpfile_$(KDUMP_TOOLS_VERSION_BASE).orig.tar.gz ./makedumpfile_$(KDUMP_TOOLS_VERSION).debian.tar.xz + rm -rf ./makedumpfile-$(KDUMP_TOOLS_VERSION_BASE) + + # Get makedumpfile release + wget http://deb.debian.org/debian/pool/main/m/makedumpfile/makedumpfile_$(KDUMP_TOOLS_VERSION_BASE).orig.tar.gz + wget http://deb.debian.org/debian/pool/main/m/makedumpfile/makedumpfile_$(KDUMP_TOOLS_VERSION).debian.tar.xz + tar -f makedumpfile_$(KDUMP_TOOLS_VERSION_BASE).orig.tar.gz -x + pushd ./makedumpfile-$(KDUMP_TOOLS_VERSION_BASE) + tar -f ../makedumpfile_$(KDUMP_TOOLS_VERSION).debian.tar.xz -x + + git init + git add -f * + git commit -m "unmodified kdump-tools source" + + # Apply patches + stg init + stg import -s ../patch/series + + # Build source and Debian packages + fakeroot debian/rules binary-indep + popd + + # Move the newly-built .deb packages to the destination directory + mv $* $(DEST)/ diff --git a/src/kdump-tools/patch/0001-Generate-initramfs-for-installed-kernels-in-chroot.patch b/src/kdump-tools/patch/0001-Generate-initramfs-for-installed-kernels-in-chroot.patch new file mode 100644 index 000000000000..1d994b88bd58 --- /dev/null +++ b/src/kdump-tools/patch/0001-Generate-initramfs-for-installed-kernels-in-chroot.patch @@ -0,0 +1,41 @@ +From 7e6c0d5b0c7299154f75f281c02cf02cf85fb80e Mon Sep 17 00:00:00 2001 +From: Benjamin Drung +Date: Thu, 2 Mar 2017 19:52:23 +0100 +Subject: [PATCH] Generate initramfs for installed kernels in chroot + +The postinst script from kdump-tools creates an initramfs for the +running kernel. When running inside a chroot, the running kernel (from +the host) might differ from the kernels that are available in the +chroot. + +Thus generate the initramfs only when the running kernel is installed in +the system. Otherwise generate the initramfs for all installed kernels. + +Bug-Debian: #856594 +--- + debian/kdump-tools.postinst | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/debian/kdump-tools.postinst b/debian/kdump-tools.postinst +index 4b6c6be..f604c8e 100755 +--- a/debian/kdump-tools.postinst ++++ b/debian/kdump-tools.postinst +@@ -33,7 +33,15 @@ update_param() { + case "$1" in + configure) + # create smaller initrd.img files for kdump use +- /etc/kernel/postinst.d/kdump-tools $(uname -r) > /dev/null 2>&1 ++ if test -d /lib/modules/$(uname -r); then ++ /etc/kernel/postinst.d/kdump-tools $(uname -r) > /dev/null 2>&1 ++ else ++ # Running kernel not installed. Running in chroot? ++ for kernel_release in $(ls /lib/modules/); do ++ /etc/kernel/postinst.d/kdump-tools $kernel_release > /dev/null 2>&1 ++ kdump-config symlinks $kernel_release ++ done ++ fi + + # Customize crashkernel= value according to architecture + ARCH="$(arch)" +-- +2.9.3 diff --git a/src/kdump-tools/patch/0002-core-file-prefixed-by-kdump.patch b/src/kdump-tools/patch/0002-core-file-prefixed-by-kdump.patch new file mode 100644 index 000000000000..2ed480b26175 --- /dev/null +++ b/src/kdump-tools/patch/0002-core-file-prefixed-by-kdump.patch @@ -0,0 +1,24 @@ +--- a/debian/kdump-config.orig 2019-10-24 09:38:19.006679000 -0700 ++++ b/debian/kdump-config 2019-10-24 12:16:23.791899000 -0700 +@@ -639,8 +639,8 @@ + { + KDUMP_STAMP=`date +"%Y%m%d%H%M"` + KDUMP_STAMPDIR=$(define_stampdir $KDUMP_STAMP) +- KDUMP_CORETEMP="$KDUMP_STAMPDIR/dump-incomplete" +- KDUMP_COREFILE="$KDUMP_STAMPDIR/dump.$KDUMP_STAMP" ++ KDUMP_CORETEMP="$KDUMP_STAMPDIR/kdump-incomplete" ++ KDUMP_COREFILE="$KDUMP_STAMPDIR/kdump.$KDUMP_STAMP" + KDUMP_DMESGFILE="$KDUMP_STAMPDIR/dmesg.$KDUMP_STAMP" + + # If we use NFS, verify that we can mount the FS +@@ -755,8 +755,8 @@ + KDUMP_STAMP=`date +"%Y%m%d%H%M"` + KDUMP_STAMPDIR=$(define_stampdir $KDUMP_STAMP) + +- KDUMP_CORETEMP="$KDUMP_STAMPDIR/dump-incomplete" +- KDUMP_COREFILE="$KDUMP_STAMPDIR/dump.$KDUMP_STAMP" ++ KDUMP_CORETEMP="$KDUMP_STAMPDIR/kdump-incomplete" ++ KDUMP_COREFILE="$KDUMP_STAMPDIR/kdump.$KDUMP_STAMP" + KDUMP_TMPDMESG="/tmp/dmesg.$KDUMP_STAMP" + KDUMP_DMESGFILE="$KDUMP_STAMPDIR/dmesg.$KDUMP_STAMP" + ERROR=0 diff --git a/src/kdump-tools/patch/series b/src/kdump-tools/patch/series new file mode 100644 index 000000000000..e1a26e55ca1b --- /dev/null +++ b/src/kdump-tools/patch/series @@ -0,0 +1,2 @@ +0001-Generate-initramfs-for-installed-kernels-in-chroot.patch +0002-core-file-prefixed-by-kdump.patch From fd8232817f27304c4b2a13f3f3588a60af80b4dc Mon Sep 17 00:00:00 2001 From: sandeep-kulambi <50737942+sandeep-kulambi@users.noreply.github.com> Date: Sat, 9 Nov 2019 12:40:12 +0530 Subject: [PATCH 0148/1427] [lldp]: ensure the LLDP PDU is sent immediately when the tx-interval is modified. (#3705) When LLDP parameter tx-interval value is modified, there was no immediate PDU sent to peer to update the peer with the latest values. Due to this the update on peer happened only after the next PDU is sent which can cause a delay of upto 30 secs (default value). --- .../0003-update-tx-interval-immediately.patch | 20 +++++++++++++++++++ src/lldpd/patch/series | 1 + 2 files changed, 21 insertions(+) create mode 100644 src/lldpd/patch/0003-update-tx-interval-immediately.patch diff --git a/src/lldpd/patch/0003-update-tx-interval-immediately.patch b/src/lldpd/patch/0003-update-tx-interval-immediately.patch new file mode 100644 index 000000000000..b6b295001288 --- /dev/null +++ b/src/lldpd/patch/0003-update-tx-interval-immediately.patch @@ -0,0 +1,20 @@ +diff --git a/src/daemon/client.c b/src/daemon/client.c +index 8382d02..38cf3f3 100644 +--- a/src/daemon/client.c ++++ b/src/daemon/client.c +@@ -71,7 +71,6 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, + if (CHANGED(c_tx_interval) && config->c_tx_interval != 0) { + if (config->c_tx_interval < 0) { + log_debug("rpc", "client asked for immediate retransmission"); +- levent_send_now(cfg); + } else { + log_debug("rpc", "client change transmit interval to %d", + config->c_tx_interval); +@@ -79,6 +78,7 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, + LOCAL_CHASSIS(cfg)->c_ttl = cfg->g_config.c_tx_interval * + cfg->g_config.c_tx_hold; + } ++ levent_send_now(cfg); + } + if (CHANGED(c_tx_hold) && config->c_tx_hold > 0) { + log_debug("rpc", "client change transmit hold to %d", diff --git a/src/lldpd/patch/series b/src/lldpd/patch/series index 2ca46b575396..5e5e8bc99714 100644 --- a/src/lldpd/patch/series +++ b/src/lldpd/patch/series @@ -1,3 +1,4 @@ # This series applies on GIT commit 396961a038a38675d46f96eaa7b430b2a1f8701b 0001-return-error-when-port-does-not-exist.patch 0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch +0003-update-tx-interval-immediately.patch From 099f9b0a6ac0e7795516bdbb0791abae2161158c Mon Sep 17 00:00:00 2001 From: CharlieChenEC <49221644+CharlieChenEC@users.noreply.github.com> Date: Sun, 10 Nov 2019 02:23:18 +0800 Subject: [PATCH 0149/1427] [devices]:start opennsl modules after platform handle mac service on AS7326-56X/AS7726-56X (#3726) AS7326-56X and AS7726-56X use the same design so both devices have the same problem. The detailed description below takes AS7326-56X as the example to explain. Original implementation: - In platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-handle_mac.service, it executes the script file "accton_handle_idt.sh". - In "accton_handle_idt.sh", it modifies the content of the script file "/etc/init.d/opennsl-modules" to insert the lines to execute "idt_init.sh" before the command to load broadcom linux kernel module "linux-kernel-bde.ko". - The script "idt_init.sh" cannot be executed at the first boot of SONiC after installing SONiC under ONIE. This is the reason why all of the ports does not work. New implementation: - Let "as7326-platform-handle_mac.service" execute "idt_init.sh". - Change the content of "as7326-platform-handle_mac.service" to define the service type as "oneshot". Add the settings to ensure "as7326-platform-handle_mac.service" is executed before "opennsl-modules.service". By setting the service type as "oneshot", it is guaranteed that "opennsl-modules.services" is started only when the forked process to execute the script file "idt_init.sh" is terminated Signed-off-by: charlie_chen --- .../service/as7326-platform-handle_mac.service | 15 +++++++-------- .../as7726-32x-platform-handle_mac.service | 15 +++++++-------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-handle_mac.service b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-handle_mac.service index 0e35d5929ef9..3d03ec4f1540 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-handle_mac.service +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-handle_mac.service @@ -1,16 +1,15 @@ [Unit] -Description=Accton AS7326-56X Platform MAC hnadle service -Before=pmon.service -After=sysinit.target -DefaultDependencies=no +Description=Accton AS7326-56X Platform MAC handle service +Before=opennsl-modules.service +After=local-fs.target [Service] -ExecStart=/usr/local/bin/accton_handle_idt.sh -KillSignal=SIGKILL -SuccessExitStatus=SIGKILL +Type=oneshot +ExecStart=/usr/local/bin/idt_init.sh +RemainAfterExit=yes # Resource Limitations LimitCORE=infinity [Install] -WantedBy=multi-user.target +WantedBy=opennsl-modules.service diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-handle_mac.service b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-handle_mac.service index d29342a56fe1..5492775eee62 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-handle_mac.service +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-handle_mac.service @@ -1,16 +1,15 @@ [Unit] -Description=Accton AS7726-32X Platform MAC hnadle service -Before=pmon.service -After=sysinit.target -DefaultDependencies=no +Description=Accton AS7726-32X Platform MAC handle service +Before=opennsl-modules.service +After=local-fs.target [Service] -ExecStart=/usr/local/bin/accton_handle_idt.sh -KillSignal=SIGKILL -SuccessExitStatus=SIGKILL +Type=oneshot +ExecStart=/usr/local/bin/idt_init.sh +RemainAfterExit=yes # Resource Limitations LimitCORE=infinity [Install] -WantedBy=multi-user.target +WantedBy=opennsl-modules.service From 85b0de3df1125ad291afe0c7c93628dd45f226db Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 9 Nov 2019 10:26:39 -0800 Subject: [PATCH 0150/1427] [docker-syncd]: Restart SwSS, syncd and dependent services if a critical process in syncd container exits unexpectedly (#3534) Add the same mechanism I developed for the SwSS service in #2845 to the syncd service. However, in order to cause the SwSS service to also exit and restart in this situation, I developed a docker-wait-any program which the SwSS service uses to wait for either the swss or syncd containers to exit. --- .../build_templates/sonic_debian_extension.j2 | 3 + files/image_config/misc/docker-wait-any | 62 +++++++++++++++++++ files/scripts/swss.sh | 17 ++++- platform/barefoot/docker-syncd-bfn-rpc.mk | 1 + .../barefoot/docker-syncd-bfn/Dockerfile.j2 | 2 + .../docker-syncd-bfn/critical_processes | 1 + platform/broadcom/docker-syncd-brcm-rpc.mk | 2 +- .../broadcom/docker-syncd-brcm/Dockerfile.j2 | 2 + .../docker-syncd-brcm/critical_processes | 2 + .../docker-syncd-brcm/supervisord.conf | 8 ++- platform/cavium/docker-syncd-cavm-rpc.mk | 1 + platform/cavium/docker-syncd-cavm.mk | 1 + .../cavium/docker-syncd-cavm/Dockerfile.j2 | 2 + .../docker-syncd-cavm/critical_processes | 1 + .../cavium/docker-syncd-cavm/supervisord.conf | 8 ++- platform/centec/docker-syncd-centec-rpc.mk | 1 + platform/centec/docker-syncd-centec.mk | 1 + .../centec/docker-syncd-centec/Dockerfile.j2 | 2 + .../docker-syncd-centec/critical_processes | 1 + .../docker-syncd-centec/supervisord.conf | 8 ++- .../marvell-arm64/docker-syncd-mrvl-rpc.mk | 1 + .../docker-syncd-mrvl/Dockerfile.j2 | 2 + .../docker-syncd-mrvl/critical_processes | 1 + .../marvell-armhf/docker-syncd-mrvl-rpc.mk | 1 + .../docker-syncd-mrvl/Dockerfile.j2 | 2 + .../docker-syncd-mrvl/critical_processes | 1 + platform/marvell/docker-syncd-mrvl-rpc.mk | 1 + .../marvell/docker-syncd-mrvl/Dockerfile.j2 | 2 + .../docker-syncd-mrvl/critical_processes | 1 + .../docker-syncd-mrvl/supervisord.conf | 8 ++- platform/mellanox/docker-syncd-mlnx-rpc.mk | 1 + .../mellanox/docker-syncd-mlnx/Dockerfile.j2 | 2 + .../docker-syncd-mlnx/critical_processes | 1 + .../docker-syncd-mlnx/supervisord.conf | 8 ++- .../nephos/docker-syncd-nephos/Dockerfile.j2 | 2 + .../docker-syncd-nephos/critical_processes | 2 + .../docker-syncd-nephos/supervisord.conf | 8 ++- platform/template/docker-syncd-base.mk | 2 + 38 files changed, 164 insertions(+), 8 deletions(-) create mode 100755 files/image_config/misc/docker-wait-any create mode 100644 platform/barefoot/docker-syncd-bfn/critical_processes create mode 100644 platform/broadcom/docker-syncd-brcm/critical_processes create mode 100644 platform/cavium/docker-syncd-cavm/critical_processes create mode 100644 platform/centec/docker-syncd-centec/critical_processes create mode 100644 platform/marvell-arm64/docker-syncd-mrvl/critical_processes create mode 100644 platform/marvell-armhf/docker-syncd-mrvl/critical_processes create mode 100644 platform/marvell/docker-syncd-mrvl/critical_processes create mode 100644 platform/mellanox/docker-syncd-mlnx/critical_processes create mode 100644 platform/nephos/docker-syncd-nephos/critical_processes diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index d81815284a34..13d5432e09ea 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -218,6 +218,9 @@ sudo cp $IMAGE_CONFIGS/hostname/hostname-config.service $FILESYSTEM_ROOT/etc/sy echo "hostname-config.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/ +# Copy miscellaneous scripts +sudo cp $IMAGE_CONFIGS/misc/docker-wait-any $FILESYSTEM_ROOT/usr/bin/ + # Copy updategraph script and service file j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/updategraph.service sudo cp $IMAGE_CONFIGS/updategraph/updategraph $FILESYSTEM_ROOT/usr/bin/ diff --git a/files/image_config/misc/docker-wait-any b/files/image_config/misc/docker-wait-any new file mode 100755 index 000000000000..3988a9fbdf57 --- /dev/null +++ b/files/image_config/misc/docker-wait-any @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +""" + docker-wait-any + This script takes one or more Docker container names as arguments, + and it will block indefinitely while all of the specified containers + are running. If any of the specified containers stop, the script will + exit. + This script was created because the 'docker wait' command is lacking + this functionality. It will block until ALL specified containers have + stopped running. Here, we spawn multiple threads and wait on one + container per thread. If any of the threads exit, the entire + application will exit. + NOTE: This script is written against docker-py version 1.6.0. Newer + versions of docker-py have a different API. +""" + +import sys +import threading +from docker import Client + +# Instantiate a global event to share among our threads +g_thread_exit_event = threading.Event() + + +def usage(): + print("Usage: {} [ ...]".format(sys.argv[0])) + sys.exit(1) + + +def wait_for_container(docker_client, container_name): + docker_client.wait(container_name) + + print("No longer waiting on container '{}'".format(container_name)) + + # Signal the main thread to exit + g_thread_exit_event.set() + + +def main(): + thread_list = [] + + docker_client = Client(base_url='unix://var/run/docker.sock') + + # Ensure we were passed at least one argument + if len(sys.argv) < 2: + usage() + + container_names = sys.argv[1:] + + for container_name in container_names: + t = threading.Thread(target=wait_for_container, args=[docker_client, container_name]) + t.daemon = True + t.start() + thread_list.append(t) + + # Wait until we receive an event signifying one of the containers has stopped + g_thread_exit_event.wait() + sys.exit(0) + +if __name__ == '__main__': + main() diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 5b2f582ef4c4..65eaf08148a8 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -131,7 +131,22 @@ start() { wait() { start_peer_and_dependent_services - /usr/bin/${SERVICE}.sh wait + + # Allow some time for peer container to start + # NOTE: This assumes Docker containers share the same names as their + # corresponding services + for SECS in {1..60}; do + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) + if [[ x"$RUNNING" == x"true" ]]; then + break + else + sleep 1 + fi + done + + # NOTE: This assumes Docker containers share the same names as their + # corresponding services + /usr/bin/docker-wait-any ${SERVICE} ${PEER} } stop() { diff --git a/platform/barefoot/docker-syncd-bfn-rpc.mk b/platform/barefoot/docker-syncd-bfn-rpc.mk index 4fbe4eb1721c..d9cb0b5d6172 100644 --- a/platform/barefoot/docker-syncd-bfn-rpc.mk +++ b/platform/barefoot/docker-syncd-bfn-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_BFN_RPC = docker-syncd-bfn-rpc.gz $(DOCKER_SYNCD_BFN_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-bfn-rpc $(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_BFN_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 index 73a12b8a05cc..c12c36b1260b 100755 --- a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 @@ -29,6 +29,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/barefoot/docker-syncd-bfn/critical_processes b/platform/barefoot/docker-syncd-bfn/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/broadcom/docker-syncd-brcm-rpc.mk b/platform/broadcom/docker-syncd-brcm-rpc.mk index ed7fc1b5265e..80d6ea2d8147 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc.mk +++ b/platform/broadcom/docker-syncd-brcm-rpc.mk @@ -9,7 +9,7 @@ $(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) endif -$(DOCKER_SYNCD_BRCM_RPC)_FILES += $(DSSERVE) $(BCMCMD) +$(DOCKER_SYNCD_BRCM_RPC)_FILES += $(DSSERVE) $(BCMCMD) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_BRCM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM_RPC) SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BRCM_RPC) diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index 328f698fdb6d..b20e353f842f 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -26,6 +26,8 @@ COPY ["files/dsserve", "files/bcmcmd", "start.sh", "bcmsh", "/usr/bin/"] RUN chmod +x /usr/bin/dsserve /usr/bin/bcmcmd COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/broadcom/docker-syncd-brcm/critical_processes b/platform/broadcom/docker-syncd-brcm/critical_processes new file mode 100644 index 000000000000..489668a89e08 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/critical_processes @@ -0,0 +1,2 @@ +dsserve +syncd diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index a2e0743b1cf5..cd6712acbf22 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/cavium/docker-syncd-cavm-rpc.mk b/platform/cavium/docker-syncd-cavm-rpc.mk index cb1077c5a391..e57370fce5ca 100644 --- a/platform/cavium/docker-syncd-cavm-rpc.mk +++ b/platform/cavium/docker-syncd-cavm-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CAVM_RPC = docker-syncd-cavm-rpc.gz $(DOCKER_SYNCD_CAVM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm-rpc $(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) +$(DOCKER_SYNCD_CAVM_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/cavium/docker-syncd-cavm.mk b/platform/cavium/docker-syncd-cavm.mk index 5cec8390593f..a136828dbff1 100644 --- a/platform/cavium/docker-syncd-cavm.mk +++ b/platform/cavium/docker-syncd-cavm.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CAVM = docker-syncd-cavm.gz $(DOCKER_SYNCD_CAVM)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm $(DOCKER_SYNCD_CAVM)_DEPENDS += $(SYNCD) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) +$(DOCKER_SYNCD_CAVM)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CAVM)_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 index 800be7e1bb04..0e2bc4b6bbc7 100755 --- a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 +++ b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 @@ -23,6 +23,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] COPY ["profile.ini", "/etc/ssw/AS7512/"] diff --git a/platform/cavium/docker-syncd-cavm/critical_processes b/platform/cavium/docker-syncd-cavm/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/cavium/docker-syncd-cavm/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/cavium/docker-syncd-cavm/supervisord.conf b/platform/cavium/docker-syncd-cavm/supervisord.conf index 1af5d70a1d0c..c823ab5680ef 100644 --- a/platform/cavium/docker-syncd-cavm/supervisord.conf +++ b/platform/cavium/docker-syncd-cavm/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/centec/docker-syncd-centec-rpc.mk b/platform/centec/docker-syncd-centec-rpc.mk index 744f60a71ff1..71c8ef7753c1 100644 --- a/platform/centec/docker-syncd-centec-rpc.mk +++ b/platform/centec/docker-syncd-centec-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CENTEC_RPC = docker-syncd-centec-rpc.gz $(DOCKER_SYNCD_CENTEC_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec-rpc $(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_CENTEC_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/centec/docker-syncd-centec.mk b/platform/centec/docker-syncd-centec.mk index 7447dd54717b..360690731a58 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CENTEC = docker-syncd-centec.gz $(DOCKER_SYNCD_CENTEC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec $(DOCKER_SYNCD_CENTEC)_DEPENDS += $(SYNCD) +$(DOCKER_SYNCD_CENTEC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CENTEC)_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/centec/docker-syncd-centec/Dockerfile.j2 b/platform/centec/docker-syncd-centec/Dockerfile.j2 index d5b9bc73eeca..b40103a24f28 100755 --- a/platform/centec/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec/Dockerfile.j2 @@ -24,6 +24,8 @@ RUN apt-get install -f kmod COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/centec/docker-syncd-centec/critical_processes b/platform/centec/docker-syncd-centec/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/centec/docker-syncd-centec/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/centec/docker-syncd-centec/supervisord.conf b/platform/centec/docker-syncd-centec/supervisord.conf index 1af5d70a1d0c..c823ab5680ef 100644 --- a/platform/centec/docker-syncd-centec/supervisord.conf +++ b/platform/centec/docker-syncd-centec/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk b/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk index f5eb6d2de272..0e1b65f2fd5d 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 index 201d52284361..410911e6a4f8 100755 --- a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 @@ -28,6 +28,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/marvell-arm64/docker-syncd-mrvl/critical_processes b/platform/marvell-arm64/docker-syncd-mrvl/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/marvell-arm64/docker-syncd-mrvl/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk b/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk index f5eb6d2de272..0e1b65f2fd5d 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 index 201d52284361..410911e6a4f8 100755 --- a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 @@ -28,6 +28,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/marvell-armhf/docker-syncd-mrvl/critical_processes b/platform/marvell-armhf/docker-syncd-mrvl/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/marvell-armhf/docker-syncd-mrvl/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/marvell/docker-syncd-mrvl-rpc.mk b/platform/marvell/docker-syncd-mrvl-rpc.mk index 375c6ba91cd1..5b1968bde39c 100644 --- a/platform/marvell/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell/docker-syncd-mrvl-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 index 889971652c61..40973653e8d3 100755 --- a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 @@ -23,6 +23,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "syncd.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/marvell/docker-syncd-mrvl/critical_processes b/platform/marvell/docker-syncd-mrvl/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/marvell/docker-syncd-mrvl/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/marvell/docker-syncd-mrvl/supervisord.conf b/platform/marvell/docker-syncd-mrvl/supervisord.conf index 1e015fef931f..aea4d45b9afd 100644 --- a/platform/marvell/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell/docker-syncd-mrvl/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.mk b/platform/mellanox/docker-syncd-mlnx-rpc.mk index f154f8c28d2e..608c1bb3ad20 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc.mk +++ b/platform/mellanox/docker-syncd-mlnx-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_MLNX_RPC = docker-syncd-mlnx-rpc.gz $(DOCKER_SYNCD_MLNX_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mlnx-rpc $(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MLNX_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index d3716dffcbbc..4d22335ec783 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -35,5 +35,7 @@ RUN apt-get clean -y && \ COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/platform/mellanox/docker-syncd-mlnx/critical_processes b/platform/mellanox/docker-syncd-mlnx/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/mellanox/docker-syncd-mlnx/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/mellanox/docker-syncd-mlnx/supervisord.conf b/platform/mellanox/docker-syncd-mlnx/supervisord.conf index 1af5d70a1d0c..c823ab5680ef 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 index b889200f6ca4..f891ace1e8e4 100755 --- a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 @@ -36,6 +36,8 @@ COPY ["files/dsserve", "files/npx_diag", "start.sh", "/usr/bin/"] RUN chmod +x /usr/bin/npx_diag /usr/bin/dsserve COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/nephos/docker-syncd-nephos/critical_processes b/platform/nephos/docker-syncd-nephos/critical_processes new file mode 100644 index 000000000000..489668a89e08 --- /dev/null +++ b/platform/nephos/docker-syncd-nephos/critical_processes @@ -0,0 +1,2 @@ +dsserve +syncd diff --git a/platform/nephos/docker-syncd-nephos/supervisord.conf b/platform/nephos/docker-syncd-nephos/supervisord.conf index 1af5d70a1d0c..c823ab5680ef 100644 --- a/platform/nephos/docker-syncd-nephos/supervisord.conf +++ b/platform/nephos/docker-syncd-nephos/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/template/docker-syncd-base.mk b/platform/template/docker-syncd-base.mk index d8776d179a02..cefcf15ebd62 100644 --- a/platform/template/docker-syncd-base.mk +++ b/platform/template/docker-syncd-base.mk @@ -7,6 +7,8 @@ DOCKER_SYNCD_BASE_DBG = $(DOCKER_SYNCD_BASE_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_SYNCD_BASE)_PATH = $(PLATFORM_PATH)/docker-syncd-$(DOCKER_SYNCD_PLATFORM_CODE) +$(DOCKER_SYNCD_BASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) + $(DOCKER_SYNCD_BASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) From 6e926a184206d4a7f2490e87eab9f6dc1c3ec9c6 Mon Sep 17 00:00:00 2001 From: dereksun01 <52683998+dereksun01@users.noreply.github.com> Date: Sun, 10 Nov 2019 06:16:16 +0800 Subject: [PATCH 0151/1427] [device]: rename as5835_54x configuration file (#3429) Signed-off-by: derek_sun --- ...0G+6x100G.config.bcm => mv2-as5835-48x10G+6x100G.config.bcm} | 0 .../x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/{td3-as5835-48x10G+6x100G.config.bcm => mv2-as5835-48x10G+6x100G.config.bcm} (100%) diff --git a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/td3-as5835-48x10G+6x100G.config.bcm b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/mv2-as5835-48x10G+6x100G.config.bcm similarity index 100% rename from device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/td3-as5835-48x10G+6x100G.config.bcm rename to device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/mv2-as5835-48x10G+6x100G.config.bcm diff --git a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile index 04c02ee5861d..8b795f81c4f2 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile +++ b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as5835-48x10G+6x100G.config.bcm +SAI_INIT_CONFIG_FILE=/etc/bcm/mv2-as5835-48x10G+6x100G.config.bcm From d8931db996309fec1a32c075cc0b3f591d20d78a Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 9 Nov 2019 19:32:10 +0000 Subject: [PATCH 0152/1427] [submodules]: update swss/sairedis/utilities swss: * f354798 2019-11-09 | [tests] fix build agains real SAI (#1123) (HEAD, origin/master, origin/HEAD) [Stepan Blyshchak] * 56d66a1 2019-11-07 | Sub port interface implementation (#969) [Wenda Ni] * c57fc34 2019-11-07 | [bufferorch] Fixed buffer and buffer profile attributes types accoring to changes in SAI 1.5 (#1120) [Vitaliy Senchyshyn] * 85ff17d 2019-11-07 | [VRF]: submit vrf feature (#943) [Tyler Li] * 5604566 2019-11-06 | [vs_test] fix fdb test failed randomly (#1118) [Tyler Li] * 038d994 2019-11-05 | [vnet]: Correct VNET route table size for BITMAP implementation (#1115) [Volodymyr Samotiy] * bb4e19c 2019-11-04 | Not wait till kernel net_devices are created for all physical ports to (#1109) [Wenda Ni] * bab7b93 2019-11-02 | [portsorch] fix PortsOrch::allPortsReady() returns true when it should not (#1103) [Stepan Blyshchak] * 5ab3f6b 2019-10-31 | Updating pytest for sflow (#1095) [Sudharsan D.G] * d4ccdc3 2019-10-29 | Quote input strings before constructing a command line (#1098) [Qi Luo] * 5516ec4 2019-10-29 | Check RIF/Port exists only for add entries (#1110) [Prince Sunny] * 59440f2 2019-10-29 | Allow buffer profile apply after init (#1099) [Wenda Ni] sairedis: * d9faa58 2019-10-24 | Copp changes for supporting genetlink in vs (#522) [Sudharsan D.G] utiltiies: * e4a5e4c 2019-11-07 | Do not start pfcwd for M0 devices (#726) (HEAD, origin/master, origin/HEAD) [Neetha John] * 2c0af8a 2019-11-07 | Add an on/off knob for BGP EOIU pulling on warm restart (#655) [heidinet2007] * 2bce9ce 2019-11-07 | Make configlet application script idempotent for updates. (#728) [Renuka Manavalan] * 4740617 2019-11-06 | Revert "show BPS, PPS, UTIL rates w/o previous clear (#508)" (#718) [Mykola F] --- src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- src/sonic-utilities | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 1f4a1d76bd9c..d9faa5890b68 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 1f4a1d76bd9cd3e8865911840ab8e47c0ba221f1 +Subproject commit d9faa5890b6843a6a31e620752e865eba23f9564 diff --git a/src/sonic-swss b/src/sonic-swss index 20747fa63d59..f3547983a1e2 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 20747fa63d59f4aadaa06da282e23d8e1e0b9fdf +Subproject commit f3547983a1e2c67bdacb4e87593e65f20b483d8e diff --git a/src/sonic-utilities b/src/sonic-utilities index 0e23e1cd0a3b..e4a5e4ce1c3f 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 0e23e1cd0a3b3538061c8f971acd579bf2a9e151 +Subproject commit e4a5e4ce1c3f55600ca3e6bcbffbd4bcaef4cbe6 From c07ae3b16f379a0649ca091fa8194976a976b8c7 Mon Sep 17 00:00:00 2001 From: Tyler Li Date: Sat, 9 Nov 2019 21:51:43 +0000 Subject: [PATCH 0153/1427] Loopback ip addresses move to intfmgrd for supporting VRF --- files/image_config/interfaces/interfaces.j2 | 7 ------- .../tests/sample_output/interfaces | 13 ------------- .../tests/sample_output/mvrf_interfaces | 13 ------------- 3 files changed, 33 deletions(-) diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index ad7b5202637d..91be4437fc06 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -14,13 +14,6 @@ iface mgmt # The loopback network interface auto lo iface lo inet loopback -# Use command 'ip addr list dev lo' to check all addresses -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -iface lo {{ 'inet' if prefix | ipv4 else 'inet6' }} static - address {{ prefix | ip }} - netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }} -# -{% endfor %} {% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} # The loopback network interface for mgmt VRF that is required for applications like NTP up ip link add lo-m type dummy diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index 2c4c01b7b9b1..d3921bcbab4d 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -6,19 +6,6 @@ # The loopback network interface auto lo iface lo inet loopback -# Use command 'ip addr list dev lo' to check all addresses -iface lo inet static - address 10.1.0.32 - netmask 255.255.255.255 -# -iface lo inet6 static - address fc00:1::32 - netmask 128 -# -iface lo inet static - address 10.10.0.99 - netmask 255.255.255.255 -# # The management network interface auto eth0 diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces index e66b1b252835..afd0615b81e9 100644 --- a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces @@ -9,19 +9,6 @@ iface mgmt # The loopback network interface auto lo iface lo inet loopback -# Use command 'ip addr list dev lo' to check all addresses -iface lo inet static - address 10.1.0.32 - netmask 255.255.255.255 -# -iface lo inet6 static - address fc00:1::32 - netmask 128 -# -iface lo inet static - address 10.10.0.99 - netmask 255.255.255.255 -# # The loopback network interface for mgmt VRF that is required for applications like NTP up ip link add lo-m type dummy up ip addr add 127.0.0.1/8 dev lo-m From 473fc6d4f37f89bc30ab2b66182f0e3386cf2e73 Mon Sep 17 00:00:00 2001 From: "Dante (Kuo-Jung) Su" Date: Wed, 13 Nov 2019 07:26:11 +0800 Subject: [PATCH 0154/1427] celestica: reallocate the empty LIST at the constructor of subclasses (#3738) Signed-off-by: Dante Su --- device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py | 2 +- .../celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py | 2 +- device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py index 291ece986222..99eb49ce53e0 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py @@ -42,6 +42,7 @@ class Chassis(ChassisBase): """Platform-specific Chassis class""" def __init__(self): + ChassisBase.__init__(self) self.config_data = {} for fant_index in range(0, NUM_FAN_TRAY): for fan_index in range(0, NUM_FAN): @@ -59,7 +60,6 @@ def __init__(self): for index in range(0, NUM_COMPONENT): component = Component(index) self._component_list.append(component) - ChassisBase.__init__(self) self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self.__is_host( ) else PMON_REBOOT_CAUSE_PATH diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index 768a15ce22ef..c9447b56a2fe 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -44,6 +44,7 @@ class Chassis(ChassisBase): """Platform-specific Chassis class""" def __init__(self): + ChassisBase.__init__(self) self.config_data = {} for fant_index in range(0, NUM_FAN_TRAY): for fan_index in range(0, NUM_FAN): @@ -61,7 +62,6 @@ def __init__(self): for index in range(0, NUM_COMPONENT): component = Component(index) self._component_list.append(component) - ChassisBase.__init__(self) self._watchdog = Watchdog() self._eeprom = Tlv() diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py index 7e18827cbfb0..8558b0b0cadd 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py @@ -39,6 +39,7 @@ class Psu(PsuBase): """Platform-specific Psu class""" def __init__(self, psu_index): + PsuBase.__init__(self) self.index = psu_index self.green_led_path = GREEN_LED_PATH.format(self.index+1) self.dx010_psu_gpio = [ @@ -52,7 +53,6 @@ def __init__(self, psu_index): for fan_index in range(0, PSU_NUM_FAN[self.index]): fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index) self._fan_list.append(fan) - PsuBase.__init__(self) def __read_txt_file(self, file_path): try: From 64c43f767a7b3d8e6af1549396df797c36302bc0 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 11 Nov 2019 20:19:23 +0000 Subject: [PATCH 0155/1427] [submodule]: update sonic-sairedis * afe2a0d 2019-10-30 | [vs]: Fix learn fdb events after fdb flush event (#524) (HEAD, origin/master, origin/HEAD) [Kamil Cudnik] * d29760f 2019-10-28 | [sai_redis_interface_query] Add sairedis support for sai_object_type_get_availability (#528) [Danny Allen] * ff5306e 2019-10-28 | [sai_redis_interface_query] Add sairedis support for sai_query_attribute_enum_values_capability (#525) [Danny Allen] Signed-off-by: Guohan Lu --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index d9faa5890b68..afe2a0d29299 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit d9faa5890b6843a6a31e620752e865eba23f9564 +Subproject commit afe2a0d29299128d314b93c9e4726e62d3116948 From 5174ec89239bfc42c1d1bc851572d244eea84c56 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Tue, 12 Nov 2019 12:15:45 -0800 Subject: [PATCH 0156/1427] [bcm SAI] Upgrade Broadcom SAI to version 3.5.3.1m-26 (#50) Signed-off-by: Danny Allen --- platform/broadcom/sai.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 6ef784e21ced..833c22f6bb94 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ BRCM_SAI = libsaibcm_3.5.3.1m-25_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.3.1m-25_amd64.deb?sv=2015-04-05&sr=b&sig=kLfhfLeBmENmTXVa%2BZ90k2Fq8ZOQ84kxn5%2FzY3KLV2s%3D&se=2033-06-17T23%3A45%3A50Z&sp=r" +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=zo83IKnlT7goymXwynW8%2Fx6rR2eIh0AiIS%2BSrSMUhRE%3D&se=2033-07-21T18%3A50%3A27Z&sp=r" BRCM_SAI_DEV = libsaibcm-dev_3.5.3.1m-25_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm-dev_3.5.3.1m-25_amd64.deb?sv=2015-04-05&sr=b&sig=a%2BvxIrNcVwnp0CBXS%2BTGiGl%2F%2Fl8mo9ZKPkZyroPY0bI%3D&se=2033-06-17T23%3A45%3A21Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm-dev_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=tQmkCIy2mnb9rH7B9oXFUZDwijMGXWnVtta2CNTMbFM%3D&se=2033-07-21T18%3A50%3A47Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 73721223cd92679cb730830322e27c043b1ba5d9 Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Wed, 13 Nov 2019 22:36:45 +0530 Subject: [PATCH 0157/1427] [Juniper][QFX5210] Updating platform README (#3746) * Updating the platform README Added the steps for configuring FEC mode Signed-off-by: Ciju Rajan K --- .../sonic-platform-modules-juniper/qfx5210/utils/README | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README index a69ac017c6f2..ec9ebe97f0ee 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README @@ -64,8 +64,10 @@ SFPs There are 64 QSFP+ modules supported in qfx5210 platform. EEPORMs will be mapped under /sys/bus/i2c/devices/[25-88]-0050/ sysfs directory. -FEC should be turned on for SR4 optics and should be turned off for LR4 -optics. +FEC should be turned on for 100G SR optics and should be turned off for +100G LR optics. If the optic is changed, please update the entry and +reload the configuration. If the FEC mode is not set as per the optic +type the port may not link up or work properly. As an example, see this configuration for FEC for 100G SR4 optics in /etc/sonic/config_db.json From 864a7c60bd9cbd5d6a03dab4e33fb9577787dc08 Mon Sep 17 00:00:00 2001 From: heidinet2007 <43017482+heidinet2007@users.noreply.github.com> Date: Wed, 13 Nov 2019 14:10:11 -0800 Subject: [PATCH 0158/1427] start bgp_eoiu_mark service to populate bgp eoiu marker flags for warm start, if configured so (#3489) * start bgp_eoiu_mark service to populate bgp eoiu marker if configured so * Address code review comments: check db value via "-v" option in sonic-cfggen * Address code review comment 2: check string against 'true' directly, instead of couting * Update start.sh --- dockers/docker-fpm-frr/start.sh | 7 +++++++ dockers/docker-fpm-frr/supervisord.conf | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/start.sh index ad9beec766d3..80f9c69ec989 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/start.sh @@ -33,6 +33,13 @@ rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd +# start eoiu pulling, only if configured so +if [[ $(sonic-cfggen -d -v 'WARM_RESTART.bgp.bgp_eoiu') == 'true' ]]; then + supervisorctl start bgp_eoiu_marker +fi + +supervisorctl start bgpcfgd + # Start Quagga processes supervisorctl start zebra supervisorctl start staticd diff --git a/dockers/docker-fpm-frr/supervisord.conf b/dockers/docker-fpm-frr/supervisord.conf index ba9f38507b80..fe0ce6eda1a4 100644 --- a/dockers/docker-fpm-frr/supervisord.conf +++ b/dockers/docker-fpm-frr/supervisord.conf @@ -75,3 +75,13 @@ autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog + +[program:bgp_eoiu_marker] +command=/usr/bin/bgp_eoiu_marker.py +priority=7 +autostart=false +autorestart=false +startsecs=0 +startretries=0 +stdout_logfile=syslog +stderr_logfile=syslog From f5f45f8b6b57f95c7c3635f028cf2725e014bec8 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Wed, 13 Nov 2019 14:33:35 -0800 Subject: [PATCH 0159/1427] [Submodule] Update sonic-utilities (#3750) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index e4a5e4ce1c3f..fe4446a4808b 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit e4a5e4ce1c3f55600ca3e6bcbffbd4bcaef4cbe6 +Subproject commit fe4446a4808bc98ca2b24b0a9afe822aaa50a7ce From f9dea23191e199b75bcc498c7b2f642c1c8ae610 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 13 Nov 2019 16:41:41 -0800 Subject: [PATCH 0160/1427] Don't run bgpcfgd twice (#3752) --- dockers/docker-fpm-frr/start.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/start.sh index 80f9c69ec989..b3cef5e63244 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/start.sh @@ -35,11 +35,9 @@ supervisorctl start rsyslogd # start eoiu pulling, only if configured so if [[ $(sonic-cfggen -d -v 'WARM_RESTART.bgp.bgp_eoiu') == 'true' ]]; then - supervisorctl start bgp_eoiu_marker + supervisorctl start bgp_eoiu_marker fi -supervisorctl start bgpcfgd - # Start Quagga processes supervisorctl start zebra supervisorctl start staticd From c50c390eb4d9ef4ca717a197d087acc2560e6297 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 14 Nov 2019 00:00:55 -0800 Subject: [PATCH 0161/1427] [rsyslog] Add support for IPv6 remote addresses (#3754) --- files/image_config/rsyslog/rsyslog.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/rsyslog/rsyslog.conf.j2 b/files/image_config/rsyslog/rsyslog.conf.j2 index e714fcec5ab4..fbf8bf20160a 100644 --- a/files/image_config/rsyslog/rsyslog.conf.j2 +++ b/files/image_config/rsyslog/rsyslog.conf.j2 @@ -42,7 +42,7 @@ $ActionFileDefaultTemplate SONiCFileFormat #Set remote syslog server {% for server in SYSLOG_SERVER %} -*.* @{{ server }}:514;SONiCFileFormat +*.* @[{{ server }}]:514;SONiCFileFormat {% endfor %} # From c78465b78fefcae3fe0f87ed65519a0c162a8d2e Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Thu, 14 Nov 2019 10:02:32 +0200 Subject: [PATCH 0162/1427] [Mellanox]: Update SAI submodule to 1.15.2 (#3748) Signed-off-by: Volodymyr Samotiy --- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 2bf37a7600bb..39942111f26a 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.15.1-ptf-rif-vlan-fix +MLNX_SAI_VERSION = SAIRel1.15.2-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index d93eaed7ba8b..925116eb63a5 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit d93eaed7ba8b996fb70e000af468c485bbfbbfae +Subproject commit 925116eb63a5a9012dcc22a7a0682ada6e976380 From 4f35a810656b9568125fddf461efa99ab80419b9 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Thu, 14 Nov 2019 13:34:11 +0530 Subject: [PATCH 0163/1427] DellEMC:optoe driver support in DellEMC platforms (#3747) - optoe driver truncates invalid pages(ff) but sff driver doesn't truncate.so,the DOM related calculation made by sff8436 driver will show incorrect data. - Few optics doesn't support DOM. - SFP plugins currently returns None for unreadable pages and this'd throw the below mentioned error in sfpshow eeprom --dom. --- .../plugins/sfputil.py | 36 +++++++++---------- .../s6000/scripts/s6000_platform.sh | 2 +- .../s6000/sonic_platform/sfp.py | 26 ++++++++------ .../s6100/scripts/s6100_platform.sh | 6 ++-- .../s6100/sonic_platform/sfp.py | 20 +++++------ .../z9100/scripts/z9100_platform.sh | 6 ++-- .../z9100/sonic_platform/sfp.py | 25 +++++++------ 7 files changed, 64 insertions(+), 57 deletions(-) diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py index df841bf88355..bb1c961ab670 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py @@ -362,11 +362,11 @@ def get_transceiver_dom_info_dict(self, port_num): sfpd_obj = sff8436Dom() if sfpd_obj is None: - return None + return transceiver_dom_info_dict sfpi_obj = sff8436InterfaceId() if sfpi_obj is None: - return None + return transceiver_dom_info_dict # QSFP capability byte parse, through this byte can know whether it support tx_power or not. # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, @@ -376,25 +376,25 @@ def get_transceiver_dom_info_dict(self, port_num): if qsfp_dom_capability_raw is not None: qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) else: - return None + return transceiver_dom_info_dict dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) if dom_temperature_raw is not None: dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) else: - return None + return transceiver_dom_info_dict dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) if dom_voltage_raw is not None: dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) else: - return None + return transceiver_dom_info_dict qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) if qsfp_dom_rev_raw is not None: qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) else: - return None + return transceiver_dom_info_dict transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] @@ -409,7 +409,7 @@ def get_transceiver_dom_info_dict(self, port_num): if dom_channel_monitor_raw is not None: dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) else: - return None + return transceiver_dom_info_dict transceiver_dom_info_dict['tx1power'] = 'N/A' transceiver_dom_info_dict['tx2power'] = 'N/A' @@ -433,7 +433,7 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] else: - offset = 0 + offset = 256 file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) if not self._sfp_eeprom_present(file_path, 0): return None @@ -452,21 +452,21 @@ def get_transceiver_dom_info_dict(self, port_num): if dom_temperature_raw is not None: dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) else: - return None + return transceiver_dom_info_dict dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) if dom_voltage_raw is not None: dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) else: - return None + return transceiver_dom_info_dict dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) if dom_channel_monitor_raw is not None: dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) else: - return None + return transceiver_dom_info_dict try: sysfsfile_eeprom.close() @@ -519,11 +519,11 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): sfpd_obj = sff8436Dom() if sfpd_obj is None: - return None + return transceiver_dom_threshold_info_dict # Dom Threshold data starts from offset 384 # Revert offset back to 0 once data is retrieved - offset = 0 + offset = 384 dom_module_threshold_raw = self._read_eeprom_specific_bytes( sysfsfile_eeprom, (offset + QSFP_MODULE_THRESHOLD_OFFSET), @@ -531,7 +531,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): if dom_module_threshold_raw is not None: dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) else: - return None + return transceiver_dom_threshold_info_dict dom_channel_threshold_raw = self._read_eeprom_specific_bytes( sysfsfile_eeprom, @@ -540,7 +540,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): if dom_channel_threshold_raw is not None: dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) else: - return None + return transceiver_dom_threshold_info_dict try: sysfsfile_eeprom.close() @@ -567,7 +567,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] else: - offset = 0 + offset = 256 file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) if not self._sfp_eeprom_present(file_path, 0): return None @@ -580,7 +580,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): sfpd_obj = sff8472Dom(None,1) if sfpd_obj is None: - return None + return transceiver_dom_threshold_info_dict dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) @@ -588,7 +588,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): if dom_module_threshold_raw is not None: dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) else: - return None + return transceiver_dom_threshold_info_dict try: sysfsfile_eeprom.close() diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh index 316fbaec5fee..bf6c730425e7 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh @@ -32,7 +32,7 @@ add_i2c_devices() { echo 24c02 0x52 > /sys/class/i2c-adapter/i2c-11/new_device echo 24c02 0x53 > /sys/class/i2c-adapter/i2c-11/new_device for i in `seq 0 31`; do - echo sff8436 0x50 > /sys/class/i2c-adapter/i2c-$((20+i))/new_device + echo optoe1 0x50 > /sys/class/i2c-adapter/i2c-$((20+i))/new_device done } diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py index a334aa7a7f97..9ab89db5d61a 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py @@ -44,7 +44,7 @@ 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', - 'specification_compliance', 'vendor_date', 'vendor_oui'] + 'specification_compliance', 'type_abbrv_name','vendor_date', 'vendor_oui'] dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', @@ -87,6 +87,7 @@ 'nominal_bit_rate': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'specification_compliance': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type_abbrv_name' : [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'], 'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], @@ -168,6 +169,7 @@ def _get_eeprom_data(self, eeprom_key): return eeprom_data + def get_transceiver_info(self): """ Retrieves transceiver info of this SFP @@ -184,6 +186,7 @@ def get_transceiver_info(self): ext_id = iface_data['data']['Extended Identifier']['value'] rate_identifier = iface_data['data']['RateIdentifier']['value'] identifier = iface_data['data']['type']['value'] + type_abbrv_name=iface_data['data']['type_abbrv_name']['value'] bit_rate = str( iface_data['data']['Nominal Bit Rate(100Mbs)']['value']) @@ -195,7 +198,7 @@ def get_transceiver_info(self): cable_type = key cable_length = str(iface_data['data'][key]['value']) else: - return None + return transceiver_info_dict # Vendor Date vendor_date_data = self._get_eeprom_data('vendor_date') @@ -209,36 +212,36 @@ def get_transceiver_info(self): if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: - return None + return transceiver_info_dict # Vendor OUI vendor_oui_data = self._get_eeprom_data('vendor_oui') if (vendor_oui_data is not None): vendor_oui = vendor_oui_data['data']['Vendor OUI']['value'] else: - return None + return transceiver_info_dict # Vendor PN vendor_pn_data = self._get_eeprom_data('modelname') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: - return None + return transceiver_info_dict # Vendor Revision vendor_rev_data = self._get_eeprom_data('hardwarerev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: - return None + return transceiver_info_dict # Vendor Serial Number vendor_sn_data = self._get_eeprom_data('serialnum') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: - return None - + return transceiver_info_dict + # Fill The Dictionary and return transceiver_info_dict['type'] = identifier transceiver_info_dict['hardwarerev'] = vendor_rev @@ -256,6 +259,7 @@ def get_transceiver_info(self): compliance_code_dict) transceiver_info_dict['vendor_date'] = vendor_date transceiver_info_dict['vendor_oui'] = vendor_oui + transceiver_info_dict['type_abbrv_name']=type_abbrv_name return transceiver_info_dict @@ -279,7 +283,7 @@ def get_transceiver_threshold_info(self): vccHighWarn = module_threshold_data['data']['VccHighWarning']['value'] vccLowWarn = module_threshold_data['data']['VccLowWarning']['value'] else: - return None + return transceiver_dom_threshold_dict # Channel Threshold channel_threshold_data = self._get_eeprom_data('ChannelThreshold') @@ -293,7 +297,7 @@ def get_transceiver_threshold_info(self): txBiasHighWarn = channel_threshold_data['data']['TxBiasHighWarning']['value'] txBiasLowWarn = channel_threshold_data['data']['TxBiasLowWarning']['value'] else: - return None + return transceiver_dom_threshold_dict transceiver_dom_threshold_dict['temphighalarm'] = tempHighAlarm transceiver_dom_threshold_dict['templowalarm'] = tempLowAlarm @@ -367,7 +371,7 @@ def get_transceiver_bulk_status(self): rx_power = channel_monitor_data['data']['RX4Power']['value'] rx_power_list.append(rx_power) else: - return None + return transceiver_dom_dict transceiver_dom_dict['rx_los'] = rx_los transceiver_dom_dict['tx_fault'] = tx_fault diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh index 52eb757ad696..d8b13ca02c1e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -109,8 +109,8 @@ switch_board_qsfp_mux() { #Attach/Detach the SFP modules on PCA9548_2 switch_board_sfp() { case $1 in - "new_device") i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-11/$1" - i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + "new_device") i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-12/$1" ;; "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-11/$1" i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-12/$1" @@ -125,7 +125,7 @@ qsfp_device_mod() { case $1 in "new_device") for ((i=$2;i<=$3;i++)); do - i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + i2c_config "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" done ;; "delete_device") for ((i=$2;i<=$3;i++)); diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py index 8f8f63266f7b..e94c53b11a95 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py @@ -195,49 +195,49 @@ def get_transceiver_info(self): cable_type = key cable_length = str(iface_data['data'][key]['value']) else: - return None + return transceiver_info_dict # Vendor Date vendor_date_data = self._get_eeprom_data('vendor_date') if (vendor_date_data is not None): vendor_date = vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] else: - return None + return transceiver_info_dict # Vendor Name vendor_name_data = self._get_eeprom_data('manufacturename') if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: - return None + return transceiver_info_dict # Vendor OUI vendor_oui_data = self._get_eeprom_data('vendor_oui') if (vendor_oui_data is not None): vendor_oui = vendor_oui_data['data']['Vendor OUI']['value'] else: - return None + return transceiver_info_dict # Vendor PN vendor_pn_data = self._get_eeprom_data('modelname') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: - return None + return transceiver_info_dict # Vendor Revision vendor_rev_data = self._get_eeprom_data('hardwarerev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: - return None + return transceiver_info_dict # Vendor Serial Number vendor_sn_data = self._get_eeprom_data('serialnum') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: - return None + return transceiver_info_dict # Fill The Dictionary and return transceiver_info_dict['type'] = identifier @@ -279,7 +279,7 @@ def get_transceiver_threshold_info(self): vccHighWarn = module_threshold_data['data']['VccHighWarning']['value'] vccLowWarn = module_threshold_data['data']['VccLowWarning']['value'] else: - return None + return transceiver_dom_threshold_dict # Channel Threshold channel_threshold_data = self._get_eeprom_data('ChannelThreshold') @@ -293,7 +293,7 @@ def get_transceiver_threshold_info(self): txBiasHighWarn = channel_threshold_data['data']['TxBiasHighWarning']['value'] txBiasLowWarn = channel_threshold_data['data']['TxBiasLowWarning']['value'] else: - return None + return transceiver_dom_threshold_dict transceiver_dom_threshold_dict['temphighalarm'] = tempHighAlarm transceiver_dom_threshold_dict['templowalarm'] = tempLowAlarm @@ -367,7 +367,7 @@ def get_transceiver_bulk_status(self): rx_power = channel_monitor_data['data']['RX4Power']['value'] rx_power_list.append(rx_power) else: - return None + return transceiver_dom_dict transceiver_dom_dict['rx_los'] = rx_los transceiver_dom_dict['tx_fault'] = tx_fault diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh index 276acd882f14..7fe841ef5447 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh @@ -107,8 +107,8 @@ switch_board_qsfp_mux() { #Attach/Detach the SFP modules on PCA9548_2 switch_board_sfp() { case $1 in - "new_device") i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-11/$1" - i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + "new_device") i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-12/$1" ;; "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-11/$1" i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-12/$1" @@ -125,7 +125,7 @@ switch_board_qsfp() { "new_device") for ((i=18;i<=49;i++)); do - i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + i2c_config "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" done ;; "delete_device") diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py index f29b708b8ea5..87057545cbb7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py @@ -44,7 +44,7 @@ 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', - 'specification_compliance', 'vendor_date', 'vendor_oui'] + 'specification_compliance', ,'type_abbrv_name','vendor_date', 'vendor_oui'] dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', @@ -87,6 +87,7 @@ 'nominal_bit_rate': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'specification_compliance': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type_abbrv_name': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'], 'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], @@ -186,6 +187,7 @@ def get_transceiver_info(self): identifier = iface_data['data']['type']['value'] bit_rate = str( iface_data['data']['Nominal Bit Rate(100Mbs)']['value']) + type_abbrv_name=iface_data['data']['type_abbrv_name']['value'] for key in compliance_code_tup: if key in iface_data['data']['Specification compliance']['value']: @@ -195,49 +197,49 @@ def get_transceiver_info(self): cable_type = key cable_length = str(iface_data['data'][key]['value']) else: - return None + return transceiver_info_dict # Vendor Date vendor_date_data = self._get_eeprom_data('vendor_date') if (vendor_date_data is not None): vendor_date = vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] else: - return None + return transceiver_info_dict # Vendor Name vendor_name_data = self._get_eeprom_data('manufacturename') if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: - return None + return transceiver_info_dict # Vendor OUI vendor_oui_data = self._get_eeprom_data('vendor_oui') if (vendor_oui_data is not None): vendor_oui = vendor_oui_data['data']['Vendor OUI']['value'] else: - return None + return transceiver_info_dict # Vendor PN vendor_pn_data = self._get_eeprom_data('modelname') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: - return None + return transceiver_info_dict # Vendor Revision vendor_rev_data = self._get_eeprom_data('hardwarerev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: - return None + return transceiver_info_dict # Vendor Serial Number vendor_sn_data = self._get_eeprom_data('serialnum') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: - return None + return transceiver_info_dict # Fill The Dictionary and return transceiver_info_dict['type'] = identifier @@ -256,6 +258,7 @@ def get_transceiver_info(self): compliance_code_dict) transceiver_info_dict['vendor_date'] = vendor_date transceiver_info_dict['vendor_oui'] = vendor_oui + transceiver_info_dict['type_abbrv_name']=type_abbrv_name return transceiver_info_dict @@ -279,7 +282,7 @@ def get_transceiver_threshold_info(self): vccHighWarn = module_threshold_data['data']['VccHighWarning']['value'] vccLowWarn = module_threshold_data['data']['VccLowWarning']['value'] else: - return None + return transceiver_dom_threshold_dict # Channel Threshold channel_threshold_data = self._get_eeprom_data('ChannelThreshold') @@ -293,7 +296,7 @@ def get_transceiver_threshold_info(self): txBiasHighWarn = channel_threshold_data['data']['TxBiasHighWarning']['value'] txBiasLowWarn = channel_threshold_data['data']['TxBiasLowWarning']['value'] else: - return None + return transceiver_dom_threshold_dict transceiver_dom_threshold_dict['temphighalarm'] = tempHighAlarm transceiver_dom_threshold_dict['templowalarm'] = tempLowAlarm @@ -367,7 +370,7 @@ def get_transceiver_bulk_status(self): rx_power = channel_monitor_data['data']['RX4Power']['value'] rx_power_list.append(rx_power) else: - return None + return transceiver_dom_dict transceiver_dom_dict['rx_los'] = rx_los transceiver_dom_dict['tx_fault'] = tx_fault From 4007d9ba9c1be83d56cf9fcec20edfd32a4d51cc Mon Sep 17 00:00:00 2001 From: kannankvs Date: Thu, 14 Nov 2019 13:36:54 +0530 Subject: [PATCH 0164/1427] [ntp]: modified ntp script to hide the error related to cfggen (#3745) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR is to handle the issue 3527. When device boots up, NTP throws a traceback as explained in the issue 3527. - Traceback will be seen when MGMT_VRF_CONFIG does not exist in the database. Traceback is coming from the script “/etc/init.d/ntpâ€. - Traceback does not affect the NTP functionality with/without management VRF. When MGMT_VRF_CONFIG does not exist or when MGMT_VRF_CONFIG’s mgmtVrfEnabled is configured to “falseâ€, “NTP†will be started in the “default VRF†context, which is working fine even with this traceback. - This traceback error will be hidden by redirecting the error to /dev/null without affecting functionality. --- files/image_config/ntp/ntp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/ntp/ntp b/files/image_config/ntp/ntp index 976269241bbb..ecf0e5089071 100755 --- a/files/image_config/ntp/ntp +++ b/files/image_config/ntp/ntp @@ -50,7 +50,7 @@ case $1 in fi ( flock -w 180 9 - vrfEnabled=$(/usr/local/bin/sonic-cfggen -d -v 'MGMT_VRF_CONFIG["vrf_global"]["mgmtVrfEnabled"]') + vrfEnabled=$(/usr/local/bin/sonic-cfggen -d -v 'MGMT_VRF_CONFIG["vrf_global"]["mgmtVrfEnabled"]' 2> /dev/null) if [ "$vrfEnabled" = "true" ] then log_daemon_msg "Starting NTP server in mgmt-vrf" "ntpd" From 413f07820d55e1fdd95a6982855fedebbcb5fb4b Mon Sep 17 00:00:00 2001 From: srideepDell Date: Thu, 14 Nov 2019 01:08:15 -0700 Subject: [PATCH 0165/1427] [devices]: Firmware upgrade support for DellEMC platforms(s5248,s5232,z9100,s6100,z9264f) (#3743) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * This method is used to update firmware components such as CPLD,FPGA,BIOS,SMF * This uses ONIE firmware upgrade design to stage firmware update from NOS. a) Copy latest firmware updater image to target running sonic. b) Run “./fw-updater -u onie-firmware-x86_64-dellemc_s5200_c3538-r0.3.40.5.1-9.binâ€. c) This would automatically reboot ONIE into update mode and update firmware components to latest and reboot back to sonic without any user intervention. Signed-off-by: Srideep Devireddy --- platform/broadcom/platform-modules-dell.mk | 5 + .../common/fw-updater | 91 +++++++++++++++++++ .../debian/platform-modules-s5232f.install | 1 + .../debian/platform-modules-s5248f.install | 1 + .../debian/platform-modules-s6100.install | 1 + .../debian/platform-modules-z9100.install | 1 + .../debian/platform-modules-z9264f.install | 1 + 7 files changed, 101 insertions(+) create mode 100755 platform/broadcom/sonic-platform-modules-dell/common/fw-updater diff --git a/platform/broadcom/platform-modules-dell.mk b/platform/broadcom/platform-modules-dell.mk index 34e404cfae45..583f74f72d8b 100644 --- a/platform/broadcom/platform-modules-dell.mk +++ b/platform/broadcom/platform-modules-dell.mk @@ -5,12 +5,14 @@ DELL_Z9100_PLATFORM_MODULE_VERSION = 1.1 DELL_S6100_PLATFORM_MODULE_VERSION = 1.1 DELL_Z9264F_PLATFORM_MODULE_VERSION = 1.1 DELL_S5232F_PLATFORM_MODULE_VERSION = 1.1 +DELL_S5248F_PLATFORM_MODULE_VERSION = 1.1 export DELL_S6000_PLATFORM_MODULE_VERSION export DELL_Z9100_PLATFORM_MODULE_VERSION export DELL_S6100_PLATFORM_MODULE_VERSION export DELL_Z9264F_PLATFORM_MODULE_VERSION export DELL_S5232F_PLATFORM_MODULE_VERSION +export DELL_S5248F_PLATFORM_MODULE_VERSION DELL_Z9100_PLATFORM_MODULE = platform-modules-z9100_$(DELL_Z9100_PLATFORM_MODULE_VERSION)_amd64.deb $(DELL_Z9100_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-dell @@ -35,6 +37,9 @@ DELL_S5232F_PLATFORM_MODULE = platform-modules-s5232f_$(DELL_S5232F_PLATFORM_MOD $(DELL_S5232F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5232f_c3538-r0 $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5232F_PLATFORM_MODULE))) +DELL_S5248F_PLATFORM_MODULE = platform-modules-s5248f_$(DELL_S5248F_PLATFORM_MODULE_VERSION)_amd64.deb +$(DELL_S5248F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5248f_c3538-r0 +$(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5248F_PLATFORM_MODULE))) SONIC_STRETCH_DEBS += $(DELL_Z9100_PLATFORM_MODULE) #flashrom tool diff --git a/platform/broadcom/sonic-platform-modules-dell/common/fw-updater b/platform/broadcom/sonic-platform-modules-dell/common/fw-updater new file mode 100755 index 000000000000..6905664672ad --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/fw-updater @@ -0,0 +1,91 @@ +#!/usr/bin/python + +# dell staging fw updater script + +import os +import sys +import subprocess +import argparse + + +onie_boot_folder = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' +onie_fwpkg_tool = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' +ONIE_BOOT_MODE_CMD = '/mnt/onie-boot/onie/tools/bin/onie-boot-mode' +HOST_GRUB_DIR = '/host' +HOST_GRUB_CFG = HOST_GRUB_DIR + '/grub/grub.cfg' +HOST_GRUB_ENV = HOST_GRUB_DIR + '/grub/grubenv' +HOST_GRUB_BOOT_DIR = '--boot-directory=' + HOST_GRUB_DIR +HOST_PLATFORM_INFO = HOST_GRUB_DIR + '/platform' +dell_reload_tool = '/usr/bin/reboot' + + + + +def set_onie_mode(option): + """Select the ONIE boot mode, and set the next_entry to point to ONIE""" + _set_env_option('next_entry', 'ONIE') + subprocess.check_call([ONIE_BOOT_MODE_CMD, '-o', option]) + +def set_onie_fw_update_env(): + """Select the ONIE boot mode, and set the next_entry to point to ONIE""" + + if not os.path.exists(onie_boot_folder): + os.makedirs(onie_boot_folder) + + try: + subprocess.check_call(['mount','/dev/disk/by-label/ONIE-BOOT','/mnt/onie-boot']) + except: + print "onie-boot not able to mount" + +def _set_env_option(option, value): + """Set an option in the GRUB environment block. Pass None to value to + unset the option""" + if value is None: + action = 'unset' + key_value = option + else: + action = 'set' + key_value = '%s=%s' % (option, value) + + subprocess.check_call(['grub-editenv', HOST_GRUB_ENV, action, key_value]) + + +def dell_firmware_update_staging(image_name): + + try: + p = subprocess.Popen([onie_fwpkg_tool,"purge"],stdout=subprocess.PIPE,stdin=subprocess.PIPE) + p.communicate("y") + except: + print "onie-fwpkg command not found for purging old fw updates" + + try: + subprocess.check_call([onie_fwpkg_tool,"add", str(image_name)]) + except: + print "onie-fwpkg is not found to stage fw updates" + + try: + set_onie_mode("update") + except: + print "dell-image command not found" + + try: + subprocess.check_call([dell_reload_tool]) + except: + print "reload command not found" + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Dell HOST Firmware updates') + opts = parser.add_mutually_exclusive_group(required=True) + opts.add_argument('-u', '--update', nargs=1, metavar='IMAGE', + help='update specified image') + + args = parser.parse_args() + + if os.getuid() != 0: + parser.exit(127, 'ERROR: Must be root\n') + + if args.update: + set_onie_fw_update_env() + dell_firmware_update_staging(args.update[0]) + diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install index 51bed7edd95a..b577c5cd5b10 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install @@ -7,3 +7,4 @@ s5232f/scripts/qsfp_irq_enable.py usr/bin s5232f/cfg/s5232f-modules.conf etc/modules-load.d s5232f/systemd/platform-modules-s5232f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 +common/fw-updater usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install index 084208955317..7aa27d23b536 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install @@ -7,3 +7,4 @@ s5248f/scripts/qsfp_irq_enable.py usr/bin s5248f/cfg/s5248f-modules.conf etc/modules-load.d s5248f/systemd/platform-modules-s5248f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5248f_c3538-r0 +common/fw-updater usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install index b0c27702cb4a..5d1cb6341fc7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install @@ -13,3 +13,4 @@ s6100/scripts/sensors usr/bin s6100/systemd/platform-modules-s6100.service etc/systemd/system s6100/systemd/s6100-lpc-monitor.service etc/systemd/system tools/flashrom/flashrom usr/local/bin/ +common/fw-updater usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install index bb3d869cf274..5c5c4cc55be2 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install @@ -11,3 +11,4 @@ z9100/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64- z9100/cfg/z9100-modules.conf etc/modules-load.d z9100/systemd/platform-modules-z9100.service etc/systemd/system z9100/systemd/z9100-lpc-monitor.service etc/systemd/system +common/fw-updater usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install index 6a2f15511d66..29e8b1df2e36 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install @@ -7,3 +7,4 @@ z9264f/scripts/qsfp_irq_enable.py usr/bin z9264f/cfg/z9264f-modules.conf etc/modules-load.d z9264f/systemd/platform-modules-z9264f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 +common/fw-updater usr/local/bin From f9e36d3b0b73c34a10e31951d25b53ddb0eaa949 Mon Sep 17 00:00:00 2001 From: lguohan Date: Thu, 14 Nov 2019 17:58:28 -0800 Subject: [PATCH 0166/1427] [submodule]: update sonic-utilities (#3756) * be337d4 2019-11-14 | [bugfix]: allow loopback vrf migration from version 1_0_1 (#737) (HEAD, origin/master, origin/HEAD) [lguohan] * 201132d 2019-11-14 | [config]: add the vid range check for creating vlan. (#634) [wangshengjun] Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index fe4446a4808b..be337d4f09c9 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit fe4446a4808bc98ca2b24b0a9afe822aaa50a7ce +Subproject commit be337d4f09c9fc901c85d2d615a3cdebbc039a33 From df11b2b9f18394782f089a6d6bc4e28d3b6392f4 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Mon, 18 Nov 2019 16:56:44 -0800 Subject: [PATCH 0167/1427] [Services] Restart Telemetry service upon unexpected critical process exit. (#3768) Signed-off-by: Yong Zhao --- dockers/docker-sonic-telemetry/Dockerfile.j2 | 2 ++ dockers/docker-sonic-telemetry/critical_processes | 2 ++ dockers/docker-sonic-telemetry/supervisord.conf | 12 +++++++++--- files/build_templates/telemetry.service.j2 | 4 ++++ rules/telemetry.mk | 1 + 5 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 dockers/docker-sonic-telemetry/critical_processes diff --git a/dockers/docker-sonic-telemetry/Dockerfile.j2 b/dockers/docker-sonic-telemetry/Dockerfile.j2 index cfbe7c6f266c..3a5716001ca5 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/Dockerfile.j2 @@ -35,5 +35,7 @@ RUN apt-get clean -y && \ COPY ["start.sh", "telemetry.sh", "dialout.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sonic-telemetry/critical_processes b/dockers/docker-sonic-telemetry/critical_processes new file mode 100644 index 000000000000..d6953dd0c883 --- /dev/null +++ b/dockers/docker-sonic-telemetry/critical_processes @@ -0,0 +1,2 @@ +telemetry +dialout diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index dcd8a9eb1e80..b6a01de58a7b 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=always +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=true stdout_logfile=syslog stderr_logfile=syslog @@ -23,7 +29,7 @@ stderr_logfile=syslog command=/usr/bin/telemetry.sh priority=3 autostart=false -autorestart=true +autorestart=false stdout_logfile=syslog stderr_logfile=syslog @@ -31,6 +37,6 @@ stderr_logfile=syslog command=/usr/bin/dialout.sh priority=4 autostart=false -autorestart=true +autorestart=false stdout_logfile=syslog stderr_logfile=syslog diff --git a/files/build_templates/telemetry.service.j2 b/files/build_templates/telemetry.service.j2 index 2e7e45218df2..98ae2871bf6f 100644 --- a/files/build_templates/telemetry.service.j2 +++ b/files/build_templates/telemetry.service.j2 @@ -3,12 +3,16 @@ Description=Telemetry container Requires=database.service After=database.service swss.service syncd.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/rules/telemetry.mk b/rules/telemetry.mk index 1d903e603251..af568fb5bd6f 100644 --- a/rules/telemetry.mk +++ b/rules/telemetry.mk @@ -3,3 +3,4 @@ SONIC_TELEMETRY = sonic-telemetry_0.1_$(CONFIGURED_ARCH).deb $(SONIC_TELEMETRY)_SRC_PATH = $(SRC_PATH)/telemetry SONIC_DPKG_DEBS += $(SONIC_TELEMETRY) +$(SONIC_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From 7c65f8c58abcc6756be2f193ccd6063b9abb75f9 Mon Sep 17 00:00:00 2001 From: Tyler Li Date: Wed, 20 Nov 2019 00:15:33 +0800 Subject: [PATCH 0168/1427] Fix vrf test failed after frr update to 7.2 (#3763) --- ...nexthops-compare-vrf-only-if-ip-type.patch | 73 +++++++++++++++++++ src/sonic-frr/patch/series | 1 + 2 files changed, 74 insertions(+) create mode 100644 src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch diff --git a/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch b/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch new file mode 100644 index 000000000000..343f1b3262d9 --- /dev/null +++ b/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch @@ -0,0 +1,73 @@ +From 2f0b5aef66316b47d2cc8ac18453600621a6a317 Mon Sep 17 00:00:00 2001 +From: Tyler Li +Date: Thu, 14 Nov 2019 23:46:52 -0800 +Subject: [PATCH] nexthops compare vrf only if ip type + +--- + lib/nexthop.c | 12 ++++++------ + lib/zclient.c | 12 ++++++------ + 2 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/lib/nexthop.c b/lib/nexthop.c +index cf5bed3d6..7d9f646c9 100644 +--- a/lib/nexthop.c ++++ b/lib/nexthop.c +@@ -105,12 +105,6 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, + { + int ret = 0; + +- if (next1->vrf_id < next2->vrf_id) +- return -1; +- +- if (next1->vrf_id > next2->vrf_id) +- return 1; +- + if (next1->type < next2->type) + return -1; + +@@ -120,6 +114,12 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, + switch (next1->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV6: ++ if (next1->vrf_id < next2->vrf_id) ++ return -1; ++ ++ if (next1->vrf_id > next2->vrf_id) ++ return 1; ++ + ret = _nexthop_gateway_cmp(next1, next2); + if (ret != 0) + return ret; +diff --git a/lib/zclient.c b/lib/zclient.c +index c739af043..0d37c46d1 100644 +--- a/lib/zclient.c ++++ b/lib/zclient.c +@@ -783,12 +783,6 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, + { + int ret = 0; + +- if (next1->vrf_id < next2->vrf_id) +- return -1; +- +- if (next1->vrf_id > next2->vrf_id) +- return 1; +- + if (next1->type < next2->type) + return -1; + +@@ -798,6 +792,12 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, + switch (next1->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV6: ++ if (next1->vrf_id < next2->vrf_id) ++ return -1; ++ ++ if (next1->vrf_id > next2->vrf_id) ++ return 1; ++ + ret = nexthop_g_addr_cmp(next1->type, &next1->gate, + &next2->gate); + if (ret != 0) +-- +2.11.0 + diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 233021ace50b..13619c87ff65 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -2,4 +2,5 @@ 0002-Reduce-severity-of-Vty-connected-from-message.patch 0003-Use-vrf_id-for-vrf-not-tabled_id.patch 0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch +0005-nexthops-compare-vrf-only-if-ip-type.patch 0006-changes-for-making-snmp-socket-non-blocking.patch From b25ec7d59176b5e196903bc3d6078abdf6a034f1 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Tue, 19 Nov 2019 13:09:42 -0800 Subject: [PATCH 0169/1427] Update submodule: sonic-snmpagent (#3782) --- src/sonic-snmpagent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 875831ecda26..862e51ab85d4 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 875831ecda2601a88612c0185242d11e97eb6e82 +Subproject commit 862e51ab85d48290082adfcbb801bfbbe3a95bf3 From 0e0699ce4e2057e86b572f0a424109b7eaaf2df7 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Tue, 19 Nov 2019 22:13:21 -0800 Subject: [PATCH 0170/1427] [Submodule] Update sonic-swss-common (#3770) a4a1e10 - 2019-11-07 : Changes in swss-common submodule to support NAT feature. (#304) [Kiran Kumar Kella] b1375bb - 2019-10-28 : [consumer_table] Add messages for performing object availability query (#314) [Danny Allen] 2fe2327 - 2019-10-25 : adding FDB table in CFG db (#303) [anilkpandey] 2018880 - 2019-09-26 : added COUNTERS_LAG_NAME_MAP_TABLE in COUNTERS_DB [anilkpandey] f41dcc3 - 2019-10-07 : added lua script to flush fdb entries [anilkpandey] c87a7cf - 2019-10-25 : [consumer_table] Add messages for performing attribute enum value capabilities query (#313) [Danny Allen] --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index aaa8133e8be9..a4a1e108afb3 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit aaa8133e8be9eb2a2f924c9eec997a502b795544 +Subproject commit a4a1e108afb3e75717e204da49a975681d964e8c From fc495dc10ecd942ba8e8766cd01f8b5933f73a3e Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Wed, 20 Nov 2019 08:14:29 +0200 Subject: [PATCH 0171/1427] [barefoot][build] Fixed BFN platform build failure (#3766) Signed-off-by: Andriy Kokhan --- .../x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf | 2 +- .../Arista-7170-64C/switch-tna-sai.conf | 2 +- .../x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf | 2 +- .../Arista-7170-Q59S20/switch-tna-sai.conf | 2 +- .../x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf | 2 +- .../x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf | 2 +- .../montara/switch-tna-sai.conf | 2 +- .../x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf | 2 +- .../mavericks/switch-tna-sai.conf | 2 +- .../INGRASYS-S9180-32X/switch-sai.conf | 2 +- .../INGRASYS-S9180-32X/switch-tna-sai.conf | 2 +- .../INGRASYS-S9280-64X/switch-sai.conf | 2 +- .../INGRASYS-S9280-64X/switch-tna-sai.conf | 2 +- .../wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf | 2 +- .../x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-tna-sai.conf | 2 +- platform/barefoot/bfn-platform.mk | 4 ++-- platform/barefoot/bfn-sai.mk | 4 ++-- 17 files changed, 19 insertions(+), 19 deletions(-) diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf index c3abb3ebd8fc..0a807b1c9ea7 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "switchapi_port_add": false, "non_default_port_ppgs": 5 } diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-tna-sai.conf b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-tna-sai.conf index 403b08d6bb5e..ece3fcbe6a90 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-tna-sai.conf +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-tna-sai.conf @@ -27,7 +27,7 @@ } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf index c3abb3ebd8fc..0a807b1c9ea7 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "switchapi_port_add": false, "non_default_port_ppgs": 5 } diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-tna-sai.conf b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-tna-sai.conf index 403b08d6bb5e..ece3fcbe6a90 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-tna-sai.conf +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-tna-sai.conf @@ -27,7 +27,7 @@ } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf index a1ee06da879c..cf6e445dba1a 100644 --- a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf @@ -28,7 +28,7 @@ } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf index 089153b6a5ce..fc224c9602e4 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "agent0": "lib/platform/x86_64-accton_wedge100bf_32x-r0/libpltfm_mgr.so", "switchapi_port_add": false, "non_default_port_ppgs": 5 diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf index a459e925531c..085a1b8dcdfc 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf @@ -28,7 +28,7 @@ } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf index 1f0ff8b32bb1..81a7d7bc28c3 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "agent0": "lib/platform/x86_64-accton_wedge100bf_65x-r0/libpltfm_mgr.so", "switchapi_port_add": false, "non_default_port_ppgs": 5 diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf index 5497836266e1..ddcb9d4ba287 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf @@ -28,7 +28,7 @@ } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf index 4f316bb9e5af..bf15b40d0c58 100644 --- a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "agent0": "lib/platform/x86_64-ingrasys_s9180_32x-r0/libpltfm_mgr.so", "switchapi_port_add": false } diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-tna-sai.conf b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-tna-sai.conf index 43ed0e4af6ae..9fbf9d3cdb69 100644 --- a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-tna-sai.conf +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-tna-sai.conf @@ -28,7 +28,7 @@ } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-sai.conf b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-sai.conf index 224d1fc58b18..f1e9c0bc10da 100644 --- a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-sai.conf +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "agent0": "lib/platform/x86_64-ingrasys_s9280_64x-r0/libpltfm_mgr.so", "switchapi_port_add": false } diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-tna-sai.conf b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-tna-sai.conf index 29e8f4bae0b3..4895ac901ff6 100644 --- a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-tna-sai.conf +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-tna-sai.conf @@ -28,7 +28,7 @@ } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, diff --git a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf index 65a02a621f03..ae01f3ebe96a 100644 --- a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf +++ b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "agent0": "lib/platform/x86_64-wnc_osw1800-r0/libpltfm_mgr.so", "switchapi_port_add": false } diff --git a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-tna-sai.conf b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-tna-sai.conf index f156534f873d..7cb3ddc48fc9 100644 --- a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-tna-sai.conf +++ b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-tna-sai.conf @@ -28,7 +28,7 @@ } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 32ba62e3feb2..854026b52949 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ -BFN_PLATFORM = bfnplatform_20191107_deb9.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnplatform_20191107_deb9.deb" +BFN_PLATFORM = bfnplatform_20191115_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnplatform_20191115_deb9.deb" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 366a7487deb8..6f413d50c11e 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,5 @@ -BFN_SAI = bfnsdk_20191107_deb9.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnsdk_20191107_deb9.deb" +BFN_SAI = bfnsdk_20191115_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnsdk_20191115_deb9.deb" SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) From 5466bb53264b22c0eeaee21d28801b0db646d3e1 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 19 Nov 2019 22:52:29 -0800 Subject: [PATCH 0172/1427] [sonic-mgmt]: install ansible 2.8.7 and pytest-ansible 2.2.2 (#3776) Signed-off-by: Guohan Lu --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index d4ac92feec50..d24df1ca5d77 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -76,7 +76,7 @@ RUN pip install azure-kusto-data==0.0.13 \ azure-kusto-ingest==0.0.13 # Install pytest-ansible module -RUN pip install pytest-ansible==2.0.2 +RUN pip install pytest-ansible==2.2.2 ## Copy and install sonic-mgmt docker dependencies COPY \ @@ -90,8 +90,7 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -RUN git clone https://github.com/ansible/ansible -RUN cd ansible && git checkout v2.0.0.2-1 -b v2.0.0.2-1 && git submodule update --init --recursive && make && make install +RUN pip install ansible==2.8.7 RUN mkdir /var/run/sshd EXPOSE 22 From 420278f286fcc5e4ccfa60766761b3430baa4380 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 20 Nov 2019 07:39:49 -0800 Subject: [PATCH 0173/1427] [docker-base/ptf]: Make a link to vim. Add tmux to docker-ptf (#3758) --- dockers/docker-base-stretch/Dockerfile.j2 | 2 ++ dockers/docker-ptf/Dockerfile.j2 | 1 + 2 files changed, 3 insertions(+) diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index ed59c3298715..95272e2322ce 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -83,4 +83,6 @@ COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"] COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"] COPY ["root/.vimrc", "/root/.vimrc"] +RUN ln /usr/bin/vim.tiny /usr/bin/vim + COPY ["etc/supervisor/supervisord.conf", "/etc/supervisor/"] diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index dcf67aeff5f9..deb1892959e6 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -51,6 +51,7 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / hping3 \ curl \ tcpdump \ + tmux \ python \ python-dev \ python-libpcap \ From 82e309f6dea47058037941e1f0629dc7c45d5de1 Mon Sep 17 00:00:00 2001 From: ChiouRung Haung Date: Wed, 20 Nov 2019 23:41:04 +0800 Subject: [PATCH 0174/1427] [broadcom]: Add bcmcmd and bcmsh to docker-syncd-brcm-rpc (#3739) Signed-off-by: chiourung_huang --- platform/broadcom/docker-syncd-brcm-rpc.mk | 4 ++++ .../broadcom/docker-syncd-brcm-rpc/base_image_files/bcmcmd | 3 +++ .../broadcom/docker-syncd-brcm-rpc/base_image_files/bcmsh | 3 +++ 3 files changed, 10 insertions(+) create mode 100755 platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmcmd create mode 100755 platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmsh diff --git a/platform/broadcom/docker-syncd-brcm-rpc.mk b/platform/broadcom/docker-syncd-brcm-rpc.mk index 80d6ea2d8147..bd2ef01c5eed 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc.mk +++ b/platform/broadcom/docker-syncd-brcm-rpc.mk @@ -23,3 +23,7 @@ $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro + +$(DOCKER_SYNCD_BRCM_RPC)_BASE_IMAGE_FILES += bcmcmd:/usr/bin/bcmcmd +$(DOCKER_SYNCD_BRCM_RPC)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh + diff --git a/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmcmd b/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmcmd new file mode 100755 index 000000000000..7903db6ed6a3 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmcmd @@ -0,0 +1,3 @@ +#!/bin/bash + +docker exec -i syncd bcmcmd "$@" diff --git a/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmsh b/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmsh new file mode 100755 index 000000000000..3bb78b0da796 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmsh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker exec -it syncd bcmsh "$@" From 1d5005bc8cb624079fc07968e6db2b3fc08fbb07 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 20 Nov 2019 10:40:19 -0800 Subject: [PATCH 0175/1427] [multiDB] add database_config.json into vs images (#3757) --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 1 + .../vs/docker-sonic-vs/database_config.json | 57 +++++++++++++++++++ platform/vs/docker-sonic-vs/start.sh | 3 +- 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 platform/vs/docker-sonic-vs/database_config.json diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 85db514d77bb..7cc6f98921ff 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -106,6 +106,7 @@ COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin/"] COPY ["files/buffers_config.j2", "files/qos_config.j2", "/usr/share/sonic/templates/"] COPY ["files/sonic_version.yml", "/etc/sonic/"] +COPY ["database_config.json", "/etc/default/sonic-db/"] # Workaround the tcpdump issue RUN mv /usr/sbin/tcpdump /usr/bin/tcpdump diff --git a/platform/vs/docker-sonic-vs/database_config.json b/platform/vs/docker-sonic-vs/database_config.json new file mode 100644 index 000000000000..b86ae11bba98 --- /dev/null +++ b/platform/vs/docker-sonic-vs/database_config.json @@ -0,0 +1,57 @@ +{ + "INSTANCES": { + "redis":{ + "hostname" : "127.0.0.1", + "port" : 6379, + "unix_socket_path" : "/var/run/redis/redis.sock" + } + }, + "DATABASES" : { + "APPL_DB" : { + "id" : 0, + "separator": ":", + "instance" : "redis" + }, + "ASIC_DB" : { + "id" : 1, + "separator": ":", + "instance" : "redis" + }, + "COUNTERS_DB" : { + "id" : 2, + "separator": ":", + "instance" : "redis" + }, + "LOGLEVEL_DB" : { + "id" : 3, + "separator": ":", + "instance" : "redis" + }, + "CONFIG_DB" : { + "id" : 4, + "separator": "|", + "instance" : "redis" + }, + "PFC_WD_DB" : { + "id" : 5, + "separator": ":", + "instance" : "redis" + }, + "FLEX_COUNTER_DB" : { + "id" : 5, + "separator": ":", + "instance" : "redis" + }, + "STATE_DB" : { + "id" : 6, + "separator": "|", + "instance" : "redis" + }, + "SNMP_OVERLAY_DB" : { + "id" : 7, + "separator": "|", + "instance" : "redis" + } + }, + "VERSION" : "1.0" +} diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 8770d304fcd8..614541961c87 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -29,7 +29,8 @@ rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd -mkdir -p /var/run/redis +mkdir -p /var/run/redis/sonic-db +cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db/ supervisorctl start redis-server From 29a74516c5fe56f76dd3a6eb70d1daa3abc174aa Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Thu, 21 Nov 2019 08:27:55 +0800 Subject: [PATCH 0176/1427] [submodule] advance submodule head for sonic-platform-common (#3787) --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index cc2dac5963a1..d22f0a0e64f3 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit cc2dac5963a14d04dd15735de35df9b30cff1e41 +Subproject commit d22f0a0e64f30e9e26064824fb11f27b2d636850 From 0c9040dec9642688fdb944f2f2da161acbfe07a2 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Thu, 21 Nov 2019 08:30:05 +0800 Subject: [PATCH 0177/1427] [Mellanox] support get_transceiver_threshold_info (#3777) * [sonic_platform.sfp] support get_transceiver_dom_threshold_info_dict * [platform/sfp]qsfp threshold and beautify code 1. qsfp threshold: tx power 2. beautify code, removing some magic numbers 3. optimize get_present by only reading one byte. --- .../mlnx-platform-api/sonic_platform/sfp.py | 218 ++++++++++++++++-- 1 file changed, 200 insertions(+), 18 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index dac6a8e4d4d6..845f355e28f1 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -76,6 +76,9 @@ # get_transceiver_bulk_status XCVR_INTERFACE_DATA_START = 0 XCVR_INTERFACE_DATA_SIZE = 92 +SFP_MODULE_ADDRA2_OFFSET = 256 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 QSFP_DOM_BULK_DATA_START = 22 QSFP_DOM_BULK_DATA_SIZE = 36 @@ -97,7 +100,7 @@ QSFP_VOLT_OFFSET = 26 QSFP_VOLT_WIDTH = 2 QSFP_VERSION_COMPLIANCE_OFFSET = 1 -QSFP_VERSION_COMPLIANCE_WIDTH = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 2 QSFP_CHANNL_MON_OFFSET = 34 QSFP_CHANNL_MON_WIDTH = 16 QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 @@ -118,6 +121,12 @@ QSFP_OPTION_VALUE_OFFSET = 192 QSFP_OPTION_VALUE_WIDTH = 4 +QSFP_MODULE_UPPER_PAGE3_START = 384 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 24 + SFP_TEMPE_OFFSET = 96 SFP_TEMPE_WIDTH = 2 SFP_VOLT_OFFSET = 98 @@ -203,6 +212,7 @@ def __init__(self, sfp_index, sfp_type): self.sdk_handle = None self.sdk_index = sfp_index + #SDK initializing stuff def _initialize_sdk_handle(self): """ @@ -215,6 +225,7 @@ def _initialize_sdk_handle(self): self.mypid = os.getpid() + def _open_sdk(self): if self.sdk_handle is None: self._initialize_sdk_handle() @@ -226,18 +237,21 @@ def _open_sdk(self): return True + def _close_sdk(self): rc = sxd_access_reg_deinit() if rc != 0: logger.log_warning("Failed to deinitializing register access.") #no further actions here + def _init_sx_meta_data(self): meta = sxd_reg_meta_t() meta.dev_id = DEVICE_ID meta.swid = SWITCH_ID return meta + def get_presence(self): """ Retrieves the presence of the device @@ -246,7 +260,7 @@ def get_presence(self): bool: True if device is present, False if not """ presence = False - ethtool_cmd = "ethtool -m sfp{} hex on offset 0 length 4 2>/dev/null".format(self.index) + ethtool_cmd = "ethtool -m sfp{} hex on offset 0 length 1 2>/dev/null".format(self.index) try: proc = subprocess.Popen(ethtool_cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] @@ -260,6 +274,7 @@ def get_presence(self): return presence + # Read out any bytes from any offset def _read_eeprom_specific_bytes(self, offset, num_bytes): eeprom_raw = [] @@ -277,6 +292,7 @@ def _read_eeprom_specific_bytes(self, offset, num_bytes): return eeprom_raw + def _dom_capability_detect(self): if not self.get_presence(): self.dom_supported = False @@ -300,28 +316,30 @@ def _dom_capability_detect(self): # in SFF-8636 dom capability definitions evolving with the versions. qsfp_dom_capability_raw = self._read_eeprom_specific_bytes((offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) if qsfp_dom_capability_raw is not None: - qsfp_version_compliance_raw = self._read_eeprom_specific_bytes(QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_OFFSET) + qsfp_version_compliance_raw = self._read_eeprom_specific_bytes(QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH) qsfp_version_compliance = int(qsfp_version_compliance_raw[0], 16) - qspf_dom_capability = int(qsfp_dom_capability_raw[0], 16) + dom_capability = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) if qsfp_version_compliance >= 0x08: - self.dom_temp_supported = (qspf_dom_capability & 0x20 != 0) - self.dom_volt_supported = (qspf_dom_capability & 0x10 != 0) - self.dom_rx_power_supported = (qspf_dom_capability & 0x08 != 0) - self.dom_tx_power_supported = (qspf_dom_capability & 0x04 != 0) + self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On' + self.dom_volt_supported = dom_capability['data']['Voltage_support']['value'] == 'On' + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' + self.dom_tx_power_supported = dom_capability['data']['Tx_power_support']['value'] == 'On' else: self.dom_temp_supported = True self.dom_volt_supported = True - self.dom_rx_power_supported = (qspf_dom_capability & 0x08 != 0) + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' self.dom_tx_power_supported = True self.dom_supported = True self.calibration = 1 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None qsfp_option_value_raw = self._read_eeprom_specific_bytes(QSFP_OPTION_VALUE_OFFSET, QSFP_OPTION_VALUE_WIDTH) if qsfp_option_value_raw is not None: - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return None - self.optional_capability = sfpd_obj.parse_option_params(qsfp_option_value_raw, 0) - self.dom_tx_disable_supported = self.optional_capability['data']['TxDisable']['value'] == 'On' + optional_capability = sfpd_obj.parse_option_params(qsfp_option_value_raw, 0) + self.dom_tx_disable_supported = optional_capability['data']['TxDisable']['value'] == 'On' + dom_status_indicator = sfpd_obj.parse_dom_status_indicator(qsfp_version_compliance_raw, 1) + self.qsfp_page3_available = dom_status_indicator['data']['FlatMem']['value'] == 'Off' else: self.dom_supported = False self.dom_temp_supported = False @@ -329,6 +347,7 @@ def _dom_capability_detect(self): self.dom_rx_power_supported = False self.dom_tx_power_supported = False self.calibration = 0 + self.qsfp_page3_available = False elif self.sfp_type == "SFP": sfpi_obj = sff8472InterfaceId() if sfpi_obj is None: @@ -362,6 +381,7 @@ def _dom_capability_detect(self): self.dom_rx_power_supported = False self.dom_tx_power_supported = False + def _convert_string_to_num(self, value_str): if "-inf" in value_str: return 'N/A' @@ -382,6 +402,7 @@ def _convert_string_to_num(self, value_str): else: return 'N/A' + def get_transceiver_info(self): """ Retrieves transceiver info of this SFP @@ -563,6 +584,7 @@ def get_transceiver_info(self): return transceiver_info_dict + def get_transceiver_bulk_status(self): """ Retrieves transceiver bulk status of this SFP @@ -689,6 +711,143 @@ def get_transceiver_bulk_status(self): return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict = {} + + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if self.sfp_type == OSFP_TYPE: + pass + + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported or not self.qsfp_page3_available: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = QSFP_MODULE_UPPER_PAGE3_START + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes((offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is None: + return transceiver_dom_threshold_info_dict + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + + else: + offset = SFP_MODULE_ADDRA2_OFFSET + + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = sff8472Dom(None, self.calibration) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict + + def get_reset_status(self): """ Retrieves the reset status of SFP @@ -731,6 +890,7 @@ def get_reset_status(self): else: return False + def get_rx_los(self): """ Retrieves the RX LOS (lost-of-signal) status of SFP @@ -764,6 +924,7 @@ def get_rx_los(self): return None return rx_los_list + def get_tx_fault(self): """ Retrieves the TX fault status of SFP @@ -797,6 +958,7 @@ def get_tx_fault(self): return None return tx_fault_list + def get_tx_disable(self): """ Retrieves the tx_disable status of this SFP @@ -833,6 +995,7 @@ def get_tx_disable(self): return None return tx_disable_list + def get_tx_disable_channel(self): """ Retrieves the TX disabled channels in this SFP @@ -852,6 +1015,7 @@ def get_tx_disable_channel(self): tx_disabled |= 1 << i return tx_disabled + def get_lpmode(self): """ Retrieves the lpmode (low power mode) status of this SFP @@ -882,6 +1046,7 @@ def get_lpmode(self): else: return NotImplementedError + def get_power_override(self): """ Retrieves the power-override status of this SFP @@ -902,6 +1067,7 @@ def get_power_override(self): else: return NotImplementedError + def get_temperature(self): """ Retrieves the temperature of this SFP @@ -944,6 +1110,7 @@ def get_temperature(self): else: return None + def get_voltage(self): """ Retrieves the supply voltage of this SFP @@ -986,7 +1153,8 @@ def get_voltage(self): return voltage else: return None - + + def get_tx_bias(self): """ Retrieves the TX bias current of this SFP @@ -1031,7 +1199,8 @@ def get_tx_bias(self): return None return tx_bias_list - + + def get_rx_power(self): """ Retrieves the received optical power for this SFP @@ -1085,7 +1254,8 @@ def get_rx_power(self): else: return None return rx_power_list - + + def get_tx_power(self): """ Retrieves the TX power of this SFP @@ -1138,7 +1308,8 @@ def get_tx_power(self): else: return None return tx_power_list - + + def reset(self): """ Reset SFP and return all user module settings to their default state. @@ -1174,6 +1345,7 @@ def reset(self): self._close_sdk() return rc == SXD_STATUS_SUCCESS + def _write_i2c_via_mcia(self, page, i2caddr, address, data, mask): handle = self._open_sdk() if handle is None: @@ -1208,6 +1380,7 @@ def _write_i2c_via_mcia(self, page, i2caddr, address, data, mask): self._close_sdk() return rc == SXD_STATUS_SUCCESS + def tx_disable(self, tx_disable): """ Disable SFP TX for all channels @@ -1251,6 +1424,7 @@ def tx_disable(self, tx_disable): else: return NotImplementedError + def tx_disable_channel(self, channel, disable): """ Sets the tx_disable for specified SFP channels @@ -1280,9 +1454,11 @@ def tx_disable_channel(self, channel, disable): else: return NotImplementedError + def is_nve(self, port): return (port & NVE_MASK) != 0 + def is_port_admin_status_up(self, log_port): oper_state_p = new_sx_port_oper_state_t_p() admin_state_p = new_sx_port_admin_state_t_p() @@ -1296,10 +1472,12 @@ def is_port_admin_status_up(self, log_port): else: return False + def set_port_admin_status_by_log_port(self, log_port, admin_status): rc = sx_api_port_state_set(self.sdk_handle, log_port, admin_status) assert rc == SX_STATUS_SUCCESS, "sx_api_port_state_set failed, rc = %d" % rc + # Get all the ports related to the sfp, if port admin status is up, put it to list def get_log_ports(self): port_attributes_list = new_sx_port_attributes_t_arr(SX_PORT_ATTR_ARR_SIZE) @@ -1320,6 +1498,7 @@ def get_log_ports(self): return log_port_list + def _set_sfp_admin_status_raw(self, admin_status): # Get PMAOS pmaos = ku_pmaos_reg() @@ -1343,6 +1522,7 @@ def _set_sfp_admin_status_raw(self, admin_status): rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc + def _set_lpmode_raw(self, lpmode): # Get PMMP pmmp = ku_pmmp_reg() @@ -1364,6 +1544,7 @@ def _set_lpmode_raw(self, lpmode): return rc + def set_lpmode(self, lpmode): """ Sets the lpmode (low power mode) of SFP @@ -1396,6 +1577,7 @@ def set_lpmode(self, lpmode): self._close_sdk() return False + def set_power_override(self, power_override, power_set): """ Sets SFP power level using power_override and power_set From cb2e01d503aefbcf89e3c1d0d623d3842d575cc8 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Thu, 21 Nov 2019 10:58:21 -0800 Subject: [PATCH 0178/1427] [submodule]: Update sairedis/swss/utilities (#3786) sairedis: * [SAI] Update SAI submodule to v1.5.1 (#532) * Cleanup Makefile.am from BFN specific code (#530) * [vs] Implement indices for debug counters in VS (#531) * Enable FastReboot if we have key "FAST_REBOOT|system" in State db (#529) * [flex_counter] Add sairedis support for drop counters (#520) swss: * [orchagent] Add swss support for drop counters (#1075) * [orchagent] warning fixes for 32bit arch compilation (#1129) * [utilities] Create utility classes for interacting with flex counters (#1093) * [portsorch] add support to set mac-address learning attribute on bridge-port (#809) * Fix traceroute issue (#1113) utilities: * Add CLI support for configurable drop counters (#688) * Revert "SONiC Management Framework Release 1.0 (#659)" (#741) * SONiC Management Framework Release 1.0 (#659) Signed-off-by: Danny Allen --- src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- src/sonic-utilities | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index afe2a0d29299..667f74427497 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit afe2a0d29299128d314b93c9e4726e62d3116948 +Subproject commit 667f74427497b9b188b949269a29791642f81d17 diff --git a/src/sonic-swss b/src/sonic-swss index f3547983a1e2..c3b8fe10b156 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit f3547983a1e2c67bdacb4e87593e65f20b483d8e +Subproject commit c3b8fe10b1568022fa025ef4be9cb063bfe49df4 diff --git a/src/sonic-utilities b/src/sonic-utilities index be337d4f09c9..587e630ace4f 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit be337d4f09c9fc901c85d2d615a3cdebbc039a33 +Subproject commit 587e630ace4f5e6d2df1d0fbfa112aef19283d3a From bad57cc51afa8881373a8fe6d4c1e02b2376f8ca Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Thu, 21 Nov 2019 12:54:28 -0800 Subject: [PATCH 0179/1427] [minigraph.py] Generate items needed by streaming telemetry service (#3759) --- src/sonic-config-engine/minigraph.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 7799f3367d95..a82cd4c48582 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -627,7 +627,13 @@ def parse_xml(filename, platform=None, port_config_file=None): 'hostname': hostname, 'hwsku': hwsku, 'type': current_device['type'] - }} + }, + 'x509': { + 'server_crt': '/etc/sonic/telemetry/streamingtelemetryserver.cer', + 'server_key': '/etc/sonic/telemetry/streamingtelemetryclient.key', + 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' + } + } results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range @@ -806,6 +812,13 @@ def parse_xml(filename, platform=None, port_config_file=None): 'status': 'enabled' } } + results['TELEMETRY'] = { + 'gnmi': { + 'client_auth': 'true', + 'port': '50051', + 'log_level': '2' + } + } # Do not configure the minigraph's mirror session, which is currently unused # mirror_sessions = {} From 3470000e3a12d265f04ad7affe7a93cc0a6680a1 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 21 Nov 2019 16:14:32 -0800 Subject: [PATCH 0180/1427] [sonic-slave]: Remove `base` from image name, rename folder to prevent user confliction (jessie) (#3790) --- Makefile.work | 4 ++-- {sonic-slave => sonic-slave-jessie}/Dockerfile.j2 | 0 {sonic-slave => sonic-slave-jessie}/Dockerfile.user | 2 +- {sonic-slave => sonic-slave-jessie}/sonic-jenkins-id_rsa.pub | 0 sonic-slave-stretch/Dockerfile.user | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename {sonic-slave => sonic-slave-jessie}/Dockerfile.j2 (100%) rename {sonic-slave => sonic-slave-jessie}/Dockerfile.user (93%) rename {sonic-slave => sonic-slave-jessie}/sonic-jenkins-id_rsa.pub (100%) diff --git a/Makefile.work b/Makefile.work index 37ee2e11529d..b81ac591246f 100644 --- a/Makefile.work +++ b/Makefile.work @@ -74,11 +74,11 @@ endif ifeq ($(BLDENV), stretch) SLAVE_DIR = sonic-slave-stretch else -SLAVE_DIR = sonic-slave +SLAVE_DIR = sonic-slave-jessie endif SLAVE_BASE_TAG = $(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) j2 $(SLAVE_DIR)/Dockerfile.j2 > $(SLAVE_DIR)/Dockerfile && sha1sum $(SLAVE_DIR)/Dockerfile | awk '{print substr($$1,0,11);}') SLAVE_TAG = $(shell cat $(SLAVE_DIR)/Dockerfile.user $(SLAVE_DIR)/Dockerfile | sha1sum | awk '{print substr($$1,0,11);}') -SLAVE_BASE_IMAGE = $(SLAVE_DIR)-base +SLAVE_BASE_IMAGE = $(SLAVE_DIR) SLAVE_IMAGE = $(SLAVE_BASE_IMAGE)-$(USER) OVERLAY_MODULE_CHECK := \ diff --git a/sonic-slave/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 similarity index 100% rename from sonic-slave/Dockerfile.j2 rename to sonic-slave-jessie/Dockerfile.j2 diff --git a/sonic-slave/Dockerfile.user b/sonic-slave-jessie/Dockerfile.user similarity index 93% rename from sonic-slave/Dockerfile.user rename to sonic-slave-jessie/Dockerfile.user index 253475b21878..37dd7256c4e5 100644 --- a/sonic-slave/Dockerfile.user +++ b/sonic-slave-jessie/Dockerfile.user @@ -1,5 +1,5 @@ ARG slave_base_tag_ref=latest -FROM sonic-slave-base:${slave_base_tag_ref} +FROM sonic-slave-jessie:${slave_base_tag_ref} # Add user ARG user diff --git a/sonic-slave/sonic-jenkins-id_rsa.pub b/sonic-slave-jessie/sonic-jenkins-id_rsa.pub similarity index 100% rename from sonic-slave/sonic-jenkins-id_rsa.pub rename to sonic-slave-jessie/sonic-jenkins-id_rsa.pub diff --git a/sonic-slave-stretch/Dockerfile.user b/sonic-slave-stretch/Dockerfile.user index 1e5b91414393..87e4d9568bb1 100644 --- a/sonic-slave-stretch/Dockerfile.user +++ b/sonic-slave-stretch/Dockerfile.user @@ -1,5 +1,5 @@ ARG slave_base_tag_ref=latest -FROM sonic-slave-stretch-base:${slave_base_tag_ref} +FROM sonic-slave-stretch:${slave_base_tag_ref} # Add user ARG user From 8a7c1300c24aa6446dc062918a00ce6f9a04bbe8 Mon Sep 17 00:00:00 2001 From: byu343 Date: Thu, 21 Nov 2019 16:21:08 -0800 Subject: [PATCH 0181/1427] [devices]: Fix the clock setting on arista 7280 (#3788) * Fix serdes setting for B0/B1 revision chip on 7280 --- .../jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm | 14 +++++++++----- .../jr2-a7280cr3-32p4-40x100G.config.bcm | 14 +++++++++----- src/sonic-device-data/tests/config_checker | 2 +- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm index 3c0a0ee443a4..3d89e2b41b4a 100644 --- a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm @@ -277,11 +277,15 @@ bcm_stat_interval.BCM8869X=1000 mem_cache_enable_ecc.BCM8869X=1 mem_cache_enable_parity.BCM8869X=1 -serdes_nif_clk_freq_in.BCM8869X=2 -serdes_nif_clk_freq_out.BCM8869X=1 - -serdes_fabric_clk_freq_in.BCM8869X=2 -serdes_fabric_clk_freq_out.BCM8869X=1 +serdes_nif_clk_freq_in.BCM8869X_A0=2 +serdes_nif_clk_freq_out.BCM8869X_A0=1 +serdes_fabric_clk_freq_in.BCM8869X_A0=2 +serdes_fabric_clk_freq_out.BCM8869X_A0=1 + +serdes_nif_clk_freq_in.BCM8869X=1 +serdes_nif_clk_freq_out.BCM8869X=bypass +serdes_fabric_clk_freq_in.BCM8869X=1 +serdes_fabric_clk_freq_out.BCM8869X=bypass dram_phy_tune_mode_on_init.BCM8869X=RUN_TUNE diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm index 4787dc7db709..654a4d8f158f 100644 --- a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm @@ -281,11 +281,15 @@ bcm_stat_interval.BCM8869X=1000 mem_cache_enable_ecc.BCM8869X=1 mem_cache_enable_parity.BCM8869X=1 -serdes_nif_clk_freq_in.BCM8869X=2 -serdes_nif_clk_freq_out.BCM8869X=1 - -serdes_fabric_clk_freq_in.BCM8869X=2 -serdes_fabric_clk_freq_out.BCM8869X=1 +serdes_nif_clk_freq_in.BCM8869X_A0=2 +serdes_nif_clk_freq_out.BCM8869X_A0=1 +serdes_fabric_clk_freq_in.BCM8869X_A0=2 +serdes_fabric_clk_freq_out.BCM8869X_A0=1 + +serdes_nif_clk_freq_in.BCM8869X=1 +serdes_nif_clk_freq_out.BCM8869X=bypass +serdes_fabric_clk_freq_in.BCM8869X=1 +serdes_fabric_clk_freq_out.BCM8869X=bypass dram_phy_tune_mode_on_init.BCM8869X=RUN_TUNE diff --git a/src/sonic-device-data/tests/config_checker b/src/sonic-device-data/tests/config_checker index 6d95c13efc7c..6cb4d029be58 100755 --- a/src/sonic-device-data/tests/config_checker +++ b/src/sonic-device-data/tests/config_checker @@ -31,7 +31,7 @@ def check_file(file_name): p = line.split("=", 1)[0] # Remove trailing chip name "bcm8869x" - p = re.sub(r"\.bcm8869x(_adapter)?$", "", p) + p = re.sub(r"\.bcm8869x(_adapter|_[a-z]\d)?$", "", p) # Remove trailing unit ".$" p = re.sub(r"\.[0-9]+$", '', p) # Remove trailing port name From 643ef82a2ff88302b0217811052ffd33f0a6a645 Mon Sep 17 00:00:00 2001 From: Tyler Li Date: Fri, 22 Nov 2019 09:49:31 +0800 Subject: [PATCH 0182/1427] [config] supplement loopback interface in mimigraph (#3792) --- src/sonic-config-engine/minigraph.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index a82cd4c48582..443d96c31161 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -573,7 +573,7 @@ def parse_xml(filename, platform=None, port_config_file=None): vlan_members = None pcs = None mgmt_intf = None - lo_intf = None + lo_intfs = None neighbors = None devices = None hostname = None @@ -656,7 +656,10 @@ def parse_xml(filename, platform=None, port_config_file=None): if alias in port_speeds_default: results['MGMT_PORT'][name]['speed'] = port_speeds_default[alias] results['MGMT_INTERFACE'][(name, key[1])] = mgmt_intf[key] - results['LOOPBACK_INTERFACE'] = lo_intfs + results['LOOPBACK_INTERFACE'] = {} + for lo_intf in lo_intfs: + results['LOOPBACK_INTERFACE'][lo_intf] = lo_intfs[lo_intf] + results['LOOPBACK_INTERFACE'][lo_intf[0]] = {} results['MGMT_VRF_CONFIG'] = mvrf phyport_intfs = {} From 6864ed58866dc1cd6b6bd95c3de58404edb5f220 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Fri, 22 Nov 2019 00:34:17 -0800 Subject: [PATCH 0183/1427] [sairedis] Submodule update for sairedis (#3801) - [syncd] Fix off-by-one error for attribute enum values query (#536) - Add support for remove hostif when using tap device (#533) Signed-off-by: Danny Allen --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 667f74427497..54d2864a2261 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 667f74427497b9b188b949269a29791642f81d17 +Subproject commit 54d2864a2261e518f969cb0bf7e2569fe4825ea7 From a5423357d55ea9d81f04b144b64ea38ee4d84486 Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 22 Nov 2019 10:04:56 -0800 Subject: [PATCH 0184/1427] [submodule]: update sonic-sairedis (#3804) * 5337490 2019-11-22 | Send port status notification when creating hostif interface (#535) [Kamil Cudnik] Signed-off-by: Guohan Lu --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 54d2864a2261..533749062f63 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 54d2864a2261e518f969cb0bf7e2569fe4825ea7 +Subproject commit 533749062f638f74ebc09c4bd0a5162b2c575564 From a73eb66546900aeea9dc451b6f5a509cfdd8d654 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 22 Nov 2019 11:07:36 -0800 Subject: [PATCH 0185/1427] [docker-fpm-frr]: Refactor bgpcfgd (#3789) --- dockers/docker-fpm-frr/bgpcfgd | 383 +++++++++++++++++++++++---------- 1 file changed, 266 insertions(+), 117 deletions(-) diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index b98a3f7ad45a..120e07fcdbe2 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -8,11 +8,11 @@ import syslog import signal import traceback import os -import shutil import tempfile import json from collections import defaultdict from pprint import pprint +from pprint import pformat import jinja2 import netaddr @@ -34,6 +34,7 @@ def run_command(command, shell=False): return p.returncode, stdout, stderr + class TemplateFabric(object): def __init__(self): j2_template_paths = ['/usr/share/sonic/templates'] @@ -76,130 +77,18 @@ class TemplateFabric(object): return addr.version == 6 -class BGPConfigManager(object): - def __init__(self, daemon): - self.bgp_asn = None - self.meta = None - self.neig_meta = {} - self.bgp_messages = [] - self.peers = self.load_peers() # we can have bgp monitors peers here. it could be fixed by adding support for it here - fabric = TemplateFabric() - self.bgp_peer_add_template = fabric.from_file('bgpd.peer.conf.j2') - self.bgp_peer_del_template = fabric.from_string('no neighbor {{ neighbor_addr }}') - self.bgp_peer_shutdown = fabric.from_string('neighbor {{ neighbor_addr }} shutdown') - self.bgp_peer_no_shutdown = fabric.from_string('no neighbor {{ neighbor_addr }} shutdown') - daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, self.__metadata_handler) - daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME, self.__neighbor_metadata_handler) - daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, self.__bgp_handler) - - def load_peers(self): - peers = set() - command = ["vtysh", "-c", "show bgp neighbors json"] - rc, out, err = run_command(command) - if rc == 0: - js_bgp = json.loads(out) - peers = set(js_bgp.keys()) - return peers - - def __metadata_handler(self, key, op, data): - if key != "localhost" \ - or "bgp_asn" not in data \ - or self.bgp_asn == data["bgp_asn"]: - return - - # TODO add ASN update commands - - self.meta = { 'localhost': data } - self.bgp_asn = data["bgp_asn"] - self.__update_bgp() - - def __neighbor_metadata_handler(self, key, op, data): - if op == swsscommon.SET_COMMAND: - self.neig_meta[key] = data - elif op == swsscommon.DEL_COMMAND: - if key in self.neig_meta: - del self.neig_meta[key] - else: - syslog.syslog(syslog.LOG_ERR,"Can't remove key '%s' from neighbor metadata handler. The key doesn't exist" % key) - else: - syslog.syslog(syslog.LOG_ERR,"Wrong operation '%s' for neighbor metadata handler" % op) - self.__update_bgp() - - def __update_bgp(self): - cmds = [] - new_bgp_messages = [] - for key, op, data in self.bgp_messages: - if op == swsscommon.SET_COMMAND: - if key not in self.peers: - if 'name' in data and data['name'] not in self.neig_meta: - # DEVICE_NEIGHBOR_METADATA should be populated before the rendering - new_bgp_messages.append((key, op, data)) - continue - try: - txt = self.bgp_peer_add_template.render(DEVICE_METADATA=self.meta, DEVICE_NEIGHBOR_METADATA=self.neig_meta, neighbor_addr=key, bgp_session=data) - cmds.append(txt) - except: - syslog.syslog(syslog.LOG_ERR, 'Peer {}. Error in rendering the template for "SET" command {}'.format(key, data)) - else: - syslog.syslog(syslog.LOG_INFO, 'Peer {} added with attributes {}'.format(key, data)) - self.peers.add(key) - else: - # when the peer is already configured we support "shutdown/no shutdown" - # commands for the peers only - if "admin_status" in data: - if data['admin_status'] == 'up': - cmds.append(self.bgp_peer_no_shutdown.render(neighbor_addr=key)) - syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "up"'.format(key)) - elif data['admin_status'] == 'down': - cmds.append(self.bgp_peer_shutdown.render(neighbor_addr=key)) - syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "down"'.format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. has wrong attribute value attr['admin_status'] = '{}'".format(key, data['admin_status'])) - else: - syslog.syslog(syslog.LOG_INFO, "Peer {}: Can't update the peer. No 'admin_status' attribute in the request".format(key)) - elif op == swsscommon.DEL_COMMAND: - if key in self.peers: - cmds.append(self.bgp_peer_del_template.render(neighbor_addr=key)) - syslog.syslog(syslog.LOG_INFO, 'Peer {} has been removed'.format(key)) - self.peers.remove(key) - else: - syslog.syslog(syslog.LOG_WARNING, 'Peer {} is not found'.format(key)) - self.bgp_messages = new_bgp_messages - - if len(cmds) == 0: - return - - fd, tmp_filename = tempfile.mkstemp(dir='/tmp') - os.close(fd) - with open (tmp_filename, 'w') as fp: - fp.write('router bgp %s\n' % self.bgp_asn) - for cmd in cmds: - fp.write("%s\n" % cmd) - - command = ["vtysh", "-f", tmp_filename] - run_command(command) #FIXME - os.remove(tmp_filename) - - def __bgp_handler(self, key, op, data): - self.bgp_messages.append((key, op, data)) - # If ASN is not set, we just cache this message until the ASN is set. - if self.bgp_asn is not None: - self.__update_bgp() - - class Daemon(object): SELECT_TIMEOUT = 1000 - DATABASE_LIST = [ swsscommon.CONFIG_DB ] def __init__(self): - self.db_connectors = { db : swsscommon.DBConnector(db, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) for db in Daemon.DATABASE_LIST } + self.db_connectors = {} self.selector = swsscommon.Select() self.callbacks = defaultdict(lambda : defaultdict(list)) # db -> table -> [] self.subscribers = set() def add_manager(self, db, table_name, callback): - if db not in Daemon.DATABASE_LIST: - raise ValueError("database {} isn't supported. Supported '{}' only.".format(db, ",".join(Daemon.DATABASE_LIST))) + if db not in self.db_connectors: + self.db_connectors[db] = swsscommon.DBConnector(db, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) if table_name not in self.callbacks[db]: conn = self.db_connectors[db] @@ -226,6 +115,260 @@ class Daemon(object): callback(key, op, dict(fvs)) +class Directory(object): + def __init__(self): + self.data = defaultdict(dict) + self.notify = defaultdict(lambda: defaultdict(list)) + + def path_exist(self, slot, path): + if slot not in self.data: + return False + elif path == '': + return True + d = self.data[slot] + for p in path.split("/"): + if p not in d: + return False + d = d[p] + return True + + def get_path(self, slot, path): + if slot not in self.data: + return None + elif path == '': + return self.data[slot] + d = self.data[slot] + for p in path.split("/"): + if p not in d: + return None + d = d[p] + return d + + def put(self, slot, key, value): + self.data[slot][key] = value + if slot in self.notify: + for path in self.notify[slot].keys(): + if self.path_exist(slot, path): + for handler in self.notify[slot][path]: + handler() + + def get(self, slot, key): + return self.data[slot][key] + + def remove(self, slot, key): + if slot in self.data: + if key in self.data[slot]: + del self.data[slot][key] + else: + syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) + else: + syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) + + def remove_slot(self, slot, key): + if slot in self.data: + del self.data[slot] + else: + syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) + + def get_slot(self, slot): + return self.data[slot] + + def available_slot(self, slot): + return slot in self.data + + def available_deps(self, deps): + res = True + for slot, path in deps: + res = res and self.path_exist(slot, path) + return res + + def subscribe(self, deps, handler): + for slot, path in deps: + self.notify[slot][path].append(handler) + + +class Manager(object): + def __init__(self, daemon, directory, deps, database, table_name): + self.directory = directory + self.deps = deps + self.set_queue = [] + daemon.add_manager(database, table_name, self.handler) + directory.subscribe(deps, self.on_deps_change) + + def handler(self, key, op, data): + if op == swsscommon.SET_COMMAND: + if self.directory.available_deps(self.deps): + res = self.set_handler(key, data) + if not res: + self.set_queue.append((key, data)) + else: + self.set_queue.append((key, data)) + elif op == swsscommon.DEL_COMMAND: + self.del_handler(key) + else: + syslog.syslog(syslog.LOG_ERR, 'Invalid operation "%s" for key "%s"' % (op, key)) + + def on_deps_change(self): + new_queue = [] + for key, data in self.set_queue: + res = self.set_handler(key, data) + if not res: + new_queue.append((key, data)) + self.set_queue = new_queue + + def set_handler(self, key, data): + syslog.syslog(syslog.LOG_ERR, "%s wasn't implemented for %s" % (self.__name__, self.__class__)) + + def del_handler(self, key): + syslog.syslog(syslog.LOG_ERR, "%s wasn't implemented for %s" % (self.__name__, self.__class__)) + + +class BGPDeviceMetaMgr(Manager): + def __init__(self, daemon, directory): + super(BGPDeviceMetaMgr, self).__init__( + daemon, + directory, + [], + swsscommon.CONFIG_DB, + swsscommon.CFG_DEVICE_METADATA_TABLE_NAME + ) + + def set_handler(self, key, data): + if key != "localhost" or "bgp_asn" not in data: + return + if self.directory.path_exist("meta", "localhost/bgp_asn"): + bgp_asn = self.directory.get_path("meta", "localhost/bgp_asn") + if bgp_asn == data["bgp_asn"]: + return + self.directory.put("meta", key, data) + + return True + + def del_handler(self, key): + self.directory.remove("meta", key) + + +class BGPNeighborMetaMgr(Manager): + def __init__(self, daemon, directory): + super(BGPNeighborMetaMgr, self).__init__( + daemon, + directory, + [], + swsscommon.CONFIG_DB, + swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME + ) + + def set_handler(self, key, data): + self.directory.put("neigmeta", key, data) + + return True + + def del_handler(self, key): + self.directory.remove("neigmeta", key) + + +class BGPPeerMgr(Manager): + def __init__(self, daemon, directory): + super(BGPPeerMgr, self).__init__( + daemon, + directory, + [ + ("meta", "localhost/bgp_asn"), + ("neigmeta", ""), + ], + swsscommon.CONFIG_DB, + swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME + ) + self.peers = self.load_peers() + fabric = TemplateFabric() + self.templates = { + "add": fabric.from_file('bgpd.peer.conf.j2'), + "delete": fabric.from_string('no neighbor {{ neighbor_addr }}'), + "shutdown": fabric.from_string('neighbor {{ neighbor_addr }} shutdown'), + "no shutdown": fabric.from_string('no neighbor {{ neighbor_addr }} shutdown'), + } + + def set_handler(self, key, data): + if key not in self.peers: + cmd = None + neigmeta = self.directory.get_slot("neigmeta") + if 'name' in data and data["name"] not in neigmeta: + return False + try: + cmd = self.templates["add"].render( + DEVICE_METADATA=self.directory.get_slot("meta"), + DEVICE_NEIGHBOR_METADATA=neigmeta, + neighbor_addr=key, + bgp_session=data + ) + except: + syslog.syslog(syslog.LOG_ERR, 'Peer {}. Error in rendering the template for "SET" command {}'.format(key, data)) + return True + if cmd is not None: + rc = self.apply_op(cmd) + if rc: + self.peers.add(key) + syslog.syslog(syslog.LOG_INFO, 'Peer {} added with attributes {}'.format(key, data)) + else: + syslog.syslog(syslog.LOG_ERR, "Peer {} wasn't added.".format(key)) + else: + # when the peer is already configured we support "shutdown/no shutdown" + # commands for the peers only + if "admin_status" in data: + if data['admin_status'] == 'up': + rc = self.apply_op(self.templates["no shutdown"].render(neighbor_addr=key)) + if rc: + syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "up"'.format(key)) + else: + syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'up'.".format(key)) + elif data['admin_status'] == 'down': + rc = self.apply_op(self.templates["shutdown"].render(neighbor_addr=key)) + if rc: + syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "down"'.format(key)) + else: + syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'down'.".format(key)) + else: + syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. has wrong attribute value attr['admin_status'] = '{}'".format(key, data['admin_status'])) + else: + syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. No 'admin_status' attribute in the request".format(key)) + return True + + def del_handler(self, key): + if key not in self.peers: + syslog.syslog(syslog.LOG_WARNING, 'Peer {} has not been found'.format(key)) + return + cmd = self.templates["delete"].render(neighbor_addr=key) + rc = self.apply_op(cmd) + if rc: + syslog.syslog(syslog.LOG_INFO, 'Peer {} has been removed'.format(key)) + self.peers.remove(key) + else: + syslog.syslog(syslog.LOG_ERR, "Peer {} hasn't been removed".format(key)) + + def apply_op(self, cmd): + bgp_asn = self.directory.get_slot("meta")["localhost"]["bgp_asn"] + fd, tmp_filename = tempfile.mkstemp(dir='/tmp') + os.close(fd) + with open(tmp_filename, 'w') as fp: + fp.write('router bgp %s\n' % bgp_asn) + fp.write("%s\n" % cmd) + + command = ["vtysh", "-f", tmp_filename] + rc, _, _ = run_command(command) + os.remove(tmp_filename) + return rc == 0 + + @staticmethod + def load_peers(): + peers = set() + command = ["vtysh", "-c", "show bgp neighbors json"] + rc, out, err = run_command(command) + if rc == 0: + js_bgp = json.loads(out) + peers = set(js_bgp.keys()) + return peers + + def wait_for_bgpd(): # wait for 20 seconds stop_time = datetime.datetime.now() + datetime.timedelta(seconds=20) @@ -240,9 +383,15 @@ def wait_for_bgpd(): def main(): + managers = [ + BGPDeviceMetaMgr, + BGPNeighborMetaMgr, + BGPPeerMgr, + ] wait_for_bgpd() daemon = Daemon() - bgp_manager = BGPConfigManager(daemon) + directory = Directory() + manager_instanses = [ manager(daemon, directory) for manager in managers ] daemon.run() From 295b0bdc5655ff6dc8b7cdf9f4fbd21bfce31609 Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Fri, 22 Nov 2019 22:48:35 +0200 Subject: [PATCH 0186/1427] [Mellanox] Update FW/SDK: 13/29.2000.2602 and 4.3.2602 (#3796) Signed-off-by: Volodymyr Samotiy --- platform/mellanox/fw.mk | 4 ++-- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 2df1fd11cd75..9d506c1f5bdd 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,12 +11,12 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.2308 +MLNX_SPC_FW_VERSION = 13.2000.2602 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.2308 +MLNX_SPC2_FW_VERSION = 29.2000.2602 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index f4df2ccaa534..87f7a7911275 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit f4df2ccaa5342e7f3fa5a45a851ef32ea59c0654 +Subproject commit 87f7a7911275285abc63c24ba39aa4af4c4b4678 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index dee478e7d52c..73568ce84596 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.3.2308 +MLNX_SDK_VERSION = 4.3.2602 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From f943440fcbbb9a4dd76f313ea6d83109ed4f52c2 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Sat, 23 Nov 2019 00:28:40 +0200 Subject: [PATCH 0187/1427] Moved telemetry exit listener from process package into Docker (#3805) Signed-off-by: Andriy Kokhan --- rules/docker-telemetry.mk | 1 + rules/telemetry.mk | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 94920c464381..defeb4d00821 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -28,3 +28,4 @@ $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry $(DOCKER_TELEMETRY)_RUN_OPT += --net=host --privileged -t $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/telemetry.mk b/rules/telemetry.mk index af568fb5bd6f..1d903e603251 100644 --- a/rules/telemetry.mk +++ b/rules/telemetry.mk @@ -3,4 +3,3 @@ SONIC_TELEMETRY = sonic-telemetry_0.1_$(CONFIGURED_ARCH).deb $(SONIC_TELEMETRY)_SRC_PATH = $(SRC_PATH)/telemetry SONIC_DPKG_DEBS += $(SONIC_TELEMETRY) -$(SONIC_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From 351410ea8cd7e45be42ab394e138a350c241183a Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 22 Nov 2019 20:39:09 -0800 Subject: [PATCH 0188/1427] [swss.sh] When starting, call 'systemctl restart' on dependents, not (#3807) 'systemctl start' --- files/scripts/swss.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 65eaf08148a8..f54c13697753 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -85,7 +85,9 @@ start_peer_and_dependent_services() { if [[ x"$WARM_BOOT" != x"true" ]]; then /bin/systemctl start ${PEER} for dep in ${DEPENDENT}; do - /bin/systemctl start ${dep} + # Here we call `systemctl restart` on each dependent service instead of `systemctl start` to + # ensure the services actually get stopped and started in case they were not previously stopped. + /bin/systemctl restart ${dep} done fi } From 3d80afa41546fe29d6e0d45ed05a2de421d84f0d Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Fri, 22 Nov 2019 20:41:45 -0800 Subject: [PATCH 0189/1427] [swsssdk-py] submodule update for sonic-py-swsssdk (#3808) update multiDB changes in sonic-py-swsssdk, including: *[multi-DB] Part 4: add sonic-db-cli to replace redis-cli (#54) *[multi-DB] Part 3: Python API changes (#52) *remove SonicV2Connector which is not used any more (#53) --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 4cee38534919..bc3964b788c3 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 4cee38534919e34f407363ac3ab5f31b4d09be6d +Subproject commit bc3964b788c3a4a45f2b359a5df5934ecdee84c2 From d44cc30191043be64d27403eb53ab1f46fda92eb Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 22 Nov 2019 20:43:44 -0800 Subject: [PATCH 0190/1427] [docker-fpm-frr]: Enable sending ipv6 prefixes over ipv4 BGPMON session (#3799) * Enable ipv6 prefixes over ipv4 BGPMON session --- dockers/docker-fpm-frr/bgpd.conf.default.j2 | 21 +++++++++++-------- .../tests/sample_output/bgpd_frr.conf | 21 +++++++++++-------- .../tests/sample_output/frr.conf | 21 +++++++++++-------- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index b53e5dff6762..e12782b035aa 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -24,9 +24,9 @@ route-map TO_BGP_PEER_V4 permit 100 route-map TO_BGP_PEER_V6 permit 100 ! {% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} -route-map FROM_BGPMON_V4 deny 10 +route-map FROM_BGPMON deny 10 ! -route-map TO_BGPMON_V4 permit 10 +route-map TO_BGPMON permit 10 ! {% endif %} ! @@ -136,21 +136,24 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endblock bgp_peers_with_range %} {% block bgp_monitors %} {% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} - neighbor BGPMON_V4 peer-group + neighbor BGPMON peer-group {% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} {% if prefix | ipv4 and name == 'Loopback0' %} - neighbor BGPMON_V4 update-source {{ prefix | ip }} + neighbor BGPMON update-source {{ prefix | ip }} {% endif %} {% endfor %} - neighbor BGPMON_V4 route-map FROM_BGPMON_V4 in - neighbor BGPMON_V4 route-map TO_BGPMON_V4 out - neighbor BGPMON_V4 send-community - neighbor BGPMON_V4 maximum-prefix 1 + neighbor BGPMON route-map FROM_BGPMON in + neighbor BGPMON route-map TO_BGPMON out + neighbor BGPMON send-community + neighbor BGPMON maximum-prefix 1 {% for neighbor_addr, bgp_session in BGP_MONITORS.items() %} neighbor {{ neighbor_addr }} remote-as {{ DEVICE_METADATA['localhost']['bgp_asn'] }} - neighbor {{ neighbor_addr }} peer-group BGPMON_V4 + neighbor {{ neighbor_addr }} peer-group BGPMON neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} neighbor {{ neighbor_addr }} activate + address-family ipv6 + neighbor {{ neighbor_addr }} activate + exit-address-family {% endfor %} {% endif %} {% endblock bgp_monitors %} diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf index 3a8abf050b45..566d6384fcfd 100644 --- a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf @@ -31,9 +31,9 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! -route-map FROM_BGPMON_V4 deny 10 +route-map FROM_BGPMON deny 10 ! -route-map TO_BGPMON_V4 permit 10 +route-map TO_BGPMON permit 10 ! ! route-map ISOLATE permit 10 @@ -73,14 +73,17 @@ router bgp 65100 neighbor PEER_V6 soft-reconfiguration inbound neighbor PEER_V6 route-map TO_BGP_PEER_V6 out exit-address-family - neighbor BGPMON_V4 peer-group - neighbor BGPMON_V4 update-source 10.1.0.32 - neighbor BGPMON_V4 route-map FROM_BGPMON_V4 in - neighbor BGPMON_V4 route-map TO_BGPMON_V4 out - neighbor BGPMON_V4 send-community - neighbor BGPMON_V4 maximum-prefix 1 + neighbor BGPMON peer-group + neighbor BGPMON update-source 10.1.0.32 + neighbor BGPMON route-map FROM_BGPMON in + neighbor BGPMON route-map TO_BGPMON out + neighbor BGPMON send-community + neighbor BGPMON maximum-prefix 1 neighbor 10.20.30.40 remote-as 65100 - neighbor 10.20.30.40 peer-group BGPMON_V4 + neighbor 10.20.30.40 peer-group BGPMON neighbor 10.20.30.40 description BGPMonitor neighbor 10.20.30.40 activate + address-family ipv6 + neighbor 10.20.30.40 activate + exit-address-family !! diff --git a/src/sonic-config-engine/tests/sample_output/frr.conf b/src/sonic-config-engine/tests/sample_output/frr.conf index edcf0939a03f..47855ce7c841 100644 --- a/src/sonic-config-engine/tests/sample_output/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/frr.conf @@ -63,9 +63,9 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! -route-map FROM_BGPMON_V4 deny 10 +route-map FROM_BGPMON deny 10 ! -route-map TO_BGPMON_V4 permit 10 +route-map TO_BGPMON permit 10 ! ! route-map ISOLATE permit 10 @@ -105,14 +105,17 @@ router bgp 65100 neighbor PEER_V6 soft-reconfiguration inbound neighbor PEER_V6 route-map TO_BGP_PEER_V6 out exit-address-family - neighbor BGPMON_V4 peer-group - neighbor BGPMON_V4 update-source 10.1.0.32 - neighbor BGPMON_V4 route-map FROM_BGPMON_V4 in - neighbor BGPMON_V4 route-map TO_BGPMON_V4 out - neighbor BGPMON_V4 send-community - neighbor BGPMON_V4 maximum-prefix 1 + neighbor BGPMON peer-group + neighbor BGPMON update-source 10.1.0.32 + neighbor BGPMON route-map FROM_BGPMON in + neighbor BGPMON route-map TO_BGPMON out + neighbor BGPMON send-community + neighbor BGPMON maximum-prefix 1 neighbor 10.20.30.40 remote-as 65100 - neighbor 10.20.30.40 peer-group BGPMON_V4 + neighbor 10.20.30.40 peer-group BGPMON neighbor 10.20.30.40 description BGPMonitor neighbor 10.20.30.40 activate + address-family ipv6 + neighbor 10.20.30.40 activate + exit-address-family !! From f558f170bb5fcf48a0fe5e80685c7f2f9ba984ca Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Sat, 23 Nov 2019 12:44:32 +0800 Subject: [PATCH 0191/1427] [nephos] upgrade Nephos SAI to version 06a67d (#3793) [Nephos SAI] upgrade Nephos SAI to version 06a67d --- platform/nephos/sai.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/nephos/sai.mk b/platform/nephos/sai.mk index edaa245cf5ad..5f7c4a23ae95 100644 --- a/platform/nephos/sai.mk +++ b/platform/nephos/sai.mk @@ -1,6 +1,6 @@ SDK_VERSION = 3.0.0 SAI_VERSION = 1.5.0 -SAI_COMMIT_ID = 426624 +SAI_COMMIT_ID = 06a67d # Place here URL where SAI deb exist NEPHOS_SAI_DEB_LOCAL_URL = From 8d4516ca3d7e43f19a0d1a17a6849a600c1eb957 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 23 Nov 2019 12:30:22 -0800 Subject: [PATCH 0192/1427] [kvm]: increase mem to 3G to avoid OOM during onie installation (#3811) Signed-off-by: Guohan Lu --- build_image.sh | 2 +- build_kvm_image.sh => scripts/build_kvm_image.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename build_kvm_image.sh => scripts/build_kvm_image.sh (99%) diff --git a/build_image.sh b/build_image.sh index 3084a4a2bd5d..9635201ae067 100755 --- a/build_image.sh +++ b/build_image.sh @@ -96,7 +96,7 @@ elif [ "$IMAGE_TYPE" = "kvm" ]; then generate_onie_installer_image - SONIC_USERNAME=$USERNAME PASSWD=$PASSWORD sudo -E ./build_kvm_image.sh $KVM_IMAGE_DISK $onie_recovery_image $OUTPUT_ONIE_IMAGE $KVM_IMAGE_DISK_SIZE + SONIC_USERNAME=$USERNAME PASSWD=$PASSWORD sudo -E ./scripts/build_kvm_image.sh $KVM_IMAGE_DISK $onie_recovery_image $OUTPUT_ONIE_IMAGE $KVM_IMAGE_DISK_SIZE if [ $? -ne 0 ]; then echo "Error : build kvm image failed" diff --git a/build_kvm_image.sh b/scripts/build_kvm_image.sh similarity index 99% rename from build_kvm_image.sh rename to scripts/build_kvm_image.sh index bc0f54e12d5c..a8ae21c9777a 100755 --- a/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -4,7 +4,7 @@ # # SPDX-License-Identifier: GPL-2.0 -MEM=2048 +MEM=3072 DISK=$1 ONIE_RECOVERY_ISO=$2 INSTALLER=$3 From 65f7da87a7c71dbd69e858a1f4b62fab285f3347 Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Sat, 23 Nov 2019 12:30:56 -0800 Subject: [PATCH 0193/1427] [telemetry.sh] Fix string null check with special characters by adding quotes (#3810) * adding quotes for string comparison with special characters * Update dockers/docker-sonic-telemetry/telemetry.sh Co-Authored-By: Joe LeVeque * Update dockers/docker-sonic-telemetry/telemetry.sh Co-Authored-By: Joe LeVeque --- dockers/docker-sonic-telemetry/telemetry.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 053b1dae6ead..8cfd8a531cca 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -7,7 +7,7 @@ TELEMETRY=`sonic-cfggen -d -v 'TELEMETRY.keys() | join(" ") if TELEMETRY'` TELEMETRY_ARGS=" -logtostderr" -if [ ! -z $X509 ]; then +if [ -n "$X509" ]; then SERVER_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']"` SERVER_KEY=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']"` if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then @@ -19,7 +19,7 @@ else TELEMETRY_ARGS+=" --insecure" fi -if [ ! -z $X509 ]; then +if [ -n "$X509" ]; then CA_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']"` if [ ! -z $CA_CRT ]; then TELEMETRY_ARGS+=" --ca_crt $CA_CRT" @@ -47,5 +47,3 @@ else fi exec /usr/sbin/telemetry ${TELEMETRY_ARGS} - - From 45e13b9929d6bd0e86942b52263315380bea14ba Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Sat, 23 Nov 2019 12:31:23 -0800 Subject: [PATCH 0194/1427] [sonic-telemetry]: correcting server key name in configdb (#3809) --- src/sonic-config-engine/minigraph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 443d96c31161..3ba6362c6ff0 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -630,7 +630,7 @@ def parse_xml(filename, platform=None, port_config_file=None): }, 'x509': { 'server_crt': '/etc/sonic/telemetry/streamingtelemetryserver.cer', - 'server_key': '/etc/sonic/telemetry/streamingtelemetryclient.key', + 'server_key': '/etc/sonic/telemetry/streamingtelemetryserver.key', 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' } } From 62a7846960797204600bfd86003872e651cb174b Mon Sep 17 00:00:00 2001 From: padmanarayana Date: Sun, 24 Nov 2019 15:21:43 -0800 Subject: [PATCH 0195/1427] [sFlow]: Upgrade hsflowd to 2.0.26-1 (#3812) --- rules/sflow.mk | 4 ++-- src/sflow/hsflowd/Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rules/sflow.mk b/rules/sflow.mk index 4366e3479734..f267353c0f93 100644 --- a/rules/sflow.mk +++ b/rules/sflow.mk @@ -1,7 +1,7 @@ # host-sflow package -HSFLOWD_VERSION = 2.0.25 -HSFLOWD_SUBVERSION = 4 +HSFLOWD_VERSION = 2.0.26 +HSFLOWD_SUBVERSION = 1 export HSFLOWD_VERSION HSFLOWD_SUBVERSION HSFLOWD = hsflowd_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb diff --git a/src/sflow/hsflowd/Makefile b/src/sflow/hsflowd/Makefile index f0ff92a7af62..0a8094e3b695 100644 --- a/src/sflow/hsflowd/Makefile +++ b/src/sflow/hsflowd/Makefile @@ -10,7 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git clone https://github.com/sflow/host-sflow pushd ./host-sflow - git checkout -b sflow tags/v2.0.25-4 + git checkout -b sflow tags/v2.0.26-1 # Apply patch series stg init From 4ae1f7069f10532149d45ee01c540eb6efd0d38c Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 25 Nov 2019 08:32:55 -0800 Subject: [PATCH 0196/1427] Revert "[swsssdk-py] submodule update for sonic-py-swsssdk (#3808)" (#3816) This reverts commit 3d80afa41546fe29d6e0d45ed05a2de421d84f0d. --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index bc3964b788c3..4cee38534919 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit bc3964b788c3a4a45f2b359a5df5934ecdee84c2 +Subproject commit 4cee38534919e34f407363ac3ab5f31b4d09be6d From 57728c5c8bf9013fe67f59eace42450b2e6fbe39 Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 25 Nov 2019 09:00:47 -0800 Subject: [PATCH 0197/1427] [docker-ptf]: add ethtool and telnet package in ptf (#3815) --- dockers/docker-ptf/Dockerfile.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index deb1892959e6..326df49d9764 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -29,10 +29,12 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / && apt-get install -y \ openssh-server \ vim \ + telnet \ net-tools \ traceroute \ lsof \ tcpdump \ + ethtool \ unzip \ pkg-config \ binutils \ From 67fc68513ee784e12e4588f7eb6c8f51135bd16b Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Mon, 25 Nov 2019 13:02:00 -0800 Subject: [PATCH 0198/1427] [Services] Restart Sflow service upon unexpected critical process exit. (#3751) Signed-off-by: Yong Zhao --- dockers/docker-sflow/Dockerfile.j2 | 2 ++ dockers/docker-sflow/critical_processes | 1 + dockers/docker-sflow/supervisord.conf | 6 ++++++ files/build_templates/sflow.service.j2 | 4 ++++ rules/docker-sflow.mk | 2 +- 5 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 dockers/docker-sflow/critical_processes diff --git a/dockers/docker-sflow/Dockerfile.j2 b/dockers/docker-sflow/Dockerfile.j2 index e88789fb6992..75da64e02e4d 100644 --- a/dockers/docker-sflow/Dockerfile.j2 +++ b/dockers/docker-sflow/Dockerfile.j2 @@ -29,5 +29,7 @@ RUN sed -ri '/^DAEMON_ARGS=""/c DAEMON_ARGS="-c /var/log/hsflowd.crash"' /etc/in COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sflow/critical_processes b/dockers/docker-sflow/critical_processes new file mode 100644 index 000000000000..5b24e2d8e1da --- /dev/null +++ b/dockers/docker-sflow/critical_processes @@ -0,0 +1 @@ +sflowmgrd diff --git a/dockers/docker-sflow/supervisord.conf b/dockers/docker-sflow/supervisord.conf index e4f9259712b5..50986f197d88 100644 --- a/dockers/docker-sflow/supervisord.conf +++ b/dockers/docker-sflow/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/files/build_templates/sflow.service.j2 b/files/build_templates/sflow.service.j2 index 3a5752412b98..de08f027adff 100644 --- a/files/build_templates/sflow.service.j2 +++ b/files/build_templates/sflow.service.j2 @@ -3,12 +3,16 @@ Description=sFlow container Requires=swss.service After=swss.service syncd.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk index 19b0f290bf99..94b568481885 100644 --- a/rules/docker-sflow.mk +++ b/rules/docker-sflow.mk @@ -32,4 +32,4 @@ $(DOCKER_SFLOW)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SFLOW)_BASE_IMAGE_FILES += psample:/usr/bin/psample $(DOCKER_SFLOW)_BASE_IMAGE_FILES += sflowtool:/usr/bin/sflowtool - +$(DOCKER_SFLOW)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From 794d459483042427a06ad602de2a7b93d24b1a49 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Mon, 25 Nov 2019 13:12:57 -0800 Subject: [PATCH 0199/1427] Update frr with latest changes from frr master (#3806) --- .gitmodules | 2 +- src/sonic-frr/frr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 08546d46073a..cfc6878c7291 100644 --- a/.gitmodules +++ b/.gitmodules @@ -47,7 +47,7 @@ [submodule "src/sonic-frr/frr"] path = src/sonic-frr/frr url = https://github.com/Azure/sonic-frr.git - branch = frr/7.1 + branch = frr/7.2 [submodule "platform/p4/p4-hlir/p4-hlir-v1.1"] path = platform/p4/p4-hlir/p4-hlir-v1.1 url = https://github.com/p4lang/p4-hlir.git diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index 514f508fc60e..d49e8f75bd46 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit 514f508fc60e0573d9863beaad8924927d373954 +Subproject commit d49e8f75bd46879c799375f304506dbc5d26230f From d3a1555f3042bd3002d3d35c371a375fe6f58af3 Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Tue, 26 Nov 2019 14:11:12 -0800 Subject: [PATCH 0200/1427] [hostcfgd] Add support to enable/disable optional features (#3653) --- files/image_config/hostcfgd/hostcfgd | 41 +++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index b32e3d8cd668..7fa8ed2ba205 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -304,6 +304,45 @@ class HostConfigDaemon: add = False self.iptables.iptables_handler(key, data, add) + + def feature_status_handler(self, key, data): + status_data = self.config_db.get_table('FEATURE') + for key in status_data.keys(): + if not key: + syslog.syslog(syslog.LOG_WARNING, "FEATURE key is missing") + return + status = status_data[key]['status'] + if not status: + syslog.syslog(syslog.LOG_WARNING, "status is missing for {}".format(key)) + return + if status == "enabled": + start_cmds=[] + start_cmds.append("sudo systemctl enable {}".format(key)) + start_cmds.append("sudo systemctl start {}".format(key)) + for cmd in start_cmds: + syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + syslog.syslog(syslog.LOG_INFO, "Feature '{}' is enabled and started".format(key)) + elif status == "disabled": + stop_cmds=[] + stop_cmds.append("sudo systemctl stop {}".format(key)) + stop_cmds.append("sudo systemctl disable {}".format(key)) + for cmd in stop_cmds: + syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(key)) + else: + syslog.syslog(syslog.LOG_ERR, "Unexpected status value '{}' for '{}'".format(status, key)) def start(self): self.config_db.subscribe('AAA', lambda table, key, data: self.aaa_handler(key, data)) @@ -311,6 +350,7 @@ class HostConfigDaemon: self.config_db.subscribe('TACPLUS', lambda table, key, data: self.tacacs_global_handler(key, data)) self.config_db.subscribe('DEVICE_METADATA', lambda table, key, data: self.hostname_handler(key, data)) self.config_db.subscribe('LOOPBACK_INTERFACE', lambda table, key, data: self.lpbk_handler(key, data)) + self.config_db.subscribe('FEATURE', lambda table, key, data: self.feature_status_handler(key, data)) self.config_db.listen() @@ -321,4 +361,3 @@ def main(): if __name__ == "__main__": main() - From 5e6f8adb2236dbd0d5aefae9a95df7d833447859 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 26 Nov 2019 16:59:45 -0800 Subject: [PATCH 0201/1427] [services] Remove explicit dependencies from dhcp_relay service file, control in swss.sh (#3823) --- files/build_templates/dhcp_relay.service.j2 | 4 ++-- files/scripts/swss.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/files/build_templates/dhcp_relay.service.j2 b/files/build_templates/dhcp_relay.service.j2 index 9106e29a41e2..d501a663feba 100644 --- a/files/build_templates/dhcp_relay.service.j2 +++ b/files/build_templates/dhcp_relay.service.j2 @@ -1,6 +1,6 @@ [Unit] Description=DHCP relay container -Requires=updategraph.service swss.service teamd.service +Requires=updategraph.service After=updategraph.service swss.service syncd.service teamd.service Before=ntp-config.service StartLimitIntervalSec=1200 @@ -15,4 +15,4 @@ Restart=always RestartSec=30 [Install] -WantedBy=multi-user.target swss.service teamd.service +WantedBy=multi-user.target diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index f54c13697753..416075d8b33a 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -2,7 +2,7 @@ SERVICE="swss" PEER="syncd" -DEPENDENT="teamd radv" +DEPENDENT="teamd radv dhcp_relay" DEBUGLOG="/tmp/swss-syncd-debug.log" LOCKFILE="/tmp/swss-syncd-lock" From 7622a30d98553288ca5cb53bb3b1eff210d40a77 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 26 Nov 2019 18:16:57 -0800 Subject: [PATCH 0202/1427] [dhcp_relay] Add extra sleep before starting relay agent processes (#3824) --- dockers/docker-dhcp-relay/start.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index 0ac5ea1a10ec..54e58dd42a07 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -16,6 +16,12 @@ if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then # lifetime of the process. /usr/bin/wait_for_intf.sh + # Allow a bit more time for interfaces to settle before starting the + # relay agent processes. + # FIXME: Remove/decrease this once we determine how to prevent future race + # conditions here. + sleep 180 + # Start all DHCP relay agent(s) supervisorctl start isc-dhcp-relay:* fi From bfa96bbce36462115974e3c1a748c02294c80920 Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Wed, 27 Nov 2019 15:35:41 -0800 Subject: [PATCH 0203/1427] Add daemon which periodically pushes process and docker stats to State DB (#3525) --- .../build_templates/sonic_debian_extension.j2 | 5 + .../procdockerstatsd/procdockerstatsd | 214 ++++++++++++++++++ .../procdockerstatsd/procdockerstatsd.service | 13 ++ 3 files changed, 232 insertions(+) create mode 100644 files/image_config/procdockerstatsd/procdockerstatsd create mode 100644 files/image_config/procdockerstatsd/procdockerstatsd.service diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 13d5432e09ea..f62ef44f0fc0 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -253,6 +253,11 @@ sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd.service $FILESYSTEM_ROOT/etc/systemd/s echo "caclmgrd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd $FILESYSTEM_ROOT/usr/bin/ +# Copy process/docker cpu/memory utilization data export daemon +sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd.service $FILESYSTEM_ROOT/etc/systemd/system/ +echo "procdockerstatsd.service" | sudo tee -a $GENERATED_SERVICE_FILE +sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd $FILESYSTEM_ROOT/usr/bin/ + # Copy process-reboot-cause service files sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause.service $FILESYSTEM_ROOT/etc/systemd/system/ echo "process-reboot-cause.service" | sudo tee -a $GENERATED_SERVICE_FILE diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd new file mode 100644 index 000000000000..66d2d45009d5 --- /dev/null +++ b/files/image_config/procdockerstatsd/procdockerstatsd @@ -0,0 +1,214 @@ +# !/usr/bin/env python +''' +procdockerstatsd +Daemon which periodically gathers process and docker statistics and pushes the data to STATE_DB +''' + +import os +import re +import subprocess +import sys +import syslog +import time +from datetime import datetime + +import swsssdk + +VERSION = '1.0' + +SYSLOG_IDENTIFIER = "procdockerstatsd" + +REDIS_HOSTIP = "127.0.0.1" + +# ========================== Syslog wrappers ========================== +def log_info(msg, also_print_to_console=False): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_INFO, msg) + syslog.closelog() + +def log_warning(msg, also_print_to_console=False): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_WARNING, msg) + syslog.closelog() + +def log_error(msg, also_print_to_console=False): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + +# ========================== ProcessDocker class ========================== +class ProcDockerStats: + + def __init__(self): + self.state_db = swsssdk.SonicV2Connector(host=REDIS_HOSTIP) + self.state_db.connect("STATE_DB") + + def run_command(self, cmd): + proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) + (stdout, stderr) = proc.communicate() + if proc.returncode != 0: + log_error("Error running command '{}'".format(cmd)) + return None + else: + return stdout + + def format_docker_cmd_output(self, cmdout): + lines = re.split("\n", cmdout) + keys = re.split(" +", lines[0]) + docker_data = dict() + docker_data_list = [] + for item in lines[1:]: + values1 = re.split(" +", item) + docker_data = dict(zip(keys, values1)) + docker_data_list.append(docker_data) + formatted_dict = self.create_docker_dict(docker_data_list) + return formatted_dict + + def format_process_cmd_output(self, cmdout): + lines = re.split("\n", cmdout) + keys = re.split(" +", lines[0]) + keylist = list(filter(None, keys)) + process_data = dict() + process_data_list = [] + for item in lines[1:]: + values1 = re.split(" +", str(item)) + # To remove extra space before UID + val = list(filter(None, values1)) + # Merging extra columns created due to space in cmd ouput + val[8:] = [''.join(val[8:])] + process_data = dict(zip(keylist, val)) + process_data_list.append(process_data) + return process_data_list + + def convert_to_bytes(self, value): + unit_value = re.search('[a-zA-Z]+', value) + value_to_convert = float(filter(str.isdigit, value)) + unit = unit_value.group(0) + UNITS_B = 'B' + UNITS_KB = 'KB' + UNITS_MB = 'MB' + UNITS_MiB = 'MiB' + UNITS_GiB = 'GiB' + if unit.lower() == UNITS_B.lower(): + return int(round(value_to_convert)) + elif unit.lower() == UNITS_KB.lower(): + value_converted = value_to_convert * 1000 + return int(round(value_converted)) + elif unit.lower() == UNITS_MB.lower(): + value_converted = value_to_convert * 1000 * 1000 + return int(round(value_converted)) + elif unit.lower() == UNITS_MiB.lower(): + value_converted = value_to_convert * 1024 * 1024 + return int(round(value_converted)) + elif unit.lower() == UNITS_GiB.lower(): + value_converted = value_to_convert * 1024 * 1024 * 1024 + return int(round(value_converted)) + + def create_docker_dict(self, dict_list): + dockerdict = {} + for row in dict_list[0:]: + cid = row.get('CONTAINER ID') + if cid: + key = 'DOCKER_STATS|' + str(cid) + dockerdict[key] = {} + dockerdict[key]['NAME'] = row.get('NAME') + + splitcol = row.get('CPU %') + cpu = re.split("%", str(splitcol)) + dockerdict[key]['CPU%'] = str(cpu[0]) + + splitcol = row.get('MEM USAGE / LIMIT') + memuse = re.split(" / ", str(splitcol)) + # converting MiB and GiB to bytes + dockerdict[key]['MEM_BYTES'] = str(self.convert_to_bytes(memuse[0])) + dockerdict[key]['MEM_LIMIT_BYTES'] = str(self.convert_to_bytes(memuse[1])) + + splitcol = row.get('MEM %') + mem = re.split("%", str(splitcol)) + dockerdict[key]['MEM%'] = str(mem[0]) + + splitcol = row.get('NET I/O') + netio = re.split(" / ", str(splitcol)) + dockerdict[key]['NET_IN_BYTES'] = str(self.convert_to_bytes(netio[0])) + dockerdict[key]['NET_OUT_BYTES'] = str(self.convert_to_bytes(netio[1])) + + splitcol = row.get('BLOCK I/O') + blockio = re.split(" / ", str(splitcol)) + dockerdict[key]['BLOCK_IN_BYTES'] = str(self.convert_to_bytes(blockio[0])) + dockerdict[key]['BLOCK_OUT_BYTES'] = str(self.convert_to_bytes(blockio[1])) + + dockerdict[key]['PIDS'] = row.get('PIDS') + return dockerdict + + def update_dockerstats_command(self): + cmd = "docker stats --no-stream -a" + data = self.run_command(cmd) + if not data: + log_error("'{}' returned null output".format(cmd)) + return False + dockerdata = self.format_docker_cmd_output(data) + if not dockerdata: + log_error("formatting for docker output failed") + return False + # wipe out all data from state_db before updating + self.state_db.delete_all_by_pattern('STATE_DB', 'DOCKER_STATS|*') + for k1,v1 in dockerdata.iteritems(): + for k2,v2 in v1.iteritems(): + self.update_state_db(k1, k2, v2) + return True + + def update_processstats_command(self): + data = self.run_command("ps -eo uid,pid,ppid,%mem,%cpu,stime,tty,time,cmd --sort -%cpu | head -1024") + processdata = self.format_process_cmd_output(data) + value = "" + # wipe out all data before updating with new values + self.state_db.delete_all_by_pattern('STATE_DB', 'PROCESS_STATS|*') + for row in processdata[0:]: + cid = row.get('PID') + if cid: + value = 'PROCESS_STATS|' + str(cid) + uid = row.get('UID') + self.update_state_db(value, 'UID', uid) + ppid = row.get('PPID') + self.update_state_db(value, 'PPID', ppid) + cpu = row.get('%CPU') + self.update_state_db(value, '%CPU', str(cpu)) + mem = row.get('%MEM') + self.update_state_db(value, '%MEM', str(mem)) + stime = row.get('STIME') + self.update_state_db(value, 'STIME', stime) + tty = row.get('TT') + self.update_state_db(value, 'TT', tty) + time = row.get('TIME') + self.update_state_db(value, 'TIME', time) + cmd = row.get('CMD') + self.update_state_db(value, 'CMD', cmd) + + def update_state_db(self, key1, key2, value2): + self.state_db.set('STATE_DB', key1, key2, value2) + + def run(self): + self.update_dockerstats_command() + datetimeobj = datetime.now() + # Adding key to store latest update time. + self.update_state_db('DOCKER_STATS|LastUpdateTime', 'lastupdate', datetimeobj) + self.update_processstats_command() + self.update_state_db('PROCESS_STATS|LastUpdateTime', 'lastupdate', datetimeobj) + +# main start +def main(): + log_info("process-docker stats daemon starting up..") + if not os.getuid() == 0: + log_error("Must be root to run process-docker daemon") + print "Error: Must be root to run process-docker daemon" + sys.exit(1) + pd = ProcDockerStats() + # Data need to be updated every 2 mins. hence adding delay of 120 seconds + while True: + pd.run() + time.sleep(120) + log_info("process-docker stats daemon exited") + +if __name__ == '__main__': + main() + diff --git a/files/image_config/procdockerstatsd/procdockerstatsd.service b/files/image_config/procdockerstatsd/procdockerstatsd.service new file mode 100644 index 000000000000..4e38c350a577 --- /dev/null +++ b/files/image_config/procdockerstatsd/procdockerstatsd.service @@ -0,0 +1,13 @@ +[Unit] +Description=Process and docker CPU/memory utilization data export daemon +Requires=database.service updategraph.service +After=database.service updategraph.service + +[Service] +Type=simple +ExecStart=/usr/bin/procdockerstatsd +Restart=Always + +[Install] +WantedBy=multi-user.target + From 5b18aa5f4d3e6685707c575031042283173fdb33 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Fri, 29 Nov 2019 04:11:58 +0530 Subject: [PATCH 0204/1427] DellEMC: Skip starting 'ledd' in pmon in DellEMC platforms (#3762) --- .../dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json | 3 +++ .../dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json | 3 +++ .../dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json | 3 +++ .../x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json | 3 +++ .../x86_64-dellemc_s5248f_c3538-r0/pmon_daemon_control.json | 3 +++ .../x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json | 3 +++ 6 files changed, 18 insertions(+) create mode 100644 device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json create mode 100644 device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json create mode 100644 device/dell/x86_64-dellemc_s5248f_c3538-r0/pmon_daemon_control.json create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json b/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json b/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json b/device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_s5248f_c3538-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} From 7a3e4972d10e6a484bf6db799b7aa212c8b7a6c4 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Sat, 30 Nov 2019 21:42:28 +0200 Subject: [PATCH 0205/1427] [barefoot][as9516] Updated Newport configuration (#3797) - Updated buffers config; - Set eth2 as CPU port; - Added systemd service file to load bf_fpga.ko Signed-off-by: Andriy Kokhan --- .../newport/buffers_defaults_t0.j2 | 10 +++++----- .../newport/buffers_defaults_t1.j2 | 10 +++++----- .../newport/switch-tna-sai.conf | 3 ++- .../configs/network/interfaces.d/eth2 | 4 ++++ .../configs/systemd/system/bfn-newport.service | 14 ++++++++++++++ .../debian/install | 1 + .../debian/postinst | 6 ++++++ 7 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/configs/network/interfaces.d/eth2 create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/configs/systemd/system/bfn-newport.service create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/debian/install create mode 100644 platform/barefoot/sonic-platform-modules-bfn-newport/debian/postinst diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 index 199f4ad135fb..33698097285e 100644 --- a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '4194304' %} -{% set ingress_lossy_pool_size = '7340032' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '7340032' %} +{% set ingress_lossless_pool_size = '23850816' %} +{% set ingress_lossy_pool_size = '36222208' %} +{% set egress_lossless_pool_size = '29482816' %} +{% set egress_lossy_pool_size = '26400000' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -17,7 +17,7 @@ "size": "{{ ingress_lossless_pool_size }}", "type": "ingress", "mode": "dynamic", - "xoff": "2867200" + "xoff": "36222208" }, "ingress_lossy_pool": { "size": "{{ ingress_lossy_pool_size }}", diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 index 01f50a4419e9..33698097285e 100644 --- a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '2097152' %} -{% set ingress_lossy_pool_size = '5242880' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '5242880' %} +{% set ingress_lossless_pool_size = '23850816' %} +{% set ingress_lossy_pool_size = '36222208' %} +{% set egress_lossless_pool_size = '29482816' %} +{% set egress_lossy_pool_size = '26400000' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -17,7 +17,7 @@ "size": "{{ ingress_lossless_pool_size }}", "type": "ingress", "mode": "dynamic", - "xoff": "2867200" + "xoff": "36222208" }, "ingress_lossy_pool": { "size": "{{ ingress_lossy_pool_size }}", diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf index cf6e445dba1a..ca838c1bb5da 100644 --- a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf @@ -32,7 +32,8 @@ "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, - "non_default_port_ppgs": 5 + "non_default_port_ppgs": 5, + "cpu_port": "eth2" } ] } diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/configs/network/interfaces.d/eth2 b/platform/barefoot/sonic-platform-modules-bfn-newport/configs/network/interfaces.d/eth2 new file mode 100644 index 000000000000..725bc89e0ebb --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/configs/network/interfaces.d/eth2 @@ -0,0 +1,4 @@ +# eth cpu port +auto eth2 +iface eth2 inet +up ifconfig eth2 promisc mtu 9000 diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/configs/systemd/system/bfn-newport.service b/platform/barefoot/sonic-platform-modules-bfn-newport/configs/systemd/system/bfn-newport.service new file mode 100644 index 000000000000..9d6ca1271e85 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/configs/systemd/system/bfn-newport.service @@ -0,0 +1,14 @@ +[Unit] +Description=Barefoot Newport FPGA driver +Before=syncd.service + +[Service] +User=root +ExecStartPre=/sbin/depmod -a +ExecStart=/sbin/modprobe bf_fpga +ExecStartPost=/sbin/modprobe bf_tun +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target + diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/install b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/install new file mode 100644 index 000000000000..7cb6ed7fe336 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/install @@ -0,0 +1 @@ +configs/systemd/system/bfn-newport.service etc/systemd/system diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/postinst b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/postinst new file mode 100644 index 000000000000..a89ac4f4f5b2 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/postinst @@ -0,0 +1,6 @@ +#!/bin/sh +set -e +depmod -a +systemctl enable bfn-newport.service +systemctl start bfn-newport.service +#DEBHELPER# From 558292f462d37f03718e5f08968bd739214fe0df Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Sun, 1 Dec 2019 11:19:22 -0800 Subject: [PATCH 0206/1427] [sonic-utilities] submodule update for sonic-utilities (#3825) update multiDB changes in sonic-utilities, including earlier commit by others as well: - [multiDB]: all application should use API to get redis_client (#753) - [VRF]: submit vrf CLI #392 (#558) - [show] Add 'features' subcommand to display status for optional features (#712) - [neighbor_advertiser] Adds initial support for HTTPS to neighbor advertiser (#750) after this update , we are able to update sonic-py-swsssdk submodule without hitting error as before. Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 587e630ace4f..1898102cf2c3 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 587e630ace4f5e6d2df1d0fbfa112aef19283d3a +Subproject commit 1898102cf2c399ebf2360c461297b0ac9fae98e4 From f0a3d85ec2b50cc9fa785340bdbaf601aabe97ac Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 2 Dec 2019 10:27:35 -0800 Subject: [PATCH 0207/1427] [submodule]: update sonic-sairedis (#3833) * 27a93ff 2019-11-25 | Don't learn fdb entries on LAG when rif based (#538) [Kamil Cudnik] * 5ef1764 2019-11-22 | Changes in sonic-sairedis repo to support the NAT feature. (#519) [Kiran Kumar Kella] Signed-off-by: Guohan Lu --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 533749062f63..27a93ff0d5f0 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 533749062f638f74ebc09c4bd0a5162b2c575564 +Subproject commit 27a93ff0d5f0e5fae74c2ef6b78258ad89a066a8 From eff9d868725c813635b4399b64d916b2c7f1f03f Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Mon, 2 Dec 2019 14:20:35 -0800 Subject: [PATCH 0208/1427] [swsssdk-py] update submodule for sonic-py-swsssdk (#3826) update multiDB changes in sonic-py-swsssdk, including: *[multi-DB] Part 4: add sonic-db-cli to replace redis-cli (#54) *[multi-DB] Part 3: Python API changes (#52) *remove SonicV2Connector which is not used any more (#53) This needs #3825 to be merged first. Otherwise when reloading minigraph/config will hit error. Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 4cee38534919..bc3964b788c3 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 4cee38534919e34f407363ac3ab5f31b4d09be6d +Subproject commit bc3964b788c3a4a45f2b359a5df5934ecdee84c2 From fc36ca6e4586812651677e95cc1fd537f43008e7 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Mon, 2 Dec 2019 15:54:55 -0800 Subject: [PATCH 0209/1427] Revert "[swss.sh] When starting, call 'systemctl restart' on dependents, not (#3807)" (#3835) This reverts commit 351410ea8cd7e45be42ab394e138a350c241183a. --- files/scripts/swss.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 416075d8b33a..7dde4aecb365 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -85,9 +85,7 @@ start_peer_and_dependent_services() { if [[ x"$WARM_BOOT" != x"true" ]]; then /bin/systemctl start ${PEER} for dep in ${DEPENDENT}; do - # Here we call `systemctl restart` on each dependent service instead of `systemctl start` to - # ensure the services actually get stopped and started in case they were not previously stopped. - /bin/systemctl restart ${dep} + /bin/systemctl start ${dep} done fi } From d3e544e7ba31ddc56804a2b22b157d5c12eec1b2 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 3 Dec 2019 08:32:50 -0800 Subject: [PATCH 0210/1427] [sonic-utilities] Update submodule (#3829) [config] Add 'feature' subcommand (#746) Fix a bug in idempotent check. (#755) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 1898102cf2c3..08169487110a 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 1898102cf2c399ebf2360c461297b0ac9fae98e4 +Subproject commit 08169487110a95152d2e52dc0f2584f6e3b16579 From 100d67941a42a5ff1452c4e8085c5a8f7c73a0c3 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 3 Dec 2019 09:50:49 -0800 Subject: [PATCH 0211/1427] [services] sflow service sets swss service as Requisite=, not Requires= (#3819) The sflow service should not start unless the swss service is started. However, if this service is not started, the sflow service should not attempt to start them, instead it should simply fail to start. Using Requisite=, we will achieve this behavior, whereas using Requires= will cause the required service to be started. --- files/build_templates/sflow.service.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/sflow.service.j2 b/files/build_templates/sflow.service.j2 index de08f027adff..643bf646964d 100644 --- a/files/build_templates/sflow.service.j2 +++ b/files/build_templates/sflow.service.j2 @@ -1,6 +1,6 @@ [Unit] Description=sFlow container -Requires=swss.service +Requisite=swss.service After=swss.service syncd.service Before=ntp-config.service StartLimitIntervalSec=1200 From 343ad789316700b0d3994e894675fd8ff1f1c793 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Wed, 4 Dec 2019 00:06:41 +0530 Subject: [PATCH 0212/1427] DellEMC : Platform2.0 API Implementation [S6100, S6000, Z9100] (#3740) --- .../common/dell_pmc.c | 36 +++++++++----- .../s6000/sonic_platform/chassis.py | 14 +++--- .../s6000/sonic_platform/eeprom.py | 25 +++++++--- .../s6000/sonic_platform/fan.py | 44 +++++++++++++---- .../s6000/sonic_platform/psu.py | 3 ++ .../s6100/scripts/platform_sensors.py | 8 ++-- .../s6100/scripts/s6100_platform.sh | 24 +++++++++- .../s6100/sonic_platform/chassis.py | 15 +++--- .../s6100/sonic_platform/eeprom.py | 27 ++++++++--- .../s6100/sonic_platform/fan.py | 48 ++++++++++++++----- .../s6100/sonic_platform/module.py | 13 ++--- .../z9100/scripts/platform_sensors.py | 8 ++-- .../z9100/sonic_platform/chassis.py | 14 +++--- .../z9100/sonic_platform/fan.py | 48 ++++++++++++++----- 14 files changed, 233 insertions(+), 94 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c index 7c258cdfeab7..e8cddf4fad11 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -631,7 +631,7 @@ static ssize_t show_fan(struct device *dev, ret = smf_read_reg16(data, PSU_2_FAN_SPEED); break; case 12: - ret = ~smf_read_reg(data, FAN_TRAY_PRESENCE); + ret = (~smf_read_reg(data, FAN_TRAY_PRESENCE) & 0xff); export_hex = 1; break; @@ -682,14 +682,26 @@ static ssize_t show_fan_alarm(struct device *dev, struct smf_data *data = dev_get_drvdata(dev); int ret, psu_fan_status=0; - if(index < 2) - psu_fan_status = smf_read_reg(data, FAN_STATUS_GROUP_B); + if (data->kind == z9100smf) { + if ((index % 2) == 0) + index = index / 2; + else + index = (index / 2) + 5; + } + + if (data->kind == s6100smf) + index = index / 2; + + if (index > 7) { + psu_fan_status = ~smf_read_reg(data, FAN_STATUS_GROUP_A); + index = index % 8; + } else + psu_fan_status = ~smf_read_reg(data, FAN_STATUS_GROUP_B); if (psu_fan_status & (1 << (index))) ret=0; - - if (ret < 0) - return ret; + else + ret=1; return sprintf(buf, "%d\n", ret); } @@ -726,12 +738,12 @@ static ssize_t show_psu_fan(struct device *dev, if (index < FAN_601_FAULT){ fan_status = smf_read_reg(data, PSU_1_FAN_STATUS); - ret = fan_status & (1 << index); + ret = (fan_status >> index) & 1; } else{ fan_status = smf_read_reg(data, PSU_2_FAN_STATUS); - ret = fan_status & (1 << (index - 3)); + ret = (fan_status >> (index - 3)) & 1; } if (ret < 0) @@ -1319,17 +1331,15 @@ static ssize_t show_current(struct device *dev, else ret = smf_read_reg16(data, SWITCH_CURRENT_Z9100 + index * 2); else if (index < CURR602_INPUT) - curr = smf_read_reg16(data, PSU_1_INPUT_CURRENT + (index % 4) * 2); + ret = smf_read_reg16(data, PSU_1_INPUT_CURRENT + (index % 2) * 2); else - curr = smf_read_reg16(data, PSU_2_INPUT_CURRENT + (index % 4) * 2); + ret = smf_read_reg16(data, PSU_2_INPUT_CURRENT + (index % 4) * 2); if (ret < 0) return ret; - /* TODO: docs say 10mA, value look like A? */ - if(index < 2) - curr = ret*1000; + curr = ret*10; return sprintf(buf, "%d\n", curr); } diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index 005fdd15b269..c212df88c147 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -65,7 +65,7 @@ def __init__(self): # Get Transceiver status self.modprs_register = self._get_transceiver_status() - self.sys_eeprom = Eeprom() + self._eeprom = Eeprom() for i in range(MAX_S6000_FAN): fan = Fan(i) self._fan_list.append(fan) @@ -105,7 +105,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self.sys_eeprom.modelstr() + return self._eeprom.modelstr() def get_presence(self): """ @@ -121,7 +121,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self.sys_eeprom.part_number_str() + return self._eeprom.part_number_str() def get_serial(self): """ @@ -129,7 +129,7 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self.sys_eeprom.serial_str() + return self._eeprom.serial_str() def get_status(self): """ @@ -148,7 +148,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self.sys_eeprom.base_mac_addr() + return self._eeprom.base_mac_addr() def get_serial_number(self): """ @@ -158,7 +158,7 @@ def get_serial_number(self): A string containing the hardware serial number for this chassis. """ - return self.sys_eeprom.serial_number_str() + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -170,7 +170,7 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self.sys_eeprom.system_eeprom_info() + return self._eeprom.system_eeprom_info() def get_reboot_cause(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py index 3d824ba28268..32462e5a256e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py @@ -28,14 +28,15 @@ psu_eeprom_format = [ ('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7), ('Part Number', 's', 10), ('Part Num Revision', 's', 3), - ('Mfg Test', 's', 2), ('PSU Type', 's', 1), ('Fab Rev', 's', 2) + ('Mfg Test', 's', 2), ('Redundant copy', 's', 83), ('PSU Type', 's', 1), + ('Fab Rev', 's', 2) ] # Fan eeprom fields in format required by EepromDecoder fan_eeprom_format = [ ('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7), ('Part Number', 's', 10), ('Part Num Revision', 's', 3), - ('Mfg Test', 's', 2), ('Redundant copy', 's', 82), + ('Mfg Test', 's', 2), ('Redundant copy', 's', 83), ('Number of Fans', 's', 1), ('Fan Type', 's', 1), ('Fab Rev', 's', 2) ] @@ -168,11 +169,18 @@ def _load_device_eeprom(self): else: self.part_number = 'NA' - (valid, data) = self._get_eeprom_field("Fan Type") - if valid: - self.fan_type = data + if self.is_psu_eeprom: + (valid, data) = self._get_eeprom_field("PSU Type") + if valid: + self.psu_type = data + else: + self.psu_type = 'NA' else: - self.fan_type = 'NA' + (valid, data) = self._get_eeprom_field("Fan Type") + if valid: + self.fan_type = data + else: + self.fan_type = 'NA' def _get_eeprom_field(self, field_name): """ @@ -204,7 +212,10 @@ def airflow_fan_type(self): """ Returns the airflow fan type. """ - return int(self.fan_type.encode('hex'), 16) + if self.is_psu_eeprom: + return int(self.psu_type.encode('hex'), 16) + else: + return int(self.fan_type.encode('hex'), 16) # System EEPROM specific methods def base_mac_addr(self): diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py index 3350b4818401..29555b443a22 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py @@ -17,6 +17,7 @@ raise ImportError(str(e) + "- required module not found") +MAX_S6000_PSU_FAN_SPEED = 18000 MAX_S6000_FAN_SPEED = 19000 @@ -26,12 +27,12 @@ class Fan(FanBase): CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0/" I2C_DIR = "/sys/class/i2c-adapter/" - def __init__(self, fan_index, psu_fan=False): - # Fan is 1-based in DellEMC platforms - self.index = fan_index + 1 + def __init__(self, fan_index, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan if not self.is_psu_fan: + # Fan is 1-based in DellEMC platforms + self.index = fan_index + 1 self.fan_presence_reg = "fan_prs" self.fan_led_reg = "fan{}_led".format(fan_index) self.get_fan_speed_reg = self.I2C_DIR + "i2c-11/11-0029/" +\ @@ -42,8 +43,13 @@ def __init__(self, fan_index, psu_fan=False): self.max_fan_speed = MAX_S6000_FAN_SPEED self.supported_led_color = ['off', 'green', 'amber'] else: - self.get_fan_speed_reg = self.I2C_DIR + "i2c-1/1-005{}/" +\ - "fan1_input".format(10 - self.index) + self.index = fan_index + self.dependency = dependency + self.get_fan_speed_reg = self.I2C_DIR +\ + "i2c-1/1-005{}/fan1_target".format(10 - self.index) + self.set_fan_speed_reg = self.I2C_DIR +\ + "i2c-1/1-005{}/fan1_target".format(10 - self.index) + self.max_fan_speed = MAX_S6000_PSU_FAN_SPEED def _get_cpld_register(self, reg_name): # On successful read, returns the value read from given @@ -136,6 +142,9 @@ def get_presence(self): bool: True if Fan is present, False if not """ status = False + if self.is_psu_fan: + return self.dependency.get_presence() + fan_presence = self._get_cpld_register(self.fan_presence_reg) if (fan_presence != 'ERR'): fan_presence = int(fan_presence,16) & self.index @@ -151,7 +160,10 @@ def get_model(self): Returns: string: Part number of Fan """ - return self.eeprom.part_number_str() + if not self.is_psu_fan: + return self.eeprom.part_number_str() + else: + return 'NA' def get_serial(self): """ @@ -161,7 +173,10 @@ def get_serial(self): string: Serial number of Fan """ # Sample Serial number format "US-01234D-54321-25A-0123-A00" - return self.eeprom.serial_number_str() + if not self.is_psu_fan: + return self.eeprom.serial_number_str() + else: + return 'NA' def get_status(self): """ @@ -186,8 +201,13 @@ def get_direction(self): A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction """ - direction = {1: 'FAN_DIRECTION_INTAKE', 2: 'FAN_DIRECTION_EXHAUST'} - fan_direction = self.eeprom.airflow_fan_type() + if self.is_psu_fan: + direction = {1: 'FAN_DIRECTION_EXHAUST', 2: 'FAN_DIRECTION_INTAKE', + 3: 'FAN_DIRECTION_EXHAUST', 4: 'FAN_DIRECTION_INTAKE'} + fan_direction = self.dependency.eeprom.airflow_fan_type() + else: + direction = {1: 'FAN_DIRECTION_EXHAUST', 2: 'FAN_DIRECTION_INTAKE'} + fan_direction = self.eeprom.airflow_fan_type() return direction.get(fan_direction,'NA') @@ -248,7 +268,7 @@ def set_status_led(self, color): Returns: bool: True if set success, False if fail. """ - if color not in self.supported_led_color: + if self.is_psu_fan or (color not in self.supported_led_color): return False if(color == self.STATUS_LED_COLOR_AMBER): color = 'yellow' @@ -266,6 +286,10 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ + if self.is_psu_fan: + # No LED available for PSU Fan + return None + fan_led = self._get_cpld_register(self.fan_led_reg) if (fan_led != 'ERR'): if (fan_led == 'yellow'): diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py index dfbd2a87eb5d..e2897a78d9fd 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py @@ -13,6 +13,7 @@ import os from sonic_platform_base.psu_base import PsuBase from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -46,6 +47,8 @@ def __init__(self, psu_index): # make it unique per Psu object self._fan_list = [] + self._fan_list.append(Fan(self.index, psu_fan=True, dependency=self)) + def _get_cpld_register(self, reg_name): # On successful read, returns the value read from given # reg_name and on failure returns 'ERR' diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py index a0231bc507cf..b94b69388300 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py @@ -255,8 +255,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan11_fault')) input_voltage = float(get_pmc_register('in29_input')) / 1000 output_voltage = float(get_pmc_register('in30_input')) / 1000 - input_current = float(get_pmc_register('curr601_input')) / 100 - output_current = float(get_pmc_register('curr602_input')) / 100 + input_current = float(get_pmc_register('curr601_input')) / 1000 + output_current = float(get_pmc_register('curr602_input')) / 1000 input_power = float(get_pmc_register('power1_input')) / 1000000 output_power = float(get_pmc_register('power2_input')) / 1000000 if (input_power != 0): @@ -268,8 +268,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan12_fault')) input_voltage = float(get_pmc_register('in31_input')) / 1000 output_voltage = float(get_pmc_register('in32_input')) / 1000 - input_current = float(get_pmc_register('curr701_input')) / 100 - output_current = float(get_pmc_register('curr702_input')) / 100 + input_current = float(get_pmc_register('curr701_input')) / 1000 + output_current = float(get_pmc_register('curr702_input')) / 1000 input_power = float(get_pmc_register('power3_input')) / 1000000 output_power = float(get_pmc_register('power4_input')) / 1000000 if (input_power != 0): diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh index d8b13ca02c1e..8533d9a198e2 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -54,6 +54,26 @@ sys_eeprom() { esac } +#Attach/Detach eeprom on each IOM +switch_board_eeprom() { + case $1 in + "new_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + *) echo "s6100_platform: switch_board_eeprom : invalid command !" + ;; + esac +} + #Attach/Detach CPLD devices to drivers for each IOM switch_board_cpld() { case $1 in @@ -245,7 +265,7 @@ install_python_api_package() { remove_python_api_package() { rv=$(pip show sonic-platform > /dev/null 2>/dev/null) if [ $? -eq 0 ]; then - rv = $(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) + rv=$(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) fi } @@ -267,6 +287,7 @@ if [[ "$1" == "init" ]]; then cpu_board_mux "new_device" switch_board_mux "new_device" sys_eeprom "new_device" + switch_board_eeprom "new_device" switch_board_cpld "new_device" switch_board_qsfp_mux "new_device" switch_board_sfp "new_device" @@ -280,6 +301,7 @@ elif [[ "$1" == "deinit" ]]; then xcvr_presence_interrupts "disable" switch_board_sfp "delete_device" switch_board_cpld "delete_device" + switch_board_eeprom "delete_device" switch_board_mux "delete_device" sys_eeprom "delete_device" switch_board_qsfp "delete_device" diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py index e39e8480e2c7..ec1848fc8dca 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py @@ -54,10 +54,11 @@ def __init__(self): ChassisBase.__init__(self) # Initialize EEPROM - self.sys_eeprom = Eeprom() + self._eeprom = Eeprom() for i in range(MAX_S6100_MODULE): module = Module(i) self._module_list.append(module) + self._sfp_list.extend(module._sfp_list) for i in range(MAX_S6100_FAN): fan = Fan(i) @@ -107,7 +108,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self.sys_eeprom.modelstr() + return self._eeprom.modelstr() def get_presence(self): """ @@ -123,7 +124,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self.sys_eeprom.part_number_str() + return self._eeprom.part_number_str() def get_serial(self): """ @@ -131,7 +132,7 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self.sys_eeprom.serial_str() + return self._eeprom.serial_str() def get_status(self): """ @@ -150,7 +151,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self.sys_eeprom.base_mac_addr() + return self._eeprom.base_mac_addr() def get_serial_number(self): """ @@ -160,7 +161,7 @@ def get_serial_number(self): A string containing the hardware serial number for this chassis. """ - return self.sys_eeprom.serial_number_str() + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -170,7 +171,7 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self.sys_eeprom.system_eeprom_info() + return self._eeprom.system_eeprom_info() def get_reboot_cause(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py index 4e683e1e511b..8bd900b6c26b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py @@ -18,15 +18,26 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): - def __init__(self): - self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom" + def __init__(self, i2c_line=0, iom_eeprom=False): + self.is_module = iom_eeprom + if self.is_module: + self.eeprom_path = ("/sys/class/i2c-adapter" + "/i2c-{0}/{0}-0050/eeprom").format(i2c_line) + else: + self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom" super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) self.eeprom_tlv_dict = dict() + try: - self.eeprom_data = self.read_eeprom() + if self.is_module: + self.write_eeprom("\x00\x00") + self.eeprom_data = self.read_eeprom_bytes(256) + else: + self.eeprom_data = self.read_eeprom() except: self.eeprom_data = "N/A" - raise RuntimeError("Eeprom is not Programmed") + if not self.is_module: + raise RuntimeError("Eeprom is not Programmed") else: eeprom = self.eeprom_data @@ -76,8 +87,12 @@ def base_mac_addr(self): return ":".join([binascii.b2a_hex(T) for T in results[2]]) def modelstr(self): - (is_valid, results) = self.get_tlv_field( - self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if self.is_module: + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PLATFORM_NAME) + else: + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) if not is_valid: return "N/A" diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py index 2aef71b756e7..a2ee0cd10421 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py @@ -33,6 +33,10 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): # from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 + self.fan_presence_reg = "fan{}_fault".format( + 2 * self.fantrayindex - 1) + self.fan_status_reg = "fan{}_alarm".format( + 2 * self.fantrayindex - 1) self.get_fan_speed_reg = "fan{}_input".format( 2 * self.fantrayindex - 1) self.get_fan_dir_reg = "fan{}_airflow".format( @@ -43,7 +47,9 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): else: # PSU Fan index starts from 11 self.fanindex = fan_index + 10 + self.fan_presence_reg = "fan{}_fault".format(self.fanindex) self.get_fan_speed_reg = "fan{}_input".format(self.fanindex) + self.get_fan_dir_reg = "fan{}_airflow".format(self.fanindex) self.max_fan_speed = MAX_S6100_PSU_FAN_SPEED def _get_pmc_register(self, reg_name): @@ -84,6 +90,9 @@ def get_model(self): """ # For Serial number "US-01234D-54321-25A-0123-A00", the part # number is "01234D" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno != 'ERR') and self.get_presence(): if (len(fan_serialno.split('-')) > 1): @@ -102,6 +111,9 @@ def get_serial(self): string: Serial number of FAN """ # Sample Serial number format "US-01234D-54321-25A-0123-A00" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno == 'ERR') or not self.get_presence(): fan_serialno = 'NA' @@ -115,11 +127,11 @@ def get_presence(self): bool: True if fan is present, False if not """ status = False - fantray_presence = self._get_pmc_register(self.get_fan_speed_reg) + fantray_presence = self._get_pmc_register(self.fan_presence_reg) if (fantray_presence != 'ERR'): fantray_presence = int(fantray_presence, 10) - if (fantray_presence > 0): - status = True + if (~fantray_presence & 0b1): + status = True return status @@ -130,11 +142,18 @@ def get_status(self): bool: True if FAN is operating properly, False if not """ status = False - fantray_status = self._get_pmc_register(self.get_fan_speed_reg) - if (fantray_status != 'ERR'): - fantray_status = int(fantray_status, 10) - if (fantray_status > 5000): - status = True + if self.is_psu_fan: + fantray_status = self._get_pmc_register(self.get_fan_speed_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (fantray_status > 5000): + status = True + else: + fantray_status = self._get_pmc_register(self.fan_status_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (~fantray_status & 0b1): + status = True return status @@ -216,10 +235,17 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ - if self.get_status(): - return self.STATUS_LED_COLOR_GREEN + if self.is_psu_fan: + # No LED available for PSU Fan + return None else: - return self.STATUS_LED_COLOR_OFF + if self.get_presence(): + if self.get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_AMBER + else: + return self.STATUS_LED_COLOR_OFF def get_target_speed(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py index 265dc206ad0c..19198098dfd7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py @@ -14,6 +14,7 @@ from sonic_platform_base.module_base import ModuleBase from sonic_platform.sfp import Sfp from sonic_platform.component import Component + from sonic_platform.eeprom import Eeprom except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -55,7 +56,7 @@ def __init__(self, module_index): self.port_start = (self.index - 1) * 16 self.port_end = (self.index * 16) - 1 self.port_i2c_line = self.IOM_I2C_MAPPING[self.index] - self.eeprom_tlv_dict = dict() + self._eeprom = Eeprom(iom_eeprom=True, i2c_line=self.port_i2c_line) self.iom_status_reg = "iom_status" self.iom_presence_reg = "iom_presence" @@ -108,7 +109,7 @@ def get_name(self): Returns: string: The name of the device """ - return "IOM{}: 16xQSFP+".format(self.index) + return "IOM{}: {}".format(self.index, self._eeprom.modelstr()) def get_presence(self): """ @@ -133,7 +134,7 @@ def get_model(self): Returns: string: part number of module """ - return 'NA' + return self._eeprom.part_number_str() def get_serial(self): """ @@ -142,7 +143,7 @@ def get_serial(self): Returns: string: Serial number of module """ - return 'NA' + return self._eeprom.serial_str() def get_status(self): """ @@ -178,7 +179,7 @@ def get_serial_number(self): Returns: A string containing the hardware serial number for this module. """ - return 'NA' + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -192,4 +193,4 @@ def get_system_eeprom_info(self): ‘0x24’:’001c0f000fcd0a’, ‘0x25’:’02/03/2018 16:22:00’, ‘0x26’:’01’, ‘0x27’:’REV01’, ‘0x28’:’AG9064-C2358-16G’} """ - return self.eeprom_tlv_dict + return self._eeprom.system_eeprom_info() diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py index 76e527e13d73..05cbb3a1a4c1 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py @@ -262,8 +262,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan11_fault')) input_voltage = float(get_pmc_register('in29_input')) / 1000 output_voltage = float(get_pmc_register('in30_input')) / 1000 - input_current = float(get_pmc_register('curr601_input')) / 100 - output_current = float(get_pmc_register('curr602_input')) /100 + input_current = float(get_pmc_register('curr601_input')) / 1000 + output_current = float(get_pmc_register('curr602_input')) / 1000 input_power = float(get_pmc_register('power1_input')) / 1000000 output_power = float(get_pmc_register('power2_input')) / 1000000 if (input_power != 0): @@ -275,8 +275,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan12_fault')) input_voltage = float(get_pmc_register('in31_input')) / 1000 output_voltage = float(get_pmc_register('in32_input')) / 1000 - input_current = float(get_pmc_register('curr701_input')) / 100 - output_current = float(get_pmc_register('curr702_input')) / 100 + input_current = float(get_pmc_register('curr701_input')) / 1000 + output_current = float(get_pmc_register('curr702_input')) / 1000 input_power = float(get_pmc_register('power3_input')) / 1000000 output_power = float(get_pmc_register('power4_input')) / 1000000 if (input_power != 0): diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index 3472bb3e7fb0..27164409d962 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py @@ -94,7 +94,7 @@ def __init__(self): ChassisBase.__init__(self) # Initialize EEPROM - self.sys_eeprom = Eeprom() + self._eeprom = Eeprom() for i in range(MAX_Z9100_FANTRAY): for j in range(MAX_Z9100_FAN): fan = Fan(i, j) @@ -137,7 +137,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self.sys_eeprom.modelstr() + return self._eeprom.modelstr() def get_presence(self): """ @@ -153,7 +153,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self.sys_eeprom.part_number_str() + return self._eeprom.part_number_str() def get_serial(self): """ @@ -161,7 +161,7 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self.sys_eeprom.serial_str() + return self._eeprom.serial_str() def get_status(self): """ @@ -180,7 +180,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self.sys_eeprom.base_mac_addr() + return self._eeprom.base_mac_addr() def get_serial_number(self): """ @@ -189,7 +189,7 @@ def get_serial_number(self): Returns: A string containing the hardware serial number for this chassis. """ - return self.sys_eeprom.serial_number_str() + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -200,7 +200,7 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self.sys_eeprom.system_eeprom_info() + return self._eeprom.system_eeprom_info() def get_reboot_cause(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py index ae3c5e9fbcab..03ac8cd5c71f 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py @@ -33,6 +33,10 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): # from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 + self.fan_presence_reg = "fan{}_fault".format( + 2 * (self.fantrayindex - 1) + (self.fanindex - 1) + 1 ) + self.fan_status_reg = "fan{}_alarm".format( + 2 * (self.fantrayindex - 1) + (self.fanindex - 1) + 1 ) self.get_fan_speed_reg = "fan{}_input".format( 2 * (self.fantrayindex - 1) + (self.fanindex - 1) + 1 ) self.get_fan_dir_reg = "fan{}_airflow".format( @@ -43,7 +47,9 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): else: # PSU Fan index starts from 11 self.fanindex = fan_index + 10 + self.fan_presence_reg = "fan{}_fault".format(self.fanindex) self.get_fan_speed_reg = "fan{}_input".format(self.fanindex) + self.get_fan_dir_reg = "fan{}_airflow".format(self.fanindex) self.max_fan_speed = MAX_Z9100_PSU_FAN_SPEED def _get_pmc_register(self, reg_name): @@ -83,6 +89,9 @@ def get_model(self): """ # For Serial number "US-01234D-54321-25A-0123-A00", the part # number is "01234D" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno != 'ERR') and self.get_presence(): if (len(fan_serialno.split('-')) > 1): @@ -101,6 +110,9 @@ def get_serial(self): string: Serial number of FAN """ # Sample Serial number format "US-01234D-54321-25A-0123-A00" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno == 'ERR') or not self.get_presence(): fan_serialno = 'NA' @@ -114,11 +126,11 @@ def get_presence(self): bool: True if fan is present, False if not """ status = False - fantray_presence = self._get_pmc_register(self.get_fan_speed_reg) + fantray_presence = self._get_pmc_register(self.fan_presence_reg) if (fantray_presence != 'ERR'): fantray_presence = int(fantray_presence, 10) - if (fantray_presence > 0): - status = True + if (~fantray_presence & 0b1): + status = True return status @@ -129,11 +141,18 @@ def get_status(self): bool: True if FAN is operating properly, False if not """ status = False - fantray_status = self._get_pmc_register(self.get_fan_speed_reg) - if (fantray_status != 'ERR'): - fantray_status = int(fantray_status, 10) - if (fantray_status > 5000): - status = True + if self.is_psu_fan: + fantray_status = self._get_pmc_register(self.get_fan_speed_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (fantray_status > 5000): + status = True + else: + fantray_status = self._get_pmc_register(self.fan_status_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (~fantray_status & 0b1): + status = True return status @@ -215,10 +234,17 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ - if self.get_status(): - return self.STATUS_LED_COLOR_GREEN + if self.is_psu_fan: + # No LED available for PSU Fan + return None else: - return self.STATUS_LED_COLOR_OFF + if self.get_presence(): + if self.get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_AMBER + else: + return self.STATUS_LED_COLOR_OFF def get_target_speed(self): """ From 654bb0eae7c2e17eebda2cf586c3efae8e7d3a03 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 3 Dec 2019 13:54:57 -0800 Subject: [PATCH 0213/1427] [kvm]: reconnect during kvm installation process (#3837) * [kvm]: reconnect during kvm installation process retry connect every 1 second for 10 maximum times Signed-off-by: Guohan Lu --- check_install.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/check_install.py b/check_install.py index 09979f61e4ba..d95d831daa70 100755 --- a/check_install.py +++ b/check_install.py @@ -24,7 +24,17 @@ def main(): cmd_prompt = "%s@sonic:~\$ $" % args.u grub_selection = "The highlighted entry will be executed" - p = pexpect.spawn("telnet 127.0.0.1 %s" % args.p, timeout=600, logfile=sys.stdout) + i = 0 + while True: + try: + p = pexpect.spawn("telnet 127.0.0.1 %s" % args.p, timeout=600, logfile=sys.stdout) + break + except Exception as e: + print str(e) + i += 1 + if i == 10: + raise + time.sleep(1) # select ONIE embed p.expect(grub_selection) From 3853b31f3cc50a6bf4e53745c2563c268acec9da Mon Sep 17 00:00:00 2001 From: Tony Titus <49417625+tonytitus@users.noreply.github.com> Date: Tue, 3 Dec 2019 13:55:25 -0800 Subject: [PATCH 0214/1427] [innovium]: Add Innovium Jenkins build (#3820) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 129af89f05d4..1ab18f5e646f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ *master*: +Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all) Barefoot: [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all) Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all) Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all) @@ -16,6 +17,7 @@ Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mell VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201904) *201811*: +Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/) Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/) Barefoot: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201811/) Centec: [![Centec](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201811/) From eec594adf207aec69b255f58ea86075c8be729e4 Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Wed, 4 Dec 2019 07:50:56 -0500 Subject: [PATCH 0215/1427] [sonic-ztp]: Build sonic-ztp package (#3299) * Build sonic-ztp package - Add changes in make rules to conditionally include sonic-ztp package Signed-off-by: Rajendra Dendukuri --- Makefile.work | 2 ++ files/build_templates/sonic_debian_extension.j2 | 6 ++++++ rules/config | 3 +++ rules/sonic-ztp.mk | 17 +++++++++++++++++ slave.mk | 3 +++ 5 files changed, 31 insertions(+) create mode 100644 rules/sonic-ztp.mk diff --git a/Makefile.work b/Makefile.work index b81ac591246f..71175d5c4757 100644 --- a/Makefile.work +++ b/Makefile.work @@ -7,6 +7,7 @@ # * BUILD_NUMBER: Desired version-number to pass to the building-system. # * ENABLE_DHCP_GRAPH_SERVICE: Enables get-graph service to fetch minigraph files # through http. +# * ENABLE_ZTP: Enables zero touch provisioning. # * SHUTDOWN_BGP_ON_START: Sets admin-down state for all bgp peerings after restart. # * ENABLE_PFCWD_ON_START: Enable PFC Watchdog (PFCWD) on server-facing ports # * by default for TOR switch. @@ -162,6 +163,7 @@ SONIC_BUILD_INSTRUCTION := make \ BUILD_NUMBER=$(BUILD_NUMBER) \ BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) \ ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \ + ENABLE_ZTP=$(ENABLE_ZTP) \ SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \ SONIC_ENABLE_PFCWD_ON_START=$(ENABLE_PFCWD_ON_START) \ SONIC_ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \ diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index f62ef44f0fc0..58ebf24bdf7c 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -141,6 +141,12 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install tabulat sudo dpkg --root=$FILESYSTEM_ROOT -i $python_debs_path/python-sonic-utilities_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +{% if enable_ztp == "y" %} +# Install ZTP (and its dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-ztp_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +{% endif %} + # SONiC utilities installs bash-completion as a dependency. However, it is disabled by default # in bash.bashrc, so we copy a version of the file with it enabled here. sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/ diff --git a/rules/config b/rules/config index 04af59ccd818..c158fcc27726 100644 --- a/rules/config +++ b/rules/config @@ -44,6 +44,9 @@ DEFAULT_PASSWORD = YourPaSsWoRd # If not set (default behavior) the default minigraph built into the image will be used. # ENABLE_DHCP_GRAPH_SERVICE = y +# ENABLE_ZTP - installs Zero Touch Provisioning support. +# ENABLE_ZTP = y + # SHUTDOWN_BGP_ON_START - if set to y all bgp sessions will be in admin down state when # bgp service starts. # SHUTDOWN_BGP_ON_START = y diff --git a/rules/sonic-ztp.mk b/rules/sonic-ztp.mk new file mode 100644 index 000000000000..43615b7dcc8a --- /dev/null +++ b/rules/sonic-ztp.mk @@ -0,0 +1,17 @@ +# SONiC ztp package +# + +ifeq ($(ENABLE_ZTP), y) + +SONIC_ZTP_VERSION = 1.0.0 + +SONIC_ZTP = sonic-ztp_$(SONIC_ZTP_VERSION)_all.deb +$(SONIC_ZTP)_SRC_PATH = $(SRC_PATH)/sonic-ztp +SONIC_DPKG_DEBS += $(SONIC_ZTP) +SONIC_STRETCH_DEBS += $(SONIC_ZTP) + +export SONIC_ZTP_VERSION +export SONIC_ZTP + +endif + diff --git a/slave.mk b/slave.mk index f81895f74dd2..e518f1e4d8a5 100644 --- a/slave.mk +++ b/slave.mk @@ -190,6 +190,7 @@ $(info "ENABLE_ORGANIZATION_EXTENSIONS" : "$(ENABLE_ORGANIZATION_EXTENSIONS)") $(info "HTTP_PROXY" : "$(HTTP_PROXY)") $(info "HTTPS_PROXY" : "$(HTTPS_PROXY)") $(info "ENABLE_SYSTEM_TELEMETRY" : "$(ENABLE_SYSTEM_TELEMETRY)") +$(info "ENABLE_ZTP" : "$(ENABLE_ZTP)") $(info "SONIC_DEBUGGING_ON" : "$(SONIC_DEBUGGING_ON)") $(info "SONIC_PROFILING_ON" : "$(SONIC_PROFILING_ON)") $(info "KERNEL_PROCURE_METHOD" : "$(KERNEL_PROCURE_METHOD)") @@ -619,6 +620,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(LIBNSS_TACPLUS)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ + $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(DEBS_PATH)/,$(SONIC_ZTP))) \ $(addprefix $(STRETCH_FILES_PATH)/, $(if $(filter $(CONFIGURED_ARCH),amd64), $(IXGBE_DRIVER))) \ $(addprefix $(PYTHON_DEBS_PATH)/,$(SONIC_UTILS)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ @@ -639,6 +641,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export sonic_asic_platform="$(patsubst %-$(CONFIGURED_ARCH),%,$(CONFIGURED_PLATFORM))" export enable_organization_extensions="$(ENABLE_ORGANIZATION_EXTENSIONS)" export enable_dhcp_graph_service="$(ENABLE_DHCP_GRAPH_SERVICE)" + export enable_ztp="$(ENABLE_ZTP)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" export installer_debs="$(addprefix $(STRETCH_DEBS_PATH)/,$($*_INSTALLS))" From cda61290ac01d0e3231dad513e5cec4b29e0cf21 Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Wed, 4 Dec 2019 10:15:58 -0500 Subject: [PATCH 0216/1427] [config-setup]: create a SONiC configuration management service (#3227) * Create a SONiC configuration management service * Perform config db migration after loading config_db.json to redis DB * Migrate config-setup post migration hooks on image upgrade config-setup post migration hooks help user to migrate configurations from old image to new image. If the installed hooks are user defined they will not be part of the newly installed image. So these hooks have to be migrated to new image and only then they can be executing when the new image is booting. The changes in this fix migrate config-setup post-migration hooks and ensure that any hooks with the same filename in newly installed image are not overwritten. It is expected that users install new hooks as per their requirement and not edit existing hooks. Any changes to existing hooks need to be done as part of new image and not post bootup. --- files/build_templates/config-setup.service.j2 | 18 + .../build_templates/sonic_debian_extension.j2 | 5 + files/build_templates/updategraph.service.j2 | 9 +- files/image_config/config-setup/config-setup | 399 ++++++++++++++++++ files/image_config/updategraph/updategraph | 72 +--- 5 files changed, 430 insertions(+), 73 deletions(-) create mode 100644 files/build_templates/config-setup.service.j2 create mode 100755 files/image_config/config-setup/config-setup diff --git a/files/build_templates/config-setup.service.j2 b/files/build_templates/config-setup.service.j2 new file mode 100644 index 000000000000..a4b614a5f7fb --- /dev/null +++ b/files/build_templates/config-setup.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=Config initialization and migration service +After=rc-local.service +After=database.service +Requires=database.service +{% if sonic_asic_platform == 'mellanox' -%} +Requires=hw-management.service +{% endif -%} + + +[Service] +Type=oneshot +ExecStart=/usr/bin/config-setup boot +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target + diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 58ebf24bdf7c..209bc19971b3 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -244,6 +244,11 @@ sudo bash -c "echo '{ \"DEVICE_METADATA\": { \"localhost\": { \"default_bgp_stat \"{{crm_res}}_threshold_type\": \"percentage\", \"{{crm_res}}_low_threshold\": \"70\", \"{{crm_res}}_high_threshold\": \"85\"{% if not loop.last %}, {% endif %} {%- endfor %} } } }' >> $FILESYSTEM_ROOT/etc/sonic/init_cfg.json" +# Copy config-setup script and service file +j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/config-setup.service +sudo cp $IMAGE_CONFIGS/config-setup/config-setup $FILESYSTEM_ROOT/usr/bin/config-setup +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-setup.service + # Copy SNMP configuration files sudo cp $IMAGE_CONFIGS/snmp/snmp.yml $FILESYSTEM_ROOT/etc/sonic/ diff --git a/files/build_templates/updategraph.service.j2 b/files/build_templates/updategraph.service.j2 index 8039f42531cd..0e05cbf147d6 100644 --- a/files/build_templates/updategraph.service.j2 +++ b/files/build_templates/updategraph.service.j2 @@ -1,12 +1,7 @@ [Unit] Description=Update minigraph and set configuration based on minigraph -After=rc-local.service -After=database.service -Requires=database.service -{% if sonic_asic_platform == 'mellanox' -%} -Requires=hw-management.service -{% endif -%} - +After=config-setup.service +Requires=config-setup.service [Service] Type=oneshot diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup new file mode 100755 index 000000000000..bd497d06b257 --- /dev/null +++ b/files/image_config/config-setup/config-setup @@ -0,0 +1,399 @@ +#!/bin/bash +########################################################################### +# Copyright 2019 Broadcom. The term "Broadcom" refers to Broadcom Inc. # +# and/or its subsidiaries. # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# +# See the License for the specific language governing permissions and # +# limitations under the License. # +# # +########################################################################### +# SONiC Configuration Setup # +# # +# This script is used to initialize configuration used # +# by SONiC SWSS. It also performs configuration # +# migration. # +# # +########################################################################### + +# Initialize constants +CONFIG_DB_INDEX=4 +UPDATEGRAPH_CONF=/etc/sonic/updategraph.conf +CONFIG_DB_JSON=/etc/sonic/config_db.json +MINGRAPH_FILE=/etc/sonic/minigraph.xml +TMP_ZTP_CONFIG_DB_JSON=/tmp/ztp_config_db.json +FACTORY_DEFAULT_HOOKS=/etc/config-setup/factory-default-hooks.d +CONFIG_PRE_MIGRATION_HOOKS=/etc/config-setup/config-migration-pre-hooks.d +CONFIG_POST_MIGRATION_HOOKS=/etc/config-setup/config-migration-post-hooks.d +CONFIG_SETUP_VAR_DIR=/var/lib/config-setup +CONFIG_SETUP_PRE_MIGRATION_FLAG=${CONFIG_SETUP_VAR_DIR}/pending_pre_migration +CONFIG_SETUP_POST_MIGRATION_FLAG=${CONFIG_SETUP_VAR_DIR}/pending_post_migration +CONFIG_SETUP_INITIALIZATION_FLAG=${CONFIG_SETUP_VAR_DIR}/pending_initialization + +# Command usage and help +usage() +{ + cat << EOF + Usage: config-setup < backup | boot | factory > + + backup - Take a backup copy of SONiC configuration. + boot - Initialize/migrate SONiC configuration during system boot. + factory - Create factory default SONiC configuration and save it to + to ${CONFIG_DB_JSON}. +EOF +} + +# run given script +run_hook() { + local script="$1" + local exit_status=0 + + if [ -f $script ]; then + # Check hook for syntactical correctness before executing it + /bin/bash -n $script + exit_status=$? + if [ "$exit_status" -eq 0 ]; then + . $script + fi + exit_status=$? + fi + + if [ -n "$exit_status" ] && [ "$exit_status" -ne 0 ]; then + echo "$script returned non-zero exit status $exit_status" + fi + + return $exit_status +} + +# run scripts in given directory +run_hookdir() { + local dir="$1" + local progress_file="$2" + local exit_status=0 + + if [ -d "$dir" ]; then + if [ -n $progress_file ]; then + [ ! -d $(dirname $progress_file) ] && mkdir -p $(dirname $progress_file) + [ ! -e $progress_file ] && run-parts --list $dir > $progress_file + SCRIPT_LIST=$(cat $progress_file) + else + SCRIPT_LIST=$(run-parts --list $dir) + fi + + for script in $SCRIPT_LIST; do + run_hook $script + exit_status=$((exit_status|$?)) + script_name=$(basename $script) + sed -i "/$script_name/d" $progress_file + done + [ -n $progress_file ] && [ "$(cat ${progress_file})" = "" ] && rm -f ${progress_file} + fi + + return $exit_status +} + +# Reload minigraph.xml file on disk +reload_minigraph() +{ + echo "Reloading minigraph..." + if [ ! -f /etc/sonic/init_cfg.json ]; then + echo "{}" > /etc/sonic/init_cfg.json + fi + redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + if [ -f /etc/sonic/acl.json ]; then + acl-loader update full /etc/sonic/acl.json + fi + config qos reload + pfcwd start_default + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Set latest version number + /usr/bin/db_migrator.py -o set_version + fi +} + +# Restore SONiC configuration from a backup copy +function copy_config_files_and_directories() +{ + for file_dir in $@; do + if [ -f /etc/sonic/old_config/${file_dir} ] || [ -d /etc/sonic/old_config/${file_dir} ]; then + echo "Copying SONiC configuration ${file_dir} ..." + cp -ar /etc/sonic/old_config/${file_dir} /etc/sonic/ + else + echo "Missing SONiC configuration ${file_dir} ..." + fi + done +} + +# Check if SONiC swich has booted after a warm reboot request +check_system_warm_boot() +{ + SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. + if [[ x"$SYSTEM_WARM_START" == x"true" ]]; then + WARM_BOOT="true" + else + WARM_BOOT="false" + fi +} + +# Check if updategraph service is administratively enabled +updategraph_is_enabled() +{ + rv=1 + if [ -e ${UPDATEGRAPH_CONF} ]; then + updategraph_mode=$(grep enabled ${UPDATEGRAPH_CONF} | head -n 1 | cut -f2 -d=) + [ "${updategraph_mode}" = "true" ] && rv = 0 + fi + return $rv +} + +# Disable updategraph admininistratively +disable_updategraph() +{ + sed -i "/enabled=/d" ${UPDATEGRAPH_CONF} + echo "enabled=false" >> ${UPDATEGRAPH_CONF} +} + +# Check if Zero Touch Provisioning is available and is administratively enabled +ztp_is_enabled() +{ + rv=1 + if [ -e /usr/bin/ztp ]; then + status=$(ztp status -c) + [ "$status" != "0:DISABLED" ] && [ "$status" != "" ] && rv=0 + fi + return $rv +} + +# Load requested SONiC configuration into config DB and initialize it +# Usage: load_config +# +# +load_config() +{ + CONFIG_FILE=${1} + if [ "${CONFIG_FILE}" = "" ]; then + return 1 + fi + + redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-cfggen -j ${CONFIG_FILE} --write-to-db + if [ $? -ne 0 ]; then + return $? + fi + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Migrate the DB to the latest schema version if needed + /usr/bin/db_migrator.py -o migrate + fi + + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + return 0 +} + + +# Generate requested SONiC configuration and save it as destination file +# Usage: generate_config < factory | ztp > +# +# factory - Create factory default configuration +# ztp - Create Zero Touch Provisioning Configuration +# used for provisioning data discovery. +# +generate_config() +{ + # Collect all information needed to generate configuration + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PRESET=(`head -n 1 /usr/share/sonic/device/$PLATFORM/default_sku`) + HW_KEY=${PRESET[0]} + DEFAULT_PRESET=${PRESET[1]} + + # Parse arguments passed + CONFIG_TYPE=$1 + DEST_FILE=$2 + + if [ "$1" = "ztp" ]; then + /usr/lib/ztp/ztp-profile.sh create ${DEST_FILE} + elif [ "$1" = "factory" ]; then + rv=1 + + # Execute config initialization hooks + run_hookdir ${FACTORY_DEFAULT_HOOKS} ${CONFIG_SETUP_INITIALIZATION_FLAG} + + # Use preset defined in default_sku + if [ ! -e ${DEST_FILE} ]; then + sonic-cfggen -H -k ${HW_KEY} --preset ${DEFAULT_PRESET} > ${DEST_FILE} + rv=$? + if [ $rv -ne 0 ]; then + return $rv + fi + fi + fi + return 0 +} + +# Create SONiC configuration for first time bootup +# - If ZTP is enabled, ZTP configuraion is created +# - If ZTP is disabled and updategraph is disabled, factory default configuration +# is created +# - If updategraph is enabled and ZTP is disabled, updategraph initializes +# configuration +do_config_intialization() +{ + if ! updategraph_is_enabled ; then + if ! ztp_is_enabled ; then + echo "No configuration detected, generating factory default configuration..." + generate_config factory ${CONFIG_DB_JSON} + load_config ${CONFIG_DB_JSON} + fi + fi + + if ztp_is_enabled ; then + echo "No configuration detected, initiating zero touch provisioning..." + generate_config ztp ${TMP_ZTP_CONFIG_DB_JSON} + load_config ${TMP_ZTP_CONFIG_DB_JSON} + rm -f ${TMP_ZTP_CONFIG_DB_JSON} + fi + + rm -f /tmp/pending_config_initialization +} + +# Restore config-setup post migration hooks from a backup copy +copy_post_migration_hooks() +{ + BACKUP_DIR=/etc/sonic/old_config/config-migration-post-hooks.d + if [ -d ${BACKUP_DIR} ]; then + [ -d ${CONFIG_POST_MIGRATION_HOOKS} ] || mkdir -p ${CONFIG_POST_MIGRATION_HOOKS} + for hook in $(ls -1 ${BACKUP_DIR}) ; do + if [ ! -e ${CONFIG_POST_MIGRATION_HOOKS}/$hook ]; then + cp -ar ${BACKUP_DIR}/$hook ${CONFIG_POST_MIGRATION_HOOKS} + fi + done + fi +} + +# Perform configuration migration from backup copy. +# - This step is performed when a new image is installed and SONiC switch boots into it +do_config_migration() +{ + # Identify list of files to migrate + copy_list="minigraph.xml snmp.yml acl.json config_db.json frr" + + # Migrate all configuration files from old to new + copy_config_files_and_directories $copy_list + + # Migrate post-migration hooks + copy_post_migration_hooks + + # Execute custom hooks if present + run_hookdir ${CONFIG_POST_MIGRATION_HOOKS} ${CONFIG_SETUP_POST_MIGRATION_FLAG} + + if [ x"${WARM_BOOT}" == x"true" ]; then + echo "Warm reboot detected..." + disable_updategraph + rm -f /tmp/pending_config_migration + exit 0 + elif [ -r ${CONFIG_DB_JSON} ]; then + echo "Use config_db.json from old system..." + sonic-cfggen -j ${CONFIG_DB_JSON} --write-to-db + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Migrate the DB to the latest schema version if needed + /usr/bin/db_migrator.py -o migrate + fi + elif [ -r ${MINGRAPH_FILE} ]; then + echo "Use minigraph.xml from old system..." + reload_minigraph + sonic-cfggen -d --print-data > ${CONFIG_DB_JSON} + + # Disable updategraph + disable_updategraph + else + echo "Didn't found neither config_db.json nor minigraph.xml ..." + fi + + rm -f /tmp/pending_config_migration +} + +# Take a backup of current SONiC configuration +do_config_backup() +{ + echo "Taking backup of curent configuration" + rm -rf /host/old_config + cp -ar /etc/sonic /host/old_config + [ -d ${CONFIG_POST_MIGRATION_HOOKS} ] && cp -arL ${CONFIG_POST_MIGRATION_HOOKS} /host/old_config + + # Execute custom hooks if present + run_hookdir ${CONFIG_PRE_MIGRATION_HOOKS} ${CONFIG_SETUP_PRE_MIGRATION_FLAG} +} + +# Process switch bootup event +# - Check if it is warm boot and take no further action +# - Perform configuration migration if requested +# - Perform configuration initialization if requested +# - If no saved SONiC configuration is found and ZTP is enabled, +# start ZTP +boot_config() +{ + check_system_warm_boot + if [ -e /tmp/pending_config_migration ] || [ -e ${CONFIG_SETUP_POST_MIGRATION_FLAG} ]; then + do_config_migration + fi + + if [ -e /tmp/pending_config_initialization ] || [ -e ${CONFIG_SETUP_INITIALIZATION_FLAG} ]; then + do_config_intialization + fi + + # If no startup configuration is found, create a configuration to be used + if [ ! -e ${CONFIG_DB_JSON} ]; then + do_config_intialization + # force ZTP to restart + if ztp_is_enabled ; then + ztp_status=$(ztp status -c) + if [ "$ztp_status" = "5:SUCCESS" ] || \ + [ "$ztp_status" = "6:FAILED" ]; then + # Clear completed ztp information, before starting a new one + ztp erase -y + else + touch /tmp/pending_ztp_restart + fi + fi + fi +} + +### Execution starts here ### + +CMD=$1 +# Default command is boot +if [ "$CMD" = "" ] || [ "$CMD" = "help" ] || \ + [ "$CMD" = "-h" ] || [ "$CMD" = "--help" ]; then + usage + exit 1 +fi + +# Process switch bootup event +if [ "$CMD" = "boot" ]; then + boot_config +fi + +# Process factory default configuration creation request +if [ "$CMD" = "factory" ]; then + generate_config factory ${CONFIG_DB_JSON} +fi + +# Take a backup of current configuration +if [ "$CMD" = "backup" ]; then + do_config_backup +fi + +exit 0 diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index 2eb510afa4e1..b2bd027e82e7 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -26,32 +26,6 @@ reload_minigraph() fi } -function copy_config_files_and_directories() -{ - for file_dir in $@; do - if [ -f /etc/sonic/old_config/${file_dir} ] || [ -d /etc/sonic/old_config/${file_dir} ]; then - logger "Copying SONiC configuration ${file_dir} ..." - cp -ar /etc/sonic/old_config/${file_dir} /etc/sonic/ - else - logger "Missing SONiC configuration ${file_dir} ..." - fi - done - - sync -} - -function check_system_warm_boot() -{ - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. - if [[ x"$SYSTEM_WARM_START" == x"true" ]]; then - WARM_BOOT="true" - else - WARM_BOOT="false" - fi -} - - if [ ! -f /etc/sonic/updategraph.conf ]; then echo "No updategraph.conf found, generating a default one." echo "enabled=false" >/etc/sonic/updategraph.conf @@ -59,46 +33,6 @@ fi . /etc/sonic/updategraph.conf -check_system_warm_boot -copy_list="minigraph.xml snmp.yml acl.json config_db.json frr" -if [ -f /tmp/pending_config_migration ]; then - copy_config_files_and_directories $copy_list - if [ x"${WARM_BOOT}" == x"true" ]; then - echo "Warm reboot detected..." - elif [ -r /etc/sonic/config_db.json ]; then - echo "Use config_db.json from old system..." - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - - if [[ -x /usr/bin/db_migrator.py ]]; then - # Migrate the DB to the latest schema version if needed - /usr/bin/db_migrator.py -o migrate - fi - elif [ -r /etc/sonic/minigraph.xml ]; then - echo "Use minigraph.xml from old system..." - reload_minigraph - sonic-cfggen -d --print-data > /etc/sonic/config_db.json - else - echo "Didn't found neither config_db.json nor minigraph.xml ..." - fi - rm -f /tmp/pending_config_migration - sed -i "/enabled=/d" /etc/sonic/updategraph.conf - echo "enabled=false" >> /etc/sonic/updategraph.conf - exit 0 -fi - -if [ -f /tmp/pending_config_initialization ]; then - rm -f /tmp/pending_config_initialization - if [ "$enabled" != "true" ]; then - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` - PRESET=(`head -n 1 /usr/share/sonic/device/$PLATFORM/default_sku`) - sonic-cfggen -H -k ${PRESET[0]} --preset ${PRESET[1]} > /etc/sonic/config_db.json - redis-cli -n $CONFIG_DB_INDEX FLUSHDB - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" - exit 0 - fi -fi - if [ "$enabled" = "reload_only" ]; then reload_minigraph sed -i "/enabled=/d" /etc/sonic/updategraph.conf @@ -111,6 +45,12 @@ if [ "$enabled" != "true" ]; then exit 0 fi +# If ZTP package is available and enabled, use ZTP to download and load the graph. +if [ -e /usr/bin/ztp ] && [ "$(ztp status -c)" != "0:DISABLED" ]; then + echo "ZTP is available and enabled. Skipping graph update." + exit 0 +fi + ACL_URL=$acl_src if [ "$src" = "dhcp" ]; then From d5aa0d438219d5c84bbc4ad3bfb6fdfa46ef425c Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Thu, 5 Dec 2019 03:40:42 +0800 Subject: [PATCH 0217/1427] [Mellanox]support led for fan/psu and fan's direction (#3795) --- .../sonic_platform/chassis.py | 19 ++- .../mlnx-platform-api/sonic_platform/fan.py | 134 +++++++++++++++--- .../mlnx-platform-api/sonic_platform/psu.py | 116 ++++++++++++++- 3 files changed, 244 insertions(+), 25 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 44ef8981281f..d34245390c59 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -14,6 +14,7 @@ from sonic_daemon_base.daemon_base import Logger from os import listdir from os.path import isfile, join + from glob import glob import sys import io import re @@ -33,6 +34,10 @@ HWMGMT_SYSTEM_ROOT = '/var/run/hw-management/system/' +MST_DEVICE_NAME_PATTERN = '/dev/mst/mt[0-9]*_pciconf0' +MST_DEVICE_RE_PATTERN = '/dev/mst/mt([0-9]*)_pciconf0' +SPECTRUM1_CHIP_ID = '52100' + #reboot cause related definitions REBOOT_CAUSE_ROOT = HWMGMT_SYSTEM_ROOT @@ -87,11 +92,21 @@ def initialize_fan(self): num_of_fan, num_of_drawer = self._extract_num_of_fans_and_fan_drawers() multi_rotor_in_drawer = num_of_fan > num_of_drawer + # Fan's direction isn't supported on spectrum 1 devices for now + mst_dev_list = glob(MST_DEVICE_NAME_PATTERN) + if not mst_dev_list: + raise RuntimeError("Can't get chip type due to {} not found".format(MST_DEVICE_NAME_PATTERN)) + m = re.search(MST_DEVICE_RE_PATTERN, mst_dev_list[0]) + if m.group(1) == SPECTRUM1_CHIP_ID: + has_fan_dir = False + else: + has_fan_dir = True + for index in range(num_of_fan): if multi_rotor_in_drawer: - fan = Fan(index, index/2) + fan = Fan(has_fan_dir, index, index/2) else: - fan = Fan(index, index) + fan = Fan(has_fan_dir, index, index) self._fan_list.append(fan) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py index 8b057e4123a2..818aa0f0110b 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py @@ -15,23 +15,28 @@ except ImportError as e: raise ImportError (str(e) + "- required module not found") -LED_ON = 1 -LED_OFF = 0 +LED_ON = '1' +LED_OFF = '0' PWM_MAX = 255 FAN_PATH = "/var/run/hw-management/thermal/" LED_PATH = "/var/run/hw-management/led/" +# fan_dir isn't supported on Spectrum 1. It is supported on Spectrum 2 and later switches +FAN_DIR = "/var/run/hw-management/system/fan_dir" class Fan(FanBase): """Platform-specific Fan class""" - def __init__(self, fan_index, drawer_index = 1, psu_fan = False): + + STATUS_LED_COLOR_ORANGE = "orange" + + def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False): # API index is starting from 0, Mellanox platform index is starting from 1 self.index = fan_index + 1 self.drawer_index = drawer_index + 1 self.is_psu_fan = psu_fan - + self.fan_min_speed_path = "fan{}_min".format(self.index) if not self.is_psu_fan: self.fan_speed_get_path = "fan{}_speed_get".format(self.index) @@ -48,6 +53,45 @@ def __init__(self, fan_index, drawer_index = 1, psu_fan = False): self.fan_orange_led_path = "led_fan{}_orange".format(self.drawer_index) self.fan_pwm_path = "pwm1" self.fan_led_cap_path = "led_fan{}_capability".format(self.drawer_index) + if has_fan_dir: + self.fan_dir = FAN_DIR + else: + self.fan_dir = None + + + def get_direction(self): + """ + Retrieves the fan's direction + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + + Notes: + What Mellanox calls forward: + Air flows from fans side to QSFP side, for example: MSN2700-CS2F + which means intake in community + What Mellanox calls reverse: + Air flow from QSFP side to fans side, for example: MSN2700-CS2R + which means exhaust in community + According to hw-mgmt: + 1 stands for forward, in other words intake + 0 stands for reverse, in other words exhaust + """ + if not self.fan_dir or self.is_psu_fan: + return self.FAN_DIRECTION_NOT_APPLICABLE + + try: + with open(os.path.join(self.fan_dir), 'r') as fan_dir: + fan_dir_bits = int(fan_dir.read()) + fan_mask = 1 << self.index - 1 + if fan_dir_bits & fan_mask: + return self.FAN_DIRECTION_INTAKE + else: + return self.FAN_DIRECTION_EXHAUST + except (ValueError, IOError) as e: + raise RuntimeError("Failed to read fan direction status to {}".format(repr(e))) + def get_status(self): """ @@ -68,6 +112,7 @@ def get_status(self): return status == 1 + def get_presence(self): """ Retrieves the presence status of fan @@ -89,7 +134,8 @@ def get_presence(self): status = 0 return status == 1 - + + def _get_min_speed_in_rpm(self): speed = 0 try: @@ -99,7 +145,8 @@ def _get_min_speed_in_rpm(self): speed = 0 return speed - + + def _get_max_speed_in_rpm(self): speed = 0 try: @@ -110,6 +157,7 @@ def _get_max_speed_in_rpm(self): return speed + def get_speed(self): """ Retrieves the speed of fan @@ -129,6 +177,7 @@ def get_speed(self): return speed + def get_target_speed(self): """ Retrieves the expected speed of fan @@ -151,6 +200,7 @@ def get_target_speed(self): return speed + def set_speed(self, speed): """ Set fan speed to expected value @@ -176,7 +226,8 @@ def set_speed(self, speed): status = False return status - + + def _get_led_capability(self): cap_list = None try: @@ -188,6 +239,7 @@ def _get_led_capability(self): return cap_list + def set_status_led(self, color): """ Set led to expected color @@ -208,32 +260,70 @@ def set_status_led(self, color): return False status = False try: - if color == 'green': + if color == self.STATUS_LED_COLOR_GREEN: with open(os.path.join(LED_PATH, self.fan_green_led_path), 'w') as fan_led: - fan_led.write(str(LED_ON)) - elif color == 'red': + fan_led.write(LED_ON) + status = True + elif color == self.STATUS_LED_COLOR_RED: # Some fan don't support red led but support orange led, in this case we set led to orange - if 'red' in led_cap_list: + if self.STATUS_LED_COLOR_RED in led_cap_list: led_path = os.path.join(LED_PATH, self.fan_red_led_path) - elif 'orange' in led_cap_list: + elif self.STATUS_LED_COLOR_ORANGE in led_cap_list: led_path = os.path.join(LED_PATH, self.fan_orange_led_path) else: return False with open(led_path, 'w') as fan_led: - fan_led.write(str(LED_ON)) - - elif color == 'off': - with open(os.path.join(LED_PATH, self.fan_green_led_path), 'w') as fan_led: - fan_led.write(str(LED_OFF)) - - with open(os.path.join(LED_PATH, self.fan_red_led_path), 'w') as fan_led: - fan_led.write(str(LED_OFF)) + fan_led.write(LED_ON) + status = True + elif color == self.STATUS_LED_COLOR_OFF: + if self.STATUS_LED_COLOR_GREEN in led_cap_list: + with open(os.path.join(LED_PATH, self.fan_green_led_path), 'w') as fan_led: + fan_led.write(str(LED_OFF)) + if self.STATUS_LED_COLOR_RED in led_cap_list: + with open(os.path.join(LED_PATH, self.fan_red_led_path), 'w') as fan_led: + fan_led.write(str(LED_OFF)) + if self.STATUS_LED_COLOR_ORANGE in led_cap_list: + with open(os.path.join(LED_PATH, self.fan_orange_led_path), 'w') as fan_led: + fan_led.write(str(LED_OFF)) + + status = True else: status = False except (ValueError, IOError): - status = False + status = False + return status + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + led_cap_list = self._get_led_capability() + if led_cap_list is None: + return self.STATUS_LED_COLOR_OFF + + try: + with open(os.path.join(LED_PATH, self.fan_green_led_path), 'r') as fan_led: + if LED_OFF != fan_led.read().rstrip('\n'): + return self.STATUS_LED_COLOR_GREEN + if self.STATUS_LED_COLOR_RED in led_cap_list: + with open(os.path.join(LED_PATH, self.fan_red_led_path), 'r') as fan_led: + if LED_OFF != fan_led.read().rstrip('\n'): + return self.STATUS_LED_COLOR_RED + if self.STATUS_LED_COLOR_ORANGE in led_cap_list: + with open(os.path.join(LED_PATH, self.fan_orange_led_path), 'r') as fan_led: + if LED_OFF != fan_led.read().rstrip('\n'): + return self.STATUS_LED_COLOR_RED + except (ValueError, IOError) as e: + raise RuntimeError("Failed to read led status for fan {} due to {}".format(self.index, repr(e))) + + return self.STATUS_LED_COLOR_OFF + + def get_speed_tolerance(self): """ Retrieves the speed tolerance of the fan @@ -243,4 +333,4 @@ def get_speed_tolerance(self): considered tolerable """ # The tolerance value is fixed as 20% for all the Mellanox platform - return 20 \ No newline at end of file + return 20 diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 0789f67e4f09..0e4c3fd50f7a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -16,6 +16,9 @@ except ImportError as e: raise ImportError (str(e) + "- required module not found") +LED_ON = '1' +LED_OFF = '0' + # Global logger class instance logger = Logger() @@ -25,6 +28,8 @@ PSU_VOLTAGE = "voltage" PSU_POWER = "power" +LED_PATH = "/var/run/hw-management/led/" + # SKUs with unplugable PSUs: # 1. don't have psuX_status and should be treated as always present # 2. don't have voltage, current and power values @@ -50,6 +55,9 @@ class Psu(PsuBase): """Platform-specific Psu class""" + + STATUS_LED_COLOR_ORANGE = "orange" + def __init__(self, psu_index, sku): global psu_list PsuBase.__init__(self) @@ -90,10 +98,16 @@ def __init__(self, psu_index, sku): psu_presence = os.path.join(self.psu_path, psu_presence) self.psu_presence = psu_presence - fan = Fan(psu_index, psu_index, True) + fan = Fan(sku, psu_index, psu_index, True) if fan.get_presence(): self._fan = fan + self.psu_green_led_path = "led_psu_green" + self.psu_red_led_path = "led_psu_red" + self.psu_orange_led_path = "led_psu_orange" + self.psu_led_cap_path = "led_psu_capability" + + def _read_generic_file(self, filename, len): """ Read a generic file, returns the contents of the file @@ -106,6 +120,7 @@ def _read_generic_file(self, filename, len): logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) return result + def get_powergood_status(self): """ Retrieves the operational status of power supply unit (PSU) defined @@ -117,6 +132,7 @@ def get_powergood_status(self): return status == 1 + def get_presence(self): """ Retrieves the presence status of power supply unit (PSU) defined @@ -130,6 +146,7 @@ def get_presence(self): status = self._read_generic_file(self.psu_presence, 0) return status == 1 + def get_voltage(self): """ Retrieves current PSU voltage output @@ -144,6 +161,7 @@ def get_voltage(self): else: return None + def get_current(self): """ Retrieves present electric current supplied by PSU @@ -169,3 +187,99 @@ def get_power(self): return float(power) / 1000000 else: return None + + + def _get_led_capability(self): + cap_list = None + try: + with open(os.path.join(LED_PATH, self.psu_led_cap_path), 'r') as psu_led_cap: + caps = psu_led_cap.read() + cap_list = caps.split() + except (ValueError, IOError): + status = 0 + + return cap_list + + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + + Args: + color: A string representing the color with which to set the + PSU status LED + + Returns: + bool: True if status LED state is set successfully, False if not + + Notes: + Only one led for all PSUs. + """ + led_cap_list = self._get_led_capability() + if led_cap_list is None: + return False + + status = False + try: + if color == self.STATUS_LED_COLOR_GREEN: + with open(os.path.join(LED_PATH, self.psu_green_led_path), 'w') as psu_led: + psu_led.write(LED_ON) + status = True + elif color == self.STATUS_LED_COLOR_RED: + # Some fan don't support red led but support orange led, in this case we set led to orange + if self.STATUS_LED_COLOR_RED in led_cap_list: + led_path = os.path.join(LED_PATH, self.psu_red_led_path) + elif self.STATUS_LED_COLOR_ORANGE in led_cap_list: + led_path = os.path.join(LED_PATH, self.psu_orange_led_path) + else: + return False + with open(led_path, 'w') as psu_led: + psu_led.write(LED_ON) + status = True + elif color == self.STATUS_LED_COLOR_OFF: + if self.STATUS_LED_COLOR_GREEN in led_cap_list: + with open(os.path.join(LED_PATH, self.psu_green_led_path), 'w') as psu_led: + psu_led.write(str(LED_OFF)) + if self.STATUS_LED_COLOR_RED in led_cap_list: + with open(os.path.join(LED_PATH, self.psu_red_led_path), 'w') as psu_led: + psu_led.write(str(LED_OFF)) + if self.STATUS_LED_COLOR_ORANGE in led_cap_list: + with open(os.path.join(LED_PATH, self.psu_orange_led_path), 'w') as psu_led: + psu_led.write(str(LED_OFF)) + + status = True + else: + status = False + except (ValueError, IOError): + status = False + + return status + + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + led_cap_list = self._get_led_capability() + if led_cap_list is None: + return self.STATUS_LED_COLOR_OFF + + try: + with open(os.path.join(LED_PATH, self.psu_green_led_path), 'r') as psu_led: + if LED_OFF != psu_led.read().rstrip('\n'): + return self.STATUS_LED_COLOR_GREEN + if self.STATUS_LED_COLOR_RED in led_cap_list: + with open(os.path.join(LED_PATH, self.psu_red_led_path), 'r') as psu_led: + if LED_OFF != psu_led.read().rstrip('\n'): + return self.STATUS_LED_COLOR_RED + if self.STATUS_LED_COLOR_ORANGE in led_cap_list: + with open(os.path.join(LED_PATH, self.psu_orange_led_path), 'r') as psu_led: + if LED_OFF != psu_led.read().rstrip('\n'): + return self.STATUS_LED_COLOR_RED + except (ValueError, IOError) as e: + raise RuntimeError("Failed to read led status for psu due to {}".format(repr(e))) + + return self.STATUS_LED_COLOR_OFF From 1848fb262b0ad24a8791d9ff8aa8d95764b470c8 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 4 Dec 2019 14:10:19 -0800 Subject: [PATCH 0218/1427] [fast-reboot]: Save fast-reboot state into the db (#3741) Put a flag for fast-reboot to the db using EXPIRE feature. Using this flag in other part of SONiC to start in Fast-reboot mode. If we reload a config, the state in the db will be removed. --- dockers/docker-base-stretch/Dockerfile.j2 | 8 +++++++- dockers/docker-orchagent/Dockerfile.j2 | 7 ------- dockers/docker-sonic-telemetry/Dockerfile.j2 | 9 +-------- dockers/docker-teamd/Dockerfile.j2 | 9 +-------- files/build_templates/docker_image_ctl.j2 | 5 +++++ files/scripts/syncd.sh | 7 ++++++- rules/docker-base-stretch.mk | 2 +- src/sonic-quagga | 2 +- 8 files changed, 22 insertions(+), 27 deletions(-) diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 95272e2322ce..3b3ede376d12 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -47,7 +47,13 @@ RUN apt-get update && \ vim-tiny \ # Install dependencies of supervisor python-pkg-resources \ - python-meld3 + python-meld3 \ +# dependencies of redis-tools + libatomic1 \ + libjemalloc1 \ + liblua5.1-0 \ + lua-bitop \ + lua-cjson {% if CONFIGURED_ARCH == "armhf" %} # ip and ifconfig utility missing in docker for armhf diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index f01bca724094..8a66e2adbe43 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -18,13 +18,6 @@ RUN apt-get update && \ iproute2 \ ndisc6 \ tcpdump \ - # Install redis-tools dependencies - # TODO: implicitly install dependencies - libatomic1 \ - libjemalloc1 \ - liblua5.1-0 \ - lua-bitop \ - lua-cjson \ libelf1 \ libmnl0 \ bridge-utils diff --git a/dockers/docker-sonic-telemetry/Dockerfile.j2 b/dockers/docker-sonic-telemetry/Dockerfile.j2 index 3a5716001ca5..e94441b4f066 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/Dockerfile.j2 @@ -11,14 +11,7 @@ RUN apt-get update && \ apt-get install -f -y \ libdbus-1-3 \ libdaemon0 \ - libjansson4 \ - # Install redis-tools dependencies - # TODO: implicitly install dependencies - libatomic1 \ - libjemalloc1 \ - liblua5.1-0 \ - lua-bitop \ - lua-cjson + libjansson4 {% if docker_sonic_telemetry_debs.strip() -%} # Copy locally-built Debian package dependencies diff --git a/dockers/docker-teamd/Dockerfile.j2 b/dockers/docker-teamd/Dockerfile.j2 index fc8626e77229..4282a10d0c86 100644 --- a/dockers/docker-teamd/Dockerfile.j2 +++ b/dockers/docker-teamd/Dockerfile.j2 @@ -12,14 +12,7 @@ RUN apt-get update && \ libdbus-1-3 \ libdaemon0 \ libjansson4 \ - libpython2.7 \ - # Install redis-tools dependencies - # TODO: implicitly install dependencies - libatomic1 \ - libjemalloc1 \ - liblua5.1-0 \ - lua-bitop \ - lua-cjson + libpython2.7 {% if docker_teamd_debs.strip() -%} # Copy locally-built Debian package dependencies diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index c485254647b8..167a392730e4 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -149,6 +149,11 @@ function postStartAction() sonic-cfggen -j /etc/sonic/config_db.json --write-to-db fi + if [[ "$BOOT_TYPE" == "fast" ]]; then + # set the key to expire in 3 minutes + redis-cli -n 6 SET "FAST_REBOOT|system" "1" "EX" "180" + fi + redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" fi diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 2b7c76263d8a..89f15f0f413f 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -64,7 +64,12 @@ function getBootType() TYPE='fastfast' ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) - TYPE=$(awk '{ if ($1 <= 180) print "fast"; else print "cold" }' /proc/uptime) + # check that the key exists + if [[ $(redis-cli -n 6 GET "FAST_REBOOT|system") == "1" ]]; then + TYPE='fast' + else + TYPE='cold' + fi ;; *) TYPE='cold' diff --git a/rules/docker-base-stretch.mk b/rules/docker-base-stretch.mk index 55b7fd9f8661..a54f4ec092aa 100644 --- a/rules/docker-base-stretch.mk +++ b/rules/docker-base-stretch.mk @@ -2,7 +2,7 @@ DOCKER_BASE_STRETCH = docker-base-stretch.gz $(DOCKER_BASE_STRETCH)_PATH = $(DOCKERS_PATH)/docker-base-stretch -$(DOCKER_BASE_STRETCH)_DEPENDS += $(SUPERVISOR) +$(DOCKER_BASE_STRETCH)_DEPENDS += $(SUPERVISOR) $(REDIS_TOOLS) $(DOCKER_BASE_STRETCH)_DEPENDS += $(SOCAT) GDB = gdb diff --git a/src/sonic-quagga b/src/sonic-quagga index 904a35010779..7101eeda1a1c 160000 --- a/src/sonic-quagga +++ b/src/sonic-quagga @@ -1 +1 @@ -Subproject commit 904a350107793d44be7167500fcec9087ca3243b +Subproject commit 7101eeda1a1ccef2e951e4bea5a2f15d9a43e3b5 From 77b8e74fc0283ff41b60225a172596bb0e93bea8 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 5 Dec 2019 10:00:13 +0700 Subject: [PATCH 0219/1427] [platform/device] - Implement Silverstone platform API [PSU] (#3784) Implement part of the Chassis and Fan related APIs. Psu APIs get_voltage() get_current() get_power() get_powergood_status() set_status_led() get_status_led() Update Fan APIs to support PSU FAN get_direction() get_speed() get_target_speed() get_speed_tolerance() get_target_speed() PSU APIs base on Device API get_name() get_presence() get_model() get_serial() get_status() - How I did it Implement PSU APIs Update FAN API to support PSU Fans Add PSU object to Chassis API --- .../sonic_platform/chassis.py | 4 + .../sonic_platform/fan.py | 36 ++- .../sonic_platform/psu.py | 243 ++++++++++++++++++ 3 files changed, 278 insertions(+), 5 deletions(-) create mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py index dc622016cbb2..d984b3578b27 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py @@ -18,6 +18,7 @@ from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.eeprom import Tlv from sonic_platform.fan import Fan + from sonic_platform.psu import Psu from helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -46,6 +47,9 @@ def __init__(self): for fan_index in range(0, NUM_FAN): fan = Fan(fant_index, fan_index) self._fan_list.append(fan) + for index in range(0, NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) def get_base_mac(self): """ diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py index 902de261f8cb..d1b36effc1ac 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py @@ -30,7 +30,7 @@ IPMI_SET_FAN_LED_CMD = "0x07 {} {}" IPMI_GET_FAN_LED_CMD = "0x08 {}" IPMI_SET_PWM = "0x03 0x01 0x02 {} {}" -IPMI_FRU_PRINT_ID = "ipmitool fru print {}" + IPMI_FRU_MODEL_KEY = "Board Part Number" IPMI_FRU_SERIAL_KEY = "Board Serial" @@ -48,6 +48,9 @@ FAN_PWM_REGISTER_STEP = 0x10 FAN1_FRU_ID = 6 +NUM_OF_FAN_TRAY = 7 +PSU_FAN1_FRONT_SS_ID = "0x33" + class Fan(FanBase): """Platform-specific Fan class""" @@ -69,8 +72,10 @@ def get_direction(self): depending on fan direction """ direction = self.FAN_DIRECTION_EXHAUST + fan_direction_key = hex(self.fan_tray_index) if not self.is_psu_fan else hex( + self.psu_index + NUM_OF_FAN_TRAY) status, raw_flow = self._api_helper.ipmi_raw( - IPMI_OEM_NETFN, IPMI_AIR_FLOW_CMD.format(hex(self.fan_tray_index))) + IPMI_OEM_NETFN, IPMI_AIR_FLOW_CMD.format(fan_direction_key)) if status and raw_flow == "01": direction = self.FAN_DIRECTION_INTAKE @@ -88,13 +93,12 @@ def get_speed(self): Max F2B = 24700 RPM Max B2F = 29700 RPM """ - # ipmitool raw 0x3a 0x03 0x01 0x01 {register} - # register = 22 32 42 52 62 72 82 max_rpm = MAX_OUTLET if self.fan_index % 2 == 0 else MAX_INLET fan1_ss_start = FAN1_FRONT_SS_ID if self.fan_index % 2 == 0 else FAN1_REAR_SS_ID - ss_id = hex(int(fan1_ss_start, 16) + self.fan_tray_index) + ss_id = hex(int(fan1_ss_start, 16) + self.fan_tray_index) if not self.psu_index else hex( + int(PSU_FAN1_FRONT_SS_ID, 16) + self.fan_tray_index) status, raw_ss_read = self._api_helper.ipmi_raw( IPMI_SENSOR_NETFN, IPMI_FAN_SPEED_CMD.format(ss_id)) @@ -145,6 +149,10 @@ def set_speed(self, speed): # ipmitool raw 0x3a 0x03 0x01 0x02 {register} {pwm_speed} # register = 22 32 42 52 62 72 82 + if self.is_psu_fan: + ## TODO + return False + speed_hex = hex(int(float(speed)/100 * 255)) fan_register_hex = hex(FAN_PWM_REGISTER_START + (self.fan_tray_index*FAN_PWM_REGISTER_STEP)) @@ -171,6 +179,11 @@ def set_status_led(self, color): manual: ipmitool raw 0x3A 0x09 0x02 0x00 auto: ipmitool raw 0x3A 0x09 0x02 0x01 """ + + if self.is_psu_fan: + # Not support + return False + led_cmd = { self.STATUS_LED_COLOR_GREEN: FAN_LED_GREEN_CMD, self.STATUS_LED_COLOR_RED: FAN_LED_RED_CMD, @@ -196,6 +209,10 @@ def get_status_led(self): STATUS_LED_COLOR_RED = "red" STATUS_LED_COLOR_OFF = "off" """ + if self.is_psu_fan: + # Not support + return self.STATUS_LED_COLOR_OFF + fan_selector = hex(int(FAN1_LED_CMD, 16) + self.fan_tray_index) status, hx_color = self._api_helper.ipmi_raw( IPMI_OEM_NETFN, IPMI_GET_FAN_LED_CMD.format(fan_selector)) @@ -225,6 +242,9 @@ def get_presence(self): Returns: bool: True if FAN is present, False if not """ + if self.is_psu_fan: + return True + presence = False status, raw_present = self._api_helper.ipmi_raw( IPMI_OEM_NETFN, IPMI_FAN_PRESENT_CMD.format(hex(self.index))) @@ -239,6 +259,9 @@ def get_model(self): Returns: string: Model/part number of device """ + if self.is_psu_fan: + return "Unknown" + model = "Unknown" ipmi_fru_idx = self.fan_tray_index + FAN1_FRU_ID status, raw_model = self._api_helper.ipmi_fru_id( @@ -256,6 +279,9 @@ def get_serial(self): Returns: string: Serial number of device """ + if self.is_psu_fan: + return "Unknown" + serial = "Unknown" ipmi_fru_idx = self.fan_tray_index + FAN1_FRU_ID status, raw_model = self._api_helper.ipmi_fru_id( diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py new file mode 100644 index 000000000000..c5d2270d2657 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py @@ -0,0 +1,243 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +import os +import re +import math +import sonic_platform + +try: + from sonic_platform_base.psu_base import PsuBase + from helper import APIHelper + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PSU_NAME_LIST = ["PSU-1", "PSU-2"] +PSU_NUM_FAN = [1, 1] + +IPMI_SENSOR_NETFN = "0x04" +IPMI_OEM_NETFN = "0x3A" +IPMI_SS_READ_CMD = "0x2D {}" +IPMI_SET_PSU_LED_CMD = "0x07 0x02 {}" +IPMI_GET_PSU_LED_CMD = "0x08 0x02" +IPMI_FRU_MODEL_KEY = "Board Part Number" +IPMI_FRU_SERIAL_KEY = "Board Serial" + +PSU_LED_OFF_CMD = "0x00" +PSU_LED_GREEN_CMD = "0x01" +PSU_LED_AMBER_CMD = "0x02" + +PSU1_VOUT_SS_ID = "0x36" +PSU1_COUT_SS_ID = "0x37" +PSU1_POUT_SS_ID = "0x38" +PSU1_STATUS_REG = "0x39" + +PSU2_VOUT_SS_ID = "0x40" +PSU2_COUT_SS_ID = "0x41" +PSU2_POUT_SS_ID = "0x42" +PSU2_STATUS_REG = "0x2f" + +PSU1_FRU_ID = 3 + +SS_READ_OFFSET = 0 + + +class Psu(PsuBase): + """Platform-specific Psu class""" + + def __init__(self, psu_index): + PsuBase.__init__(self) + self.index = psu_index + for fan_index in range(0, PSU_NUM_FAN[self.index]): + fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index) + self._fan_list.append(fan) + self._api_helper = APIHelper() + + def find_value(self, in_string): + result = re.search("^.+ ([0-9a-f]{2}) .+$", in_string) + return result.group(1) if result else result + + def get_voltage(self): + """ + Retrieves current PSU voltage output + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + psu_voltage = 0.0 + psu_vout_key = globals()['PSU{}_VOUT_SS_ID'.format(self.index+1)] + status, raw_ss_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_vout_key)) + ss_read = raw_ss_read.split()[SS_READ_OFFSET] + # Formula: Rx1x10^-1 + psu_voltage = int(ss_read, 16) * math.pow(10, -1) + + return psu_voltage + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + psu_current = 0.0 + psu_cout_key = globals()['PSU{}_COUT_SS_ID'.format(self.index+1)] + status, raw_ss_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_cout_key)) + ss_read = raw_ss_read.split()[SS_READ_OFFSET] + # Formula: Rx5x10^-1 + psu_current = int(ss_read, 16) * 5 * math.pow(10, -1) + + return psu_current + + def get_power(self): + """ + Retrieves current energy supplied by PSU + Returns: + A float number, the power in watts, e.g. 302.6 + """ + psu_power = 0.0 + psu_pout_key = globals()['PSU{}_POUT_SS_ID'.format(self.index+1)] + status, raw_ss_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_pout_key)) + ss_read = raw_ss_read.split()[SS_READ_OFFSET] + # Formula: Rx6x10^0 + psu_power = int(ss_read, 16) * 6 + return psu_power + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the PSU status LED + Note: Only support green and off + Returns: + bool: True if status LED state is set successfully, False if not + Note + Set manual + ipmitool raw 0x3a 0x09 0x2 0x0 + """ + led_cmd = { + self.STATUS_LED_COLOR_GREEN: PSU_LED_GREEN_CMD, + self.STATUS_LED_COLOR_AMBER: PSU_LED_AMBER_CMD, + self.STATUS_LED_COLOR_OFF: PSU_LED_OFF_CMD + }.get(color) + + status, set_led = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_SET_PSU_LED_CMD.format(led_cmd)) + set_status_led = False if not status else True + + return set_status_led + + def get_status_led(self): + """ + Gets the state of the PSU status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + status, hx_color = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_GET_PSU_LED_CMD) + + status_led = { + "00": self.STATUS_LED_COLOR_OFF, + "01": self.STATUS_LED_COLOR_GREEN, + "02": self.STATUS_LED_COLOR_AMBER, + }.get(hx_color, self.STATUS_LED_COLOR_OFF) + + return status_led + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return PSU_NAME_LIST[self.index] + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + psu_presence = False + psu_pstatus_key = globals()['PSU{}_STATUS_REG'.format(self.index+1)] + status, raw_status_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_pstatus_key)) + status_byte = self.find_value(raw_status_read) + + if status: + presence_int = (int(status_byte, 16) >> 0) & 1 + psu_presence = True if presence_int else False + + return psu_presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + model = "Unknown" + ipmi_fru_idx = self.index + PSU1_FRU_ID + status, raw_model = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_MODEL_KEY) + + fru_pn_list = raw_model.split() + if len(fru_pn_list) > 4: + model = fru_pn_list[4] + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + serial = "Unknown" + ipmi_fru_idx = self.index + PSU1_FRU_ID + status, raw_model = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_SERIAL_KEY) + + fru_sr_list = raw_model.split() + if len(fru_sr_list) > 3: + serial = fru_sr_list[3] + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + psu_status = False + psu_pstatus_key = globals()['PSU{}_STATUS_REG'.format(self.index+1)] + status, raw_status_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_pstatus_key)) + status_byte = self.find_value(raw_status_read) + + if status: + failure_detected = (int(status_byte, 16) >> 1) & 1 + input_lost = (int(status_byte, 16) >> 3) & 1 + psu_status = False if (input_lost or failure_detected) else True + + return psu_status From 157317d7105351225151c51abc71fb35d01beb2a Mon Sep 17 00:00:00 2001 From: Sujin Kang <54082335+sujinmkang@users.noreply.github.com> Date: Wed, 4 Dec 2019 20:27:39 -0800 Subject: [PATCH 0220/1427] [doc]: Remove all non-existing build jobs from README.md (#3844) --- README.md | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/README.md b/README.md index 1ab18f5e646f..a1de15524b63 100644 --- a/README.md +++ b/README.md @@ -9,35 +9,21 @@ VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimag *201904*: Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201904/) -Barefoot: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201904/) -Centec: [![Centec](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201904/) -Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201904/) -Marvell: [![Marvell](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201904/) Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201904/) -VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201904) *201811*: Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/) Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/) -Barefoot: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201811/) -Centec: [![Centec](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201811/) -Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811/) -Marvell: [![Marvell](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201811/) Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/) VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811) *201807*: Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/) -Barefoot: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/) -Centec: [![Centec](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201807/) -Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201807/) -Marvell: [![Marvell](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201807/) +Barefoot: [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/) Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201807/) *201803*: Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/) -Cavium: [![Cavium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/cavium/job/buildimage-cavm-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/cavium/job/buildimage-cavm-201803/) -Centec: [![Centec](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201803/) Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/) Marvell: [![Marvell](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/) Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/) From f345935aec5325c76d34d1fa38f158a9171dbbe9 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Thu, 5 Dec 2019 21:23:16 +0200 Subject: [PATCH 0221/1427] [submodule]: Advance sonic-platform-common. (#3848) Signed-off-by: Nazarii Hnydyn --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index d22f0a0e64f3..6ad48b87eb96 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit d22f0a0e64f30e9e26064824fb11f27b2d636850 +Subproject commit 6ad48b87eb9654daa3f3c854134434d14572573f From 8ab75e0e90879a8b59a55b16f89ca4f4c2439d55 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 7 Dec 2019 11:26:29 -0800 Subject: [PATCH 0222/1427] [isc-dhcp-relay] Patch to allow relay to discover interfaces even if (#3851) Patch isc-dhcp-relay in order to allow the relay agent to discover configured interfaces even if they are down. Without this patch, the relay agent will not discover configured interfaces if they are down when the relay agent starts up. If the interface(s) then get brought up after the relay started, the relay will discard packets received on these interfaces and log the message, Discarding packet received on interface that has no IPv4 address assigned. This led to race conditions when starting SONiC (or loading configuration). To resolve this, the relay agent would need to be restarted with all configured interfaces up. With this patch, the relay agent will discover all configured interfaces, whether or not they are up at the time the relay agent starts. Thus, the state of the configured interfaces can be down when the relay agent starts and brought up during the lifetime of the relay agent process, and the relay agent will relay packets as expected; it will not discard them. --- ...interfaces-when-discovering-interfac.patch | 32 +++++++++++++++++++ src/isc-dhcp/patch/series | 1 + 2 files changed, 33 insertions(+) create mode 100644 src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch diff --git a/src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch b/src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch new file mode 100644 index 000000000000..f088b035edb4 --- /dev/null +++ b/src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch @@ -0,0 +1,32 @@ +From 06850e9beb2c50b5cc23fc94168acd9ae58d8ef8 Mon Sep 17 00:00:00 2001 +From: Joe LeVeque +Date: Fri, 6 Dec 2019 05:53:09 +0000 +Subject: [PATCH] Don't skip down interfaces when discovering interfaces in + relay mode + +When discovering interfaces in relay mode, don't skip interfaces just +because they're down. If we fail to discover the interfaces because they +are down when the relay starts, but then are brought up at a later point +in time, the relay will discard any packets received on them because it +didn't discover the interface(s) when it started up. +--- + common/discover.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/common/discover.c b/common/discover.c +index 8d5b958..5efff49 100644 +--- a/common/discover.c ++++ b/common/discover.c +@@ -1016,7 +1016,8 @@ discover_interfaces(int state) { + info.flags & IFF_LOOPBACK || + info.flags & IFF_POINTOPOINT) && !tmp) || + (!(info.flags & IFF_UP) && +- state != DISCOVER_UNCONFIGURED)) ++ state != DISCOVER_UNCONFIGURED && ++ state != DISCOVER_RELAY)) + continue; + + /* If there isn't already an interface by this name, +-- +2.17.1 + diff --git a/src/isc-dhcp/patch/series b/src/isc-dhcp/patch/series index 1b83f2166b96..ec68967e28b9 100644 --- a/src/isc-dhcp/patch/series +++ b/src/isc-dhcp/patch/series @@ -10,3 +10,4 @@ 0009-CVE-2018-5733.patch 0010-CVE-2018-5732.patch 0008-interface-name-maxlen-crash.patch +0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch From 90ddad48d1ff0a1482867b12b7552e1d774a6fd7 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Sun, 8 Dec 2019 03:28:49 +0800 Subject: [PATCH 0223/1427] [mellanox ]improve the method the type of sfp module is detected (#3846) Fix the issue when an SFP module is plugged into a QSFP port via an adapter. - How I did it Originally the type of an SFP module is determined according to the SKU dictionary. However, it's possible that as SFP module is plugged into a QSFP port via an adapter. In this case, the EEPROM content will be parsed in the wrong format. To address that we fetch the identifier value of an xSFP module and then get the type by parsing it. --- .../mlnx-platform-api/sonic_platform/sfp.py | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 845f355e28f1..254d9c2e3e58 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -136,6 +136,26 @@ SFP_CHANNL_STATUS_OFFSET = 110 SFP_CHANNL_STATUS_WIDTH = 1 +# identifier value of xSFP module which is in the first byte of the EEPROM +# if the identifier value falls into SFP_TYPE_CODE_LIST the module is treated as a SFP module and parsed according to 8472 +# for QSFP_TYPE_CODE_LIST the module is treated as a QSFP module and parsed according to 8436/8636 +# Originally the type (SFP/QSFP) of each module is determined according to the SKU dictionary +# where the type of each FP port is defined. The content of EEPROM is parsed according to its type. +# However, sometimes the SFP module can be fit in an adapter and then pluged into a QSFP port. +# In this case the EEPROM content is in format of SFP but parsed as QSFP, causing failure. +# To resolve that issue the type field of the xSFP module is also fetched so that we can know exectly what type the +# module is. Currently only the following types are recognized as SFP/QSFP module. +# Meanwhile, if the a module's identifier value can't be recognized, it will be parsed according to the SKU dictionary. +# This is because in the future it's possible that some new identifier value which is not regonized but backward compatible +# with the current format and by doing so it can be parsed as much as possible. +SFP_TYPE_CODE_LIST = [ + '03' # SFP/SFP+/SFP28 +] +QSFP_TYPE_CODE_LIST = [ + '0d', # QSFP+ or later + '11' # QSFP28 or later +] + qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') @@ -206,7 +226,7 @@ def __init__(self, sfp_index, sfp_type): self.index = sfp_index + 1 self.sfp_eeprom_path = "qsfp{}".format(self.index) self.sfp_status_path = "qsfp{}_status".format(self.index) - self.sfp_type = sfp_type + self._detect_sfp_type(sfp_type) self.dom_tx_disable_supported = False self._dom_capability_detect() self.sdk_handle = None @@ -293,6 +313,26 @@ def _read_eeprom_specific_bytes(self, offset, num_bytes): return eeprom_raw + def _detect_sfp_type(self, sfp_type): + eeprom_raw = [] + eeprom_raw = self._read_eeprom_specific_bytes(XCVR_TYPE_OFFSET, XCVR_TYPE_WIDTH) + if eeprom_raw: + if eeprom_raw[0] in SFP_TYPE_CODE_LIST: + self.sfp_type = SFP_TYPE + elif eeprom_raw[0] in QSFP_TYPE_CODE_LIST: + self.sfp_type = QSFP_TYPE + else: + # we don't regonize this identifier value, treat the xSFP module as the default type + self.sfp_type = sfp_type + logger.log_info("Identifier value of {} module {} is {} which isn't regonized and will be treated as default type ({})".format( + sfp_type, self.index, eeprom_raw[0], sfp_type + )) + else: + # eeprom_raw being None indicates the module is not present. + # in this case we treat it as the default type according to the SKU + self.sfp_type = sfp_type + + def _dom_capability_detect(self): if not self.get_presence(): self.dom_supported = False @@ -303,7 +343,7 @@ def _dom_capability_detect(self): self.calibration = 0 return - if self.sfp_type == "QSFP": + if self.sfp_type == QSFP_TYPE: self.calibration = 1 sfpi_obj = sff8436InterfaceId() if sfpi_obj is None: @@ -348,7 +388,7 @@ def _dom_capability_detect(self): self.dom_tx_power_supported = False self.calibration = 0 self.qsfp_page3_available = False - elif self.sfp_type == "SFP": + elif self.sfp_type == SFP_TYPE: sfpi_obj = sff8472InterfaceId() if sfpi_obj is None: return None From d39f10b31fafeb4ca55d6551bfa1cba26e384306 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 7 Dec 2019 20:18:49 -0800 Subject: [PATCH 0224/1427] Revert "[dhcp_relay] Add extra sleep before starting relay agent processes (#3824)" (#3857) This reverts commit 7622a30d98553288ca5cb53bb3b1eff210d40a77. --- dockers/docker-dhcp-relay/start.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index 54e58dd42a07..0ac5ea1a10ec 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -16,12 +16,6 @@ if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then # lifetime of the process. /usr/bin/wait_for_intf.sh - # Allow a bit more time for interfaces to settle before starting the - # relay agent processes. - # FIXME: Remove/decrease this once we determine how to prevent future race - # conditions here. - sleep 180 - # Start all DHCP relay agent(s) supervisorctl start isc-dhcp-relay:* fi From 335514bf87ee93f6d4c381192574dc82ae6547c4 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Mon, 9 Dec 2019 18:42:29 -0800 Subject: [PATCH 0225/1427] [swss-common] update submodule for sonic-swss-common (#3863) --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index a4a1e108afb3..29a2cdfe9ea9 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit a4a1e108afb3e75717e204da49a975681d964e8c +Subproject commit 29a2cdfe9ea9bb0c4d2d82be9428228a8ab6b9d4 From fec80293dd22c358b5ccc68eedc23d9feb15aca5 Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Tue, 10 Dec 2019 11:16:56 -0500 Subject: [PATCH 0226/1427] ZTP infrastructure changes to support DHCP discovery provisioning data (#3298) * ZTP infrastructure changes to support DHCP discovery provisioning data - Dynamically generate DHCP client configuration based on current ZTP state - Added support to request and process hostname when using DHCPv6 - Do not process graphservice url dhcp option if ZTP is enabled, ZTP service will process it - Generate /e/n/i file with all active interfaces seeking address assignment via DHCP. Only interfaces that are created in Linux will be added to /e/n/i. Also DHCP is started only on linked up in-band interfaces. Signed-off-by: Rajendra Dendukuri --- build_debian.sh | 5 +-- .../build_templates/sonic_debian_extension.j2 | 6 +++ files/dhcp/90-dhcp6-systcl.conf.j2 | 7 +++ files/dhcp/dhclient.conf | 24 ---------- files/dhcp/dhclient.conf.j2 | 45 +++++++++++++++++++ files/dhcp/graphserviceurl | 26 ++++++----- files/dhcp/ifupdown2_policy.json | 12 +++++ files/dhcp/rfc3442-classless-routes | 7 ++- files/dhcp/sethostname6 | 14 ++++++ .../interfaces/interfaces-config.sh | 32 ++++++++++++- files/image_config/interfaces/interfaces.j2 | 36 +++++++++++++++ 11 files changed, 172 insertions(+), 42 deletions(-) create mode 100644 files/dhcp/90-dhcp6-systcl.conf.j2 delete mode 100644 files/dhcp/dhclient.conf create mode 100644 files/dhcp/dhclient.conf.j2 create mode 100644 files/dhcp/ifupdown2_policy.json create mode 100644 files/dhcp/sethostname6 diff --git a/build_debian.sh b/build_debian.sh index fb3ecfef6ce6..666e140416c9 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -392,9 +392,6 @@ set /files/etc/sysctl.conf/net.ipv6.conf.default.keep_addr_on_down 1 set /files/etc/sysctl.conf/net.ipv6.conf.all.keep_addr_on_down 1 set /files/etc/sysctl.conf/net.ipv6.conf.eth0.keep_addr_on_down 1 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra_defrtr 0 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra 0 - set /files/etc/sysctl.conf/net.ipv4.tcp_l3mdev_accept 1 set /files/etc/sysctl.conf/net.ipv4.udp_l3mdev_accept 1 @@ -429,10 +426,10 @@ EOF sudo cp files/dhcp/rfc3442-classless-routes $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d sudo cp files/dhcp/sethostname $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ +sudo cp files/dhcp/sethostname6 $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/graphserviceurl $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/snmpcommunity $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/vrf $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ -sudo cp files/dhcp/dhclient.conf $FILESYSTEM_ROOT/etc/dhcp/ if [ -f files/image_config/ntp/ntp ]; then sudo cp ./files/image_config/ntp/ntp $FILESYSTEM_ROOT/etc/init.d/ fi diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 209bc19971b3..4e81593298f6 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -203,6 +203,12 @@ sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/interfaces/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ echo "interfaces-config.service" | sudo tee -a $GENERATED_SERVICE_FILE +# Copy dhcp client configuration template and create an initial configuration +sudo cp files/dhcp/dhclient.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +j2 files/dhcp/dhclient.conf.j2 | sudo tee $FILESYSTEM_ROOT/etc/dhcp/dhclient.conf +sudo cp files/dhcp/ifupdown2_policy.json $FILESYSTEM_ROOT/etc/network/ifupdown2/policy.d +sudo cp files/dhcp/90-dhcp6-systcl.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ + # Copy initial interfaces configuration file, will be overwritten on first boot sudo cp $IMAGE_CONFIGS/interfaces/init_interfaces $FILESYSTEM_ROOT/etc/network/interfaces sudo mkdir -p $FILESYSTEM_ROOT/etc/network/interfaces.d diff --git a/files/dhcp/90-dhcp6-systcl.conf.j2 b/files/dhcp/90-dhcp6-systcl.conf.j2 new file mode 100644 index 000000000000..addb94675258 --- /dev/null +++ b/files/dhcp/90-dhcp6-systcl.conf.j2 @@ -0,0 +1,7 @@ +{% if MGMT_INTERFACE %} +net.ipv6.conf.eth0.accept_ra_defrtr = 0 +net.ipv6.conf.eth0.accept_ra = 0 +{% else %} +net.ipv6.conf.eth0.accept_ra_defrtr = 1 +net.ipv6.conf.eth0.accept_ra = 1 +{% endif %} diff --git a/files/dhcp/dhclient.conf b/files/dhcp/dhclient.conf deleted file mode 100644 index 6a542e069fab..000000000000 --- a/files/dhcp/dhclient.conf +++ /dev/null @@ -1,24 +0,0 @@ -# Configuration file for /sbin/dhclient, which is included in Debian's -# dhcp3-client package. -# -# This is a sample configuration file for dhclient. See dhclient.conf's -# man page for more information about the syntax of this file -# and a more comprehensive list of the parameters understood by -# dhclient. -# -# Normally, if the DHCP server provides reasonable information and does -# not leave anything out (like the domain name, for example), then -# few changes must be made to this file, if any. -# - -option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; -option snmp-community code 224 = text; -option minigraph-url code 225 = text; -option acl-url code 226 = text; - -send host-name = gethostname(); -request subnet-mask, broadcast-address, time-offset, routers, - domain-name, domain-name-servers, domain-search, host-name, - dhcp6.name-servers, dhcp6.domain-search, interface-mtu, - rfc3442-classless-static-routes, ntp-servers, - snmp-community, minigraph-url, acl-url; diff --git a/files/dhcp/dhclient.conf.j2 b/files/dhcp/dhclient.conf.j2 new file mode 100644 index 000000000000..2a6f6fa84fbd --- /dev/null +++ b/files/dhcp/dhclient.conf.j2 @@ -0,0 +1,45 @@ +{% block banner %} +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/dhclient.conf.j2 using sonic-cfggen +# file: /etc/dhcp/dhclient.conf +# +{% endblock banner %} +# Configuration file for /sbin/dhclient, which is included in Debian's +# dhcp3-client package. +# +# This is a sample configuration file for dhclient. See dhclient.conf's +# man page for more information about the syntax of this file +# and a more comprehensive list of the parameters understood by +# dhclient. +# +# Normally, if the DHCP server provides reasonable information and does +# not leave anything out (like the domain name, for example), then +# few changes must be made to this file, if any. +# + +option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; +option snmp-community code 224 = text; +option minigraph-url code 225 = text; +option acl-url code 226 = text; +option tftp-server-name code 66 = text; +option bootfile-name code 67 = text; +option user-class code 77 = text; +option provisioning-script-url code 239 = text; +option dhcp6.user-class code 15 = text; +option dhcp6.provisioning-script-url code 239 = text; +option dhcp6.boot-file-url code 59 = text; + +send host-name = gethostname(); +request subnet-mask, broadcast-address, time-offset, routers, + domain-name, domain-name-servers, domain-search, host-name, + dhcp6.name-servers, dhcp6.domain-search, interface-mtu, dhcp6.fqdn, + rfc3442-classless-static-routes, ntp-servers, log-servers, +{%- if ZTP is defined and ZTP_DHCP_DISABLED is not defined -%}bootfile-name, provisioning-script-url, tftp-server-name, + dhcp6.provisioning-script-url, dhcp6.boot-file-url,{%- endif -%} + snmp-community, minigraph-url, acl-url; +{% if ZTP is defined and ZTP_DHCP_DISABLED is not defined %} +send user-class "SONiC-ZTP"; +send dhcp6.user-class "SONiC-ZTP"; +send dhcp-client-identifier "SONiC##{{ ZTP['mode']['product-name'] }}##{{ ZTP['mode']['serial-no'] }}"; +retry 60; +{% endif %} diff --git a/files/dhcp/graphserviceurl b/files/dhcp/graphserviceurl index f255cdff9877..9bd5fded4b8f 100644 --- a/files/dhcp/graphserviceurl +++ b/files/dhcp/graphserviceurl @@ -1,12 +1,14 @@ -case $reason in - BOUND|RENEW|REBIND|REBOOT) - if [ -n "$new_minigraph_url" ]; then - echo $new_minigraph_url > /tmp/dhcp_graph_url - else - echo "N/A" > /tmp/dhcp_graph_url - fi - if [ -n "$new_acl_url" ]; then - echo $new_acl_url > /tmp/dhcp_acl_url - fi - ;; -esac +if [ ! -e /usr/bin/ztp ] || [ "$(ztp status -c)" = "0:DISABLED" ]; then + case $reason in + BOUND|RENEW|REBIND|REBOOT) + if [ -n "$new_minigraph_url" ]; then + echo $new_minigraph_url > /tmp/dhcp_graph_url + else + echo "N/A" > /tmp/dhcp_graph_url + fi + if [ -n "$new_acl_url" ]; then + echo $new_acl_url > /tmp/dhcp_acl_url + fi + ;; + esac +fi diff --git a/files/dhcp/ifupdown2_policy.json b/files/dhcp/ifupdown2_policy.json new file mode 100644 index 000000000000..9a5010dead8a --- /dev/null +++ b/files/dhcp/ifupdown2_policy.json @@ -0,0 +1,12 @@ +{ + "dhcp" : { + "defaults" : { + "dhcp-wait" : "no" + }, + "iface_defaults" : { + "eth0" : { + "dhcp6-duid" : "LL" + } + } + } +} diff --git a/files/dhcp/rfc3442-classless-routes b/files/dhcp/rfc3442-classless-routes index 64e24192816b..797a0d24429f 100644 --- a/files/dhcp/rfc3442-classless-routes +++ b/files/dhcp/rfc3442-classless-routes @@ -55,8 +55,13 @@ if [ "$RUN" = "yes" ]; then fi # set route (ip detects host routes automatically) - ip -4 route add "${net_address}/${net_length}" \ + if echo $interface | grep -v Ethernet ; then + ip -4 route add "${net_address}/${net_length}" \ ${via_arg} dev "${interface}" table default >/dev/null 2>&1 + else + ip -4 route add "${net_address}/${net_length}" \ + ${via_arg} dev "${interface}" >/dev/null 2>&1 + fi done fi fi diff --git a/files/dhcp/sethostname6 b/files/dhcp/sethostname6 new file mode 100644 index 000000000000..6ca5d8dbc995 --- /dev/null +++ b/files/dhcp/sethostname6 @@ -0,0 +1,14 @@ +case $reason in + BOUND6|RENEW6|REBIND6|REBOOT) + current_dhcp6_fqdn=`hostname` + if [ "$current_dhcp6_fqdn" != "$new_dhcp6_fqdn" ] && [ -n "$new_dhcp6_fqdn" ] + then + echo $new_dhcp6_fqdn > /etc/hostname + hostname -F /etc/hostname + sed -i "/\s$current_dhcp6_fqdn$/d" /etc/hosts + sed -i "/\s$new_dhcp6_fqdn$/d" /etc/hosts + echo "127.0.0.1 $new_dhcp6_fqdn" >> /etc/hosts + echo ":: $new_dhcp6_fqdn" >> /etc/hosts + fi + ;; +esac diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index a702917419ca..8dddc215bbd9 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -2,10 +2,40 @@ ifdown --force eth0 -sonic-cfggen -d -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces +# Check if ZTP DHCP policy has been installed +if [ -e /etc/network/ifupdown2/policy.d/ztp_dhcp.json ]; then + # Obtain port operational state information + redis-dump -d 0 -k "PORT_TABLE:Ethernet*" -y > /tmp/ztp_port_data.json + + if [ $? -ne 0 ] || [ ! -e /tmp/ztp_port_data.json ] || [ "$(cat /tmp/ztp_port_data.json)" = "" ]; then + echo "{}" > /tmp/ztp_port_data.json + fi + + # Create an input file with ztp input information + echo "{ \"PORT_DATA\" : $(cat /tmp/ztp_port_data.json) }" > \ + /tmp/ztp_input.json +else + echo "{ \"ZTP_DHCP_DISABLED\" : \"true\" }" > /tmp/ztp_input.json +fi + +# Create /e/n/i file for existing and active interfaces +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces [ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid +[ -f /var/run/dhclient6.eth0.pid ] && kill `cat /var/run/dhclient6.eth0.pid` && rm -f /var/run/dhclient6.eth0.pid +for intf_pid in $(ls -1 /var/run/dhclient*.Ethernet*.pid 2> /dev/null); do + [ -f ${intf_pid} ] && kill `cat ${intf_pid}` && rm -f ${intf_pid} +done + +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/90-dhcp6-systcl.conf.j2 > /etc/sysctl.d/90-dhcp6-systcl.conf +# Read sysctl conf files again +sysctl -p /etc/sysctl.d/90-dhcp6-systcl.conf + +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/dhclient.conf.j2 > /etc/dhcp/dhclient.conf systemctl restart networking +# Clean-up created files +rm -f /tmp/ztp_input.json /tmp/ztp_port_data.json + ifdown lo && ifup lo diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 91be4437fc06..8b8ea0b52bc8 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -27,6 +27,38 @@ iface lo inet loopback # The management network interface auto eth0 +{% if (ZTP_DHCP_DISABLED is not defined) and (ZTP is defined) and (ZTP['mode'] is defined and ZTP['mode']['profile'] == 'active') %} + + +# ZTP out-of-band interface +allow-hotplug eth0 +{% if ZTP['mode']['ipv4'] == 'true' %} +iface eth0 inet dhcp +{% endif %} +{% if ZTP['mode']['ipv6'] == 'true' %} +iface eth0 inet6 dhcp + up sysctl net.ipv6.conf.eth0.accept_ra=1 + down sysctl net.ipv6.conf.eth0.accept_ra=0 +{% endif %} + +{% if ZTP['mode']['inband'] == 'true' %} +{% for port in PORT %} + +# ZTP in-band interface {{ port }} +auto {{ port }} +allow-hotplug {{ port }} +{% if PORT_DATA['PORT_TABLE:'+port] is defined and PORT_DATA['PORT_TABLE:'+port]['value']['oper_status'] == 'up' %} +{% if ZTP['mode']['ipv4'] == 'true' %} +iface {{ port }} inet dhcp +{% endif %} +{% if ZTP['mode']['ipv6'] == 'true' %} +iface {{ port }} inet6 dhcp +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +{% else %} {% if MGMT_INTERFACE %} {% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static @@ -70,6 +102,10 @@ iface eth0 inet dhcp up cgset -r l3mdev.master-device=mgmt mgmt down cgdelete -g l3mdev:mgmt {% endif %} +iface eth0 inet6 dhcp + up sysctl net.ipv6.conf.eth0.accept_ra=1 + down sysctl net.ipv6.conf.eth0.accept_ra=0 +{% endif %} {% endif %} # source /etc/network/interfaces.d/* From 9b8c59f4090d462ccc89a31e2951a10a664b4413 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Tue, 10 Dec 2019 09:45:32 -0800 Subject: [PATCH 0227/1427] [swss] update submodule for sonic-swss (#3864) update multiDB changes in sonic-swss to include multiDB API changes: - [MultiDB]: using new APIs in orch agents and mocktest (#1138) - [vstest]: gather logs when dvs fail to start (#1140) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index c3b8fe10b156..fc085ee70df1 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit c3b8fe10b1568022fa025ef4be9cb063bfe49df4 +Subproject commit fc085ee70df1b6e4edf512bcfac212be429ab021 From dd322270cba96dbb766688b899167c01f485ef73 Mon Sep 17 00:00:00 2001 From: srideepDell Date: Tue, 10 Dec 2019 16:13:25 -0700 Subject: [PATCH 0228/1427] [DellEMC]: utility to set onie modes from NOS (#3860) This common utility would set next boot option as onie mode and when reboot is triggered it would reboot the box into that specific onie mode. Current support modes are rescue/install/uninstall --- .../common/onie_mode_set | 90 +++++++++++++++++++ .../debian/platform-modules-s5232f.install | 1 + .../debian/platform-modules-s5248f.install | 1 + .../debian/platform-modules-s6100.install | 1 + .../debian/platform-modules-z9100.install | 1 + .../debian/platform-modules-z9264f.install | 1 + 6 files changed, 95 insertions(+) create mode 100755 platform/broadcom/sonic-platform-modules-dell/common/onie_mode_set diff --git a/platform/broadcom/sonic-platform-modules-dell/common/onie_mode_set b/platform/broadcom/sonic-platform-modules-dell/common/onie_mode_set new file mode 100755 index 000000000000..247dda5dcc8e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/onie_mode_set @@ -0,0 +1,90 @@ +#!/bin/bash +#scrit to set onie boot modes from NOS +# modes supported rescue/install/uninstall + +VERBOSE=no +ONIEPATH="/mnt/onie-boot" + +unset ONIE_MODE + +function set_onie_boot() +{ + # If reboot to ONIE is requested, set the ONIE boot mode (update/install/uninstall/rescue) + # and reboot. + + # Exit if not superuser + if [[ "$EUID" -ne 0 ]]; then + echo "This command must be run as root" >&2 + exit 1 + fi + + # Mount ONIE partition if not already mounted + if ! grep -qs '/mnt/onie-boot ' /proc/mounts; then + mkdir -p ${ONIEPATH} + mount LABEL=ONIE-BOOT ${ONIEPATH} || ERR=$? + if [[ ${ERR} -ne 0 ]]; then + VERBOSE=yes debug "Failed to mount ONIE partition." + exit 1 + fi + fi + + # Set mode + ${ONIEPATH}/onie/tools/bin/onie-boot-mode -o ${ONIE_MODE} || ERR=$? + if [[ ${ERR} -ne 0 ]]; then + VERBOSE=yes debug "Failed to set ONIE boot mode. Ensure that mode is valid" + exit 1 + fi + + # Set next boot to ONIE + grub-editenv /host/grub/grubenv set next_entry=ONIE || ERR=$? + if [[ ${ERR} -ne 0 ]]; then + VERBOSE=yes debug "Failed to set next boot to ONIE." + exit 1 + fi + echo "next boot mode set to onie - ${ONIE_MODE}" + +} + + +function debug() +{ + if [[ x"${VERBOSE}" == x"yes" ]]; then + echo `date` $@ + fi + logger "$@" +} + + +SCRIPT=$0 + +function show_help_and_exit() +{ + echo "Usage ${SCRIPT} [options]" + echo " This script will set modes in onie rescue/uninstall/install." + echo " " + echo " Available options:" + echo " -h, -? : getting this help" + echo " -o [mode] : boot into ONIE" + + exit 0 +} + +function parse_options() +{ + while getopts "h?vo:" opt; do + case $opt in + h|\? ) + show_help_and_exit + ;; + o ) + ONIE_MODE=$OPTARG + set_onie_boot + ;; + v ) + VERBOSE=yes + ;; + esac + done +} + +parse_options $@ diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install index b577c5cd5b10..303e978848db 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install @@ -8,3 +8,4 @@ s5232f/cfg/s5232f-modules.conf etc/modules-load.d s5232f/systemd/platform-modules-s5232f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install index 7aa27d23b536..e87ea7e37b4e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install @@ -8,3 +8,4 @@ s5248f/cfg/s5248f-modules.conf etc/modules-load.d s5248f/systemd/platform-modules-s5248f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5248f_c3538-r0 common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install index 5d1cb6341fc7..eb0211b3afde 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install @@ -14,3 +14,4 @@ s6100/systemd/platform-modules-s6100.service etc/systemd/system s6100/systemd/s6100-lpc-monitor.service etc/systemd/system tools/flashrom/flashrom usr/local/bin/ common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install index 5c5c4cc55be2..a4dffe0d023c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install @@ -12,3 +12,4 @@ z9100/cfg/z9100-modules.conf etc/modules-load.d z9100/systemd/platform-modules-z9100.service etc/systemd/system z9100/systemd/z9100-lpc-monitor.service etc/systemd/system common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install index 29e8b1df2e36..e7d589f14e0c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install @@ -8,3 +8,4 @@ z9264f/cfg/z9264f-modules.conf etc/modules-load.d z9264f/systemd/platform-modules-z9264f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin From 7ef57f92e1479b382fce962b2ea8c0346d0550b5 Mon Sep 17 00:00:00 2001 From: Myron Sosyak <49795530+msosyak@users.noreply.github.com> Date: Tue, 10 Dec 2019 18:03:55 -0800 Subject: [PATCH 0229/1427] [docker-sonic-mgmt]: Add docker-ce-cli to sonic-mgmt container (#3868) In the scope of migration from docker shell plugin to docker connection plugin, we need to have docker-ce-cli installed in docker-sonic-mgmt. Azure/sonic-mgmt#1269 Added docker-ce-cli package to docker-sonic-mgmt. --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index d24df1ca5d77..4c53baf7c485 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -71,6 +71,19 @@ RUN pip install ipaddr \ && pip install nnpy \ && pip install dpkt +# Install docker-ce-cli +RUN apt-get update \ + && apt-get install -y \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg-agent \ + software-properties-common \ + && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - \ + && add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \ + && apt-get update \ + && apt-get install -y docker-ce-cli + # Install Microsoft Azure Kusto Library for Python RUN pip install azure-kusto-data==0.0.13 \ azure-kusto-ingest==0.0.13 From 979b0dd4a2e051a2226aac3f5daa4c8be11bfa94 Mon Sep 17 00:00:00 2001 From: kannankvs Date: Wed, 11 Dec 2019 13:18:18 +0530 Subject: [PATCH 0230/1427] [doc]: Added one extra sentence to give example for check out 201911 branch (#3867) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a1de15524b63..301bff39547e 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ To build SONiC installer image and docker images, run the following commands: # Enter the source directory cd sonic-buildimage - # (Optional) Checkout a specific branch. By default, it uses master branch + # (Optional) Checkout a specific branch. By default, it uses master branch. For example, to checkout the branch 201911, use "git checkout 201911" git checkout [branch_name] # Execute make init once after cloning the repo, or after fetching remote repo with submodule updates From 3b0c51f423637aafb0c0c42c98c6729e1609468a Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Thu, 12 Dec 2019 01:41:29 +0800 Subject: [PATCH 0231/1427] [sub module] Update sonic-platform-common pointer to pick up fix (#3859) Azure/sonic-platform-common#71 [Bug fix] fix a syntax error which was introduced by last commit Azure/sonic-platform-common#70 Fix EEPROM vendor extension TLV number counting issue Azure/sonic-platform-common#62 Platform Driver Development Framework (PDDF): 1) Changes to psu base class (1.0 APIs) to support PDDF CLI utils, 2) Adding fan_base class to support PDDF fan CLI utils (comments incorporated) Azure/sonic-platform-common#68 DeviceBase.get_name should raise NotImplementedError like other member --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 6ad48b87eb96..6f74dd3f4f42 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 6ad48b87eb9654daa3f3c854134434d14572573f +Subproject commit 6f74dd3f4f42bc945467cffa4f889b50e4b1468a From ef26ba024d73996073ff9afc2fc15d8da0802d7e Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Fri, 13 Dec 2019 03:09:28 +0800 Subject: [PATCH 0232/1427] [Mellanox]Update hw-mgmt to V7.0000.2308 (#3858) * [Mellanox]Update hw-mgmt to V7.0000.2308 sonic-linux-kernel should be updated accordingly with necessary patches uploaded. * [sub-module]Advance submodule head for sonic-linux-kernel --- platform/mellanox/hw-management.mk | 2 +- platform/mellanox/hw-management/hw-mgmt | 2 +- src/sonic-linux-kernel | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index f41c2b9a25ce..ff1ea207572d 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0000.2303 +MLNX_HW_MANAGEMENT_VERSION = 7.0000.2308 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 7c26a8f6a520..28d83cdb3565 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 7c26a8f6a520b06663992afe874bc56b1fcd9311 +Subproject commit 28d83cdb3565d3b0352cc718fe82a14cacd1d4a5 diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index feb42b05eb91..87576c061d10 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit feb42b05eb912ea64f0b4ce17f4bc890929eb57e +Subproject commit 87576c061d10dfe7de8e8e5cc1bae6bd29b0143b From 13eec88732835b82802721deed72c2c43f3751bc Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 12 Dec 2019 18:46:35 -0800 Subject: [PATCH 0233/1427] Change the dpkg default behavior in slave, and docker-base, in order to prevent prompt (#3879) * Change the dpkg default behavior in slave, and docker-base, in order to prevent prompt * Move to right place --- dockers/docker-base-stretch/dpkg_01_drop | 8 ++++++++ dockers/docker-base/dpkg_01_drop | 8 ++++++++ sonic-slave-stretch/Dockerfile.j2 | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/dockers/docker-base-stretch/dpkg_01_drop b/dockers/docker-base-stretch/dpkg_01_drop index e75ef3147158..d749943797d9 100644 --- a/dockers/docker-base-stretch/dpkg_01_drop +++ b/dockers/docker-base-stretch/dpkg_01_drop @@ -20,3 +20,11 @@ path-exclude /usr/share/pyshared/twisted/test* path-exclude /usr/lib/python*/dist-packages/twisted/test* path-exclude /usr/share/pyshared/twisted/*/test* path-exclude /usr/lib/python*/dist-packages/twisted/*/test* + +## install the configuration file if it’s currently missing +force-confmiss +## combined with confold: overwrite configuration files that you have not modified +force-confdef +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +force-confold + diff --git a/dockers/docker-base/dpkg_01_drop b/dockers/docker-base/dpkg_01_drop index e75ef3147158..d749943797d9 100644 --- a/dockers/docker-base/dpkg_01_drop +++ b/dockers/docker-base/dpkg_01_drop @@ -20,3 +20,11 @@ path-exclude /usr/share/pyshared/twisted/test* path-exclude /usr/lib/python*/dist-packages/twisted/test* path-exclude /usr/share/pyshared/twisted/*/test* path-exclude /usr/lib/python*/dist-packages/twisted/*/test* + +## install the configuration file if it’s currently missing +force-confmiss +## combined with confold: overwrite configuration files that you have not modified +force-confdef +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +force-confold + diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index f52bd943b0a7..133238622f76 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -293,6 +293,14 @@ RUN apt-get update && apt-get install -y \ # For kdump-tools liblzo2-dev +## Config dpkg +## install the configuration file if it’s currently missing +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confmiss" +## combined with confold: overwrite configuration files that you have not modified +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confdef" +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confold" + # For smartmontools 6.6-1 RUN apt-get -t stretch-backports install -y debhelper From f126258d5fa40406b5412cb6afff7eeb6529b224 Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Fri, 13 Dec 2019 22:36:05 +0530 Subject: [PATCH 0234/1427] [Juniper][QFX5210] Platform monitoring updates (#3899) As part of this commit, there are a few enhancements being made for EM policy implementation: a) Introduced hysteresis algorithm to prevent fan hunting b) Reading ASIC temperature to make decision for fan speed. As part of the PR# 3599, Workaround for the boot problem from secondary bios was addressed. When the SONiC image is upgraded, this resulted in creating multiple entries for BOOTX64.EFI. To fix the problem, as part of this changeset, introducing a check to see if there is already an UEFI entry for BOOTX64.EFI and accordingly creating / skipping the UEFI entry. Signed-off-by: Ciju Rajan K --- .../sonic-platform-juniper-qfx5210.postinst | 11 +- .../qfx5210/utils/juniper_qfx5210_monitor.py | 221 ++++++++++++++---- 2 files changed, 181 insertions(+), 51 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst index dcff39f53799..97b66fb44e4c 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst @@ -1,3 +1,5 @@ +#!/bin/bash + systemctl enable qfx5210-platform-init.service systemctl start qfx5210-platform-init.service @@ -18,5 +20,12 @@ if [ -f $FIRST_BOOT_FILE ]; then cp SONiC-OS/grubx64.efi BOOT/BOOTX64.EFI cd /tmp umount sda1 - efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /dev/null 2>&1 + # This code block ensures that no additional entries + # are added. This is applicable during SONiC image + # upgrades. + entries=`efibootmgr -v | grep "BOOTX64"` + if [ -z "$entries" ]; then + # Creating the UEFI entry for the first time. + efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /var/tmp/efi_log 2>&1 + fi fi diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py index d225400121b8..97adf9588f9f 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py @@ -47,6 +47,7 @@ import traceback import glob import collections + import StringIO from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) @@ -54,15 +55,20 @@ # Deafults VERSION = '1.0' FUNCTION_NAME = '/var/log/juniper_qfx5210_monitor' - +verbose = False +DEBUG = False global log_file global log_level global isPlatformAFI +global is80PerFlag +global is60PerFlag global isFireThresholdReached -FireThresholdSecsRemaining = 120 +global isFireThresholdPrint +global PrevASICValue +global FireThresholdSecsRemaining temp_policy_AFI = { 0: [[70, 0, 48000], [70, 48000, 53000], [80, 53000, 0], [80, 53000, 58000], [100, 58000, 0], ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 75000], ['Fire Shut Alarm', 75000, 0]], @@ -72,6 +78,7 @@ 4: [[70, 0, 31000], [70, 31000, 36000], [80, 36000, 0], [80, 36000, 42000], [100, 42000, 0], ['Yellow Alarm', 48000, 55000], ['Red Alarm', 55000, 60000], ['Fire Shut Alarm', 60000, 0]], 5: [[70, 0, 31000], [70, 31000, 36000], [80, 36000, 0], [80, 36000, 43000], [100, 43000, 0], ['Yellow Alarm', 49000, 56000], ['Red Alarm', 56000, 61000], ['Fire Shut Alarm', 61000, 0]], 6: [[70, 0, 70000], [70, 70000, 78000], [80, 78000, 0], [80, 78000, 86000], [100, 86000, 0], ['Yellow Alarm', 91000, 96000], ['Red Alarm', 96000, 102000], ['Fire Shut Alarm', 102000, 0]], + 7: [[70, 0, 84000], [70, 84000, 91000], [80, 91000, 0], [80, 91000, 98000], [100, 98000, 0], ['Yellow Alarm', 103000, 108000], ['Red Alarm', 108000, 120000], ['Fire Shut Alarm', 120000, 0]], } temp_policy_AFO = { @@ -82,6 +89,7 @@ 4: [[60, 0, 39000], [60, 39000, 45000], [80, 45000, 0], [80, 45000, 52000], [100, 52000, 0], ['Yellow Alarm', 59000, 65000], ['Red Alarm', 65000, 69000], ['Fire Shut Alarm', 69000, 0]], 5: [[60, 0, 37000], [60, 37000, 43000], [80, 43000, 0], [80, 43000, 50000], [100, 50000, 0], ['Yellow Alarm', 57000, 63000], ['Red Alarm', 63000, 67000], ['Fire Shut Alarm', 67000, 0]], 6: [[60, 0, 70000], [60, 70000, 78000], [80, 78000, 0], [80, 78000, 86000], [100, 86000, 0], ['Yellow Alarm', 91000, 96000], ['Red Alarm', 96000, 102000], ['Fire Shut Alarm', 102000, 0]], + 7: [[60, 0, 84000], [60, 84000, 91000], [80, 91000, 0], [80, 91000, 98000], [100, 98000, 0], ['Yellow Alarm', 103000, 108000], ['Red Alarm', 108000, 120000], ['Fire Shut Alarm', 120000, 0]], } class QFX5210_FanUtil(object): @@ -97,7 +105,7 @@ def get_fan_duty_cycle(self): try: val_file = open(self.FAN_DUTY_PATH) except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('get_fan_duty_cycle: unable to open file: %s', str(e)) return False content = val_file.readline().rstrip() @@ -110,7 +118,7 @@ def set_fan_duty_cycle(self, val): try: fan_file = open(self.FAN_DUTY_PATH, 'r+') except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('set_fan_duty_cycle: unable to open file: %s', str(e)) return False fan_file.write(str(val)) fan_file.close() @@ -120,7 +128,8 @@ class QFX5210_ThermalUtil(object): """QFX5210 Platform ThermalUtil class""" SENSOR_NUM_ON_MAIN_BOARD = 6 - SENSOR_CORETEMP_NUM_ON_MAIN_BOARD = 7 + CORETEMP_INDEX_ON_MAIN_BOARD = 6 + SENSOR_CORETEMP_NUM_ON_MAIN_BOARD = 8 CORETEMP_NUM_ON_MAIN_BOARD = 5 THERMAL_NUM_RANGE = 8 SENSOR_NUM_1_IDX = 1 @@ -181,19 +190,19 @@ def _get_sensor_node_val(self, thermal_num): try: val_file = open(filename, 'r') except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) + logging.error('get_sensor_node_val: unable to open file: %s', str(e)) return None content = val_file.readline().rstrip() if content == '': - logging.debug('GET. content is NULL. device_path:%s', device_path) + logging.debug('get_sensor_node_val: content is NULL. device_path:%s', device_path) return None try: - val_file.close() + val_file.close() except: - logging.debug('GET. unable to close file. device_path:%s', device_path) + logging.debug('get_sensor_node_val: unable to close file. device_path:%s', device_path) return None return int(content) @@ -208,19 +217,19 @@ def _get_coretemp_node_val(self, thermal_num): try: val_file = open(filename, 'r') except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) + logging.error('get_coretemp_node_val: unable to open file: %s', str(e)) return None content = val_file.readline().rstrip() if content == '': - logging.debug('GET. content is NULL. device_path:%s', device_path) + logging.debug('get_coretemp_node_val: content is NULL. device_path:%s', device_path) return None try: val_file.close() except: - logging.debug('GET. unable to close file. device_path:%s', device_path) + logging.debug('get_coretemp_node_val: unable to close file. device_path:%s', device_path) return None return int(content) @@ -243,7 +252,7 @@ def get_alarm_led_brightness(self): try: val_file = open(self.ALARM_LED_PATH) except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('get_alarm_led_brightness: unable to open file: %s', str(e)) return False content = val_file.readline().rstrip() @@ -260,7 +269,7 @@ def set_alarm_led_brightness(self, val): try: val_file = open(self.ALARM_LED_PATH, 'r+') except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) return False val_file.write(str(val)) val_file.close() @@ -274,8 +283,12 @@ def set_alarm_led_brightness(self, val): def getSensorTemp(self): sum = 0 global isPlatformAFI + global is80PerFlag + global is60PerFlag global isFireThresholdReached - global FireThresholdSecsRemaining + global FireThresholdSecsRemaining + global isFireThresholdPrint + global PrevASICValue #AFI if (isPlatformAFI == True): temp_policy = temp_policy_AFI @@ -294,14 +307,22 @@ def getSensorTemp(self): 4: [0,0,0,0,0,0,0,0], 5: [0,0,0,0,0,0,0,0], 6: [0,0,0,0,0,0,0,0], + 7: [0,0,0,0,0,0,0,0], } # if the Firethreshold Flag is set and 120 seconds have elapsed, invoking the "poweroff" to shutdown the box if (isFireThresholdReached == True): firethr = FireThresholdSecsRemaining - 20 - logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds', firethr) - print "Fire Threshold reached: System is going to shutdown in %s seconds\n" % firethr + if firethr == 0: + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown now') + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown now' > /dev/console") + else: + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds', firethr) + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds' > /dev/console" % firethr) + FireThresholdSecsRemaining = FireThresholdSecsRemaining - 20 - if (FireThresholdSecsRemaining == 20): + logging.critical('CRITICAL: Value of FireThresholdSecsRemaining %s seconds', FireThresholdSecsRemaining) + + if (FireThresholdSecsRemaining == 0): isFireThresholdReached == False time.sleep(20) cmd = "poweroff" @@ -310,9 +331,32 @@ def getSensorTemp(self): for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): if x < self.SENSOR_NUM_ON_MAIN_BOARD: value = self._get_sensor_node_val(x+1) + logging.debug('Sensor value %d : %s', x, value) + elif x == self.CORETEMP_INDEX_ON_MAIN_BOARD: + value = self.get_coretempValue() + logging.debug('Main Board CORE temp: %s', value) else: - value = self.get_coretempValue() - + logging.debug('Reading ASIC Temp value using bcmcmd') + proc = subprocess.Popen("bcmcmd \"show temp\" | grep \"maximum peak temperature\" | awk '{ print $5 }' > /var/log/asic_value 2>&1 & ",shell=True) + time.sleep(2) + cmd = "kill -9 %s"%(proc.pid) + status, cmd_out = commands.getstatusoutput(cmd) + + if os.stat("/var/log/asic_value").st_size == 0: + value = PrevASICValue + logging.debug('No ASIC Temp file, Prev ASIC Temp Value: %s', PrevASICValue) + else: + with open('/var/log/asic_value', 'r') as f: + value1 = f.readline() + value2 = float(value1) + value1 = value2 * 1000 + value = int(value1) + PrevASICValue = value + logging.debug('Reading from ASIC Temp file: %s', value) + logging.debug('Reading from Prev ASIC Temp Value: %s', PrevASICValue) + + os.system('rm /var/log/asic_value') + # 60% Duty Cycle for AFO and 70% Duty Cycle for AFI if value > temp_policy[x][0][1] and value <= temp_policy[x][0][2]: SensorFlag[x][0] = True @@ -350,57 +394,113 @@ def getSensorTemp(self): fan = QFX5210_FanUtil() # CHECK IF ANY TEMPERATURE SENSORS HAS SET FIRE SHUTDOWN FLAG - if SensorFlag[0][7] or SensorFlag[1][7] or SensorFlag[2][7] or SensorFlag[3][7] or SensorFlag[4][7] or SensorFlag[5][7] or SensorFlag[6][7]: + if SensorFlag[0][7] or SensorFlag[1][7] or SensorFlag[2][7] or SensorFlag[3][7] or SensorFlag[4][7] or SensorFlag[5][7] or SensorFlag[6][7] or SensorFlag[7][7]: isFireThresholdReached = True - logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds') - print "CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds\n" - value = self.get_alarm_led_brightness() - if ( value > 0): - self.set_alarm_led_brightness(0) + if (isFireThresholdPrint == True): + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds') + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds' > /dev/console") + isFireThresholdPrint = False + + logging.debug('Temp Sensor is set to FIRE SHUTDOWN Flag') + fan.set_fan_duty_cycle(100) + self.set_alarm_led_brightness(2) # CHECK IF ANY TEMPERATURE SENSORS HAS SET 'RED' ALARM FLAG, IF YES, SET THE ALARM LED TO 'RED' - elif SensorFlag[0][6] or SensorFlag[1][6] or SensorFlag[2][6] or SensorFlag[3][6] or SensorFlag[4][6] or SensorFlag[5][6] or SensorFlag[6][6]: + elif SensorFlag[0][6] or SensorFlag[1][6] or SensorFlag[2][6] or SensorFlag[3][6] or SensorFlag[4][6] or SensorFlag[5][6] or SensorFlag[6][6] or SensorFlag[7][6]: + fan.set_fan_duty_cycle(100) self.set_alarm_led_brightness(2) + logging.debug('Temp Sensor is set to Red Alarm Flag') + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False # CHECK IF ANY TEMPERATURE SENSORS HAS SET 'YELLOW' ALARM FLAG, IF YES, SET THE ALARM LED TO 'YELLOW' - elif SensorFlag[0][5] or SensorFlag[1][5] or SensorFlag[2][5] or SensorFlag[3][5] or SensorFlag[4][5] or SensorFlag[5][5] or SensorFlag[6][5]: + elif SensorFlag[0][5] or SensorFlag[1][5] or SensorFlag[2][5] or SensorFlag[3][5] or SensorFlag[4][5] or SensorFlag[5][5] or SensorFlag[6][5] or SensorFlag[7][5]: + fan.set_fan_duty_cycle(100) self.set_alarm_led_brightness(1) + logging.debug('Temp Sensor is set to Yellow Alarm Flag') + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False # CHECK IF ANY TEMPERATURE SENSORS HAS SET 100% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 100% - elif SensorFlag[0][4] or SensorFlag[1][4] or SensorFlag[2][4] or SensorFlag[3][4] or SensorFlag[4][4] or SensorFlag[5][4] or SensorFlag[6][4]: + elif SensorFlag[0][4] or SensorFlag[1][4] or SensorFlag[2][4] or SensorFlag[3][4] or SensorFlag[4][4] or SensorFlag[5][4] or SensorFlag[6][4] or SensorFlag[7][4]: fan.set_fan_duty_cycle(100) value = self.get_alarm_led_brightness() if ( value > 0): self.set_alarm_led_brightness(0) + is80PerFlag = False + is60PerFlag = False + logging.debug('Temp Sensor is set to 100% Duty Cycle Flag') # CHECK IF ANY TEMPERATURE SENSORS HAS SET 80% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 80% - elif SensorFlag[0][3] or SensorFlag[1][3] or SensorFlag[2][3] or SensorFlag[3][3] or SensorFlag[4][3] or SensorFlag[5][3] or SensorFlag[6][3]: - fan.set_fan_duty_cycle(80) + elif SensorFlag[0][3] or SensorFlag[1][3] or SensorFlag[2][3] or SensorFlag[3][3] or SensorFlag[4][3] or SensorFlag[5][3] or SensorFlag[6][3] or SensorFlag[7][3]: + if (is80PerFlag == True): + fan.set_fan_duty_cycle(80) + is80PerFlag = False + else: + pass + value = self.get_alarm_led_brightness() if ( value > 0): self.set_alarm_led_brightness(0) + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + logging.debug('Temp Sensor is set to 80% Prev Duty Cycle Flag') + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 80% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 80% - elif SensorFlag[0][2] or SensorFlag[1][2] or SensorFlag[2][2] or SensorFlag[3][2] or SensorFlag[4][2] or SensorFlag[5][2] or SensorFlag[6][2]: + elif SensorFlag[0][2] or SensorFlag[1][2] or SensorFlag[2][2] or SensorFlag[3][2] or SensorFlag[4][2] or SensorFlag[5][2] or SensorFlag[6][2] or SensorFlag[7][2]: fan.set_fan_duty_cycle(80) value = self.get_alarm_led_brightness() if ( value > 0): self.set_alarm_led_brightness(0) + is80PerFlag = True + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + logging.debug('Temp Sensor is set to 80% Duty Cycle Flag') # FOR "AFO" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 60% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 60% # FOR "AFI" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 70% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 70% - elif SensorFlag[0][1] or SensorFlag[1][1] or SensorFlag[2][1] or SensorFlag[3][1] or SensorFlag[4][1] or SensorFlag[5][1] or SensorFlag[6][1]: - if (isPlatformAFI == True): - fan.set_fan_duty_cycle(70) + elif SensorFlag[0][1] or SensorFlag[1][1] or SensorFlag[2][1] or SensorFlag[3][1] or SensorFlag[4][1] or SensorFlag[5][1] or SensorFlag[6][1] or SensorFlag[7][1]: + if (is60PerFlag == True): + if (isPlatformAFI == True): + fan.set_fan_duty_cycle(70) + else: + fan.set_fan_duty_cycle(60) + + is60PerFlag = False + is80PerFlag = True else: - fan.set_fan_duty_cycle(60) + pass + value = self.get_alarm_led_brightness() if ( value > 0): self.set_alarm_led_brightness(0) + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + logging.debug('Temp Sensor is set to 60% Prev Duty Cycle Flag') + # FOR "AFO" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 60% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 60% # FOR "AFI" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 70% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 70% - elif SensorFlag[0][0] or SensorFlag[1][0] or SensorFlag[2][0] or SensorFlag[3][0] or SensorFlag[4][0] or SensorFlag[5][0] or SensorFlag[6][0]: + elif SensorFlag[0][0] or SensorFlag[1][0] or SensorFlag[2][0] or SensorFlag[3][0] or SensorFlag[4][0] or SensorFlag[5][0] or SensorFlag[6][0] or SensorFlag[7][0]: if (isPlatformAFI == True): fan.set_fan_duty_cycle(70) else: @@ -408,6 +508,15 @@ def getSensorTemp(self): value = self.get_alarm_led_brightness() if ( value > 0): self.set_alarm_led_brightness(0) + is60PerFlag = True + is80PerFlag = True + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + logging.debug('Temp Sensor is set to 60% Duty Cycle Flag') else: pass @@ -417,14 +526,18 @@ def getSensorTemp(self): for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): for y in range(self.THERMAL_NUM_RANGE): SensorFlag[x][y] = 0 - class device_monitor(object): def __init__(self, log_file, log_level): - + global DEBUG global isPlatformAFI global isFireThresholdReached + global is80PerFlag + global is60PerFlag + global isFireThresholdPrint + global PrevASICValue + global FireThresholdSecsRemaining MASTER_LED_PATH = '/sys/class/leds/master/brightness' SYSTEM_LED_PATH = '/sys/class/leds/system/brightness' FANTYPE_PATH = '/sys/bus/i2c/devices/17-0068/fan1_direction' @@ -439,13 +552,14 @@ def __init__(self, log_file, log_level): datefmt='%H:%M:%S' ) + if DEBUG == True: # set up logging to console - if log_level == logging.DEBUG: - console = logging.StreamHandler() - console.setLevel(log_level) - formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') - console.setFormatter(formatter) - logging.getLogger('').addHandler(console) + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) import sonic_platform platform = sonic_platform.platform.Platform() @@ -454,20 +568,25 @@ def __init__(self, log_file, log_level): # the return value of get_fan_type is AFO = 0, AFI = 1 and for error condition it is -1 # In the error condition also, we are making default platform as AFO, to continue with Energy Monitoring - if (fan_type == -1 or fan_type == 0): - if (fan_type == -1): - print "Error: unable to open sys file for fan handling, defaulting it to AFO" + if (int(fan_type) == -1 or int(fan_type) == 0): + if (int(fan_type) == -1): + logging.error('device_monitor: unable to open sys file for fan handling, defaulting it to AFO') isPlatformAFI = False else: isPlatformAFI = True isFireThresholdReached = False + is80PerFlag = True + is60PerFlag = True + isFireThresholdPrint = True + FireThresholdSecsRemaining = 120 + PrevASICValue = 0 master_led_value = 1 try: masterLED_file = open(MASTER_LED_PATH, 'r+') except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('device_monitor: unable to open Master LED file: %s', str(e)) return False masterLED_file.write(str(master_led_value)) masterLED_file.close() @@ -476,7 +595,7 @@ def __init__(self, log_file, log_level): try: systemLED_file = open(SYSTEM_LED_PATH, 'r+') except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('device_monitor: unable to open System LED file: %s', str(e)) return False systemLED_file.write(str(system_led_value)) systemLED_file.close() @@ -490,6 +609,8 @@ def main(): log_file = '%s.log' % FUNCTION_NAME log_level = logging.DEBUG + #Introducing sleep of 150 seconds to wait for all the docker containers to start before starting the EM policy. + time.sleep(150) monitor = device_monitor(log_file, log_level) while True: monitor.manage_device() From 86e23f9ededb0b56d55bdad09e4d9c91b20aaee4 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 13 Dec 2019 13:46:48 -0800 Subject: [PATCH 0235/1427] [lldpd]: Ports few fixes from lldpd master (#3889) * lldpctl: put a lock around some commands to avoid race conditions * Read all notifications in lldpctl_recv * lib: fix memory leak * lib: fix memory leak when handling I/O * Update series --- ...ck-around-some-commands-to-avoid-rac.patch | 169 ++++++++++++++++++ ...ad-all-notifications-in-lldpctl_recv.patch | 27 +++ .../patch/0006-lib-fix-memory-leak.patch | 24 +++ ...ib-fix-memory-leak-when-handling-I-O.patch | 85 +++++++++ src/lldpd/patch/series | 4 + 5 files changed, 309 insertions(+) create mode 100644 src/lldpd/patch/0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch create mode 100644 src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch create mode 100644 src/lldpd/patch/0006-lib-fix-memory-leak.patch create mode 100644 src/lldpd/patch/0007-lib-fix-memory-leak-when-handling-I-O.patch diff --git a/src/lldpd/patch/0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch b/src/lldpd/patch/0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch new file mode 100644 index 000000000000..df7f26131dd4 --- /dev/null +++ b/src/lldpd/patch/0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch @@ -0,0 +1,169 @@ +From 46aa45d0fa3e8879ecdca1c156cb2d91194c45e9 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Thu, 12 Dec 2019 13:47:17 -0800 +Subject: [PATCH 1/1] lldpctl: put a lock around some commands to avoid race + conditions + +--- + src/client/client.h | 3 +++ + src/client/commands.c | 58 ++++++++++++++++++++++++++++++++++++++++--- + src/client/conf.c | 4 +-- + 3 files changed, 60 insertions(+), 5 deletions(-) + +diff --git a/src/client/client.h b/src/client/client.h +index e3ee352..6c3e30d 100644 +--- a/src/client/client.h ++++ b/src/client/client.h +@@ -62,6 +62,8 @@ extern void add_history (); + #endif + #undef NEWLINE + ++extern const char *ctlname; ++ + /* commands.c */ + #define NEWLINE "" + struct cmd_node; +@@ -76,6 +78,7 @@ struct cmd_node *commands_new( + struct cmd_env*, void *), + void *); + struct cmd_node* commands_privileged(struct cmd_node *); ++struct cmd_node* commands_lock(struct cmd_node *); + struct cmd_node* commands_hidden(struct cmd_node *); + void commands_free(struct cmd_node *); + const char *cmdenv_arg(struct cmd_env*); +diff --git a/src/client/commands.c b/src/client/commands.c +index beedbf1..58df4a7 100644 +--- a/src/client/commands.c ++++ b/src/client/commands.c +@@ -18,6 +18,9 @@ + #include "client.h" + #include + #include ++#include ++#include ++#include + + /** + * An element of the environment (a key and a value). +@@ -68,6 +71,7 @@ struct cmd_node { + const char *token; /**< Token to enter this cnode */ + const char *doc; /**< Documentation string */ + int privileged; /**< Privileged command? */ ++ int lock; /**< Lock required for execution? */ + int hidden; /**< Hidden command? */ + + /** +@@ -113,6 +117,21 @@ commands_privileged(struct cmd_node *node) + return node; + } + ++/** ++ * Make a node accessible only with a lock. ++ * ++ * @param node node to use lock to execute ++ * @return the modified node ++ * ++ * The node is modified. It is returned to ease chaining. ++ */ ++struct cmd_node* ++commands_lock(struct cmd_node *node) ++{ ++ if (node) node->lock = 1; ++ return node; ++} ++ + /** + * Hide a node from help or completion. + * +@@ -344,6 +363,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w, + int n, rc = 0, completion = (word != NULL); + int help = 0; /* Are we asking for help? */ + int complete = 0; /* Are we asking for possible completions? */ ++ int needlock = 0; /* Do we need a lock? */ + struct cmd_env env = { + .elements = TAILQ_HEAD_INITIALIZER(env.elements), + .stack = TAILQ_HEAD_INITIALIZER(env.stack), +@@ -351,6 +371,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w, + .argv = argv, + .argp = 0 + }; ++ static int lockfd = -1; + cmdenv_push(&env, root); + if (!completion) + for (n = 0; n < argc; n++) +@@ -388,6 +409,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w, + !strcmp(candidate->token, token)) { + /* Exact match */ + best = candidate; ++ needlock = needlock || candidate->lock; + break; + } + if (!best) best = candidate; +@@ -406,6 +428,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w, + if (!candidate->token && + CAN_EXECUTE(candidate)) { + best = candidate; ++ needlock = needlock || candidate->lock; + break; + } + } +@@ -421,9 +444,38 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w, + + /* Push and execute */ + cmdenv_push(&env, best); +- if (best->execute && best->execute(conn, w, &env, best->arg) != 1) { +- rc = -1; +- goto end; ++ if (best->execute) { ++ struct sockaddr_un su; ++ if (needlock) { ++ if (lockfd == -1) { ++ log_debug("lldpctl", "reopen %s for locking", ctlname); ++ if ((lockfd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { ++ log_warn("lldpctl", "cannot open for lock %s", ctlname); ++ rc = -1; ++ goto end; ++ } ++ su.sun_family = AF_UNIX; ++ strlcpy(su.sun_path, ctlname, sizeof(su.sun_path)); ++ if (connect(lockfd, (struct sockaddr *)&su, sizeof(struct sockaddr_un)) == -1) { ++ log_warn("lldpctl", "cannot connect to socket %s", ctlname); ++ rc = -1; ++ close(lockfd); lockfd = -1; ++ goto end; ++ } ++ } ++ if (lockf(lockfd, F_LOCK, 0) == -1) { ++ log_warn("lldpctl", "cannot get lock on %s", ctlname); ++ rc = -1; ++ close(lockfd); lockfd = -1; ++ goto end; ++ } ++ } ++ rc = best->execute(conn, w, &env, best->arg) != 1 ? -1 : rc; ++ if (needlock && lockf(lockfd, F_ULOCK, 0) == -1) { ++ log_warn("lldpctl", "cannot unlock %s", ctlname); ++ close(lockfd); lockfd = -1; ++ } ++ if (rc == -1) goto end; + } + env.argp++; + } +diff --git a/src/client/conf.c b/src/client/conf.c +index 1a14981..ba5743f 100644 +--- a/src/client/conf.c ++++ b/src/client/conf.c +@@ -37,8 +37,8 @@ register_commands_configure(struct cmd_node *root) + "unconfigure", + "Unconfigure system settings", + NULL, NULL, NULL); +- commands_privileged(configure); +- commands_privileged(unconfigure); ++ commands_privileged(commands_lock(configure)); ++ commands_privileged(commands_lock(unconfigure)); + cmd_restrict_ports(configure); + cmd_restrict_ports(unconfigure); + +-- +2.17.1.windows.2 + diff --git a/src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch b/src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch new file mode 100644 index 000000000000..1c3781da67ce --- /dev/null +++ b/src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch @@ -0,0 +1,27 @@ +From b8e66b52f40103fd3abea77031c4634742c31860 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Thu, 12 Dec 2019 12:47:42 -0800 +Subject: [PATCH 1/1] Read all notifications in lldpctl_recv + +--- + src/lib/connection.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/lib/connection.c b/src/lib/connection.c +index 591d9e9..88bbc99 100644 +--- a/src/lib/connection.c ++++ b/src/lib/connection.c +@@ -253,8 +253,8 @@ lldpctl_recv(lldpctl_conn_t *conn, const uint8_t *data, size_t length) + memcpy(conn->input_buffer + conn->input_buffer_len, data, length); + conn->input_buffer_len += length; + +- /* Is it a notification? */ +- check_for_notification(conn); ++ /* Read all notifications */ ++ while(!check_for_notification(conn)); + + RESET_ERROR(conn); + +-- +2.17.1.windows.2 + diff --git a/src/lldpd/patch/0006-lib-fix-memory-leak.patch b/src/lldpd/patch/0006-lib-fix-memory-leak.patch new file mode 100644 index 000000000000..765b5fb751e7 --- /dev/null +++ b/src/lldpd/patch/0006-lib-fix-memory-leak.patch @@ -0,0 +1,24 @@ +From 833653dffb9be40110142af2a7cb4076a0dd24f5 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Thu, 12 Dec 2019 12:48:47 -0800 +Subject: [PATCH 1/1] lib: fix memory leak + +--- + src/lib/connection.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/lib/connection.c b/src/lib/connection.c +index 88bbc99..aa88dad 100644 +--- a/src/lib/connection.c ++++ b/src/lib/connection.c +@@ -114,6 +114,7 @@ lldpctl_new_name(const char *ctlname, lldpctl_send_callback send, lldpctl_recv_c + } + if (!send && !recv) { + if ((data = malloc(sizeof(struct lldpctl_conn_sync_t))) == NULL) { ++ free(conn->ctlname); + free(conn); + return NULL; + } +-- +2.17.1.windows.2 + diff --git a/src/lldpd/patch/0007-lib-fix-memory-leak-when-handling-I-O.patch b/src/lldpd/patch/0007-lib-fix-memory-leak-when-handling-I-O.patch new file mode 100644 index 000000000000..cad8bf2fd48a --- /dev/null +++ b/src/lldpd/patch/0007-lib-fix-memory-leak-when-handling-I-O.patch @@ -0,0 +1,85 @@ +From f6086575e63b5e089814ca116aa637d7588bfcd3 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Thu, 12 Dec 2019 13:52:42 -0800 +Subject: [PATCH 1/1] lib: fix memory leak when handling I/O. + +--- + src/lib/atom.c | 11 ++++++----- + src/lib/atom.h | 9 ++++----- + src/lib/atoms/port.c | 2 +- + 3 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/src/lib/atom.c b/src/lib/atom.c +index 955f434..f81d3bb 100644 +--- a/src/lib/atom.c ++++ b/src/lib/atom.c +@@ -322,10 +322,12 @@ _lldpctl_do_something(lldpctl_conn_t *conn, + return SET_ERROR(conn, LLDPCTL_ERR_SERIALIZATION); + conn->state = state_send; + if (state_data) +- conn->state_data = strdup(state_data); ++ strlcpy(conn->state_data, state_data, sizeof(conn->state_data)); ++ else ++ conn->state_data[0] = 0; + } + if (conn->state == state_send && +- (state_data == NULL || !strcmp(conn->state_data, state_data))) { ++ (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data)))) { + /* We need to send the currently built message */ + rc = lldpctl_send(conn); + if (rc < 0) +@@ -333,7 +335,7 @@ _lldpctl_do_something(lldpctl_conn_t *conn, + conn->state = state_recv; + } + if (conn->state == state_recv && +- (state_data == NULL || !strcmp(conn->state_data, state_data))) { ++ (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data)))) { + /* We need to receive the answer */ + while ((rc = ctl_msg_recv_unserialized(&conn->input_buffer, + &conn->input_buffer_len, +@@ -347,8 +349,7 @@ _lldpctl_do_something(lldpctl_conn_t *conn, + return SET_ERROR(conn, LLDPCTL_ERR_SERIALIZATION); + /* rc == 0 */ + conn->state = CONN_STATE_IDLE; +- free(conn->state_data); +- conn->state_data = NULL; ++ conn->state_data[0] = 0; + return 0; + } else + return SET_ERROR(conn, LLDPCTL_ERR_INVALID_STATE); +diff --git a/src/lib/atom.h b/src/lib/atom.h +index 265c0a7..ab7037d 100644 +--- a/src/lib/atom.h ++++ b/src/lib/atom.h +@@ -55,11 +55,10 @@ struct lldpctl_conn_t { + #define CONN_STATE_GET_DEFAULT_PORT_SEND 14 + #define CONN_STATE_GET_DEFAULT_PORT_RECV 15 + int state; /* Current state */ +- char *state_data; /* Data attached to the state. It is used to +- * check that we are using the same data as a +- * previous call until the state machine goes to +- * CONN_STATE_IDLE. */ +- ++ /* Data attached to the state. It is used to check that we are using the ++ * same data as a previous call until the state machine goes to ++ * CONN_STATE_IDLE. */ ++ char state_data[IFNAMSIZ + 64]; + /* Error handling */ + lldpctl_error_t error; /* Last error */ + +diff --git a/src/lib/atoms/port.c b/src/lib/atoms/port.c +index 545155c..d902188 100644 +--- a/src/lib/atoms/port.c ++++ b/src/lib/atoms/port.c +@@ -329,7 +329,7 @@ _lldpctl_atom_set_atom_port(lldpctl_atom_t *atom, lldpctl_key_t key, lldpctl_ato + struct lldpd_hardware *hardware = p->hardware; + struct lldpd_port_set set = {}; + int rc; +- char *canary; ++ char *canary = NULL; + + #ifdef ENABLE_DOT3 + struct _lldpctl_atom_dot3_power_t *dpow; +-- +2.17.1.windows.2 + diff --git a/src/lldpd/patch/series b/src/lldpd/patch/series index 5e5e8bc99714..626c5d59751b 100644 --- a/src/lldpd/patch/series +++ b/src/lldpd/patch/series @@ -2,3 +2,7 @@ 0001-return-error-when-port-does-not-exist.patch 0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch 0003-update-tx-interval-immediately.patch +0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch +0005-Read-all-notifications-in-lldpctl_recv.patch +0006-lib-fix-memory-leak.patch +0007-lib-fix-memory-leak-when-handling-I-O.patch From fbcaaa498e2dd87fbeb9e519a0f706133e477e48 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Sat, 14 Dec 2019 00:30:52 +0200 Subject: [PATCH 0236/1427] [config engine] For l2 preset, use admin_status: up by default (#3902) Updated the l2 preset config generator to specify 'admin_status': 'up' for every port by default. The use of setdefault() ensures that if port already has some admin_status set, the original value will not be overwritten. Signed-off-by: Mykola Faryma --- src/sonic-config-engine/config_samples.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sonic-config-engine/config_samples.py b/src/sonic-config-engine/config_samples.py index adaea0c4532c..1b38276524c0 100644 --- a/src/sonic-config-engine/config_samples.py +++ b/src/sonic-config-engine/config_samples.py @@ -51,6 +51,7 @@ def generate_l2_config(data): data['VLAN']['Vlan1000'].setdefault('members', vp) data['VLAN_MEMBER'] = {} for port in natsorted(data['PORT'].keys()): + data['PORT'][port].setdefault('admin_status', 'up') data['VLAN_MEMBER']['Vlan1000|{}'.format(port)] = {'tagging_mode': 'untagged'} return data From e8f3bee0b4ef54cf3d903d94083dfc6a224a8ff5 Mon Sep 17 00:00:00 2001 From: Wataru Ishida <5915117+ishidawataru@users.noreply.github.com> Date: Fri, 13 Dec 2019 14:41:00 -0800 Subject: [PATCH 0237/1427] [broadcom]: fix KNET MTU setting with Linux Kernel > 4.10.0 (#3895) We need to set min_mtu/max_mtu properly to support MTU setting https://github.com/torvalds/linux/commit/61e84623 Signed-off-by: Wataru Ishida --- .../systems/linux/kernel/modules/bcm-knet/bcm-knet.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c index 6767090ec7bb..3559ace7a898 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c @@ -5128,6 +5128,10 @@ bkn_init_ndev(u8 *mac, char *name) if (dev->mtu == 0) { dev->mtu = rx_buffer_size; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) + dev->min_mtu = 68; + dev->max_mtu = rx_buffer_size; +#endif /* Device vectors */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) From eefa8455d73c35b41bd43d4b988b74f5c474581d Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 13 Dec 2019 19:26:39 -0800 Subject: [PATCH 0238/1427] [hostcfgd] avoid in place editing config file contents (#3904) In place editing (sed -i) seems having some issues with filesystem interaction. It could leave 0 size file or corrupted file behind. It would be safer to sed the file contents into a new file and switch new file with the old file. Signed-off-by: Ying Xie --- files/image_config/hostcfgd/hostcfgd | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 7fa8ed2ba205..e10288c0dd37 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -176,6 +176,11 @@ class AaaCfg(object): if modify_conf: self.modify_conf_file() + def modify_single_file(self, filename, operations=None): + if operations: + cmd = "sed -e {0} {1} > {1}.new; mv -f {1} {1}.old; mv -f {1}.new {1}".format(' -e '.join(operations), filename) + os.system(cmd) + def modify_conf_file(self): auth = self.auth_default.copy() auth.update(self.auth) @@ -201,19 +206,19 @@ class AaaCfg(object): # Modify common-auth include file in /etc/pam.d/login and sshd if os.path.isfile(PAM_AUTH_CONF): - os.system("sed -i -e '/^@include/s/common-auth$/common-auth-sonic/' /etc/pam.d/sshd") - os.system("sed -i -e '/^@include/s/common-auth$/common-auth-sonic/' /etc/pam.d/login") + self.modify_single_file('/etc/pam.d/sshd', [ "'/^@include/s/common-auth$/common-auth-sonic/'" ]) + self.modify_single_file('/etc/pam.d/login', [ "'/^@include/s/common-auth$/common-auth-sonic/'" ]) else: - os.system("sed -i -e '/^@include/s/common-auth-sonic$/common-auth/' /etc/pam.d/sshd") - os.system("sed -i -e '/^@include/s/common-auth-sonic$/common-auth/' /etc/pam.d/login") + self.modify_single_file('/etc/pam.d/sshd', [ "'/^@include/s/common-auth-sonic$/common-auth/'" ]) + self.modify_single_file('/etc/pam.d/login', [ "'/^@include/s/common-auth-sonic$/common-auth/'" ]) # Add tacplus in nsswitch.conf if TACACS+ enable if 'tacacs+' in auth['login']: if os.path.isfile(NSS_CONF): - os.system("sed -i -e '/tacplus/b' -e '/^passwd/s/compat/tacplus &/' /etc/nsswitch.conf") + self.modify_single_file(NSS_CONF, [ "'/tacplus/b'", "'/^passwd/s/compat/tacplus &/'"]) else: if os.path.isfile(NSS_CONF): - os.system("sed -i -e '/^passwd/s/tacplus //' /etc/nsswitch.conf") + self.modify_single_file(NSS_CONF, [ "'/^passwd/s/tacplus //'" ]) # Set tacacs+ server in nss-tacplus conf template_file = os.path.abspath(NSS_TACPLUS_CONF_TEMPLATE) From 80bb7fd15a92d7f0153869854d43f9590a191572 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Sun, 15 Dec 2019 01:41:48 +0800 Subject: [PATCH 0239/1427] [process-reboot-cause]Address the issue: Incorrect reboot cause returned when warm reboot follows a hardware caused reboot (#3880) * [process-reboot-cause]Address the issue: Incorrect reboot cause returned when warm reboot follows a hardware caused reboot 1. check whether /proc/cmdline indicates warm/fast reboot. if yes the software reboot cause file will be treated as the reboot cause. finish 2. check whether platform api returns a reboot cause. if yes it is treated as the reboot cause. finish. 3. check whether /hosts/reboot-cause contains a cause. if yes it is treated as the cause otherwise return unknown. * [process-reboot-cause]Fix review comments * [process-reboot-cause]address comments 1. use "with" statement 2. update fast/warm reboot BOOT_ARG * [process-reboot-cause]address comments * refactor the code flow * Remove escape * Remove extra ':' --- .../process-reboot-cause/process-reboot-cause | 114 +++++++++++------- 1 file changed, 73 insertions(+), 41 deletions(-) diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause index 49cfa752641f..e5d228b4c6b6 100755 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -11,6 +11,7 @@ try: import pwd import sys import syslog + import re except ImportError as err: raise ImportError("%s - required module not found" % str(err)) @@ -22,6 +23,16 @@ REBOOT_CAUSE_DIR = "/host/reboot-cause/" REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "reboot-cause.txt" PREVIOUS_REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "previous-reboot-cause.txt" FIRST_BOOT_PLATFORM_FILE = "/tmp/notify_firstboot_to_platform" +REBOOT_TYPE_KEXEC_FILE = "/proc/cmdline" +# The following SONIC_BOOT_TYPEs come from the warm/fast reboot script which is in sonic-utilities +# Because the system can be rebooted from some old versions, we have to take all possible BOOT options into consideration. +# On 201803, 201807 we have +# BOOT_OPTIONS="$(echo $KERNEL_OPTIONS | sed -e 's/\s*linux\s*/BOOT_IMAGE=/') fast-reboot" +# On 201811 and later we have +# BOOT_OPTIONS="$(echo $KERNEL_OPTIONS | sed -e 's/\s*linux\s*/BOOT_IMAGE=/') SONIC_BOOT_TYPE=${BOOT_TYPE_ARG}" where BOOT_TYPE_ARG can be warm, fastfast or fast +# To extract the commom part of them, we should have the following PATTERN +REBOOT_TYPE_KEXEC_PATTERN_WARM = ".*SONIC_BOOT_TYPE=(warm|fastfast).*" +REBOOT_TYPE_KEXEC_PATTERN_FAST = ".*SONIC_BOOT_TYPE=(fast|fast-reboot).*" UNKNOWN_REBOOT_CAUSE = "Unknown" @@ -47,7 +58,32 @@ def log_error(msg): # ============================= Functions ============================= - +def parse_warmfast_reboot_from_proc_cmdline(): + if os.path.isfile(REBOOT_TYPE_KEXEC_FILE): + with open(REBOOT_TYPE_KEXEC_FILE, "r") as cause_file: + cause_file_kexec = cause_file.readline() + m = re.match(REBOOT_TYPE_KEXEC_PATTERN_WARM, cause_file_kexec) + if m and m.group(1): + return 'warm-reboot' + m = re.match(REBOOT_TYPE_KEXEC_PATTERN_FAST, cause_file_kexec) + if m and m.group(1): + return 'fast-reboot' + return None + + +def find_software_reboot_cause(): + software_reboot_cause = UNKNOWN_REBOOT_CAUSE + + if os.path.isfile(REBOOT_CAUSE_FILE): + with open(REBOOT_CAUSE_FILE, "r") as cause_file: + software_reboot_cause = cause_file.readline().rstrip('\n') + + if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): + os.remove(FIRST_BOOT_PLATFORM_FILE) + + return software_reboot_cause + + def main(): log_info("Starting up...") @@ -73,51 +109,48 @@ def main(): try: import sonic_platform - # Check if the previous reboot was caused by hardware - platform = sonic_platform.platform.Platform() - - chassis = platform.get_chassis() - - hardware_reboot_cause, optional_details = chassis.get_reboot_cause() - - if hardware_reboot_cause == chassis.REBOOT_CAUSE_NON_HARDWARE: - # The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will - # contain any software-related reboot info. We will use it as the previous cause. + # 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline + # If yes, the content of /hosts/reboot-cause/reboot-cause.txt will be treated as the reboot cause + proc_cmdline_reboot_cause = parse_warmfast_reboot_from_proc_cmdline() + if proc_cmdline_reboot_cause: + log_info("/proc/cmdline indicates reboot type: {}".format(proc_cmdline_reboot_cause)) if os.path.isfile(REBOOT_CAUSE_FILE): - cause_file = open(REBOOT_CAUSE_FILE, "r") - previous_reboot_cause = cause_file.readline().rstrip('\n') - cause_file.close() - # If it is FirstTime Boot and previous_reboot_cause is unknown - # and hardware_reboot cause is non_hardware then - # Update the reboot cause as required - if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): - if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE): - previous_reboot_cause = UNKNOWN_REBOOT_CAUSE - os.remove(FIRST_BOOT_PLATFORM_FILE) - elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER: - previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details) + with open(REBOOT_CAUSE_FILE, "r") as cause_file: + proc_cmdline_reboot_cause = cause_file.readline().rstrip('\n') + else: + # /proc/cmdline says it's a warm/fast reboot but /host/reboot-cause.txt doesn't exist. + # This could happen when upgrading from a version doesn't support reboot cause. + log_info("Reboot cause file {} doesn't exist".format(REBOOT_CAUSE_DIR)) + + if proc_cmdline_reboot_cause is not None: + previous_reboot_cause = proc_cmdline_reboot_cause else: - previous_reboot_cause = hardware_reboot_cause + # 2. Check if the previous reboot was caused by hardware + # If yes, the hardware reboot cause will be treated as the reboot cause + platform = sonic_platform.platform.Platform() + + chassis = platform.get_chassis() + + hardware_reboot_cause, optional_details = chassis.get_reboot_cause() + + if hardware_reboot_cause == chassis.REBOOT_CAUSE_NON_HARDWARE: + # The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will + # contain any software-related reboot info. We will use it as the previous cause. + previous_reboot_cause = find_software_reboot_cause() + elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER: + previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details) + else: + previous_reboot_cause = hardware_reboot_cause except ImportError as err: log_warning("sonic_platform package not installed. Unable to detect hardware reboot causes.") # If there is a REBOOT_CAUSE_FILE, it will contain any software-related # reboot info. We will use it as the previous cause. - if os.path.isfile(REBOOT_CAUSE_FILE): - cause_file = open(REBOOT_CAUSE_FILE, "r") - previous_reboot_cause = cause_file.readline().rstrip('\n') - cause_file.close() - - # If it is FirstTime Boot and previous_reboot_cause is unknown - # Update the reboot cause as required - if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): - if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE): - previous_reboot_cause = UNKNOWN_REBOOT_CAUSE - os.remove(FIRST_BOOT_PLATFORM_FILE) + previous_reboot_cause = find_software_reboot_cause() + # Write the previous reboot cause to PREVIOUS_REBOOT_CAUSE_FILE - prev_cause_file = open(PREVIOUS_REBOOT_CAUSE_FILE, "w") - prev_cause_file.write(previous_reboot_cause) - prev_cause_file.close() + with open(PREVIOUS_REBOOT_CAUSE_FILE, "w") as prev_cause_file: + prev_cause_file.write(previous_reboot_cause) # Also log the previous reboot cause to the syslog log_info("Previous reboot cause: {}".format(previous_reboot_cause)) @@ -127,9 +160,8 @@ def main(): os.remove(REBOOT_CAUSE_FILE) # Write a new default reboot cause file for the next reboot - cause_file = open(REBOOT_CAUSE_FILE, "w") - cause_file.write(UNKNOWN_REBOOT_CAUSE) - cause_file.close() + with open(REBOOT_CAUSE_FILE, "w") as cause_file: + cause_file.write(UNKNOWN_REBOOT_CAUSE) if __name__ == "__main__": From 3ab4b71656e8cd300aab69e897de6fa7e8103e3d Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Sun, 15 Dec 2019 16:48:48 -0800 Subject: [PATCH 0240/1427] Corefile uploader service (#3887) * Corefile uploader service 1) A service is added to watch /var/core and upload to Azure storage 2) The service is disabled on boot. One may enable explicitly. 3) The .rc file to be updated with acct credentials and http proxy to use. 4) If service is enabled with no credentials, it would sleep, with periodic log messages 5) For any update in .rc, the service has to be restarted to take effect. * Remove rw permission for .rc file for group & others. * Changes per review comments. Re-ordered .rc file per JSON.dump order. Added a script to enable partial update of .rc, which HWProxy would use to add acct key. * Azure storage upload requires python module futures, hence added it to install list. * Removed trailing spaces. * A mistake in name corrected. Copy the .rc updater script to /usr/bin. --- .../build_templates/sonic_debian_extension.j2 | 13 + .../corefile_uploader/core_analyzer.rc.json | 17 ++ .../corefile_uploader/core_uploader.py | 276 ++++++++++++++++++ .../corefile_uploader/core_uploader.service | 11 + .../corefile_uploader/update_json.py | 55 ++++ 5 files changed, 372 insertions(+) create mode 100644 files/image_config/corefile_uploader/core_analyzer.rc.json create mode 100755 files/image_config/corefile_uploader/core_uploader.py create mode 100644 files/image_config/corefile_uploader/core_uploader.service create mode 100755 files/image_config/corefile_uploader/update_json.py diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 4e81593298f6..b11325e86835 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -36,6 +36,8 @@ FILESYSTEM_ROOT_USR="$FILESYSTEM_ROOT/usr" FILESYSTEM_ROOT_USR_SHARE="$FILESYSTEM_ROOT_USR/share" FILESYSTEM_ROOT_USR_SHARE_SONIC="$FILESYSTEM_ROOT_USR_SHARE/sonic" FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES="$FILESYSTEM_ROOT_USR_SHARE_SONIC/templates" +FILESYSTEM_ROOT_ETC="$FILESYSTEM_ROOT/etc" +FILESYSTEM_ROOT_ETC_SONIC="$FILESYSTEM_ROOT_ETC/sonic" GENERATED_SERVICE_FILE="$FILESYSTEM_ROOT/etc/sonic/generated_services.conf" @@ -219,6 +221,17 @@ echo "hostcfgd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/hostcfgd/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +# copy core file uploader files +sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable core_uploader.service +sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.py $FILESYSTEM_ROOT/usr/bin/ +sudo cp $IMAGE_CONFIGS/corefile_uploader/update_json.py $FILESYSTEM_ROOT/usr/bin/ +sudo cp $IMAGE_CONFIGS/corefile_uploader/core_analyzer.rc.json $FILESYSTEM_ROOT_ETC_SONIC/ +sudo chmod og-rw $FILESYSTEM_ROOT_ETC_SONIC/core_analyzer.rc.json +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures + # Copy the buffer configuration template sudo cp $BUILD_TEMPLATES/buffers_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ diff --git a/files/image_config/corefile_uploader/core_analyzer.rc.json b/files/image_config/corefile_uploader/core_analyzer.rc.json new file mode 100644 index 000000000000..3ffa33fd1e1d --- /dev/null +++ b/files/image_config/corefile_uploader/core_analyzer.rc.json @@ -0,0 +1,17 @@ +{ + "local_work": { + "core_upload": "/tmp/core_upload/" + }, + "azure_sonic_core_storage": { + "account_name": "corefilecollection", + "account_key": "", + "share_name": "corefiles-root" + }, + "metadata_files_in_archive": { + "version": "/etc/sonic/sonic_version.yml", + "core_info": "core_info.json" + }, + "env": { + "https_proxy": "" + } +} diff --git a/files/image_config/corefile_uploader/core_uploader.py b/files/image_config/corefile_uploader/core_uploader.py new file mode 100755 index 000000000000..676ff9583b06 --- /dev/null +++ b/files/image_config/corefile_uploader/core_uploader.py @@ -0,0 +1,276 @@ +#!/usr/bin/env python + +import os +import time +import tarfile +import socket +import yaml +import json +import syslog +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +from azure.storage.file import FileService + +global CORE_FILE_PATH, RC_FILE +global hostname, sonicversion, asicname, acctname, acctkey, sharename, cwd +global INIT_CWD +global log_level +global this_file + +this_file = os.path.basename(__file__) + +global cfg +cfg = "" + +CORE_FILE_PATH = "/var/core/" +RC_FILE = "/etc/sonic/core_analyzer.rc.json" +INIT_CWD = "/tmp" + +hostname = "" +sonicversion = "" +asicname = "" +acctname = "" +acctkey = "" +sharename = "" +cwd = [] + +HOURS_4 = (4 * 60 * 60) +PAUSE_ON_FAIL = (60 * 60) +MAX_RETRIES = 5 + +log_level = syslog.LOG_DEBUG + +def log_msg(lvl, fname, m): + if (lvl <= log_level): + syslog.syslog(lvl, "{}: {}".format(fname, m)) + + if log_level == syslog.LOG_DEBUG: + print("{}: {}".format(fname, m)) + +def log_err(m): + log_msg(syslog.LOG_ERR, this_file, m) + +def log_info(m): + log_msg(syslog.LOG_INFO, this_file, m) + +def log_warn(m): + log_msg(syslog.LOG_WARNING, this_file, m) + +def log_debug(m): + log_msg(syslog.LOG_DEBUG, this_file, m) + + +def make_new_dir(p): + os.system("rm -rf " + p) + os.system("mkdir -p " + p) + +def parse_a_json(data, prefix, val): + for i in data: + if type(data[i]) == dict: + parse_a_json(data[i], prefix + (i,), val) + else: + val[prefix + (i,)] = data[i] + +class config: + parsed_data = {} + cfg_data = {} + + def __init__(self): + while not os.path.exists(RC_FILE): + # Wait here until service restart + log_err("Unable to retrieve Azure storage credentials") + time.sleep (HOURS_4) + + with open(RC_FILE, 'r') as f: + self.parsed_data = json.load(f) + parse_a_json(self.parsed_data, (), self.cfg_data) + + def get_data(self, k): + return self.cfg_data[k] if self.cfg_data.has_key(k) else "" + + def get_dict(self): + return self.parsed_data + + def get_core_info(self, corepath, devicename): + info = {} + info["corefname"] = os.path.basename(corepath) + info["tstamp"] = str(os.stat(corepath).st_ctime) + info["devicename"] = devicename + + lpath = self.get_data(("metadata_files_in_archive", "core_info")) + f = open(lpath, "w+") + f.write(json.dumps(info, indent=4)) + f.close() + + return lpath + + +class Watcher: + + def __init__(self): + self.observer = Observer() + + def run(self): + event_handler = Handler() + self.observer.schedule(event_handler, CORE_FILE_PATH) + self.observer.start() + try: + while True: + time.sleep(5) + except: + self.observer.stop() + log_err("Error in watcher") + + self.observer.join() + +def set_env(lst): + for k in lst: + if lst[k]: + os.environ[k] = lst[k] + log_debug("set env {} = {}".format(k, lst[k])) + +class Handler(FileSystemEventHandler): + + @staticmethod + def init(): + global hostname, sonicversion, asicname, acctname, acctkey, sharename + global cwd, cfg + + cfg = config() + + set_env(cfg.get_dict()["env"]) + + hostname = socket.gethostname() + if not hostname: + raise Exception("Failed to read hostname") + + acctname = cfg.get_data(("azure_sonic_core_storage", "account_name")) + acctkey = cfg.get_data(("azure_sonic_core_storage", "account_key")) + sharename = cfg.get_data(("azure_sonic_core_storage", "share_name")) + + if not acctname or not acctkey or not sharename: + while True: + # Wait here until service restart + log_err("Unable to retrieve Azure storage credentials") + time.sleep (HOURS_4) + + with open("/etc/sonic/sonic_version.yml", 'r') as stream: + l = yaml.safe_load(stream) + sonicversion = l['build_version'] + asicname = l['asic_type'] + + if not sonicversion: + raise Exception("Failed to read build_version from /etc/sonic/sonic_version.yml") + + if not asicname: + raise Exception("Failed to read asic_type from /etc/sonic/sonic_version.yml") + + cwd = cfg.get_data(("local_work", "core_upload")).split("/") + if not len(cwd) > 2: + raise Exception("Invalid path for core_upload. Expect a min of two elements in path") + + os.chdir(INIT_CWD) + + @staticmethod + def on_any_event(event): + if event.is_directory: + return None + + elif event.event_type == 'created': + # Take any action here when a file is first created. + log_debug("Received create event - " + event.src_path) + Handler.handle_file(event.src_path) + + + @staticmethod + def wait_for_file_write_complete(path): + ct_size = -1 + + while ct_size != os.path.getsize(path): + ct_size = os.path.getsize(path) + time.sleep(2) + + time.sleep(2) + if ct_size != os.path.getsize(path): + raise Exception("Dump file creation is too slow: " + path) + + log_debug("File write complete - " + path) + + + @staticmethod + def handle_file(path): + + Handler.wait_for_file_write_complete(path) + + lpath = "/".join(cwd) + make_new_dir(lpath) + os.chdir(lpath) + + # Create a new archive with core & more. + metafiles = cfg.get_dict()["metadata_files_in_archive"] + + fname = os.path.basename(path) + tarf_name = fname + ".tar.gz" + + cfg.get_core_info(path, hostname) + + tar = tarfile.open(tarf_name, "w:gz") + for e in metafiles: + tar.add(metafiles[e]) + tar.add(path) + tar.close() + log_debug("Tar file for upload created: " + tarf_name) + + Handler.upload_file(tarf_name, tarf_name) + + log_debug("File uploaded - " + path) + os.chdir(INIT_CWD) + + @staticmethod + def upload_file(fname, fpath): + daemonname = fname.split(".")[0] + i = 0 + fail_msg = "" + + while i <= MAX_RETRIES: + try: + svc = FileService(account_name=acctname, account_key=acctkey) + + l = [sonicversion, asicname, daemonname, hostname] + e = [] + while len(e) != len(l): + e.append(l[len(e)]) + svc.create_directory(sharename, "/".join(e)) + + log_debug("Remote dir created: " + "/".join(e)) + + svc.create_file_from_path(sharename, "/".join(l), fname, fpath) + log_debug("Remote file created: name{} path{}".format(fname, fpath)) + break + + except Exception as e: + log_err("core uploader failed: Failed during upload (" + str(e) +")") + fail_msg = str(e) + i += 1 + if i >= MAX_RETRIES: + raise Exception("Failed while uploading. msg(" + fail_msg + ") after " + str(i) + " retries") + time.sleep(PAUSE_ON_FAIL) + + + @staticmethod + def scan(): + for e in os.listdir(CORE_FILE_PATH): + fl = CORE_FILE_PATH + e + if os.path.isfile(fl): + Handler.handle_file(fl) + + +if __name__ == '__main__': + try: + Handler.init() + w = Watcher() + Handler.scan() + w.run() + except Exception as e: + log_err("core uploader failed: " + str(e) + " Exiting ...") + diff --git a/files/image_config/corefile_uploader/core_uploader.service b/files/image_config/corefile_uploader/core_uploader.service new file mode 100644 index 000000000000..5c061e72a16e --- /dev/null +++ b/files/image_config/corefile_uploader/core_uploader.service @@ -0,0 +1,11 @@ +[Unit] +Description=Host core file uploader daemon +Requires=updategraph.service +After=updategraph.service + +[Service] +Type=simple +ExecStart=/usr/bin/core_uploader.py + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/corefile_uploader/update_json.py b/files/image_config/corefile_uploader/update_json.py new file mode 100755 index 000000000000..03bb39aa4ec8 --- /dev/null +++ b/files/image_config/corefile_uploader/update_json.py @@ -0,0 +1,55 @@ +#! /usr/bin/env python + +import os +import sys +import json +import argparse + +TMP_SUFFIX = ".tmp" +BAK_SUFFIX = ".bak" + +def dict_update(dst, patch): + for k in patch.keys(): + if type(patch[k]) == dict: + dst[k] = dict_update(dst[k], patch[k]) + else: + dst[k] = patch[k] + return dst + +def do_update(rcf, patchf): + dst = {} + patch = {} + + tmpf = rcf + TMP_SUFFIX + bakf = rcf + BAK_SUFFIX + + with open(rcf, "r") as f: + dst = json.load(f) + + with open(patchf, "r") as f: + patch = json.load(f) + + dst = dict_update(dst, patch) + + with open(tmpf, "w") as f: + json.dump(dst, f, indent = 4) + + os.rename(rcf, bakf) + os.rename(tmpf, rcf) + + +def main(): + parser=argparse.ArgumentParser(description="Update JSON based file") + parser.add_argument("-r", "--rc", help="JSON file to be updated") + parser.add_argument("-p", "--patch", help="JSON file holding patch") + args = parser.parse_args() + + if not args.rc or not args.patch: + raise Exception("check usage") + + do_update(args.rc, args.patch) + +if __name__ == '__main__': + main() + + From 1286e5ed3fada79fd81526f91ab079ea254756b8 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Mon, 16 Dec 2019 22:30:35 +0700 Subject: [PATCH 0241/1427] [platform/cel]: Remove afulnx_64 (#3900) remove afulnx_64 install script --- .../sonic_platform/component.py | 4 ++-- .../sonic_platform/component.py | 4 ++-- .../debian/platform-modules-dx010.install | 1 - .../debian/platform-modules-haliburton.install | 1 - .../sonic-platform-modules-cel/tools/afulnx_64 | Bin 828912 -> 0 bytes 5 files changed, 4 insertions(+), 6 deletions(-) delete mode 100755 platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py index ad6810b14c38..fe34bc45c670 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py @@ -140,7 +140,7 @@ def install_firmware(self, image_path): new_image_path = os.path.join("/tmp", (root.lower() + ext)) shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path - elif self.name == "BIOS": - install_command = "afulnx_64 %s /p /b /n /x /r" % image_path + # elif self.name == "BIOS": + # install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py index 67c7a9c46341..d94a93474452 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py @@ -141,7 +141,7 @@ def install_firmware(self, image_path): new_image_path = os.path.join("/tmp", (root.lower() + ext)) shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path - elif self.name == "BIOS": - install_command = "afulnx_64 %s /p /b /n /x /r" % image_path + # elif self.name == "BIOS": + # install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install index 2ab53302a9bf..8570fa1eae84 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install @@ -3,4 +3,3 @@ dx010/cfg/dx010-modules.conf etc/modules-load.d dx010/systemd/platform-modules-dx010.service lib/systemd/system dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin -tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install index d50306304cd5..df78b7a34ea4 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install @@ -5,4 +5,3 @@ services/fancontrol/fancontrol.service lib/systemd/system services/fancontrol/fancontrol usr/local/bin haliburton/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_e1031-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin -tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 b/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 deleted file mode 100755 index c32823393c0805484f1a5ef37375c0ca3384a72b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 828912 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 zⅅ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%0AW?1 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�!aAZIt39-bB2bc;J1p7Y_!T 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 Si3xq7R#~=kHl`c Date: Mon, 16 Dec 2019 07:58:16 -0800 Subject: [PATCH 0242/1427] [swss service] flush fast-reboot enabled flag upon swss stopping (#3908) If we need to stop swss during fast-reboot procedure on the boot up path, it means that something went wrong, like syncd/orchagent crashed already, we are stopping and restarting swss/syncd to re-initialize. In this case, we should proceed as if it is a cold reboot. Signed-off-by: Ying Xie --- files/scripts/swss.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 7dde4aecb365..93f311019d66 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -161,6 +161,13 @@ stop() { /usr/bin/${SERVICE}.sh stop debug "Stopped ${SERVICE} service..." + # Flush FAST_REBOOT table when swss needs to stop. The only + # time when this would take effect is when fast-reboot + # encountered error, e.g. syncd crashed. And swss needs to + # be restarted. + debug "Clearing FAST_REBOOT flag..." + clean_up_tables 6 "'FAST_REBOOT*'" + # Unlock has to happen before reaching out to peer service unlock_service_state_change From 2c6c6bb33fbc9e5b6d77d87a7c39d820e7c8c2be Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Mon, 16 Dec 2019 11:28:29 -0500 Subject: [PATCH 0243/1427] [sonic-ztp]: Add Azure/sonic-ztp as a submodule to Azure/sonic-buildimage (#3903) --- .gitmodules | 3 +++ src/sonic-ztp | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/sonic-ztp diff --git a/.gitmodules b/.gitmodules index cfc6878c7291..b2ffb2b26fff 100644 --- a/.gitmodules +++ b/.gitmodules @@ -69,3 +69,6 @@ [submodule "Switch-SDK-drivers"] path = platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers url = https://github.com/Mellanox/Switch-SDK-drivers +[submodule "src/sonic-ztp"] + path = src/sonic-ztp + url = https://github.com/Azure/sonic-ztp diff --git a/src/sonic-ztp b/src/sonic-ztp new file mode 160000 index 000000000000..374c9e804a9f --- /dev/null +++ b/src/sonic-ztp @@ -0,0 +1 @@ +Subproject commit 374c9e804a9f434cdb58fa7afe0c3f6201bfe56f From 9cb12e6474c263c4e5d1bb10b4e18e230a525093 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Mon, 16 Dec 2019 22:27:25 +0530 Subject: [PATCH 0244/1427] DellEMC: S52xx platforms optoe driver changes (#3865) used overriding method instead of making changes in sfputilbase.py and changed the sff84xx to optoe driver for both QSFP and SFP. --- .../plugins/sfputil.py | 328 ++++++++++++++++- .../plugins/sfputil.py | 329 ++++++++++++++++++ .../plugins/sfputil.py | 12 +- .../s5232f/scripts/s5232f_platform.sh | 33 +- .../s5248f/scripts/s5248f_platform.sh | 2 +- .../z9100/sonic_platform/sfp.py | 2 +- 6 files changed, 692 insertions(+), 14 deletions(-) diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py index 192fb80f6c56..d09f621ee882 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py @@ -8,13 +8,42 @@ import sys import getopt import time + import io from sonic_sfp.sfputilbase import SfpUtilBase from os import * from mmap import * - + from sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_sfp.sff8436 import sff8436Dom + from sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_sfp.sff8472 import sff8472Dom except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_MON_MASK_OFFSET = 242 +QSFP_CHANNL_MON_MASK_WIDTH = 4 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 + +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -225,3 +254,300 @@ def get_transceiver_change_event(self): return True, port_dict time.sleep(0.5) + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power', + ] + transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + offset = 0 + offset_xcvr = 128 + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return transceiver_dom_info_dict + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return transceiver_dom_info_dict + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + else: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + else: + return None + + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), + SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), + SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + + def get_transceiver_dom_threshold_info_dict(self, port_num): + transceiver_dom_threshold_info_dict = {} + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + #Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py index e6680dc8d919..911c04a0fe0d 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py @@ -9,13 +9,44 @@ import sys import getopt import time + import io from sonic_sfp.sfputilbase import SfpUtilBase from os import * from mmap import * + from sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_sfp.sff8436 import sff8436Dom + from sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_sfp.sff8472 import sff8472Dom except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +#definitions of the offset and width for values in DOM info eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_MON_MASK_OFFSET = 242 +QSFP_CHANNL_MON_MASK_WIDTH = 4 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 + +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -287,3 +318,301 @@ def get_transceiver_change_event(self, timeout=0): return True, port_dict time.sleep(0.5) + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power', + ] + transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + offset = 0 + offset_xcvr = 128 + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return transceiver_dom_info_dict + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return transceiver_dom_info_dict + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + else: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + else: + return None + + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), + SFP_TEMPE_WIDTH) + + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), + SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + + def get_transceiver_dom_threshold_info_dict(self, port_num): + transceiver_dom_threshold_info_dict = {} + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + #Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py index bb1c961ab670..70e0b26f7890 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py @@ -348,7 +348,7 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') if port_num in self.qsfp_ports: - offset = 0 + offset = 0 offset_xcvr = 128 file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) if not self._sfp_eeprom_present(file_path, 0): @@ -415,7 +415,7 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx2power'] = 'N/A' transceiver_dom_info_dict['tx3power'] = 'N/A' transceiver_dom_info_dict['tx4power'] = 'N/A' - try: + try: sysfsfile_eeprom.close() except IOError: print("Error: closing sysfs file %s" % file_path) @@ -433,7 +433,7 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] else: - offset = 256 + offset = 256 file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) if not self._sfp_eeprom_present(file_path, 0): return None @@ -507,7 +507,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') if port_num in self.qsfp_ports: - file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) if not self._sfp_eeprom_present(file_path, 0): return None @@ -578,7 +578,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): print("Error: reading sysfs file %s" % file_path) return None - sfpd_obj = sff8472Dom(None,1) + sfpd_obj = sff8472Dom(None,1) if sfpd_obj is None: return transceiver_dom_threshold_info_dict @@ -608,7 +608,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] - transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh index 18e5ca2d5159..6923c9f4b353 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh @@ -51,19 +51,41 @@ switch_board_qsfp_mux() { sleep 2 } -#Attach/Detach 64 instances of EEPROM driver QSFP ports +#Attach/Detach 32 instances of EEPROM driver QSFP ports #eeprom can dump data using below command switch_board_qsfp() { case $1 in "new_device") - for ((i=2;i<=41;i++)); + for ((i=2;i<=33;i++)); do - echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 done ;; "delete_device") - for ((i=2;i<=41;i++)); + for ((i=2;i<=33;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "s5232f_platform: switch_board_qsfp: invalid command !" + ;; + esac +} + +#Attach 2 instances of EEPROM driver SFP ports +switch_board_sfp() { + case $1 in + "new_device") + for ((i=34;i<=35;i++)); + do + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=34;i<=35;i++)); do echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 done @@ -103,6 +125,7 @@ if [ "$1" == "init" ]; then sys_eeprom "new_device" switch_board_qsfp_mux "new_device" switch_board_qsfp "new_device" + switch_board_sfp "new_device" switch_board_modsel switch_board_led_default python /usr/bin/qsfp_irq_enable.py @@ -111,7 +134,7 @@ elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" switch_board_qsfp "delete_device" switch_board_qsfp_mux "delete_device" - + switch_board_sfp "delete_device" modprobe -r i2c-mux-pca954x modprobe -r i2c-dev else diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh index e74a3d6c40de..094c88eeaba6 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh @@ -58,7 +58,7 @@ switch_board_qsfp() { "new_device") for ((i=2;i<=57;i++)); do - echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 done ;; diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py index 87057545cbb7..9f5844d2058c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py @@ -44,7 +44,7 @@ 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', - 'specification_compliance', ,'type_abbrv_name','vendor_date', 'vendor_oui'] + 'specification_compliance','type_abbrv_name','vendor_date', 'vendor_oui'] dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', From 1e5d25b48e896c46ae31a10d2ebeef7dafde40a0 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Tue, 17 Dec 2019 00:04:42 +0700 Subject: [PATCH 0245/1427] [platform-celestica]: Update fancontrol service for Seastone-DX010 device (#3690) * [platform/cel]: add fancontrol service support for dx010 * [device/celestica]: add hysteresis temp to dx010 fancontrol configuration --- .../x86_64-cel_seastone-r0/fancontrol | 12 --- .../x86_64-cel_seastone-r0/fancontrol-B2F | 11 +++ .../x86_64-cel_seastone-r0/fancontrol-F2B | 12 +++ .../debian/platform-modules-dx010.install | 3 + .../debian/platform-modules-dx010.postinst | 3 + .../dx010/scripts/fancontrol.sh | 81 +++++++++++++++++++ .../services/fancontrol/fancontrol | 11 +-- 7 files changed, 116 insertions(+), 17 deletions(-) delete mode 100644 device/celestica/x86_64-cel_seastone-r0/fancontrol create mode 100644 device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F create mode 100644 device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh diff --git a/device/celestica/x86_64-cel_seastone-r0/fancontrol b/device/celestica/x86_64-cel_seastone-r0/fancontrol deleted file mode 100644 index 8d5cbccb9d00..000000000000 --- a/device/celestica/x86_64-cel_seastone-r0/fancontrol +++ /dev/null @@ -1,12 +0,0 @@ -# Configuration file generated by pwmconfig, changes will be lost -INTERVAL=10 -DEVPATH=hwmon6=devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e hwmon7=devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d -DEVNAME=hwmon6=emc2305 hwmon7=emc2305 -FCTEMPS=hwmon6/device/pwm1=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon6/device/pwm2=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon6/device/pwm3=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon6/device/pwm4=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon6/device/pwm5=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon7/device/pwm1=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon7/device/pwm2=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon7/device/pwm3=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon7/device/pwm4=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon7/device/pwm5=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input -FCFANS=hwmon7/device/pwm5=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d/pwm5 hwmon7/device/pwm4=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d/pwm4 hwmon7/device/pwm3=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d/pwm3 hwmon7/device/pwm2=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d/pwm2 hwmon7/device/pwm1=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d/pwm1 hwmon6/device/pwm5=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e/pwm5 hwmon6/device/pwm4=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e/pwm4 hwmon6/device/pwm3=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e/pwm3 hwmon6/device/pwm2=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e/pwm2 hwmon6/device/pwm1=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e/pwm1 -MINTEMP=hwmon6/device/pwm1=26 hwmon6/device/pwm2=26 hwmon6/device/pwm3=26 hwmon6/device/pwm4=26 hwmon6/device/pwm5=26 hwmon7/device/pwm1=26 hwmon7/device/pwm2=26 hwmon7/device/pwm3=26 hwmon7/device/pwm4=26 hwmon7/device/pwm5=26 -MAXTEMP=hwmon6/device/pwm1=45 hwmon6/device/pwm2=45 hwmon6/device/pwm3=45 hwmon6/device/pwm4=45 hwmon6/device/pwm5=45 hwmon7/device/pwm1=45 hwmon7/device/pwm2=45 hwmon7/device/pwm3=45 hwmon7/device/pwm4=45 hwmon7/device/pwm5=45 -MINSTART=hwmon6/device/pwm1=89 hwmon6/device/pwm2=89 hwmon6/device/pwm3=89 hwmon6/device/pwm4=89 hwmon6/device/pwm5=89 hwmon7/device/pwm1=89 hwmon7/device/pwm2=89 hwmon7/device/pwm3=89 hwmon7/device/pwm4=89 hwmon7/device/pwm5=89 -MINSTOP=hwmon6/device/pwm1=89 hwmon6/device/pwm2=89 hwmon6/device/pwm3=89 hwmon6/device/pwm4=89 hwmon6/device/pwm5=89 hwmon7/device/pwm1=89 hwmon7/device/pwm2=89 hwmon7/device/pwm3=89 hwmon7/device/pwm4=89 hwmon7/device/pwm5=89 -MINPWM=hwmon6/device/pwm1=89 hwmon6/device/pwm2=89 hwmon6/device/pwm3=89 hwmon6/device/pwm4=89 hwmon6/device/pwm5=89 hwmon7/device/pwm1=89 hwmon7/device/pwm2=89 hwmon7/device/pwm3=89 hwmon7/device/pwm4=89 hwmon7/device/pwm5=89 -MAXPWM=hwmon6/device/pwm1=255 hwmon6/device/pwm2=255 hwmon6/device/pwm3=255 hwmon6/device/pwm4=255 hwmon6/device/pwm5=255 hwmon7/device/pwm1=255 hwmon7/device/pwm2=255 hwmon7/device/pwm3=255 hwmon7/device/pwm4=255 hwmon7/device/pwm5=255 diff --git a/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F b/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F new file mode 100644 index 000000000000..c2132d7f2806 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F @@ -0,0 +1,11 @@ +# Configuration file generated by pwmconfig, changes will be lost +INTERVAL=2 +FCTEMPS=13-002e/pwm1=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-002e/pwm2=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-002e/pwm3=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-002e/pwm4=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-002e/pwm5=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-004d/pwm1=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-004d/pwm2=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-004d/pwm3=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-004d/pwm4=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-004d/pwm5=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input +FCFANS=13-004d/pwm5=13-004d/fan5_input 13-004d/pwm4=13-004d/fan4_input 13-004d/pwm3=13-004d/fan3_input 13-004d/pwm2=13-004d/fan2_input 13-004d/pwm1=13-004d/fan1_input 13-002e/pwm5=13-002e/fan5_input 13-002e/pwm4=13-002e/fan4_input 13-002e/pwm3=13-002e/fan3_input 13-002e/pwm2=13-002e/fan2_input 13-002e/pwm1=13-002e/fan1_input +MINTEMP=13-002e/pwm1=27 13-002e/pwm2=27 13-002e/pwm3=27 13-002e/pwm4=27 13-002e/pwm5=27 13-004d/pwm1=27 13-004d/pwm2=27 13-004d/pwm3=27 13-004d/pwm4=27 13-004d/pwm5=27 +MAXTEMP=13-002e/pwm1=46 13-002e/pwm2=46 13-002e/pwm3=46 13-002e/pwm4=46 13-002e/pwm5=46 13-004d/pwm1=46 13-004d/pwm2=46 13-004d/pwm3=46 13-004d/pwm4=46 13-004d/pwm5=46 +MINSTART=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MINSTOP=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MINPWM=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MAXPWM=13-002e/pwm1=255 13-002e/pwm2=255 13-002e/pwm3=255 13-002e/pwm4=255 13-002e/pwm5=255 13-004d/pwm1=255 13-004d/pwm2=255 13-004d/pwm3=255 13-004d/pwm4=255 13-004d/pwm5=255 +THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3 \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B b/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B new file mode 100644 index 000000000000..dc67e2623cc2 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B @@ -0,0 +1,12 @@ +# Configuration file generated by pwmconfig, changes will be lost +INTERVAL=2 +FCTEMPS=13-002e/pwm1=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-002e/pwm2=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-002e/pwm3=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-002e/pwm4=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-002e/pwm5=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-004d/pwm1=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-004d/pwm2=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-004d/pwm3=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-004d/pwm4=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-004d/pwm5=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input +FCFANS=13-004d/pwm5=13-004d/fan5_input 13-004d/pwm4=13-004d/fan4_input 13-004d/pwm3=13-004d/fan3_input 13-004d/pwm2=13-004d/fan2_input 13-004d/pwm1=13-004d/fan1_input 13-002e/pwm5=13-002e/fan5_input 13-002e/pwm4=13-002e/fan4_input 13-002e/pwm3=13-002e/fan3_input 13-002e/pwm2=13-002e/fan2_input 13-002e/pwm1=13-002e/fan1_input +MINTEMP=13-002e/pwm1=26 13-002e/pwm2=26 13-002e/pwm3=26 13-002e/pwm4=26 13-002e/pwm5=26 13-004d/pwm1=26 13-004d/pwm2=26 13-004d/pwm3=26 13-004d/pwm4=26 13-004d/pwm5=26 +MAXTEMP=13-002e/pwm1=45 13-002e/pwm2=45 13-002e/pwm3=45 13-002e/pwm4=45 13-002e/pwm5=45 13-004d/pwm1=45 13-004d/pwm2=45 13-004d/pwm3=45 13-004d/pwm4=45 13-004d/pwm5=45 +MINSTART=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MINSTOP=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MINPWM=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MAXPWM=13-002e/pwm1=255 13-002e/pwm2=255 13-002e/pwm3=255 13-002e/pwm4=255 13-002e/pwm5=255 13-004d/pwm1=255 13-004d/pwm2=255 13-004d/pwm3=255 13-004d/pwm4=255 13-004d/pwm5=255 +THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3 + diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install index 8570fa1eae84..9b456a7c9112 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install @@ -1,5 +1,8 @@ dx010/scripts/dx010_check_qsfp.sh usr/local/bin dx010/cfg/dx010-modules.conf etc/modules-load.d dx010/systemd/platform-modules-dx010.service lib/systemd/system +dx010/scripts/fancontrol.sh etc/init.d +services/fancontrol/fancontrol.service lib/systemd/system +services/fancontrol/fancontrol usr/local/bin dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst index 15243c935ca3..8dbf0ece6676 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst @@ -1,6 +1,9 @@ depmod -a systemctl enable platform-modules-dx010.service +systemctl enable fancontrol.service + systemctl start platform-modules-dx010.service +systemctl start fancontrol.service /usr/local/bin/platform_api_mgnt.sh install diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh new file mode 100644 index 000000000000..75ad6c65b37f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh @@ -0,0 +1,81 @@ +#! /bin/sh + +### BEGIN INIT INFO +# Provides: fancontrol +# Required-Start: $remote_fs +# Required-Stop: $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: +# Short-Description: fancontrol +# Description: fan speed regulator +### END INIT INFO + +. /lib/lsb/init-functions + +[ -f /etc/default/rcS ] && . /etc/default/rcS +PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin +DAEMON=/usr/local/bin/fancontrol +DESC="fan speed regulator" +NAME="fancontrol" +PIDFILE=/var/run/fancontrol.pid +MAIN_CONF=/usr/share/sonic/device/x86_64-cel_seastone-r0/fancontrol +DEVPATH=/sys/devices/pci0000:00/0000:00:13.0/i2c-*/i2c-13/13-002e +GPIO_DIR=/sys/class/gpio +BASE_GPIO=$(find $GPIO_DIR | grep gpiochip | grep -o '[[:digit:]]*') +DIRGPIO_START=15 + +test -x $DAEMON || exit 0 + +for i in 1 2 3 4 5 +do + FANFAULT=$(cat ${DEVPATH}/fan${i}_fault) + [ $FANFAULT = 1 ] && continue + FANDIR_GPIO_NUMBER=$((DIRGPIO_START + BASE_GPIO)) + FANDIR_VALUE=$(cat ${GPIO_DIR}/gpio${FANDIR_GPIO_NUMBER}/value) + DIRGPIO_START=$((DIRGPIO_START+1)) + FANDIR=$([ $FANDIR_VALUE = 1 ] && echo "B2F" || echo "F2B") +done +CONF=${MAIN_CONF}-${FANDIR} + +case "$1" in + start) + if [ -f $CONF ] ; then + if $DAEMON --check $CONF 1>/dev/null 2>/dev/null ; then + log_daemon_msg "Starting $DESC" "$NAME\n" + start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON $CONF + log_end_msg $? + else + log_failure_msg "Not starting fancontrol, broken configuration file; please re-run pwmconfig." + fi + else + if [ "$VERBOSE" != no ]; then + log_warning_msg "Not starting fancontrol; run pwmconfig first." + fi + fi + ;; + stop) + log_daemon_msg "Stopping $DESC" "$NAME" + start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo --startas $DAEMON $CONF + rm -f $PIDFILE + log_end_msg $? + ;; + restart) + $0 stop + sleep 3 + $0 start + ;; + force-reload) + if start-stop-daemon --stop --test --quiet --pidfile $PIDFILE --startas $DAEMON $CONF ; then + $0 restart + fi + ;; + status) + status_of_proc $DAEMON $NAME $CONF && exit 0 || exit $? + ;; + *) + log_success_msg "Usage: /etc/init.d/fancontrol {start|stop|restart|force-reload|status}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol b/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol index 9155d8a66998..eb15598b0efa 100755 --- a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol +++ b/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol @@ -322,11 +322,12 @@ fi cd $DIR # Check for configuration change -if [ "$DIR" != "/" ] && [ -z "$DEVPATH" -o -z "$DEVNAME" ] -then - echo "Configuration is too old, please run pwmconfig again" >&2 - exit 1 -fi +# if [ "$DIR" != "/" ] && [ -z "$DEVPATH" -o -z "$DEVNAME" ] +# then +# echo "Configuration is too old, please run pwmconfig again" >&2 +# exit 1 +# fi + if [ "$DIR" = "/" -a -n "$DEVPATH" ] then echo "Unneeded DEVPATH with absolute device paths" >&2 From 4ba0ff25d2ac89b10b2a94208140f7c52776fb69 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Mon, 16 Dec 2019 19:07:05 +0200 Subject: [PATCH 0246/1427] [services] make snmp.timer work again and delay telemetry.service (#3742) Delay CPU intensive services at boot - How I did it Made snmp.timer work and add telemetry.timer. But this is not enough because it breaks the existing snmp dependency on swss. So, in this solution snmp timer is a wanted by swss service, but since OnBootSec timer expires only once it will not trigger snmp service, so I added line "OnUnitActiveSec=0 sec" which will start snmp service based on the last time it was active. On boot only OnBootSec will expire, on swss start/restarts only second timer will expire immediately and trigger snmp service. However, snmp service will not stop after "systemctl stop snmp" because of the second timer which will always expire when snmp service because unavailable. So there is a conflict which will be handled by systemd if we add "Conflicts=" line to both snmp.service and snmp.timer. So during boot: snmp does not start by default swss starts and starts snmp timer OnUnitActiveSec=0 does not expire since there is no snmp active OnBootSec expires and starts snmp service and snmp timer gets stopped During "systemctl restart swss" snmp stops because of Requisite on swss snmp unblocks snmp timer from running swss starts and starts snmp timer OnUnitActiveSec=0 expires imidiately and start snmp which stops snmp timer During "systemctl stop snmp" stop of snmp service unblocks snmp timer but no one starts the timer so it is not started by "OnUnitActiveSec=0" --- files/build_templates/snmp.service.j2 | 3 +-- files/build_templates/snmp.timer | 4 +++- files/build_templates/sonic_debian_extension.j2 | 8 ++++++-- files/build_templates/telemetry.service.j2 | 2 -- files/build_templates/telemetry.timer | 9 +++++++++ slave.mk | 1 + 6 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 files/build_templates/telemetry.timer diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index 310048e68beb..4997ab737e37 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -4,6 +4,7 @@ Requires=updategraph.service Requisite=swss.service After=updategraph.service swss.service syncd.service Before=ntp-config.service +Conflicts=snmp.timer StartLimitIntervalSec=1200 StartLimitBurst=3 @@ -14,5 +15,3 @@ ExecStop=/usr/bin/{{docker_container_name}}.sh stop Restart=always RestartSec=30 -[Install] -WantedBy=multi-user.target swss.service diff --git a/files/build_templates/snmp.timer b/files/build_templates/snmp.timer index 464cf01459ba..6d1838554d0e 100644 --- a/files/build_templates/snmp.timer +++ b/files/build_templates/snmp.timer @@ -1,9 +1,11 @@ [Unit] Description=Delays snmp container until SONiC has started +Conflicts=snmp.service [Timer] +OnUnitActiveSec=0 sec OnBootSec=3min 30 sec Unit=snmp.service [Install] -WantedBy=timers.target +WantedBy=timers.target swss.service diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index b11325e86835..b63b5addac4b 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -359,7 +359,7 @@ EOF ## Bind docker path if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then sudo mkdir -p $FILESYSTEM_ROOT/dockerfs - sudo mount --bind dockerfs $FILESYSTEM_ROOT/dockerfs + sudo mount --bind dockerfs $FILESYSTEM_ROOT/dockerfs fi {% if installer_images.strip() -%} @@ -376,7 +376,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta {% endif %} {% endfor %} if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then - sudo umount $FILESYSTEM_ROOT/dockerfs + sudo umount $FILESYSTEM_ROOT/dockerfs sudo rm -fr $FILESYSTEM_ROOT/dockerfs sudo kill -9 `sudo $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS_PID` || true else @@ -404,6 +404,10 @@ sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer +{% if enable_system_telemetry == 'y' %} +sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable telemetry.timer +{% endif %} sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-dev sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get clean -y diff --git a/files/build_templates/telemetry.service.j2 b/files/build_templates/telemetry.service.j2 index 98ae2871bf6f..43fa039156d7 100644 --- a/files/build_templates/telemetry.service.j2 +++ b/files/build_templates/telemetry.service.j2 @@ -14,5 +14,3 @@ ExecStop=/usr/bin/{{docker_container_name}}.sh stop Restart=always RestartSec=30 -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/telemetry.timer b/files/build_templates/telemetry.timer new file mode 100644 index 000000000000..e08f1c09eac6 --- /dev/null +++ b/files/build_templates/telemetry.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays telemetry container until SONiC has started + +[Timer] +OnBootSec=3min 30 sec +Unit=telemetry.service + +[Install] +WantedBy=timers.target diff --git a/slave.mk b/slave.mk index e518f1e4d8a5..44b903ddf9c9 100644 --- a/slave.mk +++ b/slave.mk @@ -641,6 +641,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export sonic_asic_platform="$(patsubst %-$(CONFIGURED_ARCH),%,$(CONFIGURED_PLATFORM))" export enable_organization_extensions="$(ENABLE_ORGANIZATION_EXTENSIONS)" export enable_dhcp_graph_service="$(ENABLE_DHCP_GRAPH_SERVICE)" + export enable_system_telemetry="$(ENABLE_SYSTEM_TELEMETRY)" export enable_ztp="$(ENABLE_ZTP)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" From 08ec4fcfe7290d4a05e14a6b7597f4b38f2cef34 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Tue, 17 Dec 2019 08:00:14 -0800 Subject: [PATCH 0247/1427] [swss-common] update submodule for sonic-swss-common (#3916) update multiDB changes in sonic-swss-common, including: [Enhancement] debian/conffiles will give prompt when file existing, need a way to supress prompt (#323) [MultiDB]:swsscommon replace old API with new APIs including tests (#324) Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 29a2cdfe9ea9..5b55954c5d6d 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 29a2cdfe9ea9bb0c4d2d82be9428228a8ab6b9d4 +Subproject commit 5b55954c5d6d4ae343af141357c3a2f6dd600c58 From 7ae371287f5d2c7c046003812c558e5cf169fd85 Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Tue, 17 Dec 2019 19:45:28 +0200 Subject: [PATCH 0248/1427] [Mellanox]: Update SAI submodule (#3883) Signed-off-by: Volodymyr Samotiy --- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 925116eb63a5..d878245e364c 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 925116eb63a5a9012dcc22a7a0682ada6e976380 +Subproject commit d878245e364ce8d5edd08bbd7120c44c92362235 From 51b78b5c335099e2c47e7277cbc8748a219eed77 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Tue, 17 Dec 2019 20:58:55 +0200 Subject: [PATCH 0249/1427] [mellanox]: Enhance pmon synchronization with hw-mgmt platform counters. (#3885) Signed-off-by: Nazarii Hnydyn --- .../x86_64-mlnx_msn2700-r0/platform_wait | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_wait index 44321184dccc..a233eb41de42 100755 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_wait +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_wait @@ -1,12 +1,37 @@ #!/bin/bash +declare -r SYSLOG_LOGGER="/usr/bin/logger" +declare -r SYSLOG_IDENTIFIER="platform_wait" +declare -r SYSLOG_ERROR="error" +declare -r SYSLOG_NOTICE="notice" +declare -r SYSLOG_INFO="info" + +declare -r HW_MGMT_CONFIG="/var/run/hw-management/config" + +declare -r MODULE_COUNTER="${HW_MGMT_CONFIG}/module_counter" +declare -r SFP_COUNTER="${HW_MGMT_CONFIG}/sfp_counter" + declare -r EXIT_SUCCESS="0" declare -r EXIT_TIMEOUT="1" -declare -r QSFP_PATH="/var/run/hw-management/qsfp" +function log_error() { + eval "${SYSLOG_LOGGER} -t ${SYSLOG_IDENTIFIER} -p ${SYSLOG_ERROR} $@" +} -function WaitForQsfpReady() { - local -r _QSFP_PATH="${1}" +function log_notice() { + eval "${SYSLOG_LOGGER} -t ${SYSLOG_IDENTIFIER} -p ${SYSLOG_NOTICE} $@" +} + +function log_info() { + eval "${SYSLOG_LOGGER} -t ${SYSLOG_IDENTIFIER} -p ${SYSLOG_INFO} $@" +} + +function wait_for_sfp() { + local -r _NUM_MATCH="^[0-9]+$" + local -r _NUM_ZERO="0" + + local _MODULE_CNT="0" + local _SFP_CNT="0" local -i _WDOG_CNT="1" local -ir _WDOG_MAX="300" @@ -14,11 +39,14 @@ function WaitForQsfpReady() { local -r _TIMEOUT="1s" while [[ "${_WDOG_CNT}" -le "${_WDOG_MAX}" ]]; do - for _QSFP in ${_QSFP_PATH}/qsfp*; do - if [[ -e "${_QSFP}" ]]; then + _MODULE_CNT="$(cat ${MODULE_COUNTER} 2>&1)" + _SFP_CNT="$(cat ${SFP_COUNTER} 2>&1)" + + if [[ "${_MODULE_CNT}" =~ ${_NUM_MATCH} && "${_SFP_CNT}" =~ ${_NUM_MATCH} ]]; then + if [[ "${_SFP_CNT}" -gt "${_NUM_ZERO}" && "${_MODULE_CNT}" -eq "${_SFP_CNT}" ]]; then return "${EXIT_SUCCESS}" fi - done + fi let "_WDOG_CNT++" sleep "${_TIMEOUT}" @@ -27,14 +55,15 @@ function WaitForQsfpReady() { return "${EXIT_TIMEOUT}" } -echo "Wait for QSFP I2C interface is ready" +log_info "Wait for SFP interfaces to be ready" -WaitForQsfpReady "${QSFP_PATH}" +wait_for_sfp EXIT_CODE="$?" if [[ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]]; then - echo "QSFP I2C interface is not ready: timeout" + log_error "SFP interfaces are not ready: timeout" exit "${EXIT_CODE}" fi -echo "QSFP I2C interface is ready: mlxsw_minimal has finished initialization" +log_info "SFP interfaces are ready" + exit "${EXIT_SUCCESS}" From a4b107b1dea1b16bbb000dfd7acaa335cd8e604f Mon Sep 17 00:00:00 2001 From: Ciju Rajan K Date: Wed, 18 Dec 2019 01:23:53 +0530 Subject: [PATCH 0250/1427] [Juniper][QFX5210] Skip starting 'ledd' (#3920) There is no ledd in qfx5210 platform. This patch skip starting ledd in pmon container. This also will help in fixing the pmon container not getting started if there is no ledd running. Signed-off-by: Ciju Rajan K --- .../juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json b/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} From 063deb9b5f1e0601e7f7d55eef6939943c0f8a2b Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Wed, 18 Dec 2019 01:28:17 +0530 Subject: [PATCH 0251/1427] [Marvell HwSKU] port configration updated with speed (#3919) Signed-off-by: Antony Rheneus --- .../et6448m/port_config.ini | 106 +++++++++--------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini index 8073e8bec86e..062c252ce195 100644 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini @@ -1,53 +1,53 @@ -# name lanes alias -Ethernet0 1 Ethernet0 -Ethernet1 2 Ethernet1 -Ethernet2 3 Ethernet2 -Ethernet3 4 Ethernet3 -Ethernet4 5 Ethernet4 -Ethernet5 6 Ethernet5 -Ethernet6 7 Ethernet6 -Ethernet7 8 Ethernet7 -Ethernet8 9 Ethernet8 -Ethernet9 10 Ethernet9 -Ethernet10 11 Ethernet10 -Ethernet11 12 Ethernet11 -Ethernet12 13 Ethernet12 -Ethernet13 14 Ethernet13 -Ethernet14 15 Ethernet14 -Ethernet15 16 Ethernet15 -Ethernet16 17 Ethernet16 -Ethernet17 18 Ethernet17 -Ethernet18 19 Ethernet18 -Ethernet19 20 Ethernet19 -Ethernet20 21 Ethernet20 -Ethernet21 22 Ethernet21 -Ethernet22 23 Ethernet22 -Ethernet23 24 Ethernet23 -Ethernet24 25 Ethernet24 -Ethernet25 26 Ethernet25 -Ethernet26 27 Ethernet26 -Ethernet27 28 Ethernet27 -Ethernet28 29 Ethernet28 -Ethernet29 30 Ethernet29 -Ethernet30 31 Ethernet30 -Ethernet31 32 Ethernet31 -Ethernet32 33 Ethernet32 -Ethernet33 34 Ethernet33 -Ethernet34 35 Ethernet34 -Ethernet35 36 Ethernet35 -Ethernet36 37 Ethernet36 -Ethernet37 38 Ethernet37 -Ethernet38 39 Ethernet38 -Ethernet39 40 Ethernet39 -Ethernet40 41 Ethernet40 -Ethernet41 42 Ethernet41 -Ethernet42 43 Ethernet42 -Ethernet43 44 Ethernet43 -Ethernet44 45 Ethernet44 -Ethernet45 46 Ethernet45 -Ethernet46 47 Ethernet46 -Ethernet47 48 Ethernet47 -Ethernet48 49 Ethernet48 -Ethernet49 50 Ethernet49 -Ethernet50 51 Ethernet50 -Ethernet51 52 Ethernet51 +# name lanes alias index speed +Ethernet0 1 Ethernet0 1 1000 +Ethernet1 2 Ethernet1 2 1000 +Ethernet2 3 Ethernet2 3 1000 +Ethernet3 4 Ethernet3 4 1000 +Ethernet4 5 Ethernet4 5 1000 +Ethernet5 6 Ethernet5 6 1000 +Ethernet6 7 Ethernet6 7 1000 +Ethernet7 8 Ethernet7 8 1000 +Ethernet8 9 Ethernet8 9 1000 +Ethernet9 10 Ethernet9 10 1000 +Ethernet10 11 Ethernet10 11 1000 +Ethernet11 12 Ethernet11 12 1000 +Ethernet12 13 Ethernet12 13 1000 +Ethernet13 14 Ethernet13 14 1000 +Ethernet14 15 Ethernet14 15 1000 +Ethernet15 16 Ethernet15 16 1000 +Ethernet16 17 Ethernet16 17 1000 +Ethernet17 18 Ethernet17 18 1000 +Ethernet18 19 Ethernet18 19 1000 +Ethernet19 20 Ethernet19 20 1000 +Ethernet20 21 Ethernet20 21 1000 +Ethernet21 22 Ethernet21 22 1000 +Ethernet22 23 Ethernet22 23 1000 +Ethernet23 24 Ethernet23 24 1000 +Ethernet24 25 Ethernet24 25 1000 +Ethernet25 26 Ethernet25 26 1000 +Ethernet26 27 Ethernet26 27 1000 +Ethernet27 28 Ethernet27 28 1000 +Ethernet28 29 Ethernet28 29 1000 +Ethernet29 30 Ethernet29 30 1000 +Ethernet30 31 Ethernet30 31 1000 +Ethernet31 32 Ethernet31 32 1000 +Ethernet32 33 Ethernet32 33 1000 +Ethernet33 34 Ethernet33 34 1000 +Ethernet34 35 Ethernet34 35 1000 +Ethernet35 36 Ethernet35 36 1000 +Ethernet36 37 Ethernet36 37 1000 +Ethernet37 38 Ethernet37 38 1000 +Ethernet38 39 Ethernet38 39 1000 +Ethernet39 40 Ethernet39 40 1000 +Ethernet40 41 Ethernet40 41 1000 +Ethernet41 42 Ethernet41 42 1000 +Ethernet42 43 Ethernet42 43 1000 +Ethernet43 44 Ethernet43 44 1000 +Ethernet44 45 Ethernet44 45 1000 +Ethernet45 46 Ethernet45 46 1000 +Ethernet46 47 Ethernet46 47 1000 +Ethernet47 48 Ethernet47 48 1000 +Ethernet48 49 Ethernet48 49 10000 +Ethernet49 50 Ethernet49 50 10000 +Ethernet50 51 Ethernet50 51 10000 +Ethernet51 52 Ethernet51 52 10000 From 4458efbd7161985c8c14b76fcaf66688d06b2c8d Mon Sep 17 00:00:00 2001 From: srideepDell Date: Tue, 17 Dec 2019 16:26:23 -0700 Subject: [PATCH 0252/1427] DellEMC: Add support for new platform z9332f -32x400G (#3845) * Switch Vendor: DellEMC * Switch SKU: z9332F * ASIC Vendor: Broadcom * Swich ASIC: tomahawk3 * Port Configuration: 32x400G * SONiC Image: sonic-broadcom.bin * Changes Include ipmitool implementation for platform_sensors script is inclued in pmon startup --- .../DellEMC-Z9332f-O32/buffers.json.j2 | 2 + .../DellEMC-Z9332f-O32/buffers_defaults_t0.j2 | 20 + .../DellEMC-Z9332f-O32/buffers_defaults_t1.j2 | 20 + .../DellEMC-Z9332f-O32/custom_led.bin | Bin 0 -> 920 bytes .../DellEMC-Z9332f-O32/linkscan_led_fw.bin | Bin 0 -> 4752 bytes .../DellEMC-Z9332f-O32/pg_profile_lookup.ini | 23 + .../DellEMC-Z9332f-O32/port_config.ini | 35 + .../DellEMC-Z9332f-O32/qos.json.j2 | 226 ++ .../DellEMC-Z9332f-O32/sai.profile | 1 + .../DellEMC-Z9332f-O32/sai_postinit_cmd.soc | 2530 +++++++++++++++++ .../DellEMC-Z9332f-O32/sai_preinit_cmd.soc | 3 + .../th3-z9332f-32x400G.config.bcm | 519 ++++ .../default_sku | 1 + .../installer.conf | 2 + .../led_proc_init.soc | 7 + .../plugins/eeprom.py | 22 + .../plugins/psuutil.py | 126 + .../plugins/sfputil.py | 307 ++ platform/broadcom/one-image.mk | 1 + platform/broadcom/platform-modules-dell.mk | 8 +- .../debian/control | 5 + .../debian/platform-modules-z9332f.init | 39 + .../debian/platform-modules-z9332f.install | 7 + .../debian/platform-modules-z9332f.postinst | 10 + .../sonic-platform-modules-dell/debian/rules | 2 +- .../z9332f/cfg/z9332f-modules.conf | 17 + .../z9332f/modules/Makefile | 4 + .../z9332f/modules/cls-i2c-ocore.c | 845 ++++++ .../z9332f/modules/cls-i2c-ocore.h | 22 + .../z9332f/modules/cls-switchboard.c | 447 +++ .../z9332f/modules/mc24lc64t.c | 142 + .../z9332f/modules/z9332f-modules.conf | 17 + .../z9332f/scripts/pcisysfs.py | 102 + .../z9332f/scripts/platform_sensors.py | 198 ++ .../z9332f/scripts/sensors | 8 + .../z9332f/scripts/z9332f_platform.sh | 180 ++ .../systemd/platform-modules-z9332f.service | 13 + src/sonic-device-data/tests/permitted_list | 1 + 38 files changed, 5910 insertions(+), 2 deletions(-) create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers.json.j2 create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2 create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/custom_led.bin create mode 100755 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/linkscan_led_fw.bin create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/pg_profile_lookup.ini create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/port_config.ini create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/qos.json.j2 create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_postinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/default_sku create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/installer.conf create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/led_proc_init.soc create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.init create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.postinst create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/cfg/z9332f-modules.conf create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.h create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/z9332f-modules.conf create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/sensors create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers.json.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..77747f6403c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2 @@ -0,0 +1,20 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + }, + "BUFFER_PROFILE": { + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..77747f6403c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2 @@ -0,0 +1,20 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + }, + "BUFFER_PROFILE": { + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/custom_led.bin b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..3ee9545e28ae08c5b597570c490af69a5d1f2bb4 GIT binary patch literal 920 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 X`cUsHXR!vGk^Z4y?GFw9z}SBSTZoUr literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/pg_profile_lookup.ini b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/pg_profile_lookup.ini new file mode 100644 index 000000000000..a5f3286beef8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/pg_profile_lookup.ini @@ -0,0 +1,23 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1270 0 190500 -2 2540 + 25000 5m 1270 0 190500 -2 2540 + 40000 5m 1270 0 190500 -2 2540 + 50000 5m 1270 0 190500 -2 2540 + 100000 5m 1270 0 190500 -2 2540 + 200000 5m 1270 0 190500 -2 2540 + 400000 5m 1270 0 190500 -2 2540 + 10000 40m 1270 0 190500 -2 2540 + 25000 40m 1270 0 190500 -2 2540 + 40000 40m 1270 0 190500 -2 2540 + 50000 40m 1270 0 190500 -2 2540 + 100000 40m 1270 0 190500 -2 2540 + 200000 40m 1270 0 190500 -2 2540 + 400000 40m 1270 0 190500 -2 2540 + 10000 300m 1270 0 190500 -2 2540 + 25000 300m 1270 0 190500 -2 2540 + 40000 300m 1270 0 190500 -2 2540 + 50000 300m 1270 0 190500 -2 2540 + 100000 300m 1270 0 190500 -2 2540 + 200000 300m 1270 0 190500 -2 2540 + 400000 300m 1270 0 190500 -2 2540 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/port_config.ini b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/port_config.ini new file mode 100644 index 000000000000..790fb490cfe6 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias index speed +Ethernet0 33,34,35,36,37,38,39,40 fourhundredGigE1/1 1 400000 +Ethernet8 41,42,43,44,45,46,47,48 fourhundredGigE1/2 2 400000 +Ethernet16 49,50,51,52,53,54,55,56 fourhundredGigE1/3 3 400000 +Ethernet24 57,58,59,60,61,62,63,64 fourhundredGigE1/4 4 400000 +Ethernet32 65,66,67,68,69,70,71,72 fourhundredGigE1/5 5 400000 +Ethernet40 73,74,75,76,77,78,79,80 fourhundredGigE1/6 6 400000 +Ethernet48 81,82,83,84,85,86,87,88 fourhundredGigE1/7 7 400000 +Ethernet56 89,90,91,92,93,94,95,96 fourhundredGigE1/8 8 400000 +Ethernet64 1,2,3,4,5,6,7,8 fourhundredGigE1/9 9 400000 +Ethernet72 9,10,11,12,13,14,15,16 fourhundredGigE1/10 10 400000 +Ethernet80 17,18,19,20,21,22,23,24 fourhundredGigE1/11 11 400000 +Ethernet88 25,26,27,28,29,30,31,32 fourhundredGigE1/12 12 400000 +Ethernet96 97,98,99,100,101,102,103,104 fourhundredGigE1/13 13 400000 +Ethernet104 105,106,107,108,109,110,111,112 fourhundredGigE1/14 14 400000 +Ethernet112 113,114,115,116,117,118,119,120 fourhundredGigE1/15 15 400000 +Ethernet120 121,122,123,124,125,126,127,128 fourhundredGigE1/16 16 400000 +Ethernet128 129,130,131,132,133,134,135,136 fourhundredGigE1/17 17 400000 +Ethernet136 137,138,139,140,141,142,143,144 fourhundredGigE1/18 18 400000 +Ethernet144 145,146,147,148,149,150,151,152 fourhundredGigE1/19 19 400000 +Ethernet152 153,154,155,156,157,158,159,160 fourhundredGigE1/20 20 400000 +Ethernet160 225,226,227,228,229,230,231,232 fourhundredGigE1/21 21 400000 +Ethernet168 233,234,235,236,237,238,239,240 fourhundredGigE1/22 22 400000 +Ethernet176 241,242,243,244,245,246,247,248 fourhundredGigE1/23 23 400000 +Ethernet184 249,250,251,252,253,254,255,256 fourhundredGigE1/24 24 400000 +Ethernet192 161,162,163,164,165,166,167,168 fourhundredGigE1/25 25 400000 +Ethernet200 169,170,171,172,173,174,175,176 fourhundredGigE1/26 26 400000 +Ethernet208 177,178,179,180,181,182,183,184 fourhundredGigE1/27 27 400000 +Ethernet216 185,186,187,188,189,190,191,192 fourhundredGigE1/28 28 400000 +Ethernet224 193,194,195,196,197,198,199,200 fourhundredGigE1/29 29 400000 +Ethernet232 201,202,203,204,205,206,207,208 fourhundredGigE1/30 30 400000 +Ethernet240 209,210,211,212,213,214,215,216 fourhundredGigE1/31 31 400000 +Ethernet248 217,218,219,220,221,222,223,224 fourhundredGigE1/32 32 400000 +Ethernet256 257 tenGigE1/33 33 10000 +Ethernet257 258 tenGigE1/34 34 10000 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/qos.json.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/qos.json.j2 new file mode 100644 index 000000000000..a48e1b56621c --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/qos.json.j2 @@ -0,0 +1,226 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "STRICT" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "pfc_enable" : "3,4", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile new file mode 100644 index 000000000000..19cd5cb02839 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-z9332f-32x400G.config.bcm diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_postinit_cmd.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_postinit_cmd.soc new file mode 100644 index 000000000000..9550e9c822c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_postinit_cmd.soc @@ -0,0 +1,2530 @@ +delay 200 +link off +counter off + +#*** +#*** Port CD0 Preemphasis setting *** +#*** + +local port cd0 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD1 Preemphasis setting *** +#*** + +local port cd1 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD2 Preemphasis setting *** +#*** + +local port cd2 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD3 Preemphasis setting *** +#*** + +local port cd3 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD4 Preemphasis setting *** +#*** + +local port cd4 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD5 Preemphasis setting *** +#*** + +local port cd5 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD6 Preemphasis setting *** +#*** + +local port cd6 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD7 Preemphasis setting *** +#*** + +local port cd7 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD8 Preemphasis setting *** +#*** + +local port cd8 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD9 Preemphasis setting *** +#*** + +local port cd9 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD10 Preemphasis setting *** +#*** + +local port cd10 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x78 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD11 Preemphasis setting *** +#*** + +local port cd11 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD12 Preemphasis setting *** +#*** + +local port cd12 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD13 Preemphasis setting *** +#*** + +local port cd13 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD14 Preemphasis setting *** +#*** + +local port cd14 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD15 Preemphasis setting *** +#*** + +local port cd15 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD16 Preemphasis setting *** +#*** + +local port cd16 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD17 Preemphasis setting *** +#*** + +local port cd17 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD18 Preemphasis setting *** +#*** + +local port cd18 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD19 Preemphasis setting *** +#*** + +local port cd19 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD20 Preemphasis setting *** +#*** + +local port cd20 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD21 Preemphasis setting *** +#*** + +local port cd21 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD22 Preemphasis setting *** +#*** + +local port cd22 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD23 Preemphasis setting *** +#*** + +local port cd23 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD24 Preemphasis setting *** +#*** + +local port cd24 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD25 Preemphasis setting *** +#*** + +local port cd25 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD26 Preemphasis setting *** +#*** + +local port cd26 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD27 Preemphasis setting *** +#*** + +local port cd27 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD28 Preemphasis setting *** +#*** + +local port cd28 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD29 Preemphasis setting *** +#*** + +local port cd29 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD30 Preemphasis setting *** +#*** + +local port cd30 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD31 Preemphasis setting *** +#*** + +local port cd31 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +link on +counter on diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_preinit_cmd.soc new file mode 100644 index 000000000000..e48c05b9f664 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_preinit_cmd.soc @@ -0,0 +1,3 @@ +#Not supported Until SAI 3.6 +#m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +#m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm new file mode 100644 index 000000000000..3d204640d5aa --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm @@ -0,0 +1,519 @@ +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 + +#firmware load method, use fast load +load_firmware=0x2 + +ccm_dma_enable=0 +ccmdma_intr_enable=0 +mem_cache_enable=0 +phy_enable=0 +phy_null=1 + +dport_map_enable=1 + +module_64ports.0=0 +tdma_intr_enable.0=1 +ipv6_lpm_128b_enable.0=1 +stat_if_parity_enable.0=1 +oversubscribe_mode=0 +bcm_tunnel_term_compatible_mode.0=1 +table_dma_enable.0=1 +schan_intr_enable.0=0 +parity_enable.0=1 +tdma_timeout_usec=1000000 +lls_num_l2uc.0=10 +miim_intr_enable.0=0 +table_dma_enable=1 +max_vp_lags.0=0 +tdma_intr_enable=1 +tdma_timeout_usec.0=5000000 +parity_correction.0=1 +mmu_lossless.0=0 +bcm_num_cos=8 +default_cpu_tx_queue=7 +pktdma_poll_mode_channel_bitmap=1 +l3_max_ecmp_mode.0=1 +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 + +l2xlrn_thread_interval=50000 +l2xlrn_intr_en=0 + +pbmp_xport_xe=0xffffffFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + +phy_an_c73=3 + +portmap_1.0=1:400 +portmap_5.0=9:400 +portmap_10.0=17:400 +portmap_14.0=25:400 + +portmap_20.0=33:400 +portmap_24.0=41:400 +portmap_29.0=49:400 +portmap_33.0=57:400 + +portmap_40.0=65:400 +portmap_44.0=73:400 +portmap_49.0=81:400 +portmap_53.0=89:400 + +portmap_60.0=97:400 +portmap_64.0=105:400 +portmap_69.0=113:400 +portmap_73.0=121:400 + +portmap_80.0=129:400 +portmap_84.0=137:400 +portmap_89.0=145:400 +portmap_93.0=153:400 + +portmap_100.0=161:400 +portmap_104.0=169:400 +portmap_109.0=177:400 +portmap_113.0=185:400 + +portmap_120.0=193:400 +portmap_124.0=201:400 +portmap_129.0=209:400 +portmap_133.0=217:400 + +portmap_140.0=225:400 +portmap_144.0=233:400 +portmap_149.0=241:400 +portmap_153.0=249:400 + +portmap_38.0=257:10:1 +portmap_118.0=258:10:1 + +dport_map_port_20=1 +dport_map_port_21=2 +dport_map_port_22=3 +dport_map_port_23=4 +dport_map_port_24=5 +dport_map_port_25=6 +dport_map_port_26=7 +dport_map_port_27=8 +dport_map_port_28=9 +dport_map_port_29=10 +dport_map_port_30=11 +dport_map_port_31=12 +dport_map_port_32=13 +dport_map_port_33=14 +dport_map_port_34=15 +dport_map_port_35=16 +dport_map_port_36=17 +dport_map_port_37=18 +dport_map_port_40=19 +dport_map_port_41=20 +dport_map_port_42=21 +dport_map_port_43=22 +dport_map_port_44=23 +dport_map_port_45=24 +dport_map_port_46=25 +dport_map_port_47=26 +dport_map_port_48=27 +dport_map_port_49=28 +dport_map_port_50=29 +dport_map_port_51=30 +dport_map_port_52=31 +dport_map_port_53=32 +dport_map_port_54=33 +dport_map_port_55=34 +dport_map_port_56=35 +dport_map_port_57=36 +dport_map_port_1=37 +dport_map_port_2=38 +dport_map_port_3=39 +dport_map_port_4=40 +dport_map_port_5=41 +dport_map_port_6=42 +dport_map_port_7=43 +dport_map_port_8=44 +dport_map_port_9=45 +dport_map_port_10=46 +dport_map_port_11=47 +dport_map_port_12=48 +dport_map_port_13=49 +dport_map_port_14=50 +dport_map_port_15=51 +dport_map_port_16=52 +dport_map_port_17=53 +dport_map_port_18=54 +dport_map_port_60=55 +dport_map_port_61=56 +dport_map_port_62=57 +dport_map_port_63=58 +dport_map_port_64=59 +dport_map_port_65=60 +dport_map_port_66=61 +dport_map_port_67=62 +dport_map_port_68=63 +dport_map_port_69=64 +dport_map_port_70=65 +dport_map_port_71=66 +dport_map_port_72=67 +dport_map_port_73=68 +dport_map_port_74=69 +dport_map_port_75=70 +dport_map_port_76=71 +dport_map_port_77=72 +dport_map_port_80=73 +dport_map_port_81=74 +dport_map_port_82=75 +dport_map_port_83=76 +dport_map_port_84=77 +dport_map_port_85=78 +dport_map_port_86=79 +dport_map_port_87=80 +dport_map_port_88=81 +dport_map_port_89=82 +dport_map_port_90=83 +dport_map_port_91=84 +dport_map_port_92=85 +dport_map_port_93=86 +dport_map_port_94=87 +dport_map_port_95=88 +dport_map_port_96=89 +dport_map_port_97=90 +dport_map_port_140=91 +dport_map_port_141=92 +dport_map_port_142=93 +dport_map_port_143=94 +dport_map_port_144=95 +dport_map_port_145=96 +dport_map_port_146=97 +dport_map_port_147=98 +dport_map_port_148=99 +dport_map_port_149=100 +dport_map_port_150=101 +dport_map_port_151=102 +dport_map_port_152=103 +dport_map_port_153=104 +dport_map_port_154=105 +dport_map_port_155=106 +dport_map_port_156=107 +dport_map_port_157=108 +dport_map_port_100=109 +dport_map_port_101=110 +dport_map_port_102=111 +dport_map_port_103=112 +dport_map_port_104=113 +dport_map_port_105=114 +dport_map_port_106=115 +dport_map_port_107=116 +dport_map_port_108=117 +dport_map_port_109=118 +dport_map_port_110=119 +dport_map_port_111=120 +dport_map_port_112=121 +dport_map_port_113=122 +dport_map_port_114=123 +dport_map_port_115=124 +dport_map_port_116=125 +dport_map_port_117=126 +dport_map_port_120=127 +dport_map_port_121=128 +dport_map_port_122=129 +dport_map_port_123=130 +dport_map_port_124=131 +dport_map_port_125=132 +dport_map_port_126=133 +dport_map_port_127=134 +dport_map_port_128=135 +dport_map_port_129=136 +dport_map_port_130=137 +dport_map_port_131=138 +dport_map_port_132=139 +dport_map_port_133=140 +dport_map_port_134=141 +dport_map_port_135=142 +dport_map_port_136=143 +dport_map_port_137=144 +dport_map_port_38=145 +dport_map_port_118=146 + +phy_chain_rx_lane_map_physical{33.0}=0x65732041 +phy_chain_tx_lane_map_physical{33.0}=0x47206531 +phy_chain_rx_lane_map_physical{41.0}=0x07561243 +phy_chain_tx_lane_map_physical{41.0}=0x36207514 +phy_chain_rx_lane_map_physical{49.0}=0x54632071 +phy_chain_tx_lane_map_physical{49.0}=0x06241735 +phy_chain_rx_lane_map_physical{57.0}=0x07561243 +phy_chain_tx_lane_map_physical{57.0}=0x35207614 +phy_chain_rx_lane_map_physical{65.0}=0x45623170 +phy_chain_tx_lane_map_physical{65.0}=0x51260734 +phy_chain_rx_lane_map_physical{73.0}=0x07561243 +phy_chain_tx_lane_map_physical{73.0}=0x37245610 +phy_chain_rx_lane_map_physical{81.0}=0x45632071 +phy_chain_tx_lane_map_physical{81.0}=0x51260734 +phy_chain_rx_lane_map_physical{89.0}=0x07561243 +phy_chain_tx_lane_map_physical{89.0}=0x26437510 +phy_chain_rx_lane_map_physical{1.0}=0x30176524 +phy_chain_tx_lane_map_physical{1.0}=0x20615374 +phy_chain_rx_lane_map_physical{9.0}=0x37562041 +phy_chain_tx_lane_map_physical{9.0}=0x05176432 +phy_chain_rx_lane_map_physical{17.0}=0x43607251 +phy_chain_tx_lane_map_physical{17.0}=0x70261435 +phy_chain_rx_lane_map_physical{25.0}=0x60347125 +phy_chain_tx_lane_map_physical{25.0}=0x46357120 +phy_chain_rx_lane_map_physical{97.0}=0x47601352 +phy_chain_tx_lane_map_physical{97.0}=0x04265137 +phy_chain_rx_lane_map_physical{105.0}=0x73206415 +phy_chain_tx_lane_map_physical{105.0}=0x26374150 +phy_chain_rx_lane_map_physical{113.0}=0x47632051 +phy_chain_tx_lane_map_physical{113.0}=0x03254617 +phy_chain_rx_lane_map_physical{121.0}=0x63027415 +phy_chain_tx_lane_map_physical{121.0}=0x63721045 +phy_chain_rx_lane_map_physical{129.0}=0x30154627 +phy_chain_tx_lane_map_physical{129.0}=0x04735261 +phy_chain_rx_lane_map_physical{137.0}=0x24753061 +phy_chain_tx_lane_map_physical{137.0}=0x37614520 +phy_chain_rx_lane_map_physical{145.0}=0x47601352 +phy_chain_tx_lane_map_physical{145.0}=0x63274510 +phy_chain_rx_lane_map_physical{153.0}=0x07361524 +phy_chain_tx_lane_map_physical{153.0}=0x36527104 +phy_chain_rx_lane_map_physical{225.0}=0x56410273 +phy_chain_tx_lane_map_physical{225.0}=0x10274635 +phy_chain_rx_lane_map_physical{233.0}=0x15740263 +phy_chain_tx_lane_map_physical{233.0}=0x24351607 +phy_chain_rx_lane_map_physical{241.0}=0x74015263 +phy_chain_tx_lane_map_physical{241.0}=0x04152637 +phy_chain_rx_lane_map_physical{249.0}=0x62037514 +phy_chain_tx_lane_map_physical{249.0}=0x72453160 +phy_chain_rx_lane_map_physical{161.0}=0x46510273 +phy_chain_tx_lane_map_physical{161.0}=0x01653724 +phy_chain_rx_lane_map_physical{169.0}=0x25743160 +phy_chain_tx_lane_map_physical{169.0}=0x07216435 +phy_chain_rx_lane_map_physical{177.0}=0x46510273 +phy_chain_tx_lane_map_physical{177.0}=0x01652734 +phy_chain_rx_lane_map_physical{185.0}=0x25743160 +phy_chain_tx_lane_map_physical{185.0}=0x37016425 +phy_chain_rx_lane_map_physical{193.0}=0x46510372 +phy_chain_tx_lane_map_physical{193.0}=0x06153724 +phy_chain_rx_lane_map_physical{201.0}=0x25743160 +phy_chain_tx_lane_map_physical{201.0}=0x36017524 +phy_chain_rx_lane_map_physical{209.0}=0x47601352 +phy_chain_tx_lane_map_physical{209.0}=0x04152736 +phy_chain_rx_lane_map_physical{217.0}=0x26453170 +phy_chain_tx_lane_map_physical{217.0}=0x36027415 + +serdes_core_rx_polarity_flip_physical{33}=0x29 +serdes_core_tx_polarity_flip_physical{33}=0xfe +serdes_core_rx_polarity_flip_physical{41}=0xb1 +serdes_core_tx_polarity_flip_physical{41}=0xe8 +serdes_core_rx_polarity_flip_physical{49}=0xca +serdes_core_tx_polarity_flip_physical{49}=0xb6 +serdes_core_rx_polarity_flip_physical{57}=0x9b +serdes_core_tx_polarity_flip_physical{57}=0xdc +serdes_core_rx_polarity_flip_physical{65}=0x17 +serdes_core_tx_polarity_flip_physical{65}=0x86 +serdes_core_rx_polarity_flip_physical{73}=0x9b +serdes_core_tx_polarity_flip_physical{73}=0x55 +serdes_core_rx_polarity_flip_physical{81}=0xa +serdes_core_tx_polarity_flip_physical{81}=0x6 +serdes_core_rx_polarity_flip_physical{89}=0x9b +serdes_core_tx_polarity_flip_physical{89}=0x48 +serdes_core_rx_polarity_flip_physical{1}=0xec +serdes_core_tx_polarity_flip_physical{1}=0x56 +serdes_core_rx_polarity_flip_physical{9}=0x13 +serdes_core_tx_polarity_flip_physical{9}=0xa6 +serdes_core_rx_polarity_flip_physical{17}=0x5a +serdes_core_tx_polarity_flip_physical{17}=0xc6 +serdes_core_rx_polarity_flip_physical{25}=0xf +serdes_core_tx_polarity_flip_physical{25}=0x4e +serdes_core_rx_polarity_flip_physical{97}=0x17 +serdes_core_tx_polarity_flip_physical{97}=0x2e +serdes_core_rx_polarity_flip_physical{105}=0xce +serdes_core_tx_polarity_flip_physical{105}=0x7c +serdes_core_rx_polarity_flip_physical{113}=0xa +serdes_core_tx_polarity_flip_physical{113}=0x35 + +serdes_core_rx_polarity_flip_physical{121}=0xb9 +serdes_core_tx_polarity_flip_physical{121}=0xef +serdes_core_rx_polarity_flip_physical{129}=0xe8 +serdes_core_tx_polarity_flip_physical{129}=0xac +serdes_core_rx_polarity_flip_physical{137}=0xcb +serdes_core_tx_polarity_flip_physical{137}=0x9c +serdes_core_rx_polarity_flip_physical{145}=0x17 +serdes_core_tx_polarity_flip_physical{145}=0x32 +serdes_core_rx_polarity_flip_physical{153}=0xb9 +serdes_core_tx_polarity_flip_physical{153}=0xaf +serdes_core_rx_polarity_flip_physical{225}=0xaa +serdes_core_tx_polarity_flip_physical{225}=0x7 +serdes_core_rx_polarity_flip_physical{233}=0x31 +serdes_core_tx_polarity_flip_physical{233}=0x47 +serdes_core_rx_polarity_flip_physical{241}=0xe8 +serdes_core_tx_polarity_flip_physical{241}=0x9e +serdes_core_rx_polarity_flip_physical{249}=0xec +serdes_core_tx_polarity_flip_physical{249}=0x1f +serdes_core_rx_polarity_flip_physical{161}=0x6a +serdes_core_tx_polarity_flip_physical{161}=0xd4 +serdes_core_rx_polarity_flip_physical{169}=0x9e +serdes_core_tx_polarity_flip_physical{169}=0x7b +serdes_core_rx_polarity_flip_physical{177}=0x6a +serdes_core_tx_polarity_flip_physical{177}=0xcc +serdes_core_rx_polarity_flip_physical{185}=0x9e +serdes_core_tx_polarity_flip_physical{185}=0x58 +serdes_core_rx_polarity_flip_physical{193}=0x6f +serdes_core_tx_polarity_flip_physical{193}=0x24 +serdes_core_rx_polarity_flip_physical{201}=0x9e +serdes_core_tx_polarity_flip_physical{201}=0xdf +serdes_core_rx_polarity_flip_physical{209}=0x17 +serdes_core_tx_polarity_flip_physical{209}=0xe9 +serdes_core_rx_polarity_flip_physical{217}=0xec +serdes_core_tx_polarity_flip_physical{217}=0x68 + +serdes_lane_config_media_type_49=copper +serdes_lane_config_media_type_50=copper +serdes_lane_config_media_type_51=copper +serdes_lane_config_media_type_52=copper +serdes_lane_config_media_type_54=copper +serdes_lane_config_media_type_55=copper +serdes_lane_config_media_type_56=copper +serdes_lane_config_media_type_57=copper +serdes_lane_config_media_type_53=copper +serdes_lane_config_media_type_60=copper +serdes_lane_config_media_type_61=copper +serdes_lane_config_media_type_62=copper +serdes_lane_config_media_type_63=copper +serdes_lane_config_media_type_65=copper +serdes_lane_config_media_type_66=copper +serdes_lane_config_media_type_67=copper +serdes_lane_config_media_type_68=copper +serdes_lane_config_media_type_64=copper +serdes_lane_config_media_type_80=copper +serdes_lane_config_media_type_81=copper +serdes_lane_config_media_type_82=copper +serdes_lane_config_media_type_83=copper +serdes_lane_config_media_type_85=copper +serdes_lane_config_media_type_86=copper +serdes_lane_config_media_type_87=copper +serdes_lane_config_media_type_88=copper +serdes_lane_config_media_type_84=copper +serdes_lane_config_media_type_100=copper +serdes_lane_config_media_type_101=copper +serdes_lane_config_media_type_102=copper +serdes_lane_config_media_type_103=copper +serdes_lane_config_media_type_105=copper +serdes_lane_config_media_type_106=copper +serdes_lane_config_media_type_107=copper +serdes_lane_config_media_type_108=copper +serdes_lane_config_media_type_104=copper +serdes_lane_config_media_type_120=copper +serdes_lane_config_media_type_121=copper +serdes_lane_config_media_type_122=copper +serdes_lane_config_media_type_123=copper +serdes_lane_config_media_type_125=copper +serdes_lane_config_media_type_126=copper +serdes_lane_config_media_type_127=copper +serdes_lane_config_media_type_128=copper +serdes_lane_config_media_type_124=copper +serdes_lane_config_media_type_140=copper +serdes_lane_config_media_type_141=copper +serdes_lane_config_media_type_142=copper +serdes_lane_config_media_type_143=copper +serdes_lane_config_media_type_145=copper +serdes_lane_config_media_type_146=copper +serdes_lane_config_media_type_147=copper +serdes_lane_config_media_type_148=copper +serdes_lane_config_media_type_144=copper +serdes_lane_config_media_type_40=copper +serdes_lane_config_media_type_41=copper +serdes_lane_config_media_type_42=copper +serdes_lane_config_media_type_43=copper +serdes_lane_config_media_type_45=copper +serdes_lane_config_media_type_46=copper +serdes_lane_config_media_type_47=copper +serdes_lane_config_media_type_48=copper +serdes_lane_config_media_type_44=copper +serdes_lane_config_media_type_69=copper +serdes_lane_config_media_type_70=copper +serdes_lane_config_media_type_71=copper +serdes_lane_config_media_type_72=copper +serdes_lane_config_media_type_74=copper +serdes_lane_config_media_type_75=copper +serdes_lane_config_media_type_76=copper +serdes_lane_config_media_type_77=copper +serdes_lane_config_media_type_73=copper +serdes_lane_config_media_type_1=copper +serdes_lane_config_media_type_2=copper +serdes_lane_config_media_type_3=copper +serdes_lane_config_media_type_4=copper +serdes_lane_config_media_type_6=copper +serdes_lane_config_media_type_7=copper +serdes_lane_config_media_type_8=copper +serdes_lane_config_media_type_9=copper +serdes_lane_config_media_type_5=copper +serdes_lane_config_media_type_29=copper +serdes_lane_config_media_type_30=copper +serdes_lane_config_media_type_31=copper +serdes_lane_config_media_type_32=copper +serdes_lane_config_media_type_34=copper +serdes_lane_config_media_type_35=copper +serdes_lane_config_media_type_36=copper +serdes_lane_config_media_type_37=copper +serdes_lane_config_media_type_33=copper +serdes_lane_config_media_type_89=copper +serdes_lane_config_media_type_90=copper +serdes_lane_config_media_type_91=copper +serdes_lane_config_media_type_92=copper +serdes_lane_config_media_type_94=copper +serdes_lane_config_media_type_95=copper +serdes_lane_config_media_type_96=copper +serdes_lane_config_media_type_97=copper +serdes_lane_config_media_type_93=copper +serdes_lane_config_media_type_109=copper +serdes_lane_config_media_type_110=copper +serdes_lane_config_media_type_111=copper +serdes_lane_config_media_type_112=copper +serdes_lane_config_media_type_114=copper +serdes_lane_config_media_type_115=copper +serdes_lane_config_media_type_116=copper +serdes_lane_config_media_type_117=copper +serdes_lane_config_media_type_113=copper +serdes_lane_config_media_type_129=copper +serdes_lane_config_media_type_130=copper +serdes_lane_config_media_type_131=copper +serdes_lane_config_media_type_132=copper +serdes_lane_config_media_type_134=copper +serdes_lane_config_media_type_135=copper +serdes_lane_config_media_type_136=copper +serdes_lane_config_media_type_137=copper +serdes_lane_config_media_type_133=copper +serdes_lane_config_media_type_149=copper +serdes_lane_config_media_type_150=copper +serdes_lane_config_media_type_151=copper +serdes_lane_config_media_type_152=copper +serdes_lane_config_media_type_154=copper +serdes_lane_config_media_type_155=copper +serdes_lane_config_media_type_156=copper +serdes_lane_config_media_type_157=copper +serdes_lane_config_media_type_153=copper +serdes_lane_config_media_type_10=copper +serdes_lane_config_media_type_11=copper +serdes_lane_config_media_type_12=copper +serdes_lane_config_media_type_13=copper +serdes_lane_config_media_type_15=copper +serdes_lane_config_media_type_16=copper +serdes_lane_config_media_type_17=copper +serdes_lane_config_media_type_18=copper +serdes_lane_config_media_type_14=copper +serdes_lane_config_media_type_20=copper +serdes_lane_config_media_type_21=copper +serdes_lane_config_media_type_22=copper +serdes_lane_config_media_type_23=copper +serdes_lane_config_media_type_25=copper +serdes_lane_config_media_type_26=copper +serdes_lane_config_media_type_27=copper +serdes_lane_config_media_type_28=copper +serdes_lane_config_media_type_24=copper + +#sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc +sai_postinit_cmd_file=/usr/share/sonic/hwsku/sai_postinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/default_sku b/device/dell/x86_64-dellemc_z9332f_d1508-r0/default_sku new file mode 100644 index 000000000000..7716a7af3216 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/default_sku @@ -0,0 +1 @@ +DellEMC-Z9332f-O32 t1 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/installer.conf b/device/dell/x86_64-dellemc_z9332f_d1508-r0/installer.conf new file mode 100644 index 000000000000..924e0fb81963 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/installer.conf @@ -0,0 +1,2 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/led_proc_init.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/led_proc_init.soc new file mode 100644 index 000000000000..0c116f35f80b --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/led_proc_init.soc @@ -0,0 +1,7 @@ +# LED microprocessor initialization for Dell z9332f +# +# +#Led0 +#Support only after SAI 3.6 +#led auto on +#led start diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py new file mode 100644 index 000000000000..e224cd452496 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# DellEMC Z9332f +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py new file mode 100644 index 000000000000..b2c373de358f --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py @@ -0,0 +1,126 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path +import logging +import commands +import sys + + +Z9332F_MAX_PSUS = 2 +IPMI_PSU1_DATA = "docker exec -it pmon ipmitool raw 0x04 0x2d 0x2f | awk '{print substr($0,9,1)}'" +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x2f | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA = "docker exec -it pmon ipmitool raw 0x04 0x2d 0x39 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x39 | awk '{print substr($0,9,1)}'" +PSU_PRESENCE = "PSU{0}_Status" +# Use this for older firmware +# PSU_PRESENCE="PSU{0}_prsnt" +ipmi_sdr_list = "" + + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + def isDockerEnv(self): + num_docker = open('/proc/self/cgroup', 'r').read().count(":/docker") + if num_docker > 0: + return True + else: + return False + + # Fetch a BMC register + def get_pmc_register(self, reg_name): + + status = 1 + global ipmi_sdr_list + ipmi_dev_node = "/dev/pmi0" + ipmi_cmd_1 = IPMI_PSU1_DATA + ipmi_cmd_2 = IPMI_PSU1_DATA + dockerenv = self.isDockerEnv() + if dockerenv == True: + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) + + if status: + logging.error('Failed to execute ipmitool') + sys.exit(0) + + output = ipmi_sdr_list + + return output + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + Z9332F_MAX_PSUS = 2 + return Z9332F_MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + # Until psu_status is implemented this is hardcoded temporarily + + status = 1 + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + ret_status = 1 + global ipmi_sdr_list + ipmi_dev_node = "/dev/pmi0" + dockerenv = self.isDockerEnv() + if dockerenv == True: + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) + + #if ret_status: + # print ipmi_sdr_list + # logging.error('Failed to execute ipmitool') + # sys.exit(0) + + psu_status = ipmi_sdr_list + + if psu_status == '1': + status = 1 + + return status + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py new file mode 100644 index 000000000000..1ea6af1f8d26 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py @@ -0,0 +1,307 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import struct + import sys + import getopt + import time + import select + from sonic_sfp.sfputilbase import SfpUtilBase + from os import * + from mmap import * + +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +#from xcvrd +SFP_STATUS_REMOVED = '0' +SFP_STATUS_INSERTED = '1' + + + + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 34 + PORTS_IN_BLOCK = 34 + + BASE_RES_PATH = "/sys/bus/pci/devices/0000:09:00.0/resource0" + + _port_to_i2c_mapping = { + 1: 10, + 2: 11, + 3: 12, + 4: 13, + 5: 14, + 6: 15, + 7: 16, + 8: 17, + 9: 18, + 10: 19, + 11: 20, + 12: 21, + 13: 22, + 14: 23, + 15: 24, + 16: 25, + 17: 26, + 18: 27, + 19: 28, + 20: 29, + 21: 30, + 22: 31, + 23: 32, + 24: 33, + 25: 34, + 26: 35, + 27: 36, + 28: 37, + 29: 38, + 30: 39, + 31: 40, + 32: 41, + 33: 1, + 34: 2, + } + + _port_to_eeprom_mapping = {} + + _global_port_pres_dict = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def pci_mem_read(self, mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + reg_val = struct.unpack('I', read_data_stream) + mem_val = str(reg_val)[1:-2] + # print "reg_val read:%x"%reg_val + return mem_val + + def pci_mem_write(self, mm, offset, data): + mm.seek(offset) + # print "data to write:%x"%data + mm.write(struct.pack('I', data)) + + def pci_set_value(self, resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + + def pci_get_value(self, resource, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_read(mm, offset) + mm.close() + close(fd) + return val + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + else: + self._global_port_pres_dict[port_num] = '0' + + def mod_pres(self): + port_pres_mask =0 + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + port_val = (1 << (port_num -1)) + port_pres_mask = (port_pres_mask | port_val) + else: + self._global_port_pres_dict[port_num] = '0' + port_val = ~(1 << (port_num -1)) + port_pres_mask = (port_pres_mask & port_val) + + return port_pres_mask + + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for x in range(self.port_start, self.port_end + 1): + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x]) + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4004 + port_offset = 16388 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + mask = (1 << 4) + + # Mask off 1st bit for presence 33,34 + if (port_num > 32): + mask = (1 << 0) + + # ModPrsL is active low + if reg_value & mask == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high + if reg_value & mask == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + def reset(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + # Sleep 1 second to allow it to settle + time.sleep(1) + + reg_value = reg_value | mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + def get_register(self, reg_file): + retval = 'ERR' + if (not path.isfile(reg_file)): + print reg_file, 'not found !' + return retval + + try: + with fdopen(open(reg_file, O_RDONLY)) as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", reg_file, "file !") + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + def get_transceiver_change_event(self): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) + + diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 8cbf72695920..7436fef0ef1b 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -9,6 +9,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(DELL_Z9264F_PLATFORM_MODULE) \ $(DELL_S5232F_PLATFORM_MODULE) \ $(DELL_S5248F_PLATFORM_MODULE) \ + $(DELL_Z9332F_PLATFORM_MODULE) \ $(DELL_Z9100_PLATFORM_MODULE) \ $(DELL_S6100_PLATFORM_MODULE) \ $(INGRASYS_S8900_54XC_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-dell.mk b/platform/broadcom/platform-modules-dell.mk index 583f74f72d8b..298e3c4f7396 100644 --- a/platform/broadcom/platform-modules-dell.mk +++ b/platform/broadcom/platform-modules-dell.mk @@ -1,10 +1,11 @@ -# Dell S6000,Z9100, S6100, Z9264F , S5232 Platform modules +# Dell S6000,Z9100, S6100, Z9264F , S5232F,Z9332F Platform modules DELL_S6000_PLATFORM_MODULE_VERSION = 1.1 DELL_Z9100_PLATFORM_MODULE_VERSION = 1.1 DELL_S6100_PLATFORM_MODULE_VERSION = 1.1 DELL_Z9264F_PLATFORM_MODULE_VERSION = 1.1 DELL_S5232F_PLATFORM_MODULE_VERSION = 1.1 +DELL_Z9332F_PLATFORM_MODULE_VERSION = 1.1 DELL_S5248F_PLATFORM_MODULE_VERSION = 1.1 export DELL_S6000_PLATFORM_MODULE_VERSION @@ -12,6 +13,7 @@ export DELL_Z9100_PLATFORM_MODULE_VERSION export DELL_S6100_PLATFORM_MODULE_VERSION export DELL_Z9264F_PLATFORM_MODULE_VERSION export DELL_S5232F_PLATFORM_MODULE_VERSION +export DELL_Z9332F_PLATFORM_MODULE_VERSION export DELL_S5248F_PLATFORM_MODULE_VERSION DELL_Z9100_PLATFORM_MODULE = platform-modules-z9100_$(DELL_Z9100_PLATFORM_MODULE_VERSION)_amd64.deb @@ -37,6 +39,10 @@ DELL_S5232F_PLATFORM_MODULE = platform-modules-s5232f_$(DELL_S5232F_PLATFORM_MOD $(DELL_S5232F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5232f_c3538-r0 $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5232F_PLATFORM_MODULE))) +DELL_Z9332F_PLATFORM_MODULE = platform-modules-z9332f_$(DELL_Z9332F_PLATFORM_MODULE_VERSION)_amd64.deb +$(DELL_Z9332F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_z9332f_d1508-r0 +$(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_Z9332F_PLATFORM_MODULE))) + DELL_S5248F_PLATFORM_MODULE = platform-modules-s5248f_$(DELL_S5248F_PLATFORM_MODULE_VERSION)_amd64.deb $(DELL_S5248F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5248f_c3538-r0 $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5248F_PLATFORM_MODULE))) diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index f32fa7244acc..3131890e6353 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -34,3 +34,8 @@ Package: platform-modules-s5248f Architecture: amd64 Depends: linux-image-4.9.0-9-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-z9332f +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.init b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.init new file mode 100644 index 000000000000..f4fe9eb396fd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.init @@ -0,0 +1,39 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup Z9332f board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + /usr/local/bin/z9332f_platform.sh init + + echo "done." + ;; + +stop) + /usr/local/bin/z9332f_platform.sh deinit + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-z9332f.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install new file mode 100644 index 000000000000..16d2b952186f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install @@ -0,0 +1,7 @@ +z9332f/scripts/z9332f_platform.sh usr/local/bin +z9332f/scripts/platform_sensors.py usr/local/bin +z9332f/scripts/sensors usr/bin +z9332f/scripts/pcisysfs.py usr/bin +z9332f/cfg/z9332f-modules.conf etc/modules-load.d +z9332f/systemd/platform-modules-z9332f.service etc/systemd/system +common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.postinst new file mode 100644 index 000000000000..3a3a72cb304a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.postinst @@ -0,0 +1,10 @@ +# postinst script for Z9332f + +# Enable Dell-Z9332f-platform-service +depmod -a +systemctl enable platform-modules-z9332f.service +systemctl start platform-modules-z9332f.service + + +#DEBHELPER# + diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index a7f68a21f55a..8af0642b40d3 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f +MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f z9332f COMMON_DIR := common %: diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/cfg/z9332f-modules.conf b/platform/broadcom/sonic-platform-modules-dell/z9332f/cfg/z9332f-modules.conf new file mode 100644 index 000000000000..b6d4fe4fb00a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/cfg/z9332f-modules.conf @@ -0,0 +1,17 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x + +ipmi_devintf +ipmi_si diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile new file mode 100644 index 000000000000..bb71bb0d9185 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile @@ -0,0 +1,4 @@ +obj-m += cls-switchboard.o +obj-m += cls-i2c-ocore.o +obj-m += mc24lc64t.o + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c new file mode 100644 index 000000000000..c80757e6619d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c @@ -0,0 +1,845 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * cls-i2c-ocores.c: I2C bus driver for OpenCores I2C controller + * (https://opencores.org/project/i2c/overview) + * + * Peter Korsgaard + * + * Support for the GRLIB port of the controller by + * Andreas Larsson + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#include +#include +#include +#include +#include +#include "cls-i2c-ocore.h" + +#define OCORES_FLAG_POLL BIT(0) + +/* + * 'process_lock' exists because ocores_process() and ocores_process_timeout() + * can't run in parallel. + */ +struct ocores_i2c { + void __iomem *base; + int iobase; + u32 reg_shift; + u32 reg_io_width; + unsigned long flags; + wait_queue_head_t wait; + struct i2c_adapter adap; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; /* see STATE_ */ + int nack_retry; + spinlock_t process_lock; + struct clk *clk; + int ip_clock_khz; + int bus_clock_khz; + void (*setreg)(struct ocores_i2c *i2c, int reg, u8 value); + u8 (*getreg)(struct ocores_i2c *i2c, int reg); +}; + +/* registers */ +#define OCI2C_PRELOW 0 +#define OCI2C_PREHIGH 1 +#define OCI2C_CONTROL 2 +#define OCI2C_DATA 3 +#define OCI2C_CMD 4 /* write only */ +#define OCI2C_STATUS 4 /* read only, same address as OCI2C_CMD */ + +#define OCI2C_CTRL_IEN 0x40 +#define OCI2C_CTRL_EN 0x80 + +#define OCI2C_CMD_START 0x91 +#define OCI2C_CMD_STOP 0x41 +#define OCI2C_CMD_READ 0x21 +#define OCI2C_CMD_WRITE 0x11 +#define OCI2C_CMD_READ_ACK 0x21 +#define OCI2C_CMD_READ_NACK 0x29 +#define OCI2C_CMD_IACK 0x01 + +#define OCI2C_STAT_IF 0x01 +#define OCI2C_STAT_TIP 0x02 +#define OCI2C_STAT_ARBLOST 0x20 +#define OCI2C_STAT_BUSY 0x40 +#define OCI2C_STAT_NACK 0x80 + +#define STATE_DONE 0 +#define STATE_START 1 +#define STATE_WRITE 2 +#define STATE_READ 3 +#define STATE_ERROR 4 + +#define TYPE_OCORES 0 +#define TYPE_GRLIB 1 + +static void oc_setreg_8(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite8(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_16(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite16(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_32(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite32(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_16be(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_32be(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_8(struct ocores_i2c *i2c, int reg) +{ + return ioread8(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_16(struct ocores_i2c *i2c, int reg) +{ + return ioread16(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_32(struct ocores_i2c *i2c, int reg) +{ + return ioread32(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_16be(struct ocores_i2c *i2c, int reg) +{ + return ioread16be(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_32be(struct ocores_i2c *i2c, int reg) +{ + return ioread32be(i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_io_8(struct ocores_i2c *i2c, int reg, u8 value) +{ + outb(value, i2c->iobase + reg); +} + +static inline u8 oc_getreg_io_8(struct ocores_i2c *i2c, int reg) +{ + return inb(i2c->iobase + reg); +} + +static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) +{ + i2c->setreg(i2c, reg, value); +} + +static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) +{ + return i2c->getreg(i2c, reg); +} + +static void ocores_process(struct ocores_i2c *i2c, u8 stat) +{ + struct i2c_msg *msg = i2c->msg; + unsigned long flags; + + /* + * If we spin here is because we are in timeout, so we are going + * to be in STATE_ERROR. See ocores_process_timeout() + */ + spin_lock_irqsave(&i2c->process_lock, flags); + + dev_dbg(&i2c->adap.dev, "STATE: %d\n", i2c->state); + + if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { + /* stop has been sent */ + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + wake_up(&i2c->wait); + goto out; + } + + /* error? */ + if (stat & OCI2C_STAT_ARBLOST) { + // i2c->state = STATE_ERROR; + i2c->state = STATE_START; + // i2c->nack_retry = 1; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + dev_dbg(&i2c->adap.dev, "ERR: AL\n"); + goto out; + } + + if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { + i2c->state = + (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & OCI2C_STAT_NACK) { + dev_dbg(&i2c->adap.dev, "ERR: NACK\n"); + // printk(KERN_INFO "ERR: NACK\n"); + i2c->state = STATE_ERROR; + if(!(msg->flags & I2C_M_RD)) + i2c->nack_retry = 1; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + goto out; + } + } else { + msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); + } + + /* end of msg? */ + if (i2c->pos == msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { /* end? */ + /* send start? */ + if (!(msg->flags & I2C_M_NOSTART)) { + u8 addr = i2c_8bit_addr_from_msg(msg); + + i2c->state = STATE_START; + + oc_setreg(i2c, OCI2C_DATA, addr); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + goto out; + } + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } else { + i2c->state = STATE_DONE; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + goto out; + } + } + + if (i2c->state == STATE_READ) { + oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ? + OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK); + } else { + oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); + } + +out: + spin_unlock_irqrestore(&i2c->process_lock, flags); +} + +static irqreturn_t ocores_isr(int irq, void *dev_id) +{ + struct ocores_i2c *i2c = dev_id; + u8 stat = oc_getreg(i2c, OCI2C_STATUS); + + dev_dbg(&i2c->adap.dev, "STATUS: 0x%x\n", stat); + // printk(KERN_INFO "STATUS: 0x%x\n", stat); + + if (!(stat & OCI2C_STAT_IF)) + return IRQ_NONE; + + ocores_process(i2c, stat); + + return IRQ_HANDLED; +} + +/** + * Process timeout event + * @i2c: ocores I2C device instance + */ +static void ocores_process_timeout(struct ocores_i2c *i2c) +{ + unsigned long flags; + + spin_lock_irqsave(&i2c->process_lock, flags); + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + spin_unlock_irqrestore(&i2c->process_lock, flags); +} + +/** + * Wait until something change in a given register + * @i2c: ocores I2C device instance + * @reg: register to query + * @mask: bitmask to apply on register value + * @val: expected result + * @timeout: timeout in jiffies + * + * Timeout is necessary to avoid to stay here forever when the chip + * does not answer correctly. + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int ocores_wait(struct ocores_i2c *i2c, + int reg, u8 mask, u8 val, + const unsigned long timeout) +{ + unsigned long j; + + j = jiffies + timeout; + while (1) { + u8 status = oc_getreg(i2c, reg); + + if ((status & mask) == val) + break; + + if (time_after(jiffies, j)) + return -ETIMEDOUT; + cpu_relax(); + cond_resched(); + } + return 0; +} + +/** + * Wait until is possible to process some data + * @i2c: ocores I2C device instance + * + * Used when the device is in polling mode (interrupts disabled). + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int ocores_poll_wait(struct ocores_i2c *i2c) +{ + u8 mask; + int err; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* transfer is over */ + mask = OCI2C_STAT_BUSY; + } else { + /* on going transfer */ + mask = OCI2C_STAT_TIP; + /* + * We wait for the data to be transferred (8bit), + * then we start polling on the ACK/NACK bit + */ + udelay((8 * 1000) / i2c->bus_clock_khz); + } + + dev_dbg(&i2c->adap.dev, "Wait for: 0x%x\n", mask); + // printk(KERN_INFO "Wait for: 0x%x\n", mask); + + /* + * once we are here we expect to get the expected result immediately + * so if after 1ms we timeout then something is broken. + */ + err = ocores_wait(i2c, OCI2C_STATUS, mask, 0, msecs_to_jiffies(30)); + if (err) + dev_warn(i2c->adap.dev.parent, + "%s: STATUS timeout, bit 0x%x did not clear in 1ms\n", + __func__, mask); + return err; +} + +/** + * It handles an IRQ-less transfer + * @i2c: ocores I2C device instance + * + * Even if IRQ are disabled, the I2C OpenCore IP behavior is exactly the same + * (only that IRQ are not produced). This means that we can re-use entirely + * ocores_isr(), we just add our polling code around it. + * + * It can run in atomic context + */ +static void ocores_process_polling(struct ocores_i2c *i2c) +{ + while (1) { + irqreturn_t ret; + int err; + + err = ocores_poll_wait(i2c); + if (err) { + i2c->state = STATE_ERROR; + break; /* timeout */ + } + + ret = ocores_isr(-1, i2c); + if (ret == IRQ_NONE) + break; /* all messages have been transferred */ + } +} + +static int ocores_xfer_core(struct ocores_i2c *i2c, + struct i2c_msg *msgs, int num, + bool polling) +{ + int ret; + u8 ctrl; + + ctrl = oc_getreg(i2c, OCI2C_CONTROL); + if (polling) + oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~OCI2C_CTRL_IEN); + else + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN); + + i2c->msg = msgs; + i2c->pos = 0; + i2c->nmsgs = num; + i2c->state = STATE_START; + + dev_dbg(&i2c->adap.dev, "STATE: %d\n", i2c->state); + // printk(KERN_INFO "STATE: %d\n", i2c->state); + + oc_setreg(i2c, OCI2C_DATA, i2c_8bit_addr_from_msg(i2c->msg)); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + + if (polling) { + ocores_process_polling(i2c); + } else { + ret = wait_event_timeout(i2c->wait, + (i2c->state == STATE_ERROR) || + (i2c->state == STATE_DONE), HZ); + if (ret == 0) { + ocores_process_timeout(i2c); + return -ETIMEDOUT; + } + } + + return (i2c->state == STATE_DONE) ? num : -EIO; +} + +static int ocores_xfer_polling(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + return ocores_xfer_core(i2c_get_adapdata(adap), msgs, num, true); +} + +static int ocores_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + int ret; + int retry=0; + int max_retry = 0; + struct ocores_i2c *i2c = i2c_get_adapdata(adap); + + i2c->nack_retry = 0; + + if (i2c->flags & OCORES_FLAG_POLL) + { + //return ocores_xfer_polling(adap, msgs, num); + ret = ocores_xfer_polling(adap, msgs, num); + // Fix i2cdetect issue + if(num == 1) + max_retry = 5; + else + max_retry = 5; + + while((i2c->nack_retry == 1)&&(retry < max_retry)) + { + retry++; + i2c->nack_retry = 0; + ret = ocores_xfer_polling(adap, msgs, num); + // printk("nack retry polling = %d\n",retry); + } + // if(i2c->nack_retry!=0){ + // printk("nack retry = %d, ret=%d\n",retry, ret); + // } + i2c->nack_retry = 0; + return ret; + } + return ocores_xfer_core(i2c, msgs, num, false); +} + +static int ocores_init(struct device *dev, struct ocores_i2c *i2c) +{ + int prescale; + int diff; + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* make sure the device is disabled */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); + + dev_info(dev, "Prescale: %d\n", prescale); + + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + dev_err(dev, + "Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } + + oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); + oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); + + /* Init the device */ + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); + + return 0; +} + + +static u32 ocores_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm ocores_algorithm = { + .master_xfer = ocores_xfer, + .functionality = ocores_func, +}; + +static const struct i2c_adapter ocores_adapter = { + .owner = THIS_MODULE, + .name = "i2c-goodcores", + .class = I2C_CLASS_DEPRECATED, + .algo = &ocores_algorithm, +}; + +static const struct of_device_id ocores_i2c_match[] = { + { + .compatible = "opencores,i2c-ocores", + .data = (void *)TYPE_OCORES, + }, + { + .compatible = "aeroflexgaisler,i2cmst", + .data = (void *)TYPE_GRLIB, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, ocores_i2c_match); + +#ifdef CONFIG_OF +/* + * Read and write functions for the GRLIB port of the controller. Registers are + * 32-bit big endian and the PRELOW and PREHIGH registers are merged into one + * register. The subsequent registers have their offsets decreased accordingly. + */ +static u8 oc_getreg_grlib(struct ocores_i2c *i2c, int reg) +{ + u32 rd; + int rreg = reg; + + if (reg != OCI2C_PRELOW) + rreg--; + rd = ioread32be(i2c->base + (rreg << i2c->reg_shift)); + if (reg == OCI2C_PREHIGH) + return (u8)(rd >> 8); + else + return (u8)rd; +} + +static void oc_setreg_grlib(struct ocores_i2c *i2c, int reg, u8 value) +{ + u32 curr, wr; + int rreg = reg; + + if (reg != OCI2C_PRELOW) + rreg--; + if (reg == OCI2C_PRELOW || reg == OCI2C_PREHIGH) { + curr = ioread32be(i2c->base + (rreg << i2c->reg_shift)); + if (reg == OCI2C_PRELOW) + wr = (curr & 0xff00) | value; + else + wr = (((u32)value) << 8) | (curr & 0xff); + } else { + wr = value; + } + iowrite32be(wr, i2c->base + (rreg << i2c->reg_shift)); +} + +static int ocores_i2c_of_probe(struct platform_device *pdev, + struct ocores_i2c *i2c) +{ + struct device_node *np = pdev->dev.of_node; + const struct of_device_id *match; + u32 val; + u32 clock_frequency; + bool clock_frequency_present; + + if (of_property_read_u32(np, "reg-shift", &i2c->reg_shift)) { + /* no 'reg-shift', check for deprecated 'regstep' */ + if (!of_property_read_u32(np, "regstep", &val)) { + if (!is_power_of_2(val)) { + dev_err(&pdev->dev, "invalid regstep %d\n", + val); + return -EINVAL; + } + i2c->reg_shift = ilog2(val); + dev_warn(&pdev->dev, + "regstep property deprecated, use reg-shift\n"); + } + } + + clock_frequency_present = !of_property_read_u32(np, "clock-frequency", + &clock_frequency); + i2c->bus_clock_khz = 100; + + i2c->clk = devm_clk_get(&pdev->dev, NULL); + + if (!IS_ERR(i2c->clk)) { + int ret = clk_prepare_enable(i2c->clk); + + if (ret) { + dev_err(&pdev->dev, + "clk_prepare_enable failed: %d\n", ret); + return ret; + } + i2c->ip_clock_khz = clk_get_rate(i2c->clk) / 1000; + if (clock_frequency_present) + i2c->bus_clock_khz = clock_frequency / 1000; + } + + if (i2c->ip_clock_khz == 0) { + if (of_property_read_u32(np, "opencores,ip-clock-frequency", + &val)) { + if (!clock_frequency_present) { + dev_err(&pdev->dev, + "Missing required parameter 'opencores,ip-clock-frequency'\n"); + clk_disable_unprepare(i2c->clk); + return -ENODEV; + } + i2c->ip_clock_khz = clock_frequency / 1000; + dev_warn(&pdev->dev, + "Deprecated usage of the 'clock-frequency' property, please update to 'opencores,ip-clock-frequency'\n"); + } else { + i2c->ip_clock_khz = val / 1000; + if (clock_frequency_present) + i2c->bus_clock_khz = clock_frequency / 1000; + } + } + + of_property_read_u32(pdev->dev.of_node, "reg-io-width", + &i2c->reg_io_width); + + match = of_match_node(ocores_i2c_match, pdev->dev.of_node); + if (match && (long)match->data == TYPE_GRLIB) { + dev_dbg(&pdev->dev, "GRLIB variant of i2c-ocores\n"); + // printk(KERN_INFO "GRLIB variant of i2c-ocores\n"); + i2c->setreg = oc_setreg_grlib; + i2c->getreg = oc_getreg_grlib; + } + + return 0; +} +#else +#define ocores_i2c_of_probe(pdev, i2c) -ENODEV +#endif + +static int ocores_i2c_probe(struct platform_device *pdev) +{ + struct ocores_i2c *i2c; + struct ocores_i2c_platform_data *pdata; + struct resource *res; + int irq; + int ret; + int i; + + i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); + if (!i2c) + return -ENOMEM; + + spin_lock_init(&i2c->process_lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) { + i2c->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(i2c->base)) + return PTR_ERR(i2c->base); + } else { + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (!res) + return -EINVAL; + i2c->iobase = res->start; + if (!devm_request_region(&pdev->dev, res->start, + resource_size(res), + pdev->name)) { + dev_err(&pdev->dev, "Can't get I/O resource.\n"); + return -EBUSY; + } + i2c->setreg = oc_setreg_io_8; + i2c->getreg = oc_getreg_io_8; + } + + pdata = dev_get_platdata(&pdev->dev); + if (pdata) { + i2c->reg_shift = pdata->reg_shift; + i2c->reg_io_width = pdata->reg_io_width; + i2c->ip_clock_khz = pdata->clock_khz; + if (pdata->bus_khz) + i2c->bus_clock_khz = pdata->bus_khz; + else + i2c->bus_clock_khz = 100; + } else { + ret = ocores_i2c_of_probe(pdev, i2c); + if (ret) + return ret; + } + + if (i2c->reg_io_width == 0) + i2c->reg_io_width = 1; /* Set to default value */ + + if (!i2c->setreg || !i2c->getreg) { + bool be = pdata ? pdata->big_endian : + of_device_is_big_endian(pdev->dev.of_node); + + switch (i2c->reg_io_width) { + case 1: + i2c->setreg = oc_setreg_8; + i2c->getreg = oc_getreg_8; + break; + + case 2: + i2c->setreg = be ? oc_setreg_16be : oc_setreg_16; + i2c->getreg = be ? oc_getreg_16be : oc_getreg_16; + break; + + case 4: + i2c->setreg = be ? oc_setreg_32be : oc_setreg_32; + i2c->getreg = be ? oc_getreg_32be : oc_getreg_32; + break; + + default: + dev_err(&pdev->dev, "Unsupported I/O width (%d)\n", + i2c->reg_io_width); + ret = -EINVAL; + goto err_clk; + } + } + + init_waitqueue_head(&i2c->wait); + + irq = platform_get_irq(pdev, 0); + if (irq == -ENXIO) { + i2c->flags |= OCORES_FLAG_POLL; + } else { + if (irq < 0) + return irq; + } + + if (!(i2c->flags & OCORES_FLAG_POLL)) { + ret = devm_request_irq(&pdev->dev, irq, ocores_isr, 0, + pdev->name, i2c); + if (ret) { + dev_err(&pdev->dev, "Cannot claim IRQ\n"); + goto err_clk; + } + } + + ret = ocores_init(&pdev->dev, i2c); + if (ret) + goto err_clk; + + /* hook up driver to tree */ + platform_set_drvdata(pdev, i2c); + i2c->adap = ocores_adapter; + i2c_set_adapdata(&i2c->adap, i2c); + i2c->adap.dev.parent = &pdev->dev; + i2c->adap.dev.of_node = pdev->dev.of_node; + + /* add i2c adapter to i2c tree */ + ret = i2c_add_adapter(&i2c->adap); + if (ret) + goto err_clk; + + /* add in known devices to the bus */ + if (pdata) { + for (i = 0; i < pdata->num_devices; i++) + i2c_new_device(&i2c->adap, pdata->devices + i); + } + + return 0; + +err_clk: + clk_disable_unprepare(i2c->clk); + return ret; +} + +static int ocores_i2c_remove(struct platform_device *pdev) +{ + struct ocores_i2c *i2c = platform_get_drvdata(pdev); + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* disable i2c logic */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + /* remove adapter & data */ + i2c_del_adapter(&i2c->adap); + + if (!IS_ERR(i2c->clk)) + clk_disable_unprepare(i2c->clk); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int ocores_i2c_suspend(struct device *dev) +{ + struct ocores_i2c *i2c = dev_get_drvdata(dev); + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* make sure the device is disabled */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + if (!IS_ERR(i2c->clk)) + clk_disable_unprepare(i2c->clk); + return 0; +} + +static int ocores_i2c_resume(struct device *dev) +{ + struct ocores_i2c *i2c = dev_get_drvdata(dev); + + if (!IS_ERR(i2c->clk)) { + unsigned long rate; + int ret = clk_prepare_enable(i2c->clk); + + if (ret) { + dev_err(dev, + "clk_prepare_enable failed: %d\n", ret); + return ret; + } + rate = clk_get_rate(i2c->clk) / 1000; + if (rate) + i2c->ip_clock_khz = rate; + } + return ocores_init(dev, i2c); +} + +static SIMPLE_DEV_PM_OPS(ocores_i2c_pm, ocores_i2c_suspend, ocores_i2c_resume); +#define OCORES_I2C_PM (&ocores_i2c_pm) +#else +#define OCORES_I2C_PM NULL +#endif + +static struct platform_driver ocores_i2c_driver = { + .probe = ocores_i2c_probe, + .remove = ocores_i2c_remove, + .driver = { + .name = "goodcores-i2c", + .of_match_table = ocores_i2c_match, + .pm = OCORES_I2C_PM, + }, +}; + +module_platform_driver(ocores_i2c_driver); + +MODULE_AUTHOR("Peter Korsgaard "); +MODULE_DESCRIPTION("OpenCores I2C bus driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ocores-i2c"); diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.h b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.h new file mode 100644 index 000000000000..bc2a53cd6832 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * cls-i2c-ocores.h - definitions for the i2c-ocores interface + * + * Peter Korsgaard + */ + +#ifndef _LINUX_I2C_OCORES_H +#define _LINUX_I2C_OCORES_H + +struct ocores_i2c_platform_data { + u32 reg_shift; /* register offset shift value */ + u32 reg_io_width; /* register io read/write width */ + u32 clock_khz; /* input clock in kHz */ + u32 bus_khz; /* bus clock in kHz */ + bool big_endian; /* registers are big endian */ + u8 num_devices; /* number of devices in the devices list */ + struct i2c_board_info const *devices; /* devices connected to the bus */ +}; + +#endif /* _LINUX_I2C_OCORES_H */ + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c new file mode 100644 index 000000000000..240580e577a3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c @@ -0,0 +1,447 @@ +/* + * cls_switchboard.c - PCI device driver for Silverstone Switch board FPGA. + * + * Author: Pradchaya Phucharoen + * + * Copyright (C) 2019 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cls-i2c-ocore.h" + +#define MOD_VERSION "2.1.0-1" +#define DRV_NAME "cls-switchboard" + +#define I2C_MUX_CHANNEL(_ch, _adap_id, _deselect) \ + [_ch] = { .adap_id = _adap_id, .deselect_on_exit = _deselect } + +#define FPGA_PCIE_DEVICE_ID 0x7021 +#define MMIO_BAR 0 +#define I2C_BUS_OFS 9 + +/* I2C ocore configurations */ +#define OCORE_REGSHIFT 2 +#define OCORE_IP_CLK_khz 62500 //TODO: check fpga's `wb_clk_i` +#define OCORE_BUS_CLK_khz 100 +#define OCORE_REG_IO_WIDTH 1 + +/* Optical port xcvr configuration */ +#define XCVR_REG_SHIFT 2 +#define XCVR_NUM_PORT 34 +#define XCVR_PORT_REG_SIZE 0x10 + +/* i2c_bus_config - an i2c-core resource and platform data + * @id - I2C bus device ID, for identification. + * @res - resources for an i2c-core device. + * @num_res - size of the resources. + * @pdata - a platform data of an i2c-core device. + */ +struct i2c_bus_config { + int id; + struct resource *res; + ssize_t num_res; + struct ocores_i2c_platform_data pdata; +}; + +/* switchbrd_priv - switchboard private data */ +struct switchbrd_priv { + unsigned long base; + int num_i2c_bus; + struct platform_device **i2cbuses_pdev; + struct platform_device *regio_pdev; + struct platform_device *spiflash_pdev; + //struct platform_device *xcvr_pdev; +}; + + +// NOTE: Silverstone i2c channel mapping is very wierd!!! +/* PCA9548 channel config on MASTER BUS 3 */ +static struct pca954x_platform_mode i2c_mux_70_modes[] = { + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 23, true), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 26, true), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 27, true), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 28, true), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 29, true), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 30, true), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 31, true), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 32, true), +}; + +static struct pca954x_platform_mode i2c_mux_71_modes[] = { + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 1, true), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 2, true), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 3, true), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 4, true), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 5, true), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 6, true), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 15, true), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 8, true), +}; + +static struct pca954x_platform_mode i2c_mux_72_modes[] = { + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 17, true), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 18, true), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 19, true), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 20, true), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 21, true), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 22, true), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 25, true), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 24, true), +}; + +static struct pca954x_platform_mode i2c_mux_73_modes[] = { + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 9, true), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 10, true), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 11, true), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 12, true), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 13, true), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 14, true), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 7, true), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 16, true), +}; + +static struct pca954x_platform_data om_muxes[] = { + { + .modes = i2c_mux_70_modes, + .num_modes = ARRAY_SIZE(i2c_mux_70_modes), + }, + { + .modes = i2c_mux_71_modes, + .num_modes = ARRAY_SIZE(i2c_mux_71_modes), + }, + { + .modes = i2c_mux_72_modes, + .num_modes = ARRAY_SIZE(i2c_mux_72_modes), + }, + { + .modes = i2c_mux_73_modes, + .num_modes = ARRAY_SIZE(i2c_mux_73_modes), + }, +}; + +/* Optical Module bus 3 i2c muxes info */ +static struct i2c_board_info i2c_info_3[] = { + { + I2C_BOARD_INFO("pca9548", 0x70), + .platform_data = &om_muxes[0], + }, + { + I2C_BOARD_INFO("pca9548", 0x71), + .platform_data = &om_muxes[1], + }, + { + I2C_BOARD_INFO("pca9548", 0x72), + .platform_data = &om_muxes[2], + }, + { + I2C_BOARD_INFO("pca9548", 0x73), + .platform_data = &om_muxes[3], + }, +}; + +/* RESOURCE SEPERATES BY FUNCTION */ +/* Resource IOMEM for i2c bus 1 */ +static struct resource cls_i2c_res_1[] = { + { + .start = 0x800, .end = 0x81F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 2 */ +static struct resource cls_i2c_res_2[] = { + { + .start = 0x820, .end = 0x83F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 3 */ +static struct resource cls_i2c_res_3[] = { + { + .start = 0x840, .end = 0x85F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 4 */ +static struct resource cls_i2c_res_4[] = { + { + .start = 0x860, .end = 0x87F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 5 */ +static struct resource cls_i2c_res_5[] = { + { + .start = 0x880, .end = 0x89F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for reg access */ +static struct resource reg_io_res[] = { + { + .start = 0x00, .end = 0xFF, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for spi flash firmware upgrade */ +static struct resource spi_flash_res[] = { + { + .start = 0x1200, .end = 0x121F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for front panel XCVR */ +// static struct resource xcvr_res[] = { +// { +// .start = 0x4000, .end = 0x421F, +// .flags = IORESOURCE_MEM,}, +// }; + +static struct i2c_bus_config i2c_bus_configs[] = { + { + .id = 1, + .res = cls_i2c_res_1, + .num_res = ARRAY_SIZE(cls_i2c_res_1), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, + { + .id = 2, + .res = cls_i2c_res_2, + .num_res = ARRAY_SIZE(cls_i2c_res_2), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, + { + .id = 3, + .res = cls_i2c_res_3, + .num_res = ARRAY_SIZE(cls_i2c_res_3), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = ARRAY_SIZE(i2c_info_3), + .devices = i2c_info_3, + }, + }, + { + .id = 4, + .res = cls_i2c_res_4, + .num_res = ARRAY_SIZE(cls_i2c_res_4), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, + { + .id = 5, + .res = cls_i2c_res_5, + .num_res = ARRAY_SIZE(cls_i2c_res_5), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, +}; + +// TODO: Add a platform configuration struct, and use probe as a factory, +// so xcvr, fwupgrade device can configured as options. + +static int cls_fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + + struct switchbrd_priv *priv; + struct platform_device **i2cbuses_pdev; + struct platform_device *regio_pdev; + struct platform_device *spiflash_pdev; + //struct platform_device *xcvr_pdev; + unsigned long rstart; + int num_i2c_bus, i; + int err; + + err = pci_enable_device(dev); + if (err){ + dev_err(&dev->dev, "Failed to enable PCI device\n"); + goto err_exit; + } + + /* Check for valid MMIO address */ + rstart = pci_resource_start(dev, MMIO_BAR); + if (!rstart) { + dev_err(&dev->dev, "Switchboard base address uninitialized, " + "check FPGA\n"); + err = -ENODEV; + goto err_disable_device; + } + + dev_dbg(&dev->dev, "BAR%d res: 0x%lx-0x%llx\n", MMIO_BAR, + rstart, pci_resource_end(dev, MMIO_BAR)); + + priv = devm_kzalloc(&dev->dev, + sizeof(struct switchbrd_priv), GFP_KERNEL); + if (!priv){ + err = -ENOMEM; + goto err_disable_device; + } + + pci_set_drvdata(dev, priv); + num_i2c_bus = ARRAY_SIZE(i2c_bus_configs); + i2cbuses_pdev = devm_kzalloc( + &dev->dev, + num_i2c_bus * sizeof(struct platform_device*), + GFP_KERNEL); + + reg_io_res[0].start += rstart; + reg_io_res[0].end += rstart; + + spi_flash_res[0].start += rstart; + spi_flash_res[0].end += rstart; + + regio_pdev = platform_device_register_resndata( + &dev->dev, "cls-swbrd-io", + -1, + reg_io_res, ARRAY_SIZE(reg_io_res), + NULL, 0); + + if (IS_ERR(regio_pdev)) { + dev_err(&dev->dev, "Failed to register cls-swbrd-io\n"); + err = PTR_ERR(regio_pdev); + goto err_disable_device; + } + + spiflash_pdev = platform_device_register_resndata( + &dev->dev, "cls-swbrd-fwug", + -1, + spi_flash_res, ARRAY_SIZE(spi_flash_res), + NULL, 0); + + if (IS_ERR(spiflash_pdev)) { + dev_err(&dev->dev, "Failed to register firmware upgrade node\n"); + err = PTR_ERR(spiflash_pdev); + goto err_unregister_regio; + } + + for(i = 0; i < num_i2c_bus; i++){ + + i2c_bus_configs[i].res[0].start += rstart; + i2c_bus_configs[i].res[0].end += rstart; + + dev_dbg(&dev->dev, "i2c-bus.%d: 0x%llx - 0x%llx\n", + i2c_bus_configs[i].id, + i2c_bus_configs[i].res[0].start, + i2c_bus_configs[i].res[0].end); + + i2cbuses_pdev[i] = platform_device_register_resndata( + &dev->dev, "goodcores-i2c", + i2c_bus_configs[i].id, + i2c_bus_configs[i].res, + i2c_bus_configs[i].num_res, + &i2c_bus_configs[i].pdata, + sizeof(i2c_bus_configs[i].pdata)); + + if (IS_ERR(i2cbuses_pdev[i])) { + dev_err(&dev->dev, "Failed to register goodcores-i2c.%d\n", + i2c_bus_configs[i].id); + err = PTR_ERR(i2cbuses_pdev[i]); + goto err_unregister_ocore; + } + } + + priv->base = rstart; + priv->num_i2c_bus = num_i2c_bus; + priv->i2cbuses_pdev = i2cbuses_pdev; + priv->regio_pdev = regio_pdev; + priv->spiflash_pdev = spiflash_pdev; + return 0; + +err_unregister_ocore: + for(i = 0; i < num_i2c_bus; i++){ + if(priv->i2cbuses_pdev[i]){ + platform_device_unregister(priv->i2cbuses_pdev[i]); + } + } +// err_unregister_spiflash: +// platform_device_unregister(spiflash_pdev); +err_unregister_regio: + platform_device_unregister(regio_pdev); +err_disable_device: + pci_disable_device(dev); +err_exit: + return err; +} + +static void cls_fpga_remove(struct pci_dev *dev) +{ + int i; + struct switchbrd_priv *priv = pci_get_drvdata(dev); + + for(i = 0; i < priv->num_i2c_bus; i++){ + if(priv->i2cbuses_pdev[i]) + platform_device_unregister(priv->i2cbuses_pdev[i]); + } + platform_device_unregister(priv->spiflash_pdev); + platform_device_unregister(priv->regio_pdev); + pci_disable_device(dev); + return; +}; + +static const struct pci_device_id pci_clsswbrd[] = { + { PCI_VDEVICE(XILINX, FPGA_PCIE_DEVICE_ID) }, + {0, } +}; + +MODULE_DEVICE_TABLE(pci, pci_clsswbrd); + +static struct pci_driver clsswbrd_pci_driver = { + .name = DRV_NAME, + .id_table = pci_clsswbrd, + .probe = cls_fpga_probe, + .remove = cls_fpga_remove, +}; + +module_pci_driver(clsswbrd_pci_driver); + +MODULE_AUTHOR("Pradchaya P."); +MODULE_DESCRIPTION("Celestica Silverstone switchboard driver"); +MODULE_VERSION(MOD_VERSION); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c new file mode 100644 index 000000000000..a391056d09a7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c @@ -0,0 +1,142 @@ +/* + * mc24lc64t.c - driver for Microchip 24LC64T + * + * Copyright (C) 2017 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct mc24lc64t_data { + struct i2c_client *fake_client; + struct mutex update_lock; +}; + +static ssize_t mc24lc64t_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, read_time, i = 0; + int status; + + mutex_lock(&drvdata->update_lock); + + if (i2c_smbus_write_byte_data(client, off>>8, off)) + { + status = -EIO; + goto exit; + } + + msleep(1); + +begin: + + if (i < count) + { + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + do { + read_time = jiffies; + + status = i2c_smbus_read_byte(client); + if (status >= 0) + { + buf[i++] = status; + goto begin; + } + } while (time_before(read_time, timeout)); + + status = -ETIMEDOUT; + goto exit; + } + + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + + return status; +} + +static struct bin_attribute mc24lc64t_bit_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = 65536, + .read = mc24lc64t_read, +}; + +static int mc24lc64t_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct mc24lc64t_data *drvdata; + int err; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA + | I2C_FUNC_SMBUS_READ_BYTE)) + return -EPFNOSUPPORT; + + if (!(drvdata = devm_kzalloc(&client->dev, + sizeof(struct mc24lc64t_data), GFP_KERNEL))) + return -ENOMEM; + + drvdata->fake_client = i2c_new_dummy(client->adapter, client->addr + 1); + if (!drvdata->fake_client) + return -ENOMEM; + + i2c_set_clientdata(client, drvdata); + mutex_init(&drvdata->update_lock); + + err = sysfs_create_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + if (err) + i2c_unregister_device(drvdata->fake_client); + + return err; +} + +static int mc24lc64t_remove(struct i2c_client *client) +{ + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + + i2c_unregister_device(drvdata->fake_client); + + sysfs_remove_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + + return 0; +} + +static const struct i2c_device_id mc24lc64t_id[] = { + { "24lc64t", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mc24lc64t_id); + +static struct i2c_driver mc24lc64t_driver = { + .driver = { + .name = "mc24lc64t", + .owner = THIS_MODULE, + }, + .probe = mc24lc64t_probe, + .remove = mc24lc64t_remove, + .id_table = mc24lc64t_id, +}; + +module_i2c_driver(mc24lc64t_driver); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_DESCRIPTION("Microchip 24LC64T Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/z9332f-modules.conf b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/z9332f-modules.conf new file mode 100644 index 000000000000..b6d4fe4fb00a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/z9332f-modules.conf @@ -0,0 +1,17 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x + +ipmi_devintf +ipmi_si diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py new file mode 100755 index 000000000000..047618e057c8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py @@ -0,0 +1,102 @@ +#!/usr/bin/python +# Copyright (c) 2015 Dell Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. + +import struct +import sys +import getopt +from os import * +from mmap import * + +def usage(): + ''' This is the Usage Method ''' + + print '\t\t pcisysfs.py --get --offset --res ' + print '\t\t pcisysfs.py --set --val --offset --res ' + sys.exit(1) + +def pci_mem_read(mm,offset): + mm.seek(offset) + read_data_stream=mm.read(4) + print "" + reg_val=struct.unpack('I',read_data_stream) + print "reg_val read:%x"%reg_val + return reg_val + +def pci_mem_write(mm,offset,data): + mm.seek(offset) + print "data to write:%x"%data + mm.write(struct.pack('I',data)) + +def pci_set_value(resource,val,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_write(mm,offset,val) + +def pci_get_value(resource,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_read(mm,offset) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resource = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgsv:" , \ + ["val=","res=","offset=","help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt,arg in opts: + + if opt in ('-h','--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--res': + resource = arg + + elif opt == '--val': + val = int(arg,16) + + elif opt == '--offset': + offset = int(arg,16) + + if choice == 'set' and val != '' and offset !='' and resource !='': + pci_set_value(resource,val,offset) + + elif choice == 'get' and offset != '' and resource !='': + pci_get_value(resource,offset) + + else: + usage() + +#Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py new file mode 100755 index 000000000000..2fd2b84900da --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py @@ -0,0 +1,198 @@ +#!/usr/bin/python +# On Z9332F, the BaseBoard Management Controller is an +# autonomous subsystem provides monitoring and management +# facility independent of the host CPU. IPMI standard +# protocol is used with ipmitool to fetch sensor details. +# Current script support X00 board only. X01 support will +# be added soon. This provies support for the +# following objects: +# * Onboard temperature sensors +# * FAN trays +# * PSU + + +import os +import sys +import logging +import subprocess +import commands + +Z9332F_MAX_FAN_TRAYS = 7 +Z9332F_MAX_PSUS = 2 +IPMI_SENSOR_DATA = "ipmitool sdr list" +IPMI_SENSOR_DUMP = "/tmp/sdr" + +FAN_PRESENCE = "Fan{0}_Status" +PSU_PRESENCE = "PSU{0}_Status" +# Use this for older firmware +# PSU_PRESENCE="PSU{0}_prsnt" + +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x2f | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x39 | awk '{print substr($0,9,1)}'" + +ipmi_sdr_list = "" + +# Dump sensor registers + + +def ipmi_sensor_dump(): + + status = 1 + global ipmi_sdr_list + ipmi_cmd = IPMI_SENSOR_DATA + status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + + if status: + logging.error('Failed to execute:' + ipmi_sdr_list) + sys.exit(0) + +# Fetch a BMC register + + +def get_pmc_register(reg_name): + + output = None + for item in ipmi_sdr_list.split("\n"): + if reg_name in item: + output = item.strip() + + if output is None: + print('\nFailed to fetch: ' + reg_name + ' sensor ') + sys.exit(0) + + output = output.split('|')[1] + + logging.basicConfig(level=logging.DEBUG) + return output + + +# Print the information for temperature sensors + + +def print_temperature_sensors(): + + print("\nOnboard Temperature Sensors:") + + for x in (('TEMP_FAN_U52', 'Fan U52'), + ('TEMP_FAN_U17', 'Fan U17'), + ('TEMP_SW_U52', 'SW U52'), + ('TEMP_SW_U16', 'SW U16'), + ('TEMP_BB_U3', 'Baseboard U3'), + ('TEMP_CPU', 'Near CPU'), + ('TEMP_SW_Internal', 'SW interal'), + ('PSU1_Temp1', 'PSU1 inlet'), + ('PSU1_Temp2', 'PSU1 hotspot'), + ('PSU2_Temp1', 'PSU2 inlet'), + ('PSU2_Temp2', 'PSU2 hotspot'), + ('SW_U04_Temp', 'SW U04'), + ('SW_U14_Temp', 'SW U14'), + ('SW_U4403_Temp', 'SW U4403') + ): + print ' {0:32}{1}'.format(x[1] + ':', get_pmc_register(x[0])) + +ipmi_sensor_dump() + +print_temperature_sensors() + +# Print the information for 1 Fan Tray + + +def print_fan_tray(tray): + + Fan_Status = [' Normal', ' Abnormal'] + Airflow_Direction = ['B2F', 'F2B'] + + print ' Fan Tray ' + str(tray) + ':' + + print ' Fan1 Speed: ',\ + get_pmc_register('Fan{}_Front'.format(tray)) + print ' Fan2 Speed: ',\ + get_pmc_register('Fan{}_Rear'.format(tray)) + print ' Fan State: ',\ + Fan_Status[int(get_pmc_register('Fan{}_Status'.format(tray)), 16)] + + +print('\nFan Trays:') + +for tray in range(1, Z9332F_MAX_FAN_TRAYS + 1): + fan_presence = FAN_PRESENCE.format(tray) + if (get_pmc_register(fan_presence)): + print_fan_tray(tray) + else: + print '\n Fan Tray ' + str(tray + 1) + ': Not present' + + def get_psu_presence(index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + ret_status = 1 + + if index == 1: + status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + + #if ret_status: + # print ipmi_cmd_ret + # logging.error('Failed to execute ipmitool') + # sys.exit(0) + + psu_status = ipmi_cmd_ret + + if psu_status == '1': + status = 1 + + return status + + +# Print the information for PSU1, PSU2 +def print_psu(psu): + Psu_Type = ['Normal', 'Mismatch'] + Psu_Input_Type = ['AC', 'DC'] + PSU_STATUS_TYPE_BIT = 4 + PSU_STATUS_INPUT_TYPE_BIT = 1 + PSU_FAN_PRESENT_BIT = 2 + PSU_FAN_STATUS_BIT = 1 + PSU_FAN_AIR_FLOW_BIT = 0 + Psu_Fan_Presence = ['Present', 'Absent'] + Psu_Fan_Status = ['Normal', 'Abnormal'] + Psu_Fan_Airflow = ['B2F', 'F2B'] + + # print ' Input: ', Psu_Input_Type[psu_input_type] + # print ' Type: ', Psu_Type[psu_type] + + print ' PSU{}:'.format(psu) + print ' Inlet Temperature: ',\ + get_pmc_register('PSU{}_Temp1'.format(psu)) + print ' Hotspot Temperature: ',\ + get_pmc_register('PSU{}_Temp2'.format(psu)) + print ' FAN RPM: ',\ + get_pmc_register('PSU{}_Fan'.format(psu)) + # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] + + # PSU input & output monitors + print ' Input Voltage: ',\ + get_pmc_register('PSU{}_VIn'.format(psu)) + print ' Output Voltage: ',\ + get_pmc_register('PSU{}_VOut'.format(psu)) + print ' Input Power: ',\ + get_pmc_register('PSU{}_PIn'.format(psu)) + print ' Output Power: ',\ + get_pmc_register('PSU{}_POut'.format(psu)) + print ' Input Current: ',\ + get_pmc_register('PSU{}_CIn'.format(psu)) + print ' Output Current: ',\ + get_pmc_register('PSU{}_COut'.format(psu)) + + +print('\nPSUs:') +for psu in range(1, Z9332F_MAX_PSUS + 1): + #psu_presence = PSU_PRESENCE.format(psu) + if (get_psu_presence(psu)): + print_psu(psu) + else: + print '\n PSU ', psu, 'Not present' diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/sensors b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/sensors new file mode 100755 index 000000000000..ee53f2b0f325 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/sensors @@ -0,0 +1,8 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" +docker exec -i pmon /usr/bin/platform_sensors.py "$@" + +#To probe sensors not part of lm-sensors +#if [ -r /usr/local/bin/platform_sensors.py ]; then +# python /usr/local/bin/platform_sensors.py +#fi diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh new file mode 100755 index 000000000000..ab2a787a6627 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh @@ -0,0 +1,180 @@ +#!/bin/bash + +init_devnum() { + found=0 + for devnum in 0; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # I801 adapter f000 + if [[ $devname == 'SMBus I801 adapter at '* ]]; then + found=1 + break + fi + done + + [ $found -eq 0 ] && echo "cannot find I801" && exit 1 +} + +# Attach/Detach syseeprom on CPU board +sys_eeprom() { + case $1 in + "new_device") echo 24lc64t 0x56 > /sys/bus/i2c/devices/i2c-0/$1 + ;; + "delete_device") echo 0x56 > /sys/bus/i2c/devices/i2c-0/$1 + ;; + *) echo "z9332f_platform: sys_eeprom : invalid command !" + ;; + esac +} + +#Attach/Detach the MUX connecting all QSFPs +switch_board_qsfp_mux() { + case $1 in + "new_device") + for ((i=603;i<=607;i++)); + do + echo "Attaching PCA9548 @ 0x74" + echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + + ;; + "delete_device") + for ((i=603;i<=607;i++)); + do + echo "Detaching PCA9548 @ 0x74" + echo 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + + ;; + *) echo "z9332f_platform: switch_board_qsfp_mux: invalid command !" + ;; + esac + sleep 2 +} + +#Attach/Detach 64 instances of EEPROM driver QSFP ports +#eeprom can dump data using below command +switch_board_qsfp() { + case $1 in + "new_device") + for ((i=10;i<=41;i++)); + do + echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=10;i<=41;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "z9332f_platform: switch_board_qsfp: invalid command !" + ;; + esac +} + +#Attach/Detach 2 instances of EEPROM driver SFP+ ports +#eeprom can dump data using below command +switch_board_sfp() { + case $1 in + "new_device") + for ((i=1;i<=2;i++)); + do + echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=1;i<=2;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "z9332f_platform: switch_board_qsfp: invalid command !" + ;; + esac +} + +#Modsel 64 ports to applicable QSFP type modules +#This enables the adapter to respond for i2c commands +switch_board_modsel() { + resource="/sys/bus/pci/devices/0000:09:00.0/resource0" + for ((i=1;i<=32;i++)); + do + port_addr=$(( 16384 + ((i - 1) * 16))) + hex=$( printf "0x%x" $port_addr ) + python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + done +} + +#This enables the led control for CPU and default states +switch_board_led_default() { + /usr/sbin/i2cset -y 5 0x0d 0x62 0xd0 +} + +# Readout firmware version of the system and +# store in /var/log/firmware_versions +platform_firmware_versions() { + + FIRMWARE_VERSION_FILE=/var/log/firmware_versions + + rm -rf ${FIRMWARE_VERSION_FILE} + echo "BIOS:`dmidecode -t bios | grep Version | awk -F":" '{print $2}'`" > $FIRMWARE_VERSION_FILE + # Get FPGA version + r=`/usr/bin/pcisysfs.py --get --offset 0x00 --res /sys/bus/pci/devices/0000\:09\:00.0/resource0 | sed '1d; s/.*\(....\)$/\1/; s/\(..\{1\}\)/\1./'` + r_min=$(echo $r | sed 's/.*\(..\)$/0x\1/') + r_maj=$(echo $r | sed 's/^\(..\).*/0x\1/') + echo "FPGA: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + ## Get BMC Firmware Revision + #r=`docker exec -it pmon ipmitool mc info | awk '/Firmware Revision/ { print $NF }'` + r=`cat /sys/class/ipmi/ipmi0/device/bmc/firmware_revision` + echo "BMC: $r" >> $FIRMWARE_VERSION_FILE + + #BaseBoard CPLD 0x0d on i2c bus 5 ( physical FPGA I2C-5) + ver=`/usr/sbin/i2cget -y 5 0x0d 0x0` + echo "Baseboard CPLD: $((ver))" >> $FIRMWARE_VERSION_FILE + + #Switch CPLD 1 0x30 on i2c bus 4 ( physical FPGA I2C-4) + ver=`/usr/sbin/i2cget -y 4 0x30 0x0` + echo "Switch CPLD 1: $((ver))" >> $FIRMWARE_VERSION_FILE + + #Switch CPLD 1 0x30 on i2c bus 4 ( physical FPGA I2C-4) + ver=`/usr/sbin/i2cget -y 4 0x31 0x0` + echo "Switch CPLD 2: $((ver))" >> $FIRMWARE_VERSION_FILE +} +init_devnum + +if [ "$1" == "init" ]; then + modprobe i2c-dev + modprobe i2c-mux-pca954x force_deselect_on_exit=1 + modprobe ipmi_devintf + modprobe ipmi_si + modprobe cls-i2c-ocore + modprobe cls-switchboard + modprobe mc24lc64t + #insmod /lib/modules/`uname -r`/extra/mc24lc64t.ko + sys_eeprom "new_device" + switch_board_qsfp "new_device" + switch_board_sfp "new_device" + switch_board_led_default + # python /usr/bin/qsfp_irq_enable.py + platform_firmware_versions + +elif [ "$1" == "deinit" ]; then + sys_eeprom "delete_device" + switch_board_qsfp "delete_device" + switch_board_sfp "delete_device" + modprobe -r i2c-mux-pca954x + modprobe -r i2c-dev + modprobe -r ipmi_devintf + modprobe -r ipmi_si + modprobe -r cls-i2c-ocore + modprobe -r cls-switchboard + modprobe -r mc24lc64t +else + echo "z9332f_platform : Invalid option !" +fi + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service b/platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service new file mode 100644 index 000000000000..49064b00d682 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service @@ -0,0 +1,13 @@ +[Unit] +Description=Dell Z9332f Platform modules +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/z9332f_platform.sh init +ExecStop=/usr/local/bin/z9332f_platform.sh deinit +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index 370a920d2187..5bddb7a0ded7 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -2,6 +2,7 @@ arl_clean_timeout_usec asf_mem_profile bcm_linkscan_interval bcm_num_cos +default_cpu_tx_queue bcm_stat_flags bcm_stat_interval bcm_stat_jumbo From 9c4c36e1b5717446e12d119d1a487bf9611c9e89 Mon Sep 17 00:00:00 2001 From: Judy Joseph Date: Thu, 19 Dec 2019 06:26:34 +0000 Subject: [PATCH 0253/1427] [broadom]: Upgrade broadcom SAI to 3.7.3.2 [Broadcom] : update saibcm-modules to sdk 6.5.16 [Broadcom SAI] : upgrade Broadcom SAI to 3.7.3.2 --- .../broadcom/docker-syncd-brcm/Dockerfile.j2 | 7 +- platform/broadcom/sai-modules.mk | 2 +- platform/broadcom/sai.mk | 10 +- .../broadcom/saibcm-modules/debian/changelog | 21 + .../debian/opennsl-modules.init | 26 +- .../debian/opennsl-modules.install | 1 + platform/broadcom/saibcm-modules/debian/rules | 6 +- .../broadcom/saibcm-modules/include/ibde.h | 8 - .../broadcom/saibcm-modules/include/kcom.h | 19 +- .../saibcm-modules/include/soc/devids.h | 313 +-- .../broadcom/saibcm-modules/make/Make.config | 7 +- .../saibcm-modules/make/Makefile.linux-gto | 6 - .../make/Makefile.linux-gto-2_6 | 6 - .../saibcm-modules/make/Makefile.linux-iproc | 8 +- .../make/Makefile.linux-kmodule | 2 +- .../make/Makefile.linux-x86-common-2_6 | 2 +- .../Makefile.linux-x86-generic-common-2_6 | 2 +- .../Makefile.linux-x86-smp_generic_64-2_6 | 1 - .../systems/bde/linux/include/linux-bde.h | 13 +- .../systems/bde/linux/include/linux_dma.h | 4 +- .../systems/bde/linux/kernel/Makefile | 24 +- .../bde/linux/kernel/linux-kernel-bde.c | 1287 ++---------- .../systems/bde/linux/kernel/linux_dma.c | 117 +- .../systems/bde/linux/shared/mpool.c | 133 +- .../bde/linux/user/kernel/linux-user-bde.c | 177 +- .../systems/bde/shared/shbde_iproc.c | 16 +- .../linux/kernel/modules/bcm-knet/bcm-knet.c | 1732 ++++++++++++++--- .../linux/kernel/modules/include/bcm-knet.h | 84 +- .../kernel/modules/include/net/psample.h | 24 + .../modules/include/uapi/linux/psample.h | 35 + .../linux/kernel/modules/knet-cb/Makefile | 4 +- .../linux/kernel/modules/knet-cb/knet-cb.c | 104 +- .../linux/kernel/modules/knet-cb/psample-cb.c | 875 +++++++++ .../linux/kernel/modules/knet-cb/psample-cb.h | 58 + .../linux/kernel/modules/psample/Makefile | 64 + .../linux/kernel/modules/psample/psample.c | 302 +++ .../systems/linux/user/common/Makefile | 21 + .../systems/linux/user/iproc/Makefile | 2 +- sonic-slave-stretch/Dockerfile.j2 | 4 +- 39 files changed, 3560 insertions(+), 1967 deletions(-) create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.h create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index b20e353f842f..1ef1c588777c 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -1,3 +1,4 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages %} FROM docker-config-engine-stretch ARG docker_container_name @@ -14,10 +15,8 @@ debs/{{ deb }}{{' '}} {%- endfor -%} debs/ -RUN dpkg -i \ -{% for deb in docker_syncd_brcm_debs.split(' ') -%} -debs/{{ deb }}{{' '}} -{%- endfor %} +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_syncd_brcm_debs.split(' ')) }} ## TODO: add kmod into Depends RUN apt-get install -yf kmod diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index dc77c4b5cb78..1d559d0ad320 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,7 +1,7 @@ # Broadcom SAI modules KVERSION = 4.9.0-9-2-amd64 -BRCM_OPENNSL_KERNEL_VERSION = 3.4.1.11-1 +BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb $(BRCM_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 833c22f6bb94..63c1e21ec7fc 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.5.3.1m-25_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=zo83IKnlT7goymXwynW8%2Fx6rR2eIh0AiIS%2BSrSMUhRE%3D&se=2033-07-21T18%3A50%3A27Z&sp=r" +BRCM_SAI = libsaibcm_3.7.3.3_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=Y66VSRUEl4PDf5kHRo%2FS3DBBE9tONSyCzNJvi8IP9n8%3D&se=2033-08-25T01%3A22%3A08Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.5.3.1m-25_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm-dev_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=tQmkCIy2mnb9rH7B9oXFUZDwijMGXWnVtta2CNTMbFM%3D&se=2033-07-21T18%3A50%3A47Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=6%2BWzgFL845H9lKE0COsN53P4MO4UWfSo0z%2FmUMFbYVk%3D&se=2033-08-25T01%3A21%3A50Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) -$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) +$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) \ No newline at end of file diff --git a/platform/broadcom/saibcm-modules/debian/changelog b/platform/broadcom/saibcm-modules/debian/changelog index 5ea7b289ee65..2be513ed0435 100644 --- a/platform/broadcom/saibcm-modules/debian/changelog +++ b/platform/broadcom/saibcm-modules/debian/changelog @@ -1,3 +1,24 @@ +opennsl (3.7.3.3-1) unstable; urgency=medium + + * Port Broadcom SAI 3.7.3.3 + * Cherry-pick change from master branch, 3.7.3.3-1 + + -- Judy Joseph Fri, 2 Dec 2019 15:32:47 +0000 + +opennsl (3.7.3.2-1) unstable; urgency=medium + + * Port Broadcom SAI 3.7.3.2 + * Cherry-pick change from master branch, 3.7.3.2-1 + + -- Judy Joseph Fri, 12 Nov 2019 15:22:47 +0000 + +opennsl (3.7.3.1-1) unstable; urgency=medium + + * Port Broadcom SAI 3.7.3.1 + * Cherry-pick change from master branch, 3.7.3.1-1 + + -- Judy Joseph Fri, 19 Sep 2019 13:11:47 +0000 + opennsl (3.4.1.11-1) unstable; urgency=medium * Port Broadcom SAI 3.4.1.11 diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.init b/platform/broadcom/saibcm-modules/debian/opennsl-modules.init index 1aaa91bb2d82..7def10cbff86 100755 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.init +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.init @@ -32,14 +32,38 @@ function create_devices() # level logs function load_kernel_modules() { - modprobe linux-kernel-bde dmasize=32M maxpayload=128 debug=4 dma_debug=1 + . /host/machine.conf + + if [ -n "$aboot_platform" ]; then + platform=$aboot_platform + elif [ -n "$onie_platform" ]; then + platform=$onie_platform + else + platform="unknown" + fi + + # Set the default configuration for dmasize and usemsi parameters + dmasize=32M + usemsi=0 + + # Source the platform env file + env_file="/usr/share/sonic/device/$platform/platform_env.conf" + source $env_file + + modprobe linux-kernel-bde dmasize=$dmasize maxpayload=128 debug=4 dma_debug=1 usemsi=$usemsi modprobe linux-user-bde + + # Using insmod with absolute path for psample to make sure bcm psample is loaded. + # There is a different psample.ko module getting created at net/psample/psample.ko + insmod /lib/modules/$(uname -r)/extra/psample.ko + modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 debug=0x5020 modprobe linux-knet-cb } function remove_kernel_modules() { + rmmod psample.ko rmmod linux-knet-cb rmmod linux-bcm-knet rmmod linux-user-bde diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index 11b100d37f30..e16980dc2c0d 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -2,4 +2,5 @@ systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-9- systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.9.0-9-2-amd64/extra systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.9.0-9-2-amd64/extra systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.9.0-9-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.9.0-9-2-amd64/extra systemd/opennsl-modules.service lib/systemd/system diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index 33abe645d44a..0092cc1a1027 100755 --- a/platform/broadcom/saibcm-modules/debian/rules +++ b/platform/broadcom/saibcm-modules/debian/rules @@ -60,7 +60,7 @@ kdist_config: prep-deb-files kdist_clean: clean dh_testdir dh_clean - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean # rm -f driver/*.o driver/*.ko # ### end KERNEL SETUP @@ -78,7 +78,7 @@ build-arch-stamp: dh_testdir # Add here command to compile/build the package. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 touch $@ @@ -103,7 +103,7 @@ clean: rm -f build-arch-stamp build-indep-stamp configure-stamp # Add here commands to clean up after the build process. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean dh_clean diff --git a/platform/broadcom/saibcm-modules/include/ibde.h b/platform/broadcom/saibcm-modules/include/ibde.h index 9c8956f5e3e0..45112eadcb4b 100644 --- a/platform/broadcom/saibcm-modules/include/ibde.h +++ b/platform/broadcom/saibcm-modules/include/ibde.h @@ -148,14 +148,6 @@ typedef struct ibde_s { */ int (*get_cmic_ver)(int d, uint32 *ver); - /* - * Probe available devices. - * Return value : - * 0: success to probe available devices - * -1: error happens during probe - */ - int (*probe)(void); - /* * I2C operations on the Device, assuming it is connected by I2C to the CPU. */ diff --git a/platform/broadcom/saibcm-modules/include/kcom.h b/platform/broadcom/saibcm-modules/include/kcom.h index 76f3e47a8de5..1e3cad0753bc 100644 --- a/platform/broadcom/saibcm-modules/include/kcom.h +++ b/platform/broadcom/saibcm-modules/include/kcom.h @@ -121,6 +121,13 @@ typedef struct kcom_msg_hdr_s { #define KCOM_NETIF_NAME_MAX 16 +/* + * Max size of Sand System Headers + * For DNX, Module Header(20B) + PTCH(2B) + ITMH(5B) + * For DPP, PTCH(2B) + ITMH(4B) + */ +#define KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX 27 + typedef struct kcom_netif_s { uint16 id; uint8 type; @@ -133,6 +140,8 @@ typedef struct kcom_netif_s { uint8 macaddr[6]; uint8 ptch[2]; uint8 itmh[4]; + uint8 system_headers[KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX]; + uint8 system_headers_size; char name[KCOM_NETIF_NAME_MAX]; } kcom_netif_t; @@ -216,6 +225,13 @@ typedef struct kcom_filter_s { uint8 b[KCOM_FILTER_BYTES_MAX]; uint32 w[KCOM_FILTER_WORDS_MAX]; } mask; + /** Information to parse Dune system headers */ + uint32 ftmh_lb_key_ext_size; + uint32 ftmh_stacking_ext_size; + uint32 pph_base_size; + uint32 pph_lif_ext_size[8]; + uint8 udh_enable; + uint32 udh_length_type[4]; } kcom_filter_t; /* @@ -470,8 +486,7 @@ typedef struct kcom_msg_filter_destroy_s { * Get list of currently defined packet filters. */ #ifndef KCOM_FILTER_MAX -/* SAI_FIXUP - Increased the filters to 1024 from 128 */ -#define KCOM_FILTER_MAX 1024 +#define KCOM_FILTER_MAX 128 #endif typedef struct kcom_msg_filter_list_s { diff --git a/platform/broadcom/saibcm-modules/include/soc/devids.h b/platform/broadcom/saibcm-modules/include/soc/devids.h index cb072a78cbd7..7546ef392298 100644 --- a/platform/broadcom/saibcm-modules/include/soc/devids.h +++ b/platform/broadcom/saibcm-modules/include/soc/devids.h @@ -14,7 +14,7 @@ * version 2 (GPLv2) along with this source code. */ /* - * Copyright: (c) 2018 Broadcom. + * Copyright: (c) 2019 Broadcom. * All Rights Reserved. */ @@ -835,31 +835,6 @@ #define BCM56746_A0_REV_ID 1 #define BCM56746_A1_REV_ID 2 -#define BCM88230_DEVICE_ID 0x0230 -#define BCM88230_A0_REV_ID 1 -#define BCM88230_B0_REV_ID 0x11 -#define BCM88230_C0_REV_ID 0x21 -#define BCM88231_DEVICE_ID 0x0231 -#define BCM88231_A0_REV_ID 1 -#define BCM88231_B0_REV_ID 0x11 -#define BCM88231_C0_REV_ID 0x21 -#define BCM88235_DEVICE_ID 0x0235 -#define BCM88235_A0_REV_ID 1 -#define BCM88235_B0_REV_ID 0x11 -#define BCM88235_C0_REV_ID 0x21 -#define BCM88236_DEVICE_ID 0x0236 -#define BCM88236_A0_REV_ID 1 -#define BCM88236_B0_REV_ID 0x11 -#define BCM88236_C0_REV_ID 0x21 -#define BCM88239_DEVICE_ID 0x0239 -#define BCM88239_A0_REV_ID 1 -#define BCM88239_B0_REV_ID 0x11 -#define BCM88239_C0_REV_ID 0x21 -#define BCM56613_DEVICE_ID 0xb613 -#define BCM56613_A0_REV_ID 1 -#define BCM56613_B0_REV_ID 0x11 -#define BCM56613_C0_REV_ID 0x21 - #define BCM88732_DEVICE_ID 0x0732 #define BCM88732_A0_REV_ID 1 #define BCM88732_A1_REV_ID 2 @@ -1243,10 +1218,13 @@ #define BCM56981_A0_REV_ID 1 #define BCM56982_DEVICE_ID 0xb982 #define BCM56982_A0_REV_ID 1 +#define BCM56982_B0_REV_ID 0x11 #define BCM56983_DEVICE_ID 0xb983 #define BCM56983_A0_REV_ID 1 +#define BCM56983_B0_REV_ID 0x11 #define BCM56984_DEVICE_ID 0xb984 #define BCM56984_A0_REV_ID 1 +#define BCM56984_B0_REV_ID 0x11 #define BCM56968_DEVICE_ID 0xb968 #define BCM56968_A0_REV_ID 1 @@ -1428,33 +1406,43 @@ #define BCM56370_DEVICE_ID 0xb370 #define BCM56370_A0_REV_ID 1 +#define BCM56370_A1_REV_ID 0x02 #define BCM56371_DEVICE_ID 0xb371 #define BCM56371_A0_REV_ID 1 +#define BCM56371_A1_REV_ID 0x02 #define BCM56372_DEVICE_ID 0xb372 #define BCM56372_A0_REV_ID 1 +#define BCM56372_A1_REV_ID 0x02 #define BCM56374_DEVICE_ID 0xb374 #define BCM56374_A0_REV_ID 1 +#define BCM56374_A1_REV_ID 0x02 #define BCM56375_DEVICE_ID 0xb375 #define BCM56375_A0_REV_ID 1 +#define BCM56375_A1_REV_ID 0x02 #define BCM56376_DEVICE_ID 0xb376 #define BCM56376_A0_REV_ID 1 +#define BCM56376_A1_REV_ID 0x02 #define BCM56377_DEVICE_ID 0xb377 #define BCM56377_A0_REV_ID 1 +#define BCM56377_A1_REV_ID 0x02 #define BCM56577_DEVICE_ID 0xb577 #define BCM56577_A0_REV_ID 1 +#define BCM56577_A1_REV_ID 0x02 #define BCM56578_DEVICE_ID 0xb578 #define BCM56578_A0_REV_ID 1 +#define BCM56578_A1_REV_ID 0x02 #define BCM56579_DEVICE_ID 0xb579 #define BCM56579_A0_REV_ID 1 +#define BCM56579_A1_REV_ID 0x02 #define BCM56770_DEVICE_ID 0xb770 #define BCM56770_A0_REV_ID 1 @@ -1488,247 +1476,6 @@ #define BROADCOM_PHYID_HIGH 0x0040 -#define BCM5338_PHYID_LOW 0x62b0 -#define BCM5338_A0_REV_ID 0 -#define BCM5338_A1_REV_ID 1 -#define BCM5338_B0_REV_ID 3 - -#define BCM5324_PHYID_LOW 0xbc20 -#define BCM5324_PHYID_HIGH 0x143 -#define BCM5324_A1_PHYID_HIGH 0x153 -#define BCM5324_DEVICE_ID 0xbc20 -#define BCM5324_A0_REV_ID 0 -#define BCM5324_A1_REV_ID 1 -#define BCM5324_A2_REV_ID 2 - -#define BCM5380_PHYID_LOW 0x6250 -#define BCM5380_A0_REV_ID 0 - -#define BCM5388_PHYID_LOW 0x6288 -#define BCM5388_A0_REV_ID 0 - -#define BCM5396_PHYID_LOW 0xbd70 -#define BCM5396_PHYID_HIGH 0x143 -#define BCM5396_DEVICE_ID 0x96 -#define BCM5396_A0_REV_ID 0 - -#define BCM5389_PHYID_LOW 0xbd70 -#define BCM5389_PHYID_HIGH 0x143 -#define BCM5389_DEVICE_ID 0x89 -#define BCM5389_A0_REV_ID 0 -#define BCM5389_A1_DEVICE_ID 0x86 -#define BCM5389_A1_REV_ID 1 - -#define BCM5398_PHYID_LOW 0xbcd0 -#define BCM5398_PHYID_HIGH 0x0143 -#define BCM5398_DEVICE_ID 0x98 -#define BCM5398_A0_REV_ID 0 - -#define BCM5325_PHYID_LOW 0xbc30 -#define BCM5325_PHYID_HIGH 0x143 -#define BCM5325_DEVICE_ID 0xbc30 -#define BCM5325_A0_REV_ID 0 -#define BCM5325_A1_REV_ID 1 - -#define BCM5348_PHYID_LOW 0xbe40 -#define BCM5348_PHYID_HIGH 0x0143 -#define BCM5348_DEVICE_ID 0x48 -#define BCM5348_A0_REV_ID 0 -#define BCM5348_A1_REV_ID 1 - -#define BCM5397_PHYID_LOW 0xbcd0 -#define BCM5397_PHYID_HIGH 0x0143 -#define BCM5397_DEVICE_ID 0x97 -#define BCM5397_A0_REV_ID 0 - -#define BCM5347_PHYID_LOW 0xbe40 -#define BCM5347_PHYID_HIGH 0x0143 -#define BCM5347_DEVICE_ID 0x47 -#define BCM5347_A0_REV_ID 0 - -#define BCM5395_PHYID_LOW 0xbcf0 -#define BCM5395_PHYID_HIGH 0x0143 -#define BCM5395_DEVICE_ID 0xbcf0 -#define BCM5395_A0_REV_ID 0 - -#define BCM53242_PHYID_LOW 0xbf10 -#define BCM53242_PHYID_HIGH 0x0143 -#define BCM53242_DEVICE_ID 0xbf10 -#define BCM53242_A0_REV_ID 0 -#define BCM53242_B0_REV_ID 4 -#define BCM53242_B1_REV_ID 5 - -#define BCM53262_PHYID_LOW 0xbf20 -#define BCM53262_PHYID_HIGH 0x0143 -#define BCM53262_DEVICE_ID 0xbf20 -#define BCM53262_A0_REV_ID 0 -#define BCM53262_B0_REV_ID 4 -#define BCM53262_B1_REV_ID 5 - -#define BCM53115_PHYID_LOW 0xbf80 -#define BCM53115_PHYID_HIGH 0x0143 -#define BCM53115_DEVICE_ID 0xbf80 -#define BCM53115_A0_REV_ID 0 -#define BCM53115_A1_REV_ID 1 -#define BCM53115_B0_REV_ID 2 -#define BCM53115_B1_REV_ID 3 -#define BCM53115_C0_REV_ID 8 - -#define BCM53118_PHYID_LOW 0xbfe0 -#define BCM53118_PHYID_HIGH 0x0143 -#define BCM53118_DEVICE_ID 0xbfe0 -#define BCM53118_A0_REV_ID 0 - -#define BCM53118_B0_REV_ID 4 -#define BCM53118_B1_REV_ID 5 - -#define BCM53280_PHYID_LOW 0x5e90 -#define BCM53280_PHYID_HIGH 0x0362 -#define BCM53280_DEVICE_ID (0x4 | BCM53280_PHYID_LOW) -#define BCM53280_A0_REV_ID 0 -#define BCM53280_B0_REV_ID 0x4 -#define BCM53280_B1_REV_ID 0x5 -#define BCM53280_B2_REV_ID 0x6 -#define BCM53286_DEVICE_ID (0x4 | BCM53280_PHYID_LOW) -#define BCM53288_DEVICE_ID (0xc | BCM53280_PHYID_LOW) -#define BCM53284_DEVICE_ID (0x7 | BCM53280_PHYID_LOW) -#define BCM53283_DEVICE_ID (0x6 | BCM53280_PHYID_LOW) -#define BCM53282_DEVICE_ID (0x5 | BCM53280_PHYID_LOW) -#define BCM53101_PHYID_LOW 0x5ed0 -#define BCM53101_PHYID_HIGH 0x0362 -#define BCM53101_DEVICE_ID 0x5ed0 -#define BCM53101_A0_REV_ID 0 -#define BCM53101_B0_REV_ID 4 - -#define BCM53125_PHYID_LOW 0x5f20 -#define BCM53125_PHYID_HIGH 0x0362 -#define BCM53125_DEVICE_ID 0x5f20 -#define BCM53125_A0_REV_ID 0 -#define BCM53125_B0_REV_ID 0x4 -#define BCM53125_MODEL_ID 0x53125 - -#define BCM53134_PHYID_LOW 0x5350 -#define BCM53134_PHYID_HIGH 0xAE02 -#define BCM53134_DEVICE_ID 0x5350 -#define BCM53134_A0_REV_ID 0x0 -#define BCM53134_B0_REV_ID 0x1 -#define BCM53134_B1_REV_ID 0x2 -#define BCM53134_A0_MODEL_ID 0x5035 -#define BCM53134_B0_MODEL_ID 0x5075 - -#define BCM53128_PHYID_LOW 0x5e10 -#define BCM53128_PHYID_HIGH 0x0362 -#define BCM53128_DEVICE_ID 0x5e10 -#define BCM53128_A0_REV_ID 0 -#define BCM53128_B0_REV_ID 0x4 -#define BCM53128_MODEL_ID 0x53128 - -#define BCM53600_PHYID_LOW 0x5f40 -#define BCM53600_PHYID_HIGH 0x0362 -#define BCM53600_DEVICE_ID (0x3 | BCM53600_PHYID_LOW) -#define BCM53600_A0_REV_ID 0 -#define BCM53602_DEVICE_ID (0x1 | BCM53600_PHYID_LOW) -#define BCM53603_DEVICE_ID (0x2 | BCM53600_PHYID_LOW) -#define BCM53604_DEVICE_ID (0x3 | BCM53600_PHYID_LOW) -#define BCM53606_DEVICE_ID (0x7 | BCM53600_PHYID_LOW) - -#define BCM89500_PHYID_LOW 0x5d30 -#define BCM89500_PHYID_HIGH 0x0362 -#define BCM89500_DEVICE_ID 0x9500 -#define BCM89501_DEVICE_ID 0x9501 -#define BCM89200_DEVICE_ID 0x9200 -#define BCM89500_A0_REV_ID 0 -#define BCM89500_B0_REV_ID 0x4 -#define BCM89500_MODEL_ID 0x89500 - -#define BCM53010_PHYID_LOW 0x8760 -#define BCM53010_PHYID_HIGH 0x600d -#define BCM53010_DEVICE_ID 0x3010 -#define BCM53011_DEVICE_ID 0x3011 -#define BCM53012_DEVICE_ID 0x3012 -#define BCM53010_A0_REV_ID 0 -#define BCM53010_A2_REV_ID 0x2 -#define BCM53010_MODEL_ID 0x53010 - -#define BCM53018_PHYID_LOW 0x87c0 -#define BCM53018_PHYID_HIGH 0x600d -#define BCM53017_DEVICE_ID 0x3016 -#define BCM53018_DEVICE_ID 0x3018 -#define BCM53019_DEVICE_ID 0x3019 -#define BCM53018_A0_REV_ID 0 -#define BCM53018_MODEL_ID 0x53016 - -#define BCM53020_PHYID_LOW 0x87f0 -#define BCM53020_PHYID_HIGH 0x600d -#define BCM53020_DEVICE_ID 0x8022 -#define BCM53022_DEVICE_ID 0x8022 -#define BCM53023_DEVICE_ID 0x8023 -#define BCM53025_DEVICE_ID 0x8025 -#define BCM58625_DEVICE_ID 0x8625 -#define BCM58622_DEVICE_ID 0x8622 -#define BCM58623_DEVICE_ID 0x8623 -#define BCM58525_DEVICE_ID 0x8525 -#define BCM58522_DEVICE_ID 0x8522 -#define BCM53020_A0_REV_ID 0 -#define BCM53020_MODEL_ID 0x3025 - -#define BCM4713_DEVICE_ID 0x4713 -#define BCM4713_A0_REV_ID 0 -#define BCM4713_A9_REV_ID 9 - -#define BCM53000_GMAC_DEVICE_ID 0x4715 -#define BCM53000_A0_REV_ID 0 - -#define BCM53010_GMAC_DEVICE_ID 0x4715 - -#define BCM53000PCIE_DEVICE_ID 0x5300 - -#define SANDBURST_VENDOR_ID 0x17ba -#define BME3200_DEVICE_ID 0x0280 -#define BME3200_A0_REV_ID 0x0000 -#define BME3200_B0_REV_ID 0x0001 -#define BM9600_DEVICE_ID 0x0480 -#define BM9600_A0_REV_ID 0x0000 -#define BM9600_B0_REV_ID 0x0010 -#define QE2000_DEVICE_ID 0x0300 -#define QE2000_A1_REV_ID 0x0001 -#define QE2000_A2_REV_ID 0x0002 -#define QE2000_A3_REV_ID 0x0003 -#define QE2000_A4_REV_ID 0x0004 -#define BCM88020_DEVICE_ID 0x0380 -#define BCM88020_A0_REV_ID 0x0000 -#define BCM88020_A1_REV_ID 0x0001 -#define BCM88020_A2_REV_ID 0x0002 -#define BCM88025_DEVICE_ID 0x0580 -#define BCM88025_A0_REV_ID 0x0000 -#define BCM88030_DEVICE_ID 0x0038 -#define BCM88030_A0_REV_ID 0x0001 -#define BCM88030_A1_REV_ID 0x0002 -#define BCM88030_B0_REV_ID 0x0011 -#define BCM88030_B1_REV_ID 0x0012 -#define BCM88034_DEVICE_ID 0x0034 -#define BCM88034_A0_REV_ID (BCM88030_A0_REV_ID) -#define BCM88034_A1_REV_ID (BCM88030_A1_REV_ID) -#define BCM88034_B0_REV_ID (BCM88030_B0_REV_ID) -#define BCM88034_B1_REV_ID (BCM88030_B1_REV_ID) -#define BCM88039_DEVICE_ID 0x0039 -#define BCM88039_A0_REV_ID (BCM88030_A0_REV_ID) -#define BCM88039_A1_REV_ID (BCM88030_A1_REV_ID) -#define BCM88039_B0_REV_ID (BCM88030_B0_REV_ID) -#define BCM88039_B1_REV_ID (BCM88030_B1_REV_ID) -#define BCM88130_DEVICE_ID 0x0480 -#define BCM88130_A0_REV_ID 0x0000 -#define BCM88130_A1_REV_ID 0x0001 -#define BCM88130_B0_REV_ID 0x0010 -#define PLX_VENDOR_ID 0x10b5 -#define PLX9656_DEVICE_ID 0x9656 -#define PLX9656_REV_ID 0x0000 -#define PLX9056_DEVICE_ID 0x9056 -#define PLX9056_REV_ID 0x0000 - -#define TK371X_DEVICE_ID 0x8600 -#define TK371X_A0_REV_ID 0x0 - #define GEDI_DEVICE_ID 0xa100 #define GEDI_REV_ID 0x0001 #define ARAD_DEVICE_ID 0x8650 @@ -1778,6 +1525,7 @@ #define DNXC_A0_REV_ID 0x0001 #define DNXC_A1_REV_ID 0x0002 #define DNXC_B0_REV_ID 0x0011 +#define DNXC_B1_REV_ID 0x0012 #define BCM88790_DEVICE_ID 0x8790 #define BCM88790_A0_REV_ID DNXC_A0_REV_ID #define BCM88790_B0_REV_ID DNXC_B0_REV_ID @@ -1933,9 +1681,34 @@ #define BCM88381_A0_REV_ID JERICHO_PLUS_A0_REV_ID #define JERICHO_2_DEVICE_ID 0x8690 -#define JERICHO_2_A0_REV_ID 0x0001 +#define JERICHO_2_A0_REV_ID DNXC_A0_REV_ID +#define JERICHO_2_B0_REV_ID DNXC_B0_REV_ID +#define JERICHO_2_B1_REV_ID DNXC_B1_REV_ID #define BCM88690_DEVICE_ID JERICHO_2_DEVICE_ID #define BCM88690_A0_REV_ID JERICHO_2_A0_REV_ID +#define BCM88690_B0_REV_ID JERICHO_2_B0_REV_ID +#define BCM88690_B1_REV_ID JERICHO_2_B1_REV_ID +#define BCM88691_DEVICE_ID 0x8691 +#define BCM88692_DEVICE_ID 0x8692 +#define BCM88693_DEVICE_ID 0x8693 +#define BCM88694_DEVICE_ID 0x8694 +#define BCM88695_DEVICE_ID 0x8695 +#define BCM88696_DEVICE_ID 0x8696 +#define BCM88697_DEVICE_ID 0x8697 +#define BCM88698_DEVICE_ID 0x8698 +#define BCM88699_DEVICE_ID 0x8699 +#define BCM8869A_DEVICE_ID 0x869A +#define BCM8869B_DEVICE_ID 0x869B +#define BCM8869C_DEVICE_ID 0x869C +#define BCM8869D_DEVICE_ID 0x869D +#define BCM8869E_DEVICE_ID 0x869E +#define BCM8869F_DEVICE_ID 0x869F +#define BCM_JR2_DEVID_MASK 0xFFF0 + +#define J2C_DEVICE_ID 0x8800 +#define J2C_A0_REV_ID DNXC_A0_REV_ID +#define BCM88800_DEVICE_ID J2C_DEVICE_ID +#define BCM88800_A0_REV_ID J2C_A0_REV_ID #define QAX_DEVICE_ID 0x8470 #define QAX_A0_REV_ID 0x0001 @@ -1964,6 +1737,7 @@ #define BCM88270_A1_REV_ID QUX_A1_REV_ID #define BCM88272_DEVICE_ID 0x8272 #define BCM88273_DEVICE_ID 0x8273 +#define BCM88274_DEVICE_ID 0x8274 #define BCM88278_DEVICE_ID 0x8278 #define BCM88279_DEVICE_ID 0x8279 @@ -2045,5 +1819,8 @@ #define ACP_PCI_VENDOR_ID 0x10ee #define ACP_PCI_DEVICE_ID 0x7011 #define ACP_PCI_REV_ID 0x0001 + +#define PLX9056_DEVICE_ID 0x9056 + #endif diff --git a/platform/broadcom/saibcm-modules/make/Make.config b/platform/broadcom/saibcm-modules/make/Make.config index b8fa17bda119..409a6a49b3f3 100644 --- a/platform/broadcom/saibcm-modules/make/Make.config +++ b/platform/broadcom/saibcm-modules/make/Make.config @@ -54,12 +54,7 @@ endif -include ${SDK}/make/Make.local ifdef ALL_CHIPS - ROBO_CHIPS = 1 ESW_CHIPS = 1 -else - ifndef ROBO_CHIPS - ESW_CHIPS = 1 - endif endif # ALL_CHIPS # @@ -166,7 +161,7 @@ CFLAGS += ${INCFLAGS} CXXFLAGS += ${INCFLAGS} CPPFLAGS += ${INCFLAGS} -CFLAGS += -DSAI_FIXUP -DBCM_PORT_DEFAULT_DISABLE -DBCM_VLAN_NO_DEFAULT_ETHER -DBCM_VLAN_NO_DEFAULT_CPU -DBCM_WARM_BOOT_SUPPORT -DSAL_CONFIG_FILE_DISABLE -DSAL_THREAD_NAME_PRINT_DISABLE -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=256 -DALPM_ENABLE -DOPENNSL_PHY_ROUTINES -DTH2_CPU_POOL_SETUP -DINCLUDE_L3 -DSAI_ONLY -DPRINT_TO_SYSLOG -D_SHR_PBMP_WIDTH=256 -DINCLUDE_DIAG_SHELL -DSTATIC=static -DLOG_TEST -DLOG_SAI -D_GNU_SOURCE +CFLAGS += -DSAI_FIXUP -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=1024 # # Debug #ifdef control diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto index 947c20e74f93..786b4cc26bc3 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto @@ -74,12 +74,6 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\ KFLAG_INCLD = $(TOOLCHAIN_BIN_DIR)/../lib/gcc/$(TARGET_ARCHITECTURE)/4.6.4/include ifdef BROADCOM_SVK -ifdef BCM_BME3200_B0 -PLX_PCI2LBUS=1 -endif -ifdef BCM_BM9600_B0 -PLX_PCI2LBUS=1 -endif ifeq ($PLX_PCI2LBUS, 1) CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto-2_6 index 4caa4902421f..56085c7a3cdd 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto-2_6 @@ -224,12 +224,6 @@ endif endif ifdef BROADCOM_SVK -ifdef BCM_BME3200_B0 -PLX_PCI2LBUS=1 -endif -ifdef BCM_BM9600_B0 -PLX_PCI2LBUS=1 -endif ifeq ($PLX_PCI2LBUS, 1) CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc index 7c0f9411f5e2..092e474e2563 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc @@ -27,11 +27,11 @@ endif # TARGET_ARCHITECTURE Compiler for target architecture # KERNDIR Kernel directory for iPROC-CMICd devices ifeq (BE,$(ENDIAN_MODE)) -TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/iproc-be/XLDK +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50-be/XLDK32 TARGET_ARCHITECTURE:=armeb-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux else -TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/iproc/XLDK +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50/XLDK32 TARGET_ARCHITECTURE:= arm-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux endif @@ -60,6 +60,8 @@ CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 ENDIAN = LE_HOST=1 endif +CFLAGS += -fno-aggressive-loop-optimizations + CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" @@ -80,7 +82,7 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") -KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.3/include +KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.4/include ifeq (,$(KFLAGS)) KFLAGS := -D__LINUX_ARM_ARCH__=7 -D__KERNEL__ -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm/include -I$(KERNDIR)/arch/arm/include/generated -I$(KERNDIR)/arch/arm/mach-iproc/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -marm -mabi=aapcs-linux -fno-pic -pipe -msoft-float -ffreestanding -march=armv7-a -mfpu=vfp -mfloat-abi=softfp -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mlong-calls diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule b/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule index 3ad11d169c64..540c497ea258 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule @@ -71,7 +71,7 @@ $(KMODULE): rm -f *.o *.ko .*.cmd rm -fr .tmp_versions ln -s $(LIBDIR)/$(MODULE) $(PRE_COMPILED_OBJ)_shipped - echo "suppress warning" > .$(PRE_COMPILED_OBJ).cmd + if [ ! -f $(KERNBLDDIR)/NO_SUPRESS ]; then echo "# suppress warning" > .$(PRE_COMPILED_OBJ).cmd; fi $(MAKE) -C $(KERNBLDDIR) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules if [ ! -f Module.symvers ]; then echo "old kernel (pre-2.6.17)" > Module.symvers; fi cp -f $(KMODULE) $(LIBDIR) diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 index 07af2afcc93b..25e953136bc0 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 @@ -22,7 +22,7 @@ ENDIAN = LE_HOST=1 CFGFLAGS += -D$(ENDIAN) CFGFLAGS += -DBCM_PLATFORM_STRING=\"X86\" ifeq (,$(findstring -DSAL_BDE_DMA_MEM_DEFAULT,$(CFGFLAGS))) -CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32 +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=16 endif # Extra variables. diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 index ab342c12d210..bf0ea85d578e 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 @@ -48,4 +48,4 @@ AUTOCONF = $(KERNDIR)/include/linux/autoconf.h endif # gcc system include path -SYSINC = $(shell gcc -print-search-dirs | grep install | cut -c 10-)include +SYSINC = $(shell $(CC) -print-search-dirs | grep install | cut -c 10-)include diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 index bb0bbea536a3..bc0230ec8226 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 @@ -43,4 +43,3 @@ KFLAGS += -I$(KERNDIR_COMMON)/include -I$(KERNDIR_COMMON)/include/uapi -I$(KERND endif include ${SDK}/make/Makefile.linux-x86-common-2_6 - diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h index 927201bc1fd8..bdf7a56dcabb 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h @@ -222,7 +222,7 @@ extern int lkbde_dev_instid_set(int d, uint32 instid); extern int lkbde_irq_mask_set(int d, uint32 addr, uint32 mask, uint32 fmask); extern int lkbde_irq_mask_get(int d, uint32 *mask, uint32 *fmask); -#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)) +#ifdef BCM_SAND_SUPPORT extern int lkbde_cpu_write(int d, uint32 addr, uint32 *buf); extern int lkbde_cpu_read(int d, uint32 addr, uint32 *buf); extern int lkbde_cpu_pci_register(int d); @@ -241,15 +241,12 @@ extern int lkbde_cpu_pci_register(int d); */ #define LKBDE_IPROC_REG 0x4000 -#if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) +#ifdef BCM_SAND_SUPPORT #include #if defined(__DUNE_LINUX_BCM_CPU_PCIE__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) #ifndef _SIMPLE_MEMORY_ALLOCATION_ #define _SIMPLE_MEMORY_ALLOCATION_ 1 #endif -#ifndef USE_LINUX_BDE_MMAP -#define USE_LINUX_BDE_MMAP 1 -#endif #endif #endif @@ -271,13 +268,9 @@ extern int lkbde_cpu_pci_register(int d); #define _SIMPLE_MEMORY_ALLOCATION_ 9 /* compile in the allocation method, but do not use it by default */ #endif -/* By default we use our private mmap only if /dev/mem mmap has restrictions */ +/* By default we use our private mmap for DMA pool */ #ifndef USE_LINUX_BDE_MMAP -#ifdef CONFIG_STRICT_DEVMEM #define USE_LINUX_BDE_MMAP 1 -#else -#define USE_LINUX_BDE_MMAP 0 -#endif #endif #endif /* __KERNEL__ */ diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h index bfbbceb2d8e7..3bf7488abce9 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h @@ -58,7 +58,7 @@ #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) #endif -extern void _dma_init(int robo_switch, int dev_index); +extern void _dma_init(int dev_index); extern int _dma_cleanup(void); extern void _dma_pprint(void); extern uint32_t *_salloc(int d, int size, const char *name); @@ -68,7 +68,7 @@ extern int _sflush(int d, void *ptr, int length); extern sal_paddr_t _l2p(int d, void *vaddr); extern void *_p2l(int d, sal_paddr_t paddr); extern int _dma_pool_allocated(void); -extern int _dma_range_valid(unsigned long phys_addr, unsigned long size); +extern int _dma_mmap(struct file *filp, struct vm_area_struct *vma); #endif /* __KERNEL__ */ diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile index 3d504a5665fa..aedd487b1f11 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile @@ -33,33 +33,11 @@ LIBS = $(LIBDIR)/libkern.a BDE = linux-kernel-bde.o -ifdef ROBO_CHIPS -CFLAGS += -I$(ET_ROBO) -I${SDK}/include/shared/et -ET_ROBO = ${SDK}/systems/drv/et -endif - # need to add vpath sources -VPATH = ../shared $(ET_ROBO) +VPATH = ../shared # Add the srcs to be found by vpath LSRCS += mpool.c -ifdef ROBO_CHIPS -platformsplt = $(subst -, , ${platform}) # change hyphens to spaces -platformbase = $(word 1,${platformsplt}) - -ifeq ($(platformbase), keystone) - LSRCS += etc_robo_spi.c aiutils.c -else - ifeq ($(platformbase), keystone_le) - LSRCS += etc_robo_spi.c aiutils.c - else - ifeq ($(platformbase), iproc) - LSRCS += robo_srab.c robo_spi.c aiutils.c - endif - endif -endif # platformbase - -endif # ROBO_CHIPS # Add shared BDE sources VPATH += ../../shared diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c index 1a04b2b52e9b..464a72bd3e41 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c @@ -35,30 +35,22 @@ #include "linux_shbde.h" -#ifdef BCM_ROBO_SUPPORT -/* robo/et related header files */ -#include - -#include - -#if defined(KEYSTONE) -#include -#include -#include -#include -#elif defined(IPROC_CMICD) -#include -#include -#ifdef BCM_STARFIGHTER3_SUPPORT -#include -#endif -#include -#include -#else /* BCM4704 */ -#include -#include -#endif -#endif /* BCM_ROBO_SUPPORT */ + +#ifdef __GNUC__ +#if __GNUC__ == 8 +/* + * Prevent gcc 8.1.10 using a compiler inline memcpy even if using -fno-builtin or + * -fno-builtin-memcpy . + * __inline_memcpy and __memcpy are kernel functions that may be used instead, + * for either an inline or non-inline implementations of the function + */ +#define MEMCPY __inline_memcpy +#else +#define MEMCPY memcpy +#endif /* __GNUC__ == 8 */ +#else /* ifdef __GNUC__ */ +#define MEMCPY memcpy +#endif /* ifdef __GNUC__ */ #define PCI_USE_INT_NONE (-1) #define PCI_USE_INT_INTX (0) @@ -108,26 +100,6 @@ int msixcnt = 1; #define PCI_DEVICE_ID_PLX_9056 0x9056 #endif -/* local defined device IDs, refer to bcmdevs.h */ -#ifndef BCM53000_GMAC_ID -#define BCM53000_GMAC_ID 0x4715 /* 53003 gmac id */ -#endif -#ifndef BCM53010_GMAC_ID -#define BCM53010_GMAC_ID 0x4715 /* 5301x gmac id */ -#endif -#ifndef BCM47XX_ENET_ID -#define BCM47XX_ENET_ID 0x4713 /* 4710 enet */ -#endif -#ifndef BCM53010_CHIP_ID -#define BCM53010_CHIP_ID 0xcf12 /* 53010 chipcommon chipid */ -#endif -#ifndef BCM53018_CHIP_ID -#define BCM53018_CHIP_ID 0xcf1a /* 53018 chipcommon chipid */ -#endif -#ifndef BCM53020_CHIP_ID -#define BCM53020_CHIP_ID 0xcf1e /* 53020 chipcommon chipid */ -#endif - /* For 2.4.x kernel support */ #ifndef IRQF_SHARED #define IRQF_SHARED SA_SHIRQ @@ -186,14 +158,6 @@ MODULE_PARM_DESC(spifreq, "Force SPI Frequency for Keystone CPU (0 for default frequency)"); #endif -#if defined(BCM_EA_SUPPORT) -#if defined(BCM_TK371X_SUPPORT) -static int eadevices; -LKM_MOD_PARAM(eadevices, "i", int, 0); -MODULE_PARM_DESC(eadevices, -"Number of TK371X devices"); -#endif /* */ -#endif /* BCM_EA_SUPPORT */ /* Compatibility */ #ifdef LKM_2_4 @@ -203,7 +167,7 @@ MODULE_PARM_DESC(eadevices, #define IRQ_HANDLED #define SYNC_IRQ(_i) synchronize_irq() #else /* LKM_2_6 */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) #define _ISR_RET irqreturn_t #else #define _ISR_RET int @@ -212,6 +176,7 @@ MODULE_PARM_DESC(eadevices, #define _ISR_PARAMS(_i,_d,_r) int _i, void *_d #else #define _ISR_PARAMS(_i,_d,_r) int _i, void *_d, struct pt_regs *_r +typedef irqreturn_t (*irq_handler_t)(int _i, void *_d, struct pt_regs *_r); #endif #define SYNC_IRQ(_i) synchronize_irq(_i) char * ___strtok; @@ -364,7 +329,6 @@ static int _ndevices = 0; static int _switch_ndevices = 0; static int _ether_ndevices = 0; static int _cpu_ndevices = 0; -static int robo_switch = 0; #define VALID_DEVICE(_n) ((_n >= 0) && (_n < _ndevices)) @@ -375,48 +339,10 @@ static uint32 iproc_cmicx_irqs[IHOST_CMICX_MAX_INTRS]; #endif /* CPU MMIO area used with CPU cards provided on demo boards */ -#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT)) && (defined(__DUNE_WRX_BCM_CPU__) || defined(__DUNE_GTO_BCM_CPU__)) +#if defined(BCM_SAND_SUPPORT) && (defined(__DUNE_WRX_BCM_CPU__) || defined(__DUNE_GTO_BCM_CPU__)) static void *cpu_address = NULL; #endif -#ifdef BCM_ROBO_SUPPORT - -/* for SPI access via bcm4710 core */ -static void *robo = NULL; -static void *sbh = NULL; - -#ifdef ALTA_ROBO_SPI - -extern void *alta_eth_spi_ctrl; - -extern int -robo_spi_read(void *cookie, uint16_t reg, uint8_t *buf, int len); - -extern int -robo_spi_write(void *cookie, uint16_t reg, uint8_t *buf, int len); - -#define ROBO_RREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_spi_read(_dev ? NULL : alta_eth_spi_ctrl, \ - (_page << 8) | (_reg), _buf, _len) -#define ROBO_WREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_spi_write(_dev ? NULL : alta_eth_spi_ctrl, \ - (_page << 8) | (_reg), _buf, _len) - -#else /* !ALTA_ROBO_SPI */ - -#if defined(KEYSTONE) || defined(IPROC_CMICD) -#define ROBO_RREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_rreg(_robo, _dev, _page, _reg, _buf, _len) -#define ROBO_WREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_wreg(_robo, _dev, _page, _reg, _buf, _len) -#else -#define ROBO_RREG(_robo, _dev, _page, _reg, _buf, _len) -#define ROBO_WREG(_robo, _dev, _page, _reg, _buf, _len) -#endif - -#endif /* ALTA_ROBO_SPI */ - -#endif /* BCM_ROBO_SUPPORT */ /* Broadcom BCM4704 */ #define BCM4704_VENDOR_ID 0x14E4 @@ -500,6 +426,17 @@ robo_spi_write(void *cookie, uint16_t reg, uint8_t *buf, int len); #define BCM58712_PCI_VENDOR_ID 0x14E4 #define BCM58712_PCI_DEVICE_ID 0x168E +/* Default gicd address if not available in DTB */ +#define IHOST_GICD_REG_ADDR 0x10781100 +#define IHOST_GICD_REG_REMAP_LEN 0x100 + +#define IHOST_GICD_REG_ADDR_VALID(d, addr) \ + (_devices[d].bde_dev.base_address1 && \ + (addr & 0xFFFFFF00) == _devices[d].phys_address1) + +#define IHOST_GICD_REG_ADDR_REMAP(d, addr) \ + (void *)(_devices[d].bde_dev.base_address1 + (addr - _devices[d].phys_address1)) + static uint32_t _read(int d, uint32_t addr); #ifdef BCM_ICS @@ -551,6 +488,19 @@ _parse_eb_args(char *str, char * format, ...) static void _bde_add_device(void) { + int add_switch_device = 0; + if (_devices[_ndevices].dev_type & BDE_SWITCH_DEV_TYPE) { + _switch_ndevices++; + add_switch_device = 1; + } else if (_devices[_ndevices].dev_type & BDE_ETHER_DEV_TYPE) { + _ether_ndevices++; + } else if (_devices[_ndevices].dev_type & BDE_CPU_DEV_TYPE) { + _cpu_ndevices++; + } else { + return; + } + _ndevices++; + /* * In order to be backward compatible with the user mode BDE * (specifically the interrupt IOCTLs) and the CM, switch devices @@ -558,7 +508,7 @@ _bde_add_device(void) * order), we let the non-switch device(s) drop down to the end of * the device array. */ - if (_switch_ndevices > 0) { + if (add_switch_device) { bde_ctrl_t tmp_dev; int i, s = 0; @@ -573,13 +523,12 @@ _bde_add_device(void) } _devices[i] = tmp_dev; } - } - /* Initialize device locks and dma */ - if (_ndevices > 0) { - spin_lock_init(&_devices[_ndevices-1].lock); - _dma_init(robo_switch, _ndevices-1); + _dma_init(_switch_ndevices-1); } + + /* Initialize device locks */ + spin_lock_init(&_devices[_ndevices-1].lock); } static int @@ -590,8 +539,7 @@ _eb_device_create(resource_size_t paddr, int irq, int rd_hw, int wr_hw) dev_id = _ndevices; - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_EB_DEV_TYPE | BDE_SWITCH_DEV_TYPE; ctrl->pci_device = NULL; /* No PCI bus */ @@ -617,15 +565,15 @@ _eb_device_create(resource_size_t paddr, int irq, int rd_hw, int wr_hw) ctrl->isr = NULL; ctrl->isr_data = NULL; - _bde_add_device(); - gprintk("Created EB device at BA=%x IRQ=%d RD16=%d WR16=%d device=0x%x\n", (unsigned int)paddr, irq, rd_hw, wr_hw, ctrl->bde_dev.device); + _bde_add_device(); + return 0; } -#if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT) +#ifdef BCM_SAND_SUPPORT #include @@ -637,9 +585,6 @@ sand_device_create(void) ctrl = _devices; /* FIX_ME: on petra, take first device */ #ifndef __DUNE_LINUX_BCM_CPU_PCIE__ - _switch_ndevices++; - _ndevices++; - ctrl->dev_type |= BDE_PCI_DEV_TYPE | BDE_SWITCH_DEV_TYPE; ctrl->pci_device = NULL; /* No PCI bus */ @@ -677,7 +622,7 @@ sand_device_create(void) return 0; } -#endif +#endif /* BCM_SAND_SUPPORT */ #ifdef IPROC_CMICD static void @@ -739,8 +684,7 @@ iproc_cmicd_probe(struct platform_device *pldev) } size = memres->end - memres->start + 1; - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type = BDE_AXI_DEV_TYPE | BDE_SWITCH_DEV_TYPE | BDE_256K_REG_SPACE; ctrl->pci_device = NULL; /* No PCI bus */ @@ -764,6 +708,24 @@ iproc_cmicd_probe(struct platform_device *pldev) ctrl->bde_dev.device = readl(icfg_chip_id) & 0xffff; ctrl->bde_dev.rev = readl(icfg_chip_id+1) & 0xff; iounmap(icfg_chip_id); + /* Map GICD block in the AXI memory space into CPU address space */ + memres = iproc_platform_get_resource(pldev, IORESOURCE_MEM, 1); + if (memres) { + ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(memres->start, memres->end - memres->start + 1); + ctrl->phys_address1 = memres->start; + } else { + /* Use default address if not available in DTB */ + ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(IHOST_GICD_REG_ADDR, IHOST_GICD_REG_REMAP_LEN); + ctrl->phys_address1 = IHOST_GICD_REG_ADDR; + } + if (ctrl->bde_dev.base_address1) { + if (debug >= 1) { + gprintk("base_address1:0x%lx phys_address1:0x%lx\n", + (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)ctrl->phys_address1); + } + } else { + gprintk("Error mapping ihost GICD registers\n"); + } } else #endif { @@ -777,6 +739,7 @@ iproc_cmicd_probe(struct platform_device *pldev) ctrl->bde_dev.device = dev_rev_id & 0xffff; ctrl->bde_dev.rev = (dev_rev_id >> 16) & 0xff; #endif + ctrl->bde_dev.base_address1 = 0; } #ifdef CONFIG_OF @@ -901,10 +864,6 @@ iproc_has_cmicd(void) /* Only allowed accessing CMICD module if the SOC has it */ switch (cca_cid) { - case BCM53010_CHIP_ID: - case BCM53018_CHIP_ID: - case BCM53020_CHIP_ID: - return 0; default: break; } @@ -1052,8 +1011,7 @@ _ics_bde_create(void) resource_size_t paddr; if (_ndevices == 0) { - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_ICS_DEV_TYPE | BDE_SWITCH_DEV_TYPE; ctrl->pci_device = NULL; /* No PCI bus */ @@ -1072,8 +1030,8 @@ _ics_bde_create(void) ctrl->isr = NULL; ctrl->isr_data = NULL; - _bde_add_device(); printk("Created ICS device ..%x\n", ctrl->bde_dev.base_address); + _bde_add_device(); } return 0; @@ -1248,7 +1206,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56150_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56151_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56152_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM56613_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56930_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56931_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1301,14 +1258,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56044_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56045_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56046_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88230_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88030_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88034_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88039_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88231_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88235_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88236_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88239_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM55440_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56440_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56441_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1450,15 +1399,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56174_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53570_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53575_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, -#ifdef BCM_ROBO_SUPPORT - { BROADCOM_VENDOR_ID, BCM47XX_ENET_ID, PCI_ANY_ID, PCI_ANY_ID }, -#ifdef KEYSTONE - { BROADCOM_VENDOR_ID, BCM53000_GMAC_ID, PCI_ANY_ID, PCI_ANY_ID }, -#endif -#endif - { SANDBURST_VENDOR_ID, QE2000_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { SANDBURST_VENDOR_ID, BCM88020_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { SANDBURST_VENDOR_ID, BCM88025_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9656, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, PCI_ANY_ID, PCI_ANY_ID }, { BCM53000_VENDOR_ID, BCM53000PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1506,6 +1446,7 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88270_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88272_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88273_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88274_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88278_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88279_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1524,7 +1465,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88685_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88380_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88381_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88690_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88202_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88360_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88361_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1537,6 +1477,25 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88661_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88664_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, #endif +#ifdef BCM_DNX_SUPPORT + { BROADCOM_VENDOR_ID, BCM88690_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88690_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88691_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88692_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88693_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88694_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88695_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88696_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88697_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88698_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88699_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869A_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88800_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, +#endif /* BCM_DNX_SUPPORT */ #ifdef BCM_DFE_SUPPORT { BROADCOM_VENDOR_ID, BCM88750_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88753_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -2083,24 +2042,20 @@ _msi_connect(bde_ctrl_t *ctrl) #else ret = pci_enable_msix(ctrl->pci_device, ctrl->entries, ctrl->msix_cnt); -#endif if (ret > 0) { /* Not enough vectors available , Retry MSI-X */ gprintk("Retrying with MSI-X interrupts = %d\n", ret); ctrl->msix_cnt = ret; msixcnt = ret; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) - ret = pci_enable_msix_range(ctrl->pci_device, - ctrl->entries, ctrl->msix_cnt, ctrl->msix_cnt); -#else ret = pci_enable_msix(ctrl->pci_device, ctrl->entries, ctrl->msix_cnt); -#endif if (ret != 0) goto er_intx_free; - } else if (ret < 0) { - /* Error */ - goto er_intx_free; + } +#endif + if (ret < 0) { + /* Error */ + goto er_intx_free; } else { gprintk("Enabled MSI-X interrupts = %d\n", ctrl->msix_cnt); return 0; @@ -2228,13 +2183,12 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) int cmic_bar; int baroff = 0; int iproc = 0; - uint32 gmac_base = 0; int plx_dev = 0; int eth_dev = 0; int cpu_dev = 0; int update_devid = 0; int paxb_core = 0; - int rescan = 0, rescan_idx = -1; + int add_dev = 0, rescan = 0, rescan_idx = -1; shbde_hal_t shared_bde, *shbde = &shared_bde; if (debug >= 4) {gprintk("probing: vendor_id=0x%x, device_id=0x%x\n", dev->vendor, dev->device);} @@ -2280,17 +2234,6 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) case PCI_DEVICE_ID_PLX_9656: plx_dev = 1; break; -#if defined (BCM_ROBO_SUPPORT) && defined(KEYSTONE) - case BCM53000_GMAC_ID: - eth_dev = 1; - gmac_base = SB_ENUM_BASE; - break; -#endif -#if defined (BCM_ROBO_SUPPORT) - case BCM47XX_ENET_ID: - eth_dev = 1; - break; -#endif case BCM53000PCIE_DEVICE_ID: cpu_dev = 1; break; @@ -2332,10 +2275,10 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) if (_ether_ndevices >= LINUX_BDE_MAX_ETHER_DEVICES) { return 0;; } - ctrl = _devices + _ndevices++; - _ether_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_ETHER_DEV_TYPE; ctrl->iLine = dev->irq; + add_dev = 1; if (debug >= 1) gprintk("Found PCI device %04x:%04x as Ethernet device\n", dev->vendor, dev->device); @@ -2343,9 +2286,9 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) if (_cpu_ndevices >= LINUX_BDE_MAX_CPU_DEVICES) { return 0;; } - ctrl = _devices + _ndevices++; - _cpu_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_CPU_DEV_TYPE; + add_dev = 1; if (debug >= 1) gprintk("Found PCI device %04x:%04x as CPU device\n", dev->vendor, dev->device); @@ -2365,16 +2308,16 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) ctrl = _devices + rescan_idx; ctrl->dev_state = BDE_DEV_STATE_CHANGED; } else { - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_SWITCH_DEV_TYPE; ctrl->domain_no = pci_domain_nr(dev->bus); ctrl->bus_no = dev->bus->number; ctrl->dev_state = BDE_DEV_STATE_NORMAL; + add_dev = 1; } /* Save shared BDE HAL in device structure */ - memcpy(&ctrl->shbde, shbde, sizeof(ctrl->shbde)); + MEMCPY(&ctrl->shbde, shbde, sizeof(ctrl->shbde)); if (update_devid) { /* Re-read the device ID */ @@ -2675,42 +2618,8 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } /* Save shared BDE HAL in device structure */ - memcpy(&ctrl->shbde, shbde, sizeof(ctrl->shbde)); - - - /* - * Since the GMAC driver of Robo chips needs access to the - * ChipCommon and Wrapper registers, we set the base address - * as the enumeration base address and its size as 3MB to - * cover all Wrapper register regions. - */ - if (gmac_base) { - uint32_t offset; - - ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(gmac_base, 0x300000); - - /* Record the base address of GMAC core */ - offset = ctrl->phys_address - gmac_base; - ctrl->alt_base_addr = ctrl->bde_dev.base_address + offset; - ctrl->phys_address = gmac_base; - } - - /* - * Workaround bug in FE2K A1 part; shows as A0 part in PCI config space, - * read the FE's regs directly to get the true revision - */ - if (ctrl->bde_dev.device == BCM88020_DEVICE_ID && ctrl->bde_dev.rev == 0) { -#define FE2000_REVISION_OFFSET (0x0) - uint32_t fe_rev; + MEMCPY(&ctrl->shbde, shbde, sizeof(ctrl->shbde)); - fe_rev = *((uint32_t*)(ctrl->bde_dev.base_address + FE2000_REVISION_OFFSET)); - if ((fe_rev >> 16) == BCM88020_DEVICE_ID) { - fe_rev &= 0xff; - } else { - fe_rev = (fe_rev >> 24) & 0xff; - } - ctrl->bde_dev.rev = fe_rev; - } ctrl->isr = NULL; ctrl->isr_data = NULL; @@ -2732,28 +2641,21 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) if (debug >= 1) gprintk("PCI resource len 8MB\n"); } -#if defined (BCM_ROBO_SUPPORT) && !defined(ALTA_ROBO_SPI) - /* MDC/MDIO path for pseudo PHY access to ROBO register on BCM5836/4704 */ - if (dev->device == BCM47XX_ENET_ID) { - ((uint32 *)ctrl->bde_dev.base_address)[0x410 / 4] = 0; - } -#endif #ifdef LINUX_BDE_DMA_DEVICE_SUPPORT ctrl->dma_dev = &dev->dev; #endif - if (!rescan) { - _bde_add_device(); - } - if (debug >= 2) { gprintk("_pci_probe: configured dev:0x%x rev:0x%x with base_addresses: 0x%lx 0x%lx\n", (unsigned)ctrl->bde_dev.device, (unsigned)ctrl->bde_dev.rev, (unsigned long)ctrl->bde_dev.base_address, (unsigned long)ctrl->bde_dev.base_address1); } - /* Let's boogie */ + if (add_dev) { + _bde_add_device(); + } + /* Let's boogie */ return 0; } @@ -2833,8 +2735,7 @@ static struct pci_driver _device_driver = { static void _spi_device_setup(void) { bde_ctrl_t *ctrl; - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_SWITCH_DEV_TYPE; ctrl->iLine = 0xa3; ctrl->be_pio = 0; @@ -2846,483 +2747,12 @@ _spi_device_setup(void) { gprintk("SPI Slave Mode: force ctrl->bde_dev.rev=0x%x\n",ctrl->bde_dev.rev); gprintk("SPI Slave Mode: force ctrl->dev_type=0x%x\n",ctrl->dev_type); } + _bde_add_device(); } #endif /* BCM_ICS */ -#ifdef BCM_ROBO_SUPPORT - -#ifdef KEYSTONE -#define DEFAULT_FREQ (SPI_FREQ_DEFAULT) -#define FREQ_20MHZ (SPI_FREQ_20MHZ) -#else /* IPROC_CMICD */ -#define DEFAULT_FREQ (0) -#define FREQ_20MHZ (0) -#endif - - -/* -* The model_info /rev_info for Robo devices is defined like this: -* -* 31 28 27 24 23 20 19 16 15 8 7 0 -* +----+---------+------+-----+---------+--------+ -* | op | reserved| mask |len | page |offset | -* +----+---------+------+-----+---------+--------+ -* -* op: 1:OR phyidl, 2: use PCIE device ID -* mlen: mask len (in bytes) 1:means 0xf,2 means 0xff -* len: Size of model/rev ID register (in bytes) -* page: Page containing model ID and revision registers -* offset: Model/rev ID register offset -*/ -static struct bde_spi_device_id _spi_id_table[] = { - { BCM53242_PHYID_HIGH, BCM53242_PHYID_LOW , 0, 0, DEFAULT_FREQ}, - { BCM53262_PHYID_HIGH, BCM53262_PHYID_LOW , 0, 0, DEFAULT_FREQ}, - { BCM53115_PHYID_HIGH, BCM53115_PHYID_LOW , 0, 0, DEFAULT_FREQ}, - { BCM53118_PHYID_HIGH, BCM53118_PHYID_LOW , 0, 0, DEFAULT_FREQ}, - { BCM53280_PHYID_HIGH, BCM53280_PHYID_LOW , 0x101800e8, 0, FREQ_20MHZ}, - { BCM53101_PHYID_HIGH, BCM53101_PHYID_LOW , 0, 0x110240, FREQ_20MHZ}, - { BCM53125_PHYID_HIGH, BCM53125_PHYID_LOW , 0, 0x110240, FREQ_20MHZ}, - { BCM53128_PHYID_HIGH, BCM53128_PHYID_LOW , 0, 0x110240, FREQ_20MHZ}, - { BCM53600_PHYID_HIGH, BCM53600_PHYID_LOW , 0x101800e8, 0, FREQ_20MHZ}, - { BCM89500_PHYID_HIGH, BCM89500_PHYID_LOW ,0x240230, 0x110240, FREQ_20MHZ}, - { BCM53010_PHYID_HIGH, BCM53010_PHYID_LOW ,0x240230, 0x110240, 0}, - { BCM53018_PHYID_HIGH, BCM53018_PHYID_LOW ,0x240230, 0x110240, 0}, - { BCM5389_PHYID_HIGH, BCM5389_PHYID_LOW, 0x110230, 0x110240, DEFAULT_FREQ}, - { BCM53020_PHYID_HIGH, BCM53020_PHYID_LOW ,0x20240230, 0x110240, 0}, - { BCM5396_PHYID_HIGH , BCM5396_PHYID_LOW, 0x110230, 0x110240, DEFAULT_FREQ}, - { BCM53134_PHYID_HIGH, BCM53134_PHYID_LOW , 0, 0x110240, DEFAULT_FREQ}, - { 0, 0, 0, 0, 0 }, -}; -#endif - -#ifdef BCM_ROBO_SUPPORT - -static int -_spi_device_valid_check(unsigned short phyidh,unsigned short phyidl, uint8 check_flag) -{ - struct bde_spi_device_id *_ids; - int idx, match_idx; - - match_idx = -1; - idx = 0; - - if (check_flag == 0){ - /* check_flag == 0 check phyidh only*/ - for (_ids = _spi_id_table; - _ids->phyid_high && _ids->phyid_low; _ids++){ - if (_ids->phyid_high == phyidh) { - return 0; - } - } - /* No valid SPI devices found */ - return 1; - } else { - while(_spi_id_table[idx].phyid_high){ - if (phyidh == _spi_id_table[idx].phyid_high && - phyidl == _spi_id_table[idx].phyid_low) { - /* Found a match */ - match_idx = idx; - break; - } - idx++; - } - return match_idx; - } -} - -#if defined(IPROC_CMICD) || defined(KEYSTONE) -#define ROBO_ATTACH_AVAIL -#endif - -#ifdef ROBO_ATTACH_AVAIL - -#define SOC_ATTACH(_sc)\ - ai_soc_kattach(_sc) - -#if defined(IPROC_CMICD) -#ifdef BCM_STARFIGHTER3_SUPPORT -#define ROBO_ATTACH_SPI(_sih, _ss)\ - robo_attach_spi(_sih) -#define ROBO_DETACH_SPI(robo)\ - robo_detach_spi(robo) -#define ROBO_SPI_RREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_spi_rreg(_robo, _dev, _page, _reg, _buf, _len) -#define ROBO_SPI_WREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_spi_wreg(_robo, _dev, _page, _reg, _buf, _len) -#endif -#define ROBO_ATTACH(_sih, _ss)\ - robo_attach(_sih) -#define MAX_BUSTYPE 1 -#define ROBO_SWITCH_BUS(_robo, _bustype) -#define ROBO_SELECT_DEVICE(_robo, _phyidh, _phyidl) -#else /* KEYSTONE */ -#define ROBO_ATTACH(_sih, _ss)\ - robo_attach(_sih, _ss) -/* bustype 2: ROBO_MDCMDIO_BUS, 1: ROBO_SPI_BUS */ -#define MAX_BUSTYPE 2 -#define ROBO_SWITCH_BUS(_robo, _bustype)\ - robo_switch_bus(_robo, _bustype) - -#define ROBO_SELECT_DEVICE(_robo, _phyidh, _phyidl) \ - robo_select_device(_robo, _phyidh, _phyidl) -#endif - -#else - -#define SOC_ATTACH(_sc) (NULL) -#define ROBO_ATTACH(_sih, _ss) (NULL) -#define MAX_BUSTYPE (0) -#define ROBO_SWITCH_BUS(_robo, _bustype) -#define ROBO_SELECT_DEVICE(_robo, _phyidh, _phyidl) -#endif - - -#if defined(IPROC_CMICD) && defined(BCM_STARFIGHTER3_SUPPORT) -static int -probe_robo_switch_iproc_spi(void) -{ - int dev; - int max_devices, max_bustype; - uint8 buf[8]; - unsigned short phyidh = 0, phyidl = 0; - - - /* Get Robo device handle */ - if (robo == NULL) { - robo = (void *)ROBO_ATTACH_SPI(sbh, 0); - } - if (robo == NULL) { - return -ENODEV; - } - - max_bustype = MAX_BUSTYPE + 1; - - while(_spi_device_valid_check(phyidh, 0, 0)) { - max_bustype --; - if(!max_bustype) - return -ENODEV; - buf[0] = buf[1] = 0; - ROBO_SPI_RREG(robo, 0, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - /* re-try */ - if ((phyidh == 0x0) || (phyidh == 0xffff)) { - ROBO_SPI_RREG(robo, 0, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - } - } - - /* For psedo_phy access, only support one robo switch*/ - /* For Northstar, only one switch on SRAB interface */ - max_devices = (max_bustype == MAX_BUSTYPE) ? 1 : LINUX_BDE_MAX_SWITCH_DEVICES; - - for (dev = 0; dev < max_devices; dev++) { - bde_ctrl_t *ctrl; - int match_idx, i; - unsigned short phyidl_nr; /* phyidl with revision stripped */ - uint16 model_id; - uint8 rev_id; - uint32 addr, len; - uint32 mlen; - - if (_switch_ndevices >= LINUX_BDE_MAX_SWITCH_DEVICES) { - break; - } - buf[0] = buf[1] = 0; - ROBO_SPI_RREG(robo, dev, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - - buf[0] = buf[1] = 0; - ROBO_SPI_RREG(robo, dev, 0x10, 0x06, buf, (uint)2); - phyidl = buf[0] | (buf[1] << 8); - - /* Strip revision */ - phyidl_nr = phyidl & 0xfff0; - - match_idx = _spi_device_valid_check(phyidh, phyidl_nr, 1); - if (match_idx == -1) { - if (debug >= 1) gprintk("found %d robo device(s).\n", robo_switch); - break; - } - - model_id = phyidl_nr; - - if(_spi_id_table[match_idx].rev_info){ - addr = _spi_id_table[match_idx].rev_info & 0xffff; - len = (_spi_id_table[match_idx].rev_info >> 16) & 0xf; - ROBO_SPI_RREG(robo, dev, (addr >> 8), (addr & 0xff), buf, (uint)len); - mlen = (_spi_id_table[match_idx].rev_info >> 20) & 0xf; - rev_id = 0; - for (i = 0; i < mlen; i++) - rev_id |= buf[i] << (i << 3); - } else { - rev_id = phyidl & 0xf; - } - - gprintk("found robo device with %d:%04x:%04x:%04x:%02x\n", - dev, phyidh, phyidl, model_id, rev_id); - - ROBO_SELECT_DEVICE(robo, phyidh, phyidl); - - /* Match supported chips */ - ctrl = _devices + _ndevices++; - _switch_ndevices++; - - if (NULL == (ctrl->spi_device = (struct spi_dev *) - KMALLOC(sizeof(struct spi_dev), GFP_KERNEL))) { - gprintk("no memory available"); - return -ENOMEM; - } - ctrl->dev_type = (BDE_SPI_DEV_TYPE | BDE_SWITCH_DEV_TYPE); - ctrl->spi_device->cid = dev; - ctrl->spi_device->part = model_id; - ctrl->spi_device->rev = rev_id; - ctrl->spi_device->robo = robo; - ctrl->spi_device->phyid_high = phyidh; - ctrl->spi_device->phyid_low = phyidl; - ctrl->bde_dev.device = model_id; - ctrl->bde_dev.rev = rev_id; - ctrl->bde_dev.base_address = (sal_vaddr_t)NULL; - ctrl->isr = NULL; - ctrl->isr_data = NULL; - robo_switch++; - _bde_add_device(); - - } - - return robo_switch; - -} - -int spi_device_found = 0; - -#endif /* IPROC_CMICD || SF3 */ - - -static int -probe_robo_switch(void) -{ - int dev; - int max_devices, max_bustype; - uint8 buf[8]; - unsigned short phyidh = 0, phyidl = 0; -#if defined(KEYSTONE) - uint32 spi_freq = 0; -#endif -#if defined(IPROC_CMICD) - sal_vaddr_t addr_base; - uint32 data_reg; -#endif /* IPROC_CMICD */ - - - spin_lock_init(&bus_lock); - - if (_switch_ndevices) { - /* - * Currently skip probe robo if esw chips were found - * FIX this while combined plateform support. - */ - return robo_switch; - } - - /* Get Robo device handle */ - if (robo == NULL) { - sbh = (void *)SOC_ATTACH(NULL); - if (sbh == NULL) { - return -ENODEV; - } - } - -#if defined(IPROC_CMICD) && defined(BCM_STARFIGHTER3_SUPPORT) - robo_switch = probe_robo_switch_iproc_spi(); - - if (robo_switch > 0) { - /* Robo switch found by SPI probe */ - spi_device_found = 1; - gprintk("SPI device found, Skipping SRAB probe\n"); - return robo_switch; - } else { - gprintk("SPI device NOT found, Probe SRAB probe\n"); - ROBO_DETACH_SPI(robo); - } -#endif - - if (robo == NULL) { - robo = (void *)ROBO_ATTACH(sbh, 0); - } - if (robo == NULL) { - return -ENODEV; - } - - max_bustype = MAX_BUSTYPE + 1; - - while(_spi_device_valid_check(phyidh, 0, 0)) { - max_bustype --; - if(!max_bustype) - return -ENODEV; - ROBO_SWITCH_BUS(robo, max_bustype); - buf[0] = buf[1] = 0; - ROBO_RREG(robo, 0, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - /* re-try */ - if ((phyidh == 0x0) || (phyidh == 0xffff)) { - ROBO_RREG(robo, 0, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - } - } - - /* For psedo_phy access, only support one robo switch*/ - /* For Northstar, only one switch on SRAB interface */ - max_devices = (max_bustype == MAX_BUSTYPE) ? 1 : LINUX_BDE_MAX_SWITCH_DEVICES; - - for (dev = 0; dev < max_devices; dev++) { - bde_ctrl_t *ctrl; - int match_idx, i; - unsigned short phyidl_nr; /* phyidl with revision stripped */ - uint16 model_id; - uint8 rev_id; -#if defined(KEYSTONE) || defined(IPROC_CMICD) - uint32 addr, len; -#endif - uint32 mlen, op; - - if (_switch_ndevices >= LINUX_BDE_MAX_SWITCH_DEVICES) { - break; - } - buf[0] = buf[1] = 0; - ROBO_RREG(robo, dev, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - - buf[0] = buf[1] = 0; - ROBO_RREG(robo, dev, 0x10, 0x06, buf, (uint)2); - phyidl = buf[0] | (buf[1] << 8); - - /* Strip revision */ - phyidl_nr = phyidl & 0xfff0; - - match_idx = _spi_device_valid_check(phyidh, phyidl_nr, 1); - if (match_idx == -1) { - if (debug >= 1) gprintk("found %d robo device(s).\n", robo_switch); - break; - } - - if(_spi_id_table[match_idx].model_info){ -#if defined(KEYSTONE) || defined(IPROC_CMICD) - addr = _spi_id_table[match_idx].model_info & 0xffff; - len = (_spi_id_table[match_idx].model_info >> 16) & 0xf; -#endif - ROBO_RREG(robo, dev, (addr >> 8), (addr & 0xff), buf, (uint)len); - mlen = (_spi_id_table[match_idx].model_info >> 20) & 0xf; - model_id = 0; - for (i = 0; i < mlen; i++) - model_id |= buf[i] << (i << 3); - op = (_spi_id_table[match_idx].model_info >> 28) & 0xf; - if(op == 1) { - model_id |= phyidl_nr; -#if defined(IPROC_CMICD) - } else if (op == 2) { - /* The package id of NS+ is determined by : - * Write 0 to 0x18012120 (PAXB_0_CONFIG_IND_ADDR) - * Read 0x18012124 (PAX_B_CONFIG_IND_DATA), - * bits 31:16 will be the device id from OTP space - */ -#define PAXB_ENUM_BASE (0x18012000) -#define PAXB_CONFIG_IND_ADDR_OFFSET (0x120) -#define PAXB_CONFIG_IND_DATA_OFFSET (0x124) - - addr_base = (sal_vaddr_t)IOREMAP(PAXB_ENUM_BASE, 0x1000); - if (!addr_base) { - gprintk("ioremap of PAXB registers failed\n"); - } else { - writel(0x0, (uint32 *)(addr_base + - PAXB_CONFIG_IND_ADDR_OFFSET)); - data_reg = readl((uint32 *)(addr_base + - PAXB_CONFIG_IND_DATA_OFFSET)); - model_id = (data_reg >> 16); - iounmap((void *)addr_base); - - /* - * Some model ID can't be determined by PCIE device ID - * It needs to refer some OTP values. - */ - robo_model_id_adjust_from_otp(robo, &model_id); - } - -#undef PAXB_ENUM_BASE -#undef PAXB_CONFIG_IND_ADDR_OFFSET -#undef PAXB_CONFIG_IND_DATA_OFFSET -#endif /* IPROC_CMICD */ - } - } else { - model_id = phyidl_nr; - } - if(_spi_id_table[match_idx].rev_info){ -#if defined(KEYSTONE) || defined(IPROC_CMICD) - addr = _spi_id_table[match_idx].rev_info & 0xffff; - len = (_spi_id_table[match_idx].rev_info >> 16) & 0xf; -#endif - ROBO_RREG(robo, dev, (addr >> 8), (addr & 0xff), buf, (uint)len); - mlen = (_spi_id_table[match_idx].rev_info >> 20) & 0xf; - rev_id = 0; - for (i = 0; i < mlen; i++) - rev_id |= buf[i] << (i << 3); - } else { - rev_id = phyidl & 0xf; - } - gprintk("found robo device with %d:%04x:%04x:%04x:%02x\n", - dev, phyidh, phyidl, model_id, rev_id); - - ROBO_SELECT_DEVICE(robo, phyidh, phyidl); - - /* Match supported chips */ - ctrl = _devices + _ndevices++; - _switch_ndevices++; - - if (NULL == (ctrl->spi_device = (struct spi_dev *) - KMALLOC(sizeof(struct spi_dev), GFP_KERNEL))) { - gprintk("no memory available"); - return -ENOMEM; - } - ctrl->dev_type = (BDE_SPI_DEV_TYPE | BDE_SWITCH_DEV_TYPE); - ctrl->spi_device->cid = dev; - ctrl->spi_device->part = model_id; - ctrl->spi_device->rev = rev_id; - ctrl->spi_device->robo = robo; - ctrl->spi_device->phyid_high = phyidh; - ctrl->spi_device->phyid_low = phyidl; - ctrl->bde_dev.device = model_id; - ctrl->bde_dev.rev = rev_id; - ctrl->bde_dev.base_address = (sal_vaddr_t)NULL; - ctrl->isr = NULL; - ctrl->isr_data = NULL; - robo_switch++; -#if defined(KEYSTONE) - spi_freq = _spi_id_table[match_idx].spifreq; -#endif - _bde_add_device(); - } - -#if defined(KEYSTONE) - /* Override the SPI frequency from user configuration */ - if (spifreq != 0) { - spi_freq = spifreq; - } - if (spi_freq != 0) { - /* - * The underlying chip can support the SPI frequency - * higher than default (2MHz). - */ - if (spi_freq != SPI_FREQ_DEFAULT) { - chipc_spi_set_freq(robo, 0, spi_freq); - } - } -#endif - return robo_switch; - -} - -#endif #if defined(BCM_METROCORE_LOCAL_BUS) static bde_ctrl_t* @@ -3330,8 +2760,7 @@ map_local_bus(uint64_t addr, uint32_t size) { bde_ctrl_t *ctrl; - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; /* * For now: use EB type as `local bus' @@ -3347,7 +2776,6 @@ map_local_bus(uint64_t addr, uint32_t size) ctrl->phys_address = addr; _bde_add_device(); - return(ctrl); } @@ -3355,106 +2783,6 @@ map_local_bus(uint64_t addr, uint32_t size) #endif - -#ifdef BCM_METROCORE_LOCAL_BUS - /* - * SBX platform has both PCI- and local bus-attached devices - * The local bus devices have fixed address ranges (and don't - * support or require DMA), but are otherwise the same as PCI devices - */ -#define FPGA_IRQ 37 -#define FPGA_PHYS 0x100E0000 -#define BME_PHYS 0x100C0000 -#define SE_PHYS 0x100D0000 -#define FPGA_SIZE 0x00004000 -#define BME_SIZE 0x00004000 -#define MAC0_PHYS 0x100B0000 -#define MAC1_PHYS 0x100B8000 -#define MAC_SIZE 0x800 - - -/* - * Please refer to "Supervisor Fabric Module (SFM) Specification" - * page 23 for the following registers. - */ -#define FPGA_LC_POWER_DISABLE_OFFSET 0x4 -#define FPGA_LC_POWER_DISABLE_ENABLE_ALL_MASK 0x1e - -#define FPGA_LC_POWER_RESET_OFFSET 0x5 -#define FPGA_LC_POWER_RESET_ENABLE_ALL_MASK 0x1e - -#define FPGA_SW_SFM_MASTER_MODE_OFFSET 0x14 -#define FPGA_SW_SFM_MASTER_MODE_ENABLE_MASK 0x10 - - -static int -probe_metrocore_local_bus(void) { - bde_ctrl_t *ctrl; - uint32_t dev_rev_id; - VOL uint8_t *fpga; - - /* - * Write the FPGA on the fabric card, to let metrocore - * line cards out of reset. We actually don't bother to determine whether - * the card is a line card or a fabric card because when we do - * this on the line cards, it has no effect. - */ - fpga = (uint8_t *) IOREMAP(FPGA_PHYS, FPGA_SIZE); - fpga[FPGA_SW_SFM_MASTER_MODE_OFFSET] - |= FPGA_SW_SFM_MASTER_MODE_ENABLE_MASK; - fpga[FPGA_LC_POWER_DISABLE_OFFSET] - |= FPGA_LC_POWER_DISABLE_ENABLE_ALL_MASK; - fpga[FPGA_LC_POWER_RESET_OFFSET] - |= FPGA_LC_POWER_RESET_ENABLE_ALL_MASK; - - ctrl = map_local_bus(BME_PHYS, BME_SIZE); - - dev_rev_id = - *((uint32_t *) - (((uint8_t *) ctrl->bde_dev.base_address) + BME_REVISION_OFFSET)); - ctrl->bde_dev.device = dev_rev_id >> 16; - ctrl->bde_dev.rev = (dev_rev_id & 0xFF); - - if ((ctrl->bde_dev.device != BME3200_DEVICE_ID) && - (ctrl->bde_dev.device != BCM88130_DEVICE_ID)) { - gprintk("probe_metrocore_local_bus: wrong BME type: " - "0x%x (vs 0x%x or 0x%x)\n", - ctrl->bde_dev.device, BME3200_DEVICE_ID, BCM88130_DEVICE_ID); - return -1; - } - - ctrl->iLine = FPGA_IRQ; - ctrl->isr = NULL; - ctrl->isr_data = NULL; - - /* - * - * We start from SE & include the FPGA, which is 128k - */ - ctrl = map_local_bus(SE_PHYS, 128 * 1024); - - dev_rev_id = - *((uint32_t *) - (((uint8_t *) ctrl->bde_dev.base_address) + BME_REVISION_OFFSET)); - ctrl->bde_dev.device = dev_rev_id >> 16; - ctrl->bde_dev.rev = (dev_rev_id & 0xFF); - - if ((ctrl->bde_dev.device != BME3200_DEVICE_ID) && - (ctrl->bde_dev.device != BCM88130_DEVICE_ID)) { - gprintk("probe_metrocore_local_bus: wrong SE (BME) type: " - "0x%x (vs 0x%x)\n", - ctrl->bde_dev.device, BME3200_DEVICE_ID); - return -1; - } - - ctrl->iLine = FPGA_IRQ; - ctrl->isr = NULL; - ctrl->isr_data = NULL; - - return 0; -} -#endif - #ifdef BCM_PLX9656_LOCAL_BUS #if 1 @@ -3476,8 +2804,7 @@ map_local_bus2(bde_ctrl_t *plx_ctrl, uint32_t dev_base, uint32_t size) uint8_t *addr; bde_ctrl_t *ctrl; - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; /* * For now: use EB type as `local bus' @@ -3499,15 +2826,11 @@ map_local_bus2(bde_ctrl_t *plx_ctrl, uint32_t dev_base, uint32_t size) ctrl->bde_dev.device = dev_rev_id >> 16; ctrl->bde_dev.rev = (dev_rev_id & 0xFF); + _bde_add_device(); switch (ctrl->bde_dev.device) { - case BCM88130_DEVICE_ID: - case BME3200_DEVICE_ID: - break; default: - gprintk("wrong BME type: 0x%x (vs 0x%x or 0x%x)\n", - ctrl->bde_dev.device, BME3200_DEVICE_ID, BCM88130_DEVICE_ID); return 0; } return(ctrl); @@ -3557,143 +2880,8 @@ probe_plx_local_bus(void) #endif /* BCM_PLX9656_LOCAL_BUS */ -#if defined(BCM_EA_SUPPORT) -#if defined(BCM_TK371X_SUPPORT) -static void -probe_tk371x_dev(void) -{ - bde_ctrl_t *ctrl; - int ea_uid=0; - /* eadevices is from the argument of insmod */ - for (ea_uid = 0; ea_uid < eadevices; ea_uid++) { - ctrl = _devices + _ndevices++; - _switch_ndevices++; - ctrl->dev_type = (BDE_MII_DEV_TYPE | BDE_SWITCH_DEV_TYPE); - ctrl->bde_dev.device = TK371X_DEVICE_ID; - ctrl->bde_dev.rev = 0x0; - ctrl->bde_dev.base_address = (sal_vaddr_t)NULL; - ctrl->iLine = 0; - } -} -#endif /* BCM_TK371X_SUPPORT*/ -#endif /* BCM_EA_SUPPORT */ - - -#if defined(BCM_ROBO_SUPPORT) -#if defined(IPROC_CMICD) -struct chip_device_info { - uint32 cc_base; /* Chip-common register base */ - uint32 cc_size; /* Chip-common register limit */ - uint32 cid_reg_off; /* Chip id register offset */ -}; - -static struct chip_device_info _chip_table = { -#if defined(IPROC_CMICD) - 0x18000000, 0x00000300, 0x00000000 -#else - 0,0,0 -#endif -}; - -struct gmac_device_info { - uint32 cid; /* chip id */ - uint32 rid; /* revision id */ - uint32 pid; /* package id */ - - uint32 gmac_dev_id; /* gmac core device id */ - uint32 gmac_base_addr; /* gmac core base address */ - int gmac_irq; /* gmac irq number */ -}; - -static struct gmac_device_info _gmac_table[] = { -#if defined(IPROC_CMICD) - {BCM53010_CHIP_ID, 0, 0, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53012 */ - {BCM53010_CHIP_ID, 0, 2, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53011 */ - {BCM53010_CHIP_ID, 0, 1, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53010 */ - {BCM53018_CHIP_ID, 0, 0, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53018 */ - {BCM53018_CHIP_ID, 0, 2, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53017 */ - {BCM53018_CHIP_ID, 0, 1, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53019 */ - {BCM53020_CHIP_ID, 0, 0, BCM53010_GMAC_ID, 0x18024000, 181}, /* BCM53022 */ - {BCM53020_CHIP_ID, 4, 0, BCM53010_GMAC_ID, 0x18023000, 180}, /* BCM53022 */ -#endif - {0,0,0,0,0,0} -}; - -static sal_vaddr_t _cca_base = 0; - -static int -_gmac_dev_create(void) -{ - bde_ctrl_t *ctrl; - uint32 gmac_base = 0; - uint32 offset = 0; - uint32 cca_cid; - uint32 cid, rid, pid; - int i = 0, found; - if (_chip_table.cc_base == 0) { - gprintk("Create GMAC device failed. Unable to identify CPU.\n"); - return -1; - } - - /* 1. Determine which CPU/GMAC configuration is now */ - _cca_base = (sal_vaddr_t)IOREMAP(_chip_table.cc_base, _chip_table.cc_size); - cca_cid = readl((uint32 *)(_cca_base + _chip_table.cid_reg_off)); - - cid = cca_cid & CID_ID_MASK; - rid = (cca_cid & CID_REV_MASK) >> CID_REV_SHIFT; - pid = (cca_cid & CID_PKG_MASK) >> CID_PKG_SHIFT; - - found = 0; - for (i = 0; ; i++) { - if (_gmac_table[i].cid == 0) { - /* End of table */ - break; - } - if ((_gmac_table[i].cid == cid) && - (_gmac_table[i].rid == rid) && - (_gmac_table[i].pid == pid)) { - /* found */ - found = 1; - break; - } - } - if (!found) { - gprintk("Create GMAC device failed. Unable to identify GMAC device.\n"); - } - - /* 2. Create GMAC device */ - /* fill-in necessary information depends on the CPU/GMAC configuration */ - if ((cid == BCM53010_CHIP_ID) || (cid == BCM53018_CHIP_ID) || - (cid == BCM53020_CHIP_ID)) { - ctrl = _devices + _ndevices++; - _ether_ndevices++; - - ctrl->dev_type |= BDE_ETHER_DEV_TYPE; - ctrl->dev_type |= BDE_PCI_DEV_TYPE; - - ctrl->iLine = _gmac_table[i].gmac_irq; - - ctrl->be_pio = 0; - - ctrl->bde_dev.rev = _gmac_table[i].rid; - ctrl->bde_dev.device = _gmac_table[i].gmac_dev_id; - - gmac_base = 0x18000000; - offset = _gmac_table[i].gmac_base_addr - gmac_base; - ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(gmac_base, 0x300000); - ctrl->alt_base_addr = ctrl->bde_dev.base_address + offset; - ctrl->phys_address = gmac_base; - - ctrl->isr = NULL; - ctrl->isr_data = NULL; - } - - return 0; -} -#endif -#endif /* * Generic module functions @@ -3738,13 +2926,6 @@ _init(void) /* Register our goodies */ _device_driver.name = LINUX_KERNEL_BDE_NAME; -#if defined(BCM_ROBO_SUPPORT) -#if defined(IPROC_CMICD) - if (_gmac_dev_create()) { - return -ENODEV; - } -#endif -#endif /* defined (BCM_ROBO_SUPPORT) */ /* Configure MSI interrupt support */ use_msi = usemsi; @@ -3797,17 +2978,11 @@ _init(void) #endif #endif /* BCM_ICS */ -#ifdef BCM_ROBO_SUPPORT - probe_robo_switch(); -#endif -#if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT) +#ifdef BCM_SAND_SUPPORT sand_device_create(); #endif -#if defined(BCM_TK371X_SUPPORT) - probe_tk371x_dev(); -#endif /* * Probe for EB Bus devices. */ @@ -3863,24 +3038,6 @@ _cleanup(void) } #endif -#if defined(BCM_ROBO_SUPPORT) -#if defined(IPROC_CMICD) - if (_cca_base) { - iounmap((void *)_cca_base); - } -#endif - - if (robo) { -#if defined(KEYSTONE) || defined(IPROC_CMICD) - robo_detach(robo); -#endif /* KEYSTONE || IPROC_CMICD */ - } - if (sbh) { -#if defined(KEYSTONE) || defined(IPROC_CMICD) - ai_soc_detach(sbh); -#endif /* KEYSTONE || IPROC_CMICD */ - } -#endif for (i = 0; i < _ndevices; i++) { bde_ctrl_t *ctrl = _devices + i; @@ -3891,7 +3048,7 @@ _cleanup(void) } } } -#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT)) && (defined(__DUNE_WRX_BCM_CPU__) || defined(__DUNE_GTO_BCM_CPU__)) +#if defined(BCM_SAND_SUPPORT) && (defined(__DUNE_WRX_BCM_CPU__) || defined(__DUNE_GTO_BCM_CPU__)) if (cpu_address) { /* unmap CPU card MMIO */ iounmap(cpu_address); cpu_address = NULL; @@ -3950,7 +3107,10 @@ _pprint(void) continue; } if (ctrl->dev_type & BDE_PCI_DEV_TYPE) { - pprintf("PCI device 0x%x:0x%x:%d:0x%.8lx:0x%.8lx:%d%s\n", + pprintf("PCI device %02x:%02x.%x 0x%x:0x%x:%d:0x%.8lx:0x%.8lx:%d%s\n", + (unsigned int)ctrl->pci_device->bus->number, + PCI_SLOT(ctrl->pci_device->devfn), + PCI_FUNC(ctrl->pci_device->devfn), ctrl->pci_device->vendor, ctrl->pci_device->device, ctrl->bde_dev.rev, @@ -3991,40 +3151,6 @@ _pprint(void) return 0; } -#if USE_LINUX_BDE_MMAP -/* - * Some kernels (mainly x86) prevent mapping of kernel RAM memory to - * user space via the /dev/mem device. The function below provides a - * backdoor to mapping the DMA pool to user space via the - * /dev/linux-kernel-bde device. - */ -static int _mmap(struct file *filp, struct vm_area_struct *vma) -{ - unsigned long phys_addr = vma->vm_pgoff << PAGE_SHIFT; - unsigned long size = vma->vm_end - vma->vm_start; - - if(!_dma_range_valid(phys_addr, size)) { - return -EINVAL; - } - -#ifdef REMAP_DMA_NONCACHED - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -#endif - - if (remap_pfn_range(vma, - vma->vm_start, - vma->vm_pgoff, - size, - vma->vm_page_prot)) { - gprintk("Failed to mmap phys range 0x%lx-0x%lx to 0x%lx-0x%lx\n", - phys_addr, phys_addr + size, vma->vm_start,vma->vm_end); - return -EAGAIN; - } - - return 0; -} -#endif /* USE_LINUX_BDE_MMAP */ - /* Workaround for broken Busybox/PPC insmod */ static char _modname[] = LINUX_KERNEL_BDE_NAME; @@ -4034,9 +3160,7 @@ static gmodule_t _gmodule = { init: _init, cleanup: _cleanup, pprint: _pprint, -#if USE_LINUX_BDE_MMAP - mmap: _mmap, -#endif + mmap: _dma_mmap, }; gmodule_t * @@ -4336,7 +3460,7 @@ _interrupt_connect(int d, gprintk("%s(%d):device# = %d, irq = %d\n", __func__, __LINE__, d, ctrl->entries[i].vector); } - ret = request_irq(ctrl->entries[i].vector, _isr, 0, + ret = request_irq(ctrl->entries[i].vector, (irq_handler_t)_isr, 0, LINUX_KERNEL_BDE_NAME, ctrl); if (ret < 0) break; @@ -4358,7 +3482,7 @@ _interrupt_connect(int d, if (unlikely(debug >= 1)) gprintk("%s(%d):device# = %d, request_irq(%d)\n", __func__, __LINE__, d, iproc_cmicx_irqs[i]); - ret = request_irq(iproc_cmicx_irqs[i], _isr, + ret = request_irq(iproc_cmicx_irqs[i], (irq_handler_t)_isr, irq_flags, LINUX_KERNEL_BDE_NAME, ctrl); if (ret < 0) { gprintk("request_irq(%d) failed(%d)\n", iproc_cmicx_irqs[i], ret); @@ -4536,6 +3660,9 @@ _iproc_read(int d, uint32_t addr) } if (_devices[d].dev_type & BDE_AXI_DEV_TYPE) { + if (IHOST_GICD_REG_ADDR_VALID(d, addr)) { + return readl(IHOST_GICD_REG_ADDR_REMAP(d, addr)); + } return _iproc_ihost_read(d, addr); } @@ -4556,6 +3683,10 @@ _iproc_write(int d, uint32_t addr, uint32_t data) } if (_devices[d].dev_type & BDE_AXI_DEV_TYPE) { + if (IHOST_GICD_REG_ADDR_VALID(d, addr)) { + writel(data, IHOST_GICD_REG_ADDR_REMAP(d, addr)); + return 0; + } return _iproc_ihost_write(d, addr, data); } @@ -4626,126 +3757,7 @@ _get_cmic_ver(int d , uint32_t *ver) return -1; } -#ifdef BCM_ROBO_SUPPORT -#define SOC_ROBO_PAGE_BP 8 /* for Robo Chip only */ - -#if defined(IPROC_CMICD) -extern int ccb_mii_read(int dev_type, int phy_addr, int reg_off, uint16 *data); -extern int ccb_mii_write(int dev_type, int phy_addr, int reg_off, uint16 data); - -/* device type */ -#define MII_DEV_LOCAL 0 -#define MII_DEV_EXT 1 -#endif - -static int -_spi_read(int d, uint32 addr, uint8 *buf, int len) -{ -#if defined(KEYSTONE) || defined(IPROC_CMICD) - bde_ctrl_t *ctrl; - uint8 page, offset; -#endif -#if defined(IPROC_CMICD) - int rv = 0; - uint16 value = 0; -#endif - - if (!VALID_DEVICE(d)) { - return -1; - } - - if (!(_devices[d].dev_type & BDE_SPI_DEV_TYPE)) { - gprintk("_spi_read: Not SPI device %d, type %x\n", - d, _devices[d].dev_type); - return -1; - } - -#if defined(KEYSTONE) || defined(IPROC_CMICD) - ctrl = _devices + d; -#endif - -#if defined(IPROC_CMICD) - if (addr & SOC_EXTERNAL_PHY_BUS_CPUMDIO) { - rv = ccb_mii_read(MII_DEV_EXT, (addr >> 8) & 0xff, addr & 0xff, &value); - memcpy(buf, &value, 2); - return rv; - } -#endif - -#if defined(KEYSTONE) || defined(IPROC_CMICD) - page = (addr >> SOC_ROBO_PAGE_BP) & 0xFF; - offset = addr & 0xFF; -#endif - -#if defined(IPROC_CMICD) && defined(BCM_STARFIGHTER3_SUPPORT) - if (spi_device_found) { - ROBO_SPI_RREG(ctrl->spi_device->robo, ctrl->spi_device->cid, - page, offset, buf, (uint)len); - } else -#endif - { - ROBO_RREG(ctrl->spi_device->robo, ctrl->spi_device->cid, - page, offset, buf, (uint)len); - } - - return 0; -} - -static int -_spi_write(int d, uint32 addr, uint8 *buf, int len) -{ -#if defined(KEYSTONE) || defined(IPROC_CMICD) - bde_ctrl_t *ctrl; - uint8 page, offset; -#endif -#if defined(IPROC_CMICD) - int rv = 0; - uint16 value = 0; -#endif - if (!VALID_DEVICE(d)) { - return -1; - } - - if (!(_devices[d].dev_type & BDE_SPI_DEV_TYPE)) { - gprintk("_spi_write: Not SPI device %d, type %x\n", - d, _devices[d].dev_type); - return -1; - } - -#if defined(KEYSTONE) || defined(IPROC_CMICD) - ctrl = _devices + d; -#endif - -#if defined(IPROC_CMICD) - if (addr & SOC_EXTERNAL_PHY_BUS_CPUMDIO) { - memcpy(&value, buf, 2); - rv = ccb_mii_write(MII_DEV_EXT, (addr >> 8) & 0xff, addr & 0xff, value); - return rv; - } -#endif - -#if defined(KEYSTONE) || defined(IPROC_CMICD) - page = (addr >> SOC_ROBO_PAGE_BP) & 0xFF; - offset = addr & 0xFF; -#endif - -#if defined(IPROC_CMICD) && defined(BCM_STARFIGHTER3_SUPPORT) - if (spi_device_found) { - ROBO_SPI_WREG(ctrl->spi_device->robo, ctrl->spi_device->cid, - page, offset, buf, (uint)len); - } else -#endif - { - ROBO_WREG(ctrl->spi_device->robo, ctrl->spi_device->cid, - page, offset, buf, (uint)len); - } - - return 0; -} - -#endif - -#if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT) +#ifdef BCM_SAND_SUPPORT int lkbde_cpu_write(int d, uint32 addr, uint32 *buf) { @@ -4853,7 +3865,7 @@ lkbde_cpu_pci_register(int d) case BCM88380_DEVICE_ID: case BCM88381_DEVICE_ID: case BCM88680_DEVICE_ID: - case BCM88690_DEVICE_ID: + case BCM88800_DEVICE_ID: case BCM88470_DEVICE_ID: case BCM88470P_DEVICE_ID: case BCM88471_DEVICE_ID: @@ -4865,6 +3877,7 @@ lkbde_cpu_pci_register(int d) case BCM88270_DEVICE_ID: case BCM88272_DEVICE_ID: case BCM88273_DEVICE_ID: + case BCM88274_DEVICE_ID: case BCM88278_DEVICE_ID: case BCM8206_DEVICE_ID: case BCM88350_DEVICE_ID: @@ -4902,6 +3915,22 @@ lkbde_cpu_pci_register(int d) break; } +#ifdef BCM_DNX_SUPPORT + /*All Jericho 2 devices from 0x8690 to 0x869F*/ + if (SOC_IS_JERICHO_2_TYPE(ctrl->bde_dev.device)) { + /* Fix bar 0 address */ /* FIXME: write full phy address */ + pci_write_config_byte(ctrl->pci_device, 0x12, 0x10); + pci_write_config_byte(ctrl->pci_device, 0x13, 0x60); + + /* + * For DMA transactions - set Max_Payload_Size and + * Max_Read_Request_Size to 128 bytes. + */ + pci_write_config_byte(ctrl->pci_device, 0xb5, 0x0c); + pci_write_config_byte(ctrl->pci_device, 0xb4, 0x0); + } +#endif + /* Redo ioremap */ if (ctrl->bde_dev.base_address) { iounmap((void *)ctrl->bde_dev.base_address); @@ -4955,7 +3984,7 @@ lkbde_mem_read(int d, uint32 addr, uint32 *buf) return 0; } LKM_EXPORT_SYM(lkbde_mem_read); -#endif /* defined(BCM_PETRA_SUPPORT) */ +#endif /* BCM_SAND_SUPPORT */ static ibde_t _ibde = { name: _name, @@ -4975,13 +4004,9 @@ static ibde_t _ibde = { interrupt_disconnect: _interrupt_disconnect, l2p: _l2p, p2l: _p2l, -#if defined(BCM_ROBO_SUPPORT) - spi_read: _spi_read, - spi_write: _spi_write, -#else + NULL, NULL, -#endif /* defined(BCM_ROBO_SUPPORT) */ iproc_read: _iproc_read, iproc_write: _iproc_write, get_cmic_ver: _get_cmic_ver, @@ -5328,7 +4353,7 @@ LKM_EXPORT_SYM(lkbde_dev_state_set); LKM_EXPORT_SYM(lkbde_dev_state_get); LKM_EXPORT_SYM(lkbde_dev_instid_set); LKM_EXPORT_SYM(lkbde_dev_instid_get); -#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)) +#ifdef BCM_SAND_SUPPORT LKM_EXPORT_SYM(lkbde_cpu_write); LKM_EXPORT_SYM(lkbde_cpu_read); LKM_EXPORT_SYM(lkbde_cpu_pci_register); diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c index 32b769784c2e..eb3dc0495195 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c @@ -85,10 +85,25 @@ #if _SIMPLE_MEMORY_ALLOCATION_ == 1 #define ALLOC_METHOD_DEFAULT ALLOC_TYPE_API +#if defined(__arm__) +#define USE_DMA_MMAP_COHERENT +#define _PGPROT_NONCACHED(x) x = pgprot_noncached((x)) +#elif defined(__aarch64__ ) +#define USE_DMA_MMAP_COHERENT +#define _PGPROT_NONCACHED(x) x = pgprot_writecombine((x)) +#endif #else #define ALLOC_METHOD_DEFAULT ALLOC_TYPE_CHUNK #endif +#ifndef _PGPROT_NONCACHED +#ifdef REMAP_DMA_NONCACHED +#define _PGPROT_NONCACHED(x) x = pgprot_noncached((x)) +#else +#define _PGPROT_NONCACHED(x) +#endif +#endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) #include #define virt_to_bus virt_to_phys @@ -101,6 +116,12 @@ #define VIRT_TO_PAGE(p) virt_to_page((p)) #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) +#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((d),(p)) +#else +#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((p)) +#endif + #ifndef KMALLOC_MAX_SIZE #define KMALLOC_MAX_SIZE (1UL << (MAX_ORDER - 1 + PAGE_SHIFT)) #endif @@ -170,7 +191,6 @@ MODULE_PARM_DESC(himemaddr, #else #define DMA_MEM_DEFAULT (8 * ONE_MB) #endif -#define DMA_MEM_DEFAULT_ROBO (4 * ONE_MB) /* We try to assemble a contiguous segment from chunks of this size */ #define DMA_BLOCK_SIZE (512 * ONE_KB) @@ -203,6 +223,7 @@ static unsigned long _himemaddr = 0; static int _use_dma_mapping = 0; static LIST_HEAD(_dma_seg); +#define DMA_DEV_INDEX 0 /* Device index to allocate memory pool */ #define DMA_DEV(n) lkbde_get_dma_dev(n) #define BDE_NUM_DEVICES(t) lkbde_get_num_devices(t) @@ -545,7 +566,7 @@ _pgcleanup(void) case ALLOC_TYPE_API: if (_dma_vbase) { if (dma_debug >= 1) gprintk("freeing v=%p p=0x%lx size=0x%lx\n", _dma_vbase,(unsigned long) _dma_pbase, (unsigned long)_dma_mem_size); - dma_free_coherent(DMA_DEV(0), _dma_mem_size, _dma_vbase, _dma_pbase); + dma_free_coherent(DMA_DEV(DMA_DEV_INDEX), _dma_mem_size, _dma_vbase, _dma_pbase); } break; #endif /* _SIMPLE_MEMORY_ALLOCATION_ */ @@ -554,7 +575,7 @@ _pgcleanup(void) struct list_head *pos, *tmp; int i, ndevices; if (_use_dma_mapping) { - ndevices = BDE_NUM_DEVICES(BDE_ALL_DEVICES); + ndevices = BDE_NUM_DEVICES(BDE_SWITCH_DEVICES); for (i = 0; i < ndevices && DMA_DEV(i); i ++) { dma_unmap_single(DMA_DEV(i), (dma_addr_t)_dma_pbase, _dma_mem_size, DMA_BIDIRECTIONAL); } @@ -591,7 +612,6 @@ static void _alloc_mpool(size_t size) { unsigned long pbase = 0; - #if defined(__arm__) && !defined(CONFIG_HIGHMEM) if (_use_himem) { gprintk("DMA in high memory requires CONFIG_HIGHMEM on ARM CPUs.\n"); @@ -614,6 +634,9 @@ _alloc_mpool(size_t size) _dma_vbase = IOREMAP(_dma_pbase, size); } else { /* Get DMA memory from kernel */ + if (dma_debug >= 1) { + gprintk("Allocating DMA memory using method dmaalloc=%d\n", dmaalloc); + } switch (dmaalloc) { #if _SIMPLE_MEMORY_ALLOCATION_ case ALLOC_TYPE_API: { @@ -624,8 +647,9 @@ _alloc_mpool(size_t size) /* get a memory allocation from the kernel */ { dma_addr_t dma_handle; - if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(0), alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) { - gprintk("failed to allocate the memory pool of size 0x%lx\n", (unsigned long)alloc_size); + if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(DMA_DEV_INDEX), + alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) { + gprintk("Failed to allocate coherent memory pool of size 0x%lx\n", (unsigned long)alloc_size); return; } _cpu_pbase = pbase = dma_handle; @@ -643,14 +667,14 @@ _alloc_mpool(size_t size) case ALLOC_TYPE_CHUNK: _dma_vbase = _pgalloc(size); if (!_dma_vbase) { - gprintk("failed to allocate the memory pool of size 0x%lx\n", (unsigned long)size); + gprintk("Failed to allocate memory pool of size 0x%lx\n", (unsigned long)size); return; } _cpu_pbase = virt_to_bus(_dma_vbase); /* Use dma_map_single to obtain DMA bus address or IOVA if iommu is present. */ - if (DMA_DEV(0)) { - pbase = dma_map_single(DMA_DEV(0), _dma_vbase, size, DMA_BIDIRECTIONAL); - if (dma_mapping_error(DMA_DEV(0), pbase)) { + if (DMA_DEV(DMA_DEV_INDEX)) { + pbase = dma_map_single(DMA_DEV(DMA_DEV_INDEX), _dma_vbase, size, DMA_BIDIRECTIONAL); + if (DMA_MAPPING_ERROR(DMA_DEV(DMA_DEV_INDEX), pbase)) { gprintk("Failed to map memory at %p\n", _dma_vbase); _pgcleanup(); _dma_vbase = NULL; @@ -659,7 +683,6 @@ _alloc_mpool(size_t size) } _use_dma_mapping = 1; } else { - /* Device has not been probed. */ pbase = _cpu_pbase; } break; @@ -719,15 +742,21 @@ _dma_cleanup(void) return 0; } -void _dma_init(int robo_switch, int dev_index) +void _dma_init(int dev_index) { unsigned long pbase; - if (dev_index > 0) { - if ((_use_dma_mapping == 1) && DMA_DEV(dev_index) && _dma_vbase) { + if (dev_index > DMA_DEV_INDEX) { + if (_use_dma_mapping && DMA_DEV(dev_index) && _dma_vbase) { pbase = dma_map_single(DMA_DEV(dev_index), _dma_vbase, _dma_mem_size, DMA_BIDIRECTIONAL); - if (dma_mapping_error(DMA_DEV(dev_index), pbase)) { + if (DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) { gprintk("Failed to map memory for device %d at %p\n", dev_index, _dma_vbase); + return; + } + if (pbase != (unsigned long)_dma_pbase) { + /* Bus address/IOVA must be identical for all devices. */ + gprintk("Device %d has different pbase: %lx (should be %lx)\n", + dev_index, pbase, (unsigned long)_dma_pbase); } } return; @@ -745,10 +774,6 @@ void _dma_init(int robo_switch, int dev_index) gprintk("dmasize must be a power of 2 (1M, 2M, 4M, 8M etc.)\n"); _dma_mem_size = 0; } - } else { - if(robo_switch){ - _dma_mem_size = DMA_MEM_DEFAULT_ROBO; - } } if (himem) { @@ -775,42 +800,54 @@ void _dma_init(int robo_switch, int dev_index) _alloc_mpool(_dma_mem_size); if (_dma_vbase == NULL) { gprintk("no DMA memory available\n"); - } - else { + } else { mpool_init(); _dma_pool = mpool_create(_dma_vbase, _dma_mem_size); } } } -#if USE_LINUX_BDE_MMAP /* - * Function: _dma_range_valid + * Some kernels are configured to prevent mapping of kernel RAM memory + * into user space via the /dev/mem device. * - * Purpose: - * Check if DMA address range is valid. - * Parameters: - * phys_addr - start physical address - * size - range size - * Returns: - * 0 : not valid - * 1 : valid + * The function below provides a backdoor to mapping the DMA pool to + * user space via the BDE device file. */ -int -_dma_range_valid(unsigned long phys_addr, unsigned long size) +int _dma_mmap(struct file *filp, struct vm_area_struct *vma) { - unsigned long pool_start = _cpu_pbase; - unsigned long pool_end = pool_start + _dma_mem_size; + unsigned long phys_addr = vma->vm_pgoff << PAGE_SHIFT; + unsigned long size = vma->vm_end - vma->vm_start; - if (phys_addr < pool_start || (phys_addr + size) > pool_end) { + if (phys_addr < (unsigned long )_cpu_pbase || + (phys_addr + size) > ((unsigned long )_cpu_pbase + _dma_mem_size)) { gprintk("range 0x%lx-0x%lx outside DMA pool 0x%lx-0x%lx\n", - phys_addr, phys_addr + size, pool_start, pool_end); - return 0; + phys_addr, phys_addr + size, (unsigned long )_cpu_pbase, + (unsigned long )_cpu_pbase + _dma_mem_size); + return -EINVAL; + } + +#ifdef USE_DMA_MMAP_COHERENT + if (dmaalloc == ALLOC_TYPE_API) { + vma->vm_pgoff = 0; + return dma_mmap_coherent(DMA_DEV(DMA_DEV_INDEX), vma, (void *)_dma_vbase, phys_addr, size); } - return 1; -} #endif + _PGPROT_NONCACHED(vma->vm_page_prot); + + if (remap_pfn_range(vma, + vma->vm_start, + vma->vm_pgoff, + size, + vma->vm_page_prot)) { + gprintk("Failed to mmap phys range 0x%lx-0x%lx to 0x%lx-0x%lx\n", + phys_addr, phys_addr + size, vma->vm_start,vma->vm_end); + return -EAGAIN; + } + return 0; +} + /* * Function: _dma_pool_allocated * diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c b/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c index 7a377cd00787..13206596ee26 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c @@ -70,12 +70,31 @@ static sal_sem_t _mpool_lock; #endif #endif +#define MPOOL_BUF_SIZE 1024 +#define MPOOL_BUF_ALLOC_COUNT_MAX 16 + typedef struct mpool_mem_s { unsigned char *address; int size; + struct mpool_mem_s *prev; struct mpool_mem_s *next; } mpool_mem_t; +static int _buf_alloc_count; +static mpool_mem_t *mpool_buf[MPOOL_BUF_ALLOC_COUNT_MAX]; +static mpool_mem_t *free_list; + +#define ALLOC_INIT_MPOOL_BUF(ptr) \ + ptr = MALLOC((sizeof(mpool_mem_t) * MPOOL_BUF_SIZE)); \ + if (ptr) { \ + int i; \ + for (i = 0; i < MPOOL_BUF_SIZE - 1; i++) { \ + ptr[i].next = &ptr[i+1]; \ + } \ + ptr[MPOOL_BUF_SIZE - 1].next = NULL; \ + free_list = &ptr[0]; \ + } + /* * Function: mpool_init * @@ -116,6 +135,10 @@ mpool_alloc(mpool_handle_t pool, int size) MPOOL_LOCK(); + if (size < BCM_CACHE_LINE_BYTES) { + size = BCM_CACHE_LINE_BYTES; + } + mod = size & (BCM_CACHE_LINE_BYTES - 1); if (mod != 0 ) { size += (BCM_CACHE_LINE_BYTES - mod); @@ -131,21 +154,37 @@ mpool_alloc(mpool_handle_t pool, int size) MPOOL_UNLOCK(); return NULL; } - newptr = MALLOC(sizeof(mpool_mem_t)); - if (!newptr) { - MPOOL_UNLOCK(); - return NULL; + + if (!free_list) { + if (_buf_alloc_count == MPOOL_BUF_ALLOC_COUNT_MAX) { + MPOOL_UNLOCK(); + return NULL; + } + + ALLOC_INIT_MPOOL_BUF(mpool_buf[_buf_alloc_count]); + + if (mpool_buf[_buf_alloc_count] == NULL) { + MPOOL_UNLOCK(); + return NULL; + } + + _buf_alloc_count++; } + + newptr = free_list; + free_list = free_list->next; newptr->address = ptr->address + ptr->size; newptr->size = size; newptr->next = ptr->next; + newptr->prev = ptr; + ptr->next->prev = newptr; ptr->next = newptr; #ifdef TRACK_DMA_USAGE _dma_mem_used += size; #endif - MPOOL_UNLOCK(); + MPOOL_UNLOCK(); return newptr->address; } @@ -165,25 +204,29 @@ void mpool_free(mpool_handle_t pool, void *addr) { unsigned char *address = (unsigned char *)addr; - mpool_mem_t *ptr = pool, *prev = NULL; + mpool_mem_t *head = pool, *ptr = NULL; MPOOL_LOCK(); - - while (ptr && ptr->next) { - if (ptr->next->address == address) { + + if (!(head && head->prev)) { + MPOOL_UNLOCK(); + return; + } + + ptr = head->prev->prev; + + while (ptr && (ptr != head)) { + if (ptr->address == address) { #ifdef TRACK_DMA_USAGE - _dma_mem_used -= ptr->next->size; + _dma_mem_used -= ptr->size; #endif + ptr->prev->next = ptr->next; + ptr->next->prev = ptr->prev; + ptr->next = free_list; + free_list = ptr; break; } - ptr = ptr->next; - } - - if (ptr && ptr->next) { - prev = ptr; - ptr = ptr->next; - prev->next = ptr->next; - FREE(ptr); + ptr = ptr->prev; } MPOOL_UNLOCK(); @@ -208,34 +251,45 @@ mpool_create(void *base_ptr, int size) { mpool_mem_t *head, *tail; int mod = (int)(((unsigned long)base_ptr) & (BCM_CACHE_LINE_BYTES - 1)); + int i; MPOOL_LOCK(); + for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) { + mpool_buf[i] = NULL; + } + + _buf_alloc_count = 0; + + ALLOC_INIT_MPOOL_BUF(mpool_buf[_buf_alloc_count]); + + if (mpool_buf[_buf_alloc_count] == NULL) { + MPOOL_UNLOCK(); + return NULL; + } + + _buf_alloc_count++; + if (mod) { base_ptr = (char*)base_ptr + (BCM_CACHE_LINE_BYTES - mod); size -= (BCM_CACHE_LINE_BYTES - mod); } size &= ~(BCM_CACHE_LINE_BYTES - 1); - - head = (mpool_mem_t *)MALLOC(sizeof(mpool_mem_t)); - if (head == NULL) { - return NULL; - } - tail = (mpool_mem_t *)MALLOC(sizeof(mpool_mem_t)); - if (tail == NULL) { - FREE(head); - return NULL; - } - + head = free_list; + free_list = free_list->next; + tail = free_list; + free_list = free_list->next; + head->size = tail->size = 0; head->address = base_ptr; tail->address = head->address + size; + head->prev = tail; head->next = tail; + tail->prev = head; tail->next = NULL; MPOOL_UNLOCK(); - return head; } @@ -252,13 +306,20 @@ mpool_create(void *base_ptr, int size) int mpool_destroy(mpool_handle_t pool) { - mpool_mem_t *ptr, *next; - + int i; + MPOOL_LOCK(); - for (ptr = pool; ptr; ptr = next) { - next = ptr->next; - FREE(ptr); + if ((mpool_mem_t *)pool != mpool_buf[0]) { + MPOOL_UNLOCK(); + return 0; + } + + for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) { + if (mpool_buf[i]) { + FREE(mpool_buf[i]); + mpool_buf[i] = NULL; + } } MPOOL_UNLOCK(); @@ -285,7 +346,7 @@ mpool_usage(mpool_handle_t pool) MPOOL_LOCK(); for (ptr = pool; ptr; ptr = ptr->next) { - usage += ptr->size; + usage += ptr->size; } MPOOL_UNLOCK(); diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c index 6c7c9bb95056..370f89e022c4 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c @@ -33,9 +33,6 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) #include #endif -#ifdef KEYSTONE -#include -#endif MODULE_AUTHOR("Broadcom Corporation"); @@ -676,124 +673,10 @@ _bcm88750_interrupt(bde_ctrl_t *ctrl) #endif } -static void -_qe2k_interrupt(bde_ctrl_t *ctrl) -{ - bde_inst_resource_t *res; - - res = &_bde_inst_resource[ctrl->inst]; - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x20/sizeof(uint32)); - - atomic_set(&res->intr, 1); -#ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); -#else - wake_up_interruptible(&res->intr_wq); -#endif -} - -static void -_fe2k_interrupt(bde_ctrl_t *ctrl) -{ - bde_inst_resource_t *res; - - res = &_bde_inst_resource[ctrl->inst]; - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x18/sizeof(uint32)); /* PC_INTERRUPT_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x24/sizeof(uint32)); /* PC_ERROR0_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PC_ERROR1_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x34/sizeof(uint32)); /* PC_UNIT_MASK */ - - atomic_set(&res->intr, 1); -#ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); -#else - wake_up_interruptible(&res->intr_wq); -#endif -} - -static void -_fe2kxt_interrupt(bde_ctrl_t *ctrl) -{ - bde_inst_resource_t *res; - - res = &_bde_inst_resource[ctrl->inst]; - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PC_INTERRUPT_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x38/sizeof(uint32)); /* PC_ERROR0_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x40/sizeof(uint32)); /* PC_ERROR1_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x50/sizeof(uint32)); /* PC_UNIT_MASK */ - - atomic_set(&res->intr, 1); -#ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); -#else - wake_up_interruptible(&res->intr_wq); -#endif -} - -static void -_bme3200_interrupt(bde_ctrl_t *ctrl) -{ - bde_inst_resource_t *res; - - res = &_bde_inst_resource[ctrl->inst]; - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x54/sizeof(uint32)); /* PI_PT_ERROR0 */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x5c/sizeof(uint32)); /* PI_PT_ERROR1 */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x64/sizeof(uint32)); /* PI_PT_ERROR2 */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x6c/sizeof(uint32)); /* PI_PT_ERROR3 */ - - atomic_set(&res->intr, 1); -#ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); -#else - wake_up_interruptible(&res->intr_wq); -#endif -} - - -static void -_bm9600_interrupt(bde_ctrl_t *ctrl) -{ - bde_inst_resource_t *res; - - res = &_bde_inst_resource[ctrl->inst]; - - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x5c/sizeof(uint32)); /* PI_INTERRUPT_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0xc/sizeof(uint32)); /* PI_UNIT_INTERRUPT0_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x14/sizeof(uint32)); /* PI_UNIT_INTERRUPT1_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x1c/sizeof(uint32)); /* PI_UNIT_INTERRUPT2_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x24/sizeof(uint32)); /* PI_UNIT_INTERRUPT3_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PI_UNIT_INTERRUPT4_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x34/sizeof(uint32)); /* PI_UNIT_INTERRUPT5_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x3c/sizeof(uint32)); /* PI_UNIT_INTERRUPT6_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x44/sizeof(uint32)); /* PI_UNIT_INTERRUPT7_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x4c/sizeof(uint32)); /* PI_UNIT_INTERRUPT8_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x54/sizeof(uint32)); /* PI_UNIT_INTERRUPT9_MASK */ - - atomic_set(&res->intr, 1); -#ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); -#else - wake_up_interruptible(&res->intr_wq); -#endif -} - - - /* The actual interrupt handler of ethernet devices */ static void _ether_interrupt(bde_ctrl_t *ctrl) { -#ifdef KEYSTONE - /* - * Since the two GMAC cores are sharing the same IRQ. - * Add the checking to handle the interrupt events. - */ - if ((ctrl->devid == BCM53000_GMAC_ID)) { - if ((readl(ctrl->ba + 0x020/4) & readl(ctrl->ba + 0x024/4)) == 0) { - return; - } - } -#endif SSOC_WRITEL(0, ctrl->ba + 0x024/4); atomic_set(&_ether_interrupt_has_taken_place, 1); @@ -813,11 +696,6 @@ static struct _intr_mode_s { { (isr_f)_cmicm_interrupt, "CMICm" }, { (isr_f)_cmicd_interrupt, "CMICd" }, { (isr_f)_cmicd_cmc0_interrupt, "CMICd CMC0" }, - { (isr_f)_qe2k_interrupt, "QE2K" }, - { (isr_f)_fe2k_interrupt, "FE2K" }, - { (isr_f)_fe2kxt_interrupt, "FE2KXT" }, - { (isr_f)_bme3200_interrupt, "BME3200" }, - { (isr_f)_bm9600_interrupt, "BM9600" }, { (isr_f)_bcm88750_interrupt, "BCM88750" }, { (isr_f)_cmicx_interrupt, "CMICx" }, { NULL, NULL } @@ -845,7 +723,7 @@ _devices_init(int d) uint32 ver; uint16 device_id_mask = 0xFFF0; uint16 device_id; - int state = 0; + uint32 state = 0; (void)lkbde_dev_state_get(d, &state); if (state == BDE_DEV_STATE_REMOVED) { @@ -864,21 +742,6 @@ _devices_init(int d) } if (ctrl->dev_type & BDE_SWITCH_DEV_TYPE) { switch (user_bde->get_dev(d)->device) { - case QE2000_DEVICE_ID: - ctrl->isr = (isr_f)_qe2k_interrupt; - break; - case BCM88020_DEVICE_ID: - ctrl->isr = (isr_f)_fe2k_interrupt; - break; - case BCM88025_DEVICE_ID: - ctrl->isr = (isr_f)_fe2kxt_interrupt; - break; - case BME3200_DEVICE_ID: - ctrl->isr = (isr_f)_bme3200_interrupt; - break; - case BM9600_DEVICE_ID: - ctrl->isr = (isr_f)_bm9600_interrupt; - break; case BCM88750_DEVICE_ID: case BCM88753_DEVICE_ID: case BCM88754_DEVICE_ID: @@ -920,7 +783,7 @@ _devices_init(int d) case BCM88380_DEVICE_ID: case BCM88381_DEVICE_ID: case BCM88680_DEVICE_ID: - case BCM88690_DEVICE_ID: + case BCM88800_DEVICE_ID: case BCM88770_DEVICE_ID: case BCM88773_DEVICE_ID: case BCM88774_DEVICE_ID: @@ -938,6 +801,7 @@ _devices_init(int d) case BCM88270_DEVICE_ID: case BCM88272_DEVICE_ID: case BCM88273_DEVICE_ID: + case BCM88274_DEVICE_ID: case BCM88278_DEVICE_ID: case BCM88279_DEVICE_ID: case BCM8206_DEVICE_ID: @@ -1002,7 +866,15 @@ _devices_init(int d) } break; } - /* All Ramon devices from 0x8790 to 0x879F */ + +#ifdef BCM_DNX_SUPPORT + /*All Jericho 2 devices from 0x8690 to 0x869F*/ + if (SOC_IS_JERICHO_2_TYPE(user_bde->get_dev(d)->device)) { + ctrl->isr = (isr_f)_cmicx_interrupt; + } +#endif + + /*All Ramon devices from 0x8790 to 0x879F*/ if ((user_bde->get_dev(d)->device & BCM88790_DEVICE_ID) == BCM88790_DEVICE_ID) { ctrl->isr = (isr_f)_cmicx_interrupt; } @@ -1456,30 +1328,9 @@ _ioctl(unsigned int cmd, unsigned long arg) } break; case LUBDE_USLEEP: - sal_usleep(io.d0); - break; case LUBDE_UDELAY: - sal_udelay(io.d0); - break; case LUBDE_SEM_OP: - switch (io.d0) { - case LUBDE_SEM_OP_CREATE: - io.p0 = (bde_kernel_addr_t)sal_sem_create("", io.d1, io.d2); - break; - case LUBDE_SEM_OP_DESTROY: - sal_sem_destroy((sal_sem_t)io.p0); - break; - case LUBDE_SEM_OP_TAKE: - io.rc = sal_sem_take((sal_sem_t)io.p0, io.d2); - break; - case LUBDE_SEM_OP_GIVE: - io.rc = sal_sem_give((sal_sem_t)io.p0); - break; - default: - io.rc = LUBDE_FAIL; - break; - } - break; + return -EINVAL; case LUBDE_WRITE_IRQ_MASK: io.rc = lkbde_irq_mask_set(io.dev, io.d0, io.d1, 0); break; @@ -1499,7 +1350,7 @@ _ioctl(unsigned int cmd, unsigned long arg) case LUBDE_WRITE_REG_16BIT_BUS: io.rc = user_bde->write(io.dev, io.d0, io.d1); break; -#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)) +#ifdef BCM_SAND_SUPPORT case LUBDE_CPU_WRITE_REG: { if (lkbde_cpu_write(io.dev, io.d0, (uint32*)io.dx.buf) == -1) { diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c index e1bdcc4db0da..05253141b2ff 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c @@ -30,6 +30,8 @@ #define BAR0_PAXB_CONFIG_IND_ADDR 0x2120 #define BAR0_PAXB_CONFIG_IND_DATA 0x2124 +#define PAXB_0_CMICD_TO_PCIE_INTR_EN 0x2380 + #define BAR0_PAXB_IMAP0_0 (0x2c00) #define BAR0_PAXB_IMAP0_1 (0x2c04) #define BAR0_PAXB_IMAP0_2 (0x2c08) @@ -287,7 +289,8 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs, iproc32_write(shbde, reg, data | 0x1); } } - /* Configure MSIX interrupt page, only need for iproc ver == 0x10 */ + + /* Configure MSIX interrupt page, only need for iproc ver == 0x10 */ if ((icfg->use_msi == 2) && (icfg->iproc_ver == 0x10)) { unsigned int mask = (0x1 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT) - 1; reg = ROFFS(iproc_regs, PAXB_0_FUNC0_IMAP1_3); @@ -296,6 +299,17 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs, data |= 0x410 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT; iproc32_write(shbde, reg, data); } + + /* Disable INTx interrupt if MSI/MSIX is selected */ + reg = ROFFS(iproc_regs, PAXB_0_CMICD_TO_PCIE_INTR_EN); + data = iproc32_read(shbde, reg); + if (icfg->use_msi) { + data &= ~0x1; + } else { + data |= 0x1; + } + iproc32_write(shbde, reg, data); + return pci_num; } diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c index 3559ace7a898..0c91c3ecd5f7 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c @@ -67,6 +67,7 @@ #include #include +#include #include #include #include @@ -405,6 +406,59 @@ static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) pci_dma_mapping_error(d, a) #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) +enum { + SKBTX_HW_TSTAMP = 1 << 0, + SKBTX_SW_TSTAMP = 1 << 1, + SKBTX_IN_PROGRESS = 1 << 2, +}; +struct skb_shared_hwtstamps { + ktime_t hwtstamp; + ktime_t syststamp; +}; +struct bkn_skb_shared_info { + uint8_t tx_flags; + struct skb_shared_hwtstamps hwtstamps; +}; +#define bkn_skb_shinfo(_skb) ((struct bkn_skb_shared_info *)(unsigned char *)_skb->end) +#define bkn_skb_tx_flags(_skb) bkn_skb_shinfo(_skb)->tx_flags +static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb) +{ + return &bkn_skb_shinfo(skb)->hwtstamps; +} +void skb_tstamp_tx(struct sk_buff *orig_skb, struct skb_shared_hwtstamps *hwtstamps) +{ +} +static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) +{ +} +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +static inline ktime_t ns_to_ktime(u64 ns) +{ + static const ktime_t ktime; + return ktime; +} +#endif +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) +#include +enum { + SKBTX_HW_TSTAMP = 1 << 0, + SKBTX_SW_TSTAMP = 1 << 1, + SKBTX_IN_PROGRESS = 1 << 2, +}; +#define bkn_skb_tx_flags(_skb) skb_shinfo(_skb)->tx_flags.flags +static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) +{ +} +#else +#include +#define bkn_skb_tx_flags(_skb) skb_shinfo(_skb)->tx_flags +static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) +{ + return skb_tx_timestamp(skb); +} +#endif + #ifdef LINUX_BDE_DMA_DEVICE_SUPPORT #define DMA_DEV device #define DMA_FROMDEV DMA_FROM_DEVICE @@ -471,6 +525,9 @@ typedef struct bkn_dcb_chain_s { #define NUM_CMICX_RX_CHAN 7 #define NUM_CMICM_RX_CHAN 3 +#define FCS_SZ 4 +#define TAG_SZ 4 + /* Device control info */ typedef struct bkn_switch_info_s { struct list_head list; @@ -497,6 +554,12 @@ typedef struct bkn_switch_info_s { int dcb_type; /* DCB type */ int dcb_wsize; /* DCB size (in 32-bit words) */ int pkt_hdr_size; /* Packet header size */ + uint32_t ftmh_lb_key_ext_size; /* FTMH LB-Key Extension existence/size */ + uint32_t ftmh_stacking_ext_size; /* FTMH Stacking extension existence/size */ + uint32_t pph_base_size; /* Size of PPH base */ + uint32_t pph_lif_ext_size[8]; /* Size of PPH Lif extension header */ + uint8_t udh_enable; /* Indicates UDH existence */ + uint32_t udh_length_type[4]; /* Size of UDH header per type */ int rx_chans; /* Number of Rx channels */ uint32_t dma_hi; /* DMA higher address */ uint32_t cmic_type; /* CMIC type (CMICe or CMICm) */ @@ -516,6 +579,10 @@ typedef struct bkn_switch_info_s { uint32_t inst_id; /* Instance id of this device */ int evt_idx; /* Event queue index for this device*/ int basedev_suspended; /* Base device suspended */ + int tx_hwts; /* HW timestamp for Tx */ + int rx_hwts; /* HW timestamp for Rx */ + struct sk_buff_head tx_ptp_queue; /* Tx PTP skb queue */ + struct work_struct tx_ptp_work; /* Tx PTP work */ struct { bkn_desc_info_t desc[MAX_TX_DCBS+1]; int free; /* Number of free Tx DCBs */ @@ -574,71 +641,163 @@ typedef struct bkn_switch_info_s { } rx[NUM_RX_CHAN]; } bkn_switch_info_t; -#define BKN_DNX_HDR_MAX_SIZE 40 +/* PTCH_2 */ +#define BKN_DNX_PTCH_2_SIZE 2 +/* ITMH */ +#define BKN_DNX_ITMH_SIZE 5 +/* Modlue Header */ +#define BKN_DNX_MODULE_HEADER_SIZE 20 +/* FTMH */ +#define BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_MSB 17 +#define BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_NOF_BITS 16 +#define BKN_DNX_FTMH_PP_DSP_MSB 33 +#define BKN_DNX_FTMH_PP_DSP_NOF_BITS 8 +#define BKN_DNX_FTMH_ACTION_TYPE_MSB 43 +#define BKN_DNX_FTMH_ACTION_TYPE_NOF_BITS 2 +#define BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_MSB 73 +#define BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_NOF_BITS 1 +#define BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_MSB 74 +#define BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_NOF_BITS 1 +#define BKN_DNX_FTMH_TM_DST_EXT_PRESENT_MSB 75 +#define BKN_DNX_FTMH_TM_DST_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_MSB 76 +#define BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_NOF_BITS 1 +#define BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_MSB 77 +#define BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_NOF_BITS 1 +#define BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_MSB 78 +#define BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_NOF_BITS 1 +/* Fix Length for FTMH and Extension headers */ +#define BKN_DNX_FTMH_BASE_SIZE 10 +#define BKN_DNX_FTMH_BIER_BFR_EXT_SIZE 2 +#define BKN_DNX_FTMH_TM_DST_EXT_SIZE 3 +#define BKN_DNX_FTMH_FLOW_ID_EXT_SIZE 3 +#define BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE 6 +/* TSH */ +#define BKN_DNX_TSH_SIZE 4 +/* PPH */ +#define BKN_DNX_PPH_BASE_TYPE_9 9 +#define BKN_DNX_PPH_BASE_TYPE_10 10 +#define BKN_DNX_PPH_BASE_TYPE_12 12 +#define BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB 5 +#define BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS 16 +#define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB 53 +#define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_PPH_9_FHEI_SIZE_MSB 54 +#define BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB 56 +#define BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB 9 +#define BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS 16 +#define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB 61 +#define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_PPH_10_FHEI_SIZE_MSB 62 +#define BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB 64 +#define BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB 21 +#define BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS 18 +#define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB 77 +#define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_PPH_12_FHEI_SIZE_MSB 78 +#define BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB 80 +#define BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS 3 +/* PPH.FHEI_TYPE */ +#define BKN_DNX_PPH_FHEI_TYPE_SZ0 1 +#define BKN_DNX_PPH_FHEI_TYPE_SZ1 2 +#define BKN_DNX_PPH_FHEI_TYPE_SZ2 3 +/* FHEI */ +#define BKN_DNX_PPH_FHEI_SZ0_SIZE 3 +#define BKN_DNX_PPH_FHEI_SZ1_SIZE 5 +#define BKN_DNX_PPH_FHEI_SZ2_SIZE 8 +#define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB 0 +#define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS 27 +#define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB 27 +#define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS 9 +#define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB 36 +#define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS 4 +/* PPH Extension */ +#define BKN_DNX_PPH_LEARN_EXT_SIZE 19 +/* UDH */ +#define BKN_DNX_UDH_DATA_TYPE_0_MSB 0 +#define BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS 2 +#define BKN_DNX_UDH_DATA_TYPE_1_MSB 2 +#define BKN_DNX_UDH_DATA_TYPE_1_NOF_BITS 2 +#define BKN_DNX_UDH_DATA_TYPE_2_MSB 4 +#define BKN_DNX_UDH_DATA_TYPE_2_NOF_BITS 2 +#define BKN_DNX_UDH_DATA_TYPE_3_MSB 6 +#define BKN_DNX_UDH_DATA_TYPE_3_NOF_BITS 2 +#define BKN_DNX_UDH_BASE_SIZE 1 + +#define BKN_DPP_HDR_MAX_SIZE 40 +/* PTCH_2 */ +#define BKN_DPP_PTCH_2_SIZE 2 +/* ITMH */ +#define BKN_DPP_ITMH_SIZE 4 /* FTMH */ -#define BKN_DNX_FTMH_LB_EXT_EN 0x1 -#define BKN_DNX_FTMH_STACKING_EXT_EN 0x2 -#define BKN_DNX_FTMH_SIZE_BYTE 9 -#define BKN_DNX_FTMH_LB_EXT_SIZE_BYTE 1 -#define BKN_DNX_FTMH_STACKING_SIZE_BYTE 2 -#define BKN_DNX_FTMH_DEST_EXT_SIZE_BYTE 2 -#define BKN_DNX_FTMH_LB_EXT_SIZE_BYTE 1 -#define BKN_DNX_FTMH_PKT_SIZE_MSB 0 -#define BKN_DNX_FTMH_PKT_SIZE_NOF_BITS 14 -#define BKN_DNX_FTMH_TC_MSB 14 -#define BKN_DNX_FTMH_TC_NOF_BITS 3 -#define BKN_DNX_FTMH_SRC_SYS_PORT_MSB 17 -#define BKN_DNX_FTMH_SRC_SYS_PORT_NOF_BITS 16 -#define BKN_DNX_FTMH_EXT_DSP_EXIST_MSB 68 -#define BKN_DNX_FTMH_EXT_DSP_EXIST_NOF_BITS 1 -#define BKN_DNX_FTMH_EXT_MSB 45 -#define BKN_DNX_FTMH_EXT_NOF_BITS 2 -#define BKN_DNX_FTMH_FIRST_EXT_MSB 72 -#define BKN_DNX_FTMH_ACTION_TYPE_MSB 43 -#define BKN_DNX_FTMH_ACTION_TYPE_NOF_BITS 2 -#define BKN_DNX_FTMH_PPH_TYPE_MSB 45 -#define BKN_DNX_FTMH_PPH_TYPE_NOF_BITS 2 +#define BKN_DPP_FTMH_LB_EXT_EN 0x1 +#define BKN_DPP_FTMH_STACKING_EXT_EN 0x2 +#define BKN_DPP_FTMH_SIZE_BYTE 9 +#define BKN_DPP_FTMH_LB_EXT_SIZE_BYTE 1 +#define BKN_DPP_FTMH_STACKING_SIZE_BYTE 2 +#define BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE 2 +#define BKN_DPP_FTMH_LB_EXT_SIZE_BYTE 1 +#define BKN_DPP_FTMH_PKT_SIZE_MSB 0 +#define BKN_DPP_FTMH_PKT_SIZE_NOF_BITS 14 +#define BKN_DPP_FTMH_TC_MSB 14 +#define BKN_DPP_FTMH_TC_NOF_BITS 3 +#define BKN_DPP_FTMH_SRC_SYS_PORT_MSB 17 +#define BKN_DPP_FTMH_SRC_SYS_PORT_NOF_BITS 16 +#define BKN_DPP_FTMH_EXT_DSP_EXIST_MSB 68 +#define BKN_DPP_FTMH_EXT_DSP_EXIST_NOF_BITS 1 +#define BKN_DPP_FTMH_EXT_MSB 45 +#define BKN_DPP_FTMH_EXT_NOF_BITS 2 +#define BKN_DPP_FTMH_FIRST_EXT_MSB 72 +#define BKN_DPP_FTMH_ACTION_TYPE_MSB 43 +#define BKN_DPP_FTMH_ACTION_TYPE_NOF_BITS 2 +#define BKN_DPP_FTMH_PPH_TYPE_MSB 45 +#define BKN_DPP_FTMH_PPH_TYPE_NOF_BITS 2 + /* PPH */ -#define BKN_DNX_PPH_SIZE_BYTE 7 -#define BKN_DNX_PPH_EEI_EXTENSION_PRESENT_MSB 0 -#define BKN_DNX_PPH_EEI_EXTENSION_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_LEARN_EXENSION_PRESENT_MSB 1 -#define BKN_DNX_PPH_LEARN_EXENSION_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_FHEI_SIZE_MSB 2 -#define BKN_DNX_PPH_FHEI_SIZE_NOF_BITS 2 -#define BKN_DNX_PPH_FORWARD_CODE_MSB 4 -#define BKN_DNX_PPH_FORWARD_CODE_NOF_BITS 4 -#define BKN_DNX_PPH_VSI_MSB 22 -#define BKN_DNX_PPH_VSI_NOF_BITS 16 +#define BKN_DPP_PPH_SIZE_BYTE 7 +#define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB 0 +#define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS 1 +#define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB 1 +#define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS 1 +#define BKN_DPP_PPH_FHEI_SIZE_MSB 2 +#define BKN_DPP_PPH_FHEI_SIZE_NOF_BITS 2 +#define BKN_DPP_PPH_FORWARD_CODE_MSB 4 +#define BKN_DPP_PPH_FORWARD_CODE_NOF_BITS 4 +#define BKN_DPP_PPH_VSI_MSB 22 +#define BKN_DPP_PPH_VSI_NOF_BITS 16 /* FHEI TRAP/SNOOP 3B */ -#define BKN_DNX_PPH_FHEI_3B_SIZE_BYTE 3 -#define BKN_DNX_PPH_FHEI_5B_SIZE_BYTE 5 -#define BKN_DNX_PPH_FHEI_8B_SIZE_BYTE 8 -#define BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB 0 -#define BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS 16 -#define BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB 16 -#define BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS 8 +#define BKN_DPP_PPH_FHEI_3B_SIZE_BYTE 3 +#define BKN_DPP_PPH_FHEI_5B_SIZE_BYTE 5 +#define BKN_DPP_PPH_FHEI_8B_SIZE_BYTE 8 +#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB 0 +#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS 16 +#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB 16 +#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS 8 /* PPH extension */ -#define BKN_DNX_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE 3 -#define BKN_DNX_PPH_LEARN_EXTENSION_SIZE_BYTE 5 - +#define BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE 3 +#define BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE 5 /* ftmh action type. */ -typedef enum bkn_dnx_ftmh_action_type_e { - BKN_DNX_FTMH_ACTION_TYPE_FORWARD = 0, /* TM action is forward */ - BKN_DNX_FTMH_ACTION_TYPE_SNOOP = 1, /* TM action is snoop */ - BKN_DNX_FTMH_ACTION_TYPE_INBOUND_MIRROR = 2, /* TM action is inbound mirror. */ - BKN_DNX_FTMH_ACTION_TYPE_OUTBOUND_MIRROR = 3 /* TM action is outbound mirror. */ -}bkn_dnx_ftmh_action_type_t; +typedef enum bkn_dpp_ftmh_action_type_e { + BKN_DPP_FTMH_ACTION_TYPE_FORWARD = 0, /* TM action is forward */ + BKN_DPP_FTMH_ACTION_TYPE_SNOOP = 1, /* TM action is snoop */ + BKN_DPP_FTMH_ACTION_TYPE_INBOUND_MIRROR = 2, /* TM action is inbound mirror. */ + BKN_DPP_FTMH_ACTION_TYPE_OUTBOUND_MIRROR = 3 /* TM action is outbound mirror. */ +}bkn_dpp_ftmh_action_type_t; /* ftmh dest extension. */ -typedef struct bkn_dnx_ftmh_dest_extension_s { +typedef struct bkn_dpp_ftmh_dest_extension_s { uint8 valid; /* Set if the extension is present */ uint32_t dst_sys_port; /* Destination System Port */ -} bkn_dnx_ftmh_dest_extension_t; +} bkn_dpp_ftmh_dest_extension_t; /* dnx packet */ -typedef struct bkn_pkt_dnx_s { +typedef struct bkn_dune_system_header_info_s { uint32_t ntwrk_header_ptr; struct { uint32_t packet_size; /* Packet size in bytes */ @@ -652,8 +811,13 @@ typedef struct bkn_pkt_dnx_s { uint32_t trap_qualifier; /* RAW Data */ uint32_t trap_id; /* RAW Data */ } internal; -} bkn_dnx_packet_info; - + uint32_t system_header_size; + uint32_t ftmh_spa; /* FTMH: Source-System-Port-Aggregate*/ + uint32_t pph_forward_domain; /* PPH: Forward-Domain*/ + uint32_t fhei_qualifier; /* FHEI: Qualifier */ + uint32_t fhei_code; /* FHEI: Code */ + uint32_t fhei_type; /* FHEI: Type */ +} bkn_dune_system_header_info_t; #define PREV_IDX(_cur, _max) (((_cur) == 0) ? (_max) - 1 : (_cur) - 1) @@ -715,6 +879,8 @@ typedef struct bkn_priv_s { uint32_t vlan; uint32_t flags; uint32_t cb_user_data; + uint8_t system_headers[27]; + uint32_t system_headers_size; } bkn_priv_t; typedef struct bkn_filter_s { @@ -755,6 +921,14 @@ LIST_HEAD(_sinfo_list); static knet_skb_cb_f knet_rx_cb = NULL; static knet_skb_cb_f knet_tx_cb = NULL; static knet_filter_cb_f knet_filter_cb = NULL; +static knet_hw_tstamp_enable_cb_f knet_hw_tstamp_enable_cb = NULL; +static knet_hw_tstamp_enable_cb_f knet_hw_tstamp_disable_cb = NULL; +static knet_hw_tstamp_tx_time_get_cb_f knet_hw_tstamp_tx_time_get_cb = NULL; +static knet_hw_tstamp_tx_meta_get_cb_f knet_hw_tstamp_tx_meta_get_cb = NULL; +static knet_hw_tstamp_ptp_clock_index_cb_f knet_hw_tstamp_ptp_clock_index_cb = NULL; +static knet_hw_tstamp_rx_time_upscale_cb_f knet_hw_tstamp_rx_time_upscale_cb = NULL; +static knet_netif_cb_f knet_netif_create_cb = NULL; +static knet_netif_cb_f knet_netif_destroy_cb = NULL; /* * Thread management @@ -955,6 +1129,8 @@ static bkn_thread_ctrl_t bkn_evt_ctrl; #define CMICX_IRQ_STATr (CMICX_CMC_BASE + 0x0000106c) #define CMICX_IRQ_STAT_CLRr (CMICX_CMC_BASE + 0x00001074) #define CMICX_IRQ_ENABr 0x18013100 +#define IHOST_GIC_GIC400_GICD_ISENABLERN_5r 0x10781114 +#define IHOST_GIC_GIC400_GICD_ICENABLERN_5r 0x10781194 /* CMICx interrupts reserved for kernel handler */ #define CMICX_TXRX_IRQ_MASK 0xffffffff @@ -992,6 +1168,7 @@ static bkn_thread_ctrl_t bkn_evt_ctrl; #define CMICX_DS_CMC_DESC_DONE(ch) (0x00000001 << ((ch) * 4)) #define CMICX_DS_CMC_CHAIN_DONE(ch) (0x00000002 << ((ch) * 4)) #define CMICX_DS_CMC_CTRLD_INT(ch) (0x00000008 << ((ch) * 4)) +#define CMICX_DS_CMC_DMA_CHAIN_DONE (0x00000001) #define CMICX_DS_CMC_DMA_ACTIVE (0x00000002) #define DMA_TO_BUS_HI(dma) ((dma) | sinfo->dma_hi) @@ -1498,12 +1675,25 @@ xgsx_dma_chan_abort(bkn_switch_info_t *sinfo, int chan, int polls) static inline void xgsx_irq_mask_set(bkn_switch_info_t *sinfo, uint32_t mask) { + uint32_t irq_mask_reg = CMICX_IRQ_ENABr; + uint32_t irq_mask, irq_fmask, disable_mask; + if (sinfo->napi_poll_mode) { mask = 0; } + if (sinfo->cpu_no == 1) { + lkbde_irq_mask_get(sinfo->dev_no, &irq_mask, &irq_fmask); + disable_mask = ~mask & (irq_mask & irq_fmask); + if (disable_mask) { + lkbde_irq_mask_set(sinfo->dev_no | LKBDE_ISR2_DEV | LKBDE_IPROC_REG, + IHOST_GIC_GIC400_GICD_ICENABLERN_5r, disable_mask, CMICX_TXRX_IRQ_MASK); + } + irq_mask_reg = IHOST_GIC_GIC400_GICD_ISENABLERN_5r; + } + lkbde_irq_mask_set(sinfo->dev_no | LKBDE_ISR2_DEV | LKBDE_IPROC_REG, - CMICX_IRQ_ENABr, mask, CMICX_TXRX_IRQ_MASK); + irq_mask_reg, mask, CMICX_TXRX_IRQ_MASK); } static inline void @@ -2094,6 +2284,7 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) bkn_desc_info_t *desc; uint32_t *dcb; uint32_t resv_size = sinfo->cmic_type == 'x' ? RCPU_HDR_SIZE : RCPU_RX_ENCAP_SIZE; + uint32_t meta_size = sinfo->cmic_type == 'x' ? RCPU_RX_META_SIZE : 0; int prev; if (sinfo->rx[chan].use_rx_skb == 0) { @@ -2121,7 +2312,7 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) chan, sinfo->rx[chan].cur)); } skb = desc->skb; - desc->dma_size = rx_buffer_size; + desc->dma_size = rx_buffer_size + meta_size; #ifdef KNET_NO_AXI_DMA_INVAL /* * FIXME: Need to retain this code until iProc customers have been @@ -2166,7 +2357,7 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) } if (sinfo->cmic_type == 'x') { dcb[1] = DMA_TO_BUS_HI(desc->skb_dma >> 32); - dcb[2] |= rx_buffer_size; + dcb[2] |= rx_buffer_size + meta_size; } else { dcb[1] |= rx_buffer_size; } @@ -2327,6 +2518,37 @@ bkn_dma_abort(bkn_switch_info_t *sinfo) return 0; } +static int +device_is_dpp(bkn_switch_info_t *sinfo) +{ + int is_dpp = 0; + + is_dpp = (sinfo->dcb_type == 28) ? 1 : 0; + return is_dpp; +} + +static int +device_is_dnx(bkn_switch_info_t *sinfo) +{ + int is_dnx = 0; + + /* No EP_TO_CPU header for DNX(JR2) */ + is_dnx = ((sinfo->cmic_type == 'x') && (sinfo->pkt_hdr_size ==0)) ? 1 : 0; + return is_dnx; +} + +/* is DPP or is DNX*/ +static int +device_is_sand(bkn_switch_info_t *sinfo) +{ + int is_sand = 0; + + if (device_is_dpp(sinfo) || device_is_dnx(sinfo)) { + is_sand = 1; + } + return is_sand; +} + static bkn_filter_t * bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, void *meta, int chan, bkn_filter_t *cbf) @@ -2349,12 +2571,38 @@ bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, wsize = BYTES2WORDS(size); DBG_VERB(("Filter: size = %d (%d), data = 0x%08x, mask = 0x%08x\n", size, wsize, kf->data.w[0], kf->mask.w[0])); + + if (device_is_dnx(sinfo)) { + DBG_DUNE(("Filter: size = %d (wsize %d)\n", size, wsize)); + for (idx = 0; idx < wsize; idx++) + { + DBG_DUNE(("OOB[%d]: 0x%08x [0x%08x]\n", idx, kf->data.w[idx], kf->mask.w[idx])); + } + DBG_DUNE(("Meta Data [+ Selected Raw packet data]\n")); + for (idx = 0; idx < wsize; idx++) + { + DBG_DUNE(("Scratch[%d]: 0x%08x\n", idx, scratch.data.w[idx])); + } + } + match = 1; if (match) { - if (kf->priority < (num_rx_prio * sinfo->rx_chans)) { - if (kf->priority < (num_rx_prio * chan) || - kf->priority >= (num_rx_prio * (chan + 1))) { - match = 0; + if (device_is_sand(sinfo)) + { + /** priority 0 means no priority check */ + if (kf->priority && (kf->priority < (num_rx_prio * sinfo->rx_chans))) { + if (kf->priority < (num_rx_prio * chan) || + kf->priority >= (num_rx_prio * (chan + 1))) { + match = 0; + } + } + } + else { + if (kf->priority < (num_rx_prio * sinfo->rx_chans)) { + if (kf->priority < (num_rx_prio * chan) || + kf->priority >= (num_rx_prio * (chan + 1))) { + match = 0; + } } } } @@ -2422,6 +2670,43 @@ bkn_netif_lookup(bkn_switch_info_t *sinfo, int id) return NULL; } +static int +bkn_hw_tstamp_rx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32 *meta) +{ + struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); + uint32_t *md = meta; + uint64_t ts = 0; + + switch (sinfo->dcb_type) { + case 26: + case 32: + case 33: + ts = md[14]; + ts = ts << 32 | md[12]; + break; + case 36: + ts = md[10]; + break; + case 38: + ts = md[4] & 0xffff; + ts = ts << 32 | md[5]; + break; + default: + return -1; + } + + if (knet_hw_tstamp_rx_time_upscale_cb) { + if (knet_hw_tstamp_rx_time_upscale_cb(sinfo->dev_no, &ts) < 0) { + return -1; + } + } + + memset(shhwtstamps, 0, sizeof(*shhwtstamps)); + shhwtstamps->hwtstamp = ns_to_ktime(be64_to_cpu(ts)); + + return 0; +} + static int bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta) { @@ -2491,15 +2776,6 @@ bkn_eth_type_update(struct sk_buff *skb, int ethertype) #define BKN_DNX_BYTE_SWAP(x) ((((x) << 24)) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24))) #endif -static int -device_is_dune(bkn_switch_info_t *sinfo) -{ - int is_dune = 0; - - is_dune = (sinfo->dcb_type == 28) ? 1 : 0; - return is_dune; -} - static int packet_is_untagged(uint16_t tpid) { @@ -2513,7 +2789,7 @@ packet_is_untagged(uint16_t tpid) } static void -bkn_dnx_bitstream_set_field(uint32_t *input_buffer, uint32_t start_bit, uint32_t nof_bits, uint32_t field) +bkn_bitstream_set_field(uint32_t *input_buffer, uint32_t start_bit, uint32_t nof_bits, uint32_t field) { uint32_t place; uint32_t field_bit_i; @@ -2540,7 +2816,7 @@ bkn_dnx_bitstream_set_field(uint32_t *input_buffer, uint32_t start_bit, uint32_t } static void -bkn_dnx_bitstream_get_field(uint8_t *input_buffer, uint32_t start_bit, uint32_t nof_bits, uint32_t *output_value) +bkn_bitstream_get_field(uint8_t *input_buffer, uint32_t start_bit, uint32_t nof_bits, uint32_t *output_value) { uint32_t idx; uint32_t buf_sizes=0; @@ -2590,7 +2866,7 @@ bkn_dnx_bitstream_get_field(uint8_t *input_buffer, uint32_t start_bit, uint32_t } static void -bkn_dnx_packet_parse_ftmh(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dnx_packet_info *packet_info) +bkn_dpp_packet_parse_ftmh(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) { uint32_t header_ptr = 0; uint32_t dsp_ext_exist=0; @@ -2599,76 +2875,76 @@ bkn_dnx_packet_parse_ftmh(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dnx_ header_ptr = packet_info->ntwrk_header_ptr; /* Packet-size */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_PKT_SIZE_MSB, - BKN_DNX_FTMH_PKT_SIZE_NOF_BITS, + BKN_DPP_FTMH_PKT_SIZE_MSB, + BKN_DPP_FTMH_PKT_SIZE_NOF_BITS, &fld_val); packet_info->ftmh.packet_size = fld_val; /* Traffic-class */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_TC_MSB, - BKN_DNX_FTMH_TC_NOF_BITS, + BKN_DPP_FTMH_TC_MSB, + BKN_DPP_FTMH_TC_NOF_BITS, &fld_val); packet_info->ftmh.prio = fld_val; /* Source-system-port-aggregate */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_SRC_SYS_PORT_MSB, - BKN_DNX_FTMH_SRC_SYS_PORT_NOF_BITS, + BKN_DPP_FTMH_SRC_SYS_PORT_MSB, + BKN_DPP_FTMH_SRC_SYS_PORT_NOF_BITS, &fld_val); packet_info->ftmh.src_sys_port = fld_val; /* TM-action-type */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_ACTION_TYPE_MSB, - BKN_DNX_FTMH_ACTION_TYPE_NOF_BITS, + BKN_DPP_FTMH_ACTION_TYPE_MSB, + BKN_DPP_FTMH_ACTION_TYPE_NOF_BITS, &fld_val); packet_info->ftmh.action_type = fld_val; /* PPH-type */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_PPH_TYPE_MSB, - BKN_DNX_FTMH_PPH_TYPE_NOF_BITS, + BKN_DPP_FTMH_PPH_TYPE_MSB, + BKN_DPP_FTMH_PPH_TYPE_NOF_BITS, &fld_val); packet_info->ftmh.pph_type = fld_val; - packet_info->ntwrk_header_ptr += BKN_DNX_FTMH_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_SIZE_BYTE; DBG_DUNE(("FTMH(%d) Packet-size %d Action-type %d PPH-type %d Source-system-port 0x%x Traffic-class %d\n", packet_info->ntwrk_header_ptr, packet_info->ftmh.packet_size, packet_info->ftmh.action_type, packet_info->ftmh.pph_type, packet_info->ftmh.src_sys_port, packet_info->ftmh.prio)); /* LB-Key ext */ - if ((sinfo->pkt_hdr_size & BKN_DNX_FTMH_LB_EXT_EN) == BKN_DNX_FTMH_LB_EXT_EN) + if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_LB_EXT_EN) == BKN_DPP_FTMH_LB_EXT_EN) { - packet_info->ntwrk_header_ptr += BKN_DNX_FTMH_LB_EXT_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_LB_EXT_SIZE_BYTE; DBG_DUNE(("FTMH(%d) FTMH LB-Key Extension is present\n", packet_info->ntwrk_header_ptr)); } /* DSP ext*/ fld_val = 0; - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_EXT_DSP_EXIST_MSB, - BKN_DNX_FTMH_EXT_DSP_EXIST_NOF_BITS, + BKN_DPP_FTMH_EXT_DSP_EXIST_MSB, + BKN_DPP_FTMH_EXT_DSP_EXIST_NOF_BITS, &dsp_ext_exist); if (dsp_ext_exist) { - packet_info->ntwrk_header_ptr += BKN_DNX_FTMH_DEST_EXT_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE; DBG_DUNE(("FTMH(%d) DSP-extension-present 1\n", packet_info->ntwrk_header_ptr)); } /* stacking ext */ - if ((sinfo->pkt_hdr_size & BKN_DNX_FTMH_STACKING_EXT_EN) == BKN_DNX_FTMH_STACKING_EXT_EN) + if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_STACKING_EXT_EN) == BKN_DPP_FTMH_STACKING_EXT_EN) { - packet_info->ntwrk_header_ptr += BKN_DNX_FTMH_STACKING_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_STACKING_SIZE_BYTE; DBG_DUNE(("FTMH(%d) FTMH Stacking Extension is present\n", packet_info->ntwrk_header_ptr)); } return; } static void -bkn_dnx_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dnx_packet_info *packet_info) +bkn_dpp_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) { uint32_t header_ptr = 0; uint32_t fld_val; @@ -2680,38 +2956,38 @@ bkn_dnx_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_ header_ptr = packet_info->ntwrk_header_ptr; - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_EEI_EXTENSION_PRESENT_MSB, - BKN_DNX_PPH_EEI_EXTENSION_PRESENT_NOF_BITS, + BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB, + BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS, &eei_extension_present); - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_LEARN_EXENSION_PRESENT_MSB, - BKN_DNX_PPH_LEARN_EXENSION_PRESENT_NOF_BITS, + BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB, + BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS, &learn_extension_present); - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_FHEI_SIZE_MSB, - BKN_DNX_PPH_FHEI_SIZE_NOF_BITS, + BKN_DPP_PPH_FHEI_SIZE_MSB, + BKN_DPP_PPH_FHEI_SIZE_NOF_BITS, &fhei_size); - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_FORWARD_CODE_MSB, - BKN_DNX_PPH_FORWARD_CODE_NOF_BITS, + BKN_DPP_PPH_FORWARD_CODE_MSB, + BKN_DPP_PPH_FORWARD_CODE_NOF_BITS, &forward_code); /* 7: CPU-Trap */ is_trapped = (uint8_t)(forward_code == 7); - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_VSI_MSB, - BKN_DNX_PPH_VSI_NOF_BITS, + BKN_DPP_PPH_VSI_MSB, + BKN_DPP_PPH_VSI_NOF_BITS, &fld_val); packet_info->internal.vsi = fld_val; /* size of PPH base is 7 */ - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_SIZE_BYTE; header_ptr = packet_info->ntwrk_header_ptr; DBG_DUNE(("PPH(%d) Forward-Code %d EEI-Extension %d Learn-Extension %d VSI %d FHEI-size %d\n", packet_info->ntwrk_header_ptr, @@ -2721,38 +2997,38 @@ bkn_dnx_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_ if (is_trapped && (fhei_size == 1)) { /* CPU trap code qualifier */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB, - BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS, + BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB, + BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS, &fld_val); packet_info->internal.trap_qualifier = fld_val; /* CPU trap code */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB, - BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS, + BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB, + BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS, &fld_val); packet_info->internal.trap_id = fld_val; } switch(fhei_size) { case 1: - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_FHEI_3B_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_3B_SIZE_BYTE; break; case 2: - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_FHEI_5B_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_5B_SIZE_BYTE; break; case 3: - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_FHEI_8B_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_8B_SIZE_BYTE; break; default: break; } if (eei_extension_present) { - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE; } if (learn_extension_present) { - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_LEARN_EXTENSION_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE; } DBG_DUNE(("FHEI(%d) trap_qualifier 0x%x trap_id 0x%x\n", packet_info->ntwrk_header_ptr, packet_info->internal.trap_qualifier, packet_info->internal.trap_id)); @@ -2760,23 +3036,23 @@ bkn_dnx_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_ } static int -bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff_len, bkn_dnx_packet_info *packet_info) +bkn_dpp_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff_len, bkn_dune_system_header_info_t *packet_info) { - uint8_t hdr_buff[BKN_DNX_HDR_MAX_SIZE]; + uint8_t hdr_buff[BKN_DPP_HDR_MAX_SIZE]; uint32_t hdr_size; uint8_t has_internal = 0; if ((buff == NULL) || (packet_info == NULL)) { return -1; } - hdr_size = buff_len < BKN_DNX_HDR_MAX_SIZE ? buff_len: BKN_DNX_HDR_MAX_SIZE; + hdr_size = buff_len < BKN_DPP_HDR_MAX_SIZE ? buff_len: BKN_DPP_HDR_MAX_SIZE; memcpy(hdr_buff, buff, hdr_size); /* FTMH */ - bkn_dnx_packet_parse_ftmh(sinfo, hdr_buff, packet_info); + bkn_dpp_packet_parse_ftmh(sinfo, hdr_buff, packet_info); if (packet_info->ftmh.packet_size != (buff_len + 2)) { DBG_DUNE(("FTMH packet size verfication failed, %d-%d\n", packet_info->ftmh.packet_size, buff_len)); - memset(packet_info, 0, sizeof(bkn_dnx_packet_info)); + memset(packet_info, 0, sizeof(bkn_dune_system_header_info_t)); return -1; } switch (packet_info->ftmh.pph_type) { @@ -2798,7 +3074,7 @@ bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff } if (has_internal) { - bkn_dnx_packet_parse_internal(sinfo, &hdr_buff[0], packet_info); + bkn_dpp_packet_parse_internal(sinfo, &hdr_buff[0], packet_info); } /* FIXME: */ @@ -2807,6 +3083,398 @@ bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff return 0; } +static int +bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buf, uint32_t buf_len, bkn_dune_system_header_info_t *packet_info) +{ + uint32_t fld_val; + uint32_t hdr_size = 0; + uint32_t pkt_offset_ingress_untrapped =0; + uint8_t tm_dst_ext_present = 0; + uint8_t app_specific_ext_size = 0; + uint8_t flow_id_ext_size = 0; + uint8_t bier_bfr_ext_size = 0; + uint8_t is_pph_en = 0; + uint8_t is_tsh_en = 0; + + if ((buf == NULL) || (packet_info == NULL)) { + return -1; + } + + /* FTMH: Source-System-Port-Aggregate */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_MSB, + BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_NOF_BITS, + &fld_val); + packet_info->ftmh_spa = fld_val; + /* FTMH: PPH-Type TSH */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_MSB, + BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_NOF_BITS, + &fld_val); + is_tsh_en = fld_val; + /* FTMH: PPH-Type PPH base */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_MSB, + BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_NOF_BITS, + &fld_val); + is_pph_en = fld_val; + /* FTMH: TM-Destination-Extension-Present */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_TM_DST_EXT_PRESENT_MSB, + BKN_DNX_FTMH_TM_DST_EXT_PRESENT_NOF_BITS, + &fld_val); + tm_dst_ext_present = fld_val; + /* FTMH: Application-Specific-Extension-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_MSB, + BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_NOF_BITS, + &fld_val); + app_specific_ext_size = fld_val; + /* FTMH: Flow-ID-Extension-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_MSB, + BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_NOF_BITS, + &fld_val); + flow_id_ext_size = fld_val; + /* FTMH: BIER-BFR-Extension-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_MSB, + BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_NOF_BITS, + &fld_val); + bier_bfr_ext_size = fld_val; + + hdr_size = BKN_DNX_FTMH_BASE_SIZE; + pkt_offset_ingress_untrapped = BKN_DNX_FTMH_BASE_SIZE; + + DBG_DUNE(("FTMH(%d) source-system-port 0x%x is_tsh_en %d is_pph_en %d\n", + hdr_size, packet_info->ftmh_spa, is_tsh_en, is_pph_en)); + + /* FTMH LB-Key Extension */ + if (sinfo->ftmh_lb_key_ext_size > 0) + { + hdr_size += sinfo->ftmh_lb_key_ext_size; + DBG_DUNE(("FTMH LB-Key Extension(%d) is present\n", sinfo->ftmh_lb_key_ext_size)); + } + /* FTMH Stacking Extension */ + if (sinfo->ftmh_stacking_ext_size > 0) + { + hdr_size += sinfo->ftmh_stacking_ext_size; + DBG_DUNE(("FTMH Stacking Extension(%d) is present\n", sinfo->ftmh_stacking_ext_size)); + } + /* FTMH BIER BFR Extension */ + if (bier_bfr_ext_size > 0) + { + hdr_size += BKN_DNX_FTMH_BIER_BFR_EXT_SIZE; + DBG_DUNE(("FTMH BIER BFR Extension(2) is present\n")); + } + /* FTMH TM Destination Extension */ + if (tm_dst_ext_present > 0) + { + hdr_size += BKN_DNX_FTMH_TM_DST_EXT_SIZE; + DBG_DUNE(("FTMH TM Destination Extension(3) is present\n")); + } + /* FTMH Application Specific Extension */ + if (app_specific_ext_size > 0) + { + hdr_size += BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE; + DBG_DUNE(("FTMH Application Specific Extension(6) is present\n")); + } + /* FTMH Flow-ID Extension */ + if (flow_id_ext_size > 0) + { + hdr_size += BKN_DNX_FTMH_FLOW_ID_EXT_SIZE; + DBG_DUNE(("FTMH Flow-ID Extension(3) is present\n")); + } + + /* Given the packet is trapped to CPU */ + + /* Time-Stamp Header */ + if (is_tsh_en == TRUE) + { + hdr_size += BKN_DNX_TSH_SIZE; + DBG_DUNE(("Time-Stamp Header(4) is present\n")); + } + + /* Packet Processing Header */ + if (is_pph_en) + { + uint8_t learn_ext_present; + uint8_t fhei_size; + uint8_t lif_ext_type; + + switch (sinfo->pph_base_size) + { + case BKN_DNX_PPH_BASE_TYPE_9: + /* FTMH: Forward-Domain */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB, + BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS, + &fld_val); + packet_info->pph_forward_domain = fld_val; + /* FTMH: Learn-Extension-Present */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB, + BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS, + &fld_val); + learn_ext_present = fld_val; + /* FTMH: FHEI-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_9_FHEI_SIZE_MSB, + BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS, + &fld_val); + fhei_size = fld_val; + /* FTMH: LIF-Extension-Type */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB, + BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS, + &fld_val); + lif_ext_type = fld_val; + + hdr_size += BKN_DNX_PPH_BASE_TYPE_9; + DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", + packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); + break; + case BKN_DNX_PPH_BASE_TYPE_10: + /* FTMH: Forward-Domain */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB, + BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS, + &fld_val); + packet_info->pph_forward_domain = fld_val; + /* FTMH: Learn-Extension-Present */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB, + BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS, + &fld_val); + learn_ext_present = fld_val; + /* FTMH: FHEI-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_10_FHEI_SIZE_MSB, + BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS, + &fld_val); + fhei_size = fld_val; + /* FTMH: LIF-Extension-Type */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB, + BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS, + &fld_val); + lif_ext_type = fld_val; + + hdr_size += BKN_DNX_PPH_BASE_TYPE_10; + DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", + packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); + break; + case BKN_DNX_PPH_BASE_TYPE_12: + /* FTMH: Forward-Domain */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, + BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, + &fld_val); + packet_info->pph_forward_domain = fld_val; + /* FTMH: Learn-Extension-Present */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB, + BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS, + &fld_val); + learn_ext_present = fld_val; + /* FTMH: FHEI-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_12_FHEI_SIZE_MSB, + BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS, + &fld_val); + fhei_size = fld_val; + /* FTMH: LIF-Extension-Type */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB, + BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS, + &fld_val); + lif_ext_type = fld_val; + + hdr_size += BKN_DNX_PPH_BASE_TYPE_12; + DBG_DUNE(("PPH(12) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", + packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); + break; + default: + fhei_size = 0; + lif_ext_type = 0; + learn_ext_present = 0; + break; + } + if (fhei_size) + { + switch (fhei_size) + { + case BKN_DNX_PPH_FHEI_TYPE_SZ0: + hdr_size += BKN_DNX_PPH_FHEI_SZ0_SIZE; + DBG_DUNE(("FHEI(3) is present\n")); + break; + case BKN_DNX_PPH_FHEI_TYPE_SZ1: + /* FHEI: Code */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB, + BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS, + &fld_val); + packet_info->fhei_type = fld_val; + /* FHEI-Size == 5B, FHEI-Type == Trap/Sniff */ + if (packet_info->fhei_type == 0x5) + { + /* FHEI: Qualifier */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB, + BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS, + &fld_val); + packet_info->fhei_qualifier = fld_val; + /* FHEI: Code */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB, + BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS, + &fld_val); + packet_info->fhei_code = fld_val; + } + hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(5) is present code 0x%x qualifier 0x%x\n", packet_info->fhei_code, packet_info->fhei_qualifier)); + break; + case BKN_DNX_PPH_FHEI_TYPE_SZ2: + hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(8) is present\n")); + break; + } + } + + /* PPH LIF Extension */ + if (lif_ext_type) + { + hdr_size += sinfo->pph_lif_ext_size[lif_ext_type]; + DBG_DUNE(("PPH LIF Extension(%d) is present\n", sinfo->pph_lif_ext_size[lif_ext_type])); + } + + /* PPH Learn Extension */ + if (learn_ext_present) + { + hdr_size += BKN_DNX_PPH_LEARN_EXT_SIZE; + DBG_DUNE(("PPH Learn Extension(19) is present\n")); + } + } + + /* UDH Header */ + if (sinfo->udh_enable) + { + uint8 data_type_0; + uint8 data_type_1; + uint8 data_type_2; + uint8 data_type_3; + + DBG_DUNE(("UDH base(1) is present\n")); + + /* UDH: UDH-Data-Type[0] */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_UDH_DATA_TYPE_0_MSB, + BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS, + &fld_val); + data_type_0 = fld_val; + hdr_size += sinfo->udh_length_type[data_type_0]; + /* UDH: UDH-Data-Type[1] */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_UDH_DATA_TYPE_1_MSB, + BKN_DNX_UDH_DATA_TYPE_1_NOF_BITS, + &fld_val); + data_type_1 = fld_val; + hdr_size += sinfo->udh_length_type[data_type_1]; + /* UDH: UDH-Data-Type[2] */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_UDH_DATA_TYPE_2_MSB, + BKN_DNX_UDH_DATA_TYPE_2_NOF_BITS, + &fld_val); + data_type_2 = fld_val; + hdr_size += sinfo->udh_length_type[data_type_2]; + /* UDH: UDH-Data-Type[3] */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_UDH_DATA_TYPE_3_MSB, + BKN_DNX_UDH_DATA_TYPE_3_NOF_BITS, + &fld_val); + data_type_3 = fld_val; + hdr_size += sinfo->udh_length_type[data_type_3]; + hdr_size += BKN_DNX_UDH_BASE_SIZE; + } + + /* + * Check if fhei_type if of type trap + * There is a RISK that raw packet data is parsed and fhei_type is 0x5 by chance + */ + if (packet_info->fhei_type == 0x5) + { + /* Done for ingress trapped packets */ + packet_info->system_header_size = hdr_size; + DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); + return 0; + } + else + { + /* New generated header will be FTMH(80b), TSH(32b), PPH(96b), FHEI(40b) */ + + /* Revert packet_info except info from FTHM base header */ + packet_info->fhei_qualifier = 0; + packet_info->fhei_code = 0; + packet_info->fhei_type = 0; + hdr_size = pkt_offset_ingress_untrapped; + + /* Time-Stamp Header */ + hdr_size += BKN_DNX_TSH_SIZE; + DBG_DUNE(("Time-Stamp Header(4) is present\n")); + + /** Packet Processing Header */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, + BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, + &fld_val); + packet_info->pph_forward_domain = fld_val; + hdr_size += BKN_DNX_PPH_BASE_TYPE_12; + DBG_DUNE(("PPH(12) is present\n")); + + /* + * FHEI(Trap,40) + * 5B-FHEI format for sys_hdr_generation_profile:J2-OAM + * 8b' 0 + * 19b'oam_id + * 9b' cpu_trap_code: INGRESS_TRAP_ID is always 0 here + * 4b' type(0x5): J2-Configuration FHEI Type for CPU trap + */ + hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(5) is present\n")); + } + packet_info->system_header_size = hdr_size; + DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); + return 0; +} + + static int bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) { @@ -2824,7 +3492,8 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) int pktlen; int idx; int dcbs_done = 0; - bkn_dnx_packet_info packet_info = {0}; + bkn_dune_system_header_info_t packet_info = {0}; + uint32_t dnx_meta_data[3] = {0}; dcb_chain = sinfo->rx[chan].api_dcb_chain; if (dcb_chain == NULL) { @@ -2868,9 +3537,16 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } pkt = (uint8_t *)kernel_bde->p2l(sinfo->dev_no, (sal_paddr_t)pkt_dma); if (sinfo->cmic_type == 'x') { - meta = (uint32_t *)pkt; - err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; - meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + if (device_is_dnx(sinfo)){ + meta = &dnx_meta_data[0]; + /* get error bit from last DCB words */ + err_woff = 2; + meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } else { + meta = (uint32_t *)pkt; + err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; + meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } } else { meta = dcb; err_woff = sinfo->dcb_wsize - 1; @@ -2878,22 +3554,22 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) pktlen = dcb[sinfo->dcb_wsize-1] & SOC_DCB_KNET_COUNT_MASK; bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); - if (device_is_dune(sinfo)) { + if (device_is_dpp(sinfo)) { uint16_t tpid = 0; uint16_t vid = 0; int res = -1; - memset(&packet_info, 0, sizeof(bkn_dnx_packet_info)); - res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); + res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); if (res == 0) { if (packet_info.ftmh.action_type == 0x2) { - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); + bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); } else if (packet_info.ftmh.action_type == 0x1) { - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); + bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); } - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); + bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); + bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); + bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); pkt += packet_info.ntwrk_header_ptr; pktlen -= packet_info.ntwrk_header_ptr; bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); @@ -2919,10 +3595,25 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } } + else if (device_is_dnx(sinfo)) { + int res = -1; + res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + if (res == 0) { + bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); + bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); + bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); + bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); - if (device_is_dune(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, pkt, pktlen + packet_info.ntwrk_header_ptr, - dcb, chan, &cbf); + pkt += packet_info.system_header_size; + pktlen -= packet_info.system_header_size; + bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); + } + } + + if (device_is_dpp(sinfo)) { + filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, dcb, chan, &cbf); + } else if (device_is_dnx(sinfo)) { + filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, meta, chan, &cbf); } else { filter = bkn_match_rx_pkt(sinfo, pkt + sinfo->pkt_hdr_size, pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); @@ -3001,7 +3692,7 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } skb_copy_to_linear_data(skb, pkt, pktlen); - if (device_is_dune(sinfo)) { + if (device_is_sand(sinfo)) { /* CRC has been stripped */ skb_put(skb, pktlen); } else { @@ -3023,6 +3714,11 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } + /* Do Rx timestamping */ + if (sinfo->rx_hwts) { + bkn_hw_tstamp_rx_set(sinfo, skb, meta); + } + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { bkn_add_rcpu_encap(sinfo, skb, meta); DBG_PDMP(("After add RCPU ENCAP\n")); @@ -3095,7 +3791,8 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) int pktlen; int idx; int dcbs_done = 0; - bkn_dnx_packet_info packet_info = {0}; + bkn_dune_system_header_info_t packet_info = {0}; + uint32_t dnx_meta_data[3] = {0}; if (!sinfo->rx[chan].running) { /* Rx not ready */ @@ -3122,9 +3819,16 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) sinfo->rx[chan].pkts++; skb = desc->skb; if (sinfo->cmic_type == 'x') { - meta = (uint32_t *)skb->data; - err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; - meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + if (device_is_dnx(sinfo)){ + meta = &dnx_meta_data[0]; + /* get error bit from last DCB words */ + err_woff = 2; + meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } else { + meta = (uint32_t *)skb->data; + err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; + meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } } else { meta = dcb; err_woff = sinfo->dcb_wsize - 1; @@ -3138,23 +3842,23 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) desc->skb_dma = 0; bkn_dump_pkt(skb->data, pktlen, XGS_DMA_RX_CHAN); - if (device_is_dune(sinfo)) { + if (device_is_dpp(sinfo)) { uint16_t tpid = 0; uint16_t vid = 0; uint8_t *pkt = skb->data; int res = 0; - memset(&packet_info, 0, sizeof(bkn_dnx_packet_info)); - res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); + res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); if (res == 0) { if (packet_info.ftmh.action_type == 0x2) { - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); + bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); } else if (packet_info.ftmh.action_type == 0x1) { - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); + bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); } - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); + bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); + bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); + bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); pkt = skb->data + packet_info.ntwrk_header_ptr; /* check if vlan tag exists */ tpid = (uint16_t)((pkt[12] << 8) | pkt[13]); @@ -3178,10 +3882,29 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } } + else if (device_is_dnx(sinfo)) { + uint8_t *pkt = skb->data; + int res = -1; + + res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + if (res == 0) { + bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); + bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); + bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); + bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); - if (device_is_dune(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.ntwrk_header_ptr, + pkt += packet_info.system_header_size; + pktlen -= packet_info.ntwrk_header_ptr; + bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); + } + } + + if (device_is_dpp(sinfo)) { + filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.ntwrk_header_ptr, pktlen, dcb, chan, &cbf); + } else if (device_is_dnx(sinfo)) { + filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.system_header_size, + pktlen, meta, chan, &cbf); } else { filter = bkn_match_rx_pkt(sinfo, skb->data + sinfo->pkt_hdr_size, pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); @@ -3216,12 +3939,12 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) sinfo->rx[chan].pkts_f_netif++; if (((filter->kf.mirror_type == KCOM_DEST_T_API) && - (!device_is_dune(sinfo))) || dbg_pkt_enable) { + (!device_is_sand(sinfo))) || dbg_pkt_enable) { sinfo->rx[chan].pkts_m_api++; bkn_api_rx_copy_from_skb(sinfo, chan, desc); } - if (device_is_dune(sinfo)) { + if (device_is_dpp(sinfo)) { if (filter->kf.mirror_type == KCOM_DEST_T_API) { sinfo->rx[chan].pkts_m_api++; bkn_api_rx_copy_from_skb(sinfo, chan, desc); @@ -3232,11 +3955,22 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); /* CRC has been stripped on Dune*/ skb_put(skb, pktlen); + } else if (device_is_dnx(sinfo)) { + if (filter->kf.mirror_type == KCOM_DEST_T_API) { + sinfo->rx[chan].pkts_m_api++; + bkn_api_rx_copy_from_skb(sinfo, chan, desc); + } + /* Strip Dune headers */ + skb->data += packet_info.system_header_size; + pktlen -= packet_info.system_header_size; + bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); + /* CRC has been stripped on Dune*/ + skb_put(skb, pktlen); } else { skb_put(skb, pktlen - 4); /* Strip CRC */ } - if (sinfo->cmic_type == 'x') { + if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { skb_pull(skb, sinfo->pkt_hdr_size); } @@ -3252,7 +3986,7 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) ((u32*)skb->data)[2] = ((u32*)skb->data)[1]; ((u32*)skb->data)[1] = ((u32*)skb->data)[0]; skb_pull(skb, 4); - if (sinfo->cmic_type == 'x') { + if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { for (idx = sinfo->pkt_hdr_size / sizeof(uint32_t); idx; idx--) { meta[idx] = meta[idx - 1]; } @@ -3292,6 +4026,11 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } + /* Do Rx timestamping */ + if (sinfo->rx_hwts) { + bkn_hw_tstamp_rx_set(sinfo, skb, meta); + } + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { bkn_add_rcpu_encap(sinfo, skb, meta); DBG_PDMP(("After add RCPU ENCAP\n")); @@ -3489,6 +4228,45 @@ bkn_resume_tx(bkn_switch_info_t *sinfo) } } +static int +bkn_hw_tstamp_tx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb) +{ + struct skb_shared_hwtstamps shhwtstamps; + uint64_t ts = 0; + uint32_t hdrlen = sinfo->cmic_type == 'x' ? PKT_TX_HDR_SIZE : 0; + int port; + + if (!knet_hw_tstamp_tx_time_get_cb) { + return -1; + } + + port = KNET_SKB_CB(skb)->port; + if (knet_hw_tstamp_tx_time_get_cb(sinfo->dev_no, port, skb->data + hdrlen, &ts) < 0) { + return -1; + } + + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); + shhwtstamps.hwtstamp = ns_to_ktime(be64_to_cpu(ts)); + skb_tstamp_tx(skb, &shhwtstamps); + + return 0; +} + +static void +bkn_hw_tstamp_tx_work(struct work_struct *work) +{ + bkn_switch_info_t *sinfo = container_of(work, bkn_switch_info_t, tx_ptp_work); + struct sk_buff *skb; + + while (skb_queue_len(&sinfo->tx_ptp_queue)) { + skb = skb_dequeue(&sinfo->tx_ptp_queue); + if (bkn_hw_tstamp_tx_set(sinfo, skb) < 0) { + gprintk("Timestamp has not been taken for the current skb.\n"); + } + dev_kfree_skb_any(skb); + } +} + static int bkn_do_tx(bkn_switch_info_t *sinfo) { @@ -3515,7 +4293,12 @@ bkn_do_tx(bkn_switch_info_t *sinfo) DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, DMA_TODEV); - dev_kfree_skb_any(desc->skb); + if (bkn_skb_tx_flags(desc->skb) & SKBTX_IN_PROGRESS) { + skb_queue_tail(&sinfo->tx_ptp_queue, desc->skb); + schedule_work(&sinfo->tx_ptp_work); + } else { + dev_kfree_skb_any(desc->skb); + } desc->skb = NULL; desc->skb_dma = 0; } @@ -3926,10 +4709,16 @@ xgsx_do_dma(bkn_switch_info_t *sinfo, int budget) { int rx_dcbs_done = 0, tx_dcbs_done = 0; int chan_done, budget_chans = 0; - uint32_t irq_stat; + uint32_t irq_stat, tx_dma_stat, rx_dma_stat[NUM_CMICX_RX_CHAN]; int chan; DEV_READ32(sinfo, CMICX_IRQ_STATr, &irq_stat); + DEV_READ32(sinfo, CMICX_DMA_STATr + 0x80 * XGS_DMA_TX_CHAN, &tx_dma_stat); + for (chan = 0; chan < sinfo->rx_chans; chan++) { + DEV_READ32(sinfo, + CMICX_DMA_STATr + 0x80 * (XGS_DMA_RX_CHAN + chan), + &rx_dma_stat[chan]); + } for (chan = 0; chan < sinfo->rx_chans; chan++) { if ((irq_stat & CMICX_DS_CMC_CTRLD_INT(XGS_DMA_RX_CHAN + chan)) || @@ -3964,14 +4753,14 @@ xgsx_do_dma(bkn_switch_info_t *sinfo, int budget) continue; } - if (irq_stat & CMICX_DS_CMC_CHAIN_DONE(XGS_DMA_RX_CHAN + chan)) { + if (rx_dma_stat[chan] & CMICX_DS_CMC_DMA_CHAIN_DONE) { xgsx_dma_chain_clear(sinfo, XGS_DMA_RX_CHAN + chan); bkn_rx_chain_done(sinfo, chan); } } if ((irq_stat & CMICX_DS_CMC_CTRLD_INT(XGS_DMA_TX_CHAN)) || - (irq_stat & CMICX_DS_CMC_CHAIN_DONE(XGS_DMA_TX_CHAN))) { + (tx_dma_stat & CMICX_DS_CMC_DMA_CHAIN_DONE)) { if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN)) { xgsx_dma_desc_clear(sinfo, XGS_DMA_TX_CHAN); } else { @@ -4229,6 +5018,70 @@ bkn_set_mac_address(struct net_device *dev, void *addr) } #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) +static int +bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + bkn_priv_t *priv = netdev_priv(dev); + bkn_switch_info_t *sinfo = priv->sinfo; + struct hwtstamp_config config; + + if (cmd == SIOCSHWTSTAMP) { + if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) { + return -EFAULT; + } + + if (!knet_hw_tstamp_enable_cb || !knet_hw_tstamp_disable_cb || + priv->type != KCOM_NETIF_T_PORT) { + return -ERANGE; + } + + switch (config.tx_type) { + case HWTSTAMP_TX_OFF: + knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); + sinfo->tx_hwts = 0; + break; + case HWTSTAMP_TX_ON: + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); + sinfo->tx_hwts = 1; + break; + default: + return -ERANGE; + } + + switch (config.rx_filter) { + case HWTSTAMP_FILTER_NONE: + if (sinfo->rx_hwts) { + knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); + sinfo->rx_hwts = 0; + } + break; + default: + if (!sinfo->rx_hwts) { + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); + sinfo->rx_hwts = 1; + } + config.rx_filter = HWTSTAMP_FILTER_ALL; + break; + } + + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + if (cmd == SIOCGHWTSTAMP) { + config.flags = 0; + config.tx_type = sinfo->tx_hwts ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; + config.rx_filter = sinfo->rx_hwts ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; + + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; + } +#endif + + return -EINVAL; +} +#endif + static int bkn_change_mtu(struct net_device *dev, int new_mtu) { @@ -4354,6 +5207,44 @@ bkn_set_multicast_list(struct net_device *dev) { } +static int +bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t *meta) +{ + uint32_t *md = NULL; + + if (!knet_hw_tstamp_tx_meta_get_cb) { + return -1; + } + + KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; + knet_hw_tstamp_tx_meta_get_cb(sinfo->dev_no, skb, &md); + if (!md) { + return -1; + } + + switch (sinfo->dcb_type) { + case 26: + case 32: + case 33: + meta[2] |= md[0]; + meta[3] |= md[1]; + meta[4] |= md[2]; + meta[5] |= md[3]; + break; + case 36: + case 38: + meta[0] |= md[0]; + meta[1] |= md[1]; + meta[2] |= md[2]; + meta[3] |= md[3]; + break; + default: + return -1; + } + + return 0; +} + static int bkn_tx(struct sk_buff *skb, struct net_device *dev) { @@ -4391,8 +5282,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) uint32_t *dcb, *meta; pktdata = skb->data; - pktlen = skb->len + 4; - hdrlen = sinfo->cmic_type == 'x' ? PKT_TX_HDR_SIZE : 0; + pktlen = skb->len; + hdrlen = (sinfo->cmic_type == 'x' ) ? ((device_is_dnx(sinfo)) ? priv->system_headers_size: PKT_TX_HDR_SIZE) : 0; rcpulen = 0; sop = 0; @@ -4447,7 +5338,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (skb_header_cloned(skb)) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); - new_skb = dev_alloc_skb(pktlen + 4); + new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory\n")); priv->stats.tx_dropped++; @@ -4458,7 +5349,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } memcpy(new_skb->data, pktdata, 12); memcpy(&new_skb->data[16], &pktdata[12], pktlen - 12); - skb_put(new_skb, pktlen + 4); + skb_put(new_skb, pktlen + TAG_SZ); dev_kfree_skb_any(skb); skb = new_skb; pktdata = skb->data; @@ -4466,26 +5357,25 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } else { /* Add tag to RCPU header space */ DBG_SKB(("Expand into unused RCPU header\n")); - rcpulen -= 4; + rcpulen -= TAG_SZ; pktdata = &skb->data[rcpulen]; for (idx = 0; idx < 12; idx++) { - pktdata[idx] = pktdata[idx + 4]; + pktdata[idx] = pktdata[idx + TAG_SZ]; } } pktdata[12] = 0x81; pktdata[13] = 0x00; pktdata[14] = (priv->vlan >> 8) & 0xf; pktdata[15] = priv->vlan & 0xff; - pktlen += 4; + pktlen += TAG_SZ; } } } else { if (sinfo->cmic_type == 'x' && priv->port >= 0) { - if (skb_header_cloned(skb) || skb_headroom(skb) < hdrlen + 4 || - (sinfo->dcb_type == 36 && (unsigned long)skb->data % 4)) { + if (skb_header_cloned(skb) || skb_headroom(skb) < hdrlen + 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); - new_skb = dev_alloc_skb(pktlen + hdrlen + 4); + new_skb = dev_alloc_skb(pktlen + hdrlen + 4 + FCS_SZ); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory\n")); priv->stats.tx_dropped++; @@ -4494,7 +5384,10 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sinfo->lock, flags); return 0; } - skb_reserve(new_skb, 4); + if (!device_is_dnx(sinfo)) + { + skb_reserve(new_skb, 4); + } memcpy(new_skb->data + hdrlen, skb->data, pktlen); skb_put(new_skb, pktlen + hdrlen); dev_kfree_skb_any(skb); @@ -4511,13 +5404,14 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } if (priv->port < 0 || (priv->flags & KCOM_NETIF_F_ADD_TAG)) { + DBG_DUNE(("ADD VLAN TAG\n")); /* Need to add VLAN tag if packet is untagged */ tpid = (skb->data[hdrlen + 12] << 8) | skb->data[hdrlen + 13]; if (tpid != 0x8100) { if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); - new_skb = dev_alloc_skb(pktlen + 4); + new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory\n")); priv->stats.tx_dropped++; @@ -4529,15 +5423,15 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) memcpy(new_skb->data, skb->data, hdrlen + 12); memcpy(&new_skb->data[hdrlen + 16], &skb->data[hdrlen + 12], pktlen - hdrlen - 12); - skb_put(new_skb, pktlen + 4); + skb_put(new_skb, pktlen + TAG_SZ); dev_kfree_skb_any(skb); skb = new_skb; } else { /* Add tag to existing buffer */ DBG_SKB(("Expand Tx SKB\n")); - skb_push(skb, 4); + skb_push(skb, TAG_SZ); for (idx = 0; idx < hdrlen + 12; idx++) { - skb->data[idx] = skb->data[idx + 4]; + skb->data[idx] = skb->data[idx + TAG_SZ]; } } pktdata = skb->data; @@ -4545,7 +5439,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) pktdata[hdrlen + 13] = 0x00; pktdata[hdrlen + 14] = (priv->vlan >> 8) & 0xf; pktdata[hdrlen + 15] = priv->vlan & 0xff; - pktlen += 4; + pktlen += TAG_SZ; } } } @@ -4556,8 +5450,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (tpid == 0x8100) { taglen = 4; } - if (pktlen < (64 + taglen + hdrlen)) { - pktlen = (64 + taglen + hdrlen); + if (pktlen < (60 + taglen + hdrlen)) { + pktlen = (60 + taglen + hdrlen); if (SKB_PADTO(skb, pktlen) != 0) { DBG_WARN(("Tx drop: skb_padto failed\n")); priv->stats.tx_dropped++; @@ -4568,12 +5462,11 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } /* skb_padto may update the skb->data pointer */ pktdata = &skb->data[rcpulen]; - DBG_SKB(("Packet padded to %d bytes\n", pktlen)); } - if (pktlen > SOC_DCB_KNET_COUNT_MASK) { + if ((pktlen + FCS_SZ) > SOC_DCB_KNET_COUNT_MASK) { DBG_WARN(("Tx drop: size of pkt (%d) is out of range(%d)\n", - pktlen, SOC_DCB_KNET_COUNT_MASK)); + (pktlen + FCS_SZ), SOC_DCB_KNET_COUNT_MASK)); sinfo->tx.pkts_d_over_limit++; priv->stats.tx_dropped++; dev_kfree_skb_any(skb); @@ -4582,7 +5475,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } dcb = desc->dcb_mem; - meta = sinfo->cmic_type == 'x' ? (uint32_t *)pktdata : dcb; + meta = (sinfo->cmic_type == 'x') ? (uint32_t *)pktdata : dcb; memset(dcb, 0, sinfo->dcb_wsize * sizeof(uint32_t)); if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { /* If module header SOP is non-zero, use RCPU meta data */ @@ -4634,7 +5527,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB for DNX ITMH header\n")); - new_skb = dev_alloc_skb(pktlen + 4 + 2); + new_skb = dev_alloc_skb(pktlen + 4 + 2 + FCS_SZ); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory for DNX ITMH header\n")); priv->stats.tx_dropped++; @@ -4663,7 +5556,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB for DNX header\n")); - new_skb = dev_alloc_skb(pktlen + 2); + new_skb = dev_alloc_skb(pktlen + 2 + FCS_SZ); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory for DNX header\n")); priv->stats.tx_dropped++; @@ -4737,6 +5630,16 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) dcb[4] |= (priv->qnum & 0x3f) << 8; } break; + case 39: + if (device_is_dnx(sinfo)) { + /* + * if KCOM_NETIF_T_PORT, add MH+PTCH+ITMH header + * if KCOM_NETIF_T_VLAN, add MH+PTCH+header + */ + pktdata = skb->data; + memcpy(&pktdata[0], priv->system_headers, priv->system_headers_size); + } + break; default: dcb[2] = 0xff000000; dcb[3] = 0x00000100; @@ -4761,10 +5664,10 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) /* Restore (possibly) altered packet variables * bit0 -bit15 of dcb[1] is used to save requested byte count */ - if ((skb->len + 4) <= SOC_DCB_KNET_COUNT_MASK) { - pktlen = skb->len + 4; - if (pktlen < (64 + taglen + hdrlen)) { - pktlen = (64 + taglen + hdrlen); + if ((skb->len + FCS_SZ) <= SOC_DCB_KNET_COUNT_MASK) { + pktlen = skb->len; + if (pktlen < (60 + taglen + hdrlen)) { + pktlen = (60 + taglen + hdrlen); if (SKB_PADTO(skb, pktlen) != 0) { DBG_WARN(("Tx drop: skb_padto failed\n")); priv->stats.tx_dropped++; @@ -4776,9 +5679,12 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) DBG_SKB(("Packet padded to %d bytes after tx callback\n", pktlen)); } pktdata = skb->data; + if (sinfo->cmic_type == 'x') { + meta = (uint32_t *)pktdata; + } } else { DBG_WARN(("Tx drop: size of pkt (%d) is out of range(%d)\n", - pktlen, SOC_DCB_KNET_COUNT_MASK)); + (pktlen + FCS_SZ), SOC_DCB_KNET_COUNT_MASK)); sinfo->tx.pkts_d_over_limit++; priv->stats.tx_dropped++; sinfo->tx.pkts_d_callback++; @@ -4788,8 +5694,20 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } } + /* Do Tx timestamping */ + if (priv->port >= 0) { + if (bkn_skb_tx_flags(skb) & SKBTX_HW_TSTAMP && sinfo->tx_hwts) { + KNET_SKB_CB(skb)->port = priv->port; + bkn_hw_tstamp_tx_config(sinfo, skb, meta); + bkn_skb_tx_flags(skb) |= SKBTX_IN_PROGRESS; + } + bkn_skb_tx_timestamp(skb); + } + /* Prepare for DMA */ desc->skb = skb; + /* Add FCS bytes */ + pktlen = pktlen + FCS_SZ; desc->dma_size = pktlen; desc->skb_dma = DMA_MAP_SINGLE(sinfo->dma_dev, pktdata, desc->dma_size, @@ -4859,9 +5777,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } static void -bkn_timer(unsigned long context) +bkn_timer_func(bkn_switch_info_t *sinfo) { - bkn_switch_info_t *sinfo = (bkn_switch_info_t *)context; unsigned long flags; int chan; int restart_timer; @@ -4892,6 +5809,22 @@ bkn_timer(unsigned long context) spin_unlock_irqrestore(&sinfo->lock, flags); } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) +static void +bkn_timer(unsigned long context) +{ + bkn_switch_info_t *sinfo = (bkn_switch_info_t *)context; + return bkn_timer_func(sinfo); +} +#else +static void +bkn_timer(struct timer_list *t) +{ + bkn_switch_info_t *sinfo = from_timer(sinfo, t, timer); + return bkn_timer_func(sinfo); +} +#endif + static void bkn_rx_add_tokens(bkn_switch_info_t *sinfo, int chan) { @@ -4925,9 +5858,8 @@ bkn_rx_add_tokens(bkn_switch_info_t *sinfo, int chan) } static void -bkn_rxtick(unsigned long context) +bkn_rxtick_func(bkn_switch_info_t *sinfo) { - bkn_switch_info_t *sinfo = (bkn_switch_info_t *)context; unsigned long flags; unsigned long cur_jif, ticks; uint32_t pkt_diff; @@ -4962,6 +5894,22 @@ bkn_rxtick(unsigned long context) add_timer(&sinfo->rxtick); } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) +static void +bkn_rxtick(unsigned long context) +{ + bkn_switch_info_t *sinfo = (bkn_switch_info_t *)context; + return bkn_rxtick_func(sinfo); +} +#else +static void +bkn_rxtick(struct timer_list *t) +{ + bkn_switch_info_t *sinfo = from_timer(sinfo, t, rxtick); + return bkn_rxtick_func(sinfo); +} +#endif + static void bkn_rx_rate_config(bkn_switch_info_t *sinfo) { @@ -5041,11 +5989,17 @@ bkn_create_sinfo(int dev_no) sinfo->evt_idx = -1; spin_lock_init(&sinfo->lock); + skb_queue_head_init(&sinfo->tx_ptp_queue); + INIT_WORK(&sinfo->tx_ptp_work, bkn_hw_tstamp_tx_work); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) init_timer(&sinfo->timer); - sinfo->timer.expires = jiffies + 1; sinfo->timer.data = (unsigned long)sinfo; sinfo->timer.function = bkn_timer; +#else + timer_setup(&sinfo->timer, bkn_timer, 0); +#endif + sinfo->timer.expires = jiffies + 1; INIT_LIST_HEAD(&sinfo->tx.api_dcb_list); @@ -5063,10 +6017,14 @@ bkn_create_sinfo(int dev_no) sinfo->rx[0].use_rx_skb = 0; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) init_timer(&sinfo->rxtick); - sinfo->rxtick.expires = jiffies + 1; sinfo->rxtick.data = (unsigned long)sinfo; sinfo->rxtick.function = bkn_rxtick; +#else + timer_setup(&sinfo->rxtick, bkn_rxtick, 0); +#endif + sinfo->rxtick.expires = jiffies + 1; for (chan = 0; chan < NUM_RX_CHAN; chan++) { sinfo->rx[chan].rate_max = rx_rate[chan]; @@ -5081,7 +6039,6 @@ bkn_create_sinfo(int dev_no) return sinfo; } - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) static const struct net_device_ops bkn_netdev_ops = { .ndo_open = bkn_open, @@ -5091,7 +6048,7 @@ static const struct net_device_ops bkn_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = bkn_set_multicast_list, .ndo_set_mac_address = bkn_set_mac_address, - .ndo_do_ioctl = NULL, + .ndo_do_ioctl = bkn_ioctl, .ndo_tx_timeout = NULL, .ndo_change_mtu = bkn_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -5100,6 +6057,61 @@ static const struct net_device_ops bkn_netdev_ops = { }; #endif +static void +bkn_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) +{ + strlcpy(drvinfo->driver, "bcm-knet", sizeof(drvinfo->driver)); + snprintf(drvinfo->version, sizeof(drvinfo->version), "%d", KCOM_VERSION); + strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); + strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info)); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) +static int +bkn_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) +{ + bkn_priv_t *priv = netdev_priv(dev); + bkn_switch_info_t *sinfo = priv->sinfo; + + switch (sinfo->dcb_type) { + case 26: + case 32: + case 33: + case 36: + case 38: + info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON; + info->rx_filters = 1 << HWTSTAMP_FILTER_NONE | 1 << HWTSTAMP_FILTER_ALL; + if (knet_hw_tstamp_ptp_clock_index_cb) { + info->phc_index = knet_hw_tstamp_ptp_clock_index_cb(sinfo->dev_no); + } else { + info->phc_index = -1; + } + break; + default: + info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE; + info->phc_index = -1; + break; + } + + return 0; +} +#endif + +static const struct ethtool_ops bkn_ethtool_ops = { + .get_drvinfo = bkn_get_drvinfo, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) + .get_ts_info = bkn_get_ts_info, +#endif +}; + static struct net_device * bkn_init_ndev(u8 *mac, char *name) { @@ -5148,6 +6160,7 @@ bkn_init_ndev(u8 *mac, char *name) dev->poll_controller = bkn_poll_controller; #endif #endif + dev->ethtool_ops = &bkn_ethtool_ops; if (name && *name) { strncpy(dev->name, name, IFNAMSIZ-1); } @@ -6417,10 +7430,12 @@ bkn_knet_hw_reset(kcom_msg_hw_reset_t *kmsg, int len) /* Clean all if no channels specified */ bkn_dma_abort(sinfo); bkn_clean_dcbs(sinfo); + skb_queue_purge(&sinfo->tx_ptp_queue); } else { if (kmsg->channels & (1 << XGS_DMA_TX_CHAN)) { bkn_dma_abort_tx(sinfo); bkn_clean_tx_dcbs(sinfo); + skb_queue_purge(&sinfo->tx_ptp_queue); } for (chan = 0; chan < sinfo->rx_chans; chan++) { if (kmsg->channels & (1 << (XGS_DMA_RX_CHAN + chan))) { @@ -6464,6 +7479,10 @@ bkn_knet_hw_init(kcom_msg_hw_init_t *kmsg, int len) sinfo->rx_chans = NUM_RX_CHAN; } + DBG_DUNE(("CMIC:%c DCB:%d WSIZE:%d DMA HI: 0x%08x HDR size: %d\n", + sinfo->cmic_type, sinfo->dcb_type, sinfo->dcb_wsize, + sinfo->dma_hi, sinfo->pkt_hdr_size)); + /* Config Continuous DMA mode */ sinfo->cdma_channels = kmsg->cdma_channels & ~(~0 << (sinfo->rx_chans + 1)); @@ -6602,17 +7621,26 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) priv->vlan = kmsg->netif.vlan; if (priv->type == KCOM_NETIF_T_PORT) { priv->port = kmsg->netif.port; - memcpy(priv->itmh, kmsg->netif.itmh, 4); + if (device_is_dpp(sinfo)) { + memcpy(priv->itmh, kmsg->netif.itmh, 4); + } else if (device_is_dnx(sinfo)) { + memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); + priv->system_headers_size = kmsg->netif.system_headers_size; + } priv->qnum = kmsg->netif.qnum; } else { - if ((device_is_dune(sinfo)) && (priv->type == KCOM_NETIF_T_VLAN)) { - /* set port as SSP to PTCH */ - priv->port = kmsg->netif.port; - priv->qnum = kmsg->netif.qnum; - } - else { - priv->port = -1; - } + if (device_is_sand(sinfo)) { + if (device_is_dpp(sinfo)) { + priv->port = kmsg->netif.port; + priv->qnum = kmsg->netif.qnum; + }else if (device_is_dnx(sinfo)) { + memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); + priv->system_headers_size = kmsg->netif.system_headers_size; + } + } + else { + priv->port = -1; + } } priv->flags = kmsg->netif.flags; priv->cb_user_data = kmsg->netif.cb_user_data; @@ -6673,14 +7701,28 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) } } - spin_unlock_irqrestore(&sinfo->lock, flags); - DBG_VERB(("Assigned ID %d to Ethernet device %s\n", priv->id, dev->name)); kmsg->netif.id = priv->id; memcpy(kmsg->netif.macaddr, dev->dev_addr, 6); memcpy(kmsg->netif.name, dev->name, KCOM_NETIF_NAME_MAX - 1); + + if (knet_netif_create_cb != NULL) { + int retv = knet_netif_create_cb(kmsg->hdr.unit, &(kmsg->netif), dev); + if (retv) { + gprintk("Warning: knet_netif_create_cb() returned %d for netif '%s'\n", retv, dev->name); + } + } + + spin_unlock_irqrestore(&sinfo->lock, flags); + + if (device_is_dnx(sinfo)) { + int idx = 0; + for (idx = 0; idx < priv->system_headers_size; idx++) { + DBG_DUNE(("System Header[%d]: 0x%02x\n", idx, priv->system_headers[idx])); + } + } return sizeof(*kmsg); } @@ -6720,6 +7762,12 @@ bkn_knet_netif_destroy(kcom_msg_netif_destroy_t *kmsg, int len) return sizeof(kcom_msg_hdr_t); } + if (knet_netif_destroy_cb != NULL) { + kcom_netif_t netif; + memset(&netif, 0, sizeof(kcom_netif_t)); + netif.id = priv->id; + knet_netif_destroy_cb(kmsg->hdr.unit, &netif, priv->dev); + } list_del(&priv->list); if (priv->id < sinfo->ndev_max) { @@ -6875,6 +7923,17 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) } memset(filter, 0, sizeof(*filter)); memcpy(&filter->kf, &kmsg->filter, sizeof(filter->kf)); + + if (device_is_dnx(sinfo)) { + /* Information to parser Dune system headers */ + sinfo->ftmh_lb_key_ext_size = kmsg->filter.ftmh_lb_key_ext_size; + sinfo->ftmh_stacking_ext_size = kmsg->filter.ftmh_stacking_ext_size; + sinfo->pph_base_size = kmsg->filter.pph_base_size; + memcpy(sinfo->pph_lif_ext_size, kmsg->filter.pph_lif_ext_size, sizeof(sinfo->pph_lif_ext_size)); + sinfo->udh_enable = kmsg->filter.udh_enable; + memcpy(sinfo->udh_length_type, kmsg->filter.udh_length_type, sizeof(sinfo->udh_length_type)); + } + filter->kf.id = id; /* Add according to priority */ @@ -6898,6 +7957,20 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) DBG_VERB(("Created filter ID %d (%s).\n", filter->kf.id, filter->kf.desc)); + if (device_is_dnx(sinfo)) { + int idx, wsize; + wsize = BYTES2WORDS(filter->kf.oob_data_size + filter->kf.pkt_data_size); + DBG_DUNE(("Filter: oob_data_size = %d pkt_data_size=%d wsize %d\n", filter->kf.oob_data_size, filter->kf.pkt_data_size, wsize)); + for (idx = 0; idx < wsize; idx++) + { + DBG_DUNE(("OOB[%d]: 0x%08x [0x%08x]\n", idx, filter->kf.data.w[idx], filter->kf.mask.w[idx])); + } + DBG_DUNE(("DNX system headers parameters:LB_KEY_EXT %d, STK_EXT %d, PPH_BASE %d, LIF_EXT %d %d %d, UDH_ENA %d, %d %d %d %d\n", + sinfo->ftmh_lb_key_ext_size, sinfo->ftmh_stacking_ext_size, sinfo->pph_base_size, + sinfo->pph_lif_ext_size[1],sinfo->pph_lif_ext_size[2], sinfo->pph_lif_ext_size[3], + sinfo->udh_enable, sinfo->udh_length_type[0], sinfo->udh_length_type[1], sinfo->udh_length_type[2], sinfo->udh_length_type[3])); + } + return len; } @@ -7252,10 +8325,14 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) if (sinfo && (sinfo->inst_id != 0) && ((sinfo->inst_id & (1 << dev_evt)) == 0)) { - DBG_INST((" %s skip dev(%d)\n",__FUNCTION__,dev_evt)); + DBG_INST((" %s skip dev(%d)\n",__FUNCTION__,dev_no)); continue; } + if (sinfo->evt_idx == -1) { + /* Event queue is not ready yet */ + continue; + } if (sinfo && sinfo->dma_events) { DBG_EVT(("Next DMA events (0x%08x)\n", sinfo->dma_events)); kmsg->hdr.unit = sinfo->dev_no; @@ -7269,9 +8346,11 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) break; } - if (dev_no == last_dev_no) { + if ((dev_no == last_dev_no) || + (_bkn_multi_inst && (dev_no == dev_evt))) { evt = &_bkn_evt[sinfo->evt_idx]; - DBG_INST(("wait queue index %d\n",sinfo->evt_idx)); + DBG_INST(("dev_no %d dev_evt %d wait queue index %d\n", + dev_no, dev_evt, sinfo->evt_idx)); wait_event_interruptible(evt->evt_wq, evt->evt_wq_get != evt->evt_wq_put); DBG_VERB(("Event thread wakeup\n")); @@ -7367,6 +8446,7 @@ _cleanup(void) spin_lock_irqsave(&sinfo->lock, flags); bkn_clean_dcbs(sinfo); + skb_queue_purge(&sinfo->tx_ptp_queue); spin_unlock_irqrestore(&sinfo->lock, flags); } @@ -7671,6 +8751,68 @@ gmodule_get(void) return &_gmodule; } +/* + * Get DCB type and other HW info + */ +int +bkn_hw_info_get(int unit, knet_hw_info_t *hw_info) +{ + bkn_switch_info_t *sinfo; + sinfo = bkn_sinfo_from_unit(unit); + if (sinfo == NULL) { + gprintk("Warning: unknown unit: %d\n", unit); + return (-1); + } + + hw_info->cmic_type = sinfo->cmic_type; + hw_info->dcb_type = sinfo->dcb_type; + hw_info->dcb_size = WORDS2BYTES(sinfo->dcb_wsize); + hw_info->pkt_hdr_size = sinfo->pkt_hdr_size; + hw_info->cdma_channels = sinfo->cdma_channels; + + return (0); +} + +int +bkn_netif_create_cb_register(knet_netif_cb_f netif_cb) +{ + if (knet_netif_create_cb != NULL) { + return -1; + } + knet_netif_create_cb = netif_cb; + return 0; +} + +int +bkn_netif_create_cb_unregister(knet_netif_cb_f netif_cb) +{ + if (netif_cb != NULL && knet_netif_create_cb != netif_cb) { + return -1; + } + knet_netif_create_cb = NULL; + return 0; +} + +int +bkn_netif_destroy_cb_register(knet_netif_cb_f netif_cb) +{ + if (knet_netif_destroy_cb != NULL) { + return -1; + } + knet_netif_destroy_cb = netif_cb; + return 0; +} + +int +bkn_netif_destroy_cb_unregister(knet_netif_cb_f netif_cb) +{ + if (netif_cb != NULL && knet_netif_destroy_cb != netif_cb) { + return -1; + } + knet_netif_destroy_cb = NULL; + return 0; +} + /* * Call-back interfaces for other Linux kernel drivers. * @@ -7679,6 +8821,11 @@ gmodule_get(void) * * The Tx call-back allows an external module to modify SKB contents * before it is injected inot the switch. + * + * The HW timestamp callbacks invoke an external module to enable, disable + * HW timestamp on a specific port which is indicated while the netif is + * created through KNET API. KNET can also get device-specific SOBMH and + * timestamp for a Tx PTP packet through these callbacks. */ int @@ -7741,9 +8888,152 @@ bkn_filter_cb_unregister(knet_filter_cb_f filter_cb) return 0; } +int +bkn_hw_tstamp_enable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb) +{ + if (knet_hw_tstamp_enable_cb != NULL) { + return -1; + } + knet_hw_tstamp_enable_cb = hw_tstamp_enable_cb; + return 0; +} + +int +bkn_hw_tstamp_enable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb) +{ + if (hw_tstamp_enable_cb == NULL || + knet_hw_tstamp_enable_cb != hw_tstamp_enable_cb) { + return -1; + } + knet_hw_tstamp_enable_cb = NULL; + return 0; +} + +int +bkn_hw_tstamp_disable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb) +{ + if (knet_hw_tstamp_disable_cb != NULL) { + return -1; + } + knet_hw_tstamp_disable_cb = hw_tstamp_disable_cb; + return 0; +} + +int +bkn_hw_tstamp_disable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb) +{ + if (hw_tstamp_disable_cb == NULL || + knet_hw_tstamp_disable_cb != hw_tstamp_disable_cb) { + return -1; + } + knet_hw_tstamp_disable_cb = NULL; + return 0; +} + +int +bkn_hw_tstamp_tx_time_get_cb_register(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb) +{ + if (knet_hw_tstamp_tx_time_get_cb != NULL) { + return -1; + } + knet_hw_tstamp_tx_time_get_cb = hw_tstamp_tx_time_get_cb; + return 0; +} + +int +bkn_hw_tstamp_tx_time_get_cb_unregister(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb) +{ + if (hw_tstamp_tx_time_get_cb == NULL || + knet_hw_tstamp_tx_time_get_cb != hw_tstamp_tx_time_get_cb) { + return -1; + } + knet_hw_tstamp_tx_time_get_cb = NULL; + return 0; +} + +int +bkn_hw_tstamp_tx_meta_get_cb_register(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb) +{ + if (knet_hw_tstamp_tx_meta_get_cb != NULL) { + return -1; + } + knet_hw_tstamp_tx_meta_get_cb = hw_tstamp_tx_meta_get_cb; + return 0; +} + +int +bkn_hw_tstamp_tx_meta_get_cb_unregister(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb) +{ + if (hw_tstamp_tx_meta_get_cb == NULL || + knet_hw_tstamp_tx_meta_get_cb != hw_tstamp_tx_meta_get_cb) { + return -1; + } + knet_hw_tstamp_tx_meta_get_cb = NULL; + return 0; +} + +int +bkn_hw_tstamp_ptp_clock_index_cb_register(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb) +{ + if (knet_hw_tstamp_ptp_clock_index_cb != NULL) { + return -1; + } + knet_hw_tstamp_ptp_clock_index_cb = hw_tstamp_ptp_clock_index_cb; + return 0; +} + +int +bkn_hw_tstamp_ptp_clock_index_cb_unregister(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb) +{ + if (hw_tstamp_ptp_clock_index_cb == NULL || + knet_hw_tstamp_ptp_clock_index_cb != hw_tstamp_ptp_clock_index_cb) { + return -1; + } + knet_hw_tstamp_ptp_clock_index_cb = NULL; + return 0; +} + +int +bkn_hw_tstamp_rx_time_upscale_cb_register(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb) +{ + if (knet_hw_tstamp_rx_time_upscale_cb != NULL) { + return -1; + } + knet_hw_tstamp_rx_time_upscale_cb = hw_tstamp_rx_time_upscale_cb; + return 0; +} + +int +bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb) +{ + if (hw_tstamp_rx_time_upscale_cb == NULL || + knet_hw_tstamp_rx_time_upscale_cb != hw_tstamp_rx_time_upscale_cb) { + return -1; + } + knet_hw_tstamp_rx_time_upscale_cb = NULL; + return 0; +} + LKM_EXPORT_SYM(bkn_rx_skb_cb_register); LKM_EXPORT_SYM(bkn_rx_skb_cb_unregister); LKM_EXPORT_SYM(bkn_tx_skb_cb_register); LKM_EXPORT_SYM(bkn_tx_skb_cb_unregister); LKM_EXPORT_SYM(bkn_filter_cb_register); LKM_EXPORT_SYM(bkn_filter_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_enable_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_enable_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_disable_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_disable_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_tx_time_get_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_tx_time_get_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_tx_meta_get_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_tx_meta_get_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_ptp_clock_index_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_ptp_clock_index_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_rx_time_upscale_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_rx_time_upscale_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_info_get); +LKM_EXPORT_SYM(bkn_netif_create_cb_register); +LKM_EXPORT_SYM(bkn_netif_create_cb_unregister); +LKM_EXPORT_SYM(bkn_netif_destroy_cb_register); +LKM_EXPORT_SYM(bkn_netif_destroy_cb_unregister); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h index 760690b3fb9d..477c037a0c43 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h @@ -39,14 +39,17 @@ typedef struct { * Call-back interfaces for other Linux kernel drivers. */ #include +#include +#include typedef struct { uint32 netif_user_data; uint32 filter_user_data; uint16 dcb_type; + int port; } knet_skb_cb_t; -#define KNET_SKB_CB(__skb) ((knet_skb_cb_t *)&((__skb)->cb[0])) +#define KNET_SKB_CB(_skb) ((knet_skb_cb_t *)_skb->cb) typedef struct sk_buff * (*knet_skb_cb_f)(struct sk_buff *skb, int dev_no, void *meta); @@ -55,6 +58,21 @@ typedef int (*knet_filter_cb_f)(uint8_t *pkt, int size, int dev_no, void *meta, int chan, kcom_filter_t *filter); +typedef int +(*knet_hw_tstamp_enable_cb_f)(int dev_no, int port); + +typedef int +(*knet_hw_tstamp_tx_time_get_cb_f)(int dev_no, int port, uint8_t *pkt, uint64_t *ts); + +typedef int +(*knet_hw_tstamp_tx_meta_get_cb_f)(int dev_no, struct sk_buff *skb, uint32_t **md); + +typedef int +(*knet_hw_tstamp_ptp_clock_index_cb_f)(int dev_no); + +typedef int +(*knet_hw_tstamp_rx_time_upscale_cb_f)(int dev_no, uint64_t *ts); + extern int bkn_rx_skb_cb_register(knet_skb_cb_f rx_cb); @@ -73,6 +91,68 @@ bkn_filter_cb_register(knet_filter_cb_f filter_cb); extern int bkn_filter_cb_unregister(knet_filter_cb_f filter_cb); -#endif +extern int +bkn_hw_tstamp_enable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb); + +extern int +bkn_hw_tstamp_enable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb); + +extern int +bkn_hw_tstamp_disable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb); + +extern int +bkn_hw_tstamp_disable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb); + +extern int +bkn_hw_tstamp_tx_time_get_cb_register(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb); + +extern int +bkn_hw_tstamp_tx_time_get_cb_unregister(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb); + +extern int +bkn_hw_tstamp_tx_meta_get_cb_register(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb); + +extern int +bkn_hw_tstamp_tx_meta_get_cb_unregister(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb); + +extern int +bkn_hw_tstamp_ptp_clock_index_cb_register(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb); + +extern int +bkn_hw_tstamp_ptp_clock_index_cb_unregister(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb); + +extern int +bkn_hw_tstamp_rx_time_upscale_cb_register(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb); + +extern int +bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb); + +typedef struct { + uint8 cmic_type; + uint8 dcb_type; + uint8 dcb_size; + uint8 pkt_hdr_size; + uint32 cdma_channels; +} knet_hw_info_t; + +extern int +bkn_hw_info_get(int unit, knet_hw_info_t *hw_info); + +typedef int +(*knet_netif_cb_f)(int unit, kcom_netif_t *netif, struct net_device *dev); + +extern int +bkn_netif_create_cb_register(knet_netif_cb_f netif_cb); + +extern int +bkn_netif_create_cb_unregister(knet_netif_cb_f netif_cb); + +extern int +bkn_netif_destroy_cb_register(knet_netif_cb_f netif_cb); + +extern int +bkn_netif_destroy_cb_unregister(knet_netif_cb_f netif_cb); + +#endif /* __KERNEL__ */ #endif /* __LINUX_BCM_KNET_H__ */ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h new file mode 100644 index 000000000000..57c000785e9c --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h @@ -0,0 +1,24 @@ +#ifndef __NET_PSAMPLE_H +#define __NET_PSAMPLE_H + +#include +#include +#include +#include + +struct psample_group { + struct list_head list; + struct net *net; + u32 group_num; + u32 refcount; + u32 seq; +}; + +extern struct psample_group *psample_group_get(struct net *net, u32 group_num); +extern void psample_group_put(struct psample_group *group); + +extern void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, + u32 trunc_size, int in_ifindex, int out_ifindex, + u32 sample_rate); + +#endif /* __NET_PSAMPLE_H */ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h new file mode 100644 index 000000000000..ed48996ec0e8 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h @@ -0,0 +1,35 @@ +#ifndef __UAPI_PSAMPLE_H +#define __UAPI_PSAMPLE_H + +enum { + /* sampled packet metadata */ + PSAMPLE_ATTR_IIFINDEX, + PSAMPLE_ATTR_OIFINDEX, + PSAMPLE_ATTR_ORIGSIZE, + PSAMPLE_ATTR_SAMPLE_GROUP, + PSAMPLE_ATTR_GROUP_SEQ, + PSAMPLE_ATTR_SAMPLE_RATE, + PSAMPLE_ATTR_DATA, + + /* commands attributes */ + PSAMPLE_ATTR_GROUP_REFCOUNT, + + __PSAMPLE_ATTR_MAX +}; + +enum psample_command { + PSAMPLE_CMD_SAMPLE, + PSAMPLE_CMD_GET_GROUP, + PSAMPLE_CMD_NEW_GROUP, + PSAMPLE_CMD_DEL_GROUP, +}; + +/* Can be overridden at runtime by module option */ +#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1) + +#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config" +#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets" +#define PSAMPLE_GENL_NAME "psample" +#define PSAMPLE_GENL_VERSION 1 + +#endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile index d7ca56cd5701..2a167bb9e811 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile @@ -36,7 +36,9 @@ KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko build: $(MODULE) $(KMODULE) endif -KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers +ifeq ($(BUILD_PSAMPLE),1) +KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../psample/kernel_module/Module.symvers +endif # BCM Network Device diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c index da221f9f453a..89d1087212c7 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c @@ -1,5 +1,5 @@ /* - * Copyright 2017 Broadcom + * Copyright 2017-2019 Broadcom * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -45,17 +45,20 @@ #include #include +/* Enable sflow sampling using psample */ +#ifdef PSAMPLE_SUPPORT +#include "psample-cb.h" +#endif + MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom Linux KNET Call-Back Driver"); MODULE_LICENSE("GPL"); - -static int debug; +int debug; LKM_MOD_PARAM(debug, "i", int, 0); MODULE_PARM_DESC(debug, "Debug level (default 0)"); - /* Module Information */ #define MODULE_MAJOR 121 #define MODULE_NAME "linux-knet-cb" @@ -63,8 +66,10 @@ MODULE_PARM_DESC(debug, /* set KNET_CB_DEBUG for debug info */ #define KNET_CB_DEBUG -#define FILTER_TAG_STRIP 0 -#define FILTER_TAG_KEEP 1 +/* These below need to match incoming enum values */ +#define FILTER_TAG_STRIP 0 +#define FILTER_TAG_KEEP 1 +#define FILTER_TAG_ORIGINAL 2 /* Maintain tag strip statistics */ struct strip_stats_s { @@ -105,7 +110,7 @@ strip_vlan_tag(struct sk_buff *skb) * * DCB type 14: word 12, bits 10.11 * DCB type 19, 20, 21, 22, 30: word 12, bits 10..11 - * DCB type 23, 29: word 13, bits 0..1 + * DCB type 23, 29: word 13, bits 0..1 * DCB type 31, 34, 37: word 13, bits 0..1 * DCB type 26, 32, 33, 35: word 13, bits 0..1 * @@ -150,7 +155,7 @@ get_tag_status(int dcb_type, void *meta) { /* untested */ /* TH3 only parses outer tag. */ - const int tag_map[4] = { 0, 2, -1, -1 }; + const int tag_map[4] = { 0, 2, -1, -1 }; tag_status = tag_map[(dcb[9] >> 13) & 0x3]; } break; @@ -162,7 +167,7 @@ get_tag_status(int dcb_type, void *meta) if (debug & 0x1) { gprintk("%s; DCB Type: %d; tag status: %d\n", __func__, dcb_type, tag_status); } -#endif +#endif return tag_status; } @@ -183,12 +188,12 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) if (debug & 0x1) { gprintk("%s Enter; netif Flags: %08X filter_flags %08X \n", __func__, netif_flags, filter_flags); - } + } #endif /* KNET implements this already */ if (filter_flags == FILTER_TAG_KEEP) - { +{ strip_stats.skipped++; return skb; } @@ -217,8 +222,17 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) return skb; } + if (filter_flags == FILTER_TAG_ORIGINAL) + { + /* If untagged or single inner, strip the extra tag that knet + keep tag will add. */ + if (tag_status < 2) + { + strip_tag = 1; + } + } strip_stats.checked++; - + if (strip_tag) { #ifdef KNET_CB_DEBUG if (debug & 0x1) { @@ -235,7 +249,6 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) } } #endif - return skb; } @@ -250,16 +263,50 @@ strip_tag_tx_cb(struct sk_buff *skb, int dev_no, void *meta) /* Filter callback not used */ static int strip_tag_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, - int chan, kcom_filter_t *kf) + int chan, kcom_filter_t *kf) { /* Pass through for now */ return 0; } +static int +knet_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, + int chan, kcom_filter_t *kf) +{ + /* check for filter callback handler */ +#ifdef PSAMPLE_SUPPORT + if (strncmp(kf->desc, PSAMPLE_CB_NAME, KCOM_FILTER_DESC_MAX) == 0) { + return psample_filter_cb (pkt, size, dev_no, meta, chan, kf); + } +#endif + return strip_tag_filter_cb (pkt, size, dev_no, meta, chan, kf); +} + +static int +knet_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) +{ + int retv = 0; +#ifdef PSAMPLE_SUPPORT + retv = psample_netif_create_cb(unit, netif, dev); +#endif + return retv; +} + +static int +knet_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) +{ + int retv = 0; +#ifdef PSAMPLE_SUPPORT + retv = psample_netif_destroy_cb(unit, netif, dev); +#endif + return retv; +} + /* * Get statistics. * % cat /proc/linux-knet-cb */ + static int _pprint(void) { @@ -275,19 +322,40 @@ static int _cleanup(void) { bkn_rx_skb_cb_unregister(strip_tag_rx_cb); - bkn_tx_skb_cb_unregister(strip_tag_tx_cb); - bkn_filter_cb_unregister(strip_tag_filter_cb); + /* strip_tag_tx_cb is currently a no-op, so no need to unregister */ + if (0) + { + bkn_tx_skb_cb_unregister(strip_tag_tx_cb); + } + bkn_filter_cb_unregister(knet_filter_cb); + bkn_netif_create_cb_unregister(knet_netif_create_cb); + bkn_netif_destroy_cb_unregister(knet_netif_destroy_cb); + +#ifdef PSAMPLE_SUPPORT + psample_cleanup(); +#endif return 0; } static int _init(void) { + bkn_rx_skb_cb_register(strip_tag_rx_cb); - bkn_tx_skb_cb_register(strip_tag_tx_cb); - bkn_filter_cb_register(strip_tag_filter_cb); + /* strip_tag_tx_cb is currently a no-op, so no need to register */ + if (0) + { + bkn_tx_skb_cb_register(strip_tag_tx_cb); + } +#ifdef PSAMPLE_SUPPORT + psample_init(); +#endif + + bkn_filter_cb_register(knet_filter_cb); + bkn_netif_create_cb_register(knet_netif_create_cb); + bkn_netif_destroy_cb_register(knet_netif_destroy_cb); return 0; } diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c new file mode 100644 index 000000000000..ef6fc102ce78 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c @@ -0,0 +1,875 @@ +/* + * Copyright 2017-2019 Broadcom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ +/* + * $Id: psample_cb.c $ + * $Copyright: (c) 2019 Broadcom Corp. + * All Rights Reserved.$ + */ + +/* + * Driver for call-back functions for Linux KNET driver. + * + * This code is used to integrate packet sampling KNET callback to + * the psample infra for sending sampled pkts to userspace sflow + * applications such as Host Sflow (https://github.com/sflow/host-sflow) + * using genetlink interfaces. + * + * The module can be built from the standard Linux user mode target + * directories using the following command (assuming bash), e.g. + * + * cd $SDK/systems/linux/user/ + * make BUILD_KNET_CB=1 + * + */ + +#include /* Must be included first */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "psample-cb.h" + +#define PSAMPLE_CB_DBG +#ifdef PSAMPLE_CB_DBG +extern int debug; +#define PSAMPLE_CB_DBG_PRINT(...) \ + if (debug & 0x1) { \ + gprintk(__VA_ARGS__); \ + } +#else +#define PSAMPLE_CB_DBG_PRINT(...) +#endif + +/* HIGIG2 header fields */ +#define SOC_HIGIG_SOP (0xfb) +#define SOC_HIGIG_START(x) ((x[0] >> 24) & 0xff) +#define SOC_HIGIG_DSTPORT(x) ((x[1] >> 11) & 0x1f) +#define SOC_HIGIG_SRCPORT(x) ((x[1] >> 16) & 0x1f) +#define SOC_HIGIG2_SOP (0xfb) //0xfc - TODO: how can we differentiate between Higig and higig2? +#define SOC_HIGIG2_START(x) ((x[0] >> 24) & 0xff) +#define SOC_HIGIG2_DSTPORT(x) ((x[0] >> 0) & 0xff) +#define SOC_HIGIG2_SRCPORT(x) ((x[1] >> 16) & 0xff) +#define SOC_DCB32_HG_OFFSET (6) + +#define FCS_SZ 4 +#define PSAMPLE_NLA_PADDING 4 + +#define PSAMPLE_RATE_DFLT 1 +#define PSAMPLE_SIZE_DFLT 128 +static int psample_size = PSAMPLE_SIZE_DFLT; +LKM_MOD_PARAM(psample_size, "i", int, 0); +MODULE_PARM_DESC(psample_size, +"psample pkt size (default 128 bytes)"); + +/* driver proc entry root */ +static struct proc_dir_entry *psample_proc_root = NULL; + +/* psample general info */ +typedef struct { + struct list_head netif_list; + knet_hw_info_t hw; + struct net *netns; + spinlock_t lock; +} psample_info_t; +static psample_info_t g_psample_info = {{0}}; + +/* Maintain sampled pkt statistics */ +typedef struct psample_stats_s { + unsigned long pkts_f_psample_cb; + unsigned long pkts_f_psample_mod; + unsigned long pkts_f_handled; + unsigned long pkts_f_pass_through; + unsigned long pkts_d_no_group; + unsigned long pkts_d_sampling_disabled; + unsigned long pkts_d_no_skb; + unsigned long pkts_d_not_ready; + unsigned long pkts_d_metadata; + unsigned long pkts_d_meta_srcport; + unsigned long pkts_d_meta_dstport; + unsigned long pkts_d_invalid_size; +} psample_stats_t; +static psample_stats_t g_psample_stats = {0}; + +typedef struct psample_meta_s { + int trunc_size; + int src_ifindex; + int dst_ifindex; + int sample_rate; +} psample_meta_t; + + +static psample_netif_t* +psample_netif_lookup_by_port(int unit, int port) +{ + struct list_head *list; + psample_netif_t *psample_netif = NULL; + unsigned long flags; + + /* look for port from list of available net_devices */ + spin_lock_irqsave(&g_psample_info.lock, flags); + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (psample_netif->port == port) { + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return psample_netif; + } + } + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return (NULL); +} + +static int +psample_info_get (int unit, psample_info_t *psample_info) +{ + int rv = 0; + if (!psample_info) { + gprintk("%s: psample_info is NULL\n", __func__); + return (-1); + } + + /* get hw info */ + rv = bkn_hw_info_get(unit, &psample_info->hw); + if (rv < 0) { + gprintk("%s: failed to get hw info\n", __func__); + return (-1); + } + + PSAMPLE_CB_DBG_PRINT("%s: DCB type %d\n", + __func__, psample_info->hw.dcb_type); + return (0); +} + +static int +psample_meta_srcport_get(uint8_t *pkt, void *pkt_meta) +{ + int srcport = 0; + uint32_t *metadata = (uint32_t*)pkt_meta; + + switch(g_psample_info.hw.dcb_type) { + case 36: /* TD3 */ + case 38: /* TH3 */ + break; + case 32: /* TH1/TH2 */ + case 26: /* TD2 */ + case 23: /* HX4 */ + metadata += SOC_DCB32_HG_OFFSET; + break; + default: + break; + } + + if (SOC_HIGIG2_START(metadata) == SOC_HIGIG2_SOP) + { + srcport = SOC_HIGIG2_SRCPORT(metadata); + } + else if (SOC_HIGIG_START(metadata) == SOC_HIGIG_SOP) + { + srcport = SOC_HIGIG_SRCPORT(metadata); + } + else + { + PSAMPLE_CB_DBG_PRINT("%s: Could not detect metadata sop type: 0x%02x (w[0]: 0x%04x)\n", __func__, + SOC_HIGIG_START(metadata), metadata[0]); + return -1; + } + return srcport; +} + +static int +psample_meta_dstport_get(uint8_t *pkt, void *pkt_meta) +{ + int dstport = 0; + uint32_t *metadata = (uint32_t*)pkt_meta; + + switch(g_psample_info.hw.dcb_type) { + case 36: /* TD3 */ + case 38: /* TH3 */ + break; + case 32: /* TH1/TH2 */ + case 26: /* TD2 */ + case 23: /* HX4 */ + metadata += SOC_DCB32_HG_OFFSET; + break; + default: + break; + } + + if (SOC_HIGIG2_START(metadata) == SOC_HIGIG2_SOP) + { + dstport = SOC_HIGIG2_DSTPORT(metadata); + } + else if (SOC_HIGIG_START(metadata) == SOC_HIGIG_SOP) + { + dstport = SOC_HIGIG_DSTPORT(metadata); + } + else + { + PSAMPLE_CB_DBG_PRINT("%s: Could not detect metadata sop type: 0x%02x (w[0]: 0x%04x)\n", __func__, + SOC_HIGIG_START(metadata), metadata[0]); + return (-1); + } + return dstport; +} + +static int +psample_meta_sample_reason(uint8_t *pkt, void *pkt_meta) +{ + uint32_t *metadata = (uint32_t*)pkt_meta; + uint32_t reason = 0; + uint32_t reason_hi = 0; + uint32_t sample_rx_reason_mask = 0; + + /* Sample Pkt reason code (bcmRxReasonSampleSource) */ + switch(g_psample_info.hw.dcb_type) { + case 36: /* TD3 */ + case 38: /* TH3 */ + reason_hi = *(metadata + 4); + reason = *(metadata + 5); + sample_rx_reason_mask = (1 << 3); + break; + case 32: /* TH1/TH2 */ + case 26: /* TD2 */ + case 23: /* HX4 */ + default: + reason_hi = *(metadata + 2); + reason = *(metadata + 3); + sample_rx_reason_mask = (1 << 5); + break; + } + + PSAMPLE_CB_DBG_PRINT("%s: DCB%d sample_rx_reason_mask: 0x%08x, reason: 0x%08x, reason_hi: 0x%08x\n", + __func__, g_psample_info.hw.dcb_type, sample_rx_reason_mask, reason, reason_hi); + + /* Check if only sample reason code is set. + * If only sample reason code, then consume pkt. + * If other reason codes exist, then pkt should be + * passed through to Linux network stack. + */ + if ((reason & ~sample_rx_reason_mask) || reason_hi) { + return 0; /* multiple reasons set, pass through */ + } + + /* only sample rx reason set, consume pkt */ + return (1); +} + +static int +psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_meta) +{ + int srcport, dstport; + int src_ifindex = 0; + int dst_ifindex = 0; + int sample_rate = PSAMPLE_RATE_DFLT; + int sample_size = PSAMPLE_SIZE_DFLT; + psample_netif_t *psample_netif = NULL; + +#ifdef PSAMPLE_CB_DBG + if (debug & 0x1) { + int i=0; + uint8_t *meta = (uint8_t*)pkt_meta; + PSAMPLE_CB_DBG_PRINT("%s: psample pkt metadata\n", __func__); + for (i=0; i<64; i+=16) { + PSAMPLE_CB_DBG_PRINT("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + meta[i+0], meta[i+1], meta[i+2], meta[i+3], meta[i+4], meta[i+5], meta[i+6], meta[i+7], + meta[i+8], meta[i+9], meta[i+10], meta[i+11], meta[i+12], meta[i+13], meta[i+14], meta[i+15]); + } + } +#endif + + /* parse pkt metadata for src and dst ports */ + srcport = psample_meta_srcport_get(pkt, pkt_meta); + dstport = psample_meta_dstport_get(pkt, pkt_meta); + if ((srcport == -1) || (dstport == -1)) { + gprintk("%s: invalid srcport %d or dstport %d\n", __func__, srcport, dstport); + return (-1); + } + + /* find src port netif (no need to lookup CPU port) */ + if (srcport != 0) { + if ((psample_netif = psample_netif_lookup_by_port(unit, srcport))) { + src_ifindex = psample_netif->dev->ifindex; + sample_rate = psample_netif->sample_rate; + sample_size = psample_netif->sample_size; + } else { + g_psample_stats.pkts_d_meta_srcport++; + PSAMPLE_CB_DBG_PRINT("%s: could not find srcport(%d)\n", __func__, srcport); + } + } + + /* find dst port netif (no need to lookup CPU port) */ + if (dstport != 0) { + if ((psample_netif = psample_netif_lookup_by_port(unit, dstport))) { + dst_ifindex = psample_netif->dev->ifindex; + } else { + g_psample_stats.pkts_d_meta_dstport++; + PSAMPLE_CB_DBG_PRINT("%s: could not find dstport(%d)\n", __func__, dstport); + } + } + + PSAMPLE_CB_DBG_PRINT("%s: srcport %d, dstport %d, src_ifindex %d, dst_ifindex %d, trunc_size %d, sample_rate %d\n", + __func__, srcport, dstport, src_ifindex, dst_ifindex, sample_size, sample_rate); + + sflow_meta->src_ifindex = src_ifindex; + sflow_meta->dst_ifindex = dst_ifindex; + sflow_meta->trunc_size = sample_size; + sflow_meta->sample_rate = sample_rate; + + return (0); +} + +int +psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta, + int chan, kcom_filter_t *kf) +{ + struct psample_group *group; + psample_meta_t meta; + struct sk_buff skb; + int rv = 0; + static int info_get = 0; + + if (!info_get) { + rv = psample_info_get (dev_no, &g_psample_info); + if (rv < 0) { + gprintk("%s: failed to get psample info\n", __func__); + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + info_get = 1; + } + + PSAMPLE_CB_DBG_PRINT("%s: pkt size %d, kf->dest_id %d, kf->cb_user_data %d\n", + __func__, size, kf->dest_id, kf->cb_user_data); + g_psample_stats.pkts_f_psample_cb++; + + /* get psample group info. psample genetlink group ID passed in kf->dest_id */ + group = psample_group_get(g_psample_info.netns, kf->dest_id); + if (!group) { + gprintk("%s: Could not find psample genetlink group %d\n", __func__, kf->cb_user_data); + g_psample_stats.pkts_d_no_group++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + + /* get psample metadata */ + rv = psample_meta_get(dev_no, pkt, pkt_meta, &meta); + if (rv < 0) { + gprintk("%s: Could not parse pkt metadata\n", __func__); + g_psample_stats.pkts_d_metadata++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + + /* Adjust original pkt size to remove 4B FCS */ + if (size < FCS_SZ) { + g_psample_stats.pkts_d_invalid_size++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } else { + size -= FCS_SZ; + } + + /* Account for padding in libnl used by psample */ + if (meta.trunc_size >= size) { + meta.trunc_size = size - PSAMPLE_NLA_PADDING; + } + + PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx %d, dst_ifdx %d, sample_rate %d\n", + __func__, group->group_num, meta.trunc_size, meta.src_ifindex, meta.dst_ifindex, meta.sample_rate); + + /* drop if configured sample rate is 0 */ + if (meta.sample_rate > 0) { + /* setup skb to point to pkt */ + memset(&skb, 0, sizeof(struct sk_buff)); + skb.len = size; + skb.data = pkt; + + psample_sample_packet(group, + &skb, + meta.trunc_size, + meta.src_ifindex, + meta.dst_ifindex, + meta.sample_rate); + + g_psample_stats.pkts_f_psample_mod++; + } else { + g_psample_stats.pkts_d_sampling_disabled++; + } + +PSAMPLE_FILTER_CB_PKT_HANDLED: + /* if sample reason only, consume pkt. else pass through */ + rv = psample_meta_sample_reason(pkt, pkt_meta); + if (rv) { + g_psample_stats.pkts_f_handled++; + } else { + g_psample_stats.pkts_f_pass_through++; + } + return rv; +} + +int +psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif, *lpsample_netif; + unsigned long flags; + + if ((psample_netif = kmalloc(sizeof(psample_netif_t), GFP_KERNEL)) == NULL) { + gprintk("%s: failed to alloc psample mem for netif '%s'\n", + __func__, dev->name); + return (-1); + } + + spin_lock_irqsave(&g_psample_info.lock, flags); + + psample_netif->dev = dev; + psample_netif->id = netif->id; + psample_netif->port = netif->port; + psample_netif->vlan = netif->vlan; + psample_netif->qnum = netif->qnum; + psample_netif->sample_rate = PSAMPLE_RATE_DFLT; + psample_netif->sample_size = PSAMPLE_SIZE_DFLT; + + /* insert netif sorted by ID similar to bkn_knet_netif_create() */ + found = 0; + list_for_each(list, &g_psample_info.netif_list) { + lpsample_netif = (psample_netif_t*)list; + if (netif->id < lpsample_netif->id) { + found = 1; + break; + } + } + + if (found) { + /* Replace previously removed interface */ + list_add_tail(&psample_netif->list, &lpsample_netif->list); + } else { + /* No holes - add to end of list */ + list_add_tail(&psample_netif->list, &g_psample_info.netif_list); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + PSAMPLE_CB_DBG_PRINT("%s: added psample netif '%s'\n", __func__, dev->name); + return (0); +} + +int +psample_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + if (!netif || !dev) { + gprintk("%s: netif or net_device is NULL\n", __func__); + return (-1); + } + + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (netif->id == psample_netif->id) { + found = 1; + list_del(&psample_netif->list); + PSAMPLE_CB_DBG_PRINT("%s: removing psample netif '%s'\n", __func__, dev->name); + kfree(psample_netif); + break; + } + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + if (!found) { + gprintk("%s: netif ID %d not found!\n", __func__, netif->id); + return (-1); + } + return (0); +} + +/* + * psample rate Proc Read Entry + */ +static int +psample_proc_rate_show(struct seq_file *m, void *v) +{ + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + seq_printf(m, " %-14s %d\n", psample_netif->dev->name, psample_netif->sample_rate); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + return 0; +} + +static int +psample_proc_rate_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_rate_show, NULL); +} + +/* + * psample rate Proc Write Entry + * + * Syntax: + * = + * + * Where is a virtual network interface name. + * + * Examples: + * eth4=1000 + */ +static ssize_t +psample_proc_rate_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif; + char sample_str[40], *ptr, *newline; + unsigned long flags; + + + if (count > sizeof(sample_str)) { + count = sizeof(sample_str) - 1; + sample_str[count] = '\0'; + } + if (copy_from_user(sample_str, buf, count)) { + return -EFAULT; + } + sample_str[count] = 0; + newline = strchr(sample_str, '\n'); + if (newline) { + /* Chop off the trailing newline */ + *newline = '\0'; + } + + if ((ptr = strchr(sample_str, '=')) == NULL && + (ptr = strchr(sample_str, ':')) == NULL) { + gprintk("Error: Pkt sample rate syntax not recognized: '%s'\n", sample_str); + return count; + } + *ptr++ = 0; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + found = 0; + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (strcmp(psample_netif->dev->name, sample_str) == 0) { + psample_netif->sample_rate = simple_strtol(ptr, NULL, 10); + // TODO MLI@BRCM - check valid sample rate + found = 1; + break; + } + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + if (!found) { + gprintk("Warning: Failed setting psample rate on unknown network interface: '%s'\n", sample_str); + } + return count; +} + +struct file_operations psample_proc_rate_file_ops = { + owner: THIS_MODULE, + open: psample_proc_rate_open, + read: seq_read, + llseek: seq_lseek, + write: psample_proc_rate_write, + release: single_release, +}; + +/* + * psample size Proc Read Entry + */ +static int +psample_proc_size_show(struct seq_file *m, void *v) +{ + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + seq_printf(m, " %-14s %d\n", psample_netif->dev->name, psample_netif->sample_size); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return 0; +} + +static int +psample_proc_size_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_size_show, NULL); +} + +/* + * psample size Proc Write Entry + * + * Syntax: + * = + * + * Where is a virtual network interface name. + * + * Examples: + * eth4=128 + */ +static ssize_t +psample_proc_size_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif; + char sample_str[40], *ptr, *newline; + unsigned long flags; + + if (count > sizeof(sample_str)) { + count = sizeof(sample_str) - 1; + sample_str[count] = '\0'; + } + if (copy_from_user(sample_str, buf, count)) { + return -EFAULT; + } + sample_str[count] = 0; + newline = strchr(sample_str, '\n'); + if (newline) { + /* Chop off the trailing newline */ + *newline = '\0'; + } + + if ((ptr = strchr(sample_str, '=')) == NULL && + (ptr = strchr(sample_str, ':')) == NULL) { + gprintk("Error: Pkt sample size syntax not recognized: '%s'\n", sample_str); + return count; + } + *ptr++ = 0; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + found = 0; + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (strcmp(psample_netif->dev->name, sample_str) == 0) { + psample_netif->sample_size = simple_strtol(ptr, NULL, 10); + // TODO MLI@BRCM - check valid sample size + found = 1; + break; + } + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + if (!found) { + gprintk("Warning: Failed setting psample size on unknown network interface: '%s'\n", sample_str); + } + return count; +} + +struct file_operations psample_proc_size_file_ops = { + owner: THIS_MODULE, + open: psample_proc_size_open, + read: seq_read, + llseek: seq_lseek, + write: psample_proc_size_write, + release: single_release, +}; + +/* + * psample debug Proc Read Entry + */ +static int +psample_proc_debug_show(struct seq_file *m, void *v) +{ + seq_printf(m, "BCM KNET %s Callback Config\n", PSAMPLE_CB_NAME); + seq_printf(m, " debug: 0x%x\n", debug); + seq_printf(m, " cmic_type: %d\n", g_psample_info.hw.cmic_type); + seq_printf(m, " dcb_type: %d\n", g_psample_info.hw.dcb_type); + seq_printf(m, " dcb_size: %d\n", g_psample_info.hw.dcb_size); + seq_printf(m, " pkt_hdr_size: %d\n", g_psample_info.hw.pkt_hdr_size); + seq_printf(m, " cdma_channels: %d\n", g_psample_info.hw.cdma_channels); + + return 0; +} + +static int +psample_proc_debug_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_debug_show, NULL); +} + +/* + * psample debug Proc Write Entry + * + * Syntax: + * debug= + * + * Where corresponds to the debug module parameter. + * + * Examples: + * debug=0x1 + */ +static ssize_t +psample_proc_debug_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + char debug_str[40]; + char *ptr; + + if (count > sizeof(debug_str)) { + count = sizeof(debug_str) - 1; + debug_str[count] = '\0'; + } + if (copy_from_user(debug_str, buf, count)) { + return -EFAULT; + } + + if ((ptr = strstr(debug_str, "debug=")) != NULL) { + ptr += 6; + debug = simple_strtol(ptr, NULL, 0); + } else { + gprintk("Warning: unknown configuration setting\n"); + } + + return count; +} + +struct file_operations psample_proc_debug_file_ops = { + owner: THIS_MODULE, + open: psample_proc_debug_open, + read: seq_read, + llseek: seq_lseek, + write: psample_proc_debug_write, + release: single_release, +}; + +static int +psample_proc_stats_show(struct seq_file *m, void *v) +{ + seq_printf(m, "BCM KNET %s Callback Stats\n", PSAMPLE_CB_NAME); + seq_printf(m, " DCB type %d\n", g_psample_info.hw.dcb_type); + seq_printf(m, " pkts filter psample cb %10lu\n", g_psample_stats.pkts_f_psample_cb); + seq_printf(m, " pkts sent to psample module %10lu\n", g_psample_stats.pkts_f_psample_mod); + seq_printf(m, " pkts handled by psample %10lu\n", g_psample_stats.pkts_f_handled); + seq_printf(m, " pkts pass through %10lu\n", g_psample_stats.pkts_f_pass_through); + seq_printf(m, " pkts drop no psample group %10lu\n", g_psample_stats.pkts_d_no_group); + seq_printf(m, " pkts drop sampling disabled %10lu\n", g_psample_stats.pkts_d_sampling_disabled); + seq_printf(m, " pkts drop no skb %10lu\n", g_psample_stats.pkts_d_no_skb); + seq_printf(m, " pkts drop psample not ready %10lu\n", g_psample_stats.pkts_d_not_ready); + seq_printf(m, " pkts drop metadata parse error %10lu\n", g_psample_stats.pkts_d_metadata); + seq_printf(m, " pkts with invalid src port %10lu\n", g_psample_stats.pkts_d_meta_srcport); + seq_printf(m, " pkts with invalid dst port %10lu\n", g_psample_stats.pkts_d_meta_dstport); + seq_printf(m, " pkts with invalid orig pkt sz %10lu\n", g_psample_stats.pkts_d_invalid_size); + return 0; +} + +static int +psample_proc_stats_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_stats_show, NULL); +} + +struct file_operations psample_proc_stats_file_ops = { + owner: THIS_MODULE, + open: psample_proc_stats_open, + read: seq_read, + llseek: seq_lseek, + write: NULL, + release: single_release, +}; + +int psample_cleanup(void) +{ + remove_proc_entry("stats", psample_proc_root); + remove_proc_entry("rate", psample_proc_root); + remove_proc_entry("size", psample_proc_root); + remove_proc_entry("debug", psample_proc_root); + return 0; +} + +int psample_init(void) +{ + #define PROCFS_MAX_PATH 1024 + char psample_procfs_path[PROCFS_MAX_PATH]; + struct proc_dir_entry *entry; + + /* create procfs for psample */ + snprintf(psample_procfs_path, PROCFS_MAX_PATH, "bcm/knet-cb"); + proc_mkdir(psample_procfs_path, NULL); + snprintf(psample_procfs_path, PROCFS_MAX_PATH, "%s/%s", psample_procfs_path, PSAMPLE_CB_NAME); + psample_proc_root = proc_mkdir(psample_procfs_path, NULL); + + /* create procfs for psample stats */ + PROC_CREATE(entry, "stats", 0666, psample_proc_root, &psample_proc_stats_file_ops); + if (entry == NULL) { + gprintk("%s: Unable to create procfs entry '/procfs/%s/stats'\n", __func__, psample_procfs_path); + return -1; + } + + /* create procfs for setting sample rates */ + PROC_CREATE(entry, "rate", 0666, psample_proc_root, &psample_proc_rate_file_ops); + if (entry == NULL) { + gprintk("%s: Unable to create procfs entry '/procfs/%s/rate'\n", __func__, psample_procfs_path); + return -1; + } + + /* create procfs for setting sample size */ + PROC_CREATE(entry, "size", 0666, psample_proc_root, &psample_proc_size_file_ops); + if (entry == NULL) { + gprintk("%s: Unable to create procfs entry '/procfs/%s/size'\n", __func__, psample_procfs_path); + return -1; + } + + /* create procfs for debug log */ + PROC_CREATE(entry, "debug", 0666, psample_proc_root, &psample_proc_debug_file_ops); + if (entry == NULL) { + gprintk("%s: Unable to create procfs entry '/procfs/%s/debug'\n", __func__, psample_procfs_path); + return -1; + } + + /* clear data structs */ + memset(&g_psample_stats, 0, sizeof(psample_stats_t)); + memset(&g_psample_info, 0, sizeof(psample_info_t)); + + /* setup psample_info struct */ + INIT_LIST_HEAD(&g_psample_info.netif_list); + spin_lock_init(&g_psample_info.lock); + + /* get net namespace */ + g_psample_info.netns = get_net_ns_by_pid(current->pid); + if (!g_psample_info.netns) { + gprintk("%s: Could not get network namespace for pid %d\n", __func__, current->pid); + return (-1); + } + PSAMPLE_CB_DBG_PRINT("%s: current->pid %d, netns 0x%p, sample_size %d\n", __func__, + current->pid, g_psample_info.netns, psample_size); + + return 0; +} diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.h new file mode 100644 index 000000000000..8f9398c51692 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.h @@ -0,0 +1,58 @@ +/* + * Copyright 2017 Broadcom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ +/* + * $Id: psample_cb.h $ + * $Copyright: (c) 2019 Broadcom Corp. + * All Rights Reserved.$ + */ +#ifndef __PSAMPLE_CB_H__ +#define __PSAMPLE_CB_H__ + +#include +#include +#include + +#define PSAMPLE_CB_NAME "psample" + +extern int +psample_init(void); + +extern int +psample_cleanup(void); + +extern int +psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta, + int chan, kcom_filter_t *kf); + +/* psample data per interface */ +typedef struct { + struct list_head list; + struct net_device *dev; + uint16 id; + uint8 port; + uint16 vlan; + uint16 qnum; + uint32 sample_rate; + uint32 sample_size; +} psample_netif_t; + +extern int +psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev); + +extern int +psample_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev); + +#endif /* __PSAMPLE_CB_H__ */ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile new file mode 100644 index 000000000000..631590104cd8 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile @@ -0,0 +1,64 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 1.3 Broadcom SDK $ +# $Copyright: (c) 2005 Broadcom Corp. +# All Rights Reserved.$ +# +LOCALDIR = systems/linux/kernel/modules/psample + +include ${SDK}/make/Make.config + +LIBS = $(LIBDIR)/libkern.a + +ifeq ($(kernel_version),2_4) +MODULE = $(LIBDIR)/psample.o +else +KERNEL_MODULE_DIR = kernel_module + +THIS_MOD_NAME := psample +MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o +KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko + +build: $(MODULE) $(KMODULE) +endif + +KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers + +# BCM Network Device + +$(MODULE): $(BLDDIR)/.tree $(BOBJS) $(LIBS) + $(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@ +ifneq ($(kernel_version),2_4) +$(KMODULE): $(MODULE) + rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR) + mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR) + cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile + cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers + MOD_NAME=$(THIS_MOD_NAME) $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko +endif + +# Make.depend is before clean:: so that Make.depend's clean:: runs first. + +include ${SDK}/make/Make.depend + +clean:: + $(RM) $(BLDDIR)/version.c $(BLDDIR)/version.o + $(RM) $(BOBJS) $(MODULE) + +ifneq ($(kernel_version),2_4) +.PHONY: build +endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c new file mode 100644 index 000000000000..e1d4e2353b09 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c @@ -0,0 +1,302 @@ +/* + * net/psample/psample.c - Netlink channel for packet sampling + * Copyright (c) 2017 Yotam Gigi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PSAMPLE_MAX_PACKET_SIZE 0xffff + +static LIST_HEAD(psample_groups_list); +static DEFINE_SPINLOCK(psample_groups_lock); + +/* multicast groups */ +enum psample_nl_multicast_groups { + PSAMPLE_NL_MCGRP_CONFIG, + PSAMPLE_NL_MCGRP_SAMPLE, +}; + +static const struct genl_multicast_group psample_nl_mcgrps[] = { + [PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME }, + [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME }, +}; + +static struct genl_family psample_nl_family __ro_after_init; + +static int psample_group_nl_fill(struct sk_buff *msg, + struct psample_group *group, + enum psample_command cmd, u32 portid, u32 seq, + int flags) +{ + void *hdr; + int ret; + + hdr = genlmsg_put(msg, portid, seq, &psample_nl_family, flags, cmd); + if (!hdr) + return -EMSGSIZE; + + ret = nla_put_u32(msg, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num); + if (ret < 0) + goto error; + + ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_REFCOUNT, group->refcount); + if (ret < 0) + goto error; + + ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_SEQ, group->seq); + if (ret < 0) + goto error; + + genlmsg_end(msg, hdr); + return 0; + +error: + genlmsg_cancel(msg, hdr); + return -EMSGSIZE; +} + +static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg, + struct netlink_callback *cb) +{ + struct psample_group *group; + int start = cb->args[0]; + int idx = 0; + int err; + + spin_lock(&psample_groups_lock); + list_for_each_entry(group, &psample_groups_list, list) { + if (!net_eq(group->net, sock_net(msg->sk))) + continue; + if (idx < start) { + idx++; + continue; + } + err = psample_group_nl_fill(msg, group, PSAMPLE_CMD_NEW_GROUP, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI); + if (err) + break; + idx++; + } + + spin_unlock(&psample_groups_lock); + cb->args[0] = idx; + return msg->len; +} + +static const struct genl_ops psample_nl_ops[] = { + { + .cmd = PSAMPLE_CMD_GET_GROUP, + .dumpit = psample_nl_cmd_get_group_dumpit, + /* can be retrieved by unprivileged users */ + } +}; + +static struct genl_family psample_nl_family __ro_after_init = { + .name = PSAMPLE_GENL_NAME, + .version = PSAMPLE_GENL_VERSION, + .maxattr = PSAMPLE_ATTR_MAX, + .netnsok = true, + .module = THIS_MODULE, + .mcgrps = psample_nl_mcgrps, + .ops = psample_nl_ops, + .n_ops = ARRAY_SIZE(psample_nl_ops), + .n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps), +}; + +static void psample_group_notify(struct psample_group *group, + enum psample_command cmd) +{ + struct sk_buff *msg; + int err; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); + if (!msg) + return; + + err = psample_group_nl_fill(msg, group, cmd, 0, 0, NLM_F_MULTI); + if (!err) + genlmsg_multicast_netns(&psample_nl_family, group->net, msg, 0, + PSAMPLE_NL_MCGRP_CONFIG, GFP_ATOMIC); + else + nlmsg_free(msg); +} + +static struct psample_group *psample_group_create(struct net *net, + u32 group_num) +{ + struct psample_group *group; + + group = kzalloc(sizeof(*group), GFP_ATOMIC); + if (!group) + return NULL; + + group->net = net; + group->group_num = group_num; + list_add_tail(&group->list, &psample_groups_list); + + psample_group_notify(group, PSAMPLE_CMD_NEW_GROUP); + return group; +} + +static void psample_group_destroy(struct psample_group *group) +{ + psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP); + list_del(&group->list); + kfree(group); +} + +static struct psample_group * +psample_group_lookup(struct net *net, u32 group_num) +{ + struct psample_group *group; + + list_for_each_entry(group, &psample_groups_list, list) + if ((group->group_num == group_num) && (group->net == net)) + return group; + return NULL; +} + +struct psample_group *psample_group_get(struct net *net, u32 group_num) +{ + struct psample_group *group; + + spin_lock(&psample_groups_lock); + + group = psample_group_lookup(net, group_num); + if (!group) { + group = psample_group_create(net, group_num); + if (!group) + goto out; + } + group->refcount++; + +out: + spin_unlock(&psample_groups_lock); + return group; +} +EXPORT_SYMBOL_GPL(psample_group_get); + +void psample_group_put(struct psample_group *group) +{ + spin_lock(&psample_groups_lock); + + if (--group->refcount == 0) + psample_group_destroy(group); + + spin_unlock(&psample_groups_lock); +} +EXPORT_SYMBOL_GPL(psample_group_put); + +void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, + u32 trunc_size, int in_ifindex, int out_ifindex, + u32 sample_rate) +{ + struct sk_buff *nl_skb; + int data_len; + int meta_len; + void *data; + int ret; + + meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) + + (out_ifindex ? nla_total_size(sizeof(u16)) : 0) + + nla_total_size(sizeof(u32)) + /* sample_rate */ + nla_total_size(sizeof(u32)) + /* orig_size */ + nla_total_size(sizeof(u32)) + /* group_num */ + nla_total_size(sizeof(u32)); /* seq */ + + data_len = min(skb->len, trunc_size); + if (meta_len + nla_total_size(data_len) > PSAMPLE_MAX_PACKET_SIZE) + data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN + - NLA_ALIGNTO; + + nl_skb = genlmsg_new(meta_len + data_len, GFP_ATOMIC); + if (unlikely(!nl_skb)) + return; + + data = genlmsg_put(nl_skb, 0, 0, &psample_nl_family, 0, + PSAMPLE_CMD_SAMPLE); + if (unlikely(!data)) + goto error; + + if (in_ifindex) { + ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_IIFINDEX, in_ifindex); + if (unlikely(ret < 0)) + goto error; + } + + if (out_ifindex) { + ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OIFINDEX, out_ifindex); + if (unlikely(ret < 0)) + goto error; + } + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_RATE, sample_rate); + if (unlikely(ret < 0)) + goto error; + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_ORIGSIZE, skb->len); + if (unlikely(ret < 0)) + goto error; + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num); + if (unlikely(ret < 0)) + goto error; + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_GROUP_SEQ, group->seq++); + if (unlikely(ret < 0)) + goto error; + + if (data_len) { + int nla_len = nla_total_size(data_len); + struct nlattr *nla; + + nla = (struct nlattr *)skb_put(nl_skb, nla_len); + nla->nla_type = PSAMPLE_ATTR_DATA; + nla->nla_len = nla_attr_size(data_len); + + if (skb_copy_bits(skb, 0, nla_data(nla), data_len)) + goto error; + } + + genlmsg_end(nl_skb, data); + genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0, + PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC); + + return; +error: + pr_err_ratelimited("Could not create psample log message\n"); + nlmsg_free(nl_skb); +} +EXPORT_SYMBOL_GPL(psample_sample_packet); + +static int __init psample_module_init(void) +{ + return genl_register_family(&psample_nl_family); +} + +static void __exit psample_module_exit(void) +{ + genl_unregister_family(&psample_nl_family); +} + +module_init(psample_module_init); +module_exit(psample_module_exit); + +MODULE_AUTHOR("Yotam Gigi "); +MODULE_DESCRIPTION("netlink channel for packet sampling"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile index 0e6226544334..20d83735fcce 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile @@ -91,6 +91,9 @@ KNET_CB := $(DEST_DIR)/$(KNET_CB_LOCAL) BCM_KNET_LOCAL :=linux-bcm-knet.$(KOBJ) BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL) +PSAMPLE_LOCAL := psample.$(KOBJ) +PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL) + ifeq (,$(findstring DELIVER,$(MAKECMDGOALS))) .DEFAULT_GOAL := all all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE) @@ -126,6 +129,15 @@ all_targets +=$(LOCAL_TARGETS) endif endif +ifdef BUILD_PSAMPLE +all_targets += $(PSAMPLE) +ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT +ifeq ($(NO_LOCAL_TARGETS),) +LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(PSAMPLE_LOCAL)) +all_targets +=$(LOCAL_TARGETS) +endif +endif + ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include COND_KNET_LIBS = libuser.$(libext) endif @@ -159,6 +171,10 @@ kernel_modules: ifeq ($(BUILD_KNET),1) $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="shared bcm-knet" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" +ifdef BUILD_PSAMPLE + $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + subdirs="psample" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" +endif ifdef BUILD_KNET_CB $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" @@ -178,6 +194,10 @@ $(BCM_KNET): $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ) $(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ) $(OBJCOPY) --strip-debug $< $@ +$(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ) + $(OBJCOPY) --strip-debug $< $@ + + ifeq ($(NO_LOCAL_TARGETS),) $(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ)))) endif @@ -194,6 +214,7 @@ clean:: $(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ) + $(RM) $(KERN_BLDROOT)/psample.$(KOBJ) $(RM) $(LOCAL_TARGETS) distclean:: clean diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile index 7a8b4a8b0c4d..03300ff8a046 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile @@ -44,7 +44,7 @@ endif export SDK -override kernel_version=4_4 +override kernel_version=4_14 platform=iproc IPROC_BUILD=1 diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 133238622f76..08e002624abb 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -291,7 +291,9 @@ RUN apt-get update && apt-get install -y \ automake1.11 \ libselinux1-dev \ # For kdump-tools - liblzo2-dev + liblzo2-dev \ +# For SAI3.7 + libprotobuf-dev ## Config dpkg ## install the configuration file if it’s currently missing From 1e05a41c7f8e8f8b06cc9dd6c6de510241f5cb58 Mon Sep 17 00:00:00 2001 From: Polly Hsu Date: Thu, 19 Dec 2019 03:09:19 +0800 Subject: [PATCH 0254/1427] [device][accton]: Update for AS7326-56X complying the BCM SAI 3.5.3.1m-26 (#3830) * [device][accton]: Update for AS7326-56X complying the Broadcom SAI latest version 3.5.3.1m-26 * Update Accton-AS7326-56X to adapt xxx.config.bcm based on the latest update of Device-Specific File Directory Structure. * Update Accton-AS7326-56X LED BIN complying the Broadcom SAI latest version 3.5.3.1m-26 Signed-off-by: polly_hsu@edge-core.com * [device][accton]: Merge the SDK config with #3103 (Fix Accton as7326 port breakouk) Signed-off-by: Polly Hsu --- .../Accton-AS7326-56X/sai.profile | 2 +- .../td3-as7326-48x25G+8x100G.config.bcm | 3 +++ .../x86_64-accton_as7326_56x-r0/custom_led.bin | Bin 0 -> 1092 bytes .../led_proc_init.soc | 6 ++++++ .../linkscan_led_fw.bin | Bin 0 -> 4716 bytes 5 files changed, 10 insertions(+), 1 deletion(-) mode change 100644 => 100755 device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile create mode 100755 device/accton/x86_64-accton_as7326_56x-r0/custom_led.bin create mode 100755 device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc create mode 100755 device/accton/x86_64-accton_as7326_56x-r0/linkscan_led_fw.bin diff --git a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile old mode 100644 new mode 100755 index 0e465ce12edd..47e3107477a2 --- a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile +++ b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as7326-48x25G+8x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7326-48x25G+8x100G.config.bcm diff --git a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm index 2b7b6fb08007..1a4b7da32df3 100755 --- a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm +++ b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm @@ -17,6 +17,7 @@ l2xmsg_mode=1 bcm_num_cos=8 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 +ifp_inports_support_enable=1 ipv6_lpm_128b_enable=0x1 l3_max_ecmp_mode=1 l3_alpm_enable=2 @@ -24,11 +25,13 @@ lpm_scaling_enable=0 max_vp_lags=0 miim_intr_enable=0 module_64ports=1 +port_flex_enable=1 schan_intr_enable=0 stable_size=0x5500000 tdma_timeout_usec=3000000 skip_L2_USER_ENTRY=0 bcm_tunnel_term_compatible_mode=1 +l3_alpm_ipv6_128b_bkt_rsvd=1 dport_map_port_1=6 dport_map_port_2=2 diff --git a/device/accton/x86_64-accton_as7326_56x-r0/custom_led.bin b/device/accton/x86_64-accton_as7326_56x-r0/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..8495c821680117741b78205c42c959878fbfd2b4 GIT binary patch literal 1092 zcmZwGT~E_c7zgmvuCxO(gdj5Th#e(_w-8`NVW^B14rWAArU)zu8^lcU0>ujiUncVd zs3QhCjS1d)VTj0`B=Z}r(F-FtBV2f4OqOT@8k71j8wQL`emOaPdY*sJNt;@YEDO{| zi9#IV@+V|8^uAAUMm@iDQd!!&VkJ?TR#O*sQj*I3DIBY+|A9(TuY7#P>UQp}{@ymL z-*s;#d1|h)dEHIuno4bRj*U^GD1q$qU?8u2DX6)!KL74aC2;P+_Icnn{OfH zU@IZ>z!5@tuz&zrAc6!|ut6RifP5%|Lr@HMI09vG6l8EfIVey8)ldVqPzR0B1WsrM zyaI7S8=QcXa0=SN4ISVC6*{2{7<9vFI0I*)7tX;&=!Z)%0K;$@Mqm^I5QH%phpTW6 zCg3{UfSWJ{x8OF+z%1N>yKoQgLl_=F1dPlT2@Tr0R_nA{w$L%z9cSrz?zFX5Ok~&c z2_j3i7M+v1Brh9ZCcAg*S#6)+2sOE%qD1t57mEG9Ww03JxvB2RWV;DA!ABdniw zvEo5*u)(UYU+D;kSR zVuDvVt8R{tHG}c1RwXY13`j|!47@s7S1W%^#zc#|`A@MP)T9QOrV5n92nZLvz z(irEgPPEYT%-D(`xmfS(@pbM`Ui651RN@m{EGBUu!wOZ?&rcyuP)WV0r{}YVn-f$% zsWLxDRkMF=r+;gvzYqQGy6ZpvrN8}o^j{~t37$-XHIv{q2#-YUt02kOOPRav#vHTo zRF#l?7^7L|uuqK*cYX^^&<5mJ<8%sl@=JTZ{&TX69^1bB7~Vd;g5R@4vqO#%N4^!= s7Tw3zk!9}I9A`o~u^4&Q$1l@&kC?_@veX(rr}jGh7!6>K&CmjW02uKW<^TWy literal 0 HcmV?d00001 diff --git a/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc b/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc new file mode 100755 index 000000000000..01b49772c0ba --- /dev/null +++ b/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc @@ -0,0 +1,6 @@ +#led auto off +#led stop +m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on +led start diff --git a/device/accton/x86_64-accton_as7326_56x-r0/linkscan_led_fw.bin b/device/accton/x86_64-accton_as7326_56x-r0/linkscan_led_fw.bin new file mode 100755 index 0000000000000000000000000000000000000000..a6a4794ecc2bfa213cd2dfcbb38f743421708819 GIT binary patch literal 4716 zcmaJ_3v?URnf_<=8u=+ZZX?^WGg2ITWK59LH17>#O}Lg6J5fx^QK65KF)&IUR_p;c zG+QD$DX}4S9msC&B(x3X6qiSFb0U`AMJIAtvLVfZv7KxaOwZ9da1iBe5~U`VY|EPc zM>1^avbE3k+_`tY|Nrm*zJ?$`I{^4`+>hgL{XB5X=0i9S;|Sa`G_IczD(Osv3tD$m zxPi2@iO+ulHoCwX7B{&zc%1&Q-(aQu!Pa18O*_1qF%pahBYF~& z3apTPRjF;aOIyq=OC|421GiNEy%ZLk1C;-fK#Tto=|994F(6T*+Y%6eD?vTjjq-U3 zmLG9eO^o?R#Hu(_6oSzw{b&8D#Q6X;GV-K!+-bag#(zFA=s$-iVd7`;x!&K43%B6@AyID?+rD5!CtV>A(LOB)c<^ zG-R_0#65xPi|A}AcR3ApUg0jYmlXxhJoW>yGjdC}{++{4tsL$KJ0-`u`&zp!rlzY? zS6v}VNre=Z`;Ew-+j~bj2{=jyHXGGhjr2z@NZze{l&&1HmZcwFfA zHkbqE?IQh)0r3ywgQUa{^#lHr&TX9+{2i7}gl_zF>OKn$Kka;fl4T*eS9zBjUFLrhUqwz;e|G^L8Z6OFDxOvnX~Q?S`f80 zhXPhbfxUF%VB=rmPhdBx4L?})UWa~f!#E9ILD)CLbtq{_6di!f-PqD zF8{W`n|r&?beTx7RsA;DnwS58CuH{8cHr*kE1@q|I7hH`I--aDqx)RcV5xjFpdGqH z>XsM>48G|sn}B3*7ApCgH=Mdjiq*zdy1LP16jX2cEUJa*XR7pq$Kg?=0G3n z9g?POpG6X>A<7C8BT&PP2<+R5>BzxR9We5>z-lQd9dPQ$DdcTLNmPmE61s)}^3Wf7 z9!~o9!+CFGj>Gdg4sST8C+VROR5&2{c$OJP`-?`o!iI?C^#x{#K1xYC_K%fCaT;k| zO#FW|9Fjc{tISIoUFfqoMEy`Sk&aXl0~lpE!jNLZII;mqezMR~18h-FTj}VATV&~l zmwdm5zj*slCK$3yA!zmjn~tU;?6zJ!VYz%gpcyWEk7;J^qy`T-;V?r~E1X_{N@|#| z>2qq)4w@Y04T=A?!fLd_s|(byzsg>FsKho8|uMr*{|A!g=52LcVI7n43LayN&o0N zjL?@Bbg)6T*XVHWU9b}qKHKn#+Q3=s0NuHz%R)SI|=F@KrQJl3VDqFikU4e{$IgV75At)e;UpfGn^?^&>T^ z=P(2O*H&OHgeL6jFx>0qEuF||cFGi;j>v5%&_Y_7tAS)HLt!Rh$#O(;XmvI(=fw$c2HE^FzhG4zV%~X0{K`Fz~=~LHL`9`(@``b2lO&AJ@ zvg)x_&-=cQdrSEr;_he2sTax!ELWNzYd%DN+2$vH-|@C%+t}4F_+IxlkhOdX|1X%= zf4g%*SoX3Fis4lV(q?d#Y9Vh)5$WiVM+;rybJS4CVoItit9Bz;Sy?3& znO9O5P?qv>7W2pt=Z$XQ`osd+=r&?k#^m~d7Qe>YA}XmGJe?`3=0#QJpBe!y_*{!m z;50IYp4;FGwi;Q`U^QiV{9BltLqthkQ~I^WBK}^8s&9$ho3jI=78mRZwpO{Bp!zpv zFiPj84yFTQrL=Hf47Pp^tpR&uhFEE^wcH)k8>OcL9mWnSRzeF;VYgcB>cVOW1L_yp zSB<-C=f{JshTLlCuU4_&QvkN0%*t*hnt6>ko`=zEOn{Ok|%NG69gbd&Bp&w;PtIna5q`*WTHooBoANK+oUo9up*%v8U(tH-jD ze~6sc?JM4>MyBqCg5|;=Izzi(7GiqdsKI$hU&q#S(la_UUtVky&WXur7CoqK8#M@n zTH**QsZ7?>&WRLyRVpiqF4u_Y@?c$}+?56X3nFhh+{~1cn$A)UqvD;K^+b{& zIXU~UrV)I;H>+mulX&y!H($7)<kd_Ehcu$NI%_IV9SimN=BP4VsO zoEClDPN*UDkdYszOG$Koypd;0cVm` zdCz2()ce_LmtPubt#m1=8(DFWlKRiws-B1_ktnhOC3Sq(ff1CC9P^xdd(c8zE^^+V zRU?P-8)Yl@&&7*zL+9cqJgdeHmBs)!#1semo+ha%N8A8MFz!{Ke619KT8DSOVm0QA zhz>LL-LtpWjC*FoE*r_$=ey_g^|=S>2C@1Y$X?fGqLnJvghw4@(`rb5bC$1dF}|(u zhoZ`>B@WD3O|ulCSg>0qS{~skfr^jtVZkakqXr?_FuRV>s-~4}G>tunj#R8JA!@xa zA*F*S*<2kjn2nuWj~QlZ)`}F1XVnT+Fx#BVk1r_cMPvzL%~;Q;(<%=8$TVLYKDhz8 zD=8|A802?7ok#T}Dv10l9L3lbK=MjDc2Y^D7xGelkhY@?N~%XuPZ=JiegSnAYaIC9 z+iA+$Pd`v=Abn1lY$ECj|2@6Yv(df3YS7sv7kyB`+2k%9KekOksLCp@@yO27ajmT? zzS=Wnu8~7H?(lRtL*{C^8TY7hqpc|3M4EG_{$-jTR=sIG>H|BdIBomU&Kn7hZ9bv1 z%_j7=RKj4pnP6w)OXWl7a#>BLZa}%0);T}y;?L|9kXD5QK6DO%St-jaJ;~Us!unSy53b0S9L}`em`8)bO>MJ>_(j;I5s$q~5VKL}O!uP@vM8yJW@{06pF?_1kpu4<*Be+k~P`L#?LO zr<|$DY-&_VmjRf|0UW0uC0(^E_HaKjJN-*CgIo@J6LR^rRh;&RFr)x}j zcmMBk^gvECzHadzpN#4~dY4Jmd&;XOm Date: Thu, 19 Dec 2019 07:15:27 -0800 Subject: [PATCH 0255/1427] [caclmgrd] Fix application of IPv6 service ACL rules (#3917) --- files/image_config/caclmgrd/caclmgrd | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 5e8d83074de1..6226bb16768f 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -194,13 +194,14 @@ class ControlPlaneAclManager(object): continue # If we haven't determined the IP version for this ACL table yet, - # try to do it now. We determine heuristically based on whether the - # src IP is an IPv4 or IPv6 address. - if not table_ip_version and "SRC_IP" in rule_props and rule_props["SRC_IP"]: - ip_addr = ipaddress.IPAddress(rule_props["SRC_IP"].split("/")[0]) - if isinstance(ip_addr, ipaddress.IPv6Address): + # try to do it now. We attempt to determine heuristically based on + # whether the src or dst IP of this rule is an IPv4 or IPv6 address. + if not table_ip_version: + if (("SRC_IPV6" in rule_props and rule_props["SRC_IPV6"]) or + ("DST_IPV6" in rule_props and rule_props["DST_IPV6"])): table_ip_version = 6 - elif isinstance(ip_addr, ipaddress.IPv4Address): + elif (("SRC_IP" in rule_props and rule_props["SRC_IP"]) or + ("DST_IP" in rule_props and rule_props["DST_IP"])): table_ip_version = 4 # If we were unable to determine whether this ACL table contains From b6ad09aa352370e6e69fd609802dfd74ea8cd00e Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Mon, 23 Dec 2019 11:15:08 +0200 Subject: [PATCH 0256/1427] [syncd.sh] remove chipdown on mellanox (#3926) ASIC reset events are captured by hw-mgmt and hw-mgmt calls chipup/chipdown internally without OS iteraction Signed-off-by: Stepan Blyschak --- files/scripts/syncd.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 89f15f0f413f..05e5552a64b1 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -111,7 +111,6 @@ start() { /bin/systemctl stop pmon debug "pmon is active while syncd starting, stop it first" fi - /usr/bin/hw-management.sh chipdown fi if [[ x"$BOOT_TYPE" == x"fast" ]]; then From ed2d5f8a32f1deffb6e8a59c4b153b36f7c30e16 Mon Sep 17 00:00:00 2001 From: Wataru Ishida <5915117+ishidawataru@users.noreply.github.com> Date: Mon, 23 Dec 2019 10:27:22 -0800 Subject: [PATCH 0257/1427] [broadcom]: respect the current network namespace when creating netdev (#3896) https://github.com/Broadcom-Switch/OpenNSL/issues/26 Signed-off-by: Wataru Ishida --- .../systems/linux/kernel/modules/bcm-knet/bcm-knet.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c index 0c91c3ecd5f7..077386e6dcbc 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c @@ -6165,6 +6165,10 @@ bkn_init_ndev(u8 *mac, char *name) strncpy(dev->name, name, IFNAMSIZ-1); } +#ifdef CONFIG_NET_NS + dev_net_set(dev, current->nsproxy->net_ns); +#endif + /* Register the kernel Ethernet device */ if (register_netdev(dev)) { DBG_WARN(("Error registering Ethernet device.\n")); From 183c945ab109d541083123277d9553863cd44df8 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Mon, 23 Dec 2019 20:34:22 +0200 Subject: [PATCH 0258/1427] [slave.mk] use curl instead of wget (#3939) wget creates empty file on failure which makes subsequent make runs think that file is already there and won't try to download it again. e.g.: $ make target/files/stretch/fw-SPC-rel-13_2000_2602-EVB.mfa ... Fails to download ... $ ls target/files/stretch/fw-SPC-rel-13_2000_2602-EVB.mfa target/files/stretch/fw-SPC-rel-13_2000_2602-EVB.mfa $ make target/files/stretch/fw-SPC-rel-13_2000_2602-EVB.mfa make: `target/files/stretch/fw-SPC-rel-13_2000_2602-EVB.mfa' is up to date. Signed-off-by: Stepan Blyschak --- slave.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slave.mk b/slave.mk index 44b903ddf9c9..f62be5672221 100644 --- a/slave.mk +++ b/slave.mk @@ -256,7 +256,7 @@ SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_COPY_FILES)) $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) : $(DEBS_PATH)/% : .platform $(HEADER) $(foreach deb,$* $($*_DERIVED_DEBS), \ - { wget --no-use-server-timestamps -O $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || exit 1 ; } ; ) + { curl -f -o $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || { exit 1 ; } } ; ) $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) @@ -269,7 +269,7 @@ SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) # SONIC_ONLINE_FILES += $(SOME_NEW_FILE) $(addprefix $(FILES_PATH)/, $(SONIC_ONLINE_FILES)) : $(FILES_PATH)/% : .platform $(HEADER) - wget --no-use-server-timestamps -O $@ $($*_URL) $(LOG) + curl -f -o $@ $($*_URL) $(LOG) $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_ONLINE_FILES)) @@ -631,7 +631,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ # Pass initramfs and linux kernel explicitly. They are used for all platforms export debs_path="$(STRETCH_DEBS_PATH)" export files_path="$(FILES_PATH)" - export python_debs_path="$(PYTHON_DEBS_PATH)" + export python_debs_path="$(PYTHON_DEBS_PATH)" export initramfs_tools="$(STRETCH_DEBS_PATH)/$(INITRAMFS_TOOLS)" export linux_kernel="$(STRETCH_DEBS_PATH)/$(LINUX_KERNEL)" export onie_recovery_image="$(FILES_PATH)/$(ONIE_RECOVERY_IMAGE)" From 87f70108cb240c484dff6913500e56eda8c1bdb5 Mon Sep 17 00:00:00 2001 From: Prabhu Sreenivasan <45380242+PrabhuSreenivasan@users.noreply.github.com> Date: Tue, 24 Dec 2019 11:17:16 +0530 Subject: [PATCH 0259/1427] SONiC Management Framework Release 1.0 (#3488) * Added sonic-mgmt-framework as submodule / docker * fix build issues * update sonic-mgmt-framework submodule branch to master * Merged changes 70007e6d2ba3a4c0b371cd693ccc63e0a8906e77..00d4fcfed6a759e40d7b92120ea0ee1f08300fc6 00d4fcfed6a759e40d7b92120ea0ee1f08300fc6 Modified environemnt variables * Changes to build sonic-mgmt-framework docker * bumped up sonic-mgmt-framework commit-id * version bump for sonic-mgmt-framework commit-it * bumped up sonic-mgmt-framework commit-id * Add python packages to docker * Build fix for docker with python packages * added libyang as dependent package * Allow building images on NFS-mounted clones Prior to this change, `build_debian.sh` would generate a Debian filesystem in `./fsroot`. This needs root permissions, and one of the tests that is performed is whether the user can create a character special file in the filesystem (using mknod). On most NFS deployments, `root` is the least privileged user, and cannot run mknod. Also, attempting to run commands like rm or mv as root would fail due to permission errors, since the root user gets mapped to an unprivileged user like `nobody`. This commit changes the location of the Debian filesystem to `/fsroot`, which is a tmpfs mount within the slave Docker. The default squashfs, docker tarball and zip files are also created within /tmp, before being copied back to /sonic as the regular user. The side effect of this change is that the contents of `/fsroot` are no longer available once the slave container exits, however they are available within the squashfs image. Signed-off-by: Nirenjan Krishnan * bumped up sonc-mgmt-framework commit to include PR #18 * REST Server startup script is enahnced to read the settings from ConfigDB. Below table provides mapping of db field to command line argument name. ============================================================ ConfigDB entry key Field name REST Server argument ============================================================ REST_SERVER|default port -port REST_SERVER|default client_auth -client_auth REST_SERVER|default log_level -v DEVICE_METADATA|x509 server_crt -cert DEVICE_METADATA|x509 server_key -key DEVICE_METADATA|x509 ca_crt -cacert ============================================================ * Replace src/telemetry as submodule to sonic-telemetry * Update telemetry commit HEAD * Update sonic-telemetry commit HEAD * libyang env path update * Add libyang dependency to telemetry * Add scripts to create JSON files for CLI backend Scripts to create /var/platform/syseeprom and /var/platform/system, which are back-end files for CLI, for system EEPROM and system information. Signed-off-by: Howard Persh * In startup script, create directory where CLI back-end files live Signed-off-by: Howard Persh * build dependency pkgs added to docker for build failure fix * Changes to fix build issue for mgmt framework * Fix exec path issue with telemetry * s5232[device] PSU detecttion and default led state support * Processing of first boot in rc.local should not have premature exit Signed-off-by: Howard Persh * docker mount options added for platform, system features * bumped up sonic-mgmt-framework commit id to pick 23rd July 2019 changes * Added mount options for telemetry docker to get access for system and platform info. * Update commit for sonic-utilities * [dell]: Corrected dport map and renamed config files for S5232F * Fix telemetry submodule commit * added support for sonic-cli console * [Dell S5232F, Z9264F] Harden FPGA driver kernel module For Dell S5232F and Z9264F platforms, be more strict when checking state in ISR of FPGA driver, to harden against spurious interrupts. Signed-off-by: Howard Persh * update mgmt-framework submodule to 27th Aug commit. * remove changes not related to mgmt-framework and sonic-telemetry * Revert "Replace src/telemetry as submodule to sonic-telemetry" This reverts commit 11c31929759a17122782d4944066a6ac8453b78d. * Revert "Replace src/telemetry as submodule to sonic-telemetry" This reverts commit 11c31929759a17122782d4944066a6ac8453b78d. * make submodule changes and remove a change not related to PR * more changes * Update .gitmodules * Update Dockerfile.j2 * Update .gitmodules * Update .gitmodules * Update .gitmodules reverting experimental change * Removed syspoll for release_1.0 Signed-off-by: Jeff Yin <29264773+jeff-yin@users.noreply.github.com> * Update docker-sonic-mgmt-framework.mk * Update sonic-mgmt-framework.mk * Update sonic-mgmt-framework.mk * Update docker-sonic-mgmt-framework.mk * Update docker-sonic-mgmt-framework.mk * Revert "Processing of first boot in rc.local should not have premature exit" This reverts commit e99a91ffc28a0fd13f4ad458719d2511c3665431. * Remove old telemetry directory * Update docker-sonic-mgmt-framework.mk * Resolving merge conflict with Azure * Reverting the wrong merge * Use CVL_SCHEMA_PATH instead of changing directory for telemetry startup * Add missing export * Add python mmh3 to slave dockerfile * Remove sonic-mgmt-framework build dep for telemetry, fix dialout startup issues * Provided flag to disable compiling mgmt-framework * Update sonic-utilites point latest commit id * Point sonic-utilities to Azure accepted SHA * Updating mgmt framework to right sha * Add sonic-telemetry submodule * Update the mgmt-framework commit id Co-authored-by: jghalam Co-authored-by: Partha Dutta <51353699+dutta-partha@users.noreply.github.com> Co-authored-by: srideepDell Co-authored-by: nirenjan Co-authored-by: Sachin Holla <51310506+sachinholla@users.noreply.github.com> Co-authored-by: Eric Seifert Co-authored-by: Howard Persh Co-authored-by: Jeff Yin <29264773+jeff-yin@users.noreply.github.com> Co-authored-by: Arunsundar Kannan <31632515+arunsundark@users.noreply.github.com> Co-authored-by: rvasanthm <51932293+rvasanthm@users.noreply.github.com> Co-authored-by: Ashok Daparthi-Dell Co-authored-by: anand-kumar-subramanian <51383315+anand-kumar-subramanian@users.noreply.github.com> --- .gitmodules | 6 +++ .../docker-sonic-mgmt-framework/Dockerfile.j2 | 42 +++++++++++++++ .../base_image_files/sonic-cli | 4 ++ .../rest-server.sh | 52 +++++++++++++++++++ dockers/docker-sonic-mgmt-framework/start.sh | 10 ++++ .../supervisord.conf | 28 ++++++++++ dockers/docker-sonic-telemetry/dialout.sh | 2 +- .../docker-sonic-telemetry/supervisord.conf | 4 +- dockers/docker-sonic-telemetry/telemetry.sh | 1 + .../build_templates/mgmt-framework.service.j2 | 14 +++++ files/image_config/platform/rc.local | 3 ++ rules/config | 3 ++ rules/docker-sonic-mgmt-framework.mk | 34 ++++++++++++ rules/docker-telemetry.mk | 1 + rules/sonic-mgmt-framework.mk | 16 ++++++ rules/telemetry.mk | 4 +- sonic-slave-stretch/Dockerfile.j2 | 3 ++ src/sonic-mgmt-framework | 1 + src/sonic-telemetry | 1 + src/telemetry/Makefile | 20 ------- src/telemetry/debian/changelog | 5 -- src/telemetry/debian/compat | 1 - src/telemetry/debian/control | 17 ------ src/telemetry/debian/rules | 3 -- src/telemetry/debian/telemetry.init.d | 14 ----- 25 files changed, 225 insertions(+), 64 deletions(-) create mode 100644 dockers/docker-sonic-mgmt-framework/Dockerfile.j2 create mode 100755 dockers/docker-sonic-mgmt-framework/base_image_files/sonic-cli create mode 100755 dockers/docker-sonic-mgmt-framework/rest-server.sh create mode 100755 dockers/docker-sonic-mgmt-framework/start.sh create mode 100644 dockers/docker-sonic-mgmt-framework/supervisord.conf create mode 100644 files/build_templates/mgmt-framework.service.j2 create mode 100644 rules/docker-sonic-mgmt-framework.mk create mode 100644 rules/sonic-mgmt-framework.mk create mode 160000 src/sonic-mgmt-framework create mode 160000 src/sonic-telemetry delete mode 100644 src/telemetry/Makefile delete mode 100644 src/telemetry/debian/changelog delete mode 100644 src/telemetry/debian/compat delete mode 100644 src/telemetry/debian/control delete mode 100755 src/telemetry/debian/rules delete mode 100644 src/telemetry/debian/telemetry.init.d diff --git a/.gitmodules b/.gitmodules index b2ffb2b26fff..0cccf14a8e94 100644 --- a/.gitmodules +++ b/.gitmodules @@ -66,6 +66,12 @@ [submodule "platform/mellanox/mlnx-sai/SAI-Implementation"] path = platform/mellanox/mlnx-sai/SAI-Implementation url = https://github.com/Mellanox/SAI-Implementation +[submodule "src/sonic-mgmt-framework"] + path = src/sonic-mgmt-framework + url = https://github.com/Azure/sonic-mgmt-framework +[submodule "src/sonic-telemetry"] + path = src/sonic-telemetry + url = https://github.com/Azure/sonic-telemetry [submodule "Switch-SDK-drivers"] path = platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers url = https://github.com/Mellanox/Switch-SDK-drivers diff --git a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 new file mode 100644 index 000000000000..08c819c1cc14 --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 @@ -0,0 +1,42 @@ +FROM docker-config-engine-stretch + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update +RUN pip install connexion==1.1.15 \ + setuptools==21.0.0 \ + grpcio-tools==1.20.0 \ + pyangbind==0.6.0 \ + certifi==2017.4.17 \ + python-dateutil==2.6.0 \ + six==1.11.0 \ + urllib3==1.21.1 + + + +## Install redis-tools dependencies +## TODO: implicitly install dependencies +RUN apt-get -y install libjemalloc1 libatomic1 liblua5.1-0 lua-bitop lua-cjson + +COPY \ +{% for deb in docker_sonic_mgmt_framework_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN dpkg -i \ +{% for deb in docker_sonic_mgmt_framework_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor %} + +COPY ["start.sh", "rest-server.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] + +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /debs + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sonic-mgmt-framework/base_image_files/sonic-cli b/dockers/docker-sonic-mgmt-framework/base_image_files/sonic-cli new file mode 100755 index 000000000000..6675e3badbaf --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/base_image_files/sonic-cli @@ -0,0 +1,4 @@ +#!/bin/bash + +docker exec -it mgmt-framework /usr/sbin/cli/clish_start "$@" + diff --git a/dockers/docker-sonic-mgmt-framework/rest-server.sh b/dockers/docker-sonic-mgmt-framework/rest-server.sh new file mode 100755 index 000000000000..f2a29c9b1ed2 --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/rest-server.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# Startup script for SONiC Management REST Server + +SERVER_PORT= +LOG_LEVEL= +CLIENT_AUTH= +SERVER_CRT= +SERVER_KEY= +CA_CERT= + +# Read basic server settings from REST_SERVER|default entry +HAS_REST_CONFIG=$(sonic-cfggen -d -v "1 if REST_SERVER and REST_SERVER['default']") +if [ "$HAS_REST_CONFIG" == "1" ]; then + SERVER_PORT=$(sonic-cfggen -d -v "REST_SERVER['default']['port']") + CLIENT_AUTH=$(sonic-cfggen -d -v "REST_SERVER['default']['client_auth']") + LOG_LEVEL=$(sonic-cfggen -d -v "REST_SERVER['default']['log_level']") +fi + +# Read certificate file paths from DEVICE_METADATA|x509 entry. +HAS_X509_CONFIG=$(sonic-cfggen -d -v "1 if DEVICE_METADATA and DEVICE_METADATA['x509']") +if [ "$HAS_X509_CONFIG" == "1" ]; then + SERVER_CRT=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']") + SERVER_KEY=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']") + CA_CRT=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']") +fi + +# Create temporary server certificate if they not configured in ConfigDB +if [ -z $SERVER_CRT ] && [ -z $SERVER_KEY ]; then + echo "Generating temporary TLS server certificate ..." + (cd /tmp && /usr/sbin/generate_cert --host="localhost,127.0.0.1") + SERVER_CRT=/tmp/cert.pem + SERVER_KEY=/tmp/key.pem +fi + + +REST_SERVER_ARGS="-ui /rest_ui -logtostderr" +[ ! -z $SERVER_PORT ] && REST_SERVER_ARGS+=" -port $SERVER_PORT" +[ ! -z $LOG_LEVEL ] && REST_SERVER_ARGS+=" -v $LOG_LEVEL" +[ ! -z $CLIENT_AUTH ] && REST_SERVER_ARGS+=" -client_auth $CLIENT_AUTH" +[ ! -z $SERVER_CRT ] && REST_SERVER_ARGS+=" -cert $SERVER_CRT" +[ ! -z $SERVER_KEY ] && REST_SERVER_ARGS+=" -key $SERVER_KEY" +[ ! -z $CA_CRT ] && REST_SERVER_ARGS+=" -cacert $CA_CRT" + +echo "REST_SERVER_ARGS = $REST_SERVER_ARGS" + + +export CVL_SCHEMA_PATH=/usr/sbin/schema +export LIBYANG_EXTENSIONS_PLUGINS_DIR=/usr/lib/x86_64-linux-gnu/libyang/extensions +export LIBYANG_USER_TYPES_PLUGINS_DIR=/usr/lib/x86_64-linux-gnu/libyang/user_types + +exec /usr/sbin/rest_server ${REST_SERVER_ARGS} diff --git a/dockers/docker-sonic-mgmt-framework/start.sh b/dockers/docker-sonic-mgmt-framework/start.sh new file mode 100755 index 000000000000..24d355670e87 --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/start.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +rm -f /var/run/rsyslogd.pid + +supervisorctl start rsyslogd + +supervisorctl start rest-server diff --git a/dockers/docker-sonic-mgmt-framework/supervisord.conf b/dockers/docker-sonic-mgmt-framework/supervisord.conf new file mode 100644 index 000000000000..e26f815f5fb9 --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/supervisord.conf @@ -0,0 +1,28 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rest-server] +command=/usr/bin/rest-server.sh +priority=3 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/dockers/docker-sonic-telemetry/dialout.sh b/dockers/docker-sonic-telemetry/dialout.sh index 8683e8edae8e..485c3292d0df 100755 --- a/dockers/docker-sonic-telemetry/dialout.sh +++ b/dockers/docker-sonic-telemetry/dialout.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Start with default config - +export CVL_SCHEMA_PATH=/usr/sbin/schema exec /usr/sbin/dialout_client_cli -insecure -logtostderr -v 2 diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index b6a01de58a7b..e1346fe7db4e 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -6,8 +6,8 @@ nodaemon=true [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener events=PROCESS_STATE_EXITED -autostart=always -autorestart=unexpected +autostart=true +autorestart=false [program:start.sh] command=/usr/bin/start.sh diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 8cfd8a531cca..8b29b4d616a5 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -6,6 +6,7 @@ X509=`sonic-cfggen -d -v "DEVICE_METADATA['x509']"` TELEMETRY=`sonic-cfggen -d -v 'TELEMETRY.keys() | join(" ") if TELEMETRY'` TELEMETRY_ARGS=" -logtostderr" +export CVL_SCHEMA_PATH=/usr/sbin/schema if [ -n "$X509" ]; then SERVER_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']"` diff --git a/files/build_templates/mgmt-framework.service.j2 b/files/build_templates/mgmt-framework.service.j2 new file mode 100644 index 000000000000..d0a030347b51 --- /dev/null +++ b/files/build_templates/mgmt-framework.service.j2 @@ -0,0 +1,14 @@ +[Unit] +Description=Management Framework container +Requires=swss.service +After=swss.service +Before=ntp-config.service + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index b74e9f40c4b0..d64ec1bb7916 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -331,4 +331,7 @@ if [ -f $FIRST_BOOT_FILE ]; then firsttime_exit fi +# Create dir where following scripts put their output files +mkdir -p /var/platform + exit 0 diff --git a/rules/config b/rules/config index c158fcc27726..a559a5b2fc88 100644 --- a/rules/config +++ b/rules/config @@ -101,3 +101,6 @@ DEFAULT_VS_PREPARE_MEM = yes # ENABLE_SYSTEM_SFLOW - build docker-sonic-sflow for sFlow support ENABLE_SFLOW = y + +# ENABLE_MGMT_FRAMEWORK - build docker-sonic-mgt-framework for CLI and REST server support +ENABLE_MGMT_FRAMEWORK = y diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk new file mode 100644 index 000000000000..eb99f37875fc --- /dev/null +++ b/rules/docker-sonic-mgmt-framework.mk @@ -0,0 +1,34 @@ +# docker image for mgmt-framework + +DOCKER_MGMT_FRAMEWORK_STEM = docker-sonic-mgmt-framework +DOCKER_MGMT_FRAMEWORK = $(DOCKER_MGMT_FRAMEWORK_STEM).gz +DOCKER_MGMT_FRAMEWORK_DBG = $(DOCKER_MGMT_FRAMEWORK_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_MGMT_FRAMEWORK)_PATH = $(DOCKERS_PATH)/$(DOCKER_MGMT_FRAMEWORK_STEM) + +$(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK) +$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK_DBG) + +SONIC_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) +$(DOCKER_MGMT_FRAMEWORK)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_MGMT_FRAMEWORK)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) + +ifeq ($(ENABLE_MGMT_FRAMEWORK), y) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) +SONIC_STRETCH_DOCKERS += $(DOCKER_MGMT_FRAMEWORK) +endif + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) +ifeq ($(ENABLE_MGMT_FRAMEWORK), y) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_MGMT_FRAMEWORK_DBG) +endif + +$(DOCKER_MGMT_FRAMEWORK)_CONTAINER_NAME = mgmt-framework +$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --net=host --privileged -t +$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += -v /etc:/host_etc:ro +$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" + +$(DOCKER_MGMT_FRAMEWORK)_BASE_IMAGE_FILES += sonic-cli:/usr/bin/sonic-cli diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index defeb4d00821..799bef1b1735 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -27,5 +27,6 @@ endif $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry $(DOCKER_TELEMETRY)_RUN_OPT += --net=host --privileged -t $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" $(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/sonic-mgmt-framework.mk b/rules/sonic-mgmt-framework.mk new file mode 100644 index 000000000000..a57ce6b1b083 --- /dev/null +++ b/rules/sonic-mgmt-framework.mk @@ -0,0 +1,16 @@ +# SONiC mgmt-framework package + +ifeq ($(ENABLE_MGMT_FRAMEWORK), y) + +SONIC_MGMT_FRAMEWORK = sonic-mgmt-framework_1.0-01_amd64.deb +$(SONIC_MGMT_FRAMEWORK)_SRC_PATH = $(SRC_PATH)/sonic-mgmt-framework +$(SONIC_MGMT_FRAMEWORK)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) +$(SONIC_MGMT_FRAMEWORK)_RDEPENDS = $(LIBYANG) +SONIC_DPKG_DEBS += $(SONIC_MGMT_FRAMEWORK) + +SONIC_MGMT_FRAMEWORK_DBG = sonic-mgmt-framework-dbg_1.0-01_amd64.deb +$(SONIC_MGMT_FRAMEWORK_DBG)_DEPENDS += $(SONIC_MGMT_FRAMEWORK) +$(SONIC_MGMT_FRAMEWORK_DBG)_RDEPENDS += $(SONIC_MGMT_FRAMEWORK) +$(eval $(call add_derived_package,$(SONIC_MGMT_FRAMEWORK),$(SONIC_MGMT_FRAMEWORK_DBG))) + +endif diff --git a/rules/telemetry.mk b/rules/telemetry.mk index 1d903e603251..0b4421b11942 100644 --- a/rules/telemetry.mk +++ b/rules/telemetry.mk @@ -1,5 +1,7 @@ # SONiC telemetry package SONIC_TELEMETRY = sonic-telemetry_0.1_$(CONFIGURED_ARCH).deb -$(SONIC_TELEMETRY)_SRC_PATH = $(SRC_PATH)/telemetry +$(SONIC_TELEMETRY)_SRC_PATH = $(SRC_PATH)/sonic-telemetry +$(SONIC_TELEMETRY)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) +$(SONIC_TELEMETRY)_RDEPENDS = $(LIBYANG) SONIC_DPKG_DEBS += $(SONIC_TELEMETRY) diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 08e002624abb..d0e3775396dc 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -362,6 +362,9 @@ RUN pip install mockredispy==2.9.3 RUN pip install pytest-runner==4.4 RUN pip install setuptools==40.8.0 +# For mgmt-framework build +RUN pip install mmh3 + # Install dependencies for isc-dhcp-relay build RUN apt-get -y build-dep isc-dhcp diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework new file mode 160000 index 000000000000..8b199a9f822c --- /dev/null +++ b/src/sonic-mgmt-framework @@ -0,0 +1 @@ +Subproject commit 8b199a9f822ca42564a7a89da0cab3133684bd12 diff --git a/src/sonic-telemetry b/src/sonic-telemetry new file mode 160000 index 000000000000..aaa9188fda4b --- /dev/null +++ b/src/sonic-telemetry @@ -0,0 +1 @@ +Subproject commit aaa9188fda4b6f36dd5da00cdb240933fedae5ce diff --git a/src/telemetry/Makefile b/src/telemetry/Makefile deleted file mode 100644 index 91a822d4f93c..000000000000 --- a/src/telemetry/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -export GOPATH=/tmp/go - -INSTALL := /usr/bin/install - -all: sonic-telemetry - -sonic-telemetry: - /usr/local/go/bin/go get -v github.com/Azure/sonic-telemetry/telemetry - /usr/local/go/bin/go get -v github.com/Azure/sonic-telemetry/dialout/dialout_client_cli - -install: - $(INSTALL) -D ${GOPATH}/bin/telemetry $(DESTDIR)/usr/sbin/telemetry - $(INSTALL) -D ${GOPATH}/bin/dialout_client_cli $(DESTDIR)/usr/sbin/dialout_client_cli - -deinstall: - rm $(DESTDIR)/usr/sbin/telemetry - rm $(DESTDIR)/usr/sbin/dialout_client_cli - -clean: - rm -fr ${GOPATH} diff --git a/src/telemetry/debian/changelog b/src/telemetry/debian/changelog deleted file mode 100644 index 77dab629040e..000000000000 --- a/src/telemetry/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -sonic-telemetry (0.1) UNRELEASED; urgency=medium - - * Initial release. - - -- Jipan Yang Sat, 24 Mar 2018 12:48:22 -0700 diff --git a/src/telemetry/debian/compat b/src/telemetry/debian/compat deleted file mode 100644 index ec635144f600..000000000000 --- a/src/telemetry/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/src/telemetry/debian/control b/src/telemetry/debian/control deleted file mode 100644 index f1b6a7c07282..000000000000 --- a/src/telemetry/debian/control +++ /dev/null @@ -1,17 +0,0 @@ -Source: sonic-telemetry -Section: devel -Priority: optional -Maintainer: Jipan Yang -Build-Depends: debhelper (>= 8.0.0), - dh-systemd -Standards-Version: 3.9.3 -Homepage: https://github.com/Azure/sonic-telemetry -XS-Go-Import-Path: github.com/Azure/sonic-telemetry - -Package: sonic-telemetry -Architecture: any -Built-Using: ${misc:Built-Using} -Depends: ${misc:Depends}, - ${shlibs:Depends} -Description: SONiC telemetry - sonic-telemetry \ No newline at end of file diff --git a/src/telemetry/debian/rules b/src/telemetry/debian/rules deleted file mode 100755 index 3995a26d7fcd..000000000000 --- a/src/telemetry/debian/rules +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/make -f -%: - dh $@ --with systemd diff --git a/src/telemetry/debian/telemetry.init.d b/src/telemetry/debian/telemetry.init.d deleted file mode 100644 index 2fea32e17c49..000000000000 --- a/src/telemetry/debian/telemetry.init.d +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -# -### BEGIN INIT INFO -# Provides: sonic-telemetry -# Required-Start: $local_fs $network $remote_fs $syslog -# Required-Stop: $local_fs $network $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: start and stop the telemetry -# Description: sonic-telemetry is an implementation of sonic telemetry daemon in Go -### END INIT INFO -# - -exit 0 From baea7e2a24d5e948ef47b3922839ff8066a16766 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Fri, 27 Dec 2019 19:26:51 +0200 Subject: [PATCH 0260/1427] [slave.mk] make curl follow HTTP redirects (#3947) Fix an issue with SONIC_ONLINE_DEBS with curl by instructing curl to follow http redirects Signed-off-by: Stepan Blyschak --- slave.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slave.mk b/slave.mk index f62be5672221..382b03607186 100644 --- a/slave.mk +++ b/slave.mk @@ -256,7 +256,7 @@ SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_COPY_FILES)) $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) : $(DEBS_PATH)/% : .platform $(HEADER) $(foreach deb,$* $($*_DERIVED_DEBS), \ - { curl -f -o $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || { exit 1 ; } } ; ) + { curl -L -f -o $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || { exit 1 ; } } ; ) $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) @@ -269,7 +269,7 @@ SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) # SONIC_ONLINE_FILES += $(SOME_NEW_FILE) $(addprefix $(FILES_PATH)/, $(SONIC_ONLINE_FILES)) : $(FILES_PATH)/% : .platform $(HEADER) - curl -f -o $@ $($*_URL) $(LOG) + curl -L -f -o $@ $($*_URL) $(LOG) $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_ONLINE_FILES)) From 86ab2aee06e931cf1fb21d86de150371cf0cea60 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Fri, 27 Dec 2019 09:30:47 -0800 Subject: [PATCH 0261/1427] [swsssdk-py] submodule update for sonic-py-swsssdk (#3929) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update multiDB changes in sonic-py-swsssdk, including: - read portchannel name from LAG_NAME_MAP_TABLE in COUNTERS_DB (#51) - Revert "read portchannel name from LAG_NAME_MAP_TABLE in COUNTERS_DB (#51)" (#57) - [MultiDB] sonic-db-cli should support EVAL operation, app script use … (#58) PR #3928 needs this swsssdk-py changes to work Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index bc3964b788c3..ccc1307aae0b 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit bc3964b788c3a4a45f2b359a5df5934ecdee84c2 +Subproject commit ccc1307aae0b017a5c0d92385c9df67379da6d22 From 18cb5c6765a694467ab4eca733efab9ab9ad00b6 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Fri, 27 Dec 2019 19:38:39 +0200 Subject: [PATCH 0262/1427] [swss] submodule update (#3925) 9f6efa0 [port/buffer] introduce a sync mechanism to protect port PG/queue from changes under PFC storm (#1143) 823e426 [aclorch] Enable DSCP rules on IPv6 mirror tables (#1146) b8745f8 [bitmap_vnet]: Fix removal flow for tunnel route (#1139) 03be983 Increase ip2me CIR/CBR for faster in-band file transfers (#1000) a4a1d3b [vnet]: Update VNET route table size to 40K for BITMAP implementation (#1132) efe142a Fix bug: Wrong condition for mac address (#1142) 7bf63a0 [teammgrd]during warm-reboot teamd need to recover system-id from saved lacp-pdu (#1003) 8b4cfb6 Cleanup configure.ac from BFN specific code (#1133) b931751 [teamsyncd]: Add retry logic in teamsyncd to avoid team handler init failure (#854) Signed-off-by: Stepan Blyschak --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index fc085ee70df1..9f6efa088d86 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit fc085ee70df1b6e4edf512bcfac212be429ab021 +Subproject commit 9f6efa088d8645572b82af590f20e8d60e9be285 From bd72844f758dbe424a07f4b4fe98d326764f2725 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 28 Dec 2019 21:21:09 +0000 Subject: [PATCH 0263/1427] [kvm]: increase the kvm installer size to 2G for dbg image Signed-off-by: Guohan Lu --- scripts/build_kvm_image.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_kvm_image.sh b/scripts/build_kvm_image.sh index a8ae21c9777a..5a56ac46efce 100755 --- a/scripts/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -31,7 +31,7 @@ create_disk() prepare_installer_disk() { - fallocate -l 1024M $INSTALLER_DISK + fallocate -l 2048M $INSTALLER_DISK mkfs.vfat $INSTALLER_DISK From 78db0804d3a0ab9cf54a7ddf4c4d00c7ecd8751d Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Mon, 30 Dec 2019 13:01:03 -0800 Subject: [PATCH 0264/1427] corefile uploader: Updates per review comments offline (#3915) * Updates per review comments 1) core_uploader service waits for syslog.service 2) core_uploader service enabled for restart on failure 3) Use mtime instead of file size + ample time to be robust. * Avoid reloading already uploaded file, by marking the names with a prefix. * Updated failing path. 1) If rc file is missing or required data missing, it periodically logs error in forever loop. 2) If upload fails, retry every hour with a error log, forever. * Fix few bugs * The binary update_json.py will come from sonic-utilities. --- .../build_templates/sonic_debian_extension.j2 | 1 - .../corefile_uploader/core_uploader.py | 47 +++++++++------- .../corefile_uploader/core_uploader.service | 6 +- .../corefile_uploader/update_json.py | 55 ------------------- 4 files changed, 32 insertions(+), 77 deletions(-) delete mode 100755 files/image_config/corefile_uploader/update_json.py diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index b63b5addac4b..a007745406e4 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -225,7 +225,6 @@ sudo cp $IMAGE_CONFIGS/hostcfgd/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.service $FILESYSTEM_ROOT/etc/systemd/system/ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable core_uploader.service sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.py $FILESYSTEM_ROOT/usr/bin/ -sudo cp $IMAGE_CONFIGS/corefile_uploader/update_json.py $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/corefile_uploader/core_analyzer.rc.json $FILESYSTEM_ROOT_ETC_SONIC/ sudo chmod og-rw $FILESYSTEM_ROOT_ETC_SONIC/core_analyzer.rc.json sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage diff --git a/files/image_config/corefile_uploader/core_uploader.py b/files/image_config/corefile_uploader/core_uploader.py index 676ff9583b06..2ae91ce0896b 100755 --- a/files/image_config/corefile_uploader/core_uploader.py +++ b/files/image_config/corefile_uploader/core_uploader.py @@ -36,7 +36,11 @@ HOURS_4 = (4 * 60 * 60) PAUSE_ON_FAIL = (60 * 60) +WAIT_FILE_WRITE1 = (10 * 60) +WAIT_FILE_WRITE2= (5 * 60) +POLL_SLEEP = (60 * 60) MAX_RETRIES = 5 +UPLOAD_PREFIX = "UPLOADED_" log_level = syslog.LOG_DEBUG @@ -116,7 +120,7 @@ def run(self): self.observer.start() try: while True: - time.sleep(5) + time.sleep(POLL_SLEEP) except: self.observer.stop() log_err("Error in watcher") @@ -179,29 +183,33 @@ def on_any_event(event): elif event.event_type == 'created': # Take any action here when a file is first created. log_debug("Received create event - " + event.src_path) + Handler.wait_for_file_write_complete(event.src_path) Handler.handle_file(event.src_path) @staticmethod def wait_for_file_write_complete(path): - ct_size = -1 + mtime = 0 - while ct_size != os.path.getsize(path): - ct_size = os.path.getsize(path) - time.sleep(2) + # Sleep for ample time enough for file dump to complete. + time.sleep(WAIT_FILE_WRITE1) - time.sleep(2) - if ct_size != os.path.getsize(path): + # Give another chance & poll until mtime stabilizes + while mtime != os.stat(path).st_mtime: + mtime = os.stat(path).st_mtime + time.sleep(10) + + # A safety pause for double confirmation + time.sleep(WAIT_FILE_WRITE2) + if mtime != os.stat(path).st_mtime: raise Exception("Dump file creation is too slow: " + path) + # Give up as something is terribly wrong with this file. log_debug("File write complete - " + path) @staticmethod def handle_file(path): - - Handler.wait_for_file_write_complete(path) - lpath = "/".join(cwd) make_new_dir(lpath) os.chdir(lpath) @@ -221,18 +229,18 @@ def handle_file(path): tar.close() log_debug("Tar file for upload created: " + tarf_name) - Handler.upload_file(tarf_name, tarf_name) + Handler.upload_file(tarf_name, tarf_name, path) log_debug("File uploaded - " + path) os.chdir(INIT_CWD) @staticmethod - def upload_file(fname, fpath): + def upload_file(fname, fpath, coref): daemonname = fname.split(".")[0] i = 0 fail_msg = "" - while i <= MAX_RETRIES: + while True: try: svc = FileService(account_name=acctname, account_key=acctkey) @@ -246,14 +254,15 @@ def upload_file(fname, fpath): svc.create_file_from_path(sharename, "/".join(l), fname, fpath) log_debug("Remote file created: name{} path{}".format(fname, fpath)) + newcoref = os.path.dirname(coref) + "/" + UPLOAD_PREFIX + os.path.basename(coref) + os.rename(coref, newcoref) break - except Exception as e: - log_err("core uploader failed: Failed during upload (" + str(e) +")") - fail_msg = str(e) + except Exception as ex: + log_err("core uploader failed: Failed during upload (" + coref + ") err: ("+ str(ex) +") retry:" + str(i)) + if not os.path.exists(fpath): + break i += 1 - if i >= MAX_RETRIES: - raise Exception("Failed while uploading. msg(" + fail_msg + ") after " + str(i) + " retries") time.sleep(PAUSE_ON_FAIL) @@ -261,7 +270,7 @@ def upload_file(fname, fpath): def scan(): for e in os.listdir(CORE_FILE_PATH): fl = CORE_FILE_PATH + e - if os.path.isfile(fl): + if os.path.isfile(fl) and not e.startswith(UPLOAD_PREFIX): Handler.handle_file(fl) diff --git a/files/image_config/corefile_uploader/core_uploader.service b/files/image_config/corefile_uploader/core_uploader.service index 5c061e72a16e..09ac1bd5191f 100644 --- a/files/image_config/corefile_uploader/core_uploader.service +++ b/files/image_config/corefile_uploader/core_uploader.service @@ -1,11 +1,13 @@ [Unit] Description=Host core file uploader daemon -Requires=updategraph.service -After=updategraph.service +Requires=syslog.service +After=syslog.service [Service] Type=simple ExecStart=/usr/bin/core_uploader.py +StandardOutput=null +Restart=on-failure [Install] WantedBy=multi-user.target diff --git a/files/image_config/corefile_uploader/update_json.py b/files/image_config/corefile_uploader/update_json.py deleted file mode 100755 index 03bb39aa4ec8..000000000000 --- a/files/image_config/corefile_uploader/update_json.py +++ /dev/null @@ -1,55 +0,0 @@ -#! /usr/bin/env python - -import os -import sys -import json -import argparse - -TMP_SUFFIX = ".tmp" -BAK_SUFFIX = ".bak" - -def dict_update(dst, patch): - for k in patch.keys(): - if type(patch[k]) == dict: - dst[k] = dict_update(dst[k], patch[k]) - else: - dst[k] = patch[k] - return dst - -def do_update(rcf, patchf): - dst = {} - patch = {} - - tmpf = rcf + TMP_SUFFIX - bakf = rcf + BAK_SUFFIX - - with open(rcf, "r") as f: - dst = json.load(f) - - with open(patchf, "r") as f: - patch = json.load(f) - - dst = dict_update(dst, patch) - - with open(tmpf, "w") as f: - json.dump(dst, f, indent = 4) - - os.rename(rcf, bakf) - os.rename(tmpf, rcf) - - -def main(): - parser=argparse.ArgumentParser(description="Update JSON based file") - parser.add_argument("-r", "--rc", help="JSON file to be updated") - parser.add_argument("-p", "--patch", help="JSON file holding patch") - args = parser.parse_args() - - if not args.rc or not args.patch: - raise Exception("check usage") - - do_update(args.rc, args.patch) - -if __name__ == '__main__': - main() - - From 08cde0600c2dc5015894a56fe8ba4f5da49f85c9 Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Tue, 31 Dec 2019 07:39:32 +0530 Subject: [PATCH 0265/1427] [Juniper][QFX5210] Adding qos.json (#3946) Adding buffers.json.j2, buffers_defaults_t1.j2 and qos.json.j2 for qfx5210 platform. Signed-off-by: Ciju Rajan K --- .../Juniper-QFX5210-64C/buffers.json.j2 | 1 + .../buffers_defaults_t1.j2 | 46 +++++++++++++++++++ .../Juniper-QFX5210-64C/qos.json.j2 | 1 + 3 files changed, 48 insertions(+) create mode 100644 device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers.json.j2 create mode 100644 device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers_defaults_t1.j2 create mode 100644 device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/qos.json.j2 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers.json.j2 b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers_defaults_t1.j2 b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..3442612f70b2 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ +{%- set default_cable = '5m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "33329088", + "type": "ingress", + "mode": "dynamic", + "xoff": "7827456" + }, + "egress_lossy_pool": { + "size": "26663272", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "42349632", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"44302336" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"42349632" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1664", + "dynamic_th":"-1" + } + }, +{%- endmacro %} diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/qos.json.j2 b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} From 24a0c464648fa8d9e53d4cdfdaae7c12eaaaf95f Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 30 Dec 2019 18:25:57 -0800 Subject: [PATCH 0266/1427] [monit] Build from source and patch to use MemAvailable value if available on system (#3875) --- .gitignore | 3 + build_debian.sh | 5 -- .../build_templates/sonic_debian_extension.j2 | 8 +++ files/image_config/monit/conf.d/sonic-host | 22 ++++++ files/image_config/monit/monitrc | 19 +---- rules/monit.mk | 14 ++++ slave.mk | 3 +- src/monit/Makefile | 33 +++++++++ ...ry_sysdep-Use-MemAvailable-value-if-.patch | 70 +++++++++++++++++++ src/monit/patch/series | 2 + 10 files changed, 157 insertions(+), 22 deletions(-) create mode 100644 files/image_config/monit/conf.d/sonic-host create mode 100644 rules/monit.mk create mode 100644 src/monit/Makefile create mode 100644 src/monit/patch/0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch create mode 100644 src/monit/patch/series diff --git a/.gitignore b/.gitignore index 739454168796..1f921971d8bb 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,9 @@ src/lldpd/* !src/lldpd/patch/ src/lm-sensors/* !src/lm-sensors/Makefile +src/monit/* +!src/monit/Makefile +!src/monit/patch/ src/mpdecimal/* !src/mpdecimal/Makefile src/python-click/* diff --git a/build_debian.sh b/build_debian.sh index 666e140416c9..335dab8ba89f 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -240,7 +240,6 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in openssh-server \ python \ python-setuptools \ - monit \ python-apt \ traceroute \ iputils-ping \ @@ -348,10 +347,6 @@ EOF sudo sed -i 's/^ListenAddress ::/#ListenAddress ::/' $FILESYSTEM_ROOT/etc/ssh/sshd_config sudo sed -i 's/^#ListenAddress 0.0.0.0/ListenAddress 0.0.0.0/' $FILESYSTEM_ROOT/etc/ssh/sshd_config -## Config monit -sudo cp files/image_config/monit/monitrc $FILESYSTEM_ROOT/etc/monit/ -sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/monitrc - ## Config sysctl sudo mkdir -p $FILESYSTEM_ROOT/var/core sudo augtool --autosave " diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index a007745406e4..e5dd9d9e0912 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -172,6 +172,14 @@ sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf sudo DEBIAN_FRONTEND=noninteractive dpkg --root=$FILESYSTEM_ROOT -i $debs_path/kdump-tools_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=truechroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install +# Install custom-built monit package and SONiC configuration files +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/monit_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +sudo cp $IMAGE_CONFIGS/monit/monitrc $FILESYSTEM_ROOT/etc/monit/ +sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/monitrc +sudo cp $IMAGE_CONFIGS/monit/conf.d/* $FILESYSTEM_ROOT/etc/monit/conf.d/ +sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/conf.d/* + # Copy crontabs sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ diff --git a/files/image_config/monit/conf.d/sonic-host b/files/image_config/monit/conf.d/sonic-host new file mode 100644 index 000000000000..8eaa1671d821 --- /dev/null +++ b/files/image_config/monit/conf.d/sonic-host @@ -0,0 +1,22 @@ +############################################################################### +## Monit configuration for SONiC host OS +## +## This includes system-level monitoring as well as processes which +## run in the host OS (i.e., not inside a Docker container) +############################################################################### + +check filesystem root-overlay with path / + if space usage > 90% for 5 times within 10 cycles then alert + +check filesystem var-log with path /var/log + if space usage > 90% for 5 times within 10 cycles then alert + +check system $HOST + if memory usage > 90% for 5 times within 10 cycles then alert + if cpu usage (user) > 90% for 5 times within 10 cycles then alert + if cpu usage (system) > 90% for 5 times within 10 cycles then alert + +check process rsyslog with pidfile /var/run/rsyslogd.pid + start program = "/bin/systemctl start rsyslog.service" + stop program = "/bin/systemctl stop rsyslog.service" + if totalmem > 800 MB for 5 times within 10 cycles then restart diff --git a/files/image_config/monit/monitrc b/files/image_config/monit/monitrc index f9350733fa44..7864069e3af1 100644 --- a/files/image_config/monit/monitrc +++ b/files/image_config/monit/monitrc @@ -24,8 +24,7 @@ ## Set syslog logging. If you want to log to a standalone log file instead, ## specify the full path to the log file # -# set logfile /var/log/monit.log -set logfile syslog + set logfile syslog # # ## Set the location of the Monit lock file which stores the process id of the @@ -153,8 +152,8 @@ set logfile syslog ## commands to a running Monit daemon. See the Monit Wiki if you want to ## enable SSL for the HTTP interface. # -set httpd unixsocket /var/run/monit.sock and - allow localhost # allow localhost to connect to the server and + set httpd unixsocket /var/run/monit.sock and + allow localhost # allow localhost to connect to the server # ############################################################################### ## Services @@ -294,15 +293,3 @@ set httpd unixsocket /var/run/monit.sock and include /etc/monit/conf.d/* include /etc/monit/conf-enabled/* # -check filesystem root-overlay with path / - if space usage > 90% for 5 times within 10 cycles then alert -check filesystem var-log with path /var/log - if space usage > 90% for 5 times within 10 cycles then alert -check system $HOST - if memory usage > 90% for 5 times within 10 cycles then alert - if cpu usage (user) > 90% for 5 times within 10 cycles then alert - if cpu usage (system) > 90% for 5 times within 10 cycles then alert -check process rsyslog with pidfile /var/run/rsyslogd.pid - start program = "/bin/systemctl start rsyslog.service" - stop program = "/bin/systemctl stop rsyslog.service" - if totalmem > 800 MB for 5 times within 10 cycles then restart diff --git a/rules/monit.mk b/rules/monit.mk new file mode 100644 index 000000000000..d4c73453e4a6 --- /dev/null +++ b/rules/monit.mk @@ -0,0 +1,14 @@ +# monit package + +MONIT_VERSION = 5.20.0-6 + +export MONIT_VERSION + +MONIT = monit_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb +$(MONIT)_SRC_PATH = $(SRC_PATH)/monit +SONIC_MAKE_DEBS += $(MONIT) + +SONIC_STRETCH_DEBS += $(MONIT) + +MONIT_DBG = monit-dbgsym_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(MONIT),$(MONIT_DBG))) diff --git a/slave.mk b/slave.mk index 382b03607186..9a34e5379b14 100644 --- a/slave.mk +++ b/slave.mk @@ -617,7 +617,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(IFUPDOWN2) \ $(KDUMP_TOOLS) \ $(LIBPAM_TACPLUS) \ - $(LIBNSS_TACPLUS)) \ + $(LIBNSS_TACPLUS) \ + $(MONIT)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(DEBS_PATH)/,$(SONIC_ZTP))) \ diff --git a/src/monit/Makefile b/src/monit/Makefile new file mode 100644 index 000000000000..4ad9edd79143 --- /dev/null +++ b/src/monit/Makefile @@ -0,0 +1,33 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = monit_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb +DERIVED_TARGETS = monit-dbgsym_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Remove any stale files + rm -rf ./monit + + # Clone monit repo + git clone https://salsa.debian.org/sk-guest/monit.git + pushd ./monit + + # Reset HEAD to the commit of the proper tag + # NOTE: Using "git checkout " here detaches our HEAD, + # which stg doesn't like, so we use this method instead + # NOTE: For some reason, tags in the Debian monit repo are prefixed with "1%" + git reset --hard debian/1\%$(MONIT_VERSION) + + # Apply patches + stg init + stg import -s ../patch/series + + # Build source and Debian packages + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + # Move the newly-built .deb packages to the destination directory + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/monit/patch/0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch b/src/monit/patch/0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch new file mode 100644 index 000000000000..9c67d153cbbb --- /dev/null +++ b/src/monit/patch/0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch @@ -0,0 +1,70 @@ +From c392362c9c1d57256b7e8ab7c77926824677fd73 Mon Sep 17 00:00:00 2001 +From: Joe LeVeque +Date: Tue, 19 Nov 2019 01:51:13 +0000 +Subject: [PATCH] [used_system_memory_sysdep] Use 'MemAvailable' value if + available + +--- + src/process/sysdep_LINUX.c | 35 +++++++++++++++++++++++------------ + 1 file changed, 23 insertions(+), 12 deletions(-) + +diff --git a/src/process/sysdep_LINUX.c b/src/process/sysdep_LINUX.c +index 0d18f85..221e785 100644 +--- a/src/process/sysdep_LINUX.c ++++ b/src/process/sysdep_LINUX.c +@@ -335,6 +335,7 @@ int getloadavg_sysdep(double *loadv, int nelem) { + boolean_t used_system_memory_sysdep(SystemInfo_T *si) { + char *ptr; + char buf[2048]; ++ unsigned long mem_available = 0UL; + unsigned long mem_free = 0UL; + unsigned long buffers = 0UL; + unsigned long cached = 0UL; +@@ -343,22 +344,32 @@ boolean_t used_system_memory_sysdep(SystemInfo_T *si) { + unsigned long swap_free = 0UL; + + if (! file_readProc(buf, sizeof(buf), "meminfo", -1, NULL)) { +- LogError("system statistic error -- cannot get real memory free amount\n"); ++ LogError("system statistic error -- cannot read /proc/meminfo\n"); + goto error; + } + +- /* Memory */ +- if (! (ptr = strstr(buf, "MemFree:")) || sscanf(ptr + 8, "%ld", &mem_free) != 1) { +- LogError("system statistic error -- cannot get real memory free amount\n"); +- goto error; ++ /* ++ * Memory ++ * ++ * First, check if the "MemAvailable" value is available on this system. If it is, we will ++ * use it. Otherwise we will attempt to calculate the amount of available memory ourself. ++ */ ++ if ((ptr = strstr(buf, "MemAvailable:")) && sscanf(ptr + 13, "%ld", &mem_available) == 1) { ++ si->total_mem = systeminfo.mem_max - (uint64_t)mem_available * 1024; ++ } else { ++ DEBUG("'MemAvailable' value not available on this system. Attempting to calculate available memory manually...\n"); ++ if (! (ptr = strstr(buf, "MemFree:")) || sscanf(ptr + 8, "%ld", &mem_free) != 1) { ++ LogError("system statistic error -- cannot get real memory free amount\n"); ++ goto error; ++ } ++ if (! (ptr = strstr(buf, "Buffers:")) || sscanf(ptr + 8, "%ld", &buffers) != 1) ++ DEBUG("system statistic error -- cannot get real memory buffers amount\n"); ++ if (! (ptr = strstr(buf, "Cached:")) || sscanf(ptr + 7, "%ld", &cached) != 1) ++ DEBUG("system statistic error -- cannot get real memory cache amount\n"); ++ if (! (ptr = strstr(buf, "SReclaimable:")) || sscanf(ptr + 13, "%ld", &slabreclaimable) != 1) ++ DEBUG("system statistic error -- cannot get slab reclaimable memory amount\n"); ++ si->total_mem = systeminfo.mem_max - (uint64_t)(mem_free + buffers + cached + slabreclaimable) * 1024; + } +- if (! (ptr = strstr(buf, "Buffers:")) || sscanf(ptr + 8, "%ld", &buffers) != 1) +- DEBUG("system statistic error -- cannot get real memory buffers amount\n"); +- if (! (ptr = strstr(buf, "Cached:")) || sscanf(ptr + 7, "%ld", &cached) != 1) +- DEBUG("system statistic error -- cannot get real memory cache amount\n"); +- if (! (ptr = strstr(buf, "SReclaimable:")) || sscanf(ptr + 13, "%ld", &slabreclaimable) != 1) +- DEBUG("system statistic error -- cannot get slab reclaimable memory amount\n"); +- si->total_mem = systeminfo.mem_max - (uint64_t)(mem_free + buffers + cached + slabreclaimable) * 1024; + + /* Swap */ + if (! (ptr = strstr(buf, "SwapTotal:")) || sscanf(ptr + 10, "%ld", &swap_total) != 1) { +-- +2.17.1 + diff --git a/src/monit/patch/series b/src/monit/patch/series new file mode 100644 index 000000000000..15fcdd50c8a5 --- /dev/null +++ b/src/monit/patch/series @@ -0,0 +1,2 @@ +# This series applies on GIT commit dc9bc1c949125140d967edfc598dfad47eedc552 +0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch From ea1128741c28f89294c4296110dcd33dde7458d9 Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Tue, 31 Dec 2019 17:01:08 +0200 Subject: [PATCH 0267/1427] [Mellanox] Update FW/SDK: 13/29.2000.2696 and 4.3.2904 (#3948) --- platform/mellanox/fw.mk | 4 ++-- platform/mellanox/sdk-src/sx-kernel/Makefile | 1 - .../sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- .../sx_kernel_makefile_sonic_build.patch | 18 ------------------ platform/mellanox/sdk.mk | 2 +- 5 files changed, 4 insertions(+), 23 deletions(-) delete mode 100644 platform/mellanox/sdk-src/sx-kernel/sx_kernel_makefile_sonic_build.patch diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 9d506c1f5bdd..eb1a58cfda9d 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,12 +11,12 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.2602 +MLNX_SPC_FW_VERSION = 13.2000.2696 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.2602 +MLNX_SPC2_FW_VERSION = 29.2000.2696 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Makefile b/platform/mellanox/sdk-src/sx-kernel/Makefile index 9e979879fef8..422f2ae95aae 100644 --- a/platform/mellanox/sdk-src/sx-kernel/Makefile +++ b/platform/mellanox/sdk-src/sx-kernel/Makefile @@ -19,7 +19,6 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : fi # build - patch -p1 < ../sx_kernel_makefile_sonic_build.patch debuild -e KVERSION=$(KVERSION) -e KSRC_EXT=/lib/modules/$(KVERSION)/source/ -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 87f7a7911275..c08b5bb3810f 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 87f7a7911275285abc63c24ba39aa4af4c4b4678 +Subproject commit c08b5bb3810fe7da2811622aa7003ac9cc95344b diff --git a/platform/mellanox/sdk-src/sx-kernel/sx_kernel_makefile_sonic_build.patch b/platform/mellanox/sdk-src/sx-kernel/sx_kernel_makefile_sonic_build.patch deleted file mode 100644 index e7c87d079922..000000000000 --- a/platform/mellanox/sdk-src/sx-kernel/sx_kernel_makefile_sonic_build.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/makefile b/makefile -index f23f0ac..a16b2ce 100644 ---- a/makefile -+++ b/makefile -@@ -93,10 +93,10 @@ V ?= 1 - - ifneq ($(findstring 3.10,$(KVERSION))$(findstring 3.13,$(KVERSION))$(findstring 3.14,$(KVERSION))$(findstring 3.16,$(KVERSION)),) - MLNX_LINUX_AUTOCONF_FILE = include/generated/autoconf.h --MLNX_LINUX_EXTRA_INCLUDE_FILES = -include include/linux/kconfig.h -+MLNX_LINUX_EXTRA_INCLUDE_FILES = -include $(KSRC_EXT)/include/linux/kconfig.h - MLNX_LINUX_EXTRA_INCLUDE_FOLDERS = \ -- -Iarch/$$(SRCARCH)/include/uapi \ -- -Iinclude/uapi \ -+ -I$(KSRC_EXT)/arch/$$(SRCARCH)/include/uapi \ -+ -I$(KSRC_EXT)/include/uapi \ - -Iarch/$$(SRCARCH)/include/generated/uapi \ - -Iarch/$$(SRCARCH)/include/generated \ - -Iinclude/generated/uapi diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 73568ce84596..55a5b08bba31 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.3.2602 +MLNX_SDK_VERSION = 4.3.2904 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 476be913c1238e07f1f4004638ee76dadb177cd5 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 31 Dec 2019 16:30:10 -0800 Subject: [PATCH 0268/1427] [docker-base-stretch]: Do not check expire for stretch-backports repo (#3958) * [docker-base-stretch]: Do not check expire for stretch-backports repo Signed-off-by: Guohan Lu --- build_debian.sh | 2 +- dockers/docker-base-stretch/Dockerfile.j2 | 1 + dockers/docker-base-stretch/aptconf_archive_expired_release | 3 +++ files/apt/apt.conf.d/no-check-valid-until | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 dockers/docker-base-stretch/aptconf_archive_expired_release create mode 100644 files/apt/apt.conf.d/no-check-valid-until diff --git a/build_debian.sh b/build_debian.sh index 335dab8ba89f..39b984edec4e 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -107,7 +107,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT mount proc /proc -t proc ## Pointing apt to public apt mirrors and getting latest packages, needed for latest security updates sudo cp files/apt/sources.list.$CONFIGURED_ARCH $FILESYSTEM_ROOT/etc/apt/sources.list -sudo cp files/apt/apt.conf.d/{81norecommends,apt-{clean,gzip-indexes,no-languages}} $FILESYSTEM_ROOT/etc/apt/apt.conf.d/ +sudo cp files/apt/apt.conf.d/{81norecommends,apt-{clean,gzip-indexes,no-languages},no-check-valid-until} $FILESYSTEM_ROOT/etc/apt/apt.conf.d/ sudo LANG=C chroot $FILESYSTEM_ROOT bash -c 'apt-mark auto `apt-mark showmanual`' ## Note: set lang to prevent locale warnings in your chroot diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 3b3ede376d12..d8188a06afd6 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -34,6 +34,7 @@ COPY ["sources.list.arm64", "/etc/apt/sources.list"] COPY ["sources.list", "/etc/apt/sources.list"] {% endif %} COPY ["no_install_recommend_suggest", "/etc/apt/apt.conf.d"] +COPY ["aptconf_archive_expired_release", "/etc/apt/apt.conf.d"] # Update apt cache and # pre-install fundamental packages diff --git a/dockers/docker-base-stretch/aptconf_archive_expired_release b/dockers/docker-base-stretch/aptconf_archive_expired_release new file mode 100644 index 000000000000..67bc409b2174 --- /dev/null +++ b/dockers/docker-base-stretch/aptconf_archive_expired_release @@ -0,0 +1,3 @@ +# Instruct apt-get to override expired releases repo list for jessie archives + +Acquire::Check-Valid-Until "0"; diff --git a/files/apt/apt.conf.d/no-check-valid-until b/files/apt/apt.conf.d/no-check-valid-until new file mode 100644 index 000000000000..97b9c9005181 --- /dev/null +++ b/files/apt/apt.conf.d/no-check-valid-until @@ -0,0 +1 @@ +Acquire::Check-Valid-Until "false"; From 0dae59ac301f18e7dad948282addf961b69d82fc Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Thu, 2 Jan 2020 14:46:25 -0800 Subject: [PATCH 0269/1427] [MultiDB]except src and dockers : replace redis-cli with sonic-db-cli and use new DBConnector (#3928) * [MultiDB]except src and dockers : replace redis-cli with sonic-db-cli and use new DBConnector * fix vs tests along with swss vs tests together --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 9 ++--- files/build_templates/docker_image_ctl.j2 | 34 +++++++++---------- files/image_config/config-setup/config-setup | 11 +++--- files/image_config/updategraph/updategraph | 10 +++--- .../warmboot-finalizer/finalize-warmboot.sh | 10 +++--- files/scripts/configdb-load.sh | 2 +- files/scripts/swss.sh | 26 +++++++------- files/scripts/syncd.sh | 12 +++---- .../s9180-32x/utils/qsfp_monitor.sh | 2 +- .../s9280-64x/utils/qsfp_monitor.sh | 2 +- .../s8810-32q/utils/qsfp_monitor.sh | 2 +- .../s8900-54xc/utils/qsfp_monitor.sh | 2 +- .../s8900-64xc/utils/qsfp_monitor.sh | 2 +- .../s9100/utils/qsfp_monitor.sh | 2 +- .../s9200-64x/utils/qsfp_monitor.sh | 2 +- .../s9130-32x/utils/qsfp_monitor.sh | 2 +- .../s9230-64x/utils/qsfp_monitor.sh | 2 +- 17 files changed, 60 insertions(+), 72 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index e41ac2924da2..7c4f33f74973 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -22,8 +22,6 @@ SFP_I2C_PAGE_SIZE = 256 # parameters for DB connection -REDIS_HOSTNAME = "localhost" -REDIS_PORT = 6379 REDIS_TIMEOUT_USECS = 0 # parameters for SFP presence @@ -190,10 +188,9 @@ def get_transceiver_change_event(self, timeout=0): if self.db_sel == None: from swsscommon import swsscommon - self.state_db = swsscommon.DBConnector(swsscommon.STATE_DB, - REDIS_HOSTNAME, - REDIS_PORT, - REDIS_TIMEOUT_USECS) + self.state_db = swsscommon.DBConnector("STATE_DB", + REDIS_TIMEOUT_USECS, + True)) # Subscribe to state table for SFP change notifications self.db_sel = swsscommon.Select() diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 167a392730e4..df236f6523e8 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -63,20 +63,20 @@ function preStartAction() docker cp /tmp/dump.rdb database:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) - vrfenabled=`/usr/bin/redis-cli -n 4 hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` - v1SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` - v1SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` - v1Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` - v1Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` - v2SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` - v2SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` - v2Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` - v2Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` - v3SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` - v3SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` - v3Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` - v3Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` + sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + vrfenabled=`sonic-db-cli CONFIG_DB hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` + v1SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` + v1SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` + v1Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` + v1Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` + v2SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` + v2SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` + v2Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` + v2Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` + v3SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` + v3SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` + v3Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` + v3Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` if [ "${v1SnmpTrapIp}" != "" ] then @@ -113,7 +113,7 @@ function preStartAction() fi echo -n "" > /tmp/snmpagentaddr.yml - keys=`/usr/bin/redis-cli -n 4 keys "SNMP_AGENT_ADDRESS_CONFIG|*"` + keys=`sonic-db-cli CONFIG_DB keys "SNMP_AGENT_ADDRESS_CONFIG|*"` count=1 for key in $keys;do ip=`echo $key|cut -d "|" -f2` @@ -151,10 +151,10 @@ function postStartAction() if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - redis-cli -n 6 SET "FAST_REBOOT|system" "1" "EX" "180" + sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" fi - redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index bd497d06b257..f19abd266e95 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -25,7 +25,6 @@ ########################################################################### # Initialize constants -CONFIG_DB_INDEX=4 UPDATEGRAPH_CONF=/etc/sonic/updategraph.conf CONFIG_DB_JSON=/etc/sonic/config_db.json MINGRAPH_FILE=/etc/sonic/minigraph.xml @@ -107,9 +106,9 @@ reload_minigraph() if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -138,7 +137,7 @@ function copy_config_files_and_directories() # Check if SONiC swich has booted after a warm reboot request check_system_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -187,7 +186,7 @@ load_config() return 1 fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -j ${CONFIG_FILE} --write-to-db if [ $? -ne 0 ]; then return $? @@ -198,7 +197,7 @@ load_config() /usr/bin/db_migrator.py -o migrate fi - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" return 0 } diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index b2bd027e82e7..a24d452b1ad2 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -1,16 +1,14 @@ #!/bin/bash -CONFIG_DB_INDEX=4 - reload_minigraph() { echo "Reloading minigraph..." if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -77,9 +75,9 @@ if [ "$src" = "dhcp" ]; then else cp -f /tmp/device_meta.json /etc/sonic/config_db.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ "$dhcp_as_static" = "true" ]; then sed -i "/enabled=/d" /etc/sonic/updategraph.conf echo "enabled=false" >> /etc/sonic/updategraph.conf diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index 32c9c8444cc3..eec50ccef692 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -20,7 +20,7 @@ function debug() function check_warm_boot() { - WARM_BOOT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + WARM_BOOT=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` } @@ -29,12 +29,10 @@ function wait_for_database_service() debug "Wait for database to become ready..." # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done @@ -44,7 +42,7 @@ function wait_for_database_service() function get_component_state() { - /usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|$1" state + sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|$1" state } diff --git a/files/scripts/configdb-load.sh b/files/scripts/configdb-load.sh index 5ba2e0e0bc7f..e7080eb40f3d 100755 --- a/files/scripts/configdb-load.sh +++ b/files/scripts/configdb-load.sh @@ -10,4 +10,4 @@ if [ -r /etc/sonic/config_db.json ]; then sonic-cfggen -j /etc/sonic/config_db.json --write-to-db fi -redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" +sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 93f311019d66..a14d03e40f50 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -31,8 +31,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -43,7 +43,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -54,12 +54,10 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -69,7 +67,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - redis-cli -n $1 EVAL " + sonic-db-cli $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -114,11 +112,11 @@ start() { # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - /usr/bin/docker exec database redis-cli -n 0 FLUSHDB - /usr/bin/docker exec database redis-cli -n 1 FLUSHDB - /usr/bin/docker exec database redis-cli -n 2 FLUSHDB - /usr/bin/docker exec database redis-cli -n 5 FLUSHDB - clean_up_tables 6 "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" + sonic-db-cli APPL_DB FLUSHDB + sonic-db-cli ASIC_DB FLUSHDB + sonic-db-cli COUNTERS_DB FLUSHDB + sonic-db-cli FLEX_COUNTER_DB FLUSHDB + clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker @@ -166,7 +164,7 @@ stop() { # encountered error, e.g. syncd crashed. And swss needs to # be restarted. debug "Clearing FAST_REBOOT flag..." - clean_up_tables 6 "'FAST_REBOOT*'" + clean_up_tables STATE_DB "'FAST_REBOOT*'" # Unlock has to happen before reaching out to peer service unlock_service_state_change diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 05e5552a64b1..4b47e7ad4c45 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -30,8 +30,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -43,12 +43,10 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -65,7 +63,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(redis-cli -n 6 GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $(sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh index 23a3fd066bee..9213d115f656 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh index 7f50d137bcb7..0a4ba20ab767 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh index 36f9e53ef108..b3192f2efb7a 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh index 51c49c1152f5..47cfbb3ea008 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh index 23a3fd066bee..9213d115f656 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi From 122124679dbcb5210efd29b9535d7f2f81b74230 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 3 Jan 2020 16:35:08 -0800 Subject: [PATCH 0270/1427] Update bgpcfgd with vrf support (#3952) * Implement path traversal just once * Add support of vrf to bgpcfgd --- dockers/docker-fpm-frr/bgpcfgd | 72 +++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 120e07fcdbe2..4211f49d2272 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -120,29 +120,23 @@ class Directory(object): self.data = defaultdict(dict) self.notify = defaultdict(lambda: defaultdict(list)) - def path_exist(self, slot, path): + def path_traverse(self, slot, path): if slot not in self.data: - return False + return False, None elif path == '': - return True + return True, self.data[slot] d = self.data[slot] for p in path.split("/"): if p not in d: - return False + return False, None d = d[p] - return True + return True, d + + def path_exist(self, slot, path): + return self.path_traverse(slot, path)[0] def get_path(self, slot, path): - if slot not in self.data: - return None - elif path == '': - return self.data[slot] - d = self.data[slot] - for p in path.split("/"): - if p not in d: - return None - d = d[p] - return d + return self.path_traverse(slot, path)[1] def put(self, slot, key, value): self.data[slot][key] = value @@ -289,6 +283,8 @@ class BGPPeerMgr(Manager): } def set_handler(self, key, data): + key = self.normalize_key(key) + vrf, nbr = key.split('|', 1) if key not in self.peers: cmd = None neigmeta = self.directory.get_slot("neigmeta") @@ -298,14 +294,14 @@ class BGPPeerMgr(Manager): cmd = self.templates["add"].render( DEVICE_METADATA=self.directory.get_slot("meta"), DEVICE_NEIGHBOR_METADATA=neigmeta, - neighbor_addr=key, + neighbor_addr=nbr, bgp_session=data ) except: syslog.syslog(syslog.LOG_ERR, 'Peer {}. Error in rendering the template for "SET" command {}'.format(key, data)) return True if cmd is not None: - rc = self.apply_op(cmd) + rc = self.apply_op(cmd, vrf) if rc: self.peers.add(key) syslog.syslog(syslog.LOG_INFO, 'Peer {} added with attributes {}'.format(key, data)) @@ -316,13 +312,13 @@ class BGPPeerMgr(Manager): # commands for the peers only if "admin_status" in data: if data['admin_status'] == 'up': - rc = self.apply_op(self.templates["no shutdown"].render(neighbor_addr=key)) + rc = self.apply_op(self.templates["no shutdown"].render(neighbor_addr=nbr), vrf) if rc: syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "up"'.format(key)) else: syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'up'.".format(key)) elif data['admin_status'] == 'down': - rc = self.apply_op(self.templates["shutdown"].render(neighbor_addr=key)) + rc = self.apply_op(self.templates["shutdown"].render(neighbor_addr=nbr), vrf) if rc: syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "down"'.format(key)) else: @@ -334,23 +330,28 @@ class BGPPeerMgr(Manager): return True def del_handler(self, key): + key = self.normalize_key(key) + vrf, nbr = key.split('|', 1) if key not in self.peers: syslog.syslog(syslog.LOG_WARNING, 'Peer {} has not been found'.format(key)) return - cmd = self.templates["delete"].render(neighbor_addr=key) - rc = self.apply_op(cmd) + cmd = self.templates["delete"].render(neighbor_addr=nbr) + rc = self.apply_op(cmd, vrf) if rc: syslog.syslog(syslog.LOG_INFO, 'Peer {} has been removed'.format(key)) self.peers.remove(key) else: syslog.syslog(syslog.LOG_ERR, "Peer {} hasn't been removed".format(key)) - def apply_op(self, cmd): + def apply_op(self, cmd, vrf): bgp_asn = self.directory.get_slot("meta")["localhost"]["bgp_asn"] fd, tmp_filename = tempfile.mkstemp(dir='/tmp') os.close(fd) with open(tmp_filename, 'w') as fp: - fp.write('router bgp %s\n' % bgp_asn) + if vrf == 'default': + fp.write('router bgp %s\n' % bgp_asn) + else: + fp.write('router bgp %s vrf %s\n' % (bgp_asn, vrf)) fp.write("%s\n" % cmd) command = ["vtysh", "-f", tmp_filename] @@ -358,14 +359,31 @@ class BGPPeerMgr(Manager): os.remove(tmp_filename) return rc == 0 + @staticmethod + def normalize_key(key): + if '|' not in key: + return 'default|' + key + else: + return key + @staticmethod def load_peers(): - peers = set() - command = ["vtysh", "-c", "show bgp neighbors json"] + vrfs = [] + command = ["vtysh", "-c", "show bgp vrfs json"] rc, out, err = run_command(command) if rc == 0: - js_bgp = json.loads(out) - peers = set(js_bgp.keys()) + js_vrf = json.loads(out) + vrfs = js_vrf['vrfs'].keys() + + peers = set() + for vrf in vrfs: + command = ["vtysh", "-c", 'show bgp vrf {} neighbors json'.format(vrf)] + rc, out, err = run_command(command) + if rc == 0: + js_bgp = json.loads(out) + for nbr in js_bgp.keys(): + peers.add((vrf, nbr)) + return peers From df04809cb878ca69d408448c82da8f57f696bd9f Mon Sep 17 00:00:00 2001 From: tahmed-dev <56694863+tahmed-dev@users.noreply.github.com> Date: Mon, 6 Jan 2020 17:01:28 -0800 Subject: [PATCH 0271/1427] [libnl]: Debian Packaging libnl version 3.5.0 (#3967) Packaging libnl 3.5.0 based off libnl 3.2.27 packaging. libnl contains various bug fixes that are nice to have. pull-request: https://github.com/Azure/sonic-buildimage/pull/3967 signed-off-by: Tamer Ahmed --- .gitignore | 16 + rules/libnl3.mk | 4 +- src/libnl3/Makefile | 9 +- src/libnl3/debian/README.Debian | 17 + src/libnl3/debian/README.source | 10 + src/libnl3/debian/changelog | 1043 +++++++++ src/libnl3/debian/compat | 1 + src/libnl3/debian/control | 245 ++ src/libnl3/debian/copyright | 160 ++ src/libnl3/debian/gbp.conf | 16 + src/libnl3/debian/libnl-3-200-udeb.install | 1 + src/libnl3/debian/libnl-3-200.install | 3 + src/libnl3/debian/libnl-3-200.symbols | 661 ++++++ src/libnl3/debian/libnl-3-dev.install | 5 + src/libnl3/debian/libnl-cli-3-200.install | 4 + src/libnl3/debian/libnl-cli-3-200.symbols | 226 ++ src/libnl3/debian/libnl-cli-3-dev.install | 3 + .../debian/libnl-genl-3-200-udeb.install | 2 + src/libnl3/debian/libnl-genl-3-200.install | 2 + src/libnl3/debian/libnl-genl-3-200.symbols | 88 + src/libnl3/debian/libnl-genl-3-dev.install | 4 + src/libnl3/debian/libnl-idiag-3-200.install | 1 + src/libnl3/debian/libnl-idiag-3-200.symbols | 206 ++ src/libnl3/debian/libnl-idiag-3-dev.install | 3 + src/libnl3/debian/libnl-nf-3-200.install | 1 + src/libnl3/debian/libnl-nf-3-200.symbols | 620 +++++ src/libnl3/debian/libnl-nf-3-dev.install | 3 + src/libnl3/debian/libnl-route-3-200.install | 1 + src/libnl3/debian/libnl-route-3-200.symbols | 2051 +++++++++++++++++ src/libnl3/debian/libnl-route-3-dev.install | 3 + src/libnl3/debian/libnl-utils.install | 1 + src/libnl3/debian/libnl-utils.manpages | 1 + src/libnl3/debian/libnl-xfrm-3-200.install | 1 + src/libnl3/debian/libnl-xfrm-3-200.symbols | 484 ++++ src/libnl3/debian/libnl-xfrm-3-dev.install | 3 + src/libnl3/debian/patches/series | 0 src/libnl3/debian/rules | 39 + src/libnl3/debian/source/format | 1 + src/libnl3/debian/watch | 2 + 39 files changed, 5934 insertions(+), 7 deletions(-) create mode 100644 src/libnl3/debian/README.Debian create mode 100644 src/libnl3/debian/README.source create mode 100644 src/libnl3/debian/changelog create mode 100644 src/libnl3/debian/compat create mode 100644 src/libnl3/debian/control create mode 100644 src/libnl3/debian/copyright create mode 100644 src/libnl3/debian/gbp.conf create mode 100644 src/libnl3/debian/libnl-3-200-udeb.install create mode 100755 src/libnl3/debian/libnl-3-200.install create mode 100644 src/libnl3/debian/libnl-3-200.symbols create mode 100755 src/libnl3/debian/libnl-3-dev.install create mode 100755 src/libnl3/debian/libnl-cli-3-200.install create mode 100644 src/libnl3/debian/libnl-cli-3-200.symbols create mode 100644 src/libnl3/debian/libnl-cli-3-dev.install create mode 100755 src/libnl3/debian/libnl-genl-3-200-udeb.install create mode 100755 src/libnl3/debian/libnl-genl-3-200.install create mode 100644 src/libnl3/debian/libnl-genl-3-200.symbols create mode 100755 src/libnl3/debian/libnl-genl-3-dev.install create mode 100644 src/libnl3/debian/libnl-idiag-3-200.install create mode 100644 src/libnl3/debian/libnl-idiag-3-200.symbols create mode 100644 src/libnl3/debian/libnl-idiag-3-dev.install create mode 100644 src/libnl3/debian/libnl-nf-3-200.install create mode 100644 src/libnl3/debian/libnl-nf-3-200.symbols create mode 100644 src/libnl3/debian/libnl-nf-3-dev.install create mode 100644 src/libnl3/debian/libnl-route-3-200.install create mode 100644 src/libnl3/debian/libnl-route-3-200.symbols create mode 100644 src/libnl3/debian/libnl-route-3-dev.install create mode 100644 src/libnl3/debian/libnl-utils.install create mode 100644 src/libnl3/debian/libnl-utils.manpages create mode 100644 src/libnl3/debian/libnl-xfrm-3-200.install create mode 100644 src/libnl3/debian/libnl-xfrm-3-200.symbols create mode 100644 src/libnl3/debian/libnl-xfrm-3-dev.install create mode 100644 src/libnl3/debian/patches/series create mode 100755 src/libnl3/debian/rules create mode 100644 src/libnl3/debian/source/format create mode 100644 src/libnl3/debian/watch diff --git a/.gitignore b/.gitignore index 1f921971d8bb..fbf646fcd40f 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,8 @@ src/isc-dhcp/* !src/isc-dhcp/Makefile !src/isc-dhcp/patch/ src/libnl3/* +!src/libnl3/debian +src/libnl3/debian/libnl-*/ !src/libnl3/Makefile src/libteam/* !src/libteam/Makefile @@ -140,3 +142,17 @@ src/sonic-daemon-base/sonic_daemon_base.egg-info # Misc. files files/initramfs-tools/arista-convertfs files/initramfs-tools/union-mount + +# Debian byproduct files +src/**/debian/stamp-*/ +src/**/debian/*.log +src/**/debian/*.substvars +src/**/debian/.debhelper/ +src/**/debian/tmp/ +src/**/debian/autoreconf.* +src/**/debian/build/ +src/**/debian/files +src/**/debian/stamp-autotools-files + +# .o files +src/**/*.o diff --git a/rules/libnl3.mk b/rules/libnl3.mk index 897b6c34482f..cdd807b2f5c8 100644 --- a/rules/libnl3.mk +++ b/rules/libnl3.mk @@ -1,7 +1,7 @@ # libnl3 -LIBNL3_VERSION_BASE = 3.2.27 -LIBNL3_VERSION = $(LIBNL3_VERSION_BASE)-2 +LIBNL3_VERSION_BASE = 3.5.0 +LIBNL3_VERSION = $(LIBNL3_VERSION_BASE)-1 export LIBNL3_VERSION_BASE export LIBNL3_VERSION diff --git a/src/libnl3/Makefile b/src/libnl3/Makefile index c9fc72f50f74..a0e9891c9efc 100644 --- a/src/libnl3/Makefile +++ b/src/libnl3/Makefile @@ -16,12 +16,11 @@ DERIVED_TARGETS = libnl-3-dev_$(LIBNL3_VERSION)_$(CONFIGURED_ARCH).deb \ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Obtaining the libnl3 rm -rf ./libnl3-$(LIBNL3_VERSION_BASE) - wget -O libnl3_$(LIBNL3_VERSION_BASE).orig.tar.gz -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION_BASE).orig.tar.gz?sv=2015-04-05&sr=b&sig=b4DnqrIsyVBDLmYhw7qwfaUJWqGCX2lDVMmmx7ihfrU%3D&se=2028-06-16T21%3A06%3A00Z&sp=r" - wget -O libnl3_$(LIBNL3_VERSION).dsc -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION).dsc?sv=2015-04-05&sr=b&sig=AWTX45oDbeGA%2BRJZyiCcHmeIfCAgSeNV3IqopOBaRDg%3D&se=2028-06-16T21%3A05%3A30Z&sp=r" - wget -O libnl3_$(LIBNL3_VERSION).debian.tar.xz -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION).debian.tar.xz?sv=2015-04-05&sr=b&sig=upIZ9dp5WEcLqp3ODeWKJXq5pJWCfeT0TIM0bx76wxM%3D&se=2028-06-16T21%3A04%3A44Z&sp=r" - dpkg-source -x libnl3_$(LIBNL3_VERSION).dsc + git clone https://github.com/thom311/libnl libnl3-$(LIBNL3_VERSION_BASE) + pushd libnl3-$(LIBNL3_VERSION_BASE) + git checkout tags/libnl$(subst .,_,$(LIBNL3_VERSION_BASE)) - pushd ./libnl3-$(LIBNL3_VERSION_BASE) + ln -s ../debian debian dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) popd diff --git a/src/libnl3/debian/README.Debian b/src/libnl3/debian/README.Debian new file mode 100644 index 000000000000..002e249bbfcb --- /dev/null +++ b/src/libnl3/debian/README.Debian @@ -0,0 +1,17 @@ + +libnl versions explained +======================== + +Once libnl3 hits the archive there will exist 3 versions of libnl. +libnl1 with libnl-dev - up until March 2011 the stable version +libnl2 with libnl2-dev - development version that resulted in +libnl3 with libnl3-dev - the new stable (API and ABI wise) version + +libnl1 has currently a lot of users in the archive and a lot of changes +happened since its last upstream release in 2008-01. + +The plan is therefore to introduce libnl3, port the two users of libnl2 +(freesmartphone.org libs and powertop) to it, remove libnl2 and don't touch +libnl1 and libnl-dev for now. + + -- Heiko Stuebner Sat, 21 May 2011 19:25:13 +0200 diff --git a/src/libnl3/debian/README.source b/src/libnl3/debian/README.source new file mode 100644 index 000000000000..f6e8ee70da94 --- /dev/null +++ b/src/libnl3/debian/README.source @@ -0,0 +1,10 @@ +This package uses the simple-patchsys of cdbs. + +The following patches are used: +0001: Fixes the header inclusion in the Makefiles. + This for example make distcheck +0002: Includes all generated libraries as linktargets in the pkg-config file. + Reason: Currently libnl3 generates a bunch of child libraries. + These don't get individual .pc files from upstream at the moment but + programs linking against libnl3 using the .pc file mostly need these + additional libraries too. diff --git a/src/libnl3/debian/changelog b/src/libnl3/debian/changelog new file mode 100644 index 000000000000..c51ae1121796 --- /dev/null +++ b/src/libnl3/debian/changelog @@ -0,0 +1,1043 @@ +libnl3 (3.5.0-1) unstable; urgency=low + + [ skuklinski ] + * route/link: IFLA_VLAN_PROTOCOL added to vlan_put_attrs + + [ Thomas Haller ] + * rtnl/link: indicate capability NL_CAPABILITY_RTNL_LINK_VLAN_PROTOCOL_SERIALZE + + [ David Ahern ] + * route/vrf: add VRF support + * neigh: add support for NTF_SELF + + [ Beniamino Galvani ] + * route/link: fix parsing of 'remote' attribute for GRE links + + [ Thomas Haller ] + * route/vlan: allow clearing vlan ingress map + + [ David Ahern ] + * link/neigh: add flags option to link and neighbor caches + + [ Thomas Haller ] + * gitignore: ignore test binaries in "tests/" + + [ Beniamino Galvani ] + * route/link: add macvtap support + * route/link: fix dump of parent link for some link types + * route/link: add ipv6 support to vxlan links + + [ Tobias Jungel ] + * route/link: corrected array size for inet_policy + + [ David Ahern ] + * route/link: add link info compare operation + * route/link/vxlan: trivial rename VXLAN_HAS_ prefix and vxi_mask + * route/link/vxlan: add support for link_info compare + + [ Andrew Vagin ] + * libnl: don't use out-of-scope buffer in nl_send_iovec() + + [ David Ahern ] + * link: add AF operation to append attributes to a GETLINK message + * lib: handle family-based parsing of IFLA_AF_SPEC attribute + + [ Thomas Haller ] + * include/linux: update copy of kernel headers + + [ David Ahern ] + * bridge: add support for VLANs + + [ Tobias Jungel ] + * route/link: handle RTEXT_FILTER_BRVLAN_COMPRESSED + * route/link/bridge: fixed return type + + [ Quentin Armitage ] + * route/link: add support for IN6_ADDR_GEN_MODE_STABLE_PRIVACY + + [ Amit Khatri ] + * lib/route: potential memory leak in pktloc.c + + [ Nick Lewycky ] + * remove null dereference from netlink/link.h + + [ David Ahern ] + * lib: update ce-mask to uint64_t + + [ Thomas Haller ] + * libnl: add nl_object_diff64() to libnl-3.sym + * lib/utils: add NL_CAPABILITY_NL_OBJECT_DIFF64 capability + + [ Przemyslaw Szczerbik ] + * lib: add type casting for nla_for_each_nested macro + + [ Tobias Klauser ] + * build: move -rdynamic from CPPFLAGS to LDFLAGS + + [ Thomas Haller ] + * route: sort entries in libnl-route-3.sym by name + + [ Haishuang Yan ] + * ipgre: add support for gretap tunnel + + [ Thadeu Lima de Souza Cascardo ] + * sit: add 6RD support + + [ Thomas Haller ] + * sit/trivial: whitespace + * sit: don't print ip6rd_prefix as integer in sit_dump_details() + * sit: refactor IS_SIT_LINK_ASSERT() + * sit: fix invalid declaration of rtnl_link_sit_get_proto() in sit.h + * sit: add public API for sit 6RD support + + [ Jonas Johansson ] + * neigh: support neighbour flag NTF_SELF + * neigh: add function to look up neighbour (fdb) by ifindex, mac and vlan + + [ Jef Oliver ] + * link: support RTEXT_FILTER_VF + + [ Thomas Haller ] + * link: allow overwriting IFLA_EXT_MASK flag in ao_get_af() function + + [ Przemyslaw Szczerbik ] + * lib: return error on Netlink attribute length overflow + + [ Thomas Egerer ] + * xfrm: fix buffer overflow when copying keys + * xfrm: check length of alg_name before strcpying it + * xfrm: make character pointers in setters const + * xfrm: fix segfault when using encapsulation templates + + [ Thomas Haller ] + * xfrm: reuse encap data in xfrmnl_sa_set_encap_tmpl() + + [ Thomas Egerer ] + * xfrm: fix memory leak for encap original address + * xfrm: attach only one xfrm alg attribute to netlink message + + [ Thomas Haller ] + * xfrm: fix memleak in build_xfrm_sa_message() error-path + + [ Sabrina Dubroca ] + * pass flags through ->io_compare op + * vxlan: properly handle LOOSE_COMPARISON in ->io_compare + * import macsec uapi headers + * lib/route: add macsec support + + [ Thomas Haller ] + * xfrm: allow avoiding buffer overflow for key in xfrmnl_sa_get_*_params() + * route/addr: fix ID comparison for AF_INET and AF_INET6 addresses + * route/addr: fix handling peer addresses for IPv4 addresses + * route/addr: add capability NL_CAPABILITY_RTNL_ADDR_PEER_FIX to indicate address fixes + * build: fix adding macsec files to include/Makefile.am + * libnl-3.2.28-rc1 release + * libnl-3.2.28 release + + [ Craig Gallek ] + * build: fixup headers for C++ inclusion + + [ Peter Wu ] + * trivial: whitespace-only fixes for src and lib + * cli: add noreturn attributes + * xfrm: fix memleak in another error path of build_xfrm_sa_message + * exp: fix a GCC 6 -Wmisleading-indentation warning + * doc: fix URLs and typo + + [ Tobias Jungel ] + * route/addr: address attributes based on object + + [ Thomas Haller ] + * lib: capability NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX for ID comparison of v4 addresses + * nl-addr: avoid read-out-of-bound in nl_addr_fill_sockaddr() + + [ André Draszik ] + * lib: add utility function nl_strerror_l() + * lib: switch to using strerror_l() instead of strerror_r() + * src: switch to using strerror_l() instead of strerror_r() + + [ Jeff Squyres ] + * compat: add linux/socket.h for __kernel_sa_family_t + + [ Jef Oliver ] + * lib/route: allow override of message type during link change + * lib/route: set IFLA_PROTINFO attribute in request message + * lib/route: modify link/bridge to set attributes + + [ Davide Caratti ] + * macsec: fix endianness of 'sci' parameter + * macsec: fix maximum ICV length + * remove multiple implementations of htonll(), ntohll() + + [ Jef Oliver ] + * lib/route: Fix appending IFLA_BRPORT_FASTLEAVE + * lib/route: Add port state translation functions + * lib/route: Extend Bridge Flags + * lib/route: Allow override of IFLA_AF_SPEC nesting + * lib/route: Support IFLA_BRIDGE_MODE + + [ Thomas Haller ] + * trivial: whitespace + * bridge: change return values for rtnl_link_bridge_get_hwmode() + + [ Michael Braun ] + * macvlan: add support for "source" mode + + [ Thomas Haller ] + * macvlan: adjust types and merge MACVLAN_HAS_MACCOUNT and MACVLAN_HAS_MACDATA + + [ Brandon Carpenter ] + * vxlan: add support for additional VXLAN attributes. + + [ Thomas Haller ] + * vxlan: fix exporting new symbols + * vxlan: remove redundant enable/disable API from vxlan + * vxlan: restore previous VXLAN_ATTR flag values + * vxlan: don't store vxlan flags as ce_mask + * vxlan: refactor setting/getting vxlan flags + * vxlan: fix error code for missing attribute + + [ Jef Oliver ] + * lib/route: Export correct ipgre functionality + + [ Thomas Haller ] + * lib/route: preserve old ABI for rtnl_link_get_pmtudisc() + + [ Thomas Egerer ] + * xfrm: fix xfrm security context management + * xfrm: add capability reference to xfrmnl_sa_set_* + + [ Thomas Haller ] + * xfrm: remove unused struct xfrmnl_sec_ctx from header files + + [ Jef Oliver ] + * lib/route: SRIOV Parse and Read support + * lib/route: SRIOV Clone Support + * lib/route: SRIOV Utility Functions + * lib/route: SRIOV Info Dump Functions + * lib/route: SRIOV Set Functionality + + [ Thomas Haller ] + * route: remove symbols of internal API from ABI + + [ Tobias Klauser ] + * lib/route: keep link stats minlen compatible with kernel < 4.6 + + [ Thomas Haller ] + * utils: add internal _nl_offset_plus_sizeof() macro + * lib/route: use _nl_offset_plus_sizeof() macro for minlen field for rtln_link_policy + + [ Jonas Johansson ] + * Add PPP support + * ppp: update code after review + * ppp: rename local struct ppp_info* variables; pi -> info + * ppp: fix type of file descriptor; uint32_t -> int32_t + + [ Thomas Haller ] + * ppp: fix API in ppp.h header + + [ Sushma Sitaram ] + * route/cls: support setting of selector fields + + [ Tobias Klauser ] + * src: nl-link-stats: use correct rtnl link stats maximum + * lib/route: add rx_nohandler link stats field + + [ Thomas Haller ] + * nl-link-stats: prefer RTNL_LINK_STATS_MAX over __RTNL_LINK_STATS_MAX + * lib/route: pass sizeof() argument to nl_memcpy() + * link: set ifi_change flags for rtnl_link_build_add_request() + * lib: use MSG_PEEK by default for nl_recvmsgs() + + [ Tobias Jungel ] + * cache_mngr: add include callback v2 + + [ Tobias Klauser ] + * cache: fix GCC warning and avoid variable shadowing + + [ Sushma Sitaram ] + * route/act: add gact tc action + + [ Tobias Klauser ] + * link: add support for IFLA_CARRIER_CHANGES + * link: add support for IFLA_PHYS_PORT_NAME + * link: add support for IFLA_PHYS_SWITCH_ID + * link: add support for IFLA_GSO_MAX_SEGS and IFLA_GSO_MAX_SIZE + * link: fix documentation for rtnl_link_get_carrier_changes + + [ Thomas Haller ] + * libnl-3.2.29-rc1 release + * utils/trivial: rename internal _nl_offset_plus_sizeof() macro to _nl_offsetofend() + + [ Beniamino Galvani ] + * Revert "macsec: fix endianness of 'sci' parameter" + * macsec: document byte order for the SCI and port attributes + + [ Thomas Haller ] + * macsec: fix endianness of sci during dump() + * libnl-3.2.29 release + + [ Tobias Klauser ] + * route/tc: Remove unused function tca_set_kind() + + [ Laine Stump ] + * sriov: fix crash in rtnl_link_sriov_parse_vflist + + [ Thomas Haller ] + * sriov: avoid buffer overrun in rtnl_link_sriov_parse_vflist() + + [ Nick Kralevich ] + * lib/utils.c: lazy initialize user_hz and psched_hz + + [ Thomas Haller ] + * lib/utils.c: ensure calling get_psched_settings() for nl_us2ticks()/nl_ticks2us() + * lib/utils.c: add mutex to get_psched_settings() + + [ Nick Kralevich ] + * fopen: add O_CLOEXEC + + [ Thomas Haller ] + * lib/attr.c: check for valid length argument in nla_reserve() + + [ Tobias Klauser ] + * sit: Fix invalid function prototypes in public header + * sriov: Add missing prototype for rtnl_link_vf_vlan_free() + * qdisc/red: Add missing prototypes for rtnl_red_set_limit() and rtnl_red_get_limit() + * fib_lookup: Add missing prototypes to public header + * link/inet6: Include own public header for function prototypes + * link/ipip: Include own public header for function prototypes + * link/ipip: Add missing prototype for rtnl_link_is_ipip() + * link/ipvti: Include own public header for function prototypes + * link/ipvti: Fix and add function prototypes in public header + * link/macsec: Include own public header for function prototypes + * link/sit: Add missing prototype for rtnl_link_is_sit() + * link/ipgre: Add prototype for ABI-preserving wrapper rtnl_link_get_pmtudisc() + * netfilter/queue: Add missing prototype for nfnl_queue_msg_build_verdict_batch() + * netfilter/exp: Add missing function prototypes + * idiag/req: Add missing function prototype + * xfrm/ae: Include own public header for function prototypes + * xfrm/lifetime: Include own public header for function prototypes + * xfrm/sa: Include own public header for function prototypes + * xfrm/selector: Include own public header for function prototypes + * xfrm/template: Include own public header for function prototypes + * pktloc: Add missing function prototypes + * ematch: Add missing function prototypes + * build: Add -Wmissing-prototypes to CPPFLAGS + + [ Jeroen Roovers ] + * build: distribute in.h in6.h libc-compat.h + + [ Thomas Haller ] + * lib: fix comment for nl_recv() about return value for non-blocking read + * lib: check for integer-overflow in nlmsg_reserve() + * build: cleanup top-level Makefile.am + * build: merge include/Makefile.am into top-level makefile + * build: merge lib/Makefile.am into top-level makefile + * build: merge man/Makefile.am into top-level makefile + * build: merge python/Makefile.am into top-level makefile + * build: merge tests/Makefile.am into top-level makefile + * build: merge src/lib/Makefile.am into top-level makefile + * build: merge src/Makefile.am into top-level makefile + * build: enable building cli during tests + * build: move compiler warning flags to separate autoconf variable + * all: enable -Wmissing-prototype warning for all components + * build: enable more warnings + + [ Roopa Prabhu ] + * route: neigh: use NDA_MASTER for neigh->n_master if available + + [ Simon Buttgereit ] + * fix build_xfrm_sp_message index condition + * fix xfrmnl_sp_set_sec_ctx length attributes + * little style fixes. + * update sp_attr condition in build_xfrm_sp_message + * add possibity to delete policy without index + * update documentation of xfrmnl_sp_get_sec_ctx + * fix of boolean operators + + [ Thomas Haller ] + * xfrm: allow quering optional arguments from xfrmnl_sp_get_sec_ctx() + * xfrm: NUL terminate the ctx_str buffer in xfrmnl_sa_set_sec_ctx() + * build: ensure build directory for generated sources exist + * build: pass --disable-dependency-tracking to `make distcheck` + * build: fix creating directories for generated sources + * build: style cleanup in doc/Makefile.am + * build: reorder checks in configure.ac + * build: add tools/build_release.sh script + * include: don't include kernel headers in public libnl3 headers + * include: restore linux header includes in public headers + * libnl-3.3.0-rc1 release + + [ Alexey Brodkin ] + * lib: escape usage of strerror_l() if it doesn't exist in libc + + [ Thomas Haller ] + * all: don't use math.h or link with libm.so + * libnl-3.3.0 release + * tools: fix building doc in build_release.sh + + [ Markus Trapp ] + * route/link: add accessor API for IPv6 flags + + [ Santhosh Kumar ] + * Provide accessors for actions (rtnl_act). + * Do not increment refcount in rtnl_*_get_action APIs. + + [ Thomas Haller ] + * route: fix symbol versioning + + [ David Ahern ] + * route: Add support for netconf + * nl-monitor: All user to specify line format + * nl-monitor: Add support for netconf caches + * route: Add support for MPLS to netconf + * Update fib_rules.h to latest kernel + * rule: Add support for l3mdev in FIB rules + + [ Thomas Haller ] + * rule: change API for setting/getting l3mdev rule property + + [ Tobias Klauser ] + * addr: add AF_VSOCK to translation table + + [ Thomas Haller ] + * build: don't build cli libraries by default + * build: allow building cli without dynamic librarires support + + [ Tobias Klauser ] + * genl: drop usage of GENL_ID_GENERATE + + [ Rasmus Villemoes ] + * lib/cache_mngr.c: avoid memleak if realloc fails + * lib/cache_mgr.c: remove pointless goto + * lib/data.c: avoid memleak if realloc fails + * lib/route/cls/u32.c: remove pointless nl_data_append calls + * lib/route/cls/u32.c: avoid overflowing an unsigned char + * lib/route/cls/u32.c: let the compiler do pointer arithmetic + * lib/route/cls/u32.c: remove bogus comment + * lib/route/qdisc/netem.c: avoid memory leak if realloc fails + + [ Thomas Haller ] + * lib/route/cls/u32.c: use UCHAR_MAX define instead of numeric 255 + * lib/route/qdisc/netem.c/trivial: fix whitespace and indentation in netem_msg_fill_raw() + * lib/route/qdisc/netem.c/trivial: don't use braces for one-line blocks + + [ Rasmus Villemoes ] + * lib/xfrm/ae.c: fix memcpy(dst, dst) bug + * lib/genl/family.c: fix if (x) y; else y; + + [ Thomas Haller ] + * all: avoid compiler warnings -Wimplicit-fallthrough + * lib/route: add /usr/lib64/tc/ search path for netem dist file + + [ David Ahern ] + * Update rtnetlink.h from kernel tree + * Import mpls header from kernel tree + + [ Thomas Haller ] + * build: add include/linux-private/linux/mpls.h to Makefile.am + + [ David Ahern ] + * addr: Add implementations for mpls_ntop and mpls_pton + * addr: Add support for AF_MPLS + * route: Add support for MPLS address family + * route: Add support for ttl propagation in MPLS routes + * Add support for label stack in nl-route commands + * Import lwtunnel encap files from kernel + * route: Add support for lwtunnel encapsulations + * route: Add support for MPLS encap + + [ Thomas Haller ] + * build: add new include/netlink-private/route/*.h files to Makefile.am + + [ Amit Khatri ] + * Potential memory leak becaue of wrong variable check. + + [ Tobias Klauser ] + * cli: include sys/select.h for select(2) + + [ Thomas Haller ] + * libnl-3.4.0-rc1 release + + [ David Ahern ] + * netconf: Put nc reference in msg_parser + + [ Jeroen Roovers ] + * build: add missing headers for issue #152 + + [ Thomas Haller ] + * libnl-3.4.0 release + * nl: add "const" specifier for nla_policy argument of parse functions [ Roopa Prabhu ] + * route: link: add family to dump messages + * route: neigh: print family in neigh dumps + + [ Sebastian Bixl ] + * route/vlan: fix memory corruption in rtnl_link_vlan_set_egress_map + + [ Thomas Haller ] + * route/vlan: fix cloning vlan link in vlan_clone() + * route/vlan: grow buffer exponentially in rtnl_link_vlan_set_egress_map() + * route/vlan: add capability to indicate heap overflow fix in rtnl_link_vlan_set_egress_map() + * route: fix handling old_nh in rtnl_route_parse() and avoid leak + + [ Jef Oliver ] + * Change rtnl_link_af_ops.ao_override_rtm behavior + + [ Chris Grahn ] + * tests: fix bug in test-create-bridge.c + + [ Steffen Vogel ] + * route: add separate function to set netem qdisc delay distribution + + [ Thomas Haller ] + * all: declare all variables at the beginning of scope (-Wdeclaration-after-statement) + * route: add rtnl_netem_set_delay_distribution_data() to linker script + * route: mark data argument for rtnl_netem_set_delay_distribution_data() as const + * route: fix memleak in rtnl_netem_set_delay_distribution_data() + * route: free previous data in rtnl_netem_set_delay_distribution_data() + * travis: enable more warnings during build + + [ Marcos Paulo de Souza ] + * tests: Add test to {de}activate loopback interface + * lib/veth.c: Disassociate link name of peer name + + [ d0u9 ] + * Coding style format + * Add new function for setting ifindex and parent of a classifier cache. + + [ Thomas Haller ] + * route: rename rtnl_cls_cache_set_tcm_params() and fix symbol versioning + + [ d0u9 ] + * Fix for cgroup filter addition problem. + + [ Thomas Haller ] + * lib: merge implementations of nl_attr_end() and nl_attr_keep_empty() + + [ Wang Jian ] + * link: add Geneve support. + + [ Thomas Haller ] + * lib/rtnl: rename public define RTNL_GENEVE_ID_MAX + + [ Roopa Prabhu ] + * lib: route: rule: add rule_groups to cache ops + + [ Jonas Johansson ] + * route/vrf: initalize clone destination with NULL in vrf_clone() + + [ David Ahern ] + * Update fib_rules.h to latest kernel + * rule: Add support for protocol and port ranges + + [ Lukáš Karas ] + * add demo program for listen conntrack events + * nf-ct-add typo + + [ Thomas Haller ] + * build: sort entries in Makefile.am and .gitignore by name + * build: indent libnl-route-3.sym with tabs + + [ Tobias Jungel ] + * neigh: set correct AF for NDA_DST + * neigh: support bridge entries for vxlan interfaces + + [ Tuetuopay ] + * cache: make "result" output argument for nl_cache_mngr_add() optional + + [ Volodymyr Bendiuga ] + * include: copy entire pkt_cls.h from linux + * route:cls: add matchall classifier + + [ Thomas Haller ] + * route/mall: fix deep cloning mall + + [ Tuetuopay ] + * route/link: fix sequence number handling in rtnl_link_change() + + [ Thomas Haller ] + * route/link: assert in rtnl_link_change() that the sequence number is set as expected + * nl-msg: explicitly initialize nlmsg_seq and nlmsg_pid field in nlmsg_alloc_simple() + + [ d0u9 ] + * route/class: add new api rtnl_class_get_by_parent() + + [ Tobias Jungel ] + * neigh: correct symbol exposed + + [ Matthieu Baerts ] + * nl: fix function name in debug msg + + [ Tobias Jungel ] + * neigh: cache updates as well query AF_BRIDGE neigh + * whitespace cleanup + * nl-neigh-list: free allocated items + * neigh: add get/set functions for NEIGH_ATTR_MASTER + * neigh_dump_line: dump master as well + + [ d0u9 ] + * Add support for cloning cgroup filter object. + + [ Tuetuopay ] + * route/link/vxlan: Fix IPv4 set_local resetting ce_mask + + [ Tobias Jungel ] + * neigh: update neighbour.h and add missing flags + + [ Thomas Winter ] + * ipgre: Fix wrong array size initialization + * ipvti: Fix wrong array size initialization + * if_tunnel: Update IFLA defines up to FWMARK + + [ Thomas Haller ] + * include/linux: update copy of kernel headers + + [ Volodymyr Bendiuga ] + * include: import linux header pkt_sched.h + * route:qdisc: add MQPRIO Qdisc + + [ Thomas Haller ] + * build: cleanup Makefile.am + * lib/tc: ensure correct error code in rtnl_tc_msg_build() + * lib/qdisc: style fixes in "lib/route/qdisc/mqprio.c" + * lib/qdisc: avoid BUG() in "lib/route/qdisc/mqprio.c" + * build: sort entries in libnl-route-3.sym + * lib/tc: fix uninitalized err variable in rtnl_tc_msg_build() + + [ Volodymyr Bendiuga ] + * route:tc: allow to set chain index for tc objects + + [ Thomas Haller ] + * route/tc: return error code from rtnl_tc_get_chain() + + [ Volodymyr Bendiuga ] + * include: import tc_vlan.h + * route:act: add vlan action + + [ Thomas Haller ] + * route/act: style fixes in "lib/route/act/vlan.c" + * route/act: return error code from act-vlan getters + + [ Ilya Pronin ] + * route/cls: fix potential memory leak + + [ Patrick Havelange ] + * nla_ok: fix overrun in attribute iteration. + + [ Wang Jian ] + * link: macvlan fixes + + [ Thomas Haller ] + * route/macvlan: style fixes in "lib/route/link/macvlan.c" + + [ Tobias Jungel ] + * route/link: expose IFLA_INFO_SLAVE_KIND + + [ Thomas Haller ] + * route/link: avoid dangling pointer in rtnl_link_set_slave_type() + + [ Byeonggon Lee ] + * tests: use nl_send_auto() instead of deprecated nl_send_auto_complete() in test-genl.c + + [ Thomas Haller ] + * doc: fix typos in example in documentation + * attr: mark nested attributes as NLA_F_NESTED + + [ xinbao ] + * Add CTA_LABELS and CTA_LABELS_MASK to ctattr_type according to the new kernel + + [ Thomas Haller ] + * route: fix strncpy() warning from coverity about unterminated string + * link/sriov: fix memleak in rtnl_link_sriov_clone() + * utils: add internal helper macros for cleanup + * lib/genl: avoid VLA in cmd_msg_parser() + * travis: enable -Wvla compiler warning in tests + * travis: build tests with NL_MORE_ASSERTS enabled + * xfrm: fix memory corruption (dangling pointer) when when setting xfrmnl_sa + * route/inet6: fix strncpy() in inet6_dump_details() + * route/tc: ensure not string truncation in rtnl_tc_set_kind() + * genl: reject invalid group names in genl_family_add_grp() + + [ Yegor Yefremov ] + * Add SPDX identifiers + + [ Thomas Haller ] + * lib/genl: fix allocating buffer of too small size in cmd_msg_parser() + + [ Michael Forney ] + * dbg: Use __func__ instead of __PRETTY_FUNCTION__ + * all: Avoid pointer arithmetic on `void *` + * lib: Don't return expression in function returning void + * lib: Don't omit second operand to `?` operator + * all: Use __typeof__ instead of typeof + * route: Remove stray `;` at top-level + * Sync linux headers to 4.19.66 + + [ Thomas Haller ] + * idiag: workaround and add comment about idiagnl_send_simple() only handling 8 bit flags + * lib: accept %NULL arguments for nl_addr_cmp() + * lib: fix error code from nfnl_exp_build_message() + + [ Eyal Birger ] + * doc/route: fix example code comments + * xfrmi: introduce XFRM interfaces support + + [ Thomas Haller ] + * xfrmi: return error code from getters for XFRM links + * route/trivial: sort entries in "libnl-route-3.sym" asciibetically + + [ d0u9 ] + * Add 64bit rate/ceil support for htb class + + [ Thomas Haller ] + * route/qdisc: adjust API for 64 bit rate/ceil support for htb class + * libnl-3.5.0 release + + -- Tamer Ahmed Thu, 02 Jan 2020 10:25:18 -0800 + +libnl3 (3.2.27-2) unstable; urgency=low + + * Add upstream fix for CVE-2017-0553 (Closes: #859948) + + -- Heiko Stuebner Mon, 10 Apr 2017 11:48:23 +0200 + +libnl3 (3.2.27-1) unstable; urgency=low + + * New upstream release + Including fixes for unusable sockets after a failed portid + generation (Closes: #808213) + + -- Heiko Stuebner Sun, 24 Jan 2016 23:54:47 +0100 + +libnl3 (3.2.26-1) unstable; urgency=low + + * New upstream release + * Provide Multiarch:same dev packages + * Add new libnl-xfrm library handling packet transformations + * Update standards to 3.9.6 + + -- Heiko Stuebner Mon, 13 Jul 2015 14:16:22 +0200 + +libnl3 (3.2.24-2) unstable; urgency=low + + * Backport two upstream fixes to prevent issues with older kernels: + - dfd0a80ec845 (route: don't enforce minlen in inet6_parse_protinfo() + (IFLA_PROTINFO) and inet_parse_af() (IFLA_AF_SPEC) + - 5206c050504f (route/addr: only sent IFA_FLAGS when needed to workaround + picky older kernels) + + -- Heiko Stuebner Fri, 18 Apr 2014 17:19:37 +0200 + +libnl3 (3.2.24-1) unstable; urgency=low + + * New upstream release + * Add new libnl-idiag library handling inetdiag requests + + -- Heiko Stuebner Sun, 16 Feb 2014 14:23:26 +0100 + +libnl3 (3.2.21-1) unstable; urgency=low + + * New upstream release (Closes: #707081) + Including CAN support (Closes: #698954) + * Add symbols files (Closes: #654758) + * Provide static libraries (Closes: #693939, #693940) + * Update standards to 3.9.4 + * Removed doc package. Libnl3 documentation is released + separately now. + + -- Heiko Stuebner Tue, 21 May 2013 11:39:13 +0200 + +libnl3 (3.2.7-4) unstable; urgency=low + + * Add watch file (Closes: #679473) + * Use dh-autoreconf to update the build system (Closes: 679474) + + -- Heiko Stuebner Sat, 30 Jun 2012 15:54:25 +0200 + +libnl3 (3.2.7-3) unstable; urgency=low + + * Fix FTBFS due to failing gen-tags.sh (Closes: #674322) + * Convert to Multi-Arch (Closes: #676611) + * Update standards to 3.9.3 - no changes + * Switch to dpkg-source format 3.0 (quilt) + + -- Heiko Stuebner Mon, 18 Jun 2012 21:19:30 +0200 + +libnl3 (3.2.7-2) unstable; urgency=low + + * Force doxygen dot-threads to 1 to circumvent segfaults on armel + * Add missing build-dependency on ghostscript + + -- Heiko Stuebner Mon, 05 Mar 2012 23:29:10 +0100 + +libnl3 (3.2.7-1) unstable; urgency=low + + * New upstream release + * Build-depend on source-highlight (Closes: #657254) + + -- Heiko Stuebner Mon, 13 Feb 2012 18:59:30 +0100 + +libnl3 (3.2.3-2) unstable; urgency=low + + * Upload to unstable + * Split split udeb to be in line with regular packages + * Move libnl and libnl-genl to /lib for iw and wpa_supplicant. + + -- Heiko Stuebner Mon, 19 Dec 2011 20:43:21 +0100 + +libnl3 (3.2.3-1) experimental; urgency=low + + * Upload to experimental to not break debian-installer + * Split library and dev packages for the individual libraries + * Add utils package + + [Mathieu Trudel-Lapierre ] + * New upstream release (Closes: #648819) + * debian/patches/0001-fix-headers.patch, + debian/patches/0002-link-sub-libs.patch, + debian/patches/0003-fix-out-of-tree-build.patch: dropped. + * debian/patches/0004-more-out-of-tree-build-fixes.patch: new patch; adjust + Makefiles some more to properly deal with the out-of-tree build when + generating headers and documentation. + * debian/control: + - rename packages to follow upstream soname. + - add python-pygments, xmlstarlet, texlive-latex-base and asciidoc to + Build-Depends. + * debian/rules: update due to upstream soname changes. + * debian/*.install: rename and update due to upstream soname changes. + * debian/libnl-3-200.install: netlink config files should be installed to + /etc/libnl, not /etc/libnl3. + * debian/libnl-3-doc.install, + debian/libnl-3-doc.doc-base: update to take into account new paths. + + -- Heiko Stuebner Tue, 06 Nov 2011 21:23:12 +0200 + +libnl3 (3.0-2) unstable; urgency=low + + * Acknowledge NMU + * Install config-files to /etc/libnl3 (Closes: #632790) + + -- Heiko Stuebner Mon, 26 Sep 2011 20:27:45 +0200 + +libnl3 (3.0-1.1) unstable; urgency=low + + * Non-maintainer upload with agreement from Heiko Stuebner + * Add libnl3-udeb package with seperate build for + debian-installer (Closes: #635962). + + -- Gaudenz Steinlin Fri, 29 Jul 2011 23:25:48 +0200 + +libnl3 (3.0-1) unstable; urgency=low + + * New upstream release (Closes: #626098) + see README.Debian for version explanation. + * Update standards to 3.9.2 + + -- Heiko Stuebner Sat, 21 May 2011 19:25:13 +0200 + +libnl2 (2.0-1) unstable; urgency=low + + * New upstream release (Closes: #603765) + * Fix compilation with binutils-gold or ld --no-add-needed + (Closes: #615745) + * Update standards + * Update build dependencies - tetex-live is not necessary + anymore (Closes: #616260) + + -- Heiko Stuebner Sun, 06 Mar 2011 18:20:47 +0100 + +libnl2 (1.99+git20091216-2) unstable; urgency=low + + * add README.source describing the patches in use. + * remove libnl*-provides - libnl2 should stay sepparate + from libnl1 for now + + -- Heiko Stuebner Wed, 10 Mar 2010 18:03:35 +0100 + +libnl2 (1.99+git20091216-1) unstable; urgency=low + + * New upstream snapshot + * New source name to enable installing libnl and libnl2 side by side + * Set myself as new maintainer for libnl2 according to agreement + with Michael Biebl + * Add debug package + * README.Debian warns of possible breakage in this snapshot + * Add Patch 0001 which fixes some errors in the build system + * Add Patch 0002 which adds libnl-?? libs to linker statement + until I can resolve this with upstream + + -- Heiko Stuebner Mon, 15 Feb 2010 21:50:35 +0100 + +libnl (1.1-5) unstable; urgency=low + + * Add symbols file for libnl1. + + -- Michael Biebl Wed, 25 Feb 2009 00:26:05 +0100 + +libnl (1.1-4) unstable; urgency=low + + * debian/control + - Add ${misc:Depends} to all binary packages. + - Bump Build-Depends on debhelper to (>= 7). + * debian/compat + - Bump debhelper compat level to 7. + * debian/rules + - Include debhelper.mk before other files as recommended by the cdbs + documentation. + + -- Michael Biebl Wed, 18 Feb 2009 13:26:53 +0100 + +libnl (1.1-3) unstable; urgency=low + + * debian/control + - Bump Standards-Version to 3.8.0. + * Switch to quilt for patch management. + * Add README.source which refers to the quilt documentation. + * debian/patches/limits.patch + - Add missing include to limits.h. This is required when compiling against + glibc 2.8. Thanks to Kees Cook for the patch. Closes: #501485 + + -- Michael Biebl Wed, 08 Oct 2008 21:34:34 +0200 + +libnl (1.1-2) unstable; urgency=low + + * debian/libnl-doc.doc-base + - Register the API documentation with doc-base. + * debian/control + - Add Suggests: doc-base to libnl-doc. + + -- Michael Biebl Wed, 05 Mar 2008 00:42:54 +0100 + +libnl (1.1-1) unstable; urgency=low + + * New stable upstream release. + * debian/patches/01-ip_mg_alg_internal_only.patch + - Removed, merged upstream. + * debian/control + - Rename binary package libnl1-pre8 to libnl1. + - [libnl1] Add Conflicts/Replaces: libnl1-pre8. + - [libnl-dev] Change Depends to libnl1. + * Rename debian/libnl1-pre8.install to debian/libnl1.install + * debian/copyright + - Minor updates and additions. + + -- Michael Biebl Thu, 10 Jan 2008 16:58:12 +0100 + +libnl (1.0~pre8-1) unstable; urgency=low + + * New upstream release. Closes: #456175 + * debian/control + - Bump Standards-Version to 3.7.3. No further changes required. + - The Vcs-* fields are now officially supported, so remove the XS- prefix. + - Rename binary package libnl1-pre6 to libnl1-pre8. + - [libnl1-pre8] Add Conflicts/Replaces: libnl1-pre6. The two versions are + not coinstallable. + - [libnl-dev] Change Depends to libnl1-pre8. + * Rename debian/libnl1-pre6.install to debian/libnl1-pre8.install. + * debian/patches/10-amd64-linux-types.patch + - Removed, merged upstream. + * debian/patches/01-ip_mg_alg_internal_only.patch + - Pull a fix from upstream. The header linux/ip_mp_alg.h is no longer part + of the linux kernel headers (i.e. linux-libc-dev) so remove it from + netlink/netlink.h. + + -- Michael Biebl Thu, 20 Dec 2007 07:45:03 +0100 + +libnl (1.0~pre6-6) unstable; urgency=low + + * debian/control + - Use the new "Homepage:" field to specify the upstream URL. + - Replace deprecated ${Source-Version} substvar with ${binary:Version}. + - Change Build-Depends: gs-gpl | gs-esp to Build-Depends: ghostscript. + + -- Michael Biebl Mon, 22 Oct 2007 07:15:29 +0200 + +libnl (1.0~pre6-5) unstable; urgency=low + + * debian/control + - Add XS-Vcs-* fields. + - Replace Build-Depends: tetex-bin with texlive-latex-base. teTeX is now + gone, superseded by texlive. + - Add Build-Depends: graphviz, gs-gpl | gs-esp. + The "dot" program is needed for generating the diagram image and "gs" + for the ps to png conversion. + + -- Michael Biebl Sun, 15 Apr 2007 15:45:48 +0200 + +libnl (1.0~pre6-4) unstable; urgency=medium + + * Autobuilders do not distinguish between build-arch and build-indep, they + simply run build. So we have to move doxygen and tetex-bin from + Build-Depends-Indep to Build-Depends. Closes: #408719 + * Urgency medium, as it fixes a FTBFS bug. + + -- Michael Biebl Fri, 12 Jan 2007 11:23:52 +0100 + +libnl (1.0~pre6-3) unstable; urgency=low + + * Build and package the API documentation. Closes: #406497 + * debian/control + - Add Build-Depends-Indep on doxygen and tetex-bin (dvips). + - Add new package libnl-doc. + - Add a "Suggests: libnl-doc" to libnl-dev. + * debian/rules + - Call "make gendoc" to build the API documentation. + * debian/libnl-doc.install + - Added. List the files that should be installed. + + -- Michael Biebl Fri, 12 Jan 2007 10:30:40 +0100 + +libnl (1.0~pre6-2) unstable; urgency=low + + * Update maintainer email address to biebl@debian.org. + + -- Michael Biebl Thu, 19 Oct 2006 20:16:09 +0200 + +libnl (1.0~pre6-1) unstable; urgency=low + + * New upstream release. + * Removed 20-autoconf-dirs.patch, merged upstream. + * Updated debian/copyright, libnl is now licensed under the LGPL 2.1. + * Updated debian/watch. + + -- Michael Biebl Fri, 18 Aug 2006 00:40:34 +0200 + +libnl (1.0~pre6~svn30-1) unstable; urgency=low + + * Updated to svn revision 30. + * Bumped Standards-Version to 3.7.2, no further changes required. + * Now that dak officially supports ~ in the version number, let's make use + of it. + * Some install directories were not set correctly, 20-autoconf-dirs.patch + fixes that. + + -- Michael Biebl Thu, 10 Aug 2006 19:51:42 +0200 + +libnl (0.99+1.0.svn21-4) unstable; urgency=low + + * Do not create bogus /usr/lib/pkg-config directory. Closes: #364601 + + -- Michael Biebl Mon, 24 Apr 2006 15:40:23 +0200 + +libnl (0.99+1.0.svn21-3) unstable; urgency=low + + * Include simple-patchsys.mk in debian/rules. + * Merged debian/patches/10-amd64-linux-types.patch from Ubuntu which fixes + the FTBFS error on AMD64. Closes: #358887 + Thanks to Scott James Remnant for this patch. + + -- Michael Biebl Sat, 1 Apr 2006 04:52:13 +0200 + +libnl (0.99+1.0.svn21-2) unstable; urgency=low + + * Initial upload to unstable. + * Renamed libnl1 to libnl1-pre6 to match the currently used so-name. + Otherwise dependent packages like NM will break on upgrades of libnl. + + -- Michael Biebl Tue, 7 Mar 2006 21:22:09 +0100 + +libnl (0.99+1.0.svn21-1) experimental; urgency=low + + * Initial release. Closes: #286847 + + -- Michael Biebl Tue, 21 Feb 2006 18:36:35 +0100 diff --git a/src/libnl3/debian/compat b/src/libnl3/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/libnl3/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/libnl3/debian/control b/src/libnl3/debian/control new file mode 100644 index 000000000000..ba5062607bc1 --- /dev/null +++ b/src/libnl3/debian/control @@ -0,0 +1,245 @@ +Source: libnl3 +Section: net +Priority: optional +Maintainer: Heiko Stuebner +Build-Depends: debhelper (>= 9), dh-exec (>= 0.3), cdbs (>= 0.4.93~), bison, flex, + automake, autoconf, dh-autoreconf, linux-libc-dev (>= 3.2.41), pkg-config +Standards-Version: 3.9.6 +Homepage: http://www.infradead.org/~tgr/libnl/ +#Vcs-Git: https://github.com/thom311/libnl/ +#Vcs-Browser: https://github.com/thom311/libnl/ + +Package: libnl-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + +Package: libnl-cli-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), libnl-genl-3-200 (= ${binary:Version}), libnl-nf-3-200 (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - cli helpers + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + Library for cli helpers in libnl-utils. + +Package: libnl-utils +Architecture: linux-any +Section: libs +Depends: libnl-cli-3-200 (= ${binary:Version}), libnl-idiag-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Description: Utilities for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + These utilities help dealing with netlink sockets. + +Package: libnl-genl-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - generic netlink + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the generic netlink protocol, an extended version of the netlink + protocol. + +Package: libnl-idiag-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - inetdiag interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the inetdiag netlink protocol, handling inetdiag requests + +Package: libnl-nf-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - netfilter interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to netlink based netfilter configuration and monitoring interfaces. + +Package: libnl-route-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - route interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the configuration interfaces of the NETLINK_ROUTE family. + +Package: libnl-xfrm-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - package transformations + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to netlink based package transformations (such as encrypting + their payloads). + +Package: libnl-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends} +Conflicts: libnl-dev, libnl2-dev +Breaks: libnl3-dev +Replaces: libnl3-dev +Multi-Arch: same +Description: development library and headers for libnl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the headers needed by all libraries and the files + that are needed to build applications using libnl3. + +Package: libnl-cli-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-genl-3-dev (= ${binary:Version}), libnl-nf-3-dev (= ${binary:Version}), libnl-route-3-dev (= ${binary:Version}), libnl-cli-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-cli-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-cli-3. + +Package: libnl-genl-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-genl-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-genl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-genl-3. + +Package: libnl-idiag-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-idiag-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-genl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-idiag-3. + +Package: libnl-nf-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-route-3-dev (= ${binary:Version}), libnl-nf-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-nf-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-nf-3. + +Package: libnl-route-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-route-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-route-3. + +Package: libnl-xfrm-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-xfrm-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-xfrm-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-xfrm-3. + +Package: libnl-3-200-dbg +Architecture: linux-any +Section: debug +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends} +Priority: extra +Description: debug symbols for libnl3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains unstripped shared libraries. It is provided primarily + to provide a backtrace with names in a debugger, this makes it somewhat easier + to interpret core dumps. The libraries are installed in /usr/lib/debug and + are automatically used by gdb. + +Package: libnl-3-200-udeb +Architecture: linux-any +XC-Package-Type: udeb +Section: debian-installer +Depends: ${misc:Depends}, ${shlibs:Depends} +Description: library for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package is a udeb. It's only useful inside of debian-installer. + +Package: libnl-genl-3-200-udeb +Architecture: linux-any +XC-Package-Type: udeb +Section: debian-installer +Depends: libnl-3-200-udeb (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Description: library for dealing with netlink sockets - generic netlink + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package is a udeb. It's only useful inside of debian-installer. diff --git a/src/libnl3/debian/copyright b/src/libnl3/debian/copyright new file mode 100644 index 000000000000..07457363bf67 --- /dev/null +++ b/src/libnl3/debian/copyright @@ -0,0 +1,160 @@ +This package was debianized by Tamer Ahmed on +Tue, 31 Decn 2019 12:00:46 +0000. +The packaging is based on Heiko Stuebner's original packaging +of libnl1. + +It was downloaded from https://github.com/thom311/libnl/releases + +Upstream Author: + Thomas Graf + + +Copyright: + +lib/route/addr.c +include/netlink/route/addr.h + + Copyright (c) Thomas Graf + Baruch Even + + +lib/route/cls/u32.c +lib/route/cls/fw.c +lib/route/sch/htb.c +include/netlink/route/cls/fw.h +include/netlink/route/sch/htb.h + + Copyright (c) Thomas Graf + Copyright (c) Petr Gotthard + Copyright (c) Siemens AG Oesterreich + + + +lib/netfilter/log_msg.c +lib/netfilter/ct.c +include/netlink/netfilter/log_msg.h +include/netlink/netfilter/log.h +lib/netfilter/log_obj.c + + Copyright (c) Thomas Graf + Copyright (c) Philip Craig + Copyright (c) Patrick McHardy + Copyright (c) Secure Computing Corporation + + + +include/netlink/netfilter/queue_msg.h +lib/netfilter/queue_msg_obj.c +lib/netfilter/queue_msg.c +lib/netfilter/queue.c +lib/netfilter/netfilter.c +lib/netfilter/queue_obj.c +include/netlink/netfilter/netfilter.h +include/netlink/netfilter/queue.h +src/nf-queue.c + + Copyright (c) Patrick McHardy + + + +include/netlink/xfrm/selector.h +include/netlink/xfrm/sa.h +include/netlink/xfrm/ae.h +include/netlink/xfrm/sp.h +include/netlink/xfrm/template.h +include/netlink/xfrm/lifetime.h +lib/xfrm/sa.c +lib/xfrm/template.c +lib/xfrm/ae.c +lib/xfrm/sp.c +lib/xfrm/selector.c +lib/xfrm/lifetime.c + + Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + + +All other *.c and *.h files not mentioned above are copyright of: + + Copyright (c) 2003-2006 Thomas Graf + + +License: + +src/nl-addr-add.c +src/nl-addr-list.c +src/nl-cls-add.c +src/cls/utils.c +src/cls/cgroup.c +src/cls/utils.h +src/cls/basic.c +src/nl-addr-delete.c: + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + +On Debian GNU/Linux systems, the complete text of the GNU General +Public License can be found in /usr/share/common-licenses/GPL-2 + + +include/netlink/xfrm/selector.h +include/netlink/xfrm/sa.h +include/netlink/xfrm/ae.h +include/netlink/xfrm/sp.h +include/netlink/xfrm/template.h +include/netlink/xfrm/lifetime.h +lib/xfrm/sa.c +lib/xfrm/template.c +lib/xfrm/ae.c +lib/xfrm/sp.c +lib/xfrm/selector.c +lib/xfrm/lifetime.c + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the + distribution. + + Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +All other *.c and *.h files not mentioned above: + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation version 2.1 of the License. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + +On Debian GNU/Linux systems, the complete text of the GNU Lesser General +Public License can be found in /usr/share/common-licenses/LGPL-2.1 + diff --git a/src/libnl3/debian/gbp.conf b/src/libnl3/debian/gbp.conf new file mode 100644 index 000000000000..a504bacc7748 --- /dev/null +++ b/src/libnl3/debian/gbp.conf @@ -0,0 +1,16 @@ +# Configuration file for git-buildpackage and friends + +[DEFAULT] +# the default build command: +#builder = debuild -i -I +# the default clean command: +#cleaner = debuild clean +# the default branch for upstream sources: +upstream-branch = upstream-dist +# the default branch for the debian patch: +#debian-branch = master +# the default tag formats used: +#upstream-tag = upstream/%(version)s +#debian-tag = debian/%(version)s +# use pristine-tar: +pristine-tar = true diff --git a/src/libnl3/debian/libnl-3-200-udeb.install b/src/libnl3/debian/libnl-3-200-udeb.install new file mode 100644 index 000000000000..4b3a77ce011d --- /dev/null +++ b/src/libnl3/debian/libnl-3-200-udeb.install @@ -0,0 +1 @@ +usr/lib/*/libnl-3.so.* lib diff --git a/src/libnl3/debian/libnl-3-200.install b/src/libnl3/debian/libnl-3-200.install new file mode 100755 index 000000000000..0a6aa3850b2c --- /dev/null +++ b/src/libnl3/debian/libnl-3-200.install @@ -0,0 +1,3 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3*.so.* lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/etc/libnl/* etc/libnl-3 diff --git a/src/libnl3/debian/libnl-3-200.symbols b/src/libnl3/debian/libnl-3-200.symbols new file mode 100644 index 000000000000..119e0554920f --- /dev/null +++ b/src/libnl3/debian/libnl-3-200.symbols @@ -0,0 +1,661 @@ +libnl-3.so.200 libnl-3-200 #MINVER# + __flags2str@Base 3.5.0-1 + __flags2str@libnl_3 3.5.0-1 + __list_str2type@Base 3.5.0-1 + __list_str2type@libnl_3 3.5.0-1 + __list_type2str@Base 3.5.0-1 + __list_type2str@libnl_3 3.5.0-1 + __nl_cache_mngt_require@Base 3.5.0-1 + __nl_cache_mngt_require@libnl_3 3.5.0-1 + __nl_cache_ops_lookup@Base 3.5.0-1 + __nl_read_num_str_file@Base 3.5.0-1 + __nl_read_num_str_file@libnl_3 3.5.0-1 + __str2flags@Base 3.5.0-1 + __str2flags@libnl_3 3.5.0-1 + __str2type@Base 3.5.0-1 + __str2type@libnl_3 3.5.0-1 + __trans_list_add@Base 3.5.0-1 + __trans_list_add@libnl_3 3.5.0-1 + __trans_list_clear@Base 3.5.0-1 + __trans_list_clear@libnl_3 3.5.0-1 + __type2str@Base 3.5.0-1 + __type2str@libnl_3 3.5.0-1 + _nl_socket_generate_local_port_no_release@Base 3.5.0-1 + _nl_socket_is_local_port_unspecified@Base 3.5.0-1 + _nl_socket_set_local_port_no_release@Base 3.5.0-1 + _nl_socket_used_ports_release_all@Base 3.5.0-1 + _nl_socket_used_ports_set@Base 3.5.0-1 + dump_from_ops@Base 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_26@libnl_3_2_26 3.5.0-1 + libnl_3_2_27@libnl_3_2_27 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + libnl_3_2_29@libnl_3_2_29 3.5.0-1 + libnl_3_5@libnl_3_5 3.5.0-1 + nl_addr2str@Base 3.5.0-1 + nl_addr2str@libnl_3 3.5.0-1 + nl_addr_alloc@Base 3.5.0-1 + nl_addr_alloc@libnl_3 3.5.0-1 + nl_addr_alloc_attr@Base 3.5.0-1 + nl_addr_alloc_attr@libnl_3 3.5.0-1 + nl_addr_build@Base 3.5.0-1 + nl_addr_build@libnl_3 3.5.0-1 + nl_addr_clone@Base 3.5.0-1 + nl_addr_clone@libnl_3 3.5.0-1 + nl_addr_cmp@Base 3.5.0-1 + nl_addr_cmp@libnl_3 3.5.0-1 + nl_addr_cmp_prefix@Base 3.5.0-1 + nl_addr_cmp_prefix@libnl_3 3.5.0-1 + nl_addr_fill_sockaddr@Base 3.5.0-1 + nl_addr_fill_sockaddr@libnl_3 3.5.0-1 + nl_addr_get@Base 3.5.0-1 + nl_addr_get@libnl_3 3.5.0-1 + nl_addr_get_binary_addr@Base 3.5.0-1 + nl_addr_get_binary_addr@libnl_3 3.5.0-1 + nl_addr_get_family@Base 3.5.0-1 + nl_addr_get_family@libnl_3 3.5.0-1 + nl_addr_get_len@Base 3.5.0-1 + nl_addr_get_len@libnl_3 3.5.0-1 + nl_addr_get_prefixlen@Base 3.5.0-1 + nl_addr_get_prefixlen@libnl_3 3.5.0-1 + nl_addr_guess_family@Base 3.5.0-1 + nl_addr_guess_family@libnl_3 3.5.0-1 + nl_addr_info@Base 3.5.0-1 + nl_addr_info@libnl_3 3.5.0-1 + nl_addr_iszero@Base 3.5.0-1 + nl_addr_iszero@libnl_3 3.5.0-1 + nl_addr_parse@Base 3.5.0-1 + nl_addr_parse@libnl_3 3.5.0-1 + nl_addr_put@Base 3.5.0-1 + nl_addr_put@libnl_3 3.5.0-1 + nl_addr_resolve@Base 3.5.0-1 + nl_addr_resolve@libnl_3 3.5.0-1 + nl_addr_set_binary_addr@Base 3.5.0-1 + nl_addr_set_binary_addr@libnl_3 3.5.0-1 + nl_addr_set_family@Base 3.5.0-1 + nl_addr_set_family@libnl_3 3.5.0-1 + nl_addr_set_prefixlen@Base 3.5.0-1 + nl_addr_set_prefixlen@libnl_3 3.5.0-1 + nl_addr_shared@Base 3.5.0-1 + nl_addr_shared@libnl_3 3.5.0-1 + nl_addr_valid@Base 3.5.0-1 + nl_addr_valid@libnl_3 3.5.0-1 + nl_af2str@Base 3.5.0-1 + nl_af2str@libnl_3 3.5.0-1 + nl_auto_complete@Base 3.5.0-1 + nl_auto_complete@libnl_3 3.5.0-1 + nl_cache_add@Base 3.5.0-1 + nl_cache_add@libnl_3 3.5.0-1 + nl_cache_alloc@Base 3.5.0-1 + nl_cache_alloc@libnl_3 3.5.0-1 + nl_cache_alloc_and_fill@Base 3.5.0-1 + nl_cache_alloc_and_fill@libnl_3 3.5.0-1 + nl_cache_alloc_name@Base 3.5.0-1 + nl_cache_alloc_name@libnl_3 3.5.0-1 + nl_cache_clear@Base 3.5.0-1 + nl_cache_clear@libnl_3 3.5.0-1 + nl_cache_clone@Base 3.5.0-1 + nl_cache_clone@libnl_3 3.5.0-1 + nl_cache_dump@Base 3.5.0-1 + nl_cache_dump@libnl_3 3.5.0-1 + nl_cache_dump_filter@Base 3.5.0-1 + nl_cache_dump_filter@libnl_3 3.5.0-1 + nl_cache_find@Base 3.5.0-1 + nl_cache_find@libnl_3 3.5.0-1 + nl_cache_foreach@Base 3.5.0-1 + nl_cache_foreach@libnl_3 3.5.0-1 + nl_cache_foreach_filter@Base 3.5.0-1 + nl_cache_foreach_filter@libnl_3 3.5.0-1 + nl_cache_free@Base 3.5.0-1 + nl_cache_free@libnl_3 3.5.0-1 + nl_cache_get@Base 3.5.0-1 + nl_cache_get@libnl_3 3.5.0-1 + nl_cache_get_first@Base 3.5.0-1 + nl_cache_get_first@libnl_3 3.5.0-1 + nl_cache_get_last@Base 3.5.0-1 + nl_cache_get_last@libnl_3 3.5.0-1 + nl_cache_get_next@Base 3.5.0-1 + nl_cache_get_next@libnl_3 3.5.0-1 + nl_cache_get_ops@Base 3.5.0-1 + nl_cache_get_ops@libnl_3 3.5.0-1 + nl_cache_get_prev@Base 3.5.0-1 + nl_cache_get_prev@libnl_3 3.5.0-1 + nl_cache_include@Base 3.5.0-1 + nl_cache_include@libnl_3 3.5.0-1 + nl_cache_include_v2@libnl_3_2_29 3.5.0-1 + nl_cache_is_empty@Base 3.5.0-1 + nl_cache_is_empty@libnl_3 3.5.0-1 + nl_cache_mark_all@Base 3.5.0-1 + nl_cache_mark_all@libnl_3 3.5.0-1 + nl_cache_mngr_add@Base 3.5.0-1 + nl_cache_mngr_add@libnl_3 3.5.0-1 + nl_cache_mngr_add_cache@Base 3.5.0-1 + nl_cache_mngr_add_cache@libnl_3 3.5.0-1 + nl_cache_mngr_add_cache_v2@libnl_3_2_29 3.5.0-1 + nl_cache_mngr_alloc@Base 3.5.0-1 + nl_cache_mngr_alloc@libnl_3 3.5.0-1 + nl_cache_mngr_data_ready@Base 3.5.0-1 + nl_cache_mngr_data_ready@libnl_3 3.5.0-1 + nl_cache_mngr_free@Base 3.5.0-1 + nl_cache_mngr_free@libnl_3 3.5.0-1 + nl_cache_mngr_get_fd@Base 3.5.0-1 + nl_cache_mngr_get_fd@libnl_3 3.5.0-1 + nl_cache_mngr_info@Base 3.5.0-1 + nl_cache_mngr_info@libnl_3 3.5.0-1 + nl_cache_mngr_poll@Base 3.5.0-1 + nl_cache_mngr_poll@libnl_3 3.5.0-1 + nl_cache_mngt_provide@Base 3.5.0-1 + nl_cache_mngt_provide@libnl_3 3.5.0-1 + nl_cache_mngt_register@Base 3.5.0-1 + nl_cache_mngt_register@libnl_3 3.5.0-1 + nl_cache_mngt_require@Base 3.5.0-1 + nl_cache_mngt_require@libnl_3 3.5.0-1 + nl_cache_mngt_require_safe@Base 3.5.0-1 + nl_cache_mngt_require_safe@libnl_3 3.5.0-1 + nl_cache_mngt_unprovide@Base 3.5.0-1 + nl_cache_mngt_unprovide@libnl_3 3.5.0-1 + nl_cache_mngt_unregister@Base 3.5.0-1 + nl_cache_mngt_unregister@libnl_3 3.5.0-1 + nl_cache_move@Base 3.5.0-1 + nl_cache_move@libnl_3 3.5.0-1 + nl_cache_nitems@Base 3.5.0-1 + nl_cache_nitems@libnl_3 3.5.0-1 + nl_cache_nitems_filter@Base 3.5.0-1 + nl_cache_nitems_filter@libnl_3 3.5.0-1 + nl_cache_ops_associate@Base 3.5.0-1 + nl_cache_ops_associate@libnl_3 3.5.0-1 + nl_cache_ops_associate_safe@Base 3.5.0-1 + nl_cache_ops_associate_safe@libnl_3 3.5.0-1 + nl_cache_ops_foreach@Base 3.5.0-1 + nl_cache_ops_foreach@libnl_3 3.5.0-1 + nl_cache_ops_get@Base 3.5.0-1 + nl_cache_ops_get@libnl_3 3.5.0-1 + nl_cache_ops_lookup@Base 3.5.0-1 + nl_cache_ops_lookup@libnl_3 3.5.0-1 + nl_cache_ops_lookup_safe@Base 3.5.0-1 + nl_cache_ops_lookup_safe@libnl_3 3.5.0-1 + nl_cache_ops_put@Base 3.5.0-1 + nl_cache_ops_put@libnl_3 3.5.0-1 + nl_cache_ops_set_flags@Base 3.5.0-1 + nl_cache_ops_set_flags@libnl_3 3.5.0-1 + nl_cache_parse@Base 3.5.0-1 + nl_cache_parse@libnl_3 3.5.0-1 + nl_cache_parse_and_add@Base 3.5.0-1 + nl_cache_parse_and_add@libnl_3 3.5.0-1 + nl_cache_pickup@Base 3.5.0-1 + nl_cache_pickup@libnl_3 3.5.0-1 + nl_cache_pickup_checkdup@Base 3.5.0-1 + nl_cache_pickup_checkdup@libnl_3 3.5.0-1 + nl_cache_put@Base 3.5.0-1 + nl_cache_put@libnl_3 3.5.0-1 + nl_cache_refill@Base 3.5.0-1 + nl_cache_refill@libnl_3 3.5.0-1 + nl_cache_remove@Base 3.5.0-1 + nl_cache_remove@libnl_3 3.5.0-1 + nl_cache_resync@Base 3.5.0-1 + nl_cache_resync@libnl_3 3.5.0-1 + nl_cache_search@Base 3.5.0-1 + nl_cache_search@libnl_3 3.5.0-1 + nl_cache_set_arg1@Base 3.5.0-1 + nl_cache_set_arg1@libnl_3 3.5.0-1 + nl_cache_set_arg2@Base 3.5.0-1 + nl_cache_set_arg2@libnl_3 3.5.0-1 + nl_cache_set_flags@Base 3.5.0-1 + nl_cache_set_flags@libnl_3 3.5.0-1 + nl_cache_subset@Base 3.5.0-1 + nl_cache_subset@libnl_3 3.5.0-1 + nl_cancel_down_bits@Base 3.5.0-1 + nl_cancel_down_bits@libnl_3 3.5.0-1 + nl_cancel_down_bytes@Base 3.5.0-1 + nl_cancel_down_bytes@libnl_3 3.5.0-1 + nl_cancel_down_us@Base 3.5.0-1 + nl_cancel_down_us@libnl_3 3.5.0-1 + nl_cb_active_type@Base 3.5.0-1 + nl_cb_active_type@libnl_3 3.5.0-1 + nl_cb_alloc@Base 3.5.0-1 + nl_cb_alloc@libnl_3 3.5.0-1 + nl_cb_clone@Base 3.5.0-1 + nl_cb_clone@libnl_3 3.5.0-1 + nl_cb_err@Base 3.5.0-1 + nl_cb_err@libnl_3 3.5.0-1 + nl_cb_get@Base 3.5.0-1 + nl_cb_get@libnl_3 3.5.0-1 + nl_cb_overwrite_recv@Base 3.5.0-1 + nl_cb_overwrite_recv@libnl_3 3.5.0-1 + nl_cb_overwrite_recvmsgs@Base 3.5.0-1 + nl_cb_overwrite_recvmsgs@libnl_3 3.5.0-1 + nl_cb_overwrite_send@Base 3.5.0-1 + nl_cb_overwrite_send@libnl_3 3.5.0-1 + nl_cb_put@Base 3.5.0-1 + nl_cb_put@libnl_3 3.5.0-1 + nl_cb_set@Base 3.5.0-1 + nl_cb_set@libnl_3 3.5.0-1 + nl_cb_set_all@Base 3.5.0-1 + nl_cb_set_all@libnl_3 3.5.0-1 + nl_close@Base 3.5.0-1 + nl_close@libnl_3 3.5.0-1 + nl_complete_msg@Base 3.5.0-1 + nl_complete_msg@libnl_3 3.5.0-1 + nl_connect@Base 3.5.0-1 + nl_connect@libnl_3 3.5.0-1 + nl_data_alloc@Base 3.5.0-1 + nl_data_alloc@libnl_3 3.5.0-1 + nl_data_alloc_attr@Base 3.5.0-1 + nl_data_alloc_attr@libnl_3 3.5.0-1 + nl_data_append@Base 3.5.0-1 + nl_data_append@libnl_3 3.5.0-1 + nl_data_clone@Base 3.5.0-1 + nl_data_clone@libnl_3 3.5.0-1 + nl_data_cmp@Base 3.5.0-1 + nl_data_cmp@libnl_3 3.5.0-1 + nl_data_free@Base 3.5.0-1 + nl_data_free@libnl_3 3.5.0-1 + nl_data_get@Base 3.5.0-1 + nl_data_get@libnl_3 3.5.0-1 + nl_data_get_size@Base 3.5.0-1 + nl_data_get_size@libnl_3 3.5.0-1 + nl_debug@Base 3.5.0-1 + nl_debug@libnl_3 3.5.0-1 + nl_debug_dp@Base 3.5.0-1 + nl_debug_dp@libnl_3 3.5.0-1 + nl_dump@Base 3.5.0-1 + nl_dump@libnl_3 3.5.0-1 + nl_dump_line@Base 3.5.0-1 + nl_dump_line@libnl_3 3.5.0-1 + nl_ether_proto2str@Base 3.5.0-1 + nl_ether_proto2str@libnl_3 3.5.0-1 + nl_get_psched_hz@Base 3.5.0-1 + nl_get_psched_hz@libnl_3 3.5.0-1 + nl_get_user_hz@Base 3.5.0-1 + nl_get_user_hz@libnl_3 3.5.0-1 + nl_geterror@Base 3.5.0-1 + nl_geterror@libnl_3 3.5.0-1 + nl_has_capability@Base 3.5.0-1 + nl_has_capability@libnl_3 3.5.0-1 + nl_hash@Base 3.5.0-1 + nl_hash@libnl_3 3.5.0-1 + nl_hash_any@Base 3.5.0-1 + nl_hash_any@libnl_3 3.5.0-1 + nl_hash_table_add@Base 3.5.0-1 + nl_hash_table_add@libnl_3 3.5.0-1 + nl_hash_table_alloc@Base 3.5.0-1 + nl_hash_table_alloc@libnl_3 3.5.0-1 + nl_hash_table_del@Base 3.5.0-1 + nl_hash_table_del@libnl_3 3.5.0-1 + nl_hash_table_free@Base 3.5.0-1 + nl_hash_table_free@libnl_3 3.5.0-1 + nl_hash_table_lookup@Base 3.5.0-1 + nl_hash_table_lookup@libnl_3 3.5.0-1 + nl_ip_proto2str@Base 3.5.0-1 + nl_ip_proto2str@libnl_3 3.5.0-1 + nl_join_groups@Base 3.5.0-1 + nl_join_groups@libnl_3 3.5.0-1 + nl_llproto2str@Base 3.5.0-1 + nl_llproto2str@libnl_3 3.5.0-1 + nl_msec2str@Base 3.5.0-1 + nl_msec2str@libnl_3 3.5.0-1 + nl_msg_dump@Base 3.5.0-1 + nl_msg_dump@libnl_3 3.5.0-1 + nl_msg_parse@Base 3.5.0-1 + nl_msg_parse@libnl_3 3.5.0-1 + nl_msgtype_lookup@Base 3.5.0-1 + nl_msgtype_lookup@libnl_3 3.5.0-1 + nl_new_line@Base 3.5.0-1 + nl_new_line@libnl_3 3.5.0-1 + nl_nlfamily2str@Base 3.5.0-1 + nl_nlfamily2str@libnl_3 3.5.0-1 + nl_nlmsg_flags2str@Base 3.5.0-1 + nl_nlmsg_flags2str@libnl_3 3.5.0-1 + nl_nlmsgtype2str@Base 3.5.0-1 + nl_nlmsgtype2str@libnl_3 3.5.0-1 + nl_object_alloc@Base 3.5.0-1 + nl_object_alloc@libnl_3 3.5.0-1 + nl_object_alloc_name@Base 3.5.0-1 + nl_object_alloc_name@libnl_3 3.5.0-1 + nl_object_attr_list@Base 3.5.0-1 + nl_object_attr_list@libnl_3 3.5.0-1 + nl_object_attrs2str@Base 3.5.0-1 + nl_object_attrs2str@libnl_3 3.5.0-1 + nl_object_clone@Base 3.5.0-1 + nl_object_clone@libnl_3 3.5.0-1 + nl_object_diff64@libnl_3_2_28 3.5.0-1 + nl_object_diff@Base 3.5.0-1 + nl_object_diff@libnl_3 3.5.0-1 + nl_object_dump@Base 3.5.0-1 + nl_object_dump@libnl_3 3.5.0-1 + nl_object_dump_buf@Base 3.5.0-1 + nl_object_dump_buf@libnl_3 3.5.0-1 + nl_object_free@Base 3.5.0-1 + nl_object_free@libnl_3 3.5.0-1 + nl_object_get@Base 3.5.0-1 + nl_object_get@libnl_3 3.5.0-1 + nl_object_get_cache@Base 3.5.0-1 + nl_object_get_cache@libnl_3 3.5.0-1 + nl_object_get_id_attrs@Base 3.5.0-1 + nl_object_get_id_attrs@libnl_3 3.5.0-1 + nl_object_get_msgtype@Base 3.5.0-1 + nl_object_get_msgtype@libnl_3 3.5.0-1 + nl_object_get_ops@Base 3.5.0-1 + nl_object_get_ops@libnl_3 3.5.0-1 + nl_object_get_refcnt@Base 3.5.0-1 + nl_object_get_refcnt@libnl_3 3.5.0-1 + nl_object_get_type@Base 3.5.0-1 + nl_object_get_type@libnl_3 3.5.0-1 + nl_object_identical@Base 3.5.0-1 + nl_object_identical@libnl_3 3.5.0-1 + nl_object_is_marked@Base 3.5.0-1 + nl_object_is_marked@libnl_3 3.5.0-1 + nl_object_keygen@Base 3.5.0-1 + nl_object_keygen@libnl_3 3.5.0-1 + nl_object_mark@Base 3.5.0-1 + nl_object_mark@libnl_3 3.5.0-1 + nl_object_match_filter@Base 3.5.0-1 + nl_object_match_filter@libnl_3 3.5.0-1 + nl_object_put@Base 3.5.0-1 + nl_object_put@libnl_3 3.5.0-1 + nl_object_shared@Base 3.5.0-1 + nl_object_shared@libnl_3 3.5.0-1 + nl_object_unmark@Base 3.5.0-1 + nl_object_unmark@libnl_3 3.5.0-1 + nl_object_update@Base 3.5.0-1 + nl_object_update@libnl_3 3.5.0-1 + nl_perror@Base 3.5.0-1 + nl_perror@libnl_3 3.5.0-1 + nl_pickup@Base 3.5.0-1 + nl_pickup@libnl_3 3.5.0-1 + nl_pickup_keep_syserr@Base 3.5.0-1 + nl_pickup_keep_syserr@libnl_3 3.5.0-1 + nl_prob2int@Base 3.5.0-1 + nl_prob2int@libnl_3 3.5.0-1 + nl_rate2str@Base 3.5.0-1 + nl_rate2str@libnl_3 3.5.0-1 + nl_recv@Base 3.5.0-1 + nl_recv@libnl_3 3.5.0-1 + nl_recvmsgs@Base 3.5.0-1 + nl_recvmsgs@libnl_3 3.5.0-1 + nl_recvmsgs_default@Base 3.5.0-1 + nl_recvmsgs_default@libnl_3 3.5.0-1 + nl_recvmsgs_report@Base 3.5.0-1 + nl_recvmsgs_report@libnl_3 3.5.0-1 + nl_send@Base 3.5.0-1 + nl_send@libnl_3 3.5.0-1 + nl_send_auto@Base 3.5.0-1 + nl_send_auto@libnl_3 3.5.0-1 + nl_send_auto_complete@Base 3.5.0-1 + nl_send_auto_complete@libnl_3 3.5.0-1 + nl_send_iovec@Base 3.5.0-1 + nl_send_iovec@libnl_3 3.5.0-1 + nl_send_simple@Base 3.5.0-1 + nl_send_simple@libnl_3 3.5.0-1 + nl_send_sync@Base 3.5.0-1 + nl_send_sync@libnl_3 3.5.0-1 + nl_sendmsg@Base 3.5.0-1 + nl_sendmsg@libnl_3 3.5.0-1 + nl_sendto@Base 3.5.0-1 + nl_sendto@libnl_3 3.5.0-1 + nl_size2int@Base 3.5.0-1 + nl_size2int@libnl_3 3.5.0-1 + nl_size2str@Base 3.5.0-1 + nl_size2str@libnl_3 3.5.0-1 + nl_socket_add_membership@Base 3.5.0-1 + nl_socket_add_membership@libnl_3 3.5.0-1 + nl_socket_add_memberships@Base 3.5.0-1 + nl_socket_add_memberships@libnl_3 3.5.0-1 + nl_socket_alloc@Base 3.5.0-1 + nl_socket_alloc@libnl_3 3.5.0-1 + nl_socket_alloc_cb@Base 3.5.0-1 + nl_socket_alloc_cb@libnl_3 3.5.0-1 + nl_socket_disable_auto_ack@Base 3.5.0-1 + nl_socket_disable_auto_ack@libnl_3 3.5.0-1 + nl_socket_disable_msg_peek@Base 3.5.0-1 + nl_socket_disable_msg_peek@libnl_3 3.5.0-1 + nl_socket_disable_seq_check@Base 3.5.0-1 + nl_socket_disable_seq_check@libnl_3 3.5.0-1 + nl_socket_drop_membership@Base 3.5.0-1 + nl_socket_drop_membership@libnl_3 3.5.0-1 + nl_socket_drop_memberships@Base 3.5.0-1 + nl_socket_drop_memberships@libnl_3 3.5.0-1 + nl_socket_enable_auto_ack@Base 3.5.0-1 + nl_socket_enable_auto_ack@libnl_3 3.5.0-1 + nl_socket_enable_msg_peek@Base 3.5.0-1 + nl_socket_enable_msg_peek@libnl_3 3.5.0-1 + nl_socket_free@Base 3.5.0-1 + nl_socket_free@libnl_3 3.5.0-1 + nl_socket_get_cb@Base 3.5.0-1 + nl_socket_get_cb@libnl_3 3.5.0-1 + nl_socket_get_fd@Base 3.5.0-1 + nl_socket_get_fd@libnl_3 3.5.0-1 + nl_socket_get_local_port@Base 3.5.0-1 + nl_socket_get_local_port@libnl_3 3.5.0-1 + nl_socket_get_msg_buf_size@Base 3.5.0-1 + nl_socket_get_msg_buf_size@libnl_3 3.5.0-1 + nl_socket_get_peer_groups@Base 3.5.0-1 + nl_socket_get_peer_groups@libnl_3 3.5.0-1 + nl_socket_get_peer_port@Base 3.5.0-1 + nl_socket_get_peer_port@libnl_3 3.5.0-1 + nl_socket_modify_cb@Base 3.5.0-1 + nl_socket_modify_cb@libnl_3 3.5.0-1 + nl_socket_modify_err_cb@Base 3.5.0-1 + nl_socket_modify_err_cb@libnl_3 3.5.0-1 + nl_socket_recv_pktinfo@Base 3.5.0-1 + nl_socket_recv_pktinfo@libnl_3 3.5.0-1 + nl_socket_set_buffer_size@Base 3.5.0-1 + nl_socket_set_buffer_size@libnl_3 3.5.0-1 + nl_socket_set_cb@Base 3.5.0-1 + nl_socket_set_cb@libnl_3 3.5.0-1 + nl_socket_set_fd@Base 3.5.0-1 + nl_socket_set_fd@libnl_3_2_26 3.5.0-1 + nl_socket_set_local_port@Base 3.5.0-1 + nl_socket_set_local_port@libnl_3 3.5.0-1 + nl_socket_set_msg_buf_size@Base 3.5.0-1 + nl_socket_set_msg_buf_size@libnl_3 3.5.0-1 + nl_socket_set_nonblocking@Base 3.5.0-1 + nl_socket_set_nonblocking@libnl_3 3.5.0-1 + nl_socket_set_passcred@Base 3.5.0-1 + nl_socket_set_passcred@libnl_3 3.5.0-1 + nl_socket_set_peer_groups@Base 3.5.0-1 + nl_socket_set_peer_groups@libnl_3 3.5.0-1 + nl_socket_set_peer_port@Base 3.5.0-1 + nl_socket_set_peer_port@libnl_3 3.5.0-1 + nl_socket_use_seq@Base 3.5.0-1 + nl_socket_use_seq@libnl_3 3.5.0-1 + nl_str2af@Base 3.5.0-1 + nl_str2af@libnl_3 3.5.0-1 + nl_str2ether_proto@Base 3.5.0-1 + nl_str2ether_proto@libnl_3 3.5.0-1 + nl_str2ip_proto@Base 3.5.0-1 + nl_str2ip_proto@libnl_3 3.5.0-1 + nl_str2llproto@Base 3.5.0-1 + nl_str2llproto@libnl_3 3.5.0-1 + nl_str2msec@Base 3.5.0-1 + nl_str2msec@libnl_3 3.5.0-1 + nl_str2nlfamily@Base 3.5.0-1 + nl_str2nlfamily@libnl_3 3.5.0-1 + nl_str2nlmsgtype@Base 3.5.0-1 + nl_str2nlmsgtype@libnl_3 3.5.0-1 + nl_strerror_l@libnl_3_2_29 3.5.0-1 + nl_syserr2nlerr@Base 3.5.0-1 + nl_syserr2nlerr@libnl_3 3.5.0-1 + nl_ticks2us@Base 3.5.0-1 + nl_ticks2us@libnl_3 3.5.0-1 + nl_us2ticks@Base 3.5.0-1 + nl_us2ticks@libnl_3 3.5.0-1 + nl_ver_maj@Base 3.5.0-1 + nl_ver_maj@libnl_3 3.5.0-1 + nl_ver_mic@Base 3.5.0-1 + nl_ver_mic@libnl_3 3.5.0-1 + nl_ver_min@Base 3.5.0-1 + nl_ver_min@libnl_3 3.5.0-1 + nl_ver_num@Base 3.5.0-1 + nl_ver_num@libnl_3 3.5.0-1 + nl_wait_for_ack@Base 3.5.0-1 + nl_wait_for_ack@libnl_3 3.5.0-1 + nla_attr_size@Base 3.5.0-1 + nla_attr_size@libnl_3 3.5.0-1 + nla_data@Base 3.5.0-1 + nla_data@libnl_3 3.5.0-1 + nla_find@Base 3.5.0-1 + nla_find@libnl_3 3.5.0-1 + nla_get_flag@Base 3.5.0-1 + nla_get_flag@libnl_3 3.5.0-1 + nla_get_msecs@Base 3.5.0-1 + nla_get_msecs@libnl_3 3.5.0-1 + nla_get_s16@Base 3.5.0-1 + nla_get_s16@libnl_3_2_27 3.5.0-1 + nla_get_s32@Base 3.5.0-1 + nla_get_s32@libnl_3_2_27 3.5.0-1 + nla_get_s64@Base 3.5.0-1 + nla_get_s64@libnl_3_2_27 3.5.0-1 + nla_get_s8@Base 3.5.0-1 + nla_get_s8@libnl_3_2_27 3.5.0-1 + nla_get_string@Base 3.5.0-1 + nla_get_string@libnl_3 3.5.0-1 + nla_get_u16@Base 3.5.0-1 + nla_get_u16@libnl_3 3.5.0-1 + nla_get_u32@Base 3.5.0-1 + nla_get_u32@libnl_3 3.5.0-1 + nla_get_u64@Base 3.5.0-1 + nla_get_u64@libnl_3 3.5.0-1 + nla_get_u8@Base 3.5.0-1 + nla_get_u8@libnl_3 3.5.0-1 + nla_is_nested@Base 3.5.0-1 + nla_is_nested@libnl_3 3.5.0-1 + nla_len@Base 3.5.0-1 + nla_len@libnl_3 3.5.0-1 + nla_memcmp@Base 3.5.0-1 + nla_memcmp@libnl_3 3.5.0-1 + nla_memcpy@Base 3.5.0-1 + nla_memcpy@libnl_3 3.5.0-1 + nla_nest_cancel@Base 3.5.0-1 + nla_nest_cancel@libnl_3 3.5.0-1 + nla_nest_end@Base 3.5.0-1 + nla_nest_end@libnl_3 3.5.0-1 + nla_nest_end_keep_empty@libnl_3_5 3.5.0-1 + nla_nest_start@Base 3.5.0-1 + nla_nest_start@libnl_3 3.5.0-1 + nla_next@Base 3.5.0-1 + nla_next@libnl_3 3.5.0-1 + nla_ok@Base 3.5.0-1 + nla_ok@libnl_3 3.5.0-1 + nla_padlen@Base 3.5.0-1 + nla_padlen@libnl_3 3.5.0-1 + nla_parse@Base 3.5.0-1 + nla_parse@libnl_3 3.5.0-1 + nla_parse_nested@Base 3.5.0-1 + nla_parse_nested@libnl_3 3.5.0-1 + nla_put@Base 3.5.0-1 + nla_put@libnl_3 3.5.0-1 + nla_put_addr@Base 3.5.0-1 + nla_put_addr@libnl_3 3.5.0-1 + nla_put_data@Base 3.5.0-1 + nla_put_data@libnl_3 3.5.0-1 + nla_put_flag@Base 3.5.0-1 + nla_put_flag@libnl_3 3.5.0-1 + nla_put_msecs@Base 3.5.0-1 + nla_put_msecs@libnl_3 3.5.0-1 + nla_put_nested@Base 3.5.0-1 + nla_put_nested@libnl_3 3.5.0-1 + nla_put_s16@Base 3.5.0-1 + nla_put_s16@libnl_3_2_27 3.5.0-1 + nla_put_s32@Base 3.5.0-1 + nla_put_s32@libnl_3_2_27 3.5.0-1 + nla_put_s64@Base 3.5.0-1 + nla_put_s64@libnl_3_2_27 3.5.0-1 + nla_put_s8@Base 3.5.0-1 + nla_put_s8@libnl_3_2_27 3.5.0-1 + nla_put_string@Base 3.5.0-1 + nla_put_string@libnl_3 3.5.0-1 + nla_put_u16@Base 3.5.0-1 + nla_put_u16@libnl_3 3.5.0-1 + nla_put_u32@Base 3.5.0-1 + nla_put_u32@libnl_3 3.5.0-1 + nla_put_u64@Base 3.5.0-1 + nla_put_u64@libnl_3 3.5.0-1 + nla_put_u8@Base 3.5.0-1 + nla_put_u8@libnl_3 3.5.0-1 + nla_reserve@Base 3.5.0-1 + nla_reserve@libnl_3 3.5.0-1 + nla_strcmp@Base 3.5.0-1 + nla_strcmp@libnl_3 3.5.0-1 + nla_strdup@Base 3.5.0-1 + nla_strdup@libnl_3 3.5.0-1 + nla_strlcpy@Base 3.5.0-1 + nla_strlcpy@libnl_3 3.5.0-1 + nla_total_size@Base 3.5.0-1 + nla_total_size@libnl_3 3.5.0-1 + nla_type@Base 3.5.0-1 + nla_type@libnl_3 3.5.0-1 + nla_validate@Base 3.5.0-1 + nla_validate@libnl_3 3.5.0-1 + nlmsg_alloc@Base 3.5.0-1 + nlmsg_alloc@libnl_3 3.5.0-1 + nlmsg_alloc_simple@Base 3.5.0-1 + nlmsg_alloc_simple@libnl_3 3.5.0-1 + nlmsg_alloc_size@Base 3.5.0-1 + nlmsg_alloc_size@libnl_3 3.5.0-1 + nlmsg_append@Base 3.5.0-1 + nlmsg_append@libnl_3 3.5.0-1 + nlmsg_attrdata@Base 3.5.0-1 + nlmsg_attrdata@libnl_3 3.5.0-1 + nlmsg_attrlen@Base 3.5.0-1 + nlmsg_attrlen@libnl_3 3.5.0-1 + nlmsg_convert@Base 3.5.0-1 + nlmsg_convert@libnl_3 3.5.0-1 + nlmsg_data@Base 3.5.0-1 + nlmsg_data@libnl_3 3.5.0-1 + nlmsg_datalen@Base 3.5.0-1 + nlmsg_datalen@libnl_3 3.5.0-1 + nlmsg_expand@Base 3.5.0-1 + nlmsg_expand@libnl_3 3.5.0-1 + nlmsg_find_attr@Base 3.5.0-1 + nlmsg_find_attr@libnl_3 3.5.0-1 + nlmsg_free@Base 3.5.0-1 + nlmsg_free@libnl_3 3.5.0-1 + nlmsg_get@Base 3.5.0-1 + nlmsg_get@libnl_3 3.5.0-1 + nlmsg_get_creds@Base 3.5.0-1 + nlmsg_get_creds@libnl_3 3.5.0-1 + nlmsg_get_dst@Base 3.5.0-1 + nlmsg_get_dst@libnl_3 3.5.0-1 + nlmsg_get_max_size@Base 3.5.0-1 + nlmsg_get_max_size@libnl_3 3.5.0-1 + nlmsg_get_proto@Base 3.5.0-1 + nlmsg_get_proto@libnl_3 3.5.0-1 + nlmsg_get_src@Base 3.5.0-1 + nlmsg_get_src@libnl_3 3.5.0-1 + nlmsg_hdr@Base 3.5.0-1 + nlmsg_hdr@libnl_3 3.5.0-1 + nlmsg_inherit@Base 3.5.0-1 + nlmsg_inherit@libnl_3 3.5.0-1 + nlmsg_next@Base 3.5.0-1 + nlmsg_next@libnl_3 3.5.0-1 + nlmsg_ok@Base 3.5.0-1 + nlmsg_ok@libnl_3 3.5.0-1 + nlmsg_padlen@Base 3.5.0-1 + nlmsg_padlen@libnl_3 3.5.0-1 + nlmsg_parse@Base 3.5.0-1 + nlmsg_parse@libnl_3 3.5.0-1 + nlmsg_put@Base 3.5.0-1 + nlmsg_put@libnl_3 3.5.0-1 + nlmsg_reserve@Base 3.5.0-1 + nlmsg_reserve@libnl_3 3.5.0-1 + nlmsg_set_creds@Base 3.5.0-1 + nlmsg_set_creds@libnl_3 3.5.0-1 + nlmsg_set_default_size@Base 3.5.0-1 + nlmsg_set_default_size@libnl_3 3.5.0-1 + nlmsg_set_dst@Base 3.5.0-1 + nlmsg_set_dst@libnl_3 3.5.0-1 + nlmsg_set_proto@Base 3.5.0-1 + nlmsg_set_proto@libnl_3 3.5.0-1 + nlmsg_set_src@Base 3.5.0-1 + nlmsg_set_src@libnl_3 3.5.0-1 + nlmsg_size@Base 3.5.0-1 + nlmsg_size@libnl_3 3.5.0-1 + nlmsg_tail@Base 3.5.0-1 + nlmsg_tail@libnl_3 3.5.0-1 + nlmsg_total_size@Base 3.5.0-1 + nlmsg_total_size@libnl_3 3.5.0-1 + nlmsg_valid_hdr@Base 3.5.0-1 + nlmsg_valid_hdr@libnl_3 3.5.0-1 + nlmsg_validate@Base 3.5.0-1 + nlmsg_validate@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-3-dev.install b/src/libnl3/debian/libnl-3-dev.install new file mode 100755 index 000000000000..3715b8b22bbd --- /dev/null +++ b/src/libnl3/debian/libnl-3-dev.install @@ -0,0 +1,5 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/include/* +debian/tmp/usr/lib/*/pkgconfig/libnl-3* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3.so lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3.a lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-cli-3-200.install b/src/libnl3/debian/libnl-cli-3-200.install new file mode 100755 index 000000000000..6735ec9d14b1 --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-200.install @@ -0,0 +1,4 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-cli-3*.so.* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl/cli/cls/*.so usr/lib/${DEB_HOST_MULTIARCH}/libnl-3/cli/cls +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl/cli/qdisc/*.so usr/lib/${DEB_HOST_MULTIARCH}/libnl-3/cli/qdisc diff --git a/src/libnl3/debian/libnl-cli-3-200.symbols b/src/libnl3/debian/libnl-cli-3-200.symbols new file mode 100644 index 000000000000..2d21c139623c --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-200.symbols @@ -0,0 +1,226 @@ +basic.so libnl-cli-3-200 #MINVER# +bfifo.so libnl-cli-3-200 #MINVER# +blackhole.so libnl-cli-3-200 #MINVER# +cgroup.so libnl-cli-3-200 #MINVER# +fq_codel.so libnl-cli-3-200 #MINVER# +hfsc.so libnl-cli-3-200 #MINVER# +htb.so libnl-cli-3-200 #MINVER# +ingress.so libnl-cli-3-200 #MINVER# +libnl-cli-3.so.200 libnl-cli-3-200 #MINVER# + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + nl_cli_addr_alloc@Base 3.5.0-1 + nl_cli_addr_alloc@libnl_3 3.5.0-1 + nl_cli_addr_parse@Base 3.5.0-1 + nl_cli_addr_parse@libnl_3 3.5.0-1 + nl_cli_addr_parse_broadcast@Base 3.5.0-1 + nl_cli_addr_parse_broadcast@libnl_3 3.5.0-1 + nl_cli_addr_parse_dev@Base 3.5.0-1 + nl_cli_addr_parse_dev@libnl_3 3.5.0-1 + nl_cli_addr_parse_family@Base 3.5.0-1 + nl_cli_addr_parse_family@libnl_3 3.5.0-1 + nl_cli_addr_parse_label@Base 3.5.0-1 + nl_cli_addr_parse_label@libnl_3 3.5.0-1 + nl_cli_addr_parse_local@Base 3.5.0-1 + nl_cli_addr_parse_local@libnl_3 3.5.0-1 + nl_cli_addr_parse_peer@Base 3.5.0-1 + nl_cli_addr_parse_peer@libnl_3 3.5.0-1 + nl_cli_addr_parse_preferred@Base 3.5.0-1 + nl_cli_addr_parse_preferred@libnl_3 3.5.0-1 + nl_cli_addr_parse_scope@Base 3.5.0-1 + nl_cli_addr_parse_scope@libnl_3 3.5.0-1 + nl_cli_addr_parse_valid@Base 3.5.0-1 + nl_cli_addr_parse_valid@libnl_3 3.5.0-1 + nl_cli_alloc_cache@Base 3.5.0-1 + nl_cli_alloc_cache@libnl_3 3.5.0-1 + nl_cli_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + nl_cli_alloc_socket@Base 3.5.0-1 + nl_cli_alloc_socket@libnl_3 3.5.0-1 + nl_cli_class_alloc@Base 3.5.0-1 + nl_cli_class_alloc@libnl_3 3.5.0-1 + nl_cli_class_alloc_cache@Base 3.5.0-1 + nl_cli_class_alloc_cache@libnl_3 3.5.0-1 + nl_cli_cls_alloc@Base 3.5.0-1 + nl_cli_cls_alloc@libnl_3 3.5.0-1 + nl_cli_cls_alloc_cache@Base 3.5.0-1 + nl_cli_cls_alloc_cache@libnl_3 3.5.0-1 + nl_cli_cls_parse_ematch@Base 3.5.0-1 + nl_cli_cls_parse_ematch@libnl_3 3.5.0-1 + nl_cli_cls_parse_proto@Base 3.5.0-1 + nl_cli_cls_parse_proto@libnl_3 3.5.0-1 + nl_cli_confirm@Base 3.5.0-1 + nl_cli_confirm@libnl_3 3.5.0-1 + nl_cli_connect@Base 3.5.0-1 + nl_cli_connect@libnl_3 3.5.0-1 + nl_cli_ct_alloc@Base 3.5.0-1 + nl_cli_ct_alloc@libnl_3 3.5.0-1 + nl_cli_ct_alloc_cache@Base 3.5.0-1 + nl_cli_ct_alloc_cache@libnl_3 3.5.0-1 + nl_cli_ct_parse_dst@Base 3.5.0-1 + nl_cli_ct_parse_dst@libnl_3 3.5.0-1 + nl_cli_ct_parse_dst_port@Base 3.5.0-1 + nl_cli_ct_parse_dst_port@libnl_3 3.5.0-1 + nl_cli_ct_parse_family@Base 3.5.0-1 + nl_cli_ct_parse_family@libnl_3 3.5.0-1 + nl_cli_ct_parse_id@Base 3.5.0-1 + nl_cli_ct_parse_id@libnl_3 3.5.0-1 + nl_cli_ct_parse_mark@Base 3.5.0-1 + nl_cli_ct_parse_mark@libnl_3 3.5.0-1 + nl_cli_ct_parse_protocol@Base 3.5.0-1 + nl_cli_ct_parse_protocol@libnl_3 3.5.0-1 + nl_cli_ct_parse_src@Base 3.5.0-1 + nl_cli_ct_parse_src@libnl_3 3.5.0-1 + nl_cli_ct_parse_src_port@Base 3.5.0-1 + nl_cli_ct_parse_src_port@libnl_3 3.5.0-1 + nl_cli_ct_parse_status@Base 3.5.0-1 + nl_cli_ct_parse_status@libnl_3 3.5.0-1 + nl_cli_ct_parse_tcp_state@Base 3.5.0-1 + nl_cli_ct_parse_tcp_state@libnl_3 3.5.0-1 + nl_cli_ct_parse_timeout@Base 3.5.0-1 + nl_cli_ct_parse_timeout@libnl_3 3.5.0-1 + nl_cli_ct_parse_use@Base 3.5.0-1 + nl_cli_ct_parse_use@libnl_3 3.5.0-1 + nl_cli_ct_parse_zone@Base 3.5.0-1 + nl_cli_ct_parse_zone@libnl_3 3.5.0-1 + nl_cli_exp_alloc@Base 3.5.0-1 + nl_cli_exp_alloc@libnl_3 3.5.0-1 + nl_cli_exp_alloc_cache@Base 3.5.0-1 + nl_cli_exp_alloc_cache@libnl_3 3.5.0-1 + nl_cli_exp_parse_class@Base 3.5.0-1 + nl_cli_exp_parse_class@libnl_3 3.5.0-1 + nl_cli_exp_parse_dst@Base 3.5.0-1 + nl_cli_exp_parse_dst@libnl_3 3.5.0-1 + nl_cli_exp_parse_dst_port@Base 3.5.0-1 + nl_cli_exp_parse_dst_port@libnl_3 3.5.0-1 + nl_cli_exp_parse_family@Base 3.5.0-1 + nl_cli_exp_parse_family@libnl_3 3.5.0-1 + nl_cli_exp_parse_flags@Base 3.5.0-1 + nl_cli_exp_parse_flags@libnl_3 3.5.0-1 + nl_cli_exp_parse_fn@Base 3.5.0-1 + nl_cli_exp_parse_fn@libnl_3 3.5.0-1 + nl_cli_exp_parse_helper_name@Base 3.5.0-1 + nl_cli_exp_parse_helper_name@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_code@Base 3.5.0-1 + nl_cli_exp_parse_icmp_code@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_id@Base 3.5.0-1 + nl_cli_exp_parse_icmp_id@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_type@Base 3.5.0-1 + nl_cli_exp_parse_icmp_type@libnl_3 3.5.0-1 + nl_cli_exp_parse_id@Base 3.5.0-1 + nl_cli_exp_parse_id@libnl_3 3.5.0-1 + nl_cli_exp_parse_l4protonum@Base 3.5.0-1 + nl_cli_exp_parse_l4protonum@libnl_3 3.5.0-1 + nl_cli_exp_parse_nat_dir@Base 3.5.0-1 + nl_cli_exp_parse_nat_dir@libnl_3 3.5.0-1 + nl_cli_exp_parse_src@Base 3.5.0-1 + nl_cli_exp_parse_src@libnl_3 3.5.0-1 + nl_cli_exp_parse_src_port@Base 3.5.0-1 + nl_cli_exp_parse_src_port@libnl_3 3.5.0-1 + nl_cli_exp_parse_timeout@Base 3.5.0-1 + nl_cli_exp_parse_timeout@libnl_3 3.5.0-1 + nl_cli_exp_parse_zone@Base 3.5.0-1 + nl_cli_exp_parse_zone@libnl_3 3.5.0-1 + nl_cli_fatal@Base 3.5.0-1 + nl_cli_fatal@libnl_3 3.5.0-1 + nl_cli_link_alloc@Base 3.5.0-1 + nl_cli_link_alloc@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache@Base 3.5.0-1 + nl_cli_link_alloc_cache@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache_family@Base 3.5.0-1 + nl_cli_link_alloc_cache_family@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache_family_flags@libnl_3_2_28 3.5.0-1 + nl_cli_link_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + nl_cli_link_parse_family@Base 3.5.0-1 + nl_cli_link_parse_family@libnl_3 3.5.0-1 + nl_cli_link_parse_ifalias@Base 3.5.0-1 + nl_cli_link_parse_ifalias@libnl_3 3.5.0-1 + nl_cli_link_parse_ifindex@Base 3.5.0-1 + nl_cli_link_parse_ifindex@libnl_3 3.5.0-1 + nl_cli_link_parse_mtu@Base 3.5.0-1 + nl_cli_link_parse_mtu@libnl_3 3.5.0-1 + nl_cli_link_parse_name@Base 3.5.0-1 + nl_cli_link_parse_name@libnl_3 3.5.0-1 + nl_cli_link_parse_txqlen@Base 3.5.0-1 + nl_cli_link_parse_txqlen@libnl_3 3.5.0-1 + nl_cli_link_parse_weight@Base 3.5.0-1 + nl_cli_link_parse_weight@libnl_3 3.5.0-1 + nl_cli_load_module@Base 3.5.0-1 + nl_cli_load_module@libnl_3 3.5.0-1 + nl_cli_neigh_alloc@Base 3.5.0-1 + nl_cli_neigh_alloc@libnl_3 3.5.0-1 + nl_cli_neigh_parse_dev@Base 3.5.0-1 + nl_cli_neigh_parse_dev@libnl_3 3.5.0-1 + nl_cli_neigh_parse_dst@Base 3.5.0-1 + nl_cli_neigh_parse_dst@libnl_3 3.5.0-1 + nl_cli_neigh_parse_family@Base 3.5.0-1 + nl_cli_neigh_parse_family@libnl_3 3.5.0-1 + nl_cli_neigh_parse_lladdr@Base 3.5.0-1 + nl_cli_neigh_parse_lladdr@libnl_3 3.5.0-1 + nl_cli_neigh_parse_state@Base 3.5.0-1 + nl_cli_neigh_parse_state@libnl_3 3.5.0-1 + nl_cli_parse_dumptype@Base 3.5.0-1 + nl_cli_parse_dumptype@libnl_3 3.5.0-1 + nl_cli_parse_u32@Base 3.5.0-1 + nl_cli_parse_u32@libnl_3 3.5.0-1 + nl_cli_print_version@Base 3.5.0-1 + nl_cli_print_version@libnl_3 3.5.0-1 + nl_cli_qdisc_alloc@Base 3.5.0-1 + nl_cli_qdisc_alloc@libnl_3 3.5.0-1 + nl_cli_route_alloc@Base 3.5.0-1 + nl_cli_route_alloc@libnl_3 3.5.0-1 + nl_cli_route_alloc_cache@Base 3.5.0-1 + nl_cli_route_alloc_cache@libnl_3 3.5.0-1 + nl_cli_route_parse_dst@Base 3.5.0-1 + nl_cli_route_parse_dst@libnl_3 3.5.0-1 + nl_cli_route_parse_family@Base 3.5.0-1 + nl_cli_route_parse_family@libnl_3 3.5.0-1 + nl_cli_route_parse_iif@Base 3.5.0-1 + nl_cli_route_parse_iif@libnl_3 3.5.0-1 + nl_cli_route_parse_metric@Base 3.5.0-1 + nl_cli_route_parse_metric@libnl_3 3.5.0-1 + nl_cli_route_parse_nexthop@Base 3.5.0-1 + nl_cli_route_parse_nexthop@libnl_3 3.5.0-1 + nl_cli_route_parse_pref_src@Base 3.5.0-1 + nl_cli_route_parse_pref_src@libnl_3 3.5.0-1 + nl_cli_route_parse_prio@Base 3.5.0-1 + nl_cli_route_parse_prio@libnl_3 3.5.0-1 + nl_cli_route_parse_protocol@Base 3.5.0-1 + nl_cli_route_parse_protocol@libnl_3 3.5.0-1 + nl_cli_route_parse_scope@Base 3.5.0-1 + nl_cli_route_parse_scope@libnl_3 3.5.0-1 + nl_cli_route_parse_src@Base 3.5.0-1 + nl_cli_route_parse_src@libnl_3 3.5.0-1 + nl_cli_route_parse_table@Base 3.5.0-1 + nl_cli_route_parse_table@libnl_3 3.5.0-1 + nl_cli_route_parse_type@Base 3.5.0-1 + nl_cli_route_parse_type@libnl_3 3.5.0-1 + nl_cli_rule_alloc@Base 3.5.0-1 + nl_cli_rule_alloc@libnl_3 3.5.0-1 + nl_cli_rule_alloc_cache@Base 3.5.0-1 + nl_cli_rule_alloc_cache@libnl_3 3.5.0-1 + nl_cli_rule_parse_family@Base 3.5.0-1 + nl_cli_rule_parse_family@libnl_3 3.5.0-1 + nl_cli_tc_lookup@Base 3.5.0-1 + nl_cli_tc_lookup@libnl_3 3.5.0-1 + nl_cli_tc_parse_dev@Base 3.5.0-1 + nl_cli_tc_parse_dev@libnl_3 3.5.0-1 + nl_cli_tc_parse_handle@Base 3.5.0-1 + nl_cli_tc_parse_handle@libnl_3 3.5.0-1 + nl_cli_tc_parse_kind@Base 3.5.0-1 + nl_cli_tc_parse_kind@libnl_3 3.5.0-1 + nl_cli_tc_parse_linktype@Base 3.5.0-1 + nl_cli_tc_parse_linktype@libnl_3 3.5.0-1 + nl_cli_tc_parse_mpu@Base 3.5.0-1 + nl_cli_tc_parse_mpu@libnl_3 3.5.0-1 + nl_cli_tc_parse_mtu@Base 3.5.0-1 + nl_cli_tc_parse_mtu@libnl_3 3.5.0-1 + nl_cli_tc_parse_overhead@Base 3.5.0-1 + nl_cli_tc_parse_overhead@libnl_3 3.5.0-1 + nl_cli_tc_parse_parent@Base 3.5.0-1 + nl_cli_tc_parse_parent@libnl_3 3.5.0-1 + nl_cli_tc_register@Base 3.5.0-1 + nl_cli_tc_register@libnl_3 3.5.0-1 + nl_cli_tc_unregister@Base 3.5.0-1 + nl_cli_tc_unregister@libnl_3 3.5.0-1 +pfifo.so libnl-cli-3-200 #MINVER# +plug.so libnl-cli-3-200 #MINVER# diff --git a/src/libnl3/debian/libnl-cli-3-dev.install b/src/libnl3/debian/libnl-cli-3-dev.install new file mode 100644 index 000000000000..66aa3b3d9457 --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-cli-3* +debian/tmp/usr/lib/*/libnl-cli-3*.so +debian/tmp/usr/lib/*/libnl-cli-3*.a diff --git a/src/libnl3/debian/libnl-genl-3-200-udeb.install b/src/libnl3/debian/libnl-genl-3-200-udeb.install new file mode 100755 index 000000000000..cb5597bf74da --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200-udeb.install @@ -0,0 +1,2 @@ +#!/usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3.so.* lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-genl-3-200.install b/src/libnl3/debian/libnl-genl-3-200.install new file mode 100755 index 000000000000..d9d6fae40b21 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200.install @@ -0,0 +1,2 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.so.* lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-genl-3-200.symbols b/src/libnl3/debian/libnl-genl-3-200.symbols new file mode 100644 index 000000000000..0eb2e3be4460 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200.symbols @@ -0,0 +1,88 @@ +libnl-genl-3.so.200 libnl-genl-3-200 #MINVER# + genl_connect@Base 3.5.0-1 + genl_connect@libnl_3 3.5.0-1 + genl_ctrl_alloc_cache@Base 3.5.0-1 + genl_ctrl_alloc_cache@libnl_3 3.5.0-1 + genl_ctrl_resolve@Base 3.5.0-1 + genl_ctrl_resolve@libnl_3 3.5.0-1 + genl_ctrl_resolve_grp@Base 3.5.0-1 + genl_ctrl_resolve_grp@libnl_3 3.5.0-1 + genl_ctrl_search@Base 3.5.0-1 + genl_ctrl_search@libnl_3 3.5.0-1 + genl_ctrl_search_by_name@Base 3.5.0-1 + genl_ctrl_search_by_name@libnl_3 3.5.0-1 + genl_family_add_grp@Base 3.5.0-1 + genl_family_add_grp@libnl_3 3.5.0-1 + genl_family_add_op@Base 3.5.0-1 + genl_family_add_op@libnl_3 3.5.0-1 + genl_family_alloc@Base 3.5.0-1 + genl_family_alloc@libnl_3 3.5.0-1 + genl_family_get_hdrsize@Base 3.5.0-1 + genl_family_get_hdrsize@libnl_3 3.5.0-1 + genl_family_get_id@Base 3.5.0-1 + genl_family_get_id@libnl_3 3.5.0-1 + genl_family_get_maxattr@Base 3.5.0-1 + genl_family_get_maxattr@libnl_3 3.5.0-1 + genl_family_get_name@Base 3.5.0-1 + genl_family_get_name@libnl_3 3.5.0-1 + genl_family_get_version@Base 3.5.0-1 + genl_family_get_version@libnl_3 3.5.0-1 + genl_family_ops@Base 3.5.0-1 + genl_family_ops@libnl_3 3.5.0-1 + genl_family_put@Base 3.5.0-1 + genl_family_put@libnl_3 3.5.0-1 + genl_family_set_hdrsize@Base 3.5.0-1 + genl_family_set_hdrsize@libnl_3 3.5.0-1 + genl_family_set_id@Base 3.5.0-1 + genl_family_set_id@libnl_3 3.5.0-1 + genl_family_set_maxattr@Base 3.5.0-1 + genl_family_set_maxattr@libnl_3 3.5.0-1 + genl_family_set_name@Base 3.5.0-1 + genl_family_set_name@libnl_3 3.5.0-1 + genl_family_set_version@Base 3.5.0-1 + genl_family_set_version@libnl_3 3.5.0-1 + genl_handle_msg@Base 3.5.0-1 + genl_handle_msg@libnl_3 3.5.0-1 + genl_mngt_resolve@Base 3.5.0-1 + genl_mngt_resolve@libnl_3 3.5.0-1 + genl_op2name@Base 3.5.0-1 + genl_op2name@libnl_3 3.5.0-1 + genl_ops_resolve@Base 3.5.0-1 + genl_ops_resolve@libnl_3 3.5.0-1 + genl_register@Base 3.5.0-1 + genl_register@libnl_3 3.5.0-1 + genl_register_family@Base 3.5.0-1 + genl_register_family@libnl_3 3.5.0-1 + genl_resolve_id@Base 3.5.0-1 + genl_resolve_id@libnl_3 3.5.0-1 + genl_send_simple@Base 3.5.0-1 + genl_send_simple@libnl_3 3.5.0-1 + genl_unregister@Base 3.5.0-1 + genl_unregister@libnl_3 3.5.0-1 + genl_unregister_family@Base 3.5.0-1 + genl_unregister_family@libnl_3 3.5.0-1 + genlmsg_attrdata@Base 3.5.0-1 + genlmsg_attrdata@libnl_3 3.5.0-1 + genlmsg_attrlen@Base 3.5.0-1 + genlmsg_attrlen@libnl_3 3.5.0-1 + genlmsg_data@Base 3.5.0-1 + genlmsg_data@libnl_3 3.5.0-1 + genlmsg_hdr@Base 3.5.0-1 + genlmsg_hdr@libnl_3 3.5.0-1 + genlmsg_len@Base 3.5.0-1 + genlmsg_len@libnl_3 3.5.0-1 + genlmsg_parse@Base 3.5.0-1 + genlmsg_parse@libnl_3 3.5.0-1 + genlmsg_put@Base 3.5.0-1 + genlmsg_put@libnl_3 3.5.0-1 + genlmsg_user_data@Base 3.5.0-1 + genlmsg_user_data@libnl_3 3.5.0-1 + genlmsg_user_datalen@Base 3.5.0-1 + genlmsg_user_datalen@libnl_3 3.5.0-1 + genlmsg_user_hdr@Base 3.5.0-1 + genlmsg_user_hdr@libnl_3 3.5.0-1 + genlmsg_valid_hdr@Base 3.5.0-1 + genlmsg_valid_hdr@libnl_3 3.5.0-1 + genlmsg_validate@Base 3.5.0-1 + genlmsg_validate@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-genl-3-dev.install b/src/libnl3/debian/libnl-genl-3-dev.install new file mode 100755 index 000000000000..cbc6b51ef474 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-dev.install @@ -0,0 +1,4 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/*/pkgconfig/libnl-genl-3* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.so lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.a lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-idiag-3-200.install b/src/libnl3/debian/libnl-idiag-3-200.install new file mode 100644 index 000000000000..f6d6b8064e5f --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-idiag-3*.so.* diff --git a/src/libnl3/debian/libnl-idiag-3-200.symbols b/src/libnl3/debian/libnl-idiag-3-200.symbols new file mode 100644 index 000000000000..13cf27c7c8ac --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-200.symbols @@ -0,0 +1,206 @@ +libnl-idiag-3.so.200 libnl-idiag-3-200 #MINVER# + idiagnl_attrs2str@Base 3.5.0-1 + idiagnl_attrs2str@libnl_3 3.5.0-1 + idiagnl_connect@Base 3.5.0-1 + idiagnl_connect@libnl_3 3.5.0-1 + idiagnl_exts2str@Base 3.5.0-1 + idiagnl_exts2str@libnl_3 3.5.0-1 + idiagnl_meminfo_alloc@Base 3.5.0-1 + idiagnl_meminfo_alloc@libnl_3 3.5.0-1 + idiagnl_meminfo_get@Base 3.5.0-1 + idiagnl_meminfo_get@libnl_3 3.5.0-1 + idiagnl_meminfo_get_fmem@Base 3.5.0-1 + idiagnl_meminfo_get_fmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_rmem@Base 3.5.0-1 + idiagnl_meminfo_get_rmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_tmem@Base 3.5.0-1 + idiagnl_meminfo_get_tmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_wmem@Base 3.5.0-1 + idiagnl_meminfo_get_wmem@libnl_3 3.5.0-1 + idiagnl_meminfo_obj_ops@Base 3.5.0-1 + idiagnl_meminfo_obj_ops@libnl_3 3.5.0-1 + idiagnl_meminfo_put@Base 3.5.0-1 + idiagnl_meminfo_put@libnl_3 3.5.0-1 + idiagnl_meminfo_set_fmem@Base 3.5.0-1 + idiagnl_meminfo_set_fmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_rmem@Base 3.5.0-1 + idiagnl_meminfo_set_rmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_tmem@Base 3.5.0-1 + idiagnl_meminfo_set_tmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_wmem@Base 3.5.0-1 + idiagnl_meminfo_set_wmem@libnl_3 3.5.0-1 + idiagnl_msg_alloc@Base 3.5.0-1 + idiagnl_msg_alloc@libnl_3 3.5.0-1 + idiagnl_msg_alloc_cache@Base 3.5.0-1 + idiagnl_msg_alloc_cache@libnl_3 3.5.0-1 + idiagnl_msg_get@Base 3.5.0-1 + idiagnl_msg_get@libnl_3 3.5.0-1 + idiagnl_msg_get_cong@Base 3.5.0-1 + idiagnl_msg_get_cong@libnl_3 3.5.0-1 + idiagnl_msg_get_dport@Base 3.5.0-1 + idiagnl_msg_get_dport@libnl_3 3.5.0-1 + idiagnl_msg_get_dst@Base 3.5.0-1 + idiagnl_msg_get_dst@libnl_3 3.5.0-1 + idiagnl_msg_get_expires@Base 3.5.0-1 + idiagnl_msg_get_expires@libnl_3 3.5.0-1 + idiagnl_msg_get_family@Base 3.5.0-1 + idiagnl_msg_get_family@libnl_3 3.5.0-1 + idiagnl_msg_get_ifindex@Base 3.5.0-1 + idiagnl_msg_get_ifindex@libnl_3 3.5.0-1 + idiagnl_msg_get_inode@Base 3.5.0-1 + idiagnl_msg_get_inode@libnl_3 3.5.0-1 + idiagnl_msg_get_meminfo@Base 3.5.0-1 + idiagnl_msg_get_meminfo@libnl_3 3.5.0-1 + idiagnl_msg_get_retrans@Base 3.5.0-1 + idiagnl_msg_get_retrans@libnl_3 3.5.0-1 + idiagnl_msg_get_rqueue@Base 3.5.0-1 + idiagnl_msg_get_rqueue@libnl_3 3.5.0-1 + idiagnl_msg_get_shutdown@Base 3.5.0-1 + idiagnl_msg_get_shutdown@libnl_3 3.5.0-1 + idiagnl_msg_get_sport@Base 3.5.0-1 + idiagnl_msg_get_sport@libnl_3 3.5.0-1 + idiagnl_msg_get_src@Base 3.5.0-1 + idiagnl_msg_get_src@libnl_3 3.5.0-1 + idiagnl_msg_get_state@Base 3.5.0-1 + idiagnl_msg_get_state@libnl_3 3.5.0-1 + idiagnl_msg_get_tclass@Base 3.5.0-1 + idiagnl_msg_get_tclass@libnl_3 3.5.0-1 + idiagnl_msg_get_tcpinfo@Base 3.5.0-1 + idiagnl_msg_get_tcpinfo@libnl_3 3.5.0-1 + idiagnl_msg_get_timer@Base 3.5.0-1 + idiagnl_msg_get_timer@libnl_3 3.5.0-1 + idiagnl_msg_get_tos@Base 3.5.0-1 + idiagnl_msg_get_tos@libnl_3 3.5.0-1 + idiagnl_msg_get_uid@Base 3.5.0-1 + idiagnl_msg_get_uid@libnl_3 3.5.0-1 + idiagnl_msg_get_vegasinfo@Base 3.5.0-1 + idiagnl_msg_get_vegasinfo@libnl_3 3.5.0-1 + idiagnl_msg_get_wqueue@Base 3.5.0-1 + idiagnl_msg_get_wqueue@libnl_3 3.5.0-1 + idiagnl_msg_obj_ops@Base 3.5.0-1 + idiagnl_msg_obj_ops@libnl_3 3.5.0-1 + idiagnl_msg_parse@Base 3.5.0-1 + idiagnl_msg_parse@libnl_3 3.5.0-1 + idiagnl_msg_put@Base 3.5.0-1 + idiagnl_msg_put@libnl_3 3.5.0-1 + idiagnl_msg_set_cong@Base 3.5.0-1 + idiagnl_msg_set_cong@libnl_3 3.5.0-1 + idiagnl_msg_set_dport@Base 3.5.0-1 + idiagnl_msg_set_dport@libnl_3 3.5.0-1 + idiagnl_msg_set_dst@Base 3.5.0-1 + idiagnl_msg_set_dst@libnl_3 3.5.0-1 + idiagnl_msg_set_expires@Base 3.5.0-1 + idiagnl_msg_set_expires@libnl_3 3.5.0-1 + idiagnl_msg_set_family@Base 3.5.0-1 + idiagnl_msg_set_family@libnl_3 3.5.0-1 + idiagnl_msg_set_ifindex@Base 3.5.0-1 + idiagnl_msg_set_ifindex@libnl_3 3.5.0-1 + idiagnl_msg_set_inode@Base 3.5.0-1 + idiagnl_msg_set_inode@libnl_3 3.5.0-1 + idiagnl_msg_set_meminfo@Base 3.5.0-1 + idiagnl_msg_set_meminfo@libnl_3 3.5.0-1 + idiagnl_msg_set_retrans@Base 3.5.0-1 + idiagnl_msg_set_retrans@libnl_3 3.5.0-1 + idiagnl_msg_set_rqueue@Base 3.5.0-1 + idiagnl_msg_set_rqueue@libnl_3 3.5.0-1 + idiagnl_msg_set_shutdown@Base 3.5.0-1 + idiagnl_msg_set_shutdown@libnl_3 3.5.0-1 + idiagnl_msg_set_sport@Base 3.5.0-1 + idiagnl_msg_set_sport@libnl_3 3.5.0-1 + idiagnl_msg_set_src@Base 3.5.0-1 + idiagnl_msg_set_src@libnl_3 3.5.0-1 + idiagnl_msg_set_state@Base 3.5.0-1 + idiagnl_msg_set_state@libnl_3 3.5.0-1 + idiagnl_msg_set_tclass@Base 3.5.0-1 + idiagnl_msg_set_tclass@libnl_3 3.5.0-1 + idiagnl_msg_set_tcpinfo@Base 3.5.0-1 + idiagnl_msg_set_tcpinfo@libnl_3 3.5.0-1 + idiagnl_msg_set_timer@Base 3.5.0-1 + idiagnl_msg_set_timer@libnl_3 3.5.0-1 + idiagnl_msg_set_tos@Base 3.5.0-1 + idiagnl_msg_set_tos@libnl_3 3.5.0-1 + idiagnl_msg_set_uid@Base 3.5.0-1 + idiagnl_msg_set_uid@libnl_3 3.5.0-1 + idiagnl_msg_set_vegasinfo@Base 3.5.0-1 + idiagnl_msg_set_vegasinfo@libnl_3 3.5.0-1 + idiagnl_msg_set_wqueue@Base 3.5.0-1 + idiagnl_msg_set_wqueue@libnl_3 3.5.0-1 + idiagnl_req_alloc@Base 3.5.0-1 + idiagnl_req_alloc@libnl_3 3.5.0-1 + idiagnl_req_get@Base 3.5.0-1 + idiagnl_req_get@libnl_3 3.5.0-1 + idiagnl_req_get_dbs@Base 3.5.0-1 + idiagnl_req_get_dbs@libnl_3 3.5.0-1 + idiagnl_req_get_dst@Base 3.5.0-1 + idiagnl_req_get_dst@libnl_3 3.5.0-1 + idiagnl_req_get_ext@Base 3.5.0-1 + idiagnl_req_get_ext@libnl_3 3.5.0-1 + idiagnl_req_get_family@Base 3.5.0-1 + idiagnl_req_get_family@libnl_3 3.5.0-1 + idiagnl_req_get_ifindex@Base 3.5.0-1 + idiagnl_req_get_ifindex@libnl_3 3.5.0-1 + idiagnl_req_get_src@Base 3.5.0-1 + idiagnl_req_get_src@libnl_3 3.5.0-1 + idiagnl_req_get_states@Base 3.5.0-1 + idiagnl_req_get_states@libnl_3 3.5.0-1 + idiagnl_req_obj_ops@Base 3.5.0-1 + idiagnl_req_obj_ops@libnl_3 3.5.0-1 + idiagnl_req_parse@Base 3.5.0-1 + idiagnl_req_parse@libnl_3 3.5.0-1 + idiagnl_req_put@Base 3.5.0-1 + idiagnl_req_put@libnl_3 3.5.0-1 + idiagnl_req_set_dbs@Base 3.5.0-1 + idiagnl_req_set_dbs@libnl_3 3.5.0-1 + idiagnl_req_set_dst@Base 3.5.0-1 + idiagnl_req_set_dst@libnl_3 3.5.0-1 + idiagnl_req_set_ext@Base 3.5.0-1 + idiagnl_req_set_ext@libnl_3 3.5.0-1 + idiagnl_req_set_family@Base 3.5.0-1 + idiagnl_req_set_family@libnl_3 3.5.0-1 + idiagnl_req_set_ifindex@Base 3.5.0-1 + idiagnl_req_set_ifindex@libnl_3 3.5.0-1 + idiagnl_req_set_src@Base 3.5.0-1 + idiagnl_req_set_src@libnl_3 3.5.0-1 + idiagnl_req_set_states@Base 3.5.0-1 + idiagnl_req_set_states@libnl_3 3.5.0-1 + idiagnl_send_simple@Base 3.5.0-1 + idiagnl_send_simple@libnl_3 3.5.0-1 + idiagnl_shutdown2str@Base 3.5.0-1 + idiagnl_shutdown2str@libnl_3 3.5.0-1 + idiagnl_state2str@Base 3.5.0-1 + idiagnl_state2str@libnl_3 3.5.0-1 + idiagnl_str2state@Base 3.5.0-1 + idiagnl_str2state@libnl_3 3.5.0-1 + idiagnl_str2timer@Base 3.5.0-1 + idiagnl_str2timer@libnl_3 3.5.0-1 + idiagnl_tcpopts2str@Base 3.5.0-1 + idiagnl_tcpopts2str@libnl_3 3.5.0-1 + idiagnl_tcpstate2str@Base 3.5.0-1 + idiagnl_tcpstate2str@libnl_3 3.5.0-1 + idiagnl_timer2str@Base 3.5.0-1 + idiagnl_timer2str@libnl_3 3.5.0-1 + idiagnl_vegasinfo_alloc@Base 3.5.0-1 + idiagnl_vegasinfo_alloc@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get@Base 3.5.0-1 + idiagnl_vegasinfo_get@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_enabled@Base 3.5.0-1 + idiagnl_vegasinfo_get_enabled@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_minrtt@Base 3.5.0-1 + idiagnl_vegasinfo_get_minrtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_rtt@Base 3.5.0-1 + idiagnl_vegasinfo_get_rtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_rttcnt@Base 3.5.0-1 + idiagnl_vegasinfo_get_rttcnt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_obj_ops@Base 3.5.0-1 + idiagnl_vegasinfo_obj_ops@libnl_3 3.5.0-1 + idiagnl_vegasinfo_put@Base 3.5.0-1 + idiagnl_vegasinfo_put@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_enabled@Base 3.5.0-1 + idiagnl_vegasinfo_set_enabled@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_minrtt@Base 3.5.0-1 + idiagnl_vegasinfo_set_minrtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_rtt@Base 3.5.0-1 + idiagnl_vegasinfo_set_rtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_rttcnt@Base 3.5.0-1 + idiagnl_vegasinfo_set_rttcnt@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-idiag-3-dev.install b/src/libnl3/debian/libnl-idiag-3-dev.install new file mode 100644 index 000000000000..6f19a6e83d61 --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-idiag-3* +debian/tmp/usr/lib/*/libnl-idiag-3*.so +debian/tmp/usr/lib/*/libnl-idiag-3*.a diff --git a/src/libnl3/debian/libnl-nf-3-200.install b/src/libnl3/debian/libnl-nf-3-200.install new file mode 100644 index 000000000000..6d65611ed34e --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-nf-3*.so.* diff --git a/src/libnl3/debian/libnl-nf-3-200.symbols b/src/libnl3/debian/libnl-nf-3-200.symbols new file mode 100644 index 000000000000..2ce4d2ad0ffc --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-200.symbols @@ -0,0 +1,620 @@ +libnl-nf-3.so.200 libnl-nf-3-200 #MINVER# + ct_obj_ops@Base 3.5.0-1 + ct_obj_ops@libnl_3 3.5.0-1 + exp_obj_ops@Base 3.5.0-1 + exp_obj_ops@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + log_msg_obj_ops@Base 3.5.0-1 + log_msg_obj_ops@libnl_3 3.5.0-1 + log_obj_ops@Base 3.5.0-1 + log_obj_ops@libnl_3 3.5.0-1 + nfnl_connect@Base 3.5.0-1 + nfnl_connect@libnl_3 3.5.0-1 + nfnl_ct_add@Base 3.5.0-1 + nfnl_ct_add@libnl_3 3.5.0-1 + nfnl_ct_alloc@Base 3.5.0-1 + nfnl_ct_alloc@libnl_3 3.5.0-1 + nfnl_ct_alloc_cache@Base 3.5.0-1 + nfnl_ct_alloc_cache@libnl_3 3.5.0-1 + nfnl_ct_build_add_request@Base 3.5.0-1 + nfnl_ct_build_add_request@libnl_3 3.5.0-1 + nfnl_ct_build_delete_request@Base 3.5.0-1 + nfnl_ct_build_delete_request@libnl_3 3.5.0-1 + nfnl_ct_build_query_request@Base 3.5.0-1 + nfnl_ct_build_query_request@libnl_3 3.5.0-1 + nfnl_ct_del@Base 3.5.0-1 + nfnl_ct_del@libnl_3 3.5.0-1 + nfnl_ct_dump_request@Base 3.5.0-1 + nfnl_ct_dump_request@libnl_3 3.5.0-1 + nfnl_ct_get@Base 3.5.0-1 + nfnl_ct_get@libnl_3 3.5.0-1 + nfnl_ct_get_bytes@Base 3.5.0-1 + nfnl_ct_get_bytes@libnl_3 3.5.0-1 + nfnl_ct_get_dst@Base 3.5.0-1 + nfnl_ct_get_dst@libnl_3 3.5.0-1 + nfnl_ct_get_dst_port@Base 3.5.0-1 + nfnl_ct_get_dst_port@libnl_3 3.5.0-1 + nfnl_ct_get_family@Base 3.5.0-1 + nfnl_ct_get_family@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_code@Base 3.5.0-1 + nfnl_ct_get_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_id@Base 3.5.0-1 + nfnl_ct_get_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_type@Base 3.5.0-1 + nfnl_ct_get_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_get_id@Base 3.5.0-1 + nfnl_ct_get_id@libnl_3 3.5.0-1 + nfnl_ct_get_mark@Base 3.5.0-1 + nfnl_ct_get_mark@libnl_3 3.5.0-1 + nfnl_ct_get_packets@Base 3.5.0-1 + nfnl_ct_get_packets@libnl_3 3.5.0-1 + nfnl_ct_get_proto@Base 3.5.0-1 + nfnl_ct_get_proto@libnl_3 3.5.0-1 + nfnl_ct_get_src@Base 3.5.0-1 + nfnl_ct_get_src@libnl_3 3.5.0-1 + nfnl_ct_get_src_port@Base 3.5.0-1 + nfnl_ct_get_src_port@libnl_3 3.5.0-1 + nfnl_ct_get_status@Base 3.5.0-1 + nfnl_ct_get_status@libnl_3 3.5.0-1 + nfnl_ct_get_tcp_state@Base 3.5.0-1 + nfnl_ct_get_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_get_timeout@Base 3.5.0-1 + nfnl_ct_get_timeout@libnl_3 3.5.0-1 + nfnl_ct_get_timestamp@Base 3.5.0-1 + nfnl_ct_get_timestamp@libnl_3 3.5.0-1 + nfnl_ct_get_use@Base 3.5.0-1 + nfnl_ct_get_use@libnl_3 3.5.0-1 + nfnl_ct_get_zone@Base 3.5.0-1 + nfnl_ct_get_zone@libnl_3 3.5.0-1 + nfnl_ct_put@Base 3.5.0-1 + nfnl_ct_put@libnl_3 3.5.0-1 + nfnl_ct_query@Base 3.5.0-1 + nfnl_ct_query@libnl_3 3.5.0-1 + nfnl_ct_set_bytes@Base 3.5.0-1 + nfnl_ct_set_bytes@libnl_3 3.5.0-1 + nfnl_ct_set_dst@Base 3.5.0-1 + nfnl_ct_set_dst@libnl_3 3.5.0-1 + nfnl_ct_set_dst_port@Base 3.5.0-1 + nfnl_ct_set_dst_port@libnl_3 3.5.0-1 + nfnl_ct_set_family@Base 3.5.0-1 + nfnl_ct_set_family@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_code@Base 3.5.0-1 + nfnl_ct_set_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_id@Base 3.5.0-1 + nfnl_ct_set_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_type@Base 3.5.0-1 + nfnl_ct_set_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_set_id@Base 3.5.0-1 + nfnl_ct_set_id@libnl_3 3.5.0-1 + nfnl_ct_set_mark@Base 3.5.0-1 + nfnl_ct_set_mark@libnl_3 3.5.0-1 + nfnl_ct_set_packets@Base 3.5.0-1 + nfnl_ct_set_packets@libnl_3 3.5.0-1 + nfnl_ct_set_proto@Base 3.5.0-1 + nfnl_ct_set_proto@libnl_3 3.5.0-1 + nfnl_ct_set_src@Base 3.5.0-1 + nfnl_ct_set_src@libnl_3 3.5.0-1 + nfnl_ct_set_src_port@Base 3.5.0-1 + nfnl_ct_set_src_port@libnl_3 3.5.0-1 + nfnl_ct_set_status@Base 3.5.0-1 + nfnl_ct_set_status@libnl_3 3.5.0-1 + nfnl_ct_set_tcp_state@Base 3.5.0-1 + nfnl_ct_set_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_set_timeout@Base 3.5.0-1 + nfnl_ct_set_timeout@libnl_3 3.5.0-1 + nfnl_ct_set_timestamp@Base 3.5.0-1 + nfnl_ct_set_timestamp@libnl_3 3.5.0-1 + nfnl_ct_set_use@Base 3.5.0-1 + nfnl_ct_set_use@libnl_3 3.5.0-1 + nfnl_ct_set_zone@Base 3.5.0-1 + nfnl_ct_set_zone@libnl_3 3.5.0-1 + nfnl_ct_status2str@Base 3.5.0-1 + nfnl_ct_status2str@libnl_3 3.5.0-1 + nfnl_ct_str2status@Base 3.5.0-1 + nfnl_ct_str2status@libnl_3 3.5.0-1 + nfnl_ct_str2tcp_state@Base 3.5.0-1 + nfnl_ct_str2tcp_state@libnl_3 3.5.0-1 + nfnl_ct_tcp_state2str@Base 3.5.0-1 + nfnl_ct_tcp_state2str@libnl_3 3.5.0-1 + nfnl_ct_test_bytes@Base 3.5.0-1 + nfnl_ct_test_bytes@libnl_3 3.5.0-1 + nfnl_ct_test_dst_port@Base 3.5.0-1 + nfnl_ct_test_dst_port@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_code@Base 3.5.0-1 + nfnl_ct_test_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_id@Base 3.5.0-1 + nfnl_ct_test_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_type@Base 3.5.0-1 + nfnl_ct_test_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_test_id@Base 3.5.0-1 + nfnl_ct_test_id@libnl_3 3.5.0-1 + nfnl_ct_test_mark@Base 3.5.0-1 + nfnl_ct_test_mark@libnl_3 3.5.0-1 + nfnl_ct_test_packets@Base 3.5.0-1 + nfnl_ct_test_packets@libnl_3 3.5.0-1 + nfnl_ct_test_proto@Base 3.5.0-1 + nfnl_ct_test_proto@libnl_3 3.5.0-1 + nfnl_ct_test_src_port@Base 3.5.0-1 + nfnl_ct_test_src_port@libnl_3 3.5.0-1 + nfnl_ct_test_status@Base 3.5.0-1 + nfnl_ct_test_status@libnl_3 3.5.0-1 + nfnl_ct_test_tcp_state@Base 3.5.0-1 + nfnl_ct_test_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_test_timeout@Base 3.5.0-1 + nfnl_ct_test_timeout@libnl_3 3.5.0-1 + nfnl_ct_test_timestamp@Base 3.5.0-1 + nfnl_ct_test_timestamp@libnl_3 3.5.0-1 + nfnl_ct_test_use@Base 3.5.0-1 + nfnl_ct_test_use@libnl_3 3.5.0-1 + nfnl_ct_test_zone@Base 3.5.0-1 + nfnl_ct_test_zone@libnl_3 3.5.0-1 + nfnl_ct_unset_status@Base 3.5.0-1 + nfnl_ct_unset_status@libnl_3 3.5.0-1 + nfnl_exp_add@Base 3.5.0-1 + nfnl_exp_add@libnl_3 3.5.0-1 + nfnl_exp_alloc@Base 3.5.0-1 + nfnl_exp_alloc@libnl_3 3.5.0-1 + nfnl_exp_alloc_cache@Base 3.5.0-1 + nfnl_exp_alloc_cache@libnl_3 3.5.0-1 + nfnl_exp_build_add_request@Base 3.5.0-1 + nfnl_exp_build_add_request@libnl_3 3.5.0-1 + nfnl_exp_build_delete_request@Base 3.5.0-1 + nfnl_exp_build_delete_request@libnl_3 3.5.0-1 + nfnl_exp_build_query_request@Base 3.5.0-1 + nfnl_exp_build_query_request@libnl_3 3.5.0-1 + nfnl_exp_del@Base 3.5.0-1 + nfnl_exp_del@libnl_3 3.5.0-1 + nfnl_exp_dump_request@Base 3.5.0-1 + nfnl_exp_dump_request@libnl_3 3.5.0-1 + nfnl_exp_flags2str@Base 3.5.0-1 + nfnl_exp_flags2str@libnl_3 3.5.0-1 + nfnl_exp_get@Base 3.5.0-1 + nfnl_exp_get@libnl_3 3.5.0-1 + nfnl_exp_get_class@Base 3.5.0-1 + nfnl_exp_get_class@libnl_3 3.5.0-1 + nfnl_exp_get_dst@Base 3.5.0-1 + nfnl_exp_get_dst@libnl_3 3.5.0-1 + nfnl_exp_get_dst_port@Base 3.5.0-1 + nfnl_exp_get_dst_port@libnl_3 3.5.0-1 + nfnl_exp_get_family@Base 3.5.0-1 + nfnl_exp_get_family@libnl_3 3.5.0-1 + nfnl_exp_get_flags@Base 3.5.0-1 + nfnl_exp_get_flags@libnl_3 3.5.0-1 + nfnl_exp_get_fn@Base 3.5.0-1 + nfnl_exp_get_fn@libnl_3 3.5.0-1 + nfnl_exp_get_helper_name@Base 3.5.0-1 + nfnl_exp_get_helper_name@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_code@Base 3.5.0-1 + nfnl_exp_get_icmp_code@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_id@Base 3.5.0-1 + nfnl_exp_get_icmp_id@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_type@Base 3.5.0-1 + nfnl_exp_get_icmp_type@libnl_3 3.5.0-1 + nfnl_exp_get_id@Base 3.5.0-1 + nfnl_exp_get_id@libnl_3 3.5.0-1 + nfnl_exp_get_l4protonum@Base 3.5.0-1 + nfnl_exp_get_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_get_nat_dir@Base 3.5.0-1 + nfnl_exp_get_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_get_src@Base 3.5.0-1 + nfnl_exp_get_src@libnl_3 3.5.0-1 + nfnl_exp_get_src_port@Base 3.5.0-1 + nfnl_exp_get_src_port@libnl_3 3.5.0-1 + nfnl_exp_get_timeout@Base 3.5.0-1 + nfnl_exp_get_timeout@libnl_3 3.5.0-1 + nfnl_exp_get_zone@Base 3.5.0-1 + nfnl_exp_get_zone@libnl_3 3.5.0-1 + nfnl_exp_put@Base 3.5.0-1 + nfnl_exp_put@libnl_3 3.5.0-1 + nfnl_exp_query@Base 3.5.0-1 + nfnl_exp_query@libnl_3 3.5.0-1 + nfnl_exp_set_class@Base 3.5.0-1 + nfnl_exp_set_class@libnl_3 3.5.0-1 + nfnl_exp_set_dst@Base 3.5.0-1 + nfnl_exp_set_dst@libnl_3 3.5.0-1 + nfnl_exp_set_family@Base 3.5.0-1 + nfnl_exp_set_family@libnl_3 3.5.0-1 + nfnl_exp_set_flags@Base 3.5.0-1 + nfnl_exp_set_flags@libnl_3 3.5.0-1 + nfnl_exp_set_fn@Base 3.5.0-1 + nfnl_exp_set_fn@libnl_3 3.5.0-1 + nfnl_exp_set_helper_name@Base 3.5.0-1 + nfnl_exp_set_helper_name@libnl_3 3.5.0-1 + nfnl_exp_set_icmp@Base 3.5.0-1 + nfnl_exp_set_icmp@libnl_3 3.5.0-1 + nfnl_exp_set_id@Base 3.5.0-1 + nfnl_exp_set_id@libnl_3 3.5.0-1 + nfnl_exp_set_l4protonum@Base 3.5.0-1 + nfnl_exp_set_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_set_nat_dir@Base 3.5.0-1 + nfnl_exp_set_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_set_ports@Base 3.5.0-1 + nfnl_exp_set_ports@libnl_3 3.5.0-1 + nfnl_exp_set_src@Base 3.5.0-1 + nfnl_exp_set_src@libnl_3 3.5.0-1 + nfnl_exp_set_timeout@Base 3.5.0-1 + nfnl_exp_set_timeout@libnl_3 3.5.0-1 + nfnl_exp_set_zone@Base 3.5.0-1 + nfnl_exp_set_zone@libnl_3 3.5.0-1 + nfnl_exp_str2flags@Base 3.5.0-1 + nfnl_exp_str2flags@libnl_3 3.5.0-1 + nfnl_exp_test_class@Base 3.5.0-1 + nfnl_exp_test_class@libnl_3 3.5.0-1 + nfnl_exp_test_dst@Base 3.5.0-1 + nfnl_exp_test_dst@libnl_3 3.5.0-1 + nfnl_exp_test_flags@Base 3.5.0-1 + nfnl_exp_test_flags@libnl_3 3.5.0-1 + nfnl_exp_test_fn@Base 3.5.0-1 + nfnl_exp_test_fn@libnl_3 3.5.0-1 + nfnl_exp_test_helper_name@Base 3.5.0-1 + nfnl_exp_test_helper_name@libnl_3 3.5.0-1 + nfnl_exp_test_icmp@Base 3.5.0-1 + nfnl_exp_test_icmp@libnl_3 3.5.0-1 + nfnl_exp_test_id@Base 3.5.0-1 + nfnl_exp_test_id@libnl_3 3.5.0-1 + nfnl_exp_test_l4protonum@Base 3.5.0-1 + nfnl_exp_test_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_test_nat_dir@Base 3.5.0-1 + nfnl_exp_test_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_test_ports@Base 3.5.0-1 + nfnl_exp_test_ports@libnl_3 3.5.0-1 + nfnl_exp_test_src@Base 3.5.0-1 + nfnl_exp_test_src@libnl_3 3.5.0-1 + nfnl_exp_test_timeout@Base 3.5.0-1 + nfnl_exp_test_timeout@libnl_3 3.5.0-1 + nfnl_exp_test_zone@Base 3.5.0-1 + nfnl_exp_test_zone@libnl_3 3.5.0-1 + nfnl_exp_unset_flags@Base 3.5.0-1 + nfnl_exp_unset_flags@libnl_3 3.5.0-1 + nfnl_inet_hook2str@Base 3.5.0-1 + nfnl_inet_hook2str@libnl_3 3.5.0-1 + nfnl_log_alloc@Base 3.5.0-1 + nfnl_log_alloc@libnl_3 3.5.0-1 + nfnl_log_build_change_request@Base 3.5.0-1 + nfnl_log_build_change_request@libnl_3 3.5.0-1 + nfnl_log_build_create_request@Base 3.5.0-1 + nfnl_log_build_create_request@libnl_3 3.5.0-1 + nfnl_log_build_delete_request@Base 3.5.0-1 + nfnl_log_build_delete_request@libnl_3 3.5.0-1 + nfnl_log_build_pf_bind@Base 3.5.0-1 + nfnl_log_build_pf_bind@libnl_3 3.5.0-1 + nfnl_log_build_pf_unbind@Base 3.5.0-1 + nfnl_log_build_pf_unbind@libnl_3 3.5.0-1 + nfnl_log_change@Base 3.5.0-1 + nfnl_log_change@libnl_3 3.5.0-1 + nfnl_log_copy_mode2str@Base 3.5.0-1 + nfnl_log_copy_mode2str@libnl_3 3.5.0-1 + nfnl_log_create@Base 3.5.0-1 + nfnl_log_create@libnl_3 3.5.0-1 + nfnl_log_delete@Base 3.5.0-1 + nfnl_log_delete@libnl_3 3.5.0-1 + nfnl_log_flags2str@Base 3.5.0-1 + nfnl_log_flags2str@libnl_3 3.5.0-1 + nfnl_log_get@Base 3.5.0-1 + nfnl_log_get@libnl_3 3.5.0-1 + nfnl_log_get_alloc_size@Base 3.5.0-1 + nfnl_log_get_alloc_size@libnl_3 3.5.0-1 + nfnl_log_get_copy_mode@Base 3.5.0-1 + nfnl_log_get_copy_mode@libnl_3 3.5.0-1 + nfnl_log_get_copy_range@Base 3.5.0-1 + nfnl_log_get_copy_range@libnl_3 3.5.0-1 + nfnl_log_get_flush_timeout@Base 3.5.0-1 + nfnl_log_get_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_get_group@Base 3.5.0-1 + nfnl_log_get_group@libnl_3 3.5.0-1 + nfnl_log_get_queue_threshold@Base 3.5.0-1 + nfnl_log_get_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_msg_alloc@Base 3.5.0-1 + nfnl_log_msg_alloc@libnl_3 3.5.0-1 + nfnl_log_msg_get@Base 3.5.0-1 + nfnl_log_msg_get@libnl_3 3.5.0-1 + nfnl_log_msg_get_family@Base 3.5.0-1 + nfnl_log_msg_get_family@libnl_3 3.5.0-1 + nfnl_log_msg_get_gid@Base 3.5.0-1 + nfnl_log_msg_get_gid@libnl_3 3.5.0-1 + nfnl_log_msg_get_hook@Base 3.5.0-1 + nfnl_log_msg_get_hook@libnl_3 3.5.0-1 + nfnl_log_msg_get_hwaddr@Base 3.5.0-1 + nfnl_log_msg_get_hwaddr@libnl_3 3.5.0-1 + nfnl_log_msg_get_hwproto@Base 3.5.0-1 + nfnl_log_msg_get_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_get_indev@Base 3.5.0-1 + nfnl_log_msg_get_indev@libnl_3 3.5.0-1 + nfnl_log_msg_get_mark@Base 3.5.0-1 + nfnl_log_msg_get_mark@libnl_3 3.5.0-1 + nfnl_log_msg_get_outdev@Base 3.5.0-1 + nfnl_log_msg_get_outdev@libnl_3 3.5.0-1 + nfnl_log_msg_get_payload@Base 3.5.0-1 + nfnl_log_msg_get_payload@libnl_3 3.5.0-1 + nfnl_log_msg_get_physindev@Base 3.5.0-1 + nfnl_log_msg_get_physindev@libnl_3 3.5.0-1 + nfnl_log_msg_get_physoutdev@Base 3.5.0-1 + nfnl_log_msg_get_physoutdev@libnl_3 3.5.0-1 + nfnl_log_msg_get_prefix@Base 3.5.0-1 + nfnl_log_msg_get_prefix@libnl_3 3.5.0-1 + nfnl_log_msg_get_seq@Base 3.5.0-1 + nfnl_log_msg_get_seq@libnl_3 3.5.0-1 + nfnl_log_msg_get_seq_global@Base 3.5.0-1 + nfnl_log_msg_get_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_get_timestamp@Base 3.5.0-1 + nfnl_log_msg_get_timestamp@libnl_3 3.5.0-1 + nfnl_log_msg_get_uid@Base 3.5.0-1 + nfnl_log_msg_get_uid@libnl_3 3.5.0-1 + nfnl_log_msg_put@Base 3.5.0-1 + nfnl_log_msg_put@libnl_3 3.5.0-1 + nfnl_log_msg_set_family@Base 3.5.0-1 + nfnl_log_msg_set_family@libnl_3 3.5.0-1 + nfnl_log_msg_set_gid@Base 3.5.0-1 + nfnl_log_msg_set_gid@libnl_3 3.5.0-1 + nfnl_log_msg_set_hook@Base 3.5.0-1 + nfnl_log_msg_set_hook@libnl_3 3.5.0-1 + nfnl_log_msg_set_hwaddr@Base 3.5.0-1 + nfnl_log_msg_set_hwaddr@libnl_3 3.5.0-1 + nfnl_log_msg_set_hwproto@Base 3.5.0-1 + nfnl_log_msg_set_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_set_indev@Base 3.5.0-1 + nfnl_log_msg_set_indev@libnl_3 3.5.0-1 + nfnl_log_msg_set_mark@Base 3.5.0-1 + nfnl_log_msg_set_mark@libnl_3 3.5.0-1 + nfnl_log_msg_set_outdev@Base 3.5.0-1 + nfnl_log_msg_set_outdev@libnl_3 3.5.0-1 + nfnl_log_msg_set_payload@Base 3.5.0-1 + nfnl_log_msg_set_payload@libnl_3 3.5.0-1 + nfnl_log_msg_set_physindev@Base 3.5.0-1 + nfnl_log_msg_set_physindev@libnl_3 3.5.0-1 + nfnl_log_msg_set_physoutdev@Base 3.5.0-1 + nfnl_log_msg_set_physoutdev@libnl_3 3.5.0-1 + nfnl_log_msg_set_prefix@Base 3.5.0-1 + nfnl_log_msg_set_prefix@libnl_3 3.5.0-1 + nfnl_log_msg_set_seq@Base 3.5.0-1 + nfnl_log_msg_set_seq@libnl_3 3.5.0-1 + nfnl_log_msg_set_seq_global@Base 3.5.0-1 + nfnl_log_msg_set_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_set_timestamp@Base 3.5.0-1 + nfnl_log_msg_set_timestamp@libnl_3 3.5.0-1 + nfnl_log_msg_set_uid@Base 3.5.0-1 + nfnl_log_msg_set_uid@libnl_3 3.5.0-1 + nfnl_log_msg_test_gid@Base 3.5.0-1 + nfnl_log_msg_test_gid@libnl_3 3.5.0-1 + nfnl_log_msg_test_hook@Base 3.5.0-1 + nfnl_log_msg_test_hook@libnl_3 3.5.0-1 + nfnl_log_msg_test_hwproto@Base 3.5.0-1 + nfnl_log_msg_test_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_test_mark@Base 3.5.0-1 + nfnl_log_msg_test_mark@libnl_3 3.5.0-1 + nfnl_log_msg_test_seq@Base 3.5.0-1 + nfnl_log_msg_test_seq@libnl_3 3.5.0-1 + nfnl_log_msg_test_seq_global@Base 3.5.0-1 + nfnl_log_msg_test_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_test_uid@Base 3.5.0-1 + nfnl_log_msg_test_uid@libnl_3 3.5.0-1 + nfnl_log_pf_bind@Base 3.5.0-1 + nfnl_log_pf_bind@libnl_3 3.5.0-1 + nfnl_log_pf_unbind@Base 3.5.0-1 + nfnl_log_pf_unbind@libnl_3 3.5.0-1 + nfnl_log_put@Base 3.5.0-1 + nfnl_log_put@libnl_3 3.5.0-1 + nfnl_log_set_alloc_size@Base 3.5.0-1 + nfnl_log_set_alloc_size@libnl_3 3.5.0-1 + nfnl_log_set_copy_mode@Base 3.5.0-1 + nfnl_log_set_copy_mode@libnl_3 3.5.0-1 + nfnl_log_set_copy_range@Base 3.5.0-1 + nfnl_log_set_copy_range@libnl_3 3.5.0-1 + nfnl_log_set_flags@Base 3.5.0-1 + nfnl_log_set_flags@libnl_3 3.5.0-1 + nfnl_log_set_flush_timeout@Base 3.5.0-1 + nfnl_log_set_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_set_group@Base 3.5.0-1 + nfnl_log_set_group@libnl_3 3.5.0-1 + nfnl_log_set_queue_threshold@Base 3.5.0-1 + nfnl_log_set_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_str2copy_mode@Base 3.5.0-1 + nfnl_log_str2copy_mode@libnl_3 3.5.0-1 + nfnl_log_str2flags@Base 3.5.0-1 + nfnl_log_str2flags@libnl_3 3.5.0-1 + nfnl_log_test_alloc_size@Base 3.5.0-1 + nfnl_log_test_alloc_size@libnl_3 3.5.0-1 + nfnl_log_test_copy_mode@Base 3.5.0-1 + nfnl_log_test_copy_mode@libnl_3 3.5.0-1 + nfnl_log_test_copy_range@Base 3.5.0-1 + nfnl_log_test_copy_range@libnl_3 3.5.0-1 + nfnl_log_test_flush_timeout@Base 3.5.0-1 + nfnl_log_test_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_test_group@Base 3.5.0-1 + nfnl_log_test_group@libnl_3 3.5.0-1 + nfnl_log_test_queue_threshold@Base 3.5.0-1 + nfnl_log_test_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_unset_flags@Base 3.5.0-1 + nfnl_log_unset_flags@libnl_3 3.5.0-1 + nfnl_queue_alloc@Base 3.5.0-1 + nfnl_queue_alloc@libnl_3 3.5.0-1 + nfnl_queue_build_change_request@Base 3.5.0-1 + nfnl_queue_build_change_request@libnl_3 3.5.0-1 + nfnl_queue_build_create_request@Base 3.5.0-1 + nfnl_queue_build_create_request@libnl_3 3.5.0-1 + nfnl_queue_build_delete_request@Base 3.5.0-1 + nfnl_queue_build_delete_request@libnl_3 3.5.0-1 + nfnl_queue_build_pf_bind@Base 3.5.0-1 + nfnl_queue_build_pf_bind@libnl_3 3.5.0-1 + nfnl_queue_build_pf_unbind@Base 3.5.0-1 + nfnl_queue_build_pf_unbind@libnl_3 3.5.0-1 + nfnl_queue_change@Base 3.5.0-1 + nfnl_queue_change@libnl_3 3.5.0-1 + nfnl_queue_copy_mode2str@Base 3.5.0-1 + nfnl_queue_copy_mode2str@libnl_3 3.5.0-1 + nfnl_queue_create@Base 3.5.0-1 + nfnl_queue_create@libnl_3 3.5.0-1 + nfnl_queue_delete@Base 3.5.0-1 + nfnl_queue_delete@libnl_3 3.5.0-1 + nfnl_queue_get@Base 3.5.0-1 + nfnl_queue_get@libnl_3 3.5.0-1 + nfnl_queue_get_copy_mode@Base 3.5.0-1 + nfnl_queue_get_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_get_copy_range@Base 3.5.0-1 + nfnl_queue_get_copy_range@libnl_3 3.5.0-1 + nfnl_queue_get_group@Base 3.5.0-1 + nfnl_queue_get_group@libnl_3 3.5.0-1 + nfnl_queue_get_maxlen@Base 3.5.0-1 + nfnl_queue_get_maxlen@libnl_3 3.5.0-1 + nfnl_queue_msg_alloc@Base 3.5.0-1 + nfnl_queue_msg_alloc@libnl_3 3.5.0-1 + nfnl_queue_msg_build_verdict@Base 3.5.0-1 + nfnl_queue_msg_build_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_build_verdict_batch@Base 3.5.0-1 + nfnl_queue_msg_build_verdict_batch@libnl_3 3.5.0-1 + nfnl_queue_msg_get@Base 3.5.0-1 + nfnl_queue_msg_get@libnl_3 3.5.0-1 + nfnl_queue_msg_get_family@Base 3.5.0-1 + nfnl_queue_msg_get_family@libnl_3 3.5.0-1 + nfnl_queue_msg_get_group@Base 3.5.0-1 + nfnl_queue_msg_get_group@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hook@Base 3.5.0-1 + nfnl_queue_msg_get_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_get_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hwproto@Base 3.5.0-1 + nfnl_queue_msg_get_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_get_indev@Base 3.5.0-1 + nfnl_queue_msg_get_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_mark@Base 3.5.0-1 + nfnl_queue_msg_get_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_get_outdev@Base 3.5.0-1 + nfnl_queue_msg_get_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_packetid@Base 3.5.0-1 + nfnl_queue_msg_get_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_get_payload@Base 3.5.0-1 + nfnl_queue_msg_get_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_get_physindev@Base 3.5.0-1 + nfnl_queue_msg_get_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_get_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_timestamp@Base 3.5.0-1 + nfnl_queue_msg_get_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_get_verdict@Base 3.5.0-1 + nfnl_queue_msg_get_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_put@Base 3.5.0-1 + nfnl_queue_msg_put@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict@Base 3.5.0-1 + nfnl_queue_msg_send_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict_batch@Base 3.5.0-1 + nfnl_queue_msg_send_verdict_batch@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict_payload@Base 3.5.0-1 + nfnl_queue_msg_send_verdict_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_set_family@Base 3.5.0-1 + nfnl_queue_msg_set_family@libnl_3 3.5.0-1 + nfnl_queue_msg_set_group@Base 3.5.0-1 + nfnl_queue_msg_set_group@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hook@Base 3.5.0-1 + nfnl_queue_msg_set_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_set_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hwproto@Base 3.5.0-1 + nfnl_queue_msg_set_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_set_indev@Base 3.5.0-1 + nfnl_queue_msg_set_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_mark@Base 3.5.0-1 + nfnl_queue_msg_set_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_set_outdev@Base 3.5.0-1 + nfnl_queue_msg_set_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_packetid@Base 3.5.0-1 + nfnl_queue_msg_set_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_set_payload@Base 3.5.0-1 + nfnl_queue_msg_set_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_set_physindev@Base 3.5.0-1 + nfnl_queue_msg_set_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_set_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_timestamp@Base 3.5.0-1 + nfnl_queue_msg_set_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_set_verdict@Base 3.5.0-1 + nfnl_queue_msg_set_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_test_family@Base 3.5.0-1 + nfnl_queue_msg_test_family@libnl_3 3.5.0-1 + nfnl_queue_msg_test_group@Base 3.5.0-1 + nfnl_queue_msg_test_group@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hook@Base 3.5.0-1 + nfnl_queue_msg_test_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_test_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hwproto@Base 3.5.0-1 + nfnl_queue_msg_test_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_test_indev@Base 3.5.0-1 + nfnl_queue_msg_test_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_mark@Base 3.5.0-1 + nfnl_queue_msg_test_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_test_outdev@Base 3.5.0-1 + nfnl_queue_msg_test_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_packetid@Base 3.5.0-1 + nfnl_queue_msg_test_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_test_payload@Base 3.5.0-1 + nfnl_queue_msg_test_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_test_physindev@Base 3.5.0-1 + nfnl_queue_msg_test_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_test_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_timestamp@Base 3.5.0-1 + nfnl_queue_msg_test_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_test_verdict@Base 3.5.0-1 + nfnl_queue_msg_test_verdict@libnl_3 3.5.0-1 + nfnl_queue_pf_bind@Base 3.5.0-1 + nfnl_queue_pf_bind@libnl_3 3.5.0-1 + nfnl_queue_pf_unbind@Base 3.5.0-1 + nfnl_queue_pf_unbind@libnl_3 3.5.0-1 + nfnl_queue_put@Base 3.5.0-1 + nfnl_queue_put@libnl_3 3.5.0-1 + nfnl_queue_set_copy_mode@Base 3.5.0-1 + nfnl_queue_set_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_set_copy_range@Base 3.5.0-1 + nfnl_queue_set_copy_range@libnl_3 3.5.0-1 + nfnl_queue_set_group@Base 3.5.0-1 + nfnl_queue_set_group@libnl_3 3.5.0-1 + nfnl_queue_set_maxlen@Base 3.5.0-1 + nfnl_queue_set_maxlen@libnl_3 3.5.0-1 + nfnl_queue_socket_alloc@Base 3.5.0-1 + nfnl_queue_socket_alloc@libnl_3 3.5.0-1 + nfnl_queue_str2copy_mode@Base 3.5.0-1 + nfnl_queue_str2copy_mode@libnl_3 3.5.0-1 + nfnl_queue_test_copy_mode@Base 3.5.0-1 + nfnl_queue_test_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_test_copy_range@Base 3.5.0-1 + nfnl_queue_test_copy_range@libnl_3 3.5.0-1 + nfnl_queue_test_group@Base 3.5.0-1 + nfnl_queue_test_group@libnl_3 3.5.0-1 + nfnl_queue_test_maxlen@Base 3.5.0-1 + nfnl_queue_test_maxlen@libnl_3 3.5.0-1 + nfnl_send_simple@Base 3.5.0-1 + nfnl_send_simple@libnl_3 3.5.0-1 + nfnl_str2inet_hook@Base 3.5.0-1 + nfnl_str2inet_hook@libnl_3 3.5.0-1 + nfnl_str2verdict@Base 3.5.0-1 + nfnl_str2verdict@libnl_3 3.5.0-1 + nfnl_verdict2str@Base 3.5.0-1 + nfnl_verdict2str@libnl_3 3.5.0-1 + nfnlmsg_alloc_simple@Base 3.5.0-1 + nfnlmsg_alloc_simple@libnl_3 3.5.0-1 + nfnlmsg_ct_group@Base 3.5.0-1 + nfnlmsg_ct_group@libnl_3 3.5.0-1 + nfnlmsg_ct_parse@Base 3.5.0-1 + nfnlmsg_ct_parse@libnl_3 3.5.0-1 + nfnlmsg_exp_group@Base 3.5.0-1 + nfnlmsg_exp_group@libnl_3 3.5.0-1 + nfnlmsg_exp_parse@Base 3.5.0-1 + nfnlmsg_exp_parse@libnl_3 3.5.0-1 + nfnlmsg_family@Base 3.5.0-1 + nfnlmsg_family@libnl_3 3.5.0-1 + nfnlmsg_log_msg_parse@Base 3.5.0-1 + nfnlmsg_log_msg_parse@libnl_3 3.5.0-1 + nfnlmsg_put@Base 3.5.0-1 + nfnlmsg_put@libnl_3 3.5.0-1 + nfnlmsg_queue_msg_parse@Base 3.5.0-1 + nfnlmsg_queue_msg_parse@libnl_3 3.5.0-1 + nfnlmsg_res_id@Base 3.5.0-1 + nfnlmsg_res_id@libnl_3 3.5.0-1 + nfnlmsg_subsys@Base 3.5.0-1 + nfnlmsg_subsys@libnl_3 3.5.0-1 + nfnlmsg_subtype@Base 3.5.0-1 + nfnlmsg_subtype@libnl_3 3.5.0-1 + queue_msg_obj_ops@Base 3.5.0-1 + queue_msg_obj_ops@libnl_3 3.5.0-1 + queue_obj_ops@Base 3.5.0-1 + queue_obj_ops@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-nf-3-dev.install b/src/libnl3/debian/libnl-nf-3-dev.install new file mode 100644 index 000000000000..d1307c751b84 --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-nf-3* +debian/tmp/usr/lib/*/libnl-nf-3*.so +debian/tmp/usr/lib/*/libnl-nf-3*.a diff --git a/src/libnl3/debian/libnl-route-3-200.install b/src/libnl3/debian/libnl-route-3-200.install new file mode 100644 index 000000000000..44c7ec8cdfad --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-route-3*.so.* diff --git a/src/libnl3/debian/libnl-route-3-200.symbols b/src/libnl3/debian/libnl-route-3-200.symbols new file mode 100644 index 000000000000..e11157ba4e88 --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-200.symbols @@ -0,0 +1,2051 @@ +libnl-route-3.so.200 libnl-route-3-200 #MINVER# + ematch__create_buffer@Base 3.5.0-1 + ematch__delete_buffer@Base 3.5.0-1 + ematch__flush_buffer@Base 3.5.0-1 + ematch__scan_buffer@Base 3.5.0-1 + ematch__scan_bytes@Base 3.5.0-1 + ematch__scan_string@Base 3.5.0-1 + ematch__switch_to_buffer@Base 3.5.0-1 + ematch_alloc@Base 3.5.0-1 + ematch_free@Base 3.5.0-1 + ematch_get_column@Base 3.5.0-1 + ematch_get_debug@Base 3.5.0-1 + ematch_get_extra@Base 3.5.0-1 + ematch_get_in@Base 3.5.0-1 + ematch_get_leng@Base 3.5.0-1 + ematch_get_lineno@Base 3.5.0-1 + ematch_get_lval@Base 3.5.0-1 + ematch_get_out@Base 3.5.0-1 + ematch_get_text@Base 3.5.0-1 + ematch_lex@Base 3.5.0-1 + ematch_lex_destroy@Base 3.5.0-1 + ematch_lex_init@Base 3.5.0-1 + ematch_lex_init_extra@Base 3.5.0-1 + ematch_parse@Base 3.5.0-1 + ematch_pop_buffer_state@Base 3.5.0-1 + ematch_push_buffer_state@Base 3.5.0-1 + ematch_realloc@Base 3.5.0-1 + ematch_restart@Base 3.5.0-1 + ematch_set_column@Base 3.5.0-1 + ematch_set_debug@Base 3.5.0-1 + ematch_set_extra@Base 3.5.0-1 + ematch_set_in@Base 3.5.0-1 + ematch_set_lineno@Base 3.5.0-1 + ematch_set_lval@Base 3.5.0-1 + ematch_set_out@Base 3.5.0-1 + flnl_lookup@Base 3.5.0-1 + flnl_lookup@libnl_3 3.5.0-1 + flnl_lookup_build_request@Base 3.5.0-1 + flnl_lookup_build_request@libnl_3 3.5.0-1 + flnl_request_alloc@Base 3.5.0-1 + flnl_request_alloc@libnl_3 3.5.0-1 + flnl_request_get_addr@Base 3.5.0-1 + flnl_request_get_addr@libnl_3 3.5.0-1 + flnl_request_get_fwmark@Base 3.5.0-1 + flnl_request_get_fwmark@libnl_3 3.5.0-1 + flnl_request_get_scope@Base 3.5.0-1 + flnl_request_get_scope@libnl_3 3.5.0-1 + flnl_request_get_table@Base 3.5.0-1 + flnl_request_get_table@libnl_3 3.5.0-1 + flnl_request_get_tos@Base 3.5.0-1 + flnl_request_get_tos@libnl_3 3.5.0-1 + flnl_request_set_addr@Base 3.5.0-1 + flnl_request_set_addr@libnl_3 3.5.0-1 + flnl_request_set_fwmark@Base 3.5.0-1 + flnl_request_set_fwmark@libnl_3 3.5.0-1 + flnl_request_set_scope@Base 3.5.0-1 + flnl_request_set_scope@libnl_3 3.5.0-1 + flnl_request_set_table@Base 3.5.0-1 + flnl_request_set_table@libnl_3 3.5.0-1 + flnl_request_set_tos@Base 3.5.0-1 + flnl_request_set_tos@libnl_3 3.5.0-1 + flnl_result_alloc@Base 3.5.0-1 + flnl_result_alloc@libnl_3 3.5.0-1 + flnl_result_alloc_cache@Base 3.5.0-1 + flnl_result_alloc_cache@libnl_3 3.5.0-1 + flnl_result_get_error@Base 3.5.0-1 + flnl_result_get_error@libnl_3 3.5.0-1 + flnl_result_get_nexthop_sel@Base 3.5.0-1 + flnl_result_get_nexthop_sel@libnl_3 3.5.0-1 + flnl_result_get_prefixlen@Base 3.5.0-1 + flnl_result_get_prefixlen@libnl_3 3.5.0-1 + flnl_result_get_scope@Base 3.5.0-1 + flnl_result_get_scope@libnl_3 3.5.0-1 + flnl_result_get_table_id@Base 3.5.0-1 + flnl_result_get_table_id@libnl_3 3.5.0-1 + flnl_result_get_type@Base 3.5.0-1 + flnl_result_get_type@libnl_3 3.5.0-1 + flnl_result_put@Base 3.5.0-1 + flnl_result_put@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_26@libnl_3_2_26 3.5.0-1 + libnl_3_2_27@libnl_3_2_27 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + libnl_3_2_29@libnl_3_2_29 3.5.0-1 + libnl_3_4@libnl_3_4 3.5.0-1 + libnl_3_5@libnl_3_5 3.5.0-1 + nl_ovl_strategy2str@Base 3.5.0-1 + nl_ovl_strategy2str@libnl_3 3.5.0-1 + nl_police2str@Base 3.5.0-1 + nl_police2str@libnl_3 3.5.0-1 + nl_rtgen_request@Base 3.5.0-1 + nl_rtgen_request@libnl_3 3.5.0-1 + nl_rtntype2str@Base 3.5.0-1 + nl_rtntype2str@libnl_3 3.5.0-1 + nl_str2ovl_strategy@Base 3.5.0-1 + nl_str2ovl_strategy@libnl_3 3.5.0-1 + nl_str2police@Base 3.5.0-1 + nl_str2police@libnl_3 3.5.0-1 + nl_str2rtntype@Base 3.5.0-1 + nl_str2rtntype@libnl_3 3.5.0-1 + pktloc__create_buffer@Base 3.5.0-1 + pktloc__delete_buffer@Base 3.5.0-1 + pktloc__flush_buffer@Base 3.5.0-1 + pktloc__scan_buffer@Base 3.5.0-1 + pktloc__scan_bytes@Base 3.5.0-1 + pktloc__scan_string@Base 3.5.0-1 + pktloc__switch_to_buffer@Base 3.5.0-1 + pktloc_alloc@Base 3.5.0-1 + pktloc_free@Base 3.5.0-1 + pktloc_get_column@Base 3.5.0-1 + pktloc_get_debug@Base 3.5.0-1 + pktloc_get_extra@Base 3.5.0-1 + pktloc_get_in@Base 3.5.0-1 + pktloc_get_leng@Base 3.5.0-1 + pktloc_get_lineno@Base 3.5.0-1 + pktloc_get_lloc@Base 3.5.0-1 + pktloc_get_lval@Base 3.5.0-1 + pktloc_get_out@Base 3.5.0-1 + pktloc_get_text@Base 3.5.0-1 + pktloc_lex@Base 3.5.0-1 + pktloc_lex_destroy@Base 3.5.0-1 + pktloc_lex_init@Base 3.5.0-1 + pktloc_lex_init_extra@Base 3.5.0-1 + pktloc_parse@Base 3.5.0-1 + pktloc_pop_buffer_state@Base 3.5.0-1 + pktloc_push_buffer_state@Base 3.5.0-1 + pktloc_realloc@Base 3.5.0-1 + pktloc_restart@Base 3.5.0-1 + pktloc_set_column@Base 3.5.0-1 + pktloc_set_debug@Base 3.5.0-1 + pktloc_set_extra@Base 3.5.0-1 + pktloc_set_in@Base 3.5.0-1 + pktloc_set_lineno@Base 3.5.0-1 + pktloc_set_lloc@Base 3.5.0-1 + + pktloc_set_lval@Base 3.5.0-1 + pktloc_set_out@Base 3.5.0-1 + route_obj_ops@Base 3.5.0-1 + route_obj_ops@libnl_3 3.5.0-1 + rtln_link_policy@Base 3.5.0-1 + rtln_link_policy@libnl_3 3.5.0-1 + rtnl_act_add@Base 3.5.0-1 + rtnl_act_add@libnl_3 3.5.0-1 + rtnl_act_alloc@Base 3.5.0-1 + rtnl_act_alloc@libnl_3 3.5.0-1 + rtnl_act_append@Base 3.5.0-1 + rtnl_act_append@libnl_3 3.5.0-1 + rtnl_act_build_add_request@Base 3.5.0-1 + rtnl_act_build_add_request@libnl_3 3.5.0-1 + rtnl_act_build_change_request@Base 3.5.0-1 + rtnl_act_build_change_request@libnl_3 3.5.0-1 + rtnl_act_build_delete_request@Base 3.5.0-1 + rtnl_act_build_delete_request@libnl_3 3.5.0-1 + rtnl_act_change@Base 3.5.0-1 + rtnl_act_change@libnl_3 3.5.0-1 + rtnl_act_delete@Base 3.5.0-1 + rtnl_act_delete@libnl_3 3.5.0-1 + rtnl_act_fill@Base 3.5.0-1 + rtnl_act_fill@libnl_3 3.5.0-1 + rtnl_act_get@Base 3.5.0-1 + rtnl_act_get@libnl_3 3.5.0-1 + rtnl_act_next@libnl_3_4 3.5.0-1 + rtnl_act_parse@Base 3.5.0-1 + rtnl_act_parse@libnl_3 3.5.0-1 + rtnl_act_put@Base 3.5.0-1 + rtnl_act_put@libnl_3 3.5.0-1 + rtnl_act_put_all@Base 3.5.0-1 + rtnl_act_put_all@libnl_3 3.5.0-1 + rtnl_act_remove@Base 3.5.0-1 + rtnl_act_remove@libnl_3 3.5.0-1 + rtnl_addr_add@Base 3.5.0-1 + rtnl_addr_add@libnl_3 3.5.0-1 + rtnl_addr_alloc@Base 3.5.0-1 + rtnl_addr_alloc@libnl_3 3.5.0-1 + rtnl_addr_alloc_cache@Base 3.5.0-1 + rtnl_addr_alloc_cache@libnl_3 3.5.0-1 + rtnl_addr_build_add_request@Base 3.5.0-1 + rtnl_addr_build_add_request@libnl_3 3.5.0-1 + rtnl_addr_build_delete_request@Base 3.5.0-1 + rtnl_addr_build_delete_request@libnl_3 3.5.0-1 + rtnl_addr_delete@Base 3.5.0-1 + rtnl_addr_delete@libnl_3 3.5.0-1 + rtnl_addr_flags2str@Base 3.5.0-1 + rtnl_addr_flags2str@libnl_3 3.5.0-1 + rtnl_addr_get@Base 3.5.0-1 + rtnl_addr_get@libnl_3 3.5.0-1 + rtnl_addr_get_anycast@Base 3.5.0-1 + rtnl_addr_get_anycast@libnl_3 3.5.0-1 + rtnl_addr_get_broadcast@Base 3.5.0-1 + rtnl_addr_get_broadcast@libnl_3 3.5.0-1 + rtnl_addr_get_create_time@Base 3.5.0-1 + rtnl_addr_get_create_time@libnl_3 3.5.0-1 + rtnl_addr_get_family@Base 3.5.0-1 + rtnl_addr_get_family@libnl_3 3.5.0-1 + rtnl_addr_get_flags@Base 3.5.0-1 + rtnl_addr_get_flags@libnl_3 3.5.0-1 + rtnl_addr_get_ifindex@Base 3.5.0-1 + rtnl_addr_get_ifindex@libnl_3 3.5.0-1 + rtnl_addr_get_label@Base 3.5.0-1 + rtnl_addr_get_label@libnl_3 3.5.0-1 + rtnl_addr_get_last_update_time@Base 3.5.0-1 + rtnl_addr_get_last_update_time@libnl_3 3.5.0-1 + rtnl_addr_get_link@Base 3.5.0-1 + rtnl_addr_get_link@libnl_3 3.5.0-1 + rtnl_addr_get_local@Base 3.5.0-1 + rtnl_addr_get_local@libnl_3 3.5.0-1 + rtnl_addr_get_multicast@Base 3.5.0-1 + rtnl_addr_get_multicast@libnl_3 3.5.0-1 + rtnl_addr_get_peer@Base 3.5.0-1 + rtnl_addr_get_peer@libnl_3 3.5.0-1 + rtnl_addr_get_preferred_lifetime@Base 3.5.0-1 + rtnl_addr_get_preferred_lifetime@libnl_3 3.5.0-1 + rtnl_addr_get_prefixlen@Base 3.5.0-1 + rtnl_addr_get_prefixlen@libnl_3 3.5.0-1 + rtnl_addr_get_scope@Base 3.5.0-1 + rtnl_addr_get_scope@libnl_3 3.5.0-1 + rtnl_addr_get_valid_lifetime@Base 3.5.0-1 + rtnl_addr_get_valid_lifetime@libnl_3 3.5.0-1 + rtnl_addr_put@Base 3.5.0-1 + rtnl_addr_put@libnl_3 3.5.0-1 + rtnl_addr_set_anycast@Base 3.5.0-1 + rtnl_addr_set_anycast@libnl_3 3.5.0-1 + rtnl_addr_set_broadcast@Base 3.5.0-1 + rtnl_addr_set_broadcast@libnl_3 3.5.0-1 + rtnl_addr_set_family@Base 3.5.0-1 + rtnl_addr_set_family@libnl_3 3.5.0-1 + rtnl_addr_set_flags@Base 3.5.0-1 + rtnl_addr_set_flags@libnl_3 3.5.0-1 + rtnl_addr_set_ifindex@Base 3.5.0-1 + rtnl_addr_set_ifindex@libnl_3 3.5.0-1 + rtnl_addr_set_label@Base 3.5.0-1 + rtnl_addr_set_label@libnl_3 3.5.0-1 + rtnl_addr_set_link@Base 3.5.0-1 + rtnl_addr_set_link@libnl_3 3.5.0-1 + rtnl_addr_set_local@Base 3.5.0-1 + rtnl_addr_set_local@libnl_3 3.5.0-1 + rtnl_addr_set_multicast@Base 3.5.0-1 + rtnl_addr_set_multicast@libnl_3 3.5.0-1 + rtnl_addr_set_peer@Base 3.5.0-1 + rtnl_addr_set_peer@libnl_3 3.5.0-1 + rtnl_addr_set_preferred_lifetime@Base 3.5.0-1 + rtnl_addr_set_preferred_lifetime@libnl_3 3.5.0-1 + rtnl_addr_set_prefixlen@Base 3.5.0-1 + rtnl_addr_set_prefixlen@libnl_3 3.5.0-1 + rtnl_addr_set_scope@Base 3.5.0-1 + rtnl_addr_set_scope@libnl_3 3.5.0-1 + rtnl_addr_set_valid_lifetime@Base 3.5.0-1 + rtnl_addr_set_valid_lifetime@libnl_3 3.5.0-1 + rtnl_addr_str2flags@Base 3.5.0-1 + rtnl_addr_str2flags@libnl_3 3.5.0-1 + rtnl_addr_unset_flags@Base 3.5.0-1 + rtnl_addr_unset_flags@libnl_3 3.5.0-1 + rtnl_basic_add_action@Base 3.5.0-1 + rtnl_basic_add_action@libnl_3 3.5.0-1 + rtnl_basic_del_action@Base 3.5.0-1 + rtnl_basic_del_action@libnl_3 3.5.0-1 + rtnl_basic_get_action@libnl_3_4 3.5.0-1 + rtnl_basic_get_ematch@Base 3.5.0-1 + rtnl_basic_get_ematch@libnl_3 3.5.0-1 + rtnl_basic_get_target@Base 3.5.0-1 + rtnl_basic_get_target@libnl_3 3.5.0-1 + rtnl_basic_set_ematch@Base 3.5.0-1 + rtnl_basic_set_ematch@libnl_3 3.5.0-1 + rtnl_basic_set_target@Base 3.5.0-1 + rtnl_basic_set_target@libnl_3 3.5.0-1 + rtnl_cgroup_get_ematch@Base 3.5.0-1 + rtnl_cgroup_get_ematch@libnl_3 3.5.0-1 + rtnl_cgroup_set_ematch@Base 3.5.0-1 + rtnl_cgroup_set_ematch@libnl_3 3.5.0-1 + rtnl_class_add@Base 3.5.0-1 + rtnl_class_add@libnl_3 3.5.0-1 + rtnl_class_alloc@Base 3.5.0-1 + rtnl_class_alloc@libnl_3 3.5.0-1 + rtnl_class_alloc_cache@Base 3.5.0-1 + rtnl_class_alloc_cache@libnl_3 3.5.0-1 + rtnl_class_build_add_request@Base 3.5.0-1 + rtnl_class_build_add_request@libnl_3 3.5.0-1 + rtnl_class_build_delete_request@Base 3.5.0-1 + rtnl_class_build_delete_request@libnl_3 3.5.0-1 + rtnl_class_delete@Base 3.5.0-1 + rtnl_class_delete@libnl_3 3.5.0-1 + rtnl_class_dsmark_get_bitmask@Base 3.5.0-1 + rtnl_class_dsmark_get_bitmask@libnl_3 3.5.0-1 + rtnl_class_dsmark_get_value@Base 3.5.0-1 + rtnl_class_dsmark_get_value@libnl_3 3.5.0-1 + rtnl_class_dsmark_set_bitmask@Base 3.5.0-1 + rtnl_class_dsmark_set_bitmask@libnl_3 3.5.0-1 + rtnl_class_dsmark_set_value@Base 3.5.0-1 + rtnl_class_dsmark_set_value@libnl_3 3.5.0-1 + rtnl_class_foreach_child@Base 3.5.0-1 + rtnl_class_foreach_child@libnl_3 3.5.0-1 + rtnl_class_foreach_cls@Base 3.5.0-1 + rtnl_class_foreach_cls@libnl_3 3.5.0-1 + rtnl_class_get@Base 3.5.0-1 + rtnl_class_get@libnl_3 3.5.0-1 + rtnl_class_get_by_parent@libnl_3_5 3.5.0-1 + rtnl_class_hfsc_get_fsc@Base 3.5.0-1 + rtnl_class_hfsc_get_fsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_get_rsc@Base 3.5.0-1 + rtnl_class_hfsc_get_rsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_get_usc@Base 3.5.0-1 + rtnl_class_hfsc_get_usc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_fsc@Base 3.5.0-1 + rtnl_class_hfsc_set_fsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_rsc@Base 3.5.0-1 + rtnl_class_hfsc_set_rsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_usc@Base 3.5.0-1 + rtnl_class_hfsc_set_usc@libnl_3 3.5.0-1 + rtnl_class_leaf_qdisc@Base 3.5.0-1 + rtnl_class_leaf_qdisc@libnl_3 3.5.0-1 + rtnl_class_put@Base 3.5.0-1 + rtnl_class_put@libnl_3 3.5.0-1 + rtnl_classid_generate@Base 3.5.0-1 + rtnl_classid_generate@libnl_3 3.5.0-1 + rtnl_cls_add@Base 3.5.0-1 + rtnl_cls_add@libnl_3 3.5.0-1 + rtnl_cls_alloc@Base 3.5.0-1 + rtnl_cls_alloc@libnl_3 3.5.0-1 + rtnl_cls_alloc_cache@Base 3.5.0-1 + rtnl_cls_alloc_cache@libnl_3 3.5.0-1 + rtnl_cls_build_add_request@Base 3.5.0-1 + rtnl_cls_build_add_request@libnl_3 3.5.0-1 + rtnl_cls_build_change_request@Base 3.5.0-1 + rtnl_cls_build_change_request@libnl_3 3.5.0-1 + rtnl_cls_build_delete_request@Base 3.5.0-1 + rtnl_cls_build_delete_request@libnl_3 3.5.0-1 + rtnl_cls_cache_set_tc_params@libnl_3_5 3.5.0-1 + rtnl_cls_change@Base 3.5.0-1 + rtnl_cls_change@libnl_3 3.5.0-1 + rtnl_cls_delete@Base 3.5.0-1 + rtnl_cls_delete@libnl_3 3.5.0-1 + rtnl_cls_get_prio@Base 3.5.0-1 + rtnl_cls_get_prio@libnl_3 3.5.0-1 + rtnl_cls_get_protocol@Base 3.5.0-1 + rtnl_cls_get_protocol@libnl_3 3.5.0-1 + rtnl_cls_put@Base 3.5.0-1 + rtnl_cls_put@libnl_3 3.5.0-1 + rtnl_cls_set_prio@Base 3.5.0-1 + rtnl_cls_set_prio@libnl_3 3.5.0-1 + rtnl_cls_set_protocol@Base 3.5.0-1 + rtnl_cls_set_protocol@libnl_3 3.5.0-1 + rtnl_ematch_add_child@Base 3.5.0-1 + rtnl_ematch_add_child@libnl_3 3.5.0-1 + rtnl_ematch_alloc@Base 3.5.0-1 + rtnl_ematch_alloc@libnl_3 3.5.0-1 + rtnl_ematch_cmp_get@Base 3.5.0-1 + rtnl_ematch_cmp_get@libnl_3 3.5.0-1 + rtnl_ematch_cmp_set@Base 3.5.0-1 + rtnl_ematch_cmp_set@libnl_3 3.5.0-1 + rtnl_ematch_data@Base 3.5.0-1 + rtnl_ematch_data@libnl_3 3.5.0-1 + rtnl_ematch_fill_attr@Base 3.5.0-1 + rtnl_ematch_fill_attr@libnl_3 3.5.0-1 + rtnl_ematch_free@Base 3.5.0-1 + rtnl_ematch_free@libnl_3 3.5.0-1 + rtnl_ematch_get_flags@Base 3.5.0-1 + rtnl_ematch_get_flags@libnl_3 3.5.0-1 + rtnl_ematch_lookup_ops@Base 3.5.0-1 + rtnl_ematch_lookup_ops@libnl_3 3.5.0-1 + rtnl_ematch_lookup_ops_by_name@Base 3.5.0-1 + rtnl_ematch_lookup_ops_by_name@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_lvalue@Base 3.5.0-1 + rtnl_ematch_meta_set_lvalue@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_operand@Base 3.5.0-1 + rtnl_ematch_meta_set_operand@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_rvalue@Base 3.5.0-1 + rtnl_ematch_meta_set_rvalue@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_layer@Base 3.5.0-1 + rtnl_ematch_nbyte_get_layer@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_len@Base 3.5.0-1 + rtnl_ematch_nbyte_get_len@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_offset@Base 3.5.0-1 + rtnl_ematch_nbyte_get_offset@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_pattern@Base 3.5.0-1 + rtnl_ematch_nbyte_get_pattern@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_set_offset@Base 3.5.0-1 + rtnl_ematch_nbyte_set_offset@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_set_pattern@Base 3.5.0-1 + rtnl_ematch_nbyte_set_pattern@libnl_3 3.5.0-1 + rtnl_ematch_offset2txt@Base 3.5.0-1 + rtnl_ematch_offset2txt@libnl_3 3.5.0-1 + rtnl_ematch_opnd2txt@Base 3.5.0-1 + rtnl_ematch_opnd2txt@libnl_3 3.5.0-1 + rtnl_ematch_parse_attr@Base 3.5.0-1 + rtnl_ematch_parse_attr@libnl_3 3.5.0-1 + rtnl_ematch_parse_expr@Base 3.5.0-1 + rtnl_ematch_parse_expr@libnl_3 3.5.0-1 + rtnl_ematch_register@Base 3.5.0-1 + rtnl_ematch_register@libnl_3 3.5.0-1 + rtnl_ematch_set_flags@Base 3.5.0-1 + rtnl_ematch_set_flags@libnl_3 3.5.0-1 + rtnl_ematch_set_kind@Base 3.5.0-1 + rtnl_ematch_set_kind@libnl_3 3.5.0-1 + rtnl_ematch_set_name@Base 3.5.0-1 + rtnl_ematch_set_name@libnl_3 3.5.0-1 + rtnl_ematch_set_ops@Base 3.5.0-1 + rtnl_ematch_set_ops@libnl_3 3.5.0-1 + rtnl_ematch_text_get_algo@Base 3.5.0-1 + rtnl_ematch_text_get_algo@libnl_3 3.5.0-1 + rtnl_ematch_text_get_from_layer@Base 3.5.0-1 + rtnl_ematch_text_get_from_layer@libnl_3 3.5.0-1 + rtnl_ematch_text_get_from_offset@Base 3.5.0-1 + rtnl_ematch_text_get_from_offset@libnl_3 3.5.0-1 + rtnl_ematch_text_get_len@Base 3.5.0-1 + rtnl_ematch_text_get_len@libnl_3 3.5.0-1 + rtnl_ematch_text_get_pattern@Base 3.5.0-1 + rtnl_ematch_text_get_pattern@libnl_3 3.5.0-1 + rtnl_ematch_text_get_to_layer@Base 3.5.0-1 + rtnl_ematch_text_get_to_layer@libnl_3 3.5.0-1 + rtnl_ematch_text_get_to_offset@Base 3.5.0-1 + rtnl_ematch_text_get_to_offset@libnl_3 3.5.0-1 + rtnl_ematch_text_set_algo@Base 3.5.0-1 + rtnl_ematch_text_set_algo@libnl_3 3.5.0-1 + rtnl_ematch_text_set_from@Base 3.5.0-1 + rtnl_ematch_text_set_from@libnl_3 3.5.0-1 + rtnl_ematch_text_set_pattern@Base 3.5.0-1 + rtnl_ematch_text_set_pattern@libnl_3 3.5.0-1 + rtnl_ematch_text_set_to@Base 3.5.0-1 + rtnl_ematch_text_set_to@libnl_3 3.5.0-1 + rtnl_ematch_tree_add@Base 3.5.0-1 + rtnl_ematch_tree_add@libnl_3 3.5.0-1 + rtnl_ematch_tree_alloc@Base 3.5.0-1 + rtnl_ematch_tree_alloc@libnl_3 3.5.0-1 + rtnl_ematch_tree_clone@libnl_3_5 3.5.0-1 + rtnl_ematch_tree_dump@Base 3.5.0-1 + rtnl_ematch_tree_dump@libnl_3 3.5.0-1 + rtnl_ematch_tree_free@Base 3.5.0-1 + rtnl_ematch_tree_free@libnl_3 3.5.0-1 + rtnl_ematch_unlink@Base 3.5.0-1 + rtnl_ematch_unlink@libnl_3 3.5.0-1 + rtnl_ematch_unset_flags@Base 3.5.0-1 + rtnl_ematch_unset_flags@libnl_3 3.5.0-1 + rtnl_fw_set_classid@Base 3.5.0-1 + rtnl_fw_set_classid@libnl_3 3.5.0-1 + rtnl_fw_set_mask@Base 3.5.0-1 + rtnl_fw_set_mask@libnl_3 3.5.0-1 + rtnl_gact_get_action@libnl_3_2_29 3.5.0-1 + rtnl_gact_set_action@libnl_3_2_29 3.5.0-1 + rtnl_htb_get_cbuffer@Base 3.5.0-1 + rtnl_htb_get_cbuffer@libnl_3 3.5.0-1 + rtnl_htb_get_ceil64@libnl_3_5 3.5.0-1 + rtnl_htb_get_ceil@Base 3.5.0-1 + rtnl_htb_get_ceil@libnl_3 3.5.0-1 + rtnl_htb_get_defcls@Base 3.5.0-1 + rtnl_htb_get_defcls@libnl_3 3.5.0-1 + rtnl_htb_get_level@Base 3.5.0-1 + rtnl_htb_get_level@libnl_3 3.5.0-1 + rtnl_htb_get_prio@Base 3.5.0-1 + rtnl_htb_get_prio@libnl_3 3.5.0-1 + rtnl_htb_get_quantum@Base 3.5.0-1 + rtnl_htb_get_quantum@libnl_3 3.5.0-1 + rtnl_htb_get_rate2quantum@Base 3.5.0-1 + rtnl_htb_get_rate2quantum@libnl_3 3.5.0-1 + rtnl_htb_get_rate64@libnl_3_5 3.5.0-1 + rtnl_htb_get_rate@Base 3.5.0-1 + rtnl_htb_get_rate@libnl_3 3.5.0-1 + rtnl_htb_get_rbuffer@Base 3.5.0-1 + rtnl_htb_get_rbuffer@libnl_3 3.5.0-1 + rtnl_htb_set_cbuffer@Base 3.5.0-1 + rtnl_htb_set_cbuffer@libnl_3 3.5.0-1 + rtnl_htb_set_ceil64@libnl_3_5 3.5.0-1 + rtnl_htb_set_ceil@Base 3.5.0-1 + rtnl_htb_set_ceil@libnl_3 3.5.0-1 + rtnl_htb_set_defcls@Base 3.5.0-1 + rtnl_htb_set_defcls@libnl_3 3.5.0-1 + rtnl_htb_set_level@Base 3.5.0-1 + rtnl_htb_set_level@libnl_3 3.5.0-1 + rtnl_htb_set_prio@Base 3.5.0-1 + rtnl_htb_set_prio@libnl_3 3.5.0-1 + rtnl_htb_set_quantum@Base 3.5.0-1 + rtnl_htb_set_quantum@libnl_3 3.5.0-1 + rtnl_htb_set_rate2quantum@Base 3.5.0-1 + rtnl_htb_set_rate2quantum@libnl_3 3.5.0-1 + rtnl_htb_set_rate64@libnl_3_5 3.5.0-1 + rtnl_htb_set_rate@Base 3.5.0-1 + rtnl_htb_set_rate@libnl_3 3.5.0-1 + rtnl_htb_set_rbuffer@Base 3.5.0-1 + rtnl_htb_set_rbuffer@libnl_3 3.5.0-1 + rtnl_link_add@Base 3.5.0-1 + rtnl_link_add@libnl_3 3.5.0-1 + rtnl_link_af_alloc@Base 3.5.0-1 + rtnl_link_af_alloc@libnl_3 3.5.0-1 + rtnl_link_af_data@Base 3.5.0-1 + rtnl_link_af_data@libnl_3 3.5.0-1 + rtnl_link_af_data_compare@Base 3.5.0-1 + rtnl_link_af_data_compare@libnl_3 3.5.0-1 + rtnl_link_af_ops_lookup@Base 3.5.0-1 + rtnl_link_af_ops_lookup@libnl_3 3.5.0-1 + rtnl_link_af_ops_put@Base 3.5.0-1 + rtnl_link_af_ops_put@libnl_3 3.5.0-1 + rtnl_link_af_register@Base 3.5.0-1 + rtnl_link_af_register@libnl_3 3.5.0-1 + rtnl_link_af_unregister@Base 3.5.0-1 + rtnl_link_af_unregister@libnl_3 3.5.0-1 + rtnl_link_alloc@Base 3.5.0-1 + rtnl_link_alloc@libnl_3 3.5.0-1 + rtnl_link_alloc_cache@Base 3.5.0-1 + rtnl_link_alloc_cache@libnl_3 3.5.0-1 + rtnl_link_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_bond_add@Base 3.5.0-1 + rtnl_link_bond_add@libnl_3 3.5.0-1 + rtnl_link_bond_alloc@Base 3.5.0-1 + rtnl_link_bond_alloc@libnl_3 3.5.0-1 + rtnl_link_bond_enslave@Base 3.5.0-1 + rtnl_link_bond_enslave@libnl_3 3.5.0-1 + rtnl_link_bond_enslave_ifindex@Base 3.5.0-1 + rtnl_link_bond_enslave_ifindex@libnl_3 3.5.0-1 + rtnl_link_bond_release@Base 3.5.0-1 + rtnl_link_bond_release@libnl_3 3.5.0-1 + rtnl_link_bond_release_ifindex@Base 3.5.0-1 + rtnl_link_bond_release_ifindex@libnl_3 3.5.0-1 + rtnl_link_bridge_add@Base 3.5.0-1 + rtnl_link_bridge_add@libnl_3 3.5.0-1 + rtnl_link_bridge_alloc@Base 3.5.0-1 + rtnl_link_bridge_alloc@libnl_3 3.5.0-1 + rtnl_link_bridge_flags2str@Base 3.5.0-1 + rtnl_link_bridge_flags2str@libnl_3 3.5.0-1 + rtnl_link_bridge_get_cost@Base 3.5.0-1 + rtnl_link_bridge_get_cost@libnl_3 3.5.0-1 + rtnl_link_bridge_get_flags@Base 3.5.0-1 + rtnl_link_bridge_get_flags@libnl_3 3.5.0-1 + rtnl_link_bridge_get_hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_get_port_state@Base 3.5.0-1 + rtnl_link_bridge_get_port_state@libnl_3 3.5.0-1 + rtnl_link_bridge_get_port_vlan@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_get_priority@Base 3.5.0-1 + rtnl_link_bridge_get_priority@libnl_3 3.5.0-1 + rtnl_link_bridge_has_ext_info@Base 3.5.0-1 + rtnl_link_bridge_has_ext_info@libnl_3 3.5.0-1 + rtnl_link_bridge_has_vlan@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_hwmode2str@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_portstate2str@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_pvid@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_set_cost@Base 3.5.0-1 + rtnl_link_bridge_set_cost@libnl_3 3.5.0-1 + rtnl_link_bridge_set_flags@Base 3.5.0-1 + rtnl_link_bridge_set_flags@libnl_3 3.5.0-1 + rtnl_link_bridge_set_hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_set_port_state@Base 3.5.0-1 + rtnl_link_bridge_set_port_state@libnl_3 3.5.0-1 + rtnl_link_bridge_set_priority@Base 3.5.0-1 + rtnl_link_bridge_set_priority@libnl_3 3.5.0-1 + rtnl_link_bridge_set_self@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_str2flags@Base 3.5.0-1 + rtnl_link_bridge_str2flags@libnl_3 3.5.0-1 + rtnl_link_bridge_str2hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_str2portstate@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_unset_flags@Base 3.5.0-1 + rtnl_link_bridge_unset_flags@libnl_3 3.5.0-1 + rtnl_link_build_add_request@Base 3.5.0-1 + rtnl_link_build_add_request@libnl_3 3.5.0-1 + rtnl_link_build_change_request@Base 3.5.0-1 + rtnl_link_build_change_request@libnl_3 3.5.0-1 + rtnl_link_build_delete_request@Base 3.5.0-1 + rtnl_link_build_delete_request@libnl_3 3.5.0-1 + rtnl_link_build_get_request@Base 3.5.0-1 + rtnl_link_build_get_request@libnl_3 3.5.0-1 + rtnl_link_can_berr@Base 3.5.0-1 + rtnl_link_can_berr@libnl_3 3.5.0-1 + rtnl_link_can_berr_rx@Base 3.5.0-1 + rtnl_link_can_berr_rx@libnl_3 3.5.0-1 + rtnl_link_can_berr_tx@Base 3.5.0-1 + rtnl_link_can_berr_tx@libnl_3 3.5.0-1 + rtnl_link_can_ctrlmode2str@Base 3.5.0-1 + rtnl_link_can_ctrlmode2str@libnl_3 3.5.0-1 + rtnl_link_can_freq@Base 3.5.0-1 + rtnl_link_can_freq@libnl_3 3.5.0-1 + rtnl_link_can_get_bitrate@Base 3.5.0-1 + rtnl_link_can_get_bitrate@libnl_3 3.5.0-1 + rtnl_link_can_get_bittiming@Base 3.5.0-1 + rtnl_link_can_get_bittiming@libnl_3 3.5.0-1 + rtnl_link_can_get_bt_const@Base 3.5.0-1 + rtnl_link_can_get_bt_const@libnl_3 3.5.0-1 + rtnl_link_can_get_ctrlmode@Base 3.5.0-1 + rtnl_link_can_get_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_get_restart_ms@Base 3.5.0-1 + rtnl_link_can_get_restart_ms@libnl_3 3.5.0-1 + rtnl_link_can_get_sample_point@Base 3.5.0-1 + rtnl_link_can_get_sample_point@libnl_3 3.5.0-1 + rtnl_link_can_restart@Base 3.5.0-1 + rtnl_link_can_restart@libnl_3 3.5.0-1 + rtnl_link_can_set_bitrate@Base 3.5.0-1 + rtnl_link_can_set_bitrate@libnl_3 3.5.0-1 + rtnl_link_can_set_bittiming@Base 3.5.0-1 + rtnl_link_can_set_bittiming@libnl_3 3.5.0-1 + rtnl_link_can_set_ctrlmode@Base 3.5.0-1 + rtnl_link_can_set_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_set_restart_ms@Base 3.5.0-1 + rtnl_link_can_set_restart_ms@libnl_3 3.5.0-1 + rtnl_link_can_set_sample_point@Base 3.5.0-1 + rtnl_link_can_set_sample_point@libnl_3 3.5.0-1 + rtnl_link_can_state@Base 3.5.0-1 + rtnl_link_can_state@libnl_3 3.5.0-1 + rtnl_link_can_str2ctrlmode@Base 3.5.0-1 + rtnl_link_can_str2ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_unset_ctrlmode@Base 3.5.0-1 + rtnl_link_can_unset_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_carrier2str@Base 3.5.0-1 + rtnl_link_carrier2str@libnl_3 3.5.0-1 + rtnl_link_change@Base 3.5.0-1 + rtnl_link_change@libnl_3 3.5.0-1 + rtnl_link_delete@Base 3.5.0-1 + rtnl_link_delete@libnl_3 3.5.0-1 + rtnl_link_enslave@Base 3.5.0-1 + rtnl_link_enslave@libnl_3 3.5.0-1 + rtnl_link_enslave_ifindex@Base 3.5.0-1 + rtnl_link_enslave_ifindex@libnl_3 3.5.0-1 + rtnl_link_fill_info@Base 3.5.0-1 + rtnl_link_fill_info@libnl_3 3.5.0-1 + rtnl_link_flags2str@Base 3.5.0-1 + rtnl_link_flags2str@libnl_3 3.5.0-1 + rtnl_link_geneve_alloc@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_flags@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_id@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_label@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_port@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_remote@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_tos@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_ttl@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_csum@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_zero_csum6_rx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_zero_csum6_tx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_flags@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_id@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_label@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_port@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_remote@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_tos@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_ttl@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_csum@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_zero_csum6_rx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_zero_csum6_tx@libnl_3_5 3.5.0-1 + rtnl_link_get@Base 3.5.0-1 + rtnl_link_get@libnl_3 3.5.0-1 + rtnl_link_get_addr@Base 3.5.0-1 + rtnl_link_get_addr@libnl_3 3.5.0-1 + rtnl_link_get_arptype@Base 3.5.0-1 + rtnl_link_get_arptype@libnl_3 3.5.0-1 + rtnl_link_get_broadcast@Base 3.5.0-1 + rtnl_link_get_broadcast@libnl_3 3.5.0-1 + rtnl_link_get_by_name@Base 3.5.0-1 + rtnl_link_get_by_name@libnl_3 3.5.0-1 + rtnl_link_get_carrier@Base 3.5.0-1 + rtnl_link_get_carrier@libnl_3 3.5.0-1 + rtnl_link_get_carrier_changes@libnl_3_2_29 3.5.0-1 + rtnl_link_get_family@Base 3.5.0-1 + rtnl_link_get_family@libnl_3 3.5.0-1 + rtnl_link_get_flags@Base 3.5.0-1 + rtnl_link_get_flags@libnl_3 3.5.0-1 + rtnl_link_get_group@Base 3.5.0-1 + rtnl_link_get_group@libnl_3 3.5.0-1 + rtnl_link_get_gso_max_segs@libnl_3_2_29 3.5.0-1 + rtnl_link_get_gso_max_size@libnl_3_2_29 3.5.0-1 + rtnl_link_get_ifalias@Base 3.5.0-1 + rtnl_link_get_ifalias@libnl_3 3.5.0-1 + rtnl_link_get_ifindex@Base 3.5.0-1 + rtnl_link_get_ifindex@libnl_3 3.5.0-1 + rtnl_link_get_info_type@Base 3.5.0-1 + rtnl_link_get_info_type@libnl_3 3.5.0-1 + rtnl_link_get_kernel@Base 3.5.0-1 + rtnl_link_get_kernel@libnl_3 3.5.0-1 + rtnl_link_get_link@Base 3.5.0-1 + rtnl_link_get_link@libnl_3 3.5.0-1 + rtnl_link_get_link_netnsid@Base 3.5.0-1 + rtnl_link_get_link_netnsid@libnl_3_2_27 3.5.0-1 + rtnl_link_get_linkmode@Base 3.5.0-1 + rtnl_link_get_linkmode@libnl_3 3.5.0-1 + rtnl_link_get_master@Base 3.5.0-1 + rtnl_link_get_master@libnl_3 3.5.0-1 + rtnl_link_get_mtu@Base 3.5.0-1 + rtnl_link_get_mtu@libnl_3 3.5.0-1 + rtnl_link_get_name@Base 3.5.0-1 + rtnl_link_get_name@libnl_3 3.5.0-1 + rtnl_link_get_ns_fd@Base 3.5.0-1 + rtnl_link_get_ns_fd@libnl_3 3.5.0-1 + rtnl_link_get_ns_pid@Base 3.5.0-1 + rtnl_link_get_ns_pid@libnl_3 3.5.0-1 + rtnl_link_get_num_rx_queues@Base 3.5.0-1 + rtnl_link_get_num_rx_queues@libnl_3 3.5.0-1 + rtnl_link_get_num_tx_queues@Base 3.5.0-1 + rtnl_link_get_num_tx_queues@libnl_3 3.5.0-1 + rtnl_link_get_num_vf@Base 3.5.0-1 + rtnl_link_get_num_vf@libnl_3 3.5.0-1 + rtnl_link_get_operstate@Base 3.5.0-1 + rtnl_link_get_operstate@libnl_3 3.5.0-1 + rtnl_link_get_phys_port_id@Base 3.5.0-1 + rtnl_link_get_phys_port_id@libnl_3 3.5.0-1 + rtnl_link_get_phys_port_name@libnl_3_2_29 3.5.0-1 + rtnl_link_get_phys_switch_id@libnl_3_2_29 3.5.0-1 + rtnl_link_get_pmtudisc@Base 3.5.0-1 + rtnl_link_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_get_promiscuity@Base 3.5.0-1 + rtnl_link_get_promiscuity@libnl_3 3.5.0-1 + rtnl_link_get_qdisc@Base 3.5.0-1 + rtnl_link_get_qdisc@libnl_3 3.5.0-1 + rtnl_link_get_slave_type@libnl_3_5 3.5.0-1 + rtnl_link_get_stat@Base 3.5.0-1 + rtnl_link_get_stat@libnl_3 3.5.0-1 + rtnl_link_get_txqlen@Base 3.5.0-1 + rtnl_link_get_txqlen@libnl_3 3.5.0-1 + rtnl_link_get_type@Base 3.5.0-1 + rtnl_link_get_type@libnl_3 3.5.0-1 + rtnl_link_get_weight@Base 3.5.0-1 + rtnl_link_get_weight@libnl_3 3.5.0-1 + rtnl_link_has_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_i2name@Base 3.5.0-1 + rtnl_link_i2name@libnl_3 3.5.0-1 + rtnl_link_inet6_addrgenmode2str@Base 3.5.0-1 + rtnl_link_inet6_addrgenmode2str@libnl_3 3.5.0-1 + rtnl_link_inet6_flags2str@libnl_3_4 3.5.0-1 + rtnl_link_inet6_get_addr_gen_mode@Base 3.5.0-1 + rtnl_link_inet6_get_addr_gen_mode@libnl_3 3.5.0-1 + rtnl_link_inet6_get_flags@libnl_3_4 3.5.0-1 + rtnl_link_inet6_get_token@Base 3.5.0-1 + rtnl_link_inet6_get_token@libnl_3 3.5.0-1 + rtnl_link_inet6_set_addr_gen_mode@Base 3.5.0-1 + rtnl_link_inet6_set_addr_gen_mode@libnl_3 3.5.0-1 + rtnl_link_inet6_set_flags@libnl_3_4 3.5.0-1 + rtnl_link_inet6_set_token@Base 3.5.0-1 + rtnl_link_inet6_set_token@libnl_3 3.5.0-1 + rtnl_link_inet6_str2addrgenmode@Base 3.5.0-1 + rtnl_link_inet6_str2addrgenmode@libnl_3 3.5.0-1 + rtnl_link_inet6_str2flags@libnl_3_4 3.5.0-1 + rtnl_link_inet_devconf2str@Base 3.5.0-1 + rtnl_link_inet_devconf2str@libnl_3 3.5.0-1 + rtnl_link_inet_get_conf@Base 3.5.0-1 + rtnl_link_inet_get_conf@libnl_3 3.5.0-1 + rtnl_link_inet_set_conf@Base 3.5.0-1 + rtnl_link_inet_set_conf@libnl_3 3.5.0-1 + rtnl_link_inet_str2devconf@Base 3.5.0-1 + rtnl_link_inet_str2devconf@libnl_3 3.5.0-1 + rtnl_link_info_ops_lookup@Base 3.5.0-1 + rtnl_link_info_ops_lookup@libnl_3 3.5.0-1 + rtnl_link_info_ops_put@Base 3.5.0-1 + rtnl_link_info_ops_put@libnl_3 3.5.0-1 + rtnl_link_info_parse@Base 3.5.0-1 + rtnl_link_info_parse@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_add@Base 3.5.0-1 + rtnl_link_ip6_tnl_add@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_alloc@Base 3.5.0-1 + rtnl_link_ip6_tnl_alloc@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_encaplimit@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_encaplimit@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_flags@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_flags@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_flowinfo@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_flowinfo@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_link@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_link@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_local@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_local@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_proto@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_proto@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_remote@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_remote@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_tos@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_tos@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_ttl@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_encaplimit@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_encaplimit@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_flags@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_flags@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_flowinfo@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_flowinfo@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_link@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_link@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_local@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_local@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_proto@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_proto@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_remote@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_remote@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_tos@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_tos@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_ttl@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgre_add@Base 3.5.0-1 + rtnl_link_ipgre_add@libnl_3 3.5.0-1 + rtnl_link_ipgre_alloc@Base 3.5.0-1 + rtnl_link_ipgre_alloc@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_iflags@Base 3.5.0-1 + rtnl_link_ipgre_get_iflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_ikey@Base 3.5.0-1 + rtnl_link_ipgre_get_ikey@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_link@Base 3.5.0-1 + rtnl_link_ipgre_get_link@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_local@Base 3.5.0-1 + rtnl_link_ipgre_get_local@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_oflags@Base 3.5.0-1 + rtnl_link_ipgre_get_oflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_okey@Base 3.5.0-1 + rtnl_link_ipgre_get_okey@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_pmtudisc@libnl_3_2_29 3.5.0-1 + rtnl_link_ipgre_get_remote@Base 3.5.0-1 + rtnl_link_ipgre_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_tos@Base 3.5.0-1 + rtnl_link_ipgre_get_tos@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_ttl@Base 3.5.0-1 + rtnl_link_ipgre_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_iflags@Base 3.5.0-1 + rtnl_link_ipgre_set_iflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_ikey@Base 3.5.0-1 + rtnl_link_ipgre_set_ikey@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_link@Base 3.5.0-1 + rtnl_link_ipgre_set_link@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_local@Base 3.5.0-1 + rtnl_link_ipgre_set_local@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_oflags@Base 3.5.0-1 + rtnl_link_ipgre_set_oflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_okey@Base 3.5.0-1 + rtnl_link_ipgre_set_okey@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_pmtudisc@Base 3.5.0-1 + rtnl_link_ipgre_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_remote@Base 3.5.0-1 + rtnl_link_ipgre_set_remote@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_tos@Base 3.5.0-1 + rtnl_link_ipgre_set_tos@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_ttl@Base 3.5.0-1 + rtnl_link_ipgre_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgretap_add@libnl_3_2_28 3.5.0-1 + rtnl_link_ipgretap_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_ipip_add@Base 3.5.0-1 + rtnl_link_ipip_add@libnl_3 3.5.0-1 + rtnl_link_ipip_alloc@Base 3.5.0-1 + rtnl_link_ipip_alloc@libnl_3 3.5.0-1 + rtnl_link_ipip_get_link@Base 3.5.0-1 + rtnl_link_ipip_get_link@libnl_3 3.5.0-1 + rtnl_link_ipip_get_local@Base 3.5.0-1 + rtnl_link_ipip_get_local@libnl_3 3.5.0-1 + rtnl_link_ipip_get_pmtudisc@Base 3.5.0-1 + rtnl_link_ipip_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipip_get_remote@Base 3.5.0-1 + rtnl_link_ipip_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipip_get_tos@Base 3.5.0-1 + rtnl_link_ipip_get_tos@libnl_3 3.5.0-1 + rtnl_link_ipip_get_ttl@Base 3.5.0-1 + rtnl_link_ipip_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ipip_set_link@Base 3.5.0-1 + rtnl_link_ipip_set_link@libnl_3 3.5.0-1 + rtnl_link_ipip_set_local@Base 3.5.0-1 + rtnl_link_ipip_set_local@libnl_3 3.5.0-1 + rtnl_link_ipip_set_pmtudisc@Base 3.5.0-1 + rtnl_link_ipip_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipip_set_remote@Base 3.5.0-1 + rtnl_link_ipip_set_remote@libnl_3 3.5.0-1 + rtnl_link_ipip_set_tos@Base 3.5.0-1 + rtnl_link_ipip_set_tos@libnl_3 3.5.0-1 + rtnl_link_ipip_set_ttl@Base 3.5.0-1 + rtnl_link_ipip_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipvlan_alloc@Base 3.5.0-1 + rtnl_link_ipvlan_alloc@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_get_mode@Base 3.5.0-1 + rtnl_link_ipvlan_get_mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_mode2str@Base 3.5.0-1 + rtnl_link_ipvlan_mode2str@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_set_mode@Base 3.5.0-1 + rtnl_link_ipvlan_set_mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_str2mode@Base 3.5.0-1 + rtnl_link_ipvlan_str2mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvti_add@Base 3.5.0-1 + rtnl_link_ipvti_add@libnl_3 3.5.0-1 + rtnl_link_ipvti_alloc@Base 3.5.0-1 + rtnl_link_ipvti_alloc@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_ikey@Base 3.5.0-1 + rtnl_link_ipvti_get_ikey@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_link@Base 3.5.0-1 + rtnl_link_ipvti_get_link@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_local@Base 3.5.0-1 + rtnl_link_ipvti_get_local@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_okey@Base 3.5.0-1 + rtnl_link_ipvti_get_okey@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_remote@Base 3.5.0-1 + rtnl_link_ipvti_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_ikey@Base 3.5.0-1 + rtnl_link_ipvti_set_ikey@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_link@Base 3.5.0-1 + rtnl_link_ipvti_set_link@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_local@Base 3.5.0-1 + rtnl_link_ipvti_set_local@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_okey@Base 3.5.0-1 + rtnl_link_ipvti_set_okey@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_remote@Base 3.5.0-1 + rtnl_link_ipvti_set_remote@libnl_3 3.5.0-1 + rtnl_link_is_bridge@Base 3.5.0-1 + rtnl_link_is_bridge@libnl_3 3.5.0-1 + rtnl_link_is_can@Base 3.5.0-1 + rtnl_link_is_can@libnl_3 3.5.0-1 + rtnl_link_is_geneve@libnl_3_5 3.5.0-1 + rtnl_link_is_ip6_tnl@Base 3.5.0-1 + rtnl_link_is_ip6_tnl@libnl_3 3.5.0-1 + rtnl_link_is_ipgre@Base 3.5.0-1 + rtnl_link_is_ipgre@libnl_3 3.5.0-1 + rtnl_link_is_ipgretap@libnl_3_2_29 3.5.0-1 + rtnl_link_is_ipip@Base 3.5.0-1 + rtnl_link_is_ipip@libnl_3 3.5.0-1 + rtnl_link_is_ipvlan@Base 3.5.0-1 + rtnl_link_is_ipvlan@libnl_3_2_27 3.5.0-1 + rtnl_link_is_ipvti@Base 3.5.0-1 + rtnl_link_is_ipvti@libnl_3 3.5.0-1 + rtnl_link_is_macvlan@Base 3.5.0-1 + rtnl_link_is_macvlan@libnl_3 3.5.0-1 + rtnl_link_is_macvtap@libnl_3_2_28 3.5.0-1 + rtnl_link_is_sit@Base 3.5.0-1 + rtnl_link_is_sit@libnl_3 3.5.0-1 + rtnl_link_is_veth@Base 3.5.0-1 + rtnl_link_is_veth@libnl_3 3.5.0-1 + rtnl_link_is_vlan@Base 3.5.0-1 + rtnl_link_is_vlan@libnl_3 3.5.0-1 + rtnl_link_is_vrf@libnl_3_2_28 3.5.0-1 + rtnl_link_is_vxlan@Base 3.5.0-1 + rtnl_link_is_vxlan@libnl_3 3.5.0-1 + rtnl_link_is_xfrmi@libnl_3_5 3.5.0-1 + rtnl_link_macsec_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_cipher_suite@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_encoding_sa@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_encrypt@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_end_station@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_icv_len@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_port@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_replay_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_scb@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_send_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_validation_type@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_window@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_cipher_suite@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_encoding_sa@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_encrypt@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_end_station@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_icv_len@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_port@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_replay_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_scb@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_send_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_validation_type@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_window@libnl_3_2_28 3.5.0-1 + rtnl_link_macvlan_add_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_alloc@Base 3.5.0-1 + rtnl_link_macvlan_alloc@libnl_3 3.5.0-1 + rtnl_link_macvlan_count_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_del_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_flags2str@Base 3.5.0-1 + rtnl_link_macvlan_flags2str@libnl_3 3.5.0-1 + rtnl_link_macvlan_get_flags@Base 3.5.0-1 + rtnl_link_macvlan_get_flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_get_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_get_macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_get_mode@Base 3.5.0-1 + rtnl_link_macvlan_get_mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_macmode2str@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_mode2str@Base 3.5.0-1 + rtnl_link_macvlan_mode2str@libnl_3 3.5.0-1 + rtnl_link_macvlan_set_flags@Base 3.5.0-1 + rtnl_link_macvlan_set_flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_set_macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_set_mode@Base 3.5.0-1 + rtnl_link_macvlan_set_mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_str2flags@Base 3.5.0-1 + rtnl_link_macvlan_str2flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_str2macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_str2mode@Base 3.5.0-1 + rtnl_link_macvlan_str2mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_unset_flags@Base 3.5.0-1 + rtnl_link_macvlan_unset_flags@libnl_3 3.5.0-1 + rtnl_link_macvtap_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_flags2str@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_get_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_get_mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_mode2str@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_set_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_set_mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_str2flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_str2mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_unset_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_mode2str@Base 3.5.0-1 + rtnl_link_mode2str@libnl_3 3.5.0-1 + rtnl_link_name2i@Base 3.5.0-1 + rtnl_link_name2i@libnl_3 3.5.0-1 + rtnl_link_operstate2str@Base 3.5.0-1 + rtnl_link_operstate2str@libnl_3 3.5.0-1 + rtnl_link_ppp_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_ppp_get_fd@libnl_3_2_29 3.5.0-1 + rtnl_link_ppp_set_fd@libnl_3_2_29 3.5.0-1 + rtnl_link_put@Base 3.5.0-1 + rtnl_link_put@libnl_3 3.5.0-1 + rtnl_link_register_info@Base 3.5.0-1 + rtnl_link_register_info@libnl_3 3.5.0-1 + rtnl_link_release@Base 3.5.0-1 + rtnl_link_release@libnl_3 3.5.0-1 + rtnl_link_release_ifindex@Base 3.5.0-1 + rtnl_link_release_ifindex@libnl_3 3.5.0-1 + rtnl_link_set_addr@Base 3.5.0-1 + rtnl_link_set_addr@libnl_3 3.5.0-1 + rtnl_link_set_arptype@Base 3.5.0-1 + rtnl_link_set_arptype@libnl_3 3.5.0-1 + rtnl_link_set_broadcast@Base 3.5.0-1 + rtnl_link_set_broadcast@libnl_3 3.5.0-1 + rtnl_link_set_carrier@Base 3.5.0-1 + rtnl_link_set_carrier@libnl_3 3.5.0-1 + rtnl_link_set_family@Base 3.5.0-1 + rtnl_link_set_family@libnl_3 3.5.0-1 + rtnl_link_set_flags@Base 3.5.0-1 + rtnl_link_set_flags@libnl_3 3.5.0-1 + rtnl_link_set_group@Base 3.5.0-1 + rtnl_link_set_group@libnl_3 3.5.0-1 + rtnl_link_set_ifalias@Base 3.5.0-1 + rtnl_link_set_ifalias@libnl_3 3.5.0-1 + rtnl_link_set_ifindex@Base 3.5.0-1 + rtnl_link_set_ifindex@libnl_3 3.5.0-1 + rtnl_link_set_info_type@Base 3.5.0-1 + rtnl_link_set_info_type@libnl_3 3.5.0-1 + rtnl_link_set_link@Base 3.5.0-1 + rtnl_link_set_link@libnl_3 3.5.0-1 + rtnl_link_set_link_netnsid@Base 3.5.0-1 + rtnl_link_set_link_netnsid@libnl_3_2_27 3.5.0-1 + rtnl_link_set_linkmode@Base 3.5.0-1 + rtnl_link_set_linkmode@libnl_3 3.5.0-1 + rtnl_link_set_master@Base 3.5.0-1 + rtnl_link_set_master@libnl_3 3.5.0-1 + rtnl_link_set_mtu@Base 3.5.0-1 + rtnl_link_set_mtu@libnl_3 3.5.0-1 + rtnl_link_set_name@Base 3.5.0-1 + rtnl_link_set_name@libnl_3 3.5.0-1 + rtnl_link_set_ns_fd@Base 3.5.0-1 + rtnl_link_set_ns_fd@libnl_3 3.5.0-1 + rtnl_link_set_ns_pid@Base 3.5.0-1 + rtnl_link_set_ns_pid@libnl_3 3.5.0-1 + rtnl_link_set_num_rx_queues@Base 3.5.0-1 + rtnl_link_set_num_rx_queues@libnl_3 3.5.0-1 + rtnl_link_set_num_tx_queues@Base 3.5.0-1 + rtnl_link_set_num_tx_queues@libnl_3 3.5.0-1 + rtnl_link_set_operstate@Base 3.5.0-1 + rtnl_link_set_operstate@libnl_3 3.5.0-1 + rtnl_link_set_promiscuity@Base 3.5.0-1 + rtnl_link_set_promiscuity@libnl_3 3.5.0-1 + rtnl_link_set_qdisc@Base 3.5.0-1 + rtnl_link_set_qdisc@libnl_3 3.5.0-1 + rtnl_link_set_slave_type@libnl_3_5 3.5.0-1 + rtnl_link_set_stat@Base 3.5.0-1 + rtnl_link_set_stat@libnl_3 3.5.0-1 + rtnl_link_set_txqlen@Base 3.5.0-1 + rtnl_link_set_txqlen@libnl_3 3.5.0-1 + rtnl_link_set_type@Base 3.5.0-1 + rtnl_link_set_type@libnl_3 3.5.0-1 + rtnl_link_set_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_set_weight@Base 3.5.0-1 + rtnl_link_set_weight@libnl_3 3.5.0-1 + rtnl_link_sit_add@Base 3.5.0-1 + rtnl_link_sit_add@libnl_3 3.5.0-1 + rtnl_link_sit_alloc@Base 3.5.0-1 + rtnl_link_sit_alloc@libnl_3 3.5.0-1 + rtnl_link_sit_get_flags@Base 3.5.0-1 + rtnl_link_sit_get_flags@libnl_3 3.5.0-1 + rtnl_link_sit_get_ip6rd_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_relay_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_relay_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_link@Base 3.5.0-1 + rtnl_link_sit_get_link@libnl_3 3.5.0-1 + rtnl_link_sit_get_local@Base 3.5.0-1 + rtnl_link_sit_get_local@libnl_3 3.5.0-1 + rtnl_link_sit_get_pmtudisc@Base 3.5.0-1 + rtnl_link_sit_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_sit_get_proto@Base 3.5.0-1 + rtnl_link_sit_get_proto@libnl_3 3.5.0-1 + rtnl_link_sit_get_remote@Base 3.5.0-1 + rtnl_link_sit_get_remote@libnl_3 3.5.0-1 + rtnl_link_sit_get_tos@Base 3.5.0-1 + rtnl_link_sit_get_tos@libnl_3 3.5.0-1 + rtnl_link_sit_get_ttl@Base 3.5.0-1 + rtnl_link_sit_get_ttl@libnl_3 3.5.0-1 + rtnl_link_sit_set_flags@Base 3.5.0-1 + rtnl_link_sit_set_flags@libnl_3 3.5.0-1 + rtnl_link_sit_set_ip6rd_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_relay_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_relay_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_link@Base 3.5.0-1 + rtnl_link_sit_set_link@libnl_3 3.5.0-1 + rtnl_link_sit_set_local@Base 3.5.0-1 + rtnl_link_sit_set_local@libnl_3 3.5.0-1 + rtnl_link_sit_set_pmtudisc@Base 3.5.0-1 + rtnl_link_sit_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_sit_set_proto@Base 3.5.0-1 + rtnl_link_sit_set_proto@libnl_3 3.5.0-1 + rtnl_link_sit_set_remote@Base 3.5.0-1 + rtnl_link_sit_set_remote@libnl_3 3.5.0-1 + rtnl_link_sit_set_tos@Base 3.5.0-1 + rtnl_link_sit_set_tos@libnl_3 3.5.0-1 + rtnl_link_sit_set_ttl@Base 3.5.0-1 + rtnl_link_sit_set_ttl@libnl_3 3.5.0-1 + rtnl_link_stat2str@Base 3.5.0-1 + rtnl_link_stat2str@libnl_3 3.5.0-1 + rtnl_link_str2carrier@Base 3.5.0-1 + rtnl_link_str2carrier@libnl_3 3.5.0-1 + rtnl_link_str2flags@Base 3.5.0-1 + rtnl_link_str2flags@libnl_3 3.5.0-1 + rtnl_link_str2mode@Base 3.5.0-1 + rtnl_link_str2mode@libnl_3 3.5.0-1 + rtnl_link_str2operstate@Base 3.5.0-1 + rtnl_link_str2operstate@libnl_3 3.5.0-1 + rtnl_link_str2stat@Base 3.5.0-1 + rtnl_link_str2stat@libnl_3 3.5.0-1 + rtnl_link_unregister_info@Base 3.5.0-1 + rtnl_link_unregister_info@libnl_3 3.5.0-1 + rtnl_link_unset_flags@Base 3.5.0-1 + rtnl_link_unset_flags@libnl_3 3.5.0-1 + rtnl_link_unset_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_veth_add@Base 3.5.0-1 + rtnl_link_veth_add@libnl_3 3.5.0-1 + rtnl_link_veth_alloc@Base 3.5.0-1 + rtnl_link_veth_alloc@libnl_3 3.5.0-1 + rtnl_link_veth_get_peer@Base 3.5.0-1 + rtnl_link_veth_get_peer@libnl_3 3.5.0-1 + rtnl_link_veth_release@Base 3.5.0-1 + rtnl_link_veth_release@libnl_3 3.5.0-1 + rtnl_link_vf_add@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_free@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_addr@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_index@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_rate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_rss_query_en@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_spoofchk@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_stat@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_trust@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_vlans@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_linkstate2str@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_put@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_addr@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_ib_node_guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_ib_port_guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_index@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_rate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_rss_query_en@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_spoofchk@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_trust@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_vlans@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2vlanproto@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_free@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_put@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlanproto2str@libnl_3_2_29 3.5.0-1 + rtnl_link_vlan_alloc@Base 3.5.0-1 + rtnl_link_vlan_alloc@libnl_3 3.5.0-1 + rtnl_link_vlan_flags2str@Base 3.5.0-1 + rtnl_link_vlan_flags2str@libnl_3 3.5.0-1 + rtnl_link_vlan_get_egress_map@Base 3.5.0-1 + rtnl_link_vlan_get_egress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_get_flags@Base 3.5.0-1 + rtnl_link_vlan_get_flags@libnl_3 3.5.0-1 + rtnl_link_vlan_get_id@Base 3.5.0-1 + rtnl_link_vlan_get_id@libnl_3 3.5.0-1 + rtnl_link_vlan_get_ingress_map@Base 3.5.0-1 + rtnl_link_vlan_get_ingress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_get_protocol@Base 3.5.0-1 + rtnl_link_vlan_get_protocol@libnl_3 3.5.0-1 + rtnl_link_vlan_set_egress_map@Base 3.5.0-1 + rtnl_link_vlan_set_egress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_set_flags@Base 3.5.0-1 + rtnl_link_vlan_set_flags@libnl_3 3.5.0-1 + rtnl_link_vlan_set_id@Base 3.5.0-1 + rtnl_link_vlan_set_id@libnl_3 3.5.0-1 + rtnl_link_vlan_set_ingress_map@Base 3.5.0-1 + rtnl_link_vlan_set_ingress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_set_protocol@Base 3.5.0-1 + rtnl_link_vlan_set_protocol@libnl_3 3.5.0-1 + rtnl_link_vlan_str2flags@Base 3.5.0-1 + rtnl_link_vlan_str2flags@libnl_3 3.5.0-1 + rtnl_link_vlan_unset_flags@Base 3.5.0-1 + rtnl_link_vlan_unset_flags@libnl_3 3.5.0-1 + rtnl_link_vrf_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_vrf_get_tableid@libnl_3_2_28 3.5.0-1 + rtnl_link_vrf_set_tableid@libnl_3_2_28 3.5.0-1 + rtnl_link_vxlan_alloc@Base 3.5.0-1 + rtnl_link_vxlan_alloc@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_disable_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_disable_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_learning@Base 3.5.0-1 + rtnl_link_vxlan_disable_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_proxy@Base 3.5.0-1 + rtnl_link_vxlan_disable_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_rsc@Base 3.5.0-1 + rtnl_link_vxlan_disable_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_enable_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_enable_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_learning@Base 3.5.0-1 + rtnl_link_vxlan_enable_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_proxy@Base 3.5.0-1 + rtnl_link_vxlan_enable_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_rsc@Base 3.5.0-1 + rtnl_link_vxlan_enable_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_ageing@Base 3.5.0-1 + rtnl_link_vxlan_get_ageing@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_collect_metadata@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_flags@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_group@Base 3.5.0-1 + rtnl_link_vxlan_get_group@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_id@Base 3.5.0-1 + rtnl_link_vxlan_get_id@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_get_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_get_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_label@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_learning@Base 3.5.0-1 + rtnl_link_vxlan_get_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_limit@Base 3.5.0-1 + rtnl_link_vxlan_get_limit@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_link@Base 3.5.0-1 + rtnl_link_vxlan_get_link@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_local@Base 3.5.0-1 + rtnl_link_vxlan_get_local@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_port@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_port_range@Base 3.5.0-1 + rtnl_link_vxlan_get_port_range@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_proxy@Base 3.5.0-1 + rtnl_link_vxlan_get_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_remcsum_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_remcsum_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_rsc@Base 3.5.0-1 + rtnl_link_vxlan_get_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_tos@Base 3.5.0-1 + rtnl_link_vxlan_get_tos@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_ttl@Base 3.5.0-1 + rtnl_link_vxlan_get_ttl@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_udp_csum@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_udp_zero_csum6_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_udp_zero_csum6_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_ageing@Base 3.5.0-1 + rtnl_link_vxlan_set_ageing@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_collect_metadata@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_flags@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_group@Base 3.5.0-1 + rtnl_link_vxlan_set_group@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_id@Base 3.5.0-1 + rtnl_link_vxlan_set_id@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_set_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_set_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_label@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_learning@Base 3.5.0-1 + rtnl_link_vxlan_set_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_limit@Base 3.5.0-1 + rtnl_link_vxlan_set_limit@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_link@Base 3.5.0-1 + rtnl_link_vxlan_set_link@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_local@Base 3.5.0-1 + rtnl_link_vxlan_set_local@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_port@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_port_range@Base 3.5.0-1 + rtnl_link_vxlan_set_port_range@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_proxy@Base 3.5.0-1 + rtnl_link_vxlan_set_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_remcsum_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_remcsum_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_rsc@Base 3.5.0-1 + rtnl_link_vxlan_set_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_tos@Base 3.5.0-1 + rtnl_link_vxlan_set_tos@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_ttl@Base 3.5.0-1 + rtnl_link_vxlan_set_ttl@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_udp_csum@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_udp_zero_csum6_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_udp_zero_csum6_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_xfrmi_alloc@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_get_if_id@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_get_link@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_set_if_id@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_set_link@libnl_3_5 3.5.0-1 + rtnl_mall_append_action@libnl_3_5 3.5.0-1 + rtnl_mall_del_action@libnl_3_5 3.5.0-1 + rtnl_mall_get_classid@libnl_3_5 3.5.0-1 + rtnl_mall_get_first_action@libnl_3_5 3.5.0-1 + rtnl_mall_get_flags@libnl_3_5 3.5.0-1 + rtnl_mall_set_classid@libnl_3_5 3.5.0-1 + rtnl_mall_set_flags@libnl_3_5 3.5.0-1 + rtnl_meta_value_alloc_id@Base 3.5.0-1 + rtnl_meta_value_alloc_id@libnl_3 3.5.0-1 + rtnl_meta_value_alloc_int@Base 3.5.0-1 + rtnl_meta_value_alloc_int@libnl_3 3.5.0-1 + rtnl_meta_value_alloc_var@Base 3.5.0-1 + rtnl_meta_value_alloc_var@libnl_3 3.5.0-1 + rtnl_meta_value_put@Base 3.5.0-1 + rtnl_meta_value_put@libnl_3 3.5.0-1 + rtnl_mirred_get_action@Base 3.5.0-1 + rtnl_mirred_get_action@libnl_3 3.5.0-1 + rtnl_mirred_get_ifindex@Base 3.5.0-1 + rtnl_mirred_get_ifindex@libnl_3 3.5.0-1 + rtnl_mirred_get_policy@Base 3.5.0-1 + rtnl_mirred_get_policy@libnl_3 3.5.0-1 + rtnl_mirred_set_action@Base 3.5.0-1 + rtnl_mirred_set_action@libnl_3 3.5.0-1 + rtnl_mirred_set_ifindex@Base 3.5.0-1 + rtnl_mirred_set_ifindex@libnl_3 3.5.0-1 + rtnl_mirred_set_policy@Base 3.5.0-1 + rtnl_mirred_set_policy@libnl_3 3.5.0-1 + rtnl_neigh_add@Base 3.5.0-1 + rtnl_neigh_add@libnl_3 3.5.0-1 + rtnl_neigh_alloc@Base 3.5.0-1 + rtnl_neigh_alloc@libnl_3 3.5.0-1 + rtnl_neigh_alloc_cache@Base 3.5.0-1 + rtnl_neigh_alloc_cache@libnl_3 3.5.0-1 + rtnl_neigh_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + rtnl_neigh_build_add_request@Base 3.5.0-1 + rtnl_neigh_build_add_request@libnl_3 3.5.0-1 + rtnl_neigh_build_delete_request@Base 3.5.0-1 + rtnl_neigh_build_delete_request@libnl_3 3.5.0-1 + rtnl_neigh_delete@Base 3.5.0-1 + rtnl_neigh_delete@libnl_3 3.5.0-1 + rtnl_neigh_flags2str@Base 3.5.0-1 + rtnl_neigh_flags2str@libnl_3 3.5.0-1 + rtnl_neigh_get@Base 3.5.0-1 + rtnl_neigh_get@libnl_3 3.5.0-1 + rtnl_neigh_get_by_vlan@libnl_3_5 3.5.0-1 + rtnl_neigh_get_dst@Base 3.5.0-1 + rtnl_neigh_get_dst@libnl_3 3.5.0-1 + rtnl_neigh_get_family@Base 3.5.0-1 + rtnl_neigh_get_family@libnl_3 3.5.0-1 + rtnl_neigh_get_flags@Base 3.5.0-1 + rtnl_neigh_get_flags@libnl_3 3.5.0-1 + rtnl_neigh_get_ifindex@Base 3.5.0-1 + rtnl_neigh_get_ifindex@libnl_3 3.5.0-1 + rtnl_neigh_get_lladdr@Base 3.5.0-1 + rtnl_neigh_get_lladdr@libnl_3 3.5.0-1 + rtnl_neigh_get_master@libnl_3_5 3.5.0-1 + rtnl_neigh_get_state@Base 3.5.0-1 + rtnl_neigh_get_state@libnl_3 3.5.0-1 + rtnl_neigh_get_type@Base 3.5.0-1 + rtnl_neigh_get_type@libnl_3 3.5.0-1 + rtnl_neigh_get_vlan@Base 3.5.0-1 + rtnl_neigh_get_vlan@libnl_3_2_26 3.5.0-1 + rtnl_neigh_parse@Base 3.5.0-1 + rtnl_neigh_parse@libnl_3 3.5.0-1 + rtnl_neigh_put@Base 3.5.0-1 + rtnl_neigh_put@libnl_3 3.5.0-1 + rtnl_neigh_set_dst@Base 3.5.0-1 + rtnl_neigh_set_dst@libnl_3 3.5.0-1 + rtnl_neigh_set_family@Base 3.5.0-1 + rtnl_neigh_set_family@libnl_3 3.5.0-1 + rtnl_neigh_set_flags@Base 3.5.0-1 + rtnl_neigh_set_flags@libnl_3 3.5.0-1 + rtnl_neigh_set_ifindex@Base 3.5.0-1 + rtnl_neigh_set_ifindex@libnl_3 3.5.0-1 + rtnl_neigh_set_lladdr@Base 3.5.0-1 + rtnl_neigh_set_lladdr@libnl_3 3.5.0-1 + rtnl_neigh_set_master@libnl_3_5 3.5.0-1 + rtnl_neigh_set_state@Base 3.5.0-1 + rtnl_neigh_set_state@libnl_3 3.5.0-1 + rtnl_neigh_set_type@Base 3.5.0-1 + rtnl_neigh_set_type@libnl_3 3.5.0-1 + rtnl_neigh_set_vlan@Base 3.5.0-1 + rtnl_neigh_set_vlan@libnl_3_2_26 3.5.0-1 + rtnl_neigh_state2str@Base 3.5.0-1 + rtnl_neigh_state2str@libnl_3 3.5.0-1 + rtnl_neigh_str2flag@Base 3.5.0-1 + rtnl_neigh_str2flag@libnl_3 3.5.0-1 + rtnl_neigh_str2state@Base 3.5.0-1 + rtnl_neigh_str2state@libnl_3 3.5.0-1 + rtnl_neigh_unset_flags@Base 3.5.0-1 + rtnl_neigh_unset_flags@libnl_3 3.5.0-1 + rtnl_neigh_unset_state@Base 3.5.0-1 + rtnl_neigh_unset_state@libnl_3 3.5.0-1 + rtnl_neightbl_alloc@Base 3.5.0-1 + rtnl_neightbl_alloc@libnl_3 3.5.0-1 + rtnl_neightbl_alloc_cache@Base 3.5.0-1 + rtnl_neightbl_alloc_cache@libnl_3 3.5.0-1 + rtnl_neightbl_build_change_request@Base 3.5.0-1 + rtnl_neightbl_build_change_request@libnl_3 3.5.0-1 + rtnl_neightbl_change@Base 3.5.0-1 + rtnl_neightbl_change@libnl_3 3.5.0-1 + rtnl_neightbl_get@Base 3.5.0-1 + rtnl_neightbl_get@libnl_3 3.5.0-1 + rtnl_neightbl_put@Base 3.5.0-1 + rtnl_neightbl_put@libnl_3 3.5.0-1 + rtnl_neightbl_set_anycast_delay@Base 3.5.0-1 + rtnl_neightbl_set_anycast_delay@libnl_3 3.5.0-1 + rtnl_neightbl_set_app_probes@Base 3.5.0-1 + rtnl_neightbl_set_app_probes@libnl_3 3.5.0-1 + rtnl_neightbl_set_base_reachable_time@Base 3.5.0-1 + rtnl_neightbl_set_base_reachable_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_delay_probe_time@Base 3.5.0-1 + rtnl_neightbl_set_delay_probe_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_dev@Base 3.5.0-1 + rtnl_neightbl_set_dev@libnl_3 3.5.0-1 + rtnl_neightbl_set_family@Base 3.5.0-1 + rtnl_neightbl_set_family@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_interval@Base 3.5.0-1 + rtnl_neightbl_set_gc_interval@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_stale_time@Base 3.5.0-1 + rtnl_neightbl_set_gc_stale_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh1@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh1@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh2@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh2@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh3@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh3@libnl_3 3.5.0-1 + rtnl_neightbl_set_locktime@Base 3.5.0-1 + rtnl_neightbl_set_locktime@libnl_3 3.5.0-1 + rtnl_neightbl_set_mcast_probes@Base 3.5.0-1 + rtnl_neightbl_set_mcast_probes@libnl_3 3.5.0-1 + rtnl_neightbl_set_name@Base 3.5.0-1 + rtnl_neightbl_set_name@libnl_3 3.5.0-1 + rtnl_neightbl_set_proxy_delay@Base 3.5.0-1 + rtnl_neightbl_set_proxy_delay@libnl_3 3.5.0-1 + rtnl_neightbl_set_proxy_queue_len@Base 3.5.0-1 + rtnl_neightbl_set_proxy_queue_len@libnl_3 3.5.0-1 + rtnl_neightbl_set_queue_len@Base 3.5.0-1 + rtnl_neightbl_set_queue_len@libnl_3 3.5.0-1 + rtnl_neightbl_set_retrans_time@Base 3.5.0-1 + rtnl_neightbl_set_retrans_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_ucast_probes@Base 3.5.0-1 + rtnl_neightbl_set_ucast_probes@libnl_3 3.5.0-1 + rtnl_netconf_get_all@libnl_3_4 3.5.0-1 + rtnl_netconf_get_by_idx@libnl_3_4 3.5.0-1 + rtnl_netconf_get_default@libnl_3_4 3.5.0-1 + rtnl_netconf_get_family@libnl_3_4 3.5.0-1 + rtnl_netconf_get_forwarding@libnl_3_4 3.5.0-1 + rtnl_netconf_get_ifindex@libnl_3_4 3.5.0-1 + rtnl_netconf_get_input@libnl_3_4 3.5.0-1 + rtnl_netconf_get_mc_forwarding@libnl_3_4 3.5.0-1 + rtnl_netconf_get_rp_filter@libnl_3_4 3.5.0-1 + rtnl_netconf_put@libnl_3_4 3.5.0-1 + rtnl_netem_get_corruption_correlation@Base 3.5.0-1 + rtnl_netem_get_corruption_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_corruption_probability@Base 3.5.0-1 + rtnl_netem_get_corruption_probability@libnl_3 3.5.0-1 + rtnl_netem_get_delay@Base 3.5.0-1 + rtnl_netem_get_delay@libnl_3 3.5.0-1 + rtnl_netem_get_delay_correlation@Base 3.5.0-1 + rtnl_netem_get_delay_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_delay_distribution@Base 3.5.0-1 + rtnl_netem_get_delay_distribution@libnl_3 3.5.0-1 + rtnl_netem_get_delay_distribution_size@Base 3.5.0-1 + rtnl_netem_get_delay_distribution_size@libnl_3 3.5.0-1 + rtnl_netem_get_duplicate@Base 3.5.0-1 + rtnl_netem_get_duplicate@libnl_3 3.5.0-1 + rtnl_netem_get_duplicate_correlation@Base 3.5.0-1 + rtnl_netem_get_duplicate_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_gap@Base 3.5.0-1 + rtnl_netem_get_gap@libnl_3 3.5.0-1 + rtnl_netem_get_jitter@Base 3.5.0-1 + rtnl_netem_get_jitter@libnl_3 3.5.0-1 + rtnl_netem_get_limit@Base 3.5.0-1 + rtnl_netem_get_limit@libnl_3 3.5.0-1 + rtnl_netem_get_loss@Base 3.5.0-1 + rtnl_netem_get_loss@libnl_3 3.5.0-1 + rtnl_netem_get_loss_correlation@Base 3.5.0-1 + rtnl_netem_get_loss_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_reorder_correlation@Base 3.5.0-1 + rtnl_netem_get_reorder_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_reorder_probability@Base 3.5.0-1 + rtnl_netem_get_reorder_probability@libnl_3 3.5.0-1 + rtnl_netem_set_corruption_correlation@Base 3.5.0-1 + rtnl_netem_set_corruption_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_corruption_probability@Base 3.5.0-1 + rtnl_netem_set_corruption_probability@libnl_3 3.5.0-1 + rtnl_netem_set_delay@Base 3.5.0-1 + rtnl_netem_set_delay@libnl_3 3.5.0-1 + rtnl_netem_set_delay_correlation@Base 3.5.0-1 + rtnl_netem_set_delay_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_delay_distribution@Base 3.5.0-1 + rtnl_netem_set_delay_distribution@libnl_3 3.5.0-1 + rtnl_netem_set_delay_distribution_data@libnl_3_5 3.5.0-1 + rtnl_netem_set_duplicate@Base 3.5.0-1 + rtnl_netem_set_duplicate@libnl_3 3.5.0-1 + rtnl_netem_set_duplicate_correlation@Base 3.5.0-1 + rtnl_netem_set_duplicate_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_gap@Base 3.5.0-1 + rtnl_netem_set_gap@libnl_3 3.5.0-1 + rtnl_netem_set_jitter@Base 3.5.0-1 + rtnl_netem_set_jitter@libnl_3 3.5.0-1 + rtnl_netem_set_limit@Base 3.5.0-1 + rtnl_netem_set_limit@libnl_3 3.5.0-1 + rtnl_netem_set_loss@Base 3.5.0-1 + rtnl_netem_set_loss@libnl_3 3.5.0-1 + rtnl_netem_set_loss_correlation@Base 3.5.0-1 + rtnl_netem_set_loss_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_reorder_correlation@Base 3.5.0-1 + rtnl_netem_set_reorder_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_reorder_probability@Base 3.5.0-1 + rtnl_netem_set_reorder_probability@libnl_3 3.5.0-1 + rtnl_pktloc_add@Base 3.5.0-1 + rtnl_pktloc_add@libnl_3 3.5.0-1 + rtnl_pktloc_alloc@Base 3.5.0-1 + rtnl_pktloc_alloc@libnl_3 3.5.0-1 + rtnl_pktloc_foreach@Base 3.5.0-1 + rtnl_pktloc_foreach@libnl_3 3.5.0-1 + rtnl_pktloc_lookup@Base 3.5.0-1 + rtnl_pktloc_lookup@libnl_3 3.5.0-1 + rtnl_pktloc_put@Base 3.5.0-1 + rtnl_pktloc_put@libnl_3 3.5.0-1 + rtnl_prio2str@Base 3.5.0-1 + rtnl_prio2str@libnl_3 3.5.0-1 + rtnl_qdisc_add@Base 3.5.0-1 + rtnl_qdisc_add@libnl_3 3.5.0-1 + rtnl_qdisc_alloc@Base 3.5.0-1 + rtnl_qdisc_alloc@libnl_3 3.5.0-1 + rtnl_qdisc_alloc_cache@Base 3.5.0-1 + rtnl_qdisc_alloc_cache@libnl_3 3.5.0-1 + rtnl_qdisc_build_add_request@Base 3.5.0-1 + rtnl_qdisc_build_add_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_change_request@Base 3.5.0-1 + rtnl_qdisc_build_change_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_delete_request@Base 3.5.0-1 + rtnl_qdisc_build_delete_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_update_request@Base 3.5.0-1 + rtnl_qdisc_build_update_request@libnl_3 3.5.0-1 + rtnl_qdisc_change@Base 3.5.0-1 + rtnl_qdisc_change@libnl_3 3.5.0-1 + rtnl_qdisc_delete@Base 3.5.0-1 + rtnl_qdisc_delete@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_default_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_default_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_indices@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_indices@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_set_tc_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_set_tc_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_default_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_default_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_indices@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_indices@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_set_tc_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_set_tc_index@libnl_3 3.5.0-1 + rtnl_qdisc_fifo_get_limit@Base 3.5.0-1 + rtnl_qdisc_fifo_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fifo_set_limit@Base 3.5.0-1 + rtnl_qdisc_fifo_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_foreach_child@Base 3.5.0-1 + rtnl_qdisc_foreach_child@libnl_3 3.5.0-1 + rtnl_qdisc_foreach_cls@Base 3.5.0-1 + rtnl_qdisc_foreach_cls@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_ecn@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_ecn@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_flows@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_flows@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_interval@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_interval@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_limit@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_quantum@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_quantum@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_target@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_target@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_ecn@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_ecn@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_flows@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_flows@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_interval@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_interval@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_limit@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_quantum@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_quantum@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_target@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_target@libnl_3 3.5.0-1 + rtnl_qdisc_get@Base 3.5.0-1 + rtnl_qdisc_get@libnl_3 3.5.0-1 + rtnl_qdisc_get_by_parent@Base 3.5.0-1 + rtnl_qdisc_get_by_parent@libnl_3 3.5.0-1 + rtnl_qdisc_hfsc_get_defcls@Base 3.5.0-1 + rtnl_qdisc_hfsc_get_defcls@libnl_3 3.5.0-1 + rtnl_qdisc_hfsc_set_defcls@Base 3.5.0-1 + rtnl_qdisc_hfsc_set_defcls@libnl_3 3.5.0-1 + rtnl_qdisc_mqprio_get_hw_offload@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_max_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_min_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_mode@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_num_tc@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_priomap@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_queue@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_shaper@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_hw_offload@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_max_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_min_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_mode@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_num_tc@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_priomap@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_queue@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_shaper@libnl_3_5 3.5.0-1 + rtnl_qdisc_plug_buffer@Base 3.5.0-1 + rtnl_qdisc_plug_buffer@libnl_3 3.5.0-1 + rtnl_qdisc_plug_release_indefinite@Base 3.5.0-1 + rtnl_qdisc_plug_release_indefinite@libnl_3 3.5.0-1 + rtnl_qdisc_plug_release_one@Base 3.5.0-1 + rtnl_qdisc_plug_release_one@libnl_3 3.5.0-1 + rtnl_qdisc_plug_set_limit@Base 3.5.0-1 + rtnl_qdisc_plug_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_prio_get_bands@Base 3.5.0-1 + rtnl_qdisc_prio_get_bands@libnl_3 3.5.0-1 + rtnl_qdisc_prio_get_priomap@Base 3.5.0-1 + rtnl_qdisc_prio_get_priomap@libnl_3 3.5.0-1 + rtnl_qdisc_prio_set_bands@Base 3.5.0-1 + rtnl_qdisc_prio_set_bands@libnl_3 3.5.0-1 + rtnl_qdisc_prio_set_priomap@Base 3.5.0-1 + rtnl_qdisc_prio_set_priomap@libnl_3 3.5.0-1 + rtnl_qdisc_put@Base 3.5.0-1 + rtnl_qdisc_put@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_limit@Base 3.5.0-1 + rtnl_qdisc_tbf_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_bucket@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_bucket@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_cell@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_cell@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate_bucket@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate_bucket@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate_cell@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate_cell@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_limit@Base 3.5.0-1 + rtnl_qdisc_tbf_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_limit_by_latency@Base 3.5.0-1 + rtnl_qdisc_tbf_set_limit_by_latency@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_peakrate@Base 3.5.0-1 + rtnl_qdisc_tbf_set_peakrate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_rate@Base 3.5.0-1 + rtnl_qdisc_tbf_set_rate@libnl_3 3.5.0-1 + rtnl_qdisc_update@Base 3.5.0-1 + rtnl_qdisc_update@libnl_3 3.5.0-1 + rtnl_realms2str@Base 3.5.0-1 + rtnl_realms2str@libnl_3 3.5.0-1 + rtnl_red_get_limit@Base 3.5.0-1 + rtnl_red_get_limit@libnl_3 3.5.0-1 + rtnl_red_set_limit@Base 3.5.0-1 + rtnl_red_set_limit@libnl_3 3.5.0-1 + rtnl_route_add@Base 3.5.0-1 + rtnl_route_add@libnl_3 3.5.0-1 + rtnl_route_add_nexthop@Base 3.5.0-1 + rtnl_route_add_nexthop@libnl_3 3.5.0-1 + rtnl_route_alloc@Base 3.5.0-1 + rtnl_route_alloc@libnl_3 3.5.0-1 + rtnl_route_alloc_cache@Base 3.5.0-1 + rtnl_route_alloc_cache@libnl_3 3.5.0-1 + rtnl_route_build_add_request@Base 3.5.0-1 + rtnl_route_build_add_request@libnl_3 3.5.0-1 + rtnl_route_build_del_request@Base 3.5.0-1 + rtnl_route_build_del_request@libnl_3 3.5.0-1 + rtnl_route_build_msg@Base 3.5.0-1 + rtnl_route_build_msg@libnl_3 3.5.0-1 + rtnl_route_delete@Base 3.5.0-1 + rtnl_route_delete@libnl_3 3.5.0-1 + rtnl_route_foreach_nexthop@Base 3.5.0-1 + rtnl_route_foreach_nexthop@libnl_3 3.5.0-1 + rtnl_route_get@Base 3.5.0-1 + rtnl_route_get@libnl_3 3.5.0-1 + rtnl_route_get_dst@Base 3.5.0-1 + rtnl_route_get_dst@libnl_3 3.5.0-1 + rtnl_route_get_family@Base 3.5.0-1 + rtnl_route_get_family@libnl_3 3.5.0-1 + rtnl_route_get_flags@Base 3.5.0-1 + rtnl_route_get_flags@libnl_3 3.5.0-1 + rtnl_route_get_iif@Base 3.5.0-1 + rtnl_route_get_iif@libnl_3 3.5.0-1 + rtnl_route_get_metric@Base 3.5.0-1 + rtnl_route_get_metric@libnl_3 3.5.0-1 + rtnl_route_get_nexthops@Base 3.5.0-1 + rtnl_route_get_nexthops@libnl_3 3.5.0-1 + rtnl_route_get_nnexthops@Base 3.5.0-1 + rtnl_route_get_nnexthops@libnl_3 3.5.0-1 + rtnl_route_get_pref_src@Base 3.5.0-1 + rtnl_route_get_pref_src@libnl_3 3.5.0-1 + rtnl_route_get_priority@Base 3.5.0-1 + rtnl_route_get_priority@libnl_3 3.5.0-1 + rtnl_route_get_protocol@Base 3.5.0-1 + rtnl_route_get_protocol@libnl_3 3.5.0-1 + rtnl_route_get_scope@Base 3.5.0-1 + rtnl_route_get_scope@libnl_3 3.5.0-1 + rtnl_route_get_src@Base 3.5.0-1 + rtnl_route_get_src@libnl_3 3.5.0-1 + rtnl_route_get_table@Base 3.5.0-1 + rtnl_route_get_table@libnl_3 3.5.0-1 + rtnl_route_get_tos@Base 3.5.0-1 + rtnl_route_get_tos@libnl_3 3.5.0-1 + rtnl_route_get_ttl_propagate@libnl_3_4 3.5.0-1 + rtnl_route_get_type@Base 3.5.0-1 + rtnl_route_get_type@libnl_3 3.5.0-1 + rtnl_route_guess_scope@Base 3.5.0-1 + rtnl_route_guess_scope@libnl_3 3.5.0-1 + rtnl_route_metric2str@Base 3.5.0-1 + rtnl_route_metric2str@libnl_3 3.5.0-1 + rtnl_route_nexthop_n@Base 3.5.0-1 + rtnl_route_nexthop_n@libnl_3 3.5.0-1 + rtnl_route_nh_alloc@Base 3.5.0-1 + rtnl_route_nh_alloc@libnl_3 3.5.0-1 + rtnl_route_nh_clone@Base 3.5.0-1 + rtnl_route_nh_clone@libnl_3 3.5.0-1 + rtnl_route_nh_compare@Base 3.5.0-1 + rtnl_route_nh_compare@libnl_3 3.5.0-1 + rtnl_route_nh_dump@Base 3.5.0-1 + rtnl_route_nh_dump@libnl_3 3.5.0-1 + rtnl_route_nh_encap_mpls@libnl_3_4 3.5.0-1 + rtnl_route_nh_flags2str@Base 3.5.0-1 + rtnl_route_nh_flags2str@libnl_3 3.5.0-1 + rtnl_route_nh_free@Base 3.5.0-1 + rtnl_route_nh_free@libnl_3 3.5.0-1 + rtnl_route_nh_get_flags@Base 3.5.0-1 + rtnl_route_nh_get_flags@libnl_3 3.5.0-1 + rtnl_route_nh_get_gateway@Base 3.5.0-1 + rtnl_route_nh_get_gateway@libnl_3 3.5.0-1 + rtnl_route_nh_get_ifindex@Base 3.5.0-1 + rtnl_route_nh_get_ifindex@libnl_3 3.5.0-1 + rtnl_route_nh_get_newdst@libnl_3_4 3.5.0-1 + rtnl_route_nh_get_realms@Base 3.5.0-1 + rtnl_route_nh_get_realms@libnl_3 3.5.0-1 + rtnl_route_nh_get_via@libnl_3_4 3.5.0-1 + rtnl_route_nh_get_weight@Base 3.5.0-1 + rtnl_route_nh_get_weight@libnl_3 3.5.0-1 + rtnl_route_nh_set_flags@Base 3.5.0-1 + rtnl_route_nh_set_flags@libnl_3 3.5.0-1 + rtnl_route_nh_set_gateway@Base 3.5.0-1 + rtnl_route_nh_set_gateway@libnl_3 3.5.0-1 + rtnl_route_nh_set_ifindex@Base 3.5.0-1 + rtnl_route_nh_set_ifindex@libnl_3 3.5.0-1 + rtnl_route_nh_set_newdst@libnl_3_4 3.5.0-1 + rtnl_route_nh_set_realms@Base 3.5.0-1 + rtnl_route_nh_set_realms@libnl_3 3.5.0-1 + rtnl_route_nh_set_via@libnl_3_4 3.5.0-1 + rtnl_route_nh_set_weight@Base 3.5.0-1 + rtnl_route_nh_set_weight@libnl_3 3.5.0-1 + rtnl_route_nh_str2flags@Base 3.5.0-1 + rtnl_route_nh_str2flags@libnl_3 3.5.0-1 + rtnl_route_nh_unset_flags@Base 3.5.0-1 + rtnl_route_nh_unset_flags@libnl_3 3.5.0-1 + rtnl_route_parse@Base 3.5.0-1 + rtnl_route_parse@libnl_3 3.5.0-1 + rtnl_route_proto2str@Base 3.5.0-1 + rtnl_route_proto2str@libnl_3 3.5.0-1 + rtnl_route_put@Base 3.5.0-1 + rtnl_route_put@libnl_3 3.5.0-1 + rtnl_route_read_protocol_names@Base 3.5.0-1 + rtnl_route_read_protocol_names@libnl_3 3.5.0-1 + rtnl_route_read_table_names@Base 3.5.0-1 + rtnl_route_read_table_names@libnl_3 3.5.0-1 + rtnl_route_remove_nexthop@Base 3.5.0-1 + rtnl_route_remove_nexthop@libnl_3 3.5.0-1 + rtnl_route_set_dst@Base 3.5.0-1 + rtnl_route_set_dst@libnl_3 3.5.0-1 + rtnl_route_set_family@Base 3.5.0-1 + rtnl_route_set_family@libnl_3 3.5.0-1 + rtnl_route_set_flags@Base 3.5.0-1 + rtnl_route_set_flags@libnl_3 3.5.0-1 + rtnl_route_set_iif@Base 3.5.0-1 + rtnl_route_set_iif@libnl_3 3.5.0-1 + rtnl_route_set_metric@Base 3.5.0-1 + rtnl_route_set_metric@libnl_3 3.5.0-1 + rtnl_route_set_pref_src@Base 3.5.0-1 + rtnl_route_set_pref_src@libnl_3 3.5.0-1 + rtnl_route_set_priority@Base 3.5.0-1 + rtnl_route_set_priority@libnl_3 3.5.0-1 + rtnl_route_set_protocol@Base 3.5.0-1 + rtnl_route_set_protocol@libnl_3 3.5.0-1 + rtnl_route_set_scope@Base 3.5.0-1 + rtnl_route_set_scope@libnl_3 3.5.0-1 + rtnl_route_set_src@Base 3.5.0-1 + rtnl_route_set_src@libnl_3 3.5.0-1 + rtnl_route_set_table@Base 3.5.0-1 + rtnl_route_set_table@libnl_3 3.5.0-1 + rtnl_route_set_tos@Base 3.5.0-1 + rtnl_route_set_tos@libnl_3 3.5.0-1 + rtnl_route_set_ttl_propagate@libnl_3_4 3.5.0-1 + rtnl_route_set_type@Base 3.5.0-1 + rtnl_route_set_type@libnl_3 3.5.0-1 + rtnl_route_str2metric@Base 3.5.0-1 + rtnl_route_str2metric@libnl_3 3.5.0-1 + rtnl_route_str2proto@Base 3.5.0-1 + rtnl_route_str2proto@libnl_3 3.5.0-1 + rtnl_route_str2table@Base 3.5.0-1 + rtnl_route_str2table@libnl_3 3.5.0-1 + rtnl_route_table2str@Base 3.5.0-1 + rtnl_route_table2str@libnl_3 3.5.0-1 + rtnl_route_unset_flags@Base 3.5.0-1 + rtnl_route_unset_flags@libnl_3 3.5.0-1 + rtnl_route_unset_metric@Base 3.5.0-1 + rtnl_route_unset_metric@libnl_3 3.5.0-1 + rtnl_rule_add@Base 3.5.0-1 + rtnl_rule_add@libnl_3 3.5.0-1 + rtnl_rule_alloc@Base 3.5.0-1 + rtnl_rule_alloc@libnl_3 3.5.0-1 + rtnl_rule_alloc_cache@Base 3.5.0-1 + rtnl_rule_alloc_cache@libnl_3 3.5.0-1 + rtnl_rule_build_add_request@Base 3.5.0-1 + rtnl_rule_build_add_request@libnl_3 3.5.0-1 + rtnl_rule_build_delete_request@Base 3.5.0-1 + rtnl_rule_build_delete_request@libnl_3 3.5.0-1 + rtnl_rule_delete@Base 3.5.0-1 + rtnl_rule_delete@libnl_3 3.5.0-1 + rtnl_rule_get_action@Base 3.5.0-1 + rtnl_rule_get_action@libnl_3 3.5.0-1 + rtnl_rule_get_dport@libnl_3_5 3.5.0-1 + rtnl_rule_get_dsfield@Base 3.5.0-1 + rtnl_rule_get_dsfield@libnl_3 3.5.0-1 + rtnl_rule_get_dst@Base 3.5.0-1 + rtnl_rule_get_dst@libnl_3 3.5.0-1 + rtnl_rule_get_family@Base 3.5.0-1 + rtnl_rule_get_family@libnl_3 3.5.0-1 + rtnl_rule_get_goto@Base 3.5.0-1 + rtnl_rule_get_goto@libnl_3 3.5.0-1 + rtnl_rule_get_iif@Base 3.5.0-1 + rtnl_rule_get_iif@libnl_3 3.5.0-1 + rtnl_rule_get_ipproto@libnl_3_5 3.5.0-1 + rtnl_rule_get_l3mdev@libnl_3_4 3.5.0-1 + rtnl_rule_get_mark@Base 3.5.0-1 + rtnl_rule_get_mark@libnl_3 3.5.0-1 + rtnl_rule_get_mask@Base 3.5.0-1 + rtnl_rule_get_mask@libnl_3 3.5.0-1 + rtnl_rule_get_oif@Base 3.5.0-1 + rtnl_rule_get_oif@libnl_3 3.5.0-1 + rtnl_rule_get_prio@Base 3.5.0-1 + rtnl_rule_get_prio@libnl_3 3.5.0-1 + rtnl_rule_get_protocol@libnl_3_5 3.5.0-1 + rtnl_rule_get_realms@Base 3.5.0-1 + rtnl_rule_get_realms@libnl_3 3.5.0-1 + rtnl_rule_get_sport@libnl_3_5 3.5.0-1 + rtnl_rule_get_src@Base 3.5.0-1 + rtnl_rule_get_src@libnl_3 3.5.0-1 + rtnl_rule_get_table@Base 3.5.0-1 + rtnl_rule_get_table@libnl_3 3.5.0-1 + rtnl_rule_put@Base 3.5.0-1 + rtnl_rule_put@libnl_3 3.5.0-1 + rtnl_rule_set_action@Base 3.5.0-1 + rtnl_rule_set_action@libnl_3 3.5.0-1 + rtnl_rule_set_dport@libnl_3_5 3.5.0-1 + rtnl_rule_set_dport_range@libnl_3_5 3.5.0-1 + rtnl_rule_set_dsfield@Base 3.5.0-1 + rtnl_rule_set_dsfield@libnl_3 3.5.0-1 + rtnl_rule_set_dst@Base 3.5.0-1 + rtnl_rule_set_dst@libnl_3 3.5.0-1 + rtnl_rule_set_family@Base 3.5.0-1 + rtnl_rule_set_family@libnl_3 3.5.0-1 + rtnl_rule_set_goto@Base 3.5.0-1 + rtnl_rule_set_goto@libnl_3 3.5.0-1 + rtnl_rule_set_iif@Base 3.5.0-1 + rtnl_rule_set_iif@libnl_3 3.5.0-1 + rtnl_rule_set_ipproto@libnl_3_5 3.5.0-1 + rtnl_rule_set_l3mdev@libnl_3_4 3.5.0-1 + rtnl_rule_set_mark@Base 3.5.0-1 + rtnl_rule_set_mark@libnl_3 3.5.0-1 + rtnl_rule_set_mask@Base 3.5.0-1 + rtnl_rule_set_mask@libnl_3 3.5.0-1 + rtnl_rule_set_oif@Base 3.5.0-1 + rtnl_rule_set_oif@libnl_3 3.5.0-1 + rtnl_rule_set_prio@Base 3.5.0-1 + rtnl_rule_set_prio@libnl_3 3.5.0-1 + rtnl_rule_set_protocol@libnl_3_5 3.5.0-1 + rtnl_rule_set_realms@Base 3.5.0-1 + rtnl_rule_set_realms@libnl_3 3.5.0-1 + rtnl_rule_set_sport@libnl_3_5 3.5.0-1 + rtnl_rule_set_sport_range@libnl_3_5 3.5.0-1 + rtnl_rule_set_src@Base 3.5.0-1 + rtnl_rule_set_src@libnl_3 3.5.0-1 + rtnl_rule_set_table@Base 3.5.0-1 + rtnl_rule_set_table@libnl_3 3.5.0-1 + rtnl_scope2str@Base 3.5.0-1 + rtnl_scope2str@libnl_3 3.5.0-1 + rtnl_sfq_get_divisor@Base 3.5.0-1 + rtnl_sfq_get_divisor@libnl_3 3.5.0-1 + rtnl_sfq_get_limit@Base 3.5.0-1 + rtnl_sfq_get_limit@libnl_3 3.5.0-1 + rtnl_sfq_get_perturb@Base 3.5.0-1 + rtnl_sfq_get_perturb@libnl_3 3.5.0-1 + rtnl_sfq_get_quantum@Base 3.5.0-1 + rtnl_sfq_get_quantum@libnl_3 3.5.0-1 + rtnl_sfq_set_limit@Base 3.5.0-1 + rtnl_sfq_set_limit@libnl_3 3.5.0-1 + rtnl_sfq_set_perturb@Base 3.5.0-1 + rtnl_sfq_set_perturb@libnl_3 3.5.0-1 + rtnl_sfq_set_quantum@Base 3.5.0-1 + rtnl_sfq_set_quantum@libnl_3 3.5.0-1 + rtnl_skbedit_get_action@Base 3.5.0-1 + rtnl_skbedit_get_action@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_mark@Base 3.5.0-1 + rtnl_skbedit_get_mark@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_priority@Base 3.5.0-1 + rtnl_skbedit_get_priority@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_queue_mapping@Base 3.5.0-1 + rtnl_skbedit_get_queue_mapping@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_action@Base 3.5.0-1 + rtnl_skbedit_set_action@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_mark@Base 3.5.0-1 + rtnl_skbedit_set_mark@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_priority@Base 3.5.0-1 + rtnl_skbedit_set_priority@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_queue_mapping@Base 3.5.0-1 + rtnl_skbedit_set_queue_mapping@libnl_3_2_26 3.5.0-1 + rtnl_str2prio@Base 3.5.0-1 + rtnl_str2prio@libnl_3 3.5.0-1 + rtnl_str2scope@Base 3.5.0-1 + rtnl_str2scope@libnl_3 3.5.0-1 + rtnl_tc_build_rate_table@Base 3.5.0-1 + rtnl_tc_build_rate_table@libnl_3 3.5.0-1 + rtnl_tc_calc_bufsize@Base 3.5.0-1 + rtnl_tc_calc_bufsize@libnl_3 3.5.0-1 + rtnl_tc_calc_cell_log@Base 3.5.0-1 + rtnl_tc_calc_cell_log@libnl_3 3.5.0-1 + rtnl_tc_calc_txtime@Base 3.5.0-1 + rtnl_tc_calc_txtime@libnl_3 3.5.0-1 + rtnl_tc_clone@Base 3.5.0-1 + rtnl_tc_clone@libnl_3 3.5.0-1 + rtnl_tc_compare@Base 3.5.0-1 + rtnl_tc_compare@libnl_3 3.5.0-1 + rtnl_tc_data@Base 3.5.0-1 + rtnl_tc_data@libnl_3 3.5.0-1 + rtnl_tc_data_check@Base 3.5.0-1 + rtnl_tc_data_check@libnl_3 3.5.0-1 + rtnl_tc_data_peek@Base 3.5.0-1 + rtnl_tc_dump_details@Base 3.5.0-1 + rtnl_tc_dump_details@libnl_3 3.5.0-1 + rtnl_tc_dump_line@Base 3.5.0-1 + rtnl_tc_dump_line@libnl_3 3.5.0-1 + rtnl_tc_dump_stats@Base 3.5.0-1 + rtnl_tc_dump_stats@libnl_3 3.5.0-1 + rtnl_tc_free_data@Base 3.5.0-1 + rtnl_tc_free_data@libnl_3 3.5.0-1 + rtnl_tc_get_chain@libnl_3_5 3.5.0-1 + rtnl_tc_get_handle@Base 3.5.0-1 + rtnl_tc_get_handle@libnl_3 3.5.0-1 + rtnl_tc_get_ifindex@Base 3.5.0-1 + rtnl_tc_get_ifindex@libnl_3 3.5.0-1 + rtnl_tc_get_kind@Base 3.5.0-1 + rtnl_tc_get_kind@libnl_3 3.5.0-1 + rtnl_tc_get_link@Base 3.5.0-1 + rtnl_tc_get_link@libnl_3 3.5.0-1 + rtnl_tc_get_linktype@Base 3.5.0-1 + rtnl_tc_get_linktype@libnl_3 3.5.0-1 + rtnl_tc_get_mpu@Base 3.5.0-1 + rtnl_tc_get_mpu@libnl_3 3.5.0-1 + rtnl_tc_get_mtu@Base 3.5.0-1 + rtnl_tc_get_mtu@libnl_3 3.5.0-1 + rtnl_tc_get_ops@Base 3.5.0-1 + rtnl_tc_get_ops@libnl_3 3.5.0-1 + rtnl_tc_get_overhead@Base 3.5.0-1 + rtnl_tc_get_overhead@libnl_3 3.5.0-1 + rtnl_tc_get_parent@Base 3.5.0-1 + rtnl_tc_get_parent@libnl_3 3.5.0-1 + rtnl_tc_get_stat@Base 3.5.0-1 + rtnl_tc_get_stat@libnl_3 3.5.0-1 + rtnl_tc_handle2str@Base 3.5.0-1 + rtnl_tc_handle2str@libnl_3 3.5.0-1 + rtnl_tc_lookup_ops@Base 3.5.0-1 + rtnl_tc_lookup_ops@libnl_3 3.5.0-1 + rtnl_tc_msg_build@Base 3.5.0-1 + rtnl_tc_msg_build@libnl_3 3.5.0-1 + rtnl_tc_msg_parse@Base 3.5.0-1 + rtnl_tc_msg_parse@libnl_3 3.5.0-1 + rtnl_tc_read_classid_file@Base 3.5.0-1 + rtnl_tc_read_classid_file@libnl_3 3.5.0-1 + rtnl_tc_register@Base 3.5.0-1 + rtnl_tc_register@libnl_3 3.5.0-1 + rtnl_tc_set_chain@libnl_3_5 3.5.0-1 + rtnl_tc_set_handle@Base 3.5.0-1 + rtnl_tc_set_handle@libnl_3 3.5.0-1 + rtnl_tc_set_ifindex@Base 3.5.0-1 + rtnl_tc_set_ifindex@libnl_3 3.5.0-1 + rtnl_tc_set_kind@Base 3.5.0-1 + rtnl_tc_set_kind@libnl_3 3.5.0-1 + rtnl_tc_set_link@Base 3.5.0-1 + rtnl_tc_set_link@libnl_3 3.5.0-1 + rtnl_tc_set_linktype@Base 3.5.0-1 + rtnl_tc_set_linktype@libnl_3 3.5.0-1 + rtnl_tc_set_mpu@Base 3.5.0-1 + rtnl_tc_set_mpu@libnl_3 3.5.0-1 + rtnl_tc_set_mtu@Base 3.5.0-1 + rtnl_tc_set_mtu@libnl_3 3.5.0-1 + rtnl_tc_set_overhead@Base 3.5.0-1 + rtnl_tc_set_overhead@libnl_3 3.5.0-1 + rtnl_tc_set_parent@Base 3.5.0-1 + rtnl_tc_set_parent@libnl_3 3.5.0-1 + rtnl_tc_stat2str@Base 3.5.0-1 + rtnl_tc_stat2str@libnl_3_2_26 3.5.0-1 + rtnl_tc_str2handle@Base 3.5.0-1 + rtnl_tc_str2handle@libnl_3 3.5.0-1 + rtnl_tc_str2stat@Base 3.5.0-1 + rtnl_tc_str2stat@libnl_3_2_26 3.5.0-1 + rtnl_tc_type_register@Base 3.5.0-1 + rtnl_tc_type_register@libnl_3 3.5.0-1 + rtnl_tc_type_unregister@Base 3.5.0-1 + rtnl_tc_type_unregister@libnl_3 3.5.0-1 + rtnl_tc_unregister@Base 3.5.0-1 + rtnl_tc_unregister@libnl_3 3.5.0-1 + rtnl_u32_add_action@Base 3.5.0-1 + rtnl_u32_add_action@libnl_3 3.5.0-1 + rtnl_u32_add_key@Base 3.5.0-1 + rtnl_u32_add_key@libnl_3 3.5.0-1 + rtnl_u32_add_key_in6_addr@Base 3.5.0-1 + rtnl_u32_add_key_in6_addr@libnl_3 3.5.0-1 + rtnl_u32_add_key_in_addr@Base 3.5.0-1 + rtnl_u32_add_key_in_addr@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint16@Base 3.5.0-1 + rtnl_u32_add_key_uint16@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint32@Base 3.5.0-1 + rtnl_u32_add_key_uint32@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint8@Base 3.5.0-1 + rtnl_u32_add_key_uint8@libnl_3 3.5.0-1 + rtnl_u32_add_mark@Base 3.5.0-1 + rtnl_u32_add_mark@libnl_3 3.5.0-1 + rtnl_u32_del_action@Base 3.5.0-1 + rtnl_u32_del_action@libnl_3 3.5.0-1 + rtnl_u32_del_mark@Base 3.5.0-1 + rtnl_u32_del_mark@libnl_3 3.5.0-1 + rtnl_u32_get_action@libnl_3_4 3.5.0-1 + rtnl_u32_get_classid@Base 3.5.0-1 + rtnl_u32_get_classid@libnl_3_2_26 3.5.0-1 + rtnl_u32_get_key@Base 3.5.0-1 + rtnl_u32_get_key@libnl_3 3.5.0-1 + rtnl_u32_set_classid@Base 3.5.0-1 + rtnl_u32_set_classid@libnl_3 3.5.0-1 + rtnl_u32_set_cls_terminal@Base 3.5.0-1 + rtnl_u32_set_cls_terminal@libnl_3 3.5.0-1 + rtnl_u32_set_divisor@Base 3.5.0-1 + rtnl_u32_set_divisor@libnl_3 3.5.0-1 + rtnl_u32_set_flags@Base 3.5.0-1 + rtnl_u32_set_flags@libnl_3 3.5.0-1 + rtnl_u32_set_handle@Base 3.5.0-1 + rtnl_u32_set_handle@libnl_3 3.5.0-1 + rtnl_u32_set_hashmask@Base 3.5.0-1 + rtnl_u32_set_hashmask@libnl_3 3.5.0-1 + rtnl_u32_set_hashtable@Base 3.5.0-1 + rtnl_u32_set_hashtable@libnl_3 3.5.0-1 + rtnl_u32_set_link@Base 3.5.0-1 + rtnl_u32_set_link@libnl_3 3.5.0-1 + rtnl_u32_set_selector@libnl_3_2_29 3.5.0-1 + rtnl_vlan_get_action@libnl_3_5 3.5.0-1 + rtnl_vlan_get_mode@libnl_3_5 3.5.0-1 + rtnl_vlan_get_protocol@libnl_3_5 3.5.0-1 + rtnl_vlan_get_vlan_id@libnl_3_5 3.5.0-1 + rtnl_vlan_get_vlan_prio@libnl_3_5 3.5.0-1 + rtnl_vlan_set_action@libnl_3_5 3.5.0-1 + rtnl_vlan_set_mode@libnl_3_5 3.5.0-1 + rtnl_vlan_set_protocol@libnl_3_5 3.5.0-1 + rtnl_vlan_set_vlan_id@libnl_3_5 3.5.0-1 + rtnl_vlan_set_vlan_prio@libnl_3_5 3.5.0-1 + tc_groups@Base 3.5.0-1 + tca_parse@Base 3.5.0-1 + tca_set_kind@Base 3.5.0-1 diff --git a/src/libnl3/debian/libnl-route-3-dev.install b/src/libnl3/debian/libnl-route-3-dev.install new file mode 100644 index 000000000000..37e248c3ed5b --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-route-3* +debian/tmp/usr/lib/*/libnl-route-3*.so +debian/tmp/usr/lib/*/libnl-route-3*.a diff --git a/src/libnl3/debian/libnl-utils.install b/src/libnl3/debian/libnl-utils.install new file mode 100644 index 000000000000..8ffdce84e93a --- /dev/null +++ b/src/libnl3/debian/libnl-utils.install @@ -0,0 +1 @@ +debian/tmp/usr/bin/* diff --git a/src/libnl3/debian/libnl-utils.manpages b/src/libnl3/debian/libnl-utils.manpages new file mode 100644 index 000000000000..0b2dcacf5b84 --- /dev/null +++ b/src/libnl3/debian/libnl-utils.manpages @@ -0,0 +1 @@ +debian/tmp/usr/share/man/man8/* diff --git a/src/libnl3/debian/libnl-xfrm-3-200.install b/src/libnl3/debian/libnl-xfrm-3-200.install new file mode 100644 index 000000000000..89b2d4e0c9e0 --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-xfrm-3*.so.* diff --git a/src/libnl3/debian/libnl-xfrm-3-200.symbols b/src/libnl3/debian/libnl-xfrm-3-200.symbols new file mode 100644 index 000000000000..3704a7aa4384 --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-200.symbols @@ -0,0 +1,484 @@ +libnl-xfrm-3.so.200 libnl-xfrm-3-200 #MINVER# + libnl_3@libnl_3 3.5.0-1 + xfrmnl_ae_alloc@Base 3.5.0-1 + xfrmnl_ae_alloc@libnl_3 3.5.0-1 + xfrmnl_ae_build_get_request@Base 3.5.0-1 + xfrmnl_ae_build_get_request@libnl_3 3.5.0-1 + xfrmnl_ae_flags2str@Base 3.5.0-1 + xfrmnl_ae_flags2str@libnl_3 3.5.0-1 + xfrmnl_ae_get_curlifetime@Base 3.5.0-1 + xfrmnl_ae_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_ae_get_daddr@Base 3.5.0-1 + xfrmnl_ae_get_daddr@libnl_3 3.5.0-1 + xfrmnl_ae_get_family@Base 3.5.0-1 + xfrmnl_ae_get_family@libnl_3 3.5.0-1 + xfrmnl_ae_get_flags@Base 3.5.0-1 + xfrmnl_ae_get_flags@libnl_3 3.5.0-1 + xfrmnl_ae_get_kernel@Base 3.5.0-1 + xfrmnl_ae_get_kernel@libnl_3 3.5.0-1 + xfrmnl_ae_get_mark@Base 3.5.0-1 + xfrmnl_ae_get_mark@libnl_3 3.5.0-1 + xfrmnl_ae_get_proto@Base 3.5.0-1 + xfrmnl_ae_get_proto@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_maxage@Base 3.5.0-1 + xfrmnl_ae_get_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_maxdiff@Base 3.5.0-1 + xfrmnl_ae_get_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_state@Base 3.5.0-1 + xfrmnl_ae_get_replay_state@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_state_esn@Base 3.5.0-1 + xfrmnl_ae_get_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_ae_get_reqid@Base 3.5.0-1 + xfrmnl_ae_get_reqid@libnl_3 3.5.0-1 + xfrmnl_ae_get_saddr@Base 3.5.0-1 + xfrmnl_ae_get_saddr@libnl_3 3.5.0-1 + xfrmnl_ae_get_spi@Base 3.5.0-1 + xfrmnl_ae_get_spi@libnl_3 3.5.0-1 + xfrmnl_ae_parse@Base 3.5.0-1 + xfrmnl_ae_parse@libnl_3 3.5.0-1 + xfrmnl_ae_put@Base 3.5.0-1 + xfrmnl_ae_put@libnl_3 3.5.0-1 + xfrmnl_ae_set@Base 3.5.0-1 + xfrmnl_ae_set@libnl_3 3.5.0-1 + xfrmnl_ae_set_curlifetime@Base 3.5.0-1 + xfrmnl_ae_set_curlifetime@libnl_3 3.5.0-1 + xfrmnl_ae_set_daddr@Base 3.5.0-1 + xfrmnl_ae_set_daddr@libnl_3 3.5.0-1 + xfrmnl_ae_set_family@Base 3.5.0-1 + xfrmnl_ae_set_family@libnl_3 3.5.0-1 + xfrmnl_ae_set_flags@Base 3.5.0-1 + xfrmnl_ae_set_flags@libnl_3 3.5.0-1 + xfrmnl_ae_set_mark@Base 3.5.0-1 + xfrmnl_ae_set_mark@libnl_3 3.5.0-1 + xfrmnl_ae_set_proto@Base 3.5.0-1 + xfrmnl_ae_set_proto@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_maxage@Base 3.5.0-1 + xfrmnl_ae_set_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_maxdiff@Base 3.5.0-1 + xfrmnl_ae_set_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_state@Base 3.5.0-1 + xfrmnl_ae_set_replay_state@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_state_esn@Base 3.5.0-1 + xfrmnl_ae_set_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_ae_set_reqid@Base 3.5.0-1 + xfrmnl_ae_set_reqid@libnl_3 3.5.0-1 + xfrmnl_ae_set_saddr@Base 3.5.0-1 + xfrmnl_ae_set_saddr@libnl_3 3.5.0-1 + xfrmnl_ae_set_spi@Base 3.5.0-1 + xfrmnl_ae_set_spi@libnl_3 3.5.0-1 + xfrmnl_ae_str2flag@Base 3.5.0-1 + xfrmnl_ae_str2flag@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_alloc@Base 3.5.0-1 + xfrmnl_ltime_cfg_alloc@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_clone@Base 3.5.0-1 + xfrmnl_ltime_cfg_clone@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_cmp@Base 3.5.0-1 + xfrmnl_ltime_cfg_cmp@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get@Base 3.5.0-1 + xfrmnl_ltime_cfg_get@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_put@Base 3.5.0-1 + xfrmnl_ltime_cfg_put@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_shared@Base 3.5.0-1 + xfrmnl_ltime_cfg_shared@libnl_3 3.5.0-1 + xfrmnl_sa_add@Base 3.5.0-1 + xfrmnl_sa_add@libnl_3 3.5.0-1 + xfrmnl_sa_alloc@Base 3.5.0-1 + xfrmnl_sa_alloc@libnl_3 3.5.0-1 + xfrmnl_sa_alloc_cache@Base 3.5.0-1 + xfrmnl_sa_alloc_cache@libnl_3 3.5.0-1 + xfrmnl_sa_build_add_request@Base 3.5.0-1 + xfrmnl_sa_build_add_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_delete_request@Base 3.5.0-1 + xfrmnl_sa_build_delete_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_get_request@Base 3.5.0-1 + xfrmnl_sa_build_get_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_update_request@Base 3.5.0-1 + xfrmnl_sa_build_update_request@libnl_3 3.5.0-1 + xfrmnl_sa_delete@Base 3.5.0-1 + xfrmnl_sa_delete@libnl_3 3.5.0-1 + xfrmnl_sa_flags2str@Base 3.5.0-1 + xfrmnl_sa_flags2str@libnl_3 3.5.0-1 + xfrmnl_sa_get@Base 3.5.0-1 + xfrmnl_sa_get@libnl_3 3.5.0-1 + xfrmnl_sa_get_aead_params@Base 3.5.0-1 + xfrmnl_sa_get_aead_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_auth_params@Base 3.5.0-1 + xfrmnl_sa_get_auth_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_coaddr@Base 3.5.0-1 + xfrmnl_sa_get_coaddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_comp_params@Base 3.5.0-1 + xfrmnl_sa_get_comp_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_crypto_params@Base 3.5.0-1 + xfrmnl_sa_get_crypto_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_curlifetime@Base 3.5.0-1 + xfrmnl_sa_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_sa_get_daddr@Base 3.5.0-1 + xfrmnl_sa_get_daddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_encap_tmpl@Base 3.5.0-1 + xfrmnl_sa_get_encap_tmpl@libnl_3 3.5.0-1 + xfrmnl_sa_get_family@Base 3.5.0-1 + xfrmnl_sa_get_family@libnl_3 3.5.0-1 + xfrmnl_sa_get_flags@Base 3.5.0-1 + xfrmnl_sa_get_flags@libnl_3 3.5.0-1 + xfrmnl_sa_get_kernel@Base 3.5.0-1 + xfrmnl_sa_get_kernel@libnl_3 3.5.0-1 + xfrmnl_sa_get_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sa_get_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sa_get_mark@Base 3.5.0-1 + xfrmnl_sa_get_mark@libnl_3 3.5.0-1 + xfrmnl_sa_get_mode@Base 3.5.0-1 + xfrmnl_sa_get_mode@libnl_3 3.5.0-1 + xfrmnl_sa_get_proto@Base 3.5.0-1 + xfrmnl_sa_get_proto@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_maxage@Base 3.5.0-1 + xfrmnl_sa_get_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_maxdiff@Base 3.5.0-1 + xfrmnl_sa_get_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_state@Base 3.5.0-1 + xfrmnl_sa_get_replay_state@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_state_esn@Base 3.5.0-1 + xfrmnl_sa_get_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_window@Base 3.5.0-1 + xfrmnl_sa_get_replay_window@libnl_3 3.5.0-1 + xfrmnl_sa_get_reqid@Base 3.5.0-1 + xfrmnl_sa_get_reqid@libnl_3 3.5.0-1 + xfrmnl_sa_get_saddr@Base 3.5.0-1 + xfrmnl_sa_get_saddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_sec_ctx@Base 3.5.0-1 + xfrmnl_sa_get_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sa_get_sel@Base 3.5.0-1 + xfrmnl_sa_get_sel@libnl_3 3.5.0-1 + xfrmnl_sa_get_seq@Base 3.5.0-1 + xfrmnl_sa_get_seq@libnl_3 3.5.0-1 + xfrmnl_sa_get_spi@Base 3.5.0-1 + xfrmnl_sa_get_spi@libnl_3 3.5.0-1 + xfrmnl_sa_get_stats@Base 3.5.0-1 + xfrmnl_sa_get_stats@libnl_3 3.5.0-1 + xfrmnl_sa_get_tfcpad@Base 3.5.0-1 + xfrmnl_sa_get_tfcpad@libnl_3 3.5.0-1 + xfrmnl_sa_is_expiry_reached@Base 3.5.0-1 + xfrmnl_sa_is_expiry_reached@libnl_3 3.5.0-1 + xfrmnl_sa_is_hardexpiry_reached@Base 3.5.0-1 + xfrmnl_sa_is_hardexpiry_reached@libnl_3 3.5.0-1 + xfrmnl_sa_mode2str@Base 3.5.0-1 + xfrmnl_sa_mode2str@libnl_3 3.5.0-1 + xfrmnl_sa_parse@Base 3.5.0-1 + xfrmnl_sa_parse@libnl_3 3.5.0-1 + xfrmnl_sa_put@Base 3.5.0-1 + xfrmnl_sa_put@libnl_3 3.5.0-1 + xfrmnl_sa_set_aead_params@Base 3.5.0-1 + xfrmnl_sa_set_aead_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_auth_params@Base 3.5.0-1 + xfrmnl_sa_set_auth_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_coaddr@Base 3.5.0-1 + xfrmnl_sa_set_coaddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_comp_params@Base 3.5.0-1 + xfrmnl_sa_set_comp_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_crypto_params@Base 3.5.0-1 + xfrmnl_sa_set_crypto_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_daddr@Base 3.5.0-1 + xfrmnl_sa_set_daddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_encap_tmpl@Base 3.5.0-1 + xfrmnl_sa_set_encap_tmpl@libnl_3 3.5.0-1 + xfrmnl_sa_set_family@Base 3.5.0-1 + xfrmnl_sa_set_family@libnl_3 3.5.0-1 + xfrmnl_sa_set_flags@Base 3.5.0-1 + xfrmnl_sa_set_flags@libnl_3 3.5.0-1 + xfrmnl_sa_set_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sa_set_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sa_set_mark@Base 3.5.0-1 + xfrmnl_sa_set_mark@libnl_3 3.5.0-1 + xfrmnl_sa_set_mode@Base 3.5.0-1 + xfrmnl_sa_set_mode@libnl_3 3.5.0-1 + xfrmnl_sa_set_proto@Base 3.5.0-1 + xfrmnl_sa_set_proto@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_maxage@Base 3.5.0-1 + xfrmnl_sa_set_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_maxdiff@Base 3.5.0-1 + xfrmnl_sa_set_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_state@Base 3.5.0-1 + xfrmnl_sa_set_replay_state@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_state_esn@Base 3.5.0-1 + xfrmnl_sa_set_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_window@Base 3.5.0-1 + xfrmnl_sa_set_replay_window@libnl_3 3.5.0-1 + xfrmnl_sa_set_reqid@Base 3.5.0-1 + xfrmnl_sa_set_reqid@libnl_3 3.5.0-1 + xfrmnl_sa_set_saddr@Base 3.5.0-1 + xfrmnl_sa_set_saddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_sec_ctx@Base 3.5.0-1 + xfrmnl_sa_set_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sa_set_sel@Base 3.5.0-1 + xfrmnl_sa_set_sel@libnl_3 3.5.0-1 + xfrmnl_sa_set_spi@Base 3.5.0-1 + xfrmnl_sa_set_spi@libnl_3 3.5.0-1 + xfrmnl_sa_set_tfcpad@Base 3.5.0-1 + xfrmnl_sa_set_tfcpad@libnl_3 3.5.0-1 + xfrmnl_sa_str2flag@Base 3.5.0-1 + xfrmnl_sa_str2flag@libnl_3 3.5.0-1 + xfrmnl_sa_str2mode@Base 3.5.0-1 + xfrmnl_sa_str2mode@libnl_3 3.5.0-1 + xfrmnl_sa_update@Base 3.5.0-1 + xfrmnl_sa_update@libnl_3 3.5.0-1 + xfrmnl_sel_alloc@Base 3.5.0-1 + xfrmnl_sel_alloc@libnl_3 3.5.0-1 + xfrmnl_sel_clone@Base 3.5.0-1 + xfrmnl_sel_clone@libnl_3 3.5.0-1 + xfrmnl_sel_cmp@Base 3.5.0-1 + xfrmnl_sel_cmp@libnl_3 3.5.0-1 + xfrmnl_sel_dump@Base 3.5.0-1 + xfrmnl_sel_dump@libnl_3 3.5.0-1 + xfrmnl_sel_get@Base 3.5.0-1 + xfrmnl_sel_get@libnl_3 3.5.0-1 + xfrmnl_sel_get_daddr@Base 3.5.0-1 + xfrmnl_sel_get_daddr@libnl_3 3.5.0-1 + xfrmnl_sel_get_dport@Base 3.5.0-1 + xfrmnl_sel_get_dport@libnl_3 3.5.0-1 + xfrmnl_sel_get_dportmask@Base 3.5.0-1 + xfrmnl_sel_get_dportmask@libnl_3 3.5.0-1 + xfrmnl_sel_get_family@Base 3.5.0-1 + xfrmnl_sel_get_family@libnl_3 3.5.0-1 + xfrmnl_sel_get_ifindex@Base 3.5.0-1 + xfrmnl_sel_get_ifindex@libnl_3 3.5.0-1 + xfrmnl_sel_get_prefixlen_d@Base 3.5.0-1 + xfrmnl_sel_get_prefixlen_d@libnl_3 3.5.0-1 + xfrmnl_sel_get_prefixlen_s@Base 3.5.0-1 + xfrmnl_sel_get_prefixlen_s@libnl_3 3.5.0-1 + xfrmnl_sel_get_proto@Base 3.5.0-1 + xfrmnl_sel_get_proto@libnl_3 3.5.0-1 + xfrmnl_sel_get_saddr@Base 3.5.0-1 + xfrmnl_sel_get_saddr@libnl_3 3.5.0-1 + xfrmnl_sel_get_sport@Base 3.5.0-1 + xfrmnl_sel_get_sport@libnl_3 3.5.0-1 + xfrmnl_sel_get_sportmask@Base 3.5.0-1 + xfrmnl_sel_get_sportmask@libnl_3 3.5.0-1 + xfrmnl_sel_get_userid@Base 3.5.0-1 + xfrmnl_sel_get_userid@libnl_3 3.5.0-1 + xfrmnl_sel_put@Base 3.5.0-1 + xfrmnl_sel_put@libnl_3 3.5.0-1 + xfrmnl_sel_set_daddr@Base 3.5.0-1 + xfrmnl_sel_set_daddr@libnl_3 3.5.0-1 + xfrmnl_sel_set_dport@Base 3.5.0-1 + xfrmnl_sel_set_dport@libnl_3 3.5.0-1 + xfrmnl_sel_set_dportmask@Base 3.5.0-1 + xfrmnl_sel_set_dportmask@libnl_3 3.5.0-1 + xfrmnl_sel_set_family@Base 3.5.0-1 + xfrmnl_sel_set_family@libnl_3 3.5.0-1 + xfrmnl_sel_set_ifindex@Base 3.5.0-1 + xfrmnl_sel_set_ifindex@libnl_3 3.5.0-1 + xfrmnl_sel_set_prefixlen_d@Base 3.5.0-1 + xfrmnl_sel_set_prefixlen_d@libnl_3 3.5.0-1 + xfrmnl_sel_set_prefixlen_s@Base 3.5.0-1 + xfrmnl_sel_set_prefixlen_s@libnl_3 3.5.0-1 + xfrmnl_sel_set_proto@Base 3.5.0-1 + xfrmnl_sel_set_proto@libnl_3 3.5.0-1 + xfrmnl_sel_set_saddr@Base 3.5.0-1 + xfrmnl_sel_set_saddr@libnl_3 3.5.0-1 + xfrmnl_sel_set_sport@Base 3.5.0-1 + xfrmnl_sel_set_sport@libnl_3 3.5.0-1 + xfrmnl_sel_set_sportmask@Base 3.5.0-1 + xfrmnl_sel_set_sportmask@libnl_3 3.5.0-1 + xfrmnl_sel_set_userid@Base 3.5.0-1 + xfrmnl_sel_set_userid@libnl_3 3.5.0-1 + xfrmnl_sel_shared@Base 3.5.0-1 + xfrmnl_sel_shared@libnl_3 3.5.0-1 + xfrmnl_sp_action2str@Base 3.5.0-1 + xfrmnl_sp_action2str@libnl_3 3.5.0-1 + xfrmnl_sp_add@Base 3.5.0-1 + xfrmnl_sp_add@libnl_3 3.5.0-1 + xfrmnl_sp_add_usertemplate@Base 3.5.0-1 + xfrmnl_sp_add_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_alloc@Base 3.5.0-1 + xfrmnl_sp_alloc@libnl_3 3.5.0-1 + xfrmnl_sp_alloc_cache@Base 3.5.0-1 + xfrmnl_sp_alloc_cache@libnl_3 3.5.0-1 + xfrmnl_sp_build_add_request@Base 3.5.0-1 + xfrmnl_sp_build_add_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_delete_request@Base 3.5.0-1 + xfrmnl_sp_build_delete_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_get_request@Base 3.5.0-1 + xfrmnl_sp_build_get_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_update_request@Base 3.5.0-1 + xfrmnl_sp_build_update_request@libnl_3 3.5.0-1 + xfrmnl_sp_delete@Base 3.5.0-1 + xfrmnl_sp_delete@libnl_3 3.5.0-1 + xfrmnl_sp_dir2str@Base 3.5.0-1 + xfrmnl_sp_dir2str@libnl_3 3.5.0-1 + xfrmnl_sp_flags2str@Base 3.5.0-1 + xfrmnl_sp_flags2str@libnl_3 3.5.0-1 + xfrmnl_sp_foreach_usertemplate@Base 3.5.0-1 + xfrmnl_sp_foreach_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_get@Base 3.5.0-1 + xfrmnl_sp_get@libnl_3 3.5.0-1 + xfrmnl_sp_get_action@Base 3.5.0-1 + xfrmnl_sp_get_action@libnl_3 3.5.0-1 + xfrmnl_sp_get_curlifetime@Base 3.5.0-1 + xfrmnl_sp_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_sp_get_dir@Base 3.5.0-1 + xfrmnl_sp_get_dir@libnl_3 3.5.0-1 + xfrmnl_sp_get_flags@Base 3.5.0-1 + xfrmnl_sp_get_flags@libnl_3 3.5.0-1 + xfrmnl_sp_get_index@Base 3.5.0-1 + xfrmnl_sp_get_index@libnl_3 3.5.0-1 + xfrmnl_sp_get_kernel@Base 3.5.0-1 + xfrmnl_sp_get_kernel@libnl_3 3.5.0-1 + xfrmnl_sp_get_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sp_get_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sp_get_mark@Base 3.5.0-1 + xfrmnl_sp_get_mark@libnl_3 3.5.0-1 + xfrmnl_sp_get_nusertemplates@Base 3.5.0-1 + xfrmnl_sp_get_nusertemplates@libnl_3 3.5.0-1 + xfrmnl_sp_get_priority@Base 3.5.0-1 + xfrmnl_sp_get_priority@libnl_3 3.5.0-1 + xfrmnl_sp_get_sec_ctx@Base 3.5.0-1 + xfrmnl_sp_get_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sp_get_sel@Base 3.5.0-1 + xfrmnl_sp_get_sel@libnl_3 3.5.0-1 + xfrmnl_sp_get_share@Base 3.5.0-1 + xfrmnl_sp_get_share@libnl_3 3.5.0-1 + xfrmnl_sp_get_userpolicy_type@Base 3.5.0-1 + xfrmnl_sp_get_userpolicy_type@libnl_3 3.5.0-1 + xfrmnl_sp_get_usertemplates@Base 3.5.0-1 + xfrmnl_sp_get_usertemplates@libnl_3 3.5.0-1 + xfrmnl_sp_index2dir@Base 3.5.0-1 + xfrmnl_sp_index2dir@libnl_3 3.5.0-1 + xfrmnl_sp_parse@Base 3.5.0-1 + xfrmnl_sp_parse@libnl_3 3.5.0-1 + xfrmnl_sp_put@Base 3.5.0-1 + xfrmnl_sp_put@libnl_3 3.5.0-1 + xfrmnl_sp_remove_usertemplate@Base 3.5.0-1 + xfrmnl_sp_remove_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_set_action@Base 3.5.0-1 + xfrmnl_sp_set_action@libnl_3 3.5.0-1 + xfrmnl_sp_set_dir@Base 3.5.0-1 + xfrmnl_sp_set_dir@libnl_3 3.5.0-1 + xfrmnl_sp_set_flags@Base 3.5.0-1 + xfrmnl_sp_set_flags@libnl_3 3.5.0-1 + xfrmnl_sp_set_index@Base 3.5.0-1 + xfrmnl_sp_set_index@libnl_3 3.5.0-1 + xfrmnl_sp_set_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sp_set_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sp_set_mark@Base 3.5.0-1 + xfrmnl_sp_set_mark@libnl_3 3.5.0-1 + xfrmnl_sp_set_priority@Base 3.5.0-1 + xfrmnl_sp_set_priority@libnl_3 3.5.0-1 + xfrmnl_sp_set_sec_ctx@Base 3.5.0-1 + xfrmnl_sp_set_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sp_set_sel@Base 3.5.0-1 + xfrmnl_sp_set_sel@libnl_3 3.5.0-1 + xfrmnl_sp_set_share@Base 3.5.0-1 + xfrmnl_sp_set_share@libnl_3 3.5.0-1 + xfrmnl_sp_set_userpolicy_type@Base 3.5.0-1 + xfrmnl_sp_set_userpolicy_type@libnl_3 3.5.0-1 + xfrmnl_sp_share2str@Base 3.5.0-1 + xfrmnl_sp_share2str@libnl_3 3.5.0-1 + xfrmnl_sp_str2action@Base 3.5.0-1 + xfrmnl_sp_str2action@libnl_3 3.5.0-1 + xfrmnl_sp_str2dir@Base 3.5.0-1 + xfrmnl_sp_str2dir@libnl_3 3.5.0-1 + xfrmnl_sp_str2flag@Base 3.5.0-1 + xfrmnl_sp_str2flag@libnl_3 3.5.0-1 + xfrmnl_sp_str2share@Base 3.5.0-1 + xfrmnl_sp_str2share@libnl_3 3.5.0-1 + xfrmnl_sp_str2type@Base 3.5.0-1 + xfrmnl_sp_str2type@libnl_3 3.5.0-1 + xfrmnl_sp_type2str@Base 3.5.0-1 + xfrmnl_sp_type2str@libnl_3 3.5.0-1 + xfrmnl_sp_update@Base 3.5.0-1 + xfrmnl_sp_update@libnl_3 3.5.0-1 + xfrmnl_sp_usertemplate_n@Base 3.5.0-1 + xfrmnl_sp_usertemplate_n@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_alloc@Base 3.5.0-1 + xfrmnl_user_tmpl_alloc@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_clone@Base 3.5.0-1 + xfrmnl_user_tmpl_clone@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_cmp@Base 3.5.0-1 + xfrmnl_user_tmpl_cmp@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_dump@Base 3.5.0-1 + xfrmnl_user_tmpl_dump@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_free@Base 3.5.0-1 + xfrmnl_user_tmpl_free@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_aalgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_aalgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_calgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_calgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_daddr@Base 3.5.0-1 + xfrmnl_user_tmpl_get_daddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_ealgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_ealgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_family@Base 3.5.0-1 + xfrmnl_user_tmpl_get_family@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_mode@Base 3.5.0-1 + xfrmnl_user_tmpl_get_mode@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_optional@Base 3.5.0-1 + xfrmnl_user_tmpl_get_optional@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_proto@Base 3.5.0-1 + xfrmnl_user_tmpl_get_proto@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_reqid@Base 3.5.0-1 + xfrmnl_user_tmpl_get_reqid@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_saddr@Base 3.5.0-1 + xfrmnl_user_tmpl_get_saddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_share@Base 3.5.0-1 + xfrmnl_user_tmpl_get_share@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_spi@Base 3.5.0-1 + xfrmnl_user_tmpl_get_spi@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_mode2str@Base 3.5.0-1 + xfrmnl_user_tmpl_mode2str@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_aalgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_aalgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_calgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_calgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_daddr@Base 3.5.0-1 + xfrmnl_user_tmpl_set_daddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_ealgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_ealgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_family@Base 3.5.0-1 + xfrmnl_user_tmpl_set_family@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_mode@Base 3.5.0-1 + xfrmnl_user_tmpl_set_mode@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_optional@Base 3.5.0-1 + xfrmnl_user_tmpl_set_optional@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_proto@Base 3.5.0-1 + xfrmnl_user_tmpl_set_proto@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_reqid@Base 3.5.0-1 + xfrmnl_user_tmpl_set_reqid@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_saddr@Base 3.5.0-1 + xfrmnl_user_tmpl_set_saddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_share@Base 3.5.0-1 + xfrmnl_user_tmpl_set_share@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_spi@Base 3.5.0-1 + xfrmnl_user_tmpl_set_spi@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_str2mode@Base 3.5.0-1 + xfrmnl_user_tmpl_str2mode@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-xfrm-3-dev.install b/src/libnl3/debian/libnl-xfrm-3-dev.install new file mode 100644 index 000000000000..f57e152c5aae --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-xfrm-3* +debian/tmp/usr/lib/*/libnl-xfrm-3*.so +debian/tmp/usr/lib/*/libnl-xfrm-3*.a diff --git a/src/libnl3/debian/patches/series b/src/libnl3/debian/patches/series new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/libnl3/debian/rules b/src/libnl3/debian/rules new file mode 100755 index 000000000000..bb33dda05a64 --- /dev/null +++ b/src/libnl3/debian/rules @@ -0,0 +1,39 @@ +#!/usr/bin/make -f + +DEB_BUILDDIR = debian/build +DEB_MAKE_FLAVORS = main udeb + +udeb_libnl=libnl-3-200-udeb +udeb_libnl_genl=libnl-genl-3-200-udeb + +TG_BRANCHES := debian/etc-libnl-3,debian/out-of-tree,debian/no-symvers + +-include /usr/share/topgit/tg2quilt.mk + +# to export the patch series use +# debian/rules tg-clean +# debian/rules tg-export + + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/rules/autoreconf.mk +include /usr/share/cdbs/1/class/autotools.mk + +# FIXME: not honoured +#CFLAGS_udeb += $(CFLAGS) -Os +CFLAGS += $(if $(findstring udeb,$(cdbs_make_curflavor)),-Os) + +DEB_DH_STRIP_ARGS := --dbg-package=libnl-3-200-dbg +DEB_DH_MAKESHLIBS_ARGS_libnl-3-200 := --add-udeb=$(udeb_libnl) +DEB_DH_MAKESHLIBS_ARGS_libnl-genl-3-200 := --add-udeb=$(udeb_libnl_genl) + +DEB_MAKE_DESTDIRSKEL = $(CURDIR)/debian/tmp +DEB_MAKE_DESTDIRSKEL_udeb = $(CURDIR)/debian/tmp/udeb + +DEB_DH_INSTALL_ARGS_$(udeb) += --sourcedir=debian/tmp/udeb + +DEB_CONFIGURE_EXTRA_FLAGS += --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) + +clean:: + # from some unknown reason CDBS does not remove the builddir + rm -rf $(DEB_BUILDDIR) diff --git a/src/libnl3/debian/source/format b/src/libnl3/debian/source/format new file mode 100644 index 000000000000..163aaf8d82b6 --- /dev/null +++ b/src/libnl3/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/src/libnl3/debian/watch b/src/libnl3/debian/watch new file mode 100644 index 000000000000..9939913ca0e0 --- /dev/null +++ b/src/libnl3/debian/watch @@ -0,0 +1,2 @@ +version=3 +https://github.com/thom311/libnl/releases/libnl-(.*)\.tar\.gz From 04b911341016546fcfa39f31742fb28a2b7686a8 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Tue, 7 Jan 2020 16:42:00 +0800 Subject: [PATCH 0272/1427] [Mellanox]Update the hw-mgmt patch for simx on V.7.0000.2308 (#3957) * [Mellanox/hw-mgmt] Update the hw-mgmt patch for simx on V.7.0000.2308 * removing the extra "[PATCH]" --- .../0001-Make-hw-mgmt-SimX-compatiable.patch | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch index 31a85434fb49..f16c0d02794b 100644 --- a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch +++ b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch @@ -1,53 +1,53 @@ -From 051938b7c49cc18aaddd699939353f591554d635 Mon Sep 17 00:00:00 2001 -From: Mykola Faryma -Date: Wed, 3 Apr 2019 14:09:26 +0000 +From c6ee8c86c35f8b1e60bf4df0d7198f349f8552c1 Mon Sep 17 00:00:00 2001 +From: Stephen Sun +Date: Wed, 25 Dec 2019 19:33:17 +0800 Subject: [PATCH] Make hw-mgmt SimX compatiable. -Signed-off-by: Mykola Faryma +Signed-off-by: Stephen Sun --- usr/usr/bin/hw-management.sh | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh -index fdb3013..68da9bc 100755 +index cff10fe..0511c7c 100755 --- a/usr/usr/bin/hw-management.sh +++ b/usr/usr/bin/hw-management.sh -@@ -646,6 +646,35 @@ do_chip_down() +@@ -737,6 +737,35 @@ do_chip_down() /usr/bin/hw-management-thermal-events.sh change hotplug_asic down %S %p } +handle_simx() +{ -+ local -r onie_platform="$(cat /host/machine.conf | grep onie_platform | cut -d= -f2)" ++ local -r onie_platform="$(cat /host/machine.conf | grep onie_platform | cut -d= -f2)" + -+ local -r syseeprom_cache_path="/var/cache/sonic/decode-syseeprom/syseeprom_cache" -+ local -r syseeprom_hex_path="/usr/share/sonic/device/${onie_platform}/syseeprom.hex" -+ local -r syseeprom_vpd_path="/var/run/hw-management/eeprom/vpd_info" ++ local -r syseeprom_cache_path="/var/cache/sonic/decode-syseeprom/syseeprom_cache" ++ local -r syseeprom_hex_path="/usr/share/sonic/device/${onie_platform}/syseeprom.hex" ++ local -r syseeprom_vpd_path="/var/run/hw-management/eeprom/vpd_info" + -+ case $ACTION in -+ start) -+ /bin/bash -c "/bin/rm -f ${syseeprom_cache_path}" -+ /bin/bash -c "/bin/mkdir -p ${eeprom_path}" -+ /bin/bash -c "/usr/bin/xxd -r -p ${syseeprom_hex_path} ${syseeprom_vpd_path}" -+ ;; -+ stop) -+ /bin/bash -c "/bin/rm -fr ${hw_management_path}" -+ ;; -+ *) -+ echo "Usage: `basename $0` {start|stop}" -+ exit 1 -+ ;; -+ esac ++ case $ACTION in ++ start) ++ /bin/bash -c "/bin/rm -f ${syseeprom_cache_path}" ++ /bin/bash -c "/bin/mkdir -p ${eeprom_path}" ++ /bin/bash -c "/usr/bin/xxd -r -p ${syseeprom_hex_path} ${syseeprom_vpd_path}" ++ ;; ++ stop) ++ /bin/bash -c "/bin/rm -fr ${hw_management_path}" ++ ;; ++ *) ++ echo "Usage: `basename $0` {start|stop}" ++ exit 1 ++ ;; ++ esac +} + +if [[ "$(cat /sys/devices/virtual/dmi/id/chassis_vendor)" = "QEMU" ]]; then -+ handle_simx -+ exit 0 ++ handle_simx ++ exit 0 +fi + case $ACTION in start) - do_start + if [ -d /var/run/hw-management ]; then -- 1.9.1 From 3548587b733f1c11ffadc4af0a7598b269b85588 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 7 Jan 2020 15:52:49 -0800 Subject: [PATCH 0273/1427] [apt] Instruct apt-get to NOT check the "Valid Until" date in Release files (#3973) This is an addendum to #3958, which also instructs apt to ignore the "Valid Until" date in Release files inside the slave containers, making a complete solution, much like the previously abandoned PR #2609. This patch also unifies file names and contents. When the Debian team archives a repo, it stops updating the "Valid Until" date, thus apt-get will not apply updates for that repo unless we explicitly tell it to ignore the "Valid Until" date. Also, this has become an issue with active (i.e., non-archived) repos twice in the past year because the Debian folks seem to occasionally let the expiration lapse before updating the date. This will cause SONiC builds to fail with a message like E: Release file for http://debian-archive.trafficmanager.net/debian-security/dists/jessie/updates/InRelease is expired (invalid since 3d 3h 11min 20s). Updates for this repository will not be applied. until the dates have been updated and propagated to all mirrors. With this patch, SONiC should no longer be affected by lapsed "Valid Until" dates, whether they be accidental or purposeful. --- dockers/docker-base-stretch/Dockerfile.j2 | 2 +- dockers/docker-base-stretch/aptconf_archive_expired_release | 3 --- dockers/docker-base-stretch/no-check-valid-until | 4 ++++ dockers/docker-base/Dockerfile.j2 | 2 +- dockers/docker-base/aptconf_archive_expired_release | 3 --- dockers/docker-base/no-check-valid-until | 4 ++++ files/apt/apt.conf.d/no-check-valid-until | 3 +++ sonic-slave-jessie/Dockerfile.j2 | 2 ++ sonic-slave-jessie/no-check-valid-until | 4 ++++ sonic-slave-stretch/Dockerfile.j2 | 2 ++ sonic-slave-stretch/no-check-valid-until | 4 ++++ 11 files changed, 25 insertions(+), 8 deletions(-) delete mode 100644 dockers/docker-base-stretch/aptconf_archive_expired_release create mode 100644 dockers/docker-base-stretch/no-check-valid-until delete mode 100644 dockers/docker-base/aptconf_archive_expired_release create mode 100644 dockers/docker-base/no-check-valid-until create mode 100644 sonic-slave-jessie/no-check-valid-until create mode 100644 sonic-slave-stretch/no-check-valid-until diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index d8188a06afd6..dea58a210f89 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -34,7 +34,7 @@ COPY ["sources.list.arm64", "/etc/apt/sources.list"] COPY ["sources.list", "/etc/apt/sources.list"] {% endif %} COPY ["no_install_recommend_suggest", "/etc/apt/apt.conf.d"] -COPY ["aptconf_archive_expired_release", "/etc/apt/apt.conf.d"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] # Update apt cache and # pre-install fundamental packages diff --git a/dockers/docker-base-stretch/aptconf_archive_expired_release b/dockers/docker-base-stretch/aptconf_archive_expired_release deleted file mode 100644 index 67bc409b2174..000000000000 --- a/dockers/docker-base-stretch/aptconf_archive_expired_release +++ /dev/null @@ -1,3 +0,0 @@ -# Instruct apt-get to override expired releases repo list for jessie archives - -Acquire::Check-Valid-Until "0"; diff --git a/dockers/docker-base-stretch/no-check-valid-until b/dockers/docker-base-stretch/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/dockers/docker-base-stretch/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2 index cb2ff80186a3..e45235a1e139 100644 --- a/dockers/docker-base/Dockerfile.j2 +++ b/dockers/docker-base/Dockerfile.j2 @@ -32,7 +32,7 @@ COPY ["dpkg_01_drop", "/etc/dpkg/dpkg.cfg.d/01_drop"] COPY ["sources.list.armhf", "/etc/apt/sources.list"] {% elif CONFIGURED_ARCH == "arm64" %} COPY ["sources.list.arm64", "/etc/apt/sources.list"] -COPY ["aptconf_archive_expired_release", "/etc/apt/apt.conf.d"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] {% else %} COPY ["sources.list", "/etc/apt/sources.list"] {% endif %} diff --git a/dockers/docker-base/aptconf_archive_expired_release b/dockers/docker-base/aptconf_archive_expired_release deleted file mode 100644 index 67bc409b2174..000000000000 --- a/dockers/docker-base/aptconf_archive_expired_release +++ /dev/null @@ -1,3 +0,0 @@ -# Instruct apt-get to override expired releases repo list for jessie archives - -Acquire::Check-Valid-Until "0"; diff --git a/dockers/docker-base/no-check-valid-until b/dockers/docker-base/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/dockers/docker-base/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/files/apt/apt.conf.d/no-check-valid-until b/files/apt/apt.conf.d/no-check-valid-until index 97b9c9005181..c7c25d017f7f 100644 --- a/files/apt/apt.conf.d/no-check-valid-until +++ b/files/apt/apt.conf.d/no-check-valid-until @@ -1 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + Acquire::Check-Valid-Until "false"; diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index 7ed7c4eb7096..dce30193420c 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -8,6 +8,8 @@ FROM debian:jessie MAINTAINER johnar@microsoft.com +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d/"] + ## Remove retired jessie-updates repo RUN sed -i '/http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list diff --git a/sonic-slave-jessie/no-check-valid-until b/sonic-slave-jessie/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/sonic-slave-jessie/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index d0e3775396dc..054920b8280e 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -8,6 +8,8 @@ FROM debian:stretch MAINTAINER gulv@microsoft.com +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d/"] + RUN echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free" >> /etc/apt/sources.list && \ echo "deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free" >> /etc/apt/sources.list && \ echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free" >> /etc/apt/sources.list && \ diff --git a/sonic-slave-stretch/no-check-valid-until b/sonic-slave-stretch/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/sonic-slave-stretch/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; From 2658ab8add1aea30380f83564e55af0931fd49f8 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Tue, 7 Jan 2020 17:48:03 -0800 Subject: [PATCH 0274/1427] [dhcp-relay]: Add DHCP Relay Monitor (#3886) DHCP relay MONitor (dhcpmon) keeps track of DORA messages. If DHCP Relay is detected to be not forwarding DORA message, dhcpmon will log such event to syslog. Under the hood dhcpmon keeps counts of clients DR messages, forwarded DR messages, DHCP server OA messages, and forwarded OA messages. dhcpmon will check every 12 sec (configurable) if counts are monotonically increasing and record snapshot of those counters. dhcpmon will report discrepancies when detected between current counters and snapshot counters. pull-request: https://github.com/Azure/sonic-buildimage/pull/3886 signed-off-by: Tamer Ahmed --- .gitignore | 6 + .../docker-dhcp-relay.supervisord.conf.j2 | 48 ++ dockers/docker-dhcp-relay/start.sh | 6 + rules/dhcpmon.mk | 8 + rules/docker-dhcp-relay.mk | 2 +- sonic-slave-stretch/Dockerfile.j2 | 5 +- src/dhcpmon/Makefile | 44 ++ src/dhcpmon/debian/changelog | 5 + src/dhcpmon/debian/compat | 1 + src/dhcpmon/debian/control | 16 + src/dhcpmon/debian/rules | 3 + src/dhcpmon/objects.mk | 4 + src/dhcpmon/src/dhcp_device.c | 460 ++++++++++++++++++ src/dhcpmon/src/dhcp_device.h | 113 +++++ src/dhcpmon/src/dhcp_devman.c | 149 ++++++ src/dhcpmon/src/dhcp_devman.h | 76 +++ src/dhcpmon/src/dhcp_mon.c | 199 ++++++++ src/dhcpmon/src/dhcp_mon.h | 54 ++ src/dhcpmon/src/main.c | 174 +++++++ src/dhcpmon/src/subdir.mk | 29 ++ .../docker-dhcp-relay.supervisord.conf | 13 + 21 files changed, 1413 insertions(+), 2 deletions(-) create mode 100644 rules/dhcpmon.mk create mode 100644 src/dhcpmon/Makefile create mode 100644 src/dhcpmon/debian/changelog create mode 100644 src/dhcpmon/debian/compat create mode 100644 src/dhcpmon/debian/control create mode 100755 src/dhcpmon/debian/rules create mode 100644 src/dhcpmon/objects.mk create mode 100644 src/dhcpmon/src/dhcp_device.c create mode 100644 src/dhcpmon/src/dhcp_device.h create mode 100644 src/dhcpmon/src/dhcp_devman.c create mode 100644 src/dhcpmon/src/dhcp_devman.h create mode 100644 src/dhcpmon/src/dhcp_mon.c create mode 100644 src/dhcpmon/src/dhcp_mon.h create mode 100644 src/dhcpmon/src/main.c create mode 100644 src/dhcpmon/src/subdir.mk diff --git a/.gitignore b/.gitignore index fbf646fcd40f..316cf974e6c1 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,11 @@ target/ # Subdirectories in src src/bash/* !src/bash/Makefile +src/dhcpmon/debian/* +!src/dhcpmon/debian/changelog +!src/dhcpmon/debian/compat +!src/dhcpmon/debian/control +!src/dhcpmon/debian/rules src/ixgbe/* !src/ixgbe/Makefile src/isc-dhcp/* @@ -106,6 +111,7 @@ src/thrift/* # Autogenerated Dockerfiles sonic-slave/Dockerfile sonic-slave-stretch/Dockerfile +sonic-slave-jessie/Dockerfile dockers/docker-base/Dockerfile dockers/docker-base-stretch/Dockerfile dockers/docker-config-engine/Dockerfile diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index e738e8699e6c..94fdbfdaff2f 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -85,5 +85,53 @@ stderr_logfile=syslog {% endif %} {% endif %} {% endfor %} + +[group:dhcpmon] +programs= +{%- set add_preceding_comma = { 'flag': False } %} +{% for vlan_name in VLAN %} +{% if VLAN[vlan_name]['dhcp_servers'] %} +{% if add_preceding_comma.flag %},{% endif %} +{% set _dummy = add_preceding_comma.update({'flag': True}) %} +dhcpmon-{{ vlan_name }} +{%- endif %} +{% endfor %} + + +{# Create a program entry for each DHCP MONitor instance #} +{% set relay_for_ipv4 = { 'flag': False } %} +{% for vlan_name in VLAN %} +{% if VLAN[vlan_name]['dhcp_servers'] %} +{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} +{% if dhcp_server | ipv4 %} +{% set _dummy = relay_for_ipv4.update({'flag': True}) %} +{% endif %} +{% endfor %} +{% if relay_for_ipv4.flag %} +{% set _dummy = relay_for_ipv4.update({'flag': False}) %} +[program:dhcpmon-{{ vlan_name }}] +{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #} +command=/usr/sbin/dhcpmon -id {{ vlan_name }} +{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #} +{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%} +{% endfor %} +{% for (name, prefix) in INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} -iu {{ name }}{% endif -%} +{% endfor %} +{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} -iu {{ name }}{% endif -%} +{% endfor %} + +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +{% endif %} +{% endif %} +{% endfor %} + {% endif %} {% endif %} diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index 0ac5ea1a10ec..dbbf32251080 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -19,3 +19,9 @@ if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then # Start all DHCP relay agent(s) supervisorctl start isc-dhcp-relay:* fi + +# If our supervisor config has entries in the "dhcpmon" group... +if [ $(supervisorctl status | grep -c "^dhcpmon:") -gt 0 ]; then + # Start all DHCP Monitor daemon(s) + supervisorctl start dhcpmon:* +fi diff --git a/rules/dhcpmon.mk b/rules/dhcpmon.mk new file mode 100644 index 000000000000..3d80d227c156 --- /dev/null +++ b/rules/dhcpmon.mk @@ -0,0 +1,8 @@ +# SONiC DHCP MONitor package + +SONIC_DHCPMON_VERSION = 1.0.0-0 +SONIC_DHCPMON_PKG_NAME = dhcpmon + +SONIC_DHCPMON = sonic-$(SONIC_DHCPMON_PKG_NAME)_$(SONIC_DHCPMON_VERSION)_$(CONFIGURED_ARCH).deb +$(SONIC_DHCPMON)_SRC_PATH = $(SRC_PATH)/$(SONIC_DHCPMON_PKG_NAME) +SONIC_DPKG_DEBS += $(SONIC_DHCPMON) diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 5aae24ee33b5..8deb6ebbfad7 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -6,7 +6,7 @@ DOCKER_DHCP_RELAY_DBG = $(DOCKER_DHCP_RELAY_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/$(DOCKER_DHCP_RELAY_STEM) -$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(REDIS_TOOLS) +$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(REDIS_TOOLS) $(SONIC_DHCPMON) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS += $(ISC_DHCP_RELAY_DBG) diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 054920b8280e..8786a9d4101f 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -295,7 +295,10 @@ RUN apt-get update && apt-get install -y \ # For kdump-tools liblzo2-dev \ # For SAI3.7 - libprotobuf-dev + libprotobuf-dev \ +# For DHCP Monitor tool + libexplain-dev \ + libevent-dev ## Config dpkg ## install the configuration file if it’s currently missing diff --git a/src/dhcpmon/Makefile b/src/dhcpmon/Makefile new file mode 100644 index 000000000000..61cde376730b --- /dev/null +++ b/src/dhcpmon/Makefile @@ -0,0 +1,44 @@ +RM := rm -rf +DHCPMON_TARGET := dhcpmon +CP := cp +MKDIR := mkdir +CC := gcc +MV := mv + +# All of the sources participating in the build are defined here +-include src/subdir.mk +-include objects.mk + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: sonic-dhcpmon + +# Tool invocations +sonic-dhcpmon: $(OBJS) $(USER_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: GCC C Linker' + $(CC) -o "$(DHCPMON_TARGET)" $(OBJS) $(USER_OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +# Other Targets +install: + $(MKDIR) -p $(DESTDIR)/usr/sbin + $(MV) $(DHCPMON_TARGET) $(DESTDIR)/usr/sbin + +deinstall: + $(RM) $(DESTDIR)/usr/sbin/$(DHCPMON_TARGET) + $(RM) -rf $(DESTDIR)/usr/sbin + +clean: + -$(RM) $(EXECUTABLES)$(OBJS)$(C_DEPS) $(DHCPMON_TARGET) + -@echo ' ' + +.PHONY: all clean dependents diff --git a/src/dhcpmon/debian/changelog b/src/dhcpmon/debian/changelog new file mode 100644 index 000000000000..83b79d6d93bd --- /dev/null +++ b/src/dhcpmon/debian/changelog @@ -0,0 +1,5 @@ +sonic-dhcpmon (1.0.0-0) UNRELEASED; urgency=medium + + * Initial release. + + -- Tamer Ahmed Mon, 09 Dec 2019 12:00:00 -0700 diff --git a/src/dhcpmon/debian/compat b/src/dhcpmon/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/dhcpmon/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/dhcpmon/debian/control b/src/dhcpmon/debian/control new file mode 100644 index 000000000000..2f05fda79963 --- /dev/null +++ b/src/dhcpmon/debian/control @@ -0,0 +1,16 @@ +Source: sonic-dhcpmon +Section: devel +Priority: optional +Maintainer: Tamer Ahmed +Build-Depends: debhelper (>= 8.0.0), + dh-systemd +Standards-Version: 3.9.3 +Homepage: https://github.com/Azure/sonic-buildimage +XS-Go-Import-Path: github.com/Azure/sonic-buildimage + +Package: sonic-dhcpmon +Architecture: any +Built-Using: ${misc:Built-Using} +Depends: libexplain51, + libevent-2.0-5 +Description: SONiC DHCP Monitor diff --git a/src/dhcpmon/debian/rules b/src/dhcpmon/debian/rules new file mode 100755 index 000000000000..3995a26d7fcd --- /dev/null +++ b/src/dhcpmon/debian/rules @@ -0,0 +1,3 @@ +#!/usr/bin/make -f +%: + dh $@ --with systemd diff --git a/src/dhcpmon/objects.mk b/src/dhcpmon/objects.mk new file mode 100644 index 000000000000..c9b774a53921 --- /dev/null +++ b/src/dhcpmon/objects.mk @@ -0,0 +1,4 @@ +USER_OBJS := + +LIBS := -levent -lexplain + diff --git a/src/dhcpmon/src/dhcp_device.c b/src/dhcpmon/src/dhcp_device.c new file mode 100644 index 000000000000..aa0c0f835cbd --- /dev/null +++ b/src/dhcpmon/src/dhcp_device.c @@ -0,0 +1,460 @@ +/** + * @file dhcp_device.c + * + * device (interface) module + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_device.h" + +/** Start of Ether header of a captured frame */ +#define ETHER_START_OFFSET 0 +/** Start of IP header of a captured frame */ +#define IP_START_OFFSET (ETHER_START_OFFSET + ETHER_HDR_LEN) +/** Start of UDP header of a captured frame */ +#define UDP_START_OFFSET (IP_START_OFFSET + sizeof(struct ip)) +/** Start of DHCP header of a captured frame */ +#define DHCP_START_OFFSET (UDP_START_OFFSET + sizeof(struct udphdr)) +/** Start of DHCP Options segment of a captured frame */ +#define DHCP_OPTIONS_HEADER_SIZE 240 + +#define OP_LDHA (BPF_LD | BPF_H | BPF_ABS) /** bpf ldh Abs */ +#define OP_LDHI (BPF_LD | BPF_H | BPF_IND) /** bpf ldh Ind */ +#define OP_LDB (BPF_LD | BPF_B | BPF_ABS) /** bpf ldb Abs*/ +#define OP_JEQ (BPF_JMP | BPF_JEQ | BPF_K) /** bpf jeq */ +#define OP_JGT (BPF_JMP | BPF_JGT | BPF_K) /** bpf jgt */ +#define OP_RET (BPF_RET | BPF_K) /** bpf ret */ +#define OP_JSET (BPF_JMP | BPF_JSET | BPF_K) /** bpf jset */ +#define OP_LDXB (BPF_LDX | BPF_B | BPF_MSH) /** bpf ldxb */ + +/** Berkley Packet Fitler program for "udp and (port 67 or port 68)". This program is obtained suing the following + * tcpdump command: 'tcpdump -dd "udp and (port 67 or port 68)"' + */ +static struct sock_filter dhcp_bpf_code[] = { + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x0000000c}, // (000) ldh [12] + {.code = OP_JEQ, .jt = 0, .jf = 7, .k = 0x000086dd}, // (001) jeq #0x86dd jt 2 jf 9 + {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000014}, // (002) ldb [20] + {.code = OP_JEQ, .jt = 0, .jf = 18, .k = 0x00000011}, // (003) jeq #0x11 jt 4 jf 22 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000036}, // (004) ldh [54] + {.code = OP_JEQ, .jt = 15, .jf = 0, .k = 0x00000043}, // (005) jeq #0x43 jt 21 jf 6 + {.code = OP_JEQ, .jt = 14, .jf = 0, .k = 0x00000044}, // (006) jeq #0x44 jt 21 jf 7 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000038}, // (007) ldh [56] + {.code = OP_JEQ, .jt = 12, .jf = 11, .k = 0x00000043}, // (008) jeq #0x43 jt 21 jf 20 + {.code = OP_JEQ, .jt = 0, .jf = 12, .k = 0x00000800}, // (009) jeq #0x800 jt 10 jf 22 + {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000017}, // (010) ldb [23] + {.code = OP_JEQ, .jt = 0, .jf = 10, .k = 0x00000011}, // (011) jeq #0x11 jt 12 jf 22 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000014}, // (012) ldh [20] + {.code = OP_JSET, .jt = 8, .jf = 0, .k = 0x00001fff}, // (013) jset #0x1fff jt 22 jf 14 + {.code = OP_LDXB, .jt = 0, .jf = 0, .k = 0x0000000e}, // (014) ldxb 4*([14]&0xf) + {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x0000000e}, // (015) ldh [x + 14] + {.code = OP_JEQ, .jt = 4, .jf = 0, .k = 0x00000043}, // (016) jeq #0x43 jt 21 jf 17 + {.code = OP_JEQ, .jt = 3, .jf = 0, .k = 0x00000044}, // (017) jeq #0x44 jt 21 jf 18 + {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x00000010}, // (018) ldh [x + 16] + {.code = OP_JEQ, .jt = 1, .jf = 0, .k = 0x00000043}, // (019) jeq #0x43 jt 21 jf 20 + {.code = OP_JEQ, .jt = 0, .jf = 1, .k = 0x00000044}, // (020) jeq #0x44 jt 21 jf 22 + {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00040000}, // (021) ret #262144 + {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00000000}, // (022) ret #0 +}; + +/** Filter program socket struct */ +static struct sock_fprog dhcp_sock_bfp = { + .len = sizeof(dhcp_bpf_code) / sizeof(*dhcp_bpf_code), .filter = dhcp_bpf_code +}; + +/** global aggregate counter for DHCP interfaces */ +static dhcp_device_counters_t glob_counters[DHCP_DIR_COUNT] = { + [DHCP_RX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, + [DHCP_TX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, +}; + +/** global aggregate counter snapshot for DHCP interfaces */ +static dhcp_device_counters_t glob_counters_snapshot[DHCP_DIR_COUNT] = { + [DHCP_RX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, + [DHCP_TX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, +}; + +/** + * @code handle_dhcp_option_53(context, dhcp_option, dir); + * + * @brief handle the logic related to DHCP option 53 + * + * @param context Device (interface) context + * @param dhcp_option pointer to DHCP option buffer space + * @param dir packet direction + * + * @return none + */ +static void handle_dhcp_option_53(dhcp_device_context_t *context, const u_char *dhcp_option, dhcp_packet_direction_t dir) +{ + switch (dhcp_option[2]) + { + case 1: + context->counters[dir].discover++; + if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].discover++; + } + break; + case 2: + context->counters[dir].offer++; + if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].offer++; + } + break; + case 3: + context->counters[dir].request++; + if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].request++; + } + break; + case 5: + context->counters[dir].ack++; + if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].ack++; + } + break; + case 4: // type: Decline + case 6 ... 8: + // type: NAK, Release, Inform + break; + default: + syslog(LOG_WARNING, "handle_dhcp_option_53(%s): Unknown DHCP option 53 type %d", context->intf, dhcp_option[2]); + break; + } +} + +/** + * @code read_callback(fd, event, arg); + * + * @brief callback for libevent which is called every time out in order to read queued packet capture + * + * @param fd socket to read from + * @param event libevent triggered event + * @param arg user provided argument for callback (interface context) + * @param packet pointer to packet data + * + * @return none + */ +static void read_callback(int fd, short event, void *arg) +{ + dhcp_device_context_t *context = (dhcp_device_context_t*) arg; + ssize_t buffer_sz; + + while ((event == EV_READ) && + ((buffer_sz = recv(fd, context->buffer, context->snaplen, MSG_DONTWAIT)) > 0)) { + struct ether_header *ethhdr = (struct ether_header*) context->buffer; + struct udphdr *udp = (struct udphdr*) (context->buffer + UDP_START_OFFSET); + int dhcp_option_offset = DHCP_START_OFFSET + DHCP_OPTIONS_HEADER_SIZE; + + if ((buffer_sz > UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) && + (ntohs(udp->len) > DHCP_OPTIONS_HEADER_SIZE)) { + int dhcp_sz = ntohs(udp->len) < buffer_sz - UDP_START_OFFSET - sizeof(struct udphdr) ? + ntohs(udp->len) : buffer_sz - UDP_START_OFFSET - sizeof(struct udphdr); + int dhcp_option_sz = dhcp_sz - DHCP_OPTIONS_HEADER_SIZE; + const u_char *dhcp_option = context->buffer + dhcp_option_offset; + dhcp_packet_direction_t dir = (ethhdr->ether_shost[0] == context->mac[0] && + ethhdr->ether_shost[1] == context->mac[1] && + ethhdr->ether_shost[2] == context->mac[2] && + ethhdr->ether_shost[3] == context->mac[3] && + ethhdr->ether_shost[4] == context->mac[4] && + ethhdr->ether_shost[5] == context->mac[5]) ? + DHCP_TX : DHCP_RX; + int offset = 0; + int stop_dhcp_processing = 0; + while ((offset < (dhcp_option_sz + 1)) && dhcp_option[offset] != 255) { + switch (dhcp_option[offset]) + { + case 53: + if (offset < (dhcp_option_sz + 2)) { + handle_dhcp_option_53(context, &dhcp_option[offset], dir); + } + stop_dhcp_processing = 1; // break while loop since we are only interested in Option 53 + break; + default: + break; + } + + if (stop_dhcp_processing == 1) { + break; + } + + if (dhcp_option[offset] == 0) { // DHCP Option Padding + offset++; + } else { + offset += dhcp_option[offset + 1] + 2; + } + } + } else { + syslog(LOG_WARNING, "read_callback(%s): read length (%ld) is too small to capture DHCP options", + context->intf, buffer_sz); + } + } +} + +/** + * @code dhcp_device_validate(counters, counters_snapshot); + * + * @brief validate current interface counters by comparing aggregate counter with snapshot counters. + * + * @param counters recent interface counter + * @param counters_snapshot snapshot counters + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +static dhcp_mon_status_t dhcp_device_validate(dhcp_device_counters_t *counters, + dhcp_device_counters_t *counters_snapshot) +{ + dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY; + + if ((counters[DHCP_RX].discover == counters_snapshot[DHCP_RX].discover) && + (counters[DHCP_RX].offer == counters_snapshot[DHCP_RX].offer ) && + (counters[DHCP_RX].request == counters_snapshot[DHCP_RX].request ) && + (counters[DHCP_RX].ack == counters_snapshot[DHCP_RX].ack ) ) { + rv = DHCP_MON_STATUS_INDETERMINATE; + } else { + // if we have rx DORA then we should have corresponding tx DORA (DORA being relayed) + if (((counters[DHCP_RX].discover > counters_snapshot[DHCP_RX].discover) && + (counters[DHCP_TX].discover <= counters_snapshot[DHCP_TX].discover) ) || + ((counters[DHCP_RX].offer > counters_snapshot[DHCP_RX].offer ) && + (counters[DHCP_TX].offer <= counters_snapshot[DHCP_TX].offer ) ) || + ((counters[DHCP_RX].request > counters_snapshot[DHCP_RX].request ) && + (counters[DHCP_TX].request <= counters_snapshot[DHCP_TX].request ) ) || + ((counters[DHCP_RX].ack > counters_snapshot[DHCP_RX].ack ) && + (counters[DHCP_TX].ack <= counters_snapshot[DHCP_TX].ack ) ) ) { + rv = DHCP_MON_STATUS_UNHEALTHY; + } + } + + return rv; +} + +/** + * @code dhcp_print_counters(counters); + * + * @brief prints DHCP counters to sylsog. + * + * @param counters interface counter + */ +static void dhcp_print_counters(dhcp_device_counters_t *counters) +{ + syslog(LOG_NOTICE, "DHCP Discover rx: %lu, tx:%lu, Offer rx: %lu, tx:%lu, Request rx: %lu, tx:%lu, ACK rx: %lu, tx:%lu\n", + counters[DHCP_RX].discover, counters[DHCP_TX].discover, + counters[DHCP_RX].offer, counters[DHCP_TX].offer, + counters[DHCP_RX].request, counters[DHCP_TX].request, + counters[DHCP_RX].ack, counters[DHCP_TX].ack); +} + +/** + * @code init_socket(context, intf, snaplen, base); + * + * @brief initializes socket, bind it to interface and bpf prgram, and + * associate with libevent base + * + * @param context pointer to device (interface) context + * @param intf interface name + * @param snaplen length of packet capture + * @param base libevent base + * + * @return 0 on success, otherwise for failure + */ +static int init_socket(dhcp_device_context_t *context, + const char *intf, + size_t snaplen, + struct event_base *base) +{ + int rv = -1; + + do { + if (snaplen < UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) { + syslog(LOG_ALERT, "init_socket(%s): snap length is too low to capture DHCP options", intf); + break; + } + + context->sock = socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, htons(ETH_P_ALL)); + if (context->sock < 0) { + syslog(LOG_ALERT, "socket: failed to open socket with '%s'\n", strerror(errno)); + break; + } + + struct sockaddr_ll addr; + memset(&addr, 0, sizeof(addr)); + addr.sll_ifindex = if_nametoindex(intf); + addr.sll_family = AF_PACKET; + addr.sll_protocol = htons(ETH_P_ALL); + if (bind(context->sock, (struct sockaddr *) &addr, sizeof(addr))) { + syslog(LOG_ALERT, "bind: failed to bind to interface '%s' with '%s'\n", intf, strerror(errno)); + break; + } + + if (setsockopt(context->sock, SOL_SOCKET, SO_ATTACH_FILTER, &dhcp_sock_bfp, sizeof(dhcp_sock_bfp)) != 0) { + syslog(LOG_ALERT, "setsockopt: failed to attach filter with '%s'\n", strerror(errno)); + break; + } + + context->buffer = (uint8_t *) malloc(snaplen); + if (context->buffer == NULL) { + syslog(LOG_ALERT, "malloc: failed to allocate memory for socket buffer '%s'\n", strerror(errno)); + break; + } + context->snaplen = snaplen; + + struct event *ev = event_new(base, context->sock, EV_READ | EV_PERSIST, read_callback, context); + if (ev == NULL) { + syslog(LOG_ALERT, "event_new: failed to allocate memory for libevent event '%s'\n", strerror(errno)); + break; + } + event_add(ev, NULL); + + strncpy(context->intf, intf, sizeof(context->intf) - 1); + context->intf[sizeof(context->intf) - 1] = '\0'; + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code initialize_intf_mac_and_ip_addr(context); + * + * @brief initializes device (interface) mac/ip addresses + * + * @param context pointer to device (interface) context + * + * @return 0 on success, otherwise for failure + */ +static int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context) +{ + int rv = -1; + + do { + int fd; + struct ifreq ifr; + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + syslog(LOG_ALERT, "socket: %s", strerror(errno)); + break; + } + + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name, context->intf, sizeof(ifr.ifr_name) - 1); + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + + // Get network address + if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) { + syslog(LOG_ALERT, "ioctl: %s", explain_ioctl(fd, SIOCGIFADDR, &ifr)); + break; + } + context->ip = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr; + + // Get mac address + if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { + syslog(LOG_ALERT, "ioctl: %s", explain_ioctl(fd, SIOCGIFHWADDR, &ifr)); + break; + } + memcpy(context->mac, ifr.ifr_hwaddr.sa_data, sizeof(context->mac)); + + close(fd); + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_device_init(context, intf, snaplen, is_uplink, base); + * + * @brief initializes device (interface) that handles packet capture per interface. + */ +int dhcp_device_init(dhcp_device_context_t **context, + const char *intf, + int snaplen, + uint8_t is_uplink, + struct event_base *base) +{ + int rv = -1; + dhcp_device_context_t *dev_context = NULL; + + if ((context != NULL) && (strlen(intf) < sizeof(dev_context->intf))) { + + dev_context = (dhcp_device_context_t *) malloc(sizeof(dhcp_device_context_t)); + if (dev_context != NULL) { + if ((init_socket(dev_context, intf, snaplen, base) == 0) && + (initialize_intf_mac_and_ip_addr(dev_context) == 0 ) ) { + + dev_context->is_uplink = is_uplink; + + memset(&dev_context->counters, 0, sizeof(dev_context->counters)); + memset(&dev_context->counters_snapshot, 0, sizeof(dev_context->counters_snapshot)); + + *context = dev_context; + rv = 0; + } + } + else { + syslog(LOG_ALERT, "malloc: failed to allocated device context memory for '%s'", dev_context->intf); + } + } + + return rv; +} + +/** + * @code dhcp_device_shutdown(context); + * + * @brief shuts down device (interface). Also, stops packet capture on interface and cleans up any allocated memory + */ +void dhcp_device_shutdown(dhcp_device_context_t *context) +{ + free(context); +} + +/** + * @code dhcp_device_get_status(context); + * + * @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate + * status + */ +dhcp_mon_status_t dhcp_device_get_status(dhcp_device_context_t *context) +{ + dhcp_mon_status_t rv = 0; + + if (context != NULL) { + rv = dhcp_device_validate(context->counters, context->counters_snapshot); + memcpy(context->counters_snapshot, context->counters, sizeof(context->counters_snapshot)); + } else { + rv = dhcp_device_validate(glob_counters, glob_counters_snapshot); + memcpy(glob_counters_snapshot, glob_counters, sizeof(glob_counters_snapshot)); + } + + return rv; +} + +/** + * @code dhcp_device_print_status(); + * + * @brief prints status counters to syslog. If context is null, it will print aggregate status + */ +void dhcp_device_print_status(dhcp_device_context_t *context) +{ + if (context != NULL) { + dhcp_print_counters(context->counters); + } else { + dhcp_print_counters(glob_counters); + } +} diff --git a/src/dhcpmon/src/dhcp_device.h b/src/dhcpmon/src/dhcp_device.h new file mode 100644 index 000000000000..04113eeabdc0 --- /dev/null +++ b/src/dhcpmon/src/dhcp_device.h @@ -0,0 +1,113 @@ +/** + * @file dhcp_device.h + * + * device (interface) module + */ + +#ifndef DHCP_DEVICE_H_ +#define DHCP_DEVICE_H_ + +#include +#include +#include +#include + +#include +#include +#include + + +/** packet direction */ +typedef enum +{ + DHCP_RX, /** RX DHCP packet */ + DHCP_TX, /** TX DHCP packet */ + + DHCP_DIR_COUNT +} dhcp_packet_direction_t; + +/** dhcp health status */ +typedef enum +{ + DHCP_MON_STATUS_HEALTHY, /** DHCP relay is healthy */ + DHCP_MON_STATUS_UNHEALTHY, /** DHCP relay is unhealthy and is missing out on some packets */ + DHCP_MON_STATUS_INDETERMINATE, /** DHCP relay health could not be determined */ +} dhcp_mon_status_t; + +/** DHCP device (interface) health counters */ +typedef struct +{ + uint64_t discover; /** DHCP discover packets */ + uint64_t offer; /** DHCP offer packets */ + uint64_t request; /** DHCP request packets */ + uint64_t ack; /** DHCP ack packets */ +} dhcp_device_counters_t; + +/** DHCP device (interface) context */ +typedef struct +{ + int sock; /** Raw socket associated with this device/interface */ + in_addr_t ip; /** network address of this device (interface) */ + uint8_t mac[ETHER_ADDR_LEN]; /** hardware address of this device (interface) */ + uint8_t is_uplink; /** north interface? */ + char intf[IF_NAMESIZE]; /** device (interface) name */ + uint8_t *buffer; /** buffer used to read socket data */ + size_t snaplen; /** snap length or buffer size */ + dhcp_device_counters_t counters[DHCP_DIR_COUNT]; + /** current coutners of DORA packets */ + dhcp_device_counters_t counters_snapshot[DHCP_DIR_COUNT]; + /** counter snapshot */ +} dhcp_device_context_t; + +/** + * @code dhcp_device_init(context, intf, snaplen, timeout_ms, is_uplink, base); + * + * @brief initializes device (interface) that handles packet capture per interface. + * + * @param context(inout) pointer to device (interface) context + * @param intf interface name + * @param snaplen length of packet capture + * @param is_uplink uplink interface + * @param base pointer to libevent base + * + * @return 0 on success, otherwise for failure + */ +int dhcp_device_init(dhcp_device_context_t **context, + const char *intf, + int snaplen, + uint8_t is_uplink, + struct event_base *base); + +/** + * @code dhcp_device_shutdown(context); + * + * @brief shuts down device (interface). Also, stops packet capture on interface and cleans up any allocated memory + * + * @param context Device (interface) context + * + * @return nonedhcp_device_shutdown + */ +void dhcp_device_shutdown(dhcp_device_context_t *context); + +/** + * @code dhcp_device_get_status(context); + * + * @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate + * status + * + * @param context Device (interface) context + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +dhcp_mon_status_t dhcp_device_get_status(dhcp_device_context_t *context); + +/** + * @code dhcp_device_print_status(); + * + * @brief prints status counters to syslog. If context is null, it will print aggregate status + * + * @return none + */ +void dhcp_device_print_status(dhcp_device_context_t *context); + +#endif /* DHCP_DEVICE_H_ */ diff --git a/src/dhcpmon/src/dhcp_devman.c b/src/dhcpmon/src/dhcp_devman.c new file mode 100644 index 000000000000..c19cbde591b8 --- /dev/null +++ b/src/dhcpmon/src/dhcp_devman.c @@ -0,0 +1,149 @@ +/** + * @file dhcp_devman.c + * + * Device (interface) manager + */ +#include +#include +#include +#include +#include +#include + +#include "dhcp_devman.h" + +/** struct for interface information */ +struct intf +{ + const char *name; /** interface name */ + uint8_t is_uplink; /** is uplink (north) interface */ + dhcp_device_context_t *dev_context; /** device (interface_ context */ + LIST_ENTRY(intf) entry; /** list link/pointers entries */ +}; + +/** intfs list of interfaces */ +static LIST_HEAD(intf_list, intf) intfs; +/** dhcp_num_south_intf number of south interfaces */ +static uint32_t dhcp_num_south_intf = 0; +/** dhcp_num_north_intf number of north interfaces */ +static uint32_t dhcp_num_north_intf = 0; + +/** + * @code dhcp_devman_init(); + * + * initializes device (interface) manager that keeps track of interfaces and assert that there is one south + * interface and as many north interfaces + */ +void dhcp_devman_init() +{ + LIST_INIT(&intfs); +} + +/** + * @code dhcp_devman_shutdown(); + * + * shuts down device (interface) manager. Also, stops packet capture on interface and cleans up any allocated + * memory + */ +void dhcp_devman_shutdown() +{ + struct intf *int_ptr, *prev_intf = NULL; + + LIST_FOREACH(int_ptr, &intfs, entry) { + dhcp_device_shutdown(int_ptr->dev_context); + if (prev_intf) { + LIST_REMOVE(prev_intf, entry); + free(prev_intf); + prev_intf = int_ptr; + } + } + + if (prev_intf) { + LIST_REMOVE(prev_intf, entry); + free(prev_intf); + } +} + +/** + * @code dhcp_devman_add_intf(name, uplink); + * + * @brief adds interface to the device manager. + */ +int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) +{ + int rv = -1; + struct intf *dev = malloc(sizeof(struct intf)); + + if (dev != NULL) { + dev->name = name; + dev->is_uplink = is_uplink; + if (is_uplink) { + dhcp_num_north_intf++; + } else { + dhcp_num_south_intf++; + assert(dhcp_num_south_intf <= 1); + } + + LIST_INSERT_HEAD(&intfs, dev, entry); + + rv = 0; + } + else { + syslog(LOG_ALERT, "malloc: failed to allocate memory for intf '%s'\n", name); + } + + return rv; +} + +/** + * @code dhcp_devman_start_capture(snaplen, base); + * + * @brief start packet capture on the devman interface list + */ +int dhcp_devman_start_capture(int snaplen, struct event_base *base) +{ + int rv = -1; + struct intf *int_ptr; + + if ((dhcp_num_south_intf == 1) && (dhcp_num_north_intf >= 1)) { + LIST_FOREACH(int_ptr, &intfs, entry) { + rv = dhcp_device_init(&int_ptr->dev_context, int_ptr->name, snaplen, int_ptr->is_uplink, base); + if (rv == 0) { + syslog(LOG_INFO, + "Capturing DHCP packets on interface %s, ip: 0x%08x, mac [%02x:%02x:%02x:%02x:%02x:%02x] \n", + int_ptr->name, int_ptr->dev_context->ip, int_ptr->dev_context->mac[0], + int_ptr->dev_context->mac[1], int_ptr->dev_context->mac[2], int_ptr->dev_context->mac[3], + int_ptr->dev_context->mac[4], int_ptr->dev_context->mac[5]); + } + else { + break; + } + } + } + else { + syslog(LOG_ERR, "Invalid number of interfaces, downlink/south %d, uplink/north %d\n", + dhcp_num_south_intf, dhcp_num_north_intf); + } + + return rv; +} + +/** + * @code dhcp_devman_get_status(); + * + * @brief collects DHCP relay status info. + */ +dhcp_mon_status_t dhcp_devman_get_status() +{ + return dhcp_device_get_status(NULL); +} + +/** + * @code dhcp_devman_print_status(); + * + * @brief prints status counters to syslog + */ +void dhcp_devman_print_status() +{ + dhcp_device_print_status(NULL); +} diff --git a/src/dhcpmon/src/dhcp_devman.h b/src/dhcpmon/src/dhcp_devman.h new file mode 100644 index 000000000000..a0753b4b93a1 --- /dev/null +++ b/src/dhcpmon/src/dhcp_devman.h @@ -0,0 +1,76 @@ +/** + * @file dhcp_devman.h + * + * Device (interface) manager + */ + +#ifndef DHCP_DEVMAN_H_ +#define DHCP_DEVMAN_H_ + +#include + +#include "dhcp_device.h" + +/** + * @code dhcp_devman_init(); + * + * @brief initializes device (interface) manager that keeps track of interfaces and assert that there is one south + * interface and as many north interfaces + * + * @return none + */ +void dhcp_devman_init(); + +/** + * @code dhcp_devman_shutdown(); + * + * @brief shuts down device (interface) manager. Also, stops packet capture on interface and cleans up any allocated + * memory + * + * @return none + */ +void dhcp_devman_shutdown(); + +/** + * @code dhcp_devman_add_intf(name, uplink); + * + * @brief adds interface to the device manager. + * + * @param name interface name + * @param is_uplink true for uplink (north) interface + * + * @return 0 on success, nonzero otherwise + */ +int dhcp_devman_add_intf(const char *name, uint8_t is_uplink); + +/** + * @code dhcp_devman_start_capture(snaplen, timeout_ms); + * + * @brief start packet capture on the devman interface list + * + * @param snaplen packet capture snap length + * @param base libevent base + * + * @return 0 on success, nonzero otherwise + */ +int dhcp_devman_start_capture(int snaplen, struct event_base *base); + +/** + * @code dhcp_devman_get_status(); + * + * @brief collects DHCP relay status info. + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +dhcp_mon_status_t dhcp_devman_get_status(); + +/** + * @code dhcp_devman_print_status(); + * + * @brief prints status counters to syslog + * + * @return none + */ +void dhcp_devman_print_status(); + +#endif /* DHCP_DEVMAN_H_ */ diff --git a/src/dhcpmon/src/dhcp_mon.c b/src/dhcpmon/src/dhcp_mon.c new file mode 100644 index 000000000000..dc0a7d94f149 --- /dev/null +++ b/src/dhcpmon/src/dhcp_mon.c @@ -0,0 +1,199 @@ +/** + * @file dhcp_mon.c + * + * @brief dhcp relay monitor module + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_mon.h" +#include "dhcp_devman.h" + +/** window_interval_sec monitoring window for dhcp relay health checks */ +static int window_interval_sec = 12; +/** dhcp_unhealthy_max_count max count of consecutive unhealthy statuses before reporting to syslog */ +static int dhcp_unhealthy_max_count = 10; +/** libevent base struct */ +static struct event_base *base; +/** libevent timeout event struct */ +static struct event *ev_timeout = NULL; +/** libevent SIGINT signal event struct */ +static struct event *ev_sigint; +/** libevent SIGTERM signal event struct */ +static struct event *ev_sigterm; + +/** + * @code signal_callback(fd, event, arg); + * + * @brief signal handler for dhcpmon. It will initiate shutdown when signal is caught + * + * @param fd libevent socket + * @param event event triggered + * @param arg pointer user provided context (libevent base) + * + * @return none + */ +static void signal_callback(evutil_socket_t fd, short event, void *arg) +{ + syslog(LOG_ALERT, "Received signal %d\n", event); + dhcp_devman_print_status(); + dhcp_mon_stop(); +} + +/** + * @code timeout_callback(fd, event, arg); + * + * @brief periodic timer call back + * + * @param fd libevent socket + * @param event event triggered + * @param arg pointer user provided context (libevent base) + * + * @return none + */ +static void timeout_callback(evutil_socket_t fd, short event, void *arg) +{ + static int count = 0; + dhcp_mon_status_t dhcp_mon_status = dhcp_devman_get_status(); + + switch (dhcp_mon_status) + { + case DHCP_MON_STATUS_UNHEALTHY: + if (++count > dhcp_unhealthy_max_count) { + syslog(LOG_ALERT, "DHCP Relay is not healthy after %d health checks\n", count); + } + break; + case DHCP_MON_STATUS_HEALTHY: + if (count > 0) { + count = 0; + } + break; + case DHCP_MON_STATUS_INDETERMINATE: + break; + default: + syslog(LOG_ERR, "DHCP Relay returned unknown status %d\n", dhcp_mon_status); + break; + } +} + +/** + * @code dhcp_mon_init(window_sec, max_count); + * + * initializes event base and periodic timer event that continuously collects dhcp relay health status every window_sec + * seconds. It also writes to syslog when dhcp relay has been unhealthy for consecutive max_count checks. + * + */ +int dhcp_mon_init(int window_sec, int max_count) +{ + int rv = -1; + + do { + window_interval_sec = window_sec; + dhcp_unhealthy_max_count = max_count; + + base = event_base_new(); + if (base == NULL) { + syslog(LOG_ERR, "Could not initialize libevent!\n"); + break; + } + + ev_sigint = evsignal_new(base, SIGINT, signal_callback, base); + if (ev_sigint == NULL) { + syslog(LOG_ERR, "Could not create SIGINT libevent signal!\n"); + break; + } + + ev_sigterm = evsignal_new(base, SIGTERM, signal_callback, base); + if (ev_sigterm == NULL) { + syslog(LOG_ERR, "Could not create SIGTERM libevent signal!\n"); + break; + } + + ev_timeout = event_new(base, -1, EV_PERSIST, timeout_callback, base); + if (ev_timeout == NULL) { + syslog(LOG_ERR, "Could not create libevent timer!\n"); + break; + } + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_mon_shutdown(); + * + * @brief shuts down libevent loop + */ +void dhcp_mon_shutdown() +{ + event_del(ev_timeout); + event_del(ev_sigint); + event_del(ev_sigterm); + + event_free(ev_timeout); + event_free(ev_sigint); + event_free(ev_sigterm); + + event_base_free(base); +} + +/** + * @code dhcp_mon_start(snaplen); + * + * @brief start monitoring DHCP Relay + */ +int dhcp_mon_start(int snaplen) +{ + int rv = -1; + + do + { + if (dhcp_devman_start_capture(snaplen, base) != 0) { + break; + } + + if (evsignal_add(ev_sigint, NULL) != 0) { + syslog(LOG_ERR, "Could not add SIGINT libevent signal!\n"); + break; + } + + if (evsignal_add(ev_sigterm, NULL) != 0) { + syslog(LOG_ERR, "Could not add SIGTERM libevent signal!\n"); + break; + } + + struct timeval event_time = {.tv_sec = window_interval_sec, .tv_usec = 0}; + if (evtimer_add(ev_timeout, &event_time) != 0) { + syslog(LOG_ERR, "Could not add event timer to libevent!\n"); + break; + } + + if (event_base_dispatch(base) != 0) { + syslog(LOG_ERR, "Could not start libevent dispatching loop!\n"); + break; + } + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_mon_stop(); + * + * @brief stop monitoring DHCP Relay + */ +void dhcp_mon_stop() +{ + event_base_loopexit(base, NULL); +} diff --git a/src/dhcpmon/src/dhcp_mon.h b/src/dhcpmon/src/dhcp_mon.h new file mode 100644 index 000000000000..44d361b32ec0 --- /dev/null +++ b/src/dhcpmon/src/dhcp_mon.h @@ -0,0 +1,54 @@ +/** + * @file dhcp_mon.h + * + * @brief dhcp relay monitor module + * + */ + +#ifndef DHCP_MON_H_ +#define DHCP_MON_H_ + +/** + * @code dhcp_mon_init(window_ssec, max_count); + * + * @brief initializes event base and periodic timer event that continuously collects dhcp relay health status every + * window_sec seconds. It also writes to syslog when dhcp relay has been unhealthy for consecutive max_count + * checks. + * + * @param window_sec time interval between health checks + * @param max_count max count of consecutive unhealthy statuses before reporting to syslog + * + * @return 0 upon success, otherwise upon failure + */ +int dhcp_mon_init(int window_sec, int max_count); + +/** + * @code dhcp_mon_shutdown(); + * + * @brief shuts down libevent loop + * + * @return none + */ +void dhcp_mon_shutdown(); + +/** + * @code dhcp_mon_start(snaplen); + * + * @brief start monitoring DHCP Relay + * + * @param snaplen packet capture length + * + * @return 0 upon success, otherwise upon failure + */ +int dhcp_mon_start(int snaplen); + +/** + * @code dhcp_mon_stop(); + * + * @brief stop monitoring DHCP Relay + * + * @return none + */ +void dhcp_mon_stop(); + +#endif /* DHCP_MON_H_ */ diff --git a/src/dhcpmon/src/main.c b/src/dhcpmon/src/main.c new file mode 100644 index 000000000000..11eab6ee9ea1 --- /dev/null +++ b/src/dhcpmon/src/main.c @@ -0,0 +1,174 @@ +/** + * @file main.c + * + * @brief: Main entry point for dhcpmon utility. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_mon.h" +#include "dhcp_devman.h" + +/** dhcpmon_default_snaplen: default snap length of packet being captured */ +static const uint32_t dhcpmon_default_snaplen = 65535; +/** dhcpmon_default_health_check_window: default value for a time window, during which DHCP DORA packet counts are being + * collected */ +static const uint32_t dhcpmon_default_health_check_window = 12; +/** dhcpmon_default_unhealthy_max_count: default max consecutive unhealthy status reported before reporting an issue + * with DHCP relay */ +static const uint32_t dhcpmon_default_unhealthy_max_count = 10; + +/** + * @code usage(prog); + * + * @brief prints help message about how to use dhcpmon utility + * + * @param prog program name + * + * @return none + */ +static void usage(const char *prog) +{ + printf("Usage: %s -id {-iu }+ [-w ]" + "[-c ] [-s ] [-d]\n", prog); + printf("where\n"); + printf("\tsouth interface: is a vlan interface,\n"); + printf("\tnorth interface: is a TOR-T1 interface,\n"); + printf("\tsnapshot window: during which DHCP counters are gathered and DHCP status is validated (default %d),\n", + dhcpmon_default_health_check_window); + printf("\tunhealthy status count: count of consecutive unhealthy status before writing an alert to syslog " + "(default %d),\n", + dhcpmon_default_unhealthy_max_count); + printf("\tsnap length: snap length of packet capture (default %d),\n", dhcpmon_default_snaplen); + printf("\t-d: daemonize %s.\n", prog); + + exit(EXIT_SUCCESS); +} + +/** + * @code dhcpmon_daemonize(); + * + * @brief make this utility run as a daemon. + * + * @return none + */ +static void dhcpmon_daemonize() +{ + pid_t pid, sid; + pid = fork(); + if (pid < 0) { + syslog(LOG_ALERT, "fork: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + if (pid > 0) { + exit(EXIT_SUCCESS); + } + + // this is the daemon running now + umask(0); + // Create a new SID for the child process + sid = setsid(); + if (sid < 0) { + syslog(LOG_ALERT, "setsid: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + // Change the current working directory + if ((chdir("/")) < 0) { + syslog(LOG_ALERT, "chdir: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); +} + +/** + * @code main(argc, argv); + * + * @brief main entry point of dhcpmon utility + * + * @return int 0 on success, otherwise on failure + */ +int main(int argc, char **argv) +{ + int rv = EXIT_FAILURE; + int i; + int window_interval = dhcpmon_default_health_check_window; + int max_unhealthy_count = dhcpmon_default_unhealthy_max_count; + uint32_t snaplen = dhcpmon_default_snaplen; + int make_daemon = 0; + + setlogmask(LOG_UPTO(LOG_INFO)); + openlog(basename(argv[0]), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_DAEMON); + + dhcp_devman_init(); + + for (i = 1; i < argc;) { + if ((argv[i] == NULL) || (argv[i][0] != '-')) { + break; + } + switch (argv[i][1]) + { + case 'h': + usage(basename(argv[0])); + break; + case 'i': + if (dhcp_devman_add_intf(argv[i + 1], argv[i][2] == 'u') != 0) { + usage(basename(argv[0])); + } + i += 2; + break; + case 'd': + make_daemon = 1; + i++; + break; + case 's': + snaplen = atoi(argv[i + 1]); + i += 2; + break; + case 'w': + window_interval = atoi(argv[i + 1]); + i += 2; + break; + case 'c': + max_unhealthy_count = atoi(argv[i + 1]); + i += 2; + break; + default: + fprintf(stderr, "%s: %c: Unknown option\n", basename(argv[0]), argv[i][1]); + usage(basename(argv[0])); + } + } + + if (make_daemon) { + dhcpmon_daemonize(); + } + + if ((dhcp_mon_init(window_interval, max_unhealthy_count) == 0) && + (dhcp_mon_start(snaplen) == 0)) { + + rv = EXIT_SUCCESS; + + dhcp_mon_shutdown(); + } + + dhcp_devman_shutdown(); + + closelog(); + + return rv; +} diff --git a/src/dhcpmon/src/subdir.mk b/src/dhcpmon/src/subdir.mk new file mode 100644 index 000000000000..324977aa39f7 --- /dev/null +++ b/src/dhcpmon/src/subdir.mk @@ -0,0 +1,29 @@ +# Add inputs and outputs from these tool invocations to the build variables +CC := gcc + +C_SRCS += \ +../src/dhcp_device.c \ +../src/dhcp_devman.c \ +../src/dhcp_mon.c \ +../src/main.c + +OBJS += \ +./src/dhcp_device.o \ +./src/dhcp_devman.o \ +./src/dhcp_mon.o \ +./src/main.o + +C_DEPS += \ +./src/dhcp_device.d \ +./src/dhcp_devman.d \ +./src/dhcp_mon.d \ +./src/main.d + + +# Each subdirectory must supply rules for building sources it contributes +src/%.o: ../src/%.c + @echo 'Building file: $<' + @echo 'Invoking: GCC C Compiler' + $(CC) -O3 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index bae273eeaf81..a29982a646f4 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -37,3 +37,16 @@ stdout_logfile=syslog stderr_logfile=syslog +[group:dhcpmon] +programs=dhcpmon-Vlan1000 + +[program:dhcpmon-Vlan1000] +command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + + + From 68499e681f533be96e5e0bc21c4a4acaccd0861d Mon Sep 17 00:00:00 2001 From: Iris Hsu Date: Thu, 9 Jan 2020 00:01:06 +0800 Subject: [PATCH 0275/1427] [sonic-mgmt]: Install python-subnettree to sonic-mgmt container. (#3978) * Install python-subnettree to sonic-mgmt container. --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 4c53baf7c485..4a7e1a977549 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -143,4 +143,6 @@ RUN azure-cli_bundle_*/installer # TODO: if azure-cli contains newer version azure-keyvault, remove this RUN ~/lib/azure-cli/bin/python -m pip install azure-keyvault==0.3.7 -U +RUN pip install pysubnettree + RUN git clone https://github.com/Azure/sonic-mgmt From c4755192b1ecdd256f842a86cb999b82a1e9e2e6 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 8 Jan 2020 14:37:06 -0800 Subject: [PATCH 0276/1427] Fix bug: chroot command line (#3972) --- files/build_templates/sonic_debian_extension.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index e5dd9d9e0912..7e24df158f59 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -170,7 +170,7 @@ sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf # Install a custom version of kdump-tools (and its dependencies via 'apt-get -y install -f') sudo DEBIAN_FRONTEND=noninteractive dpkg --root=$FILESYSTEM_ROOT -i $debs_path/kdump-tools_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=truechroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install + sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true chroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install # Install custom-built monit package and SONiC configuration files sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/monit_*.deb || \ From 483a5946a85793a7fba0aa329e6fec21e9091c87 Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 10 Jan 2020 08:27:34 -0800 Subject: [PATCH 0277/1427] Revert "[MultiDB]except src and dockers : replace redis-cli with sonic-db-cli and use new DBConnector (#3928)" (#4002) This reverts commit 0dae59ac301f18e7dad948282addf961b69d82fc. --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 9 +++-- files/build_templates/docker_image_ctl.j2 | 34 +++++++++---------- files/image_config/config-setup/config-setup | 11 +++--- files/image_config/updategraph/updategraph | 10 +++--- .../warmboot-finalizer/finalize-warmboot.sh | 10 +++--- files/scripts/configdb-load.sh | 2 +- files/scripts/swss.sh | 26 +++++++------- files/scripts/syncd.sh | 12 ++++--- .../s9180-32x/utils/qsfp_monitor.sh | 2 +- .../s9280-64x/utils/qsfp_monitor.sh | 2 +- .../s8810-32q/utils/qsfp_monitor.sh | 2 +- .../s8900-54xc/utils/qsfp_monitor.sh | 2 +- .../s8900-64xc/utils/qsfp_monitor.sh | 2 +- .../s9100/utils/qsfp_monitor.sh | 2 +- .../s9200-64x/utils/qsfp_monitor.sh | 2 +- .../s9130-32x/utils/qsfp_monitor.sh | 2 +- .../s9230-64x/utils/qsfp_monitor.sh | 2 +- 17 files changed, 72 insertions(+), 60 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 7c4f33f74973..e41ac2924da2 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -22,6 +22,8 @@ SFP_I2C_PAGE_SIZE = 256 # parameters for DB connection +REDIS_HOSTNAME = "localhost" +REDIS_PORT = 6379 REDIS_TIMEOUT_USECS = 0 # parameters for SFP presence @@ -188,9 +190,10 @@ def get_transceiver_change_event(self, timeout=0): if self.db_sel == None: from swsscommon import swsscommon - self.state_db = swsscommon.DBConnector("STATE_DB", - REDIS_TIMEOUT_USECS, - True)) + self.state_db = swsscommon.DBConnector(swsscommon.STATE_DB, + REDIS_HOSTNAME, + REDIS_PORT, + REDIS_TIMEOUT_USECS) # Subscribe to state table for SFP change notifications self.db_sel = swsscommon.Select() diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index df236f6523e8..167a392730e4 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -63,20 +63,20 @@ function preStartAction() docker cp /tmp/dump.rdb database:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) - vrfenabled=`sonic-db-cli CONFIG_DB hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` - v1SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` - v1SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` - v1Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` - v1Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` - v2SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` - v2SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` - v2Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` - v2Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` - v3SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` - v3SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` - v3Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` - v3Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` + docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + vrfenabled=`/usr/bin/redis-cli -n 4 hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` + v1SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` + v1SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` + v1Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` + v1Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` + v2SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` + v2SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` + v2Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` + v2Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` + v3SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` + v3SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` + v3Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` + v3Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` if [ "${v1SnmpTrapIp}" != "" ] then @@ -113,7 +113,7 @@ function preStartAction() fi echo -n "" > /tmp/snmpagentaddr.yml - keys=`sonic-db-cli CONFIG_DB keys "SNMP_AGENT_ADDRESS_CONFIG|*"` + keys=`/usr/bin/redis-cli -n 4 keys "SNMP_AGENT_ADDRESS_CONFIG|*"` count=1 for key in $keys;do ip=`echo $key|cut -d "|" -f2` @@ -151,10 +151,10 @@ function postStartAction() if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" + redis-cli -n 6 SET "FAST_REBOOT|system" "1" "EX" "180" fi - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index f19abd266e95..bd497d06b257 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -25,6 +25,7 @@ ########################################################################### # Initialize constants +CONFIG_DB_INDEX=4 UPDATEGRAPH_CONF=/etc/sonic/updategraph.conf CONFIG_DB_JSON=/etc/sonic/config_db.json MINGRAPH_FILE=/etc/sonic/minigraph.xml @@ -106,9 +107,9 @@ reload_minigraph() if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - sonic-db-cli CONFIG_DB FLUSHDB + redis-cli -n $CONFIG_DB_INDEX FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -137,7 +138,7 @@ function copy_config_files_and_directories() # Check if SONiC swich has booted after a warm reboot request check_system_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -186,7 +187,7 @@ load_config() return 1 fi - sonic-db-cli CONFIG_DB FLUSHDB + redis-cli -n $CONFIG_DB_INDEX FLUSHDB sonic-cfggen -j ${CONFIG_FILE} --write-to-db if [ $? -ne 0 ]; then return $? @@ -197,7 +198,7 @@ load_config() /usr/bin/db_migrator.py -o migrate fi - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" return 0 } diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index a24d452b1ad2..b2bd027e82e7 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -1,14 +1,16 @@ #!/bin/bash +CONFIG_DB_INDEX=4 + reload_minigraph() { echo "Reloading minigraph..." if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - sonic-db-cli CONFIG_DB FLUSHDB + redis-cli -n $CONFIG_DB_INDEX FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -75,9 +77,9 @@ if [ "$src" = "dhcp" ]; then else cp -f /tmp/device_meta.json /etc/sonic/config_db.json fi - sonic-db-cli CONFIG_DB FLUSHDB + redis-cli -n $CONFIG_DB_INDEX FLUSHDB sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" if [ "$dhcp_as_static" = "true" ]; then sed -i "/enabled=/d" /etc/sonic/updategraph.conf echo "enabled=false" >> /etc/sonic/updategraph.conf diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index eec50ccef692..32c9c8444cc3 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -20,7 +20,7 @@ function debug() function check_warm_boot() { - WARM_BOOT=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + WARM_BOOT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` } @@ -29,10 +29,12 @@ function wait_for_database_service() debug "Wait for database to become ready..." # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; + do sleep 1; + done # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done @@ -42,7 +44,7 @@ function wait_for_database_service() function get_component_state() { - sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|$1" state + /usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|$1" state } diff --git a/files/scripts/configdb-load.sh b/files/scripts/configdb-load.sh index e7080eb40f3d..5ba2e0e0bc7f 100755 --- a/files/scripts/configdb-load.sh +++ b/files/scripts/configdb-load.sh @@ -10,4 +10,4 @@ if [ -r /etc/sonic/config_db.json ]; then sonic-cfggen -j /etc/sonic/config_db.json --write-to-db fi -sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" +redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index a14d03e40f50..93f311019d66 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -31,8 +31,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -43,7 +43,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -54,10 +54,12 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; + do sleep 1; + done # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -67,7 +69,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - sonic-db-cli $1 EVAL " + redis-cli -n $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -112,11 +114,11 @@ start() { # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - sonic-db-cli APPL_DB FLUSHDB - sonic-db-cli ASIC_DB FLUSHDB - sonic-db-cli COUNTERS_DB FLUSHDB - sonic-db-cli FLEX_COUNTER_DB FLUSHDB - clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" + /usr/bin/docker exec database redis-cli -n 0 FLUSHDB + /usr/bin/docker exec database redis-cli -n 1 FLUSHDB + /usr/bin/docker exec database redis-cli -n 2 FLUSHDB + /usr/bin/docker exec database redis-cli -n 5 FLUSHDB + clean_up_tables 6 "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker @@ -164,7 +166,7 @@ stop() { # encountered error, e.g. syncd crashed. And swss needs to # be restarted. debug "Clearing FAST_REBOOT flag..." - clean_up_tables STATE_DB "'FAST_REBOOT*'" + clean_up_tables 6 "'FAST_REBOOT*'" # Unlock has to happen before reaching out to peer service unlock_service_state_change diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 4b47e7ad4c45..05e5552a64b1 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -30,8 +30,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -43,10 +43,12 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; + do sleep 1; + done # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -63,7 +65,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $(redis-cli -n 6 GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh index 7776493bc20a..249f179216a6 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh index 9213d115f656..23a3fd066bee 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh index 7776493bc20a..249f179216a6 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh index 0a4ba20ab767..7f50d137bcb7 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh index b3192f2efb7a..36f9e53ef108 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh index 7776493bc20a..249f179216a6 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh index 47cfbb3ea008..51c49c1152f5 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh index 7776493bc20a..249f179216a6 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh index 9213d115f656..23a3fd066bee 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi From 856b4b64eb62b7a1cc9ddcaf7418a9a3128f130f Mon Sep 17 00:00:00 2001 From: Sujin Kang Date: Fri, 10 Jan 2020 09:47:13 -0800 Subject: [PATCH 0278/1427] [reboot cause]: Delay process-reboot-cause service until network connection is stable (#4003) --- files/build_templates/process-reboot-cause.timer | 9 +++++++++ files/build_templates/sonic_debian_extension.j2 | 5 +++++ .../process-reboot-cause/process-reboot-cause.service | 3 --- 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 files/build_templates/process-reboot-cause.timer diff --git a/files/build_templates/process-reboot-cause.timer b/files/build_templates/process-reboot-cause.timer new file mode 100644 index 000000000000..222c51a79a03 --- /dev/null +++ b/files/build_templates/process-reboot-cause.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays process-reboot-cause until network is stably connected + +[Timer] +OnBootSec=1min 30 sec +Unit=process-reboot-cause.service + +[Install] +WantedBy=timers.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 7e24df158f59..bdcb415839d4 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -295,6 +295,11 @@ sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd.service $FILESYSTEM_RO echo "procdockerstatsd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd $FILESYSTEM_ROOT/usr/bin/ +# Copy systemd timer configuration +# It implements delayed start of services +sudo cp $BUILD_TEMPLATES/process-reboot-cause.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable process-reboot-cause.timer + # Copy process-reboot-cause service files sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause.service $FILESYSTEM_ROOT/etc/systemd/system/ echo "process-reboot-cause.service" | sudo tee -a $GENERATED_SERVICE_FILE diff --git a/files/image_config/process-reboot-cause/process-reboot-cause.service b/files/image_config/process-reboot-cause/process-reboot-cause.service index a429339dbe58..b9821f60c420 100644 --- a/files/image_config/process-reboot-cause/process-reboot-cause.service +++ b/files/image_config/process-reboot-cause/process-reboot-cause.service @@ -5,6 +5,3 @@ After=rc-local.service [Service] Type=simple ExecStart=/usr/bin/process-reboot-cause - -[Install] -WantedBy=multi-user.target From bac6615bf5a946d68a28c2c6610fb02167eb97fe Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Sat, 11 Jan 2020 03:50:51 +0700 Subject: [PATCH 0279/1427] [device/celestica]: Fix xcvrd error (#3979) * [device/celestica]: add pmon_daemon_control config * [device/celestica]: update sfp index follow port_config * [device/celestica]: update get_watchdog to avoid multiple daemon try opening watchdog --- .../pmon_daemon_control.json | 3 +++ .../sonic_platform/chassis.py | 19 ++++++++++++++++--- .../x86_64-cel_e1031-r0/sonic_platform/sfp.py | 2 +- .../pmon_daemon_control.json | 3 +++ .../pmon_daemon_control.json | 3 +++ .../sonic_platform/chassis.py | 19 ++++++++++++++++--- .../sonic_platform/sfp.py | 2 +- .../pmon_daemon_control.json | 3 +++ 8 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json create mode 100644 device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json create mode 100644 device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json create mode 100644 device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json diff --git a/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py index 99eb49ce53e0..719170d831b7 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py @@ -19,7 +19,6 @@ from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.component import Component - from sonic_platform.watchdog import Watchdog from sonic_platform.thermal import Thermal from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Tlv @@ -54,7 +53,9 @@ def __init__(self): for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) - for index in range(0, NUM_SFP): + # sfp index start from 1 + self._sfp_list.append(None) + for index in range(1, NUM_SFP+1): sfp = Sfp(index) self._sfp_list.append(sfp) for index in range(0, NUM_COMPONENT): @@ -63,7 +64,6 @@ def __init__(self): self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self.__is_host( ) else PMON_REBOOT_CAUSE_PATH - self._watchdog = Watchdog() self._eeprom = Tlv() def __is_host(self): @@ -134,3 +134,16 @@ def get_reboot_cause(self): description = 'Unknown reason' return (reboot_cause, description) + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py index 4cfdcf50b66d..6ef8838ba8af 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py @@ -94,7 +94,7 @@ class Sfp(SfpBase): def __init__(self, sfp_index): # Init index self.index = sfp_index - self.port_num = self.index + 1 + self.port_num = self.index # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' diff --git a/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index c9447b56a2fe..7db46e55bd8c 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -19,7 +19,6 @@ from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.component import Component - from sonic_platform.watchdog import Watchdog from sonic_platform.thermal import Thermal from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Tlv @@ -56,14 +55,15 @@ def __init__(self): for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) - for index in range(0, NUM_SFP): + # sfp index start from 1 + self._sfp_list.append(None) + for index in range(1, NUM_SFP+1): sfp = Sfp(index) self._sfp_list.append(sfp) for index in range(0, NUM_COMPONENT): component = Component(index) self._component_list.append(component) - self._watchdog = Watchdog() self._eeprom = Tlv() def __is_host(self): @@ -146,3 +146,16 @@ def get_reboot_cause(self): description = 'Unknown reason' return (reboot_cause, description) + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py index 3a02be39df6e..04fb36b72b8f 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py @@ -100,7 +100,7 @@ class Sfp(SfpBase): def __init__(self, sfp_index): # Init index self.index = sfp_index - self.port_num = self.index + 1 if self.PORT_START == 1 else index + self.port_num = self.index # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' diff --git a/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} From e45ff4edb4944bfd8521239936a87e5816d65467 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:55:29 +0200 Subject: [PATCH 0280/1427] [build] make debian package install noninteractive (#3980) Otherwise, build process gets stuck because isc-dhcp-relay gives promt: ``` $ make SONIC_PROFILING_ON=y INSTALL_DEBUG_TOOLS=y SONIC_BUILD_JOBS=12 target/debs/stretch/isc-dhcp-relay_4.3.5-2_amd64.deb-install +++ --- Making target/debs/stretch/isc-dhcp-relay_4.3.5-2_amd64.deb-install --- +++ EXTRA_JESSIE_TARGETS=isc-dhcp-relay_4.3.5-2_amd64.deb-install make -f Makefile.work jessie make[1]: Entering directory `/build2/stepanb/hitless/sonic-buildimage' SONiC Build System Build Configuration "CONFIGURED_PLATFORM" : "mellanox" "CONFIGURED_ARCH" : "amd64" "SONIC_CONFIG_PRINT_DEPENDENCIES" : "" "SONIC_BUILD_JOBS" : "12" "SONIC_CONFIG_MAKE_JOBS" : "12" "SONIC_USE_DOCKER_BUILDKIT" : "" "USERNAME" : "admin" "PASSWORD" : "YourPaSsWoRd" "ENABLE_DHCP_GRAPH_SERVICE" : "" "SHUTDOWN_BGP_ON_START" : "" "ENABLE_PFCWD_ON_START" : "" "INSTALL_DEBUG_TOOLS" : "" "ROUTING_STACK" : "frr" "FRR_USER_UID" : "300" "FRR_USER_GID" : "300" "ENABLE_SYNCD_RPC" : "" "ENABLE_ORGANIZATION_EXTENSIONS" : "y" "HTTP_PROXY" : "" "HTTPS_PROXY" : "" "ENABLE_SYSTEM_TELEMETRY" : "y" "ENABLE_ZTP" : "" "SONIC_DEBUGGING_ON" : "" "SONIC_PROFILING_ON" : "" "KERNEL_PROCURE_METHOD" : "build" "BUILD_TIMESTAMP" : "20200106.124851" "BLDENV" : "" "VS_PREPARE_MEM" : "yes" "ENABLE_SFLOW" : "y" make: Nothing to be done for 'jessie'. make[1]: Leaving directory `/build2/stepanb/hitless/sonic-buildimage' BLDENV=stretch make -f Makefile.work target/debs/stretch/isc-dhcp-relay_4.3.5-2_amd64.deb-install make[1]: Entering directory `/build2/stepanb/hitless/sonic-buildimage' SONiC Build System Build Configuration "CONFIGURED_PLATFORM" : "mellanox" "CONFIGURED_ARCH" : "amd64" "SONIC_CONFIG_PRINT_DEPENDENCIES" : "" "SONIC_BUILD_JOBS" : "12" "SONIC_CONFIG_MAKE_JOBS" : "12" "SONIC_USE_DOCKER_BUILDKIT" : "" "USERNAME" : "admin" "PASSWORD" : "YourPaSsWoRd" "ENABLE_DHCP_GRAPH_SERVICE" : "" "SHUTDOWN_BGP_ON_START" : "" "ENABLE_PFCWD_ON_START" : "" "INSTALL_DEBUG_TOOLS" : "" "ROUTING_STACK" : "frr" "FRR_USER_UID" : "300" "FRR_USER_GID" : "300" "ENABLE_SYNCD_RPC" : "" "ENABLE_ORGANIZATION_EXTENSIONS" : "y" "HTTP_PROXY" : "" "HTTPS_PROXY" : "" "ENABLE_SYSTEM_TELEMETRY" : "y" "ENABLE_ZTP" : "" "SONIC_DEBUGGING_ON" : "" "SONIC_PROFILING_ON" : "" "KERNEL_PROCURE_METHOD" : "build" "BUILD_TIMESTAMP" : "20200106.124855" "BLDENV" : "stretch" "VS_PREPARE_MEM" : "yes" "ENABLE_SFLOW" : "y" [ 01 ] [ target/debs/stretch/isc-dhcp-relay_4.3.5-2_amd64.deb-install ] Servers the DHCP relay should forward requests to: Interfaces the DHCP relay should listen on: ``` Signed-off-by: Stepan Blyschak --- slave.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slave.mk b/slave.mk index 9a34e5379b14..8f8c4dd87890 100644 --- a/slave.mk +++ b/slave.mk @@ -399,7 +399,7 @@ $(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -inst # put a lock here because dpkg does not allow installing packages in parallel while true; do if mkdir $(DEBS_PATH)/dpkg_lock &> /dev/null; then - { sudo dpkg -i $(DEBS_PATH)/$* $(LOG) && rm -d $(DEBS_PATH)/dpkg_lock && break; } || { rm -d $(DEBS_PATH)/dpkg_lock && exit 1 ; } + { sudo DEBIAN_FRONTEND=noninteractive dpkg -i $(DEBS_PATH)/$* $(LOG) && rm -d $(DEBS_PATH)/dpkg_lock && break; } || { rm -d $(DEBS_PATH)/dpkg_lock && exit 1 ; } fi done $(FOOTER) From f3b5b13a7551f974128c62d2b3f51d20cc199525 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Fri, 10 Jan 2020 12:56:42 -0800 Subject: [PATCH 0281/1427] [barefoot]: Update SDK package (#3950) Updated SDK package with X1/X2 profiles Signed-off-by: Andriy Kokhan --- platform/barefoot/bfn-platform.mk | 4 ++-- platform/barefoot/bfn-sai.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 854026b52949..96c204d25ea0 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ -BFN_PLATFORM = bfnplatform_20191115_deb9.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnplatform_20191115_deb9.deb" +BFN_PLATFORM = bfnplatform_20191227_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnplatform_20191227_deb9.deb" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 6f413d50c11e..25c851de313c 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,5 @@ -BFN_SAI = bfnsdk_20191115_deb9.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnsdk_20191115_deb9.deb" +BFN_SAI = bfnsdk_20191227_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnsdk_20191227_deb9.deb" SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) From aa67921d066b0b56022c2f08b37bf3ff8f8b8d82 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 10 Jan 2020 13:01:24 -0800 Subject: [PATCH 0282/1427] [Monit] Change the monitoring period from 120 seconds to 60 seconds. (#3974) * [Monit] Change the monitoring period of monit from 120 seconds to 60 seconds and also at the same time double the interval for existing sonic monit config file in host. Signed-off-by: Yong Zhao --- files/image_config/monit/conf.d/sonic-host | 12 ++++++------ files/image_config/monit/monitrc | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/files/image_config/monit/conf.d/sonic-host b/files/image_config/monit/conf.d/sonic-host index 8eaa1671d821..5a67f7a9909b 100644 --- a/files/image_config/monit/conf.d/sonic-host +++ b/files/image_config/monit/conf.d/sonic-host @@ -6,17 +6,17 @@ ############################################################################### check filesystem root-overlay with path / - if space usage > 90% for 5 times within 10 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert check filesystem var-log with path /var/log - if space usage > 90% for 5 times within 10 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert check system $HOST - if memory usage > 90% for 5 times within 10 cycles then alert - if cpu usage (user) > 90% for 5 times within 10 cycles then alert - if cpu usage (system) > 90% for 5 times within 10 cycles then alert + if memory usage > 90% for 10 times within 20 cycles then alert + if cpu usage (user) > 90% for 10 times within 20 cycles then alert + if cpu usage (system) > 90% for 10 times within 20 cycles then alert check process rsyslog with pidfile /var/run/rsyslogd.pid start program = "/bin/systemctl start rsyslog.service" stop program = "/bin/systemctl stop rsyslog.service" - if totalmem > 800 MB for 5 times within 10 cycles then restart + if totalmem > 800 MB for 10 times within 20 cycles then restart diff --git a/files/image_config/monit/monitrc b/files/image_config/monit/monitrc index 7864069e3af1..3c3714882dcc 100644 --- a/files/image_config/monit/monitrc +++ b/files/image_config/monit/monitrc @@ -16,7 +16,7 @@ ## ## Start Monit in the background (run as a daemon): # - set daemon 120 # check services at 2-minute intervals + set daemon 60 # check services at 1-minute intervals # with start delay 240 # optional: delay the first check by 4-minutes (by # # default Monit check immediately after Monit start) # From 6dcc08e36cc517a7d8b9bc14dd5721c52abc0548 Mon Sep 17 00:00:00 2001 From: Kalimuthu-Velappan <53821802+Kalimuthu-Velappan@users.noreply.github.com> Date: Sat, 11 Jan 2020 02:56:04 +0530 Subject: [PATCH 0283/1427] [psud]: Fix for psud crash because of database connection reset (#3647) When database service is down, psud daemon throws an error because of DB connection reset, this because pmon service has no dependency with database service. To resolve this issue, added database service dependency to the pmon service. Also, increased the net.core.somaxconn value to 512 to solve the connection failure on the scaled setup. --- build_debian.sh | 3 +++ files/build_templates/pmon.service.j2 | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 39b984edec4e..3ccdd3e9820a 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -392,6 +392,9 @@ set /files/etc/sysctl.conf/net.ipv4.udp_l3mdev_accept 1 set /files/etc/sysctl.conf/net.core.rmem_max 2097152 set /files/etc/sysctl.conf/net.core.wmem_max 2097152 + +set /files/etc/sysctl.conf/net.core.somaxconn 512 + " -r $FILESYSTEM_ROOT if [[ $CONFIGURED_ARCH == amd64 ]]; then diff --git a/files/build_templates/pmon.service.j2 b/files/build_templates/pmon.service.j2 index 11dea5d12783..9195b4d38ad6 100644 --- a/files/build_templates/pmon.service.j2 +++ b/files/build_templates/pmon.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=Platform monitor container -Requires=updategraph.service -After=updategraph.service +Requires=database.service updategraph.service +After=database.service updategraph.service {% if sonic_asic_platform == 'mellanox' %} After=syncd.service {% endif %} From 3b1ee5dc2b8e5ac9411292d65e190ea7562ca4ec Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Fri, 10 Jan 2020 13:46:32 -0800 Subject: [PATCH 0284/1427] Changes to build restapi docker (#3993) --- .gitmodules | 4 +++ dockers/docker-sonic-restapi/Dockerfile.j2 | 25 +++++++++++++++++++ dockers/docker-sonic-restapi/start.sh | 10 ++++++++ dockers/docker-sonic-restapi/supervisord.conf | 12 +++++++++ rules/docker-restapi.mk | 20 +++++++++++++++ rules/restapi.mk | 9 +++++++ src/sonic-restapi | 1 + 7 files changed, 81 insertions(+) create mode 100644 dockers/docker-sonic-restapi/Dockerfile.j2 create mode 100755 dockers/docker-sonic-restapi/start.sh create mode 100644 dockers/docker-sonic-restapi/supervisord.conf create mode 100644 rules/docker-restapi.mk create mode 100644 rules/restapi.mk create mode 160000 src/sonic-restapi diff --git a/.gitmodules b/.gitmodules index 0cccf14a8e94..4fd4bd52be6c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -78,3 +78,7 @@ [submodule "src/sonic-ztp"] path = src/sonic-ztp url = https://github.com/Azure/sonic-ztp +[submodule "src/sonic-restapi"] + path = src/sonic-restapi + url = https://github.com/Azure/sonic-restapi.git + branch = master diff --git a/dockers/docker-sonic-restapi/Dockerfile.j2 b/dockers/docker-sonic-restapi/Dockerfile.j2 new file mode 100644 index 000000000000..de8080880fc7 --- /dev/null +++ b/dockers/docker-sonic-restapi/Dockerfile.j2 @@ -0,0 +1,25 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-config-engine-stretch + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +{% if docker_sonic_restapi_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_sonic_restapi_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages( docker_sonic_restapi_debs.split(' ')) }} +{%- endif %} + +## Clean up +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y + +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sonic-restapi/start.sh b/dockers/docker-sonic-restapi/start.sh new file mode 100755 index 000000000000..015d246d1200 --- /dev/null +++ b/dockers/docker-sonic-restapi/start.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +rm -f /var/run/rsyslogd.pid + +supervisorctl start rsyslogd + +supervisorctl start restapi diff --git a/dockers/docker-sonic-restapi/supervisord.conf b/dockers/docker-sonic-restapi/supervisord.conf new file mode 100644 index 000000000000..284c8aef423b --- /dev/null +++ b/dockers/docker-sonic-restapi/supervisord.conf @@ -0,0 +1,12 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:restapi] +command=/usr/sbin/go-server-server -loglevel trace +priority=1 +autostart=true +autorestart=false +stdout_logfile=/tmp/rest-api.out.log +stderr_logfile=/tmp/rest-api.err.log diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk new file mode 100644 index 000000000000..66d60205915a --- /dev/null +++ b/rules/docker-restapi.mk @@ -0,0 +1,20 @@ +# docker image for rest-api + +DOCKER_RESTAPI_STEM = docker-sonic-restapi +DOCKER_RESTAPI = $(DOCKER_RESTAPI_STEM).gz + +$(DOCKER_RESTAPI)_DEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ + $(LIBNL_ROUTE3) $(LIBSWSSCOMMON) $(RESTAPI) + +$(DOCKER_RESTAPI)_PATH = $(DOCKERS_PATH)/$(DOCKER_RESTAPI_STEM) + +$(DOCKER_RESTAPI)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) + +SONIC_DOCKER_IMAGES += $(DOCKER_RESTAPI) +SONIC_STRETCH_DOCKERS += $(DOCKER_RESTAPI) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_RESTAPI) + +$(DOCKER_RESTAPI)_CONTAINER_NAME = rest-api +$(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t +$(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock +$(DOCKER_RESTAPI)_RUN_OPT += -p=8090:8090/tcp diff --git a/rules/restapi.mk b/rules/restapi.mk new file mode 100644 index 000000000000..e66b4a1d976a --- /dev/null +++ b/rules/restapi.mk @@ -0,0 +1,9 @@ +# sonic-rest-api package + +RESTAPI = sonic-rest-api_1.0.1_amd64.deb +$(RESTAPI)_SRC_PATH = $(SRC_PATH)/sonic-restapi +$(RESTAPI)_DEPENDS += $(LIBHIREDIS_DEV) $(LIBNL3_DEV) $(LIBNL_GENL3_DEV) \ + $(LIBNL_ROUTE3_DEV) $(LIBSWSSCOMMON_DEV) $(LIBSWSSCOMMON) +$(RESTAPI)_RDEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ + $(LIBNL_ROUTE3) $(LIBSWSSCOMMON) +SONIC_DPKG_DEBS += $(RESTAPI) diff --git a/src/sonic-restapi b/src/sonic-restapi new file mode 160000 index 000000000000..163ee272ae99 --- /dev/null +++ b/src/sonic-restapi @@ -0,0 +1 @@ +Subproject commit 163ee272ae992f5885990dcca6552cd86b74391a From b7e48b422f44947502daab3740245152eab651f9 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 10 Jan 2020 16:21:02 -0800 Subject: [PATCH 0285/1427] [Services] Allow monit system tool to monitor the critical processes status running in various SONiC containers. (#3940) * Add a monit config file for teamd container. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file in teamd container into base image. Signed-off-by: Yong Zhao * Add a monit config file for snmp container. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file of snmp container into the base image. Signed-off-by: Yong Zhao * Add a monit config file for dhcp_relay container in the dir base_image_files. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file of dhcp_relay container into base image under /etc/monit/conf.d. Signed-off-by: Yong Zhao * Add a monit config file for router advertiser container. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file of router advertiser contianer into base image. Signed-off-by: Yong Zhao * [Docker-Pmon] Add a monit config file for pmon container. Signed-off-by: Yong Zhao * [Docker-Pmon] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-lldp] Add a monit config file for lldp container. Signed-off-by: Yong Zhao * [Docker-lldp] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-bgp] Add a monit config file for BGP container. Signed-off-by: Yong Zhao * [Docker-bgp] Add a copy mechanism to put monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-swss] Add a monit config file for the swss container. Signed-off-by: Yong Zhao * [Docker-swss] Add a copy mechanism to put monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on barefoot platform. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image on barefoot. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on broadcom. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image on broadcom. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on cavium. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-centec] Add a monit config file for syncd container on centen platform. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on centen platform. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit conifg file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on marvell-arm64. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image on marvell-arm64. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on marvell-armhf. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on mellanox. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on nephos. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-sflow] Add a monit config file for sflow container. Signed-off-by: Yong Zhao * [Docker-sflow] Add a copy mechanism to put the monit conifg file into the base image. Signed-off-by: Yong Zhao * [Docker-telemetry] Add a monit config file for telemetry container. Signed-off-by: Yong Zhao * [Docker-telemetry] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-database] Add a monit config file for database container. Signed-off-by: Yong Zhao * [Docker-database] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-Dhcprelay] Change a typo. Signed-off-by: Yong Zhao * [Docker-Dhcprelay] Change the process name in monit config file to dhcrelay. Signed-off-by: Yong Zhao * [Docker-syncd] There is no desserve process in syncd container on barefoot. Signed-off-by: Yong Zhao * [Docker-syncd] There is no process desserve in syncd container on cavium. Signed-off-by: Yong Zhao * [Docker-syncd] There is no process named desserve in syncd on centec. Signed-off-by: Yong Zhao * [Docker-syncd] There is no process named desserve in syncd on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Should not delete the process desserve in syncd container on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd container on marvell-arm64. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd container on marvell-armhf. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd container on mellanox. Signed-off-by: Yong Zhao * [Docker-Radv] Change the process name to radvd. Signed-off-by: Yong Zhao * [Docker-telemetry] Correct a typo in monit_telemetry. Signed-off-by: Yong Zhao * [Docker-teamd] Delete the monit config file for teamd. Signed-off-by: Yong Zhao * [Docker-teamd] Delete the mechanism to copy the monit config file into base image. Signed-off-by: Yong Zhao * [Docker-dhcprelay] Delete the monit config file for dhcp_relay container. Signed-off-by: Yong Zhao * [Docker-dhcprelay] Delete the mechanism to copy the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-radv] Delete the monit config file foe radv container. Signed-off-by: Yong Zhao * [Docker-radv] Delete the mechanism to copy the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-bgp] change the monit config file for BGP container such that monit only generates alert if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-snmp] Change the monit config file for snmp container such that monit only generates alret if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-pmon] Change the monit config file for pmon container such that monit only generates alert if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-lldp] Change the monit config file for lldp container such that monit only generates alerts if some processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-pmon] Delete the monit config file for pmon container since some of processes are not running depended on the type of box. Signed-off-by: Yong Zhao * [Docker-pmon] Delete the copy mechanism to copy the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-lldp] Change the matching name for the process lldpd. Signed-off-by: Yong Zhao * [Docker-swss] Change the monit config file for swss container such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on barefoot such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Correct a typo in monit config file. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on broadcom such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on cavium such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on marvell such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on marvell-arm64 such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on marvell-armhf such that monit will generate alert if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on mellanox such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-sycnd] Change the monit config file for syncd container such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-sflow] Change the monit config file for sflow container such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-telemetry] Change the monit config file for telemetry container such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-database] Change the monit config file for database container such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-database] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-bgp] Use 4 spcess to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-lldp] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-swss] Use 4 spaces to replace 2 space in monit config file. Signed-off-by: Yong Zhao * [Docker-sflow] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-snmp] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-telemetry] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on barefoot. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on broadcom. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on cavium. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on centec. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on mellanox. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to repalce 2 spaces in the monit config file on nephos. Signed-off-by: Yong Zhao * [Docker-bgp] Remove the trailing extra spaces in monit config file. Signed-off-by: Yong Zhao --- .../base_image_files/monit_database | 7 +++ .../docker-fpm-frr/base_image_files/monit_bgp | 23 ++++++++++ .../base_image_files/monit_lldp | 15 +++++++ .../base_image_files/monit_swss | 43 +++++++++++++++++++ .../docker-sflow/base_image_files/monit_sflow | 7 +++ .../base_image_files/monit_snmp | 11 +++++ .../base_image_files/monit_telemetry | 11 +++++ platform/barefoot/docker-syncd-bfn.mk | 2 +- .../base_image_files/monit_syncd | 7 +++ platform/broadcom/docker-syncd-brcm.mk | 1 + .../base_image_files/monit_syncd | 11 +++++ platform/cavium/docker-syncd-cavm.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/centec/docker-syncd-centec.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/marvell-arm64/docker-syncd-mrvl.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/marvell-armhf/docker-syncd-mrvl.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/marvell/docker-syncd-mrvl.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/mellanox/docker-syncd-mlnx.mk | 2 +- .../base_image_files/monit_syncd | 7 +++ platform/nephos/docker-syncd-nephos.mk | 2 +- .../base_image_files/monit_syncd | 11 +++++ rules/docker-database.mk | 1 + rules/docker-fpm-frr.mk | 1 + rules/docker-lldp-sv2.mk | 1 + rules/docker-orchagent.mk | 1 + rules/docker-sflow.mk | 1 + rules/docker-snmp-sv2.mk | 1 + rules/docker-telemetry.mk | 1 + 32 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 dockers/docker-database/base_image_files/monit_database create mode 100644 dockers/docker-fpm-frr/base_image_files/monit_bgp create mode 100644 dockers/docker-lldp-sv2/base_image_files/monit_lldp create mode 100644 dockers/docker-orchagent/base_image_files/monit_swss create mode 100644 dockers/docker-sflow/base_image_files/monit_sflow create mode 100644 dockers/docker-snmp-sv2/base_image_files/monit_snmp create mode 100644 dockers/docker-sonic-telemetry/base_image_files/monit_telemetry create mode 100644 platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd create mode 100644 platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd create mode 100644 platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd create mode 100644 platform/centec/docker-syncd-centec/base_image_files/monit_syncd create mode 100644 platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd create mode 100644 platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd create mode 100644 platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd create mode 100644 platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd create mode 100644 platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd diff --git a/dockers/docker-database/base_image_files/monit_database b/dockers/docker-database/base_image_files/monit_database new file mode 100644 index 000000000000..c5508922864e --- /dev/null +++ b/dockers/docker-database/base_image_files/monit_database @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for database container +## process list: +## redis_server +############################################################################### +check process redis_server matching "/usr/bin/redis-server" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp new file mode 100644 index 000000000000..5b943ea7c0bb --- /dev/null +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -0,0 +1,23 @@ +############################################################################### +## Monit configuration for BGP container +## process list: +## zebra +## fpmsyncd +## bgpd +## staticd +## bgpcfgd +############################################################################### +check process zebra matching "/usr/lib/frr/zebra" + if does not exist for 5 times within 5 cycles then alert + +check process fpmsyncd matching "fpmsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process bgpd matching "/usr/lib/frr/bgpd" + if does not exist for 5 times within 5 cycles then alert + +check process staticd matching "/usr/lib/frr/staticd" + if does not exist for 5 times within 5 cycles then alert + +check process bgpcfgd matching "python /usr/bin/bgpcfgd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-lldp-sv2/base_image_files/monit_lldp b/dockers/docker-lldp-sv2/base_image_files/monit_lldp new file mode 100644 index 000000000000..200c52c7d332 --- /dev/null +++ b/dockers/docker-lldp-sv2/base_image_files/monit_lldp @@ -0,0 +1,15 @@ +############################################################################### +## Monit configuration for lldp container +## process list: +## lldpd +## lldp-syncd +## lldpmgrd +############################################################################### +check process lldpd_monitor matching "lldpd: " + if does not exist for 5 times within 5 cycles then alert + +check process lldp_syncd matching "python2 -m lldp_syncd" + if does not exist for 5 times within 5 cycles then alert + +check process lldpmgrd matching "python /usr/bin/lldpmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-orchagent/base_image_files/monit_swss b/dockers/docker-orchagent/base_image_files/monit_swss new file mode 100644 index 000000000000..5928dbd4ddb0 --- /dev/null +++ b/dockers/docker-orchagent/base_image_files/monit_swss @@ -0,0 +1,43 @@ +############################################################################### +## Monit configuration for swss container +## process list: +## orchagent +## portsyncd +## neighsyncd +## vrfmgrd +## vlanmgrd +## intfmgrd +## portmgrd +## buffermgrd +## nbrmgrd +## vxlanmgrd +############################################################################### +check process orchagent matching "/usr/bin/orchagent -d /var/log/swss" + if does not exist for 5 times within 5 cycles then alert + +check process portsyncd matching "/usr/bin/portsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process neighsyncd matching "/usr/bin/neighsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process vrfmgrd matching "/usr/bin/vrfmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process vlanmgrd matching "/usr/bin/vlanmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process intfmgrd matching "/usr/bin/intfmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process portmgrd matching "/usr/bin/portmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process buffermgrd matching "/usr/bin/buffermgrd -l" + if does not exist for 5 times within 5 cycles then alert + +check process nbrmgrd matching "/usr/bin/nbrmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process vxlanmgrd matching "/usr/bin/vxlanmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sflow/base_image_files/monit_sflow b/dockers/docker-sflow/base_image_files/monit_sflow new file mode 100644 index 000000000000..d041f81001ea --- /dev/null +++ b/dockers/docker-sflow/base_image_files/monit_sflow @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for sflow container +## process list: +## sflowmgrd +############################################################################### +check process sflowmgrd matching "/usr/bin/sflowmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-snmp-sv2/base_image_files/monit_snmp b/dockers/docker-snmp-sv2/base_image_files/monit_snmp new file mode 100644 index 000000000000..811f9d14b3d4 --- /dev/null +++ b/dockers/docker-snmp-sv2/base_image_files/monit_snmp @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for snmp container +## process list: +## snmpd +## snmpd_subagent +############################################################################### +check process snmpd matching "/usr/sbin/snmpd -f" + if does not exist for 5 times within 5 cycles then alert + +check process snmp_subagent matching "python3.6 -m sonic_ax_impl" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry new file mode 100644 index 000000000000..555822c57f80 --- /dev/null +++ b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for telemetry container +## process list: +## telemetry +## dialout_client +############################################################################### +check process telemetry matching "/usr/sbin/telemetry -logtostderr --insecure" + if does not exist for 5 times within 5 cycles then alert + +check process dialout_client matching "/usr/sbin/dialout_client_cli -insecure -logtostderr" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/barefoot/docker-syncd-bfn.mk b/platform/barefoot/docker-syncd-bfn.mk index 6f3ed59ad285..3a5c693e2fa8 100644 --- a/platform/barefoot/docker-syncd-bfn.mk +++ b/platform/barefoot/docker-syncd-bfn.mk @@ -11,4 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/broadcom/docker-syncd-brcm.mk b/platform/broadcom/docker-syncd-brcm.mk index 29727dbb2260..d3a6d67c5cbc 100644 --- a/platform/broadcom/docker-syncd-brcm.mk +++ b/platform/broadcom/docker-syncd-brcm.mk @@ -16,3 +16,4 @@ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmcmd:/usr/bin/bcmcmd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd new file mode 100644 index 000000000000..3f8bc50007d7 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +## dsserve +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert + +check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/cavium/docker-syncd-cavm.mk b/platform/cavium/docker-syncd-cavm.mk index a136828dbff1..ad43d6f1196f 100644 --- a/platform/cavium/docker-syncd-cavm.mk +++ b/platform/cavium/docker-syncd-cavm.mk @@ -20,3 +20,4 @@ $(DOCKER_SYNCD_CAVM)_CONTAINER_NAME = syncd $(DOCKER_SYNCD_CAVM)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_CAVM)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CAVM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_CAVM)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/centec/docker-syncd-centec.mk b/platform/centec/docker-syncd-centec.mk index 360690731a58..a0dbcc629dee 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -21,3 +21,4 @@ $(DOCKER_SYNCD_CENTEC)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_CENTEC)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-arm64/docker-syncd-mrvl.mk b/platform/marvell-arm64/docker-syncd-mrvl.mk index e00769a59700..841e3b4b165f 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl.mk @@ -11,3 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-armhf/docker-syncd-mrvl.mk b/platform/marvell-armhf/docker-syncd-mrvl.mk index e00769a59700..841e3b4b165f 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl.mk +++ b/platform/marvell-armhf/docker-syncd-mrvl.mk @@ -11,3 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell/docker-syncd-mrvl.mk b/platform/marvell/docker-syncd-mrvl.mk index 5257bf5e68e7..97b7eab19895 100644 --- a/platform/marvell/docker-syncd-mrvl.mk +++ b/platform/marvell/docker-syncd-mrvl.mk @@ -12,3 +12,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/mellanox/docker-syncd-mlnx.mk b/platform/mellanox/docker-syncd-mlnx.mk index db582e517bff..9bdc5a8ad8ec 100644 --- a/platform/mellanox/docker-syncd-mlnx.mk +++ b/platform/mellanox/docker-syncd-mlnx.mk @@ -15,4 +15,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(MLNX_SDK_DBG_DEBS) $(MLNX_SAI_DBGSYM) endif $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/nephos/docker-syncd-nephos.mk b/platform/nephos/docker-syncd-nephos.mk index 6829c91c67aa..67bad252870a 100644 --- a/platform/nephos/docker-syncd-nephos.mk +++ b/platform/nephos/docker-syncd-nephos.mk @@ -15,4 +15,4 @@ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += npx_diag:/usr/bin/npx_diag - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd new file mode 100644 index 000000000000..3f8bc50007d7 --- /dev/null +++ b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +## dsserve +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert + +check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 43dc2ed5d446..9ad6b0b36b45 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -27,3 +27,4 @@ $(DOCKER_DATABASE)_RUN_OPT += --net=host --privileged -t $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli +$(DOCKER_DATABASE)_BASE_IMAGE_FILES += monit_database:/etc/monit/conf.d diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 1d158effe7ff..e833d360bec2 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -30,3 +30,4 @@ $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSA:/usr/bin/TSA $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSB:/usr/bin/TSB $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSC:/usr/bin/TSC +$(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += monit_bgp:/etc/monit/conf.d diff --git a/rules/docker-lldp-sv2.mk b/rules/docker-lldp-sv2.mk index 91acbe58ad82..8224239c1ced 100644 --- a/rules/docker-lldp-sv2.mk +++ b/rules/docker-lldp-sv2.mk @@ -30,4 +30,5 @@ $(DOCKER_LLDP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpctl:/usr/bin/lldpctl $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpcli:/usr/bin/lldpcli +$(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += monit_lldp:/etc/monit/conf.d $(DOCKER_LLDP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index 20536adc2520..0244138cbfe2 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -34,4 +34,5 @@ $(DOCKER_ORCHAGENT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel +$(DOCKER_ORCHAGENT)_BASE_IMAGE_FILES += monit_swss:/etc/monit/conf.d $(DOCKER_ORCHAGENT)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk index 94b568481885..449ff7c566f2 100644 --- a/rules/docker-sflow.mk +++ b/rules/docker-sflow.mk @@ -32,4 +32,5 @@ $(DOCKER_SFLOW)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SFLOW)_BASE_IMAGE_FILES += psample:/usr/bin/psample $(DOCKER_SFLOW)_BASE_IMAGE_FILES += sflowtool:/usr/bin/sflowtool +$(DOCKER_SFLOW)_BASE_IMAGE_FILES += monit_sflow:/etc/monit/conf.d $(DOCKER_SFLOW)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-snmp-sv2.mk b/rules/docker-snmp-sv2.mk index bd34f271b861..1f403b7a8c8a 100644 --- a/rules/docker-snmp-sv2.mk +++ b/rules/docker-snmp-sv2.mk @@ -31,3 +31,4 @@ $(DOCKER_SNMP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # mount Arista platform python libraries to support corresponding platforms SNMP power status query $(DOCKER_SNMP_SV2)_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro $(DOCKER_SNMP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_SNMP_SV2)_BASE_IMAGE_FILES += monit_snmp:/etc/monit/conf.d diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 799bef1b1735..361136306337 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -30,3 +30,4 @@ $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" $(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_TELEMETRY)_BASE_IMAGE_FILES += monit_telemetry:/etc/monit/conf.d From 952dfb15f706a9be10833c186a8bcbed3847843f Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sun, 12 Jan 2020 21:53:52 +0000 Subject: [PATCH 0286/1427] [docker-sonic-mgmt]: fix installation permission issue --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 4a7e1a977549..7cfaeaaf7d2b 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -105,6 +105,8 @@ debs/{{ deb }}{{' '}} RUN pip install ansible==2.8.7 +RUN pip install pysubnettree + RUN mkdir /var/run/sshd EXPOSE 22 @@ -143,6 +145,4 @@ RUN azure-cli_bundle_*/installer # TODO: if azure-cli contains newer version azure-keyvault, remove this RUN ~/lib/azure-cli/bin/python -m pip install azure-keyvault==0.3.7 -U -RUN pip install pysubnettree - RUN git clone https://github.com/Azure/sonic-mgmt From 918fdc6c443945986816358aac39b2adafc67c25 Mon Sep 17 00:00:00 2001 From: padmanarayana Date: Tue, 14 Jan 2020 14:16:33 -0800 Subject: [PATCH 0287/1427] [sflow]: Upgrade hsflowd to v2.0.26-3 (#4020) --- rules/sflow.mk | 2 +- src/sflow/hsflowd/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/sflow.mk b/rules/sflow.mk index f267353c0f93..4bc443647f80 100644 --- a/rules/sflow.mk +++ b/rules/sflow.mk @@ -1,7 +1,7 @@ # host-sflow package HSFLOWD_VERSION = 2.0.26 -HSFLOWD_SUBVERSION = 1 +HSFLOWD_SUBVERSION = 3 export HSFLOWD_VERSION HSFLOWD_SUBVERSION HSFLOWD = hsflowd_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb diff --git a/src/sflow/hsflowd/Makefile b/src/sflow/hsflowd/Makefile index 0a8094e3b695..e3a930549f19 100644 --- a/src/sflow/hsflowd/Makefile +++ b/src/sflow/hsflowd/Makefile @@ -10,7 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git clone https://github.com/sflow/host-sflow pushd ./host-sflow - git checkout -b sflow tags/v2.0.26-1 + git checkout -b sflow tags/v2.0.26-3 # Apply patch series stg init From ebb07d99424de7421baffa10b9cb2ee91ac61494 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Tue, 14 Jan 2020 17:13:45 -0800 Subject: [PATCH 0288/1427] [docker-restapi]: Avoid building RestAPI docker by default (#4018) Provide build option for RESTAPI docker --- Makefile.work | 1 + rules/config | 3 +++ rules/docker-restapi.mk | 2 ++ slave.mk | 6 ++++++ 4 files changed, 12 insertions(+) diff --git a/Makefile.work b/Makefile.work index 71175d5c4757..a1ccf8715567 100644 --- a/Makefile.work +++ b/Makefile.work @@ -177,6 +177,7 @@ SONIC_BUILD_INSTRUCTION := make \ HTTP_PROXY=$(http_proxy) \ HTTPS_PROXY=$(https_proxy) \ SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY) \ + SONIC_ENABLE_RESTAPI=$(ENABLE_RESTAPI) \ EXTRA_JESSIE_TARGETS=$(EXTRA_JESSIE_TARGETS) \ $(SONIC_OVERRIDE_BUILD_VARS) diff --git a/rules/config b/rules/config index a559a5b2fc88..c8a24606f426 100644 --- a/rules/config +++ b/rules/config @@ -104,3 +104,6 @@ ENABLE_SFLOW = y # ENABLE_MGMT_FRAMEWORK - build docker-sonic-mgt-framework for CLI and REST server support ENABLE_MGMT_FRAMEWORK = y + +# ENABLE_RESTAPI - build docker-sonic-restapi for configuring the switch using REST APIs +ENABLE_RESTAPI = n diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index 66d60205915a..7c02e0d4e44b 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -10,9 +10,11 @@ $(DOCKER_RESTAPI)_PATH = $(DOCKERS_PATH)/$(DOCKER_RESTAPI_STEM) $(DOCKER_RESTAPI)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +ifeq ($(ENABLE_RESTAPI), y) SONIC_DOCKER_IMAGES += $(DOCKER_RESTAPI) SONIC_STRETCH_DOCKERS += $(DOCKER_RESTAPI) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_RESTAPI) +endif $(DOCKER_RESTAPI)_CONTAINER_NAME = rest-api $(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t diff --git a/slave.mk b/slave.mk index 8f8c4dd87890..8e7253d7e57c 100644 --- a/slave.mk +++ b/slave.mk @@ -100,6 +100,10 @@ ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) ENABLE_SYSTEM_TELEMETRY = N endif +ifeq ($(SONIC_ENABLE_RESTAPI),y) +ENABLE_RESTAPI = y +endif + ifeq ($(SONIC_ENABLE_SYNCD_RPC),y) ENABLE_SYNCD_RPC = y endif @@ -190,6 +194,7 @@ $(info "ENABLE_ORGANIZATION_EXTENSIONS" : "$(ENABLE_ORGANIZATION_EXTENSIONS)") $(info "HTTP_PROXY" : "$(HTTP_PROXY)") $(info "HTTPS_PROXY" : "$(HTTPS_PROXY)") $(info "ENABLE_SYSTEM_TELEMETRY" : "$(ENABLE_SYSTEM_TELEMETRY)") +$(info "ENABLE_RESTAPI" : "$(ENABLE_RESTAPI)") $(info "ENABLE_ZTP" : "$(ENABLE_ZTP)") $(info "SONIC_DEBUGGING_ON" : "$(SONIC_DEBUGGING_ON)") $(info "SONIC_PROFILING_ON" : "$(SONIC_PROFILING_ON)") @@ -643,6 +648,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_organization_extensions="$(ENABLE_ORGANIZATION_EXTENSIONS)" export enable_dhcp_graph_service="$(ENABLE_DHCP_GRAPH_SERVICE)" export enable_system_telemetry="$(ENABLE_SYSTEM_TELEMETRY)" + export enable_restapi="$(ENABLE_RESTAPI)" export enable_ztp="$(ENABLE_ZTP)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" From 237835f37a3fe4e49da9dc7f8cd569fe1eac445a Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Wed, 15 Jan 2020 17:19:49 +0200 Subject: [PATCH 0289/1427] Change MFT version to 14.13.3 (#4022) --- platform/mellanox/mft.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index ae2c92e0ac18..af2192de4543 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -1,7 +1,7 @@ # Mellanox SAI -MFT_VERSION = 4.12.0 -MFT_REVISION = 104 +MFT_VERSION = 4.13.3 +MFT_REVISION = 6 export MFT_VERSION MFT_REVISION From 9a089c2e1c8ecb673670a2f2b356e1c58d9b1e7b Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 15 Jan 2020 17:23:25 +0200 Subject: [PATCH 0290/1427] [mellanox] Update FW to 13/29.2000.2714. (#3998) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/fw.mk | 4 ++-- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index eb1a58cfda9d..4f6e7199eac8 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,12 +11,12 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.2696 +MLNX_SPC_FW_VERSION = 13.2000.2714 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.2696 +MLNX_SPC2_FW_VERSION = 29.2000.2714 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index c08b5bb3810f..b85c06417b2d 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit c08b5bb3810fe7da2811622aa7003ac9cc95344b +Subproject commit b85c06417b2df7e18990d0143a30ab1c46e34225 From 6bd17d47808e3889d0625e59a027c0960b82c164 Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Wed, 15 Jan 2020 21:55:01 +0530 Subject: [PATCH 0291/1427] [initramfs] Updated required tools for initramfs (#3734) * [initramfs] Updated reuired tools for initramfs Signed-off-by: Antony Rheneus * [initramfs] Updated required tools for initramfs Signed-off-by: Antony Rheneus * [Platform] [Marvell] Platform specific debian package for et6448m device Signed-off-by: Antony Rheneus * Removed auto-generated files Signed-off-by: Antony Rheneus * [initramfs] Added mtd and uboot firmware tools package required for arm arch Its been enabled to all arch including amd64 Signed-off-by: Antony Rheneus * [initramfs] Added mtd and uboot firmware tools package required for arm arch Its been enabled to all arch including amd64 Signed-off-by: Antony Rheneus * [initramfs] Marvell arm modules update and platform config update Signed-off-by: Antony Rheneus * [iniramfs] add initramfs uboot-utils hook script only for ARM Signed-off-by: Antony Rheneus --- build_debian.sh | 19 ++ .../armhf-marvell_et6448m_52x-r0/fancontrol | 17 +- files/initramfs-tools/modules.arm | 7 + files/initramfs-tools/uboot-utils | 21 ++ files/initramfs-tools/union-mount.j2 | 15 +- files/initramfs-tools/varlog | 10 +- installer/armhf/install.sh | 134 ++++++++++- onie-image-armhf.conf | 3 + platform/marvell-armhf/one-image.mk | 1 + platform/marvell-armhf/platform-et6448m.mk | 9 + platform/marvell-armhf/platform.conf | 226 ++++++++++-------- platform/marvell-armhf/rules.mk | 1 + .../sonic-platform-et6448m/.gitignore | 50 ++++ .../sonic-platform-et6448m/debian/changelog | 5 + .../sonic-platform-et6448m/debian/compat | 1 + .../sonic-platform-et6448m/debian/control | 15 ++ .../sonic-platform-et6448m/debian/install | 1 + .../sonic-platform-et6448m/debian/postinst | 40 ++++ .../sonic-platform-et6448m/debian/rules | 25 ++ .../et6448m_plt_setup.sh | 57 +++++ 20 files changed, 535 insertions(+), 122 deletions(-) create mode 100644 files/initramfs-tools/modules.arm create mode 100644 files/initramfs-tools/uboot-utils create mode 100644 platform/marvell-armhf/platform-et6448m.mk create mode 100644 platform/marvell-armhf/sonic-platform-et6448m/.gitignore create mode 100755 platform/marvell-armhf/sonic-platform-et6448m/debian/changelog create mode 100644 platform/marvell-armhf/sonic-platform-et6448m/debian/compat create mode 100755 platform/marvell-armhf/sonic-platform-et6448m/debian/control create mode 100644 platform/marvell-armhf/sonic-platform-et6448m/debian/install create mode 100644 platform/marvell-armhf/sonic-platform-et6448m/debian/postinst create mode 100755 platform/marvell-armhf/sonic-platform-et6448m/debian/rules create mode 100755 platform/marvell-armhf/sonic-platform-et6448m/et6448m_plt_setup.sh diff --git a/build_debian.sh b/build_debian.sh index 3ccdd3e9820a..57c85e033f58 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -176,6 +176,11 @@ sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/varlog sudo cp files/initramfs-tools/union-fsck $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/union-fsck sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/union-fsck pushd $FILESYSTEM_ROOT/usr/share/initramfs-tools/scripts/init-bottom && sudo patch -p1 < $OLDPWD/files/initramfs-tools/udev.patch; popd +if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then + sudo cp files/initramfs-tools/uboot-utils $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/uboot-utils + sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/uboot-utils + cat files/initramfs-tools/modules.arm | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null +fi if [[ $CONFIGURED_ARCH == amd64 ]]; then ## Install latest intel ixgbe driver @@ -494,8 +499,22 @@ fi ## Remove gcc and python dev pkgs sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y remove gcc libpython2.7-dev +## Add mtd and uboot firmware tools package +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install u-boot-tools mtd-utils +sudo LANG=C chroot $FILESYSTEM_ROOT apt-mark manual u-boot-tools mtd-utils + ## Update initramfs sudo chroot $FILESYSTEM_ROOT update-initramfs -u +## Convert initrd image to u-boot format +if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then + INITRD_FILE=initrd.img-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH} + if [[ $CONFIGURED_ARCH == armhf ]]; then + INITRD_FILE=initrd.img-${LINUX_KERNEL_VERSION}-armmp + fi + sudo LANG=C chroot $FILESYSTEM_ROOT mkimage -A arm -O linux -T ramdisk -C gzip -d /boot/$INITRD_FILE /boot/u${INITRD_FILE} + ## Overwriting the initrd image with uInitrd + sudo LANG=C chroot $FILESYSTEM_ROOT mv /boot/u${INITRD_FILE} /boot/$INITRD_FILE +fi ## Clean up apt sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y autoremove diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/fancontrol b/device/marvell/armhf-marvell_et6448m_52x-r0/fancontrol index c2150eb45741..050e2504626c 100755 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/fancontrol +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/fancontrol @@ -1,10 +1,9 @@ INTERVAL=10 -DEVPATH=hwmon0=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-002e hwmon1=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004a hwmon2=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004b -DEVNAME=hwmon0=adt7473 hwmon1=lm75a hwmon2=lm75a -FCTEMPS=hwmon0/device/pwm2=hwmon2/temp1_input hwmon0/device/pwm1=hwmon1/temp1_input -FCFANS=hwmon0/device/pwm2=hwmon0/device/fan2_input hwmon0/device/pwm1=hwmon0/device/fan1_input -MINTEMP=hwmon0/device/pwm2=20 hwmon0/device/pwm1=20 -MAXTEMP=hwmon0/device/pwm2=60 hwmon0/device/pwm1=60 -MINSTART=hwmon0/device/pwm2=150 hwmon0/device/pwm1=150 -MINSTOP=hwmon0/device/pwm2=0 hwmon0/device/pwm1=0 - +DEVPATH=hwmon1=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-002e +DEVNAME=hwmon1=adt7473 +FCTEMPS=hwmon1/device/pwm1=hwmon1/device/temp1_input hwmon1/device/pwm2=hwmon1/device/temp2_input +FCFANS=hwmon1/device/pwm1= hwmon1/device/pwm2=hwmon1/device/fan1_input +MINTEMP=hwmon1/device/pwm1=20 hwmon1/device/pwm2=20 +MAXTEMP=hwmon1/device/pwm1=60 hwmon1/device/pwm2=60 +MINSTART=hwmon1/device/pwm1=150 hwmon1/device/pwm2=150 +MINSTOP=hwmon1/device/pwm1=0 hwmon1/device/pwm2=0 diff --git a/files/initramfs-tools/modules.arm b/files/initramfs-tools/modules.arm new file mode 100644 index 000000000000..a923920bb1b2 --- /dev/null +++ b/files/initramfs-tools/modules.arm @@ -0,0 +1,7 @@ +crc16 +deflate +zlib_deflate +m25p80 +ubi +ubifs +squashfs diff --git a/files/initramfs-tools/uboot-utils b/files/initramfs-tools/uboot-utils new file mode 100644 index 000000000000..a9255a37eacf --- /dev/null +++ b/files/initramfs-tools/uboot-utils @@ -0,0 +1,21 @@ +#!/bin/sh +#Part of the code is revised based on initramfs-tool is under GPL v2. + +PREREQ="" + +prereqs() +{ + echo "$PREREQ" +} + +case $1 in +prereqs) + prereqs + exit 0 + ;; +esac + +. /usr/share/initramfs-tools/hook-functions + +copy_exec /usr/sbin/ubiattach /sbin/ubiattach +copy_exec /usr/sbin/mtdinfo /sbin/mtdinfo diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index f6f1deff4220..2376ea490e64 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -45,8 +45,19 @@ mkdir -p ${rootmnt}/host/$image_dir/work mount -n -o lowerdir=${rootmnt},upperdir=${rootmnt}/host/$image_dir/rw,workdir=${rootmnt}/host/$image_dir/work -t overlay root-overlay ${rootmnt} ## Check if the root block device is still there [ -b ${ROOT} ] || mdev -s -## Mount the raw partition again -mount ${ROOT} ${rootmnt}/host +case "${ROOT}" in + ubi*) + mtd=$(cat /proc/cmdline | sed -e 's/.*ubi.mtd=\([0-9]\) .*/\1/') + if [ ! -f /dev/${ROOT}_0 ]; then + ubiattach /dev/ubi_ctrl -m $mtd || true + fi + mount -t ubifs /dev/${ROOT}_0 ${rootmnt}/host + ;; + *) + ## Mount the raw partition again + mount ${ROOT} ${rootmnt}/host + ;; +esac mkdir -p ${rootmnt}/var/lib/docker if [ -f ${rootmnt}/host/$image_dir/{{ FILESYSTEM_DOCKERFS }} ]; then diff --git a/files/initramfs-tools/varlog b/files/initramfs-tools/varlog index d1340eaa9d8b..e8063e41a59c 100644 --- a/files/initramfs-tools/varlog +++ b/files/initramfs-tools/varlog @@ -33,4 +33,12 @@ if [ -e "${rootmnt}/host/disk-img/var-log.ext4" ]; then fi # create varlog disk -mkdir -p ${rootmnt}/host/disk-img && ${rootmnt}/usr/bin/fallocate -l "$varlog_size"M ${rootmnt}/host/disk-img/var-log.ext4 && mkfs.ext4 -q -F ${rootmnt}/host/disk-img/var-log.ext4 +case "${ROOT}" in + ubi*) + # sys_fallocate is NOT supported over UBIFS + mkdir -p ${rootmnt}/host/disk-img && ${rootmnt}/usr/bin/truncate -s "$varlog_size"M ${rootmnt}/host/disk-img/var-log.ext4 && mkfs.ext4 -q -F ${rootmnt}/host/disk-img/var-log.ext4 + ;; + *) + mkdir -p ${rootmnt}/host/disk-img && ${rootmnt}/usr/bin/fallocate -l "$varlog_size"M ${rootmnt}/host/disk-img/var-log.ext4 && mkfs.ext4 -q -F ${rootmnt}/host/disk-img/var-log.ext4 + ;; +esac diff --git a/installer/armhf/install.sh b/installer/armhf/install.sh index bfd7eeef9e41..53f2fdf99661 100755 --- a/installer/armhf/install.sh +++ b/installer/armhf/install.sh @@ -3,6 +3,17 @@ # Copyright (C) Marvell Inc # +_trap_push() { + local next="$1" + eval "trap_push() { + local oldcmd='$(echo "$next" | sed -e s/\'/\'\\\\\'\'/g)' + local newcmd=\"\$1; \$oldcmd\" + trap -- \"\$newcmd\" EXIT INT TERM HUP + _trap_push \"\$newcmd\" + }" +} +_trap_push true + set -e if [ -d "/etc/sonic" ]; then @@ -26,27 +37,124 @@ if [ -r ./onie-image-armhf.conf ]; then . ./onie-image-armhf.conf fi +echo "ONIE Installer: platform: $platform" -echo "Installer: platform: $platform" +# Make sure run as root or under 'sudo' +if [ $(id -u) -ne 0 ] + then echo "Please run as root" + exit 1 +fi -# install_uimage will be overriden from platform.conf as it is non generic -install_uimage() { - echo "Copying uImage to NOR flash:" - flashcp -v demo-${platform}.itb $mtd_dev -} +if [ -r /etc/machine.conf ]; then + . /etc/machine.conf +elif [ -r /host/machine.conf ]; then + . /host/machine.conf +elif [ "$install_env" != "build" ]; then + echo "cannot find machine.conf" + exit 1 +fi + +echo "onie_platform: $onie_platform" + +# Get platform specific linux kernel command line arguments +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="" + +# Default var/log device size in MB +VAR_LOG_SIZE=4096 + +[ -r platforms/$onie_platform ] && . platforms/$onie_platform + + +# If running in ONIE +if [ "$install_env" = "onie" ]; then + # The onie bin tool prefix + onie_bin= + # The persistent ONIE directory location + onie_root_dir=/mnt/onie-boot/onie + # The onie file system root + onie_initrd_tmp=/ +fi + +# The build system prepares this script by replacing %%DEMO-TYPE%% +# with "OS" or "DIAG". +demo_type="%%DEMO_TYPE%%" + +# The build system prepares this script by replacing %%IMAGE_VERSION%% +# with git revision hash as a version identifier +image_version="%%IMAGE_VERSION%%" +timestamp="$(date -u +%Y%m%d)" + +demo_volume_label="SONiC-${demo_type}" +demo_volume_revision_label="SONiC-${demo_type}-${image_version}" -# hw_load will be overriden from platform.conf as it is non generic -hw_load() { - echo "cp.b $img_start \$loadaddr $img_sz" -} . ./platform.conf -install_uimage +image_dir="image-$image_version" + +if [ "$install_env" = "onie" ]; then + # Create/format the flash + create_partition + mount_partition +elif [ "$install_env" = "sonic" ]; then + demo_mnt="/host" + eval running_sonic_revision=$(cat /etc/sonic/sonic_version.yml | grep build_version | cut -f2 -d" ") + # Prevent installing existing SONiC if it is running + if [ "$image_dir" = "image-$running_sonic_revision" ]; then + echo "Not installing SONiC version $running_sonic_revision, as current running SONiC has the same version" + exit 0 + fi + # Remove extra SONiC images if any + for f in $demo_mnt/image-* ; do + if [ -d $f ] && [ "$f" != "$demo_mnt/image-$running_sonic_revision" ] && [ "$f" != "$demo_mnt/$image_dir" ]; then + echo "Removing old SONiC installation $f" + rm -rf $f + fi + done +fi + +# Create target directory or clean it up if exists +if [ -d $demo_mnt/$image_dir ]; then + echo "Directory $demo_mnt/$image_dir/ already exists. Cleaning up..." + rm -rf $demo_mnt/$image_dir/* +else + mkdir $demo_mnt/$image_dir || { + echo "Error: Unable to create SONiC directory" + exit 1 + } +fi -hw_load_str="$(hw_load)" +# Decompress the file for the file system directly to the partition +if [ x"$docker_inram" = x"on" ]; then + # when disk is small, keep dockerfs.tar.gz in disk, expand it into ramfs during initrd + unzip -o $ONIE_INSTALLER_PAYLOAD -d $demo_mnt/$image_dir +else + unzip -o $ONIE_INSTALLER_PAYLOAD -x "$FILESYSTEM_DOCKERFS" -d $demo_mnt/$image_dir + + if [ "$install_env" = "onie" ]; then + TAR_EXTRA_OPTION="--numeric-owner" + else + TAR_EXTRA_OPTION="--numeric-owner --warning=no-timestamp" + fi + mkdir -p $demo_mnt/$image_dir/$DOCKERFS_DIR + unzip -op $ONIE_INSTALLER_PAYLOAD "$FILESYSTEM_DOCKERFS" | tar xz $TAR_EXTRA_OPTION -f - -C $demo_mnt/$image_dir/$DOCKERFS_DIR +fi + + +if [ "$install_env" = "onie" ]; then + # Store machine description in target file system + if [ -f /etc/machine-build.conf ]; then + # onie_ variable are generate at runtime. + # they are no longer hardcoded in /etc/machine.conf + # also remove single quotes around the value + set | grep ^onie | sed -e "s/='/=/" -e "s/'$//" > $demo_mnt/machine.conf + else + cp /etc/machine.conf $demo_mnt + fi +fi -cd / +# Update Bootloader Menu with installed image +bootloader_menu_config # Set NOS mode if available. For manufacturing diag installers, you # probably want to skip this step so that the system remains in ONIE diff --git a/onie-image-armhf.conf b/onie-image-armhf.conf index 0d816e4a898c..bbff03f64041 100644 --- a/onie-image-armhf.conf +++ b/onie-image-armhf.conf @@ -24,6 +24,9 @@ FILESYSTEM_DOCKERFS=dockerfs.tar.gz ## docker directory on the root filesystem DOCKERFS_DIR=docker +## docker ramfs disk space +DOCKER_RAMFS_SIZE=900M + ## Output file name for onie installer OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin diff --git a/platform/marvell-armhf/one-image.mk b/platform/marvell-armhf/one-image.mk index bed895d84d86..000ac9ea3e18 100644 --- a/platform/marvell-armhf/one-image.mk +++ b/platform/marvell-armhf/one-image.mk @@ -5,6 +5,7 @@ $(SONIC_ONE_IMAGE)_MACHINE = marvell-armhf $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_INSTALLS += $(LINUX_KERNEL_DTB) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(ET6448M_PLATFORM) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/marvell-armhf/platform-et6448m.mk b/platform/marvell-armhf/platform-et6448m.mk new file mode 100644 index 000000000000..eeef04a20ae7 --- /dev/null +++ b/platform/marvell-armhf/platform-et6448m.mk @@ -0,0 +1,9 @@ +# ET6448M Platform + +ET6448M_VERSION=0.1 +ET6448M_PLATFORM = sonic-platform-et6448m_$(ET6448M_VERSION)_$(CONFIGURED_ARCH).deb +$(ET6448M_PLATFORM)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-et6448m +$(ET6448M_PLATFORM)_PLATFORM = armhf-marvell_et6448m_52x-r0 +SONIC_DPKG_DEBS += $(ET6448M_PLATFORM) + +SONIC_STRETCH_DEBS += $(ET6448M_PLATFORM) diff --git a/platform/marvell-armhf/platform.conf b/platform/marvell-armhf/platform.conf index e574a8d1a0cd..7799b33d57d9 100644 --- a/platform/marvell-armhf/platform.conf +++ b/platform/marvell-armhf/platform.conf @@ -7,76 +7,133 @@ echo "Preparing for installation ... " # global defines kernel_addr=0x1100000 fdt_addr=0x1000000 +initrd_addr=0x2000000 +VAR_LOG=512 -image_name="/vmlinuz" -fdt_name="/boot/armada-385-ET6448M_4G_Nand.dtb" +kernel_fname="/boot/vmlinuz-4.9.0-9-2-armmp" +initrd_fname="/boot/initrd.img-4.9.0-9-2-armmp" +fdt_fname="/boot/armada-385-ET6448M_4G_Nand.dtb" # global mount defines demo_dev=ubi0 mtd_dev=/dev/$(cat /proc/mtd | grep "SONIC" | grep -o "mtd[0-9]") mtd_num=$(echo $mtd_dev | grep -o "[0-9]") -demo_mount=/tmp -FW_ENV='/dev/mtd0 \t\t 0x00500000 \t 0x80000 \t 0x100000 \t 8' - -BOOTARGS='setenv bootargs root='$demo_dev' rw rootwait ubi.mtd='$mtd_num' rootfstype=ubifs panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts}' -UBI_LOAD='run ubi_sonic_boot_mount_ubi; ubifsload $kernel_addr $image_name;ubifsload $fdt_addr $fdt_name' -UBIBOOTCMD='run ubi_sonic_boot_bootargs; run ubi_sonic_boot_load; bootz $kernel_addr - $fdt_addr' - -et6448m_machine_conf() { - SYSCTL_CFG=$demo_mount/usr/share/sonic/device/armhf-marvell_et6448m_52x-r0/syncd.conf - - echo "Configure platform et6448m " - rm $demo_mount/lib/udev/rules.d/73-usb-net-by-mac.rules - rm -f $demo_mount/usr/bin/reboot || true - rm -fr $demo_mount/host/machine.conf - cp /etc/machine.conf $demo_mount/host/ - - SONIC_VERSION=$(cat $demo_mount/etc/sonic/sonic_version.yml | grep build_version | cut -f2 -d"'") - FIRST_BOOT_FILE="$demo_mount/host/image-$SONIC_VERSION/platform" - mkdir -p $FIRST_BOOT_FILE - touch $FIRST_BOOT_FILE/firsttime - - MAC_ADDR=$(fw_printenv | grep ^ethaddr= | cut -f2 -d"=") - sed -i "s/switchMacAddress=.*/switchMacAddress=$MAC_ADDR/g" $demo_mount/usr/share/sonic/device/armhf-marvell_et6448m_52x-r0/et6448m/profile.ini - - # IPv4 and IPv6 arp cache limits - echo "sysctl -w net.ipv4.neigh.default.gc_thresh1=16000" >> $SYSCTL_CFG - echo "sysctl -w net.ipv4.neigh.default.gc_thresh2=32000" >> $SYSCTL_CFG - echo "sysctl -w net.ipv4.neigh.default.gc_thresh3=48000" >> $SYSCTL_CFG - echo "sysctl -w net.ipv6.neigh.default.gc_thresh1=8000 " >> $SYSCTL_CFG - echo "sysctl -w net.ipv6.neigh.default.gc_thresh2=16000" >> $SYSCTL_CFG - echo "sysctl -w net.ipv6.neigh.default.gc_thresh3=32000" >> $SYSCTL_CFG -} - -prepare_uboot() { +demo_mnt=/tmp +FW_ENV_DEFAULT='/dev/mtd0 0x00500000 0x80000 0x100000 8' +UBOOT_FW_DEFAULT=1 + +# Skip VID Header in UBIFS +BOOTARGS='setenv bootargs root='$demo_dev' rw rootwait ubi.mtd='$mtd_num',8192 rootfstype=ubifs panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts} ${linuxargs}' +UBI_LOAD='run ubi_sonic_boot_mount_ubi; ubifsload $kernel_addr $image_name;ubifsload $fdt_addr $fdt_name; ubifsload $initrd_addr $initrd_name' +BOOTARGS_OLD='setenv bootargs root='$demo_dev' rw rootwait ubi.mtd='$mtd_num',8192 rootfstype=ubifs panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts} ${linuxargs_old}' +UBI_LOAD_OLD='run ubi_sonic_boot_mount_ubi; ubifsload $kernel_addr $image_name_old;ubifsload $fdt_addr $fdt_name_old; ubifsload $initrd_addr $initrd_name_old' +UBIBOOTCMD='run ubi_sonic_boot_bootargs; run ubi_sonic_boot_load; test -n "$boot_once" && setenv boot_once "" && saveenv; bootz $kernel_addr $initrd_addr $fdt_addr' +UBIBOOTCMD_OLD='run ubi_sonic_boot_bootargs_old; run ubi_sonic_boot_load_old; test -n "$boot_once" && setenv boot_once "" && saveenv; bootz $kernel_addr $initrd_addr $fdt_addr' +LINUX_MISC_CMD='apparmor=1 security=apparmor usbcore.autosuspend=-1' + +prepare_boot_menu() { echo "Setting up U-Boot environment..." - echo -e $FW_ENV > /etc/fw_env.config - - fw_setenv -f image_name $image_name > /dev/null - fw_setenv -f fdt_name $fdt_name > /dev/null - fw_setenv -f kernel_addr $kernel_addr > /dev/null - fw_setenv -f fdt_addr $fdt_addr > /dev/null - - #make sure ubi number (0) and ubi volume name (ubi0) are set correctly in bootargs_root: - #For example, the below command creates an 3000MiB volume on UBI device 0: - #setenv bootargs_root root=ubi0:ubi0 rw ubi.mtd=2 rootfstype=ubifs - - fw_setenv -f mtdids 'nand0=armada-nand' > /dev/null - fw_setenv -f mtdparts 'mtdparts=armada-nand:10m(U-Boot)ro,20m@10m(ONIE),-(SONIC)' > /dev/null - fw_setenv -f ubi_sonic_boot_mount_ubi 'ubi part SONIC; ubifsmount ubi0' > /dev/null + DTB_HAS_ENV_BLK=$(grep uboot-env /proc/mtd | sed -e 's/:.*$//') + if [ -c "/dev/$DTB_HAS_ENV_BLK" ]; then + PROC_ENV_FILE=$(find /proc/device-tree/ -name env_size) + if [ -n "$PROC_ENV_FILE" ] + then + UBOOT_ENV_SIZ="0x$(hd $PROC_ENV_FILE | awk 'FNR==1 {print $2 $3 $4 $5}')" + UBOOT_ENV_ERASE_SIZ="0x$(grep uboot-env /proc/mtd | awk '{print $3}')" + if [[ -n "$UBOOT_ENV_SIZ" && -n "$UBOOT_ENV_ERASE_SIZ" ]] + then + # Env info from DTB + FW_ENV_DTB="/dev/$DTB_HAS_ENV_BLK 0x00000000 $UBOOT_ENV_SIZ $UBOOT_ENV_ERASE_SIZ" + fi + fi + fi + if [ -n "$FW_ENV_DTB" ] + then + echo $FW_ENV_DTB > /etc/fw_env.config + echo "Found uboot env offset in device tree" + UBOOT_ENV_CRC=$(fw_printenv 2>&1 | grep -c 'Warning: Bad CRC') || true + if [ "$UBOOT_ENV_CRC" -eq 0 ] + then + echo "Uboot env offset in device tree is valid" + UBOOT_FW_DEFAULT=0 + fdt_fname="/boot/armada-385-ET6448M_4G_Nand_r2019.dtb" + else + echo "Uboot env offset in device tree is NOT valid" + UBOOT_FW_DEFAULT=1 + fi + fi + if [ $UBOOT_FW_DEFAULT -eq 1 ] + then + echo $FW_ENV_DEFAULT > /etc/fw_env.config + echo "Using pre-configured uboot env" + fi + image_name=${image_dir}${kernel_fname} + initrd_name=${image_dir}${initrd_fname} + fdt_name=${image_dir}${fdt_fname} + + if [ "$install_env" = "onie" ]; then + FW_ARG="-f" + image_dir_old="" + image_name_old="" + initrd_name_old="" + fdt_name_old="" + sonic_version_2="None" + else + image_dir_old=$(fw_printenv -n image_dir || true) + image_name_old=$(fw_printenv -n image_name || true) + initrd_name_old=$(fw_printenv -n initrd_name || true) + fdt_name_old=$(fw_printenv -n fdt_name || true) + sonic_version_2=$(fw_printenv -n sonic_version_1 || true) + fi - fw_setenv -f ubi_sonic_boot_bootargs $BOOTARGS > /dev/null - fw_setenv -f ubi_sonic_boot_load $UBI_LOAD > /dev/null - fw_setenv -f ubi_sonic_boot $UBIBOOTCMD > /dev/null - fw_setenv -f bootcmd 'usb start; run ubi_sonic_boot' > /dev/null + # Set boot variables + fw_setenv ${FW_ARG} image_dir $image_dir > /dev/null + fw_setenv ${FW_ARG} image_name $image_name > /dev/null + fw_setenv ${FW_ARG} initrd_name $initrd_name > /dev/null + fw_setenv ${FW_ARG} fdt_name $fdt_name > /dev/null + fw_setenv ${FW_ARG} sonic_version_1 $demo_volume_revision_label > /dev/null + fw_setenv ${FW_ARG} image_dir_old $image_dir_old > /dev/null + fw_setenv ${FW_ARG} image_name_old $image_name_old > /dev/null + fw_setenv ${FW_ARG} initrd_name_old $initrd_name_old > /dev/null + fw_setenv ${FW_ARG} fdt_name_old $fdt_name_old > /dev/null + fw_setenv ${FW_ARG} sonic_version_2 $sonic_version_2 > /dev/null + BOOT1='echo " > Boot1: $sonic_version_1 - run sonic_image_1";echo;' + BOOT2='echo " > Boot2: $sonic_version_2 - run sonic_image_2";echo;' + BOOT3='echo " > Boot3: ONIE - run onie_nand_boot";echo;' + BORDER='echo "---------------------------------------------------";echo;' + fw_setenv ${FW_ARG} print_menu $BORDER $BOOT1 $BOOT2 $BOOT3 $BORDER > /dev/null + + fw_setenv ${FW_ARG} linuxargs "net.ifnames=0 loopfstype=squashfs loop=$image_dir/$FILESYSTEM_SQUASHFS varlog_size=$VAR_LOG" > /dev/null + fw_setenv ${FW_ARG} linuxargs_old "net.ifnames=0 loopfstype=squashfs loop=$image_dir_old/$FILESYSTEM_SQUASHFS varlog_size=$VAR_LOG" > /dev/null + + # Set boot configs + fw_setenv ${FW_ARG} kernel_addr $kernel_addr > /dev/null + fw_setenv ${FW_ARG} fdt_addr $fdt_addr > /dev/null + fw_setenv ${FW_ARG} initrd_addr $initrd_addr > /dev/null + fw_setenv ${FW_ARG} mtdids 'nand0=armada-nand' > /dev/null + if [ $UBOOT_FW_DEFAULT -eq 1 ] + then + fw_setenv ${FW_ARG} mtdparts 'mtdparts=armada-nand:10m(U-Boot)ro,20m@10m(ONIE),-(SONIC)' > /dev/null + else + fw_setenv ${FW_ARG} mtdparts 'mtdparts=armada-nand:4m(uboot)ro,5m@5m(uboot-env),20m@10m(ONIE),-(SONIC)' > /dev/null + fi + fw_setenv ${FW_ARG} ubi_sonic_boot_mount_ubi 'ubi part SONIC; ubifsmount ubi0' > /dev/null + fw_setenv ${FW_ARG} ubi_sonic_boot_bootargs $BOOTARGS > /dev/null + fw_setenv ${FW_ARG} ubi_sonic_boot_load $UBI_LOAD > /dev/null + fw_setenv ${FW_ARG} sonic_image_1 "$UBIBOOTCMD" > /dev/null + fw_setenv ${FW_ARG} ubi_sonic_boot_bootargs_old $BOOTARGS_OLD > /dev/null + fw_setenv ${FW_ARG} ubi_sonic_boot_load_old $UBI_LOAD_OLD > /dev/null + fw_setenv ${FW_ARG} sonic_image_2 "$UBIBOOTCMD_OLD" > /dev/null + fw_setenv ${FW_ARG} boot_next 'run sonic_image_1'> /dev/null + fw_setenv ${FW_ARG} bootcmd 'run print_menu; usb start; test -n "$boot_once" && run boot_once; run boot_next' > /dev/null } -install_uimage() { - - ubidetach /dev/ubi_ctrl -m $mtd_num 2>/dev/null || true +create_ubi_partition() { + ubidetach /dev/ubi_ctrl -d 0 2>/dev/null || true + trap_push "${onie_bin} ubidetach -d 0 /dev/ubi_ctrl || true" echo -en "Format mtd partition '$mtd_dev' " ubiformat $mtd_dev -y -q || { echo "Failed" @@ -90,54 +147,29 @@ install_uimage() { #creates UBI volumes on UBI devices ubimkvol /dev/$demo_dev -N $demo_dev -s 3900MiB +} + +create_partition() { + # Platform speicific partition + create_ubi_partition +} + +mount_partition() { - demo_mount=$(mktemp -d) || { + demo_mnt=$(mktemp -d) || { echo "Error: Unable to create file sstem mount point" exit 1 } - echo "Mounting $demo_dev on $demo_mount " - mount -t ubifs /dev/ubi0_0 $demo_mount || { + echo "Mounting $demo_dev on $demo_mnt " + trap_push "${onie_bin} umount /dev/ubi0_0|| true" + mount -t ubifs /dev/ubi0_0 $demo_mnt || { echo "Failed" } +} - echo "Extracting NOS " - - # Decompress the file for the file system directly to the partition - unzip -o $ONIE_INSTALLER_PAYLOAD -x "$FILESYSTEM_DOCKERFS" -d $demo_mount/ - cd $demo_mount - - if [ -f fs.cpio ]; then - cpio -id < fs.cpio - if [ $? -ne 0 ]; then - echo "cpio extraction Failed" - fi - rm fs.cpio - elif [ -f fs.squashfs ]; then - unsquashfs -f -d $demo_mount $FILESYSTEM_SQUASHFS - if [ $? -ne 0 ]; then - echo "unsquashfs extraction Failed" - fi - rm -f $FILESYSTEM_SQUASHFS - fi - - cd - - TAR_EXTRA_OPTION="--numeric-owner" - mkdir -p $demo_mount/var/lib/$DOCKERFS_DIR - unzip -op $ONIE_INSTALLER_PAYLOAD "$FILESYSTEM_DOCKERFS" | tar -xpz $TAR_EXTRA_OPTION -f - -C $demo_mount/var/lib/$DOCKERFS_DIR - +bootloader_menu_config() { # Update uboot Environment - prepare_uboot - - # Platform configuration - et6448m_machine_conf - - # Unmounting mount path - umount $demo_mount - - echo "Reboot board to boot from installed OS" + prepare_boot_menu } -hw_load() { - echo "mtdpart default && ubi part SONIC && ubifsmount 'demo_dev' && ubifsload '$kernel_addr' 'image_name'" -} diff --git a/platform/marvell-armhf/rules.mk b/platform/marvell-armhf/rules.mk index 809e46bd1738..fb46b261fa06 100644 --- a/platform/marvell-armhf/rules.mk +++ b/platform/marvell-armhf/rules.mk @@ -7,6 +7,7 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-mrvl.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/linux-kernel-armhf.mk +include $(PLATFORM_PATH)/platform-et6448m.mk ENABLE_SYSTEM_TELEMETRY = "" ENABLE_SYNCD_RPC = "" diff --git a/platform/marvell-armhf/sonic-platform-et6448m/.gitignore b/platform/marvell-armhf/sonic-platform-et6448m/.gitignore new file mode 100644 index 000000000000..7f287d538227 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-et6448m/.gitignore @@ -0,0 +1,50 @@ +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su + +# Kernel Module Compile Results +*.mod* +*.cmd +*.o.d +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# Debian packaging +*.debhelper.log +*.postinst.debhelper +*.postrm.debhelper +*.prerm.debhelper +*.substvars diff --git a/platform/marvell-armhf/sonic-platform-et6448m/debian/changelog b/platform/marvell-armhf/sonic-platform-et6448m/debian/changelog new file mode 100755 index 000000000000..98934823b4f5 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-et6448m/debian/changelog @@ -0,0 +1,5 @@ +sonic-platform-et6448m (0.1) unstable; urgency=low + + * Add support for ET6448M. + + -- Marvell Mon, 11 Nov 2019 09:35:58 +0800 diff --git a/platform/marvell-armhf/sonic-platform-et6448m/debian/compat b/platform/marvell-armhf/sonic-platform-et6448m/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-et6448m/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/marvell-armhf/sonic-platform-et6448m/debian/control b/platform/marvell-armhf/sonic-platform-et6448m/debian/control new file mode 100755 index 000000000000..52c9593a1ea5 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-et6448m/debian/control @@ -0,0 +1,15 @@ +Source: sonic-platform-et6448m +Section: unknown +Priority: optional +Maintainer: Marvell +Build-Depends: debhelper (>=9) +Standards-Version: 3.9.6 +Homepage: +#Vcs-Git: git://anonscm.debian.org/collab-maint/sonic-platform-et6448m.git +#Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/sonic-platform-et6448m.git + +Package: sonic-platform-et6448m +Architecture: armhf +Depends: ${misc:Depends} +Description: + diff --git a/platform/marvell-armhf/sonic-platform-et6448m/debian/install b/platform/marvell-armhf/sonic-platform-et6448m/debian/install new file mode 100644 index 000000000000..af8265fb38ce --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-et6448m/debian/install @@ -0,0 +1 @@ +et6448m_plt_setup.sh usr/sbin diff --git a/platform/marvell-armhf/sonic-platform-et6448m/debian/postinst b/platform/marvell-armhf/sonic-platform-et6448m/debian/postinst new file mode 100644 index 000000000000..a3a727c7222c --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-et6448m/debian/postinst @@ -0,0 +1,40 @@ +#!/bin/sh +# postinst script for sonic-platform-et6448m +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-remove' +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see https://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + sh /usr/sbin/et6448m_plt_setup.sh + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/platform/marvell-armhf/sonic-platform-et6448m/debian/rules b/platform/marvell-armhf/sonic-platform-et6448m/debian/rules new file mode 100755 index 000000000000..2f54c4710f17 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-et6448m/debian/rules @@ -0,0 +1,25 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + + +# see FEATURE AREAS in dpkg-buildflags(1) +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# see ENVIRONMENT in dpkg-buildflags(1) +# package maintainers to append CFLAGS +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# package maintainers to append LDFLAGS +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + + +%: + dh $@ + + +# dh_make generated override targets +# This is example for Cmake (See https://bugs.debian.org/641051 ) +#override_dh_auto_configure: +# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) + diff --git a/platform/marvell-armhf/sonic-platform-et6448m/et6448m_plt_setup.sh b/platform/marvell-armhf/sonic-platform-et6448m/et6448m_plt_setup.sh new file mode 100755 index 000000000000..83a0add5f005 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-et6448m/et6448m_plt_setup.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +fw_uboot_env_cfg() +{ + echo "Setting up U-Boot environment..." + FW_ENV_DEFAULT='/dev/mtd0 0x00500000 0x80000 0x100000 8' + UBOOT_FW_DFAULT=1 + + DTB_HAS_ENV_BLK=$(grep uboot-env /proc/mtd | sed -e 's/:.*$//') + if [ -c "/dev/$DTB_HAS_ENV_BLK" ]; then + PROC_ENV_FILE=$(find /proc/device-tree/ -name env_size) + if [ -n "$PROC_ENV_FILE" ] + then + UBOOT_ENV_SIZ="0x$(hd $PROC_ENV_FILE | awk 'FNR==1 {print $2 $3 $4 $5}')" + UBOOT_ENV_ERASE_SIZ="0x$(grep uboot-env /proc/mtd | awk '{print $3}')" + if [[ -n "$UBOOT_ENV_SIZ" && -n "$UBOOT_ENV_ERASE_SIZ" ]] + then + # Env info from DTB + FW_ENV_DTB="/dev/$DTB_HAS_ENV_BLK 0x00000000 $UBOOT_ENV_SIZ $UBOOT_ENV_ERASE_SIZ" + fi + fi + fi + if [ -n "$FW_ENV_DTB" ] + then + echo $FW_ENV_DTB > /etc/fw_env.config + echo "Found uboot env offset in device tree" + UBOOT_ENV_CRC=$(fw_printenv -c /etc/fw_env.config 2>&1 | grep -c 'Warning: Bad CRC') + if [ $UBOOT_ENV_CRC -eq 0 ] + then + echo "Uboot env offset in device tree is valid" + UBOOT_FW_DFAULT=0 + else + echo "Uboot env offset in device tree is NOT valid" + UBOOT_FW_DFAULT=1 + fi + fi + if [ $UBOOT_FW_DFAULT -eq 1 ] + then + echo $FW_ENV_DEFAULT > /etc/fw_env.config + echo "Using pre-configured uboot env" + fi +} + +et6448m_profile() +{ + MAC_ADDR=$(fw_printenv -n ethaddr) + sed -i "s/switchMacAddress=.*/switchMacAddress=$MAC_ADDR/g" /usr/share/sonic/device/armhf-marvell_et6448m_52x-r0/et6448m/profile.ini + echo "ET6448M: Updating switch mac address ${MAC_ADDR}" +} + +main() +{ + fw_uboot_env_cfg + et6448m_profile +} + +main $@ From 522916397de22a80d511bd4319fad948b8308646 Mon Sep 17 00:00:00 2001 From: Pradchaya Phucharoen Date: Thu, 16 Jan 2020 10:42:09 +0800 Subject: [PATCH 0292/1427] [Celestica/Seastone2] Add support Seastone2 device and platform (#3761) * [device/celestica] Add seastone2 device specific plugins and SKU * [platform/broadcom] Add Celestica seastone2 platform module * update minigraph for Seastone_2 and remove 10KR port configuration * [device/celestica] hwsku:Seastone2 update port configuration * [plugins/psuutil] fix psutuil cannot run in pmon docker * [plugins/sfputil] raise error in get_transceiver_change_event * [device/celestica] Seastone2 add config to skip ledd in pmon Co-authored-by: tiantianlv <38775940+tiantianlv@users.noreply.github.com> --- .../Seastone_2/port_config.ini | 33 + .../Seastone_2/sai.profile | 1 + .../td3-seastone_2-32x100G.config.bcm | 597 +++++ .../x86_64-cel_seastone_2-r0/custom.bin | Bin 0 -> 264 bytes .../x86_64-cel_seastone_2-r0/default_sku | 1 + .../x86_64-cel_seastone_2-r0/installer.conf | 3 + .../led_proc_init.soc | 9 + .../x86_64-cel_seastone_2-r0/linkscan_fw.bin | Bin 0 -> 4716 bytes .../plugins/eeprom.py | 23 + .../plugins/psuutil.py | 88 + .../plugins/sfputil.py | 182 ++ .../pmon_daemon_control.json | 6 + platform/broadcom/one-image.mk | 1 + platform/broadcom/platform-modules-cel.mk | 6 + .../sonic-platform-modules-cel/README.md | 2 +- .../sonic-platform-modules-cel/debian/control | 7 +- .../debian/platform-modules-seastone2.init | 52 + .../debian/platform-modules-seastone2.install | 2 + .../platform-modules-seastone2.postinst | 3 + .../sonic-platform-modules-cel/debian/rules | 2 +- .../seastone2/cfg/seastone2-modules.conf | 16 + .../seastone2/modules/Makefile | 2 + .../seastone2/modules/baseboard_cpld.c | 378 +++ .../seastone2/modules/mc24lc64t.c | 174 ++ .../seastone2/modules/switchboard_fpga.c | 2089 +++++++++++++++++ .../platform-modules-seastone2.service | 14 + src/sonic-device-data/tests/permitted_list | 7 + 27 files changed, 3695 insertions(+), 3 deletions(-) create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/port_config.ini create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/custom.bin create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/default_sku create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/installer.conf create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/led_proc_init.soc create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/linkscan_fw.bin create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/plugins/eeprom.py create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/plugins/psuutil.py create mode 100755 device/celestica/x86_64-cel_seastone_2-r0/plugins/sfputil.py create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.init create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/cfg/seastone2-modules.conf create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/modules/baseboard_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/modules/mc24lc64t.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/systemd/platform-modules-seastone2.service diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/port_config.ini b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/port_config.ini new file mode 100644 index 000000000000..ed6bcff2331c --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias fec index speed +Ethernet0 1,2,3,4 QSFP1 rs 1 100000 +Ethernet4 5,6,7,8 QSFP2 rs 2 100000 +Ethernet8 9,10,11,12 QSFP3 rs 3 100000 +Ethernet12 13,14,15,16 QSFP4 rs 4 100000 +Ethernet16 17,18,19,20 QSFP5 rs 5 100000 +Ethernet20 21,22,23,24 QSFP6 rs 6 100000 +Ethernet24 25,26,27,28 QSFP7 rs 7 100000 +Ethernet28 29,30,31,32 QSFP8 rs 8 100000 +Ethernet32 33,34,35,36 QSFP9 rs 9 100000 +Ethernet36 37,38,39,40 QSFP10 rs 10 100000 +Ethernet40 41,42,43,44 QSFP11 rs 11 100000 +Ethernet44 45,46,47,48 QSFP12 rs 12 100000 +Ethernet48 49,50,51,52 QSFP13 rs 13 100000 +Ethernet52 53,54,55,56 QSFP14 rs 14 100000 +Ethernet56 57,58,59,60 QSFP15 rs 15 100000 +Ethernet60 61,62,63,64 QSFP16 rs 16 100000 +Ethernet64 65,66,67,68 QSFP17 rs 17 100000 +Ethernet68 69,70,71,72 QSFP18 rs 18 100000 +Ethernet72 73,74,75,76 QSFP19 rs 19 100000 +Ethernet76 77,78,79,80 QSFP20 rs 20 100000 +Ethernet80 81,82,83,84 QSFP21 rs 21 100000 +Ethernet84 85,86,87,88 QSFP22 rs 22 100000 +Ethernet88 89,90,91,92 QSFP23 rs 23 100000 +Ethernet92 93,94,95,96 QSFP24 rs 24 100000 +Ethernet96 97,98,99,100 QSFP25 rs 25 100000 +Ethernet100 101,102,103,104 QSFP26 rs 26 100000 +Ethernet104 105,106,107,108 QSFP27 rs 27 100000 +Ethernet108 109,110,111,112 QSFP28 rs 28 100000 +Ethernet112 113,114,115,116 QSFP29 rs 29 100000 +Ethernet116 117,118,119,120 QSFP30 rs 30 100000 +Ethernet120 121,122,123,124 QSFP31 rs 31 100000 +Ethernet124 125,126,127,128 QSFP32 rs 32 100000 \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile new file mode 100644 index 000000000000..ea150bf237c3 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-seastone_2-32x100G.config.bcm diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm new file mode 100644 index 000000000000..2c23d0da2f22 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm @@ -0,0 +1,597 @@ +help_cli_enable=1 +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=0x1 +l2_mem_entries=32768 +l2xmsg_mode=1 +l3_max_ecmp_mode=1 +l3_mem_entries=16384 +lpm_scaling_enable=1 +max_vp_lags=0 +mem_cache_enable=0 +memlist_enable=1 +miim_intr_enable=0 +module_64ports=1 +oversubscribe_mode=1 +parity_enable=0 +serdes_lane_config_dfe=on +#serdes_fec_enable=1 +serdes_if_type_ce=14 +pbmp_gport_stack.0=0x0000000000000000000000000000000000000000000000000000000000000000 +pbmp_xport_xe=0x88888888888888882222222222222222 + +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 + +portmap_1.0=1:100 +portmap_5.0=5:100 +portmap_9.0=9:100 +portmap_13.0=13:100 +portmap_17.0=17:100 +portmap_21.0=21:100 +portmap_25.0=25:100 +portmap_29.0=29:100 +portmap_33.0=33:100 +portmap_37.0=37:100 +portmap_41.0=41:100 +portmap_45.0=45:100 +portmap_49.0=49:100 +portmap_53.0=53:100 +portmap_57.0=57:100 +portmap_61.0=61:100 +portmap_67.0=65:100 +portmap_71.0=69:100 +portmap_75.0=73:100 +portmap_79.0=77:100 +portmap_83.0=81:100 +portmap_87.0=85:100 +portmap_91.0=89:100 +portmap_95.0=93:100 +portmap_99.0=97:100 +portmap_103.0=101:100 +portmap_107.0=105:100 +portmap_111.0=109:100 +portmap_115.0=113:100 +portmap_119.0=117:100 +portmap_123.0=121:100 +portmap_127.0=125:100 +#portmap_66.0=129:10:m +#portmap_130.0=128:10:m + +#wc0 lane swap +phy_chain_tx_lane_map_physical{1.0}=0x0132 +phy_chain_rx_lane_map_physical{1.0}=0x3210 + +#wc1 lane swap +phy_chain_tx_lane_map_physical{5.0}=0x2301 +phy_chain_rx_lane_map_physical{5.0}=0x2031 + +#wc2 lane swap +phy_chain_tx_lane_map_physical{9.0}=0x0132 +phy_chain_rx_lane_map_physical{9.0}=0x3210 + +#wc3 lane swap +phy_chain_tx_lane_map_physical{13.0}=0x3201 +phy_chain_rx_lane_map_physical{13.0}=0x2031 + +#wc4 lane swap +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x3210 + +#wc5 lane swap +phy_chain_tx_lane_map_physical{21.0}=0x2301 +phy_chain_rx_lane_map_physical{21.0}=0x2031 + +#wc6 lane swap +phy_chain_tx_lane_map_physical{25.0}=0x0123 +phy_chain_rx_lane_map_physical{25.0}=0x3210 + +#wc7 lane swap +phy_chain_tx_lane_map_physical{29.0}=0x3201 +phy_chain_rx_lane_map_physical{29.0}=0x2031 + +#wc8 lane swap +phy_chain_tx_lane_map_physical{33.0}=0x0213 +phy_chain_rx_lane_map_physical{33.0}=0x1302 + +#wc9 lane swap +phy_chain_tx_lane_map_physical{37.0}=0x1302 +phy_chain_rx_lane_map_physical{37.0}=0x2031 + +#wc10 lane swap +phy_chain_tx_lane_map_physical{41.0}=0x0231 +phy_chain_rx_lane_map_physical{41.0}=0x3120 + +#wc11 lane swap +phy_chain_tx_lane_map_physical{45.0}=0x1302 +phy_chain_rx_lane_map_physical{45.0}=0x2031 + +#wc12 lane swap +phy_chain_tx_lane_map_physical{49.0}=0x2103 +phy_chain_rx_lane_map_physical{49.0}=0x3120 + +#wc13 lane swap +phy_chain_tx_lane_map_physical{53.0}=0x2301 +phy_chain_rx_lane_map_physical{53.0}=0x2031 + +#wc14 lane swap +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x2301 + +#wc15 lane swap +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x1032 + +#wc16 lane swap +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x1023 + +#wc17 lane swap +phy_chain_tx_lane_map_physical{69.0}=0x0123 +phy_chain_rx_lane_map_physical{69.0}=0x1302 + +#wc18 lane swap +phy_chain_tx_lane_map_physical{73.0}=0x2301 +phy_chain_rx_lane_map_physical{73.0}=0x1032 + +#wc19 lane swap +phy_chain_tx_lane_map_physical{77.0}=0x2013 +phy_chain_rx_lane_map_physical{77.0}=0x3120 + +#wc20 lane swap +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_rx_lane_map_physical{81.0}=0x2031 + +#wc21 lane swap +phy_chain_tx_lane_map_physical{85.0}=0x0123 +phy_chain_rx_lane_map_physical{85.0}=0x2130 + +#wc22 lane swap +phy_chain_tx_lane_map_physical{89.0}=0x2301 +phy_chain_rx_lane_map_physical{89.0}=0x2031 + +#wc23 lane swap +phy_chain_tx_lane_map_physical{93.0}=0x0312 +phy_chain_rx_lane_map_physical{93.0}=0x2310 + +#wc24 lane swap +phy_chain_tx_lane_map_physical{97.0}=0x2301 +phy_chain_rx_lane_map_physical{97.0}=0x1032 + +#wc25 lane swap +phy_chain_tx_lane_map_physical{101.0}=0x0123 +phy_chain_rx_lane_map_physical{101.0}=0x3210 + +#wc26 lane swap +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_rx_lane_map_physical{105.0}=0x1032 + +#wc27 lane swap +phy_chain_tx_lane_map_physical{109.0}=0x0123 +phy_chain_rx_lane_map_physical{109.0}=0x3210 + +#wc28 lane swap +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{113.0}=0x2031 + +#wc29 lane swap +phy_chain_tx_lane_map_physical{117.0}=0x0123 +phy_chain_rx_lane_map_physical{117.0}=0x3210 + +#wc30 lane swap +phy_chain_tx_lane_map_physical{121.0}=0x2301 +phy_chain_rx_lane_map_physical{121.0}=0x1032 + +#wc31 lane swap +phy_chain_tx_lane_map_physical{125.0}=0x0123 +phy_chain_rx_lane_map_physical{125.0}=0x3210 + +#MC lane swap +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_lane_map_physical{129.0}=0x3210 + + +#wc0 P/N flip +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 + +#wc1 P/N flip +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 + +#wc2 P/N flip +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 + +#wc3 P/N flip +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 + +#wc4 P/N flip +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 + +#wc5 P/N flip +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 + +#wc6 P/N flip +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 + +#wc7 P/N flip +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 + +#wc8 P/N flip +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 + +#wc9 P/N flip +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 + +#wc10 P/N flip +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 + +#wc11 P/N flip +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 + +#wc12 P/N flip +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 + +#wc13 P/N flip +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 + +#wc14 P/N flip +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 + +#wc15 P/N flip +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 + +#wc16 P/N flip +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 + +#wc17 P/N flip +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 + +#wc18 P/N flip +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 + +#wc19 P/N flip +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 + +#wc20 P/N flip +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x0 + +#wc21 P/N flip +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 + +#wc22 P/N flip +phy_chain_tx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 + +#wc23 P/N flip +phy_chain_tx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 + +#wc24 P/N flip +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x0 + +#wc25 P/N flip +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 + +#wc26 P/N flip +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 + +#wc27 P/N flip +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_rx_polarity_flip_physical{112.0}=0x0 + +#wc28 P/N flip +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 + +#wc29 P/N flip +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 + +#wc30 P/N flip +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 + +#wc31 P/N flip +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 + +#MC P/N flip +phy_chain_tx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_tx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x0 +phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_tx_polarity_flip_physical{132.0}=0x0 +phy_chain_rx_polarity_flip_physical{132.0}=0x0 + +dport_map_port_1=1 +dport_map_port_5=2 +dport_map_port_9=3 +dport_map_port_13=4 +dport_map_port_17=5 +dport_map_port_21=6 +dport_map_port_25=7 +dport_map_port_29=8 +dport_map_port_33=9 +dport_map_port_37=10 +dport_map_port_41=11 +dport_map_port_45=12 +dport_map_port_49=13 +dport_map_port_53=14 +dport_map_port_57=15 +dport_map_port_61=16 +dport_map_port_67=17 +dport_map_port_71=18 +dport_map_port_75=19 +dport_map_port_79=20 +dport_map_port_83=21 +dport_map_port_87=22 +dport_map_port_91=23 +dport_map_port_95=24 +dport_map_port_99=25 +dport_map_port_103=26 +dport_map_port_107=27 +dport_map_port_111=28 +dport_map_port_115=29 +dport_map_port_119=30 +dport_map_port_123=31 +dport_map_port_127=32 +#dport_map_port_66=33 +#dport_map_port_130=34 + +# configuration for 100G optical module +serdes_preemphasis_1=0x164608 +serdes_preemphasis_5=0x164608 +serdes_preemphasis_9=0x164608 +serdes_preemphasis_13=0x134908 +serdes_preemphasis_17=0x134908 +serdes_preemphasis_21=0x134908 +serdes_preemphasis_25=0x124a08 +serdes_preemphasis_29=0x124a08 +serdes_preemphasis_33=0x114b08 +serdes_preemphasis_37=0x114b08 +serdes_preemphasis_41=0x0f4d08 +serdes_preemphasis_45=0x0f4d08 +serdes_preemphasis_49=0x0d4f08 +serdes_preemphasis_53=0x0d4f08 +serdes_preemphasis_57=0x0d4f08 +serdes_preemphasis_61=0x0d4f08 +serdes_preemphasis_67=0x0d4f08 +serdes_preemphasis_71=0x0d4f08 +serdes_preemphasis_75=0x0d4f08 +serdes_preemphasis_79=0x0d4f08 +serdes_preemphasis_83=0x0d4f08 +serdes_preemphasis_87=0x0f4d08 +serdes_preemphasis_91=0x0f4d08 +serdes_preemphasis_95=0x0f4d08 +serdes_preemphasis_99=0x114b08 +serdes_preemphasis_103=0x114b08 +serdes_preemphasis_107=0x114b08 +serdes_preemphasis_111=0x124a08 +serdes_preemphasis_115=0x134908 +serdes_preemphasis_119=0x134908 +serdes_preemphasis_123=0x134908 +serdes_preemphasis_127=0x164608 + +reglist_enable=1 +scache_filename=/tmp/scache +schan_intr_enable=0 +stable_size=0x5500000 +tdma_timeout_usec=3000000 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/custom.bin b/device/celestica/x86_64-cel_seastone_2-r0/custom.bin new file mode 100644 index 0000000000000000000000000000000000000000..a9597df309ab08e818a2cf65d3a9950e01ab7891 GIT binary patch literal 264 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 + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + grep_key = "PSUL_Status" if index == 1 else "PSUR_Status" + grep_string = self.run_command(self.ipmi_sensor + ' | grep '+ grep_key) + status_byte = self.find_value(grep_string) + + if status_byte is None: + return False + + failure_detected = (int(status_byte, 16) >> 1) & 1 + input_lost = (int(status_byte, 16) >> 3) & 1 + if failure_detected or input_lost: + return False + else: + return True + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + grep_key = "PSUL_Status" if index == 1 else "PSUR_Status" + grep_string = self.run_command(self.ipmi_sensor + ' | grep '+ grep_key) + status_byte = self.find_value(grep_string) + + if status_byte is None: + return False + + presence = ( int(status_byte, 16) >> 0 ) & 1 + if presence: + return True + else: + return False diff --git a/device/celestica/x86_64-cel_seastone_2-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_seastone_2-r0/plugins/sfputil.py new file mode 100755 index 000000000000..db3ca9976e32 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/plugins/sfputil.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 33 + QSFP_PORT_START = 1 + QSFP_PORT_END = 32 + + EEPROM_OFFSET = 1 + PORT_INFO_PATH = '/sys/class/seastone2_fpga' + + _port_name = "" + _port_to_eeprom_mapping = {} + _port_to_i2cbus_mapping = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(self.QSFP_PORT_START, self.QSFP_PORT_END + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + @property + def port_to_i2cbus_mapping(self): + return self._port_to_i2cbus_mapping + + def get_port_name(self, port_num): + if port_num in self.qsfp_ports: + self._port_name = "QSFP" + str(port_num - self.QSFP_PORT_START + 1) + else: + self._port_name = "SFP" + str(port_num) + return self._port_name + + # def get_eeprom_dom_raw(self, port_num): + # if port_num in self.qsfp_ports: + # # QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw + # return None + # else: + # # Read dom eeprom at addr 0x51 + # return self._read_eeprom_devid(port_num, self.DOM_EEPROM_ADDR, 256) + + def __init__(self): + # Override port_to_eeprom_mapping for class initialization + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' + + for x in range(self.PORT_START, self.PORT_END+1): + self.port_to_i2cbus_mapping[x] = (x + self.EEPROM_OFFSET) + self.port_to_eeprom_mapping[x] = eeprom_path.format( + x + self.EEPROM_OFFSET) + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + + # Check for invalid port_num + if port_num not in range(self.port_start, self.port_end + 1): + return False + + # Get path for access port presence status + port_name = self.get_port_name(port_num) + sysfs_filename = "qsfp_modprs" if port_num in self.qsfp_ports else "sfp_modabs" + reg_path = "/".join([self.PORT_INFO_PATH, port_name, sysfs_filename]) + + # Read status + try: + reg_file = open(reg_path) + content = reg_file.readline().rstrip() + reg_value = int(content) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Module present is active low + if reg_value == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid QSFP port_num + if port_num not in self.qsfp_ports: + return False + + try: + port_name = self.get_port_name(port_num) + reg_file = open( + "/".join([self.PORT_INFO_PATH, port_name, "qsfp_lpmode"]), "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Read status + content = reg_file.readline().rstrip() + reg_value = int(content, 16) + # ModPrsL is active low + if reg_value == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid QSFP port_num + if port_num not in self.qsfp_ports: + return False + + try: + port_name = self.get_port_name(port_num) + reg_file = open( + "/".join([self.PORT_INFO_PATH, port_name, "qsfp_lpmode"]), "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = hex(lpmode) + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + def reset(self, port_num): + # Check for invalid QSFP port_num + if port_num not in self.qsfp_ports: + return False + + try: + port_name = self.get_port_name(port_num) + reg_file = open( + "/".join([self.PORT_INFO_PATH, port_name, "qsfp_reset"]), "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(0)) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + reg_file = open( + "/".join([self.PORT_INFO_PATH, port_name, "qsfp_reset"]), "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + reg_file.write(hex(1)) + reg_file.close() + + return True + + def get_transceiver_change_event(self, timeout=0): + """ + TBD: When the feature request. + """ + raise NotImplementedError + diff --git a/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..294259681a11 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json @@ -0,0 +1,6 @@ +{ + "skip_ledd": true, + "skip_xcvrd": false, + "skip_psud": false, + "skip_syseepromd": false +} \ No newline at end of file diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 7436fef0ef1b..b833f9ee2bc3 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -41,6 +41,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(INVENTEC_D6356_PLATFORM_MODULE) \ $(CEL_DX010_PLATFORM_MODULE) \ $(CEL_HALIBURTON_PLATFORM_MODULE) \ + $(CEL_SEASTONE2_PLATFORM_MODULE) \ $(DELTA_AG9032V1_PLATFORM_MODULE) \ $(DELTA_AG9064_PLATFORM_MODULE) \ $(DELTA_AG5648_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index b7371e3282de..9fe4eb7b6932 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -2,10 +2,12 @@ CEL_DX010_PLATFORM_MODULE_VERSION = 0.9 CEL_HALIBURTON_PLATFORM_MODULE_VERSION = 0.9 +CEL_SEASTONE2_PLATFORM_MODULE_VERSION = 0.9 CEL_SILVERSTONE_PLATFORM_MODULE_VERSION = 0.9 export CEL_DX010_PLATFORM_MODULE_VERSION export CEL_HALIBURTON_PLATFORM_MODULE_VERSION +export CEL_SEASTONE2_PLATFORM_MODULE_VERSION export CEL_SILVERSTONE_PLATFORM_MODULE_VERSION CEL_DX010_PLATFORM_MODULE = platform-modules-dx010_$(CEL_DX010_PLATFORM_MODULE_VERSION)_amd64.deb @@ -18,6 +20,10 @@ CEL_HALIBURTON_PLATFORM_MODULE = platform-modules-haliburton_$(CEL_HALIBURTON_PL $(CEL_HALIBURTON_PLATFORM_MODULE)_PLATFORM = x86_64-cel_e1031-r0 $(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_HALIBURTON_PLATFORM_MODULE))) +CEL_SEASTONE2_PLATFORM_MODULE = platform-modules-seastone2_$(CEL_SEASTONE2_PLATFORM_MODULE_VERSION)_amd64.deb +$(CEL_SEASTONE2_PLATFORM_MODULE)_PLATFORM = x86_64-cel_seastone_2-r0 +$(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_SEASTONE2_PLATFORM_MODULE))) + CEL_SILVERSTONE_PLATFORM_MODULE = platform-modules-silverstone_$(CEL_SILVERSTONE_PLATFORM_MODULE_VERSION)_amd64.deb $(CEL_SILVERSTONE_PLATFORM_MODULE)_PLATFORM = x86_64-cel_silverstone-r0 $(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_SILVERSTONE_PLATFORM_MODULE))) diff --git a/platform/broadcom/sonic-platform-modules-cel/README.md b/platform/broadcom/sonic-platform-modules-cel/README.md index 26e45c685e44..9881d6ecb1d0 100644 --- a/platform/broadcom/sonic-platform-modules-cel/README.md +++ b/platform/broadcom/sonic-platform-modules-cel/README.md @@ -1 +1 @@ -platform drivers for Celestica DX010 and Haliburton for the SONiC project +platform drivers of Celestica network switchs for the SONiC project diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 2e9b578872fa..ea39a49e7e12 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -1,7 +1,7 @@ Source: sonic-cel-platform-modules Section: main Priority: extra -Maintainer: Abhisit Sangjan +Maintainer: Wirut Getbamrung Build-Depends: debhelper (>= 8.0.0), bzip2 Standards-Version: 3.9.3 @@ -16,6 +16,11 @@ Architecture: amd64 Depends: linux-image-4.9.0-9-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp +Package: platform-modules-seastone2 +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel modules for platform devices such as led, sfp + Package: platform-modules-silverstone Architecture: amd64 Depends: linux-image-4.9.0-9-2-amd64 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.init new file mode 100644 index 000000000000..977cdac06000 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.init @@ -0,0 +1,52 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: $portmap +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup seastone2 board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + # Add driver to support HW + modprobe i2c-dev + modprobe ipmi_devintf + modprobe ipmi_si + modprobe baseboard_cpld + modprobe switchboard_fpga + modprobe mc24lc64t + + # Add driver to support TLV - EEPROM + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + if [[ $devname == 'SMBus iSMT adapter at '* ]]; then + echo 24lc64t 0x56 > /sys/bus/i2c/devices/i2c-${devnum}/new_device + break + fi + done + sleep 1 + echo "done." + ;; + +stop) + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-seastone2.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install new file mode 100644 index 000000000000..e17b5e9cae83 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install @@ -0,0 +1,2 @@ +seastone2/cfg/seastone2-modules.conf etc/modules-load.d +seastone2/systemd/platform-modules-seastone2.service lib/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst new file mode 100644 index 000000000000..9a8e57cb8e9c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst @@ -0,0 +1,3 @@ +depmod -a +systemctl enable platform-modules-seastone2.service +systemctl start platform-modules-seastone2.service \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/rules b/platform/broadcom/sonic-platform-modules-cel/debian/rules index dd5452ccaa11..0ed48f9feaea 100755 --- a/platform/broadcom/sonic-platform-modules-cel/debian/rules +++ b/platform/broadcom/sonic-platform-modules-cel/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= dx010 haliburton silverstone +MODULE_DIRS:= dx010 haliburton silverstone seastone2 %: dh $@ diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/cfg/seastone2-modules.conf b/platform/broadcom/sonic-platform-modules-cel/seastone2/cfg/seastone2-modules.conf new file mode 100644 index 000000000000..795e6af74305 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/cfg/seastone2-modules.conf @@ -0,0 +1,16 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x +ipmi_devintf +ipmi_si diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/Makefile new file mode 100644 index 000000000000..3b59a78682a0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/Makefile @@ -0,0 +1,2 @@ +KBUILD_CFLAGS+=-DSEASTONE2 +obj-m := mc24lc64t.o baseboard_cpld.o switchboard_fpga.o \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/baseboard_cpld.c b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/baseboard_cpld.c new file mode 100644 index 000000000000..07ab42c21686 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/baseboard_cpld.c @@ -0,0 +1,378 @@ +/* + * baseboard_cpld.c - driver for Seastone2 Base Board CPLD + * This driver implement sysfs for CPLD register access using LPC bus. + * Copyright (C) 2019 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "baseboard" +/** + * CPLD register address for read and write. + */ +#define VERSION_ADDR 0xA100 +#define SCRATCH_ADDR 0xA101 +#define SYS_LED_ADDR 0xA162 + +#define CPLD_REGISTER_SIZE 0x77 + +struct baseboard_cpld_data { + struct mutex cpld_lock; + uint16_t read_addr; +}; + +struct baseboard_cpld_data *cpld_data; + +/** + * Read the value from scratch register as hex string. + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +static ssize_t scratch_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SCRATCH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf,"0x%2.2x\n", data); +} + +/** + * Set scratch register with specific hex string. + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +static ssize_t scratch_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned long data; + char *last; + + mutex_lock(&cpld_data->cpld_lock); + data = (uint16_t)strtoul(buf,&last,16); + if(data == 0 && buf == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + outb(data, SCRATCH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(scratch); + + +/* CPLD version attributes */ +static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len = -EIO; + // CPLD register is one byte + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n",inb(VERSION_ADDR)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RO(version); + + +static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + // CPLD register is one byte + uint16_t addr; + char *last; + + addr = (uint16_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + cpld_data->read_addr = addr; + return count; +} + +static ssize_t getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len = -EIO; + // CPLD register is one byte + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n",inb(cpld_data->read_addr)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RW(getreg); + +static ssize_t setreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + // CPLD register is one byte + uint16_t addr; + uint8_t value; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + + strcpy(clone, buf); + + mutex_lock(&cpld_data->cpld_lock); + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + addr = (uint16_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + value = (uint8_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + outb(value,addr); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_WO(setreg); + +/** + * Show system led status - on/off/1hz/4hz + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +static ssize_t sys_led_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + data = data & 0x3; + return sprintf(buf, "%s\n", + data == 0x03 ? "off" : data == 0x02 ? "4hz" : data ==0x01 ? "1hz": "on"); +} + +/** + * Set the status of system led - on/off/1hz/4hz + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +static ssize_t sys_led_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status,data; + if(sysfs_streq(buf, "off")){ + led_status = 0x03; + }else if(sysfs_streq(buf, "4hz")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "1hz")){ + led_status = 0x01; + }else if(sysfs_streq(buf, "on")){ + led_status = 0x00; + }else{ + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + data = data & ~(0x3); + data = data | led_status; + outb(data, SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(sys_led); + +/** + * Show system led color - both/green/yellow/none + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +static ssize_t sys_led_color_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + data = (data >> 4) & 0x3; + return sprintf(buf, "%s\n", + data == 0x03 ? "off" : data == 0x02 ? "yellow" : data ==0x01 ? "green": "both"); +} + +/** + * Set the color of system led - both/green/yellow/none + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +static ssize_t sys_led_color_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status,data; + if(sysfs_streq(buf, "off")){ + led_status = 0x03; + }else if(sysfs_streq(buf, "yellow")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "green")){ + led_status = 0x01; + }else if(sysfs_streq(buf, "both")){ + led_status = 0x00; + }else{ + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + data = data & ~( 0x3 << 4); + data = data | (led_status << 4); + outb(data, SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(sys_led_color); + +static struct attribute *baseboard_cpld_attrs[] = { + &dev_attr_version.attr, + &dev_attr_scratch.attr, + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, + &dev_attr_sys_led.attr, + &dev_attr_sys_led_color.attr, + NULL, +}; + +static struct attribute_group baseboard_cpld_attrs_grp = { + .attrs = baseboard_cpld_attrs, +}; + +static struct resource baseboard_cpld_resources[] = { + { + .start = 0xA100, + .end = 0xA1FF, + .flags = IORESOURCE_IO, + }, +}; + +static void baseboard_cpld_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device baseboard_cpld_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(baseboard_cpld_resources), + .resource = baseboard_cpld_resources, + .dev = { + .release = baseboard_cpld_dev_release, + } +}; + +static int baseboard_cpld_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret =0; + + cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct baseboard_cpld_data), + GFP_KERNEL); + if (!cpld_data) + return -ENOMEM; + + mutex_init(&cpld_data->cpld_lock); + + cpld_data->read_addr = VERSION_ADDR; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (unlikely(!res)) { + printk(KERN_ERR "Specified Resource Not Available...\n"); + return -1; + } + + ret = sysfs_create_group(&pdev->dev.kobj, &baseboard_cpld_attrs_grp); + if (ret) { + printk(KERN_ERR "Cannot create sysfs for baseboard CPLD\n"); + } + return 0; +} + +static int baseboard_cpld_drv_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &baseboard_cpld_attrs_grp); + return 0; +} + +static struct platform_driver baseboard_cpld_drv = { + .probe = baseboard_cpld_drv_probe, + .remove = __exit_p(baseboard_cpld_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +int baseboard_cpld_init(void) +{ + // Register platform device and platform driver + platform_device_register(&baseboard_cpld_dev); + platform_driver_register(&baseboard_cpld_drv); + return 0; +} + +void baseboard_cpld_exit(void) +{ + // Unregister platform device and platform driver + platform_driver_unregister(&baseboard_cpld_drv); + platform_device_unregister(&baseboard_cpld_dev); +} + +module_init(baseboard_cpld_init); +module_exit(baseboard_cpld_exit); + +MODULE_AUTHOR("Pradchaya Phucharoen "); +MODULE_DESCRIPTION("Celestica Seastone2 Baseboard CPLD Driver"); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/mc24lc64t.c new file mode 100644 index 000000000000..fc15bb74b68d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/mc24lc64t.c @@ -0,0 +1,174 @@ +/* + * mc24lc64t.c - driver for Microchip 24LC64T + * + * Copyright (C) 2017 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define EEPROM_SIZE 8192 //mc24lt64t eeprom size in bytes. + +struct mc24lc64t_data { + struct mutex update_lock; +}; + +static ssize_t mc24lc64t_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, read_time, i = 0; + int status; + + mutex_lock(&drvdata->update_lock); + + if (i2c_smbus_write_byte_data(client, off>>8, off)) + { + status = -EIO; + goto exit; + } + + msleep(1); + +begin: + + if (i < count) + { + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + do { + read_time = jiffies; + + status = i2c_smbus_read_byte(client); + if (status >= 0) + { + buf[i++] = status; + goto begin; + } + } while (time_before(read_time, timeout)); + + status = -ETIMEDOUT; + goto exit; + } + + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + + return status; +} + + +static ssize_t mc24lc64t_write (struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count){ + + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, write_time, i = 0; + int status; + u16 value; + + mutex_lock(&drvdata->update_lock); + +begin: + if (i < count){ + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + value = (buf[i] << 8 | ( off &0xff)); + do { + write_time = jiffies; + status = i2c_smbus_write_word_data(client, off>>8, value); + if (status >= 0) + { + // increase offset + off++; + // increase buffer index + i++; + goto begin; + } + } while (time_before(write_time, timeout)); + status = -ETIMEDOUT; + goto exit; + } + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + return status; +} + + +static struct bin_attribute mc24lc64t_bit_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO | S_IWUGO, + }, + .size = EEPROM_SIZE, + .read = mc24lc64t_read, + .write = mc24lc64t_write, +}; + +static int mc24lc64t_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct mc24lc64t_data *drvdata; + int err; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA + | I2C_FUNC_SMBUS_READ_BYTE)) + return -EPFNOSUPPORT; + + if (!(drvdata = devm_kzalloc(&client->dev, + sizeof(struct mc24lc64t_data), GFP_KERNEL))) + return -ENOMEM; + + i2c_set_clientdata(client, drvdata); + mutex_init(&drvdata->update_lock); + + err = sysfs_create_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + return err; +} + +static int mc24lc64t_remove(struct i2c_client *client) +{ + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + sysfs_remove_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + + return 0; +} + +static const struct i2c_device_id mc24lc64t_id[] = { + { "24lc64t", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mc24lc64t_id); + +static struct i2c_driver mc24lc64t_driver = { + .driver = { + .name = "mc24lc64t", + .owner = THIS_MODULE, + }, + .probe = mc24lc64t_probe, + .remove = mc24lc64t_remove, + .id_table = mc24lc64t_id, +}; + +module_i2c_driver(mc24lc64t_driver); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_DESCRIPTION("Microchip 24LC64T Driver"); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c new file mode 100644 index 000000000000..c7a86e13d3ad --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c @@ -0,0 +1,2089 @@ +/* + * switchboard_fpga.c - driver for seastone2 Switch board FPGA/CPLD. + * + * Author: Pradchaya Phucharoen + * + * Copyright (C) 2019 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * / + * \--sys + * \--devices + * \--platform + * \--switchboard + * |--FPGA + * |--CPLD1 + * |--CPLD2 + * \--SFF + * |--QSFP[1..32] + * \--SFP1 + * + */ + +#ifndef TEST_MODE +#define MOD_VERSION "2.1.3" +#else +#define MOD_VERSION "TEST" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +static int majorNumber; + +#define CLASS_NAME "seastone2_fpga" +#define DRIVER_NAME "switchboard" +#define FPGA_PCI_NAME "Seastone2_fpga_pci" +#define DEVICE_NAME "fwupgrade" + + +static int smbus_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); + +static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); + +static int fpgafw_init(void); +static void fpgafw_exit(void); + + +/* +======================================== +FPGA PCIe BAR 0 Registers +======================================== +Misc Control 0x00000000 – 0x000000FF. +I2C_CH1 0x00000100 - 0x00000110 +I2C_CH2 0x00000200 - 0x00000210. +I2C_CH3 0x00000300 - 0x00000310. +I2C_CH4 0x00000400 - 0x00000410. +I2C_CH5 0x00000500 - 0x00000510. +I2C_CH6 0x00000600 - 0x00000610. +I2C_CH7 0x00000700 - 0x00000710. +I2C_CH8 0x00000800 - 0x00000810. +I2C_CH9 0x00000900 - 0x00000910. +I2C_CH10 0x00000A00 - 0x00000A10. +SPI Master 0x00001200 - 0x00001300. +PORT XCVR 0x00004000 - 0x00004FFF. +*/ + +/* MISC */ +#define FPGA_VERSION 0x0000 +#define FPGA_VERSION_MJ_MSK 0xff00 +#define FPGA_VERSION_MN_MSK 0x00ff +#define FPGA_SCRATCH 0x0004 +#define FPGA_BROAD_TYPE 0x0008 +#define FPGA_BROAD_REV_MSK 0x0038 +#define FPGA_BROAD_ID_MSK 0x0007 +#define FPGA_PLL_STATUS 0x0014 +#define BMC_I2C_SCRATCH 0x0020 +#define FPGA_SLAVE_CPLD_REST 0x0030 +#define FPGA_PERIPH_RESET_CTRL 0x0034 +#define FPGA_INT_STATUS 0x0040 +#define FPGA_INT_SRC_STATUS 0x0044 +#define FPGA_INT_FLAG 0x0048 +#define FPGA_INT_MASK 0x004c +#define FPGA_MISC_CTRL 0x0050 +#define FPGA_MISC_STATUS 0x0054 +#define FPGA_AVS_VID_STATUS 0x0068 +#define FPGA_FEATURE_CARD_GPIO 0x0070 +#define FPGA_PORT_XCVR_READY 0x000c + +/* I2C_MASTER BASE ADDR */ +#define I2C_MASTER_FREQ_1 0x0100 +#define I2C_MASTER_CTRL_1 0x0104 +#define I2C_MASTER_STATUS_1 0x0108 +#define I2C_MASTER_DATA_1 0x010c +#define I2C_MASTER_PORT_ID_1 0x0110 +#define I2C_MASTER_CH_1 1 +#define I2C_MASTER_CH_2 2 +#define I2C_MASTER_CH_3 3 +#define I2C_MASTER_CH_4 4 +#define I2C_MASTER_CH_5 5 +#define I2C_MASTER_CH_6 6 +#define I2C_MASTER_CH_7 7 +#define I2C_MASTER_CH_8 8 +#define I2C_MASTER_CH_9 9 +#define I2C_MASTER_CH_10 10 +#define I2C_MASTER_CH_TOTAL I2C_MASTER_CH_10 + +/* SPI_MASTER */ +#define SPI_MASTER_WR_EN 0x1200 /* one bit */ +#define SPI_MASTER_WR_DATA 0x1204 /* 32 bits */ +#define SPI_MASTER_CHK_ID 0x1208 /* one bit */ +#define SPI_MASTER_VERIFY 0x120c /* one bit */ +#define SPI_MASTER_STATUS 0x1210 /* 15 bits */ +#define SPI_MASTER_MODULE_RST 0x1214 /* one bit */ + +/* FPGA FRONT PANEL PORT MGMT */ +#define SFF_PORT_CTRL_BASE 0x4000 +#define SFF_PORT_STATUS_BASE 0x4004 +#define SFF_PORT_INT_STATUS_BASE 0x4008 +#define SFF_PORT_INT_MASK_BASE 0x400c + +#define PORT_XCVR_REGISTER_SIZE 0x1000 + +/* PORT CTRL REGISTER +[31:7] RSVD +[6] LPMOD 6 +[5] RSVD +[4] RST 4 +[3:1] RSVD +[0] TXDIS 0 +*/ +#define CTRL_LPMOD 6 +#define CTRL_RST 4 +#define CTRL_TXDIS 0 + +/* PORT STATUS REGISTER +[31:6] RSVD +[5] IRQ 5 +[4] PRESENT 4 +[3] RSVD +[2] TXFAULT 2 +[1] RXLOS 1 +[0] MODABS 0 +*/ +#define STAT_IRQ 5 +#define STAT_PRESENT 4 +#define STAT_TXFAULT 2 +#define STAT_RXLOS 1 +#define STAT_MODABS 0 + +/* PORT INTRPT REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS 1 +[0] MODABS 0 +*/ +#define INTR_INT_N 5 +#define INTR_PRESENT 4 +#define INTR_TXFAULT 2 +#define INTR_RXLOS 1 +#define INTR_MODABS 0 + +/* PORT INT MASK REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS_INT 1 +[0] MODABS 0 +*/ +#define MASK_INT_N 5 +#define MASK_PRESENT 4 +#define MASK_TXFAULT 2 +#define MASK_RXLOS 1 +#define MASK_MODABS 0 + +enum { + I2C_SR_BIT_RXAK = 0, + I2C_SR_BIT_MIF, + I2C_SR_BIT_SRW, + I2C_SR_BIT_BCSTM, + I2C_SR_BIT_MAL, + I2C_SR_BIT_MBB, + I2C_SR_BIT_MAAS, + I2C_SR_BIT_MCF +}; + +enum { + I2C_CR_BIT_BCST = 0, + I2C_CR_BIT_RSTA = 2, + I2C_CR_BIT_TXAK, + I2C_CR_BIT_MTX, + I2C_CR_BIT_MSTA, + I2C_CR_BIT_MIEN, + I2C_CR_BIT_MEN, +}; + +/** + * + * The function is i2c algorithm implement to allow master access to + * correct endpoint devices trough the PCA9548 switch devices. + * + * FPGA I2C Master [mutex resource] + * | + * | + * --------------------------- + * | PCA9548(s) | + * ---1--2--3--4--5--6--7--8-- + * | | | | | | | | + * EEPROM ... EEPROM + * + */ + + +#define VIRTUAL_I2C_QSFP_PORT 32 +#define VIRTUAL_I2C_SFP_PORT 1 + +#define SFF_PORT_TOTAL VIRTUAL_I2C_QSFP_PORT + VIRTUAL_I2C_SFP_PORT + +#define VIRTUAL_I2C_BUS_OFFSET 2 +#define CPLD1_SLAVE_ADDR 0x30 +#define CPLD2_SLAVE_ADDR 0x31 + +static struct class* fpgafwclass = NULL; ///< The device-driver class struct pointer +static struct device* fpgafwdev = NULL; ///< The device-driver device struct pointer + +#define PCI_VENDOR_ID_TEST 0x1af4 + +#ifndef PCI_VENDOR_ID_XILINX +#define PCI_VENDOR_ID_XILINX 0x10EE +#endif + +#define FPGA_PCIE_DEVICE_ID 0x7021 +#define TEST_PCIE_DEVICE_ID 0x1110 + + +#ifdef DEBUG_KERN +#define info(fmt,args...) printk(KERN_INFO "line %3d : "fmt,__LINE__,##args) +#define check(REG) printk(KERN_INFO "line %3d : %-8s = %2.2X",__LINE__,#REG,ioread8(REG)); +#else +#define info(fmt,args...) +#define check(REG) +#endif + +#define GET_REG_BIT(REG,BIT) ((ioread8(REG) >> BIT) & 0x01) +#define SET_REG_BIT_H(REG,BIT) iowrite8(ioread8(REG) | (0x01 << BIT),REG) +#define SET_REG_BIT_L(REG,BIT) iowrite8(ioread8(REG) & ~(0x01 << BIT),REG) + +static struct mutex fpga_i2c_master_locks[I2C_MASTER_CH_TOTAL]; +/* Store lasted switch address and channel */ +static uint16_t fpga_i2c_lasted_access_port[I2C_MASTER_CH_TOTAL]; + +enum PORT_TYPE { + NONE, + QSFP, + SFP +}; + +struct i2c_switch{ + unsigned char master_bus; // I2C bus number + unsigned char switch_addr; // PCA9548 device address, 0xFF if directly connect to a bus. + unsigned char channel; // PCA9548 channel number. If the switch_addr is 0xFF, this value is ignored. + enum PORT_TYPE port_type; // QSFP/SFP tranceiver port type. + char calling_name[20]; // Calling name. +}; + +struct i2c_dev_data { + int portid; + struct i2c_switch pca9548; +}; + +/* PREDEFINED I2C SWITCH DEVICE TOPOLOGY */ +static struct i2c_switch fpga_i2c_bus_dev[] = { + /* BUS2 QSFP Exported as virtual bus */ + {I2C_MASTER_CH_2,0x72,0,QSFP,"QSFP1"}, {I2C_MASTER_CH_2,0x72,1,QSFP,"QSFP2"}, + {I2C_MASTER_CH_2,0x72,2,QSFP,"QSFP3"}, {I2C_MASTER_CH_2,0x72,3,QSFP,"QSFP4"}, + {I2C_MASTER_CH_2,0x72,4,QSFP,"QSFP5"}, {I2C_MASTER_CH_2,0x72,5,QSFP,"QSFP6"}, + {I2C_MASTER_CH_2,0x72,6,QSFP,"QSFP7"}, {I2C_MASTER_CH_2,0x72,7,QSFP,"QSFP8"}, + {I2C_MASTER_CH_2,0x73,0,QSFP,"QSFP9"}, {I2C_MASTER_CH_2,0x73,1,QSFP,"QSFP10"}, + {I2C_MASTER_CH_2,0x73,2,QSFP,"QSFP11"},{I2C_MASTER_CH_2,0x73,3,QSFP,"QSFP12"}, + {I2C_MASTER_CH_2,0x73,4,QSFP,"QSFP13"},{I2C_MASTER_CH_2,0x73,5,QSFP,"QSFP14"}, + {I2C_MASTER_CH_2,0x73,6,QSFP,"QSFP15"},{I2C_MASTER_CH_2,0x73,7,QSFP,"QSFP16"}, + {I2C_MASTER_CH_2,0x74,0,QSFP,"QSFP17"},{I2C_MASTER_CH_2,0x74,1,QSFP,"QSFP18"}, + {I2C_MASTER_CH_2,0x74,2,QSFP,"QSFP19"},{I2C_MASTER_CH_2,0x74,3,QSFP,"QSFP20"}, + {I2C_MASTER_CH_2,0x74,4,QSFP,"QSFP21"},{I2C_MASTER_CH_2,0x74,5,QSFP,"QSFP22"}, + {I2C_MASTER_CH_2,0x74,6,QSFP,"QSFP23"},{I2C_MASTER_CH_2,0x74,7,QSFP,"QSFP24"}, + {I2C_MASTER_CH_2,0x75,0,QSFP,"QSFP25"},{I2C_MASTER_CH_2,0x75,1,QSFP,"QSFP26"}, + {I2C_MASTER_CH_2,0x75,2,QSFP,"QSFP27"},{I2C_MASTER_CH_2,0x75,3,QSFP,"QSFP28"}, + {I2C_MASTER_CH_2,0x75,4,QSFP,"QSFP29"},{I2C_MASTER_CH_2,0x75,5,QSFP,"QSFP30"}, + {I2C_MASTER_CH_2,0x75,6,QSFP,"QSFP31"},{I2C_MASTER_CH_2,0x75,7,QSFP,"QSFP32"}, + /* BUS1 SFP+ Exported as virtual bus */ + {I2C_MASTER_CH_1,0x72,0,SFP,"SFP1"}, + /* BUS3 Switchboard CPLD */ + {I2C_MASTER_CH_3,0xFF,0,NONE,"I2C_3"}, +}; + +#define VIRTUAL_I2C_PORT_LENGTH ARRAY_SIZE(fpga_i2c_bus_dev) +#define VIRTUAL_I2C_CPLD_INDEX SFF_PORT_TOTAL + +struct fpga_device{ + /* data mmio region */ + void __iomem *data_base_addr; + resource_size_t data_mmio_start; + resource_size_t data_mmio_len; +}; + +static struct fpga_device fpga_dev = { + .data_base_addr = 0, + .data_mmio_start = 0, + .data_mmio_len = 0, +}; + +struct seastone2_fpga_data { + struct device *sff_devices[SFF_PORT_TOTAL]; + struct i2c_client *sff_i2c_clients[SFF_PORT_TOTAL]; + struct i2c_adapter *i2c_adapter[VIRTUAL_I2C_PORT_LENGTH]; + struct mutex fpga_lock; // For FPGA internal lock + void __iomem * fpga_read_addr; + uint8_t cpld1_read_addr; + uint8_t cpld2_read_addr; +}; + +struct sff_device_data { + int portid; + enum PORT_TYPE port_type; +}; + +struct seastone2_fpga_data *fpga_data; + +/* + * Kernel object for other module drivers. + * Other module can use these kobject as a parent. + */ + +static struct kobject *fpga = NULL; +static struct kobject *cpld1 = NULL; +static struct kobject *cpld2 = NULL; + +/** + * Device node in sysfs tree. + */ +static struct device *sff_dev = NULL; + +/** + * [get_fpga_reg_value description] + * @param dev [description] + * @param devattr [description] + * @param buf [description] + * @return [description] + */ +static ssize_t get_fpga_reg_value(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + // read data from the address + uint32_t data; + data = ioread32(fpga_data->fpga_read_addr); + return sprintf(buf,"0x%8.8x\n",data); +} +/** + * [set_fpga_reg_address description] + * @param dev [description] + * @param devattr [description] + * @param buf [description] + * @param count [description] + * @return [description] + */ +static ssize_t set_fpga_reg_address(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint32_t addr; + char *last; + + addr = (uint32_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + fpga_data->fpga_read_addr = fpga_dev.data_base_addr+addr; + return count; +} +/** + * [get_fpga_scratch description] + * @param dev [description] + * @param devattr [description] + * @param buf [description] + * @return [description] + */ +static ssize_t get_fpga_scratch(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + return sprintf(buf,"0x%8.8x\n", ioread32(fpga_dev.data_base_addr+FPGA_SCRATCH) & 0xffffffff); +} +/** + * [set_fpga_scratch description] + * @param dev [description] + * @param devattr [description] + * @param buf [description] + * @param count [description] + * @return [description] + */ +static ssize_t set_fpga_scratch(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint32_t data; + char *last; + data = (uint32_t)strtoul(buf,&last,16); + if(data == 0 && buf == last){ + return -EINVAL; + } + iowrite32(data, fpga_dev.data_base_addr+FPGA_SCRATCH); + return count; +} +/** + * [set_fpga_reg_value description] + * @param dev [description] + * @param devattr [description] + * @param buf [description] + * @return [description] + */ +static ssize_t set_fpga_reg_value(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + //register is 4 bytes + uint32_t addr; + uint32_t value; + uint32_t mode = 8; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + + strcpy(clone, buf); + + mutex_lock(&fpga_data->fpga_lock); + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + addr = (uint32_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + value = (uint32_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mode = 32; + }else{ + mode = (uint32_t)strtoul(tok,&last,10); + if(mode == 0 && tok == last){ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + } + if(mode == 32){ + iowrite32(value, fpga_dev.data_base_addr+addr); + }else if(mode == 8){ + iowrite8(value, fpga_dev.data_base_addr+addr); + }else{ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + mutex_unlock(&fpga_data->fpga_lock); + return count; +} + +/** + * Show FPGA port XCVR ready status + */ +static ssize_t ready_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + unsigned int REGISTER = FPGA_PORT_XCVR_READY; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> 0) & 1U); +} + +/* FPGA attributes */ +static DEVICE_ATTR( getreg, 0600, get_fpga_reg_value, set_fpga_reg_address); +static DEVICE_ATTR( scratch, 0600, get_fpga_scratch, set_fpga_scratch); +static DEVICE_ATTR( setreg, 0200, NULL , set_fpga_reg_value); +static DEVICE_ATTR_RO(ready); + +static struct attribute *fpga_attrs[] = { + &dev_attr_getreg.attr, + &dev_attr_scratch.attr, + &dev_attr_setreg.attr, + &dev_attr_ready.attr, + NULL, +}; + +static struct attribute_group fpga_attr_grp = { + .attrs = fpga_attrs, +}; + +/* SW CPLDs attributes */ +static ssize_t cpld1_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,fpga_data->cpld1_read_addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + return sprintf(buf,"0x%2.2x\n",data); +} +static ssize_t cpld1_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + uint8_t addr; + char *last; + addr = (uint8_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + fpga_data->cpld1_read_addr = addr; + return size; +} +struct device_attribute dev_attr_cpld1_getreg = __ATTR(getreg,0600,cpld1_getreg_show,cpld1_getreg_store); + +static ssize_t cpld1_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + __u8 data; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + if(err < 0) + return err; + return sprintf(buf, "0x%2.2x\n",data); +} +static ssize_t cpld1_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + __u8 data; + char *last; + int err; + data = (uint8_t)strtoul(buf,&last,16); + if(data == 0 && buf == last){ + return -EINVAL; + } + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + if(err < 0) + return err; + return size; +} +struct device_attribute dev_attr_cpld1_scratch = __ATTR(scratch,0600,cpld1_scratch_show,cpld1_scratch_store); + +static ssize_t cpld1_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + + uint8_t addr,value; + char *tok; + char clone[size]; + char *pclone = clone; + int err; + char *last; + + strcpy(clone, buf); + + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + return -EINVAL; + } + addr = (uint8_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + return -EINVAL; + } + value = (uint8_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + return -EINVAL; + } + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&value); + if(err < 0) + return err; + + return size; +} +struct device_attribute dev_attr_cpld1_setreg = __ATTR(setreg,0200,NULL,cpld1_setreg_store); + +static struct attribute *cpld1_attrs[] = { + &dev_attr_cpld1_getreg.attr, + &dev_attr_cpld1_scratch.attr, + &dev_attr_cpld1_setreg.attr, + NULL, +}; + +static struct attribute_group cpld1_attr_grp = { + .attrs = cpld1_attrs, +}; + +static ssize_t cpld2_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,fpga_data->cpld2_read_addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + return sprintf(buf,"0x%2.2x\n",data); +} +static ssize_t cpld2_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + uint32_t addr; + char *last; + addr = (uint8_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + fpga_data->cpld2_read_addr = addr; + return size; +} +struct device_attribute dev_attr_cpld2_getreg = __ATTR(getreg,0600,cpld2_getreg_show,cpld2_getreg_store); + +static ssize_t cpld2_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + __u8 data; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + if(err < 0) + return err; + return sprintf(buf, "0x%2.2x\n",data); +} +static ssize_t cpld2_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + __u8 data; + char *last; + int err; + + data = (uint8_t)strtoul(buf,&last,16); + if(data == 0 && buf == last){ + return -EINVAL; + } + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + if(err < 0) + return err; + return size; +} +struct device_attribute dev_attr_cpld2_scratch = __ATTR(scratch,0600,cpld2_scratch_show,cpld2_scratch_store); + +static ssize_t cpld2_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + uint8_t addr,value; + char *tok; + char clone[size]; + char *pclone = clone; + int err; + char *last; + + strcpy(clone, buf); + + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + return -EINVAL; + } + addr = (uint8_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + return -EINVAL; + } + value = (uint8_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + return -EINVAL; + } + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&value); + if(err < 0) + return err; + + return size; +} +struct device_attribute dev_attr_cpld2_setreg = __ATTR(setreg,0200,NULL,cpld2_setreg_store); + +static struct attribute *cpld2_attrs[] = { + &dev_attr_cpld2_getreg.attr, + &dev_attr_cpld2_scratch.attr, + &dev_attr_cpld2_setreg.attr, + NULL, +}; + +static struct attribute_group cpld2_attr_grp = { + .attrs = cpld2_attrs, +}; + +/* QSFP/SFP+ attributes */ +static ssize_t qsfp_modirq_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_IRQ) & 1U); +} +DEVICE_ATTR_RO(qsfp_modirq); + +static ssize_t qsfp_modprs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_PRESENT) & 1U); +} +DEVICE_ATTR_RO(qsfp_modprs); + +static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_TXFAULT) & 1U); +} +DEVICE_ATTR_RO(sfp_txfault); + +static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_RXLOS) & 1U); +} +DEVICE_ATTR_RO(sfp_rxlos); + +static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_MODABS) & 1U); +} +DEVICE_ATTR_RO(sfp_modabs); + +static ssize_t qsfp_lpmode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_LPMOD) & 1U); +} +static ssize_t qsfp_lpmode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + data = ioread32(fpga_dev.data_base_addr+REGISTER); + if(!value) + data = data & ~( (u32)0x1 << CTRL_LPMOD); + else + data = data | ((u32)0x1 << CTRL_LPMOD); + iowrite32(data,fpga_dev.data_base_addr+REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_lpmode); + +static ssize_t qsfp_reset_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_RST) & 1U); +} + +static ssize_t qsfp_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + data = ioread32(fpga_dev.data_base_addr+REGISTER); + if(!value) + data = data & ~( (u32)0x1 << CTRL_RST); + else + data = data | ((u32)0x1 << CTRL_RST); + iowrite32(data,fpga_dev.data_base_addr+REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_reset); + +static ssize_t sfp_txdisable_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_TXDIS) & 1U); +} +static ssize_t sfp_txdisable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + data = ioread32(fpga_dev.data_base_addr+REGISTER); + if(!value) + data = data & ~( (u32)0x1 << CTRL_TXDIS); + else + data = data | ((u32)0x1 << CTRL_TXDIS); + iowrite32(data,fpga_dev.data_base_addr+REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(sfp_txdisable); + +static struct attribute *sff_attrs[] = { + &dev_attr_qsfp_modirq.attr, + &dev_attr_qsfp_modprs.attr, + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_sfp_txfault.attr, + &dev_attr_sfp_rxlos.attr, + &dev_attr_sfp_modabs.attr, + &dev_attr_sfp_txdisable.attr, + NULL, +}; + +static struct attribute_group sff_attr_grp = { + .attrs = sff_attrs, +}; + +static const struct attribute_group *sff_attr_grps[] = { + &sff_attr_grp, + NULL +}; + + +static ssize_t port_led_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // value can be "nomal", "test" + __u8 led_mode_1,led_mode_2; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); + if(err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_2); + if(err < 0) + return err; + return sprintf(buf, "%s %s\n", + led_mode_1 ? "test" : "normal", + led_mode_2 ? "test" : "normal"); +} +static ssize_t port_led_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int status; + __u8 led_mode_1; + if(sysfs_streq(buf, "test")){ + led_mode_1 = 0x01; + }else if(sysfs_streq(buf, "normal")){ + led_mode_1 = 0x00; + }else{ + return -EINVAL; + } + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, + I2C_SMBUS_WRITE,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, + I2C_SMBUS_WRITE,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); + return size; +} +DEVICE_ATTR_RW(port_led_mode); + +// Only work when port_led_mode set to 1 +static ssize_t port_led_color_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // value can be "off", "green", "amber", "both" + __u8 led_color1,led_color2; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color1); + if(err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color2); + if(err < 0) + return err; + return sprintf(buf, "%s %s\n", + led_color1 == 0x03 ? "off" : led_color1 == 0x02 ? "green" : led_color1 ==0x01 ? "amber": "both", + led_color2 == 0x03 ? "off" : led_color2 == 0x02 ? "green" : led_color2 ==0x01 ? "amber": "both"); +} + +static ssize_t port_led_color_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int status; + __u8 led_color; + if(sysfs_streq(buf, "off")){ + led_color = 0x03; + }else if(sysfs_streq(buf, "green")){ + led_color = 0x02; + }else if(sysfs_streq(buf, "amber")){ + led_color = 0x01; + }else if(sysfs_streq(buf, "both")){ + led_color = 0x00; + }else{ + status = -EINVAL; + return status; + } + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, + I2C_SMBUS_WRITE,0x0A,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color); + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, + I2C_SMBUS_WRITE,0x0A,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color); + return size; +} +DEVICE_ATTR_RW(port_led_color); + +static struct attribute *sff_led_test[] = { + &dev_attr_port_led_mode.attr, + &dev_attr_port_led_color.attr, + NULL, +}; + +static struct attribute_group sff_led_test_grp = { + .attrs = sff_led_test, +}; + +static struct device * seastone2_sff_init(int portid){ + struct sff_device_data *new_data; + struct device *new_device; + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) { + printk(KERN_ALERT "Cannot alloc sff device data @port%d", portid); + return NULL; + } + /* The QSFP port ID start from 1 */ + new_data->portid = portid+1; + new_data->port_type = fpga_i2c_bus_dev[portid].port_type; + new_device = device_create_with_groups(fpgafwclass, sff_dev, MKDEV(0,0), new_data, sff_attr_grps, "%s",fpga_i2c_bus_dev[portid].calling_name); + if (IS_ERR(new_device)) { + printk(KERN_ALERT "Cannot create sff device @port%d", portid); + kfree(new_data); + return NULL; + } + return new_device; +} + +static int i2c_wait_ack(struct i2c_adapter *a,unsigned long timeout,int writing){ + int error = 0; + int Status; + + struct i2c_dev_data *new_data = i2c_get_adapdata(a); + void __iomem *pci_bar = fpga_dev.data_base_addr; + + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + unsigned int master_bus = new_data->pca9548.master_bus; + + if(master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL){ + error = -EINVAL; + return error; + } + + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus-1)*0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus-1)*0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus-1)*0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus-1)*0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus-1)*0x0100; + + check(pci_bar+REG_SR0); + check(pci_bar+REG_CR0); + + timeout = jiffies + msecs_to_jiffies(timeout); + while(1){ + Status = ioread8(pci_bar+REG_SR0); + if(jiffies > timeout){ + info("Status %2.2X",Status); + info("Error Timeout"); + error = -ETIMEDOUT; + break; + } + + + if(Status & (1 << I2C_SR_BIT_MIF)){ + break; + } + + if(writing == 0 && (Status & (1<portid; + pci_bar = fpga_dev.data_base_addr; + +#ifdef DEBUG_KERN + printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-15s|CMD %2.2X " + ,portid,addr,flags,rw,rw == 1 ? "READ ":"WRITE" + ,size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + ,cmd); +#endif + /* Map the size to what the chip understands */ + switch (size) { + case I2C_SMBUS_QUICK: + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + break; + default: + printk(KERN_INFO "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; + } + + master_bus = dev_data->pca9548.master_bus; + + if(master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL){ + error = -ENXIO; + goto Done; + } + + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus-1)*0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus-1)*0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus-1)*0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus-1)*0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus-1)*0x0100; + + iowrite8(portid,pci_bar+REG_ID0); + + ////[S][ADDR/R] + // Clear status register + iowrite8(0,pci_bar+REG_SR0); + iowrite8(1 << I2C_CR_BIT_MIEN | 1 << I2C_CR_BIT_MTX | 1 << I2C_CR_BIT_MSTA ,pci_bar+REG_CR0); + SET_REG_BIT_H(pci_bar+REG_CR0,I2C_CR_BIT_MEN); + + if(rw == I2C_SMBUS_READ && + (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)){ + // sent device address with Read mode + iowrite8(addr << 1 | 0x01,pci_bar+REG_DR0); + }else{ + // sent device address with Write mode + iowrite8(addr << 1 | 0x00,pci_bar+REG_DR0); + } + + + + info( "MS Start"); + + //// Wait {A} + error = i2c_wait_ack(adapter,12,1); + if(error<0){ + info( "get error %d",error); + goto Done; + } + + //// [CMD]{A} + if(size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA || + (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)){ + + // sent command code to data register + iowrite8(cmd,pci_bar+REG_DR0); + info( "MS Send CMD 0x%2.2X",cmd); + + // Wait {A} + error = i2c_wait_ack(adapter,12,1); + if(error<0){ + info( "get error %d",error); + goto Done; + } + } + + switch(size){ + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + /* In block data modes keep number of byte in block[0] */ + cnt = data->block[0]; + break; + default: + cnt = 0; break; + } + + // [CNT] used only block data write + if(size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE){ + + iowrite8(cnt,pci_bar+REG_DR0); + info( "MS Send CNT 0x%2.2X",cnt); + + // Wait {A} + error = i2c_wait_ack(adapter,12,1); + if(error<0){ + info( "get error %d",error); + goto Done; + } + } + + // [DATA]{A} + if( rw == I2C_SMBUS_WRITE && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )){ + bid = 0; + info( "MS prepare to sent [%d bytes]",cnt); + if(size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA){ + bid=1; // block[0] is cnt; + cnt+=1; // offset from block[0] + } + for(;bidblock[bid],pci_bar+REG_DR0); + info( " Data > %2.2X",data->block[bid]); + // Wait {A} + error = i2c_wait_ack(adapter,12,1); + if(error<0){ + goto Done; + } + } + + } + + // REPEATE START + if( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )){ + info( "MS Repeated Start"); + + SET_REG_BIT_L(pci_bar+REG_CR0,I2C_CR_BIT_MEN); + iowrite8(1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MTX | + 1 << I2C_CR_BIT_MSTA | + 1 << I2C_CR_BIT_RSTA ,pci_bar+REG_CR0); + SET_REG_BIT_H(pci_bar+REG_CR0,I2C_CR_BIT_MEN); + + // sent Address with Read mode + iowrite8( addr<<1 | 0x1 ,pci_bar+REG_DR0); + + // Wait {A} + error = i2c_wait_ack(adapter,12,1); + if(error<0){ + goto Done; + } + + } + + if( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )){ + + switch(size){ + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + // will be changed after recived first data + cnt = 3; break; + case I2C_SMBUS_I2C_BLOCK_DATA: + cnt = data->block[0]; break; + default: + cnt = 0; break; + } + + bid = 0; + info( "MS Receive"); + + //set to Receive mode + iowrite8(1 << I2C_CR_BIT_MEN | + 1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MSTA , pci_bar+REG_CR0); + + for(bid=-1;bidblock[bid+1] = ioread8(pci_bar+REG_DR0); + }else { + data->block[bid] = ioread8(pci_bar+REG_DR0); + } + info( "DATA IN [%d] %2.2X",bid,data->block[bid]); + + if(size == I2C_SMBUS_BLOCK_DATA && bid == 0){ + cnt = data->block[0] + 1; + } + } + } + } + + // [P] + SET_REG_BIT_L(pci_bar+REG_CR0,I2C_CR_BIT_MSTA); + info( "MS STOP"); + +Done: + iowrite8(1<pca9548.master_bus; + switch_addr = dev_data->pca9548.switch_addr; + channel = dev_data->pca9548.channel; + + // Acquire the master resource. + mutex_lock(&fpga_i2c_master_locks[master_bus - 1]); + prev_port = fpga_i2c_lasted_access_port[master_bus - 1]; + prev_switch = (unsigned char)(prev_port >> 8) & 0xFF; + prev_ch = (unsigned char)(prev_port & 0xFF); + + if (switch_addr != 0xFF) { + + // Check lasted access switch address on a master + if ( prev_switch != switch_addr && prev_switch != 0 ) { + // reset prev_port PCA9548 chip + retry = 3; + while(retry--){ + error = smbus_access(adapter, (u16)(prev_switch), flags, I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); + if(error >= 0){ + break; + }else{ + dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); + } + } + if(retry < 0){ + goto release_unlock; + } + // set PCA9548 to current channel + retry = 3; + while(retry--){ + error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); + if(error >= 0){ + break; + }else{ + dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); + } + } + if(retry < 0){ + goto release_unlock; + } + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + + } else { + // check if channel is also changes + if ( prev_ch != channel || prev_switch == 0 ) { + // set new PCA9548 at switch_addr to current + retry = 3; + while(retry--){ + error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); + if(error >= 0){ + break; + }else{ + dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); + } + } + if(retry < 0){ + goto release_unlock; + } + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + } + } + } + + // Do SMBus communication + error = smbus_access(adapter, addr, flags, rw, cmd, size, data); + if(error < 0){ + dev_dbg( &adapter->dev,"smbus_xfer failed (%d) @ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " + , error, addr, flags, rw, rw == 1 ? "READ " : "WRITE" + , size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + , cmd); + } + +release_unlock: + mutex_unlock(&fpga_i2c_master_locks[master_bus - 1]); + dev_dbg(&adapter->dev,"switch ch %d of 0x%x -> ch %d of 0x%x\n", prev_ch, prev_switch, channel, switch_addr); + return error; +} + + + +/** + * A callback function show available smbus functions. + */ +static u32 fpga_i2c_func(struct i2c_adapter *a) +{ + return I2C_FUNC_SMBUS_QUICK | + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA| + I2C_FUNC_SMBUS_I2C_BLOCK; +} + +static const struct i2c_algorithm seastone2_i2c_algorithm = { + .smbus_xfer = fpga_i2c_access, + .functionality = fpga_i2c_func, +}; + +/** + * Create virtual I2C bus adapter for switch devices + * @param pdev platform device pointer + * @param portid virtual i2c port id for switch device mapping + * @param bus_number_offset bus offset for virtual i2c adapter in system + * @return i2c adapter. + * + * When bus_number_offset is -1, created adapter with dynamic bus number. + * Otherwise create adapter at i2c bus = bus_number_offset + portid. + */ +static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int portid, int bus_number_offset) +{ + int error; + struct i2c_adapter *new_adapter; + struct i2c_dev_data *new_data; + void __iomem *i2c_freq_base_reg; + + new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL); + if (!new_adapter){ + printk(KERN_ALERT "Cannot alloc i2c adapter for %s", fpga_i2c_bus_dev[portid].calling_name); + return NULL; + } + + new_adapter->owner = THIS_MODULE; + new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + new_adapter->algo = &seastone2_i2c_algorithm; + /* If the bus offset is -1, use dynamic bus number */ + if (bus_number_offset == -1){ + new_adapter->nr = -1; + }else{ + new_adapter->nr = bus_number_offset + portid; + } + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data){ + printk(KERN_ALERT "Cannot alloc i2c data for %s", fpga_i2c_bus_dev[portid].calling_name); + kzfree(new_adapter); + return NULL; + } + + new_data->portid = portid; + new_data->pca9548.master_bus = fpga_i2c_bus_dev[portid].master_bus; + new_data->pca9548.switch_addr = fpga_i2c_bus_dev[portid].switch_addr; + new_data->pca9548.channel = fpga_i2c_bus_dev[portid].channel; + strcpy(new_data->pca9548.calling_name,fpga_i2c_bus_dev[portid].calling_name); + + snprintf(new_adapter->name, sizeof(new_adapter->name), + "SMBus I2C Adapter PortID: %s", new_data->pca9548.calling_name); + + i2c_freq_base_reg = fpga_dev.data_base_addr+I2C_MASTER_FREQ_1; + iowrite8(0x07,i2c_freq_base_reg+(new_data->pca9548.master_bus-1)*0x100); // 0x07 400kHz + i2c_set_adapdata(new_adapter,new_data); + error = i2c_add_numbered_adapter(new_adapter); + if(error < 0){ + printk(KERN_ALERT "Cannot add i2c adapter %s", new_data->pca9548.calling_name); + kzfree(new_adapter); + kzfree(new_data); + return NULL; + } + + return new_adapter; +}; + +// I/O resource need. +static struct resource seastone2_resources[] = { + { + .start = 0x10000000, + .end = 0x10001000, + .flags = IORESOURCE_MEM, + }, +}; + +static void seastone2_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device seastone2_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(seastone2_resources), + .resource = seastone2_resources, + .dev = { + .release = seastone2_dev_release, + } +}; + +/** + * Board info for QSFP/SFP+ eeprom. + * Note: Using sff8436 as I2C eeprom driver. + */ +static struct i2c_board_info sff8436_eeprom_info[] = { + { I2C_BOARD_INFO("optoe1", 0x50) }, + { I2C_BOARD_INFO("optoe2", 0x50) }, +}; + +static int seastone2_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret = 0; + int portid_count; + uint8_t cpld1_version, cpld2_version; + uint16_t prev_i2c_switch = 0; + struct sff_device_data *sff_data; + + /* The device class need to be instantiated before this function called */ + BUG_ON(fpgafwclass == NULL); + + fpga_data = devm_kzalloc(&pdev->dev, sizeof(struct seastone2_fpga_data), + GFP_KERNEL); + + if (!fpga_data) + return -ENOMEM; + + // Set default read address to VERSION + fpga_data->fpga_read_addr = fpga_dev.data_base_addr+FPGA_VERSION; + fpga_data->cpld1_read_addr = 0x00; + fpga_data->cpld2_read_addr = 0x00; + + mutex_init(&fpga_data->fpga_lock); + for(ret=I2C_MASTER_CH_1 ;ret <= I2C_MASTER_CH_TOTAL; ret++){ + mutex_init(&fpga_i2c_master_locks[ret-1]); + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!res)) { + printk(KERN_ERR "Specified Resource Not Available...\n"); + kzfree(fpga_data); + return -1; + } + + fpga = kobject_create_and_add("FPGA", &pdev->dev.kobj); + if (!fpga){ + kzfree(fpga_data); + return -ENOMEM; + } + + ret = sysfs_create_group(fpga, &fpga_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create FPGA sysfs attributes\n"); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + cpld1 = kobject_create_and_add("CPLD1", &pdev->dev.kobj); + if (!cpld1){ + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return -ENOMEM; + } + ret = sysfs_create_group(cpld1, &cpld1_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD1 sysfs attributes\n"); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + cpld2 = kobject_create_and_add("CPLD2", &pdev->dev.kobj); + if (!cpld2){ + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return -ENOMEM; + } + ret = sysfs_create_group(cpld2, &cpld2_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD2 sysfs attributes\n"); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + sff_dev = device_create(fpgafwclass, NULL, MKDEV(0,0), NULL, "sff_device"); + if (IS_ERR(sff_dev)){ + printk(KERN_ERR "Failed to create sff device\n"); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return PTR_ERR(sff_dev); + } + + ret = sysfs_create_group(&sff_dev->kobj, &sff_led_test_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create SFF attributes\n"); + device_destroy(fpgafwclass, MKDEV(0,0)); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + ret = sysfs_create_link(&pdev->dev.kobj,&sff_dev->kobj,"SFF"); + if (ret != 0){ + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + device_destroy(fpgafwclass, MKDEV(0,0)); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + for(portid_count=0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++){ + fpga_data->i2c_adapter[portid_count] = seastone2_i2c_init(pdev, portid_count, VIRTUAL_I2C_BUS_OFFSET); + } + + + /* Init SFF devices */ + for(portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ + struct i2c_adapter *i2c_adap = fpga_data->i2c_adapter[portid_count]; + if(i2c_adap){ + fpga_data->sff_devices[portid_count] = seastone2_sff_init(portid_count); + sff_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); + BUG_ON(sff_data == NULL); + if( sff_data->port_type == QSFP ){ + fpga_data->sff_i2c_clients[portid_count] = i2c_new_device(i2c_adap, &sff8436_eeprom_info[0]); + }else{ + fpga_data->sff_i2c_clients[portid_count] = i2c_new_device(i2c_adap, &sff8436_eeprom_info[1]); + } + sff_data = NULL; + sysfs_create_link(&fpga_data->sff_devices[portid_count]->kobj, + &fpga_data->sff_i2c_clients[portid_count]->dev.kobj, + "i2c"); + } + + } + + printk(KERN_INFO "Virtual I2C buses created\n"); + +#ifdef TEST_MODE + return 0; +#endif + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, + I2C_SMBUS_READ,0x00,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&cpld1_version); + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, + I2C_SMBUS_READ,0x00,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&cpld2_version); + + printk(KERN_INFO "CPLD1 VERSON: %2.2x\n", cpld1_version); + printk(KERN_INFO "CPLD2 VERSON: %2.2x\n", cpld2_version); + + /* Init I2C buses that has PCA9548 switch device. */ + for (portid_count = 0; portid_count < VIRTUAL_I2C_PORT_LENGTH; portid_count++) { + + struct i2c_dev_data *dev_data; + unsigned char master_bus; + unsigned char switch_addr; + + dev_data = i2c_get_adapdata(fpga_data->i2c_adapter[portid_count]); + master_bus = dev_data->pca9548.master_bus; + switch_addr = dev_data->pca9548.switch_addr; + + if (switch_addr != 0xFF) { + + if (prev_i2c_switch != ( (master_bus << 8) | switch_addr) ) { + // Found the bus with PCA9548, trying to clear all switch in it. + smbus_access(fpga_data->i2c_adapter[portid_count], switch_addr, 0x00, + I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); + prev_i2c_switch = ( master_bus << 8 ) | switch_addr; + } + } + } + return 0; +} + +static int seastone2_drv_remove(struct platform_device *pdev) +{ + int portid_count; + struct sff_device_data *rem_data; + + for(portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ + sysfs_remove_link(&fpga_data->sff_devices[portid_count]->kobj,"i2c"); + i2c_unregister_device(fpga_data->sff_i2c_clients[portid_count]); + } + + for(portid_count=0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++){ + if(fpga_data->i2c_adapter[portid_count] != NULL){ + info(KERN_INFO "<%x>",fpga_data->i2c_adapter[portid_count]); + i2c_del_adapter(fpga_data->i2c_adapter[portid_count]); + } + } + + for (portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ + if(fpga_data->sff_devices[portid_count] != NULL){ + rem_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); + device_unregister(fpga_data->sff_devices[portid_count]); + put_device(fpga_data->sff_devices[portid_count]); + kfree(rem_data); + } + } + + sysfs_remove_group(fpga, &fpga_attr_grp); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + kobject_put(fpga); + kobject_put(cpld1); + kobject_put(cpld2); + device_destroy(fpgafwclass, MKDEV(0,0)); + devm_kfree(&pdev->dev, fpga_data); + return 0; +} + +static struct platform_driver seastone2_drv = { + .probe = seastone2_drv_probe, + .remove = __exit_p(seastone2_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +#ifdef TEST_MODE + #define FPGA_PCI_BAR_NUM 2 +#else + #define FPGA_PCI_BAR_NUM 0 +#endif + +static const struct pci_device_id fpga_id_table[] = { + { PCI_VDEVICE(XILINX, FPGA_PCIE_DEVICE_ID) }, + { PCI_VDEVICE(TEST, TEST_PCIE_DEVICE_ID) }, + {0, } +}; + +MODULE_DEVICE_TABLE(pci, fpga_id_table); + +static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int err; + struct device *dev = &pdev->dev; + uint32_t fpga_version; + + if ((err = pci_enable_device(pdev))) { + dev_err(dev, "pci_enable_device probe error %d for device %s\n", + err, pci_name(pdev)); + return err; + } + + if ((err = pci_request_regions(pdev, FPGA_PCI_NAME)) < 0) { + dev_err(dev, "pci_request_regions error %d\n", err); + goto pci_disable; + } + + /* bar0: data mmio region */ + fpga_dev.data_mmio_start = pci_resource_start(pdev, FPGA_PCI_BAR_NUM); + fpga_dev.data_mmio_len = pci_resource_len(pdev, FPGA_PCI_BAR_NUM); + fpga_dev.data_base_addr = pci_iomap(pdev, FPGA_PCI_BAR_NUM, 0); + if (!fpga_dev.data_base_addr) { + dev_err(dev, "cannot iomap region of size %lu\n", + (unsigned long)fpga_dev.data_mmio_len); + goto pci_release; + } + dev_info(dev, "data_mmio iomap base = 0x%lx \n", + (unsigned long)fpga_dev.data_base_addr); + dev_info(dev, "data_mmio_start = 0x%lx data_mmio_len = %lu\n", + (unsigned long)fpga_dev.data_mmio_start, + (unsigned long)fpga_dev.data_mmio_len); + + printk(KERN_INFO "FPGA PCIe driver probe OK.\n"); + printk(KERN_INFO "FPGA ioremap registers of size %lu\n",(unsigned long)fpga_dev.data_mmio_len); + printk(KERN_INFO "FPGA Virtual BAR %d at %8.8lx - %8.8lx\n", FPGA_PCI_BAR_NUM, + (unsigned long)fpga_dev.data_base_addr, + (unsigned long)(fpga_dev.data_base_addr + fpga_dev.data_mmio_len)); + printk(KERN_INFO ""); + fpga_version = ioread32(fpga_dev.data_base_addr); + printk(KERN_INFO "FPGA VERSION : %8.8x\n", fpga_version); + fpgafw_init(); + platform_device_register(&seastone2_dev); + platform_driver_register(&seastone2_drv); + return 0; + +pci_release: + pci_release_regions(pdev); +pci_disable: + pci_disable_device(pdev); + return -EBUSY; +} + +static void fpga_pci_remove(struct pci_dev *pdev) +{ + platform_driver_unregister(&seastone2_drv); + platform_device_unregister(&seastone2_dev); + fpgafw_exit(); + pci_iounmap(pdev, fpga_dev.data_base_addr); + pci_release_regions(pdev); + pci_disable_device(pdev); + printk(KERN_INFO "FPGA PCIe driver remove OK.\n"); +}; + +static struct pci_driver pci_dev_ops = { + .name = FPGA_PCI_NAME, + .probe = fpga_pci_probe, + .remove = fpga_pci_remove, + .id_table = fpga_id_table, +}; + +enum{ + READREG, + WRITEREG +}; + +struct fpga_reg_data { + uint32_t addr; + uint32_t value; +}; + +static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg){ + int ret = 0; + struct fpga_reg_data data; + mutex_lock(&fpga_data->fpga_lock); + +#ifdef TEST_MODE + static uint32_t status_reg; +#endif + // Switch function to read and write. + switch (cmd){ + case READREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0){ + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + data.value = ioread32(fpga_dev.data_base_addr+data.addr); + if (copy_to_user((void __user*)arg ,&data, sizeof(data)) != 0){ + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } +#ifdef TEST_MODE + if(data.addr == 0x1210){ + switch (status_reg){ + case 0x0000 : status_reg=0x8000; + break; + + case 0x8080 : status_reg=0x80C0; + break; + case 0x80C0 : status_reg=0x80F0; + break; + case 0x80F0 : status_reg=0x80F8; + break; + + } + iowrite32(status_reg,fpga_dev.data_base_addr+0x1210); + } +#endif + + + break; + case WRITEREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0){ + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + iowrite32(data.value,fpga_dev.data_base_addr+data.addr); + +#ifdef TEST_MODE + if(data.addr == 0x1204){ + status_reg=0x8080; + iowrite32(status_reg,fpga_dev.data_base_addr+0x1210); + } +#endif + + break; + default: + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + mutex_unlock(&fpga_data->fpga_lock); + return ret; +} + + +const struct file_operations fpgafw_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = fpgafw_unlocked_ioctl, +}; + + +static int fpgafw_init(void){ + printk(KERN_INFO "Initializing the switchboard driver\n"); + // Try to dynamically allocate a major number for the device -- more difficult but worth it + majorNumber = register_chrdev(0, DEVICE_NAME, &fpgafw_fops); + if (majorNumber<0){ + printk(KERN_ALERT "Failed to register a major number\n"); + return majorNumber; + } + printk(KERN_INFO "Device registered correctly with major number %d\n", majorNumber); + + // Register the device class + fpgafwclass = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(fpgafwclass)){ // Check for error and clean up if there is + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to register device class\n"); + return PTR_ERR(fpgafwclass); // Correct way to return an error on a pointer + } + printk(KERN_INFO "Device class registered correctly\n"); + + // Register the device driver + fpgafwdev = device_create(fpgafwclass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME); + if (IS_ERR(fpgafwdev)){ // Clean up if there is an error + class_destroy(fpgafwclass); // Repeated code but the alternative is goto statements + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to create the FW upgrade device node\n"); + return PTR_ERR(fpgafwdev); + } + printk(KERN_INFO "FPGA fw upgrade device node created correctly\n"); // Made it! device was initialized + return 0; +} + +static void fpgafw_exit(void){ + device_destroy(fpgafwclass, MKDEV(majorNumber, 0)); // remove the device + class_unregister(fpgafwclass); // unregister the device class + class_destroy(fpgafwclass); // remove the device class + unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number + printk(KERN_INFO "Goodbye!\n"); +} + +int seastone2_init(void) +{ + int rc; + rc = pci_register_driver(&pci_dev_ops); + if(rc) + return rc; + return 0; +} + +void seastone2_exit(void) +{ + pci_unregister_driver(&pci_dev_ops); +} + +module_init(seastone2_init); +module_exit(seastone2_exit); + +MODULE_AUTHOR("Pradchaya P. pphuhcar@celestica.com"); +MODULE_DESCRIPTION("Celestica seastone2 platform driver"); +MODULE_VERSION(MOD_VERSION); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/systemd/platform-modules-seastone2.service b/platform/broadcom/sonic-platform-modules-cel/seastone2/systemd/platform-modules-seastone2.service new file mode 100644 index 000000000000..02553bf24538 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/systemd/platform-modules-seastone2.service @@ -0,0 +1,14 @@ + +[Unit] +Description=Celestica seastone2 platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-seastone2 start +ExecStop=-/etc/init.d/platform-modules-seastone2 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index 5bddb7a0ded7..7740da96aa2d 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -210,3 +210,10 @@ sai_preinit_cmd_file sai_preinit_warmboot_cmd_file sai_postinit_cmd_file sai_postinit_warmboot_cmd_file +help_cli_enable +memlist_enable +serdes_lane_config_dfe +serdes_fec_enable +pbmp_gport_stack +reglist_enable +scache_filename From 4c526d964014e598bc8edcb6e0b4e9921c0ff7b0 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 16 Jan 2020 09:43:48 +0700 Subject: [PATCH 0293/1427] [device/celestica]: Implement Silverstone platform API [THERMAL/COMPONENT] (#3938) - Add Thermal APIs - Add Component APIs --- .../sonic_platform/chassis.py | 13 +- .../sonic_platform/component.py | 121 ++++++++++++++ .../sonic_platform/helper.py | 56 ++++++- .../sonic_platform/thermal.py | 153 ++++++++++++++++++ 4 files changed, 340 insertions(+), 3 deletions(-) create mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py create mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/thermal.py diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py index d984b3578b27..a3ccc9439ada 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py @@ -16,9 +16,11 @@ try: from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.component import Component from sonic_platform.eeprom import Tlv from sonic_platform.fan import Fan from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal from helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -26,7 +28,7 @@ NUM_FAN_TRAY = 7 NUM_FAN = 2 NUM_PSU = 2 -NUM_THERMAL = 5 +NUM_THERMAL = 10 NUM_SFP = 32 NUM_COMPONENT = 5 @@ -50,6 +52,12 @@ def __init__(self): for index in range(0, NUM_PSU): psu = Psu(index) self._psu_list.append(psu) + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) + for index in range(0, NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) def get_base_mac(self): """ @@ -92,7 +100,8 @@ def get_reboot_cause(self): status, raw_cause = self._api_helper.ipmi_raw( IPMI_OEM_NETFN, IPMI_GET_REBOOT_CAUSE) - hx_cause = raw_cause.split()[0] if status else 00 + hx_cause = raw_cause.split()[0] if status and len( + raw_cause.split()) > 0 else 00 reboot_cause = { "00": self.REBOOT_CAUSE_HARDWARE_OTHER, "11": self.REBOOT_CAUSE_POWER_LOSS, diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py new file mode 100644 index 000000000000..737908b5b50e --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Component contains an implementation of SONiC Platform Base API and +# provides the components firmware management function +# +############################################################################# + +import json +import os.path + +try: + from sonic_platform_base.component_base import ComponentBase + from helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +COMPONENT_LIST = [ + ("BIOS", "Basic Input/Output System"), + ("BMC", "Baseboard Management Controller"), + ("SWITCH_CPLD", "Switch board CPLD"), + ("BASE_CPLD", "Base board CPLD"), + ("FPGA", "Field-programmable gate array") +] +SW_CPLD_VER_PATH = "/sys/module/switch_cpld/version" +BASE_CPLD_VER_PATH = "/sys/module/baseboard_lpc/version" +CPLD_UPGRADE_OPT = 4 +BIOS_VER_PATH = "/sys/class/dmi/id/bios_version" +BIOS__UPGRADE_OPT = 2 +BMC_VER_CMD = "ipmitool mc info | grep 'Firmware Revision'" +BMC_UPGRADE_OPT = 1 +CFUFLASH_FW_UPGRADE_CMD = "CFUFLASH -cd -d {} -mse 3 {}" +MEM_PCI_RESOURCE = "/sys/bus/pci/devices/0000:09:00.0/resource0" +FPGA_VER_MEM_OFFSET = 0 + + +class Component(ComponentBase): + """Platform-specific Component class""" + + DEVICE_TYPE = "component" + + def __init__(self, component_index): + ComponentBase.__init__(self) + self.index = component_index + self.name = self.get_name() + self._api_helper = APIHelper() + + def __get_bmc_ver(self): + bmc_ver = "Unknown" + status, raw_bmc_data = self._api_helper.run_command(BMC_VER_CMD) + if status: + bmc_ver_data = raw_bmc_data.split(":") + bmc_ver = bmc_ver_data[-1].strip() if len( + bmc_ver_data) > 1 else bmc_ver + return bmc_ver + + def __get_fpga_ver(self): + fpga_ver = "Unknown" + status, reg_val = self._api_helper.pci_get_value( + MEM_PCI_RESOURCE, FPGA_VER_MEM_OFFSET) + if status: + major = reg_val[0] >> 16 + minor = int(bin(reg_val[0])[16:32], 2) + fpga_ver = '{}.{}'.format(major, minor) + return fpga_ver + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return COMPONENT_LIST[self.index][0] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return COMPONENT_LIST[self.index][1] + + def get_firmware_version(self): + """ + Retrieves the firmware version of module + Returns: + string: The firmware versions of the module + """ + fw_version = { + "BIOS": self._api_helper.read_txt_file(BIOS_VER_PATH), + "BMC": self.__get_bmc_ver(), + "FPGA": self.__get_fpga_ver(), + "SWITCH_CPLD": self._api_helper.read_txt_file(SW_CPLD_VER_PATH), + "BASE_CPLD": self._api_helper.read_txt_file(BASE_CPLD_VER_PATH), + }.get(self.name, "Unknown") + + return fw_version + + def install_firmware(self, image_path): + """ + Install firmware to module + Args: + image_path: A string, path to firmware image + Returns: + A boolean, True if install successfully, False if not + """ + install_command = { + "BMC": CFUFLASH_FW_UPGRADE_CMD.format(BMC_UPGRADE_OPT, image_path), + "BIOS": CFUFLASH_FW_UPGRADE_CMD.format(BIOS__UPGRADE_OPT, image_path), + "SWITCH_CPLD": CFUFLASH_FW_UPGRADE_CMD.format(CPLD_UPGRADE_OPT, image_path), + "BASE_CPLD": CFUFLASH_FW_UPGRADE_CMD.format(CPLD_UPGRADE_OPT, image_path) + }.get(self.name, None) + + if not os.path.isfile(image_path) or install_command is None: + return False + + # print(install_command) + status = self._api_helper.run_interactive_command(install_command) + return status diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py index 1132b5b06785..82f0eea6b448 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py @@ -1,8 +1,9 @@ #!/usr/bin/env python import os +import struct import subprocess - +from mmap import * HOST_CHK_CMD = "docker > /dev/null 2>&1" EMPTY_STRING = "" @@ -16,6 +17,39 @@ def __init__(self): def is_host(self): return os.system(HOST_CHK_CMD) == 0 + def pci_get_value(self, resource, offset): + status = True + result = "" + try: + fd = os.open(resource, os.O_RDWR) + mm = mmap(fd, 0) + mm.seek(int(offset)) + read_data_stream = mm.read(4) + result = struct.unpack('I', read_data_stream) + except: + status = False + return status, result + + def run_command(self, cmd): + status = True + result = "" + try: + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + except: + status = False + return status, result + + def run_interactive_command(self, cmd): + try: + os.system(cmd) + except: + return False + return True + def read_txt_file(self, file_path): try: with open(file_path, 'r') as fd: @@ -35,6 +69,8 @@ def ipmi_raw(self, netfn, cmd): raw_data, err = p.communicate() if err == '': result = raw_data.strip() + else: + status = False except: status = False return status, result @@ -51,6 +87,24 @@ def ipmi_fru_id(self, id, key=None): raw_data, err = p.communicate() if err == '': result = raw_data.strip() + else: + status = False + except: + status = False + return status, result + + def ipmi_set_ss_thres(self, id, threshold_key, value): + status = True + result = "" + try: + cmd = "ipmitool sensor thresh '{}' {} {}".format(str(id), str(threshold_key), str(value)) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False except: status = False return status, result diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/thermal.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/thermal.py new file mode 100644 index 000000000000..e3138e6bb897 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/thermal.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Thermal contains an implementation of SONiC Platform Base API and +# provides the thermal device status which are available in the platform +# +############################################################################# + +import os +import re +import os.path + +try: + from sonic_platform_base.thermal_base import ThermalBase + from helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +IPMI_SENSOR_NETFN = "0x04" +IPMI_SS_READ_CMD = "0x2D {}" +IPMI_SS_THRESHOLD_CMD = "0x27 {}" +DEFUALT_LOWER_TRESHOLD = 0.0 +HIGH_TRESHOLD_SET_KEY = "unc" + + +class Thermal(ThermalBase): + """Platform-specific Thermal class""" + + def __init__(self, thermal_index): + ThermalBase.__init__(self) + self._api_helper = APIHelper() + self.index = thermal_index + self.THERMAL_LIST = [ + ('TEMP_FAN_U52', 'Fan Tray Middle Temperature Sensor', '0x00'), + ('TEMP_FAN_U17', 'Fan Tray Right Temperature Sensor', '0x01'), + ('TEMP_SW_U52', 'Switchboard Left Inlet Temperature Sensor', '0x02'), + ('TEMP_SW_U16', 'Switchboard Right Inlet Temperature Sensor', '0x03'), + ('TEMP_BB_U3', 'Baseboard Temperature Sensor', '0x04'), + ('TEMP_CPU', 'CPU Internal Temperature Sensor', '0x05'), + ('TEMP_SW_Internal', 'ASIC Internal Temperature Sensor', '0x61'), + ('SW_U04_Temp', 'IR3595 Chip Left Temperature Sensor', '0x4F'), + ('SW_U14_Temp', 'IR3595 Chip Right Temperature Sensor', '0x56'), + ('SW_U4403_Temp', 'IR3584 Chip Temperature Sensor', '0x5D'), + ] + self.sensor_id = self.THERMAL_LIST[self.index][0] + self.sensor_des = self.THERMAL_LIST[self.index][1] + self.sensor_reading_addr = self.THERMAL_LIST[self.index][2] + def __set_threshold(self, key, value): + print(key, value) + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temperature = 0.0 + status, raw_ss_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(self.sensor_reading_addr)) + if status and len(raw_ss_read.split()) > 0: + ss_read = raw_ss_read.split()[0] + temperature = float(int(ss_read, 16)) + return temperature + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + high_threshold = 0.0 + status, raw_up_thres_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_THRESHOLD_CMD.format(self.sensor_reading_addr)) + if status and len(raw_up_thres_read.split()) > 6: + ss_read = raw_up_thres_read.split()[4] + high_threshold = float(int(ss_read, 16)) + return high_threshold + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return DEFUALT_LOWER_TRESHOLD + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if not + """ + status, ret_txt = self._api_helper.ipmi_set_ss_thres(self.sensor_id, HIGH_TRESHOLD_SET_KEY, temperature) + return status + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if not + """ + return False + + def get_name(self): + """ + Retrieves the name of the thermal device + Returns: + string: The name of the thermal device + """ + return self.THERMAL_LIST[self.index][0] + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + return True if self.get_temperature() > 0 else False + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self.sensor_des + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return "Unknown" + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() \ No newline at end of file From 4c46178ee809bf8ac49151bf708116f689195847 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 16 Jan 2020 09:45:01 +0700 Subject: [PATCH 0294/1427] [device/celestica]: Implement SFP API (#3869) Add Sfp APIs base on SfpBase and SfpUtilBase --- .../sonic_platform/chassis.py | 7 + .../sonic_platform/sfp.py | 1467 +++++++++++++++++ 2 files changed, 1474 insertions(+) create mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py index a3ccc9439ada..b4e2760d0ce9 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py @@ -19,6 +19,7 @@ from sonic_platform.component import Component from sonic_platform.eeprom import Tlv from sonic_platform.fan import Fan + from sonic_platform.sfp import Sfp from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal from helper import APIHelper @@ -49,6 +50,11 @@ def __init__(self): for fan_index in range(0, NUM_FAN): fan = Fan(fant_index, fan_index) self._fan_list.append(fan) + + for index in range(0, NUM_SFP): + sfp = Sfp(index) + self._sfp_list.append(sfp) + for index in range(0, NUM_PSU): psu = Psu(index) self._psu_list.append(psu) @@ -59,6 +65,7 @@ def __init__(self): thermal = Thermal(index) self._thermal_list.append(thermal) + def get_base_mac(self): """ Retrieves the base MAC address for the chassis diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py new file mode 100644 index 000000000000..d0d0f59cd10d --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py @@ -0,0 +1,1467 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +# +############################################################################# + +import os +import time +import subprocess +import sonic_device_util +from ctypes import create_string_buffer + +try: + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_eeprom import eeprom_dts + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 128 +DOM_OFFSET = 0 + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 2 + +XCVR_INTERFACE_DATA_START = 0 +XCVR_INTERFACE_DATA_SIZE = 92 + +QSFP_DOM_BULK_DATA_START = 22 +QSFP_DOM_BULK_DATA_SIZE = 36 +SFP_DOM_BULK_DATA_START = 96 +SFP_DOM_BULK_DATA_SIZE = 10 + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 + +# Offset for values in QSFP eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_VERSION_COMPLIANCE_OFFSET = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_MODULE_MONITOR_OFFSET = 0 +QSFP_MODULE_MONITOR_WIDTH = 9 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_POWEROVERRIDE_BIT = 0 +QSFP_POWERSET_BIT = 1 +QSFP_OPTION_VALUE_OFFSET = 192 +QSFP_OPTION_VALUE_WIDTH = 4 +QSFP_MODULE_UPPER_PAGE3_START = 384 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 24 + +SFP_MODULE_ADDRA2_OFFSET = 256 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_CHANNL_STATUS_OFFSET = 110 +SFP_CHANNL_STATUS_WIDTH = 1 + + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +SFP_TYPE = "SFP" +QSFP_TYPE = "QSFP" +OSFP_TYPE = "OSFP" + +PORT_START = 1 +PORT_END = 34 +OSFP_PORT_START = 1 +OSFP_PORT_END = 32 +SFP_PORT_START = 33 +SFP_PORT_END = 34 + +PORT_INFO_PATH = '/sys/devices/platform/cls-xcvr' + + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + # Path to QSFP sysfs + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + HOST_CHK_CMD = "docker > /dev/null 2>&1" + + PLATFORM = "x86_64-cel_silverstone-r0" + HWSKU = "Silverstone" + + def __init__(self, sfp_index): + SfpBase.__init__(self) + # Init index + self.index = sfp_index + self.port_num = self.index + 1 + self.dom_supported = False + self.sfp_type, self.port_name = self.__get_sfp_info() + + # Init eeprom path + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' + self.port_to_eeprom_mapping = {} + self.port_to_i2c_mapping = { + 1: 10, + 2: 11, + 3: 12, + 4: 13, + 5: 14, + 6: 15, + 7: 16, + 8: 17, + 9: 18, + 10: 19, + 11: 20, + 12: 21, + 13: 22, + 14: 23, + 15: 24, + 16: 25, + 17: 26, + 18: 27, + 19: 28, + 20: 29, + 21: 30, + 22: 31, + 23: 32, + 24: 33, + 25: 34, + 26: 35, + 27: 36, + 28: 37, + 29: 38, + 30: 39, + 31: 40, + 32: 41, + 33: 1, + 34: 2 + } + + for x in range(PORT_START, PORT_END + 1): + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path + + self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + self._dom_capability_detect() + + def __get_sfp_info(self): + port_num = self.index + PORT_START + sfp_type = OSFP_PORT_START + port_name = "Unknown" + + if port_num >= OSFP_PORT_START and port_num <= OSFP_PORT_END: + sfp_type = OSFP_TYPE + port_name = "QSFP" + str(port_num - OSFP_PORT_START + 1) + elif port_num >= SFP_PORT_START and port_num <= SFP_PORT_END: + sfp_type = SFP_TYPE + port_name = "SFP" + str(port_num - SFP_PORT_START + 1) + return sfp_type, port_name + + def __convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def _dom_capability_detect(self): + if not self.get_presence(): + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + return + + if self.sfp_type == "QSFP": + self.calibration = 1 + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + offset = 128 + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qsfp_version_compliance_raw = self.__read_eeprom_specific_bytes( + QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH) + qsfp_version_compliance = int( + qsfp_version_compliance_raw[0], 16) + dom_capability = sfpi_obj.parse_qsfp_dom_capability( + qsfp_dom_capability_raw, 0) + if qsfp_version_compliance >= 0x08: + self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On' + self.dom_volt_supported = dom_capability['data']['Voltage_support']['value'] == 'On' + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' + self.dom_tx_power_supported = dom_capability['data']['Tx_power_support']['value'] == 'On' + else: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' + self.dom_tx_power_supported = True + + self.dom_supported = True + self.calibration = 1 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + qsfp_option_value_raw = self.__read_eeprom_specific_bytes( + QSFP_OPTION_VALUE_OFFSET, QSFP_OPTION_VALUE_WIDTH) + if qsfp_option_value_raw is not None: + optional_capability = sfpd_obj.parse_option_params( + qsfp_option_value_raw, 0) + self.dom_tx_disable_supported = optional_capability[ + 'data']['TxDisable']['value'] == 'On' + dom_status_indicator = sfpd_obj.parse_dom_status_indicator( + qsfp_version_compliance_raw, 1) + self.qsfp_page3_available = dom_status_indicator['data']['FlatMem']['value'] == 'Off' + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.qsfp_page3_available = False + + elif self.sfp_type == "SFP": + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + return None + sfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) + self.dom_supported = (sfp_dom_capability & 0x40 != 0) + if self.dom_supported: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + if sfp_dom_capability & 0x20 != 0: + self.calibration = 1 + elif sfp_dom_capability & 0x10 != 0: + self.calibration = 2 + else: + self.calibration = 0 + else: + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.dom_tx_disable_supported = ( + int(sfp_dom_capability_raw[1], 16) & 0x40 != 0) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + compliance_code_dict = {} + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + if not self.get_presence(): + return transceiver_info_dict + + # ToDo: OSFP tranceiver info parsing not fully supported. + # in inf8628.py lack of some memory map definition + # will be implemented when the inf8628 memory map ready + if self.sfp_type == OSFP_TYPE: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + + sfpi_obj = inf8628InterfaceId() + if sfpi_obj is None: + return None + + sfp_type_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + else: + return None + + transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = 'N/A' + transceiver_info_dict['vendor_date'] = 'N/A' + transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['encoding'] = 'N/A' + transceiver_info_dict['ext_identifier'] = 'N/A' + transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' + transceiver_info_dict['cable_type'] = 'N/A' + transceiver_info_dict['cable_length'] = 'N/A' + transceiver_info_dict['specification_compliance'] = 'N/A' + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + + else: + if self.sfp_type == QSFP_TYPE: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) + if sfp_interface_bulk_raw is None: + return None + + start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START + end = start + interface_info_bulk_width + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_NAME_WIDTH + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_PN_WIDTH + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START + end = start + vendor_rev_width + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_SN_WIDTH + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_OUI_WIDTH + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_DATE_WIDTH + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_interface_bulk_raw[start: end], 0) + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + if self.sfp_type == QSFP_TYPE: + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + + if self.sfp_type == OSFP_TYPE: + pass + + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported: + return transceiver_dom_info_dict + + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_data_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_DOM_BULK_DATA_START), QSFP_DOM_BULK_DATA_SIZE) + if dom_data_raw is None: + return transceiver_dom_info_dict + + if self.dom_temp_supported: + start = QSFP_TEMPE_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + temp = self.__convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + if temp is not None: + transceiver_dom_info_dict['temperature'] = temp + + if self.dom_volt_supported: + start = QSFP_VOLT_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + volt = self.__convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + if volt is not None: + transceiver_dom_info_dict['voltage'] = volt + + start = QSFP_CHANNL_MON_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_data_raw[start: end], 0) + + if self.dom_tx_power_supported: + transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX1Power']['value']) + transceiver_dom_info_dict['tx2power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX2Power']['value']) + transceiver_dom_info_dict['tx3power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX3Power']['value']) + transceiver_dom_info_dict['tx4power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX4Power']['value']) + + if self.dom_rx_power_supported: + transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX1Power']['value']) + transceiver_dom_info_dict['rx2power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX2Power']['value']) + transceiver_dom_info_dict['rx3power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX3Power']['value']) + transceiver_dom_info_dict['rx4power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX4Power']['value']) + + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + if not self.dom_supported: + return transceiver_dom_info_dict + + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + sfpd_obj._calibration_type = self.calibration + + dom_data_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE) + + start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + + start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + + start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_CHANNL_MON_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_data_raw[start: end], 0) + + transceiver_dom_info_dict['temperature'] = self.__convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + transceiver_dom_info_dict['voltage'] = self.__convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value']) + transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXBias']['value']) + transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value']) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') + + if self.sfp_type == OSFP_TYPE: + pass + + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported or not self.qsfp_page3_available: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = QSFP_MODULE_UPPER_PAGE3_START + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values( + dom_module_threshold_raw, 0) + + dom_channel_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is None: + return transceiver_dom_threshold_info_dict + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values( + dom_channel_threshold_raw, 0) + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + + else: + offset = SFP_MODULE_ADDRA2_OFFSET + + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = sff8472Dom(None, self.calibration) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[ + 'data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + if not self.dom_supported: + return False + + if self.sfp_type == OSFP_TYPE: + return False + elif self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + dom_module_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_MODULE_MONITOR_OFFSET), QSFP_MODULE_MONITOR_WIDTH) + + if dom_module_monitor_raw is not None: + return True + else: + return False + elif self.sfp_type == SFP_TYPE: + offset = 0 + sfpd_obj = sff8472Dom() + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + + if dom_channel_monitor_raw is not None: + return True + else: + return False + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + if not self.dom_supported: + return None + + rx_los_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x02 != 0) + else: + return None + return rx_los_list + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + if not self.dom_supported: + return None + + tx_fault_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + else: + return None + return tx_fault_list + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + if not self.dom_supported: + return None + + tx_disable_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0xC0 != 0) + else: + return None + return tx_disable_list + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + return tx_disabled + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + if self.sfp_type != OSFP_TYPE: + return False + + try: + reg_file = open( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_lpmode"])) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + # Read status + content = reg_file.readline().rstrip() + reg_value = int(content) + # low power mode is active high + if reg_value == 0: + return False + + return True + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + if self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes( + dom_control_raw, 0) + power_override = ( + 'On' == dom_control_data['data']['PowerOverride']['value']) + else: + return False + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + transceiver_bulk_status = self.get_transceiver_bulk_status() + return transceiver_bulk_status.get("temperature", "N/A") + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + transceiver_bulk_status = self.get_transceiver_bulk_status() + return transceiver_bulk_status.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_bulk_status = self.get_transceiver_bulk_status() + tx1_bs = transceiver_bulk_status.get("tx1bias", "N/A") + tx2_bs = transceiver_bulk_status.get("tx2bias", "N/A") + tx3_bs = transceiver_bulk_status.get("tx3bias", "N/A") + tx4_bs = transceiver_bulk_status.get("tx4bias", "N/A") + tx_bias_list = [tx1_bs, tx2_bs, tx3_bs, tx4_bs] + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + rx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX1Power']['value'])) + rx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX2Power']['value'])) + rx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX3Power']['value'])) + rx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX4Power']['value'])) + else: + return None + else: + return None + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + rx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value'])) + else: + return None + else: + return None + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + tx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX1Power']['value'])) + tx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX2Power']['value'])) + tx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX3Power']['value'])) + tx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX4Power']['value'])) + else: + return None + else: + return None + else: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + tx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value'])) + else: + return None + else: + return None + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + if self.sfp_type != OSFP_TYPE: + return False + + try: + reg_file = open( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_resetL"]), "w") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(0)) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + reg_file = open( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_resetL"]), "w") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + reg_file.seek(0) + reg_file.write(hex(1)) + reg_file.close() + + return True + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + tx_disable_ctl = 0xf if tx_disable else 0x0 + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + channel_state = self.get_tx_disable_channel() + tx_enable_mask = [0xe, 0xd, 0xb, 0x7] + tx_disable_mask = [0x1, 0x3, 0x7, 0xf] + tx_disable_ctl = channel_state | tx_disable_mask[ + channel] if disable else channel_state & tx_enable_mask[channel] + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + if self.sfp_type != OSFP_TYPE: + return False + + try: + reg_file = open( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_lpmode"]), "r+") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + content = hex(lpmode) + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + if self.sfp_type == QSFP_TYPE: + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + sysfs_filename = "sfp_modabs" if self.sfp_type == SFP_TYPE else "qsfp_modprsL" + reg_path = "/".join([PORT_INFO_PATH, self.port_name, sysfs_filename]) + + # Read status + try: + reg_file = open(reg_path) + content = reg_file.readline().rstrip() + reg_value = int(content) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + # Module present is active low + if reg_value == 0: + return True + + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("modelname", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("serialnum", "N/A") + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() From 2eda2d815607e7ab63436d94d07c4405fb9b0954 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Thu, 16 Jan 2020 16:11:49 -0800 Subject: [PATCH 0295/1427] [sonic-py-swsssdk] update submodule for sonic-py-swsssdk (#4031) * [MultiDB]: update sonic-db-cli output to redis-cli output format (#59) Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index ccc1307aae0b..0b4099954498 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit ccc1307aae0b017a5c0d92385c9df67379da6d22 +Subproject commit 0b4099954498c4e6fef57a8535d18a2c1fa198b4 From 4e3bf842c76a81847af7368db716a7108df0a0a4 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Thu, 16 Jan 2020 16:12:28 -0800 Subject: [PATCH 0296/1427] [mgmt-framework] submodule update (#4030) 00410e5 (HEAD, origin/master, origin/HEAD) [mgmt-framework] Update Swagger URL to repo1.maven.org (#37) 7562028 Merge pull request #36 from Azure/Arlo cd22b4d (origin/Arlo) Added the certificate check to quiet 7fbcd46 Changed the swagger website to https 5d1041f Added sonic-mgmt-framework deb install to install the contents of sonic-mgmt-framework deb package (#30) 229fe69 Added sonic-mgmt-framework deb install to install the contents of sonic-mgmt-framework deb package signed-off-by: Tamer Ahmed --- src/sonic-mgmt-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework index 8b199a9f822c..00410e5516ec 160000 --- a/src/sonic-mgmt-framework +++ b/src/sonic-mgmt-framework @@ -1 +1 @@ -Subproject commit 8b199a9f822ca42564a7a89da0cab3133684bd12 +Subproject commit 00410e5516ec4dce957c6bb1fdd0258ef47bfafa From d150721fa1b2f5c68fc7ec7978a4ba42b9a4c08c Mon Sep 17 00:00:00 2001 From: kannankvs Date: Fri, 17 Jan 2020 09:06:49 +0530 Subject: [PATCH 0297/1427] =?UTF-8?q?modified=20down=20rules=20to=20pre-do?= =?UTF-8?q?wn=20rules=20to=20ensure=20that=20default=20route=20is=E2=80=A6?= =?UTF-8?q?=20(#3853)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * modified down rules to pre-down rules to ensure that default route is deleted just before interface is made down --- files/image_config/interfaces/interfaces.j2 | 24 +++++++++---------- .../tests/sample_output/interfaces | 12 +++++----- .../tests/sample_output/mvrf_interfaces | 22 ++++++++--------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 8b8ea0b52bc8..dbb2b1f3418a 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -5,23 +5,23 @@ # file: /etc/network/interfaces # {% endblock banner %} +{% block mgmt_vrf %} {% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} auto mgmt iface mgmt vrf-table 5000 -{% endif %} -{% block loopback %} -# The loopback network interface -auto lo -iface lo inet loopback -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} # The loopback network interface for mgmt VRF that is required for applications like NTP up ip link add lo-m type dummy + up ip link set dev lo-m master mgmt up ip addr add 127.0.0.1/8 dev lo-m up ip link set lo-m up - up ip link set dev lo-m master mgmt - down ip link delete dev lo-m + down ip link delete dev lo-m {% endif %} +{% endblock mgmt_vrf %} +{% block loopback %} +# The loopback network interface +auto lo +iface lo inet loopback {% endblock loopback %} {% block mgmt_interface %} @@ -82,14 +82,14 @@ iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static up ip rule add to {{ route }} table {{ vrf_table }} {% endfor %} # management port down rules - down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} - down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} - down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} + pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} + pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} + pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} {% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} down cgdelete -g l3mdev:mgmt {% endif %} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} - down ip rule delete to {{ route }} table {{ vrf_table }} + pre-down ip rule delete to {{ route }} table {{ vrf_table }} {% endfor %} {# TODO: COPP policy type rules #} {% endfor %} diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index d3921bcbab4d..913fc8531443 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -18,9 +18,9 @@ iface eth0 inet static up ip -4 route add 10.0.0.0/24 dev eth0 table default up ip -4 rule add from 10.0.0.100/32 table default # management port down rules - down ip -4 route delete default via 10.0.0.1 dev eth0 table default - down ip -4 route delete 10.0.0.0/24 dev eth0 table default - down ip -4 rule delete from 10.0.0.100/32 table default + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default + pre-down ip -4 rule delete from 10.0.0.100/32 table default iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 @@ -30,9 +30,9 @@ iface eth0 inet6 static up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default up ip -6 rule add from 2603:10e2:0:2902::8/128 table default # management port down rules - down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default - down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default - down ip -6 rule delete from 2603:10e2:0:2902::8/128 table default + pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default + pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default + pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table default # source /etc/network/interfaces.d/* # diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces index afd0615b81e9..7bd664d4a9db 100644 --- a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces @@ -6,15 +6,15 @@ auto mgmt iface mgmt vrf-table 5000 -# The loopback network interface -auto lo -iface lo inet loopback # The loopback network interface for mgmt VRF that is required for applications like NTP up ip link add lo-m type dummy + up ip link set dev lo-m master mgmt up ip addr add 127.0.0.1/8 dev lo-m up ip link set lo-m up - up ip link set dev lo-m master mgmt - down ip link delete dev lo-m + down ip link delete dev lo-m +# The loopback network interface +auto lo +iface lo inet loopback # The management network interface auto eth0 @@ -30,9 +30,9 @@ iface eth0 inet static up cgcreate -g l3mdev:mgmt up cgset -r l3mdev.master-device=mgmt mgmt # management port down rules - down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 - down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 - down ip -4 rule delete from 10.0.0.100/32 table 5000 + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 + pre-down ip -4 rule delete from 10.0.0.100/32 table 5000 down cgdelete -g l3mdev:mgmt iface eth0 inet6 static address 2603:10e2:0:2902::8 @@ -46,9 +46,9 @@ iface eth0 inet6 static up cgcreate -g l3mdev:mgmt up cgset -r l3mdev.master-device=mgmt mgmt # management port down rules - down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 - down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 - down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 + pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 + pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 + pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 down cgdelete -g l3mdev:mgmt # source /etc/network/interfaces.d/* From b45d2b4130cebf1b5dd7aadaf6cc055307682e9a Mon Sep 17 00:00:00 2001 From: byu343 Date: Fri, 17 Jan 2020 10:36:12 -0800 Subject: [PATCH 0298/1427] [arista]: Add support for bald eagle phy (#3922) * Add support for bald edgle phy --- platform/broadcom/one-aboot.mk | 1 + rules/phy-credo.mk | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 rules/phy-credo.mk diff --git a/platform/broadcom/one-aboot.mk b/platform/broadcom/one-aboot.mk index 66f3ca8797f4..f68319ab6449 100644 --- a/platform/broadcom/one-aboot.mk +++ b/platform/broadcom/one-aboot.mk @@ -4,6 +4,7 @@ SONIC_ONE_ABOOT_IMAGE = sonic-aboot-broadcom.swi $(SONIC_ONE_ABOOT_IMAGE)_MACHINE = broadcom $(SONIC_ONE_ABOOT_IMAGE)_IMAGE_TYPE = aboot $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(BRCM_OPENNSL_KERNEL) $(ARISTA_PLATFORM_MODULE_DRIVERS) $(ARISTA_PLATFORM_MODULE_PYTHON2) $(ARISTA_PLATFORM_MODULE_PYTHON3) $(ARISTA_PLATFORM_MODULE) +$(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(PHY_CREDO) $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_ABOOT_IMAGE) diff --git a/rules/phy-credo.mk b/rules/phy-credo.mk new file mode 100644 index 000000000000..f132498ec211 --- /dev/null +++ b/rules/phy-credo.mk @@ -0,0 +1,3 @@ +PHY_CREDO = phy-credo_1.0_amd64.deb +$(PHY_CREDO)_URL = "https://github.com/aristanetworks/sonic-firmware/raw/78a3df2/phy/phy-credo_1.0_amd64.deb" +SONIC_ONLINE_DEBS += $(PHY_CREDO) From 64500e143b040c2be296a5e14363d1cc6e8003db Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 17 Jan 2020 10:44:49 -0800 Subject: [PATCH 0299/1427] [Arista] Update drivers and boot script (#3959) * Update arista driver submodule * Add support for 7260CX3-64E in boot0 * Refactor boot0 platform specific definition Make it easier to manage new sku * Add support for 7050CX3-32S in boot0 Just contains the required boot0 information * Add basic plugin support for DCS-7050CX3-32S * Add port config for Arista-7050CX3-32S-C32 Co-authored-by: yurypm Co-authored-by: byu343 --- .../Arista-7050CX3-32S-C32/port_config.ini | 35 ++ .../Arista-7050CX3-32S-C32/sai.profile | 1 + .../td3-a7050cx3-32s-32x100G.config.bcm | 503 ++++++++++++++++++ .../x86_64-arista_7050cx3_32s/default_sku | 1 + .../x86_64-arista_7050cx3_32s/platform_reboot | 1 + .../arista/x86_64-arista_7050cx3_32s/plugins | 1 + .../x86_64-arista_7050cx3_32s/sensors.conf | 39 ++ files/Aboot/boot0.j2 | 61 ++- .../barefoot/sonic-platform-modules-arista | 2 +- .../broadcom/sonic-platform-modules-arista | 2 +- 10 files changed, 624 insertions(+), 22 deletions(-) create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/port_config.ini create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm create mode 100644 device/arista/x86_64-arista_7050cx3_32s/default_sku create mode 120000 device/arista/x86_64-arista_7050cx3_32s/platform_reboot create mode 120000 device/arista/x86_64-arista_7050cx3_32s/plugins create mode 100644 device/arista/x86_64-arista_7050cx3_32s/sensors.conf diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/port_config.ini b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/port_config.ini new file mode 100644 index 000000000000..d3d339076a59 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias index +Ethernet0 1,2,3,4 Ethernet1/1 1 +Ethernet4 5,6,7,8 Ethernet2/1 2 +Ethernet8 9,10,11,12 Ethernet3/1 3 +Ethernet12 13,14,15,16 Ethernet4/1 4 +Ethernet16 21,22,23,24 Ethernet5/1 5 +Ethernet20 17,18,19,20 Ethernet6/1 6 +Ethernet24 25,26,27,28 Ethernet7/1 7 +Ethernet28 29,30,31,32 Ethernet8/1 8 +Ethernet32 37,38,39,40 Ethernet9/1 9 +Ethernet36 33,34,35,36 Ethernet10/1 10 +Ethernet40 41,42,43,44 Ethernet11/1 11 +Ethernet44 45,46,47,48 Ethernet12/1 12 +Ethernet48 53,54,55,56 Ethernet13/1 13 +Ethernet52 49,50,51,52 Ethernet14/1 14 +Ethernet56 57,58,59,60 Ethernet15/1 15 +Ethernet60 61,62,63,64 Ethernet16/1 16 +Ethernet64 69,70,71,72 Ethernet17/1 17 +Ethernet68 65,66,67,68 Ethernet18/1 18 +Ethernet72 73,74,75,76 Ethernet19/1 19 +Ethernet76 77,78,79,80 Ethernet20/1 20 +Ethernet80 85,86,87,88 Ethernet21/1 21 +Ethernet84 81,82,83,84 Ethernet22/1 22 +Ethernet88 89,90,91,92 Ethernet23/1 23 +Ethernet92 93,94,95,96 Ethernet24/1 24 +Ethernet96 101,102,103,104 Ethernet25/1 25 +Ethernet100 97,98,99,100 Ethernet26/1 26 +Ethernet104 105,106,107,108 Ethernet27/1 27 +Ethernet108 109,110,111,112 Ethernet28/1 28 +Ethernet112 117,118,119,120 Ethernet29/1 29 +Ethernet116 113,114,115,116 Ethernet30/1 30 +Ethernet120 121,122,123,124 Ethernet31/1 31 +Ethernet124 125,126,127,128 Ethernet32/1 32 +Ethernet128 129 Ethernet33 33 +Ethernet132 128 Ethernet34 34 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile new file mode 100644 index 000000000000..d359ffc15cba --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-a7050cx3-32s-32x100G.config.bcm diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm new file mode 100644 index 000000000000..217d15b4e579 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm @@ -0,0 +1,503 @@ +arl_clean_timeout_usec=15000000 +asf_mem_profile=2 +bcm_num_cos=8 +bcm_stat_flags=1 +bcm_stat_jumbo=9236 +bcm_tunnel_term_compatible_mode=1 +cdma_timeout_usec=15000000 +core_clock_frequency=1525 +dma_desc_timeout_usec=15000000 +dpp_clock_ratio=2:3 +fpem_mem_entries=0 +higig2_hdr_mode=1 +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l2xmsg_mode=1 +l3_alpm_enable=2 +l3_max_ecmp_mode=1 +l3_mem_entries=16384 +max_vp_lags=0 +miim_intr_enable=0 +module_64ports=1 +multicast_l2_range=16383 +multicast_l3_range=0 +os=unix +oversubscribe_mode=1 +pbmp_xport_xe=0x4888888888888888c2222222222222222 +PHY_AN_ALLOW_PLL_CHANGE=1 +phy_an_c37_130=2 +phy_an_c37_66=2 +phy_an_c73=1 +port_flex_enable=1 +port_init_autoneg=0 +port_phy_addr=0xff +robust_hash_disable_egress_vlan=1 +robust_hash_disable_mpls=1 +robust_hash_disable_vlan=1 +sram_scan_enable=0 +stable_size=0x5500000 +tdma_timeout_usec=15000000 +tslam_timeout_usec=15000000 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_rx_lane_map_physical{101.0}=0x0213 +phy_chain_rx_lane_map_physical{105.0}=0x2031 +phy_chain_rx_lane_map_physical{109.0}=0x0213 +phy_chain_rx_lane_map_physical{113.0}=0x2130 +phy_chain_rx_lane_map_physical{117.0}=0x0213 +phy_chain_rx_lane_map_physical{121.0}=0x2031 +phy_chain_rx_lane_map_physical{125.0}=0x0213 +phy_chain_rx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_lane_map_physical{13.0}=0x3120 +phy_chain_rx_lane_map_physical{17.0}=0x1203 +phy_chain_rx_lane_map_physical{21.0}=0x3120 +phy_chain_rx_lane_map_physical{25.0}=0x3120 +phy_chain_rx_lane_map_physical{29.0}=0x3120 +phy_chain_rx_lane_map_physical{33.0}=0x1203 +phy_chain_rx_lane_map_physical{37.0}=0x3120 +phy_chain_rx_lane_map_physical{41.0}=0x3120 +phy_chain_rx_lane_map_physical{45.0}=0x3120 +phy_chain_rx_lane_map_physical{49.0}=0x1203 +phy_chain_rx_lane_map_physical{5.0}=0x3120 +phy_chain_rx_lane_map_physical{53.0}=0x3120 +phy_chain_rx_lane_map_physical{57.0}=0x3120 +phy_chain_rx_lane_map_physical{61.0}=0x3120 +phy_chain_rx_lane_map_physical{65.0}=0x2130 +phy_chain_rx_lane_map_physical{69.0}=0x0213 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_rx_lane_map_physical{77.0}=0x0213 +phy_chain_rx_lane_map_physical{81.0}=0x2130 +phy_chain_rx_lane_map_physical{85.0}=0x0213 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_rx_lane_map_physical{9.0}=0x3120 +phy_chain_rx_lane_map_physical{93.0}=0x0213 +phy_chain_rx_lane_map_physical{97.0}=0x2130 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{109.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{56.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_lane_map_physical{1.0}=0x3021 +phy_chain_tx_lane_map_physical{101.0}=0x3120 +phy_chain_tx_lane_map_physical{105.0}=0x1302 +phy_chain_tx_lane_map_physical{109.0}=0x2130 +phy_chain_tx_lane_map_physical{113.0}=0x1302 +phy_chain_tx_lane_map_physical{117.0}=0x3120 +phy_chain_tx_lane_map_physical{121.0}=0x1302 +phy_chain_tx_lane_map_physical{125.0}=0x3120 +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_tx_lane_map_physical{13.0}=0x0213 +phy_chain_tx_lane_map_physical{17.0}=0x2031 +phy_chain_tx_lane_map_physical{21.0}=0x0213 +phy_chain_tx_lane_map_physical{25.0}=0x2031 +phy_chain_tx_lane_map_physical{29.0}=0x1203 +phy_chain_tx_lane_map_physical{33.0}=0x2031 +phy_chain_tx_lane_map_physical{37.0}=0x0213 +phy_chain_tx_lane_map_physical{41.0}=0x2031 +phy_chain_tx_lane_map_physical{45.0}=0x1203 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_tx_lane_map_physical{5.0}=0x1203 +phy_chain_tx_lane_map_physical{53.0}=0x0213 +phy_chain_tx_lane_map_physical{57.0}=0x2031 +phy_chain_tx_lane_map_physical{61.0}=0x1203 +phy_chain_tx_lane_map_physical{65.0}=0x1302 +phy_chain_tx_lane_map_physical{69.0}=0x1302 +phy_chain_tx_lane_map_physical{73.0}=0x1302 +phy_chain_tx_lane_map_physical{77.0}=0x2130 +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_tx_lane_map_physical{85.0}=0x3120 +phy_chain_tx_lane_map_physical{89.0}=0x1302 +phy_chain_tx_lane_map_physical{9.0}=0x0213 +phy_chain_tx_lane_map_physical{93.0}=0x2130 +phy_chain_tx_lane_map_physical{97.0}=0x1302 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x1 +phy_chain_tx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x0 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x0 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_tx_polarity_flip_physical{129.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{131.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x0 +phy_chain_tx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x0 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x1 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +portmap_103=101:100 +portmap_107=105:100 +portmap_1=1:100 +portmap_111=109:100 +portmap_115=113:100 +portmap_119=117:100 +portmap_123=121:100 +portmap_127=125:100 +portmap_130=128:10:m +portmap_13=13:100 +portmap_17=17:100 +portmap_21=21:100 +portmap_25=25:100 +portmap_29=29:100 +portmap_33=33:100 +portmap_37=37:100 +portmap_41=41:100 +portmap_45=45:100 +portmap_49=49:100 +portmap_53=53:100 +portmap_5=5:100 +portmap_57=57:100 +portmap_61=61:100 +portmap_66=129:10:m +portmap_67=65:100 +portmap_71=69:100 +portmap_75=73:100 +portmap_79=77:100 +portmap_83=81:100 +portmap_87=85:100 +portmap_91=89:100 +portmap_95=93:100 +portmap_9=9:100 +portmap_99=97:100 +serdes_core_rx_polarity_flip_physical{101}=0x9 +serdes_core_rx_polarity_flip_physical{105}=0x7 +serdes_core_rx_polarity_flip_physical{109}=0xc +serdes_core_rx_polarity_flip_physical{1}=0x8 +serdes_core_rx_polarity_flip_physical{113}=0xb +serdes_core_rx_polarity_flip_physical{117}=0xc +serdes_core_rx_polarity_flip_physical{121}=0x7 +serdes_core_rx_polarity_flip_physical{125}=0xc +serdes_core_rx_polarity_flip_physical{129}=0x0 +serdes_core_rx_polarity_flip_physical{13}=0x3 +serdes_core_rx_polarity_flip_physical{17}=0x4 +serdes_core_rx_polarity_flip_physical{21}=0x3 +serdes_core_rx_polarity_flip_physical{25}=0x6 +serdes_core_rx_polarity_flip_physical{29}=0x3 +serdes_core_rx_polarity_flip_physical{33}=0x4 +serdes_core_rx_polarity_flip_physical{37}=0x3 +serdes_core_rx_polarity_flip_physical{41}=0xc +serdes_core_rx_polarity_flip_physical{45}=0x3 +serdes_core_rx_polarity_flip_physical{49}=0x4 +serdes_core_rx_polarity_flip_physical{5}=0x2 +serdes_core_rx_polarity_flip_physical{53}=0x3 +serdes_core_rx_polarity_flip_physical{57}=0xc +serdes_core_rx_polarity_flip_physical{61}=0x3 +serdes_core_rx_polarity_flip_physical{65}=0xb +serdes_core_rx_polarity_flip_physical{69}=0xc +serdes_core_rx_polarity_flip_physical{73}=0x7 +serdes_core_rx_polarity_flip_physical{77}=0xc +serdes_core_rx_polarity_flip_physical{81}=0xb +serdes_core_rx_polarity_flip_physical{85}=0xc +serdes_core_rx_polarity_flip_physical{89}=0x7 +serdes_core_rx_polarity_flip_physical{9}=0xc +serdes_core_rx_polarity_flip_physical{93}=0xc +serdes_core_rx_polarity_flip_physical{97}=0xb +serdes_core_tx_polarity_flip_physical{101}=0x6 +serdes_core_tx_polarity_flip_physical{105}=0x1 +serdes_core_tx_polarity_flip_physical{109}=0x3 +serdes_core_tx_polarity_flip_physical{1}=0x3 +serdes_core_tx_polarity_flip_physical{113}=0x0 +serdes_core_tx_polarity_flip_physical{117}=0x3 +serdes_core_tx_polarity_flip_physical{121}=0x1 +serdes_core_tx_polarity_flip_physical{125}=0x3 +serdes_core_tx_polarity_flip_physical{129}=0x0 +serdes_core_tx_polarity_flip_physical{13}=0xb +serdes_core_tx_polarity_flip_physical{17}=0x0 +serdes_core_tx_polarity_flip_physical{21}=0x3 +serdes_core_tx_polarity_flip_physical{25}=0x4 +serdes_core_tx_polarity_flip_physical{29}=0xc +serdes_core_tx_polarity_flip_physical{33}=0xf +serdes_core_tx_polarity_flip_physical{37}=0xc +serdes_core_tx_polarity_flip_physical{41}=0xe +serdes_core_tx_polarity_flip_physical{45}=0xc +serdes_core_tx_polarity_flip_physical{49}=0xf +serdes_core_tx_polarity_flip_physical{5}=0xb +serdes_core_tx_polarity_flip_physical{53}=0xc +serdes_core_tx_polarity_flip_physical{57}=0xe +serdes_core_tx_polarity_flip_physical{61}=0xc +serdes_core_tx_polarity_flip_physical{65}=0xf +serdes_core_tx_polarity_flip_physical{69}=0xe +serdes_core_tx_polarity_flip_physical{73}=0xe +serdes_core_tx_polarity_flip_physical{77}=0xc +serdes_core_tx_polarity_flip_physical{81}=0xf +serdes_core_tx_polarity_flip_physical{85}=0xc +serdes_core_tx_polarity_flip_physical{89}=0xe +serdes_core_tx_polarity_flip_physical{9}=0x3 +serdes_core_tx_polarity_flip_physical{93}=0xc +serdes_core_tx_polarity_flip_physical{97}=0xf +serdes_preemphasis_1=0x14410a +serdes_preemphasis_5=0x14410a +serdes_preemphasis_9=0x14410a +serdes_preemphasis_13=0x14410a +serdes_preemphasis_17=0x14410a +serdes_preemphasis_21=0x14410a +serdes_preemphasis_25=0x14410a +serdes_preemphasis_29=0x14410a +serdes_preemphasis_33=0x14410a +serdes_preemphasis_37=0x14410a +serdes_preemphasis_41=0x14410a +serdes_preemphasis_45=0x14410a +serdes_preemphasis_49=0xf5005 +serdes_preemphasis_53=0xf5005 +serdes_preemphasis_57=0xf5005 +serdes_preemphasis_61=0xf5005 +serdes_driver_current_66=0xe +serdes_preemphasis_66=0x102804 +serdes_preemphasis_67=0xf5005 +serdes_preemphasis_71=0xf5005 +serdes_preemphasis_75=0xf5005 +serdes_preemphasis_79=0xf5005 +serdes_preemphasis_83=0x14410a +serdes_preemphasis_87=0x14410a +serdes_preemphasis_91=0x14410a +serdes_preemphasis_95=0x14410a +serdes_preemphasis_99=0x14410a +serdes_preemphasis_103=0x14410a +serdes_preemphasis_107=0x14410a +serdes_preemphasis_111=0x14410a +serdes_preemphasis_115=0x14410a +serdes_preemphasis_119=0x14410a +serdes_preemphasis_123=0x14410a +serdes_preemphasis_127=0x14410a +serdes_driver_current_130=0xe +serdes_preemphasis_130=0x102804 diff --git a/device/arista/x86_64-arista_7050cx3_32s/default_sku b/device/arista/x86_64-arista_7050cx3_32s/default_sku new file mode 100644 index 000000000000..bff7a549cb2c --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/default_sku @@ -0,0 +1 @@ +Arista-7050CX3-32S-C32 t1 diff --git a/device/arista/x86_64-arista_7050cx3_32s/platform_reboot b/device/arista/x86_64-arista_7050cx3_32s/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins b/device/arista/x86_64-arista_7050cx3_32s/plugins new file mode 120000 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/sensors.conf b/device/arista/x86_64-arista_7050cx3_32s/sensors.conf new file mode 100644 index 000000000000..9501656fb9aa --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/sensors.conf @@ -0,0 +1,39 @@ +# libsensors configuration file for DCS-7050CX3-32S +# ------------------------------------------------ +# + +bus "i2c-2" "SCD 0000:02:00.0 SMBus master 0 bus 0" +bus "i2c-11" "SCD 0000:02:00.0 SMBus master 1 bus 1" +bus "i2c-13" "SCD 0000:02:00.0 SMBus master 1 bus 3" +bus "i2c-14" "SCD 0000:02:00.0 SMBus master 1 bus 4" + +chip "k10temp-pci-00c3" + label temp1 "Cpu temp sensor" + +chip "max6658-i2c-2-4c" + label temp1 "Cpu board temp sensor" + set temp1_max 75 + set temp1_crit 80 + + label temp2 "Back panel temp sensor" + set temp2_max 75 + set temp2_crit 85 + +chip "max6658-i2c-11-4c" + label temp1 "Board temp sensor" + set temp1_max 55 + set temp1_crit 70 + + label temp2 "Front panel temp sensor" + set temp2_max 60 + set temp2_crit 65 + +chip "pmbus-i2c-13-58" + label temp1 "Power supply 1 hotspot sensor" + label temp2 "Power supply 1 inlet temp sensor" + label temp3 "Power supply 1 sensor" + +chip "pmbus-i2c-14-58" + label temp1 "Power supply 2 hotspot sensor" + label temp2 "Power supply 2 inlet temp sensor" + label temp3 "Power supply 2 sensor" diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 66e86774e766..a916cef30e73 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -216,9 +216,31 @@ EOF chmod a+r "${target_path}/machine.conf" } +in_array() { + local value="$1" + shift + + for other in $@; do + if [ "$value" = "$other" ]; then + return 0 + fi + done + + return 1 +} + +read_system_eeprom() { + if [ -x /bin/readprefdl ]; then + readprefdl -f /tmp/.system-prefdl -d > $target_path/.system-prefdl + elif [ -f /etc/prefdl ]; then + cp /etc/prefdl $target_path/.system-prefdl + chmod a+r $target_path/.system-prefdl + fi +} + platform_specific() { - local platform="$(grep -Eo 'platform=[^ ]+' "$cmdline_base" | cut -f2 -d=)" - local sid="$(grep -Eo 'sid=[^ ]+' "$cmdline_base" | cut -f2 -d=)" + local platform="$(sed -nr 's/.*platform=([^ ]+).*/\1/p' "$cmdline_base")" + local sid="$(sed -nr 's/.*sid=([^ ]+).*/\1/p' "$cmdline_base" | sed 's/Ssd$//')" # set varlog size to 100MB local varlog_size=100 @@ -227,31 +249,35 @@ platform_specific() { local flash_size=$(($(df | grep -E "$flash_re" | tr -s ' ' | cut -f2 -d' ') / 1000)) if [ "$platform" = "raven" ]; then + # Assuming sid=Cloverdale aboot_machine=arista_7050_qx32 flash_size=2000 docker_inram=on echo "modprobe.blacklist=radeon,sp5100_tco acpi=off docker_inram=on" >>/tmp/append fi if [ "$platform" = "crow" ]; then + # Assuming sid=Clearlake aboot_machine=arista_7050_qx32s flash_size=3700 echo "modprobe.blacklist=radeon,sp5100_tco" >>/tmp/append fi - if [ "$sid" = "Upperlake" ] || [ "$sid" = "UpperlakeES" ] || - [ "$sid" = "UpperlakeSsd" ]; then + if [ "$sid" = "Upperlake" ] || [ "$sid" = "UpperlakeES" ]; then aboot_machine=arista_7060_cx32s flash_size=3700 - echo "amd_iommu=off" >> /tmp/append fi - if [ "$sid" = "Gardena" ] || [ "$sid" = "GardenaSsd" ]; then + if [ "$sid" = "Gardena" ] || [ "$sid" = "GardenaE" ]; then aboot_machine=arista_7260cx3_64 flash_size=28000 fi - if [ "$sid" = "Alhambra" ] || [ "$sid" = "AlhambraSsd" ]; then + if [ "$sid" = "Alhambra" ]; then aboot_machine=arista_7170_64c flash_size=28000 echo "hugepages=128" >> /tmp/append fi + if [ "$sid" = "Lodoga" ]; then + aboot_machine=arista_7050cx3_32s + flash_size=3700 + fi if [ "$sid" = "BlackhawkO" ]; then aboot_machine=arista_7060px4_32 flash_size=28000 @@ -260,35 +286,30 @@ platform_specific() { aboot_machine=arista_7060dx4_32 flash_size=28000 fi - if [ "$sid" = "Smartsville" ] || [ "$sid" = "SmartsvilleSsd" ]; then + if [ "$sid" = "Smartsville" ]; then aboot_machine=arista_7280cr3_32p4 flash_size=7382 fi - if [ "$sid" = "SmartsvilleBK" ] || [ "$sid" = "SmartsvilleBKSsd" ]; then + if [ "$sid" = "SmartsvilleBK" ]; then aboot_machine=arista_7280cr3k_32p4 flash_size=7382 fi - if [ "$sid" = "SmartsvilleDD" ] || [ "$sid" = "SmartsvilleDDSsd" ]; then + if [ "$sid" = "SmartsvilleDD" ]; then aboot_machine=arista_7280cr3_32d4 flash_size=7382 fi - if [ "$platform" = "rook" ] || [ "$platform" = "magpie" ] || - [ "$platform" = "woodpecker" ]; then + if in_array "$platform" "rook" "magpie" "woodpecker"; then echo "tsc=reliable pcie_ports=native" >>/tmp/append echo "rhash_entries=1 usb-storage.delay_use=0" >>/tmp/append - if [ -x /bin/readprefdl ]; then - readprefdl -f /tmp/.system-prefdl -d > /mnt/flash/.system-prefdl - elif [ -f /etc/prefdl ]; then - cp /etc/prefdl /mnt/flash/.system-prefdl - chmod a+r /mnt/flash/.system-prefdl - fi echo "reassign_prefmem" >> /tmp/append fi - if [ "$platform" = "rook" ] || [ "$platform" = "magpie" ]; then + if in_array "$platform" "rook"; then echo "iommu=on intel_iommu=on" >>/tmp/append + read_system_eeprom fi - if [ "$platform" = "woodpecker" ]; then + if in_array "$platform" "crow" "woodpecker" "magpie"; then echo "amd_iommu=off modprobe.blacklist=snd_hda_intel,hdaudio" >> /tmp/append + read_system_eeprom fi if [ $flash_size -ge 28000 ]; then diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 10750325b6cf..e61666bbc9d2 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 10750325b6cfc7a1dc1a8b0734008bde1bb3ac06 +Subproject commit e61666bbc9d2c384b1f50a9d193754c7c1668141 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 390d5e22f9c6..e61666bbc9d2 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 390d5e22f9c6c1a007ed325f6b0bd050a79aa5b1 +Subproject commit e61666bbc9d2c384b1f50a9d193754c7c1668141 From 05d61b5ed545819ca8447733b54db727a3717be1 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 17 Jan 2020 14:04:14 -0800 Subject: [PATCH 0300/1427] [bgpcfgd]: Fix bgpcfgd. Don't notify before all deps are ready. (#4027) * Fix bgpcfgd error. Previously subscribers were notified before all dependencies were ready --- dockers/docker-fpm-frr/bgpcfgd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 4211f49d2272..972c85ee271b 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -203,6 +203,8 @@ class Manager(object): syslog.syslog(syslog.LOG_ERR, 'Invalid operation "%s" for key "%s"' % (op, key)) def on_deps_change(self): + if not self.directory.available_deps(self.deps): + return new_queue = [] for key, data in self.set_queue: res = self.set_handler(key, data) From f636ae9bac193273904ad2254e55250ac385af5f Mon Sep 17 00:00:00 2001 From: John Cheung Date: Fri, 17 Jan 2020 14:04:43 -0800 Subject: [PATCH 0301/1427] [barefoot]: updated SDK to 9.1.0 released debian packages (#4032) updated BFN SDK to 9.1.0 released package --- platform/barefoot/bfn-platform.mk | 4 ++-- platform/barefoot/bfn-sai.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 96c204d25ea0..0db9f2d26a77 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ -BFN_PLATFORM = bfnplatform_20191227_deb9.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnplatform_20191227_deb9.deb" +BFN_PLATFORM = bfnplatform_9.1.0.fddc672_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_1/bfnplatform_9.1.0.fddc672_deb9.deb" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 25c851de313c..60a88fad1caf 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,5 @@ -BFN_SAI = bfnsdk_20191227_deb9.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnsdk_20191227_deb9.deb" +BFN_SAI = bfnsdk_9.1.0.fddc672_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_1/bfnsdk_9.1.0.fddc672_deb9.deb" SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) From 1886bdf7ad0cc62f21ef7ffd0b07aaea76c4b99a Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Sat, 18 Jan 2020 06:05:35 +0800 Subject: [PATCH 0302/1427] [Mellanox] fix gearbox ambient thermal name (#4005) --- platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 6862b3fb258b..8030db19edaf 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -56,7 +56,7 @@ THERMAL_API_GET_HIGH_THRESHOLD:"psu{}_temp_max" } thermal_api_handler_gearbox = { - THERMAL_API_GET_TEMPERATURE:"temp_input_gearbox{}", + THERMAL_API_GET_TEMPERATURE:"gearbox{}_temp_input", THERMAL_API_GET_HIGH_THRESHOLD:None } thermal_ambient_apis = { From aca1a86856f995ecf89f1e85e0c592a14537aa27 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 17 Jan 2020 17:33:31 -0800 Subject: [PATCH 0303/1427] [caclmgrd] Fix application of IPv6 service ACL rules (part 2) (#4036) --- files/image_config/caclmgrd/caclmgrd | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 6226bb16768f..e5744c7ca65b 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -225,7 +225,9 @@ class ControlPlaneAclManager(object): rule_cmd = "ip6tables" if table_ip_version == 6 else "iptables" rule_cmd += " -A INPUT -p {}".format(ip_protocol) - if "SRC_IP" in rule_props and rule_props["SRC_IP"]: + if "SRC_IPV6" in rule_props and rule_props["SRC_IPV6"]: + rule_cmd += " -s {}".format(rule_props["SRC_IPV6"]) + elif "SRC_IP" in rule_props and rule_props["SRC_IP"]: rule_cmd += " -s {}".format(rule_props["SRC_IP"]) rule_cmd += " --dport {}".format(dst_port) From d0d1a5592ba552f0be8670fa7f6bb6cabba1035a Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Sun, 19 Jan 2020 11:29:02 -0800 Subject: [PATCH 0304/1427] [sonic-py-swsssdk] update submodule for sonic-py-swsssdk (#4040) update multiDB changes in swsssdk, including: [MultiDB]: update sonic-db-cli list output separator to '\n' (#60) --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 0b4099954498..ae2e038eebbe 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 0b4099954498c4e6fef57a8535d18a2c1fa198b4 +Subproject commit ae2e038eebbea3f4c742395f76390b23c1394f83 From bcc4e557424373cc47bd4b22b185040a1d64607a Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 22 Jan 2020 01:50:02 +0200 Subject: [PATCH 0305/1427] [grub]: Allow ONiE oneshoot boot for FW update. (#3935) Added ONiE oneshoot boot feature Signed-off-by: Nazarii Hnydyn --- installer/x86_64/install.sh | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index 2cd579e28b29..78e8e2f4623b 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -555,15 +555,21 @@ EOF # Add the logic to support grub-reboot and grub-set-default cat <> $grub_cfg if [ -s \$prefix/grubenv ]; then - load_env + load_env fi -if [ "\${saved_entry}" ] ; then - set default="\${saved_entry}" +if [ "\${saved_entry}" ]; then + set default="\${saved_entry}" fi -if [ "\${next_entry}" ] ; then - set default="\${next_entry}" - set next_entry= - save_env next_entry +if [ "\${next_entry}" ]; then + set default="\${next_entry}" + unset next_entry + save_env next_entry +fi +if [ "\${onie_entry}" ]; then + set next_entry="\${default}" + set default="\${onie_entry}" + unset onie_entry + save_env onie_entry next_entry fi EOF From 44fa5efe0008ec4bb689b4e29ae689d1741a3ce6 Mon Sep 17 00:00:00 2001 From: Howard Persh Date: Wed, 22 Jan 2020 10:02:28 -0800 Subject: [PATCH 0306/1427] [startup] Fixes issue with /var/platform directory not created (#4000) --- files/image_config/platform/rc.local | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index d64ec1bb7916..e36b20950b42 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -328,10 +328,10 @@ if [ -f $FIRST_BOOT_FILE ]; then mv /host/grub.cfg /host/grub/grub.cfg fi + # Create dir where following scripts put their output files + mkdir -p /var/platform + firsttime_exit fi -# Create dir where following scripts put their output files -mkdir -p /var/platform - exit 0 From 83202679277db5f27ca59383b11e8ca2bc08aa17 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 22 Jan 2020 10:39:21 -0800 Subject: [PATCH 0307/1427] [sairedis] update submodule for sairedis (#3984) update multiDB changes in sairedis, including: [MultiDB]: repalce old APIs with New APIs incuding testing (#537) [syncd] Move port map and port map parser to proper class (#542) [syncd] Update syncd to expect correct object query message (#548) Support for snat available entry switch attribute in vslib (needed to run vs pytests) (#546) Move apiInitialized flag to Globals namespace (#545) Move command line options and parser to separate classes (#541) Move ntf_queue to proper NotificationQueue class (#539) Move api mutex to global class and add sairedis namespace (#544) Clean sairedis.h header (#543) Fix mlnx.pl script for perl include local directory (#540) Layer 2 Forwarding Enhancements (#510) Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 27a93ff0d5f0..e75a4d64792c 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 27a93ff0d5f0e5fae74c2ef6b78258ad89a066a8 +Subproject commit e75a4d64792c6834bd2a00628ce11ad29a65be7b From 7aa0baf7091402bff497ca8dcc346eb84299d54a Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 22 Jan 2020 11:26:23 -0800 Subject: [PATCH 0308/1427] [MultiDB] (except ./src and ./dockers dirs): replace redis-cli with sonic-db-cli and use new DBConnector (#4035) * [MultiDB] (except ./src and ./dockers dirs): replace redis-cli with sonic-db-cli and use new DBConnector * update comment for a potential bug * update comment * add TODO maker as review reqirement --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 9 ++--- files/build_templates/docker_image_ctl.j2 | 38 ++++++++++--------- files/image_config/config-setup/config-setup | 11 +++--- files/image_config/updategraph/updategraph | 10 ++--- .../warmboot-finalizer/finalize-warmboot.sh | 10 ++--- files/scripts/configdb-load.sh | 2 +- files/scripts/swss.sh | 26 ++++++------- files/scripts/syncd.sh | 12 +++--- .../s9180-32x/utils/qsfp_monitor.sh | 2 +- .../s9280-64x/utils/qsfp_monitor.sh | 2 +- .../s8810-32q/utils/qsfp_monitor.sh | 2 +- .../s8900-54xc/utils/qsfp_monitor.sh | 2 +- .../s8900-64xc/utils/qsfp_monitor.sh | 2 +- .../s9100/utils/qsfp_monitor.sh | 2 +- .../s9200-64x/utils/qsfp_monitor.sh | 2 +- .../s9130-32x/utils/qsfp_monitor.sh | 2 +- .../s9230-64x/utils/qsfp_monitor.sh | 2 +- 17 files changed, 64 insertions(+), 72 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index e41ac2924da2..7c4f33f74973 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -22,8 +22,6 @@ SFP_I2C_PAGE_SIZE = 256 # parameters for DB connection -REDIS_HOSTNAME = "localhost" -REDIS_PORT = 6379 REDIS_TIMEOUT_USECS = 0 # parameters for SFP presence @@ -190,10 +188,9 @@ def get_transceiver_change_event(self, timeout=0): if self.db_sel == None: from swsscommon import swsscommon - self.state_db = swsscommon.DBConnector(swsscommon.STATE_DB, - REDIS_HOSTNAME, - REDIS_PORT, - REDIS_TIMEOUT_USECS) + self.state_db = swsscommon.DBConnector("STATE_DB", + REDIS_TIMEOUT_USECS, + True)) # Subscribe to state table for SFP change notifications self.db_sel = swsscommon.Select() diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 167a392730e4..4f568c793393 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -63,20 +63,20 @@ function preStartAction() docker cp /tmp/dump.rdb database:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) - vrfenabled=`/usr/bin/redis-cli -n 4 hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` - v1SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` - v1SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` - v1Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` - v1Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` - v2SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` - v2SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` - v2Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` - v2Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` - v3SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` - v3SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` - v3Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` - v3Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` + sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + vrfenabled=`sonic-db-cli CONFIG_DB hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` + v1SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` + v1SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` + v1Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` + v1Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` + v2SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` + v2SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` + v2Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` + v2Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` + v3SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` + v3SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` + v3Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` + v3Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` if [ "${v1SnmpTrapIp}" != "" ] then @@ -113,7 +113,11 @@ function preStartAction() fi echo -n "" > /tmp/snmpagentaddr.yml - keys=`/usr/bin/redis-cli -n 4 keys "SNMP_AGENT_ADDRESS_CONFIG|*"` + # TODO + # we should avoid using 'keys' operation via redis-cli or sonic-db-cli + # there would be an issue when KEY in database contains space or '\n' + # for loop on the non-tty 'keys' output will take the space or `\n` as seperator when parsing the element + keys=`sonic-db-cli CONFIG_DB keys "SNMP_AGENT_ADDRESS_CONFIG|*"` count=1 for key in $keys;do ip=`echo $key|cut -d "|" -f2` @@ -151,10 +155,10 @@ function postStartAction() if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - redis-cli -n 6 SET "FAST_REBOOT|system" "1" "EX" "180" + sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" fi - redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index bd497d06b257..f19abd266e95 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -25,7 +25,6 @@ ########################################################################### # Initialize constants -CONFIG_DB_INDEX=4 UPDATEGRAPH_CONF=/etc/sonic/updategraph.conf CONFIG_DB_JSON=/etc/sonic/config_db.json MINGRAPH_FILE=/etc/sonic/minigraph.xml @@ -107,9 +106,9 @@ reload_minigraph() if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -138,7 +137,7 @@ function copy_config_files_and_directories() # Check if SONiC swich has booted after a warm reboot request check_system_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -187,7 +186,7 @@ load_config() return 1 fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -j ${CONFIG_FILE} --write-to-db if [ $? -ne 0 ]; then return $? @@ -198,7 +197,7 @@ load_config() /usr/bin/db_migrator.py -o migrate fi - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" return 0 } diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index b2bd027e82e7..a24d452b1ad2 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -1,16 +1,14 @@ #!/bin/bash -CONFIG_DB_INDEX=4 - reload_minigraph() { echo "Reloading minigraph..." if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -77,9 +75,9 @@ if [ "$src" = "dhcp" ]; then else cp -f /tmp/device_meta.json /etc/sonic/config_db.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ "$dhcp_as_static" = "true" ]; then sed -i "/enabled=/d" /etc/sonic/updategraph.conf echo "enabled=false" >> /etc/sonic/updategraph.conf diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index 32c9c8444cc3..eec50ccef692 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -20,7 +20,7 @@ function debug() function check_warm_boot() { - WARM_BOOT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + WARM_BOOT=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` } @@ -29,12 +29,10 @@ function wait_for_database_service() debug "Wait for database to become ready..." # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done @@ -44,7 +42,7 @@ function wait_for_database_service() function get_component_state() { - /usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|$1" state + sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|$1" state } diff --git a/files/scripts/configdb-load.sh b/files/scripts/configdb-load.sh index 5ba2e0e0bc7f..e7080eb40f3d 100755 --- a/files/scripts/configdb-load.sh +++ b/files/scripts/configdb-load.sh @@ -10,4 +10,4 @@ if [ -r /etc/sonic/config_db.json ]; then sonic-cfggen -j /etc/sonic/config_db.json --write-to-db fi -redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" +sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 93f311019d66..a14d03e40f50 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -31,8 +31,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -43,7 +43,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -54,12 +54,10 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -69,7 +67,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - redis-cli -n $1 EVAL " + sonic-db-cli $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -114,11 +112,11 @@ start() { # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - /usr/bin/docker exec database redis-cli -n 0 FLUSHDB - /usr/bin/docker exec database redis-cli -n 1 FLUSHDB - /usr/bin/docker exec database redis-cli -n 2 FLUSHDB - /usr/bin/docker exec database redis-cli -n 5 FLUSHDB - clean_up_tables 6 "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" + sonic-db-cli APPL_DB FLUSHDB + sonic-db-cli ASIC_DB FLUSHDB + sonic-db-cli COUNTERS_DB FLUSHDB + sonic-db-cli FLEX_COUNTER_DB FLUSHDB + clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker @@ -166,7 +164,7 @@ stop() { # encountered error, e.g. syncd crashed. And swss needs to # be restarted. debug "Clearing FAST_REBOOT flag..." - clean_up_tables 6 "'FAST_REBOOT*'" + clean_up_tables STATE_DB "'FAST_REBOOT*'" # Unlock has to happen before reaching out to peer service unlock_service_state_change diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 05e5552a64b1..4b47e7ad4c45 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -30,8 +30,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -43,12 +43,10 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -65,7 +63,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(redis-cli -n 6 GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $(sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh index 23a3fd066bee..9213d115f656 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh index 7f50d137bcb7..0a4ba20ab767 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh index 36f9e53ef108..b3192f2efb7a 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh index 51c49c1152f5..47cfbb3ea008 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh index 23a3fd066bee..9213d115f656 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi From 5057ac31226ad5e72e3eae3bc3798c64d1477e16 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 22 Jan 2020 11:27:21 -0800 Subject: [PATCH 0309/1427] [MultiDB] (./dockers dir) : replace redis-cli with sonic-db-cli and use new DBConnector (#3923) * [MultiDB] (./dockers dirs): replace redis-cli with sonic-db-cli and use new DBConnector * remove unnecessary quota * update typo --- dockers/docker-dhcp-relay/wait_for_intf.sh.j2 | 4 +--- dockers/docker-fpm-frr/bgpcfgd | 11 ++++++----- dockers/docker-lldp-sv2/lldpmgrd | 16 ++++++---------- dockers/docker-orchagent/swssconfig.sh | 6 +++--- .../docker-router-advertiser/wait_for_intf.sh.j2 | 4 +--- dockers/docker-sonic-telemetry/telemetry.sh | 2 +- .../tests/sample_output/wait_for_intf.sh | 4 +--- 7 files changed, 19 insertions(+), 28 deletions(-) diff --git a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 index 0488799a4c81..568f128b3772 100644 --- a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 +++ b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 @@ -1,7 +1,5 @@ #!/usr/bin/env bash -STATE_DB_IDX="6" - function wait_until_iface_ready { IFACE_NAME=$1 @@ -12,7 +10,7 @@ function wait_until_iface_ready # Wait for the interface to come up # (i.e., interface is present in STATE_DB and state is "ok") while true; do - RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) + RESULT=$(sonic-db-cli STATE_DB HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) if [ x"$RESULT" == x"ok" ]; then break fi diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 972c85ee271b..4348d22bcb8f 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -86,9 +86,10 @@ class Daemon(object): self.callbacks = defaultdict(lambda : defaultdict(list)) # db -> table -> [] self.subscribers = set() - def add_manager(self, db, table_name, callback): + def add_manager(self, db_name, table_name, callback): + db = swsscommon.SonicDBConfig.getDbId(db_name) if db not in self.db_connectors: - self.db_connectors[db] = swsscommon.DBConnector(db, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) + self.db_connectors[db] = swsscommon.DBConnector(db_name, 0) if table_name not in self.callbacks[db]: conn = self.db_connectors[db] @@ -225,7 +226,7 @@ class BGPDeviceMetaMgr(Manager): daemon, directory, [], - swsscommon.CONFIG_DB, + "CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME ) @@ -250,7 +251,7 @@ class BGPNeighborMetaMgr(Manager): daemon, directory, [], - swsscommon.CONFIG_DB, + "CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME ) @@ -272,7 +273,7 @@ class BGPPeerMgr(Manager): ("meta", "localhost/bgp_asn"), ("neigmeta", ""), ], - swsscommon.CONFIG_DB, + "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME ) self.peers = self.load_peers() diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd index edcdc5c42e47..36b6e67a5f47 100755 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ b/dockers/docker-lldp-sv2/lldpmgrd @@ -84,22 +84,18 @@ class LldpManager(object): pending_cmds: Dictionary where key is port name, value is pending LLDP configuration command to run """ - REDIS_HOSTNAME = "localhost" - REDIS_PORT = 6379 REDIS_TIMEOUT_MS = 0 def __init__(self): # Open a handle to the Config database - self.config_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, - self.REDIS_HOSTNAME, - self.REDIS_PORT, - self.REDIS_TIMEOUT_MS) + self.config_db = swsscommon.DBConnector("CONFIG_DB", + self.REDIS_TIMEOUT_MS, + True) # Open a handle to the Application database - self.appl_db = swsscommon.DBConnector(swsscommon.APPL_DB, - self.REDIS_HOSTNAME, - self.REDIS_PORT, - self.REDIS_TIMEOUT_MS) + self.appl_db = swsscommon.DBConnector("APPL_DB", + self.REDIS_TIMEOUT_MS, + True) self.pending_cmds = {} diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index c521fadf0a49..856b3bcd0e41 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -43,11 +43,11 @@ HWSKU=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['hwsku']"` # Don't load json config if system warm start or # swss docker warm start is enabled, the data already exists in appDB. -SYSTEM_WARM_START=`redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` -SWSS_WARM_START=`redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|swss" enable` +SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` +SWSS_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|swss" enable` if [[ "$SYSTEM_WARM_START" == "true" ]] || [[ "$SWSS_WARM_START" == "true" ]]; then # We have to make sure db data has not been flushed. - RESTORE_COUNT=`redis-cli -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` if [[ -n "$RESTORE_COUNT" ]] && [[ "$RESTORE_COUNT" != "0" ]]; then exit 0 fi diff --git a/dockers/docker-router-advertiser/wait_for_intf.sh.j2 b/dockers/docker-router-advertiser/wait_for_intf.sh.j2 index a044df0fc996..980b472b3e0a 100644 --- a/dockers/docker-router-advertiser/wait_for_intf.sh.j2 +++ b/dockers/docker-router-advertiser/wait_for_intf.sh.j2 @@ -1,7 +1,5 @@ #!/usr/bin/env bash -STATE_DB_IDX="6" - VLAN_TABLE_PREFIX="VLAN_TABLE" function wait_until_iface_ready @@ -14,7 +12,7 @@ function wait_until_iface_ready # Wait for the interface to come up # (i.e., interface is present in STATE_DB and state is "ok") while true; do - RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) + RESULT=$(sonic-db-cli STATE_DB HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) if [ x"$RESULT" == x"ok" ]; then break fi diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 8b29b4d616a5..37ab4dd2d04f 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -29,7 +29,7 @@ fi # If no configuration entry exists for TELEMETRY, create one default port if [ -z $TELEMETRY ]; then - redis-cli -n 4 hset "TELEMETRY|gnmi" port 8080 + sonic-db-cli CONFIG_DB hset "TELEMETRY|gnmi" port 8080 fi PORT=`sonic-cfggen -d -v "TELEMETRY['gnmi']['port']"` diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh index 918f0b6e1648..6d90afa60ad7 100644 --- a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh +++ b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh @@ -1,7 +1,5 @@ #!/usr/bin/env bash -STATE_DB_IDX="6" - function wait_until_iface_ready { IFACE_NAME=$1 @@ -12,7 +10,7 @@ function wait_until_iface_ready # Wait for the interface to come up # (i.e., interface is present in STATE_DB and state is "ok") while true; do - RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) + RESULT=$(sonic-db-cli STATE_DB HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) if [ x"$RESULT" == x"ok" ]; then break fi From db7668638a3d7ddd484940c9fc2189f54c0b91aa Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Wed, 22 Jan 2020 17:00:50 -0800 Subject: [PATCH 0310/1427] [Monit] Change the full process name of syncd in the monit config file. (#4033) Since the syncd process running on different platforms will have the different full path names, we change the full path name of process syncd in the monit config file such that it will be universal and is not for a specific vendor. Signed-off-by: Yong Zhao --- platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd | 2 +- .../broadcom/docker-syncd-brcm/base_image_files/monit_syncd | 2 +- platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd | 2 +- .../centec/docker-syncd-centec/base_image_files/monit_syncd | 2 +- .../docker-syncd-mrvl/base_image_files/monit_syncd | 2 +- .../docker-syncd-mrvl/base_image_files/monit_syncd | 2 +- platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd | 2 +- .../mellanox/docker-syncd-mlnx/base_image_files/monit_syncd | 2 +- .../nephos/docker-syncd-nephos/base_image_files/monit_syncd | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd +++ b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd index 3f8bc50007d7..0b9ec741cd57 100644 --- a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd @@ -4,7 +4,7 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" diff --git a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd +++ b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd +++ b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd +++ b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd index 3f8bc50007d7..0b9ec741cd57 100644 --- a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd +++ b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd @@ -4,7 +4,7 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" From b76e2790a41681d3ea22d7281b21e4934a0c80fe Mon Sep 17 00:00:00 2001 From: Myron Sosyak <49795530+msosyak@users.noreply.github.com> Date: Wed, 22 Jan 2020 17:02:10 -0800 Subject: [PATCH 0311/1427] [submodule]: Update sonic-utilities submodule (#4050) - catch all exceptions while trying https endpoint - Used "config-setup backup" command to take a backup copy of current SONiC configuration. - raise exception when http endpoint return failure --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 08169487110a..640f4a792552 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 08169487110a95152d2e52dc0f2584f6e3b16579 +Subproject commit 640f4a79255268583ed365b94c32259efecf4dcc From a664123786053778c2c2347a6316e8d99612d6cf Mon Sep 17 00:00:00 2001 From: paavaanan Date: Thu, 23 Jan 2020 22:57:41 +0530 Subject: [PATCH 0312/1427] [devices]: DellEMC S6000 fancontrol support (#4048) - Implemented fancontrol service to monitor S6000 fans and adjust fan speed w.r.t temperature. - fancontrol.service starts the fancontrol script at startup. - This script takes the average temperature by reading three sensors and configure FANS to appropritate RPM against the temperature. - When the temperature is adjusted script will log in syslog for future reference. - Also, script checks for faulty fans and report the status in syslog. --- .../debian/platform-modules-s6000.install | 2 + .../debian/platform-modules-s6000.postinst | 5 + .../s6000/scripts/fancontrol.sh | 189 ++++++++++++++++++ .../s6000/systemd/fancontrol.service | 13 ++ 4 files changed, 209 insertions(+) create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6000/systemd/fancontrol.service diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install index c2dcb5dc03a9..f662e751a3f8 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install @@ -1,6 +1,8 @@ s6000/scripts/s6000_platform.sh usr/local/bin s6000/scripts/reset-qsfp usr/local/bin s6000/scripts/set-fan-speed usr/local/bin +s6000/scripts/fancontrol.sh usr/local/bin s6000/systemd/platform-modules-s6000.service etc/systemd/system +s6000/systemd/fancontrol.service etc/systemd/system common/io_rd_wr.py usr/local/bin s6000/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dell_s6000_s1220-r0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst index a9b90fa86f3a..052e5a6f574e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst @@ -4,4 +4,9 @@ depmod -a systemctl enable platform-modules-s6000.service systemctl start platform-modules-s6000.service + +systemctl enable fancontrol.service +systemctl start fancontrol.service + + #DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh new file mode 100755 index 000000000000..43315e06c930 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh @@ -0,0 +1,189 @@ +#!/bin/bash + +LEVEL=99 +INTERVAL=5 +FAULTY_FANTRAY1=1 +FAULTY_FANTRAY2=1 +FAULTY_FANTRAY3=1 + +# FAN RPM Speed +IDLE=7000 +LEVEL1=10000 +LEVEL2=13000 +LEVEL3=16000 +LEVEL4=19000 +LEVEL5=19000 + +I2C_ADAPTER="/sys/class/i2c-adapter/i2c-2/i2c-11" +SENSOR1="$I2C_ADAPTER/11-004c/hwmon/hwmon*/temp1_input" +SENSOR2="$I2C_ADAPTER/11-004d/hwmon/hwmon*/temp1_input" +SENSOR3="$I2C_ADAPTER/11-004e/hwmon/hwmon*/temp1_input" + +# Three fan trays with each contains two separate fans +# fan1-fan4 fan2-fan5 fan3-fan6 +FANTRAY1_FAN1=$I2C_ADAPTER/11-0029/fan1_target +FANTRAY1_FAN2=$I2C_ADAPTER/11-0029/fan2_target +FANTRAY2_FAN1=$I2C_ADAPTER/11-0029/fan3_target +FANTRAY2_FAN2=$I2C_ADAPTER/11-0029/fan4_target +FANTRAY3_FAN1=$I2C_ADAPTER/11-002a/fan1_target +FANTRAY3_FAN2=$I2C_ADAPTER/11-002a/fan2_target + +FANTRAY1_FAN1_RPM=$I2C_ADAPTER/11-0029/fan1_input +FANTRAY1_FAN2_RPM=$I2C_ADAPTER/11-0029/fan2_input +FANTRAY2_FAN1_RPM=$I2C_ADAPTER/11-0029/fan3_input +FANTRAY2_FAN2_RPM=$I2C_ADAPTER/11-0029/fan4_input +FANTRAY3_FAN1_RPM=$I2C_ADAPTER/11-002a/fan1_input +FANTRAY3_FAN2_RPM=$I2C_ADAPTER/11-002a/fan2_input + +function check_module +{ + MODULE=$1 + lsmod | grep "$MODULE" > /dev/null + ret=$? + if [[ $ret = "1" ]]; then + echo "$MODULE is not loaded!" + exit 1 + fi +} + +function check_faulty_fan +{ + + # Assume fans in FanTray spins less than 1000 RPM is faulty. + # To Maintain temperature assign max speed 16200 RPM to all other fans. + # This RPM speed handle temperature upto 75C degrees + + fan1=$(cat $FANTRAY1_FAN1_RPM) + fan2=$(cat $FANTRAY1_FAN2_RPM) + fan3=$(cat $FANTRAY2_FAN1_RPM) + fan4=$(cat $FANTRAY2_FAN2_RPM) + fan5=$(cat $FANTRAY3_FAN1_RPM) + fan6=$(cat $FANTRAY3_FAN2_RPM) + + # FanTray1 + if [ "$fan1" -le "1000" ] || [ "$fan2" -le "1000" ]; then + + # First time detecting failure + if [ $FAULTY_FANTRAY1 -lt "2" ]; then + FAULTY_FANTRAY1=2 + /usr/local/bin/set-fan-speed 16200 2 > /dev/null + logger "Faulty Fans in Fantray1 $fan1 $fan2 Please check." + fi + + elif [ "$fan1" -ge "1000" ] || [ "$fan2" -ge "1000" ]; then + FAULTY_FANTRAY1=0 + fi + + + # FanTray2 + if [ "$fan3" -le "1000" ] || [ "$fan4" -le "1000" ]; then + + # First time detecting failure + if [ $FAULTY_FANTRAY2 -lt "2" ]; then + + FAULTY_FANTRAY2=2 + /usr/local/bin/set-fan-speed 16200 2 > /dev/null + logger "Faulty Fans in FanTray2: $fan3 $fan4. Please check." + fi + + elif [ "$fan3" -ge "1000" ] || [ "$fan4" -ge "1000" ]; then + FAULTY_FANTRAY2=0 + fi + + # FanTray3 + if [ "$fan5" -le "1000" ] || [ "$fan6" -le "1000" ]; then + + # First time detecting failure + if [ $FAULTY_FANTRAY3 -lt "2" ]; then + + FAULTY_FANTRAY3=2 + /usr/local/bin/set-fan-speed 16200 2 > /dev/null + logger "FanTray3 Fans are Faulty.. $fan5 $fan6. Please check." + fi + + elif [ "$fan5" -ge "1000" ] || [ "$fan6" -ge "1000" ]; then + + FAULTY_FANTRAY3=0 + fi + +} + +function update_fan_speed +{ + local fan_speed=$1 + + echo $fan_speed > $FANTRAY1_FAN1 + echo $fan_speed > $FANTRAY1_FAN2 + echo $fan_speed > $FANTRAY2_FAN1 + echo $fan_speed > $FANTRAY2_FAN2 + echo $fan_speed > $FANTRAY3_FAN1 + echo $fan_speed > $FANTRAY3_FAN2 + +} + +function monitor_temp_sensors +{ + + while true # go through all temp sensor outputs + do + sensor1=$(expr `echo $(cat $SENSOR1)` / 1000) + sensor2=$(expr `echo $(cat $SENSOR2)` / 1000) + sensor3=$(expr `echo $(cat $SENSOR3)` / 1000) + sum=$(($sensor1 + $sensor2 + $sensor3)) + sensor_temp=$(($sum/3)) + + if [ "$sensor_temp" -le "25" ] && [ "$LEVEL" -ne "0" ] + then + # Set Fan Speed to 7000 RPM" + LEVEL=0 + update_fan_speed $IDLE + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "26" ] && [ "$sensor_temp" -le "44" ] && [ "$LEVEL" -ne "1" ] + then + # Set Fan Speed to 10000 RPM" + LEVEL=1 + update_fan_speed $LEVEL1 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "45" ] && [ "$sensor_temp" -le "59" ] && [ "$LEVEL" -ne "2" ] + then + # Set Fan Speed to 13000 RPM" + LEVEL=2 + update_fan_speed $LEVEL2 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "60" ] && [ "$sensor_temp" -le "79" ] && [ "$LEVEL" -ne "3" ] + then + # Set Fan Speed to 16000 RPM" + LEVEL=3 + update_fan_speed $LEVEL3 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "80" ] && [ "$LEVEL" -ne "4" ] + then + # Set Fan Speed to 19000 RPM" + LEVEL=4 + update_fan_speed $LEVEL4 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + fi + + # Check for faulty fan + check_faulty_fan + + done + +} + +# Check drivers for sysfs attributes +check_module "dell_s6000_platform" +check_module "max6620" + +# main loop calling the main function at specified intervals +while true +do + monitor_temp_sensors + # Sleep while still handling signals + sleep $INTERVAL & + wait +done diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/fancontrol.service b/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/fancontrol.service new file mode 100644 index 000000000000..75cc977b9935 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/fancontrol.service @@ -0,0 +1,13 @@ +[Unit] +Description=Dell S6000 fan speed regulator +After=platform-modules-s6000.service +Before=pmon.service + +[Service] +ExecStart=-/usr/local/bin/fancontrol.sh +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target + From c6fee49e76907718bbf33d5f82babab4168bf566 Mon Sep 17 00:00:00 2001 From: chitra-raghavan <32665166+chitra-raghavan@users.noreply.github.com> Date: Thu, 23 Jan 2020 22:58:39 +0530 Subject: [PATCH 0313/1427] [docker-ptf]: Adding sflowtool to ptf docker to for sflow tests (#4045) Adding sflowtool to ptf docker for running sflow tests in sonic-mgmt repository --- dockers/docker-ptf/Dockerfile.j2 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index 326df49d9764..ba5577954039 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -27,6 +27,7 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / && apt-get upgrade -y \ && apt-get dist-upgrade -y \ && apt-get install -y \ + autoconf \ openssh-server \ vim \ telnet \ @@ -81,6 +82,14 @@ RUN rm -rf /debs \ && python setup.py install \ && cd .. \ && rm -fr scapy-vxlan \ + && git clone https://github.com/sflow/sflowtool \ + && cd sflowtool \ + && ./boot.sh \ + && ./configure \ + && make \ + && make install \ + && cd .. \ + && rm -fr sflowtool \ && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && tar xvfz 1.0.0.tar.gz \ && cd nanomsg-1.0.0 \ From c2677a561409098cd262aac50c582ab7d42f6bb2 Mon Sep 17 00:00:00 2001 From: rkdevi27 <54701695+rkdevi27@users.noreply.github.com> Date: Thu, 23 Jan 2020 23:02:34 +0530 Subject: [PATCH 0314/1427] [devices]: DellEMC: Platform 2.0 Api(sfp,eeprom,chassis )for z9264f (#4007) - Sfp,Eeprom,Chassis(transceiver change event) support added for z9264f Platform 2.0 API - Added Interrupt handler to SFP change event in dell_z9264f_fpga_ocores.c - Fixed few indentation and offset issues in sfputil.py for z9264f --- .../plugins/eeprom.py | 11 +- .../plugins/sfputil.py | 142 ++- .../debian/platform-modules-z9264f.install | 1 + .../sonic-platform-modules-dell/debian/rules | 8 + .../z9264f/modules/dell_z9264f_fpga_ocores.c | 38 +- .../z9264f/scripts/qsfp_irq_enable.py | 3 +- .../z9264f/scripts/z9264f_platform.sh | 20 +- .../z9264f/setup.py | 1 + .../z9264f/sonic_platform/__init__.py | 3 + .../z9264f/sonic_platform/chassis.py | 247 ++++ .../z9264f/sonic_platform/eeprom.py | 140 +++ .../z9264f/sonic_platform/sfp.py | 1056 +++++++++++++++++ 12 files changed, 1602 insertions(+), 68 deletions(-) create mode 120000 platform/broadcom/sonic-platform-modules-dell/z9264f/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py index 2af10473065e..ce1691a72945 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py @@ -10,6 +10,7 @@ ############################################################################# try: + import os.path from sonic_eeprom import eeprom_tlvinfo except ImportError, e: raise ImportError (str(e) + "- required module not found") @@ -18,5 +19,13 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): - self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0050/eeprom" + self.eeprom_path = None + for b in (0,1): + f = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'.format(b) + if os.path.exists(f): + self.eeprom_path = f + break + if self.eeprom_path is None: + return + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py index 70e0b26f7890..6aa18d85e2e7 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py @@ -44,6 +44,8 @@ SFP_VOLT_WIDTH = 2 SFP_MODULE_THRESHOLD_OFFSET = 0 SFP_MODULE_THRESHOLD_WIDTH = 56 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 XCVR_DOM_CAPABILITY_OFFSET = 92 XCVR_DOM_CAPABILITY_WIDTH = 1 @@ -226,8 +228,8 @@ def reset(self, port_num): if (reg_value == ""): return False - # Mask off 4th bit for presence - mask = (1 << 6) + # Mask off 4th bit for reset + mask = (1 << 4) # ResetL is active low reg_value = reg_value & ~mask @@ -347,7 +349,7 @@ def get_transceiver_dom_info_dict(self, port_num): ] transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') - if port_num in self.qsfp_ports: + if port_num in self.qsfp_ports: offset = 0 offset_xcvr = 128 file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) @@ -379,7 +381,7 @@ def get_transceiver_dom_info_dict(self, port_num): return transceiver_dom_info_dict dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) - if dom_temperature_raw is not None: + if dom_temperature_raw is not None: dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) else: return transceiver_dom_info_dict @@ -411,10 +413,22 @@ def get_transceiver_dom_info_dict(self, port_num): else: return transceiver_dom_info_dict - transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = 'N/A' transceiver_dom_info_dict['tx2power'] = 'N/A' transceiver_dom_info_dict['tx3power'] = 'N/A' transceiver_dom_info_dict['tx4power'] = 'N/A' + else: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + else: + return None + + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + try: sysfsfile_eeprom.close() except IOError: @@ -433,64 +447,66 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] else: - offset = 256 - file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) - if not self._sfp_eeprom_present(file_path, 0): - return None - - try: - sysfsfile_eeprom = io.open(file_path,"rb",0) - except IOError: - print("Error: reading sysfs file %s" % file_path) - return None - - sfpd_obj = sff8472Dom(None,1) - if sfpd_obj is None: - return None - dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), - SFP_TEMPE_WIDTH) - if dom_temperature_raw is not None: - dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) - else: - return transceiver_dom_info_dict - - dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), - SFP_VOLT_WIDTH) - if dom_voltage_raw is not None: - dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) - else: - return transceiver_dom_info_dict - - dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_MODULE_THRESHOLD_OFFSET), - SFP_MODULE_THRESHOLD_WIDTH) - if dom_channel_monitor_raw is not None: - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) - else: - return transceiver_dom_info_dict - - try: - sysfsfile_eeprom.close() - except IOError: - print("Error: closing sysfs file %s" % file_path) - return None - - transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] - transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] - transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] - transceiver_dom_info_dict['rx2power'] = 'N/A' - transceiver_dom_info_dict['rx3power'] = 'N/A' - transceiver_dom_info_dict['rx4power'] = 'N/A' - transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] - transceiver_dom_info_dict['tx2bias'] = 'N/A' - transceiver_dom_info_dict['tx3bias'] = 'N/A' - transceiver_dom_info_dict['tx4bias'] = 'N/A' - transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] - transceiver_dom_info_dict['tx2power'] = 'N/A' - transceiver_dom_info_dict['tx3power'] = 'N/A' - transceiver_dom_info_dict['tx4power'] = 'N/A' - - return transceiver_dom_info_dict - + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return None + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), + SFP_TEMPE_WIDTH) + + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), + SFP_VOLT_WIDTH) + + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), + SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + def get_transceiver_dom_threshold_info_dict(self, port_num): transceiver_dom_threshold_info_dict = {} dom_info_dict_keys = ['temphighalarm', 'temphighwarning', diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install index e7d589f14e0c..ffe23322fb83 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install @@ -6,6 +6,7 @@ z9264f/scripts/pcisysfs.py usr/bin z9264f/scripts/qsfp_irq_enable.py usr/bin z9264f/cfg/z9264f-modules.conf etc/modules-load.d z9264f/systemd/platform-modules-z9264f.service etc/systemd/system +z9264f/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index 8af0642b40d3..d73f63209e4b 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -29,6 +29,10 @@ override_dh_auto_build: cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ + elif [ $$mod = "z9264f" ]; then \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + cd $(MOD_SRC_DIR); \ fi; \ echo "making man page alias $$mod -> $$mod APIs";\ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ @@ -67,6 +71,10 @@ override_dh_clean: rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ rm -rf $(MOD_SRC_DIR)/$${mod}/build; \ rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ + elif [ $$mod = "z9264f" ]; then \ + rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/build; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ fi; \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ done) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c index c1644ecf705d..c3bd78131e87 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c @@ -231,6 +231,7 @@ enum { #define IRQ_LTCH_STS 0x20 #define PRSNT_LTCH_STS 0x10 +#define MODABS_STS 0x01 #define PORT_CTRL_OFFSET 0x4000 #define PORT_STS_OFFSET 0x4004 @@ -296,6 +297,7 @@ enum { #define FPGA_MSI_VECTOR_ID_4 4 #define FPGA_MSI_VECTOR_ID_5 5 +#define FPGA_MSI_VECTOR_ID_6 6 #define FPGA_MSI_VECTOR_ID_8 8 #define FPGA_MSI_VECTOR_ID_9 9 #define FPGA_MSI_VECTOR_ID_10 10 @@ -523,7 +525,7 @@ static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, int ind = 0, port_status=0, port_irq_status=0; struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); PRINT("%s:xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); - for(ind=0;ind<64;ind++) + for(ind=0;ind<66;ind++) { port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); @@ -585,6 +587,28 @@ static irqreturn_t fpgaport_33_64_isr(int irq, void *dev) return IRQ_HANDLED; } + +static irqreturn_t fpgaport_65_66_isr(int irq, void *dev) +{ + struct pci_dev *pdev = dev; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + int ind = 0, port_status=0, port_irq_status=0; + for(ind=64;ind<66;ind++) + { + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + if(port_irq_status| (MODABS_STS)) + { + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + //write on clear + iowrite32( MODABS_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + } + } + fpgapci->xcvr_intr_count++; + PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); + return IRQ_HANDLED; +} + static void fpgai2c_process(struct fpgalogic_i2c *i2c) { struct i2c_msg *msg = i2c->msg; @@ -1122,6 +1146,12 @@ static int register_intr_handler(struct pci_dev *dev, int irq_num_id) PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); fpgapci->irq_assigned++; break; + case FPGA_MSI_VECTOR_ID_6: + err = request_irq(dev->irq + irq_num_id, fpgaport_65_66_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; case FPGA_MSI_VECTOR_ID_8: err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[0]); @@ -1180,6 +1210,12 @@ static int register_intr_handler(struct pci_dev *dev, int irq_num_id) PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); fpgapci->irq_assigned++; break; + case FPGA_MSI_VECTOR_ID_6: + err = request_irq(dev->irq + irq_num_id, fpgaport_65_66_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; case FPGA_MSI_VECTOR_ID_8: err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[0]); diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py index b2eb03dd2011..e7442ba168f5 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py @@ -27,6 +27,7 @@ def pci_set_value(resource, val, offset): close(fd) return val +#Enabled interrupt for qsfp and sfp for port_num in range(PORT_START, PORT_END+1): port_offset = 0x400c + ((port_num) * 16) - pci_set_value(BASE_RES_PATH, 0x30, port_offset) + pci_set_value(BASE_RES_PATH, 0x31, port_offset) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh index 3435704a65cb..7361bdea2d6d 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh @@ -17,9 +17,9 @@ init_devnum() { # Attach/Detach syseeprom on CPU board sys_eeprom() { case $1 in - "new_device") echo 24c16 0x50 > /sys/bus/i2c/devices/i2c-0/$1 + "new_device") echo 24c16 0x50 > /sys/bus/i2c/devices/i2c-${devnum}/$1 ;; - "delete_device") echo 0x50 > /sys/bus/i2c/devices/i2c-0/$1 + "delete_device") echo 0x50 > /sys/bus/i2c/devices/i2c-${devnum}/$1 ;; *) echo "z9264f_platform: sys_eeprom : invalid command !" ;; @@ -125,6 +125,20 @@ init_switch_port_led() { fi } +install_python_api_package() { + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + + rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) +} + +remove_python_api_package() { + rv=$(pip show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi +} + init_devnum if [ "$1" == "init" ]; then @@ -140,6 +154,7 @@ if [ "$1" == "init" ]; then switch_board_sfp "new_device" switch_board_modsel init_switch_port_led + install_python_api_package python /usr/bin/qsfp_irq_enable.py elif [ "$1" == "deinit" ]; then @@ -149,6 +164,7 @@ elif [ "$1" == "deinit" ]; then switch_board_sfp "delete_device" modprobe -r i2c-mux-pca954x modprobe -r i2c-dev + remove_python_api_package else echo "z9264f_platform : Invalid option !" fi diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/setup.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/setup.py new file mode 120000 index 000000000000..4f6de9941d96 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/setup.py @@ -0,0 +1 @@ +../s6100/setup.py \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py new file mode 100644 index 000000000000..328d25319343 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["chassis", "sfp", "eeprom"] +from sonic_platform import * + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py new file mode 100644 index 000000000000..3714d391475f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC Z9264F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import os + import select + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Eeprom + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Chassis(ChassisBase): + """ + DELLEMC Platform-specific Chassis class + """ + + OIR_FD_PATH = "/sys/bus/pci/devices/0000:04:00.0/port_msi" + + oir_fd = -1 + epoll = -1 + + _global_port_pres_dict = {} + + def __init__(self): + ChassisBase.__init__(self) + # sfp.py will read eeprom contents and retrive the eeprom data. + # We pass the eeprom path from chassis.py + self.PORT_START = 1 + self.PORT_END = 66 + PORTS_IN_BLOCK = (self.PORT_END + 1) + _sfp_port = range(65, self.PORT_END + 1) + eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for index in range(self.PORT_START, PORTS_IN_BLOCK): + port_num = index + 1 + eeprom_path = eeprom_base.format(port_num) + if index not in _sfp_port: + sfp_node = Sfp(index, 'QSFP', eeprom_path) + else: + sfp_node = Sfp(index, 'SFP', eeprom_path) + self._sfp_list.append(sfp_node) + + self._eeprom = Eeprom() + + for port_num in range(self.PORT_START, (self.PORT_END + 1)): + presence = self.get_sfp(port_num).get_presence() + if presence: + self._global_port_pres_dict[port_num] = '1' + else: + self._global_port_pres_dict[port_num] = '0' + + def __del__(self): + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + + def _get_register(self, reg_file): + retval = 'ERR' + if (not os.path.isfile(reg_file)): + print reg_file, 'not found !' + return retval + + try: + with os.fdopen(os.open(reg_file, os.O_RDONLY)) as fd: + retval = fd.read() + except: + pass + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + def _check_interrupts(self, port_dict): + retval = 0 + is_port_dict_updated = False + for port_num in range(self.PORT_START, (self.PORT_END + 1)): + sfp = self.get_sfp(port_num) + presence = sfp.get_presence() + if(presence and (self._global_port_pres_dict[port_num] == '0')): + is_port_dict_updated = True + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and (self._global_port_pres_dict[port_num] == '1')): + is_port_dict_updated = True + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + return retval, is_port_dict_updated + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + """ + port_dict = {} + change_dict = {} + change_dict['sfp'] = port_dict + try: + # We get notified when there is a MSI interrupt (vector 4/5)CVR + # Open the sysfs file and register the epoll object + self.oir_fd = os.fdopen(os.open(self.OIR_FD_PATH, os.O_RDONLY)) + if self.oir_fd != -1: + # Do a dummy read before epoll register + self.oir_fd.read() + self.epoll = select.epoll() + self.epoll.register( + self.oir_fd.fileno(), select.EPOLLIN & select.EPOLLET) + else: + print("get_transceiver_change_event : unable to create fd") + return False, change_dict + # Check for missed interrupts by invoking self._check_interrupts + # which will update the port_dict. + while True: + interrupt_count_start = self._get_register(self.OIR_FD_PATH) + retval, is_port_dict_updated = self._check_interrupts(port_dict) + if ((retval == 0) and (is_port_dict_updated is True)): + return True, change_dict + interrupt_count_end = self._get_register(self.OIR_FD_PATH) + if (interrupt_count_start == 'ERR' or + interrupt_count_end == 'ERR'): + print("get_transceiver_change_event : \ + unable to retrive interrupt count") + break + # check_interrupts() itself may take upto 100s of msecs. + # We detect a missed interrupt based on the count + if interrupt_count_start == interrupt_count_end: + break + # Block until an xcvr is inserted or removed with timeout = -1 + events = self.epoll.poll( + timeout=timeout if timeout != 0 else -1) + if events: + # check interrupts and return the change_dict + retval, is_port_dict_updated = \ + self._check_interrupts(port_dict) + if (retval != 0): + return False, change_dict + return True, change_dict + except: + return False, change_dict + finally: + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + self.oir_fd = -1 + self.epoll = -1 + return False, change_dict + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 1. + For example, 1 for Ethernet0, 2 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + # The index will start from 1 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.system_eeprom_info() diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py new file mode 100644 index 000000000000..82cf6d6489aa --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python + +############################################################################# +# DellEmc Z9264F +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import os.path + from sonic_eeprom import eeprom_tlvinfo + import binascii +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self): + self.eeprom_path = None + for b in (0, 1): + f = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'.format(b) + if os.path.exists(f): + self.eeprom_path = f + break + if self.eeprom_path is None: + return + super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_tlv_dict = dict() + try: + self.eeprom_data = self.read_eeprom() + except: + self.eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + ord(eeprom[tlv_index + 1])] + code = "0x%02X" % (ord(tlv[0])) + + if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | + (ord(tlv[4]) << 8) | ord(tlv[5])) + value += str(tlv[6:6 + ord(tlv[1])]) + else: + name, value = self.decoder(None, tlv) + + self.eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+1]) + 2 + + def serial_number_str(self): + """ + Returns the serial number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2] + + def base_mac_addr(self): + """ + Returns the base mac address found in the system EEPROM + """ + (is_valid, t) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(TlvInfoDecoder, self).switchaddrstr(e) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + """ + Returns the Model name + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def part_number_str(self): + """ + Returns the part number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def serial_str(self): + """ + Returns the servicetag number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2] + + def revision_str(self): + """ + Returns the device revision + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2] + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.eeprom_tlv_dict diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py new file mode 100644 index 000000000000..19c678f0e9df --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py @@ -0,0 +1,1056 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import os + import time + import struct + import sys + import getopt + import select + import mmap + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PAGE_OFFSET = 0 +KEY_OFFSET = 1 +KEY_WIDTH = 2 +FUNC_NAME = 3 + +QSFP_INFO_OFFSET = 128 +QSFP_DOM_OFFSET = 0 +QSFP_DOM_OFFSET1 = 384 + +SFP_INFO_OFFSET = 0 +SFP_DOM_OFFSET = 256 + +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 7 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', + 'Length OM1(m)', 'Length Cable Assembly(m)') + +qsfp_compliance_code_tup = ( + '10/40G Ethernet Compliance Code', + 'SONET Compliance codes', + 'SAS/SATA compliance codes', + 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', + 'Fibre Channel Speed') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthOM3(UnitsOf10m)', 'LengthCable(UnitsOfm)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +info_dict_keys = ['type', 'hardwarerev', 'serialnum', + 'manufacturename', 'modelname', 'Connector', + 'encoding', 'ext_identifier', 'ext_rateselect_compliance', + 'cable_type', 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'type_abbrv_name','vendor_date', 'vendor_oui'] + +dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', + 'power_lpmode', 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power'] + +threshold_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning'] + +sff8436_parser = { + 'reset_status': [QSFP_DOM_OFFSET, 2, 1, 'parse_dom_status_indicator'], + 'rx_los': [QSFP_DOM_OFFSET, 3, 1, 'parse_dom_tx_rx_los'], + 'tx_fault': [QSFP_DOM_OFFSET, 4, 1, 'parse_dom_tx_fault'], + 'tx_disable': [QSFP_DOM_OFFSET, 86, 1, 'parse_dom_tx_disable'], + 'power_lpmode': [QSFP_DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'power_override': [QSFP_DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'Temperature': [QSFP_DOM_OFFSET, 22, 2, 'parse_temperature'], + 'Voltage': [QSFP_DOM_OFFSET, 26, 2, 'parse_voltage'], + 'ChannelMonitor': [QSFP_DOM_OFFSET, 34, 16, 'parse_channel_monitor_params'], + 'ChannelMonitor_TxPower': + [QSFP_DOM_OFFSET, 34, 24, 'parse_channel_monitor_params_with_tx_power'], + + 'cable_type': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'cable_length': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'Connector': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'encoding': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_identifier': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_rateselect_compliance': + [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'nominal_bit_rate': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'specification_compliance': + [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type_abbrv_name': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'manufacturename': [QSFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'vendor_oui': [QSFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], + 'modelname': [QSFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardwarerev': [QSFP_INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serialnum': [QSFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'vendor_date': [QSFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], + 'dom_capability': [QSFP_INFO_OFFSET, 92, 1, 'parse_qsfp_dom_capability'], + 'dom_rev': [QSFP_DOM_OFFSET, 1, 1, 'parse_sfp_dom_rev'], + 'ModuleThreshold': [QSFP_DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], + 'ChannelThreshold': [QSFP_DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], +} + +sff8472_parser = { + 'Temperature': [SFP_DOM_OFFSET, 96, 2, 'parse_temperature'], + 'Voltage': [SFP_DOM_OFFSET, 98, 2, 'parse_voltage'], + 'ChannelMonitor': [SFP_DOM_OFFSET, 100, 6, 'parse_channel_monitor_params'], + + 'cable_type': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'cable_length': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'Connector': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'type': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'encoding': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'ext_identifier': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'ext_rateselect_compliance': + [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'nominal_bit_rate': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'specification_compliance': + [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'type_abbrv_name': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'manufacturename': [SFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'vendor_oui': [SFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], + 'modelname': [SFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardwarerev': [SFP_INFO_OFFSET, 56, 4, 'parse_vendor_rev'], + 'serialnum': [SFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'vendor_date': [SFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], + 'ModuleThreshold': [SFP_DOM_OFFSET, 0, 56, 'parse_alarm_warning_threshold'], +} + + +class Sfp(SfpBase): + """ + DELLEMC Platform-specific Sfp class + """ + BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" + OIR_FD_PATH = "/sys/bus/pci/devices/0000:04:00.0/port_msi" + + def __init__(self, index, sfp_type, eeprom_path): + SfpBase.__init__(self) + self.sfp_type = sfp_type + self.index = index + self.eeprom_path = eeprom_path + self.qsfpInfo = sff8436InterfaceId() + self.qsfpDomInfo = sff8436Dom() + self.sfpInfo = sff8472InterfaceId() + self.sfpDomInfo = sff8472Dom(None,1) + + def pci_mem_read(self, mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + reg_val = struct.unpack('I', read_data_stream) + mem_val = str(reg_val)[1:-2] + # print "reg_val read:%x"%reg_val + return mem_val + + def pci_mem_write(self, mm, offset, data): + mm.seek(offset) + # print "data to write:%x"%data + mm.write(struct.pack('I', data)) + + def pci_set_value(self, resource, val, offset): + fd = os.open(resource, os.O_RDWR) + mm = mmap.mmap(fd, 0) + val = self.pci_mem_write(mm, offset, val) + mm.close() + os.close(fd) + return val + + def pci_get_value(self, resource, offset): + fd = os.open(resource, os.O_RDWR) + mm = mmap.mmap(fd, 0) + val = self.pci_mem_read(mm, offset) + mm.close() + os.close(fd) + return val + + def _read_eeprom_bytes(self, eeprom_path, offset, num_bytes): + eeprom_raw = [] + try: + eeprom = open(eeprom_path, mode="rb", buffering=0) + except IOError: + return None + + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + eeprom.seek(offset) + raw = eeprom.read(num_bytes) + except IOError: + eeprom.close() + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except BaseException: + eeprom.close() + return None + + eeprom.close() + return eeprom_raw + + def _get_eeprom_data(self, eeprom_key): + eeprom_data = None + page_offset = None + + if(self.sfp_type == 'QSFP'): + page_offset = sff8436_parser[eeprom_key][PAGE_OFFSET] + eeprom_data_raw = self._read_eeprom_bytes( + self.eeprom_path, + (sff8436_parser[eeprom_key][PAGE_OFFSET] + + sff8436_parser[eeprom_key][KEY_OFFSET]), + sff8436_parser[eeprom_key][KEY_WIDTH]) + if (eeprom_data_raw is not None): + # Offset 128 is used to retrieve sff8436InterfaceId Info + # Offset 0 is used to retrieve sff8436Dom Info + if (page_offset == 128): + if ( self.qsfpInfo is None): + return None + eeprom_data = getattr( + self.qsfpInfo, sff8436_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + if ( self.qsfpDomInfo is None): + return None + eeprom_data = getattr( + self.qsfpDomInfo, sff8436_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + page_offset = sff8472_parser[eeprom_key][PAGE_OFFSET] + eeprom_data_raw = self._read_eeprom_bytes( + self.eeprom_path, + (sff8472_parser[eeprom_key][PAGE_OFFSET] + + sff8472_parser[eeprom_key][KEY_OFFSET]), + sff8472_parser[eeprom_key][KEY_WIDTH]) + if (eeprom_data_raw is not None): + # Offset 0 is used to retrieve sff8472InterfaceId Info + # Offset 256 is used to retrieve sff8472Dom Info + if (page_offset == 0): + if ( self.sfpInfo is None): + return None + eeprom_data = getattr( + self.sfpInfo, sff8472_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + if ( self.sfpDomInfo is None): + return None + eeprom_data = getattr( + self.sfpDomInfo, sff8472_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + + return eeprom_data + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + """ + transceiver_info_dict = {} + compliance_code_dict = {} + transceiver_info_dict = dict.fromkeys(info_dict_keys, 'N/A') + # BaseInformation + iface_data = self._get_eeprom_data('type') + if (iface_data is not None): + connector = iface_data['data']['Connector']['value'] + encoding = iface_data['data']['EncodingCodes']['value'] + ext_id = iface_data['data']['Extended Identifier']['value'] + rate_identifier = iface_data['data']['RateIdentifier']['value'] + identifier = iface_data['data']['type']['value'] + type_abbrv_name=iface_data['data']['type_abbrv_name']['value'] + if(self.sfp_type == 'QSFP'): + bit_rate = str( + iface_data['data']['Nominal Bit Rate(100Mbs)']['value']) + for key in qsfp_compliance_code_tup: + if key in iface_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value'] + for key in qsfp_cable_length_tup: + if key in iface_data['data']: + cable_type = key + cable_length = str(iface_data['data'][key]['value']) + else: + bit_rate = str( + iface_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + for key in sfp_compliance_code_tup: + if key in iface_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value'] + for key in sfp_cable_length_tup: + if key in iface_data['data']: + cable_type = key + cable_length = str(iface_data['data'][key]['value']) + else: + return transceiver_info_dict + + # Vendor Date + vendor_date_data = self._get_eeprom_data('vendor_date') + if (vendor_date_data is not None): + vendor_date = vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + else: + return transceiver_info_dict + + # Vendor Name + vendor_name_data = self._get_eeprom_data('manufacturename') + if (vendor_name_data is not None): + vendor_name = vendor_name_data['data']['Vendor Name']['value'] + else: + return transceiver_info_dict + + # Vendor OUI + vendor_oui_data = self._get_eeprom_data('vendor_oui') + if (vendor_oui_data is not None): + vendor_oui = vendor_oui_data['data']['Vendor OUI']['value'] + else: + return transceiver_info_dict + + # Vendor PN + vendor_pn_data = self._get_eeprom_data('modelname') + if (vendor_pn_data is not None): + vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] + else: + return transceiver_info_dict + + # Vendor Revision + vendor_rev_data = self._get_eeprom_data('hardwarerev') + if (vendor_rev_data is not None): + vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] + else: + return transceiver_info_dict + + # Vendor Serial Number + vendor_sn_data = self._get_eeprom_data('serialnum') + if (vendor_sn_data is not None): + vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] + else: + return transceiver_info_dict + + # Fill The Dictionary and return + transceiver_info_dict['type'] = identifier + transceiver_info_dict['hardwarerev'] = vendor_rev + transceiver_info_dict['serialnum'] = vendor_sn + transceiver_info_dict['manufacturename'] = vendor_name + transceiver_info_dict['modelname'] = vendor_pn + transceiver_info_dict['Connector'] = connector + transceiver_info_dict['encoding'] = encoding + transceiver_info_dict['ext_identifier'] = ext_id + transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier + transceiver_info_dict['cable_type'] = cable_type + transceiver_info_dict['cable_length'] = cable_length + transceiver_info_dict['nominal_bit_rate'] = bit_rate + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + transceiver_info_dict['vendor_date'] = vendor_date + transceiver_info_dict['vendor_oui'] = vendor_oui + transceiver_info_dict['type_abbrv_name']=type_abbrv_name + + return transceiver_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + """ + transceiver_dom_threshold_dict = {} + transceiver_dom_threshold_dict = dict.fromkeys( + threshold_dict_keys, 'N/A') + + # Module Threshold + module_threshold_data = self._get_eeprom_data('ModuleThreshold') + if (self.sfp_type == 'QSFP'): + # Channel Threshold + channel_threshold_data = self._get_eeprom_data('ChannelThreshold') + + if (channel_threshold_data is not None and module_threshold_data is not None): + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + return transceiver_dom_threshold_dict + else: + #SFP + if (module_threshold_data is not None): + #Threshold Data + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_dict['txbiashighalarm'] = module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['txpowerlowalarm'] = module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['txpowerhighwarning'] = module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_dict['txpowerlowwarning'] = module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_dict['rxpowerhighalarm'] = module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = module_threshold_data['data']['RXPowerLowWarning']['value'] + else: + return transceiver_dom_threshold_dict + + return transceiver_dom_threshold_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + """ + tx_bias_list = [] + rx_power_list = [] + transceiver_dom_dict = {} + transceiver_dom_dict = dict.fromkeys(dom_dict_keys, 'N/A') + + # RxLos + rx_los = self.get_rx_los() + + # TxFault + tx_fault = self.get_tx_fault() + + # ResetStatus + reset_state = self.get_reset_status() + + # LowPower Mode + lp_mode = self.get_lpmode() + + # TxDisable + tx_disable = self.get_tx_disable() + + # TxDisable Channel + tx_disable_channel = self.get_tx_disable_channel() + + # Temperature + temperature = self.get_temperature() + + # Voltage + voltage = self.get_voltage() + + # Channel Monitor + tx_power_list = self.get_tx_power() + + # tx bias + tx_bias_list = self.get_tx_bias() + + # rx power + rx_power_list = self.get_rx_power() + + if (len(tx_bias_list) != 0): + transceiver_dom_dict['tx1bias'] = tx_bias_list[0] + transceiver_dom_dict['tx2bias'] = tx_bias_list[1] + transceiver_dom_dict['tx3bias'] = tx_bias_list[2] + transceiver_dom_dict['tx4bias'] = tx_bias_list[3] + + if (len(rx_power_list) != 0): + transceiver_dom_dict['rx1power'] = rx_power_list[0] + transceiver_dom_dict['rx2power'] = rx_power_list[1] + transceiver_dom_dict['rx3power'] = rx_power_list[2] + transceiver_dom_dict['rx4power'] = rx_power_list[3] + + if (len(tx_power_list) != 0): + transceiver_dom_dict['tx1power'] = tx_power_list[0] + transceiver_dom_dict['tx2power'] = tx_power_list[1] + transceiver_dom_dict['tx3power'] = tx_power_list[2] + transceiver_dom_dict['tx4power'] = tx_power_list[3] + + transceiver_dom_dict['rx_los'] = rx_los + transceiver_dom_dict['tx_fault'] = tx_fault + transceiver_dom_dict['reset_status'] = reset_state + transceiver_dom_dict['power_lpmode'] = lp_mode + transceiver_dom_dict['tx_disable'] = tx_disable + transceiver_dom_dict['tx_disable_channel'] = tx_disable_channel + transceiver_dom_dict['temperature'] = temperature + transceiver_dom_dict['voltage'] = voltage + + return transceiver_dom_dict + + def get_name(self): + """ + Retrieves the name of the sfp + Returns : QSFP or QSFP+ or QSFP28 + """ + + iface_data = self._get_eeprom_data('type') + if (iface_data is not None): + identifier = iface_data['data']['type']['value'] + else: + return None + + return identifier + + def get_presence(self): + """ + Retrieves the presence of the sfp + Returns : True if sfp is present and false if it is absent + """ + # Check for invalid port_num + + # Port offset starts with 0x4004 + port_offset = 16388 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + if(self.sfp_type == 'QSFP'): + mask = (1 << 4) + + # Mask off 1st bit for presence 65,66 + if (self.sfp_type == 'SFP'): + mask = (1 << 0) + # ModPrsL is active low + if reg_value & mask == 0: + return True + + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the sfp + """ + vendor_pn_data = self._get_eeprom_data('modelname') + if (vendor_pn_data is not None): + vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] + else: + return None + + return vendor_pn + + def get_serial(self): + """ + Retrieves the serial number of the sfp + """ + vendor_sn_data = self._get_eeprom_data('serialnum') + if (vendor_sn_data is not None): + vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] + else: + return None + + return vendor_sn + + def get_reset_status(self): + """ + Retrives the reset status of SFP + """ + reset_status = False + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return reset_status + + # Mask off 4th bit for reset status + mask = (1 << 4) + + if ((reg_value & mask) == 0): + reset_status = True + else: + reset_status = False + + return reset_status + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + """ + rx_los = None + rx_los_list = [] + if (self.sfp_type == 'QSFP'): + rx_los_data = self._get_eeprom_data('rx_los') + if (rx_los_data is not None): + rx_los = rx_los_data['data']['Rx1LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + rx_los = rx_los_data['data']['Rx2LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + rx_los = rx_los_data['data']['Rx3LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + rx_los = rx_los_data['data']['Rx4LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + + if (rx_los_list[0] and rx_los_list[1] + and rx_los_list[2] and rx_los_list[3]): + rx_los = True + else: + rx_los = False + else: + rx_los_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if (rx_los_data is not None): + data = int(rx_los_data[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + """ + tx_fault = None + tx_fault_list = [] + if (self.sfp_type == 'QSFP'): + tx_fault_data = self._get_eeprom_data('tx_fault') + if (tx_fault_data is not None): + tx_fault = tx_fault_data['data']['Tx1Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + tx_fault = tx_fault_data['data']['Tx2Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + tx_fault = tx_fault_data['data']['Tx3Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + tx_fault = tx_fault_data['data']['Tx4Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + + if (tx_fault_list[0] and tx_fault_list[1] + and tx_fault_list[2] and tx_fault_list[3]): + tx_fault = True + else: + tx_fault = False + + else: + tx_fault_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if (tx_fault_data is not None): + data = int(tx_fault_data[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + """ + tx_disable = None + tx_disable_list = [] + if (self.sfp_type == 'QSFP'): + tx_disable_data = self._get_eeprom_data('tx_disable') + if (tx_disable_data is not None): + tx_disable = tx_disable_data['data']['Tx1Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + tx_disable = tx_disable_data['data']['Tx2Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + tx_disable = tx_disable_data['data']['Tx3Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + tx_disable = tx_disable_data['data']['Tx4Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + + if (tx_disable_list[0] and tx_disable_list[1] + and tx_disable_list[2] and tx_disable_list[3]): + tx_disable = True + else: + tx_disable = False + + else: + tx_disable_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if (tx_disable_data is not None): + data = int(tx_disable_data[0], 16) + tx_disable_hard = (sffbase().test_bit(data, SFP_TX_DISABLE_HARD_BIT) != 0) + tx_disable_soft = (sffbase().test_bit(data, SFP_TX_DISABLE_SOFT_BIT) != 0) + tx_disable = tx_disable_hard | tx_disable_soft + + + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + """ + tx_disable = None + tx_disable_list = [] + tx_disable_channel = 0 + + if (self.sfp_type == 'QSFP'): + tx_disable_data = self._get_eeprom_data('tx_disable') + if (tx_disable_data is not None): + tx_disable = tx_disable_data['data']['Tx1Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + tx_disable = tx_disable_data['data']['Tx2Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + tx_disable = tx_disable_data['data']['Tx3Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + tx_disable = tx_disable_data['data']['Tx4Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + + bit4 = int(tx_disable_list[3]) * 8 + bit3 = int(tx_disable_list[2]) * 4 + bit2 = int(tx_disable_list[1]) * 2 + bit1 = int(tx_disable_list[0]) * 1 + + tx_disable_channel = hex(bit4 + bit3 + bit2 + bit1) + + return tx_disable_channel + + def get_lpmode(self): + """ + Retrieves the lpmode(low power mode) of this SFP + """ + lpmode_state = False + if (self.sfp_type == 'QSFP'): + + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return lpmode_state + + # Mask off 6th bit for lpmode + mask = (1 << 6) + + # LPMode is active high + if reg_value & mask == 0: + lpmode_state = False + else: + lpmode_state = True + + return lpmode_state + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + """ + power_override_state = False + + if (self.sfp_type == 'QSFP'): + power_override_data = self._get_eeprom_data('power_override') + if (power_override_data is not None): + power_override = power_override_data['data']['PowerOverRide']['value'] + if (power_override is 'On'): + power_override_state = True + else: + power_override_state = False + + return power_override_state + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + """ + temperature = None + + temperature_data = self._get_eeprom_data('Temperature') + if (temperature_data is not None): + temperature = temperature_data['data']['Temperature']['value'] + + return temperature + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + """ + voltage = None + + voltage_data = self._get_eeprom_data('Voltage') + if (voltage_data is not None): + voltage = voltage_data['data']['Vcc']['value'] + + return voltage + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + """ + tx_bias = None + tx_bias_list = [] + + tx_bias_data = self._get_eeprom_data('ChannelMonitor') + if (tx_bias_data is not None): + if (self.sfp_type == 'QSFP'): + tx_bias = tx_bias_data['data']['TX1Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = tx_bias_data['data']['TX2Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = tx_bias_data['data']['TX3Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = tx_bias_data['data']['TX4Bias']['value'] + tx_bias_list.append(tx_bias) + else: + tx1_bias = tx_bias_data['data']['TXBias']['value'] + return [tx1_bias, "N/A", "N/A", "N/A"] + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + """ + rx_power = None + rx_power_list = [] + + rx_power_data = self._get_eeprom_data('ChannelMonitor') + if (rx_power_data is not None): + if (self.sfp_type == 'QSFP'): + rx_power = rx_power_data['data']['RX1Power']['value'] + rx_power_list.append(rx_power) + rx_power = rx_power_data['data']['RX2Power']['value'] + rx_power_list.append(rx_power) + rx_power = rx_power_data['data']['RX3Power']['value'] + rx_power_list.append(rx_power) + rx_power = rx_power_data['data']['RX4Power']['value'] + rx_power_list.append(rx_power) + else: + rx1_pw = rx_power_data['data']['RXPower']['value'] + return [rx1_pw, "N/A", "N/A", "N/A"] + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + """ + tx_power_list = [] + if(self.sfp_type == 'QSFP'): + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qspf_dom_capability_data = self._get_eeprom_data('dom_capability') + qsfp_dom_rev_data = self._get_eeprom_data('dom_rev') + if (qspf_dom_capability_data is not None and qsfp_dom_rev_data is not None): + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + else: + return tx_power_list + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + return tx_power_list + else: + channel_monitor_data = self._get_eeprom_data('ChannelMonitor_TxPower') + if (channel_monitor_data is not None): + tx1_pw = channel_monitor_data['data']['TX1Power']['value'] + tx2_pw = channel_monitor_data['data']['TX2Power']['value'] + tx3_pw = channel_monitor_data['data']['TX3Power']['value'] + tx4_pw = channel_monitor_data['data']['TX4Power']['value'] + else: + return tx_power_list + + else: + channel_monitor_data = self._get_eeprom_data('ChannelMonitor') + if (channel_monitor_data is not None): + tx1_pw = channel_monitor_data['data']['TXPower']['value'] + tx2_pw = 'N/A' + tx3_pw = 'N/A' + tx4_pw = 'N/A' + else: + return tx_power_list + + tx_power_list.append(tx1_pw) + tx_power_list.append(tx2_pw) + tx_power_list.append(tx3_pw) + tx_power_list.append(tx4_pw) + + return tx_power_list + + def reset(self): + """ + Reset the SFP and returns all user settings to their default state + """ + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for reset + mask = (1 << 4) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + # Sleep 1 second to allow it to settle + time.sleep(1) + + reg_value = reg_value | mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + else: + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode(low power mode) of this SFP + """ + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 6th bit for lowpower mode + mask = (1 << 6) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + else: + return False + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + """ + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + """ + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + """ + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + """ + return False + + def get_status(self): + """ + Retrieves the operational status of the device + """ + reset = self.get_reset_status() + + if (reset == True): + status = False + else: + status = True + + return status From 38b7d302955b4e56010051676bcd0443a636028b Mon Sep 17 00:00:00 2001 From: brandonchuang Date: Fri, 24 Jan 2020 04:20:20 +0800 Subject: [PATCH 0315/1427] [device] as7326-56x: Fix the default low power mode on issue (#4047) Signed-off-by: brandon_chuang --- .../x86_64-accton_as7326_56x-r0/plugins/sfputil.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py index 0292e2d52e1a..b88536ecfeb2 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py @@ -175,12 +175,13 @@ def get_low_power_mode(self, port_num): eeprom.seek(93) lpmode = ord(eeprom.read(1)) - if ((lpmode & 0x3) == 0x1): - return False # High Power Mode if "Power override" bit is 1 and "Power set" bit is 0 + if ((lpmode & 0x3) == 0x3): + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 else: - return True # Low Power Mode if one of the following conditions is matched: - # 1. Power override" bit is 0 - # 2. Power override" bit is 1 and "Power set" bit is 1 + return False # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + except IOError as e: print "Error: unable to open file: %s" % str(e) return False From 70e8c5e29ef50ebb9b1318f82cea8f70d0e4412f Mon Sep 17 00:00:00 2001 From: wangshengjun Date: Fri, 24 Jan 2020 06:41:02 +0800 Subject: [PATCH 0316/1427] [FRR]there is no need to checkout master branch after compiling frr. (#3941) Signed-off-by: wangshengjun --- src/sonic-frr/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index abd9adc3fc67..9ecade09f71d 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -21,7 +21,6 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git checkout $(FRR_BRANCH) stg branch --delete $(STG_BRANCH) git rev-parse --short HEAD | xargs git checkout - git checkout master git branch -D $(FRR_BRANCH) popd mv $(DERIVED_TARGET) $* $(DEST)/ From fd6df31b5b50617fb9a9730a8841511599cc8870 Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Fri, 24 Jan 2020 06:20:17 +0530 Subject: [PATCH 0317/1427] [Platform] ARM64 support for Marvell ARM platform (#4043) [Makefile] Fix for multi docker issue on 19 version above Signed-off-by: Antony Rheneus --- Makefile.work | 16 +- build_debian.sh | 13 +- dockers/docker-base-stretch/Dockerfile.j2 | 4 +- installer/arm64/install.sh | 142 +++++++++-- onie-image-arm64.conf | 3 + .../marvell-arm64/docker-saiserver-mrvl.mk | 1 - platform/marvell-arm64/linux-kernel-arm64.mk | 13 +- platform/marvell-arm64/linux/Makefile | 6 +- platform/marvell-arm64/one-image.mk | 1 + platform/marvell-arm64/platform.conf | 226 ++++++++++++++++++ platform/marvell-arm64/rules.mk | 11 +- platform/marvell-arm64/sai.mk | 2 +- platform/marvell-armhf/rules.mk | 5 +- platform/marvell/rules.mk | 2 +- sonic-slave-jessie/Dockerfile.j2 | 6 +- 15 files changed, 395 insertions(+), 56 deletions(-) mode change 100644 => 100755 installer/arm64/install.sh diff --git a/Makefile.work b/Makefile.work index a1ccf8715567..4810afd97da6 100644 --- a/Makefile.work +++ b/Makefile.work @@ -130,12 +130,16 @@ ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) DOCKER_SERVICE_SAFE_KILLER := (MARCH_PID=`ps -eo pid,cmd | grep "[0-9] dockerd.*march" | awk '{print $$1}'`; echo "Killing march docker $$MARCH_PID"; [ -z "$$MARCH_PID" ] || sudo kill -9 "$$MARCH_PID";) DOCKER_SERVICE_MULTIARCH_CHECK := ($(DOCKER_SERVICE_SAFE_KILLER); sudo rm -fr /var/run/march/; (echo "Starting docker march service..."; sudo $(SONIC_NATIVE_DOCKERD_FOR_MUTLIARCH) &) &>/dev/null ; sleep 2; sudo $(SONIC_USERFACL_DOCKERD_FOR_MUTLIARCH);) - # Docker service to load the compiled dockers-*.gz - SONIC_NATIVE_DOCKERD_FOR_DOCKERFS := rm -fr $(PWD)/dockerfs/; mkdir -p $(PWD)/dockerfs/; sudo dockerd --storage-driver=overlay2 --iptables=false \ - --data-root $(PWD)/dockerfs/var/lib/docker/ --exec-root=$(PWD)/dockerfs/var/run/docker/ \ - -H unix://$(PWD)/dockerfs/var/run/docker.sock -p $(PWD)/dockerfs/var/run/docker.pid & - SONIC_USERFACL_DOCKERD_FOR_DOCKERFS := setfacl -m user:$(USER):rw $(PWD)/dockerfs/var/run/docker.sock - DOCKER_SERVICE_DOCKERFS_CHECK := (sudo docker -H unix://$(PWD)/dockerfs/var/run/docker.sock info &> /dev/null && sudo kill -9 `sudo cat $(PWD)/dockerfs/var/run/docker.pid` && false) || (echo "Starting docker build service..."; (sudo $(SONIC_NATIVE_DOCKERD_FOR_DOCKERFS) ) &>/dev/null ; sleep 1; sudo $(SONIC_USERFACL_DOCKERD_FOR_DOCKERFS);) + # Docker service to load the compiled dockers-*.gz + # docker 19.0 version above has path/length restriction, so replaced it with soft link in /tmp/ + # Also dockerd does mkdir on the provided softlink, so used two level path "d/d" + D_ROOT=/tmp/d/d + SONIC_NATIVE_DOCKERD_FOR_DOCKERFS := rm -fr $(PWD)/dockerfs; mkdir -p $(PWD)/dockerfs; sudo rm -fr /tmp/d; mkdir -p /tmp/d; ln -s -f $(PWD)/dockerfs $(D_ROOT); \ + sudo dockerd --storage-driver=overlay2 --iptables=false \ + --data-root $(D_ROOT)/var/lib/docker/ --exec-root=$(D_ROOT)/var/run/docker/ \ + -H unix://$(D_ROOT)/var/run/docker.sock -p $(D_ROOT)/var/run/docker.pid & + SONIC_USERFACL_DOCKERD_FOR_DOCKERFS := setfacl -m user:$(USER):rw $(D_ROOT)/var/run/docker.sock + DOCKER_SERVICE_DOCKERFS_CHECK := (sudo docker -H unix://$(D_ROOT)/var/run/docker.sock info &> /dev/null && sudo kill -9 `sudo cat $(D_ROOT)/var/run/docker.pid` && false) || (echo "Starting docker build service..."; (sudo $(SONIC_NATIVE_DOCKERD_FOR_DOCKERFS) ) &> /tmp/dockerfs.log ; sleep 1; sudo $(SONIC_USERFACL_DOCKERD_FOR_DOCKERFS);) endif diff --git a/build_debian.sh b/build_debian.sh index 57c85e033f58..8bbbd0868e74 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -500,8 +500,8 @@ fi sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y remove gcc libpython2.7-dev ## Add mtd and uboot firmware tools package -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install u-boot-tools mtd-utils -sudo LANG=C chroot $FILESYSTEM_ROOT apt-mark manual u-boot-tools mtd-utils +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install u-boot-tools mtd-utils device-tree-compiler +sudo LANG=C chroot $FILESYSTEM_ROOT apt-mark manual u-boot-tools mtd-utils device-tree-compiler ## Update initramfs sudo chroot $FILESYSTEM_ROOT update-initramfs -u @@ -510,10 +510,13 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then INITRD_FILE=initrd.img-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH} if [[ $CONFIGURED_ARCH == armhf ]]; then INITRD_FILE=initrd.img-${LINUX_KERNEL_VERSION}-armmp + sudo LANG=C chroot $FILESYSTEM_ROOT mkimage -A arm -O linux -T ramdisk -C gzip -d /boot/$INITRD_FILE /boot/u${INITRD_FILE} + ## Overwriting the initrd image with uInitrd + sudo LANG=C chroot $FILESYSTEM_ROOT mv /boot/u${INITRD_FILE} /boot/$INITRD_FILE + elif [[ $CONFIGURED_ARCH == arm64 ]]; then + sudo cp -v $PLATFORM_DIR/${sonic_asic_platform}-${CONFIGURED_ARCH}/sonic_fit.its $FILESYSTEM_ROOT/boot/ + sudo LANG=C chroot $FILESYSTEM_ROOT mkimage -f /boot/sonic_fit.its /boot/sonic_${CONFIGURED_ARCH}.fit fi - sudo LANG=C chroot $FILESYSTEM_ROOT mkimage -A arm -O linux -T ramdisk -C gzip -d /boot/$INITRD_FILE /boot/u${INITRD_FILE} - ## Overwriting the initrd image with uInitrd - sudo LANG=C chroot $FILESYSTEM_ROOT mv /boot/u${INITRD_FILE} /boot/$INITRD_FILE fi ## Clean up apt diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index dea58a210f89..65b7f9d537ce 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -56,12 +56,10 @@ RUN apt-get update && \ lua-bitop \ lua-cjson -{% if CONFIGURED_ARCH == "armhf" %} -# ip and ifconfig utility missing in docker for armhf +# ip and ifconfig utility missing in docker for arm arch RUN apt-get -y install \ iproute2 \ net-tools -{% endif %} RUN mkdir -p /etc/supervisor /var/log/supervisor diff --git a/installer/arm64/install.sh b/installer/arm64/install.sh old mode 100644 new mode 100755 index e4a24214da38..280d9f200af9 --- a/installer/arm64/install.sh +++ b/installer/arm64/install.sh @@ -1,9 +1,18 @@ #!/bin/sh -# Copyright (C) 2014,2015 Curt Brune -# Copyright (C) 2015 david_yang +# Copyright (C) Marvell Inc # -# SPDX-License-Identifier: GPL-2.0 + +_trap_push() { + local next="$1" + eval "trap_push() { + local oldcmd='$(echo "$next" | sed -e s/\'/\'\\\\\'\'/g)' + local newcmd=\"\$1; \$oldcmd\" + trap -- \"\$newcmd\" EXIT INT TERM HUP + _trap_push \"\$newcmd\" + }" +} +_trap_push true set -e @@ -28,35 +37,124 @@ if [ -r ./onie-image-arm64.conf ]; then . ./onie-image-arm64.conf fi +echo "ONIE Installer: platform: $platform" -echo "Installer: platform: $platform" +# Make sure run as root or under 'sudo' +if [ $(id -u) -ne 0 ] + then echo "Please run as root" + exit 1 +fi -install_uimage() { - echo "Copying uImage to NOR flash:" - flashcp -v demo-${platform}.itb $mtd_dev -} +if [ -r /etc/machine.conf ]; then + . /etc/machine.conf +elif [ -r /host/machine.conf ]; then + . /host/machine.conf +elif [ "$install_env" != "build" ]; then + echo "cannot find machine.conf" + exit 1 +fi + +echo "onie_platform: $onie_platform" + +# Get platform specific linux kernel command line arguments +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="" + +# Default var/log device size in MB +VAR_LOG_SIZE=4096 + +[ -r platforms/$onie_platform ] && . platforms/$onie_platform + + +# If running in ONIE +if [ "$install_env" = "onie" ]; then + # The onie bin tool prefix + onie_bin= + # The persistent ONIE directory location + onie_root_dir=/mnt/onie-boot/onie + # The onie file system root + onie_initrd_tmp=/ +fi + +# The build system prepares this script by replacing %%DEMO-TYPE%% +# with "OS" or "DIAG". +demo_type="%%DEMO_TYPE%%" + +# The build system prepares this script by replacing %%IMAGE_VERSION%% +# with git revision hash as a version identifier +image_version="%%IMAGE_VERSION%%" +timestamp="$(date -u +%Y%m%d)" + +demo_volume_label="SONiC-${demo_type}" +demo_volume_revision_label="SONiC-${demo_type}-${image_version}" -hw_load() { - echo "cp.b $img_start \$loadaddr $img_sz" -} . ./platform.conf -install_uimage +image_dir="image-$image_version" + +if [ "$install_env" = "onie" ]; then + # Create/format the flash + create_partition + mount_partition +elif [ "$install_env" = "sonic" ]; then + demo_mnt="/host" + eval running_sonic_revision=$(cat /etc/sonic/sonic_version.yml | grep build_version | cut -f2 -d" ") + # Prevent installing existing SONiC if it is running + if [ "$image_dir" = "image-$running_sonic_revision" ]; then + echo "Not installing SONiC version $running_sonic_revision, as current running SONiC has the same version" + exit 0 + fi + # Remove extra SONiC images if any + for f in $demo_mnt/image-* ; do + if [ -d $f ] && [ "$f" != "$demo_mnt/image-$running_sonic_revision" ] && [ "$f" != "$demo_mnt/$image_dir" ]; then + echo "Removing old SONiC installation $f" + rm -rf $f + fi + done +fi -hw_load_str="$(hw_load)" +# Create target directory or clean it up if exists +if [ -d $demo_mnt/$image_dir ]; then + echo "Directory $demo_mnt/$image_dir/ already exists. Cleaning up..." + rm -rf $demo_mnt/$image_dir/* +else + mkdir $demo_mnt/$image_dir || { + echo "Error: Unable to create SONiC directory" + exit 1 + } +fi -echo "Updating U-Boot environment variables" -(cat < /tmp/env.txt +# Decompress the file for the file system directly to the partition +if [ x"$docker_inram" = x"on" ]; then + # when disk is small, keep dockerfs.tar.gz in disk, expand it into ramfs during initrd + unzip -o $ONIE_INSTALLER_PAYLOAD -d $demo_mnt/$image_dir +else + unzip -o $ONIE_INSTALLER_PAYLOAD -x "$FILESYSTEM_DOCKERFS" -d $demo_mnt/$image_dir + + if [ "$install_env" = "onie" ]; then + TAR_EXTRA_OPTION="--numeric-owner" + else + TAR_EXTRA_OPTION="--numeric-owner --warning=no-timestamp" + fi + mkdir -p $demo_mnt/$image_dir/$DOCKERFS_DIR + unzip -op $ONIE_INSTALLER_PAYLOAD "$FILESYSTEM_DOCKERFS" | tar xz $TAR_EXTRA_OPTION -f - -C $demo_mnt/$image_dir/$DOCKERFS_DIR +fi -fw_setenv -f -s /tmp/env.txt -cd / +if [ "$install_env" = "onie" ]; then + # Store machine description in target file system + if [ -f /etc/machine-build.conf ]; then + # onie_ variable are generate at runtime. + # they are no longer hardcoded in /etc/machine.conf + # also remove single quotes around the value + set | grep ^onie | sed -e "s/='/=/" -e "s/'$//" > $demo_mnt/machine.conf + else + cp /etc/machine.conf $demo_mnt + fi +fi + +# Update Bootloader Menu with installed image +bootloader_menu_config # Set NOS mode if available. For manufacturing diag installers, you # probably want to skip this step so that the system remains in ONIE diff --git a/onie-image-arm64.conf b/onie-image-arm64.conf index f14e5602c21d..2bbadb3aeac4 100644 --- a/onie-image-arm64.conf +++ b/onie-image-arm64.conf @@ -24,6 +24,9 @@ FILESYSTEM_DOCKERFS=dockerfs.tar.gz ## docker directory on the root filesystem DOCKERFS_DIR=docker +## docker ramfs disk space +DOCKER_RAMFS_SIZE=900M + ## Output file name for onie installer OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin diff --git a/platform/marvell-arm64/docker-saiserver-mrvl.mk b/platform/marvell-arm64/docker-saiserver-mrvl.mk index 398902961da8..07dac2a4610d 100644 --- a/platform/marvell-arm64/docker-saiserver-mrvl.mk +++ b/platform/marvell-arm64/docker-saiserver-mrvl.mk @@ -3,7 +3,6 @@ DOCKER_SAISERVER_MRVL = docker-saiserver-mrvl.gz $(DOCKER_SAISERVER_MRVL)_PATH = $(PLATFORM_PATH)/docker-saiserver-mrvl $(DOCKER_SAISERVER_MRVL)_DEPENDS += $(SAISERVER) -$(DOCKER_SAISERVER_MRVL)_FILES += $(DSSERVE) $(BCMCMD) $(DOCKER_SAISERVER_MRVL)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_MRVL) diff --git a/platform/marvell-arm64/linux-kernel-arm64.mk b/platform/marvell-arm64/linux-kernel-arm64.mk index ba7638ad108c..2c5438db982d 100644 --- a/platform/marvell-arm64/linux-kernel-arm64.mk +++ b/platform/marvell-arm64/linux-kernel-arm64.mk @@ -1,10 +1,7 @@ # linux kernel package for marvell arm64 -KVERSION = 4.9.168 - - -LINUX_KERNEL = linux-image-4.9.168-arm64.deb -export LINUX_KERNEL - -$(LINUX_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/linux -SONIC_MAKE_DEBS += $(LINUX_KERNEL) +# Add platform specific DTB +LINUX_KERNEL_DTB = linux-image-4.9.168-arm64.deb +$(LINUX_KERNEL_DTB)_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/arm64/kernel/$(LINUX_KERNEL_DTB) +SONIC_ONLINE_DEBS += $(LINUX_KERNEL_DTB) +SONIC_STRETCH_DEBS += $(LINUX_KERNEL_DTB) diff --git a/platform/marvell-arm64/linux/Makefile b/platform/marvell-arm64/linux/Makefile index 3b43f181dc71..89415f493c0b 100644 --- a/platform/marvell-arm64/linux/Makefile +++ b/platform/marvell-arm64/linux/Makefile @@ -2,9 +2,9 @@ SHELL = /bin/bash .SHELLFLAGS += -e -LINUX_KERNEL_MRVL_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/arm64/kernel/$(LINUX_KERNEL) +LINUX_KERNEL_MRVL_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/arm64/kernel/$(LINUX_KERNEL_DTB) -$(addprefix $(DEST)/, $(LINUX_KERNEL)): $(DEST)/% : +$(addprefix $(DEST)/, $(LINUX_KERNEL_DTB)): $(DEST)/% : # get deb package - wget -O $(DEST)/$(LINUX_KERNEL) $(LINUX_KERNEL_MRVL_URL) + wget -O $(DEST)/$(LINUX_KERNEL_DTB) $(LINUX_KERNEL_MRVL_URL) diff --git a/platform/marvell-arm64/one-image.mk b/platform/marvell-arm64/one-image.mk index 3a68f54fcdf7..3d916be4e852 100644 --- a/platform/marvell-arm64/one-image.mk +++ b/platform/marvell-arm64/one-image.mk @@ -4,6 +4,7 @@ SONIC_ONE_IMAGE = sonic-marvell-arm64.bin $(SONIC_ONE_IMAGE)_MACHINE = marvell-arm64 $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +$(SONIC_ONE_IMAGE)_INSTALLS += $(LINUX_KERNEL_DTB) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/marvell-arm64/platform.conf b/platform/marvell-arm64/platform.conf index e69de29bb2d1..15f25a27b6b9 100644 --- a/platform/marvell-arm64/platform.conf +++ b/platform/marvell-arm64/platform.conf @@ -0,0 +1,226 @@ +# Copyright (C) Marvell Inc + +# over ride default behaviour + +echo "Preparing for installation ... " + +IS_MASS=0 +# global defines +kernel_addr=0x1100000 +fdt_addr=0x1000000 +fit_addr=0x1000000 +initrd_addr=0x2000000 +VAR_LOG=512 +DISK_SIZE=9 + +kernel_fname="/boot/vmlinuz-4.9.0-9-2-arm64" +initrd_fname="/boot/initrd.img-4.9.0-9-2-arm64" +fdt_fname="/boot/armada-7020-comexpress.dtb" +fit_fname="/boot/sonic_arm64.fit" + +# global mount defines +#demo_dev=/dev/sda1 +demo_mnt=/tmp +#mtd_dev=/dev/$(cat /proc/mtd | grep "ENV" | grep -o "mtd[0-9]") +FW_ENV_DEFAULT='/dev/mtd1 0x0 0x10000 0x100000' +UBOOT_FW_DEFAULT=1 + +# Skip VID Header in UBIFS +LINUX_MISC_CMD='apparmor=1 security=apparmor usbcore.autosuspend=-1' + +prepare_boot_menu() { + echo "Sync up cache ..." + sync + echo "Setting up U-Boot environment..." + + DTB_HAS_ENV_BLK=$(grep uboot-env /proc/mtd | sed -e 's/:.*$//') + if [ -c "/dev/$DTB_HAS_ENV_BLK" ]; then + PROC_ENV_FILE=$(find /proc/device-tree/ -name env_size) + if [ -n "$PROC_ENV_FILE" ] + then + UBOOT_ENV_SIZ="0x$(hd $PROC_ENV_FILE | awk 'FNR==1 {print $2 $3 $4 $5}')" + UBOOT_ENV_ERASE_SIZ="0x$(grep uboot-env /proc/mtd | awk '{print $3}')" + if [[ -n "$UBOOT_ENV_SIZ" && -n "$UBOOT_ENV_ERASE_SIZ" ]] + then + # Env info from DTB + FW_ENV_DTB="/dev/$DTB_HAS_ENV_BLK 0x00000000 $UBOOT_ENV_SIZ $UBOOT_ENV_ERASE_SIZ" + fi + fi + fi + if [ $UBOOT_FW_DEFAULT -eq 1 ] + then + echo $FW_ENV_DEFAULT > /etc/fw_env.config + echo "Using pre-configured uboot env" + fi + image_name=${image_dir}${kernel_fname} + initrd_name=${image_dir}${initrd_fname} + fdt_name=${image_dir}${fdt_fname} + fit_name=${image_dir}${fit_fname} + + if [ "$install_env" = "onie" ]; then + FW_ARG="-f" + image_dir_old="" + image_name_old="" + initrd_name_old="" + fdt_name_old="" + fit_name_old="" + sonic_version_2="None" + else + image_dir_old=$(fw_printenv -n image_dir || true) + image_name_old=$(fw_printenv -n image_name || true) + initrd_name_old=$(fw_printenv -n initrd_name || true) + fdt_name_old=$(fw_printenv -n fdt_name || true) + fit_name_old=$(fw_printenv -n fit_name || true) + sonic_version_2=$(fw_printenv -n sonic_version_1 || true) + if [ -z "$demo_dev" ] + then + get_install_device + if [ $? -ne 0 ]; then + echo "Error: Unable to detect $blk_dev $demo_dev" + exit 1 + fi + if [ ${IS_MASS} -eq 1 ] + then + demo_dev=${blk_dev}1 + else + #demo_dev=$(echo $blk_dev | sed -e 's/\(mmcblk[0-9]\)/\1p/')$demo_part + demo_dev=/dev/mmcblk0p1 + fi + fi + fi + + # Set boot variables + fw_setenv ${FW_ARG} image_dir $image_dir > /dev/null + fw_setenv ${FW_ARG} image_name $image_name > /dev/null + fw_setenv ${FW_ARG} initrd_name $initrd_name > /dev/null + fw_setenv ${FW_ARG} fdt_name $fdt_name > /dev/null + fw_setenv ${FW_ARG} fit_name $fit_name > /dev/null + fw_setenv ${FW_ARG} sonic_version_1 $demo_volume_revision_label > /dev/null + fw_setenv ${FW_ARG} image_dir_old $image_dir_old > /dev/null + fw_setenv ${FW_ARG} image_name_old $image_name_old > /dev/null + fw_setenv ${FW_ARG} initrd_name_old $initrd_name_old > /dev/null + fw_setenv ${FW_ARG} fdt_name_old $fdt_name_old > /dev/null + fw_setenv ${FW_ARG} fit_name_old $fit_name_old > /dev/null + fw_setenv ${FW_ARG} sonic_version_2 $sonic_version_2 > /dev/null + BOOT1='echo " > Boot1: $sonic_version_1 - run sonic_image_1";echo;' + BOOT2='echo " > Boot2: $sonic_version_2 - run sonic_image_2";echo;' + BOOT3='echo " > Boot3: ONIE - run onie-nand-boot";echo;' + BORDER='echo "---------------------------------------------------";echo;' + fw_setenv ${FW_ARG} print_menu $BORDER $BOOT1 $BOOT2 $BOOT3 $BORDER > /dev/null + + fw_setenv ${FW_ARG} linuxargs "net.ifnames=0 loopfstype=squashfs loop=$image_dir/$FILESYSTEM_SQUASHFS varlog_size=$VAR_LOG" > /dev/null + fw_setenv ${FW_ARG} linuxargs_old "net.ifnames=0 loopfstype=squashfs loop=$image_dir_old/$FILESYSTEM_SQUASHFS varlog_size=$VAR_LOG" > /dev/null + sonic_bootargs_old='setenv bootargs root='$demo_dev' rw rootwait rootfstype=ext4 panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts} ${linuxargs_old}' + fw_setenv ${FW_ARG} sonic_bootargs_old $sonic_bootargs_old > /dev/null || true + sonic_boot_load_old=$(fw_printenv -n sonic_boot_load || true) + old_str="_old" + fw_setenv ${FW_ARG} sonic_boot_load_old $sonic_boot_load_old$old_str > /dev/null || true + + fw_setenv ${FW_ARG} kernel_addr $kernel_addr > /dev/null + fw_setenv ${FW_ARG} fdt_addr $fdt_addr > /dev/null + fw_setenv ${FW_ARG} fit_addr $fit_addr > /dev/null + fw_setenv ${FW_ARG} initrd_addr $initrd_addr > /dev/null + # Set boot configs + if [ ${IS_MASS} -eq 1 ] + then + #USB_LOAD='ext4load usb 0 $kernel_addr $image_name; ext4load usb 0 $fdt_addr $fdt_name; ext4load usb 0 $initrd_addr $initrd_name' + USB_LOAD='ext4load usb 0 $fit_addr $fit_name' + fw_setenv ${FW_ARG} sonic_boot_load $USB_LOAD > /dev/null + else + #MMC_LOAD='ext4load mmc 0:'$demo_part' $kernel_addr $image_name; ext4load mmc 0:'$demo_part' $fdt_addr $fdt_name; ext4load mmc 0:'$demo_part' $initrd_addr $initrd_name' + MMC_LOAD='ext4load mmc 0:'$demo_part' $fit_addr $fit_name' + fw_setenv ${FW_ARG} sonic_boot_load $MMC_LOAD > /dev/null + fi + #SONIC_BOOT_CMD='run sonic_bootargs; run sonic_boot_load; booti $kernel_addr $initrd_addr $fdt_addr' + SONIC_BOOT_CMD='run sonic_bootargs; run sonic_boot_load; bootm $fit_addr' + SONIC_BOOT_CMD_OLD='run sonic_bootargs_old; run sonic_boot_load_old; bootm $fit_addr' + BOOTARGS='setenv bootargs root='$demo_dev' rw rootwait rootfstype=ext4 panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts} ${linuxargs}' + fw_setenv ${FW_ARG} sonic_bootargs $BOOTARGS > /dev/null + fw_setenv ${FW_ARG} sonic_bootcmd $SONIC_BOOT_CMD > /dev/null + fw_setenv ${FW_ARG} sonic_image_2 $SONIC_BOOT_CMD_OLD > /dev/null + fw_setenv ${FW_ARG} sonic_image_1 "$SONIC_BOOT_CMD" > /dev/null + fw_setenv ${FW_ARG} boot_next 'run sonic_image_1'> /dev/null + fw_setenv ${FW_ARG} bootcmd 'run print_menu; usb start; test -n "$boot_once" && run boot_once; run boot_next' > /dev/null + +} + +#Get block device +#Default block device is eMMC, if not look for usb storage +get_install_device() +{ + mass_bus="target0:0:0" + for i in a b c ; do + if $(ls -l /sys/block/sd$i/device 2>/dev/null | grep -q "$mass_bus") ; then + echo "/dev/sd$i" + blk_dev=/dev/sd$i + IS_MASS=1 + echo "Selected Mass storage $blk_dev" + return 0 + fi + done + mmc_bus="mmc0:aaaa" + for i in 0 1 2 ; do + if $(ls -l /sys/block/mmcblk$i/device 2>/dev/null | grep -q "$mmc_bus") ; then + echo "/dev/mmcblk$i" + blk_dev=/dev/mmcblk$i + echo "Selected mmc $blk_dev" + return 0 + fi + done + + echo "ERROR storage not found" + return 1 +} + +create_demo_partition() { + + if [ ${IS_MASS} -eq 1 ] + then + # USB drive + parted -s $blk_dev rm 1 || true + partprobe || true + parted -s --align optimal $blk_dev unit gb mkpart primary 1 $DISK_SIZE || true + partprobe || true + else + # SD CARD + parted -s /dev/mmcblk0 rm 1 + partprobe + parted -s --align optimal /dev/mmcblk0 unit gb mkpart primary 1 $DISK_SIZE + partprobe + fi +} + +create_partition() { + get_install_device + if [ $? -ne 0 ]; then + echo "Error: Unable to detect $blk_dev $demo_dev" + exit 1 + fi + # Platform specific partition + create_demo_partition +} + +mount_partition() { + if [ ${IS_MASS} -eq 1 ] + then + demo_dev=${blk_dev}1 + else + #demo_dev=$(echo $blk_dev | sed -e 's/\(mmcblk[0-9]\)/\1p/')$demo_part + demo_dev=/dev/mmcblk0p1 + fi + + # Make filesystem + echo "demo label: $demo_volume_label. $demo_dev..." + mkfs.ext4 -L $demo_volume_label $demo_dev + + mount -t ext4 -o defaults,rw $demo_dev $demo_mnt || { + echo "Error: Unable to mount $demo_dev on $demo_mnt" + exit 1 + } +} + +bootloader_menu_config() { + # Update uboot Environment + prepare_boot_menu +} + diff --git a/platform/marvell-arm64/rules.mk b/platform/marvell-arm64/rules.mk index b61a7a87c3c6..bf4667a46d41 100644 --- a/platform/marvell-arm64/rules.mk +++ b/platform/marvell-arm64/rules.mk @@ -8,15 +8,18 @@ include $(PLATFORM_PATH)/docker-ptf-mrvl.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/linux-kernel-arm64.mk ENABLE_SYSTEM_TELEMETRY = "" -ENABLE_SYNCD_RPC = "" SONIC_ALL += $(SONIC_ONE_IMAGE) \ - $(DOCKER_FPM) - #$(DOCKER_SYNCD_MRVL_RPC) + $(DOCKER_FPM) \ + $(DOCKER_PTF_MRVL) \ + $(DOCKER_SYNCD_MRVL_RPC) # Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_SAI) $(LIBSAITHRIFT_DEV_MRVL) +$(LIBSAIREDIS)_DEPENDS += $(MRVL_SAI) +ifeq ($(ENABLE_SYNCD_RPC),y) +$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +endif # Runtime dependency on mrvl sai is set only for syncd $(SYNCD)_RDEPENDS += $(MRVL_SAI) diff --git a/platform/marvell-arm64/sai.mk b/platform/marvell-arm64/sai.mk index ad8ff329ba6c..d5f044c6cb71 100644 --- a/platform/marvell-arm64/sai.mk +++ b/platform/marvell-arm64/sai.mk @@ -1,6 +1,6 @@ # Marvell SAI -export MRVL_SAI_VERSION = 1.4.1 +export MRVL_SAI_VERSION = 1.5.1 export MRVL_SAI_TAG = SONiC.201904 export MRVL_SAI = mrvllibsai_$(PLATFORM_ARCH)_$(MRVL_SAI_VERSION).deb diff --git a/platform/marvell-armhf/rules.mk b/platform/marvell-armhf/rules.mk index fb46b261fa06..05ca4788069e 100644 --- a/platform/marvell-armhf/rules.mk +++ b/platform/marvell-armhf/rules.mk @@ -17,7 +17,10 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ #$(DOCKER_SYNCD_MRVL_RPC) # Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_SAI) $(LIBSAITHRIFT_DEV_MRVL) +$(LIBSAIREDIS)_DEPENDS += $(MRVL_SAI) +ifeq ($(ENABLE_SYNCD_RPC),y) +$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +endif # Runtime dependency on mrvl sai is set only for syncd $(SYNCD)_RDEPENDS += $(MRVL_SAI) diff --git a/platform/marvell/rules.mk b/platform/marvell/rules.mk index d819cfb67dae..c01e1e491803 100644 --- a/platform/marvell/rules.mk +++ b/platform/marvell/rules.mk @@ -11,7 +11,7 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ # Inject mrvl sai into sairedis $(LIBSAIREDIS)_DEPENDS += $(MRVL_FPA) $(MRVL_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV_MRVL) +$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mrvl sai is set only for syncd diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index dce30193420c..0e59310fc30c 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -273,7 +273,9 @@ RUN apt-get update && apt-get install -y \ # RUN apt-get -y install ca-certificates-java=20161107~bpo8+1 openjdk-8-jdk # For linux build +{% if CONFIGURED_ARCH != "arm64" %} RUN apt-get -y build-dep linux +{%- endif %} # For gobgp and telemetry build RUN export VERSION=1.11.5 \ @@ -356,7 +358,9 @@ RUN add-apt-repository \ RUN apt-get update {%- if CONFIGURED_ARCH == "amd64" %} RUN apt-get install -y docker-ce=17.03.2~ce-0~debian-jessie -{%- else %} +{%- elif CONFIGURED_ARCH == "arm64" %} +RUN apt-get install -y docker-ce=18.03.1~ce-0~debian +{%- elif CONFIGURED_ARCH == "armhf" %} RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian {%- endif %} RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker From e3475b81d7107cbe238ef44594ecd7b6101e4fb4 Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Thu, 23 Jan 2020 17:49:41 -0800 Subject: [PATCH 0318/1427] [baseimage]: removing space from shebang in procdockerstatsd (#4051) --- files/image_config/procdockerstatsd/procdockerstatsd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd index 66d2d45009d5..a7bdcd6e6ce6 100644 --- a/files/image_config/procdockerstatsd/procdockerstatsd +++ b/files/image_config/procdockerstatsd/procdockerstatsd @@ -1,4 +1,4 @@ -# !/usr/bin/env python +#!/usr/bin/env python ''' procdockerstatsd Daemon which periodically gathers process and docker statistics and pushes the data to STATE_DB From d2dadc976b3352c0b54b71f722ffb584a8d4e677 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Fri, 24 Jan 2020 23:38:22 +0530 Subject: [PATCH 0319/1427] DellEMC: Platform2.0 API enhancements in DellEMC S6000 and other API changes (#3956) --- .../s6000/sonic_platform/chassis.py | 1 + .../s6000/sonic_platform/eeprom.py | 4 ++ .../s6000/sonic_platform/fan.py | 42 ++++++++++++++++--- .../s6000/sonic_platform/psu.py | 30 ++++++++++++- .../s6000/sonic_platform/thermal.py | 37 +++++++++++++++- .../s6100/sonic_platform/fan.py | 11 +++-- .../z9100/sonic_platform/chassis.py | 2 +- .../z9100/sonic_platform/fan.py | 11 +++-- 8 files changed, 122 insertions(+), 16 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index c212df88c147..e94a7d1210f5 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -43,6 +43,7 @@ class Chassis(ChassisBase): reset_reason_dict[0x6] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE def __init__(self): + ChassisBase.__init__(self) # Initialize SFP list self.PORT_START = 0 self.PORT_END = 31 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py index 32462e5a256e..a82fd6a70201 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py @@ -150,6 +150,10 @@ def _load_device_eeprom(self): except: self.serial_number = 'NA' self.part_number = 'NA' + if self.is_psu_eeprom: + self.psu_type = 'NA' + else: + self.fan_type = 'NA' else: (valid, data) = self._get_eeprom_field("PPID") if valid: diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py index 29555b443a22..92f83c8fbc79 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py @@ -11,6 +11,7 @@ try: import os + import glob from sonic_platform_base.fan_base import FanBase from sonic_platform.eeprom import Eeprom except ImportError as e: @@ -29,6 +30,7 @@ class Fan(FanBase): def __init__(self, fan_index, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan + self.is_driver_initialized = True if not self.is_psu_fan: # Fan is 1-based in DellEMC platforms @@ -45,10 +47,18 @@ def __init__(self, fan_index, psu_fan=False, dependency=None): else: self.index = fan_index self.dependency = dependency - self.get_fan_speed_reg = self.I2C_DIR +\ - "i2c-1/1-005{}/fan1_target".format(10 - self.index) self.set_fan_speed_reg = self.I2C_DIR +\ "i2c-1/1-005{}/fan1_target".format(10 - self.index) + + hwmon_dir = self.I2C_DIR +\ + "i2c-1/1-005{}/hwmon/".format(10 - self.index) + try: + hwmon_node = os.listdir(hwmon_dir)[0] + except OSError: + hwmon_node = "hwmon*" + self.is_driver_initialized = False + + self.get_fan_speed_reg = hwmon_dir + hwmon_node + '/fan1_input' self.max_fan_speed = MAX_S6000_PSU_FAN_SPEED def _get_cpld_register(self, reg_name): @@ -93,6 +103,14 @@ def _get_i2c_register(self, reg_file): # reg_name and on failure returns 'ERR' rv = 'ERR' + if not self.is_driver_initialized: + reg_file_path = glob.glob(reg_file) + if len(reg_file_path): + reg_file = reg_file_path[0] + self._get_sysfs_path() + else: + return rv + if (not os.path.isfile(reg_file)): return rv @@ -122,6 +140,13 @@ def _set_i2c_register(self, reg_file, value): return rv + def _get_sysfs_path(self): + fan_speed_reg = glob.glob(self.get_fan_speed_reg) + + if len(fan_speed_reg): + self.get_fan_speed_reg = fan_speed_reg[0] + self.is_driver_initialized = True + def get_name(self): """ Retrieves the name of the Fan @@ -200,16 +225,21 @@ def get_direction(self): Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. """ if self.is_psu_fan: - direction = {1: 'FAN_DIRECTION_EXHAUST', 2: 'FAN_DIRECTION_INTAKE', - 3: 'FAN_DIRECTION_EXHAUST', 4: 'FAN_DIRECTION_INTAKE'} + direction = {1: self.FAN_DIRECTION_EXHAUST, 2: self.FAN_DIRECTION_INTAKE, + 3: self.FAN_DIRECTION_EXHAUST, 4: self.FAN_DIRECTION_INTAKE} fan_direction = self.dependency.eeprom.airflow_fan_type() else: - direction = {1: 'FAN_DIRECTION_EXHAUST', 2: 'FAN_DIRECTION_INTAKE'} + direction = {1: self.FAN_DIRECTION_EXHAUST, 2: self.FAN_DIRECTION_INTAKE} fan_direction = self.eeprom.airflow_fan_type() - return direction.get(fan_direction,'NA') + return direction.get(fan_direction, self.FAN_DIRECTION_NOT_APPLICABLE) def get_speed(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py index e2897a78d9fd..24200f1c7d39 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py @@ -11,6 +11,7 @@ try: import os + import glob from sonic_platform_base.psu_base import PsuBase from sonic_platform.eeprom import Eeprom from sonic_platform.fan import Fan @@ -29,12 +30,20 @@ def __init__(self, psu_index): self.index = psu_index + 1 self.psu_presence_reg = "psu{}_prs".format(psu_index) self.psu_status_reg = "powersupply_status" + self.is_driver_initialized = False if self.index == 1: ltc_dir = self.I2C_DIR + "i2c-11/11-0042/hwmon/" else: ltc_dir = self.I2C_DIR + "i2c-11/11-0040/hwmon/" - hwmon_node = os.listdir(ltc_dir)[0] + + try: + hwmon_node = os.listdir(ltc_dir)[0] + except OSError: + hwmon_node = "hwmon*" + else: + self.is_driver_initialized = True + self.HWMON_DIR = ltc_dir + hwmon_node + '/' self.psu_voltage_reg = self.HWMON_DIR + "in1_input" @@ -73,6 +82,14 @@ def _get_i2c_register(self, reg_file): # reg_name and on failure returns 'ERR' rv = 'ERR' + if not self.is_driver_initialized: + reg_file_path = glob.glob(reg_file) + if len(reg_file_path): + reg_file = reg_file_path[0] + self._get_sysfs_path() + else: + return rv + if (not os.path.isfile(reg_file)): return rv @@ -86,6 +103,17 @@ def _get_i2c_register(self, reg_file): rv = rv.lstrip(" ") return rv + def _get_sysfs_path(self): + voltage_reg = glob.glob(self.psu_voltage_reg) + current_reg = glob.glob(self.psu_current_reg) + power_reg = glob.glob(self.psu_power_reg) + + if len(voltage_reg) and len(current_reg) and len(power_reg): + self.psu_voltage_reg = voltage_reg_path[0] + self.psu_current_reg = current_reg_path[0] + self.psu_power_reg = power_reg_path[0] + self.is_driver_initialized = True + def get_name(self): """ Retrieves the name of the device diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py index 70bac0c729d2..a54336d40f1c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py @@ -11,6 +11,7 @@ try: import os + import glob from sonic_platform_base.thermal_base import ThermalBase from sonic_platform.psu import Psu except ImportError as e: @@ -36,13 +37,19 @@ class Thermal(ThermalBase): def __init__(self, thermal_index): self.index = thermal_index + 1 self.is_psu_thermal = False + self.is_driver_initialized = True self.dependency = None if self.index < 9: i2c_path = self.I2C_DIR + self.I2C_DEV_MAPPING[self.index - 1][0] hwmon_temp_index = self.I2C_DEV_MAPPING[self.index - 1][1] hwmon_temp_suffix = "max" - hwmon_node = os.listdir(i2c_path)[0] + try: + hwmon_node = os.listdir(i2c_path)[0] + except OSError: + hwmon_node = "hwmon*" + self.is_driver_initialized = False + self.HWMON_DIR = i2c_path + hwmon_node + '/' if self.index == 4: @@ -55,7 +62,12 @@ def __init__(self, thermal_index): dev_path = "/sys/devices/platform/coretemp.0/hwmon/" hwmon_temp_index = self.index - 7 hwmon_temp_suffix = "crit" - hwmon_node = os.listdir(dev_path)[0] + try: + hwmon_node = os.listdir(dev_path)[0] + except OSError: + hwmon_node = "hwmon*" + self.is_driver_initialized = False + self.HWMON_DIR = dev_path + hwmon_node + '/' self.thermal_temperature_file = self.HWMON_DIR \ @@ -70,6 +82,14 @@ def _read_sysfs_file(self, sysfs_file): # sysfs_file and on failure returns 'ERR' rv = 'ERR' + if not self.is_driver_initialized: + sysfs_file_path = glob.glob(sysfs_file) + if len(sysfs_file_path): + sysfs_file = sysfs_file_path[0] + self._get_sysfs_path() + else: + return rv + if (not os.path.isfile(sysfs_file)): return rv @@ -83,6 +103,19 @@ def _read_sysfs_file(self, sysfs_file): rv = rv.lstrip(" ") return rv + def _get_sysfs_path(self): + temperature_path = glob.glob(self.thermal_temperature_file) + high_threshold_path = glob.glob(self.thermal_high_threshold_file) + low_threshold_path = glob.glob(self.thermal_low_threshold_file) + + if len(temperature_path) and len(high_threshold_path): + self.thermal_temperature_file = temperature_path[0] + self.thermal_high_threshold_file = high_threshold_path[0] + if len(low_threshold_path): + self.thermal_low_threshold_file = low_threshold_path + + self.is_driver_initialized = True + def get_name(self): """ Retrieves the name of the thermal diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py index a2ee0cd10421..49e95357b6f1 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py @@ -146,7 +146,7 @@ def get_status(self): fantray_status = self._get_pmc_register(self.get_fan_speed_reg) if (fantray_status != 'ERR'): fantray_status = int(fantray_status, 10) - if (fantray_status > 5000): + if (fantray_status > 1000): status = True else: fantray_status = self._get_pmc_register(self.fan_status_reg) @@ -163,13 +163,18 @@ def get_direction(self): Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. """ - direction = ['FAN_DIRECTION_INTAKE', 'FAN_DIRECTION_EXHAUST'] + direction = [self.FAN_DIRECTION_INTAKE, self.FAN_DIRECTION_EXHAUST] fan_direction = self._get_pmc_register(self.get_fan_dir_reg) if (fan_direction != 'ERR') and self.get_presence(): fan_direction = int(fan_direction, 10) else: - return 'N/A' + return self.FAN_DIRECTION_NOT_APPLICABLE return direction[fan_direction] def get_speed(self): diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index 27164409d962..7f4dab3a19c0 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py @@ -73,6 +73,7 @@ class Chassis(ChassisBase): power_reason_dict[44] = ChassisBase.REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED def __init__(self): + ChassisBase.__init__(self) PORT_START = 0 PORT_END = 31 PORTS_IN_BLOCK = (PORT_END + 1) @@ -92,7 +93,6 @@ def __init__(self): self.PORT_I2C_MAPPING[index][1]) self._sfp_list.append(sfp_node) - ChassisBase.__init__(self) # Initialize EEPROM self._eeprom = Eeprom() for i in range(MAX_Z9100_FANTRAY): diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py index 03ac8cd5c71f..6ff688fa3a1e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py @@ -145,7 +145,7 @@ def get_status(self): fantray_status = self._get_pmc_register(self.get_fan_speed_reg) if (fantray_status != 'ERR'): fantray_status = int(fantray_status, 10) - if (fantray_status > 5000): + if (fantray_status > 1000): status = True else: fantray_status = self._get_pmc_register(self.fan_status_reg) @@ -162,13 +162,18 @@ def get_direction(self): Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. """ - direction = ['FAN_DIRECTION_INTAKE', 'FAN_DIRECTION_EXHAUST'] + direction = [self.FAN_DIRECTION_INTAKE, self.FAN_DIRECTION_EXHAUST] fan_direction = self._get_pmc_register(self.get_fan_dir_reg) if (fan_direction != 'ERR') and self.get_presence(): fan_direction = int(fan_direction, 10) else: - return 'N/A' + return self.FAN_DIRECTION_NOT_APPLICABLE return direction[fan_direction] def get_speed(self): From cb2edcf3df43d826aa310ee4524f734296d9277a Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Fri, 24 Jan 2020 21:26:17 +0200 Subject: [PATCH 0320/1427] [mellanox] Add fwutil platform components. (#3999) Signed-off-by: Nazarii Hnydyn --- .../x86_64-mlnx_msn2010-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn2100-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn2410-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn2700-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn2740-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn3700-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn3700c-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn3800-r0/platform_components.json | 10 ++++++++++ 8 files changed, 80 insertions(+) create mode 100644 device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json new file mode 100644 index 000000000000..775c6e22cf5c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2010-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json new file mode 100644 index 000000000000..6a6a74301cbc --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2100-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json new file mode 100644 index 000000000000..77da35ce5818 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2410-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json new file mode 100644 index 000000000000..2a6069414786 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2700-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json new file mode 100644 index 000000000000..7964d9cb8713 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2740-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json new file mode 100644 index 000000000000..7c0b7598aff7 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn3700-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json new file mode 100644 index 000000000000..c55b9feab7cb --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn3700c-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json new file mode 100644 index 000000000000..fa3b172b763e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn3800-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} From 3239d7fc5b26fb0b4639a69fdd54f76abcdb8161 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Sat, 25 Jan 2020 03:27:32 +0800 Subject: [PATCH 0321/1427] [Mellanox]Implement plugins for PSU, fan and thermal (#4041) * [plugins]add fan functions, add voltage, current, power for psu * [plugins]link fanutil.py and psuutil.py to those in 2700 * [plugin]add thermal * [plugin]add symbol links for thermalutil for all SKUs --- .../x86_64-mlnx_msn2010-r0/plugins/fanutil.py | 1 + .../plugins/thermalutil.py | 1 + .../x86_64-mlnx_msn2100-r0/plugins/fanutil.py | 1 + .../plugins/thermalutil.py | 1 + .../x86_64-mlnx_msn2410-r0/plugins/fanutil.py | 1 + .../x86_64-mlnx_msn2410-r0/plugins/psuutil.py | 75 +-- .../plugins/thermalutil.py | 1 + .../x86_64-mlnx_msn2700-r0/plugins/fanutil.py | 199 ++++++++ .../x86_64-mlnx_msn2700-r0/plugins/psuutil.py | 148 +++++- .../plugins/thermalutil.py | 456 ++++++++++++++++++ .../x86_64-mlnx_msn2740-r0/plugins/fanutil.py | 1 + .../x86_64-mlnx_msn2740-r0/plugins/psuutil.py | 75 +-- .../plugins/thermalutil.py | 1 + .../x86_64-mlnx_msn3700-r0/plugins/fanutil.py | 1 + .../plugins/fanutil.py | 1 + .../plugins/thermalutil.py | 1 + .../x86_64-mlnx_msn3800-r0/plugins/fanutil.py | 1 + .../plugins/thermalutil.py | 1 + 18 files changed, 799 insertions(+), 167 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_msn2010-r0/plugins/fanutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn2010-r0/plugins/thermalutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn2100-r0/plugins/fanutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn2100-r0/plugins/thermalutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn2410-r0/plugins/fanutil.py mode change 100644 => 120000 device/mellanox/x86_64-mlnx_msn2410-r0/plugins/psuutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn2410-r0/plugins/thermalutil.py create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/plugins/fanutil.py create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/plugins/thermalutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn2740-r0/plugins/fanutil.py mode change 100644 => 120000 device/mellanox/x86_64-mlnx_msn2740-r0/plugins/psuutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn2740-r0/plugins/thermalutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn3700-r0/plugins/fanutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn3700c-r0/plugins/fanutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn3700c-r0/plugins/thermalutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/plugins/fanutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/plugins/thermalutil.py diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/plugins/fanutil.py b/device/mellanox/x86_64-mlnx_msn2010-r0/plugins/fanutil.py new file mode 120000 index 000000000000..82ea06ef915f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/plugins/fanutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/fanutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/plugins/thermalutil.py b/device/mellanox/x86_64-mlnx_msn2010-r0/plugins/thermalutil.py new file mode 120000 index 000000000000..cef21ffacccc --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/plugins/thermalutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/thermalutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/fanutil.py b/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/fanutil.py new file mode 120000 index 000000000000..82ea06ef915f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/fanutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/fanutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/thermalutil.py b/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/thermalutil.py new file mode 120000 index 000000000000..cef21ffacccc --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/thermalutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/thermalutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/fanutil.py b/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/fanutil.py new file mode 120000 index 000000000000..82ea06ef915f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/fanutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/fanutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/psuutil.py deleted file mode 100644 index f3cce52b12aa..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/psuutil.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python - -############################################################################# -# Mellanox -# -# Module contains an implementation of SONiC PSU Base API and -# provides the PSUs status which are available in the platform -# -############################################################################# - -import os.path - -try: - from sonic_psu.psu_base import PsuBase -except ImportError as e: - raise ImportError (str(e) + "- required module not found") - -class PsuUtil(PsuBase): - """Platform-specific PSUutil class""" - - def __init__(self): - PsuBase.__init__(self) - - self.psu_path = "/var/run/hw-management/thermal/" - self.psu_presence = "psu{}_status" - self.psu_oper_status = "psu{}_pwr_status" - - def get_num_psus(self): - """ - Retrieves the number of PSUs available on the device - - :return: An integer, the number of PSUs available on the device - """ - return 2 - - def get_psu_status(self, index): - """ - Retrieves the oprational status of power supply unit (PSU) defined - by 1-based index - - :param index: An integer, 1-based index of the PSU of which to query status - :return: Boolean, True if PSU is operating properly, False if PSU is faulty - """ - if index is None: - return False - - status = 0 - try: - with open(self.psu_path + self.psu_oper_status.format(index), 'r') as power_status: - status = int(power_status.read()) - except IOError: - return False - - return status == 1 - - def get_psu_presence(self, index): - """ - Retrieves the presence status of power supply unit (PSU) defined - by 1-based index - - :param index: An integer, 1-based index of the PSU of which to query status - :return: Boolean, True if PSU is plugged, False if not - """ - if index is None: - return False - - status = 0 - try: - with open(self.psu_path + self.psu_presence.format(index), 'r') as presence_status: - status = int(presence_status.read()) - except IOError: - return False - - return status == 1 diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/psuutil.py new file mode 120000 index 000000000000..9f724238a8d5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/psuutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/thermalutil.py b/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/thermalutil.py new file mode 120000 index 000000000000..cef21ffacccc --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/thermalutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/thermalutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/fanutil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/fanutil.py new file mode 100644 index 000000000000..429bf44750a2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/fanutil.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + + +try: + import os.path + import syslog + import subprocess + from glob import glob + from sonic_fan.fan_base import FanBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +def log_err(msg): + syslog.openlog("fanutil") + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + +class FanUtil(FanBase): + """Platform-specific FanUtil class""" + + PWM_MAX = 255 + MAX_FAN_PER_DRAWER = 2 + GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" + sku_without_fan_direction = ['ACS-MSN2010', 'ACS-MSN2100', 'ACS-MSN2410', 'ACS-MSN2700', 'Mellanox-SN2700', 'Mellanox-SN2700-D48C8', 'LS-SN2700', 'ACS-MSN2740'] + sku_with_unpluggable_fan = ['ACS-MSN2010', 'ACS-MSN2100'] + + def __init__(self): + FanBase.__init__(self) + + self.sku_name = self._get_sku_name() + + self.fan_path = "/var/run/hw-management/" + if self.sku_name in self.sku_with_unpluggable_fan: + self.fan_status = None + self.unpluggable_fan = True + else: + self.fan_status = "thermal/fan{}_status" + self.unpluggable_fan = False + self.fan_get_speed = "thermal/fan{}_speed_get" + self.fan_set_speed = "thermal/fan{}_speed_set" + if self.sku_name in self.sku_without_fan_direction: + self.fan_direction = None + else: + self.fan_direction = "system/fan_dir" + + self.fan_led_green = "led/led_fan*_green" + self.num_of_fan, self.num_of_drawer = self._extract_num_of_fans_and_fan_drawers() + + def _get_sku_name(self): + p = subprocess.Popen(self.GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + return out.rstrip('\n') + + def _extract_num_of_fans_and_fan_drawers(self): + # So far we don't have files representing the number of fans and drawers + # The only way to retrieve the number is to count files. + # for number of fans, we get it via couting the speed files. + # for number of draws, we get it via couting the green led files. + list_of_fan_speed = glob(self.fan_path + self.fan_get_speed.format("*")) + num_of_fan = len(list_of_fan_speed) + list_of_fan_leds = glob(self.fan_path + self.fan_led_green) + num_of_drawer = len(list_of_fan_leds) + + return num_of_fan, num_of_drawer + + def _convert_fan_index_to_drawer_index(self, index): + return (index + self.MAX_FAN_PER_DRAWER - 1) / self.MAX_FAN_PER_DRAWER + + def _read_file(self, file_pattern, index = 0): + """ + Reads the file of the fan + + :param file_pattern: The filename convention + :param index: An integer, 1-based index of the fan of which to query status + :return: int + """ + return_value = 0 + try: + with open(os.path.join(self.fan_path, file_pattern.format(index)), 'r') as file_to_read: + return_value = int(file_to_read.read()) + except IOError: + log_err("Read file {} failed".format(self.fan_path + file_pattern.format(index))) + return return_value + + return return_value + + def get_num_fans(self): + """ + Retrieves the number of FANs supported on the device + + :return: An integer, the number of FANs supported on the device + """ + return self.num_of_fan + + def get_status(self, index): + """ + Retrieves the operational status of FAN defined + by index 1-based + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, + - True if FAN is running with some speed + - False if FAN has stopped running + """ + if not self.get_presence(index): + return False + + return self.get_speed(index) != 0 + + def get_presence(self, index): + """ + Retrieves the presence status of a FAN defined + by 1-based index + + :param index: An integer, 1-based index of the FAN of which to query status + :return: Boolean, True if FAN is plugged, False if not + """ + if index > self.num_of_fan: + raise RuntimeError("index ({}) shouldn't be greater than number of fans ({})".format(index, self.num_of_fan)) + + if self.unpluggable_fan: + return True + + draw_index = self._convert_fan_index_to_drawer_index(index) + presence = self._read_file(self.fan_status, draw_index) + + return presence != 0 + + def get_direction(self, index): + """ + Retrieves the airflow direction of a FAN defined + by 1-based index + + :param index: An integer, 1-based index of the FAN of which to query status + :return: string, denoting FAN airflow direction + Note: + What Mellanox calls forward: + Air flows from fans side to QSFP side, for example: MSN2700-CS2F + which means intake in community + What Mellanox calls reverse: + Air flow from QSFP side to fans side, for example: MSN2700-CS2R + which means exhaust in community + According to hw-mgmt: + 1 stands for forward, in other words intake + 0 stands for reverse, in other words exhaust + """ + if not self.fan_direction: + return self.FAN_DIRECTION_NOT_APPLICABLE + + if index > self.num_of_fan: + raise RuntimeError("index ({}) shouldn't be greater than number of fans ({})".format(index, self.num_of_fan)) + + drawer_index = self._convert_fan_index_to_drawer_index(index) + + fan_dir_bits = self._read_file(self.fan_direction) + fan_mask = 1 << drawer_index - 1 + if fan_dir_bits & fan_mask: + return self.FAN_DIRECTION_INTAKE + else: + return self.FAN_DIRECTION_EXHAUST + + def get_speed(self, index): + """ + Retrieves the speed of a Front FAN in the tray in revolutions per minute defined + by 1-based index + + :param index: An integer, 1-based index of the FAN of which to query speed + :return: integer, denoting front FAN speed + """ + speed = self._read_file(self.fan_get_speed, index) + + return speed + + def set_speed(self, val): + """ + Sets the speed of all the FANs to a value denoted by the duty-cycle percentage val + + :param val: An integer, <0-100> denoting FAN duty cycle percentage + :return: Boolean, True if operation is successful, False if not + """ + status = True + pwm = int(round(self.PWM_MAX*val/100.0)) + + try: + with open(os.path.join(self.fan_path, self.fan_set_speed.format(1)), 'w') as fan_pwm: + fan_pwm.write(str(pwm)) + except (ValueError, IOError): + log_err("Read file {} failed".format(self.fan_path + self.fan_set_speed.format(1))) + status = False + + return status diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/psuutil.py index f3cce52b12aa..cd01a1905a06 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/psuutil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/psuutil.py @@ -8,22 +8,50 @@ # ############################################################################# -import os.path - try: + import os.path + import syslog + import subprocess from sonic_psu.psu_base import PsuBase except ImportError as e: raise ImportError (str(e) + "- required module not found") +def log_err(msg): + syslog.openlog("psuutil") + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" + MAX_PSU_FAN = 1 + MAX_NUM_PSU = 2 + GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" + # for spectrum1 switches with plugable PSUs, the output voltage file is psuX_volt + # for spectrum2 switches the output voltage file is psuX_volt_out2 + sku_spectrum1_with_plugable_psu = ['ACS-MSN2410', 'ACS-MSN2700', 'Mellanox-SN2700', 'Mellanox-SN2700-D48C8', 'LS-SN2700', 'ACS-MSN2740'] + def __init__(self): PsuBase.__init__(self) - self.psu_path = "/var/run/hw-management/thermal/" - self.psu_presence = "psu{}_status" - self.psu_oper_status = "psu{}_pwr_status" + self.sku_name = self._get_sku_name() + + self.psu_path = "/var/run/hw-management/" + self.psu_presence = "thermal/psu{}_status" + self.psu_oper_status = "thermal/psu{}_pwr_status" + self.psu_current = "power/psu{}_curr" + self.psu_power = "power/psu{}_power" + if self.sku_name in self.sku_spectrum1_with_plugable_psu: + self.psu_voltage = "power/psu{}_volt" + else: + self.psu_voltage = "power/psu{}_volt_out2" + self.fan_speed = "thermal/psu{}_fan1_speed_get" + + def _get_sku_name(self): + p = subprocess.Popen(self.GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + return out.rstrip('\n') def get_num_psus(self): """ @@ -31,7 +59,25 @@ def get_num_psus(self): :return: An integer, the number of PSUs available on the device """ - return 2 + return self.MAX_NUM_PSU + + def _read_file(self, file_pattern, index): + """ + Reads the file of the PSU + + :param file_pattern: The filename convention + :param index: An integer, 1-based index of the PSU of which to query status + :return: int + """ + return_value = 0 + try: + with open(self.psu_path + file_pattern.format(index), 'r') as file_to_read: + return_value = int(file_to_read.read()) + except IOError: + log_err("Read file {} failed".format(self.psu_path + file_pattern.format(index))) + return 0 + + return return_value def get_psu_status(self, index): """ @@ -43,13 +89,10 @@ def get_psu_status(self, index): """ if index is None: return False + if index > self.MAX_NUM_PSU: + raise RuntimeError("index ({}) shouldn't be greater than {}".format(index, self.MAX_NUM_PSU)) - status = 0 - try: - with open(self.psu_path + self.psu_oper_status.format(index), 'r') as power_status: - status = int(power_status.read()) - except IOError: - return False + status = self._read_file(self.psu_oper_status, index) return status == 1 @@ -62,13 +105,80 @@ def get_psu_presence(self, index): :return: Boolean, True if PSU is plugged, False if not """ if index is None: - return False + raise RuntimeError("index shouldn't be None") + if index > self.MAX_NUM_PSU: + raise RuntimeError("index ({}) shouldn't be greater than {}".format(index, self.MAX_NUM_PSU)) - status = 0 - try: - with open(self.psu_path + self.psu_presence.format(index), 'r') as presence_status: - status = int(presence_status.read()) - except IOError: - return False + status = self._read_file(self.psu_presence, index) return status == 1 + + def get_output_voltage(self, index): + """ + Retrieves the ouput volatage in milli volts of a power supply unit (PSU) defined + by 1-based index + :param index: An integer, 1-based index of the PSU of which to query o/p volatge + :return: An integer, value of o/p voltage in mV if PSU is good, else zero + """ + if index is None: + raise RuntimeError("index shouldn't be None") + + if not self.get_psu_presence(index) or not self.get_psu_status(index): + return 0 + + voltage = self._read_file(self.psu_voltage, index) + + return voltage + + def get_output_current(self, index): + """ + Retrieves the output current in milli amperes of a power supply unit (PSU) defined + by 1-based index + :param index: An integer, 1-based index of the PSU of which to query o/p current + :return: An integer, value of o/p current in mA if PSU is good, else zero + """ + if index is None: + raise RuntimeError("index shouldn't be None") + + if not self.get_psu_presence(index) or not self.get_psu_status(index): + return 0 + + current = self._read_file(self.psu_current, index) + + return current + + def get_output_power(self, index): + """ + Retrieves the output power in micro watts of a power supply unit (PSU) defined + by 1-based index + :param index: An integer, 1-based index of the PSU of which to query o/p power + :return: An integer, value of o/p power in micro Watts if PSU is good, else zero + """ + if index is None: + raise RuntimeError("index shouldn't be None") + + if not self.get_psu_presence(index) or not self.get_psu_status(index): + return 0 + + power = self._read_file(self.psu_power, index) + + return power + + def get_fan_speed(self, index, fan_index): + """ + Retrieves the speed of fan, in rpm, denoted by 1-based of a power + supply unit (PSU) defined by 1-based index + :param index: An integer, 1-based index of the PSU of which to query fan speed + :param fan_index: An integer, 1-based index of the PSU-fan of which to query speed + :return: An integer, value of PSU-fan speed in rpm if PSU-fan is good, else zero + """ + if index is None: + raise RuntimeError("index shouldn't be None") + if fan_index > self.MAX_PSU_FAN: + raise RuntimeError("fan_index ({}) shouldn't be greater than {}".format(fan_index, self.MAX_PSU_FAN)) + if not self.get_psu_presence(index) or not self.get_psu_status(index): + return 0 + + fan_speed = self._read_file(self.fan_speed, index) + + return fan_speed diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/thermalutil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/thermalutil.py new file mode 100644 index 000000000000..73d27a41ac23 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/thermalutil.py @@ -0,0 +1,456 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# Module contains an implementation of SONiC Thermal Base API and +# provides the thermal sensor status which are available in the platform +# +############################################################################# + +try: + from os.path import join + import syslog + import subprocess + from sonic_thermal.thermal_base import ThermalBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +def log_info(msg): + syslog.openlog("thermalutil") + syslog.syslog(syslog.LOG_INFO, msg) + syslog.closelog() + + +THERMAL_DEV_CATEGORY_CPU_CORE = "cpu_core" +THERMAL_DEV_CATEGORY_CPU_PACK = "cpu_pack" +THERMAL_DEV_CATEGORY_MODULE = "module" +THERMAL_DEV_CATEGORY_PSU = "psu" +THERMAL_DEV_CATEGORY_GEARBOX = "gearbox" +THERMAL_DEV_CATEGORY_AMBIENT = "ambient" + +THERMAL_DEV_ASIC_AMBIENT = "asic_amb" +THERMAL_DEV_FAN_AMBIENT = "fan_amb" +THERMAL_DEV_PORT_AMBIENT = "port_amb" +THERMAL_DEV_COMEX_AMBIENT = "comex_amb" +THERMAL_DEV_BOARD_AMBIENT = "board_amb" + +THERMAL_API_GET_TEMPERATURE = "get_temperature" +THERMAL_API_GET_HIGH_THRESHOLD = "get_high_threshold" +THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD = "get_high_critical_threshold" + +THERMAL_API_INVALID_HIGH_THRESHOLD = 0.0 + +HW_MGMT_THERMAL_ROOT = "/var/run/hw-management/thermal/" + +thermal_api_handler_cpu_core = { + THERMAL_API_GET_TEMPERATURE:"cpu_core{}", + THERMAL_API_GET_HIGH_THRESHOLD:"cpu_core{}_max", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:"cpu_core{}_crit" +} +thermal_api_handler_cpu_pack = { + THERMAL_API_GET_TEMPERATURE:"cpu_pack", + THERMAL_API_GET_HIGH_THRESHOLD:"cpu_pack_max", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:"cpu_pack_crit" +} +thermal_api_handler_module = { + THERMAL_API_GET_TEMPERATURE:"module{}_temp_input", + THERMAL_API_GET_HIGH_THRESHOLD:"module{}_temp_crit", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:"module{}_temp_emergency" +} +thermal_api_handler_psu = { + THERMAL_API_GET_TEMPERATURE:"psu{}_temp", + THERMAL_API_GET_HIGH_THRESHOLD:"psu{}_temp_max", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:None +} +thermal_api_handler_gearbox = { + THERMAL_API_GET_TEMPERATURE:"gearbox{}_temp_input", + THERMAL_API_GET_HIGH_THRESHOLD:None, + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:None +} +thermal_ambient_apis = { + THERMAL_DEV_ASIC_AMBIENT : "asic", + THERMAL_DEV_PORT_AMBIENT : "port_amb", + THERMAL_DEV_FAN_AMBIENT : "fan_amb", + THERMAL_DEV_COMEX_AMBIENT : "comex_amb", + THERMAL_DEV_BOARD_AMBIENT : "board_amb" +} +thermal_ambient_name = { + THERMAL_DEV_ASIC_AMBIENT : "Ambient ASIC Temp", + THERMAL_DEV_PORT_AMBIENT : "Ambient Port Side Temp", + THERMAL_DEV_FAN_AMBIENT : "Ambient Fan Side Temp", + THERMAL_DEV_COMEX_AMBIENT : "Ambient COMEX Temp", + THERMAL_DEV_BOARD_AMBIENT : "Ambient Board Temp" +} +thermal_api_handlers = { + THERMAL_DEV_CATEGORY_CPU_CORE : thermal_api_handler_cpu_core, + THERMAL_DEV_CATEGORY_CPU_PACK : thermal_api_handler_cpu_pack, + THERMAL_DEV_CATEGORY_MODULE : thermal_api_handler_module, + THERMAL_DEV_CATEGORY_PSU : thermal_api_handler_psu, + THERMAL_DEV_CATEGORY_GEARBOX : thermal_api_handler_gearbox +} +thermal_name = { + THERMAL_DEV_CATEGORY_CPU_CORE : "CPU Core {} Temp", + THERMAL_DEV_CATEGORY_CPU_PACK : "CPU Pack Temp", + THERMAL_DEV_CATEGORY_MODULE : "xSFP module {} Temp", + THERMAL_DEV_CATEGORY_PSU : "PSU-{} Temp", + THERMAL_DEV_CATEGORY_GEARBOX : "Gearbox {} Temp" +} + +thermal_device_categories_all = [ + THERMAL_DEV_CATEGORY_CPU_CORE, + THERMAL_DEV_CATEGORY_CPU_PACK, + THERMAL_DEV_CATEGORY_MODULE, + THERMAL_DEV_CATEGORY_PSU, + THERMAL_DEV_CATEGORY_AMBIENT, + THERMAL_DEV_CATEGORY_GEARBOX +] + +thermal_device_categories_singleton = [ + THERMAL_DEV_CATEGORY_CPU_PACK, + THERMAL_DEV_CATEGORY_AMBIENT +] +thermal_api_names = [ + THERMAL_API_GET_TEMPERATURE, + THERMAL_API_GET_HIGH_THRESHOLD +] + +hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7} +thermal_profile_list = [ + # 2700 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 2), + THERMAL_DEV_CATEGORY_MODULE:(1, 32), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) + }, + # 2100 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 16), + THERMAL_DEV_CATEGORY_PSU:(0, 0), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,0), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT, + ] + ) + }, + # 2410 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 2), + THERMAL_DEV_CATEGORY_MODULE:(1, 56), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT, + ] + ) + }, + # 2740 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 32), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,0), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT, + ] + ) + }, + # 2010 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 22), + THERMAL_DEV_CATEGORY_PSU:(0, 0), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,0), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT, + ] + ) + }, + # 3700 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 32), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_COMEX_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) + }, + # 3700c + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 2), + THERMAL_DEV_CATEGORY_MODULE:(1, 32), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_COMEX_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) + }, + # 3800 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 64), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(1,32), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_COMEX_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) + }, +] + + +class Thermal(object): + def __init__(self, category, index, has_index): + """ + index should be a string for category ambient and int for other categories + """ + if category == THERMAL_DEV_CATEGORY_AMBIENT: + self.name = thermal_ambient_name[index] + self.index = index + elif has_index: + self.name = thermal_name[category].format(index) + self.index = index + else: + self.name = thermal_name[category] + self.index = 0 + + self.category = category + self.temperature = self._get_file_from_api(THERMAL_API_GET_TEMPERATURE) + self.high_threshold = self._get_file_from_api(THERMAL_API_GET_HIGH_THRESHOLD) + self.high_critical_threshold = self._get_file_from_api(THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.name + + def _read_generic_file(self, filename, len): + """ + Read a generic file, returns the contents of the file + """ + result = None + try: + with open(filename, 'r') as fileobj: + result = fileobj.read() + except Exception as e: + log_info("Fail to read file {} due to {}".format(filename, repr(e))) + return result + + def _get_file_from_api(self, api_name): + if self.category == THERMAL_DEV_CATEGORY_AMBIENT: + if api_name == THERMAL_API_GET_TEMPERATURE: + filename = thermal_ambient_apis[self.index] + else: + return None + else: + handler = thermal_api_handlers[self.category][api_name] + if self.category in thermal_device_categories_singleton: + filename = handler + else: + if handler: + filename = handler.format(self.index) + else: + return None + return join(HW_MGMT_THERMAL_ROOT, filename) + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + value_str = self._read_generic_file(self.temperature, 0) + if value_str is None: + return None + value_float = float(value_str) + if self.category == THERMAL_DEV_CATEGORY_MODULE and value_float == THERMAL_API_INVALID_HIGH_THRESHOLD: + return None + return value_float / 1000.0 + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + if self.high_threshold is None: + return None + value_str = self._read_generic_file(self.high_threshold, 0) + if value_str is None: + return None + value_float = float(value_str) + if self.category == THERMAL_DEV_CATEGORY_MODULE and value_float == THERMAL_API_INVALID_HIGH_THRESHOLD: + return None + return value_float / 1000.0 + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + if self.high_critical_threshold is None: + return None + value_str = self._read_generic_file(self.high_critical_threshold, 0) + if value_str is None: + return None + value_float = float(value_str) + if self.category == THERMAL_DEV_CATEGORY_MODULE and value_float == THERMAL_API_INVALID_HIGH_THRESHOLD: + return None + return value_float / 1000.0 + + +class ThermalUtil(ThermalBase): + """Platform-specific Thermalutil class""" + + MAX_PSU_FAN = 1 + MAX_NUM_PSU = 2 + GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" + number_of_thermals = 0 + thermal_list = [] + + def _get_sku_name(self): + p = subprocess.Popen(self.GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + return out.rstrip('\n') + + def __init__(self): + sku = self._get_sku_name() + # create thermal objects for all categories of sensors + tp_index = hwsku_dict_thermal[sku] + thermal_profile = thermal_profile_list[tp_index] + for category in thermal_device_categories_all: + if category == THERMAL_DEV_CATEGORY_AMBIENT: + count, ambient_list = thermal_profile[category] + for ambient in ambient_list: + thermal = Thermal(category, ambient, True) + self.thermal_list.append(thermal) + else: + start, count = 0, 0 + if category in thermal_profile: + start, count = thermal_profile[category] + if count == 0: + continue + if count == 1: + thermal = Thermal(category, 0, False) + self.thermal_list.append(thermal) + else: + for index in range(count): + thermal = Thermal(category, start + index, True) + self.thermal_list.append(thermal) + self.number_of_thermals = len(self.thermal_list) + + def get_num_thermals(self): + """ + Retrieves the number of thermal sensors supported on the device + + :return: An integer, the number of thermal sensors supported on the device + """ + return self.number_of_thermals + + def get_name(self, index): + """ + Retrieves the human-readable name of a thermal sensor by 1-based index + + Returns: + :param index: An integer, 1-based index of the thermal sensor of which to query status + :return: String, + A string representing the name of the thermal sensor. + """ + if index >= self.number_of_thermals: + raise RuntimeError("index ({}) shouldn't be greater than {}".format(index, self.number_of_thermals)) + return self.thermal_list[index].get_name() + + def get_temperature(self, index): + """ + Retrieves current temperature reading from thermal sensor by 1-based index + + :param index: An integer, 1-based index of the thermal sensor of which to query status + :return: Float, + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + if index >= self.number_of_thermals: + raise RuntimeError("index ({}) shouldn't be greater than {}".format(index, self.number_of_thermals)) + return self.thermal_list[index].get_temperature() + + def get_high_threshold(self, index): + """ + Retrieves the high threshold temperature of thermal by 1-based index + Actions should be taken if the temperature becomes higher than the threshold. + + :param index: An integer, 1-based index of the thermal sensor of which to query status + :return: A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + if index >= self.number_of_thermals: + raise RuntimeError("index ({}) shouldn't be greater than {}".format(index, self.number_of_thermals)) + return self.thermal_list[index].get_high_threshold() + + def get_high_critical_threshold(self, index): + """ + Retrieves the high critical threshold temperature of thermal by 1-based index + Actions should be taken immediately if the temperature becomes higher than the high critical + threshold otherwise the device will be damaged. + + :param index: An integer, 1-based index of the thermal sensor of which to query status + :return: A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + if index >= self.number_of_thermals: + raise RuntimeError("index ({}) shouldn't be greater than {}".format(index, self.number_of_thermals)) + return self.thermal_list[index].get_high_critical_threshold() diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/fanutil.py b/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/fanutil.py new file mode 120000 index 000000000000..82ea06ef915f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/fanutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/fanutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/psuutil.py deleted file mode 100644 index f3cce52b12aa..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/psuutil.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python - -############################################################################# -# Mellanox -# -# Module contains an implementation of SONiC PSU Base API and -# provides the PSUs status which are available in the platform -# -############################################################################# - -import os.path - -try: - from sonic_psu.psu_base import PsuBase -except ImportError as e: - raise ImportError (str(e) + "- required module not found") - -class PsuUtil(PsuBase): - """Platform-specific PSUutil class""" - - def __init__(self): - PsuBase.__init__(self) - - self.psu_path = "/var/run/hw-management/thermal/" - self.psu_presence = "psu{}_status" - self.psu_oper_status = "psu{}_pwr_status" - - def get_num_psus(self): - """ - Retrieves the number of PSUs available on the device - - :return: An integer, the number of PSUs available on the device - """ - return 2 - - def get_psu_status(self, index): - """ - Retrieves the oprational status of power supply unit (PSU) defined - by 1-based index - - :param index: An integer, 1-based index of the PSU of which to query status - :return: Boolean, True if PSU is operating properly, False if PSU is faulty - """ - if index is None: - return False - - status = 0 - try: - with open(self.psu_path + self.psu_oper_status.format(index), 'r') as power_status: - status = int(power_status.read()) - except IOError: - return False - - return status == 1 - - def get_psu_presence(self, index): - """ - Retrieves the presence status of power supply unit (PSU) defined - by 1-based index - - :param index: An integer, 1-based index of the PSU of which to query status - :return: Boolean, True if PSU is plugged, False if not - """ - if index is None: - return False - - status = 0 - try: - with open(self.psu_path + self.psu_presence.format(index), 'r') as presence_status: - status = int(presence_status.read()) - except IOError: - return False - - return status == 1 diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/psuutil.py new file mode 120000 index 000000000000..9f724238a8d5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/psuutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/thermalutil.py b/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/thermalutil.py new file mode 120000 index 000000000000..cef21ffacccc --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/thermalutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/thermalutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/plugins/fanutil.py b/device/mellanox/x86_64-mlnx_msn3700-r0/plugins/fanutil.py new file mode 120000 index 000000000000..82ea06ef915f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/plugins/fanutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/fanutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/plugins/fanutil.py b/device/mellanox/x86_64-mlnx_msn3700c-r0/plugins/fanutil.py new file mode 120000 index 000000000000..82ea06ef915f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/plugins/fanutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/fanutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/plugins/thermalutil.py b/device/mellanox/x86_64-mlnx_msn3700c-r0/plugins/thermalutil.py new file mode 120000 index 000000000000..cef21ffacccc --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/plugins/thermalutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/thermalutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/plugins/fanutil.py b/device/mellanox/x86_64-mlnx_msn3800-r0/plugins/fanutil.py new file mode 120000 index 000000000000..82ea06ef915f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/plugins/fanutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/fanutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/plugins/thermalutil.py b/device/mellanox/x86_64-mlnx_msn3800-r0/plugins/thermalutil.py new file mode 120000 index 000000000000..cef21ffacccc --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/plugins/thermalutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/thermalutil.py \ No newline at end of file From 08f60f652a025366d89080021d257f826c69fe60 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 24 Jan 2020 11:52:52 -0800 Subject: [PATCH 0322/1427] Update lldpd to latest stable version (#3905) * Change lldpd version * Remove patches not-required patches --- rules/lldpd.mk | 2 +- ...el-to-find-appropriate-nl_pid-automa.patch | 25 ----------------- .../0003-update-tx-interval-immediately.patch | 20 -------------- ...ad-all-notifications-in-lldpctl_recv.patch | 27 ------------------- src/lldpd/patch/series | 3 --- 5 files changed, 1 insertion(+), 76 deletions(-) delete mode 100644 src/lldpd/patch/0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch delete mode 100644 src/lldpd/patch/0003-update-tx-interval-immediately.patch delete mode 100644 src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch diff --git a/rules/lldpd.mk b/rules/lldpd.mk index bae83f7263b3..acd28f3359d7 100644 --- a/rules/lldpd.mk +++ b/rules/lldpd.mk @@ -1,6 +1,6 @@ # lldpd package -LLDPD_VERSION = 0.9.6 +LLDPD_VERSION = 1.0.4 LLDPD_VERSION_SUFFIX = 1 LLDPD_VERSION_FULL = $(LLDPD_VERSION)-$(LLDPD_VERSION_SUFFIX) diff --git a/src/lldpd/patch/0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch b/src/lldpd/patch/0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch deleted file mode 100644 index 801fdd8ec96e..000000000000 --- a/src/lldpd/patch/0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 2ee8585e8b716719a11235ab5c291b2f6ac9ce1a Mon Sep 17 00:00:00 2001 -From: Pavel Shirshov -Date: Wed, 17 Oct 2018 21:05:58 +0000 -Subject: [PATCH] Let linux kernel to find appropriate nl_pid automatically - ---- - src/daemon/netlink.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/daemon/netlink.c b/src/daemon/netlink.c -index 1a64a23..f4227b8 100644 ---- a/src/daemon/netlink.c -+++ b/src/daemon/netlink.c -@@ -93,7 +93,7 @@ netlink_connect(struct lldpd *cfg, int protocol, unsigned groups) - int s; - struct sockaddr_nl local = { - .nl_family = AF_NETLINK, -- .nl_pid = getpid(), -+ .nl_pid = 0, - .nl_groups = groups - }; - --- -2.7.4 - diff --git a/src/lldpd/patch/0003-update-tx-interval-immediately.patch b/src/lldpd/patch/0003-update-tx-interval-immediately.patch deleted file mode 100644 index b6b295001288..000000000000 --- a/src/lldpd/patch/0003-update-tx-interval-immediately.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/src/daemon/client.c b/src/daemon/client.c -index 8382d02..38cf3f3 100644 ---- a/src/daemon/client.c -+++ b/src/daemon/client.c -@@ -71,7 +71,6 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, - if (CHANGED(c_tx_interval) && config->c_tx_interval != 0) { - if (config->c_tx_interval < 0) { - log_debug("rpc", "client asked for immediate retransmission"); -- levent_send_now(cfg); - } else { - log_debug("rpc", "client change transmit interval to %d", - config->c_tx_interval); -@@ -79,6 +78,7 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, - LOCAL_CHASSIS(cfg)->c_ttl = cfg->g_config.c_tx_interval * - cfg->g_config.c_tx_hold; - } -+ levent_send_now(cfg); - } - if (CHANGED(c_tx_hold) && config->c_tx_hold > 0) { - log_debug("rpc", "client change transmit hold to %d", diff --git a/src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch b/src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch deleted file mode 100644 index 1c3781da67ce..000000000000 --- a/src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch +++ /dev/null @@ -1,27 +0,0 @@ -From b8e66b52f40103fd3abea77031c4634742c31860 Mon Sep 17 00:00:00 2001 -From: Pavel Shirshov -Date: Thu, 12 Dec 2019 12:47:42 -0800 -Subject: [PATCH 1/1] Read all notifications in lldpctl_recv - ---- - src/lib/connection.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/lib/connection.c b/src/lib/connection.c -index 591d9e9..88bbc99 100644 ---- a/src/lib/connection.c -+++ b/src/lib/connection.c -@@ -253,8 +253,8 @@ lldpctl_recv(lldpctl_conn_t *conn, const uint8_t *data, size_t length) - memcpy(conn->input_buffer + conn->input_buffer_len, data, length); - conn->input_buffer_len += length; - -- /* Is it a notification? */ -- check_for_notification(conn); -+ /* Read all notifications */ -+ while(!check_for_notification(conn)); - - RESET_ERROR(conn); - --- -2.17.1.windows.2 - diff --git a/src/lldpd/patch/series b/src/lldpd/patch/series index 626c5d59751b..419fbc96a16f 100644 --- a/src/lldpd/patch/series +++ b/src/lldpd/patch/series @@ -1,8 +1,5 @@ # This series applies on GIT commit 396961a038a38675d46f96eaa7b430b2a1f8701b 0001-return-error-when-port-does-not-exist.patch -0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch -0003-update-tx-interval-immediately.patch 0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch -0005-Read-all-notifications-in-lldpctl_recv.patch 0006-lib-fix-memory-leak.patch 0007-lib-fix-memory-leak-when-handling-I-O.patch From 6ffa419304eb362da284e48525c2abf645b205aa Mon Sep 17 00:00:00 2001 From: B S Rama krishna <54837361+banagiri@users.noreply.github.com> Date: Sat, 25 Jan 2020 02:26:09 +0530 Subject: [PATCH 0323/1427] [marvell]: adopt SAI v1.5 on marvell-armhf (#3963) --- platform/marvell-armhf/sai.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/marvell-armhf/sai.mk b/platform/marvell-armhf/sai.mk index ad8ff329ba6c..d5f044c6cb71 100644 --- a/platform/marvell-armhf/sai.mk +++ b/platform/marvell-armhf/sai.mk @@ -1,6 +1,6 @@ # Marvell SAI -export MRVL_SAI_VERSION = 1.4.1 +export MRVL_SAI_VERSION = 1.5.1 export MRVL_SAI_TAG = SONiC.201904 export MRVL_SAI = mrvllibsai_$(PLATFORM_ARCH)_$(MRVL_SAI_VERSION).deb From 61858807ceb8267c092d3c83fbf4c45b97641b1d Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Sat, 25 Jan 2020 19:43:22 -0800 Subject: [PATCH 0324/1427] [frr]: Update FRR to 7.2.1 (#4066) Update rules for frr package. Update frr submodule --- rules/frr.mk | 5 +++-- src/sonic-frr/Makefile | 1 - src/sonic-frr/frr | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rules/frr.mk b/rules/frr.mk index 27391ce0cf73..b2e347e0b12d 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -1,8 +1,9 @@ # FRRouting (frr) package -FRR_VERSION = 7.2 +FRR_VERSION = 7.2.1 FRR_SUBVERSION = 0 -export FRR_VERSION FRR_SUBVERSION +FRR_BRANCH = frr/7.2 +export FRR_VERSION FRR_SUBVERSION FRR_BRANCH FRR = frr_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_$(CONFIGURED_ARCH).deb diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index 9ecade09f71d..9b8b3ffc23e9 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -5,7 +5,6 @@ SHELL = /bin/bash MAIN_TARGET = $(FRR) DERIVED_TARGET = $(FRR_PYTHONTOOLS) $(FRR_DBG) $(FRR_SNMP) $(FRR_SNMP_DBG) SUFFIX = $(shell date +%Y%m%d\.%H%M%S) -FRR_BRANCH = frr/$(FRR_VERSION) STG_BRANCH = stg_temp.$(SUFFIX) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index d49e8f75bd46..90446e3c3310 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit d49e8f75bd46879c799375f304506dbc5d26230f +Subproject commit 90446e3c3310001a7b84017fa4b237ea7914f45e From c9483796dc7dc6ad68b19e3970d851ed43ffbad3 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Sun, 26 Jan 2020 13:56:42 -0800 Subject: [PATCH 0325/1427] [baseimage]: support building multi-asic component (#3856) - move single instance services into their own folder - generate Systemd templates for any multi-instance service files in slave.mk - detect single or multi-instance platform in systemd-sonic-generator based on asic.conf platform specific file. - update container hostname after creation instead of during creation (docker_image_ctl) - run Docker containers in a network namespace if specified - add a service to create a simulated multi-ASIC topology on the virtual switch platform Signed-off-by: Lawrence Lee Signed-off-by: Suvarna Meenakshi --- device/virtual/x86_64-kvm_x86_64-r0/asic.conf | 1 + .../msft_multi_asic_vs/0/buffers.json.j2 | 3 + .../0/buffers_defaults_def.j2 | 45 ++ .../0/buffers_defaults_t0.j2 | 45 ++ .../0/buffers_defaults_t1.j2 | 45 ++ .../0/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/0/port_config.ini | 33 + .../msft_multi_asic_vs/0/qos.json.j2 | 1 + .../msft_multi_asic_vs/0/sai.profile | 2 + .../0/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/1/buffers.json.j2 | 3 + .../1/buffers_defaults_def.j2 | 45 ++ .../1/buffers_defaults_t0.j2 | 45 ++ .../1/buffers_defaults_t1.j2 | 45 ++ .../1/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/1/port_config.ini | 33 + .../msft_multi_asic_vs/1/qos.json.j2 | 1 + .../msft_multi_asic_vs/1/sai.profile | 2 + .../1/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/2/buffers.json.j2 | 3 + .../2/buffers_defaults_def.j2 | 45 ++ .../2/buffers_defaults_t0.j2 | 45 ++ .../2/buffers_defaults_t1.j2 | 45 ++ .../2/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/2/port_config.ini | 33 + .../msft_multi_asic_vs/2/qos.json.j2 | 1 + .../msft_multi_asic_vs/2/sai.profile | 2 + .../2/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/3/buffers.json.j2 | 3 + .../3/buffers_defaults_def.j2 | 45 ++ .../3/buffers_defaults_t0.j2 | 45 ++ .../3/buffers_defaults_t1.j2 | 45 ++ .../3/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/3/port_config.ini | 33 + .../msft_multi_asic_vs/3/qos.json.j2 | 1 + .../msft_multi_asic_vs/3/sai.profile | 2 + .../3/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/4/buffers.json.j2 | 3 + .../4/buffers_defaults_def.j2 | 45 ++ .../4/buffers_defaults_t0.j2 | 45 ++ .../4/buffers_defaults_t1.j2 | 45 ++ .../4/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/4/port_config.ini | 33 + .../msft_multi_asic_vs/4/qos.json.j2 | 1 + .../msft_multi_asic_vs/4/sai.profile | 2 + .../4/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/5/buffers.json.j2 | 3 + .../5/buffers_defaults_def.j2 | 45 ++ .../5/buffers_defaults_t0.j2 | 45 ++ .../5/buffers_defaults_t1.j2 | 45 ++ .../5/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/5/port_config.ini | 33 + .../msft_multi_asic_vs/5/qos.json.j2 | 1 + .../msft_multi_asic_vs/5/sai.profile | 2 + .../5/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/topology.sh | 81 +++ files/build_templates/docker_image_ctl.j2 | 96 ++- .../{ => single_instance}/bgp.service.j2 | 0 .../{ => single_instance}/database.service.j2 | 0 .../{ => single_instance}/swss.service.j2 | 0 .../{ => single_instance}/syncd.service.j2 | 0 .../{ => single_instance}/teamd.service.j2 | 0 .../build_templates/sonic_debian_extension.j2 | 14 + files/image_config/topology/topology.service | 16 + files/image_config/topology/topology.sh | 30 + platform/template/docker-syncd-base.mk | 2 +- platform/vs/README.vsvm.md | 58 +- platform/vs/sonic_multiasic.xml | 110 +++ rules/docker-database.mk | 2 +- rules/docker-dhcp-relay.mk | 2 +- rules/docker-fpm-frr.mk | 2 +- rules/docker-fpm-gobgp.mk | 2 +- rules/docker-fpm-quagga.mk | 2 +- rules/docker-lldp-sv2.mk | 2 +- rules/docker-orchagent.mk | 2 +- rules/docker-platform-monitor.mk | 2 +- rules/docker-router-advertiser.mk | 2 +- rules/docker-sflow.mk | 2 +- rules/docker-snmp-sv2.mk | 2 +- rules/docker-teamd.mk | 2 +- rules/docker-telemetry.mk | 2 +- slave.mk | 29 +- .../systemd-sonic-generator.c | 378 +++++++++- 83 files changed, 5781 insertions(+), 82 deletions(-) create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/asic.conf create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm create mode 100755 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh rename files/build_templates/{ => single_instance}/bgp.service.j2 (100%) rename files/build_templates/{ => single_instance}/database.service.j2 (100%) rename files/build_templates/{ => single_instance}/swss.service.j2 (100%) rename files/build_templates/{ => single_instance}/syncd.service.j2 (100%) rename files/build_templates/{ => single_instance}/teamd.service.j2 (100%) create mode 100644 files/image_config/topology/topology.service create mode 100755 files/image_config/topology/topology.sh create mode 100644 platform/vs/sonic_multiasic.xml diff --git a/device/virtual/x86_64-kvm_x86_64-r0/asic.conf b/device/virtual/x86_64-kvm_x86_64-r0/asic.conf new file mode 100644 index 000000000000..58c5d5348bb9 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/asic.conf @@ -0,0 +1 @@ +NUM_ASIC=1 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh new file mode 100755 index 000000000000..378f794190d4 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh @@ -0,0 +1,81 @@ +#!/bin/bash +#topolgy script for 6 ASIC PLATFORM +FIRST_FRONTEND_ASIC=0 +LAST_FRONTEND_ASIC=3 +FIRST_BACKEND_ASIC=4 +LAST_BACKEND_ASIC=5 +NUM_INTERFACES_PER_ASIC=32 + +start () { + # Move external links into assigned frontend namespaces + # eth0 - eth15: asic2 + # eth16 - eth31: asic3 + # eth32 - eth47: asic4 + # eth48 - eth63: asic5 + for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do + for NUM in `seq 1 16`; do + ORIG="eth$((16 * $ASIC + $NUM - 1))" + TEMP="ethTemp999" + NEW="eth$(($NUM + 16))" + ip link set dev $ORIG down + ip link set dev $ORIG name $TEMP # rename to prevent conflicts before renaming in new namespace + ip link set dev $TEMP netns asic$ASIC + sudo ip netns exec asic$ASIC ip link set $TEMP name $NEW # rename to final interface name + sudo ip netns exec asic$ASIC ip link set $NEW up + done + done + + # Connect all backend namespaces to frontend namespaces + for BACKEND in `seq $FIRST_BACKEND_ASIC $LAST_BACKEND_ASIC`; do + for FRONTEND in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do + for LINK in `seq 1 8`; do + BACK_NAME="eth$((8 * $FRONTEND + $LINK))" + FRONT_NAME="eth$((8 * $(($LAST_BACKEND_ASIC - $BACKEND)) + $LINK))" + TEMP_BACK="ethBack999" + TEMP_FRONT="ethFront999" + + ip link add $TEMP_BACK type veth peer name $TEMP_FRONT # temporary name to prevent conflicts between interfaces + ip link set dev $TEMP_BACK netns asic$BACKEND + ip link set dev $TEMP_FRONT netns asic$FRONTEND + + sudo ip netns exec asic$BACKEND ip link set $TEMP_BACK name $BACK_NAME + sudo ip netns exec asic$FRONTEND ip link set $TEMP_FRONT name $FRONT_NAME + + sudo ip netns exec asic$BACKEND ip link set $BACK_NAME up + sudo ip netns exec asic$FRONTEND ip link set $FRONT_NAME up + done + done + done +} + +stop() { + for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do + for NUM in `seq 1 16`; do + TEMP="eth999" + OLD="eth$(($NUM + 16))" + NAME="eth$((16 * $ASIC + $NUM - 1))" + sudo ip netns exec asic$ASIC ip link set dev $OLD down + sudo ip netns exec asic$ASIC ip link set dev $OLD name $TEMP + sudo ip netns exec asic$ASIC ip link set dev $TEMP netns 1 + ip link set dev $TEMP name $NAME + ip link set dev $NAME up + done + done + + for ASIC in `seq $FIRST_BACKEND_ASIC $LAST_BACKEND_ASIC`; do + for NUM in `seq 1 $NUM_INTERFACES_PER_ASIC`; do + sudo ip netns exec asic$ASIC ip link set dev eth$NUM down + sudo ip netns exec asic$ASIC ip link delete dev eth$NUM + done + done +} + +case "$1" in + start|stop) + $1 + ;; + *) + echo "Usage: $0 {start|stop}" + ;; +esac + diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 4f568c793393..995abce19379 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -1,5 +1,31 @@ #!/bin/bash +# single instance containers are still supported (even though it might not look like it) +# if no instance number is passed to this script, $DEV will simply be unset, resulting in docker +# commands being sent to the base container name. E.g. `docker start database$DEV` simply starts +# the container `database` if no instance number is passed since `$DEV` is not defined + + +{%- if docker_container_name == "database" %} +link_namespace() { + # Makes namespace of a docker container available in + # /var/run/netns so it can be managed with iproute2 + + mkdir -p /var/run/netns + PID="$(docker inspect -f {{"'{{.State.Pid}}'"}} "{{docker_container_name}}$DEV")" + + if `ip netns | grep --quiet -w "{{docker_container_name}}$DEV"`; then # namespace exists + if [ $(readlink -f /var/run/netns/$NET_NS$DEV) = $(readlink -f /proc/$PID/ns/net) ]; then # namespace is correctly linked + return 0 + else # if it's incorrectly linked remove it + ip netns delete "{{docker_container_name}}$DEV" + fi + fi + + ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS$DEV +} +{%- endif %} + function getMountPoint() { echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.basename(mnts[0]['Source'])" 2>/dev/null @@ -10,7 +36,7 @@ function updateHostName() HOSTS=/etc/hosts HOSTS_TMP=/etc/hosts.tmp - EXEC="docker exec -i {{docker_container_name}} bash -c" + EXEC="docker exec -i {{docker_container_name}}$DEV bash -c" NEW_HOSTNAME="$1" HOSTNAME=`$EXEC "hostname"` @@ -25,7 +51,7 @@ function updateHostName() # add entry with new hostname $EXEC "echo -e \"127.0.0.1\t$NEW_HOSTNAME\" >> $HOSTS_TMP" - echo "Set hostname in {{docker_container_name}} container" + echo "Set hostname in {{docker_container_name}}$DEV container" $EXEC "hostname '$NEW_HOSTNAME'" $EXEC "cat $HOSTS_TMP > $HOSTS" $EXEC "rm -f $HOSTS_TMP" @@ -143,6 +169,9 @@ function preStartAction() function postStartAction() { {%- if docker_container_name == "database" %} + if [ "$DEV" ]; then + link_namespace $DEV + fi # Wait until redis starts /usr/bin/docker exec database ping_pong_db_insts if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then @@ -209,7 +238,7 @@ start() { HOSTNAME=`hostname` fi - DOCKERCHECK=`docker inspect --type container {{docker_container_name}} 2>/dev/null` + DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` if [ "$?" -eq "0" ]; then {%- if docker_container_name == "database" %} DOCKERMOUNT="" @@ -218,39 +247,52 @@ start() { {%- endif %} if [ x"$DOCKERMOUNT" == x"$HWSKU" ]; then {%- if docker_container_name == "database" %} - echo "Starting existing {{docker_container_name}} container" + echo "Starting existing {{docker_container_name}}$DEV container" {%- else %} - echo "Starting existing {{docker_container_name}} container with HWSKU $HWSKU" + echo "Starting existing {{docker_container_name}}$DEV container with HWSKU $HWSKU" {%- endif %} preStartAction - docker start {{docker_container_name}} - CURRENT_HOSTNAME="$(docker exec {{docker_container_name}} hostname)" + docker start {{docker_container_name}}$DEV + postStartAction + CURRENT_HOSTNAME="$(docker exec {{docker_container_name}}$DEV hostname)" if [ x"$HOSTNAME" != x"$CURRENT_HOSTNAME" ]; then updateHostName "$HOSTNAME" fi - postStartAction + updateHostName "$HOSTNAME" exit $? fi # docker created with a different HWSKU, remove and recreate - echo "Removing obsolete {{docker_container_name}} container with HWSKU $DOCKERMOUNT" - docker rm -f {{docker_container_name}} + echo "Removing obsolete {{docker_container_name}}$DEV container with HWSKU $DOCKERMOUNT" + docker rm -f {{docker_container_name}}$DEV fi -{%- if docker_container_name == "database" %} - echo "Creating new {{docker_container_name}} container" + {%- if docker_container_name == "database" %} + echo "Creating new {{docker_container_name}}$DEV container" # if database_config exists in old_config, use it; otherwise use the default one in new image if [ -f /etc/sonic/old_config/database_config.json ]; then echo "Use database_config.json from old system..." mv /etc/sonic/old_config/database_config.json /etc/sonic/ fi -{%- else %} - echo "Creating new {{docker_container_name}} container with HWSKU $HWSKU" -{%- endif %} + {%- else %} + echo "Creating new {{docker_container_name}}$DEV container with HWSKU $HWSKU" + {%- endif %} + + if [ -z "$DEV" ]; then + NET="host" + else + {%- if docker_container_name == "database" %} + NET="bridge" + {%- else %} + NET="container:database$DEV" + {%- endif %} + fi + {%- if sonic_asic_platform == "mellanox" %} # TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version {%- endif %} docker create {{docker_image_run_opt}} \ + --net=$NET \ {%- if install_debug_image == "y" %} -v /src:/src:ro -v /debug:/debug:rw \ {%- endif %} @@ -279,8 +321,7 @@ start() { --tmpfs /tmp \ {%- endif %} --tmpfs /var/tmp \ - --hostname "$HOSTNAME" \ - --name={{docker_container_name}} {{docker_image_name}}:latest || { + --name={{docker_container_name}}$DEV {{docker_image_name}}:latest || { echo "Failed to docker run" >&1 exit 4 } @@ -288,24 +329,35 @@ start() { preStartAction docker start {{docker_container_name}} postStartAction + updateHostName "$HOSTNAME" } wait() { - docker wait {{docker_container_name}} + docker wait {{docker_container_name}}$DEV } stop() { - docker stop {{docker_container_name}} + docker stop {{docker_container_name}}$DEV +{%- if docker_container_name == "database" %} + ip netns delete "$NET_NS$DEV" +{%- endif %} } +OP=$1 +DEV=$2 # namespace/device number to operate on +NET_NS="asic" #name of the network namespace + case "$1" in - start|wait|stop|updateHostName) + start|wait|stop) + $1 + ;; + updateHostName) cmd=$1 - shift + shift 2 $cmd $@ ;; *) - echo "Usage: $0 {start|wait|stop|updateHostName new_hostname}" + echo "Usage: $0 {start namespace(optional)|wait namespace(optional)|stop namespace(optional)|updateHostName namespace(optional) new_hostname}" exit 1 ;; esac diff --git a/files/build_templates/bgp.service.j2 b/files/build_templates/single_instance/bgp.service.j2 similarity index 100% rename from files/build_templates/bgp.service.j2 rename to files/build_templates/single_instance/bgp.service.j2 diff --git a/files/build_templates/database.service.j2 b/files/build_templates/single_instance/database.service.j2 similarity index 100% rename from files/build_templates/database.service.j2 rename to files/build_templates/single_instance/database.service.j2 diff --git a/files/build_templates/swss.service.j2 b/files/build_templates/single_instance/swss.service.j2 similarity index 100% rename from files/build_templates/swss.service.j2 rename to files/build_templates/single_instance/swss.service.j2 diff --git a/files/build_templates/syncd.service.j2 b/files/build_templates/single_instance/syncd.service.j2 similarity index 100% rename from files/build_templates/syncd.service.j2 rename to files/build_templates/single_instance/syncd.service.j2 diff --git a/files/build_templates/teamd.service.j2 b/files/build_templates/single_instance/teamd.service.j2 similarity index 100% rename from files/build_templates/teamd.service.j2 rename to files/build_templates/single_instance/teamd.service.j2 diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index bdcb415839d4..208d45203037 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -253,6 +253,13 @@ sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/ # Copy miscellaneous scripts sudo cp $IMAGE_CONFIGS/misc/docker-wait-any $FILESYSTEM_ROOT/usr/bin/ +# Copy internal topology configuration scripts +{%- if sonic_asic_platform == "vs" %} +sudo cp $IMAGE_CONFIGS/topology/topology.service $FILESYSTEM_ROOT/etc/systemd/system/ +echo "topology.service" | sudo tee -a $GENERATED_SERVICE_FILE +sudo cp $IMAGE_CONFIGS/topology/topology.sh $FILESYSTEM_ROOT/usr/bin +{%- endif %} + # Copy updategraph script and service file j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/updategraph.service sudo cp $IMAGE_CONFIGS/updategraph/updategraph $FILESYSTEM_ROOT/usr/bin/ @@ -401,6 +408,13 @@ sudo cp {{script}} $FILESYSTEM_ROOT/usr/bin/ {% for service in installer_services.split(' ') -%} if [ -f {{service}} ]; then sudo cp {{service}} $FILESYSTEM_ROOT/etc/systemd/system/ + + {% if "@" in service %} + MULTI_INSTANCE="{{service}}" + SINGLE_INSTANCE=${MULTI_INSTANCE/"@"} + sudo cp $SINGLE_INSTANCE $FILESYSTEM_ROOT/etc/systemd/system/ + {% endif %} + echo "{{service}}" | sudo tee -a $GENERATED_SERVICE_FILE fi {% endfor %} diff --git a/files/image_config/topology/topology.service b/files/image_config/topology/topology.service new file mode 100644 index 000000000000..eea4bf65230a --- /dev/null +++ b/files/image_config/topology/topology.service @@ -0,0 +1,16 @@ +[Unit] +Description=Internal topology service +Requires=database.service +After=database.service +PartOf=database.service + +[Service] +Type=oneshot +User=root +RemainAfterExit=yes +ExecStart=/usr/bin/topology.sh start +ExecStop=/usr/bin/topology.sh stop + +[Install] +WantedBy=multi-user.target + diff --git a/files/image_config/topology/topology.sh b/files/image_config/topology/topology.sh new file mode 100755 index 000000000000..7013920ec016 --- /dev/null +++ b/files/image_config/topology/topology.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# This script is invoked by topology.service only +# for multi-asic virtual platform. For multi-asic platform +# multiple Database instances are present +# and HWKSU information is retrieved from first database instance. +# + +start() { + DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` + /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start +} +stop() { + DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` + /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop +} + +case "$1" in + start|stop) + $1 + ;; + *) + echo "Usage: $0 {start|stop}" + ;; +esac diff --git a/platform/template/docker-syncd-base.mk b/platform/template/docker-syncd-base.mk index cefcf15ebd62..d0407beee8a0 100644 --- a/platform/template/docker-syncd-base.mk +++ b/platform/template/docker-syncd-base.mk @@ -29,7 +29,7 @@ endif $(DOCKER_SYNCD_BASE)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_BASE)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_BASE)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/platform/vs/README.vsvm.md b/platform/vs/README.vsvm.md index d627859578b4..68f7d0244017 100644 --- a/platform/vs/README.vsvm.md +++ b/platform/vs/README.vsvm.md @@ -6,10 +6,10 @@ HOWTO Use Virtual Switch (VM) sudo apt-get install libvirt-clients qemu-kvm libvirt-bin ``` -2. Create SONiC VM +2. Create SONiC VM for single ASIC HWSKU ``` -$ virsh +$ sudo virsh Welcome to virsh, the virtualization interactive terminal. Type: 'help' for help with commands @@ -22,14 +22,54 @@ Domain sonic created from sonic.xml virsh # ``` -2. Connect SONiC VM via console +2. Create SONiC VM for multi-ASIC HWSKU +Update sonic_multiasic.xml with the external interfaces +required for HWSKU. ``` -$ telnet 127.0.0.1 7000 -``` +$ sudo virsh +Welcome to virsh, the virtualization interactive terminal. -3. Connect SONiC VM via SSH +Type: 'help' for help with commands + 'quit' to quit -``` -$ ssh -p 3040 admin@127.0.0.1 -``` +virsh # +virsh # create sonic_multiasic.xml +Domain sonic created from sonic.xml + +virsh # + +Once booted up, create a file "asic.conf" with the content: +NUM_ASIC= +under /usr/share/sonic/device/x86_64-kvm_x86_64-r0/ +Also, create a "topology.sh" file which will simulate the internal +asic connectivity of the hardware under +/usr/share/sonic/device/x86_64-kvm_x86_64-r0/ +The HWSKU directory will have the required files like port_config.ini +for each ASIC. + +Having done this, a new service "topology.service" will be started +during bootup which will invoke topology.sh script. + +3. Access virtual switch: + + 1. Connect SONiC VM via console + ``` + $ telnet 127.0.0.1 7000 + ``` + + OR + + 2. Connect SONiC VM via SSH + + 1. Connect via console (see 3.1 above) + + 2. Request a new DHCP address + ``` + sudo dhclient -v + ``` + + 3. Connect via SSH + ``` + $ ssh -p 3040 admin@127.0.0.1 + ``` diff --git a/platform/vs/sonic_multiasic.xml b/platform/vs/sonic_multiasic.xml new file mode 100644 index 000000000000..b406bfd40475 --- /dev/null +++ b/platform/vs/sonic_multiasic.xml @@ -0,0 +1,110 @@ + + sonic + 8 + 2 + + /machine + + + hvm + + + + + + + + destroy + restart + restart + + /usr/bin/qemu-system-x86_64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + + + + diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 9ad6b0b36b45..91fd06819a4b 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -23,7 +23,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DATABASE_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DATABASE_DBG) $(DOCKER_DATABASE)_CONTAINER_NAME = database -$(DOCKER_DATABASE)_RUN_OPT += --net=host --privileged -t +$(DOCKER_DATABASE)_RUN_OPT += --privileged -t $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 8deb6ebbfad7..4c044d5e05a0 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -23,6 +23,6 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DHCP_RELAY_DBG) $(DOCKER_DHCP_RELAY)_CONTAINER_NAME = dhcp_relay -$(DOCKER_DHCP_RELAY)_RUN_OPT += --net=host --privileged -t +$(DOCKER_DHCP_RELAY)_RUN_OPT += --privileged -t $(DOCKER_DHCP_RELAY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DHCP_RELAY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index e833d360bec2..1d918830ab55 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -22,7 +22,7 @@ SONIC_DOCKER_DBG_IMAGES += $(DOCKER_FPM_FRR_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_FPM_FRR_DBG) $(DOCKER_FPM_FRR)_CONTAINER_NAME = bgp -$(DOCKER_FPM_FRR)_RUN_OPT += --net=host --privileged -t +$(DOCKER_FPM_FRR)_RUN_OPT += --privileged -t $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw diff --git a/rules/docker-fpm-gobgp.mk b/rules/docker-fpm-gobgp.mk index 12fa37dc1d97..3e1839d47099 100644 --- a/rules/docker-fpm-gobgp.mk +++ b/rules/docker-fpm-gobgp.mk @@ -7,5 +7,5 @@ $(DOCKER_FPM_GOBGP)_LOAD_DOCKERS += $(DOCKER_FPM_QUAGGA) SONIC_DOCKER_IMAGES += $(DOCKER_FPM_GOBGP) $(DOCKER_FPM_GOBGP)_CONTAINER_NAME = bgp -$(DOCKER_FPM_GOBGP)_RUN_OPT += --net=host --privileged -t +$(DOCKER_FPM_GOBGP)_RUN_OPT += --privileged -t $(DOCKER_FPM_GOBGP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/rules/docker-fpm-quagga.mk b/rules/docker-fpm-quagga.mk index a9c0511ba173..2c78d1917b0e 100644 --- a/rules/docker-fpm-quagga.mk +++ b/rules/docker-fpm-quagga.mk @@ -7,7 +7,7 @@ $(DOCKER_FPM_QUAGGA)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_FPM_QUAGGA) $(DOCKER_FPM_QUAGGA)_CONTAINER_NAME = bgp -$(DOCKER_FPM_QUAGGA)_RUN_OPT += --net=host --privileged -t +$(DOCKER_FPM_QUAGGA)_RUN_OPT += --privileged -t $(DOCKER_FPM_QUAGGA)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_FPM_QUAGGA)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh diff --git a/rules/docker-lldp-sv2.mk b/rules/docker-lldp-sv2.mk index 8224239c1ced..a39b307d5063 100644 --- a/rules/docker-lldp-sv2.mk +++ b/rules/docker-lldp-sv2.mk @@ -25,7 +25,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_SV2_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_LLDP_SV2_DBG) $(DOCKER_LLDP_SV2)_CONTAINER_NAME = lldp -$(DOCKER_LLDP_SV2)_RUN_OPT += --net=host --privileged -t +$(DOCKER_LLDP_SV2)_RUN_OPT += --privileged -t $(DOCKER_LLDP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpctl:/usr/bin/lldpctl diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index 0244138cbfe2..bab1a3a29920 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -26,7 +26,7 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ORCHAGENT_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ORCHAGENT_DBG) $(DOCKER_ORCHAGENT)_CONTAINER_NAME = swss -$(DOCKER_ORCHAGENT)_RUN_OPT += --net=host --privileged -t +$(DOCKER_ORCHAGENT)_RUN_OPT += --privileged -t $(DOCKER_ORCHAGENT)_RUN_OPT += -v /etc/network/interfaces:/etc/network/interfaces:ro $(DOCKER_ORCHAGENT)_RUN_OPT += -v /etc/network/interfaces.d/:/etc/network/interfaces.d/:ro $(DOCKER_ORCHAGENT)_RUN_OPT += -v /host/machine.conf:/host/machine.conf:ro diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index 7a319e4bf120..a37f4d2e9ee7 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -33,7 +33,7 @@ SONIC_DOCKER_DBG_IMAGES += $(DOCKER_PLATFORM_MONITOR_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_PLATFORM_MONITOR_DBG) $(DOCKER_PLATFORM_MONITOR)_CONTAINER_NAME = pmon -$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += --net=host --privileged -t +$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += --privileged -t $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # Mount Arista python library on Aboot images to be used by plugins diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk index 53e0d7600ec9..ec3fcf6e1fa3 100644 --- a/rules/docker-router-advertiser.mk +++ b/rules/docker-router-advertiser.mk @@ -23,6 +23,6 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ROUTER_ADVERTISER_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ROUTER_ADVERTISER_DBG) $(DOCKER_ROUTER_ADVERTISER)_CONTAINER_NAME = radv -$(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += --net=host --privileged -t +$(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += --privileged -t $(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ROUTER_ADVERTISER)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk index 449ff7c566f2..67724ad7c548 100644 --- a/rules/docker-sflow.mk +++ b/rules/docker-sflow.mk @@ -26,7 +26,7 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SFLOW_DBG) endif $(DOCKER_SFLOW)_CONTAINER_NAME = sflow -$(DOCKER_SFLOW)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SFLOW)_RUN_OPT += --privileged -t $(DOCKER_SFLOW)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_SFLOW)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/rules/docker-snmp-sv2.mk b/rules/docker-snmp-sv2.mk index 1f403b7a8c8a..59f99ac78bc7 100644 --- a/rules/docker-snmp-sv2.mk +++ b/rules/docker-snmp-sv2.mk @@ -26,7 +26,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_SV2_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SNMP_SV2_DBG) $(DOCKER_SNMP_SV2)_CONTAINER_NAME = snmp -$(DOCKER_SNMP_SV2)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SNMP_SV2)_RUN_OPT += --privileged -t $(DOCKER_SNMP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # mount Arista platform python libraries to support corresponding platforms SNMP power status query $(DOCKER_SNMP_SV2)_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk index 598eff97e8f1..ce7b5bbab1f5 100644 --- a/rules/docker-teamd.mk +++ b/rules/docker-teamd.mk @@ -24,7 +24,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_TEAMD_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_TEAMD_DBG) $(DOCKER_TEAMD)_CONTAINER_NAME = teamd -$(DOCKER_TEAMD)_RUN_OPT += --net=host --privileged -t +$(DOCKER_TEAMD)_RUN_OPT += --privileged -t $(DOCKER_TEAMD)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TEAMD)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 361136306337..04f1871f334b 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -25,7 +25,7 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_TELEMETRY_DBG) endif $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry -$(DOCKER_TELEMETRY)_RUN_OPT += --net=host --privileged -t +$(DOCKER_TELEMETRY)_RUN_OPT += --privileged -t $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" diff --git a/slave.mk b/slave.mk index 8e7253d7e57c..cc118da7aa06 100644 --- a/slave.mk +++ b/slave.mk @@ -667,15 +667,39 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export docker_container_name="$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)" $(eval $(docker:-dbg.gz=.gz)_RUN_OPT += $($(docker:-dbg.gz=.gz)_$($*_IMAGE_TYPE)_RUN_OPT)) export docker_image_run_opt="$($(docker:-dbg.gz=.gz)_RUN_OPT)" - j2 files/build_templates/docker_image_ctl.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh + if [ -f files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then j2 files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service fi + + if [ -f files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 ]; then + j2 files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service + + # performs the same check as the elif above, except with make commands so eval behaves properly + $(if $(shell ls files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_TEMPLATE = yes) + ) + fi + if [ -f files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then + j2 files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service + fi + j2 files/build_templates/docker_image_ctl.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh chmod +x $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh ) + # Exported variables are used by sonic_debian_extension.sh export installer_start_scripts="$(foreach docker, $($*_DOCKERS),$(addsuffix .sh, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)))" - export installer_services="$(foreach docker, $($*_DOCKERS),$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)))" + + # Marks template services with an "@" according to systemd convention + # If the $($docker)_TEMPLATE) variable is set, the service will be treated as a template + $(foreach docker, $($*_DOCKERS),\ + $(if $($(docker:-dbg.gz=.gz)_TEMPLATE),\ + $(eval SERVICES += "$(addsuffix @.service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))"),\ + $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))") + ) + ) + export installer_services="$(SERVICES)" + export installer_extra_files="$(foreach docker, $($*_DOCKERS), $(foreach file, $($(docker:-dbg.gz=.gz)_BASE_IMAGE_FILES), $($(docker:-dbg.gz=.gz)_PATH)/base_image_files/$(file)))" j2 -f env files/initramfs-tools/union-mount.j2 onie-image.conf > files/initramfs-tools/union-mount @@ -706,6 +730,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(foreach docker, $($*_DOCKERS), \ rm -f $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh rm -f $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service + rm -f $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service ) $(if $($*_DOCKERS), diff --git a/src/systemd-sonic-generator/systemd-sonic-generator.c b/src/systemd-sonic-generator/systemd-sonic-generator.c index a2723a28ff03..566d37ff0a4c 100644 --- a/src/systemd-sonic-generator/systemd-sonic-generator.c +++ b/src/systemd-sonic-generator/systemd-sonic-generator.c @@ -9,13 +9,17 @@ #include #include -#define MAX_NUM_TARGETS 5 -#define MAX_NUM_INSTALL_LINES 5 +#define MAX_NUM_TARGETS 15 +#define MAX_NUM_INSTALL_LINES 15 #define MAX_NUM_UNITS 128 +#define MAX_BUF_SIZE 512 static const char* UNIT_FILE_PREFIX = "/etc/systemd/system/"; static const char* CONFIG_FILE = "/etc/sonic/generated_services.conf"; - +static const char* MACHINE_CONF_FILE = "/host/machine.conf"; +static int num_asics; +static char** multi_instance_services; +static int num_multi_inst; void strip_trailing_newline(char* str) { /*** @@ -61,7 +65,7 @@ static int get_target_lines(char* unit_file, char* target_lines[]) { if (num_target_lines >= MAX_NUM_INSTALL_LINES) { fprintf(stderr, "Number of lines in [Install] section of %s exceeds MAX_NUM_INSTALL_LINES\n", unit_file); fputs("Extra [Install] lines will be ignored\n", stderr); - return num_target_lines; + break; } target_lines[num_target_lines] = strdup(line); num_target_lines++; @@ -75,7 +79,18 @@ static int get_target_lines(char* unit_file, char* target_lines[]) { return num_target_lines; } -static int get_install_targets_from_line(char* target_string, char* suffix, char* targets[], int existing_targets) { +static bool is_multi_instance_service(char *service_name){ + int i; + for(i=0; i < num_multi_inst; i++){ + if (strstr(service_name, multi_instance_services[i]) != NULL) { + return true; + } + } + return false; + +} + +static int get_install_targets_from_line(char* target_string, char* install_type, char* targets[], int existing_targets) { /*** Helper fuction for get_install_targets @@ -88,26 +103,113 @@ static int get_install_targets_from_line(char* target_string, char* suffix, char int num_targets = 0; while ((token = strtok_r(target_string, " ", &target_string))) { - target = strdup(token); - strip_trailing_newline(target); - - strcpy(final_target, target); - strcat(final_target, suffix); - - free(target); - if (num_targets + existing_targets >= MAX_NUM_TARGETS) { fputs("Number of targets found exceeds MAX_NUM_TARGETS\n", stderr); fputs("Additional targets will be ignored \n", stderr); return num_targets; } + target = strdup(token); + strip_trailing_newline(target); + + if (strstr(target, "%") != NULL) { + char* prefix = strtok(target, "."); + char* suffix = strtok(NULL, "."); + int prefix_len = strlen(prefix); + + strncpy(final_target, prefix, prefix_len - 2); + final_target[prefix_len - 2] = '\0'; + strcat(final_target, "."); + strcat(final_target, suffix); + } + else { + strcpy(final_target, target); + } + strcat(final_target, install_type); + + free(target); + targets[num_targets + existing_targets] = strdup(final_target); num_targets++; } return num_targets; } +static void replace_multi_inst_dep(char *src) { + FILE *fp_src; + FILE *fp_tmp; + char buf[MAX_BUF_SIZE]; + char* line = NULL; + int i; + ssize_t len; + char *token; + char *word; + char *line_copy; + char *service_name; + char *type; + ssize_t nread; + bool section_done = false; + char tmp_file_path[PATH_MAX]; + + /* assumes that the service files has 3 sections, + * in the order: Unit, Service and Install. + * Read service dependency from Unit and Install + * sections, replace if dependent on multi instance + * service. + */ + fp_src = fopen(src, "r"); + snprintf(tmp_file_path, PATH_MAX, "%s.tmp", src); + fp_tmp = fopen(tmp_file_path, "w"); + + while ((nread = getline(&line, &len, fp_src)) != -1 ) { + if (strstr(line, "[Service]") != NULL) { + section_done = true; + fputs(line,fp_tmp); + } else if (strstr(line, "[Install]") != NULL) { + section_done = false; + fputs(line,fp_tmp); + } else if ((strstr(line, "[Unit]") != NULL) || + (strstr(line, "Description") != NULL) || + (section_done == true)){ + fputs(line,fp_tmp); + } else { + line_copy = strdup(line); + token = strtok(line_copy, "="); + while ((word = strtok(NULL, " "))){ + if((strchr(word, '.') == NULL) || + (strchr(word, '@') != NULL)) { + snprintf(buf, MAX_BUF_SIZE,"%s=%s\n",token, word); + fputs(buf,fp_tmp); + } else { + service_name = strdup(word); + service_name = strtok(service_name, "."); + type = strtok(NULL, " "); + if (is_multi_instance_service(word)) { + for(i = 0; i < num_asics; i++){ + snprintf(buf, MAX_BUF_SIZE, "%s=%s@%d.%s\n", + token, service_name, i, type); + fputs(buf,fp_tmp); + } + } else { + snprintf(buf, MAX_BUF_SIZE,"%s=%s.%s\n",token, service_name, type); + fputs(buf, fp_tmp); + } + free(service_name); + } + } + free(line_copy); + } + } + fclose(fp_src); + fclose(fp_tmp); + free(line); + /* remove the .service file, rename the .service.tmp file + * as .service. + */ + remove(src); + rename(tmp_file_path, src); +} + static int get_install_targets(char* unit_file, char* targets[]) { /*** Returns install targets for a unit file @@ -124,10 +226,21 @@ static int get_install_targets(char* unit_file, char* targets[]) { char* line = NULL; bool first; char* target_suffix; + char *instance_name; + char *dot_ptr; strcpy(file_path, UNIT_FILE_PREFIX); strcat(file_path, unit_file); + instance_name = strdup(unit_file); + dot_ptr = strchr(instance_name, '.'); + *dot_ptr = '\0'; + + if((num_asics > 1) && (!is_multi_instance_service(instance_name))) { + replace_multi_inst_dep(file_path); + } + free(instance_name); + num_target_lines = get_target_lines(file_path, target_lines); if (num_target_lines < 0) { fprintf(stderr, "Error parsing targets for %s\n", unit_file); @@ -170,6 +283,7 @@ static int get_unit_files(char* unit_files[]) { char *line = NULL; size_t len = 0; ssize_t read; + char *pos; fp = fopen(CONFIG_FILE, "r"); @@ -179,13 +293,30 @@ static int get_unit_files(char* unit_files[]) { } int num_unit_files = 0; + num_multi_inst = 0; + + multi_instance_services = malloc(MAX_NUM_UNITS * sizeof(char *)); while ((read = getline(&line, &len, fp)) != -1) { if (num_unit_files >= MAX_NUM_UNITS) { fprintf(stderr, "Maximum number of units exceeded, ignoring extras\n"); - return num_unit_files; + break; } strip_trailing_newline(line); + + /* Get the multi-instance services */ + pos = strchr(line, '@'); + if (pos != NULL) { + multi_instance_services[num_multi_inst] = malloc(strlen(line)*sizeof(char)); + strncpy(multi_instance_services[num_multi_inst], line, pos-line); + num_multi_inst++; + } + + /* topology service to be started only for multiasic VS platform */ + if ((strcmp(line, "topology.service") == 0) && + (num_asics == 1)) { + continue; + } unit_files[num_unit_files] = strdup(line); num_unit_files++; } @@ -198,28 +329,70 @@ static int get_unit_files(char* unit_files[]) { } -static int install_unit_file(char* unit_file, char* target, char* install_dir) { +static char* insert_instance_number(char* unit_file, int instance) { /*** - Creates a symlink for a unit file installation + Adds an instance number to a systemd template name - For a given unit file and target directory, - create the appropriate symlink in the target directory - to enable the unit and have it started by Systemd + E.g. given unit_file='example@.service', instance=3, + returns a pointer to 'example@1.service' ***/ - char final_install_dir[PATH_MAX]; + char* prefix; + char* suffix; + char* instance_string; + char* instance_name; + char* temp_unit_file; + + instance_string = malloc(2 * sizeof(char)); + snprintf(instance_string, 2, "%d", instance); + + instance_name = malloc(strlen(unit_file) + 2); + + if (instance_name == NULL) { + fprintf(stderr, "Error creating instance %d of %s\n", instance, unit_file); + return NULL; + } + + temp_unit_file = strdup(unit_file); + prefix = strtok(temp_unit_file, "@"); + suffix = strtok(NULL, "@"); + + strcpy(instance_name, prefix); + strcat(instance_name, "@"); + strcat(instance_name, instance_string); + strcat(instance_name, suffix); + + free(instance_string); + free(temp_unit_file); + + return instance_name; +} + + +static int create_symlink(char* unit, char* target, char* install_dir, int instance) { + struct stat st; char src_path[PATH_MAX]; char dest_path[PATH_MAX]; - struct stat st; + char final_install_dir[PATH_MAX]; + char* unit_instance; int r; - assert(unit_file); - assert(target); + strcpy(src_path, UNIT_FILE_PREFIX); + strcat(src_path, unit); + + if (instance < 0) { + unit_instance = strdup(unit); + } + else { + unit_instance = insert_instance_number(unit, instance); + } strcpy(final_install_dir, install_dir); strcat(final_install_dir, target); + strcpy(dest_path, final_install_dir); + strcat(dest_path, "/"); + strcat(dest_path, unit_instance); - strcpy(src_path, UNIT_FILE_PREFIX); - strcat(src_path, unit_file); + free(unit_instance); if (stat(final_install_dir, &st) == -1) { // If doesn't exist, create @@ -242,7 +415,7 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { fprintf(stderr, "Unable to create target directory %s\n", final_install_dir); return -1; } - } + } else if (S_ISDIR(st.st_mode)) { // If directory, verify correct permissions r = chmod(final_install_dir, 0755); @@ -251,11 +424,6 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { return -1; } } - - - strcpy(dest_path, final_install_dir); - strcat(dest_path, "/"); - strcat(dest_path, unit_file); r = symlink(src_path, dest_path); @@ -267,6 +435,123 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { } return 0; + +} + + +static int install_unit_file(char* unit_file, char* target, char* install_dir) { + /*** + Creates a symlink for a unit file installation + + For a given unit file and target directory, + create the appropriate symlink in the target directory + to enable the unit and have it started by Systemd + + If a multi ASIC platform is detected, enables multi-instance + services as well + ***/ + char* target_instance; + char* prefix; + char* suffix; + int r; + + assert(unit_file); + assert(target); + + + if ((num_asics > 1) && strstr(unit_file, "@") != NULL) { + + for (int i = 0; i < num_asics; i++) { + + if (strstr(target, "@") != NULL) { + target_instance = insert_instance_number(target, i); + } + else { + target_instance = strdup(target); + } + + r = create_symlink(unit_file, target_instance, install_dir, i); + if (r < 0) + fprintf(stderr, "Error installing %s for target %s\n", unit_file, target_instance); + + free(target_instance); + + } + } + else { + r = create_symlink(unit_file, target, install_dir, -1); + if (r < 0) + fprintf(stderr, "Error installing %s for target %s\n", unit_file, target); + } + + return 0; +} + + +static int get_num_of_asic() { + /*** + Determines if the current platform is single or multi-ASIC + ***/ + FILE *fp; + FILE *env_fp; + char *line = NULL; + char* token; + char* platform; + size_t len = 0; + ssize_t nread; + bool ans; + char asic_file[512]; + char* str_num_asic; + int num_asic = 1; + + fp = fopen(MACHINE_CONF_FILE, "r"); + + if (fp == NULL) { + fprintf(stderr, "Failed to open %s\n", MACHINE_CONF_FILE); + exit(EXIT_FAILURE); + } + + while ((nread = getline(&line, &len, fp)) != -1) { + if ((strstr(line, "onie_platform") != NULL) || + (strstr(line, "aboot_platform") != NULL)) { + token = strtok(line, "="); + platform = strtok(NULL, "="); + strip_trailing_newline(platform); + break; + } + } + + fclose(fp); + if(platform != NULL) { + snprintf(asic_file, 512, "/usr/share/sonic/device/%s/asic.conf", platform); + fp = fopen(asic_file, "r"); + if (fp != NULL) { + while ((nread = getline(&line, &len, fp)) != -1) { + if (strstr(line, "NUM_ASIC") != NULL) { + token = strtok(line, "="); + str_num_asic = strtok(NULL, "="); + strip_trailing_newline(str_num_asic); + if (str_num_asic != NULL){ + sscanf(str_num_asic, "%d",&num_asic); + } + break; + } + } + fclose(fp); + free(line); + } + } + + /*set environment variable NUM_ASIC */ + env_fp = fopen("/etc/environment", "a"); + if (env_fp == NULL) { + fprintf(stderr, "Failed to open environment file\n"); + exit(EXIT_FAILURE); + } + fprintf(env_fp, "NUM_ASIC=%d\n", num_asic); + fclose(env_fp); + return num_asic; + } @@ -274,14 +559,20 @@ int main(int argc, char **argv) { char* unit_files[MAX_NUM_UNITS]; char install_dir[PATH_MAX]; char* targets[MAX_NUM_TARGETS]; + char* unit_instance; + char* prefix; + char* suffix; int num_unit_files; int num_targets; + int r; if (argc <= 1) { fputs("Installation directory required as argument\n", stderr); return 1; } + num_asics = get_num_of_asic(); + strcpy(install_dir, argv[1]); strcat(install_dir, "/"); @@ -289,21 +580,38 @@ int main(int argc, char **argv) { // For each unit file, get the installation targets and install the unit for (int i = 0; i < num_unit_files; i++) { - num_targets = get_install_targets(unit_files[i], targets); + unit_instance = strdup(unit_files[i]); + if ((num_asics == 1) && strstr(unit_instance, "@") != NULL) { + prefix = strtok(unit_instance, "@"); + suffix = strtok(NULL, "@"); + + strcpy(unit_instance, prefix); + strcat(unit_instance, suffix); + } + + num_targets = get_install_targets(unit_instance, targets); if (num_targets < 0) { - fprintf(stderr, "Error parsing %s\n", unit_files[i]); + fprintf(stderr, "Error parsing %s\n", unit_instance); + free(unit_instance); free(unit_files[i]); continue; } for (int j = 0; j < num_targets; j++) { - if (install_unit_file(unit_files[i], targets[j], install_dir) != 0) - fprintf(stderr, "Error installing %s to target directory %s\n", unit_files[i], targets[j]); + if (install_unit_file(unit_instance, targets[j], install_dir) != 0) + fprintf(stderr, "Error installing %s to target directory %s\n", unit_instance, targets[j]); free(targets[j]); } + free(unit_instance); free(unit_files[i]); } + + for (int i = 0; i < num_multi_inst; i++) { + free(multi_instance_services[i]); + } + free(multi_instance_services); + return 0; } From dc994b8425fb58293f6cb091f6b371f4a2fc9987 Mon Sep 17 00:00:00 2001 From: Srideep Date: Tue, 28 Jan 2020 00:28:26 -0700 Subject: [PATCH 0326/1427] DellEMC: Dell platform bug fixes on s5248 and s6232 (#4071) * Dynamic bus detection and loading driver for eeprom on s5248,s5232 * sfputil fix for S5248 --- .../x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py | 12 +++++++++++- .../x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py | 12 +++++++++++- .../plugins/sfputil.py | 2 +- .../s5232f/scripts/s5232f_platform.sh | 4 ++-- .../s5248f/scripts/s5248f_platform.sh | 4 ++-- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py index ed10672bed19..0b96b00d4ec7 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py @@ -9,7 +9,9 @@ # - specific encoder/decoder if there is special need ############################################################################# + try: + import os.path from sonic_eeprom import eeprom_tlvinfo except ImportError, e: raise ImportError (str(e) + "- required module not found") @@ -18,5 +20,13 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): - self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0050/eeprom" + self.eeprom_path = None + for b in (0, 1): + f = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'.format(b) + if os.path.exists(f): + self.eeprom_path = f + break + if self.eeprom_path is None: + return + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py index 5b044d0ee30a..b6305a6ed634 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py @@ -9,7 +9,9 @@ # - specific encoder/decoder if there is special need ############################################################################# + try: + import os.path from sonic_eeprom import eeprom_tlvinfo except ImportError, e: raise ImportError (str(e) + "- required module not found") @@ -18,5 +20,13 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): - self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0050/eeprom" + self.eeprom_path = None + for b in (0, 1): + f = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'.format(b) + if os.path.exists(f): + self.eeprom_path = f + break + if self.eeprom_path is None: + return + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py index 911c04a0fe0d..4bc0745df2de 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py @@ -319,7 +319,7 @@ def get_transceiver_change_event(self, timeout=0): time.sleep(0.5) - def get_transceiver_dom_info_dict(self, port_num): + def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict = {} dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh index 6923c9f4b353..a419b7d22e5f 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh @@ -17,9 +17,9 @@ init_devnum() { # Attach/Detach syseeprom on CPU board sys_eeprom() { case $1 in - "new_device") echo 24c16 0x50 > /sys/bus/i2c/devices/i2c-0/$1 + "new_device") echo 24c16 0x50 > /sys/bus/i2c/devices/i2c-${devnum}/$1 ;; - "delete_device") echo 0x50 > /sys/bus/i2c/devices/i2c-0/$1 + "delete_device") echo 0x50 > /sys/bus/i2c/devices/i2c-${devnum}/$1 ;; *) echo "s5232f_platform: sys_eeprom : invalid command !" ;; diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh index 094c88eeaba6..77032d643397 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh @@ -17,9 +17,9 @@ init_devnum() { # Attach/Detach syseeprom on CPU board sys_eeprom() { case $1 in - "new_device") echo 24c16 0x50 > /sys/bus/i2c/devices/i2c-0/$1 + "new_device") echo 24c16 0x50 > /sys/bus/i2c/devices/i2c-${devnum}/$1 ;; - "delete_device") echo 0x50 > /sys/bus/i2c/devices/i2c-0/$1 + "delete_device") echo 0x50 > /sys/bus/i2c/devices/i2c-${devnum}/$1 ;; *) echo "s5248f_platform: sys_eeprom : invalid command !" ;; From d2362986883502780ebf6665395fbd8d027fb611 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Tue, 28 Jan 2020 09:23:36 -0800 Subject: [PATCH 0327/1427] [bfn] Added GENL3 dependency for SAI (#4069) Signed-off-by: Andriy Kokhan --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 0db9f2d26a77..2b7711bd844f 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ BFN_PLATFORM = bfnplatform_9.1.0.fddc672_deb9.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_1/bfnplatform_9.1.0.fddc672_deb9.deb" +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_1/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 60a88fad1caf..dca95460bf3a 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,8 @@ BFN_SAI = bfnsdk_9.1.0.fddc672_deb9.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_1/bfnsdk_9.1.0.fddc672_deb9.deb" +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_1/$(BFN_SAI)" + +$(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) +$(BFN_SAI)_RDEPENDS += $(LIBNL_GENL3) SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) From 2e36b25c5aeafa4952e1ef7fe8a61b7be553bcb4 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Tue, 28 Jan 2020 15:26:21 -0800 Subject: [PATCH 0328/1427] [utilities] Update utilities submodule (#4080) - [neighbor advertiser] remove http endpoint access (#792) - [dropconfig] Move prefix-handling from CLI to orchagent (#785) - [acl-loader] Use V6 ethertype for IPv6 ACL rule (#788) - kdump support (#729) - Add command line support for thermal control (#777) - [fdbshow][nbrshow] Print interface OID in lieu of name if there is no OID->interface name mapping (#789) - ipaddr module to ipaddress for show command (#786) - [sonic_installer] Adding support for ARM Uboot firmware (#769) - [config] Merge duplicate vrf configuration (#759) - [dropconfig] Clean-up error output for devices that do not support drop counters (#784) - [show] enhance 'show ip[v6] bgp summary' command (#754) - On sflow enable, start the docker since it is disabled by default (#773) - [portstat] fix header used (#743) - Add VRF-related commands to Command Reference Document (#778) - [intfstat] fix --delete fail when counters dump does not exist (#752) - [scripts] Adds support for management (1.0) commands (#745) - A generic JSON file updater, which can add/update-existing attributes. (#770) - [command reference] Update show int counters info with l3 RIF (#725) - [fast/warm reboot] ignore errors after shutting down critical service(s) (#761) - Platform Driver Development Framework (PDDF): Adding PDDF CLI utils (#624) - Platform plugin for Fast-reboot/warm-reboot (#740) Signed-off-by: Danny Allen --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 640f4a792552..5214a8d66eb4 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 640f4a79255268583ed365b94c32259efecf4dcc +Subproject commit 5214a8d66eb48b536e0b95e4ddc3b9879d0ce49f From 7cb63008d793adb71c11e81f6f31eaa31e20d4b2 Mon Sep 17 00:00:00 2001 From: kannankvs Date: Wed, 29 Jan 2020 07:11:21 +0530 Subject: [PATCH 0329/1427] =?UTF-8?q?mvrf=5Favoid=5Fsnmp=5Fyml=5Fconfig:?= =?UTF-8?q?=20made=20changes=20to=20pass=20SNMP=20config=20from=20con?= =?UTF-8?q?=E2=80=A6=20(#4057)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * mvrf_avoid_snmp_yml_config: made changes to pass SNMP config from confiDB to snmpd.conf without using snmp.yml * added a missing if condition --- dockers/docker-snmp-sv2/snmpd.conf.j2 | 38 +++++++----- files/build_templates/docker_image_ctl.j2 | 71 ----------------------- files/image_config/snmp/snmp.yml | 3 - 3 files changed, 22 insertions(+), 90 deletions(-) diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp-sv2/snmpd.conf.j2 index 16d7e5bff79c..7d4022501fbb 100644 --- a/dockers/docker-snmp-sv2/snmpd.conf.j2 +++ b/dockers/docker-snmp-sv2/snmpd.conf.j2 @@ -15,16 +15,10 @@ # Listen for connections on all ip addresses, including eth0, ipv4 lo # -{% if snmp_agent_address_1 or snmp_agent_address_2 or snmp_agent_address_3 %} -{% if snmp_agent_address_1 %} -agentAddress {{ snmp_agent_address_1 }} -{% endif %} -{% if snmp_agent_address_2 %} -agentAddress {{ snmp_agent_address_2 }} -{% endif %} -{% if snmp_agent_address_3 %} -agentAddress {{ snmp_agent_address_3 }} -{% endif %} +{% if SNMP_AGENT_ADDRESS_CONFIG %} +{% for (agentip, port, vrf) in SNMP_AGENT_ADDRESS_CONFIG %} +agentAddress {{ agentip }}{% if port %}:{{ port }}{% endif %}{% if vrf %}%{{ vrf }}{% endif %}{{ "" }} +{% endfor %} {% else %} agentAddress udp:161 agentAddress udp6:161 @@ -105,20 +99,32 @@ load 12 10 5 # Note: disabled snmp traps due to side effect of causing snmpd to listen on all ports (0.0.0.0) # # send SNMPv1 traps -{%if v1_trap_dest and v1_trap_dest != 'NotConfigured' %} -trapsink {{ v1_trap_dest }} +{% if SNMP_TRAP_CONFIG and SNMP_TRAP_CONFIG['v1TrapDest'] %} +{% set v1SnmpTrapIp = SNMP_TRAP_CONFIG['v1TrapDest']['DestIp'] %} +{% set v1SnmpTrapPort = SNMP_TRAP_CONFIG['v1TrapDest']['DestPort'] %} +{% set v1SnmpTrapVrf = SNMP_TRAP_CONFIG['v1TrapDest']['vrf'] %} +{% set v1SnmpTrapComm = SNMP_TRAP_CONFIG['v1TrapDest']['Community'] %} +trapsink {{ v1SnmpTrapIp }}:{{ v1SnmpTrapPort }}{% if v1SnmpTrapVrf != 'None' %}%{{ v1SnmpTrapVrf }}{% endif %} {{ v1SnmpTrapComm }}{{ "" }} {% else %} #trapsink localhost public {% endif %} # send SNMPv2c traps -{%if v2_trap_dest and v2_trap_dest != 'NotConfigured' %} -trap2sink {{ v2_trap_dest }} +{% if SNMP_TRAP_CONFIG and SNMP_TRAP_CONFIG['v2TrapDest'] %} +{% set v2SnmpTrapIp = SNMP_TRAP_CONFIG['v2TrapDest']['DestIp'] %} +{% set v2SnmpTrapPort = SNMP_TRAP_CONFIG['v2TrapDest']['DestPort'] %} +{% set v2SnmpTrapVrf = SNMP_TRAP_CONFIG['v2TrapDest']['vrf'] %} +{% set v2SnmpTrapComm = SNMP_TRAP_CONFIG['v2TrapDest']['Community'] %} +trap2sink {{ v2SnmpTrapIp }}:{{ v2SnmpTrapPort }}{% if v2SnmpTrapVrf != 'None' %}%{{ v2SnmpTrapVrf }}{% endif %} {{ v2SnmpTrapComm }}{{ "" }} {% else %} #trap2sink localhost public {% endif %} # send SNMPv2c INFORMs -{%if v3_trap_dest and v3_trap_dest != 'NotConfigured' %} -informsink {{ v3_trap_dest }} +{% if SNMP_TRAP_CONFIG and SNMP_TRAP_CONFIG['v3TrapDest'] %} +{% set v3SnmpTrapIp = SNMP_TRAP_CONFIG['v3TrapDest']['DestIp'] %} +{% set v3SnmpTrapPort = SNMP_TRAP_CONFIG['v3TrapDest']['DestPort'] %} +{% set v3SnmpTrapVrf = SNMP_TRAP_CONFIG['v3TrapDest']['vrf'] %} +{% set v3SnmpTrapComm = SNMP_TRAP_CONFIG['v3TrapDest']['Community'] %} +trapsink {{ v3SnmpTrapIp }}:{{ v3SnmpTrapPort }}{% if v3SnmpTrapVrf != 'None' %}%{{ v3SnmpTrapVrf }}{% endif %} {{ v3SnmpTrapComm }}{{ "" }} {% else %} #informsink localhost public {% endif %} diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 995abce19379..2777a26c8edf 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -90,77 +90,6 @@ function preStartAction() fi {%- elif docker_container_name == "snmp" %} sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) - vrfenabled=`sonic-db-cli CONFIG_DB hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` - v1SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` - v1SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` - v1Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` - v1Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` - v2SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` - v2SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` - v2Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` - v2Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` - v3SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` - v3SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` - v3Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` - v3Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` - - if [ "${v1SnmpTrapIp}" != "" ] - then - if [ "${v1Vrf}" != "None" ] - then - sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort}%${v1Vrf} ${v1Comm}/" "/etc/sonic/snmp.yml" - else - sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort} ${v1Comm}/" "/etc/sonic/snmp.yml" - fi - else - sed -i "s/v1_trap_dest:.*/v1_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" - fi - if [ "${v2SnmpTrapIp}" != "" ] - then - if [ "${v2Vrf}" != "None" ] - then - sed -i "s/v2_trap_dest:.*/v2_trap_dest: ${v2SnmpTrapIp}:${v2SnmpTrapPort}%${v2Vrf} ${v2Comm}/" "/etc/sonic/snmp.yml" - else - sed -i "s/v2_trap_dest:.*/v2_trap_dest: ${v2SnmpTrapIp}:${v2SnmpTrapPort} ${v2Comm}/" "/etc/sonic/snmp.yml" - fi - else - sed -i "s/v2_trap_dest:.*/v2_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" - fi - if [ "${v3SnmpTrapIp}" != "" ] - then - if [ "${v3Vrf}" != "None" ] - then - sed -i "s/v3_trap_dest:.*/v3_trap_dest: ${v3SnmpTrapIp}:${v3SnmpTrapPort}%${v3Vrf} ${v3Comm}/" "/etc/sonic/snmp.yml" - else - sed -i "s/v3_trap_dest:.*/v3_trap_dest: ${v3SnmpTrapIp}:${v3SnmpTrapPort} ${v3Comm}/" "/etc/sonic/snmp.yml" - fi - else - sed -i "s/v3_trap_dest:.*/v3_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" - fi - - echo -n "" > /tmp/snmpagentaddr.yml - # TODO - # we should avoid using 'keys' operation via redis-cli or sonic-db-cli - # there would be an issue when KEY in database contains space or '\n' - # for loop on the non-tty 'keys' output will take the space or `\n` as seperator when parsing the element - keys=`sonic-db-cli CONFIG_DB keys "SNMP_AGENT_ADDRESS_CONFIG|*"` - count=1 - for key in $keys;do - ip=`echo $key|cut -d "|" -f2` - echo -n "snmp_agent_address_$count: $ip" >> /tmp/snmpagentaddr.yml - port=`echo $key|cut -d "|" -f3` - if [ -n "$port" ]; then - echo -n ":$port" >> /tmp/snmpagentaddr.yml - fi - vrf=`echo $key|cut -d "|" -f4` - if [ -n "$vrf" ]; then - echo -n "%$vrf" >> /tmp/snmpagentaddr.yml - fi - echo "" >> /tmp/snmpagentaddr.yml - count=$((count+1)) - done - sed -i '/snmp_agent_address_*/d' /etc/sonic/snmp.yml - cat /tmp/snmpagentaddr.yml >> /etc/sonic/snmp.yml {%- else %} : # nothing {%- endif %} diff --git a/files/image_config/snmp/snmp.yml b/files/image_config/snmp/snmp.yml index b200670f0d94..117619975fbb 100644 --- a/files/image_config/snmp/snmp.yml +++ b/files/image_config/snmp/snmp.yml @@ -1,5 +1,2 @@ snmp_rocommunity: public snmp_location: public -v1_trap_dest: NotConfigured -v2_trap_dest: NotConfigured -v3_trap_dest: NotConfigured From 9cf5730b93af3f4445e387c6bcd2e11f05264002 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Tue, 28 Jan 2020 21:53:07 -0800 Subject: [PATCH 0330/1427] [swss] update swss pointer (#4077) 4628a5a [vs tests] Refactor fdb_update tests to be consistent with vs test suite (#1185) 9594de0 Enable MIRRORv6 for BFN platform (#1177) a35afac [portsorch] use ingress/egress disable for LAG member enable/disable (#1166) faab3e1 remove the obsoleted platforms build links (#1169) 97abec5 [restore_neighbors.py] build arp packet with correct hwsrc and psrc (#1158) 97a22ca [vs tests] Mark VLAN and warm reboot tests as xfail (#1183) b453797 [Teamdmgrd]Fix "teamd cannot start when port channel was down before warm reboot" issue (#1171) 3732e74 [cfgmgr] clear loopback and vrf in kernel if not warmstart (#1141) 51315c1 [debugcounterorch] Add checks for supported counter types and drop reasons (#1173) 10f091d [vs tests] Disable NAT tests to unblock Jenkins (#1179) 698ca2a [portsorch] Refactor portsorch to use FlexCounterManager to setup port and queue stats (#1170) ea8b1da Merge pull request #1125 from AkhileshSamineni/natorch_changes_in_sonic bbd77fc Merge pull request #1126 from AkhileshSamineni/natsyncd_changes_in_sonic 419d9d2 Fix bug: shellquote the inner string (#1168) d507a93 [aclorch] Validate that provided IN/OUT_PORTS are physical interfaces (#1156) f24081b [AclOrch] add validation for check CRM (#1082) 85036df Merge pull request #1059 from AkhileshSamineni/nat_changes_in_sonic 1eac91e [portsorch] process PortsOrch tables in specific order (#1108) 80e01c0 Teamd :: fix for cleaning up the teamd processes correctly on teamd docker stop (#1159) 77fa5a4 Move away sairedis logrotate from signal handler (#1153) 5ad47af Merge branch 'master' into natorch_changes_in_sonic 982abd6 Fixed compilation issue after forced push. 286ca21 Fixed compilation issue. 3350b85 Added pytest testcases for NAT. 63ebb3a Added platform changes to avoid nexthop traching in OA. f9a8302 Addressed review comments. 946e53d Fixed compilation issue. 3d2b900 Addressed review comments and added 'nat miss' traps in copp json. ff2c78c Added changes to verify the NAT is supported before setting nat zone. 346f59a Addressed review comments. 8246acb Removed debug framework change to avoid compilation error f59ec87 Fixed compilation issue. e8b9dab Added aclorch changes for "do_not_nat" action. 88fe411 Orchagent changes in sonic-swss submodule to support NAT feature. 3ca530c Addressed review comments e4b7724 Addressed Review comments 72750ac Natsyncd changes in sonic-swss submodule to support NAT feature. 2086ad2 Fixed compilation issue after forced push. 3fcfea3 Fix in cleanup. 4028803 Added missed check ed405bf Addressed review comments ae6eb80 Compilation fix to pick proper ACL Table name - CFG_ACL_TABLE_TABLE_NAME d750132 Fix for string compilation issue 904e80b Corrected Makefile.am change. 5b09c41 Removed pytest related files and added those to PR #1125 fd733b8 Removed the Orchagent and Natsyncd related files as those are covered as part of PRs #1125 and #1126 b53c888 Loopback related changes for NAT. 29bb539 Added neighsync changes to support warm reboot for NAT. 4e0d0a1 Changes in sonic-swss submodule to support NAT feature. Signed-off-by: Stepan Blyschak --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 9f6efa088d86..4628a5a211b8 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 9f6efa088d8645572b82af590f20e8d60e9be285 +Subproject commit 4628a5a211b809deca3f76352dc0497396cb63a0 From 20d8b563b32ad30c9535e6b46554ae505a590f13 Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Wed, 29 Jan 2020 07:53:46 +0200 Subject: [PATCH 0331/1427] [Mellanox] Update SAI/SDK/FW versions (#4028) * SAI implementation 1.15.5 (headers 1.5.1) * SDK 4.3.2908 * FW xx.2000.2720 Signed-off-by: Volodymyr Samotiy --- platform/mellanox/fw.mk | 4 ++-- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 4f6e7199eac8..c088fe274b06 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,12 +11,12 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.2714 +MLNX_SPC_FW_VERSION = 13.2000.2720 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.2714 +MLNX_SPC2_FW_VERSION = 29.2000.2720 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 39942111f26a..baced2780637 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.15.2-master +MLNX_SAI_VERSION = SAIRel1.15.5-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index d878245e364c..4b40b5191b07 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit d878245e364ce8d5edd08bbd7120c44c92362235 +Subproject commit 4b40b5191b07118326a29be2d491f4362fc02eee diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index b85c06417b2d..026b12e2bd02 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit b85c06417b2df7e18990d0143a30ab1c46e34225 +Subproject commit 026b12e2bd02b79fdf50eb5f45a161c95ec94837 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 55a5b08bba31..f105f6b22f7b 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.3.2904 +MLNX_SDK_VERSION = 4.3.2908 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 33e918f7ff507a762eca13d51af638adab2e9ff3 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 29 Jan 2020 13:55:50 +0800 Subject: [PATCH 0332/1427] [Mellanox] platform api support firmware install (#3931) support firmware install, including CPLD and BIOS. CPLD: cpldupdate BIOS: boot to onie and update BIOS in onie and then boot to SONiC --- .../build_templates/sonic_debian_extension.j2 | 1 + .../sonic_platform/chassis.py | 16 ++ .../sonic_platform/component.py | 220 ++++++++++++++++-- platform/mellanox/one-image.mk | 2 +- platform/mellanox/onie-fw-update | 120 ++++++++++ platform/mellanox/onie-fw-update.mk | 7 + platform/mellanox/rules.mk | 1 + 7 files changed, 351 insertions(+), 16 deletions(-) create mode 100755 platform/mellanox/onie-fw-update create mode 100644 platform/mellanox/onie-fw-update.mk diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 208d45203037..b98c9c30396b 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -453,6 +453,7 @@ sudo cp $files_path/$MLNX_SPC_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC.mfa sudo cp $files_path/$MLNX_SPC2_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC2.mfa sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh +sudo cp $files_path/$ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/onie-fw-update.sh j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index d34245390c59..1f9af04319a1 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -11,6 +11,7 @@ try: from sonic_platform_base.chassis_base import ChassisBase from sonic_platform_base.component_base import ComponentBase + from sonic_device_util import get_machine_info from sonic_daemon_base.daemon_base import Logger from os import listdir from os.path import isfile, join @@ -59,6 +60,11 @@ def __init__(self): # Initialize SKU name self.sku_name = self._get_sku_name() + mi = get_machine_info() + if mi is not None: + self.name = mi['onie_platform'] + else: + self.name = self.sku_name # move the initialization of each components to their dedicated initializer # which will be called from platform @@ -151,6 +157,16 @@ def initialize_components(self): self._component_list.append(ComponentCPLD()) + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.name + + ############################################## # SFP methods ############################################## diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index fd593f7bbe45..dc09ae4011fa 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -5,13 +5,16 @@ # # implementation of new platform api ############################################################################# - +from __future__ import print_function try: from sonic_platform_base.component_base import ComponentBase + from sonic_device_util import get_machine_info from glob import glob import subprocess import io + import os import re + import sys except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -19,11 +22,12 @@ COMPONENT_BIOS = "BIOS" COMPONENT_CPLD = "CPLD" -BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' -CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' -CPLD_VERSION_MAX_LENGTH = 4 - class Component(ComponentBase): + def __init__(self): + self.name = None + self.image_ext_name = None + + def get_name(self): """ Retrieves the name of the component @@ -51,8 +55,10 @@ def _get_command_result(self, cmdline): try: proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] - proc.wait() + rc = proc.wait() result = stdout.rstrip('\n') + if rc != 0: + raise RuntimeError("Failed to execute command {}, return code {}, message {}".format(cmdline, rc, stdout)) except OSError as e: raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) @@ -60,12 +66,45 @@ def _get_command_result(self, cmdline): return result + def _check_file_validity(self, image_path): + # check whether the image file exists + if not os.path.isfile(image_path): + print("ERROR: File {} doesn't exist or is not a file".format(image_path)) + return False + + if self.image_ext_name is not None: + name_list = os.path.splitext(image_path) + if name_list[1] != self.image_ext_name: + print("ERROR: Extend name of file {} is wrong. Image for {} should have extend name {}".format(image_path, self.name, self.image_ext_name)) + return False + + return True + + + class ComponentBIOS(Component): + # To update BIOS requires the ONIE with version 5.2.0016 or upper + ONIE_VERSION_PARSE_PATTERN = '[0-9]{4}\.[0-9]{2}-([0-9]+)\.([0-9]+)\.([0-9]+)' + ONIE_VERSION_MAJOR_OFFSET = 1 + ONIE_VERSION_MINOR_OFFSET = 2 + ONIE_VERSION_RELEASE_OFFSET = 3 + ONIE_REQUIRED_MAJOR = "5" + ONIE_REQUIRED_MINOR = "2" + ONIE_REQUIRED_RELEASE = "0016" + BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' + BIOS_PENDING_UPDATE_PATTERN = '([0-9A-Za-z_]*.rom)[\s]*\|[\s]*bios_update' + ONIE_FW_UPDATE_CMD_ADD = "/usr/bin/onie-fw-update.sh add {}" + ONIE_FW_UPDATE_CMD_REMOVE = "/usr/bin/onie-fw-update.sh remove {}" + ONIE_FW_UPDATE_CMD_UPDATE = "/usr/bin/onie-fw-update.sh update" + ONIE_FW_UPDATE_CMD_SHOW = "/usr/bin/onie-fw-update.sh show-pending" + + BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' def __init__(self): self.name = COMPONENT_BIOS + self.image_ext_name = ".rom" def get_description(self): @@ -99,20 +138,95 @@ def get_firmware_version(self): By using regular expression 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' we can extrace the version string which is marked with * in the above context """ - bios_ver_str = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) try: + bios_ver_str = self._get_command_result(self.BIOS_QUERY_VERSION_COMMAND) m = re.search(self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str) result = m.group(1) - except AttributeError as e: - raise RuntimeError("Failed to parse BIOS version by {} from {} due to {}".format( - self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str, repr(e))) + except (AttributeError, RuntimeError) as e: + raise RuntimeError("Failed to parse BIOS version due to {}".format(repr(e))) return result + def _check_onie_version(self): + # check ONIE version. To update ONIE requires version 5.2.0016 or later. + try: + machine_info = get_machine_info() + onie_version_string = machine_info['onie_version'] + m = re.search(self.ONIE_VERSION_PARSE_PATTERN, onie_version_string) + onie_major = m.group(self.ONIE_VERSION_MAJOR_OFFSET) + onie_minor = m.group(self.ONIE_VERSION_MINOR_OFFSET) + onie_release = m.group(self.ONIE_VERSION_RELEASE_OFFSET) + except AttributeError as e: + print("ERROR: Failed to parse ONIE version by {} from {} due to {}".format( + self.ONIE_VERSION_PARSE_PATTERN, machine_conf, repr(e))) + return False + + if onie_major < self.ONIE_REQUIRED_MAJOR or onie_minor < self.ONIE_REQUIRED_MINOR or onie_release < self.ONIE_REQUIRED_RELEASE: + print("ERROR: ONIE {}.{}.{} or later is required".format(self.ONIE_REQUIRED_MAJOR, self.ONIE_REQUIRED_MINOR, self.ONIE_REQUIRED_RELEASE)) + return False + + return True + + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + # check ONIE version requirement + if not self._check_onie_version(): + return False + + # check whether the file exists + if not self._check_file_validity(image_path): + return False + + # do the real work + try: + # check whether there has already been some images pending + # if yes, remove them + result = self._get_command_result(self.ONIE_FW_UPDATE_CMD_SHOW) + pending_list = result.split("\n") + for pending in pending_list: + m = re.match(self.BIOS_PENDING_UPDATE_PATTERN, pending) + if m is not None: + pending_image = m.group(1) + self._get_command_result(self.ONIE_FW_UPDATE_CMD_REMOVE.format(pending_image)) + print("WARNING: Image {} which is already pending to upgrade has been removed".format(pending_image)) + + result = subprocess.check_call(self.ONIE_FW_UPDATE_CMD_ADD.format(image_path).split()) + if result: + return False + result = subprocess.check_call(self.ONIE_FW_UPDATE_CMD_UPDATE.split()) + if result: + return False + except Exception as e: + print("ERROR: Installing BIOS failed due to {}".format(repr(e))) + return False + + print("INFO: Reboot is required to finish BIOS installation.") + return True + + + class ComponentCPLD(Component): + CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' + CPLD_VERSION_MAX_LENGTH = 4 + + CPLD_UPDATE_COMMAND = "cpldupdate --dev {} {}" + CPLD_INSTALL_SUCCESS_FLAG = "PASS!" + + MST_DEVICE_PATTERN = "/dev/mst/mt[0-9]*_pciconf0" + def __init__(self): self.name = COMPONENT_CPLD + self.image_ext_name = ".vme" def get_description(self): @@ -132,17 +246,93 @@ def get_firmware_version(self): Returns: A string containing the firmware version of the component """ - cpld_version_file_list = glob(CPLD_VERSION_FILE_PATTERN) + cpld_version_file_list = glob(self.CPLD_VERSION_FILE_PATTERN) cpld_version = '' - if cpld_version_file_list is not None and cpld_version_file_list: + if cpld_version_file_list: cpld_version_file_list.sort() for version_file in cpld_version_file_list: - version = self._read_generic_file(version_file, CPLD_VERSION_MAX_LENGTH) - if not cpld_version == '': + version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH) + if cpld_version: cpld_version += '.' cpld_version += version.rstrip('\n') else: - raise RuntimeError("Failed to get CPLD version files by matching {}".format(CPLD_VERSION_FILE_PATTERN)) + raise RuntimeError("Failed to get CPLD version files by matching {}".format(self.CPLD_VERSION_FILE_PATTERN)) return cpld_version + + def _get_mst_device(self): + mst_dev_list = glob(self.MST_DEVICE_PATTERN) + if mst_dev_list is None or len(mst_dev_list) != 1: + return None + return mst_dev_list + + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + + Details: + The command "cpldupdate" is provided to install CPLD. There are two ways to do it: + 1. To burn CPLD via gpio, which is faster but only supported on new systems, like Anaconda, ... + 2. To install CPLD via firmware, which is slower but supported on older systems. + This also requires the mst device designated. + "cpldupdate --dev " has the logic of testing whether to update via gpio is supported, + and if so then go this way, otherwise tries updating software via fw. So we take advantage of it to update the CPLD. + By doing so we don't have to mind whether to update via gpio supported, which belongs to hardware details. + + So the procedure should be: + 1. Test whether the file exists + 2. Fetch the mst device name + 3. Update CPLD via executing "cpldupdate --dev " + 4. Check the result + """ + # check whether the image file exists + if not self._check_file_validity(image_path): + return False + + mst_dev_list = self._get_mst_device() + if mst_dev_list is None: + print("ERROR: Failed to get mst device which is required for CPLD updating or multiple device files matched") + return False + + cmdline = self.CPLD_UPDATE_COMMAND.format(mst_dev_list[0], image_path) + outputline = "" + success_flag = False + try: + proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) + while True: + out = proc.stdout.read(1) + + if out == '' and proc.poll() != None: + break + + if out != '': + sys.stdout.write(out) + sys.stdout.flush() + outputline += out + + if (out == '\n' or out == '\r') and len(outputline): + m = re.search(self.CPLD_INSTALL_SUCCESS_FLAG, outputline) + if m and m.group(0) == self.CPLD_INSTALL_SUCCESS_FLAG: + success_flag = True + + if proc.returncode: + print("ERROR: Upgrade CPLD failed, return code {}".format(proc.returncode)) + success_flag = False + + except OSError as e: + raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + + if success_flag: + print("INFO: Success. Refresh or power cycle is required to finish CPLD installation.") + else: + print("ERROR: Failed to install CPLD") + + return success_flag diff --git a/platform/mellanox/one-image.mk b/platform/mellanox/one-image.mk index 2946ae53f47b..d30e44690991 100644 --- a/platform/mellanox/one-image.mk +++ b/platform/mellanox/one-image.mk @@ -11,5 +11,5 @@ $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.g else $(SONIC_ONE_IMAGE)_DOCKERS = $(SONIC_INSTALL_DOCKER_IMAGES) endif -$(SONIC_ONE_IMAGE)_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_FFB_SCRIPT) $(ISSU_VERSION_FILE) +$(SONIC_ONE_IMAGE)_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_FFB_SCRIPT) $(ISSU_VERSION_FILE) $(ONIE_FW_UPDATE) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/mellanox/onie-fw-update b/platform/mellanox/onie-fw-update new file mode 100755 index 000000000000..314f4ed70268 --- /dev/null +++ b/platform/mellanox/onie-fw-update @@ -0,0 +1,120 @@ +#!/bin/sh + +# Copyright (C) 2019 Mellanox Technologies Ltd. +# Copyright (C) 2019 Michael Shych +# +# SPDX-License-Identifier: GPL-2.0 + +this_script=${ONIE_FWPKG_PROGRAM_NAME:-$(basename $(realpath $0))} + +onie_mount=/mnt/onie-boot +os_boot=/host +onie_partition= + +export ONIE_FWPKG_PROGRAM_NAME=$(basename $(realpath $0)) + +usage() +{ +cat < before update." + clean_onie_access + exit 1 + fi + ;; + purge | show | show-results | show-log | show-pending | help) + ;; + *) + echo "Unknown command: $cmd" + exit 1 + ;; +esac + +enable_onie_access +$onie_mount/onie/tools/bin/onie-fwpkg "$@" +rc=$? +if [ $cmd = "help" ]; then + usage +fi +clean_onie_access + +exit $rc diff --git a/platform/mellanox/onie-fw-update.mk b/platform/mellanox/onie-fw-update.mk new file mode 100644 index 000000000000..160f1c98f7b1 --- /dev/null +++ b/platform/mellanox/onie-fw-update.mk @@ -0,0 +1,7 @@ +# bios update tool + +ONIE_FW_UPDATE= onie-fw-update +$(ONIE_FW_UPDATE)_PATH = platform/mellanox/ +SONIC_COPY_FILES += $(ONIE_FW_UPDATE) + +export ONIE_FW_UPDATE diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index dd10cefda571..efd0af2c8f4a 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -12,6 +12,7 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-mlnx.mk include $(PLATFORM_PATH)/mlnx-ffb.mk include $(PLATFORM_PATH)/issu-version.mk +include $(PLATFORM_PATH)/onie-fw-update.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) From c095e515b4ba31657285793a6cebc6af80175ae8 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Wed, 29 Jan 2020 11:36:04 +0530 Subject: [PATCH 0333/1427] DellEMC: Z9264-Platform2.0 Implementation [ipmihelper] (#4060) Implement classes IpmiSensor, IpmiFru to obtain platform sensors information for Platform2.0 APIs in DellEMC Z9264 platform. Add a new file ipmihelper.py with the implementation for IpmiSensor, IpmiFru classes. --- .../common/ipmihelper.py | 259 ++++++++++++++++++ .../sonic-platform-modules-dell/debian/rules | 2 + 2 files changed, 261 insertions(+) create mode 100644 platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py diff --git a/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py b/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py new file mode 100644 index 000000000000..182d74c218cf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py @@ -0,0 +1,259 @@ +#! /usr/bin/python + +######################################################################## +# DellEMC +# +# Module contains implementation of IpmiSensor and IpmiFru classes that +# provide Sensor's and FRU's information respectively. +# +######################################################################## + +import subprocess +import re + +# IPMI Request Network Function Codes +NetFn_SensorEvent = 0x04 +NetFn_Storage = 0x0A + +# IPMI Sensor Device Commands +Cmd_GetSensorReadingFactors = 0x23 +Cmd_GetSensorThreshold = 0x27 +Cmd_GetSensorReading = 0x2D + +# IPMI FRU Device Commands +Cmd_ReadFRUData = 0x11 + +class IpmiSensor(object): + + # Sensor Threshold types and their respective bit masks + THRESHOLD_BIT_MASK = { + "LowerNonCritical" : 0, + "LowerCritical" : 1, + "LowerNonRecoverable" : 2, + "UpperNonCritical" : 3, + "UpperCritical" : 4, + "UpperNonRecoverable" : 5 + } + + def __init__(self, sensor_id, is_discrete=False): + self.id = sensor_id + self.is_discrete = is_discrete + + def _get_ipmitool_raw_output(self, args): + """ + Returns a list the elements of which are the individual bytes of + ipmitool raw command output. + """ + result_bytes = list() + result = "" + command = "ipmitool raw {}".format(args) + try: + proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + if not proc.returncode: + result = stdout.rstrip('\n') + except: + pass + + for i in result.split(): + result_bytes.append(int(i, 16)) + + return result_bytes + + def _get_converted_sensor_reading(self, raw_value): + """ + Returns a 2 element tuple(bool, int) in which first element + provides the validity of the reading and the second element is + the converted sensor reading + """ + # Get Sensor Reading Factors + cmd_args = "{} {} {} {}".format(NetFn_SensorEvent, + Cmd_GetSensorReadingFactors, + self.id, raw_value) + factors = self._get_ipmitool_raw_output(cmd_args) + + if len(factors) != 7: + return False, 0 + + # Compute Twos complement + def get_twos_complement(val, bits): + if val & (1 << (bits - 1)): + val = val - (1 << bits) + return val + + # Calculate actual sensor value from the raw sensor value + # using the sensor reading factors. + M = get_twos_complement(((factors[2] & 0xC0) << 8) | factors[1], 10) + B = get_twos_complement(((factors[4] & 0xC0) << 8) | factors[3], 10) + R_exp = get_twos_complement((factors[6] & 0xF0) >> 4, 4) + B_exp = get_twos_complement(factors[6] & 0x0F, 4) + + converted_reading = ((M * raw_value) + (B * 10**B_exp)) * 10**R_exp + + return True, converted_reading + + def get_reading(self): + """ + For Threshold sensors, returns the sensor reading. + For Discrete sensors, returns the state value. + + Returns: + A tuple (bool, int) where the first element provides the + validity of the reading and the second element provides the + sensor reading/state value. + """ + # Get Sensor Reading + cmd_args = "{} {} {}".format(NetFn_SensorEvent, Cmd_GetSensorReading, + self.id) + output = self._get_ipmitool_raw_output(cmd_args) + if len(output) != 4: + return False, 0 + + # Check reading/state unavailable + if output[1] & 0x20: + return False, 0 + + if self.is_discrete: + state = ((output[3] & 0x7F) << 8) | output[2] + return True, state + else: + return self._get_converted_sensor_reading(output[0]) + + def get_threshold(self, threshold_type): + """ + Returns the sensor's threshold value for a given threshold type. + + Args: + threshold_type (str) - one of the below mentioned + threshold type strings + + "LowerNonCritical" + "LowerCritical" + "LowerNonRecoverable" + "UpperNonCritical" + "UpperCritical" + "UpperNonRecoverable" + Returns: + A tuple (bool, int) where the first element provides the + validity of that threshold and second element provides the + threshold value. + """ + # Thresholds are not valid for discrete sensors + if self.is_discrete: + raise TypeError("Threshold is not applicable for Discrete Sensor") + + if threshold_type not in self.THRESHOLD_BIT_MASK.keys(): + raise ValueError("Invalid threshold type {} provided. Valid types " + "are {}".format(threshold_type, + self.THRESHOLD_BIT_MASK.keys())) + + bit_mask = self.THRESHOLD_BIT_MASK[threshold_type] + + # Get Sensor Threshold + cmd_args = "{} {} {}".format(NetFn_SensorEvent, Cmd_GetSensorThreshold, + self.id) + thresholds = self._get_ipmitool_raw_output(cmd_args) + if len(thresholds) != 7: + return False, 0 + + valid_thresholds = thresholds.pop(0) + # Check whether particular threshold is readable + if valid_thresholds & (1 << bit_mask): + return self._get_converted_sensor_reading(thresholds[bit_mask]) + else: + return False, 0 + +class IpmiFru(object): + + def __init__(self, fru_id): + self.id = fru_id + + def _get_ipmitool_fru_print(self): + result = "" + command = "ipmitool fru print {}".format(self.id) + try: + proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + if not proc.returncode: + result = stdout.rstrip('\n') + except: + pass + + return result + + def get_board_serial(self): + """ + Returns a string containing the Serial Number of the device. + """ + fru_output = self._get_ipmitool_fru_print() + if not fru_output: + return "NA" + + board_serial = re.search(r'Board Serial\s*:(.*)', fru_output) + if not board_serial: + return "NA" + + return board_serial.group(1).strip() + + def get_board_part_number(self): + """ + Returns a string containing the Part Number of the device. + """ + fru_output = self._get_ipmitool_fru_print() + if not fru_output: + return "NA" + + board_pn = re.search(r'Board Part Number\s*:(.*)', fru_output) + if not board_pn: + return "NA" + + return board_pn.group(1).strip() + + def get_fru_data(self, offset, count=1): + """ + Reads and returns the FRU data at the provided offset. + + Args: + offset (int) - FRU offset to read + count (int) - Number of bytes to read [optional, default = 1] + Returns: + A tuple (bool, list(int)) where the first element provides + the validity of the data read and the second element is a + list, the elements of which are the individual bytes of the + FRU data read. + """ + result_bytes = list() + is_valid = True + result = "" + + offset_LSB = offset & 0xFF + offset_MSB = offset & 0xFF00 + command = "ipmitool raw {} {} {} {} {} {}".format(NetFn_Storage, + Cmd_ReadFRUData, + self.id, offset_LSB, + offset_MSB, count) + try: + proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + if not proc.returncode: + result = stdout.rstrip('\n') + except: + is_valid = False + + if (not result) or (not is_valid): + return False, result_bytes + + for i in result.split(): + result_bytes.append(int(i, 16)) + + read_count = result_bytes.pop(0) + if read_count != count: + return False, result_bytes + else: + return True, result_bytes diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index d73f63209e4b..d3ba62afa4a0 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -30,6 +30,7 @@ override_dh_auto_build: python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ elif [ $$mod = "z9264f" ]; then \ + cp $(COMMON_DIR)/ipmihelper.py $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ @@ -72,6 +73,7 @@ override_dh_clean: rm -rf $(MOD_SRC_DIR)/$${mod}/build; \ rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ elif [ $$mod = "z9264f" ]; then \ + rm -f $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ rm -rf $(MOD_SRC_DIR)/$${mod}/build; \ rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ From 1a7d8226383867ec2bdf396b3f6cb3658a3695cd Mon Sep 17 00:00:00 2001 From: B S Rama krishna <54837361+banagiri@users.noreply.github.com> Date: Wed, 29 Jan 2020 11:42:52 +0530 Subject: [PATCH 0334/1427] [kdump]: kdump support for arm, as the dependency with uboot, working on that. (#3962) as the current kdump installation is searching for grub path, and ARM arch (marvell-armhf) are dependent on uboot, these changes has to be addressed. For now skipping kdump installation on ARM Co-authored-by: lguohan --- files/build_templates/sonic_debian_extension.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index b98c9c30396b..bba8a0f5bede 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -169,8 +169,10 @@ sudo LANG=C chroot $FILESYSTEM_ROOT pam-auth-update --remove tacplus sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf # Install a custom version of kdump-tools (and its dependencies via 'apt-get -y install -f') +if [[ $CONFIGURED_ARCH == amd64 ]]; then sudo DEBIAN_FRONTEND=noninteractive dpkg --root=$FILESYSTEM_ROOT -i $debs_path/kdump-tools_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true chroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install +fi # Install custom-built monit package and SONiC configuration files sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/monit_*.deb || \ From 5383e2c765ea24bece651ce39ee75d040c954d14 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Wed, 29 Jan 2020 10:25:06 +0100 Subject: [PATCH 0335/1427] [sairedis] Advance pointer to fix rpc thrift (#4079) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 567191f [sairedis] Add knob to disable recording statistics API calls (#547) 8513506 Create Switch and SwitchContainer classes (#549) … e991281 Update .gitignore (#551) 84b0eed [sairedis] Skip recording GET operations on AVAILABLE attributes (#550) … 634e4e3 [meta] Return OBJECT_IN_USE when removing port is in use (#553) 2961bd3 [syncd] Fix rpc server flag condition (#557) --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index e75a4d64792c..2961bd329636 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit e75a4d64792c6834bd2a00628ce11ad29a65be7b +Subproject commit 2961bd3296365c89a27820207c73a94cf060a41a From 97165a0d6921bcbb29db5b24d1472a509348fc85 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Kella <45939429+kirankella@users.noreply.github.com> Date: Thu, 30 Jan 2020 07:10:43 +0530 Subject: [PATCH 0336/1427] Changes in sonic-buildimage to support the NAT feature (#3494) * Changes in sonic-buildimage for the NAT feature - Docker for NAT - installing the required tools iptables and conntrack for nat Signed-off-by: kiran.kella@broadcom.com * Add redis-tools dependencies in the docker nat compilation * Addressed review comments * add natsyncd to warm-boot finalizer list * addressed review comments * using swsscommon.DBConnector instead of swsssdk.SonicV2Connector * Enable NAT application in docker-sonic-vs --- build_debian.sh | 3 +- dockers/docker-nat/Dockerfile.j2 | 46 +++ dockers/docker-nat/base_image_files/natctl | 5 + dockers/docker-nat/restore_nat_entries.py | 104 +++++++ dockers/docker-nat/start.sh | 15 + dockers/docker-nat/supervisord.conf | 47 +++ dockers/docker-orchagent/Dockerfile.j2 | 3 +- files/build_templates/nat.service.j2 | 15 + .../build_templates/sonic_debian_extension.j2 | 4 + .../warmboot-finalizer/finalize-warmboot.sh | 2 +- platform/vs/docker-sonic-vs/start.sh | 4 + platform/vs/docker-sonic-vs/supervisord.conf | 16 ++ rules/docker-nat.mk | 30 ++ rules/iptables.mk | 27 ++ sonic-slave-stretch/Dockerfile.j2 | 3 + src/iptables/Makefile | 47 +++ ...ng-fullcone-option-for-SNAT-and-DNAT.patch | 267 ++++++++++++++++++ src/iptables/patch/series | 1 + 18 files changed, 636 insertions(+), 3 deletions(-) create mode 100644 dockers/docker-nat/Dockerfile.j2 create mode 100644 dockers/docker-nat/base_image_files/natctl create mode 100755 dockers/docker-nat/restore_nat_entries.py create mode 100755 dockers/docker-nat/start.sh create mode 100644 dockers/docker-nat/supervisord.conf create mode 100644 files/build_templates/nat.service.j2 create mode 100644 rules/docker-nat.mk create mode 100644 rules/iptables.mk create mode 100644 src/iptables/Makefile create mode 100644 src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch create mode 100644 src/iptables/patch/series diff --git a/build_debian.sh b/build_debian.sh index 8bbbd0868e74..34065bbceef1 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -277,7 +277,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in cgroup-tools \ ipmitool \ ndisc6 \ - makedumpfile + makedumpfile \ + conntrack if [[ $CONFIGURED_ARCH == amd64 ]]; then diff --git a/dockers/docker-nat/Dockerfile.j2 b/dockers/docker-nat/Dockerfile.j2 new file mode 100644 index 000000000000..3cfbd99e95e1 --- /dev/null +++ b/dockers/docker-nat/Dockerfile.j2 @@ -0,0 +1,46 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, copy_files %} +FROM docker-config-engine-stretch + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +RUN echo + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +## Install redis-tools dependencies +## TODO: implicitly install dependencies +RUN apt-get update \ +&& apt-get install -f -y \ + libdbus-1-3 \ + libdaemon0 \ + libjansson4 \ + libpython2.7 \ + libatomic1 \ + libjemalloc1 \ + liblua5.1-0 \ + lua-bitop \ + lua-cjson \ + libelf1 \ + libmnl0 \ + bridge-utils \ + conntrack + +{% if docker_nat_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{copy_files ("debs/", docker_nat_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_nat_debs.split(' ')) }} +{%- endif %} + +COPY ["start.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["restore_nat_entries.py", "/usr/bin/"] + +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /debs + +ENTRYPOINT ["/usr/bin/supervisord"] + diff --git a/dockers/docker-nat/base_image_files/natctl b/dockers/docker-nat/base_image_files/natctl new file mode 100644 index 000000000000..6cba3c86be70 --- /dev/null +++ b/dockers/docker-nat/base_image_files/natctl @@ -0,0 +1,5 @@ +#!/bin/bash + +# -t option needed only for shell, not for commands + +docker exec -i nat natctl "$@" diff --git a/dockers/docker-nat/restore_nat_entries.py b/dockers/docker-nat/restore_nat_entries.py new file mode 100755 index 000000000000..9fb62e82f573 --- /dev/null +++ b/dockers/docker-nat/restore_nat_entries.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python + +"""" +Description: restore_nat_entries.py -- restoring nat entries table into kernel during system warm reboot. + The script is started by supervisord in nat docker when the docker is started. + It does not do anything in case neither system nor nat warm restart is enabled. + In case nat warm restart enabled only, it sets the stateDB flag so natsyncd can continue + the reconciation process. + In case system warm reboot is enabled, it will try to restore the nat entries table into kernel + , then it sets the stateDB flag for natsyncd to continue the + reconciliation process. +""" + +import sys +import subprocess +from swsscommon import swsscommon +import logging +import logging.handlers +import re +import os + +WARM_BOOT_FILE_DIR = '/var/warmboot/nat/' +NAT_WARM_BOOT_FILE = 'nat_entries.dump' +IP_PROTO_TCP = '6' + +MATCH_CONNTRACK_ENTRY = '^(\w+)\s+(\d+).*src=([\d.]+)\s+dst=([\d.]+)\s+sport=(\d+)\s+dport=(\d+).*src=([\d.]+)\s+dst=([\d.]+)\s+sport=(\d+)\s+dport=(\d+)' +REDIS_SOCK = "/var/run/redis/redis.sock" + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) +handler = logging.handlers.SysLogHandler(address = '/dev/log') +logger.addHandler(handler) + +def add_nat_conntrack_entry_in_kernel(ipproto, srcip, dstip, srcport, dstport, natsrcip, natdstip, natsrcport, natdstport): + # pyroute2 doesn't have support for adding conntrack entries via netlink yet. So, invoking the conntrack utility to add the entries. + state = '' + if (ipproto == IP_PROTO_TCP): + state = ' --state ESTABLISHED ' + ctcmd = 'conntrack -I -n ' + natdstip + ':' + natdstport + ' -g ' + natsrcip + ':' + natsrcport + \ + ' --protonum ' + ipproto + state + ' --timeout 600 --src ' + srcip + ' --sport ' + srcport + \ + ' --dst ' + dstip + ' --dport ' + dstport + ' -u ASSURED' + subprocess.call(ctcmd, shell=True) + logger.info("Restored NAT entry: {}".format(ctcmd)) + +# Set the statedb "NAT_RESTORE_TABLE|Flags", so natsyncd can start reconciliation +def set_statedb_nat_restore_done(): + statedb = swsscommon.DBConnector(swsscommon.STATE_DB, REDIS_SOCK, 0) + tbl = swsscommon.Table(statedb, "NAT_RESTORE_TABLE") + fvs = swsscommon.FieldValuePairs([("restored", "true")]) + tbl.set("Flags", fvs) + return + +# This function is to restore the kernel nat entries based on the saved nat entries. +def restore_update_kernel_nat_entries(filename): + # Read the entries from nat_entries.dump file and add them to kernel + conntrack_match_pattern = re.compile(r'{}'.format(MATCH_CONNTRACK_ENTRY)) + with open(filename, 'r') as fp: + for line in fp: + ctline = conntrack_match_pattern.findall(line) + if not ctline: + continue + cmdargs = list(ctline.pop(0)) + proto = cmdargs.pop(0) + if proto not in ('tcp', 'udp'): + continue + add_nat_conntrack_entry_in_kernel(*cmdargs) + +def main(): + logger.info("restore_nat_entries service is started") + + # Use warmstart python binding to check warmstart information + warmstart = swsscommon.WarmStart() + warmstart.initialize("natsyncd", "nat") + warmstart.checkWarmStart("natsyncd", "nat", False) + + # if swss or system warm reboot not enabled, don't run + if not warmstart.isWarmStart(): + logger.info("restore_nat_entries service is skipped as warm restart not enabled") + return + + # NAT restart not system warm reboot, set statedb directly + if not warmstart.isSystemWarmRebootEnabled(): + set_statedb_nat_restore_done() + logger.info("restore_nat_entries service is done as system warm reboot not enabled") + return + + # Program the nat conntrack entries in the kernel by reading the + # entries from nat_entries.dump + try: + restore_update_kernel_nat_entries(WARM_BOOT_FILE_DIR + NAT_WARM_BOOT_FILE) + except Exception as e: + logger.exception(str(e)) + sys.exit(1) + + # Remove the dump file after restoration + os.remove(WARM_BOOT_FILE_DIR + NAT_WARM_BOOT_FILE) + + # set statedb to signal other processes like natsyncd + set_statedb_nat_restore_done() + logger.info("restore_nat_entries service is done for system warmreboot") + return + +if __name__ == '__main__': + main() diff --git a/dockers/docker-nat/start.sh b/dockers/docker-nat/start.sh new file mode 100755 index 000000000000..e1f303fee6f2 --- /dev/null +++ b/dockers/docker-nat/start.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +rm -f /var/run/rsyslogd.pid +rm -f /var/run/nat/* + +mkdir -p /var/warmboot/nat + +supervisorctl start rsyslogd + +supervisorctl start natmgrd + +supervisorctl start natsyncd + +supervisorctl start restore_nat_entries + diff --git a/dockers/docker-nat/supervisord.conf b/dockers/docker-nat/supervisord.conf new file mode 100644 index 000000000000..bb42d23fe355 --- /dev/null +++ b/dockers/docker-nat/supervisord.conf @@ -0,0 +1,47 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:natmgrd] +command=/usr/bin/natmgrd +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:natsyncd] +command=/usr/bin/natsyncd +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:restore_nat_entries] +command=/usr/bin/restore_nat_entries.py +priority=5 +autostart=false +autorestart=false +startsecs=0 +startretries=0 +stdout_logfile=syslog +stderr_logfile=syslog + diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 8a66e2adbe43..f95acd48fdbd 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -20,7 +20,8 @@ RUN apt-get update && \ tcpdump \ libelf1 \ libmnl0 \ - bridge-utils + bridge-utils \ + conntrack {% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %} ## Fix for gcc/python not found in arm docker diff --git a/files/build_templates/nat.service.j2 b/files/build_templates/nat.service.j2 new file mode 100644 index 000000000000..2e3e17439ef7 --- /dev/null +++ b/files/build_templates/nat.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=NAT container +Requires=updategraph.service swss.service +After=updategraph.service swss.service syncd.service +Before=ntp-config.service + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop + +[Install] +WantedBy=multi-user.target swss.service + diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index bba8a0f5bede..a32120bf8dc4 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -81,6 +81,10 @@ sudo mkdir -p $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/ifupdown2_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +# Install ipables (and its dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/iptables_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f + # Install dependencies for SONiC config engine sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ python-dev \ diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index eec50ccef692..0f9e0f7da299 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -3,7 +3,7 @@ VERBOSE=no # Check components -COMP_LIST="orchagent neighsyncd bgp" +COMP_LIST="orchagent neighsyncd bgp natsyncd" EXP_STATE="reconciled" ASSISTANT_SCRIPT="/usr/bin/neighbor_advertiser" diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 614541961c87..dd9fee4deb3d 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -70,6 +70,10 @@ supervisorctl start vxlanmgrd supervisorctl start sflowmgrd +supervisorctl start natmgrd + +supervisorctl start natsyncd + # Start arp_update when VLAN exists VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` if [ "$VLAN" != "" ]; then diff --git a/platform/vs/docker-sonic-vs/supervisord.conf b/platform/vs/docker-sonic-vs/supervisord.conf index 143fe49d44a9..3a7acfd20bbe 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -188,3 +188,19 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog + +[program:natmgrd] +command=/usr/bin/natmgrd +priority=23 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:natsyncd] +command=/usr/bin/natsyncd +priority=24 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk new file mode 100644 index 000000000000..765b6f7d3b0f --- /dev/null +++ b/rules/docker-nat.mk @@ -0,0 +1,30 @@ +# docker image for nat + +DOCKER_NAT_STEM = docker-nat +DOCKER_NAT = $(DOCKER_NAT_STEM).gz +DOCKER_NAT_DBG = $(DOCKER_NAT_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_NAT)_PATH = $(DOCKERS_PATH)/$(DOCKER_NAT_STEM) + +$(DOCKER_NAT)_DEPENDS += $(SWSS) $(REDIS_TOOLS) $(IPTABLESIP4TC) $(IPTABLESIP6TC) $(IPTABLESIPTC) $(IPXTABLES12) $(IPTABLES) +$(DOCKER_NAT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_NAT)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) +$(DOCKER_NAT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) + +$(DOCKER_NAT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) + +SONIC_DOCKER_IMAGES += $(DOCKER_NAT) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_NAT) +SONIC_STRETCH_DOCKERS += $(DOCKER_NAT) + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_NAT_DBG) + +$(DOCKER_NAT)_CONTAINER_NAME = nat +$(DOCKER_NAT)_RUN_OPT += --net=host --privileged -t +$(DOCKER_NAT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_NAT)_RUN_OPT += -v /host/warmboot:/var/warmboot + +$(DOCKER_NAT)_BASE_IMAGE_FILES += natctl:/usr/bin/natctl + diff --git a/rules/iptables.mk b/rules/iptables.mk new file mode 100644 index 000000000000..4d88c0a224b2 --- /dev/null +++ b/rules/iptables.mk @@ -0,0 +1,27 @@ +# iptables package + +IPTABLES_VERSION = 1.6.0+snapshot20161117 +IPTABLES_VERSION_SUFFIX = 6 +IPTABLES_VERSION_FULL = $(IPTABLES_VERSION)-$(IPTABLES_VERSION_SUFFIX) + +IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_amd64.deb +$(IPTABLES)_SRC_PATH = $(SRC_PATH)/iptables +SONIC_MAKE_DEBS += $(IPTABLES) +SONIC_STRETCH_DEBS += $(IPTABLES) + +IPTABLESIP4TC = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP4TC))) + +IPTABLESIP6TC = libip6tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP6TC))) + +IPTABLESIPTC = libiptc0_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIPTC))) + +IPXTABLES12 = libxtables12_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPXTABLES12))) + +# Export these variables so they can be used in a sub-make +export IPTABLES_VERSION +export IPTABLES_VERSION_FULL +export IPTABLES diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 8786a9d4101f..4d34e8e81a75 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -294,6 +294,9 @@ RUN apt-get update && apt-get install -y \ libselinux1-dev \ # For kdump-tools liblzo2-dev \ +# For iptables + libnetfilter-conntrack-dev \ + libnftnl-dev \ # For SAI3.7 libprotobuf-dev \ # For DHCP Monitor tool diff --git a/src/iptables/Makefile b/src/iptables/Makefile new file mode 100644 index 000000000000..60154c19ddb1 --- /dev/null +++ b/src/iptables/Makefile @@ -0,0 +1,47 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = $(IPTABLES) +DERIVED_TARGETS = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ + libip6tc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ + libiptc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ + libxtables12_$(IPTABLES_VERSION_FULL)_amd64.deb + +IPTABLES_URL = http://deb.debian.org/debian/pool/main/i/iptables + +DSC_FILE = iptables_$(IPTABLES_VERSION_FULL).dsc +ORIG_FILE = iptables_$(IPTABLES_VERSION).orig.tar.bz2 +DEBIAN_FILE = iptables_$(IPTABLES_VERSION_FULL).debian.tar.xz + +DSC_FILE_URL = $(IPTABLES_URL)/$(DSC_FILE) +ORIG_FILE_URL = $(IPTABLES_URL)/$(ORIG_FILE) +DEBIAN_FILE_URL = $(IPTABLES_URL)/$(DEBIAN_FILE) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Remove any stale files + rm -rf ./iptables-$(IPTABLES_VERSION) + + # Get iptables release + wget -NO "$(DSC_FILE)" $(DSC_FILE_URL) + wget -NO "$(ORIG_FILE)" $(ORIG_FILE_URL) + wget -NO "$(DEBIAN_FILE)" $(DEBIAN_FILE_URL) + dpkg-source -x iptables_$(IPTABLES_VERSION_FULL).dsc + + pushd iptables-$(IPTABLES_VERSION) + git init + git add -f * + git commit -m "unmodified iptables source" + + # Apply patches + stg init + stg import -s ../patch/series + + # Build source and Debian packages + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + # Move the newly-built .deb packages to the destination directory + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch new file mode 100644 index 000000000000..f7fba85a270b --- /dev/null +++ b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch @@ -0,0 +1,267 @@ +From 92f5aee7372748845f11b7a10d880f968769e860 Mon Sep 17 00:00:00 2001 +From: Kiran Kella +Date: Wed, 7 Aug 2019 07:22:42 -0700 +Subject: [PATCH] Passing fullcone option for SNAT and DNAT + +--- + extensions/libipt_DNAT.c | 22 +++++++++++++++++++++- + extensions/libipt_MASQUERADE.c | 21 ++++++++++++++++++++- + extensions/libipt_SNAT.c | 22 +++++++++++++++++++++- + 3 files changed, 62 insertions(+), 3 deletions(-) + +diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c +index a14d16f..4bfab98 100644 +--- a/extensions/libipt_DNAT.c ++++ b/extensions/libipt_DNAT.c +@@ -8,14 +8,20 @@ + #include + #include + ++/* Temporarily defining here, need to be picked up from the ++ * new kernel header linux/netfilter/nf_nat.h */ ++#define NF_NAT_RANGE_FULLCONE (1 << 5) ++ + enum { + O_TO_DEST = 0, + O_RANDOM, + O_PERSISTENT, + O_X_TO_DEST, /* hidden flag */ ++ O_FULLCONE, + F_TO_DEST = 1 << O_TO_DEST, + F_RANDOM = 1 << O_RANDOM, + F_X_TO_DEST = 1 << O_X_TO_DEST, ++ F_FULLCONE = 1 << O_FULLCONE + }; + + /* Dest NAT data consists of a multi-range, indicating where to map +@@ -32,7 +38,7 @@ static void DNAT_help(void) + "DNAT target options:\n" + " --to-destination [[-]][:port[-port]]\n" + " Address to map destination to.\n" +-"[--random] [--persistent]\n"); ++"[--random] [--persistent] [--fullcone]\n"); + } + + static const struct xt_option_entry DNAT_opts[] = { +@@ -40,6 +46,7 @@ static const struct xt_option_entry DNAT_opts[] = { + .flags = XTOPT_MAND | XTOPT_MULTI}, + {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, + {.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE}, ++ {.name = "fullcone", .id = O_FULLCONE, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, + }; + +@@ -185,10 +192,14 @@ static void DNAT_parse(struct xt_option_call *cb) + static void DNAT_fcheck(struct xt_fcheck_call *cb) + { + static const unsigned int f = F_TO_DEST | F_RANDOM; ++ static const unsigned int c = F_FULLCONE; + struct nf_nat_ipv4_multi_range_compat *mr = cb->data; + + if ((cb->xflags & f) == f) + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM; ++ ++ if ((cb->xflags & c) == c) ++ mr->range[0].flags |= NF_NAT_RANGE_FULLCONE; + } + + static void print_range(const struct nf_nat_ipv4_range *r) +@@ -224,6 +235,8 @@ static void DNAT_print(const void *ip, const struct xt_entry_target *target, + printf(" random"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" fullcone"); + } + } + +@@ -239,6 +252,8 @@ static void DNAT_save(const void *ip, const struct xt_entry_target *target) + printf(" --random"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" --persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" --fullcone"); + } + } + +@@ -282,6 +297,11 @@ static int DNAT_xlate(struct xt_xlate *xl, + sep = ","; + xt_xlate_add(xl, "%spersistent", sep); + } ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) { ++ if (sep_need) ++ sep = ","; ++ xt_xlate_add(xl, "%sfullcone", sep); ++ } + } + + return 1; +diff --git a/extensions/libipt_MASQUERADE.c b/extensions/libipt_MASQUERADE.c +index b7b5fc7..88ff650 100644 +--- a/extensions/libipt_MASQUERADE.c ++++ b/extensions/libipt_MASQUERADE.c +@@ -8,9 +8,15 @@ + #include + #include + ++/* Temporarily defining here, need to be picked up from the ++ * new kernel header linux/netfilter/nf_nat.h */ ++#define NF_NAT_RANGE_FULLCONE (1 << 5) ++ + enum { + O_TO_PORTS = 0, + O_RANDOM, ++ O_RANDOM_FULLY, ++ O_FULLCONE + }; + + static void MASQUERADE_help(void) +@@ -20,12 +26,15 @@ static void MASQUERADE_help(void) + " --to-ports [-]\n" + " Port (range) to map to.\n" + " --random\n" +-" Randomize source port.\n"); ++" Randomize source port.\n" ++" --fullcone\n" ++" Do fullcone NAT mapping.\n"); + } + + static const struct xt_option_entry MASQUERADE_opts[] = { + {.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING}, + {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, ++ {.name = "fullcone", .id = O_FULLCONE, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, + }; + +@@ -97,6 +106,9 @@ static void MASQUERADE_parse(struct xt_option_call *cb) + case O_RANDOM: + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM; + break; ++ case O_FULLCONE: ++ mr->range[0].flags |= NF_NAT_RANGE_FULLCONE; ++ break; + } + } + +@@ -116,6 +128,8 @@ MASQUERADE_print(const void *ip, const struct xt_entry_target *target, + + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) + printf(" random"); ++ if (r->flags & NF_NAT_RANGE_FULLCONE) ++ printf(" fullcone"); + } + + static void +@@ -132,6 +146,8 @@ MASQUERADE_save(const void *ip, const struct xt_entry_target *target) + + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) + printf(" --random"); ++ if (r->flags & NF_NAT_RANGE_FULLCONE) ++ printf(" --fullcone"); + } + + static int MASQUERADE_xlate(struct xt_xlate *xl, +@@ -153,6 +169,9 @@ static int MASQUERADE_xlate(struct xt_xlate *xl, + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) + xt_xlate_add(xl, "random "); + ++ if (r->flags & NF_NAT_RANGE_FULLCONE) ++ xt_xlate_add(xl, "fullcone "); ++ + return 1; + } + +diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c +index e92d811..9634ba9 100644 +--- a/extensions/libipt_SNAT.c ++++ b/extensions/libipt_SNAT.c +@@ -8,16 +8,22 @@ + #include + #include + ++/* Temporarily defining here, need to be picked up from the ++ * new kernel header linux/netfilter/nf_nat.h */ ++#define NF_NAT_RANGE_FULLCONE (1 << 5) ++ + enum { + O_TO_SRC = 0, + O_RANDOM, + O_RANDOM_FULLY, + O_PERSISTENT, + O_X_TO_SRC, ++ O_FULLCONE, + F_TO_SRC = 1 << O_TO_SRC, + F_RANDOM = 1 << O_RANDOM, + F_RANDOM_FULLY = 1 << O_RANDOM_FULLY, + F_X_TO_SRC = 1 << O_X_TO_SRC, ++ F_FULLCONE = 1 << O_FULLCONE + }; + + /* Source NAT data consists of a multi-range, indicating where to map +@@ -34,7 +40,7 @@ static void SNAT_help(void) + "SNAT target options:\n" + " --to-source [[-]][:port[-port]]\n" + " Address to map source to.\n" +-"[--random] [--random-fully] [--persistent]\n"); ++"[--random] [--random-fully] [--persistent] [--fullcone]\n"); + } + + static const struct xt_option_entry SNAT_opts[] = { +@@ -43,6 +49,7 @@ static const struct xt_option_entry SNAT_opts[] = { + {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, + {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE}, + {.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE}, ++ {.name = "fullcone", .id = O_FULLCONE, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, + }; + +@@ -189,12 +196,15 @@ static void SNAT_fcheck(struct xt_fcheck_call *cb) + { + static const unsigned int f = F_TO_SRC | F_RANDOM; + static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY; ++ static const unsigned int c = F_TO_SRC | F_FULLCONE; + struct nf_nat_ipv4_multi_range_compat *mr = cb->data; + + if ((cb->xflags & f) == f) + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM; + if ((cb->xflags & r) == r) + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; ++ if ((cb->xflags & c) == c) ++ mr->range[0].flags |= NF_NAT_RANGE_FULLCONE; + } + + static void print_range(const struct nf_nat_ipv4_range *r) +@@ -232,6 +242,8 @@ static void SNAT_print(const void *ip, const struct xt_entry_target *target, + printf(" random-fully"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" fullcone"); + } + } + +@@ -249,6 +261,8 @@ static void SNAT_save(const void *ip, const struct xt_entry_target *target) + printf(" --random-fully"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" --persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" --fullcone"); + } + } + +@@ -299,6 +313,12 @@ static int SNAT_xlate(struct xt_xlate *xl, + sep = ","; + xt_xlate_add(xl, "%spersistent", sep); + } ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) { ++ if (sep_need) ++ sep = ","; ++ xt_xlate_add(xl, "%sfullcone", sep); ++ sep_need = true; ++ } + } + + return 1; +-- +2.18.0 + diff --git a/src/iptables/patch/series b/src/iptables/patch/series new file mode 100644 index 000000000000..df084ed96ed3 --- /dev/null +++ b/src/iptables/patch/series @@ -0,0 +1 @@ +0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch From c95d8e4d47c3c38784d65b1fb36088f5bc757c7c Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Thu, 30 Jan 2020 00:46:55 -0800 Subject: [PATCH 0337/1427] [teamd]: increase startsecs to 5 seconds for teamsyncd (#4083) Updating the startsecs=5sec for teamsyncd to make the time for which the process needs to stay up before declaring the startup successfull. --- dockers/docker-teamd/supervisord.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index 3a420e0fcdcf..43d6d2d6d116 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -36,6 +36,7 @@ stderr_logfile=syslog [program:teamsyncd] command=/usr/bin/teamsyncd priority=3 +startsecs=5 autostart=false autorestart=false stdout_logfile=syslog From c39b1883c5bf95e9b7c6a7404e730e7728c079de Mon Sep 17 00:00:00 2001 From: rlhui <48738894+rlhui@users.noreply.github.com> Date: Thu, 30 Jan 2020 08:36:49 -0800 Subject: [PATCH 0338/1427] Update build badge in the README.md (#4084) Update build badge in the README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 301bff39547e..2ce3de9ca5f4 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,10 @@ Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/j P4: [![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all) VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all) -*201904*: -Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201904/) -Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201904/) +*201911*: +Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/) +Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/) +VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911) *201811*: Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/) From a4d3e5a26f7b746eae2d6cc0394e7515128b8f8c Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 31 Jan 2020 02:29:20 +0000 Subject: [PATCH 0339/1427] [swss]: fix sonic-swss submodule due to history change Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 4628a5a211b8..11fe6b520693 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 4628a5a211b809deca3f76352dc0497396cb63a0 +Subproject commit 11fe6b520693c31c5e1398274035e103d2977a31 From fc101b6cebefb81c2d82169ee070bcfee721b8d7 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Fri, 31 Jan 2020 04:54:09 +0200 Subject: [PATCH 0340/1427] [mellanox]: Add new Mellanox-SN3800-D112C8 sku. (#4085) Signed-off-by: Nazarii Hnydyn --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 2 +- .../Mellanox-SN3800-D112C8/buffers.json.j2 | 1 + .../buffers_defaults_t0.j2 | 1 + .../buffers_defaults_t1.j2 | 1 + .../pg_profile_lookup.ini | 1 + .../Mellanox-SN3800-D112C8/port_config.ini | 105 ++++++++++++++++++ .../Mellanox-SN3800-D112C8/qos.json.j2 | 1 + .../Mellanox-SN3800-D112C8/sai.profile | 1 + .../Mellanox-SN3800-D112C8/sai_3800.xml | 1 + .../sonic_platform/chassis.py | 2 +- .../mlnx-platform-api/sonic_platform/psu.py | 2 +- .../sonic_platform/thermal.py | 2 +- 12 files changed, 116 insertions(+), 4 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/qos.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 7c4f33f74973..40734349a230 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -41,7 +41,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4} +hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] def log_info(msg, also_print_to_console=False): diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..85f0b6b6b354 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..3bb496a5103b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini new file mode 120000 index 000000000000..252ae8d4149b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini new file mode 100644 index 000000000000..9559119c7e38 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini @@ -0,0 +1,105 @@ +# name lanes alias index speed fec +Ethernet0 0,1 etp1a 0 50000 none +Ethernet2 2,3 etp1b 0 50000 none +Ethernet4 4,5 etp2a 1 50000 none +Ethernet6 6,7 etp2b 1 50000 none +Ethernet8 8,9 etp3a 2 50000 none +Ethernet10 10,11 etp3b 2 50000 none +Ethernet12 12,13,14,15 etp4 3 50000 none +Ethernet16 16,17 etp5a 4 50000 none +Ethernet18 18,19 etp5b 4 50000 none +Ethernet20 20,21 etp6a 5 50000 none +Ethernet22 22,23 etp6b 5 50000 none +Ethernet24 24,25 etp7a 6 50000 none +Ethernet26 26,27 etp7b 6 50000 none +Ethernet28 28,29,30,31 etp8 7 50000 none +Ethernet32 32,33 etp9a 8 50000 none +Ethernet34 34,35 etp9b 8 50000 none +Ethernet36 36,37 etp10a 9 50000 none +Ethernet38 38,39 etp10b 9 50000 none +Ethernet40 40,41 etp11a 10 50000 none +Ethernet42 42,43 etp11b 10 50000 none +Ethernet44 44,45,46,47 etp12 11 50000 none +Ethernet48 48,49 etp13a 12 50000 none +Ethernet50 50,51 etp13b 12 50000 none +Ethernet52 52,53 etp14a 13 50000 none +Ethernet54 54,55 etp14b 13 50000 none +Ethernet56 56,57 etp15a 14 50000 none +Ethernet58 58,59 etp15b 14 50000 none +Ethernet60 60,61,62,63 etp16 15 50000 none +Ethernet64 64,65 etp17a 16 50000 none +Ethernet66 66,67 etp17b 16 50000 none +Ethernet68 68,69 etp18a 17 50000 none +Ethernet70 70,71 etp18b 17 50000 none +Ethernet72 72,73 etp19a 18 50000 none +Ethernet74 74,75 etp19b 18 50000 none +Ethernet76 76,77,78,79 etp20 19 50000 none +Ethernet80 80,81 etp21a 20 50000 none +Ethernet82 82,83 etp21b 20 50000 none +Ethernet84 84,85 etp22a 21 50000 none +Ethernet86 86,87 etp22b 21 50000 none +Ethernet88 88,89 etp23a 22 50000 none +Ethernet90 90,91 etp23b 22 50000 none +Ethernet92 92,93,94,95 etp24 23 50000 none +Ethernet96 96,97,98,99 etp25 24 100000 rs +Ethernet100 100,101,102,103 etp26 25 100000 rs +Ethernet104 104,105 etp27a 26 50000 none +Ethernet106 106,107 etp27b 26 50000 none +Ethernet108 108,109,110,111 etp28 27 50000 none +Ethernet112 112,113,114,115 etp29 28 100000 rs +Ethernet116 116,117,118,119 etp30 29 100000 rs +Ethernet120 120,121 etp31a 30 50000 none +Ethernet122 122,123 etp31b 30 50000 none +Ethernet124 124,125,126,127 etp32 31 50000 none +Ethernet128 128,129,130,131 etp33 32 100000 rs +Ethernet132 132,133,134,135 etp34 33 100000 rs +Ethernet136 136,137 etp35a 34 50000 none +Ethernet138 138,139 etp35b 34 50000 none +Ethernet140 140,141,142,143 etp36 35 50000 none +Ethernet144 144,145,146,147 etp37 36 100000 rs +Ethernet148 148,149,150,151 etp38 37 100000 rs +Ethernet152 152,153 etp39a 38 50000 none +Ethernet154 154,155 etp39b 38 50000 none +Ethernet156 156,157,158,159 etp40 39 50000 none +Ethernet160 160,161 etp41a 40 50000 none +Ethernet162 162,163 etp41b 40 50000 none +Ethernet164 164,165 etp42a 41 50000 none +Ethernet166 166,167 etp42b 41 50000 none +Ethernet168 168,169 etp43a 42 50000 none +Ethernet170 170,171 etp43b 42 50000 none +Ethernet172 172,173,174,175 etp44 43 50000 none +Ethernet176 176,177 etp45a 44 50000 none +Ethernet178 178,179 etp45b 44 50000 none +Ethernet180 180,181 etp46a 45 50000 none +Ethernet182 182,183 etp46b 45 50000 none +Ethernet184 184,185 etp47a 46 50000 none +Ethernet186 186,187 etp47b 46 50000 none +Ethernet188 188,189,190,191 etp48 47 50000 none +Ethernet192 192,193 etp49a 48 50000 none +Ethernet194 194,195 etp49b 48 50000 none +Ethernet196 196,197 etp50a 49 50000 none +Ethernet198 198,199 etp50b 49 50000 none +Ethernet200 200,201 etp51a 50 50000 none +Ethernet202 202,203 etp51b 50 50000 none +Ethernet204 204,205,206,207 etp52 51 50000 none +Ethernet208 208,209 etp53a 52 50000 none +Ethernet210 210,211 etp53b 52 50000 none +Ethernet212 212,213 etp54a 53 50000 none +Ethernet214 214,215 etp54b 53 50000 none +Ethernet216 216,217 etp55a 54 50000 none +Ethernet218 218,219 etp55b 54 50000 none +Ethernet220 220,221,222,223 etp56 55 50000 none +Ethernet224 224,225 etp57a 56 50000 none +Ethernet226 226,227 etp57b 56 50000 none +Ethernet228 228,229 etp58a 57 50000 none +Ethernet230 230,231 etp58b 57 50000 none +Ethernet232 232,233 etp59a 58 50000 none +Ethernet234 234,235 etp59b 58 50000 none +Ethernet236 236,237,238,239 etp60 59 50000 none +Ethernet240 240,241 etp61a 60 50000 none +Ethernet242 242,243 etp61b 60 50000 none +Ethernet244 244,245 etp62a 61 50000 none +Ethernet246 246,247 etp62b 61 50000 none +Ethernet248 248,249 etp63a 62 50000 none +Ethernet250 250,251 etp63b 62 50000 none +Ethernet252 252,253,254,255 etp64 63 50000 none diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/qos.json.j2 new file mode 120000 index 000000000000..eccf286dc879 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile new file mode 100644 index 000000000000..367f6c4e99c0 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3800.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml new file mode 120000 index 000000000000..686d6298865c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml @@ -0,0 +1 @@ +../ACS-MSN3800/sai_3800.xml \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 1f9af04319a1..5e8c76ccd617 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -49,7 +49,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4} +hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] class Chassis(ChassisBase): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 0e4c3fd50f7a..59893f21cd0a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -37,7 +37,7 @@ # in most SKUs the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. # but there are exceptions which will be handled by the following dictionary -hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1} +hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1} psu_profile_list = [ # default filename convention { diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 8030db19edaf..67fbe3a6b51b 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -106,7 +106,7 @@ THERMAL_API_GET_HIGH_THRESHOLD ] -hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7} +hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7} thermal_profile_list = [ # 2700 { From fb535bb2ba871bf6eef8a46081fb63b953578107 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 31 Jan 2020 12:38:46 +0000 Subject: [PATCH 0341/1427] [docker-sonic-mgmt]: set wheel version to 0.33.6 to fix sonic-mgmt build break looks like version 0.42 has build issues Signed-off-by: Guohan Lu --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 7cfaeaaf7d2b..8c02a58aa2c0 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -89,6 +89,7 @@ RUN pip install azure-kusto-data==0.0.13 \ azure-kusto-ingest==0.0.13 # Install pytest-ansible module +RUN pip install wheel==0.33.6 RUN pip install pytest-ansible==2.2.2 ## Copy and install sonic-mgmt docker dependencies From 142d45ce98008aac6437070a3a941083494b52a8 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Sat, 1 Feb 2020 00:30:00 -0800 Subject: [PATCH 0342/1427] Revert "Disable SNMPv1 (#2156)" (#4088) --- .../0004-Disable-SNMPv1.patch | 25 ------------------- src/snmpd/patch-5.7.3+dfsg/series | 1 - 2 files changed, 26 deletions(-) delete mode 100644 src/snmpd/patch-5.7.3+dfsg/0004-Disable-SNMPv1.patch diff --git a/src/snmpd/patch-5.7.3+dfsg/0004-Disable-SNMPv1.patch b/src/snmpd/patch-5.7.3+dfsg/0004-Disable-SNMPv1.patch deleted file mode 100644 index 6782a18c7758..000000000000 --- a/src/snmpd/patch-5.7.3+dfsg/0004-Disable-SNMPv1.patch +++ /dev/null @@ -1,25 +0,0 @@ -From db633987abf1ea093cb1785b3cd37adfdb55e4cc Mon Sep 17 00:00:00 2001 -From: Qi Luo -Date: Mon, 15 Oct 2018 22:30:28 +0000 -Subject: [PATCH] Disable SNMPv1 - -Signed-off-by: Qi Luo ---- - debian/rules | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/debian/rules b/debian/rules -index 9eb8d2d..4c3b5b6 100755 ---- a/debian/rules -+++ b/debian/rules -@@ -42,6 +42,7 @@ endif - override_dh_auto_configure: - dh_auto_configure -- --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man \ - --with-persistent-directory=/var/lib/snmp \ -+ --disable-snmpv1 \ - --enable-ucd-snmp-compatibility \ - --enable-shared --with-cflags="$(CFLAGS) -DNETSNMP_USE_INLINE" \ - --with-ldflags="$(LDFLAGS)" \ --- -2.18.0 - diff --git a/src/snmpd/patch-5.7.3+dfsg/series b/src/snmpd/patch-5.7.3+dfsg/series index 5cd0b06510f6..428a81eb6b22 100644 --- a/src/snmpd/patch-5.7.3+dfsg/series +++ b/src/snmpd/patch-5.7.3+dfsg/series @@ -1,7 +1,6 @@ 0001-SNMP-Stop-spamming-logs-with-statfs-permission-denie.patch 0002-at.c-properly-check-return-status-from-realloc.-Than.patch 0003-CHANGES-BUG-2743-snmpd-crashes-when-receiving-a-GetN.patch -0004-Disable-SNMPv1.patch 0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch 0006-From-Jiri-Cervenka-snmpd-Fixed-agentx-crashing-and-or-freezing-on-timeout.patch 0007-Linux-VRF-5.7.3-Support.patch From 211cff55cde8dd9d8d0d1baee67f6e35a1b6d2bb Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Tue, 4 Feb 2020 01:03:16 -0800 Subject: [PATCH 0343/1427] [kernel]: Increasing gc threshold values for kernel neighbors (#4100) Increase gc threashold values as below: Previous: net.ipv6.neigh.default.gc_thresh1=128 net.ipv6.neigh.default.gc_thresh2=512 net.ipv6.neigh.default.gc_thresh3=1024 net.ipv4.neigh.default.gc_thresh1=128 net.ipv4.neigh.default.gc_thresh2=512 net.ipv4.neigh.default.gc_thresh3=1024 New net.ipv6.neigh.default.gc_thresh1=1024 net.ipv6.neigh.default.gc_thresh2=2048 net.ipv6.neigh.default.gc_thresh3=4096 net.ipv4.neigh.default.gc_thresh1=1024 net.ipv4.neigh.default.gc_thresh2=2048 net.ipv4.neigh.default.gc_thresh3=4096 --- build_debian.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build_debian.sh b/build_debian.sh index 34065bbceef1..b51994e615dc 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -380,6 +380,12 @@ set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_ignore 2 set /files/etc/sysctl.conf/net.ipv4.neigh.default.base_reachable_time_ms 1800000 set /files/etc/sysctl.conf/net.ipv6.neigh.default.base_reachable_time_ms 1800000 +set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh1 1024 +set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh1 1024 +set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh2 2048 +set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh2 2048 +set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh3 4096 +set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh3 4096 set /files/etc/sysctl.conf/net.ipv6.conf.default.forwarding 1 set /files/etc/sysctl.conf/net.ipv6.conf.all.forwarding 1 From 3c12b325298f3b2327dcae496530edf6f1b99a4e Mon Sep 17 00:00:00 2001 From: Xin Wang Date: Wed, 5 Feb 2020 17:08:27 +0800 Subject: [PATCH 0344/1427] [docker-sonic-mgmt]: Add the snmp tool to the sonic-mgmt docker (#4110) The snmp tool is required for interacting with certain type of PDU hosts in platform PSU/power related testing. This change is to have the snmp tool pre-built in the sonic-mgmt docker image. Signed-off-by: Xin Wang --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 8c02a58aa2c0..662f781dc7c0 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -23,6 +23,7 @@ RUN apt-get install -y \ curl \ cmake \ tcpdump \ + snmp \ python-dev \ python-scapy From b5b68c75e54083db504d3fbad93880ff93d0e19a Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 5 Feb 2020 01:09:16 -0800 Subject: [PATCH 0345/1427] teamd: fix possible race in master ifname callback (#4109) - What I did Ported a fix from libteam master to our master. Fixes #4070 Fixes #3649 - How I did it Applied patch jpirko/libteam@c723737 from upstream. - How to verify it Build image for your DUT and warm-reboot your DUT 10 times. Check that all PortChannels are up and no error messages in teamd.log --- ...sible-race-in-master-ifname-callback.patch | 101 ++++++++++++++++++ src/libteam/patch/series | 1 + 2 files changed, 102 insertions(+) create mode 100644 src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch diff --git a/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch b/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch new file mode 100644 index 000000000000..9203cd17c58b --- /dev/null +++ b/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch @@ -0,0 +1,101 @@ +From c0eb9e4bfe1c6a0e77f02b1459d91498c1a3dcff Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 4 Feb 2020 09:39:08 -0800 +Subject: [PATCH 1/1] teamd: fix possible race in master ifname callback + +--- + teamd/teamd.h | 2 ++ + teamd/teamd_link_watch.c | 13 ++++++++++--- + teamd/teamd_per_port.c | 24 +++++++++++++++++++----- + 3 files changed, 31 insertions(+), 8 deletions(-) + +diff --git a/teamd/teamd.h b/teamd/teamd.h +index 418214d..1ce120e 100644 +--- a/teamd/teamd.h ++++ b/teamd/teamd.h +@@ -334,6 +334,8 @@ int teamd_port_remove_all(struct teamd_context *ctx); + void teamd_port_obj_remove_all(struct teamd_context *ctx); + int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, + bool *enabled); ++int teamd_port_enabled_check(struct teamd_context *ctx, ++ struct teamd_port *tdport, bool *enabled); + int teamd_port_prio(struct teamd_context *ctx, struct teamd_port *tdport); + int teamd_port_check_enable(struct teamd_context *ctx, + struct teamd_port *tdport, +diff --git a/teamd/teamd_link_watch.c b/teamd/teamd_link_watch.c +index 62f8267..e4b3d3f 100644 +--- a/teamd/teamd_link_watch.c ++++ b/teamd/teamd_link_watch.c +@@ -423,9 +423,16 @@ static int link_watch_refresh_forced_send(struct teamd_context *ctx) + int err; + + teamd_for_each_tdport(tdport, ctx) { +- err = teamd_port_enabled(ctx, tdport, &port_enabled); +- if (err) +- return err; ++ err = teamd_port_enabled_check(ctx, tdport, &port_enabled); ++ if (err) { ++ /* Looks like the options are not ready for this port. ++ * This can happen when called from ++ * link_watch_port_master_ifindex_changed(). Skip this ++ * for now, let it be handled by future call of ++ * link_watch_enabled_option_changed(). ++ */ ++ continue; ++ } + __set_forced_send_for_port(tdport, port_enabled); + if (port_enabled) + enabled_port_count++; +diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c +index a87e809..d10cfb2 100644 +--- a/teamd/teamd_per_port.c ++++ b/teamd/teamd_per_port.c +@@ -395,19 +395,21 @@ int teamd_port_remove_ifname(struct teamd_context *ctx, const char *port_name) + return teamd_port_remove(ctx, tdport); + } + +-int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, +- bool *enabled) ++int __teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, ++ bool *enabled, bool may_fail) + { + struct team_option *option; + + option = team_get_option(ctx->th, "np", "enabled", tdport->ifindex); + if (!option) { +- teamd_log_err("%s: Failed to find \"enabled\" option.", +- tdport->ifname); ++ if (!may_fail) ++ teamd_log_err("%s: Failed to find \"enabled\" option.", ++ tdport->ifname); + return -ENOENT; + } + if (team_get_option_type(option) != TEAM_OPTION_TYPE_BOOL) { +- teamd_log_err("Unexpected type of \"enabled\" option."); ++ if (!may_fail) ++ teamd_log_err("Unexpected type of \"enabled\" option."); + return -EINVAL; + } + +@@ -415,6 +417,18 @@ int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, + return 0; + } + ++int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, ++ bool *enabled) ++{ ++ return __teamd_port_enabled(ctx, tdport, enabled, false); ++} ++ ++int teamd_port_enabled_check(struct teamd_context *ctx, ++ struct teamd_port *tdport, bool *enabled) ++{ ++ return __teamd_port_enabled(ctx, tdport, enabled, true); ++} ++ + int teamd_port_prio(struct teamd_context *ctx, struct teamd_port *tdport) + { + int prio; +-- +2.17.1.windows.2 + diff --git a/src/libteam/patch/series b/src/libteam/patch/series index 7be69525d9d0..62c39e780f1a 100644 --- a/src/libteam/patch/series +++ b/src/libteam/patch/series @@ -8,3 +8,4 @@ 0008-libteam-Add-warm_reboot-mode.patch 0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch 0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch +0011-teamd-fix-possible-race-in-master-ifname-callback.patch From 2e0f9ca0f46659a7465abe8b36db5c6a281f5f76 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 5 Feb 2020 19:04:19 -0800 Subject: [PATCH 0346/1427] [hsflowd]: remove linux kernel header dependency from hsflowd package (#4111) hsflowd compilation does not linux kernel header Signed-off-by: Guohan Lu --- rules/sflow.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/sflow.mk b/rules/sflow.mk index 4bc443647f80..d4c579ddf167 100644 --- a/rules/sflow.mk +++ b/rules/sflow.mk @@ -5,7 +5,7 @@ HSFLOWD_SUBVERSION = 3 export HSFLOWD_VERSION HSFLOWD_SUBVERSION HSFLOWD = hsflowd_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb -$(HSFLOWD)_DEPENDS += $(LIBHIREDIS_DEV) $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(HSFLOWD)_DEPENDS += $(LIBHIREDIS_DEV) $(HSFLOWD)_SRC_PATH = $(SRC_PATH)/sflow/hsflowd SONIC_MAKE_DEBS += $(HSFLOWD) From 74e28ad6ffd7f4e981e88dcc110506e83040bceb Mon Sep 17 00:00:00 2001 From: Santhosh Kumar T <53558409+santhosh-kt@users.noreply.github.com> Date: Thu, 6 Feb 2020 18:53:27 +0530 Subject: [PATCH 0347/1427] [DellEMC] S6000 - Thermal support - Last Reboot Reason (#4097) - Added support for Thermal event in Last Reboot Reason "show reboot-cause" command. - Added support for sending log message in case of thermal shutdown. sonic NOTICE root: Shutting down due to over temperature (40 degree, 30 degree, 34 degree) --- .../s6000/scripts/fancontrol.sh | 154 +++++++++++++----- .../s6000/sonic_platform/chassis.py | 34 ++++ 2 files changed, 143 insertions(+), 45 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh index 43315e06c930..665d5494b6b7 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh @@ -1,4 +1,5 @@ #!/bin/bash +trap 'cleanup' 0 1 2 3 6 9 10 11 13 15 LEVEL=99 INTERVAL=5 @@ -14,11 +15,27 @@ LEVEL3=16000 LEVEL4=19000 LEVEL5=19000 +LRR_FILE="/host/reboot-cause/reboot-cause.txt" I2C_ADAPTER="/sys/class/i2c-adapter/i2c-2/i2c-11" + SENSOR1="$I2C_ADAPTER/11-004c/hwmon/hwmon*/temp1_input" SENSOR2="$I2C_ADAPTER/11-004d/hwmon/hwmon*/temp1_input" SENSOR3="$I2C_ADAPTER/11-004e/hwmon/hwmon*/temp1_input" +SENSOR1_MAX="$I2C_ADAPTER/11-004c/hwmon/hwmon*/temp1_max" +SENSOR2_MAX="$I2C_ADAPTER/11-004d/hwmon/hwmon*/temp1_max" +SENSOR3_MAX="$I2C_ADAPTER/11-004e/hwmon/hwmon*/temp1_max" + +SENSOR1_MAX_VAL=$(cat $SENSOR1_MAX) +SENSOR2_MAX_VAL=$(cat $SENSOR2_MAX) +SENSOR3_MAX_VAL=$(cat $SENSOR3_MAX) + +# Reducing by 63 to differentiate this temperature settings +# from pmon sensors configuration settings +SENSOR1_NEW_MAX=$(expr `echo $SENSOR1_MAX_VAL` + 5000 - 63) +SENSOR2_NEW_MAX=$(expr `echo $SENSOR2_MAX_VAL` + 5000 - 63) +SENSOR3_NEW_MAX=$(expr `echo $SENSOR3_MAX_VAL` + 5000 - 63) + # Three fan trays with each contains two separate fans # fan1-fan4 fan2-fan5 fan3-fan6 FANTRAY1_FAN1=$I2C_ADAPTER/11-0029/fan1_target @@ -46,6 +63,14 @@ function check_module fi } +function cleanup +{ + echo $SENSOR1_MAX_VAL > $SENSOR1_MAX + echo $SENSOR2_MAX_VAL > $SENSOR2_MAX + echo $SENSOR3_MAX_VAL > $SENSOR3_MAX + exit 1 +} + function check_faulty_fan { @@ -123,56 +148,95 @@ function update_fan_speed function monitor_temp_sensors { + SENSOR1_CUR_MAX_VAL=$(cat $SENSOR1_MAX) + SENSOR2_CUR_MAX_VAL=$(cat $SENSOR2_MAX) + SENSOR3_CUR_MAX_VAL=$(cat $SENSOR3_MAX) + if [ "$SENSOR1_CUR_MAX_VAL" -ne "$SENSOR1_NEW_MAX" ] + then + SENSOR1_NEW_MAX=$(expr `echo $SENSOR1_CUR_MAX_VAL` + 5000 - 63) + SENSOR1_MAX_VAL=$SENSOR1_CUR_MAX_VAL + echo $SENSOR1_NEW_MAX > $SENSOR1_MAX + fi + if [ "$SENSOR2_CUR_MAX_VAL" -ne "$SENSOR2_NEW_MAX" ] + then + SENSOR2_NEW_MAX=$(expr `echo $SENSOR2_CUR_MAX_VAL` + 5000 - 63) + SENSOR2_MAX_VAL=$SENSOR2_CUR_MAX_VAL + echo $SENSOR2_NEW_MAX > $SENSOR2_MAX + fi + if [ "$SENSOR3_CUR_MAX_VAL" -ne "$SENSOR3_NEW_MAX" ] + then + SENSOR3_NEW_MAX=$(expr `echo $SENSOR3_CUR_MAX_VAL` + 5000 - 63) + SENSOR3_MAX_VAL=$SENSOR3_CUR_MAX_VAL + echo $SENSOR3_NEW_MAX > $SENSOR3_MAX + fi - while true # go through all temp sensor outputs - do - sensor1=$(expr `echo $(cat $SENSOR1)` / 1000) - sensor2=$(expr `echo $(cat $SENSOR2)` / 1000) - sensor3=$(expr `echo $(cat $SENSOR3)` / 1000) - sum=$(($sensor1 + $sensor2 + $sensor3)) - sensor_temp=$(($sum/3)) - - if [ "$sensor_temp" -le "25" ] && [ "$LEVEL" -ne "0" ] - then - # Set Fan Speed to 7000 RPM" - LEVEL=0 - update_fan_speed $IDLE - logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" - - elif [ "$sensor_temp" -ge "26" ] && [ "$sensor_temp" -le "44" ] && [ "$LEVEL" -ne "1" ] - then - # Set Fan Speed to 10000 RPM" - LEVEL=1 - update_fan_speed $LEVEL1 - logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" - - elif [ "$sensor_temp" -ge "45" ] && [ "$sensor_temp" -le "59" ] && [ "$LEVEL" -ne "2" ] - then - # Set Fan Speed to 13000 RPM" - LEVEL=2 - update_fan_speed $LEVEL2 - logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" - - elif [ "$sensor_temp" -ge "60" ] && [ "$sensor_temp" -le "79" ] && [ "$LEVEL" -ne "3" ] - then - # Set Fan Speed to 16000 RPM" - LEVEL=3 - update_fan_speed $LEVEL3 - logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" - - elif [ "$sensor_temp" -ge "80" ] && [ "$LEVEL" -ne "4" ] - then - # Set Fan Speed to 19000 RPM" - LEVEL=4 - update_fan_speed $LEVEL4 - logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" - fi + # go through all temp sensor outputs + sensor1=$(expr `echo $(cat $SENSOR1)` / 1000) + sensor2=$(expr `echo $(cat $SENSOR2)` / 1000) + sensor3=$(expr `echo $(cat $SENSOR3)` / 1000) + # All sensors output in 1000's + s1=$(cat $SENSOR1) + s2=$(cat $SENSOR2) + s3=$(cat $SENSOR3) + + if [ "$s1" -ge "$SENSOR1_MAX_VAL" ] || [ "$s2" -ge "$SENSOR2_MAX_VAL" ] || [ "$s3" -ge "$SENSOR3_MAX_VAL" ] + then + # Thermal trip is about to happen + echo "Thermal Overload $sensor1 $sensor2 $sensor3" > $LRR_FILE + logger "Shutting down due to over temperature ($sensor1 degree, $sensor2 degree, $sensor3 degree)" + sync + sleep 1 # Give time to send logger message to server + # Assigning the original max values back in sensors + echo $SENSOR1_MAX_VAL > $SENSOR1_MAX + echo $SENSOR2_MAX_VAL > $SENSOR2_MAX + echo $SENSOR3_MAX_VAL > $SENSOR3_MAX + + ### Not Reached ### + # In case if HW fails to shutdown + /sbin/shutdown -P now + fi + sum=$(($sensor1 + $sensor2 + $sensor3)) + sensor_temp=$(($sum/3)) + + if [ "$sensor_temp" -le "25" ] && [ "$LEVEL" -ne "0" ] + then + # Set Fan Speed to 7000 RPM" + LEVEL=0 + update_fan_speed $IDLE + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "26" ] && [ "$sensor_temp" -le "44" ] && [ "$LEVEL" -ne "1" ] + then + # Set Fan Speed to 10000 RPM" + LEVEL=1 + update_fan_speed $LEVEL1 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "45" ] && [ "$sensor_temp" -le "59" ] && [ "$LEVEL" -ne "2" ] + then + # Set Fan Speed to 13000 RPM" + LEVEL=2 + update_fan_speed $LEVEL2 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "60" ] && [ "$sensor_temp" -le "79" ] && [ "$LEVEL" -ne "3" ] + then + # Set Fan Speed to 16000 RPM" + LEVEL=3 + update_fan_speed $LEVEL3 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "80" ] && [ "$LEVEL" -ne "4" ] + then + # Set Fan Speed to 19000 RPM" + LEVEL=4 + update_fan_speed $LEVEL4 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + fi # Check for faulty fan check_faulty_fan - done - } # Check drivers for sysfs attributes diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index e94a7d1210f5..8bb95cac1d63 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -11,6 +11,7 @@ import os import time import datetime + import struct import subprocess from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp @@ -41,6 +42,7 @@ class Chassis(ChassisBase): reset_reason_dict = {} reset_reason_dict[0xe] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE reset_reason_dict[0x6] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE + reset_reason_dict[0x7] = ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER def __init__(self): ChassisBase.__init__(self) @@ -100,6 +102,36 @@ def _get_cpld_register(self, reg_name): rv = rv.lstrip(" ") return rv + def _nvram_write(self, offset, val): + resource = "/dev/nvram" + fd = os.open(resource, os.O_RDWR) + if (fd < 0): + print('File open failed ',resource) + return + if (os.lseek(fd, offset, os.SEEK_SET) != offset): + print('lseek failed on ',resource) + return + ret = os.write(fd, struct.pack('B', val)) + if ret != 1: + print('Write failed ',str(ret)) + return + os.close(fd) + + def _get_thermal_reset(self): + reset_file = "/host/reboot-cause/reboot-cause.txt" + if (not os.path.isfile(reset_file)): + return False + try: + with open(reset_file, 'r') as fd: + rv = fd.read() + except Exception as error: + return False + + if "Thermal Overload" in rv: + return True + + return False + def get_name(self): """ Retrieves the name of the chassis @@ -181,6 +213,8 @@ def get_reboot_cause(self): # NVRAM. Only Warmboot and Coldboot reason are supported here. # Since it does not support any hardware reason, we return # non_hardware as default + if self._get_thermal_reset() == True: + self._nvram_write(0x49, 0x7) lrr = self._get_cpld_register('last_reboot_reason') if (lrr != 'ERR'): From f8e530577de9eb61d86f1ee1dfb2851c9546b9c5 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Fri, 7 Feb 2020 02:27:20 +0200 Subject: [PATCH 0348/1427] [docker] remove leftover --net=host docker run options (#4119) Fixes #4118 Signed-off-by: Mykola Faryma --- rules/docker-nat.mk | 2 +- rules/docker-sonic-mgmt-framework.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk index 765b6f7d3b0f..f41c8f06647c 100644 --- a/rules/docker-nat.mk +++ b/rules/docker-nat.mk @@ -22,7 +22,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_NAT_DBG) $(DOCKER_NAT)_CONTAINER_NAME = nat -$(DOCKER_NAT)_RUN_OPT += --net=host --privileged -t +$(DOCKER_NAT)_RUN_OPT += --privileged -t $(DOCKER_NAT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_NAT)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk index eb99f37875fc..f07b8d023d2d 100644 --- a/rules/docker-sonic-mgmt-framework.mk +++ b/rules/docker-sonic-mgmt-framework.mk @@ -26,7 +26,7 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_MGMT_FRAMEWORK_DBG) endif $(DOCKER_MGMT_FRAMEWORK)_CONTAINER_NAME = mgmt-framework -$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --net=host --privileged -t +$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --privileged -t $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += -v /etc:/host_etc:ro $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" From 4338fbe12b107c411db2e18cb3d7ea5eaedeb268 Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Fri, 7 Feb 2020 07:46:29 -0800 Subject: [PATCH 0349/1427] [procdockerstats]: Update file permission for procdockerstatsd (#4126) --- files/image_config/procdockerstatsd/procdockerstatsd | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 files/image_config/procdockerstatsd/procdockerstatsd diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd old mode 100644 new mode 100755 From 9c73df9cda389cf5962362b3830665b09405fe8e Mon Sep 17 00:00:00 2001 From: John Cheung Date: Fri, 7 Feb 2020 07:46:47 -0800 Subject: [PATCH 0350/1427] [barefoot]: Update SDE to 9.2.0 pre-release debian package (#4124) --- platform/barefoot/bfn-platform.mk | 4 ++-- platform/barefoot/bfn-sai.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 2b7711bd844f..622563e09853 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ -BFN_PLATFORM = bfnplatform_9.1.0.fddc672_deb9.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_1/$(BFN_PLATFORM)" +BFN_PLATFORM = bfnplatform_20200205_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index dca95460bf3a..2f2429845f5d 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,5 @@ -BFN_SAI = bfnsdk_9.1.0.fddc672_deb9.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_9_1/$(BFN_SAI)" +BFN_SAI = bfnsdk_20200205_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) $(BFN_SAI)_RDEPENDS += $(LIBNL_GENL3) From 57d4c841dbd56144c460daa7944482dc208e3dad Mon Sep 17 00:00:00 2001 From: Santhosh Kumar T <53558409+santhosh-kt@users.noreply.github.com> Date: Fri, 7 Feb 2020 21:19:08 +0530 Subject: [PATCH 0351/1427] [DellEMC] Dell Platform Modules Debian Build Error Fix (#4108) - Fix for Azure/sonic-buildimage#4095 - Exit status from failed make command(action) didnt reached parent target because the make command is inside the "for" loop. - Only the exit status of the last command in the last iteration of the for loop is read by parent target. - This is the reason why dpkg-buildpackage ignored the make error. - Fixed the issue with help of "set -e". --- .../sonic-platform-modules-dell/debian/rules | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index d3ba62afa4a0..3f0f79979886 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -12,6 +12,7 @@ COMMON_DIR := common dh $@ override_dh_auto_build: + set -e; \ (for mod in $(MODULE_DIRS); do \ if [ $$mod = "s6100" ]; then \ cp $(COMMON_DIR)/dell_pmc.c $(MOD_SRC_DIR)/$${mod}/modules/dell_s6100_lpc.c; \ @@ -37,9 +38,11 @@ override_dh_auto_build: fi; \ echo "making man page alias $$mod -> $$mod APIs";\ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ - done) + done); \ + set +e override_dh_auto_install: + set -e; \ (for mod in $(MODULE_DIRS); do \ dh_installdirs -pplatform-modules-$${mod} \ $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ @@ -49,12 +52,14 @@ override_dh_auto_install: dh_installdirs -pplatform-modules-$${mod} usr/local/bin ; \ cp -r $(MOD_SRC_DIR)/$${mod}/scripts/* debian/platform-modules-$${mod}/usr/local/bin; \ fi; \ - done) + done); \ + set +e override_dh_usrlocal: override_dh_clean: dh_clean + set -e; \ (for mod in $(MODULE_DIRS); do \ if [ $$mod = "s6100" ]; then \ rm -f $(MOD_SRC_DIR)/$${mod}/modules/dell_s6100_lpc.c; \ @@ -79,5 +84,6 @@ override_dh_clean: rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ fi; \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ - done) + done); \ + set +e From c63b5fc71951b5a5b9e4b9d090c3e6a90c752dd2 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 7 Feb 2020 07:51:01 -0800 Subject: [PATCH 0352/1427] [frr]: Use tag for building frr (#4082) Changed logic for building frr. Previously we used latest commit in the FRR_BRANCH. Now the buildsystem will use a tag to identify a commit for building. New approach will let us to update sonic-frr without corrupting building sonic-buildimage. --- rules/frr.mk | 1 + src/sonic-frr/Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/frr.mk b/rules/frr.mk index b2e347e0b12d..e5c9c230a766 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -3,6 +3,7 @@ FRR_VERSION = 7.2.1 FRR_SUBVERSION = 0 FRR_BRANCH = frr/7.2 +FRR_TAG = frr-7.2.1-s1 export FRR_VERSION FRR_SUBVERSION FRR_BRANCH diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index 9b8b3ffc23e9..e479f5e2ca1e 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -11,7 +11,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Build the package pushd ./frr git checkout -b $(FRR_BRANCH) origin/$(FRR_BRANCH) - stg branch --create $(STG_BRANCH) $(FRR_BRANCH) + stg branch --create $(STG_BRANCH) $(FRR_TAG) stg import -s ../patch/series tools/tarsource.sh -V -e '-sonic' dpkg-buildpackage -rfakeroot -b -us -uc -Ppkg.frr.nortrlib -j$(SONIC_CONFIG_MAKE_JOBS) From a6efbaed975e1bc6f010002b63a465d969744166 Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Fri, 7 Feb 2020 23:53:55 +0800 Subject: [PATCH 0353/1427] [device]Add check exception case when read port present fail (#4107) Modify get_psu_presence(). Move read() and close() to "try: ... except IOError:" To avoid when read port present sysfs fail. This exception will let sfputil.py to exit. So "sfputil show eeprom" can't show other port status. --- .../plugins/sfputil.py | 11 +++++----- .../plugins/sfputil.py | 22 +++++++++---------- .../plugins/sfputil.py | 20 ++++++++--------- .../plugins/sfputil.py | 20 ++++++++--------- .../plugins/sfputil.py | 14 +++++------- .../plugins/sfputil.py | 14 +++++------- .../plugins/sfputil.py | 22 +++++++++---------- .../plugins/sfputil.py | 9 ++++---- .../plugins/sfputil.py | 9 ++++---- .../plugins/sfputil.py | 11 +++++----- .../plugins/sfputil.py | 8 +++---- .../plugins/sfputil.py | 11 +++++----- .../plugins/sfputil.py | 9 ++++---- .../plugins/sfputil.py | 9 ++++---- .../plugins/sfputil.py | 8 ++++--- .../plugins/sfputil.py | 11 +++++----- .../plugins/sfputil.py | 9 ++++---- .../plugins/sfputil.py | 11 +++++----- .../plugins/sfputil.py | 8 ++++--- .../plugins/sfputil.py | 8 +++---- 20 files changed, 116 insertions(+), 128 deletions(-) diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py index cb18eb0d540c..33a2630f1d71 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py @@ -70,16 +70,15 @@ def get_presence(self, port_num): present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num) self.__port_to_is_present = present_path + content="0" try: val_file = open(self.__port_to_is_present) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True diff --git a/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py index 2ca1b8eec77d..b1727f0a79b6 100755 --- a/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py @@ -144,16 +144,15 @@ def get_presence(self, port_num): present_path = present_path + "module_present_" + str(port_num) self.__port_to_is_present = present_path + content="0" try: val_file = open(self.__port_to_is_present) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True @@ -175,16 +174,15 @@ def get_low_power_mode_cpld(self, port_num): q = self.qsfp_sb_remap(port_num) lp_mode_path = lp_mode_path + str(q) + content="0" try: val_file = open(lp_mode_path) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True diff --git a/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py index c9f3008dcc55..5647c84a35db 100755 --- a/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py @@ -105,16 +105,15 @@ def get_presence(self, port_num): present_path = present_path + "module_present_" + str(port_num) self.__port_to_is_present = present_path + content="0" try: val_file = open(self.__port_to_is_present) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True @@ -129,16 +128,15 @@ def get_low_power_mode_cpld(self, port_num): lp_mode_path = lp_mode_path + "module_lp_mode_" lp_mode_path = lp_mode_path + str(port_num) + content="0" try: val_file = open(lp_mode_path) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: print "Error: unable to open file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True diff --git a/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py index 88d8e536c4b6..62b9db604363 100755 --- a/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py @@ -158,16 +158,15 @@ def get_presence(self, port_num): present_path = present_path + "module_present_" + str(port_num) self.__port_to_is_present = present_path + content="0" try: val_file = open(self.__port_to_is_present) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True @@ -189,16 +188,15 @@ def get_low_power_mode_cpld(self, port_num): q = self.qsfp_sb_remap(port_num) lp_mode_path = lp_mode_path + str(q) + content = "0" try: val_file = open(lp_mode_path) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: print "Error: unable to open file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True diff --git a/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py index 4fcbdb022579..34e8f724ae42 100644 --- a/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py @@ -100,16 +100,15 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/3-0062/module_present_{0}" port_ps = path.format(cage_num) + content="0" try: val_file = open(port_ps) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True @@ -131,8 +130,7 @@ def get_low_power_mode_cpld(self, port_num): content = val_file.readline().rstrip() val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True diff --git a/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py index ba8e6181ebe8..7782f708fccd 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py @@ -167,16 +167,15 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/{0}/module_present_{1}" port_ps = path.format(cpld_ps, cage_num) + content = "0" try: val_file = open(port_ps) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True @@ -201,8 +200,7 @@ def get_low_power_mode_cpld(self, port_num): content = val_file.readline().rstrip() val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True diff --git a/device/accton/x86_64-accton_as6712_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as6712_32x-r0/plugins/sfputil.py index 661ecc72243e..6889280608fb 100644 --- a/device/accton/x86_64-accton_as6712_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as6712_32x-r0/plugins/sfputil.py @@ -127,16 +127,15 @@ def get_presence(self, port_num): self.__port_to_is_present = present_path + content="0" try: val_file = open(self.__port_to_is_present) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True @@ -150,16 +149,15 @@ def get_low_power_mode_cpld(self, port_num): _path = cpld_path + "/module_lp_mode_" _path += str(self._port_to_i2c_mapping[port_num][0]) + content="0" try: reg_file = open(_path) + content = reg_file.readline().rstrip() + reg_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = reg_file.readline().rstrip() - reg_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py index 4f0e4ef8273c..3562043ad9fc 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py @@ -126,14 +126,15 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" port_ps = path.format(self._port_to_i2c_mapping[port_num]) - + reg_value = '0' try: reg_file = open(port_ps) + reg_value = reg_file.readline().rstrip() + reg_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - reg_value = reg_file.readline().rstrip() + if reg_value == '1': return True diff --git a/device/accton/x86_64-accton_as7212_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7212_54x-r0/plugins/sfputil.py index fa706867a585..92ba72507285 100755 --- a/device/accton/x86_64-accton_as7212_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7212_54x-r0/plugins/sfputil.py @@ -97,14 +97,15 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" port_ps = path.format(self.port_to_i2c_mapping[port_num+1]) - + reg_value = '0' try: reg_file = open(port_ps) + reg_value = reg_file.readline().rstrip() + reg_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - reg_value = reg_file.readline().rstrip() + if reg_value == '1': return True diff --git a/device/accton/x86_64-accton_as7312_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7312_54x-r0/plugins/sfputil.py index a1785fde5532..52b57e210ebb 100644 --- a/device/accton/x86_64-accton_as7312_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7312_54x-r0/plugins/sfputil.py @@ -142,16 +142,15 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/{0}/module_present_{1}" port_ps = path.format(cpld_ps, port_num) + content = "0" try: val_file = open(port_ps) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7312_54xs-r0/plugins/sfputil.py index a1785fde5532..90349ff53908 100644 --- a/device/accton/x86_64-accton_as7312_54xs-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7312_54xs-r0/plugins/sfputil.py @@ -142,15 +142,15 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/{0}/module_present_{1}" port_ps = path.format(cpld_ps, port_num) + content = "0" try: val_file = open(port_ps) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - content = val_file.readline().rstrip() - val_file.close() - # content is a string, either "0" or "1" if content == "1": return True diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7315_27xb-r0/plugins/sfputil.py index 1d777d25aee7..dc37f5ea360c 100644 --- a/device/accton/x86_64-accton_as7315_27xb-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7315_27xb-r0/plugins/sfputil.py @@ -114,16 +114,15 @@ def get_presence(self, port_num): index = ((port_num-1)%24) +1 port_ps = path.format(cpld_ps, index) + content = "0" try: val_file = open(port_ps) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True diff --git a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py index b88536ecfeb2..553e48fdd2a9 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py @@ -145,16 +145,15 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/{0}/module_present_{1}" port_ps = path.format(cpld_ps, port_num) + content="0" try: val_file = open(port_ps) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" if content == "1": return True diff --git a/device/accton/x86_64-accton_as7512_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7512_32x-r0/plugins/sfputil.py index d18e9295f49a..a4f405fa6afd 100644 --- a/device/accton/x86_64-accton_as7512_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7512_32x-r0/plugins/sfputil.py @@ -39,14 +39,15 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" port_ps = path.format(port_num+18) - + reg_value = '0' try: reg_file = open(port_ps) + reg_value = reg_file.readline().rstrip() + reg_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - reg_value = reg_file.readline().rstrip() + if reg_value == '1': return True diff --git a/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py index 2b8d61ef42e3..8cfde932e7e3 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py @@ -96,13 +96,15 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/4-0060/module_present_{0}" port_ps = path.format(port_num) + reg_value = '0' try: reg_file = open(port_ps) + reg_value = reg_file.readline().rstrip() + reg_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - reg_value = reg_file.readline().rstrip() + if reg_value == '1': return True diff --git a/device/accton/x86_64-accton_as7716_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7716_32x-r0/plugins/sfputil.py index 96637e85a0f8..b8e4e8d1317d 100755 --- a/device/accton/x86_64-accton_as7716_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7716_32x-r0/plugins/sfputil.py @@ -97,16 +97,15 @@ def get_presence(self, port_num): present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num) self.__port_to_is_present = present_path + content = "0" try: val_file = open(self.__port_to_is_present) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7716_32xb-r0/plugins/sfputil.py index b582602fa9b5..8bc5869e6b94 100755 --- a/device/accton/x86_64-accton_as7716_32xb-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7716_32xb-r0/plugins/sfputil.py @@ -87,16 +87,15 @@ def get_presence(self, port_num): present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num+1) self.__port_to_is_present = present_path + content = "0" try: val_file = open(self.__port_to_is_present) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - # content is a string, either "0" or "1" if content == "1": return True diff --git a/device/accton/x86_64-accton_as7726_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7726_32x-r0/plugins/sfputil.py index 04a0388daab8..f8ef438af954 100755 --- a/device/accton/x86_64-accton_as7726_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7726_32x-r0/plugins/sfputil.py @@ -100,16 +100,15 @@ def get_presence(self, port_num): present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num) self.__port_to_is_present = present_path + content="0" try: val_file = open(self.__port_to_is_present) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - - # content is a string, either "0" or "1" + if content == "1": return True diff --git a/device/accton/x86_64-accton_as7816_64x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7816_64x-r0/plugins/sfputil.py index b5e76ec8385a..afb6f0c74147 100644 --- a/device/accton/x86_64-accton_as7816_64x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7816_64x-r0/plugins/sfputil.py @@ -122,13 +122,15 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/19-0060/module_present_{0}" port_ps = path.format(port_num) + reg_value = '0' try: reg_file = open(port_ps) + reg_value = reg_file.readline().rstrip() + reg_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - - reg_value = reg_file.readline().rstrip() + if reg_value == '1': return True diff --git a/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py index 17799035963e..bc3297471c5c 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py @@ -98,15 +98,15 @@ def get_presence(self, port_num): present_path = self.BASE_CPLD2_PATH + "module_present_" + str(port_num+1) self.__port_to_is_present = present_path + content="0" try: val_file = open(self.__port_to_is_present) + content = val_file.readline().rstrip() + val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to access file: %s" % str(e) return False - content = val_file.readline().rstrip() - val_file.close() - if content == "1": return True From 91e5fb56027e04fdc1082e867f3c0f90dd1923f0 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 7 Feb 2020 12:34:07 -0800 Subject: [PATCH 0354/1427] [Service] Enable/disable container auto-restart based on configuration. (#4073) --- .../docker-dhcp-relay.supervisord.conf.j2 | 2 +- dockers/docker-lldp-sv2/supervisord.conf | 2 +- dockers/docker-orchagent/supervisord.conf | 2 +- .../docker-pmon.supervisord.conf.j2 | 2 +- .../docker-router-advertiser.supervisord.conf | 2 +- dockers/docker-sflow/supervisord.conf | 2 +- dockers/docker-snmp-sv2/supervisord.conf | 2 +- .../docker-sonic-telemetry/supervisord.conf | 2 +- dockers/docker-teamd/supervisord.conf | 2 +- files/scripts/supervisor-proc-exit-listener | 42 +++++++++++++++++-- .../docker-syncd-bfn/supervisord.conf | 6 +++ .../docker-syncd-brcm/supervisord.conf | 2 +- .../cavium/docker-syncd-cavm/supervisord.conf | 2 +- .../docker-syncd-centec/supervisord.conf | 2 +- .../docker-syncd-mrvl/supervisord.conf | 6 +++ .../docker-syncd-mrvl/supervisord.conf | 6 +++ .../docker-syncd-mrvl/supervisord.conf | 2 +- .../docker-syncd-mlnx/supervisord.conf | 2 +- .../docker-syncd-nephos/supervisord.conf | 2 +- .../docker-dhcp-relay.supervisord.conf | 2 +- 20 files changed, 72 insertions(+), 20 deletions(-) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index 94fdbfdaff2f..d52400480775 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-lldp-sv2/supervisord.conf b/dockers/docker-lldp-sv2/supervisord.conf index 3f3f5beabc8d..73ff52f4420e 100644 --- a/dockers/docker-lldp-sv2/supervisord.conf +++ b/dockers/docker-lldp-sv2/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name lldp events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 9ae2776f6d26..6b21d73f3c81 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name swss events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index 9a2414c30d05..13ae0e767ab2 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name pmon events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf index 4ea84ab11c92..bf9320acc776 100644 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-script] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name radv events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-sflow/supervisord.conf b/dockers/docker-sflow/supervisord.conf index 50986f197d88..8eb1bdc05e57 100644 --- a/dockers/docker-sflow/supervisord.conf +++ b/dockers/docker-sflow/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name sflow events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-snmp-sv2/supervisord.conf b/dockers/docker-snmp-sv2/supervisord.conf index 7fd16eec5bbe..992292330552 100644 --- a/dockers/docker-snmp-sv2/supervisord.conf +++ b/dockers/docker-snmp-sv2/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name snmp events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index e1346fe7db4e..54f4c5b2348d 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name telemetry events=PROCESS_STATE_EXITED autostart=true autorestart=false diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index 43d6d2d6d116..0c3071bbfdda 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name teamd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index 8d1735cd2b0c..cf26d5383074 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -1,17 +1,34 @@ #!/usr/bin/env python +import getopt import os import signal import sys import syslog +import swsssdk + from supervisor import childutils # Contents of file should be the names of critical processes (as defined in # supervisor.conf file), one per line CRITICAL_PROCESSES_FILE = '/etc/supervisor/critical_processes' -def main(): +# This table in databse contains the features for container and each +# feature for a row will be configured a state or number. +CONTAINER_FEATURE_TABLE_NAME = 'CONTAINER_FEATURE' + +def main(argv): + container_name = None + opts, args = getopt.getopt(argv, "c:", ["container-name="]) + for opt, arg in opts: + if opt in ("-c", "--container-name"): + container_name = arg + + if not container_name: + syslog.syslog(syslog.LOG_ERR, "Container name not specified. Exiting...") + sys.exit(1) + # Read the list of critical processes from a file with open(CRITICAL_PROCESSES_FILE, 'r') as f: critical_processes = [line.rstrip('\n') for line in f] @@ -35,12 +52,29 @@ def main(): processname = payload_headers['processname'] groupname = payload_headers['groupname'] - # If a critical process exited unexpectedly, terminate supervisor - if expected == 0 and processname in critical_processes or groupname in critical_processes: + config_db = swsssdk.ConfigDBConnector() + config_db.connect() + container_features_table = config_db.get_table(CONTAINER_FEATURE_TABLE_NAME) + if not container_features_table: + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve container features table from Config DB. Exiting...") + sys.exit(2) + + if not container_features_table.has_key(container_name): + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve features for container '{}'. Exiting...".format(container_name)) + sys.exit(3) + + restart_feature = container_features_table[container_name].get('auto_restart') + if not restart_feature: + syslog.syslog(syslog.LOG_ERR, "Unable to determine auto-restart feature status for container '{}'. Exiting...".format(container_name)) + sys.exit(4) + + # If auto-restart feature is enabled and a critical process exited unexpectedly, terminate supervisor + if restart_feature == 'enabled' and expected == 0 and (processname in critical_processes or groupname in critical_processes): MSG_FORMAT_STR = "Process {} exited unxepectedly. Terminating supervisor..." msg = MSG_FORMAT_STR.format(payload_headers['processname']) syslog.syslog(syslog.LOG_INFO, msg) os.kill(os.getppid(), signal.SIGTERM) + if __name__ == "__main__": - main() + main(sys.argv[1:]) diff --git a/platform/barefoot/docker-syncd-bfn/supervisord.conf b/platform/barefoot/docker-syncd-bfn/supervisord.conf index 1e015fef931f..1744d6ffefb5 100644 --- a/platform/barefoot/docker-syncd-bfn/supervisord.conf +++ b/platform/barefoot/docker-syncd-bfn/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index cd6712acbf22..3fa8febb85d8 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/cavium/docker-syncd-cavm/supervisord.conf b/platform/cavium/docker-syncd-cavm/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/cavium/docker-syncd-cavm/supervisord.conf +++ b/platform/cavium/docker-syncd-cavm/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/centec/docker-syncd-centec/supervisord.conf b/platform/centec/docker-syncd-centec/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/centec/docker-syncd-centec/supervisord.conf +++ b/platform/centec/docker-syncd-centec/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf index 1af5d70a1d0c..b11e045fac7e 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf index 1af5d70a1d0c..b11e045fac7e 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/platform/marvell/docker-syncd-mrvl/supervisord.conf b/platform/marvell/docker-syncd-mrvl/supervisord.conf index aea4d45b9afd..43de2426f981 100644 --- a/platform/marvell/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell/docker-syncd-mrvl/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/mellanox/docker-syncd-mlnx/supervisord.conf b/platform/mellanox/docker-syncd-mlnx/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/nephos/docker-syncd-nephos/supervisord.conf b/platform/nephos/docker-syncd-nephos/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/nephos/docker-syncd-nephos/supervisord.conf +++ b/platform/nephos/docker-syncd-nephos/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index a29982a646f4..fde1d6c7714d 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected From 974e6e98c34b4d3adb9e926e0d07992d5903f998 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Sat, 8 Feb 2020 04:34:29 +0800 Subject: [PATCH 0355/1427] [daemon_base]fix error: syslog is not a member of DaemonBase (#4039) --- src/sonic-daemon-base/sonic_daemon_base/daemon_base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index a0a5bff0a297..d3807bf91524 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -102,15 +102,15 @@ def __init__(self): # Signal handler def signal_handler(self, sig, frame): if sig == signal.SIGHUP: - self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGHUP - ignoring...") + syslog.syslog(syslog.LOG_INFO, "Caught SIGHUP - ignoring...") elif sig == signal.SIGINT: - self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGINT - exiting...") + syslog.syslog(syslog.LOG_INFO, "Caught SIGINT - exiting...") sys.exit(128 + sig) elif sig == signal.SIGTERM: - self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGTERM - exiting...") + syslog.syslog(syslog.LOG_INFO, "Caught SIGTERM - exiting...") sys.exit(128 + sig) else: - self.syslog.syslog(self.syslog.LOG_WARNING, "Caught unhandled signal '" + sig + "'") + syslog.syslog(syslog.LOG_WARNING, "Caught unhandled signal '" + sig + "'") # Returns platform and hwsku def get_platform_and_hwsku(self): From 3bb61ab10c63c283e6e541e75f51cd016df64cc9 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 7 Feb 2020 12:35:35 -0800 Subject: [PATCH 0356/1427] [init_cfg.json] Maintain a separate init_cfg.json.j2 template file (#4092) --- files/build_templates/init_cfg.json.j2 | 20 +++++++++++++++++++ .../build_templates/sonic_debian_extension.j2 | 8 +++----- 2 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 files/build_templates/init_cfg.json.j2 diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 new file mode 100644 index 000000000000..33cfe990f900 --- /dev/null +++ b/files/build_templates/init_cfg.json.j2 @@ -0,0 +1,20 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "default_bgp_status": {% if shutdown_bgp_on_start == "y" %}"down"{% else %}"up"{% endif %}, + "default_pfcwd_status": {% if enable_pfcwd_on_start == "y" %}"enable"{% else %}"disable"{% endif %} + } + }, + "CRM": { + "Config": { + "polling_interval": "300", +{%- for crm_res in ["ipv4_route", "ipv6_route", "ipv4_nexthop", "ipv6_nexthop", "ipv4_neighbor", + "ipv6_neighbor", "nexthop_group_member", "nexthop_group", "acl_table", + "acl_group", "acl_entry", "acl_counter", "fdb_entry"] %} + "{{crm_res}}_threshold_type": "percentage", + "{{crm_res}}_low_threshold": "70", + "{{crm_res}}_high_threshold": "85"{% if not loop.last %},{% endif -%} +{% endfor %} + } + } +} diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index a32120bf8dc4..50f242a0a0c4 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -277,11 +277,9 @@ sudo bash -c "echo dhcp_as_static=true >> $FILESYSTEM_ROOT/etc/sonic/updategraph {% else %} sudo bash -c "echo enabled=false > $FILESYSTEM_ROOT/etc/sonic/updategraph.conf" {% endif %} -sudo bash -c "echo '{ \"DEVICE_METADATA\": { \"localhost\": { \"default_bgp_status\": {% if shutdown_bgp_on_start == "y" %}\"down\"{% else %}\"up\"{% endif %}, \"default_pfcwd_status\": {% if enable_pfcwd_on_start == "y" %}\"enable\"{% else %}\"disable\"{% endif %} } }, -{%- print ' \\"CRM\\": { \\"Config\\": { \\"polling_interval\\": \\"300\\", ' %} -{%- for crm_res in ["ipv4_route", "ipv6_route", "ipv4_nexthop", "ipv6_nexthop", "ipv4_neighbor", "ipv6_neighbor", "nexthop_group_member", "nexthop_group", "acl_table", "acl_group", "acl_entry", "acl_counter", "fdb_entry"] -%} -\"{{crm_res}}_threshold_type\": \"percentage\", \"{{crm_res}}_low_threshold\": \"70\", \"{{crm_res}}_high_threshold\": \"85\"{% if not loop.last %}, {% endif %} -{%- endfor %} } } }' >> $FILESYSTEM_ROOT/etc/sonic/init_cfg.json" + +# Generate initial SONiC configuration file +j2 files/build_templates/init_cfg.json.j2 | sudo tee $FILESYSTEM_ROOT/etc/sonic/init_cfg.json # Copy config-setup script and service file j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/config-setup.service From 5bf66af5a6d036032322f4277dbd526de3bcc948 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Sat, 8 Feb 2020 18:44:37 -0800 Subject: [PATCH 0357/1427] Update submodule: swss, swss-common (#4130) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Including commits in those repos: sonic-swss-common 7ee1179 2020-01-15 | Add unregister method to NetDispatcher (#326) [Kamil Cudnik] b080150 2019-12-19 | Add resultToString method for Select class (#325) [Kamil Cudnik] sonic-swss 412c5eb 2020-02-06 | Quote input strings before constructing a command line (#1193) [Qi Luo] 1215262 2020-02-06 | [DPB portsyncd/portmgrd/portorch] Support dynamic port add/deletion without dependencies (#1112) [zhenggen-xu] ddb84fb 2020-02-03 | [aclorch] Enable IN_PORTS ACL qualifier on MIRROR tables (#1176) [Danny Allen] 750982e 2020-01-30 | adding mirrorv6 support for mrvl platform (#1190) [B S Rama krishna] 73ab143 2020-01-29 | [pytest]: print out stdout/stderr message when cmd fails (#1188) [lguohan] 1883c0a 2020-01-29 | [vs tests] Remove class-level flaky fixtures (#1189) [Danny Allen] dc695fb 2020-01-29 | [orch] change Consumer class to support multiple values for the same key (#1184) [zhenggen-xu] 49ad38f 2020-01-30 | [orchagent/copp] : copp trap priority not supported for marvell platf… (#1163) [rajkumar38] cbe1811 2020-01-28 | Fix the stack-overflow issue in AclOrch::getTableById() (#1073) [zhenggen-xu] c6a8a04 2020-01-29 | [aclorch]: add support for acl rule to match out port (#810) [shine4chen] 8f4c54a 2020-01-29 | [qosorch] converting shaper bandwidth value to unsigned long instead of int (#1167) [Sabareesh-Kumar-Anandan] 84415f6 2020-01-28 | [vs tests] Activate flaky plugin for virtual switch pytests (#1186) [Danny Allen] 5eb1ea3 2020-01-28 | [qosorch]: Remove Init Color ACLs (#1084) [zhenggen-xu] --- src/sonic-swss | 2 +- src/sonic-swss-common | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-swss b/src/sonic-swss index 11fe6b520693..412c5ebd1762 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 11fe6b520693c31c5e1398274035e103d2977a31 +Subproject commit 412c5ebd1762f94afc51b1129f54a27a53f132bb diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 5b55954c5d6d..7ee11792342f 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 5b55954c5d6d4ae343af141357c3a2f6dd600c58 +Subproject commit 7ee11792342f2673ea6905952d556e3f9a27234d From ae491a9c47ae64cd876c11504ba8b2bd0ca9385f Mon Sep 17 00:00:00 2001 From: zhenggen-xu Date: Sun, 9 Feb 2020 20:34:55 -0800 Subject: [PATCH 0358/1427] [docker-lldp] Fix lldpcli issue when description has special characters (#4133) Before the fix: lldpcli configure ports Ethernet96 lldp portidsubtype local 'Eth1/1' description 50G|sonic1|Eth1/3/2 bash: sonic1: command not found bash: Eth1/3/2: No such file or directory After fix: lldpcli configure ports Ethernet96 lldp portidsubtype local 'Eth1/1' description '50G|sonic1|Eth1/3/2' run successfully. Signed-off-by: Zhenggen Xu --- dockers/docker-lldp-sv2/lldpmgrd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd index 36b6e67a5f47..7e9ef1642a06 100755 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ b/dockers/docker-lldp-sv2/lldpmgrd @@ -153,7 +153,7 @@ class LldpManager(object): # if there is a description available, also configure that if port_desc: - lldpcli_cmd += " description {}".format(port_desc) + lldpcli_cmd += " description '{}'".format(port_desc) else: log_info("Unable to retrieve description for port '{}'. Not adding port description".format(port_name)) From ab1a945cb9b362cb5ce46a70386156c3cc2f50d6 Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Mon, 10 Feb 2020 11:08:42 -0800 Subject: [PATCH 0359/1427] [procdockerstatsd] Fix incorrect case issue in service file (#4134) --- files/image_config/procdockerstatsd/procdockerstatsd.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/procdockerstatsd/procdockerstatsd.service b/files/image_config/procdockerstatsd/procdockerstatsd.service index 4e38c350a577..010dac15b2e6 100644 --- a/files/image_config/procdockerstatsd/procdockerstatsd.service +++ b/files/image_config/procdockerstatsd/procdockerstatsd.service @@ -6,7 +6,7 @@ After=database.service updategraph.service [Service] Type=simple ExecStart=/usr/bin/procdockerstatsd -Restart=Always +Restart=always [Install] WantedBy=multi-user.target From 1f4325e3bf188c6af1b1ffc43e2340e2e49f41d9 Mon Sep 17 00:00:00 2001 From: David Xiao <53024022+david-xk@users.noreply.github.com> Date: Mon, 10 Feb 2020 12:26:48 -0800 Subject: [PATCH 0360/1427] [Inventec][D6356] Update Inventec 6356 (#3839) * [Inventec][D6356] Update Inventec 6356 1.[Platform API] Add get_change_event implementation for Chassis class 2.[Platforn monitor] skip ledd to avoid pmon init failure --- .../led_proc_init.soc | 2 - .../pmon_daemon_control.json | 4 + .../d6356/sonic_platform/chassis.py | 36 ++++++ .../d6356/sonic_platform/transceiver_event.py | 116 ++++++++++++++++++ .../debian/platform-modules-d6356.init | 32 +++-- 5 files changed, 170 insertions(+), 20 deletions(-) create mode 100644 device/inventec/x86_64-inventec_d6356-r0/pmon_daemon_control.json create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/transceiver_event.py diff --git a/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc b/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc index 01b49772c0ba..55c82d388da8 100644 --- a/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc +++ b/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc @@ -1,5 +1,3 @@ -#led auto off -#led stop m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin led auto on diff --git a/device/inventec/x86_64-inventec_d6356-r0/pmon_daemon_control.json b/device/inventec/x86_64-inventec_d6356-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py index 761d21cf46ce..f961cb8cde21 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py @@ -14,6 +14,7 @@ from sonic_platform.sfp import Sfp from sonic_platform.qsfp import QSfp from sonic_platform.thermal import Thermal + from sonic_platform.transceiver_event import TransceiverEvent except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -53,6 +54,8 @@ def __init__(self): thermal = Thermal(index) self._thermal_list.append(thermal) + # Initialize TRANSCEIVER EVENT MONITOR + self.__xcvr_event = TransceiverEvent() ############################################## # Device methods @@ -147,3 +150,36 @@ def get_reboot_cause(self): to pass a description of the reboot cause. """ raise NotImplementedError + +############################################## +# Other methods +############################################## + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + + rc, xcvr_event = self.__xcvr_event.get_transceiver_change_event(timeout) + + return rc, {'sfp': xcvr_event} + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/transceiver_event.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/transceiver_event.py new file mode 100644 index 000000000000..3eda411de3ba --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/transceiver_event.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# +# Name: transceiver_event.py, version: 1.0 +# + +try: + import time + import socket + import re + import os + from collections import OrderedDict +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class NetlinkEventMonitor(object): + __instance = None + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + # print(cls) + cls.__instance = super(NetlinkEventMonitor, cls).__new__(cls) + cls.__instance.__recieved_events = OrderedDict() + return cls.__instance + + def __init__(self, timeout): + # print('__init__', self) + NETLINK_KOBJECT_UEVENT = 15 + self.__socket = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT) + self.__timeout = timeout + + def start(self): + # print('start', self.__timeout) + self.__socket.bind((os.getpid(), -1)) + if 0 == self.__timeout: + self.__socket.settimeout(None) + else: + self.__socket.settimeout(self.__timeout/1000.0) + + def stop(self): + self.__socket.close() + + def __enter__(self): + # print('__enter__', self) + self.start() + return self + + def __exit__(self, exc_type, exc_value, traceback): + # print('__exit__', self) + self.stop() + + def __iter__(self): + # print('__iter__', self) + while True: + for item in self.next_events(): + yield item + + def next_events(self): + try: + data = self.__socket.recv(16384) + event = {} + for item in data.split(b'\x00'): + if not item: + # check if we have an event and if we already received it + if event and 'SEQNUM' in event: + event_seqnum = event['SEQNUM'] + if event_seqnum in self.__recieved_events: + pass + else: + # print("=", event_seqnum) + self.__recieved_events[event_seqnum] = event + length = len(self.__recieved_events) + # print("=", length) + if (length > 100): + self.__recieved_events.popitem(last=False) + yield event + event = {} + else: + try: + k, v = item.split(b'=', 1) + event[k.decode('ascii')] = v.decode('ascii') + # print("=",k,v) + except ValueError: + pass + except Exception: + yield {} + +class TransceiverEvent(object): + + def __init__(self): + pass + + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + with NetlinkEventMonitor(timeout) as netlink_monitor: + for event in netlink_monitor: + if event and 'SUBSYSTEM' in event: + if event['SUBSYSTEM'] == 'swps': + #print('SWPS event. From %s, ACTION %s, IF_TYPE %s, IF_LANE %s' % (event['DEVPATH'], event['ACTION'], event['IF_TYPE'], event['IF_LANE'])) + portname = event['DEVPATH'].split("/")[-1] + rc = re.match(r"port(?P\d+)",portname) + if rc is not None: + if event['ACTION'] == "remove": + remove_num = int(rc.group("num")) + port_dict[remove_num] = "0" + elif event['ACTION'] == "add": + add_num = int(rc.group("num")) + port_dict[add_num] = "1" + return True, port_dict + else: + return False, {} + else: + pass + else: + return True, {} + diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.init b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.init index eaeb97406a1c..6d0f785fcd14 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.init +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.init @@ -29,30 +29,26 @@ do_monitor_stop() { case "$1" in start) - echo -n "Setting up board... " - -# depmod -a - /usr/local/bin/inventec_d6356_util.py -f install - do_monitor_${1} - echo "done." - ;; + echo -n "Setting up board... " + /usr/local/bin/inventec_d6356_util.py -f install + do_monitor_${1} + echo "done." + ;; stop) - - /usr/local/bin/inventec_d6356_util.py -f clean - do_monitor_${1} - echo "done." - - ;; + /usr/local/bin/inventec_d6356_util.py -f clean + do_monitor_${1} + echo "done." + ;; force-reload|restart) - echo "Not supported" - ;; + echo "Not supported" + ;; *) - echo "Usage: /etc/init.d/platform-modules-d6356.init {start|stop}" - exit 1 - ;; + echo "Usage: /etc/init.d/platform-modules-d6356.init {start|stop}" + exit 1 + ;; esac exit 0 From 51fa5e4666fca83816b4e022dcb1989af4d3ae0c Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 10 Feb 2020 17:16:42 -0800 Subject: [PATCH 0361/1427] [sonic-buildimage] Fix build issue for docker-dhcp-relay-dbg.gz. Issue (#4136) is coming becuase some of debian package not able to fetch. Signed-off-by: Abhishek --- build_debug_docker_j2.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_debug_docker_j2.sh b/build_debug_docker_j2.sh index 3655ac037bd6..0b167cf0f39e 100755 --- a/build_debug_docker_j2.sh +++ b/build_debug_docker_j2.sh @@ -28,7 +28,7 @@ debs/{{ deb }}{{' '}} {% if $3 is defined %} {% if $3|length %} -RUN apt-get install -f -y \ +RUN apt-get update && apt-get install -f -y \ {% for dbg in $3.split(' ') -%} {{ dbg }}{{' '}} {%- endfor %} From e069e44d05474c0ced28916d2f89d4b51867a16e Mon Sep 17 00:00:00 2001 From: Tony Titus <49417625+tonytitus@users.noreply.github.com> Date: Tue, 11 Feb 2020 06:09:29 -0800 Subject: [PATCH 0362/1427] Add Innovium 201911 build support (#4113) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2ce3de9ca5f4..f9cef7fba212 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ P4: [![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimag VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all) *201911*: +Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/) Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/) Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/) VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911) From af44856d5c7d6f197e19561ef893fe0294852f20 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 12 Feb 2020 01:54:12 +0800 Subject: [PATCH 0363/1427] [process-reboot-cause]Clean up the process-reboot-cause as reqired in issue 3927 (#4128) --- .../process-reboot-cause/process-reboot-cause | 121 +++++++++++------- 1 file changed, 74 insertions(+), 47 deletions(-) diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause index e5d228b4c6b6..409deb7d6859 100755 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -62,10 +62,10 @@ def parse_warmfast_reboot_from_proc_cmdline(): if os.path.isfile(REBOOT_TYPE_KEXEC_FILE): with open(REBOOT_TYPE_KEXEC_FILE, "r") as cause_file: cause_file_kexec = cause_file.readline() - m = re.match(REBOOT_TYPE_KEXEC_PATTERN_WARM, cause_file_kexec) + m = re.search(REBOOT_TYPE_KEXEC_PATTERN_WARM, cause_file_kexec) if m and m.group(1): return 'warm-reboot' - m = re.match(REBOOT_TYPE_KEXEC_PATTERN_FAST, cause_file_kexec) + m = re.search(REBOOT_TYPE_KEXEC_PATTERN_FAST, cause_file_kexec) if m and m.group(1): return 'fast-reboot' return None @@ -77,13 +77,61 @@ def find_software_reboot_cause(): if os.path.isfile(REBOOT_CAUSE_FILE): with open(REBOOT_CAUSE_FILE, "r") as cause_file: software_reboot_cause = cause_file.readline().rstrip('\n') + log_info("{} indicates the reboot cause: {}".format(REBOOT_CAUSE_FILE, software_reboot_cause)) + else: + log_info("Reboot cause file {} not found".format(REBOOT_CAUSE_FILE)) if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): os.remove(FIRST_BOOT_PLATFORM_FILE) return software_reboot_cause + + +def find_proc_cmdline_reboot_cause(): + proc_cmdline_reboot_cause = parse_warmfast_reboot_from_proc_cmdline() + if proc_cmdline_reboot_cause: + log_info("/proc/cmdline indicates reboot type: {}".format(proc_cmdline_reboot_cause)) + else: + log_info("No reboot cause found from /proc/cmdline") + return proc_cmdline_reboot_cause + + +def find_hardware_reboot_cause(): + hardware_reboot_cause = None + + # Until all platform vendors have provided sonic_platform packages, + # if there is no sonic_platform package installed, we only provide + # software-related reboot causes. + try: + import sonic_platform + + platform = sonic_platform.platform.Platform() + + chassis = platform.get_chassis() + + hardware_reboot_cause_major, hardware_reboot_cause_minor = chassis.get_reboot_cause() + + if hardware_reboot_cause_major == chassis.REBOOT_CAUSE_NON_HARDWARE: + # The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will + # contain any software-related reboot info. We will use it as the previous cause. + pass + elif hardware_reboot_cause_major == chassis.REBOOT_CAUSE_HARDWARE_OTHER: + hardware_reboot_cause = "{} ({})".format(hardware_reboot_cause_major, hardware_reboot_cause_minor) + else: + hardware_reboot_cause = hardware_reboot_cause_major + except ImportError as err: + log_warning("sonic_platform package not installed. Unable to detect hardware reboot causes.") + + if hardware_reboot_cause: + log_info("Platform api indicates reboot cause {}".format(hardware_reboot_cause)) + else: + log_info("No reboot cause found from platform api") + + return hardware_reboot_cause + + def main(): log_info("Starting up...") @@ -99,54 +147,33 @@ def main(): if os.path.exists(PREVIOUS_REBOOT_CAUSE_FILE): os.remove(PREVIOUS_REBOOT_CAUSE_FILE) - # Set a default previous reboot cause previous_reboot_cause = UNKNOWN_REBOOT_CAUSE - # Until all platform vendors have provided sonic_platform packages, - # if there is no sonic_platform package installed, we only provide - # software-related reboot causes. - try: - import sonic_platform - - # 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline - # If yes, the content of /hosts/reboot-cause/reboot-cause.txt will be treated as the reboot cause - proc_cmdline_reboot_cause = parse_warmfast_reboot_from_proc_cmdline() - if proc_cmdline_reboot_cause: - log_info("/proc/cmdline indicates reboot type: {}".format(proc_cmdline_reboot_cause)) - if os.path.isfile(REBOOT_CAUSE_FILE): - with open(REBOOT_CAUSE_FILE, "r") as cause_file: - proc_cmdline_reboot_cause = cause_file.readline().rstrip('\n') - else: - # /proc/cmdline says it's a warm/fast reboot but /host/reboot-cause.txt doesn't exist. - # This could happen when upgrading from a version doesn't support reboot cause. - log_info("Reboot cause file {} doesn't exist".format(REBOOT_CAUSE_DIR)) - - if proc_cmdline_reboot_cause is not None: - previous_reboot_cause = proc_cmdline_reboot_cause - else: - # 2. Check if the previous reboot was caused by hardware - # If yes, the hardware reboot cause will be treated as the reboot cause - platform = sonic_platform.platform.Platform() - - chassis = platform.get_chassis() - - hardware_reboot_cause, optional_details = chassis.get_reboot_cause() - - if hardware_reboot_cause == chassis.REBOOT_CAUSE_NON_HARDWARE: - # The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will - # contain any software-related reboot info. We will use it as the previous cause. - previous_reboot_cause = find_software_reboot_cause() - elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER: - previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details) - else: - previous_reboot_cause = hardware_reboot_cause - except ImportError as err: - log_warning("sonic_platform package not installed. Unable to detect hardware reboot causes.") - - # If there is a REBOOT_CAUSE_FILE, it will contain any software-related - # reboot info. We will use it as the previous cause. - previous_reboot_cause = find_software_reboot_cause() + # 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline + proc_cmdline_reboot_cause = find_proc_cmdline_reboot_cause() + + # 2. Check if the previous reboot was caused by hardware + # If yes, the hardware reboot cause will be treated as the reboot cause + hardware_reboot_cause = find_hardware_reboot_cause() + + # 3. If there is a REBOOT_CAUSE_FILE, it will contain any software-related + # reboot info. We will use it as the previous cause. + software_reboot_cause = find_software_reboot_cause() + + # The main decision logic of the reboot cause: + # If there is a reboot cause indicated by /proc/cmdline, it should be warmreboot/fastreboot + # the software_reboot_cause which is the content of /hosts/reboot-cause/reboot-cause.txt + # will be treated as the reboot cause + # Elif there is a reboot cause indicated by platform API, + # the hardware_reboot_cause will be treated as the reboot cause + # Else the software_reboot_cause will be treated as the reboot cause + if proc_cmdline_reboot_cause is not None: + previous_reboot_cause = software_reboot_cause + elif hardware_reboot_cause is not None: + previous_reboot_cause = hardware_reboot_cause + else: + previous_reboot_cause = software_reboot_cause # Write the previous reboot cause to PREVIOUS_REBOOT_CAUSE_FILE with open(PREVIOUS_REBOOT_CAUSE_FILE, "w") as prev_cause_file: From fb59e9d753bf78f80bc5366339d9d0c2099f647d Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Tue, 11 Feb 2020 09:54:38 -0800 Subject: [PATCH 0364/1427] [mellanox] enable ISSU on SPC2 systems (#4087) Signed-off-by: Stepan Blyschak --- .../mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml | 3 +++ .../mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml index 8f6c427888b1..a7ac42950668 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 32 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml index 2d4c0f93d100..1b3c77ce381c 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 64 From 41958aad52b5d81a145fe1865178150f48811ad7 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Tue, 11 Feb 2020 11:05:21 -0800 Subject: [PATCH 0365/1427] [init_cfg.json] Add new FEATURE and CONTAINER_FEATURE tables (#4137) * [init_cfg.json] Add a new table CONTAINER_FEATURE. Signed-off-by: Yong Zhao * [init_cfg.json] Update the content of table CONTAINER_FEATURE. Signed-off-by: Yong Zhao * [init_cfg.json] Use the template to generate the table CONTAINER_FEATURE. Signed-off-by: Yong Zhao * [init_cfg.json] Add a new table FEATURE. Signed-off-by: Yong Zhao * [init_cfg.json] Change the order of container names according to alphabetical order. Signed-off-by: Yong Zhao * [init_cfg.json] Change the dhcp_relay container name and add rest-api. Signed-off-by: Yong Zhao --- files/build_templates/init_cfg.json.j2 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 33cfe990f900..bc2eff3ede56 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -16,5 +16,21 @@ "{{crm_res}}_high_threshold": "85"{% if not loop.last %},{% endif -%} {% endfor %} } + }, + "FEATURE": { +{%- for feature in ["sflow", "telemetry"] %} + "{{feature}}": { + "status": "disabled" + }{% if not loop.last %},{% endif -%} +{% endfor %} + }, + "CONTAINER_FEATURE": { +{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "pmon", "radv", "rest-api", "sflow", + "snmp", "swss", "syncd", "teamd", "telemetry"] %} + "{{container}}": { + "auto_restart": "disabled", + "high_mem_alert": "disabled" + }{% if not loop.last %},{% endif -%} +{% endfor %} } } From ae522238929a01cf4885fb940efc66d9a24e02b8 Mon Sep 17 00:00:00 2001 From: byu343 Date: Tue, 11 Feb 2020 13:19:07 -0800 Subject: [PATCH 0366/1427] [arista]: Add fancontrol for arista 7050cx3 (#4121) --- device/arista/x86_64-arista_7050cx3_32s/fancontrol | 10 ++++++++++ device/arista/x86_64-arista_7050cx3_32s/sensors.conf | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 device/arista/x86_64-arista_7050cx3_32s/fancontrol diff --git a/device/arista/x86_64-arista_7050cx3_32s/fancontrol b/device/arista/x86_64-arista_7050cx3_32s/fancontrol new file mode 100644 index 000000000000..913075f73d12 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/fancontrol @@ -0,0 +1,10 @@ +INTERVAL=5 +DEVPATH=hwmon4=devices/pci0000:00/0000:00:02.2/0000:02:00.0/i2c-11/11-004c hwmon3=devices/pci0000:00/0000:00:02.2/0000:02:00.0/i2c-2/2-0060 +DEVNAME=hwmon4=max6658 hwmon3=crow_cpld +FCTEMPS=hwmon3/pwm4=hwmon4/temp1_input hwmon3/pwm3=hwmon4/temp1_input hwmon3/pwm2=hwmon4/temp1_input hwmon3/pwm1=hwmon4/temp1_input +FCFANS=hwmon3/pwm4=hwmon3/fan4_input hwmon3/pwm3=hwmon3/fan3_input hwmon3/pwm2=hwmon3/fan2_input hwmon3/pwm1=hwmon3/fan1_input +MINTEMP=hwmon3/pwm4=40 hwmon3/pwm3=40 hwmon3/pwm2=40 hwmon3/pwm1=40 +MINPWM=hwmon3/pwm4=179 hwmon3/pwm3=179 hwmon3/pwm2=179 hwmon3/pwm1=179 +MAXTEMP=hwmon3/pwm4=50 hwmon3/pwm3=50 hwmon3/pwm2=50 hwmon3/pwm1=50 +MINSTART=hwmon3/pwm4=179 hwmon3/pwm3=179 hwmon3/pwm2=179 hwmon3/pwm1=179 +MINSTOP=hwmon3/pwm4=179 hwmon3/pwm3=179 hwmon3/pwm2=179 hwmon3/pwm1=179 diff --git a/device/arista/x86_64-arista_7050cx3_32s/sensors.conf b/device/arista/x86_64-arista_7050cx3_32s/sensors.conf index 9501656fb9aa..c63a526124d0 100644 --- a/device/arista/x86_64-arista_7050cx3_32s/sensors.conf +++ b/device/arista/x86_64-arista_7050cx3_32s/sensors.conf @@ -21,8 +21,8 @@ chip "max6658-i2c-2-4c" chip "max6658-i2c-11-4c" label temp1 "Board temp sensor" - set temp1_max 55 - set temp1_crit 70 + set temp1_max 75 + set temp1_crit 85 label temp2 "Front panel temp sensor" set temp2_max 60 From 729f343f7707bda59dcef020721e7b85f2fc5d84 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Tue, 11 Feb 2020 14:03:02 -0800 Subject: [PATCH 0367/1427] [Services] Restart database service upon unexpected critical process exit. (#4138) * [database] Implement the auto-restart feature for database container. Signed-off-by: Yong Zhao * [database] Remove the duplicate dependency in service files. Since we already have updategraph ---> config_setup ---> database, we do not need explicitly add database.service in all other container service files. Signed-off-by: Yong Zhao * [event listener] Reorganize the line 73 in event listener script. Signed-off-by: Yong Zhao * [database] update the file sflow.service.j2 to remove the duplicate dependency. Signed-off-by: Yong Zhao * [event listener] Add comments in event listener. Signed-off-by: Yong Zhao * [event listener] Update the comments in line 56. Signed-off-by: Yong Zhao * [event listener] Add parentheses for if statement in line 76 in event listener. Signed-off-by: Yong Zhao --- dockers/docker-database/Dockerfile.j2 | 2 + dockers/docker-database/critical_processes | 1 + dockers/docker-database/supervisord.conf.j2 | 7 ++++ .../single_instance/database.service.j2 | 4 ++ files/scripts/supervisor-proc-exit-listener | 40 ++++++++++--------- rules/docker-database.mk | 1 + 6 files changed, 37 insertions(+), 18 deletions(-) create mode 100644 dockers/docker-database/critical_processes diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index acb5e013fb84..8cd181614672 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -36,5 +36,7 @@ COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["docker-database-init.sh", "/usr/local/bin/"] COPY ["ping_pong_db_insts", "/usr/local/bin/"] COPY ["database_config.json", "/etc/default/sonic-db/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"] diff --git a/dockers/docker-database/critical_processes b/dockers/docker-database/critical_processes new file mode 100644 index 000000000000..7800f0fad3ff --- /dev/null +++ b/dockers/docker-database/critical_processes @@ -0,0 +1 @@ +redis diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index 110619f762be..442bec1438c8 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -3,6 +3,13 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name database +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + + [program:rsyslogd] command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n" priority=1 diff --git a/files/build_templates/single_instance/database.service.j2 b/files/build_templates/single_instance/database.service.j2 index 472b9d328b7d..fd0063195e31 100644 --- a/files/build_templates/single_instance/database.service.j2 +++ b/files/build_templates/single_instance/database.service.j2 @@ -3,12 +3,16 @@ Description=Database container Requires=docker.service After=docker.service After=rc-local.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User=root ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index cf26d5383074..cf154b3a5c10 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -52,24 +52,28 @@ def main(argv): processname = payload_headers['processname'] groupname = payload_headers['groupname'] - config_db = swsssdk.ConfigDBConnector() - config_db.connect() - container_features_table = config_db.get_table(CONTAINER_FEATURE_TABLE_NAME) - if not container_features_table: - syslog.syslog(syslog.LOG_ERR, "Unable to retrieve container features table from Config DB. Exiting...") - sys.exit(2) - - if not container_features_table.has_key(container_name): - syslog.syslog(syslog.LOG_ERR, "Unable to retrieve features for container '{}'. Exiting...".format(container_name)) - sys.exit(3) - - restart_feature = container_features_table[container_name].get('auto_restart') - if not restart_feature: - syslog.syslog(syslog.LOG_ERR, "Unable to determine auto-restart feature status for container '{}'. Exiting...".format(container_name)) - sys.exit(4) - - # If auto-restart feature is enabled and a critical process exited unexpectedly, terminate supervisor - if restart_feature == 'enabled' and expected == 0 and (processname in critical_processes or groupname in critical_processes): + # Read the status of auto-restart feature from Config_DB. + if container_name != 'database': + config_db = swsssdk.ConfigDBConnector() + config_db.connect() + container_features_table = config_db.get_table(CONTAINER_FEATURE_TABLE_NAME) + if not container_features_table: + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve container features table from Config DB. Exiting...") + sys.exit(2) + + if not container_features_table.has_key(container_name): + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve features for container '{}'. Exiting...".format(container_name)) + sys.exit(3) + + restart_feature = container_features_table[container_name].get('auto_restart') + if not restart_feature: + syslog.syslog(syslog.LOG_ERR, "Unable to determine auto-restart feature status for container '{}'. Exiting...".format(container_name)) + sys.exit(4) + + # If container is database or auto-restart feature is enabled and at the same time + # a critical process exited unexpectedly, terminate supervisor + if ((container_name == 'database' or restart_feature == 'enabled') and expected == 0 and + (processname in critical_processes or groupname in critical_processes)): MSG_FORMAT_STR = "Process {} exited unxepectedly. Terminating supervisor..." msg = MSG_FORMAT_STR.format(payload_headers['processname']) syslog.syslog(syslog.LOG_INFO, msg) diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 91fd06819a4b..7e372048afab 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -28,3 +28,4 @@ $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli $(DOCKER_DATABASE)_BASE_IMAGE_FILES += monit_database:/etc/monit/conf.d +$(DOCKER_DATABASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From 169cfe79bf290348f2ed6a3047c5f2283b058581 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Wed, 12 Feb 2020 05:04:05 +0530 Subject: [PATCH 0368/1427] [devices]: DellEMC:S5232 fix transceiver change event (#3924) --- device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py index d09f621ee882..be2d31a16afc 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py @@ -237,7 +237,7 @@ def reset(self, port_num): return True - def get_transceiver_change_event(self): + def get_transceiver_change_event(self, timeout=0): port_dict = {} while True: for port_num in range(self.port_start, (self.port_end + 1)): From fb3253329eee2c0cac7ecc96da2808c541b1c068 Mon Sep 17 00:00:00 2001 From: byu343 Date: Tue, 11 Feb 2020 18:44:25 -0800 Subject: [PATCH 0369/1427] [arista]: Fix convertfs condition for booting from EOS (#4139) Fix the issue of incorrectly skipping the convertfs hook when fast-reboot from EOS, by adding an extra kernel cmdline param "prev_os" to differentiate fast-reboot from EOS and from SONiC. This is because we still do disk conversion for fast reboot from eos to sonic, like format the disk. --- files/Aboot/boot0.j2 | 2 +- files/initramfs-tools/arista-convertfs.j2 | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index a916cef30e73..5a2f2555d1ea 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -383,7 +383,7 @@ write_boot_configs() { } run_kexec() { - local cmdline="$(cat $cmdline_image | tr '\n' ' ')" + local cmdline="$(cat $cmdline_image | tr '\n' ' ') $ENV_EXTRA_CMDLINE" local kernel="${KERNEL:-$(find $image_path/boot -name 'vmlinuz-*' -type f | head -n 1)}" local initrd="${INITRD:-$(find $image_path/boot -name 'initrd.img-*' -type f | head -n 1)}" diff --git a/files/initramfs-tools/arista-convertfs.j2 b/files/initramfs-tools/arista-convertfs.j2 index 535bb441f117..56616d2ba04a 100644 --- a/files/initramfs-tools/arista-convertfs.j2 +++ b/files/initramfs-tools/arista-convertfs.j2 @@ -18,6 +18,8 @@ flash_dev='' block_flash='' aboot_flag='' backup_file='' +prev_os='' +sonic_fast_reboot='' # Wait until get the fullpath of flash device, e.g., /dev/sda wait_get_flash_dev() { @@ -133,9 +135,11 @@ for x in "$@"; do docker_inram=*) docker_inram="${x#docker_inram=}" ;; + prev_os=*) + prev_os="${x#prev_os=}" + ;; SONIC_BOOT_TYPE=warm*|SONIC_BOOT_TYPE=fast*) - # Skip this script for warm-reboot and fast-reboot - exit 0 + sonic_fast_reboot=true ;; esac done @@ -143,6 +147,9 @@ done # Check aboot [ -z "$aboot_flag" ] && exit 0 +# Skip this script for warm-reboot/fast-reboot from sonic +[ "$sonic_fast_reboot" == true ] && [ "$prev_os" != eos ] && exit 0 + # Get flash dev name if [ -z "$block_flash" ]; then echo "Error: flash device info is not provided" From a9f3619901dad39d140e41540452140f25125847 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Wed, 12 Feb 2020 16:38:45 -0800 Subject: [PATCH 0370/1427] Start RestAPI container when sonic boots (#4140) * Start RestAPI container when sonic boots --- files/build_templates/restapi.service.j2 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 files/build_templates/restapi.service.j2 diff --git a/files/build_templates/restapi.service.j2 b/files/build_templates/restapi.service.j2 new file mode 100644 index 000000000000..df1a50eb56c7 --- /dev/null +++ b/files/build_templates/restapi.service.j2 @@ -0,0 +1,16 @@ +[Unit] +Description=RestAPI container +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target \ No newline at end of file From 6a0dcb1b16c767be9a47240a926244440a1625e7 Mon Sep 17 00:00:00 2001 From: Olivier Singla <47356901+olivier-singla@users.noreply.github.com> Date: Wed, 12 Feb 2020 20:41:58 -0500 Subject: [PATCH 0371/1427] [kernel]: security kernel update to 4.9.189 (#3913) This patch upgrade the kernel from version 4.9.0-9-2 (4.9.168-1+deb9u3) to 4.9.0-11-2 (4.9.189-3+deb9u2) Co-authored-by: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> --- build_debian.sh | 2 +- .../build_templates/single_instance/swss.service.j2 | 2 +- .../build_templates/single_instance/syncd.service.j2 | 4 ++-- installer/x86_64/install.sh | 4 ++-- platform/barefoot/bfn-modules/debian/control | 2 +- .../debian/control | 2 +- .../debian/control | 2 +- .../sonic-platform-modules-bfn/debian/control | 2 +- platform/broadcom/sai-modules.mk | 2 +- platform/broadcom/saibcm-modules/debian/control | 2 +- .../saibcm-modules/debian/opennsl-modules.dirs | 2 +- .../saibcm-modules/debian/opennsl-modules.install | 10 +++++----- platform/broadcom/saibcm-modules/debian/rules | 6 +++--- .../debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 8 ++++---- .../sonic-platform-modules-dell/debian/control | 12 ++++++------ .../sonic-platform-modules-delta/debian/control | 10 +++++----- .../debian/platform-modules-et-6248brb.init | 2 +- .../et-6248brb/scripts/led_status.sh | 2 +- .../d6356/utils/inventec_d6356_util.py | 2 +- .../sonic-platform-modules-inventec/debian/control | 12 ++++++------ .../sonic-platform-modules-e582/debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 2 +- .../sonic-platform-modules-delta/debian/control | 2 +- platform/marvell-armhf/linux-kernel-armhf.mk | 2 +- platform/nephos/nephos-modules.mk | 2 +- platform/nephos/nephos-modules/debian/control | 2 +- .../modules/init.d/nps-modules-4.9.0-9-2-amd64 | 2 +- .../service/nps-modules-4.9.0-9-2-amd64.service | 4 ++-- .../sonic-platform-modules-accton/debian/control | 4 ++-- rules/linux-kernel.mk | 6 +++--- src/sonic-linux-kernel | 2 +- 32 files changed, 63 insertions(+), 63 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index b51994e615dc..5b9a8e25adb0 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -37,7 +37,7 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then else DOCKER_VERSION=5:18.09.8~3-0~debian-stretch fi -LINUX_KERNEL_VERSION=4.9.0-9-2 +LINUX_KERNEL_VERSION=4.9.0-11-2 ## Working directory to prepare the file system FILESYSTEM_ROOT=./fsroot diff --git a/files/build_templates/single_instance/swss.service.j2 b/files/build_templates/single_instance/swss.service.j2 index b7a6396749bd..44206b08ebce 100644 --- a/files/build_templates/single_instance/swss.service.j2 +++ b/files/build_templates/single_instance/swss.service.j2 @@ -4,7 +4,7 @@ Requires=database.service updategraph.service {% if sonic_asic_platform == 'broadcom' %} Requires=opennsl-modules.service {% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-9-2-amd64.service +Requires=nps-modules-4.9.0-11-2-amd64.service {% endif %} After=database.service updategraph.service After=interfaces-config.service diff --git a/files/build_templates/single_instance/syncd.service.j2 b/files/build_templates/single_instance/syncd.service.j2 index b52772e9b114..7a7d27114b07 100644 --- a/files/build_templates/single_instance/syncd.service.j2 +++ b/files/build_templates/single_instance/syncd.service.j2 @@ -4,14 +4,14 @@ Requires=database.service updategraph.service {% if sonic_asic_platform == 'broadcom' %} Requires=opennsl-modules.service {% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-9-2-amd64.service +Requires=nps-modules-4.9.0-11-2-amd64.service {% endif %} After=database.service updategraph.service After=interfaces-config.service {% if sonic_asic_platform == 'broadcom' %} After=opennsl-modules.service {% elif sonic_asic_platform == 'nephos' %} -After=nps-modules-4.9.0-9-2-amd64.service +After=nps-modules-4.9.0-11-2-amd64.service {% endif %} After=swss.service Before=ntp-config.service diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index 78e8e2f4623b..d0aa7818df9b 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -606,12 +606,12 @@ menuentry '$demo_grub_entry' { if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 - linux /$image_dir/boot/vmlinuz-4.9.0-9-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ + linux /$image_dir/boot/vmlinuz-4.9.0-11-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ net.ifnames=0 biosdevname=0 \ loop=$image_dir/$FILESYSTEM_SQUASHFS loopfstype=squashfs \ apparmor=1 security=apparmor varlog_size=$VAR_LOG_SIZE usbcore.autosuspend=-1 $ONIE_PLATFORM_EXTRA_CMDLINE_LINUX echo 'Loading $demo_volume_label $demo_type initial ramdisk ...' - initrd /$image_dir/boot/initrd.img-4.9.0-9-2-amd64 + initrd /$image_dir/boot/initrd.img-4.9.0-11-2-amd64 } EOF diff --git a/platform/barefoot/bfn-modules/debian/control b/platform/barefoot/bfn-modules/debian/control index c9a53ec1d08b..d6f7a991107d 100644 --- a/platform/barefoot/bfn-modules/debian/control +++ b/platform/barefoot/bfn-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: bfn-modules Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for bfn asic for mmap diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index 192da9dab95c..e3f5356f22db 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-montara Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control index edbc5b890c58..bc6c990efebb 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-newport Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index 04d4c598e9d9..cca87831f1f1 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index 1d559d0ad320..93132c2287bd 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,6 +1,6 @@ # Broadcom SAI modules -KVERSION = 4.9.0-9-2-amd64 +KVERSION = 4.9.0-11-2-amd64 BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb diff --git a/platform/broadcom/saibcm-modules/debian/control b/platform/broadcom/saibcm-modules/debian/control index 75b77c8a2f00..fafe7dfb9299 100644 --- a/platform/broadcom/saibcm-modules/debian/control +++ b/platform/broadcom/saibcm-modules/debian/control @@ -10,5 +10,5 @@ Standards-Version: 3.9.3 Package: opennsl-modules Architecture: amd64 Section: main -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for broadcom SAI diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs index 38af58a5c5ee..a32540eadcf5 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs @@ -1 +1 @@ -lib/modules/4.9.0-9-2-amd64/extra +lib/modules/4.9.0-11-2-amd64/extra diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index e16980dc2c0d..9802d2f2443a 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -1,6 +1,6 @@ -systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.9.0-9-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.9.0-11-2-amd64/extra systemd/opennsl-modules.service lib/systemd/system diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index 0092cc1a1027..636874251aa9 100755 --- a/platform/broadcom/saibcm-modules/debian/rules +++ b/platform/broadcom/saibcm-modules/debian/rules @@ -60,7 +60,7 @@ kdist_config: prep-deb-files kdist_clean: clean dh_testdir dh_clean - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean # rm -f driver/*.o driver/*.ko # ### end KERNEL SETUP @@ -78,7 +78,7 @@ build-arch-stamp: dh_testdir # Add here command to compile/build the package. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 touch $@ @@ -103,7 +103,7 @@ clean: rm -f build-arch-stamp build-indep-stamp configure-stamp # Add here commands to clean up after the build process. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean dh_clean diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control index 9a53b9823222..beba5b5f4e62 100644 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: sonic-platform-alphanetworks-snh60a0-320fv2 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-alphanetworks-snh60b0-640f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index ea39a49e7e12..d5dd43ee4918 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -7,21 +7,21 @@ Standards-Version: 3.9.3 Package: platform-modules-dx010 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-haliburton Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-seastone2 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as led, sfp Package: platform-modules-silverstone Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as led, sfp. diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index 3131890e6353..e4d5a24f3542 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -7,32 +7,32 @@ Standards-Version: 3.9.3 Package: platform-modules-s6000 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9100 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s6100 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9264f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5232f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5248f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9332f diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index 65b01234b4ec..e2e9883f9b2b 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -7,25 +7,25 @@ Standards-Version: 3.9.3 Package: platform-modules-ag9032v1 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9064 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag5648 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-et-6248brb Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9032v2a Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as syseeprom, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init index 64361ced6b6c..58681208ef6c 100755 --- a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init @@ -25,7 +25,7 @@ start) modprobe dni_gpio modprobe delta_et-6248brb_platform - if [ `uname -a | awk '{print $3}'` = "4.9.0-9-2-amd64" ]; then + if [ `uname -a | awk '{print $3}'` = "4.9.0-11-2-amd64" ]; then echo "453" > "/sys/class/gpio/export" echo "454" > "/sys/class/gpio/export" echo "455" > "/sys/class/gpio/export" diff --git a/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh b/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh index 734a44a6ca95..573af2156661 100644 --- a/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh +++ b/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh @@ -7,7 +7,7 @@ FAN2_RPM="/sys/bus/i2c/devices/0-002e/fan2_input" FAN_TRAY1_LED="/sys/devices/platform/delta-et6248brb-gpio.0/FAN/fan1_led_ag" FAN_TRAY2_LED="/sys/devices/platform/delta-et6248brb-gpio.0/FAN/fan2_led_ag" -if [ `uname -a | awk '{print $3}'` = "4.9.0-9-2-amd64" ]; then +if [ `uname -a | awk '{print $3}'` = "4.9.0-11-2-amd64" ]; then SYS_LED_G="/sys/class/gpio/gpio453/value" SYS_LED_R="/sys/class/gpio/gpio454/value" PWR_LED_G="/sys/class/gpio/gpio455/value" diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py index 890973cb8356..10fcb001b0c2 100755 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py @@ -141,7 +141,7 @@ def system_install(): status, output = exec_cmd("rmmod lpc_ich ", 1) #insert extra module - status, output = exec_cmd("insmod /lib/modules/4.9.0-9-2-amd64/kernel/drivers/gpio/gpio-ich.ko gpiobase=0",1) + status, output = exec_cmd("insmod /lib/modules/4.9.0-11-2-amd64/kernel/drivers/gpio/gpio-ich.ko gpiobase=0",1) #install drivers for i in range(0,len(drivers)): diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index 6cb61630823f..86f7e7b20f65 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-d7032q28b Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7054q28b Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6254qs Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6556 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6356 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7264q28b Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led diff --git a/platform/centec/sonic-platform-modules-e582/debian/control b/platform/centec/sonic-platform-modules-e582/debian/control index ba30e04f0388..c449246b2823 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/control +++ b/platform/centec/sonic-platform-modules-e582/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: platform-modules-e582-48x2q4z Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-e582-48x6q Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/innovium/sonic-platform-modules-cel/debian/control b/platform/innovium/sonic-platform-modules-cel/debian/control index 48ef777a99a6..543d381ab6f7 100755 --- a/platform/innovium/sonic-platform-modules-cel/debian/control +++ b/platform/innovium/sonic-platform-modules-cel/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: platform-modules-midstone-200i Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices diff --git a/platform/innovium/sonic-platform-modules-delta/debian/control b/platform/innovium/sonic-platform-modules-delta/debian/control index 71c403387f80..3fe3ffc9f526 100644 --- a/platform/innovium/sonic-platform-modules-delta/debian/control +++ b/platform/innovium/sonic-platform-modules-delta/debian/control @@ -7,7 +7,7 @@ Standards-Version: 3.9.3 Package: platform-modules-et-c032if Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/marvell-armhf/linux-kernel-armhf.mk b/platform/marvell-armhf/linux-kernel-armhf.mk index 32e8ea3c604a..4d52beac49d9 100644 --- a/platform/marvell-armhf/linux-kernel-armhf.mk +++ b/platform/marvell-armhf/linux-kernel-armhf.mk @@ -1,7 +1,7 @@ # linux kernel package for marvell armhf # Add platform specific DTB -LINUX_KERNEL_DTB = linux-image-4.9.168-armhf.deb +LINUX_KERNEL_DTB = linux-image-4.9.189-armhf.deb $(LINUX_KERNEL_DTB)_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/armhf/kernel/$(LINUX_KERNEL_DTB) SONIC_ONLINE_DEBS += $(LINUX_KERNEL_DTB) SONIC_STRETCH_DEBS += $(LINUX_KERNEL_DTB) diff --git a/platform/nephos/nephos-modules.mk b/platform/nephos/nephos-modules.mk index b76141b40663..ebd696217b8e 100644 --- a/platform/nephos/nephos-modules.mk +++ b/platform/nephos/nephos-modules.mk @@ -9,7 +9,7 @@ SDK_FROM_LOCAL = n endif SDK_VERSION = 3.0.0 -LINUX_VER = 4.9.0-9-2 +LINUX_VER = 4.9.0-11-2 SDK_COMMIT_ID = 529202 ifeq ($(SAI_FROM_LOCAL), y) diff --git a/platform/nephos/nephos-modules/debian/control b/platform/nephos/nephos-modules/debian/control index f5e6e00d13c0..246b89eab477 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: nephos-modules Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for nephos asic diff --git a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 b/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 index 366ca6b08456..a6deb4217a95 100755 --- a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 +++ b/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 @@ -45,7 +45,7 @@ force-reload|restart) ;; *) - echo "Usage: /etc/init.d/nps-modules-4.9.0-9-2-amd64.init {start|stop}" + echo "Usage: /etc/init.d/nps-modules-4.9.0-11-2-amd64.init {start|stop}" exit 1 ;; esac diff --git a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service index 246226ea9d40..9acdeb30a44c 100644 --- a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service +++ b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service @@ -5,8 +5,8 @@ Before=syncd.service [Service] Type=oneshot -ExecStart=-/etc/init.d/nps-modules-4.9.0-9-2-amd64 start -ExecStop=-/etc/init.d/nps-modules-4.9.0-9-2-amd64 stop +ExecStart=-/etc/init.d/nps-modules-4.9.0-11-2-amd64 start +ExecStop=-/etc/init.d/nps-modules-4.9.0-11-2-amd64 stop RemainAfterExit=yes [Install] diff --git a/platform/nephos/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control index 8f7258ebdd6a..639534f3edcc 100755 --- a/platform/nephos/sonic-platform-modules-accton/debian/control +++ b/platform/nephos/sonic-platform-modules-accton/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: sonic-platform-accton-as7116-54x Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 -Description: kernel modules for platform devices such as fan, led, sfp \ No newline at end of file +Depends: linux-image-4.9.0-11-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/rules/linux-kernel.mk b/rules/linux-kernel.mk index 5250f8b97e8f..e6742bdf14cf 100644 --- a/rules/linux-kernel.mk +++ b/rules/linux-kernel.mk @@ -1,9 +1,9 @@ # linux kernel package -KVERSION_SHORT = 4.9.0-9-2 +KVERSION_SHORT = 4.9.0-11-2 KVERSION = $(KVERSION_SHORT)-$(CONFIGURED_ARCH) -KERNEL_VERSION = 4.9.168 -KERNEL_SUBVERSION = 1+deb9u5 +KERNEL_VERSION = 4.9.189 +KERNEL_SUBVERSION = 3+deb9u2 ifeq ($(CONFIGURED_ARCH), armhf) # Override kernel version for ARMHF as it uses arm MP (multi-platform) for short version KVERSION = $(KVERSION_SHORT)-armmp diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 87576c061d10..66e9dfa59136 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 87576c061d10dfe7de8e8e5cc1bae6bd29b0143b +Subproject commit 66e9dfa591369782eff63f1de09818df3a941b29 From 427ed1f29ad2c70ab66712fc8f0133a4d30592d3 Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Thu, 13 Feb 2020 09:55:58 +0800 Subject: [PATCH 0372/1427] [platform]:Fix as7726 read thermal sensor issue (#4135) Due to linux create hwmonN node number, N isn't fixed. So modify to use "" to let thermal.py can correct sysfs. For example, use /sys/bus/i2c/devices/55-0048/hwmon/hwmon/temp1_input to instead of /sys/bus/i2c/devices/55-0048/hwmon/hwmon4/temp1_input --- .../as7726-32x/classes/thermalutil.py | 53 ++++++++----------- .../utils/accton_as7726_32x_monitor.py | 27 +++------- 2 files changed, 30 insertions(+), 50 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/classes/thermalutil.py index 96163f1d63ab..35ccf7efdd1e 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/classes/thermalutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/classes/thermalutil.py @@ -55,41 +55,38 @@ class ThermalUtil(object): THERMAL_NUM_5_IDX: ['54', '4c'], } thermal_sysfspath ={ - THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/55-0048/hwmon/hwmon4/temp1_input"], - THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/55-0049/hwmon/hwmon5/temp1_input"], - THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/55-004a/hwmon/hwmon6/temp1_input"], - THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/55-004b/hwmon/hwmon7/temp1_input"], - THERMAL_NUM_5_IDX: ["/sys/bus/i2c/devices/54-004c/hwmon/hwmon3/temp1_input"], + THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/55-0048/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/55-0049/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/55-004a/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/55-004b/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_5_IDX: ["/sys/bus/i2c/devices/54-004c/hwmon/hwmon*/temp1_input"], } - - #def __init__(self): + def _get_thermal_val(self, thermal_num): if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_MAX: logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) return None device_path = self.get_thermal_to_device_path(thermal_num) - if(os.path.isfile(device_path)): - for filename in glob.glob(device_path): - try: - val_file = open(filename, 'r') - except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) - return None + + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None content = val_file.readline().rstrip() if content == '': logging.debug('GET. content is NULL. device_path:%s', device_path) return None try: - val_file.close() + val_file.close() except: logging.debug('GET. unable to close file. device_path:%s', device_path) return None return int(content) - - else: - print "No such device_path=%s"%device_path - return 0 + + return 0 def get_num_thermals(self): return self.THERMAL_NUM_MAX @@ -116,16 +113,10 @@ def get_thermal_temp(self): def main(): thermal = ThermalUtil() - print "termal1=%d" %thermal._get_thermal_val(1) - print "termal2=%d" %thermal._get_thermal_val(2) - print "termal3=%d" %thermal._get_thermal_val(3) - print "termal4=%d" %thermal._get_thermal_val(4) - print "termal5=%d" %thermal._get_thermal_val(5) -# -# print 'get_size_node_map : %d' % thermal.get_size_node_map() -# print 'get_size_path_map : %d' % thermal.get_size_path_map() -# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): -# print thermal.get_thermal_to_device_path(x) -# + logging.debug('thermal1=%d', thermal._get_thermal_val(1)) + logging.debug('thermal2=%d', thermal._get_thermal_val(2)) + logging.debug('thermal3=%d', thermal._get_thermal_val(3)) + logging.debug('thermal4=%d', thermal._get_thermal_val(4)) + logging.debug('thermal5=%d', thermal._get_thermal_val(5)) if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py index b88b440c9032..631a7915383b 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py @@ -124,15 +124,12 @@ def __init__(self, log_file, log_level): sys_handler = handler = logging.handlers.SysLogHandler(address = '/dev/log') sys_handler.setLevel(logging.WARNING) logging.getLogger('').addHandler(sys_handler) - - #logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) def get_state_from_fan_policy(self, temp, policy): state=0 logging.debug('temp=%d', temp) for i in range(0, len(policy)): - #logging.debug('policy[%d][0]=%d, policy[%d][1]=%d, policy[%d][2]=%d', i,policy[i][0],i, policy[i][1], i, policy[i][2]) if temp > policy[i][2]: if temp <= policy[i][3]: state =i @@ -141,7 +138,6 @@ def get_state_from_fan_policy(self, temp, policy): break return state - def manage_fans(self): @@ -156,8 +152,7 @@ def manage_fans(self): LEVEL_FAN_MID=1 LEVEL_FAN_MAX=2 LEVEL_TEMP_HIGH=3 - LEVEL_TEMP_CRITICAL=4 - + LEVEL_TEMP_CRITICAL=4 fan_policy_f2b = { LEVEL_FAN_DEF: [38, 0x4, 0, 38000], @@ -212,16 +207,14 @@ def manage_fans(self): temp_get= (temp3 + temp4)/2 # Use (sensor_LM75_4a + sensor_LM75_4b) /2 ori_state=fan_policy_state - #temp_test_data=temp_test_data+1000 - #temp_get = temp_get + temp_test_data - #print "Unit test:temp_get=%d"%temp_get + if test_temp!=0: + temp_test_data=temp_test_data+1000 + temp_get = temp_get + temp_test_data + logging.debug('Unit test:temp_get=%d', temp_get) fan_policy_state=self.get_state_from_fan_policy(temp_get, fan_policy) - #print "temp3=%d"%temp3 - #print "temp4=%d"%temp4 - #print "temp_get=%d"%temp_get - - logging.debug('lm75_48=%d, lm75_49=%d, lm75_4a=%d, lm_4b=%d, lm_4b=%d', temp1,temp2,temp3,temp4,temp5) + + logging.debug('lm75_48=%d, lm75_49=%d, lm75_4a=%d, lm_4b=%d, lm_4c=%d', temp1,temp2,temp3,temp4,temp5) logging.debug('ori_state=%d, fan_policy_state=%d', ori_state, fan_policy_state) new_pwm = fan_policy[fan_policy_state][0] if fan_fail==0: @@ -244,12 +237,8 @@ def manage_fans(self): else: fan_fail=0 - #if fan_policy_state == ori_state: - # return True - #else: new_state = fan_policy_state - - #logging.warning('Temperature high alarm testing') + if ori_state==LEVEL_FAN_DEF: if new_state==LEVEL_TEMP_HIGH: if alarm_state==0: From 031e69d5741202235db56cd56b558a817ce4fae0 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Fri, 14 Feb 2020 01:04:58 +0800 Subject: [PATCH 0373/1427] [sfputil]fix an syntax error (#4141) --- device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 40734349a230..07dbbe1cc21b 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -190,7 +190,7 @@ def get_transceiver_change_event(self, timeout=0): from swsscommon import swsscommon self.state_db = swsscommon.DBConnector("STATE_DB", REDIS_TIMEOUT_USECS, - True)) + True) # Subscribe to state table for SFP change notifications self.db_sel = swsscommon.Select() From 1a0ce9874d8d4f02c4dd0ddb4181a5ab99502d33 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 13 Feb 2020 10:27:37 -0800 Subject: [PATCH 0374/1427] Update arp_update to refresh neighbor entries from APP_DB (#4125) --- files/scripts/arp_update | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/files/scripts/arp_update b/files/scripts/arp_update index 055aa98baf5d..4c7d655cfdaf 100755 --- a/files/scripts/arp_update +++ b/files/scripts/arp_update @@ -46,5 +46,26 @@ while /bin/true; do ip6cmd="ip -6 neigh show | grep -v fe80 | grep $vlan | cut -d ' ' -f 1,3 | $ndisc6cmd" eval `eval $ip6cmd` done + + # refresh neighbor entries from APP_DB in case of mismatch with kernel + DBNEIGH=$(sonic-db-cli APPL_DB keys NEIGH_TABLE*) + KERNEIGH4=$(ip -4 neigh show | grep Vlan | cut -d ' ' -f 1,3 --output-delimiter=',') + KERNEIGH6=$(ip -6 neigh show | grep -v fe80 | grep Vlan | cut -d ' ' -f 1,3 --output-delimiter=',') + for neigh in $DBNEIGH; do + intf="$( cut -d ':' -f 2 <<< "$neigh" )" + ip="$( cut -d ':' -f 3- <<< "$neigh" )" + if [[ $intf == *"Vlan"* ]]; then + if [[ $ip == *"."* ]] && [[ ! $KERNEIGH4 =~ "${ip},${intf}" ]]; then + pingcmd="timeout 0.2 ping -I $intf -n -q -i 0 -c 1 -W 1 $ip >/dev/null" + eval $pingcmd + logger "arp_update: mismatch arp entry, pinging ${ip} on ${intf}" + elif [[ $ip == *":"* ]] && [[ ! $KERNEIGH6 =~ "${ip},${intf}" ]]; then + ping6cmd="timeout 0.2 ping6 -I $intf -n -q -i 0 -c 1 -W 1 $ip >/dev/null" + eval $ping6cmd + logger "arp_update: mismatch v6 nbr entry, pinging ${ip} on ${intf}" + fi + fi + done + sleep 300 done From 2cfdb283672ceb133111216abca40def7ba3b439 Mon Sep 17 00:00:00 2001 From: Partha Dutta <51353699+dutta-partha@users.noreply.github.com> Date: Fri, 14 Feb 2020 03:17:16 +0530 Subject: [PATCH 0375/1427] [mgmt-framework]: Removing explicit libyang plugin path settings (#4144) Removing explicit libyang plugin path settings. Libyang debian package installs the extensions in standard location. Libyang debian package installs the extensions in standard location as per build time configuration (install prefix is set in patch/libyang.patch). If plugin directory is not set, libyang explicitly searches the plugins in LYEXT_PLUGINS_DIR which is populated during build. The plugins are installed in LYEXT_PLUGINS_DIR itself through debian package installation. $ grep -nr LYEXT_PLUGINS_DIR src/ src/plugin_config.h.in:18:#define LYEXT_PLUGINS_DIR "@EXTENSIONS_PLUGINS_DIR_MACRO@" /**< directory with YANG extension plugins */ src/plugins.c:420: pluginsdir = LYEXT_PLUGINS_DIR; --- dockers/docker-sonic-mgmt-framework/rest-server.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dockers/docker-sonic-mgmt-framework/rest-server.sh b/dockers/docker-sonic-mgmt-framework/rest-server.sh index f2a29c9b1ed2..e450f707dfd1 100755 --- a/dockers/docker-sonic-mgmt-framework/rest-server.sh +++ b/dockers/docker-sonic-mgmt-framework/rest-server.sh @@ -46,7 +46,5 @@ echo "REST_SERVER_ARGS = $REST_SERVER_ARGS" export CVL_SCHEMA_PATH=/usr/sbin/schema -export LIBYANG_EXTENSIONS_PLUGINS_DIR=/usr/lib/x86_64-linux-gnu/libyang/extensions -export LIBYANG_USER_TYPES_PLUGINS_DIR=/usr/lib/x86_64-linux-gnu/libyang/user_types exec /usr/sbin/rest_server ${REST_SERVER_ARGS} From 1e40c598a377efea5cefd1fce5d752091cfaf0af Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Thu, 13 Feb 2020 18:16:10 -0800 Subject: [PATCH 0376/1427] [arista] Update drivers submodules (#4147) Update the linux-kernel dependency to 4.9.0-11-2 --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index e61666bbc9d2..3517d941893b 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit e61666bbc9d2c384b1f50a9d193754c7c1668141 +Subproject commit 3517d941893b1d4a58e2a42c549ff55eeb31c496 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index e61666bbc9d2..3517d941893b 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit e61666bbc9d2c384b1f50a9d193754c7c1668141 +Subproject commit 3517d941893b1d4a58e2a42c549ff55eeb31c496 From 4b42a48f452515422ad8f9bd8bb4afef0b4358a2 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 13 Feb 2020 18:45:37 -0800 Subject: [PATCH 0377/1427] Update frr to latest 7.2.1 (#4145) --- rules/frr.mk | 2 +- src/sonic-frr/frr | 2 +- ...nexthops-compare-vrf-only-if-ip-type.patch | 73 ------------------- src/sonic-frr/patch/series | 1 - 4 files changed, 2 insertions(+), 76 deletions(-) delete mode 100644 src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch diff --git a/rules/frr.mk b/rules/frr.mk index e5c9c230a766..6dc25b30dfff 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -3,7 +3,7 @@ FRR_VERSION = 7.2.1 FRR_SUBVERSION = 0 FRR_BRANCH = frr/7.2 -FRR_TAG = frr-7.2.1-s1 +FRR_TAG = frr-7.2.1-s2 export FRR_VERSION FRR_SUBVERSION FRR_BRANCH diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index 90446e3c3310..e1b0c939960c 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit 90446e3c3310001a7b84017fa4b237ea7914f45e +Subproject commit e1b0c939960c49eba05e972a68d50ca32dd09303 diff --git a/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch b/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch deleted file mode 100644 index 343f1b3262d9..000000000000 --- a/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 2f0b5aef66316b47d2cc8ac18453600621a6a317 Mon Sep 17 00:00:00 2001 -From: Tyler Li -Date: Thu, 14 Nov 2019 23:46:52 -0800 -Subject: [PATCH] nexthops compare vrf only if ip type - ---- - lib/nexthop.c | 12 ++++++------ - lib/zclient.c | 12 ++++++------ - 2 files changed, 12 insertions(+), 12 deletions(-) - -diff --git a/lib/nexthop.c b/lib/nexthop.c -index cf5bed3d6..7d9f646c9 100644 ---- a/lib/nexthop.c -+++ b/lib/nexthop.c -@@ -105,12 +105,6 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, - { - int ret = 0; - -- if (next1->vrf_id < next2->vrf_id) -- return -1; -- -- if (next1->vrf_id > next2->vrf_id) -- return 1; -- - if (next1->type < next2->type) - return -1; - -@@ -120,6 +114,12 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, - switch (next1->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV6: -+ if (next1->vrf_id < next2->vrf_id) -+ return -1; -+ -+ if (next1->vrf_id > next2->vrf_id) -+ return 1; -+ - ret = _nexthop_gateway_cmp(next1, next2); - if (ret != 0) - return ret; -diff --git a/lib/zclient.c b/lib/zclient.c -index c739af043..0d37c46d1 100644 ---- a/lib/zclient.c -+++ b/lib/zclient.c -@@ -783,12 +783,6 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, - { - int ret = 0; - -- if (next1->vrf_id < next2->vrf_id) -- return -1; -- -- if (next1->vrf_id > next2->vrf_id) -- return 1; -- - if (next1->type < next2->type) - return -1; - -@@ -798,6 +792,12 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, - switch (next1->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV6: -+ if (next1->vrf_id < next2->vrf_id) -+ return -1; -+ -+ if (next1->vrf_id > next2->vrf_id) -+ return 1; -+ - ret = nexthop_g_addr_cmp(next1->type, &next1->gate, - &next2->gate); - if (ret != 0) --- -2.11.0 - diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 13619c87ff65..233021ace50b 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -2,5 +2,4 @@ 0002-Reduce-severity-of-Vty-connected-from-message.patch 0003-Use-vrf_id-for-vrf-not-tabled_id.patch 0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch -0005-nexthops-compare-vrf-only-if-ip-type.patch 0006-changes-for-making-snmp-socket-non-blocking.patch From 31fb631cd33451c21e1b2f89218193a53398ba1f Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Fri, 14 Feb 2020 11:08:57 -0800 Subject: [PATCH 0378/1427] Fix service and container name to be same (#4151) --- files/build_templates/init_cfg.json.j2 | 2 +- rules/docker-restapi.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index bc2eff3ede56..17617ee1a3cb 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -25,7 +25,7 @@ {% endfor %} }, "CONTAINER_FEATURE": { -{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "pmon", "radv", "rest-api", "sflow", +{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "pmon", "radv", "restapi", "sflow", "snmp", "swss", "syncd", "teamd", "telemetry"] %} "{{container}}": { "auto_restart": "disabled", diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index 7c02e0d4e44b..2141dea64d17 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -16,7 +16,7 @@ SONIC_STRETCH_DOCKERS += $(DOCKER_RESTAPI) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_RESTAPI) endif -$(DOCKER_RESTAPI)_CONTAINER_NAME = rest-api +$(DOCKER_RESTAPI)_CONTAINER_NAME = restapi $(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t $(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock $(DOCKER_RESTAPI)_RUN_OPT += -p=8090:8090/tcp From 8126916b46e510895f54ffc77812ad1bc61a959b Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 14 Feb 2020 14:55:03 -0800 Subject: [PATCH 0379/1427] [interfaces-config.sh] Do not bring 'lo' interface down and up (#4150) --- files/image_config/interfaces/interfaces-config.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index 8dddc215bbd9..b5352745a7ef 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -37,5 +37,3 @@ systemctl restart networking # Clean-up created files rm -f /tmp/ztp_input.json /tmp/ztp_port_data.json - -ifdown lo && ifup lo From 15eaf360366d576ca945e51adbda40caead5d78e Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Sat, 15 Feb 2020 04:28:24 +0530 Subject: [PATCH 0380/1427] DellEMC: Z9264-Platform2.0 Implementation [PSU] (#4104) --- .../z9264f/sonic_platform/chassis.py | 8 +- .../z9264f/sonic_platform/psu.py | 154 ++++++++++++++++++ 2 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py index 3714d391475f..47649d0bccde 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py @@ -14,10 +14,12 @@ from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Eeprom - + from sonic_platform.psu import Psu except ImportError as e: raise ImportError(str(e) + "- required module not found") +MAX_Z9264F_PSU = 2 + class Chassis(ChassisBase): """ @@ -52,6 +54,10 @@ def __init__(self): self._eeprom = Eeprom() + for i in range(MAX_Z9264F_PSU): + psu = Psu(i) + self._psu_list.append(psu) + for port_num in range(self.PORT_START, (self.PORT_END + 1)): presence = self.get_sfp(port_num).get_presence() if presence: diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py new file mode 100644 index 000000000000..374ac2e1c202 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9264 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + + +try: + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Psu(PsuBase): + """DellEMC Platform-specific PSU class""" + + # { PSU-ID: { Sensor-Name: Sensor-ID } } + SENSOR_MAPPING = { 1: { "State": 0x31, "Current": 0x39, + "Power": 0x37, "Voltage": 0x38 }, + 2: { "State": 0x32, "Current": 0x3F, + "Power": 0x3D, "Voltage": 0x3E } } + # ( PSU-ID: FRU-ID } + FRU_MAPPING = { 1: 6, 2: 7 } + + def __init__(self, psu_index): + PsuBase.__init__(self) + # PSU is 1-based in DellEMC platforms + self.index = psu_index + 1 + self.state_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["State"], + is_discrete=True) + self.voltage_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Voltage"]) + self.current_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Current"]) + self.power_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Power"]) + self.fru = IpmiFru(self.FRU_MAPPING[self.index]) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Power Supply Unit (PSU) + + Returns: + bool: True if PSU is present, False if not + """ + presence = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state & 0b1): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + return self.fru.get_board_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + return self.fru.get_board_serial() + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state == 0x01): + status = True + + return status + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + is_valid, voltage = self.voltage_sensor.get_reading() + if not is_valid: + voltage = 0 + + return "{:.1f}".format(voltage) + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + is_valid, current = self.current_sensor.get_reading() + if not is_valid: + current = 0 + + return "{:.1f}".format(current) + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + is_valid, power = self.power_sensor.get_reading() + if not is_valid: + power = 0 + + return "{:.1f}".format(power) + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and + passed all its internal self-tests, False if not. + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state == 0x01): + status = True + + return status From 4afb56da1da7972d5b02a3c72045c0274fc60d38 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sun, 16 Feb 2020 19:47:16 +0800 Subject: [PATCH 0381/1427] Update SDK to 4.3.3052 (#4153) update FW to xx_2000_3298 update SAI to 1.16.0 update Spectrum-1 and Spectrum-2 buffer pool size according to the new SDK default config change. modified: ../../device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 modified: ../../device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 modified: ../../device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 modified: ../../device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 modified: fw.mk modified: mlnx-sai.mk modified: mlnx-sai/SAI-Implementation modified: sdk-src/sx-kernel/Switch-SDK-drivers modified: sdk.mk signed-off by kebol@mellanox.com --- .../ACS-MSN2700/buffers_defaults_t0.j2 | 8 ++++---- .../ACS-MSN2700/buffers_defaults_t1.j2 | 8 ++++---- .../ACS-MSN3700/buffers_defaults_t0.j2 | 8 ++++---- .../ACS-MSN3700/buffers_defaults_t1.j2 | 8 ++++---- platform/mellanox/fw.mk | 4 ++-- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 9 files changed, 22 insertions(+), 22 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 index 8c3cac4b80b8..5529ee3d8598 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '4194304' %} -{% set ingress_lossy_pool_size = '7340032' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '7340032' %} +{% set ingress_lossless_pool_size = '5029836' %} +{% set ingress_lossy_pool_size = '5029836' %} +{% set egress_lossless_pool_size = '14024599' %} +{% set egress_lossy_pool_size = '5029836' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 index 45433b1b2641..f418e2ffa1db 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '2097152' %} -{% set ingress_lossy_pool_size = '5242880' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '5242880' %} +{% set ingress_lossless_pool_size = '2097100' %} +{% set ingress_lossy_pool_size = '2097100' %} +{% set egress_lossless_pool_size = '14024599' %} +{% set egress_lossy_pool_size = '2097100' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 index d40bc03fbb59..e26ad28b9f0e 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '8224768' %} -{% set ingress_lossy_pool_size = '8224768' %} -{% set egress_lossless_pool_size = '35966016' %} -{% set egress_lossy_pool_size = '8224768' %} +{% set ingress_lossless_pool_size = '14983147' %} +{% set ingress_lossy_pool_size = '14983147' %} +{% set egress_lossless_pool_size = '34340822' %} +{% set egress_lossy_pool_size = '14983147' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 index fe8c27b9d364..b5e4ff8d1747 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '12042240' %} -{% set ingress_lossy_pool_size = '12042240' %} -{% set egress_lossless_pool_size = '35966016' %} -{% set egress_lossy_pool_size = '12042240' %} +{% set ingress_lossless_pool_size = '9158635' %} +{% set ingress_lossy_pool_size = '9158635' %} +{% set egress_lossless_pool_size = '34340822' %} +{% set egress_lossy_pool_size = '9158635' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index c088fe274b06..97ff9d93d486 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,12 +11,12 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.2720 +MLNX_SPC_FW_VERSION = 13.2000.3298 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.2720 +MLNX_SPC2_FW_VERSION = 29.2000.3298 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index baced2780637..419598a6a776 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.15.5-master +MLNX_SAI_VERSION = SAIRel1.16.0-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 4b40b5191b07..df052a406255 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 4b40b5191b07118326a29be2d491f4362fc02eee +Subproject commit df052a4062556e0f3a1e695fa73efccf81d32a9d diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 026b12e2bd02..fa26ae9d24b4 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 026b12e2bd02b79fdf50eb5f45a161c95ec94837 +Subproject commit fa26ae9d24b4d1ff162f56d83d944c2fc2bcea0b diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index f105f6b22f7b..649422429771 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.3.2908 +MLNX_SDK_VERSION = 4.3.3052 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 936749c44f011aaeea817ca6164b3545d435d9e9 Mon Sep 17 00:00:00 2001 From: michealylj1 <46735287+michealylj1@users.noreply.github.com> Date: Tue, 18 Feb 2020 06:09:15 +0800 Subject: [PATCH 0382/1427] [Device]: Add new CIG device CS6436-54P and CS5435-54P, also update code for CS6436-56P (#4157) * Add new CIG device CS6436-54P and CS5435-54P, also update code for CS6436-56P * security kernel update to 4.9.189 for CIG devices * security kernel update to 4.9.189 for CIG devices * Update rules Update rule file --- .../Cig-CS5435-54P/buffers.json.j2 | 111 + .../Cig-CS5435-54P/led.bin | Bin 0 -> 652 bytes .../Cig-CS5435-54P/pg_profile_lookup.ini | 17 + .../Cig-CS5435-54P/port_config.ini | 55 + .../Cig-CS5435-54P/port_config.nps} | 240 +- .../Cig-CS5435-54P/qos.json.j2 | 1 + .../Cig-CS5435-54P/sai.profile | 3 + .../cig/x86_64-cig_cs5435_54p-r0/default_sku | 1 + .../x86_64-cig_cs5435_54p-r0/installer.conf | 4 + .../plugins/eeprom.py | 21 + .../plugins/psuutil.py | 93 + .../plugins/sfputil.py | 250 ++ .../cig/x86_64-cig_cs5435_54p-r0/sensors.conf | 13 + .../Cig-CS6436-54P/buffers.json.j2 | 111 + .../Cig-CS6436-54P/led.bin | Bin 0 -> 652 bytes .../Cig-CS6436-54P/pg_profile_lookup.ini | 17 + .../Cig-CS6436-54P/port_config.ini | 55 + .../Cig-CS6436-54P/port_config.nps} | 88 +- .../Cig-CS6436-54P/qos.json.j2 | 1 + .../Cig-CS6436-54P/sai.profile | 3 + .../cig/x86_64-cig_cs6436_54p-r0/default_sku | 1 + .../x86_64-cig_cs6436_54p-r0/installer.conf | 4 + .../plugins/eeprom.py | 21 + .../plugins/psuutil.py | 93 + .../plugins/sfputil.py | 250 ++ .../cig/x86_64-cig_cs6436_54p-r0/sensors.conf | 13 + .../Cig-CS6436-56P/buffers.json.j2 | 0 .../Cig-CS6436-56P/led.bin | Bin 0 -> 652 bytes .../Cig-CS6436-56P/pg_profile_lookup.ini | 0 .../Cig-CS6436-56P/port_config.ini | 112 +- .../Cig-CS6436-56P/port_config.nps | 4 +- .../proc_init.nps} | 2 +- .../Cig-CS6436-56P/qos.json.j2 | 0 .../Cig-CS6436-56P/sai.profile | 3 +- .../cig/x86_64-cig_cs6436_56p-r0/default_sku | 0 .../x86_64-cig_cs6436_56p-r0/installer.conf | 4 +- .../plugins/psuutil.py | 3 +- .../plugins/sfputil.py | 254 +- .../cig/x86_64-cig_cs6436_56p-r0/sensors.conf | 0 platform/nephos/one-image.mk | 5 +- platform/nephos/platform-modules-cig.mk | 24 +- .../cs5435-54p/classes/__init__.py | 0 .../cs5435-54p/classes/fanutil.py | 0 .../cs5435-54p/classes/thermalutil.py | 0 .../cs5435-54p/modules/Makefile | 6 + .../cs5435-54p/modules/i2c-algo-lpc.h | 222 ++ .../modules/x86-64-cig-cs5435-54p-cpld.c | 2209 +++++++++++++++++ .../modules/x86-64-cig-cs5435-54p-fan.c | 521 ++++ .../modules/x86-64-cig-cs5435-54p-led.c | 594 +++++ .../modules/x86-64-cig-cs5435-54p-psu.c | 946 +++++++ .../modules/x86-64-cig-cs5435-54p-sfp.c | 1713 +++++++++++++ .../modules/x86-64-cig-cs5435-54p-sysfs.c | 335 +++ .../service/cs5435-platform-init.service | 13 + .../service/cs5435-platform-misc.service | 15 + .../cs5435-54p/setup.py | 15 + .../cs5435-54p/utils/cig_cs5435_misc.py | 574 +++++ .../cs5435-54p/utils/cig_cs5435_util.py | 563 +++++ .../cs6436-54p/classes/__init__.py | 0 .../cs6436-54p/classes/fanutil.py | 0 .../cs6436-54p/classes/thermalutil.py | 0 .../cs6436-54p/modules/Makefile | 6 + .../cs6436-54p/modules/i2c-algo-lpc.h | 222 ++ .../modules/x86-64-cig-cs6436-54p-cpld.c | 2202 ++++++++++++++++ .../modules/x86-64-cig-cs6436-54p-fan.c | 521 ++++ .../modules/x86-64-cig-cs6436-54p-led.c | 594 +++++ .../modules/x86-64-cig-cs6436-54p-psu.c | 943 +++++++ .../modules/x86-64-cig-cs6436-54p-sfp.c | 1713 +++++++++++++ .../modules/x86-64-cig-cs6436-54p-sysfs.c | 335 +++ .../service/cs6436-platform-init.service | 13 + .../service/cs6436-platform-misc.service | 15 + .../cs6436-54p/setup.py | 15 + .../cs6436-54p/utils/cig_cs6436_misc.py | 574 +++++ .../cs6436-54p/utils/cig_cs6436_util.py | 565 +++++ .../cs6436-56p/modules/Makefile | 3 +- .../cs6436-56p/modules/i2c-algo-lpc.h | 129 +- .../cs6436-56p/modules/i2c-algo-lpc2iic.h | 0 .../modules/x86-64-cig-cs6436-56p-cpld.c | 1200 ++++++--- .../modules/x86-64-cig-cs6436-56p-fan.c | 70 + .../modules/x86-64-cig-cs6436-56p-led.c | 0 .../modules/x86-64-cig-cs6436-56p-psu.c | 1339 ++++++---- .../modules/x86-64-cig-cs6436-56p-sfp.c | 339 ++- .../modules/x86-64-cig-cs6436-56p-sysfs.c | 335 +++ .../service/cs6436-platform-init.service | 0 .../service/cs6436-platform-misc.service | 2 +- .../cs6436-56p/utils/cig_cs6436_misc.py | 596 ++++- .../cs6436-56p/utils/cig_cs6436_util.py | 336 +-- .../debian/changelog | 0 .../sonic-platform-modules-cig/debian/compat | 0 .../sonic-platform-modules-cig/debian/control | 12 +- .../sonic-platform-modules-cig/debian/rules | 7 +- 90 files changed, 20251 insertions(+), 1438 deletions(-) create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/buffers.json.j2 create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/led.bin create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/pg_profile_lookup.ini create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.ini rename device/cig/{x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.DAC.R0B => x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps} (82%) mode change 100755 => 100644 create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/qos.json.j2 create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/sai.profile create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/default_sku create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/installer.conf create mode 100755 device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py create mode 100755 device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py create mode 100755 device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/buffers.json.j2 create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/led.bin create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/pg_profile_lookup.ini create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.ini rename device/cig/{x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.AOC.R0B => x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps} (92%) mode change 100755 => 100644 create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/qos.json.j2 create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/sai.profile create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/default_sku create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/installer.conf create mode 100755 device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py create mode 100755 device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py create mode 100755 device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/buffers.json.j2 create mode 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/led.bin mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/pg_profile_lookup.ini mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.ini mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps rename device/cig/x86_64-cig_cs6436_56p-r0/{led_proc_init.nps => Cig-CS6436-56P/proc_init.nps} (90%) mode change 100755 => 100644 mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/qos.json.j2 mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/sai.profile mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/default_sku mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/installer.conf mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/sensors.conf create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/__init__.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/fanutil.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/thermalutil.py create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/Makefile create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/i2c-algo-lpc.h create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-cpld.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-fan.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-led.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-psu.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sfp.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sysfs.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-init.service create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-misc.service create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/__init__.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/fanutil.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/thermalutil.py create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/Makefile create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/i2c-algo-lpc.h create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-cpld.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-fan.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-led.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-psu.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sfp.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sysfs.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-init.service create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-misc.service create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc2iic.h mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sysfs.c mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-init.service mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/debian/changelog mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/debian/compat mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/debian/control diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/buffers.json.j2 b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/buffers.json.j2 new file mode 100644 index 000000000000..2c391214fa65 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/buffers.json.j2 @@ -0,0 +1,111 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_speed = '10G' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "20971328", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"3584", + "dynamic_th":"-4" + } + }, + "BUFFER_PG": { + }, + "BUFFER_QUEUE": { + } +} + \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/led.bin b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/led.bin new file mode 100644 index 0000000000000000000000000000000000000000..201662a1c605693991df041260615085a9b5eb7b GIT binary patch literal 652 zcmWN`$uk0Q7{}qC8Dp3cZL(b}N?9vwi@MsWq^r14mvBk`bbSZAFz)>vhg7rbDLEjHQYB`?`vgMa+vlvDolmlIC- z!ykV0n_v9mm}8DO;*djr@{=F@;5*;>#y1W);45F*XP+;8VUImN^O;?C*V!Z literal 0 HcmV?d00001 diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/pg_profile_lookup.ini b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/pg_profile_lookup.ini new file mode 100644 index 000000000000..d98b0eca6d19 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 3584 32256 59136 36736 + 25000 5m 3584 41216 68096 45696 + 40000 5m 3584 47488 74368 51968 + 50000 5m 3584 52864 79744 57344 + 100000 5m 3584 78400 132160 82880 + 10000 40m 3584 32256 59136 36736 + 25000 40m 3584 41216 68096 45696 + 40000 40m 3584 47488 74368 51968 + 50000 40m 3584 52864 79744 57344 + 100000 40m 3584 78400 132160 82880 + 10000 300m 3584 32256 65856 36736 + 25000 300m 3584 41216 84672 45696 + 40000 300m 3584 47488 101024 51968 + 50000 300m 3584 52864 113120 57344 + 100000 300m 3584 78400 198688 82880 \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.ini b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.ini new file mode 100644 index 000000000000..ab29b7bed9ff --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.ini @@ -0,0 +1,55 @@ +# name lanes alias index speed +Ethernet0 8 Ethernet1/1 1 10000 +Ethernet1 9 Ethernet2/1 2 10000 +Ethernet2 10 Ethernet3/1 3 10000 +Ethernet3 11 Ethernet4/1 4 10000 +Ethernet4 12 Ethernet5/1 5 10000 +Ethernet5 13 Ethernet6/1 6 10000 +Ethernet6 14 Ethernet7/1 7 10000 +Ethernet7 15 Ethernet8/1 8 10000 +Ethernet8 16 Ethernet9/1 9 10000 +Ethernet9 17 Ethernet10/1 10 10000 +Ethernet10 18 Ethernet11/1 11 10000 +Ethernet11 19 Ethernet12/1 12 10000 +Ethernet12 20 Ethernet13/1 13 10000 +Ethernet13 21 Ethernet14/1 14 10000 +Ethernet14 22 Ethernet15/1 15 10000 +Ethernet15 23 Ethernet16/1 16 10000 +Ethernet16 32 Ethernet17/1 17 10000 +Ethernet17 33 Ethernet18/1 18 10000 +Ethernet18 34 Ethernet19/1 19 10000 +Ethernet19 35 Ethernet20/1 20 10000 +Ethernet20 40 Ethernet21/1 21 10000 +Ethernet21 41 Ethernet22/1 22 10000 +Ethernet22 42 Ethernet23/1 23 10000 +Ethernet23 43 Ethernet24/1 24 10000 +Ethernet24 48 Ethernet25/1 25 10000 +Ethernet25 49 Ethernet26/1 26 10000 +Ethernet26 50 Ethernet27/1 27 10000 +Ethernet27 51 Ethernet28/1 28 10000 +Ethernet28 56 Ethernet29/1 29 10000 +Ethernet29 57 Ethernet30/1 30 10000 +Ethernet30 58 Ethernet31/1 31 10000 +Ethernet31 59 Ethernet32/1 32 10000 +Ethernet32 64 Ethernet33/1 33 10000 +Ethernet33 65 Ethernet34/1 34 10000 +Ethernet34 66 Ethernet35/1 35 10000 +Ethernet35 67 Ethernet36/1 36 10000 +Ethernet36 68 Ethernet37/1 37 10000 +Ethernet37 69 Ethernet38/1 38 10000 +Ethernet38 70 Ethernet39/1 39 10000 +Ethernet39 71 Ethernet40/1 40 10000 +Ethernet40 72 Ethernet41/1 41 10000 +Ethernet41 73 Ethernet42/1 42 10000 +Ethernet42 74 Ethernet43/1 43 10000 +Ethernet43 75 Ethernet44/1 44 10000 +Ethernet44 76 Ethernet45/1 45 10000 +Ethernet45 77 Ethernet46/1 46 10000 +Ethernet46 78 Ethernet47/1 47 10000 +Ethernet47 79 Ethernet48/1 48 10000 +Ethernet48 84,85,86,87 Ethernet49/1 49 100000 +Ethernet49 80,81,82,83 Ethernet50/1 50 100000 +Ethernet50 108,109,110,111 Ethernet51/1 51 100000 +Ethernet51 104,105,106,107 Ethernet52/1 52 100000 +Ethernet52 116,117,118,119 Ethernet53/1 53 100000 +Ethernet53 112,113,114,115 Ethernet54/1 54 100000 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.DAC.R0B b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps old mode 100755 new mode 100644 similarity index 82% rename from device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.DAC.R0B rename to device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps index 857e5f1ede5f..9c6a5af8e5f0 --- a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.DAC.R0B +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps @@ -1,60 +1,58 @@ init start stage unit=0 low-level -init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true -init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true -init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true -init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true -init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true -init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true -init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true -init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true -init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true -init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true -init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true -init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true -init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true -init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true -init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true -init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true -init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true -init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true -init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true -init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true -init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true -init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true -init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true -init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true -init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true -init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true -init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true -init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true -init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=10g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=10g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=10g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=10g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=10g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=10g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=10g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=10g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=10g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=10g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=10g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=10g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=10g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=10g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=10g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=10g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=10g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=10g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=10g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=10g active=true +init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=10g active=true +init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=10g active=true +init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=10g active=true +init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=10g active=true +init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=10g active=true +init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=10g active=true +init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=10g active=true +init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=10g active=true +init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=10g active=true +init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=10g active=true +init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=10g active=true +init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=10g active=true +init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=10g active=true +init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=10g active=true +init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=10g active=true +init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=10g active=true +init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=10g active=true +init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=10g active=true +init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=10g active=true +init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=10g active=true +init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=10g active=true +init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=10g active=true +init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=10g active=true +init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=10g active=true +init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=10g active=true +init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=10g active=true +init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=10g active=true +init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=10g active=true init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map unit=0 port=50 eth-macro=23 lane=0 max-speed=100g active=true -init set port-map unit=0 port=51 eth-macro=22 lane=0 max-speed=100g active=true -init set port-map unit=0 port=52 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map unit=0 port=53 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map unit=0 port=54 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map unit=0 port=55 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=28 lane=0 max-speed=100g active=true init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true init start stage unit=0 task-rsrc @@ -110,12 +108,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x3.0.1.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.0.1 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=tx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -168,12 +164,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x3.1.0.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.0.1.2 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x2.0.1.3 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x2.0.1.3 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x1.0.3.2 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=rx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 @@ -230,8 +224,6 @@ phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -284,12 +276,10 @@ phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.1.0 phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.1 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.1.1.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=c2 data=0x2 @@ -508,14 +498,6 @@ phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x0.0.0.0 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c2 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=cn1 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c0 data=0x2 @@ -524,62 +506,60 @@ phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c2 data=0x1 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=cn1 data=0x0 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c0 data=0x2 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c1 data=0x3 -port set property unit=0 portlist=0 speed=25g -port set property unit=0 portlist=1 speed=25g -port set property unit=0 portlist=2 speed=25g -port set property unit=0 portlist=3 speed=25g -port set property unit=0 portlist=4 speed=25g -port set property unit=0 portlist=5 speed=25g -port set property unit=0 portlist=6 speed=25g -port set property unit=0 portlist=7 speed=25g -port set property unit=0 portlist=8 speed=25g -port set property unit=0 portlist=9 speed=25g -port set property unit=0 portlist=10 speed=25g -port set property unit=0 portlist=11 speed=25g -port set property unit=0 portlist=12 speed=25g -port set property unit=0 portlist=13 speed=25g -port set property unit=0 portlist=14 speed=25g -port set property unit=0 portlist=15 speed=25g -port set property unit=0 portlist=16 speed=25g -port set property unit=0 portlist=17 speed=25g -port set property unit=0 portlist=18 speed=25g -port set property unit=0 portlist=19 speed=25g -port set property unit=0 portlist=20 speed=25g -port set property unit=0 portlist=21 speed=25g -port set property unit=0 portlist=22 speed=25g -port set property unit=0 portlist=23 speed=25g -port set property unit=0 portlist=24 speed=25g -port set property unit=0 portlist=25 speed=25g -port set property unit=0 portlist=26 speed=25g -port set property unit=0 portlist=27 speed=25g -port set property unit=0 portlist=28 speed=25g -port set property unit=0 portlist=29 speed=25g -port set property unit=0 portlist=30 speed=25g -port set property unit=0 portlist=31 speed=25g -port set property unit=0 portlist=32 speed=25g -port set property unit=0 portlist=33 speed=25g -port set property unit=0 portlist=34 speed=25g -port set property unit=0 portlist=35 speed=25g -port set property unit=0 portlist=36 speed=25g -port set property unit=0 portlist=37 speed=25g -port set property unit=0 portlist=38 speed=25g -port set property unit=0 portlist=39 speed=25g -port set property unit=0 portlist=40 speed=25g -port set property unit=0 portlist=41 speed=25g -port set property unit=0 portlist=42 speed=25g -port set property unit=0 portlist=43 speed=25g -port set property unit=0 portlist=44 speed=25g -port set property unit=0 portlist=45 speed=25g -port set property unit=0 portlist=46 speed=25g -port set property unit=0 portlist=47 speed=25g +port set property unit=0 portlist=0 speed=10g +port set property unit=0 portlist=1 speed=10g +port set property unit=0 portlist=2 speed=10g +port set property unit=0 portlist=3 speed=10g +port set property unit=0 portlist=4 speed=10g +port set property unit=0 portlist=5 speed=10g +port set property unit=0 portlist=6 speed=10g +port set property unit=0 portlist=7 speed=10g +port set property unit=0 portlist=8 speed=10g +port set property unit=0 portlist=9 speed=10g +port set property unit=0 portlist=10 speed=10g +port set property unit=0 portlist=11 speed=10g +port set property unit=0 portlist=12 speed=10g +port set property unit=0 portlist=13 speed=10g +port set property unit=0 portlist=14 speed=10g +port set property unit=0 portlist=15 speed=10g +port set property unit=0 portlist=16 speed=10g +port set property unit=0 portlist=17 speed=10g +port set property unit=0 portlist=18 speed=10g +port set property unit=0 portlist=19 speed=10g +port set property unit=0 portlist=20 speed=10g +port set property unit=0 portlist=21 speed=10g +port set property unit=0 portlist=22 speed=10g +port set property unit=0 portlist=23 speed=10g +port set property unit=0 portlist=24 speed=10g +port set property unit=0 portlist=25 speed=10g +port set property unit=0 portlist=26 speed=10g +port set property unit=0 portlist=27 speed=10g +port set property unit=0 portlist=28 speed=10g +port set property unit=0 portlist=29 speed=10g +port set property unit=0 portlist=30 speed=10g +port set property unit=0 portlist=31 speed=10g +port set property unit=0 portlist=32 speed=10g +port set property unit=0 portlist=33 speed=10g +port set property unit=0 portlist=34 speed=10g +port set property unit=0 portlist=35 speed=10g +port set property unit=0 portlist=36 speed=10g +port set property unit=0 portlist=37 speed=10g +port set property unit=0 portlist=38 speed=10g +port set property unit=0 portlist=39 speed=10g +port set property unit=0 portlist=40 speed=10g +port set property unit=0 portlist=41 speed=10g +port set property unit=0 portlist=42 speed=10g +port set property unit=0 portlist=43 speed=10g +port set property unit=0 portlist=44 speed=10g +port set property unit=0 portlist=45 speed=10g +port set property unit=0 portlist=46 speed=10g +port set property unit=0 portlist=47 speed=10g port set property unit=0 portlist=48 speed=100g port set property unit=0 portlist=49 speed=100g port set property unit=0 portlist=50 speed=100g port set property unit=0 portlist=51 speed=100g port set property unit=0 portlist=52 speed=100g port set property unit=0 portlist=53 speed=100g -port set property unit=0 portlist=54 speed=100g -port set property unit=0 portlist=55 speed=100g port set property unit=0 portlist=129 speed=10g port set property unit=0 portlist=130 speed=1g port set property unit=0 portlist=0 medium-type=sr @@ -636,8 +616,6 @@ port set property unit=0 portlist=50 medium-type=sr4 port set property unit=0 portlist=51 medium-type=sr4 port set property unit=0 portlist=52 medium-type=sr4 port set property unit=0 portlist=53 medium-type=sr4 -port set property unit=0 portlist=54 medium-type=sr4 -port set property unit=0 portlist=55 medium-type=sr4 port set property unit=0 portlist=129 medium-type=kr port set property unit=0 portlist=130 medium-type=x port advertise unit=0 portlist=129 speed-10g-kr @@ -696,7 +674,5 @@ port set property unit=0 portlist=50 admin=enable port set property unit=0 portlist=51 admin=enable port set property unit=0 portlist=52 admin=enable port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=54 admin=enable -port set property unit=0 portlist=55 admin=enable -port set property unit=0 portlist=129 admin=enable -port set property unit=0 portlist=130 admin=enable +port set property unit=0 portlist=129 admin=disable +port set property unit=0 portlist=130 admin=disable diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/qos.json.j2 b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/sai.profile b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/sai.profile new file mode 100644 index 000000000000..e7b5f90ac88a --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/sai.profile @@ -0,0 +1,3 @@ +SAI_INIT_LED_CONFIG_FILE=/usr/share/sonic/hwsku/led.bin +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps +SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/default_sku b/device/cig/x86_64-cig_cs5435_54p-r0/default_sku new file mode 100644 index 000000000000..66b35b61e09b --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/default_sku @@ -0,0 +1 @@ +Cig-CS5435-54P t1 diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/installer.conf b/device/cig/x86_64-cig_cs5435_54p-r0/installer.conf new file mode 100644 index 000000000000..ea6b4f6ebe31 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer" diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py new file mode 100755 index 000000000000..5019b9c40a9a --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/7-0057/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py new file mode 100755 index 000000000000..70d50e6c3458 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py @@ -0,0 +1,93 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path +import logging + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/5-005a", + "/sys/bus/i2c/devices/5-005b"] + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open %s file !", attr_path) + + retval = retval.rstrip('\r\n') + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + attr_file = 'psu_power_good' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU status + if (attr_value == 1): + status = 1 + + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_absent = 0 + attr_file ='psu_present' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU presence + if (attr_value == 1): + status = 1 + + return status + diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py new file mode 100755 index 000000000000..2863b80c9950 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 1 + _port_end = 54 + _qsfp_port_start = 49 + _ports_in_block = 54 + + _port_to_eeprom_mapping = {} + _global_port_pres_dict = {} + + _port_to_i2c_mapping = { + 1 : 8, + 2 : 9, + 3 : 10, + 4 : 11, + 5 : 12, + 6 : 13, + 7 : 14, + 8 : 15, + 9 : 16, + 10: 17, + 11 : 18, + 12 : 19, + 13 : 20, + 14 : 21, + 15 : 22, + 16 : 23, + 17 : 24, + 18 : 25, + 19 : 26, + 20 : 27, + 21 : 28, + 22 : 29, + 23 : 30, + 24 : 31, + 25 : 32, + 26 : 33, + 27 : 34, + 28 : 35, + 29 : 36, + 30 : 37, + 31 : 38, + 32 : 39, + 33 : 40, + 34 : 41, + 35 : 42, + 36 : 43, + 37 : 44, + 38 : 45, + 39 : 46, + 40 : 47, + 41 : 48, + 42 : 49, + 43 : 50, + 44 : 51, + 45 : 52, + 46 : 53, + 47 : 54, + 48 : 55, + 49 : 56, + 50 : 57, + 51 : 60, + 52 : 61, + 53 : 62, + 54 : 63, + } + + _qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + time.sleep(1) + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error:try again to read file failed: %s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + if reg_value == '1': + return True + + reg_file.close() + if reg_value == '1': + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + self._global_port_pres_dict[port_num] = '0' + + + def __init__(self): + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' + for x in range(self._port_start, self._port_end + 1): + port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x]) + self._port_to_eeprom_mapping[x] = port_eeprom_path + + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps,'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + + if lpmode == 1: + reg_file.write('1') + elif lpmode == 0: + reg_file.write('0') + reg_file.close() + + return True + + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + + if reg_value == '1': + return True + + return False + + def get_transceiver_change_event(self): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) + + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf b/device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf new file mode 100644 index 000000000000..f0964c87dae7 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf @@ -0,0 +1,13 @@ +# libsensors configuration file + +chip "cs5435_54p_fan-*" + label fan1 "front fan 1" + label fan2 "front fan 2" + label fan3 "front fan 3" + label fan4 "front fan 4" + label fan5 "front fan 5" + label fan6 "rear fan 1" + label fan7 "rear fan 2" + label fan8 "rear fan 3" + label fan9 "rear fan 4" + label fan10 "rear fan 5" diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/buffers.json.j2 b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/buffers.json.j2 new file mode 100644 index 000000000000..2c391214fa65 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/buffers.json.j2 @@ -0,0 +1,111 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_speed = '10G' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "20971328", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"3584", + "dynamic_th":"-4" + } + }, + "BUFFER_PG": { + }, + "BUFFER_QUEUE": { + } +} + \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/led.bin b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/led.bin new file mode 100644 index 0000000000000000000000000000000000000000..201662a1c605693991df041260615085a9b5eb7b GIT binary patch literal 652 zcmWN`$uk0Q7{}qC8Dp3cZL(b}N?9vwi@MsWq^r14mvBk`bbSZAFz)>vhg7rbDLEjHQYB`?`vgMa+vlvDolmlIC- z!ykV0n_v9mm}8DO;*djr@{=F@;5*;>#y1W);45F*XP+;8VUImN^O;?C*V!Z literal 0 HcmV?d00001 diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/pg_profile_lookup.ini b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/pg_profile_lookup.ini new file mode 100644 index 000000000000..d98b0eca6d19 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 3584 32256 59136 36736 + 25000 5m 3584 41216 68096 45696 + 40000 5m 3584 47488 74368 51968 + 50000 5m 3584 52864 79744 57344 + 100000 5m 3584 78400 132160 82880 + 10000 40m 3584 32256 59136 36736 + 25000 40m 3584 41216 68096 45696 + 40000 40m 3584 47488 74368 51968 + 50000 40m 3584 52864 79744 57344 + 100000 40m 3584 78400 132160 82880 + 10000 300m 3584 32256 65856 36736 + 25000 300m 3584 41216 84672 45696 + 40000 300m 3584 47488 101024 51968 + 50000 300m 3584 52864 113120 57344 + 100000 300m 3584 78400 198688 82880 \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.ini b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.ini new file mode 100644 index 000000000000..165b5204c2f8 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.ini @@ -0,0 +1,55 @@ +# name lanes alias index speed +Ethernet0 8 Ethernet1/1 1 25000 +Ethernet1 9 Ethernet2/1 2 25000 +Ethernet2 10 Ethernet3/1 3 25000 +Ethernet3 11 Ethernet4/1 4 25000 +Ethernet4 12 Ethernet5/1 5 25000 +Ethernet5 13 Ethernet6/1 6 25000 +Ethernet6 14 Ethernet7/1 7 25000 +Ethernet7 15 Ethernet8/1 8 25000 +Ethernet8 16 Ethernet9/1 9 25000 +Ethernet9 17 Ethernet10/1 10 25000 +Ethernet10 18 Ethernet11/1 11 25000 +Ethernet11 19 Ethernet12/1 12 25000 +Ethernet12 20 Ethernet13/1 13 25000 +Ethernet13 21 Ethernet14/1 14 25000 +Ethernet14 22 Ethernet15/1 15 25000 +Ethernet15 23 Ethernet16/1 16 25000 +Ethernet16 32 Ethernet17/1 17 25000 +Ethernet17 33 Ethernet18/1 18 25000 +Ethernet18 34 Ethernet19/1 19 25000 +Ethernet19 35 Ethernet20/1 20 25000 +Ethernet20 40 Ethernet21/1 21 25000 +Ethernet21 41 Ethernet22/1 22 25000 +Ethernet22 42 Ethernet23/1 23 25000 +Ethernet23 43 Ethernet24/1 24 25000 +Ethernet24 48 Ethernet25/1 25 25000 +Ethernet25 49 Ethernet26/1 26 25000 +Ethernet26 50 Ethernet27/1 27 25000 +Ethernet27 51 Ethernet28/1 28 25000 +Ethernet28 56 Ethernet29/1 29 25000 +Ethernet29 57 Ethernet30/1 30 25000 +Ethernet30 58 Ethernet31/1 31 25000 +Ethernet31 59 Ethernet32/1 32 25000 +Ethernet32 64 Ethernet33/1 33 25000 +Ethernet33 65 Ethernet34/1 34 25000 +Ethernet34 66 Ethernet35/1 35 25000 +Ethernet35 67 Ethernet36/1 36 25000 +Ethernet36 68 Ethernet37/1 37 25000 +Ethernet37 69 Ethernet38/1 38 25000 +Ethernet38 70 Ethernet39/1 39 25000 +Ethernet39 71 Ethernet40/1 40 25000 +Ethernet40 72 Ethernet41/1 41 25000 +Ethernet41 73 Ethernet42/1 42 25000 +Ethernet42 74 Ethernet43/1 43 25000 +Ethernet43 75 Ethernet44/1 44 25000 +Ethernet44 76 Ethernet45/1 45 25000 +Ethernet45 77 Ethernet46/1 46 25000 +Ethernet46 78 Ethernet47/1 47 25000 +Ethernet47 79 Ethernet48/1 48 25000 +Ethernet48 84,85,86,87 Ethernet49/1 49 100000 +Ethernet49 80,81,82,83 Ethernet50/1 50 100000 +Ethernet50 108,109,110,111 Ethernet51/1 51 100000 +Ethernet51 104,105,106,107 Ethernet52/1 52 100000 +Ethernet52 116,117,118,119 Ethernet53/1 53 100000 +Ethernet53 112,113,114,115 Ethernet54/1 54 100000 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.AOC.R0B b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps old mode 100755 new mode 100644 similarity index 92% rename from device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.AOC.R0B rename to device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps index 857e5f1ede5f..aca222f5962d --- a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.AOC.R0B +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps @@ -1,24 +1,24 @@ init start stage unit=0 low-level -init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true @@ -49,12 +49,10 @@ init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map unit=0 port=50 eth-macro=23 lane=0 max-speed=100g active=true -init set port-map unit=0 port=51 eth-macro=22 lane=0 max-speed=100g active=true -init set port-map unit=0 port=52 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map unit=0 port=53 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map unit=0 port=54 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map unit=0 port=55 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=28 lane=0 max-speed=100g active=true init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true init start stage unit=0 task-rsrc @@ -110,12 +108,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x3.0.1.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.0.1 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=tx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -168,12 +164,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x3.1.0.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.0.1.2 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x2.0.1.3 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x2.0.1.3 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x1.0.3.2 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=rx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 @@ -230,8 +224,6 @@ phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -284,12 +276,10 @@ phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.1.0 phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.1 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.1.1.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=c2 data=0x2 @@ -508,14 +498,6 @@ phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x0.0.0.0 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c2 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=cn1 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c0 data=0x2 @@ -578,8 +560,6 @@ port set property unit=0 portlist=50 speed=100g port set property unit=0 portlist=51 speed=100g port set property unit=0 portlist=52 speed=100g port set property unit=0 portlist=53 speed=100g -port set property unit=0 portlist=54 speed=100g -port set property unit=0 portlist=55 speed=100g port set property unit=0 portlist=129 speed=10g port set property unit=0 portlist=130 speed=1g port set property unit=0 portlist=0 medium-type=sr @@ -636,8 +616,6 @@ port set property unit=0 portlist=50 medium-type=sr4 port set property unit=0 portlist=51 medium-type=sr4 port set property unit=0 portlist=52 medium-type=sr4 port set property unit=0 portlist=53 medium-type=sr4 -port set property unit=0 portlist=54 medium-type=sr4 -port set property unit=0 portlist=55 medium-type=sr4 port set property unit=0 portlist=129 medium-type=kr port set property unit=0 portlist=130 medium-type=x port advertise unit=0 portlist=129 speed-10g-kr @@ -696,7 +674,5 @@ port set property unit=0 portlist=50 admin=enable port set property unit=0 portlist=51 admin=enable port set property unit=0 portlist=52 admin=enable port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=54 admin=enable -port set property unit=0 portlist=55 admin=enable -port set property unit=0 portlist=129 admin=enable -port set property unit=0 portlist=130 admin=enable +port set property unit=0 portlist=129 admin=disable +port set property unit=0 portlist=130 admin=disable diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/qos.json.j2 b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/sai.profile b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/sai.profile new file mode 100644 index 000000000000..e7b5f90ac88a --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/sai.profile @@ -0,0 +1,3 @@ +SAI_INIT_LED_CONFIG_FILE=/usr/share/sonic/hwsku/led.bin +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps +SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/default_sku b/device/cig/x86_64-cig_cs6436_54p-r0/default_sku new file mode 100644 index 000000000000..24afbb73b770 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/default_sku @@ -0,0 +1 @@ +Cig-CS6436-54P t1 diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/installer.conf b/device/cig/x86_64-cig_cs6436_54p-r0/installer.conf new file mode 100644 index 000000000000..ea6b4f6ebe31 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer" diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py new file mode 100755 index 000000000000..5019b9c40a9a --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/7-0057/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py new file mode 100755 index 000000000000..70d50e6c3458 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py @@ -0,0 +1,93 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path +import logging + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/5-005a", + "/sys/bus/i2c/devices/5-005b"] + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open %s file !", attr_path) + + retval = retval.rstrip('\r\n') + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + attr_file = 'psu_power_good' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU status + if (attr_value == 1): + status = 1 + + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_absent = 0 + attr_file ='psu_present' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU presence + if (attr_value == 1): + status = 1 + + return status + diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py new file mode 100755 index 000000000000..2863b80c9950 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 1 + _port_end = 54 + _qsfp_port_start = 49 + _ports_in_block = 54 + + _port_to_eeprom_mapping = {} + _global_port_pres_dict = {} + + _port_to_i2c_mapping = { + 1 : 8, + 2 : 9, + 3 : 10, + 4 : 11, + 5 : 12, + 6 : 13, + 7 : 14, + 8 : 15, + 9 : 16, + 10: 17, + 11 : 18, + 12 : 19, + 13 : 20, + 14 : 21, + 15 : 22, + 16 : 23, + 17 : 24, + 18 : 25, + 19 : 26, + 20 : 27, + 21 : 28, + 22 : 29, + 23 : 30, + 24 : 31, + 25 : 32, + 26 : 33, + 27 : 34, + 28 : 35, + 29 : 36, + 30 : 37, + 31 : 38, + 32 : 39, + 33 : 40, + 34 : 41, + 35 : 42, + 36 : 43, + 37 : 44, + 38 : 45, + 39 : 46, + 40 : 47, + 41 : 48, + 42 : 49, + 43 : 50, + 44 : 51, + 45 : 52, + 46 : 53, + 47 : 54, + 48 : 55, + 49 : 56, + 50 : 57, + 51 : 60, + 52 : 61, + 53 : 62, + 54 : 63, + } + + _qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + time.sleep(1) + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error:try again to read file failed: %s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + if reg_value == '1': + return True + + reg_file.close() + if reg_value == '1': + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + self._global_port_pres_dict[port_num] = '0' + + + def __init__(self): + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' + for x in range(self._port_start, self._port_end + 1): + port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x]) + self._port_to_eeprom_mapping[x] = port_eeprom_path + + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps,'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + + if lpmode == 1: + reg_file.write('1') + elif lpmode == 0: + reg_file.write('0') + reg_file.close() + + return True + + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + + if reg_value == '1': + return True + + return False + + def get_transceiver_change_event(self): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) + + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf b/device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf new file mode 100644 index 000000000000..22cd3ccda958 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf @@ -0,0 +1,13 @@ +# libsensors configuration file + +chip "cs6436_54p_fan-*" + label fan1 "front fan 1" + label fan2 "front fan 2" + label fan3 "front fan 3" + label fan4 "front fan 4" + label fan5 "front fan 5" + label fan6 "rear fan 1" + label fan7 "rear fan 2" + label fan8 "rear fan 3" + label fan9 "rear fan 4" + label fan10 "rear fan 5" diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/buffers.json.j2 b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/buffers.json.j2 old mode 100755 new mode 100644 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/led.bin b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/led.bin new file mode 100644 index 0000000000000000000000000000000000000000..8b3490ca3b7c9f2a0b934b770a56d512277844c0 GIT binary patch literal 652 zcmWN`$uk0Q7{}qC8Dp4HN(*sK%2r9)3gv2vwBQ;p(j~cA{&mmco#*||Clo>mb0Hkg zyI2S{)>vhg2Rz^@PkF)<9`l$-JmNXedB!s~*kGM?Uh4R3hOYhLk+GqWKi{0aXuml self._port_end: + return False + path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + time.sleep(1) + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error:try again to read file failed: %s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + if reg_value == '1': + return True + + reg_file.close() + if reg_value == '1': + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + self._global_port_pres_dict[port_num] = '0' + + def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' for x in range(self._port_start, self._port_end + 1): port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x]) self._port_to_eeprom_mapping[x] = port_eeprom_path - - SfpUtilBase.__init__(self) + + self.init_global_port_presence() + SfpUtilBase.__init__(self) def reset(self, port_num): # Check for invalid port_num @@ -107,41 +152,88 @@ def reset(self, port_num): reg_file.write('0') reg_file.close() return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps,'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + + if lpmode == 1: + reg_file.write('1') + elif lpmode == 0: + reg_file.write('0') + reg_file.close() + + return True - def set_low_power_mode(self, port_nuM, lpmode): - raise NotImplementedError def get_low_power_mode(self, port_num): - raise NotImplementedError - - def get_presence(self, port_num): # Check for invalid port_num - if port_num < self._port_start or port_num > self._port_end: - return False - path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" port_ps = path.format(self._port_to_i2c_mapping[port_num]) - try: reg_file = open(port_ps) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to open file:%s %s" % (str(e), port_ps) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + reg_file.close() return False + + reg_file.close() - reg_value = reg_file.readline().rstrip() if reg_value == '1': return True return False - + def get_transceiver_change_event(self): - """ - TODO: This function need to be implemented - when decide to support monitoring SFP(Xcvrd) - on this platform. - """ - raise NotImplementedError + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) + @property def port_start(self): diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/sensors.conf b/device/cig/x86_64-cig_cs6436_56p-r0/sensors.conf old mode 100755 new mode 100644 diff --git a/platform/nephos/one-image.mk b/platform/nephos/one-image.mk index 3651325456c7..60254051c5b5 100644 --- a/platform/nephos/one-image.mk +++ b/platform/nephos/one-image.mk @@ -8,7 +8,10 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9130_32X_PLATFORM_MODULE) \ $(INGRASYS_S9230_64X_PLATFORM_MODULE) \ $(ACCTON_AS7116_54X_PLATFORM_MODULE) \ - $(CIG_CS6436_56P_PLATFORM_MODULE) + $(CIG_CS6436_56P_PLATFORM_MODULE) \ + $(CIG_CS6436_54P_PLATFORM_MODULE) \ + $(CIG_CS5435_54P_PLATFORM_MODULE) + ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/nephos/platform-modules-cig.mk b/platform/nephos/platform-modules-cig.mk index 98bbadf9ce3c..5cccf1692550 100644 --- a/platform/nephos/platform-modules-cig.mk +++ b/platform/nephos/platform-modules-cig.mk @@ -1,12 +1,26 @@ -# Cig CS6436 56P Platform modules +# Cig Nephos Switch Platform modules -CIG_CS6436_56P_PLATFORM_MODULE_VERSION = 1.0.0 +CIG_MTK_PLATFORM_MODULE_VERSION = 1.0.0 -export CIG_CS6436_56P_PLATFORM_MODULE_VERSION +export CIG_MTK_PLATFORM_MODULE_VERSION -CIG_CS6436_56P_PLATFORM_MODULE = sonic-platform-cig-cs6436-56p_$(CIG_CS6436_56P_PLATFORM_MODULE_VERSION)_amd64.deb +CIG_CS6436_56P_PLATFORM_MODULE = sonic-platform-cig-cs6436-56p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb $(CIG_CS6436_56P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig $(CIG_CS6436_56P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CIG_CS6436_56P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs6436_56p-r0 SONIC_DPKG_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE) \ No newline at end of file +SONIC_STRETCH_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE) + +CIG_CS6436_54P_PLATFORM_MODULE = sonic-platform-cig-cs6436-54p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb +$(CIG_CS6436_54P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig +$(CIG_CS6436_54P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(CIG_CS6436_54P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs6436_54p-r0 +SONIC_DPKG_DEBS += $(CIG_CS6436_54P_PLATFORM_MODULE) +SONIC_STRETCH_DEBS += $(CIG_CS6436_54P_PLATFORM_MODULE) + +CIG_CS5435_54P_PLATFORM_MODULE = sonic-platform-cig-cs5435-54p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb +$(CIG_CS5435_54P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig +$(CIG_CS5435_54P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(CIG_CS5435_54P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs5435_54p-r0 +SONIC_DPKG_DEBS += $(CIG_CS5435_54P_PLATFORM_MODULE) +SONIC_STRETCH_DEBS += $(CIG_CS5435_54P_PLATFORM_MODULE) diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/__init__.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/fanutil.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/fanutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/thermalutil.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/thermalutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/Makefile b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/Makefile new file mode 100644 index 000000000000..446fde4b0a70 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/Makefile @@ -0,0 +1,6 @@ +obj-m :=x86-64-cig-cs5435-54p-sysfs.o \ + x86-64-cig-cs5435-54p-cpld.o \ + x86-64-cig-cs5435-54p-fan.o \ + x86-64-cig-cs5435-54p-led.o \ + x86-64-cig-cs5435-54p-psu.o \ + x86-64-cig-cs5435-54p-sfp.o diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/i2c-algo-lpc.h b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/i2c-algo-lpc.h new file mode 100644 index 000000000000..dc9e30d16ddd --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/i2c-algo-lpc.h @@ -0,0 +1,222 @@ +/* -------------------------------------------------------------------- + + * A hwmon driver for the CIG cs5435-54P + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* -------------------------------------------------------------------- */ + +#ifndef I2C_LPC_H +#define I2C_LPC_H 1 + +/* ----- Control register bits ---------------------------------------- */ +#define I2C_LPC_PIN 0x80 +#define I2C_LPC_ESO 0x40 +#define I2C_LPC_ES1 0x20 +#define I2C_LPC_ES2 0x10 +#define I2C_LPC_ENI 0x08 + +#define I2C_LPC_STO 0x40 +#define I2C_LPC_ACK 0x01 + +/*command register*/ +#define I2C_LPC_STA 0x80 +#define I2C_LPC_ABT 0x40 + +/*status register*/ +#define I2C_LPC_TBE 0x02 +#define I2C_LPC_IBB 0x80 +#define I2C_LPC_RBF 0x01 +#define I2C_LPC_TD 0x08 + +#define I2C_LPC_START I2C_LPC_STA +#define I2C_LPC_STOP I2C_LPC_STO +#define I2C_LPC_REPSTART I2C_LPC_STA +#define I2C_LPC_IDLE + +/* ----- Status register bits ----------------------------------------- */ +/*#define I2C_LPC_PIN 0x80 as above*/ + +#define I2C_LPC_INI 0x40 /* 1 if not initialized */ +#define I2C_LPC_STS 0x20 +#define I2C_LPC_BER 0x10 +#define I2C_LPC_AD0 0x08 +#define I2C_LPC_LRB 0x08 +#define I2C_LPC_AAS 0x04 +#define I2C_LPC_LAB 0x02 +#define I2C_LPC_BB 0x80 + +/* ----- Chip clock frequencies --------------------------------------- */ +#define I2C_LPC_CLK3 0x00 +#define I2C_LPC_CLK443 0x10 +#define I2C_LPC_CLK6 0x14 +#define I2C_LPC_CLK 0x18 +#define I2C_LPC_CLK12 0x1c + +/* ----- transmission frequencies ------------------------------------- */ +#define I2C_LPC_TRNS90 0x00 /* 90 kHz */ +#define I2C_LPC_TRNS45 0x01 /* 45 kHz */ +#define I2C_LPC_TRNS11 0x02 /* 11 kHz */ +#define I2C_LPC_TRNS15 0x03 /* 1.5 kHz */ + + +#define I2C_LPC_OWNADR 0 +#define I2C_LPC_INTREG I2C_LPC_ES2 +#define I2C_LPC_CLKREG I2C_LPC_ES1 + +#define I2C_LPC_REG_TEST 0x01 +#define I2C_LPC_REG_BUS_SEL 0x80 +#define I2C_LPC_REG_DEVICE_ADDR 0x81 +#define I2C_LPC_REG_BYTE_COUNT 0x83 +#define I2C_LPC_REG_COMMAND 0x84 +#define I2C_LPC_REG_STATUS 0x85 +#define I2C_LPC_REG_DATA_RX1 0x86 +#define I2C_LPC_REG_DATA_RX2 0x87 +#define I2C_LPC_REG_DATA_RX3 0x88 +#define I2C_LPC_REG_DATA_RX4 0x89 +#define I2C_LPC_REG_DATA_TX1 0x8a +#define I2C_LPC_REG_DATA_TX2 0x8b +#define I2C_LPC_REG_DATA_TX3 0x8c +#define I2C_LPC_REG_DATA_TX4 0x8d + + +#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 +#define ADDR_REG_SFP_STATUS_TX 0X63 // write data +#define ADDR_REG_SFP_STATUS_RX 0X64 //read data +#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go +#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status + +#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20 +#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21 +#define CPLD_MASTER_INTERRUPT_ALL 0x3f +#define CPLD_MASTER_INTERRUPT_CPLD2 0x20 +#define CPLD_MASTER_INTERRUPT_CPLD1 0x10 +#define CPLD_MASTER_INTERRUPT_PSU2 0x08 +#define CPLD_MASTER_INTERRUPT_PSU1 0x04 +#define CPLD_MASTER_INTERRUPT_6320 0x02 +#define CPLD_MASTER_INTERRUPT_LSW 0x01 + + + +#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20 +#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21 +#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22 +#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23 +#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24 +#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25 + + +#define CPLD_SLAVE1_PRESENT08_REG 0x01 +#define CPLD_SLAVE1_PRESENT16_REG 0x02 +#define CPLD_SLAVE1_PRESENT24_REG 0x03 +#define CPLD_SLAVE2_PRESENT32_REG 0x04 +#define CPLD_SLAVE2_PRESENT40_REG 0x05 +#define CPLD_SLAVE2_PRESENT48_REG 0x06 + +#define CPLD_SLAVE1_RX_LOST08_REG 0x07 +#define CPLD_SLAVE1_RX_LOST16_REG 0x08 +#define CPLD_SLAVE1_RX_LOST24_REG 0x09 +#define CPLD_SLAVE2_RX_LOST32_REG 0x0a +#define CPLD_SLAVE2_RX_LOST40_REG 0x0b +#define CPLD_SLAVE2_RX_LOST48_REG 0x0c + +#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d +#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e +#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f +#define CPLD_SLAVE2_TX_FAULT32_REG 0x10 +#define CPLD_SLAVE2_TX_FAULT40_REG 0x11 +#define CPLD_SLAVE2_TX_FAULT48_REG 0x12 + +#define CPLD_SLAVE2_PRESENT56_REG 0x19 +#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a + + +#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001 +#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002 +#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004 +#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001 +#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002 +#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004 + +#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200 +#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400 + +#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020 + +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100 + + + + + + + +#define WAIT_TIME_OUT_COUNT 100 + + +struct i2c_algo_lpc_data { + void *data; /* private data for lolevel routines */ + void (*setlpc) (void *data, int ctl, int val); + int (*getlpc) (void *data, int ctl); + int (*getown) (void *data); + int (*getclock) (void *data); + void (*waitforpin) (void *data); + + int (*xfer_begin) (void *data); + int (*xfer_end) (void *data); + + /* Multi-master lost arbitration back-off delay (msecs) + * This should be set by the bus adapter or knowledgable client + * if bus is multi-mastered, else zero + */ + unsigned long lab_mdelay; +}; + + +struct subsys_private { + struct kset subsys; + struct kset *devices_kset; + struct list_head interfaces; + struct mutex mutex; + + struct kset *drivers_kset; + struct klist klist_devices; + struct klist klist_drivers; + struct blocking_notifier_head bus_notifier; + unsigned int drivers_autoprobe:1; + struct bus_type *bus; + + struct kset glue_dirs; + struct class *class; +}; + +void cs5435_54p_sysfs_add_client(struct i2c_client *client); +void cs5435_54p_sysfs_remove_client(struct i2c_client *client); + + +#endif /* I2C_LPC8584_H */ diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-cpld.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-cpld.c new file mode 100644 index 000000000000..68f1192e58b1 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-cpld.c @@ -0,0 +1,2209 @@ +/* + * A hwmon driver for the CIG cs5435-54P CPLD + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CPLD_USER +# include +#else +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + + + + + +/********************************************** Start ********************************************************/ + +/* + * ISA bus. + */ + +static void platform_isa_bus_release(struct device * dev) +{ + return ; +} + + +static struct device isa_bus = { + .init_name = "lpc-isa", + .release = platform_isa_bus_release, +}; + +struct isa_dev { + struct device dev; + struct device *next; + unsigned int id; +}; + +#define to_isa_dev(x) container_of((x), struct isa_dev, dev) + +static int isa_bus_match(struct device *dev, struct device_driver *driver) +{ + struct isa_driver *isa_driver = to_isa_driver(driver); + + if (dev->platform_data == isa_driver) { + if (!isa_driver->match || + isa_driver->match(dev, to_isa_dev(dev)->id)) + return 1; + dev->platform_data = NULL; + } + return 0; +} + +static int isa_bus_probe(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->probe) + return isa_driver->probe(dev, to_isa_dev(dev)->id); + + return 0; +} + +static int isa_bus_remove(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->remove) + return isa_driver->remove(dev, to_isa_dev(dev)->id); + + return 0; +} + +static void isa_bus_shutdown(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->shutdown) + isa_driver->shutdown(dev, to_isa_dev(dev)->id); +} + +static int isa_bus_suspend(struct device *dev, pm_message_t state) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->suspend) + return isa_driver->suspend(dev, to_isa_dev(dev)->id, state); + + return 0; +} + +static int isa_bus_resume(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->resume) + return isa_driver->resume(dev, to_isa_dev(dev)->id); + + return 0; +} + +static struct bus_type isa_bus_type = { + .name = "lpc-isa", + .match = isa_bus_match, + .probe = isa_bus_probe, + .remove = isa_bus_remove, + .shutdown = isa_bus_shutdown, + .suspend = isa_bus_suspend, + .resume = isa_bus_resume +}; + +static void isa_dev_release(struct device *dev) +{ + kfree(to_isa_dev(dev)); +} + +void lpc_unregister_driver(struct isa_driver *isa_driver) +{ + struct device *dev = isa_driver->devices; + + while (dev) { + struct device *tmp = to_isa_dev(dev)->next; + device_unregister(dev); + dev = tmp; + } + driver_unregister(&isa_driver->driver); +} + + +int lpc_register_driver(struct isa_driver *isa_driver, unsigned int ndev) +{ + int error; + unsigned int id; + + isa_driver->driver.bus = &isa_bus_type; + isa_driver->devices = NULL; + + error = driver_register(&isa_driver->driver); + if (error) + return error; + + for (id = 0; id < ndev; id++) { + struct isa_dev *isa_dev; + + isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL); + if (!isa_dev) { + error = -ENOMEM; + break; + } + + isa_dev->dev.parent = &isa_bus; + isa_dev->dev.bus = &isa_bus_type; + + dev_set_name(&isa_dev->dev, "%s.%u", + isa_driver->driver.name, id); + isa_dev->dev.platform_data = isa_driver; + isa_dev->dev.release = isa_dev_release; + isa_dev->id = id; + + isa_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24); + isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask; + + error = device_register(&isa_dev->dev); + if (error) { + put_device(&isa_dev->dev); + break; + } + + if (isa_dev->dev.platform_data) { + isa_dev->next = isa_driver->devices; + isa_driver->devices = &isa_dev->dev; + } else + device_unregister(&isa_dev->dev); + } + + if (!error && !isa_driver->devices) + error = -ENODEV; + + if (error) + isa_unregister_driver(isa_driver); + + return error; +} + + +int lpc_bus_init(void) +{ + int error; + + error = bus_register(&isa_bus_type); + if (!error) { + error = device_register(&isa_bus); + if (error) + bus_unregister(&isa_bus_type); + } + return error; +} + +void lpc_bus_exit(void) +{ + + device_unregister(&isa_bus); + + bus_unregister(&isa_bus_type); +} + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +/* + * module parameters: + */ +static int i2c_debug = 0; +static struct mutex lpc_lock; + + +#define DEB2(x) if (i2c_debug == 2) x +#define DEB3(x) if (i2c_debug == 3) x + /* print several statistical values */ +#define DEBPROTO(x) if (i2c_debug == 9) x; + /* debug the protocol by showing transferred bits */ +#define DEF_TIMEOUT 160 + + + +/* setting states on the bus with the right timing: */ + +#define set_lpc(adap, ctl, val) adap->setlpc(adap->data, ctl, val) +#define get_lpc(adap, ctl) adap->getlpc(adap->data, ctl) +#define get_own(adap) adap->getown(adap->data) +#define get_clock(adap) adap->getclock(adap->data) +#define i2c_outaddr(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DEVICE_ADDR, val) + +#define i2c_outbyte1(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX1, val) +#define i2c_outbyte2(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX2, val) +#define i2c_outbyte3(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX3, val) +#define i2c_outbyte4(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX4, val) +#define i2c_inbyte1(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX1) +#define i2c_inbyte2(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX2) +#define i2c_inbyte3(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX3) +#define i2c_inbyte4(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX4) + + + +#define LPC_FPRINTF_LOG_PATH "/tmp/file.log" +struct file *lpc_fprintf_file = NULL; + +static int lpc_fprintf_debug(const char *fmt, ...) +{ + char lpc_fprintf_buf[256]={0}; + struct va_format vaf; + va_list args; + int r; + mm_segment_t old_fs; + struct timeval tv; + struct rtc_time tm; + + do_gettimeofday(&tv); + + rtc_time_to_tm(tv.tv_sec,&tm); + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + r=snprintf(lpc_fprintf_buf,sizeof(lpc_fprintf_buf),"[%04d.%08d] %pV\n",tm.tm_sec, (int)tv.tv_usec, &vaf); + va_end(args); + old_fs = get_fs(); + set_fs(KERNEL_DS); + vfs_write(lpc_fprintf_file, (char *)&lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); + set_fs(old_fs); + memset(lpc_fprintf_buf,0x0,sizeof(lpc_fprintf_buf)); + return r; + +} + + + +static int lpc_fprintf_init(void) +{ + printk("lpc_fprintf_init.\n"); + + if(lpc_fprintf_file == NULL) + lpc_fprintf_file = filp_open(LPC_FPRINTF_LOG_PATH, O_RDWR | O_APPEND | O_CREAT, 0644); + + if (IS_ERR(lpc_fprintf_file)) { + printk("Error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH); + return -1; + } + + return 0; +} + +static int lpc_fprintf_exit(void) +{ + printk("lpc_fprintf_exit.\n"); + + if(lpc_fprintf_file != NULL) + filp_close(lpc_fprintf_file, NULL); + + return 0; +} + + +/* other auxiliary functions */ + + +void print_reg(struct i2c_algo_lpc_data *adap) +{ + unsigned char status; + DEBPROTO(lpc_fprintf_debug("================================================\n");) + status = get_lpc(adap, I2C_LPC_REG_BUS_SEL); + DEBPROTO(lpc_fprintf_debug("%s select reg %x : %x\n",__func__,I2C_LPC_REG_BUS_SEL, status);) + status = get_lpc(adap, I2C_LPC_REG_BYTE_COUNT); + DEBPROTO(lpc_fprintf_debug("%s count reg %x : %x\n",__func__,I2C_LPC_REG_BYTE_COUNT, status);) + + status = get_lpc(adap, I2C_LPC_REG_COMMAND); + DEBPROTO(lpc_fprintf_debug("%s command reg %x : %x\n",__func__,I2C_LPC_REG_COMMAND, status);) + status = get_lpc(adap, I2C_LPC_REG_DEVICE_ADDR); + DEBPROTO(lpc_fprintf_debug("%s address reg %x : %x\n",__func__,I2C_LPC_REG_DEVICE_ADDR, status);) + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + DEBPROTO(lpc_fprintf_debug("%s status reg %x : %x\n",__func__,I2C_LPC_REG_STATUS, status);) +} + + + +static void i2c_repstart(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_REPSTART); +} + +static void i2c_stop(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_STOP); + udelay(60); + set_lpc(adap, I2C_LPC_REG_COMMAND, 0x00); +} + + + + +static void i2c_start(struct i2c_algo_lpc_data *adap) +{ + print_reg(adap); + + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_START); + + print_reg(adap); +} + + + + +static int wait_for_bb(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus free status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is free status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout for free busy status : %x\n",__func__,status);) + return -ETIMEDOUT; + } + + + + return 0; +} + + +static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + unsigned char status; + + + while (--timeout) { + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus empty status : %x\n",__func__,status);) + + if(mode == 1) + { + if((status & I2C_LPC_IBB) && (status & I2C_LPC_TBE)) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + else + { + if(status & I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Empty\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + +static int wait_for_bf(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus full status : %x\n",__func__,status);) + + if(status & I2C_LPC_RBF) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is full status : %x\n",__func__,status);) + break; + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Full\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + +static int wait_for_td(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status=0; + + while (--timeout) { + udelay(4); + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus done status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is done status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Done\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + + +static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) +{ + int timeout = DEF_TIMEOUT; + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + + while ((*status & I2C_LPC_TBE) && --timeout) { + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + } + + if (timeout == 0) + return -ETIMEDOUT; + + + return 0; +} + + +static int lpc_doAddress(struct i2c_algo_lpc_data *adap,struct i2c_msg *msg) +{ + unsigned short flags = msg->flags; + unsigned char addr; + + addr = msg->addr << 1; + if (flags & I2C_M_RD) + { + addr |= 1; + DEBPROTO(lpc_fprintf_debug("step 7 : read mode then write device address 0x%x\n",addr);) + } + else + { + DEBPROTO(lpc_fprintf_debug("step 2 : write mode then write device address 0x%x\n",addr);) + } + + if (flags & I2C_M_REV_DIR_ADDR) + { + addr ^= 1; + + } + i2c_outaddr(adap, addr); + return 0; + +} + + +static int lpc_sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + int i = 0,timeout=0; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 3 : write register count %x\n",count);) + + if((count -i) >= 4) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + i2c_outbyte4(adap, buf[i+3] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+3,buf[i+3]);) + i += 4; + } + else if((count -i) == 3) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 5-1 : Delay 6mS \n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 5-2 : Start to transfrom \n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 5-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 6 : Waiting for BE\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 6 : Timeout waiting for BE \n");) + return -EREMOTEIO; + } + }while (i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes failed \n",count);) + return -EIO; + } +} + +static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + int i=0,timeout=0; + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 8 : write register count %d\n",count);) + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 9-1 : Delay 6mS\n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 9-2 : Start to receive data\n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 9-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 10 : Waiting for TD\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 10 : Timeout waiting for TD \n");) + return -EREMOTEIO; + } + + if((count -i) >= 4) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + buf[i+3] = 0xff & i2c_inbyte4(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+3,buf[i+3]);) + + i += 4; + } + else if((count -i) == 3) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + + }while(i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes failed \n",count);) + return -EIO; + } +} + + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; +#define LPC_I2C_MAX_NCHANS 6 + + +struct lpc_iic { + struct i2c_adapter *virt_adaps[LPC_I2C_MAX_NCHANS]; + u8 last_chan; /* last register value */ +}; + + +static int lpc_master_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + struct i2c_msg *pmsg; + int i; + int ret=0; + + mutex_lock(&lpc_lock); + + if (adap->xfer_begin) + adap->xfer_begin(&i2c_adap->nr); + + + for (i = 0;ret >= 0 && i < num; i++) { + pmsg = &msgs[i]; + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", + pmsg->flags & I2C_M_RD ? "read" : "write", + pmsg->len, pmsg->addr, i + 1, num);) + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", + i, msgs[i].addr, msgs[i].flags, msgs[i].len);) + + if (pmsg->flags & I2C_M_RD) { + ret = lpc_readbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only read %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: read %d bytes.\n",ret)); + } + } else { + + ret = lpc_sendbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only wrote %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: wrote %d bytes.\n",ret)); + } + } + } + + if (adap->xfer_end) + adap->xfer_end(&i2c_adap->nr); + + mutex_unlock(&lpc_lock); + + DEBPROTO(lpc_fprintf_debug("ret = 0x%x num = 0x%x i = 0x%x.\n",ret,num,i)); + + return ret = (ret < 0) ? ret : num; +} + + +static u32 lpc_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + +/* exported algorithm data: */ +static const struct i2c_algorithm lpc_algo = { + .master_xfer = lpc_master_xfer, + //.smbus_xfer = lpc_smbus_xfer, + .functionality = lpc_func, +}; + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +#define DEFAULT_BASE 0x0a00 + +static int lpc_base= 0x0a00; +static u8 __iomem *lpc_base_iomem; + +static int lpc_irq; +static int lpc_clock = 0x1c; +static int lpc_own = 0x55; +static int lpc_mmapped; + +static unsigned long lpc_base_addr = 0x0a00; +static unsigned int lpc_io_space_size = 2; + +static unsigned long LPC_INDEX_REG; +static unsigned long LPC_DATA_REG; + + +/* notice : removed static struct i2c_lpc_iic gpi; code - + this module in real supports only one device, due to missing arguments + in some functions, called from the algo-lpc module. Sometimes it's + need to be rewriten - but for now just remove this for simpler reading */ + +static wait_queue_head_t lpc_wait; +static int lpc_pending; +static spinlock_t lock; +static spinlock_t lpc_slock; + +static struct i2c_adapter lpc_iic_ops; + +struct cpld_dev_type { + struct resource *io_resource; + struct semaphore sem; + struct cdev cdev; +}; + +struct cpld_dev_type *cpld_device; + + +/* ----- local functions ---------------------------------------------- */ + +static void lpc_cpld_setbyte(void *data, int ctl, int val) +{ + outb(ctl, LPC_INDEX_REG); + mb(); + + outb(val, LPC_DATA_REG); + mb(); +} + +static int lpc_cpld_getbyte(void *data, int ctl) +{ + u8 val = 0; + + outb(ctl, LPC_INDEX_REG); + mb(); + + val = inb(LPC_DATA_REG); + mb(); + + return val; +} + +static void lpc_iic_setbyte(void *data, int ctl, int val) +{ + if (!cpld_device) + { + return ; + } + + if (down_interruptible(&cpld_device->sem)) + { + return ; + } + + + lpc_cpld_setbyte(data,ctl,val); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) +} + + +static int lpc_iic_getbyte(void *data, int ctl) +{ + u8 val = 0; + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + val = lpc_cpld_getbyte(data,ctl); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) + return val; +} + +int cig_cpld_read_register(u8 reg_off, u8 *val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + *val = lpc_cpld_getbyte(cpld_device, reg_off); + + up(&cpld_device->sem); + + return 0; +} +EXPORT_SYMBOL(cig_cpld_read_register); + +int cig_cpld_write_register(u8 reg_off, u8 val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + lpc_cpld_setbyte(cpld_device, reg_off, val); + up(&cpld_device->sem); + return 0; +} +EXPORT_SYMBOL(cig_cpld_write_register); + + + +static int lpc_iic_getown(void *data) +{ + return (lpc_own); +} + + +static int lpc_iic_getclock(void *data) +{ + return (lpc_clock); +} + +static void lpc_iic_waitforpin(void *data) +{ + DEFINE_WAIT(wait); + int timeout = 2; + unsigned long flags; + + if (lpc_irq > 0) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 0) { + spin_unlock_irqrestore(&lock, flags); + prepare_to_wait(&lpc_wait, &wait, TASK_INTERRUPTIBLE); + if (schedule_timeout(timeout*HZ)) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 1) { + lpc_pending = 0; + } + spin_unlock_irqrestore(&lock, flags); + } + finish_wait(&lpc_wait, &wait); + } else { + lpc_pending = 0; + spin_unlock_irqrestore(&lock, flags); + } + } else { + udelay(100); + } +} + + +static irqreturn_t lpc_iic_handler(int this_irq, void *dev_id) { + spin_lock(&lock); + lpc_pending = 1; + spin_unlock(&lock); + wake_up_interruptible(&lpc_wait); + return IRQ_HANDLED; +} + +static int board_id = 0; + + +static int lpc_iic_select(void *data) +{ + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step 1 : selest channel id = %d\n",chan_id);) + lpc_iic_setbyte(data,I2C_LPC_REG_BUS_SEL,chan_id); + + return 0; +} + +static int lpc_iic_deselect(void *data) +{ + + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step last :deselect channel id = %d\n",chan_id);) + + return 0; +} + + +/* ------------------------------------------------------------------------ + * Encapsulate the above functions in the correct operations structure. + * This is only done when more than one hardware adapter is supported. + */ +static struct i2c_algo_lpc_data lpc_iic_data = { + .setlpc = lpc_iic_setbyte, + .getlpc = lpc_iic_getbyte, + .getown = lpc_iic_getown, + .getclock = lpc_iic_getclock, + .waitforpin = lpc_iic_waitforpin, + .xfer_begin = lpc_iic_select, + .xfer_end = lpc_iic_deselect, +}; + +#include + +static struct i2c_adapter lpc_iic_arr_ops[LPC_I2C_MAX_NCHANS] = {0}; + +static void dummy_setscl(void *data, int state) +{ + return; +} + +static void dummy_setsda(void *data, int state) +{ + return; + +} + +static int dummy_getscl(void *data) +{ + return 1; + +} + +static int dummy_getsda(void *data) +{ + return 1; +} + + +static struct i2c_algo_bit_data dummy_algo_data = { + .setsda = dummy_setsda, + .setscl = dummy_setscl, + .getsda = dummy_getsda, + .getscl = dummy_getscl, + .udelay = 50, + .timeout = HZ, +}; + + +static int dummy_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + return 1; +} + +static u32 dummy_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + + +static const struct i2c_algorithm dummy_algo = { + .master_xfer = dummy_xfer, + .functionality = dummy_func, +}; + + + +static struct i2c_adapter i2c_dummy = { + .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .algo_data = &dummy_algo_data, + .algo = &dummy_algo, + .name = "i2c_dummy", +}; + + +static int lpc_iic_match(struct device *dev, unsigned int id) +{ + /* sanity checks for lpc_mmapped I/O */ + + DEB2(printk("lpc_iic_match\n");) + + + if (lpc_base < DEFAULT_BASE) { + dev_err(dev, "incorrect lpc_base address (%#x) specified " + "for lpc_mmapped I/O\n", lpc_base); + return 0; + } + + if (lpc_base == 0) { + lpc_base = DEFAULT_BASE; + } + return 1; +} + +static int lpc_iic_probe(struct device *dev, unsigned int id) +{ + int rval,num; + + lpc_fprintf_init(); + + DEB2(printk("lpc_iic_probe\n");) + + mutex_init(&lpc_lock); + + for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) + { + lpc_iic_arr_ops[num].dev.parent = dev; + lpc_iic_arr_ops[num].owner = THIS_MODULE; + lpc_iic_arr_ops[num].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + lpc_iic_arr_ops[num].algo = &lpc_algo; + lpc_iic_arr_ops[num].algo_data = &lpc_iic_data, + lpc_iic_arr_ops[num].nr=num; + snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num])); + rval |= i2c_add_adapter(&lpc_iic_arr_ops[num]); + DEB2(printk("%s\n",lpc_iic_arr_ops[num].name);) + } + + return 0; +} + +static int lpc_iic_remove(struct device *dev, unsigned int id) +{ + int num; + DEB2(printk("lpc_iic_remove\n")); + + lpc_fprintf_exit(); + for(num = LPC_I2C_MAX_NCHANS - 1; num >= 0 ;num--) + i2c_del_adapter(&lpc_iic_arr_ops[num]); + + + return 0; +} + +static struct isa_driver i2c_lpc_driver = { + .match = lpc_iic_match, + .probe = lpc_iic_probe, + .remove = lpc_iic_remove, + .driver = { + .owner = THIS_MODULE, + .name = "lpc-iic", + }, +}; + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ + +static int cpld_major = 0; +static int cpld_minor = 0; + +struct cpld_rw_msg { + unsigned char addr; + unsigned char data; +}; + + +static struct cpld_rw_msg param_read = {-1}; +static struct cpld_rw_msg param_write = {-1}; +static struct cpld_rw_msg param_reads = {-1}; +static struct cpld_rw_msg param_writes = {-1}; + +void cpld_sysfs_kobj_release(struct kobject *kobj) +{ + return; +} + +int cpld_sysfs_add_attr(struct kobject* kobj, char* attr_name) +{ + + struct attribute *attr; + + attr = kmalloc(sizeof(struct attribute), GFP_KERNEL); + attr->name = attr_name; + attr->mode = 0644; + + return sysfs_create_file(kobj, attr); +} + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data); +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data); + + +static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buffer) +{ + u8 val=0,ret=0,year=0,month=0,day=0,cpld_m=0,cpld_1=0,cpld_2=0; + + if (0 == strcmp(attr->name, "read")) + { + val = lpc_iic_getbyte(NULL,param_read.addr); + ret = sprintf(buffer,"read : addr = 0x%x val = 0x%x\n",param_read.addr, val); + + } + else if (0 == strcmp(attr->name, "write")) + { + lpc_iic_setbyte(NULL, param_write.addr,param_write.data); + ret = sprintf(buffer,"write : addr = 0x%x val = 0x%x\n",param_write.addr, param_write.data); + } + else if (0 == strcmp(attr->name, "version")) + { + cpld_m = lpc_iic_getbyte(NULL, 0x02); + year = lpc_iic_getbyte(NULL, 0x03); + month = lpc_iic_getbyte(NULL, 0x04); + day = lpc_iic_getbyte(NULL, 0x05); + + cig_cpld_read_slave_cpld_register(0x1d,&cpld_1); + cig_cpld_read_slave_cpld_register(0x1e,&cpld_2); + + ret = sprintf(buffer,"Main CPLD version : V%02x\n"\ + "Main CPLD date : 20%02x-%02x-%02x\n"\ + "Slave 1 CPLD version : V%02x\n"\ + "Slave 2 CPLD version : V%02x\n",cpld_m,year,month,day,cpld_1,cpld_2); + } + if (0 == strcmp(attr->name, "reads")) + { + ret = cig_cpld_read_slave_cpld_register(param_reads.addr,&val); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"reads : addr = 0x%x val = 0x%x\n",param_reads.addr, val); + + } + else if (0 == strcmp(attr->name, "writes")) + { + ret = cig_cpld_write_slave_cpld_register(param_writes.addr,param_writes.data); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"writes : addr = 0x%x val = 0x%x\n",param_writes.addr, param_writes.data); + } + + + return ret; + +} + +static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t count) +{ + int param[3]; + + if (0 == strcmp(attr->name, "read")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_read.addr = param[0]; + } + else if (0 == strcmp(attr->name, "write")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_write.addr = param[0]; + param_write.data = param[1]; + } + if (0 == strcmp(attr->name, "reads")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_reads.addr = param[0]; + } + else if (0 == strcmp(attr->name, "writes")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_writes.addr = param[0]; + param_writes.data = param[1]; + } + return count; +} + + + +static struct sysfs_ops cpld_sysfs_ops = +{ + .show = cpld_sysfs_show, + .store = cpld_sysfs_store, +}; + +static struct kobj_type cpld_kobj_type = +{ + .release = cpld_sysfs_kobj_release, + .sysfs_ops = &cpld_sysfs_ops, + .default_attrs = NULL, +}; + + +static const char driver_name[] = "cpld_drv"; +static atomic_t cpld_available = ATOMIC_INIT(1); +static struct class *cpld_class; +static struct device *cpld_dev; + + + +#define CPLD_IOC_MAGIC '[' + +#define CPLD_IOC_RDREG _IOR(CPLD_IOC_MAGIC, 0, struct cpld_rw_msg) +#define CPLD_IOC_WRREG _IOW(CPLD_IOC_MAGIC, 1, struct cpld_rw_msg) + +#define CPLD_IOC_MAXNR 2 + + +int cpld_open(struct inode *inode, struct file *filp) +{ + struct cpld_dev_type *dev; + + if (! atomic_dec_and_test(&cpld_available)) { + atomic_inc(&cpld_available); + return -EBUSY; + } + + dev = container_of(inode->i_cdev, struct cpld_dev_type, cdev); + filp->private_data = dev; + + return 0; +} + +int cpld_release(struct inode *inode, struct file *flip) +{ + atomic_inc(&cpld_available); + return 0; +} + + +long cpld_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int rc = 0; + int err = 0; + struct cpld_dev_type *dev = (struct cpld_dev_type *)filp->private_data; + struct cpld_rw_msg msg; + + if (_IOC_TYPE(cmd) != CPLD_IOC_MAGIC) + return -ENOTTY; + if (_IOC_NR(cmd) > CPLD_IOC_MAXNR) + return -ENOTTY; + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); + if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + + if (down_interruptible(&dev->sem)) + return -ERESTARTSYS; + + switch(cmd){ + case CPLD_IOC_RDREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + msg.data = lpc_cpld_getbyte(dev, msg.addr); + rc = copy_to_user((void __user *)arg, &msg, sizeof(msg)); + } + break; + + case CPLD_IOC_WRREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + lpc_cpld_setbyte(dev, msg.addr, msg.data); + } + break; + default: + rc = -ENOTTY; + break; + } + up(&dev->sem); + + return rc; +} + +struct file_operations cpld_fops = { + .owner = THIS_MODULE, + .open = cpld_open, + .unlocked_ioctl = cpld_ioctl, + .release = cpld_release, +}; + + +static void cpld_setup_cdev(struct cpld_dev_type *dev) +{ + int err, devno = MKDEV(cpld_major, cpld_minor); + + cdev_init(&dev->cdev, &cpld_fops); + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &cpld_fops; + err = cdev_add(&dev->cdev, devno, 1); + + if (err) + DEB2(printk(KERN_NOTICE "Error %d adding cpld", err);) +} +/********************************************** End ********************************************************/ + + + + +/********************************************** Start ********************************************************/ +#include +#include +#include + +static spinlock_t irq_inter_lock; +static struct delayed_work irq_inter_work; +static unsigned long irq_inter_delay; + + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<=======write=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1); + DEB2(printk("[62]=%x\n",reg_addr << 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, reg_data); + DEB2(printk("[63]=%x\n",reg_data)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x02); + DEB2(printk("<=======write=========>")); + + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<========read=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1 | 1); + DEB2(printk("[62]=%x\n",reg_addr << 1 | 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,reg_data); + DEB2(printk("[64]=%x\n",*reg_data)); + DEB2(printk("<========read=========>")); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + +struct sock *nlsk = NULL; +extern struct net init_net; +#define NETLINK_TEST 26 +#define MSG_LEN 125 +#define USER_PORT 100 +static u32 irq_present_status_low_current,irq_present_status_low_next; +static u32 irq_present_status_high_current,irq_present_status_high_next; +static u32 irq_tx_fault_status_low_current,irq_tx_fault_status_low_next; +static u32 irq_tx_fault_status_high_current,irq_tx_fault_status_high_next; +static u32 irq_rx_lost_status_low_current,irq_rx_lost_status_low_next; +static u32 irq_rx_lost_status_high_current,irq_rx_lost_status_high_next; + +static u8 irq_present_qsfp_current,irq_present_qsfp_next; +static u8 irq_interrupt_qsfp_current,irq_interrupt_qsfp_next; + +struct input_dev *cpld_input_dev; + + + +int send_usrmsg(char *pbuf, uint16_t len) +{ + struct sk_buff *nl_skb; + struct nlmsghdr *nlh; + + int ret; + + + nl_skb = nlmsg_new(len, GFP_ATOMIC); + if(!nl_skb) + { + printk("netlink alloc failure\n"); + return -1; + } + + + nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0); + if(nlh == NULL) + { + printk("nlmsg_put failaure \n"); + nlmsg_free(nl_skb); + return -1; + } + + memcpy(nlmsg_data(nlh), pbuf, len); + ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); + + return ret; +} + +static void netlink_rcv_msg(struct sk_buff *skb) +{ + + struct nlmsghdr *nlh = NULL; + char *umsg = NULL; + char kmsg[1024] = {0}; + char kmsg_tmp[16] = {0}; + u8 i = 0; + u8 tmp[3]={0}; + + if(skb->len >= nlmsg_total_size(0)) + { + nlh = nlmsg_hdr(skb); + umsg = NLMSG_DATA(nlh); + if(umsg) + { + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+1,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+25,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + + for(i = 0;i < 8;i++) + { + if(!(irq_present_qsfp_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"qsfp%02d:%1d:%1d:%1d ",i+49,tmp[0],tmp[1],0); + strcat(kmsg,kmsg_tmp); + } + + printk("kernel recv from user: %s\n", umsg); + send_usrmsg(kmsg, strlen(kmsg)); + } + } + + return ; +} + + + +struct netlink_kernel_cfg cfg = { + .input = netlink_rcv_msg, /* set recv callback */ +}; + + + +#define RANGE_OF_BYTE_SHIFT(to_arg,shift,from_arg) {to_arg &= ~(0xff << shift); to_arg |= from_arg << shift;} + + +static void irq_inter_wapper(struct work_struct * work) +{ + + u8 m_data = 0; + u8 data_high8 = 0,data_low8 = 0; + u16 data_16 = 0; + u8 status = 0; + u8 i = 0; + char kmsg[64]={0}; + u8 tmp[3] = {0}; + + DEB2(printk("CPLD_MASTER_INTERRUPT\r\n")); + + m_data = lpc_iic_getbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG); + lpc_iic_setbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG,0xff); + + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0xff); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0xff); + if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD1)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,16,status); + } + DEB2(printk("irq_present_status_low_next = %08x irq_present_status_low_current = %08x \n",irq_present_status_low_next,irq_present_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_RX_LOST08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,16,status); + } + DEB2(printk("irq_rx_lost_status_low_next = %08x irq_rx_lost_status_low_current = %08x \n",irq_rx_lost_status_low_next,irq_rx_lost_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,16,status); + } + DEB2(printk("irq_tx_fault_status_low_next = %08x irq_tx_fault_status_low_current = %08x \n",irq_tx_fault_status_low_next,irq_tx_fault_status_low_current)); + + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD2)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT32_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT40_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,16,status); + } + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,16,status); + } + + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,16,status); + } + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT56)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT56_REG,&status); + irq_present_qsfp_current = status; + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_QSFP_CR56)) + { + DEB2(printk("CPLD_SLAVE2_QSFP_CR56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_QSFP_CR56_REG,&status); + irq_interrupt_qsfp_current = status; + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_LSW)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_LSW\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU1)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU1\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU2)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU2\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_6320)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_6320\r\n")); + } + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0x0); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0x0); + + memset(tmp,0xff,sizeof(tmp)); + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i)) && (irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+1)); + tmp[0] = 1; + } + else if((irq_present_status_low_current & (0x1 << i)) && !(irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+1)); + tmp[0] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i)) && (irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+1)); + tmp[1] = 1; + } + else if((irq_tx_fault_status_low_current & (0x1 << i)) && !(irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+1)); + tmp[1] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i)) && (irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+1)); + tmp[2] = 1; + } + else if((irq_rx_lost_status_low_current & (0x1 << i)) && !(irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+1)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+1,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i)) && (irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+25)); + tmp[0] = 1; + } + else if((irq_present_status_high_current & (0x1 << i)) && !(irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+25)); + tmp[0] = 0; + + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i)) && (irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+25)); + tmp[1] = 1; + } + else if((irq_rx_lost_status_high_current & (0x1 << i)) && !(irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+25)); + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i)) && (irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+25)); + tmp[2] = 1; + } + else if((irq_tx_fault_status_high_current & (0x1 << i)) && !(irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+25)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+25,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0 ; i < 8; i++) + { + if(!(irq_present_qsfp_current & (0x1 << i)) && (irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+49)); + tmp[0] = 1; + } + else if((irq_present_qsfp_current & (0x1 << i)) && !(irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+49)); + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i)) && (irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is occured \r\n",i+49)); + tmp[1] = 1; + } + else if((irq_interrupt_qsfp_current & (0x1 << i)) && !(irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is cleaned\r\n",i+49)); + tmp[1] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"qsfp%02d:%1d:%1d:%1d ",i+49,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],0); + break; + } + } + + + irq_present_status_low_next = irq_present_status_low_current; + irq_rx_lost_status_low_next = irq_rx_lost_status_low_current; + irq_tx_fault_status_low_next = irq_tx_fault_status_low_current; + irq_present_status_high_next = irq_present_status_high_current; + irq_rx_lost_status_high_next = irq_rx_lost_status_high_current; + irq_tx_fault_status_high_next = irq_tx_fault_status_high_current; + irq_present_qsfp_next = irq_present_qsfp_current; + irq_interrupt_qsfp_next = irq_interrupt_qsfp_current; + + send_usrmsg(kmsg, strlen(kmsg)); +} + +static void disableIrq(unsigned short maskReg, unsigned short mask) +{ + u8 data = 0; + + data = lpc_iic_getbyte(NULL,maskReg); + data |= mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + +static void enableIrq(unsigned short maskReg, unsigned short mask) +{ + unsigned short data; + + data = lpc_iic_getbyte(NULL,maskReg); + data &= ~mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + + +static irqreturn_t irq_inter_isr(int irq, void *handle) +{ + + /* + * use keventd context to read the event fifo registers + * Schedule readout at least 25ms after notification for + * REVID < 4 + */ + + schedule_delayed_work(&irq_inter_work, irq_inter_delay); + + return IRQ_HANDLED; +} + + +#define CIG_CPLD_CHR_NAME "cpld" + + +static int __init cpld_init(void) +{ + int rval,rc=0; + dev_t dev; + u8 s_data; + int isr_GPIO_num = 289; + + DEB2(printk("cpld_init\n");) + +/**************************************************************************************/ + + LPC_INDEX_REG = lpc_base_addr; + LPC_DATA_REG = lpc_base_addr + 1; + + cpld_device = kzalloc(sizeof(struct cpld_dev_type), GFP_KERNEL); + if (!cpld_device) + goto error3; + cpld_device->io_resource = request_region(lpc_base_addr, + lpc_io_space_size, "lpc-i2c"); + if (!cpld_device->io_resource) { + printk("lpc: claim I/O resource fail\n"); + goto error2; + } + sema_init(&cpld_device->sem, 1); + + if (cpld_major) { + dev = MKDEV(cpld_major, cpld_minor); + rc = register_chrdev_region(dev, 1, CIG_CPLD_CHR_NAME); + } else { + rc = alloc_chrdev_region(&dev, cpld_major, 1, CIG_CPLD_CHR_NAME); + cpld_major = MAJOR(dev); + } + + cpld_setup_cdev(cpld_device); + + cpld_class = class_create(THIS_MODULE,CIG_CPLD_CHR_NAME); + if (!cpld_class) { + DEB2(printk("failed to create class\n");) + goto error1; + } + + cpld_class->p->subsys.kobj.ktype= &cpld_kobj_type; + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "read"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "write"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "reads"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "writes"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "version"); + + cpld_dev = device_create(cpld_class, NULL, dev, NULL, CIG_CPLD_CHR_NAME); + +/**************************************************************************************/ + + rval = lpc_bus_init(); + rval = lpc_register_driver(&i2c_lpc_driver, 1); + +/**************************************************************************************/ + return 0; +error1: + cdev_del(&cpld_device->cdev); + unregister_chrdev_region(dev, 1); +error2: + release_resource(cpld_device->io_resource); +error3: + kfree(cpld_device); + + return rc; +} + +static void __exit cpld_exit(void) +{ + DEB2(printk("cpld_exit\n")); + + if (nlsk){ + netlink_kernel_release(nlsk); /* release ..*/ + nlsk = NULL; + } + + + lpc_unregister_driver(&i2c_lpc_driver); + lpc_bus_exit(); + dev_t devno = MKDEV(cpld_major, cpld_minor); + + cdev_del(&cpld_device->cdev); + if (cpld_class) { + device_destroy(cpld_class, devno); + class_destroy(cpld_class); + } + + if (cpld_device) { + if (cpld_device->io_resource) + release_resource(cpld_device->io_resource); + + kfree(cpld_device); + } + unregister_chrdev_region(devno, 1); + + +} + +module_param(cpld_major, int, S_IRUGO); +module_param(cpld_minor, int, S_IRUGO); +module_param(i2c_debug, int, S_IRUGO); +module_param(board_id, int, S_IRUGO); + +module_init(cpld_init); +module_exit(cpld_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435-54p-cpld driver"); +MODULE_LICENSE("GPL"); + + +/********************************************** End ********************************************************/ + + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-fan.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-fan.c new file mode 100644 index 000000000000..a254dae33c2c --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-fan.c @@ -0,0 +1,521 @@ +/* + * A hwmon driver for the CIG cs5435-54p fan + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define FAN_SPEED_DUTY_TO_CPLD_STEP 10 + +static struct cs5435_54p_fan_data *cs5435_54p_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + + +extern int cig_cpld_write_register(u8 reg_off, u8 val); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x41, /* fan enable/disable */ + 0x40, /* fan PWM(for all fan) */ + 0x42, /* front fan 1 speed(rpm) */ + 0x44, /* front fan 2 speed(rpm) */ + 0x46, /* front fan 3 speed(rpm) */ + 0x48, /* front fan 4 speed(rpm) */ + 0x4a, /* front fan 5 speed(rpm) */ + 0x43, /* rear fan 1 speed(rpm) */ + 0x45, /* rear fan 2 speed(rpm) */ + 0x47, /* rear fan 3 speed(rpm) */ + 0x49, /* rear fan 4 speed(rpm) */ + 0x4b, /* rear fan 5 speed(rpm) */ + 0x4c, /* fan direction rear to front or front to rear */ +}; + + +/* Each client has this additional data */ +struct cs5435_54p_fan_data { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ +}; + +static struct cs5435_54p_fan_data *fan_data = NULL; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID, +}; + +enum sysfs_fan_attributes { + FAN_STATE_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN_DIRECTION, + FAN1_STATE, + FAN2_STATE, + FAN3_STATE, + FAN4_STATE, + FAN5_STATE, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, +}; + +/* Define attributes + */ +#define DECLARE_FAN_STATE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_state, S_IRUGO, fan_show_value, NULL, FAN##index##_STATE) +#define DECLARE_FAN_STATE_ATTR(index) &sensor_dev_attr_fan##index##_state.dev_attr.attr + +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index) &sensor_dev_attr_fan##index##_fault.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##index##_DUTY_CYCLE_PERCENTAGE) +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan##index##_duty_cycle_percentage.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + + +/* 5 fan state attributes in this platform */ +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(3); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(4); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(5); + + +/* 5 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5); + +/* 5 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5); + +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); + +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); + + +static struct attribute *cs5435_54p_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_STATE_ATTR(1), + DECLARE_FAN_STATE_ATTR(2), + DECLARE_FAN_STATE_ATTR(3), + DECLARE_FAN_STATE_ATTR(4), + DECLARE_FAN_STATE_ATTR(5), + DECLARE_FAN_FAULT_ATTR(1), + DECLARE_FAN_FAULT_ATTR(2), + DECLARE_FAN_FAULT_ATTR(3), + DECLARE_FAN_FAULT_ATTR(4), + DECLARE_FAN_FAULT_ATTR(5), + DECLARE_FAN_SPEED_RPM_ATTR(1), + DECLARE_FAN_SPEED_RPM_ATTR(2), + DECLARE_FAN_SPEED_RPM_ATTR(3), + DECLARE_FAN_SPEED_RPM_ATTR(4), + DECLARE_FAN_SPEED_RPM_ATTR(5), + DECLARE_FAN_DUTY_CYCLE_ATTR(), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), + NULL +}; + +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + if (reg_val +== 0xFF) { + return 100; + } + return ((u32)(reg_val) * 100)/ 255; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + if (duty_cycle >= FAN_MAX_DUTY_CYCLE) { + return 0xFF; + } + + return 255 / 10 * (duty_cycle / 10); +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_is_state(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct cs5435_54p_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value <= 0 || value > FAN_MAX_DUTY_CYCLE) + return -EINVAL; + + cig_cpld_write_register(fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + + return count; +} + +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value,fan_index; + u8 mask,reg_val; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + fan_index = attr->index - FAN1_DIRECTION; + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (!(value == 0 || value == 1)) + return -EINVAL; + + + cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val); + + if(value == 1) + { + reg_val |= (1 << fan_index); + } + else + { + reg_val &= ~(1 << fan_index); + } + + cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val); + + return count; +} + + + + + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + cs5435_54p_fan_update_device(dev); + + struct cs5435_54p_fan_data *data = fan_data; + + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + + case FAN1_STATE: + case FAN2_STATE: + case FAN3_STATE: + case FAN4_STATE: + case FAN5_STATE: + //printk("FAN_STATE_REG: 0x%x\n", data->reg_val[FAN_STATE_REG]); + //printk("index: %d\n", attr->index); + ret = sprintf(buf, "%d\n", + reg_val_to_is_state(data->reg_val[FAN_STATE_REG], + attr->index - FAN1_STATE)); + break; + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: +// printk("FAN_seed_REG: 0x%x\n", data->reg_val[attr->index]); +// printk("index: %d\n", attr->index); + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group cs5435_54p_fan_group = { + .attrs = cs5435_54p_fan_attributes, +}; + +static struct cs5435_54p_fan_data *cs5435_54p_fan_update_device(struct device *dev) +{ + struct cs5435_54p_fan_data *data = fan_data; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + u8 status; + (void)cig_cpld_read_register(fan_reg[i], &status); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int cs5435_54p_fan_probe(struct platform_device *pdev) +{ + int status = -1; + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &cs5435_54p_fan_group); + if (status) { + goto exit; + + } + + fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(fan_data->hwmon_dev)) { + status = PTR_ERR(fan_data->hwmon_dev); + goto exit_remove; + } + + dev_info(&pdev->dev, "cs5435_54p_fan\n"); + + return 0; + +exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &cs5435_54p_fan_group); +exit: + return status; +} + +static int cs5435_54p_fan_remove(struct platform_device *pdev) +{ + hwmon_device_unregister(fan_data->hwmon_dev); + sysfs_remove_group(&fan_data->pdev->dev.kobj, &cs5435_54p_fan_group); + + return 0; +} + +#define DRVNAME "cs5435_54p_fan" + +static struct platform_driver cs5435_54p_fan_driver = { + .probe = cs5435_54p_fan_probe, + .remove = cs5435_54p_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + + + + + +static int __init cs5435_54p_fan_init(void) +{ + int ret; + + cig_cpld_write_register(0x40, duty_cycle_to_reg_val(50)); + + ret = platform_driver_register(&cs5435_54p_fan_driver); + if (ret < 0) { + goto exit; + } + + fan_data = kzalloc(sizeof(struct cs5435_54p_fan_data), GFP_KERNEL); + if (!fan_data) { + ret = -ENOMEM; + platform_driver_unregister(&cs5435_54p_fan_driver); + goto exit; + } + + mutex_init(&fan_data->update_lock); + fan_data->valid = 0; + + fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(fan_data->pdev)) { + ret = PTR_ERR(fan_data->pdev); + platform_driver_unregister(&cs5435_54p_fan_driver); + kfree(fan_data); + goto exit; + } + +exit: + return ret; +} + +static void __exit cs5435_54p_fan_exit(void) +{ + platform_device_unregister(fan_data->pdev); + platform_driver_unregister(&cs5435_54p_fan_driver); + kfree(fan_data); +} + +MODULE_AUTHOR("CIG"); +MODULE_DESCRIPTION("cs5435_54p_fan driver"); +MODULE_LICENSE("GPL"); + +module_init(cs5435_54p_fan_init); +module_exit(cs5435_54p_fan_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-led.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-led.c new file mode 100644 index 000000000000..dae49967592e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-led.c @@ -0,0 +1,594 @@ +/* + * A hwmon driver for the CIG cs5435-54P LED + * + * Copyright (C) 2018 Cambridge, Inc. + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "cs5435_54p_led" + +struct cs5435_54p_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[6]; /* 0: system & location + 1: PSU1 &PSU12 + 2: fan & management + 3: console & ToD + 4-5 : fan1-fan5*/ +}; + +static struct cs5435_54p_led_data *ledctl = NULL; + +/* LED related data + */ +#define LED_TYPE_PSU1_REG_MASK 0x0C +#define LED_MODE_PSU1_GREEN_MASK 0x08 +#define LED_MODE_PSU1_RED_MASK 0x04 +#define LED_MODE_PSU1_AMBER_MASK 0x0C +#define LED_MODE_PSU1_OFF_MASK 0x00 + +#define LED_TYPE_PSU2_REG_MASK 0x30 +#define LED_MODE_PSU2_GREEN_MASK 0x20 +#define LED_MODE_PSU2_RED_MASK 0x10 +#define LED_MODE_PSU2_AMBER_MASK 0x30 +#define LED_MODE_PSU2_OFF_MASK 0x00 + +#define LED_TYPE_SYS_REG_MASK 0xF0 +#define LED_MODE_SYS_GREEN_MASK 0x40 +#define LED_MODE_SYS_RED_MASK 0x20 +#define LED_MODE_SYS_AMBER_MASK 0x60 +#define LED_MODE_SYS_AMBER_FLASHING_MASK 0x70 +#define LED_MODE_SYS_OFF_MASK 0x00 + +#define LED_TYPE_RES_REG_MASK 0x0F +#define LED_MODE_RES_GREEN_MASK 0x04 +#define LED_MODE_RES_RED_MASK 0x02 +#define LED_MODE_RES_AMBER_MASK 0x06 +#define LED_MODE_RES_AMBER_FLASHING_MASK 0x07 +#define LED_MODE_RES_OFF_MASK 0x00 + +#define LED_TYPE_FAN_REG_MASK 0x03 +#define LED_MODE_FAN_GREEN_MASK 0x02 +#define LED_MODE_FAN_RED_MASK 0x01 +#define LED_MODE_FAN_AMBER_MASK 0x03 +#define LED_MODE_FAN_OFF_MASK 0x00 + +#define LED_TYPE_FAN1_REG_MASK 0x03 +#define LED_TYPE_FAN2_REG_MASK 0x0C +#define LED_TYPE_FAN3_REG_MASK 0x30 +#define LED_TYPE_FAN4_REG_MASK 0xC0 +#define LED_TYPE_FAN5_REG_MASK 0x03 + +#define LED_MODE_FANX_GREEN_MASK 0x02 +#define LED_MODE_FANX_RED_MASK 0x01 +#define LED_MODE_FANX_AMBER_MASK 0x03 +#define LED_MODE_FANX_OFF_MASK 0x00 + +enum led_type { + LED_TYPE_SYS, + LED_TYPE_PSU2, + LED_TYPE_PSU1, + LED_TYPE_FAN, + LED_TYPE_FAN1, + LED_TYPE_FAN2, + LED_TYPE_FAN3, + LED_TYPE_FAN4, + LED_TYPE_FAN5, +}; + +static const u8 led_reg[] = { + 0x30, /* system & reserved*/ + 0x31, /* fan & PSU1 & PSU2 */ + 0x32, /* FAN5 LED */ + 0x33, /* FAN1-4 LED */ +}; + + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_GREEN, + LED_MODE_AMBER, + LED_MODE_RED, + LED_MODE_GREEN_BLINK, + LED_MODE_AMBER_BLINK, + LED_MODE_RED_BLINK, + LED_MODE_GREEN_FLASHING, + LED_MODE_AMBER_FLASHING, + LED_MODE_RED_FLASHING, + LED_MODE_AUTO, + LED_MODE_UNKNOWN +}; + +struct led_type_mode { + enum led_type type; + int type_mask; + enum led_light_mode mode; + int mode_mask; +}; + +static struct led_type_mode led_type_mode_data[] = { +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_RED, LED_MODE_PSU1_RED_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK}, + +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_RED, LED_MODE_PSU2_RED_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK}, + +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_GREEN, LED_MODE_SYS_GREEN_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER, LED_MODE_SYS_AMBER_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_RED, LED_MODE_SYS_RED_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER_FLASHING, LED_MODE_SYS_AMBER_FLASHING_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_OFF, LED_MODE_SYS_OFF_MASK}, + +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_RED, LED_MODE_FAN_RED_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK}, + +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +}; + +struct fanx_info_s { + u8 cname; /* device name */ + enum led_type type; + u8 reg_id; /* map to led_reg & reg_val */ +}; + +static struct fanx_info_s fanx_info[] = { + {'1', LED_TYPE_FAN1, 3}, + {'2', LED_TYPE_FAN2, 3}, + {'3', LED_TYPE_FAN3, 3}, + {'4', LED_TYPE_FAN4, 3}, + {'5', LED_TYPE_FAN5, 2}, +}; + + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + + if (type != led_type_mode_data[i].type) + continue; + + if ((led_type_mode_data[i].type_mask & reg_val) == + led_type_mode_data[i].mode_mask) + { + return led_type_mode_data[i].mode; + } + } + + return 0; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + reg_val = led_type_mode_data[i].mode_mask | + (reg_val & (~led_type_mode_data[i].type_mask)); + break; + } + + return reg_val; +} + +static void cs5435_54p_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting cs5435_54p_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + u8 status; + cig_cpld_read_register(led_reg[i], &status); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs5435_54p_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + u8 reg, enum led_type type) +{ + u8 reg_val; + mutex_lock(&ledctl->update_lock); + + cig_cpld_read_register(reg, ®_val); + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + + cig_cpld_write_register(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs5435_54p_led_fanx_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (led_cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1); + return; + } + } +} + + +static enum led_brightness cs5435_54p_led_fanx_get(struct led_classdev *cdev) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]); + } + } + + return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[5]); +} + + +static void cs5435_54p_led_psu1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1); +} + +static enum led_brightness cs5435_54p_led_psu1_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]); +} + +static void cs5435_54p_led_psu2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2); +} + +static enum led_brightness cs5435_54p_led_psu2_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]); +} + +static void cs5435_54p_led_sys_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode,led_reg[0], LED_TYPE_SYS); +} + +static enum led_brightness cs5435_54p_led_sys_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_SYS, ledctl->reg_val[0]); +} + + +static enum led_brightness cs5435_54p_led_fan_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[1]); +} + +static void cs5435_54p_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_FAN); +} + + +static struct led_classdev cs5435_54p_leds[] = { + [LED_TYPE_SYS] = { + .name = "cs5435_54p_led::sys", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_sys_set, + .brightness_get = cs5435_54p_led_sys_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN] = { + .name = "cs5435_54p_led::fan", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fan_set, + .brightness_get = cs5435_54p_led_fan_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_PSU1] = { + .name = "cs5435_54p_led::psu1", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_psu1_set, + .brightness_get = cs5435_54p_led_psu1_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "cs5435_54p_led::psu2", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_psu2_set, + .brightness_get = cs5435_54p_led_psu2_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_FAN1] = { + .name = "cs5435_54p_led::fan1", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN2] = { + .name = "cs5435_54p_led::fan2", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN3] = { + .name = "cs5435_54p_led::fan3", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN4] = { + .name = "cs5435_54p_led::fan4", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN5] = { + .name = "cs5435_54p_led::fan5", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + } +}; + +static int cs5435_54p_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + led_classdev_suspend(&cs5435_54p_leds[i]); + } + + return 0; +} + +static int cs5435_54p_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + led_classdev_resume(&cs5435_54p_leds[i]); + } + + return 0; +} + +static int cs5435_54p_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + ret = led_classdev_register(&pdev->dev, &cs5435_54p_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(cs5435_54p_leds)) { + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&cs5435_54p_leds[i]); + } + } + + return ret; +} + +static int cs5435_54p_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + led_classdev_unregister(&cs5435_54p_leds[i]); + } + + return 0; +} + +static struct platform_driver cs5435_54p_led_driver = { + .probe = cs5435_54p_led_probe, + .remove = cs5435_54p_led_remove, + .suspend = cs5435_54p_led_suspend, + .resume = cs5435_54p_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int cs5435_54p_led_default(void) +{ + cig_cpld_write_register(0x30, 0x40);// system green led solid on +} + +static int __init cs5435_54p_led_init(void) +{ + int ret; + + ret = platform_driver_register(&cs5435_54p_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct cs5435_54p_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&cs5435_54p_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&cs5435_54p_led_driver); + kfree(ledctl); + goto exit; + } + + cs5435_54p_led_default(); + +exit: + return ret; +} + +static void __exit cs5435_54p_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&cs5435_54p_led_driver); + kfree(ledctl); +} + +module_init(cs5435_54p_led_init); +module_exit(cs5435_54p_led_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_led driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-psu.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-psu.c new file mode 100644 index 000000000000..5a7942653fc3 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-psu.c @@ -0,0 +1,946 @@ +/* + * A hwmon driver for the CIG cs5435-54P Power Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" + + + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Address scanned */ +static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; + +/* This is additional data */ +struct cs5435_54p_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 v_in; + u16 v_out; + u16 i_in; + u16 i_out; + u16 p_in; + u16 p_out; + u16 temp_input[3]; + u8 temp_fault; + u8 fan_fault; + u16 fan_duty_cycle[2]; + u16 fan_speed[2]; + u8 mfr_id[8]; + u8 mfr_model[20]; + u8 mfr_serial[20]; + u8 psu_is_present; + u8 psu_is_good; + struct i2c_client *client; + struct bin_attribute *bin; /* eeprom data */ +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static int cs5435_54p_psu_read_byte(struct i2c_client *client, u8 reg); +static int cs5435_54p_psu_read_word(struct i2c_client *client, u8 reg); +static int cs5435_54p_psu_write_word(struct i2c_client *client, u8 reg, u16 value); +static int cs5435_54p_psu_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len); +static struct cs5435_54p_psu_data *cs5435_54p_psu_update_device(struct device *dev); +static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); + +enum cs5435_54p_psu_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_TEMP2_INPUT, + PSU_TEMP3_INPUT, + PSU_TEMP_FAULT, + PSU_TEMP_WARN, + PSU_FAN1_FAULT, + PSU_FAN1_WARN, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, + PSU_PRESENT, + PSU_P_GOOD, +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + + bool is_negative = valid_data >> (valid_bit - 1); + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); + struct cs5435_54p_psu_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + if (data->valid != 1) + { + return -ENODEV; + } + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + cs5435_54p_psu_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_TEMP2_INPUT: + value = data->temp_input[1]; + break; + case PSU_TEMP3_INPUT: + value = data->temp_input[2]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + + + return sprintf(buf, "%d\n", data->temp_fault >> 7); +} + +static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + if (data->valid != 1) + { + return -ENODEV; + } + + + return sprintf(buf, "%d\n", data->temp_fault >> 6); +} +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + if (data->valid != 1) + { + return -ENODEV; + } + + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + u8 *ptr = NULL; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_MFR_ID: + ptr = data->mfr_id + 1; + break; + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} + + +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + u8 *ptr = NULL; + + u8 status = 0; + + if (attr->index == PSU_PRESENT) { + status = data->psu_is_present; + } + else { /* PSU_POWER_GOOD */ + if (!data->valid) { + return -ENODEV; + } + + status = data->psu_is_good; + } + + return sprintf(buf, "%d\n", status); +} + + +static int cs5435_54p_psu_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cs5435_54p_psu_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int cs5435_54p_psu_write_word(struct i2c_client *client, u8 reg, \ + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + +static int cs5435_54p_psu_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, + data); + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; +abort: + return result; + +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + + + +#define EEPROM_NAME "psu_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +/* Platform dependent --- */ +static ssize_t psu_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; + +} + + +static ssize_t psu_page_write(struct i2c_client *client,const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_write(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; +} + + + +static ssize_t psu_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs5435_54p_psu_data *data; + ssize_t retval = 0; + struct i2c_client *client; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + + mutex_lock(&data->update_lock); + retval = psu_page_write(client, buf, off, count); + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t psu_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + +abort: + return status; +} + + + +static ssize_t psu_page_read(struct i2c_client *client,char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + printk("Count = 0, return"); + return count; + } + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_read(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; + +} + + +static ssize_t psu_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs5435_54p_psu_data *data; + struct i2c_client *client; + ssize_t retval = 0; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + mutex_lock(&data->update_lock); + retval = psu_page_read(client, buf, off, count); + mutex_unlock(&data->update_lock); + + return retval; +} + + + +static int psu_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = psu_bin_read; + eeprom->write = psu_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + + +static int psu_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + + +static int psu_i2c_check_functionality(struct i2c_client *client) +{ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK); +} + + + +static int psu_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + int status; + + struct cs5435_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + data->bin = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL); + if (!data->bin) { + status = -ENOMEM; + goto eeprom_bin_error; + } + + /* init eeprom */ + status = psu_sysfs_eeprom_init(&client->dev.kobj, data->bin); + if (status) { + status = -ENOMEM; + goto sys_init_error; + } + + dev_info(&client->dev, "psu eeprom '%s'\n", client->name); + + return 0; + + sys_init_error: + kfree(data->bin); + + eeprom_bin_error: + kfree(data); + + exit: + return status; +} + + + + +static struct cs5435_54p_psu_data *cs5435_54p_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cs5435_54p_psu_data *data = i2c_get_clientdata(client); + + + mutex_lock(&data->update_lock); + + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}, + {0x7d, &data->temp_fault}, + }; + struct reg_data_word regs_word[] = { + {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x90, &(data->fan_speed[0])}, + }; + data->valid = 1; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cs5435_54p_psu_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + data->valid = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) + { + status = cs5435_54p_psu_read_word(client,regs_word[i].reg); + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + data->valid = 0; + } + else + { + *(regs_word[i].value) = status; + } + } + + command = 0x99; /* PSU mfr_id */ + status = cs5435_54p_psu_read_block(client, command, + data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); + data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_id, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9a; /* PSU mfr_model */ + status = cs5435_54p_psu_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_model, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9e; /* PSU mfr_serial */ + status = cs5435_54p_psu_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_serial, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + data->psu_is_present = strlen(data->mfr_id) > 1 ? 1:0; + if(data->psu_is_present) + { + data->psu_is_good = ((data->fan_fault) || (data->temp_fault))? 0:1; + } + else + { + data->valid = 0; + data->psu_is_good = 0; + } + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, for_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, for_status, NULL, PSU_P_GOOD); + + + +static struct attribute *cs5435_54p_psu_attributes[] = { + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_temp2_input.dev_attr.attr, + &sensor_dev_attr_psu_temp3_input.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_temp_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static const struct attribute_group cs5435_54p_psu_group = { + .attrs = cs5435_54p_psu_attributes, +}; + + +static int psu_register_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + + struct cs5435_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cs5435_54p_psu_group); + if (status) + goto exit_sysfs_create_group; + + cs5435_54p_sysfs_add_client(client); + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + /* init eeprom */ + + return 0; + + exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &cs5435_54p_psu_group); + exit_sysfs_create_group: + kfree(data); + exit: + return status; + +} + + +static int cs5435_54p_psu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + status = psu_eeprom_probe(client, id); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + status = psu_register_probe(client, id); + } + return status; +} + +static int cs5435_54p_psu_remove(struct i2c_client *client) +{ + cs5435_54p_sysfs_remove_client(client); + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + struct cs5435_54p_psu_data *data; + data = i2c_get_clientdata(client); + psu_sysfs_eeprom_cleanup(&client->dev.kobj,data->bin); + kfree(data); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + struct cs5435_54p_psu_data *data; + data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cs5435_54p_psu_group); + kfree(data); + } + + return 0; +} + +enum psu_index +{ + cs5435_54p_psu1, + cs5435_54p_psu2 +}; + +static const struct i2c_device_id cs5435_54p_psu_id[] = { + { "cs5435_54p_psu1", cs5435_54p_psu1 }, + { "cs5435_54p_psu2", cs5435_54p_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cs5435_54p_psu_id); + +static struct i2c_driver cs5435_54p_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "cs5435_54p_psu", + }, + .probe = cs5435_54p_psu_probe, + .remove = cs5435_54p_psu_remove, + .id_table = cs5435_54p_psu_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs5435_54p_psu_driver); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sfp.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sfp.c new file mode 100644 index 000000000000..3bdb3d2de791 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sfp.c @@ -0,0 +1,1713 @@ +/* + * A hwmon driver for the CIG cs5435-54P SFP Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" + +#define DRIVER_NAME "cs5435_54p_sfp" /* Platform dependent */ + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 /* Platform dependent */ +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) +#define SFP_EEPROM_A2_I2C_ADDR (0xA2 >> 1) + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 +#define SFF8472_10G_BASE_MASK 0xF0 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 +#define QSFP_RESET_ADDR 0x1b +#define QSFP_INTER_ADDR 0x1a +#define QSFP_LPMODE_ADDR 0x1c + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);; +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL, + QSFPRESET, + QSFPINT, + QSFPLPMODE +}; + +/* SFP/QSFP common attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_port_type, S_IRUGO, show_port_type, NULL, PORT_TYPE); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT); + +/* QSFP attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, qsfp_reset_read, qsfp_reset_write, QSFPRESET); +static SENSOR_DEVICE_ATTR(sfp_inter, S_IRUGO, qsfp_inter_read, NULL, QSFPINT); +static SENSOR_DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, qsfp_lpmode_read, qsfp_lpmode_write, QSFPLPMODE); +static struct attribute *qsfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + &sensor_dev_attr_sfp_reset.dev_attr.attr, + &sensor_dev_attr_sfp_inter.dev_attr.attr, + &sensor_dev_attr_sfp_lpmode.dev_attr.attr, + NULL +}; + +/* SFP msa attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_ddm_implemented, S_IRUGO, sfp_show_ddm_implemented, NULL, DDM_IMPLEMENTED); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS_ALL); +static struct attribute *sfp_msa_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_ddm_implemented.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + NULL +}; + +/* SFP ddm attributes for sysfs */ +static struct attribute *sfp_ddm_attributes[] = { + NULL +}; + +/* Platform dependent +++ */ +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { +cs5435_54p_sfp1, cs5435_54p_sfp2, cs5435_54p_sfp3, cs5435_54p_sfp4, +cs5435_54p_sfp5, cs5435_54p_sfp6, cs5435_54p_sfp7, cs5435_54p_sfp8, +cs5435_54p_sfp9, cs5435_54p_sfp10, cs5435_54p_sfp11, cs5435_54p_sfp12, +cs5435_54p_sfp13, cs5435_54p_sfp14, cs5435_54p_sfp15, cs5435_54p_sfp16, +cs5435_54p_sfp17, cs5435_54p_sfp18, cs5435_54p_sfp19, cs5435_54p_sfp20, +cs5435_54p_sfp21, cs5435_54p_sfp22, cs5435_54p_sfp23, cs5435_54p_sfp24, +cs5435_54p_sfp25, cs5435_54p_sfp26, cs5435_54p_sfp27, cs5435_54p_sfp28, +cs5435_54p_sfp29, cs5435_54p_sfp30, cs5435_54p_sfp31, cs5435_54p_sfp32, +cs5435_54p_sfp33, cs5435_54p_sfp34, cs5435_54p_sfp35, cs5435_54p_sfp36, +cs5435_54p_sfp37, cs5435_54p_sfp38, cs5435_54p_sfp39, cs5435_54p_sfp40, +cs5435_54p_sfp41, cs5435_54p_sfp42, cs5435_54p_sfp43, cs5435_54p_sfp44, +cs5435_54p_sfp45, cs5435_54p_sfp46, cs5435_54p_sfp47, cs5435_54p_sfp48, +cs5435_54p_sfp49, cs5435_54p_sfp50, cs5435_54p_sfp51, cs5435_54p_sfp52, +cs5435_54p_sfp53, cs5435_54p_sfp54, cs5435_54p_sfp55, cs5435_54p_sfp56 +}; + +#define I2C_DEV_ID(x) { #x, x} + +static const struct i2c_device_id sfp_device_id[] = { +I2C_DEV_ID(cs5435_54p_sfp1), +I2C_DEV_ID(cs5435_54p_sfp2), +I2C_DEV_ID(cs5435_54p_sfp3), +I2C_DEV_ID(cs5435_54p_sfp4), +I2C_DEV_ID(cs5435_54p_sfp5), +I2C_DEV_ID(cs5435_54p_sfp6), +I2C_DEV_ID(cs5435_54p_sfp7), +I2C_DEV_ID(cs5435_54p_sfp8), +I2C_DEV_ID(cs5435_54p_sfp9), +I2C_DEV_ID(cs5435_54p_sfp10), +I2C_DEV_ID(cs5435_54p_sfp11), +I2C_DEV_ID(cs5435_54p_sfp12), +I2C_DEV_ID(cs5435_54p_sfp13), +I2C_DEV_ID(cs5435_54p_sfp14), +I2C_DEV_ID(cs5435_54p_sfp15), +I2C_DEV_ID(cs5435_54p_sfp16), +I2C_DEV_ID(cs5435_54p_sfp17), +I2C_DEV_ID(cs5435_54p_sfp18), +I2C_DEV_ID(cs5435_54p_sfp19), +I2C_DEV_ID(cs5435_54p_sfp20), +I2C_DEV_ID(cs5435_54p_sfp21), +I2C_DEV_ID(cs5435_54p_sfp22), +I2C_DEV_ID(cs5435_54p_sfp23), +I2C_DEV_ID(cs5435_54p_sfp24), +I2C_DEV_ID(cs5435_54p_sfp25), +I2C_DEV_ID(cs5435_54p_sfp26), +I2C_DEV_ID(cs5435_54p_sfp27), +I2C_DEV_ID(cs5435_54p_sfp28), +I2C_DEV_ID(cs5435_54p_sfp29), +I2C_DEV_ID(cs5435_54p_sfp30), +I2C_DEV_ID(cs5435_54p_sfp31), +I2C_DEV_ID(cs5435_54p_sfp32), +I2C_DEV_ID(cs5435_54p_sfp33), +I2C_DEV_ID(cs5435_54p_sfp34), +I2C_DEV_ID(cs5435_54p_sfp35), +I2C_DEV_ID(cs5435_54p_sfp36), +I2C_DEV_ID(cs5435_54p_sfp37), +I2C_DEV_ID(cs5435_54p_sfp38), +I2C_DEV_ID(cs5435_54p_sfp39), +I2C_DEV_ID(cs5435_54p_sfp40), +I2C_DEV_ID(cs5435_54p_sfp41), +I2C_DEV_ID(cs5435_54p_sfp42), +I2C_DEV_ID(cs5435_54p_sfp43), +I2C_DEV_ID(cs5435_54p_sfp44), +I2C_DEV_ID(cs5435_54p_sfp45), +I2C_DEV_ID(cs5435_54p_sfp46), +I2C_DEV_ID(cs5435_54p_sfp47), +I2C_DEV_ID(cs5435_54p_sfp48), +I2C_DEV_ID(cs5435_54p_sfp49), +I2C_DEV_ID(cs5435_54p_sfp50), +I2C_DEV_ID(cs5435_54p_sfp51), +I2C_DEV_ID(cs5435_54p_sfp52), +I2C_DEV_ID(cs5435_54p_sfp53), +I2C_DEV_ID(cs5435_54p_sfp54), +I2C_DEV_ID(cs5435_54p_sfp55), +I2C_DEV_ID(cs5435_54p_sfp56), +{ /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28 +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[6]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss + 3 => device id + 4 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 5 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +}; + +struct sfp_ddm_data { + struct eeprom_data eeprom; +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct sfp_ddm_data *ddm; + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + + + +static int cig_cpld_write_sfp_register(u8 sfp_reg_addr, u8 sfp_write_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, sfp_write_reg_data); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x02); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1 | 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,sfp_read_reg_data); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + + + + +/* Platform dependent +++ */ +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + int i = 0, j = 0, status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + data->present = 0; + + udelay(6000); + + /* Read present status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 1 + i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->present |= (u64)cpld_reg_data << (i*8); + + DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); + } + + /* Read present status of port 49-56(QSFP port) */ + cpld_reg_addr = 25; + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + else { + data->present |= (u64)cpld_reg_data << 48; + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0, j = 0; + int status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + + if (time_before(jiffies, data->msa->last_updated + HZ + HZ / 2) && data->msa->valid) { + return data; + } + + DEBUG_PRINT("Starting cs5435_54p sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->msa->valid = 0; + memset(data->msa->status, 0, sizeof(data->msa->status)); + + udelay(6000); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 13+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[0] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); + } + + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 19+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[1] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); + } + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 7+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[2] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); + } + + data->msa->valid = 1; + data->msa->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0,cpld_reg_bit = 0,cpld_reg_val = 0; + long disable; + int error; + + if (data->driver_type == DRIVER_TYPE_QSFP) { + return qsfp_set_tx_disable(dev, da, buf, count); + } + + error = kstrtol(buf, 10, &disable); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + + if(data->port <= 48) { + cpld_reg_addr = 19 + data->port / 8; + cpld_reg_bit = 1 << ((data->port) % 8); + } + + /* Read current status */ + error = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + /* Update tx_disable status */ + if (disable) { + data->msa->status[1] |= BIT_INDEX(data->port); + cpld_reg_data |= cpld_reg_bit; + } + else { + data->msa->status[1] &= ~ BIT_INDEX(data->port); + cpld_reg_data &= ~cpld_reg_bit; + } + + error = cig_cpld_write_sfp_register(cpld_reg_addr,cpld_reg_data); + + mutex_unlock(&data->update_lock); + return count; +} +/* Platform dependent --- */ + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = sfp_update_present(client); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + return !(data->present & BIT_INDEX(data->port)); /* Platform dependent */ +} + +/* Platform dependent +++ */ +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if (PRESENT_ALL == attr->index) { + int i; + u8 values[7] = {0}; + struct sfp_port_data *data = sfp_update_present(client); + + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = ~(u8)(data->present >> (i * 8)); + } + + /* Return values 1 -> 56 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5], + values[6]); + } + else { + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + /* PRESENT */ + return sprintf(buf, "%d\n", present); + } +} +/* Platform dependent --- */ + +static struct sfp_port_data *sfp_update_port_type(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 buf = 0; + int status; + + mutex_lock(&data->update_lock); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + if (buf != SFF8024_DEVICE_ID_SFP) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + status = sfp_eeprom_read(client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); + data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; + break; + } + case DRIVER_TYPE_QSFP: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); + switch (buf) { + case SFF8024_DEVICE_ID_QSFP: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; + break; + case SFF8024_DEVICE_ID_QSFP_PLUS: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + case SFF8024_DEVICE_ID_QSFP28: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + default: + data->port_type = buf; + break; + } + + break; + } + default: + break; + } + + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + if (!present) { + /* port is not present */ + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_type(dev); + return sprintf(buf, "%d\n", data->port_type); +} + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + DEBUG_PRINT(""); + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + DEBUG_PRINT("Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + DEBUG_PRINT(""); + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + } + msleep(200); + DEBUG_PRINT(""); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + DEBUG_PRINT(""); + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + +exit: + DEBUG_PRINT(""); + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_INTER_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("inter read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("reset read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_RESET_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + + +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("lpmode read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_LPMODE_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + int present; + u8 val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT(""); + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + DEBUG_PRINT(""); + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + DEBUG_PRINT(""); + data = qsfp_update_tx_rx_status(dev); + DEBUG_PRINT(""); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + DEBUG_PRINT(""); + switch (attr->index) { + case TX_FAULT: + val = !!(data->qsfp->status[2] & 0xF); + break; + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)); + break; + case TX_DISABLE: + val = data->qsfp->status[1] & 0xF; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)); + break; + case RX_LOS: + val = !!(data->qsfp->status[0] & 0xF); + break; + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)); + break; + default: + break; + } + + DEBUG_PRINT(""); + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (!status) { + /* port is not present */ + return -ENXIO; + } + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + mutex_lock(&data->update_lock); + + if (attr->index == TX_DISABLE) { + data->qsfp->status[1] = disable & 0xF; + } + else {/* TX_DISABLE1 ~ TX_DISABLE4*/ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + if (unlikely(status < 0)) { + count = status; + } + + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + char ddm; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (status == 0) { + /* port is not present */ + return -ENODEV; + } + + status = sfp_eeprom_read(client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); + if (unlikely(status < 0)) { + return status; + } + + return sprintf(buf, "%d\n", !!(ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK)); +} + +/* Platform dependent +++ */ +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("driver type = (%d)", data->driver_type); + if (data->driver_type == DRIVER_TYPE_QSFP) { + DEBUG_PRINT(""); + return qsfp_show_tx_rx_status(dev, da, buf); + } + + DEBUG_PRINT(""); + data = sfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + if(attr->index == RX_LOS_ALL) { + int i = 0; + u8 values[6] = {0}; + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = (u8)(data->msa->status[2] >> (i * 8)); + } + + /** Return values 1 -> 48 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5]); + } + + switch (attr->index) { + case TX_FAULT: + index = 0; + break; + case TX_DISABLE: + index = 1; + break; + case RX_LOS: + index = 2; + break; + default: + break; + } + + val = !!(data->msa->status[index] & BIT_INDEX(data->port)); + return sprintf(buf, "%d\n", val); +} +/* Platform dependent --- */ +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, command, *data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return 1; +#endif + + +} + +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_write(data, buf, off, count); +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + + //result = data_len; + +abort: + return status; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, command); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status); + goto abort; + } + + *data = (u8)status; + status = 1; + +abort: + return status; +#endif +} + +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_read(data, buf, off, count); +} + +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + cs5435_54p_sysfs_add_client(client); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group sfp_ddm_group = { + .attrs = sfp_ddm_attributes, +}; + +static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_ddm_data **data) +{ + int status; + struct sfp_ddm_data *ddm; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); + if (!ddm) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = ddm; + dev_info(&client->dev, "sfp ddm '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); +exit_free: + kfree(ddm); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); + if (status) { + goto exit_remove; + } + + /* Bring QSFPs out of reset */ + //cig_lpc_write(0x62, 0x15, 0x3F); + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +/* Platform dependent +++ */ +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct sfp_port_data *data = NULL; + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + if (dev_id->driver_data >= cs5435_54p_sfp1 && dev_id->driver_data <= cs5435_54p_sfp48) { + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_MSA; + return sfp_msa_probe(client, dev_id, &data->msa); + } + else if (client->addr == SFP_EEPROM_A2_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_DDM; + return sfp_ddm_probe(client, dev_id, &data->ddm); + } + } + else { /* cs5435_54p_sfp49 ~ cs5435_54p_sfp56 */ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_QSFP; + return qsfp_probe(client, dev_id, &data->qsfp); + } + } + + return -ENODEV; +} +/* Platform dependent --- */ + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + cs5435_54p_sysfs_remove_client(client); + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_SFP_DDM: + return sfp_ddm_remove(client, data->ddm); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + + return 0; +} + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static struct i2c_driver cs5435_54p_sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs5435_54p_sfp_driver); + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_sfp driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sysfs.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sysfs.c new file mode 100644 index 000000000000..0ba8836cf33a --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sysfs.c @@ -0,0 +1,335 @@ +/* + * A hwmon driver for the CIG cs5435-54P sysfs Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c-algo-lpc.h" + + +static LIST_HEAD(sysfs_client_list); +static struct mutex list_lock; + +struct sysfs_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define DEVICE_NAME "cigfs" +static int dev_major; +static struct class *dev_class; +static struct cdev *dev_cdev; +static struct device *dev_device; +static struct class *psu_class; +static struct class *sfp_class; + + +void cs5435_54p_sysfs_add_client(struct i2c_client *client) +{ + struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &sysfs_client_list); + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs5435_54p_sysfs_add_client); + +void cs5435_54p_sysfs_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (IS_ERR(sysfs_node)) + { + break; + } + if (sysfs_node->client == client) { + found = 1; + break; + } + } + if (found) { + list_del(list_node); + kfree(sysfs_node); + } + + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs5435_54p_sysfs_remove_client); + +struct class * cs5435_54p_sysfs_create_symclass(char *cls_name) +{ + int rc = 0; + struct class *my_class; +/**************************************************************************************/ + my_class = class_create(THIS_MODULE,cls_name); + if (IS_ERR(my_class)) { + pr_err("failed to create my class\n"); + } + return my_class; + +/**************************************************************************************/ +} + +void cs5435_54p_sysfs_delete_symclass(struct class *my_class) +{ +/**************************************************************************************/ + + if (IS_ERR(my_class)) { + pr_err("Pointer is invaild\n"); + } + class_destroy(my_class); + +/**************************************************************************************/ +} + + + + + +int cs5435_54p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name); + if(rc) + { + pr_err("failed to create symlink %d\n",rc); + } + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +int cs5435_54p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + sysfs_remove_link(&my_class->p->subsys.kobj,device_name); + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +static int cs5435_54p_sysfs_open(struct inode *inode, struct file *file) +{ + return 0; +} + + + +static ssize_t cs5435_54p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) +{ + char str[10],name[18],port[8]; + int ret; + int i; + memset(str, 0, sizeof(str)); + ret = copy_from_user(str, buf, count); + if (ret) + { + printk(KERN_ERR "copy_from_user fail\n"); + return -EINVAL; + } + + if(!strncmp(str,"start",5)) + { + psu_class = cs5435_54p_sysfs_create_symclass("psu"); + cs5435_54p_sysfs_create_symlink(psu_class,"cs5435_54p_psu1","psu1"); + cs5435_54p_sysfs_create_symlink(psu_class,"cs5435_54p_psu2","psu2"); + sfp_class = cs5435_54p_sysfs_create_symclass("swps"); + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs5435_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs5435_54p_sysfs_create_symlink(sfp_class,name,port); + } + } + else if(!strncmp(str,"stop",4)) + { + cs5435_54p_sysfs_delete_symlink(psu_class,"cs5435_54p_psu1","psu1"); + cs5435_54p_sysfs_delete_symlink(psu_class,"cs5435_54p_psu2","psu2"); + cs5435_54p_sysfs_delete_symclass(psu_class); + + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs5435_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs5435_54p_sysfs_delete_symlink(sfp_class,name,port); + } + cs5435_54p_sysfs_delete_symclass(sfp_class); + } + return count; +} + + +static struct file_operations cs5435_54p_sysfs_fops = { + .owner = THIS_MODULE, + .open = cs5435_54p_sysfs_open, + .write = cs5435_54p_sysfs_write, +}; + + +static int __init cs5435_54p_sysfs_init(void) +{ + int result = 0; + int err = 0; + dev_t dev = MKDEV(dev_major, 0); + + if (dev_major) + result = register_chrdev_region(dev, 1, DEVICE_NAME); + else { + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + dev_major = MAJOR(dev); + } + if (result < 0) + { + printk("unable to get major %d\n", dev_major); + err= -EINVAL; + } + printk("get major is %d\n", dev_major); + if (dev_major == 0) + dev_major = result; + + dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL); + if(IS_ERR(dev_cdev)) { + err= -ENOMEM; + } + + cdev_init(dev_cdev, &cs5435_54p_sysfs_fops); + dev_cdev->owner = THIS_MODULE; + dev_cdev->ops = &cs5435_54p_sysfs_fops; + err = cdev_add(dev_cdev, dev, 1); + if (err) + { + printk("error %d add fpga ", err); + goto err_malloc; + } + + dev_class = class_create(THIS_MODULE, DEVICE_NAME); + if (IS_ERR(dev_class)) + { + printk("Err:failed in creating class.\n"); + goto err_cdev_add; + } + + dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME); + if (IS_ERR(dev_device)) + { + printk("Err:failed in creating device.\n"); + goto err_class_crt; + } + + mutex_init(&list_lock); + + return err; + + err_class_crt: + cdev_del(dev_cdev); + err_cdev_add: + kfree(dev_cdev); + err_malloc: + unregister_chrdev_region(MKDEV(dev_major,0), 1); + + return err; + +} + +static void __exit cs5435_54p_sysfs_exit(void) +{ + cdev_del(dev_cdev); + printk("cdev_del ok\n"); + device_destroy(dev_class, MKDEV(dev_major, 0)); + + class_destroy(dev_class); + + if(dev_cdev != NULL) + kfree(dev_cdev); + + unregister_chrdev_region(MKDEV(dev_major, 0), 1); + printk("cs5435_54p_sysfs_exit...\r\n"); +} + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435-54p-sysfs driver"); +MODULE_LICENSE("GPL"); + +module_init(cs5435_54p_sysfs_init); +module_exit(cs5435_54p_sysfs_exit); + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-init.service b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-init.service new file mode 100644 index 000000000000..b609a2be45c7 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Cig CS5435-54P Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/cig_cs5435_util.py install +ExecStop=/usr/local/bin/cig_cs5435_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-misc.service b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-misc.service new file mode 100644 index 000000000000..852ab5689a70 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-misc.service @@ -0,0 +1,15 @@ +[Unit] +Description=Cig CS5435-54P Platform miscellaneous service +After=cs5435-platform-init.service +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/cig_cs5435_misc.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py new file mode 100755 index 000000000000..1d4fa7f36452 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='cs5435-54p', + version='1.0.0', + description='Module to initialize Cig CS5435-54P platforms', + + packages=['cs5435-54p'], + package_dir={'cs5435-54p': 'cs5435-54p/classes'}, + ) diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py new file mode 100755 index 000000000000..0a78085fd49b --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py @@ -0,0 +1,574 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os +import commands +import sys, getopt +import logging +import re +import time +import datetime +from collections import namedtuple +from threading import Thread + +DEBUG = False +i2c_prefix = '/sys/bus/i2c/devices/' +leds_prefix = '/sys/devices/platform/cs5435_54p_led/leds/' +fans_prefix = '/sys/devices/platform/cs5435_54p_fan/' +fansdir_prefix = fans_prefix + 'fan{}_direction' + +ageing_controlfile = '/etc/sonic/agcontrol' +AGFlag = 0 + + +platform_misc_log = '/var/log/platform_misc.log' +misclogger = logging.getLogger('platform_misc') +misclogger.setLevel(logging.INFO) +miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s') + +if not os.path.isfile(platform_misc_log): + try: + os.mknod(platform_misc_log) + except: + print 'Failed to creat platform_misc.log' + +fileHandler = logging.FileHandler(platform_misc_log) +fileHandler.setLevel(logging.INFO) +fileHandler.setFormatter(miscformatter) +misclogger.addHandler(fileHandler) + + +starttime = datetime.datetime.now() +IsGetlswt = 0 +coretemp_prefix = '/sys/class/hwmon/hwmon1/' +coretemp_ps = [] +psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present' +psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present' +psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom' +psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom' +psu1led_d = leds_prefix + 'cs5435_54p_led::psu1/brightness' +psu2led_d = leds_prefix + 'cs5435_54p_led::psu2/brightness' +cs5435_ledpath = {'fan':leds_prefix + 'cs5435_54p_led::fan/brightness', + 'fan1':leds_prefix + 'cs5435_54p_led::fan1/brightness', + 'fan2':leds_prefix + 'cs5435_54p_led::fan2/brightness', + 'fan3':leds_prefix + 'cs5435_54p_led::fan3/brightness', + 'fan4':leds_prefix + 'cs5435_54p_led::fan4/brightness', + 'fan5':leds_prefix + 'cs5435_54p_led::fan5/brightness', + 'psu1':leds_prefix + 'cs5435_54p_led::psu1/brightness', + 'psu2':leds_prefix + 'cs5435_54p_led::psu2/brightness', + 'sys':leds_prefix + 'cs5435_54p_led::sys/brightness'} + + +def system_read_filestr(node): + with open(node, 'r') as f: + try: + str = f.read() + except IOError as e: + misclogger.error('Failed to get node, str={}'.format(node)) + return "0" + return str + + +def system_bright_leds(dev, colour): + global AGFlag + + if AGFlag == 1: + return + + cmd = 'echo {} > {}'.format(colour, dev) + log_os_system(cmd, 1) + return + +''' +1: front in tail out +0: front out tail in +''' +def system_getpsu_direction(dev): + try: + with open(dev) as f: + f.seek(0x30) + str = f.read(2) + except IOError as e: + misclogger.error('Failed to get psu eep') + return 1 + if str == 'AA': ## front in tail out + return 1 + elif str == 'RA':## tail in front out + return 0 + else: + misclogger.error('Failed to get psu eep, str={}'.format(str)) + return -1 + + +def system_get_cputype(): + cmdretfd = os.popen("lscpu | grep 'Model name'") + retstring = cmdretfd.read() + endindex = retstring.find('@') - 1 + startindex = retstring[:endindex].rfind(' ') + 1 + cputype = retstring[startindex:endindex] + + return cputype + + +def system_init_coretemppath(): + global coretemp_ps + + cmdstr = "ls {} | grep 'input'".format(coretemp_prefix) + cmdretfd = os.popen(cmdstr) + + coretemppss = cmdretfd.read().splitlines() + if len(coretemppss) < 3: + cputype = system_get_cputype() + misclogger.error('Failed to init core temperature path.' + ' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps))) + return 1 + + for i in range(0,3): + coretemp_ps.append(coretemp_prefix + coretemppss[i]) + + print coretemp_ps + + return 0 + + +class cs5435_fanattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.rear = 0 + self.rear_p = '' + self.front = 0 + self.front_p = '' + self.fault = 0 + self.fault_p = '' + self.status = 0 + self.setpath() + self.updatedevice() + + return + + def setpath(self): + self.direction_p = fans_prefix + '{}_direction'.format(self.name) + self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name) + self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name) + self.fault_p = fans_prefix + '{}_fault'.format(self.name) + + return + + def updatedevice(self): + self.direction = int(system_read_filestr(self.direction_p)) + self.rear = int(system_read_filestr(self.rear_p)) + self.front = int(system_read_filestr(self.front_p)) + self.fault = int(system_read_filestr(self.fault_p)) + + return + + def checkspeedrpm(self, speedrpm): + frontrpmexp = speedrpm * 21000 / 100 + rearrpmexp = speedrpm * 19000 / 100 + deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp) + deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp) + + if deviationfront < 0.3 and deviationrear < 0.3: + return 0 + else: + misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear)) + return 1 + + def checkstatus(self, speedrpm, totaldirct): + speedstatus = self.checkspeedrpm(speedrpm) + if self.direction != totaldirct: + self.status = 1 + misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction)) + elif speedstatus != 0: + self.status = 1 + elif self.fault != 0: + misclogger.error(':{} fault.'.format(self.name)) + self.status = 1 + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs5435_ledpath[self.name], 3) + else: + system_bright_leds(cs5435_ledpath[self.name], 1) + + return self.status + +cs5435_fanattrnodes = [] + + +class cs5435_psuattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.present = 0 + self.present_p = '' + self.status = 0 + + self.setpath() + self.updatepresent() + self.updatedirection() + + return + + def setpath(self): + if self.name == 'psu1': + self.present_p = psu1_p + self.direction_p = psu1_d + if self.name == 'psu2': + self.present_p = psu2_p + self.direction_p = psu2_d + + return + + def updatepresent(self): + self.present = int(system_read_filestr(self.present_p)) + + return + + def updatedirection(self): + if self.present == 1: + self.direction = system_getpsu_direction(self.direction_p) + else: + self.direction = 2 + + return + + def checkstatus(self, totaldirct): + if self.present != 1: + self.status = 1 + misclogger.error(':{} not present.'.format(self.name)) + elif self.direction == 2: + self.status = 0 + misclogger.info(':{} direction need to be update.'.format(self.name)) + elif self.direction != totaldirct: + self.status = 1 + misclogger.info(':{} direction is wrong.'.format(self.name)) + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs5435_ledpath[self.name], 3) + else: + system_bright_leds(cs5435_ledpath[self.name], 1) + + return self.status + +cs5435_psuattrnodes = [] + + + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0) + ret3, log = log_os_system("ls "+leds_prefix+"cs5435_54p_led*", 0) + return not(ret1 or ret2 or ret3) + + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + + +def system_get_coretemp(): + temp1 = system_read_filestr(coretemp_ps[0]).strip() + temp2 = system_read_filestr(coretemp_ps[1]).strip() + temp3 = system_read_filestr(coretemp_ps[2]).strip() + + return int(temp1), int(temp2), int(temp3) + +def system_get_boardtemp(): + for i in range(0,16): + temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i + if os.access(temp1path, os.F_OK): + break + for i in range(0,16): + temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i + if os.access(temp2path, os.F_OK): + break + temp1 = system_read_filestr(temp1path).strip() + temp2 = system_read_filestr(temp2path).strip() + + return int(temp1), int(temp2) + + +def system_get_lswtemp(): + global IsGetlswt + global starttime + if IsGetlswt == 0: + now = datetime.datetime.now() + misclogger.info("time wait.") + misclogger.info("start = {}, now = {}.".format(starttime, now)) + if (now - starttime).seconds > 150: + misclogger.info("time = ".format((now - starttime).seconds)) + IsGetlswt = 1 + + return 25 + +# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) +# if chp.poll() == None: +# misclogger.info("No subp.") +# chp.kill() +# +# return 25 + +# retstring = chp.stdout.read() +# chp.kill() +# if 'Up' not in retstring: +# misclogger.info("lsw not up.") +# +# return 25 + + status, output = log_os_system('npx_diag swc show temperature', 1) + if status: + misclogger.error('failed to show lsw temperature') + + return 25 + + output = output.strip() + if output.find("it 0, temperature ") > 0: + startindex = output.find('temperature') + len('temperature') + 1 + endindex = output[startindex:].find(" ") + endindex = startindex + endindex + temp = output[startindex:endindex] + b = temp.find('.') + if b > 0: + temp=temp[:b] + temp = int(temp) + else: + misclogger.error("Failed to get temperature.") + temp = 0 + + return int(temp) + +def system_monitor_temperature(): + + ctemp1, ctemp2, ctemp3 = system_get_coretemp() + btemp1, btemp2 = system_get_boardtemp() + ltemp = system_get_lswtemp() + fan_speed_str = system_cs5435_getfanexspeed() + fan_speed = int(fan_speed_str) + policy = 'stay' + pos = 0 + #speed c1 c2 c3 b1 b2 lsw + fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95], + [40, 44000, 44000, 44000, 44000, 39000, 96], + [50, 49000, 49000, 49000, 47000, 44000, 91], + [60, 52000, 52000, 52000, 51500, 47500, 92], + [70, 53000, 53000, 53000, 52000, 49000, 93], + [100,999999,999999,999999,999999,999999,999]) + + fan_policy_down=([30, 0, 0, 0, 0, 0, 0], + [40, 34000, 34000, 34000, 34000, 30000, 80], + [50, 38000, 38000, 38000, 37000, 33000, 81], + [60, 44000, 44000, 44000, 43000, 39000, 84], + [70, 44000, 44000, 44000, 43000, 40000, 84], + [100, 48000, 48000, 48000, 46000, 42000, 85],) + + for policytable in fan_policy_up: + if fan_speed <= policytable[0]: + break + pos = pos + 1 + fan_speed = policytable[0] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'stay' + policytable = fan_policy_down[pos] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'down' + else: + policy = 'up' + + if policy == 'up': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos + 1][0] + misclogger.info("fan policy: up. speedexp = {}".format(fan_speed)) + + if policy == 'stay': + fan_speed = fan_policy_down[pos] + return + + if policy == 'down': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos - 1][0] + misclogger.info("fan policy: down.speedexp = {}".format(fan_speed)) + + cmd = "echo %d > /sys/devices/platform/cs5435_54p_fan/fan_duty_cycle_percentage" % fan_speed + status, output = log_os_system(cmd, 1) + if status: + misclogger.error("set fan speed fault") + + return + + +def system_cs5435_setfanexspeed(num): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + numstr = str(num) + with open(fanspeednode, 'w') as f: + f.write(numstr) + + +def system_cs5435_getfanexspeed(): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + fanspeedstr = system_read_filestr(fanspeednode) + fanspeedexp = int(fanspeedstr) + + return fanspeedexp + + +def system_cs5435_getdirection(): + global cs5435_fanattrnodes + direction = 0 + + for fan in cs5435_fanattrnodes: + direction = direction + fan.direction + + if direction > 2: + direction = 1 + else: + direction = 0 + + return direction + + +def system_check_psusdirection(): + global cs5435_psuattrnodes + cs5435totaldirct = system_cs5435_getdirection() + psutatus = 0 + + for psu in cs5435_psuattrnodes: + psu.updatedirection() + psu.checkstatus(cs5435totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_psuspresent(): + global cs5435_psuattrnodes + cs5435totaldirct = system_cs5435_getdirection() + psutatus = 0 + + for psu in cs5435_psuattrnodes: + psu.updatepresent() + psu.checkstatus(cs5435totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_fansstate(): + global cs5435_fanattrnodes + global cs5435_ledpath + cs5435totaldirct = system_cs5435_getdirection() + fanstatus = 0 + fanexspeed = 0 + + fanexspeed = system_cs5435_getfanexspeed() + + for fan in cs5435_fanattrnodes: + fan.updatedevice() + fan.checkstatus(fanexspeed, cs5435totaldirct) + fanstatus = fanstatus + fan.status + + if fanstatus > 0: + misclogger.error(':fan error.set fans speed 100.') + system_cs5435_setfanexspeed(100) + system_bright_leds(cs5435_ledpath['fan'], 3) + else: + system_bright_leds(cs5435_ledpath['fan'], 1) + + return (fanstatus != 0) + + +def system_misc_polling(threadName,delay): + for count in range(1,5): + if device_exist() == False: + time.sleep(delay+3) + print "%s: %s, count=%d" % ( threadName, time.ctime(time.time()), count) + else: + break + + if count == 4: + return + + status, output = log_os_system("echo 1 > /sys/devices/platform/cs5435_54p_led/leds/cs5435_54p_led::sys/brightness", 1) + status, output = log_os_system("hwconfig -cfp 1", 1) + + global AGFlag + if os.access(ageing_controlfile, os.F_OK): + AGFlag = 1 + else: + AGFlag = 0 + + os.system('csw_daemon &') + + + global cs5435_fanattrnodes + global cs5435_psuattrnodes + + for num in range(1,6): + name = 'fan{}'.format(num) + fannode = cs5435_fanattr(name) + cs5435_fanattrnodes.append(fannode) + for num in range(1,3): + name = 'psu{}'.format(num) + psunode = cs5435_psuattr(name) + cs5435_psuattrnodes.append(psunode) + + tempcontrol = system_init_coretemppath() + + misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time()))) + count = 0 + while 1: + count = count + 1 + ret = system_check_psuspresent() + ret = system_check_fansstate() + + if count % 10 == 0: + misclogger.info(": adjust fans and check psu direction.") + system_check_psusdirection() + if tempcontrol == 0: + system_monitor_temperature() + count = 0 + time.sleep(delay) + + return + +if __name__ == '__main__': + target=system_misc_polling("Thread-misc",10) + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py new file mode 100755 index 000000000000..03302592257c --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py @@ -0,0 +1,563 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'cs5435_54p' +version = '0.1.1' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':54} +FORCE = 0 +CPU_TYPE = 'C3308' + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + for count in range(1,5): + time.sleep(1) + ret, lsmod = log_os_system("lsmod| grep i2c_i801", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_i801", 0) + break + + ret, lsmod = log_os_system("lsmod| grep i2c_designware_platform", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_designware_platform", 0) + log_os_system("modprobe i2c-designware-platform", 0) + + ret, lsmod = log_os_system("lsmod| grep cig", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ + 'depmod', + 'modprobe i2c_dev', + 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe x86-64-cig-cs5435-54p-sysfs ' , + 'modprobe x86-64-cig-cs5435-54p-cpld ' , + 'modprobe x86-64-cig-cs5435-54p-fan' , + 'modprobe x86-64-cig-cs5435-54p-psu' , + 'modprobe x86-64-cig-cs5435-54p-sfp' , + 'modprobe x86-64-cig-cs5435-54p-led' ] + +def driver_install(): + global FORCE + + for i in range(0,len(kos)): + if i == 4: + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) + if CPU_TYPE=='i3-6100U': + kos[i] =kos[i] + 'board_id=1' + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0) + if CPU_TYPE=='C3758' or CPU_TYPE=='C3308': + kos[i] =kos[i] + 'board_id=2' + + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['sys','fan','fan1','fan2','fan3','fan4','fan5','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'thermal': ['4-0048','4-0049', '5-004a', '5-004b'] , + 'psu': ['5-005a','5-005b'], + 'sfp': ['-0050']} +i2c_nodes = {'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} + +fan_prefix ='/sys/bus/platform/devices/'+PROJECT_NAME+'_fan' +fan_types = {'fan': ['fan1','fan2', 'fan3', 'fan4', 'fan5']} +fan_nodes = {'fan': ['state', 'front_speed_rpm', 'rear_speed_rpm', 'fault']} + + +sfp_map = [8,9,10,11,12,13,14,15,16, + 17,18,19,20,21,22,23,24,25,26, + 27,28,29,30,31,32,33,34,35,36, + 37,38,39,40,41,42,43,44,45,46, + 47,48,49,50,51,52,53,54,55,56, + 57,60,61,62,63] + +mknod =[ + 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu1 0x5a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu2 0x5b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu1 0x52 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu2 0x53 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo 24c128 0x57 > /sys/bus/i2c/devices/i2c-7/new_device'] + +port = 0 + +def device_install(): + global FORCE + global port + for i in range(0,len(mknod)): + #all nodes need times to built new i2c buses + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + if (i == 50): + port = port + 3 + else: + port = port + 1 + + + status, output =log_os_system("echo cs5435_54p_sfp"+str(port)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + if port <= 48: + status, output =log_os_system("echo cs5435_54p_sfp"+str(port)+" 0x51 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + return + +def device_uninstall(): + global FORCE + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types, fan_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + for key in fan_types: + itypes = fan_types[key] + nodes = fan_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + + +def get_ledname(ledx): + name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'} + if name_table.has_key(ledx): + name = name_table[ledx] + else: + name = ledx + return name + + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + nwnamex = get_ledname(j) + if nwnamex == j: + print " "+j+":", + else: + print " "+nwnamex+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0) + return not(ret1 or ret2) + + +if __name__ == "__main__": + main() diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/__init__.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/fanutil.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/fanutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/thermalutil.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/thermalutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/Makefile b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/Makefile new file mode 100644 index 000000000000..e37e985a2147 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/Makefile @@ -0,0 +1,6 @@ +obj-m :=x86-64-cig-cs6436-54p-sysfs.o \ + x86-64-cig-cs6436-54p-cpld.o \ + x86-64-cig-cs6436-54p-fan.o \ + x86-64-cig-cs6436-54p-led.o \ + x86-64-cig-cs6436-54p-psu.o \ + x86-64-cig-cs6436-54p-sfp.o diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/i2c-algo-lpc.h b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/i2c-algo-lpc.h new file mode 100644 index 000000000000..749aa94ef934 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/i2c-algo-lpc.h @@ -0,0 +1,222 @@ +/* -------------------------------------------------------------------- + + * A hwmon driver for the CIG cs6436-54P + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* -------------------------------------------------------------------- */ + +#ifndef I2C_LPC_H +#define I2C_LPC_H 1 + +/* ----- Control register bits ---------------------------------------- */ +#define I2C_LPC_PIN 0x80 +#define I2C_LPC_ESO 0x40 +#define I2C_LPC_ES1 0x20 +#define I2C_LPC_ES2 0x10 +#define I2C_LPC_ENI 0x08 + +#define I2C_LPC_STO 0x40 +#define I2C_LPC_ACK 0x01 + +/*command register*/ +#define I2C_LPC_STA 0x80 +#define I2C_LPC_ABT 0x40 + +/*status register*/ +#define I2C_LPC_TBE 0x02 +#define I2C_LPC_IBB 0x80 +#define I2C_LPC_RBF 0x01 +#define I2C_LPC_TD 0x08 + +#define I2C_LPC_START I2C_LPC_STA +#define I2C_LPC_STOP I2C_LPC_STO +#define I2C_LPC_REPSTART I2C_LPC_STA +#define I2C_LPC_IDLE + +/* ----- Status register bits ----------------------------------------- */ +/*#define I2C_LPC_PIN 0x80 as above*/ + +#define I2C_LPC_INI 0x40 /* 1 if not initialized */ +#define I2C_LPC_STS 0x20 +#define I2C_LPC_BER 0x10 +#define I2C_LPC_AD0 0x08 +#define I2C_LPC_LRB 0x08 +#define I2C_LPC_AAS 0x04 +#define I2C_LPC_LAB 0x02 +#define I2C_LPC_BB 0x80 + +/* ----- Chip clock frequencies --------------------------------------- */ +#define I2C_LPC_CLK3 0x00 +#define I2C_LPC_CLK443 0x10 +#define I2C_LPC_CLK6 0x14 +#define I2C_LPC_CLK 0x18 +#define I2C_LPC_CLK12 0x1c + +/* ----- transmission frequencies ------------------------------------- */ +#define I2C_LPC_TRNS90 0x00 /* 90 kHz */ +#define I2C_LPC_TRNS45 0x01 /* 45 kHz */ +#define I2C_LPC_TRNS11 0x02 /* 11 kHz */ +#define I2C_LPC_TRNS15 0x03 /* 1.5 kHz */ + + +#define I2C_LPC_OWNADR 0 +#define I2C_LPC_INTREG I2C_LPC_ES2 +#define I2C_LPC_CLKREG I2C_LPC_ES1 + +#define I2C_LPC_REG_TEST 0x01 +#define I2C_LPC_REG_BUS_SEL 0x80 +#define I2C_LPC_REG_DEVICE_ADDR 0x81 +#define I2C_LPC_REG_BYTE_COUNT 0x83 +#define I2C_LPC_REG_COMMAND 0x84 +#define I2C_LPC_REG_STATUS 0x85 +#define I2C_LPC_REG_DATA_RX1 0x86 +#define I2C_LPC_REG_DATA_RX2 0x87 +#define I2C_LPC_REG_DATA_RX3 0x88 +#define I2C_LPC_REG_DATA_RX4 0x89 +#define I2C_LPC_REG_DATA_TX1 0x8a +#define I2C_LPC_REG_DATA_TX2 0x8b +#define I2C_LPC_REG_DATA_TX3 0x8c +#define I2C_LPC_REG_DATA_TX4 0x8d + + +#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 +#define ADDR_REG_SFP_STATUS_TX 0X63 // write data +#define ADDR_REG_SFP_STATUS_RX 0X64 //read data +#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go +#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status + +#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20 +#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21 +#define CPLD_MASTER_INTERRUPT_ALL 0x3f +#define CPLD_MASTER_INTERRUPT_CPLD2 0x20 +#define CPLD_MASTER_INTERRUPT_CPLD1 0x10 +#define CPLD_MASTER_INTERRUPT_PSU2 0x08 +#define CPLD_MASTER_INTERRUPT_PSU1 0x04 +#define CPLD_MASTER_INTERRUPT_6320 0x02 +#define CPLD_MASTER_INTERRUPT_LSW 0x01 + + + +#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20 +#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21 +#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22 +#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23 +#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24 +#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25 + + +#define CPLD_SLAVE1_PRESENT08_REG 0x01 +#define CPLD_SLAVE1_PRESENT16_REG 0x02 +#define CPLD_SLAVE1_PRESENT24_REG 0x03 +#define CPLD_SLAVE2_PRESENT32_REG 0x04 +#define CPLD_SLAVE2_PRESENT40_REG 0x05 +#define CPLD_SLAVE2_PRESENT48_REG 0x06 + +#define CPLD_SLAVE1_RX_LOST08_REG 0x07 +#define CPLD_SLAVE1_RX_LOST16_REG 0x08 +#define CPLD_SLAVE1_RX_LOST24_REG 0x09 +#define CPLD_SLAVE2_RX_LOST32_REG 0x0a +#define CPLD_SLAVE2_RX_LOST40_REG 0x0b +#define CPLD_SLAVE2_RX_LOST48_REG 0x0c + +#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d +#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e +#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f +#define CPLD_SLAVE2_TX_FAULT32_REG 0x10 +#define CPLD_SLAVE2_TX_FAULT40_REG 0x11 +#define CPLD_SLAVE2_TX_FAULT48_REG 0x12 + +#define CPLD_SLAVE2_PRESENT56_REG 0x19 +#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a + + +#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001 +#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002 +#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004 +#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001 +#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002 +#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004 + +#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200 +#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400 + +#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020 + +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100 + + + + + + + +#define WAIT_TIME_OUT_COUNT 100 + + +struct i2c_algo_lpc_data { + void *data; /* private data for lolevel routines */ + void (*setlpc) (void *data, int ctl, int val); + int (*getlpc) (void *data, int ctl); + int (*getown) (void *data); + int (*getclock) (void *data); + void (*waitforpin) (void *data); + + int (*xfer_begin) (void *data); + int (*xfer_end) (void *data); + + /* Multi-master lost arbitration back-off delay (msecs) + * This should be set by the bus adapter or knowledgable client + * if bus is multi-mastered, else zero + */ + unsigned long lab_mdelay; +}; + + +struct subsys_private { + struct kset subsys; + struct kset *devices_kset; + struct list_head interfaces; + struct mutex mutex; + + struct kset *drivers_kset; + struct klist klist_devices; + struct klist klist_drivers; + struct blocking_notifier_head bus_notifier; + unsigned int drivers_autoprobe:1; + struct bus_type *bus; + + struct kset glue_dirs; + struct class *class; +}; + +void cs6436_54p_sysfs_add_client(struct i2c_client *client); +void cs6436_54p_sysfs_remove_client(struct i2c_client *client); + + +#endif /* I2C_LPC8584_H */ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-cpld.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-cpld.c new file mode 100644 index 000000000000..1c7930b3d268 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-cpld.c @@ -0,0 +1,2202 @@ +/* + * A hwmon driver for the CIG cs6436-54P CPLD + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CPLD_USER +# include +#else +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + + + + + +/********************************************** Start ********************************************************/ + +/* + * ISA bus. + */ + +static void platform_isa_bus_release(struct device * dev) +{ + return ; +} + + +static struct device isa_bus = { + .init_name = "lpc-isa", + .release = platform_isa_bus_release, +}; + +struct isa_dev { + struct device dev; + struct device *next; + unsigned int id; +}; + +#define to_isa_dev(x) container_of((x), struct isa_dev, dev) + +static int isa_bus_match(struct device *dev, struct device_driver *driver) +{ + struct isa_driver *isa_driver = to_isa_driver(driver); + + if (dev->platform_data == isa_driver) { + if (!isa_driver->match || + isa_driver->match(dev, to_isa_dev(dev)->id)) + return 1; + dev->platform_data = NULL; + } + return 0; +} + +static int isa_bus_probe(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->probe) + return isa_driver->probe(dev, to_isa_dev(dev)->id); + + return 0; +} + +static int isa_bus_remove(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->remove) + return isa_driver->remove(dev, to_isa_dev(dev)->id); + + return 0; +} + +static void isa_bus_shutdown(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->shutdown) + isa_driver->shutdown(dev, to_isa_dev(dev)->id); +} + +static int isa_bus_suspend(struct device *dev, pm_message_t state) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->suspend) + return isa_driver->suspend(dev, to_isa_dev(dev)->id, state); + + return 0; +} + +static int isa_bus_resume(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->resume) + return isa_driver->resume(dev, to_isa_dev(dev)->id); + + return 0; +} + +static struct bus_type isa_bus_type = { + .name = "lpc-isa", + .match = isa_bus_match, + .probe = isa_bus_probe, + .remove = isa_bus_remove, + .shutdown = isa_bus_shutdown, + .suspend = isa_bus_suspend, + .resume = isa_bus_resume +}; + +static void isa_dev_release(struct device *dev) +{ + kfree(to_isa_dev(dev)); +} + +void lpc_unregister_driver(struct isa_driver *isa_driver) +{ + struct device *dev = isa_driver->devices; + + while (dev) { + struct device *tmp = to_isa_dev(dev)->next; + device_unregister(dev); + dev = tmp; + } + driver_unregister(&isa_driver->driver); +} + + +int lpc_register_driver(struct isa_driver *isa_driver, unsigned int ndev) +{ + int error; + unsigned int id; + + isa_driver->driver.bus = &isa_bus_type; + isa_driver->devices = NULL; + + error = driver_register(&isa_driver->driver); + if (error) + return error; + + for (id = 0; id < ndev; id++) { + struct isa_dev *isa_dev; + + isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL); + if (!isa_dev) { + error = -ENOMEM; + break; + } + + isa_dev->dev.parent = &isa_bus; + isa_dev->dev.bus = &isa_bus_type; + + dev_set_name(&isa_dev->dev, "%s.%u", + isa_driver->driver.name, id); + isa_dev->dev.platform_data = isa_driver; + isa_dev->dev.release = isa_dev_release; + isa_dev->id = id; + + isa_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24); + isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask; + + error = device_register(&isa_dev->dev); + if (error) { + put_device(&isa_dev->dev); + break; + } + + if (isa_dev->dev.platform_data) { + isa_dev->next = isa_driver->devices; + isa_driver->devices = &isa_dev->dev; + } else + device_unregister(&isa_dev->dev); + } + + if (!error && !isa_driver->devices) + error = -ENODEV; + + if (error) + isa_unregister_driver(isa_driver); + + return error; +} + + +int lpc_bus_init(void) +{ + int error; + + error = bus_register(&isa_bus_type); + if (!error) { + error = device_register(&isa_bus); + if (error) + bus_unregister(&isa_bus_type); + } + return error; +} + +void lpc_bus_exit(void) +{ + + device_unregister(&isa_bus); + + bus_unregister(&isa_bus_type); +} + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +/* + * module parameters: + */ +static int i2c_debug = 0; +static struct mutex lpc_lock; + + +#define DEB2(x) if (i2c_debug == 2) x +#define DEB3(x) if (i2c_debug == 3) x + /* print several statistical values */ +#define DEBPROTO(x) if (i2c_debug == 9) x; + /* debug the protocol by showing transferred bits */ +#define DEF_TIMEOUT 160 + + + +/* setting states on the bus with the right timing: */ + +#define set_lpc(adap, ctl, val) adap->setlpc(adap->data, ctl, val) +#define get_lpc(adap, ctl) adap->getlpc(adap->data, ctl) +#define get_own(adap) adap->getown(adap->data) +#define get_clock(adap) adap->getclock(adap->data) +#define i2c_outaddr(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DEVICE_ADDR, val) + +#define i2c_outbyte1(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX1, val) +#define i2c_outbyte2(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX2, val) +#define i2c_outbyte3(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX3, val) +#define i2c_outbyte4(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX4, val) +#define i2c_inbyte1(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX1) +#define i2c_inbyte2(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX2) +#define i2c_inbyte3(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX3) +#define i2c_inbyte4(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX4) + + + +#define LPC_FPRINTF_LOG_PATH "/tmp/file.log" +struct file *lpc_fprintf_file = NULL; + +static int lpc_fprintf_debug(const char *fmt, ...) +{ + char lpc_fprintf_buf[256]={0}; + struct va_format vaf; + va_list args; + int r; + mm_segment_t old_fs; + struct timeval tv; + struct rtc_time tm; + + do_gettimeofday(&tv); + + rtc_time_to_tm(tv.tv_sec,&tm); + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + r=snprintf(lpc_fprintf_buf,sizeof(lpc_fprintf_buf),"[%04d.%08d] %pV\n",tm.tm_sec, (int)tv.tv_usec, &vaf); + va_end(args); + old_fs = get_fs(); + set_fs(KERNEL_DS); + vfs_write(lpc_fprintf_file, (char *)&lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); + set_fs(old_fs); + memset(lpc_fprintf_buf,0x0,sizeof(lpc_fprintf_buf)); + return r; + +} + + + +static int lpc_fprintf_init(void) +{ + printk("lpc_fprintf_init.\n"); + + if(lpc_fprintf_file == NULL) + lpc_fprintf_file = filp_open(LPC_FPRINTF_LOG_PATH, O_RDWR | O_APPEND | O_CREAT, 0644); + + if (IS_ERR(lpc_fprintf_file)) { + printk("Error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH); + return -1; + } + + return 0; +} + +static int lpc_fprintf_exit(void) +{ + printk("lpc_fprintf_exit.\n"); + + if(lpc_fprintf_file != NULL) + filp_close(lpc_fprintf_file, NULL); + + return 0; +} + + +/* other auxiliary functions */ + + +void print_reg(struct i2c_algo_lpc_data *adap) +{ + unsigned char status; + DEBPROTO(lpc_fprintf_debug("================================================\n");) + status = get_lpc(adap, I2C_LPC_REG_BUS_SEL); + DEBPROTO(lpc_fprintf_debug("%s select reg %x : %x\n",__func__,I2C_LPC_REG_BUS_SEL, status);) + status = get_lpc(adap, I2C_LPC_REG_BYTE_COUNT); + DEBPROTO(lpc_fprintf_debug("%s count reg %x : %x\n",__func__,I2C_LPC_REG_BYTE_COUNT, status);) + + status = get_lpc(adap, I2C_LPC_REG_COMMAND); + DEBPROTO(lpc_fprintf_debug("%s command reg %x : %x\n",__func__,I2C_LPC_REG_COMMAND, status);) + status = get_lpc(adap, I2C_LPC_REG_DEVICE_ADDR); + DEBPROTO(lpc_fprintf_debug("%s address reg %x : %x\n",__func__,I2C_LPC_REG_DEVICE_ADDR, status);) + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + DEBPROTO(lpc_fprintf_debug("%s status reg %x : %x\n",__func__,I2C_LPC_REG_STATUS, status);) +} + + + +static void i2c_repstart(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_REPSTART); +} + +static void i2c_stop(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_STOP); + udelay(60); + set_lpc(adap, I2C_LPC_REG_COMMAND, 0x00); +} + + + + +static void i2c_start(struct i2c_algo_lpc_data *adap) +{ + print_reg(adap); + + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_START); + + print_reg(adap); +} + + + + +static int wait_for_bb(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus free status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is free status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout for free busy status : %x\n",__func__,status);) + return -ETIMEDOUT; + } + + + + return 0; +} + + +static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + unsigned char status; + + + while (--timeout) { + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus empty status : %x\n",__func__,status);) + + if(mode == 1) + { + if((status & I2C_LPC_IBB) && (status & I2C_LPC_TBE)) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + else + { + if(status & I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Empty\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + +static int wait_for_bf(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus full status : %x\n",__func__,status);) + + if(status & I2C_LPC_RBF) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is full status : %x\n",__func__,status);) + break; + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Full\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + +static int wait_for_td(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status=0; + + while (--timeout) { + udelay(4); + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus done status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is done status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Done\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + + +static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) +{ + int timeout = DEF_TIMEOUT; + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + + while ((*status & I2C_LPC_TBE) && --timeout) { + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + } + + if (timeout == 0) + return -ETIMEDOUT; + + + return 0; +} + + +static int lpc_doAddress(struct i2c_algo_lpc_data *adap,struct i2c_msg *msg) +{ + unsigned short flags = msg->flags; + unsigned char addr; + + addr = msg->addr << 1; + if (flags & I2C_M_RD) + { + addr |= 1; + DEBPROTO(lpc_fprintf_debug("step 7 : read mode then write device address 0x%x\n",addr);) + } + else + { + DEBPROTO(lpc_fprintf_debug("step 2 : write mode then write device address 0x%x\n",addr);) + } + + if (flags & I2C_M_REV_DIR_ADDR) + { + addr ^= 1; + + } + i2c_outaddr(adap, addr); + return 0; + +} + + +static int lpc_sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + int i = 0,timeout=0; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 3 : write register count %x\n",count);) + + if((count -i) >= 4) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + i2c_outbyte4(adap, buf[i+3] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+3,buf[i+3]);) + i += 4; + } + else if((count -i) == 3) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 5-1 : Delay 6mS \n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 5-2 : Start to transfrom \n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 5-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 6 : Waiting for BE\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 6 : Timeout waiting for BE \n");) + return -EREMOTEIO; + } + }while (i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes failed \n",count);) + return -EIO; + } +} + +static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + int i=0,timeout=0; + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 8 : write register count %d\n",count);) + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 9-1 : Delay 6mS\n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 9-2 : Start to receive data\n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 9-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 10 : Waiting for TD\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 10 : Timeout waiting for TD \n");) + return -EREMOTEIO; + } + + if((count -i) >= 4) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + buf[i+3] = 0xff & i2c_inbyte4(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+3,buf[i+3]);) + + i += 4; + } + else if((count -i) == 3) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + + }while(i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes failed \n",count);) + return -EIO; + } +} + + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; +#define LPC_I2C_MAX_NCHANS 6 + + +struct lpc_iic { + struct i2c_adapter *virt_adaps[LPC_I2C_MAX_NCHANS]; + u8 last_chan; /* last register value */ +}; + + +static int lpc_master_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + struct i2c_msg *pmsg; + int i; + int ret=0; + + mutex_lock(&lpc_lock); + + if (adap->xfer_begin) + adap->xfer_begin(&i2c_adap->nr); + + + for (i = 0;ret >= 0 && i < num; i++) { + pmsg = &msgs[i]; + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", + pmsg->flags & I2C_M_RD ? "read" : "write", + pmsg->len, pmsg->addr, i + 1, num);) + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", + i, msgs[i].addr, msgs[i].flags, msgs[i].len);) + + if (pmsg->flags & I2C_M_RD) { + ret = lpc_readbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only read %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: read %d bytes.\n",ret)); + } + } else { + + ret = lpc_sendbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only wrote %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: wrote %d bytes.\n",ret)); + } + } + } + + if (adap->xfer_end) + adap->xfer_end(&i2c_adap->nr); + + mutex_unlock(&lpc_lock); + + DEBPROTO(lpc_fprintf_debug("ret = 0x%x num = 0x%x i = 0x%x.\n",ret,num,i)); + + return ret = (ret < 0) ? ret : num; +} + + +static u32 lpc_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + +/* exported algorithm data: */ +static const struct i2c_algorithm lpc_algo = { + .master_xfer = lpc_master_xfer, + //.smbus_xfer = lpc_smbus_xfer, + .functionality = lpc_func, +}; + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +#define DEFAULT_BASE 0x0a00 + +static int lpc_base= 0x0a00; +static u8 __iomem *lpc_base_iomem; + +static int lpc_irq; +static int lpc_clock = 0x1c; +static int lpc_own = 0x55; +static int lpc_mmapped; + +static unsigned long lpc_base_addr = 0x0a00; +static unsigned int lpc_io_space_size = 2; + +static unsigned long LPC_INDEX_REG; +static unsigned long LPC_DATA_REG; + + +/* notice : removed static struct i2c_lpc_iic gpi; code - + this module in real supports only one device, due to missing arguments + in some functions, called from the algo-lpc module. Sometimes it's + need to be rewriten - but for now just remove this for simpler reading */ + +static wait_queue_head_t lpc_wait; +static int lpc_pending; +static spinlock_t lock; +static spinlock_t lpc_slock; + +static struct i2c_adapter lpc_iic_ops; + +struct cpld_dev_type { + struct resource *io_resource; + struct semaphore sem; + struct cdev cdev; +}; + +struct cpld_dev_type *cpld_device; + + +/* ----- local functions ---------------------------------------------- */ + +static void lpc_cpld_setbyte(void *data, int ctl, int val) +{ + outb(ctl, LPC_INDEX_REG); + mb(); + + outb(val, LPC_DATA_REG); + mb(); +} + +static int lpc_cpld_getbyte(void *data, int ctl) +{ + u8 val = 0; + + outb(ctl, LPC_INDEX_REG); + mb(); + + val = inb(LPC_DATA_REG); + mb(); + + return val; +} + +static void lpc_iic_setbyte(void *data, int ctl, int val) +{ + if (!cpld_device) + { + return ; + } + + if (down_interruptible(&cpld_device->sem)) + { + return ; + } + + + lpc_cpld_setbyte(data,ctl,val); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) +} + + +static int lpc_iic_getbyte(void *data, int ctl) +{ + u8 val = 0; + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + val = lpc_cpld_getbyte(data,ctl); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) + return val; +} + +int cig_cpld_read_register(u8 reg_off, u8 *val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + *val = lpc_cpld_getbyte(cpld_device, reg_off); + + up(&cpld_device->sem); + + return 0; +} +EXPORT_SYMBOL(cig_cpld_read_register); + +int cig_cpld_write_register(u8 reg_off, u8 val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + lpc_cpld_setbyte(cpld_device, reg_off, val); + up(&cpld_device->sem); + return 0; +} +EXPORT_SYMBOL(cig_cpld_write_register); + + + +static int lpc_iic_getown(void *data) +{ + return (lpc_own); +} + + +static int lpc_iic_getclock(void *data) +{ + return (lpc_clock); +} + +static void lpc_iic_waitforpin(void *data) +{ + DEFINE_WAIT(wait); + int timeout = 2; + unsigned long flags; + + if (lpc_irq > 0) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 0) { + spin_unlock_irqrestore(&lock, flags); + prepare_to_wait(&lpc_wait, &wait, TASK_INTERRUPTIBLE); + if (schedule_timeout(timeout*HZ)) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 1) { + lpc_pending = 0; + } + spin_unlock_irqrestore(&lock, flags); + } + finish_wait(&lpc_wait, &wait); + } else { + lpc_pending = 0; + spin_unlock_irqrestore(&lock, flags); + } + } else { + udelay(100); + } +} + + +static irqreturn_t lpc_iic_handler(int this_irq, void *dev_id) { + spin_lock(&lock); + lpc_pending = 1; + spin_unlock(&lock); + wake_up_interruptible(&lpc_wait); + return IRQ_HANDLED; +} + +static int board_id = 0; + + +static int lpc_iic_select(void *data) +{ + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step 1 : selest channel id = %d\n",chan_id);) + lpc_iic_setbyte(data,I2C_LPC_REG_BUS_SEL,chan_id); + + return 0; +} + +static int lpc_iic_deselect(void *data) +{ + + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step last :deselect channel id = %d\n",chan_id);) + + return 0; +} + + +/* ------------------------------------------------------------------------ + * Encapsulate the above functions in the correct operations structure. + * This is only done when more than one hardware adapter is supported. + */ +static struct i2c_algo_lpc_data lpc_iic_data = { + .setlpc = lpc_iic_setbyte, + .getlpc = lpc_iic_getbyte, + .getown = lpc_iic_getown, + .getclock = lpc_iic_getclock, + .waitforpin = lpc_iic_waitforpin, + .xfer_begin = lpc_iic_select, + .xfer_end = lpc_iic_deselect, +}; + +#include + +static struct i2c_adapter lpc_iic_arr_ops[LPC_I2C_MAX_NCHANS] = {0}; + +static void dummy_setscl(void *data, int state) +{ + return; +} + +static void dummy_setsda(void *data, int state) +{ + return; + +} + +static int dummy_getscl(void *data) +{ + return 1; + +} + +static int dummy_getsda(void *data) +{ + return 1; +} + + +static struct i2c_algo_bit_data dummy_algo_data = { + .setsda = dummy_setsda, + .setscl = dummy_setscl, + .getsda = dummy_getsda, + .getscl = dummy_getscl, + .udelay = 50, + .timeout = HZ, +}; + + +static int dummy_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + return 1; +} + +static u32 dummy_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + + +static const struct i2c_algorithm dummy_algo = { + .master_xfer = dummy_xfer, + .functionality = dummy_func, +}; + + + +static struct i2c_adapter i2c_dummy = { + .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .algo_data = &dummy_algo_data, + .algo = &dummy_algo, + .name = "i2c_dummy", +}; + + +static int lpc_iic_match(struct device *dev, unsigned int id) +{ + /* sanity checks for lpc_mmapped I/O */ + + DEB2(printk("lpc_iic_match\n");) + + + if (lpc_base < DEFAULT_BASE) { + dev_err(dev, "incorrect lpc_base address (%#x) specified " + "for lpc_mmapped I/O\n", lpc_base); + return 0; + } + + if (lpc_base == 0) { + lpc_base = DEFAULT_BASE; + } + return 1; +} + +static int lpc_iic_probe(struct device *dev, unsigned int id) +{ + int rval,num; + + lpc_fprintf_init(); + + DEB2(printk("lpc_iic_probe\n");) + + mutex_init(&lpc_lock); + + for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) + { + lpc_iic_arr_ops[num].dev.parent = dev; + lpc_iic_arr_ops[num].owner = THIS_MODULE; + lpc_iic_arr_ops[num].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + lpc_iic_arr_ops[num].algo = &lpc_algo; + lpc_iic_arr_ops[num].algo_data = &lpc_iic_data, + lpc_iic_arr_ops[num].nr=num; + snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num])); + rval |= i2c_add_adapter(&lpc_iic_arr_ops[num]); + DEB2(printk("%s\n",lpc_iic_arr_ops[num].name);) + } + + return 0; +} + +static int lpc_iic_remove(struct device *dev, unsigned int id) +{ + int num; + DEB2(printk("lpc_iic_remove\n")); + + lpc_fprintf_exit(); + for(num = LPC_I2C_MAX_NCHANS - 1; num >= 0 ;num--) + i2c_del_adapter(&lpc_iic_arr_ops[num]); + + + return 0; +} + +static struct isa_driver i2c_lpc_driver = { + .match = lpc_iic_match, + .probe = lpc_iic_probe, + .remove = lpc_iic_remove, + .driver = { + .owner = THIS_MODULE, + .name = "lpc-iic", + }, +}; + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ + +static int cpld_major = 0; +static int cpld_minor = 0; + +struct cpld_rw_msg { + unsigned char addr; + unsigned char data; +}; + + +static struct cpld_rw_msg param_read = {-1}; +static struct cpld_rw_msg param_write = {-1}; +static struct cpld_rw_msg param_reads = {-1}; +static struct cpld_rw_msg param_writes = {-1}; + +void cpld_sysfs_kobj_release(struct kobject *kobj) +{ + return; +} + +int cpld_sysfs_add_attr(struct kobject* kobj, char* attr_name) +{ + + struct attribute *attr; + + attr = kmalloc(sizeof(struct attribute), GFP_KERNEL); + attr->name = attr_name; + attr->mode = 0644; + + return sysfs_create_file(kobj, attr); +} + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data); +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data); + + +static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buffer) +{ + u8 val=0,ret=0,year=0,month=0,day=0,cpld_m=0,cpld_1=0,cpld_2=0; + + if (0 == strcmp(attr->name, "read")) + { + val = lpc_iic_getbyte(NULL,param_read.addr); + ret = sprintf(buffer,"read : addr = 0x%x val = 0x%x\n",param_read.addr, val); + + } + else if (0 == strcmp(attr->name, "write")) + { + lpc_iic_setbyte(NULL, param_write.addr,param_write.data); + ret = sprintf(buffer,"write : addr = 0x%x val = 0x%x\n",param_write.addr, param_write.data); + } + else if (0 == strcmp(attr->name, "version")) + { + cpld_m = lpc_iic_getbyte(NULL, 0x02); + year = lpc_iic_getbyte(NULL, 0x03); + month = lpc_iic_getbyte(NULL, 0x04); + day = lpc_iic_getbyte(NULL, 0x05); + + cig_cpld_read_slave_cpld_register(0x1d,&cpld_1); + cig_cpld_read_slave_cpld_register(0x1e,&cpld_2); + + ret = sprintf(buffer,"Main CPLD version : V%02x\n"\ + "Main CPLD date : 20%02x-%02x-%02x\n"\ + "Slave 1 CPLD version : V%02x\n"\ + "Slave 2 CPLD version : V%02x\n",cpld_m,year,month,day,cpld_1,cpld_2); + } + if (0 == strcmp(attr->name, "reads")) + { + ret = cig_cpld_read_slave_cpld_register(param_reads.addr,&val); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"reads : addr = 0x%x val = 0x%x\n",param_reads.addr, val); + + } + else if (0 == strcmp(attr->name, "writes")) + { + ret = cig_cpld_write_slave_cpld_register(param_writes.addr,param_writes.data); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"writes : addr = 0x%x val = 0x%x\n",param_writes.addr, param_writes.data); + } + + + return ret; + +} + +static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t count) +{ + int param[3]; + + if (0 == strcmp(attr->name, "read")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_read.addr = param[0]; + } + else if (0 == strcmp(attr->name, "write")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_write.addr = param[0]; + param_write.data = param[1]; + } + if (0 == strcmp(attr->name, "reads")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_reads.addr = param[0]; + } + else if (0 == strcmp(attr->name, "writes")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_writes.addr = param[0]; + param_writes.data = param[1]; + } + return count; +} + + + +static struct sysfs_ops cpld_sysfs_ops = +{ + .show = cpld_sysfs_show, + .store = cpld_sysfs_store, +}; + +static struct kobj_type cpld_kobj_type = +{ + .release = cpld_sysfs_kobj_release, + .sysfs_ops = &cpld_sysfs_ops, + .default_attrs = NULL, +}; + + +static const char driver_name[] = "cpld_drv"; +static atomic_t cpld_available = ATOMIC_INIT(1); +static struct class *cpld_class; +static struct device *cpld_dev; + + + +#define CPLD_IOC_MAGIC '[' + +#define CPLD_IOC_RDREG _IOR(CPLD_IOC_MAGIC, 0, struct cpld_rw_msg) +#define CPLD_IOC_WRREG _IOW(CPLD_IOC_MAGIC, 1, struct cpld_rw_msg) + +#define CPLD_IOC_MAXNR 2 + + +int cpld_open(struct inode *inode, struct file *filp) +{ + struct cpld_dev_type *dev; + + if (! atomic_dec_and_test(&cpld_available)) { + atomic_inc(&cpld_available); + return -EBUSY; + } + + dev = container_of(inode->i_cdev, struct cpld_dev_type, cdev); + filp->private_data = dev; + + return 0; +} + +int cpld_release(struct inode *inode, struct file *flip) +{ + atomic_inc(&cpld_available); + return 0; +} + + +long cpld_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int rc = 0; + int err = 0; + struct cpld_dev_type *dev = (struct cpld_dev_type *)filp->private_data; + struct cpld_rw_msg msg; + + if (_IOC_TYPE(cmd) != CPLD_IOC_MAGIC) + return -ENOTTY; + if (_IOC_NR(cmd) > CPLD_IOC_MAXNR) + return -ENOTTY; + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); + if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + + if (down_interruptible(&dev->sem)) + return -ERESTARTSYS; + + switch(cmd){ + case CPLD_IOC_RDREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + msg.data = lpc_cpld_getbyte(dev, msg.addr); + rc = copy_to_user((void __user *)arg, &msg, sizeof(msg)); + } + break; + + case CPLD_IOC_WRREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + lpc_cpld_setbyte(dev, msg.addr, msg.data); + } + break; + default: + rc = -ENOTTY; + break; + } + up(&dev->sem); + + return rc; +} + +struct file_operations cpld_fops = { + .owner = THIS_MODULE, + .open = cpld_open, + .unlocked_ioctl = cpld_ioctl, + .release = cpld_release, +}; + + +static void cpld_setup_cdev(struct cpld_dev_type *dev) +{ + int err, devno = MKDEV(cpld_major, cpld_minor); + + cdev_init(&dev->cdev, &cpld_fops); + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &cpld_fops; + err = cdev_add(&dev->cdev, devno, 1); + + if (err) + DEB2(printk(KERN_NOTICE "Error %d adding cpld", err);) +} +/********************************************** End ********************************************************/ + + + + +/********************************************** Start ********************************************************/ +#include +#include +#include + +static spinlock_t irq_inter_lock; +static struct delayed_work irq_inter_work; +static unsigned long irq_inter_delay; + + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<=======write=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1); + DEB2(printk("[62]=%x\n",reg_addr << 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, reg_data); + DEB2(printk("[63]=%x\n",reg_data)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x02); + DEB2(printk("<=======write=========>")); + + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<========read=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1 | 1); + DEB2(printk("[62]=%x\n",reg_addr << 1 | 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,reg_data); + DEB2(printk("[64]=%x\n",*reg_data)); + DEB2(printk("<========read=========>")); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + +struct sock *nlsk = NULL; +extern struct net init_net; +#define NETLINK_TEST 26 +#define MSG_LEN 125 +#define USER_PORT 100 +static u32 irq_present_status_low_current,irq_present_status_low_next; +static u32 irq_present_status_high_current,irq_present_status_high_next; +static u32 irq_tx_fault_status_low_current,irq_tx_fault_status_low_next; +static u32 irq_tx_fault_status_high_current,irq_tx_fault_status_high_next; +static u32 irq_rx_lost_status_low_current,irq_rx_lost_status_low_next; +static u32 irq_rx_lost_status_high_current,irq_rx_lost_status_high_next; + +static u8 irq_present_qsfp_current,irq_present_qsfp_next; +static u8 irq_interrupt_qsfp_current,irq_interrupt_qsfp_next; + +struct input_dev *cpld_input_dev; + + + +int send_usrmsg(char *pbuf, uint16_t len) +{ + struct sk_buff *nl_skb; + struct nlmsghdr *nlh; + + int ret; + + + nl_skb = nlmsg_new(len, GFP_ATOMIC); + if(!nl_skb) + { + printk("netlink alloc failure\n"); + return -1; + } + + + nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0); + if(nlh == NULL) + { + printk("nlmsg_put failaure \n"); + nlmsg_free(nl_skb); + return -1; + } + + memcpy(nlmsg_data(nlh), pbuf, len); + ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); + + return ret; +} + +static void netlink_rcv_msg(struct sk_buff *skb) +{ + + struct nlmsghdr *nlh = NULL; + char *umsg = NULL; + char kmsg[1024] = {0}; + char kmsg_tmp[16] = {0}; + u8 i = 0; + u8 tmp[3]={0}; + + if(skb->len >= nlmsg_total_size(0)) + { + nlh = nlmsg_hdr(skb); + umsg = NLMSG_DATA(nlh); + if(umsg) + { + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+1,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+25,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + + for(i = 0;i < 8;i++) + { + if(!(irq_present_qsfp_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"qsfp%02d:%1d:%1d:%1d ",i+49,tmp[0],tmp[1],0); + strcat(kmsg,kmsg_tmp); + } + + printk("kernel recv from user: %s\n", umsg); + send_usrmsg(kmsg, strlen(kmsg)); + } + } + + return ; +} + + + +struct netlink_kernel_cfg cfg = { + .input = netlink_rcv_msg, /* set recv callback */ +}; + + + +#define RANGE_OF_BYTE_SHIFT(to_arg,shift,from_arg) {to_arg &= ~(0xff << shift); to_arg |= from_arg << shift;} + + +static void irq_inter_wapper(struct work_struct * work) +{ + + u8 m_data = 0; + u8 data_high8 = 0,data_low8 = 0; + u16 data_16 = 0; + u8 status = 0; + u8 i = 0; + char kmsg[64]={0}; + u8 tmp[3] = {0}; + + DEB2(printk("CPLD_MASTER_INTERRUPT\r\n")); + + m_data = lpc_iic_getbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG); + lpc_iic_setbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG,0xff); + + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0xff); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0xff); + if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD1)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,16,status); + } + DEB2(printk("irq_present_status_low_next = %08x irq_present_status_low_current = %08x \n",irq_present_status_low_next,irq_present_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_RX_LOST08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,16,status); + } + DEB2(printk("irq_rx_lost_status_low_next = %08x irq_rx_lost_status_low_current = %08x \n",irq_rx_lost_status_low_next,irq_rx_lost_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,16,status); + } + DEB2(printk("irq_tx_fault_status_low_next = %08x irq_tx_fault_status_low_current = %08x \n",irq_tx_fault_status_low_next,irq_tx_fault_status_low_current)); + + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD2)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT32_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT40_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,16,status); + } + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,16,status); + } + + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,16,status); + } + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT56)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT56_REG,&status); + irq_present_qsfp_current = status; + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_QSFP_CR56)) + { + DEB2(printk("CPLD_SLAVE2_QSFP_CR56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_QSFP_CR56_REG,&status); + irq_interrupt_qsfp_current = status; + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_LSW)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_LSW\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU1)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU1\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU2)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU2\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_6320)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_6320\r\n")); + } + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0x0); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0x0); + + memset(tmp,0xff,sizeof(tmp)); + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i)) && (irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+1)); + tmp[0] = 1; + } + else if((irq_present_status_low_current & (0x1 << i)) && !(irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+1)); + tmp[0] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i)) && (irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+1)); + tmp[1] = 1; + } + else if((irq_tx_fault_status_low_current & (0x1 << i)) && !(irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+1)); + tmp[1] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i)) && (irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+1)); + tmp[2] = 1; + } + else if((irq_rx_lost_status_low_current & (0x1 << i)) && !(irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+1)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+1,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i)) && (irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+25)); + tmp[0] = 1; + } + else if((irq_present_status_high_current & (0x1 << i)) && !(irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+25)); + tmp[0] = 0; + + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i)) && (irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+25)); + tmp[1] = 1; + } + else if((irq_rx_lost_status_high_current & (0x1 << i)) && !(irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+25)); + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i)) && (irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+25)); + tmp[2] = 1; + } + else if((irq_tx_fault_status_high_current & (0x1 << i)) && !(irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+25)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+25,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0 ; i < 8; i++) + { + if(!(irq_present_qsfp_current & (0x1 << i)) && (irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+49)); + tmp[0] = 1; + } + else if((irq_present_qsfp_current & (0x1 << i)) && !(irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+49)); + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i)) && (irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is occured \r\n",i+49)); + tmp[1] = 1; + } + else if((irq_interrupt_qsfp_current & (0x1 << i)) && !(irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is cleaned\r\n",i+49)); + tmp[1] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"qsfp%02d:%1d:%1d:%1d ",i+49,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],0); + break; + } + } + + + irq_present_status_low_next = irq_present_status_low_current; + irq_rx_lost_status_low_next = irq_rx_lost_status_low_current; + irq_tx_fault_status_low_next = irq_tx_fault_status_low_current; + irq_present_status_high_next = irq_present_status_high_current; + irq_rx_lost_status_high_next = irq_rx_lost_status_high_current; + irq_tx_fault_status_high_next = irq_tx_fault_status_high_current; + irq_present_qsfp_next = irq_present_qsfp_current; + irq_interrupt_qsfp_next = irq_interrupt_qsfp_current; + + send_usrmsg(kmsg, strlen(kmsg)); +} + +static void disableIrq(unsigned short maskReg, unsigned short mask) +{ + u8 data = 0; + + data = lpc_iic_getbyte(NULL,maskReg); + data |= mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + +static void enableIrq(unsigned short maskReg, unsigned short mask) +{ + unsigned short data; + + data = lpc_iic_getbyte(NULL,maskReg); + data &= ~mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + + +static irqreturn_t irq_inter_isr(int irq, void *handle) +{ + + /* + * use keventd context to read the event fifo registers + * Schedule readout at least 25ms after notification for + * REVID < 4 + */ + + schedule_delayed_work(&irq_inter_work, irq_inter_delay); + + return IRQ_HANDLED; +} + + +#define CIG_CPLD_CHR_NAME "cpld" + + +static int __init cpld_init(void) +{ + int rval,rc=0; + dev_t dev; + u8 s_data; + + DEB2(printk("cpld_init\n");) + +/**************************************************************************************/ + + LPC_INDEX_REG = lpc_base_addr; + LPC_DATA_REG = lpc_base_addr + 1; + + cpld_device = kzalloc(sizeof(struct cpld_dev_type), GFP_KERNEL); + if (!cpld_device) + goto error3; + cpld_device->io_resource = request_region(lpc_base_addr, + lpc_io_space_size, "lpc-i2c"); + if (!cpld_device->io_resource) { + printk("lpc: claim I/O resource fail\n"); + goto error2; + } + sema_init(&cpld_device->sem, 1); + + if (cpld_major) { + dev = MKDEV(cpld_major, cpld_minor); + rc = register_chrdev_region(dev, 1, CIG_CPLD_CHR_NAME); + } else { + rc = alloc_chrdev_region(&dev, cpld_major, 1, CIG_CPLD_CHR_NAME); + cpld_major = MAJOR(dev); + } + + cpld_setup_cdev(cpld_device); + + cpld_class = class_create(THIS_MODULE,CIG_CPLD_CHR_NAME); + if (!cpld_class) { + DEB2(printk("failed to create class\n");) + goto error1; + } + + cpld_class->p->subsys.kobj.ktype= &cpld_kobj_type; + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "read"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "write"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "reads"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "writes"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "version"); + + cpld_dev = device_create(cpld_class, NULL, dev, NULL, CIG_CPLD_CHR_NAME); + +/**************************************************************************************/ + + rval = lpc_bus_init(); + rval = lpc_register_driver(&i2c_lpc_driver, 1); + +/**************************************************************************************/ + return 0; +error1: + cdev_del(&cpld_device->cdev); + unregister_chrdev_region(dev, 1); +error2: + release_resource(cpld_device->io_resource); +error3: + kfree(cpld_device); + + return rc; +} + +static void __exit cpld_exit(void) +{ + DEB2(printk("cpld_exit\n")); + + lpc_unregister_driver(&i2c_lpc_driver); + lpc_bus_exit(); + dev_t devno = MKDEV(cpld_major, cpld_minor); + + cdev_del(&cpld_device->cdev); + if (cpld_class) { + device_destroy(cpld_class, devno); + class_destroy(cpld_class); + } + + if (cpld_device) { + if (cpld_device->io_resource) + release_resource(cpld_device->io_resource); + + kfree(cpld_device); + } + unregister_chrdev_region(devno, 1); + + +} + +module_param(cpld_major, int, S_IRUGO); +module_param(cpld_minor, int, S_IRUGO); +module_param(i2c_debug, int, S_IRUGO); +module_param(board_id, int, S_IRUGO); + +module_init(cpld_init); +module_exit(cpld_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436-54p-cpld driver"); +MODULE_LICENSE("GPL"); + + +/********************************************** End ********************************************************/ + + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-fan.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-fan.c new file mode 100644 index 000000000000..881cb7304b06 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-fan.c @@ -0,0 +1,521 @@ +/* + * A hwmon driver for the CIG cs6436-54p fan + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define FAN_SPEED_DUTY_TO_CPLD_STEP 10 + +static struct cs6436_54p_fan_data *cs6436_54p_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + + +extern int cig_cpld_write_register(u8 reg_off, u8 val); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x41, /* fan enable/disable */ + 0x40, /* fan PWM(for all fan) */ + 0x42, /* front fan 1 speed(rpm) */ + 0x44, /* front fan 2 speed(rpm) */ + 0x46, /* front fan 3 speed(rpm) */ + 0x48, /* front fan 4 speed(rpm) */ + 0x4a, /* front fan 5 speed(rpm) */ + 0x43, /* rear fan 1 speed(rpm) */ + 0x45, /* rear fan 2 speed(rpm) */ + 0x47, /* rear fan 3 speed(rpm) */ + 0x49, /* rear fan 4 speed(rpm) */ + 0x4b, /* rear fan 5 speed(rpm) */ + 0x4c, /* fan direction rear to front or front to rear */ +}; + + +/* Each client has this additional data */ +struct cs6436_54p_fan_data { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ +}; + +static struct cs6436_54p_fan_data *fan_data = NULL; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID, +}; + +enum sysfs_fan_attributes { + FAN_STATE_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN_DIRECTION, + FAN1_STATE, + FAN2_STATE, + FAN3_STATE, + FAN4_STATE, + FAN5_STATE, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, +}; + +/* Define attributes + */ +#define DECLARE_FAN_STATE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_state, S_IRUGO, fan_show_value, NULL, FAN##index##_STATE) +#define DECLARE_FAN_STATE_ATTR(index) &sensor_dev_attr_fan##index##_state.dev_attr.attr + +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index) &sensor_dev_attr_fan##index##_fault.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##index##_DUTY_CYCLE_PERCENTAGE) +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan##index##_duty_cycle_percentage.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + + +/* 5 fan state attributes in this platform */ +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(3); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(4); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(5); + + +/* 5 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5); + +/* 5 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5); + +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); + +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); + + +static struct attribute *cs6436_54p_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_STATE_ATTR(1), + DECLARE_FAN_STATE_ATTR(2), + DECLARE_FAN_STATE_ATTR(3), + DECLARE_FAN_STATE_ATTR(4), + DECLARE_FAN_STATE_ATTR(5), + DECLARE_FAN_FAULT_ATTR(1), + DECLARE_FAN_FAULT_ATTR(2), + DECLARE_FAN_FAULT_ATTR(3), + DECLARE_FAN_FAULT_ATTR(4), + DECLARE_FAN_FAULT_ATTR(5), + DECLARE_FAN_SPEED_RPM_ATTR(1), + DECLARE_FAN_SPEED_RPM_ATTR(2), + DECLARE_FAN_SPEED_RPM_ATTR(3), + DECLARE_FAN_SPEED_RPM_ATTR(4), + DECLARE_FAN_SPEED_RPM_ATTR(5), + DECLARE_FAN_DUTY_CYCLE_ATTR(), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), + NULL +}; + +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + if (reg_val +== 0xFF) { + return 100; + } + return ((u32)(reg_val) * 100)/ 255; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + if (duty_cycle >= FAN_MAX_DUTY_CYCLE) { + return 0xFF; + } + + return 255 / 10 * (duty_cycle / 10); +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_is_state(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct cs6436_54p_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value <= 0 || value > FAN_MAX_DUTY_CYCLE) + return -EINVAL; + + cig_cpld_write_register(fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + + return count; +} + +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value,fan_index; + u8 mask,reg_val; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + fan_index = attr->index - FAN1_DIRECTION; + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (!(value == 0 || value == 1)) + return -EINVAL; + + + cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val); + + if(value == 1) + { + reg_val |= (1 << fan_index); + } + else + { + reg_val &= ~(1 << fan_index); + } + + cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val); + + return count; +} + + + + + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + cs6436_54p_fan_update_device(dev); + + struct cs6436_54p_fan_data *data = fan_data; + + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + + case FAN1_STATE: + case FAN2_STATE: + case FAN3_STATE: + case FAN4_STATE: + case FAN5_STATE: + //printk("FAN_STATE_REG: 0x%x\n", data->reg_val[FAN_STATE_REG]); + //printk("index: %d\n", attr->index); + ret = sprintf(buf, "%d\n", + reg_val_to_is_state(data->reg_val[FAN_STATE_REG], + attr->index - FAN1_STATE)); + break; + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: +// printk("FAN_seed_REG: 0x%x\n", data->reg_val[attr->index]); +// printk("index: %d\n", attr->index); + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group cs6436_54p_fan_group = { + .attrs = cs6436_54p_fan_attributes, +}; + +static struct cs6436_54p_fan_data *cs6436_54p_fan_update_device(struct device *dev) +{ + struct cs6436_54p_fan_data *data = fan_data; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + u8 status; + (void)cig_cpld_read_register(fan_reg[i], &status); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int cs6436_54p_fan_probe(struct platform_device *pdev) +{ + int status = -1; + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &cs6436_54p_fan_group); + if (status) { + goto exit; + + } + + fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(fan_data->hwmon_dev)) { + status = PTR_ERR(fan_data->hwmon_dev); + goto exit_remove; + } + + dev_info(&pdev->dev, "cs6436_54p_fan\n"); + + return 0; + +exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &cs6436_54p_fan_group); +exit: + return status; +} + +static int cs6436_54p_fan_remove(struct platform_device *pdev) +{ + hwmon_device_unregister(fan_data->hwmon_dev); + sysfs_remove_group(&fan_data->pdev->dev.kobj, &cs6436_54p_fan_group); + + return 0; +} + +#define DRVNAME "cs6436_54p_fan" + +static struct platform_driver cs6436_54p_fan_driver = { + .probe = cs6436_54p_fan_probe, + .remove = cs6436_54p_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + + + + + +static int __init cs6436_54p_fan_init(void) +{ + int ret; + + cig_cpld_write_register(0x40, duty_cycle_to_reg_val(50)); + + ret = platform_driver_register(&cs6436_54p_fan_driver); + if (ret < 0) { + goto exit; + } + + fan_data = kzalloc(sizeof(struct cs6436_54p_fan_data), GFP_KERNEL); + if (!fan_data) { + ret = -ENOMEM; + platform_driver_unregister(&cs6436_54p_fan_driver); + goto exit; + } + + mutex_init(&fan_data->update_lock); + fan_data->valid = 0; + + fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(fan_data->pdev)) { + ret = PTR_ERR(fan_data->pdev); + platform_driver_unregister(&cs6436_54p_fan_driver); + kfree(fan_data); + goto exit; + } + +exit: + return ret; +} + +static void __exit cs6436_54p_fan_exit(void) +{ + platform_device_unregister(fan_data->pdev); + platform_driver_unregister(&cs6436_54p_fan_driver); + kfree(fan_data); +} + +MODULE_AUTHOR("CIG"); +MODULE_DESCRIPTION("cs6436_54p_fan driver"); +MODULE_LICENSE("GPL"); + +module_init(cs6436_54p_fan_init); +module_exit(cs6436_54p_fan_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-led.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-led.c new file mode 100644 index 000000000000..74c8b6d0b10e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-led.c @@ -0,0 +1,594 @@ +/* + * A hwmon driver for the CIG cs6436-54P LED + * + * Copyright (C) 2018 Cambridge, Inc. + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "cs6436_54p_led" + +struct cs6436_54p_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[6]; /* 0: system & location + 1: PSU1 &PSU12 + 2: fan & management + 3: console & ToD + 4-5 : fan1-fan5*/ +}; + +static struct cs6436_54p_led_data *ledctl = NULL; + +/* LED related data + */ +#define LED_TYPE_PSU1_REG_MASK 0x0C +#define LED_MODE_PSU1_GREEN_MASK 0x08 +#define LED_MODE_PSU1_RED_MASK 0x04 +#define LED_MODE_PSU1_AMBER_MASK 0x0C +#define LED_MODE_PSU1_OFF_MASK 0x00 + +#define LED_TYPE_PSU2_REG_MASK 0x30 +#define LED_MODE_PSU2_GREEN_MASK 0x20 +#define LED_MODE_PSU2_RED_MASK 0x10 +#define LED_MODE_PSU2_AMBER_MASK 0x30 +#define LED_MODE_PSU2_OFF_MASK 0x00 + +#define LED_TYPE_SYS_REG_MASK 0xF0 +#define LED_MODE_SYS_GREEN_MASK 0x40 +#define LED_MODE_SYS_RED_MASK 0x20 +#define LED_MODE_SYS_AMBER_MASK 0x60 +#define LED_MODE_SYS_AMBER_FLASHING_MASK 0x70 +#define LED_MODE_SYS_OFF_MASK 0x00 + +#define LED_TYPE_RES_REG_MASK 0x0F +#define LED_MODE_RES_GREEN_MASK 0x04 +#define LED_MODE_RES_RED_MASK 0x02 +#define LED_MODE_RES_AMBER_MASK 0x06 +#define LED_MODE_RES_AMBER_FLASHING_MASK 0x07 +#define LED_MODE_RES_OFF_MASK 0x00 + +#define LED_TYPE_FAN_REG_MASK 0x03 +#define LED_MODE_FAN_GREEN_MASK 0x02 +#define LED_MODE_FAN_RED_MASK 0x01 +#define LED_MODE_FAN_AMBER_MASK 0x03 +#define LED_MODE_FAN_OFF_MASK 0x00 + +#define LED_TYPE_FAN1_REG_MASK 0x03 +#define LED_TYPE_FAN2_REG_MASK 0x0C +#define LED_TYPE_FAN3_REG_MASK 0x30 +#define LED_TYPE_FAN4_REG_MASK 0xC0 +#define LED_TYPE_FAN5_REG_MASK 0x03 + +#define LED_MODE_FANX_GREEN_MASK 0x02 +#define LED_MODE_FANX_RED_MASK 0x01 +#define LED_MODE_FANX_AMBER_MASK 0x03 +#define LED_MODE_FANX_OFF_MASK 0x00 + +enum led_type { + LED_TYPE_SYS, + LED_TYPE_PSU2, + LED_TYPE_PSU1, + LED_TYPE_FAN, + LED_TYPE_FAN1, + LED_TYPE_FAN2, + LED_TYPE_FAN3, + LED_TYPE_FAN4, + LED_TYPE_FAN5, +}; + +static const u8 led_reg[] = { + 0x30, /* system & reserved*/ + 0x31, /* fan & PSU1 & PSU2 */ + 0x32, /* FAN5 LED */ + 0x33, /* FAN1-4 LED */ +}; + + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_GREEN, + LED_MODE_AMBER, + LED_MODE_RED, + LED_MODE_GREEN_BLINK, + LED_MODE_AMBER_BLINK, + LED_MODE_RED_BLINK, + LED_MODE_GREEN_FLASHING, + LED_MODE_AMBER_FLASHING, + LED_MODE_RED_FLASHING, + LED_MODE_AUTO, + LED_MODE_UNKNOWN +}; + +struct led_type_mode { + enum led_type type; + int type_mask; + enum led_light_mode mode; + int mode_mask; +}; + +static struct led_type_mode led_type_mode_data[] = { +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_RED, LED_MODE_PSU1_RED_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK}, + +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_RED, LED_MODE_PSU2_RED_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK}, + +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_GREEN, LED_MODE_SYS_GREEN_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER, LED_MODE_SYS_AMBER_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_RED, LED_MODE_SYS_RED_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER_FLASHING, LED_MODE_SYS_AMBER_FLASHING_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_OFF, LED_MODE_SYS_OFF_MASK}, + +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_RED, LED_MODE_FAN_RED_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK}, + +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +}; + +struct fanx_info_s { + u8 cname; /* device name */ + enum led_type type; + u8 reg_id; /* map to led_reg & reg_val */ +}; + +static struct fanx_info_s fanx_info[] = { + {'1', LED_TYPE_FAN1, 3}, + {'2', LED_TYPE_FAN2, 3}, + {'3', LED_TYPE_FAN3, 3}, + {'4', LED_TYPE_FAN4, 3}, + {'5', LED_TYPE_FAN5, 2}, +}; + + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + + if (type != led_type_mode_data[i].type) + continue; + + if ((led_type_mode_data[i].type_mask & reg_val) == + led_type_mode_data[i].mode_mask) + { + return led_type_mode_data[i].mode; + } + } + + return 0; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + reg_val = led_type_mode_data[i].mode_mask | + (reg_val & (~led_type_mode_data[i].type_mask)); + break; + } + + return reg_val; +} + +static void cs6436_54p_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting cs6436_54p_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + u8 status; + cig_cpld_read_register(led_reg[i], &status); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs6436_54p_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + u8 reg, enum led_type type) +{ + u8 reg_val; + mutex_lock(&ledctl->update_lock); + + cig_cpld_read_register(reg, ®_val); + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + + cig_cpld_write_register(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs6436_54p_led_fanx_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (led_cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1); + return; + } + } +} + + +static enum led_brightness cs6436_54p_led_fanx_get(struct led_classdev *cdev) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]); + } + } + + return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[5]); +} + + +static void cs6436_54p_led_psu1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1); +} + +static enum led_brightness cs6436_54p_led_psu1_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]); +} + +static void cs6436_54p_led_psu2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2); +} + +static enum led_brightness cs6436_54p_led_psu2_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]); +} + +static void cs6436_54p_led_sys_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode,led_reg[0], LED_TYPE_SYS); +} + +static enum led_brightness cs6436_54p_led_sys_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_SYS, ledctl->reg_val[0]); +} + + +static enum led_brightness cs6436_54p_led_fan_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[1]); +} + +static void cs6436_54p_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_FAN); +} + + +static struct led_classdev cs6436_54p_leds[] = { + [LED_TYPE_SYS] = { + .name = "cs6436_54p_led::sys", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_sys_set, + .brightness_get = cs6436_54p_led_sys_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN] = { + .name = "cs6436_54p_led::fan", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fan_set, + .brightness_get = cs6436_54p_led_fan_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_PSU1] = { + .name = "cs6436_54p_led::psu1", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_psu1_set, + .brightness_get = cs6436_54p_led_psu1_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "cs6436_54p_led::psu2", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_psu2_set, + .brightness_get = cs6436_54p_led_psu2_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_FAN1] = { + .name = "cs6436_54p_led::fan1", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN2] = { + .name = "cs6436_54p_led::fan2", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN3] = { + .name = "cs6436_54p_led::fan3", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN4] = { + .name = "cs6436_54p_led::fan4", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN5] = { + .name = "cs6436_54p_led::fan5", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + } +}; + +static int cs6436_54p_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + led_classdev_suspend(&cs6436_54p_leds[i]); + } + + return 0; +} + +static int cs6436_54p_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + led_classdev_resume(&cs6436_54p_leds[i]); + } + + return 0; +} + +static int cs6436_54p_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + ret = led_classdev_register(&pdev->dev, &cs6436_54p_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(cs6436_54p_leds)) { + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&cs6436_54p_leds[i]); + } + } + + return ret; +} + +static int cs6436_54p_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + led_classdev_unregister(&cs6436_54p_leds[i]); + } + + return 0; +} + +static struct platform_driver cs6436_54p_led_driver = { + .probe = cs6436_54p_led_probe, + .remove = cs6436_54p_led_remove, + .suspend = cs6436_54p_led_suspend, + .resume = cs6436_54p_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int cs6436_54p_led_default(void) +{ + cig_cpld_write_register(0x30, 0x40);// system green led solid on +} + +static int __init cs6436_54p_led_init(void) +{ + int ret; + + ret = platform_driver_register(&cs6436_54p_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct cs6436_54p_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&cs6436_54p_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&cs6436_54p_led_driver); + kfree(ledctl); + goto exit; + } + + cs6436_54p_led_default(); + +exit: + return ret; +} + +static void __exit cs6436_54p_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&cs6436_54p_led_driver); + kfree(ledctl); +} + +module_init(cs6436_54p_led_init); +module_exit(cs6436_54p_led_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_led driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-psu.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-psu.c new file mode 100644 index 000000000000..e8fc896ea13a --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-psu.c @@ -0,0 +1,943 @@ +/* + * A hwmon driver for the CIG cs6436-54P Power Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" + + + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Address scanned */ +static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; + +/* This is additional data */ +struct cs6436_54p_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 v_in; + u16 v_out; + u16 i_in; + u16 i_out; + u16 p_in; + u16 p_out; + u16 temp_input[3]; + u8 temp_fault; + u8 fan_fault; + u16 fan_duty_cycle[2]; + u16 fan_speed[2]; + u8 mfr_id[8]; + u8 mfr_model[20]; + u8 mfr_serial[20]; + u8 psu_is_present; + u8 psu_is_good; + struct i2c_client *client; + struct bin_attribute *bin; /* eeprom data */ +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static int cs6436_54p_psu_read_byte(struct i2c_client *client, u8 reg); +static int cs6436_54p_psu_read_word(struct i2c_client *client, u8 reg); +static int cs6436_54p_psu_write_word(struct i2c_client *client, u8 reg, u16 value); +static int cs6436_54p_psu_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len); +static struct cs6436_54p_psu_data *cs6436_54p_psu_update_device(struct device *dev); +static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); + +enum cs6436_54p_psu_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_TEMP2_INPUT, + PSU_TEMP3_INPUT, + PSU_TEMP_FAULT, + PSU_TEMP_WARN, + PSU_FAN1_FAULT, + PSU_FAN1_WARN, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, + PSU_PRESENT, + PSU_P_GOOD, +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + + bool is_negative = valid_data >> (valid_bit - 1); + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); + struct cs6436_54p_psu_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + if (data->valid != 1) + { + return -ENODEV; + } + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + cs6436_54p_psu_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_TEMP2_INPUT: + value = data->temp_input[1]; + break; + case PSU_TEMP3_INPUT: + value = data->temp_input[2]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + + + return sprintf(buf, "%d\n", data->temp_fault >> 7); +} + +static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + if (data->valid != 1) + { + return -ENODEV; + } + + + return sprintf(buf, "%d\n", data->temp_fault >> 6); +} +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + if (data->valid != 1) + { + return -ENODEV; + } + + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + u8 *ptr = NULL; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_MFR_ID: + ptr = data->mfr_id + 1; + break; + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} + + +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + u8 *ptr = NULL; + + u8 status = 0; + + if (attr->index == PSU_PRESENT) { + status = data->psu_is_present; + } + else { /* PSU_POWER_GOOD */ + if (!data->valid) { + return -ENODEV; + } + + status = data->psu_is_good; + } + + return sprintf(buf, "%d\n", status); +} + + +static int cs6436_54p_psu_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cs6436_54p_psu_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int cs6436_54p_psu_write_word(struct i2c_client *client, u8 reg, \ + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + +static int cs6436_54p_psu_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, + data); + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; +abort: + return result; + +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + + + +#define EEPROM_NAME "psu_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +/* Platform dependent --- */ +static ssize_t psu_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; + +} + + +static ssize_t psu_page_write(struct i2c_client *client,const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_write(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; +} + + + +static ssize_t psu_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_54p_psu_data *data; + ssize_t retval = 0; + struct i2c_client *client; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + + mutex_lock(&data->update_lock); + retval = psu_page_write(client, buf, off, count); + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t psu_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + +abort: + return status; +} + + + +static ssize_t psu_page_read(struct i2c_client *client,char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + printk("Count = 0, return"); + return count; + } + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_read(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; + +} + + +static ssize_t psu_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_54p_psu_data *data; + struct i2c_client *client; + ssize_t retval = 0; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + mutex_lock(&data->update_lock); + retval = psu_page_read(client, buf, off, count); + mutex_unlock(&data->update_lock); + + return retval; +} + + + +static int psu_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = psu_bin_read; + eeprom->write = psu_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + + +static int psu_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + + +static int psu_i2c_check_functionality(struct i2c_client *client) +{ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK); +} + + + +static int psu_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + int status; + + struct cs6436_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + data->bin = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL); + if (!data->bin) { + status = -ENOMEM; + goto eeprom_bin_error; + } + + /* init eeprom */ + status = psu_sysfs_eeprom_init(&client->dev.kobj, data->bin); + if (status) { + status = -ENOMEM; + goto sys_init_error; + } + + dev_info(&client->dev, "psu eeprom '%s'\n", client->name); + + return 0; + + sys_init_error: + kfree(data->bin); + + eeprom_bin_error: + kfree(data); + + exit: + return status; +} + + + + +static struct cs6436_54p_psu_data *cs6436_54p_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cs6436_54p_psu_data *data = i2c_get_clientdata(client); + + + mutex_lock(&data->update_lock); + + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}, + {0x7d, &data->temp_fault}, + }; + struct reg_data_word regs_word[] = { + {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x90, &(data->fan_speed[0])}, + }; + data->valid = 1; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cs6436_54p_psu_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + data->valid = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = cs6436_54p_psu_read_word(client, + regs_word[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + data->valid = 0; + } else { + *(regs_word[i].value) = status; + } + } + + command = 0x99; /* PSU mfr_id */ + status = cs6436_54p_psu_read_block(client, command, + data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); + data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_id, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9a; /* PSU mfr_model */ + status = cs6436_54p_psu_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_model, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9e; /* PSU mfr_serial */ + status = cs6436_54p_psu_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_serial, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + data->psu_is_present = strlen(data->mfr_id) > 1 ? 1:0; + if(data->psu_is_present) + { + data->psu_is_good = ((data->fan_fault) || (data->temp_fault))? 0:1; + } + else + { + data->valid = 0; + data->psu_is_good = 0; + } + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, for_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, for_status, NULL, PSU_P_GOOD); + + + +static struct attribute *cs6436_54p_psu_attributes[] = { + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_temp2_input.dev_attr.attr, + &sensor_dev_attr_psu_temp3_input.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_temp_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static const struct attribute_group cs6436_54p_psu_group = { + .attrs = cs6436_54p_psu_attributes, +}; + + +static int psu_register_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + + struct cs6436_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cs6436_54p_psu_group); + if (status) + goto exit_sysfs_create_group; + + cs6436_54p_sysfs_add_client(client); + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + /* init eeprom */ + + return 0; + + exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &cs6436_54p_psu_group); + exit_sysfs_create_group: + kfree(data); + exit: + return status; + +} + + +static int cs6436_54p_psu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + status = psu_eeprom_probe(client, id); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + status = psu_register_probe(client, id); + } + return status; +} + +static int cs6436_54p_psu_remove(struct i2c_client *client) +{ + cs6436_54p_sysfs_remove_client(client); + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + struct cs6436_54p_psu_data *data; + data = i2c_get_clientdata(client); + psu_sysfs_eeprom_cleanup(&client->dev.kobj,data->bin); + kfree(data); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + struct cs6436_54p_psu_data *data; + data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cs6436_54p_psu_group); + kfree(data); + } + + return 0; +} + +enum psu_index +{ + cs6436_54p_psu1, + cs6436_54p_psu2 +}; + +static const struct i2c_device_id cs6436_54p_psu_id[] = { + { "cs6436_54p_psu1", cs6436_54p_psu1 }, + { "cs6436_54p_psu2", cs6436_54p_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cs6436_54p_psu_id); + +static struct i2c_driver cs6436_54p_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "cs6436_54p_psu", + }, + .probe = cs6436_54p_psu_probe, + .remove = cs6436_54p_psu_remove, + .id_table = cs6436_54p_psu_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs6436_54p_psu_driver); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sfp.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sfp.c new file mode 100644 index 000000000000..5d02bd849a5f --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sfp.c @@ -0,0 +1,1713 @@ +/* + * A hwmon driver for the CIG cs6436-54P SFP Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" + +#define DRIVER_NAME "cs6436_54p_sfp" /* Platform dependent */ + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 /* Platform dependent */ +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) +#define SFP_EEPROM_A2_I2C_ADDR (0xA2 >> 1) + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 +#define SFF8472_10G_BASE_MASK 0xF0 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 +#define QSFP_RESET_ADDR 0x1b +#define QSFP_INTER_ADDR 0x1a +#define QSFP_LPMODE_ADDR 0x1c + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);; +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL, + QSFPRESET, + QSFPINT, + QSFPLPMODE +}; + +/* SFP/QSFP common attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_port_type, S_IRUGO, show_port_type, NULL, PORT_TYPE); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT); + +/* QSFP attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, qsfp_reset_read, qsfp_reset_write, QSFPRESET); +static SENSOR_DEVICE_ATTR(sfp_inter, S_IRUGO, qsfp_inter_read, NULL, QSFPINT); +static SENSOR_DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, qsfp_lpmode_read, qsfp_lpmode_write, QSFPLPMODE); +static struct attribute *qsfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + &sensor_dev_attr_sfp_reset.dev_attr.attr, + &sensor_dev_attr_sfp_inter.dev_attr.attr, + &sensor_dev_attr_sfp_lpmode.dev_attr.attr, + NULL +}; + +/* SFP msa attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_ddm_implemented, S_IRUGO, sfp_show_ddm_implemented, NULL, DDM_IMPLEMENTED); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS_ALL); +static struct attribute *sfp_msa_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_ddm_implemented.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + NULL +}; + +/* SFP ddm attributes for sysfs */ +static struct attribute *sfp_ddm_attributes[] = { + NULL +}; + +/* Platform dependent +++ */ +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { +cs6436_54p_sfp1, cs6436_54p_sfp2, cs6436_54p_sfp3, cs6436_54p_sfp4, +cs6436_54p_sfp5, cs6436_54p_sfp6, cs6436_54p_sfp7, cs6436_54p_sfp8, +cs6436_54p_sfp9, cs6436_54p_sfp10, cs6436_54p_sfp11, cs6436_54p_sfp12, +cs6436_54p_sfp13, cs6436_54p_sfp14, cs6436_54p_sfp15, cs6436_54p_sfp16, +cs6436_54p_sfp17, cs6436_54p_sfp18, cs6436_54p_sfp19, cs6436_54p_sfp20, +cs6436_54p_sfp21, cs6436_54p_sfp22, cs6436_54p_sfp23, cs6436_54p_sfp24, +cs6436_54p_sfp25, cs6436_54p_sfp26, cs6436_54p_sfp27, cs6436_54p_sfp28, +cs6436_54p_sfp29, cs6436_54p_sfp30, cs6436_54p_sfp31, cs6436_54p_sfp32, +cs6436_54p_sfp33, cs6436_54p_sfp34, cs6436_54p_sfp35, cs6436_54p_sfp36, +cs6436_54p_sfp37, cs6436_54p_sfp38, cs6436_54p_sfp39, cs6436_54p_sfp40, +cs6436_54p_sfp41, cs6436_54p_sfp42, cs6436_54p_sfp43, cs6436_54p_sfp44, +cs6436_54p_sfp45, cs6436_54p_sfp46, cs6436_54p_sfp47, cs6436_54p_sfp48, +cs6436_54p_sfp49, cs6436_54p_sfp50, cs6436_54p_sfp51, cs6436_54p_sfp52, +cs6436_54p_sfp53, cs6436_54p_sfp54, cs6436_54p_sfp55, cs6436_54p_sfp56 +}; + +#define I2C_DEV_ID(x) { #x, x} + +static const struct i2c_device_id sfp_device_id[] = { +I2C_DEV_ID(cs6436_54p_sfp1), +I2C_DEV_ID(cs6436_54p_sfp2), +I2C_DEV_ID(cs6436_54p_sfp3), +I2C_DEV_ID(cs6436_54p_sfp4), +I2C_DEV_ID(cs6436_54p_sfp5), +I2C_DEV_ID(cs6436_54p_sfp6), +I2C_DEV_ID(cs6436_54p_sfp7), +I2C_DEV_ID(cs6436_54p_sfp8), +I2C_DEV_ID(cs6436_54p_sfp9), +I2C_DEV_ID(cs6436_54p_sfp10), +I2C_DEV_ID(cs6436_54p_sfp11), +I2C_DEV_ID(cs6436_54p_sfp12), +I2C_DEV_ID(cs6436_54p_sfp13), +I2C_DEV_ID(cs6436_54p_sfp14), +I2C_DEV_ID(cs6436_54p_sfp15), +I2C_DEV_ID(cs6436_54p_sfp16), +I2C_DEV_ID(cs6436_54p_sfp17), +I2C_DEV_ID(cs6436_54p_sfp18), +I2C_DEV_ID(cs6436_54p_sfp19), +I2C_DEV_ID(cs6436_54p_sfp20), +I2C_DEV_ID(cs6436_54p_sfp21), +I2C_DEV_ID(cs6436_54p_sfp22), +I2C_DEV_ID(cs6436_54p_sfp23), +I2C_DEV_ID(cs6436_54p_sfp24), +I2C_DEV_ID(cs6436_54p_sfp25), +I2C_DEV_ID(cs6436_54p_sfp26), +I2C_DEV_ID(cs6436_54p_sfp27), +I2C_DEV_ID(cs6436_54p_sfp28), +I2C_DEV_ID(cs6436_54p_sfp29), +I2C_DEV_ID(cs6436_54p_sfp30), +I2C_DEV_ID(cs6436_54p_sfp31), +I2C_DEV_ID(cs6436_54p_sfp32), +I2C_DEV_ID(cs6436_54p_sfp33), +I2C_DEV_ID(cs6436_54p_sfp34), +I2C_DEV_ID(cs6436_54p_sfp35), +I2C_DEV_ID(cs6436_54p_sfp36), +I2C_DEV_ID(cs6436_54p_sfp37), +I2C_DEV_ID(cs6436_54p_sfp38), +I2C_DEV_ID(cs6436_54p_sfp39), +I2C_DEV_ID(cs6436_54p_sfp40), +I2C_DEV_ID(cs6436_54p_sfp41), +I2C_DEV_ID(cs6436_54p_sfp42), +I2C_DEV_ID(cs6436_54p_sfp43), +I2C_DEV_ID(cs6436_54p_sfp44), +I2C_DEV_ID(cs6436_54p_sfp45), +I2C_DEV_ID(cs6436_54p_sfp46), +I2C_DEV_ID(cs6436_54p_sfp47), +I2C_DEV_ID(cs6436_54p_sfp48), +I2C_DEV_ID(cs6436_54p_sfp49), +I2C_DEV_ID(cs6436_54p_sfp50), +I2C_DEV_ID(cs6436_54p_sfp51), +I2C_DEV_ID(cs6436_54p_sfp52), +I2C_DEV_ID(cs6436_54p_sfp53), +I2C_DEV_ID(cs6436_54p_sfp54), +I2C_DEV_ID(cs6436_54p_sfp55), +I2C_DEV_ID(cs6436_54p_sfp56), +{ /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28 +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[6]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss + 3 => device id + 4 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 5 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +}; + +struct sfp_ddm_data { + struct eeprom_data eeprom; +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct sfp_ddm_data *ddm; + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + + + +static int cig_cpld_write_sfp_register(u8 sfp_reg_addr, u8 sfp_write_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, sfp_write_reg_data); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x02); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1 | 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,sfp_read_reg_data); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + + + + +/* Platform dependent +++ */ +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + int i = 0, j = 0, status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + data->present = 0; + + udelay(6000); + + /* Read present status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 1 + i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->present |= (u64)cpld_reg_data << (i*8); + + DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); + } + + /* Read present status of port 49-56(QSFP port) */ + cpld_reg_addr = 25; + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + else { + data->present |= (u64)cpld_reg_data << 48; + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0, j = 0; + int status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + + if (time_before(jiffies, data->msa->last_updated + HZ + HZ / 2) && data->msa->valid) { + return data; + } + + DEBUG_PRINT("Starting cs6436_54p sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->msa->valid = 0; + memset(data->msa->status, 0, sizeof(data->msa->status)); + + udelay(6000); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 13+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[0] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); + } + + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 19+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[1] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); + } + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 7+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[2] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); + } + + data->msa->valid = 1; + data->msa->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0,cpld_reg_bit = 0,cpld_reg_val = 0; + long disable; + int error; + + if (data->driver_type == DRIVER_TYPE_QSFP) { + return qsfp_set_tx_disable(dev, da, buf, count); + } + + error = kstrtol(buf, 10, &disable); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + + if(data->port <= 48) { + cpld_reg_addr = 19 + data->port / 8; + cpld_reg_bit = 1 << ((data->port) % 8); + } + + /* Read current status */ + error = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + /* Update tx_disable status */ + if (disable) { + data->msa->status[1] |= BIT_INDEX(data->port); + cpld_reg_data |= cpld_reg_bit; + } + else { + data->msa->status[1] &= ~ BIT_INDEX(data->port); + cpld_reg_data &= ~cpld_reg_bit; + } + + error = cig_cpld_write_sfp_register(cpld_reg_addr,cpld_reg_data); + + mutex_unlock(&data->update_lock); + return count; +} +/* Platform dependent --- */ + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = sfp_update_present(client); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + return !(data->present & BIT_INDEX(data->port)); /* Platform dependent */ +} + +/* Platform dependent +++ */ +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if (PRESENT_ALL == attr->index) { + int i; + u8 values[7] = {0}; + struct sfp_port_data *data = sfp_update_present(client); + + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = ~(u8)(data->present >> (i * 8)); + } + + /* Return values 1 -> 56 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5], + values[6]); + } + else { + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + /* PRESENT */ + return sprintf(buf, "%d\n", present); + } +} +/* Platform dependent --- */ + +static struct sfp_port_data *sfp_update_port_type(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 buf = 0; + int status; + + mutex_lock(&data->update_lock); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + if (buf != SFF8024_DEVICE_ID_SFP) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + status = sfp_eeprom_read(client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); + data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; + break; + } + case DRIVER_TYPE_QSFP: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); + switch (buf) { + case SFF8024_DEVICE_ID_QSFP: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; + break; + case SFF8024_DEVICE_ID_QSFP_PLUS: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + case SFF8024_DEVICE_ID_QSFP28: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + default: + data->port_type = buf; + break; + } + + break; + } + default: + break; + } + + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + if (!present) { + /* port is not present */ + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_type(dev); + return sprintf(buf, "%d\n", data->port_type); +} + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + DEBUG_PRINT(""); + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + DEBUG_PRINT("Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + DEBUG_PRINT(""); + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + } + msleep(200); + DEBUG_PRINT(""); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + DEBUG_PRINT(""); + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + +exit: + DEBUG_PRINT(""); + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_INTER_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("inter read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("reset read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_RESET_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + + +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("lpmode read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_LPMODE_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + int present; + u8 val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT(""); + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + DEBUG_PRINT(""); + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + DEBUG_PRINT(""); + data = qsfp_update_tx_rx_status(dev); + DEBUG_PRINT(""); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + DEBUG_PRINT(""); + switch (attr->index) { + case TX_FAULT: + val = !!(data->qsfp->status[2] & 0xF); + break; + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)); + break; + case TX_DISABLE: + val = data->qsfp->status[1] & 0xF; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)); + break; + case RX_LOS: + val = !!(data->qsfp->status[0] & 0xF); + break; + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)); + break; + default: + break; + } + + DEBUG_PRINT(""); + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (!status) { + /* port is not present */ + return -ENXIO; + } + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + mutex_lock(&data->update_lock); + + if (attr->index == TX_DISABLE) { + data->qsfp->status[1] = disable & 0xF; + } + else {/* TX_DISABLE1 ~ TX_DISABLE4*/ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + if (unlikely(status < 0)) { + count = status; + } + + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + char ddm; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (status == 0) { + /* port is not present */ + return -ENODEV; + } + + status = sfp_eeprom_read(client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); + if (unlikely(status < 0)) { + return status; + } + + return sprintf(buf, "%d\n", !!(ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK)); +} + +/* Platform dependent +++ */ +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("driver type = (%d)", data->driver_type); + if (data->driver_type == DRIVER_TYPE_QSFP) { + DEBUG_PRINT(""); + return qsfp_show_tx_rx_status(dev, da, buf); + } + + DEBUG_PRINT(""); + data = sfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + if(attr->index == RX_LOS_ALL) { + int i = 0; + u8 values[6] = {0}; + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = (u8)(data->msa->status[2] >> (i * 8)); + } + + /** Return values 1 -> 48 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5]); + } + + switch (attr->index) { + case TX_FAULT: + index = 0; + break; + case TX_DISABLE: + index = 1; + break; + case RX_LOS: + index = 2; + break; + default: + break; + } + + val = !!(data->msa->status[index] & BIT_INDEX(data->port)); + return sprintf(buf, "%d\n", val); +} +/* Platform dependent --- */ +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, command, *data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return 1; +#endif + + +} + +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_write(data, buf, off, count); +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + + //result = data_len; + +abort: + return status; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, command); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status); + goto abort; + } + + *data = (u8)status; + status = 1; + +abort: + return status; +#endif +} + +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_read(data, buf, off, count); +} + +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + cs6436_54p_sysfs_add_client(client); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group sfp_ddm_group = { + .attrs = sfp_ddm_attributes, +}; + +static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_ddm_data **data) +{ + int status; + struct sfp_ddm_data *ddm; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); + if (!ddm) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = ddm; + dev_info(&client->dev, "sfp ddm '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); +exit_free: + kfree(ddm); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); + if (status) { + goto exit_remove; + } + + /* Bring QSFPs out of reset */ + //cig_lpc_write(0x62, 0x15, 0x3F); + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +/* Platform dependent +++ */ +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct sfp_port_data *data = NULL; + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + if (dev_id->driver_data >= cs6436_54p_sfp1 && dev_id->driver_data <= cs6436_54p_sfp48) { + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_MSA; + return sfp_msa_probe(client, dev_id, &data->msa); + } + else if (client->addr == SFP_EEPROM_A2_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_DDM; + return sfp_ddm_probe(client, dev_id, &data->ddm); + } + } + else { /* cs6436_54p_sfp49 ~ cs6436_54p_sfp56 */ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_QSFP; + return qsfp_probe(client, dev_id, &data->qsfp); + } + } + + return -ENODEV; +} +/* Platform dependent --- */ + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + cs6436_54p_sysfs_remove_client(client); + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_SFP_DDM: + return sfp_ddm_remove(client, data->ddm); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + + return 0; +} + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static struct i2c_driver cs6436_54p_sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs6436_54p_sfp_driver); + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_sfp driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sysfs.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sysfs.c new file mode 100644 index 000000000000..1383fcfd40f3 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sysfs.c @@ -0,0 +1,335 @@ +/* + * A hwmon driver for the CIG cs6436-54P sysfs Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c-algo-lpc.h" + + +static LIST_HEAD(sysfs_client_list); +static struct mutex list_lock; + +struct sysfs_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define DEVICE_NAME "cigfs" +static int dev_major; +static struct class *dev_class; +static struct cdev *dev_cdev; +static struct device *dev_device; +static struct class *psu_class; +static struct class *sfp_class; + + +void cs6436_54p_sysfs_add_client(struct i2c_client *client) +{ + struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &sysfs_client_list); + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_54p_sysfs_add_client); + +void cs6436_54p_sysfs_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (IS_ERR(sysfs_node)) + { + break; + } + if (sysfs_node->client == client) { + found = 1; + break; + } + } + if (found) { + list_del(list_node); + kfree(sysfs_node); + } + + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_54p_sysfs_remove_client); + +struct class * cs6436_54p_sysfs_create_symclass(char *cls_name) +{ + int rc = 0; + struct class *my_class; +/**************************************************************************************/ + my_class = class_create(THIS_MODULE,cls_name); + if (IS_ERR(my_class)) { + pr_err("failed to create my class\n"); + } + return my_class; + +/**************************************************************************************/ +} + +void cs6436_54p_sysfs_delete_symclass(struct class *my_class) +{ +/**************************************************************************************/ + + if (IS_ERR(my_class)) { + pr_err("Pointer is invaild\n"); + } + class_destroy(my_class); + +/**************************************************************************************/ +} + + + + + +int cs6436_54p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name); + if(rc) + { + pr_err("failed to create symlink %d\n",rc); + } + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +int cs6436_54p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + sysfs_remove_link(&my_class->p->subsys.kobj,device_name); + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +static int cs6436_54p_sysfs_open(struct inode *inode, struct file *file) +{ + return 0; +} + + + +static ssize_t cs6436_54p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) +{ + char str[10],name[18],port[8]; + int ret; + int i; + memset(str, 0, sizeof(str)); + ret = copy_from_user(str, buf, count); + if (ret) + { + printk(KERN_ERR "copy_from_user fail\n"); + return -EINVAL; + } + + if(!strncmp(str,"start",5)) + { + psu_class = cs6436_54p_sysfs_create_symclass("psu"); + cs6436_54p_sysfs_create_symlink(psu_class,"cs6436_54p_psu1","psu1"); + cs6436_54p_sysfs_create_symlink(psu_class,"cs6436_54p_psu2","psu2"); + sfp_class = cs6436_54p_sysfs_create_symclass("swps"); + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_54p_sysfs_create_symlink(sfp_class,name,port); + } + } + else if(!strncmp(str,"stop",4)) + { + cs6436_54p_sysfs_delete_symlink(psu_class,"cs6436_54p_psu1","psu1"); + cs6436_54p_sysfs_delete_symlink(psu_class,"cs6436_54p_psu2","psu2"); + cs6436_54p_sysfs_delete_symclass(psu_class); + + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_54p_sysfs_delete_symlink(sfp_class,name,port); + } + cs6436_54p_sysfs_delete_symclass(sfp_class); + } + return count; +} + + +static struct file_operations cs6436_54p_sysfs_fops = { + .owner = THIS_MODULE, + .open = cs6436_54p_sysfs_open, + .write = cs6436_54p_sysfs_write, +}; + + +static int __init cs6436_54p_sysfs_init(void) +{ + int result = 0; + int err = 0; + dev_t dev = MKDEV(dev_major, 0); + + if (dev_major) + result = register_chrdev_region(dev, 1, DEVICE_NAME); + else { + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + dev_major = MAJOR(dev); + } + if (result < 0) + { + printk("unable to get major %d\n", dev_major); + err= -EINVAL; + } + printk("get major is %d\n", dev_major); + if (dev_major == 0) + dev_major = result; + + dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL); + if(IS_ERR(dev_cdev)) { + err= -ENOMEM; + } + + cdev_init(dev_cdev, &cs6436_54p_sysfs_fops); + dev_cdev->owner = THIS_MODULE; + dev_cdev->ops = &cs6436_54p_sysfs_fops; + err = cdev_add(dev_cdev, dev, 1); + if (err) + { + printk("error %d add fpga ", err); + goto err_malloc; + } + + dev_class = class_create(THIS_MODULE, DEVICE_NAME); + if (IS_ERR(dev_class)) + { + printk("Err:failed in creating class.\n"); + goto err_cdev_add; + } + + dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME); + if (IS_ERR(dev_device)) + { + printk("Err:failed in creating device.\n"); + goto err_class_crt; + } + + mutex_init(&list_lock); + + return err; + + err_class_crt: + cdev_del(dev_cdev); + err_cdev_add: + kfree(dev_cdev); + err_malloc: + unregister_chrdev_region(MKDEV(dev_major,0), 1); + + return err; + +} + +static void __exit cs6436_54p_sysfs_exit(void) +{ + cdev_del(dev_cdev); + printk("cdev_del ok\n"); + device_destroy(dev_class, MKDEV(dev_major, 0)); + + class_destroy(dev_class); + + if(dev_cdev != NULL) + kfree(dev_cdev); + + unregister_chrdev_region(MKDEV(dev_major, 0), 1); + printk("cs6436_54p_sysfs_exit...\r\n"); +} + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436-54p-sysfs driver"); +MODULE_LICENSE("GPL"); + +module_init(cs6436_54p_sysfs_init); +module_exit(cs6436_54p_sysfs_exit); + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-init.service b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-init.service new file mode 100644 index 000000000000..ad18c2c2703a --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Cig CS6436-54P Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/cig_cs6436_util.py install +ExecStop=/usr/local/bin/cig_cs6436_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-misc.service b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-misc.service new file mode 100644 index 000000000000..33f99935cd95 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-misc.service @@ -0,0 +1,15 @@ +[Unit] +Description=Cig CS6436-54P Platform miscellaneous service +After=cs6436-platform-init.service +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/cig_cs6436_misc.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py new file mode 100755 index 000000000000..05ee2c6e36ac --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='cs6436-54p', + version='1.0.0', + description='Module to initialize Cig CS6436-54P platforms', + + packages=['cs6436-54p'], + package_dir={'cs6436-54p': 'cs6436-54p/classes'}, + ) diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py new file mode 100755 index 000000000000..c186676cbf3f --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py @@ -0,0 +1,574 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os +import commands +import sys, getopt +import logging +import re +import time +import datetime +from collections import namedtuple +from threading import Thread + +DEBUG = False +i2c_prefix = '/sys/bus/i2c/devices/' +leds_prefix = '/sys/devices/platform/cs6436_54p_led/leds/' +fans_prefix = '/sys/devices/platform/cs6436_54p_fan/' +fansdir_prefix = fans_prefix + 'fan{}_direction' + +ageing_controlfile = '/etc/sonic/agcontrol' +AGFlag = 0 + + +platform_misc_log = '/var/log/platform_misc.log' +misclogger = logging.getLogger('platform_misc') +misclogger.setLevel(logging.INFO) +miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s') + +if not os.path.isfile(platform_misc_log): + try: + os.mknod(platform_misc_log) + except: + print 'Failed to creat platform_misc.log' + +fileHandler = logging.FileHandler(platform_misc_log) +fileHandler.setLevel(logging.INFO) +fileHandler.setFormatter(miscformatter) +misclogger.addHandler(fileHandler) + + +starttime = datetime.datetime.now() +IsGetlswt = 0 +coretemp_prefix = '/sys/class/hwmon/hwmon1/' +coretemp_ps = [] +psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present' +psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present' +psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom' +psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom' +psu1led_d = leds_prefix + 'cs6436_54p_led::psu1/brightness' +psu2led_d = leds_prefix + 'cs6436_54p_led::psu2/brightness' +cs6436_ledpath = {'fan':leds_prefix + 'cs6436_54p_led::fan/brightness', + 'fan1':leds_prefix + 'cs6436_54p_led::fan1/brightness', + 'fan2':leds_prefix + 'cs6436_54p_led::fan2/brightness', + 'fan3':leds_prefix + 'cs6436_54p_led::fan3/brightness', + 'fan4':leds_prefix + 'cs6436_54p_led::fan4/brightness', + 'fan5':leds_prefix + 'cs6436_54p_led::fan5/brightness', + 'psu1':leds_prefix + 'cs6436_54p_led::psu1/brightness', + 'psu2':leds_prefix + 'cs6436_54p_led::psu2/brightness', + 'sys':leds_prefix + 'cs6436_54p_led::sys/brightness'} + + +def system_read_filestr(node): + with open(node, 'r') as f: + try: + str = f.read() + except IOError as e: + misclogger.error('Failed to get node, str={}'.format(node)) + return "0" + return str + + +def system_bright_leds(dev, colour): + global AGFlag + + if AGFlag == 1: + return + + cmd = 'echo {} > {}'.format(colour, dev) + log_os_system(cmd, 1) + return + +''' +1: front in tail out +0: front out tail in +''' +def system_getpsu_direction(dev): + try: + with open(dev) as f: + f.seek(0x30) + str = f.read(2) + except IOError as e: + misclogger.error('Failed to get psu eep') + return 1 + if str == 'AA': ## front in tail out + return 1 + elif str == 'RA':## tail in front out + return 0 + else: + misclogger.error('Failed to get psu eep, str={}'.format(str)) + return -1 + + +def system_get_cputype(): + cmdretfd = os.popen("lscpu | grep 'Model name'") + retstring = cmdretfd.read() + endindex = retstring.find('@') - 1 + startindex = retstring[:endindex].rfind(' ') + 1 + cputype = retstring[startindex:endindex] + + return cputype + + +def system_init_coretemppath(): + global coretemp_ps + + cmdstr = "ls {} | grep 'input'".format(coretemp_prefix) + cmdretfd = os.popen(cmdstr) + + coretemppss = cmdretfd.read().splitlines() + if len(coretemppss) < 3: + cputype = system_get_cputype() + misclogger.error('Failed to init core temperature path.' + ' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps))) + return 1 + + for i in range(0,3): + coretemp_ps.append(coretemp_prefix + coretemppss[i]) + + print coretemp_ps + + return 0 + + +class cs6436_fanattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.rear = 0 + self.rear_p = '' + self.front = 0 + self.front_p = '' + self.fault = 0 + self.fault_p = '' + self.status = 0 + self.setpath() + self.updatedevice() + + return + + def setpath(self): + self.direction_p = fans_prefix + '{}_direction'.format(self.name) + self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name) + self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name) + self.fault_p = fans_prefix + '{}_fault'.format(self.name) + + return + + def updatedevice(self): + self.direction = int(system_read_filestr(self.direction_p)) + self.rear = int(system_read_filestr(self.rear_p)) + self.front = int(system_read_filestr(self.front_p)) + self.fault = int(system_read_filestr(self.fault_p)) + + return + + def checkspeedrpm(self, speedrpm): + frontrpmexp = speedrpm * 21000 / 100 + rearrpmexp = speedrpm * 19000 / 100 + deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp) + deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp) + + if deviationfront < 0.3 and deviationrear < 0.3: + return 0 + else: + misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear)) + return 1 + + def checkstatus(self, speedrpm, totaldirct): + speedstatus = self.checkspeedrpm(speedrpm) + if self.direction != totaldirct: + self.status = 1 + misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction)) + elif speedstatus != 0: + self.status = 1 + elif self.fault != 0: + misclogger.error(':{} fault.'.format(self.name)) + self.status = 1 + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_fanattrnodes = [] + + +class cs6436_psuattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.present = 0 + self.present_p = '' + self.status = 0 + + self.setpath() + self.updatepresent() + self.updatedirection() + + return + + def setpath(self): + if self.name == 'psu1': + self.present_p = psu1_p + self.direction_p = psu1_d + if self.name == 'psu2': + self.present_p = psu2_p + self.direction_p = psu2_d + + return + + def updatepresent(self): + self.present = int(system_read_filestr(self.present_p)) + + return + + def updatedirection(self): + if self.present == 1: + self.direction = system_getpsu_direction(self.direction_p) + else: + self.direction = 2 + + return + + def checkstatus(self, totaldirct): + if self.present != 1: + self.status = 1 + misclogger.error(':{} not present.'.format(self.name)) + elif self.direction == 2: + self.status = 0 + misclogger.info(':{} direction need to be update.'.format(self.name)) + elif self.direction != totaldirct: + self.status = 1 + misclogger.info(':{} direction is wrong.'.format(self.name)) + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_psuattrnodes = [] + + + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0) + ret3, log = log_os_system("ls "+leds_prefix+"cs6436_54p_led*", 0) + return not(ret1 or ret2 or ret3) + + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + + +def system_get_coretemp(): + temp1 = system_read_filestr(coretemp_ps[0]).strip() + temp2 = system_read_filestr(coretemp_ps[1]).strip() + temp3 = system_read_filestr(coretemp_ps[2]).strip() + + return int(temp1), int(temp2), int(temp3) + +def system_get_boardtemp(): + for i in range(0,16): + temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i + if os.access(temp1path, os.F_OK): + break + for i in range(0,16): + temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i + if os.access(temp2path, os.F_OK): + break + temp1 = system_read_filestr(temp1path).strip() + temp2 = system_read_filestr(temp2path).strip() + + return int(temp1), int(temp2) + + +def system_get_lswtemp(): + global IsGetlswt + global starttime + if IsGetlswt == 0: + now = datetime.datetime.now() + misclogger.info("time wait.") + misclogger.info("start = {}, now = {}.".format(starttime, now)) + if (now - starttime).seconds > 150: + misclogger.info("time = ".format((now - starttime).seconds)) + IsGetlswt = 1 + + return 25 + +# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) +# if chp.poll() == None: +# misclogger.info("No subp.") +# chp.kill() +# +# return 25 + +# retstring = chp.stdout.read() +# chp.kill() +# if 'Up' not in retstring: +# misclogger.info("lsw not up.") +# +# return 25 + + status, output = log_os_system('npx_diag swc show temperature', 1) + if status: + misclogger.error('failed to show lsw temperature') + + return 25 + + output = output.strip() + if output.find("it 0, temperature ") > 0: + startindex = output.find('temperature') + len('temperature') + 1 + endindex = output[startindex:].find(" ") + endindex = startindex + endindex + temp = output[startindex:endindex] + b = temp.find('.') + if b > 0: + temp=temp[:b] + temp = int(temp) + else: + misclogger.error("Failed to get temperature.") + temp = 0 + + return int(temp) + +def system_monitor_temperature(): + + ctemp1, ctemp2, ctemp3 = system_get_coretemp() + btemp1, btemp2 = system_get_boardtemp() + ltemp = system_get_lswtemp() + fan_speed_str = system_cs6436_getfanexspeed() + fan_speed = int(fan_speed_str) + policy = 'stay' + pos = 0 + #speed c1 c2 c3 b1 b2 lsw + fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95], + [40, 44000, 44000, 44000, 44000, 39000, 96], + [50, 49000, 49000, 49000, 47000, 44000, 91], + [60, 52000, 52000, 52000, 51500, 47500, 92], + [70, 53000, 53000, 53000, 52000, 49000, 93], + [100,999999,999999,999999,999999,999999,999]) + + fan_policy_down=([30, 0, 0, 0, 0, 0, 0], + [40, 34000, 34000, 34000, 34000, 30000, 80], + [50, 38000, 38000, 38000, 37000, 33000, 81], + [60, 44000, 44000, 44000, 43000, 39000, 84], + [70, 44000, 44000, 44000, 43000, 40000, 84], + [100, 48000, 48000, 48000, 46000, 42000, 85],) + + for policytable in fan_policy_up: + if fan_speed <= policytable[0]: + break + pos = pos + 1 + fan_speed = policytable[0] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'stay' + policytable = fan_policy_down[pos] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'down' + else: + policy = 'up' + + if policy == 'up': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos + 1][0] + misclogger.info("fan policy: up. speedexp = {}".format(fan_speed)) + + if policy == 'stay': + fan_speed = fan_policy_down[pos] + return + + if policy == 'down': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos - 1][0] + misclogger.info("fan policy: down.speedexp = {}".format(fan_speed)) + + cmd = "echo {} > /sys/devices/platform/cs6436_54p_fan/fan_duty_cycle_percentage".format(fan_speed) + status, output = log_os_system(cmd, 1) + if status: + misclogger.error("set fan speed fault") + + return + + +def system_cs6436_setfanexspeed(num): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + numstr = str(num) + with open(fanspeednode, 'w') as f: + f.write(numstr) + + +def system_cs6436_getfanexspeed(): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + fanspeedstr = system_read_filestr(fanspeednode) + fanspeedexp = int(fanspeedstr) + + return fanspeedexp + + +def system_cs6436_getdirection(): + global cs6436_fanattrnodes + direction = 0 + + for fan in cs6436_fanattrnodes: + direction = direction + fan.direction + + if direction > 2: + direction = 1 + else: + direction = 0 + + return direction + + +def system_check_psusdirection(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatedirection() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_psuspresent(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatepresent() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_fansstate(): + global cs6436_fanattrnodes + global cs6436_ledpath + cs6436totaldirct = system_cs6436_getdirection() + fanstatus = 0 + fanexspeed = 0 + + fanexspeed = system_cs6436_getfanexspeed() + + for fan in cs6436_fanattrnodes: + fan.updatedevice() + fan.checkstatus(fanexspeed, cs6436totaldirct) + fanstatus = fanstatus + fan.status + + if fanstatus > 0: + misclogger.error(':fan error.set fans speed 100.') + system_cs6436_setfanexspeed(100) + system_bright_leds(cs6436_ledpath['fan'], 3) + else: + system_bright_leds(cs6436_ledpath['fan'], 1) + + return (fanstatus != 0) + + +def system_misc_polling(threadName,delay): + for count in range(1,5): + if device_exist() == False: + time.sleep(delay+3) + print "%s: %s, count=%d" % ( threadName, time.ctime(time.time()), count) + else: + break + + if count == 4: + return + + status, output = log_os_system("echo 1 > /sys/devices/platform/cs6436_54p_led/leds/cs6436_54p_led::sys/brightness", 1) + status, output = log_os_system("hwconfig -cfp 1", 1) + + global AGFlag + if os.access(ageing_controlfile, os.F_OK): + AGFlag = 1 + else: + AGFlag = 0 + + os.system('csw_daemon &') + + + global cs6436_fanattrnodes + global cs6436_psuattrnodes + + for num in range(1,6): + name = 'fan{}'.format(num) + fannode = cs6436_fanattr(name) + cs6436_fanattrnodes.append(fannode) + for num in range(1,3): + name = 'psu{}'.format(num) + psunode = cs6436_psuattr(name) + cs6436_psuattrnodes.append(psunode) + + tempcontrol = system_init_coretemppath() + + misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time()))) + count = 0 + while 1: + count = count + 1 + ret = system_check_psuspresent() + ret = system_check_fansstate() + + if count % 10 == 0: + misclogger.info(": adjust fans and check psu direction.") + system_check_psusdirection() + if tempcontrol == 0: + system_monitor_temperature() + count = 0 + time.sleep(delay) + + return + +if __name__ == '__main__': + target=system_misc_polling("Thread-misc",10) + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py new file mode 100755 index 000000000000..81e6bb7c0b6b --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py @@ -0,0 +1,565 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'cs6436_54p' +version = '0.1.1' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':54} +FORCE = 0 +CPU_TYPE = 'C3308' + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + for count in range(1,5): + time.sleep(1) + ret, lsmod = log_os_system("lsmod| grep i2c_i801", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_i801", 0) + break + + ret, lsmod = log_os_system("lsmod| grep i2c_designware_platform", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_designware_platform", 0) + log_os_system("modprobe i2c-designware-platform", 0) + + ret, lsmod = log_os_system("lsmod| grep cig", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ + 'depmod', + 'modprobe i2c_dev', + 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe x86-64-cig-cs6436-54p-sysfs ' , + 'modprobe x86-64-cig-cs6436-54p-cpld ' , + 'modprobe x86-64-cig-cs6436-54p-fan' , + 'modprobe x86-64-cig-cs6436-54p-psu' , + 'modprobe x86-64-cig-cs6436-54p-sfp' , + 'modprobe x86-64-cig-cs6436-54p-led' ] + +def driver_install(): + global FORCE + + for i in range(0,len(kos)): + if i == 4: + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) + if CPU_TYPE=='i3-6100U': + kos[i] =kos[i] + 'board_id=1' + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0) + if CPU_TYPE=='C3758' or CPU_TYPE=='C3308': + kos[i] =kos[i] + 'board_id=2' + + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['sys','fan','fan1','fan2','fan3','fan4','fan5','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'thermal': ['4-0048','4-0049', '5-004a', '5-004b'] , + 'psu': ['5-005a','5-005b'], + 'sfp': ['-0050']} +i2c_nodes = {'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} + +fan_prefix ='/sys/bus/platform/devices/'+PROJECT_NAME+'_fan' +fan_types = {'fan': ['fan1','fan2', 'fan3', 'fan4', 'fan5']} +fan_nodes = {'fan': ['state', 'front_speed_rpm', 'rear_speed_rpm', 'fault']} + + +sfp_map = [8,9,10,11,12,13,14,15,16, + 17,18,19,20,21,22,23,24,25,26, + 27,28,29,30,31,32,33,34,35,36, + 37,38,39,40,41,42,43,44,45,46, + 47,48,49,50,51,52,53,54,55,56, + 57,60,61,62,63] + +mknod =[ + 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu1 0x5a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu2 0x5b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu1 0x52 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu2 0x53 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo 24c128 0x57 > /sys/bus/i2c/devices/i2c-7/new_device'] + +port = 0 + +def device_install(): + global FORCE + global port + + for i in range(0,len(mknod)): + #all nodes need times to built new i2c buses + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + if (i == 50): + port = port + 3 + else: + port = port + 1 + + + status, output =log_os_system("echo cs6436_54p_sfp"+str(port)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + if port <= 48: + status, output =log_os_system("echo cs6436_54p_sfp"+str(port)+" 0x51 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + return + +def device_uninstall(): + global FORCE + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types, fan_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + for key in fan_types: + itypes = fan_types[key] + nodes = fan_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + + +def get_ledname(ledx): + name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'} + if name_table.has_key(ledx): + name = name_table[ledx] + else: + name = ledx + return name + + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + nwnamex = get_ledname(j) + if nwnamex == j: + print " "+j+":", + else: + print " "+nwnamex+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0) + return not(ret1 or ret2) + + +if __name__ == "__main__": + main() diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile old mode 100755 new mode 100644 index cdb114aad510..b0b4f1f7df06 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile @@ -1,4 +1,5 @@ -obj-m := x86-64-cig-cs6436-56p-cpld.o \ +obj-m :=x86-64-cig-cs6436-56p-sysfs.o \ + x86-64-cig-cs6436-56p-cpld.o \ x86-64-cig-cs6436-56p-fan.o \ x86-64-cig-cs6436-56p-led.o \ x86-64-cig-cs6436-56p-psu.o \ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h old mode 100755 new mode 100644 index 7ce6ae378596..9f1acd52ea68 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h @@ -65,7 +65,7 @@ #define I2C_LPC_CLK3 0x00 #define I2C_LPC_CLK443 0x10 #define I2C_LPC_CLK6 0x14 -#define I2C_LPC_CLK 0x18 +#define I2C_LPC_CLK 0x18 #define I2C_LPC_CLK12 0x1c /* ----- transmission frequencies ------------------------------------- */ @@ -94,4 +94,129 @@ #define I2C_LPC_REG_DATA_TX3 0x8c #define I2C_LPC_REG_DATA_TX4 0x8d -#endif /* I2C_LPC_H */ + +#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 +#define ADDR_REG_SFP_STATUS_TX 0X63 // write data +#define ADDR_REG_SFP_STATUS_RX 0X64 //read data +#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go +#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status + +#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20 +#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21 +#define CPLD_MASTER_INTERRUPT_ALL 0x3f +#define CPLD_MASTER_INTERRUPT_CPLD2 0x20 +#define CPLD_MASTER_INTERRUPT_CPLD1 0x10 +#define CPLD_MASTER_INTERRUPT_PSU2 0x08 +#define CPLD_MASTER_INTERRUPT_PSU1 0x04 +#define CPLD_MASTER_INTERRUPT_6320 0x02 +#define CPLD_MASTER_INTERRUPT_LSW 0x01 + + + +#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20 +#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21 +#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22 +#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23 +#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24 +#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25 + + +#define CPLD_SLAVE1_PRESENT08_REG 0x01 +#define CPLD_SLAVE1_PRESENT16_REG 0x02 +#define CPLD_SLAVE1_PRESENT24_REG 0x03 +#define CPLD_SLAVE2_PRESENT32_REG 0x04 +#define CPLD_SLAVE2_PRESENT40_REG 0x05 +#define CPLD_SLAVE2_PRESENT48_REG 0x06 + +#define CPLD_SLAVE1_RX_LOST08_REG 0x07 +#define CPLD_SLAVE1_RX_LOST16_REG 0x08 +#define CPLD_SLAVE1_RX_LOST24_REG 0x09 +#define CPLD_SLAVE2_RX_LOST32_REG 0x0a +#define CPLD_SLAVE2_RX_LOST40_REG 0x0b +#define CPLD_SLAVE2_RX_LOST48_REG 0x0c + +#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d +#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e +#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f +#define CPLD_SLAVE2_TX_FAULT32_REG 0x10 +#define CPLD_SLAVE2_TX_FAULT40_REG 0x11 +#define CPLD_SLAVE2_TX_FAULT48_REG 0x12 + +#define CPLD_SLAVE2_PRESENT56_REG 0x19 +#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a + + +#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001 +#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002 +#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004 +#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001 +#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002 +#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004 + +#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200 +#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400 + +#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020 + +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100 + + + + + + + +#define WAIT_TIME_OUT_COUNT 100 + + +struct i2c_algo_lpc_data { + void *data; /* private data for lolevel routines */ + void (*setlpc) (void *data, int ctl, int val); + int (*getlpc) (void *data, int ctl); + int (*getown) (void *data); + int (*getclock) (void *data); + void (*waitforpin) (void *data); + + int (*xfer_begin) (void *data); + int (*xfer_end) (void *data); + + /* Multi-master lost arbitration back-off delay (msecs) + * This should be set by the bus adapter or knowledgable client + * if bus is multi-mastered, else zero + */ + unsigned long lab_mdelay; +}; + + +struct subsys_private { + struct kset subsys; + struct kset *devices_kset; + struct list_head interfaces; + struct mutex mutex; + + struct kset *drivers_kset; + struct klist klist_devices; + struct klist klist_drivers; + struct blocking_notifier_head bus_notifier; + unsigned int drivers_autoprobe:1; + struct bus_type *bus; + + struct kset glue_dirs; + struct class *class; +}; + +void cs6436_56p_sysfs_add_client(struct i2c_client *client); +void cs6436_56p_sysfs_remove_client(struct i2c_client *client); + + +#endif /* I2C_LPC8584_H */ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc2iic.h b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc2iic.h old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c old mode 100755 new mode 100644 index a3c6e2db54eb..dcff94085f09 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c @@ -17,8 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - #include #include #include @@ -32,7 +30,6 @@ #include #include #include "i2c-algo-lpc.h" -#include "i2c-algo-lpc2iic.h" #include #include #include @@ -41,11 +38,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include @@ -56,6 +51,20 @@ # include #endif +#include +#include +#include +#include +#include +#include +#include + + + + + +/********************************************** Start ********************************************************/ + /* * ISA bus. */ @@ -65,7 +74,7 @@ static void platform_isa_bus_release(struct device * dev) return ; } - + static struct device isa_bus = { .init_name = "lpc-isa", .release = platform_isa_bus_release, @@ -76,9 +85,9 @@ struct isa_dev { struct device *next; unsigned int id; }; - -#define to_isa_dev(x) container_of((x), struct isa_dev, dev) - + +#define to_isa_dev(x) container_of((x), struct isa_dev, dev) + static int isa_bus_match(struct device *dev, struct device_driver *driver) { struct isa_driver *isa_driver = to_isa_driver(driver); @@ -223,7 +232,7 @@ int lpc_register_driver(struct isa_driver *isa_driver, unsigned int ndev) return error; } - + int lpc_bus_init(void) { int error; @@ -246,28 +255,36 @@ void lpc_bus_exit(void) } +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ /* * module parameters: */ static int i2c_debug = 0; static struct mutex lpc_lock; - -#define DEB2(x) if (i2c_debug >= 2) x -#define DEB3(x) if (i2c_debug >= 3) x + +#define DEB2(x) if (i2c_debug == 2) x +#define DEB3(x) if (i2c_debug == 3) x /* print several statistical values */ -#define DEBPROTO(x) if (i2c_debug >= 9) x; - /* debug the protocol by showing transferred bits */ +#define DEBPROTO(x) if (i2c_debug == 9) x; + /* debug the protocol by showing transferred bits */ #define DEF_TIMEOUT 160 - - - -/* setting states on the bus with the right timing: */ - + + + +/* setting states on the bus with the right timing: */ + #define set_lpc(adap, ctl, val) adap->setlpc(adap->data, ctl, val) #define get_lpc(adap, ctl) adap->getlpc(adap->data, ctl) -#define get_own(adap) adap->getown(adap->data) -#define get_clock(adap) adap->getclock(adap->data) +#define get_own(adap) adap->getown(adap->data) +#define get_clock(adap) adap->getclock(adap->data) #define i2c_outaddr(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DEVICE_ADDR, val) #define i2c_outbyte1(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX1, val) @@ -278,54 +295,52 @@ static struct mutex lpc_lock; #define i2c_inbyte2(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX2) #define i2c_inbyte3(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX3) #define i2c_inbyte4(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX4) - + #define LPC_FPRINTF_LOG_PATH "/tmp/file.log" struct file *lpc_fprintf_file = NULL; - static int lpc_fprintf_debug(const char *fmt, ...) { char lpc_fprintf_buf[256]={0}; - struct va_format vaf; va_list args; int r; - unsigned int file_size = 0; mm_segment_t old_fs; struct timeval tv; + struct rtc_time tm; + do_gettimeofday(&tv); + rtc_time_to_tm(tv.tv_sec,&tm); + va_start(args, fmt); vaf.fmt = fmt; vaf.va = &args; - r=snprintf(lpc_fprintf_buf,"[%012d.%012d] %pV\n",sizeof(lpc_fprintf_buf),tv.tv_sec, tv.tv_usec, &vaf); + r=snprintf(lpc_fprintf_buf,sizeof(lpc_fprintf_buf),"[%04d.%08d] %pV\n",tm.tm_sec, (int)tv.tv_usec, &vaf); va_end(args); - old_fs = get_fs(); set_fs(KERNEL_DS); - lpc_fprintf_file->f_op->write(lpc_fprintf_file, (char *)lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); + vfs_write(lpc_fprintf_file, (char *)&lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); set_fs(old_fs); - memset(lpc_fprintf_buf,0x0,sizeof(lpc_fprintf_buf)); return r; } + static int lpc_fprintf_init(void) { - mm_segment_t old_fs; - - DEB2(printk("lpc_fprintf_init.\n");) - + printk("lpc_fprintf_init.\n"); if(lpc_fprintf_file == NULL) lpc_fprintf_file = filp_open(LPC_FPRINTF_LOG_PATH, O_RDWR | O_APPEND | O_CREAT, 0644); + if (IS_ERR(lpc_fprintf_file)) { - DEB2(printk("error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH);) - return 0; + printk("Error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH); + return -1; } return 0; @@ -333,10 +348,11 @@ static int lpc_fprintf_init(void) static int lpc_fprintf_exit(void) { - DEB2(printk("lpc_fprintf_exit.\n");) + printk("lpc_fprintf_exit.\n"); if(lpc_fprintf_file != NULL) filp_close(lpc_fprintf_file, NULL); + return 0; } @@ -366,14 +382,13 @@ void print_reg(struct i2c_algo_lpc_data *adap) static void i2c_repstart(struct i2c_algo_lpc_data *adap) { - DEBPROTO(lpc_fprintf_debug(" Sr\n")); + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_REPSTART); } static void i2c_stop(struct i2c_algo_lpc_data *adap) { DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) - set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_STOP); udelay(60); set_lpc(adap, I2C_LPC_REG_COMMAND, 0x00); @@ -384,60 +399,56 @@ static void i2c_stop(struct i2c_algo_lpc_data *adap) static void i2c_start(struct i2c_algo_lpc_data *adap) { - unsigned char status; - int timeout = DEF_TIMEOUT; - print_reg(adap); set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_START); print_reg(adap); - } static int wait_for_bb(struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - int status; - +{ + + int timeout = DEF_TIMEOUT; + int status; + while (--timeout) { status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus free status : %x\n",__func__,status);) - + if(status == I2C_LPC_TD) { DEBPROTO(lpc_fprintf_debug("%s : Bus is free status : %x\n",__func__,status);) break; } - } - - if (timeout == 0) { + } + + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout for free busy status : %x\n",__func__,status);) - return -ETIMEDOUT; - } + return -ETIMEDOUT; + } + - - - return 0; + + return 0; } static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - unsigned char status; - +{ + + int timeout = DEF_TIMEOUT; + unsigned char status; + while (--timeout) { - + status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus empty status : %x\n",__func__,status);) if(mode == 1) @@ -446,42 +457,42 @@ static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) { DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) break; - } + } } else - { + { if(status & I2C_LPC_TD) { DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) break; } } - + status = get_lpc(adap, I2C_LPC_REG_TEST); - + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) udelay(1); /* wait for 100 us */ } - if (timeout == 0) { + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Empty\n",__func__);) - return -ETIMEDOUT; - } - - return 0; + return -ETIMEDOUT; + } + + return 0; } static int wait_for_bf(struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - int status; - +{ + + int timeout = DEF_TIMEOUT; + int status; + while (--timeout) { status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus full status : %x\n",__func__,status);) if(status & I2C_LPC_RBF) @@ -491,29 +502,29 @@ static int wait_for_bf(struct i2c_algo_lpc_data *adap) } status = get_lpc(adap, I2C_LPC_REG_TEST); - + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) udelay(1); /* wait for 100 us */ } - - if (timeout == 0) { + + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Full\n",__func__);) - return -ETIMEDOUT; - } - - return 0; + return -ETIMEDOUT; + } + + return 0; } static int wait_for_td(struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - int status=0; - +{ + + int timeout = DEF_TIMEOUT; + int status=0; + while (--timeout) { - udelay(4); + udelay(4); status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus done status : %x\n",__func__,status);) if(status == I2C_LPC_TD) @@ -521,18 +532,18 @@ static int wait_for_td(struct i2c_algo_lpc_data *adap) DEBPROTO(lpc_fprintf_debug("%s : Bus is done status : %x\n",__func__,status);) break; } - } - - if (timeout == 0) { + } + + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Done\n",__func__);) - return -ETIMEDOUT; - } - - return 0; + return -ETIMEDOUT; + } + + return 0; } - + static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) { int timeout = DEF_TIMEOUT; @@ -545,7 +556,7 @@ static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) if (timeout == 0) return -ETIMEDOUT; - + return 0; } @@ -565,7 +576,7 @@ static int lpc_doAddress(struct i2c_algo_lpc_data *adap,struct i2c_msg *msg) { DEBPROTO(lpc_fprintf_debug("step 2 : write mode then write device address 0x%x\n",addr);) } - + if (flags & I2C_M_REV_DIR_ADDR) { addr ^= 1; @@ -629,33 +640,33 @@ static int lpc_sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) i += 1; } - + /* Send START */ DEBPROTO(lpc_fprintf_debug("step 5-1 : Delay 6mS \n");) - udelay(6000); + udelay(6000); DEBPROTO(lpc_fprintf_debug("step 5-2 : Start to transfrom \n");) i2c_stop(adap); i2c_start(adap); DEBPROTO(lpc_fprintf_debug("step 5-3 : Start done\n");) - udelay(400); + udelay(400); DEBPROTO(lpc_fprintf_debug("step 6 : Waiting for BE\n");) timeout = wait_for_td(adap); if (timeout) { DEBPROTO(lpc_fprintf_debug("step 6 : Timeout waiting for BE \n");) - return -1; + return -EREMOTEIO; } }while (i < count); - + if(i == count) { DEBPROTO(lpc_fprintf_debug("Writen %d bytes successd !\n",count);) return i; } else - { + { DEBPROTO(lpc_fprintf_debug("Writen %d bytes failed \n",count);) - return -1; + return -EIO; } } @@ -663,7 +674,6 @@ static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { int i=0,timeout=0; struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; - int wfp; unsigned int count = msg->len; unsigned char *buf = msg->buf; @@ -675,27 +685,27 @@ static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) /* Send START */ DEBPROTO(lpc_fprintf_debug("step 9-1 : Delay 6mS\n");) - udelay(6000); + udelay(6000); DEBPROTO(lpc_fprintf_debug("step 9-2 : Start to receive data\n");) i2c_stop(adap); i2c_start(adap); DEBPROTO(lpc_fprintf_debug("step 9-3 : Start done\n");) - udelay(400); + udelay(400); DEBPROTO(lpc_fprintf_debug("step 10 : Waiting for TD\n");) timeout = wait_for_td(adap); if (timeout) { DEBPROTO(lpc_fprintf_debug("step 10 : Timeout waiting for TD \n");) - return -1; + return -EREMOTEIO; } - + if((count -i) >= 4) { buf[i+0] = 0xff & i2c_inbyte1(adap); buf[i+1] = 0xff & i2c_inbyte2(adap); buf[i+2] = 0xff & i2c_inbyte3(adap); buf[i+3] = 0xff & i2c_inbyte4(adap); - + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) @@ -732,19 +742,17 @@ static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) }while(i < count); - + if(i == count) { DEBPROTO(lpc_fprintf_debug("Read %d bytes successd !\n",count);) return i; } else - { + { DEBPROTO(lpc_fprintf_debug("Read %d bytes failed \n",count);) - return -1; + return -EIO; } - - return i; } @@ -768,7 +776,7 @@ static int lpc_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; struct i2c_msg *pmsg; int i; - int ret=0, timeout, status; + int ret=0; mutex_lock(&lpc_lock); @@ -810,11 +818,12 @@ static int lpc_master_xfer(struct i2c_adapter *i2c_adap, if (adap->xfer_end) adap->xfer_end(&i2c_adap->nr); - + mutex_unlock(&lpc_lock); - return i; + DEBPROTO(lpc_fprintf_debug("ret = 0x%x num = 0x%x i = 0x%x.\n",ret,num,i)); + return ret = (ret < 0) ? ret : num; } @@ -831,38 +840,14 @@ static const struct i2c_algorithm lpc_algo = { }; -/* - * registering functions to load algorithms at runtime - */ -int lpc_add_iic_bus(struct i2c_adapter *adap,unsigned int id) -{ - //struct i2c_algo_lpc_data *lpc_adap = adap->3; - int rval,num; +/********************************************** End ********************************************************/ + + - DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); - /* register new adapter to i2c module... */ - adap->algo = &lpc_algo; - - for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) - { - adap->nr = num; - snprintf(adap->name, sizeof(adap->name), - "i2c-%d-lpc (chan_id %d)", i2c_adapter_id(adap), num); - if(num) - { - rval = i2c_add_numbered_adapter(adap); - } - else - { - rval = i2c_add_adapter(adap); - } - } - return rval; -} -EXPORT_SYMBOL(lpc_add_iic_bus); +/********************************************** Start ********************************************************/ #define DEFAULT_BASE 0x0a00 static int lpc_base= 0x0a00; @@ -905,7 +890,6 @@ struct cpld_dev_type *cpld_device; static void lpc_cpld_setbyte(void *data, int ctl, int val) { - //udelay(2); outb(ctl, LPC_INDEX_REG); mb(); @@ -916,7 +900,7 @@ static void lpc_cpld_setbyte(void *data, int ctl, int val) static int lpc_cpld_getbyte(void *data, int ctl) { u8 val = 0; - //udelay(2); + outb(ctl, LPC_INDEX_REG); mb(); @@ -929,17 +913,23 @@ static int lpc_cpld_getbyte(void *data, int ctl) static void lpc_iic_setbyte(void *data, int ctl, int val) { if (!cpld_device) - return -ENOTTY; + { + return ; + } if (down_interruptible(&cpld_device->sem)) - return -ERESTARTSYS; - + { + return ; + } + + lpc_cpld_setbyte(data,ctl,val); - + up(&cpld_device->sem); - DEB2(printk("%s REG[%x] = %x\n",__func__,ctl,val);) + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) } + static int lpc_iic_getbyte(void *data, int ctl) { u8 val = 0; @@ -950,9 +940,9 @@ static int lpc_iic_getbyte(void *data, int ctl) return -ERESTARTSYS; val = lpc_cpld_getbyte(data,ctl); - + up(&cpld_device->sem); - DEB2(printk("%s REG[%x] = %x\n",__func__,ctl,val);) + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) return val; } @@ -964,7 +954,7 @@ int cig_cpld_read_register(u8 reg_off, u8 *val) if (down_interruptible(&cpld_device->sem)) return -ERESTARTSYS; - *val = lpc_cpld_getbyte(cpld_device, reg_off); + *val = lpc_cpld_getbyte(cpld_device, reg_off); up(&cpld_device->sem); @@ -1039,24 +1029,24 @@ static irqreturn_t lpc_iic_handler(int this_irq, void *dev_id) { static int board_id = 0; -static int lpc_select_chan(void *data) +static int lpc_iic_select(void *data) { unsigned int chan_id=0; chan_id = *(unsigned int *)data; - chan_id -= 1; - DEB2(printk("step 1 : selest channel id = %d\n",chan_id);) + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step 1 : selest channel id = %d\n",chan_id);) lpc_iic_setbyte(data,I2C_LPC_REG_BUS_SEL,chan_id); return 0; } -static int lpc_deselect_chan(void *data) +static int lpc_iic_deselect(void *data) { unsigned int chan_id=0; chan_id = *(unsigned int *)data; - chan_id -= 1; - DEB2(printk("step last :deselect channel id = %d\n",chan_id);) + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step last :deselect channel id = %d\n",chan_id);) return 0; } @@ -1072,8 +1062,8 @@ static struct i2c_algo_lpc_data lpc_iic_data = { .getown = lpc_iic_getown, .getclock = lpc_iic_getclock, .waitforpin = lpc_iic_waitforpin, - .xfer_begin = lpc_select_chan, - .xfer_end = lpc_deselect_chan, + .xfer_begin = lpc_iic_select, + .xfer_end = lpc_iic_deselect, }; #include @@ -1082,12 +1072,12 @@ static struct i2c_adapter lpc_iic_arr_ops[LPC_I2C_MAX_NCHANS] = {0}; static void dummy_setscl(void *data, int state) { - return 1; + return; } static void dummy_setsda(void *data, int state) { - return 1; + return; } @@ -1170,9 +1160,7 @@ static int lpc_iic_probe(struct device *dev, unsigned int id) DEB2(printk("lpc_iic_probe\n");) mutex_init(&lpc_lock); - if(board_id == 1) - i2c_add_adapter(&i2c_dummy); - + for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) { lpc_iic_arr_ops[num].dev.parent = dev; @@ -1181,11 +1169,11 @@ static int lpc_iic_probe(struct device *dev, unsigned int id) lpc_iic_arr_ops[num].algo = &lpc_algo; lpc_iic_arr_ops[num].algo_data = &lpc_iic_data, lpc_iic_arr_ops[num].nr=num; - snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num]), num); + snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num])); rval |= i2c_add_adapter(&lpc_iic_arr_ops[num]); DEB2(printk("%s\n",lpc_iic_arr_ops[num].name);) } - + return 0; } @@ -1198,8 +1186,6 @@ static int lpc_iic_remove(struct device *dev, unsigned int id) for(num = LPC_I2C_MAX_NCHANS - 1; num >= 0 ;num--) i2c_del_adapter(&lpc_iic_arr_ops[num]); - if(board_id == 1) - i2c_del_adapter(&i2c_dummy); return 0; } @@ -1214,8 +1200,15 @@ static struct isa_driver i2c_lpc_driver = { }, }; +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ -struct kset cpld_kset; static int cpld_major = 0; static int cpld_minor = 0; @@ -1227,6 +1220,8 @@ struct cpld_rw_msg { static struct cpld_rw_msg param_read = {-1}; static struct cpld_rw_msg param_write = {-1}; +static struct cpld_rw_msg param_reads = {-1}; +static struct cpld_rw_msg param_writes = {-1}; void cpld_sysfs_kobj_release(struct kobject *kobj) { @@ -1245,28 +1240,57 @@ int cpld_sysfs_add_attr(struct kobject* kobj, char* attr_name) return sysfs_create_file(kobj, attr); } +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data); +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data); + static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buffer) { - u8 val,ret; + u8 val=0,ret=0,year=0,month=0,day=0,cpld_m=0,cpld_1=0,cpld_2=0; if (0 == strcmp(attr->name, "read")) { - val = lpc_iic_getbyte(NULL,param_read.addr); - ret = sprintf(buffer,"read : addr = %x val = %x\n",param_read.addr, val); + val = lpc_iic_getbyte(NULL,param_read.addr); + ret = sprintf(buffer,"read : addr = 0x%x val = 0x%x\n",param_read.addr, val); } else if (0 == strcmp(attr->name, "write")) { lpc_iic_setbyte(NULL, param_write.addr,param_write.data); - ret = sprintf(buffer,"write : addr = %x val = %x\n",param_write.addr, param_write.data); + ret = sprintf(buffer,"write : addr = 0x%x val = 0x%x\n",param_write.addr, param_write.data); } else if (0 == strcmp(attr->name, "version")) { - val = lpc_iic_getbyte(NULL, 0x02); - ret = sprintf(buffer,"CPLD version : V%02x\n",val); + cpld_m = lpc_iic_getbyte(NULL, 0x02); + year = lpc_iic_getbyte(NULL, 0x03); + month = lpc_iic_getbyte(NULL, 0x04); + day = lpc_iic_getbyte(NULL, 0x05); + + cig_cpld_read_slave_cpld_register(0x1d,&cpld_1); + cig_cpld_read_slave_cpld_register(0x1e,&cpld_2); + + ret = sprintf(buffer,"Main CPLD version : V%02x\n"\ + "Main CPLD date : 20%02x-%02x-%02x\n"\ + "Slave 1 CPLD version : V%02x\n"\ + "Slave 2 CPLD version : V%02x\n",cpld_m,year,month,day,cpld_1,cpld_2); + } + if (0 == strcmp(attr->name, "reads")) + { + ret = cig_cpld_read_slave_cpld_register(param_reads.addr,&val); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"reads : addr = 0x%x val = 0x%x\n",param_reads.addr, val); + + } + else if (0 == strcmp(attr->name, "writes")) + { + ret = cig_cpld_write_slave_cpld_register(param_writes.addr,param_writes.data); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"writes : addr = 0x%x val = 0x%x\n",param_writes.addr, param_writes.data); } - + + return ret; } @@ -1274,7 +1298,7 @@ static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, cha static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t count) { int param[3]; - + if (0 == strcmp(attr->name, "read")) { sscanf(buffer, "0x%02x", ¶m[0]); @@ -1285,19 +1309,30 @@ static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, co sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); param_write.addr = param[0]; param_write.data = param[1]; + } + if (0 == strcmp(attr->name, "reads")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_reads.addr = param[0]; + } + else if (0 == strcmp(attr->name, "writes")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_writes.addr = param[0]; + param_writes.data = param[1]; } return count; } -static struct sysfs_ops cpld_sysfs_ops = -{ +static struct sysfs_ops cpld_sysfs_ops = +{ .show = cpld_sysfs_show, .store = cpld_sysfs_store, }; -static struct kobj_type cpld_kobj_type = +static struct kobj_type cpld_kobj_type = { .release = cpld_sysfs_kobj_release, .sysfs_ops = &cpld_sysfs_ops, @@ -1308,6 +1343,10 @@ static struct kobj_type cpld_kobj_type = static const char driver_name[] = "cpld_drv"; static atomic_t cpld_available = ATOMIC_INIT(1); static struct class *cpld_class; +static struct device *cpld_dev; + + + #define CPLD_IOC_MAGIC '[' #define CPLD_IOC_RDREG _IOR(CPLD_IOC_MAGIC, 0, struct cpld_rw_msg) @@ -1340,7 +1379,7 @@ int cpld_release(struct inode *inode, struct file *flip) long cpld_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - int rc = 0; + int rc = 0; int err = 0; struct cpld_dev_type *dev = (struct cpld_dev_type *)filp->private_data; struct cpld_rw_msg msg; @@ -1390,7 +1429,7 @@ struct file_operations cpld_fops = { .unlocked_ioctl = cpld_ioctl, .release = cpld_release, }; - + static void cpld_setup_cdev(struct cpld_dev_type *dev) { @@ -1404,166 +1443,710 @@ static void cpld_setup_cdev(struct cpld_dev_type *dev) if (err) DEB2(printk(KERN_NOTICE "Error %d adding cpld", err);) } -//#define CPLD_KTHREAD_TEST -#ifdef CPLD_KTHREAD_TEST -#include -#include -#include -#include -#include -#include -static struct task_struct *test_TaskStruct; -void get_random_bytes(void *buf, int nbytes); +/********************************************** End ********************************************************/ + + + -#define LM75_REAR_LEFT_PATH "/sys/class/hwmon/hwmon5/temp1_input" -#define LM75_REAR_RIGHT_PATH "/sys/class/hwmon/hwmon6/temp1_input" +/********************************************** Start ********************************************************/ +#include +#include +#include + +static spinlock_t irq_inter_lock; +static struct delayed_work irq_inter_work; +static unsigned long irq_inter_delay; -static int threadTask(void* arg) +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data) { - static int count =0; - unsigned char lpc_read_data=0; - unsigned char lpc_write_data=0; - unsigned char lpc_random_data=0; - - struct file *temp1_file = NULL,*temp2_file = NULL; - unsigned char temp1_buffer[8]={0},temp2_buffer[8]={0}; - - mm_segment_t old_fs; - while(1) + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<=======write=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1); + DEB2(printk("[62]=%x\n",reg_addr << 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, reg_data); + DEB2(printk("[63]=%x\n",reg_data)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x02); + DEB2(printk("<=======write=========>")); + + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<========read=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1 | 1); + DEB2(printk("[62]=%x\n",reg_addr << 1 | 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,reg_data); + DEB2(printk("[64]=%x\n",*reg_data)); + DEB2(printk("<========read=========>")); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + +struct sock *nlsk = NULL; +extern struct net init_net; +#define NETLINK_TEST 26 +#define MSG_LEN 125 +#define USER_PORT 100 +static u32 irq_present_status_low_current,irq_present_status_low_next; +static u32 irq_present_status_high_current,irq_present_status_high_next; +static u32 irq_tx_fault_status_low_current,irq_tx_fault_status_low_next; +static u32 irq_tx_fault_status_high_current,irq_tx_fault_status_high_next; +static u32 irq_rx_lost_status_low_current,irq_rx_lost_status_low_next; +static u32 irq_rx_lost_status_high_current,irq_rx_lost_status_high_next; + +static u8 irq_present_qsfp_current,irq_present_qsfp_next; +static u8 irq_interrupt_qsfp_current,irq_interrupt_qsfp_next; + +struct input_dev *cpld_input_dev; + + + +int send_usrmsg(char *pbuf, uint16_t len) +{ + struct sk_buff *nl_skb; + struct nlmsghdr *nlh; + + int ret; + + + nl_skb = nlmsg_new(len, GFP_ATOMIC); + if(!nl_skb) + { + printk("netlink alloc failure\n"); + return -1; + } + + + nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0); + if(nlh == NULL) + { + printk("nlmsg_put failaure \n"); + nlmsg_free(nl_skb); + return -1; + } + + memcpy(nlmsg_data(nlh), pbuf, len); + ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); + + return ret; +} + +static void netlink_rcv_msg(struct sk_buff *skb) +{ + + struct nlmsghdr *nlh = NULL; + char *umsg = NULL; + char kmsg[1024] = {0}; + char kmsg_tmp[16] = {0}; + u8 i = 0; + u8 tmp[3]={0}; + + if(skb->len >= nlmsg_total_size(0)) + { + nlh = nlmsg_hdr(skb); + umsg = NLMSG_DATA(nlh); + if(umsg) + { + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+1,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+25,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + + for(i = 0;i < 8;i++) + { + if(!(irq_present_qsfp_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"qsfp%02d:%1d:%1d:%1d ",i+49,tmp[0],tmp[1],0); + strcat(kmsg,kmsg_tmp); + } + + printk("kernel recv from user: %s\n", umsg); + send_usrmsg(kmsg, strlen(kmsg)); + } + } + + return ; +} + + + +struct netlink_kernel_cfg cfg = { + .input = netlink_rcv_msg, /* set recv callback */ +}; + + + +#define RANGE_OF_BYTE_SHIFT(to_arg,shift,from_arg) {to_arg &= ~(0xff << shift); to_arg |= from_arg << shift;} + + +static void irq_inter_wapper(struct work_struct * work) +{ + + u8 m_data = 0; + u8 data_high8 = 0,data_low8 = 0; + u16 data_16 = 0; + u8 status = 0; + u8 i = 0; + char kmsg[64]={0}; + u8 tmp[3] = {0}; + + DEB2(printk("CPLD_MASTER_INTERRUPT\r\n")); + + m_data = lpc_iic_getbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG); + lpc_iic_setbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG,0xff); + + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0xff); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0xff); + if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD1)) { - if(kthread_should_stop()) + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24) + ) { - DEB2(printk("threadTask: kthread_should_stop\n")); - break; - } - -#if 1 - get_random_bytes(&lpc_random_data,1); - - lpc_write_data = lpc_random_data; - - lpc_iic_setbyte(NULL,I2C_LPC_REG_TEST,lpc_write_data); - //DEB2(printk("threadTask: lpc write reg[01] data : %02x\n",lpc_write_data)); - - lpc_read_data = lpc_iic_getbyte(NULL,I2C_LPC_REG_TEST); - //DEB2(printk("threadTask: lpc read reg[01] data : %02x\n",lpc_read_data)); - udelay(10000); - if(lpc_write_data != lpc_read_data) + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,16,status); + } + DEB2(printk("irq_present_status_low_next = %08x irq_present_status_low_current = %08x \n",irq_present_status_low_next,irq_present_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) { - printk("Error : WRITE %02x != READ %02x\n",lpc_write_data,lpc_read_data); + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_RX_LOST08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,16,status); + } + DEB2(printk("irq_rx_lost_status_low_next = %08x irq_rx_lost_status_low_current = %08x \n",irq_rx_lost_status_low_next,irq_rx_lost_status_low_current)); } - msleep(10); -#else - if(temp1_file != NULL) - temp1_file = filp_open(LM75_REAR_LEFT_PATH, O_RDONLY , 0); - if (IS_ERR(temp1_file)) { - printk("error occured while opening file %s, exiting...\n", LM75_REAR_LEFT_PATH); + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,16,status); + } + DEB2(printk("irq_tx_fault_status_low_next = %08x irq_tx_fault_status_low_current = %08x \n",irq_tx_fault_status_low_next,irq_tx_fault_status_low_current)); + + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD2)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT32_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT40_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,16,status); + } } - if(temp2_file != NULL) - temp2_file = filp_open(LM75_REAR_RIGHT_PATH, O_RDONLY ,0); - if (IS_ERR(temp2_file)) { - printk("error occured while opening file %s, exiting...\n", LM75_REAR_RIGHT_PATH); + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,16,status); + } + } + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,16,status); + } + } - old_fs = get_fs(); - set_fs(KERNEL_DS); + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT56)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT56_REG,&status); + irq_present_qsfp_current = status; + } - temp1_file->f_op->read(temp1_file, (char *)temp1_buffer, strlen(temp1_buffer), &temp1_file->f_pos); + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_QSFP_CR56)) + { + DEB2(printk("CPLD_SLAVE2_QSFP_CR56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_QSFP_CR56_REG,&status); + irq_interrupt_qsfp_current = status; + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_LSW)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_LSW\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU1)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU1\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU2)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU2\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_6320)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_6320\r\n")); + } + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0x0); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0x0); - temp2_file->f_op->read(temp2_file, (char *)temp2_buffer, strlen(temp2_buffer), &temp2_file->f_pos); - - set_fs(old_fs); + memset(tmp,0xff,sizeof(tmp)); - if((simple_strtoul(temp1_buffer,NULL,10) >=30000) || (simple_strtoul(temp2_buffer,NULL,10) >=30000)) + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i)) && (irq_present_status_low_next & (0x1 << i))) { - lpc_iic_setbyte(NULL,0x40,0xff); - printk("Full speed\n"); + DEB2(printk("SFP%d is present\r\n",i+1)); + tmp[0] = 1; + } + else if((irq_present_status_low_current & (0x1 << i)) && !(irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+1)); + tmp[0] = 0; } - msleep(1000); -#endif + if(!(irq_tx_fault_status_low_current & (0x1 << i)) && (irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+1)); + tmp[1] = 1; + } + else if((irq_tx_fault_status_low_current & (0x1 << i)) && !(irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+1)); + tmp[1] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i)) && (irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+1)); + tmp[2] = 1; + } + else if((irq_rx_lost_status_low_current & (0x1 << i)) && !(irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+1)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+1,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } } -} - -static int init_kernel_Thread(void) -{ - test_TaskStruct=kthread_create(threadTask,NULL,"KernelThead",0); - if(IS_ERR(test_TaskStruct)) + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0;i < 24;i++) { - printk("kthread_create error\n"); + if(!(irq_present_status_high_current & (0x1 << i)) && (irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+25)); + tmp[0] = 1; + } + else if((irq_present_status_high_current & (0x1 << i)) && !(irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+25)); + tmp[0] = 0; + + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i)) && (irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+25)); + tmp[1] = 1; + } + else if((irq_rx_lost_status_high_current & (0x1 << i)) && !(irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+25)); + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i)) && (irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+25)); + tmp[2] = 1; + } + else if((irq_tx_fault_status_high_current & (0x1 << i)) && !(irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+25)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+25,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } } - else + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0 ; i < 8; i++) { - wake_up_process(test_TaskStruct); + if(!(irq_present_qsfp_current & (0x1 << i)) && (irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+49)); + tmp[0] = 1; + } + else if((irq_present_qsfp_current & (0x1 << i)) && !(irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+49)); + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i)) && (irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is occured \r\n",i+49)); + tmp[1] = 1; + } + else if((irq_interrupt_qsfp_current & (0x1 << i)) && !(irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is cleaned\r\n",i+49)); + tmp[1] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"qsfp%02d:%1d:%1d:%1d ",i+49,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],0); + break; + } } - return 0; + + + irq_present_status_low_next = irq_present_status_low_current; + irq_rx_lost_status_low_next = irq_rx_lost_status_low_current; + irq_tx_fault_status_low_next = irq_tx_fault_status_low_current; + irq_present_status_high_next = irq_present_status_high_current; + irq_rx_lost_status_high_next = irq_rx_lost_status_high_current; + irq_tx_fault_status_high_next = irq_tx_fault_status_high_current; + irq_present_qsfp_next = irq_present_qsfp_current; + irq_interrupt_qsfp_next = irq_interrupt_qsfp_current; + + send_usrmsg(kmsg, strlen(kmsg)); } -static void exit_kernel_Thread(void) +static void disableIrq(unsigned short maskReg, unsigned short mask) { - kthread_stop(test_TaskStruct); - test_TaskStruct = NULL; + u8 data = 0; + + data = lpc_iic_getbyte(NULL,maskReg); + data |= mask; + lpc_iic_setbyte(NULL,maskReg, data); } -#endif +static void enableIrq(unsigned short maskReg, unsigned short mask) +{ + unsigned short data; + + data = lpc_iic_getbyte(NULL,maskReg); + data &= ~mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + + +static irqreturn_t irq_inter_isr(int irq, void *handle) +{ + + /* + * use keventd context to read the event fifo registers + * Schedule readout at least 25ms after notification for + * REVID < 4 + */ + + schedule_delayed_work(&irq_inter_work, irq_inter_delay); + + return IRQ_HANDLED; +} + + +#define CIG_CPLD_CHR_NAME "cpld" static int __init cpld_init(void) { - int rval,rc; + int rval,rc=0; dev_t dev; - + u8 s_data; + int isr_GPIO_num = 289; + DEB2(printk("cpld_init\n");) +/**************************************************************************************/ + + LPC_INDEX_REG = lpc_base_addr; + LPC_DATA_REG = lpc_base_addr + 1; + cpld_device = kzalloc(sizeof(struct cpld_dev_type), GFP_KERNEL); if (!cpld_device) goto error3; - cpld_device->io_resource = request_region(lpc_base_addr, + cpld_device->io_resource = request_region(lpc_base_addr, lpc_io_space_size, "lpc-i2c"); if (!cpld_device->io_resource) { - DEB2(printk("lpc: claim I/O resource fail\n");) + printk("lpc: claim I/O resource fail\n"); goto error2; } sema_init(&cpld_device->sem, 1); - LPC_INDEX_REG = lpc_base_addr; - LPC_DATA_REG = lpc_base_addr + 1; - - rval = lpc_bus_init(); - rval = lpc_register_driver(&i2c_lpc_driver, 1); - - kobject_set_name(&cpld_kset.kobj, "cpld"); - cpld_kset.kobj.ktype= &cpld_kobj_type; - kset_register(&cpld_kset); - cpld_sysfs_add_attr(&cpld_kset.kobj, "read"); - cpld_sysfs_add_attr(&cpld_kset.kobj, "write"); - cpld_sysfs_add_attr(&cpld_kset.kobj, "version"); - if (cpld_major) { dev = MKDEV(cpld_major, cpld_minor); - rc = register_chrdev_region(dev, 1, "cpld"); + rc = register_chrdev_region(dev, 1, CIG_CPLD_CHR_NAME); } else { - rc = alloc_chrdev_region(&dev, cpld_major, 1, "cpld"); + rc = alloc_chrdev_region(&dev, cpld_major, 1, CIG_CPLD_CHR_NAME); cpld_major = MAJOR(dev); } cpld_setup_cdev(cpld_device); - cpld_class = class_create(THIS_MODULE, KBUILD_MODNAME); + cpld_class = class_create(THIS_MODULE,CIG_CPLD_CHR_NAME); if (!cpld_class) { DEB2(printk("failed to create class\n");) goto error1; } - device_create(cpld_class, NULL, dev, NULL, "cpld"); -#ifdef CPLD_KTHREAD_TEST - init_kernel_Thread(); -#endif - + cpld_class->p->subsys.kobj.ktype= &cpld_kobj_type; + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "read"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "write"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "reads"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "writes"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "version"); + + cpld_dev = device_create(cpld_class, NULL, dev, NULL, CIG_CPLD_CHR_NAME); + +/**************************************************************************************/ + + rval = lpc_bus_init(); + rval = lpc_register_driver(&i2c_lpc_driver, 1); + +/**************************************************************************************/ return 0; error1: cdev_del(&cpld_device->cdev); @@ -1572,20 +2155,18 @@ static int __init cpld_init(void) release_resource(cpld_device->io_resource); error3: kfree(cpld_device); - + return rc; } static void __exit cpld_exit(void) { - DEB2(printk("cpld_exit\n")); - - lpc_unregister_driver(&i2c_lpc_driver); - lpc_bus_exit(); -#ifdef CPLD_KTHREAD_TEST - exit_kernel_Thread(); -#endif - dev_t devno = MKDEV(cpld_major, cpld_minor); + + DEB2(printk("cpld_exit\n")); + + lpc_unregister_driver(&i2c_lpc_driver); + lpc_bus_exit(); + dev_t devno = MKDEV(cpld_major, cpld_minor); cdev_del(&cpld_device->cdev); if (cpld_class) { @@ -1593,11 +2174,6 @@ static void __exit cpld_exit(void) class_destroy(cpld_class); } - kobject_put(&cpld_kset.kobj); - - if(cpld_kset.kobj.ktype) - kset_unregister(&cpld_kset); - if (cpld_device) { if (cpld_device->io_resource) release_resource(cpld_device->io_resource); @@ -1622,11 +2198,7 @@ MODULE_DESCRIPTION("cs6436-56p-cpld driver"); MODULE_LICENSE("GPL"); - - - - - +/********************************************** End ********************************************************/ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c old mode 100755 new mode 100644 index 09beb6912c32..33eaaa840305 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c @@ -44,6 +44,9 @@ static struct cs6436_56p_fan_data *cs6436_56p_fan_update_device(struct device *d static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + extern int cig_cpld_write_register(u8 reg_off, u8 val); extern int cig_cpld_read_register(u8 reg_off, u8 *val); @@ -63,6 +66,7 @@ static const u8 fan_reg[] = { 0x47, /* rear fan 3 speed(rpm) */ 0x49, /* rear fan 4 speed(rpm) */ 0x4b, /* rear fan 5 speed(rpm) */ + 0x4c, /* fan direction rear to front or front to rear */ }; @@ -99,6 +103,7 @@ enum sysfs_fan_attributes { FAN3_REAR_SPEED_RPM, FAN4_REAR_SPEED_RPM, FAN5_REAR_SPEED_RPM, + FAN_DIRECTION, FAN1_STATE, FAN2_STATE, FAN3_STATE, @@ -109,6 +114,11 @@ enum sysfs_fan_attributes { FAN3_FAULT, FAN4_FAULT, FAN5_FAULT, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, }; /* Define attributes @@ -131,6 +141,11 @@ enum sysfs_fan_attributes { #define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + + /* 5 fan state attributes in this platform */ DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1); DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2); @@ -156,6 +171,13 @@ DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5); /* 1 fan duty cycle attribute in this platform */ DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); + + static struct attribute *cs6436_56p_fan_attributes[] = { /* fan related attributes */ DECLARE_FAN_STATE_ATTR(1), @@ -174,6 +196,11 @@ static struct attribute *cs6436_56p_fan_attributes[] = { DECLARE_FAN_SPEED_RPM_ATTR(4), DECLARE_FAN_SPEED_RPM_ATTR(5), DECLARE_FAN_DUTY_CYCLE_ATTR(), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), NULL }; @@ -230,6 +257,7 @@ static u8 is_fan_fault(struct cs6436_56p_fan_data *data, enum fan_id id) return ret; } + static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { @@ -247,6 +275,41 @@ static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, return count; } +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value,fan_index; + u8 mask,reg_val; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + fan_index = attr->index - FAN1_DIRECTION; + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (!(value == 0 || value == 1)) + return -EINVAL; + + + cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val); + + if(value == 1) + { + reg_val |= (1 << fan_index); + } + else + { + reg_val &= ~(1 << fan_index); + } + + cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val); + + return count; +} + + + + + static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf) { @@ -300,6 +363,13 @@ static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, case FAN5_FAULT: ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION)); + break; default: break; } diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c old mode 100755 new mode 100644 index 8754007408c7..1a4734d4ba25 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c @@ -17,265 +17,306 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -#define MAX_FAN_DUTY_CYCLE 100 - -/* Address scanned */ -static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; - -/* This is additional data */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" + + + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Address scanned */ +static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; + +/* This is additional data */ struct cs6436_56p_psu_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; - unsigned long last_updated; /* In jiffies */ - - /* Registers value */ - u8 vout_mode; - u16 v_in; - u16 v_out; - u16 i_in; - u16 i_out; - u16 p_in; - u16 p_out; - u16 temp_input[3]; - u8 temp_fault; - u8 fan_fault; - u16 fan_duty_cycle[2]; - u16 fan_speed[2]; - u8 mfr_id[8]; - u8 mfr_model[20]; - u8 mfr_serial[20]; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 v_in; + u16 v_out; + u16 i_in; + u16 i_out; + u16 p_in; + u16 p_out; + u16 temp_input[3]; + u8 temp_fault; + u8 fan_fault; + u16 fan_duty_cycle[2]; + u16 fan_speed[2]; + u8 mfr_id[8]; + u8 mfr_model[20]; + u8 mfr_serial[20]; u8 psu_is_present; u8 psu_is_good; -}; - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask); -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); -static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); + struct i2c_client *client; + struct bin_attribute *bin; /* eeprom data */ +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); static int cs6436_56p_psu_read_byte(struct i2c_client *client, u8 reg); static int cs6436_56p_psu_read_word(struct i2c_client *client, u8 reg); static int cs6436_56p_psu_write_word(struct i2c_client *client, u8 reg, u16 value); static int cs6436_56p_psu_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len); static struct cs6436_56p_psu_data *cs6436_56p_psu_update_device(struct device *dev); -static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); enum cs6436_56p_psu_sysfs_attributes { - PSU_V_IN, - PSU_V_OUT, - PSU_I_IN, - PSU_I_OUT, - PSU_P_IN, - PSU_P_OUT, - PSU_TEMP1_INPUT, - PSU_TEMP2_INPUT, - PSU_TEMP3_INPUT, - PSU_TEMP_FAULT, - PSU_TEMP_WARN, - PSU_FAN1_FAULT, - PSU_FAN1_WARN, - PSU_FAN1_DUTY_CYCLE, - PSU_FAN1_SPEED, - PSU_MFR_ID, - PSU_MFR_MODEL, - PSU_MFR_SERIAL, + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_TEMP2_INPUT, + PSU_TEMP3_INPUT, + PSU_TEMP_FAULT, + PSU_TEMP_WARN, + PSU_FAN1_FAULT, + PSU_FAN1_WARN, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, PSU_PRESENT, PSU_P_GOOD, -}; - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask) -{ - u16 valid_data = data & mask; - - bool is_negative = valid_data >> (valid_bit - 1); - return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; -} - -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ - *dev_attr, const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct i2c_client *client = to_i2c_client(dev); +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + + bool is_negative = valid_data >> (valid_bit - 1); + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); struct cs6436_56p_psu_data *data = i2c_get_clientdata(client); - int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; - long speed; - int error; - - error = kstrtol(buf, 10, &speed); - if (error) - return error; - - if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) - return -EINVAL; - - - mutex_lock(&data->update_lock); - data->fan_duty_cycle[nr] = speed; + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + if (data->valid != 1) + { + return -ENODEV; + } + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; cs6436_56p_psu_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - u16 value = 0; - int exponent, mantissa; - int multiplier = 1000; - - switch (attr->index) { - case PSU_V_IN: - value = data->v_in; - break; - case PSU_I_IN: - value = data->i_in; - break; - case PSU_I_OUT: - value = data->i_out; - break; - case PSU_P_IN: - value = data->p_in; - break; - case PSU_P_OUT: - value = data->p_out; - break; - case PSU_TEMP1_INPUT: - value = data->temp_input[0]; - break; - case PSU_TEMP2_INPUT: - value = data->temp_input[1]; - break; - case PSU_TEMP3_INPUT: - value = data->temp_input[2]; - break; - case PSU_FAN1_DUTY_CYCLE: - multiplier = 1; - value = data->fan_duty_cycle[0]; - break; - case PSU_FAN1_SPEED: - multiplier = 1; - value = data->fan_speed[0]; - break; - default: - break; - } - - exponent = two_complement_to_int(value >> 11, 5, 0x1f); - mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); - - return (exponent >= 0) ? sprintf(buf, "%d\n", \ - (mantissa << exponent) * multiplier) : \ - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - - return sprintf(buf, "%d\n", data->temp_fault >> 7); -} - -static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - return sprintf(buf, "%d\n", data->temp_fault >> 6); -} -static ssize_t for_vout_data(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_TEMP2_INPUT: + value = data->temp_input[1]; + break; + case PSU_TEMP3_INPUT: + value = data->temp_input[2]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? \ + sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) :\ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + + + return sprintf(buf, "%d\n", data->temp_fault >> 7); +} + +static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + if (data->valid != 1) + { + return -ENODEV; + } + + + return sprintf(buf, "%d\n", data->temp_fault >> 6); +} +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - int exponent, mantissa; - int multiplier = 1000; - - exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); - mantissa = data->v_out; - - return (exponent > 0) ? sprintf(buf, "%d\n", \ - (mantissa << exponent) * multiplier) : \ - sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); -} - -static ssize_t for_ascii(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + int exponent, mantissa; + int multiplier = 1000; + if (data->valid != 1) + { + return -ENODEV; + } + + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - u8 *ptr = NULL; - - if (!data->valid) - return 0; - - switch (attr->index) { - case PSU_MFR_ID: - ptr = data->mfr_id + 1; - break; - case PSU_MFR_MODEL: - ptr = data->mfr_model + 1; - break; - case PSU_MFR_SERIAL: - ptr = data->mfr_serial + 1; - break; - default: - return 0; - } - return sprintf(buf, "%s\n", ptr); -} + u8 *ptr = NULL; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_MFR_ID: + ptr = data->mfr_id + 1; + break; + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf) @@ -286,14 +327,14 @@ static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, u8 status = 0; - if (!data->valid) { - return -EIO; - } - if (attr->index == PSU_PRESENT) { status = data->psu_is_present; } else { /* PSU_POWER_GOOD */ + if (!data->valid) { + return -ENODEV; + } + status = data->psu_is_good; } @@ -301,286 +342,602 @@ static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, } - static int cs6436_56p_psu_read_byte(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - +{ + return i2c_smbus_read_byte_data(client, reg); +} + static int cs6436_56p_psu_read_word(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_word_data(client, reg); -} - +{ + return i2c_smbus_read_word_data(client, reg); +} + static int cs6436_56p_psu_write_word(struct i2c_client *client, u8 reg, \ - u16 value) -{ - union i2c_smbus_data data; - data.word = value; - return i2c_smbus_xfer(client->adapter, client->addr, - client->flags |= I2C_CLIENT_PEC, - I2C_SMBUS_WRITE, reg, - I2C_SMBUS_WORD_DATA, &data); - -} - + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + static int cs6436_56p_psu_read_block(struct i2c_client *client, u8 command, \ - u8 *data, int data_len) -{ - int result = i2c_smbus_read_i2c_block_data(client, command, data_len, - data); - if (unlikely(result < 0)) - goto abort; - if (unlikely(result != data_len)) { - result = -EIO; - goto abort; - } - - result = 0; -abort: - return result; - -} - -struct reg_data_byte { - u8 reg; - u8 *value; -}; - -struct reg_data_word { - u8 reg; - u16 *value; -}; - -static struct cs6436_56p_psu_data *cs6436_56p_psu_update_device( \ - struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); + u8 *data, int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, + data); + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; +abort: + return result; + +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + + + +#define EEPROM_NAME "psu_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +/* Platform dependent --- */ +static ssize_t psu_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; + +} + + +static ssize_t psu_page_write(struct i2c_client *client,const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_write(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; +} + + + +static ssize_t psu_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_56p_psu_data *data; + ssize_t retval = 0; + struct i2c_client *client; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + + mutex_lock(&data->update_lock); + retval = psu_page_write(client, buf, off, count); + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t psu_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + +abort: + return status; +} + + + +static ssize_t psu_page_read(struct i2c_client *client,char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + printk("Count = 0, return"); + return count; + } + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_read(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; + +} + + +static ssize_t psu_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_56p_psu_data *data; + struct i2c_client *client; + ssize_t retval = 0; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + mutex_lock(&data->update_lock); + retval = psu_page_read(client, buf, off, count); + mutex_unlock(&data->update_lock); + + return retval; +} + + + +static int psu_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = psu_bin_read; + eeprom->write = psu_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + + +static int psu_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + + +static int psu_i2c_check_functionality(struct i2c_client *client) +{ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK); +} + + + +static int psu_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + int status; + + struct cs6436_56p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + data->bin = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL); + if (!data->bin) { + status = -ENOMEM; + goto eeprom_bin_error; + } + + /* init eeprom */ + status = psu_sysfs_eeprom_init(&client->dev.kobj, data->bin); + if (status) { + status = -ENOMEM; + goto sys_init_error; + } + + dev_info(&client->dev, "psu eeprom '%s'\n", client->name); + + return 0; + + sys_init_error: + kfree(data->bin); + + eeprom_bin_error: + kfree(data); + + exit: + return status; +} + + + + +static struct cs6436_56p_psu_data *cs6436_56p_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); struct cs6436_56p_psu_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - - if (time_after(jiffies, data->last_updated)) { - int i, status; - u8 command; - struct reg_data_byte regs_byte[] = { - {0x20, &data->vout_mode}, - {0x81, &data->fan_fault}, - {0x7d, &data->temp_fault}, - }; - struct reg_data_word regs_word[] = { - {0x88, &data->v_in}, - {0x8b, &data->v_out}, - {0x89, &data->i_in}, - {0x8c, &data->i_out}, - {0x96, &data->p_out}, - {0x97, &data->p_in}, - {0x8d, &(data->temp_input[0])}, - {0x8e, &(data->temp_input[1])}, - {0x8f, &(data->temp_input[2])}, - {0x3b, &(data->fan_duty_cycle[0])}, - {0x90, &(data->fan_speed[0])}, - }; - - dev_dbg(&client->dev, "start data update\n"); - - /* one milliseconds from now */ - data->last_updated = jiffies + HZ / 1000; - - for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { - status = cs6436_56p_psu_read_byte(client, - regs_byte[i].reg); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_byte[i].reg, status); - } else { - *(regs_byte[i].value) = status; - } - } - - for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + + + mutex_lock(&data->update_lock); + + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}, + {0x7d, &data->temp_fault}, + }; + struct reg_data_word regs_word[] = { + {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x90, &(data->fan_speed[0])}, + }; + data->valid = 1; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cs6436_56p_psu_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + data->valid = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { status = cs6436_56p_psu_read_word(client, - regs_word[i].reg); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_word[i].reg, status); - } else { - *(regs_word[i].value) = status; - } - } - - command = 0x99; /* PSU mfr_id */ - status = cs6436_56p_psu_read_block(client, command, - data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); - data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - - command = 0x9a; /* PSU mfr_model */ - status = cs6436_56p_psu_read_block(client, command, - data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); - data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - - command = 0x9e; /* PSU mfr_serial */ - status = cs6436_56p_psu_read_block(client, command, - data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); - data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - data->valid = 1; + regs_word[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + data->valid = 0; + } else { + *(regs_word[i].value) = status; + } + } + + command = 0x99; /* PSU mfr_id */ + status = cs6436_56p_psu_read_block(client, command, + data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); + data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_id, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9a; /* PSU mfr_model */ + status = cs6436_56p_psu_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_model, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9e; /* PSU mfr_serial */ + status = cs6436_56p_psu_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_serial, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + data->psu_is_present = strlen(data->mfr_id) > 1 ? 1:0; if(data->psu_is_present) + { data->psu_is_good = ((data->fan_fault) || (data->temp_fault))? 0:1; - else + } + else + { + data->valid = 0; data->psu_is_good = 0; - } - - mutex_unlock(&data->update_lock); - - return data; - -} - -/* sysfs attributes for hwmon */ -static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); -static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); -static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); -static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); -static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); -static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); -static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); -static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); -static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); -static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); -static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); -static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); -static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); -static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); + } + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, for_status, NULL, PSU_PRESENT); static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, for_status, NULL, PSU_P_GOOD); - + static struct attribute *cs6436_56p_psu_attributes[] = { - &sensor_dev_attr_psu_v_in.dev_attr.attr, - &sensor_dev_attr_psu_v_out.dev_attr.attr, - &sensor_dev_attr_psu_i_in.dev_attr.attr, - &sensor_dev_attr_psu_i_out.dev_attr.attr, - &sensor_dev_attr_psu_p_in.dev_attr.attr, - &sensor_dev_attr_psu_p_out.dev_attr.attr, - &sensor_dev_attr_psu_temp1_input.dev_attr.attr, - &sensor_dev_attr_psu_temp2_input.dev_attr.attr, - &sensor_dev_attr_psu_temp3_input.dev_attr.attr, - &sensor_dev_attr_psu_temp_fault.dev_attr.attr, - &sensor_dev_attr_psu_temp_warning.dev_attr.attr, - &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, - &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, - &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, - &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, - &sensor_dev_attr_psu_mfr_id.dev_attr.attr, - &sensor_dev_attr_psu_mfr_model.dev_attr.attr, - &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_temp2_input.dev_attr.attr, + &sensor_dev_attr_psu_temp3_input.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_temp_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, &sensor_dev_attr_psu_present.dev_attr.attr, &sensor_dev_attr_psu_power_good.dev_attr.attr, - NULL -}; - + NULL +}; + static const struct attribute_group cs6436_56p_psu_group = { .attrs = cs6436_56p_psu_attributes, -}; - -static int cs6436_56p_psu_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ +}; + + +static int psu_register_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + struct cs6436_56p_psu_data *data; - int status; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) { - status = -EIO; - goto exit; - } - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - status = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - data->valid = 0; - mutex_init(&data->update_lock); - - dev_info(&client->dev, "new chip found\n"); - - /* Register sysfs hooks */ + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ status = sysfs_create_group(&client->dev.kobj, &cs6436_56p_psu_group); - if (status) - goto exit_sysfs_create_group; - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_hwmon_device_register; - } - - return 0; - -exit_hwmon_device_register: - sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); -exit_sysfs_create_group: - kfree(data); -exit: - return status; -} - + if (status) + goto exit_sysfs_create_group; + + cs6436_56p_sysfs_add_client(client); + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + /* init eeprom */ + + return 0; + + exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); + exit_sysfs_create_group: + kfree(data); + exit: + return status; + +} + + +static int cs6436_56p_psu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + status = psu_eeprom_probe(client, id); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + status = psu_register_probe(client, id); + } + return status; +} + static int cs6436_56p_psu_remove(struct i2c_client *client) -{ - struct cs6436_56p_psu_data *data = i2c_get_clientdata(client); - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); - kfree(data); - - return 0; -} - -enum psu_index -{ +{ + cs6436_56p_sysfs_remove_client(client); + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + struct cs6436_56p_psu_data *data; + data = i2c_get_clientdata(client); + psu_sysfs_eeprom_cleanup(&client->dev.kobj,data->bin); + kfree(data); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + struct cs6436_56p_psu_data *data; + data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); + kfree(data); + } + + return 0; +} + +enum psu_index +{ cs6436_56p_psu1, cs6436_56p_psu2 -}; - +}; + static const struct i2c_device_id cs6436_56p_psu_id[] = { { "cs6436_56p_psu1", cs6436_56p_psu1 }, { "cs6436_56p_psu2", cs6436_56p_psu2 }, - {} -}; + {} +}; MODULE_DEVICE_TABLE(i2c, cs6436_56p_psu_id); - + static struct i2c_driver cs6436_56p_psu_driver = { - .class = I2C_CLASS_HWMON, - .driver = { + .class = I2C_CLASS_HWMON, + .driver = { .name = "cs6436_56p_psu", - }, + }, .probe = cs6436_56p_psu_probe, .remove = cs6436_56p_psu_remove, .id_table = cs6436_56p_psu_id, - .address_list = normal_i2c, -}; + .address_list = normal_i2c, +}; module_i2c_driver(cs6436_56p_psu_driver); - -MODULE_AUTHOR("Zhang Peng "); + +MODULE_AUTHOR("Zhang Peng "); MODULE_DESCRIPTION("cs6436_56p_psu driver"); MODULE_LICENSE("GPL"); diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c old mode 100755 new mode 100644 index f2b54a260fcb..5665fa33048b --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c @@ -28,6 +28,7 @@ #include #include #include +#include "i2c-algo-lpc.h" #define DRIVER_NAME "cs6436_56p_sfp" /* Platform dependent */ @@ -64,15 +65,9 @@ #define SFF8436_RX_LOS_ADDR 3 #define SFF8436_TX_FAULT_ADDR 4 #define SFF8436_TX_DISABLE_ADDR 86 - - -#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 -#define ADDR_REG_SFP_STATUS_TX 0X63 // write data -#define ADDR_REG_SFP_STATUS_RX 0X64 //read data -#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go -#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status - - +#define QSFP_RESET_ADDR 0x1b +#define QSFP_INTER_ADDR 0x1a +#define QSFP_LPMODE_ADDR 0x1c static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); @@ -87,6 +82,11 @@ static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); extern int cig_cpld_read_register(u8 reg_off, u8 *val); extern int cig_cpld_write_register(u8 reg_off, u8 val); +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); enum sfp_sysfs_attributes { PRESENT, @@ -109,7 +109,10 @@ enum sfp_sysfs_attributes { RX_LOS2, RX_LOS3, RX_LOS4, - RX_LOS_ALL + RX_LOS_ALL, + QSFPRESET, + QSFPINT, + QSFPLPMODE }; /* SFP/QSFP common attributes for sysfs */ @@ -134,6 +137,9 @@ static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, qsfp_reset_read, qsfp_reset_write, QSFPRESET); +static SENSOR_DEVICE_ATTR(sfp_inter, S_IRUGO, qsfp_inter_read, NULL, QSFPINT); +static SENSOR_DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, qsfp_lpmode_read, qsfp_lpmode_write, QSFPLPMODE); static struct attribute *qsfp_attributes[] = { &sensor_dev_attr_sfp_port_number.dev_attr.attr, &sensor_dev_attr_sfp_port_type.dev_attr.attr, @@ -154,6 +160,9 @@ static struct attribute *qsfp_attributes[] = { &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + &sensor_dev_attr_sfp_reset.dev_attr.attr, + &sensor_dev_attr_sfp_inter.dev_attr.attr, + &sensor_dev_attr_sfp_lpmode.dev_attr.attr, NULL }; @@ -342,13 +351,13 @@ static ssize_t show_port_number(struct device *dev, struct device_attribute *da, return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); } -#define WAIT_TIME_OUT_COUNT 100 + static int cig_cpld_write_sfp_register(u8 sfp_reg_addr, u8 sfp_write_reg_data) { u8 sfp_read_status = 0; u8 wait_time_out = WAIT_TIME_OUT_COUNT; - + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1); cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, sfp_write_reg_data); cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); @@ -371,7 +380,7 @@ static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) { u8 sfp_read_status = 0; u8 wait_time_out = WAIT_TIME_OUT_COUNT; - + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1 | 1); cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); do{ @@ -393,7 +402,7 @@ static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) - + /* Platform dependent +++ */ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) @@ -411,7 +420,7 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) /* Read present status of port 1~48(SFP port) */ for (i = 0; i < 6; i++) { cpld_reg_addr = 1 + i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { @@ -420,8 +429,8 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) } data->present |= (u64)cpld_reg_data << (i*8); - - DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); + + DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); } /* Read present status of port 49-56(QSFP port) */ @@ -433,7 +442,7 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) } else { data->present |= (u64)cpld_reg_data << 48; - } + } DEBUG_PRINT("Present status = 0x%lx", data->present); exit: @@ -463,7 +472,7 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) /* Read status of port 1~48(SFP port) */ for (i = 0; i < 6; i++) { cpld_reg_addr = 13+i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); @@ -471,14 +480,14 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) } data->msa->status[0] |= (u64)cpld_reg_data << (i * 8); - - DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); + + DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); } - + for (i = 0; i < 6; i++) { cpld_reg_addr = 19+i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); @@ -486,13 +495,13 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) } data->msa->status[1] |= (u64)cpld_reg_data << (i * 8); - - DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); + + DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); } for (i = 0; i < 6; i++) { cpld_reg_addr = 7+i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); @@ -500,8 +509,8 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) } data->msa->status[2] |= (u64)cpld_reg_data << (i * 8); - - DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); + + DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); } data->msa->valid = 1; @@ -531,12 +540,12 @@ static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *d } mutex_lock(&data->update_lock); - + udelay(6000); if(data->port <= 48) { cpld_reg_addr = 19 + data->port / 8; - cpld_reg_bit = 1 << (data->port); + cpld_reg_bit = 1 << ((data->port) % 8); } /* Read current status */ @@ -548,10 +557,10 @@ static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *d cpld_reg_data |= cpld_reg_bit; } else { - data->msa->status[1] &= ~BIT_INDEX(data->port); + data->msa->status[1] &= ~ BIT_INDEX(data->port); cpld_reg_data &= ~cpld_reg_bit; } - + error = cig_cpld_write_sfp_register(cpld_reg_addr,cpld_reg_data); mutex_unlock(&data->update_lock); @@ -582,7 +591,7 @@ static ssize_t show_present(struct device *dev, struct device_attribute *da, int i; u8 values[7] = {0}; struct sfp_port_data *data = sfp_update_present(client); - + if (IS_ERR(data)) { return PTR_ERR(data); } @@ -682,7 +691,7 @@ static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf) { struct i2c_client *client = to_i2c_client(dev); - struct sfp_port_data *data = i2c_get_clientdata(client); + struct sfp_port_data *data = i2c_get_clientdata(client); int present = sfp_is_port_present(client, data->port); if (IS_ERR_VALUE(present)) { @@ -750,6 +759,253 @@ static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) return (status < 0) ? ERR_PTR(status) : data; } +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_INTER_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("inter read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("reset read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_RESET_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + + +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("lpmode read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_LPMODE_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf) { @@ -822,7 +1078,7 @@ static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute * int status; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); - struct sfp_port_data *data = i2c_get_clientdata(client); + struct sfp_port_data *data = i2c_get_clientdata(client); status = sfp_is_port_present(client, data->port); if (IS_ERR_VALUE(status)) { @@ -922,13 +1178,13 @@ static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute for (i = 0; i < ARRAY_SIZE(values); i++) { values[i] = (u8)(data->msa->status[2] >> (i * 8)); } - + /** Return values 1 -> 48 in order */ return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", values[0], values[1], values[2], - values[3], values[4], values[5]); + values[3], values[4], values[5]); } - + switch (attr->index) { case TX_FAULT: index = 0; @@ -938,7 +1194,7 @@ static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute break; case RX_LOS: index = 2; - break; + break; default: break; } @@ -1246,6 +1502,8 @@ static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id * *data = msa; dev_info(&client->dev, "sfp msa '%s'\n", client->name); + cs6436_56p_sysfs_add_client(client); + return 0; exit_remove: @@ -1386,7 +1644,7 @@ static int sfp_device_probe(struct i2c_client *client, return qsfp_probe(client, dev_id, &data->qsfp); } } - + return -ENODEV; } /* Platform dependent --- */ @@ -1419,6 +1677,7 @@ static int sfp_device_remove(struct i2c_client *client) { struct sfp_port_data *data = i2c_get_clientdata(client); + cs6436_56p_sysfs_remove_client(client); switch (data->driver_type) { case DRIVER_TYPE_SFP_MSA: return sfp_msa_remove(client, data->msa); diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sysfs.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sysfs.c new file mode 100644 index 000000000000..89f6bba3aab2 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sysfs.c @@ -0,0 +1,335 @@ +/* + * A hwmon driver for the CIG cs6436-56P sysfs Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c-algo-lpc.h" + + +static LIST_HEAD(sysfs_client_list); +static struct mutex list_lock; + +struct sysfs_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define DEVICE_NAME "cigfs" +static int dev_major; +static struct class *dev_class; +static struct cdev *dev_cdev; +static struct device *dev_device; +static struct class *psu_class; +static struct class *sfp_class; + + +void cs6436_56p_sysfs_add_client(struct i2c_client *client) +{ + struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &sysfs_client_list); + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_56p_sysfs_add_client); + +void cs6436_56p_sysfs_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (IS_ERR(sysfs_node)) + { + break; + } + if (sysfs_node->client == client) { + found = 1; + break; + } + } + if (found) { + list_del(list_node); + kfree(sysfs_node); + } + + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_56p_sysfs_remove_client); + +struct class * cs6436_56p_sysfs_create_symclass(char *cls_name) +{ + int rc = 0; + struct class *my_class; +/**************************************************************************************/ + my_class = class_create(THIS_MODULE,cls_name); + if (IS_ERR(my_class)) { + pr_err("failed to create my class\n"); + } + return my_class; + +/**************************************************************************************/ +} + +void cs6436_56p_sysfs_delete_symclass(struct class *my_class) +{ +/**************************************************************************************/ + + if (IS_ERR(my_class)) { + pr_err("Pointer is invaild\n"); + } + class_destroy(my_class); + +/**************************************************************************************/ +} + + + + + +int cs6436_56p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name); + if(rc) + { + pr_err("failed to create symlink %d\n",rc); + } + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +int cs6436_56p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + sysfs_remove_link(&my_class->p->subsys.kobj,device_name); + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +static int cs6436_56p_sysfs_open(struct inode *inode, struct file *file) +{ + return 0; +} + + + +static ssize_t cs6436_56p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) +{ + char str[10],name[18],port[8]; + int ret; + int i; + memset(str, 0, sizeof(str)); + ret = copy_from_user(str, buf, count); + if (ret) + { + printk(KERN_ERR "copy_from_user fail\n"); + return -EINVAL; + } + + if(!strncmp(str,"start",5)) + { + psu_class = cs6436_56p_sysfs_create_symclass("psu"); + cs6436_56p_sysfs_create_symlink(psu_class,"cs6436_56p_psu1","psu1"); + cs6436_56p_sysfs_create_symlink(psu_class,"cs6436_56p_psu2","psu2"); + sfp_class = cs6436_56p_sysfs_create_symclass("swps"); + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_56p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_56p_sysfs_create_symlink(sfp_class,name,port); + } + } + else if(!strncmp(str,"stop",4)) + { + cs6436_56p_sysfs_delete_symlink(psu_class,"cs6436_56p_psu1","psu1"); + cs6436_56p_sysfs_delete_symlink(psu_class,"cs6436_56p_psu2","psu2"); + cs6436_56p_sysfs_delete_symclass(psu_class); + + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_56p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_56p_sysfs_delete_symlink(sfp_class,name,port); + } + cs6436_56p_sysfs_delete_symclass(sfp_class); + } + return count; +} + + +static struct file_operations cs6436_56p_sysfs_fops = { + .owner = THIS_MODULE, + .open = cs6436_56p_sysfs_open, + .write = cs6436_56p_sysfs_write, +}; + + +static int __init cs6436_56p_sysfs_init(void) +{ + int result = 0; + int err = 0; + dev_t dev = MKDEV(dev_major, 0); + + if (dev_major) + result = register_chrdev_region(dev, 1, DEVICE_NAME); + else { + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + dev_major = MAJOR(dev); + } + if (result < 0) + { + printk("unable to get major %d\n", dev_major); + err= -EINVAL; + } + printk("get major is %d\n", dev_major); + if (dev_major == 0) + dev_major = result; + + dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL); + if(IS_ERR(dev_cdev)) { + err= -ENOMEM; + } + + cdev_init(dev_cdev, &cs6436_56p_sysfs_fops); + dev_cdev->owner = THIS_MODULE; + dev_cdev->ops = &cs6436_56p_sysfs_fops; + err = cdev_add(dev_cdev, dev, 1); + if (err) + { + printk("error %d add fpga ", err); + goto err_malloc; + } + + dev_class = class_create(THIS_MODULE, DEVICE_NAME); + if (IS_ERR(dev_class)) + { + printk("Err:failed in creating class.\n"); + goto err_cdev_add; + } + + dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME); + if (IS_ERR(dev_device)) + { + printk("Err:failed in creating device.\n"); + goto err_class_crt; + } + + mutex_init(&list_lock); + + return err; + + err_class_crt: + cdev_del(dev_cdev); + err_cdev_add: + kfree(dev_cdev); + err_malloc: + unregister_chrdev_region(MKDEV(dev_major,0), 1); + + return err; + +} + +static void __exit cs6436_56p_sysfs_exit(void) +{ + cdev_del(dev_cdev); + printk("cdev_del ok\n"); + device_destroy(dev_class, MKDEV(dev_major, 0)); + + class_destroy(dev_class); + + if(dev_cdev != NULL) + kfree(dev_cdev); + + unregister_chrdev_region(MKDEV(dev_major, 0), 1); + printk("cs6436_56p_sysfs_exit...\r\n"); +} + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436-56p-sysfs driver"); +MODULE_LICENSE("GPL"); + +module_init(cs6436_56p_sysfs_init); +module_exit(cs6436_56p_sysfs_exit); + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-init.service b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-init.service old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service old mode 100755 new mode 100644 index 7ff410cbb3c1..ed44bc0b3438 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service @@ -4,7 +4,7 @@ After=cs6436-platform-init.service DefaultDependencies=no [Service] -ExecStart=/usr/local/bin/cig_cs6436_misc.py +ExecStart=/usr/local/bin/cig_cs6436_misc.py KillSignal=SIGKILL SuccessExitStatus=SIGKILL diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py index 08decef98ad0..3b685236a075 100755 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py @@ -21,12 +21,259 @@ import logging import re import time +import datetime from collections import namedtuple from threading import Thread DEBUG = False i2c_prefix = '/sys/bus/i2c/devices/' -cs6436__prefix = '/sys/devices/platform/cs6436_56p_led/leds/' +leds_prefix = '/sys/devices/platform/cs6436_56p_led/leds/' +fans_prefix = '/sys/devices/platform/cs6436_56p_fan/' +fansdir_prefix = fans_prefix + 'fan{}_direction' + +ageing_controlfile = '/etc/sonic/agcontrol' +AGFlag = 0 + + +platform_misc_log = '/var/log/platform_misc.log' +misclogger = logging.getLogger('platform_misc') +misclogger.setLevel(logging.INFO) +miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s') + +if not os.path.isfile(platform_misc_log): + try: + os.mknod(platform_misc_log) + except: + print 'Failed to creat platform_misc.log' + +fileHandler = logging.FileHandler(platform_misc_log) +fileHandler.setLevel(logging.INFO) +fileHandler.setFormatter(miscformatter) +misclogger.addHandler(fileHandler) + + +starttime = datetime.datetime.now() +IsGetlswt = 0 +coretemp_prefix = '/sys/class/hwmon/hwmon1/' +coretemp_ps = [] +psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present' +psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present' +psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom' +psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom' +psu1led_d = leds_prefix + 'cs6436_56p_led::psu1/brightness' +psu2led_d = leds_prefix + 'cs6436_56p_led::psu2/brightness' +cs6436_ledpath = {'fan':leds_prefix + 'cs6436_56p_led::fan/brightness', + 'fan1':leds_prefix + 'cs6436_56p_led::fan1/brightness', + 'fan2':leds_prefix + 'cs6436_56p_led::fan2/brightness', + 'fan3':leds_prefix + 'cs6436_56p_led::fan3/brightness', + 'fan4':leds_prefix + 'cs6436_56p_led::fan4/brightness', + 'fan5':leds_prefix + 'cs6436_56p_led::fan5/brightness', + 'psu1':leds_prefix + 'cs6436_56p_led::psu1/brightness', + 'psu2':leds_prefix + 'cs6436_56p_led::psu2/brightness', + 'sys':leds_prefix + 'cs6436_56p_led::sys/brightness'} + + +def system_read_filestr(node): + with open(node, 'r') as f: + try: + str = f.read() + except IOError as e: + misclogger.error('Failed to get node, str={}'.format(node)) + return "0" + return str + + +def system_bright_leds(dev, colour): + global AGFlag + + if AGFlag == 1: + return + + cmd = 'echo {} > {}'.format(colour, dev) + log_os_system(cmd, 1) + return + +''' +1: front in tail out +0: front out tail in +''' +def system_getpsu_direction(dev): + try: + with open(dev) as f: + f.seek(0x30) + str = f.read(2) + except IOError as e: + misclogger.error('Failed to get psu eep') + return 1 + if str == 'AA': ## front in tail out + return 1 + elif str == 'RA':## tail in front out + return 0 + else: + misclogger.error('Failed to get psu eep, str={}'.format(str)) + return -1 + + +def system_get_cputype(): + cmdretfd = os.popen("lscpu | grep 'Model name'") + retstring = cmdretfd.read() + endindex = retstring.find('@') - 1 + startindex = retstring[:endindex].rfind(' ') + 1 + cputype = retstring[startindex:endindex] + + return cputype + + +def system_init_coretemppath(): + global coretemp_ps + + cmdstr = "ls {} | grep 'input'".format(coretemp_prefix) + cmdretfd = os.popen(cmdstr) + + coretemppss = cmdretfd.read().splitlines() + if len(coretemppss) < 3: + cputype = system_get_cputype() + misclogger.error('Failed to init core temperature path.' + ' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps))) + return 1 + + for i in range(0,3): + coretemp_ps.append(coretemp_prefix + coretemppss[i]) + + print coretemp_ps + + return 0 + + +class cs6436_fanattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.rear = 0 + self.rear_p = '' + self.front = 0 + self.front_p = '' + self.fault = 0 + self.fault_p = '' + self.status = 0 + self.setpath() + self.updatedevice() + + return + + def setpath(self): + self.direction_p = fans_prefix + '{}_direction'.format(self.name) + self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name) + self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name) + self.fault_p = fans_prefix + '{}_fault'.format(self.name) + + return + + def updatedevice(self): + self.direction = int(system_read_filestr(self.direction_p)) + self.rear = int(system_read_filestr(self.rear_p)) + self.front = int(system_read_filestr(self.front_p)) + self.fault = int(system_read_filestr(self.fault_p)) + + return + + def checkspeedrpm(self, speedrpm): + frontrpmexp = speedrpm * 21000 / 100 + rearrpmexp = speedrpm * 19000 / 100 + deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp) + deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp) + + if deviationfront < 0.3 and deviationrear < 0.3: + return 0 + else: + misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear)) + return 1 + + def checkstatus(self, speedrpm, totaldirct): + speedstatus = self.checkspeedrpm(speedrpm) + if self.direction != totaldirct: + self.status = 1 + misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction)) + elif speedstatus != 0: + self.status = 1 + elif self.fault != 0: + misclogger.error(':{} fault.'.format(self.name)) + self.status = 1 + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_fanattrnodes = [] + + +class cs6436_psuattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.present = 0 + self.present_p = '' + self.status = 0 + + self.setpath() + self.updatepresent() + self.updatedirection() + + return + + def setpath(self): + if self.name == 'psu1': + self.present_p = psu1_p + self.direction_p = psu1_d + if self.name == 'psu2': + self.present_p = psu2_p + self.direction_p = psu2_d + + return + + def updatepresent(self): + self.present = int(system_read_filestr(self.present_p)) + + return + + def updatedirection(self): + if self.present == 1: + self.direction = system_getpsu_direction(self.direction_p) + else: + self.direction = 2 + + return + + def checkstatus(self, totaldirct): + if self.present != 1: + self.status = 1 + misclogger.error(':{} not present.'.format(self.name)) + elif self.direction == 2: + self.status = 0 + misclogger.info(':{} direction need to be update.'.format(self.name)) + elif self.direction != totaldirct: + self.status = 1 + misclogger.info(':{} direction is wrong.'.format(self.name)) + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_psuattrnodes = [] + + def my_log(txt): if DEBUG == True: @@ -36,15 +283,15 @@ def my_log(txt): def device_exist(): ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0) ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0) - ret3, log = log_os_system("ls "+cs6436__prefix+"cs6436_56p_led*", 0) + ret3, log = log_os_system("ls "+leds_prefix+"cs6436_56p_led*", 0) return not(ret1 or ret2 or ret3) - + def log_os_system(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) my_log (cmd +"with result:" + str(status)) - my_log (" output:"+output) + my_log (" output:"+output) if status: logging.info('Failed :'+cmd) if show: @@ -52,7 +299,223 @@ def log_os_system(cmd, show): return status, output -def system_misc_polling(threadName,delay): +def system_get_coretemp(): + temp1 = system_read_filestr(coretemp_ps[0]).strip() + temp2 = system_read_filestr(coretemp_ps[1]).strip() + temp3 = system_read_filestr(coretemp_ps[2]).strip() + + return int(temp1), int(temp2), int(temp3) + +def system_get_boardtemp(): + for i in range(0,16): + temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i + if os.access(temp1path, os.F_OK): + break + for i in range(0,16): + temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i + if os.access(temp2path, os.F_OK): + break + temp1 = system_read_filestr(temp1path).strip() + temp2 = system_read_filestr(temp2path).strip() + + return int(temp1), int(temp2) + + +def system_get_lswtemp(): + global IsGetlswt + global starttime + if IsGetlswt == 0: + now = datetime.datetime.now() + misclogger.info("time wait.") + misclogger.info("start = {}, now = {}.".format(starttime, now)) + if (now - starttime).seconds > 150: + misclogger.info("time = ".format((now - starttime).seconds)) + IsGetlswt = 1 + + return 25 + +# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) +# if chp.poll() == None: +# misclogger.info("No subp.") +# chp.kill() +# +# return 25 + +# retstring = chp.stdout.read() +# chp.kill() +# if 'Up' not in retstring: +# misclogger.info("lsw not up.") +# +# return 25 + + status, output = log_os_system('npx_diag swc show temperature', 1) + if status: + misclogger.error('failed to show lsw temperature') + + return 25 + + output = output.strip() + if output.find("it 0, temperature ") > 0: + startindex = output.find('temperature') + len('temperature') + 1 + endindex = output[startindex:].find(" ") + endindex = startindex + endindex + temp = output[startindex:endindex] + b = temp.find('.') + if b > 0: + temp=temp[:b] + temp = int(temp) + else: + misclogger.error("Failed to get temperature.") + temp = 0 + + return int(temp) + +def system_monitor_temperature(): + + ctemp1, ctemp2, ctemp3 = system_get_coretemp() + btemp1, btemp2 = system_get_boardtemp() + ltemp = system_get_lswtemp() + fan_speed_str = system_cs6436_getfanexspeed() + fan_speed = int(fan_speed_str) + policy = 'stay' + pos = 0 + #speed c1 c2 c3 b1 b2 lsw + fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95], + [40, 44000, 44000, 44000, 44000, 39000, 96], + [50, 49000, 49000, 49000, 47000, 44000, 91], + [60, 52000, 52000, 52000, 51500, 47500, 92], + [70, 53000, 53000, 53000, 52000, 49000, 93], + [100,999999,999999,999999,999999,999999,999]) + + fan_policy_down=([30, 0, 0, 0, 0, 0, 0], + [40, 34000, 34000, 34000, 34000, 30000, 80], + [50, 38000, 38000, 38000, 37000, 33000, 81], + [60, 44000, 44000, 44000, 43000, 39000, 84], + [70, 44000, 44000, 44000, 43000, 40000, 84], + [100, 48000, 48000, 48000, 46000, 42000, 85],) + + for policytable in fan_policy_up: + if fan_speed <= policytable[0]: + break + pos = pos + 1 + fan_speed = policytable[0] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'stay' + policytable = fan_policy_down[pos] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'down' + else: + policy = 'up' + + if policy == 'up': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos + 1][0] + misclogger.info("fan policy: up. speedexp = {}".format(fan_speed)) + + if policy == 'stay': + fan_speed = fan_policy_down[pos] + return + + if policy == 'down': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos - 1][0] + misclogger.info("fan policy: down.speedexp = {}".format(fan_speed)) + + cmd = "echo %d > /sys/devices/platform/cs6436_56p_fan/fan_duty_cycle_percentage" % fan_speed + status, output = log_os_system(cmd, 1) + if status: + misclogger.error("set fan speed fault") + + return + + +def system_cs6436_setfanexspeed(num): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + numstr = str(num) + with open(fanspeednode, 'w') as f: + f.write(numstr) + + +def system_cs6436_getfanexspeed(): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + fanspeedstr = system_read_filestr(fanspeednode) + fanspeedexp = int(fanspeedstr) + + return fanspeedexp + + +def system_cs6436_getdirection(): + global cs6436_fanattrnodes + direction = 0 + + for fan in cs6436_fanattrnodes: + direction = direction + fan.direction + + if direction > 2: + direction = 1 + else: + direction = 0 + + return direction + + +def system_check_psusdirection(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatedirection() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_psuspresent(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatepresent() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_fansstate(): + global cs6436_fanattrnodes + global cs6436_ledpath + cs6436totaldirct = system_cs6436_getdirection() + fanstatus = 0 + fanexspeed = 0 + + fanexspeed = system_cs6436_getfanexspeed() + + for fan in cs6436_fanattrnodes: + fan.updatedevice() + fan.checkstatus(fanexspeed, cs6436totaldirct) + fanstatus = fanstatus + fan.status + + if fanstatus > 0: + misclogger.error(':fan error.set fans speed 100.') + system_cs6436_setfanexspeed(100) + system_bright_leds(cs6436_ledpath['fan'], 3) + else: + system_bright_leds(cs6436_ledpath['fan'], 1) + + return (fanstatus != 0) + + +def system_misc_polling(threadName,delay): for count in range(1,5): if device_exist() == False: time.sleep(delay+3) @@ -62,93 +525,50 @@ def system_misc_polling(threadName,delay): if count == 4: return - + status, output = log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::sys/brightness", 1) status, output = log_os_system("hwconfig -cfp 1", 1) + global AGFlag + if os.access(ageing_controlfile, os.F_OK): + AGFlag = 1 + else: + AGFlag = 0 + + os.system('csw_daemon &') + + + global cs6436_fanattrnodes + global cs6436_psuattrnodes + + for num in range(1,6): + name = 'fan{}'.format(num) + fannode = cs6436_fanattr(name) + cs6436_fanattrnodes.append(fannode) + for num in range(1,3): + name = 'psu{}'.format(num) + psunode = cs6436_psuattr(name) + cs6436_psuattrnodes.append(psunode) + + tempcontrol = system_init_coretemppath() + + misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time()))) + count = 0 while 1: - status, output = log_os_system("cat /sys/bus/i2c/devices/5-005a/psu_present", 1) - if status: - print "failed to check status for 5-005a/psu_present" - continue - - if output=='1': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu1/brightness", 1) - else: - log_os_system("echo 0 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu1/brightness", 1) - - status, output = log_os_system("cat /sys/bus/i2c/devices/5-005b/psu_present", 1) - if status: - print "failed to check status for 5-005b/psu_present" - continue - - if output=='1': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu2/brightness", 1) - else: - log_os_system("echo 0 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu2/brightness", 1) - - status, fan1 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan1_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan1_fault" - continue - - if fan1=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan1/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan1/brightness", 1) - - status, fan2 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan2_fault",1) - - if status: - print "failed to check status for cs6436_56p_fan/fan2_fault" - continue - - if fan2=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan2/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan2/brightness", 1) - - status, fan3 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan3_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan3_fault" - continue - - if fan3=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan3/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan3/brightness", 1) - - status, fan4 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan4_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan4_fault" - continue - - if fan4=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan4/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan4/brightness", 1) - - status, fan5 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan5_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan5_fault" - continue - - if fan5=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan5/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan5/brightness", 1) - - if fan1=='0' or fan2=='0' or fan3=='0' or fan4=='0' or fan5=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan/brightness", 1) + count = count + 1 + ret = system_check_psuspresent() + ret = system_check_fansstate() + + if count % 10 == 0: + misclogger.info(": adjust fans and check psu direction.") + system_check_psusdirection() + if tempcontrol == 0: + system_monitor_temperature() + count = 0 time.sleep(delay) - print "%s: %s" % ( threadName, time.ctime(time.time())) + return if __name__ == '__main__': - target=system_misc_polling("Thread-misc",3) - - - + target=system_misc_polling("Thread-misc",10) diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py index 2b64d2e107b9..86285c7e4106 100755 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py @@ -21,13 +21,13 @@ options: -h | --help : this help message -d | --debug : run with debug mode - -f | --force : ignore error during installation or clean + -f | --force : ignore error during installation or clean command: install : install drivers and generate related sysfs nodes clean : uninstall drivers and remove related sysfs nodes show : show all systen status sff : dump SFP eeprom - set : change board setting with fan|led|sfp + set : change board setting with fan|led|sfp """ import os @@ -42,47 +42,48 @@ PROJECT_NAME = 'cs6436_56p' -version = '0.1.0' +version = '0.1.1' verbose = False DEBUG = False args = [] -ALL_DEVICE = {} +ALL_DEVICE = {} DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':56} FORCE = 0 +CPU_TYPE = 'C3308' if DEBUG == True: print sys.argv[0] - print 'ARGV :', sys.argv[1:] + print 'ARGV :', sys.argv[1:] def main(): global DEBUG global args global FORCE - + if len(sys.argv)<2: show_help() - + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', 'debug', 'force', ]) - if DEBUG == True: + if DEBUG == True: print options print args print len(sys.argv) - + for opt, arg in options: if opt in ('-h', '--help'): show_help() - elif opt in ('-d', '--debug'): + elif opt in ('-d', '--debug'): DEBUG = True logging.basicConfig(level=logging.INFO) - elif opt in ('-f', '--force'): + elif opt in ('-f', '--force'): FORCE = 1 else: - logging.info('no option') - for arg in args: + logging.info('no option') + for arg in args: if arg == 'install': do_install() elif arg == 'clean': @@ -92,23 +93,23 @@ def main(): elif arg == 'sff': if len(args)!=2: show_eeprom_help() - elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: show_eeprom_help() else: - show_eeprom(args[1]) - return + show_eeprom(args[1]) + return elif arg == 'set': if len(args)<3: show_set_help() else: - set_device(args[1:]) - return + set_device(args[1:]) + return else: show_help() - - - return 0 - + + + return 0 + def show_help(): print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} sys.exit(0) @@ -117,31 +118,31 @@ def show_set_help(): cmd = sys.argv[0].split("/")[-1]+ " " + args[0] print cmd +" [led|sfp|fan]" print " use \""+ cmd + " led 0-4 \" to set led color" - print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" - print " use \""+ cmd + " sfp 1-56 {0|1}\" to set sfp# tx_disable" - sys.exit(0) - + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-56 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + def show_eeprom_help(): cmd = sys.argv[0].split("/")[-1]+ " " + args[0] - print " use \""+ cmd + " 1-56 \" to dump sfp# eeprom" - sys.exit(0) - + print " use \""+ cmd + " 1-56 \" to dump sfp# eeprom" + sys.exit(0) + def my_log(txt): if DEBUG == True: - print "[ROY]"+txt + print "[ROY]"+txt return - + def log_os_system(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) my_log (cmd +"with result:" + str(status)) - my_log (" output:"+output) + my_log (" output:"+output) if status: logging.info('Failed :'+cmd) if show: print('Failed :'+cmd) return status, output - + def driver_check(): for count in range(1,5): time.sleep(1) @@ -154,11 +155,11 @@ def driver_check(): if len(lsmod) > 2: log_os_system("rmmod i2c_designware_platform", 0) log_os_system("modprobe i2c-designware-platform", 0) - + ret, lsmod = log_os_system("lsmod| grep cig", 0) logging.info('mods:'+lsmod) if len(lsmod) ==0: - return False + return False return True @@ -167,6 +168,7 @@ def driver_check(): 'depmod', 'modprobe i2c_dev', 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe x86-64-cig-cs6436-56p-sysfs ' , 'modprobe x86-64-cig-cs6436-56p-cpld ' , 'modprobe x86-64-cig-cs6436-56p-fan' , 'modprobe x86-64-cig-cs6436-56p-psu' , @@ -175,28 +177,31 @@ def driver_check(): def driver_install(): global FORCE - + for i in range(0,len(kos)): - if i == 3: - ret, board_type = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) - if board_type=='i3-6100U': - kos[i] =kos[i] + 'board_id=1' - + if i == 4: + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) + if CPU_TYPE=='i3-6100U': + kos[i] =kos[i] + 'board_id=1' + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0) + if CPU_TYPE=='C3758' or CPU_TYPE=='C3308': + kos[i] =kos[i] + 'board_id=2' + status, output = log_os_system(kos[i], 1) if status: - if FORCE == 0: - return status + if FORCE == 0: + return status return 0 - + def driver_uninstall(): global FORCE for i in range(0,len(kos)): rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") - rm = rm.replace("insmod", "rmmod") + rm = rm.replace("insmod", "rmmod") status, output = log_os_system(rm, 1) if status: - if FORCE == 0: - return status + if FORCE == 0: + return status return 0 led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' @@ -245,23 +250,22 @@ def driver_uninstall(): def device_install(): global FORCE - + for i in range(0,len(mknod)): - #for pca954x need times to built new i2c buses - if mknod[i].find('pca954') != -1: - time.sleep(1) - + #all nodes need times to built new i2c buses + time.sleep(1) + status, output = log_os_system(mknod[i], 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status - + for i in range(0,len(sfp_map)): status, output =log_os_system("echo cs6436_56p_sfp"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status if i <= 47: @@ -271,21 +275,21 @@ def device_install(): if FORCE == 0: return status - return - + return + def device_uninstall(): global FORCE - + for i in range(0,len(sfp_map)): target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" status, output =log_os_system("echo 0x50 > "+ target, 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status - + nodelist = mknod - + for i in range(len(nodelist)): target = nodelist[-(i+1)] temp = target.split() @@ -294,129 +298,129 @@ def device_uninstall(): status, output = log_os_system(" ".join(temp), 1) if status: print output - if FORCE == 0: - return status - - return - + if FORCE == 0: + return status + + return + def system_ready(): if driver_check() == False: return False - if not device_exist(): + if not device_exist(): return False return True - + def do_install(): print "Checking system...." if driver_check() == False: - print "No driver, installing...." + print "No driver, installing...." status = driver_install() if status: - if FORCE == 0: + if FORCE == 0: return status else: - print PROJECT_NAME.upper()+" drivers detected...." + print PROJECT_NAME.upper()+" drivers detected...." if not device_exist(): - print "No device, installing...." - status = device_install() + print "No device, installing...." + status = device_install() if status: - if FORCE == 0: - return status + if FORCE == 0: + return status else: - print PROJECT_NAME.upper()+" devices detected...." + print PROJECT_NAME.upper()+" devices detected...." return - + def do_uninstall(): print "Checking system...." if not device_exist(): - print PROJECT_NAME.upper() +" has no device installed...." + print PROJECT_NAME.upper() +" has no device installed...." else: - print "Removing device...." - status = device_uninstall() + print "Removing device...." + status = device_uninstall() if status: - if FORCE == 0: - return status - + if FORCE == 0: + return status + if driver_check()== False : print PROJECT_NAME.upper() +" has no driver installed...." else: print "Removing installed driver...." status = driver_uninstall() if status: - if FORCE == 0: - return status - - return + if FORCE == 0: + return status + + return def devices_info(): global DEVICE_NO global ALL_DEVICE global i2c_bus, hwmon_types, fan_types - for key in DEVICE_NO: - ALL_DEVICE[key]= {} + for key in DEVICE_NO: + ALL_DEVICE[key]= {} for i in range(0,DEVICE_NO[key]): ALL_DEVICE[key][key+str(i+1)] = [] - + for key in i2c_bus: buses = i2c_bus[key] - nodes = i2c_nodes[key] + nodes = i2c_nodes[key] for i in range(0,len(buses)): for j in range(0,len(nodes)): if 'sfp' == key: for k in range(0,DEVICE_NO[key]): node = key+str(k+1) - path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) + ALL_DEVICE[key][node].append(path) else: node = key+str(i+1) - path = i2c_prefix+ buses[i]+"/"+ nodes[j] + path = i2c_prefix+ buses[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) - + ALL_DEVICE[key][node].append(path) + for key in hwmon_types: itypes = hwmon_types[key] - nodes = hwmon_nodes[key] + nodes = hwmon_nodes[key] for i in range(0,len(itypes)): - for j in range(0,len(nodes)): + for j in range(0,len(nodes)): node = key+"_"+itypes[i] - path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][ key+str(i+1)].append(path) + ALL_DEVICE[key][ key+str(i+1)].append(path) for key in fan_types: itypes = fan_types[key] - nodes = fan_nodes[key] + nodes = fan_nodes[key] for i in range(0,len(itypes)): - for j in range(0,len(nodes)): + for j in range(0,len(nodes)): node = key+"_"+itypes[i] - path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] + path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] my_log(node+": "+ path) ALL_DEVICE[key][ key+str(i+1)].append(path) - + #show dict all in the order if DEBUG == True: for i in sorted(ALL_DEVICE.keys()): print(i+": ") - for j in sorted(ALL_DEVICE[i].keys()): + for j in sorted(ALL_DEVICE[i].keys()): print(" "+j) - for k in (ALL_DEVICE[i][j]): + for k in (ALL_DEVICE[i][j]): print(" "+" "+k) - return - + return + def show_eeprom(index): if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: - devices_info() + devices_info() node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] node = node.replace(node.split("/")[-1], 'sfp_eeprom') # check if got hexdump command in current environment ret, log = log_os_system("which hexdump", 0) - ret, log2 = log_os_system("which busybox hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) if len(log): hex_cmd = 'hexdump' elif len(log2): @@ -425,109 +429,123 @@ def show_eeprom(index): log = 'Failed : no hexdump cmd!!' logging.info(log) print log - return 1 - + return 1 + print node + ":" ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) - if ret==0: - print log + if ret==0: + print log else: - print "**********device no found**********" - return - + print "**********device no found**********" + return + def set_device(args): global DEVICE_NO global ALL_DEVICE if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: - devices_info() - + devices_info() + if args[0]=='led': if int(args[1])>4: show_set_help() return #print ALL_DEVICE['led'] - for i in range(0,len(ALL_DEVICE['led'])): - for k in (ALL_DEVICE['led']['led'+str(i+1)]): + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): ret, log = log_os_system("echo "+args[1]+" >"+k, 1) if ret: - return ret + return ret elif args[0]=='fan': if int(args[1])>100: show_set_help() return #print ALL_DEVICE['fan'] - #fan1~6 is all fine, all fan share same setting - node = ALL_DEVICE['fan'] ['fan1'][0] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') - ret, log = log_os_system("cat "+ node, 1) + ret, log = log_os_system("cat "+ node, 1) if ret==0: - print ("Previous fan duty: " + log.strip() +"%") + print ("Previous fan duty: " + log.strip() +"%") ret, log = log_os_system("echo "+args[1]+" >"+node, 1) if ret==0: - print ("Current fan duty: " + args[1] +"%") + print ("Current fan duty: " + args[1] +"%") return ret elif args[0]=='sfp': if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: show_set_help() - return + return if len(args)<2: show_set_help() - return - + return + if int(args[2])>1: show_set_help() return - - #print ALL_DEVICE[args[0]] - for i in range(0,len(ALL_DEVICE[args[0]])): - for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: - if j.find('tx_disable')!= -1: + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) if ret: - return ret - + return ret + return def get_value(input): digit = re.findall('\d+', input) return int(digit[0]) - + + +def get_ledname(ledx): + name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'} + if name_table.has_key(ledx): + name = name_table[ledx] + else: + name = ledx + return name + + def device_traversal(): if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: devices_info() for i in sorted(ALL_DEVICE.keys()): - print("============================================") + print("============================================") print(i.upper()+": ") print("============================================") - - for j in sorted(ALL_DEVICE[i].keys(), key=get_value): - print " "+j+":", + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + nwnamex = get_ledname(j) + if nwnamex == j: + print " "+j+":", + else: + print " "+nwnamex+":", for k in (ALL_DEVICE[i][j]): ret, log = log_os_system("cat "+k, 0) func = k.split("/")[-1].strip() func = re.sub(j+'_','',func,1) - func = re.sub(i.lower()+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) if ret==0: - print func+"="+log+" ", + print func+"="+log+" ", else: print func+"="+"X"+" ", - print + print print("----------------------------------------------------------------") - - + + print return - + def device_exist(): ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0) diff --git a/platform/nephos/sonic-platform-modules-cig/debian/changelog b/platform/nephos/sonic-platform-modules-cig/debian/changelog old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/debian/compat b/platform/nephos/sonic-platform-modules-cig/debian/compat old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/debian/control b/platform/nephos/sonic-platform-modules-cig/debian/control old mode 100755 new mode 100644 index 356ce313ab63..bf40791b24e0 --- a/platform/nephos/sonic-platform-modules-cig/debian/control +++ b/platform/nephos/sonic-platform-modules-cig/debian/control @@ -7,5 +7,15 @@ Standards-Version: 3.9.3 Package: sonic-platform-cig-cs6436-56p Architecture: amd64 -Depends: linux-image-4.9.0-9-amd64 +Depends: linux-image-4.9.0-11-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-cig-cs6436-54p +Architecture: amd64 +Depends: linux-image-4.9.0-11-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-cig-cs5435-54p +Architecture: amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-cig/debian/rules b/platform/nephos/sonic-platform-modules-cig/debian/rules index 3192948cc08d..b9ca7642b8bd 100755 --- a/platform/nephos/sonic-platform-modules-cig/debian/rules +++ b/platform/nephos/sonic-platform-modules-cig/debian/rules @@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-cig KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= cs6436-56p +MODULE_DIRS:= cs6436-56p cs6436-54p cs5435-54p MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service @@ -59,11 +59,12 @@ binary-indep: # Custom package commands (for mod in $(MODULE_DIRS); do \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin; \ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/etc/sonic; \ cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.py debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ done) From 2626565afbfdb2fd863d7eac2e82cb98639934d5 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar T <53558409+santhosh-kt@users.noreply.github.com> Date: Tue, 18 Feb 2020 13:32:33 +0530 Subject: [PATCH 0383/1427] [DellEMC] S6100 Last Reboot Reason Thermal Support (#3767) --- files/image_config/platform/rc.local | 6 + .../common/nvram_rd_wr.py | 97 ++++++++++ .../debian/platform-modules-s6100.install | 5 + .../s6100/scripts/fast-reboot_plugin | 6 + .../s6100/scripts/platform_reboot_override | 7 + .../s6100/scripts/s6100_platform.sh | 22 +-- .../s6100/scripts/track_reboot_reason.sh | 168 ++++++++++++++++++ .../s6100/scripts/warm-reboot_plugin | 1 + .../s6100/sonic_platform/chassis.py | 49 ++--- .../s6100/sonic_platform/eeprom.py | 8 +- .../s6100/systemd/s6100-reboot-cause.service | 12 ++ 11 files changed, 337 insertions(+), 44 deletions(-) create mode 100755 platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh create mode 120000 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/warm-reboot_plugin create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6100/systemd/s6100-reboot-cause.service diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index e36b20950b42..2884270b7870 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -240,6 +240,12 @@ if [ -f $FIRST_BOOT_FILE ]; then # Notify firstboot to Platform, to use it for reboot-cause touch /tmp/notify_firstboot_to_platform + # Create /host/reboot-cause/platform/ directory + # can be used to track last reboot reason by some platforms + if [ ! -d /host/reboot-cause/platform ]; then + mkdir -p /host/reboot-cause/platform + fi + if [ -d /host/image-$SONIC_VERSION/platform/$platform ]; then dpkg -i /host/image-$SONIC_VERSION/platform/$platform/*.deb fi diff --git a/platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py b/platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py new file mode 100755 index 000000000000..30108892741b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py @@ -0,0 +1,97 @@ +#!/usr/bin/python +#Script to read/write the nvram + +import sys +import os +import getopt +import struct + +nvram_resource='/dev/nvram' + +def usage(): + ''' This is the Usage Method ''' + + print 'Utility for NVRAM read/write' + print '\t\t nvram_rd_wr.py --get --offset ' + print '\t\t nvram_rd_wr.py --set --val --offset ' + sys.exit(1) + +def nvram_reg_read(nvram_resource,offset): + fd=os.open(nvram_resource, os.O_RDONLY) + if(fd<0): + print 'file open failed %s"%nvram_resource' + return + if(os.lseek(fd, offset, os.SEEK_SET) != offset): + print 'lseek failed on %s'%nvram_resource + return + buf=os.read(fd,1) + reg_val1=ord(buf) + print 'value %x'%reg_val1 + os.close(fd) + +def nvram_reg_write(nvram_resource,offset,val): + fd=os.open(nvram_resource,os.O_RDWR) + if(fd<0): + print 'file open failed %s"%nvram_resource' + return + if(os.lseek(fd, offset, os.SEEK_SET) != offset): + print 'lseek failed on %s'%nvram_resource + return + ret=os.write(fd,struct.pack('B',val)) + if(ret != 1): + print 'write failed %d'%ret + return + os.close(fd) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resouce = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgs:" , \ + ["val=","offset=","help", "get", "set"]) + + except getopt.GetoptError: + usage() + + if not os.path.exists(nvram_resource): + print 'NVRAM is not initialized' + sys.exit(1) + + for opt,arg in opts: + + if opt in ('-h','--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--offset': + offset = int(arg,16) - 0xE + + elif opt == '--val': + val = int(arg,16) + + if choice == 'get' and offset != '': + nvram_reg_read(nvram_resource,offset) + + elif choice == 'set' and offset != '' and val != '': + nvram_reg_write(nvram_resource,offset,val) + + else: + usage() + +#Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install index eb0211b3afde..a08f782bdfad 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install @@ -2,7 +2,11 @@ s6100/scripts/iom_power_*.sh usr/local/bin s6100/scripts/s6100_platform.sh usr/local/bin common/dell_i2c_utils.sh usr/local/bin common/io_rd_wr.py usr/local/bin +common/nvram_rd_wr.py usr/local/bin s6100/scripts/platform_reboot_override usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 +s6100/scripts/fast-reboot_plugin usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 +s6100/scripts/track_reboot_reason.sh usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 +s6100/scripts/warm-reboot_plugin usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 s6100/scripts/override.conf /etc/systemd/system/systemd-reboot.service.d common/dell_lpc_mon.sh usr/local/bin s6100/scripts/platform_sensors.py usr/local/bin @@ -12,6 +16,7 @@ s6100/scripts/platform_watchdog_disable.sh usr/local/bin s6100/scripts/sensors usr/bin s6100/systemd/platform-modules-s6100.service etc/systemd/system s6100/systemd/s6100-lpc-monitor.service etc/systemd/system +s6100/systemd/s6100-reboot-cause.service etc/systemd/system tools/flashrom/flashrom usr/local/bin/ common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin new file mode 100755 index 000000000000..d385be3bc685 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin @@ -0,0 +1,6 @@ +#!/bin/bash + +if [[ -d /sys/devices/platform/SMF.512/hwmon/ ]]; then + cd /sys/devices/platform/SMF.512/hwmon/* + echo 0xcc > mb_poweron_reason +fi diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override index 3e165630658b..dcec8067054a 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override @@ -1,11 +1,17 @@ #!/usr/bin/python import sys import os +import subprocess import struct PORT_RES = '/dev/port' +def log_software_reboot(): + # Run plugin script which will track the cli triggered reboot, fastboot, warmboot + res = subprocess.check_output(['/usr/share/sonic/device/x86_64-dell_s6100_c2538-r0/fast-reboot_plugin']) + return + def portio_reg_write(resource, offset, val): fd = os.open(resource, os.O_RDWR) if(fd < 0): @@ -21,5 +27,6 @@ def portio_reg_write(resource, offset, val): os.close(fd) if __name__ == "__main__": + log_software_reboot() portio_reg_write(PORT_RES, 0xcf9, 0xe) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh index 8533d9a198e2..1d974f64504a 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -237,24 +237,6 @@ reset_muxes() { io_rd_wr.py --set --val 0xff --offset 0x20b } -track_reboot_reason() { - if [[ -d /sys/devices/platform/SMF.512/hwmon/ ]]; then - rv=$(cd /sys/devices/platform/SMF.512/hwmon/*; cat mb_poweron_reason) - reason=$(echo $rv | cut -d 'x' -f2) - if [ $reason == "ff" ]; then - cd /sys/devices/platform/SMF.512/hwmon/* - if [[ -e /tmp/notify_firstboot_to_platform ]]; then - echo 0x01 > mb_poweron_reason - else - echo 0xbb > mb_poweron_reason - fi - elif [ $reason == "bb" ] || [ $reason == "1" ]; then - cd /sys/devices/platform/SMF.512/hwmon/* - echo 0xaa > mb_poweron_reason - fi - fi -} - install_python_api_package() { device="/usr/share/sonic/device" platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) @@ -277,7 +259,8 @@ if [[ "$1" == "init" ]]; then modprobe dell_ich modprobe dell_s6100_iom_cpld modprobe dell_s6100_lpc - track_reboot_reason + modprobe nvram + systemctl start s6100-reboot-cause.service # Disable Watchdog Timer if [[ -e /usr/local/bin/platform_watchdog_disable.sh ]]; then @@ -313,6 +296,7 @@ elif [[ "$1" == "deinit" ]]; then modprobe -r i2c-mux-pca954x modprobe -r i2c-dev modprobe -r dell_ich + modprobe -r nvram remove_python_api_package else echo "s6100_platform : Invalid option !" diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh new file mode 100755 index 000000000000..0686d577c9e4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh @@ -0,0 +1,168 @@ +#!/bin/bash + +reboot_dir_found=false +reboot_file_found=false +smf_dir_missing=0 +nvram_missing=0 + +REBOOT_CAUSE_FILE=/host/reboot-cause/reboot-cause.txt +REBOOT_REASON_FILE=/host/reboot-cause/platform/reboot_reason +BIOS_VERSION_FILE=/host/reboot-cause/platform/bios_minor_version +SMF_POWERON_REASON=/sys/devices/platform/SMF.512/hwmon/*/smf_poweron_reason +SMF_RESET_REASON=/sys/devices/platform/SMF.512/hwmon/*/smf_reset_reason +MAILBOX_POWERON_REASON=/sys/devices/platform/SMF.512/hwmon/*/mb_poweron_reason +NVRAM_DEVICE_FILE=/dev/nvram +RESET_REASON_FILE=/host/reboot-cause/platform/reset_reason +SMF_DIR=/sys/devices/platform/SMF.512/hwmon/ + +while [[ ! -d $SMF_DIR ]] +do + sleep 0.5 + let smf_dir_missing=$smf_dir_missing+1 + if [[ "$smf_dir_missing" = "5" ]]; then + echo "SMF is not initialized" + smf_dir_missing=0 + fi +done + +SMF_RESET=$(cat $SMF_RESET_REASON) + +if [[ -d /host/reboot-cause/platform ]]; then + reboot_dir_found=true + if [[ -f $REBOOT_REASON_FILE ]]; then + reboot_file_found=true + fi +fi + +SMF_BIOS_REG=$(io_rd_wr.py --get --offset 0x203 | cut -d " " -f 3) +SMF_BIOS_REG=$((16#$SMF_BIOS_REG)) +bios_secondary_boot=$(($SMF_BIOS_REG & 1)) + +_get_smf_reset_register(){ + BIOS_VERSION=$(/usr/sbin/dmidecode -s system-version) + BIOS_VERSION_MINOR=$(echo $BIOS_VERSION | cut -d'-' -f 2) + + if [[ $BIOS_VERSION_MINOR -gt 7 ]]; then + echo $BIOS_VERSION > $BIOS_VERSION_FILE + elif [[ "$bios_secondary_boot" = "0" ]]; then + # For Primary BIOS with older version + if [[ -e $BIOS_VERSION_FILE ]]; then + rm $BIOS_VERSION_FILE + fi + fi + + if [[ -e $BIOS_VERSION_FILE ]]; then + while [[ ! -e $NVRAM_DEVICE_FILE ]] + do + sleep 1 + let nvram_missing=$nvram_missing+1 + if [[ "$nvram_missing" = "5" ]]; then + echo "NVRAM is not initialized" + nvram_missing=0 + fi + done + first_reset=$(nvram_rd_wr.py --get --offset 0x5c | cut -d " " -f 2) + second_reset=$(nvram_rd_wr.py --get --offset 0x5d | cut -d " " -f 2) + third_reset=$(nvram_rd_wr.py --get --offset 0x5e | cut -d " " -f 2) + fourth_reset=$(nvram_rd_wr.py --get --offset 0x5f | cut -d " " -f 2) + + if [[ "$first_reset" != "ee" ]]; then + SMF_RESET=$first_reset + fi + + # Saving NVRAM values for future debugging + if [[ $reboot_dir_found = true ]]; then + echo "First reset - $first_reset" > $RESET_REASON_FILE + echo "Second reset - $second_reset" >> $RESET_REASON_FILE + echo "Third reset - $third_reset" >> $RESET_REASON_FILE + echo "Fourth reset - $fourth_reset" >> $RESET_REASON_FILE + fi + + # Clearing NVRAM values to holding next reset values + nvram_rd_wr.py --set --val 0xee --offset 0x58 + nvram_rd_wr.py --set --val 0xee --offset 0x5c + nvram_rd_wr.py --set --val 0xee --offset 0x5d + nvram_rd_wr.py --set --val 0xee --offset 0x5e + nvram_rd_wr.py --set --val 0xee --offset 0x5f + fi +} + +_is_thermal_reset() { + prev_thermal=$(cat $REBOOT_REASON_FILE) + curr_poweron_reason=$(cat $SMF_POWERON_REASON) + if [[ $curr_poweron_reason = "11" ]]; then + echo 0 + return + fi + if [[ $prev_thermal = $curr_poweron_reason ]]; then + echo 2 + return + else + echo "$curr_poweron_reason" > $REBOOT_REASON_FILE + echo 1 + return + fi + + echo 0 + return +} + +_is_watchdog_reset(){ + curr_reset_reason=$SMF_RESET + if [[ $curr_reset_reason = "33" ]]; then + echo 1 + return + fi + + echo 0 + return +} + +_is_unknown_reset(){ + if [[ -f $REBOOT_CAUSE_FILE ]]; then + if [[ $1 = 0 ]]; then + echo "Unknown software reboot" > $REBOOT_CAUSE_FILE + return + fi + curr_poweron_reason=$(cat $SMF_POWERON_REASON) + curr_reset_reason=$SMF_RESET + mb_poweron_reason=$(cat $MAILBOX_POWERON_REASON) + echo "Unknown POR: $curr_poweron_reason RST: $curr_reset_reason MBR: $mb_poweron_reason" > $REBOOT_CAUSE_FILE + fi + +} + +update_mailbox_register(){ + if [[ "$bios_secondary_boot" = "1" ]]; then + echo "Secondary BIOS booted" + fi + + if [[ $reboot_file_found = false ]]; then + echo "None" > $REBOOT_REASON_FILE + fi + + _get_smf_reset_register + if [[ -d /sys/devices/platform/SMF.512/hwmon/ ]]; then + is_thermal_reboot=$(_is_thermal_reset) + + is_wd_reboot=$(_is_watchdog_reset) + + mbr=$(cat $MAILBOX_POWERON_REASON) + reason=$(echo $mbr | cut -d 'x' -f2) + if [[ $reason = "ff" ]]; then + echo "None" > $REBOOT_REASON_FILE + echo 0xbb > $MAILBOX_POWERON_REASON + elif [[ $is_thermal_reboot = 1 ]]; then + echo 0xee > $MAILBOX_POWERON_REASON + elif [[ $is_wd_reboot = 1 ]] && [[ $reason != "cc" ]]; then + echo 0xdd > $MAILBOX_POWERON_REASON + elif [[ $reason = "cc" ]]; then + echo 0xaa > $MAILBOX_POWERON_REASON + else + _is_unknown_reset $is_thermal_reboot + echo 0x99 > $MAILBOX_POWERON_REASON + fi + fi +} + +update_mailbox_register diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/warm-reboot_plugin b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/warm-reboot_plugin new file mode 120000 index 000000000000..180742bbc4d5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/warm-reboot_plugin @@ -0,0 +1 @@ +fast-reboot_plugin \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py index ec1848fc8dca..a1c7692b5f6e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py @@ -18,7 +18,9 @@ from sonic_platform.module import Module from sonic_platform.thermal import Thermal from sonic_platform.component import Component + from sonic_platform.watchdog import Watchdog from eeprom import Eeprom + import time except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -43,6 +45,8 @@ class Chassis(ChassisBase): reset_reason_dict[33] = ChassisBase.REBOOT_CAUSE_WATCHDOG reset_reason_dict[44] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE reset_reason_dict[55] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE + reset_reason_dict[66] = ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER + reset_reason_dict[77] = ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER power_reason_dict = {} power_reason_dict[11] = ChassisBase.REBOOT_CAUSE_POWER_LOSS @@ -76,10 +80,15 @@ def __init__(self): component = Component(i) self._component_list.append(component) + self._watchdog = Watchdog() + def _get_reboot_reason_smf_register(self): - # Returns 0xAA on software reload - # Returns 0xFF on power-cycle - # Returns 0x01 on first-boot + # In S6100, mb_poweron_reason register will + # Returns 0xaa or 0xcc on software reload + # Returns 0xff or 0xbb on power-cycle + # Returns 0xdd on Watchdog + # Returns 0xee on Thermal Shutdown + # Returns 0x99 on Unknown reset smf_mb_reg_reason = self._get_pmc_register('mb_poweron_reason') return int(smf_mb_reg_reason, 16) @@ -188,27 +197,21 @@ def get_reboot_cause(self): power_reason = int(self._get_pmc_register('smf_poweron_reason')) smf_mb_reg_reason = self._get_reboot_reason_smf_register() - if ((smf_mb_reg_reason == 0x01) and (power_reason == 0x11)): + if ((smf_mb_reg_reason == 0xbb) or (smf_mb_reg_reason == 0xff)): + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif ((smf_mb_reg_reason == 0xaa) or (smf_mb_reg_reason == 0xcc)): return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) - - # Reset_Reason = 11 ==> PowerLoss - # So return the reboot reason from Last Power_Reason Dictionary - # If Reset_Reason is not 11 return from Reset_Reason dictionary - # Also check if power_reason, reset_reason are valid values by - # checking key presence in dictionary else return - # REBOOT_CAUSE_HARDWARE_OTHER as the Power_Reason and Reset_Reason - # registers returned invalid data - - # In S6100, if Reset_Reason is not 11 and smf_mb_reg_reason - # is ff or bb, then it is PowerLoss - if (reset_reason == 11): - if (power_reason in self.power_reason_dict): - return (self.power_reason_dict[power_reason], None) + elif (smf_mb_reg_reason == 0xdd): + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif (smf_mb_reg_reason == 0xee): + return (self.power_reason_dict[power_reason], None) + elif (reset_reason == 66): + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, + "Emulated Cold Reset") + elif (reset_reason == 77): + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, + "Emulated Warm Reset") else: - if ((smf_mb_reg_reason == 0xbb) or (smf_mb_reg_reason == 0xff)): - return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) - - if (reset_reason in self.reset_reason_dict): - return (self.reset_reason_dict[reset_reason], None) + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py index 8bd900b6c26b..d281783827b6 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py @@ -35,9 +35,13 @@ def __init__(self, i2c_line=0, iom_eeprom=False): else: self.eeprom_data = self.read_eeprom() except: - self.eeprom_data = "N/A" if not self.is_module: - raise RuntimeError("Eeprom is not Programmed") + try: + self.eeprom_data = self.read_eeprom() + except: + raise RuntimeError("Eeprom is not Programmed") + else: + self.eeprom_data = "N/A" else: eeprom = self.eeprom_data diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/s6100-reboot-cause.service b/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/s6100-reboot-cause.service new file mode 100644 index 000000000000..bcf903d56d80 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/s6100-reboot-cause.service @@ -0,0 +1,12 @@ +[Unit] +Description=Read Dell S6100 reboot cause +Before=process-reboot-cause.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/share/sonic/device/x86_64-dell_s6100_c2538-r0/track_reboot_reason.sh +RemainAfterExit=no + +[Install] +WantedBy=multi-user.target From 236013142c39e70ceafaac846f06c73877c10322 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Thu, 20 Feb 2020 11:20:50 -0800 Subject: [PATCH 0384/1427] [frr] Update FRR build to include version tags (#4172) Signed-off-by: Danny Allen --- rules/frr.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/frr.mk b/rules/frr.mk index 6dc25b30dfff..0ef1296cb7b5 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -4,7 +4,7 @@ FRR_VERSION = 7.2.1 FRR_SUBVERSION = 0 FRR_BRANCH = frr/7.2 FRR_TAG = frr-7.2.1-s2 -export FRR_VERSION FRR_SUBVERSION FRR_BRANCH +export FRR_VERSION FRR_SUBVERSION FRR_BRANCH FRR_TAG FRR = frr_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_$(CONFIGURED_ARCH).deb From 7ffa2ccb435ea04199c407d97c640a27dbd847ac Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 20 Feb 2020 12:54:39 -0800 Subject: [PATCH 0385/1427] Sleep done before mismatch handler (#4165) * Sleep done before mismatch handler --- files/scripts/arp_update | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/scripts/arp_update b/files/scripts/arp_update index 4c7d655cfdaf..3cc9cd267985 100755 --- a/files/scripts/arp_update +++ b/files/scripts/arp_update @@ -47,6 +47,9 @@ while /bin/true; do eval `eval $ip6cmd` done + # sleep here before handling the mismatch as it is not required during startup + sleep 300 + # refresh neighbor entries from APP_DB in case of mismatch with kernel DBNEIGH=$(sonic-db-cli APPL_DB keys NEIGH_TABLE*) KERNEIGH4=$(ip -4 neigh show | grep Vlan | cut -d ' ' -f 1,3 --output-delimiter=',') @@ -67,5 +70,4 @@ while /bin/true; do fi done - sleep 300 done From 6005f4c976dd15d897ca0e1a8c51e269864ac493 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Thu, 20 Feb 2020 13:47:21 -0800 Subject: [PATCH 0386/1427] Revert "Update frr to latest 7.2.1 (#4145)" (#4170) This reverts commit 4b42a48f452515422ad8f9bd8bb4afef0b4358a2. --- rules/frr.mk | 2 +- src/sonic-frr/frr | 2 +- ...nexthops-compare-vrf-only-if-ip-type.patch | 73 +++++++++++++++++++ src/sonic-frr/patch/series | 1 + 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch diff --git a/rules/frr.mk b/rules/frr.mk index 0ef1296cb7b5..6b2e92fcbd2e 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -3,7 +3,7 @@ FRR_VERSION = 7.2.1 FRR_SUBVERSION = 0 FRR_BRANCH = frr/7.2 -FRR_TAG = frr-7.2.1-s2 +FRR_TAG = frr-7.2.1-s1 export FRR_VERSION FRR_SUBVERSION FRR_BRANCH FRR_TAG diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index e1b0c939960c..90446e3c3310 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit e1b0c939960c49eba05e972a68d50ca32dd09303 +Subproject commit 90446e3c3310001a7b84017fa4b237ea7914f45e diff --git a/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch b/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch new file mode 100644 index 000000000000..343f1b3262d9 --- /dev/null +++ b/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch @@ -0,0 +1,73 @@ +From 2f0b5aef66316b47d2cc8ac18453600621a6a317 Mon Sep 17 00:00:00 2001 +From: Tyler Li +Date: Thu, 14 Nov 2019 23:46:52 -0800 +Subject: [PATCH] nexthops compare vrf only if ip type + +--- + lib/nexthop.c | 12 ++++++------ + lib/zclient.c | 12 ++++++------ + 2 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/lib/nexthop.c b/lib/nexthop.c +index cf5bed3d6..7d9f646c9 100644 +--- a/lib/nexthop.c ++++ b/lib/nexthop.c +@@ -105,12 +105,6 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, + { + int ret = 0; + +- if (next1->vrf_id < next2->vrf_id) +- return -1; +- +- if (next1->vrf_id > next2->vrf_id) +- return 1; +- + if (next1->type < next2->type) + return -1; + +@@ -120,6 +114,12 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, + switch (next1->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV6: ++ if (next1->vrf_id < next2->vrf_id) ++ return -1; ++ ++ if (next1->vrf_id > next2->vrf_id) ++ return 1; ++ + ret = _nexthop_gateway_cmp(next1, next2); + if (ret != 0) + return ret; +diff --git a/lib/zclient.c b/lib/zclient.c +index c739af043..0d37c46d1 100644 +--- a/lib/zclient.c ++++ b/lib/zclient.c +@@ -783,12 +783,6 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, + { + int ret = 0; + +- if (next1->vrf_id < next2->vrf_id) +- return -1; +- +- if (next1->vrf_id > next2->vrf_id) +- return 1; +- + if (next1->type < next2->type) + return -1; + +@@ -798,6 +792,12 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, + switch (next1->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV6: ++ if (next1->vrf_id < next2->vrf_id) ++ return -1; ++ ++ if (next1->vrf_id > next2->vrf_id) ++ return 1; ++ + ret = nexthop_g_addr_cmp(next1->type, &next1->gate, + &next2->gate); + if (ret != 0) +-- +2.11.0 + diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 233021ace50b..13619c87ff65 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -2,4 +2,5 @@ 0002-Reduce-severity-of-Vty-connected-from-message.patch 0003-Use-vrf_id-for-vrf-not-tabled_id.patch 0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch +0005-nexthops-compare-vrf-only-if-ip-type.patch 0006-changes-for-making-snmp-socket-non-blocking.patch From ab78ee0232573085c38973a5825776b1e8d9bd25 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Fri, 21 Feb 2020 00:49:28 +0200 Subject: [PATCH 0387/1427] [mgmt-framework] start after syncd (#4174) every service starts after syncd to start the most critical parts first Signed-off-by: Stepan Blyschak --- files/build_templates/mgmt-framework.service.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/mgmt-framework.service.j2 b/files/build_templates/mgmt-framework.service.j2 index d0a030347b51..acc938c13d90 100644 --- a/files/build_templates/mgmt-framework.service.j2 +++ b/files/build_templates/mgmt-framework.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=Management Framework container Requires=swss.service -After=swss.service +After=swss.service syncd.service Before=ntp-config.service [Service] From 30ef11198fb6fac52de38027944b2b64ea44aab8 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Fri, 21 Feb 2020 04:27:54 +0530 Subject: [PATCH 0388/1427] DellEMC: Z9264-Platform2.0 Implementation [Thermal] (#4175) --- .../z9264f/sonic_platform/chassis.py | 6 + .../z9264f/sonic_platform/thermal.py | 155 ++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py index 47649d0bccde..ecf0b39fb819 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py @@ -15,10 +15,12 @@ from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Eeprom from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal except ImportError as e: raise ImportError(str(e) + "- required module not found") MAX_Z9264F_PSU = 2 +MAX_Z9264F_THERMAL = 8 class Chassis(ChassisBase): @@ -58,6 +60,10 @@ def __init__(self): psu = Psu(i) self._psu_list.append(psu) + for i in range(MAX_Z9264F_THERMAL): + thermal = Thermal(i) + self._thermal_list.append(thermal) + for port_num in range(self.PORT_START, (self.PORT_END + 1)): presence = self.get_sfp(port_num).get_presence() if presence: diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py new file mode 100644 index 000000000000..58a39005b54e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9264 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + from sonic_platform_base.thermal_base import ThermalBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """DellEMC Platform-specific Thermal class""" + + # [ Sensor-Name, Sensor-ID ] + SENSOR_MAPPING = [ + ['CPU On-board', 0x6], + ['ASIC On-board', 0x8], + ['System Front Left', 0x3], + ['System Front Middle', 0x7], + ['System Front Right', 0x4], + ['Inlet Airflow Sensor', 0x5], + ['PSU1 Airflow Sensor', 0x2], + ['PSU2 Airflow Sensor', 0x1] + ] + + def __init__(self, thermal_index): + ThermalBase.__init__(self) + self.index = thermal_index + 1 + self.sensor = IpmiSensor(self.SENSOR_MAPPING[self.index - 1][1]) + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + return self.SENSOR_MAPPING[self.index - 1][0] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + Returns: + bool: True if thermal is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the Thermal + + Returns: + string: Model/part number of Thermal + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the Thermal + + Returns: + string: Serial number of Thermal + """ + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the thermal + + Returns: + A boolean value, True if thermal is operating properly, + False if not + """ + return True + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + is_valid, temperature = self.sensor.get_reading() + if not is_valid: + temperature = 0 + + return "{:.3f}".format(temperature) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + is_valid, high_threshold = self.sensor.get_threshold("UpperNonRecoverable") + if not is_valid: + high_threshold = 0 + + return "{:.3f}".format(high_threshold) + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + is_valid, low_threshold = self.sensor.get_threshold("LowerNonRecoverable") + if not is_valid: + low_threshold = 0 + + return "{:.3f}".format(low_threshold) + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False From fbc24b4279e6e57b6b73ccbedb64846719262baa Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 20 Feb 2020 19:16:14 -0800 Subject: [PATCH 0389/1427] [orchagent] Use mac address from config_db instead of from eth0 (#4166) * Use mac address from config_db instead of eth0 --- dockers/docker-orchagent/orchagent.sh | 6 +++++- platform/p4/docker-sonic-p4/orchagent.sh | 6 +++++- platform/vs/docker-sonic-vs/orchagent.sh | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 5e01cd480f52..3352e5fbb7ec 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -4,7 +4,11 @@ # vendor specific code. export platform=`sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type` -MAC_ADDRESS=`ip link show eth0 | grep ether | awk '{print $2}'` +MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then + MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') + logger "Mac address not found in Device Metadata, Falling back to eth0" +fi # Create a folder for SwSS record files mkdir -p /var/log/swss diff --git a/platform/p4/docker-sonic-p4/orchagent.sh b/platform/p4/docker-sonic-p4/orchagent.sh index 7e250dfa20e9..9abfc22c967e 100755 --- a/platform/p4/docker-sonic-p4/orchagent.sh +++ b/platform/p4/docker-sonic-p4/orchagent.sh @@ -1,6 +1,10 @@ #!/usr/bin/env bash -MAC_ADDRESS=`ip link show eth0 | grep ether | awk '{print $2}'` +MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then + MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') + logger "Mac address not found in Device Metadata, Falling back to eth0" +fi # Create a folder for SsWW record files mkdir -p /var/log/swss diff --git a/platform/vs/docker-sonic-vs/orchagent.sh b/platform/vs/docker-sonic-vs/orchagent.sh index d9bebf117346..2acd709a8e94 100755 --- a/platform/vs/docker-sonic-vs/orchagent.sh +++ b/platform/vs/docker-sonic-vs/orchagent.sh @@ -6,7 +6,11 @@ else export platform=$fake_platform fi -MAC_ADDRESS=`ip link show eth0 | grep ether | awk '{print $2}'` +MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then + MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') + logger "Mac address not found in Device Metadata, Falling back to eth0" +fi # Create a folder for SwSS record files mkdir -p /var/log/swss From f5ab24d8f120f41609bd6dd7c9635efcd51e2234 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 21 Feb 2020 10:20:07 -0800 Subject: [PATCH 0390/1427] Made Change to have Configurable option to enable/disable docker image (#4171) * Made Change to have Configurable option to enable/disable docker image * [Submodule-Update] sonic-utilities to latest master --- rules/config | 3 +++ rules/docker-nat.mk | 4 ++++ slave.mk | 7 +++++++ src/sonic-utilities | 2 +- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/rules/config b/rules/config index c8a24606f426..c168fa5a964e 100644 --- a/rules/config +++ b/rules/config @@ -107,3 +107,6 @@ ENABLE_MGMT_FRAMEWORK = y # ENABLE_RESTAPI - build docker-sonic-restapi for configuring the switch using REST APIs ENABLE_RESTAPI = n + +# ENABLE_NAT - build docker-sonic-nat for nat support +ENABLE_NAT = y diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk index f41c8f06647c..dcccc24ba2ff 100644 --- a/rules/docker-nat.mk +++ b/rules/docker-nat.mk @@ -13,13 +13,17 @@ $(DOCKER_NAT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_P $(DOCKER_NAT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +ifeq ($(ENABLE_NAT), y) SONIC_DOCKER_IMAGES += $(DOCKER_NAT) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_NAT) SONIC_STRETCH_DOCKERS += $(DOCKER_NAT) +endif +ifeq ($(ENABLE_NAT), y) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_NAT_DBG) +endif $(DOCKER_NAT)_CONTAINER_NAME = nat $(DOCKER_NAT)_RUN_OPT += --privileged -t diff --git a/slave.mk b/slave.mk index cc118da7aa06..71e6aeb3a866 100644 --- a/slave.mk +++ b/slave.mk @@ -116,6 +116,11 @@ ifeq ($(SONIC_ENABLE_SFLOW),y) ENABLE_SFLOW = y endif +ifeq ($(SONIC_ENABLE_NAT),y) +ENABLE_NAT = y +endif + + include $(RULES_PATH)/functions include $(RULES_PATH)/*.mk ifneq ($(CONFIGURED_PLATFORM), undefined) @@ -203,6 +208,7 @@ $(info "BUILD_TIMESTAMP" : "$(BUILD_TIMESTAMP)") $(info "BLDENV" : "$(BLDENV)") $(info "VS_PREPARE_MEM" : "$(VS_PREPARE_MEM)") $(info "ENABLE_SFLOW" : "$(ENABLE_SFLOW)") +$(info "ENABLE_NAT" : "$(ENABLE_NAT)") $(info ) ifeq ($(SONIC_USE_DOCKER_BUILDKIT),y) @@ -650,6 +656,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_system_telemetry="$(ENABLE_SYSTEM_TELEMETRY)" export enable_restapi="$(ENABLE_RESTAPI)" export enable_ztp="$(ENABLE_ZTP)" + export enable_nat="$(ENABLE_NAT)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" export installer_debs="$(addprefix $(STRETCH_DEBS_PATH)/,$($*_INSTALLS))" diff --git a/src/sonic-utilities b/src/sonic-utilities index 5214a8d66eb4..ea374a7aa20e 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 5214a8d66eb48b536e0b95e4ddc3b9879d0ce49f +Subproject commit ea374a7aa20edb3a1c3040f5c40422b44f896f3c From 52e3947487c9e0e505b915a87758d3d6cf457766 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Sat, 22 Feb 2020 07:22:43 -0800 Subject: [PATCH 0391/1427] Updated the file permission mode to include +x (#4183) This to avoid git status reporting dirty. Signed-off-by: Abhishek Dosi --- platform/broadcom/sonic-platform-modules-quanta/debian/rules | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 platform/broadcom/sonic-platform-modules-quanta/debian/rules diff --git a/platform/broadcom/sonic-platform-modules-quanta/debian/rules b/platform/broadcom/sonic-platform-modules-quanta/debian/rules old mode 100644 new mode 100755 From b85615458652eb202d4dd3d083c21ec5639a948b Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Sun, 23 Feb 2020 15:48:15 +0800 Subject: [PATCH 0392/1427] [Mellanox]Fix issue that syncd rpc docker unable to start (#4181) --- platform/mellanox/docker-syncd-mlnx-rpc.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.mk b/platform/mellanox/docker-syncd-mlnx-rpc.mk index 608c1bb3ad20..ed9eea9ae8f8 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc.mk +++ b/platform/mellanox/docker-syncd-mlnx-rpc.mk @@ -20,7 +20,7 @@ SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_MLNX_RPC) endif $(DOCKER_SYNCD_MLNX_RPC)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot From df623b7e3395944ecb2c773423b7a76e09331fef Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Mon, 24 Feb 2020 11:42:09 -0800 Subject: [PATCH 0393/1427] [sonic-py-swsssdk] update submodule for sonic-py-swsssdk (#4179) --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index ae2e038eebbe..df617345d807 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit ae2e038eebbea3f4c742395f76390b23c1394f83 +Subproject commit df617345d807bc01e3f5740fdfdc4b9799f1cf63 From 70657cb182776c9834cc81b90a82ac9fcd386f26 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Tue, 25 Feb 2020 10:25:31 +0200 Subject: [PATCH 0394/1427] [Mellanox] update hw-mgmt patch for SimX (#4180) Signed-off-by: Mykola Faryma --- .../0001-Make-hw-mgmt-SimX-compatiable.patch | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch index f16c0d02794b..ccbd6322d2e6 100644 --- a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch +++ b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch @@ -1,15 +1,15 @@ -From c6ee8c86c35f8b1e60bf4df0d7198f349f8552c1 Mon Sep 17 00:00:00 2001 -From: Stephen Sun -Date: Wed, 25 Dec 2019 19:33:17 +0800 -Subject: [PATCH] Make hw-mgmt SimX compatiable. +From 6aecc8fed8cc78c1fb5c6b52bdfa3d07ca66e652 Mon Sep 17 00:00:00 2001 +From: Mykola Faryma +Date: Fri, 21 Feb 2020 12:28:54 +0200 +Subject: [PATCH 1/1] Make hw-mgmt SimX compatiable -Signed-off-by: Stephen Sun +Signed-off-by: Mykola Faryma --- usr/usr/bin/hw-management.sh | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh -index cff10fe..0511c7c 100755 +index cff10fe..7f3c295 100755 --- a/usr/usr/bin/hw-management.sh +++ b/usr/usr/bin/hw-management.sh @@ -737,6 +737,35 @@ do_chip_down() @@ -40,7 +40,7 @@ index cff10fe..0511c7c 100755 + esac +} + -+if [[ "$(cat /sys/devices/virtual/dmi/id/chassis_vendor)" = "QEMU" ]]; then ++if [[ "$(cat /sys/devices/virtual/dmi/id/sys_vendor)" = "QEMU" ]]; then + handle_simx + exit 0 +fi From 7aae61abb5b42bee3daf821d49d4e120e534a655 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Tue, 25 Feb 2020 09:14:23 -0800 Subject: [PATCH 0395/1427] [broadcom]: Updated BRCM SAI Debian package revision number to 3.7.3.3-2. (#4182) This has patch to fix enable/disable attribute for lag member. It's on top of vanilla 3.7.3.3 --- platform/broadcom/sai.mk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 63c1e21ec7fc..54f44271ad56 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.7.3.3_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=Y66VSRUEl4PDf5kHRo%2FS3DBBE9tONSyCzNJvi8IP9n8%3D&se=2033-08-25T01%3A22%3A08Z&sp=r" +BRCM_SAI = libsaibcm_3.7.3.3-2_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3-2_amd64.deb?sv=2015-04-05&sr=b&sig=701AT0Rwcn%2FKT33UPE1TTQRoJ9tQG0iDfOSXXVCtnyY%3D&se=2033-10-29T22%3A32%3A29Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3-2_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=6%2BWzgFL845H9lKE0COsN53P4MO4UWfSo0z%2FmUMFbYVk%3D&se=2033-08-25T01%3A21%3A50Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3-2_amd64.deb?sv=2015-04-05&sr=b&sig=vXdUpaP0o71SatqEoqqDH2kai%2FLuFUWZWZAy7HKfeiQ%3D&se=2033-10-29T22%3A31%3A07Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) -$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) \ No newline at end of file +$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 75181702d3e21353529e04431a13840968ded696 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Tue, 25 Feb 2020 09:14:57 -0800 Subject: [PATCH 0396/1427] [arista] Update drivers submodule (#4164) - Refactor of the cli - Refactor of the logging mechanism - Add some more utilities - Miscelaneous fixes and improvements --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 3517d941893b..b1940cf49a18 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 3517d941893b1d4a58e2a42c549ff55eeb31c496 +Subproject commit b1940cf49a185745cc9365afed8efb511478807e diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 3517d941893b..b1940cf49a18 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 3517d941893b1d4a58e2a42c549ff55eeb31c496 +Subproject commit b1940cf49a185745cc9365afed8efb511478807e From 71592fc86669bfcf54a6459e2a0b4ed7f2df7a75 Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Tue, 25 Feb 2020 23:14:45 +0530 Subject: [PATCH 0397/1427] [Platform] Marvell Makefile updates/cleanup (#4168) Signed-off-by: Antony Rheneus --- platform/marvell-arm64/sai.mk | 2 -- platform/marvell-armhf/sai.mk | 2 -- platform/marvell/docker-syncd-mrvl-rpc.mk | 4 +++- platform/marvell/sai.mk | 3 ++- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/platform/marvell-arm64/sai.mk b/platform/marvell-arm64/sai.mk index d5f044c6cb71..ebdd7030a3d4 100644 --- a/platform/marvell-arm64/sai.mk +++ b/platform/marvell-arm64/sai.mk @@ -1,9 +1,7 @@ # Marvell SAI export MRVL_SAI_VERSION = 1.5.1 -export MRVL_SAI_TAG = SONiC.201904 export MRVL_SAI = mrvllibsai_$(PLATFORM_ARCH)_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai -#$(MRVL_SAI)_DEPENDS += $(MRVL_FPA) SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/marvell-armhf/sai.mk b/platform/marvell-armhf/sai.mk index d5f044c6cb71..ebdd7030a3d4 100644 --- a/platform/marvell-armhf/sai.mk +++ b/platform/marvell-armhf/sai.mk @@ -1,9 +1,7 @@ # Marvell SAI export MRVL_SAI_VERSION = 1.5.1 -export MRVL_SAI_TAG = SONiC.201904 export MRVL_SAI = mrvllibsai_$(PLATFORM_ARCH)_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai -#$(MRVL_SAI)_DEPENDS += $(MRVL_FPA) SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/marvell/docker-syncd-mrvl-rpc.mk b/platform/marvell/docker-syncd-mrvl-rpc.mk index 5b1968bde39c..0e1b65f2fd5d 100644 --- a/platform/marvell/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell/docker-syncd-mrvl-rpc.mk @@ -10,8 +10,9 @@ $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) endif -$(DOCKER_SYNCD_MRVL_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_MRVL) +$(DOCKER_SYNCD_MRVL_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL_RPC) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_MRVL_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL_RPC) endif @@ -20,3 +21,4 @@ $(DOCKER_SYNCD_MRVL_RPC)_CONTAINER_NAME = syncd $(DOCKER_SYNCD_MRVL_RPC)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_MRVL_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_MRVL_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_MRVL_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/marvell/sai.mk b/platform/marvell/sai.mk index 7953ad5dd82f..553188100045 100644 --- a/platform/marvell/sai.mk +++ b/platform/marvell/sai.mk @@ -1,6 +1,7 @@ # Marvell SAI -export MRVL_SAI = mrvllibsai_amd64_1.4.1.deb +export MRVL_SAI_VERSION = 1.5.1 +export MRVL_SAI = mrvllibsai_amd64_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai SONIC_MAKE_DEBS += $(MRVL_SAI) From 1ef740361c4ee4e00cadc29fe2228ac5712afefd Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Wed, 26 Feb 2020 10:56:54 +0200 Subject: [PATCH 0398/1427] [docker_image_ctl.j2] Share UTS namespace with host OS (#4169) Instead of updating hostname manualy on Config DB hostname change, simply share containers UTS namespace with host OS. Ideally, instead of setting `--uts=host` for every container in SONiC, this setting can be set per container if feature requires. One behaviour change is introduced in this commit, when `--privileged` or `--cap-add=CAP_SYS_ADMIN` and `--uts=host` are combined, container has privilege to change host OS and every other container hostname. Such privilege should be fixed by limiting containers capabilities. Signed-off-by: Stepan Blyschak --- files/build_templates/docker_image_ctl.j2 | 48 ++------------------- files/image_config/hostcfgd/hostcfgd | 51 +---------------------- 2 files changed, 5 insertions(+), 94 deletions(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 2777a26c8edf..c8137b9f574c 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -1,7 +1,7 @@ #!/bin/bash # single instance containers are still supported (even though it might not look like it) -# if no instance number is passed to this script, $DEV will simply be unset, resulting in docker +# if no instance number is passed to this script, $DEV will simply be unset, resulting in docker # commands being sent to the base container name. E.g. `docker start database$DEV` simply starts # the container `database` if no instance number is passed since `$DEV` is not defined @@ -31,32 +31,6 @@ function getMountPoint() echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.basename(mnts[0]['Source'])" 2>/dev/null } -function updateHostName() -{ - HOSTS=/etc/hosts - HOSTS_TMP=/etc/hosts.tmp - - EXEC="docker exec -i {{docker_container_name}}$DEV bash -c" - - NEW_HOSTNAME="$1" - HOSTNAME=`$EXEC "hostname"` - if ! [[ $HOSTNAME =~ ^[a-zA-Z0-9.\-]*$ ]]; then - HOSTNAME=`hostname` - fi - - # copy HOSTS to HOSTS_TMP - $EXEC "cp $HOSTS $HOSTS_TMP" - # remove entry with hostname - $EXEC "sed -i \"/$HOSTNAME$/d\" $HOSTS_TMP" - # add entry with new hostname - $EXEC "echo -e \"127.0.0.1\t$NEW_HOSTNAME\" >> $HOSTS_TMP" - - echo "Set hostname in {{docker_container_name}}$DEV container" - $EXEC "hostname '$NEW_HOSTNAME'" - $EXEC "cat $HOSTS_TMP > $HOSTS" - $EXEC "rm -f $HOSTS_TMP" -} - function getBootType() { # same code snippet in files/scripts/syncd.sh @@ -161,11 +135,7 @@ start() { {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` - HOSTNAME=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hostname"]'` {%- endif %} - if [ -z "$HOSTNAME" ] || ! [[ $HOSTNAME =~ ^[a-zA-Z0-9.\-]*$ ]]; then - HOSTNAME=`hostname` - fi DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` if [ "$?" -eq "0" ]; then @@ -183,11 +153,6 @@ start() { preStartAction docker start {{docker_container_name}}$DEV postStartAction - CURRENT_HOSTNAME="$(docker exec {{docker_container_name}}$DEV hostname)" - if [ x"$HOSTNAME" != x"$CURRENT_HOSTNAME" ]; then - updateHostName "$HOSTNAME" - fi - updateHostName "$HOSTNAME" exit $? fi @@ -210,7 +175,7 @@ start() { if [ -z "$DEV" ]; then NET="host" else - {%- if docker_container_name == "database" %} + {%- if docker_container_name == "database" %} NET="bridge" {%- else %} NET="container:database$DEV" @@ -222,6 +187,7 @@ start() { {%- endif %} docker create {{docker_image_run_opt}} \ --net=$NET \ + --uts=host \{# W/A: this should be set per-docker, for those dockers which really need host's UTS namespace #} {%- if install_debug_image == "y" %} -v /src:/src:ro -v /debug:/debug:rw \ {%- endif %} @@ -258,7 +224,6 @@ start() { preStartAction docker start {{docker_container_name}} postStartAction - updateHostName "$HOSTNAME" } wait() { @@ -280,13 +245,8 @@ case "$1" in start|wait|stop) $1 ;; - updateHostName) - cmd=$1 - shift 2 - $cmd $@ - ;; *) - echo "Usage: $0 {start namespace(optional)|wait namespace(optional)|stop namespace(optional)|updateHostName namespace(optional) new_hostname}" + echo "Usage: $0 {start namespace(optional)|wait namespace(optional)|stop namespace(optional)}" exit 1 ;; esac diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index e10288c0dd37..4ac3be83d06e 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -2,7 +2,6 @@ # -*- coding: utf-8 -*- import os -import re import sys import subprocess import syslog @@ -24,13 +23,6 @@ TACPLUS_SERVER_TIMEOUT_DEFAULT = "5" TACPLUS_SERVER_AUTH_TYPE_DEFAULT = "pap" -def is_valid_hostname(hostname): - if hostname[-1] == "." or len(hostname) > 253: - return False - allowed = re.compile("(?!-)[A-Z\d-]{1,63}(? Date: Wed, 26 Feb 2020 21:27:52 +0200 Subject: [PATCH 0399/1427] [image]: Add SSD maintenance utility - hdparm. (#4177) Signed-off-by: Nazarii Hnydyn --- build_debian.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build_debian.sh b/build_debian.sh index 5b9a8e25adb0..37db2bdeb44e 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -139,7 +139,9 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/initramfs-tools_*.deb || \ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/linux-image-${LINUX_KERNEL_VERSION}-*_${CONFIGURED_ARCH}.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install acl -[[ $CONFIGURED_ARCH == amd64 ]] && sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install dmidecode +if [[ $CONFIGURED_ARCH == amd64 ]]; then + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install dmidecode hdparm +fi ## Update initramfs for booting with squashfs+overlay cat files/initramfs-tools/modules | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null From 7b1f0a6d339c81690801404867d9d86c1210dec0 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Thu, 27 Feb 2020 08:21:35 -0800 Subject: [PATCH 0400/1427] [gitignore] Ignore all auto-generated Dockerfiles (#4195) * [gitignore] Ignore all auto-generated Dockerfiles - Simplify gitignore to ignore all known directories with generated Dockerfiles - Rename Barefoot and Cavium saiserver Dockerfiles to follow same convention as other platforms Signed-off-by: Danny Allen --- .gitignore | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 316cf974e6c1..d9ca023fedc3 100644 --- a/.gitignore +++ b/.gitignore @@ -109,30 +109,9 @@ src/thrift/* !src/thrift/Makefile # Autogenerated Dockerfiles -sonic-slave/Dockerfile -sonic-slave-stretch/Dockerfile -sonic-slave-jessie/Dockerfile -dockers/docker-base/Dockerfile -dockers/docker-base-stretch/Dockerfile -dockers/docker-config-engine/Dockerfile -dockers/docker-config-engine-stretch/Dockerfile -dockers/docker-database/Dockerfile -dockers/docker-dhcp-relay/Dockerfile -dockers/docker-fpm-frr/Dockerfile -dockers/docker-fpm-gobgp/Dockerfile -dockers/docker-fpm-quagga/Dockerfile -dockers/docker-lldp-sv2/Dockerfile -dockers/docker-orchagent/Dockerfile -dockers/docker-platform-monitor/Dockerfile -dockers/docker-router-advertiser/Dockerfile -dockers/docker-snmp-sv2/Dockerfile -dockers/docker-teamd/Dockerfile -dockers/docker-sonic-mgmt/Dockerfile -dockers/docker-sonic-telemetry/Dockerfile -platform/*/docker-saiserver-*/Dockerfile -platform/*/docker-syncd-*/Dockerfile -platform/*/docker-syncd-*-rpc/Dockerfile -platform/vs/docker-sonic-vs/Dockerfile +sonic-slave*/Dockerfile +dockers/*/Dockerfile +platform/*/docker-*/Dockerfile # Installer-related files and directories installer/x86_64/platforms/ From d5c69bc9fcc697fdf5262954db1ee606c067f599 Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Fri, 28 Feb 2020 07:03:13 +0200 Subject: [PATCH 0401/1427] [Mellanox] Update MFT version to 4.13.5 (#4199) --- platform/mellanox/mft.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index af2192de4543..e6c9d9ba0ea6 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -1,7 +1,7 @@ # Mellanox SAI -MFT_VERSION = 4.13.3 -MFT_REVISION = 6 +MFT_VERSION = 4.13.5 +MFT_REVISION = 1 export MFT_VERSION MFT_REVISION From d19bba0ec0979a4f9bc4dd6b03c1f5e7bdb8cc6a Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 27 Feb 2020 22:08:52 -0800 Subject: [PATCH 0402/1427] [sonic-cfggen] Load JSON files before minigraph file (#4202) If sonic-cfggen is passed the -m argument (to load the minigraph file) along with one or more -j arguments, load the JSON files before loading the minigraph file. This ensures that the init_cfg.json file is loaded before the minigraph, therefore the minigraph can override any default configuration options specified in init_cfg.json. Currently, the behavior is reversed. Note: This is not an issue if loading loading multiple JSON files, because sonic-cfggen loads them in the left-to-right order they were specified on the command line, therefore providing flexibility for loading JSON files in a specific order. As long as init_cfg.json is specified before config_db.json, the values specified in config_db.json will take precedence. --- src/sonic-config-engine/sonic-cfggen | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 7cff6c9fb384..34f5a36f0fe3 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -233,6 +233,10 @@ def main(): sys.exit(1) deep_update(data, {'PORT': ports}) + for json_file in args.json: + with open(json_file, 'r') as stream: + deep_update(data, FormatConverter.to_deserialized(json.load(stream))) + if args.minigraph != None: minigraph = args.minigraph if platform: @@ -254,10 +258,6 @@ def main(): additional_data = yaml.load(stream) deep_update(data, FormatConverter.to_deserialized(additional_data)) - for json_file in args.json: - with open(json_file, 'r') as stream: - deep_update(data, FormatConverter.to_deserialized(json.load(stream))) - if args.additional_data != None: deep_update(data, json.loads(args.additional_data)) From 41ae7a21025009e3f6993ccce318273552d7c84e Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Sat, 29 Feb 2020 01:57:03 +0200 Subject: [PATCH 0403/1427] [snmp] remove hostname change as it share uts namespace with host (#4206) Signed-off-by: Stepan Blyschak --- dockers/docker-snmp-sv2/start.sh | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/dockers/docker-snmp-sv2/start.sh b/dockers/docker-snmp-sv2/start.sh index 786968cf9d90..6ec3379df58f 100755 --- a/dockers/docker-snmp-sv2/start.sh +++ b/dockers/docker-snmp-sv2/start.sh @@ -9,17 +9,6 @@ sonic-cfggen -d -y /etc/sonic/snmp.yml -t /usr/share/sonic/templates/snmpd.conf. mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status -CURRENT_HOSTNAME=`hostname` -HOSTNAME=`sonic-cfggen -d -v DEVICE_METADATA[\'localhost\'][\'hostname\']` - -if [ "$?" == "0" ] && [ "$HOSTNAME" != "" ]; then - echo $HOSTNAME > /etc/hostname - hostname -F /etc/hostname - - sed -i "/\s$CURRENT_HOSTNAME$/d" /etc/hosts - echo "127.0.0.1 $HOSTNAME" >> /etc/hosts -fi - rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd From 7a9c8ee1fce8277ed974c79f283a73376c2ed843 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Wed, 4 Mar 2020 03:19:30 +0800 Subject: [PATCH 0404/1427] filter out CPU ports to avoid any operation on them (#4197) --- device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py index c11675766d3f..f9b35b8e74e7 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py @@ -18,14 +18,19 @@ PMAOS_ENABLE = 1 PMAOS_DISABLE = 2 +PORT_TYPE_CPU = 4 PORT_TYPE_NVE = 8 PORT_TYPE_OFFSET = 28 PORT_TYPE_MASK = 0xF0000000 NVE_MASK = PORT_TYPE_MASK & (PORT_TYPE_NVE << PORT_TYPE_OFFSET) +CPU_MASK = PORT_TYPE_MASK & (PORT_TYPE_CPU << PORT_TYPE_OFFSET) def is_nve(port): return (port & NVE_MASK) != 0 +def is_cpu(port): + return (port & CPU_MASK) != 0 + def is_port_admin_status_up(log_port): oper_state_p = new_sx_port_oper_state_t_p() admin_state_p = new_sx_port_admin_state_t_p() @@ -57,6 +62,7 @@ def get_log_ports(handle, sfp_module): for i in range(0, port_cnt): port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i) if is_nve(int(port_attributes.log_port)) == False \ + and is_cpu(int(port_attributes.log_port)) == False \ and port_attributes.port_mapping.module_port == sfp_module \ and is_port_admin_status_up(port_attributes.log_port): log_port_list.append(port_attributes.log_port) From 23ff55a7093a17f786edee7c3885a12ca907c05f Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Tue, 3 Mar 2020 16:50:32 -0800 Subject: [PATCH 0405/1427] [Services] Restart BGP service upon unexpected critical process exit. (#4207) --- dockers/docker-database/supervisord.conf.j2 | 1 - dockers/docker-fpm-frr/Dockerfile.j2 | 2 ++ dockers/docker-fpm-frr/critical_processes | 5 +++++ dockers/docker-fpm-frr/supervisord.conf | 8 +++++++- dockers/docker-fpm-gobgp/Dockerfile.j2 | 2 ++ dockers/docker-fpm-gobgp/critical_processes | 2 ++ dockers/docker-fpm-gobgp/supervisord.conf | 8 +++++++- dockers/docker-fpm-quagga/Dockerfile.j2 | 2 ++ dockers/docker-fpm-quagga/critical_processes | 4 ++++ dockers/docker-fpm-quagga/supervisord.conf | 8 +++++++- files/build_templates/single_instance/bgp.service.j2 | 4 ++++ rules/docker-fpm-frr.mk | 2 ++ rules/docker-fpm-gobgp.mk | 1 + rules/docker-fpm-quagga.mk | 2 ++ 14 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 dockers/docker-fpm-frr/critical_processes create mode 100644 dockers/docker-fpm-gobgp/critical_processes create mode 100644 dockers/docker-fpm-quagga/critical_processes diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index 442bec1438c8..9e855527edba 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -9,7 +9,6 @@ events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected - [program:rsyslogd] command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n" priority=1 diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index 418676c18329..1c670682a342 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -50,6 +50,8 @@ COPY ["snmp.conf", "/etc/snmp/frr.conf"] COPY ["TSA", "/usr/bin/TSA"] COPY ["TSB", "/usr/bin/TSB"] COPY ["TSC", "/usr/bin/TSC"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] RUN chmod a+x /usr/bin/TSA && \ chmod a+x /usr/bin/TSB && \ chmod a+x /usr/bin/TSC diff --git a/dockers/docker-fpm-frr/critical_processes b/dockers/docker-fpm-frr/critical_processes new file mode 100644 index 000000000000..8ea09e1bb538 --- /dev/null +++ b/dockers/docker-fpm-frr/critical_processes @@ -0,0 +1,5 @@ +zebra +staticd +bgpd +fpmsyncd +bgpcfgd diff --git a/dockers/docker-fpm-frr/supervisord.conf b/dockers/docker-fpm-frr/supervisord.conf index fe0ce6eda1a4..3e544b64b296 100644 --- a/dockers/docker-fpm-frr/supervisord.conf +++ b/dockers/docker-fpm-frr/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name bgp +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -25,7 +31,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=3 autostart=false -autorestart=false +autorestart=unexpected startsecs=0 stdout_logfile=syslog stderr_logfile=syslog diff --git a/dockers/docker-fpm-gobgp/Dockerfile.j2 b/dockers/docker-fpm-gobgp/Dockerfile.j2 index 1e333d9026c0..b9b969edeb09 100644 --- a/dockers/docker-fpm-gobgp/Dockerfile.j2 +++ b/dockers/docker-fpm-gobgp/Dockerfile.j2 @@ -24,5 +24,7 @@ COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["*.j2", "/usr/share/sonic/templates/"] COPY ["daemons", "/etc/quagga/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-fpm-gobgp/critical_processes b/dockers/docker-fpm-gobgp/critical_processes new file mode 100644 index 000000000000..2a9e47831e0d --- /dev/null +++ b/dockers/docker-fpm-gobgp/critical_processes @@ -0,0 +1,2 @@ +gobgpd +fpmsyncd diff --git a/dockers/docker-fpm-gobgp/supervisord.conf b/dockers/docker-fpm-gobgp/supervisord.conf index 4e635f4093d4..b814dc024fa3 100644 --- a/dockers/docker-fpm-gobgp/supervisord.conf +++ b/dockers/docker-fpm-gobgp/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name bgp +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/dockers/docker-fpm-quagga/Dockerfile.j2 b/dockers/docker-fpm-quagga/Dockerfile.j2 index f048e2789429..9d1312d073ee 100644 --- a/dockers/docker-fpm-quagga/Dockerfile.j2 +++ b/dockers/docker-fpm-quagga/Dockerfile.j2 @@ -33,5 +33,7 @@ RUN rm -rf /debs ~/.cache COPY ["bgpcfgd", "start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["*.j2", "/usr/share/sonic/templates/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-fpm-quagga/critical_processes b/dockers/docker-fpm-quagga/critical_processes new file mode 100644 index 000000000000..f151af9c4bdd --- /dev/null +++ b/dockers/docker-fpm-quagga/critical_processes @@ -0,0 +1,4 @@ +zebra +bgpd +fpmsyncd +bgpcfgd diff --git a/dockers/docker-fpm-quagga/supervisord.conf b/dockers/docker-fpm-quagga/supervisord.conf index c4351fafefe9..7397a7428a08 100644 --- a/dockers/docker-fpm-quagga/supervisord.conf +++ b/dockers/docker-fpm-quagga/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name bgp +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -25,7 +31,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=3 autostart=false -autorestart=false +autorestart=unexpected startsecs=0 stdout_logfile=syslog stderr_logfile=syslog diff --git a/files/build_templates/single_instance/bgp.service.j2 b/files/build_templates/single_instance/bgp.service.j2 index 7200a0e3ecf2..fdf9d9c78c04 100644 --- a/files/build_templates/single_instance/bgp.service.j2 +++ b/files/build_templates/single_instance/bgp.service.j2 @@ -3,12 +3,16 @@ Description=BGP container Requires=updategraph.service After=updategraph.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 1d918830ab55..517aff3ea9fc 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -26,6 +26,8 @@ $(DOCKER_FPM_FRR)_RUN_OPT += --privileged -t $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw +$(DOCKER_FPM_FRR)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) + $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSA:/usr/bin/TSA $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSB:/usr/bin/TSB diff --git a/rules/docker-fpm-gobgp.mk b/rules/docker-fpm-gobgp.mk index 3e1839d47099..03ec88e85b56 100644 --- a/rules/docker-fpm-gobgp.mk +++ b/rules/docker-fpm-gobgp.mk @@ -9,3 +9,4 @@ SONIC_DOCKER_IMAGES += $(DOCKER_FPM_GOBGP) $(DOCKER_FPM_GOBGP)_CONTAINER_NAME = bgp $(DOCKER_FPM_GOBGP)_RUN_OPT += --privileged -t $(DOCKER_FPM_GOBGP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_FPM_GOBPG)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-fpm-quagga.mk b/rules/docker-fpm-quagga.mk index 2c78d1917b0e..5a384eedab2c 100644 --- a/rules/docker-fpm-quagga.mk +++ b/rules/docker-fpm-quagga.mk @@ -10,4 +10,6 @@ $(DOCKER_FPM_QUAGGA)_CONTAINER_NAME = bgp $(DOCKER_FPM_QUAGGA)_RUN_OPT += --privileged -t $(DOCKER_FPM_QUAGGA)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_FPM_QUAGGA)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) + $(DOCKER_FPM_QUAGGA)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh From d9fcb2fa79b06b7e91c97eb0dfc7448cc07a3aab Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Wed, 4 Mar 2020 18:04:33 +0100 Subject: [PATCH 0406/1427] [sairedis] Advance pointer to origin/master (bigrebase) (#4217) --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 2961bd329636..1809f7aaef17 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 2961bd3296365c89a27820207c73a94cf060a41a +Subproject commit 1809f7aaef1770bd44fab6bcaf26e812cdfbf667 From b08bedbfe89c77711f327362ed741420d7bc7103 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 4 Mar 2020 10:02:55 -0800 Subject: [PATCH 0407/1427] [Mellanox]Integrate hw-mgmt 7.0000.3012 and advance the linux kernel (#4193) * [Mellanox]Integrate hw-mgmt 7.0000.3012 * [sonic-linux-kernel]Advance the submodule head Advance the sonic-linux-kernel [sFlow]: Patch to fix skb_over_panic in psample driver (#120) Added support in the kernel for fullcone 3-tuple unique nat. (#100) Adding support to compile ARM architecture (#102) [ixgbe] Support bcm54616s external phy in ixgbe (#122) Fix i2c ISMT DMA buffer alignment issue (#123) [mellanox]: Add SN4700 patches. (#126) --- platform/mellanox/hw-management.mk | 2 +- platform/mellanox/hw-management/hw-mgmt | 2 +- src/sonic-linux-kernel | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index ff1ea207572d..692a816a0f4f 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0000.2308 +MLNX_HW_MANAGEMENT_VERSION = 7.0000.3012 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 28d83cdb3565..2f659142ab3b 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 28d83cdb3565d3b0352cc718fe82a14cacd1d4a5 +Subproject commit 2f659142ab3b4deb58989a2ca38b0b1671600509 diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 66e9dfa59136..231bebb41b86 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 66e9dfa591369782eff63f1de09818df3a941b29 +Subproject commit 231bebb41b86c9f744adc86972773d75fd4a2a2a From f906a758cdeab9c00579a4219a5781538696939e Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Wed, 4 Mar 2020 11:47:31 -0800 Subject: [PATCH 0408/1427] [spytest] Create new sonic-mgmt docker for running spytests (#4212) Signed-off-by: Danny Allen --- .../docker-sonic-mgmt-spytest/Dockerfile.j2 | 29 +++++++++++++++++++ rules/docker-sonic-mgmt-spytest.mk | 6 ++++ 2 files changed, 35 insertions(+) create mode 100644 dockers/docker-sonic-mgmt-spytest/Dockerfile.j2 create mode 100644 rules/docker-sonic-mgmt-spytest.mk diff --git a/dockers/docker-sonic-mgmt-spytest/Dockerfile.j2 b/dockers/docker-sonic-mgmt-spytest/Dockerfile.j2 new file mode 100644 index 000000000000..4f6b0d8fffac --- /dev/null +++ b/dockers/docker-sonic-mgmt-spytest/Dockerfile.j2 @@ -0,0 +1,29 @@ +FROM docker-sonic-mgmt:latest + +ENV CC=gcc CPP=cpp CXX=c++ LDSHARED="gcc -pthread -shared" PYMSSQL_BUILD_WITH_BUNDLED_FREETDS=1 + +RUN sudo -H pip install \ + "cryptography>=2.5" \ + "future>=0.16.0" \ + gitpython \ + jinja2 \ + jsonpatch \ + "netmiko==2.4.2" \ + prettytable \ + psutil \ + pycryptodome \ + pyfiglet \ + "pylint==1.8.1" \ + pyro4 \ + pytest-repeat \ + "pytest-xdist==1.28.0" \ + "pytest==4.6.5" \ + redis \ + requests \ + rpyc \ + tabulate \ + textfsm + +RUN sudo apt-get update && sudo apt-get install -y \ + inetutils-ping \ + telnet diff --git a/rules/docker-sonic-mgmt-spytest.mk b/rules/docker-sonic-mgmt-spytest.mk new file mode 100644 index 000000000000..c3906263eff3 --- /dev/null +++ b/rules/docker-sonic-mgmt-spytest.mk @@ -0,0 +1,6 @@ +# SPYTest Management Docker + +DOCKER_MGMT_SPYTEST = docker-sonic-mgmt-spytest.gz +$(DOCKER_MGMT_SPYTEST)_PATH = $(DOCKERS_PATH)/docker-sonic-mgmt-spytest +$(DOCKER_MGMT_SPYTEST)_LOAD_DOCKERS += $(DOCKER_SONIC_MGMT) +SONIC_DOCKER_IMAGES += $(DOCKER_MGMT_SPYTEST) From f6ec95cf2b70c24b222476f3a131dc0eb6123147 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 4 Mar 2020 19:15:12 -0800 Subject: [PATCH 0409/1427] [Mellanox]the port index in port_config.ini should starts from 0 (#4152) --- .../Mellanox-SN2700-C28D8/port_config.ini | 74 ++++++------ .../Mellanox-SN2700-D48C8/port_config.ini | 114 +++++++++--------- 2 files changed, 94 insertions(+), 94 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini index 345e6a206731..8bc48269d163 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini @@ -1,37 +1,37 @@ -# name lanes speed alias index -Ethernet0 0,1,2,3 100000 etp1 1 -Ethernet4 4,5,6,7 100000 etp2 2 -Ethernet8 8,9,10,11 100000 etp3 3 -Ethernet12 12,13,14,15 100000 etp4 4 -Ethernet16 16,17,18,19 100000 etp5 5 -Ethernet20 20,21,22,23 100000 etp6 6 -Ethernet24 24,25,26,27 100000 etp7 7 -Ethernet28 28,29,30,31 100000 etp8 8 -Ethernet32 32,33,34,35 100000 etp9 9 -Ethernet36 36,37,38,39 100000 etp10 10 -Ethernet40 40,41,42,43 100000 etp11 11 -Ethernet44 44,45,46,47 100000 etp12 12 -Ethernet48 48,49,50,51 100000 etp13 13 -Ethernet52 52,53,54,55 100000 etp14 14 -Ethernet56 56,57,58,59 100000 etp15 15 -Ethernet60 60,61,62,63 100000 etp16 16 -Ethernet64 64,65,66,67 100000 etp17 17 -Ethernet68 68,69,70,71 100000 etp18 18 -Ethernet72 72,73,74,75 100000 etp19 19 -Ethernet76 76,77,78,79 100000 etp20 20 -Ethernet80 80,81,82,83 100000 etp21 21 -Ethernet84 84,85,86,87 100000 etp22 22 -Ethernet88 88,89,90,91 100000 etp23 23 -Ethernet92 92,93,94,95 100000 etp24 24 -Ethernet96 96,97,98,99 100000 etp25 25 -Ethernet100 100,101,102,103 100000 etp26 26 -Ethernet104 104,105,106,107 100000 etp27 27 -Ethernet108 108,109,110,111 100000 etp28 28 -Ethernet112 112,113 50000 etp29a 29 -Ethernet114 114,115 50000 etp29b 29 -Ethernet116 116,117 50000 etp30a 30 -Ethernet118 118,119 50000 etp30b 30 -Ethernet120 120,121 50000 etp31a 31 -Ethernet122 122,123 50000 etp31b 31 -Ethernet124 124,125 50000 etp32a 32 -Ethernet126 126,127 50000 etp32b 32 \ No newline at end of file +# name lanes alias index speed +Ethernet0 0,1,2,3 etp1 0 100000 +Ethernet4 4,5,6,7 etp2 1 100000 +Ethernet8 8,9,10,11 etp3 2 100000 +Ethernet12 12,13,14,15 etp4 3 100000 +Ethernet16 16,17,18,19 etp5 4 100000 +Ethernet20 20,21,22,23 etp6 5 100000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32,33,34,35 etp9 8 100000 +Ethernet36 36,37,38,39 etp10 9 100000 +Ethernet40 40,41,42,43 etp11 10 100000 +Ethernet44 44,45,46,47 etp12 11 100000 +Ethernet48 48,49,50,51 etp13 12 100000 +Ethernet52 52,53,54,55 etp14 13 100000 +Ethernet56 56,57,58,59 etp15 14 100000 +Ethernet60 60,61,62,63 etp16 15 100000 +Ethernet64 64,65,66,67 etp17 16 100000 +Ethernet68 68,69,70,71 etp18 17 100000 +Ethernet72 72,73,74,75 etp19 18 100000 +Ethernet76 76,77,78,79 etp20 19 100000 +Ethernet80 80,81,82,83 etp21 20 100000 +Ethernet84 84,85,86,87 etp22 21 100000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105,106,107 etp27 26 100000 +Ethernet108 108,109,110,111 etp28 27 100000 +Ethernet112 112,113 etp29a 28 50000 +Ethernet114 114,115 etp29b 28 50000 +Ethernet116 116,117 etp30a 29 50000 +Ethernet118 118,119 etp30b 29 50000 +Ethernet120 120,121 etp31a 30 50000 +Ethernet122 122,123 etp31b 30 50000 +Ethernet124 124,125 etp32a 31 50000 +Ethernet126 126,127 etp32b 31 50000 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini index 9e01da79f449..f9f465f1a3ea 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini @@ -1,57 +1,57 @@ -# name lanes speed alias index -Ethernet0 0,1 50000 etp1a 1 -Ethernet2 2,3 50000 etp1b 1 -Ethernet4 4,5 50000 etp2a 2 -Ethernet6 6,7 50000 etp2b 2 -Ethernet8 8,9 50000 etp3a 3 -Ethernet10 10,11 50000 etp3b 3 -Ethernet12 12,13 50000 etp4a 4 -Ethernet14 14,15 50000 etp4b 4 -Ethernet16 16,17 50000 etp5a 5 -Ethernet18 18,19 50000 etp5b 5 -Ethernet20 20,21 50000 etp6a 6 -Ethernet22 22,23 50000 etp6b 6 -Ethernet24 24,25,26,27 100000 etp7 7 -Ethernet28 28,29,30,31 100000 etp8 8 -Ethernet32 32,33,34,35 100000 etp9 9 -Ethernet36 36,37,38,39 100000 etp10 10 -Ethernet40 40,41 50000 etp11a 11 -Ethernet42 42,43 50000 etp11b 11 -Ethernet44 44,45 50000 etp12a 12 -Ethernet46 46,47 50000 etp12b 12 -Ethernet48 48,49 50000 etp13a 13 -Ethernet50 50,51 50000 etp13b 13 -Ethernet52 52,53 50000 etp14a 14 -Ethernet54 54,55 50000 etp14b 14 -Ethernet56 56,57 50000 etp15a 15 -Ethernet58 58,59 50000 etp15b 15 -Ethernet60 60,61 50000 etp16a 16 -Ethernet62 62,63 50000 etp16b 16 -Ethernet64 64,65 50000 etp17a 17 -Ethernet66 66,67 50000 etp17b 17 -Ethernet68 68,69 50000 etp18a 18 -Ethernet70 70,71 50000 etp18b 18 -Ethernet72 72,73 50000 etp19a 19 -Ethernet74 74,75 50000 etp19b 19 -Ethernet76 76,77 50000 etp20a 20 -Ethernet78 78,79 50000 etp20b 20 -Ethernet80 80,81 50000 etp21a 21 -Ethernet82 82,83 50000 etp21b 21 -Ethernet84 84,85 50000 etp22a 22 -Ethernet86 86,87 50000 etp22b 22 -Ethernet88 88,89,90,91 100000 etp23 23 -Ethernet92 92,93,94,95 100000 etp24 24 -Ethernet96 96,97,98,99 100000 etp25 25 -Ethernet100 100,101,102,103 100000 etp26 26 -Ethernet104 104,105 50000 etp27a 27 -Ethernet106 106,107 50000 etp27b 27 -Ethernet108 108,109 50000 etp28a 28 -Ethernet110 110,111 50000 etp28b 28 -Ethernet112 112,113 50000 etp29a 29 -Ethernet114 114,115 50000 etp29b 29 -Ethernet116 116,117 50000 etp30a 30 -Ethernet118 118,119 50000 etp30b 30 -Ethernet120 120,121 50000 etp31a 31 -Ethernet122 122,123 50000 etp31b 31 -Ethernet124 124,125 50000 etp32a 32 -Ethernet126 126,127 50000 etp32b 32 +# name lanes alias index speed +Ethernet0 0,1 etp1a 0 50000 +Ethernet2 2,3 etp1b 0 50000 +Ethernet4 4,5 etp2a 1 50000 +Ethernet6 6,7 etp2b 1 50000 +Ethernet8 8,9 etp3a 2 50000 +Ethernet10 10,11 etp3b 2 50000 +Ethernet12 12,13 etp4a 3 50000 +Ethernet14 14,15 etp4b 3 50000 +Ethernet16 16,17 etp5a 4 50000 +Ethernet18 18,19 etp5b 4 50000 +Ethernet20 20,21 etp6a 5 50000 +Ethernet22 22,23 etp6b 5 50000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32,33,34,35 etp9 8 100000 +Ethernet36 36,37,38,39 etp10 9 100000 +Ethernet40 40,41 etp11a 10 50000 +Ethernet42 42,43 etp11b 10 50000 +Ethernet44 44,45 etp12a 11 50000 +Ethernet46 46,47 etp12b 11 50000 +Ethernet48 48,49 etp13a 12 50000 +Ethernet50 50,51 etp13b 12 50000 +Ethernet52 52,53 etp14a 13 50000 +Ethernet54 54,55 etp14b 13 50000 +Ethernet56 56,57 etp15a 14 50000 +Ethernet58 58,59 etp15b 14 50000 +Ethernet60 60,61 etp16a 15 50000 +Ethernet62 62,63 etp16b 15 50000 +Ethernet64 64,65 etp17a 16 50000 +Ethernet66 66,67 etp17b 16 50000 +Ethernet68 68,69 etp18a 17 50000 +Ethernet70 70,71 etp18b 17 50000 +Ethernet72 72,73 etp19a 18 50000 +Ethernet74 74,75 etp19b 18 50000 +Ethernet76 76,77 etp20a 19 50000 +Ethernet78 78,79 etp20b 19 50000 +Ethernet80 80,81 etp21a 20 50000 +Ethernet82 82,83 etp21b 20 50000 +Ethernet84 84,85 etp22a 21 50000 +Ethernet86 86,87 etp22b 21 50000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105 etp27a 26 50000 +Ethernet106 106,107 etp27b 26 50000 +Ethernet108 108,109 etp28a 27 50000 +Ethernet110 110,111 etp28b 27 50000 +Ethernet112 112,113 etp29a 28 50000 +Ethernet114 114,115 etp29b 28 50000 +Ethernet116 116,117 etp30a 29 50000 +Ethernet118 118,119 etp30b 29 50000 +Ethernet120 120,121 etp31a 30 50000 +Ethernet122 122,123 etp31b 30 50000 +Ethernet124 124,125 etp32a 31 50000 +Ethernet126 126,127 etp32b 31 50000 From ab4861deb8e41af4067df4d4ecafd03e4271bf6e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 4 Mar 2020 19:17:09 -0800 Subject: [PATCH 0410/1427] DellEMC: Platform 2.0 Api - Component for z9264f (#4091) --- .../z9264f/scripts/z9264f_platform.sh | 46 ++++++++++ .../z9264f/sonic_platform/chassis.py | 12 ++- .../z9264f/sonic_platform/component.py | 91 +++++++++++++++++++ 3 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/component.py diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh index 7361bdea2d6d..a613fd080384 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh @@ -139,6 +139,51 @@ remove_python_api_package() { fi } +# Readout firmware version of the system and +# store in /var/log/firmware_versions +platform_firmware_versions() +{ + FIRMWARE_VERSION_FILE=/var/log/firmware_versions + rm -rf ${FIRMWARE_VERSION_FILE} + echo "BIOS: `dmidecode -s system-version `" > $FIRMWARE_VERSION_FILE + + ## Get FPGA version + r=`/usr/bin/pcisysfs.py --get --offset 0x00 --res /sys/bus/pci/devices/0000\:04\:00.0/resource0 | sed '1d; s/.*\(....\)$/\1/; s/\(..\{1\}\)/\1./'` + r_min=$(echo $r | sed 's/.*\(..\)$/0x\1/') + r_maj=$(echo $r | sed 's/^\(..\).*/0x\1/') + echo "FPGA: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + ## Get BMC Firmware Revision + r=`cat /sys/class/ipmi/ipmi0/device/bmc/firmware_revision` + echo "BMC: $r" >> $FIRMWARE_VERSION_FILE + + #System CPLD 0x31 on i2c bus 601 ( physical FPGA I2C-2) + r_min=`/usr/sbin/i2cget -y 601 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 601 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "System CPLD: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 1 0x30 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x30 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x30 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 1: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 2 0x31 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 2: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x32 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x32 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 3: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 4 0x33 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x33 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x33 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE +} + + init_devnum if [ "$1" == "init" ]; then @@ -156,6 +201,7 @@ if [ "$1" == "init" ]; then init_switch_port_led install_python_api_package python /usr/bin/qsfp_irq_enable.py + platform_firmware_versions elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py index ecf0b39fb819..36f2ca8df264 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py @@ -14,11 +14,13 @@ from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Eeprom + from sonic_platform.component import Component from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal except ImportError as e: raise ImportError(str(e) + "- required module not found") +MAX_Z9264F_COMPONENT = 8 # BIOS,BMC,FPGA,SYSTEM CPLD,4 SLAVE CPLDs MAX_Z9264F_PSU = 2 MAX_Z9264F_THERMAL = 8 @@ -55,15 +57,19 @@ def __init__(self): self._sfp_list.append(sfp_node) self._eeprom = Eeprom() - + + for i in range(MAX_Z9264F_COMPONENT): + component = Component(i) + self._component_list.append(component) + for i in range(MAX_Z9264F_PSU): psu = Psu(i) self._psu_list.append(psu) - + for i in range(MAX_Z9264F_THERMAL): thermal = Thermal(i) self._thermal_list.append(thermal) - + for port_num in range(self.PORT_START, (self.PORT_END + 1)): presence = self.get_sfp(port_num).get_presence() if presence: diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/component.py new file mode 100644 index 000000000000..6ead7ef524f2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/component.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python + +######################################################################## +# DELLEMC Z9264F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, BMC etc.) available in +# the platform +# +######################################################################## + +try: + import os + import re + from sonic_platform_base.component_base import ComponentBase + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +FIRMWARE_VERSION_FILE="/var/log/firmware_versions" + +class Component(ComponentBase): + """DellEMC Platform-specific Component class""" + + CHASSIS_COMPONENTS = [ + ["BIOS", ("Performs initialization of hardware components during " + "booting")], + ["FPGA", ("Used for managing the system LEDs")], + ["BMC", ("Platform management controller for on-board temperature " + "monitoring, in-chassis power, Fan and LED control")], + ["System CPLD", ("Used for managing the CPU power sequence and CPU states")], + ["Slave CPLD 1", ("Used for managing QSFP/QSFP28 port transceivers (1-16)")], + ["Slave CPLD 2", ("Used for managing QSFP/QSFP28 port transceivers (17-32)")], + ["Slave CPLD 3", ("Used for managing QSFP/QSFP28 port transceivers (33-48)")], + ["Slave CPLD 4", ("Used for managing QSFP/QSFP28 port transceivers (49-64) and SFP/SFP28 " + "port transceivers (65 and 66)")], + ] + def __init__(self, component_index=0): + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return self.name + + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + Returns: + A string containing the firmware version of the component + """ + rv = "" + try: + fd = open(FIRMWARE_VERSION_FILE,"r") + except IOError: + return rv + version_contents = fd.read() + fd.close() + if not version_contents: + return rv + if self.index < 8: + version = re.search(r''+self.CHASSIS_COMPONENTS[self.index][0]+':(.*)',version_contents) + if version: + rv = version.group(1).strip() + return rv + + def install_firmware(self, image_path): + """ + Installs firmware to the component + Args: + image_path: A string, path to firmware image + Returns: + A boolean, True if install was successful, False if not + """ + return False + + From 09c056369286d48d2748186f7ef5a634e7b71b80 Mon Sep 17 00:00:00 2001 From: lguohan Date: Thu, 5 Mar 2020 01:37:23 -0800 Subject: [PATCH 0411/1427] [docker-ptf]: install tacacs+ server to test tacacs (#4224) Signed-off-by: Guohan Lu --- dockers/docker-ptf/Dockerfile.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index ba5577954039..73c881cab1a9 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -59,7 +59,9 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / python-dev \ python-libpcap \ python-scapy \ - python-six + python-six \ + tacacs+ \ + rsyslog RUN dpkg -i \ {% for deb in docker_ptf_debs.split(' ') -%} From 64a6989d022a5a1621f8470329d2762dddc64eb1 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 5 Mar 2020 15:27:21 -0800 Subject: [PATCH 0412/1427] [Services] Restart NAT service upon unexpected critical process exit. (#4208) --- dockers/docker-nat/Dockerfile.j2 | 2 ++ dockers/docker-nat/critical_processes | 2 ++ dockers/docker-nat/supervisord.conf | 8 +++++++- files/build_templates/nat.service.j2 | 4 ++++ rules/docker-nat.mk | 3 ++- 5 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 dockers/docker-nat/critical_processes diff --git a/dockers/docker-nat/Dockerfile.j2 b/dockers/docker-nat/Dockerfile.j2 index 3cfbd99e95e1..a74147cc26fd 100644 --- a/dockers/docker-nat/Dockerfile.j2 +++ b/dockers/docker-nat/Dockerfile.j2 @@ -38,6 +38,8 @@ RUN apt-get update \ COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["restore_nat_entries.py", "/usr/bin/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs diff --git a/dockers/docker-nat/critical_processes b/dockers/docker-nat/critical_processes new file mode 100644 index 000000000000..d442976143f1 --- /dev/null +++ b/dockers/docker-nat/critical_processes @@ -0,0 +1,2 @@ +natmgrd +natsyncd diff --git a/dockers/docker-nat/supervisord.conf b/dockers/docker-nat/supervisord.conf index bb42d23fe355..839d6f59ab3c 100644 --- a/dockers/docker-nat/supervisord.conf +++ b/dockers/docker-nat/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name nat +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/files/build_templates/nat.service.j2 b/files/build_templates/nat.service.j2 index 2e3e17439ef7..79a56f67ca89 100644 --- a/files/build_templates/nat.service.j2 +++ b/files/build_templates/nat.service.j2 @@ -3,12 +3,16 @@ Description=NAT container Requires=updategraph.service swss.service After=updategraph.service swss.service syncd.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target swss.service diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk index dcccc24ba2ff..eb6bd16ccd46 100644 --- a/rules/docker-nat.mk +++ b/rules/docker-nat.mk @@ -30,5 +30,6 @@ $(DOCKER_NAT)_RUN_OPT += --privileged -t $(DOCKER_NAT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_NAT)_RUN_OPT += -v /host/warmboot:/var/warmboot -$(DOCKER_NAT)_BASE_IMAGE_FILES += natctl:/usr/bin/natctl +$(DOCKER_NAT)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_NAT)_BASE_IMAGE_FILES += natctl:/usr/bin/natctl From 7c8da2051691272d15e7e8aaaace29c673c7d291 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 5 Mar 2020 15:35:35 -0800 Subject: [PATCH 0413/1427] [sonic-cfggen] Loading the configuration from init_cfg.json and then from config_db.json (#4148) --- files/build_templates/docker_image_ctl.j2 | 8 ++++++-- files/scripts/configdb-load.sh | 8 ++++++-- platform/p4/docker-sonic-p4/start.sh | 2 +- platform/vs/docker-sonic-vs/start.sh | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index c8137b9f574c..dd067c74891e 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -80,9 +80,13 @@ function postStartAction() if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else - # If there is a config db dump file, load it + # If there is a config_db.json dump file, load it. if [ -r /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + if [ -r /etc/sonic/init_cfg.json ]; then + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --write-to-db + else + sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + fi fi if [[ "$BOOT_TYPE" == "fast" ]]; then diff --git a/files/scripts/configdb-load.sh b/files/scripts/configdb-load.sh index e7080eb40f3d..b1bf761371bf 100755 --- a/files/scripts/configdb-load.sh +++ b/files/scripts/configdb-load.sh @@ -5,9 +5,13 @@ until [[ $(redis-cli ping | grep -c PONG) -gt 0 ]]; do sleep 1; done -# If there is a config db dump file, load it +# If there is a config_db.json dump file, load it. if [ -r /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + if [ -r /etc/sonic/init_cfg.json ]; then + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --write-to-db + else + sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + fi fi sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" diff --git a/platform/p4/docker-sonic-p4/start.sh b/platform/p4/docker-sonic-p4/start.sh index c9cf4528bedd..e3251bb2f4e5 100755 --- a/platform/p4/docker-sonic-p4/start.sh +++ b/platform/p4/docker-sonic-p4/start.sh @@ -11,7 +11,7 @@ SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /etc/sonic/init_cfg.json if [ -f /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json -j /etc/sonic/init_cfg.json --print-data > /tmp/config_db.json + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --print-data > /tmp/config_db.json mv /tmp/config_db.json /etc/sonic/config_db.json else sonic-cfggen -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index dd9fee4deb3d..f8fcf974b65c 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -13,7 +13,7 @@ SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /etc/sonic/init_cfg.json if [ -f /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json -j /etc/sonic/init_cfg.json --print-data > /tmp/config_db.json + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --print-data > /tmp/config_db.json mv /tmp/config_db.json /etc/sonic/config_db.json else # generate and merge buffers configuration into config file From 590caaf5cfae54dd7b7d152f9a6fbc90cf83f4eb Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Sat, 7 Mar 2020 00:38:09 -0800 Subject: [PATCH 0414/1427] [bcmsai] Update BRCM SAI Debian to 3.7.3.3-3 (#4233) Signed-off-by: Danny Allen --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 54f44271ad56..3d38c760d85b 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.7.3.3-2_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3-2_amd64.deb?sv=2015-04-05&sr=b&sig=701AT0Rwcn%2FKT33UPE1TTQRoJ9tQG0iDfOSXXVCtnyY%3D&se=2033-10-29T22%3A32%3A29Z&sp=r" +BRCM_SAI = libsaibcm_3.7.3.3-3_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3-3_amd64.deb?sv=2015-04-05&sr=b&sig=1MS77TFH1wpXHIQuxvysznffb8shDJa7QWTCpXX3qH4%3D&se=2033-11-14T01%3A39%3A44Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3-2_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3-3_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3-2_amd64.deb?sv=2015-04-05&sr=b&sig=vXdUpaP0o71SatqEoqqDH2kai%2FLuFUWZWZAy7HKfeiQ%3D&se=2033-10-29T22%3A31%3A07Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3-3_amd64.deb?sv=2015-04-05&sr=b&sig=Y%2FXr6tZPrUQn5bLZqXYr6Nba%2BBbhz8lJdXyNEKZ3Sh8%3D&se=2033-11-14T01%3A44%3A38Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 67f520ff5b2a9b0dbc0bd2ec2f5aac2cb5b863c4 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Mon, 9 Mar 2020 23:58:49 +0800 Subject: [PATCH 0415/1427] [Mellanox] Add sdk 4.4.0542 (#4227) * [Mellanox] Add sdk 4.4.0542 * fix typo --- platform/mellanox/fw.mk | 20 +++++++++++++++---- platform/mellanox/mlnx-fw-upgrade.j2 | 7 +++++++ platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/one-image.mk | 2 +- .../sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 7 files changed, 28 insertions(+), 9 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 97ff9d93d486..dc8243be1e83 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,20 +11,27 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.3298 +MLNX_SPC_FW_VERSION = 13.2007.0322 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.3298 +MLNX_SPC2_FW_VERSION = 29.2007.0322 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) +MLNX_SPC3_FW_VERSION = 30.2007.0322 +MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa +$(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) +$(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) + +MLNX_FW_FILES = $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_SPC3_FW_FILE) + ifeq ($(FW_FROM_URL),n) -SONIC_COPY_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) +SONIC_COPY_FILES += $(MLNX_FW_FILES) else -SONIC_ONLINE_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) +SONIC_ONLINE_FILES += $(MLNX_FW_FILES) endif export MLNX_SPC_FW_VERSION @@ -32,3 +39,8 @@ export MLNX_SPC_FW_FILE export MLNX_SPC2_FW_VERSION export MLNX_SPC2_FW_FILE + +export MLNX_SPC3_FW_VERSION +export MLNX_SPC3_FW_FILE + +export MLNX_FW_FILES diff --git a/platform/mellanox/mlnx-fw-upgrade.j2 b/platform/mellanox/mlnx-fw-upgrade.j2 index 3857244a1504..d0f69c35e0bc 100755 --- a/platform/mellanox/mlnx-fw-upgrade.j2 +++ b/platform/mellanox/mlnx-fw-upgrade.j2 @@ -25,15 +25,18 @@ declare -r QUERY_FILE="/tmp/mlxfwmanager-query.log" declare -r SPC1_ASIC="spc1" declare -r SPC2_ASIC="spc2" +declare -r SPC3_ASIC="spc3" declare -r UNKN_ASIC="unknown" declare -rA FW_FILE_MAP=( \ [$SPC1_ASIC]="/etc/mlnx/fw-SPC.mfa" \ [$SPC2_ASIC]="/etc/mlnx/fw-SPC2.mfa" \ + [$SPC3_ASIC]="/etc/mlnx/fw-SPC3.mfa" \ ) declare -rA FW_REQUIRED_MAP=( \ [$SPC1_ASIC]="{{ MLNX_SPC_FW_VERSION }}" \ [$SPC2_ASIC]="{{ MLNX_SPC2_FW_VERSION }}" \ + [$SPC3_ASIC]="{{ MLNX_SPC3_FW_VERSION }}" \ ) IMAGE_UPGRADE="${NO_PARAM}" @@ -135,6 +138,7 @@ function GetAsicType() { local -r SPC1_PRODUCT_ID="cb84" local -r SPC2_PRODUCT_ID="cf6c" + local -r SPC3_PRODUCT_ID="cf70" if lspci -n | grep "${VENDOR_ID}:${SPC1_PRODUCT_ID}" &>/dev/null; then echo "${SPC1_ASIC}" @@ -142,6 +146,9 @@ function GetAsicType() { elif lspci -n | grep "${VENDOR_ID}:${SPC2_PRODUCT_ID}" &>/dev/null; then echo "${SPC2_ASIC}" exit "${EXIT_SUCCESS}" + elif lspci -n | grep "${VENDOR_ID}:${SPC3_PRODUCT_ID}" &>/dev/null; then + echo "${SPC3_ASIC}" + exit "${EXIT_SUCCESS}" fi echo "${UNKN_ASIC}" diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 419598a6a776..4f9e3b292465 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.0-master +MLNX_SAI_VERSION = SAIRel1.16.1-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index df052a406255..ef47a5592190 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit df052a4062556e0f3a1e695fa73efccf81d32a9d +Subproject commit ef47a5592190c08d2f127d3fe8fa5a77ee4087ba diff --git a/platform/mellanox/one-image.mk b/platform/mellanox/one-image.mk index d30e44690991..e4723c3bd1b0 100644 --- a/platform/mellanox/one-image.mk +++ b/platform/mellanox/one-image.mk @@ -11,5 +11,5 @@ $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.g else $(SONIC_ONE_IMAGE)_DOCKERS = $(SONIC_INSTALL_DOCKER_IMAGES) endif -$(SONIC_ONE_IMAGE)_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_FFB_SCRIPT) $(ISSU_VERSION_FILE) $(ONIE_FW_UPDATE) +$(SONIC_ONE_IMAGE)_FILES += $(MLNX_FW_FILES) $(MLNX_FFB_SCRIPT) $(ISSU_VERSION_FILE) $(ONIE_FW_UPDATE) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index fa26ae9d24b4..07425a0957d1 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit fa26ae9d24b4d1ff162f56d83d944c2fc2bcea0b +Subproject commit 07425a0957d100405e3781f8bb633c462f37a92c diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 649422429771..f2af75cccf2b 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.3.3052 +MLNX_SDK_VERSION = 4.4.0542 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From be549db3950faca247f41bdb4aaa7bf1f7051f09 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Tue, 10 Mar 2020 01:41:10 +0800 Subject: [PATCH 0416/1427] Add thermal control support for SONiC (#3949) --- .../thermal_policy.json | 1 + .../thermal_policy.json | 1 + .../thermal_policy.json | 1 + .../thermal_policy.json | 1 + .../thermal_policy.json | 72 +++++ .../thermal_policy.json | 1 + .../thermal_policy.json | 1 + .../thermal_policy.json | 1 + .../thermal_policy.json | 1 + .../thermal_policy.json | 1 + .../thermal_policy.json | 1 + .../docker-pmon.supervisord.conf.j2 | 11 + dockers/docker-platform-monitor/start.sh.j2 | 4 + ...-Disable-thermal-policy-running-in-h.patch | 31 ++ platform/mellanox/mlnx-platform-api.mk | 1 + .../mellanox/mlnx-platform-api/.gitignore | 2 + .../mellanox/mlnx-platform-api/pytest.ini | 3 + platform/mellanox/mlnx-platform-api/setup.cfg | 2 + platform/mellanox/mlnx-platform-api/setup.py | 9 + .../sonic_platform/__init__.py | 2 +- .../sonic_platform/chassis.py | 5 + .../mlnx-platform-api/sonic_platform/fan.py | 18 +- .../sonic_platform/platform.py | 1 + .../mlnx-platform-api/sonic_platform/psu.py | 6 +- .../sonic_platform/thermal.py | 52 +++- .../sonic_platform/thermal_actions.py | 108 +++++++ .../sonic_platform/thermal_conditions.py | 63 ++++ .../sonic_platform/thermal_infos.py | 136 +++++++++ .../sonic_platform/thermal_manager.py | 50 ++++ .../mlnx-platform-api/tests/__init__.py | 0 .../mlnx-platform-api/tests/mock_platform.py | 44 +++ .../tests/test_thermal_policy.py | 272 ++++++++++++++++++ .../tests/thermal_policy.json | 72 +++++ rules/docker-platform-monitor.mk | 2 +- rules/sonic-thermalctld.mk | 6 + .../sonic_daemon_base/task_base.py | 50 ++++ src/sonic-platform-common | 2 +- src/sonic-platform-daemons | 2 +- 38 files changed, 1021 insertions(+), 15 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_lssn2700-r0/thermal_policy.json create mode 120000 device/mellanox/x86_64-mlnx_msn2010-r0/thermal_policy.json create mode 120000 device/mellanox/x86_64-mlnx_msn2100-r0/thermal_policy.json create mode 120000 device/mellanox/x86_64-mlnx_msn2410-r0/thermal_policy.json create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json create mode 120000 device/mellanox/x86_64-mlnx_msn2700_simx-r0/thermal_policy.json create mode 120000 device/mellanox/x86_64-mlnx_msn2740-r0/thermal_policy.json create mode 120000 device/mellanox/x86_64-mlnx_msn3700-r0/thermal_policy.json create mode 120000 device/mellanox/x86_64-mlnx_msn3700_simx-r0/thermal_policy.json create mode 120000 device/mellanox/x86_64-mlnx_msn3700c-r0/thermal_policy.json create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/thermal_policy.json create mode 100644 platform/mellanox/hw-management/0002-hw-management.sh-Disable-thermal-policy-running-in-h.patch create mode 100644 platform/mellanox/mlnx-platform-api/.gitignore create mode 100644 platform/mellanox/mlnx-platform-api/pytest.ini create mode 100644 platform/mellanox/mlnx-platform-api/setup.cfg create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py create mode 100644 platform/mellanox/mlnx-platform-api/tests/__init__.py create mode 100644 platform/mellanox/mlnx-platform-api/tests/mock_platform.py create mode 100644 platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py create mode 100644 platform/mellanox/mlnx-platform-api/tests/thermal_policy.json create mode 100644 rules/sonic-thermalctld.mk create mode 100644 src/sonic-daemon-base/sonic_daemon_base/task_base.py diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_lssn2700-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn2010-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn2100-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn2410-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json new file mode 100644 index 000000000000..054d797be951 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json @@ -0,0 +1,72 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "false", + "fan_speed_when_suspend": "60" + }, + "info_types": [ + { + "type": "fan_info" + }, + { + "type": "psu_info" + }, + { + "type": "chassis_info" + } + ], + "policies": [ + { + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "any psu absence", + "conditions": [ + { + "type": "psu.any.absence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "all fan and psu presence", + "conditions": [ + { + "type": "fan.all.presence" + }, + { + "type": "psu.all.presence" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "60" + } + ] + } + ] +} \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn2740-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn3700-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700_simx-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn3800-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index 13ae0e767ab2..ca5e521abec9 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -86,3 +86,14 @@ stdout_logfile=syslog stderr_logfile=syslog startsecs=0 {% endif %} + +{% if not skip_thermalctld %} +[program:thermalctld] +command=/usr/bin/thermalctld +priority=9 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog +startsecs=0 +{% endif %} diff --git a/dockers/docker-platform-monitor/start.sh.j2 b/dockers/docker-platform-monitor/start.sh.j2 index 44f8f159f612..a72f4fa8eb85 100644 --- a/dockers/docker-platform-monitor/start.sh.j2 +++ b/dockers/docker-platform-monitor/start.sh.j2 @@ -71,3 +71,7 @@ supervisorctl start psud supervisorctl start syseepromd {% endif %} +{% if not skip_thermalctld %} +supervisorctl start thermalctld +{% endif %} + diff --git a/platform/mellanox/hw-management/0002-hw-management.sh-Disable-thermal-policy-running-in-h.patch b/platform/mellanox/hw-management/0002-hw-management.sh-Disable-thermal-policy-running-in-h.patch new file mode 100644 index 000000000000..d1c34fd16ec0 --- /dev/null +++ b/platform/mellanox/hw-management/0002-hw-management.sh-Disable-thermal-policy-running-in-h.patch @@ -0,0 +1,31 @@ +From 76b02916794be2e2558fcff1d11609a594f633d7 Mon Sep 17 00:00:00 2001 +From: Stephen Sun +Date: Fri, 14 Feb 2020 13:48:00 +0800 +Subject: [PATCH] Disable thermal policy running in hw-mgmt service SONiC + thermal control algorithm has been supported. + +Signed-off-by: Stephen Sun +--- + usr/usr/bin/hw-management.sh | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh +index 2cdbfb2..48b41d5 100755 +--- a/usr/usr/bin/hw-management.sh ++++ b/usr/usr/bin/hw-management.sh +@@ -799,7 +799,11 @@ do_start() + #disabled for leopard chipless bringup. + echo 1 > $config_path/suspend + +- $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& ++# ++# Disable thermal control algorithm in hw-management service ++# because there has already been that in SONiC ++# ++# $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& + } + + do_stop() +-- +1.9.1 + diff --git a/platform/mellanox/mlnx-platform-api.mk b/platform/mellanox/mlnx-platform-api.mk index 4b70e59debc1..7bbbc3c70b0e 100644 --- a/platform/mellanox/mlnx-platform-api.mk +++ b/platform/mellanox/mlnx-platform-api.mk @@ -3,6 +3,7 @@ SONIC_PLATFORM_API_PY2 = mlnx_platform_api-1.0-py2-none-any.whl $(SONIC_PLATFORM_API_PY2)_SRC_PATH = $(PLATFORM_PATH)/mlnx-platform-api $(SONIC_PLATFORM_API_PY2)_PYTHON_VERSION = 2 +$(SONIC_PLATFORM_API_PY2)_DEPENDS = $(SONIC_PLATFORM_COMMON_PY2) $(SONIC_DAEMON_BASE_PY2) $(SONIC_CONFIG_ENGINE) SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) export mlnx_platform_api_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2))" diff --git a/platform/mellanox/mlnx-platform-api/.gitignore b/platform/mellanox/mlnx-platform-api/.gitignore new file mode 100644 index 000000000000..07f8a98e1f4a --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/.gitignore @@ -0,0 +1,2 @@ +*.pyc +.cache/ diff --git a/platform/mellanox/mlnx-platform-api/pytest.ini b/platform/mellanox/mlnx-platform-api/pytest.ini new file mode 100644 index 000000000000..c24fe5bb9e65 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +filterwarnings = + ignore::DeprecationWarning diff --git a/platform/mellanox/mlnx-platform-api/setup.cfg b/platform/mellanox/mlnx-platform-api/setup.cfg new file mode 100644 index 000000000000..b7e478982ccf --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/setup.cfg @@ -0,0 +1,2 @@ +[aliases] +test=pytest diff --git a/platform/mellanox/mlnx-platform-api/setup.py b/platform/mellanox/mlnx-platform-api/setup.py index 12809c4085ed..f10f84924d2c 100644 --- a/platform/mellanox/mlnx-platform-api/setup.py +++ b/platform/mellanox/mlnx-platform-api/setup.py @@ -12,6 +12,14 @@ maintainer_email='kevinw@mellanox.com', packages=[ 'sonic_platform', + 'tests' + ], + setup_requires= [ + 'pytest-runner' + ], + tests_require = [ + 'pytest', + 'mock>=2.0.0' ], classifiers=[ 'Development Status :: 3 - Alpha', @@ -26,5 +34,6 @@ 'Topic :: Utilities', ], keywords='sonic SONiC platform PLATFORM', + test_suite='setup.get_test_suite' ) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/__init__.py b/platform/mellanox/mlnx-platform-api/sonic_platform/__init__.py index d94d4c9ec820..d82f3749319c 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/__init__.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/__init__.py @@ -1,2 +1,2 @@ __all__ = ["platform", "chassis"] -from sonic_platform import * \ No newline at end of file +from sonic_platform import * diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 5e8c76ccd617..fe8b31898387 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -470,3 +470,8 @@ def get_change_event(self, timeout=0): return True, {'sfp':port_dict} else: return True, {'sfp':{}} + + def get_thermal_manager(self): + from .thermal_manager import ThermalManager + return ThermalManager + diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py index 818aa0f0110b..cc4f8e81d9b5 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py @@ -43,10 +43,12 @@ def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False): self.fan_speed_set_path = "fan{}_speed_set".format(self.index) self.fan_presence_path = "fan{}_status".format(self.drawer_index) self.fan_max_speed_path = "fan{}_max".format(self.index) + self._name = "fan{}".format(fan_index + 1) else: self.fan_speed_get_path = "psu{}_fan1_speed_get".format(self.index) self.fan_presence_path = "psu{}_fan1_speed_get".format(self.index) - self.fan_max_speed_path = "psu{}_max".format(self.index) + self._name = 'psu_{}_fan_{}'.format(self.index, fan_index) + self.fan_max_speed_path = None self.fan_status_path = "fan{}_fault".format(self.index) self.fan_green_led_path = "led_fan{}_green".format(self.drawer_index) self.fan_red_led_path = "led_fan{}_red".format(self.drawer_index) @@ -93,6 +95,9 @@ def get_direction(self): raise RuntimeError("Failed to read fan direction status to {}".format(repr(e))) + def get_name(self): + return self._name + def get_status(self): """ Retrieves the operational status of fan @@ -171,7 +176,11 @@ def get_speed(self): speed_in_rpm = int(fan_curr_speed.read()) except (ValueError, IOError): speed_in_rpm = 0 - + + if self.fan_max_speed_path is None: + # in case of max speed unsupported, we just return speed in unit of RPM. + return speed_in_rpm + max_speed_in_rpm = self._get_max_speed_in_rpm() speed = 100*speed_in_rpm/max_speed_in_rpm @@ -185,11 +194,10 @@ def get_target_speed(self): Returns: int: percentage of the max fan speed """ - speed = 0 - if self.is_psu_fan: # Not like system fan, psu fan speed can not be modified, so target speed is N/A - return speed + return self.get_speed() + try: with open(os.path.join(FAN_PATH, self.fan_speed_set_path), 'r') as fan_pwm: pwm = int(fan_pwm.read()) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py index 25461986f37a..6d81ca3e7b51 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -24,6 +24,7 @@ def __init__(self): self._chassis.initialize_psu() self._chassis.initialize_fan() self._chassis.initialize_eeprom() + self._chassis.initialize_thermals() def _is_host(self): """ diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 59893f21cd0a..31887ddf4f25 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -68,6 +68,7 @@ def __init__(self, psu_index, sku): psu_oper_status = "thermal/psu{}_pwr_status".format(self.index) #psu_oper_status should always be present for all SKUs self.psu_oper_status = os.path.join(self.psu_path, psu_oper_status) + self._name = "PSU{}".format(psu_index + 1) if sku in hwsku_dict_psu: filemap = psu_profile_list[hwsku_dict_psu[sku]] @@ -100,7 +101,10 @@ def __init__(self, psu_index, sku): fan = Fan(sku, psu_index, psu_index, True) if fan.get_presence(): - self._fan = fan + self._fan_list.append(fan) + + def get_name(self): + return self._name self.psu_green_led_path = "led_psu_green" self.psu_red_led_path = "led_psu_red" diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 67fbe3a6b51b..462267951130 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -36,24 +36,31 @@ THERMAL_API_GET_TEMPERATURE = "get_temperature" THERMAL_API_GET_HIGH_THRESHOLD = "get_high_threshold" +THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD = "get_high_critical_threshold" + +THERMAL_API_INVALID_HIGH_THRESHOLD = 0.0 HW_MGMT_THERMAL_ROOT = "/var/run/hw-management/thermal/" thermal_api_handler_cpu_core = { THERMAL_API_GET_TEMPERATURE:"cpu_core{}", - THERMAL_API_GET_HIGH_THRESHOLD:"cpu_core{}_max" + THERMAL_API_GET_HIGH_THRESHOLD:"cpu_core{}_max", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:"cpu_core{}_crit" } thermal_api_handler_cpu_pack = { THERMAL_API_GET_TEMPERATURE:"cpu_pack", - THERMAL_API_GET_HIGH_THRESHOLD:"cpu_pack_max" + THERMAL_API_GET_HIGH_THRESHOLD:"cpu_pack_max", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:"cpu_pack_crit" } thermal_api_handler_module = { THERMAL_API_GET_TEMPERATURE:"module{}_temp_input", - THERMAL_API_GET_HIGH_THRESHOLD:"module{}_temp_crit" + THERMAL_API_GET_HIGH_THRESHOLD:"module{}_temp_crit", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:"module{}_temp_emergency" } thermal_api_handler_psu = { THERMAL_API_GET_TEMPERATURE:"psu{}_temp", - THERMAL_API_GET_HIGH_THRESHOLD:"psu{}_temp_max" + THERMAL_API_GET_HIGH_THRESHOLD:"psu{}_temp_max", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:None } thermal_api_handler_gearbox = { THERMAL_API_GET_TEMPERATURE:"gearbox{}_temp_input", @@ -233,6 +240,7 @@ }, ] + def initialize_thermals(sku, thermal_list, psu_list): # create thermal objects for all categories of sensors tp_index = hwsku_dict_thermal[sku] @@ -262,6 +270,8 @@ def initialize_thermals(sku, thermal_list, psu_list): thermal = Thermal(category, start + index, True) thermal_list.append(thermal) + + class Thermal(ThermalBase): def __init__(self, category, index, has_index, dependency = None, hint = None): """ @@ -280,9 +290,11 @@ def __init__(self, category, index, has_index, dependency = None, hint = None): self.category = category self.temperature = self._get_file_from_api(THERMAL_API_GET_TEMPERATURE) self.high_threshold = self._get_file_from_api(THERMAL_API_GET_HIGH_THRESHOLD) + self.high_critical_threshold = self._get_file_from_api(THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD) self.dependency = dependency self.dependent_hint = hint + def get_name(self): """ Retrieves the name of the device @@ -292,6 +304,7 @@ def get_name(self): """ return self.name + def _read_generic_file(self, filename, len): """ Read a generic file, returns the contents of the file @@ -304,6 +317,7 @@ def _read_generic_file(self, filename, len): logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) return result + def _get_file_from_api(self, api_name): if self.category == THERMAL_DEV_CATEGORY_AMBIENT: if api_name == THERMAL_API_GET_TEMPERATURE: @@ -315,9 +329,13 @@ def _get_file_from_api(self, api_name): if self.category in thermal_device_categories_singleton: filename = handler else: - filename = handler.format(self.index) + if handler: + filename = handler.format(self.index) + else: + return None return join(HW_MGMT_THERMAL_ROOT, filename) + def get_temperature(self): """ Retrieves current temperature reading from thermal @@ -337,8 +355,11 @@ def get_temperature(self): if value_str is None: return None value_float = float(value_str) + if self.category == THERMAL_DEV_CATEGORY_MODULE and value_float == THERMAL_API_INVALID_HIGH_THRESHOLD: + return None return value_float / 1000.0 + def get_high_threshold(self): """ Retrieves the high threshold temperature of thermal @@ -353,4 +374,25 @@ def get_high_threshold(self): if value_str is None: return None value_float = float(value_str) + if self.category == THERMAL_DEV_CATEGORY_MODULE and value_float == THERMAL_API_INVALID_HIGH_THRESHOLD: + return None + return value_float / 1000.0 + + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + if self.high_critical_threshold is None: + return None + value_str = self._read_generic_file(self.high_critical_threshold, 0) + if value_str is None: + return None + value_float = float(value_str) + if self.category == THERMAL_DEV_CATEGORY_MODULE and value_float == THERMAL_API_INVALID_HIGH_THRESHOLD: + return None return value_float / 1000.0 diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py new file mode 100644 index 000000000000..72729287d1c5 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py @@ -0,0 +1,108 @@ +from sonic_platform_base.sonic_thermal_control.thermal_action_base import ThermalPolicyActionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + + +class SetFanSpeedAction(ThermalPolicyActionBase): + """ + Base thermal action class to set speed for fans + """ + # JSON field definition + JSON_FIELD_SPEED = 'speed' + + def __init__(self): + """ + Constructor of SetFanSpeedAction which actually do nothing. + """ + self.speed = None + + def load_from_json(self, json_obj): + """ + Construct SetFanSpeedAction via JSON. JSON example: + { + "type": "fan.all.set_speed" + "speed": "100" + } + :param json_obj: A JSON object representing a SetFanSpeedAction action. + :return: + """ + if SetFanSpeedAction.JSON_FIELD_SPEED in json_obj: + speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_SPEED]) + if speed < 0 or speed > 100: + raise ValueError('SetFanSpeedAction invalid speed value {} in JSON policy file, valid value should be [0, 100]'. + format(speed)) + self.speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_SPEED)) + + +@thermal_json_object('fan.all.set_speed') +class SetAllFanSpeedAction(SetFanSpeedAction): + """ + Action to set speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + fan_info_obj = thermal_info_dict[FanInfo.INFO_NAME] + for fan in fan_info_obj.get_presence_fans(): + fan.set_speed(self.speed) + + +@thermal_json_object('thermal_control.control') +class ControlThermalAlgoAction(ThermalPolicyActionBase): + """ + Action to control the thermal control algorithm + """ + # JSON field definition + JSON_FIELD_STATUS = 'status' + + def __init__(self): + self.status = True + + def load_from_json(self, json_obj): + """ + Construct ControlThermalAlgoAction via JSON. JSON example: + { + "type": "thermal_control.control" + "status": "true" + } + :param json_obj: A JSON object representing a ControlThermalAlgoAction action. + :return: + """ + if ControlThermalAlgoAction.JSON_FIELD_STATUS in json_obj: + status_str = json_obj[ControlThermalAlgoAction.JSON_FIELD_STATUS].lower() + if status_str == 'true': + self.status = True + elif status_str == 'false': + self.status = False + else: + raise ValueError('Invalid {} field value, please specify true of false'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + else: + raise ValueError('ControlThermalAlgoAction ' + 'missing mandatory field {} in JSON policy file'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + + def execute(self, thermal_info_dict): + """ + Disable thermal control algorithm + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + from .thermal_infos import ChassisInfo + if ChassisInfo.INFO_NAME in thermal_info_dict: + chassis_info_obj = thermal_info_dict[ChassisInfo.INFO_NAME] + chassis = chassis_info_obj.get_chassis() + thermal_manager = chassis.get_thermal_manager() + if self.status: + thermal_manager.start_thermal_control_algorithm() + else: + thermal_manager.stop_thermal_control_algorithm() + + diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py new file mode 100644 index 000000000000..2df59acc9bf1 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py @@ -0,0 +1,63 @@ +from sonic_platform_base.sonic_thermal_control.thermal_condition_base import ThermalPolicyConditionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + + +class FanCondition(ThermalPolicyConditionBase): + def get_fan_info(self, thermal_info_dict): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + return thermal_info_dict[FanInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('fan.any.absence') +class AnyFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.absence') +class AllFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_presence_fans()) == 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.presence') +class AllFanPresenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) == 0 if fan_info_obj else False + + +class PsuCondition(ThermalPolicyConditionBase): + def get_psu_info(self, thermal_info_dict): + from .thermal_infos import PsuInfo + if PsuInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[PsuInfo.INFO_NAME], PsuInfo): + return thermal_info_dict[PsuInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('psu.any.absence') +class AnyPsuAbsenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_absence_psus()) > 0 if psu_info_obj else False + + +@thermal_json_object('psu.all.absence') +class AllPsuAbsenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_presence_psus()) == 0 if psu_info_obj else False + + +@thermal_json_object('psu.all.presence') +class AllPsuPresenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_absence_psus()) == 0 if psu_info_obj else False + diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py new file mode 100644 index 000000000000..34d31e47d24c --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py @@ -0,0 +1,136 @@ +from sonic_platform_base.sonic_thermal_control.thermal_info_base import ThermalPolicyInfoBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + + +@thermal_json_object('fan_info') +class FanInfo(ThermalPolicyInfoBase): + """ + Fan information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'fan_info' + + def __init__(self): + self._absence_fans = set() + self._presence_fans = set() + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence fans. + :param chassis: The chassis object + :return: + """ + self._status_changed = False + for fan in chassis.get_all_fans(): + if fan.get_presence() and fan not in self._presence_fans: + self._presence_fans.add(fan) + self._status_changed = True + if fan in self._absence_fans: + self._absence_fans.remove(fan) + elif not fan.get_presence() and fan not in self._absence_fans: + self._absence_fans.add(fan) + self._status_changed = True + if fan in self._presence_fans: + self._presence_fans.remove(fan) + + def get_absence_fans(self): + """ + Retrieves absence fans + :return: A set of absence fans + """ + return self._absence_fans + + def get_presence_fans(self): + """ + Retrieves presence fans + :return: A set of presence fans + """ + return self._presence_fans + + def is_status_changed(self): + """ + Retrieves if the status of fan information changed + :return: True if status changed else False + """ + return self._status_changed + + +@thermal_json_object('psu_info') +class PsuInfo(ThermalPolicyInfoBase): + """ + PSU information needed by thermal policy + """ + INFO_NAME = 'psu_info' + + def __init__(self): + self._absence_psus = set() + self._presence_psus = set() + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence PSUs. + :param chassis: The chassis object + :return: + """ + self._status_changed = False + for psu in chassis.get_all_psus(): + if psu.get_presence() and psu not in self._presence_psus: + self._presence_psus.add(psu) + self._status_changed = True + if psu in self._absence_psus: + self._absence_psus.remove(psu) + elif not psu.get_presence() and psu not in self._absence_psus: + self._absence_psus.add(psu) + self._status_changed = True + if psu in self._presence_psus: + self._presence_psus.remove(psu) + + def get_absence_psus(self): + """ + Retrieves presence PSUs + :return: A set of absence PSUs + """ + return self._absence_psus + + def get_presence_psus(self): + """ + Retrieves presence PSUs + :return: A set of presence fans + """ + return self._presence_psus + + def is_status_changed(self): + """ + Retrieves if the status of PSU information changed + :return: True if status changed else False + """ + return self._status_changed + + +@thermal_json_object('chassis_info') +class ChassisInfo(ThermalPolicyInfoBase): + """ + Chassis information needed by thermal policy + """ + INFO_NAME = 'chassis_info' + + def __init__(self): + self._chassis = None + + def collect(self, chassis): + """ + Collect platform chassis. + :param chassis: The chassis object + :return: + """ + self._chassis = chassis + + def get_chassis(self): + """ + Retrieves platform chassis object + :return: A platform chassis object. + """ + return self._chassis diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py new file mode 100644 index 000000000000..133bb078ca20 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py @@ -0,0 +1,50 @@ +import os +from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase +from .thermal_actions import * +from .thermal_conditions import * +from .thermal_infos import * + + +class ThermalManager(ThermalManagerBase): + THERMAL_ALGORITHM_CONTROL_PATH = '/var/run/hw-management/config/suspend' + + @classmethod + def start_thermal_control_algorithm(cls): + """ + Start thermal control algorithm + + Returns: + bool: True if set success, False if fail. + """ + cls._control_thermal_control_algorithm(False) + + @classmethod + def stop_thermal_control_algorithm(cls): + """ + Stop thermal control algorithm + + Returns: + bool: True if set success, False if fail. + """ + cls._control_thermal_control_algorithm(True) + + @classmethod + def _control_thermal_control_algorithm(cls, suspend): + """ + Control thermal control algorithm + + Args: + suspend: Bool, indicate suspend the algorithm or not + + Returns: + bool: True if set success, False if fail. + """ + status = True + write_value = 1 if suspend else 0 + try: + with open(cls.THERMAL_ALGORITHM_CONTROL_PATH, 'w') as control_file: + control_file.write(str(write_value)) + except (ValueError, IOError): + status = False + + return status diff --git a/platform/mellanox/mlnx-platform-api/tests/__init__.py b/platform/mellanox/mlnx-platform-api/tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/mellanox/mlnx-platform-api/tests/mock_platform.py b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py new file mode 100644 index 000000000000..b8d070d44955 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py @@ -0,0 +1,44 @@ +class MockFan: + def __init__(self): + self.presence = True + self.speed = 60 + + def get_presence(self): + return self.presence + + def set_speed(self, speed): + self.speed = speed + + +class MockPsu: + def __init__(self): + self.presence = True + + def get_presence(self): + return self.presence + + +class MockChassis: + def __init__(self): + self.fan_list = [] + self.psu_list = [] + + def get_all_psus(self): + return self.psu_list + + def get_all_fans(self): + return self.fan_list + + def get_thermal_manager(self): + from sonic_platform.thermal_manager import ThermalManager + return ThermalManager + + def make_fan_absence(self): + fan = MockFan() + fan.presence = False + self.fan_list.append(fan) + + def make_psu_absence(self): + psu = MockPsu() + psu.presence = False + self.psu_list.append(psu) diff --git a/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py new file mode 100644 index 000000000000..ba9e502d4f74 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py @@ -0,0 +1,272 @@ +import os +import sys +import pytest +import json +from mock import MagicMock +from .mock_platform import MockChassis, MockFan, MockPsu + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +sys.path.insert(0, modules_path) + +from sonic_platform.thermal_manager import ThermalManager +from sonic_platform.thermal_infos import FanInfo, PsuInfo + + +@pytest.fixture(scope='session', autouse=True) +def thermal_manager(): + policy_file = os.path.join(test_path, 'thermal_policy.json') + ThermalManager.load(policy_file) + return ThermalManager + + +def test_load_policy(thermal_manager): + assert 'psu_info' in thermal_manager._thermal_info_dict + assert 'fan_info' in thermal_manager._thermal_info_dict + assert 'chassis_info' in thermal_manager._thermal_info_dict + + assert 'any fan absence' in thermal_manager._policy_dict + assert 'any psu absence' in thermal_manager._policy_dict + assert 'all fan and psu presence' in thermal_manager._policy_dict + + assert thermal_manager._fan_speed_when_suspend == 60 + assert thermal_manager._run_thermal_algorithm_at_boot_up == False + + +def test_fan_info(): + chassis = MockChassis() + chassis.make_fan_absence() + fan_info = FanInfo() + fan_info.collect(chassis) + assert len(fan_info.get_absence_fans()) == 1 + assert len(fan_info.get_presence_fans()) == 0 + assert fan_info.is_status_changed() + + fan_list = chassis.get_all_fans() + fan_list[0].presence = True + fan_info.collect(chassis) + assert len(fan_info.get_absence_fans()) == 0 + assert len(fan_info.get_presence_fans()) == 1 + assert fan_info.is_status_changed() + + +def test_psu_info(): + chassis = MockChassis() + chassis.make_psu_absence() + psu_info = PsuInfo() + psu_info.collect(chassis) + assert len(psu_info.get_absence_psus()) == 1 + assert len(psu_info.get_presence_psus()) == 0 + assert psu_info.is_status_changed() + + psu_list = chassis.get_all_psus() + psu_list[0].presence = True + psu_info.collect(chassis) + assert len(psu_info.get_absence_psus()) == 0 + assert len(psu_info.get_presence_psus()) == 1 + assert psu_info.is_status_changed() + + +def test_fan_policy(thermal_manager): + chassis = MockChassis() + chassis.make_fan_absence() + chassis.fan_list.append(MockFan()) + thermal_manager.start_thermal_control_algorithm = MagicMock() + thermal_manager.stop_thermal_control_algorithm = MagicMock() + thermal_manager.run_policy(chassis) + + fan_list = chassis.get_all_fans() + assert fan_list[1].speed == 100 + thermal_manager.stop_thermal_control_algorithm.assert_called_once() + + fan_list[0].presence = True + thermal_manager.run_policy(chassis) + thermal_manager.start_thermal_control_algorithm.assert_called_once() + + +def test_psu_policy(thermal_manager): + chassis = MockChassis() + chassis.make_psu_absence() + chassis.fan_list.append(MockFan()) + thermal_manager.start_thermal_control_algorithm = MagicMock() + thermal_manager.stop_thermal_control_algorithm = MagicMock() + thermal_manager.run_policy(chassis) + + fan_list = chassis.get_all_fans() + assert fan_list[0].speed == 100 + thermal_manager.stop_thermal_control_algorithm.assert_called_once() + + psu_list = chassis.get_all_psus() + psu_list[0].presence = True + thermal_manager.run_policy(chassis) + thermal_manager.start_thermal_control_algorithm.assert_called_once() + + +def test_any_fan_absence_condition(): + chassis = MockChassis() + chassis.make_fan_absence() + fan_info = FanInfo() + fan_info.collect(chassis) + + from sonic_platform.thermal_conditions import AnyFanAbsenceCondition + condition = AnyFanAbsenceCondition() + assert condition.is_match({'fan_info': fan_info}) + + fan = chassis.get_all_fans()[0] + fan.presence = True + fan_info.collect(chassis) + assert not condition.is_match({'fan_info': fan_info}) + + +def test_all_fan_absence_condition(): + chassis = MockChassis() + chassis.make_fan_absence() + fan = MockFan() + fan_list = chassis.get_all_fans() + fan_list.append(fan) + fan_info = FanInfo() + fan_info.collect(chassis) + + from sonic_platform.thermal_conditions import AllFanAbsenceCondition + condition = AllFanAbsenceCondition() + assert not condition.is_match({'fan_info': fan_info}) + + fan.presence = False + fan_info.collect(chassis) + assert condition.is_match({'fan_info': fan_info}) + + +def test_all_fan_presence_condition(): + chassis = MockChassis() + chassis.make_fan_absence() + fan = MockFan() + fan_list = chassis.get_all_fans() + fan_list.append(fan) + fan_info = FanInfo() + fan_info.collect(chassis) + + from sonic_platform.thermal_conditions import AllFanPresenceCondition + condition = AllFanPresenceCondition() + assert not condition.is_match({'fan_info': fan_info}) + + fan_list[0].presence = True + fan_info.collect(chassis) + assert condition.is_match({'fan_info': fan_info}) + + +def test_any_psu_absence_condition(): + chassis = MockChassis() + chassis.make_psu_absence() + psu_info = PsuInfo() + psu_info.collect(chassis) + + from sonic_platform.thermal_conditions import AnyPsuAbsenceCondition + condition = AnyPsuAbsenceCondition() + assert condition.is_match({'psu_info': psu_info}) + + psu = chassis.get_all_psus()[0] + psu.presence = True + psu_info.collect(chassis) + assert not condition.is_match({'psu_info': psu_info}) + + +def test_all_psu_absence_condition(): + chassis = MockChassis() + chassis.make_psu_absence() + psu = MockPsu() + psu_list = chassis.get_all_psus() + psu_list.append(psu) + psu_info = PsuInfo() + psu_info.collect(chassis) + + from sonic_platform.thermal_conditions import AllPsuAbsenceCondition + condition = AllPsuAbsenceCondition() + assert not condition.is_match({'psu_info': psu_info}) + + psu.presence = False + psu_info.collect(chassis) + assert condition.is_match({'psu_info': psu_info}) + + +def test_all_fan_presence_condition(): + chassis = MockChassis() + chassis.make_psu_absence() + psu = MockPsu() + psu_list = chassis.get_all_psus() + psu_list.append(psu) + psu_info = PsuInfo() + psu_info.collect(chassis) + + from sonic_platform.thermal_conditions import AllPsuPresenceCondition + condition = AllPsuPresenceCondition() + assert not condition.is_match({'psu_info': psu_info}) + + psu_list[0].presence = True + psu_info.collect(chassis) + assert condition.is_match({'psu_info': psu_info}) + + +def test_load_set_fan_speed_action(): + from sonic_platform.thermal_actions import SetAllFanSpeedAction + action = SetAllFanSpeedAction() + json_str = '{\"speed\": \"50\"}' + json_obj = json.loads(json_str) + action.load_from_json(json_obj) + assert action.speed == 50 + + json_str = '{\"speed\": \"-1\"}' + json_obj = json.loads(json_str) + with pytest.raises(ValueError): + action.load_from_json(json_obj) + + json_str = '{\"speed\": \"101\"}' + json_obj = json.loads(json_str) + with pytest.raises(ValueError): + action.load_from_json(json_obj) + + json_str = '{\"invalid\": \"101\"}' + json_obj = json.loads(json_str) + with pytest.raises(ValueError): + action.load_from_json(json_obj) + + +def test_execute_set_fan_speed_action(): + chassis = MockChassis() + fan_list = chassis.get_all_fans() + fan_list.append(MockFan()) + fan_list.append(MockFan()) + fan_info = FanInfo() + fan_info.collect(chassis) + + from sonic_platform.thermal_actions import SetAllFanSpeedAction + action = SetAllFanSpeedAction() + action.speed = 99 + action.execute({'fan_info': fan_info}) + assert fan_list[0].speed == 99 + assert fan_list[1].speed == 99 + + +def test_load_control_thermal_algo_action(): + from sonic_platform.thermal_actions import ControlThermalAlgoAction + action = ControlThermalAlgoAction() + json_str = '{\"status\": \"false\"}' + json_obj = json.loads(json_str) + action.load_from_json(json_obj) + assert not action.status + + json_str = '{\"status\": \"true\"}' + json_obj = json.loads(json_str) + action.load_from_json(json_obj) + assert action.status + + json_str = '{\"status\": \"invalid\"}' + json_obj = json.loads(json_str) + with pytest.raises(ValueError): + action.load_from_json(json_obj) + + json_str = '{\"invalid\": \"true\"}' + json_obj = json.loads(json_str) + with pytest.raises(ValueError): + action.load_from_json(json_obj) + + diff --git a/platform/mellanox/mlnx-platform-api/tests/thermal_policy.json b/platform/mellanox/mlnx-platform-api/tests/thermal_policy.json new file mode 100644 index 000000000000..5d31b2abd875 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/thermal_policy.json @@ -0,0 +1,72 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "false", + "fan_speed_when_suspend": "60" + }, + "info_types": [ + { + "type": "fan_info" + }, + { + "type": "psu_info" + }, + { + "type": "chassis_info" + } + ], + "policies": [ + { + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "any psu absence", + "conditions": [ + { + "type": "psu.any.absence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "all fan and psu presence", + "conditions": [ + { + "type": "fan.all.presence" + }, + { + "type": "psu.all.presence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "true" + } + ] + } + ] +} \ No newline at end of file diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index a37f4d2e9ee7..db1c8c5a0289 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -10,7 +10,7 @@ $(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(LIBSENSORS) $(LM_SENSORS) $(FANCONTROL) ifeq ($(CONFIGURED_PLATFORM),barefoot) $(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(PYTHON_THRIFT) endif -$(DOCKER_PLATFORM_MONITOR)_PYTHON_DEBS += $(SONIC_LEDD) $(SONIC_XCVRD) $(SONIC_PSUD) $(SONIC_SYSEEPROMD) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_DEBS += $(SONIC_LEDD) $(SONIC_XCVRD) $(SONIC_PSUD) $(SONIC_SYSEEPROMD) $(SONIC_THERMALCTLD) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY2) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) diff --git a/rules/sonic-thermalctld.mk b/rules/sonic-thermalctld.mk new file mode 100644 index 000000000000..775082e7bbce --- /dev/null +++ b/rules/sonic-thermalctld.mk @@ -0,0 +1,6 @@ +# sonic-thermalctld (SONiC Thermal control daemon) Debian package + +SONIC_THERMALCTLD = python-sonic-thermalctld_1.0-1_all.deb +$(SONIC_THERMALCTLD)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-thermalctld +$(SONIC_THERMALCTLD)_WHEEL_DEPENDS = $(SONIC_DAEMON_BASE_PY2) +SONIC_PYTHON_STDEB_DEBS += $(SONIC_THERMALCTLD) diff --git a/src/sonic-daemon-base/sonic_daemon_base/task_base.py b/src/sonic-daemon-base/sonic_daemon_base/task_base.py new file mode 100644 index 000000000000..e1738ffba213 --- /dev/null +++ b/src/sonic-daemon-base/sonic_daemon_base/task_base.py @@ -0,0 +1,50 @@ +import multiprocessing +import os +import signal +import threading + + +# +# ProcessTaskBase ===================================================================== +# +class ProcessTaskBase(object): # TODO: put this class to swss-platform-common + def __init__(self): + self.task_process = None + self.task_stopping_event = multiprocessing.Event() + + def task_worker(self): + pass + + def task_run(self): + if self.task_stopping_event.is_set(): + return + + self.task_process = multiprocessing.Process(target=self.task_worker) + self.task_process.start() + + def task_stop(self): + self.task_stopping_event.set() + os.kill(self.task_process.pid, signal.SIGKILL) + + +# +# ThreadTaskBase ===================================================================== +# +class ThreadTaskBase(object): # TODO: put this class to swss-platform-common; + def __init__(self): + self.task_thread = None + self.task_stopping_event = threading.Event() + + def task_worker(self): + pass + + def task_run(self): + if self.task_stopping_event.is_set(): + return + + self.task_thread = threading.Thread(target=self.task_worker) + self.task_thread.start() + + def task_stop(self): + self.task_stopping_event.set() + self.task_thread.join() diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 6f74dd3f4f42..ed50e72d0280 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 6f74dd3f4f42bc945467cffa4f889b50e4b1468a +Subproject commit ed50e72d028092399e2768e64a7a4ef01e7571de diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index a34ba131f618..fc455a7d01f8 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit a34ba131f618a8df6beec1f548aa08f9cedc48db +Subproject commit fc455a7d01f8df1ed6a55960056facdf1b3b0b3c From 7d0570c5176a7c582bbbd02526f80ae9b9693be5 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Tue, 10 Mar 2020 03:36:56 +0800 Subject: [PATCH 0417/1427] [Mellanox]Take advantage of sdk variable to customize the location where sdk_socket exists. (#4223) Take advantage of an SDK environment variable to customize the location where sdk_socket exists. In the latest SDK sdk_socket has been moved from /tmp to /var/run which is a better place to contain this kind of file. However, this prevents the subdirs under /var/run from being mapped to different volumes. To resolve this, we take advantage of an SDK variable to designate the location of sdk_socket. This requires every process that requires to access sdk_socket have this environment variable defined. However, to define environment variable for each process is less scalable. We take advantage of the docker scope environment variable to avoid that. It depends on PR 4227 --- files/build_templates/docker_image_ctl.j2 | 8 ++++++-- platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 | 2 ++ platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index dd067c74891e..5de892555a1b 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -201,11 +201,15 @@ start() { {%- if sonic_asic_platform == "mellanox" %} {%- if docker_container_name == "syncd" %} -v /var/log/mellanox/sniffer:/var/log/mellanox/sniffer:rw \ - -v mlnx_sdk_socket:/tmp \ + -v mlnx_sdk_socket:/var/run/sx_sdk \ + -v mlnx_sdk_ready:/tmp \ -v /dev/shm:/dev/shm:rw \ + -e SX_API_SOCKET_FILE=/var/run/sx_sdk/sx_api.sock \ {%- elif docker_container_name == "pmon" %} -v /var/run/hw-management:/var/run/hw-management:rw \ - -v mlnx_sdk_socket:/tmp \ + -v mlnx_sdk_socket:/var/run/sx_sdk \ + -v mlnx_sdk_ready:/tmp \ + -e SX_API_SOCKET_FILE=/var/run/sx_sdk/sx_api.sock \ -v /dev/shm:/dev/shm:rw \ {%- else %} --tmpfs /tmp \ diff --git a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 index d9b86e782531..3f6225c96bd3 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 @@ -4,6 +4,8 @@ FROM docker-syncd-mlnx ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive +RUN mkdir -p /var/run/sx_sdk + RUN apt-get purge -y syncd {% if docker_syncd_mlnx_rpc_debs.strip() -%} diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index 4d22335ec783..6953933735fa 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -4,6 +4,8 @@ FROM docker-config-engine-stretch ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf +RUN mkdir -p /var/run/sx_sdk + ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive From fc91f81dab6e47e65345e29733a6627763d010b0 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Mon, 9 Mar 2020 16:13:49 -0700 Subject: [PATCH 0418/1427] [libteam]: Update libteam to the latest master (#4216) --- rules/libteam.mk | 2 +- src/libteam/Makefile | 4 +- ...rily-remove-redundant-debug-messages.patch | 16 +-- ...r-will-send-lacp-update-right-after-.patch | 20 ++-- ...back-support-for-single-member-port-.patch | 35 +++--- ...-same-hwaddr-to-lag-port-to-avoid-di.patch | 17 ++- ...ult-buffer-size-from-98304-to-983040.patch | 13 +-- ...tively-shutdown-port-channel-has-mem.patch | 18 ++-- ...PDU-immediately-if-our-state-changed.patch | 19 ++-- .../0008-libteam-Add-warm_reboot-mode.patch | 60 +++++------ ...ith_port-race-condition-with-newlink.patch | 14 ++- ...erfd-returned-0-don-t-consider-this-.patch | 10 +- ...sible-race-in-master-ifname-callback.patch | 101 ------------------ src/libteam/patch/series | 1 - 14 files changed, 107 insertions(+), 223 deletions(-) delete mode 100644 src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch diff --git a/rules/libteam.mk b/rules/libteam.mk index 75e8f5db62b0..02cdcbe0306a 100644 --- a/rules/libteam.mk +++ b/rules/libteam.mk @@ -1,6 +1,6 @@ # libteam packages -LIBTEAM_VERSION = 1.28-1 +LIBTEAM_VERSION = 1.30-1 export LIBTEAM_VERSION diff --git a/src/libteam/Makefile b/src/libteam/Makefile index b1ef12375416..9fd5f582ed4d 100644 --- a/src/libteam/Makefile +++ b/src/libteam/Makefile @@ -15,7 +15,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf ./libteam git clone https://github.com/jpirko/libteam.git pushd ./libteam - git checkout -b teamd -f 8c7614abf5993d92e332a800f244bdebd7c9a2c8 + git checkout -b teamd -f c7237377dead39ae4a711297203bacf7edb9fa41 # Apply patch series stg init @@ -25,7 +25,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Obtain debian packaging git clone https://salsa.debian.org/debian/libteam.git tmp pushd ./tmp - git checkout -f 7188c361 # v1.28-1 + git checkout -f debian/1.30-1 popd mv tmp/debian libteam/ diff --git a/src/libteam/patch/0001-libteam-Temporarily-remove-redundant-debug-messages.patch b/src/libteam/patch/0001-libteam-Temporarily-remove-redundant-debug-messages.patch index d922c91c425e..bd5f2857c4bf 100644 --- a/src/libteam/patch/0001-libteam-Temporarily-remove-redundant-debug-messages.patch +++ b/src/libteam/patch/0001-libteam-Temporarily-remove-redundant-debug-messages.patch @@ -1,25 +1,25 @@ -From 10602c2b1184aa0c6907b5a7f06fcba8a7141148 Mon Sep 17 00:00:00 2001 -From: Shuotian Cheng -Date: Mon, 27 Feb 2017 14:21:09 -0800 -Subject: [PATCH 1/8] libteam: Temporarily remove redundant debug messages +From fa8c4604e739abde29278b403a1a1d502337c21b Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 3 Mar 2020 12:47:32 -0800 +Subject: [PATCH] libteam: Temporarily remove redundant debug messages --- teamd/teamd_runner_lacp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c -index d292d69..7c91aed 100644 +index ec01237..2d5a823 100644 --- a/teamd/teamd_runner_lacp.c +++ b/teamd/teamd_runner_lacp.c @@ -929,8 +929,6 @@ static void lacp_port_actor_update(struct lacp_port *lacp_port) state |= INFO_STATE_DEFAULTED; if (teamd_port_count(lacp_port->ctx) > 0) state |= INFO_STATE_AGGREGATION; -- teamd_log_dbg("%s: lacp info state: 0x%02X.", lacp_port->tdport->ifname, -- state); +- teamd_log_dbg(lacp_port->ctx, "%s: lacp info state: 0x%02X.", +- lacp_port->tdport->ifname, state); lacp_port->actor.state = state; } -- -2.7.4 +2.17.1.windows.2 diff --git a/src/libteam/patch/0002-teamd-lacp-runner-will-send-lacp-update-right-after-.patch b/src/libteam/patch/0002-teamd-lacp-runner-will-send-lacp-update-right-after-.patch index c4e78257103d..00b4badce883 100644 --- a/src/libteam/patch/0002-teamd-lacp-runner-will-send-lacp-update-right-after-.patch +++ b/src/libteam/patch/0002-teamd-lacp-runner-will-send-lacp-update-right-after-.patch @@ -1,11 +1,9 @@ -From 0ce56490a44191c4b17a75cc21aa6a5bdc535f1d Mon Sep 17 00:00:00 2001 -From: yorke -Date: Mon, 3 Jun 2019 11:58:19 +0800 -Subject: [PATCH 2/8] [teamd] lacp runner will send lacp update right after it - received SIGINT signal From: Pavel Shirshov - Date: Wed, 20 Sep 2017 00:34:07 +0000 +From 9e697b0c9fbd01f024acfea8aa25334816425c2b Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 3 Mar 2020 12:50:23 -0800 +Subject: [PATCH] [teamd] lacp runner will send lacp update right after it + received SIGINT signal -Signed-off-by: yorke --- teamd/teamd.c | 1 + teamd/teamd.h | 3 +++ @@ -14,7 +12,7 @@ Signed-off-by: yorke 4 files changed, 28 insertions(+) diff --git a/teamd/teamd.c b/teamd/teamd.c -index 6c47312..58d4fc8 100644 +index e035ac5..dc46a62 100644 --- a/teamd/teamd.c +++ b/teamd/teamd.c @@ -392,6 +392,7 @@ static int teamd_run_loop_run(struct teamd_context *ctx) @@ -26,7 +24,7 @@ index 6c47312..58d4fc8 100644 if (err) return err; diff --git a/teamd/teamd.h b/teamd/teamd.h -index 01bd022..e71a5dc 100644 +index f94c918..01ebc84 100644 --- a/teamd/teamd.h +++ b/teamd/teamd.h @@ -193,11 +193,14 @@ struct teamd_event_watch_ops { @@ -69,7 +67,7 @@ index 65aa46a..221803e 100644 struct teamd_port *tdport) { diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c -index 7c91aed..4dbd015 100644 +index 2d5a823..7592b01 100644 --- a/teamd/teamd_runner_lacp.c +++ b/teamd/teamd_runner_lacp.c @@ -1421,6 +1421,16 @@ static int lacp_event_watch_port_changed(struct teamd_context *ctx, @@ -98,5 +96,5 @@ index 7c91aed..4dbd015 100644 static int lacp_carrier_init(struct teamd_context *ctx, struct lacp *lacp) -- -2.7.4 +2.17.1.windows.2 diff --git a/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch b/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch index e1234c294fd8..742db5fc6a98 100644 --- a/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch +++ b/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch @@ -1,16 +1,14 @@ -commit f475746f56602a40861b8d94eac5f0979c4703f3 -Author: yorke -Date: Mon Jun 3 12:02:36 2019 +0800 +From 4696acb51172dbe486d175073bdce8c94817f422 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 3 Mar 2020 12:52:28 -0800 +Subject: [PATCH] [libteam] Add fallback support for single-member-port LAG - From 9b40af58575a89d06be51cfbb5a2265a59826110 Mon Sep 17 00:00:00 2001 - Subject: [PATCH 3/8] [libteam] Add fallback support for single-member-port LAG - From: Haiyang Zheng Date: Fri, 15 Dec - 2017 21:07:53 -0800 - - Signed-off-by: yorke +--- + teamd/teamd_runner_lacp.c | 48 +++++++++++++++++++++++++++++++++++---- + 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c -index 4dbd015..f8a9e16 100644 +index 7592b01..2062bf2 100644 --- a/teamd/teamd_runner_lacp.c +++ b/teamd/teamd_runner_lacp.c @@ -138,6 +138,8 @@ struct lacp { @@ -24,12 +22,12 @@ index 4dbd015..f8a9e16 100644 enum lacp_agg_select_policy agg_select_policy; @@ -272,6 +274,11 @@ static int lacp_load_config(struct teamd_context *ctx, struct lacp *lacp) lacp->cfg.fast_rate = LACP_CFG_DFLT_FAST_RATE; - teamd_log_dbg("Using fast_rate \"%d\".", lacp->cfg.fast_rate); + teamd_log_dbg(ctx, "Using fast_rate \"%d\".", lacp->cfg.fast_rate); + err = teamd_config_bool_get(ctx, &lacp->cfg.fallback, "$.runner.fallback"); + if (err) + lacp->cfg.fallback = LACP_CFG_DFLT_FALLBACK; -+ teamd_log_dbg("Using fallback \"%d\".", lacp->cfg.fallback); ++ teamd_log_dbg(ctx, "Using fallback \"%d\".", lacp->cfg.fallback); + err = teamd_config_int_get(ctx, &tmp, "$.runner.min_ports"); if (err) { @@ -45,7 +43,7 @@ index 4dbd015..f8a9e16 100644 + */ +static bool is_lacp_fallback_eligible(struct lacp_port *lacp_port) +{ -+ teamd_log_dbg("%s fallback eligible state \"%d \" cfg \"%d\".", ++ teamd_log_dbg(lacp_port->ctx, "%s fallback eligible state \"%d \" cfg \"%d\".", + lacp_port->tdport->ifname, lacp_port->state, + lacp_port->lacp->cfg.fallback); + return lacp_port->state == PORT_STATE_DEFAULTED && @@ -107,15 +105,18 @@ index 4dbd015..f8a9e16 100644 static int lacp_state_select_policy_get(struct teamd_context *ctx, struct team_state_gsc *gsc, void *priv) -@@ -1529,6 +1564,11 @@ static const struct teamd_state_val lacp_state_vals[] = { +@@ -1528,6 +1563,11 @@ static const struct teamd_state_val lacp_state_vals[] = { + .type = TEAMD_STATE_ITEM_TYPE_BOOL, .getter = lacp_state_fast_rate_get, }, - { ++ { + .subpath = "fallback", + .type = TEAMD_STATE_ITEM_TYPE_BOOL, + .getter = lacp_state_fallback_get, + }, -+ { + { .subpath = "select_policy", .type = TEAMD_STATE_ITEM_TYPE_STRING, - .getter = lacp_state_select_policy_get, +-- +2.17.1.windows.2 + diff --git a/src/libteam/patch/0004-Skip-setting-the-same-hwaddr-to-lag-port-to-avoid-di.patch b/src/libteam/patch/0004-Skip-setting-the-same-hwaddr-to-lag-port-to-avoid-di.patch index 3d99132b92dc..8f3a8592814a 100644 --- a/src/libteam/patch/0004-Skip-setting-the-same-hwaddr-to-lag-port-to-avoid-di.patch +++ b/src/libteam/patch/0004-Skip-setting-the-same-hwaddr-to-lag-port-to-avoid-di.patch @@ -1,17 +1,14 @@ -From e18cbe5a6c76366923a8ace830c89056a1542745 Mon Sep 17 00:00:00 2001 -From: yorke -Date: Mon, 3 Jun 2019 12:06:00 +0800 -Subject: [PATCH 4/8] Skip setting the same hwaddr to lag port to avoid - disrupting From: Jipan Yang Date: Sun, - 24 Feb 2019 00:04:15 -0800 +From 09af7e3106720c871cdbadff9f661685aa1bdb16 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 3 Mar 2020 12:54:09 -0800 +Subject: [PATCH] Skip setting the same hwaddr to lag port to avoid disrupting -Signed-off-by: yorke --- teamd/teamd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/teamd/teamd.c b/teamd/teamd.c -index 58d4fc8..9dc85b5 100644 +index dc46a62..bf42347 100644 --- a/teamd/teamd.c +++ b/teamd/teamd.c @@ -834,7 +834,15 @@ static int teamd_set_hwaddr(struct teamd_context *ctx) @@ -22,7 +19,7 @@ index 58d4fc8..9dc85b5 100644 + + if(!memcmp(hwaddr, ctx->hwaddr, hwaddr_len)) { + err = 0; -+ teamd_log_dbg("Skip setting same hwaddr string: \"%s\".", hwaddr_str); ++ teamd_log_dbg(ctx, "Skip setting same hwaddr string: \"%s\".", hwaddr_str); + } + else{ + err = team_hwaddr_set(ctx->th, ctx->ifindex, hwaddr, hwaddr_len); @@ -32,5 +29,5 @@ index 58d4fc8..9dc85b5 100644 ctx->hwaddr_explicit = true; free_hwaddr: -- -2.7.4 +2.17.1.windows.2 diff --git a/src/libteam/patch/0005-Increase-default-buffer-size-from-98304-to-983040.patch b/src/libteam/patch/0005-Increase-default-buffer-size-from-98304-to-983040.patch index 517b86992e27..ac86c549b686 100644 --- a/src/libteam/patch/0005-Increase-default-buffer-size-from-98304-to-983040.patch +++ b/src/libteam/patch/0005-Increase-default-buffer-size-from-98304-to-983040.patch @@ -1,11 +1,8 @@ -From 39e5b0a15bf276dffa6b8c61594ee945248a4e27 Mon Sep 17 00:00:00 2001 -From: yorke -Date: Mon, 3 Jun 2019 12:32:33 +0800 -Subject: [PATCH 5/8] Increase default buffer size from 98304 to 983040 - From: Pavel Shirshov - https://github.com/Azure/sonic-buildimage/pull/2822 +From fcb9932bdb9212e9b18302de4ffb4d64003e93ab Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 3 Mar 2020 12:55:50 -0800 +Subject: [PATCH] Increase default buffer size from 98304 to 983040 -Signed-off-by: yorke --- libteam/libteam.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) @@ -27,5 +24,5 @@ index 9c9c93a..2cc80ca 100644 /** * @param th libteam library context -- -2.7.4 +2.17.1.windows.2 diff --git a/src/libteam/patch/0006-teamd-Administratively-shutdown-port-channel-has-mem.patch b/src/libteam/patch/0006-teamd-Administratively-shutdown-port-channel-has-mem.patch index 344dbc8d2609..7cc4e52c8a0f 100644 --- a/src/libteam/patch/0006-teamd-Administratively-shutdown-port-channel-has-mem.patch +++ b/src/libteam/patch/0006-teamd-Administratively-shutdown-port-channel-has-mem.patch @@ -1,20 +1,18 @@ -From f1eec95dd0475591897a781eba15d8d8ce370a6a Mon Sep 17 00:00:00 2001 -From: yorke -Date: Mon, 3 Jun 2019 13:21:07 +0800 -Subject: [PATCH 6/8] [teamd]: Administratively shutdown port channel has - member ports in deselected state and traffic is not forwarded From: - phanindra-tv https://github.com/Azure/sonic-buildimage/pull/2882 +From b188ed48f9ea6873a2c9263d5e036a3634c0f4ba Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 3 Mar 2020 12:59:09 -0800 +Subject: [PATCH] [teamd]: Administratively shutdown port channel has member + ports in deselected state and traffic is not forwarded -Signed-off-by: yorke --- teamd/teamd_runner_lacp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c -index 9836824..7bf3700 100644 +index 2062bf2..fa732ba 100644 --- a/teamd/teamd_runner_lacp.c +++ b/teamd/teamd_runner_lacp.c -@@ -1101,12 +1101,17 @@ static int lacpdu_recv(struct lacp_port *lacp_port) +@@ -1103,12 +1103,17 @@ static int lacpdu_recv(struct lacp_port *lacp_port) struct lacpdu lacpdu; struct sockaddr_ll ll_from; int err; @@ -33,5 +31,5 @@ index 9836824..7bf3700 100644 return 0; -- -2.7.4 +2.17.1.windows.2 diff --git a/src/libteam/patch/0007-Send-LACP-PDU-immediately-if-our-state-changed.patch b/src/libteam/patch/0007-Send-LACP-PDU-immediately-if-our-state-changed.patch index d26e2a74ea42..f4af9169ae1e 100644 --- a/src/libteam/patch/0007-Send-LACP-PDU-immediately-if-our-state-changed.patch +++ b/src/libteam/patch/0007-Send-LACP-PDU-immediately-if-our-state-changed.patch @@ -1,20 +1,17 @@ -From b82da0dc94ca34b039396328a8c2fcb61aa73c0f Mon Sep 17 00:00:00 2001 -From: yorke -Date: Mon, 3 Jun 2019 13:27:26 +0800 -Subject: [PATCH 7/8] Send LACP PDU immediately if our state changed From: - Pavel Shirshov Date: Wed, 29 May 2019 19:15:20 - +0000 +From 780cc967a5544d3ab6f43cba4076b5e0dbb48395 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 3 Mar 2020 13:01:14 -0800 +Subject: [PATCH] Send LACP PDU immediately if our state changed -Signed-off-by: yorke --- teamd/teamd_runner_lacp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c -index 7bf3700..4016b15 100644 +index fa732ba..55abe88 100644 --- a/teamd/teamd_runner_lacp.c +++ b/teamd/teamd_runner_lacp.c -@@ -1017,8 +1017,7 @@ static int lacp_port_set_state(struct lacp_port *lacp_port, +@@ -1019,8 +1019,7 @@ static int lacp_port_set_state(struct lacp_port *lacp_port, return err; lacp_port_actor_update(lacp_port); @@ -24,7 +21,7 @@ index 7bf3700..4016b15 100644 return lacpdu_send(lacp_port); } -@@ -1136,9 +1135,10 @@ static int lacpdu_recv(struct lacp_port *lacp_port) +@@ -1138,9 +1137,10 @@ static int lacpdu_recv(struct lacp_port *lacp_port) if (err) return err; @@ -38,5 +35,5 @@ index 7bf3700..4016b15 100644 err = lacpdu_send(lacp_port); if (err) -- -2.7.4 +2.17.1.windows.2 diff --git a/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch b/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch index 3f428bbec19e..440d351a8b6e 100644 --- a/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch +++ b/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch @@ -1,7 +1,7 @@ -From 113d482704198685fba09cd2597fd93ca9d297c5 Mon Sep 17 00:00:00 2001 +From a4ab4de68134f6425f704a2ddcda33a4930645de Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Tue, 1 Oct 2019 09:23:23 -0700 -Subject: [PATCH 1/1] [libteam]: Reimplement Warm-Reboot procedure +Date: Tue, 3 Mar 2020 13:04:57 -0800 +Subject: [PATCH] [libteam]: Reimplement Warm-Reboot procedure' --- libteam/ifinfo.c | 6 +- @@ -35,7 +35,7 @@ index 46d56a2..b86d34c 100644 } } diff --git a/teamd/teamd.c b/teamd/teamd.c -index 9dc85b5..17221a9 100644 +index bf42347..221d71d 100644 --- a/teamd/teamd.c +++ b/teamd/teamd.c @@ -117,7 +117,9 @@ static void print_help(const struct teamd_context *ctx) { @@ -139,7 +139,7 @@ index 9dc85b5..17221a9 100644 } return 0; } -@@ -1531,7 +1574,7 @@ static int teamd_start(struct teamd_context *ctx, enum teamd_exit_code *p_ret) +@@ -1533,7 +1576,7 @@ static int teamd_start(struct teamd_context *ctx, enum teamd_exit_code *p_ret) return -errno; } @@ -149,7 +149,7 @@ index 9dc85b5..17221a9 100644 daemon_retval_send(errno); err = -errno; diff --git a/teamd/teamd.h b/teamd/teamd.h -index e71a5dc..418214d 100644 +index 01ebc84..701a6a4 100644 --- a/teamd/teamd.h +++ b/teamd/teamd.h @@ -126,6 +126,9 @@ struct teamd_context { @@ -203,7 +203,7 @@ index 221803e..bd4dcc1 100644 struct teamd_port *tdport) { diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c -index f98a90d..a87e809 100644 +index 166da57..03f8d63 100644 --- a/teamd/teamd_per_port.c +++ b/teamd/teamd_per_port.c @@ -350,6 +350,12 @@ static int teamd_port_remove(struct teamd_context *ctx, @@ -211,16 +211,16 @@ index f98a90d..a87e809 100644 int err; + if (ctx->keep_ports) { -+ teamd_log_dbg("%s: Keeping port (found ifindex \"%d\").", ++ teamd_log_dbg(ctx, "%s: Keeping port (found ifindex \"%d\").", + tdport->ifname, tdport->ifindex); + return 0; + } + - teamd_log_dbg("%s: Removing port (found ifindex \"%d\").", + teamd_log_dbg(ctx, "%s: Removing port (found ifindex \"%d\").", tdport->ifname, tdport->ifindex); err = team_port_remove(ctx->th, tdport->ifindex); diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c -index 4016b15..81be5b7 100644 +index 55abe88..f225fb2 100644 --- a/teamd/teamd_runner_lacp.c +++ b/teamd/teamd_runner_lacp.c @@ -31,6 +31,7 @@ @@ -345,7 +345,7 @@ index 4016b15..81be5b7 100644 + char filename[PATH_MAX]; + int err, nitems; + -+ teamd_log_dbg("WR-mode. function lacpdu_read(): %s", lacp_port->tdport->ifname); ++ teamd_log_dbg(lacp_port->ctx, "WR-mode. function lacpdu_read(): %s", lacp_port->tdport->ifname); + + generate_path(lacp_port->ctx, filename, lacp_port->tdport->ifname); + @@ -423,7 +423,7 @@ index 4016b15..81be5b7 100644 + FILE *fp; + int data1, data2, i, err; + -+ teamd_log_dbg("WR-mode. function lacp_state_load()"); ++ teamd_log_dbg(ctx, "WR-mode. function lacp_state_load()"); + + generate_path(ctx, filename, ctx->team_devname); + @@ -473,7 +473,7 @@ index 4016b15..81be5b7 100644 static struct lacp_port *lacp_port_get(struct lacp *lacp, struct teamd_port *tdport) { -@@ -486,20 +697,95 @@ static int lacp_set_carrier(struct lacp *lacp, bool carrier_up) +@@ -488,20 +699,95 @@ static int lacp_set_carrier(struct lacp *lacp, bool carrier_up) return 0; } @@ -489,7 +489,7 @@ index 4016b15..81be5b7 100644 int err; + if (lacp->ctx->warm_start_mode) { -+ teamd_log_dbg("WR-mode. function lacp_update_carrier()"); ++ teamd_log_dbg(lacp->ctx, "WR-mode. function lacp_update_carrier()"); + } + ports_enabled = 0; @@ -561,7 +561,7 @@ index 4016b15..81be5b7 100644 + } + + if (ports_enabled >= lacp->cfg.min_ports) { -+ teamd_log_dbg("Enable carrier. Number of enabled ports %d >= configured min_ports %d", ++ teamd_log_dbg(lacp->ctx, "Enable carrier. Number of enabled ports %d >= configured min_ports %d", + ports_enabled, lacp->cfg.min_ports); + return lacp_set_carrier(lacp, true); + } @@ -572,7 +572,7 @@ index 4016b15..81be5b7 100644 } return lacp_set_carrier(lacp, false); -@@ -919,6 +1205,18 @@ static void lacp_port_actor_system_update(struct lacp_port *lacp_port) +@@ -921,6 +1207,18 @@ static void lacp_port_actor_system_update(struct lacp_port *lacp_port) memcpy(actor->system, lacp_port->ctx->hwaddr, ETH_ALEN); } @@ -591,7 +591,7 @@ index 4016b15..81be5b7 100644 static void lacp_port_actor_init(struct lacp_port *lacp_port) { struct lacpdu_info *actor = &lacp_port->actor; -@@ -926,7 +1224,7 @@ static void lacp_port_actor_init(struct lacp_port *lacp_port) +@@ -928,7 +1226,7 @@ static void lacp_port_actor_init(struct lacp_port *lacp_port) actor->system_priority = htons(lacp_port->lacp->cfg.sys_prio); actor->key = htons(lacp_port->cfg.lacp_key); actor->port_priority = htons(lacp_port->cfg.lacp_prio); @@ -600,7 +600,7 @@ index 4016b15..81be5b7 100644 lacp_port_actor_system_update(lacp_port); } -@@ -1006,6 +1304,13 @@ static int lacp_port_set_state(struct lacp_port *lacp_port, +@@ -1008,6 +1306,13 @@ static int lacp_port_set_state(struct lacp_port *lacp_port, break; } @@ -614,7 +614,7 @@ index 4016b15..81be5b7 100644 teamd_log_info("%s: Changed port state: \"%s\" -> \"%s\"", lacp_port->tdport->ifname, lacp_port_state_name[lacp_port->state], -@@ -1095,34 +1400,23 @@ static int lacpdu_send(struct lacp_port *lacp_port) +@@ -1097,34 +1402,23 @@ static int lacpdu_send(struct lacp_port *lacp_port) return err; } @@ -657,7 +657,7 @@ index 4016b15..81be5b7 100644 err = lacp_port_partner_update(lacp_port); if (err) return err; -@@ -1138,21 +1432,56 @@ static int lacpdu_recv(struct lacp_port *lacp_port) +@@ -1140,21 +1434,56 @@ static int lacpdu_recv(struct lacp_port *lacp_port) lacp_port_actor_update(lacp_port); /* Check if the other side has correct info about us */ @@ -717,16 +717,16 @@ index 4016b15..81be5b7 100644 static int lacp_callback_timeout(struct teamd_context *ctx, int events, void *priv) { -@@ -1258,6 +1587,8 @@ static int lacp_port_added(struct teamd_context *ctx, +@@ -1260,6 +1589,8 @@ static int lacp_port_added(struct teamd_context *ctx, struct lacp *lacp = creator_priv; int err; -+ teamd_log_dbg("function lacp_port_added(): %s", tdport->ifname); ++ teamd_log_dbg(ctx, "function lacp_port_added(): %s", tdport->ifname); + lacp_port->ctx = ctx; lacp_port->tdport = tdport; lacp_port->lacp = lacp; -@@ -1304,6 +1635,13 @@ static int lacp_port_added(struct teamd_context *ctx, +@@ -1306,6 +1637,13 @@ static int lacp_port_added(struct teamd_context *ctx, goto periodic_callback_del; } @@ -740,12 +740,12 @@ index 4016b15..81be5b7 100644 /* Newly added ports are disabled */ err = team_set_port_enabled(ctx->th, tdport->ifindex, false); if (err) { -@@ -1341,7 +1679,13 @@ static void lacp_port_removed(struct teamd_context *ctx, +@@ -1343,7 +1681,13 @@ static void lacp_port_removed(struct teamd_context *ctx, { struct lacp_port *lacp_port = priv; - lacp_port_set_state(lacp_port, PORT_STATE_DISABLED); -+ teamd_log_dbg("function lacp_port_removed(): %s", tdport->ifname); ++ teamd_log_dbg(lacp_port->ctx, "function lacp_port_removed(): %s", tdport->ifname); + + if (!lacp_port->ctx->keep_ports) { + /* Don't transition into DISABLED state, @@ -755,7 +755,7 @@ index 4016b15..81be5b7 100644 teamd_loop_callback_del(ctx, LACP_TIMEOUT_CB_NAME, lacp_port); teamd_loop_callback_del(ctx, LACP_PERIODIC_CB_NAME, lacp_port); teamd_loop_callback_del(ctx, LACP_SOCKET_CB_NAME, lacp_port); -@@ -1449,16 +1793,51 @@ static int lacp_event_watch_port_changed(struct teamd_context *ctx, +@@ -1451,16 +1795,51 @@ static int lacp_event_watch_port_changed(struct teamd_context *ctx, return lacp_port_link_update(lacp_port); } @@ -810,7 +810,7 @@ index 4016b15..81be5b7 100644 static const struct teamd_event_watch_ops lacp_event_watch_ops = { .hwaddr_changed = lacp_event_watch_hwaddr_changed, .port_hwaddr_changed = lacp_event_watch_port_hwaddr_changed, -@@ -1467,21 +1846,35 @@ static const struct teamd_event_watch_ops lacp_event_watch_ops = { +@@ -1469,21 +1848,35 @@ static const struct teamd_event_watch_ops lacp_event_watch_ops = { .port_changed = lacp_event_watch_port_changed, .admin_state_changed = lacp_event_watch_admin_state_changed, .refresh = lacp_event_watch_refresh, @@ -826,7 +826,7 @@ index 4016b15..81be5b7 100644 + lacp->carrier_up = false; + + if (ctx->warm_start_mode) { -+ teamd_log_dbg("WR-mode. function lacp_carrier_init()"); ++ teamd_log_dbg(ctx, "WR-mode. function lacp_carrier_init()"); + + /* Disable WR start mode if LAG interface was down */ + if (lacp->wr.carrier_up) { @@ -851,7 +851,7 @@ index 4016b15..81be5b7 100644 return 0; } -@@ -1949,6 +2342,12 @@ static int lacp_init(struct teamd_context *ctx, void *priv) +@@ -1951,6 +2344,12 @@ static int lacp_init(struct teamd_context *ctx, void *priv) } lacp->ctx = ctx; @@ -864,7 +864,7 @@ index 4016b15..81be5b7 100644 err = teamd_hash_func_set(ctx); if (err) return err; -@@ -1990,10 +2389,13 @@ static void lacp_fini(struct teamd_context *ctx, void *priv) +@@ -1992,10 +2391,13 @@ static void lacp_fini(struct teamd_context *ctx, void *priv) { struct lacp *lacp = priv; diff --git a/src/libteam/patch/0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch b/src/libteam/patch/0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch index bab3a9108325..e2193345f576 100644 --- a/src/libteam/patch/0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch +++ b/src/libteam/patch/0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch @@ -1,6 +1,6 @@ -From 9a27e9b85afbbf6235e61c2426481e49a2139219 Mon Sep 17 00:00:00 2001 -From: Shu0T1an ChenG -Date: Tue, 15 Jan 2019 12:23:02 -0800 +From a678d9087b05aaf6947e15f0cc9a93ace299466f Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 3 Mar 2020 13:14:13 -0800 Subject: [PATCH] Fix ifinfo_link_with_port race condition with newlink The race condition could happen like this: @@ -18,17 +18,15 @@ to be added into the team handler's port list. This fix adds a condition to check if ifinfo_link_with_port is linking ifinfo to a port or to the team interface itself. If it is a port, ifinfo_find_create function is used to fix the race condition. - -Signed-off-by: Shu0T1an ChenG --- libteam/ifinfo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libteam/ifinfo.c b/libteam/ifinfo.c -index 44de4ca..444e0cd 100644 +index b86d34c..e48193e 100644 --- a/libteam/ifinfo.c +++ b/libteam/ifinfo.c -@@ -429,7 +429,10 @@ int ifinfo_link_with_port(struct team_handle *th, uint32_t ifindex, +@@ -451,7 +451,10 @@ int ifinfo_link_with_port(struct team_handle *th, uint32_t ifindex, { struct team_ifinfo *ifinfo; @@ -41,5 +39,5 @@ index 44de4ca..444e0cd 100644 return -ENOENT; if (ifinfo->linked) -- -2.1.4 +2.17.1.windows.2 diff --git a/src/libteam/patch/0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch b/src/libteam/patch/0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch index e703d73e0263..37eb10d20d49 100644 --- a/src/libteam/patch/0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch +++ b/src/libteam/patch/0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch @@ -1,6 +1,6 @@ -From 038bed6fe3970dc829dbf9a282f7bea7198e7826 Mon Sep 17 00:00:00 2001 -From: Pavel Shirshov -Date: Wed, 28 Aug 2019 16:39:35 -0700 +From e6cd756eac31e3818afb32662469ddf7797c71df Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 3 Mar 2020 13:19:28 -0800 Subject: [PATCH] When read of timerfd returned 0, don't consider this an error Just skip this event. @@ -9,7 +9,7 @@ Just skip this event. 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/teamd/teamd.c b/teamd/teamd.c -index 96794e8..a5ce745 100644 +index 221d71d..530302b 100644 --- a/teamd/teamd.c +++ b/teamd/teamd.c @@ -285,6 +285,10 @@ static int handle_period_fd(int fd) @@ -35,5 +35,5 @@ index 96794e8..a5ce745 100644 } err = lcb->func(ctx, events, lcb->priv); -- -2.7.4 +2.17.1.windows.2 diff --git a/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch b/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch deleted file mode 100644 index 9203cd17c58b..000000000000 --- a/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch +++ /dev/null @@ -1,101 +0,0 @@ -From c0eb9e4bfe1c6a0e77f02b1459d91498c1a3dcff Mon Sep 17 00:00:00 2001 -From: Pavel Shirshov -Date: Tue, 4 Feb 2020 09:39:08 -0800 -Subject: [PATCH 1/1] teamd: fix possible race in master ifname callback - ---- - teamd/teamd.h | 2 ++ - teamd/teamd_link_watch.c | 13 ++++++++++--- - teamd/teamd_per_port.c | 24 +++++++++++++++++++----- - 3 files changed, 31 insertions(+), 8 deletions(-) - -diff --git a/teamd/teamd.h b/teamd/teamd.h -index 418214d..1ce120e 100644 ---- a/teamd/teamd.h -+++ b/teamd/teamd.h -@@ -334,6 +334,8 @@ int teamd_port_remove_all(struct teamd_context *ctx); - void teamd_port_obj_remove_all(struct teamd_context *ctx); - int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, - bool *enabled); -+int teamd_port_enabled_check(struct teamd_context *ctx, -+ struct teamd_port *tdport, bool *enabled); - int teamd_port_prio(struct teamd_context *ctx, struct teamd_port *tdport); - int teamd_port_check_enable(struct teamd_context *ctx, - struct teamd_port *tdport, -diff --git a/teamd/teamd_link_watch.c b/teamd/teamd_link_watch.c -index 62f8267..e4b3d3f 100644 ---- a/teamd/teamd_link_watch.c -+++ b/teamd/teamd_link_watch.c -@@ -423,9 +423,16 @@ static int link_watch_refresh_forced_send(struct teamd_context *ctx) - int err; - - teamd_for_each_tdport(tdport, ctx) { -- err = teamd_port_enabled(ctx, tdport, &port_enabled); -- if (err) -- return err; -+ err = teamd_port_enabled_check(ctx, tdport, &port_enabled); -+ if (err) { -+ /* Looks like the options are not ready for this port. -+ * This can happen when called from -+ * link_watch_port_master_ifindex_changed(). Skip this -+ * for now, let it be handled by future call of -+ * link_watch_enabled_option_changed(). -+ */ -+ continue; -+ } - __set_forced_send_for_port(tdport, port_enabled); - if (port_enabled) - enabled_port_count++; -diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c -index a87e809..d10cfb2 100644 ---- a/teamd/teamd_per_port.c -+++ b/teamd/teamd_per_port.c -@@ -395,19 +395,21 @@ int teamd_port_remove_ifname(struct teamd_context *ctx, const char *port_name) - return teamd_port_remove(ctx, tdport); - } - --int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, -- bool *enabled) -+int __teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, -+ bool *enabled, bool may_fail) - { - struct team_option *option; - - option = team_get_option(ctx->th, "np", "enabled", tdport->ifindex); - if (!option) { -- teamd_log_err("%s: Failed to find \"enabled\" option.", -- tdport->ifname); -+ if (!may_fail) -+ teamd_log_err("%s: Failed to find \"enabled\" option.", -+ tdport->ifname); - return -ENOENT; - } - if (team_get_option_type(option) != TEAM_OPTION_TYPE_BOOL) { -- teamd_log_err("Unexpected type of \"enabled\" option."); -+ if (!may_fail) -+ teamd_log_err("Unexpected type of \"enabled\" option."); - return -EINVAL; - } - -@@ -415,6 +417,18 @@ int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, - return 0; - } - -+int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, -+ bool *enabled) -+{ -+ return __teamd_port_enabled(ctx, tdport, enabled, false); -+} -+ -+int teamd_port_enabled_check(struct teamd_context *ctx, -+ struct teamd_port *tdport, bool *enabled) -+{ -+ return __teamd_port_enabled(ctx, tdport, enabled, true); -+} -+ - int teamd_port_prio(struct teamd_context *ctx, struct teamd_port *tdport) - { - int prio; --- -2.17.1.windows.2 - diff --git a/src/libteam/patch/series b/src/libteam/patch/series index 62c39e780f1a..7be69525d9d0 100644 --- a/src/libteam/patch/series +++ b/src/libteam/patch/series @@ -8,4 +8,3 @@ 0008-libteam-Add-warm_reboot-mode.patch 0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch 0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch -0011-teamd-fix-possible-race-in-master-ifname-callback.patch From 8f0ff4b7644ebf5bd7c3b34954ce5097a71a75e0 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Thu, 12 Mar 2020 04:44:18 +0800 Subject: [PATCH 0419/1427] [Mellanox] Calculate the buffer size based on the latest excel and with gearbox considered (#4239) --- .../ACS-MSN3800/buffers_defaults_t0.j2 | 105 +++++++++++++++++- .../ACS-MSN3800/buffers_defaults_t1.j2 | 105 +++++++++++++++++- .../ACS-MSN3800/pg_profile_lookup.ini | 24 +++- .../buffers_defaults_t0.j2 | 2 +- .../buffers_defaults_t1.j2 | 2 +- .../pg_profile_lookup.ini | 2 +- 6 files changed, 234 insertions(+), 6 deletions(-) mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 deleted file mode 120000 index 85f0b6b6b354..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 +++ /dev/null @@ -1 +0,0 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..d69a0cc13835 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '28196784' %} +{% set ingress_lossy_pool_size = '28196784' %} +{% set egress_lossless_pool_size = '34340832' %} +{% set egress_lossy_pool_size = '28196784' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 deleted file mode 120000 index 3bb496a5103b..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 +++ /dev/null @@ -1 +0,0 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..78d43455a424 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '17891280' %} +{% set ingress_lossy_pool_size = '17891280' %} +{% set egress_lossless_pool_size = '34340832' %} +{% set egress_lossy_pool_size = '17891280' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini deleted file mode 120000 index 252ae8d4149b..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini +++ /dev/null @@ -1 +0,0 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini new file mode 100644 index 000000000000..7c28e4c0d500 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini @@ -0,0 +1,23 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 1000 5m 32768 18432 14336 0 + 10000 5m 34816 18432 16384 0 + 25000 5m 38912 18432 20480 0 + 40000 5m 41984 18432 23552 0 + 50000 5m 44032 18432 25600 0 + 100000 5m 55296 18432 36864 0 + 200000 5m 77824 18432 59392 0 + 1000 40m 33792 18432 15360 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 43008 18432 24576 0 + 40000 40m 49152 18432 30720 0 + 50000 40m 53248 18432 34816 0 + 100000 40m 72704 18432 54272 0 + 200000 40m 112640 18432 94208 0 + 1000 300m 34816 18432 16384 0 + 10000 300m 50176 18432 31744 0 + 25000 300m 75776 18432 57344 0 + 40000 300m 101376 18432 82944 0 + 50000 300m 117760 18432 99328 0 + 100000 300m 202752 18432 184320 0 + 200000 300m 373760 18432 355328 0 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 index 85f0b6b6b354..0987f6724863 120000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 @@ -1 +1 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 \ No newline at end of file +../ACS-MSN3800/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 index 3bb496a5103b..119460bfa556 120000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 @@ -1 +1 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 \ No newline at end of file +../ACS-MSN3800/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini index 252ae8d4149b..db2f74508aad 120000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini @@ -1 +1 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini \ No newline at end of file +../ACS-MSN3800/pg_profile_lookup.ini \ No newline at end of file From 7d2ebf8116fe9d6b8207ebe4ece34b3ff948c1e2 Mon Sep 17 00:00:00 2001 From: Kalimuthu-Velappan <53821802+Kalimuthu-Velappan@users.noreply.github.com> Date: Thu, 12 Mar 2020 03:04:52 +0000 Subject: [PATCH 0420/1427] [build]: support for DPKG local caching (#4117) DPKG caching framework provides the infrastructure to cache the sonic module/target .deb files into a local cache by tracking the target dependency files.SONIC build infrastructure is designed as a plugin framework where any new source code can be easily integrated into sonic as a module and that generates output as a .deb file. The source code compilation of a module is completely independent of other modules compilation. Inter module dependency is resolved through build artifacts like header files, libraries, and binaries in the form of Debian packages. For example module A depends on module B. While module A is being built, it uses B's .deb file to install it in the build docker. The DPKG caching framework provides an infrastructure that caches a module's deb package and restores it back to the build directory if its dependency files are not modified. When a module is compiled for the first time, the generated deb package is stored at the DPKG cache location. On the subsequent build, first, it checks the module dependency file modification. If none of the dependent files is changed, it copies the deb package from the cache location, otherwise, it goes for local compilation and generates the deb package. The modified files should be checked-in to get the newer cache deb package. This provides a huge improvement in build time and also supports the true incremental build by tracking the dependency files. - How I did it It takes two global arguments to enable the DPKG caching, the first one indicates the caching method and the second one describes the location of the cache. SONIC_DPKG_CACHE_METHOD=cache SONIC_DPKG_CACHE_SOURCE= where SONIC_DPKG_CACHE_METHOD - Default method is 'cache' for deb package caching none: no caching cache: cache from local directory Dependency file tracking: Dependency files are tracked for each target in two levels. 1. Common make infrastructure files - rules/config, rules/functions, slave.mk etc. 2. Per module files - files which are specific to modules, Makefile, debian/rules, patch files, etc. For example: dependency files for Linux Kernel - src/sonic-linux-kernel, SPATH := $($(LINUX_HEADERS_COMMON)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/linux-kernel.mk rules/linux-kernel.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) \ $(KERNEL_PROCURE_METHOD) $(KERNEL_CACHE_PATH) $(LINUX_HEADERS_COMMON)_CACHE_MODE := GIT_CONTENT_SHA $(LINUX_HEADERS_COMMON)_DEP_FLAGS := $(DEP_FLAGS) $(LINUX_HEADERS_COMMON)_DEP_FILES := $(DEP_FILES) $(LINUX_HEADERS_COMMON)_SMDEP_FILES := $(SMDEP_FILES) $(LINUX_HEADERS_COMMON)_SMDEP_PATHS := $(SPATH) Cache file tracking: The Cache file is a compressed TAR ball of a module's target DEB file and its derived-target DEB files. The cache filename is formed with the following format FORMAT: .<24 byte of DEP SHA hash >-<24 byte of MOD SHA hash>.tgz Eg: linux-headers-4.9.0-9-2-common_4.9.168-1+deb9u3_all.deb-23658712fd21bb776fa16f47-c0b63ef593d4a32643bca228.tgz < 24-byte DEP SHA value > - the SHA value is derived from all the dependent packages. < 24-byte MOD SHA value > - the SHA value is derived from either of the following. GIT_COMMIT_SHA - SHA value of the last git commit ID if it is a submodule GIT_CONTENT_SHA - SHA value is generated from the content of the target dependency files. Target Specific rules: Caching can be enabled/disabled on a global level and also on the per-target level. $(addprefix $(DEBS_PATH)/, $(SONIC_DPKG_DEBS)) : $(DEBS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) \ $(call dpkg_depend,$(DEBS_PATH)/%.dep ) $(HEADER) # Load the target deb from DPKG cache $(call LOAD_CACHE,$*,$@) # Skip building the target if it is already loaded from cache if [ -z '$($*_CACHE_LOADED)' ] ; then ..... # Rules for Generating the target DEB file. ..... # Save the target deb into DPKG cache $(call SAVE_CACHE,$*,$@) fi $(FOOTER) The make rule-'$(call dpkg_depend,$(DEBS_PATH)/%.dep )' checks for target dependency file modification. If it is newer than the target, it will go for re-generation of that target. Two main macros 'LOAD_CACHE' and 'SAVE_CACHE' are used for loading and storing the cache contents. The 'LOAD_CACHE' macro is used to load the cache file from cache storage and extracts them into the target folder. It is done only if target dependency files are not modified by checking the GIT file status, otherwise, cache loading is skipped and full compilation is performed. It also updates the target-specific variable to indicate the cache is loaded or not. The 'SAVE_CACHE' macro generates the compressed tarball of the cache file and saves them into cache storage. Saving into the cache storage is protected with a lock. - How to verify it The caching functionality is verified by enabling it in Linux kernel submodule. It uses the cache directory as 'target/cache' where Linux cache file gets stored on the first-time build and it is picked from the cache location during the subsequent clean build. - Description for the changelog The DPKG caching framework provides the infrastructure to save the module-specific deb file to be cached by tracking the module's dependency files. If the module's dependency files are not changed, it restores the module deb files from the cache storage. - Description for the changelog - A picture of a cute animal (not mandatory but encouraged) DOCUMENT PR: https://github.com/Azure/SONiC/pull/559 --- Makefile.cache | 671 ++++++++++++++++++ Makefile.work | 9 + platform/broadcom/docker-ptf-brcm.dep | 10 + platform/broadcom/docker-saiserver-brcm.dep | 10 + platform/broadcom/docker-syncd-brcm-rpc.dep | 10 + platform/broadcom/docker-syncd-brcm.dep | 11 + platform/broadcom/libsaithrift-dev.dep | 13 + platform/broadcom/one-aboot.dep | 2 + platform/broadcom/one-image.dep | 2 + platform/broadcom/one-pde-image.dep | 2 + platform/broadcom/platform-modules-accton.dep | 10 + .../platform-modules-alphanetworks.dep | 10 + platform/broadcom/platform-modules-arista.dep | 13 + .../platform-modules-brcm-xlr-gts.dep | 10 + platform/broadcom/platform-modules-cel.dep | 10 + platform/broadcom/platform-modules-dell.dep | 10 + platform/broadcom/platform-modules-delta.dep | 10 + .../broadcom/platform-modules-ingrasys.dep | 10 + .../broadcom/platform-modules-inventec.dep | 10 + .../broadcom/platform-modules-juniper.dep | 10 + platform/broadcom/platform-modules-mitac.dep | 10 + platform/broadcom/platform-modules-quanta.dep | 10 + platform/broadcom/platform-modules-s6000.dep | 10 + platform/broadcom/raw-image.dep | 2 + platform/broadcom/rules.dep | 25 + platform/broadcom/sai-modules.dep | 10 + platform/broadcom/sai.dep | 14 + .../debian/files | 2 - .../debian/files | 2 - platform/vs/docker-sonic-vs.dep | 10 + platform/vs/docker-syncd-vs.dep | 11 + platform/vs/kvm-image.dep | 2 + platform/vs/one-image.dep | 2 + platform/vs/onie.dep | 2 + platform/vs/rules.dep | 8 + platform/vs/sonic-version.dep | 2 + platform/vs/syncd-vs.dep | 11 + rules/asyncsnmp-py3.dep | 12 + rules/bash.dep | 10 + rules/config | 12 + rules/dbsyncd-py2.dep | 12 + rules/dhcpmon.dep | 10 + rules/docker-base-stretch.dep | 10 + rules/docker-base.dep | 10 + rules/docker-config-engine-stretch.dep | 10 + rules/docker-config-engine.dep | 10 + rules/docker-database.dep | 11 + rules/docker-dhcp-relay.dep | 11 + rules/docker-fpm-frr.dep | 11 + rules/docker-fpm-gobgp.dep | 10 + rules/docker-fpm-quagga.dep | 10 + rules/docker-fpm.dep | 11 + rules/docker-lldp-sv2.dep | 11 + rules/docker-nat.dep | 11 + rules/docker-orchagent.dep | 11 + rules/docker-platform-monitor.dep | 11 + rules/docker-ptf.dep | 10 + rules/docker-router-advertiser.dep | 11 + rules/docker-sflow.dep | 15 + rules/docker-snmp-sv2.dep | 11 + rules/docker-sonic-mgmt-framework.dep | 11 + rules/docker-sonic-mgmt-spytest.dep | 11 + rules/docker-sonic-mgmt.dep | 10 + rules/docker-teamd.dep | 11 + rules/docker-telemetry.dep | 11 + rules/frr.dep | 10 + rules/functions | 25 + rules/gobgp.dep | 10 + rules/hiredis.dep | 10 + rules/ifupdown2.dep | 10 + rules/initramfs-tools.dep | 10 + rules/iproute2.dep | 10 + rules/iptables.dep | 10 + rules/isc-dhcp.dep | 10 + rules/ixgbe.dep | 10 + rules/kdump-tools.dep | 10 + rules/libnl3.dep | 10 + rules/libteam.dep | 10 + rules/libyang.dep | 10 + rules/linux-kernel.dep | 15 + rules/lldpd.dep | 10 + rules/lm-sensors.dep | 10 + rules/monit.dep | 10 + rules/mpdecimal.dep | 10 + rules/phy-credo.dep | 8 + rules/ptf.dep | 12 + rules/python-click.dep | 10 + rules/python3.dep | 10 + rules/quagga.dep | 13 + rules/radvd.dep | 10 + rules/redis-dump-load-py2.dep | 12 + rules/redis.dep | 10 + rules/restapi.dep | 12 + rules/sairedis.dep | 17 + rules/scripts.dep | 8 + rules/sflow.dep | 19 + rules/smartmontools.dep | 10 + rules/snmpd.dep | 10 + rules/socat.dep | 10 + rules/sonic-config.dep | 10 + rules/sonic-daemon-base.dep | 10 + rules/sonic-device-data.dep | 10 + rules/sonic-ledd.dep | 14 + rules/sonic-mgmt-framework.dep | 12 + rules/sonic-platform-common.dep | 21 + rules/sonic-psud.dep | 12 + rules/sonic-syseepromd.dep | 12 + rules/sonic-thermalctld.dep | 12 + rules/sonic-utilities.dep | 12 + rules/sonic-xcvrd.dep | 12 + rules/sonic-ztp.dep | 13 + rules/sonic-ztp.mk | 3 - rules/supervisor.dep | 10 + rules/swig.dep | 10 + rules/swss-common.dep | 12 + rules/swss.dep | 12 + rules/swsssdk-py2.dep | 12 + rules/swsssdk-py3.dep | 12 + rules/systemd-sonic-generator.dep | 10 + rules/tacacs.dep | 23 + rules/telemetry.dep | 13 + rules/template.dep | 49 ++ rules/thrift.dep | 10 + slave.mk | 346 +++++---- 124 files changed, 2207 insertions(+), 127 deletions(-) create mode 100644 Makefile.cache create mode 100644 platform/broadcom/docker-ptf-brcm.dep create mode 100644 platform/broadcom/docker-saiserver-brcm.dep create mode 100644 platform/broadcom/docker-syncd-brcm-rpc.dep create mode 100644 platform/broadcom/docker-syncd-brcm.dep create mode 100644 platform/broadcom/libsaithrift-dev.dep create mode 100644 platform/broadcom/one-aboot.dep create mode 100644 platform/broadcom/one-image.dep create mode 100644 platform/broadcom/one-pde-image.dep create mode 100644 platform/broadcom/platform-modules-accton.dep create mode 100644 platform/broadcom/platform-modules-alphanetworks.dep create mode 100644 platform/broadcom/platform-modules-arista.dep create mode 100644 platform/broadcom/platform-modules-brcm-xlr-gts.dep create mode 100644 platform/broadcom/platform-modules-cel.dep create mode 100644 platform/broadcom/platform-modules-dell.dep create mode 100644 platform/broadcom/platform-modules-delta.dep create mode 100644 platform/broadcom/platform-modules-ingrasys.dep create mode 100644 platform/broadcom/platform-modules-inventec.dep create mode 100644 platform/broadcom/platform-modules-juniper.dep create mode 100644 platform/broadcom/platform-modules-mitac.dep create mode 100644 platform/broadcom/platform-modules-quanta.dep create mode 100644 platform/broadcom/platform-modules-s6000.dep create mode 100644 platform/broadcom/raw-image.dep create mode 100644 platform/broadcom/rules.dep create mode 100644 platform/broadcom/sai-modules.dep create mode 100644 platform/broadcom/sai.dep delete mode 100644 platform/broadcom/sonic-platform-modules-brcm-xlr-gts/debian/files delete mode 100644 platform/broadcom/sonic-platform-modules-juniper/debian/files create mode 100644 platform/vs/docker-sonic-vs.dep create mode 100644 platform/vs/docker-syncd-vs.dep create mode 100644 platform/vs/kvm-image.dep create mode 100644 platform/vs/one-image.dep create mode 100644 platform/vs/onie.dep create mode 100644 platform/vs/rules.dep create mode 100644 platform/vs/sonic-version.dep create mode 100644 platform/vs/syncd-vs.dep create mode 100644 rules/asyncsnmp-py3.dep create mode 100644 rules/bash.dep create mode 100644 rules/dbsyncd-py2.dep create mode 100644 rules/dhcpmon.dep create mode 100644 rules/docker-base-stretch.dep create mode 100644 rules/docker-base.dep create mode 100644 rules/docker-config-engine-stretch.dep create mode 100644 rules/docker-config-engine.dep create mode 100644 rules/docker-database.dep create mode 100644 rules/docker-dhcp-relay.dep create mode 100644 rules/docker-fpm-frr.dep create mode 100644 rules/docker-fpm-gobgp.dep create mode 100644 rules/docker-fpm-quagga.dep create mode 100644 rules/docker-fpm.dep create mode 100644 rules/docker-lldp-sv2.dep create mode 100644 rules/docker-nat.dep create mode 100644 rules/docker-orchagent.dep create mode 100644 rules/docker-platform-monitor.dep create mode 100644 rules/docker-ptf.dep create mode 100644 rules/docker-router-advertiser.dep create mode 100644 rules/docker-sflow.dep create mode 100644 rules/docker-snmp-sv2.dep create mode 100644 rules/docker-sonic-mgmt-framework.dep create mode 100644 rules/docker-sonic-mgmt-spytest.dep create mode 100644 rules/docker-sonic-mgmt.dep create mode 100644 rules/docker-teamd.dep create mode 100644 rules/docker-telemetry.dep create mode 100644 rules/frr.dep create mode 100644 rules/gobgp.dep create mode 100644 rules/hiredis.dep create mode 100644 rules/ifupdown2.dep create mode 100644 rules/initramfs-tools.dep create mode 100644 rules/iproute2.dep create mode 100644 rules/iptables.dep create mode 100644 rules/isc-dhcp.dep create mode 100644 rules/ixgbe.dep create mode 100644 rules/kdump-tools.dep create mode 100644 rules/libnl3.dep create mode 100644 rules/libteam.dep create mode 100644 rules/libyang.dep create mode 100644 rules/linux-kernel.dep create mode 100644 rules/lldpd.dep create mode 100644 rules/lm-sensors.dep create mode 100644 rules/monit.dep create mode 100644 rules/mpdecimal.dep create mode 100644 rules/phy-credo.dep create mode 100644 rules/ptf.dep create mode 100644 rules/python-click.dep create mode 100644 rules/python3.dep create mode 100644 rules/quagga.dep create mode 100644 rules/radvd.dep create mode 100644 rules/redis-dump-load-py2.dep create mode 100644 rules/redis.dep create mode 100644 rules/restapi.dep create mode 100644 rules/sairedis.dep create mode 100644 rules/scripts.dep create mode 100644 rules/sflow.dep create mode 100644 rules/smartmontools.dep create mode 100644 rules/snmpd.dep create mode 100644 rules/socat.dep create mode 100644 rules/sonic-config.dep create mode 100644 rules/sonic-daemon-base.dep create mode 100644 rules/sonic-device-data.dep create mode 100644 rules/sonic-ledd.dep create mode 100644 rules/sonic-mgmt-framework.dep create mode 100644 rules/sonic-platform-common.dep create mode 100644 rules/sonic-psud.dep create mode 100644 rules/sonic-syseepromd.dep create mode 100644 rules/sonic-thermalctld.dep create mode 100644 rules/sonic-utilities.dep create mode 100644 rules/sonic-xcvrd.dep create mode 100644 rules/sonic-ztp.dep create mode 100644 rules/supervisor.dep create mode 100644 rules/swig.dep create mode 100644 rules/swss-common.dep create mode 100644 rules/swss.dep create mode 100644 rules/swsssdk-py2.dep create mode 100644 rules/swsssdk-py3.dep create mode 100644 rules/systemd-sonic-generator.dep create mode 100644 rules/tacacs.dep create mode 100644 rules/telemetry.dep create mode 100644 rules/template.dep create mode 100644 rules/thrift.dep diff --git a/Makefile.cache b/Makefile.cache new file mode 100644 index 000000000000..b1e5903a60b7 --- /dev/null +++ b/Makefile.cache @@ -0,0 +1,671 @@ +####################################################################### +# +# Copyright (c) 2020 Broadcom, Inc. +# The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. +# +# Author: Kalimuthu Velappan +# Greg Paussa +# +# Email : kalimuthu.velappan@broadcom.com +# greg.paussa@broadcom.com +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +####################################################################### +# +# +# DPKG caching framework +# +# SONiC source code composes of multiple open source modules. Eg: Linux, bash, ntp etc. +# Each module considered as a build target in the sonic build framework. +# Each module gets compiled and generate the final debian package(.deb) file. +# There are two types of source code packages used by the SONiC repo. +# +# 1. Module source code is maintained as part of main repo +# Eg: sonic-utilities, Plaform files etc +# +# Some module source code is maintained outside the sonic repo, but +# the build framework is part of sonic main repo. +# The build framework downloads the zipped source content from the web, +# applies a series of patches (if applicable) on the downloaded source code, +# compiles the source and generates the final .deb package(s). +# Eg: bash, ntp, etc +# +# 2. Module source code is maintained as a submodule(SM) in the sonic repo. +# Eg: Frr, swss, Linux etc +# +# +# The sonic build framework uses the module .deb packages that are generated as part of build and +# creates the set of target docker images and the final binary image for distribution. +# +# The caching framework provides the method to cache the module .deb packages and docker images +# into a cache location by tracking module dependency information. +# +# A module can have a set of dependency files, for example Makefiles, source files, scripts, dpkg control files, etc. +# The caching is done based on the SHA hash value of the module dependency file contents. If one of the +# dependency files is changed, the corresponding cache file is also changed. So it automatically creates the new cache file +# for that module. +# +# It provides two levels of caching. +# Global cache := Module doesnt have any local changes. +# Local cache := Used for target when one of its dependency file is modified. +# +# +# Steps for adding new module is given as a template. +# Template File : rules/template.dep +# + + +# Common files and FLAGS +# Run the 'touch cache.skip.common' command in the base directory to exclude the common files from caching +SONIC_COMMON_FILES_LIST := $(if $(wildcard cache.skip.common),, .platform slave.mk rules/functions Makefile.cache) +SONIC_COMMON_FLAGS_LIST := $(CONFIGURED_PLATFORM) \ + $(SONIC_DPKG_CACHE_SOURCE) $(SONIC_DEBUGGING_ON) \ + $(SONIC_PROFILING_ON) $(SONIC_SANITIZER_ON) +SONIC_COMMON_DPKG_LIST := debian/control debian/changelog debian/rules \ + debian/compat debian/install debian/copyright +SONIC_COMMON_BASE_FILES_LIST := sonic-slave-jessie/Dockerfile.j2 sonic-slave-jessie/Dockerfile.user \ + sonic-slave-stretch/Dockerfile.j2 sonic-slave-stretch/Dockerfile.user + + + +include $(RULES_PATH)/*.dep + + +ifneq ($(CONFIGURED_PLATFORM), undefined) +ifeq ($(PDDF_SUPPORT), y) +include $(PLATFORM_PDDF_PATH)/rules.dep +endif + +-include $(PLATFORM_PATH)/rules.dep +endif + +$(info "SONIC_DPKG_CACHE_METHOD" : "$(SONIC_DPKG_CACHE_METHOD)") +ifneq ($(SONIC_DPKG_CACHE_METHOD),none) +$(info "DPKG_CACHE_PATH" : "$(SONIC_DPKG_CACHE_SOURCE)") +endif +$(info ) + + +############################################################################### +## Canned sequences +############################################################################### + +SONIC_DPKG_CACHE_DIR := /dpkg_cache +MOD_CACHE_LOCK_SUFFIX := cache_access +MOD_CACHE_LOCK_TIMEOUT := 3600 +SONIC_DPKG_LOCAL_CACHE_DIR=${TARGET_PATH}/cache +$(shell test -d $(SONIC_DPKG_LOCAL_CACHE_DIR) || \ + mkdir -p $(SONIC_DPKG_LOCAL_CACHE_DIR) && chmod 777 $(SONIC_DPKG_LOCAL_CACHE_DIR) ) +$(shell test -w $(SONIC_DPKG_CACHE_DIR) || sudo chmod 777 $(SONIC_DPKG_CACHE_DIR) ) + +DOCKER_LOCKFILE_SUFFIX := access +DOCKER_LOCKFILE_TIMEOUT := 1200 + +# Lock macro for shared file access +# Lock is implemented through flock command with a specified timeout value +# Lock file is created in the specified directory, a separate one for each target file name +# A designated suffix is appended to each target file name, followed by .lock +# +# Parameters: +# $(1) - target file name (without path) +# $(2) - lock file path (only) +# $(3) - designated lock file suffix +# $(4) - flock timeout (in seconds) +# +# $(call MOD_LOCK,file,path,suffix,timeout) +define MOD_LOCK + if [[ ! -f $(2)/$(1)_$(3).lock ]]; then + touch $(2)/$(1)_$(3).lock + chmod 777 $(2)/$(1)_$(3).lock; + fi + $(eval $(1)_lock_fd=$(subst ~,_,$(subst -,_,$(subst +,_,$(subst .,_,$(1)))))) + exec {$($(1)_lock_fd)}<>"$(2)/$(1)_$(3).lock"; + if ! flock -x -w $(4) "$${$($(1)_lock_fd)}" ; then + echo "ERROR: Lock timeout trying to access $(2)/$(1)_$(3).lock"; + exit 1; + fi +endef + +# UnLock macro for shared file access +# +# Parameters: +# $(1) - target file name (without path) +# +# $(call MOD_UNLOCK,file) +define MOD_UNLOCK + eval exec "$${$($(1)_lock_fd)}<&-"; +endef + + +# Calculate the 24 byte SHA value +# GIT_COMMIT_SHA => SHA is derived from last git commit ID +# GIT_CONTENT_SHA => SHA is derived from contents of depdency files +# Args: +# $(1) => target name +define GET_MOD_SHA + $(eval $(1)_MOD_DEP_FILES := $($(1)_DEP_FLAGS_FILE) $($(1)_MOD_HASH_FILE) $($(1)_SMOD_HASH_FILE) ) + $(if $(MDEBUG), $(info $(1)_MOD_DEP_FILES: $($(1)_MOD_DEP_FILES))) + $(eval $(1)_MOD_HASH := $(if $(filter GIT_COMMIT_SHA,$($(1)_CACHE_MODE)),\ + $(shell cd $($(1)_MOD_SRC_PATH) && git log -1 --format="%H"| awk '{print substr($$1,0,23);}' ),\ + $(shell git hash-object $($(1)_MOD_DEP_FILES)| \ + sha1sum | awk '{print substr($$1,0,23);}'))) +endef + + +# Calculate the 24 byte SHA value +# SHA value is derived from dependent files of the target which includes .flags, .sha and .smsha files. +# Args: +# $(1) => target name +define GET_MOD_DEP_SHA + $(eval $(1)_MOD_DEP_PKGS := $(foreach dfile,$($(1)_DEPENDS) $($(1)_RDEPENDS) $($(1)_WHEEL_DEPENDS) \ + $($(1)_PYTHON_DEBS) $($(1)_PYTHON_WHEELS) \ + $($(1)_DBG_DEPENDS) $($(1)_DBG_IMAGE_PACKAGES) $($(1)_LOAD_DOCKERS),\ + $(if $($(dfile)_MAIN_DEB),$($(dfile)_MAIN_DEB),$(dfile))) ) + + $(if $(MDEBUG), $(info $(1)_MOD_DEP_PKGS: $($(1)_MOD_DEP_PKGS))) + $(eval $(1)_DEP_MOD_SHA := $(shell git hash-object \ + $(foreach dfile,$($(1)_MOD_DEP_PKGS), $($(dfile)_DEP_FLAGS_FILE) $($(dfile)_MOD_HASH_FILE) $($(dfile)_SMOD_HASH_FILE) ) \ + | sha1sum | awk '{print substr($$1,0,23);}')) +endef + + +# Retrive the list of files that are modified for the target. The files can be from +# 1. Any of dependent target is modified +# 2. Files from the target dependency list +# 3. Files from submodule dependency list if the target is a submodule +# +# Args: +# $(1) => target name +define GET_MODIFIED_FILES + $(eval $(1)_FILES_MODIFIED := $(foreach dfile,$($(1)_MOD_DEP_PKGS),$(if $($(dfile)_FILES_MODIFIED),$(dfile))) \ + $(if $($(1)_DEP_FILES), $(shell cat $($(1)_MOD_DEP_FILE) | xargs git status -s)) \ + $(if $($(1)_SMDEP_PATHS), $(foreach path,$($(1)_SMDEP_PATHS), \ + $(shell cd $(path) && git status --ignore-submodules=all -s -uno .))) ) + +endef + +# Loads the deb package from debian cache +# Cache file prefix is formed using SHA value +# The SHA value consists of +# 1. 24 byte SHA value is derived from the dependency files list +# Flags: Module ENV flags file +# Dependent packages : DEPENDS, RDEPENDS, WHEEL_DEPENDS, PYTHON_DEBS, PYTHON_WHEELS, DBG_DEPENDS, DBG_IMAGE_PACKAGES, LOAD_DOCKERS +# 2. 24 byte SHA value from one of the keyword type - GIT_COMMIT_SHA or GIT_CONTENT_SHA +# GIT_COMMIT_SHA - SHA value of the last git commit id if it is a submodule +# GIT_CONTENT_SHA - SHA value is calculated from the target dependency files content. +# Cache is loaded from either local cache or global cache based on the dependency SHA match with the cache filename. +# Otherwise it builds the package from source. +# TODO: +# 1. Extend dpkg for all the chip vendor packages. + +# Args: +# $(1) => target name +# $(2) => target output file name +define LOAD_FROM_CACHE + + # Calculate the modules SHA and its dependency SHA value + $(call GET_MOD_DEP_SHA,$(1)) + $(call GET_MOD_SHA,$(1)) + + # Form the cache file name + $(eval $(1)_MOD_CACHE_FILE := $(1)-$($(1)_DEP_MOD_SHA)-$($(1)_MOD_HASH).tgz) + $(if $(MDEBUG), $(info $(1)_MODE_CACHE_FILE := $($(1)_MOD_CACHE_FILE))) + + # Retrive and log files list that are modified for the target. + $(call GET_MODIFIED_FILES,$(1)) + $(if $($(1)_FILES_MODIFIED), + echo "Target $(1) dependencies are modifed - global cache skipped" >> $($(1)_DST_PATH)/$(1).log + echo "Modified dependencies are : [$($(1)_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log + $(eval $(1)_CACHE_DIR := $(SONIC_DPKG_LOCAL_CACHE_DIR))) + + # Choose the cache file path in the following order + # 1. First load from Local cache path + # 2. If not, load from global cache path + $(eval CACHE_FILE_SELECT:=$(or $(wildcard $(SONIC_DPKG_LOCAL_CACHE_DIR)/$($(1)_MOD_CACHE_FILE)), \ + $(wildcard $(SONIC_DPKG_CACHE_DIR)/$($(1)_MOD_CACHE_FILE))) ) + + # Check if any of the derived package is not built + $(eval LOAD_DRV_DEB := $(foreach pkg,$(addprefix $($(1)_DST_PATH)/,$(1) $($(1)_DERIVED_DEBS) $($(1)_EXTRA_DEBS)),$(if $(wildcard $(pkg)),,$(pkg)))) + + # Load the cache if cache is enabled and cache file is present in the cache + # Update the cache_loaded variable + $(if $(and $(CACHE_FILE_SELECT),$(filter $(RCACHE_OPTIONS),$(SONIC_DPKG_CACHE_METHOD))), + $(if $(LOAD_DRV_DEB), $($(1)_CACHE_USER) tar -C $($(1)_BASE_PATH) -mxzvf $(CACHE_FILE_SELECT) 1>> $($(1)_DST_PATH)/$(1).log ,echo ); + echo "File $(CACHE_FILE_SELECT) is loaded from cache" >> $($(1)_DST_PATH)/$(1).log + $(eval $(1)_CACHE_LOADED := Yes) + $(shell touch $(CACHE_FILE_SELECT)) + echo "[ CACHE::LOADED ] $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE)" >> $($(1)_DST_PATH)/$(1).log + , + echo "File $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE) is not present in cache or cache mode set as $(SONIC_DPKG_CACHE_METHOD) !" >> $($(1)_DST_PATH)/$(1).log + echo "[ CACHE::SKIPPED ] $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE)" >> $($(1)_DST_PATH)/$(1).log + echo "[ CACHE::SKIPPED ] DEP_FILES - Modified Files: [$($(1)_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log + echo "[ CACHE::SKIPPED ] DEPENDS - Modified Files: [$?] " >> $($(1)_DST_PATH)/$(1).log + ) +endef + +# Saves the deb package into debian cache +# A single tared-zip cache is created for .deb and its derived packages in the cache direcory. +# It saves the .deb into global cache only when its dependencies are not changed, +# Otherwise it saves the .deb into local cache +# The cache save is protected with lock. +# Args: +# $(1) => target name +# $(2) => target output file name +define SAVE_INTO_CACHE + + # Calculate the modules SHA and its dependency SHA value + $(call GET_MOD_DEP_SHA,$(1)) + $(call GET_MOD_SHA,$(1)) + + # Form the cache file name + $(eval $(1)_MOD_CACHE_FILE := $(1)-$($(1)_DEP_MOD_SHA)-$($(1)_MOD_HASH).tgz) + $(if $(MDEBUG), $(info $(1)_MOD_CACHE_FILE := $($(1)_MOD_CACHE_FILE))) + + # Retrive and log files list that are modified for the target. + $(call GET_MODIFIED_FILES,$(1)) + + $(eval MOD_CACHE_FILE=$($(1)_MOD_CACHE_FILE)) + $(call MOD_LOCK,$(1),$(SONIC_DPKG_CACHE_DIR),$(MOD_CACHE_LOCK_SUFFIX),$(MOD_CACHE_LOCK_TIMEOUT)) + $(if $($(1)_FILES_MODIFIED), + echo "Target $(1) dependencies are modifed - global save cache skipped" >> $($(1)_DST_PATH)/$(1).log + $(eval $(1)_CACHE_DIR := $(SONIC_DPKG_LOCAL_CACHE_DIR)) + ) + $($(1)_CACHE_USER) tar -C $($(1)_BASE_PATH) -mczvf $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE) $(2) $(addprefix $($(1)_DST_PATH)/,$($(1)_DERIVED_DEBS) $($(1)_EXTRA_DEBS) ) \ + 1>>$($(1)_DST_PATH)/$(1).log + sudo chmod 777 $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE) + + echo "File $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE) saved in cache " >> $($(1)_DST_PATH)/$(1).log + echo "[ CACHE::SAVED ] $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE)" >> $($(1)_DST_PATH)/$(1).log + + $(call MOD_UNLOCK,$(1)) +endef + +# Read from the cache +RCACHE_OPTIONS := cache rcache rwcache +define CHECK_RCACHE_ENABLED +$(if $(and $(filter $(RCACHE_OPTIONS),$(SONIC_DPKG_CACHE_METHOD)),$(filter-out none,$($(1)_CACHE_MODE))),enabled) +endef + +# Write into the cache +WCACHE_OPTIONS := cache wcache rwcache +define CHECK_WCACHE_ENABLED +$(if $(and $(filter $(WCACHE_OPTIONS),$(SONIC_DPKG_CACHE_METHOD)),$(filter-out none,$($(1)_CACHE_MODE))),enabled) +endef + +# It logs the reason why the target is getting built/rebuilt +# Args: +# $(1) => target name +define SHOW_WHY + @echo "[ REASON ] :\ + $(if $(filter $(PHONY),$@), it is phony,\ + $(eval $(1)_PREREQ_PHONY:= $(filter $(PHONY),$^))\ + $(eval $(1)_PREREQ_DNE:= $(filter-out $(wildcard $^) $($(1)_PREREQ_PHONY),$^))\ + $(eval $(1)_PREREQ_NEW:= $(filter-out $($(1)_PREREQ_DNE),$?))\ + $(if $(wildcard $@),$(if $($(1)_PREREQ_NEW), NEWER PREREQUISITES: $($(1)_PREREQ_NEW)), $@ does not exist)\ + $(if $($(1)_PREREQ_DNE), NON-EXISTENT PREREQUISITES: $($(1)_PREREQ_DNE))\ + $(if $($(1)_PREREQ_PHONY), PHONY PREREQUISITES: $($(1)_PREREQ_PHONY)))" >> $($(1)_DST_PATH)/$(1).log + + @echo "[ FLAGS FILE ] : [$($(1)_FILE_FLAGS)] " >> $($(1)_DST_PATH)/$(1).log + @echo "[ FLAGS DEPENDS ] : [$($(1)_DEP_FLAGS)] " >> $($(1)_DST_PATH)/$(1).log + @echo "[ FLAGS DIFF ] : [$($(1)_FLAGS_DIFF)] " >> $($(1)_DST_PATH)/$(1).log + @echo "[ DEP DEPENDS ] : [$($(1)_DEP_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log + @echo "[ SMDEP DEPENDS ] : [$($(1)_SMDEP_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log + @echo "[ TARGET DEPENDS ] : [$?] " >> $($(1)_DST_PATH)/$(1).log +endef + + + +# It invokes the Load Cache macro if cache is enabled globally as well as per module level +# Args: +# $(1) => target name +# $(2) => target output file name +define LOAD_CACHE + $(call SHOW_WHY,$(1)) + $(if $(call CHECK_RCACHE_ENABLED,$(1)), $(call LOAD_FROM_CACHE,$(1),$(2)) ) +endef + + +# It invokes the Save Cache if cache is enabled globally as well as per module level +# Args: +# $(1) => target name +# $(2) => target output file name +define SAVE_CACHE + $(if $(call CHECK_WCACHE_ENABLED,$(1)), $(call SAVE_INTO_CACHE,$(1),$(2))) +endef + + + +# Set the target path for each target. +$(foreach pkg, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONIC_COPY_DEBS), \ + $(eval $(pkg)_DST_PATH := $(if $($(pkg)_DST_PATH), $($(pkg)_DST_PATH), $(DEBS_PATH))) \ + $(eval $(DEBS_PATH)/$(pkg)_TARGET := $(pkg)) ) + +$(foreach pkg, $(SONIC_MAKE_FILES), \ + $(eval $(pkg)_DST_PATH := $(if $($(pkg)_DST_PATH), $($(pkg)_DST_PATH), $(FILES_PATH))) \ + $(eval $(FILES_PATH)/$(pkg)_TARGET := $(pkg)) ) + +$(foreach pkg, $(SONIC_PYTHON_STDEB_DEBS), \ + $(eval $(pkg)_DST_PATH := $(if $($(pkg)_DST_PATH), $($(pkg)_DST_PATH), $(PYTHON_DEBS_PATH))) \ + $(eval $(PYTHON_DEBS_PATH)/$(pkg)_TARGET := $(pkg)) ) + +$(foreach pkg, $(SONIC_PYTHON_WHEELS), \ + $(eval $(pkg)_DST_PATH := $(if $($(pkg)_DST_PATH), $($(pkg)_DST_PATH), $(PYTHON_WHEELS_PATH))) \ + $(eval $(PYTHON_WHEELS_PATH)/$(pkg)_TARGET := $(pkg)) ) + +$(foreach pkg, $(SONIC_DOCKER_IMAGES) $(SONIC_DOCKER_DBG_IMAGES), \ + $(eval $(pkg)_DST_PATH := $(if $($(pkg)_DST_PATH), $($(pkg)_DST_PATH), $(TARGET_PATH))) \ + $(eval $(TARGET_PATH)/$(pkg)_TARGET := $(pkg)) ) + +$(foreach pkg, $(SONIC_INSTALL_PKGS), \ + $(eval $(pkg)_DST_PATH := $(if $($(pkg)_DST_PATH), $($(pkg)_DST_PATH), $(FSROOT_PATH))) \ + $(eval $(FSROOT_PATH)/$(pkg)_TARGET := $(pkg)) ) + + +# define the DEP files(.dep and .smdep) and SHA files (.sha and smsha) for each target +$(foreach pkg, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONIC_COPY_DEBS) \ + $(SONIC_MAKE_FILES) $(SONIC_PYTHON_STDEB_DEBS) $(SONIC_PYTHON_WHEELS) \ + $(SONIC_DOCKER_IMAGES) $(SONIC_DOCKER_DBG_IMAGES) $(SONIC_INSTALL_PKGS), \ + $(eval $(pkg)_MOD_SRC_PATH:=$(if $($(pkg)_SRC_PATH),$($(pkg)_SRC_PATH),$($(pkg)_PATH))) \ + $(eval $(pkg)_BASE_PATH:=$(if $($(pkg)_BASE_PATH),$($(pkg)_BASE_PATH),$(CURDIR))) \ + $(eval $(pkg)_DEP_FLAGS_FILE:=$($(pkg)_DST_PATH)/$(pkg).flags) \ + $(eval $(pkg)_MOD_DEP_FILE:=$($(pkg)_DST_PATH)/$(pkg).dep) \ + $(eval $(pkg)_MOD_HASH_FILE:=$($(pkg)_DST_PATH)/$(pkg).dep.sha) \ + $(eval $(pkg)_SMOD_DEP_FILE:=$(if $($(pkg)_SMDEP_FILES),$($(pkg)_DST_PATH)/$(pkg).smdep)) \ + $(eval $(pkg)_SMOD_HASH_FILE:=$(if $($(pkg)_SMDEP_FILES),$($(pkg)_DST_PATH)/$(pkg).smdep.smsha)) \ + $(eval $(pkg)_DEP_FILES_LIST := $($(pkg)_DEP_FLAGS_FILE) $($(pkg)_DEP_FILES) $($(pkg)_SMDEP_FILES)) \ + $(eval $(pkg)_CACHE_DIR := $(SONIC_DPKG_CACHE_DIR)) \ + $(if $(filter-out none,$(SONIC_DPKG_CACHE_METHOD)), \ + $(if $(filter-out none,$($(pkg)_CACHE_MODE)), \ + $(if $($(pkg)_SMDEP_FILES), \ + $(if $($(pkg)_SMDEP_PATHS),,$(info Missing PATH/SRC_PATH attribute for $(pkg) package)) \ + ),\ + $(info [ DPKG ] Cache is not enabled for $(pkg) package)\ + )\ + ) \ + ) + + +# DPGK framework creates three dependency files for each target. +# 1. Flags file (.flags) +# 2. Dependency file (.dep), +# 3. Dependecy SHA hash file (.sha) +# 4. If the target is a submodule, corresponding dependency file and hash file are created +# sub module dependency file (.smdep) +# sub module hash file (.smsha) +# For example: following are the cache framework files for bash module +# target/debs/stretch/bash_4.3-14_amd64.deb => Final debian package +# target/debs/stretch/bash_4.3-14_amd64.deb.flags => Environment Flag file +# target/debs/stretch/bash_4.3-14_amd64.deb.dep => Dependency files list +# target/debs/stretch/bash_4.3-14_amd64.deb.dep.sha => SHA Hash file +# +# +# [1] .flags => contains value of all the environment variables of a target. +# Each target can have dependency with one or more environment variable. +# For example: +# SONIC_DEBUGGING_ON=y +# SONIC_PROFILING_ON=y +# SONIC_SANITIZER_ON=y +# etc +# If any of the ENV flag variables are modified, the target needs to be rebuilt as +# the content of flag file is changed becase of value of ENV variable is changed. +# +# [2] .dep => contains the dependency files list for a target. Eeach traget can have one or more dependency files. +# If any of the ENV flag variables are modified, the target needs to be rebuilt. +# For example: Dependency files list for 'bash' module +# rules/bash.mk +# rules/bash.dep +# src/bash/Makefile +# etc +# +# [3] .sha => contains the 48 byte SHA value for each dependency file present in the .dep file. +# For example: +# 9604676527653dcf7b6046fdda7ba52026b7f56f rules/bash.mk +# 191c345c1270776b3902c9ec91d5e777e0b5e2a3 rules/bash.dep +# 55692fe59303554b5958b04aa62c3651bc34bb6a src/bash/Makefile +# etc +# +# If module target is a sub module in the sonic repo, the following additional files gets created for that target. +# .smdep => contains the dependency files list +# .smsha => contains the SHA hash value for .smdep files list. + + + + + +# ruiles for <.flags> file creation +# +# Each target defines a variable called '_DEP_FLAGS' that contais a list of environment flags for that target and +# that indicates that target needs to be rebuilt if any of the dependent flags are changed. +# An environmental dependency flags file is created with the name as ‘.flags’ for each target. +# This file contains the values of target environment flags and gets updated only when there is a change in the flag's value. +# This file is added as a dependency to the target, so that any change in the file will trigger the target recompilation. +# For Eg: +# target/debs/stretch/linux-headers-4.9.0-9-2-common_4.9.168-1+deb9u3_all.deb.flags +# +# RULE args: +# $(1) => target name +# $(2) => target destination folder path +# $(3) => target file extension +# +# It updates the _DEP_FLAGS variable if there is any change in the module flags. + +define FLAGS_DEP_RULES +ALL_DEP_FILES_LIST += $(foreach pkg,$(2), $(if $(filter none,$($(1)_CACHE_MODE)),$(addsuffix .$(3),$(addprefix $(pkg)/, $(1))))) +$(addsuffix .$(3),$(addprefix $(2)/, $(1))) :: $(2)/%.$(3) : + @$$(eval $$*_FILE_FLAGS := $$(shell test -f $$@ && cat $$@)) + @echo '$$($$*_DEP_FLAGS)' | cmp -s - $$@ || echo '$$($$*_DEP_FLAGS)' > $$@ + $$(eval $$*_FLAGS_DIFF := $$(filter-out $$($$*_FILE_FLAGS),$$($$*_DEP_FLAGS)) $$(filter-out $$($$*_DEP_FLAGS),$$($$*_FILE_FLAGS))) + @$$(if $$(MDEBUG), $$(info FLAGS: $$@, DEP:$$?)) +endef +$(eval $(call FLAGS_DEP_RULES, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONIC_COPY_DEBS), $(DEBS_PATH),flags) ) +$(eval $(call FLAGS_DEP_RULES, $(SONIC_MAKE_FILES), $(FILES_PATH),flags)) +$(eval $(call FLAGS_DEP_RULES, $(SONIC_PYTHON_STDEB_DEBS), $(PYTHON_DEBS_PATH),flags)) +$(eval $(call FLAGS_DEP_RULES, $(SONIC_PYTHON_WHEELS), $(PYTHON_WHEELS_PATH),flags)) +$(eval $(call FLAGS_DEP_RULES, $(SONIC_DOCKER_IMAGES) $(SONIC_DOCKER_DBG_IMAGES), $(TARGET_PATH),flags)) +$(eval $(call FLAGS_DEP_RULES, $(SONIC_INSTALL_PKGS), $(FSROOT_PATH),flags)) + + + + +# rules for <.smdep> and <.smsha> file creation +# This rule creates two dependency files for a target if the target is a submodule +# [1] .smdep file +# Each module target defines a variable called '_SMDEP_FILES' that contains the list of sub module dependency files for the target. +# Contents of the '_SMDEP_FILES' variable is stored in this file +# +# [2] .smsha file +# The SHA hash (.smsha) file is created from 48 byte SHA value for each of the dependency files present in the .smdep file +# +# The target needs to be rebuilt if any of the dependent flags are changed. +# The submodule dependency file is created with the name as '.smdep' and the SHA hash file created as '.smdep.smsha'. +# This file is added as a dependency to the target, so that any change in the file will trigger the target recompilation. +# For Eg: +# target/debs/stretch/linux-headers-4.9.0-9-2-common_4.9.168-1+deb9u3_all.deb.smdep +# target/debs/stretch/linux-headers-4.9.0-9-2-common_4.9.168-1+deb9u3_all.deb.smdep.smsha +# +# RULE args: +# $(1) => target name +# $(2) => target destination folder path +# $(3) => target file extension + +define SMSHA_DEP_RULES +ALL_DEP_FILES_LIST += $(foreach pkg,$(2), $($(filter none,$($(1)_CACHE_MODE)), \ + $(addsuffix .$(3),$(addprefix $(pkg)/, $(1))) \ + $(addsuffix .$(3).smsha,$(addprefix $(pkg)/, $(1))))) +$(addsuffix .$(3),$(addprefix $(2)/, $(1))) : $(2)/%.$(3) : \ + $(2)/%.flags $$$$($$$$*_SMDEP_FILES) + @$$(eval $$*_SMDEP_FILES_MODIFIED := $$? ) + @$$(file >$$@,$$(patsubst $$($$*_MOD_SRC_PATH)/%,%,$$($$*_SMDEP_FILES))) + @( cd $$($$*_MOD_SRC_PATH) ; cat $$($$*_BASE_PATH)/$$@ |xargs git hash-object ) >$$@.smsha + @$$(if $$(MDEBUG), $$(info SMDEP:$$@, MOD:$$?)) +endef +$(eval $(call SMSHA_DEP_RULES, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONIC_COPY_DEBS), $(DEBS_PATH),smdep)) +$(eval $(call SMSHA_DEP_RULES, $(SONIC_MAKE_FILES), $(FILES_PATH),smdep)) +$(eval $(call SMSHA_DEP_RULES, $(SONIC_PYTHON_STDEB_DEBS), $(PYTHON_DEBS_PATH),smdep)) +$(eval $(call SMSHA_DEP_RULES, $(SONIC_PYTHON_WHEELS), $(PYTHON_WHEELS_PATH),smdep)) +$(eval $(call SMSHA_DEP_RULES, $(SONIC_DOCKER_IMAGES) $(SONIC_DOCKER_DBG_IMAGES), $(TARGET_PATH),smdep)) + + + + + +# rules for <.dep> and <.sha> file creation +# +# This rule creates two dependency files for the target +# [1] .dep file +# Each module target defines a variable called '_DEP_FILES' that contains the list of dependency files for the target. +# Contents of the '_DEP_FILES' variable is stored in this file +# +# [2] .sha file +# The SHA hash (.sha) file is created from 48 byte SHA value for each of the dependency files present in the .dep file +# +# The target needs to be rebuilt if any of the dependent flags are changed. +# The module dependency file is created with the name as '.dep' and the SHA hash file created as '.dep.sha'. +# This file is added as a dependency to the target, so that any change in the file will trigger the target recompilation. +# For Eg: +# target/debs/stretch/bash_4.3-14_amd64.deb.dep +# target/debs/stretch/bash_4.3-14_amd64.deb.dep.sha +# +# RULE args: +# $(1) => target name +# $(2) => target destination folder path +# $(3) => target file extension +# + +define SHA_DEP_RULES +ALL_DEP_FILES_LIST += $(foreach pkg,$(2), $($(filter none,$($(1)_CACHE_MODE)), \ + $(addsuffix .$(3),$(addprefix $(pkg)/, $(1))) \ + $(addsuffix .$(3).sha,$(addprefix $(pkg)/, $(1))))) +$(addsuffix .$(3),$(addprefix $(2)/, $(1))) : $(2)/%.$(3) : \ + $(2)/%.flags $$$$($$$$*_DEP_FILES) $$$$(if $$$$($$$$*_SMDEP_FILES), $(2)/%.smdep) + @$$(eval $$*_DEP_FILES_MODIFIED := $$? ) + @$$(file >$$@,$$($$*_DEP_FILES)) + @cat $$@ |xargs git hash-object >$$@.sha + @$$(if $$(MDEBUG), $$(info DEP: $$@, MOD:$$?)) +endef +$(eval $(call SHA_DEP_RULES, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONIC_COPY_DEBS), $(DEBS_PATH),dep)) +$(eval $(call SHA_DEP_RULES, $(SONIC_MAKE_FILES), $(FILES_PATH),dep)) +$(eval $(call SHA_DEP_RULES, $(SONIC_PYTHON_STDEB_DEBS), $(PYTHON_DEBS_PATH),dep)) +$(eval $(call SHA_DEP_RULES, $(SONIC_PYTHON_WHEELS), $(PYTHON_WHEELS_PATH),dep)) +$(eval $(call SHA_DEP_RULES, $(SONIC_DOCKER_IMAGES) $(SONIC_DOCKER_DBG_IMAGES), $(TARGET_PATH),dep)) +$(eval $(call SHA_DEP_RULES, $(SONIC_INSTALL_PKGS), $(FSROOT_PATH),dep)) + + + + + +# Clean all the DEP and SHA files for all the DEBS target +SONIC_CACHE_CLEAN_DEBS = $(addsuffix -clean,$(addprefix $(DEBS_PATH)/, \ + $(SONIC_ONLINE_DEBS) \ + $(SONIC_COPY_DEBS) \ + $(SONIC_MAKE_DEBS) \ + $(SONIC_DPKG_DEBS) \ + $(SONIC_DERIVED_DEBS) \ + $(SONIC_EXTRA_DEBS))) +$(SONIC_CACHE_CLEAN_DEBS) :: $(DEBS_PATH)/%-clean : .platform $$(addsuffix -clean,$$(addprefix $(DEBS_PATH)/,$$($$*_MAIN_DEB))) + @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ + $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) + + +# Clean all the DEP and SHA files for all the FILES target +SONIC_CACHE_CLEAN_FILES = $(addsuffix -clean,$(addprefix $(FILES_PATH)/, \ + $(SONIC_ONLINE_FILES) \ + $(SONIC_COPY_FILES) \ + $(SONIC_MAKE_FILES))) +$(SONIC_CACHE_CLEAN_FILES) :: $(FILES_PATH)/%-clean : .platform + @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ + $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) + + +# Clean all the DEP and SHA files for all the DOCKER target +SONIC_CACHE_CLEAN_TARGETS = $(addsuffix -clean,$(addprefix $(TARGET_PATH)/, \ + $(SONIC_DOCKER_IMAGES) \ + $(SONIC_DOCKER_DBG_IMAGES) \ + $(SONIC_SIMPLE_DOCKER_IMAGES) \ + $(SONIC_INSTALLERS))) +$(SONIC_CACHE_CLEAN_TARGETS) :: $(TARGET_PATH)/%-clean : .platform + @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ + $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) + + +# Clean all the DEP and SHA files for all the PYTHON DEBS target +SONIC_CACHE_CLEAN_STDEB_DEBS = $(addsuffix -clean,$(addprefix $(PYTHON_DEBS_PATH)/, \ + $(SONIC_PYTHON_STDEB_DEBS))) +$(SONIC_CACHE_CLEAN_STDEB_DEBS) :: $(PYTHON_DEBS_PATH)/%-clean : .platform + @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ + $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) + + +# Clean all the DEP and SHA files for all the PYTHON WHEELS target +SONIC_CACHE_CLEAN_WHEELS = $(addsuffix -clean,$(addprefix $(PYTHON_WHEELS_PATH)/, \ + $(SONIC_PYTHON_WHEELS))) +$(SONIC_CACHE_CLEAN_WHEELS) :: $(PYTHON_WHEELS_PATH)/%-clean : .platform + @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ + $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) + +.PHONY: cclean +cclean:: $(SONIC_CACHE_CLEAN_DEBS) $(SONIC_CACHE_CLEAN_FILES) $(SONIC_CACHE_CLEAN_TARGETS) \ + $(SONIC_CACHE_CLEAN_STDEB_DEBS) $(SONIC_CACHE_CLEAN_WHEELS) + +.PHONY: clean +clean:: cclean + +# Clear all the local cache contents +.PHONY:lcclean +lcclean:: + @rm -f $(TARGET_PATH)/cache/* + + + +# List all main targets and its derived target with indent. +listall : + @$(foreach target,$(SONIC_TARGET_LIST),\ + $(eval DPKG:=$(lastword $(subst /, ,$(target)))) \ + $(eval PATH:= $(subst $(DPKG),,$(target))) \ + $(if $($(DPKG)_MAIN_DEB),, + echo "[$(target)] "; \ + $(foreach pkg,$($(DPKG)_DERIVED_DEBS) $($(DPKG)_EXTRA_DEBS),\ + echo " $(PATH)$(pkg)"; \ + )\ + )\ + ) + +#$(addprefix show-,$(SONIC_TARGET_LIST)):show-%: +show-%: + @$(foreach target,$(SONIC_TARGET_LIST),\ + $(eval DPKG:=$(lastword $(subst /, ,$(target)))) \ + $(eval PATH:= $(subst $(DPKG),,$(target))) \ + $(if $(findstring $*,$(target)), + $(info ) \ + $(eval MDPKG:=$(if $($(DPKG)_MAIN_DEB),$($(DPKG)_MAIN_DEB),$(DPKG))) \ + $(info [$(PATH)$(MDPKG)] ) \ + $(foreach pkg,$($(MDPKG)_DERIVED_DEBS) $($(MDPKG)_EXTRA_DEBS),\ + $(info $(SPACE)$(SPACE)$(SPACE)$(SPACE) $(PATH)$(pkg)) \ + )\ + )\ + ) + $(info ) + + + +# Cache prune - Remove least frequently used cache files. +NUMDAYS ?= 7 # Delete all the cache files which are not used within last 7 days +.PHONY: cprune +cprune: + @find $(SONIC_DPKG_CACHE_DIR) -name "*.tgz" ! -mtime -$(NUMDAYS) -exec rm -f {} \; + + + +# Invoke DPKG dependency only if DPKG cache is enabled. +define dpkg_depend + $(if $(filter-out none,$(SONIC_DPKG_CACHE_METHOD)),$(1)) +endef diff --git a/Makefile.work b/Makefile.work index 4810afd97da6..4e58ab83a40d 100644 --- a/Makefile.work +++ b/Makefile.work @@ -31,6 +31,8 @@ # * Default: yes # * Values: yes, no # * KERNEL_PROCURE_METHOD: Specifying method of obtaining kernel Debian package: download or build +# * SONIC_DPKG_CACHE_METHOD: Specifying method of obtaining the Debian packages from cache: none or cache +# * SONIC_DPKG_CACHE_SOURCE: Debian package cache location when cache enabled for debian packages # ############################################################################### @@ -107,6 +109,10 @@ DOCKER_RUN := docker run --rm=true --privileged \ include rules/config +ifneq ($(SONIC_DPKG_CACHE_SOURCE),) + DOCKER_RUN += -v "$(SONIC_DPKG_CACHE_SOURCE):/dpkg_cache:rw" +endif + ifeq ($(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD), y) DOCKER_RUN += -v /var/run/docker.sock:/var/run/docker.sock endif @@ -172,12 +178,15 @@ SONIC_BUILD_INSTRUCTION := make \ SONIC_ENABLE_PFCWD_ON_START=$(ENABLE_PFCWD_ON_START) \ SONIC_ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \ SONIC_INSTALL_DEBUG_TOOLS=$(INSTALL_DEBUG_TOOLS) \ + MDEBUG=$(MDEBUG) \ PASSWORD=$(PASSWORD) \ USERNAME=$(USERNAME) \ SONIC_BUILD_JOBS=$(SONIC_BUILD_JOBS) \ SONIC_USE_DOCKER_BUILDKIT=$(SONIC_USE_DOCKER_BUILDKIT) \ VS_PREPARE_MEM=$(VS_PREPARE_MEM) \ KERNEL_PROCURE_METHOD=$(KERNEL_PROCURE_METHOD) \ + SONIC_DPKG_CACHE_METHOD=$(SONIC_DPKG_CACHE_METHOD) \ + SONIC_DPKG_CACHE_SOURCE=$(SONIC_DPKG_CACHE_SOURCE) \ HTTP_PROXY=$(http_proxy) \ HTTPS_PROXY=$(https_proxy) \ SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY) \ diff --git a/platform/broadcom/docker-ptf-brcm.dep b/platform/broadcom/docker-ptf-brcm.dep new file mode 100644 index 000000000000..b899d058d445 --- /dev/null +++ b/platform/broadcom/docker-ptf-brcm.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_PTF_BRCM)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/docker-ptf-brcm.mk platform/broadcom/docker-ptf-brcm.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_PTF_BRCM)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_PTF_BRCM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_PTF_BRCM)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/docker-saiserver-brcm.dep b/platform/broadcom/docker-saiserver-brcm.dep new file mode 100644 index 000000000000..7d18f0809d52 --- /dev/null +++ b/platform/broadcom/docker-saiserver-brcm.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_SAISERVER_BRCM)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/docker-saiserver-brcm.mk platform/broadcom/docker-saiserver-brcm.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_SAISERVER_BRCM)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SAISERVER_BRCM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SAISERVER_BRCM)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/docker-syncd-brcm-rpc.dep b/platform/broadcom/docker-syncd-brcm-rpc.dep new file mode 100644 index 000000000000..4427b0a957a6 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm-rpc.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_SYNCD_BRCM_RPC)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk $(PLATFORM_PATH)/docker-syncd-brcm-rpc.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_SYNCD_BRCM_RPC)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SYNCD_BRCM_RPC)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SYNCD_BRCM_RPC)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/docker-syncd-brcm.dep b/platform/broadcom/docker-syncd-brcm.dep new file mode 100644 index 000000000000..48fa57f33479 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm.dep @@ -0,0 +1,11 @@ +#DPKG FRK +DPATH := $($(DOCKER_SYNCD_BASE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/docker-syncd-brcm.mk platform/broadcom/docker-syncd-brcm.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_SYNCD_BASE)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SYNCD_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SYNCD_BASE)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_SYNCD_BASE),$(DOCKER_SYNCD_BASE_DBG))) diff --git a/platform/broadcom/libsaithrift-dev.dep b/platform/broadcom/libsaithrift-dev.dep new file mode 100644 index 000000000000..2ae0106247e4 --- /dev/null +++ b/platform/broadcom/libsaithrift-dev.dep @@ -0,0 +1,13 @@ +#DPKG FRK +SPATH := $($(LIBSAITHRIFT_DEV)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/libsaithrift-dev.mk platform/broadcom/libsaithrift-dev.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_PATHS := $(SPATH) $(SPATH)/bm/behavioral-model $(SPATH)/test/ptf $(SPATH)/test/saithrift/ctypesgen +$(foreach path, $(SMDEP_PATHS), $(eval $(path) :=$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/, $(shell cd $(path) && git ls-files | grep -Ev " " ))))) + +$(LIBSAITHRIFT_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBSAITHRIFT_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBSAITHRIFT_DEV)_DEP_FILES := $(DEP_FILES) +$(LIBSAITHRIFT_DEV)_SMDEP_FILES := $(foreach path, $(SMDEP_PATHS), $($(path))) +$(LIBSAITHRIFT_DEV)_SMDEP_PATHS := $(SMDEP_PATHS) + diff --git a/platform/broadcom/one-aboot.dep b/platform/broadcom/one-aboot.dep new file mode 100644 index 000000000000..a3b49cea460d --- /dev/null +++ b/platform/broadcom/one-aboot.dep @@ -0,0 +1,2 @@ +#DPKG FRK +$(SONIC_ONE_ABOOT_IMAGE)_CACHE_MODE := none diff --git a/platform/broadcom/one-image.dep b/platform/broadcom/one-image.dep new file mode 100644 index 000000000000..c5399d808172 --- /dev/null +++ b/platform/broadcom/one-image.dep @@ -0,0 +1,2 @@ +#DPKG FRK +$(SONIC_ONE_IMAGE)_CACHE_MODE := none diff --git a/platform/broadcom/one-pde-image.dep b/platform/broadcom/one-pde-image.dep new file mode 100644 index 000000000000..2abc8cad736f --- /dev/null +++ b/platform/broadcom/one-pde-image.dep @@ -0,0 +1,2 @@ +#DPKG FRK +$(SONIC_ONE_PDE_IMAGE)_CACHE_MODE := none diff --git a/platform/broadcom/platform-modules-accton.dep b/platform/broadcom/platform-modules-accton.dep new file mode 100644 index 000000000000..1ca57ec29e80 --- /dev/null +++ b/platform/broadcom/platform-modules-accton.dep @@ -0,0 +1,10 @@ + +MPATH := $($(ACCTON_AS7712_32X_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-accton.mk platform/broadcom/platform-modules-accton.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(ACCTON_AS7712_32X_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(ACCTON_AS7712_32X_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(ACCTON_AS7712_32X_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/platform-modules-alphanetworks.dep b/platform/broadcom/platform-modules-alphanetworks.dep new file mode 100644 index 000000000000..6538525303fd --- /dev/null +++ b/platform/broadcom/platform-modules-alphanetworks.dep @@ -0,0 +1,10 @@ + +MPATH := $($(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-alphanetworks.mk platform/broadcom/platform-modules-alphanetworks.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/platform-modules-arista.dep b/platform/broadcom/platform-modules-arista.dep new file mode 100644 index 000000000000..c42d529b7280 --- /dev/null +++ b/platform/broadcom/platform-modules-arista.dep @@ -0,0 +1,13 @@ + +MPATH := $($(ARISTA_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-arista.mk platform/broadcom/platform-modules-arista.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(MPATH)/,$(shell cd $(MPATH) && git ls-files)) + + +$(ARISTA_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(ARISTA_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(ARISTA_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) +$(ARISTA_PLATFORM_MODULE)_SMDEP_FILES := $(SMDEP_FILES) +$(ARISTA_PLATFORM_MODULE)_SMDEP_PATHS := $(MPATH) + diff --git a/platform/broadcom/platform-modules-brcm-xlr-gts.dep b/platform/broadcom/platform-modules-brcm-xlr-gts.dep new file mode 100644 index 000000000000..09e81d735481 --- /dev/null +++ b/platform/broadcom/platform-modules-brcm-xlr-gts.dep @@ -0,0 +1,10 @@ + +MPATH := $($(BRCM_XLR_GTS_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-brcm-xlr-gts.mk platform/broadcom/platform-modules-brcm-xlr-gts.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(BRCM_XLR_GTS_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(BRCM_XLR_GTS_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(BRCM_XLR_GTS_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/platform-modules-cel.dep b/platform/broadcom/platform-modules-cel.dep new file mode 100644 index 000000000000..f49d8ef8abbb --- /dev/null +++ b/platform/broadcom/platform-modules-cel.dep @@ -0,0 +1,10 @@ + +MPATH := $($(CEL_DX010_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-cel.mk platform/broadcom/platform-modules-cel.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(CEL_DX010_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(CEL_DX010_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(CEL_DX010_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/platform-modules-dell.dep b/platform/broadcom/platform-modules-dell.dep new file mode 100644 index 000000000000..32f5d39d0312 --- /dev/null +++ b/platform/broadcom/platform-modules-dell.dep @@ -0,0 +1,10 @@ + +MPATH := $($(DELL_Z9100_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-dell.mk platform/broadcom/platform-modules-dell.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(DELL_Z9100_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(DELL_Z9100_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DELL_Z9100_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/platform-modules-delta.dep b/platform/broadcom/platform-modules-delta.dep new file mode 100644 index 000000000000..d6d25aed0751 --- /dev/null +++ b/platform/broadcom/platform-modules-delta.dep @@ -0,0 +1,10 @@ + +MPATH := $($(DELTA_AG9032V1_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-delta.mk platform/broadcom/platform-modules-delta.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(DELTA_AG9032V1_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(DELTA_AG9032V1_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DELTA_AG9032V1_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/platform-modules-ingrasys.dep b/platform/broadcom/platform-modules-ingrasys.dep new file mode 100644 index 000000000000..5582caf09c86 --- /dev/null +++ b/platform/broadcom/platform-modules-ingrasys.dep @@ -0,0 +1,10 @@ + +MPATH := $($(INGRASYS_S9100_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-ingrasys.mk platform/broadcom/platform-modules-ingrasys.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(INGRASYS_S9100_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(INGRASYS_S9100_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(INGRASYS_S9100_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/platform-modules-inventec.dep b/platform/broadcom/platform-modules-inventec.dep new file mode 100644 index 000000000000..1f4003caa1b8 --- /dev/null +++ b/platform/broadcom/platform-modules-inventec.dep @@ -0,0 +1,10 @@ + +MPATH := $($(INVENTEC_D7032Q28B_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-inventec.mk platform/broadcom/platform-modules-inventec.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(INVENTEC_D7032Q28B_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(INVENTEC_D7032Q28B_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(INVENTEC_D7032Q28B_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/platform-modules-juniper.dep b/platform/broadcom/platform-modules-juniper.dep new file mode 100644 index 000000000000..0301480e31cf --- /dev/null +++ b/platform/broadcom/platform-modules-juniper.dep @@ -0,0 +1,10 @@ + +SPATH := $($(JUNIPER_QFX5210_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-juniper.mk platform/broadcom/platform-modules-juniper.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(JUNIPER_QFX5210_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(JUNIPER_QFX5210_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(JUNIPER_QFX5210_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/platform-modules-mitac.dep b/platform/broadcom/platform-modules-mitac.dep new file mode 100644 index 000000000000..cbeeec81ad56 --- /dev/null +++ b/platform/broadcom/platform-modules-mitac.dep @@ -0,0 +1,10 @@ + +MPATH := $($(MITAC_LY1200_32X_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-mitac.mk platform/broadcom/platform-modules-mitac.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(MITAC_LY1200_32X_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(MITAC_LY1200_32X_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MITAC_LY1200_32X_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/platform-modules-quanta.dep b/platform/broadcom/platform-modules-quanta.dep new file mode 100644 index 000000000000..f4167a66d758 --- /dev/null +++ b/platform/broadcom/platform-modules-quanta.dep @@ -0,0 +1,10 @@ + +MPATH := $($(QUANTA_IX1B_32X_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-quanta.mk platform/broadcom/platform-modules-quanta.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(QUANTA_IX1B_32X_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(QUANTA_IX1B_32X_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(QUANTA_IX1B_32X_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/platform-modules-s6000.dep b/platform/broadcom/platform-modules-s6000.dep new file mode 100644 index 000000000000..fff2d52dd753 --- /dev/null +++ b/platform/broadcom/platform-modules-s6000.dep @@ -0,0 +1,10 @@ + +MPATH := $($(DELL_S6000_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-s6000.mk platform/broadcom/platform-modules-s6000.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(DELL_S6000_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(DELL_S6000_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DELL_S6000_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/raw-image.dep b/platform/broadcom/raw-image.dep new file mode 100644 index 000000000000..500ba2a70fef --- /dev/null +++ b/platform/broadcom/raw-image.dep @@ -0,0 +1,2 @@ +#DPKG FRK +$(SONIC_RAW_IMAGE)_CACHE_MODE := none diff --git a/platform/broadcom/rules.dep b/platform/broadcom/rules.dep new file mode 100644 index 000000000000..d8142ae3fb76 --- /dev/null +++ b/platform/broadcom/rules.dep @@ -0,0 +1,25 @@ +#DPKG FRK +include $(PLATFORM_PATH)/sai-modules.dep +include $(PLATFORM_PATH)/sai.dep +include $(PLATFORM_PATH)/platform-modules-s6000.dep +include $(PLATFORM_PATH)/platform-modules-dell.dep +include $(PLATFORM_PATH)/platform-modules-arista.dep +include $(PLATFORM_PATH)/platform-modules-ingrasys.dep +include $(PLATFORM_PATH)/platform-modules-accton.dep +include $(PLATFORM_PATH)/platform-modules-alphanetworks.dep +include $(PLATFORM_PATH)/platform-modules-inventec.dep +include $(PLATFORM_PATH)/platform-modules-cel.dep +include $(PLATFORM_PATH)/platform-modules-delta.dep +include $(PLATFORM_PATH)/platform-modules-quanta.dep +#include $(PLATFORM_PATH)/platform-modules-mitac.dep +include $(PLATFORM_PATH)/platform-modules-juniper.dep +include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.dep +include $(PLATFORM_PATH)/docker-syncd-brcm.dep +include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.dep +include $(PLATFORM_PATH)/docker-saiserver-brcm.dep +include $(PLATFORM_PATH)/one-image.dep +include $(PLATFORM_PATH)/one-pde-image.dep +include $(PLATFORM_PATH)/raw-image.dep +include $(PLATFORM_PATH)/one-aboot.dep +include $(PLATFORM_PATH)/libsaithrift-dev.dep +include $(PLATFORM_PATH)/docker-ptf-brcm.dep diff --git a/platform/broadcom/sai-modules.dep b/platform/broadcom/sai-modules.dep new file mode 100644 index 000000000000..040a7d75d4c7 --- /dev/null +++ b/platform/broadcom/sai-modules.dep @@ -0,0 +1,10 @@ + +MPATH := $($(BRCM_OPENNSL_KERNEL)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/sai-modules.mk platform/broadcom/sai-modules.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(BRCM_OPENNSL_KERNEL)_CACHE_MODE := GIT_CONTENT_SHA +$(BRCM_OPENNSL_KERNEL)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(BRCM_OPENNSL_KERNEL)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/sai.dep b/platform/broadcom/sai.dep new file mode 100644 index 000000000000..11cc72b192fb --- /dev/null +++ b/platform/broadcom/sai.dep @@ -0,0 +1,14 @@ + +#DPKG FRK +SPATH := $($(BRCM_SAI)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/sai.mk platform/broadcom/sai.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) + +$(BRCM_SAI)_CACHE_MODE := GIT_CONTENT_SHA +$(BRCM_SAI)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(BRCM_SAI)_DEP_FILES := $(DEP_FILES) + +$(BRCM_SAI_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(BRCM_SAI_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(BRCM_SAI_DEV)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/debian/files b/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/debian/files deleted file mode 100644 index 5e9df1525c06..000000000000 --- a/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/debian/files +++ /dev/null @@ -1,2 +0,0 @@ -sonic-platform-brcm-xlr-gts_1.0_amd64.buildinfo main extra -sonic-platform-brcm-xlr-gts_1.0_amd64.deb main extra diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/files b/platform/broadcom/sonic-platform-modules-juniper/debian/files deleted file mode 100644 index 24ef0ffef22b..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/files +++ /dev/null @@ -1,2 +0,0 @@ -sonic-juniper-platform-modules_1.1_amd64.buildinfo main extra -sonic-platform-juniper-qfx5210_1.1_amd64.deb main extra diff --git a/platform/vs/docker-sonic-vs.dep b/platform/vs/docker-sonic-vs.dep new file mode 100644 index 000000000000..d544423171dc --- /dev/null +++ b/platform/vs/docker-sonic-vs.dep @@ -0,0 +1,10 @@ +#DPKG FRK +DPATH := $($(DOCKER_SONIC_VS)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/vs/docker-sonic-vs.mk platform/vs/docker-sonic-vs.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_SONIC_VS)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SONIC_VS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SONIC_VS)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/vs/docker-syncd-vs.dep b/platform/vs/docker-syncd-vs.dep new file mode 100644 index 000000000000..e0330f8fcc4f --- /dev/null +++ b/platform/vs/docker-syncd-vs.dep @@ -0,0 +1,11 @@ +#DPKG FRK +DPATH := $($(DOCKER_SYNCD_BASE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/vs/docker-syncd-vs.mk platform/vs/docker-syncd-vs.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_SYNCD_BASE)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SYNCD_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SYNCD_BASE)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_SYNCD_BASE),$(DOCKER_SYNCD_BASE_DBG))) diff --git a/platform/vs/kvm-image.dep b/platform/vs/kvm-image.dep new file mode 100644 index 000000000000..05c083a51597 --- /dev/null +++ b/platform/vs/kvm-image.dep @@ -0,0 +1,2 @@ +#DPKG FRK +$(SONIC_KVM_IMAGE)_CACHE_MODE := none diff --git a/platform/vs/one-image.dep b/platform/vs/one-image.dep new file mode 100644 index 000000000000..c5399d808172 --- /dev/null +++ b/platform/vs/one-image.dep @@ -0,0 +1,2 @@ +#DPKG FRK +$(SONIC_ONE_IMAGE)_CACHE_MODE := none diff --git a/platform/vs/onie.dep b/platform/vs/onie.dep new file mode 100644 index 000000000000..36de83ce8ea3 --- /dev/null +++ b/platform/vs/onie.dep @@ -0,0 +1,2 @@ +#DPKG FRK +$(ONIE_RECOVERY_IMAGE)_CACHE_MODE := none diff --git a/platform/vs/rules.dep b/platform/vs/rules.dep new file mode 100644 index 000000000000..7d36c819509e --- /dev/null +++ b/platform/vs/rules.dep @@ -0,0 +1,8 @@ +include $(PLATFORM_PATH)/syncd-vs.dep +include $(PLATFORM_PATH)/sonic-version.dep +include $(PLATFORM_PATH)/docker-sonic-vs.dep +include $(PLATFORM_PATH)/docker-syncd-vs.dep +include $(PLATFORM_PATH)/one-image.dep +include $(PLATFORM_PATH)/onie.dep +include $(PLATFORM_PATH)/kvm-image.dep + diff --git a/platform/vs/sonic-version.dep b/platform/vs/sonic-version.dep new file mode 100644 index 000000000000..1398415bdad5 --- /dev/null +++ b/platform/vs/sonic-version.dep @@ -0,0 +1,2 @@ +#DPKG FRK +$(SONIC_VERSION)_CACHE_MODE := none diff --git a/platform/vs/syncd-vs.dep b/platform/vs/syncd-vs.dep new file mode 100644 index 000000000000..3b0cf002c9cf --- /dev/null +++ b/platform/vs/syncd-vs.dep @@ -0,0 +1,11 @@ +#DPKG FRK +DPATH := $($(SYNCD_VS)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/vs/syncd-vs.mk platform/vs/syncd-vs.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(SYNCD_VS)_CACHE_MODE := GIT_CONTENT_SHA +$(SYNCD_VS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SYNCD_VS)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(SYNCD_VS),$(SYNCD_VS_DBG))) diff --git a/rules/asyncsnmp-py3.dep b/rules/asyncsnmp-py3.dep new file mode 100644 index 000000000000..42911cb94acc --- /dev/null +++ b/rules/asyncsnmp-py3.dep @@ -0,0 +1,12 @@ + +SPATH := $($(ASYNCSNMP_PY3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/asyncsnmp-py3.mk rules/asyncsnmp-py3.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(ASYNCSNMP_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(ASYNCSNMP_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(ASYNCSNMP_PY3)_DEP_FILES := $(DEP_FILES) +$(ASYNCSNMP_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(ASYNCSNMP_PY3)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/bash.dep b/rules/bash.dep new file mode 100644 index 000000000000..9f2758be6d40 --- /dev/null +++ b/rules/bash.dep @@ -0,0 +1,10 @@ + +SPATH := $($(BASH)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/bash.mk rules/bash.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(BASH)_CACHE_MODE := GIT_CONTENT_SHA +$(BASH)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(BASH)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/config b/rules/config index c168fa5a964e..e319ff7fd5a9 100644 --- a/rules/config +++ b/rules/config @@ -96,6 +96,18 @@ DEFAULT_KERNEL_PROCURE_METHOD = build FRR_USER_UID = 300 FRR_USER_GID = 300 +# DPKG cache allows the .deb files to be stored in the cache path. This allows the submodules +# package to be cached and restored back if its commit hash is not modified and its dependencies are not modified. +# SONIC_DPKG_CACHE_METHOD - Default method of deb package caching +# none : no caching +# rwcache : Use cache if exists else build the source and update the cache +# wcache : Dont use the cache and just build the source and update the cache +# rcache : Use cache if exists, but dont update the cache +# cache : Same as rwcache +# SONIC_DPKG_CACHE_SOURCE - Stores the cache location details +SONIC_DPKG_CACHE_METHOD ?= none +SONIC_DPKG_CACHE_SOURCE ?= /var/cache/sonic/artifacts + # Default VS build memory preparation DEFAULT_VS_PREPARE_MEM = yes diff --git a/rules/dbsyncd-py2.dep b/rules/dbsyncd-py2.dep new file mode 100644 index 000000000000..6ca1ab8dd786 --- /dev/null +++ b/rules/dbsyncd-py2.dep @@ -0,0 +1,12 @@ + +SPATH := $($(DBSYNCD_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/dbsyncd-py2.mk rules/dbsyncd-py2.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(DBSYNCD_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(DBSYNCD_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DBSYNCD_PY2)_DEP_FILES := $(DEP_FILES) +$(DBSYNCD_PY2)_SMDEP_FILES := $(SMDEP_FILES) +$(DBSYNCD_PY2)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/dhcpmon.dep b/rules/dhcpmon.dep new file mode 100644 index 000000000000..cd8a410a8e95 --- /dev/null +++ b/rules/dhcpmon.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SONIC_DHCPMON)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/dhcpmon.mk rules/dhcpmon.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_DHCPMON)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_DHCPMON)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_DHCPMON)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-base-stretch.dep b/rules/docker-base-stretch.dep new file mode 100644 index 000000000000..dbbdd6b786ef --- /dev/null +++ b/rules/docker-base-stretch.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_BASE_STRETCH)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-base-stretch.mk rules/docker-base-stretch.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_BASE_STRETCH)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_BASE_STRETCH)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_BASE_STRETCH)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-base.dep b/rules/docker-base.dep new file mode 100644 index 000000000000..8de00ced7745 --- /dev/null +++ b/rules/docker-base.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_BASE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-base.mk rules/docker-base.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_BASE)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_BASE)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-config-engine-stretch.dep b/rules/docker-config-engine-stretch.dep new file mode 100644 index 000000000000..2562558f9fc0 --- /dev/null +++ b/rules/docker-config-engine-stretch.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_CONFIG_ENGINE_STRETCH)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-config-engine-stretch.mk rules/docker-config-engine-stretch.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_CONFIG_ENGINE_STRETCH)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_CONFIG_ENGINE_STRETCH)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_CONFIG_ENGINE_STRETCH)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-config-engine.dep b/rules/docker-config-engine.dep new file mode 100644 index 000000000000..f9cbaa92f0bb --- /dev/null +++ b/rules/docker-config-engine.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_CONFIG_ENGINE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-config-engine.mk rules/docker-config-engine.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_CONFIG_ENGINE)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_CONFIG_ENGINE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_CONFIG_ENGINE)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-database.dep b/rules/docker-database.dep new file mode 100644 index 000000000000..85e807d8cacf --- /dev/null +++ b/rules/docker-database.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_DATABASE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-database.mk rules/docker-database.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_DATABASE)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_DATABASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_DATABASE)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_DATABASE),$(DOCKER_DATABASE_DBG))) diff --git a/rules/docker-dhcp-relay.dep b/rules/docker-dhcp-relay.dep new file mode 100644 index 000000000000..996e346da98a --- /dev/null +++ b/rules/docker-dhcp-relay.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_DHCP_RELAY)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-dhcp-relay.mk rules/docker-dhcp-relay.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_DHCP_RELAY)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_DHCP_RELAY)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_DHCP_RELAY)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_DHCP_RELAY),$(DOCKER_DHCP_RELAY_DBG))) diff --git a/rules/docker-fpm-frr.dep b/rules/docker-fpm-frr.dep new file mode 100644 index 000000000000..47deac0c32fd --- /dev/null +++ b/rules/docker-fpm-frr.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_FPM_FRR)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-fpm-frr.mk rules/docker-fpm-frr.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_FPM_FRR)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_FPM_FRR)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_FPM_FRR)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_FPM_FRR),$(DOCKER_FPM_FRR_DBG))) diff --git a/rules/docker-fpm-gobgp.dep b/rules/docker-fpm-gobgp.dep new file mode 100644 index 000000000000..4cbb49578754 --- /dev/null +++ b/rules/docker-fpm-gobgp.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_FPM_GOBGP)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-fpm-gobgp.mk rules/docker-fpm-gobgp.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_FPM_GOBGP)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_FPM_GOBGP)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_FPM_GOBGP)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-fpm-quagga.dep b/rules/docker-fpm-quagga.dep new file mode 100644 index 000000000000..987e22b596c6 --- /dev/null +++ b/rules/docker-fpm-quagga.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_FPM_QUAGGA)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-fpm-quagga.mk rules/docker-fpm-quagga.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_FPM_QUAGGA)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_FPM_QUAGGA)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_FPM_QUAGGA)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-fpm.dep b/rules/docker-fpm.dep new file mode 100644 index 000000000000..126cdbbd9a20 --- /dev/null +++ b/rules/docker-fpm.dep @@ -0,0 +1,11 @@ +#DPKG FRK + +DOCKER_FPM := $(filter $(DOCKER_FPM_QUAGGA) $(DOCKER_FPM_FRR) $(DOCKER_FPM_GOBGP), $(SONIC_INSTALL_DOCKER_IMAGES) ) +DPATH := $($(DOCKER_FPM)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-fpm.mk rules/docker-fpm.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_FPM)_DEP_FILES += $(DEP_FILES) + + diff --git a/rules/docker-lldp-sv2.dep b/rules/docker-lldp-sv2.dep new file mode 100644 index 000000000000..185d85032d49 --- /dev/null +++ b/rules/docker-lldp-sv2.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_LLDP_SV2)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-lldp-sv2.mk rules/docker-lldp-sv2.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_LLDP_SV2)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_LLDP_SV2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_LLDP_SV2)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_LLDP_SV2),$(DOCKER_LLDP_SV2_DBG))) diff --git a/rules/docker-nat.dep b/rules/docker-nat.dep new file mode 100644 index 000000000000..a8f28f2ea30b --- /dev/null +++ b/rules/docker-nat.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_NAT)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-nat.mk rules/docker-nat.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_NAT)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_NAT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_NAT)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_NAT),$(DOCKER_NAT_DBG))) diff --git a/rules/docker-orchagent.dep b/rules/docker-orchagent.dep new file mode 100644 index 000000000000..7aff4d0d9f23 --- /dev/null +++ b/rules/docker-orchagent.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_ORCHAGENT)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-orchagent.mk rules/docker-orchagent.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_ORCHAGENT)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_ORCHAGENT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_ORCHAGENT)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_ORCHAGENT),$(DOCKER_ORCHAGENT_DBG))) diff --git a/rules/docker-platform-monitor.dep b/rules/docker-platform-monitor.dep new file mode 100644 index 000000000000..7b56d33c5134 --- /dev/null +++ b/rules/docker-platform-monitor.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_PLATFORM_MONITOR)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-platform-monitor.mk rules/docker-platform-monitor.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_PLATFORM_MONITOR)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_PLATFORM_MONITOR)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_PLATFORM_MONITOR)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_PLATFORM_MONITOR),$(DOCKER_PLATFORM_MONITOR_DBG))) diff --git a/rules/docker-ptf.dep b/rules/docker-ptf.dep new file mode 100644 index 000000000000..d62019e9b386 --- /dev/null +++ b/rules/docker-ptf.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_PTF)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-ptf.mk rules/docker-ptf.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_PTF)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_PTF)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_PTF)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-router-advertiser.dep b/rules/docker-router-advertiser.dep new file mode 100644 index 000000000000..1450462975db --- /dev/null +++ b/rules/docker-router-advertiser.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_ROUTER_ADVERTISER)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-router-advertiser.mk rules/docker-router-advertiser.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_ROUTER_ADVERTISER)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_ROUTER_ADVERTISER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_ROUTER_ADVERTISER)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_ROUTER_ADVERTISER),$(DOCKER_ROUTER_ADVERTISER_DBG))) diff --git a/rules/docker-sflow.dep b/rules/docker-sflow.dep new file mode 100644 index 000000000000..8870549f41d1 --- /dev/null +++ b/rules/docker-sflow.dep @@ -0,0 +1,15 @@ + +DPATH := $($(DOCKER_SFLOW)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-sflow.mk rules/docker-sflow.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_SFLOW)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SFLOW)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SFLOW)_DEP_FILES := $(DEP_FILES) + + +#DPKG FRK +$(eval $(call add_dbg_docker,$(DOCKER_SFLOW),$(DOCKER_SFLOW_DBG))) + + diff --git a/rules/docker-snmp-sv2.dep b/rules/docker-snmp-sv2.dep new file mode 100644 index 000000000000..38d46e1fbb03 --- /dev/null +++ b/rules/docker-snmp-sv2.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_SNMP_SV2)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-snmp-sv2.mk rules/docker-snmp-sv2.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_SNMP_SV2)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SNMP_SV2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SNMP_SV2)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_SNMP_SV2),$(DOCKER_SNMP_SV2_DBG))) diff --git a/rules/docker-sonic-mgmt-framework.dep b/rules/docker-sonic-mgmt-framework.dep new file mode 100644 index 000000000000..05ec104e26ab --- /dev/null +++ b/rules/docker-sonic-mgmt-framework.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_MGMT_FRAMEWORK)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-sonic-mgmt-framework.mk rules/docker-sonic-mgmt-framework.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_MGMT_FRAMEWORK)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_MGMT_FRAMEWORK)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_MGMT_FRAMEWORK)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_MGMT_FRAMEWORK),$(DOCKER_MGMT_FRAMEWORK_DBG))) diff --git a/rules/docker-sonic-mgmt-spytest.dep b/rules/docker-sonic-mgmt-spytest.dep new file mode 100644 index 000000000000..26daffbd1afc --- /dev/null +++ b/rules/docker-sonic-mgmt-spytest.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_MGMT_SPYTEST)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-sonic-mgmt-spytest.mk rules/docker-sonic-mgmt-spytest.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_MGMT_SPYTEST)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_MGMT_SPYTEST)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_MGMT_SPYTEST)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_MGMT_SPYTEST),$(DOCKER_MGMT_FRAMEWORK_DBG))) diff --git a/rules/docker-sonic-mgmt.dep b/rules/docker-sonic-mgmt.dep new file mode 100644 index 000000000000..29e6d39475dc --- /dev/null +++ b/rules/docker-sonic-mgmt.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_SONIC_MGMT)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-sonic-mgmt.mk rules/docker-sonic-mgmt.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_SONIC_MGMT)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SONIC_MGMT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SONIC_MGMT)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-teamd.dep b/rules/docker-teamd.dep new file mode 100644 index 000000000000..b58d934241ef --- /dev/null +++ b/rules/docker-teamd.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_TEAMD)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-teamd.mk rules/docker-teamd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_TEAMD)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_TEAMD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_TEAMD)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_TEAMD),$(DOCKER_TEAMD_DBG))) diff --git a/rules/docker-telemetry.dep b/rules/docker-telemetry.dep new file mode 100644 index 000000000000..7748370845d6 --- /dev/null +++ b/rules/docker-telemetry.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_TELEMETRY)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-telemetry.mk rules/docker-telemetry.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_TELEMETRY)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_TELEMETRY)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_TELEMETRY)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_TELEMETRY),$(DOCKER_TELEMETRY_DBG))) diff --git a/rules/frr.dep b/rules/frr.dep new file mode 100644 index 000000000000..c6bd41aca58a --- /dev/null +++ b/rules/frr.dep @@ -0,0 +1,10 @@ + +SPATH := $($(FRR)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/frr.mk rules/frr.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(FRR)_CACHE_MODE := GIT_CONTENT_SHA +$(FRR)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(FRR)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/functions b/rules/functions index 93e2a346274e..5cdd35198820 100644 --- a/rules/functions +++ b/rules/functions @@ -91,8 +91,33 @@ $(1)_EXTRA_DEBS += $(2) SONIC_EXTRA_DEBS += $(2) endef + +# call: +# add_dbg_docker some_docker.gz, some-docker-dbg.gz +define add_dbg_docker +$(2)_PATH = $($(1)_PATH) +$(2)_DBG_DEPENDS += $($(1)_DBG_DEPENDS) +$(2)_DBG_IMAGE_PACKAGES += $($(1)_DBG_IMAGE_PACKAGES) +$(2)_PYTHON_WHEELS += $($(1)_PYTHON_WHEELS) +$(2)_LOAD_DOCKERS += $($(1)_LOAD_DOCKERS) +$(2)_CACHE_MODE += $($(1)_CACHE_MODE) +$(2)_DEP_FLAGS += $($(1)_DEP_FLAGS) +$(2)_DEP_FILES += $($(1)_DEP_FILES) +$(2)_SMDEP_FILES += $($(1)_SMDEP_FILES) +$(2)_SMDEP_PATHS += $($(1)_SMDEP_PATHS) +$(2)_DEPENDS += $($(1)_DEPENDS) +$(2)_RDEPENDS += $($(1)_RDEPENDS) +$(2)_MAIN_DOCKER = $(1) +$(1)_DBG_DOCKER += $(2) +SONIC_DBG_DOCKERS += $(2) +endef + + + ############################################################################### ## Utility functions ############################################################################### +# Recursive wildcard function +rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) expand = $(foreach d,$(1),$(call expand,$($(d)_$(2)),$(2))) $(1) diff --git a/rules/gobgp.dep b/rules/gobgp.dep new file mode 100644 index 000000000000..f7462c6b8dbc --- /dev/null +++ b/rules/gobgp.dep @@ -0,0 +1,10 @@ + +SPATH := $($(GOBGP)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/gobgp.mk rules/gobgp.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(GOBGP)_CACHE_MODE := GIT_CONTENT_SHA +$(GOBGP)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(GOBGP)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/hiredis.dep b/rules/hiredis.dep new file mode 100644 index 000000000000..93bea540289f --- /dev/null +++ b/rules/hiredis.dep @@ -0,0 +1,10 @@ + +SPATH := $($(LIBHIREDIS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/hiredis.mk rules/hiredis.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LIBHIREDIS)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBHIREDIS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBHIREDIS)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/ifupdown2.dep b/rules/ifupdown2.dep new file mode 100644 index 000000000000..ec9bd68ee9d4 --- /dev/null +++ b/rules/ifupdown2.dep @@ -0,0 +1,10 @@ + +SPATH := $($(IFUPDOWN2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/ifupdown2.mk rules/ifupdown2.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(IFUPDOWN2)_CACHE_MODE := GIT_CONTENT_SHA +$(IFUPDOWN2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(IFUPDOWN2)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/initramfs-tools.dep b/rules/initramfs-tools.dep new file mode 100644 index 000000000000..5176544fd8f3 --- /dev/null +++ b/rules/initramfs-tools.dep @@ -0,0 +1,10 @@ + +SPATH := $($(INITRAMFS_TOOLS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/initramfs-tools.mk rules/initramfs-tools.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(INITRAMFS_TOOLS)_CACHE_MODE := GIT_CONTENT_SHA +$(INITRAMFS_TOOLS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(INITRAMFS_TOOLS)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/iproute2.dep b/rules/iproute2.dep new file mode 100644 index 000000000000..9e445d9c209a --- /dev/null +++ b/rules/iproute2.dep @@ -0,0 +1,10 @@ + +SPATH := $($(IPROUTE2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/iproute2.mk rules/iproute2.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(IPROUTE2)_CACHE_MODE := GIT_CONTENT_SHA +$(IPROUTE2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(IPROUTE2)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/iptables.dep b/rules/iptables.dep new file mode 100644 index 000000000000..eb751214487d --- /dev/null +++ b/rules/iptables.dep @@ -0,0 +1,10 @@ + +SPATH := $($(IPTABLES)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/iptables.mk rules/iptables.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(IPTABLES)_CACHE_MODE := GIT_CONTENT_SHA +$(IPTABLES)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(IPTABLES)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/isc-dhcp.dep b/rules/isc-dhcp.dep new file mode 100644 index 000000000000..e98df450746e --- /dev/null +++ b/rules/isc-dhcp.dep @@ -0,0 +1,10 @@ + +SPATH := $($(ISC_DHCP_RELAY)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/isc-dhcp.mk rules/isc-dhcp.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(ISC_DHCP_RELAY)_CACHE_MODE := GIT_CONTENT_SHA +$(ISC_DHCP_RELAY)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(ISC_DHCP_RELAY)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/ixgbe.dep b/rules/ixgbe.dep new file mode 100644 index 000000000000..a8e1ef1f3145 --- /dev/null +++ b/rules/ixgbe.dep @@ -0,0 +1,10 @@ + +SPATH := $($(IXGBE_DRIVER)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/ixgbe.mk rules/ixgbe.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(IXGBE_DRIVER)_CACHE_MODE := GIT_CONTENT_SHA +$(IXGBE_DRIVER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(IXGBE_DRIVER)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/kdump-tools.dep b/rules/kdump-tools.dep new file mode 100644 index 000000000000..041f2e83a99b --- /dev/null +++ b/rules/kdump-tools.dep @@ -0,0 +1,10 @@ + +SPATH := $($(KDUMP_TOOLS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/kdump-tools.mk rules/kdump-tools.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(KDUMP_TOOLS)_CACHE_MODE := GIT_CONTENT_SHA +$(KDUMP_TOOLS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(KDUMP_TOOLS)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/libnl3.dep b/rules/libnl3.dep new file mode 100644 index 000000000000..a28b97a7df41 --- /dev/null +++ b/rules/libnl3.dep @@ -0,0 +1,10 @@ + +SPATH := $($(LIBNL3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/libnl3.mk rules/libnl3.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LIBNL3)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBNL3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBNL3)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/libteam.dep b/rules/libteam.dep new file mode 100644 index 000000000000..e30ffe609711 --- /dev/null +++ b/rules/libteam.dep @@ -0,0 +1,10 @@ + +SPATH := $($(LIBTEAM)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/libteam.mk rules/libteam.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LIBTEAM)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBTEAM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBTEAM)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/libyang.dep b/rules/libyang.dep new file mode 100644 index 000000000000..681f0c86a067 --- /dev/null +++ b/rules/libyang.dep @@ -0,0 +1,10 @@ + +SPATH := $($(LIBYANG)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/libyang.mk rules/libyang.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LIBYANG)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBYANG)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBYANG)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/linux-kernel.dep b/rules/linux-kernel.dep new file mode 100644 index 000000000000..6063ddded9d0 --- /dev/null +++ b/rules/linux-kernel.dep @@ -0,0 +1,15 @@ + +SPATH := $($(LINUX_HEADERS_COMMON)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/linux-kernel.mk rules/linux-kernel.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) \ + $(KERNEL_PROCURE_METHOD) $(KERNEL_CACHE_PATH) + +$(LINUX_HEADERS_COMMON)_CACHE_MODE := GIT_CONTENT_SHA +$(LINUX_HEADERS_COMMON)_DEP_FLAGS := $(DEP_FLAGS) +$(LINUX_HEADERS_COMMON)_DEP_FILES := $(DEP_FILES) +$(LINUX_HEADERS_COMMON)_SMDEP_FILES := $(SMDEP_FILES) +$(LINUX_HEADERS_COMMON)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/lldpd.dep b/rules/lldpd.dep new file mode 100644 index 000000000000..65c2d015ab9f --- /dev/null +++ b/rules/lldpd.dep @@ -0,0 +1,10 @@ + +SPATH := $($(LLDPD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/lldpd.mk rules/lldpd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LLDPD)_CACHE_MODE := GIT_CONTENT_SHA +$(LLDPD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LLDPD)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/lm-sensors.dep b/rules/lm-sensors.dep new file mode 100644 index 000000000000..cc8bb09368fe --- /dev/null +++ b/rules/lm-sensors.dep @@ -0,0 +1,10 @@ + +SPATH := $($(LM_SENSORS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/lm-sensors.mk rules/lm-sensors.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LM_SENSORS)_CACHE_MODE := GIT_CONTENT_SHA +$(LM_SENSORS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LM_SENSORS)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/monit.dep b/rules/monit.dep new file mode 100644 index 000000000000..01d04f228c5b --- /dev/null +++ b/rules/monit.dep @@ -0,0 +1,10 @@ + +SPATH := $($(MONIT)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/monit.mk rules/monit.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(MONIT)_CACHE_MODE := GIT_CONTENT_SHA +$(MONIT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MONIT)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/mpdecimal.dep b/rules/mpdecimal.dep new file mode 100644 index 000000000000..583b1b5a1c37 --- /dev/null +++ b/rules/mpdecimal.dep @@ -0,0 +1,10 @@ + +SPATH := $($(LIBMPDECIMAL)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/mpdecimal.mk rules/mpdecimal.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LIBMPDECIMAL)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBMPDECIMAL)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBMPDECIMAL)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/phy-credo.dep b/rules/phy-credo.dep new file mode 100644 index 000000000000..5c0c9fe88fd9 --- /dev/null +++ b/rules/phy-credo.dep @@ -0,0 +1,8 @@ + +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/phy-credo.mk rules/phy-credo.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) + +$(PHY_CREDO)_CACHE_MODE := GIT_CONTENT_SHA +$(PHY_CREDO)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PHY_CREDO)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/ptf.dep b/rules/ptf.dep new file mode 100644 index 000000000000..9df93e7624bd --- /dev/null +++ b/rules/ptf.dep @@ -0,0 +1,12 @@ + +SPATH := $($(PTF)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/ptf.mk rules/ptf.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(PTF)_CACHE_MODE := GIT_CONTENT_SHA +$(PTF)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PTF)_DEP_FILES := $(DEP_FILES) +$(PTF)_SMDEP_FILES := $(SMDEP_FILES) +$(PTF)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/python-click.dep b/rules/python-click.dep new file mode 100644 index 000000000000..93e75a71efb1 --- /dev/null +++ b/rules/python-click.dep @@ -0,0 +1,10 @@ + +SPATH := $($(PYTHON_CLICK)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/python-click.mk rules/python-click.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(PYTHON_CLICK)_CACHE_MODE := GIT_CONTENT_SHA +$(PYTHON_CLICK)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PYTHON_CLICK)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/python3.dep b/rules/python3.dep new file mode 100644 index 000000000000..98cc5eb3642c --- /dev/null +++ b/rules/python3.dep @@ -0,0 +1,10 @@ + +SPATH := $($(LIBPY3_MIN)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/python3.mk rules/python3.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LIBPY3_MIN)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBPY3_MIN)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBPY3_MIN)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/quagga.dep b/rules/quagga.dep new file mode 100644 index 000000000000..abaf234a4fee --- /dev/null +++ b/rules/quagga.dep @@ -0,0 +1,13 @@ + +SPATH := $($(QUAGGA)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/quagga.mk rules/quagga.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +#DPKG_FRK +$(QUAGGA)_CACHE_MODE := GIT_CONTENT_SHA +$(QUAGGA)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(QUAGGA)_DEP_FILES := $(DEP_FILES) +$(QUAGGA)_SMDEP_FILES := $(SMDEP_FILES) +$(QUAGGA)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/radvd.dep b/rules/radvd.dep new file mode 100644 index 000000000000..457a74becc77 --- /dev/null +++ b/rules/radvd.dep @@ -0,0 +1,10 @@ + +SPATH := $($(RADVD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/radvd.mk rules/radvd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(RADVD)_CACHE_MODE := GIT_CONTENT_SHA +$(RADVD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(RADVD)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/redis-dump-load-py2.dep b/rules/redis-dump-load-py2.dep new file mode 100644 index 000000000000..adc43905b7f3 --- /dev/null +++ b/rules/redis-dump-load-py2.dep @@ -0,0 +1,12 @@ + +SPATH := $($(REDIS_DUMP_LOAD_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/redis-dump-load-py2.mk rules/redis-dump-load-py2.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(REDIS_DUMP_LOAD_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(REDIS_DUMP_LOAD_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(REDIS_DUMP_LOAD_PY2)_DEP_FILES := $(DEP_FILES) +$(REDIS_DUMP_LOAD_PY2)_SMDEP_FILES := $(SMDEP_FILES) +$(REDIS_DUMP_LOAD_PY2)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/redis.dep b/rules/redis.dep new file mode 100644 index 000000000000..1e0562bdef47 --- /dev/null +++ b/rules/redis.dep @@ -0,0 +1,10 @@ + +SPATH := $($(REDIS_TOOLS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/redis.mk rules/redis.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(REDIS_TOOLS)_CACHE_MODE := GIT_CONTENT_SHA +$(REDIS_TOOLS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(REDIS_TOOLS)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/restapi.dep b/rules/restapi.dep new file mode 100644 index 000000000000..97b69c44678e --- /dev/null +++ b/rules/restapi.dep @@ -0,0 +1,12 @@ + +SPATH := $($(RESTAPI)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/restapi.mk rules/restapi.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(RESTAPI)_CACHE_MODE := GIT_CONTENT_SHA +$(RESTAPI)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(RESTAPI)_DEP_FILES := $(DEP_FILES) +$(RESTAPI)_SMDEP_FILES := $(SMDEP_FILES) +$(RESTAPI)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/sairedis.dep b/rules/sairedis.dep new file mode 100644 index 000000000000..f501a78932c5 --- /dev/null +++ b/rules/sairedis.dep @@ -0,0 +1,17 @@ + +#DPKG FRK +SPATH := $($(LIBSAIREDIS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sairedis.mk rules/sairedis.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) + +SMDEP_PATHS := $(SPATH) $(SPATH)/SAI $(SPATH)/SAI/bm/behavioral-model $(SPATH)/SAI/test/ptf $(SPATH)/SAI/test/saithrift/ctypesgen +$(foreach path, $(SMDEP_PATHS), $(eval $(path) :=$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/, \ + $(shell cd $(path) && git ls-files | grep -v " "))))) + + +$(LIBSAIREDIS)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBSAIREDIS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBSAIREDIS)_DEP_FILES := $(DEP_FILES) +$(LIBSAIREDIS)_SMDEP_FILES := $(foreach path, $(SMDEP_PATHS), $($(path))) +$(LIBSAIREDIS)_SMDEP_PATHS := $(SMDEP_PATHS) + diff --git a/rules/scripts.dep b/rules/scripts.dep new file mode 100644 index 000000000000..907ec1722b5b --- /dev/null +++ b/rules/scripts.dep @@ -0,0 +1,8 @@ +#DPKG FRK + +$(ARP_UPDATE_SCRIPT)_CACHE_MODE := none +$(CONFIGDB_LOAD_SCRIPT)_CACHE_MODE := none +$(BUFFERS_CONFIG_TEMPLATE)_CACHE_MODE := none +$(UPDATE_PROC_VARIABLES_SCRIPT)_CACHE_MODE := none +$(QOS_CONFIG_TEMPLATE)_CACHE_MODE := none +$(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)_CACHE_MODE := none diff --git a/rules/sflow.dep b/rules/sflow.dep new file mode 100644 index 000000000000..b426959f481f --- /dev/null +++ b/rules/sflow.dep @@ -0,0 +1,19 @@ + +SPATH := $($(HSFLOWD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sflow.mk rules/sflow.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(HSFLOWD)_CACHE_MODE := GIT_CONTENT_SHA +$(HSFLOWD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(HSFLOWD)_DEP_FILES := $(DEP_FILES) + + +$(SFLOWTOOL)_CACHE_MODE := GIT_CONTENT_SHA +$(SFLOWTOOL)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SFLOWTOOL)_DEP_FILES := $(DEP_FILES) + + +$(PSAMPLE)_CACHE_MODE := GIT_CONTENT_SHA +$(PSAMPLE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PSAMPLE)_DEP_FILES := $(DEP_FILES) diff --git a/rules/smartmontools.dep b/rules/smartmontools.dep new file mode 100644 index 000000000000..0ca63f5f1fac --- /dev/null +++ b/rules/smartmontools.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SMARTMONTOOLS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/smartmontools.mk rules/smartmontools.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SMARTMONTOOLS)_CACHE_MODE := GIT_CONTENT_SHA +$(SMARTMONTOOLS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SMARTMONTOOLS)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/snmpd.dep b/rules/snmpd.dep new file mode 100644 index 000000000000..dcab16809bcf --- /dev/null +++ b/rules/snmpd.dep @@ -0,0 +1,10 @@ + +SPATH := $($(LIBSNMP_BASE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/snmpd.mk rules/snmpd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LIBSNMP_BASE)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBSNMP_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBSNMP_BASE)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/socat.dep b/rules/socat.dep new file mode 100644 index 000000000000..18dcd87c0adf --- /dev/null +++ b/rules/socat.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SOCAT)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/socat.mk rules/socat.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SOCAT)_CACHE_MODE := GIT_CONTENT_SHA +$(SOCAT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SOCAT)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic-config.dep b/rules/sonic-config.dep new file mode 100644 index 000000000000..f4c74d075d51 --- /dev/null +++ b/rules/sonic-config.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SONIC_CONFIG_ENGINE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-config.mk rules/sonic-config.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_CONFIG_ENGINE)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_CONFIG_ENGINE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_CONFIG_ENGINE)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic-daemon-base.dep b/rules/sonic-daemon-base.dep new file mode 100644 index 000000000000..2c6e8a38c757 --- /dev/null +++ b/rules/sonic-daemon-base.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SONIC_DAEMON_BASE_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-daemon-base.mk rules/sonic-daemon-base.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_DAEMON_BASE_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_DAEMON_BASE_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_DAEMON_BASE_PY2)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic-device-data.dep b/rules/sonic-device-data.dep new file mode 100644 index 000000000000..c6105f939f67 --- /dev/null +++ b/rules/sonic-device-data.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SONIC_DEVICE_DATA)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-device-data.mk rules/sonic-device-data.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_DEVICE_DATA)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_DEVICE_DATA)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_DEVICE_DATA)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic-ledd.dep b/rules/sonic-ledd.dep new file mode 100644 index 000000000000..42e54897423a --- /dev/null +++ b/rules/sonic-ledd.dep @@ -0,0 +1,14 @@ + +SPATH := $($(SONIC_LEDD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-ledd.mk rules/sonic-ledd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_LEDD)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_LEDD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_LEDD)_DEP_FILES := $(DEP_FILES) +$(SONIC_LEDD)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_LEDD)_SMDEP_PATHS := $(SPATH) + + + diff --git a/rules/sonic-mgmt-framework.dep b/rules/sonic-mgmt-framework.dep new file mode 100644 index 000000000000..d7140821083f --- /dev/null +++ b/rules/sonic-mgmt-framework.dep @@ -0,0 +1,12 @@ + +SPATH := $($(SONIC_MGMT_FRAMEWORK)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-mgmt-framework.mk rules/sonic-mgmt-framework.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_MGMT_FRAMEWORK)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_MGMT_FRAMEWORK)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_MGMT_FRAMEWORK)_DEP_FILES := $(DEP_FILES) +$(SONIC_MGMT_FRAMEWORK)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_MGMT_FRAMEWORK)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/sonic-platform-common.dep b/rules/sonic-platform-common.dep new file mode 100644 index 000000000000..f93240135988 --- /dev/null +++ b/rules/sonic-platform-common.dep @@ -0,0 +1,21 @@ + +SPATH := $($(SONIC_PLATFORM_COMMON_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-platform-common.mk rules/sonic-platform-common.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files|grep -Ev "sonic_sfp|sonic_eeprom")) + +$(SONIC_PLATFORM_COMMON_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_PLATFORM_COMMON_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PLATFORM_COMMON_PY2)_DEP_FILES := $(DEP_FILES) +$(SONIC_PLATFORM_COMMON_PY2)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_PLATFORM_COMMON_PY2)_SMDEP_PATHS := $(SPATH) + + + +$(SONIC_PLATFORM_COMMON_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_PLATFORM_COMMON_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PLATFORM_COMMON_PY3)_DEP_FILES := $(DEP_FILES) +$(SONIC_PLATFORM_COMMON_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_PLATFORM_COMMON_PY3)_SMDEP_PATHS := $(SPATH) + + diff --git a/rules/sonic-psud.dep b/rules/sonic-psud.dep new file mode 100644 index 000000000000..1999811f2a0a --- /dev/null +++ b/rules/sonic-psud.dep @@ -0,0 +1,12 @@ + +SPATH := $($(SONIC_PSUD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-psud.mk rules/sonic-psud.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_PSUD)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_PSUD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PSUD)_DEP_FILES := $(DEP_FILES) +$(SONIC_PSUD)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_PSUD)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/sonic-syseepromd.dep b/rules/sonic-syseepromd.dep new file mode 100644 index 000000000000..a00131942031 --- /dev/null +++ b/rules/sonic-syseepromd.dep @@ -0,0 +1,12 @@ + +SPATH := $($(SONIC_SYSEEPROMD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-syseepromd.mk rules/sonic-syseepromd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_SYSEEPROMD)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_SYSEEPROMD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_SYSEEPROMD)_DEP_FILES := $(DEP_FILES) +$(SONIC_SYSEEPROMD)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_SYSEEPROMD)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/sonic-thermalctld.dep b/rules/sonic-thermalctld.dep new file mode 100644 index 000000000000..6faa53b378e6 --- /dev/null +++ b/rules/sonic-thermalctld.dep @@ -0,0 +1,12 @@ + +SPATH := $($(SONIC_THERMALCTLD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-thermalctld.mk rules/sonic-thermalctld.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_THERMALCTLD)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_THERMALCTLD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_THERMALCTLD)_DEP_FILES := $(DEP_FILES) +$(SONIC_THERMALCTLD)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_THERMALCTLD)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/sonic-utilities.dep b/rules/sonic-utilities.dep new file mode 100644 index 000000000000..9d5f64e0ac62 --- /dev/null +++ b/rules/sonic-utilities.dep @@ -0,0 +1,12 @@ + +SPATH := $($(SONIC_UTILS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-utilities.mk rules/sonic-utilities.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_UTILS)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_UTILS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_UTILS)_DEP_FILES := $(DEP_FILES) +$(SONIC_UTILS)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_UTILS)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/sonic-xcvrd.dep b/rules/sonic-xcvrd.dep new file mode 100644 index 000000000000..25c1e8c2aaa7 --- /dev/null +++ b/rules/sonic-xcvrd.dep @@ -0,0 +1,12 @@ + +SPATH := $($(SONIC_XCVRD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-xcvrd.mk rules/sonic-xcvrd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_XCVRD)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_XCVRD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_XCVRD)_DEP_FILES := $(DEP_FILES) +$(SONIC_XCVRD)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_XCVRD)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/sonic-ztp.dep b/rules/sonic-ztp.dep new file mode 100644 index 000000000000..32890c5d74b6 --- /dev/null +++ b/rules/sonic-ztp.dep @@ -0,0 +1,13 @@ + +SPATH := $($(SONIC_ZTP)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-ztp.mk rules/sonic-ztp.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files|grep -Ev "inband-ztp-ip|dhclient-exit-hooks.d/ztp")) + + +$(SONIC_ZTP)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_ZTP)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_ZTP)_DEP_FILES := $(DEP_FILES) +$(SONIC_ZTP)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_ZTP)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/sonic-ztp.mk b/rules/sonic-ztp.mk index 43615b7dcc8a..3f64febd48c0 100644 --- a/rules/sonic-ztp.mk +++ b/rules/sonic-ztp.mk @@ -1,8 +1,6 @@ # SONiC ztp package # -ifeq ($(ENABLE_ZTP), y) - SONIC_ZTP_VERSION = 1.0.0 SONIC_ZTP = sonic-ztp_$(SONIC_ZTP_VERSION)_all.deb @@ -13,5 +11,4 @@ SONIC_STRETCH_DEBS += $(SONIC_ZTP) export SONIC_ZTP_VERSION export SONIC_ZTP -endif diff --git a/rules/supervisor.dep b/rules/supervisor.dep new file mode 100644 index 000000000000..7d7bcf36e952 --- /dev/null +++ b/rules/supervisor.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SUPERVISOR)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/supervisor.mk rules/supervisor.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SUPERVISOR)_CACHE_MODE := GIT_CONTENT_SHA +$(SUPERVISOR)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SUPERVISOR)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/swig.dep b/rules/swig.dep new file mode 100644 index 000000000000..603dc5587a20 --- /dev/null +++ b/rules/swig.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SWIG_BASE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/swig.mk rules/swig.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SWIG_BASE)_CACHE_MODE := GIT_CONTENT_SHA +$(SWIG_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SWIG_BASE)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/swss-common.dep b/rules/swss-common.dep new file mode 100644 index 000000000000..b4e95a9917d6 --- /dev/null +++ b/rules/swss-common.dep @@ -0,0 +1,12 @@ + +SPATH := $($(LIBSWSSCOMMON)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/swss-common.mk rules/swss-common.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(LIBSWSSCOMMON)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBSWSSCOMMON)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBSWSSCOMMON)_DEP_FILES := $(DEP_FILES) +$(LIBSWSSCOMMON)_SMDEP_FILES := $(SMDEP_FILES) +$(LIBSWSSCOMMON)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/swss.dep b/rules/swss.dep new file mode 100644 index 000000000000..e57a9e7a6314 --- /dev/null +++ b/rules/swss.dep @@ -0,0 +1,12 @@ + +SPATH := $($(SWSS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/swss.mk rules/swss.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SWSS)_CACHE_MODE := GIT_CONTENT_SHA +$(SWSS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SWSS)_DEP_FILES := $(DEP_FILES) +$(SWSS)_SMDEP_FILES := $(SMDEP_FILES) +$(SWSS)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/swsssdk-py2.dep b/rules/swsssdk-py2.dep new file mode 100644 index 000000000000..2be9565fedcc --- /dev/null +++ b/rules/swsssdk-py2.dep @@ -0,0 +1,12 @@ + +SPATH := $($(SWSSSDK_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/swsssdk-py2.mk rules/swsssdk-py2.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SWSSSDK_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SWSSSDK_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SWSSSDK_PY2)_DEP_FILES := $(DEP_FILES) +$(SWSSSDK_PY2)_SMDEP_FILES := $(SMDEP_FILES) +$(SWSSSDK_PY2)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/swsssdk-py3.dep b/rules/swsssdk-py3.dep new file mode 100644 index 000000000000..4119d9f2fa1b --- /dev/null +++ b/rules/swsssdk-py3.dep @@ -0,0 +1,12 @@ + +SPATH := $($(SWSSSDK_PY3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/swsssdk-py3.mk rules/swsssdk-py3.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SWSSSDK_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SWSSSDK_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SWSSSDK_PY3)_DEP_FILES := $(DEP_FILES) +$(SWSSSDK_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(SWSSSDK_PY3)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/systemd-sonic-generator.dep b/rules/systemd-sonic-generator.dep new file mode 100644 index 000000000000..d6094c0cd51b --- /dev/null +++ b/rules/systemd-sonic-generator.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SYSTEMD_SONIC_GENERATOR)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/systemd-sonic-generator.mk rules/systemd-sonic-generator.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SYSTEMD_SONIC_GENERATOR)_CACHE_MODE := GIT_CONTENT_SHA +$(SYSTEMD_SONIC_GENERATOR)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SYSTEMD_SONIC_GENERATOR)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/tacacs.dep b/rules/tacacs.dep new file mode 100644 index 000000000000..29de9262f557 --- /dev/null +++ b/rules/tacacs.dep @@ -0,0 +1,23 @@ +#DPKG FRK + +SPATH := $($(LIBTAC2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/tacacs.mk rules/tacacs.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LIBTAC2)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBTAC2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBTAC2)_DEP_FILES := $(DEP_FILES) + + + + +SPATH := $($(LIBNSS_TACPLUS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/tacacs.mk rules/tacacs.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LIBNSS_TACPLUS)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBNSS_TACPLUS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBNSS_TACPLUS)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/telemetry.dep b/rules/telemetry.dep new file mode 100644 index 000000000000..d759b3acac21 --- /dev/null +++ b/rules/telemetry.dep @@ -0,0 +1,13 @@ +#DPKG FRK +SPATH := $($(SONIC_TELEMETRY)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/telemetry.mk rules/telemetry.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + + +$(SONIC_TELEMETRY)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_TELEMETRY)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_TELEMETRY)_DEP_FILES := $(DEP_FILES) +$(SONIC_TELEMETRY)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_TELEMETRY)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/template.dep b/rules/template.dep new file mode 100644 index 000000000000..d110c2e20ad0 --- /dev/null +++ b/rules/template.dep @@ -0,0 +1,49 @@ +#DPKG FRK + +# This provides a template for adding a DPKG cache rule for a new module +# +# __NEW_MODULE__ => Name of the module to be cached +# __NEW_RULES__ => Module rule name +# If a module is linked as a submodule, all the depencency files should be added in the _SMDEP_FILES rule +# All other dependency files should be added in the _DEP_FILES rule +# All the ENV flags should be added in the _DEP_FLAGS rule +# If module has multiple source path as a submodule, it should be added as prt of _SMDEP_PATHS rule + +#Source path of the module +SPATH := $($(__NEW_MODULE__)_SRC_PATH) + +# Add all the dependendency files in the DEP_FILES variable +# SONIC_COMMON_FILES_LIST => It includes common files like .platform, slave.mk, rules/functions etc +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/__NEW_RULES__.mk rules/__NEW_RULES__.dep + +# SONIC_COMMON_BASE_FILES_LIST => It includes base docker files like Dockerfile, Dockerfile.user etc +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) + +# If a module source files are part of sonic-buildimage, add the source files to DEP_FILES variable +#DEP_FILES += $(shell git ls-files $(SPATH)) + +# If the module is a submodule, add all the submodule source files into SMDEP_FILES variable +#SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + + + + +# Define the DPKG cache rule for a module +# Set the Cache mode, +# GIT_CONTENT_SHA => Cache SHA is derived from contents of the module dependency files +# GIT_COMMIT_SHA => Cache SHA is derived from the last commit id of a module +$(__NEW_MODULE__)_CACHE_MODE := GIT_CONTENT_SHA + +# List all the environment flags that module depends on +# SONIC_COMMON_FLAGS_LIST => It includes the defaults flags like SONIC_DEBUGGING_ON, SONIC_PROFILE_ON etc +$(__NEW_MODULE__)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) + +# List all the dependency files +$(__NEW_MODULE__)_DEP_FILES := $(DEP_FILES) + +# List all the sub module dependendency files +#$(__NEW_MODULE__)_SMDEP_FILES := $(SMDEP_FILES) + +# List all the sub module paths +#$(__NEW_MODULE__)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/thrift.dep b/rules/thrift.dep new file mode 100644 index 000000000000..a1700a922837 --- /dev/null +++ b/rules/thrift.dep @@ -0,0 +1,10 @@ + +SPATH := $($(LIBTHRIFT)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/thrift.mk rules/thrift.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LIBTHRIFT)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBTHRIFT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBTHRIFT)_DEP_FILES := $(DEP_FILES) + diff --git a/slave.mk b/slave.mk index 71e6aeb3a866..0bb571e5b70f 100644 --- a/slave.mk +++ b/slave.mk @@ -209,7 +209,8 @@ $(info "BLDENV" : "$(BLDENV)") $(info "VS_PREPARE_MEM" : "$(VS_PREPARE_MEM)") $(info "ENABLE_SFLOW" : "$(ENABLE_SFLOW)") $(info "ENABLE_NAT" : "$(ENABLE_NAT)") -$(info ) + +include Makefile.cache ifeq ($(SONIC_USE_DOCKER_BUILDKIT),y) $(warning "Using SONIC_USE_DOCKER_BUILDKIT will produce larger installable SONiC image because of a docker bug (more details: https://github.com/moby/moby/issues/38903)") @@ -264,10 +265,22 @@ SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_COPY_FILES)) # SOME_NEW_DEB = some_new_deb.deb # $(SOME_NEW_DEB)_URL = https://url/to/this/deb.deb # SONIC_ONLINE_DEBS += $(SOME_NEW_DEB) -$(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) : $(DEBS_PATH)/% : .platform +$(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) : $(DEBS_PATH)/% : .platform \ + $(call dpkg_depend,$(DEBS_PATH)/%.dep) + $(HEADER) - $(foreach deb,$* $($*_DERIVED_DEBS), \ - { curl -L -f -o $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || { exit 1 ; } } ; ) + # Load the target deb from DPKG cache + $(call LOAD_CACHE,$*,$@) + + # Skip building the target if it is already loaded from cache + if [ -z '$($*_CACHE_LOADED)' ] ; then + + $(foreach deb,$* $($*_DERIVED_DEBS), \ + { curl -L -f -o $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || { exit 1 ; } } ; ) + + # Save the target deb into DPKG cache + $(call SAVE_CACHE,$*,$@) + fi $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) @@ -297,16 +310,28 @@ SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_ONLINE_FILES)) # $(SOME_NEW_FILE)_SRC_PATH = $(SRC_PATH)/project_name # $(SOME_NEW_FILE)_DEPENDS = $(SOME_OTHER_DEB1) $(SOME_OTHER_DEB2) ... # SONIC_MAKE_FILES += $(SOME_NEW_FILE) -$(addprefix $(FILES_PATH)/, $(SONIC_MAKE_FILES)) : $(FILES_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) +$(addprefix $(FILES_PATH)/, $(SONIC_MAKE_FILES)) : $(FILES_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) \ + $(call dpkg_depend,$(FILES_PATH)/%.dep) $(HEADER) - # Remove target to force rebuild - rm -f $(addprefix $(FILES_PATH)/, $*) - # Apply series of patches if exist - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi - # Build project and take package - make DEST=$(shell pwd)/$(FILES_PATH) -C $($*_SRC_PATH) $(shell pwd)/$(FILES_PATH)/$* $(LOG) - # Clean up - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi + + # Load the target deb from DPKG cache + $(call LOAD_CACHE,$*,$@) + + # Skip building the target if it is already loaded from cache + if [ -z '$($*_CACHE_LOADED)' ] ; then + # Remove target to force rebuild + rm -f $(addprefix $(FILES_PATH)/, $*) + # Apply series of patches if exist + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi + # Build project and take package + make DEST=$(shell pwd)/$(FILES_PATH) -C $($*_SRC_PATH) $(shell pwd)/$(FILES_PATH)/$* $(LOG) + # Clean up + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi + + # Save the target deb into DPKG cache + $(call SAVE_CACHE,$*,$@) + + fi $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_MAKE_FILES)) @@ -323,16 +348,30 @@ SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_MAKE_FILES)) # $(SOME_NEW_DEB)_SRC_PATH = $(SRC_PATH)/project_name # $(SOME_NEW_DEB)_DEPENDS = $(SOME_OTHER_DEB1) $(SOME_OTHER_DEB2) ... # SONIC_MAKE_DEBS += $(SOME_NEW_DEB) -$(addprefix $(DEBS_PATH)/, $(SONIC_MAKE_DEBS)) : $(DEBS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) +$(addprefix $(DEBS_PATH)/, $(SONIC_MAKE_DEBS)) : $(DEBS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) \ + $(call dpkg_depend,$(DEBS_PATH)/%.dep) $(HEADER) - # Remove target to force rebuild - rm -f $(addprefix $(DEBS_PATH)/, $* $($*_DERIVED_DEBS) $($*_EXTRA_DEBS)) - # Apply series of patches if exist - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi - # Build project and take package - DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC}" make DEST=$(shell pwd)/$(DEBS_PATH) -C $($*_SRC_PATH) $(shell pwd)/$(DEBS_PATH)/$* $(LOG) - # Clean up - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi + + # Load the target deb from DPKG cache + $(call LOAD_CACHE,$*,$@) + + # Skip building the target if it is already loaded from cache + if [ -z '$($*_CACHE_LOADED)' ] ; then + + # Remove target to force rebuild + rm -f $(addprefix $(DEBS_PATH)/, $* $($*_DERIVED_DEBS) $($*_EXTRA_DEBS)) + # Apply series of patches if exist + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi + # Build project and take package + DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC}" make DEST=$(shell pwd)/$(DEBS_PATH) -C $($*_SRC_PATH) $(shell pwd)/$(DEBS_PATH)/$* $(LOG) + # Clean up + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi + + # Save the target deb into DPKG cache + $(call SAVE_CACHE,$*,$@) + + fi + $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_MAKE_DEBS)) @@ -343,24 +382,37 @@ SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_MAKE_DEBS)) # $(SOME_NEW_DEB)_SRC_PATH = $(SRC_PATH)/project_name # $(SOME_NEW_DEB)_DEPENDS = $(SOME_OTHER_DEB1) $(SOME_OTHER_DEB2) ... # SONIC_DPKG_DEBS += $(SOME_NEW_DEB) -$(addprefix $(DEBS_PATH)/, $(SONIC_DPKG_DEBS)) : $(DEBS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) +$(addprefix $(DEBS_PATH)/, $(SONIC_DPKG_DEBS)) : $(DEBS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) \ + $(call dpkg_depend,$(DEBS_PATH)/%.dep ) $(HEADER) - # Remove old build logs if they exist - rm -f $($*_SRC_PATH)/debian/*.debhelper.log - # Apply series of patches if exist - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi - # Build project - pushd $($*_SRC_PATH) $(LOG) - [ ! -f ./autogen.sh ] || ./autogen.sh $(LOG) - $(if $($*_DPKG_TARGET), - DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC} ${$*_DEB_BUILD_OPTIONS}" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --as-root -T$($*_DPKG_TARGET) $(LOG), - DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC} ${$*_DEB_BUILD_OPTIONS}" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) $(LOG) - ) - popd $(LOG) - # Clean up - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi - # Take built package(s) - mv $(addprefix $($*_SRC_PATH)/../, $* $($*_DERIVED_DEBS) $($*_EXTRA_DEBS)) $(DEBS_PATH) $(LOG) + + # Load the target deb from DPKG cache + $(call LOAD_CACHE,$*,$@) + + # Skip building the target if it is already loaded from cache + if [ -z '$($*_CACHE_LOADED)' ] ; then + + # Remove old build logs if they exist + rm -f $($*_SRC_PATH)/debian/*.debhelper.log + # Apply series of patches if exist + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi + # Build project + pushd $($*_SRC_PATH) $(LOG) + [ ! -f ./autogen.sh ] || ./autogen.sh $(LOG) + $(if $($*_DPKG_TARGET), + DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC} ${$*_DEB_BUILD_OPTIONS}" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --as-root -T$($*_DPKG_TARGET) $(LOG), + DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC} ${$*_DEB_BUILD_OPTIONS}" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) $(LOG) + ) + popd $(LOG) + # Clean up + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi + # Take built package(s) + mv $(addprefix $($*_SRC_PATH)/../, $* $($*_DERIVED_DEBS) $($*_EXTRA_DEBS)) $(DEBS_PATH) $(LOG) + + # Save the target deb into DPKG cache + $(call SAVE_CACHE,$*,$@) + fi + $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_DPKG_DEBS)) @@ -427,19 +479,33 @@ $(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -inst # SONIC_PYTHON_STDEB_DEBS += $(SOME_NEW_DEB) $(addprefix $(PYTHON_DEBS_PATH)/, $(SONIC_PYTHON_STDEB_DEBS)) : $(PYTHON_DEBS_PATH)/% : .platform \ $$(addsuffix -install,$$(addprefix $(PYTHON_DEBS_PATH)/,$$($$*_DEPENDS))) \ - $$(addsuffix -install,$$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*_WHEEL_DEPENDS))) + $$(addsuffix -install,$$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*_WHEEL_DEPENDS))) \ + $(call dpkg_depend,$(PYTHON_DEBS_PATH)/%.dep) + $(HEADER) - # Apply series of patches if exist - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi - # Build project - pushd $($*_SRC_PATH) $(LOG) - rm -rf deb_dist/* $(LOG) - python setup.py --command-packages=stdeb.command bdist_deb $(LOG) - popd $(LOG) - # Clean up - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi - # Take built package(s) - mv $(addprefix $($*_SRC_PATH)/deb_dist/, $* $($*_DERIVED_DEBS)) $(PYTHON_DEBS_PATH) $(LOG) + + # Load the target deb from DPKG cache + $(call LOAD_CACHE,$*,$@) + + # Skip building the target if it is already loaded from cache + if [ -z '$($*_CACHE_LOADED)' ] ; then + + # Apply series of patches if exist + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi + # Build project + pushd $($*_SRC_PATH) $(LOG) + rm -rf deb_dist/* $(LOG) + python setup.py --command-packages=stdeb.command bdist_deb $(LOG) + popd $(LOG) + # Clean up + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi + # Take built package(s) + mv $(addprefix $($*_SRC_PATH)/deb_dist/, $* $($*_DERIVED_DEBS)) $(PYTHON_DEBS_PATH) $(LOG) + + # Save the target deb into DPKG cache + $(call SAVE_CACHE,$*,$@) + fi + $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(PYTHON_DEBS_PATH)/, $(SONIC_PYTHON_STDEB_DEBS)) @@ -452,17 +518,31 @@ SONIC_TARGET_LIST += $(addprefix $(PYTHON_DEBS_PATH)/, $(SONIC_PYTHON_STDEB_DEBS # $(SOME_NEW_WHL)_PYTHON_VERSION = 2 (or 3) # $(SOME_NEW_WHL)_DEPENDS = $(SOME_OTHER_WHL1) $(SOME_OTHER_WHL2) ... # SONIC_PYTHON_WHEELS += $(SOME_NEW_WHL) -$(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) : $(PYTHON_WHEELS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*_DEPENDS))) +$(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) : $(PYTHON_WHEELS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*_DEPENDS))) \ + $(call dpkg_depend,$(PYTHON_WHEELS_PATH)/%.dep) + $(HEADER) - pushd $($*_SRC_PATH) $(LOG) - # apply series of patches if exist - if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; fi - [ "$($*_TEST)" = "n" ] || python$($*_PYTHON_VERSION) setup.py test $(LOG) - python$($*_PYTHON_VERSION) setup.py bdist_wheel $(LOG) - # clean up - if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then quilt pop -a -f; fi - popd $(LOG) - mv $($*_SRC_PATH)/dist/$* $(PYTHON_WHEELS_PATH) $(LOG) + + # Load the target deb from DPKG cache + $(call LOAD_CACHE,$*,$@) + + # Skip building the target if it is already loaded from cache + if [ -z '$($*_CACHE_LOADED)' ] ; then + + pushd $($*_SRC_PATH) $(LOG) + # apply series of patches if exist + if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; fi + [ "$($*_TEST)" = "n" ] || python$($*_PYTHON_VERSION) setup.py test $(LOG) + python$($*_PYTHON_VERSION) setup.py bdist_wheel $(LOG) + # clean up + if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then quilt pop -a -f; fi + popd $(LOG) + mv $($*_SRC_PATH)/dist/$* $(PYTHON_WHEELS_PATH) $(LOG) + + # Save the target deb into DPKG cache + $(call SAVE_CACHE,$*,$@) + fi + $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) @@ -533,39 +613,52 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform $$(addprefix $(PYTHON_DEBS_PATH)/,$$($$*.gz_PYTHON_DEBS)) \ $$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*.gz_PYTHON_WHEELS)) \ $$(addsuffix -load,$$(addprefix $(TARGET_PATH)/,$$($$*.gz_LOAD_DOCKERS))) \ - $$($$*.gz_PATH)/Dockerfile.j2 + $$($$*.gz_PATH)/Dockerfile.j2 \ + $(call dpkg_depend,$(TARGET_PATH)/%.gz.dep) $(HEADER) - # Apply series of patches if exist - if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && QUILT_PATCHES=../$(notdir $($*.gz_PATH)).patch quilt push -a; popd; fi - mkdir -p $($*.gz_PATH)/debs $(LOG) - mkdir -p $($*.gz_PATH)/files $(LOG) - mkdir -p $($*.gz_PATH)/python-debs $(LOG) - mkdir -p $($*.gz_PATH)/python-wheels $(LOG) - sudo mount --bind $(DEBS_PATH) $($*.gz_PATH)/debs $(LOG) - sudo mount --bind $(FILES_PATH) $($*.gz_PATH)/files $(LOG) - sudo mount --bind $(PYTHON_DEBS_PATH) $($*.gz_PATH)/python-debs $(LOG) - sudo mount --bind $(PYTHON_WHEELS_PATH) $($*.gz_PATH)/python-wheels $(LOG) - # Export variables for j2. Use path for unique variable names, e.g. docker_orchagent_debs - $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_debs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DEPENDS),RDEPENDS))\n" | awk '!a[$$0]++')) - $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_pydebs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_PYTHON_DEBS)))\n" | awk '!a[$$0]++')) - $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_whls=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_PYTHON_WHEELS)))\n" | awk '!a[$$0]++')) - $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_PACKAGES)))\n" | awk '!a[$$0]++')) - j2 $($*.gz_PATH)/Dockerfile.j2 > $($*.gz_PATH)/Dockerfile - docker info $(LOG) - docker build --squash --no-cache \ - --build-arg http_proxy=$(HTTP_PROXY) \ - --build-arg https_proxy=$(HTTPS_PROXY) \ - --build-arg user=$(USER) \ - --build-arg uid=$(UID) \ - --build-arg guid=$(GUID) \ - --build-arg docker_container_name=$($*.gz_CONTAINER_NAME) \ - --build-arg frr_user_uid=$(FRR_USER_UID) \ - --build-arg frr_user_gid=$(FRR_USER_GID) \ - --label Tag=$(SONIC_GET_VERSION) \ - -t $* $($*.gz_PATH) $(LOG) - docker save $* | gzip -c > $@ - # Clean up - if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; popd; fi + + # Load the target deb from DPKG cache + $(call LOAD_CACHE,$*.gz,$@) + + # Skip building the target if it is already loaded from cache + if [ -z '$($*.gz_CACHE_LOADED)' ] ; then + + # Apply series of patches if exist + if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && QUILT_PATCHES=../$(notdir $($*.gz_PATH)).patch quilt push -a; popd; fi + mkdir -p $($*.gz_PATH)/debs $(LOG) + mkdir -p $($*.gz_PATH)/files $(LOG) + mkdir -p $($*.gz_PATH)/python-debs $(LOG) + mkdir -p $($*.gz_PATH)/python-wheels $(LOG) + sudo mount --bind $(DEBS_PATH) $($*.gz_PATH)/debs $(LOG) + sudo mount --bind $(FILES_PATH) $($*.gz_PATH)/files $(LOG) + sudo mount --bind $(PYTHON_DEBS_PATH) $($*.gz_PATH)/python-debs $(LOG) + sudo mount --bind $(PYTHON_WHEELS_PATH) $($*.gz_PATH)/python-wheels $(LOG) + # Export variables for j2. Use path for unique variable names, e.g. docker_orchagent_debs + $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_debs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DEPENDS),RDEPENDS))\n" | awk '!a[$$0]++')) + $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_pydebs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_PYTHON_DEBS)))\n" | awk '!a[$$0]++')) + $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_whls=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_PYTHON_WHEELS)))\n" | awk '!a[$$0]++')) + $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_PACKAGES)))\n" | awk '!a[$$0]++')) + j2 $($*.gz_PATH)/Dockerfile.j2 > $($*.gz_PATH)/Dockerfile + docker info $(LOG) + docker build --squash --no-cache \ + --build-arg http_proxy=$(HTTP_PROXY) \ + --build-arg https_proxy=$(HTTPS_PROXY) \ + --build-arg user=$(USER) \ + --build-arg uid=$(UID) \ + --build-arg guid=$(GUID) \ + --build-arg docker_container_name=$($*.gz_CONTAINER_NAME) \ + --build-arg frr_user_uid=$(FRR_USER_UID) \ + --build-arg frr_user_gid=$(FRR_USER_GID) \ + --label Tag=$(SONIC_GET_VERSION) \ + -t $* $($*.gz_PATH) $(LOG) + docker save $* | gzip -c > $@ + # Clean up + if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; popd; fi + + # Save the target deb into DPKG cache + $(call SAVE_CACHE,$*.gz,$@) + fi + $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) @@ -573,27 +666,40 @@ SONIC_TARGET_LIST += $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) # Targets for building docker images $(addprefix $(TARGET_PATH)/, $(DOCKER_DBG_IMAGES)) : $(TARGET_PATH)/%-$(DBG_IMAGE_MARK).gz : .platform docker-start \ $$(addprefix $(DEBS_PATH)/,$$($$*.gz_DBG_DEPENDS)) \ - $$(addsuffix -load,$$(addprefix $(TARGET_PATH)/,$$*.gz)) + $$(addsuffix -load,$$(addprefix $(TARGET_PATH)/,$$*.gz)) \ + $(call dpkg_depend,$(TARGET_PATH)/%-$(DBG_IMAGE_MARK).gz.dep) $(HEADER) - mkdir -p $($*.gz_PATH)/debs $(LOG) - sudo mount --bind $(DEBS_PATH) $($*.gz_PATH)/debs $(LOG) - # Export variables for j2. Use path for unique variable names, e.g. docker_orchagent_debs - $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbg_debs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_DEPENDS),RDEPENDS))\n" | awk '!a[$$0]++')) - $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_image_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_IMAGE_PACKAGES)))\n" | awk '!a[$$0]++')) - ./build_debug_docker_j2.sh $* $(subst -,_,$(notdir $($*.gz_PATH)))_dbg_debs $(subst -,_,$(notdir $($*.gz_PATH)))_image_dbgs > $($*.gz_PATH)/Dockerfile-dbg.j2 - j2 $($*.gz_PATH)/Dockerfile-dbg.j2 > $($*.gz_PATH)/Dockerfile-dbg - docker info $(LOG) - docker build \ - $(if $($*.gz_DBG_DEPENDS), --squash --no-cache, --no-cache) \ - --build-arg http_proxy=$(HTTP_PROXY) \ - --build-arg https_proxy=$(HTTPS_PROXY) \ - --build-arg docker_container_name=$($*.gz_CONTAINER_NAME) \ - --label Tag=$(SONIC_GET_VERSION) \ - --file $($*.gz_PATH)/Dockerfile-dbg \ - -t $*-dbg $($*.gz_PATH) $(LOG) - docker save $*-dbg | gzip -c > $@ - # Clean up - if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; popd; fi + + # Load the target deb from DPKG cache + $(call LOAD_CACHE,$*-$(DBG_IMAGE_MARK).gz,$@) + + # Skip building the target if it is already loaded from cache + if [ -z '$($*-$(DBG_IMAGE_MARK).gz_CACHE_LOADED)' ] ; then + + mkdir -p $($*.gz_PATH)/debs $(LOG) + sudo mount --bind $(DEBS_PATH) $($*.gz_PATH)/debs $(LOG) + # Export variables for j2. Use path for unique variable names, e.g. docker_orchagent_debs + $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbg_debs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_DEPENDS),RDEPENDS))\n" | awk '!a[$$0]++')) + $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_image_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_IMAGE_PACKAGES)))\n" | awk '!a[$$0]++')) + ./build_debug_docker_j2.sh $* $(subst -,_,$(notdir $($*.gz_PATH)))_dbg_debs $(subst -,_,$(notdir $($*.gz_PATH)))_image_dbgs > $($*.gz_PATH)/Dockerfile-dbg.j2 + j2 $($*.gz_PATH)/Dockerfile-dbg.j2 > $($*.gz_PATH)/Dockerfile-dbg + docker info $(LOG) + docker build \ + $(if $($*.gz_DBG_DEPENDS), --squash --no-cache, --no-cache) \ + --build-arg http_proxy=$(HTTP_PROXY) \ + --build-arg https_proxy=$(HTTPS_PROXY) \ + --build-arg docker_container_name=$($*.gz_CONTAINER_NAME) \ + --label Tag=$(SONIC_GET_VERSION) \ + --file $($*.gz_PATH)/Dockerfile-dbg \ + -t $*-dbg $($*.gz_PATH) $(LOG) + docker save $*-dbg | gzip -c > $@ + # Clean up + if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; popd; fi + + # Save the target deb into DPKG cache + $(call SAVE_CACHE,$*-$(DBG_IMAGE_MARK).gz,$@) + fi + $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(TARGET_PATH)/, $(DOCKER_DBG_IMAGES)) @@ -766,12 +872,12 @@ SONIC_CLEAN_FILES = $(addsuffix -clean,$(addprefix $(FILES_PATH)/, \ $(SONIC_COPY_FILES) \ $(SONIC_MAKE_FILES))) -$(SONIC_CLEAN_DEBS) : $(DEBS_PATH)/%-clean : .platform $$(addsuffix -clean,$$(addprefix $(DEBS_PATH)/,$$($$*_MAIN_DEB))) +$(SONIC_CLEAN_DEBS) :: $(DEBS_PATH)/%-clean : .platform $$(addsuffix -clean,$$(addprefix $(DEBS_PATH)/,$$($$*_MAIN_DEB))) @# remove derived or extra targets if main one is removed, because we treat them @# as part of one package @rm -f $(addprefix $(DEBS_PATH)/, $* $($*_DERIVED_DEBS) $($*_EXTRA_DEBS)) -$(SONIC_CLEAN_FILES) : $(FILES_PATH)/%-clean : .platform +$(SONIC_CLEAN_FILES) :: $(FILES_PATH)/%-clean : .platform @rm -f $(FILES_PATH)/$* SONIC_CLEAN_TARGETS += $(addsuffix -clean,$(addprefix $(TARGET_PATH)/, \ @@ -779,23 +885,23 @@ SONIC_CLEAN_TARGETS += $(addsuffix -clean,$(addprefix $(TARGET_PATH)/, \ $(SONIC_DOCKER_DBG_IMAGES) \ $(SONIC_SIMPLE_DOCKER_IMAGES) \ $(SONIC_INSTALLERS))) -$(SONIC_CLEAN_TARGETS) : $(TARGET_PATH)/%-clean : .platform +$(SONIC_CLEAN_TARGETS) :: $(TARGET_PATH)/%-clean : .platform @rm -f $(TARGET_PATH)/$* SONIC_CLEAN_STDEB_DEBS = $(addsuffix -clean,$(addprefix $(PYTHON_DEBS_PATH)/, \ $(SONIC_PYTHON_STDEB_DEBS))) -$(SONIC_CLEAN_STDEB_DEBS) : $(PYTHON_DEBS_PATH)/%-clean : .platform +$(SONIC_CLEAN_STDEB_DEBS) :: $(PYTHON_DEBS_PATH)/%-clean : .platform @rm -f $(PYTHON_DEBS_PATH)/$* SONIC_CLEAN_WHEELS = $(addsuffix -clean,$(addprefix $(PYTHON_WHEELS_PATH)/, \ $(SONIC_PYTHON_WHEELS))) -$(SONIC_CLEAN_WHEELS) : $(PYTHON_WHEELS_PATH)/%-clean : .platform +$(SONIC_CLEAN_WHEELS) :: $(PYTHON_WHEELS_PATH)/%-clean : .platform @rm -f $(PYTHON_WHEELS_PATH)/$* -clean-logs : .platform +clean-logs :: .platform @rm -f $(TARGET_PATH)/*.log $(DEBS_PATH)/*.log $(FILES_PATH)/*.log $(PYTHON_DEBS_PATH)/*.log $(PYTHON_WHEELS_PATH)/*.log -clean : .platform clean-logs $$(SONIC_CLEAN_DEBS) $$(SONIC_CLEAN_FILES) $$(SONIC_CLEAN_TARGETS) $$(SONIC_CLEAN_STDEB_DEBS) $$(SONIC_CLEAN_WHEELS) +clean :: .platform clean-logs $$(SONIC_CLEAN_DEBS) $$(SONIC_CLEAN_FILES) $$(SONIC_CLEAN_TARGETS) $$(SONIC_CLEAN_STDEB_DEBS) $$(SONIC_CLEAN_WHEELS) ############################################################################### ## all From 540cc7803843e04920457c8dbf9d53c32c628e06 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Fri, 13 Mar 2020 01:11:15 +0200 Subject: [PATCH 0421/1427] [Service] Added NAT entry into CONTAINER_FEATURE. Fixes #4247. (#4250) * [Service] Added NAT entry into CONTAINER_FEATURE. Fixes #4247. Signed-off-by: Andriy Kokhan --- files/build_templates/init_cfg.json.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 17617ee1a3cb..c187e02762b8 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -25,7 +25,7 @@ {% endfor %} }, "CONTAINER_FEATURE": { -{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "pmon", "radv", "restapi", "sflow", +{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "nat", "pmon", "radv", "restapi", "sflow", "snmp", "swss", "syncd", "teamd", "telemetry"] %} "{{container}}": { "auto_restart": "disabled", From 978e717727a6fecbbae255da079f311bbb99592f Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 12 Mar 2020 22:04:41 -0700 Subject: [PATCH 0422/1427] Update submodule sonic-mgmt-framework to fix build (#4255) --- src/sonic-mgmt-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework index 00410e5516ec..a4f1650d505c 160000 --- a/src/sonic-mgmt-framework +++ b/src/sonic-mgmt-framework @@ -1 +1 @@ -Subproject commit 00410e5516ec4dce957c6bb1fdd0258ef47bfafa +Subproject commit a4f1650d505c14d94872bd216f218e7c752de05c From 4721c4b54b2d4a2416399154136d042ef0cb1d1b Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Sat, 14 Mar 2020 18:27:15 -0700 Subject: [PATCH 0423/1427] Update submodule sairedis to fix rpc build (#4253) --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 1809f7aaef17..fe94170c8097 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 1809f7aaef1770bd44fab6bcaf26e812cdfbf667 +Subproject commit fe94170c809773d86b196bd8d881f78ba71a1d7c From 487a734ce0c62f4269bb73317106c571fb9c3d74 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Sun, 15 Mar 2020 13:54:05 -0700 Subject: [PATCH 0424/1427] [vs] Add dependencies for NAT to docker-sonic-vs (#4259) I added dependencies to support the NAT feature on the virtual switch. Signed-off-by: Danny Allen --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 7cc6f98921ff..ee3858aca647 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -51,7 +51,9 @@ RUN apt-get install -y net-tools \ apt-utils \ psmisc \ tcpdump \ - python-scapy + python-scapy \ + conntrack \ + iptables RUN pip install setuptools RUN pip install py2_ipaddress From a3bbdc992968a30147fbcf6c01b034e0ae78d956 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Tue, 17 Mar 2020 10:14:59 -0700 Subject: [PATCH 0425/1427] [arista] Update platform drivers submodules (#4200) * Build Arista drivers using DPKG_DEB * Update arista platform submodule --- platform/barefoot/platform-modules-arista.mk | 2 +- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/platform-modules-arista.mk | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/barefoot/platform-modules-arista.mk b/platform/barefoot/platform-modules-arista.mk index 480aa0cf8396..28c893b80713 100644 --- a/platform/barefoot/platform-modules-arista.mk +++ b/platform/barefoot/platform-modules-arista.mk @@ -7,7 +7,7 @@ export ARISTA_PLATFORM_MODULE_VERSION ARISTA_PLATFORM_MODULE = sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_amd64.deb $(ARISTA_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-arista $(ARISTA_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) -SONIC_MAKE_DEBS += $(ARISTA_PLATFORM_MODULE) +SONIC_DPKG_DEBS += $(ARISTA_PLATFORM_MODULE) ARISTA_PLATFORM_MODULE_PYTHON2 = python-sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_all.deb $(eval $(call add_extra_package,$(ARISTA_PLATFORM_MODULE),$(ARISTA_PLATFORM_MODULE_PYTHON2))) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index b1940cf49a18..e9cabadb4272 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit b1940cf49a185745cc9365afed8efb511478807e +Subproject commit e9cabadb42725d3c86eb93c3d766cfb5d58e6d29 diff --git a/platform/broadcom/platform-modules-arista.mk b/platform/broadcom/platform-modules-arista.mk index 480aa0cf8396..28c893b80713 100644 --- a/platform/broadcom/platform-modules-arista.mk +++ b/platform/broadcom/platform-modules-arista.mk @@ -7,7 +7,7 @@ export ARISTA_PLATFORM_MODULE_VERSION ARISTA_PLATFORM_MODULE = sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_amd64.deb $(ARISTA_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-arista $(ARISTA_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) -SONIC_MAKE_DEBS += $(ARISTA_PLATFORM_MODULE) +SONIC_DPKG_DEBS += $(ARISTA_PLATFORM_MODULE) ARISTA_PLATFORM_MODULE_PYTHON2 = python-sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_all.deb $(eval $(call add_extra_package,$(ARISTA_PLATFORM_MODULE),$(ARISTA_PLATFORM_MODULE_PYTHON2))) diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index b1940cf49a18..e9cabadb4272 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit b1940cf49a185745cc9365afed8efb511478807e +Subproject commit e9cabadb42725d3c86eb93c3d766cfb5d58e6d29 From 9b48c224498fa4e26e85725c9d39913c6bc5d60c Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 18 Mar 2020 11:01:36 -0700 Subject: [PATCH 0426/1427] [docker-ptf]: install ntp related package (#4275) setup ntp server to do the test Signed-off-by: Guohan Lu --- dockers/docker-ptf/Dockerfile.j2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index 73c881cab1a9..8d529779ccdb 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -61,7 +61,10 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / python-scapy \ python-six \ tacacs+ \ - rsyslog + rsyslog \ + ntp \ + ntpstat \ + ntpdate RUN dpkg -i \ {% for deb in docker_ptf_debs.split(' ') -%} From bfe690b739c921836f2cfe85a301a4ebeab32a6c Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Wed, 18 Mar 2020 20:59:39 +0200 Subject: [PATCH 0427/1427] [syncd-rpc.mk] install ptf dependancy (#4279) Signed-off-by: Mykola Faryma --- platform/barefoot/docker-syncd-bfn-rpc.mk | 2 +- platform/broadcom/docker-syncd-brcm-rpc.mk | 2 +- platform/cavium/docker-syncd-cavm-rpc.mk | 2 +- platform/centec/docker-syncd-centec-rpc.mk | 2 +- platform/innovium/docker-syncd-invm-rpc.mk | 2 +- platform/marvell-arm64/docker-syncd-mrvl-rpc.mk | 2 +- platform/marvell-armhf/docker-syncd-mrvl-rpc.mk | 2 +- platform/marvell/docker-syncd-mrvl-rpc.mk | 2 +- platform/mellanox/docker-syncd-mlnx-rpc.mk | 2 +- platform/nephos/docker-syncd-nephos-rpc.mk | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/platform/barefoot/docker-syncd-bfn-rpc.mk b/platform/barefoot/docker-syncd-bfn-rpc.mk index d9cb0b5d6172..11b70a3a774f 100644 --- a/platform/barefoot/docker-syncd-bfn-rpc.mk +++ b/platform/barefoot/docker-syncd-bfn-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_BFN_RPC = docker-syncd-bfn-rpc.gz $(DOCKER_SYNCD_BFN_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-bfn-rpc -$(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_BFN_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/broadcom/docker-syncd-brcm-rpc.mk b/platform/broadcom/docker-syncd-brcm-rpc.mk index bd2ef01c5eed..355d7e0f1f8c 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc.mk +++ b/platform/broadcom/docker-syncd-brcm-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_BRCM_RPC = docker-syncd-brcm-rpc.gz $(DOCKER_SYNCD_BRCM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-brcm-rpc -$(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/cavium/docker-syncd-cavm-rpc.mk b/platform/cavium/docker-syncd-cavm-rpc.mk index e57370fce5ca..ebe614b3c183 100644 --- a/platform/cavium/docker-syncd-cavm-rpc.mk +++ b/platform/cavium/docker-syncd-cavm-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_CAVM_RPC = docker-syncd-cavm-rpc.gz $(DOCKER_SYNCD_CAVM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm-rpc -$(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) +$(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) $(PTF) $(DOCKER_SYNCD_CAVM_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/centec/docker-syncd-centec-rpc.mk b/platform/centec/docker-syncd-centec-rpc.mk index 71c8ef7753c1..47c672dd93de 100644 --- a/platform/centec/docker-syncd-centec-rpc.mk +++ b/platform/centec/docker-syncd-centec-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_CENTEC_RPC = docker-syncd-centec-rpc.gz $(DOCKER_SYNCD_CENTEC_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec-rpc -$(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_CENTEC_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/innovium/docker-syncd-invm-rpc.mk b/platform/innovium/docker-syncd-invm-rpc.mk index 313f0d12ac20..62d6891bbc21 100755 --- a/platform/innovium/docker-syncd-invm-rpc.mk +++ b/platform/innovium/docker-syncd-invm-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_INVM_RPC = docker-syncd-invm-rpc.gz $(DOCKER_SYNCD_INVM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-invm-rpc -$(DOCKER_SYNCD_INVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(INVM_LIBSAI) +$(DOCKER_SYNCD_INVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(INVM_LIBSAI) $(PTF) $(DOCKER_SYNCD_INVM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_INVM_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk b/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk index 0e1b65f2fd5d..c3ce6c10119c 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc -$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk b/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk index 0e1b65f2fd5d..c3ce6c10119c 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc -$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/marvell/docker-syncd-mrvl-rpc.mk b/platform/marvell/docker-syncd-mrvl-rpc.mk index 0e1b65f2fd5d..c3ce6c10119c 100644 --- a/platform/marvell/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell/docker-syncd-mrvl-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc -$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.mk b/platform/mellanox/docker-syncd-mlnx-rpc.mk index ed9eea9ae8f8..ef2aec3333ac 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc.mk +++ b/platform/mellanox/docker-syncd-mlnx-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MLNX_RPC = docker-syncd-mlnx-rpc.gz $(DOCKER_SYNCD_MLNX_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mlnx-rpc -$(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MLNX_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/nephos/docker-syncd-nephos-rpc.mk b/platform/nephos/docker-syncd-nephos-rpc.mk index dafc43b3e7e3..39240c1913e4 100644 --- a/platform/nephos/docker-syncd-nephos-rpc.mk +++ b/platform/nephos/docker-syncd-nephos-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_NEPHOS_RPC = docker-syncd-nephos-rpc.gz $(DOCKER_SYNCD_NEPHOS_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-nephos-rpc -$(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ From 9c866cd17e556cbd794058e6acaeba24c81c82e4 Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Thu, 19 Mar 2020 05:05:42 +0800 Subject: [PATCH 0428/1427] [platform/nephos] Upgrade nephos-modules from 1.0.0 to 1.0.1 (#4267) --- platform/nephos/nephos-modules.mk | 2 +- .../nephos/nephos-modules/debian/changelog | 8 +- platform/nephos/nephos-modules/debian/control | 2 +- ...-4.9.0-9-2-amd64 => nps-modules-4.9-amd64} | 0 ....service => nps-modules-4.9-amd64.service} | 4 +- .../modules/src/hal_tau_pkt_knl.c | 808 +++++++++++------ .../nephos-modules/modules/src/inc/aml.h | 2 +- .../nephos-modules/modules/src/inc/hal_dev.h | 2 +- .../modules/src/inc/hal_tau_pkt_knl.h | 273 +++--- .../nephos-modules/modules/src/inc/netif_nl.h | 104 +++ .../modules/src/inc/netif_osal.h | 2 +- .../modules/src/inc/netif_perf.h | 2 +- .../nephos-modules/modules/src/inc/nps_cfg.h | 2 +- .../modules/src/inc/nps_error.h | 2 +- .../modules/src/inc/nps_types.h | 2 +- .../nephos-modules/modules/src/inc/osal_mdc.h | 12 +- .../modules/src/inc/osal_types.h | 2 +- .../nephos/nephos-modules/modules/src/make.mk | 4 +- .../nephos-modules/modules/src/netif_nl.c | 811 ++++++++++++++++++ .../nephos-modules/modules/src/netif_osal.c | 2 +- .../nephos-modules/modules/src/netif_perf.c | 2 +- .../nephos-modules/modules/src/osal_isymbol.c | 2 +- .../nephos-modules/modules/src/osal_mdc.c | 171 +++- 23 files changed, 1821 insertions(+), 400 deletions(-) rename platform/nephos/nephos-modules/modules/init.d/{nps-modules-4.9.0-9-2-amd64 => nps-modules-4.9-amd64} (100%) rename platform/nephos/nephos-modules/modules/service/{nps-modules-4.9.0-9-2-amd64.service => nps-modules-4.9-amd64.service} (60%) create mode 100755 platform/nephos/nephos-modules/modules/src/inc/netif_nl.h create mode 100755 platform/nephos/nephos-modules/modules/src/netif_nl.c diff --git a/platform/nephos/nephos-modules.mk b/platform/nephos/nephos-modules.mk index ebd696217b8e..50a2d0e5c080 100644 --- a/platform/nephos/nephos-modules.mk +++ b/platform/nephos/nephos-modules.mk @@ -1,6 +1,6 @@ # Nephos Platform modules -VERSION = 1.0.0 +VERSION = 1.0.1 ifneq ($(NEPHOS_SAI_DEB_LOCAL_URL), ) SDK_FROM_LOCAL = y diff --git a/platform/nephos/nephos-modules/debian/changelog b/platform/nephos/nephos-modules/debian/changelog index 3de2bd045efd..94c7aa7d3915 100644 --- a/platform/nephos/nephos-modules/debian/changelog +++ b/platform/nephos/nephos-modules/debian/changelog @@ -1,5 +1,11 @@ +nephos-modules (1.0.1) unstable; urgency=low + + * Upgrade ko version to 3.0.0 + +-- Support Tue, 17 Mar 2020 15:54:00 +0800 + nephos-modules (1.0.0) unstable; urgency=low * Initial release - -- Support Fri, 15 Mar 2019 15:54:00 +0800 +-- Support Fri, 15 Mar 2019 15:54:00 +0800 diff --git a/platform/nephos/nephos-modules/debian/control b/platform/nephos/nephos-modules/debian/control index 246b89eab477..3d06ca971f89 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -1,7 +1,7 @@ Source: nephos-modules Section: main Priority: extra -Maintainer: support +Maintainer: support Build-Depends: debhelper (>= 8.0.0), bzip2 Standards-Version: 3.9.3 diff --git a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 b/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 similarity index 100% rename from platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 rename to platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 diff --git a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service similarity index 60% rename from platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service rename to platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service index 9acdeb30a44c..fc45a597d74c 100644 --- a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service +++ b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service @@ -5,8 +5,8 @@ Before=syncd.service [Service] Type=oneshot -ExecStart=-/etc/init.d/nps-modules-4.9.0-11-2-amd64 start -ExecStop=-/etc/init.d/nps-modules-4.9.0-11-2-amd64 stop +ExecStart=-/etc/init.d/nps-modules-4.9-amd64 start +ExecStop=-/etc/init.d/nps-modules-4.9-amd64 stop RemainAfterExit=yes [Install] diff --git a/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c b/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c index b386da63e247..a67b1d5f8868 100755 --- a/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c +++ b/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -45,6 +45,9 @@ /* netif */ #include #include +#if defined(NETIF_EN_NETLINK) +#include +#endif #include /* nps_sdk */ @@ -69,19 +72,20 @@ /* This flag value will be specified when user inserts kernel module. */ -#define HAL_TAU_PKT_DBG_ERR (0x1 << 0) -#define HAL_TAU_PKT_DBG_TX (0x1 << 1) -#define HAL_TAU_PKT_DBG_RX (0x1 << 2) -#define HAL_TAU_PKT_DBG_INTF (0x1 << 3) -#define HAL_TAU_PKT_DBG_PROFILE (0x1 << 4) -#define HAL_TAU_PKT_DBG_COMMON (0x1 << 5) +#define HAL_TAU_PKT_DBG_ERR (0x1UL << 0) +#define HAL_TAU_PKT_DBG_TX (0x1UL << 1) +#define HAL_TAU_PKT_DBG_RX (0x1UL << 2) +#define HAL_TAU_PKT_DBG_INTF (0x1UL << 3) +#define HAL_TAU_PKT_DBG_PROFILE (0x1UL << 4) +#define HAL_TAU_PKT_DBG_COMMON (0x1UL << 5) +#define HAL_TAU_PKT_DBG_NETLINK (0x1UL << 6) /* Will be set when inserting kernel module */ -static UI32_T dbg_flag = 0; +UI32_T ext_dbg_flag = 0; #define HAL_TAU_PKT_DBG(__flag__, ...) do \ { \ - if (0 != ((__flag__) & (dbg_flag))) \ + if (0 != ((__flag__) & (ext_dbg_flag))) \ { \ osal_printf(__VA_ARGS__); \ } \ @@ -113,15 +117,15 @@ typedef struct static HAL_TAU_PKT_INTR_VEC_T _hal_tau_pkt_intr_vec[] = { - { /* 0: PDMA_ERR */ 1 << 0, 0x0, 0 }, - { /* 1: TX_CH0 */ 1 << 28, 0x0, 0 }, - { /* 2: TX_CH1 */ 1 << 29, 0x0, 0 }, - { /* 3: TX_CH2 */ 1 << 30, 0x0, 0 }, - { /* 4: TX_CH3 */ 1 << 31, 0x0, 0 }, - { /* 5: RX_CH0 */ 1 << 12, 0x0, 0 }, - { /* 6: RX_CH1 */ 1 << 13, 0x0, 0 }, - { /* 7: RX_CH2 */ 1 << 14, 0x0, 0 }, - { /* 8: RX_CH3 */ 1 << 15, 0x0, 0 }, + { /* 0: PDMA_ERR */ 1UL << 0, 0x0, 0 }, + { /* 1: TX_CH0 */ 1UL << 28, 0x0, 0 }, + { /* 2: TX_CH1 */ 1UL << 29, 0x0, 0 }, + { /* 3: TX_CH2 */ 1UL << 30, 0x0, 0 }, + { /* 4: TX_CH3 */ 1UL << 31, 0x0, 0 }, + { /* 5: RX_CH0 */ 1UL << 12, 0x0, 0 }, + { /* 6: RX_CH1 */ 1UL << 13, 0x0, 0 }, + { /* 7: RX_CH2 */ 1UL << 14, 0x0, 0 }, + { /* 8: RX_CH3 */ 1UL << 15, 0x0, 0 }, }; /***************************************************************************** @@ -136,9 +140,10 @@ static HAL_TAU_PKT_INTR_VEC_T _hal_tau_pkt_intr_vec[] = #define HAL_TAU_PKT_ALLOC_MEM_RETRY_SLEEP() osal_sleepThread(1000) /* us */ /* Network Device Definitions */ -#define HAL_TAU_PKT_TX_TIMEOUT (6*HZ) +/* In case that the watchdog alarm during warm-boot if intf isn't killed */ +#define HAL_TAU_PKT_TX_TIMEOUT (30*HZ) #define HAL_TAU_PKT_MAX_ETH_FRAME_SIZE (HAL_TAU_PKT_RX_MAX_LEN) -#define HAL_TAU_PKT_MAX_PORT_NUM (HAL_TAU_PORT_NUM + 1) /* CPU port */ +#define HAL_TAU_PKT_MAX_PORT_NUM (HAL_PORT_NUM + 1) /* CPU port */ #define HAL_TAU_PKT_NET_PROFILE_NUM_MAX (256) @@ -199,10 +204,10 @@ typedef struct NPS_ISRLOCK_ID_T intr_lock; UI32_T intr_bitmap; -#define HAL_TAU_PKT_INIT_DRV (1 << 0) -#define HAL_TAU_PKT_INIT_TASK (1 << 1) -#define HAL_TAU_PKT_INIT_INTR (1 << 2) -#define HAL_TAU_PKT_INIT_RX_START (1 << 3) +#define HAL_TAU_PKT_INIT_DRV (1UL << 0) +#define HAL_TAU_PKT_INIT_TASK (1UL << 1) +#define HAL_TAU_PKT_INIT_INTR (1UL << 2) +#define HAL_TAU_PKT_INIT_RX_START (1UL << 3) /* a bitmap to record the init status */ UI32_T init_flag; @@ -255,6 +260,10 @@ typedef struct BOOL_T running; /* TRUE when Init txTask * FALSE when Destroy txTask */ + /* to block net intf Tx in driver level since netif_tx_disable() + * cannot always prevent intf from Tx in time + */ + BOOL_T net_tx_allowed; } HAL_TAU_PKT_TX_CB_T; @@ -312,6 +321,9 @@ typedef enum { HAL_TAU_PKT_DEST_NETDEV = 0, HAL_TAU_PKT_DEST_SDK, +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_DEST_NETLINK, +#endif HAL_TAU_PKT_DEST_DROP, HAL_TAU_PKT_DEST_LAST } HAL_TAU_PKT_DEST_T; @@ -1215,7 +1227,158 @@ hal_tau_pkt_setPortAttr( return (NPS_E_OK); } +static void +_hal_tau_pkt_lockRxChannelAll( + const UI32_T unit) +{ + UI32_T rch; + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; + + for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) + { + ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); + osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); + } +} + +static void +_hal_tau_pkt_unlockRxChannelAll( + const UI32_T unit) +{ + UI32_T rch; + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; + + for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) + { + ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); + osal_giveSemaphore(&ptr_rx_pdma->sema); + } +} + +#if defined(NETIF_EN_NETLINK) + +static NPS_ERROR_NO_T +_hal_tau_pkt_setIntfProperty( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T intf_id; + NETIF_NL_INTF_PROPERTY_T property; + UI32_T param0; + UI32_T param1; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&intf_id, &ptr_cookie->intf_id, sizeof(UI32_T)); + osal_io_copyFromUser(&property, &ptr_cookie->property, sizeof(NETIF_NL_INTF_PROPERTY_T)); + osal_io_copyFromUser(¶m0, &ptr_cookie->param0, sizeof(UI32_T)); + osal_io_copyFromUser(¶m1, &ptr_cookie->param1, sizeof(UI32_T)); + + _hal_tau_pkt_lockRxChannelAll(unit); + + rc = netif_nl_setIntfProperty(unit, intf_id, property, param0, param1); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_getIntfProperty( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T intf_id; + NETIF_NL_INTF_PROPERTY_T property; + UI32_T param0; + UI32_T param1; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&intf_id, &ptr_cookie->intf_id, sizeof(UI32_T)); + osal_io_copyFromUser(&property, &ptr_cookie->property, sizeof(NETIF_NL_INTF_PROPERTY_T)); + osal_io_copyFromUser(¶m0, &ptr_cookie->param0, sizeof(UI32_T)); + + rc = netif_nl_getIntfProperty(unit, intf_id, property, ¶m0, ¶m1); + + osal_io_copyToUser(&ptr_cookie->param0, ¶m0, sizeof(UI32_T)); + osal_io_copyToUser(&ptr_cookie->param1, ¶m1, sizeof(UI32_T)); + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_createNetlink( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + NETIF_NL_NETLINK_T netlink; + UI32_T netlink_id; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&netlink, &ptr_cookie->netlink, sizeof(NETIF_NL_NETLINK_T)); + + _hal_tau_pkt_lockRxChannelAll(unit); + + rc = netif_nl_createNetlink(unit, &netlink, &netlink_id); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + osal_io_copyToUser(&ptr_cookie->netlink.id, &netlink_id, sizeof(UI32_T)); + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_destroyNetlink( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T netlink_id; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&netlink_id, &ptr_cookie->netlink.id, sizeof(UI32_T)); + + _hal_tau_pkt_lockRxChannelAll(unit); + + rc = netif_nl_destroyNetlink(unit, netlink_id); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_getNetlink( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T id; + NETIF_NL_NETLINK_T netlink; + NPS_ERROR_NO_T rc; + osal_io_copyFromUser(&id, &ptr_cookie->netlink.id, sizeof(UI32_T)); + + rc = netif_nl_getNetlink(unit, id, &netlink); + if (NPS_E_OK == rc) + { + osal_io_copyToUser(&ptr_cookie->netlink, &netlink, sizeof(NETIF_NL_NETLINK_T)); + } + else + { + rc = NPS_E_ENTRY_NOT_FOUND; + } + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (NPS_E_OK); +} + +#endif /* ----------------------------------------------------------------------------------- independent func */ /* FUNCTION NAME: _hal_tau_pkt_enQueue * PURPOSE: @@ -1877,7 +2040,7 @@ _hal_tau_pkt_rxCheckReason( HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile, BOOL_T *ptr_hit_prof) { - HAL_TAU_PKT_RX_REASON_BITMAP_T *ptr_reason_bitmap = &ptr_profile->reason_bitmap; + HAL_PKT_RX_REASON_BITMAP_T *ptr_reason_bitmap = &ptr_profile->reason_bitmap; UI32_T bitval = 0; UI32_T bitmap = 0x0; @@ -1888,10 +2051,10 @@ _hal_tau_pkt_rxCheckReason( return; } -#define HAL_TAU_PKT_DI_NON_L3_CPU_MIN (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_NON_L3_MIN) -#define HAL_TAU_PKT_DI_NON_L3_CPU_MAX (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_NON_L3_MAX) -#define HAL_TAU_PKT_DI_L3_CPU_MIN (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_L3_MIN) -#define HAL_TAU_PKT_DI_L3_CPU_MAX (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_L3_MAX) +#define HAL_TAU_PKT_DI_NON_L3_CPU_MIN (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_NON_L3_MIN) +#define HAL_TAU_PKT_DI_NON_L3_CPU_MAX (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_NON_L3_MAX) +#define HAL_TAU_PKT_DI_L3_CPU_MIN (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_L3_MIN) +#define HAL_TAU_PKT_DI_L3_CPU_MAX (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_L3_MAX) switch (ptr_rx_gpd->itmh_eth.typ) { @@ -1902,7 +2065,7 @@ _hal_tau_pkt_rxCheckReason( ptr_rx_gpd->itmh_eth.dst_idx <= HAL_TAU_PKT_DI_NON_L3_CPU_MAX) { bitval = ptr_rx_gpd->itmh_eth.dst_idx - HAL_TAU_PKT_DI_NON_L3_CPU_MIN; - bitmap = 1 << (bitval % 32); + bitmap = 1UL << (bitval % 32); if (0 != (ptr_reason_bitmap->ipp_excpt_bitmap[bitval / 32] & bitmap)) { *ptr_hit_prof = TRUE; @@ -1932,7 +2095,7 @@ _hal_tau_pkt_rxCheckReason( /* IPP cp_to_cpu_rsn */ bitval = ptr_rx_gpd->itmh_eth.cp_to_cpu_code; - bitmap = 1 << (bitval % 32); + bitmap = 1UL << (bitval % 32); if (0 != (ptr_reason_bitmap->ipp_rsn_bitmap[bitval / 32] & bitmap)) { *ptr_hit_prof = TRUE; @@ -1950,7 +2113,7 @@ _hal_tau_pkt_rxCheckReason( if (1 == ptr_rx_gpd->etmh_eth.redir) { bitval = ptr_rx_gpd->etmh_eth.excpt_code_mir_bmap; - bitmap = 1 << (bitval % 32); + bitmap = 1UL << (bitval % 32); if (0 != (ptr_reason_bitmap->epp_excpt_bitmap[bitval / 32] & bitmap)) { *ptr_hit_prof = TRUE; @@ -2059,25 +2222,30 @@ static void _hal_tau_pkt_matchUserProfile( volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd, HAL_TAU_PKT_PROFILE_NODE_T *ptr_profile_list, - BOOL_T *ptr_hit_prof) + HAL_TAU_PKT_NETIF_PROFILE_T **pptr_profile_hit) { HAL_TAU_PKT_PROFILE_NODE_T *ptr_curr_node = ptr_profile_list; + BOOL_T hit; + + *pptr_profile_hit = NULL; while (NULL != ptr_curr_node) { /* 1st match reason */ - _hal_tau_pkt_rxCheckReason(ptr_rx_gpd, ptr_curr_node->ptr_profile, ptr_hit_prof); - if (TRUE == *ptr_hit_prof) + _hal_tau_pkt_rxCheckReason(ptr_rx_gpd, ptr_curr_node->ptr_profile, &hit); + if (TRUE == hit) { HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, "rx prof matched by reason\n"); /* Then, check pattern */ - _hal_tau_pkt_rxCheckPattern(ptr_rx_gpd, ptr_curr_node->ptr_profile, ptr_hit_prof); - if (TRUE == *ptr_hit_prof) + _hal_tau_pkt_rxCheckPattern(ptr_rx_gpd, ptr_curr_node->ptr_profile, &hit); + if (TRUE == hit) { HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, "rx prof matched by pattern\n"); + + *pptr_profile_hit = ptr_curr_node->ptr_profile; break; } } @@ -2090,19 +2258,34 @@ _hal_tau_pkt_matchUserProfile( static void _hal_tau_pkt_getPacketDest( volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd, - HAL_TAU_PKT_DEST_T *ptr_dest) + HAL_TAU_PKT_DEST_T *ptr_dest, + void **pptr_cookie) { - BOOL_T hit_prof = FALSE; UI32_T port; HAL_TAU_PKT_PROFILE_NODE_T *ptr_profile_list; + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile_hit; port = ptr_rx_gpd->itmh_eth.igr_phy_port; ptr_profile_list = HAL_TAU_PKT_GET_PORT_PROFILE_LIST(port); - _hal_tau_pkt_matchUserProfile(ptr_rx_gpd, ptr_profile_list, &hit_prof); - if (TRUE == hit_prof) + _hal_tau_pkt_matchUserProfile(ptr_rx_gpd, + ptr_profile_list, + &ptr_profile_hit); + if (NULL != ptr_profile_hit) { +#if defined(NETIF_EN_NETLINK) + if (HAL_TAU_PKT_NETIF_RX_DST_NETLINK == ptr_profile_hit->dst_type) + { + *ptr_dest = HAL_TAU_PKT_DEST_NETLINK; + *pptr_cookie = (void *)&ptr_profile_hit->netlink; + } + else + { + *ptr_dest = HAL_TAU_PKT_DEST_SDK; + } +#else *ptr_dest = HAL_TAU_PKT_DEST_SDK; +#endif } else { @@ -2134,7 +2317,7 @@ _hal_tau_pkt_rxEnQueue( HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_first_gpd = ptr_sw_gpd; void *ptr_virt_addr = NULL; NPS_ADDR_T phy_addr = 0; - HAL_TAU_PKT_DEST_T pkt_dest; + HAL_TAU_PKT_DEST_T dest_type; /* skb meta */ UI32_T port = 0, len = 0, total_len = 0; @@ -2142,6 +2325,7 @@ _hal_tau_pkt_rxEnQueue( struct net_device_priv *ptr_priv = NULL; struct sk_buff *ptr_skb = NULL, *ptr_merge_skb = NULL; UI32_T copy_offset; + void *ptr_dest; #if defined(PERF_EN_TEST) /* To verify kernel Rx performance */ @@ -2166,9 +2350,16 @@ _hal_tau_pkt_rxEnQueue( } #endif - _hal_tau_pkt_getPacketDest(&ptr_sw_gpd->rx_gpd, &pkt_dest); - if (HAL_TAU_PKT_DEST_NETDEV == pkt_dest) + _hal_tau_pkt_getPacketDest(&ptr_sw_gpd->rx_gpd, &dest_type, &ptr_dest); + +#if defined(NETIF_EN_NETLINK) + if ((HAL_TAU_PKT_DEST_NETDEV == dest_type) || + (HAL_TAU_PKT_DEST_NETLINK == dest_type)) +#else + if (HAL_TAU_PKT_DEST_NETDEV == dest_type) +#endif { + /* need to encap the packet as skb */ ptr_sw_gpd = ptr_sw_first_gpd; while (NULL != ptr_sw_gpd) { @@ -2205,6 +2396,9 @@ _hal_tau_pkt_rxEnQueue( ptr_sw_gpd = ptr_sw_gpd->ptr_next; } + port = ptr_sw_first_gpd->rx_gpd.itmh_eth.igr_phy_port; + ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); + /* if the packet is composed of multiple gpd (skb), need to merge it into a single skb */ if (NULL != ptr_sw_first_gpd->ptr_next) { @@ -2247,10 +2441,6 @@ _hal_tau_pkt_rxEnQueue( _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd, FALSE); } - /* get port and net_device */ - port = ptr_sw_first_gpd->rx_gpd.itmh_eth.igr_phy_port; - ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); - /* if NULL netdev, drop the skb */ if (NULL == ptr_net_dev) { @@ -2265,19 +2455,33 @@ _hal_tau_pkt_rxEnQueue( /* skb handling */ ptr_skb->dev = ptr_net_dev; ptr_skb->pkt_type = PACKET_HOST; /* this packet is for me */ - ptr_skb->protocol = eth_type_trans(ptr_skb, ptr_net_dev); /* skip ethernet header */ ptr_skb->ip_summed = CHECKSUM_UNNECESSARY; /* skip checksum */ /* send to linux */ - osal_skb_recv(ptr_skb); + if (dest_type == HAL_TAU_PKT_DEST_NETDEV) + { + /* skip ethernet header only for Linux net interface*/ + ptr_skb->protocol = eth_type_trans(ptr_skb, ptr_net_dev); + osal_skb_recv(ptr_skb); #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) - ptr_net_dev->last_rx = jiffies; + ptr_net_dev->last_rx = jiffies; +#endif + ptr_priv = netdev_priv(ptr_net_dev); + ptr_priv->stats.rx_packets++; + ptr_priv->stats.rx_bytes += total_len; + } +#if defined(NETIF_EN_NETLINK) + else + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "hit profile dest=netlink, name=%s, mcgrp=%s\n", + ((NETIF_NL_RX_DST_NETLINK_T *)ptr_dest)->name, + ((NETIF_NL_RX_DST_NETLINK_T *)ptr_dest)->mc_group_name); + netif_nl_rxSkb(unit, ptr_skb, ptr_dest); + } #endif - ptr_priv = netdev_priv(ptr_net_dev); - ptr_priv->stats.rx_packets++; - ptr_priv->stats.rx_bytes += total_len; } - else if (HAL_TAU_PKT_DEST_SDK == pkt_dest) + else if (HAL_TAU_PKT_DEST_SDK == dest_type) { while (0 != _hal_tau_pkt_enQueue(&ptr_rx_cb->sw_queue[channel], ptr_sw_gpd)) { @@ -2289,7 +2493,7 @@ _hal_tau_pkt_rxEnQueue( osal_triggerEvent(&ptr_rx_cb->sync_sema); ptr_rx_cb->cnt.channel[channel].trig_event++; } - else if (HAL_TAU_PKT_DEST_DROP == pkt_dest) + else if (HAL_TAU_PKT_DEST_DROP == dest_type) { _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd, TRUE); } @@ -2297,10 +2501,34 @@ _hal_tau_pkt_rxEnQueue( { HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), "u=%u, rxch=%u, invalid pkt dest=%d\n", - unit, channel, pkt_dest); + unit, channel, dest_type); } } +static NPS_ERROR_NO_T +_hal_tau_pkt_flushRxQueue( + const UI32_T unit, + HAL_TAU_PKT_SW_QUEUE_T *ptr_que) +{ + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_gpd_knl = NULL; + NPS_ERROR_NO_T rc; + + while (1) + { + rc = _hal_tau_pkt_deQueue(ptr_que, (void **)&ptr_sw_gpd_knl); + if (NPS_E_OK == rc) + { + _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_gpd_knl, TRUE); + } + else + { + break; + } + } + + return (NPS_E_OK); +} + /* FUNCTION NAME: _hal_tau_pkt_schedRxDeQueue * PURPOSE: * To dequeue the packets based on the configured algorithm. @@ -2335,33 +2563,14 @@ _hal_tau_pkt_schedRxDeQueue( UI32_T buf_len = 0; NPS_ERROR_NO_T rc = NPS_E_OK; - /* get queue and count */ - for (idx = 0; idx < HAL_TAU_PKT_RX_QUEUE_NUM; idx++) - { - /* to gurantee the opportunity where each queue can be handler */ - queue = ((ptr_rx_cb->deque_idx + idx) % HAL_TAU_PKT_RX_QUEUE_NUM); - _hal_tau_pkt_getQueueCount(&ptr_rx_cb->sw_queue[queue], &que_cnt); - if (que_cnt > 0) - { - ptr_rx_cb->deque_idx = ((queue + 1) % HAL_TAU_PKT_RX_QUEUE_NUM); - break; - } - } - - /* If all of the queues are empty, wait rxTask event */ - if (0 == que_cnt) + /* normal process */ + if (TRUE == ptr_rx_cb->running) { - osal_waitEvent(&ptr_rx_cb->sync_sema); - if (FALSE == ptr_rx_cb->running) - { - return (NPS_E_OTHERS); /* deinit */ - } - - ptr_rx_cb->cnt.wait_event++; - - /* re-get queue and count */ - for (queue = 0; queue < HAL_TAU_PKT_RX_QUEUE_NUM; queue++) + /* get queue and count */ + for (idx = 0; idx < HAL_TAU_PKT_RX_QUEUE_NUM; idx++) { + /* to gurantee the opportunity where each queue can be handler */ + queue = ((ptr_rx_cb->deque_idx + idx) % HAL_TAU_PKT_RX_QUEUE_NUM); _hal_tau_pkt_getQueueCount(&ptr_rx_cb->sw_queue[queue], &que_cnt); if (que_cnt > 0) { @@ -2369,68 +2578,87 @@ _hal_tau_pkt_schedRxDeQueue( break; } } - } - /* deque */ - if ((que_cnt > 0) && (queue < HAL_TAU_PKT_RX_QUEUE_NUM)) - { - rc = _hal_tau_pkt_deQueue(&ptr_rx_cb->sw_queue[queue], (void **)&ptr_sw_gpd_knl); - if (NPS_E_OK == rc) + /* If all of the queues are empty, wait rxTask event */ + if (0 == que_cnt) { - ptr_rx_cb->cnt.channel[queue].deque_ok++; - ptr_sw_first_gpd_knl = ptr_sw_gpd_knl; + osal_waitEvent(&ptr_rx_cb->sync_sema); - osal_io_copyFromUser(&ioctl_data, ptr_cookie, sizeof(HAL_TAU_PKT_IOCTL_RX_COOKIE_T)); + ptr_rx_cb->cnt.wait_event++; - while (NULL != ptr_sw_gpd_knl) + /* re-get queue and count */ + for (queue = 0; queue < HAL_TAU_PKT_RX_QUEUE_NUM; queue++) { - /* get the IOCTL GPD from user */ - osal_io_copyFromUser(&ioctl_gpd, - ((void *)((NPS_HUGE_T)ioctl_data.ioctl_gpd_addr)) - + gpd_idx*sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T), - sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T)); + _hal_tau_pkt_getQueueCount(&ptr_rx_cb->sw_queue[queue], &que_cnt); + if (que_cnt > 0) + { + ptr_rx_cb->deque_idx = ((queue + 1) % HAL_TAU_PKT_RX_QUEUE_NUM); + break; + } + } + } - /* get knl buf addr */ - ptr_rx_gpd = &ptr_sw_gpd_knl->rx_gpd; - phy_addr = NPS_ADDR_32_TO_64(ptr_rx_gpd->data_buf_addr_hi, ptr_rx_gpd->data_buf_addr_lo); + /* deque */ + if ((que_cnt > 0) && (queue < HAL_TAU_PKT_RX_QUEUE_NUM)) + { + rc = _hal_tau_pkt_deQueue(&ptr_rx_cb->sw_queue[queue], (void **)&ptr_sw_gpd_knl); + if (NPS_E_OK == rc) + { + ptr_rx_cb->cnt.channel[queue].deque_ok++; + ptr_sw_first_gpd_knl = ptr_sw_gpd_knl; - ptr_virt_addr = ptr_sw_gpd_knl->ptr_cookie; - osal_skb_unmapDma(phy_addr, ((struct sk_buff *)ptr_virt_addr)->len, DMA_FROM_DEVICE); + osal_io_copyFromUser(&ioctl_data, ptr_cookie, sizeof(HAL_TAU_PKT_IOCTL_RX_COOKIE_T)); - buf_len = (HAL_TAU_PKT_CH_LAST_GPD == ptr_rx_gpd->ch)? - ptr_rx_gpd->cnsm_buf_len : ptr_rx_gpd->avbl_buf_len; + while (NULL != ptr_sw_gpd_knl) + { + /* get the IOCTL GPD from user */ + osal_io_copyFromUser(&ioctl_gpd, + ((void *)((NPS_HUGE_T)ioctl_data.ioctl_gpd_addr)) + + gpd_idx*sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T), + sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T)); + + /* get knl buf addr */ + ptr_rx_gpd = &ptr_sw_gpd_knl->rx_gpd; + phy_addr = NPS_ADDR_32_TO_64(ptr_rx_gpd->data_buf_addr_hi, ptr_rx_gpd->data_buf_addr_lo); + + ptr_virt_addr = ptr_sw_gpd_knl->ptr_cookie; + osal_skb_unmapDma(phy_addr, ((struct sk_buff *)ptr_virt_addr)->len, DMA_FROM_DEVICE); + + buf_len = (HAL_TAU_PKT_CH_LAST_GPD == ptr_rx_gpd->ch)? + ptr_rx_gpd->cnsm_buf_len : ptr_rx_gpd->avbl_buf_len; + + /* overwrite whole rx_gpd to user + * the user should re-assign the correct value to data_buf_addr_hi, data_buf_addr_low + * after this IOCTL returns + */ + osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.hw_gpd_addr), + &ptr_sw_gpd_knl->rx_gpd, + sizeof(HAL_TAU_PKT_RX_GPD_T)); + /* copy buf */ + /* DMA buf address allocated by the user is store in ptr_ioctl_data->gpd[idx].cookie */ + osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.dma_buf_addr), + ((struct sk_buff *)ptr_virt_addr)->data, buf_len); + ptr_sw_gpd_knl->ptr_cookie = ptr_virt_addr; + + /* next */ + ptr_sw_gpd_knl = ptr_sw_gpd_knl->ptr_next; + gpd_idx++; + } - /* overwrite whole rx_gpd to user - * the user should re-assign the correct value to data_buf_addr_hi, data_buf_addr_low - * after this IOCTL returns - */ - osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.hw_gpd_addr), - &ptr_sw_gpd_knl->rx_gpd, - sizeof(HAL_TAU_PKT_RX_GPD_T)); - /* copy buf */ - /* DMA buf address allocated by the user is store in ptr_ioctl_data->gpd[idx].cookie */ - osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.dma_buf_addr), - ((struct sk_buff *)ptr_virt_addr)->data, buf_len); - ptr_sw_gpd_knl->ptr_cookie = ptr_virt_addr; - - /* next */ - ptr_sw_gpd_knl = ptr_sw_gpd_knl->ptr_next; - gpd_idx++; + /* Must free kernel sw_gpd */ + _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd_knl, TRUE); + } + else + { + ptr_rx_cb->cnt.channel[queue].deque_fail++; } - - /* Must free kernel sw_gpd */ - _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd_knl, TRUE); } else { - ptr_rx_cb->cnt.channel[queue].deque_fail++; + /* it means that all queue's are flush -> rx stop flow */ + rc = NPS_E_OTHERS; } } - else - { - /* It may happen at last gpd, return error and do not invoke callback. */ - rc = NPS_E_OTHERS; - } return (rc); } @@ -2547,6 +2775,26 @@ _hal_tau_pkt_suspendAllIntf( return (NPS_E_OK); } +static NPS_ERROR_NO_T +_hal_tau_pkt_stopAllIntf( + const UI32_T unit) +{ + struct net_device *ptr_net_dev = NULL; + UI32_T port; + + /* Unregister net devices by id */ + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); + if (NULL != ptr_net_dev) + { + netif_tx_disable(ptr_net_dev); + } + } + + return (NPS_E_OK); +} + /* FUNCTION NAME: hal_tau_pkt_sendGpd * PURPOSE: * To perform the packet transmission form CPU to the switch. @@ -2572,85 +2820,94 @@ hal_tau_pkt_sendGpd( HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); volatile HAL_TAU_PKT_TX_GPD_T *ptr_tx_gpd = NULL; HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_first_gpd = ptr_sw_gpd; - UI32_T used_idx = 0; UI32_T used_gpd_num = ptr_sw_gpd->gpd_num; NPS_IRQ_FLAGS_T irq_flags; + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); - osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); - - /* If not PDMA error */ - if (FALSE == ptr_tx_pdma->err_flag) + if (0 != (ptr_cb->init_flag & HAL_TAU_PKT_INIT_TASK)) { - /* Make Sure GPD is enough */ - if (ptr_tx_pdma->free_gpd_num >= used_gpd_num) + osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); + + /* If not PDMA error */ + if (FALSE == ptr_tx_pdma->err_flag) { - used_idx = ptr_tx_pdma->used_idx; - while (NULL != ptr_sw_gpd) + /* Make Sure GPD is enough */ + if (ptr_tx_pdma->free_gpd_num >= used_gpd_num) { - ptr_tx_gpd = HAL_TAU_PKT_GET_TX_GPD_PTR(unit, channel, used_idx); - osal_dma_invalidateCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - - if (HAL_TAU_PKT_HWO_HW_OWN == ptr_tx_gpd->hwo) + used_idx = ptr_tx_pdma->used_idx; + while (NULL != ptr_sw_gpd) { - HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), - "u=%u, txch=%u, free gpd idx out-of-sync\n", - unit, channel); - rc = NPS_E_TABLE_FULL; - break; - } + ptr_tx_gpd = HAL_TAU_PKT_GET_TX_GPD_PTR(unit, channel, used_idx); + osal_dma_invalidateCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - /* Fill in HW-GPD Ring */ - osal_memcpy((void *)ptr_tx_gpd, &ptr_sw_gpd->tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - osal_dma_flushCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + if (HAL_TAU_PKT_HWO_HW_OWN == ptr_tx_gpd->hwo) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, free gpd idx out-of-sync\n", + unit, channel); + rc = NPS_E_TABLE_FULL; + break; + } - /* next */ - used_idx++; - used_idx %= ptr_tx_pdma->gpd_num; - ptr_sw_gpd = ptr_sw_gpd->ptr_next; - } + /* Fill in HW-GPD Ring */ + osal_memcpy((void *)ptr_tx_gpd, &ptr_sw_gpd->tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + osal_dma_flushCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) - { - /* Fill 1st GPD in SW-GPD Ring */ - ptr_tx_pdma->pptr_sw_gpd_ring[ptr_tx_pdma->used_idx] = ptr_sw_first_gpd; - } + /* next */ + used_idx++; + used_idx %= ptr_tx_pdma->gpd_num; + ptr_sw_gpd = ptr_sw_gpd->ptr_next; + } - /* update Tx PDMA */ - ptr_tx_pdma->used_idx = used_idx; - ptr_tx_pdma->used_gpd_num += used_gpd_num; - ptr_tx_pdma->free_gpd_num -= used_gpd_num; + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + /* Fill 1st GPD in SW-GPD Ring */ + ptr_tx_pdma->pptr_sw_gpd_ring[ptr_tx_pdma->used_idx] = ptr_sw_first_gpd; + } + + /* update Tx PDMA */ + ptr_tx_pdma->used_idx = used_idx; + ptr_tx_pdma->used_gpd_num += used_gpd_num; + ptr_tx_pdma->free_gpd_num -= used_gpd_num; - _hal_tau_pkt_resumeTxChannelReg(unit, channel, used_gpd_num); - ptr_tx_cb->cnt.channel[channel].send_ok++; + _hal_tau_pkt_resumeTxChannelReg(unit, channel, used_gpd_num); + ptr_tx_cb->cnt.channel[channel].send_ok++; - _hal_tau_pkt_waitTxDone(unit, channel, ptr_sw_first_gpd); + _hal_tau_pkt_waitTxDone(unit, channel, ptr_sw_first_gpd); - /* reserve 1 packet buffer for each port in case that the suspension is too late */ -#define HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW (HAL_TAU_PORT_NUM) - if (ptr_tx_pdma->free_gpd_num < HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW) + /* reserve 1 packet buffer for each port in case that the suspension is too late */ +#define HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW (HAL_PORT_NUM) + if (ptr_tx_pdma->free_gpd_num < HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, + "u=%u, txch=%u, tx avbl gpd < %d, suspend all netdev\n", + unit, channel, HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW); + _hal_tau_pkt_suspendAllIntf(unit); + } + } + else { - HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, - "u=%u, txch=%u, tx avbl gpd < %d, suspend all netdev\n", - unit, channel, HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW); - _hal_tau_pkt_suspendAllIntf(unit); + rc = NPS_E_TABLE_FULL; } } else { - rc = NPS_E_TABLE_FULL; + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma hw err\n", + unit, channel); + rc = NPS_E_OTHERS; } + + osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); } else { - HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), - "u=%u, txch=%u, pdma hw err\n", - unit, channel); + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "Tx failed, task already deinit\n"); rc = NPS_E_OTHERS; } - osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); - return (rc); } @@ -2662,6 +2919,7 @@ _hal_tau_pkt_rxStop( { NPS_ERROR_NO_T rc = NPS_E_OK; HAL_TAU_PKT_RX_CHANNEL_T channel = 0; + UI32_T idx; HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = NULL; @@ -2695,6 +2953,14 @@ _hal_tau_pkt_rxStop( osal_giveSemaphore(&ptr_rx_pdma->sema); } + /* flush packets in all queues since Rx task may be blocked in user space + * in this case it won't do ioctl to kernel to handle remaining packets + */ + for (idx = 0; idx < HAL_TAU_PKT_RX_QUEUE_NUM; idx++) + { + _hal_tau_pkt_flushRxQueue(unit, &ptr_rx_cb->sw_queue[idx]); + } + /* Return user thread */ ptr_rx_cb->running = FALSE; ptr_cb->init_flag &= (~HAL_TAU_PKT_INIT_RX_START); @@ -2848,6 +3114,12 @@ hal_tau_pkt_deinitTask( HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); UI32_T channel = 0; + /* to prevent net intf from Tx packet */ + ptr_tx_cb->net_tx_allowed = FALSE; + + /* In case that some undestroyed net intf keep Tx after task deinit */ + _hal_tau_pkt_stopAllIntf(unit); + if (0 == (ptr_cb->init_flag & HAL_TAU_PKT_INIT_TASK)) { HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), @@ -2926,13 +3198,10 @@ _hal_tau_pkt_deinitTxPdma( { HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); - NPS_IRQ_FLAGS_T irg_flags; _hal_tau_pkt_stopTxChannelReg(unit, channel); /* Free DMA and flush queue */ - osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); - osal_dma_free(ptr_tx_pdma->ptr_gpd_start_addr); if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) @@ -2945,8 +3214,6 @@ _hal_tau_pkt_deinitTxPdma( osal_destroySemaphore(&ptr_tx_pdma->sync_intr_sema); } - osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); - osal_destroyIsrLock(&ptr_tx_pdma->ring_lock); return (NPS_E_OK); @@ -3919,6 +4186,7 @@ _hal_tau_pkt_handleRxDoneTask( ptr_sw_gpd->ptr_next = NULL; ptr_sw_first_gpd->rx_complete = FALSE; _hal_tau_pkt_rxEnQueue(unit, channel, ptr_sw_first_gpd); + ptr_sw_first_gpd = NULL; } /* do error recover */ @@ -3956,7 +4224,7 @@ _hal_tau_pkt_handleRxDoneTask( { ptr_rx_cb->cnt.no_memory++; HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), - "u=%u, rxch=%u, alloc 1st sw gpd failed, size=%d\n", + "u=%u, rxch=%u, alloc 1st sw gpd failed, size=%zu\n", unit, channel, sizeof(HAL_TAU_PKT_RX_SW_GPD_T)); break; } @@ -3973,7 +4241,7 @@ _hal_tau_pkt_handleRxDoneTask( { ptr_rx_cb->cnt.no_memory++; HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), - "u=%u, rxch=%u, alloc mid sw gpd failed, size=%d\n", + "u=%u, rxch=%u, alloc mid sw gpd failed, size=%zu\n", unit, channel, sizeof(HAL_TAU_PKT_RX_SW_GPD_T)); break; } @@ -4003,6 +4271,7 @@ _hal_tau_pkt_handleRxDoneTask( ptr_sw_gpd->ptr_next = NULL; ptr_sw_first_gpd->rx_complete = TRUE; _hal_tau_pkt_rxEnQueue(unit, channel, ptr_sw_first_gpd); + ptr_sw_first_gpd = NULL; /* To rebuild the SW GPD link list */ first = TRUE; @@ -4085,8 +4354,8 @@ hal_tau_pkt_initTask( } /* Init handleErrorTask */ - rc = osal_createThread("ERROR", HAL_TAU_PKT_ERROR_ISR_STACK_SIZE, - HAL_TAU_PKT_ERROR_ISR_THREAD_PRI, _hal_tau_pkt_handleErrorTask, + rc = osal_createThread("ERROR", HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_STACK, + HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_PRI, _hal_tau_pkt_handleErrorTask, (void *)((NPS_HUGE_T)unit), &ptr_cb->err_task_id); /* Init handleTxDoneTask */ @@ -4095,8 +4364,8 @@ hal_tau_pkt_initTask( ptr_tx_cb->isr_task_cookie[channel].unit = unit; ptr_tx_cb->isr_task_cookie[channel].channel = channel; - rc = osal_createThread("TX_ISR", HAL_TAU_PKT_TX_ISR_STACK_SIZE, - HAL_TAU_PKT_TX_ISR_THREAD_PRI, _hal_tau_pkt_handleTxDoneTask, + rc = osal_createThread("TX_ISR", HAL_DFLT_CFG_PKT_TX_ISR_THREAD_STACK, + HAL_DFLT_CFG_PKT_TX_ISR_THREAD_PRI, _hal_tau_pkt_handleTxDoneTask, (void *)&ptr_tx_cb->isr_task_cookie[channel], &ptr_tx_cb->isr_task_id[channel]); } @@ -4107,8 +4376,8 @@ hal_tau_pkt_initTask( ptr_rx_cb->isr_task_cookie[channel].unit = unit; ptr_rx_cb->isr_task_cookie[channel].channel = channel; - rc = osal_createThread("RX_ISR", HAL_TAU_PKT_RX_ISR_STACK_SIZE, - HAL_TAU_PKT_RX_ISR_THREAD_PRI, _hal_tau_pkt_handleRxDoneTask, + rc = osal_createThread("RX_ISR", HAL_DFLT_CFG_PKT_RX_ISR_THREAD_STACK, + HAL_DFLT_CFG_PKT_RX_ISR_THREAD_PRI, _hal_tau_pkt_handleRxDoneTask, (void *)&ptr_rx_cb->isr_task_cookie[channel], &ptr_rx_cb->isr_task_id[channel]); } @@ -4124,6 +4393,13 @@ hal_tau_pkt_initTask( HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, pkt task init done, init flag=0x%x\n", unit, ptr_cb->init_flag); + /* For some specail case in warmboot, the netifs are not destroyed during sdk deinit + * but stopped, here we need to resume them with the original carrier status + */ + _hal_tau_pkt_resumeAllIntf(unit); + + ptr_tx_cb->net_tx_allowed = TRUE; + return (rc); } @@ -4165,8 +4441,8 @@ _hal_tau_pkt_initTxPdma( ptr_tx_pdma->used_idx = 0; ptr_tx_pdma->free_idx = 0; ptr_tx_pdma->used_gpd_num = 0; - ptr_tx_pdma->free_gpd_num = HAL_TAU_PKT_PDMA_TX_GPD_NUM; - ptr_tx_pdma->gpd_num = HAL_TAU_PKT_PDMA_TX_GPD_NUM; + ptr_tx_pdma->free_gpd_num = HAL_DFLT_CFG_PKT_TX_GPD_NUM; + ptr_tx_pdma->gpd_num = HAL_DFLT_CFG_PKT_TX_GPD_NUM; /* Prepare the HW-GPD ring */ ptr_tx_pdma->ptr_gpd_start_addr = (HAL_TAU_PKT_TX_GPD_T *)osal_dma_alloc( @@ -4263,7 +4539,7 @@ _hal_tau_pkt_initRxPdma( /* Reset Rx PDMA */ osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); ptr_rx_pdma->cur_idx = 0; - ptr_rx_pdma->gpd_num = HAL_TAU_PKT_PDMA_RX_GPD_NUM; + ptr_rx_pdma->gpd_num = HAL_DFLT_CFG_PKT_RX_GPD_NUM; /* Prepare the HW-GPD ring */ ptr_rx_pdma->ptr_gpd_start_addr = (HAL_TAU_PKT_RX_GPD_T *)osal_dma_alloc( @@ -4374,7 +4650,7 @@ _hal_tau_pkt_initPktTxCb( osal_createEvent("TX_SYNC", &ptr_tx_cb->sync_sema); /* Initialize Tx GPD-queue (of first SW-GPD) from handleTxDoneTask to txTask */ - ptr_tx_cb->sw_queue.len = HAL_TAU_PKT_TX_QUEUE_LEN; + ptr_tx_cb->sw_queue.len = HAL_DFLT_CFG_PKT_TX_QUEUE_LEN; ptr_tx_cb->sw_queue.weight = 0; osal_createSemaphore("TX_QUE", NPS_SEMAPHORE_BINARY, &ptr_tx_cb->sw_queue.sema); @@ -4422,7 +4698,7 @@ _hal_tau_pkt_initPktRxCb( osal_memset(ptr_rx_cb, 0x0, sizeof(HAL_TAU_PKT_RX_CB_T)); - ptr_rx_cb->sched_mode = HAL_TAU_PKT_RX_SCHED_MODE; + ptr_rx_cb->sched_mode = HAL_DFLT_CFG_PKT_RX_SCHED_MODE; /* Sync semaphore to signal rxTask */ osal_createEvent("RX_SYNC", &ptr_rx_cb->sync_sema); @@ -4430,8 +4706,8 @@ _hal_tau_pkt_initPktRxCb( /* Initialize Rx GPD-queue (of first SW-GPD) from handleRxDoneTask to rxTask */ for (queue = 0; ((queue < HAL_TAU_PKT_RX_QUEUE_NUM) && (NPS_E_OK == rc)); queue++) { - ptr_rx_cb->sw_queue[queue].len = HAL_TAU_PKT_RX_QUEUE_LEN; - ptr_rx_cb->sw_queue[queue].weight = HAL_TAU_PKT_RX_QUEUE_WEIGHT; + ptr_rx_cb->sw_queue[queue].len = HAL_DFLT_CFG_PKT_RX_QUEUE_LEN; + ptr_rx_cb->sw_queue[queue].weight = HAL_DFLT_CFG_PKT_RX_QUEUE_WEIGHT; osal_createSemaphore("RX_QUE", NPS_SEMAPHORE_BINARY, &ptr_rx_cb->sw_queue[queue].sema); osal_que_create(&ptr_rx_cb->sw_queue[queue].que_id, ptr_rx_cb->sw_queue[queue].len); @@ -4530,12 +4806,12 @@ _hal_tau_pkt_resetIosCreditCfg( osal_mdc_readPciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_CREDIT_CFG), &credit_cfg, sizeof(credit_cfg)); - credit_cfg |= (0x1 << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); + credit_cfg |= (0x1UL << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_CREDIT_CFG), &credit_cfg, sizeof(UI32_T)); - credit_cfg &= ~(0x1 << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); + credit_cfg &= ~(0x1UL << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_CREDIT_CFG), &credit_cfg, sizeof(UI32_T)); @@ -4544,27 +4820,6 @@ _hal_tau_pkt_resetIosCreditCfg( return (NPS_E_OK); } -static NPS_ERROR_NO_T -_hal_tau_pkt_stopAllIntf( - const UI32_T unit) -{ - struct net_device *ptr_net_dev = NULL; - UI32_T port; - - /* Unregister net devices by id */ - for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) - { - ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); - if (NULL != ptr_net_dev) - { - netif_carrier_off(ptr_net_dev); - netif_stop_queue(ptr_net_dev); - } - } - - return (NPS_E_OK); -} - static NPS_ERROR_NO_T _hal_tau_pkt_addProfToList( HAL_TAU_PKT_NETIF_PROFILE_T *ptr_new_profile, @@ -4668,8 +4923,8 @@ _hal_tau_pkt_addProfToAllIntf( for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) { ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); - /* Shall we check if the interface is ever created in the port?? */ - //if (NULL != ptr_port_db->ptr_net_dev) + /* Shall we check if the interface is ever created on the port?? */ + /* if (NULL != ptr_port_db->ptr_net_dev) */ if (1) { _hal_tau_pkt_addProfToList(ptr_new_profile, &ptr_port_db->ptr_profile_list); @@ -4759,8 +5014,8 @@ _hal_tau_pkt_delProfFromAllIntfById( for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) { ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); - /* Shall we check if the interface is ever created in the port?? */ - //if (NULL != ptr_port_db->ptr_net_dev) + /* Shall we check if the interface is ever created on the port?? */ + /* if (NULL != ptr_port_db->ptr_net_dev) */ if (1) { _hal_tau_pkt_delProfFromListById(id, &ptr_port_db->ptr_profile_list); @@ -4824,7 +5079,7 @@ _hal_tau_pkt_destroyAllIntf( ptr_port_db->meta.port, ptr_port_db->meta.port); - netif_stop_queue(ptr_port_db->ptr_net_dev); + netif_tx_disable(ptr_port_db->ptr_net_dev); unregister_netdev(ptr_port_db->ptr_net_dev); free_netdev(ptr_port_db->ptr_net_dev); @@ -5072,7 +5327,7 @@ hal_tau_pkt_prepareGpd( */ ptr_sw_gpd->tx_gpd.itmh_eth.dst_idx = port; - /* [Taurus] we should set all-1 for the following fields to skip some tm-logic */ + /* [NP8360] we should set all-1 for the following fields to skip some tm-logic */ /* TM header */ ptr_sw_gpd->tx_gpd.itmh_eth.src_idx = 0x7fff; @@ -5083,8 +5338,8 @@ hal_tau_pkt_prepareGpd( ptr_sw_gpd->tx_gpd.itmh_eth.nvo3_src_supp_tag_w1 = 0xf; /* PP header */ - ptr_sw_gpd->tx_gpd.pph_l2.nvo3_encap_idx = HAL_TAU_INVALID_NVO3_ENCAP_IDX; - ptr_sw_gpd->tx_gpd.pph_l2.nvo3_adj_idx = HAL_TAU_INVALID_NVO3_ADJ_IDX; + ptr_sw_gpd->tx_gpd.pph_l2.nvo3_encap_idx = HAL_INVALID_NVO3_ENCAP_IDX; + ptr_sw_gpd->tx_gpd.pph_l2.nvo3_adj_idx = HAL_INVALID_NVO3_ADJ_IDX; return (NPS_E_OK); } @@ -5157,6 +5412,7 @@ _hal_tau_pkt_net_dev_tx( struct net_device *ptr_net_dev) { struct net_device_priv *ptr_priv = netdev_priv(ptr_net_dev); + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb; /* chip meta */ unsigned int unit; unsigned int channel = 0; @@ -5180,6 +5436,17 @@ _hal_tau_pkt_net_dev_tx( unit = ptr_priv->unit; + ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + /* for warm de-init procedure, if any net intf not destroyed, it is possible + * that kernel still has packets to send causing segmentation fault + */ + if (FALSE == ptr_tx_cb->net_tx_allowed) { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, "net tx during sdk de-init\n"); + ptr_priv->stats.tx_dropped++; + osal_skb_free(ptr_skb); + return NETDEV_TX_OK; + } + /* pad to 60-bytes if skb_len < 60, see: eth_skb_pad(skb) */ if (ptr_skb->len < ETH_ZLEN) { @@ -5245,8 +5512,6 @@ _hal_tau_pkt_net_dev_tx( osal_skb_unmapDma(phy_addr, ptr_skb->len, DMA_TO_DEVICE); osal_skb_free(ptr_skb); osal_free(ptr_sw_gpd); - - return NETDEV_TX_OK; } } } @@ -5374,34 +5639,6 @@ _hal_tau_pkt_setup( memset(&ptr_priv->stats, 0, sizeof(struct net_device_stats)); } -static void -_hal_tau_pkt_lockRxChannelAll( - const UI32_T unit) -{ - UI32_T rch; - HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; - - for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) - { - ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); - osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); - } -} - -static void -_hal_tau_pkt_unlockRxChannelAll( - const UI32_T unit) -{ - UI32_T rch; - HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; - - for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) - { - ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); - osal_giveSemaphore(&ptr_rx_pdma->sema); - } -} - static NPS_ERROR_NO_T _hal_tau_pkt_createIntf( const UI32_T unit, @@ -5435,7 +5672,7 @@ _hal_tau_pkt_createIntf( #if defined(HAL_TAU_PKT_FORCR_REMOVE_DUPLICATE_NETDEV) ptr_net_dev->operstate = IF_OPER_DOWN; netif_carrier_off(ptr_net_dev); - netif_stop_queue(ptr_net_dev); + netif_tx_disable(ptr_net_dev); unregister_netdev(ptr_net_dev); free_netdev(ptr_net_dev); #endif @@ -5466,6 +5703,8 @@ _hal_tau_pkt_createIntf( register_netdev(ptr_net_dev); + netif_carrier_off(ptr_net_dev); + net_intf.id = net_intf.port; /* Currently, id is 1-to-1 mapped to port */ osal_memcpy(&ptr_port_db->meta, &net_intf, sizeof(HAL_TAU_PKT_NETIF_INTF_T)); @@ -5518,10 +5757,11 @@ _hal_tau_pkt_destroyIntf( "u=%u, find intf %s (id=%d) on phy port=%d, destroy done\n", unit, ptr_port_db->meta.name, + ptr_port_db->meta.id, ptr_port_db->meta.port); netif_carrier_off(ptr_port_db->ptr_net_dev); - netif_stop_queue(ptr_port_db->ptr_net_dev); + netif_tx_disable(ptr_port_db->ptr_net_dev); unregister_netdev(ptr_port_db->ptr_net_dev); free_netdev(ptr_port_db->ptr_net_dev); @@ -5553,7 +5793,7 @@ _hal_tau_pkt_traverseProfList( ptr_curr_node = ptr_prof_list; - HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "intf id=%d, prof list=\n", intf_id); + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "intf id=%d, prof list=", intf_id); while(NULL != ptr_curr_node) { HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "%s (%d) => ", @@ -6043,6 +6283,24 @@ _hal_tau_pkt_dev_ioctl( ret = hal_tau_pkt_setPortAttr(unit, (HAL_TAU_PKT_IOCTL_PORT_COOKIE_T *)arg); break; +#if defined(NETIF_EN_NETLINK) + case HAL_TAU_PKT_IOCTL_TYPE_NL_SET_INTF_PROPERTY: + ret = _hal_tau_pkt_setIntfProperty(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_GET_INTF_PROPERTY: + ret = _hal_tau_pkt_getIntfProperty(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_CREATE_NETLINK: + ret = _hal_tau_pkt_createNetlink(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_DESTROY_NETLINK: + ret = _hal_tau_pkt_destroyNetlink(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_GET_NETLINK: + ret = _hal_tau_pkt_getNetlink(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; +#endif + default: ret = -1; break; @@ -6102,6 +6360,10 @@ _hal_tau_pkt_init(void) osal_memset(_hal_tau_pkt_drv_cb, 0x0, NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM*sizeof(HAL_TAU_PKT_DRV_CB_T)); +#if defined(NETIF_EN_NETLINK) + netif_nl_init(); +#endif + return (0); } @@ -6110,16 +6372,16 @@ _hal_tau_pkt_exit(void) { UI32_T unit = 0; - /* 1st. Stop Rx HW DMA and free all the DMA buffer hooked on the ring */ + /* 1st. Stop all netdev (if any) to prevent kernel from Tx new packets */ + _hal_tau_pkt_stopAllIntf(unit); + + /* 2nd. Stop Rx HW DMA and free all the DMA buffer hooked on the ring */ _hal_tau_pkt_rxStop(unit); - /* 2nd. Need to wait Rx done task process all the availavle packets on GPD ring */ + /* 3rd. Need to wait Rx done task process all the availavle packets on GPD ring */ #define HAL_TAU_PKT_MODULE_EXIT_HOLD_TIME_US (1000000) osal_sleepThread(HAL_TAU_PKT_MODULE_EXIT_HOLD_TIME_US); - /* 3rd. Stop all netdev (if any) to prevent kernel from Tx new packets */ - _hal_tau_pkt_stopAllIntf(unit); - /* 4th. Stop all the internal tasks (if any) */ hal_tau_pkt_deinitTask(unit); @@ -6139,9 +6401,9 @@ _hal_tau_pkt_exit(void) module_init(_hal_tau_pkt_init); module_exit(_hal_tau_pkt_exit); -module_param(dbg_flag, uint, S_IRUGO); -MODULE_PARM_DESC(dbg_flag, "bit0:Error, bit1:Tx, bit2:Rx, bit3:Intf, bit4:Profile"); +module_param(ext_dbg_flag, uint, S_IRUGO); +MODULE_PARM_DESC(ext_dbg_flag, "bit0:Error, bit1:Tx, bit2:Rx, bit3:Intf, bit4:Profile"); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Nephos"); +MODULE_AUTHOR("MediaTek"); MODULE_DESCRIPTION("NETIF Kernel Module"); diff --git a/platform/nephos/nephos-modules/modules/src/inc/aml.h b/platform/nephos/nephos-modules/modules/src/inc/aml.h index 658aa6e56f46..682eaa5ea318 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/aml.h +++ b/platform/nephos/nephos-modules/modules/src/inc/aml.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h b/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h index edd582adc197..e8d491358c77 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h +++ b/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h b/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h index 96a8cf6441f0..3605323a5955 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h +++ b/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -104,15 +104,15 @@ typedef enum /* hal_tau_const.h */ -#define HAL_TAU_PORT_NUM (128) -#define HAL_TAU_EXCPT_CPU_NUM (256) -#define HAL_TAU_INVALID_NVO3_ENCAP_IDX (0x3FFF) -#define HAL_TAU_INVALID_NVO3_ADJ_IDX (0xFF) -#define HAL_TAU_EXCPT_CPU_BASE_ID (28 * 1024) -#define HAL_TAU_EXCPT_CPU_NON_L3_MIN (0) -#define HAL_TAU_EXCPT_CPU_NON_L3_MAX (HAL_TAU_EXCPT_CPU_NON_L3_MIN + HAL_TAU_EXCPT_CPU_NUM - 1) -#define HAL_TAU_EXCPT_CPU_L3_MIN (HAL_TAU_EXCPT_CPU_NON_L3_MIN + HAL_TAU_EXCPT_CPU_NUM) -#define HAL_TAU_EXCPT_CPU_L3_MAX (HAL_TAU_EXCPT_CPU_L3_MIN + HAL_TAU_EXCPT_CPU_NUM - 1) +#define HAL_PORT_NUM (128) +#define HAL_EXCPT_CPU_NUM (256) +#define HAL_INVALID_NVO3_ENCAP_IDX (0x3FFF) +#define HAL_INVALID_NVO3_ADJ_IDX (0xFF) +#define HAL_EXCPT_CPU_BASE_ID (28 * 1024) +#define HAL_EXCPT_CPU_NON_L3_MIN (0) +#define HAL_EXCPT_CPU_NON_L3_MAX (HAL_EXCPT_CPU_NON_L3_MIN + HAL_EXCPT_CPU_NUM - 1) +#define HAL_EXCPT_CPU_L3_MIN (HAL_EXCPT_CPU_NON_L3_MIN + HAL_EXCPT_CPU_NUM) +#define HAL_EXCPT_CPU_L3_MAX (HAL_EXCPT_CPU_L3_MIN + HAL_EXCPT_CPU_NUM - 1) /* hal_tau_pkt_rsrc.h */ #define HAL_TAU_PKT_IPP_EXCPT_LAST (256) @@ -238,7 +238,7 @@ typedef struct HAL_TAU_PKT_IPP_COPY2CPU_BITMAP_T ipp_copy2cpu_bitmap; HAL_TAU_PKT_EPP_COPY2CPU_BITMAP_T epp_copy2cpu_bitmap; -} HAL_TAU_PKT_RX_REASON_BITMAP_T; +} HAL_PKT_RX_REASON_BITMAP_T; /* hal_tau_pkt.h */ @@ -246,23 +246,23 @@ typedef struct /* NAMING DECLARATIONS */ /* PKT related configurable parameters */ -#define HAL_TAU_PKT_RX_FREE_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_RX_FREE_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_RX_FREE_STACK_SIZE (64 * 1024) +#define HAL_DFLT_CFG_PKT_RX_FREE_THREAD_PRI (80) -#define HAL_TAU_PKT_RX_ISR_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_RX_ISR_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_RX_ISR_THREAD_STACK (64 * 1024) +#define HAL_DFLT_CFG_PKT_RX_ISR_THREAD_PRI (80) -#define HAL_TAU_PKT_TX_FREE_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_TX_FREE_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_TX_FREE_STACK_SIZE (64 * 1024) +#define HAL_DFLT_CFG_PKT_TX_FREE_THREAD_PRI (80) -#define HAL_TAU_PKT_TX_ISR_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_TX_ISR_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_TX_ISR_THREAD_STACK (64 * 1024) +#define HAL_DFLT_CFG_PKT_TX_ISR_THREAD_PRI (80) -#define HAL_TAU_PKT_TX_NET_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_TX_NET_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_TX_NET_STACK_SIZE (64 * 1024) +#define HAL_DFLT_CFG_PKT_TX_NET_THREAD_PRI (80) -#define HAL_TAU_PKT_ERROR_ISR_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_ERROR_ISR_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_STACK (64 * 1024) +#define HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_PRI (80) /* PKT definitions */ #define HAL_TAU_PKT_TX_MAX_LEN (9216) @@ -300,29 +300,29 @@ typedef struct /* PDMA Definitions */ #define HAL_TAU_PKT_PDMA_MAX_GPD_PER_PKT (10) /* <= 256 */ -#define HAL_TAU_PKT_PDMA_TX_GPD_NUM (1024) /* <= 65535 */ -#define HAL_TAU_PKT_PDMA_RX_GPD_NUM (1024) /* <= 65535 */ +#define HAL_DFLT_CFG_PKT_TX_GPD_NUM (1024) /* <= 65535 */ +#define HAL_DFLT_CFG_PKT_RX_GPD_NUM (1024) /* <= 65535 */ #define HAL_TAU_PKT_PDMA_TX_INTR_TIMEOUT (10 * 1000) /* us */ #define HAL_TAU_PKT_PDMA_TX_POLL_MAX_LOOP (10 * 1000) /* int */ /* Mode */ #define HAL_TAU_PKT_TX_WAIT_MODE (HAL_TAU_PKT_TX_WAIT_ASYNC) -#define HAL_TAU_PKT_RX_SCHED_MODE (HAL_TAU_PKT_RX_SCHED_RR) +#define HAL_DFLT_CFG_PKT_RX_SCHED_MODE (HAL_TAU_PKT_RX_SCHED_RR) /* TX Queue */ -#define HAL_TAU_PKT_TX_QUEUE_LEN (HAL_TAU_PKT_PDMA_TX_GPD_NUM * 10) -#define HAL_TAU_PKT_TX_TASK_MAX_LOOP (HAL_TAU_PKT_TX_QUEUE_LEN) +#define HAL_DFLT_CFG_PKT_TX_QUEUE_LEN (HAL_DFLT_CFG_PKT_TX_GPD_NUM * 10) +#define HAL_TAU_PKT_TX_TASK_MAX_LOOP (HAL_DFLT_CFG_PKT_TX_QUEUE_LEN) /* RX Queue */ #define HAL_TAU_PKT_RX_QUEUE_NUM (HAL_TAU_PKT_RX_CHANNEL_LAST) -#define HAL_TAU_PKT_RX_QUEUE_WEIGHT (10) -#define HAL_TAU_PKT_RX_QUEUE_LEN (HAL_TAU_PKT_PDMA_RX_GPD_NUM * 10) -#define HAL_TAU_PKT_RX_TASK_MAX_LOOP (HAL_TAU_PKT_RX_QUEUE_LEN) +#define HAL_DFLT_CFG_PKT_RX_QUEUE_WEIGHT (10) +#define HAL_DFLT_CFG_PKT_RX_QUEUE_LEN (HAL_DFLT_CFG_PKT_RX_GPD_NUM * 10) +#define HAL_TAU_PKT_RX_TASK_MAX_LOOP (HAL_DFLT_CFG_PKT_RX_QUEUE_LEN) /* MACRO FUNCTION DECLARATIONS */ /*---------------------------------------------------------------------------*/ -/* [Taurus] Alignment to 64-bytes */ +/* [NP8360] Alignment to 64-bytes */ #if defined(NPS_EN_HOST_64_BIT_BIG_ENDIAN) || defined(NPS_EN_HOST_64_BIT_LITTLE_ENDIAN) #define HAL_TAU_PKT_PDMA_ALIGN_ADDR(pdma_addr, align_sz) (((pdma_addr) + (align_sz)) & 0xFFFFFFFFFFFFFFC0) #else @@ -1120,77 +1120,77 @@ typedef struct /* ----------------------------------------------------------------------------------- Reg Type */ typedef enum { - HAL_TAU_PKT_L2_ISR_RCH0 = (0x1 << 0), - HAL_TAU_PKT_L2_ISR_RCH1 = (0x1 << 1), - HAL_TAU_PKT_L2_ISR_RCH2 = (0x1 << 2), - HAL_TAU_PKT_L2_ISR_RCH3 = (0x1 << 3), - HAL_TAU_PKT_L2_ISR_TCH0 = (0x1 << 4), - HAL_TAU_PKT_L2_ISR_TCH1 = (0x1 << 5), - HAL_TAU_PKT_L2_ISR_TCH2 = (0x1 << 6), - HAL_TAU_PKT_L2_ISR_TCH3 = (0x1 << 7), - HAL_TAU_PKT_L2_ISR_RX_QID_MAP_ERR = (0x1 << 8), - HAL_TAU_PKT_L2_ISR_RX_FRAME_ERR = (0x1 << 9) + HAL_TAU_PKT_L2_ISR_RCH0 = (0x1UL << 0), + HAL_TAU_PKT_L2_ISR_RCH1 = (0x1UL << 1), + HAL_TAU_PKT_L2_ISR_RCH2 = (0x1UL << 2), + HAL_TAU_PKT_L2_ISR_RCH3 = (0x1UL << 3), + HAL_TAU_PKT_L2_ISR_TCH0 = (0x1UL << 4), + HAL_TAU_PKT_L2_ISR_TCH1 = (0x1UL << 5), + HAL_TAU_PKT_L2_ISR_TCH2 = (0x1UL << 6), + HAL_TAU_PKT_L2_ISR_TCH3 = (0x1UL << 7), + HAL_TAU_PKT_L2_ISR_RX_QID_MAP_ERR = (0x1UL << 8), + HAL_TAU_PKT_L2_ISR_RX_FRAME_ERR = (0x1UL << 9) } HAL_TAU_PKT_L2_ISR_T; typedef enum { - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_HWO_ERROR = (0x1 << 0), /* Tx GPD.hwo = 0 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1 << 1), /* Tx GPD.chksm is error */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_NO_OVFL_ERROR = (0x1 << 2), /* S/W push too much GPD */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_DMA_READ_ERROR = (0x1 << 3), /* AXI Rd Error when do GPD read */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_BUF_SIZE_ERROR = (0x1 << 4), /* Tx GPD.data_buf_size = 0 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_RUNT_ERROR = (0x1 << 5), /* Tx GPD.pkt_len < 64 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_OVSZ_ERROR = (0x1 << 6), /* Tx GPD.pkt_len = 9217 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_LEN_MISMATCH_ERROR = (0x1 << 7), /* Tx GPD.pkt_len != sum of data_buf_size */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PKTPL_DMA_READ_ERROR = (0x1 << 8), /* AXI Rd Error when do Payload read */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_COS_ERROR = (0x1 << 9), /* Tx GPD.cos is not match cos_to_tch_map */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1 << 10), /* Multi-GPD packet's GPD# > 255 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PFC = (0x1 << 11), /* */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_CREDIT_UDFL_ERROR = (0x1 << 12), /* Credit Underflow (count down to 0) */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1 << 13), /* AXI Wr Error (GPD Write-Back) */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1 << 14) + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_HWO_ERROR = (0x1UL << 0), /* Tx GPD.hwo = 0 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1UL << 1), /* Tx GPD.chksm is error */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_NO_OVFL_ERROR = (0x1UL << 2), /* S/W push too much GPD */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_DMA_READ_ERROR = (0x1UL << 3), /* AXI Rd Error when do GPD read */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_BUF_SIZE_ERROR = (0x1UL << 4), /* Tx GPD.data_buf_size = 0 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_RUNT_ERROR = (0x1UL << 5), /* Tx GPD.pkt_len < 64 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_OVSZ_ERROR = (0x1UL << 6), /* Tx GPD.pkt_len = 9217 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_LEN_MISMATCH_ERROR = (0x1UL << 7), /* Tx GPD.pkt_len != sum of data_buf_size */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PKTPL_DMA_READ_ERROR = (0x1UL << 8), /* AXI Rd Error when do Payload read */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_COS_ERROR = (0x1UL << 9), /* Tx GPD.cos is not match cos_to_tch_map */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1UL << 10), /* Multi-GPD packet's GPD# > 255 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PFC = (0x1UL << 11), /* */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_CREDIT_UDFL_ERROR = (0x1UL << 12), /* Credit Underflow (count down to 0) */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1UL << 13), /* AXI Wr Error (GPD Write-Back) */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1UL << 14) } HAL_TAU_PKT_TX_CHANNEL_L2_ISR_T; typedef enum { - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_LOW = (0x1 << 0), /* Rx GPD.avbl_gpd_num < threshold */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_EMPTY = (0x1 << 1), /* Rx GPD.avbl_gpd_num = 0 */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_ERROR = (0x1 << 2), /* Rx GPD.hwo = 0 */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1 << 3), /* Rx GPD.chksm is error */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_READ_ERROR = (0x1 << 4), /* DMAR error occurs in PCIE */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1 << 5), /* DMAW error occurs in PCIE */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1 << 6), /* Stop Completion Acknowledge */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1 << 7), /* Multi-GPD packet's GPD# > 255 */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_TOD_UNINIT = (0x1 << 8), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_PKT_ERROR_DROP = (0x1 << 9), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_UDSZ_DROP = (0x1 << 10), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_OVSZ_DROP = (0x1 << 11), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_CMDQ_OVF_DROP = (0x1 << 12), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_FIFO_OVF_DROP = (0x1 << 13) + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_LOW = (0x1UL << 0), /* Rx GPD.avbl_gpd_num < threshold */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_EMPTY = (0x1UL << 1), /* Rx GPD.avbl_gpd_num = 0 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_ERROR = (0x1UL << 2), /* Rx GPD.hwo = 0 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1UL << 3), /* Rx GPD.chksm is error */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_READ_ERROR = (0x1UL << 4), /* DMAR error occurs in PCIE */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1UL << 5), /* DMAW error occurs in PCIE */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1UL << 6), /* Stop Completion Acknowledge */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1UL << 7), /* Multi-GPD packet's GPD# > 255 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_TOD_UNINIT = (0x1UL << 8), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_PKT_ERROR_DROP = (0x1UL << 9), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_UDSZ_DROP = (0x1UL << 10), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_OVSZ_DROP = (0x1UL << 11), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_CMDQ_OVF_DROP = (0x1UL << 12), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_FIFO_OVF_DROP = (0x1UL << 13) } HAL_TAU_PKT_RX_CHANNEL_L2_ISR_T; typedef enum { - HAL_TAU_PKT_TX_CHANNEL_CFG_IOC = (0x1 << 0), - HAL_TAU_PKT_TX_CHANNEL_CFG_CHKSUM = (0x1 << 1), - HAL_TAU_PKT_TX_CHANNEL_CFG_PFC = (0x1 << 2), - HAL_TAU_PKT_TX_CHANNEL_CFG_PKT_LEN_CHK = (0x1 << 3), - HAL_TAU_PKT_TX_CHANNEL_CFG_EARLY_DONE_IRQ = (0x1 << 4), - HAL_TAU_PKT_TX_CHANNEL_CFG_CHK_COS = (0x1 << 5), - HAL_TAU_PKT_TX_CHANNEL_CFG_ADV_GPD_WRBK = (0x1 << 6), - HAL_TAU_PKT_TX_CHANNEL_CFG_GPD_WRBK_FULL_PKT_LEN = (0x1 << 7), - HAL_TAU_PKT_TX_CHANNEL_CFG_LAST = (0x1 << 8) + HAL_TAU_PKT_TX_CHANNEL_CFG_IOC = (0x1UL << 0), + HAL_TAU_PKT_TX_CHANNEL_CFG_CHKSUM = (0x1UL << 1), + HAL_TAU_PKT_TX_CHANNEL_CFG_PFC = (0x1UL << 2), + HAL_TAU_PKT_TX_CHANNEL_CFG_PKT_LEN_CHK = (0x1UL << 3), + HAL_TAU_PKT_TX_CHANNEL_CFG_EARLY_DONE_IRQ = (0x1UL << 4), + HAL_TAU_PKT_TX_CHANNEL_CFG_CHK_COS = (0x1UL << 5), + HAL_TAU_PKT_TX_CHANNEL_CFG_ADV_GPD_WRBK = (0x1UL << 6), + HAL_TAU_PKT_TX_CHANNEL_CFG_GPD_WRBK_FULL_PKT_LEN = (0x1UL << 7), + HAL_TAU_PKT_TX_CHANNEL_CFG_LAST = (0x1UL << 8) } HAL_TAU_PKT_TX_CHANNEL_CFG_T; typedef enum { - HAL_TAU_PKT_RX_CHANNEL_CFG_IOC = (0x1 << 0), - HAL_TAU_PKT_RX_CHANNEL_CFG_CHKSUM = (0x1 << 1), - HAL_TAU_PKT_RX_CHANNEL_CFG_LAST = (0x1 << 2) + HAL_TAU_PKT_RX_CHANNEL_CFG_IOC = (0x1UL << 0), + HAL_TAU_PKT_RX_CHANNEL_CFG_CHKSUM = (0x1UL << 1), + HAL_TAU_PKT_RX_CHANNEL_CFG_LAST = (0x1UL << 2) } HAL_TAU_PKT_RX_CHANNEL_CFG_T; @@ -2079,34 +2079,56 @@ typedef struct /* metadata */ UI8_T mac[6]; -#define HAL_TAU_PKT_NETIF_INTF_FLAGS_MAC (1 << 0) +#define HAL_TAU_PKT_NETIF_INTF_FLAGS_MAC (1UL << 0) UI32_T flags; } HAL_TAU_PKT_NETIF_INTF_T; +#if defined(NETIF_EN_NETLINK) +typedef struct +{ + C8_T name[NPS_NETIF_NAME_LEN]; + C8_T mc_group_name[NPS_NETIF_NAME_LEN]; +} HAL_TAU_PKT_NETIF_RX_DST_NETLINK_T; +#endif + +typedef enum +{ + HAL_TAU_PKT_NETIF_RX_DST_SDK = 0, +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_NETIF_RX_DST_NETLINK, +#endif + HAL_TAU_PKT_NETIF_RX_DST_LAST +} HAL_TAU_PKT_NETIF_RX_DST_TYPE_T; + typedef struct { /* unique key */ - UI32_T id; - C8_T name[NPS_NETIF_NAME_LEN]; - UI32_T priority; + UI32_T id; + C8_T name[NPS_NETIF_NAME_LEN]; + UI32_T priority; /* match fields */ - UI32_T port; /* only support unit port and local port */ - HAL_TAU_PKT_RX_REASON_BITMAP_T reason_bitmap; - UI8_T pattern[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; - UI8_T mask[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; - UI32_T offset[NPS_NETIF_PROFILE_PATTERN_NUM]; + UI32_T port; /* only support unit port and local port */ + HAL_PKT_RX_REASON_BITMAP_T reason_bitmap; + UI8_T pattern[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; + UI8_T mask[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; + UI32_T offset[NPS_NETIF_PROFILE_PATTERN_NUM]; /* for each flag 1:must hit, 0:don't care */ -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PORT (1 << 0) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_REASON (1 << 1) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_0 (1 << 2) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_1 (1 << 3) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_2 (1 << 4) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_3 (1 << 5) - UI32_T flags; +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PORT (1UL << 0) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_REASON (1UL << 1) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_0 (1UL << 2) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_1 (1UL << 3) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_2 (1UL << 4) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_3 (1UL << 5) + UI32_T flags; + + HAL_TAU_PKT_NETIF_RX_DST_TYPE_T dst_type; +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_NETIF_RX_DST_NETLINK_T netlink; +#endif } HAL_TAU_PKT_NETIF_PROFILE_T; @@ -2141,6 +2163,13 @@ typedef enum HAL_TAU_PKT_IOCTL_TYPE_CLEAR_RX_CNT, /* port attribute */ HAL_TAU_PKT_IOCTL_TYPE_SET_PORT_ATTR, +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_IOCTL_TYPE_NL_SET_INTF_PROPERTY, + HAL_TAU_PKT_IOCTL_TYPE_NL_GET_INTF_PROPERTY, + HAL_TAU_PKT_IOCTL_TYPE_NL_CREATE_NETLINK, + HAL_TAU_PKT_IOCTL_TYPE_NL_DESTROY_NETLINK, + HAL_TAU_PKT_IOCTL_TYPE_NL_GET_NETLINK, +#endif HAL_TAU_PKT_IOCTL_TYPE_LAST } HAL_TAU_PKT_IOCTL_TYPE_T; @@ -2219,6 +2248,51 @@ typedef struct } HAL_TAU_PKT_IOCTL_PORT_COOKIE_T; +#if defined(NETIF_EN_NETLINK) + +#define NPS_NETIF_NETLINK_NUM_MAX (256) +#define NPS_NETIF_NETLINK_MC_GROUP_NUM_MAX (32) + +typedef enum +{ + NPS_NETIF_INTF_PROPERTY_IGR_SAMPLING_RATE, + NPS_NETIF_INTF_PROPERTY_EGR_SAMPLING_RATE, + NPS_NETIF_INTF_PROPERTY_LAST +} NPS_NETIF_INTF_PROPERTY_T; + +typedef struct +{ + C8_T name[NPS_NETIF_NAME_LEN]; + +} NPS_NETIF_NETLINK_MC_GROUP_T; + +typedef struct +{ + UI32_T id; + C8_T name[NPS_NETIF_NAME_LEN]; + NPS_NETIF_NETLINK_MC_GROUP_T mc_group[NPS_NETIF_NETLINK_MC_GROUP_NUM_MAX]; + UI32_T mc_group_num; + +} NPS_NETIF_NETLINK_T; + +typedef struct +{ + /* intf property */ + UI32_T intf_id; + NPS_NETIF_INTF_PROPERTY_T property; + UI32_T param0; + UI32_T param1; + + /* netlink */ + NPS_NETIF_NETLINK_T netlink; + + NPS_ERROR_NO_T rc; + +} HAL_TAU_PKT_NL_IOCTL_COOKIE_T; + + +#endif /* End of NETIF_EN_NETLINK */ + typedef union { UI32_T value; @@ -2231,6 +2305,7 @@ typedef union } HAL_TAU_PKT_IOCTL_CMD_T; + #endif /* End of NPS_EN_NETIF */ NPS_ERROR_NO_T diff --git a/platform/nephos/nephos-modules/modules/src/inc/netif_nl.h b/platform/nephos/nephos-modules/modules/src/inc/netif_nl.h new file mode 100755 index 000000000000..4b31ceef1620 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/netif_nl.h @@ -0,0 +1,104 @@ +/* Copyright (C) 2020 MediaTek, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + + /* FILE NAME: netif_nl.h + * PURPOSE: + * It provide xxx API. + * NOTES: + */ + +#ifndef NETIF_NL_H +#define NETIF_NL_H + +#include + +#define NETIF_NL_NETLINK_MC_GROUP_NUM (32) +#define NETIF_NL_NETLINK_NAME_LEN (16) + +typedef enum +{ + NETIF_NL_INTF_PROPERTY_IGR_SAMPLING_RATE, + NETIF_NL_INTF_PROPERTY_EGR_SAMPLING_RATE, + NETIF_NL_INTF_PROPERTY_LAST +} NETIF_NL_INTF_PROPERTY_T; + +/* must be the same with NPS_NETIF_RX_DST_NETLINK_T */ +typedef struct +{ + C8_T name[NETIF_NL_NETLINK_NAME_LEN]; + C8_T mc_group_name[NETIF_NL_NETLINK_NAME_LEN]; +} NETIF_NL_RX_DST_NETLINK_T; + +/* must be the same with NPS_NETIF_NETLINK_MC_GROUP_T */ +typedef struct +{ + C8_T name[NETIF_NL_NETLINK_NAME_LEN]; + +} NETIF_NL_NETLINK_MC_GROUP_T; + +/* must be the same with NPS_NETIF_NETLINK_T */ +typedef struct +{ + UI32_T id; + C8_T name[NETIF_NL_NETLINK_NAME_LEN]; + NETIF_NL_NETLINK_MC_GROUP_T mc_group[NETIF_NL_NETLINK_MC_GROUP_NUM]; + UI32_T mc_group_num; + +} NETIF_NL_NETLINK_T; + +NPS_ERROR_NO_T +netif_nl_rxSkb( + const UI32_T unit, + struct sk_buff *ptr_skb, + void *ptr_cookie); + +NPS_ERROR_NO_T +netif_nl_setIntfProperty( + const UI32_T unit, + const UI32_T id, + const NETIF_NL_INTF_PROPERTY_T property, + const UI32_T param0, + const UI32_T param1); + +NPS_ERROR_NO_T +netif_nl_getIntfProperty( + const UI32_T unit, + const UI32_T port, + const NETIF_NL_INTF_PROPERTY_T property, + UI32_T *ptr_param0, + UI32_T *ptr_param1); + +NPS_ERROR_NO_T +netif_nl_createNetlink( + const UI32_T unit, + NETIF_NL_NETLINK_T *ptr_netlink, + UI32_T *ptr_netlink_id); + +NPS_ERROR_NO_T +netif_nl_destroyNetlink( + const UI32_T unit, + const UI32_T group_id); + +NPS_ERROR_NO_T +netif_nl_getNetlink( + const UI32_T unit, + const UI32_T netlink_id, + NETIF_NL_NETLINK_T *ptr_netlink); + + +NPS_ERROR_NO_T +netif_nl_init(void); + +#endif /* end of NETIF_NL_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h b/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h index 40c8c9ebc358..93f30fc61ce1 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h +++ b/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h b/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h index 35596668ba9d..5309f01b62d8 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h +++ b/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h b/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h index 34306344c55a..36de3cc70863 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_error.h b/platform/nephos/nephos-modules/modules/src/inc/nps_error.h index 261878abf3cb..3cf0a14adc0b 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/nps_error.h +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_error.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_types.h b/platform/nephos/nephos-modules/modules/src/inc/nps_types.h index 5630b521404e..88100f69738f 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/nps_types.h +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_types.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h b/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h index 47971bb38c8d..0add2c8216b1 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h +++ b/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -134,6 +134,8 @@ typedef enum OSAL_MDC_IOCTL_TYPE_MDC_FREE_SYS_DMA_MEM, OSAL_MDC_IOCTL_TYPE_MDC_CONNECT_ISR, OSAL_MDC_IOCTL_TYPE_MDC_DISCONNECT_ISR, + OSAL_MDC_IOCTL_TYPE_MDC_SAVE_PCI_CONFIG, + OSAL_MDC_IOCTL_TYPE_MDC_RESTORE_PCI_CONFIG, OSAL_MDC_IOCTL_TYPE_LAST } OSAL_MDC_IOCTL_TYPE_T; @@ -238,4 +240,12 @@ osal_mdc_invalidateCache( void *ptr_virt_addr, const UI32_T size); +NPS_ERROR_NO_T +osal_mdc_savePciConfig( + const UI32_T unit); + +NPS_ERROR_NO_T +osal_mdc_restorePciConfig( + const UI32_T unit); + #endif /* OSAL_MDC_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/osal_types.h b/platform/nephos/nephos-modules/modules/src/inc/osal_types.h index 48ac58aba335..59fd3df1260d 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/osal_types.h +++ b/platform/nephos/nephos-modules/modules/src/inc/osal_types.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/make.mk b/platform/nephos/nephos-modules/modules/src/make.mk index e556ea10d765..b49da8b43cdf 100755 --- a/platform/nephos/nephos-modules/modules/src/make.mk +++ b/platform/nephos/nephos-modules/modules/src/make.mk @@ -1,5 +1,5 @@ ################################################################################ -# Copyright (C) 2019 Nephos, Inc. +# Copyright (C) 2020 MediaTek, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -17,7 +17,7 @@ DEV_MODULE_NAME := nps_dev NETIF_MODULE_NAME := nps_netif ################################################################################ DEV_OBJS_TOTAL := ./src/osal_mdc.o ./src/osal_isymbol.o -NETIF_OBJS_TOTAL := ./src/hal_tau_pkt_knl.o ./src/netif_perf.o ./src/netif_osal.o +NETIF_OBJS_TOTAL := ./src/hal_tau_pkt_knl.o ./src/netif_perf.o ./src/netif_osal.o ./src/netif_nl.o obj-m := $(DEV_MODULE_NAME).o $(NETIF_MODULE_NAME).o $(DEV_MODULE_NAME)-objs := $(DEV_OBJS_TOTAL) diff --git a/platform/nephos/nephos-modules/modules/src/netif_nl.c b/platform/nephos/nephos-modules/modules/src/netif_nl.c new file mode 100755 index 000000000000..c112e4b6dd80 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/netif_nl.c @@ -0,0 +1,811 @@ +/* Copyright (C) 2020 MediaTek, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + + /* FILE NAME: netif_xxx.c + * PURPOSE: + * It provide xxx API. + * NOTES: + */ +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +extern UI32_T ext_dbg_flag; + +#define NETIF_NL_DBG(__flag__, ...) do \ +{ \ + if (0 != ((__flag__) & (ext_dbg_flag))) \ + { \ + osal_printf(__VA_ARGS__); \ + } \ +}while (0) + +#define NETIF_NL_DBG_NETLINK (0x1UL << 6) + +#define NETIF_NL_FAMILY_NUM_MAX (256) +#define NETIF_NL_INTF_NUM_MAX (256) + +#define NETIF_NL_GET_FAMILY_META(__idx__) &(_netif_nl_cb.fam_entry[__idx__].meta) +#define NETIF_NL_GET_INTF_IGR_SAMPLE_RATE(__inft_id__) (_netif_nl_cb.intf_entry[__inft_id__].igr_sample_rate) + +#define NETIF_NL_FAMILY_IS_PSAMPLE(__ptr_family__) (0 == strncmp(__ptr_family__->name, \ + NETIF_NL_PSAMPLE_FAMILY_NAME, \ + NETIF_NL_NETLINK_NAME_LEN)) ? 1 : 0 + +/* porting part */ +#define NETIF_NL_VER_NUM (1) +#define NETIF_NL_PSAMPLE_MAX_ATTR_NUM (NETIF_NL_PSAMPLE_ATTR_LAST) +#define NETIF_NL_REGISTER_FAMILY(__family__) genl_register_family(__family__) + +#define NETIF_NL_UNREGISTER_FAMILY(__family__) genl_unregister_family(__family__) +#define NETIF_NL_ALLOC_SKB(__len__) genlmsg_new(__len__, GFP_ATOMIC) +#define NETIF_NL_FREE_SKB(__ptr_skb__) nlmsg_free(__ptr_skb__) + +#define NETIF_NL_SEND_PKT(__ptr_family__, __mcgrp_id__, __ptr_skb__) \ + genlmsg_multicast_netns(__ptr_family__, \ + &init_net, \ + __ptr_skb__, \ + 0, /* pid, avoid loop */ \ + __mcgrp_id__, \ + GFP_ATOMIC) +#define NETIF_NL_SET_SKB_ATTR_HDR(__skb__, __family__, __hdr_len__, __cmd__) \ + genlmsg_put(__skb__, 0, 0, __family__, \ + __hdr_len__, __cmd__) +#define NETIF_NL_END_SKB_ATTR_HDR(__skb__, __hdr__) genlmsg_end(__skb__, __hdr__) + +#define NETIF_NL_SET_16_BIT_ATTR(__skb__, __attr__, __data__) nla_put_u16(__skb__, __attr__, __data__) +#define NETIF_NL_SET_32_BIT_ATTR(__skb__, __attr__, __data__) nla_put_u32(__skb__, __attr__, __data__) + + +/* + * <----------- nla_total_size(payload) -------------> + * +------------------+- - -+- - - - - - - - - +- - -+ + * | Attribute Header | Pad | Payload | Pad | + * +------------------+- - -+- - - - - - - - - +- - -+ + * + * + * <-------- nla_attr_size(payload) ----------> + * +------------------+- - -+- - - - - - - - - +- - -+ + * | Attribute Header | Pad | Payload | Pad | + * +------------------+- - -+- - - - - - - - - +- - -+ + * + */ +/* total size = attr data size + attr header size */ +#define NETIF_NL_GET_ATTR_TOTAL_SIZE(__data_size__) nla_total_size(__data_size__) +#define NETIF_NL_GET_ATTR_SIZE(__data_size__) nla_attr_size(__data_size__) /* without padding */ + + +/* psample's family and group parameter */ +#define NETIF_NL_PSAMPLE_FAMILY_NAME "psample" +#define NETIF_NL_PSAMPLE_MC_GROUP_NAME_DATA "packets" +#define NETIF_NL_PSAMPLE_MC_GROUP_NAME_CFG "config" +#define NETIF_NL_PSAMPLE_MC_GROUP_NUM (NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST) +#define NETIF_NL_DEFAULT_MC_GROUP_NUM (1) + +#define NETIF_NL_PSAMPLE_PKT_LEN_MAX (9216) +#define NETIF_NL_PSAMPLE_DFLT_USR_GROUP_ID (1) + +typedef enum +{ + NETIF_NL_PSAMPLE_MC_GROUP_ID_CONFIG = 0, + NETIF_NL_PSAMPLE_MC_GROUP_ID_SAMPLE, + NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST, +} NETIF_NL_PSAMPLE_MC_GROUP_ID_T; + +typedef enum +{ + NETIF_NL_PSAMPLE_ATTR_IIFINDEX = 0, + NETIF_NL_PSAMPLE_ATTR_OIFINDEX, + NETIF_NL_PSAMPLE_ATTR_ORIGSIZE, + NETIF_NL_PSAMPLE_ATTR_SAMPLE_GROUP, + NETIF_NL_PSAMPLE_ATTR_GROUP_SEQ, + NETIF_NL_PSAMPLE_ATTR_SAMPLE_RATE, + NETIF_NL_PSAMPLE_ATTR_DATA, + NETIF_NL_PSAMPLE_ATTR_LAST +} NETIF_NL_PSAMPLE_ATTR_ID_T; + + +typedef struct genl_multicast_group NETIF_NL_MC_GROUP_T; +typedef struct genl_family NETIF_NL_FAMILY_T; + +static NETIF_NL_MC_GROUP_T _netif_nl_psample_mc_group[NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST]; +static C8_T *_ptr_netif_nl_psample_mc_group_name[NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST] = + { + NETIF_NL_PSAMPLE_MC_GROUP_NAME_CFG, + NETIF_NL_PSAMPLE_MC_GROUP_NAME_DATA + }; + +static NETIF_NL_MC_GROUP_T _netif_nl_default_mc_group[NETIF_NL_DEFAULT_MC_GROUP_NUM]; +static C8_T *_ptr_netif_nl_default_mc_group_name[NETIF_NL_DEFAULT_MC_GROUP_NUM] = + { + "default", + }; + +typedef struct +{ + NETIF_NL_FAMILY_T meta; + BOOL_T valid; + +} NETIF_NL_FAMILY_ENTRY_T; + +typedef struct +{ + UI32_T igr_sample_rate; + UI32_T egr_sample_rate; + UI32_T trunc_size; +} NETIF_NL_INTF_ENTRY_T; + +typedef struct +{ + NETIF_NL_FAMILY_ENTRY_T fam_entry[NETIF_NL_FAMILY_NUM_MAX]; + NETIF_NL_INTF_ENTRY_T intf_entry[NETIF_NL_INTF_NUM_MAX]; /* sorted in intf_id */ + UI32_T seq_num; +} NETIF_NL_CB_T; + +static NETIF_NL_CB_T _netif_nl_cb; + +/* should extract to common */ +struct net_device_priv +{ + struct net_device *ptr_net_dev; + struct net_device_stats stats; + UI32_T unit; + UI32_T id; + UI32_T port; + UI16_T vlan; + UI32_T speed; +}; + +static NPS_ERROR_NO_T +_netif_nl_setIntfIgrSampleRate( + const UI32_T unit, + const UI32_T id, + const UI32_T rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + ptr_cb->intf_entry[id].igr_sample_rate = rate; + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_netif_nl_setIntfEgrSampleRate( + const UI32_T unit, + const UI32_T id, + const UI32_T rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + ptr_cb->intf_entry[id].egr_sample_rate = rate; + + return (NPS_E_OK); +} + + +NPS_ERROR_NO_T +netif_nl_setIntfProperty( + const UI32_T unit, + const UI32_T id, + const NETIF_NL_INTF_PROPERTY_T property, + const UI32_T param0, + const UI32_T param1) +{ + NPS_ERROR_NO_T rc = NPS_E_BAD_PARAMETER; + + if (NETIF_NL_INTF_PROPERTY_IGR_SAMPLING_RATE == property) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "receive set igr sample rate req, id=%d, property=%d, param0=%d, param=%d\n", + id, property, param0, param1); + rc = _netif_nl_setIntfIgrSampleRate(unit, id, param0); + } + else if (NETIF_NL_INTF_PROPERTY_EGR_SAMPLING_RATE == property) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "receive set egr sample rate req, id=%d, property=%d, param0=%d, param=%d\n", + id, property, param0, param1); + rc = _netif_nl_setIntfEgrSampleRate(unit, id, param0); + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[error] unknown property, property=%d\n", property); + } + + return (rc); +} + +static NPS_ERROR_NO_T +_netif_nl_getIntfIgrSampleRate( + const UI32_T unit, + const UI32_T id, + UI32_T *ptr_rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + *ptr_rate = ptr_cb->intf_entry[id].igr_sample_rate; + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_netif_nl_getIntfEgrSampleRate( + const UI32_T unit, + const UI32_T id, + UI32_T *ptr_rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + *ptr_rate = ptr_cb->intf_entry[id].egr_sample_rate; + + return (NPS_E_OK); +} + + +NPS_ERROR_NO_T +netif_nl_getIntfProperty( + const UI32_T unit, + const UI32_T id, + const NETIF_NL_INTF_PROPERTY_T property, + UI32_T *ptr_param0, + UI32_T *ptr_param1) +{ + NPS_ERROR_NO_T rc = NPS_E_BAD_PARAMETER; + + if (NETIF_NL_INTF_PROPERTY_IGR_SAMPLING_RATE == property) + { + rc = _netif_nl_getIntfIgrSampleRate(unit, id, ptr_param0); + } + else if (NETIF_NL_INTF_PROPERTY_EGR_SAMPLING_RATE == property) + { + rc = _netif_nl_getIntfEgrSampleRate(unit, id, ptr_param0); + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[error] unknown property, property=%d\n", + property); + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_allocNlFamilyEntry( + NETIF_NL_CB_T *ptr_cb, + UI32_T *ptr_index) +{ + UI32_T idx; + NPS_ERROR_NO_T rc = NPS_E_TABLE_FULL; + + for (idx = 0; idx < NETIF_NL_FAMILY_NUM_MAX; idx++) + { + if (FALSE == ptr_cb->fam_entry[idx].valid) + { + *ptr_index = idx; + ptr_cb->fam_entry[idx].valid = TRUE; + rc = NPS_E_OK; + break; + } + } + + return (rc); +} + +void +_netif_nl_freeNlFamilyEntry( + NETIF_NL_CB_T *ptr_cb, + const UI32_T index) +{ + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] free netlink family entry, idx=%d\n", + index); + ptr_cb->fam_entry[index].valid = FALSE; +} + +NPS_ERROR_NO_T +_netif_nl_setNlMcgroupPsample( + NETIF_NL_FAMILY_T *ptr_nl_family) +{ + NETIF_NL_MC_GROUP_T *ptr_nl_mc_group = _netif_nl_psample_mc_group; + UI32_T idx; + + /* init the mc group and hook the group to family */ + osal_memset(ptr_nl_mc_group, 0x0, + (NETIF_NL_PSAMPLE_MC_GROUP_NUM * sizeof(NETIF_NL_MC_GROUP_T))); + + for (idx = 0; idx < NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST; idx++) + { + osal_memcpy(ptr_nl_mc_group[idx].name, + _ptr_netif_nl_psample_mc_group_name[idx], + osal_strlen(_ptr_netif_nl_psample_mc_group_name[idx])); + } + ptr_nl_family->n_mcgrps = NETIF_NL_PSAMPLE_MC_GROUP_NUM; + ptr_nl_family->mcgrps = ptr_nl_mc_group; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +_netif_nl_setNlMcgroupDefault( + NETIF_NL_FAMILY_T *ptr_nl_family) +{ + NETIF_NL_MC_GROUP_T *ptr_nl_mc_group = _netif_nl_default_mc_group; + UI32_T idx; + + /* init the mc group and hook the group to family */ + osal_memset(ptr_nl_mc_group, 0x0, + (NETIF_NL_DEFAULT_MC_GROUP_NUM * sizeof(NETIF_NL_MC_GROUP_T))); + + for (idx = 0; idx < NETIF_NL_DEFAULT_MC_GROUP_NUM; idx++) + { + osal_memcpy(ptr_nl_mc_group[idx].name, + _ptr_netif_nl_default_mc_group_name[idx], + osal_strlen(_ptr_netif_nl_default_mc_group_name[idx])); + } + ptr_nl_family->n_mcgrps = NETIF_NL_DEFAULT_MC_GROUP_NUM; + ptr_nl_family->mcgrps = ptr_nl_mc_group; + + return (NPS_E_OK); +} + +#define NETIF_NL_IS_FAMILY_ENTRY_VALID(__idx__) \ + (TRUE == _netif_nl_cb.fam_entry[__idx__].valid) ? (TRUE) : (FALSE) +NPS_ERROR_NO_T +netif_nl_createNetlink( + const UI32_T unit, + NETIF_NL_NETLINK_T *ptr_netlink, + UI32_T *ptr_netlink_id) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + UI32_T entry_id; + NETIF_NL_FAMILY_T *ptr_nl_family; + NETIF_NL_MC_GROUP_T *ptr_nl_mcgrp; + UI32_T idx; + int ret; + NPS_ERROR_NO_T rc; + + rc = _netif_nl_allocNlFamilyEntry(ptr_cb, &entry_id); + if (NPS_E_OK == rc) + { + ptr_nl_family = NETIF_NL_GET_FAMILY_META(entry_id); + + /* fill in the meta data for that netlink family */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) + ptr_nl_family->id = GENL_ID_GENERATE; /* family id can be ignored since linux 4.10 */ +#endif + ptr_nl_family->version = NETIF_NL_VER_NUM; + ptr_nl_family->maxattr = NETIF_NL_PSAMPLE_MAX_ATTR_NUM; + ptr_nl_family->netnsok = true; + osal_memcpy(ptr_nl_family->name, ptr_netlink->name, NETIF_NL_NETLINK_NAME_LEN); + + /* fill in the mc group info */ + ptr_nl_mcgrp = osal_alloc(sizeof(NETIF_NL_MC_GROUP_T)*ptr_netlink->mc_group_num); + if (NULL != ptr_nl_mcgrp) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, "[DBG] create mc group:\n"); + for (idx = 0; idx < ptr_netlink->mc_group_num; idx++) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] - mcgrp%d: %s\n", idx, ptr_netlink->mc_group[idx].name); + osal_memcpy(ptr_nl_mcgrp[idx].name, ptr_netlink->mc_group[idx].name, + NETIF_NL_NETLINK_NAME_LEN); + } + ptr_nl_family->n_mcgrps = ptr_netlink->mc_group_num; + ptr_nl_family->mcgrps = ptr_nl_mcgrp; + + /* register the family to kernel */ + ret = NETIF_NL_REGISTER_FAMILY(ptr_nl_family); + if (0 == ret) + { + *ptr_netlink_id = entry_id; + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] create netlink family, name=%s, entry_idx=%d, mcgrp_num=%d\n", + ptr_netlink->name, entry_id, ptr_nl_family->n_mcgrps); + rc = NPS_E_OK; + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] register netlink family failed, name=%s, ret=%d\n", + ptr_netlink->name, ret); + osal_free(ptr_nl_mcgrp); + _netif_nl_freeNlFamilyEntry(ptr_cb, entry_id); + rc = NPS_E_OTHERS; + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, "[DBG] alloc mcgrp failed\n"); + rc = NPS_E_NO_MEMORY; + } + } + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_destroyNetlink( + const UI32_T unit, + const UI32_T netlink_id) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + UI32_T entry_idx = netlink_id; + NETIF_NL_FAMILY_T *ptr_nl_family; + int ret; + NPS_ERROR_NO_T rc; + + if (TRUE == NETIF_NL_IS_FAMILY_ENTRY_VALID(entry_idx)) + { + ptr_nl_family = NETIF_NL_GET_FAMILY_META(entry_idx); + ret = NETIF_NL_UNREGISTER_FAMILY(ptr_nl_family); + if (0 == ret) + { + osal_free(ptr_nl_family->mcgrps); + _netif_nl_freeNlFamilyEntry(ptr_cb, entry_idx); + rc = NPS_E_OK; + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] unregister netlink family failed, name=%s, ret=%d\n", + ptr_nl_family->name, ret); + rc = NPS_E_OTHERS; + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] destroy netlink failed, invalid netlink_id %d\n", + netlink_id); + rc = NPS_E_ENTRY_NOT_FOUND; + } + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_getNetlink( + const UI32_T unit, + const UI32_T netlink_id, + NETIF_NL_NETLINK_T *ptr_netlink) +{ + UI32_T entry_idx = netlink_id; + NETIF_NL_FAMILY_T *ptr_meta; + UI32_T grp_idx; + NPS_ERROR_NO_T rc = NPS_E_OK; + + if (TRUE == NETIF_NL_IS_FAMILY_ENTRY_VALID(entry_idx)) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] get valid netlink, id=%d\n", netlink_id); + + ptr_netlink->id = netlink_id; + ptr_meta = NETIF_NL_GET_FAMILY_META(entry_idx); + + ptr_netlink->mc_group_num = ptr_meta->n_mcgrps; + osal_memcpy(ptr_netlink->name, ptr_meta->name, NETIF_NL_NETLINK_NAME_LEN); + + for (grp_idx = 0; grp_idx < ptr_meta->n_mcgrps; grp_idx++) + { + osal_memcpy(ptr_netlink->mc_group[grp_idx].name, + ptr_meta->mcgrps[grp_idx].name, + NETIF_NL_NETLINK_NAME_LEN); + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] get netlink failed, invalid netlink_id %d\n", + netlink_id); + rc = NPS_E_ENTRY_NOT_FOUND; + } + + return (rc); +} + + +NPS_ERROR_NO_T +_netif_nl_getFamilyByName( + NETIF_NL_CB_T *ptr_cb, + const C8_T *ptr_name, + NETIF_NL_FAMILY_T **pptr_nl_family) +{ + UI32_T idx; + NPS_ERROR_NO_T rc = NPS_E_ENTRY_NOT_FOUND; + + for (idx = 0; idx < NETIF_NL_FAMILY_NUM_MAX; idx++) + { + if ((TRUE == ptr_cb->fam_entry[idx].valid) && + (0 == strncmp(ptr_cb->fam_entry[idx].meta.name, + ptr_name, + NETIF_NL_NETLINK_NAME_LEN))) + { + *pptr_nl_family = &(ptr_cb->fam_entry[idx].meta); + rc = NPS_E_OK; + break; + } + } + + if (NPS_E_ENTRY_NOT_FOUND == rc) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] find family failed, name=%s\n", + ptr_name); + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_getMcgrpIdByName( + NETIF_NL_FAMILY_T *ptr_nl_family, + const C8_T *ptr_mcgrp_name, + UI32_T *ptr_mcgrp_id) +{ + UI32_T idx; + NPS_ERROR_NO_T rc = NPS_E_ENTRY_NOT_FOUND; + + for (idx = 0; idx < ptr_nl_family->n_mcgrps; idx++) + { + if ((0 == strncmp(ptr_nl_family->mcgrps[idx].name, + ptr_mcgrp_name, + NETIF_NL_NETLINK_NAME_LEN))) + { + *ptr_mcgrp_id = idx; + rc = NPS_E_OK; + break; + } + } + + if (NPS_E_OK != rc) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] find mcgrp %s failed in family %s\n", + ptr_mcgrp_name, ptr_nl_family->name); + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_allocPsampleSkb( + NETIF_NL_CB_T *ptr_cb, + NETIF_NL_FAMILY_T *ptr_nl_family, + struct sk_buff *ptr_ori_skb, + struct sk_buff **pptr_nl_skb) +{ + UI32_T msg_hdr_len; + UI32_T data_len; + struct sk_buff *ptr_nl_skb; + UI16_T igr_intf_idx; + struct net_device_priv *ptr_priv; + UI32_T rate; + UI32_T intf_id; + void *ptr_nl_hdr = NULL; + struct nlattr *ptr_nl_attr; + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* make sure the total len (original pkt len + hdr msg) < PSAMPLE_MAX_PACKET_SIZE */ + + msg_hdr_len = NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI16_T)) + /* PSAMPLE_ATTR_IIFINDEX */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)) + /* PSAMPLE_ATTR_SAMPLE_RATE */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)) + /* PSAMPLE_ATTR_ORIGSIZE */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)) + /* PSAMPLE_ATTR_SAMPLE_GROUP */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)); /* PSAMPLE_ATTR_GROUP_SEQ */ + + data_len = NETIF_NL_GET_ATTR_TOTAL_SIZE(ptr_ori_skb->len); + + if ((msg_hdr_len + NETIF_NL_GET_ATTR_TOTAL_SIZE(ptr_ori_skb->len)) > NETIF_NL_PSAMPLE_PKT_LEN_MAX) + { + data_len = NETIF_NL_PSAMPLE_PKT_LEN_MAX - msg_hdr_len - NLA_HDRLEN - NLA_ALIGNTO; + } + else + { + data_len = ptr_ori_skb->len; + } + + ptr_nl_skb = NETIF_NL_ALLOC_SKB(NETIF_NL_GET_ATTR_TOTAL_SIZE(data_len) + msg_hdr_len); + if (NULL != ptr_nl_skb) + { + /* to create a netlink msg header (cmd=0) */ + ptr_nl_hdr = NETIF_NL_SET_SKB_ATTR_HDR(ptr_nl_skb, ptr_nl_family, 0, 0); + if (NULL != ptr_nl_hdr) + { + /* obtain the intf index for the igr_port */ + igr_intf_idx = ptr_ori_skb->dev->ifindex; + NETIF_NL_SET_16_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_IIFINDEX, + (UI16_T)igr_intf_idx); + + /* meta header */ + /* use the igr port id as the index for the database to get sample rate */ + ptr_priv = netdev_priv(ptr_ori_skb->dev); + intf_id = ptr_priv->port; + rate = NETIF_NL_GET_INTF_IGR_SAMPLE_RATE(intf_id); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_SAMPLE_RATE, rate); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_ORIGSIZE, data_len); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_SAMPLE_GROUP, + NETIF_NL_PSAMPLE_DFLT_USR_GROUP_ID); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_GROUP_SEQ, ptr_cb->seq_num); + ptr_cb->seq_num++; + + /* data */ + ptr_nl_attr = (struct nlattr *)skb_put(ptr_nl_skb, NETIF_NL_GET_ATTR_TOTAL_SIZE(data_len)); + ptr_nl_attr->nla_type = NETIF_NL_PSAMPLE_ATTR_DATA; + /* get the attr size without padding, since it's the last one */ + ptr_nl_attr->nla_len = NETIF_NL_GET_ATTR_SIZE(data_len); + skb_copy_bits(ptr_ori_skb, 0, nla_data(ptr_nl_attr), data_len); + + NETIF_NL_END_SKB_ATTR_HDR(ptr_nl_skb, ptr_nl_hdr); + } + else + { + rc = NPS_E_OTHERS; + } + } + else + { + rc = NPS_E_OTHERS; + } + + *pptr_nl_skb = ptr_nl_skb; + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_allocNetlinkSkb( + NETIF_NL_CB_T *ptr_cb, + NETIF_NL_FAMILY_T *ptr_nl_family, + struct sk_buff *ptr_ori_skb, + struct sk_buff **pptr_nl_skb) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* need to fill specific skb header format */ + if (NETIF_NL_FAMILY_IS_PSAMPLE(ptr_nl_family)) + { + rc = _netif_nl_allocPsampleSkb(ptr_cb, ptr_nl_family, + ptr_ori_skb, pptr_nl_skb); + if (NPS_E_OK != rc) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] alloc netlink skb failed\n"); + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] unknown netlink family\n"); + rc = NPS_E_OTHERS; + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_sendNetlinkSkb( + NETIF_NL_FAMILY_T *ptr_nl_family, + UI32_T nl_mcgrp_id, + struct sk_buff *ptr_nl_skb) +{ + int ret; + NPS_ERROR_NO_T rc; + + ret = NETIF_NL_SEND_PKT(ptr_nl_family, nl_mcgrp_id, ptr_nl_skb); + if (0 == ret) + { + rc = NPS_E_OK; + } + else + { + /* in errno_base.h, #define ESRCH 3 : No such process */ + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "send skb to mc group failed, ret=%d\n", ret); + rc = NPS_E_OTHERS; + } + + return (rc); +} + +void +_netif_nl_freeNetlinkSkb( + struct sk_buff *ptr_nl_skb) +{ + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, "[DBG] free nl skb\n"); + NETIF_NL_FREE_SKB(ptr_nl_skb); +} + +NPS_ERROR_NO_T +_netif_nl_forwardPkt( + NETIF_NL_CB_T *ptr_cb, + NETIF_NL_RX_DST_NETLINK_T *ptr_nl_dest, + struct sk_buff *ptr_ori_skb) +{ + struct sk_buff *ptr_nl_skb = NULL; + NETIF_NL_FAMILY_T *ptr_nl_family; + UI32_T nl_mcgrp_id; + NPS_ERROR_NO_T rc; + + rc = _netif_nl_getFamilyByName(ptr_cb, ptr_nl_dest->name, + &ptr_nl_family); + if (NPS_E_OK == rc) + { + rc = _netif_nl_getMcgrpIdByName(ptr_nl_family, ptr_nl_dest->mc_group_name, + &nl_mcgrp_id); + if (NPS_E_OK == rc) + { + rc = _netif_nl_allocNetlinkSkb(ptr_cb, ptr_nl_family, + ptr_ori_skb, &ptr_nl_skb); + if (NPS_E_OK == rc) + { + rc = _netif_nl_sendNetlinkSkb(ptr_nl_family, nl_mcgrp_id, + ptr_nl_skb); + if (NPS_E_OK != rc) + { + /* _netif_nl_freeNetlinkSkb(ptr_nl_skb); */ + } + } + } + } + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_rxSkb( + const UI32_T unit, + struct sk_buff *ptr_skb, + void *ptr_cookie) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + NETIF_NL_RX_DST_NETLINK_T *ptr_nl_dest; + NPS_ERROR_NO_T rc; + + ptr_nl_dest = (NETIF_NL_RX_DST_NETLINK_T *)ptr_cookie; + + /* send the packet to netlink mcgroup */ + rc = _netif_nl_forwardPkt(ptr_cb, ptr_nl_dest, ptr_skb); + + /* need to free the original skb anyway */ + osal_skb_free(ptr_skb); + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_init(void) +{ + osal_memset(&_netif_nl_cb, 0x0, sizeof(NETIF_NL_CB_T)); + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +netif_nl_deinit(void) +{ + return (NPS_E_OK); +} + diff --git a/platform/nephos/nephos-modules/modules/src/netif_osal.c b/platform/nephos/nephos-modules/modules/src/netif_osal.c index 15599e3a0aa0..51af7fcb3ad9 100755 --- a/platform/nephos/nephos-modules/modules/src/netif_osal.c +++ b/platform/nephos/nephos-modules/modules/src/netif_osal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/netif_perf.c b/platform/nephos/nephos-modules/modules/src/netif_perf.c index 18606d6d25d4..11dd03b58eb5 100755 --- a/platform/nephos/nephos-modules/modules/src/netif_perf.c +++ b/platform/nephos/nephos-modules/modules/src/netif_perf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/osal_isymbol.c b/platform/nephos/nephos-modules/modules/src/osal_isymbol.c index c23cc70bed23..f908c2325966 100755 --- a/platform/nephos/nephos-modules/modules/src/osal_isymbol.c +++ b/platform/nephos/nephos-modules/modules/src/osal_isymbol.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/osal_mdc.c b/platform/nephos/nephos-modules/modules/src/osal_mdc.c index 3dad3173ac79..d0a25e48fc32 100755 --- a/platform/nephos/nephos-modules/modules/src/osal_mdc.c +++ b/platform/nephos/nephos-modules/modules/src/osal_mdc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -37,7 +37,7 @@ #include #include #include - +#include #include #include @@ -685,6 +685,7 @@ _osal_mdc_removePciCallback( iounmap(ptr_dev->ptr_mmio_virt_addr); pci_release_region(pdev, OSAL_MDC_PCI_BAR0_OFFSET); pci_disable_device(pdev); + _osal_mdc_cb.dev_num--; } static struct pci_device_id _osal_mdc_id_table[] = @@ -708,6 +709,7 @@ _osal_mdc_probePciDevice(void) if (pci_register_driver(&_osal_mdc_pci_driver) < 0) { + OSAL_MDC_ERR("Cannot find PCI device\n"); rc = NPS_E_OTHERS; } return (rc); @@ -720,6 +722,119 @@ _osal_mdc_removePciDevice(void) return (NPS_E_OK); } +static NPS_ERROR_NO_T +_osal_mdc_maskStatus( + const UI32_T unit) +{ + struct pci_dev *ptr_ep_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + struct pci_dev *ptr_rc_dev = ptr_ep_dev->bus->self; + int ext_cap = 0; + UI32_T data_32 = 0; + + ext_cap = pci_find_ext_capability(ptr_rc_dev, 0x1); + if (0 != ext_cap) + { + /* Mask */ + pci_read_config_dword(ptr_rc_dev, ext_cap + 0x8, &data_32); + data_32 |= 0x20; + pci_write_config_dword(ptr_rc_dev, ext_cap + 0x8, data_32); + } + + return NPS_E_OK; +} + +static NPS_ERROR_NO_T +_osal_mdc_clearStatus( + const UI32_T unit) +{ + struct pci_dev *ptr_ep_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + struct pci_dev *ptr_rc_dev = ptr_ep_dev->bus->self; + int ext_cap = 0; + UI32_T data_32 = 0; + + ext_cap = pci_find_ext_capability(ptr_rc_dev, 0x1); + if (0 != ext_cap) + { + /* Clear */ + pci_write_config_word(ptr_rc_dev, ptr_rc_dev->pcie_cap + 0xa, 0x04); + pci_write_config_word(ptr_rc_dev, ptr_rc_dev->pcie_cap + 0x12, 0x8000); + pci_write_config_dword(ptr_rc_dev, ext_cap + 0x4, 0x20); + + /* UnMask */ + pci_read_config_dword(ptr_rc_dev, ext_cap + 0x8, &data_32); + data_32 &= ~0x20; + pci_write_config_dword(ptr_rc_dev, ext_cap + 0x8, data_32); + } + + return NPS_E_OK; +} + +static NPS_ERROR_NO_T +_osal_mdc_savePciConfig( + const UI32_T unit) +{ + struct pci_dev *ptr_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + NPS_ERROR_NO_T rc = NPS_E_OK; + + rc = _osal_mdc_maskStatus(unit); + + if (NPS_E_OK == rc) + { + pci_save_state(ptr_dev); + } + + return rc; +} + +static NPS_ERROR_NO_T +_osal_mdc_restorePciConfig( + const UI32_T unit) +{ +#define OSAL_MDC_PCI_PRESENT_POLL_CNT (100) +#define OSAL_MDC_PCI_PRESENT_POLL_INTERVAL (10) /* ms */ + + struct pci_dev *ptr_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + UI32_T poll_cnt = 0; + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* standard: at least 100ms for link recovery */ + msleep(100); + + /* make sure pci device is there before restoring the config space */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + while ((0 == pci_device_is_present(ptr_dev)) && +#else + while ((0 == pci_dev_present(_osal_mdc_id_table)) && +#endif + (poll_cnt < OSAL_MDC_PCI_PRESENT_POLL_CNT)) + { + msleep(OSAL_MDC_PCI_PRESENT_POLL_INTERVAL); + poll_cnt++; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + if (1 == pci_device_is_present(ptr_dev)) +#else + if (1 == pci_dev_present(_osal_mdc_id_table)) +#endif + { + pci_restore_state(ptr_dev); + rc = NPS_E_OK; + } + else + { + OSAL_MDC_ERR("detect pci device failed\n"); + rc = NPS_E_OTHERS; + } + + if (NPS_E_OK == rc) + { + rc = _osal_mdc_clearStatus(unit); + } + + return (rc); +} + #endif /* End of AML_EN_I2C */ /* --------------------------------------------------------------------------- DMA */ @@ -1415,6 +1530,20 @@ osal_mdc_invalidateCache( return (NPS_E_OK); } +NPS_ERROR_NO_T +osal_mdc_savePciConfig( + const UI32_T unit) +{ + return _osal_mdc_savePciConfig(unit); +} + +NPS_ERROR_NO_T +osal_mdc_restorePciConfig( + const UI32_T unit) +{ + return _osal_mdc_restorePciConfig(unit); +} + #endif /* End of NPS_LINUX_KERNEL_MODE */ /* --------------------------------------------------------------------------- Interrupt */ @@ -1458,7 +1587,7 @@ _osal_mdc_notifyUserProcess( /* set the device bitmap. */ spin_lock_irqsave(&_osal_mdc_isr_dev_bitmap_lock, flags); - _osal_mdc_isr_dev_bitmap |= (1 << unit); + _osal_mdc_isr_dev_bitmap |= (1U << unit); spin_unlock_irqrestore(&_osal_mdc_isr_dev_bitmap_lock, flags); /* notify user process. */ @@ -2045,12 +2174,12 @@ _osal_mdc_ioctl_connectIsrCallback( { NPS_ERROR_NO_T rc = NPS_E_OK; - if (0 == (_osal_mdc_isr_init_bitmap & (1 << unit))) + if (0 == (_osal_mdc_isr_init_bitmap & (1U << unit))) { rc = osal_mdc_connectIsr(unit, NULL, ptr_data); if (NPS_E_OK == rc) { - _osal_mdc_isr_init_bitmap |= (1 << unit); + _osal_mdc_isr_init_bitmap |= (1U << unit); } } return (rc); @@ -2065,11 +2194,27 @@ _osal_mdc_ioctl_disconnectIsrCallback( _osal_mdc_notifyUserProcess(unit); osal_mdc_disconnectIsr(unit); - _osal_mdc_isr_init_bitmap &= ~(1 << unit); + _osal_mdc_isr_init_bitmap &= ~(1U << unit); return (NPS_E_OK); } +static NPS_ERROR_NO_T +_osal_mdc_ioctl_savePciConfigCallback( + const UI32_T unit, + void *ptr_data) +{ + return _osal_mdc_savePciConfig(unit); +} + +static NPS_ERROR_NO_T +_osal_mdc_ioctl_restorePciConfigCallback( + const UI32_T unit, + void *ptr_data) +{ + return _osal_mdc_restorePciConfig(unit); +} + static NPS_ERROR_NO_T _osal_mdc_registerIoctlCallback( const OSAL_MDC_IOCTL_TYPE_T type, @@ -2126,6 +2271,12 @@ _osal_mdc_initIoctl(void) _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_DISCONNECT_ISR, _osal_mdc_ioctl_disconnectIsrCallback); + + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_SAVE_PCI_CONFIG, + _osal_mdc_ioctl_savePciConfigCallback); + + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_RESTORE_PCI_CONFIG, + _osal_mdc_ioctl_restorePciConfigCallback); return (NPS_E_OK); } @@ -2221,6 +2372,8 @@ _osal_mdc_ioctl( /* type: DEINIT_DEV * DEINIT_RSRV_DMA_MEM * DISCONNECT_ISR + * SAVE_PCI_CONFIG + * RESTORE_PCI_CONFIG */ if (NPS_E_OK != ptr_cb->callback[type](unit, (void *)ptr_temp_buf)) { @@ -2308,10 +2461,10 @@ osal_mdc_module_exit(void) /* ref: _osal_mdc_ioctl_disconnectIsrCallback */ for (unit = 0; unit < NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM; unit++) { - if (0 != (_osal_mdc_isr_init_bitmap & (1 << unit))) + if (0 != (_osal_mdc_isr_init_bitmap & (1U << unit))) { osal_mdc_disconnectIsr(unit); - _osal_mdc_isr_init_bitmap &= ~(1 << unit); + _osal_mdc_isr_init_bitmap &= ~(1U << unit); } } @@ -2355,5 +2508,5 @@ osal_mdc_module_exit(void) module_init(osal_mdc_module_init); module_exit(osal_mdc_module_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Nephos"); +MODULE_AUTHOR("MediaTek"); MODULE_DESCRIPTION("SDK Kernel Module"); From 4d0b1bb4f310679f8042c90283655a72a45ae665 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 19 Mar 2020 08:50:26 -0700 Subject: [PATCH 0429/1427] [NTP] Revert change in PR 2598 (#4265) We believe that the supervisord issue in face of clock rolling backwards has been addressed. Therefore reverting change 2598 to allow ntp sync to right clock at the start up time. Signed-off-by: Ying Xie --- build_debian.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 37db2bdeb44e..80c3823c14f4 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -322,10 +322,6 @@ fi ## Disable kexec supported reboot which was installed by default sudo sed -i 's/LOAD_KEXEC=true/LOAD_KEXEC=false/' $FILESYSTEM_ROOT/etc/default/kexec -## Modifty ntp default configuration: disable initial jump (add -x), and disable -## jump when time difference is greater than 1000 seconds (remove -g). -sudo sed -i "s/NTPD_OPTS='-g'/NTPD_OPTS='-x'/" $FILESYSTEM_ROOT/etc/default/ntp - ## Remove sshd host keys, and will regenerate on first sshd start sudo rm -f $FILESYSTEM_ROOT/etc/ssh/ssh_host_*_key* sudo cp files/sshd/host-ssh-keygen.sh $FILESYSTEM_ROOT/usr/local/bin/ From 0b618ab19bb41a071fe724f06501a8a4f176d17b Mon Sep 17 00:00:00 2001 From: Myron Sosyak <49795530+msosyak@users.noreply.github.com> Date: Thu, 19 Mar 2020 10:40:14 -0700 Subject: [PATCH 0430/1427] [BFN] Fix syncd RPC compilation (#4258) * Fix BFN syncd RPC compilation * Remove empty line --- platform/barefoot/rules.mk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index 8a218b3ff169..e9294dd81399 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -20,7 +20,11 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_ONE_ABOOT) \ $(DOCKER_FPM) # Inject sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) #$(LIBSAITHRIFT_DEV_BFN) +$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) + +ifeq ($(ENABLE_SYNCD_RPC),y) +$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +endif # Runtime dependency on sai is set only for syncd $(SYNCD)_RDEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) From 3e9a64cfcc831498a61f61e1a8bf11a509716222 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Thu, 19 Mar 2020 21:36:51 +0200 Subject: [PATCH 0431/1427] [build]: Add build badge for Barefoot 201911 build (#4289) Signed-off-by: Andriy Kokhan --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f9cef7fba212..e79e697c70e1 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimag *201911*: Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/) +Barefoot: [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/) Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/) Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/) VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911) From 2d23495ef7aca0df5941202b53a00e054ffdbb10 Mon Sep 17 00:00:00 2001 From: Kalimuthu-Velappan <53821802+Kalimuthu-Velappan@users.noreply.github.com> Date: Thu, 19 Mar 2020 19:37:47 +0000 Subject: [PATCH 0432/1427] [build]: Fix for missing derived package in libream.mk durinig DPKG caching (#4287) --- rules/libteam.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/libteam.mk b/rules/libteam.mk index 02cdcbe0306a..d10d5af4fa15 100644 --- a/rules/libteam.mk +++ b/rules/libteam.mk @@ -20,14 +20,14 @@ LIBTEAMDCT = libteamdctl0_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAMDCT))) LIBTEAMDCT_DBG = libteamdctl0-dbgsym_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBTEAMDCT),$(LIBTEAMDCT_DBG))) +$(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAMDCT_DBG))) LIBTEAM_UTILS = libteam-utils_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb $(LIBTEAM_UTILS)_DEPENDS += $(LIBTEAMDCT) $(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAM_UTILS))) LIBTEAM_UTILS_DBG = libteam-utils-dbgsym_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBTEAM_UTILS),$(LIBTEAM_UTILS_DBG))) +$(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAM_UTILS_DBG))) # The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} # are archived into debug one image to facilitate debugging. From 560fd50262204ba6c86a32d0980af0840450a522 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Thu, 19 Mar 2020 14:14:47 -0700 Subject: [PATCH 0433/1427] [Monit] Delay start of monitoring for 5 minutes (#4281) --- files/image_config/monit/monitrc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/files/image_config/monit/monitrc b/files/image_config/monit/monitrc index 3c3714882dcc..74068f12d3f8 100644 --- a/files/image_config/monit/monitrc +++ b/files/image_config/monit/monitrc @@ -17,8 +17,9 @@ ## Start Monit in the background (run as a daemon): # set daemon 60 # check services at 1-minute intervals -# with start delay 240 # optional: delay the first check by 4-minutes (by -# # default Monit check immediately after Monit start) + with start delay 300 # we delay Monit to start monitoring for 5 minutes + # intentionally such that all containers and processes + # have ample time to start up. # # ## Set syslog logging. If you want to log to a standalone log file instead, From 016f3884725076f2eb5dceb02c7969484e9a915e Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Fri, 20 Mar 2020 08:02:32 +0800 Subject: [PATCH 0434/1427] Add cache build flag (#4285) * Add cache build flag * Fix bug --- Makefile.cache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.cache b/Makefile.cache index b1e5903a60b7..78ee4541a861 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -69,7 +69,7 @@ SONIC_COMMON_FILES_LIST := $(if $(wildcard cache.skip.common),, .platform slave.mk rules/functions Makefile.cache) SONIC_COMMON_FLAGS_LIST := $(CONFIGURED_PLATFORM) \ $(SONIC_DPKG_CACHE_SOURCE) $(SONIC_DEBUGGING_ON) \ - $(SONIC_PROFILING_ON) $(SONIC_SANITIZER_ON) + $(SONIC_PROFILING_ON) $(SONIC_ENABLE_SYNCD_RPC) SONIC_COMMON_DPKG_LIST := debian/control debian/changelog debian/rules \ debian/compat debian/install debian/copyright SONIC_COMMON_BASE_FILES_LIST := sonic-slave-jessie/Dockerfile.j2 sonic-slave-jessie/Dockerfile.user \ From 01f3f9286f4bce393e3f45b43689962973fcfc47 Mon Sep 17 00:00:00 2001 From: Sujin Kang Date: Thu, 19 Mar 2020 17:24:22 -0700 Subject: [PATCH 0435/1427] [fancontrol] Restart process upon unexpected exit, not entire pmon container (#4101) * fancontrol restart * Cleanup the default setting for exitcodes * Remove the unnecessary stopwaitsecs default settin --- dockers/docker-platform-monitor/critical_processes | 1 - .../docker-platform-monitor/docker-pmon.supervisord.conf.j2 | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dockers/docker-platform-monitor/critical_processes b/dockers/docker-platform-monitor/critical_processes index 4233cda34982..788ba53f3ec4 100644 --- a/dockers/docker-platform-monitor/critical_processes +++ b/dockers/docker-platform-monitor/critical_processes @@ -1,4 +1,3 @@ -fancontrol ledd xcvrd psud diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index ca5e521abec9..21b508ab8f05 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -39,9 +39,10 @@ startsecs=0 command=/usr/sbin/fancontrol priority=4 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +startsecs=10 {% if not skip_ledd %} [program:ledd] From 965e65e89975e2b281406944fc5187582d3f9c50 Mon Sep 17 00:00:00 2001 From: shilimkarvg <58078339+shilimkarvg@users.noreply.github.com> Date: Fri, 20 Mar 2020 10:13:02 +0530 Subject: [PATCH 0436/1427] [marvell]: skip ledd control (#3955) --- .../armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json b/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} From 59ea0daf35508e5e5f3fd5919626cc8fb679ae8c Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Fri, 20 Mar 2020 11:55:38 +0530 Subject: [PATCH 0437/1427] [Marvell] ARM64 Uboot Fit Image for Marvell SONIC image (#4293) marvell sonic arm64 uboot fit flattened blob file. Used by uboot as refered in this change https://github.com/Azure/sonic-buildimage/pull/4043/files#diff-f6372e5829e59e22aa068273c238ba83 Signed-off-by: Antony Rheneus --- platform/marvell-arm64/sonic_fit.its | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 platform/marvell-arm64/sonic_fit.its diff --git a/platform/marvell-arm64/sonic_fit.its b/platform/marvell-arm64/sonic_fit.its new file mode 100644 index 000000000000..9b09d4cd3d4c --- /dev/null +++ b/platform/marvell-arm64/sonic_fit.its @@ -0,0 +1,55 @@ +/dts-v1/; + +/ { + description = "U-Boot fitImage for SONIC Marvell Arm64"; + #address-cells = <1>; + + images { + kernel@0 { + description = "Linux Kernel"; + data = /incbin/("/boot/vmlinuz-4.9.0-9-2-arm64"); + type = "kernel"; + arch = "arm64"; + os = "linux"; + compression = "none"; + load = <0x6000000>; + entry = <0x6000000>; + hash@1 { + algo = "sha1"; + }; + }; + fdt@0 { + description = "Flattened Device Tree blob"; + data = /incbin/("/boot/armada-7020-comexpress.dtb"); + type = "flat_dt"; + arch = "arm64"; + compression = "none"; + hash@1 { + algo = "sha1"; + }; + }; + ramdisk@0 { + description = "ramdisk"; + data = /incbin/("/boot/initrd.img-4.9.0-9-2-arm64"); + type = "ramdisk"; + arch = "arm64"; + os = "linux"; + compression = "gzip"; + hash@1 { + algo = "sha1"; + }; + }; + }; + configurations { + default = "conf@1"; + conf@1 { + description = "Boot Linux kernel with FDT blob + ramdisk"; + kernel = "kernel@0"; + fdt = "fdt@0"; + ramdisk = "ramdisk@0"; + hash@1 { + algo = "sha1"; + }; + }; + }; +}; From e0e5f994fdee2967262337d47471d988a795404b Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 19 Mar 2020 23:26:45 -0700 Subject: [PATCH 0438/1427] [makefile] make error message clearer with instructions (#4282) * [makefile] make error message clearer with instructions Signed-off-by: Ying Xie --- Makefile.work | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.work b/Makefile.work index 4e58ab83a40d..1141226ddb35 100644 --- a/Makefile.work +++ b/Makefile.work @@ -48,7 +48,7 @@ endif # Check for j2cli availability J2_VER := $(shell j2 --version 2>&1 | grep j2cli | awk '{printf $$2}') ifeq ($(J2_VER),) -$(error Install j2cli) +$(error Please install j2cli (sudo pip install j2cli)) endif # Check for minimum Docker version on build host From e05cd1135e082316d6991634bbc4b8edc4c7dfcb Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 19 Mar 2020 23:31:25 -0700 Subject: [PATCH 0439/1427] [minigraph.py] Add support for 'OutAcl' keyword and attaching ACLs to VLAN interfaces (#4229) - Support parsing egress ACLs from minigraph file specified by the "OutAcl" element - Support attaching ACLs to VLAN interfaces --- src/sonic-config-engine/minigraph.py | 15 ++++++++++++--- src/sonic-config-engine/tests/t0-sample-graph.xml | 7 ++++++- src/sonic-config-engine/tests/test_cfggen.py | 15 ++++++++------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 3ba6362c6ff0..0f2cbfc60522 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -257,7 +257,14 @@ def parse_dpg(dpg, hname): aclintfs = child.find(str(QName(ns, "AclInterfaces"))) acls = {} for aclintf in aclintfs.findall(str(QName(ns, "AclInterface"))): - aclname = aclintf.find(str(QName(ns, "InAcl"))).text.upper().replace(" ", "_").replace("-", "_") + if aclintf.find(str(QName(ns, "InAcl"))) is not None: + aclname = aclintf.find(str(QName(ns, "InAcl"))).text.upper().replace(" ", "_").replace("-", "_") + stage = "ingress" + elif aclintf.find(str(QName(ns, "OutAcl"))) is not None: + aclname = aclintf.find(str(QName(ns, "OutAcl"))).text.upper().replace(" ", "_").replace("-", "_") + stage = "egress" + else: + system.exit("Error: 'AclInterface' must contain either an 'InAcl' or 'OutAcl' subelement.") aclattach = aclintf.find(str(QName(ns, "AttachTo"))).text.split(';') acl_intfs = [] is_mirror = False @@ -274,7 +281,7 @@ def parse_dpg(dpg, hname): # to LAG will be applied to all the LAG members internally by SAI/SDK acl_intfs.append(member) elif vlans.has_key(member): - print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a Vlan interface, which is currently not supported" + acl_intfs.append(member) elif port_alias_map.has_key(member): acl_intfs.append(port_alias_map[member]) # Give a warning if trying to attach ACL to a LAG member interface, correct way is to attach ACL to the LAG interface @@ -297,13 +304,14 @@ def parse_dpg(dpg, hname): break if acl_intfs: acls[aclname] = {'policy_desc': aclname, + 'stage': stage, 'ports': acl_intfs} if is_mirror: acls[aclname]['type'] = 'MIRROR' elif is_mirror_v6: acls[aclname]['type'] = 'MIRRORV6' else: - acls[aclname]['type'] = 'L3' + acls[aclname]['type'] = 'L3V6' if 'v6' in aclname.lower() else 'L3' else: # This ACL has no interfaces to attach to -- consider this a control plane ACL try: @@ -321,6 +329,7 @@ def parse_dpg(dpg, hname): else: acls[aclname] = {'policy_desc': aclname, 'type': 'CTRLPLANE', + 'stage': stage, 'services': [aclservice]} except: print >> sys.stderr, "Warning: Ignoring Control Plane ACL %s without type" % aclname diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index 0c641107da06..47985f870e50 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -305,7 +305,12 @@ PortChannel01;PortChannel02;PortChannel03;PortChannel04 - DataAcl + DataAclIngress + DataPlane + + + PortChannel01;PortChannel02 + DataAclEgress DataPlane diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 8288b729584c..2ae28946a905 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -104,13 +104,14 @@ def test_minigraph_acl(self): self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n" "Warning: ignore interface 'fortyGigE0/2' as it is not in the port_config.ini\n" "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" - "{'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04']}, " - "'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL'}, " - "'EVERFLOW': {'type': 'MIRROR', 'policy_desc': 'EVERFLOW', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4']}, " - "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT'}, " - "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL'}, " - "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL'}, " - "'EVERFLOWV6': {'type': 'MIRRORV6', 'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4']}}") + "{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, " + "'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW'}, " + "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT', 'stage': 'ingress'}, " + "'DATAACLINGRESS': {'stage': 'ingress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04'], 'policy_desc': 'DATAACLINGRESS'}, " + "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL', 'stage': 'ingress'}, " + "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL', 'stage': 'ingress'}, " + "'DATAACLEGRESS': {'stage': 'egress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02'], 'policy_desc': 'DATAACLEGRESS'}, " + "'EVERFLOWV6': {'stage': 'ingress', 'type': 'MIRRORV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOWV6'}}") # everflow portion is not used # def test_minigraph_everflow(self): From f88dffe95cdc5f63df5edf5ebd6a894c3830eafb Mon Sep 17 00:00:00 2001 From: ashishb-juniper <61582147+ashishb-juniper@users.noreply.github.com> Date: Fri, 20 Mar 2020 12:03:44 +0530 Subject: [PATCH 0440/1427] [platform]: Added QFX5210 readme for build and install (#4211) Signed-off-by: Ciju Rajan K Signed-off-by: Ashish Bhensdadia Co-authored-by: Ashish Kumar Bhensdadia --- .../sonic-platform-modules-juniper/README.md | 277 +++++++++++++++++- 1 file changed, 276 insertions(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-juniper/README.md b/platform/broadcom/sonic-platform-modules-juniper/README.md index 8d2820a74b2e..2b43eee68271 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/README.md +++ b/platform/broadcom/sonic-platform-modules-juniper/README.md @@ -1 +1,276 @@ -platform drivers for Juniper QFX5210 for the SONiC project +Juniper Networks Platform Support for SONiC Readme +================================================== + +This readme provides information on how to install and upgrade ONIE and SONiC images on the Juniper Networks QFX5210-64C-S switch. + +Note: The QFX5210-64C-S switch ships with ONIE and SONiC images preinstalled. + +## Purpose + +This package contains kernel drivers, a python library, and a python script to provide platform support for Juniper Networks QFX5210-64C-S switch. + +## Supported platforms + +The following Juniper Networks platform is supported for the SONiC operating system: + + - QFX5210-64C-S + + +## Installing ONIE on QFX5210-64C-S Switch + +The following information describes how to install ONIE on the Juniper Networks QFX5210-64C-S switch. + +To install ONIE on Juniper Networks QFX5210-64C-S switch, you need to: + +1. Cross compile ONIE + +To compile ONIE, you need to change the directories to "build-config" and then type "make MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all". + +For example: + +``` + $ cd build-config + $ make -j4 MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all +``` + +ONIE binaries are located at the directory /build/images. The following command shows how to navigate the directory to view the ONIE binaries: + +``` +stack@controller:~/ONIE_J/onie/build/images$ ls -rlt + +total 40740 + +-rw-rw-r-- 1 stack stack 3710240 Aug 3 12:32 juniper_x86-r0.vmlinuz -- ONIE kernel image +-rw-rw-r-- 1 stack stack 6038416 Aug 3 12:32 juniper_x86-r0.initrd -- ONIE initramfs (filesystem) +-rw-rw-r-- 1 stack stack 9811831 Aug 3 12:32 onie-updater-x86_64-juniper_x86-r0 -- ONIE self-update image for installing ONIE. +-rw-rw-r-- 1 stack stack 22151168 Aug 3 12:33 onie-recovery-x86_64-juniper_x86-r0.iso -- Recovery ISO image to create a bootable USB memory device for installing/recovery ONIE. +-rw-rw-r-- 1 stack stack 31465984 Aug 3 12:33 onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe -- Recovery PXE image used for installing ONIE using PXE Network install. +``` + + +Note: Use the following command to build a demo target: + +``` + $ make -j4 MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all demo +``` + +In addition to the above list of binary files, the following two binary files are also created: + +``` +-rw-rw---- 1 build build 12576008 Aug 19 16:30 demo-installer-x86_64-juniper_qfx5210-r0.bin +-rw-rw---- 1 build build 12576008 Aug 19 16:30 demo-diag-installer-x86_64-juniper_qfx5210-r0.bin +``` + +You can install these binary files by using the 'onie-nos-install' command to test the install / boot workflow. + +Use the following command for make clean: + +``` + $ make machine-clean MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 +``` + + +## Installing ONIE on a New QFX5210-64C-S Switch + +The following information describes on how to install ONIE on the Juniper Networks QFX5210-64C-S switch. You can do a fresh install of ONIE image on the QFX5210-64C-S switch, or recover an existing ONIE image from the QFX5210-64C-S switch that has been corrupted. + +To install ONIE on a new QFX5210-64C-S switch, you can use one of the following ONIE recovery images: + +1) ..iso -- Hybrid ISO image. +2) ..efi64.pxe -- PXE image for UEFI64 machines. + + +## Creating an ISO Recovery Image + +You can use the recovery ISO (.iso) image to create a bootable USB memory device. + +To create a bootable USB memory device, use the "dd" command on a Linux workstation as follows: + +``` + $ dd if=.iso of=/dev/sdX bs=10M +``` + +For example: + +``` + $ dd if=onie-recovery-x86_64-juniper_qfx5210-r0.iso of=/dev/sdb bs=10M +``` + +You can find the correct "/dev/sdX" by validating the "dmesg" output after inserting an USB device into the Linux workstation. + + +1) Booting from a USB Memory Device + +To boot from an external USB memory device connected to the QFX5210-64C-S switch, you need to: + +a. Insert the USB memory device to the USB port of the QFX5210-64C-S switch. + +b. Power on the QFX5210-64C-S switch and enter the BIOS configuration by pressing the Esc key, as displayed in the console screen. + +c. Set the hard drive boot order as follows: + + When you see the "Boot Option #1" displayed on the console screen, select the USB memory device: + + Boot-->Boot Option Priorities-->Boot Option #1 + + If the USB memory device name is not listed in "Boot Option #1", check the priorities in the hard drive boot order: + + Boot-->Hard Drive BBS Priorities-->Boot Option #1 + + + For example, consider "JetFlashTranscend 8GB 8.07" as the USB memory device, the boot order will display as follows: + +``` + Boot Option Priorities + + Boot Option #1 [JetFlashTranscend 8...] + + Boot Option #2 [ATP ATP IG eUSB 1100] + + Boot Option #3 [IBA GE Slot 00A0 v1543] + + Boot Option #4 [UEFI: Built-in EFI ...] +``` + +d. Go to "Save & Exit" in the BIOS screen and from the Boot Override option select the USB memory device (For example, JetFlashTranscend 8GB 8.07). + +e. After a few seconds, the QFX5210-64C-S switch would restart and boot from the USB memory device and then you will see the following on the console screen: + +``` + GNU GRUB version 2.02~beta2+e4a1fe391 + + +----------------------------------------------------------------------------+ + |*ONIE: Rescue | + | ONIE: Embed ONIE | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + +----------------------------------------------------------------------------+ + + Use the ^ and v keys to select which entry is highlighted. + Press enter to boot the selected OS, `e' to edit the commands before booting or `c' for a command-line. +``` + +f. Select "ONIE: Embed ONIE" to create a fresh partition to install ONIE automatically. + + Warning: All the data on the hard disk drive will be erased. + +g. Select "ONIE: Rescue" to enter the ONIE recovery command-line shell (Optional). + + + +2) Recovering ONIE using PXE-UEFI64 Recovery Image + +You can use the onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe image to recover the ONIE image through UEFI PXE. + + The onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe is made for the QFX5210-64C-S switch that has a PXE client which is based on UEFI64. + The onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe is a combination of grub-efi-64 and the .iso recovery image, that looks like an UEFI application. The UEFI PXE client on the QFX5210-64C-S can then boot it. + + For more information on UEFI PXE Netboot, see https://wiki.ubuntu.com/UEFI/PXE-netboot-install. + + Note: To install the PXE-UEFI64 recovery image over the network, you need to configure your DHCP server so that DHCP clients receives the onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe image as the bootfile. + + To enable IPv4 PXE boot on the QFX5210-64C-S switch: + + 1) Enter the BIOS configuration. + 2) Click "Save & Exit" menu on the "Boot Override" option. + 3) Select "UEFI: IP4 Broadcom NetXtreme Gigabit Ethernet" + +## Related Documentation for ONIE: + +The following links provide more information about ONIE: + + 1. ONIE documentation: https://opencomputeproject.github.io/onie/. + 2. How to build and install ONIE on QFX5210-64C-S switch, see https://github.com/opencomputeproject/onie/blob/master/machine/juniper/juniper_qfx5210/INSTALL. + +## SONiC Build Process: + +The instruction on how to build an ONIE compatible network operating system (NOS) installer image for Juniper Networks QFX5210-64C-S switch, and how to build docker images running inside the NOS is available at https://github.com/Azure/sonic-buildimage#usage. + + +## Install SONiC on the Juniper Networks QFX5210-64C-S switch: + +You need to copy the SONiC image sonic-broadcom.bin to the Juniper Networks QFX5210-64C-S switch. You can copy the sonic-broadcom.bin to an USB memory device and insert it to the USB port of the QFX5210-64C-S switch. You can also use the 'scp' command to copy the sonic-broadcom.bin image to the QFX5210-64C-S switch over the network. + +Note: Unmount the USB memory device after copying the sonic-broadcom.bin. For example, umount /dev/sdX, where X is the name of the drive of the USB memory device. + +Run the following command to install SONIC: + +``` +For example, +ONIE:/var/tmp # onie-nos-install /var/tmp/sonic-broadcom.bin +``` + +## Booting SONiC + +The QFX5210-64C-S switch restarts automatically after the SONiC image has been successfully installed. + +1) Select SONiC from the GRUB boot manager. + +``` + GNU GRUB version 2.02 + + +----------------------------------------------------------------------------+ + |*SONiC-OS-master.0-dirty-20190913.060138 | + | ONIE | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + +----------------------------------------------------------------------------+ + + Use the ^ and v keys to select which entry is highlighted. + Press enter to boot the selected OS, `e' to edit the commands + before booting or `c' for a command-line. +``` + +2. At the SONiC login prompt, enter the username as admin and password as YourPaSsWoRd. + +You can now start configuring the Juniper Networks QFX5210-64C-S switch running SONiC as its operating system. + + +## Upgrading SONiC image + +To upgrade the SONiC operating system to a latest version, you need to: + + 1. Copy the latest image of the SONiC image to the QFX5210-64C-S switch. + 2. Run the following command from the directory where the latest SONiC image has been copied. + +``` +$ sudo ./sonic-braodcom.bin +``` + + +## Uninstalling SONiC image + +To unintall SONiC operating system from QFX5210-64C-S switch, you need to: + + 1. Reboot the QFX5210-64C-S switch. + 2. Go to the ONIE GRUB menu and then select ONIE: Uninstall OS option to uninstall SONiC. + +For more details on drivers and platform scripts see https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README + +## Related Documentation for SONiC: + +The following links provide more information about SONiC: + 1. SONiC documentation: https://github.com/azure/sonic/wiki. + 2. Learn about QFX5210-64C-S SONiC platform: https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README + +## Viewing the Device Revision of the FRU Model from IDEEPROM + +You can view the device revisions of the FRU model from IDEEPROM by using the show platform syseeprom CLI command. + +Note: The Device version shown is the HEX ASCII equivalent of the FRU model. For example, if the device version shows 41, then the HEX ASCII equivalent is character A. From 0bc7cf29add4cd7a38ad1cb713b99eda176354f7 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Fri, 20 Mar 2020 18:08:46 -0700 Subject: [PATCH 0441/1427] [mgmt-framework]: Update submodule to take build break fix. (#4302) Brief: The community code for has been updated, which mismatched with the existing sonic-mgmt-framework. Hence it broke the build. Submodule-PR: #43 Details: The SONiC mgmt Framework, pulls down the community modules in two steps. Pull the existing; This does a transparent compile too. Then checkout the specific commit-id for each and do the final compile. The community code change broke in the compilation phase of step-1. Fix: For the two affected modules, do download only. Proper fix: As part of the next phase of changes, the mgmt-framework is moving go-submodule mode, which will ensure the download happens for the assigned commit-ids only. e.g. Refer go.mod in sonic-telemetry --- src/sonic-mgmt-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework index a4f1650d505c..3b177823d406 160000 --- a/src/sonic-mgmt-framework +++ b/src/sonic-mgmt-framework @@ -1 +1 @@ -Subproject commit a4f1650d505c14d94872bd216f218e7c752de05c +Subproject commit 3b177823d406f8ff188a9770ff0f34f4820c75fc From 20260ceb1d798abc91b074b15cf7a00249d1cc14 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 21 Mar 2020 14:21:26 -0700 Subject: [PATCH 0442/1427] [build]: add SONIC_CONFIG_BUILD_LOG_TIMESTAMP to add timestamp in build log (#4269) add timestamp in each job build log example: [01:39:21] dh clean --with autotools-dev [01:39:22] dh_auto_clean [01:39:27] make -j16 distclean Signed-off-by: Guohan Lu --- .../build_templates/sonic_debian_extension.j2 | 6 +++++- rules/config | 3 +++ rules/functions | 7 ++++++- scripts/process_log.sh | 20 +++++++++++++++++++ slave.mk | 16 +++++++-------- 5 files changed, 42 insertions(+), 10 deletions(-) create mode 100755 scripts/process_log.sh diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 50f242a0a0c4..b62d24441a7f 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -386,11 +386,13 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then fi {% if installer_images.strip() -%} +sudo mkdir $FILESYSTEM_ROOT/target +sudo mount --bind target $FILESYSTEM_ROOT/target sudo chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS info {% for image in installer_images.strip().split(' ') -%} {% set imagefilename = image.split('/')|last -%} {% set imagename = imagefilename.split('.')|first -%} -sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS load < {{image}} +sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS load -i {{image}} sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS tag {{imagename}}:latest {{imagename}}:$(sonic_get_version) {% if imagename.endswith('-dbg') %} {% set imagebasename = imagename.replace('-dbg', '') -%} @@ -398,6 +400,8 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS tag {{imagename}}:latest {{imagebasename}}:latest {% endif %} {% endfor %} +sudo umount $FILESYSTEM_ROOT/target +sudo rm -r $FILESYSTEM_ROOT/target if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then sudo umount $FILESYSTEM_ROOT/dockerfs sudo rm -fr $FILESYSTEM_ROOT/dockerfs diff --git a/rules/config b/rules/config index e319ff7fd5a9..6c9346340ff9 100644 --- a/rules/config +++ b/rules/config @@ -16,6 +16,9 @@ SONIC_CONFIG_BUILD_JOBS = 1 # Corresponding -j argument will be passed to make/dpkg commands that build separate packages SONIC_CONFIG_MAKE_JOBS = $(shell nproc) +# SONIC_CONFIG_BUILD_LOG_TIMESTAMP - add timestamp in build log +# SONIC_CONFIG_BUILD_LOG_TIMESTAMP = y + # SONIC_USE_DOCKER_BUILDKIT - use docker buildkit for build. # If set to y SONiC build system will set environment variable DOCKER_BUILDKIT=1 # to enable docker buildkit. diff --git a/rules/functions b/rules/functions index 5cdd35198820..9a656130e9c6 100644 --- a/rules/functions +++ b/rules/functions @@ -17,6 +17,10 @@ GRAY=\033[0m endif endif +ifeq ($(SONIC_CONFIG_BUILD_LOG_TIMESTAMP),y) +PROCESS_LOG_OPTION = -t +endif + # Print red colored output # call: # log_red message @@ -43,7 +47,8 @@ log_green = echo -e "$(GREEN)$(1)$(GRAY)" FLUSH_LOG = rm -f $@.log -LOG = &>> $(PROJECT_ROOT)/$@.log || { [ $$? -eq 0 ] || pushd $(PROJECT_ROOT) > /dev/null ; ./update_screen.sh -e $@ ; popd > /dev/null ; false ; } +LOG_SIMPLE = &>> $(PROJECT_ROOT)/$@.log || { [ $$? -eq 0 ] || pushd $(PROJECT_ROOT) > /dev/null ; ./update_screen.sh -e $@ ; popd > /dev/null ; false ; } +LOG = |& $(PROJECT_ROOT)/scripts/process_log.sh $(PROCESS_LOG_OPTION) &>> $(PROJECT_ROOT)/$@.log ; test $${PIPESTATUS[-2]} -eq 0 || { [ $$? -eq 0 ] || pushd $(PROJECT_ROOT) > /dev/null ; ./update_screen.sh -e $@ ; popd > /dev/null ; false ; } ############################################################################### ## Header and footer for each target diff --git a/scripts/process_log.sh b/scripts/process_log.sh new file mode 100755 index 000000000000..9977535ed812 --- /dev/null +++ b/scripts/process_log.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +add_timestamp="" + +while getopts ":t" opt; do + case $opt in + t) + add_timestamp="y" + ;; + esac +done + +while IFS= read -r line; do + if [ $add_timestamp ]; then + printf '[%s] ' "$(date +%T)" + fi + printf '%s\n' "$line" +done + + diff --git a/slave.mk b/slave.mk index 0bb571e5b70f..43de48cc5f02 100644 --- a/slave.mk +++ b/slave.mk @@ -397,13 +397,13 @@ $(addprefix $(DEBS_PATH)/, $(SONIC_DPKG_DEBS)) : $(DEBS_PATH)/% : .platform $$(a # Apply series of patches if exist if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi # Build project - pushd $($*_SRC_PATH) $(LOG) - [ ! -f ./autogen.sh ] || ./autogen.sh $(LOG) + pushd $($*_SRC_PATH) $(LOG_SIMPLE) + if [ -f ./autogen.sh ]; then ./autogen.sh $(LOG); fi $(if $($*_DPKG_TARGET), DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC} ${$*_DEB_BUILD_OPTIONS}" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --as-root -T$($*_DPKG_TARGET) $(LOG), DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC} ${$*_DEB_BUILD_OPTIONS}" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) $(LOG) ) - popd $(LOG) + popd $(LOG_SIMPLE) # Clean up if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi # Take built package(s) @@ -493,10 +493,10 @@ $(addprefix $(PYTHON_DEBS_PATH)/, $(SONIC_PYTHON_STDEB_DEBS)) : $(PYTHON_DEBS_PA # Apply series of patches if exist if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi # Build project - pushd $($*_SRC_PATH) $(LOG) + pushd $($*_SRC_PATH) $(LOG_SIMPLE) rm -rf deb_dist/* $(LOG) python setup.py --command-packages=stdeb.command bdist_deb $(LOG) - popd $(LOG) + popd $(LOG_SIMPLE) # Clean up if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi # Take built package(s) @@ -529,14 +529,14 @@ $(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) : $(PYTHON_WHEELS_PA # Skip building the target if it is already loaded from cache if [ -z '$($*_CACHE_LOADED)' ] ; then - pushd $($*_SRC_PATH) $(LOG) + pushd $($*_SRC_PATH) $(LOG_SIMPLE) # apply series of patches if exist if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; fi - [ "$($*_TEST)" = "n" ] || python$($*_PYTHON_VERSION) setup.py test $(LOG) + if [ ! "$($*_TEST)" = "n" ]; then python$($*_PYTHON_VERSION) setup.py test $(LOG); fi python$($*_PYTHON_VERSION) setup.py bdist_wheel $(LOG) # clean up if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then quilt pop -a -f; fi - popd $(LOG) + popd $(LOG_SIMPLE) mv $($*_SRC_PATH)/dist/$* $(PYTHON_WHEELS_PATH) $(LOG) # Save the target deb into DPKG cache From 94162679bbc32993d12955514548a99b32cfead7 Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Sun, 22 Mar 2020 02:55:19 +0530 Subject: [PATCH 0443/1427] [sonic-cfggen] MGMT Interface configuration (#4280) update network and broadcast address in /etc/network/interfaces Before: root@sonic:/home/admin# ifconfig eth0 eth0: flags=4163 mtu 1500 inet 10.28.32.73 netmask 255.255.254.0 broadcast 0.0.0.0 <<<<< After: root@sonic:~# ifconfig eth0 eth0: flags=4163 mtu 1500 inet 10.28.32.73 netmask 255.255.254.0 broadcast 10.28.33.255 <<<<< Signed-off-by: Antony Rheneus --- files/image_config/interfaces/interfaces.j2 | 2 ++ src/sonic-config-engine/sonic-cfggen | 2 +- src/sonic-config-engine/tests/sample_output/interfaces | 4 ++++ src/sonic-config-engine/tests/sample_output/mvrf_interfaces | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index dbb2b1f3418a..0e852a1150fb 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -64,6 +64,8 @@ iface {{ port }} inet6 dhcp iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static address {{ prefix | ip }} netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }} + network {{ prefix | network }} + broadcast {{ prefix | broadcast }} {% set vrf_table = 'default' %} {% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} {% set vrf_table = '5000' %} diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 34f5a36f0fe3..13fc871d775a 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -286,7 +286,7 @@ def main(): env.filters['unique_name'] = unique_name env.filters['pfx_filter'] = pfx_filter env.filters['ip_network'] = ip_network - for attr in ['ip', 'network', 'prefixlen', 'netmask']: + for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']: env.filters[attr] = partial(prefix_attr, attr) template = env.get_template(template_file) print(template.render(sort_data(data))) diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index 913fc8531443..07fd7a522c3b 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -12,6 +12,8 @@ auto eth0 iface eth0 inet static address 10.0.0.100 netmask 255.255.255.0 + network 10.0.0.0 + broadcast 10.0.0.255 ########## management network policy routing rules # management port up rules up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 @@ -24,6 +26,8 @@ iface eth0 inet static iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 + network 2603:10e2:0:2902:: + broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff ########## management network policy routing rules # management port up rules up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table default metric 201 diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces index 7bd664d4a9db..633d8aa4498d 100644 --- a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces @@ -21,6 +21,8 @@ auto eth0 iface eth0 inet static address 10.0.0.100 netmask 255.255.255.0 + network 10.0.0.0 + broadcast 10.0.0.255 vrf mgmt ########## management network policy routing rules # management port up rules @@ -37,6 +39,8 @@ iface eth0 inet static iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 + network 2603:10e2:0:2902:: + broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff vrf mgmt ########## management network policy routing rules # management port up rules From c9059992a00eeadec6a5dab9c963bcbc60144b5c Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Sun, 22 Mar 2020 05:26:55 +0800 Subject: [PATCH 0444/1427] [AS9716-32D]:Support 0x57 and 0x56 eeprom (#4103) * [AS9716-32D]:Support 0x57 and 0x56 eeprom * Add checking sysfs use 0x57 or 0x56 Co-authored-by: Jostar Yang --- .../plugins/eeprom.py | 15 +++++++++- .../utils/accton_as9716_32d_util.py | 28 +++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py index 1e7d1046d93d..bb125d3c0cbb 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py @@ -14,8 +14,21 @@ except ImportError, e: raise ImportError (str(e) + "- required module not found") +def eeprom_check(): + filepath="/sys/bus/i2c/devices/0-0057/eeprom" + if os.path.isfile(filepath): + return 1 #now board, 0x57 + else: + return 0 #now board, 0x56 + class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 def __init__(self, name, path, cpld_root, ro): - self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" + ret=eeprom_check() + if ret==1: + self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + else: + self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py index 7ccf05a798a0..2eac0e5e704d 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py @@ -123,13 +123,14 @@ # PSU-2 'echo as9716_32d_psu2 0x51 > /sys/bus/i2c/devices/i2c-10/new_device', 'echo acbel_fsh082 0x59 > /sys/bus/i2c/devices/i2c-10/new_device', +] #EERPOM +eeprom_mknod =[ +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device', 'echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', ] - - FORCE = 0 logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) logging.basicConfig(level=logging.INFO) @@ -301,8 +302,14 @@ def driver_uninstall(): return status return 0 +def eeprom_check(): + cmd = "i2cget -y -f 0 0x57" + status, output = commands.getstatusoutput(cmd) + return status + def device_install(): global FORCE + global use_57_eeprom for i in range(0,len(mknod)): #for pca954x need times to built new i2c buses @@ -315,6 +322,12 @@ def device_install(): if FORCE == 0: return status + ret=eeprom_check() + if ret==0: + log_os_system(eeprom_mknod[0], 1) #new board, 0x57 eeprom + else: + log_os_system(eeprom_mknod[1], 1) #old board, 0x56 eeprom + for i in range(0,len(sfp_map)): status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) if status: @@ -358,6 +371,17 @@ def device_uninstall(): if FORCE == 0: return status + ret=eeprom_check() + if ret==0: + target = eeprom_mknod[0] #0x57 + else: + target = eeprom_mknod[1] #0x56 + + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + return def system_ready(): From 3e6899004c0e2d29f8c834e7ee59caa967257241 Mon Sep 17 00:00:00 2001 From: CharlieChenEC <49221644+CharlieChenEC@users.noreply.github.com> Date: Sun, 22 Mar 2020 09:47:31 +0800 Subject: [PATCH 0445/1427] [docker/brcm-syncd-rpc]: remove duplicated "--net" options in broadcom syncd rpc (#4296) In the file "files/build_templates/docker_image_ctl.j2", it adds the option "--net" to the docker create command through the commit "abe7ef7e2e2e1215c97cee19a83aab0b130cebe5" (#3856). Remove the "--net" option in "docker-syncd-brcm-rpc.mk" to avoid specifying duplicated "--net" options. Signed-off-by: charlie_chen --- platform/broadcom/docker-syncd-brcm-rpc.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/broadcom/docker-syncd-brcm-rpc.mk b/platform/broadcom/docker-syncd-brcm-rpc.mk index 355d7e0f1f8c..b1a58232927d 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc.mk +++ b/platform/broadcom/docker-syncd-brcm-rpc.mk @@ -18,7 +18,7 @@ SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM_RPC) endif $(DOCKER_SYNCD_BRCM_RPC)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd From f90bf8fe622525da5fb24cbac713de05f079ad25 Mon Sep 17 00:00:00 2001 From: RayWang910012 Date: Sun, 22 Mar 2020 09:48:17 +0800 Subject: [PATCH 0446/1427] [monit]: monit_telemetry which will have error when telemetry is in secure mode (#4286) When telemetry is in secure mode ,the monitor will have error log of the match string "--insecure". So I modify to be compatiable with insecure mode and secure mode. Co-authored-by: Ubuntu --- .../docker-sonic-telemetry/base_image_files/monit_telemetry | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry index 555822c57f80..a82c652f8179 100644 --- a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry +++ b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry @@ -4,8 +4,8 @@ ## telemetry ## dialout_client ############################################################################### -check process telemetry matching "/usr/sbin/telemetry -logtostderr --insecure" +check process telemetry matching "/usr/sbin/telemetry" if does not exist for 5 times within 5 cycles then alert -check process dialout_client matching "/usr/sbin/dialout_client_cli -insecure -logtostderr" +check process dialout_client matching "/usr/sbin/dialout_client_cli" if does not exist for 5 times within 5 cycles then alert From cfe754f665ffa4385c49d0124730c04bbbcff82f Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Sat, 21 Mar 2020 18:50:12 -0700 Subject: [PATCH 0447/1427] [ntp]: Add "tinker panic 0" in ntp.conf to avoid ntpd from panic (#4263) - What I did Add configuration to avoid ntpd from panic and exit if the drift between new time and current system time is large. - How I did it Added "tinker panic 0" in ntp.conf file. - How to verify it [this assumes that there is a valid NTP server IP in config_db/ntp.conf] Change the current system time to a bad time with a large drift from time in ntp server; drift should be greater than 1000s. Reboot the device. Before the fix: 3. upon reboot, ntp-config service comes up fine, ntp service goes to active(exited) state without any error message. This is because the offset between new time (from ntp server) and the current system time is very large, ntpd goes to panic mode and exits. The system continues to show the bad time. After the fix: 3. Upon reboot, ntp-config comes up fine, ntp services comes up from and stays in active (running) state. The system clock gets synced with the ntp server time. --- files/image_config/ntp/ntp.conf.j2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index cef6527fc28f..dbde694432e6 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -5,6 +5,10 @@ # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help +# To avoid ntpd from panic and exit if the drift between new time and +# current system time is large. +tinker panic 0 + driftfile /var/lib/ntp/ntp.drift From 1038182f3ddbd26a0474c320ae74f4eff4610ab3 Mon Sep 17 00:00:00 2001 From: Srideep Date: Sun, 22 Mar 2020 00:40:08 -0600 Subject: [PATCH 0448/1427] [DellEMC]: Support to add new HWSKU DellEMC-Z9332f-C32 (#4054) TH3 related NPU config files to configure switch in 32x100G LED Firmware support --- .../DellEMC-Z9332f-C32/buffers.json.j2 | 2 + .../DellEMC-Z9332f-C32/buffers_defaults_t0.j2 | 20 + .../DellEMC-Z9332f-C32/buffers_defaults_t1.j2 | 20 + .../DellEMC-Z9332f-C32/custom_led.bin | Bin 0 -> 920 bytes .../DellEMC-Z9332f-C32/linkscan_led_fw.bin | Bin 0 -> 4752 bytes .../DellEMC-Z9332f-C32/port_config.ini | 35 + .../DellEMC-Z9332f-C32/qos.json.j2 | 225 ++++ .../qos.json.j2.pfc.reference | 227 ++++ .../DellEMC-Z9332f-C32/sai.profile | 1 + .../DellEMC-Z9332f-C32/sai_postinit_cmd.soc | 995 ++++++++++++++++++ .../DellEMC-Z9332f-C32/sai_preinit_cmd.soc | 3 + .../th3-z9332f-32x100G.config.bcm | 519 +++++++++ .../pmon_daemon_control.json | 3 + 13 files changed, 2050 insertions(+) create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers.json.j2 create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t0.j2 create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/custom_led.bin create mode 100755 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/linkscan_led_fw.bin create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/port_config.ini create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2 create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2.pfc.reference create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_postinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/pmon_daemon_control.json diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers.json.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..77747f6403c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t0.j2 @@ -0,0 +1,20 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + }, + "BUFFER_PROFILE": { + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..77747f6403c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t1.j2 @@ -0,0 +1,20 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + }, + "BUFFER_PROFILE": { + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/custom_led.bin b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..3ee9545e28ae08c5b597570c490af69a5d1f2bb4 GIT binary patch literal 920 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 X`cUsHXR!vGk^Z4y?GFw9z}SBSTZoUr literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/port_config.ini b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/port_config.ini new file mode 100644 index 000000000000..d7d83ae21e76 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias index speed +Ethernet0 33,34,35,36 hundredGigE1/1 1 100000 +Ethernet8 41,42,43,44 hundredGigE1/2 2 100000 +Ethernet16 49,50,51,52 hundredGigE1/3 3 100000 +Ethernet24 57,58,59,60 hundredGigE1/4 4 100000 +Ethernet32 65,66,67,68 hundredGigE1/5 5 100000 +Ethernet40 73,74,75,76 hundredGigE1/6 6 100000 +Ethernet48 81,82,83,84 hundredGigE1/7 7 100000 +Ethernet56 89,90,91,92 hundredGigE1/8 8 100000 +Ethernet64 1,2,3,4 hundredGigE1/9 9 100000 +Ethernet72 9,10,11,12 hundredGigE1/10 10 100000 +Ethernet80 17,18,19,20 hundredGigE1/11 11 100000 +Ethernet88 25,26,27,28 hundredGigE1/12 12 100000 +Ethernet96 97,98,99,100 hundredGigE1/13 13 100000 +Ethernet104 105,106,107,108 hundredGigE1/14 14 100000 +Ethernet112 113,114,115,116 hundredGigE1/15 15 100000 +Ethernet120 121,122,123,124 hundredGigE1/16 16 100000 +Ethernet128 129,130,131,132 hundredGigE1/17 17 100000 +Ethernet136 137,138,139,140 hundredGigE1/18 18 100000 +Ethernet144 145,146,147,148 hundredGigE1/19 19 100000 +Ethernet152 153,154,155,156 hundredGigE1/20 20 100000 +Ethernet160 225,226,227,228 hundredGigE1/21 21 100000 +Ethernet168 233,234,235,236 hundredGigE1/22 22 100000 +Ethernet176 241,242,243,244 hundredGigE1/23 23 100000 +Ethernet184 249,250,251,252 hundredGigE1/24 24 100000 +Ethernet192 161,162,163,164 hundredGigE1/25 25 100000 +Ethernet200 169,170,171,172 hundredGigE1/26 26 100000 +Ethernet208 177,178,179,180 hundredGigE1/27 27 100000 +Ethernet216 185,186,187,188 hundredGigE1/28 28 100000 +Ethernet224 193,194,195,196 hundredGigE1/29 29 100000 +Ethernet232 201,202,203,204 hundredGigE1/30 30 100000 +Ethernet240 209,210,211,212 hundredGigE1/31 31 100000 +Ethernet248 217,218,219,220 hundredGigE1/32 32 100000 +Ethernet256 257 tenGigE1/33 33 10000 +Ethernet257 258 tenGigE1/34 34 10000 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2 new file mode 100644 index 000000000000..f6b7ac977f7b --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2 @@ -0,0 +1,225 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "0", + "4": "0", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "STRICT" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2.pfc.reference b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2.pfc.reference new file mode 100644 index 000000000000..1756f106cc71 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2.pfc.reference @@ -0,0 +1,227 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "STRICT" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "pfc_enable" : "3,4", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile new file mode 100644 index 000000000000..1c58f69c7e03 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-z9332f-32x100G.config.bcm diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_postinit_cmd.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_postinit_cmd.soc new file mode 100644 index 000000000000..52793ea0147f --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_postinit_cmd.soc @@ -0,0 +1,995 @@ +delay 200 +link off +counter off +local port ce0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce1 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce2 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce3 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce4 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce5 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce6 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x38 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce7 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce8 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce9 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce10 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce11 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce12 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce13 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x34 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce14 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x34 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x30 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce15 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x30 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x2C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x2C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce16 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x30 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x30 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce17 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x30 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce18 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x38 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce19 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x34 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce20 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + + +delay 10 +local port ce21 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce22 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce23 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce24 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce25 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x38 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce26 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce27 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3E +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce28 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce29 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce30 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce31 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x4E +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 +link on +counter on diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_preinit_cmd.soc new file mode 100644 index 000000000000..920cd33016b4 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_preinit_cmd.soc @@ -0,0 +1,3 @@ +#Not supported in current SAI version +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm new file mode 100644 index 000000000000..c3f472b41294 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm @@ -0,0 +1,519 @@ +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 + +#firmware load method, use fast load +load_firmware=0x2 + +ccm_dma_enable=0 +ccmdma_intr_enable=0 +mem_cache_enable=0 +phy_enable=0 +phy_null=1 + +dport_map_enable=1 + +module_64ports.0=0 +tdma_intr_enable.0=1 +ipv6_lpm_128b_enable.0=1 +stat_if_parity_enable.0=1 +oversubscribe_mode=0 +bcm_tunnel_term_compatible_mode.0=1 +table_dma_enable.0=1 +schan_intr_enable.0=0 +parity_enable.0=1 +tdma_timeout_usec=1000000 +lls_num_l2uc.0=10 +miim_intr_enable.0=0 +table_dma_enable=1 +max_vp_lags.0=0 +tdma_intr_enable=1 +tdma_timeout_usec.0=5000000 +parity_correction.0=1 +mmu_lossless.0=0 +bcm_num_cos=8 +default_cpu_tx_queue=7 +pktdma_poll_mode_channel_bitmap=1 +l3_max_ecmp_mode.0=1 +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 + +l2xlrn_thread_interval=50000 +l2xlrn_intr_en=0 + +pbmp_xport_xe=0x1ffffffFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + +phy_an_c73=3 + +portmap_1.0=1:100:4 +portmap_5.0=9:100:4 +portmap_10.0=17:100:4 +portmap_14.0=25:100:4 + +portmap_20.0=33:100:4 +portmap_24.0=41:100:4 +portmap_29.0=49:100:4 +portmap_33.0=57:100:4 + +portmap_40.0=65:100:4 +portmap_44.0=73:100:4 +portmap_49.0=81:100:4 +portmap_53.0=89:100:4 + +portmap_60.0=97:100:4 +portmap_64.0=105:100:4 +portmap_69.0=113:100:4 +portmap_73.0=121:100:4 + +portmap_80.0=129:100:4 +portmap_84.0=137:100:4 +portmap_89.0=145:100:4 +portmap_93.0=153:100:4 + +portmap_100.0=161:100:4 +portmap_104.0=169:100:4 +portmap_109.0=177:100:4 +portmap_113.0=185:100:4 + +portmap_120.0=193:100:4 +portmap_124.0=201:100:4 +portmap_129.0=209:100:4 +portmap_133.0=217:100:4 + +portmap_140.0=225:100:4 +portmap_144.0=233:100:4 +portmap_149.0=241:100:4 +portmap_153.0=249:100:4 + +portmap_38.0=257:10:1 +portmap_118.0=258:10:1 + +dport_map_port_20=1 +dport_map_port_21=2 +dport_map_port_22=3 +dport_map_port_23=4 +dport_map_port_24=5 +dport_map_port_25=6 +dport_map_port_26=7 +dport_map_port_27=8 +dport_map_port_28=9 +dport_map_port_29=10 +dport_map_port_30=11 +dport_map_port_31=12 +dport_map_port_32=13 +dport_map_port_33=14 +dport_map_port_34=15 +dport_map_port_35=16 +dport_map_port_36=17 +dport_map_port_37=18 +dport_map_port_40=19 +dport_map_port_41=20 +dport_map_port_42=21 +dport_map_port_43=22 +dport_map_port_44=23 +dport_map_port_45=24 +dport_map_port_46=25 +dport_map_port_47=26 +dport_map_port_48=27 +dport_map_port_49=28 +dport_map_port_50=29 +dport_map_port_51=30 +dport_map_port_52=31 +dport_map_port_53=32 +dport_map_port_54=33 +dport_map_port_55=34 +dport_map_port_56=35 +dport_map_port_57=36 +dport_map_port_1=37 +dport_map_port_2=38 +dport_map_port_3=39 +dport_map_port_4=40 +dport_map_port_5=41 +dport_map_port_6=42 +dport_map_port_7=43 +dport_map_port_8=44 +dport_map_port_9=45 +dport_map_port_10=46 +dport_map_port_11=47 +dport_map_port_12=48 +dport_map_port_13=49 +dport_map_port_14=50 +dport_map_port_15=51 +dport_map_port_16=52 +dport_map_port_17=53 +dport_map_port_18=54 +dport_map_port_60=55 +dport_map_port_61=56 +dport_map_port_62=57 +dport_map_port_63=58 +dport_map_port_64=59 +dport_map_port_65=60 +dport_map_port_66=61 +dport_map_port_67=62 +dport_map_port_68=63 +dport_map_port_69=64 +dport_map_port_70=65 +dport_map_port_71=66 +dport_map_port_72=67 +dport_map_port_73=68 +dport_map_port_74=69 +dport_map_port_75=70 +dport_map_port_76=71 +dport_map_port_77=72 +dport_map_port_80=73 +dport_map_port_81=74 +dport_map_port_82=75 +dport_map_port_83=76 +dport_map_port_84=77 +dport_map_port_85=78 +dport_map_port_86=79 +dport_map_port_87=80 +dport_map_port_88=81 +dport_map_port_89=82 +dport_map_port_90=83 +dport_map_port_91=84 +dport_map_port_92=85 +dport_map_port_93=86 +dport_map_port_94=87 +dport_map_port_95=88 +dport_map_port_96=89 +dport_map_port_97=90 +dport_map_port_140=91 +dport_map_port_141=92 +dport_map_port_142=93 +dport_map_port_143=94 +dport_map_port_144=95 +dport_map_port_145=96 +dport_map_port_146=97 +dport_map_port_147=98 +dport_map_port_148=99 +dport_map_port_149=100 +dport_map_port_150=101 +dport_map_port_151=102 +dport_map_port_152=103 +dport_map_port_153=104 +dport_map_port_154=105 +dport_map_port_155=106 +dport_map_port_156=107 +dport_map_port_157=108 +dport_map_port_100=109 +dport_map_port_101=110 +dport_map_port_102=111 +dport_map_port_103=112 +dport_map_port_104=113 +dport_map_port_105=114 +dport_map_port_106=115 +dport_map_port_107=116 +dport_map_port_108=117 +dport_map_port_109=118 +dport_map_port_110=119 +dport_map_port_111=120 +dport_map_port_112=121 +dport_map_port_113=122 +dport_map_port_114=123 +dport_map_port_115=124 +dport_map_port_116=125 +dport_map_port_117=126 +dport_map_port_120=127 +dport_map_port_121=128 +dport_map_port_122=129 +dport_map_port_123=130 +dport_map_port_124=131 +dport_map_port_125=132 +dport_map_port_126=133 +dport_map_port_127=134 +dport_map_port_128=135 +dport_map_port_129=136 +dport_map_port_130=137 +dport_map_port_131=138 +dport_map_port_132=139 +dport_map_port_133=140 +dport_map_port_134=141 +dport_map_port_135=142 +dport_map_port_136=143 +dport_map_port_137=144 +dport_map_port_38=145 +dport_map_port_118=146 + +phy_chain_rx_lane_map_physical{33.0}=0x65732041 +phy_chain_tx_lane_map_physical{33.0}=0x47206531 +phy_chain_rx_lane_map_physical{41.0}=0x07561243 +phy_chain_tx_lane_map_physical{41.0}=0x36207514 +phy_chain_rx_lane_map_physical{49.0}=0x54632071 +phy_chain_tx_lane_map_physical{49.0}=0x06241735 +phy_chain_rx_lane_map_physical{57.0}=0x07561243 +phy_chain_tx_lane_map_physical{57.0}=0x35207614 +phy_chain_rx_lane_map_physical{65.0}=0x45623170 +phy_chain_tx_lane_map_physical{65.0}=0x51260734 +phy_chain_rx_lane_map_physical{73.0}=0x07561243 +phy_chain_tx_lane_map_physical{73.0}=0x37245610 +phy_chain_rx_lane_map_physical{81.0}=0x45632071 +phy_chain_tx_lane_map_physical{81.0}=0x51260734 +phy_chain_rx_lane_map_physical{89.0}=0x07561243 +phy_chain_tx_lane_map_physical{89.0}=0x26437510 +phy_chain_rx_lane_map_physical{1.0}=0x30176524 +phy_chain_tx_lane_map_physical{1.0}=0x20615374 +phy_chain_rx_lane_map_physical{9.0}=0x37562041 +phy_chain_tx_lane_map_physical{9.0}=0x05176432 +phy_chain_rx_lane_map_physical{17.0}=0x43607251 +phy_chain_tx_lane_map_physical{17.0}=0x70261435 +phy_chain_rx_lane_map_physical{25.0}=0x60347125 +phy_chain_tx_lane_map_physical{25.0}=0x46357120 +phy_chain_rx_lane_map_physical{97.0}=0x47601352 +phy_chain_tx_lane_map_physical{97.0}=0x04265137 +phy_chain_rx_lane_map_physical{105.0}=0x73206415 +phy_chain_tx_lane_map_physical{105.0}=0x26374150 +phy_chain_rx_lane_map_physical{113.0}=0x47632051 +phy_chain_tx_lane_map_physical{113.0}=0x03254617 +phy_chain_rx_lane_map_physical{121.0}=0x63027415 +phy_chain_tx_lane_map_physical{121.0}=0x63721045 +phy_chain_rx_lane_map_physical{129.0}=0x30154627 +phy_chain_tx_lane_map_physical{129.0}=0x04735261 +phy_chain_rx_lane_map_physical{137.0}=0x24753061 +phy_chain_tx_lane_map_physical{137.0}=0x37614520 +phy_chain_rx_lane_map_physical{145.0}=0x47601352 +phy_chain_tx_lane_map_physical{145.0}=0x63274510 +phy_chain_rx_lane_map_physical{153.0}=0x07361524 +phy_chain_tx_lane_map_physical{153.0}=0x36527104 +phy_chain_rx_lane_map_physical{225.0}=0x56410273 +phy_chain_tx_lane_map_physical{225.0}=0x10274635 +phy_chain_rx_lane_map_physical{233.0}=0x15740263 +phy_chain_tx_lane_map_physical{233.0}=0x24351607 +phy_chain_rx_lane_map_physical{241.0}=0x74015263 +phy_chain_tx_lane_map_physical{241.0}=0x04152637 +phy_chain_rx_lane_map_physical{249.0}=0x62037514 +phy_chain_tx_lane_map_physical{249.0}=0x72453160 +phy_chain_rx_lane_map_physical{161.0}=0x46510273 +phy_chain_tx_lane_map_physical{161.0}=0x01653724 +phy_chain_rx_lane_map_physical{169.0}=0x25743160 +phy_chain_tx_lane_map_physical{169.0}=0x07216435 +phy_chain_rx_lane_map_physical{177.0}=0x46510273 +phy_chain_tx_lane_map_physical{177.0}=0x01652734 +phy_chain_rx_lane_map_physical{185.0}=0x25743160 +phy_chain_tx_lane_map_physical{185.0}=0x37016425 +phy_chain_rx_lane_map_physical{193.0}=0x46510372 +phy_chain_tx_lane_map_physical{193.0}=0x06153724 +phy_chain_rx_lane_map_physical{201.0}=0x25743160 +phy_chain_tx_lane_map_physical{201.0}=0x36017524 +phy_chain_rx_lane_map_physical{209.0}=0x47601352 +phy_chain_tx_lane_map_physical{209.0}=0x04152736 +phy_chain_rx_lane_map_physical{217.0}=0x26453170 +phy_chain_tx_lane_map_physical{217.0}=0x36027415 + +serdes_core_rx_polarity_flip_physical{33}=0x29 +serdes_core_tx_polarity_flip_physical{33}=0xfe +serdes_core_rx_polarity_flip_physical{41}=0xb1 +serdes_core_tx_polarity_flip_physical{41}=0xe8 +serdes_core_rx_polarity_flip_physical{49}=0xca +serdes_core_tx_polarity_flip_physical{49}=0xb6 +serdes_core_rx_polarity_flip_physical{57}=0x9b +serdes_core_tx_polarity_flip_physical{57}=0xdc +serdes_core_rx_polarity_flip_physical{65}=0x17 +serdes_core_tx_polarity_flip_physical{65}=0x86 +serdes_core_rx_polarity_flip_physical{73}=0x9b +serdes_core_tx_polarity_flip_physical{73}=0x55 +serdes_core_rx_polarity_flip_physical{81}=0xa +serdes_core_tx_polarity_flip_physical{81}=0x6 +serdes_core_rx_polarity_flip_physical{89}=0x9b +serdes_core_tx_polarity_flip_physical{89}=0x48 +serdes_core_rx_polarity_flip_physical{1}=0xec +serdes_core_tx_polarity_flip_physical{1}=0x56 +serdes_core_rx_polarity_flip_physical{9}=0x13 +serdes_core_tx_polarity_flip_physical{9}=0xa6 +serdes_core_rx_polarity_flip_physical{17}=0x5a +serdes_core_tx_polarity_flip_physical{17}=0xc6 +serdes_core_rx_polarity_flip_physical{25}=0xf +serdes_core_tx_polarity_flip_physical{25}=0x4e +serdes_core_rx_polarity_flip_physical{97}=0x17 +serdes_core_tx_polarity_flip_physical{97}=0x2e +serdes_core_rx_polarity_flip_physical{105}=0xce +serdes_core_tx_polarity_flip_physical{105}=0x7c +serdes_core_rx_polarity_flip_physical{113}=0xa +serdes_core_tx_polarity_flip_physical{113}=0x35 + +serdes_core_rx_polarity_flip_physical{121}=0xb9 +serdes_core_tx_polarity_flip_physical{121}=0xef +serdes_core_rx_polarity_flip_physical{129}=0xe8 +serdes_core_tx_polarity_flip_physical{129}=0xac +serdes_core_rx_polarity_flip_physical{137}=0xcb +serdes_core_tx_polarity_flip_physical{137}=0x9c +serdes_core_rx_polarity_flip_physical{145}=0x17 +serdes_core_tx_polarity_flip_physical{145}=0x32 +serdes_core_rx_polarity_flip_physical{153}=0xb9 +serdes_core_tx_polarity_flip_physical{153}=0xaf +serdes_core_rx_polarity_flip_physical{225}=0xaa +serdes_core_tx_polarity_flip_physical{225}=0x7 +serdes_core_rx_polarity_flip_physical{233}=0x31 +serdes_core_tx_polarity_flip_physical{233}=0x47 +serdes_core_rx_polarity_flip_physical{241}=0xe8 +serdes_core_tx_polarity_flip_physical{241}=0x9e +serdes_core_rx_polarity_flip_physical{249}=0xec +serdes_core_tx_polarity_flip_physical{249}=0x1f +serdes_core_rx_polarity_flip_physical{161}=0x6a +serdes_core_tx_polarity_flip_physical{161}=0xd4 +serdes_core_rx_polarity_flip_physical{169}=0x9e +serdes_core_tx_polarity_flip_physical{169}=0x7b +serdes_core_rx_polarity_flip_physical{177}=0x6a +serdes_core_tx_polarity_flip_physical{177}=0xcc +serdes_core_rx_polarity_flip_physical{185}=0x9e +serdes_core_tx_polarity_flip_physical{185}=0x58 +serdes_core_rx_polarity_flip_physical{193}=0x6f +serdes_core_tx_polarity_flip_physical{193}=0x24 +serdes_core_rx_polarity_flip_physical{201}=0x9e +serdes_core_tx_polarity_flip_physical{201}=0xdf +serdes_core_rx_polarity_flip_physical{209}=0x17 +serdes_core_tx_polarity_flip_physical{209}=0xe9 +serdes_core_rx_polarity_flip_physical{217}=0xec +serdes_core_tx_polarity_flip_physical{217}=0x68 + +serdes_lane_config_media_type_49=copper +serdes_lane_config_media_type_50=copper +serdes_lane_config_media_type_51=copper +serdes_lane_config_media_type_52=copper +serdes_lane_config_media_type_54=copper +serdes_lane_config_media_type_55=copper +serdes_lane_config_media_type_56=copper +serdes_lane_config_media_type_57=copper +serdes_lane_config_media_type_53=copper +serdes_lane_config_media_type_60=copper +serdes_lane_config_media_type_61=copper +serdes_lane_config_media_type_62=copper +serdes_lane_config_media_type_63=copper +serdes_lane_config_media_type_65=copper +serdes_lane_config_media_type_66=copper +serdes_lane_config_media_type_67=copper +serdes_lane_config_media_type_68=copper +serdes_lane_config_media_type_64=copper +serdes_lane_config_media_type_80=copper +serdes_lane_config_media_type_81=copper +serdes_lane_config_media_type_82=copper +serdes_lane_config_media_type_83=copper +serdes_lane_config_media_type_85=copper +serdes_lane_config_media_type_86=copper +serdes_lane_config_media_type_87=copper +serdes_lane_config_media_type_88=copper +serdes_lane_config_media_type_84=copper +serdes_lane_config_media_type_100=copper +serdes_lane_config_media_type_101=copper +serdes_lane_config_media_type_102=copper +serdes_lane_config_media_type_103=copper +serdes_lane_config_media_type_105=copper +serdes_lane_config_media_type_106=copper +serdes_lane_config_media_type_107=copper +serdes_lane_config_media_type_108=copper +serdes_lane_config_media_type_104=copper +serdes_lane_config_media_type_120=copper +serdes_lane_config_media_type_121=copper +serdes_lane_config_media_type_122=copper +serdes_lane_config_media_type_123=copper +serdes_lane_config_media_type_125=copper +serdes_lane_config_media_type_126=copper +serdes_lane_config_media_type_127=copper +serdes_lane_config_media_type_128=copper +serdes_lane_config_media_type_124=copper +serdes_lane_config_media_type_140=copper +serdes_lane_config_media_type_141=copper +serdes_lane_config_media_type_142=copper +serdes_lane_config_media_type_143=copper +serdes_lane_config_media_type_145=copper +serdes_lane_config_media_type_146=copper +serdes_lane_config_media_type_147=copper +serdes_lane_config_media_type_148=copper +serdes_lane_config_media_type_144=copper +serdes_lane_config_media_type_40=copper +serdes_lane_config_media_type_41=copper +serdes_lane_config_media_type_42=copper +serdes_lane_config_media_type_43=copper +serdes_lane_config_media_type_45=copper +serdes_lane_config_media_type_46=copper +serdes_lane_config_media_type_47=copper +serdes_lane_config_media_type_48=copper +serdes_lane_config_media_type_44=copper +serdes_lane_config_media_type_69=copper +serdes_lane_config_media_type_70=copper +serdes_lane_config_media_type_71=copper +serdes_lane_config_media_type_72=copper +serdes_lane_config_media_type_74=copper +serdes_lane_config_media_type_75=copper +serdes_lane_config_media_type_76=copper +serdes_lane_config_media_type_77=copper +serdes_lane_config_media_type_73=copper +serdes_lane_config_media_type_1=copper +serdes_lane_config_media_type_2=copper +serdes_lane_config_media_type_3=copper +serdes_lane_config_media_type_4=copper +serdes_lane_config_media_type_6=copper +serdes_lane_config_media_type_7=copper +serdes_lane_config_media_type_8=copper +serdes_lane_config_media_type_9=copper +serdes_lane_config_media_type_5=copper +serdes_lane_config_media_type_29=copper +serdes_lane_config_media_type_30=copper +serdes_lane_config_media_type_31=copper +serdes_lane_config_media_type_32=copper +serdes_lane_config_media_type_34=copper +serdes_lane_config_media_type_35=copper +serdes_lane_config_media_type_36=copper +serdes_lane_config_media_type_37=copper +serdes_lane_config_media_type_33=copper +serdes_lane_config_media_type_89=copper +serdes_lane_config_media_type_90=copper +serdes_lane_config_media_type_91=copper +serdes_lane_config_media_type_92=copper +serdes_lane_config_media_type_94=copper +serdes_lane_config_media_type_95=copper +serdes_lane_config_media_type_96=copper +serdes_lane_config_media_type_97=copper +serdes_lane_config_media_type_93=copper +serdes_lane_config_media_type_109=copper +serdes_lane_config_media_type_110=copper +serdes_lane_config_media_type_111=copper +serdes_lane_config_media_type_112=copper +serdes_lane_config_media_type_114=copper +serdes_lane_config_media_type_115=copper +serdes_lane_config_media_type_116=copper +serdes_lane_config_media_type_117=copper +serdes_lane_config_media_type_113=copper +serdes_lane_config_media_type_129=copper +serdes_lane_config_media_type_130=copper +serdes_lane_config_media_type_131=copper +serdes_lane_config_media_type_132=copper +serdes_lane_config_media_type_134=copper +serdes_lane_config_media_type_135=copper +serdes_lane_config_media_type_136=copper +serdes_lane_config_media_type_137=copper +serdes_lane_config_media_type_133=copper +serdes_lane_config_media_type_149=copper +serdes_lane_config_media_type_150=copper +serdes_lane_config_media_type_151=copper +serdes_lane_config_media_type_152=copper +serdes_lane_config_media_type_154=copper +serdes_lane_config_media_type_155=copper +serdes_lane_config_media_type_156=copper +serdes_lane_config_media_type_157=copper +serdes_lane_config_media_type_153=copper +serdes_lane_config_media_type_10=copper +serdes_lane_config_media_type_11=copper +serdes_lane_config_media_type_12=copper +serdes_lane_config_media_type_13=copper +serdes_lane_config_media_type_15=copper +serdes_lane_config_media_type_16=copper +serdes_lane_config_media_type_17=copper +serdes_lane_config_media_type_18=copper +serdes_lane_config_media_type_14=copper +serdes_lane_config_media_type_20=copper +serdes_lane_config_media_type_21=copper +serdes_lane_config_media_type_22=copper +serdes_lane_config_media_type_23=copper +serdes_lane_config_media_type_25=copper +serdes_lane_config_media_type_26=copper +serdes_lane_config_media_type_27=copper +serdes_lane_config_media_type_28=copper +serdes_lane_config_media_type_24=copper + +#sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc +sai_postinit_cmd_file=/usr/share/sonic/hwsku/sai_postinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_z9332f_d1508-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} From 3c6f23e7b7c56d9c573b6e2c9501552f3f81da70 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sun, 22 Mar 2020 09:44:48 -0700 Subject: [PATCH 0449/1427] [tacacs]: fix /etc/nsswitch.conf for buster image (#4303) in buster image, default /etc/nsswitch.conf becomes ``` passwd: files ``` when tacacs is enable, this files changes to ``` passwd: tacplus files ``` --- files/image_config/hostcfgd/hostcfgd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 4ac3be83d06e..edbbacca86c2 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -207,10 +207,10 @@ class AaaCfg(object): # Add tacplus in nsswitch.conf if TACACS+ enable if 'tacacs+' in auth['login']: if os.path.isfile(NSS_CONF): - self.modify_single_file(NSS_CONF, [ "'/tacplus/b'", "'/^passwd/s/compat/tacplus &/'"]) + self.modify_single_file(NSS_CONF, [ "'/tacplus/b'", "'/^passwd/s/compat/tacplus &/'", "'/^passwd/s/files/tacplus &/'" ]) else: if os.path.isfile(NSS_CONF): - self.modify_single_file(NSS_CONF, [ "'/^passwd/s/tacplus //'" ]) + self.modify_single_file(NSS_CONF, [ "'/^passwd/s/tacplus //g'" ]) # Set tacacs+ server in nss-tacplus conf template_file = os.path.abspath(NSS_TACPLUS_CONF_TEMPLATE) From 0dc047c32752913355eb84d68a9be8186bca714e Mon Sep 17 00:00:00 2001 From: Sangita Maity Date: Sun, 22 Mar 2020 12:30:55 -0700 Subject: [PATCH 0450/1427] [build]: add dependency of sonic-config-engine on 'sonic-platform-common' package (#3912) Signed-off-by: Sangita Maity --- rules/sonic-platform-common.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rules/sonic-platform-common.mk b/rules/sonic-platform-common.mk index 043c820743aa..d0c9366621b3 100644 --- a/rules/sonic-platform-common.mk +++ b/rules/sonic-platform-common.mk @@ -3,6 +3,7 @@ SONIC_PLATFORM_COMMON_PY2 = sonic_platform_common-1.0-py2-none-any.whl $(SONIC_PLATFORM_COMMON_PY2)_SRC_PATH = $(SRC_PATH)/sonic-platform-common $(SONIC_PLATFORM_COMMON_PY2)_PYTHON_VERSION = 2 +$(SONIC_PLATFORM_COMMON_PY2)_DEPENDS = $(SONIC_CONFIG_ENGINE) SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY2) # Als build sonic-platform-common into python3 wheel, so we can use PSU code in SNMP docker @@ -11,4 +12,5 @@ $(SONIC_PLATFORM_COMMON_PY3)_SRC_PATH = $(SRC_PATH)/sonic-platform-common $(SONIC_PLATFORM_COMMON_PY3)_PYTHON_VERSION = 3 # Synthetic dependency just to avoid race condition $(SONIC_PLATFORM_COMMON_PY3)_DEPENDS = $(SONIC_PLATFORM_COMMON_PY2) +$(SONIC_PLATFORM_COMMON_PY3)_TEST = n SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3) From 944ff080aeee5b24f5851b5317e0a9a267bad08f Mon Sep 17 00:00:00 2001 From: lguohan Date: Sun, 22 Mar 2020 22:02:28 -0700 Subject: [PATCH 0451/1427] [submodule]: update sonic-utilities (#4308) * [submodule]: update sonic-utilities * d0f8091 2020-03-22 | Revert "add support for MCLAG (#453)" (#849) (HEAD -> master, origin/master, origin/HEAD) [lguohan] * 6f54e8c 2020-03-22 | Revert "return list for _get_optional_services() (#822)" (#848) [lguohan] * f1c79d5 2020-03-22 | return list for _get_optional_services() (#822) (HEAD -> master, origin/master, origin/HEAD) [shine4chen] * 28ea21a 2020-03-21 | Fix kernel panic for irq after fast-reboot (#823) [byu343] * 727b499 2020-03-22 | [decode-syseeprom] fix getattribute check for sime platforms (#835) [Mykola F] * db78cb6 2020-03-21 | Update Command Reference with sFlow section (#841) [padmanarayana] * 780673c 2020-03-21 | explicitly specify command with underscores (#846) [lguohan] * 07dc201 2020-03-21 | [db_migrator]Do DB migration for buffer pool size change on Mellanox platform (#833) [Kebo Liu] * 9a94955 2020-03-20 | [sonic_installer] Enable ARM64 arch (#811) [arheneus@marvell.com] * 92b30c2 2020-03-18 | [config]: add syslog messages to config load_minigraph/reload (#843) [lguohan] * 4389ffe 2020-03-17 | [intfutil] set speed to 0 when interface speed is not available (#839) [Ying Xie] * 45c6c68 2020-03-17 | [Mellanox] add document for thermal control related cli (#832) [Junchao-Mellanox] * 7105400 2020-03-12 | Add kdump support for Aboot platforms (#824) [byu343] * c5c5ffc 2020-03-01 | [fwutil]: Set default socket timeout for FW download to 30 sec. (#821) [Nazarii Hnydyn] * 81c5930 2020-03-01 | Update config/show to include PFC Watchdog commands (#736) [Andriy Moroz] * 66e9dfb 2020-02-28 | [MultiDB] sonic-utilities - replace redis-cli/redis-dump with sonic-db-cli/sonic-db-dump (#810) [Dong Zhang] * 8aea564 2020-02-24 | add support for MCLAG (#453) [shine4chen] * 118620f 2020-02-23 | [reboot] make sure the reboot happens even if platform reboot failed (#819) [Ying Xie] * 40eff82 2020-02-22 | Multi-Db changes for NAT feature. (#818) [Akhilesh Samineni] * a4cb4dd 2020-02-21 | [Command-Reference.md] Unify Usage statments and Examples (including sample prompts) (#816) [Joe LeVeque] Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index ea374a7aa20e..d0f80914a088 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit ea374a7aa20edb3a1c3040f5c40422b44f896f3c +Subproject commit d0f80914a088e5081547db291d16900ab10ca740 From 440f86ee077930e8745bd91b70d21907876fcdac Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Mon, 23 Mar 2020 09:42:30 +0200 Subject: [PATCH 0452/1427] [Mellanox] Update MFT version to 4.14.0 (#4262) Signed-off-by: Noa Or --- platform/mellanox/mft.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index e6c9d9ba0ea6..229ba86b4a7b 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -1,7 +1,7 @@ # Mellanox SAI -MFT_VERSION = 4.13.5 -MFT_REVISION = 1 +MFT_VERSION = 4.14.0 +MFT_REVISION = 500 export MFT_VERSION MFT_REVISION From 4d22cd405f15985d95975fcc824a7c3e2000e2bc Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Mon, 23 Mar 2020 18:04:11 +0200 Subject: [PATCH 0453/1427] [mellanox]: Align platform API: change CPLD version representation (#4221) --- .../sonic_platform/chassis.py | 2 +- .../sonic_platform/component.py | 148 +++++++++++------- 2 files changed, 93 insertions(+), 57 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index fe8b31898387..00096eecc88c 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -154,7 +154,7 @@ def initialize_components(self): # Initialize component list from sonic_platform.component import ComponentBIOS, ComponentCPLD self._component_list.append(ComponentBIOS()) - self._component_list.append(ComponentCPLD()) + self._component_list.extend(ComponentCPLD.get_component_list()) def get_name(self): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index dc09ae4011fa..70fd96023b8c 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -18,13 +18,13 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") -#components definitions -COMPONENT_BIOS = "BIOS" -COMPONENT_CPLD = "CPLD" +ZERO = '0' +NEWLINE = '\n' class Component(ComponentBase): def __init__(self): self.name = None + self.description = None self.image_ext_name = None @@ -38,20 +38,35 @@ def get_name(self): return self.name - def _read_generic_file(self, filename, len): + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + + @staticmethod + def _read_generic_file(filename, len, ignore_errors=False): """ Read a generic file, returns the contents of the file """ - result = '' + result = None + try: with io.open(filename, 'r') as fileobj: result = fileobj.read(len) - return result except IOError as e: - raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) + if not ignore_errors: + raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) + + return result - def _get_command_result(self, cmdline): + @staticmethod + def _get_command_result(cmdline): try: proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] @@ -83,38 +98,33 @@ def _check_file_validity(self, image_path): class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + COMPONENT_FIRMWARE_EXTENSION = '.rom' + # To update BIOS requires the ONIE with version 5.2.0016 or upper ONIE_VERSION_PARSE_PATTERN = '[0-9]{4}\.[0-9]{2}-([0-9]+)\.([0-9]+)\.([0-9]+)' ONIE_VERSION_MAJOR_OFFSET = 1 ONIE_VERSION_MINOR_OFFSET = 2 ONIE_VERSION_RELEASE_OFFSET = 3 - ONIE_REQUIRED_MAJOR = "5" - ONIE_REQUIRED_MINOR = "2" - ONIE_REQUIRED_RELEASE = "0016" + ONIE_REQUIRED_MAJOR = '5' + ONIE_REQUIRED_MINOR = '2' + ONIE_REQUIRED_RELEASE = '0016' BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' BIOS_PENDING_UPDATE_PATTERN = '([0-9A-Za-z_]*.rom)[\s]*\|[\s]*bios_update' - ONIE_FW_UPDATE_CMD_ADD = "/usr/bin/onie-fw-update.sh add {}" - ONIE_FW_UPDATE_CMD_REMOVE = "/usr/bin/onie-fw-update.sh remove {}" - ONIE_FW_UPDATE_CMD_UPDATE = "/usr/bin/onie-fw-update.sh update" - ONIE_FW_UPDATE_CMD_SHOW = "/usr/bin/onie-fw-update.sh show-pending" + ONIE_FW_UPDATE_CMD_ADD = '/usr/bin/onie-fw-update.sh add {}' + ONIE_FW_UPDATE_CMD_REMOVE = '/usr/bin/onie-fw-update.sh remove {}' + ONIE_FW_UPDATE_CMD_UPDATE = '/usr/bin/onie-fw-update.sh update' + ONIE_FW_UPDATE_CMD_SHOW = '/usr/bin/onie-fw-update.sh show-pending' BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' def __init__(self): - self.name = COMPONENT_BIOS - self.image_ext_name = ".rom" - - - def get_description(self): - """ - Retrieves the description of the component - - Returns: - A string containing the description of the component - """ - return "BIOS - Basic Input/Output System" + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION def get_firmware_version(self): @@ -210,33 +220,39 @@ def install_firmware(self, image_path): print("ERROR: Installing BIOS failed due to {}".format(repr(e))) return False - print("INFO: Reboot is required to finish BIOS installation.") + print("INFO: Reboot is required to finish BIOS installation") return True class ComponentCPLD(Component): - CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' - CPLD_VERSION_MAX_LENGTH = 4 + COMPONENT_NAME = 'CPLD{}' + COMPONENT_DESCRIPTION = 'CPLD - Complex Programmable Logic Device' + COMPONENT_FIRMWARE_EXTENSION = '.vme' - CPLD_UPDATE_COMMAND = "cpldupdate --dev {} {}" - CPLD_INSTALL_SUCCESS_FLAG = "PASS!" + CPLD_NUMBER_FILE = '/var/run/hw-management/config/cpld_num' + CPLD_PART_NUMBER_FILE = '/var/run/hw-management/system/cpld{}_pn' + CPLD_VERSION_FILE = '/var/run/hw-management/system/cpld{}_version' + CPLD_VERSION_MINOR_FILE = '/var/run/hw-management/system/cpld{}_version_minor' - MST_DEVICE_PATTERN = "/dev/mst/mt[0-9]*_pciconf0" + CPLD_NUMBER_MAX_LENGTH = 1 + CPLD_PART_NUMBER_MAX_LENGTH = 6 + CPLD_VERSION_MAX_LENGTH = 2 + CPLD_VERSION_MINOR_MAX_LENGTH = 2 - def __init__(self): - self.name = COMPONENT_CPLD - self.image_ext_name = ".vme" + CPLD_PART_NUMBER_DEFAULT = ZERO + CPLD_VERSION_MINOR_DEFAULT = ZERO + CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} {}' + CPLD_INSTALL_SUCCESS_FLAG = 'PASS!' - def get_description(self): - """ - Retrieves the description of the component + MST_DEVICE_PATTERN = '/dev/mst/mt[0-9]*_pci_cr0' - Returns: - A string containing the description of the component - """ - return "CPLD - includes all CPLDs in the switch" + def __init__(self, idx): + self.idx = idx + self.name = self.COMPONENT_NAME.format(self.idx) + self.description = self.COMPONENT_DESCRIPTION + self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION def get_firmware_version(self): @@ -246,19 +262,26 @@ def get_firmware_version(self): Returns: A string containing the firmware version of the component """ - cpld_version_file_list = glob(self.CPLD_VERSION_FILE_PATTERN) - cpld_version = '' - if cpld_version_file_list: - cpld_version_file_list.sort() - for version_file in cpld_version_file_list: - version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH) - if cpld_version: - cpld_version += '.' - cpld_version += version.rstrip('\n') - else: - raise RuntimeError("Failed to get CPLD version files by matching {}".format(self.CPLD_VERSION_FILE_PATTERN)) - return cpld_version + part_number_file = self.CPLD_PART_NUMBER_FILE.format(self.idx) + version_file = self.CPLD_VERSION_FILE.format(self.idx) + version_minor_file = self.CPLD_VERSION_MINOR_FILE.format(self.idx) + + part_number = self._read_generic_file(part_number_file, self.CPLD_PART_NUMBER_MAX_LENGTH, True) + version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH) + version_minor = self._read_generic_file(version_minor_file, self.CPLD_VERSION_MINOR_MAX_LENGTH, True) + + if part_number is None: + part_number = self.CPLD_PART_NUMBER_DEFAULT + + if version_minor is None: + version_minor = self.CPLD_VERSION_MINOR_DEFAULT + + part_number = part_number.rstrip(NEWLINE).zfill(self.CPLD_PART_NUMBER_MAX_LENGTH) + version = version.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MAX_LENGTH) + version_minor = version_minor.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH) + + return "CPLD{}_REV{}{}".format(part_number, version, version_minor) def _get_mst_device(self): @@ -331,8 +354,21 @@ def install_firmware(self, image_path): raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) if success_flag: - print("INFO: Success. Refresh or power cycle is required to finish CPLD installation.") + print("INFO: Refresh or power cycle is required to finish CPLD installation") else: print("ERROR: Failed to install CPLD") return success_flag + + + @classmethod + def get_component_list(cls): + component_list = [ ] + + cpld_number = cls._read_generic_file(cls.CPLD_NUMBER_FILE, cls.CPLD_NUMBER_MAX_LENGTH) + cpld_number = cpld_number.rstrip(NEWLINE) + + for cpld_idx in xrange(1, int(cpld_number) + 1): + component_list.append(cls(cpld_idx)) + + return component_list From 760e7639351ae7ce24293323d76a9585c9eae8ee Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 23 Mar 2020 09:45:43 -0700 Subject: [PATCH 0454/1427] [build]: allow to specify timestamp format in the build log (#4311) only simple/none are supported currently Signed-off-by: Guohan Lu --- Makefile.work | 2 ++ rules/config | 5 +++-- rules/functions | 2 +- slave.mk | 5 +++++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Makefile.work b/Makefile.work index 1141226ddb35..579d35a1ed60 100644 --- a/Makefile.work +++ b/Makefile.work @@ -33,6 +33,7 @@ # * KERNEL_PROCURE_METHOD: Specifying method of obtaining kernel Debian package: download or build # * SONIC_DPKG_CACHE_METHOD: Specifying method of obtaining the Debian packages from cache: none or cache # * SONIC_DPKG_CACHE_SOURCE: Debian package cache location when cache enabled for debian packages +# * BUILD_LOG_TIMESTAMP: Set timestamp in the build log (simple/none) # ############################################################################### @@ -192,6 +193,7 @@ SONIC_BUILD_INSTRUCTION := make \ SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY) \ SONIC_ENABLE_RESTAPI=$(ENABLE_RESTAPI) \ EXTRA_JESSIE_TARGETS=$(EXTRA_JESSIE_TARGETS) \ + BUILD_LOG_TIMESTAMP=$(BUILD_LOG_TIMESTAMP) \ $(SONIC_OVERRIDE_BUILD_VARS) .PHONY: sonic-slave-build sonic-slave-bash init reset diff --git a/rules/config b/rules/config index 6c9346340ff9..70ac38e29669 100644 --- a/rules/config +++ b/rules/config @@ -16,8 +16,9 @@ SONIC_CONFIG_BUILD_JOBS = 1 # Corresponding -j argument will be passed to make/dpkg commands that build separate packages SONIC_CONFIG_MAKE_JOBS = $(shell nproc) -# SONIC_CONFIG_BUILD_LOG_TIMESTAMP - add timestamp in build log -# SONIC_CONFIG_BUILD_LOG_TIMESTAMP = y +# DEFAULT_BUILD_LOG_TIMESTAMP - add timestamp in build log +# Supported format: simple, none +DEFAULT_BUILD_LOG_TIMESTAMP = none # SONIC_USE_DOCKER_BUILDKIT - use docker buildkit for build. # If set to y SONiC build system will set environment variable DOCKER_BUILDKIT=1 diff --git a/rules/functions b/rules/functions index 9a656130e9c6..7c620f3e3f54 100644 --- a/rules/functions +++ b/rules/functions @@ -17,7 +17,7 @@ GRAY=\033[0m endif endif -ifeq ($(SONIC_CONFIG_BUILD_LOG_TIMESTAMP),y) +ifeq ($(BUILD_LOG_TIMESTAMP),simple) PROCESS_LOG_OPTION = -t endif diff --git a/slave.mk b/slave.mk index 43de48cc5f02..053382450f02 100644 --- a/slave.mk +++ b/slave.mk @@ -159,6 +159,10 @@ ifeq ($(KERNEL_PROCURE_METHOD),) override KERNEL_PROCURE_METHOD := $(DEFAULT_KERNEL_PROCURE_METHOD) endif +ifeq ($(BUILD_LOG_TIMESTAMP),) +override BUILD_LOG_TIMESTAMP := $(DEFAULT_BUILD_LOG_TIMESTAMP) +endif + MAKEFLAGS += -j $(SONIC_BUILD_JOBS) export SONIC_CONFIG_MAKE_JOBS @@ -205,6 +209,7 @@ $(info "SONIC_DEBUGGING_ON" : "$(SONIC_DEBUGGING_ON)") $(info "SONIC_PROFILING_ON" : "$(SONIC_PROFILING_ON)") $(info "KERNEL_PROCURE_METHOD" : "$(KERNEL_PROCURE_METHOD)") $(info "BUILD_TIMESTAMP" : "$(BUILD_TIMESTAMP)") +$(info "BUILD_LOG_TIMESTAMP" : "$(BUILD_LOG_TIMESTAMP)") $(info "BLDENV" : "$(BLDENV)") $(info "VS_PREPARE_MEM" : "$(VS_PREPARE_MEM)") $(info "ENABLE_SFLOW" : "$(ENABLE_SFLOW)") From 0b52be3e5f4b50bb6a58d74a38b42652d0e4c766 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Tue, 24 Mar 2020 04:00:09 +0530 Subject: [PATCH 0455/1427] DellEMC: Z9264-Platform2.0 Implementation [Reboot Cause] (#4246) - Added get_reboot_cause() API implementation in chassis.py - Added new file platform.py for platform2.0 API implementation. --- .../z9264f/scripts/z9264f_platform.sh | 13 +++++++ .../z9264f/sonic_platform/__init__.py | 2 +- .../z9264f/sonic_platform/chassis.py | 38 +++++++++++++++++++ .../z9264f/sonic_platform/platform.py | 24 ++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/platform.py diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh index a613fd080384..05f8623db0a6 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh @@ -183,6 +183,18 @@ platform_firmware_versions() echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE } +get_reboot_cause() { + REBOOT_REASON_FILE="/host/reboot-cause/platform/reboot_reason" + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + + # Handle First Boot into software version with reboot cause determination support + if [[ ! -e $REBOOT_REASON_FILE ]]; then + echo "0" > $REBOOT_REASON_FILE + else + /usr/bin/pcisysfs.py --get --offset 0x18 --res $resource | sed '1d; s/.*:\(.*\)$/\1/;' > $REBOOT_REASON_FILE + fi + /usr/bin/pcisysfs.py --set --val 0x0 --offset 0x18 --res $resource +} init_devnum @@ -194,6 +206,7 @@ if [ "$1" == "init" ]; then modprobe i2c_ocores modprobe dell_z9264f_fpga_ocores sys_eeprom "new_device" + get_reboot_cause switch_board_qsfp_mux "new_device" switch_board_qsfp "new_device" switch_board_sfp "new_device" diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py index 328d25319343..30e0d8cbfecd 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py @@ -1,3 +1,3 @@ -__all__ = ["chassis", "sfp", "eeprom"] +__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal"] from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py index 36f2ca8df264..4df8dc5df8c2 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py @@ -30,6 +30,7 @@ class Chassis(ChassisBase): DELLEMC Platform-specific Chassis class """ + REBOOT_CAUSE_PATH = "/host/reboot-cause/platform/reboot_reason" OIR_FD_PATH = "/sys/bus/pci/devices/0000:04:00.0/port_msi" oir_fd = -1 @@ -263,3 +264,40 @@ def get_system_eeprom_info(self): values. """ return self._eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + try: + with open(self.REBOOT_CAUSE_PATH) as fd: + reboot_cause = int(fd.read(), 16) + except: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + + if reboot_cause & 0x1: + return (self.REBOOT_CAUSE_POWER_LOSS, None) + elif reboot_cause & 0x2: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + elif reboot_cause & 0x4: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "PSU Shutdown") + elif reboot_cause & 0x8: + return (self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, None) + elif reboot_cause & 0x10: + return (self.REBOOT_CAUSE_WATCHDOG, None) + elif reboot_cause & 0x20: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "BMC Shutdown") + elif reboot_cause & 0x40: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Hot-Swap Shutdown") + elif reboot_cause & 0x80: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Shutdown") + elif reboot_cause & 0x100: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Cold Reboot") + else: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/platform.py new file mode 100644 index 000000000000..996d94cf5a6e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/platform.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """ + DELLEMC Platform-specific class + """ + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() From 8a6aeace6e9eb73335ab4b8afe95ea02286f9782 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Tue, 24 Mar 2020 09:39:35 +0530 Subject: [PATCH 0456/1427] [DellEMC] Fix Z9100 port index issue (#4309) --- .../z9100/sonic_platform/chassis.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index 7f4dab3a19c0..3e070d54004e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py @@ -162,6 +162,28 @@ def get_serial(self): string: Serial number of chassis """ return self._eeprom.serial_str() + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 1. + For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list)-1)) + return sfp def get_status(self): """ From a0d213cc3789382748a2c632c7a8713c72e76812 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 24 Mar 2020 00:04:36 -0700 Subject: [PATCH 0457/1427] [telemetry]: move default certs location from device metadata to telemetry (#4307) maintains backward compatibility to search original x509 location when telemetry table does not have certs Signed-off-by: Guohan Lu --- dockers/docker-sonic-telemetry/telemetry.sh | 52 +++++++++++++-------- src/sonic-config-engine/minigraph.py | 10 ++-- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 37ab4dd2d04f..b8f7fffb3ebb 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -1,34 +1,46 @@ #!/usr/bin/env bash -# Try to read telemetry and x509 config from ConfigDB. +# Try to read telemetry and certs config from ConfigDB. # Use default value if no valid config exists X509=`sonic-cfggen -d -v "DEVICE_METADATA['x509']"` -TELEMETRY=`sonic-cfggen -d -v 'TELEMETRY.keys() | join(" ") if TELEMETRY'` +gnmi=`sonic-cfggen -d -v "TELEMETRY['gnmi']"` +certs=`sonic-cfggen -d -v "TELEMETRY['certs']"` TELEMETRY_ARGS=" -logtostderr" export CVL_SCHEMA_PATH=/usr/sbin/schema -if [ -n "$X509" ]; then - SERVER_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']"` - SERVER_KEY=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']"` - if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then - TELEMETRY_ARGS+=" --insecure" - else +if [ -n "$certs" ]; then + SERVER_CRT=`sonic-cfggen -d -v "TELEMETRY['certs']['server_crt']"` + SERVER_KEY=`sonic-cfggen -d -v "TELEMETRY['certs']['server_key']"` + if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then + TELEMETRY_ARGS+=" --insecure" + else + TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " + fi + + CA_CRT=`sonic-cfggen -d -v "TELEMETRY['certs']['ca_crt']"` + if [ ! -z $CA_CRT ]; then + TELEMETRY_ARGS+=" --ca_crt $CA_CRT" + fi +elif [ -n "$X509" ]; then + SERVER_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']"` + SERVER_KEY=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']"` + if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then + TELEMETRY_ARGS+=" --insecure" + else TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " fi -else - TELEMETRY_ARGS+=" --insecure" -fi -if [ -n "$X509" ]; then - CA_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']"` - if [ ! -z $CA_CRT ]; then - TELEMETRY_ARGS+=" --ca_crt $CA_CRT" - fi + CA_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']"` + if [ ! -z $CA_CRT ]; then + TELEMETRY_ARGS+=" --ca_crt $CA_CRT" + fi +else + TELEMETRY_ARGS+=" --insecure" fi # If no configuration entry exists for TELEMETRY, create one default port -if [ -z $TELEMETRY ]; then +if [ -z "$gnmi" ]; then sonic-db-cli CONFIG_DB hset "TELEMETRY|gnmi" port 8080 fi @@ -37,14 +49,14 @@ TELEMETRY_ARGS+=" --port $PORT" CLIENT_AUTH=`sonic-cfggen -d -v "TELEMETRY['gnmi']['client_auth']"` if [ -z $CLIENT_AUTH ] || [ $CLIENT_AUTH == "false" ]; then - TELEMETRY_ARGS+=" --allow_no_client_auth" + TELEMETRY_ARGS+=" --allow_no_client_auth" fi LOG_LEVEL=`sonic-cfggen -d -v "TELEMETRY['gnmi']['log_level']"` if [ ! -z $LOG_LEVEL ]; then - TELEMETRY_ARGS+=" -v=$LOG_LEVEL" + TELEMETRY_ARGS+=" -v=$LOG_LEVEL" else - TELEMETRY_ARGS+=" -v=2" + TELEMETRY_ARGS+=" -v=2" fi exec /usr/sbin/telemetry ${TELEMETRY_ARGS} diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 0f2cbfc60522..c640d1378614 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -636,11 +636,6 @@ def parse_xml(filename, platform=None, port_config_file=None): 'hostname': hostname, 'hwsku': hwsku, 'type': current_device['type'] - }, - 'x509': { - 'server_crt': '/etc/sonic/telemetry/streamingtelemetryserver.cer', - 'server_key': '/etc/sonic/telemetry/streamingtelemetryserver.key', - 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' } } results['BGP_NEIGHBOR'] = bgp_sessions @@ -829,6 +824,11 @@ def parse_xml(filename, platform=None, port_config_file=None): 'client_auth': 'true', 'port': '50051', 'log_level': '2' + }, + 'certs': { + 'server_crt': '/etc/sonic/telemetry/streamingtelemetryserver.cer', + 'server_key': '/etc/sonic/telemetry/streamingtelemetryserver.key', + 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' } } From 6c8ed042da063fd0bc6b833a0dd3c6a36f7a1048 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Tue, 24 Mar 2020 19:32:51 +0800 Subject: [PATCH 0458/1427] Fix docker-sonic-mgmt-framework-dbg wrong dependency issue (#4314) --- rules/docker-sonic-mgmt-spytest.dep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/docker-sonic-mgmt-spytest.dep b/rules/docker-sonic-mgmt-spytest.dep index 26daffbd1afc..1f6c36eec72d 100644 --- a/rules/docker-sonic-mgmt-spytest.dep +++ b/rules/docker-sonic-mgmt-spytest.dep @@ -8,4 +8,4 @@ $(DOCKER_MGMT_SPYTEST)_CACHE_MODE := GIT_CONTENT_SHA $(DOCKER_MGMT_SPYTEST)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) $(DOCKER_MGMT_SPYTEST)_DEP_FILES := $(DEP_FILES) -$(eval $(call add_dbg_docker,$(DOCKER_MGMT_SPYTEST),$(DOCKER_MGMT_FRAMEWORK_DBG))) +$(eval $(call add_dbg_docker,$(DOCKER_MGMT_SPYTEST),$(DOCKER_MGMT_SPYTEST_DBG))) From f4ed88297ddd3e30f2784e82e4ebbe73e51e82f8 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 24 Mar 2020 20:32:52 +0800 Subject: [PATCH 0459/1427] [Mellanox] Add a new Mellanox platform x86_64-mlnx_msn4700 and new SKU ACS-MSN4700 (#3901) * add MSN4700 device files * update ACS-MSN4700 sai profile * update buffer pool size, headroom, sensor conf, port config and reboot scripts * fix ident * update sensor conf and buffer pool * [sn4700] add sku 4700 to chassis.py * [Mellanox-4700] Add 4700 info to psu and thermal platform API * update buffer config file template to the latest. update SAI profile to use 100G X 4lanes for now update port_config.ini according to the SAI profile * [Mellanox]Update the buffer configurations for 4700 * fix alignment in pg_profile_lookup.ini * add platform components file for new sku * Update device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini Co-Authored-By: Nazarii Hnydyn * remove redundant line * [Mellanox]Correct type, buffer size Co-authored-by: Nazarii Hnydyn Co-authored-by: junchao Co-authored-by: Stephen Sun --- .../ACS-MSN4700/buffers.json.j2 | 1 + .../ACS-MSN4700/buffers_defaults_t0.j2 | 106 ++++++++ .../ACS-MSN4700/buffers_defaults_t1.j2 | 106 ++++++++ .../ACS-MSN4700/pg_profile_lookup.ini | 25 ++ .../ACS-MSN4700/port_config.ini | 33 +++ .../ACS-MSN4700/qos.json.j2 | 1 + .../ACS-MSN4700/sai.profile | 1 + .../ACS-MSN4700/sai_4700_100G.xml | 244 +++++++++++++++++ .../x86_64-mlnx_msn4700-r0/default_sku | 1 + .../platform_components.json | 10 + .../x86_64-mlnx_msn4700-r0/platform_reboot | 1 + .../x86_64-mlnx_msn4700-r0/platform_wait | 1 + .../x86_64-mlnx_msn4700-r0/plugins/eeprom.py | 1 + .../x86_64-mlnx_msn4700-r0/plugins/psuutil.py | 1 + .../plugins/sfplpmget.py | 1 + .../plugins/sfplpmset.py | 1 + .../plugins/sfpreset.py | 1 + .../x86_64-mlnx_msn4700-r0/plugins/sfputil.py | 1 + .../pmon_daemon_control.json | 1 + .../x86_64-mlnx_msn4700-r0/sensors.conf | 162 +++++++++++ .../x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 | 1 + .../x86_64-mlnx_msn4700_simx-r0/default_sku | 1 + .../platform_reboot | 1 + .../x86_64-mlnx_msn4700_simx-r0/plugins | 1 + .../pmon_daemon_control.json | 5 + .../x86_64-mlnx_msn4700_simx-r0/syseeprom.hex | 256 ++++++++++++++++++ .../sonic_platform/chassis.py | 2 +- .../mlnx-platform-api/sonic_platform/psu.py | 4 +- .../sonic_platform/thermal.py | 18 +- 29 files changed, 984 insertions(+), 4 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/default_sku create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/platform_reboot create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/platform_wait create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/eeprom.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/psuutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmget.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmset.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfpreset.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfputil.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/pmon_daemon_control.json create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf create mode 120000 device/mellanox/x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 create mode 120000 device/mellanox/x86_64-mlnx_msn4700_simx-r0/default_sku create mode 120000 device/mellanox/x86_64-mlnx_msn4700_simx-r0/platform_reboot create mode 120000 device/mellanox/x86_64-mlnx_msn4700_simx-r0/plugins create mode 100644 device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json create mode 100644 device/mellanox/x86_64-mlnx_msn4700_simx-r0/syseeprom.hex diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b71e6b35fa2e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 @@ -0,0 +1,106 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '56623104' %} +{% set ingress_lossy_pool_size = '56623104' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '56623104' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + + diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..87e55d5a46e0 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 @@ -0,0 +1,106 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '36011952' %} +{% set ingress_lossy_pool_size = '36011952' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '36011952' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + + diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini new file mode 100644 index 000000000000..950cf9434967 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini @@ -0,0 +1,25 @@ +# speed cable size xon xoff threshold +1000 5m 32768 18432 14336 0 +10000 5m 32768 18432 14336 0 +25000 5m 33792 18432 15360 0 +40000 5m 33792 18432 15360 0 +50000 5m 33792 18432 15360 0 +100000 5m 35840 18432 17408 0 +200000 5m 37888 18432 19456 0 +400000 5m 43008 18432 24576 0 +1000 40m 32768 18432 14336 0 +10000 40m 34816 18432 16384 0 +25000 40m 37888 18432 19456 0 +40000 40m 40960 18432 22528 0 +50000 40m 43008 18432 24576 0 +100000 40m 53248 18432 34816 0 +200000 40m 72704 18432 54272 0 +400000 40m 112640 18432 94208 0 +1000 300m 34816 18432 16384 0 +10000 300m 48128 18432 29696 0 +25000 300m 70656 18432 52224 0 +40000 300m 93184 18432 74752 0 +50000 300m 108544 18432 90112 0 +100000 300m 183296 18432 164864 0 +200000 300m 333824 18432 315392 0 +400000 300m 634880 18432 616448 0 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini new file mode 100644 index 000000000000..1e1906ff0ef5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias +Ethernet0 0,1,2,3 etp1 +Ethernet4 4,5,6,7 etp2 +Ethernet8 8,9,10,11 etp3 +Ethernet12 12,13,14,15 etp4 +Ethernet16 16,17,18,19 etp5 +Ethernet20 20,21,22,23 etp6 +Ethernet24 24,25,26,27 etp7 +Ethernet28 28,29,30,31 etp8 +Ethernet32 32,33,34,35 etp9 +Ethernet36 36,37,38,39 etp10 +Ethernet40 40,41,42,43 etp11 +Ethernet44 44,45,46,47 etp12 +Ethernet48 48,49,50,51 etp13 +Ethernet52 52,53,54,55 etp14 +Ethernet56 56,57,58,59 etp15 +Ethernet60 60,61,62,63 etp16 +Ethernet64 64,65,66,67 etp17 +Ethernet68 68,69,70,71 etp18 +Ethernet72 72,73,74,75 etp19 +Ethernet76 76,77,78,79 etp20 +Ethernet80 80,81,82,83 etp21 +Ethernet84 84,85,86,87 etp22 +Ethernet88 88,89,90,91 etp23 +Ethernet92 92,93,94,95 etp24 +Ethernet96 96,97,98,99 etp25 +Ethernet100 100,101,102,103 etp26 +Ethernet104 104,105,106,107 etp27 +Ethernet108 108,109,110,111 etp28 +Ethernet112 112,113,114,115 etp29 +Ethernet116 116,117,118,119 etp30 +Ethernet120 120,121,122,123 etp31 +Ethernet124 124,125,126,127 etp32 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 new file mode 120000 index 000000000000..eccf286dc879 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile new file mode 100644 index 000000000000..31b3fd09ddd9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4700_100G.xml diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml new file mode 100644 index 000000000000..a76e23d5d119 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml @@ -0,0 +1,244 @@ + + + + + + 00:02:03:04:05:00 + + + 32 + + + + + 1 + 4 + 17 + 3 + 1536 + + + 5 + 4 + 16 + 3 + 1536 + + + 9 + 4 + 19 + 3 + 1536 + + + 13 + 4 + 18 + 3 + 1536 + + + 17 + 4 + 21 + 3 + 1536 + + + 21 + 4 + 20 + 3 + 1536 + + + 25 + 4 + 23 + 3 + 1536 + + + 29 + 4 + 22 + 3 + 1536 + + + 33 + 4 + 29 + 3 + 1536 + + + 37 + 4 + 28 + 3 + 1536 + + + 41 + 4 + 31 + 3 + 1536 + + + 45 + 4 + 30 + 3 + 1536 + + + 49 + 4 + 25 + 3 + 1536 + + + 53 + 4 + 24 + 3 + 1536 + + + 57 + 4 + 27 + 3 + 1536 + + + 61 + 4 + 26 + 3 + 1536 + + + 65 + 4 + 14 + 3 + 1536 + + + 69 + 4 + 15 + 3 + 1536 + + + 73 + 4 + 12 + 3 + 1536 + + + 77 + 4 + 13 + 3 + 1536 + + + 81 + 4 + 10 + 3 + 1536 + + + 85 + 4 + 11 + 3 + 1536 + + + 89 + 4 + 8 + 3 + 1536 + + + 93 + 4 + 9 + 3 + 1536 + + + 97 + 4 + 2 + 3 + 1536 + + + 101 + 4 + 3 + 3 + 1536 + + + 105 + 4 + 0 + + + 3 + + + 1536 + + + 109 + 4 + 1 + 3 + 1536 + + + 113 + 4 + 6 + 3 + 1536 + + + 117 + 4 + 7 + 3 + 1536 + + + 121 + 4 + 4 + 3 + 1536 + + + 125 + 4 + 5 + 3 + 1536 + + + + + diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/default_sku b/device/mellanox/x86_64-mlnx_msn4700-r0/default_sku new file mode 100644 index 000000000000..80e541477f79 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/default_sku @@ -0,0 +1 @@ +ACS-MSN4700 t1 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json new file mode 100644 index 000000000000..2804e29e11b1 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn4700-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_reboot new file mode 120000 index 000000000000..43c8ea567493 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_reboot @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_wait new file mode 120000 index 000000000000..4b30bd429854 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_wait @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_wait \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/eeprom.py new file mode 120000 index 000000000000..b4e2a6a61671 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/eeprom.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/psuutil.py new file mode 120000 index 000000000000..9f724238a8d5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/psuutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmget.py new file mode 120000 index 000000000000..2e84f435abd9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmget.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmset.py new file mode 120000 index 000000000000..6a88bac30467 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfpreset.py new file mode 120000 index 000000000000..fef2063e3496 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfpreset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfpreset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfputil.py new file mode 120000 index 000000000000..45909b880fc9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfputil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn4700-r0/pmon_daemon_control.json new file mode 120000 index 000000000000..435a2ce7c0ba --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pmon_daemon_control.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf new file mode 100644 index 000000000000..b4eaf76f2ec0 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf @@ -0,0 +1,162 @@ +################################################################################ +# Copyright (c) 2019 Mellanox Technologies +# +# Platform specific sensors config for SN4700 +################################################################################ + +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" + +bus "i2c-7" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-*-49" + label temp1 "Ambient Fan Side Temp (air intake)" + chip "tmp102-i2c-*-4a" + label temp1 "Ambient Port Side Temp (air exhaust)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-15-49" + label temp1 "Ambient COMEX Temp" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 4)" + chip "tps53679-i2c-*-62" + label in1 "PMIC-1 PSU 12V Rail (in)" + label in2 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail (out)" + ignore in3 + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (out)" + ignore curr2 + chip "tps53679-i2c-*-64" + label in1 "PMIC-2 PSU 12V Rail (in)" + label in2 "PMIC-2 ASIC 1.8V MAIN Rail (out)" + compute in2 (1.5)*@, @/(1.5) + label in3 "PMIC-2 ASIC 1.2V MAIN Rail (out)" + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 ASIC 1.8V MAIN Rail Pwr (out)" + label power2 "PMIC-2 ASIC 1.2V MAIN Rail Pwr (out)" + label curr1 "PMIC-2 ASIC 1.8V MAIN Rail Curr (out)" + label curr2 "PMIC-2 ASIC 1.2V MAIN Rail Curr (out)" + chip "tps53679-i2c-*-66" + label in1 "PMIC-3 PSU 12V Rail (in)" + label in2 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail (out)" + label in3 "PMIC-3 ASIC 1.8V T0_1 Rail (out)" + label temp1 "PMIC-3 Temp 1" + label temp2 "PMIC-3 Temp 2" + label power1 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail Pwr (out)" + label power2 "PMIC-3 ASIC 1.8V T0_1 Rail Pwr (out)" + label curr1 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail Curr (out)" + label curr2 "PMIC-3 ASIC 1.8V T0_1 Rail Curr (out)" + chip "tps53679-i2c-*-68" + label in1 "PMIC-4 PSU 12V Rail (in)" + label in2 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail (out)" + label in3 "PMIC-4 ASIC 1.8V T2_3 Rail (out)" + label temp1 "PMIC-4 Temp 1" + label temp2 "PMIC-4 Temp 2" + label power1 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail Pwr (out)" + label power2 "PMIC-4 ASIC 1.8V T2_3 Rail Pwr (out)" + label curr1 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail Curr (out)" + label curr2 "PMIC-4 ASIC 1.8V T2_3 Rail Curr (out)" + chip "tps53679-i2c-*-6a" + label in1 "PMIC-5 PSU 12V Rail (in)" + label in2 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail (out)" + label in3 "PMIC-5 ASIC 1.8V T4_5 Rail (out)" + label temp1 "PMIC-5 Temp 1" + label temp2 "PMIC-5 Temp 2" + label power1 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail Pwr (out)" + label power2 "PMIC-5 ASIC 1.8V T4_5 Rail Pwr (out)" + label curr1 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail Curr (out)" + label curr2 "PMIC-5 ASIC 1.8V T4_5 Rail Curr (out)" + chip "tps53679-i2c-*-6c" + label in1 "PMIC-6 PSU 12V Rail (in)" + label in2 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in3 "PMIC-6 ASIC 1.8V T6_7 Rail (out)" + label temp1 "PMIC-6 Temp 1" + label temp2 "PMIC-6 Temp 2" + label power1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power2 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr2 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (out)" + chip "tps53679-i2c-*-6e" + label in1 "PMIC-7 PSU 12V Rail (in)" + label in2 "PMIC-7 ASIC 1.2V T0_3 Rail (out)" + label in3 "PMIC-7 ASIC 1.2V T4_7 Rail (out)" + label temp1 "PMIC-7 Temp 1" + label temp2 "PMIC-7 Temp 2" + label power1 "PMIC-7 ASIC 1.2V T0_3 Rail Pwr (out)" + label power2 "PMIC-7 ASIC 1.2V T4_7 Rail Pwr (out)" + label curr1 "PMIC-7 ASIC 1.2V T0_3 Rail Curr (out)" + label curr2 "PMIC-7 ASIC 1.2V T4_7 Rail Curr (out)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tps53679-i2c-*-58" + label in1 "PMIC-8 PSU 12V Rail (in)" + label in2 "PMIC-8 COMEX 1.8V Rail (out)" + label in3 "PMIC-8 COMEX 1.05V Rail (out)" + label temp1 "PMIC-8 Temp 1" + label temp2 "PMIC-8 Temp 2" + label power1 "PMIC-8 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-8 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-8 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-8 COMEX 1.05V Rail Curr (out)" + chip "tps53679-i2c-*-61" + label in1 "PMIC-9 PSU 12V Rail (in)" + label in2 "PMIC-9 COMEX 1.2V Rail (out)" + ignore in3 + label temp1 "PMIC-9 Temp 1" + label temp2 "PMIC-9 Temp 2" + label power1 "PMIC-9 COMEX 1.2V Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-9 COMEX 1.2V Rail Curr (out)" + ignore curr2 + +# Power supplies +bus "i2c-4" "i2c-1-mux (chan_id 3)" + chip "dps460-i2c-*-58" + label in1 "PSU-1(L) 220V Rail (in)" + ignore in2 + label in3 "PSU-1(L) 12V Rail (out)" + label fan1 "PSU-1(L) Fan 1" + label temp1 "PSU-1(L) Temp 1" + label temp2 "PSU-1(L) Temp 2" + label temp3 "PSU-1(L) Temp 3" + label power1 "PSU-1(L) 220V Rail Pwr (in)" + label power2 "PSU-1(L) 12V Rail Pwr (out)" + label curr1 "PSU-1(L) 220V Rail Curr (in)" + label curr2 "PSU-1(L) 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-2(R) 220V Rail (in)" + ignore in2 + label in3 "PSU-2(R) 12V Rail (out)" + label fan1 "PSU-2(R) Fan 1" + label temp1 "PSU-2(R) Temp 1" + label temp2 "PSU-2(R) Temp 2" + label temp3 "PSU-2(R) Temp 3" + label power1 "PSU-2(R) 220V Rail Pwr (in)" + label power2 "PSU-2(R) 12V Rail Pwr (out)" + label curr1 "PSU-2(R) 220V Rail Curr (in)" + label curr2 "PSU-2(R) 12V Rail Curr (out)" + +# Chassis fans +chip "mlxreg_fan-isa-*" + label fan1 "Chassis Fan Drawer-1 Tach 1" + label fan2 "Chassis Fan Drawer-1 Tach 2" + label fan3 "Chassis Fan Drawer-2 Tach 1" + label fan4 "Chassis Fan Drawer-2 Tach 2" + label fan5 "Chassis Fan Drawer-3 Tach 1" + label fan6 "Chassis Fan Drawer-3 Tach 2" + label fan7 "Chassis Fan Drawer-4 Tach 1" + label fan8 "Chassis Fan Drawer-4 Tach 2" + label fan9 "Chassis Fan Drawer-5 Tach 1" + label fan10 "Chassis Fan Drawer-5 Tach 2" + label fan11 "Chassis Fan Drawer-6 Tach 1" + label fan12 "Chassis Fan Drawer-6 Tach 2" + +# Miscellaneous +chip "*-virtual-*" + ignore temp1 diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 new file mode 120000 index 000000000000..3f61c9909a65 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 @@ -0,0 +1 @@ +../x86_64-mlnx_msn4700-r0/ACS-MSN4700 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/default_sku b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/default_sku new file mode 120000 index 000000000000..6f72f84de680 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/default_sku @@ -0,0 +1 @@ +../x86_64-mlnx_msn4700-r0/default_sku \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/platform_reboot new file mode 120000 index 000000000000..dfaf53417665 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/platform_reboot @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700_simx-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/plugins b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/plugins new file mode 120000 index 000000000000..e98a1d3fbaeb --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/plugins @@ -0,0 +1 @@ +../x86_64-mlnx_msn4700-r0/plugins \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..40fc367acf32 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json @@ -0,0 +1,5 @@ +{ + "skip_ledd": true, + "skip_xcvrd": true, + "skip_psud": true +} diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/syseeprom.hex b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/syseeprom.hex new file mode 100644 index 000000000000..b50ffa5a0231 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/syseeprom.hex @@ -0,0 +1,256 @@ +54 6c 76 49 6e 66 6f 00 01 02 53 21 40 4d 53 4e +33 37 30 30 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 22 14 4d +53 4e 33 37 30 30 2d 56 53 32 46 00 00 00 00 00 +00 00 00 23 18 4d 54 31 38 35 31 58 30 32 39 36 +31 00 00 00 00 00 00 00 00 00 00 00 00 24 06 98 +03 9b 94 d4 80 25 13 31 32 2f 32 38 2f 32 30 31 +38 20 30 34 3a 34 32 3a 31 38 26 01 00 2a 02 00 +fe 2b 08 4d 65 6c 6c 61 6e 6f 78 fd 24 00 00 81 +19 00 16 01 01 00 56 00 00 4d 4c 4e 58 02 01 0c +05 0e 02 10 06 12 07 00 00 00 00 00 00 00 00 00 +00 fd a4 00 00 81 19 00 92 00 03 01 01 00 00 4d +54 31 38 35 31 58 30 32 39 36 31 00 00 00 00 00 +00 00 00 00 00 00 00 4d 53 4e 33 37 30 30 2d 56 +53 32 46 00 00 00 00 00 00 00 00 41 32 00 00 00 +3a 82 b8 41 6e 61 63 6f 6e 64 61 20 45 74 68 20 +32 30 30 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 70 00 00 00 0e 74 4d 53 4e 33 37 +30 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 fd 24 00 00 81 19 00 10 00 +03 05 e8 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 fd 24 00 +00 81 19 00 1e 00 11 02 85 00 00 0d 00 00 00 00 +00 00 00 98 03 9b 94 d4 80 00 fe 98 03 9b 03 00 +94 d4 80 fd 24 00 00 81 19 00 12 00 01 06 81 00 +00 00 46 00 00 08 00 06 06 06 06 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 fd 14 00 00 81 19 00 +0e 00 02 07 99 00 00 30 00 20 00 00 00 00 00 28 +40 78 38 36 5f 36 34 2d 6d 6c 6e 78 5f 6d 73 6e +33 37 30 30 2d 72 30 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 29 15 32 30 31 38 2e 31 31 2d 35 2e 32 2e 30 +30 30 38 2d 39 36 30 30 fe 04 89 cb 82 5b 00 00 +00 00 00 fe 04 72 60 7f 13 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 00096eecc88c..4c5e04b21618 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -49,7 +49,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4} +hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] class Chassis(ChassisBase): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 31887ddf4f25..5f9d529f94fb 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -37,7 +37,7 @@ # in most SKUs the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. # but there are exceptions which will be handled by the following dictionary -hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1} +hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1} psu_profile_list = [ # default filename convention { @@ -45,7 +45,7 @@ PSU_VOLTAGE : "power/psu{}_volt", PSU_POWER : "power/psu{}_power" }, - # for 3700, 3700c, 3800 + # for 3700, 3700c, 3800, 4700 { PSU_CURRENT : "power/psu{}_curr", PSU_VOLTAGE : "power/psu{}_volt_out2", diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 462267951130..424caa4b3c56 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -113,7 +113,7 @@ THERMAL_API_GET_HIGH_THRESHOLD ] -hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7} +hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8} thermal_profile_list = [ # 2700 { @@ -238,6 +238,22 @@ ] ) }, + # 4700 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 32), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_COMEX_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) + } ] From e45d07baa37545caf456af28abaecb258147ce68 Mon Sep 17 00:00:00 2001 From: tiantianlv <38775940+tiantianlv@users.noreply.github.com> Date: Wed, 25 Mar 2020 04:22:09 +0800 Subject: [PATCH 0460/1427] Load port led FW for Silverstone! (#4313) --- device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc b/device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc index 827458afefbe..3a8ac119076e 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc +++ b/device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc @@ -1,2 +1,7 @@ #The Port LED of Silverstone SONIC can't work well, after the issue is fixed by SAI, The led will start. #led auto on; led start +linkscan off +m0 load 0 0x3800 /usr/share/sonic/platform/custom.bin +sleep 10 +led auto on; led start +linkscan on From 12291b276b34e57de5261f41a80efa586e4d7e20 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar T <53558409+santhosh-kt@users.noreply.github.com> Date: Wed, 25 Mar 2020 02:22:30 +0530 Subject: [PATCH 0461/1427] DellEMC S6100 I2C Enumeration Segregation (#4312) --- .../debian/platform-modules-s6100.install | 2 + .../s6100/scripts/s6100_i2c_enumeration.sh | 263 ++++++++++++++++++ .../s6100/scripts/s6100_platform.sh | 263 +----------------- .../s6100/systemd/s6100-i2c-enumerate.service | 12 + 4 files changed, 285 insertions(+), 255 deletions(-) create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6100/systemd/s6100-i2c-enumerate.service diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install index a08f782bdfad..7f9154dbd5ec 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install @@ -1,5 +1,6 @@ s6100/scripts/iom_power_*.sh usr/local/bin s6100/scripts/s6100_platform.sh usr/local/bin +s6100/scripts/s6100_i2c_enumeration.sh usr/local/bin common/dell_i2c_utils.sh usr/local/bin common/io_rd_wr.py usr/local/bin common/nvram_rd_wr.py usr/local/bin @@ -17,6 +18,7 @@ s6100/scripts/sensors usr/bin s6100/systemd/platform-modules-s6100.service etc/systemd/system s6100/systemd/s6100-lpc-monitor.service etc/systemd/system s6100/systemd/s6100-reboot-cause.service etc/systemd/system +s6100/systemd/s6100-i2c-enumerate.service etc/systemd/system tools/flashrom/flashrom usr/local/bin/ common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh new file mode 100755 index 000000000000..04cff29ea7af --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh @@ -0,0 +1,263 @@ +#!/bin/bash + +### DellEMC S6100 I2C MUX Enumeration script + +source dell_i2c_utils.sh + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # iSMT adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus iSMT adapter at '* ]]; then + found=1 + break + fi + done + + [[ $found -eq 0 ]] && echo "cannot find iSMT" && exit 1 +} + +# Attach/Detach CPU board mux @ 0x70 +cpu_board_mux() { + case $1 in + "new_device") i2c_mux_create pca9547 0x70 $devnum 2 + ;; + "delete_device") i2c_mux_delete 0x70 $devnum + ;; + *) echo "s6100_platform: cpu_board_mux: invalid command !" + ;; + esac +} + +# Attach/Detach Switchboard MUX @ 0x71 +switch_board_mux() { + case $1 in + "new_device") i2c_mux_create pca9548 0x71 4 10 + ;; + "delete_device") i2c_mux_delete 0x71 4 + ;; + *) echo "s6100_platform: switch_board_mux : invalid command !" + ;; + esac +} + +# Attach/Detach syseeprom on CPU board +sys_eeprom() { + case $1 in + "new_device") i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-2/$1" + ;; + "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-2/$1" + ;; + *) echo "s6100_platform: sys_eeprom : invalid command !" + ;; + esac +} + +#Attach/Detach eeprom on each IOM +switch_board_eeprom() { + case $1 in + "new_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + *) echo "s6100_platform: switch_board_eeprom : invalid command !" + ;; + esac +} + +#Attach/Detach CPLD devices to drivers for each IOM +switch_board_cpld() { + case $1 in + "new_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo dell_s6100_iom_cpld 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + *) echo "s6100_platform: switch_board_cpld : invalid command !" + ;; + esac +} + +#Attach/Detach the MUX connecting all QSFPs on each IOM @0x71 and 0x72 +switch_board_qsfp_mux() { + case $1 in + "new_device") + # The mux for the QSFPs spawn {18..25}, {26..33}... {74..81} + # starting at chennel 18 and 16 channels per IOM. + channel_first=18 + for ((i=9;i>=6;i--)); + do + # 0x71 mux on the IOM 1 + mux_index=$(expr $i - 5) + echo "Attaching PCA9548 $mux_index" + i2c_mux_create pca9548 0x71 $i $channel_first + i2c_mux_create pca9548 0x72 $i $(expr $channel_first + 8) + channel_first=$(expr $channel_first + 16) + done + ;; + "delete_device") + for ((i=9;i>=6;i--)); + do + # 0x71 mux on the IOM 1 + mux_index=$(expr $i - 5) + echo "Detaching PCA9548 $mux_index" + i2c_mux_delete 0x71 $i + i2c_mux_delete 0x72 $i + done + ;; + *) echo "s6100_platform: switch_board_qsfp_mux: invalid command !" + ;; + esac +} + +#Attach/Detach the SFP modules on PCA9548_2 +switch_board_sfp() { + case $1 in + "new_device") i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + ;; + "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + ;; + *) echo "s6100_platform: switch_board_sfp: invalid command !" + ;; + esac +} + +#Add/Delete ($1) a range ($2..$3) of QSFPs +qsfp_device_mod() { + case $1 in + "new_device") for ((i=$2;i<=$3;i++)); + do + i2c_config "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") for ((i=$2;i<=$3;i++)); + do + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + *) echo "s6100_platform: qsfp_device_mod: invalid command $1:$2,$3!" + ;; + esac +} + +# Attach/Detach 16 instances of QSFP ports on each IO modules +# eeprom can dump data using below command +switch_board_qsfp() { + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-18"; then + qsfp_device_mod $1 18 33 + fi + + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-34"; then + qsfp_device_mod $1 34 49 + fi + + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-50"; then + qsfp_device_mod $1 50 65 + fi + + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-66"; then + qsfp_device_mod $1 66 81 + fi +} + +# Enable/Disable low power mode on all QSFP ports +switch_board_qsfp_lpmode() { + case $1 in + "enable") value=0xffff + ;; + "disable") value=0x0 + ;; + *) echo "s6100_platform: switch_board_qsfp_lpmode: invalid command $1!" + return + ;; + esac + echo $value > /sys/class/i2c-adapter/i2c-14/14-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-15/15-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-16/16-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-17/17-003e/qsfp_lpmode +} + +# Enable/Disable xcvr presence interrupts +xcvr_presence_interrupts() { + case $1 in + "enable") + for ((i=14;i<=17;i++)); + do + echo 0x0 > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask + done + ;; + "disable") + for ((i=14;i<=17;i++)); + do + echo 0xffff > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask + done + ;; + *) echo "s6100_platform: xcvr_presence_interrupts: invalid command !" + ;; + esac +} + +# Reset the mux tree +reset_muxes() { + local i + + # Reset the IOM muxes (if they have been already instantiated) + for ((i=14;i<=17;i++)); + do + if [[ -e /sys/class/i2c-adapter/i2c-$i/$i-003e ]]; then + echo 0xfc > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset + echo 0xff > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset + fi + done + + # Reset the switch card PCA9548A + io_rd_wr.py --set --val 0xef --offset 0x110 + io_rd_wr.py --set --val 0xff --offset 0x110 + + # Reset the CPU Card PCA9547 + io_rd_wr.py --set --val 0xfd --offset 0x20b + io_rd_wr.py --set --val 0xff --offset 0x20b +} + +init_devnum + +if [[ "$1" == "init" ]]; then + cpu_board_mux "new_device" + switch_board_mux "new_device" + sys_eeprom "new_device" + switch_board_eeprom "new_device" + switch_board_cpld "new_device" + switch_board_qsfp_mux "new_device" + switch_board_sfp "new_device" + switch_board_qsfp "new_device" + switch_board_qsfp_lpmode "disable" + xcvr_presence_interrupts "enable" +elif [[ "$1" == "deinit" ]]; then + xcvr_presence_interrupts "disable" + switch_board_sfp "delete_device" + switch_board_cpld "delete_device" + switch_board_eeprom "delete_device" + switch_board_mux "delete_device" + sys_eeprom "delete_device" + switch_board_qsfp "delete_device" + switch_board_qsfp_mux "delete_device" + cpu_board_mux "delete_device" +fi diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh index 1d974f64504a..34dc0daa4ff0 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -2,241 +2,6 @@ #platform init script for Dell S6100 -source dell_i2c_utils.sh - -init_devnum() { - found=0 - for devnum in 0 1; do - devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` - # iSMT adapter can be at either dffd0000 or dfff0000 - if [[ $devname == 'SMBus iSMT adapter at '* ]]; then - found=1 - break - fi - done - - [[ $found -eq 0 ]] && echo "cannot find iSMT" && exit 1 -} - -# Attach/Detach CPU board mux @ 0x70 -cpu_board_mux() { - case $1 in - "new_device") i2c_mux_create pca9547 0x70 $devnum 2 - ;; - "delete_device") i2c_mux_delete 0x70 $devnum - ;; - *) echo "s6100_platform: cpu_board_mux: invalid command !" - ;; - esac -} - -# Attach/Detach Switchboard MUX @ 0x71 -switch_board_mux() { - case $1 in - "new_device") i2c_mux_create pca9548 0x71 4 10 - ;; - "delete_device") i2c_mux_delete 0x71 4 - ;; - *) echo "s6100_platform: switch_board_mux : invalid command !" - ;; - esac -} - -# Attach/Detach syseeprom on CPU board -sys_eeprom() { - case $1 in - "new_device") i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-2/$1" - ;; - "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-2/$1" - ;; - *) echo "s6100_platform: sys_eeprom : invalid command !" - ;; - esac -} - -#Attach/Detach eeprom on each IOM -switch_board_eeprom() { - case $1 in - "new_device") - for ((i=14;i<=17;i++)); - do - i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" - done - ;; - "delete_device") - for ((i=14;i<=17;i++)); - do - i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" - done - ;; - *) echo "s6100_platform: switch_board_eeprom : invalid command !" - ;; - esac -} - -#Attach/Detach CPLD devices to drivers for each IOM -switch_board_cpld() { - case $1 in - "new_device") - for ((i=14;i<=17;i++)); - do - i2c_config "echo dell_s6100_iom_cpld 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" - done - ;; - "delete_device") - for ((i=14;i<=17;i++)); - do - i2c_config "echo 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" - done - ;; - *) echo "s6100_platform: switch_board_cpld : invalid command !" - ;; - esac -} - -#Attach/Detach the MUX connecting all QSFPs on each IOM @0x71 and 0x72 -switch_board_qsfp_mux() { - case $1 in - "new_device") - # The mux for the QSFPs spawn {18..25}, {26..33}... {74..81} - # starting at chennel 18 and 16 channels per IOM. - channel_first=18 - for ((i=9;i>=6;i--)); - do - # 0x71 mux on the IOM 1 - mux_index=$(expr $i - 5) - echo "Attaching PCA9548 $mux_index" - i2c_mux_create pca9548 0x71 $i $channel_first - i2c_mux_create pca9548 0x72 $i $(expr $channel_first + 8) - channel_first=$(expr $channel_first + 16) - done - ;; - "delete_device") - for ((i=9;i>=6;i--)); - do - # 0x71 mux on the IOM 1 - mux_index=$(expr $i - 5) - echo "Detaching PCA9548 $mux_index" - i2c_mux_delete 0x71 $i - i2c_mux_delete 0x72 $i - done - ;; - *) echo "s6100_platform: switch_board_qsfp_mux: invalid command !" - ;; - esac -} - -#Attach/Detach the SFP modules on PCA9548_2 -switch_board_sfp() { - case $1 in - "new_device") i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-11/$1" - i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-12/$1" - ;; - "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-11/$1" - i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-12/$1" - ;; - *) echo "s6100_platform: switch_board_sfp: invalid command !" - ;; - esac -} - -#Add/Delete ($1) a range ($2..$3) of QSFPs -qsfp_device_mod() { - case $1 in - "new_device") for ((i=$2;i<=$3;i++)); - do - i2c_config "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" - done - ;; - "delete_device") for ((i=$2;i<=$3;i++)); - do - i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" - done - ;; - *) echo "s6100_platform: qsfp_device_mod: invalid command $1:$2,$3!" - ;; - esac -} - -# Attach/Detach 16 instances of QSFP ports on each IO modules -# eeprom can dump data using below command -switch_board_qsfp() { - if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-18"; then - qsfp_device_mod $1 18 33 - fi - - if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-34"; then - qsfp_device_mod $1 34 49 - fi - - if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-50"; then - qsfp_device_mod $1 50 65 - fi - - if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-66"; then - qsfp_device_mod $1 66 81 - fi -} - -# Enable/Disable low power mode on all QSFP ports -switch_board_qsfp_lpmode() { - case $1 in - "enable") value=0xffff - ;; - "disable") value=0x0 - ;; - *) echo "s6100_platform: switch_board_qsfp_lpmode: invalid command $1!" - return - ;; - esac - echo $value > /sys/class/i2c-adapter/i2c-14/14-003e/qsfp_lpmode - echo $value > /sys/class/i2c-adapter/i2c-15/15-003e/qsfp_lpmode - echo $value > /sys/class/i2c-adapter/i2c-16/16-003e/qsfp_lpmode - echo $value > /sys/class/i2c-adapter/i2c-17/17-003e/qsfp_lpmode -} - -# Enable/Disable xcvr presence interrupts -xcvr_presence_interrupts() { - case $1 in - "enable") - for ((i=14;i<=17;i++)); - do - echo 0x0 > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask - done - ;; - "disable") - for ((i=14;i<=17;i++)); - do - echo 0xffff > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask - done - ;; - *) echo "s6100_platform: xcvr_presence_interrupts: invalid command !" - ;; - esac -} - -# Reset the mux tree -reset_muxes() { - local i - - # Reset the IOM muxes (if they have been already instantiated) - for ((i=14;i<=17;i++)); - do - if [[ -e /sys/class/i2c-adapter/i2c-$i/$i-003e ]]; then - echo 0xfc > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset - echo 0xff > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset - fi - done - - # Reset the switch card PCA9548A - io_rd_wr.py --set --val 0xef --offset 0x110 - io_rd_wr.py --set --val 0xff --offset 0x110 - - # Reset the CPU Card PCA9547 - io_rd_wr.py --set --val 0xfd --offset 0x20b - io_rd_wr.py --set --val 0xff --offset 0x20b -} - install_python_api_package() { device="/usr/share/sonic/device" platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) @@ -251,7 +16,6 @@ remove_python_api_package() { fi } -init_devnum if [[ "$1" == "init" ]]; then modprobe i2c-dev @@ -267,29 +31,18 @@ if [[ "$1" == "init" ]]; then /usr/local/bin/platform_watchdog_disable.sh fi - cpu_board_mux "new_device" - switch_board_mux "new_device" - sys_eeprom "new_device" - switch_board_eeprom "new_device" - switch_board_cpld "new_device" - switch_board_qsfp_mux "new_device" - switch_board_sfp "new_device" - switch_board_qsfp "new_device" - switch_board_qsfp_lpmode "disable" - xcvr_presence_interrupts "enable" + is_fast_warm=$(cat /proc/cmdline | grep SONIC_BOOT_TYPE | wc -l) + + if [[ "$is_fast_warm" == "1" ]]; then + systemctl start --no-block s6100-i2c-enumerate.service + else + systemctl start s6100-i2c-enumerate.service + fi install_python_api_package elif [[ "$1" == "deinit" ]]; then - xcvr_presence_interrupts "disable" - switch_board_sfp "delete_device" - switch_board_cpld "delete_device" - switch_board_eeprom "delete_device" - switch_board_mux "delete_device" - sys_eeprom "delete_device" - switch_board_qsfp "delete_device" - switch_board_qsfp_mux "delete_device" - cpu_board_mux "delete_device" + /usr/local/bin/s6100_i2c_enumeration.sh deinit modprobe -r dell_s6100_lpc modprobe -r dell_s6100_iom_cpld diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/s6100-i2c-enumerate.service b/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/s6100-i2c-enumerate.service new file mode 100644 index 000000000000..c63482831940 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/s6100-i2c-enumerate.service @@ -0,0 +1,12 @@ +[Unit] +Description=Dell S6100 I2C MUX Enumeration +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/s6100_i2c_enumeration.sh init +RemainAfterExit=no + +[Install] +WantedBy=multi-user.target From 9d3ea75c5770985911b06b46d4c9a4e2a8437eb0 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Tue, 24 Mar 2020 23:39:39 -0700 Subject: [PATCH 0462/1427] [submodule]: Update sonic-mgmt-framework to fix a build break fix. (#4318) Module updated: sonic-mgmt-framework Azure/sonic-mgmt-framework#44 --- src/sonic-mgmt-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework index 3b177823d406..f789b295f4c7 160000 --- a/src/sonic-mgmt-framework +++ b/src/sonic-mgmt-framework @@ -1 +1 @@ -Subproject commit 3b177823d406f8ff188a9770ff0f34f4820c75fc +Subproject commit f789b295f4c775ac303b4370d9380ebba8ac6272 From d2bab4424bc45413a64aa5abfbbf87c545b703c6 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 25 Mar 2020 17:08:20 +0200 Subject: [PATCH 0463/1427] [submodule]: Advance sonic-utilities. (#4316) Commits on Mar 24, 2020 - [config] Add sflow to _reset_failed_services (#850) 04648f5 - [fwutil]: Use overlay driver when mounting next image filesystem (#825) 668c116 - Fix for adding L3 interface to Vlan group (#826) 6e3679b - [fwutil]: Fix component table layout. (#831) 30adcbd Signed-off-by: Nazarii Hnydyn --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index d0f80914a088..30adcbdfb4ba 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit d0f80914a088e5081547db291d16900ab10ca740 +Subproject commit 30adcbdfb4ba0bd067aa8dab2aac60c5d72b55c7 From 80bf061b3762d11d836d87847c9227977d2b99e3 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Thu, 26 Mar 2020 01:54:07 +0800 Subject: [PATCH 0464/1427] [Mellanox] Fix thermal control bugs (#4298) * [thermal control] Fix pmon docker stop issue on 3800 * [thermal fix] Fix QA test issue * [thermal fix] change psu._get_power_available_status to psu.get_power_available_status * [thermal fix] adjust log for PSU absence and power absence * [thermal fix] add unit test for loading thermal policy file with duplicate conditions in different policies * [thermal] fix fan.get_presence for non-removable SKU * [thermal fix] fix issue: fan direction is based on drawer * Fix issue: when fan is not present, should not read fan direction from sysfs but directly return N/A * [thermal fix] add unit test for get_direction for absent FAN * Unplugable PSU has no FAN, no need add a FAN object for this PSU * Update submodules Co-authored-by: Stephen Sun <5379172+stephenxs@users.noreply.github.com> --- .../sonic_platform/chassis.py | 4 +- .../mlnx-platform-api/sonic_platform/fan.py | 34 ++++++--- .../mlnx-platform-api/sonic_platform/psu.py | 30 ++++++-- .../sonic_platform/thermal.py | 30 +++++--- .../sonic_platform/thermal_infos.py | 4 +- .../tests/duplicate_action.json | 18 +++++ .../tests/duplicate_condition.json | 17 +++++ .../mlnx-platform-api/tests/empty_action.json | 10 +++ .../tests/empty_condition.json | 11 +++ .../mlnx-platform-api/tests/mock_platform.py | 4 + .../tests/policy_with_same_conditions.json | 75 +++++++++++++++++++ .../mlnx-platform-api/tests/test_fan_api.py | 17 +++++ .../tests/test_thermal_policy.py | 46 ++++++++++++ src/sonic-platform-common | 2 +- src/sonic-platform-daemons | 2 +- 15 files changed, 270 insertions(+), 34 deletions(-) create mode 100644 platform/mellanox/mlnx-platform-api/tests/duplicate_action.json create mode 100644 platform/mellanox/mlnx-platform-api/tests/duplicate_condition.json create mode 100644 platform/mellanox/mlnx-platform-api/tests/empty_action.json create mode 100644 platform/mellanox/mlnx-platform-api/tests/empty_condition.json create mode 100644 platform/mellanox/mlnx-platform-api/tests/policy_with_same_conditions.json create mode 100644 platform/mellanox/mlnx-platform-api/tests/test_fan_api.py diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 4c5e04b21618..995d5cc8ae57 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -110,9 +110,9 @@ def initialize_fan(self): for index in range(num_of_fan): if multi_rotor_in_drawer: - fan = Fan(has_fan_dir, index, index/2) + fan = Fan(has_fan_dir, index, index/2, False, self.sku_name) else: - fan = Fan(has_fan_dir, index, index) + fan = Fan(has_fan_dir, index, index, False, self.sku_name) self._fan_list.append(fan) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py index cc4f8e81d9b5..9ce65d1e2f98 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py @@ -25,17 +25,22 @@ # fan_dir isn't supported on Spectrum 1. It is supported on Spectrum 2 and later switches FAN_DIR = "/var/run/hw-management/system/fan_dir" +# SKUs with unplugable FANs: +# 1. don't have fanX_status and should be treated as always present +hwsku_dict_with_unplugable_fan = ['ACS-MSN2010', 'ACS-MSN2100'] + class Fan(FanBase): """Platform-specific Fan class""" STATUS_LED_COLOR_ORANGE = "orange" - def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False): + def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False, sku = None): # API index is starting from 0, Mellanox platform index is starting from 1 self.index = fan_index + 1 self.drawer_index = drawer_index + 1 self.is_psu_fan = psu_fan + self.always_presence = False if sku not in hwsku_dict_with_unplugable_fan else True self.fan_min_speed_path = "fan{}_min".format(self.index) if not self.is_psu_fan: @@ -47,7 +52,7 @@ def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False): else: self.fan_speed_get_path = "psu{}_fan1_speed_get".format(self.index) self.fan_presence_path = "psu{}_fan1_speed_get".format(self.index) - self._name = 'psu_{}_fan_{}'.format(self.index, fan_index) + self._name = 'psu_{}_fan_{}'.format(self.index, 1) self.fan_max_speed_path = None self.fan_status_path = "fan{}_fault".format(self.index) self.fan_green_led_path = "led_fan{}_green".format(self.drawer_index) @@ -80,13 +85,13 @@ def get_direction(self): 1 stands for forward, in other words intake 0 stands for reverse, in other words exhaust """ - if not self.fan_dir or self.is_psu_fan: + if not self.fan_dir or self.is_psu_fan or not self.get_presence(): return self.FAN_DIRECTION_NOT_APPLICABLE try: with open(os.path.join(self.fan_dir), 'r') as fan_dir: fan_dir_bits = int(fan_dir.read()) - fan_mask = 1 << self.index - 1 + fan_mask = 1 << self.drawer_index - 1 if fan_dir_bits & fan_mask: return self.FAN_DIRECTION_INTAKE else: @@ -107,15 +112,15 @@ def get_status(self): """ status = 0 if self.is_psu_fan: - status = 1 + status = 0 else: try: with open(os.path.join(FAN_PATH, self.fan_status_path), 'r') as fault_status: status = int(fault_status.read()) except (ValueError, IOError): - status = 0 + status = 1 - return status == 1 + return status == 0 def get_presence(self): @@ -132,11 +137,14 @@ def get_presence(self): else: status = 0 else: - try: - with open(os.path.join(FAN_PATH, self.fan_presence_path), 'r') as presence_status: - status = int(presence_status.read()) - except (ValueError, IOError): - status = 0 + if self.always_presence: + status = 1 + else: + try: + with open(os.path.join(FAN_PATH, self.fan_presence_path), 'r') as presence_status: + status = int(presence_status.read()) + except (ValueError, IOError): + status = 0 return status == 1 @@ -183,6 +191,8 @@ def get_speed(self): max_speed_in_rpm = self._get_max_speed_in_rpm() speed = 100*speed_in_rpm/max_speed_in_rpm + if speed > 100: + speed = 100 return speed diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 5f9d529f94fb..1dfcf54baf17 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -99,19 +99,21 @@ def __init__(self, psu_index, sku): psu_presence = os.path.join(self.psu_path, psu_presence) self.psu_presence = psu_presence - fan = Fan(sku, psu_index, psu_index, True) - if fan.get_presence(): + # unplugable PSU has no FAN + if sku not in hwsku_dict_with_unplugable_psu: + fan = Fan(sku, psu_index, psu_index, True) self._fan_list.append(fan) - def get_name(self): - return self._name - self.psu_green_led_path = "led_psu_green" self.psu_red_led_path = "led_psu_red" self.psu_orange_led_path = "led_psu_orange" self.psu_led_cap_path = "led_psu_capability" + def get_name(self): + return self._name + + def _read_generic_file(self, filename, len): """ Read a generic file, returns the contents of the file @@ -287,3 +289,21 @@ def get_status_led(self): raise RuntimeError("Failed to read led status for psu due to {}".format(repr(e))) return self.STATUS_LED_COLOR_OFF + + + def get_power_available_status(self): + """ + Gets the power available status + + Returns: + True if power is present and power on. + False and "absence of PSU" if power is not present. + False and "absence of power" if power is present but not power on. + """ + if not self.get_presence(): + return False, "absence of PSU" + elif not self.get_powergood_status(): + return False, "absence of power" + else: + return True, "" + diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 424caa4b3c56..a5faa5ea793a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -64,7 +64,8 @@ } thermal_api_handler_gearbox = { THERMAL_API_GET_TEMPERATURE:"gearbox{}_temp_input", - THERMAL_API_GET_HIGH_THRESHOLD:None + THERMAL_API_GET_HIGH_THRESHOLD:None, + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:None } thermal_ambient_apis = { THERMAL_DEV_ASIC_AMBIENT : "asic", @@ -279,7 +280,7 @@ def initialize_thermals(sku, thermal_list, psu_list): else: if category == THERMAL_DEV_CATEGORY_PSU: for index in range(count): - thermal = Thermal(category, start + index, True, psu_list[index].get_powergood_status, "power off") + thermal = Thermal(category, start + index, True, psu_list[index].get_power_available_status) thermal_list.append(thermal) else: for index in range(count): @@ -289,7 +290,7 @@ def initialize_thermals(sku, thermal_list, psu_list): class Thermal(ThermalBase): - def __init__(self, category, index, has_index, dependency = None, hint = None): + def __init__(self, category, index, has_index, dependency = None): """ index should be a string for category ambient and int for other categories """ @@ -308,7 +309,6 @@ def __init__(self, category, index, has_index, dependency = None, hint = None): self.high_threshold = self._get_file_from_api(THERMAL_API_GET_HIGH_THRESHOLD) self.high_critical_threshold = self._get_file_from_api(THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD) self.dependency = dependency - self.dependent_hint = hint def get_name(self): @@ -360,13 +360,11 @@ def get_temperature(self): A float number of current temperature in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - if self.dependency and not self.dependency(): - if self.dependent_hint: - hint = self.dependent_hint - else: - hint = "unknown reason" - logger.log_info("get_temperature for {} failed due to {}".format(self.name, hint)) - return None + if self.dependency: + status, hint = self.dependency() + if not status: + logger.log_debug("get_temperature for {} failed due to {}".format(self.name, hint)) + return None value_str = self._read_generic_file(self.temperature, 0) if value_str is None: return None @@ -386,6 +384,11 @@ def get_high_threshold(self): """ if self.high_threshold is None: return None + if self.dependency: + status, hint = self.dependency() + if not status: + logger.log_debug("get_high_threshold for {} failed due to {}".format(self.name, hint)) + return None value_str = self._read_generic_file(self.high_threshold, 0) if value_str is None: return None @@ -405,6 +408,11 @@ def get_high_critical_threshold(self): """ if self.high_critical_threshold is None: return None + if self.dependency: + status, hint = self.dependency() + if not status: + logger.log_debug("get_high_critical_threshold for {} failed due to {}".format(self.name, hint)) + return None value_str = self._read_generic_file(self.high_critical_threshold, 0) if value_str is None: return None diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py index 34d31e47d24c..82c186495f5e 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py @@ -77,12 +77,12 @@ def collect(self, chassis): """ self._status_changed = False for psu in chassis.get_all_psus(): - if psu.get_presence() and psu not in self._presence_psus: + if psu.get_presence() and psu.get_powergood_status() and psu not in self._presence_psus: self._presence_psus.add(psu) self._status_changed = True if psu in self._absence_psus: self._absence_psus.remove(psu) - elif not psu.get_presence() and psu not in self._absence_psus: + elif (not psu.get_presence() or not psu.get_powergood_status()) and psu not in self._absence_psus: self._absence_psus.add(psu) self._status_changed = True if psu in self._presence_psus: diff --git a/platform/mellanox/mlnx-platform-api/tests/duplicate_action.json b/platform/mellanox/mlnx-platform-api/tests/duplicate_action.json new file mode 100644 index 000000000000..c19787aa26e0 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/duplicate_action.json @@ -0,0 +1,18 @@ +{ + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] +} diff --git a/platform/mellanox/mlnx-platform-api/tests/duplicate_condition.json b/platform/mellanox/mlnx-platform-api/tests/duplicate_condition.json new file mode 100644 index 000000000000..c25d84762e2a --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/duplicate_condition.json @@ -0,0 +1,17 @@ +{ + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + }, + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] +} diff --git a/platform/mellanox/mlnx-platform-api/tests/empty_action.json b/platform/mellanox/mlnx-platform-api/tests/empty_action.json new file mode 100644 index 000000000000..b1051b5a6f60 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/empty_action.json @@ -0,0 +1,10 @@ +{ + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + ] +} \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/tests/empty_condition.json b/platform/mellanox/mlnx-platform-api/tests/empty_condition.json new file mode 100644 index 000000000000..e7a588459246 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/empty_condition.json @@ -0,0 +1,11 @@ +{ + "name": "any fan absence", + "conditions": [ + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] +} \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/tests/mock_platform.py b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py index b8d070d44955..f34ace97968d 100644 --- a/platform/mellanox/mlnx-platform-api/tests/mock_platform.py +++ b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py @@ -13,10 +13,14 @@ def set_speed(self, speed): class MockPsu: def __init__(self): self.presence = True + self.powergood = True def get_presence(self): return self.presence + def get_powergood_status(self): + return self.powergood + class MockChassis: def __init__(self): diff --git a/platform/mellanox/mlnx-platform-api/tests/policy_with_same_conditions.json b/platform/mellanox/mlnx-platform-api/tests/policy_with_same_conditions.json new file mode 100644 index 000000000000..ace291be1c55 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/policy_with_same_conditions.json @@ -0,0 +1,75 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "false", + "fan_speed_when_suspend": "60" + }, + "info_types": [ + { + "type": "fan_info" + }, + { + "type": "psu_info" + }, + { + "type": "chassis_info" + } + ], + "policies": [ + { + "name": "all fan and psu presence", + "conditions": [ + { + "type": "fan.all.presence" + }, + { + "type": "psu.all.presence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "any psu absence", + "conditions": [ + { + "type": "psu.any.absence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "all fan and psu presence 1", + "conditions": [ + { + "type": "fan.all.presence" + }, + { + "type": "psu.all.presence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "true" + } + ] + } + ] +} \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py b/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py new file mode 100644 index 000000000000..381260163c0f --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py @@ -0,0 +1,17 @@ +import os +import sys +from mock import MagicMock + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +sys.path.insert(0, modules_path) + +from sonic_platform.fan import Fan + + +def test_get_absence_fan_direction(): + fan = Fan(True, 0, 0) + fan.get_presence = MagicMock(return_value=False) + assert fan.fan_dir is not None + assert not fan.is_psu_fan + assert fan.get_direction() == Fan.FAN_DIRECTION_NOT_APPLICABLE diff --git a/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py index ba9e502d4f74..843244e937fa 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py @@ -66,6 +66,12 @@ def test_psu_info(): assert len(psu_info.get_presence_psus()) == 1 assert psu_info.is_status_changed() + psu_list[0].powergood = False + psu_info.collect(chassis) + assert len(psu_info.get_absence_psus()) == 1 + assert len(psu_info.get_presence_psus()) == 0 + assert psu_info.is_status_changed() + def test_fan_policy(thermal_manager): chassis = MockChassis() @@ -269,4 +275,44 @@ def test_load_control_thermal_algo_action(): with pytest.raises(ValueError): action.load_from_json(json_obj) +def test_load_duplicate_condition(): + from sonic_platform_base.sonic_thermal_control.thermal_policy import ThermalPolicy + with open(os.path.join(test_path, 'duplicate_condition.json')) as f: + json_obj = json.load(f) + policy = ThermalPolicy() + with pytest.raises(Exception): + policy.load_from_json(json_obj) + +def test_load_duplicate_action(): + from sonic_platform_base.sonic_thermal_control.thermal_policy import ThermalPolicy + with open(os.path.join(test_path, 'duplicate_action.json')) as f: + json_obj = json.load(f) + policy = ThermalPolicy() + with pytest.raises(Exception): + policy.load_from_json(json_obj) + +def test_load_empty_condition(): + from sonic_platform_base.sonic_thermal_control.thermal_policy import ThermalPolicy + with open(os.path.join(test_path, 'empty_condition.json')) as f: + json_obj = json.load(f) + policy = ThermalPolicy() + with pytest.raises(Exception): + policy.load_from_json(json_obj) + +def test_load_empty_action(): + from sonic_platform_base.sonic_thermal_control.thermal_policy import ThermalPolicy + with open(os.path.join(test_path, 'empty_action.json')) as f: + json_obj = json.load(f) + policy = ThermalPolicy() + with pytest.raises(Exception): + policy.load_from_json(json_obj) + +def test_load_policy_with_same_conditions(): + from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase + class MockThermalManager(ThermalManagerBase): + pass + + with pytest.raises(Exception): + MockThermalManager.load(os.path.join(test_path, 'policy_with_same_conditions.json')) + diff --git a/src/sonic-platform-common b/src/sonic-platform-common index ed50e72d0280..dc59b105ff23 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit ed50e72d028092399e2768e64a7a4ef01e7571de +Subproject commit dc59b105ff234bd89b9042c934b17c10b9b261f7 diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index fc455a7d01f8..97e40cefae31 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit fc455a7d01f8df1ed6a55960056facdf1b3b0b3c +Subproject commit 97e40cefae31928fe8faf0a0995c8263e7f62465 From 592abec5d99e4830d3493506849c8658891249fd Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Thu, 26 Mar 2020 02:58:19 +0800 Subject: [PATCH 0465/1427] [as4630-54pe]Put correct fanuilt.py file (#4321) --- .../as4630-54pe/classes/fanutil.py | 173 +++++++++++++++--- 1 file changed, 143 insertions(+), 30 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py index df2e511adef7..5bcd600d1cb8 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py @@ -20,50 +20,79 @@ # ------------------------------------------------------------------ try: - import os import time import logging - import glob - import commands from collections import namedtuple except ImportError as e: raise ImportError('%s - required module not found' % str(e)) + + +class FanUtil(object): + """Platform-specific FanUtil class""" + + FAN_NUM_ON_MAIN_BROAD = 3 + FAN_NUM_1_IDX = 1 + FAN_NUM_2_IDX = 2 + FAN_NUM_3_IDX = 3 -class ThermalUtil(object): - """Platform-specific ThermalUtil class""" - THERMAL_NUM_MAX = 4 - THERMAL_NUM_1_IDX = 1 - THERMAL_NUM_2_IDX = 2 - THERMAL_NUM_3_IDX = 3 - THERMAL_NUM_4_IDX = 4 + FAN_NODE_NUM_OF_MAP = 4 + FAN_NODE_FAULT_IDX_OF_MAP = 1 + FAN_NODE_DIR_IDX_OF_MAP = 2 + FAN_NODE_PRESENT_IDX_OF_MAP= 3 + FAN_NODE_SPEED_IDX_OF_MAP = 4 + + BASE_VAL_PATH = '/sys/bus/i2c/devices/3-0060/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/3-0060/fan_duty_cycle_percentage' """ Dictionary where - key1 = thermal id index (integer) starting from 1 + key1 = fan id index (integer) starting from 1 + key2 = fan node index (interger) starting from 1 value = path to fan device file (string) """ + _fan_device_path_mapping = {} - thermal_sysfspath ={ - THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/24-004b/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/25-004a/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_4_IDX: ["/sys/class/hwmon/hwmon1/temp1_input"], + _fan_device_node_mapping = { + (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan_fault_1', + (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan_direction_1', + (FAN_NUM_1_IDX, FAN_NODE_PRESENT_IDX_OF_MAP): 'fan_present_1', + (FAN_NUM_1_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan1_input', + + + (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan_fault_2', + (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan_direction_2', + (FAN_NUM_2_IDX, FAN_NODE_PRESENT_IDX_OF_MAP):'fan_present_2', + (FAN_NUM_2_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan2_input', + + (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan_fault_3', + (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan_direction_3', + (FAN_NUM_3_IDX, FAN_NODE_PRESENT_IDX_OF_MAP):'fan_present_3', + (FAN_NUM_3_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan3_input', } - def _get_thermal_val(self, thermal_num): - if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_MAX: - logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + def _get_fan_device_node(self, fan_num, node_num): + return self._fan_device_node_mapping[(fan_num, node_num)] + + def _get_fan_node_val(self, fan_num, node_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) return None - device_path = self.get_thermal_path(thermal_num) - for filename in glob.glob(device_path): + device_path = self.get_fan_device_path(fan_num, node_num) + try: - val_file = open(filename, 'r') + val_file = open(device_path, 'r') except IOError as e: logging.error('GET. unable to open file: %s', str(e)) return None + content = val_file.readline().rstrip() if content == '': logging.debug('GET. content is NULL. device_path:%s', device_path) return None + try: val_file.close() except: @@ -72,19 +101,103 @@ def _get_thermal_val(self, thermal_num): return int(content) - return 0 + def _set_fan_node_val(self, fan_num, node_num, val): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None - def get_num_thermals(self): - return self.THERMAL_NUM_MAX + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + content = str(val) + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None - def get_size_path_map(self): - return len(self.thermal_sysfspath) + device_path = self.get_fan_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'w') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None - def get_thermal_path(self, thermal_num): - return self.thermal_sysfspath[thermal_num][0] + val_file.write(content) + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return True + + def __init__(self): + fan_path = self.BASE_VAL_PATH + for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): + for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): + self._fan_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_device_node_mapping[(fan_num, node_num)]) + + def get_size_node_map(self): + return len(self._fan_device_node_mapping) + + def get_fan_device_path(self, fan_num, node_num): + return self._fan_device_path_mapping[(fan_num, node_num)] + + def get_fan_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + + def get_fan_present(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_PRESENT_IDX_OF_MAP) + + def get_fan_dir(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) + + def get_fan_duty_cycle(self): + try: + val_file = open(self.FAN_DUTY_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + return int(content) + + def set_fan_duty_cycle(self, val): + try: + fan_file = open(self.FAN_DUTY_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + fan_file.write(str(val)) + fan_file.close() + return True + + def get_fan_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + + def get_fan_status(self, fan_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num, %d', fan_num) + return None + if self.get_fan_fault(fan_num)==0 and self.get_fan_present(fan_num)>0: + return 1 + else: + logging.debug('GET. FAN fault. fan_num, %d', fan_num) + return 0 def main(): - thermal = ThermalUtil() + fan = FanUtil() + logging.debug('fan_duty_cycle=%d', fan.get_fan_duty_cycle()) + for i in range(1,4): + logging.debug('fan-%d speed=%d', i, fan.get_fan_speed(i)) + logging.debug('fan-%d present=%d', i, fan.get_fan_present(i)) + logging.debug('fan-%d fault=%d', i, fan.get_fan_fault(i)) + logging.debug('fan-%d status=%d', i, fan.get_fan_status(i)) if __name__ == '__main__': main() \ No newline at end of file From 73c77f0d43f812745cd5fb65f2989e79c32ee77e Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Thu, 26 Mar 2020 11:04:38 -0700 Subject: [PATCH 0466/1427] [submodule]: Advance sonic-utilities. (#4324) 798ce2f [multi-asic]: Update reload of systemd services to support multi-asic platforms (#856) 6f51428 [Mellanox] Fix thermal control issue: use natural sort for fan status and thermal status (#836) 51d26ce [ntp]: support "show ntp" with mgmt vrf based on linux os version (#858) Signed-off-by: SuvarnaMeenakshi --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 30adcbdfb4ba..798ce2fa0b1b 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 30adcbdfb4ba0bd067aa8dab2aac60c5d72b55c7 +Subproject commit 798ce2fa0b1b9a6e12deaa141c39a92c17b809e8 From ed5650fa27237e9ec3aa4e631910139610aedbe4 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Fri, 27 Mar 2020 09:14:33 -0700 Subject: [PATCH 0467/1427] Updated sonic-sairedis submodule (#4323) The following changes are included in this submodule advance 54b2510 [syncd] Use correct VID when GET will fail to obrain object type (#577) 59b0430 [syncd] Unlock vendor api lock if enabling diag shell (#571) 910d45e [vs] Add more logs when setting MTU on port (#576) c0d9947 [vs] Fix setting correct port mtu value (#573) --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index fe94170c8097..54b251059691 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit fe94170c809773d86b196bd8d881f78ba71a1d7c +Subproject commit 54b251059691884da5ae28d6c1d9ecc94be1b523 From 442482685f991e76a4345c2843c3124de19e6441 Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 27 Mar 2020 10:49:08 -0700 Subject: [PATCH 0468/1427] [build]: install cmake 3.13.2 (#4319) fix #4315 download and install cmake 3.13.2 from azure storage latest cmake 3.16.3 from stretch-backports breaks the libyang 1.0.73 build Signed-off-by: Guohan Lu --- sonic-slave-stretch/Dockerfile.j2 | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 4d34e8e81a75..f9e96791464d 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -249,9 +249,6 @@ RUN apt-get update && apt-get install -y \ python3-yaml \ # For lockfile procmail \ -# For gtest - libgtest-dev \ - cmake \ # For pam_tacplus build autoconf-archive \ # For iproute2 @@ -382,6 +379,23 @@ RUN apt-get install -y vim # Install rsyslog RUN apt-get install -y rsyslog +RUN apt-get install -y libgtest-dev +RUN apt-get install -y libarchive13 librhash0 +RUN apt-get -t stretch-backports install -y libuv1 +# Install cmake/cmake-data 3.13.2-1_bpo9+1 +# latest cmake 3.16.3 break the build libyang 1.0.73 +RUN wget -O cmake-data_3.13.2-1_bpo9+1_all.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake-data_3.13.2-1_bpo9%2B1_all.deb?st=2020-03-27T02%3A22%3A24Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=Xby%2Bm3OZOjPB%2FSlDbHD65yDcPzAgoys%2FA3vK8RB4BzA%3D" +RUN dpkg -i cmake-data_3.13.2-1_bpo9+1_all.deb || apt-get install -f +{% if CONFIGURED_ARCH == "armhf" %} +RUN wget -O cmake_3.13.2-1_bpo9+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake_3.13.2-1_bpo9%2B1_armhf.deb?st=2020-03-27T02%3A29%3A41Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=sWt7kxrFumn020d2GeutGJ716cuQsFwmAmgU%2BJ0kqnk%3D" +RUN dpkg -i cmake_3.13.2-1_bpo9+1_armhf.deb || apt-get install -f +{% elif CONFIGURED_ARCH == "arm64" %} +RUN wget -O cmake_3.13.2-1_bpo9+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake_3.13.2-1_bpo9%2B1_arm64.deb?st=2020-03-27T02%3A28%3A38Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=rrHMkLi29aI8yH6s52ILCY8VcEbNFrzYT2DmC5RwOgs%3D" +RUN dpkg -i cmake_3.13.2-1_bpo9+1_arm64.deb || apt-get install -f +{% else %} +RUN wget -O cmake_3.13.2-1_bpo9+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake_3.13.2-1_bpo9%2B1_amd64.deb?st=2020-03-27T02%3A27%3A21Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=4MvmmDBQuicFEJYakLm7xCNU19yJ8GIP4ankFSnITKY%3D" +RUN dpkg -i cmake_3.13.2-1_bpo9+1_amd64.deb || apt-get install -f +{% endif %} RUN cd /usr/src/gtest && cmake . && make -C /usr/src/gtest RUN mkdir /var/run/sshd From 46df9ad5766c07019685cad654b7333f4045ede9 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Sat, 28 Mar 2020 03:57:14 +0800 Subject: [PATCH 0469/1427] [build]: Fix DPKG derived package issue (#4333) --- rules/lm-sensors.mk | 4 ++-- rules/snmpd.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rules/lm-sensors.mk b/rules/lm-sensors.mk index a97b539fd8ad..7df208abfdbf 100644 --- a/rules/lm-sensors.mk +++ b/rules/lm-sensors.mk @@ -16,14 +16,14 @@ LIBSENSORS = libsensors4_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LM_SENSORS),$(LIBSENSORS))) LIBSENSORS_DBG = libsensors4-dbgsym_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBSENSORS),$(LIBSENSORS_DBG))) +$(eval $(call add_derived_package,$(LM_SENSORS),$(LIBSENSORS_DBG))) SENSORD = sensord_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LM_SENSORS),$(SENSORD))) $(SENSORD)_DEPENDS += $(LIBSENSORS) $(LM_SENSORS) SENSORD_DBG = sensord-dbgsym_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(SENSORD),$(SENSORD_DBG))) +$(eval $(call add_derived_package,$(LM_SENSORS),$(SENSORD_DBG))) SONIC_MAKE_DEBS += $(LM_SENSORS) diff --git a/rules/snmpd.mk b/rules/snmpd.mk index 8fb8495ebc3d..168cad70ef2a 100644 --- a/rules/snmpd.mk +++ b/rules/snmpd.mk @@ -27,10 +27,10 @@ $(SNMPD)_RDEPENDS += $(LIBSNMP) $(eval $(call add_derived_package,$(LIBSNMP_BASE),$(SNMPD))) SNMP_DBG = snmp-dbgsym_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(SNMP),$(SNMP_DBG))) +$(eval $(call add_derived_package,$(LIBSNMP_BASE),$(SNMP_DBG))) SNMPD_DBG = snmpd-dbgsym_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(SNMPD),$(SNMPD_DBG))) +$(eval $(call add_derived_package,$(LIBSNMP_BASE),$(SNMPD_DBG))) LIBSNMP = libsnmp30_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(LIBSNMP)_RDEPENDS += $(LIBSNMP_BASE) From 2739ac00cabd18e2c37c27cb069bbdf725178c62 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Fri, 27 Mar 2020 23:45:21 +0200 Subject: [PATCH 0470/1427] [pmon][barefoot] Disabled thermalctld pmon daemon (#4327) Signed-off-by: Andriy Kokhan --- .../x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json | 1 + .../x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json | 1 + 2 files changed, 2 insertions(+) diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json index 3a76f2fdd0e4..d00d924bcd17 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { + "skip_thermalctld": true, "skip_ledd": true, "skip_xcvrd": false, "skip_psud": false, diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json index 3a76f2fdd0e4..d00d924bcd17 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { + "skip_thermalctld": true, "skip_ledd": true, "skip_xcvrd": false, "skip_psud": false, From 98fbd59f193bc0db035954313e53ebe4e9e8c70a Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Fri, 27 Mar 2020 17:27:28 -0700 Subject: [PATCH 0471/1427] Revert "Updated sonic-sairedis submodule (#4323)" (#4336) This reverts commit ed5650fa27237e9ec3aa4e631910139610aedbe4. --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 54b251059691..fe94170c8097 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 54b251059691884da5ae28d6c1d9ecc94be1b523 +Subproject commit fe94170c809773d86b196bd8d881f78ba71a1d7c From 5b0ec7afe621c082f91ff53b842ccb8c1a09be88 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 27 Mar 2020 17:28:27 -0700 Subject: [PATCH 0472/1427] [Arista] Update drivers submodules (#4317) * Update arista drivers submodules * Add device configs for 7060CX2-32S * Update boot0 and union-mount for 7060CX2-32S * Add 7170-32C and 7170-32CD support in boot0 * Sync after writting boot configs * Add 7170-32C and 7170-32CD device configurations Co-authored-by: Boyang Yu --- .../Arista-7060CX2-32S-C32 | 1 + .../x86_64-arista_7060cx2_32s/default_sku | 1 + .../x86_64-arista_7060cx2_32s/fancontrol | 1 + .../x86_64-arista_7060cx2_32s/platform_reboot | 1 + .../arista/x86_64-arista_7060cx2_32s/plugins | 1 + .../x86_64-arista_7060cx2_32s/sensors.conf | 1 + .../Arista-7170-32C-C32/board_lane_map.json | 1734 +++++++++++++++++ .../Arista-7170-32C-C32/port_config.ini | 33 + .../Arista-7170-32C-C32/switch-sai.conf | 33 + .../Arista-7170-32C-C32/switch-tna-sai.conf | 39 + .../arista/x86_64-arista_7170_32c/default_sku | 1 + .../x86_64-arista_7170_32c/platform_reboot | 1 + device/arista/x86_64-arista_7170_32c/plugins | 1 + .../x86_64-arista_7170_32c/sensors.conf | 1 + .../Arista-7170-32CD-C32/board_lane_map.json | 1734 +++++++++++++++++ .../Arista-7170-32CD-C32/port_config.ini | 33 + .../Arista-7170-32CD-C32/switch-sai.conf | 33 + .../Arista-7170-32CD-C32/switch-tna-sai.conf | 39 + .../x86_64-arista_7170_32cd/default_sku | 1 + .../x86_64-arista_7170_32cd/platform_reboot | 1 + device/arista/x86_64-arista_7170_32cd/plugins | 1 + .../x86_64-arista_7170_32cd/sensors.conf | 1 + files/Aboot/boot0.j2 | 17 +- files/initramfs-tools/union-mount.j2 | 1 + .../barefoot/sonic-platform-modules-arista | 2 +- .../broadcom/sonic-platform-modules-arista | 2 +- 26 files changed, 3711 insertions(+), 3 deletions(-) create mode 120000 device/arista/x86_64-arista_7060cx2_32s/Arista-7060CX2-32S-C32 create mode 100644 device/arista/x86_64-arista_7060cx2_32s/default_sku create mode 120000 device/arista/x86_64-arista_7060cx2_32s/fancontrol create mode 120000 device/arista/x86_64-arista_7060cx2_32s/platform_reboot create mode 120000 device/arista/x86_64-arista_7060cx2_32s/plugins create mode 120000 device/arista/x86_64-arista_7060cx2_32s/sensors.conf create mode 100644 device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json create mode 100644 device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/port_config.ini create mode 100644 device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-sai.conf create mode 100644 device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-tna-sai.conf create mode 100644 device/arista/x86_64-arista_7170_32c/default_sku create mode 120000 device/arista/x86_64-arista_7170_32c/platform_reboot create mode 120000 device/arista/x86_64-arista_7170_32c/plugins create mode 120000 device/arista/x86_64-arista_7170_32c/sensors.conf create mode 100644 device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/board_lane_map.json create mode 100644 device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/port_config.ini create mode 100644 device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-sai.conf create mode 100644 device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-tna-sai.conf create mode 100644 device/arista/x86_64-arista_7170_32cd/default_sku create mode 120000 device/arista/x86_64-arista_7170_32cd/platform_reboot create mode 120000 device/arista/x86_64-arista_7170_32cd/plugins create mode 120000 device/arista/x86_64-arista_7170_32cd/sensors.conf diff --git a/device/arista/x86_64-arista_7060cx2_32s/Arista-7060CX2-32S-C32 b/device/arista/x86_64-arista_7060cx2_32s/Arista-7060CX2-32S-C32 new file mode 120000 index 000000000000..3ba3c5721b19 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/Arista-7060CX2-32S-C32 @@ -0,0 +1 @@ +../x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32 \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/default_sku b/device/arista/x86_64-arista_7060cx2_32s/default_sku new file mode 100644 index 000000000000..fb5071866c25 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/default_sku @@ -0,0 +1 @@ +Arista-7060CX2-32S-C32 t1 diff --git a/device/arista/x86_64-arista_7060cx2_32s/fancontrol b/device/arista/x86_64-arista_7060cx2_32s/fancontrol new file mode 120000 index 000000000000..c37f83f5ffb5 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/fancontrol @@ -0,0 +1 @@ +../x86_64-arista_7060_cx32s/fancontrol \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/platform_reboot b/device/arista/x86_64-arista_7060cx2_32s/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/plugins b/device/arista/x86_64-arista_7060cx2_32s/plugins new file mode 120000 index 000000000000..5fbbf98a6284 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/sensors.conf b/device/arista/x86_64-arista_7060cx2_32s/sensors.conf new file mode 120000 index 000000000000..10be0183e3a7 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7060_cx32s/sensors.conf \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json new file mode 100644 index 000000000000..6ab72e55ab47 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json @@ -0,0 +1,1734 @@ +{ + "board_name": "7170-32C", + "enable_debug_log": 0, + "board_lane_map_entry": [ + { + "connector": 1, + "device_id": 0, + "mac_block": 14, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 2, + "device_id": 0, + "mac_block": 12, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 3, + "device_id": 0, + "mac_block": 10, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 4, + "device_id": 0, + "mac_block": 8, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 5, + "device_id": 0, + "mac_block": 6, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 6, + "device_id": 0, + "mac_block": 4, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 7, + "device_id": 0, + "mac_block": 2, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 8, + "device_id": 0, + "mac_block": 0, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 9, + "device_id": 0, + "mac_block": 62, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 10, + "device_id": 0, + "mac_block": 60, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 11, + "device_id": 0, + "mac_block": 58, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 12, + "device_id": 0, + "mac_block": 56, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 13, + "device_id": 0, + "mac_block": 54, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 14, + "device_id": 0, + "mac_block": 52, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 15, + "device_id": 0, + "mac_block": 50, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 16, + "device_id": 0, + "mac_block": 48, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 17, + "device_id": 0, + "mac_block": 46, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 18, + "device_id": 0, + "mac_block": 44, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 19, + "device_id": 0, + "mac_block": 42, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 20, + "device_id": 0, + "mac_block": 40, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 21, + "device_id": 0, + "mac_block": 38, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 22, + "device_id": 0, + "mac_block": 36, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 23, + "device_id": 0, + "mac_block": 34, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 24, + "device_id": 0, + "mac_block": 32, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 25, + "device_id": 0, + "mac_block": 30, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 26, + "device_id": 0, + "mac_block": 28, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 27, + "device_id": 0, + "mac_block": 26, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 28, + "device_id": 0, + "mac_block": 24, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 29, + "device_id": 0, + "mac_block": 22, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 30, + "device_id": 0, + "mac_block": 20, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 31, + "device_id": 0, + "mac_block": 18, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 32, + "device_id": 0, + "mac_block": 16, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/port_config.ini b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/port_config.ini new file mode 100644 index 000000000000..d983617f1891 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias speed index +Ethernet0 0,1,2,3 Ethernet1/1 100000 1 +Ethernet4 4,5,6,7 Ethernet2/1 100000 2 +Ethernet8 8,9,10,11 Ethernet3/1 100000 3 +Ethernet12 12,13,14,15 Ethernet4/1 100000 4 +Ethernet16 16,17,18,19 Ethernet5/1 100000 5 +Ethernet20 20,21,22,23 Ethernet6/1 100000 6 +Ethernet24 24,25,26,27 Ethernet7/1 100000 7 +Ethernet28 28,29,30,31 Ethernet8/1 100000 8 +Ethernet32 32,33,34,35 Ethernet9/1 100000 9 +Ethernet36 36,37,38,39 Ethernet10/1 100000 10 +Ethernet40 40,41,42,43 Ethernet11/1 100000 11 +Ethernet44 44,45,46,47 Ethernet12/1 100000 12 +Ethernet48 48,49,50,51 Ethernet13/1 100000 13 +Ethernet52 52,53,54,55 Ethernet14/1 100000 14 +Ethernet56 56,57,58,59 Ethernet15/1 100000 15 +Ethernet60 60,61,62,63 Ethernet16/1 100000 16 +Ethernet64 64,65,66,67 Ethernet17/1 100000 17 +Ethernet68 68,69,70,71 Ethernet18/1 100000 18 +Ethernet72 72,73,74,75 Ethernet19/1 100000 19 +Ethernet76 76,77,78,79 Ethernet20/1 100000 20 +Ethernet80 80,81,82,83 Ethernet21/1 100000 21 +Ethernet84 84,85,86,87 Ethernet22/1 100000 22 +Ethernet88 88,89,90,91 Ethernet23/1 100000 23 +Ethernet92 92,93,94,95 Ethernet24/1 100000 24 +Ethernet96 96,97,98,99 Ethernet25/1 100000 25 +Ethernet100 100,101,102,103 Ethernet26/1 100000 26 +Ethernet104 104,105,106,107 Ethernet27/1 100000 27 +Ethernet108 108,109,110,111 Ethernet28/1 100000 28 +Ethernet112 112,113,114,115 Ethernet29/1 100000 29 +Ethernet116 116,117,118,119 Ethernet30/1 100000 30 +Ethernet120 120,121,122,123 Ethernet31/1 100000 31 +Ethernet124 124,125,126,127 Ethernet32/1 100000 32 diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-sai.conf b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-sai.conf new file mode 100644 index 000000000000..0a807b1c9ea7 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-sai.conf @@ -0,0 +1,33 @@ +{ + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:1c.4/0000:07:00.0", + "pcie_domain": 0, + "pcie_bus": 7, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "instance": 0, + "p4_program_list": [ + { + "id": "pgm-0", + "instance": 0, + "path": "switch", + "program-name": "switch", + "pd": "lib/tofinopd/switch/libpd.so", + "pd-thrift": "lib/tofinopd/switch/libpdthrift.so", + "table-config": "share/tofinopd/switch/context.json", + "tofino-bin": "share/tofinopd/switch/tofino.bin", + "switchapi": "lib/libswitchapi.so", + "sai": "lib/libsai.so", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-tna-sai.conf b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-tna-sai.conf new file mode 100644 index 000000000000..ece3fcbe6a90 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-tna-sai.conf @@ -0,0 +1,39 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" + } + ], + "program-name": "switch", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32c/default_sku b/device/arista/x86_64-arista_7170_32c/default_sku new file mode 100644 index 000000000000..536bad44f086 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/default_sku @@ -0,0 +1 @@ +Arista-7170-32CD-C32 t1 diff --git a/device/arista/x86_64-arista_7170_32c/platform_reboot b/device/arista/x86_64-arista_7170_32c/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/plugins b/device/arista/x86_64-arista_7170_32c/plugins new file mode 120000 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/sensors.conf b/device/arista/x86_64-arista_7170_32c/sensors.conf new file mode 120000 index 000000000000..1ab9e0f47704 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7170_64c/sensors.conf \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/board_lane_map.json b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/board_lane_map.json new file mode 100644 index 000000000000..58a78c5fc4c9 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/board_lane_map.json @@ -0,0 +1,1734 @@ +{ + "board_name": "7170-32CD", + "enable_debug_log": 0, + "board_lane_map_entry": [ + { + "connector": 1, + "device_id": 0, + "mac_block": 7, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 2, + "device_id": 0, + "mac_block": 6, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 3, + "device_id": 0, + "mac_block": 5, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 4, + "device_id": 0, + "mac_block": 4, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 5, + "device_id": 0, + "mac_block": 3, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 6, + "device_id": 0, + "mac_block": 2, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 7, + "device_id": 0, + "mac_block": 1, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 8, + "device_id": 0, + "mac_block": 0, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 9, + "device_id": 0, + "mac_block": 31, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 10, + "device_id": 0, + "mac_block": 30, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 11, + "device_id": 0, + "mac_block": 29, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 12, + "device_id": 0, + "mac_block": 28, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 13, + "device_id": 0, + "mac_block": 27, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 14, + "device_id": 0, + "mac_block": 26, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 15, + "device_id": 0, + "mac_block": 25, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 16, + "device_id": 0, + "mac_block": 24, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 17, + "device_id": 0, + "mac_block": 23, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 18, + "device_id": 0, + "mac_block": 22, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 19, + "device_id": 0, + "mac_block": 21, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 20, + "device_id": 0, + "mac_block": 20, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 21, + "device_id": 0, + "mac_block": 19, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 22, + "device_id": 0, + "mac_block": 18, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 23, + "device_id": 0, + "mac_block": 17, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 24, + "device_id": 0, + "mac_block": 16, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 25, + "device_id": 0, + "mac_block": 15, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 26, + "device_id": 0, + "mac_block": 14, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 27, + "device_id": 0, + "mac_block": 13, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 28, + "device_id": 0, + "mac_block": 12, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 29, + "device_id": 0, + "mac_block": 11, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 30, + "device_id": 0, + "mac_block": 10, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 31, + "device_id": 0, + "mac_block": 9, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 32, + "device_id": 0, + "mac_block": 8, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/port_config.ini b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/port_config.ini new file mode 100644 index 000000000000..d983617f1891 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias speed index +Ethernet0 0,1,2,3 Ethernet1/1 100000 1 +Ethernet4 4,5,6,7 Ethernet2/1 100000 2 +Ethernet8 8,9,10,11 Ethernet3/1 100000 3 +Ethernet12 12,13,14,15 Ethernet4/1 100000 4 +Ethernet16 16,17,18,19 Ethernet5/1 100000 5 +Ethernet20 20,21,22,23 Ethernet6/1 100000 6 +Ethernet24 24,25,26,27 Ethernet7/1 100000 7 +Ethernet28 28,29,30,31 Ethernet8/1 100000 8 +Ethernet32 32,33,34,35 Ethernet9/1 100000 9 +Ethernet36 36,37,38,39 Ethernet10/1 100000 10 +Ethernet40 40,41,42,43 Ethernet11/1 100000 11 +Ethernet44 44,45,46,47 Ethernet12/1 100000 12 +Ethernet48 48,49,50,51 Ethernet13/1 100000 13 +Ethernet52 52,53,54,55 Ethernet14/1 100000 14 +Ethernet56 56,57,58,59 Ethernet15/1 100000 15 +Ethernet60 60,61,62,63 Ethernet16/1 100000 16 +Ethernet64 64,65,66,67 Ethernet17/1 100000 17 +Ethernet68 68,69,70,71 Ethernet18/1 100000 18 +Ethernet72 72,73,74,75 Ethernet19/1 100000 19 +Ethernet76 76,77,78,79 Ethernet20/1 100000 20 +Ethernet80 80,81,82,83 Ethernet21/1 100000 21 +Ethernet84 84,85,86,87 Ethernet22/1 100000 22 +Ethernet88 88,89,90,91 Ethernet23/1 100000 23 +Ethernet92 92,93,94,95 Ethernet24/1 100000 24 +Ethernet96 96,97,98,99 Ethernet25/1 100000 25 +Ethernet100 100,101,102,103 Ethernet26/1 100000 26 +Ethernet104 104,105,106,107 Ethernet27/1 100000 27 +Ethernet108 108,109,110,111 Ethernet28/1 100000 28 +Ethernet112 112,113,114,115 Ethernet29/1 100000 29 +Ethernet116 116,117,118,119 Ethernet30/1 100000 30 +Ethernet120 120,121,122,123 Ethernet31/1 100000 31 +Ethernet124 124,125,126,127 Ethernet32/1 100000 32 diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-sai.conf b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-sai.conf new file mode 100644 index 000000000000..0a807b1c9ea7 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-sai.conf @@ -0,0 +1,33 @@ +{ + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:1c.4/0000:07:00.0", + "pcie_domain": 0, + "pcie_bus": 7, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "instance": 0, + "p4_program_list": [ + { + "id": "pgm-0", + "instance": 0, + "path": "switch", + "program-name": "switch", + "pd": "lib/tofinopd/switch/libpd.so", + "pd-thrift": "lib/tofinopd/switch/libpdthrift.so", + "table-config": "share/tofinopd/switch/context.json", + "tofino-bin": "share/tofinopd/switch/tofino.bin", + "switchapi": "lib/libswitchapi.so", + "sai": "lib/libsai.so", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-tna-sai.conf b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-tna-sai.conf new file mode 100644 index 000000000000..ece3fcbe6a90 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-tna-sai.conf @@ -0,0 +1,39 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" + } + ], + "program-name": "switch", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32cd/default_sku b/device/arista/x86_64-arista_7170_32cd/default_sku new file mode 100644 index 000000000000..536bad44f086 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/default_sku @@ -0,0 +1 @@ +Arista-7170-32CD-C32 t1 diff --git a/device/arista/x86_64-arista_7170_32cd/platform_reboot b/device/arista/x86_64-arista_7170_32cd/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/plugins b/device/arista/x86_64-arista_7170_32cd/plugins new file mode 120000 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/sensors.conf b/device/arista/x86_64-arista_7170_32cd/sensors.conf new file mode 120000 index 000000000000..1ab9e0f47704 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7170_64c/sensors.conf \ No newline at end of file diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 5a2f2555d1ea..3c61c631af93 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -265,6 +265,10 @@ platform_specific() { aboot_machine=arista_7060_cx32s flash_size=3700 fi + if [ "$sid" = "UpperlakePlus" ]; then + aboot_machine=arista_7060cx2_32s + flash_size=3700 + fi if [ "$sid" = "Gardena" ] || [ "$sid" = "GardenaE" ]; then aboot_machine=arista_7260cx3_64 flash_size=28000 @@ -274,6 +278,16 @@ platform_specific() { flash_size=28000 echo "hugepages=128" >> /tmp/append fi + if [ "$sid" = "Mineral" ]; then + aboot_machine=arista_7170_32c + flash_size=28000 + echo "hugepages=128" >> /tmp/append + fi + if [ "$sid" = "MineralD" ]; then + aboot_machine=arista_7170_32cd + flash_size=28000 + echo "hugepages=128" >> /tmp/append + fi if [ "$sid" = "Lodoga" ]; then aboot_machine=arista_7050cx3_32s flash_size=3700 @@ -379,7 +393,8 @@ write_boot_configs() { mkdir -p "$image_path" cat /tmp/append > $cmdline_image - [ -e ${target_path}/machine.conf ] || write_machine_config + [ -s ${target_path}/machine.conf ] || write_machine_config + sync } run_kexec() { diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index 2376ea490e64..0fadb9a73edb 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -21,6 +21,7 @@ set_tmpfs_log_partition_size() [ X"$aboot_platform" = X"x86_64-arista_7050_qx32" ] && return [ X"$aboot_platform" = X"x86_64-arista_7050_qx32s" ] && return [ X"$aboot_platform" = X"x86_64-arista_7060_cx32s" ] && return + [ X"$aboot_platform" = X"x86_64-arista_7060cx2_32s" ] && return # set varlogsize to existing var-log.ext4 size if [ -f ${rootmnt}/host/disk-img/var-log.ext4 ]; then diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index e9cabadb4272..39860a109853 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit e9cabadb42725d3c86eb93c3d766cfb5d58e6d29 +Subproject commit 39860a109853b2f37367dfe68905e019b509d5bf diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index e9cabadb4272..39860a109853 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit e9cabadb42725d3c86eb93c3d766cfb5d58e6d29 +Subproject commit 39860a109853b2f37367dfe68905e019b509d5bf From d095d0bdbc30ca6c1c4927b2d1b7e1836fa9cd5e Mon Sep 17 00:00:00 2001 From: Garrick He <32883830+GarrickHe@users.noreply.github.com> Date: Sat, 28 Mar 2020 11:43:48 -0700 Subject: [PATCH 0473/1427] [procdockerstatsd] Fix CMD field in dB (#4335) * Fix the CMD for the PROCESSSTATS entries so that there is a space between the command name and the arguments. Signed-off-by: Garrick He --- files/image_config/procdockerstatsd/procdockerstatsd | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd index a7bdcd6e6ce6..65d4b029b0ff 100755 --- a/files/image_config/procdockerstatsd/procdockerstatsd +++ b/files/image_config/procdockerstatsd/procdockerstatsd @@ -41,8 +41,8 @@ class ProcDockerStats: def __init__(self): self.state_db = swsssdk.SonicV2Connector(host=REDIS_HOSTIP) - self.state_db.connect("STATE_DB") - + self.state_db.connect("STATE_DB") + def run_command(self, cmd): proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) (stdout, stderr) = proc.communicate() @@ -75,7 +75,7 @@ class ProcDockerStats: # To remove extra space before UID val = list(filter(None, values1)) # Merging extra columns created due to space in cmd ouput - val[8:] = [''.join(val[8:])] + val[8:] = [' '.join(val[8:])] process_data = dict(zip(keylist, val)) process_data_list.append(process_data) return process_data_list @@ -109,10 +109,10 @@ class ProcDockerStats: for row in dict_list[0:]: cid = row.get('CONTAINER ID') if cid: - key = 'DOCKER_STATS|' + str(cid) + key = 'DOCKER_STATS|' + str(cid) dockerdict[key] = {} dockerdict[key]['NAME'] = row.get('NAME') - + splitcol = row.get('CPU %') cpu = re.split("%", str(splitcol)) dockerdict[key]['CPU%'] = str(cpu[0]) @@ -131,7 +131,7 @@ class ProcDockerStats: netio = re.split(" / ", str(splitcol)) dockerdict[key]['NET_IN_BYTES'] = str(self.convert_to_bytes(netio[0])) dockerdict[key]['NET_OUT_BYTES'] = str(self.convert_to_bytes(netio[1])) - + splitcol = row.get('BLOCK I/O') blockio = re.split(" / ", str(splitcol)) dockerdict[key]['BLOCK_IN_BYTES'] = str(self.convert_to_bytes(blockio[0])) From 0fe58af6d2e1ae3eed04d5f296bb54579318c4ab Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sat, 28 Mar 2020 21:45:38 +0300 Subject: [PATCH 0474/1427] copy spc3 fw file to image (#4328) --- files/build_templates/sonic_debian_extension.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index b62d24441a7f..d9701970c531 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -459,6 +459,7 @@ sudo cp {{src}} $FILESYSTEM_ROOT/{{dst}} sudo mkdir -p $FILESYSTEM_ROOT/etc/mlnx/ sudo cp $files_path/$MLNX_SPC_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC.mfa sudo cp $files_path/$MLNX_SPC2_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC2.mfa +sudo cp $files_path/$MLNX_SPC3_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC3.mfa sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh sudo cp $files_path/$ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/onie-fw-update.sh From 84256314fec8f96bf7498fe99a140a53a80b4ad3 Mon Sep 17 00:00:00 2001 From: rkdevi27 <54701695+rkdevi27@users.noreply.github.com> Date: Sun, 29 Mar 2020 00:18:22 +0530 Subject: [PATCH 0475/1427] DellEMC: Platform 2.0 Api - Fan for z9264f (#4191) --- .../debian/platform-modules-z9264f.install | 2 +- ...{qsfp_irq_enable.py => port_irq_enable.py} | 0 .../z9264f/scripts/z9264f_platform.sh | 3 +- .../z9264f/sonic_platform/__init__.py | 5 +- .../z9264f/sonic_platform/chassis.py | 10 +- .../z9264f/sonic_platform/fan.py | 174 ++++++++++++++++++ .../z9264f/sonic_platform/psu.py | 4 + 7 files changed, 192 insertions(+), 6 deletions(-) rename platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/{qsfp_irq_enable.py => port_irq_enable.py} (100%) create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan.py diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install index ffe23322fb83..5c247bdd8e0d 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install @@ -3,7 +3,7 @@ z9264f/scripts/check_qsfp.sh usr/local/bin z9264f/scripts/platform_sensors.py usr/local/bin z9264f/scripts/sensors usr/bin z9264f/scripts/pcisysfs.py usr/bin -z9264f/scripts/qsfp_irq_enable.py usr/bin +z9264f/scripts/port_irq_enable.py usr/bin z9264f/cfg/z9264f-modules.conf etc/modules-load.d z9264f/systemd/platform-modules-z9264f.service etc/systemd/system z9264f/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/port_irq_enable.py similarity index 100% rename from platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py rename to platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/port_irq_enable.py diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh index 05f8623db0a6..33812c54b6eb 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh @@ -213,9 +213,10 @@ if [ "$1" == "init" ]; then switch_board_modsel init_switch_port_led install_python_api_package - python /usr/bin/qsfp_irq_enable.py + python /usr/bin/port_irq_enable.py platform_firmware_versions + elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" switch_board_qsfp "delete_device" diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py index 30e0d8cbfecd..656052a68223 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py @@ -1,3 +1,2 @@ -__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal"] -from sonic_platform import * - +__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal", "fan"] +from sonic_platform import * \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py index 4df8dc5df8c2..cefa7ab49561 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py @@ -16,10 +16,13 @@ from sonic_platform.eeprom import Eeprom from sonic_platform.component import Component from sonic_platform.psu import Psu + from sonic_platform.fan import Fan from sonic_platform.thermal import Thermal except ImportError as e: raise ImportError(str(e) + "- required module not found") +MAX_Z9264F_FANTRAY =4 +MAX_Z9264F_FAN = 2 MAX_Z9264F_COMPONENT = 8 # BIOS,BMC,FPGA,SYSTEM CPLD,4 SLAVE CPLDs MAX_Z9264F_PSU = 2 MAX_Z9264F_THERMAL = 8 @@ -66,7 +69,12 @@ def __init__(self): for i in range(MAX_Z9264F_PSU): psu = Psu(i) self._psu_list.append(psu) - + + for i in range(MAX_Z9264F_FANTRAY): + for j in range(MAX_Z9264F_FAN): + fan = Fan(i,j) + self._fan_list.append(fan) + for i in range(MAX_Z9264F_THERMAL): thermal = Thermal(i) self._thermal_list.append(thermal) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan.py new file mode 100644 index 000000000000..17b2f8db5b91 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9264F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_base import FanBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +#Derived the offset from BMC management information +FAN1_MAX_SPEED_OFFSET = 71 +FAN2_MAX_SPEED_OFFSET = 73 +PSU_FAN_MAX_SPEED_OFFSET = 50 +FAN_DIRECTION_OFFSET = 69 +PSU_FAN_DIRECTION_OFFSET = 47 + + +class Fan(FanBase): + """DellEMC Platform-specific Fan class""" + #Derived the sensor IDs from BMC + # { FAN-ID: { Sensor-Name: Sensor-ID } } + FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x51, "State": 0x64, "Speed": 0x24}, + 2: {"Prsnt": 0x51, "State": 0x60, "Speed": 0x20}, + 3: {"Prsnt": 0x52, "State": 0x65, "Speed": 0x25}, + 4: {"Prsnt": 0x52, "State": 0x61, "Speed": 0x21}, + 5: {"Prsnt": 0x53, "State": 0x66, "Speed": 0x26}, + 6: {"Prsnt": 0x53, "State": 0x62, "Speed": 0x22}, + 7: {"Prsnt": 0x54, "State": 0x67, "Speed": 0x27}, + 8: {"Prsnt": 0x54, "State": 0x63, "Speed": 0x23} } + PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x46, "Speed": 0x2e}, + 2: {"State": 0x47, "Speed": 0x2f} } + + # { FANTRAY-ID: FRU-ID } + FAN_FRU_MAPPING = { 1: 1, 2: 2, 3: 3, 4: 4 } + PSU_FRU_MAPPING = { 1: 6, 2: 7 } + + def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, + dependency=None): + self.is_psu_fan = psu_fan + if not self.is_psu_fan: + # API index is starting from 0, DellEMC platform index is + # starting from 1 + self.fantrayindex = fantray_index + 1 + self.fanindex = fan_index + 1 + if (self.fanindex == 1): + self.max_speed_offset = FAN1_MAX_SPEED_OFFSET + else: + self.max_speed_offset = FAN2_MAX_SPEED_OFFSET + self.fan_direction_offset = FAN_DIRECTION_OFFSET + self.index = (self.fantrayindex - 1) * 2 + self.fanindex + self.prsnt_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], + is_discrete=True) + self.state_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["State"], + is_discrete=True) + self.speed_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Speed"]) + self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) + else: + self.dependency = dependency + self.fanindex = fan_index + self.state_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], + is_discrete=True) + self.speed_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) + self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) + self.max_speed_offset = PSU_FAN_MAX_SPEED_OFFSET + self.fan_direction_offset = PSU_FAN_DIRECTION_OFFSET + self.max_speed = self.fru.get_fru_data(self.max_speed_offset,2)[1] + self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] + + def get_name(self): + """ + Retrieves the name of the device + Returns: + String: The name of the device + """ + if self.is_psu_fan: + return "PSU{} Fan".format(self.fanindex) + else: + return "FanTray{}-Fan{}".format(self.fantrayindex, self.fanindex) + + def get_model(self): + """ + Retrieves the part number of the FAN + Returns: + String: Part number of FAN + """ + if self.is_psu_fan: + return 'NA' + else: + return self.fru.get_board_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the FAN + Returns: + String: Serial number of FAN + """ + if self.is_psu_fan: + return 'NA' + else: + return self.fru.get_board_serial() + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if fan is present, False if not + """ + presence = False + if self.is_psu_fan: + return self.dependency.get_presence() + else: + is_valid, state = self.prsnt_sensor.get_reading() + if is_valid: + if (state & 0b1): + presence = True + return presence + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state == 0x00): + status = True + return status + + def get_direction(self): + """ + Retrieves the fan airfow direction + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. + """ + direction = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE] + fan_status = self.get_status() + if not fan_status: + return 'NA' + is_valid, fan_direction = self.fru.get_fru_data(self.fan_direction_offset) + if is_valid: + return direction[fan_direction[0]] + else: + return 'NA' + + def get_speed(self): + """ + Retrieves the speed of the fan + Returns: + int: percentage of the max fan speed + """ + if self.max_speed == 0: + self.max_speed = self.fru.get_fru_data(self.max_speed_offset,2)[1] + self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] + is_valid, fan_speed = self.speed_sensor.get_reading() + if not is_valid or self.max_speed == 0: + speed = 0 + else: + speed = (100 * fan_speed)/self.max_speed + return speed diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py index 374ac2e1c202..7f213edbd451 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py @@ -12,6 +12,7 @@ try: from sonic_platform_base.psu_base import PsuBase from sonic_platform.ipmihelper import IpmiSensor, IpmiFru + from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -38,6 +39,9 @@ def __init__(self, psu_index): self.power_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Power"]) self.fru = IpmiFru(self.FRU_MAPPING[self.index]) + self._fan_list.append(Fan(fan_index=self.index, psu_fan=True, + dependency=self)) + def get_name(self): """ Retrieves the name of the device From eede9a9db98e177d77270d9a916711711bb822ae Mon Sep 17 00:00:00 2001 From: padmanarayana Date: Sat, 28 Mar 2020 23:49:09 -0700 Subject: [PATCH 0476/1427] sFlow : Upgrade hsflowd to v2.0.26-4 (#4301) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per SONiC CLI requirements, we wanted the collector port to default to 6343 if not explicitly configured. In the Click based CLI, if the collector port is omitted, the port will be set to 6343 by default (https://github.com/Azure/sonic-utilities/blob/master/config/main.py#L2543). However, if sonic-mgmt-framework based CLI is used, hsflowd was using port 0 as default. host-sflow v2.0.26-4 addresses this issue (i.e. use 6343 in case “collector_port†is not set). Upgrade hsflowd to v2.0.26-4 to pick up https://github.com/sflow/host-sflow/releases/tag/v2.0.26-4. --- rules/sflow.mk | 2 +- src/sflow/hsflowd/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/sflow.mk b/rules/sflow.mk index d4c579ddf167..a7ca1b3b1d0d 100644 --- a/rules/sflow.mk +++ b/rules/sflow.mk @@ -1,7 +1,7 @@ # host-sflow package HSFLOWD_VERSION = 2.0.26 -HSFLOWD_SUBVERSION = 3 +HSFLOWD_SUBVERSION = 4 export HSFLOWD_VERSION HSFLOWD_SUBVERSION HSFLOWD = hsflowd_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb diff --git a/src/sflow/hsflowd/Makefile b/src/sflow/hsflowd/Makefile index e3a930549f19..f0b15c78bd3c 100644 --- a/src/sflow/hsflowd/Makefile +++ b/src/sflow/hsflowd/Makefile @@ -10,7 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git clone https://github.com/sflow/host-sflow pushd ./host-sflow - git checkout -b sflow tags/v2.0.26-3 + git checkout -b sflow tags/v2.0.26-4 # Apply patch series stg init From 1a0067ede074a6fa772296e94c815dc63a9515ac Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Mon, 30 Mar 2020 19:24:16 +0300 Subject: [PATCH 0477/1427] Bug fix: #4011 #4012 - "show run acl", "show run interfaces" - traceback when no ACL_RULE/INTERFACE is present. (#4226) * Fix bugs - "show run acl/interfaces" returns traceback when no ACL_RULE/INTERFACE is present in configuration - Change logic in main to take data only if the var_json appears in DB. - Add unit testing for bug fix & fix comments Signed-off-by: Noa Or --- src/sonic-config-engine/sonic-cfggen | 2 +- src/sonic-config-engine/tests/test_cfggen.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 13fc871d775a..dddfde32428b 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -295,7 +295,7 @@ def main(): template = jinja2.Template('{{' + args.var + '}}') print(template.render(data)) - if args.var_json != None: + if args.var_json != None and args.var_json in data: if args.key != None: print(json.dumps(FormatConverter.to_serialized(data[args.var_json], args.key), indent=4, cls=minigraph_encoder)) else: diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 2ae28946a905..7f5eb155092f 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -331,3 +331,13 @@ def test_minigraph_sub_port_interfaces(self, check_stderr=True): output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (BACKEND_TOR_ROUTER, TOR_ROUTER, self.sample_graph_simple), shell=True) self.test_jinja_expression(self.sample_graph_simple, TOR_ROUTER) + + def test_show_run_acl(self): + argument = '-a \'{"key1":"value"}\' --var-json ACL_RULE' + output = self.run_script(argument) + self.assertEqual(output, '') + + def test_show_run_interfaces(self): + argument = '-a \'{"key1":"value"}\' --var-json INTERFACE' + output = self.run_script(argument) + self.assertEqual(output, '') From 2c9732154546d91ec0a954814ac6721ef1b1e500 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Tue, 31 Mar 2020 08:50:57 +0800 Subject: [PATCH 0478/1427] [sonic-mgmt]: Support virtual environment for ansible 2.0.0.2 (#4325) . env-201811/bin/activate The ansible 2.0.0.2 will be used. --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 662f781dc7c0..733f81be2cc8 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -53,6 +53,7 @@ RUN pip install ipaddr \ paramiko==2.1.2 \ passlib \ ipython==5.4.1 \ + virtualenv \ && git clone https://github.com/p4lang/scapy-vxlan.git \ && cd scapy-vxlan \ && python setup.py install \ @@ -147,4 +148,8 @@ RUN azure-cli_bundle_*/installer # TODO: if azure-cli contains newer version azure-keyvault, remove this RUN ~/lib/azure-cli/bin/python -m pip install azure-keyvault==0.3.7 -U +# Install Virtual Environment +RUN python -m virtualenv --system-site-packages env-201803 +RUN env-201811/bin/pip install ansible==2.0.0.2 + RUN git clone https://github.com/Azure/sonic-mgmt From 4b8067e913d68dfcf27a924ebc855848530e8d70 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Tue, 31 Mar 2020 10:06:19 -0700 Subject: [PATCH 0479/1427] Multi-ASIC implementation (#3888) Changes made to support multi-asic platform. Added multi-instance support for swss, syncd, database, bgp, teamd and lldp. --- .../msft_multi_asic_vs/0/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/0/sai.profile | 7 +- .../msft_multi_asic_vs/1/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/1/sai.profile | 7 +- .../msft_multi_asic_vs/2/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/2/sai.profile | 7 +- .../msft_multi_asic_vs/3/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/3/sai.profile | 7 +- .../msft_multi_asic_vs/4/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/4/sai.profile | 7 +- .../msft_multi_asic_vs/5/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/5/sai.profile | 7 +- .../msft_multi_asic_vs/topology.sh | 13 +-- dockers/docker-fpm-frr/bgpd.conf.default.j2 | 20 ++++ files/build_templates/database.service.j2 | 1 + files/build_templates/docker_image_ctl.j2 | 69 +++++++----- files/build_templates/lldp.service.j2 | 18 ---- .../per_namespace/bgp.service.j2 | 21 ++++ .../per_namespace/database.service.j2 | 22 ++++ .../per_namespace/lldp.service.j2 | 22 ++++ .../per_namespace/swss.service.j2 | 31 ++++++ .../per_namespace/syncd.service.j2 | 33 ++++++ .../per_namespace/teamd.service.j2 | 19 ++++ .../single_instance/bgp.service.j2 | 18 ---- .../single_instance/database.service.j2 | 18 ---- .../single_instance/swss.service.j2 | 25 ----- .../single_instance/syncd.service.j2 | 30 ------ .../single_instance/teamd.service.j2 | 18 ---- .../build_templates/sonic_debian_extension.j2 | 4 + files/image_config/topology/topology.sh | 18 ++-- files/scripts/sonic-netns-exec | 12 +++ files/scripts/swss.sh | 100 ++++++++++++------ files/scripts/syncd.sh | 55 ++++++---- platform/vs/sonic_multiasic.xml | 2 +- rules/docker-fpm-frr.mk | 1 - slave.mk | 28 +++-- 36 files changed, 586 insertions(+), 246 deletions(-) create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini create mode 120000 files/build_templates/database.service.j2 delete mode 100644 files/build_templates/lldp.service.j2 create mode 100644 files/build_templates/per_namespace/bgp.service.j2 create mode 100644 files/build_templates/per_namespace/database.service.j2 create mode 100644 files/build_templates/per_namespace/lldp.service.j2 create mode 100644 files/build_templates/per_namespace/swss.service.j2 create mode 100644 files/build_templates/per_namespace/syncd.service.j2 create mode 100644 files/build_templates/per_namespace/teamd.service.j2 delete mode 100644 files/build_templates/single_instance/bgp.service.j2 delete mode 100644 files/build_templates/single_instance/database.service.j2 delete mode 100644 files/build_templates/single_instance/swss.service.j2 delete mode 100644 files/build_templates/single_instance/syncd.service.j2 delete mode 100644 files/build_templates/single_instance/teamd.service.j2 create mode 100755 files/scripts/sonic-netns-exec diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh index 378f794190d4..cf70f3063189 100755 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh @@ -14,9 +14,10 @@ start () { # eth48 - eth63: asic5 for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for NUM in `seq 1 16`; do - ORIG="eth$((16 * $ASIC + $NUM - 1))" + ORIG="eth$((16 * $ASIC + $NUM))" TEMP="ethTemp999" - NEW="eth$(($NUM + 16))" + NEW="eth$(($NUM))" + echo "$ASIC : $NEW old $ORIG" ip link set dev $ORIG down ip link set dev $ORIG name $TEMP # rename to prevent conflicts before renaming in new namespace ip link set dev $TEMP netns asic$ASIC @@ -29,8 +30,9 @@ start () { for BACKEND in `seq $FIRST_BACKEND_ASIC $LAST_BACKEND_ASIC`; do for FRONTEND in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for LINK in `seq 1 8`; do - BACK_NAME="eth$((8 * $FRONTEND + $LINK))" - FRONT_NAME="eth$((8 * $(($LAST_BACKEND_ASIC - $BACKEND)) + $LINK))" + FRONT_NAME="eth$((8 * $(($BACKEND - $FIRST_BACKEND_ASIC)) + $LINK + 16))" + BACK_NAME="eth$((8 * $FRONTEND + $LINK))" + echo "$FRONTEND:$FRONT_NAME - $BACKEND:$BACK_NAME" TEMP_BACK="ethBack999" TEMP_FRONT="ethFront999" @@ -52,7 +54,7 @@ stop() { for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for NUM in `seq 1 16`; do TEMP="eth999" - OLD="eth$(($NUM + 16))" + OLD="eth$((16 * $ASIC + $NUM))" NAME="eth$((16 * $ASIC + $NUM - 1))" sudo ip netns exec asic$ASIC ip link set dev $OLD down sudo ip netns exec asic$ASIC ip link set dev $OLD name $TEMP @@ -78,4 +80,3 @@ case "$1" in echo "Usage: $0 {start|stop}" ;; esac - diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index e12782b035aa..2bf80b80a787 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -23,6 +23,20 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +{% endif %} +{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} +route-map OVERRIDE_ORIGINATOR_ID permit 10 +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name == 'Loopback0' %} + set originator-id {{ prefix | ip }} +{% endif %} +{% endfor %} +! +{% endif %} {% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} route-map FROM_BGPMON deny 10 ! @@ -37,6 +51,9 @@ route-map set-next-hop-global-v6 permit 10 set ipv6 next-hop prefer-global ! router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} + redistribute connected route-map HIDE_INTERNAL +{% endif %} bgp log-neighbor-changes bgp bestpath as-path multipath-relax no bgp default ipv4-unicast @@ -151,6 +168,9 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} neighbor {{ neighbor_addr }} peer-group BGPMON neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} neighbor {{ neighbor_addr }} activate +{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} + neighbor {{ neighbor_addr }} route-map OVERRIDE_ORIGINATOR_ID in +{% endif %} address-family ipv6 neighbor {{ neighbor_addr }} activate exit-address-family diff --git a/files/build_templates/database.service.j2 b/files/build_templates/database.service.j2 new file mode 120000 index 000000000000..63340abef881 --- /dev/null +++ b/files/build_templates/database.service.j2 @@ -0,0 +1 @@ +per_namespace/database.service.j2 \ No newline at end of file diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 5de892555a1b..297c9dd1c2bd 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -14,15 +14,16 @@ link_namespace() { mkdir -p /var/run/netns PID="$(docker inspect -f {{"'{{.State.Pid}}'"}} "{{docker_container_name}}$DEV")" - if `ip netns | grep --quiet -w "{{docker_container_name}}$DEV"`; then # namespace exists - if [ $(readlink -f /var/run/netns/$NET_NS$DEV) = $(readlink -f /proc/$PID/ns/net) ]; then # namespace is correctly linked + PIDS=`ip netns pids "$NET_NS" 2>/dev/null` + if [ "$?" -eq "0" ]; then # namespace exists + if `echo $PIDS | grep --quiet -w $PID`; then # namespace is correctly linked return 0 else # if it's incorrectly linked remove it - ip netns delete "{{docker_container_name}}$DEV" + ip netns delete $NET_NS fi fi - ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS$DEV + ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS } {%- endif %} @@ -56,14 +57,14 @@ function preStartAction() WARM_DIR=/host/warmboot if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then # Load redis content from /host/warmboot/dump.rdb - docker cp $WARM_DIR/dump.rdb database:/var/lib/redis/dump.rdb + docker cp $WARM_DIR/dump.rdb database$DEV:/var/lib/redis/dump.rdb else # Create an emtpy file and overwrite any RDB if already there echo -n > /tmp/dump.rdb - docker cp /tmp/dump.rdb database:/var/lib/redis/ + docker cp /tmp/dump.rdb database$DEV:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) {%- else %} : # nothing {%- endif %} @@ -76,25 +77,25 @@ function postStartAction() link_namespace $DEV fi # Wait until redis starts - /usr/bin/docker exec database ping_pong_db_insts + /usr/bin/docker exec database$DEV ping_pong_db_insts if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else # If there is a config_db.json dump file, load it. - if [ -r /etc/sonic/config_db.json ]; then + if [ -r /etc/sonic/config_db$DEV.json ]; then if [ -r /etc/sonic/init_cfg.json ]; then - sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --write-to-db + sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db$DEV.json --write-to-db else - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/config_db$DEV.json --write-to-db fi fi if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" + /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" fi - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then @@ -102,14 +103,14 @@ function postStartAction() /usr/bin/db_migrator.py -o migrate fi {%- elif docker_container_name == "swss" %} - docker exec swss rm -f /ready # remove cruft + docker exec swss$DEV rm -f /ready # remove cruft if [[ "$BOOT_TYPE" == "fast" ]] && [[ -d /host/fast-reboot ]]; then - test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss:/ - test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss:/ - test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss:/ + test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss$DEV:/ + test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss$DEV:/ + test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss$DEV:/ rm -fr /host/fast-reboot fi - docker exec swss touch /ready # signal swssconfig.sh to go + docker exec swss$DEV touch /ready # signal swssconfig.sh to go {%- elif docker_container_name == "pmon" %} DEVPATH="/usr/share/sonic/device" @@ -131,14 +132,14 @@ start() { BOOT_TYPE=`getBootType` # Obtain our platform as we will mount directories with these names in each docker - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PLATFORM=`sonic-netns-exec "$NET_NS" sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` {%- if docker_container_name == "database" %} # Don't mount HWSKU in {{docker_container_name}} container. HWSKU="" {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + HWSKU=`sonic-netns-exec "$NET_NS" sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` {%- endif %} DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` @@ -185,7 +186,14 @@ start() { NET="container:database$DEV" {%- endif %} fi - +{%- if docker_container_name == "bgp" %} + if [ "$DEV" ]; then + if [ ! -d "/etc/sonic/frr/$DEV" ]; then + mkdir /etc/sonic/frr/$DEV + cp -r /etc/sonic/frr/*.conf /etc/sonic/frr/$DEV + fi + fi +{%- endif %} {%- if sonic_asic_platform == "mellanox" %} # TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version {%- endif %} @@ -215,10 +223,13 @@ start() { --tmpfs /tmp \ {%- endif %} {%- endif %} - -v /var/run/redis:/var/run/redis:rw \ +{%- if docker_container_name == "bgp" %} + -v /etc/sonic/frr/$DEV:/etc/frr:rw \ +{%- endif %} + -v /var/run/redis$DEV:/var/run/redis:rw \ -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ {%- if docker_container_name != "database" %} - -v /usr/share/sonic/device/$PLATFORM/$HWSKU:/usr/share/sonic/hwsku:ro \ + -v /usr/share/sonic/device/$PLATFORM/$HWSKU/$DEV:/usr/share/sonic/hwsku:ro \ {%- endif %} {%- if sonic_asic_platform != "mellanox" %} --tmpfs /tmp \ @@ -230,7 +241,7 @@ start() { } preStartAction - docker start {{docker_container_name}} + docker start {{docker_container_name}}$DEV postStartAction } @@ -241,13 +252,19 @@ wait() { stop() { docker stop {{docker_container_name}}$DEV {%- if docker_container_name == "database" %} - ip netns delete "$NET_NS$DEV" + if [ "$DEV" ]; then + ip netns delete "$NET_NS" + fi {%- endif %} } OP=$1 DEV=$2 # namespace/device number to operate on -NET_NS="asic" #name of the network namespace +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi case "$1" in start|wait|stop) diff --git a/files/build_templates/lldp.service.j2 b/files/build_templates/lldp.service.j2 deleted file mode 100644 index 2599fc5c5bdc..000000000000 --- a/files/build_templates/lldp.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=LLDP container -Requires=updategraph.service -After=updategraph.service swss.service syncd.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/bgp.service.j2 b/files/build_templates/per_namespace/bgp.service.j2 new file mode 100644 index 000000000000..79e9afc4ebc1 --- /dev/null +++ b/files/build_templates/per_namespace/bgp.service.j2 @@ -0,0 +1,21 @@ +[Unit] +Description=BGP container +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} + +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/database.service.j2 b/files/build_templates/per_namespace/database.service.j2 new file mode 100644 index 000000000000..396fdc6678c2 --- /dev/null +++ b/files/build_templates/per_namespace/database.service.j2 @@ -0,0 +1,22 @@ +[Unit] +Description=Database container +{% if multi_instance == 'true' %} +Requires=database.service +After=database.service +{% endif %} +Requires=docker.service +After=docker.service +After=rc-local.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/lldp.service.j2 b/files/build_templates/per_namespace/lldp.service.j2 new file mode 100644 index 000000000000..b48675b03202 --- /dev/null +++ b/files/build_templates/per_namespace/lldp.service.j2 @@ -0,0 +1,22 @@ +[Unit] +Description=LLDP container +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +After=syncd{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/swss.service.j2 b/files/build_templates/per_namespace/swss.service.j2 new file mode 100644 index 000000000000..53d6b4497df7 --- /dev/null +++ b/files/build_templates/per_namespace/swss.service.j2 @@ -0,0 +1,31 @@ +[Unit] +Description=switch state service +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +{% if multi_instance == 'true' and sonic_asic_platform == 'vs' %} +Requires=topology.service +After=topology.service +{% endif %} +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-11-2-amd64.service +{% endif %} +Requires=updategraph.service +After=updategraph.service +After=interfaces-config.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/swss.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/local/bin/swss.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/local/bin/swss.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/syncd.service.j2 b/files/build_templates/per_namespace/syncd.service.j2 new file mode 100644 index 000000000000..b2922e0d12b6 --- /dev/null +++ b/files/build_templates/per_namespace/syncd.service.j2 @@ -0,0 +1,33 @@ +[Unit] +Description=syncd service +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +{% if multi_instance == 'true' and sonic_asic_platform == 'vs' %} +Requires=topology.service +After=topology.service +{% endif %} +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +After=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-11-2-amd64.service +After=nps-modules-4.9.0-11-2-amd64.service +{% endif %} +Requires=updategraph.service +After=updategraph.service +After=interfaces-config.service +Before=ntp-config.service + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/syncd.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/local/bin/syncd.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/local/bin/syncd.sh stop{% if multi_instance == 'true' %} %i{% endif %} +{% if sonic_asic_platform == 'mellanox' %} +TimeoutStartSec=150 +{% endif %} + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/teamd.service.j2 b/files/build_templates/per_namespace/teamd.service.j2 new file mode 100644 index 000000000000..092f9d2ebde2 --- /dev/null +++ b/files/build_templates/per_namespace/teamd.service.j2 @@ -0,0 +1,19 @@ +[Unit] +Description=TEAMD container +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/bgp.service.j2 b/files/build_templates/single_instance/bgp.service.j2 deleted file mode 100644 index fdf9d9c78c04..000000000000 --- a/files/build_templates/single_instance/bgp.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=BGP container -Requires=updategraph.service -After=updategraph.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/database.service.j2 b/files/build_templates/single_instance/database.service.j2 deleted file mode 100644 index fd0063195e31..000000000000 --- a/files/build_templates/single_instance/database.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=Database container -Requires=docker.service -After=docker.service -After=rc-local.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User=root -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/swss.service.j2 b/files/build_templates/single_instance/swss.service.j2 deleted file mode 100644 index 44206b08ebce..000000000000 --- a/files/build_templates/single_instance/swss.service.j2 +++ /dev/null @@ -1,25 +0,0 @@ -[Unit] -Description=switch state service -Requires=database.service updategraph.service -{% if sonic_asic_platform == 'broadcom' %} -Requires=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service -{% endif %} -After=database.service updategraph.service -After=interfaces-config.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User=root -Environment=sonic_asic_platform={{ sonic_asic_platform }} -ExecStartPre=/usr/local/bin/swss.sh start -ExecStart=/usr/local/bin/swss.sh wait -ExecStop=/usr/local/bin/swss.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/syncd.service.j2 b/files/build_templates/single_instance/syncd.service.j2 deleted file mode 100644 index 7a7d27114b07..000000000000 --- a/files/build_templates/single_instance/syncd.service.j2 +++ /dev/null @@ -1,30 +0,0 @@ -[Unit] -Description=syncd service -Requires=database.service updategraph.service -{% if sonic_asic_platform == 'broadcom' %} -Requires=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service -{% endif %} -After=database.service updategraph.service -After=interfaces-config.service -{% if sonic_asic_platform == 'broadcom' %} -After=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -After=nps-modules-4.9.0-11-2-amd64.service -{% endif %} -After=swss.service -Before=ntp-config.service - -[Service] -User=root -Environment=sonic_asic_platform={{ sonic_asic_platform }} -ExecStartPre=/usr/local/bin/syncd.sh start -ExecStart=/usr/local/bin/syncd.sh wait -ExecStop=/usr/local/bin/syncd.sh stop -{% if sonic_asic_platform == 'mellanox' %} -TimeoutStartSec=150 -{% endif %} - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/teamd.service.j2 b/files/build_templates/single_instance/teamd.service.j2 deleted file mode 100644 index be0521a4fbec..000000000000 --- a/files/build_templates/single_instance/teamd.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=TEAMD container -Requires=updategraph.service -After=updategraph.service swss.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index d9701970c531..bdecdabe95d1 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -284,6 +284,7 @@ j2 files/build_templates/init_cfg.json.j2 | sudo tee $FILESYSTEM_ROOT/etc/sonic/ # Copy config-setup script and service file j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/config-setup.service sudo cp $IMAGE_CONFIGS/config-setup/config-setup $FILESYSTEM_ROOT/usr/bin/config-setup +echo "config-setup.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-setup.service # Copy SNMP configuration files @@ -434,6 +435,9 @@ sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys sudo LANG=C cp $SCRIPTS_DIR/swss.sh $FILESYSTEM_ROOT/usr/local/bin/swss.sh sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh +# Copy sonic-netns-exec script +sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netns-exec + # Copy systemd timer configuration # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ diff --git a/files/image_config/topology/topology.sh b/files/image_config/topology/topology.sh index 7013920ec016..dde7da247484 100755 --- a/files/image_config/topology/topology.sh +++ b/files/image_config/topology/topology.sh @@ -6,18 +6,16 @@ # start() { - DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" - TOPOLOGY_SCRIPT="topology.sh" - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` - /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start } stop() { - DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" - TOPOLOGY_SCRIPT="topology.sh" - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` - /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop } case "$1" in diff --git a/files/scripts/sonic-netns-exec b/files/scripts/sonic-netns-exec new file mode 100755 index 000000000000..166a2c7e4a2f --- /dev/null +++ b/files/scripts/sonic-netns-exec @@ -0,0 +1,12 @@ +#!/bin/bash +# Wrapper to execute any command in a specific +# network namespace. +# Usage: +# sonic-netns-exec +NS="$1" +shift +if [ "$NS" != "" ]; then + ip netns exec $NS $@ +else + $@ +fi diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index a14d03e40f50..360e331f3636 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -1,10 +1,7 @@ #!/bin/bash -SERVICE="swss" -PEER="syncd" -DEPENDENT="teamd radv dhcp_relay" -DEBUGLOG="/tmp/swss-syncd-debug.log" -LOCKFILE="/tmp/swss-syncd-lock" +DEPENDENT="radv dhcp_relay" +MULTI_INST_DEPENDENT="teamd" function debug() { @@ -14,25 +11,25 @@ function debug() function lock_service_state_change() { - debug "Locking ${LOCKFILE} from ${SERVICE} service" + debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" exec {LOCKFD}>${LOCKFILE} /usr/bin/flock -x ${LOCKFD} trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" } function unlock_service_state_change() { - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" /usr/bin/flock -u ${LOCKFD} } function check_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -43,7 +40,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -54,10 +51,10 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + /usr/bin/docker exec database$DEV ping_pong_db_insts # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -67,7 +64,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - sonic-db-cli $1 EVAL " + sonic-netns-exec "$NET_NS" sonic-db-cli $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -81,25 +78,48 @@ start_peer_and_dependent_services() { check_warm_boot if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl start ${PEER} + if [[ ! -z $DEV ]]; then + /bin/systemctl start ${PEER}@$DEV + else + /bin/systemctl start ${PEER} + fi for dep in ${DEPENDENT}; do /bin/systemctl start ${dep} done + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + /bin/systemctl start ${dep}@$DEV + else + /bin/systemctl start ${dep} + fi + done fi } stop_peer_and_dependent_services() { # if warm start enabled or peer lock exists, don't stop peer service docker if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl stop ${PEER} + if [[ ! -z $DEV ]]; then + /bin/systemctl stop ${PEER}@$DEV + else + /bin/systemctl stop ${PEER} + fi for dep in ${DEPENDENT}; do /bin/systemctl stop ${dep} done + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + /bin/systemctl stop ${dep}@$DEV + else + /bin/systemctl stop ${dep} + fi + done + fi } start() { - debug "Starting ${SERVICE} service..." + debug "Starting ${SERVICE}$DEV service..." lock_service_state_change @@ -107,21 +127,21 @@ start() { check_warm_boot validate_restore_count - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - sonic-db-cli APPL_DB FLUSHDB - sonic-db-cli ASIC_DB FLUSHDB - sonic-db-cli COUNTERS_DB FLUSHDB - sonic-db-cli FLEX_COUNTER_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli APPL_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli ASIC_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli COUNTERS_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli FLEX_COUNTER_DB FLUSHDB clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker - /usr/bin/${SERVICE}.sh start - debug "Started ${SERVICE} service..." + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE}$DEV service..." # Unlock has to happen before reaching out to peer service unlock_service_state_change @@ -134,7 +154,11 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services for SECS in {1..60}; do - RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) + if [[ ! -z $DEV ]]; then + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}$DEV) + else + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) + fi if [[ x"$RUNNING" == x"true" ]]; then break else @@ -144,20 +168,24 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services - /usr/bin/docker-wait-any ${SERVICE} ${PEER} + if [[ ! -z $DEV ]]; then + /usr/bin/docker-wait-any ${SERVICE}$DEV ${PEER}$DEV + else + /usr/bin/docker-wait-any ${SERVICE} ${PEER} + fi } stop() { - debug "Stopping ${SERVICE} service..." + debug "Stopping ${SERVICE}$DEV service..." [[ -f ${LOCKFILE} ]] || /usr/bin/touch ${LOCKFILE} lock_service_state_change check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." - /usr/bin/${SERVICE}.sh stop - debug "Stopped ${SERVICE} service..." + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." # Flush FAST_REBOOT table when swss needs to stop. The only # time when this would take effect is when fast-reboot @@ -172,6 +200,18 @@ stop() { stop_peer_and_dependent_services } +DEV=$2 + +SERVICE="swss" +PEER="syncd" +DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" +LOCKFILE="/tmp/swss-syncd-lock$DEV" +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi + case "$1" in start|wait|stop) $1 diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 4b47e7ad4c45..9847cfec9406 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -1,9 +1,5 @@ #!/bin/bash -SERVICE="syncd" -PEER="swss" -DEBUGLOG="/tmp/swss-syncd-debug.log" -LOCKFILE="/tmp/swss-syncd-lock" function debug() { @@ -13,25 +9,25 @@ function debug() function lock_service_state_change() { - debug "Locking ${LOCKFILE} from ${SERVICE} service" + debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" exec {LOCKFD}>${LOCKFILE} /usr/bin/flock -x ${LOCKFD} trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" } function unlock_service_state_change() { - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" /usr/bin/flock -u ${LOCKFD} } function check_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -43,10 +39,10 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + /usr/bin/docker exec database$DEV ping_pong_db_insts # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -63,7 +59,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' @@ -76,7 +72,7 @@ function getBootType() } start() { - debug "Starting ${SERVICE} service..." + debug "Starting ${SERVICE}$DEV service..." lock_service_state_change @@ -85,7 +81,7 @@ start() { wait_for_database_service check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." if [[ x"$WARM_BOOT" == x"true" ]]; then # Leave a mark for syncd scripts running inside docker. @@ -127,7 +123,7 @@ start() { fi # start service docker - /usr/bin/${SERVICE}.sh start + /usr/bin/${SERVICE}.sh start $DEV debug "Started ${SERVICE} service..." unlock_service_state_change @@ -139,15 +135,15 @@ wait() { /bin/systemctl start pmon debug "Started pmon service" fi - /usr/bin/${SERVICE}.sh wait + /usr/bin/${SERVICE}.sh wait $DEV } stop() { - debug "Stopping ${SERVICE} service..." + debug "Stopping ${SERVICE}$DEV service..." lock_service_state_change check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." if [[ x"$WARM_BOOT" == x"true" ]]; then TYPE=warm @@ -163,19 +159,19 @@ stop() { if [[ x$sonic_asic_platform != x"mellanox" ]] || [[ x$TYPE != x"cold" ]]; then debug "${TYPE} shutdown syncd process ..." - /usr/bin/docker exec -i syncd /usr/bin/syncd_request_shutdown --${TYPE} + /usr/bin/docker exec -i syncd$DEV /usr/bin/syncd_request_shutdown --${TYPE} # wait until syncd quits gracefully - while docker top syncd | grep -q /usr/bin/syncd; do + while docker top syncd$DEV | grep -q /usr/bin/syncd; do sleep 0.1 done - /usr/bin/docker exec -i syncd /bin/sync + /usr/bin/docker exec -i syncd$DEV /bin/sync debug "Finished ${TYPE} shutdown syncd process ..." fi - /usr/bin/${SERVICE}.sh stop - debug "Stopped ${SERVICE} service..." + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." # platform specific tasks @@ -192,6 +188,19 @@ stop() { unlock_service_state_change } +OP=$1 +DEV=$2 + +SERVICE="syncd" +PEER="swss" +DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" +LOCKFILE="/tmp/swss-syncd-lock$DEV" +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi + case "$1" in start|wait|stop) $1 diff --git a/platform/vs/sonic_multiasic.xml b/platform/vs/sonic_multiasic.xml index b406bfd40475..b571b5122a52 100644 --- a/platform/vs/sonic_multiasic.xml +++ b/platform/vs/sonic_multiasic.xml @@ -1,7 +1,7 @@ sonic 8 - 2 + 8 /machine diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 517aff3ea9fc..45a755a9289f 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -24,7 +24,6 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_FPM_FRR_DBG) $(DOCKER_FPM_FRR)_CONTAINER_NAME = bgp $(DOCKER_FPM_FRR)_RUN_OPT += --privileged -t $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro -$(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw $(DOCKER_FPM_FRR)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/slave.mk b/slave.mk index 053382450f02..b1ecc09541ed 100644 --- a/slave.mk +++ b/slave.mk @@ -778,6 +778,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" + export multi_instance="false" $(foreach docker, $($*_DOCKERS),\ export docker_image="$(docker)" @@ -788,18 +789,21 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ if [ -f files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then j2 files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service - fi - - if [ -f files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 ]; then - j2 files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service - # performs the same check as the elif above, except with make commands so eval behaves properly - $(if $(shell ls files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 2>/dev/null),\ - $(eval $(docker:-dbg.gz=.gz)_TEMPLATE = yes) - ) + # Set the flag GLOBAL for all the global system-wide dockers. + $(if $(shell ls files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_GLOBAL = yes) + ) fi - if [ -f files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then - j2 files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service + # Any service template, inside instance directory, will be used to generate .service and @.service file. + if [ -f files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then + export multi_instance="true" + j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service + $(if $(shell ls files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_TEMPLATE = yes) + ) + export multi_instance="false" + j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service fi j2 files/build_templates/docker_image_ctl.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh chmod +x $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh @@ -810,8 +814,12 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ # Marks template services with an "@" according to systemd convention # If the $($docker)_TEMPLATE) variable is set, the service will be treated as a template + # If the $($docker)_GLOBAL) and $($docker)_TEMPLATE) variables are set the service will be added both as a global and template service. $(foreach docker, $($*_DOCKERS),\ $(if $($(docker:-dbg.gz=.gz)_TEMPLATE),\ + $(if $($(docker:-dbg.gz=.gz)_GLOBAL),\ + $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))")\ + )\ $(eval SERVICES += "$(addsuffix @.service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))"),\ $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))") ) From 7e7777e374a368b36feca0b851885239cdbd447b Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Tue, 31 Mar 2020 21:25:52 +0300 Subject: [PATCH 0480/1427] [devices][Mellanox] create sai.xml for MSN3800-D112-C8 (#4334) sai_xml contains info about port splits, previously it simply linked to the MSN3800 sai xml, which does not have splits. New version describes splits and speeds according to Mellanox-SN3800-D112-C8 SKU. Practically it can cause port recreation on SAI init. Signed-off-by: Mykola Faryma --- .../Mellanox-SN3800-D112C8/sai.profile | 2 +- .../Mellanox-SN3800-D112C8/sai_3800.xml | 1 - .../sai_3800_112x50g_8x100g.xml | 507 ++++++++++++++++++ 3 files changed, 508 insertions(+), 2 deletions(-) delete mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile index 367f6c4e99c0..c5bb0c90f3d7 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3800.xml +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3800_112x50g_8x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml deleted file mode 120000 index 686d6298865c..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml +++ /dev/null @@ -1 +0,0 @@ -../ACS-MSN3800/sai_3800.xml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml new file mode 100644 index 000000000000..102842d72275 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml @@ -0,0 +1,507 @@ + + + + + + 00:02:03:04:05:00 + + + 64 + + + + + 1 + 4 + 48 + + + 3 + 2 + + + 384 + + + 3 + 4 + 49 + 3 + 2 + 384 + + + 5 + 4 + 50 + 3 + 2 + 384 + + + 7 + 4 + 51 + 3 + 384 + + + 9 + 4 + 52 + 3 + 2 + 384 + + + 11 + 4 + 53 + 3 + 2 + 384 + + + 13 + 4 + 54 + 3 + 2 + 384 + + + 15 + 4 + 55 + 3 + 384 + + + 17 + 4 + 56 + 3 + 2 + 384 + + + 19 + 4 + 57 + 3 + 2 + 384 + + + 21 + 4 + 58 + 3 + 2 + 384 + + + 23 + 4 + 59 + 3 + 384 + + + 25 + 4 + 60 + 3 + 2 + 384 + + + 27 + 4 + 61 + 3 + 2 + 384 + + + 29 + 4 + 62 + 3 + 2 + 384 + + + 31 + 4 + 63 + 3 + 384 + + + 33 + 4 + 12 + 3 + 2 + 384 + + + 35 + 4 + 13 + 3 + 2 + 384 + + + 37 + 4 + 14 + 3 + 2 + 384 + + + 39 + 4 + 15 + 3 + 384 + + + 41 + 4 + 8 + 3 + 2 + 384 + + + 43 + 4 + 9 + 3 + 2 + 384 + + + 45 + 4 + 10 + 3 + 2 + 384 + + + 47 + 4 + 11 + 3 + 384 + + + 49 + 4 + 4 + 3 + 2 + 384 + + + 51 + 4 + 5 + 3 + 2 + 384 + + + 53 + 4 + 6 + 3 + 2 + 384 + + + 55 + 4 + 7 + 3 + 384 + + + 57 + 4 + 0 + 3 + 2 + 384 + + + 59 + 4 + 1 + 3 + 2 + 384 + + + 61 + 4 + 2 + 3 + 2 + 384 + + + 63 + 4 + 3 + 3 + 384 + + + 65 + 4 + 44 + 3 + 2 + 384 + + + 67 + 4 + 45 + 3 + 2 + 384 + + + 69 + 4 + 46 + 3 + 2 + 384 + + + 71 + 4 + 47 + 3 + 384 + + + 73 + 4 + 40 + 3 + 2 + 384 + + + 75 + 4 + 41 + 3 + 2 + 384 + + + 77 + 4 + 42 + 3 + 2 + 384 + + + 79 + 4 + 43 + 3 + 384 + + + 81 + 4 + 36 + 3 + 1536 + + + 83 + 4 + 37 + 3 + 1536 + + + 85 + 4 + 38 + 3 + 2 + 384 + + + 87 + 4 + 39 + 3 + 384 + + + 89 + 4 + 32 + 3 + 1536 + + + 91 + 4 + 33 + 3 + 1536 + + + 93 + 4 + 34 + 3 + 2 + 384 + + + 95 + 4 + 35 + 3 + 384 + + + 97 + 4 + 16 + 3 + 2 + 384 + + + 99 + 4 + 17 + 3 + 2 + 384 + + + 101 + 4 + 18 + 3 + 2 + 384 + + + 103 + 4 + 19 + 3 + 384 + + + 105 + 4 + 20 + 3 + 2 + 384 + + + 107 + 4 + 21 + 3 + 2 + 384 + + + 109 + 4 + 22 + 3 + 2 + 384 + + + 111 + 4 + 23 + 3 + 384 + + + 113 + 4 + 24 + 3 + 1536 + + + 115 + 4 + 25 + 3 + 1536 + + + 117 + 4 + 26 + 3 + 2 + 384 + + + 119 + 4 + 27 + 3 + 384 + + + 121 + 4 + 28 + 3 + 1536 + + + 123 + 4 + 29 + 3 + 1536 + + + 125 + 4 + 30 + 3 + 2 + 384 + + + 127 + 4 + 31 + 3 + 384 + + + + From dca8a2771923f1d26031fef55147c1c4c1cf39a9 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 31 Mar 2020 15:00:48 -0700 Subject: [PATCH 0481/1427] [docker-syncd-vs]: add support for vs syncd docker auto restart (#4344) Signed-off-by: Guohan Lu --- platform/vs/docker-syncd-vs/Dockerfile.j2 | 2 ++ platform/vs/docker-syncd-vs/critical_processes | 1 + platform/vs/docker-syncd-vs/supervisord.conf | 8 +++++++- 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 platform/vs/docker-syncd-vs/critical_processes diff --git a/platform/vs/docker-syncd-vs/Dockerfile.j2 b/platform/vs/docker-syncd-vs/Dockerfile.j2 index 070d8b984f4b..25d82499edf1 100644 --- a/platform/vs/docker-syncd-vs/Dockerfile.j2 +++ b/platform/vs/docker-syncd-vs/Dockerfile.j2 @@ -24,6 +24,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/vs/docker-syncd-vs/critical_processes b/platform/vs/docker-syncd-vs/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/vs/docker-syncd-vs/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/vs/docker-syncd-vs/supervisord.conf b/platform/vs/docker-syncd-vs/supervisord.conf index 1af5d70a1d0c..0c6285d46ae0 100644 --- a/platform/vs/docker-syncd-vs/supervisord.conf +++ b/platform/vs/docker-syncd-vs/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog From 8585005a36ff7420d6d929ca46de918eaeee708d Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 1 Apr 2020 12:57:19 -0700 Subject: [PATCH 0482/1427] [FRR]: Update frr to latest 7.2.1-s3 (#4294) - Updated to latest frr 7.2.1 from the master. - Updated patches accordingly --- rules/frr.mk | 2 +- src/sonic-frr/frr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/frr.mk b/rules/frr.mk index 6b2e92fcbd2e..df924c8af711 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -3,7 +3,7 @@ FRR_VERSION = 7.2.1 FRR_SUBVERSION = 0 FRR_BRANCH = frr/7.2 -FRR_TAG = frr-7.2.1-s1 +FRR_TAG = frr-7.2.1-s3 export FRR_VERSION FRR_SUBVERSION FRR_BRANCH FRR_TAG diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index 90446e3c3310..2f3f691f44ea 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit 90446e3c3310001a7b84017fa4b237ea7914f45e +Subproject commit 2f3f691f44ea0194a145aed59606fdd0f33ecdb4 From ea38d061c75ed139d005ff0112ff957b0928c06f Mon Sep 17 00:00:00 2001 From: Ze Gan Date: Fri, 3 Apr 2020 09:17:08 +0800 Subject: [PATCH 0483/1427] Fixbug: EVPN issue in FRR template (#4260) * Fixbug: EVPN issue in FRR template --- dockers/docker-fpm-frr/bgpcfgd | 155 +++++++++++++++++++++++ dockers/docker-fpm-frr/bgpd.peer.conf.j2 | 3 +- 2 files changed, 156 insertions(+), 2 deletions(-) mode change 100644 => 100755 dockers/docker-fpm-frr/bgpd.peer.conf.j2 diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 4348d22bcb8f..4e638def47b7 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -272,6 +272,8 @@ class BGPPeerMgr(Manager): [ ("meta", "localhost/bgp_asn"), ("neigmeta", ""), + ("local_addresses", ""), + ("interfaces", ""), ], "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME @@ -290,8 +292,42 @@ class BGPPeerMgr(Manager): vrf, nbr = key.split('|', 1) if key not in self.peers: cmd = None + + if "local_addr" not in data: + syslog.syslog(syslog.LOG_WARNING, 'Peer {}. Error in missing required attribute "local_addr"'.format(key)) + else: + # The bgp session that belongs to a vnet cannot be advertised as the default BGP session. + # So we need to check whether this bgp session belongs to a vnet. + interface = InterfaceMgr.get_local_interface(self.directory, data["local_addr"]) + if not interface: + syslog.syslog(syslog.LOG_INFO, + 'Peer {} with local address {} wait for the corresponding interface to be set'.format( + key, + data["local_addr"] + ) + ) + return False + vnet = InterfaceMgr.get_vnet(interface) + if vnet: + # Ignore the bgp session that is in a vnet + syslog.syslog( + syslog.LOG_INFO, + 'Ignore the BGP peer {} as the interface {} is in vnet {}'.format( + key, + interface, + vnet + ) + ) + return True + neigmeta = self.directory.get_slot("neigmeta") if 'name' in data and data["name"] not in neigmeta: + syslog.syslog(syslog.LOG_INFO, + 'Peer {} with neighbor name {} wait for the corresponding neighbor metadata to be set'.format( + key, + data["name"] + ) + ) return False try: cmd = self.templates["add"].render( @@ -390,6 +426,121 @@ class BGPPeerMgr(Manager): return peers +class InterfaceMgr(Manager): + def __init__(self, daemon, directory, interface_table = swsscommon.CFG_INTF_TABLE_NAME): + super(InterfaceMgr, self).__init__( + daemon, + directory, + [], + "CONFIG_DB", + interface_table + ) + + def set_handler(self, key, data): + # Interface table can have two keys, + # one with ip prefix and one without ip prefix + if '|' in key: + data = {} + data["interface"], network = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network)) + except: + syslog.syslog( + syslog.LOG_WARNING, + 'Subnet {} format is wrong for interface {}'.format( + network, + data["interface"] + ) + ) + return False + data["prefixlen"] = str(network.prefixlen) + ip = str(network.ip) + self.directory.put("local_addresses", ip, data) + else: + self.directory.put("interfaces", key, data) + return True + + def del_handler(self, key): + if '|' in key: + interface, network = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network)) + except: + syslog.syslog( + syslog.LOG_WARNING, + 'Subnet {} format is wrong for interface {}'.format( + network, + interface + ) + ) + return False + ip = str(network.ip) + self.directory.remove("local_addresses", ip) + else: + self.directory.remove("interfaces", key) + + @staticmethod + def get_local_interface(directory, local_addr): + """ + @summary: Get interface according to the local address from the directory + @param directory: Directory object that stored metadata of interfaces + @param local_addr: Local address of the interface + @return: Return the metadata of the interface with the local address + If the interface has not been set, return None + """ + local_addresses = directory.get_slot("local_addresses") + # Check if the local address of this bgp session has been set + if local_addr not in local_addresses: + return None + local_address = local_addresses[local_addr] + interfaces = directory.get_slot("interfaces") + # Check if the information for the interface of this local address has been set + if local_address.has_key("interface") and local_address["interface"] in interfaces: + return interfaces[local_address["interface"]] + else: + return None + + @staticmethod + def get_vnet(interface): + """ + @summary: Get the VNet name of the interface + @param interface: The metadata of the interface + @return: Return the vnet name of the interface if this interface belongs to a vnet, + Otherwise return None + """ + if interface.has_key("vnet_name") and interface["vnet_name"]: + return interface["vnet_name"] + else: + return None + + +class LoopbackInterfaceMgr(InterfaceMgr): + def __init__(self, daemon, directory): + super(LoopbackInterfaceMgr, self).__init__( + daemon, + directory, + swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME + ) + + +class VlanInterfaceMgr(InterfaceMgr): + def __init__(self, daemon, directory): + super(VlanInterfaceMgr, self).__init__( + daemon, + directory, + swsscommon.CFG_VLAN_INTF_TABLE_NAME + ) + + +class PortChannelInterfaceMgr(InterfaceMgr): + def __init__(self, daemon, directory): + super(PortChannelInterfaceMgr, self).__init__( + daemon, + directory, + swsscommon.CFG_LAG_INTF_TABLE_NAME + ) + + def wait_for_bgpd(): # wait for 20 seconds stop_time = datetime.datetime.now() + datetime.timedelta(seconds=20) @@ -408,6 +559,10 @@ def main(): BGPDeviceMetaMgr, BGPNeighborMetaMgr, BGPPeerMgr, + InterfaceMgr, + LoopbackInterfaceMgr, + VlanInterfaceMgr, + PortChannelInterfaceMgr, ] wait_for_bgpd() daemon = Daemon() diff --git a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 old mode 100644 new mode 100755 index c3dc50449d35..bcc520f6b2df --- a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 +++ b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 @@ -26,8 +26,7 @@ neighbor {{ neighbor_addr }} next-hop-self {% endif %} {% if bgp_session["asn"] == DEVICE_METADATA['localhost']['bgp_asn'] - and DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" - and (not bgp_session.has_key("local_addr") or bgp_session["local_addr"] not in interfaces_in_vnets) %} + and DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} address-family l2vpn evpn neighbor {{ neighbor_addr }} activate advertise-all-vni From 4ed3fe4a31f1cc37a85d6a813eed8b28191d2fc8 Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Fri, 3 Apr 2020 22:55:03 +0530 Subject: [PATCH 0484/1427] [HWSKU] [Marvell] Added HWSKU for Platform 98cx8580 (#4205) Suuported profiles 32x400G and 16x400G Signed-off-by: Antony Rheneus --- .../FALCON16X25G/buffers_defaults_t0.j2 | 36 +++ .../FALCON16X25G/buffers_defaults_t1.j2 | 36 +++ .../FALCON16X25G/port_config.ini | 19 ++ .../FALCON16X25G/profile.ini | 2 + .../FALCON16X25G/sai.profile | 3 + .../FALCON16x400G/buffers_defaults_t0.j2 | 36 +++ .../FALCON16x400G/buffers_defaults_t1.j2 | 36 +++ .../FALCON16x400G/port_config.ini | 19 ++ .../FALCON16x400G/profile.ini | 2 + .../FALCON16x400G/sai.profile | 3 + .../FALCON32X25G/buffers_defaults_t0.j2 | 36 +++ .../FALCON32X25G/buffers_defaults_t1.j2 | 36 +++ .../FALCON32X25G/port_config.ini | 35 +++ .../FALCON32X25G/profile.ini | 2 + .../FALCON32X25G/sai.profile | 3 + .../db98cx8580_16cd/buffers.json.j2 | 1 + .../db98cx8580_16cd/buffers_config.j2 | 165 +++++++++++ .../db98cx8580_16cd/buffers_defaults_t0.j2 | 36 +++ .../db98cx8580_16cd/buffers_defaults_t1.j2 | 36 +++ .../db98cx8580_16cd/port_config.ini | 19 ++ .../db98cx8580_16cd/profile.ini | 2 + .../db98cx8580_16cd/qos.json.j2 | 1 + .../db98cx8580_16cd/sai.profile | 3 + .../default_sku | 1 + .../plugins/eeprom.py | 13 + .../plugins/sfputil.py | 255 +++++++++++++++++ .../pmon_daemon_control.json | 3 + .../FALCON32X25G/buffers_defaults_t0.j2 | 36 +++ .../FALCON32X25G/buffers_defaults_t1.j2 | 36 +++ .../FALCON32X25G/port_config.ini | 34 +++ .../FALCON32X25G/profile.ini | 2 + .../FALCON32X25G/sai.profile | 3 + .../FALCON32x400G/buffers_defaults_t0.j2 | 36 +++ .../FALCON32x400G/buffers_defaults_t1.j2 | 36 +++ .../FALCON32x400G/port_config.ini | 34 +++ .../FALCON32x400G/profile.ini | 2 + .../FALCON32x400G/sai.profile | 3 + .../db98cx8580_32cd/buffers.json.j2 | 1 + .../db98cx8580_32cd/buffers_config.j2 | 165 +++++++++++ .../db98cx8580_32cd/buffers_defaults_t0.j2 | 36 +++ .../db98cx8580_32cd/buffers_defaults_t1.j2 | 36 +++ .../db98cx8580_32cd/port_config.ini | 34 +++ .../db98cx8580_32cd/profile.ini | 2 + .../db98cx8580_32cd/qos.json.j2 | 1 + .../db98cx8580_32cd/sai.profile | 3 + .../default_sku | 1 + .../plugins/eeprom.py | 13 + .../plugins/sfputil.py | 261 ++++++++++++++++++ .../pmon_daemon_control.json | 3 + .../FALCON16X25G/buffers_defaults_t0.j2 | 36 +++ .../FALCON16X25G/buffers_defaults_t1.j2 | 36 +++ .../FALCON16X25G/port_config.ini | 19 ++ .../FALCON16X25G/profile.ini | 2 + .../FALCON16X25G/sai.profile | 3 + .../FALCON16x400G/buffers_defaults_t0.j2 | 36 +++ .../FALCON16x400G/buffers_defaults_t1.j2 | 36 +++ .../FALCON16x400G/port_config.ini | 19 ++ .../FALCON16x400G/profile.ini | 2 + .../FALCON16x400G/sai.profile | 3 + .../FALCON32X25G/buffers_defaults_t0.j2 | 36 +++ .../FALCON32X25G/buffers_defaults_t1.j2 | 36 +++ .../FALCON32X25G/port_config.ini | 35 +++ .../FALCON32X25G/profile.ini | 2 + .../FALCON32X25G/sai.profile | 3 + .../db98cx8580_16cd/buffers.json.j2 | 1 + .../db98cx8580_16cd/buffers_config.j2 | 165 +++++++++++ .../db98cx8580_16cd/buffers_defaults_t0.j2 | 36 +++ .../db98cx8580_16cd/buffers_defaults_t1.j2 | 36 +++ .../db98cx8580_16cd/port_config.ini | 19 ++ .../db98cx8580_16cd/profile.ini | 2 + .../db98cx8580_16cd/qos.json.j2 | 1 + .../db98cx8580_16cd/sai.profile | 3 + .../default_sku | 1 + .../plugins/eeprom.py | 13 + .../plugins/sfputil.py | 255 +++++++++++++++++ .../pmon_daemon_control.json | 3 + .../FALCON32X25G/buffers_defaults_t0.j2 | 36 +++ .../FALCON32X25G/buffers_defaults_t1.j2 | 36 +++ .../FALCON32X25G/port_config.ini | 34 +++ .../FALCON32X25G/profile.ini | 2 + .../FALCON32X25G/sai.profile | 3 + .../FALCON32x400G/buffers_defaults_t0.j2 | 36 +++ .../FALCON32x400G/buffers_defaults_t1.j2 | 36 +++ .../FALCON32x400G/port_config.ini | 34 +++ .../FALCON32x400G/profile.ini | 2 + .../FALCON32x400G/sai.profile | 3 + .../db98cx8580_32cd/buffers.json.j2 | 1 + .../db98cx8580_32cd/buffers_config.j2 | 165 +++++++++++ .../db98cx8580_32cd/buffers_defaults_t0.j2 | 36 +++ .../db98cx8580_32cd/buffers_defaults_t1.j2 | 36 +++ .../db98cx8580_32cd/port_config.ini | 34 +++ .../db98cx8580_32cd/profile.ini | 2 + .../db98cx8580_32cd/qos.json.j2 | 1 + .../db98cx8580_32cd/sai.profile | 3 + .../default_sku | 1 + .../plugins/eeprom.py | 13 + .../plugins/sfputil.py | 261 ++++++++++++++++++ .../pmon_daemon_control.json | 3 + 98 files changed, 3234 insertions(+) create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/default_sku create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py create mode 100644 device/marvell/arm64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/default_sku create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py create mode 100644 device/marvell/arm64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/default_sku create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py create mode 100644 device/marvell/x86_64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/default_sku create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py create mode 100644 device/marvell/x86_64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini new file mode 100644 index 000000000000..074c0344c896 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 10000 tenGigE16 +Ethernet17 17 10000 tenGigE17 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini new file mode 100644 index 000000000000..aeaafc4e6e4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile new file mode 100644 index 000000000000..2c9623c91105 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16X25G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini new file mode 100644 index 000000000000..6a9bfda3fb8b --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE1 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE2 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE2 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE3 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE4 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE5 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE6 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE7 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE8 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE9 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE10 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE11 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE12 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE13 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE14 +Ethernet128 128 10000 tenGigE128 +Ethernet129 129 10000 tenGigE129 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini new file mode 100644 index 000000000000..16847ec03ae2 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile new file mode 100644 index 000000000000..6a2438f50180 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..f9fb5482560d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"170000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..f9fb5482560d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"170000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini new file mode 100644 index 000000000000..d0402fd44317 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini @@ -0,0 +1,35 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 25000 twenty5GigE16 +Ethernet17 17 25000 twenty5GigE17 +Ethernet18 18 25000 twenty5GigE18 +Ethernet19 19 25000 twenty5GigE19 +Ethernet20 20 25000 twenty5GigE20 +Ethernet21 21 25000 twenty5GigE21 +Ethernet22 22 25000 twenty5GigE22 +Ethernet23 23 25000 twenty5GigE23 +Ethernet24 24 25000 twenty5GigE24 +Ethernet25 25 25000 twenty5GigE25 +Ethernet26 26 25000 twenty5GigE26 +Ethernet27 27 25000 twenty5GigE27 +Ethernet28 28 25000 twenty5GigE28 +Ethernet29 29 25000 twenty5GigE29 +Ethernet30 30 25000 twenty5GigE30 +Ethernet31 31 25000 twenty5GigE31 +Ethernet32 32 10000 tenGigE32 +Ethernet33 33 10000 tenGigE33 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini new file mode 100644 index 000000000000..0ffbefa05805 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 016:1 017:1 018:1 019:1 020:1 021:1 022:1 023:1 024:1 025:1 026:1 027:1 028:1 029:1 030:1 031:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile new file mode 100644 index 000000000000..fa9983612117 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x25G64 +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 new file mode 100644 index 000000000000..a5212d979fcb --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 @@ -0,0 +1,165 @@ +{%- macro set_default_topology() %} +{%- if default_topo is defined %} +{{ default_topo }} +{%- else %} +def +{%- endif %} +{%- endmacro -%} + +{# Determine device topology and filename postfix #} +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- if switch_role.lower() == 'torrouter' %} +{%- set filename_postfix = 't0' %} +{%- elif switch_role.lower() == 'leafrouter' %} +{%- set filename_postfix = 't1' %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- endif %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- set switch_role = '' %} +{%- endif -%} + +{# Import default values from device HWSKU folder #} +{%- import 'buffers_defaults_%s.j2' % filename_postfix as defs %} + +{%- set default_cable = defs.default_cable -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{%- if defs.ports2cable is defined %} + {%- set ports2cable = defs.ports2cable %} +{%- else %} + {%- set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } + -%} +{%- endif %} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- set PORT_ALL = [] %} + +{%- if PORT is not defined %} + {%- if defs.generate_port_lists(PORT_ALL) %} {% endif %} +{%- else %} + {%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') %} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT_ALL %} + {%- set cable = cable_length(port) %} + "{{ port }}": "{{ cable }}"{%- if not loop.last %},{% endif %} + + {% endfor %} + } + }, + +{% if defs.generate_buffer_pool_and_profiles is defined %} +{{ defs.generate_buffer_pool_and_profiles() }} +{% endif %} + +{%- if defs.generate_profile_lists is defined %} +{{ defs.generate_profile_lists(port_names_active) }}, +{% endif %} + +{%- if defs.generate_pg_profils is defined %} +{{ defs.generate_pg_profils(port_names_active) }} +{% else %} + "BUFFER_PG": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, +{% endif %} + +{% if defs.generate_queue_buffers is defined %} +{{ defs.generate_queue_buffers(port_names_active) }} +{% else %} + "BUFFER_QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{% endif %} +} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini new file mode 100644 index 000000000000..6a9bfda3fb8b --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE1 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE2 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE2 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE3 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE4 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE5 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE6 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE7 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE8 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE9 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE10 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE11 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE12 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE13 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE14 +Ethernet128 128 10000 tenGigE128 +Ethernet129 129 10000 tenGigE129 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini new file mode 100644 index 000000000000..16847ec03ae2 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile new file mode 100644 index 000000000000..6a2438f50180 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/default_sku b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/default_sku new file mode 100644 index 000000000000..7908e555c02c --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/default_sku @@ -0,0 +1 @@ +db98cx8580_16cd t1 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py new file mode 100644 index 000000000000..ea525f5d74b1 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/etc/sonic/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py new file mode 100644 index 000000000000..da13b129a9a3 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py @@ -0,0 +1,255 @@ +#!/usr/bin/env python + +try: + import os + import time + import sys + import re + import subprocess + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +smbus_present = 1 + +try: + import smbus +except ImportError, e: + smbus_present = 0 + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + _port_start = 1 + _port_end = 132 + ports_in_block = 132 + + _port_to_eeprom_mapping = {} + + _qsfp_ports = range(_port_start, ports_in_block + 1) + + def __init__(self): + os.system("modprobe i2c-dev") + if not os.path.exists("/sys/bus/i2c/devices/0-0050") : + os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + + eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' + #for x in range(self.port _start, self.port_end +1): + x = self.port_start + while(x self._port_end: + return False + + port_ps = "/sys/bus/i2c/devices/0-0050/sfp_port_reset" + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_nuM, lpmode): + raise NotImplementedError + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def i2c_get(self, device_addr, offset): + status = 0 + if smbus_present == 0: + x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) + cmdstatus, status = cmd.getstatusoutput(x) + if cmdstatus != 0: + return cmdstatus + status = int(status, 16) + else: + bus = smbus.SMBus(0) + status = bus.read_byte_data(device_addr, offset) + return status + + def i2c_set(self, device_addr, offset, value): + if smbus_present == 0: + cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) + os.system(cmd) + else: + bus = smbus.SMBus(0) + bus.write_byte_data(device_addr, offset, value) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + else: + self.i2c_set(0x70, 0, 0) + self.i2c_set(0x71, 0, 0) + self.i2c_set(0x74, 0, 0) + reg = (port_num)/8 + offset = reg % 8 + if offset >=4: + offset=offset-4 + elif offset<4: + offset=offset+4 + bin_offset = 1<= 0 and port_num <= 63: + device_reg = 0x70 + elif port_num >= 64 and port_num <= 127: + device_reg = 0x71 + elif port_num >= 128 and port_num <= 131: + device_reg = 0x74 + + #print "i2c %d %x %x" % (port_num, device_reg, bin_offset) + self.i2c_set(device_reg, 0, bin_offset) + path = "/sys/bus/i2c/devices/0-0050/eeprom" + try: + reg_file = open(path) + reg_file.seek(01) + reg_file.read(02) + except IOError as e: + return False + + return True + + def read_porttab_mappings(self, porttabfile): + #print("I am in porttab_mappings") + logical = [] + logical_to_bcm = {} + logical_to_physical = {} + physical_to_logical = {} + last_fp_port_index = 0 + last_portname = "" + first = 1 + port_pos_in_file = 0 + parse_fmt_port_config_ini = False + + try: + f = open(porttabfile) + except: + raise + + parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini") + # Read the porttab file and generate dicts + # with mapping for future reference. + # + # TODO: Refactor this to use the portconfig.py module that now + # exists as part of the sonic-config-engine package. + title = [] + for line in f: + line.strip() + if re.search("^#", line) is not None: + # The current format is: # name lanes alias index speed + # Where the ordering of the columns can vary + title = line.split()[1:] + continue + #print title + + # Parsing logic for 'port_config.ini' file + if (parse_fmt_port_config_ini): + # bcm_port is not explicitly listed in port_config.ini format + # Currently we assume ports are listed in numerical order according to bcm_port + # so we use the port's position in the file (zero-based) as bcm_port + portname = line.split()[0] + + bcm_port = str(port_pos_in_file) + + + if "index" in title: + fp_port_index = int(line.split()[title.index("index")]) + # Leave the old code for backward compatibility + #if len(line.split()) >= 4: + # fp_port_index = (line.split()[3]) + # print(fp_port_index) + else: + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + else: # Parsing logic for older 'portmap.ini' file + (portname, bcm_port) = line.split("=")[1].split(",")[:2] + + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + + if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): + continue + + if first == 1: + # Initialize last_[physical|logical]_port + # to the first valid port + last_fp_port_index = fp_port_index + last_portname = portname + first = 0 + + logical.append(portname) + + logical_to_bcm[portname] = "xe" + bcm_port + logical_to_physical[portname] = [fp_port_index] + if physical_to_logical.get(fp_port_index) is None: + physical_to_logical[fp_port_index] = [portname] + else: + physical_to_logical[fp_port_index].append( + portname) + + if (fp_port_index - last_fp_port_index) > 1: + # last port was a gang port + for p in range(last_fp_port_index+1, fp_port_index): + logical_to_physical[last_portname].append(p) + if physical_to_logical.get(p) is None: + physical_to_logical[p] = [last_portname] + else: + physical_to_logical[p].append(last_portname) + + last_fp_port_index = fp_port_index + last_portname = portname + + port_pos_in_file += 1 + + self.logical = logical + self.logical_to_bcm = logical_to_bcm + self.logical_to_physical = logical_to_physical + self.physical_to_logical = physical_to_logical + + + #print(self.logical_to_physical) + '''print("logical: " + self.logical) + print("logical to bcm: " + self.logical_to_bcm) + print("logical to physical: " + self.logical_to_physical) + print("physical to logical: " + self.physical_to_logical)''' + #print("exiting port_tab_mappings") + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + @property + def get_transceiver_change_event(self): + raise NotImplementedError diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini new file mode 100644 index 000000000000..6d8b5d0a13df --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 25000 twenty5GigE16 +Ethernet17 17 25000 twenty5GigE17 +Ethernet18 18 25000 twenty5GigE18 +Ethernet19 19 25000 twenty5GigE19 +Ethernet20 20 25000 twenty5GigE20 +Ethernet21 21 25000 twenty5GigE21 +Ethernet22 22 25000 twenty5GigE22 +Ethernet23 23 25000 twenty5GigE23 +Ethernet24 24 25000 twenty5GigE24 +Ethernet25 25 25000 twenty5GigE25 +Ethernet26 26 25000 twenty5GigE26 +Ethernet27 27 25000 twenty5GigE27 +Ethernet28 28 25000 twenty5GigE28 +Ethernet29 29 25000 twenty5GigE29 +Ethernet30 30 25000 twenty5GigE30 +Ethernet31 31 25000 twenty5GigE31 +Ethernet32 32 10000 tenGigE32 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini new file mode 100644 index 000000000000..487e80dcbd70 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 016:1 017:1 018:1 019:1 020:1 021:1 022:1 023:1 024:1 025:1 026:1 027:1 028:1 029:1 030:1 031:1 032:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile new file mode 100644 index 000000000000..dd6f707a81ab --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32X25G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini new file mode 100644 index 000000000000..62dd91ba8869 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE8 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE16 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE24 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE32 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE40 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE48 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE56 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE64 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE72 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE80 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE88 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE96 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE104 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE112 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE120 +Ethernet128 128,129,130,131,132,133,134,135 400000 four00GigE128 +Ethernet136 136,137,138,139,140,141,142,143 400000 four00GigE136 +Ethernet144 144,145,146,147,148,149,150,151 400000 four00GigE144 +Ethernet152 152,153,154,155,156,157,158,159 400000 four00GigE152 +Ethernet160 160,161,162,163,164,165,166,167 400000 four00GigE160 +Ethernet168 168,169,170,171,172,173,174,175 400000 four00GigE168 +Ethernet176 176,177,178,179,180,181,182,183 400000 four00GigE176 +Ethernet184 184,185,186,187,188,189,190,191 400000 four00GigE184 +Ethernet192 192,193,194,195,196,197,198,199 400000 four00GigE192 +Ethernet200 200,201,202,203,204,205,206,207 400000 four00GigE200 +Ethernet208 208,209,210,211,212,213,214,215 400000 four00GigE208 +Ethernet216 216,217,218,219,220,221,222,223 400000 four00GigE216 +Ethernet224 224,225,226,227,228,229,230,231 400000 four00GigE224 +Ethernet232 232,233,234,235,236,237,238,239 400000 four00GigE232 +Ethernet240 240,241,242,243,244,245,246,247 400000 four00GigE240 +Ethernet248 248,249,250,251,252,253,254,255 400000 four00GigE248 +Ethernet256 256 10000 tenGigE256 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini new file mode 100644 index 000000000000..2813bbd363f8 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 128:1 136:1 144:1 152:1 160:1 168:1 176:1 184:1 192:1 200:1 208:1 216:1 224:1 232:1 240:1 248:1 256:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile new file mode 100644 index 000000000000..6dc6f35fed4e --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 new file mode 100644 index 000000000000..a5212d979fcb --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 @@ -0,0 +1,165 @@ +{%- macro set_default_topology() %} +{%- if default_topo is defined %} +{{ default_topo }} +{%- else %} +def +{%- endif %} +{%- endmacro -%} + +{# Determine device topology and filename postfix #} +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- if switch_role.lower() == 'torrouter' %} +{%- set filename_postfix = 't0' %} +{%- elif switch_role.lower() == 'leafrouter' %} +{%- set filename_postfix = 't1' %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- endif %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- set switch_role = '' %} +{%- endif -%} + +{# Import default values from device HWSKU folder #} +{%- import 'buffers_defaults_%s.j2' % filename_postfix as defs %} + +{%- set default_cable = defs.default_cable -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{%- if defs.ports2cable is defined %} + {%- set ports2cable = defs.ports2cable %} +{%- else %} + {%- set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } + -%} +{%- endif %} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- set PORT_ALL = [] %} + +{%- if PORT is not defined %} + {%- if defs.generate_port_lists(PORT_ALL) %} {% endif %} +{%- else %} + {%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') %} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT_ALL %} + {%- set cable = cable_length(port) %} + "{{ port }}": "{{ cable }}"{%- if not loop.last %},{% endif %} + + {% endfor %} + } + }, + +{% if defs.generate_buffer_pool_and_profiles is defined %} +{{ defs.generate_buffer_pool_and_profiles() }} +{% endif %} + +{%- if defs.generate_profile_lists is defined %} +{{ defs.generate_profile_lists(port_names_active) }}, +{% endif %} + +{%- if defs.generate_pg_profils is defined %} +{{ defs.generate_pg_profils(port_names_active) }} +{% else %} + "BUFFER_PG": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, +{% endif %} + +{% if defs.generate_queue_buffers is defined %} +{{ defs.generate_queue_buffers(port_names_active) }} +{% else %} + "BUFFER_QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{% endif %} +} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini new file mode 100644 index 000000000000..62dd91ba8869 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE8 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE16 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE24 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE32 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE40 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE48 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE56 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE64 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE72 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE80 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE88 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE96 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE104 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE112 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE120 +Ethernet128 128,129,130,131,132,133,134,135 400000 four00GigE128 +Ethernet136 136,137,138,139,140,141,142,143 400000 four00GigE136 +Ethernet144 144,145,146,147,148,149,150,151 400000 four00GigE144 +Ethernet152 152,153,154,155,156,157,158,159 400000 four00GigE152 +Ethernet160 160,161,162,163,164,165,166,167 400000 four00GigE160 +Ethernet168 168,169,170,171,172,173,174,175 400000 four00GigE168 +Ethernet176 176,177,178,179,180,181,182,183 400000 four00GigE176 +Ethernet184 184,185,186,187,188,189,190,191 400000 four00GigE184 +Ethernet192 192,193,194,195,196,197,198,199 400000 four00GigE192 +Ethernet200 200,201,202,203,204,205,206,207 400000 four00GigE200 +Ethernet208 208,209,210,211,212,213,214,215 400000 four00GigE208 +Ethernet216 216,217,218,219,220,221,222,223 400000 four00GigE216 +Ethernet224 224,225,226,227,228,229,230,231 400000 four00GigE224 +Ethernet232 232,233,234,235,236,237,238,239 400000 four00GigE232 +Ethernet240 240,241,242,243,244,245,246,247 400000 four00GigE240 +Ethernet248 248,249,250,251,252,253,254,255 400000 four00GigE248 +Ethernet256 256 10000 tenGigE256 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini new file mode 100644 index 000000000000..2813bbd363f8 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 128:1 136:1 144:1 152:1 160:1 168:1 176:1 184:1 192:1 200:1 208:1 216:1 224:1 232:1 240:1 248:1 256:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile new file mode 100644 index 000000000000..6dc6f35fed4e --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/default_sku b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/default_sku new file mode 100644 index 000000000000..563676854022 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/default_sku @@ -0,0 +1 @@ +db98cx8580_32cd t1 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py new file mode 100644 index 000000000000..ea525f5d74b1 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/etc/sonic/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py new file mode 100644 index 000000000000..80b11bf0630e --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py @@ -0,0 +1,261 @@ +#!/usr/bin/env python + +try: + import os + import time + import sys + import re + import subprocess + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +smbus_present = 1 + +try: + import smbus +except ImportError, e: + smbus_present = 0 + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + _port_start = 1 + _port_end = 257 + ports_in_block = 257 + + _port_to_eeprom_mapping = {} + + _qsfp_ports = range(_port_start, ports_in_block + 1) + + def __init__(self): + os.system("modprobe i2c-dev") + if not os.path.exists("/sys/bus/i2c/devices/0-0050") : + os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + + eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' + #for x in range(self.port _start, self.port_end +1): + x = self.port_start + while(x self._port_end: + return False + + port_ps = "/sys/bus/i2c/devices/0-0050/sfp_port_reset" + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_nuM, lpmode): + raise NotImplementedError + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def i2c_get(self, device_addr, offset): + status = 0 + if smbus_present == 0: + x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) + cmdstatus, status = cmd.getstatusoutput(x) + if cmdstatus != 0: + return cmdstatus + status = int(status, 16) + else: + bus = smbus.SMBus(0) + status = bus.read_byte_data(device_addr, offset) + return status + + def i2c_set(self, device_addr, offset, value): + if smbus_present == 0: + cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) + os.system(cmd) + else: + bus = smbus.SMBus(0) + bus.write_byte_data(device_addr, offset, value) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + else: + self.i2c_set(0x70, 0, 0) + self.i2c_set(0x71, 0, 0) + self.i2c_set(0x72, 0, 0) + self.i2c_set(0x73, 0, 0) + self.i2c_set(0x74, 0, 0) + reg = (port_num)/8 + offset = reg % 8 + if offset >=4: + offset=offset-4 + elif offset<4: + offset=offset+4 + bin_offset = 1<= 0 and port_num <= 63: + device_reg = 0x70 + elif port_num >= 64 and port_num <= 127: + device_reg = 0x71 + elif port_num >= 128 and port_num <= 191: + device_reg = 0x72 + elif port_num >= 192 and port_num <= 255: + device_reg = 0x73 + elif port_num >= 256 and port_num <= 257: + device_reg = 0x74 + + #print "i2c %d %x %x" % (port_num, device_reg, bin_offset) + self.i2c_set(device_reg, 0, bin_offset) + path = "/sys/bus/i2c/devices/0-0050/eeprom" + try: + reg_file = open(path) + reg_file.seek(01) + reg_file.read(02) + except IOError as e: + return False + + return True + + def read_porttab_mappings(self, porttabfile): + #print("I am in porttab_mappings") + logical = [] + logical_to_bcm = {} + logical_to_physical = {} + physical_to_logical = {} + last_fp_port_index = 0 + last_portname = "" + first = 1 + port_pos_in_file = 0 + parse_fmt_port_config_ini = False + + try: + f = open(porttabfile) + except: + raise + + parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini") + # Read the porttab file and generate dicts + # with mapping for future reference. + # + # TODO: Refactor this to use the portconfig.py module that now + # exists as part of the sonic-config-engine package. + title = [] + for line in f: + line.strip() + if re.search("^#", line) is not None: + # The current format is: # name lanes alias index speed + # Where the ordering of the columns can vary + title = line.split()[1:] + continue + #print title + + # Parsing logic for 'port_config.ini' file + if (parse_fmt_port_config_ini): + # bcm_port is not explicitly listed in port_config.ini format + # Currently we assume ports are listed in numerical order according to bcm_port + # so we use the port's position in the file (zero-based) as bcm_port + portname = line.split()[0] + + bcm_port = str(port_pos_in_file) + + + if "index" in title: + fp_port_index = int(line.split()[title.index("index")]) + # Leave the old code for backward compatibility + #if len(line.split()) >= 4: + # fp_port_index = (line.split()[3]) + # print(fp_port_index) + else: + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + else: # Parsing logic for older 'portmap.ini' file + (portname, bcm_port) = line.split("=")[1].split(",")[:2] + + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + + if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): + continue + + if first == 1: + # Initialize last_[physical|logical]_port + # to the first valid port + last_fp_port_index = fp_port_index + last_portname = portname + first = 0 + + logical.append(portname) + + logical_to_bcm[portname] = "xe" + bcm_port + logical_to_physical[portname] = [fp_port_index] + if physical_to_logical.get(fp_port_index) is None: + physical_to_logical[fp_port_index] = [portname] + else: + physical_to_logical[fp_port_index].append( + portname) + + if (fp_port_index - last_fp_port_index) > 1: + # last port was a gang port + for p in range(last_fp_port_index+1, fp_port_index): + logical_to_physical[last_portname].append(p) + if physical_to_logical.get(p) is None: + physical_to_logical[p] = [last_portname] + else: + physical_to_logical[p].append(last_portname) + + last_fp_port_index = fp_port_index + last_portname = portname + + port_pos_in_file += 1 + + self.logical = logical + self.logical_to_bcm = logical_to_bcm + self.logical_to_physical = logical_to_physical + self.physical_to_logical = physical_to_logical + + + #print(self.logical_to_physical) + '''print("logical: " + self.logical) + print("logical to bcm: " + self.logical_to_bcm) + print("logical to physical: " + self.logical_to_physical) + print("physical to logical: " + self.physical_to_logical)''' + #print("exiting port_tab_mappings") + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + @property + def get_transceiver_change_event(self): + raise NotImplementedError diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini new file mode 100644 index 000000000000..074c0344c896 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 10000 tenGigE16 +Ethernet17 17 10000 tenGigE17 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini new file mode 100644 index 000000000000..aeaafc4e6e4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile new file mode 100644 index 000000000000..2c9623c91105 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16X25G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini new file mode 100644 index 000000000000..6a9bfda3fb8b --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE1 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE2 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE2 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE3 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE4 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE5 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE6 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE7 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE8 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE9 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE10 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE11 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE12 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE13 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE14 +Ethernet128 128 10000 tenGigE128 +Ethernet129 129 10000 tenGigE129 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini new file mode 100644 index 000000000000..16847ec03ae2 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile new file mode 100644 index 000000000000..6a2438f50180 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..f9fb5482560d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"170000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..f9fb5482560d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"170000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini new file mode 100644 index 000000000000..d0402fd44317 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini @@ -0,0 +1,35 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 25000 twenty5GigE16 +Ethernet17 17 25000 twenty5GigE17 +Ethernet18 18 25000 twenty5GigE18 +Ethernet19 19 25000 twenty5GigE19 +Ethernet20 20 25000 twenty5GigE20 +Ethernet21 21 25000 twenty5GigE21 +Ethernet22 22 25000 twenty5GigE22 +Ethernet23 23 25000 twenty5GigE23 +Ethernet24 24 25000 twenty5GigE24 +Ethernet25 25 25000 twenty5GigE25 +Ethernet26 26 25000 twenty5GigE26 +Ethernet27 27 25000 twenty5GigE27 +Ethernet28 28 25000 twenty5GigE28 +Ethernet29 29 25000 twenty5GigE29 +Ethernet30 30 25000 twenty5GigE30 +Ethernet31 31 25000 twenty5GigE31 +Ethernet32 32 10000 tenGigE32 +Ethernet33 33 10000 tenGigE33 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini new file mode 100644 index 000000000000..0ffbefa05805 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 016:1 017:1 018:1 019:1 020:1 021:1 022:1 023:1 024:1 025:1 026:1 027:1 028:1 029:1 030:1 031:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile new file mode 100644 index 000000000000..fa9983612117 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x25G64 +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 new file mode 100644 index 000000000000..a5212d979fcb --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 @@ -0,0 +1,165 @@ +{%- macro set_default_topology() %} +{%- if default_topo is defined %} +{{ default_topo }} +{%- else %} +def +{%- endif %} +{%- endmacro -%} + +{# Determine device topology and filename postfix #} +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- if switch_role.lower() == 'torrouter' %} +{%- set filename_postfix = 't0' %} +{%- elif switch_role.lower() == 'leafrouter' %} +{%- set filename_postfix = 't1' %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- endif %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- set switch_role = '' %} +{%- endif -%} + +{# Import default values from device HWSKU folder #} +{%- import 'buffers_defaults_%s.j2' % filename_postfix as defs %} + +{%- set default_cable = defs.default_cable -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{%- if defs.ports2cable is defined %} + {%- set ports2cable = defs.ports2cable %} +{%- else %} + {%- set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } + -%} +{%- endif %} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- set PORT_ALL = [] %} + +{%- if PORT is not defined %} + {%- if defs.generate_port_lists(PORT_ALL) %} {% endif %} +{%- else %} + {%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') %} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT_ALL %} + {%- set cable = cable_length(port) %} + "{{ port }}": "{{ cable }}"{%- if not loop.last %},{% endif %} + + {% endfor %} + } + }, + +{% if defs.generate_buffer_pool_and_profiles is defined %} +{{ defs.generate_buffer_pool_and_profiles() }} +{% endif %} + +{%- if defs.generate_profile_lists is defined %} +{{ defs.generate_profile_lists(port_names_active) }}, +{% endif %} + +{%- if defs.generate_pg_profils is defined %} +{{ defs.generate_pg_profils(port_names_active) }} +{% else %} + "BUFFER_PG": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, +{% endif %} + +{% if defs.generate_queue_buffers is defined %} +{{ defs.generate_queue_buffers(port_names_active) }} +{% else %} + "BUFFER_QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{% endif %} +} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini new file mode 100644 index 000000000000..6a9bfda3fb8b --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE1 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE2 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE2 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE3 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE4 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE5 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE6 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE7 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE8 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE9 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE10 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE11 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE12 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE13 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE14 +Ethernet128 128 10000 tenGigE128 +Ethernet129 129 10000 tenGigE129 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini new file mode 100644 index 000000000000..16847ec03ae2 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile new file mode 100644 index 000000000000..6a2438f50180 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/default_sku b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/default_sku new file mode 100644 index 000000000000..7908e555c02c --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/default_sku @@ -0,0 +1 @@ +db98cx8580_16cd t1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py new file mode 100644 index 000000000000..ea525f5d74b1 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/etc/sonic/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py new file mode 100644 index 000000000000..da13b129a9a3 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py @@ -0,0 +1,255 @@ +#!/usr/bin/env python + +try: + import os + import time + import sys + import re + import subprocess + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +smbus_present = 1 + +try: + import smbus +except ImportError, e: + smbus_present = 0 + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + _port_start = 1 + _port_end = 132 + ports_in_block = 132 + + _port_to_eeprom_mapping = {} + + _qsfp_ports = range(_port_start, ports_in_block + 1) + + def __init__(self): + os.system("modprobe i2c-dev") + if not os.path.exists("/sys/bus/i2c/devices/0-0050") : + os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + + eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' + #for x in range(self.port _start, self.port_end +1): + x = self.port_start + while(x self._port_end: + return False + + port_ps = "/sys/bus/i2c/devices/0-0050/sfp_port_reset" + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_nuM, lpmode): + raise NotImplementedError + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def i2c_get(self, device_addr, offset): + status = 0 + if smbus_present == 0: + x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) + cmdstatus, status = cmd.getstatusoutput(x) + if cmdstatus != 0: + return cmdstatus + status = int(status, 16) + else: + bus = smbus.SMBus(0) + status = bus.read_byte_data(device_addr, offset) + return status + + def i2c_set(self, device_addr, offset, value): + if smbus_present == 0: + cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) + os.system(cmd) + else: + bus = smbus.SMBus(0) + bus.write_byte_data(device_addr, offset, value) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + else: + self.i2c_set(0x70, 0, 0) + self.i2c_set(0x71, 0, 0) + self.i2c_set(0x74, 0, 0) + reg = (port_num)/8 + offset = reg % 8 + if offset >=4: + offset=offset-4 + elif offset<4: + offset=offset+4 + bin_offset = 1<= 0 and port_num <= 63: + device_reg = 0x70 + elif port_num >= 64 and port_num <= 127: + device_reg = 0x71 + elif port_num >= 128 and port_num <= 131: + device_reg = 0x74 + + #print "i2c %d %x %x" % (port_num, device_reg, bin_offset) + self.i2c_set(device_reg, 0, bin_offset) + path = "/sys/bus/i2c/devices/0-0050/eeprom" + try: + reg_file = open(path) + reg_file.seek(01) + reg_file.read(02) + except IOError as e: + return False + + return True + + def read_porttab_mappings(self, porttabfile): + #print("I am in porttab_mappings") + logical = [] + logical_to_bcm = {} + logical_to_physical = {} + physical_to_logical = {} + last_fp_port_index = 0 + last_portname = "" + first = 1 + port_pos_in_file = 0 + parse_fmt_port_config_ini = False + + try: + f = open(porttabfile) + except: + raise + + parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini") + # Read the porttab file and generate dicts + # with mapping for future reference. + # + # TODO: Refactor this to use the portconfig.py module that now + # exists as part of the sonic-config-engine package. + title = [] + for line in f: + line.strip() + if re.search("^#", line) is not None: + # The current format is: # name lanes alias index speed + # Where the ordering of the columns can vary + title = line.split()[1:] + continue + #print title + + # Parsing logic for 'port_config.ini' file + if (parse_fmt_port_config_ini): + # bcm_port is not explicitly listed in port_config.ini format + # Currently we assume ports are listed in numerical order according to bcm_port + # so we use the port's position in the file (zero-based) as bcm_port + portname = line.split()[0] + + bcm_port = str(port_pos_in_file) + + + if "index" in title: + fp_port_index = int(line.split()[title.index("index")]) + # Leave the old code for backward compatibility + #if len(line.split()) >= 4: + # fp_port_index = (line.split()[3]) + # print(fp_port_index) + else: + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + else: # Parsing logic for older 'portmap.ini' file + (portname, bcm_port) = line.split("=")[1].split(",")[:2] + + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + + if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): + continue + + if first == 1: + # Initialize last_[physical|logical]_port + # to the first valid port + last_fp_port_index = fp_port_index + last_portname = portname + first = 0 + + logical.append(portname) + + logical_to_bcm[portname] = "xe" + bcm_port + logical_to_physical[portname] = [fp_port_index] + if physical_to_logical.get(fp_port_index) is None: + physical_to_logical[fp_port_index] = [portname] + else: + physical_to_logical[fp_port_index].append( + portname) + + if (fp_port_index - last_fp_port_index) > 1: + # last port was a gang port + for p in range(last_fp_port_index+1, fp_port_index): + logical_to_physical[last_portname].append(p) + if physical_to_logical.get(p) is None: + physical_to_logical[p] = [last_portname] + else: + physical_to_logical[p].append(last_portname) + + last_fp_port_index = fp_port_index + last_portname = portname + + port_pos_in_file += 1 + + self.logical = logical + self.logical_to_bcm = logical_to_bcm + self.logical_to_physical = logical_to_physical + self.physical_to_logical = physical_to_logical + + + #print(self.logical_to_physical) + '''print("logical: " + self.logical) + print("logical to bcm: " + self.logical_to_bcm) + print("logical to physical: " + self.logical_to_physical) + print("physical to logical: " + self.physical_to_logical)''' + #print("exiting port_tab_mappings") + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + @property + def get_transceiver_change_event(self): + raise NotImplementedError diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini new file mode 100644 index 000000000000..6d8b5d0a13df --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 25000 twenty5GigE16 +Ethernet17 17 25000 twenty5GigE17 +Ethernet18 18 25000 twenty5GigE18 +Ethernet19 19 25000 twenty5GigE19 +Ethernet20 20 25000 twenty5GigE20 +Ethernet21 21 25000 twenty5GigE21 +Ethernet22 22 25000 twenty5GigE22 +Ethernet23 23 25000 twenty5GigE23 +Ethernet24 24 25000 twenty5GigE24 +Ethernet25 25 25000 twenty5GigE25 +Ethernet26 26 25000 twenty5GigE26 +Ethernet27 27 25000 twenty5GigE27 +Ethernet28 28 25000 twenty5GigE28 +Ethernet29 29 25000 twenty5GigE29 +Ethernet30 30 25000 twenty5GigE30 +Ethernet31 31 25000 twenty5GigE31 +Ethernet32 32 10000 tenGigE32 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini new file mode 100644 index 000000000000..487e80dcbd70 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 016:1 017:1 018:1 019:1 020:1 021:1 022:1 023:1 024:1 025:1 026:1 027:1 028:1 029:1 030:1 031:1 032:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile new file mode 100644 index 000000000000..dd6f707a81ab --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32X25G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini new file mode 100644 index 000000000000..62dd91ba8869 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE8 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE16 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE24 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE32 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE40 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE48 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE56 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE64 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE72 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE80 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE88 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE96 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE104 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE112 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE120 +Ethernet128 128,129,130,131,132,133,134,135 400000 four00GigE128 +Ethernet136 136,137,138,139,140,141,142,143 400000 four00GigE136 +Ethernet144 144,145,146,147,148,149,150,151 400000 four00GigE144 +Ethernet152 152,153,154,155,156,157,158,159 400000 four00GigE152 +Ethernet160 160,161,162,163,164,165,166,167 400000 four00GigE160 +Ethernet168 168,169,170,171,172,173,174,175 400000 four00GigE168 +Ethernet176 176,177,178,179,180,181,182,183 400000 four00GigE176 +Ethernet184 184,185,186,187,188,189,190,191 400000 four00GigE184 +Ethernet192 192,193,194,195,196,197,198,199 400000 four00GigE192 +Ethernet200 200,201,202,203,204,205,206,207 400000 four00GigE200 +Ethernet208 208,209,210,211,212,213,214,215 400000 four00GigE208 +Ethernet216 216,217,218,219,220,221,222,223 400000 four00GigE216 +Ethernet224 224,225,226,227,228,229,230,231 400000 four00GigE224 +Ethernet232 232,233,234,235,236,237,238,239 400000 four00GigE232 +Ethernet240 240,241,242,243,244,245,246,247 400000 four00GigE240 +Ethernet248 248,249,250,251,252,253,254,255 400000 four00GigE248 +Ethernet256 256 10000 tenGigE256 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini new file mode 100644 index 000000000000..2813bbd363f8 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 128:1 136:1 144:1 152:1 160:1 168:1 176:1 184:1 192:1 200:1 208:1 216:1 224:1 232:1 240:1 248:1 256:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile new file mode 100644 index 000000000000..6dc6f35fed4e --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 new file mode 100644 index 000000000000..a5212d979fcb --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 @@ -0,0 +1,165 @@ +{%- macro set_default_topology() %} +{%- if default_topo is defined %} +{{ default_topo }} +{%- else %} +def +{%- endif %} +{%- endmacro -%} + +{# Determine device topology and filename postfix #} +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- if switch_role.lower() == 'torrouter' %} +{%- set filename_postfix = 't0' %} +{%- elif switch_role.lower() == 'leafrouter' %} +{%- set filename_postfix = 't1' %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- endif %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- set switch_role = '' %} +{%- endif -%} + +{# Import default values from device HWSKU folder #} +{%- import 'buffers_defaults_%s.j2' % filename_postfix as defs %} + +{%- set default_cable = defs.default_cable -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{%- if defs.ports2cable is defined %} + {%- set ports2cable = defs.ports2cable %} +{%- else %} + {%- set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } + -%} +{%- endif %} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- set PORT_ALL = [] %} + +{%- if PORT is not defined %} + {%- if defs.generate_port_lists(PORT_ALL) %} {% endif %} +{%- else %} + {%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') %} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT_ALL %} + {%- set cable = cable_length(port) %} + "{{ port }}": "{{ cable }}"{%- if not loop.last %},{% endif %} + + {% endfor %} + } + }, + +{% if defs.generate_buffer_pool_and_profiles is defined %} +{{ defs.generate_buffer_pool_and_profiles() }} +{% endif %} + +{%- if defs.generate_profile_lists is defined %} +{{ defs.generate_profile_lists(port_names_active) }}, +{% endif %} + +{%- if defs.generate_pg_profils is defined %} +{{ defs.generate_pg_profils(port_names_active) }} +{% else %} + "BUFFER_PG": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, +{% endif %} + +{% if defs.generate_queue_buffers is defined %} +{{ defs.generate_queue_buffers(port_names_active) }} +{% else %} + "BUFFER_QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{% endif %} +} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini new file mode 100644 index 000000000000..62dd91ba8869 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE8 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE16 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE24 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE32 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE40 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE48 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE56 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE64 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE72 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE80 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE88 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE96 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE104 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE112 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE120 +Ethernet128 128,129,130,131,132,133,134,135 400000 four00GigE128 +Ethernet136 136,137,138,139,140,141,142,143 400000 four00GigE136 +Ethernet144 144,145,146,147,148,149,150,151 400000 four00GigE144 +Ethernet152 152,153,154,155,156,157,158,159 400000 four00GigE152 +Ethernet160 160,161,162,163,164,165,166,167 400000 four00GigE160 +Ethernet168 168,169,170,171,172,173,174,175 400000 four00GigE168 +Ethernet176 176,177,178,179,180,181,182,183 400000 four00GigE176 +Ethernet184 184,185,186,187,188,189,190,191 400000 four00GigE184 +Ethernet192 192,193,194,195,196,197,198,199 400000 four00GigE192 +Ethernet200 200,201,202,203,204,205,206,207 400000 four00GigE200 +Ethernet208 208,209,210,211,212,213,214,215 400000 four00GigE208 +Ethernet216 216,217,218,219,220,221,222,223 400000 four00GigE216 +Ethernet224 224,225,226,227,228,229,230,231 400000 four00GigE224 +Ethernet232 232,233,234,235,236,237,238,239 400000 four00GigE232 +Ethernet240 240,241,242,243,244,245,246,247 400000 four00GigE240 +Ethernet248 248,249,250,251,252,253,254,255 400000 four00GigE248 +Ethernet256 256 10000 tenGigE256 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini new file mode 100644 index 000000000000..2813bbd363f8 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 128:1 136:1 144:1 152:1 160:1 168:1 176:1 184:1 192:1 200:1 208:1 216:1 224:1 232:1 240:1 248:1 256:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile new file mode 100644 index 000000000000..6dc6f35fed4e --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/default_sku b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/default_sku new file mode 100644 index 000000000000..563676854022 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/default_sku @@ -0,0 +1 @@ +db98cx8580_32cd t1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py new file mode 100644 index 000000000000..ea525f5d74b1 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/etc/sonic/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py new file mode 100644 index 000000000000..80b11bf0630e --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py @@ -0,0 +1,261 @@ +#!/usr/bin/env python + +try: + import os + import time + import sys + import re + import subprocess + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +smbus_present = 1 + +try: + import smbus +except ImportError, e: + smbus_present = 0 + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + _port_start = 1 + _port_end = 257 + ports_in_block = 257 + + _port_to_eeprom_mapping = {} + + _qsfp_ports = range(_port_start, ports_in_block + 1) + + def __init__(self): + os.system("modprobe i2c-dev") + if not os.path.exists("/sys/bus/i2c/devices/0-0050") : + os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + + eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' + #for x in range(self.port _start, self.port_end +1): + x = self.port_start + while(x self._port_end: + return False + + port_ps = "/sys/bus/i2c/devices/0-0050/sfp_port_reset" + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_nuM, lpmode): + raise NotImplementedError + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def i2c_get(self, device_addr, offset): + status = 0 + if smbus_present == 0: + x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) + cmdstatus, status = cmd.getstatusoutput(x) + if cmdstatus != 0: + return cmdstatus + status = int(status, 16) + else: + bus = smbus.SMBus(0) + status = bus.read_byte_data(device_addr, offset) + return status + + def i2c_set(self, device_addr, offset, value): + if smbus_present == 0: + cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) + os.system(cmd) + else: + bus = smbus.SMBus(0) + bus.write_byte_data(device_addr, offset, value) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + else: + self.i2c_set(0x70, 0, 0) + self.i2c_set(0x71, 0, 0) + self.i2c_set(0x72, 0, 0) + self.i2c_set(0x73, 0, 0) + self.i2c_set(0x74, 0, 0) + reg = (port_num)/8 + offset = reg % 8 + if offset >=4: + offset=offset-4 + elif offset<4: + offset=offset+4 + bin_offset = 1<= 0 and port_num <= 63: + device_reg = 0x70 + elif port_num >= 64 and port_num <= 127: + device_reg = 0x71 + elif port_num >= 128 and port_num <= 191: + device_reg = 0x72 + elif port_num >= 192 and port_num <= 255: + device_reg = 0x73 + elif port_num >= 256 and port_num <= 257: + device_reg = 0x74 + + #print "i2c %d %x %x" % (port_num, device_reg, bin_offset) + self.i2c_set(device_reg, 0, bin_offset) + path = "/sys/bus/i2c/devices/0-0050/eeprom" + try: + reg_file = open(path) + reg_file.seek(01) + reg_file.read(02) + except IOError as e: + return False + + return True + + def read_porttab_mappings(self, porttabfile): + #print("I am in porttab_mappings") + logical = [] + logical_to_bcm = {} + logical_to_physical = {} + physical_to_logical = {} + last_fp_port_index = 0 + last_portname = "" + first = 1 + port_pos_in_file = 0 + parse_fmt_port_config_ini = False + + try: + f = open(porttabfile) + except: + raise + + parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini") + # Read the porttab file and generate dicts + # with mapping for future reference. + # + # TODO: Refactor this to use the portconfig.py module that now + # exists as part of the sonic-config-engine package. + title = [] + for line in f: + line.strip() + if re.search("^#", line) is not None: + # The current format is: # name lanes alias index speed + # Where the ordering of the columns can vary + title = line.split()[1:] + continue + #print title + + # Parsing logic for 'port_config.ini' file + if (parse_fmt_port_config_ini): + # bcm_port is not explicitly listed in port_config.ini format + # Currently we assume ports are listed in numerical order according to bcm_port + # so we use the port's position in the file (zero-based) as bcm_port + portname = line.split()[0] + + bcm_port = str(port_pos_in_file) + + + if "index" in title: + fp_port_index = int(line.split()[title.index("index")]) + # Leave the old code for backward compatibility + #if len(line.split()) >= 4: + # fp_port_index = (line.split()[3]) + # print(fp_port_index) + else: + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + else: # Parsing logic for older 'portmap.ini' file + (portname, bcm_port) = line.split("=")[1].split(",")[:2] + + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + + if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): + continue + + if first == 1: + # Initialize last_[physical|logical]_port + # to the first valid port + last_fp_port_index = fp_port_index + last_portname = portname + first = 0 + + logical.append(portname) + + logical_to_bcm[portname] = "xe" + bcm_port + logical_to_physical[portname] = [fp_port_index] + if physical_to_logical.get(fp_port_index) is None: + physical_to_logical[fp_port_index] = [portname] + else: + physical_to_logical[fp_port_index].append( + portname) + + if (fp_port_index - last_fp_port_index) > 1: + # last port was a gang port + for p in range(last_fp_port_index+1, fp_port_index): + logical_to_physical[last_portname].append(p) + if physical_to_logical.get(p) is None: + physical_to_logical[p] = [last_portname] + else: + physical_to_logical[p].append(last_portname) + + last_fp_port_index = fp_port_index + last_portname = portname + + port_pos_in_file += 1 + + self.logical = logical + self.logical_to_bcm = logical_to_bcm + self.logical_to_physical = logical_to_physical + self.physical_to_logical = physical_to_logical + + + #print(self.logical_to_physical) + '''print("logical: " + self.logical) + print("logical to bcm: " + self.logical_to_bcm) + print("logical to physical: " + self.logical_to_physical) + print("physical to logical: " + self.physical_to_logical)''' + #print("exiting port_tab_mappings") + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + @property + def get_transceiver_change_event(self): + raise NotImplementedError diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} From c5c1ae2173cb4628c6bfd00b17c72470824cd874 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Fri, 3 Apr 2020 22:41:37 +0300 Subject: [PATCH 0485/1427] [Mellanox] update eeprom.py plugin for SimX (#4364) Signed-off-by: Mykola Faryma --- .../x86_64-mlnx_msn2700-r0/plugins/eeprom.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py index 63303c13a244..c9ae1a335421 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py @@ -21,6 +21,7 @@ from cStringIO import StringIO from sonic_eeprom import eeprom_base from sonic_eeprom import eeprom_tlvinfo + from sonic_device_util import get_machine_info import subprocess except ImportError, e: raise ImportError (str(e) + "- required module not found") @@ -34,6 +35,14 @@ def log_error(msg): syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() + +machine_info = get_machine_info() +onie_platform = machine_info['onie_platform'] +if 'simx' in onie_platform: + platform_path = os.path.join('/usr/share/sonic/device', onie_platform) + subprocess.check_call(['/usr/bin/xxd', '-r', '-p', 'syseeprom.hex', 'syseeprom.bin'], cwd=platform_path) + CACHE_FILE = os.path.join(platform_path, 'syseeprom.bin') + class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 @@ -45,12 +54,12 @@ def __init__(self, name, path, cpld_root, ro): time.sleep(1) else: break - + if not (os.path.exists(EEPROM_SYMLINK) or os.path.isfile(CACHE_FILE)): log_error("Nowhere to read syseeprom from! No symlink or cache file found") raise RuntimeError("No syseeprom symlink or cache file found") - self.eeprom_path = EEPROM_SYMLINK + self.eeprom_path = EEPROM_SYMLINK if 'simx' not in onie_platform else CACHE_FILE super(board, self).__init__(self.eeprom_path, 0, '', True) def decode_eeprom(self, e): @@ -60,3 +69,4 @@ def decode_eeprom(self, e): decode_output = sys.stdout.getvalue() sys.stdout = original_stdout print(decode_output.replace('\0', '')) + From abbd871d552587e37a42a3aa3a09515826fcf92a Mon Sep 17 00:00:00 2001 From: CharlieChenEC <49221644+CharlieChenEC@users.noreply.github.com> Date: Sat, 4 Apr 2020 03:48:47 +0800 Subject: [PATCH 0486/1427] Fix the error that 'sensord' daemon cannot be spawn correctly in pmon container (#4354) - This commit fixes the issue #4021 (Sensord not able to start up on both master and 201911 branches) - Add the new patch file for "lm-sensors" to perform dh_installinit to include sensord.init in the packed deb. So that the missing init script file for 'sensord' will be included in the created 'sensord' deb. Signed-off-by: Charlie Chen --- ...dh_installinit-to-include-sensord.in.patch | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch diff --git a/src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch b/src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch new file mode 100644 index 000000000000..6d3e279ea5e7 --- /dev/null +++ b/src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch @@ -0,0 +1,23 @@ +From b11fd3d516b62c01513d289bc901820aa150c63e Mon Sep 17 00:00:00 2001 +From: Charlie Chen +Date: Wed, 1 Apr 2020 06:59:06 +0000 +Subject: Patch to peform dh_installinit to include sensord.install in the + packed deb + +Signed-off-by: Charlie Chen +--- + debian/rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/rules b/src/lm-sensors/lm-sensors-3.4.0/debian/rules +index 5ebda06..1d77e28 100755 +--- a/src/lm-sensors/lm-sensors-3.4.0/debian/rules ++++ b/src/lm-sensors/lm-sensors-3.4.0/debian/rules +@@ -56,3 +56,4 @@ override_dh_auto_install-arch: + + override_dh_installinit-arch: + dh_installinit -plm-sensors --no-start ++ dh_installinit -psensord --no-start +-- +2.17.1 + From 524cf9e56ad5daa6f5a110dd50fc9af3e3ef0468 Mon Sep 17 00:00:00 2001 From: shine4chen <37530989+shine4chen@users.noreply.github.com> Date: Sun, 5 Apr 2020 06:24:06 +0800 Subject: [PATCH 0487/1427] MCLAG feature for SONIC (#2514) * MCLAG feature for sonic * MCLAG feature for sonic * remove binary file * remove unused dockerfile update docker-iccpd to stretch-based container Signed-off-by: shine.chen * minor fix for isolation port setting Signed-off-by: shine.chen * iccpd docker would start on demand Signed-off-by: shine.chen * Add x attribute on mclagdctl file Signed-off-by: shine.chen * add warm-reboot support for MCLAG Signed-off-by: shine.chen * merge to master branch and reformat iccpd file Signed-off-by: shine.chen * fix some bugs and make peer-link configuration optional Signed-off-by: shine.chen * refactor code per Brcm review Signed-off-by: shine.chen * correct a typo Signed-off-by: shine.chen * * optimize iccpd arp/mac sync process * refine code according to brcm opinoin * unify function return value Signed-off-by: shine.chen * * optimize warm-reboot process * estabish iccpd connection with configurated src-ip Signed-off-by: shine.chen * fix a typo Signed-off-by: shine.chen * optimize some code * add some debug info * optimize bridge mac setting * fix vlan mac sync issue on standby node Signed-off-by: shine.chen * optimize some code Signed-off-by: shine.chen * fix some bugs for warm-reboot Signed-off-by: shine.chen * refine log level Signed-off-by: shine.chen * refine iccpd syslog & skip arp packet whose src ip is local ip Signed-off-by: shine.chen * remove iccpd dependency with teamd Signed-off-by: shine.chen * print log level when dump mclag status Signed-off-by: shine.chen * revise per community review Signed-off-by: shine.chen Co-authored-by: shine.chen Co-authored-by: shine.chen --- dockers/docker-iccpd/Dockerfile.j2 | 47 + .../docker-iccpd/base_image_files/mclagdctl | 10 + dockers/docker-iccpd/iccpd.j2 | 11 + dockers/docker-iccpd/iccpd.sh | 17 + dockers/docker-iccpd/start.sh | 18 + dockers/docker-iccpd/supervisord.conf | 29 + files/build_templates/docker_image_ctl.j2 | 3 + files/build_templates/iccpd.service.j2 | 13 + .../build_templates/sonic_debian_extension.j2 | 3 + rules/config | 5 + rules/docker-iccpd.mk | 18 + rules/iccpd.mk | 14 + src/iccpd/Makefile | 35 + src/iccpd/debian/DEBIAN/control | 12 + src/iccpd/include/app_csm.h | 73 + src/iccpd/include/cmd_option.h | 84 + src/iccpd/include/iccp_cli.h | 67 + src/iccpd/include/iccp_cmd.h | 29 + src/iccpd/include/iccp_cmd_show.h | 35 + src/iccpd/include/iccp_consistency_check.h | 43 + src/iccpd/include/iccp_csm.h | 165 ++ src/iccpd/include/iccp_ifm.h | 41 + src/iccpd/include/iccp_netlink.h | 47 + src/iccpd/include/logger.h | 70 + src/iccpd/include/mlacp_fsm.h | 106 + src/iccpd/include/mlacp_link_handler.h | 60 + src/iccpd/include/mlacp_sync_prepare.h | 55 + src/iccpd/include/mlacp_sync_update.h | 49 + src/iccpd/include/mlacp_tlv.h | 456 ++++ src/iccpd/include/msg_format.h | 499 ++++ src/iccpd/include/port.h | 156 ++ src/iccpd/include/scheduler.h | 59 + src/iccpd/include/system.h | 102 + src/iccpd/src/Makefile | 55 + src/iccpd/src/app_csm.c | 316 +++ src/iccpd/src/cmd_option.c | 266 ++ src/iccpd/src/iccp_cli.c | 498 ++++ src/iccpd/src/iccp_cmd.c | 168 ++ src/iccpd/src/iccp_cmd_show.c | 477 ++++ src/iccpd/src/iccp_consistency_check.c | 175 ++ src/iccpd/src/iccp_csm.c | 797 ++++++ src/iccpd/src/iccp_ifm.c | 762 ++++++ src/iccpd/src/iccp_main.c | 272 ++ src/iccpd/src/iccp_netlink.c | 1545 +++++++++++ src/iccpd/src/logger.c | 140 + src/iccpd/src/mclagdctl/Makefile | 28 + src/iccpd/src/mclagdctl/mclagdctl.c | 883 ++++++ src/iccpd/src/mclagdctl/mclagdctl.h | 198 ++ src/iccpd/src/mlacp_fsm.c | 1209 +++++++++ src/iccpd/src/mlacp_link_handler.c | 2401 +++++++++++++++++ src/iccpd/src/mlacp_sync_prepare.c | 624 +++++ src/iccpd/src/mlacp_sync_update.c | 740 +++++ src/iccpd/src/port.c | 665 +++++ src/iccpd/src/scheduler.c | 770 ++++++ src/iccpd/src/system.c | 200 ++ 55 files changed, 15620 insertions(+) create mode 100644 dockers/docker-iccpd/Dockerfile.j2 create mode 100755 dockers/docker-iccpd/base_image_files/mclagdctl create mode 100644 dockers/docker-iccpd/iccpd.j2 create mode 100644 dockers/docker-iccpd/iccpd.sh create mode 100644 dockers/docker-iccpd/start.sh create mode 100644 dockers/docker-iccpd/supervisord.conf create mode 100644 files/build_templates/iccpd.service.j2 create mode 100644 rules/docker-iccpd.mk create mode 100644 rules/iccpd.mk create mode 100644 src/iccpd/Makefile create mode 100644 src/iccpd/debian/DEBIAN/control create mode 100644 src/iccpd/include/app_csm.h create mode 100644 src/iccpd/include/cmd_option.h create mode 100644 src/iccpd/include/iccp_cli.h create mode 100644 src/iccpd/include/iccp_cmd.h create mode 100644 src/iccpd/include/iccp_cmd_show.h create mode 100644 src/iccpd/include/iccp_consistency_check.h create mode 100644 src/iccpd/include/iccp_csm.h create mode 100644 src/iccpd/include/iccp_ifm.h create mode 100644 src/iccpd/include/iccp_netlink.h create mode 100644 src/iccpd/include/logger.h create mode 100644 src/iccpd/include/mlacp_fsm.h create mode 100644 src/iccpd/include/mlacp_link_handler.h create mode 100644 src/iccpd/include/mlacp_sync_prepare.h create mode 100644 src/iccpd/include/mlacp_sync_update.h create mode 100644 src/iccpd/include/mlacp_tlv.h create mode 100644 src/iccpd/include/msg_format.h create mode 100644 src/iccpd/include/port.h create mode 100644 src/iccpd/include/scheduler.h create mode 100644 src/iccpd/include/system.h create mode 100644 src/iccpd/src/Makefile create mode 100644 src/iccpd/src/app_csm.c create mode 100644 src/iccpd/src/cmd_option.c create mode 100644 src/iccpd/src/iccp_cli.c create mode 100644 src/iccpd/src/iccp_cmd.c create mode 100644 src/iccpd/src/iccp_cmd_show.c create mode 100644 src/iccpd/src/iccp_consistency_check.c create mode 100644 src/iccpd/src/iccp_csm.c create mode 100644 src/iccpd/src/iccp_ifm.c create mode 100644 src/iccpd/src/iccp_main.c create mode 100644 src/iccpd/src/iccp_netlink.c create mode 100644 src/iccpd/src/logger.c create mode 100644 src/iccpd/src/mclagdctl/Makefile create mode 100644 src/iccpd/src/mclagdctl/mclagdctl.c create mode 100644 src/iccpd/src/mclagdctl/mclagdctl.h create mode 100644 src/iccpd/src/mlacp_fsm.c create mode 100644 src/iccpd/src/mlacp_link_handler.c create mode 100644 src/iccpd/src/mlacp_sync_prepare.c create mode 100644 src/iccpd/src/mlacp_sync_update.c create mode 100644 src/iccpd/src/port.c create mode 100644 src/iccpd/src/scheduler.c create mode 100644 src/iccpd/src/system.c diff --git a/dockers/docker-iccpd/Dockerfile.j2 b/dockers/docker-iccpd/Dockerfile.j2 new file mode 100644 index 000000000000..ce3969f29da5 --- /dev/null +++ b/dockers/docker-iccpd/Dockerfile.j2 @@ -0,0 +1,47 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-config-engine-stretch + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -f -y \ + libdbus-1-3 \ + libdaemon0 \ + libpython2.7 \ + # Install redis-tools dependencies + # TODO: implicitly install dependencies + libatomic1 \ + libjemalloc1 \ + liblua5.1-0 \ + lua-bitop \ + lua-cjson + +RUN apt-get -y install ebtables +RUN apt-get -y install -f kmod + +COPY \ +{% for deb in docker_iccpd_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN dpkg -i \ +{% for deb in docker_iccpd_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor %} + +COPY ["start.sh", "iccpd.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["iccpd.j2", "/usr/share/sonic/templates/"] + +RUN chmod +x /usr/bin/start.sh /usr/bin/iccpd.sh +RUN apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /debs + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-iccpd/base_image_files/mclagdctl b/dockers/docker-iccpd/base_image_files/mclagdctl new file mode 100755 index 000000000000..7c0b45dd0625 --- /dev/null +++ b/dockers/docker-iccpd/base_image_files/mclagdctl @@ -0,0 +1,10 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS iccpd mclagdctl "$@" diff --git a/dockers/docker-iccpd/iccpd.j2 b/dockers/docker-iccpd/iccpd.j2 new file mode 100644 index 000000000000..6c6f9fab1afa --- /dev/null +++ b/dockers/docker-iccpd/iccpd.j2 @@ -0,0 +1,11 @@ +{% for mclag_id in MC_LAG %} +mclag_id:{{mclag_id}} + local_ip:{{MC_LAG[mclag_id]['local_ip']}} + peer_ip:{{MC_LAG[mclag_id]['peer_ip']}} +{% if MC_LAG[mclag_id].has_key('peer_link') %} + peer_link:{{MC_LAG[mclag_id]['peer_link']}} +{% endif %} + mclag_interface:{{MC_LAG[mclag_id]['mclag_interface']}} +{% endfor %} +system_mac:{{DEVICE_METADATA['localhost']['mac']}} + diff --git a/dockers/docker-iccpd/iccpd.sh b/dockers/docker-iccpd/iccpd.sh new file mode 100644 index 000000000000..d3b2888344ac --- /dev/null +++ b/dockers/docker-iccpd/iccpd.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +function start_app { + rm -f /var/run/iccpd/* + mclagsyncd & + iccpd +} + +function clean_up { + pkill -9 mclagsyncd + pkill -9 iccpd + exit +} + +trap clean_up SIGTERM SIGKILL +start_app +read diff --git a/dockers/docker-iccpd/start.sh b/dockers/docker-iccpd/start.sh new file mode 100644 index 000000000000..d17634cb836a --- /dev/null +++ b/dockers/docker-iccpd/start.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + + +ICCPD_CONF_PATH=/etc/iccpd + +rm -rf $ICCPD_CONF_PATH +mkdir -p $ICCPD_CONF_PATH + +sonic-cfggen -d -t /usr/share/sonic/templates/iccpd.j2 > $ICCPD_CONF_PATH/iccpd.conf + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +rm -f /var/run/rsyslogd.pid + +supervisorctl start rsyslogd + +supervisorctl start iccpd diff --git a/dockers/docker-iccpd/supervisord.conf b/dockers/docker-iccpd/supervisord.conf new file mode 100644 index 000000000000..dc71f07c6c30 --- /dev/null +++ b/dockers/docker-iccpd/supervisord.conf @@ -0,0 +1,29 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:iccpd] +command=/usr/bin/iccpd.sh +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 297c9dd1c2bd..6012ccd8b573 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -231,6 +231,9 @@ start() { {%- if docker_container_name != "database" %} -v /usr/share/sonic/device/$PLATFORM/$HWSKU/$DEV:/usr/share/sonic/hwsku:ro \ {%- endif %} +{%- if docker_container_name == "iccpd" %} + -v /lib/modules:/lib/modules:ro \ +{%- endif %} {%- if sonic_asic_platform != "mellanox" %} --tmpfs /tmp \ {%- endif %} diff --git a/files/build_templates/iccpd.service.j2 b/files/build_templates/iccpd.service.j2 new file mode 100644 index 000000000000..979c45de72c5 --- /dev/null +++ b/files/build_templates/iccpd.service.j2 @@ -0,0 +1,13 @@ +[Unit] +Description=ICCPD container +Requires=updategraph.service swss.service +After=updategraph.service swss.service + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop + +[Install] +WantedBy=multi-user.target swss.service diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index bdecdabe95d1..dad1cb9b8906 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -427,6 +427,9 @@ if [ -f {{service}} ]; then echo "{{service}}" | sudo tee -a $GENERATED_SERVICE_FILE fi {% endfor %} +if [ -f iccpd.service ]; then + sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable iccpd.service +fi sudo LANG=C chroot $FILESYSTEM_ROOT fuser -km /sys || true sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys {% endif %} diff --git a/rules/config b/rules/config index 70ac38e29669..e9eb460c4dc1 100644 --- a/rules/config +++ b/rules/config @@ -115,6 +115,10 @@ SONIC_DPKG_CACHE_SOURCE ?= /var/cache/sonic/artifacts # Default VS build memory preparation DEFAULT_VS_PREPARE_MEM = yes + +# ENABLE_ICCPD - build docker-iccpd for mclag support +ENABLE_ICCPD = y + # ENABLE_SYSTEM_SFLOW - build docker-sonic-sflow for sFlow support ENABLE_SFLOW = y @@ -126,3 +130,4 @@ ENABLE_RESTAPI = n # ENABLE_NAT - build docker-sonic-nat for nat support ENABLE_NAT = y + diff --git a/rules/docker-iccpd.mk b/rules/docker-iccpd.mk new file mode 100644 index 000000000000..da661e9a2244 --- /dev/null +++ b/rules/docker-iccpd.mk @@ -0,0 +1,18 @@ +# docker image for iccpd agent + +DOCKER_ICCPD = docker-iccpd.gz +$(DOCKER_ICCPD)_PATH = $(DOCKERS_PATH)/docker-iccpd +$(DOCKER_ICCPD)_DEPENDS += $(SWSS) $(REDIS_TOOLS) $(ICCPD) +$(DOCKER_ICCPD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) + +ifeq ($(ENABLE_ICCPD), y) +SONIC_DOCKER_IMAGES += $(DOCKER_ICCPD) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ICCPD) +SONIC_STRETCH_DOCKERS += $(DOCKER_ICCPD) +endif + +$(DOCKER_ICCPD)_CONTAINER_NAME = iccpd +$(DOCKER_ICCPD)_RUN_OPT += --privileged -t +$(DOCKER_ICCPD)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro + +$(DOCKER_ICCPD)_BASE_IMAGE_FILES += mclagdctl:/usr/bin/mclagdctl diff --git a/rules/iccpd.mk b/rules/iccpd.mk new file mode 100644 index 000000000000..d54faaba5b76 --- /dev/null +++ b/rules/iccpd.mk @@ -0,0 +1,14 @@ +# iccpd package + +ICCPD_VERSION = 0.0.5 + +ICCPD = iccpd_$(ICCPD_VERSION)_amd64.deb +$(ICCPD)_DEPENDS += $(LIBNL_GENL3_DEV) $(LIBNL_CLI_DEV) +$(ICCPD)_RDEPENDS += $(LIBNL_GENL3) $(LIBNL_CLI) +$(ICCPD)_SRC_PATH = $(SRC_PATH)/iccpd +SONIC_MAKE_DEBS += $(ICCPD) +# SONIC_STRETCH_DEBS += $(ICCPD) + +# Export these variables so they can be used in a sub-make +export ICCPD_VERSION +export ICCPD diff --git a/src/iccpd/Makefile b/src/iccpd/Makefile new file mode 100644 index 000000000000..401ff394d145 --- /dev/null +++ b/src/iccpd/Makefile @@ -0,0 +1,35 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = iccpd_$(ICCPD_VERSION)_amd64.deb +DEB_PATH = debian + +all: iccpd-build mclagdctl-build + +iccpd-build: + make -C src + +mclagdctl-build: + make -C src/mclagdctl + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + make all + if [ ! -d $(DEB_PATH)/usr/bin ]; then + mkdir -p $(DEB_PATH)/usr/bin + fi + cp iccpd $(DEB_PATH)/usr/bin/iccpd + cp src/mclagdctl/mclagdctl $(DEB_PATH)/usr/bin/mclagdctl + chmod +x $(DEB_PATH)/usr/bin/iccpd + chmod +x $(DEB_PATH)/usr/bin/mclagdctl + md5sum $(DEB_PATH)/usr/bin/iccpd > $(DEB_PATH)/DEBIAN/md5sums + md5sum $(DEB_PATH)/usr/bin/mclagdctl >> $(DEB_PATH)/DEBIAN/md5sums + dpkg-deb -b $(DEB_PATH) $(DEST)/$(MAIN_TARGET) + +clean: iccpd-clean mclagdctl-clean + +iccpd-clean: + make -C src clean + +mclagdctl-clean: + make -C src/mclagdctl clean diff --git a/src/iccpd/debian/DEBIAN/control b/src/iccpd/debian/DEBIAN/control new file mode 100644 index 000000000000..cedfa03f37c0 --- /dev/null +++ b/src/iccpd/debian/DEBIAN/control @@ -0,0 +1,12 @@ +Package: iccpd-0.0.5-amd64 +Source: nps +Version: 0.0.5 +Architecture: amd64 +Maintainer: Simon Ji +Installed-Size: 1508 +Depends: +Section: main +Priority: extra +Homepage: https://github.com/NephosInc/SONiC +Description: + diff --git a/src/iccpd/include/app_csm.h b/src/iccpd/include/app_csm.h new file mode 100644 index 000000000000..a0565556d24c --- /dev/null +++ b/src/iccpd/include/app_csm.h @@ -0,0 +1,73 @@ +/* + * app_csm.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef APP_CSM_H_ +#define APP_CSM_H_ + +#include + +#include "../include/mlacp_fsm.h" + +struct CSM; + +enum APP_CONNECTION_STATE +{ + APP_NONEXISTENT, + APP_RESET, + APP_CONNSENT, + APP_CONNREC, + APP_CONNECTING, + APP_OPERATIONAL +}; + +typedef enum APP_CONNECTION_STATE APP_CONNECTION_STATE_E; + +struct AppCSM +{ + struct mLACP mlacp; + APP_CONNECTION_STATE_E current_state; + + uint32_t rx_connect_msg_id; + uint32_t tx_connect_msg_id; + uint32_t invalid_msg_id; + + TAILQ_HEAD(app_msg_list, Msg) app_msg_list; + + uint8_t invalid_msg : 1; + uint8_t nak_msg : 1; +}; + +void app_csm_init(struct CSM*, int all); +void app_csm_finalize(struct CSM*); +void app_csm_transit(struct CSM*); +int app_csm_prepare_iccp_msg(struct CSM*, char*, size_t); +void app_csm_enqueue_msg(struct CSM*, struct Msg*); +struct Msg* app_csm_dequeue_msg(struct CSM*); +void app_csm_correspond_from_msg(struct CSM*, struct Msg*); +void app_csm_correspond_from_connect_msg(struct CSM*, struct Msg*); +void app_csm_correspond_from_connect_ack_msg(struct CSM*, struct Msg*); +int app_csm_prepare_nak_msg(struct CSM*, char*, size_t); +int app_csm_prepare_connect_msg(struct CSM*, char*, size_t); +int app_csm_prepare_connect_ack_msg(struct CSM*, char*, size_t); + +#endif /* APP_CSM_H_ */ diff --git a/src/iccpd/include/cmd_option.h b/src/iccpd/include/cmd_option.h new file mode 100644 index 000000000000..ca5582cfcc60 --- /dev/null +++ b/src/iccpd/include/cmd_option.h @@ -0,0 +1,84 @@ +/* + * cmd_option.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef CMD_OPTION_H_ +#define CMD_OPTION_H_ + +#include +#include +#include +#include +#include +#include + +#define OPTION_MAX_LEN 256 +#define MSG_LEN 81 + +#define CMD_OPTION_PARSER_INIT_VALUE \ + { \ + .log_file_path = "/var/log/iccpd.log", \ + .pid_file_path = "/var/run/iccpd/iccpd.pid", \ + .cmd_file_path = "/var/run/iccpd/iccpd.vty", \ + .config_file_path = "/etc/iccpd/iccpd.conf", \ + .mclagdctl_file_path = "/var/run/iccpd/mclagdctl.sock", \ + .console_log = 0, \ + .telnet_port = 2015, \ + .init = cmd_option_parser_init, \ + .finalize = cmd_option_parser_finalize, \ + .dump_usage = cmd_option_parser_dump_usage, \ + .parse = cmd_option_parser_parse, \ + } + +struct CmdOption +{ + char* desc; + char* option; + char* parameter; + LIST_ENTRY(CmdOption) next; +}; + +struct CmdOptionParser +{ + char* log_file_path; + char* pid_file_path; + char* cmd_file_path; + char* config_file_path; + char *mclagdctl_file_path; + uint8_t console_log; + uint16_t telnet_port; + LIST_HEAD(option_list, CmdOption) option_list; + int (*parse)(struct CmdOptionParser*, int, char*[]); + void (*init)(struct CmdOptionParser*); + void (*finalize)(struct CmdOptionParser*); + void (*dump_usage)(struct CmdOptionParser*, char*); +}; + +int cmd_option_parser_parse(struct CmdOptionParser*, int, char*[]); +struct CmdOption* cmd_option_add(struct CmdOptionParser*, char*); +struct CmdOption* cmd_option_find(struct CmdOptionParser*, char*); +void cmd_option_delete(struct CmdOption*); +void cmd_option_parser_init(struct CmdOptionParser*); +void cmd_option_parser_finalize(struct CmdOptionParser*); +void cmd_option_parser_dump_usage(struct CmdOptionParser*, char*); + +#endif /* CMD_OPTION_H_ */ diff --git a/src/iccpd/include/iccp_cli.h b/src/iccpd/include/iccp_cli.h new file mode 100644 index 000000000000..c85fc4316b5f --- /dev/null +++ b/src/iccpd/include/iccp_cli.h @@ -0,0 +1,67 @@ +/* + * iccp_cli.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef _ICCP_CLI_H +#define _ICCP_CLI_H + +#include + +struct CSM; + +typedef enum +{ + QU_TYPE_NONE, + QU_TYPE_MLAG_ADD_PO +} cli_queue_type_et; + +typedef struct cli_param_queue +{ + char ifname[16]; + cli_queue_type_et type; + int param; + int itf_add; + LIST_ENTRY(cli_param_queue) cli_queue_next; +} cli_param_queue_st; + +#define MCLAG_ID_STR "mclag_id" +#define LOCAL_IP_STR "local_ip" +#define PEER_IP_STR "peer_ip" +#define PEER_LINK_STR "peer_link" +#define MCLAG_INTF_STR "mclag_interface" +#define SYSTEM_MAC_STR "system_mac" + +int set_mc_lag_id(struct CSM* csm, uint16_t domain); +int set_peer_link(int mid, const char* ifname); +int set_local_address(int mid, const char* addr); +int set_peer_address(int mid, const char* addr); +int unset_mc_lag_id(struct CSM* csm, uint16_t domain); +int unset_peer_link(int mid); +int unset_local_address(int mid); +int unset_peer_address(int mid); + +int iccp_cli_attach_mclag_domain_to_port_channel(int domain, const char* ifname); +int iccp_cli_detach_mclag_domain_to_port_channel(const char* ifname); +int set_local_system_id(const char* mac); +int unset_local_system_id( ); + +#endif diff --git a/src/iccpd/include/iccp_cmd.h b/src/iccpd/include/iccp_cmd.h new file mode 100644 index 000000000000..01f37456b71d --- /dev/null +++ b/src/iccpd/include/iccp_cmd.h @@ -0,0 +1,29 @@ +/* + * iccp_cmd.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef ICCP_CMD_H_ +#define ICCP_CMD_H_ + +int iccp_config_from_file(char *config_default_dir); + +#endif /* ICCP_CMD_H_ */ diff --git a/src/iccpd/include/iccp_cmd_show.h b/src/iccpd/include/iccp_cmd_show.h new file mode 100644 index 000000000000..0fedca7cdddd --- /dev/null +++ b/src/iccpd/include/iccp_cmd_show.h @@ -0,0 +1,35 @@ +/* + * iccp_cmd_show.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef _ICCP_CMD_SHOW_H +#define _ICCP_CMD_SHOW_H + +#define ICCP_MAX_PORT_NAME 20 +#define ICCP_MAX_IP_STR_LEN 16 + +extern int iccp_mclag_config_dump(char * *buf, int *num, int mclag_id); +extern int iccp_arp_dump(char * *buf, int *num, int mclag_id); +extern int iccp_mac_dump(char * *buf, int *num, int mclag_id); +extern int iccp_local_if_dump(char * *buf, int *num, int mclag_id); +extern int iccp_peer_if_dump(char * *buf, int *num, int mclag_id); +#endif diff --git a/src/iccpd/include/iccp_consistency_check.h b/src/iccpd/include/iccp_consistency_check.h new file mode 100644 index 000000000000..6fa8ea47e2f4 --- /dev/null +++ b/src/iccpd/include/iccp_consistency_check.h @@ -0,0 +1,43 @@ +/* + * iccp_consistency_check.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + * + */ + +#ifndef _ICCP_CONSISTENCY_CHECK_H +#define _ICCP_CONSISTENCY_CHECK_H + + +enum Reason_ID +{ + REASON_NONE = 0, + REASON_INTERRFACE_MODE_IS_ASYNC, + REASON_PEER_IF_IP_IS_ASYNC, + REASON_PEER_IF_VLAN_IS_ASYNC, + REASON_MAX_ARRAY_SIZE +}; + +extern const char *reasons[]; + +enum Reason_ID iccp_consistency_check(char* ifname); + + +#endif diff --git a/src/iccpd/include/iccp_csm.h b/src/iccpd/include/iccp_csm.h new file mode 100644 index 000000000000..9cf1022dd10c --- /dev/null +++ b/src/iccpd/include/iccp_csm.h @@ -0,0 +1,165 @@ +/* + * iccp_csm.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef ICCP_CSM_H_ +#define ICCP_CSM_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "../include/app_csm.h" +#include "../include/msg_format.h" +#include "../include/port.h" + +#define CSM_BUFFER_SIZE 65536 + +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif /*IFNAMSIZ*/ + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif /* INET_ADDRSTRLEN */ + +/* For socket binding */ +#define ICCP_TCP_PORT 8888 +#define MAX_ACCEPT_CONNETIONS 20 + +/* LDP message ID */ +extern uint32_t ICCP_MSG_ID; + +/* Global Buffer */ +extern char g_csm_buf[CSM_BUFFER_SIZE]; + +struct IccpInfo +{ + uint32_t icc_rg_id; + char sender_name[MAX_L_ICC_SENDER_NAME]; + uint32_t status_code; + uint8_t peer_capability_flag : 1; + uint8_t peer_rg_connect_flag : 1; + uint8_t sender_capability_flag : 1; + uint8_t sender_rg_connect_flag : 1; + uint32_t rejected_msg_id; +}; + +/* Receive message node */ +struct Msg +{ + char* buf; + size_t len; + TAILQ_ENTRY(Msg) tail; +}; + +/* Connection state */ +enum ICCP_CONNECTION_STATE +{ + ICCP_NONEXISTENT, + ICCP_INITIALIZED, + ICCP_CAPSENT, + ICCP_CAPREC, + ICCP_CONNECTING, + ICCP_OPERATIONAL +}; + +typedef enum ICCP_CONNECTION_STATE ICCP_CONNECTION_STATE_E; + +typedef enum stp_role_type_e +{ + STP_ROLE_NONE, /* mstp do nothing*/ + STP_ROLE_ACTIVE, /* mstp report port state*/ + STP_ROLE_STANDBY /* mstp fwd bpdu & set port state*/ +} stp_role_type_et; + +/* Connection state machine instance */ +struct CSM +{ + int mlag_id; + + /* Socket info */ + int sock_fd; + pthread_mutex_t conn_mutex; + time_t connTimePrev; + time_t heartbeat_send_time; + time_t heartbeat_update_time; + time_t peer_warm_reboot_time; + time_t warm_reboot_disconn_time; + char peer_itf_name[IFNAMSIZ]; + char peer_ip[INET_ADDRSTRLEN]; + char sender_ip[INET_ADDRSTRLEN]; + void* sock_read_event_ptr; + + /* Msg queue */ + TAILQ_HEAD(msg_list, Msg) msg_list; + + /* STP role */ + stp_role_type_et role_type; + + /* Peers msg */ + struct LocalInterface* peer_link_if; + struct IccpInfo iccp_info; + struct AppCSM app_csm; + ICCP_CONNECTION_STATE_E current_state; + + /* Statistic info */ + uint64_t icc_msg_in_count; /* ICC message input count */ + uint64_t icc_msg_out_count; /* ICC message Output count */ + uint64_t u_msg_in_count; /* Unknown message Input count */ + uint64_t i_msg_in_count; /* Illegal message Input count */ + + /* Log */ + struct MsgLog msg_log; + + LIST_ENTRY(CSM) next; + LIST_HEAD(csm_if_list, If_info) if_bind_list; +}; +int iccp_csm_send(struct CSM*, char*, int); +int iccp_csm_init_msg(struct Msg**, char*, int); +int iccp_csm_prepare_nak_msg(struct CSM*, char*, size_t); +int iccp_csm_prepare_iccp_msg(struct CSM*, char*, size_t); +int iccp_csm_prepare_capability_msg(struct CSM*, char*, size_t); +int iccp_csm_prepare_rg_connect_msg(struct CSM*, char*, size_t); +int iccp_csm_prepare_rg_disconnect_msg(struct CSM*, char*, size_t); +struct Msg* iccp_csm_dequeue_msg(struct CSM*); +void *iccp_get_csm(); +void iccp_csm_init(struct CSM*); +void iccp_csm_transit(struct CSM*); +void iccp_csm_finalize(struct CSM*); +void iccp_csm_status_reset(struct CSM*, int); +void iccp_csm_stp_role_count(struct CSM *csm); +void iccp_csm_msg_list_finalize(struct CSM*); +void iccp_csm_enqueue_msg(struct CSM*, struct Msg*); +void iccp_csm_fill_icc_rg_id_tlv(struct CSM*, ICCHdr*); +void iccp_csm_correspond_from_msg(struct CSM*, struct Msg*); +void iccp_csm_correspond_from_capability_msg(struct CSM*, struct Msg*); +void iccp_csm_correspond_from_rg_connect_msg(struct CSM*, struct Msg*); +void iccp_csm_correspond_from_rg_disconnect_msg(struct CSM*, struct Msg*); + +int mlacp_bind_port_channel_to_csm(struct CSM* csm, const char *ifname); + +#endif /* ICCP_CSM_H_ */ diff --git a/src/iccpd/include/iccp_ifm.h b/src/iccpd/include/iccp_ifm.h new file mode 100644 index 000000000000..7fbb1a8cf4f9 --- /dev/null +++ b/src/iccpd/include/iccp_ifm.h @@ -0,0 +1,41 @@ +/* + * iccp_ifm.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef ICCP_IFM_H +#define ICCP_IFM_H + +#include + +int iccp_sys_local_if_list_get_init(); + +int iccp_arp_get_init(); + +void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, uint8_t mac_addr[ETHER_ADDR_LEN]); + +int do_one_neigh_request(struct nlmsghdr *n); + +void iccp_from_netlink_port_state_handler( char * ifname, int state); + +void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n); +#endif // LACP_IFM_H + diff --git a/src/iccpd/include/iccp_netlink.h b/src/iccpd/include/iccp_netlink.h new file mode 100644 index 000000000000..612a1859591b --- /dev/null +++ b/src/iccpd/include/iccp_netlink.h @@ -0,0 +1,47 @@ +/* Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef ICCP_NETLINK_H +#define ICCP_NETLINK_H +#include +#include +#include +#include +#include +#include + +#include + +#include "../include/system.h" +#include "../include/port.h" + +int iccp_get_port_member_list(struct LocalInterface* lif); +void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg); +void iccp_event_handler_obj_input_dellink(struct nl_object *obj, void *arg); +int iccp_system_init_netlink_socket(); +void iccp_system_dinit_netlink_socket(); +int iccp_init_netlink_event_fd(struct System *sys); +int iccp_handle_events(struct System * sys); +void update_if_ipmac_on_standby(struct LocalInterface* lif_po); +int iccp_sys_local_if_list_get_addr(); +int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInterface *lif); + +#endif + diff --git a/src/iccpd/include/logger.h b/src/iccpd/include/logger.h new file mode 100644 index 000000000000..a90fece2a4d9 --- /dev/null +++ b/src/iccpd/include/logger.h @@ -0,0 +1,70 @@ +/* + * logger.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef LOGGER_H_ +#define LOGGER_H_ + +#include +#include + +#include "../include/cmd_option.h" + +typedef enum _iccpd_log_level_t +{ + CRITICAL_LOG_LEVEL = 0, + ERR_LOG_LEVEL = 1, + WARN_LOG_LEVEL = 2, + NOTICE_LOG_LEVEL = 3, + INFO_LOG_LEVEL = 4, + DEBUG_LOG_LEVEL = 5 +} _iccpd_log_level_t; + + +#define LOGBUF_SIZE 1024 +#define ICCPD_UTILS_SYSLOG (syslog) + +#define ICCPD_LOG_CRITICAL(tag, format, args ...) write_log(CRITICAL_LOG_LEVEL, tag, format, ## args) +#define ICCPD_LOG_ERR(tag, format, args ...) write_log(ERR_LOG_LEVEL, tag, format, ## args) +#define ICCPD_LOG_WARN(tag, format, args ...) write_log(WARN_LOG_LEVEL, tag, format, ## args) +#define ICCPD_LOG_NOTICE(tag, format, args ...) write_log(NOTICE_LOG_LEVEL, tag, format, ## args) +#define ICCPD_LOG_INFO(tag, format, args ...) write_log(INFO_LOG_LEVEL, tag, format, ## args) +#define ICCPD_LOG_DEBUG(tag, format, args ...) write_log(DEBUG_LOG_LEVEL, tag, format, ## args) + +struct LoggerConfig +{ + uint8_t console_log_enabled; + uint8_t log_level; + uint8_t init; +}; + +struct LoggerConfig* logger_get_configuration(); +void logger_set_configuration(int log_level); +char* log_level_to_string(int level); +void log_setup(char* progname, char* path); +void log_finalize(); +void log_init(struct CmdOptionParser* parser); +void write_log(const int level, const char* tag, const char *format, ...); + +#endif /* LOGGER_H_ */ + + diff --git a/src/iccpd/include/mlacp_fsm.h b/src/iccpd/include/mlacp_fsm.h new file mode 100644 index 000000000000..6442d9ff560d --- /dev/null +++ b/src/iccpd/include/mlacp_fsm.h @@ -0,0 +1,106 @@ +/* + * mlacp_fsm.h + * mLACP finite state machine handler. + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef _MLACP_FSM_H +#define _MLACP_FSM_H + +#include "../include/port.h" + +#define MLCAP_SYNC_PHY_DEV_SEC 1 /*every 1 sec*/ + +#define MLACP(csm_ptr) (csm_ptr->app_csm.mlacp) + +struct CSM; + +enum MLACP_APP_STATE +{ + MLACP_STATE_INIT, + MLACP_STATE_STAGE1, + MLACP_STATE_STAGE2, + MLACP_STATE_EXCHANGE, + MLACP_STATE_ERROR, +}; + +typedef enum MLACP_APP_STATE MLACP_APP_STATE_E; + +/* for sender only*/ +enum MLACP_SYNC_STATE +{ + MLACP_SYNC_SYSCONF=0, + MLACP_SYNC_AGGCONF, + MLACP_SYNC_AGGSTATE, + MLACP_SYNC_AGGINFO, + MLACP_SYNC_PEERLINKINFO, + MLACP_SYNC_ARP_INFO, + MLACP_SYNC_DONE, +}; + +typedef enum MLACP_SYNC_STATE MLACP_SYNC_STATE_E; + +struct Remote_System +{ + uint8_t system_id[ETHER_ADDR_LEN]; + uint16_t system_priority; + uint32_t node_id; +}; + +struct mLACP +{ + int id; + int sync_req_num; + + MLACP_APP_STATE_E current_state; + MLACP_SYNC_STATE_E sync_state; + + uint8_t wait_for_sync_data; + uint8_t need_to_sync; + uint8_t node_id; + uint8_t system_id[ETHER_ADDR_LEN]; + uint16_t system_priority; + uint8_t system_config_changed; + + struct Remote_System remote_system; + const char* error_msg; + TAILQ_HEAD(mlacp_msg_list, Msg) mlacp_msg_list; + TAILQ_HEAD(arp_msg_list, Msg) arp_msg_list; + TAILQ_HEAD(arp_info_list, Msg) arp_list; + TAILQ_HEAD(mac_msg_list, Msg) mac_msg_list; + TAILQ_HEAD(mac_info_list, Msg) mac_list; + + LIST_HEAD(lif_list, LocalInterface) lif_list; + LIST_HEAD(lif_purge_list, LocalInterface) lif_purge_list; + LIST_HEAD(pif_list, PeerInterface) pif_list; +}; + +void mlacp_init(struct CSM* csm, int all); +void mlacp_finalize(struct CSM* csm); +void mlacp_fsm_transit(struct CSM* csm); +void mlacp_enqueue_msg(struct CSM*, struct Msg*); +struct Msg* mlacp_dequeue_msg(struct CSM*); + +/* from app_csm*/ +extern int mlacp_bind_local_if(struct CSM* csm, struct LocalInterface* local_if); +extern int mlacp_unbind_local_if(struct LocalInterface* local_if); + +#endif /* _MLACP_HANDLER_H */ diff --git a/src/iccpd/include/mlacp_link_handler.h b/src/iccpd/include/mlacp_link_handler.h new file mode 100644 index 000000000000..55892d1861c8 --- /dev/null +++ b/src/iccpd/include/mlacp_link_handler.h @@ -0,0 +1,60 @@ +/* + * mlacp_link_handler.h + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef __MLACP_LINK_HANDLER__ +#define __MLACP_LINK_HANDLER__ + +#include "../include/iccp_csm.h" +#include "../include/mlacp_tlv.h" + +/***************************************** +* Link Handler +* +* ***************************************/ +void mlacp_portchannel_state_handler(struct CSM* csm, struct LocalInterface* local_if, int po_state); +void mlacp_peer_conn_handler(struct CSM* csm); +void mlacp_peer_disconn_handler(struct CSM* csm); +void mlacp_peerlink_up_handler(struct CSM* csm); +void mlacp_peerlink_down_handler(struct CSM* csm); +void update_stp_peer_link(struct CSM *csm, struct PeerInterface *peer_if, int po_state, int new_create); +void update_peerlink_isolate_from_pif(struct CSM *csm, struct PeerInterface *pif, int po_state, int new_create); +void mlacp_mlag_link_add_handler(struct CSM *csm, struct LocalInterface *lif); +void mlacp_mlag_link_del_handler(struct CSM *csm, struct LocalInterface *lif); +void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable); +void peerlink_port_isolate_cleanup(struct CSM* csm); +void update_peerlink_isolate_from_all_csm_lif(struct CSM* csm); + +int mlacp_fsm_arp_set(char *ifname, uint32_t ip, char *mac); +int mlacp_fsm_arp_del(char *ifname, uint32_t ip); +void del_mac_from_chip(struct MACMsg* mac_msg); +void add_mac_to_chip(struct MACMsg* mac_msg, uint8_t mac_type); +uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg* mac_msg, uint8_t set ); +void iccp_get_fdb_change_from_syncd( void); + +extern int mclagd_ctl_sock_create(); +extern int mclagd_ctl_sock_accept(int fd); +extern int mclagd_ctl_interactive_process(int client_fd); +char *show_ip_str(uint32_t ipv4_addr); + +void syncd_info_close(); +int iccp_connect_syncd(); +#endif diff --git a/src/iccpd/include/mlacp_sync_prepare.h b/src/iccpd/include/mlacp_sync_prepare.h new file mode 100644 index 000000000000..f4ea7a419f51 --- /dev/null +++ b/src/iccpd/include/mlacp_sync_prepare.h @@ -0,0 +1,55 @@ +/* + * mlacp_sync_prepare.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef __MLACP_SYNC_PREPARE__ +#define __MLACP_SYNC_PREPARE__ + +struct CSM; +/***************************************** +* Tool Function +* +* ***************************************/ +void update_system_id(struct CSM* csm); + +/***************************************** +* LACP Sync +* +* ***************************************/ +int mlacp_sync_with_kernel_callback(); + +/***************************************** +* MLACP Sync +* +* ***************************************/ +int mlacp_prepare_for_sync_request_tlv(struct CSM* csm, char* buf, size_t max_buf_size); +int mlacp_prepare_for_sync_data_tlv(struct CSM* csm, char* buf, size_t max_buf_size, int end); +int mlacp_prepare_for_sys_config(struct CSM* csm, char* buf, size_t max_buf_size); +int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_buf_size, struct MACMsg* mac_msg, int count); +int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, struct ARPMsg* arp_msg, int count); +int mlacp_prepare_for_heartbeat(struct CSM* csm, char* buf, size_t max_buf_size); +int mlacp_prepare_for_Aggport_state(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* local_if); +int mlacp_prepare_for_Aggport_config(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* lif, int purge_flag); +int mlacp_prepare_for_port_channel_info(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* port_channel); +int mlacp_prepare_for_port_peerlink_info(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* peerlink_port); +int iccp_netlink_if_hwaddr_set(uint32_t ifindex, uint8_t *addr, unsigned int addr_len); +#endif \ No newline at end of file diff --git a/src/iccpd/include/mlacp_sync_update.h b/src/iccpd/include/mlacp_sync_update.h new file mode 100644 index 000000000000..d42abe216af6 --- /dev/null +++ b/src/iccpd/include/mlacp_sync_update.h @@ -0,0 +1,49 @@ +/* + * + * mlacp_sync_update.h + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef __MLACP_SYNC_UPDATE__ +#define __MLACP_SYNC_UPDATE__ + +#include "iccp_csm.h" +#include "mlacp_tlv.h" + +/***************************************** +* FSM Sync Update API +* +* ***************************************/ +int mlacp_fsm_update_system_conf(struct CSM* csm, mLACPSysConfigTLV* tlv); + +int mlacp_fsm_update_Aggport_state(struct CSM* csm, mLACPAggPortStateTLV* tlv); + +int mlacp_fsm_update_arp_info(struct CSM* csm, struct mLACPARPInfoTLV* tlv); + +int mlacp_fsm_update_heartbeat(struct CSM* csm, struct mLACPHeartbeatTLV* tlv); + +int mlacp_fsm_update_warmboot(struct CSM* csm, struct mLACPWarmbootTLV* tlv); +void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg); + +int mlacp_fsm_update_Agg_conf(struct CSM* csm, mLACPAggConfigTLV* portconf); +int mlacp_fsm_update_port_channel_info(struct CSM* csm, struct mLACPPortChannelInfoTLV* tlv); +int mlacp_fsm_update_peerlink_info(struct CSM* csm, struct mLACPPeerLinkInfoTLV* tlv); +int mlacp_fsm_update_mac_info_from_peer(struct CSM* csm, struct mLACPMACInfoTLV* tlv); +#endif \ No newline at end of file diff --git a/src/iccpd/include/mlacp_tlv.h b/src/iccpd/include/mlacp_tlv.h new file mode 100644 index 000000000000..86bce2e0e943 --- /dev/null +++ b/src/iccpd/include/mlacp_tlv.h @@ -0,0 +1,456 @@ +/* + * mlacp_tlv.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef MLACP_TLV_H_ +#define MLACP_TLV_H_ + +#include + +#include "../include/msg_format.h" +#include "../include/port.h" + +#define MLACP_SYSCONF_NODEID_MSB_MASK 0x80 +#define MLACP_SYSCONF_NODEID_NODEID_MASK 0x70 +#define MLACP_SYSCONF_NODEID_FREE_MASK 0x0F + +/* + * RFC 7275 + * 7.2.3. mLACP System Config TLV + * [Page 51] + */ +struct mLACPSysConfigTLV +{ + ICCParameter icc_parameter; + /* [IEEE-802.1AX], Section 5.3.2. */ + uint8_t sys_id[ETHER_ADDR_LEN]; + /* [IEEE-802.1AX], Section 5.3.2. */ + uint16_t sys_priority; + /* + * RFC 7275 + * 7.2.3. mLACP System Config TLV + * [Page 51] + */ + uint8_t node_id; +} __attribute__ ((packed)); + +typedef struct mLACPSysConfigTLV mLACPSysConfigTLV; + +/* + * RFC 7275 + * 7.2.4. mLACP Aggregator Config TLV + * [Page 52] + * NOTE: In this project, Aggregator configuration and state TLV is not support. + */ +struct mLACPAggConfigTLV +{ + ICCParameter icc_parameter; + /* + * RFC 7275 + * 7.2.4. mLACP Aggregator Config TLV + * [Page 53] + */ + uint8_t ro_id[8]; + /* [IEEE-802.1AX], Section 5.4.6. */ + uint16_t agg_id; + /* + * RFC 7275 + * 7.2.4. mLACP Aggregator Config TLV + * [Page 53] + */ + uint8_t mac_addr[ETHER_ADDR_LEN]; + /* [IEEE-802.1AX], Section 5.3.5. */ + uint16_t actor_key; + /* + * RFC 7275 + * 7.2.4. mLACP Aggregator Config TLV + * [Page 53] + */ + uint16_t member_ports_priority; + uint8_t flags; + /* + * RFC 7275 + * 7.2.4. mLACP Aggregator Config TLV + * [Page 54] + */ + uint8_t agg_name_len; + char agg_name[MAX_L_PORT_NAME]; +} __attribute__ ((packed)); + +typedef struct mLACPAggConfigTLV mLACPAggConfigTLV; + +/* + * RFC 7275 + * 7.2.4. mLACP Port Config TLV + * [Page 54] + */ +struct mLACPPortConfigTLV +{ + ICCParameter icc_parameter; + /* [IEEE-802.1AX], Section 5.3.4. */ + uint16_t port_num; + /* + * RFC 7275 + * 7.2.5. mLACP Port Config TLV + * [Page 55] + */ + uint8_t mac_addr[ETHER_ADDR_LEN]; + /* [IEEE-802.1AX], Section 5.3.5. */ + uint16_t actor_key; + /* [IEEE-802.1AX], Section 5.3.4. */ + uint16_t port_priority; + /* IF-MIB [RFC2863] */ + uint32_t port_speed; + /* + * RFC 7275 + * 7.2.4. mLACP Port Config TLV + * [Page 55] + */ + uint8_t flags; + /* + * RFC 7275 + * 7.2.4. mLACP Port Config TLV + * [Page 56] + */ + uint8_t port_name_len; + /* IF-MIB [RFC2863] */ + char port_name[MAX_L_PORT_NAME]; + + /* NOS */ + uint8_t l3_mode; +} __attribute__ ((packed)); + +typedef struct mLACPPortConfigTLV mLACPPortConfigTLV; + +/* + * RFC 7275 + * 7.2.6. mLACP Port Priority TLV + * [Page 56] + */ +struct mLACPPortPriorityTLV +{ + ICCParameter icc_parameter; + /* + * RFC 7275 + * 7.2.6. mLACP Port Priority TLV + * [Page 57] + */ + uint16_t op_code; + /* [IEEE-802.1AX], Section 5.3.4. */ + uint16_t port_num; + /* [IEEE-802.1AX], Section 5.4.6. */ + uint16_t agg_id; + /* [IEEE-802.1AX], Section 5.3.4. */ + uint16_t last_port_priority; + uint16_t current_port_priority; +} __attribute__ ((packed)); + +typedef struct mLACPPortPriorityTLV mLACPPortPriorityTLV; + +/* + * RFC 7275 + * 7.2.7. mLACP Port State TLV + * [Page 58] + */ +struct mLACPPortStateTLV +{ + ICCParameter icc_parameter; + /* [IEEE-802.1AX], Section 5.4.2.2, item r. */ + uint8_t partner_sys_id[ETHER_ADDR_LEN]; + /* [IEEE-802.1AX], Section 5.4.2.2, item q. */ + uint16_t partner_sys_priority; + /* [IEEE-802.1AX], Section 5.4.2.2, item u. */ + uint16_t partner_port_num; + /* [IEEE-802.1AX], Section 5.4.2.2, item t. */ + uint16_t partner_port_priority; + /* [IEEE-802.1AX], Section 5.4.2.2, item s. */ + uint16_t partner_key; + /* [IEEE-802.1AX], Section 5.4.2.2, item v. */ + uint8_t partner_state; + /* [IEEE-802.1AX], Section 5.4.2.2, item m. */ + uint8_t actor_state; + /* [IEEE-802.1AX], Section 5.3.4. */ + uint16_t actor_port_num; + /* [IEEE-802.1AX], Section 5.3.5. */ + uint16_t actor_key; + /* [IEEE-802.1AX], Section 5.4.8 */ + uint8_t selected; + /* + * RFC 7275 + * 7.2.7. mLACP Port State TLV + * [Page 60] + */ + uint8_t port_state; + /* [IEEE-802.1AX], Section 5.4.6. */ + uint16_t agg_id; + + /* NOS */ + uint16_t port_id; + uint8_t l3_mode; + uint8_t is_peer_link; +} __attribute__ ((packed)); + +typedef struct mLACPPortStateTLV mLACPPortStateTLV; + +/* + * RFC 7275 + * 7.2.8. mLACP Aggregator State TLV + * [Page 60] + * NOTE: In this project, Aggregator configuration and state TLV is not support. + */ +struct mLACPAggPortStateTLV +{ + ICCParameter icc_parameter; + /* [IEEE-802.1AX], Section 5.4.2.2, item r. */ + uint8_t partner_sys_id[ETHER_ADDR_LEN]; + /* [IEEE-802.1AX], Section 5.4.2.2, item q. */ + uint16_t partner_sys_priority; + /* [IEEE-802.1AX], Section 5.4.2.2, item s. */ + uint16_t partner_key; + /* [IEEE-802.1AX], Section 5.4.6. */ + uint16_t agg_id; + /* [IEEE-802.1AX], Section 5.3.5. */ + uint16_t actor_key; + /* + * RFC 7275 + * 7.2.8. mLACP Aggregator State TLV + * [Page 61] + */ + uint8_t agg_state; +} __attribute__ ((packed)); + +typedef struct mLACPAggPortStateTLV mLACPAggPortStateTLV; + +/* + * RFC 7275 + * 7.2.9. mLACP Synchronization Request TLV + * [Page 61] + */ +struct mLACPSyncReqTLV +{ + ICCParameter icc_parameter; + /* + * RFC 7275 + * 7.2.9. mLACP Synchronization Request TLV + * [Page 62] + */ + uint16_t req_num; + +#if __BYTE_ORDER == __BIG_ENDIAN + uint16_t c_bit : 1; + /* + * RFC 7275 + * 7.2.9. mLACP Synchronization Request TLV + * [Page 63] + */ + uint16_t s_bit : 1; + uint16_t req_type : 14; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + uint16_t req_type : 14; + /* + * RFC 7275 + * 7.2.9. mLACP Synchronization Request TLV + * [Page 63] + */ + uint16_t s_bit : 1; + uint16_t c_bit : 1; +#endif + /* [IEEE-802.1AX], Section 5.3.4. */ + /* [IEEE-802.1AX], Section 5.4.6. */ + uint16_t port_num_agg_id; + /* [IEEE-802.1AX], Section 5.3.5. */ + uint16_t actor_key; +} __attribute__ ((packed)); + +typedef struct mLACPSyncReqTLV mLACPSyncReqTLV; + +/* + * RFC 7275 + * 7.2.10. mLACP Synchronization Data TLV + * [Page 63] + */ +struct mLACPSyncDataTLV +{ + ICCParameter icc_parameter; + /* + * RFC 7275 + * 7.2.10. mLACP Synchronization Data TLV + * [Page 64] + */ + uint16_t req_num; + uint16_t flags; +} __attribute__ ((packed)); + +typedef struct mLACPSyncDataTLV mLACPSyncDataTLV; + +/* VLAN Information TLV*/ +struct mLACPVLANData +{ + uint16_t vlan_id; +} __attribute__ ((packed)); + +/* + * Port Channel Information TLV + */ +struct mLACPPortChannelInfoTLV +{ + ICCParameter icc_parameter; + uint16_t agg_id; + char if_name[MAX_L_PORT_NAME]; + uint8_t if_name_len; + uint8_t l3_mode; + uint32_t ipv4_addr; + uint16_t po_id; + uint16_t num_of_vlan_id; + struct mLACPVLANData vlanData[0]; +} __attribute__ ((packed)); + +typedef struct mLACPPortChannelInfoTLV mLACPPortChannelInfoTLV; + +/* + * Port PeerLink Information TLV + */ +struct mLACPPeerLinkInfoTLV +{ + ICCParameter icc_parameter; + char if_name[MAX_L_PORT_NAME]; + uint8_t port_type; +} __attribute__ ((packed)); + +typedef struct mLACPPeerLinkInfoTLV mLACPPeerLinkInfoTLV; + +struct mLACPVLANInfoTLV +{ + ICCParameter icc_parameter; + uint16_t id; /* Local Interface ID, not VLAN ID */ + uint16_t num_of_vlan_id; + struct mLACPVLANData vlanData[0]; +} __attribute__ ((packed)); + +/* Mac entry Information TLV*/ +struct mLACPMACData +{ + uint8_t type;/*add or del*/ + char mac_str[ETHER_ADDR_STR_LEN]; + uint16_t vid; + /*Current if name that set in chip*/ + char ifname[MAX_L_PORT_NAME]; +} __attribute__ ((packed)); + +/* + * MAC Information TLV + */ +struct mLACPMACInfoTLV +{ + ICCParameter icc_parameter; + uint16_t num_of_entry; + struct mLACPMACData MacEntry[0]; +} __attribute__ ((packed)); + +struct ARPMsg +{ + uint8_t op_type; + char ifname[MAX_L_PORT_NAME]; + uint32_t ipv4_addr; + uint8_t mac_addr[ETHER_ADDR_LEN]; +}; + +/* + * ARP Information TLV + */ +struct mLACPARPInfoTLV +{ + ICCParameter icc_parameter; + /* Local Interface ID */ + uint16_t num_of_entry; + struct ARPMsg ArpEntry[0]; +} __attribute__ ((packed)); + +/* + * NOS: STP Information TLV + */ +struct stp_msg_s; +struct mLACPSTPInfoTLV +{ + ICCParameter icc_parameter; + uint8_t stp_msg[0]; +} __attribute__ ((packed)); + +/* + * NOS: Heartbeat + */ +struct mLACPHeartbeatTLV +{ + ICCParameter icc_parameter; + uint8_t heartbeat; +} __attribute__ ((packed)); + +/* + * NOS: Warm_reboot + */ +struct mLACPWarmbootTLV +{ + ICCParameter icc_parameter; + uint8_t warmboot; +} __attribute__ ((packed)); + +enum ARP_OP_TYPE +{ + ARP_SYNC_LIF, + ARP_SYNC_ADD, + ARP_SYNC_DEL, +}; + +enum MAC_AGE_TYPE +{ + MAC_AGE_LOCAL = 1, /*MAC in local switch is ageout*/ + MAC_AGE_PEER = 2, /*MAC in peer switch is ageout*/ +}; + +enum MAC_OP_TYPE +{ + MAC_SYNC_ADD = 1, + MAC_SYNC_DEL = 2, + MAC_SYNC_ACK = 4, +}; + +enum MAC_TYPE +{ + MAC_TYPE_STATIC = 1, + MAC_TYPE_DYNAMIC = 2, +}; + +struct MACMsg +{ + uint8_t op_type; /*add or del*/ + uint8_t fdb_type; /*static or dynamic*/ + char mac_str[ETHER_ADDR_STR_LEN]; + uint16_t vid; + /*Current if name that set in chip*/ + char ifname[MAX_L_PORT_NAME]; + /*if we set the mac to peer-link, origin_ifname store the + original if name that learned from chip*/ + char origin_ifname[MAX_L_PORT_NAME]; + uint8_t age_flag;/*local or peer is age?*/ +}; + +#endif /* MLACP_TLV_H_ */ diff --git a/src/iccpd/include/msg_format.h b/src/iccpd/include/msg_format.h new file mode 100644 index 000000000000..5f4deb18772b --- /dev/null +++ b/src/iccpd/include/msg_format.h @@ -0,0 +1,499 @@ +/* + * msg_format.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef MSG_FORMAT_H_ +#define MSG_FORMAT_H_ +#include +#include +#include "../include/port.h" + +#define MAX_MSG_LOG_SIZE 128 + +/* + * RFC 5561 + * 4. Capability Message + * [Page 7] + */ +#define MSG_T_CAPABILITY 0x0202 + +/* + * RFC 7275 + * 6.1.1. ICC Header - Message Length + * [Page 25] + * 2-octet integer specifying the total length of this message in octets, + * excluding the "U-bit", "Message Type", and "Length" fields. + */ +#define MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS 4 + +/* + * RFC 7275 + * 12.1. Message Type Name Space + * [Page 79] + */ +#define MSG_T_RG_CONNECT 0x0700 +#define MSG_T_RG_DISCONNECT 0x0701 +#define MSG_T_NOTIFICATION 0x0702 +#define MSG_T_RG_APP_DATA 0x0703 + +/* + * RFC 7275 + * 12.2. TLV Type Name Space + * [Page 79] + */ +#define TLV_T_ICCP_CAPABILITY 0x0700 +#define TLV_L_ICCP_CAPABILITY 0x4 + +/* + * RFC 7275 + * 12.3. ICC RG Parameter Type Space + * [Page 80] + */ +#define TLV_T_ICC_SENDER_NAME 0x0001 +#define MAX_L_ICC_SENDER_NAME 80 +#define TLV_T_NAK 0x0002 +#define TLV_T_REQUESTED_PROTOCOL_VER 0x0003 +#define TLV_T_DISCONNECT_CODE 0x0004 +#define TLV_L_DISCONNECT_CODE 0x4 +#define TLV_T_ICC_RG_ID 0x0005 +#define TLV_L_ICC_RG_ID 0x4 + +#define TLV_T_MLACP_CONNECT 0x0030 +#define TLV_T_MLACP_DISCONNECT 0x0031 +#define TLV_T_MLACP_SYSTEM_CONFIG 0x0032 +#define TLV_T_MLACP_PORT_CONFIG 0x0033 //no support +#define TLV_T_MLACP_PORT_PRIORITY 0x0034 //no support +#define TLV_T_MLACP_PORT_STATE 0x0035 //no support +#define TLV_T_MLACP_AGGREGATOR_CONFIG 0x0036 +#define TLV_T_MLACP_AGGREGATOR_STATE 0x0037 +#define TLV_T_MLACP_SYNC_REQUEST 0x0038 +#define TLV_T_MLACP_SYNC_DATA 0x0039 +#define TLV_T_MLACP_HEARTBEAT 0x003A +#define TLV_T_MLACP_DISCONNECT_CAUSE 0x003B //not yet + +/* Self define Feature */ +#define TLV_T_MLACP_ORPHAN_PORT 0x1033 //not yet +#define TLV_T_MLACP_PORT_CHANNEL_INFO 0x1034 +#define TLV_T_MLACP_PEERLINK_INFO 0x1035 +#define TLV_T_MLACP_ARP_INFO 0x1036 +#define TLV_T_MLACP_STP_INFO 0x1037//no support +#define TLV_T_MLACP_MAC_INFO 0x1038 +#define TLV_T_MLACP_WARMBOOT_FLAG 0x1039 +#define TLV_T_MLACP_LIST_END 0x104a //list end + +/* Debug */ +static char* get_tlv_type_string(int type) +{ + switch (type) + { + case TLV_T_ICCP_CAPABILITY: + return "TLV_T_ICCP_CAPABILITY"; + + case TLV_T_ICC_SENDER_NAME: + return "TLV_T_ICC_SENDER_NAME"; + + case TLV_T_NAK: + return "TLV_T_NAK"; + + case TLV_T_REQUESTED_PROTOCOL_VER: + return "TLV_T_REQUESTED_PROTOCOL_VER"; + + case TLV_T_DISCONNECT_CODE: + return "TLV_T_DISCONNECT_CODE"; + + case TLV_T_ICC_RG_ID: + return "TLV_T_ICC_RG_ID"; + + case TLV_T_MLACP_CONNECT: + return "TLV_T_MLACP_CONNECT"; + + case TLV_T_MLACP_DISCONNECT: + return "TLV_T_MLACP_DISCONNECT"; + + case TLV_T_MLACP_SYSTEM_CONFIG: + return "TLV_T_MLACP_SYSTEM_CONFIG"; + + case TLV_T_MLACP_PORT_CONFIG: + return "TLV_T_MLACP_PORT_CONFIG"; + + case TLV_T_MLACP_PORT_PRIORITY: + return "TLV_T_MLACP_PORT_PRIORITY"; + + case TLV_T_MLACP_PORT_STATE: + return "TLV_T_MLACP_PORT_STATE"; + + case TLV_T_MLACP_AGGREGATOR_CONFIG: + return "TLV_T_MLACP_AGGREGATOR_CONFIG"; + + case TLV_T_MLACP_AGGREGATOR_STATE: + return "TLV_T_MLACP_AGGREGATOR_STATE"; + + case TLV_T_MLACP_SYNC_REQUEST: + return "TLV_T_MLACP_SYNC_REQUEST"; + + case TLV_T_MLACP_SYNC_DATA: + return "TLV_T_MLACP_SYNC_DATA"; + + case TLV_T_MLACP_HEARTBEAT: + return "TLV_T_MLACP_HEARTBEAT"; + + case TLV_T_MLACP_DISCONNECT_CAUSE: + return "TLV_T_MLACP_DISCONNECT_CAUSE"; + + /* NOS Feature */ + case TLV_T_MLACP_ORPHAN_PORT: + return "TLV_T_MLACP_ORPHAN_PORT"; + + case TLV_T_MLACP_PORT_CHANNEL_INFO: + return "TLV_T_MLACP_PORT_CHANNEL_INFO"; + + case TLV_T_MLACP_PEERLINK_INFO: + return "TLV_T_MLACP_PEERLINK_INFO"; + + case TLV_T_MLACP_ARP_INFO: + return "TLV_T_MLACP_ARP_INFO"; + + case TLV_T_MLACP_MAC_INFO: + return "TLV_T_MLACP_MAC_INFO"; + + case TLV_T_MLACP_STP_INFO: + return "TLV_T_MLACP_STP_INFO"; + } + + return "UNKNOWN"; +} + +/* + * RFC 7275 + * 12.4. Status Code Name Space + * [Page 81] + */ +#define STATUS_CODE_U_ICCP_RG 0x00010001 +#define STATUS_CODE_ICCP_CONNECTION_COUNT_EXCEEDED 0x00010002 +#define STATUS_CODE_ICCP_APP_CONNECTION_COUNT_EXCEEDED 0x00010003 +#define STATUS_CODE_ICCP_APP_NOT_IN_RG 0x00010004 +#define STATUS_CODE_INCOMPATIBLE_ICCP_PROTOCOL_VER 0x00010005 +#define STATUS_CODE_ICCP_REJECTED_MSG 0x00010006 +#define STATUS_CODE_ICCP_ADMINISTRATIVELY_DISABLED 0x00010007 +#define STATUS_CODE_ICCP_RG_REMOVED 0x00010010 +#define STATUS_CODE_ICCP_APP_REMOVED_FROM_RG 0x00010011 + + +/* Debug */ +static char* get_status_string(int status) +{ + switch (status) + { + case STATUS_CODE_U_ICCP_RG: + return "Unknown ICCP RG"; + + case STATUS_CODE_ICCP_CONNECTION_COUNT_EXCEEDED: + return "ICCP Connection Count Exceeded"; + + case STATUS_CODE_ICCP_APP_CONNECTION_COUNT_EXCEEDED: + return "ICCP Application Connection Count Exceede"; + + case STATUS_CODE_ICCP_APP_NOT_IN_RG: + return "ICCP Application not in RG"; + + case STATUS_CODE_INCOMPATIBLE_ICCP_PROTOCOL_VER: + return "Incompatible ICCP Protocol Version"; + + case STATUS_CODE_ICCP_REJECTED_MSG: + return "ICCP Rejected Message"; + + case STATUS_CODE_ICCP_ADMINISTRATIVELY_DISABLED: + return "ICCP Administratively Disabled"; + + case STATUS_CODE_ICCP_RG_REMOVED: + return "ICCP RG Removed"; + + case STATUS_CODE_ICCP_APP_REMOVED_FROM_RG: + return "ICCP Application Removed from RG"; + } + + return "UNKNOWN"; +} +/* + * RFC 5036 + * 3.5. LDP Messages + * [Page 44] + */ +struct LDPHdr +{ +#if __BYTE_ORDER == __BIG_ENDIAN + uint16_t u_bit : 1; + uint16_t msg_type : 15; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + uint16_t msg_type : 15; + uint16_t u_bit : 1; +#endif + uint16_t msg_len; + uint32_t msg_id; +} __attribute__ ((packed)); + +typedef struct LDPHdr LDPHdr; + +/* + * RFC 7275 + * 6.1.1. ICC Header + * [Page 24] + */ +struct ICCRGIDTLV +{ + uint16_t type; + uint16_t len; + uint32_t icc_rg_id; +} __attribute__ ((packed)); + +typedef struct ICCRGIDTLV ICCRGIDTLV; + +struct ICCHdr +{ + LDPHdr ldp_hdr; + ICCRGIDTLV icc_rg_id_tlv; +} __attribute__ ((packed)); + +typedef struct ICCHdr ICCHdr; + +/* + * RFC 7275 + * 6.1.2. ICC Parameter Encoding + * [Page 26] + */ +struct ICCParameter +{ +#if __BYTE_ORDER == __BIG_ENDIAN + uint16_t u_bit : 1; + uint16_t f_bit : 1; + uint16_t type : 14; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + uint16_t type : 14; + uint16_t f_bit : 1; + uint16_t u_bit : 1; +#endif + uint16_t len; +} __attribute__ ((packed)); + +typedef struct ICCParameter ICCParameter; + +/* + * RFC 7275 + * 6.2.1. ICC Sender Name TLV + * [Page 28] + */ +struct ICCSenderNameTLV +{ + ICCParameter icc_parameter; + char sender_name[MAX_L_ICC_SENDER_NAME]; +} __attribute__ ((packed)); + +typedef struct ICCSenderNameTLV ICCSenderNameTLV; + +/* + * RFC 7275 + * 6.3. RG Disconnect Message + * [Page 29] + */ +struct DisconnectCodeTLV +{ + ICCParameter icc_parameter; + uint32_t iccp_status_code; +} __attribute__ ((packed)); + +typedef struct DisconnectCodeTLV DisconnectCodeTLV; + +/* + * RFC 7275 + * 6.4.1. Notification Message TLVs + * [Page 32] + */ +struct NAKTLV +{ + ICCParameter icc_parameter; + uint32_t iccp_status_code; + uint32_t rejected_msg_id; +} __attribute__ ((packed)); + +typedef struct NAKTLV NAKTLV; + +/* + * RFC 7275 + * 6.4.1. Notification Message TLVs + * [Page 34] + */ +struct RequestedProtocolVerTLV +{ + ICCParameter icc_parameter; + uint16_t connection_ref; + uint16_t requested_ver; +} __attribute__ ((packed)); + +typedef struct RequestedProtocolVerTLV RequestedProtocolVerTLV; + +/* + * RFC 7275 + * 8. LDP Capability Negotiation + * [Page 65] + */ +struct LDPICCPCapabilityTLV +{ + ICCParameter icc_parameter; +#if __BYTE_ORDER == __BIG_ENDIAN + uint16_t s_bit : 1; + uint16_t reserved : 15; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + uint16_t reserved : 15; + uint16_t s_bit : 1; +#endif + uint8_t major_ver; + uint8_t minior_ver; +} __attribute__ ((packed)); + +typedef struct LDPICCPCapabilityTLV LDPICCPCapabilityTLV; + +/* + * RFC 7275 + * 7.2.1. mLACP Connect TLV + * [Page 47] + */ +struct AppConnectTLV +{ + ICCParameter icc_parameter; + uint16_t protocol_version; +#if __BYTE_ORDER == __BIG_ENDIAN + uint16_t a_bit : 1; + uint16_t reserved : 15; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + uint16_t reserved : 15; + uint16_t a_bit : 1; +#endif + + /* Optional Sub-TLVs */ + /* No optional sub-TLVs in this version */ +} __attribute__ ((packed)); + +typedef struct AppConnectTLV AppConnectTLV; + +/* + * RFC 7275 + * 7.2.2. mLACP Disconnect TLV + * [Page 48] + */ +struct AppDisconnectTLV +{ + ICCParameter icc_parameter; + + /* Optional Sub-TLVs */ + /* mLACP Disconnect Cause TLV */ +} __attribute__ ((packed)); + +typedef struct AppDisconnectTLV AppDisconnectTLV; + +/* + * RFC 7275 + * 7.2.2.1. mLACP Disconnect Cause TLV + * [Page 49] + */ +struct AppDisconnectCauseTLV +{ + ICCParameter iccp_parameter; + + /* Disconnect Cause String */ + char cause_string[0]; /* Trick */ +} __attribute__ ((packed)); + +/*syncd send msg type to iccpd*/ +typedef enum mclag_syncd_msg_type_e_ +{ + MCLAG_SYNCD_MSG_TYPE_NONE = 0, + MCLAG_SYNCD_MSG_TYPE_FDB_OPERATION = 1 +}mclag_syncd_msg_type_e; + +typedef enum mclag_msg_type_e_ +{ + MCLAG_MSG_TYPE_NONE = 0, + MCLAG_MSG_TYPE_PORT_ISOLATE = 1, + MCLAG_MSG_TYPE_PORT_MAC_LEARN_MODE = 2, + MCLAG_MSG_TYPE_FLUSH_FDB = 3, + MCLAG_MSG_TYPE_SET_MAC = 4, + MCLAG_MSG_TYPE_SET_FDB = 5, + MCLAG_MSG_TYPE_GET_FDB_CHANGES = 20 +}mclag_msg_type_e; + + +typedef enum mclag_sub_option_type_e_ +{ + MCLAG_SUB_OPTION_TYPE_NONE = 0, + MCLAG_SUB_OPTION_TYPE_ISOLATE_SRC = 1, + MCLAG_SUB_OPTION_TYPE_ISOLATE_DST = 2, + MCLAG_SUB_OPTION_TYPE_MAC_LEARN_ENABLE = 3, + MCLAG_SUB_OPTION_TYPE_MAC_LEARN_DISABLE = 4, + MCLAG_SUB_OPTION_TYPE_SET_MAC_SRC = 5, + MCLAG_SUB_OPTION_TYPE_SET_MAC_DST = 6 +} mclag_sub_option_type_e; + + +struct IccpSyncdHDr +{ + uint8_t ver; + uint8_t type; + uint16_t len; +}; + +typedef struct mclag_sub_option_hdr_t_ +{ + + uint8_t op_type; + + /* + * Length of option value, not including the header. + */ + uint16_t op_len; + uint8_t data[]; +}mclag_sub_option_hdr_t; + +struct mclag_fdb_info +{ + char mac[ETHER_ADDR_STR_LEN]; + unsigned int vid; + char port_name[MAX_L_PORT_NAME]; + short type; /*dynamic or static*/ + short op_type; /*add or del*/ +}; + +/* For storing message log: For Notification TLV */ +struct MsgTypeSet +{ + uint32_t msg_id; + uint16_t type; + uint16_t tlv; + +}; + +struct MsgLog +{ + struct MsgTypeSet msg[MAX_MSG_LOG_SIZE]; + uint32_t end_index; +}; + +#endif /* MSG_FORMAT_H_ */ diff --git a/src/iccpd/include/port.h b/src/iccpd/include/port.h new file mode 100644 index 000000000000..bdcaf66a68ad --- /dev/null +++ b/src/iccpd/include/port.h @@ -0,0 +1,156 @@ +/* + * port.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef PORT_H_ +#define PORT_H_ + +#include +#include +#include + +#define ETHER_ADDR_LEN 6 +#define ETHER_ADDR_STR_LEN 18 +/* + * RFC 7275 + * 7.2.4. mLACP Port Config TLV + * [Page 56] + */ +#define MAX_L_PORT_NAME 20 + +/* defined in RFC 7275 - 7.2.7 (p.59) */ +#define PORT_STATE_UP 0x00 +#define PORT_STATE_DOWN 0x01 +#define PORT_STATE_ADMIN_DOWN 0x02 +#define PORT_STATE_TEST 0x03 + +/* Interface Type */ +#define IF_T_UNKNOW -1 +#define IF_T_PORT 0 +#define IF_T_PORT_CHANNEL 1 +#define IF_T_VLAN 2 +#define IF_T_VXLAN 3 +#define IF_T_BRIDGE 4 +typedef struct +{ + char *ifname; + int type; +} itf_type_t; + +struct If_info +{ + char name[MAX_L_PORT_NAME]; + LIST_ENTRY(If_info) csm_next; +}; + +struct VLAN_ID +{ + uint16_t vid; + uint16_t vlan_removed; + struct LocalInterface* vlan_itf; /* loacl vlan interface */ + LIST_ENTRY(VLAN_ID) port_next; +}; + +struct PeerInterface +{ + int ifindex; + int type; + char name[MAX_L_PORT_NAME]; + + uint8_t mac_addr[ETHER_ADDR_LEN]; + uint8_t state; + uint32_t ipv4_addr; + + uint8_t l3_mode; + uint8_t is_peer_link; + int po_id; + uint8_t po_active; + + struct CSM* csm; + + LIST_ENTRY(PeerInterface) mlacp_next; + LIST_HEAD(peer_vlan_list, VLAN_ID) vlan_list; +}; + +struct LocalInterface +{ + int ifindex; + int type; + char name[MAX_L_PORT_NAME]; + + uint8_t mac_addr[ETHER_ADDR_LEN]; + uint8_t mac_addr_ori[ETHER_ADDR_LEN]; + uint8_t state; + uint32_t ipv4_addr; + uint8_t prefixlen; + + uint8_t l3_mode; + uint8_t l3_mac_addr[ETHER_ADDR_LEN]; + uint8_t is_peer_link; + char portchannel_member_buf[512]; + uint8_t is_arp_accept; + int po_id; /* Port Channel ID */ + uint8_t po_active; /* Port Channel is in active status? */ + int mlacp_state; /* Record mlacp state */ + uint8_t isolate_to_peer_link; + + struct CSM* csm; + + uint8_t changed; + uint8_t port_config_sync; + + LIST_HEAD(local_vlan_list, VLAN_ID) vlan_list; + + LIST_ENTRY(LocalInterface) system_next; + LIST_ENTRY(LocalInterface) system_purge_next; + LIST_ENTRY(LocalInterface) mlacp_next; + LIST_ENTRY(LocalInterface) mlacp_purge_next; +}; + +struct LocalInterface* local_if_create(int ifindex, char* ifname, int type); +struct LocalInterface* local_if_find_by_name(const char* ifname); +struct LocalInterface* local_if_find_by_ifindex(int ifindex); +struct LocalInterface* local_if_find_by_po_id(int po_id); + +void local_if_destroy(char *ifname); +void local_if_change_flag_clear(void); +void local_if_purge_clear(void); +int local_if_is_l3_mode(struct LocalInterface* local_if); + +void local_if_init(struct LocalInterface*); +void local_if_finalize(struct LocalInterface*); + +struct PeerInterface* peer_if_create(struct CSM* csm, int peer_if_number, int type); +struct PeerInterface* peer_if_find_by_name(struct CSM* csm, char* name); + +void peer_if_destroy(struct PeerInterface* pif); +int peer_if_add_vlan(struct PeerInterface* peer_if, uint16_t vlan_id); +int peer_if_clean_unused_vlan(struct PeerInterface* peer_if); +/* VLAN manipulation */ +int local_if_add_vlan(struct LocalInterface* local_if, uint16_t vid); +void local_if_del_vlan(struct LocalInterface* local_if, uint16_t vid); +void local_if_del_all_vlan(struct LocalInterface* lif); + +/* ARP manipulation */ +int set_sys_arp_accept_flag(char* ifname, int flag); + +#endif /* PORT_H_ */ diff --git a/src/iccpd/include/scheduler.h b/src/iccpd/include/scheduler.h new file mode 100644 index 000000000000..b3be274282c8 --- /dev/null +++ b/src/iccpd/include/scheduler.h @@ -0,0 +1,59 @@ +/* + * scheduler.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef SCHEDULER_H_ +#define SCHEDULER_H_ + +#include + +#include +#include +#include + +#include +#include +#include + +struct CSM; + +#define CONNECT_INTERVAL_SEC 1 +#define CONNECT_TIMEOUT_MSEC 100 +#define HEARTBEAT_TIMEOUT_SEC 15 +#define TRANSIT_INTERVAL_SEC 1 +#define EPOLL_TIMEOUT_MSEC 100 + +int scheduler_prepare_session(struct CSM*); +int scheduler_check_csm_config(struct CSM*); +int scheduler_unregister_sock_read_event_callback(struct CSM*); +void scheduler_session_disconnect_handler(struct CSM*); +void scheduler_init(); +void scheduler_finalize(); +void scheduler_loop(); +void scheduler_start(); +void scheduler_server_sock_init(); +int scheduler_csm_read_callback(struct CSM* csm); +int iccp_get_server_sock_fd(); +int scheduler_server_accept(); +int iccp_receive_signal_handler(struct System* sys); + +#endif /* SCHEDULER_H_ */ diff --git a/src/iccpd/include/system.h b/src/iccpd/include/system.h new file mode 100644 index 000000000000..bb89dbb2f3c2 --- /dev/null +++ b/src/iccpd/include/system.h @@ -0,0 +1,102 @@ +/* + * system.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef SYSTEM_H_ +#define SYSTEM_H_ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "../include/port.h" + +#define FRONT_PANEL_PORT_PREFIX "Ethernet" +#define PORTCHANNEL_PREFIX "PortChannel" +#define VLAN_PREFIX "Vlan" +#define VXLAN_TUNNEL_PREFIX "VTTNL" + +#define WARM_REBOOT 1 + +#define MCLAG_ERROR -1 + +struct CSM; + +#ifndef MAX_BUFSIZE + #define MAX_BUFSIZE 4096 +#endif + +struct System +{ + int server_fd;/* Peer-Link Socket*/ + int sync_fd; + int sync_ctrl_fd; + int arp_receive_fd; + int epoll_fd; + + struct nl_sock * genric_sock; + int genric_sock_seq; + int family; + struct nl_sock * route_sock; + int route_sock_seq; + struct nl_sock * genric_event_sock; + struct nl_sock * route_event_sock; + + int sig_pipe_r; + int sig_pipe_w; + int warmboot_start; + int warmboot_exit; + + /* Info List*/ + LIST_HEAD(csm_list, CSM) csm_list; + LIST_HEAD(lif_all_list, LocalInterface) lif_list; + LIST_HEAD(lif_purge_all_list, LocalInterface) lif_purge_list; + + /* Settings */ + char* log_file_path; + char* cmd_file_path; + char* config_file_path; + char* mclagdctl_file_path; + int pid_file_fd; + int telnet_port; + fd_set readfd; /*record socket need to listen*/ + int readfd_count; + time_t csm_trans_time; + int need_sync_team_again; + int need_sync_netlink_again; +}; + +struct CSM* system_create_csm(); +struct CSM* system_get_csm_by_peer_ip(const char*); +struct CSM* system_get_csm_by_mlacp_id(int id); +struct System* system_get_instance(); +void system_finalize(); +void system_init(struct System*); + +#endif /* SYSTEM_H_ */ diff --git a/src/iccpd/src/Makefile b/src/iccpd/src/Makefile new file mode 100644 index 000000000000..5e8cebc703c0 --- /dev/null +++ b/src/iccpd/src/Makefile @@ -0,0 +1,55 @@ +LIBNL_CFLAGS = -I/usr/include/libnl3 +LIBNL_LIBS = -lnl-cli-3 -lnl-genl-3 -lnl-nf-3 -lnl-route-3 -lnl-3 + +CC = gcc +SOURCES = app_csm.c cmd_option.c iccp_cli.c iccp_cmd_show.c iccp_cmd.c \ +iccp_csm.c iccp_ifm.c iccp_main.c logger.c \ +port.c scheduler.c system.c iccp_consistency_check.c \ +mlacp_link_handler.c \ +mlacp_sync_prepare.c mlacp_sync_update.c\ +mlacp_fsm.c \ +iccp_netlink.c + +OBJECTS = app_csm.o cmd_option.o iccp_cli.o iccp_cmd_show.o iccp_cmd.o \ +iccp_csm.o iccp_ifm.o iccp_main.o logger.o \ +port.o scheduler.o system.o iccp_consistency_check.o\ +mlacp_link_handler.o \ +mlacp_sync_prepare.o mlacp_sync_update.o \ +mlacp_fsm.o \ +iccp_netlink.o + +HEADERS = ../include/app_csm.h ../include/cmd_option.h ../include/iccp_cli.h \ +../include/iccp_cmd_show.h \ +../include/iccp_csm.h ../include/iccp_ifm.h \ +../include/logger.h ../include/mlacp_fsm.h \ +../include/mlacp_tlv.h ../include/msg_format.h ../include/port.h \ +../include/scheduler.h ../include/system.h \ +../include/iccp_consistency_check.h ../include/route_info.h \ +../include/iccp_netlink.h + +//CFLAGS = -g -O2 -fstack-protector-strong -Wformat -Werror=format-security $(LIBNL_CFLAGS) -I../include/ +CFLAGS = -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -I../include/ $(LIBNL_CFLAGS) +LDFLAGS = $(LIBNL_LIBS) -lpthread +LDADD = $(LIBZEBRA_BIN) + +all: iccpd + +%.o: %.c $(HEADERS) + +iccpd: $(OBJECTS) + $(CC) -o ../iccpd $(OBJECTS) $(LDFLAGS) + +DEPS = $(patsubst %.o, %.d, $(OBJECTS)) + +-include $(DEPS) +%.d:%.c + @set -e; rm -f $@; \ + gcc -MM $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + + + +.PHONY: clean +clean: + -rm -f $(OBJECTS) $(DEPS) ../iccpd diff --git a/src/iccpd/src/app_csm.c b/src/iccpd/src/app_csm.c new file mode 100644 index 000000000000..589cf94015d8 --- /dev/null +++ b/src/iccpd/src/app_csm.c @@ -0,0 +1,316 @@ +/* + * app_csm.c + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include + +#include "../include/iccp_csm.h" +#include "../include/logger.h" +#include "../include/scheduler.h" +#include "../include/system.h" +#include "../include/iccp_netlink.h" +#include "../include/mlacp_link_handler.h" +/***************************************** +* Define +* +* ***************************************/ +#define APP_CSM_QUEUE_REINIT(list) \ + { \ + struct Msg* msg = NULL; \ + while (!TAILQ_EMPTY(&(list))) { \ + msg = TAILQ_FIRST(&(list)); \ + TAILQ_REMOVE(&(list), msg, tail); \ + free(msg->buf); \ + free(msg); \ + } \ + TAILQ_INIT(&(list)); \ + } + +/* Application State Machine instance initialization */ +void app_csm_init(struct CSM* csm, int all) +{ + if (csm == NULL ) + return; + + APP_CSM_QUEUE_REINIT(csm->app_csm.app_msg_list); + + if (all) + { + bzero(&(csm->app_csm), sizeof(struct AppCSM)); + APP_CSM_QUEUE_REINIT(csm->app_csm.app_msg_list); + } + + csm->app_csm.current_state = APP_NONEXISTENT; + csm->app_csm.rx_connect_msg_id = 0; + csm->app_csm.tx_connect_msg_id = 0; + csm->app_csm.invalid_msg_id = 0; + csm->app_csm.invalid_msg = 0; + csm->app_csm.nak_msg = 0; + + mlacp_init(csm, all); +} + +/* Application State Machine instance tear down */ +void app_csm_finalize(struct CSM* csm) +{ + mlacp_finalize(csm); +} + +/* Application State Machine Transition */ +void app_csm_transit(struct CSM* csm) +{ + if (csm == NULL ) + return; + + /* torn down event */ + if (csm->app_csm.current_state != APP_NONEXISTENT && csm->sock_fd <= 0) + { + csm->app_csm.current_state = APP_NONEXISTENT; + return; + } + + if (csm->app_csm.current_state != APP_OPERATIONAL && csm->current_state == ICCP_OPERATIONAL) + { + csm->app_csm.current_state = APP_OPERATIONAL; + } + + return; +} + +/* Add received message into application message list */ +void app_csm_enqueue_msg(struct CSM* csm, struct Msg* msg) +{ + ICCHdr* icc_hdr = NULL; + ICCParameter* param = NULL; + NAKTLV* naktlv = NULL; + int tlv = -1; + int i = 0; + + if (csm == NULL ) + { + if (msg != NULL ) + free(msg); + return; + } + if (msg == NULL ) + return; + + icc_hdr = (ICCHdr*)msg->buf; + param = (ICCParameter*)&msg->buf[sizeof(struct ICCHdr)]; + *(uint16_t *)param = ntohs(*(uint16_t *)param); + + if ( icc_hdr->ldp_hdr.msg_type == MSG_T_RG_APP_DATA) + { + if (param->type > TLV_T_MLACP_CONNECT && param->type < TLV_T_MLACP_LIST_END) + mlacp_enqueue_msg(csm, msg); + else + TAILQ_INSERT_TAIL(&(csm->app_csm.app_msg_list), msg, tail); + } + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_NOTIFICATION) + { + naktlv = (NAKTLV*)&msg->buf[sizeof(ICCHdr)]; + + for (i = 0; i < MAX_MSG_LOG_SIZE; ++i) + { + if (ntohl(naktlv->rejected_msg_id) == csm->msg_log.msg[i].msg_id) + { + tlv = csm->msg_log.msg[i].tlv; + break; + } + } + + if (tlv > TLV_T_MLACP_CONNECT && tlv <= TLV_T_MLACP_MAC_INFO) + mlacp_enqueue_msg(csm, msg); + else + TAILQ_INSERT_TAIL(&(csm->app_csm.app_msg_list), msg, tail); + } + else + { + /* This packet is not for me, ignore it. */ + ICCPD_LOG_DEBUG(__FUNCTION__, "Ignore the packet with msg_type = %d", icc_hdr->ldp_hdr.msg_type); + } +} + +/* Get received message from message list */ +struct Msg* app_csm_dequeue_msg(struct CSM* csm) +{ + struct Msg* msg = NULL; + + if (!TAILQ_EMPTY(&(csm->app_csm.app_msg_list))) + { + msg = TAILQ_FIRST(&(csm->app_csm.app_msg_list)); + TAILQ_REMOVE(&(csm->app_csm.app_msg_list), msg, tail); + } + + return msg; +} + +/* APP NAK message handle function */ +int app_csm_prepare_nak_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + ICCHdr* icc_hdr = (ICCHdr*)buf; + NAKTLV* naktlv = (NAKTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(NAKTLV); + + ICCPD_LOG_DEBUG(__FUNCTION__, " Response NAK"); + memset(buf, 0, max_buf_size); + icc_hdr->ldp_hdr.u_bit = 0x0; + icc_hdr->ldp_hdr.msg_type = htons(MSG_T_NOTIFICATION); + icc_hdr->ldp_hdr.msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + icc_hdr->ldp_hdr.msg_id = htonl(ICCP_MSG_ID++); + iccp_csm_fill_icc_rg_id_tlv(csm, icc_hdr); + naktlv->icc_parameter.u_bit = 0; + naktlv->icc_parameter.f_bit = 0; + naktlv->icc_parameter.type = htons(TLV_T_NAK); + naktlv->icc_parameter.len = htons(sizeof(NAKTLV) - 4); + + naktlv->iccp_status_code = htonl(STATUS_CODE_ICCP_REJECTED_MSG); + naktlv->rejected_msg_id = htonl(csm->app_csm.invalid_msg_id); + + return msg_len; +} + +int mlacp_bind_local_if(struct CSM* csm, struct LocalInterface* lif) +{ + struct LocalInterface* lifp = NULL; + struct LocalInterface* lif_po = NULL; + + if (csm == NULL || lif == NULL) + return MCLAG_ERROR; + + if (lif->csm == csm) + return 0; + + /* remove purge from the csm*/ + do { + LIST_FOREACH(lifp, &(MLACP(csm).lif_purge_list), mlacp_purge_next) + { + if (lifp == lif) + break; + } + if (lifp) + LIST_REMOVE(lifp, mlacp_purge_next); + } while (lifp); + + /* already join csm?*/ + LIST_FOREACH(lifp, &(MLACP(csm).lif_list), mlacp_next) + { + if (lifp == lif) + return 0; + } + + /* join another csm beofre? remove from csm*/ + if (lif->csm != NULL) + mlacp_unbind_local_if(lif); + + /* join new csm*/ + LIST_INSERT_HEAD(&(MLACP(csm).lif_list), lif, mlacp_next); + lif->csm = csm; + if (lif->type == IF_T_PORT_CHANNEL) + lif->port_config_sync = 1; + + ICCPD_LOG_INFO(__FUNCTION__, "%s: MLACP bind on csm %p", lif->name, csm); + if (lif->type == IF_T_PORT_CHANNEL) + return 0; + + /* if join a po member, needs to check po joined also*/ + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type == IF_T_PORT_CHANNEL && lif_po->po_id == lif->po_id) + { + /*if join a po member, may swss restart, reset portchannel ip mac to mclagsyncd*/ + update_if_ipmac_on_standby(lif_po); + return 0; + } + } + + if (lif_po == NULL) + { + lif_po = local_if_find_by_po_id(lif->po_id); + if (lif_po == NULL) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to find port_channel instance for %d.", lif->po_id); + return MCLAG_ERROR; + } + + lif_po->csm = csm; + LIST_INSERT_HEAD(&(MLACP(csm).lif_list), lif_po, mlacp_next); + lif_po->port_config_sync = 1; + ICCPD_LOG_INFO(__FUNCTION__, "Add port_channel %d into local_if_list in CSM %p.", lif->po_id, csm); + } + + return 0; +} + +int mlacp_unbind_local_if(struct LocalInterface* lif) +{ + if (lif == NULL ) + return MCLAG_ERROR; + + if (lif->csm == NULL ) + return 0; + + ICCPD_LOG_INFO(__FUNCTION__, "%s: MLACP un-bind from csm %p", lif->name, lif->csm); + LIST_REMOVE(lif, mlacp_next); + + if (MLACP(lif->csm).current_state == MLACP_STATE_EXCHANGE && lif->type == IF_T_PORT_CHANNEL) + LIST_INSERT_HEAD(&(MLACP(lif->csm).lif_purge_list), lif, mlacp_purge_next); + if (lif->type == IF_T_PORT) + lif->po_id = -1; + lif->csm = NULL; + + return 0; +} + +int mlacp_bind_port_channel_to_csm(struct CSM* csm, const char *ifname) +{ + struct System* sys = NULL; + struct LocalInterface *lif_po = NULL; + + sys = system_get_instance(); + if (sys == NULL) + return 0; + + if (csm == NULL) + return 0; + + /* bind po first*/ + lif_po = local_if_find_by_name(ifname); + if (lif_po) + { + mlacp_bind_local_if(csm, lif_po); + iccp_get_port_member_list(lif_po); + } + else + { + ICCPD_LOG_WARN(__FUNCTION__, "%s: Failed to find a port instance .", ifname); + return 0; + } + /* process link state handler after attaching it.*/ + + mlacp_mlag_link_add_handler(csm, lif_po); + + /*ICCPD_LOG_WARN(tag, "po%d active = %d\n", po_id, po_is_active);*/ + return 0; +} + diff --git a/src/iccpd/src/cmd_option.c b/src/iccpd/src/cmd_option.c new file mode 100644 index 000000000000..596dafb73711 --- /dev/null +++ b/src/iccpd/src/cmd_option.c @@ -0,0 +1,266 @@ +/* + * cmd_option.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include "../include/cmd_option.h" + +struct CmdOption* cmd_option_find(struct CmdOptionParser* parser, char* opt_name) +{ + struct CmdOption* opt = NULL; + + if (opt_name == NULL) + return NULL; + + LIST_FOREACH(opt, &(parser->option_list), next) + { + if (strcmp(opt->option, opt_name) == 0) + return opt; + } + + return NULL; +} + +void cmd_option_delete(struct CmdOption* opt) +{ + if (opt == NULL) + return; + + LIST_REMOVE(opt, next); + if (opt->option != NULL) + free(opt->option); + if (opt->parameter != NULL) + free(opt->parameter); + if (opt->desc != NULL) + free(opt->desc); + free(opt); +} + +struct CmdOption* cmd_option_add(struct CmdOptionParser* parser, char* opt_name) +{ + struct CmdOption* opt = NULL; + + if (opt_name == NULL) + return NULL; + if ((opt = cmd_option_find(parser, opt_name)) != NULL) + return opt; + + if ((opt = (struct CmdOption*)malloc(sizeof(struct CmdOption))) == NULL) + { + strerror(errno); + } + else + { + opt->option = opt_name; + opt->parameter = NULL; + opt->desc = NULL; + LIST_INSERT_HEAD(&(parser->option_list), opt, next); + } + + return opt; +} + +static void cmd_option_register(struct CmdOptionParser* parser, char* syntax, char* desc) +{ + char buf[OPTION_MAX_LEN]; + struct CmdOption* opt = NULL; + char* opt_name = NULL; + char* param = NULL; + char* desc_copy = NULL; + char* token = NULL; + + if (parser == NULL) + return; + if (syntax == NULL) + return; + + memset(buf, 0, OPTION_MAX_LEN); + snprintf(buf, OPTION_MAX_LEN - 1, "%s", syntax); + + if ((token = strtok(buf, " ")) == NULL) + return; + + opt_name = strdup(token); + if ((token = strtok(NULL, " ")) != NULL) + param = strdup(token); + desc_copy = strdup(desc); + if ((opt = cmd_option_find(parser, opt_name)) != NULL) + goto failed; + if ((opt = cmd_option_add(parser, opt_name)) == NULL) + { + goto failed; + } + opt->parameter = param; + opt->desc = desc_copy; + + return; + + failed: + if (opt_name) + free(opt_name); + if (desc_copy != NULL) + free(desc_copy); + if (param != NULL) + free(param); + if (opt != NULL) + free(opt); +} + +void cmd_option_parser_init(struct CmdOptionParser* parser) +{ + if (parser == NULL) + return; + + LIST_INIT(&parser->option_list); + cmd_option_register(parser, "-l ", "Set log file path.\n(Default: /var/log/iccpd.log)"); + cmd_option_register(parser, "-p ", "Set the port used for telnet listening port.\n(Default: 2015)"); + cmd_option_register(parser, "-c", "Dump log message to console. (Default: No)"); + cmd_option_register(parser, "-h", "Show the usage."); +} + +void cmd_option_parser_finalize(struct CmdOptionParser* parser) +{ + while (!LIST_EMPTY(&(parser->option_list))) + { + struct CmdOption* opt = NULL; + opt = LIST_FIRST(&(parser->option_list)); + cmd_option_delete(opt); + } +} + +void cmd_option_parser_dump_usage(struct CmdOptionParser* parser, char* prog_name) +{ + char buf[MSG_LEN]; + struct CmdOption* opt = NULL; + int index, begin, length; + char first_line = 0; + + fprintf(stdout, "Usage: %s [Options]\n", prog_name); + fprintf(stdout, "\n"); + fprintf(stdout, "Options:\n"); + LIST_FOREACH(opt, &(parser->option_list), next) + { + index = 0; + begin = 0; + length = 0; + first_line = 1; + memset(buf, 0, MSG_LEN); + if (opt->parameter != NULL) + snprintf(buf, MSG_LEN - 1, "%s %s", opt->option, opt->parameter); + else + snprintf(buf, MSG_LEN - 1, "%s", opt->option); + fprintf(stdout, "%24s ", buf); + + while (index < strlen(opt->desc)) + { + while (index < strlen(opt->desc) + && opt->desc[index] != '\n' && length < 49) + { + ++index; + ++length; + } + + memset(buf, 0, MSG_LEN); + strncpy(buf, &(opt->desc[begin]), length); + if (length == 49 && index < strlen(opt->desc) + && opt->desc[index] != '\n' + && opt->desc[index - 1] != ' ' + && opt->desc[index] != ' ') + { + buf[length] = '-'; + buf[length + 1] = '\0'; + } + if (length < 49) + ++index; + begin = index; + length = 0; + if (first_line != 0) + { + fprintf(stdout, "%-52s\n", buf); + first_line = 0; + } + else + fprintf(stdout, "%28c%-52s\n", ' ', buf); + } + + fflush(stdout); + } +} + +int cmd_option_parser_parse(struct CmdOptionParser* parser, int argc, char* argv[]) +{ + int index = 1; + struct CmdOption* opt = NULL; + char* opt_name = NULL; + char* val = NULL; + int num = 0; + + if (parser == NULL) + return -255; + + while (index < argc) + { + opt_name = argv[index]; + opt = cmd_option_find(parser, opt_name); + if (opt == NULL) + { + fprintf(stderr, "Unknown option %s, skip it.\n", opt_name); + ++index; + continue; + } + + if (opt->parameter != NULL) + { + ++index; + if (index >= argc) + { + fprintf(stderr, "Error: Insufficient parameter for option %s\n", opt_name); + cmd_option_parser_dump_usage(parser, argv[0]); + return -1; + } + val = argv[index]; + } + + if (strncmp(opt_name, "-h", 2) == 0) + { + cmd_option_parser_dump_usage(parser, argv[0]); + return -1; + } + + if (strncmp(opt_name, "-l", 2) == 0) + parser->log_file_path = val; + + if (strncmp(opt_name, "-p", 2) == 0) + { + num = atoi(val); + if (num > 0 && num < 65535) + parser->telnet_port = num; + } + else if (strncmp(opt_name, "-c", 2) == 0) + parser->console_log = 1; + else + fprintf(stderr, "Unknown option name %s, skip it.\n", opt_name); + + ++index; + } + + return 0; +} diff --git a/src/iccpd/src/iccp_cli.c b/src/iccpd/src/iccp_cli.c new file mode 100644 index 000000000000..8d0ede8b3feb --- /dev/null +++ b/src/iccpd/src/iccp_cli.c @@ -0,0 +1,498 @@ +/* + * iccp_cli.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include + +#include "../include/system.h" +#include "../include/scheduler.h" +#include "../include/logger.h" +#include "../include/iccp_csm.h" +#include "../include/mlacp_link_handler.h" +#include "../include/iccp_netlink.h" +/* + * 'id <1-65535>' command + */ +int set_mc_lag_id( struct CSM *csm, uint16_t id) +{ + if (!csm) + return MCLAG_ERROR; + + ICCPD_LOG_INFO(__FUNCTION__, "Set mlag-id : %d", id); + + /* Mlag-ID, RG-ID, MLACP-ID + Temporary let the three id be the same*/ + csm->mlag_id = id; + csm->iccp_info.icc_rg_id = id; + csm->app_csm.mlacp.id = id; + return 0; +} + +int unset_mc_lag_id( struct CSM *csm, uint16_t id) +{ + if (!csm) + return MCLAG_ERROR; + + /* Mlag-ID, RG-ID, MLACP-ID*/ + csm->mlag_id = 0; + csm->iccp_info.icc_rg_id = 0; + csm->app_csm.mlacp.id = 0; + + iccp_csm_finalize(csm); + + return 0; +} + +/* + * 'peer-link WORD' command + */ +int set_peer_link(int mid, const char* ifname) +{ + struct CSM* csm = NULL; + struct LocalInterface *lif = NULL; + size_t len = 0; + + len = strlen(ifname); + + if (strncmp(ifname, FRONT_PANEL_PORT_PREFIX, strlen(FRONT_PANEL_PORT_PREFIX)) != 0 && strncmp(ifname, PORTCHANNEL_PREFIX, strlen(PORTCHANNEL_PREFIX)) != 0 && strncmp(ifname, VXLAN_TUNNEL_PREFIX, strlen(VXLAN_TUNNEL_PREFIX)) != 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Peer-link is %s, must be Ethernet or PortChannel or VTTNL(Vxlan tunnel)", ifname); + return MCLAG_ERROR; + } + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + + if (len > IFNAMSIZ) + return MCLAG_ERROR; + + if (strlen(csm->peer_itf_name) > 0) + { + if (strcmp(csm->peer_itf_name, ifname) == 0) + { + ICCPD_LOG_INFO(__FUNCTION__, "Peer-link not be changed"); + return 0; + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Change peer-link : %s -> %s", + csm->peer_itf_name, ifname); + + /*disconnect the link for mac and arp sync up before change peer_itf_name*/ + scheduler_session_disconnect_handler(csm); + + if (csm->peer_link_if) + { + csm->peer_link_if->is_peer_link = 0; + csm->peer_link_if = NULL; + } + } + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Set mlag %d peer-link : %s", + csm->mlag_id, ifname); + } + + memset(csm->peer_itf_name, 0, IFNAMSIZ); + memcpy(csm->peer_itf_name, ifname, len); + + /* update peer-link link handler*/ + lif = local_if_find_by_name(csm->peer_itf_name); + if (lif) + { + /*When set peer-link, the local-if is already created*/ + csm->peer_link_if = lif; + lif->is_peer_link = 1; + MLACP(csm).system_config_changed = 1; + + if (lif->type == IF_T_PORT_CHANNEL) + iccp_get_port_member_list(lif); + } + + /*disconnect the link for mac and arp sync up*/ + scheduler_session_disconnect_handler(csm); + + return 0; +} + +int unset_peer_link(int mid) +{ + struct CSM* csm = NULL; + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + /*must be enabled mac learn*/ + if (csm->peer_link_if) + set_peerlink_mlag_port_learn(csm->peer_link_if, 1); + } + + /* update peer-link link handler*/ + scheduler_session_disconnect_handler(csm); + + /* clean peer-link*/ + memset(csm->peer_itf_name, 0, IFNAMSIZ); + if (csm->peer_link_if) + { + csm->peer_link_if->is_peer_link = 0; + csm->peer_link_if = NULL; + MLACP(csm).system_config_changed = 1; + } + + return 0; +} + +/* + * 'local ip address A.B.C.D' command + */ +int set_local_address(int mid, const char* addr) +{ + struct CSM* csm = NULL; + size_t len = 0; + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + if (addr == NULL) + return MCLAG_ERROR; + + if (strlen(csm->sender_ip) > 0) + { + if (strcmp(csm->sender_ip, addr) == 0) + { + ICCPD_LOG_INFO(__FUNCTION__, "Local-address not be changed"); + return 0; + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Change local-address : %s -> %s", + csm->sender_ip, addr); + scheduler_session_disconnect_handler(csm); + } + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Set local-address : %s", addr); + } + + len = strlen(addr); + memset(csm->sender_ip, 0, INET_ADDRSTRLEN); + memcpy(csm->sender_ip, addr, len); + memset(csm->iccp_info.sender_name, 0, INET_ADDRSTRLEN); + memcpy(csm->iccp_info.sender_name, addr, len); + + return 0; +} + +int unset_local_address(int mid) +{ + struct CSM* csm = NULL; + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + + memset(csm->sender_ip, 0, INET_ADDRSTRLEN); + memset(csm->iccp_info.sender_name, 0, INET_ADDRSTRLEN); + + /* reset link*/ + scheduler_session_disconnect_handler(csm); + + return 0; +} + +/* + * 'peer-address A.B.C.D' command + */ +int set_peer_address(int mid, const char* addr) +{ + struct CSM* csm = NULL; + size_t len = 0; + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + if (addr == NULL) + return MCLAG_ERROR; + + len = strlen(addr); + + if (strlen(csm->peer_ip) > 0) + { + if (strcmp(csm->peer_ip, addr) == 0) + { + ICCPD_LOG_INFO(__FUNCTION__, "Peer-address not be changed"); + return 0; + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Change peer-address : %s -> %s", + csm->peer_ip, addr); + scheduler_session_disconnect_handler(csm); + } + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Set peer-address : %s", addr); + } + + memset(csm->peer_ip, 0, INET_ADDRSTRLEN); + memcpy(csm->peer_ip, addr, len); + + return 0; +} + +int unset_peer_address(int mid) +{ + struct CSM* csm = NULL; + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + + memset(csm->peer_ip, 0, INET_ADDRSTRLEN); + + /* reset link*/ + scheduler_session_disconnect_handler(csm); + + return 0; +} + +int iccp_cli_attach_mclag_domain_to_port_channel( int domain, const char* ifname) +{ + struct CSM* csm = NULL; + struct LocalInterface *lif = NULL; + struct If_info * cif = NULL; + + if (!ifname) + return MCLAG_ERROR; + + if (strncmp(ifname, PORTCHANNEL_PREFIX, strlen(PORTCHANNEL_PREFIX)) != 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Attach interface(%s) is not a port-channel", ifname); + return MCLAG_ERROR; + } + + csm = system_get_csm_by_mlacp_id(domain); + if (csm == NULL) + { + ICCPD_LOG_WARN(__FUNCTION__, "MC-LAG ID %d doesn't exist", domain); + return MCLAG_ERROR; + } + + lif = local_if_find_by_name(ifname); + if (lif) + { + mlacp_bind_port_channel_to_csm(csm, ifname); + } + + LIST_FOREACH(cif, &(csm->if_bind_list), csm_next) + { + if (strcmp(cif->name, ifname) == 0) + break; + } + + if (cif == NULL) + { + cif = (struct If_info *)malloc(sizeof(struct If_info)); + if (!cif) + return MCLAG_ERROR; + + snprintf(cif->name, MAX_L_PORT_NAME, "%s", ifname); + LIST_INSERT_HEAD(&(csm->if_bind_list), cif, csm_next); + } + + return 0; +} + +int iccp_cli_detach_mclag_domain_to_port_channel( const char* ifname) +{ + int unbind_poid = -1; + struct CSM *csm = NULL; + struct LocalInterface *lif_po = NULL; + struct LocalInterface *lif = NULL; + struct If_info * cif = NULL; + + if (!ifname) + return MCLAG_ERROR; + + if (strncmp(ifname, PORTCHANNEL_PREFIX, strlen(PORTCHANNEL_PREFIX)) != 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Detach interface(%s) is not a port-channel", ifname); + return MCLAG_ERROR; + } + + /* find po*/ + if (!(lif_po = local_if_find_by_name(ifname)) + || lif_po->type != IF_T_PORT_CHANNEL + || lif_po->po_id <= 0 + || lif_po->csm == NULL) + { + return MCLAG_ERROR; + } + + /* find csm*/ + csm = lif_po->csm; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Detach mclag id = %d from ifname = %s", + csm->mlag_id, lif_po->name); + + /* process link state handler before detaching it.*/ + mlacp_mlag_link_del_handler(csm, lif_po); + + unbind_poid = lif_po->po_id; + mlacp_unbind_local_if(lif_po); + LIST_FOREACH(lif, &(csm->app_csm.mlacp.lif_list), mlacp_next) + { + if (lif->type == IF_T_PORT && lif->po_id == unbind_poid) + mlacp_unbind_local_if(lif); + } + + LIST_FOREACH(cif, &(csm->if_bind_list), csm_next) + { + if (strcmp(ifname, cif->name) == 0) + LIST_REMOVE(cif, csm_next); + } + return 0; +} + +/* This function parses a string to a binary mac address (uint8_t[6]) + The string should contain mac address only. No spaces are allowed. + The mac address separators could be either ':' or '-'*/ +int parseMacString(const char * str_mac, uint8_t* bin_mac) +{ + int i; + + if (bin_mac == NULL) + { + return MCLAG_ERROR; + } + + /* 6 hexadecimal numbers (two digits each) + 5 delimiters*/ + if (strlen(str_mac) != ETHER_ADDR_LEN * 2 + 5) + { + return MCLAG_ERROR; + } + + /* first check that all mac address separators are equal to each other + 2, 5, 8, 11, and 14 are MAC address separator positions*/ + if (!(str_mac[2] == str_mac[5] + && str_mac[5] == str_mac[8] + && str_mac[8] == str_mac[11] + && str_mac[11] == str_mac[14])) + { + return MCLAG_ERROR; + } + + /* then check that the first separator is equal to ':' or '-'*/ + if (str_mac[2] != ':' && str_mac[2] != '-') + { + return MCLAG_ERROR; + } + + for (i = 0; i < ETHER_ADDR_LEN; ++i) + { + int left = i * 3; /* left digit position of hexadecimal number*/ + int right = left + 1; /* right digit position of hexadecimal number*/ + + if (str_mac[left] >= '0' && str_mac[left] <= '9') + { + bin_mac[i] = (uint8_t)(str_mac[left] - '0'); + } + else if (str_mac[left] >= 'A' && str_mac[left] <= 'F') + { + bin_mac[i] = (uint8_t)(str_mac[left] - 'A' + 0x0a); + } + else if (str_mac[left] >= 'a' && str_mac[left] <= 'f') + { + bin_mac[i] = (uint8_t)(str_mac[left] - 'a' + 0x0a); + } + else + { + return MCLAG_ERROR; + } + + bin_mac[i] = (uint8_t)(bin_mac[i] << 4); + + if (str_mac[right] >= '0' && str_mac[right] <= '9') + { + bin_mac[i] |= (uint8_t)(str_mac[right] - '0'); + } + else if (str_mac[right] >= 'A' && str_mac[right] <= 'F') + { + bin_mac[i] |= (uint8_t)(str_mac[right] - 'A' + 0x0a); + } + else if (str_mac[right] >= 'a' && str_mac[right] <= 'f') + { + bin_mac[i] |= (uint8_t)(str_mac[right] - 'a' + 0x0a); + } + else + { + return MCLAG_ERROR; + } + } + + return 0; +} + +int set_local_system_id(const char* mac) +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + + if ((sys = system_get_instance()) == NULL ) + return 0; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + parseMacString(mac, MLACP(csm).system_id); + + ICCPD_LOG_DEBUG(__FUNCTION__, " Set local systemID [%02X:%02X:%02X:%02X:%02X:%02X].", + MLACP(csm).system_id[0], MLACP(csm).system_id[1], MLACP(csm).system_id[2], + MLACP(csm).system_id[3], MLACP(csm).system_id[4], MLACP(csm).system_id[5]); + } + + return 0; +} + +int unset_local_system_id( ) +{ + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + struct System* sys = NULL; + struct CSM* csm = NULL; + + if ((sys = system_get_instance()) == NULL ) + return 0; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + memcpy(MLACP(csm).system_id, null_mac, ETHER_ADDR_LEN); + } + + return 0; +} + diff --git a/src/iccpd/src/iccp_cmd.c b/src/iccpd/src/iccp_cmd.c new file mode 100644 index 000000000000..50025a8e3810 --- /dev/null +++ b/src/iccpd/src/iccp_cmd.c @@ -0,0 +1,168 @@ +/* + * iccp_cmd.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include + +#include "../include/iccp_csm.h" +#include "../include/msg_format.h" +#include "../include/system.h" + +#include "../include/iccp_cmd_show.h" +#include "../include/iccp_cli.h" +#include "../include/logger.h" + +int set_mc_lag_by_id(uint16_t mid) +{ + int ret = 0; + struct CSM* csm = NULL; + + csm = system_get_csm_by_mlacp_id(mid); + if (!csm) + { + csm = (struct CSM*)iccp_get_csm(); + if (csm == NULL) + { + return MCLAG_ERROR; + } + + ret = set_mc_lag_id(csm, mid); + + return ret; + } + + return ret; +} + +#define CONFIG_LINE_LEN 512 + +int iccp_config_from_command(char * line) +{ + char *cp, *start; + char token[64]; + int slen; + static int mid = 0; + char *end; + + if (line == NULL) + return 0; + + cp = line; + + /* Skip white spaces. */ + while (isspace((int)*cp) && *cp != '\0') + cp++; + + /* Return if there is only white spaces */ + if (*cp == '\0') + return 0; + + end = cp; + + /* Skip end white spaces. */ + while (!isspace((int)*end) && *end != '\0') + end++; + + *end = '\0'; + /*mc-lag id*/ + if (strncmp(cp, MCLAG_ID_STR, strlen(MCLAG_ID_STR)) == 0 ) + { + cp += strlen(MCLAG_ID_STR) + 1; + mid = atoi(cp); + set_mc_lag_by_id(mid); + } + else if (strncmp(cp, LOCAL_IP_STR, strlen(LOCAL_IP_STR)) == 0) /*local ip*/ + { + cp += strlen(LOCAL_IP_STR) + 1; + set_local_address(mid, cp); + } + else if (strncmp(cp, PEER_IP_STR, strlen(PEER_IP_STR)) == 0) /*peer ip*/ + { + cp += strlen(PEER_IP_STR) + 1; + set_peer_address(mid, cp); + } + else if (strncmp(cp, PEER_LINK_STR, strlen(PEER_LINK_STR)) == 0)/*peer link*/ + { + cp += strlen(PEER_LINK_STR) + 1; + set_peer_link(mid, cp); + } + else if (strncmp(cp, MCLAG_INTF_STR, strlen(MCLAG_INTF_STR)) == 0)/*mclag interface*/ + { + cp += strlen(MCLAG_INTF_STR) + 1; + + while (1) + { + start = cp; + + while (!(*cp == ',' || *cp == '\r' || *cp == '\n') && + *cp != '\0') + cp++; + + slen = cp - start; + strncpy(token, start, slen); + *(token + slen) = '\0'; + iccp_cli_attach_mclag_domain_to_port_channel(mid, token); + + while ((isspace((int)*cp) || *cp == '\n' || *cp == '\r' || *cp == ',') && + *cp != '\0') + cp++; + + if (*cp == '\0') + break; + } + } + else if (strncmp(cp, SYSTEM_MAC_STR, strlen(SYSTEM_MAC_STR)) == 0)/*system mac*/ + { + cp += strlen(SYSTEM_MAC_STR) + 1; + set_local_system_id(cp); + } + else + { + /*error*/ + } + + return 1; +} + +/* Configration make from file. */ +int +iccp_config_from_file(char *config_default_dir) +{ + FILE *confp = NULL; + char command_buf[CONFIG_LINE_LEN]; + + confp = fopen(config_default_dir, "r"); + if (confp == NULL) + return (1); + + while (fgets(command_buf, CONFIG_LINE_LEN, confp)) + { + iccp_config_from_command(command_buf); + } + + fclose(confp); + + return 0; +} + diff --git a/src/iccpd/src/iccp_cmd_show.c b/src/iccpd/src/iccp_cmd_show.c new file mode 100644 index 000000000000..e25a653e74b3 --- /dev/null +++ b/src/iccpd/src/iccp_cmd_show.c @@ -0,0 +1,477 @@ +/* + * iccp_cmd_show.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ +#include +#include +#include +#include + +#include "../include/iccp_csm.h" +#include "../include/mlacp_tlv.h" +#include "../include/system.h" +#include "../include/logger.h" +#include "mclagdctl/mclagdctl.h" +#include "../include/iccp_cmd_show.h" +#include "../include/mlacp_link_handler.h" + +int iccp_mclag_config_dump(char * *buf, int *num, int mclag_id) +{ + struct mclagd_state state_info; + struct System *sys = NULL; + struct CSM *csm = NULL; + struct LocalInterface *peer_link_if = NULL; + struct LocalInterface *lif_po = NULL; + struct LoggerConfig* logconfig; + char unknown[] = { "Unknown" }; + int mclag_num = 0; + int id_exist = 0; + int str_size = 0; + int len = 0; + char *state_buf = NULL; + int state_buf_size = MCLAGDCTL_CMD_SIZE; + + if (!(sys = system_get_instance())) + { + return EXEC_TYPE_NO_EXIST_SYS; + } + + state_buf = (char*)malloc(state_buf_size); + if (!state_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + memset(&state_info, 0, sizeof(struct mclagd_state)); + + if (csm->current_state == ICCP_OPERATIONAL) + state_info.keepalive = 1; + else + state_info.keepalive = 0; + + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + peer_link_if = local_if_find_by_name(csm->peer_itf_name); + + if (csm->mlag_id <= 0) + state_info.mclag_id = -1; + else + state_info.mclag_id = csm->mlag_id; + + memcpy(state_info.local_ip, csm->sender_ip, ICCP_MAX_IP_STR_LEN); + memcpy(state_info.peer_ip, csm->peer_ip, ICCP_MAX_IP_STR_LEN); + + if (peer_link_if) + memcpy(state_info.peer_link_if, peer_link_if->name, ICCP_MAX_PORT_NAME); + else + memcpy(state_info.peer_link_if, unknown, strlen(unknown)); + + if (peer_link_if) + memcpy(state_info.peer_link_mac, peer_link_if->mac_addr, 6); + + logconfig = logger_get_configuration(); + memcpy(state_info.loglevel, log_level_to_string(logconfig->log_level), strlen( log_level_to_string(logconfig->log_level))); + + state_info.role = csm->role_type; + + str_size = MCLAGDCTL_PORT_MEMBER_BUF_LEN; + + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + + if (str_size - len < ICCP_MAX_PORT_NAME) + break; + + if (lif_po->type == IF_T_PORT_CHANNEL) + len += snprintf(state_info.enabled_po + len, str_size - len, "%s,", lif_po->name); + } + + /*Skip the last ','*/ + len = strlen(state_info.enabled_po); + if (len > 0) + { + state_info.enabled_po[len - 1] = '\0'; + } + + memcpy(state_buf + MCLAGD_REPLY_INFO_HDR + mclag_num * sizeof(struct mclagd_state), + &state_info, sizeof(struct mclagd_state)); + mclag_num++; + + if ((mclag_num + 1) * sizeof(struct mclagd_state) > (state_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + state_buf_size += MCLAGDCTL_CMD_SIZE; + state_buf = (char*)realloc(state_buf, state_buf_size); + if (!state_buf) + return EXEC_TYPE_FAILED; + } + } + + *buf = state_buf; + *num = mclag_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + +int iccp_arp_dump(char * *buf, int *num, int mclag_id) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct ARPMsg *iccpd_arp = NULL; + struct mclagd_arp_msg mclagd_arp; + int arp_num = 0; + int id_exist = 0; + char * arp_buf = NULL; + int arp_buf_size = MCLAGDCTL_CMD_SIZE; + + if (!(sys = system_get_instance())) + { + return EXEC_TYPE_NO_EXIST_SYS; + } + + arp_buf = (char*)malloc(arp_buf_size); + if (!arp_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + memset(&mclagd_arp, 0, sizeof(struct mclagd_arp_msg)); + iccpd_arp = (struct ARPMsg*)msg->buf; + + mclagd_arp.op_type = iccpd_arp->op_type; + memcpy(mclagd_arp.ifname, iccpd_arp->ifname, strlen(iccpd_arp->ifname)); + memcpy(mclagd_arp.ipv4_addr, show_ip_str(htonl(iccpd_arp->ipv4_addr)), 16); + memcpy(mclagd_arp.mac_addr, iccpd_arp->mac_addr, 6); + + memcpy(arp_buf + MCLAGD_REPLY_INFO_HDR + arp_num * sizeof(struct mclagd_arp_msg), + &mclagd_arp, sizeof(struct mclagd_arp_msg)); + + arp_num++; + + if ((arp_num + 1) * sizeof(struct mclagd_arp_msg) > (arp_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + arp_buf_size += MCLAGDCTL_CMD_SIZE; + arp_buf = (char*)realloc(arp_buf, arp_buf_size); + if (!arp_buf) + return EXEC_TYPE_FAILED; + } + } + } + + *buf = arp_buf; + *num = arp_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + +int iccp_mac_dump(char * *buf, int *num, int mclag_id) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct MACMsg *iccpd_mac = NULL; + struct mclagd_mac_msg mclagd_mac; + int mac_num = 0; + int id_exist = 0; + char * mac_buf = NULL; + int mac_buf_size = MCLAGDCTL_CMD_SIZE; + + if (!(sys = system_get_instance())) + { + return EXEC_TYPE_NO_EXIST_SYS; + } + + mac_buf = (char*)malloc(mac_buf_size); + if (!mac_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + memset(&mclagd_mac, 0, sizeof(struct mclagd_mac_msg)); + iccpd_mac = (struct MACMsg*)msg->buf; + + mclagd_mac.op_type = iccpd_mac->op_type; + mclagd_mac.fdb_type = iccpd_mac->fdb_type; + memcpy(mclagd_mac.mac_str, iccpd_mac->mac_str, ETHER_ADDR_STR_LEN); + mclagd_mac.vid = iccpd_mac->vid; + memcpy(mclagd_mac.ifname, iccpd_mac->ifname, strlen(iccpd_mac->ifname)); + memcpy(mclagd_mac.origin_ifname, iccpd_mac->origin_ifname, strlen(iccpd_mac->origin_ifname)); + mclagd_mac.age_flag = iccpd_mac->age_flag; + + memcpy(mac_buf + MCLAGD_REPLY_INFO_HDR + mac_num * sizeof(struct mclagd_mac_msg), + &mclagd_mac, sizeof(struct mclagd_mac_msg)); + + mac_num++; + + if ((mac_num + 1) * sizeof(struct mclagd_mac_msg) > (mac_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + mac_buf_size += MCLAGDCTL_CMD_SIZE; + mac_buf = (char*)realloc(mac_buf, mac_buf_size); + if (!mac_buf) + return EXEC_TYPE_FAILED; + } + } + } + + *buf = mac_buf; + *num = mac_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + +int iccp_local_if_dump(char * *buf, int *num, int mclag_id) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct LocalInterface *lif_po = NULL; + struct mclagd_local_if mclagd_lif; + struct VLAN_ID* vlan_id = NULL; + char * str_buf = NULL; + int str_size = MCLAGDCTL_PARA3_LEN - 1; + int len = 0; + int lif_num = 0; + int id_exist = 0; + int lif_buf_size = MCLAGDCTL_CMD_SIZE; + char * lif_buf = NULL; + + if (!(sys = system_get_instance())) + { + return EXEC_TYPE_NO_EXIST_SYS; + } + + lif_buf = (char*)malloc(lif_buf_size); + if (!lif_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + memset(&mclagd_lif, 0, sizeof(struct mclagd_local_if)); + + mclagd_lif.ifindex = lif_po->ifindex; + + if (lif_po->type == IF_T_UNKNOW) + memcpy(mclagd_lif.type, "Unknown", 6); + else if (lif_po->type == IF_T_PORT) + memcpy(mclagd_lif.type, "Ethernet", 8); + else if (lif_po->type == IF_T_PORT_CHANNEL) + memcpy(mclagd_lif.type, "PortChannel", 11); + + memcpy(mclagd_lif.name, lif_po->name, MAX_L_PORT_NAME); + memcpy(mclagd_lif.mac_addr, lif_po->mac_addr, ETHER_ADDR_LEN); + + if (lif_po->state == PORT_STATE_UP) + memcpy(mclagd_lif.state, "Up", 2); + else if (lif_po->state == PORT_STATE_DOWN) + memcpy(mclagd_lif.state, "Down", 4); + else if (lif_po->state == PORT_STATE_ADMIN_DOWN) + memcpy(mclagd_lif.state, "Admin-down", 10); + else if (lif_po->state == PORT_STATE_TEST) + memcpy(mclagd_lif.state, "Test", 4); + + memcpy(mclagd_lif.ipv4_addr, show_ip_str(htonl(lif_po->ipv4_addr)), 16); + mclagd_lif.prefixlen = lif_po->prefixlen; + + mclagd_lif.l3_mode = local_if_is_l3_mode(lif_po); + + mclagd_lif.is_peer_link = lif_po->is_peer_link; + + memcpy(mclagd_lif.portchannel_member_buf, lif_po->portchannel_member_buf, 512); + + mclagd_lif.po_id = lif_po->po_id; + mclagd_lif.po_active = lif_po->po_active; + /*mlacp_state*/ + if (lif_po->mlacp_state == MLACP_STATE_INIT) + memcpy(mclagd_lif.mlacp_state, "INIT", 4); + else if (lif_po->mlacp_state == MLACP_STATE_STAGE1) + memcpy(mclagd_lif.mlacp_state, "STAGE1", 6); + else if (lif_po->mlacp_state == MLACP_STATE_STAGE2) + memcpy(mclagd_lif.mlacp_state, "STAGE2", 6); + else if (lif_po->mlacp_state == MLACP_STATE_EXCHANGE) + memcpy(mclagd_lif.mlacp_state, "EXCHANGE", 8); + else if (lif_po->mlacp_state == MLACP_STATE_ERROR) + memcpy(mclagd_lif.mlacp_state, "ERROR", 5); + + mclagd_lif.isolate_to_peer_link = lif_po->isolate_to_peer_link; + + str_buf = mclagd_lif.vlanlist; + + len = 0; + LIST_FOREACH(vlan_id, &(lif_po->vlan_list), port_next) + { + if (vlan_id != NULL ) + { + if (str_size - len < 4) + break; + len += snprintf(str_buf + len, str_size - len, "%d ", vlan_id->vid); + } + } + + memcpy(lif_buf + MCLAGD_REPLY_INFO_HDR + lif_num * sizeof(struct mclagd_local_if), + &mclagd_lif, sizeof(struct mclagd_local_if)); + + lif_num++; + + if ((lif_num + 1) * sizeof(struct mclagd_local_if) > (lif_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + lif_buf_size += MCLAGDCTL_CMD_SIZE; + lif_buf = (char*)realloc(lif_buf, lif_buf_size); + if (!lif_buf) + return EXEC_TYPE_FAILED; + } + } + } + + *buf = lif_buf; + *num = lif_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + +int iccp_peer_if_dump(char * *buf, int *num, int mclag_id) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct PeerInterface *pif_po = NULL; + struct mclagd_peer_if mclagd_pif; + int pif_num = 0; + int id_exist = 0; + int pif_buf_size = MCLAGDCTL_CMD_SIZE; + char *pif_buf = NULL; + + if (!(sys = system_get_instance())) + { + return EXEC_TYPE_NO_EXIST_SYS; + } + + pif_buf = (char*)malloc(pif_buf_size); + if (!pif_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + LIST_FOREACH(pif_po, &(MLACP(csm).pif_list), mlacp_next) + { + memset(&mclagd_pif, 0, sizeof(struct mclagd_peer_if)); + + mclagd_pif.ifindex = pif_po->ifindex; + + if (pif_po->type == IF_T_UNKNOW) + memcpy(mclagd_pif.type, "Unknown", 6); + else if (pif_po->type == IF_T_PORT) + memcpy(mclagd_pif.type, "Ethernet", 8); + else if (pif_po->type == IF_T_PORT_CHANNEL) + memcpy(mclagd_pif.type, "PortChannel", 11); + + memcpy(mclagd_pif.name, pif_po->name, MAX_L_PORT_NAME); + memcpy(mclagd_pif.mac_addr, pif_po->mac_addr, ETHER_ADDR_LEN); + + if (pif_po->state == PORT_STATE_UP) + memcpy(mclagd_pif.state, "Up", 2); + else if (pif_po->state == PORT_STATE_DOWN) + memcpy(mclagd_pif.state, "Down", 4); + else if (pif_po->state == PORT_STATE_ADMIN_DOWN) + memcpy(mclagd_pif.state, "Admin-down", 10); + else if (pif_po->state == PORT_STATE_TEST) + memcpy(mclagd_pif.state, "Test", 4); + + mclagd_pif.po_id = pif_po->po_id; + mclagd_pif.po_active = pif_po->po_active; + + memcpy(pif_buf + MCLAGD_REPLY_INFO_HDR + pif_num * sizeof(struct mclagd_peer_if), + &mclagd_pif, sizeof(struct mclagd_peer_if)); + + pif_num++; + + if ((pif_num + 1) * sizeof(struct mclagd_peer_if) > (pif_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + pif_buf_size += MCLAGDCTL_CMD_SIZE; + pif_buf = (char*)realloc(pif_buf, pif_buf_size); + if (!pif_buf) + return EXEC_TYPE_FAILED; + } + } + } + + *buf = pif_buf; + *num = pif_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + diff --git a/src/iccpd/src/iccp_consistency_check.c b/src/iccpd/src/iccp_consistency_check.c new file mode 100644 index 000000000000..90ac9cd9e790 --- /dev/null +++ b/src/iccpd/src/iccp_consistency_check.c @@ -0,0 +1,175 @@ +/* + * iccp_consistency_check.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + * + */ + +#include "../include/iccp_consistency_check.h" +#include "../include/system.h" +#include "../include/port.h" +#include "../include/logger.h" + +/* Return 0 if the checking procedure is failed; otherwise, 1 (non-zero) will be returned. */ +typedef int (*ConsistencyCheckFunc)(char* ifname); + +const char *reasons[] = { + /* REASON_NONE */ + "Success", + /* REASON_INTERRFACE_MODE_IS_ASYNC */ + "Port-channel interface is not in the same mode in local and peer device, please check whether the ip addr settings is correct or not.", + /* REASON_PEER_IF_IP_IS_ASYNC */ + "IP address of peer interface is not synchronized, please check the IP address setting on the corresponding interface.", + /* REASON_PEER_IF_VLAN_IS_ASYNC */ + "VLAN settings on this port-channel interface is not synchronized, please check your configuration.", + /* REASON_MAX_ARRAY_SIZE */ + NULL +}; + +/* Consistency Checking functions */ +static int iccp_check_interface_mode( char* ifname) +{ + struct CSM* csm = NULL; + struct LocalInterface* local_if = NULL; + struct PeerInterface* peer_if = NULL; + + local_if = local_if_find_by_name(ifname); + if (local_if == NULL) + return -2; + + csm = local_if->csm; + if (csm == NULL) + return -3; + + peer_if = peer_if_find_by_name(csm, ifname); + if (peer_if == NULL) + return -4; + + if (peer_if->l3_mode != local_if->l3_mode) + return -5; + + return 1; +} + +static int iccp_check_interface_layer3_addr(char* ifname) +{ + struct CSM* csm = NULL; + struct LocalInterface* local_if = NULL; + struct PeerInterface* peer_if = NULL; + + local_if = local_if_find_by_name(ifname); + if (local_if == NULL) + return -2; + + csm = local_if->csm; + if (csm == NULL) + return -3; + + peer_if = peer_if_find_by_name(csm, ifname); + if (peer_if == NULL) + return -4; + + if (peer_if->ipv4_addr != local_if->ipv4_addr) + return -5; + + return 1; +} + +static int iccp_check_interface_vlan(char* ifname) +{ + struct CSM* csm = NULL; + struct PeerInterface* peer_if = NULL; + struct VLAN_ID* local_vlan = NULL; + struct VLAN_ID* peer_vlan = NULL; + struct LocalInterface* local_if = NULL; + + local_if = local_if_find_by_name(ifname); + if (local_if == NULL) + return -2; + + csm = local_if->csm; + if (csm == NULL) + return -3; + + peer_if = peer_if_find_by_name(csm, ifname); + if (peer_if == NULL) + return -4; + + LIST_FOREACH(local_vlan, &(local_if->vlan_list), port_next) + { + LIST_FOREACH(peer_vlan, &(peer_if->vlan_list), port_next) + { + if (peer_vlan->vid == local_vlan->vid) + break; + } + + if (peer_vlan == NULL) + { + return -5; + } + } + + LIST_FOREACH(peer_vlan, &(peer_if->vlan_list), port_next) + { + + LIST_FOREACH(local_vlan, &(local_if->vlan_list), port_next) + { + if (peer_vlan->vid == local_vlan->vid) + break; + } + + if (local_vlan == NULL) + { + return -6; + } + } + + return 1; +} + +static const ConsistencyCheckFunc check_func[] = { + NULL, + iccp_check_interface_mode, /* REASON_INTERFACE_MODE_IS_ASYNC */ + iccp_check_interface_layer3_addr, /* REASON_PEER_IF_IP_IS_ASYNC */ + iccp_check_interface_vlan, /* REASON_PEER_IF_VLAN_IS_ASYNC */ + NULL /* REASON_MAX_ARRAY_SIZE */ +}; +#define ARRAY_SIZE(array_name) (sizeof(array_name) / sizeof(array_name[0])) + +enum Reason_ID iccp_consistency_check(char* ifname) +{ + int i = 0; + int ret = 0; + + for (i = REASON_INTERRFACE_MODE_IS_ASYNC; i < REASON_MAX_ARRAY_SIZE; ++i) + { + if (check_func[i] == NULL) + continue; + ret = check_func[i](ifname); + if (ret != 1) + { + ICCPD_LOG_WARN(__FUNCTION__, "%s ret = %d", reasons[i], ret); + fprintf(stdout, "%s \n", reasons[i]); + return i; + } + } + + return REASON_NONE; +} diff --git a/src/iccpd/src/iccp_csm.c b/src/iccpd/src/iccp_csm.c new file mode 100644 index 000000000000..79e17b9e1ba2 --- /dev/null +++ b/src/iccpd/src/iccp_csm.c @@ -0,0 +1,797 @@ +/* + * iccp_csm.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include + +#include "../include/logger.h" +#include "../include/system.h" +#include "../include/scheduler.h" +#include "../include/msg_format.h" +#include "../include/iccp_csm.h" +#include "../include/mlacp_link_handler.h" +/***************************************** +* Define +* +* ***************************************/ +#define ICCP_CSM_QUEUE_REINIT(list) \ + { \ + struct Msg* msg = NULL; \ + while (!TAILQ_EMPTY(&(list))) { \ + msg = TAILQ_FIRST(&(list)); \ + TAILQ_REMOVE(&(list), msg, tail); \ + free(msg->buf); \ + free(msg); \ + } \ + TAILQ_INIT(&(list)); \ + } + +/***************************************** +* Global +* +* ***************************************/ +char g_csm_buf[CSM_BUFFER_SIZE] = { 0 }; + +uint32_t ICCP_MSG_ID = 0x1; + +/* Enter Connection State Machine NONEXISTENT handle function */ +static void iccp_csm_enter_state_nonexistent(struct CSM* csm) +{ + iccp_csm_finalize(csm); +} + +/* Enter Connection State Machine INITIALIZED handle function */ +static void iccp_csm_enter_state_initialized(struct CSM* csm) +{ + if (csm == NULL) + return; + + csm->iccp_info.sender_capability_flag = 0x1; +} + +/* Enter Connection State Machine CAPREC handle function */ +static void iccp_csm_enter_state_caprec(struct CSM* csm) +{ + if (csm == NULL) + return; + + csm->iccp_info.sender_capability_flag = 0x1; + csm->iccp_info.peer_capability_flag = 0x1; +} + +/* Enter Connection State Machine CONNECTING handle function */ +static void iccp_csm_enter_state_connecting(struct CSM* csm) +{ + if (csm == NULL) + return; + + csm->iccp_info.sender_rg_connect_flag = 0x1; +} + +/* Enter Connection State Machine OPERATIONAL handle function */ +static void iccp_csm_enter_state_operational(struct CSM* csm) +{ + if (csm == NULL) + return; + + csm->iccp_info.sender_rg_connect_flag = 0x1; + csm->iccp_info.peer_rg_connect_flag = 0x1; +} + +void *iccp_get_csm() +{ + struct CSM* csm = NULL; + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + { + return NULL; + } + + csm = system_create_csm(); + + return csm; +} + +/* Connection State Machine instance initialization */ +void iccp_csm_init(struct CSM* csm) +{ + iccp_csm_status_reset(csm, 1); + memset(csm->sender_ip, 0, INET_ADDRSTRLEN); + memset(csm->peer_ip, 0, INET_ADDRSTRLEN); + memset(csm->iccp_info.sender_name, 0, MAX_L_ICC_SENDER_NAME); + csm->iccp_info.icc_rg_id = 0x0; +} + +/* Connection State Machine instance status reset */ +void iccp_csm_status_reset(struct CSM* csm, int all) +{ + ICCP_CSM_QUEUE_REINIT(csm->msg_list); + + if (all) + { + bzero(csm, sizeof(struct CSM)); + ICCP_CSM_QUEUE_REINIT(csm->msg_list); + } + + csm->sock_fd = -1; + pthread_mutex_init(&csm->conn_mutex, NULL); + csm->connTimePrev = 0; + csm->heartbeat_send_time = 0; + csm->heartbeat_update_time = 0; + csm->peer_warm_reboot_time = 0; + csm->warm_reboot_disconn_time = 0; + csm->role_type = STP_ROLE_NONE; + csm->sock_read_event_ptr = NULL; + csm->peer_link_if = NULL; + csm->u_msg_in_count = 0x0; + csm->i_msg_in_count = 0x0; + csm->icc_msg_in_count = 0x0; + csm->icc_msg_out_count = 0x0; + csm->iccp_info.status_code = 0x0; + csm->iccp_info.rejected_msg_id = 0x0; + csm->current_state = ICCP_NONEXISTENT; + csm->iccp_info.peer_capability_flag = 0x0; + csm->iccp_info.peer_rg_connect_flag = 0x0; + csm->iccp_info.sender_capability_flag = 0x0; + csm->iccp_info.sender_rg_connect_flag = 0x0; + app_csm_init(csm, all); + + memset(&csm->msg_log, 0, sizeof(struct MsgLog)); +} + +/* Connection State Machine instance tear down */ +void iccp_csm_finalize(struct CSM* csm) +{ + struct If_info * cif = NULL; + struct System* sys = NULL; + + if (csm == NULL) + return; + + if ((sys = system_get_instance()) == NULL) + return; + + /*If warm reboot, don't change port block and peer link MAC learning*/ + if (sys->warmboot_exit != WARM_REBOOT) + { + /*Enable peer link port MAC learning*/ + if (csm->peer_link_if) + set_peerlink_mlag_port_learn(csm->peer_link_if, 1); + } + + /* Disconnect from peer */ + scheduler_session_disconnect_handler(csm); + + /* Release all Connection State Machine instance */ + app_csm_finalize(csm); + + LIST_FOREACH(cif, &(csm->if_bind_list), csm_next) + { + LIST_REMOVE(cif, csm_next); + } + + /* Release iccp_csm */ + pthread_mutex_destroy(&(csm->conn_mutex)); + iccp_csm_msg_list_finalize(csm); + LIST_REMOVE(csm, next); + free(csm); +} + +/* Message list of Connection State Machine instance tear down */ +void iccp_csm_msg_list_finalize(struct CSM* csm) +{ + struct Msg* msg = NULL; + + if (csm == NULL) + return; + + while (!TAILQ_EMPTY(&(csm->msg_list))) + { + msg = TAILQ_FIRST(&(csm->msg_list)); + TAILQ_REMOVE(&(csm->msg_list), msg, tail); + free(msg); + } +} + +/* Send message to peer */ +int iccp_csm_send(struct CSM* csm, char* buf, int msg_len) +{ + LDPHdr* ldp_hdr = (LDPHdr*)buf; + ICCParameter* param = NULL; + + if (csm == NULL || buf == NULL || csm->sock_fd <= 0 || msg_len <= 0) + return MCLAG_ERROR; + + if (ntohs(ldp_hdr->msg_type) == MSG_T_CAPABILITY) + param = (struct ICCParameter*)&buf[sizeof(LDPHdr)]; + else + param = (struct ICCParameter*)&buf[sizeof(ICCHdr)]; + + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Send(%d): len=[%d] msg_type=[%s (0x%X, 0x%X)]", csm->sock_fd, msg_len, get_tlv_type_string(param->type), ldp_hdr->msg_type, param->type);*/ + csm->msg_log.msg[csm->msg_log.end_index].msg_id = ntohl(ldp_hdr->msg_id); + csm->msg_log.msg[csm->msg_log.end_index].type = ntohs(ldp_hdr->msg_type); + csm->msg_log.msg[csm->msg_log.end_index].tlv = ntohs(param->type); + ++csm->msg_log.end_index; + if (csm->msg_log.end_index >= 128) + csm->msg_log.end_index = 0; + + return write(csm->sock_fd, buf, msg_len); +} + +/* Connection State Machine Transition */ +void iccp_csm_transit(struct CSM* csm) +{ + int len = -1; + struct Msg* msg = NULL; + ICCP_CONNECTION_STATE_E prev_state; + char *state_str[] = {"NONEXISTENT", "INITIALIZED", "CAPSENT", "CAPREC", "CONNECTING", "OPERATIONAL"}; + + if (!csm) + return; + + prev_state = csm->current_state; + + /* No connection, but have state change? reset it...*/ + if (csm->current_state != ICCP_NONEXISTENT && csm->sock_fd <= 0) + { + ICCPD_LOG_NOTICE(__FUNCTION__, "csm %d change state from %s to NONEXISTENT.", csm->mlag_id, state_str[csm->current_state]); + csm->current_state = ICCP_NONEXISTENT; + iccp_csm_enter_state_nonexistent(csm); + return; + } + + msg = iccp_csm_dequeue_msg(csm); + + switch (csm->current_state) + { + case ICCP_NONEXISTENT: + scheduler_prepare_session(csm); + if (csm->sock_fd > 0 && scheduler_check_csm_config(csm) > 0) + csm->current_state = ICCP_INITIALIZED; + break; + + case ICCP_INITIALIZED: + if (msg) + iccp_csm_correspond_from_msg(csm, msg); + len = iccp_csm_prepare_iccp_msg(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + if (csm->iccp_info.sender_capability_flag == 0x1 && csm->iccp_info.peer_capability_flag == 0x0) + csm->current_state = ICCP_CAPSENT; + else if (csm->iccp_info.sender_capability_flag == 0x1 && csm->iccp_info.peer_capability_flag == 0x1) + csm->current_state = ICCP_CAPREC; + break; + + case ICCP_CAPSENT: + if (msg) + iccp_csm_correspond_from_msg(csm, msg); + if (csm->iccp_info.sender_capability_flag == 0x1 && csm->iccp_info.peer_capability_flag == 0x1) + csm->current_state = ICCP_CAPREC; + break; + + case ICCP_CAPREC: + if (msg) + iccp_csm_correspond_from_msg(csm, msg); + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = iccp_csm_prepare_iccp_msg(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + if (csm->iccp_info.peer_rg_connect_flag == 0x0 && csm->iccp_info.status_code == 0x0) + csm->current_state = ICCP_CONNECTING; + else if (csm->iccp_info.peer_rg_connect_flag == 0x1 && csm->iccp_info.status_code == 0x0) + csm->current_state = ICCP_OPERATIONAL; + break; + + case ICCP_CONNECTING: + if (msg) + iccp_csm_correspond_from_msg(csm, msg); + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = iccp_csm_prepare_iccp_msg(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + if (csm->iccp_info.status_code > 0x0) + csm->current_state = ICCP_CAPREC; + else if (csm->iccp_info.peer_rg_connect_flag == 0x1 && csm->iccp_info.status_code == 0x0) + csm->current_state = ICCP_OPERATIONAL; + break; + + case ICCP_OPERATIONAL: + if (msg) + iccp_csm_correspond_from_msg(csm, msg); + if (csm->iccp_info.sender_rg_connect_flag == 0x0 || csm->iccp_info.peer_rg_connect_flag == 0x0) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = iccp_csm_prepare_iccp_msg(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + csm->current_state = ICCP_CAPREC; + } + break; + + default: + break; + } + + if (prev_state != csm->current_state || (csm->current_state && msg != NULL)) + { + if (prev_state != csm->current_state) + ICCPD_LOG_NOTICE(__FUNCTION__, "csm %d change state from %s to %s.", csm->mlag_id, state_str[prev_state], state_str[csm->current_state]); + + switch (csm->current_state) + { + case ICCP_NONEXISTENT: + iccp_csm_enter_state_nonexistent(csm); + break; + + case ICCP_INITIALIZED: + iccp_csm_enter_state_initialized(csm); + break; + + case ICCP_CAPSENT: + /* Do nothing on this state */ + break; + + case ICCP_CAPREC: + iccp_csm_enter_state_caprec(csm); + break; + + case ICCP_CONNECTING: + iccp_csm_enter_state_connecting(csm); + break; + + case ICCP_OPERATIONAL: + iccp_csm_enter_state_operational(csm); + break; + + default: + break; + } + } +} + +/* Set up ICCP message */ +int iccp_csm_prepare_iccp_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + size_t msg_len = -1; + + if (csm == NULL || buf == NULL) + return MCLAG_ERROR; + + switch (csm->current_state) + { + case ICCP_NONEXISTENT: + /* Do nothing on this state */ + break; + + case ICCP_INITIALIZED: + msg_len = iccp_csm_prepare_capability_msg(csm, buf, max_buf_size); + break; + + case ICCP_CAPSENT: + /* Do nothing on this state */ + break; + + case ICCP_CAPREC: + if (csm->iccp_info.status_code > 0x0) + { + msg_len = iccp_csm_prepare_nak_msg(csm, buf, max_buf_size); + break; + } + msg_len = iccp_csm_prepare_rg_connect_msg(csm, buf, max_buf_size); + break; + + case ICCP_CONNECTING: + if (csm->iccp_info.status_code > 0x0) + { + msg_len = iccp_csm_prepare_nak_msg(csm, buf, max_buf_size); + break; + } + break; + + case ICCP_OPERATIONAL: + if (csm->iccp_info.peer_rg_connect_flag == 0x0) + { + msg_len = iccp_csm_prepare_rg_disconnect_msg(csm, buf, max_buf_size); + break; + } + break; + } + + return msg_len; +} + +/* ICCP capability message handle function */ +int iccp_csm_prepare_capability_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + LDPHdr* ldp_hdr = (LDPHdr*)buf; + LDPICCPCapabilityTLV* cap = (LDPICCPCapabilityTLV*)&buf[sizeof(LDPHdr)]; + size_t msg_len = sizeof(LDPHdr) + sizeof(LDPICCPCapabilityTLV); + + memset(buf, 0, max_buf_size); + + /* LDP header */ + ldp_hdr->u_bit = 0x0; + ldp_hdr->msg_type = htons(MSG_T_CAPABILITY); + ldp_hdr->msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + ldp_hdr->msg_id = htonl(ICCP_MSG_ID++); + + /* LDP ICCP capability TLV */ + cap->icc_parameter.u_bit = 0x1; + cap->icc_parameter.f_bit = 0x0; + cap->icc_parameter.type = TLV_T_ICCP_CAPABILITY; + *(uint16_t *)cap = htons(*(uint16_t *)cap); + + cap->icc_parameter.len = htons(TLV_L_ICCP_CAPABILITY); + + cap->s_bit = csm->iccp_info.sender_capability_flag; + *(uint16_t *)((uint8_t *)cap + sizeof(ICCParameter)) = htons(*(uint16_t *)((uint8_t *)cap + sizeof(ICCParameter))); + + cap->major_ver = 0x1; + cap->minior_ver = 0x0; + + return msg_len; +} + +void iccp_csm_fill_icc_rg_id_tlv(struct CSM* csm, ICCHdr* icc_hdr) +{ + if (!csm || !icc_hdr) + return; + + icc_hdr->icc_rg_id_tlv.type = htons(TLV_T_ICC_RG_ID); + icc_hdr->icc_rg_id_tlv.len = htons(TLV_L_ICC_RG_ID); + icc_hdr->icc_rg_id_tlv.icc_rg_id = htonl(csm->iccp_info.icc_rg_id); +} + +/* ICCP NAK message handle function */ +int iccp_csm_prepare_nak_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + ICCHdr* icc_hdr = (ICCHdr*)buf; + NAKTLV* nak = (NAKTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(NAKTLV); + + memset(buf, 0, max_buf_size); + + /* ICC header */ + icc_hdr->ldp_hdr.u_bit = 0x0; + icc_hdr->ldp_hdr.msg_type = htons(MSG_T_NOTIFICATION); + icc_hdr->ldp_hdr.msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + icc_hdr->ldp_hdr.msg_id = htonl(ICCP_MSG_ID++); + iccp_csm_fill_icc_rg_id_tlv(csm, icc_hdr); + + /* NAL TLV */ + nak->icc_parameter.u_bit = 0x0; + nak->icc_parameter.f_bit = 0x0; + nak->icc_parameter.type = htons(TLV_T_NAK); + nak->icc_parameter.len = htons(sizeof(((struct NAKTLV*)0)->iccp_status_code) + sizeof(((struct NAKTLV*)0)->rejected_msg_id)); + + switch (csm->iccp_info.status_code) + { + case STATUS_CODE_U_ICCP_RG: + nak->iccp_status_code = htonl(csm->iccp_info.status_code); + nak->rejected_msg_id = htonl(csm->iccp_info.rejected_msg_id); + break; + + /* Unsupported */ + case STATUS_CODE_ICCP_CONNECTION_COUNT_EXCEEDED: + case STATUS_CODE_ICCP_APP_CONNECTION_COUNT_EXCEEDED: + case STATUS_CODE_ICCP_APP_NOT_IN_RG: + case STATUS_CODE_INCOMPATIBLE_ICCP_PROTOCOL_VER: + case STATUS_CODE_ICCP_REJECTED_MSG: + case STATUS_CODE_ICCP_ADMINISTRATIVELY_DISABLED: + case STATUS_CODE_ICCP_RG_REMOVED: + case STATUS_CODE_ICCP_APP_REMOVED_FROM_RG: + break; + } + + return msg_len; +} + +/* ICCP RG connect handle function */ +int iccp_csm_prepare_rg_connect_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + ICCHdr* icc_hdr = (ICCHdr*)buf; + ICCSenderNameTLV* sender = (ICCSenderNameTLV*)&buf[sizeof(ICCHdr)]; + size_t name_len = strlen(csm->iccp_info.sender_name); + size_t msg_len = sizeof(ICCHdr) + sizeof(ICCParameter) + name_len; + + memset(buf, 0, max_buf_size); + + /* ICC header */ + icc_hdr->ldp_hdr.u_bit = 0x0; + icc_hdr->ldp_hdr.msg_type = htons(MSG_T_RG_CONNECT); + icc_hdr->ldp_hdr.msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + icc_hdr->ldp_hdr.msg_id = htonl(ICCP_MSG_ID++); + iccp_csm_fill_icc_rg_id_tlv(csm, icc_hdr); + + /* ICC sender name TLV */ + sender->icc_parameter.u_bit = 0x0; + sender->icc_parameter.f_bit = 0x0; + sender->icc_parameter.type = htons(TLV_T_ICC_SENDER_NAME); + sender->icc_parameter.len = htons(name_len); + memcpy(sender->sender_name, csm->iccp_info.sender_name, name_len); + + return msg_len; +} + +/* ICCP RG disconnect handle function */ +int iccp_csm_prepare_rg_disconnect_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + ICCHdr* icc_hdr = (ICCHdr*)buf; + DisconnectCodeTLV* disconn_code = (DisconnectCodeTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(DisconnectCodeTLV); + + memset(buf, 0, max_buf_size); + + /* ICC header */ + icc_hdr->ldp_hdr.u_bit = 0x0; + icc_hdr->ldp_hdr.msg_type = htons(MSG_T_RG_DISCONNECT); + icc_hdr->ldp_hdr.msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + icc_hdr->ldp_hdr.msg_id = htonl(ICCP_MSG_ID++); + iccp_csm_fill_icc_rg_id_tlv(csm, icc_hdr); + + /* Disconnect code TLV */ + disconn_code->icc_parameter.u_bit = 0x0; + disconn_code->icc_parameter.f_bit = 0x0; + disconn_code->icc_parameter.type = htons(TLV_T_DISCONNECT_CODE); + disconn_code->icc_parameter.len = htons(sizeof(((struct DisconnectCodeTLV*)0)->iccp_status_code)); + disconn_code->iccp_status_code = htonl(csm->iccp_info.status_code); + + return msg_len; +} + +/* Check ID(MC-LAG ID, mLACP ID, RG ID) from received message */ +static void iccp_csm_check_id_from_msg(struct CSM* csm, struct Msg* msg) +{ + ICCHdr* icc_hdr = NULL; + + if (!csm || !msg || !msg->buf) + return; + + icc_hdr = (ICCHdr*)msg->buf; + + /* Capability Message doesn't have ICC RG ID TLV */ + if (icc_hdr->ldp_hdr.msg_type == MSG_T_CAPABILITY) + return; + + /* Check if received message ID same as local configuration */ + if (ntohl(icc_hdr->icc_rg_id_tlv.icc_rg_id) == csm->iccp_info.icc_rg_id) + { + if (csm->iccp_info.status_code == STATUS_CODE_U_ICCP_RG) + { + csm->iccp_info.status_code = 0x0; + csm->iccp_info.rejected_msg_id = 0x0; + } + } + else if (ntohl(icc_hdr->icc_rg_id_tlv.icc_rg_id) != csm->iccp_info.icc_rg_id) + { + csm->iccp_info.status_code = STATUS_CODE_U_ICCP_RG; + csm->iccp_info.rejected_msg_id = ntohl(icc_hdr->icc_rg_id_tlv.icc_rg_id); + } +} + +/* Receive message correspond function */ +void iccp_csm_correspond_from_msg(struct CSM* csm, struct Msg* msg) +{ + ICCHdr* icc_hdr = NULL; + + if (csm == NULL || msg == NULL || msg->buf == NULL) + return; + + icc_hdr = (ICCHdr*)msg->buf; + NAKTLV* nak = (NAKTLV*)( icc_hdr + sizeof(ICCHdr)); + iccp_csm_check_id_from_msg(csm, msg); + + if (icc_hdr->ldp_hdr.msg_type == MSG_T_CAPABILITY) + iccp_csm_correspond_from_capability_msg(csm, msg); + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_CONNECT) + iccp_csm_correspond_from_rg_connect_msg(csm, msg); + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_DISCONNECT) + iccp_csm_correspond_from_rg_disconnect_msg(csm, msg); + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_NOTIFICATION) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Received MSG_T_NOTIFICATION ,err status %s reason of %s", get_status_string(ntohl(nak->iccp_status_code)), get_status_string(csm->iccp_info.status_code)); + sleep(1); + } + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_APP_DATA) + { + ;// do nothing + } + else + { + ++csm->u_msg_in_count; + } + + free(msg->buf); + free(msg); +} + +/* Receive capability message correspond function */ +void iccp_csm_correspond_from_capability_msg(struct CSM* csm, struct Msg* msg) +{ + LDPICCPCapabilityTLV* cap = (LDPICCPCapabilityTLV*)&(msg->buf)[sizeof(LDPHdr)]; + + *(uint16_t *)cap = ntohs(*(uint16_t *)cap); + *(uint16_t *)((uint8_t *)cap + sizeof(ICCParameter)) = ntohs(*(uint16_t *)((uint8_t *)cap + sizeof(ICCParameter))); + + if (cap->icc_parameter.u_bit == 0x1 + && cap->icc_parameter.f_bit == 0x0 + && cap->icc_parameter.type == TLV_T_ICCP_CAPABILITY + && ntohs(cap->icc_parameter.len) == (TLV_L_ICCP_CAPABILITY) + && cap->s_bit == 1 + && cap->major_ver == 0x1 + && cap->minior_ver == 0x0) + { + csm->iccp_info.peer_capability_flag = 0x1; + } +} + +/* Receive RG connect message correspond function */ +void iccp_csm_correspond_from_rg_connect_msg(struct CSM* csm, struct Msg* msg) +{ + ICCSenderNameTLV* sender = (ICCSenderNameTLV*)&(msg->buf)[sizeof(ICCHdr)]; + + *(uint16_t *)sender = ntohs(*(uint16_t *)sender); + + if (sender->icc_parameter.u_bit == 0x0 && + sender->icc_parameter.f_bit == 0x0 && + sender->icc_parameter.type == TLV_T_ICC_SENDER_NAME) + { + csm->iccp_info.peer_rg_connect_flag = 0x1; + } +} + +/* Receive RG disconnect message correspond function */ +void iccp_csm_correspond_from_rg_disconnect_msg(struct CSM* csm, struct Msg* msg) +{ + DisconnectCodeTLV* diconn_code = (DisconnectCodeTLV*)&(msg->buf)[sizeof(ICCHdr)]; + + *(uint16_t *)diconn_code = ntohs(*(uint16_t *)diconn_code); + + if (diconn_code->icc_parameter.u_bit == 0x0 + && diconn_code->icc_parameter.f_bit == 0x0 + && diconn_code->icc_parameter.type == TLV_T_DISCONNECT_CODE + && ntohs(diconn_code->icc_parameter.len) == (TLV_L_DISCONNECT_CODE) + && ntohl(diconn_code->iccp_status_code) == (STATUS_CODE_ICCP_RG_REMOVED)) + { + csm->iccp_info.sender_rg_connect_flag = 0x0; + csm->iccp_info.peer_rg_connect_flag = 0x0; + } +} + +/* Add received message into message list */ +void iccp_csm_enqueue_msg(struct CSM* csm, struct Msg* msg) +{ + ICCHdr* icc_hdr = NULL; + NAKTLV* naktlv = NULL; + int type = -1; + int i = 0; + + if (csm == NULL) + { + if (msg != NULL) + free(msg); + return; + } + + if (msg == NULL) + return; + + icc_hdr = (ICCHdr*)msg->buf; + + *(uint16_t *)icc_hdr = ntohs(*(uint16_t *)icc_hdr); + + if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_APP_DATA) + { + app_csm_enqueue_msg(csm, msg); + } + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_NOTIFICATION) + { + naktlv = (NAKTLV*)&msg->buf[sizeof(ICCHdr)]; + + for (i = 0; i < MAX_MSG_LOG_SIZE; ++i) + { + if (ntohl(naktlv->rejected_msg_id) == csm->msg_log.msg[i].msg_id) + { + type = csm->msg_log.msg[i].type; + break; + } + } + + if (type == MSG_T_RG_APP_DATA) + app_csm_enqueue_msg(csm, msg); + else + TAILQ_INSERT_TAIL(&(csm->msg_list), msg, tail); + } + else + { + TAILQ_INSERT_TAIL(&(csm->msg_list), msg, tail); + } +} + +/* Get received message from message list */ +struct Msg* iccp_csm_dequeue_msg(struct CSM* csm) +{ + struct Msg* msg = NULL; + + if (!TAILQ_EMPTY(&(csm->msg_list))) + { + msg = TAILQ_FIRST(&(csm->msg_list)); + TAILQ_REMOVE(&(csm->msg_list), msg, tail); + + } + + return msg; +} + +/* Message initialization */ +int iccp_csm_init_msg(struct Msg** msg, char* data, int len) +{ + struct Msg* iccp_msg = NULL; + + if (msg == NULL) + return -2; + + if (data == NULL || len <= 0) + return MCLAG_ERROR; + + iccp_msg = (struct Msg*)malloc(sizeof(struct Msg)); + if (iccp_msg == NULL) + goto err_ret; + + iccp_msg->buf = (char*)malloc(len); + if (iccp_msg->buf == NULL) + goto err_ret; + + memcpy(iccp_msg->buf, data, len); + iccp_msg->len = len; + *msg = iccp_msg; + + return 0; + + err_ret: + if (iccp_msg) + { + if (iccp_msg->buf) + free(iccp_msg->buf); + free(iccp_msg); + } + + return MCLAG_ERROR; +} + +void iccp_csm_stp_role_count(struct CSM *csm) +{ + /* decide the role, lower ip to be active & socket client*/ + if (csm->role_type == STP_ROLE_NONE) + { + if (inet_addr(csm->sender_ip) < inet_addr(csm->peer_ip)) + { + /* Active*/ + ICCPD_LOG_INFO(__FUNCTION__, "Role: [Active]"); + csm->role_type = STP_ROLE_ACTIVE; + } + else + { + /* Standby*/ + ICCPD_LOG_INFO(__FUNCTION__, "Role [Standby]"); + csm->role_type = STP_ROLE_STANDBY; + } + } +} \ No newline at end of file diff --git a/src/iccpd/src/iccp_ifm.c b/src/iccpd/src/iccp_ifm.c new file mode 100644 index 000000000000..cf874366b97b --- /dev/null +++ b/src/iccpd/src/iccp_ifm.c @@ -0,0 +1,762 @@ +/* + * iccp_ifm.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../include/system.h" +#include "../include/iccp_cli.h" +#include "../include/logger.h" +#include "../include/mlacp_sync_update.h" +#include "../include/mlacp_link_handler.h" +#include "../include/port.h" +#include "../include/iccp_netlink.h" + +#define fwd_neigh_state_valid(state) (state & (NUD_REACHABLE | NUD_STALE | NUD_DELAY | NUD_PROBE | NUD_PERMANENT)) + +#ifndef NDA_RTA +#define NDA_RTA(r) \ + ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) +#endif + +static int iccp_valid_handler(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + unsigned int event = 0; + + if (nlh->nlmsg_type != RTM_NEWLINK) + return 0; + + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newlink, &event) < 0) + ICCPD_LOG_ERR(__FUNCTION__, "Unknown message type."); + + return 0; +} + +/*Get kernel interfaces and ports during initialization*/ +int iccp_sys_local_if_list_get_init() +{ + struct System *sys = NULL; + struct nl_cb *cb; + struct nl_cb *orig_cb; + struct rtgenmsg rt_hdr = { + .rtgen_family = AF_UNSPEC, + }; + int ret; + int retry = 1; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + while (retry) + { + retry = 0; + ret = nl_send_simple(sys->route_sock, RTM_GETLINK, NLM_F_DUMP, + &rt_hdr, sizeof(rt_hdr)); + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "send netlink msg error."); + return ret; + } + + orig_cb = nl_socket_get_cb(sys->route_sock); + cb = nl_cb_clone(orig_cb); + nl_cb_put(orig_cb); + if (!cb) + { + ICCPD_LOG_ERR(__FUNCTION__, "nl cb clone error."); + return -ENOMEM; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_valid_handler, sys); + + ret = nl_recvmsgs(sys->route_sock, cb); + nl_cb_put(cb); + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "receive netlink msg error. ret = %d errno = %d ", ret, errno); + if (ret != -NLE_DUMP_INTR) + return ret; + retry = 1; + } + } + + return ret; +} + +static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int msgtype) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct ARPMsg *arp_msg = NULL, *arp_info = NULL; + struct VLAN_ID *vlan_id_list = NULL; + struct Msg *msg_send = NULL; + + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + + struct LocalInterface *lif_po = NULL, *arp_lif = NULL; + + int verify_arp = 0; + int arp_update = 0; + + if (!(sys = system_get_instance())) + return; + + /* Find local itf*/ + if (!(arp_lif = local_if_find_by_ifindex(ndm->ndm_ifindex))) + return; + + /* create ARP msg*/ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct ARPMsg); + arp_msg = (struct ARPMsg*)&buf; + arp_msg->op_type = ARP_SYNC_LIF; + sprintf(arp_msg->ifname, "%s", arp_lif->name); + if (tb[NDA_DST]) + memcpy(&arp_msg->ipv4_addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); + if (tb[NDA_LLADDR]) + memcpy(arp_msg->mac_addr, RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR])); + + arp_msg->ipv4_addr = ntohl(arp_msg->ipv4_addr); + + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP type %s, state (%04X)(%d) ifindex [%d] (%s) ip %s, mac [%02X:%02X:%02X:%02X:%02X:%02X]", + msgtype == RTM_NEWNEIGH ? "New":"Del", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state), + ndm->ndm_ifindex, arp_lif->name, + show_ip_str(htonl(arp_msg->ipv4_addr)), + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); + + /*Debug*/ + #if 0 + /* dump receive kernel ARP req*/ + fprintf(stderr, "\n======== Kernel ARP ==========\n"); + fprintf(stderr, " Type = [%d] (New=%d, Del=%d)\n", msgtype, RTM_NEWNEIGH, RTM_DELNEIGH); + fprintf(stderr, " State = (%04X)(%d)\n", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state)); + fprintf(stderr, " ifindex = [%d] (%s)\n", ndm->ndm_ifindex, arp_msg->ifname); + fprintf(stderr, " IP = [%s]\n", show_ip_str(htonl(arp_msg->ipv4_addr))); + fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], + arp_msg->mac_addr[4], arp_msg->mac_addr[5]); + fprintf(stderr, "==============================\n"); + #endif + + /* Find MLACP itf, member of port-channel*/ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (!local_if_is_l3_mode(lif_po)) + { + /* Is the L2 MLAG itf belong to a vlan?*/ + LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next) + { + if ( !(vlan_id_list->vlan_itf + && vlan_id_list->vlan_itf->ifindex == ndm->ndm_ifindex)) + continue; + break; + } + + if (!vlan_id_list) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled member port of vlan %s", + vlan_id_list->vlan_itf->name); + } + else + { + /* Is the ARP belong to a L3 mode MLAG itf?*/ + if (ndm->ndm_ifindex != lif_po->ifindex) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled intf %s", lif_po->name); + } + + verify_arp = 1; + + break; + } + + if (lif_po) + break; + } + + if (!(csm && lif_po)) + return; + if (!verify_arp) + return; + + /* update lif ARP*/ + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + arp_info = (struct ARPMsg*)msg->buf; + if (arp_info->ipv4_addr != arp_msg->ipv4_addr) + continue; + + if (msgtype == RTM_DELNEIGH) + { + /* delete ARP*/ + TAILQ_REMOVE(&MLACP(csm).arp_list, msg, tail); + free(msg->buf); + free(msg); + msg = NULL; + ICCPD_LOG_DEBUG(__FUNCTION__, "Delete ARP %s", show_ip_str(htonl(arp_msg->ipv4_addr))); + } + else + { + /* update ARP*/ + if (arp_info->op_type != arp_msg->op_type + || strcmp(arp_info->ifname, arp_msg->ifname) != 0 + || memcmp(arp_info->mac_addr, arp_msg->mac_addr, + ETHER_ADDR_LEN) != 0) + { + arp_update = 1; + arp_info->op_type = arp_msg->op_type; + sprintf(arp_info->ifname, "%s", arp_msg->ifname); + memcpy(arp_info->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update ARP for %s", show_ip_str(htonl(arp_msg->ipv4_addr))); + } + } + break; + } + + if (msg && !arp_update) + return; + + if (msgtype != RTM_DELNEIGH) + { + /* enquene lif_msg (add)*/ + if (!msg) + { + arp_msg->op_type = ARP_SYNC_LIF; + if (iccp_csm_init_msg(&msg, (char*)arp_msg, msg_len) == 0) + { + mlacp_enqueue_arp(csm, msg); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "ARP-list enqueue: %s, add %s", + arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP-list: %s, add %s", + arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr))); + } + + /* enqueue iccp_msg (add)*/ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + arp_msg->op_type = ARP_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[ADD] message for %s", + show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] message for %s", + show_ip_str(htonl(arp_msg->ipv4_addr))); + + } + } + else + { + /* enqueue iccp_msg (delete)*/ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + arp_msg->op_type = ARP_SYNC_DEL; + if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[DEL] message for %s", + show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[DEL] message for %s", + show_ip_str(htonl(arp_msg->ipv4_addr))); + + } + } + + /*Debug: dump for dequeue ARP Info*/ + #if 0 + fprintf(stderr, "\n======== ARP Info List ========\n"); + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + arp_msg = (struct ARPMsg*)msg->buf; + fprintf(stderr, "type %d,ifname %s , ip %s\n", arp_msg->op_type, arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr))); + } + fprintf(stderr, "==============================\n"); + #endif + + /*TEST dump for dequeue ARP message*/ + #if 0 + + while (MLACP(csm).arp_updated && !TAILQ_EMPTY(&(MLACP(csm).arp_msg_list))) + { + msg = TAILQ_FIRST(&(MLACP(csm).arp_msg_list)); + TAILQ_REMOVE(&(MLACP(csm).arp_msg_list), msg, tail); + arp_msg = (struct ARPMsg *)msg->buf; + fprintf(stderr, "\n======== Dequeue ARP ========\n"); + fprintf(stderr, " Type = [%d]\n", arp_msg->op_type); + fprintf(stderr, " State = (%04X)(%d)\n", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state)); + fprintf(stderr, " ifname = [%s]\n", arp_msg->ifname); + fprintf(stderr, " IP = [%s]\n", show_ip_str(arp_msg->ipv4_addr)); + fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], + arp_msg->mac_addr[4], arp_msg->mac_addr[5]); + fprintf(stderr, "==============================\n"); + free(msg->buf); + free(msg); + } + + MLACP(csm).arp_updated = 0; + #endif + + return; +} + +void ifm_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len) +{ + while (RTA_OK(rta, len)) + { + if (rta->rta_type <= max) + tb[rta->rta_type] = rta; + rta = RTA_NEXT(rta, len); + } +} + +int do_one_neigh_request(struct nlmsghdr *n) +{ + struct ndmsg *ndm = NLMSG_DATA(n); + int len = n->nlmsg_len; + struct rtattr * tb[NDA_MAX + 1]; + + if (n->nlmsg_type == NLMSG_DONE) + { + return 0; + } + + /* process msg_type RTM_NEWNEIGH, RTM_GETNEIGH, RTM_DELNEIGH */ + if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH ) + return(0); + + len -= NLMSG_LENGTH(sizeof(*ndm)); + if (len < 0) + return MCLAG_ERROR; + + ifm_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len); + + if (n->nlmsg_type == RTM_NEWNEIGH + && (ndm->ndm_state == NUD_INCOMPLETE + || ndm->ndm_state == NUD_FAILED + || ndm->ndm_state == NUD_NOARP + || ndm->ndm_state == NUD_PERMANENT + || ndm->ndm_state == NUD_NONE)) + { + return(0); + } + + if (!tb[NDA_DST] || ndm->ndm_type != RTN_UNICAST) + { + return(0); + } + + if (ndm->ndm_family == AF_INET) + { + do_arp_learn_from_kernel(ndm, tb, n->nlmsg_type); + } + + return(0); +} + +/*Handle arp received from kernel*/ +static int iccp_arp_valid_handler(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + + do_one_neigh_request(nlh); + + return 0; +} + +/*Get kernel arp information during initialization*/ +int iccp_arp_get_init() +{ + struct System *sys = NULL; + struct nl_cb *cb; + struct nl_cb *orig_cb; + struct rtgenmsg rt_hdr = { + .rtgen_family = AF_UNSPEC, + }; + int ret; + int retry = 1; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + while (retry) + { + retry = 0; + ret = nl_send_simple(sys->route_sock, RTM_GETNEIGH, NLM_F_DUMP, + &rt_hdr, sizeof(rt_hdr)); + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Send netlink msg error."); + return ret; + } + + orig_cb = nl_socket_get_cb(sys->route_sock); + cb = nl_cb_clone(orig_cb); + nl_cb_put(orig_cb); + if (!cb) + { + ICCPD_LOG_ERR(__FUNCTION__, "nl cb clone error."); + return -ENOMEM; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_arp_valid_handler, sys); + + ret = nl_recvmsgs(sys->route_sock, cb); + nl_cb_put(cb); + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Receive netlink msg error."); + if (ret != -NLE_DUMP_INTR) + return ret; + + retry = 1; + } + } + + return ret; +} + +/*When received ARP packets from kernel, update arp information*/ +void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, uint8_t mac_addr[ETHER_ADDR_LEN]) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct ARPMsg *arp_msg = NULL, *arp_info = NULL; + struct VLAN_ID *vlan_id_list = NULL; + struct Msg *msg_send = NULL; + + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + + struct LocalInterface *lif_po = NULL, *arp_lif = NULL; + + int verify_arp = 0; + + if (!(sys = system_get_instance())) + return; + + /* Find local itf*/ + if (!(arp_lif = local_if_find_by_ifindex(ifindex))) + return; + + /* create ARP msg*/ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct ARPMsg); + arp_msg = (struct ARPMsg*)&buf; + arp_msg->op_type = ARP_SYNC_LIF; + sprintf(arp_msg->ifname, "%s", arp_lif->name); + memcpy(&arp_msg->ipv4_addr, &addr, 4); + memcpy(arp_msg->mac_addr, mac_addr, 6); + + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP ifindex [%d] (%s) ip %s mac [%02X:%02X:%02X:%02X:%02X:%02X]", + ifindex, arp_lif->name, + show_ip_str(htonl(arp_msg->ipv4_addr)), + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); + /*Debug*/ + #if 0 + /* dump receive kernel ARP req*/ + fprintf(stderr, "\n======== Kernel ARP Update==========\n"); + fprintf(stderr, " Type = (New=%d)\n", RTM_NEWNEIGH); + fprintf(stderr, " ifindex = [%d] (%s)\n", ifindex, arp_lif->name); + fprintf(stderr, " IP = [%s]\n", show_ip_str(htonl(arp_msg->ipv4_addr))); + fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], + arp_msg->mac_addr[4], arp_msg->mac_addr[5]); + fprintf(stderr, "==============================\n"); + #endif + + /* Find MLACP itf, member of port-channel*/ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (!local_if_is_l3_mode(lif_po)) + { + /* Is the L2 MLAG itf belong to a vlan?*/ + LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next) + { + if ( !(vlan_id_list->vlan_itf + && vlan_id_list->vlan_itf->ifindex == ifindex)) + continue; + break; + } + + if (!vlan_id_list) + continue; + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled port %s of vlan %s", + lif_po->name, vlan_id_list->vlan_itf->name); + } + else + { + /* Is the ARP belong to a L3 mode MLAG itf?*/ + if (ifindex != lif_po->ifindex) + continue; + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled intf %s", lif_po->name); + } + + verify_arp = 1; + + break; + } + + if (lif_po) + break; + } + + if (!(csm && lif_po)) + return; + if (!verify_arp) + return; + + if (iccp_check_if_addr_from_netlink(AF_INET, &addr, arp_lif)) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP %s is identical with the ip address of interface %s", + show_ip_str(htonl(arp_msg->ipv4_addr)), arp_lif->name); + return; + } + + /* update lif ARP*/ + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + arp_info = (struct ARPMsg*)msg->buf; + if (arp_info->ipv4_addr != arp_msg->ipv4_addr) + continue; + + /* update ARP*/ + if (arp_info->op_type != arp_msg->op_type + || strcmp(arp_info->ifname, arp_msg->ifname) != 0 + || memcmp(arp_info->mac_addr, arp_msg->mac_addr, + ETHER_ADDR_LEN) != 0) + { + arp_info->op_type = arp_msg->op_type; + sprintf(arp_info->ifname, "%s", arp_msg->ifname); + memcpy(arp_info->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update ARP for %s", + show_ip_str(htonl(arp_msg->ipv4_addr))); + } + break; + } + + /* enquene lif_msg (add)*/ + if (!msg) + { + arp_msg->op_type = ARP_SYNC_LIF; + if (iccp_csm_init_msg(&msg, (char*)arp_msg, msg_len) == 0) + { + mlacp_enqueue_arp(csm, msg); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "ARP-list enqueue: %s, add %s", + arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP-list: %s, add %s", + arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr))); + } + + /* enqueue iccp_msg (add)*/ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + arp_msg->op_type = ARP_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[ADD] for %s", + show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] message for %s", + show_ip_str(htonl(arp_msg->ipv4_addr))); + } + + return; +} + +void iccp_from_netlink_port_state_handler( char * ifname, int state) +{ + struct CSM *csm = NULL; + struct LocalInterface *lif_po = NULL; + struct System *sys; + int po_is_active = 0; + + if ((sys = system_get_instance()) == NULL) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to obtain System instance."); + return; + } + + po_is_active = (state == PORT_STATE_UP); + + /* traverse all CSM */ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + /*If peer-link changes to down or up */ + if (strcmp(ifname, csm->peer_itf_name) == 0) + { + if (po_is_active == 0) + mlacp_peerlink_down_handler(csm); + else + mlacp_peerlink_up_handler(csm); + + break; + } + + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type == IF_T_PORT_CHANNEL && strncmp(lif_po->name, ifname, MAX_L_PORT_NAME) == 0) + { + mlacp_portchannel_state_handler(csm, lif_po, po_is_active); + } + } + } + + return; +} + +int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta, + int len, unsigned short flags) +{ + unsigned short type; + + memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); + + while (RTA_OK(rta, len)) + { + type = rta->rta_type & ~flags; + if ((type <= max) && (!tb[type])) + tb[type] = rta; + rta = RTA_NEXT(rta, len); + } + + return 0; +} + +int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) +{ + return parse_rtattr_flags(tb, max, rta, len, 0); +} + +void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n) +{ + struct LocalInterface *lif = NULL; + int msglen = 0; + + msglen = n->nlmsg_len; + + while (NLMSG_OK(n, msglen)) + { + struct ifinfomsg *ifm = NLMSG_DATA(n); + int len = n->nlmsg_len; + struct rtattr * tb[IFLA_MAX + 1]; + + if (n->nlmsg_type != RTM_NEWLINK) + { + return; + } + + len -= NLMSG_LENGTH(sizeof(*ifm)); + if (len < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "BUG: wrong nlmsg len %d\n", len); + return; + } + + if (ifm->ifi_family != AF_BRIDGE) + { + return; + } + + if ((lif = local_if_find_by_ifindex(ifm->ifi_index)) != NULL) + { + parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifm), len); + + /* if AF_SPEC isn't there, vlan table is not preset for this port */ + if (!tb[IFLA_AF_SPEC]) + { + ICCPD_LOG_WARN(__FUNCTION__, "Vlan table is not preset for %d", ifm->ifi_index); + return; + } + else + { + struct rtattr *i, *list = tb[IFLA_AF_SPEC]; + int rem = RTA_PAYLOAD(list); + struct VLAN_ID *vlan = NULL; + + /*set vlan flag is removed*/ + LIST_FOREACH(vlan, &(lif->vlan_list), port_next) + { + vlan->vlan_removed = 1; + } + + for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) + { + struct bridge_vlan_info *vinfo; + + if (i->rta_type != IFLA_BRIDGE_VLAN_INFO) + continue; + + vinfo = RTA_DATA(i); + + local_if_add_vlan(lif, vinfo->vid); + } + + /*After update vlan list, remove unused item*/ + LIST_FOREACH(vlan, &(lif->vlan_list), port_next) + { + if (vlan->vlan_removed == 1) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove %s from VLAN %d", lif->name, vlan->vid); + + LIST_REMOVE(vlan, port_next); + free(vlan); + } + } + } + } + + n = NLMSG_NEXT(n, msglen); + } +} \ No newline at end of file diff --git a/src/iccpd/src/iccp_main.c b/src/iccpd/src/iccp_main.c new file mode 100644 index 000000000000..86920f07e1fb --- /dev/null +++ b/src/iccpd/src/iccp_main.c @@ -0,0 +1,272 @@ +/* + * iccp_main.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include +#include +#include +#include + +#include "../include/cmd_option.h" +#include "../include/logger.h" +#include "../include/scheduler.h" +#include "../include/system.h" + +int check_instance(char* pid_file_path) +{ + int pid_file = 0; + int rc = 0; + + if (pid_file_path == NULL) + return MCLAG_ERROR; + + pid_file = open(pid_file_path, O_CREAT | O_RDWR, 0666); + if (pid_file <= 0 ) + { + fprintf(stderr, "Can't open a pid file. Terminate.\n"); + close(pid_file); + exit(EXIT_FAILURE); + } + + rc = flock(pid_file, LOCK_EX | LOCK_NB); + + if (rc) + { + if (errno == EWOULDBLOCK) + { + fprintf(stderr, "There is another instance running. Terminate.\n"); + close(pid_file); + exit(EXIT_FAILURE); + } + } + + return pid_file; +} + +void init_daemon(char* pid_file_path, int pid_file) +{ + pid_t pid, sid; + + pid = fork(); + if (pid < 0) + { + fprintf(stderr, "Failed to enter daemon mode: %s\n", strerror(errno)); + fprintf(stderr, "Please try to check your system resources.\n"); + close(pid_file); + unlink(pid_file_path); + exit(EXIT_FAILURE); + } + + if (pid > 0) + exit(EXIT_SUCCESS); + + umask(0); + sid = setsid(); + if (sid < 0) + { + fprintf(stderr, "Failed to create a new SID for this program: %s\n", strerror(errno)); + fprintf(stderr, "Please try to check your system resources.\n"); + close(pid_file); + unlink(pid_file_path); + exit(EXIT_FAILURE); + } + + freopen("/dev/null", "r", stdin); + freopen("/dev/null", "w", stdout); + freopen("/dev/null", "w", stderr); +} + +#ifndef ICCPD_RUN_DIR +#define ICCPD_RUN_DIR "/var/run/iccpd/" +#endif + +static inline int iccpd_make_rundir(void) +{ + int ret; + + ret = mkdir(ICCPD_RUN_DIR, 0755); + if (ret && errno != EEXIST) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to create directory \"%s\"", + ICCPD_RUN_DIR); + + return -errno; + } + + return 0; +} + +void iccpd_signal_handler(int sig) +{ + int err; + struct System* sys = NULL; + const char warmboot_flag = 'w'; + + sys = system_get_instance(); + if (!sys) + { + return; + } + + retry: + err = write(sys->sig_pipe_w, &warmboot_flag, 1); + if (err == -1 && errno == EINTR) + goto retry; + + return; +} + +static int iccpd_signal_init(struct System* sys) +{ + int fds[2]; + int err; + sigset_t ss; + struct sigaction sa; + struct epoll_event event; + + err = pipe(fds); + if (err) + return -errno; + + sys->sig_pipe_r = fds[0]; + sys->sig_pipe_w = fds[1]; + + if (sigemptyset(&ss) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "sigemptyset(): %d", errno); + goto close_pipe; + } + + if (sigaddset(&ss, SIGUSR1) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "sigaddset(): %d", errno); + goto close_pipe; + } + + if (sigprocmask(SIG_UNBLOCK, &ss, NULL) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "sigprocmask(): %d", errno); + goto close_pipe; + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = iccpd_signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + + if (sigaction(SIGUSR1, &sa, NULL) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "sigaction(): %d", errno); + goto close_pipe; + } + + event.data.fd = fds[0]; + event.events = EPOLLIN; + err = epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, fds[0], &event); + if (err) + { + goto close_pipe; + } + + FD_SET( fds[0], &(sys->readfd)); + sys->readfd_count++; + + return 0; + + close_pipe: + close(sys->sig_pipe_r); + close(sys->sig_pipe_w); + return err; +} + +int main(int argc, char* argv[]) +{ + int pid_file_fd = 0; + struct System* sys = NULL; + int err; + struct CmdOptionParser parser = CMD_OPTION_PARSER_INIT_VALUE; + + err = iccpd_make_rundir(); + if (err) + return 0; + + if (getuid() != 0) + { + fprintf(stderr, + "This program needs root permission to do device manipulation. " + "Please use sudo to execute it or change your user to root.\n"); + exit(EXIT_FAILURE); + } + + parser.init(&parser); + if (parser.parse(&parser, argc, argv) != 0) + { + parser.finalize(&parser); + return MCLAG_ERROR; + } + + pid_file_fd = check_instance(parser.pid_file_path); + if (pid_file_fd < 0) + { + fprintf(stderr, "Check instance with invalidate arguments, iccpd is terminated.\n"); + parser.finalize(&parser); + exit(EXIT_FAILURE); + } + + sys = system_get_instance(); + if (!sys) + { + fprintf(stderr, "Can't get a system instance, iccpd is terminated.\n"); + parser.finalize(&parser); + exit(EXIT_FAILURE); + } + + /*if(!parser.console_log) + init_daemon(parser.pid_file_path, pid_file_fd);*/ + + log_init(&parser); + + if (sys->log_file_path != NULL) + free(sys->log_file_path); + if (sys->cmd_file_path != NULL) + free(sys->cmd_file_path); + if (sys->config_file_path != NULL) + free(sys->config_file_path); + sys->log_file_path = strdup(parser.log_file_path); + sys->cmd_file_path = strdup(parser.cmd_file_path); + sys->config_file_path = strdup(parser.config_file_path); + sys->mclagdctl_file_path = strdup(parser.mclagdctl_file_path); + sys->pid_file_fd = pid_file_fd; + sys->telnet_port = parser.telnet_port; + parser.finalize(&parser); + iccpd_signal_init(sys); + ICCPD_LOG_INFO(__FUNCTION__, "Iccpd is started, process id = %d. uid %d ", getpid(), getuid()); + scheduler_init(); + scheduler_start(); + system_finalize(); + /*scheduler_finalize(); + log_finalize();*/ + + return EXIT_SUCCESS; +} diff --git a/src/iccpd/src/iccp_netlink.c b/src/iccpd/src/iccp_netlink.c new file mode 100644 index 000000000000..ec8971d0ceee --- /dev/null +++ b/src/iccpd/src/iccp_netlink.c @@ -0,0 +1,1545 @@ +/* + * iccp_netlink.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../include/system.h" +#include "../include/iccp_ifm.h" +#include "../include/port.h" +#include "../include/iccp_csm.h" +#include "../include/logger.h" +#include "../include/scheduler.h" +#include "../include/mlacp_link_handler.h" +#include "../include/msg_format.h" +/** + * SECTION: Netlink helpers + */ +/* \cond HIDDEN_SYMBOLS */ +#ifndef SOL_NETLINK +#define SOL_NETLINK 270 +#endif + +#define ARRAY_SIZE(array_name) (sizeof(array_name) / sizeof(array_name[0])) + +#ifndef NETLINK_BROADCAST_SEND_ERROR +#define NETLINK_BROADCAST_SEND_ERROR 0x4 +#endif + +static int iccp_ack_handler(struct nl_msg *msg, void *arg) +{ + bool *acked = arg; + + *acked = true; + + return NL_STOP; +} + +static int iccp_seq_check_handler(struct nl_msg *msg, void *arg) +{ + unsigned int *seq = arg; + struct nlmsghdr *hdr = nlmsg_hdr(msg); + + if (hdr->nlmsg_seq != *seq) + return NL_SKIP; + + return NL_OK; +} + +int iccp_send_and_recv(struct System *sys, struct nl_msg *msg, + int (*valid_handler)(struct nl_msg *, void *), + void *valid_data) +{ + int ret; + struct nl_cb *cb; + struct nl_cb *orig_cb; + bool acked; + unsigned int seq = sys->genric_sock_seq++; + int err; + + ret = nl_send_auto(sys->genric_sock, msg); + nlmsg_free(msg); + if (ret < 0) + return ret; + + orig_cb = nl_socket_get_cb(sys->genric_sock); + cb = nl_cb_clone(orig_cb); + nl_cb_put(orig_cb); + if (!cb) + return -ENOMEM; + + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, iccp_ack_handler, &acked); + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, iccp_seq_check_handler, &seq); + if (valid_handler) + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data); + + /* There is a bug in libnl. When implicit sequence number checking is in + * use the expected next number is increased when NLMSG_DONE is + * received. The ACK which comes after that correctly includes the + * original sequence number. However libnl is checking that number + * against the incremented one and therefore ack handler is never called + * and nl_recvmsgs finished with an error. To resolve this, custom + * sequence number checking is used here. + */ + + acked = false; + + while (!acked) + { + ret = nl_recvmsgs(sys->genric_sock, cb); + if (ret) + { + err = ret; + goto put_cb; + } + } + + err = 0; + put_cb: + nl_cb_put(cb); + return err; +} + +int iccp_get_portchannel_member_list_handler(struct nl_msg *msg, void * arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct nlattr *attrs[TEAM_ATTR_MAX + 1]; + struct nlattr *nl_port; + struct nlattr *port_attrs[TEAM_ATTR_PORT_MAX + 1]; + struct LocalInterface* lif = NULL; + struct LocalInterface* local_if_member = NULL; + struct CSM* csm; + int i; + uint32_t ifindex = 0; + struct System* sys = NULL; + struct LocalInterface* local_if = NULL; + char temp_buf[512]; + int len = 0; + + sys = system_get_instance(); + if (sys == NULL) + return 0; + + genlmsg_parse(nlh, 0, attrs, TEAM_ATTR_MAX, NULL); + + if (attrs[TEAM_ATTR_TEAM_IFINDEX]) + ifindex = nla_get_u32(attrs[TEAM_ATTR_TEAM_IFINDEX]); + + local_if = local_if_find_by_ifindex(ifindex); + + if (!local_if) + return NL_SKIP; + + if (local_if->type != IF_T_PORT_CHANNEL) + return NL_SKIP; + + csm = local_if->csm; + + if (csm) + { + if (!attrs[TEAM_ATTR_LIST_PORT]) + return NL_SKIP; + + nla_for_each_nested(nl_port, attrs[TEAM_ATTR_LIST_PORT], i) + { + uint32_t member_index; + + if (nla_parse_nested(port_attrs, TEAM_ATTR_PORT_MAX, nl_port, NULL)) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to parse nested attributes."); + return NL_SKIP; + } + + if (!port_attrs[TEAM_ATTR_PORT_IFINDEX]) + { + ICCPD_LOG_ERR(__FUNCTION__, "ifindex port attribute not found."); + return NL_SKIP; + } + + member_index = nla_get_u32(port_attrs[TEAM_ATTR_PORT_IFINDEX]); + + local_if_member = local_if_find_by_ifindex(member_index); + if (local_if_member == NULL) + { + + ICCPD_LOG_WARN(__FUNCTION__, "%s: Failed to find a port instance (%d).", + local_if->name, member_index); + continue; + } + + if (port_attrs[TEAM_ATTR_PORT_REMOVED] && local_if_member->po_id != -1) + { + local_if_member->po_id = -1; + mlacp_unbind_local_if(local_if_member); + } + else if ( local_if_member->po_id == -1) + { + local_if_member->po_id = local_if->po_id; + mlacp_bind_local_if(local_if->csm, local_if_member); + } + } + + memset(temp_buf, 0, 512); + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif->type == IF_T_PORT && lif->po_id == local_if->po_id) + { + if (strlen(temp_buf) != 0) + len += snprintf(temp_buf + len, 512 - len, "%s", ","); + + len += snprintf(temp_buf + len, 512 - len, "%s", lif->name); + } + } + + if (strcmp(temp_buf, local_if->portchannel_member_buf)) + { + memset(local_if->portchannel_member_buf, 0, 512); + memcpy(local_if->portchannel_member_buf, temp_buf, sizeof(local_if->portchannel_member_buf) - 1); + + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + /* portchannel member changed, update port isolate attribute*/ + update_peerlink_isolate_from_all_csm_lif(csm); + } + } + } + else /*peerlink portchannel */ + { + if (local_if->is_peer_link) + { + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (csm->peer_link_if == local_if ) + { + break; + } + } + + if (csm == NULL) + return 0; + + nla_for_each_nested(nl_port, attrs[TEAM_ATTR_LIST_PORT], i) + { + uint32_t member_index; + + if (nla_parse_nested(port_attrs, TEAM_ATTR_PORT_MAX, nl_port, NULL)) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to parse nested attributes."); + return NL_SKIP; + } + + if (!port_attrs[TEAM_ATTR_PORT_IFINDEX]) + { + ICCPD_LOG_WARN(__FUNCTION__, "ifindex port attribute not found."); + return NL_SKIP; + } + + member_index = nla_get_u32(port_attrs[TEAM_ATTR_PORT_IFINDEX]); + + local_if_member = local_if_find_by_ifindex(member_index); + if (local_if_member == NULL) + { + ICCPD_LOG_WARN(__FUNCTION__, "%s: Failed to find a port instance (%d).", + local_if->name, member_index); + continue; + } + + if (port_attrs[TEAM_ATTR_PORT_REMOVED] && local_if_member->po_id != -1) + { + local_if_member->po_id = -1; + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + /*link removed from portchannel, must be enabled mac learn*/ + set_peerlink_mlag_port_learn(local_if_member, 1); + } + + continue; + } + else if ( local_if_member->po_id == -1) + { + local_if_member->po_id = local_if->po_id; + + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + /*link add to portchannel, must be disabled mac learn*/ + set_peerlink_mlag_port_learn(local_if, 0); + } + } + } + + memset(temp_buf, 0, 512); + LIST_FOREACH(lif, &(sys->lif_list), system_next) + { + if (lif->type == IF_T_PORT && lif->po_id == local_if->po_id) + { + if (strlen(temp_buf) != 0) + len += snprintf(temp_buf + len, 512 - len, "%s", ","); + + len += snprintf(temp_buf + len, 512 - len, "%s", lif->name); + } + } + + if (strcmp(temp_buf, local_if->portchannel_member_buf)) + { + memset(local_if->portchannel_member_buf, 0, 512); + memcpy(local_if->portchannel_member_buf, temp_buf, sizeof(local_if->portchannel_member_buf) - 1); + #if 0 + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + /*peerlink portchannel member changed*/ + update_peerlink_isolate_from_all_csm_lif(csm); + } + #endif + } + } + } + + return 0; +} + +int iccp_genric_socket_team_family_get() +{ + struct System* sys = NULL; + int err = 0; + int grp_id = 0; + + if ((sys = system_get_instance()) == NULL ) + return MCLAG_ERROR; + if (sys->family < 0) + { + sys->family = genl_ctrl_resolve(sys->genric_sock, TEAM_GENL_NAME); + + while (sys->family < 0) + { + sleep(1); + + /*If no portchannel configuration, teamd will not started, genl_ctrl_resolve() will return <0 forever */ + /*Only log error message 5 times*/ + + ICCPD_LOG_ERR(__FUNCTION__, "Failed to resolve netlink family. %d of TEAM_GENL_NAME %s ", sys->family, TEAM_GENL_NAME); + sys->family = genl_ctrl_resolve(sys->genric_sock, TEAM_GENL_NAME); + + } + + grp_id = genl_ctrl_resolve_grp(sys->genric_sock, TEAM_GENL_NAME, + TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME); + if (grp_id < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to resolve netlink multicast groups. %d", grp_id); + } + + err = nl_socket_add_membership(sys->genric_event_sock, grp_id); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + + } + } + + return err; +} + +int iccp_get_port_member_list(struct LocalInterface* lif) +{ + struct System *sys; + struct nl_msg *msg; + int err; + + sys = system_get_instance(); + if (sys == NULL) + return 0; + + msg = nlmsg_alloc(); + if (!msg) + return -ENOMEM; + + err = iccp_genric_socket_team_family_get(); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "genric socket family get err err = %d . errno = %d", err, errno); + return err; + } + + genlmsg_put(msg, NL_AUTO_PID, sys->genric_sock_seq, sys->family, 0, 0, + TEAM_CMD_PORT_LIST_GET, 0); + nla_put_u32(msg, TEAM_ATTR_TEAM_IFINDEX, lif->ifindex); + + err = iccp_send_and_recv(sys, msg, iccp_get_portchannel_member_list_handler, lif); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "recv msg err err = %d . errno = %d", err, errno); + return err; + } + + return 0; +} + +int iccp_netlink_if_hwaddr_set(uint32_t ifindex, uint8_t *addr, unsigned int addr_len) +{ + struct rtnl_link *link; + int err; + struct nl_addr *nl_addr; + struct System* sys = NULL; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + link = rtnl_link_alloc(); + if (!link) + return -ENOMEM; + + nl_addr = nl_addr_build(AF_UNSPEC, (void *)addr, addr_len); + if (!nl_addr) + { + err = -ENOMEM; + goto errout; + } + + rtnl_link_set_ifindex(link, ifindex); + rtnl_link_set_addr(link, nl_addr); + + err = rtnl_link_change(sys->route_sock, link, link, 0); + + nl_addr_put(nl_addr); + + errout: + rtnl_link_put(link); + return err; +} + +#define SET_MAC_STR(buf, macArray) \ + snprintf(buf, 64, "%02x:%02x:%02x:%02x:%02x:%02x", \ + macArray[0], macArray[1], macArray[2], \ + macArray[3], macArray[4], macArray[5]); + +void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr ) +{ + struct IccpSyncdHDr * msg_hdr; + mclag_sub_option_hdr_t * sub_msg; + char msg_buf[4096]; + struct System *sys; + + int src_len = 0, dst_len = 0; + + sys = system_get_instance(); + if (sys == NULL) + return; + + memset(msg_buf, 0, 4095); + + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_SET_MAC; + msg_hdr->len = sizeof(struct IccpSyncdHDr); + + /*sub msg src*/ + sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len]; + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_SET_MAC_SRC; + + /*src_len = snprintf((char *)sub_msg->data, 512, "%s:%s/%d", lif->name,show_ip_str(htonl(lif->ipv4_addr)),lif->prefixlen);*/ + src_len = snprintf((char *)sub_msg->data, 512, "%s", lif->name); + + sub_msg->op_len = src_len; + + /*sub msg dst */ + msg_hdr->len += sub_msg->op_len; + msg_hdr->len += sizeof(mclag_sub_option_hdr_t); + sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len]; + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_SET_MAC_DST; + + dst_len = strlen(mac_addr); + memcpy(sub_msg->data, mac_addr, dst_len); + + ICCPD_LOG_DEBUG(__FUNCTION__, "If name %s ip %s mac %s", lif->name, show_ip_str(htonl(lif->ipv4_addr)), sub_msg->data); + + sub_msg->op_len = dst_len; + msg_hdr->len += sizeof(mclag_sub_option_hdr_t); + msg_hdr->len += sub_msg->op_len; + + /*send msg*/ + if (sys->sync_fd) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + return; +} + +void update_if_ipmac_on_standby(struct LocalInterface* lif_po) +{ + struct CSM* csm; + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + struct VLAN_ID *vlan = NULL; + + csm = lif_po->csm; + struct LocalInterface* lif_Bri; + char macaddr[64]; + int ret = 0; + + if (!csm) + return; + + if (lif_po->type != IF_T_PORT_CHANNEL) + return; + + if (csm->role_type != STP_ROLE_STANDBY) + { + return; + } + + if (memcmp(MLACP(csm).remote_system.system_id, null_mac, ETHER_ADDR_LEN) == 0) + return; + + /*Set new mac*/ + if (memcmp( lif_po->mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN) != 0) + { + /*Backup old sysmac*/ + memcpy(lif_po->mac_addr_ori, lif_po->mac_addr, ETHER_ADDR_LEN); + + ICCPD_LOG_DEBUG(__FUNCTION__, + "%s Change the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X].", + (csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active", + lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2], lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5], + MLACP(csm).remote_system.system_id[0], MLACP(csm).remote_system.system_id[1], MLACP(csm).remote_system.system_id[2], MLACP(csm).remote_system.system_id[3], MLACP(csm).remote_system.system_id[4], MLACP(csm).remote_system.system_id[5]); + + ret = iccp_netlink_if_hwaddr_set(lif_po->ifindex, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN); + if (ret != 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", lif_po->name, ret); + } + } + + /*Set portchannel ip mac */ + memset(macaddr, 0, 64); + SET_MAC_STR(macaddr, MLACP(csm).remote_system.system_id); + if (local_if_is_l3_mode(lif_po)) + { + if (memcmp(lif_po->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN) != 0) + { + iccp_set_interface_ipadd_mac(lif_po, macaddr ); + memcpy(lif_po->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN); + } + } + else + { + LIST_FOREACH(vlan, &(lif_po->vlan_list), port_next) + { + if (!vlan->vlan_itf) + continue; + + /*If the po is under a vlan, update vlan mac*/ + if (local_if_is_l3_mode(vlan->vlan_itf)) + { + if (memcmp(vlan->vlan_itf->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN) != 0) + { + ret = iccp_netlink_if_hwaddr_set(vlan->vlan_itf->ifindex, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN); + if (ret != 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret); + } + + iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr ); + memcpy(vlan->vlan_itf->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN); + } + } + } + } + + return; +} + +void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) +{ + struct CSM* csm; + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + struct VLAN_ID *vlan = NULL; + + csm = lif_po->csm; + char macaddr[64]; + int ret = 0; + + if (!csm) + return; + + if (lif_po->type != IF_T_PORT_CHANNEL) + return; + + if (csm->role_type != STP_ROLE_STANDBY) + { + return; + } + + /*Recover mac to origin mac, it is the 'mac' value in 'localhost' currently*/ + if (memcmp( lif_po->mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN) != 0) + { + ICCPD_LOG_DEBUG(__FUNCTION__, + "%s Recover the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X].", + (csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active", + lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2], lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5], + MLACP(csm).system_id[0], MLACP(csm).system_id[1], MLACP(csm).system_id[2], MLACP(csm).system_id[3], MLACP(csm).system_id[4], MLACP(csm).system_id[5]); + + ret = iccp_netlink_if_hwaddr_set(lif_po->ifindex, MLACP(csm).system_id, ETHER_ADDR_LEN); + if (ret != 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", lif_po->name, ret); + } + } + + /*Set portchannel ip mac */ + memset(macaddr, 0, 64); + SET_MAC_STR(macaddr, MLACP(csm).system_id); + if (local_if_is_l3_mode(lif_po)) + { + iccp_set_interface_ipadd_mac(lif_po, macaddr ); + memcpy(lif_po->l3_mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN); + } + else + { + LIST_FOREACH(vlan, &(lif_po->vlan_list), port_next) + { + if (!vlan->vlan_itf) + continue; + + /*If the po is under a vlan, update vlan mac*/ + if (local_if_is_l3_mode(vlan->vlan_itf)) + { + ret = iccp_netlink_if_hwaddr_set(vlan->vlan_itf->ifindex, MLACP(csm).system_id, ETHER_ADDR_LEN); + if (ret != 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret); + } + + iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr); + memcpy(vlan->vlan_itf->l3_mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN); + } + } + } + + return; +} + +void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg) +{ + struct rtnl_link *link; + unsigned int *event = arg; + uint32_t ifindex; + char * ifname, *p; + struct LocalInterface *lif = NULL; + struct nl_addr *nl_addr; + int addr_type = 0; + int op_state = 0; + int link_flag = 0; + + link = (struct rtnl_link *)obj; + ifindex = rtnl_link_get_ifindex(link); + op_state = rtnl_link_get_operstate(link); + ifname = rtnl_link_get_name(link); + nl_addr = rtnl_link_get_addr(link); + link_flag = rtnl_link_get_flags(link); + + if (nl_addr) + addr_type = nl_addr_guess_family(nl_addr); + + /*Vxlan tunnel dev name is like VTTNL0001-1000, VTTNL0001 is vxlan tunnel name, 1000 is vni*/ + /*If dev is vxlan tunnel, only create the tunnel with name no vni, like VTTNL0001*/ + if ((strncmp(ifname, VXLAN_TUNNEL_PREFIX, strlen(VXLAN_TUNNEL_PREFIX)) == 0)) + { + /*Change ifname from VTTNL0001-1000 to VTTNL0001*/ + if ((p = strchr(ifname, '-')) != NULL) + { + *p = '\0'; + } + /*Create vxlan tunnel dev, state is always UP*/ + lif = local_if_find_by_name(ifname); + if (!lif) + { + lif = local_if_create(ifindex, ifname, IF_T_VXLAN); + lif->state = PORT_STATE_UP; + } + return; + } + else + lif = local_if_find_by_ifindex(ifindex); + + if (!lif) + { + const itf_type_t if_whitelist[] = { + { PORTCHANNEL_PREFIX, IF_T_PORT_CHANNEL }, + { VLAN_PREFIX, IF_T_VLAN }, + { FRONT_PANEL_PORT_PREFIX, IF_T_PORT }, + { VXLAN_TUNNEL_PREFIX, IF_T_VXLAN }, + { NULL, 0 } + }; + int i = 0; + + for (i = 0; if_whitelist[i].ifname != NULL; ++i) + { + if ((strncmp(ifname, + if_whitelist[i].ifname, strlen(if_whitelist[i].ifname)) == 0)) + { + lif = local_if_create(ifindex, ifname, if_whitelist[i].type); + + lif->state = PORT_STATE_DOWN; + + if (IF_OPER_UP == op_state ) + { + lif->state = PORT_STATE_UP; + } + + switch (addr_type) + { + case AF_LLC: + memcpy( lif->mac_addr, nl_addr_get_binary_addr(nl_addr), ETHER_ADDR_LEN); + default: + break; + } + + break; + } + } + } + else /*update*/ + { + /*update*/ + if (lif->state == PORT_STATE_DOWN && op_state == IF_OPER_UP) + { + lif->state = PORT_STATE_UP; + /*if(lif->type ==IF_T_PORT_CHANNEL)*/ + ICCPD_LOG_NOTICE(__FUNCTION__, "Update local port %s state up", ifname); + + iccp_from_netlink_port_state_handler(lif->name, lif->state); + } + else if (lif->state == PORT_STATE_UP && ( IF_OPER_UP != op_state || !(link_flag & IFF_LOWER_UP))) + { + lif->state = PORT_STATE_DOWN; + /*if(lif->type ==IF_T_PORT_CHANNEL)*/ + ICCPD_LOG_NOTICE(__FUNCTION__, "Update local port %s state down", ifname); + + iccp_from_netlink_port_state_handler(lif->name, lif->state); + } + + switch (addr_type) + { + case AF_LLC: + if (memcmp(nl_addr_get_binary_addr(nl_addr), lif->mac_addr, ETHER_ADDR_LEN) != 0) + { + memcpy( lif->mac_addr, nl_addr_get_binary_addr(nl_addr), ETHER_ADDR_LEN); + lif->port_config_sync = 1; + } + + default: + break; + } + } + + return; +} + +void iccp_event_handler_obj_input_dellink(struct nl_object *obj, void *arg) +{ + struct rtnl_link *link; + struct LocalInterface *lif; + uint32_t ifindex; + + link = (struct rtnl_link *)obj; + + ifindex = rtnl_link_get_ifindex(link); + if ((lif = local_if_find_by_ifindex(ifindex)) != NULL) + local_if_destroy(lif->name); + + return; +} + +int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInterface *lif) +{ + struct + { + struct nlmsghdr nlh; + struct ifaddrmsg ifa; + } req; + + struct sockaddr_nl nladdr; + struct iovec iov; + struct msghdr msg = { + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + + int fd; + struct System *sys; + if ((sys = system_get_instance()) == NULL) + { + return 0; + } + + memset(&req, 0, sizeof(req)); + req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + req.nlh.nlmsg_type = RTM_GETADDR; + req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; + req.nlh.nlmsg_pid = 0; + req.nlh.nlmsg_seq = 0; + req.ifa.ifa_family = family; + + fd = nl_socket_get_fd(sys->route_sock); + send(fd, (void*)&req, sizeof(req), 0); + + char * buf = malloc(10000); + iov.iov_base = buf; + + while (1) + { + int status; + int msglen = 0; + iov.iov_len = 10000; + status = recvmsg(fd, &msg, 0); + + if (status < 0 || status == 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "netlink receive error (%d) status %d %d ", fd, status, errno); + free(buf); + return 0; + } + struct nlmsghdr *n = (struct nlmsghdr*)buf; + msglen = status; + + while (NLMSG_OK(n, msglen)) + { + if (n->nlmsg_type != RTM_NEWADDR) + { + free(buf); + return 0; + } + struct ifaddrmsg *ifa; + ifa = NLMSG_DATA(n); + if (lif && lif->ifindex == ifa->ifa_index) + { + struct rtattr *rth = IFA_RTA(ifa); + int rtl = IFA_PAYLOAD(n); + + while (rtl && RTA_OK(rth, rtl)) + { + if (rth->rta_type == IFA_ADDRESS || rth->rta_type == IFA_LOCAL) + { + if (family == AF_INET && ifa->ifa_family == AF_INET) + { + if (*(uint32_t *)addr == ntohl(*((uint32_t *)RTA_DATA(rth)))) + { + free(buf); + return 1; + } + } + + if (family == AF_INET6 && ifa->ifa_family == AF_INET6) + { + void *addr_netlink; + addr_netlink = RTA_DATA(rth); + if (!memcmp((uint8_t *)addr_netlink, addr, 16)) + { + free(buf); + return 1; + } + } + } + rth = RTA_NEXT(rth, rtl); + } + } + n = NLMSG_NEXT(n, msglen); + } + } + + free(buf); + + return 0; +} + +int iccp_local_if_addr_update(struct nl_msg *msg, void *arg) +{ + int len; + struct ifaddrmsg *ifa; + struct LocalInterface *lif; + + struct nlmsghdr *n = nlmsg_hdr(msg); + + if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) + return 0; + + ifa = NLMSG_DATA(n); + + if (ifa->ifa_family != AF_INET ) + return 0; + + lif = local_if_find_by_ifindex(ifa->ifa_index); + if (!lif) + { + return 0; + } + + if (n->nlmsg_type == RTM_DELADDR) + { + lif->ipv4_addr = 0; + lif->prefixlen = 0; + lif->l3_mode = 0; + memset(lif->l3_mac_addr, 0, ETHER_ADDR_LEN); + } + + len = n->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + if (len < 0) + return 0; + + struct rtattr *rth = IFA_RTA(ifa); + int rtl = IFA_PAYLOAD(n); + + while (rtl && RTA_OK(rth, rtl)) + { + if (rth->rta_type == IFA_ADDRESS) + { + uint32_t ipaddr = ntohl(*((uint32_t *)RTA_DATA(rth))); + lif->ipv4_addr = ipaddr; + lif->prefixlen = ifa->ifa_prefixlen; + lif->l3_mode = 1; + lif->port_config_sync = 1; + update_if_ipmac_on_standby(lif); + ICCPD_LOG_DEBUG(__FUNCTION__, "If name %s index %d ip %s", lif->name, lif->ifindex, show_ip_str(htonl(lif->ipv4_addr))); + } + rth = RTA_NEXT(rth, rtl); + } + + return 0; +} + +int iccp_sys_local_if_list_get_addr() +{ + struct System *sys = NULL; + struct nl_cb *cb; + struct nl_cb *orig_cb; + struct rtgenmsg rt_hdr = { + .rtgen_family = AF_UNSPEC, + }; + int ret; + int retry = 1; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + while (retry) + { + retry = 0; + ret = nl_send_simple(sys->route_sock, RTM_GETADDR, NLM_F_DUMP, + &rt_hdr, sizeof(rt_hdr)); + + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "send netlink msg error."); + return ret; + } + + orig_cb = nl_socket_get_cb(sys->route_sock); + cb = nl_cb_clone(orig_cb); + nl_cb_put(orig_cb); + if (!cb) + { + ICCPD_LOG_ERR(__FUNCTION__, "nl cb clone error."); + return -ENOMEM; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_local_if_addr_update, sys); + ret = nl_recvmsgs(sys->route_sock, cb); + nl_cb_put(cb); + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Receive netlink msg error, ret = %d errno = %d .", ret, errno); + if (ret != -NLE_DUMP_INTR) + return ret; + retry = 1; + } + } + + return ret; +} + +static int iccp_route_event_handler(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + unsigned int event = 1; + + switch (nlh->nlmsg_type) + { + case RTM_NEWLINK: + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newlink, &event) < 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_NEWLINK)"); + iccp_parse_if_vlan_info_from_netlink(nlh); + break; + + case RTM_DELLINK: + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_dellink, NULL) < 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_DELLINK)"); + break; + + case RTM_NEWNEIGH: + case RTM_DELNEIGH: + do_one_neigh_request(nlh); + break; + + case RTM_NEWADDR: + iccp_local_if_addr_update(msg, NULL); + break; + + default: + return NL_OK; + } + + return NL_STOP; +} + +/** + * SECTION: Context functions + */ +static int iccp_genric_event_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + + switch (gnlh->cmd) + { + case TEAM_CMD_PORT_LIST_GET: + return iccp_get_portchannel_member_list_handler(msg, NULL); + } + + return NL_SKIP; +} + +/*init netlink socket*/ +int iccp_system_init_netlink_socket() +{ + struct System* sys = NULL; + int val = 0; + int err = 0; + + if ((sys = system_get_instance()) == NULL ) + return MCLAG_ERROR; + + sys->genric_sock = nl_socket_alloc(); + if (!sys->genric_sock) + goto err_genric_sock_alloc; + + sys->genric_sock_seq = time(NULL); + err = genl_connect(sys->genric_sock); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to connect to netlink sock sys->genric_sock."); + goto err_genric_sock_connect; + } + + sys->genric_event_sock = nl_socket_alloc(); + if (!sys->genric_event_sock) + goto err_genric_event_sock_alloc; + + err = genl_connect(sys->genric_event_sock); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to connect to netlink sys->genric_event_sock."); + goto err_genric_event_sock_connect; + } + + sys->route_sock = nl_socket_alloc(); + if (!sys->route_sock) + goto err_route_sock_alloc; + err = nl_connect(sys->route_sock, NETLINK_ROUTE); + if (err) + goto err_route_sock_connect; + + err = nl_socket_set_buffer_size(sys->route_sock, 98304, 0); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink route event sock."); + goto err_route_sock_connect; + } + + sys->route_event_sock = nl_socket_alloc(); + if (!sys->route_event_sock) + goto err_route_event_sock_alloc; + + err = nl_connect(sys->route_event_sock, NETLINK_ROUTE); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to connect to netlink sys->route_event_sock. "); + goto err_route_event_sock_connect; + } + + err = nl_socket_set_buffer_size(sys->route_event_sock, 983040, 0); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink route event sock."); + goto err_route_event_sock_connect; + } + + val = NETLINK_BROADCAST_SEND_ERROR; + err = setsockopt(nl_socket_get_fd(sys->genric_event_sock), SOL_NETLINK, + NETLINK_BROADCAST_ERROR, &val, sizeof(val)); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed set NETLINK_BROADCAST_ERROR on netlink event sock."); + goto err_return; + } + + err = nl_socket_set_buffer_size(sys->genric_sock, 98304, 0); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink sock."); + goto err_return; + } + + err = nl_socket_set_buffer_size(sys->genric_event_sock, 98304, 0); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink event sock."); + goto err_return; + } +#if 0 + sys->family = genl_ctrl_resolve(sys->genric_sock, TEAM_GENL_NAME); + + while (sys->family < 0) + { + sleep(1); + log_err_period++; + /*If no portchannel configuration, teamd will not started, genl_ctrl_resolve() will return <0 forever */ + /*Only log error message 5 times*/ + if (log_err_period == 1 && log_err_time < 5) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to resolve netlink family. %d of TEAM_GENL_NAME %s ", sys->family, TEAM_GENL_NAME); + log_err_time++; + } + else + { + /*Log error message every 30s per time*/ + if (log_err_period == 30) + log_err_period = 0; + } + + sys->family = genl_ctrl_resolve(sys->genric_sock, TEAM_GENL_NAME); + } + + grp_id = genl_ctrl_resolve_grp(sys->genric_sock, TEAM_GENL_NAME, + TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME); + if (grp_id < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to resolve netlink multicast groups. %d", grp_id); + goto err_return; + } + + err = nl_socket_add_membership(sys->genric_event_sock, grp_id); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + goto err_return; + } +#endif + nl_socket_disable_seq_check(sys->genric_event_sock); + nl_socket_modify_cb(sys->genric_event_sock, NL_CB_VALID, NL_CB_CUSTOM, + iccp_genric_event_handler, sys); + + nl_socket_disable_seq_check(sys->route_event_sock); + nl_socket_modify_cb(sys->route_event_sock, NL_CB_VALID, NL_CB_CUSTOM, + iccp_route_event_handler, sys); + + err = nl_socket_add_membership(sys->route_event_sock, RTNLGRP_NEIGH); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + goto err_return; + } + + err = nl_socket_add_membership(sys->route_event_sock, RTNLGRP_LINK); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + goto err_return; + } + + err = nl_socket_add_membership(sys->route_event_sock, RTNLGRP_IPV4_IFADDR); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + goto err_return; + } + + /*receive arp packet socket*/ + sys->arp_receive_fd = socket(PF_PACKET, SOCK_DGRAM, 0); + if (sys->arp_receive_fd < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "socket error "); + goto err_return; + } + + if (1) + { + struct sockaddr_ll sll; + memset(&sll, 0, sizeof(sll)); + sll.sll_family = AF_PACKET; + sll.sll_protocol = htons(ETH_P_ARP); + sll.sll_ifindex = 0; + if (bind(sys->arp_receive_fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "socket bind error"); + goto err_return; + } + } + + goto succes_return; + + err_return: + + err_route_event_sock_connect: + nl_socket_free(sys->route_event_sock); + + err_route_sock_alloc: + err_route_sock_connect: + nl_socket_free(sys->route_sock); + + err_route_event_sock_alloc: + err_genric_event_sock_connect: + nl_socket_free(sys->genric_event_sock); + + err_genric_event_sock_alloc: + err_genric_sock_connect: + nl_socket_free(sys->genric_sock); + + return err; + + err_genric_sock_alloc: + + succes_return: + return 0; +} + +void iccp_system_dinit_netlink_socket() +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL ) + return; + + nl_socket_free(sys->route_event_sock); + nl_socket_free(sys->route_sock); + nl_socket_free(sys->genric_event_sock); + nl_socket_free(sys->genric_sock); + return; +} + +static int iccp_get_netlink_genic_sock_event_fd(struct System *sys) +{ + return nl_socket_get_fd(sys->genric_event_sock); +} + +static int iccp_netlink_genic_sock_event_handler(struct System *sys) +{ + int ret = 0; + + ret = nl_recvmsgs_default(sys->genric_event_sock); + if (ret) + { + sys->need_sync_team_again = 1; + ICCPD_LOG_DEBUG(__FUNCTION__, "genric_event_sock %d recvmsg error ret = %d ", nl_socket_get_fd(sys->genric_event_sock), ret); + } + + return ret; +} + +static int iccp_get_netlink_route_sock_event_fd(struct System *sys) +{ + return nl_socket_get_fd(sys->route_event_sock); +} + +static int iccp_get_receive_arp_packet_sock_fd(struct System *sys) +{ + return sys->arp_receive_fd; +} + +static int iccp_receive_arp_packet_handler(struct System *sys) +{ + unsigned char buf[1024]; + struct sockaddr_ll sll; + socklen_t sll_len = sizeof(sll); + struct arphdr *a = (struct arphdr*)buf; + int n; + unsigned int ifindex; + unsigned int addr; + uint8_t mac_addr[ETHER_ADDR_LEN]; + + n = recvfrom(sys->arp_receive_fd, buf, sizeof(buf), MSG_DONTWAIT, + (struct sockaddr*)&sll, &sll_len); + if (n < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "ARP recvfrom error: %s", buf); + return MCLAG_ERROR; + } + + /* Sanity checks */ + /*Only process ARPOP_REPLY*/ + if (n < sizeof(*a) || + a->ar_op != htons(ARPOP_REPLY) || + a->ar_pln != 4 || + a->ar_pro != htons(ETH_P_IP) || + a->ar_hln != sll.sll_halen || + sizeof(*a) + 2 * 4 + 2 * a->ar_hln > n) + return 0; + + ifindex = sll.sll_ifindex; + memcpy(mac_addr, (char*)(a + 1), ETHER_ADDR_LEN); + memcpy(&addr, (char*)(a + 1) + a->ar_hln, 4); + + do_arp_update_from_reply_packet(ifindex, ntohl(addr), mac_addr); + + return 0; +} + +void iccp_netlink_sync_again() +{ + struct System* sys = NULL; + struct LocalInterface* lif = NULL; + + if ((sys = system_get_instance()) == NULL ) + return; + + if (sys->need_sync_netlink_again) + { + sys->need_sync_netlink_again = 0; + + /*Get kernel interface and port */ + iccp_sys_local_if_list_get_init(); + } + + if (sys->need_sync_team_again) + { + sys->need_sync_team_again = 0; + + LIST_FOREACH(lif, &(sys->lif_list), system_next) + { + if (lif->type == IF_T_PORT_CHANNEL) + { + iccp_get_port_member_list(lif); + } + } + } + + return; +} + +static int iccp_netlink_route_sock_event_handler(struct System *sys) +{ + int ret = 0; + + ret = nl_recvmsgs_default(sys->route_event_sock); + + if (ret) + { + sys->need_sync_netlink_again = 1; + ICCPD_LOG_DEBUG(__FUNCTION__, "fd %d recvmsg error ret = %d errno = %d ", nl_socket_get_fd(sys->route_event_sock), ret, errno); + } + /*get netlink info again when error happens */ + if (ret == 0 && sys->need_sync_netlink_again == 1) + { + iccp_netlink_sync_again(); + } + + return ret; +} + +extern int iccp_get_receive_fdb_sock_fd(struct System *sys); +extern int iccp_receive_fdb_handler_from_syncd(struct System *sys); + +/* cond HIDDEN_SYMBOLS */ +struct iccp_eventfd +{ + int (*get_fd)(struct System* sys); + int (*event_handler)(struct System* sys); +}; +/* endcond */ + +static const struct iccp_eventfd iccp_eventfds[] = { + { + .get_fd = iccp_get_server_sock_fd, + .event_handler = scheduler_server_accept, + }, + { + .get_fd = iccp_get_netlink_genic_sock_event_fd, + .event_handler = iccp_netlink_genic_sock_event_handler, + }, + { + .get_fd = iccp_get_netlink_route_sock_event_fd, + .event_handler = iccp_netlink_route_sock_event_handler, + }, + { + .get_fd = iccp_get_receive_arp_packet_sock_fd, + .event_handler = iccp_receive_arp_packet_handler, + } +}; + +/* \cond HIDDEN_SYMBOLS */ +#define ICCP_EVENT_FDS_COUNT ARRAY_SIZE(iccp_eventfds) +/* \endcond */ +/* + @return fd. + * + **/ + +int iccp_get_eventfd_fd(struct System *sys) +{ + return sys->epoll_fd; +} + +int iccp_init_netlink_event_fd(struct System *sys) +{ + int efd; + int i; + struct epoll_event event; + int err; + + efd = epoll_create1(0); + if (efd == -1) + return -errno; + + for (i = 0; i < ICCP_EVENT_FDS_COUNT; i++) + { + int fd = iccp_eventfds[i].get_fd(sys); + + event.data.fd = fd; + event.events = EPOLLIN; + err = epoll_ctl(efd, EPOLL_CTL_ADD, fd, &event); + if (err == -1) + { + err = -errno; + goto close_efd; + } + } + + sys->epoll_fd = efd; + + return 0; + + close_efd: + close(efd); + + return err; +} + +/** + * + * @details Handler events which happened on event filedescriptor. + * + * @return Zero on success or negative number in case of an error. + **/ + +int iccp_handle_events(struct System * sys) +{ + struct epoll_event events[ICCP_EVENT_FDS_COUNT + sys->readfd_count]; + struct CSM* csm = NULL; + int nfds; + int n; + int i; + int err; + int max_nfds; + + max_nfds = ICCP_EVENT_FDS_COUNT + sys->readfd_count; + + nfds = epoll_wait(sys->epoll_fd, events, max_nfds, EPOLL_TIMEOUT_MSEC); + + /* Go over list of event fds and handle them sequentially */ + for (i = 0; i < nfds; i++) + { + for (n = 0; n < ICCP_EVENT_FDS_COUNT; n++) + { + const struct iccp_eventfd *eventfd = &iccp_eventfds[n]; + if (events[i].data.fd == eventfd->get_fd(sys)) + { + err = eventfd->event_handler(sys); + if (err) + ICCPD_LOG_INFO(__FUNCTION__, "Scheduler fd %d handler error %d !", events[i].data.fd, err ); + break; + } + } + + if (n < ICCP_EVENT_FDS_COUNT) + continue; + + if (events[i].data.fd == sys->sync_ctrl_fd) + { + int client_fd = mclagd_ctl_sock_accept(sys->sync_ctrl_fd); + if (client_fd > 0) + { + mclagd_ctl_interactive_process(client_fd); + close(client_fd); + } + continue; + } + + if (events[i].data.fd == sys->sync_fd) + { + iccp_receive_fdb_handler_from_syncd(sys); + + continue; + } + + if (events[i].data.fd == sys->sig_pipe_r) + { + iccp_receive_signal_handler(sys); + + continue; + } + + if (FD_ISSET(events[i].data.fd, &sys->readfd)) + { + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (csm->sock_fd == events[i].data.fd ) + { + scheduler_csm_read_callback(csm); + break; + } + } + } + } + + return 0; +} + diff --git a/src/iccpd/src/logger.c b/src/iccpd/src/logger.c new file mode 100644 index 000000000000..2c17610f7afc --- /dev/null +++ b/src/iccpd/src/logger.c @@ -0,0 +1,140 @@ +/* + * logger.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ +#include +#include +#include +#include + +#include "../include/cmd_option.h" +#include "../include/logger.h" + +static uint32_t _iccpd_log_level_map[] = +{ + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG, +}; + +char* log_level_to_string(int level) +{ + switch (level) + { + case CRITICAL_LOG_LEVEL: + return "CRITICAL"; + + case ERR_LOG_LEVEL: + return "ERROR"; + + case WARN_LOG_LEVEL: + return "WARN"; + + case NOTICE_LOG_LEVEL: + return "NOTICE"; + + case INFO_LOG_LEVEL: + return "INFO"; + + case DEBUG_LOG_LEVEL: + return "DEBUG"; + } + + return "INFO"; +} + +struct LoggerConfig* logger_get_configuration() +{ + static struct LoggerConfig config; + + if (config.init == 0) + { + config.console_log_enabled = 0; + config.log_level = NOTICE_LOG_LEVEL; + config.init = 1; + } + + return &config; +} + +void logger_set_configuration(int log_level) +{ + struct LoggerConfig* config = logger_get_configuration(); + + config->log_level = log_level; + config->init = 1; + + return; +} + +void log_init(struct CmdOptionParser* parser) +{ + struct LoggerConfig* config = logger_get_configuration(); + + config->console_log_enabled = parser->console_log; +} + +void log_finalize() +{ + /*do nothing*/ +} + +void write_log(const int level, const char* tag, const char* format, ...) +{ + struct LoggerConfig* config = logger_get_configuration(); + char buf[LOGBUF_SIZE]; + va_list args; + unsigned int prefix_len; + unsigned int avbl_buf_len; + unsigned int print_len; + +#if 0 + if (!config->console_log_enabled) + return; +#endif + + if (level > config->log_level) + return; + + prefix_len = snprintf(buf, LOGBUF_SIZE, "[%s.%s] ", tag, log_level_to_string(level)); + avbl_buf_len = LOGBUF_SIZE - prefix_len; + + va_start(args, format); + print_len = vsnprintf(buf + prefix_len, avbl_buf_len, format, args); + va_end(args); + + /* Since osal_vsnprintf doesn't always return the exact size written to the buffer, + * we must check if the user string length exceeds the remaing buffer size. + */ + if (print_len > avbl_buf_len) + { + print_len = avbl_buf_len; + } + + buf[prefix_len + print_len] = '\0'; + ICCPD_UTILS_SYSLOG(_iccpd_log_level_map[level], "%s", buf); + + return; +} + diff --git a/src/iccpd/src/mclagdctl/Makefile b/src/iccpd/src/mclagdctl/Makefile new file mode 100644 index 000000000000..5520da22cee2 --- /dev/null +++ b/src/iccpd/src/mclagdctl/Makefile @@ -0,0 +1,28 @@ + + +C = gcc +SOURCES = \ +mclagdctl.c + +OBJECTS = \ +mclagdctl.o + +HEADERS = \ +mclagdctl.h + +CFLAGS = -g -O2 -fstack-protector-strong -Wformat -Werror=format-security +LDFLAGS = +LDADD = + +all: mclagdctl + +%.o: %.c $(HEADERS) + +mclagdctl: $(OBJECTS) + $(CC) -o ./mclagdctl $(OBJECTS) $(LDFLAGS) + +.PHONY: clean +clean: + -rm -f $(OBJECTS) ./mclagdctl + + diff --git a/src/iccpd/src/mclagdctl/mclagdctl.c b/src/iccpd/src/mclagdctl/mclagdctl.c new file mode 100644 index 000000000000..7c5d7284066d --- /dev/null +++ b/src/iccpd/src/mclagdctl/mclagdctl.c @@ -0,0 +1,883 @@ +/* + /* Copyright(c) 2016-2019 Nephos. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: Jim Jiang from nephos + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mclagdctl.h" + +static int mclagdctl_sock_fd = -1; +char *mclagdctl_sock_path = "/var/run/iccpd/mclagdctl.sock"; + +/* + Already implemented command: + mclagdctl -i dump state + mclagdctl -i dump arp + mclagdctl -i dump mac + mclagdctl -i dump portlist local + mclagdctl -i dump portlist peer + */ + +static struct command_type command_types[] = +{ + { + .id = ID_CMDTYPE_D, + .name = "dump", + .enca_msg = NULL, + .parse_msg = NULL, + }, + { + .id = ID_CMDTYPE_D_S, + .parent_id = ID_CMDTYPE_D, + .info_type = INFO_TYPE_DUMP_STATE, + .name = "state", + .enca_msg = mclagdctl_enca_dump_state, + .parse_msg = mclagdctl_parse_dump_state, + }, + { + .id = ID_CMDTYPE_D_A, + .parent_id = ID_CMDTYPE_D, + .info_type = INFO_TYPE_DUMP_ARP, + .name = "arp", + .enca_msg = mclagdctl_enca_dump_arp, + .parse_msg = mclagdctl_parse_dump_arp, + }, + { + .id = ID_CMDTYPE_D_A, + .parent_id = ID_CMDTYPE_D, + .info_type = INFO_TYPE_DUMP_MAC, + .name = "mac", + .enca_msg = mclagdctl_enca_dump_mac, + .parse_msg = mclagdctl_parse_dump_mac, + }, + { + .id = ID_CMDTYPE_D_P, + .parent_id = ID_CMDTYPE_D, + .name = "portlist", + }, + { + .id = ID_CMDTYPE_D_P_L, + .parent_id = ID_CMDTYPE_D_P, + .info_type = INFO_TYPE_DUMP_LOCAL_PORTLIST, + .name = "local", + .enca_msg = mclagdctl_enca_dump_local_portlist, + .parse_msg = mclagdctl_parse_dump_local_portlist, + }, + { + .id = ID_CMDTYPE_D_P_P, + .parent_id = ID_CMDTYPE_D_P, + .info_type = INFO_TYPE_DUMP_PEER_PORTLIST, + .name = "peer", + .enca_msg = mclagdctl_enca_dump_peer_portlist, + .parse_msg = mclagdctl_parse_dump_peer_portlist, + }, + { + .id = ID_CMDTYPE_C, + .name = "config", + .enca_msg = NULL, + .parse_msg = NULL, + }, + { + .id = ID_CMDTYPE_C_L, + .parent_id = ID_CMDTYPE_C, + .info_type = INFO_TYPE_CONFIG_LOGLEVEL, + .name = "loglevel", + .enca_msg = mclagdctl_enca_config_loglevel, + .parse_msg = mclagdctl_parse_config_loglevel, + }, +}; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define COMMAND_TYPE_COUNT ARRAY_SIZE(command_types) + +int mclagdctl_sock_connect() +{ + struct sockaddr_un addr; + int addrlen = 0; + int ret = 0; + + if (mclagdctl_sock_fd >= 0) + return 0; + + if (strlen(mclagdctl_sock_path) <= 0) + return MCLAG_ERROR; + + mclagdctl_sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); + + if (mclagdctl_sock_fd < 0) + { + return MCLAG_ERROR; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s", mclagdctl_sock_path); + addrlen = sizeof(addr.sun_family) + strlen(mclagdctl_sock_path); + + if ((ret = connect(mclagdctl_sock_fd, (struct sockaddr*)&addr, addrlen)) < 0) + { + close(mclagdctl_sock_fd); + mclagdctl_sock_fd = -1; + return MCLAG_ERROR; + } + + return 0; +} + +void mclagdctl_sock_close() +{ + if (mclagdctl_sock_fd > 0) + { + close(mclagdctl_sock_fd); + mclagdctl_sock_fd = -1; + } + + return; +} + +int mclagdctl_sock_write(int fd, unsigned char *w_buf, int total_len) +{ + int write_len = 0; + int ret = 0; + + while (write_len < total_len) + { + ret = write(fd, w_buf + write_len, total_len - write_len); + if (ret <= 0) + { + return 0; + } + write_len += ret; + } + + return write_len; +} + +int mclagdctl_sock_read(int fd, unsigned char *r_buf, int total_len) +{ + int read_len = 0; + int ret = 0; + struct timeval tv = { 0 }; + fd_set read_fd; + + while (read_len < total_len) + { + FD_ZERO(&read_fd); + FD_SET(fd, &read_fd); + tv.tv_sec = 10; + tv.tv_usec = 0; + + switch ((ret = select(fd + 1, &read_fd, NULL, NULL, &tv))) + { + case -1: // error + fprintf(stdout, "Mclagdctl:Select return error:%s\n", strerror(errno)); + return MCLAG_ERROR; + + case 0: // timeout + fprintf(stdout, "Mclagdctl:Select timeout:%s\n", strerror(errno)); + return MCLAG_ERROR; + + default: + break; + } + + ret = read(fd, r_buf + read_len, total_len - read_len); + if (ret <= 0) + { + return MCLAG_ERROR; + } + read_len += ret; + } + + return read_len; +} + +int mclagdctl_enca_dump_state(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_STATE; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_dump_state(char *msg, int data_len) +{ + struct mclagd_state * state_info = NULL; + int len = 0; + int count = 0; + int pos = 0; + + len = sizeof(struct mclagd_state); + + for (; data_len >= len; data_len -= len, count++) + { + state_info = (struct mclagd_state*)(msg + len * count); + + fprintf(stdout, "%s: %s\n", "The MCLAG's keepalive is", state_info->keepalive ? "OK" : "ERROR"); + + if (state_info->mclag_id <= 0) + fprintf(stdout, "%s: %s\n", "Domain id", "Unknown"); + else + fprintf(stdout, "%s: %d\n", "Domain id", state_info->mclag_id); + + fprintf(stdout, "%s: %s\n", "Local Ip", state_info->local_ip); + fprintf(stdout, "%s: %s\n", "Peer Ip", state_info->peer_ip); + fprintf(stdout, "%s: %s\n", "Peer Link Interface", state_info->peer_link_if); + + fprintf(stdout, "%s: %02x:%02x:%02x:%02x:%02x:%02x \n", + "Peer Link Mac", + state_info->peer_link_mac[0], state_info->peer_link_mac[1], + state_info->peer_link_mac[2], state_info->peer_link_mac[3], + state_info->peer_link_mac[4], state_info->peer_link_mac[5]); + + if (state_info->role == 0) + fprintf(stdout, "%s: %s\n", "Role", "None"); + else if (state_info->role == 1) + fprintf(stdout, "%s: %s\n", "Role", "Active"); + else if (state_info->role == 2) + fprintf(stdout, "%s: %s\n", "Role", "Standby"); + + fprintf(stdout, "%s: %s\n", "MCLAG Interface", state_info->enabled_po); + + fprintf(stdout, "%s: %s\n", "Loglevel", state_info->loglevel); + } + + return 0; +} + +int mclagdctl_enca_dump_arp(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + if (mclag_id <= 0) + { + fprintf(stderr, "Need to specify mclag-id through the parameter i !\n"); + return MCLAG_ERROR; + } + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_ARP; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_dump_arp(char *msg, int data_len) +{ + struct mclagd_arp_msg * arp_info = NULL; + int len = 0; + int count = 0; + + fprintf(stdout, "%-6s", "No."); + fprintf(stdout, "%-20s", "IP"); + fprintf(stdout, "%-20s", "MAC"); + fprintf(stdout, "%-20s", "DEV"); + fprintf(stdout, "\n"); + + len = sizeof(struct mclagd_arp_msg); + + for (; data_len >= len; data_len -= len, count++) + { + arp_info = (struct mclagd_arp_msg*)(msg + len * count); + + fprintf(stdout, "%-6d", count + 1); + fprintf(stdout, "%-20s", arp_info->ipv4_addr); + fprintf(stdout, "%02x:%02x:%02x:%02x:%02x:%02x", + arp_info->mac_addr[0], arp_info->mac_addr[1], + arp_info->mac_addr[2], arp_info->mac_addr[3], + arp_info->mac_addr[4], arp_info->mac_addr[5]); + fprintf(stdout, " "); + fprintf(stdout, "%-20s", arp_info->ifname); + fprintf(stdout, "\n"); + } + + return 0; +} + +int mclagdctl_enca_dump_mac(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + if (mclag_id <= 0) + { + fprintf(stderr, "Need to specify mclag-id through the parameter i !\n"); + return MCLAG_ERROR; + } + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_MAC; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_dump_mac(char *msg, int data_len) +{ + struct mclagd_mac_msg * mac_info = NULL; + int len = 0; + int count = 0; + + fprintf(stdout, "%-60s\n", "TYPE: S-STATIC, D-DYNAMIC; AGE: L-Local age, P-Peer age"); + + fprintf(stdout, "%-6s", "No."); + fprintf(stdout, "%-5s", "TYPE"); + fprintf(stdout, "%-20s", "MAC"); + fprintf(stdout, "%-5s", "VID"); + fprintf(stdout, "%-20s", "DEV"); + fprintf(stdout, "%-20s", "ORIGIN-DEV"); + fprintf(stdout, "%-5s", "AGE"); + fprintf(stdout, "\n"); + + len = sizeof(struct mclagd_mac_msg); + + for (; data_len >= len; data_len -= len, count++) + { + mac_info = (struct mclagd_mac_msg*)(msg + len * count); + + fprintf(stdout, "%-6d", count + 1); + + if (mac_info->fdb_type == MAC_TYPE_STATIC_CTL) + fprintf(stdout, "%-5s", "S"); + else + fprintf(stdout, "%-5s", "D"); + + fprintf(stdout, "%-20s", mac_info->mac_str); + fprintf(stdout, "%-5d", mac_info->vid); + fprintf(stdout, "%-20s", mac_info->ifname); + fprintf(stdout, "%-20s", mac_info->origin_ifname); + + if ((mac_info->age_flag & MAC_AGE_LOCAL_CTL) && (mac_info->age_flag & MAC_AGE_PEER_CTL)) + fprintf(stdout, "%-5s", "LP"); + else if (mac_info->age_flag & MAC_AGE_LOCAL_CTL) + fprintf(stdout, "%-5s", "L"); + else if (mac_info->age_flag & MAC_AGE_PEER_CTL) + fprintf(stdout, "%-5s", "P"); + else + fprintf(stdout, "%-5s", " "); + fprintf(stdout, "\n"); + } + + return 0; +} + +int mclagdctl_enca_dump_local_portlist(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + if (mclag_id <= 0) + { + fprintf(stderr, "Need to specify mclag-id through the parameter i !\n"); + return MCLAG_ERROR; + } + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_LOCAL_PORTLIST; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_dump_local_portlist(char *msg, int data_len) +{ + struct mclagd_local_if * lif_info = NULL; + int len = 0; + int count = 0; + int pos = 0; + + len = sizeof(struct mclagd_local_if); + + for (; data_len >= len; data_len -= len, count++) + { + lif_info = (struct mclagd_local_if*)(msg + len * count); + + for (pos = 0; pos < 60; ++pos) + fprintf(stdout, "-"); + + fprintf(stdout, "\n"); + + if (memcmp(lif_info->type, "PortChannel", 11) == 0) + { + fprintf(stdout, "%s: %d\n", "Ifindex", lif_info->ifindex); + fprintf(stdout, "%s: %s\n", "Type", lif_info->type); + fprintf(stdout, "%s: %s\n", "PortName", lif_info->name); + fprintf(stdout, "%s: %02x:%02x:%02x:%02x:%02x:%02x \n", + "MAC", + lif_info->mac_addr[0], lif_info->mac_addr[1], + lif_info->mac_addr[2], lif_info->mac_addr[3], + lif_info->mac_addr[4], lif_info->mac_addr[5]); + + fprintf(stdout, "%s: %s\n", "IPv4Address", lif_info->ipv4_addr); + fprintf(stdout, "%s: %d\n", "Prefixlen", lif_info->prefixlen); + fprintf(stdout, "%s: %s\n", "State", lif_info->state); + fprintf(stdout, "%s: %s\n", "IsL3Interface", lif_info->l3_mode ? "Yes" : "No"); + /*fprintf(stdout, "%s: %s\n", "IsPeerlink", lif_info->is_peer_link ? "Yes" : "No");*/ + fprintf(stdout, "%s: %s\n", "MemberPorts", lif_info->portchannel_member_buf); + /*fprintf(stdout,"%s: %d\n" ,"PortchannelId", lif_info->po_id); + fprintf(stdout,"%s: %d\n" ,"PortchannelIsUp", lif_info->po_active); + fprintf(stdout,"%s: %s\n", "MlacpState", lif_info->mlacp_state);*/ + fprintf(stdout, "%s: %s\n", "IsIsolateWithPeerlink", lif_info->isolate_to_peer_link ? "Yes" : "No"); + fprintf(stdout, "%s: %s\n", "VlanList", lif_info->vlanlist); + } + else + { + fprintf(stdout, "%s: %d\n", "Ifindex", lif_info->ifindex); + fprintf(stdout, "%s: %s\n", "Type", lif_info->type); + fprintf(stdout, "%s: %s\n", "PortName", lif_info->name); + fprintf(stdout, "%s: %s\n", "State", lif_info->state); + /*fprintf(stdout,"%s: %d\n" ,"PortchannelId", lif_info->po_id);*/ + } + + for (pos = 0; pos < 60; ++pos) + fprintf(stdout, "-"); + + fprintf(stdout, "\n\n"); + } + + return 0; +} + +int mclagdctl_enca_dump_peer_portlist(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + if (mclag_id <= 0) + { + fprintf(stderr, "Need to specify mclag-id through the parameter i !\n"); + return MCLAG_ERROR; + } + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_PEER_PORTLIST; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_dump_peer_portlist(char *msg, int data_len) +{ + struct mclagd_peer_if * pif_info = NULL; + int len = 0; + int count = 0; + int pos = 0; + + len = sizeof(struct mclagd_peer_if); + + for (; data_len >= len; data_len -= len, count++) + { + pif_info = (struct mclagd_peer_if*)(msg + len * count); + + for (pos = 0; pos < 60; ++pos) + fprintf(stdout, "-"); + + fprintf(stdout, "\n"); + + fprintf(stdout, "%s: %d\n", "Ifindex", pif_info->ifindex); + fprintf(stdout, "%s: %s\n", "Type", pif_info->type); + fprintf(stdout, "%s: %s\n", "PortName", pif_info->name); + fprintf(stdout, "%s: %02x:%02x:%02x:%02x:%02x:%02x \n", + "MAC", + pif_info->mac_addr[0], pif_info->mac_addr[1], + pif_info->mac_addr[2], pif_info->mac_addr[3], + pif_info->mac_addr[4], pif_info->mac_addr[5]); + + fprintf(stdout, "%s: %s\n", "State", pif_info->state); + /*fprintf(stdout,"%s: %d\n" ,"PortchannelId", pif_info->po_id); + fprintf(stdout,"%s: %d\n" ,"PortchannelIsActive", pif_info->po_active);*/ + + for (pos = 0; pos < 60; ++pos) + fprintf(stdout, "-"); + + fprintf(stdout, "\n\n"); + } + + return 0; +} + +int mclagdctl_enca_config_loglevel(char *msg, int log_level, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_CONFIG_LOGLEVEL; + req.mclag_id = log_level; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_config_loglevel(char *msg, int data_len) +{ + + int ret = *(int*)msg; + + if (ret == 0) + fprintf(stdout, "%s\n", "Config loglevel success!"); + else + fprintf(stdout, "%s\n", "Config loglevel failed!"); + + return 0; +} + +static bool __mclagdctl_cmd_executable(struct command_type *cmd_type) +{ + if (!cmd_type->enca_msg || !cmd_type->parse_msg) + return 0; + + return 1; +} + +static int __mclagdctl_cmd_param_cnt(struct command_type *cmd_type) +{ + int i = 0; + + while (cmd_type->params[i]) + i++; + + return i; +} + +static struct command_type *__mclagdctl_get_cmd_by_parent(char *cmd_name, + enum id_command_type parent_id) +{ + int i; + + for (i = 0; i < COMMAND_TYPE_COUNT; i++) + { + if (!strncmp(command_types[i].name, cmd_name, strlen(cmd_name)) + && command_types[i].parent_id == parent_id) + return &command_types[i]; + } + + return NULL; +} + +static struct command_type *__mclagdctl_get_cmd_by_id(enum id_command_type id) +{ + int i; + + for (i = 0; i < COMMAND_TYPE_COUNT; i++) + { + if (command_types[i].id == id) + return &command_types[i]; + } + + return NULL; +} + +static int mclagdctl_find_cmd(struct command_type **pcmd_type, int *argc, char ***argv) +{ + char *cmd_name; + enum id_command_type parent_id = ID_CMDTYPE_NONE; + struct command_type *cmd_type; + + while (1) + { + if (!*argc) + { + fprintf(stderr, "None or incomplete command\n"); + return -EINVAL; + } + + cmd_name = *argv[0]; + (*argc)--; + (*argv)++; + cmd_type = __mclagdctl_get_cmd_by_parent(cmd_name, parent_id); + + if (!cmd_type) + { + fprintf(stderr, "Unknown command \"%s\".\n", cmd_name); + return -EINVAL; + } + + if (__mclagdctl_cmd_executable(cmd_type) && __mclagdctl_cmd_param_cnt(cmd_type) >= *argc) + { + *pcmd_type = cmd_type; + return 0; + } + + parent_id = cmd_type->id; + } +} + +static int mclagdctl_check_cmd_params(struct command_type *cmd_type, + int argc, char **argv) +{ + int i = 0; + + while (cmd_type->params[i]) + { + if (i == argc) + { + fprintf(stderr, "Command line parameter \"%s\" expected.\n", cmd_type->params[i]); + return -EINVAL; + } + i++; + } + + return 0; +} + +static void mclagdctl_print_cmd(struct command_type *cmd_type) +{ + if (cmd_type->parent_id != ID_CMDTYPE_NONE) + { + mclagdctl_print_cmd(__mclagdctl_get_cmd_by_id(cmd_type->parent_id)); + fprintf(stdout, " "); + } + fprintf(stdout, "%s", cmd_type->name); +} + +static void mclagdctl_print_help(const char *argv0) +{ + int i, j; + struct command_type *cmd_type; + + fprintf(stdout, "%s [options] command [command args]\n" + " -h --help Show this help\n" + " -i --mclag-id Specify one mclag id\n" + " -l --level Specify log level critical,err,warn,notice,info,debug\n", + argv0); + fprintf(stdout, "Commands:\n"); + + for (i = 0; i < COMMAND_TYPE_COUNT; i++) + { + cmd_type = &command_types[i]; + if (!__mclagdctl_cmd_executable(cmd_type)) + continue; + fprintf(stdout, " "); + mclagdctl_print_cmd(cmd_type); + + for (j = 0; cmd_type->params[j]; j++) + fprintf(stdout, " %s", cmd_type->params[j]); + + fprintf(stdout, "\n"); + } +} + +int main(int argc, char **argv) +{ + char buf[MCLAGDCTL_CMD_SIZE] = { 0 }; + char *argv0 = argv[0]; + char *rcv_buf = NULL; + static const struct option long_options[] = + { + { "help", no_argument, NULL, 'h' }, + { "mclag id", required_argument, NULL, 'i' }, + { "log level", required_argument, NULL, 'l' }, + { NULL, 0, NULL, 0 } + }; + int opt; + int err; + struct command_type *cmd_type; + int ret; + unsigned para_int = 0; + + int len = 0; + char *data; + struct mclagd_reply_hdr *reply; + + while ((opt = getopt_long(argc, argv, "hi:l:", long_options, NULL)) >= 0) + { + switch (opt) + { + case 'h': + mclagdctl_print_help(argv0); + return EXIT_SUCCESS; + + case 'i': + para_int = atoi(optarg); + break; + + case 'l': + switch (tolower(optarg[0])) + { + case 'c': + para_int = CRITICAL; + break; + + case 'e': + para_int = ERR; + break; + + case 'w': + para_int = WARN; + break; + + case 'n': + para_int = NOTICE; + break; + + case 'i': + para_int = INFO; + break; + + case 'd': + para_int = DEBUG; + break; + + default: + fprintf(stderr, "unknown option \"%c\".\n", opt); + mclagdctl_print_help(argv0); + return EXIT_FAILURE; + } + break; + + case '?': + fprintf(stderr, "unknown option.\n"); + mclagdctl_print_help(argv0); + return EXIT_FAILURE; + + default: + fprintf(stderr, "unknown option \"%c\".\n", opt); + mclagdctl_print_help(argv0); + return EXIT_FAILURE; + } + } + + argv += optind; + argc -= optind; + + err = mclagdctl_find_cmd(&cmd_type, &argc, &argv); + if (err) + { + mclagdctl_print_help(argv0); + return EXIT_FAILURE; + } + + err = mclagdctl_check_cmd_params(cmd_type, argc, argv); + if (err) + { + mclagdctl_print_help(argv0); + return EXIT_FAILURE; + } + + if (mclagdctl_sock_fd <= 0) + { + ret = mclagdctl_sock_connect(); + if (ret < 0) + return EXIT_FAILURE; + } + + if (cmd_type->enca_msg(buf, para_int, argc, argv) < 0) + { + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + ret = mclagdctl_sock_write(mclagdctl_sock_fd, buf, sizeof(struct mclagdctl_req_hdr)); + + if (ret <= 0) + { + fprintf(stderr, "Failed to send command to mclagd\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + /*read data length*/ + memset(buf, 0, MCLAGDCTL_CMD_SIZE); + ret = mclagdctl_sock_read(mclagdctl_sock_fd, buf, sizeof(int)); + if (ret <= 0) + { + fprintf(stderr, "Failed to read data length from mclagd\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + /*cont length*/ + len = *((int*)buf); + if (len <= 0) + { + ret = EXIT_FAILURE; + fprintf(stderr, "pkt len = %d, error\n", len); + goto mclagdctl_disconnect; + } + + rcv_buf = (char *)malloc(len); + if (!rcv_buf) + { + fprintf(stderr, "Failed to malloc rcv_buf for mclagdctl\n"); + goto mclagdctl_disconnect; + } + + /*read data*/ + ret = mclagdctl_sock_read(mclagdctl_sock_fd, rcv_buf, len); + if (ret <= 0) + { + fprintf(stderr, "Failed to read data from mclagd\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + reply = (struct mclagd_reply_hdr *)rcv_buf; + if (reply->info_type != cmd_type->info_type) + { + fprintf(stderr, "Reply info type from mclagd error\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + if (reply->exec_result == EXEC_TYPE_NO_EXIST_SYS) + { + fprintf(stderr, "No exist sys in iccpd!\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + if (reply->exec_result == EXEC_TYPE_NO_EXIST_MCLAGID) + { + fprintf(stderr, "Mclag-id %d hasn't been configured in iccpd!\n", para_int); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + if (reply->exec_result == EXEC_TYPE_FAILED) + { + fprintf(stderr, "exec error in iccpd!\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + cmd_type->parse_msg((char *)(rcv_buf + sizeof(struct mclagd_reply_hdr)), len - sizeof(struct mclagd_reply_hdr)); + + ret = EXIT_SUCCESS; + + mclagdctl_disconnect: + mclagdctl_sock_close(); + + if (rcv_buf) + free(rcv_buf); + + return ret; +} + diff --git a/src/iccpd/src/mclagdctl/mclagdctl.h b/src/iccpd/src/mclagdctl/mclagdctl.h new file mode 100644 index 000000000000..1b8c6f278cc5 --- /dev/null +++ b/src/iccpd/src/mclagdctl/mclagdctl.h @@ -0,0 +1,198 @@ +/* Copyright(c) 2016-2019 Nephos. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: Jim Jiang from nephos + */ + +#define MCLAGDCTL_PARA1_LEN 16 +#define MCLAGDCTL_PARA2_LEN 32 +#define MCLAGDCTL_PARA3_LEN 64 +#define MCLAGDCTL_CMD_SIZE 4096 + +#define MCLAGDCTL_MAX_L_PORT_NANE 32 +#define MCLAGDCTL_INET_ADDR_LEN 32 +#define MCLAGDCTL_ETHER_ADDR_LEN 6 +#define MCLAGDCTL_PORT_MEMBER_BUF_LEN 512 +#define ETHER_ADDR_STR_LEN 18 + +typedef int (*call_enca_msg_fun)(char *msg, int mclag_id, int argc, char **argv); +typedef int (*call_parse_msg_fun)(char *msg, int data_len); + +enum MAC_TYPE_CTL +{ + MAC_TYPE_STATIC_CTL = 1, + MAC_TYPE_DYNAMIC_CTL = 2, +}; + +enum MAC_AGE_TYPE_CTL +{ + MAC_AGE_LOCAL_CTL = 1, /*MAC in local switch is ageout*/ + MAC_AGE_PEER_CTL = 2 /*MAC in peer switch is ageout*/ +}; + +enum id_command_type +{ + ID_CMDTYPE_NONE = 0, + ID_CMDTYPE_D, + ID_CMDTYPE_D_S, + ID_CMDTYPE_D_A, + ID_CMDTYPE_D_P, + ID_CMDTYPE_D_P_L, + ID_CMDTYPE_D_P_P, + ID_CMDTYPE_C, + ID_CMDTYPE_C_L, +}; + +enum mclagdctl_notify_peer_type +{ + INFO_TYPE_NONE = 0, + INFO_TYPE_DUMP_STATE, + INFO_TYPE_DUMP_ARP, + INFO_TYPE_DUMP_MAC, + INFO_TYPE_DUMP_LOCAL_PORTLIST, + INFO_TYPE_DUMP_PEER_PORTLIST, + INFO_TYPE_CONFIG_LOGLEVEL, + INFO_TYPE_FINISH, +}; + +enum log_level_type +{ + CRITICAL = 0, + ERR= 1, + WARN = 2, + NOTICE= 3, + INFO = 4, + DEBUG = 5 +}; + +struct mclagdctl_req_hdr +{ + int info_type; + int mclag_id; + char para1[MCLAGDCTL_PARA2_LEN]; + char para2[MCLAGDCTL_PARA2_LEN]; + char para3[MCLAGDCTL_PARA2_LEN]; +}; + +struct mclagd_reply_hdr +{ + int info_type; + int data_len; + int exec_result; +}; + +#define EXEC_TYPE_SUCCESS -1 +#define EXEC_TYPE_NO_EXIST_SYS -2 +#define EXEC_TYPE_NO_EXIST_MCLAGID -3 +#define EXEC_TYPE_FAILED -4 + +#define MCLAG_ERROR -1 + +#define MCLAGD_REPLY_INFO_HDR (sizeof(struct mclagd_reply_hdr) + sizeof(int)) + +#define MCLAGDCTL_COMMAND_PARAM_MAX_CNT 8 +struct command_type +{ + enum id_command_type id; + enum id_command_type parent_id; + enum mclagdctl_notify_peer_type info_type; + char *name; + char *params[MCLAGDCTL_COMMAND_PARAM_MAX_CNT]; + call_enca_msg_fun enca_msg; + call_parse_msg_fun parse_msg; +}; + +struct mclagd_state +{ + int mclag_id; + int keepalive; + char local_ip[MCLAGDCTL_INET_ADDR_LEN]; + char peer_ip[MCLAGDCTL_INET_ADDR_LEN]; + char peer_link_if[MCLAGDCTL_MAX_L_PORT_NANE]; + unsigned char peer_link_mac[MCLAGDCTL_ETHER_ADDR_LEN]; + int role; + char enabled_po[MCLAGDCTL_PORT_MEMBER_BUF_LEN]; + char loglevel[MCLAGDCTL_PARA1_LEN]; +}; + +struct mclagd_arp_msg +{ + char op_type; + char ifname[MCLAGDCTL_MAX_L_PORT_NANE]; + char ipv4_addr[MCLAGDCTL_INET_ADDR_LEN]; + unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN]; +}; + +struct mclagd_mac_msg +{ + unsigned char op_type;/*add or del*/ + unsigned char fdb_type;/*static or dynamic*/ + char mac_str[ETHER_ADDR_STR_LEN]; + unsigned short vid; + /*Current if name that set in chip*/ + char ifname[MCLAGDCTL_MAX_L_PORT_NANE]; + /*if we set the mac to peer-link, origin_ifname store the + original if name that learned from chip*/ + char origin_ifname[MCLAGDCTL_MAX_L_PORT_NANE]; + unsigned char age_flag;/*local or peer is age?*/ +}; + +struct mclagd_local_if +{ + int ifindex; + char type[MCLAGDCTL_PARA1_LEN]; + char name[MCLAGDCTL_MAX_L_PORT_NANE]; + unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN]; + char state[MCLAGDCTL_PARA1_LEN]; + char ipv4_addr[MCLAGDCTL_INET_ADDR_LEN]; + unsigned char prefixlen; + + unsigned char l3_mode; + unsigned char is_peer_link; + char portchannel_member_buf[MCLAGDCTL_PORT_MEMBER_BUF_LEN]; + int po_id; /* Port Channel ID */ + unsigned char po_active; + char mlacp_state[MCLAGDCTL_PARA1_LEN]; + unsigned char isolate_to_peer_link; + + char vlanlist[MCLAGDCTL_PARA3_LEN]; +}; + +struct mclagd_peer_if +{ + int ifindex; + unsigned char type[MCLAGDCTL_PARA1_LEN]; + char name[MCLAGDCTL_MAX_L_PORT_NANE]; + unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN]; + unsigned char state[MCLAGDCTL_PARA1_LEN]; + int po_id; + unsigned char po_active; +}; + +extern int mclagdctl_enca_dump_state(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_parse_dump_state(char *msg, int data_len); +extern int mclagdctl_enca_dump_arp(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_parse_dump_arp(char *msg, int data_len); +extern int mclagdctl_enca_dump_mac(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_parse_dump_mac(char *msg, int data_len); +extern int mclagdctl_enca_dump_local_portlist(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_parse_dump_local_portlist(char *msg, int data_len); +extern int mclagdctl_enca_dump_peer_portlist(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_parse_dump_peer_portlist(char *msg, int data_len); +int mclagdctl_enca_config_loglevel(char *msg, int log_level, int argc, char **argv); +int mclagdctl_parse_config_loglevel(char *msg, int data_len); + diff --git a/src/iccpd/src/mlacp_fsm.c b/src/iccpd/src/mlacp_fsm.c new file mode 100644 index 000000000000..f479b75f36cc --- /dev/null +++ b/src/iccpd/src/mlacp_fsm.c @@ -0,0 +1,1209 @@ +/* + * mlacp_fsm.c + * mLACP finite state machine handler. + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include "../include/mlacp_tlv.h" +#include "../include/mlacp_sync_prepare.h" +#include "../include/mlacp_link_handler.h" +#include "../include/mlacp_sync_update.h" + +#include + +/***************************************** +* Define +* +* ***************************************/ +#define MLACP_MSG_QUEUE_REINIT(list) \ + { \ + struct Msg* msg = NULL; \ + while (!TAILQ_EMPTY(&(list))) { \ + msg = TAILQ_FIRST(&(list)); \ + TAILQ_REMOVE(&(list), msg, tail); \ + free(msg->buf); \ + free(msg); \ + } \ + TAILQ_INIT(&(list)); \ + } + +#define PIF_QUEUE_REINIT(list) \ + { \ + while (!LIST_EMPTY(&(list))) { \ + struct PeerInterface* peer_if = NULL; \ + peer_if = LIST_FIRST(&(list)); \ + LIST_REMOVE(peer_if, mlacp_next); \ + free(peer_if); \ + } \ + LIST_INIT(&(list)); \ + } + +#define LIF_QUEUE_REINIT(list) \ + { \ + while (!LIST_EMPTY(&(list))) { \ + struct LocalInterface* lif = NULL; \ + lif = LIST_FIRST(&(list)); \ + if (lif->type == IF_T_PORT_CHANNEL && lif->is_arp_accept) { \ + if ((set_sys_arp_accept_flag(lif->name, 0)) == 0) \ + lif->is_arp_accept = 0; \ + } \ + LIST_REMOVE (lif, mlacp_next); \ + } \ + LIST_INIT(&(list)); \ + } + +#define LIF_PURGE_QUEUE_REINIT(list) \ + { \ + while (!LIST_EMPTY(&(list))) { \ + struct LocalInterface* lif = NULL; \ + lif = LIST_FIRST(&(list)); \ + LIST_REMOVE(lif, mlacp_purge_next); \ + } \ + LIST_INIT(&(list)); \ + } + +#define WARM_REBOOT_TIMEOUT 90 + +/***************************************** +* Static Function +* +* ***************************************/ +static char *mlacp_state(struct CSM* csm); +static void mlacp_resync_arp(struct CSM* csm); +static void mlacp_resync_mac(struct CSM* csm); +/* Sync Sender APIs*/ +static void mlacp_sync_send_sysConf(struct CSM* csm); +static void mlacp_sync_send_aggConf(struct CSM* csm); +static void mlacp_sync_send_aggState(struct CSM* csm); +static void mlacp_sync_send_syncArpInfo(struct CSM* csm); +static void mlacp_sync_send_heartbeat(struct CSM* csm); +static void mlacp_sync_send_syncDoneData(struct CSM* csm); +/* Sync Reciever APIs*/ +static void mlacp_sync_recv_sysConf(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_portConf(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_portPrio(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_portState(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_aggConf(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_aggState(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_syncData(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_syncReq(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_portChanInfo(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_peerLlinkInfo(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_arpInfo(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_stpInfo(struct CSM* csm, struct Msg* msg); + +/* Sync Handler*/ +static void mlacp_sync_send_nak_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_nak_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_sender_handler(struct CSM* csm); +static void mlacp_sync_receiver_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_send_all_info_handler(struct CSM* csm); + +/* Sync State Handler*/ +static void mlacp_stage_sync_send_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_stage_sync_request_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_stage_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg); + +/****************************************************************** + * Sync Sender APIs + * + *****************************************************************/ +static void mlacp_sync_send_sysConf(struct CSM* csm) +{ + int msg_len = 0; + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_sys_config(csm, g_csm_buf, CSM_BUFFER_SIZE); + if (msg_len > 0) + iccp_csm_send(csm, g_csm_buf, msg_len); + else + ICCPD_LOG_WARN(__FUNCTION__, "Invalid sysconf packet."); + + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] SysConf, len=[%d]", msg_len);*/ + + return; +} + +static void mlacp_sync_send_aggConf(struct CSM* csm) +{ + struct System* sys = NULL; + int msg_len = 0; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_Aggport_config(csm, g_csm_buf, CSM_BUFFER_SIZE, local_if, 0); + iccp_csm_send(csm, g_csm_buf, msg_len); + local_if->port_config_sync = 0; + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] PortChannel, csm-if-name=[%s], len=[%d]", local_if->name, msg_len);*/ + } + } + + return; +} + +static void mlacp_sync_send_aggState(struct CSM* csm) +{ + struct System* sys = NULL; + int msg_len = 0; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_Aggport_state(csm, g_csm_buf, CSM_BUFFER_SIZE, local_if); + iccp_csm_send(csm, g_csm_buf, msg_len); + local_if->changed = 0; + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] PortChannel, csm-if-name=[%s], len=[%d]", local_if->name, msg_len);*/ + } + } + + return; +} +#define MAX_MAC_ENTRY_NUM 30 +#define MAX_ARP_ENTRY_NUM 40 +static void mlacp_sync_send_syncMacInfo(struct CSM* csm) +{ + int msg_len = 0; + struct Msg* msg = NULL; + int count = 0; + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + + while (!TAILQ_EMPTY(&(MLACP(csm).mac_msg_list))) + { + msg = TAILQ_FIRST(&(MLACP(csm).mac_msg_list)); + TAILQ_REMOVE(&(MLACP(csm).mac_msg_list), msg, tail); + msg_len = mlacp_prepare_for_mac_info_to_peer(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct MACMsg*)msg->buf, count); + count++; + free(msg->buf); + free(msg); + if (count >= MAX_MAC_ENTRY_NUM) + { + iccp_csm_send(csm, g_csm_buf, msg_len); + count = 0; + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + } + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] MacInfo,len=[%d]", msg_len);*/ + } + + if (count) + iccp_csm_send(csm, g_csm_buf, msg_len); + + return; +} + +static void mlacp_sync_send_syncArpInfo(struct CSM* csm) +{ + int msg_len = 0; + struct Msg* msg = NULL; + int count = 0; + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + + while (!TAILQ_EMPTY(&(MLACP(csm).arp_msg_list))) + { + msg = TAILQ_FIRST(&(MLACP(csm).arp_msg_list)); + TAILQ_REMOVE(&(MLACP(csm).arp_msg_list), msg, tail); + + msg_len = mlacp_prepare_for_arp_info(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct ARPMsg*)msg->buf, count); + count++; + free(msg->buf); + free(msg); + if (count >= MAX_ARP_ENTRY_NUM) + { + iccp_csm_send(csm, g_csm_buf, msg_len); + count = 0; + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + } + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] ArpInfo,len=[%d]", msg_len);*/ + } + + if (count) + iccp_csm_send(csm, g_csm_buf, msg_len); + + return; +} + +static void mlacp_sync_send_syncPortChannelInfo(struct CSM* csm) +{ + struct System* sys = NULL; + int msg_len = 0; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_port_channel_info(csm, g_csm_buf, CSM_BUFFER_SIZE, local_if); + iccp_csm_send(csm, g_csm_buf, msg_len); + local_if->changed = 0; + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] PortChannel, csm-if-name=[%s], len=[%d]", local_if->name, msg_len);*/ + } + } + + return; +} + +static void mlacp_sync_send_syncPeerLinkInfo(struct CSM* csm) +{ + struct System* sys = NULL; + int msg_len = 0; + + if ((sys = system_get_instance()) == NULL) + return; + + if (csm->peer_link_if) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_port_peerlink_info(csm, g_csm_buf, CSM_BUFFER_SIZE, csm->peer_link_if); + iccp_csm_send(csm, g_csm_buf, msg_len); + } + + return; +} + +static void mlacp_sync_send_heartbeat(struct CSM* csm) +{ + int msg_len = 0; + + if ((csm->heartbeat_send_time == 0) || + ((time(NULL) - csm->heartbeat_send_time) > 1)) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_heartbeat(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, msg_len); + time(&csm->heartbeat_send_time); + } + + return; +} + +static void mlacp_sync_send_syncDoneData(struct CSM* csm) +{ + int msg_len = 0; + + /*Sync done & go to next stage*/ + MLACP(csm).wait_for_sync_data = 0; + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_sync_data_tlv(csm, g_csm_buf, CSM_BUFFER_SIZE, 1); + iccp_csm_send(csm, g_csm_buf, msg_len); + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] SyncDone, len=[%d]", msg_len);*/ + + return; +} + +/****************************************************************** + * Sync Receiver APIs + * + *****************************************************************/ +static void mlacp_sync_recv_sysConf(struct CSM* csm, struct Msg* msg) +{ + mLACPSysConfigTLV* sysconf = NULL; + + sysconf = (mLACPSysConfigTLV*)&(msg->buf[sizeof(ICCHdr)]); + + if (mlacp_fsm_update_system_conf(csm, sysconf) == MCLAG_ERROR) + { + /*NOTE: we just change the node ID local side without sending NAK msg*/ + ICCPD_LOG_DEBUG(__FUNCTION__, "Same Node ID = %d, send NAK", MLACP(csm).remote_system.node_id); + mlacp_sync_send_nak_handler(csm, msg); + } + + return; +} + +static void mlacp_sync_recv_portConf(struct CSM* csm, struct Msg* msg) +{ + /*Don't support currently*/ + return; +} + +static void mlacp_sync_recv_portPrio(struct CSM* csm, struct Msg* msg) +{ + /*Don't support currently*/ + return; +} + +static void mlacp_sync_recv_portState(struct CSM* csm, struct Msg* msg) +{ + /*Don't support currently*/ + return; +} + +static void mlacp_sync_recv_aggConf(struct CSM* csm, struct Msg* msg) +{ + mLACPAggConfigTLV* portconf = NULL; + + portconf = (mLACPAggConfigTLV*)&(msg->buf[sizeof(ICCHdr)]); + if (mlacp_fsm_update_Agg_conf(csm, portconf) == MCLAG_ERROR) + { + mlacp_sync_send_nak_handler(csm, msg); + } + + return; +} + +static void mlacp_sync_recv_aggState(struct CSM* csm, struct Msg* msg) +{ + mLACPAggPortStateTLV* portstate = NULL; + + portstate = (mLACPAggPortStateTLV*)&(msg->buf[sizeof(ICCHdr)]); + if (mlacp_fsm_update_Aggport_state(csm, portstate) == MCLAG_ERROR) + { + mlacp_sync_send_nak_handler(csm, msg); + /*MLACP(csm).error_msg = "Receive a port state update on an non-existed port. It is suggest to check the environment and re-initialize mLACP again.";*/ + return; + } + + return; +} + +static void mlacp_sync_recv_syncData(struct CSM* csm, struct Msg* msg) +{ + mLACPSyncDataTLV* syncdata = NULL; + + syncdata = (mLACPSyncDataTLV*)&(msg->buf[sizeof(ICCHdr)]); + if (ntohs(syncdata->flags) == 1) + { + /* Sync done*/ + MLACP(csm).wait_for_sync_data = 0; + } + + return; +} + +static void mlacp_sync_recv_syncReq(struct CSM* csm, struct Msg* msg) +{ + mLACPSyncReqTLV* mlacp_sync_req = NULL; + + mlacp_sync_req = (mLACPSyncReqTLV*)&msg->buf[sizeof(ICCHdr)]; + MLACP(csm).sync_req_num = ntohs(mlacp_sync_req->req_num); + + /* Reply the peer all sync info*/ + mlacp_sync_send_all_info_handler(csm); + + return; +} + +static void mlacp_sync_recv_portChanInfo(struct CSM* csm, struct Msg* msg) +{ + mLACPPortChannelInfoTLV* portconf = NULL; + + portconf = (mLACPPortChannelInfoTLV*)&(msg->buf[sizeof(ICCHdr)]); + if (mlacp_fsm_update_port_channel_info(csm, portconf) == MCLAG_ERROR) + { + mlacp_sync_send_nak_handler(csm, msg); + } + + return; +} + +static void mlacp_sync_recv_peerLlinkInfo(struct CSM* csm, struct Msg* msg) +{ + mLACPPeerLinkInfoTLV* peerlink = NULL; + + peerlink = (mLACPPeerLinkInfoTLV*)&(msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_peerlink_info( csm, peerlink); + + return; +} + +static void mlacp_sync_recv_macInfo(struct CSM* csm, struct Msg* msg) +{ + struct mLACPMACInfoTLV* mac_info = NULL; + + mac_info = (struct mLACPMACInfoTLV *)&(msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_mac_info_from_peer(csm, mac_info); + + return; +} + +static void mlacp_sync_recv_arpInfo(struct CSM* csm, struct Msg* msg) +{ + struct mLACPARPInfoTLV* arp_info = NULL; + + arp_info = (struct mLACPARPInfoTLV *)&(msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_arp_info(csm, arp_info); + + return; +} + +static void mlacp_sync_recv_stpInfo(struct CSM* csm, struct Msg* msg) +{ + /*Don't support currently*/ + return; +} + +static void mlacp_sync_recv_heartbeat(struct CSM* csm, struct Msg* msg) +{ + struct mLACPHeartbeatTLV *tlv = NULL; + + tlv = (struct mLACPHeartbeatTLV *)(&msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_heartbeat(csm, tlv); + + return; +} + +static void mlacp_sync_recv_warmboot(struct CSM* csm, struct Msg* msg) +{ + struct mLACPWarmbootTLV *tlv = NULL; + + tlv = (struct mLACPWarmbootTLV *)(&msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_warmboot(csm, tlv); + + return; +} + +/***************************************** +* MLACP Init +* +* ***************************************/ +void mlacp_init(struct CSM* csm, int all) +{ + if (csm == NULL) + return; + + MLACP(csm).sync_req_num = -1; + MLACP(csm).need_to_sync = 0; + MLACP(csm).error_msg = NULL; + + MLACP(csm).current_state = MLACP_STATE_INIT; + memset(MLACP(csm).remote_system.system_id, 0, ETHER_ADDR_LEN); + + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); + PIF_QUEUE_REINIT(MLACP(csm).pif_list); + LIF_PURGE_QUEUE_REINIT(MLACP(csm).lif_purge_list); + + if (all != 0) + { + /* if no clean all, keep the arp info & local interface info for next connection*/ + MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_list); + LIF_QUEUE_REINIT(MLACP(csm).lif_list); + + MLACP(csm).node_id = MLACP_SYSCONF_NODEID_MSB_MASK; + MLACP(csm).node_id |= (((inet_addr(csm->sender_ip) >> 24) << 4) & MLACP_SYSCONF_NODEID_NODEID_MASK); + MLACP(csm).node_id |= rand() % MLACP_SYSCONF_NODEID_FREE_MASK; + } + + return; +} + +/***************************************** +* MLACP finalize +* +* ***************************************/ +void mlacp_finalize(struct CSM* csm) +{ + if (csm == NULL) + return; + + /* msg destroy*/ + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_list); + + /* remove lif & lif-purge queue */ + LIF_QUEUE_REINIT(MLACP(csm).lif_list); + LIF_PURGE_QUEUE_REINIT(MLACP(csm).lif_purge_list); + /* remove & destroy pif queue */ + PIF_QUEUE_REINIT(MLACP(csm).pif_list); + + return; +} + +/***************************************** +* MLACP FSM Transit +* +* ***************************************/ +void mlacp_fsm_transit(struct CSM* csm) +{ + struct System* sys = NULL; + struct Msg* msg = NULL; + static MLACP_APP_STATE_E prev_state = MLACP_SYNC_SYSCONF; + ICCHdr* icc_hdr = NULL; + ICCParameter* icc_param = NULL; + int have_msg = 1; + + if (csm == NULL) + return; + if ((sys = system_get_instance()) == NULL) + return; + + /* torn down event */ + if (csm->sock_fd <= 0 || csm->app_csm.current_state != APP_OPERATIONAL) + { + /* drop all legacy mlacp msg*/ + if (MLACP(csm).current_state != MLACP_STATE_INIT) + { + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); + MLACP(csm).current_state = MLACP_STATE_INIT; + } + return; + } + + if (csm->warm_reboot_disconn_time != 0) + { + /*After peer warm reboot and disconnect, if peer connection is not establised more than 90s, + recover peer disconnection to normal process, such as add peer age flag for MACs etc*/ + if ((time(NULL) - csm->warm_reboot_disconn_time) >= WARM_REBOOT_TIMEOUT) + { + csm->warm_reboot_disconn_time = 0; + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot, reconnection timeout, recover to normal reboot!"); + mlacp_peer_disconn_handler(csm); + } + } + + mlacp_sync_send_heartbeat(csm); + + /* Dequeue msg if any*/ + while (have_msg) + { + if (MLACP(csm).current_state != MLACP_STATE_INIT) + { + /* Handler NAK First*/ + msg = mlacp_dequeue_msg(csm); + if (msg != NULL) + { + have_msg = 1; + icc_hdr = (ICCHdr*)msg->buf; + icc_param = (ICCParameter*)&msg->buf[sizeof(ICCHdr)]; + /*ICCPD_LOG_DEBUG("mlacp_fsm", " SYNC: Message Type = %X, TLV=%s, Len=%d", icc_hdr->ldp_hdr.msg_type, get_tlv_type_string(icc_param->type), msg->len);*/ + + if (icc_hdr->ldp_hdr.msg_type == MSG_T_NOTIFICATION && icc_param->type == TLV_T_NAK) + { + mlacp_sync_recv_nak_handler(csm, msg); + free(msg->buf); + free(msg); + continue; + } + } + else + { + have_msg = 0; + } + } + + if (prev_state != MLACP(csm).current_state) + { + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + mlacp_peer_conn_handler(csm); + prev_state = MLACP(csm).current_state; + } + + /* Sync State */ + if (MLACP(csm).current_state == MLACP_STATE_INIT) + { + MLACP(csm).wait_for_sync_data = 0; + MLACP(csm).current_state = MLACP_STATE_STAGE1; + mlacp_resync_arp(csm); + } + + switch (MLACP(csm).current_state) + { + case MLACP_STATE_INIT: + case MLACP_STATE_ERROR: + /* should not be here*/ + break; + + case MLACP_STATE_STAGE1: + case MLACP_STATE_STAGE2: + mlacp_stage_handler(csm, msg); + break; + + case MLACP_STATE_EXCHANGE: + mlacp_exchange_handler(csm, msg); + break; + } + + /*ICCPD_LOG_DEBUG("mlacp_fsm", " Next State = %s", mlacp_state(csm));*/ + if (msg) + { + free(msg->buf); + free(msg); + } + } +} + +/* Helper function for dumping application state machine */ +static char* mlacp_state(struct CSM* csm) +{ + if (csm == NULL ) + return "MLACP_NULL"; + + switch (MLACP(csm).current_state) + { + case MLACP_STATE_INIT: + return "MLACP_STATE_INIT"; + + case MLACP_STATE_STAGE1: + return "MLACP_STATE_STAGE1"; + + case MLACP_STATE_STAGE2: + return "MLACP_STATE_STAGE2"; + + case MLACP_STATE_EXCHANGE: + return "MLACP_STATE_EXCHANGE"; + + case MLACP_STATE_ERROR: + return "MLACP_STATE_ERROR"; + } + + return "MLACP_UNKNOWN"; +} + +/* Add received message into message list */ +void mlacp_enqueue_msg(struct CSM* csm, struct Msg* msg) +{ + if (csm == NULL ) + { + if (msg != NULL ) + free(msg); + return; + } + + if (msg == NULL ) + return; + + #if 0 + icc_hdr = (ICCHdr*)msg->buf; + icc_param = (ICCParameter*)&msg->buf[sizeof(ICCHdr)]; + ICCPD_LOG_DEBUG("mlacp_fsm", " mLACP enqueue: tlv = 0x%04x", icc_param->type); + #endif + + TAILQ_INSERT_TAIL(&(MLACP(csm).mlacp_msg_list), msg, tail); + + return; +} + +/* Get received message from message list */ +struct Msg* mlacp_dequeue_msg(struct CSM* csm) +{ + struct Msg* msg = NULL; + + if (!TAILQ_EMPTY(&(MLACP(csm).mlacp_msg_list))) + { + msg = TAILQ_FIRST(&(MLACP(csm).mlacp_msg_list)); + TAILQ_REMOVE(&(MLACP(csm).mlacp_msg_list), msg, tail); + } + + return msg; +} + +/****************************************** +* When peerlink ready, prepare the MACMsg +* +******************************************/ +static void mlacp_resync_mac(struct CSM* csm) +{ + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + struct Msg *msg_send = NULL; + + /* recover MAC info sync from peer*/ + if (!TAILQ_EMPTY(&(MLACP(csm).mac_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + mac_msg->op_type = MAC_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + mac_msg->age_flag &= ~MAC_AGE_PEER; + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); + ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag); + } + } + } +} + +/****************************************** +* When peerlink ready, prepare the ARPMsg +* +******************************************/ +static void mlacp_resync_arp(struct CSM* csm) +{ + struct Msg* msg = NULL; + struct ARPMsg* arp_msg = NULL; + struct Msg *msg_send = NULL; + + /* recover ARP info sync from peer*/ + if (!TAILQ_EMPTY(&(MLACP(csm).arp_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + arp_msg = (struct ARPMsg*)msg->buf; + arp_msg->op_type = ARP_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); + } + } + } +} + +/***************************************** +* NAK handler +* +* ***************************************/ +static void mlacp_sync_send_nak_handler(struct CSM* csm, struct Msg* msg) +{ + int msg_len; + ICCHdr* icc_hdr = NULL; + + icc_hdr = (ICCHdr*)msg->buf; + + ICCPD_LOG_WARN(__FUNCTION__, "Send NAK"); + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + csm->app_csm.invalid_msg_id = ntohl(icc_hdr->ldp_hdr.msg_id); + msg_len = app_csm_prepare_nak_msg(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, msg_len); +} + +static void mlacp_sync_recv_nak_handler(struct CSM* csm, struct Msg* msg) +{ + NAKTLV* naktlv = NULL; + uint16_t tlvType = -1; + int i; + + ICCPD_LOG_WARN(__FUNCTION__, "Receive NAK "); + + /* Dequeuq NAK*/ + naktlv = (NAKTLV*)&msg->buf[sizeof(ICCHdr)]; + + /* Check NAK Type*/ + for (i = 0; i < MAX_MSG_LOG_SIZE; ++i) + { + if (ntohl(naktlv->rejected_msg_id) == csm->msg_log.msg[i].msg_id) + { + tlvType = csm->msg_log.msg[i].tlv; + break; + } + } + + if (tlvType) + { + switch (tlvType) + { + case TLV_T_MLACP_SYSTEM_CONFIG: + MLACP(csm).node_id--; + MLACP(csm).system_config_changed = 1; + ICCPD_LOG_WARN(__FUNCTION__, "[%X] change NodeID as %d", tlvType & 0x00FF, MLACP(csm).node_id); + break; + + default: + ICCPD_LOG_WARN(__FUNCTION__, " [%X]", tlvType & 0x00FF); + MLACP(csm).need_to_sync = 1; + break; + } + } + else + { + ICCPD_LOG_WARN(__FUNCTION__, "Unknow NAK"); + MLACP(csm).need_to_sync = 1; + } + + return; +} + +/***************************************** +* MLACP sync receiver +* +* ***************************************/ +static void mlacp_sync_receiver_handler(struct CSM* csm, struct Msg* msg) +{ + ICCParameter *icc_param; + + /* No receive message...*/ + if (!csm || !msg) + return; + + icc_param = (ICCParameter*)&(msg->buf[sizeof(ICCHdr)]); + + /*fprintf(stderr, " Recv Type [%d]\n", icc_param->type);*/ + switch (icc_param->type) + { + case TLV_T_MLACP_SYSTEM_CONFIG: + mlacp_sync_recv_sysConf(csm, msg); + break; + + case TLV_T_MLACP_PORT_CONFIG: + mlacp_sync_recv_portConf(csm, msg); + break; + + case TLV_T_MLACP_PORT_PRIORITY: + mlacp_sync_recv_portPrio(csm, msg); + break; + + case TLV_T_MLACP_PORT_STATE: + mlacp_sync_recv_portState(csm, msg); + break; + + case TLV_T_MLACP_AGGREGATOR_CONFIG: + /* The following line will be uncommented when Aggregator related structures are supported. */ + mlacp_sync_recv_aggConf(csm, msg); + break; + + case TLV_T_MLACP_AGGREGATOR_STATE: + mlacp_sync_recv_aggState(csm, msg); + break; + + case TLV_T_MLACP_SYNC_DATA: + mlacp_sync_recv_syncData(csm, msg); + break; + + case TLV_T_MLACP_SYNC_REQUEST: + mlacp_sync_recv_syncReq(csm, msg); + break; + + case TLV_T_MLACP_PORT_CHANNEL_INFO: + mlacp_sync_recv_portChanInfo(csm, msg); + break; + + case TLV_T_MLACP_PEERLINK_INFO: + mlacp_sync_recv_peerLlinkInfo(csm, msg); + break; + + case TLV_T_MLACP_MAC_INFO: + mlacp_sync_recv_macInfo(csm, msg); + break; + + case TLV_T_MLACP_ARP_INFO: + mlacp_sync_recv_arpInfo(csm, msg); + break; + + case TLV_T_MLACP_STP_INFO: + mlacp_sync_recv_stpInfo(csm, msg); + break; + + case TLV_T_MLACP_HEARTBEAT: + mlacp_sync_recv_heartbeat(csm, msg); + break; + + case TLV_T_MLACP_WARMBOOT_FLAG: + mlacp_sync_recv_warmboot(csm, msg); + break; + } + + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [Sync Recv] %s... DONE", get_tlv_type_string(icc_param->type));*/ + + return; +} + +/***************************************** +* MLACP sync sender +* +* ***************************************/ +static void mlacp_sync_sender_handler(struct CSM* csm) +{ + switch (MLACP(csm).sync_state) + { + case MLACP_SYNC_SYSCONF: + mlacp_sync_send_sysConf(csm); + break; + + case MLACP_SYNC_AGGCONF: + /* Do nothing due to no support in this version. */ + mlacp_sync_send_aggConf(csm); + break; + + case MLACP_SYNC_AGGSTATE: + /* Do nothing due to no support in this version. */ + mlacp_sync_send_aggState(csm); + break; + + case MLACP_SYNC_AGGINFO: + mlacp_sync_send_syncPortChannelInfo(csm); + break; + + case MLACP_SYNC_PEERLINKINFO: + mlacp_sync_send_syncPeerLinkInfo(csm); + break; + + case MLACP_SYNC_ARP_INFO: + mlacp_sync_send_syncArpInfo(csm); + break; + + case MLACP_SYNC_DONE: + mlacp_sync_send_syncDoneData(csm); + break; + + default: + break; + } + + return; +} + +static void mlacp_sync_send_all_info_handler(struct CSM* csm) +{ + size_t len = 0; + + /* Prepare for sync start reply*/ + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_sync_data_tlv(csm, g_csm_buf, CSM_BUFFER_SIZE, 0); + iccp_csm_send(csm, g_csm_buf, len); + + MLACP(csm).sync_state = MLACP_SYNC_SYSCONF; + + while (1) + { + mlacp_sync_sender_handler(csm); + if (MLACP(csm).sync_state != MLACP_SYNC_DONE) + { + MLACP(csm).sync_state++; + } + else + { + /*Next stage*/ + MLACP(csm).wait_for_sync_data = 0; + MLACP(csm).current_state++; + break; + } + } + + return; +} + +static void mlacp_stage_sync_send_handler(struct CSM* csm, struct Msg* msg) +{ + ICCHdr* icc_hdr = NULL; + ICCParameter* icc_param = NULL; + mLACPSyncReqTLV* mlacp_sync_req = NULL; + + if (MLACP(csm).wait_for_sync_data == 0) + { + /* Waiting the peer sync request*/ + if (msg) + { + icc_hdr = (ICCHdr*)msg->buf; + icc_param = (ICCParameter*)&msg->buf[sizeof(ICCHdr)]; + + if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_APP_DATA && icc_param->type == TLV_T_MLACP_SYNC_REQUEST) + { + mlacp_sync_req = (mLACPSyncReqTLV*)&msg->buf[sizeof(ICCHdr)]; + MLACP(csm).wait_for_sync_data = 1; + MLACP(csm).sync_req_num = ntohs(mlacp_sync_req->req_num); + + /* Reply the peer all sync info*/ + mlacp_sync_send_all_info_handler(csm); + } + } + } + + return; +} + +static void mlacp_stage_sync_request_handler(struct CSM* csm, struct Msg* msg) +{ + int msg_len = 0; + + /* Socket server send sync request first*/ + if (MLACP(csm).wait_for_sync_data == 0) + { + // Send out the request for ALL + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_sync_request_tlv(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, msg_len); + MLACP(csm).wait_for_sync_data = 1; + } + else + { + mlacp_sync_receiver_handler(csm, msg); + if (MLACP(csm).wait_for_sync_data == 0) + { + MLACP(csm).current_state++; + } + } + + return; +} + +static void mlacp_stage_handler(struct CSM* csm, struct Msg* msg) +{ + if (MLACP(csm).current_state == MLACP_STATE_STAGE1) + { + /*Stage 1, role active send info first*/ + if (csm->role_type == STP_ROLE_ACTIVE) + mlacp_stage_sync_send_handler(csm, msg); + else + mlacp_stage_sync_request_handler(csm, msg); + } + else + { + /*Stage 2, role standby send info*/ + if (csm->role_type == STP_ROLE_ACTIVE) + mlacp_stage_sync_request_handler(csm, msg); + else + mlacp_stage_sync_send_handler(csm, msg); + } + + return; +} + +static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg) +{ + int len; + struct System* sys = NULL; + struct LocalInterface* lif = NULL, *lif_purge = NULL; + + ICCHdr* icc_hdr = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + /* update system id*/ + /*update_system_id(csm);*/ + + /* Any msg?*/ + if (msg) + { + icc_hdr = (ICCHdr*)msg->buf; + if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_APP_DATA) + { + /* Process receive APP info*/ + mlacp_sync_receiver_handler(csm, msg); + } + } + + if (MLACP(csm).need_to_sync != 0) + { + /* Send out the request for ALL info*/ + MLACP(csm).need_to_sync = 0; + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_sync_request_tlv(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + } + + /* Send system config*/ + if (MLACP(csm).system_config_changed != 0) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_sys_config(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + + if (csm->peer_link_if) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_port_peerlink_info(csm, g_csm_buf, CSM_BUFFER_SIZE, csm->peer_link_if); + iccp_csm_send(csm, g_csm_buf, len); + } + + MLACP(csm).system_config_changed = 0; + } + + /* Send mlag purge lif*/ + LIST_FOREACH(lif_purge, &(MLACP(csm).lif_purge_list), mlacp_purge_next) + { + /* Purge info*/ + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_Aggport_config(csm, g_csm_buf, CSM_BUFFER_SIZE, lif_purge, 1); + iccp_csm_send(csm, g_csm_buf, len); + /* Destroy old interface*/ + if (lif_purge != NULL) + LIST_REMOVE(lif_purge, mlacp_purge_next); + } + + /* Send mlag lif*/ + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif->type == IF_T_PORT_CHANNEL && lif->port_config_sync) + { + /* Send port channel information*/ + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_Aggport_config(csm, g_csm_buf, CSM_BUFFER_SIZE, lif, 0); + iccp_csm_send(csm, g_csm_buf, len); + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_port_channel_info(csm, g_csm_buf, CSM_BUFFER_SIZE, lif); + iccp_csm_send(csm, g_csm_buf, len); + + lif->port_config_sync = 0; + } + + /*send if portchannel state change */ + if (lif->type == IF_T_PORT_CHANNEL && lif->changed) + { + /* Send port channel state information*/ + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_Aggport_state(csm, g_csm_buf, CSM_BUFFER_SIZE, lif); + iccp_csm_send(csm, g_csm_buf, len); + lif->changed = 0; + } + } + + /* Send MAC info if any*/ + mlacp_sync_send_syncMacInfo(csm); + + /* Send ARP info if any*/ + mlacp_sync_send_syncArpInfo(csm); + + /*If peer is warm reboot*/ + if (csm->peer_warm_reboot_time != 0) + { + /*Peer warm reboot timeout(connection is not broken more than 90s), recover to normal reboot*/ + if ((time(NULL) - csm->peer_warm_reboot_time) >= WARM_REBOOT_TIMEOUT) + { + csm->peer_warm_reboot_time = 0; + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot timeout, recover to normal reboot!"); + } + } + + return; +} diff --git a/src/iccpd/src/mlacp_link_handler.c b/src/iccpd/src/mlacp_link_handler.c new file mode 100644 index 000000000000..66a75c4b8620 --- /dev/null +++ b/src/iccpd/src/mlacp_link_handler.c @@ -0,0 +1,2401 @@ +/* + * mlacp_link_handler.c + * mLACP link handler + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../include/system.h" +#include "../include/logger.h" +#include "../include/mlacp_tlv.h" + +#include "../include/iccp_csm.h" +#include "mclagdctl/mclagdctl.h" +#include "../include/iccp_cmd_show.h" +/***************************************** +* Enum +* +* ***************************************/ +typedef enum route_manipulate_type +{ + ROUTE_NONE, + ROUTE_ADD, + ROUTE_DEL +} ROUTE_MANIPULATE_TYPE_E; + + +/***************************************** +* Global +* +* ***************************************/ +char g_ipv4_str[INET_ADDRSTRLEN]; + +/***************************************** +* Tool : show ip string +* +* ***************************************/ +char *show_ip_str(uint32_t ipv4_addr) +{ + struct in_addr in_addr; + + memset(g_ipv4_str, 0, sizeof(g_ipv4_str)); + in_addr.s_addr = ipv4_addr; + inet_ntop(AF_INET, &in_addr, g_ipv4_str, INET_ADDRSTRLEN); + + return g_ipv4_str; +} + +static int getHwAddr(char *buff, char *mac) +{ + int i = 0; + unsigned int p[6]; + + if ( buff == NULL || mac == NULL ) + { + return MCLAG_ERROR; + } + + if (sscanf(mac, "%x:%x:%x:%x:%x:%x", &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]) < 6) + { + return MCLAG_ERROR; + } + + for (i = 0; i < 6; i++) + { + buff[i] = p[i]; + } + + return 0; +} + +/* Set an entry in the ARP cache. */ +int mlacp_fsm_arp_set(char *ifname, uint32_t ip, char *mac) +{ + struct arpreq arpreq; + struct sockaddr_in *sin; + struct in_addr ina; + int flags; + int rc; + int sock_fd = 0; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Set arp entry for IP:%s MAC:%s ifname:%s", show_ip_str(htonl(ip)), mac, ifname); + + if (ifname == NULL || ip == 0 || mac == NULL) + { + return MCLAG_ERROR; + } + + /*you must add this becasue some system will return "Invlid argument" + because some argument isn't zero */ + memset(&arpreq, 0, sizeof(struct arpreq)); + sin = (struct sockaddr_in *)&arpreq.arp_pa; + memset(sin, 0, sizeof(struct sockaddr_in)); + sin->sin_family = AF_INET; + ina.s_addr = htonl(ip); + memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr)); + + if (getHwAddr((char *)arpreq.arp_ha.sa_data, mac) < 0) + { + return MCLAG_ERROR; + } + + strncpy(arpreq.arp_dev, ifname, 15); + + flags = ATF_COM; //note, must set flag, if not,you will get error + + arpreq.arp_flags = flags; + + sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + { + return MCLAG_ERROR; + } + + rc = ioctl(sock_fd, SIOCSARP, &arpreq); + if (rc < 0) + { + close(sock_fd); + return MCLAG_ERROR; + } + + close(sock_fd); + + return 0; +} + +/* Delete an entry from the ARP cache. */ +int mlacp_fsm_arp_del(char *ifname, uint32_t ip) +{ + struct arpreq arpreq; + struct sockaddr_in *sin; + struct in_addr ina; + int rc; + int sock_fd = 0; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Del arp entry for IP : %s ifname:%s", show_ip_str(htonl(ip)), ifname); + + if (ifname == NULL || ip == 0) + { + return MCLAG_ERROR; + } + + /*you must add this becasue some system will return "Invlid argument" + because some argument isn't zero */ + memset(&arpreq, 0, sizeof(struct arpreq)); + + sin = (struct sockaddr_in *)&arpreq.arp_pa; + memset(sin, 0, sizeof(struct sockaddr_in)); + sin->sin_family = AF_INET; + ina.s_addr = htonl(ip); + memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr)); + + strncpy(arpreq.arp_dev, ifname, 15); + + sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + { + return MCLAG_ERROR; + } + + rc = ioctl(sock_fd, SIOCDARP, &arpreq); + if (rc < 0) + { + close(sock_fd); + return MCLAG_ERROR; + } + + close(sock_fd); + + return 0; +} + +static int arp_set_handler(struct CSM* csm, + struct LocalInterface* lif, + int add) +{ + struct Msg* msg = NULL; + struct ARPMsg* arp_msg = NULL; + char mac_str[18] = ""; + + if (!csm || !lif) + return 0; + + if (add) + goto add_arp; + else + goto del_arp; + + /* Process Add */ + add_arp: + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return 0; + + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + mac_str[0] = '\0'; + arp_msg = (struct ARPMsg*)msg->buf; + + /* only process add*/ + if (arp_msg->op_type == ARP_SYNC_DEL) + continue; + + /* find the ARP for lif_list*/ + if (strcmp(lif->name, arp_msg->ifname) != 0) + continue; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], + arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); + + mlacp_fsm_arp_set(arp_msg->ifname, arp_msg->ipv4_addr, mac_str); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add dynamic ARP to kernel [%s]", + show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + } + goto done; + + del_arp: + /* Process Del */ + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + arp_msg = (struct ARPMsg*)msg->buf; + + /* find the ARP for lif_list*/ + if (strcmp(lif->name, arp_msg->ifname) != 0) + continue; + + /* don't process del*/ + if (arp_msg->op_type == ARP_SYNC_DEL) + continue; + + /* link broken, del all dynamic arp on the lif*/ + mlacp_fsm_arp_del(arp_msg->ifname, arp_msg->ipv4_addr); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Del dynamic ARP [%s]", + show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + } + + done: + return 0; +} + +/***************************************** + * Port-Channel Status Handler + * + ****************************************/ +static void set_route_by_linux_route(struct CSM* csm, + struct LocalInterface *local_if, + int is_add) +{ + /* TODO Need to remove this function + when set static route with zebra works fine*/ + + char ipv4_dest_str[INET_ADDRSTRLEN]; + char syscmd[128]; + char *ptr; + int ret = 0; + + /* enable kernel forwarding support*/ + system("echo 1 > /proc/sys/net/ipv4/ip_forward"); + + if (!csm || !local_if) + return; + + sprintf(ipv4_dest_str, "%s", show_ip_str(htonl(local_if->ipv4_addr))); + ptr = strrchr(ipv4_dest_str, '.'); strcpy(ptr, ".0\0"); + +#if 1 + /* set gw route*/ + /*sprintf(syscmd, "ip route %s %s/%d proto static metric 200 nexthop via %s > /dev/null 2>&1",*/ + sprintf(syscmd, "ip route %s %s/%d metric 200 nexthop via %s > /dev/null 2>&1", + (is_add) ? "add" : "del", ipv4_dest_str, local_if->prefixlen, + csm->peer_ip); +#else + // set interface route + sprintf(syscmd, "route %s -net %s/%d %s > /dev/null 2>&1", + (is_add) ? "add" : "del", ipv4_dest_str, local_if->prefixlen, + local_if->name); +#endif + + ret = system(syscmd); + ICCPD_LOG_DEBUG(__FUNCTION__, "%s ret = %d", syscmd, ret); + + return; +} + +static void update_vlan_if_info(struct CSM *csm, + struct LocalInterface *local_if, + struct LocalInterface *vlan_if, + int po_state) +{ + if (!csm || !local_if || !vlan_if) + return; + + vlan_if->mlacp_state = MLACP(csm).current_state; + + return; +} + +static void update_l3_if_info(struct CSM *csm, + struct LocalInterface *local_if, + struct LocalInterface *l3_if, + int po_state) +{ + if (!csm || !l3_if) + return; + + l3_if->mlacp_state = MLACP(csm).current_state; + + return; +} + +static void update_po_if_info(struct CSM *csm, + struct LocalInterface *local_if, + int po_state) +{ + if (!csm || !local_if) + return; + + /* update local po info*/ + if (local_if->po_active != po_state) + { + local_if->changed = 1; + local_if->po_active = (po_state != 0); + /*printf("update po [%s=%d]\n",local_if->name, local_if->po_active);*/ + } + local_if->mlacp_state = MLACP(csm).current_state; + + return; +} + +static void set_l3_itf_state(struct CSM *csm, + struct LocalInterface *set_l3_local_if, + ROUTE_MANIPULATE_TYPE_E route_type) +{ + if (!csm || !set_l3_local_if) + return; + + if (set_l3_local_if && (route_type != ROUTE_NONE)) + { + /*set_default_route(csm);*/ + + /*ICCPD_LOG_DEBUG(__FUNCTION__, " route set Interface = %s route type = %d route = %s nexthop via = %s ", + set_l3_local_if->name, route_type, show_ip_str(htonl(set_l3_local_if->ipv4_addr)), csm->peer_ip );*/ + + /* set static route*/ + if (route_type == ROUTE_ADD) + { + /*set_route_by_linux_route(csm, set_l3_local_if, 1);*/ /*add static route by linux route tool*/ + /*If the L3 intf is not Vlan, del ARP; else wait ARP age*/ + if (strncmp(set_l3_local_if->name, VLAN_PREFIX, 4) != 0) + { + arp_set_handler(csm, set_l3_local_if, 0); /* del arp*/ + } + } + else if (route_type == ROUTE_DEL) + { + /*set_route_by_linux_route(csm, set_l3_local_if, 0);*/ /*del static route by linux route tool*/ + arp_set_handler(csm, set_l3_local_if, 1); /* add arp*/ + } + } + + return; +} + +static int peer_po_is_alive(struct CSM *csm, int po_ifindex) +{ + struct PeerInterface *pif = NULL; + int pif_active = 0; + + if (!csm) + return 0; + + LIST_FOREACH(pif, &(MLACP(csm).pif_list), mlacp_next) + { + if (pif->type != IF_T_PORT_CHANNEL) + continue; + if (pif->po_id != po_ifindex) + continue; + + if (pif->po_active) + pif_active = 1; /*pif alive*/ + break; + } + + return pif_active; +} + +static void mlacp_clean_fdb(void) +{ + struct IccpSyncdHDr * msg_hdr; + char *msg_buf = g_csm_buf; + + struct System *sys; + + sys = system_get_instance(); + if (sys == NULL) + return; + memset(msg_buf, 0, CSM_BUFFER_SIZE); + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_FLUSH_FDB; + msg_hdr->len = sizeof(struct IccpSyncdHDr); + + if (sys->sync_fd) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Notify mclagsyncd to clear FDB"); + + return; +} + +void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable) +{ + struct IccpSyncdHDr * msg_hdr; + mclag_sub_option_hdr_t * sub_msg; + char *msg_buf = g_csm_buf; + int msg_len; + struct System *sys; + + sys = system_get_instance(); + if (sys == NULL) + return; + + if (!lif) + return; + memset(msg_buf, 0, CSM_BUFFER_SIZE); + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_PORT_MAC_LEARN_MODE; + + msg_hdr->len = sizeof(struct IccpSyncdHDr); + + sub_msg = (mclag_sub_option_hdr_t*)&msg_buf[msg_hdr->len]; + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MAC_LEARN_DISABLE; + + if (enable) + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MAC_LEARN_ENABLE; + + msg_len = strlen(lif->name); + memcpy(sub_msg->data, lif->name, msg_len); + + sub_msg->op_len = msg_len; + msg_hdr->len += sizeof(mclag_sub_option_hdr_t); + msg_hdr->len += sub_msg->op_len; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Send %s port MAC learn msg to mclagsyncd for %s", + sub_msg->op_type == MCLAG_SUB_OPTION_TYPE_MAC_LEARN_DISABLE ? "DISABLE":"ENABLE", lif->name); + + /*send msg*/ + if (sys->sync_fd) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + return; +} + +static void set_peerlink_mlag_port_kernel_forward( + struct CSM *csm, + struct LocalInterface *lif, + int enable) +{ + if (!csm || !csm->peer_link_if || !lif) + return; + + char cmd[256] = { 0 }; + + sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP", + "-D", csm->peer_link_if->name, lif->name); + ICCPD_LOG_DEBUG(__FUNCTION__, " ebtable cmd %s", cmd ); + system(cmd); + + sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP", + (enable) ? "-A" : "-D", csm->peer_link_if->name, lif->name); + ICCPD_LOG_DEBUG(__FUNCTION__, " ebtable cmd %s", cmd ); + system(cmd); + + return; +} + +void update_peerlink_isolate_from_all_csm_lif( + struct CSM* csm) +{ + struct LocalInterface *lif = NULL; + struct IccpSyncdHDr * msg_hdr; + mclag_sub_option_hdr_t * sub_msg; + char msg_buf[4096]; + struct System *sys; + + char mlag_po_buf[512]; + int src_len = 0, dst_len = 0; + + sys = system_get_instance(); + if (sys == NULL) + return; + + if (!csm || !csm->peer_link_if) + return; + + memset(msg_buf, 0, 4095); + memset(mlag_po_buf, 0, 511); + + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_PORT_ISOLATE; + msg_hdr->len = sizeof(struct IccpSyncdHDr); + + /*sub msg src*/ + sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len]; + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_ISOLATE_SRC; + + if (csm->peer_link_if->type == IF_T_VXLAN) + { + /*TBD: vxlan tunnel port isolation will be supportted later*/ + return; +#if 0 + int begin_eth_port = 0; + + /*VTTNL0001;Ethernet0001,Ethernet0002*/ + /*src_len= strlen(csm->peer_link_if->name); */ + src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", csm->peer_link_if->name); + src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", ";"); + + /*traverse all ethernet port */ + LIST_FOREACH(lif, &(sys->lif_list), system_next) + { + if (lif->type != IF_T_PORT) + continue; + + /* need to isolate port, get it's name */ + if (begin_eth_port != 0) + { + src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", ","); + } + + src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", lif->name); + begin_eth_port = 1; + } + memcpy(sub_msg->data, src_buf, src_len); + + ICCPD_LOG_DEBUG(__FUNCTION__, "isolate src %s, data %s, len %d", src_buf, sub_msg->data, src_len); +#endif + } + else + { + src_len = strlen(csm->peer_link_if->name); + memcpy(sub_msg->data, csm->peer_link_if->name, src_len); + } + sub_msg->op_len = src_len; + + /*sub msg dst */ + msg_hdr->len += sub_msg->op_len; + msg_hdr->len += sizeof(mclag_sub_option_hdr_t); + sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len]; + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_ISOLATE_DST; + + /*traverse all portchannel member port and send msg to syncd */ + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif->type != IF_T_PORT_CHANNEL) + continue; + + /* check pif port state and lif pochannel state */ + if (lif->isolate_to_peer_link == 1) + { + /* need to isolate port, get it's member name */ + if (strlen(mlag_po_buf) != 0) + dst_len += snprintf(mlag_po_buf + dst_len, sizeof(mlag_po_buf) - dst_len, "%s", ","); + + dst_len += snprintf(mlag_po_buf + dst_len, sizeof(mlag_po_buf) - dst_len, "%s", lif->portchannel_member_buf); + } + } + + sub_msg->op_len = dst_len; + msg_hdr->len += sizeof(mclag_sub_option_hdr_t); + msg_hdr->len += sub_msg->op_len; + + if (dst_len) + { + memcpy(sub_msg->data, mlag_po_buf, dst_len); + ICCPD_LOG_DEBUG(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port %s", csm->peer_link_if->name, mlag_po_buf); + } + else + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port is NULL", csm->peer_link_if->name); + } + + /*send msg*/ + if (sys->sync_fd) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + return; +} + +static void set_peerlink_mlag_port_isolate( + struct CSM *csm, + struct LocalInterface *lif, + int enable) +{ + if (!lif) + return; + + lif->isolate_to_peer_link = enable; + + if (!csm || !csm->peer_link_if ) + return; + + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return; + + ICCPD_LOG_DEBUG(__FUNCTION__, "%s port-isolate from %s to %s", + enable ? "Enable" : "Disable", csm->peer_link_if->name, lif->name); + update_peerlink_isolate_from_all_csm_lif(csm); + + /* Kernel also needs to block traffic from peerlink to mlag-port*/ + set_peerlink_mlag_port_kernel_forward(csm, lif, enable); + + return; +} + +void peerlink_port_isolate_cleanup(struct CSM* csm) +{ + struct LocalInterface *local_if = NULL; + + if (!csm) + return; + + /* Clean all port block*/ + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + set_peerlink_mlag_port_isolate(csm, local_if, 0); + } + } + + return; +} + +void update_peerlink_isolate_from_pif( + struct CSM *csm, + struct PeerInterface *pif, + int pif_po_state, + int new_create) +{ + struct LocalInterface *lif = NULL; + int lif_po_state = 1; + + if (!csm || !csm->peer_link_if || !pif) + return; + if (new_create == 0 && pif_po_state == pif->po_active) + return; + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return; + + /* peer link changed*/ + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (strcmp(lif->name, pif->name) != 0) + continue; + + lif_po_state = lif->po_active; + break; + } + + if (!lif) + { + ICCPD_LOG_WARN(__FUNCTION__, "Can't find local if for %s", pif->name); + return; + } + + ICCPD_LOG_DEBUG(__FUNCTION__, "From if %s local(%s) / peer(%s)", + lif->name, + (lif_po_state) ? "up" : "down", + (pif_po_state) ? "up" : "down"); + + if (lif_po_state == 1) + { + if (pif_po_state == 1) + { + /* both peer-pair link up, enable port-isolate*/ + ICCPD_LOG_DEBUG(__FUNCTION__, "Enable port-isolate from %s to %s", + csm->peer_link_if->name, lif->name); + set_peerlink_mlag_port_isolate(csm, lif, 1); + } + else + { + /* local link up, and peer link changes to down, disable port-isolate*/ + ICCPD_LOG_DEBUG(__FUNCTION__, "Disable port-isolate from %s to %s", + csm->peer_link_if->name, lif->name); + set_peerlink_mlag_port_isolate(csm, lif, 0); + } + } + else + { + ;/* local link down, do nothing*/ + } + + return; +} + +static void update_peerlink_isolate_from_lif( + struct CSM* csm, + struct LocalInterface* lif, + int lif_po_state) +{ + struct PeerInterface *pif = NULL; + int pif_po_state = 1; + + if (!csm || !csm->peer_link_if || !lif) + return; + /*if (lif_po_state == lif->po_active) return;*/ + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return; + + /* local link changed*/ + LIST_FOREACH(pif, &(MLACP(csm).pif_list), mlacp_next) + { + if (strcmp(pif->name, lif->name) != 0) + continue; + + pif_po_state = pif->po_active; + break; + } + + ICCPD_LOG_DEBUG(__FUNCTION__, "From if %s local(%s) / peer(%s)", + lif->name, (lif_po_state) ? "up" : "down", (pif_po_state) ? "up" : "down"); + + if (lif_po_state == 1) + { + if (pif_po_state == 1) + { + /* both peer-pair link up, enable port-isolate*/ + ICCPD_LOG_DEBUG(__FUNCTION__, "Enable port-isolate from %s to %s", + csm->peer_link_if->name, lif->name); + set_peerlink_mlag_port_isolate(csm, lif, 1); + } + else + { + /* peer link down, local link changes to up, disable port-isolate*/ + ICCPD_LOG_DEBUG(__FUNCTION__, " Disable port-isolate from %s to %s", + csm->peer_link_if->name, lif->name); + set_peerlink_mlag_port_isolate(csm, lif, 0); + } + } + else + { + ;/* local link down, do nothing*/ + } + + return; +} + +static void update_l2_po_state(struct CSM *csm, + struct LocalInterface *lif, + int po_state) +{ + ROUTE_MANIPULATE_TYPE_E route_type = ROUTE_NONE; + struct VLAN_ID *vlan = NULL; + struct LocalInterface *set_l3_vlan_if = NULL; + + if (!csm || !lif) + return; + + /*L2 po*/ + /*if (po_state != lif->po_active && po_state == 0) + { + mlacp_clean_fdb(); + }*/ + + /*Is there any L3 vlan over L2 po?*/ + LIST_FOREACH(vlan, &(lif->vlan_list), port_next) + { + route_type = ROUTE_NONE; + + if (!vlan->vlan_itf) + continue; + + /* If the po is under a vlan, update vlan state first*/ + update_vlan_if_info(csm, lif, vlan->vlan_itf, po_state); + + if (!local_if_is_l3_mode(vlan->vlan_itf)) + continue; + + /*NOTE + * assume only one mlag per vlan + * need to add rules for per mlag per vlan later (arp list?) + */ + set_l3_vlan_if = vlan->vlan_itf; + if (po_state != lif->po_active + || MLACP(csm).current_state != set_l3_vlan_if->mlacp_state) + { + if (po_state == 1) + { + route_type = ROUTE_DEL; + } + else if (po_state == 0 + && MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + if (peer_po_is_alive(csm, lif->ifindex) == 1) + route_type = ROUTE_ADD; + } + } + + /*update_po_arp_list(csm, set_l3_vlan_if);*/ + set_l3_itf_state(csm, set_l3_vlan_if, route_type); + update_l3_if_info(csm, lif, set_l3_vlan_if, po_state); + } + + return; +} + +static void update_l3_po_state(struct CSM *csm, + struct LocalInterface *lif, + int po_state) +{ + ROUTE_MANIPULATE_TYPE_E route_type = ROUTE_NONE; + struct LocalInterface *set_l3_lif = NULL; + + /*L3 po*/ + set_l3_lif = lif; + + if (!csm || !lif) + return; + + if (po_state != lif->po_active + && po_state == 1) + { + /* po alive, clean static route & recover the ARP*/ + route_type = ROUTE_DEL; + } + else if (po_state != lif->po_active + && po_state == 0 + && MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + /* po is not alive & peer-link alive, set static route*/ + if (peer_po_is_alive(csm, lif->po_id) == 1) + route_type = ROUTE_ADD; + } + else if (MLACP(csm).current_state != lif->mlacp_state + && MLACP(csm).current_state == MLACP_STATE_EXCHANGE + && po_state == 0) + { + /* when peer-pair link ready, set static route for broken po link*/ + if (peer_po_is_alive(csm, lif->po_id) == 1) + route_type = ROUTE_ADD; + } + + /*update_po_arp_list(csm, set_l3_lif);*/ + set_l3_itf_state(csm, set_l3_lif, route_type); + update_l3_if_info(csm, lif, set_l3_lif, po_state); + + return; +} + +int is_local_vlan_on(struct VLAN_ID* vlan_id_list) +{ + if (!vlan_id_list->vlan_itf) + return 0; + + return 1; +} + +void syn_arp_info_to_peer(struct CSM *csm, struct LocalInterface *local_if) +{ + struct Msg *msg = NULL; + struct ARPMsg *arp_msg = NULL, *arp_info = NULL; + struct Msg *msg_send = NULL; + + if (!csm || !local_if) + return; + + if (!TAILQ_EMPTY(&(MLACP(csm).arp_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + arp_info = (struct ARPMsg*)msg->buf; + + if (strcmp(arp_info->ifname, local_if->name) != 0) + continue; + + arp_msg = (struct ARPMsg*)msg->buf; + arp_msg->op_type = ARP_SYNC_ADD; + + if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); + /*ICCPD_LOG_DEBUG( __FUNCTION__, "Enqueue ARP[ADD] for %s", + show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] for %s", + show_ip_str(htonl(arp_msg->ipv4_addr))); + } + } + + return; +} + +void update_stp_peer_link(struct CSM *csm, + struct PeerInterface *pif, + int po_state, int new_create) +{ + struct LocalInterface *lif = NULL; + struct VLAN_ID *vlan = NULL; + + if (!csm || !pif) + return; + if (new_create == 0 && po_state == pif->po_active) + return; + + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (strcmp(lif->name, pif->name) != 0) + continue; + + /* update lif route if pif link status changes */ + if (local_if_is_l3_mode(lif)) + { + if (po_state == 1 && lif->po_active == 0) + set_l3_itf_state(csm, lif, ROUTE_ADD); + else if (po_state == 0 && lif->po_active == 0) + set_l3_itf_state(csm, lif, ROUTE_DEL); + + /*If pif change to active, and local is also active, syn arp to peer*/ + if (po_state == 1 && lif->po_active == 1) + { + syn_arp_info_to_peer(csm, lif); + } + } + else + { + LIST_FOREACH(vlan, &(lif->vlan_list), port_next) + { + if (!is_local_vlan_on(vlan)) + continue; + if (!local_if_is_l3_mode(vlan->vlan_itf)) + continue; + + /*NOTE + * assume only one mlag per bridge + * need to add rules for per mlag per bridge later (arp list?) + */ + if (po_state == 1 && lif->po_active == 0) + set_l3_itf_state(csm, vlan->vlan_itf, ROUTE_ADD); + else if (po_state == 0 && lif->po_active == 0) + set_l3_itf_state(csm, vlan->vlan_itf, ROUTE_DEL); + + /*If pif change to active, and local is also active, syn arp to peer*/ + if (po_state == 1 && lif->po_active == 1) + { + syn_arp_info_to_peer(csm, vlan->vlan_itf); + } + } + } + + break; + } + + return; +} + +void iccp_get_fdb_change_from_syncd( void) +{ + struct IccpSyncdHDr * msg_hdr; + char msg_buf[512]; + struct System *sys; + + sys = system_get_instance(); + if (sys == NULL) + return; + + memset(msg_buf, 0, 512); + + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_GET_FDB_CHANGES; + msg_hdr->len = sizeof(struct IccpSyncdHDr); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Send get fdb change msg to mclagsyncd"); + + /*send msg*/ + if (sys->sync_fd > 0) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + return; +} + +void iccp_send_fdb_entry_to_syncd( struct MACMsg* mac_msg, uint8_t mac_type) +{ + struct IccpSyncdHDr * msg_hdr; + char msg_buf[512]; + struct System *sys; + struct mclag_fdb_info * mac_info; + + sys = system_get_instance(); + if (sys == NULL) + return; + + memset(msg_buf, 0, 512); + + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_SET_FDB; + + /*mac msg */ + mac_info = (struct mclag_fdb_info *)&msg_buf[sizeof(struct IccpSyncdHDr)]; + mac_info->vid = mac_msg->vid; + memcpy(mac_info->port_name, mac_msg->ifname, MAX_L_PORT_NAME); + memcpy(mac_info->mac, mac_msg->mac_str, ETHER_ADDR_STR_LEN); + mac_info->type = mac_type; + mac_info->op_type = mac_msg->op_type; + msg_hdr->len = sizeof(struct IccpSyncdHDr) + sizeof(struct mclag_fdb_info); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Send mac %s msg to mclagsyncd, vid %d ; ifname %s ; mac %s; type %s", + mac_info->op_type == MAC_SYNC_ADD ? "add" : "del", mac_info->vid, mac_info->port_name, mac_info->mac, mac_info->type == MAC_TYPE_STATIC ? "static" : "dynamic"); + + /*send msg*/ + if (sys->sync_fd > 0 ) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + return; +} + +void add_mac_to_chip(struct MACMsg* mac_msg, uint8_t mac_type) +{ + mac_msg->op_type = MAC_SYNC_ADD; + iccp_send_fdb_entry_to_syncd( mac_msg, mac_type); + + return; +} + +void del_mac_from_chip(struct MACMsg* mac_msg) +{ + mac_msg->op_type = MAC_SYNC_DEL; + iccp_send_fdb_entry_to_syncd( mac_msg, mac_msg->fdb_type); + + return; +} + +uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg* mac_msg, uint8_t set ) +{ + uint8_t new_age_flag = 0; + struct Msg *msg = NULL; + + new_age_flag = mac_msg->age_flag; + + if (set == 0)/*remove age flag*/ + { + new_age_flag &= ~MAC_AGE_LOCAL; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove local age flag: %d ifname %s, add %s vlan-id %d, age_flag %d", + new_age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag); + + /*send mac MAC_SYNC_ADD message to peer*/ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + mac_msg->op_type = MAC_SYNC_ADD; + if (iccp_csm_init_msg(&msg, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/ + } + else + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue MAC-msg-list: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag); + } + } + } + else/*set age flag*/ + { + new_age_flag |= MAC_AGE_LOCAL; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Add local age flag: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag); + + /*send mac MAC_SYNC_DEL message to peer*/ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + mac_msg->op_type = MAC_SYNC_DEL; + if (iccp_csm_init_msg(&msg, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/ + } + else + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue MAC-msg-list: %s, del %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag); + } + } + } + + return new_age_flag; +} + +/*Deal with mac add,del,move when portchannel up or down*/ +static void update_l2_mac_state(struct CSM *csm, + struct LocalInterface *lif, + int po_state) +{ + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + + if (!csm || !lif) + return; + + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + /* find the MAC for this interface*/ + if (strcmp(lif->name, mac_msg->origin_ifname) != 0) + continue; + + /*portchannel down*/ + if (po_state == 0) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, age local MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); + + if (mac_msg->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER)) + { + /*send mac del message to mclagsyncd.*/ + if (mac_msg->fdb_type != MAC_TYPE_STATIC) + del_mac_from_chip(mac_msg); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, del MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*If local and peer both aged, del the mac*/ + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + else + { + /*If local is aged but peer is not aged, redirect the mac to peer-link*/ + if (strlen(csm->peer_itf_name) != 0) + { + /*Send mac add message to mclagsyncd. fdb_type is not changed*/ + /*Is need to delete the old item before add?(Old item probably is static)*/ + if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP) + { + memcpy(mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); + add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC); + } + else + { + /*must redirect but peerlink is down, del mac from ASIC*/ + /*if peerlink change to up, mac will add back to ASIC*/ + del_mac_from_chip(mac_msg); + memcpy(mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); + } + + ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, redirect MAC %s vlan-id %d to peer-link %s", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, csm->peer_itf_name); + } + else + { + /*peer-link is not configured, del mac from ASIC, mac still in mac_list*/ + del_mac_from_chip(mac_msg); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, peer-link is not configured: MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + } + } + } + else /*portchannel up*/ + { + /*the old item is redirect to peerlink for portchannel down*/ + /*when this portchannel up, recover the mac back*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s up, redirect MAC %s vlan-id %d from peerlink to %s", + mac_msg->origin_ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->origin_ifname); + + /*Remove MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0); + + /*Reverse interface from peer-link to the original portchannel*/ + memcpy(mac_msg->ifname, mac_msg->origin_ifname, MAX_L_PORT_NAME); + + /*Send dynamic or static mac add message to mclagsyncd*/ + add_mac_to_chip(mac_msg, mac_msg->fdb_type); + } + else + { + /*this may be peerlink is not configured and portchannel is down*/ + /*when this portchannel up, add the mac back to ASIC*/ + ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s up, add MAC %s vlan-id %d to ASIC", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*Remove MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0); + + /*Send dynamic or static mac add message to mclagsyncd*/ + add_mac_to_chip(mac_msg, mac_msg->fdb_type); + } + } + } + + return; +} + +void mlacp_portchannel_state_handler(struct CSM* csm, + struct LocalInterface* local_if, + int po_state) +{ + if (!csm || !local_if) + return; + + update_peerlink_isolate_from_lif(csm, local_if, po_state); + + update_l2_mac_state(csm, local_if, po_state); + + if (!local_if_is_l3_mode(local_if)) + update_l2_po_state(csm, local_if, po_state); + else + update_l3_po_state(csm, local_if, po_state); + + update_po_if_info(csm, local_if, po_state); + + return; +} + +static void mlacp_conn_handler_fdb(struct CSM* csm) +{ + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + struct Msg *msg_send = NULL; + + if (!csm) + return; + + if (!TAILQ_EMPTY(&(MLACP(csm).mac_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + /*Wait the ACK from peer?*/ + /*mac_msg->age_flag &= ~MAC_AGE_PEER;*/ + + /*If MAC with local age flag, dont sync to peer. Such MAC only exist when peer is warm-reboot. + If peer is warm-reboot, peer age flag is not set when connection is lost. + When MAC is aged in local switch, this MAC is not deleted for no peer age flag. + After warm-reboot, this MAC must be learnt by peer and sync to local switch*/ + if (!(mac_msg->age_flag & MAC_AGE_LOCAL)) + { + /*Send mac add message to peer*/ + mac_msg->op_type = MAC_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + mac_msg->age_flag &= ~MAC_AGE_PEER; + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); + ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + } + } + else + { + /*If MAC with local age flag and is point to MCLAG enabled port, reomove local age flag*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list not enqueue for local age flag: %s, mac %s vlan-id %d, remove local age flag", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + mac_msg->age_flag &= ~MAC_AGE_LOCAL; + } + } + } + } + + return; +} + +static void mlacp_fix_bridge_mac(struct CSM* csm) +{ + char syscmd[128]; + int ret = 0; + char macaddr[64]; + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + if (memcmp(MLACP(csm).system_id, null_mac, ETHER_ADDR_LEN) != 0) + { + memset(macaddr, 0, 64); + snprintf(macaddr, 64, "%02x:%02x:%02x:%02x:%02x:%02x", + MLACP(csm).system_id[0], MLACP(csm).system_id[1], MLACP(csm).system_id[2], + MLACP(csm).system_id[3], MLACP(csm).system_id[4], MLACP(csm).system_id[5]); + + /*When changing the mac of a vlan member port, the mac of Bridge will be changed.*/ + /*The Bridge mac can not be the same as peer system id, so fix the Bridge MAC address here.*/ + sprintf(syscmd, "ip link set dev Bridge address %s > /dev/null 2>&1", macaddr); + ret = system(syscmd); + ICCPD_LOG_DEBUG(__FUNCTION__, " %s ret = %d", syscmd, ret); + } + + return; +} + +/***************************************** +* Peer connect/disconnect handler +* +* ***************************************/ +void mlacp_peer_conn_handler(struct CSM* csm) +{ + struct LocalInterface *lif = NULL; + static int once_connected = 0; + struct System* sys = NULL; + + if (!csm) + return; + + if ((sys = system_get_instance()) == NULL) + return; + + if (csm->warm_reboot_disconn_time != 0) + { + /*If peer reconnected, reset peer disconnect time*/ + csm->warm_reboot_disconn_time = 0; + ICCPD_LOG_DEBUG(__FUNCTION__, "Peer warm reboot and reconnect, reset peer disconnect time!"); + } + + if (csm->peer_link_if) + { + set_peerlink_mlag_port_learn(csm->peer_link_if, 0); + } + + /*If peer connect again, don't flush FDB*/ + if (once_connected == 0) + { + once_connected = 1; + mlacp_fix_bridge_mac(csm); + /*If warm reboot, don't flush FDB*/ + if (sys->warmboot_start != WARM_REBOOT) + mlacp_clean_fdb(); + } + + iccp_get_fdb_change_from_syncd(); + sys->csm_trans_time = time(NULL); + + mlacp_conn_handler_fdb(csm); + +#if 0 + // When peer-link ready, suppose all MLAG link are alive + LIST_FOREACH(pif, &(MLACP(csm).pif_list), mlacp_next) + { + pif->po_active = 1; + } +#endif + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif->type == IF_T_PORT_CHANNEL) + { +#if 0 + if (local_if_is_l3_mode(lif)) + { + set_route_by_linux_route( csm, lif, 1); + } + else + { + LIST_FOREACH(vlan, &(lif->vlan_list), port_next) + { + if (!vlan->vlan_itf) + continue; + if (!local_if_is_l3_mode(vlan->vlan_itf)) + continue; + + set_route_by_linux_route(csm, vlan->vlan_itf, 1); /* add static route by linux route tool*/ + } + } +#endif + + mlacp_portchannel_state_handler(csm, lif, (lif->state == PORT_STATE_UP) ? 1 : 0); + } + } + + return; +} + +extern void recover_if_ipmac_on_standby(struct LocalInterface* lif_po); +void mlacp_peer_disconn_handler(struct CSM* csm) +{ + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + struct LocalInterface* lif = NULL; + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + struct System* sys = NULL; + + if (!csm) + return; + + if ((sys = system_get_instance()) == NULL) + return; + + /*If warm reboot, don't change FDB and MAC address*/ + if (sys->warmboot_exit == WARM_REBOOT) + return; + + /*If peer is warm reboot, don't change FDB*/ + if (csm->peer_warm_reboot_time != 0) + { + /*If peer disconnected, recover peer to normal reboot for next time*/ + csm->peer_warm_reboot_time = 0; + /*peer connection must be establised again within 90s + from last disconnection for peer warm reboot*/ + time(&csm->warm_reboot_disconn_time); + ICCPD_LOG_DEBUG(__FUNCTION__, "Peer warm reboot and disconnect, recover to normal reboot for next time!"); + return; + } + + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + mac_msg->age_flag |= MAC_AGE_PEER; + ICCPD_LOG_DEBUG(__FUNCTION__, "Add peer age flag: %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /* find the MAC that the port is peer-link or local and peer both aged, to be deleted*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0 && mac_msg->age_flag != (MAC_AGE_LOCAL | MAC_AGE_PEER)) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Peer disconnect, del MAC for peer-link: %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*Send mac del message to mclagsyncd, may be already deleted*/ + del_mac_from_chip(mac_msg); + + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + + /* Clean all port block*/ + peerlink_port_isolate_cleanup(csm); + + memcpy(MLACP(csm).remote_system.system_id, null_mac, ETHER_ADDR_LEN); + + /*If peer is disconnected, recover the MAC address.*/ + if (csm->role_type == STP_ROLE_STANDBY) + { + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + recover_if_ipmac_on_standby(lif); + } + } + + return; +} + +void mlacp_peerlink_up_handler(struct CSM* csm) +{ + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + + if (!csm) + return; + + /*If peer link up, set all the mac that point to the peer-link in ASIC*/ + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + /* Find the MAC that the port is peer-link to be added*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Peer link up, add MAC to ASIC for peer-link: %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*Send mac add message to mclagsyncd, local age flag is already set*/ + add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC); + } + + return; +} + +void mlacp_peerlink_down_handler(struct CSM* csm) +{ + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + + if (!csm) + return; + + /*If peer link down, remove all the mac that point to the peer-link*/ + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + /* Find the MAC that the port is peer-link to be deleted*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Peer link down, del MAC for peer-link: %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); + + /*Send mac del message to mclagsyncd*/ + del_mac_from_chip(mac_msg); + + /*If peer is not age, keep the MAC in mac_list, but ASIC is deleted*/ + if (mac_msg->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER)) + { + /*If local and peer both aged, del the mac*/ + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + } + + return; +} + +/***************************************** +* Po add/remove handler +* +*****************************************/ +void mlacp_mlag_link_add_handler(struct CSM *csm, struct LocalInterface *lif) +{ + if (!csm || !lif) + return; + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return; + + set_peerlink_mlag_port_isolate(csm, lif, 1); + + return; +} + +void mlacp_mlag_link_del_handler(struct CSM *csm, struct LocalInterface *lif) +{ + if (!csm || !lif) + return; + + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return; + + set_peerlink_mlag_port_isolate(csm, lif, 0); + + return; +} + +int iccp_connect_syncd() +{ + struct System* sys = NULL; + int ret = 0; + int fd = 0; + struct sockaddr_in serv; + static int count = 0; + struct epoll_event event; + + if ((sys = system_get_instance()) == NULL) + goto conn_fail; + + if (sys->sync_fd >= 0) + return 0; + + /*Print the fail log message every 60s*/ + if (count >= 600) + { + count = 0; + } + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) + { + if (count == 0) + ICCPD_LOG_WARN(__FUNCTION__, "Failed to create unix socket: %s", strerror(errno)); + goto conn_fail; + } + + /* Make server socket. */ + memset(&serv, 0, sizeof(serv)); + serv.sin_family = AF_INET; + serv.sin_port = htons(2626); +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + serv.sin_len = sizeof(struct sockaddr_in); +#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ + serv.sin_addr.s_addr = htonl(0x7f000006); + + ret = connect(fd, (struct sockaddr *)&serv, sizeof(serv)); + if (ret < 0) + { + if (count == 0) + ICCPD_LOG_WARN(__FUNCTION__, "Failed to connect to mclag syncd: errno str %s", strerror(errno)); + close(fd); + goto conn_fail; + } + + ICCPD_LOG_NOTICE(__FUNCTION__, "Success to link syncd"); + sys->sync_fd = fd; + + event.data.fd = fd; + event.events = EPOLLIN; + ret = epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, fd, &event); + + count = 0; + return 0; + + conn_fail: + if (count == 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Mclag syncd socket connect fail"); + + count++; + + return MCLAG_ERROR; +} + +void syncd_info_close() +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + if (sys->sync_fd > 0) + { + close(sys->sync_fd); + sys->sync_fd = -1; + } + + return; +} + +int iccp_get_receive_fdb_sock_fd(struct System *sys) +{ + return sys->sync_fd; +} + +/*When received MAC add and del packets from mclagsyncd, update mac information*/ +void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, char *ifname, uint8_t fdb_type, uint8_t op_type) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct MACMsg *mac_msg = NULL, *mac_info = NULL; + uint8_t mac_exist = 0; + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + uint8_t from_mclag_intf = 0;/*0: orphan port, 1: MCLAG port*/ + struct CSM *first_csm = NULL; + + struct LocalInterface *lif_po = NULL, *mac_lif = NULL; + + if (!(sys = system_get_instance())) + return; + + /* create MAC msg*/ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct MACMsg); + mac_msg = (struct MACMsg*)buf; + mac_msg->op_type = op_type; + mac_msg->fdb_type = fdb_type; + sprintf(mac_msg->mac_str, "%s", mac_str); + mac_msg->vid = vid; + + mac_msg->age_flag = 0; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC msg from mclagsyncd, vid %d mac %s port %s optype %s ", vid, mac_str, ifname, op_type == MAC_SYNC_ADD ? "add" : "del"); + /*Debug*/ + #if 0 + /* dump receive MAC info*/ + fprintf(stderr, "\n======== MAC Update==========\n"); + fprintf(stderr, " MAC = %s\n", mac_str); + fprintf(stderr, " vlan id = %d\n", vid); + fprintf(stderr, " fdb type = %s\n", fdb_type == MAC_TYPE_STATIC ? "static" : "dynamic"); + fprintf(stderr, " op type = %s\n", op_type == MAC_SYNC_ADD ? "add" : "del"); + fprintf(stderr, "==============================\n"); + #endif + + /* Find MLACP itf, may be mclag enabled port-channel*/ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (csm && !first_csm) + { + /*Record the first CSM, only one CSM in the system currently*/ + first_csm = csm; + } + + /*If MAC is from peer-link, break; peer-link is not in MLACP(csm).lif_list*/ + if (strcmp(ifname, csm->peer_itf_name) == 0) + break; + + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (strcmp(lif_po->name, ifname) == 0) + { + from_mclag_intf = 1; + break; + } + } + + if (from_mclag_intf == 1) + break; + } + + if (!first_csm) + return; + + /*If support multiple CSM, the MAC list of orphan port must be moved to sys->mac_list*/ + csm = first_csm; + + /* find lif MAC+vid*/ + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_info = (struct MACMsg*)msg->buf; + + /*MAC and vid are equal*/ + if (strcmp(mac_info->mac_str, mac_str) == 0 && mac_info->vid == vid) + { + mac_exist = 1; + break; + } + } + + /*handle mac add*/ + if (op_type == MAC_SYNC_ADD) + { + /* Find local itf*/ + if (!(mac_lif = local_if_find_by_name(ifname))) + return; + + sprintf(mac_msg->ifname, "%s", ifname); + sprintf(mac_msg->origin_ifname, "%s", ifname); + + /*same MAC exist*/ + if (mac_exist) + { + /*If the recv mac port is peer-link, that is add from iccpd, no need to handle*/ + if (strcmp(csm->peer_itf_name, mac_msg->ifname) == 0) + { + return; + } + + /*If the current mac port is peer-link, it will handle by port up event*/ + /*if(strcmp(csm->peer_itf_name, mac_info->ifname) == 0) + { + return; + }*/ + + /* update MAC*/ + if (mac_info->fdb_type != mac_msg->fdb_type + || strcmp(mac_info->ifname, mac_msg->ifname) != 0 + || strcmp(mac_info->origin_ifname, mac_msg->ifname) != 0) + { + mac_info->fdb_type = mac_msg->fdb_type; + sprintf(mac_info->ifname, "%s", mac_msg->ifname); + sprintf(mac_info->origin_ifname, "%s", mac_msg->ifname); + + /*Remove MAC_AGE_LOCAL flag*/ + mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 0); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Update MAC for %s, ifname %s", mac_msg->mac_str, mac_msg->ifname); + } + else + { + /*All info are the same, Remove MAC_AGE_LOCAL flag, then return*/ + /*In theory, this will be happened that mac age and then learn*/ + mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 0); + + return; + } + } + else/*same MAC not exist*/ + { + /*If the port the mac learn is change to down before the mac + sync to iccp, this mac must be deleted */ + if (mac_lif->state == PORT_STATE_DOWN) + { + del_mac_from_chip(mac_msg); + + return; + } + + /*set MAC_AGE_PEER flag before send this item to peer*/ + mac_msg->age_flag |= MAC_AGE_PEER; + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add peer age flag: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/ + mac_msg->op_type = MAC_SYNC_ADD; + + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + struct Msg *msg_send = NULL; + if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, msg_len) == 0) + { + mac_msg->age_flag &= ~MAC_AGE_PEER; + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); + + /*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/ + } + else + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue MAC-msg-list: %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + } + } + + /*enqueue mac to mac-list*/ + if (iccp_csm_init_msg(&msg, (char*)mac_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_list), msg, tail); + + /*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-list enqueue: %s, add %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);*/ + } + else + ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue MAC %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + } + } + else/*handle mac del*/ + { + /*same MAC exist*/ + if (mac_exist) + { + /*orphan port mac or origin from_mclag_intf but state is down*/ + if (strcmp(mac_info->ifname, csm->peer_itf_name) == 0) + { + /*Set MAC_AGE_LOCAL flag*/ + mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 1); + + if (mac_info->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER)) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s(peer-link), del %s vlan-id %d", + mac_info->ifname, mac_info->mac_str, mac_info->vid); + + /*If peer link is down, del the mac*/ + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + else if (csm->peer_link_if && csm->peer_link_if->state != PORT_STATE_DOWN) + { + /*peer-link learn mac is control by iccpd, ignore the chip del info*/ + add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s(peer-link is up), add back %s vlan-id %d", + mac_info->ifname, mac_info->mac_str, mac_info->vid); + } + + return; + } + + /*Add MAC_AGE_LOCAL flag*/ + mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 1); + + if (mac_info->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER)) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s, del %s vlan-id %d", + mac_info->ifname, mac_info->mac_str, mac_info->vid); + + /*If local and peer both aged, del the mac (local orphan mac is here)*/ + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + else + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s, del %s vlan-id %d, peer is not age, add back to chip", + mac_info->ifname, mac_info->mac_str, mac_info->vid); + + mac_info->fdb_type = MAC_TYPE_DYNAMIC; + + if (from_mclag_intf && lif_po && lif_po->state == PORT_STATE_DOWN) + { + /*If local if is down, redirect the mac to peer-link*/ + if (strlen(csm->peer_itf_name) != 0) + { + memcpy(&mac_info->ifname, csm->peer_itf_name, IFNAMSIZ); + + if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP) + { + add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s(down), del %s vlan-id %d, redirect to peer-link", + mac_info->ifname, mac_info->mac_str, mac_info->vid); + } + } + + return; + } + + /*If local is aged but peer is not aged, Send mac add message to mclagsyncd*/ + /*it is from_mclag_intf and port state is up, local orphan mac can not be here*/ + /* Find local itf*/ + if (!(mac_lif = local_if_find_by_name(mac_info->ifname))) + return; + if (mac_lif->state == PORT_STATE_UP) + add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); + } + } + } + + return; +} + +int iccp_receive_fdb_handler_from_syncd(struct System *sys) +{ + char *msg_buf = g_csm_buf; + struct IccpSyncdHDr *msg_hdr; + struct mclag_fdb_info * mac_info; + size_t pos = 0; + int count = 0; + int i = 0; + int n = 0; + + if (sys == NULL) + return MCLAG_ERROR; + + memset(msg_buf, 0, CSM_BUFFER_SIZE); + + n = read(sys->sync_fd, msg_buf, CSM_BUFFER_SIZE); + if (n <= 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "read msg error!!!" ); + return MCLAG_ERROR; + } + + while (pos < n) + { + msg_hdr = (struct IccpSyncdHDr *)&msg_buf[pos]; + if (msg_hdr->ver != 1 || msg_hdr->type != MCLAG_SYNCD_MSG_TYPE_FDB_OPERATION ) + { + ICCPD_LOG_ERR(__FUNCTION__, "msg version or type wrong!!!!! "); + return MCLAG_ERROR; + } + + count = ( msg_hdr->len - sizeof(struct IccpSyncdHDr )) / sizeof(struct mclag_fdb_info); + ICCPD_LOG_DEBUG(__FUNCTION__, "recv msg fdb count %d ", count); + + for (i = 0; i < count; i++) + { + mac_info = (struct mclag_fdb_info *)&msg_buf[pos + sizeof(struct IccpSyncdHDr ) + i * sizeof(struct mclag_fdb_info)]; + /*ICCPD_LOG_DEBUG(__FUNCTION__, "recv msg fdb count %d vid %d mac %s port %s optype %s ", i, mac_info->vid, mac_info->mac, mac_info->port_name, mac_info->op_type == MAC_SYNC_ADD ? "add" : "del");*/ + do_mac_update_from_syncd(mac_info->mac, mac_info->vid, mac_info->port_name, mac_info->type, mac_info->op_type); + } + + pos += msg_hdr->len; + } + + return 0; +} + +char * mclagd_ctl_cmd_str(int req_type) +{ + switch (req_type) + { + case INFO_TYPE_DUMP_STATE: + return "dump config"; + + case INFO_TYPE_DUMP_ARP: + return "dump arp"; + + case INFO_TYPE_DUMP_MAC: + return "dump mac"; + + case INFO_TYPE_DUMP_LOCAL_PORTLIST: + return "dump local portlist"; + + case INFO_TYPE_DUMP_PEER_PORTLIST: + return "dump peer portlist"; + + case INFO_TYPE_CONFIG_LOGLEVEL: + return "config loglevel"; + default: + break; + } + + return "error req type"; +} + +int mclagd_ctl_sock_create() +{ + struct sockaddr_un addr; + struct System* sys = NULL; + struct epoll_event event; + int addr_len; + int ret = 0; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + if (sys->sync_ctrl_fd > 0) + return sys->sync_ctrl_fd; + + sys->sync_ctrl_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sys->sync_ctrl_fd < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to create mclagd ctl sock"); + return sys->sync_ctrl_fd; + } + + unlink(sys->mclagdctl_file_path); + + memset((void*)&addr, 0, sizeof(struct sockaddr_un)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, 107, "%s", sys->mclagdctl_file_path); + addr_len = sizeof(addr.sun_family) + strlen(sys->mclagdctl_file_path); + + if ((ret = bind(sys->sync_ctrl_fd, (struct sockaddr*)&addr, addr_len)) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to bind mclagd ctl socket %s:%s", sys->mclagdctl_file_path, strerror(errno)); + close(sys->sync_ctrl_fd); + return MCLAG_ERROR; + } + + if (listen(sys->sync_ctrl_fd, 5) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to listen unix mclagd ctl socket%s:%s", sys->mclagdctl_file_path, strerror(errno)); + close(sys->sync_ctrl_fd); + return MCLAG_ERROR; + } + + event.data.fd = sys->sync_ctrl_fd; + event.events = EPOLLIN; + epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, sys->sync_ctrl_fd, &event); + FD_SET(sys->sync_ctrl_fd, &(sys->readfd)); + sys->readfd_count++; + + return sys->sync_ctrl_fd; +} + +int mclagd_ctl_sock_accept(int fd) +{ + struct sockaddr_in client_addr; + int client_fd = 0; + unsigned int addr_len = 0; + + client_fd = accept(fd, (struct sockaddr*)&client_addr, &addr_len); + if (client_fd < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to accept a client from mclagdctl"); + return MCLAG_ERROR; + } + + return client_fd; +} + +int mclagd_ctl_sock_read(int fd, char *r_buf, int total_len) +{ + int read_len = 0; + int ret = 0; + struct timeval tv = { 0 }; + fd_set read_fd; + + while (read_len < total_len) + { + FD_ZERO(&read_fd); + FD_SET(fd, &read_fd); + tv.tv_sec = 5; + tv.tv_usec = 0; + + switch ((ret = select(fd + 1, &read_fd, NULL, NULL, &tv))) + { + case -1: + /* error*/ + case 0: + /* timeout*/ + return MCLAG_ERROR; + + default: + break; + } + + if (FD_ISSET(fd, &read_fd)) + ret = read(fd, r_buf + read_len, total_len - read_len); + if (ret <= 0) + { + return MCLAG_ERROR; + } + read_len += ret; + } + + return read_len; +} + +int mclagd_ctl_sock_write(int fd, char *w_buf, int total_len) +{ + int write_len = 0; + int ret = 0; + + while (write_len < total_len) + { + ret = write(fd, w_buf + write_len, total_len - write_len); + if (ret <= 0) + { + return 0; + } + write_len += ret; + } + + return write_len; +} + +void mclagd_ctl_handle_dump_state(int client_fd, int mclag_id) +{ + char * Pbuf = NULL; + char buf[512] = { 0 }; + int state_num = 0; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_mclag_config_dump(&Pbuf, &state_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_STATE; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_STATE; + hd->data_len = state_num * sizeof(struct mclagd_state); + + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + +void mclagd_ctl_handle_dump_arp(int client_fd, int mclag_id) +{ + char * Pbuf = NULL; + char buf[512] = { 0 }; + int arp_num = 0; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_arp_dump(&Pbuf, &arp_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_ARP; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_ARP; + hd->data_len = arp_num * sizeof(struct mclagd_arp_msg); + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + +void mclagd_ctl_handle_dump_mac(int client_fd, int mclag_id) +{ + char * Pbuf = NULL; + char buf[512] = { 0 }; + int mac_num = 0; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_mac_dump(&Pbuf, &mac_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_MAC; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_MAC; + hd->data_len = mac_num * sizeof(struct mclagd_mac_msg); + + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + +void mclagd_ctl_handle_dump_local_portlist(int client_fd, int mclag_id) +{ + char * Pbuf = NULL; + char buf[512] = { 0 }; + int lif_num = 0;; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_local_if_dump(&Pbuf, &lif_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_LOCAL_PORTLIST; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_LOCAL_PORTLIST; + hd->data_len = lif_num * sizeof(struct mclagd_local_if); + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + +void mclagd_ctl_handle_dump_peer_portlist(int client_fd, int mclag_id) +{ + char * Pbuf = NULL; + char buf[512] = { 0 }; + int pif_num = 0; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_peer_if_dump(&Pbuf, &pif_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_PEER_PORTLIST; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_PEER_PORTLIST; + hd->data_len = pif_num * sizeof(struct mclagd_peer_if); + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + +void mclagd_ctl_handle_config_loglevel(int client_fd, int log_level) +{ + char buf[sizeof(struct mclagd_reply_hdr)+sizeof(int)]; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + logger_set_configuration(log_level); + + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_CONFIG_LOGLEVEL; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + return; +} + +int mclagd_ctl_interactive_process(int client_fd) +{ + char buf[512] = { 0 }; + int ret = 0; + + struct mclagdctl_req_hdr* req = NULL; + + if (client_fd < 0) + return MCLAG_ERROR; + + ret = mclagd_ctl_sock_read(client_fd, buf, sizeof(struct mclagdctl_req_hdr)); + + if (ret < 0) + return MCLAG_ERROR; + + req = (struct mclagdctl_req_hdr*)buf; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Receive request %s from mclagdctl", mclagd_ctl_cmd_str(req->info_type)); + + switch (req->info_type) + { + case INFO_TYPE_DUMP_STATE: + mclagd_ctl_handle_dump_state(client_fd, req->mclag_id); + break; + + case INFO_TYPE_DUMP_ARP: + mclagd_ctl_handle_dump_arp(client_fd, req->mclag_id); + break; + + case INFO_TYPE_DUMP_MAC: + mclagd_ctl_handle_dump_mac(client_fd, req->mclag_id); + break; + + case INFO_TYPE_DUMP_LOCAL_PORTLIST: + mclagd_ctl_handle_dump_local_portlist(client_fd, req->mclag_id); + break; + + case INFO_TYPE_DUMP_PEER_PORTLIST: + mclagd_ctl_handle_dump_peer_portlist(client_fd, req->mclag_id); + break; + + case INFO_TYPE_CONFIG_LOGLEVEL: + mclagd_ctl_handle_config_loglevel(client_fd, req->mclag_id); + break; + + default: + return MCLAG_ERROR; + } + + return 0; +} + + diff --git a/src/iccpd/src/mlacp_sync_prepare.c b/src/iccpd/src/mlacp_sync_prepare.c new file mode 100644 index 000000000000..f40a59884e49 --- /dev/null +++ b/src/iccpd/src/mlacp_sync_prepare.c @@ -0,0 +1,624 @@ +/* + * MLACP Sync Infomation Preparation + * mlacp_sync_prepare.c + + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + * + */ + +#include +#include + +#include + +#include "../include/system.h" +#include "../include/logger.h" +#include "../include/mlacp_fsm.h" +#include "../include/mlacp_tlv.h" +#include "../include/mlacp_link_handler.h" +#include "../include/iccp_ifm.h" +#include "../include/iccp_csm.h" + +/***************************************** +* Static Function +* +* ***************************************/ +static int mlacp_fill_icc_header(struct CSM* csm, ICCHdr* icc_hdr, size_t msg_len); + +/***************************************** +* Create Sync Request TLV +* +* ***************************************/ +int mlacp_prepare_for_sync_request_tlv(struct CSM* csm, char* buf, size_t max_buf_size) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = NULL; + mLACPSyncReqTLV* tlv = NULL; + size_t msg_len = sizeof(ICCHdr) + sizeof(mLACPSyncReqTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (mLACPSyncReqTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* mLACP Synchronization Request TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_SYNC_REQUEST); + tlv->icc_parameter.len = htons(sizeof(mLACPSyncReqTLV) - sizeof(ICCParameter)); + + tlv->req_num = 0; + MLACP(csm).sync_req_num = 0; + + tlv->c_bit = 1; + tlv->s_bit = 1; + tlv->req_type = 0x3FFF; + *(uint16_t *)((uint8_t *)tlv + sizeof(ICCParameter) + sizeof(uint16_t)) = htons(*(uint16_t *)((uint8_t *)tlv + sizeof(ICCParameter) + sizeof(uint16_t))); + + tlv->port_num_agg_id = 0; + tlv->actor_key = 0; + + return msg_len; +} + +/***************************************** +* Prprare Sync Data TLV +* +* ***************************************/ +int mlacp_prepare_for_sync_data_tlv(struct CSM* csm, char* buf, size_t max_buf_size, int end) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = (ICCHdr*)buf; + mLACPSyncDataTLV* tlv = (mLACPSyncDataTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(mLACPSyncDataTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (mLACPSyncDataTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* mLACP Synchronization Data TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_SYNC_DATA); + tlv->icc_parameter.len = htons(sizeof(mLACPSyncDataTLV) - sizeof(ICCParameter)); + + tlv->req_num = htons(MLACP(csm).sync_req_num); + if (end == 0) + tlv->flags = 0x00; + else + tlv->flags = htons(0x01); + + return msg_len; +} + +/***************************************** +* Prprare Sync System-Config TLV +* +* ***************************************/ +int mlacp_prepare_for_sys_config(struct CSM* csm, char* buf, size_t max_buf_size) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = (ICCHdr*)buf; + mLACPSysConfigTLV* tlv = (mLACPSysConfigTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(mLACPSysConfigTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (mLACPSysConfigTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* System Config TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_SYSTEM_CONFIG); + tlv->icc_parameter.len = htons(sizeof(mLACPSysConfigTLV) - sizeof(ICCParameter)); + + memcpy(tlv->sys_id, MLACP(csm).system_id, ETHER_ADDR_LEN); + tlv->sys_priority = htons(MLACP(csm).system_priority); + tlv->node_id = MLACP(csm).node_id; + return msg_len; +} + +/*Prprare Sync AggPort-State TLV */ +int mlacp_prepare_for_Aggport_state(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* local_if) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = (ICCHdr*)buf; + mLACPAggPortStateTLV* tlv = (mLACPAggPortStateTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(mLACPAggPortStateTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (local_if == NULL) + return MCLAG_ERROR; + + if (local_if->type != IF_T_PORT_CHANNEL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (mLACPAggPortStateTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Port State TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_AGGREGATOR_STATE); + tlv->icc_parameter.len = htons(sizeof(mLACPAggPortStateTLV) - sizeof(ICCParameter)); + + tlv->partner_sys_priority = 0; + tlv->partner_key = 0; + tlv->agg_id = htons(local_if->po_id); + tlv->actor_key = 0; + tlv->agg_state = local_if->state; + + return msg_len; +} + +/***************************************** +* Prprare Sync Purge Port +* +* ***************************************/ +int mlacp_prepare_for_Aggport_config(struct CSM* csm, + char* buf, size_t max_buf_size, + struct LocalInterface* lif, int purge_flag) +{ + ICCHdr* icc_hdr = (ICCHdr*)buf; + mLACPAggConfigTLV* tlv = (mLACPAggConfigTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(mLACPAggConfigTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (mLACPAggConfigTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Port Config TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_AGGREGATOR_CONFIG); + + tlv->icc_parameter.len = htons(sizeof(mLACPAggConfigTLV) - sizeof(ICCParameter)); + tlv->agg_id = htons(lif->po_id); + if (purge_flag == 1) + tlv->flags = 0x02; /*purge*/ + else + tlv->flags = 0x1; + tlv->agg_name_len = strlen(lif->name); + memcpy(tlv->agg_name, lif->name, MAX_L_PORT_NAME); + memcpy(tlv->mac_addr, lif->mac_addr, ETHER_ADDR_LEN); + + return msg_len; +} + +/***************************************** +* Preprare Sync MAC-Info TLV +* +* ***************************************/ +int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_buf_size, struct MACMsg* mac_msg, int count) +{ + struct mLACPMACInfoTLV* tlv = NULL; + size_t msg_len = 0; + size_t tlv_len = 0; + ICCHdr* icc_hdr = NULL; + struct mLACPMACData *MacData; + + if (!csm) + return MCLAG_ERROR; + if (!buf) + return MCLAG_ERROR; + + tlv_len = sizeof(struct mLACPMACInfoTLV) + sizeof(struct mLACPMACData) * (count + 1); + + if ((msg_len = sizeof(ICCHdr) + tlv_len) > max_buf_size) + return MCLAG_ERROR; + + /* ICC header */ + icc_hdr = (ICCHdr*)buf; + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + /* Prepare for MAC information TLV */ + tlv = (struct mLACPMACInfoTLV*)&buf[sizeof(ICCHdr)]; + tlv->icc_parameter.len = htons(tlv_len - sizeof(ICCParameter)); + tlv->num_of_entry = htons(count + 1); + + if (count == 0) + { + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_MAC_INFO); + } + + MacData = (struct mLACPMACData *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPMACInfoTLV) + sizeof(struct mLACPMACData) * count]; + MacData->type = mac_msg->op_type; + sprintf(MacData->mac_str, "%s", mac_msg->mac_str); + sprintf(MacData->ifname, "%s", mac_msg->origin_ifname); + MacData->vid = htons(mac_msg->vid); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Send MAC messge to peer, port %s mac = %s, vid = %d, type = %s count %d ", mac_msg->origin_ifname, + mac_msg->mac_str, mac_msg->vid, mac_msg->op_type == MAC_SYNC_ADD ? "add" : "del", count); + + return msg_len; +} + +/***************************************** +* Preprare Sync ARP-Info TLV +* +* ***************************************/ +int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, struct ARPMsg* arp_msg, int count) +{ + struct mLACPARPInfoTLV* tlv = NULL; + size_t msg_len = 0; + size_t tlv_len = 0; + ICCHdr* icc_hdr = NULL; + struct ARPMsg* ArpData; + + if (!csm) + return MCLAG_ERROR; + if (!buf) + return MCLAG_ERROR; + + tlv_len = sizeof(struct mLACPARPInfoTLV) + sizeof(struct ARPMsg) * (count + 1); + + if ((msg_len = sizeof(ICCHdr) + tlv_len) > max_buf_size) + return MCLAG_ERROR; + + /* ICC header */ + icc_hdr = (ICCHdr*)buf; + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Prepare for ARP information TLV */ + tlv = (struct mLACPARPInfoTLV*)&buf[sizeof(ICCHdr)]; + tlv->icc_parameter.len = htons(tlv_len - sizeof(ICCParameter)); + tlv->num_of_entry = htons(count + 1); + + if (count == 0) + { + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_ARP_INFO); + } + + ArpData = (struct mLACPMACData *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPARPInfoTLV) + sizeof(struct ARPMsg) * count]; + + ArpData->op_type = arp_msg->op_type; + sprintf(ArpData->ifname, "%s", arp_msg->ifname); + ArpData->ipv4_addr = htonl(arp_msg->ipv4_addr); + memcpy(ArpData->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Send ARP messge to peer, if name %s mac %02x:%02x:%02x:%02x:%02x:%02x IP %s", ArpData->ifname, ArpData->mac_addr[0], ArpData->mac_addr[1], ArpData->mac_addr[2], + ArpData->mac_addr[3], ArpData->mac_addr[4], ArpData->mac_addr[5], show_ip_str( ArpData->ipv4_addr)); + + return msg_len; +} + +/***************************************** +* Prprare Send portchannel info +* +* ***************************************/ +int mlacp_prepare_for_port_channel_info(struct CSM* csm, char* buf, + size_t max_buf_size, + struct LocalInterface* port_channel) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = NULL; + struct mLACPPortChannelInfoTLV* tlv = NULL; + size_t msg_len; + size_t tlv_len; + size_t name_len = MAX_L_PORT_NAME; + struct VLAN_ID* vlan_id = NULL; + int num_of_vlan_id = 0; + + if (csm == NULL ) + return MCLAG_ERROR; + if (buf == NULL ) + return MCLAG_ERROR; + if (port_channel == NULL ) + return MCLAG_ERROR; + if (port_channel->type == IF_T_PORT) + return MCLAG_ERROR; + if ((sys = system_get_instance()) == NULL ) + return MCLAG_ERROR; + + /* Calculate VLAN ID Length */ + LIST_FOREACH(vlan_id, &(port_channel->vlan_list), port_next) + if (vlan_id != NULL) + num_of_vlan_id++; + + tlv_len = sizeof(struct mLACPPortChannelInfoTLV) + sizeof(struct mLACPVLANData) * num_of_vlan_id; + + if ((msg_len = sizeof(ICCHdr) + tlv_len) > max_buf_size) + return MCLAG_ERROR; + + /* Prepare for port channel info */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (struct mLACPPortChannelInfoTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Port Channel Info TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_PORT_CHANNEL_INFO); + tlv->icc_parameter.len = htons(sizeof(struct mLACPPortChannelInfoTLV) - sizeof(ICCParameter) + sizeof(struct mLACPVLANData) * num_of_vlan_id); + tlv->agg_id = htons(port_channel->po_id); + tlv->ipv4_addr = htonl(port_channel->ipv4_addr); + tlv->l3_mode = port_channel->l3_mode; + tlv->po_id = htons(port_channel->po_id); + + if (strlen(port_channel->name) < name_len) + name_len = strlen(port_channel->name); + memcpy(tlv->if_name, port_channel->name, name_len); + tlv->if_name_len = name_len; + tlv->num_of_vlan_id = htons(num_of_vlan_id); + + num_of_vlan_id = 0; + LIST_FOREACH(vlan_id, &(port_channel->vlan_list), port_next) + { + if (vlan_id != NULL ) + { + tlv->vlanData[num_of_vlan_id].vlan_id = htons(vlan_id->vid); + + num_of_vlan_id++; + ICCPD_LOG_DEBUG(__FUNCTION__, "PortChannel%d: ipv4 addr = %s vlan id %d num %d ", port_channel->po_id, show_ip_str( tlv->ipv4_addr), vlan_id->vid, num_of_vlan_id ); + } + } + + ICCPD_LOG_DEBUG(__FUNCTION__, "PortChannel%d: ipv4 addr = %s l3 mode %d", port_channel->po_id, show_ip_str( tlv->ipv4_addr), tlv->l3_mode); + + return msg_len; +} + +/***************************************** +* Prprare Send port peerlink info +* +* ***************************************/ +int mlacp_prepare_for_port_peerlink_info(struct CSM* csm, char* buf, + size_t max_buf_size, + struct LocalInterface* peerlink_port) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = NULL; + struct mLACPPeerLinkInfoTLV* tlv = NULL; + size_t msg_len; + size_t tlv_len; + + if (csm == NULL ) + return MCLAG_ERROR; + if (buf == NULL ) + return MCLAG_ERROR; + if (peerlink_port == NULL ) + return MCLAG_ERROR; + if ((sys = system_get_instance()) == NULL ) + return MCLAG_ERROR; + + /* Prepare for port channel info */ + memset(buf, 0, max_buf_size); + + tlv_len = sizeof(struct mLACPPeerLinkInfoTLV); + + if ((msg_len = sizeof(ICCHdr) + tlv_len) > max_buf_size) + return MCLAG_ERROR; + + icc_hdr = (ICCHdr*)buf; + tlv = (struct mLACPPeerLinkInfoTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Port Channel Info TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_PEERLINK_INFO); + + tlv->icc_parameter.len = htons(tlv_len - sizeof(ICCParameter)); + memcpy(tlv->if_name, peerlink_port->name, MAX_L_PORT_NAME); + tlv->port_type = peerlink_port->type; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port is %s, type = %d", tlv->if_name, tlv->port_type); + + return msg_len; +} + + +/***************************************** +* Prprare Send Heartbeat +* +* ***************************************/ +int mlacp_prepare_for_heartbeat(struct CSM* csm, char* buf, size_t max_buf_size) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = (ICCHdr*)buf; + struct mLACPHeartbeatTLV* tlv = (struct mLACPHeartbeatTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(struct mLACPHeartbeatTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (struct mLACPHeartbeatTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* System Config TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_HEARTBEAT); + + tlv->icc_parameter.len = htons(sizeof(struct mLACPHeartbeatTLV) - sizeof(ICCParameter)); + tlv->heartbeat = 0xFF; + return msg_len; +} + +/***************************************** +* Prepare Send warm-reboot flag +* +* ***************************************/ +int mlacp_prepare_for_warm_reboot(struct CSM* csm, char* buf, size_t max_buf_size) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = (ICCHdr*)buf; + struct mLACPWarmbootTLV* tlv = (struct mLACPWarmbootTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(struct mLACPWarmbootTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (struct mLACPWarmbootTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* System Config TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_WARMBOOT_FLAG); + + tlv->icc_parameter.len = htons(sizeof(struct mLACPWarmbootTLV) - sizeof(ICCParameter)); + tlv->warmboot = 0x1; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Send warm reboot notification to peer!"); + return msg_len; +} + +/***************************************** +* Tool : Prepare ICC Header +* +* ***************************************/ +static int mlacp_fill_icc_header(struct CSM* csm, ICCHdr* icc_hdr, size_t msg_len) +{ + if (csm == NULL || icc_hdr == NULL) + return MCLAG_ERROR; + + /* ICC header */ + icc_hdr->ldp_hdr.u_bit = 0x0; + icc_hdr->ldp_hdr.msg_type = htons(MSG_T_RG_APP_DATA); + + icc_hdr->ldp_hdr.msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + icc_hdr->ldp_hdr.msg_id = htonl(ICCP_MSG_ID); + ICCP_MSG_ID++; + iccp_csm_fill_icc_rg_id_tlv(csm, icc_hdr); + + return 0; +} + diff --git a/src/iccpd/src/mlacp_sync_update.c b/src/iccpd/src/mlacp_sync_update.c new file mode 100644 index 000000000000..40dc33187885 --- /dev/null +++ b/src/iccpd/src/mlacp_sync_update.c @@ -0,0 +1,740 @@ +/******************************************************************************** + * mlacp_sync_update.c + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + * + *******************************************************************************/ +#include +#include + +#include +#include + +#include "../include/system.h" +#include "../include/logger.h" +#include "../include/mlacp_tlv.h" +#include "../include/iccp_csm.h" +#include "../include/mlacp_link_handler.h" +#include "../include/iccp_consistency_check.h" +#include "../include/port.h" +/***************************************** +* Port-Conf Update +* +* ***************************************/ +extern void update_if_ipmac_on_standby(struct LocalInterface* lif_po); +int mlacp_fsm_update_system_conf(struct CSM* csm, mLACPSysConfigTLV*sysconf) +{ + struct LocalInterface* lif = NULL; + + /*NOTE + a little tricky, we change the NodeID local side if collision happened first time*/ + if (sysconf->node_id == MLACP(csm).node_id) + MLACP(csm).node_id++; + + memcpy(MLACP(csm).remote_system.system_id, sysconf->sys_id, ETHER_ADDR_LEN); + MLACP(csm).remote_system.system_priority = ntohs(sysconf->sys_priority); + MLACP(csm).remote_system.node_id = sysconf->node_id; + + ICCPD_LOG_DEBUG(__FUNCTION__, "SystemID [%02X:%02X:%02X:%02X:%02X:%02X], SystemPriority [%d], Remote NodeID [%d], NodeID [%d]", + MLACP(csm).remote_system.system_id[0], MLACP(csm).remote_system.system_id[1], MLACP(csm).remote_system.system_id[2], + MLACP(csm).remote_system.system_id[3], MLACP(csm).remote_system.system_id[4], MLACP(csm).remote_system.system_id[5], + MLACP(csm).remote_system.system_priority, + MLACP(csm).remote_system.node_id, + MLACP(csm).node_id); + + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + update_if_ipmac_on_standby(lif); + } + + return 0; +} + +/***************************************** +* Port-Conf Update +* +* ***************************************/ +int mlacp_fsm_update_Agg_conf(struct CSM* csm, mLACPAggConfigTLV* portconf) +{ + struct PeerInterface* pif = NULL; + uint8_t po_active; + uint8_t new_create = 0; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Port name %s, po id %d flag %d MAC[%02x:%02x:%02x:%02x:%02x:%02x] ", + portconf->agg_name, ntohs(portconf->agg_id), portconf->flags, portconf->mac_addr[0], portconf->mac_addr[1], portconf->mac_addr[2], + portconf->mac_addr[3], portconf->mac_addr[4], portconf->mac_addr[5] ); + + /* Looking for the peer port instance, is any peer if exist?*/ + pif = peer_if_find_by_name(csm, portconf->agg_name); + + /* Process purge*/ + if (portconf->flags & 0x02) + { + /*Purge*/ + if (pif != NULL ) + peer_if_destroy(pif); + else + MLACP(csm).need_to_sync = 1; + /*ICCPD_LOG_INFO("mlacp_fsm", + " Peer port %s is removed from port-channel member.",portconf->port_name);*/ + + return 0; + } + + if (pif == NULL && portconf->flags & 0x01) + { + pif = peer_if_create(csm, ntohs(portconf->agg_id), IF_T_PORT_CHANNEL); + if (pif == NULL) + return MCLAG_ERROR; + + new_create = 1; + } + + pif->po_id = ntohs(portconf->agg_id); + memcpy(pif->name, portconf->agg_name, portconf->agg_name_len); + memcpy(pif->mac_addr, portconf->mac_addr, ETHER_ADDR_LEN); + + po_active = (pif->state == PORT_STATE_UP); + update_stp_peer_link(csm, pif, po_active, new_create); + update_peerlink_isolate_from_pif(csm, pif, po_active, new_create); + pif->po_active = po_active; + + return 0; +} + +/***************************************** +* Agg Port-State Update +* +* ***************************************/ +int mlacp_fsm_update_Aggport_state(struct CSM* csm, mLACPAggPortStateTLV* tlv) +{ + struct PeerInterface* peer_if = NULL; + uint8_t po_active; + + if (csm == NULL || tlv == NULL) + return MCLAG_ERROR; + ICCPD_LOG_DEBUG(__FUNCTION__, "Portchannel id %d state %d", ntohs(tlv->agg_id), tlv->agg_state); + + po_active = (tlv->agg_state == PORT_STATE_UP); + + LIST_FOREACH(peer_if, &(MLACP(csm).pif_list), mlacp_next) + { + if (peer_if->type != IF_T_PORT_CHANNEL) + continue; + + if (peer_if->po_id != ntohs(tlv->agg_id)) + continue; + + peer_if->state = tlv->agg_state; + + update_stp_peer_link(csm, peer_if, po_active, 0); + update_peerlink_isolate_from_pif(csm, peer_if, po_active, 0); + + peer_if->po_active = po_active; + ICCPD_LOG_DEBUG(__FUNCTION__, "Update peer interface %s to state %s", peer_if->name, tlv->agg_state ? "down" : "up"); + + break; + } + + return 0; +} + +/***************************************** +* Recv from peer, MAC-Info Update +* ***************************************/ +int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData *MacData) +{ + + struct Msg* msg = NULL; + struct MACMsg *mac_msg = NULL, mac_data; + struct LocalInterface* local_if = NULL; + uint8_t from_mclag_intf = 0;/*0: orphan port, 1: MCLAG port*/ + + ICCPD_LOG_INFO(__FUNCTION__, + "Received MAC Info, port[%s] vid[%d] MAC[%s] type[%s]", + MacData->ifname, ntohs(MacData->vid), MacData->mac_str, MacData->type == MAC_SYNC_ADD ? "add" : "del"); + + /*Find the interface in MCLAG interface list*/ + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL && strcmp(local_if->name, MacData->ifname) == 0) + { + from_mclag_intf = 1; + break; + } + } + + /* update MAC list*/ + TAILQ_FOREACH(msg, &(MLACP(csm).mac_list), tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + /*Same MAC is exist in local switch, this may be mac move*/ + if (strcmp(mac_msg->mac_str, MacData->mac_str) == 0 && mac_msg->vid == ntohs(MacData->vid)) + { + if (MacData->type == MAC_SYNC_ADD) + { + mac_msg->age_flag &= ~MAC_AGE_PEER; + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ADD, Remove peer age flag:%d ifname %s, MAC %s vlan-id %d", + mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*mac_msg->fdb_type = tlv->fdb_type;*/ + /*The port ifname is different to the local item*/ + if (from_mclag_intf == 0 || strcmp(mac_msg->ifname, MacData->ifname) != 0 || strcmp(mac_msg->origin_ifname, MacData->ifname) != 0) + { + if (mac_msg->fdb_type != MAC_TYPE_STATIC) + { + /*Update local item*/ + memcpy(&mac_msg->origin_ifname, MacData->ifname, MAX_L_PORT_NAME); + } + + /*If the MAC is learned from orphan port, or from MCLAG port but the local port is down*/ + if (from_mclag_intf == 0 || (local_if->state == PORT_STATE_DOWN && strcmp(mac_msg->ifname, csm->peer_itf_name) != 0)) + { + /*Set MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); + + if (strlen(csm->peer_itf_name) != 0) + { + if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0) + { + /* This MAC is already point to peer-link */ + return 0; + } + + if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP) + { + /*Redirect the mac to peer-link*/ + memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); + + /*Send mac add message to mclagsyncd*/ + add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC); + } + else + { + /*must redirect but peerlink is down, del mac from ASIC*/ + /*if peerlink change to up, mac will add back to ASIC*/ + del_mac_from_chip(mac_msg); + + /*Redirect the mac to peer-link*/ + memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); + } + } + else + { + /*must redirect but no peerlink, del mac from ASIC*/ + del_mac_from_chip(mac_msg); + + /*Update local item*/ + memcpy(&mac_msg->ifname, MacData->ifname, MAX_L_PORT_NAME); + + /*if orphan port mac but no peerlink, don't keep this mac*/ + if (from_mclag_intf == 0) + { + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + return 0; + } + } + } + else + { + /*Remove MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0); + + /*Update local item*/ + memcpy(&mac_msg->ifname, MacData->ifname, MAX_L_PORT_NAME); + + /*from MCLAG port and the local port is up, add mac to ASIC to update port*/ + add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC); + } + } + + #if 0 + mac_msg->op_type = MAC_SYNC_ACK; + if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + /*Reply mac ack message to peer, peer will clean MAC_AGE_PEER flag*/ + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ADD, MAC-msg-list enqueue: %s, add %s vlan-id %d, op_type %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); + } + #endif + } + #if 0 + else if (tlv->type == MAC_SYNC_ACK) + { + /*Clean the MAC_AGE_PEER flag*/ + mac_msg->age_flag &= ~MAC_AGE_PEER; + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ACK, Remove peer age flag:%d ifname %s, add %s vlan-id %d, op_type %d", + mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); + } + #endif + + break; + } + } + + /* delete/add MAC list*/ + if (msg && MacData->type == MAC_SYNC_DEL) + { + mac_msg->age_flag |= MAC_AGE_PEER; + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv DEL, Add peer age flag: %d ifname %s, MAC %s vlan-id %d", + mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + if (mac_msg->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER)) + { + /*send mac del message to mclagsyncd.*/ + del_mac_from_chip(mac_msg); + + /*If local and peer both aged, del the mac*/ + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + else + { + return 0; + } + } + else if (!msg && MacData->type == MAC_SYNC_ADD) + { + mac_msg = (struct MACMsg*)&mac_data; + mac_msg->fdb_type = MAC_TYPE_DYNAMIC; + mac_msg->vid = ntohs(MacData->vid); + sprintf(mac_msg->mac_str, "%s", MacData->mac_str); + sprintf(mac_msg->ifname, "%s", MacData->ifname); + sprintf(mac_msg->origin_ifname, "%s", MacData->ifname); + mac_msg->age_flag = 0; + + /*If the MAC is learned from orphan port, or from MCLAG port but the local port is down*/ + if (from_mclag_intf == 0 || local_if->state == PORT_STATE_DOWN) + { + /*Set MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); + + if (strlen(csm->peer_itf_name) == 0) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "From orphan port or portchannel is down, but peer-link is not configured: ifname %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*if orphan port mac but no peerlink, don't keep this mac*/ + if (from_mclag_intf == 0) + return 0; + } + else + { + /*Redirect the mac to peer-link*/ + memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Redirect to peerlink for orphan port or portchannel is down, Add local age flag: %d ifname %s, MAC %s vlan-id %d", + mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + } + } + else + { + /*Remove MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0); + } + + if (iccp_csm_init_msg(&msg, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_list), msg, tail); + /*ICCPD_LOG_INFO(__FUNCTION__, "add mac queue successfully");*/ + + /*If the mac is from orphan port, or from MCLAG port but the local port is down*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0) + { + /*Send mac add message to mclagsyncd*/ + if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP) + add_mac_to_chip(mac_msg, mac_msg->fdb_type); + } + else + { + /*from MCLAG port and the local port is up*/ + add_mac_to_chip(mac_msg, mac_msg->fdb_type); + } + + #if 0 + mac_msg->op_type = MAC_SYNC_ACK; + if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + /*Reply mac ack message to peer, peer will clean MAC_AGE_PEER flag*/ + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); + ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, op_type %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); + } + #endif + } + } + + return 0; +} + +int mlacp_fsm_update_mac_info_from_peer(struct CSM* csm, struct mLACPMACInfoTLV* tlv) +{ + int count = 0; + int i; + + if (!csm || !tlv) + return MCLAG_ERROR; + count = ntohs(tlv->num_of_entry); + ICCPD_LOG_INFO(__FUNCTION__, "Received MAC Info count %d", count ); + + for (i = 0; i < count; i++) + { + mlacp_fsm_update_mac_entry_from_peer(csm, &(tlv->MacEntry[i])); + } +} + +/***************************************** + * Tool : Add ARP Info into ARP list + * + ****************************************/ +void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg) +{ + struct ARPMsg *arp_msg = NULL; + + if (!csm) + { + if (msg) + free(msg); + return; + } + if (!msg) + return; + + arp_msg = (struct ARPMsg*)msg->buf; + if (arp_msg->op_type != ARP_SYNC_DEL) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_list), msg, tail); + } + + return; +} + +/***************************************** +* ARP-Info Update +* ***************************************/ +int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) +{ + struct Msg* msg = NULL; + struct ARPMsg *arp_msg = NULL, arp_data; + struct LocalInterface* local_if; + struct LocalInterface *peer_link_if = NULL; + struct VLAN_ID *vlan_id_list = NULL; + int set_arp_flag = 0; + char mac_str[18] = ""; + + if (!csm || !arp_entry) + return MCLAG_ERROR; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", arp_entry->mac_addr[0], arp_entry->mac_addr[1], arp_entry->mac_addr[2], + arp_entry->mac_addr[3], arp_entry->mac_addr[4], arp_entry->mac_addr[5]); + + ICCPD_LOG_INFO(__FUNCTION__, + "Received ARP Info, intf[%s] IP[%s], MAC[%02x:%02x:%02x:%02x:%02x:%02x]", + arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), + arp_entry->mac_addr[0], arp_entry->mac_addr[1], arp_entry->mac_addr[2], + arp_entry->mac_addr[3], arp_entry->mac_addr[4], arp_entry->mac_addr[5]); + + if (strncmp(arp_entry->ifname, "Vlan", 4) == 0) + { + peer_link_if = local_if_find_by_name(csm->peer_itf_name); + + if (peer_link_if && !local_if_is_l3_mode(peer_link_if)) + { + /* Is peer-linlk itf belong to a vlan the same as peer?*/ + LIST_FOREACH(vlan_id_list, &(peer_link_if->vlan_list), port_next) + { + if (!vlan_id_list->vlan_itf) + continue; + if (strcmp(vlan_id_list->vlan_itf->name, arp_entry->ifname) != 0) + continue; + if (!local_if_is_l3_mode(vlan_id_list->vlan_itf)) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is learnt from intf %s, peer-link %s is the member of this vlan", + vlan_id_list->vlan_itf->name, peer_link_if->name); + + /* Peer-link belong to L3 vlan is alive, set the ARP info*/ + set_arp_flag = 1; + + break; + } + } + } + + if (set_arp_flag == 0) + { + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + if (!local_if_is_l3_mode(local_if)) + { + /* Is the L2 MLAG itf belong to a vlan the same as peer?*/ + LIST_FOREACH(vlan_id_list, &(local_if->vlan_list), port_next) + { + if (!vlan_id_list->vlan_itf) + continue; + if (strcmp(vlan_id_list->vlan_itf->name, arp_entry->ifname) != 0) + continue; + if (!local_if_is_l3_mode(vlan_id_list->vlan_itf)) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is learnt from intf %s, mclag %s is the member of this vlan", + vlan_id_list->vlan_itf->name, local_if->name); + break; + } + + if (vlan_id_list && local_if->po_active == 1) + { + /* Any po of L3 vlan is alive, set the ARP info*/ + set_arp_flag = 1; + break; + } + } + else + { + /* Is the ARP belong to a L3 mode MLAG itf?*/ + if (strcmp(local_if->name, arp_entry->ifname) == 0) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is learnt from mclag L3 intf %s", local_if->name); + if (local_if->po_active == 1) + { + /* po is alive, set the ARP info*/ + set_arp_flag = 1; + break; + } + } + else + { + continue; + } + } + } + } + } + + /* set dynamic ARP*/ + if (set_arp_flag == 1) + { + if (arp_entry->op_type == ARP_SYNC_ADD) + { + if (mlacp_fsm_arp_set(arp_entry->ifname, ntohl(arp_entry->ipv4_addr), mac_str) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "ARP add failure for %s %s %s", + arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str); + return MCLAG_ERROR; + } + } + else + { + if (mlacp_fsm_arp_del(arp_entry->ifname, ntohl(arp_entry->ipv4_addr)) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "ARP delete failure for %s %s %s", + arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str); + return MCLAG_ERROR; + } + } + + /*ICCPD_LOG_DEBUG(__FUNCTION__, "%s: ARP update for %s %s %s", + __FUNCTION__, arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str);*/ + } + else + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Failure: port-channel is not alive"); + /*TODO Set static route through peer-link or just skip it?*/ + } + + /* update ARP list*/ + TAILQ_FOREACH(msg, &(MLACP(csm).arp_list), tail) + { + arp_msg = (struct ARPMsg*)msg->buf; + if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + { + /*arp_msg->op_type = tlv->type;*/ + sprintf(arp_msg->ifname, "%s", arp_entry->ifname); + memcpy(arp_msg->mac_addr, arp_entry->mac_addr, ETHER_ADDR_LEN); + break; + } + } + + /* delete/add ARP list*/ + if (msg && arp_entry->op_type == ARP_SYNC_DEL) + { + TAILQ_REMOVE(&(MLACP(csm).arp_list), msg, tail); + free(msg->buf); + free(msg); + /*ICCPD_LOG_INFO(__FUNCTION__, "Del arp queue successfully");*/ + } + else if (!msg && arp_entry->op_type == ARP_SYNC_ADD) + { + arp_msg = (struct ARPMsg*)&arp_data; + sprintf(arp_msg->ifname, "%s", arp_entry->ifname); + arp_msg->ipv4_addr = ntohl(arp_entry->ipv4_addr); + arp_msg->op_type = arp_entry->op_type; + memcpy(arp_msg->mac_addr, arp_entry->mac_addr, ETHER_ADDR_LEN); + if (iccp_csm_init_msg(&msg, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) + { + mlacp_enqueue_arp(csm, msg); + /*ICCPD_LOG_INFO(__FUNCTION__, "Add arp queue successfully");*/ + } + } + + /* remove all ARP msg queue, when receive peer's ARP list at the same time*/ + TAILQ_FOREACH(msg, &(MLACP(csm).arp_msg_list), tail) + { + arp_msg = (struct ARPMsg*)msg->buf; + if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + break; + } + + while (msg) + { + arp_msg = (struct ARPMsg*)msg->buf; + TAILQ_REMOVE(&(MLACP(csm).arp_msg_list), msg, tail); + free(msg->buf); + free(msg); + TAILQ_FOREACH(msg, &(MLACP(csm).arp_msg_list), tail) + { + arp_msg = (struct ARPMsg*)msg->buf; + if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + break; + } + } + + return 0; +} + +int mlacp_fsm_update_arp_info(struct CSM* csm, struct mLACPARPInfoTLV* tlv) +{ + int count = 0; + int i; + + if (!csm || !tlv) + return MCLAG_ERROR; + count = ntohs(tlv->num_of_entry); + ICCPD_LOG_INFO(__FUNCTION__, "Received ARP Info count %d ", count ); + + for (i = 0; i < count; i++) + { + mlacp_fsm_update_arp_entry(csm, &(tlv->ArpEntry[i])); + } +} + +/***************************************** +* Port-Channel-Info Update +* ***************************************/ +int mlacp_fsm_update_port_channel_info(struct CSM* csm, + struct mLACPPortChannelInfoTLV* tlv) +{ + struct PeerInterface* peer_if = NULL; + struct VLAN_ID* peer_vlan_id = NULL; + int i = 0; + + if (csm == NULL || tlv == NULL ) + return MCLAG_ERROR; + + LIST_FOREACH(peer_if, &(MLACP(csm).pif_list), mlacp_next) + { + if (peer_if->type != IF_T_PORT_CHANNEL) + continue; + + if (peer_if->po_id != ntohs(tlv->agg_id)) + continue; + + LIST_FOREACH(peer_vlan_id, &(peer_if->vlan_list), port_next) + { + peer_vlan_id->vlan_removed = 1; + } + + /* Record peer info*/ + peer_if->ipv4_addr = ntohl(tlv->ipv4_addr); + peer_if->l3_mode = tlv->l3_mode; + + for (i = 0; i < ntohs(tlv->num_of_vlan_id); i++) + { + peer_if_add_vlan(peer_if, ntohs(tlv->vlanData[i].vlan_id)); + } + + peer_if_clean_unused_vlan(peer_if); + + iccp_consistency_check(peer_if->name); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Peer intf %s info: ipv4 addr %s l3 mode %d", peer_if->name, show_ip_str( tlv->ipv4_addr), peer_if->l3_mode); + break; + } + + return 0; +} + +/***************************************** +* Peerlink port Update +* ***************************************/ +int mlacp_fsm_update_peerlink_info(struct CSM* csm, + struct mLACPPeerLinkInfoTLV* tlv) +{ + if (csm == NULL || tlv == NULL ) + return MCLAG_ERROR; + + if (!csm->peer_link_if) + { + ICCPD_LOG_WARN(__FUNCTION__, "Peerlink port info recv from peer, local peerlink is not exist!"); + return 0; + } + + if (csm->peer_link_if->type != tlv->port_type) + ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port type of peer %d is not same with local %d !", tlv->port_type, csm->peer_link_if->type); + + if (tlv->port_type == IF_T_VXLAN && strncmp(csm->peer_itf_name, tlv->if_name, strlen(csm->peer_itf_name))) + ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port is vxlan port, but peerlink port of peer %s is not same with local %s !", tlv->if_name, csm->peer_itf_name); + + return 0; +} + +/***************************************** +* Heartbeat Update +*****************************************/ +int mlacp_fsm_update_heartbeat(struct CSM* csm, struct mLACPHeartbeatTLV* tlv) +{ + if (!csm || !tlv) + return MCLAG_ERROR; + + time(&csm->heartbeat_update_time); + + return 0; +} + +/***************************************** +* warm-reboot flag Update +*****************************************/ +int mlacp_fsm_update_warmboot(struct CSM* csm, struct mLACPWarmbootTLV* tlv) +{ + if (!csm || !tlv) + return MCLAG_ERROR; + + time(&csm->peer_warm_reboot_time); + ICCPD_LOG_DEBUG(__FUNCTION__, "Receive warm reboot notification from peer!"); + + return 0; +} + diff --git a/src/iccpd/src/port.c b/src/iccpd/src/port.c new file mode 100644 index 000000000000..1414a1f86c87 --- /dev/null +++ b/src/iccpd/src/port.c @@ -0,0 +1,665 @@ +/* + * port.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include + +#include "../include/logger.h" +#include "../include/port.h" +#include "../include/system.h" +#include "../include/iccp_csm.h" + +void local_if_init(struct LocalInterface* local_if) +{ + if (local_if == NULL) + return; + + memset(local_if, 0, sizeof(struct LocalInterface)); + local_if->po_id = -1; + local_if->po_active = 1; //always guess the po is active + local_if->mlacp_state = MLACP_STATE_INIT; + local_if->type = IF_T_UNKNOW; + local_if->changed = 1; + local_if->port_config_sync = 0; + local_if->is_peer_link = 0; + local_if->is_arp_accept = 0; + local_if->l3_mode = 0; + local_if->state = PORT_STATE_DOWN; + local_if->prefixlen = 32; + local_if->csm = NULL; + local_if->isolate_to_peer_link = 0; + LIST_INIT(&local_if->vlan_list); + + return; +} + +void vlan_info_init(struct VLAN_ID* vlan) +{ + vlan->vid = -1; + vlan->vlan_removed = 0; + vlan->vlan_itf = NULL; + + return; +} + +struct LocalInterface* local_if_create(int ifindex, char* ifname, int type) +{ + struct System* sys = NULL; + struct LocalInterface* local_if = NULL; + struct CSM* csm; + struct If_info * cif = NULL; + + if (!ifname) + return NULL; + + if (!(sys = system_get_instance())) + return NULL; + + if (ifindex < 0) + return NULL; + + if ((local_if = local_if_find_by_ifindex(ifindex))) + return local_if; + + if (!(local_if = (struct LocalInterface*)malloc(sizeof(struct LocalInterface)))) + { + ICCPD_LOG_WARN(__FUNCTION__, "Port ifindex = %d, malloc failed", ifindex); + return NULL; + } + + local_if_init(local_if); + local_if->ifindex = ifindex; + local_if->type = type; + + if (local_if->type == IF_T_PORT_CHANNEL) + { + int i; + int len; + len = strlen(ifname); + + for (i = 0; i < len; ++i) + if (ifname[i] >= '0' && ifname[i] <= '9') + break; + + if (i >= len) + return NULL; + + local_if->po_id = atoi(&ifname[i]); + } + + if (ifname) + snprintf(local_if->name, MAX_L_PORT_NAME, "%s", ifname); + + switch (type) + { + case IF_T_PORT_CHANNEL: + break; + + case IF_T_PORT: + break; + + case IF_T_VLAN: + /* do nothing currently. */ + break; + + case IF_T_VXLAN: + /* do nothing currently. */ + break; + + default: + ICCPD_LOG_WARN(__FUNCTION__, "The type of local interface (%s) is not acceptable", ifname); + if (local_if) + free(local_if); + return NULL; + } + + ICCPD_LOG_NOTICE(__FUNCTION__, + "Create a local_if = %s ifindex = %d MAC = %02x:%02x:%02x:%02x:%02x:%02x, state = %s", + ifname, local_if->ifindex, local_if->mac_addr[0], local_if->mac_addr[1], local_if->mac_addr[2], + local_if->mac_addr[3], local_if->mac_addr[4], local_if->mac_addr[5], local_if->state ? "down" : "up"); + + LIST_INSERT_HEAD(&(sys->lif_list), local_if, system_next); + + /*Check the intf is peer-link? Only support PortChannel and Ethernet currently*/ + /*When set peer-link, the local-if is probably not created*/ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (strcmp(local_if->name, csm->peer_itf_name) == 0) + { + local_if->is_peer_link = 1; + csm->peer_link_if = local_if; + break; + } + /*check the intf is bind with csm*/ + LIST_FOREACH(cif, &(csm->if_bind_list), csm_next) + { + if (strcmp(ifname, cif->name) == 0) + mlacp_bind_port_channel_to_csm(csm, ifname); + } + } + + return local_if; +} + +struct LocalInterface* local_if_find_by_name(const char* ifname) +{ + struct System* sys = NULL; + struct LocalInterface* local_if = NULL; + + if (!ifname) + return NULL; + + if (!(sys = system_get_instance())) + return NULL; + + LIST_FOREACH(local_if, &(sys->lif_list), system_next) + { + if (strcmp(local_if->name, ifname) == 0) + return local_if; + } + + return NULL; +} + +struct LocalInterface* local_if_find_by_ifindex(int ifindex) +{ + struct System* sys = NULL; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return NULL; + + LIST_FOREACH(local_if, &(sys->lif_list), system_next) + { + if (local_if->ifindex == ifindex) + return local_if; + } + + return NULL; +} + +struct LocalInterface* local_if_find_by_po_id(int po_id) +{ + struct System* sys = NULL; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return NULL; + + LIST_FOREACH(local_if, &(sys->lif_list), system_next) + { + if (local_if->type == IF_T_PORT_CHANNEL && local_if->po_id == po_id) + return local_if; + } + + return NULL; +} + +static void local_if_vlan_remove(struct LocalInterface *lif_vlan) +{ + struct System *sys = NULL; + struct LocalInterface *lif = NULL; + struct VLAN_ID *vlan = NULL; + + if ((sys = system_get_instance()) != NULL) + { + LIST_FOREACH(lif, &(sys->lif_list), system_next) + { + LIST_FOREACH(vlan, &(lif->vlan_list), port_next) + { + if (lif_vlan != vlan->vlan_itf) + continue; + + vlan->vlan_itf = NULL; + } + } + } + + return; +} + +static void local_if_po_remove(struct LocalInterface *lif_po) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct LocalInterface *lif = NULL; + + /* remove all po member*/ + if ((sys = system_get_instance()) != NULL) + { + csm = lif_po->csm; + if (csm) + { + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif->type != IF_T_PORT) + continue; + if (lif->po_id != lif_po->po_id) + continue; + + mlacp_unbind_local_if(lif); + } + } + } + + return; +} + +static void local_if_remove(struct LocalInterface *lif) +{ + mlacp_unbind_local_if(lif); + lif->po_id = -1; + + return; +} + +void local_if_destroy(char *ifname) +{ + struct LocalInterface* lif = NULL; + struct CSM *csm = NULL; + struct System *sys = NULL; + + if (!(sys = system_get_instance())) + return; + + lif = local_if_find_by_name(ifname); + if (!lif) + return; + + ICCPD_LOG_WARN(__FUNCTION__, "Destroy interface %s, %d\n", lif->name, lif->ifindex); + + if (lif->type == IF_T_VLAN) + local_if_vlan_remove(lif); + else if (lif->type == IF_T_PORT_CHANNEL) + local_if_po_remove(lif); + else + local_if_remove(lif); + + csm = lif->csm; + if (csm && csm->peer_link_if && strcmp(csm->peer_link_if->name, ifname) == 0) + { + /*if the peerlink interface is not created, peer connection can not establish*/ + scheduler_session_disconnect_handler(csm); + csm->peer_link_if->is_peer_link = 0; + csm->peer_link_if = NULL; + } + + if (csm && MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + goto to_mlacp_purge; + else + goto to_sys_purge; + + to_sys_purge: + /* sys purge */ + LIST_REMOVE(lif, system_next); + if (lif->csm) + LIST_REMOVE(lif, mlacp_next); + LIST_INSERT_HEAD(&(sys->lif_purge_list), lif, system_purge_next); + return; + + to_mlacp_purge: + /* sys & mlacp purge */ + LIST_REMOVE(lif, system_next); + LIST_REMOVE(lif, mlacp_next); + LIST_INSERT_HEAD(&(sys->lif_purge_list), lif, system_purge_next); + LIST_INSERT_HEAD(&(MLACP(csm).lif_purge_list), lif, mlacp_purge_next); + return; +} + +int local_if_is_l3_mode(struct LocalInterface* local_if) +{ + int ret = 0; + + if (local_if == NULL) + return 0; + + if (local_if->ipv4_addr != 0) + ret = 1; + + return ret; +} + +void local_if_change_flag_clear(void) +{ + struct System* sys = NULL; + struct LocalInterface* lif = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + LIST_FOREACH(lif, &(sys->lif_list), system_next) + { + if (lif->changed == 1) + { + lif->changed = 0; + } + } + + return; +} + +void local_if_purge_clear(void) +{ + struct System* sys = NULL; + struct LocalInterface* lif = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + /* destroy purge if*/ + while (!LIST_EMPTY(&(sys->lif_purge_list))) + { + lif = LIST_FIRST(&(sys->lif_purge_list)); + ICCPD_LOG_DEBUG(__FUNCTION__, "Purge %s", lif->name); + LIST_REMOVE(lif, system_purge_next); + if (lif->mlacp_purge_next.le_next != 0 && lif->mlacp_purge_next.le_prev != 0) + LIST_REMOVE(lif, mlacp_purge_next); + local_if_del_all_vlan(lif); + free(lif); + } + + LIST_INIT(&(sys->lif_purge_list)); + + return; +} + +void local_if_finalize(struct LocalInterface* lif) +{ + if (lif == NULL) + return; + + local_if_del_all_vlan(lif); + + free(lif); + + return; +} + +struct PeerInterface* peer_if_create(struct CSM* csm, + int peer_if_number, int type) +{ + struct PeerInterface* peer_if = NULL; + + /* check csm*/ + if (csm == NULL) + return NULL; + + /* check id*/ + if (peer_if_number < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "peer interface id < 0"); + return NULL; + } + + /* check type*/ + if (type != IF_T_PORT && type != IF_T_PORT_CHANNEL) + { + ICCPD_LOG_WARN(__FUNCTION__, + "The type(%) of peer interface(%d) is not acceptable", + type, peer_if_number); + return NULL; + } + + /* create a new peer if*/ + if ((peer_if = (struct PeerInterface*)malloc(sizeof(struct PeerInterface))) == NULL) + { + ICCPD_LOG_WARN(__FUNCTION__, "Peer port id = %d, malloc failed", peer_if_number); + return NULL; + } + memset(peer_if, 0, sizeof(struct PeerInterface)); + + if (type == IF_T_PORT) + { + peer_if->ifindex = peer_if_number; + peer_if->type = IF_T_PORT; + peer_if->csm = csm; + } + else if (type == IF_T_PORT_CHANNEL) + { + peer_if->ifindex = peer_if_number; + peer_if->type = IF_T_PORT_CHANNEL; + } + + LIST_INSERT_HEAD(&(MLACP(csm).pif_list), peer_if, mlacp_next); + + return peer_if; +} + +struct PeerInterface* peer_if_find_by_name(struct CSM* csm, char* name) +{ + struct System* sys = NULL; + struct PeerInterface* peer_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return NULL; + + if (csm == NULL) + return NULL; + + LIST_FOREACH(peer_if, &(csm->app_csm.mlacp.pif_list), mlacp_next) + { + if (strcmp(peer_if->name, name) == 0) + return peer_if; + } + + return NULL; +} + +void peer_if_del_all_vlan(struct PeerInterface* pif) +{ + struct VLAN_ID *pvlan = NULL; + + while (!LIST_EMPTY(&(pif->vlan_list))) + { + pvlan = LIST_FIRST(&(pif->vlan_list)); + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove peer intf %s from VLAN %d", + pif->name, pvlan->vid); + LIST_REMOVE(pvlan, port_next); + free(pvlan); + } + + return; +} + +void peer_if_destroy(struct PeerInterface* pif) +{ + ICCPD_LOG_WARN(__FUNCTION__, "Destroy peer's interface %s, %d", + pif->name, pif->ifindex); + + /* destroy if*/ + LIST_REMOVE(pif, mlacp_next); + peer_if_del_all_vlan(pif); + + free(pif); + return; +} + +int local_if_add_vlan(struct LocalInterface* local_if, uint16_t vid) +{ + struct VLAN_ID *vlan = NULL; + char vlan_name[16] = ""; + + sprintf(vlan_name, "Vlan%d", vid); + + /* traverse 1 time */ + LIST_FOREACH(vlan, &(local_if->vlan_list), port_next) + { + if (vlan->vid == vid) + break; + } + + if (!vlan) + { + vlan = (struct VLAN_ID*)malloc(sizeof(struct VLAN_ID)); + if (!vlan) + return MCLAG_ERROR; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Add %s to VLAN %d", local_if->name, vid); + local_if->port_config_sync = 1; + LIST_INSERT_HEAD(&(local_if->vlan_list), vlan, port_next); + } + + vlan_info_init(vlan); + vlan->vid = vid; + vlan->vlan_removed = 0; + vlan->vlan_itf = local_if_find_by_name(vlan_name); + + update_if_ipmac_on_standby(local_if); + + return 0; +} + +void local_if_del_vlan(struct LocalInterface* local_if, uint16_t vid) +{ + struct VLAN_ID *vlan = NULL; + + /* traverse 1 time */ + LIST_FOREACH(vlan, &(local_if->vlan_list), port_next) + { + if (vlan->vid == vid) + break; + } + + if (vlan != NULL) + { + LIST_REMOVE(vlan, port_next); + free(vlan); + local_if->port_config_sync = 1; + } + + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove %s from VLAN %d", local_if->name, vid); + + return; +} + +void local_if_del_all_vlan(struct LocalInterface* lif) +{ + struct VLAN_ID* vlan = NULL; + + while (!LIST_EMPTY(&(lif->vlan_list))) + { + vlan = LIST_FIRST(&(lif->vlan_list)); + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove %s from VLAN %d", lif->name, vlan->vid); + LIST_REMOVE(vlan, port_next); + free(vlan); + } + + return; +} + +/* Add VLAN from peer-link*/ +int peer_if_add_vlan(struct PeerInterface* peer_if, uint16_t vlan_id) +{ + struct VLAN_ID *peer_vlan = NULL; + char vlan_name[16] = ""; + + sprintf(vlan_name, "Vlan%d", vlan_id); + + /* traverse 1 time */ + LIST_FOREACH(peer_vlan, &(peer_if->vlan_list), port_next) + { + if (peer_vlan->vid == vlan_id) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Update VLAN ID %d for peer intf %s", peer_vlan->vid, peer_if->name); + break; + } + } + + if (!peer_vlan) + { + peer_vlan = (struct VLAN_ID*)malloc(sizeof(struct VLAN_ID)); + if (!peer_vlan) + return MCLAG_ERROR; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Add peer intf %s to VLAN %d", peer_if->name, vlan_id); + LIST_INSERT_HEAD(&(peer_if->vlan_list), peer_vlan, port_next); + } + + vlan_info_init(peer_vlan); + peer_vlan->vid = vlan_id; + peer_vlan->vlan_removed = 0; + + return 0; +} + +/* Used by sync update*/ +int peer_if_clean_unused_vlan(struct PeerInterface* peer_if) +{ + struct VLAN_ID *peer_vlan = NULL; + struct VLAN_ID *peer_vlan_next = NULL; + + /* traverse 1 time */ + LIST_FOREACH(peer_vlan_next, &(peer_if->vlan_list), port_next) + { + if (peer_vlan != NULL) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove peer intf %s from VLAN %d", peer_if->name, peer_vlan->vid); + LIST_REMOVE(peer_vlan, port_next); + free(peer_vlan); + peer_vlan = NULL; + + } + if (peer_vlan_next->vlan_removed == 1) + peer_vlan = peer_vlan_next; + } + + if (peer_vlan != NULL) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove peer intf %s from VLAN %d", peer_if->name, peer_vlan->vid); + LIST_REMOVE(peer_vlan, port_next); + free(peer_vlan); + } + + return 0; +} + +int set_sys_arp_accept_flag(char* ifname, int flag) +{ + FILE *file_ptr = NULL; + char cmd[64]; + char arp_file[64]; + char buf[2]; + int result = MCLAG_ERROR; + + memset(arp_file, 0, 64); + snprintf(arp_file, 63, "/proc/sys/net/ipv4/conf/%s/arp_accept", ifname); + if (!(file_ptr = fopen(arp_file, "r"))) + { + ICCPD_LOG_WARN(__func__, "Failed to find device %s from %s", ifname, arp_file); + return result; + } + + fgets(buf, sizeof(buf), file_ptr); + if (atoi(buf) == flag) + result = 0; + else + { + memset(cmd, 0, 64); + snprintf(cmd, 63, "echo %d > /proc/sys/net/ipv4/conf/%s/arp_accept", flag, ifname); + if (system(cmd)) + ICCPD_LOG_WARN(__func__, "Failed to execute cmd = %s", flag, cmd); + } + + fclose(file_ptr); + return result; +} diff --git a/src/iccpd/src/scheduler.c b/src/iccpd/src/scheduler.c new file mode 100644 index 000000000000..9d08e137dce0 --- /dev/null +++ b/src/iccpd/src/scheduler.c @@ -0,0 +1,770 @@ +/* + * scheduler.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../include/logger.h" +#include "../include/system.h" +#include "../include/scheduler.h" +#include "../include/iccp_csm.h" +#include "../include/iccp_ifm.h" +#include "../include/iccp_cmd.h" +#include "../include/mlacp_link_handler.h" +#include "../include/iccp_netlink.h" + +/****************************************************** +* +* Global Variable +* +******************************************************/ + +static int session_conn_thread_lock(pthread_mutex_t *conn_mutex) +{ + return 1; /*pthread_mutex_lock(conn_mutex);*/ +} + +static int session_conn_thread_trylock(pthread_mutex_t *conn_mutex) +{ + return 0; /*pthread_mutex_trylock(conn_mutex);*/ +} + +static int session_conn_thread_unlock(pthread_mutex_t *conn_mutex) +{ + return 1;/* pthread_mutex_unlock(conn_mutex);*/ +} + +static void heartbeat_check(struct CSM *csm) +{ + if (csm->heartbeat_update_time == 0) + { + time(&csm->heartbeat_update_time); + return; + } + + if ( (time(NULL) - csm->heartbeat_update_time) > HEARTBEAT_TIMEOUT_SEC) + { + /* hearbeat timeout*/ + ICCPD_LOG_WARN(__FUNCTION__, "iccpd connection timeout (heartbeat)"); + scheduler_session_disconnect_handler(csm); + } + + return; +} + +static void heartbeat_update(struct CSM *csm) +{ + if (csm->sock_fd > 0) + { + heartbeat_check(csm); + } + + return; +} + +/* Transit FSM of all connections */ +static int scheduler_transit_fsm() +{ + struct CSM* csm = NULL; + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + heartbeat_update(csm); + iccp_csm_transit(csm); + app_csm_transit(csm); + mlacp_fsm_transit(csm); + + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE && (time(NULL) - sys->csm_trans_time) >= 60) + { + iccp_get_fdb_change_from_syncd(); + sys->csm_trans_time = time(NULL); + } + } + + local_if_change_flag_clear(); + local_if_purge_clear(); + + return 1; +} + +/* Receive packets call back function */ +int scheduler_csm_read_callback(struct CSM* csm) +{ + struct Msg* msg = NULL; + /*peer message*/ + char *peer_msg = g_csm_buf; + LDPHdr* ldp_hdr = (LDPHdr*)peer_msg; + char* data = &peer_msg[sizeof(LDPHdr)]; + size_t data_len = 0; + size_t pos = 0; + int recv_len = 0, len = 0, retval; + + if (csm->sock_fd <= 0) + return MCLAG_ERROR; + + memset(peer_msg, 0, CSM_BUFFER_SIZE); + + recv_len = 0; + + while (recv_len != sizeof(LDPHdr)) + { + len = recv(csm->sock_fd, peer_msg + recv_len, sizeof(LDPHdr) - recv_len, 0); + if (len == -1) + { + perror("recv(). Error"); + goto recv_err; + } + else if (len == 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Peer disconnect for receive error"); + goto recv_err; + } + recv_len += len; + /*usleep(100);*/ + } + + data_len = ntohs(ldp_hdr->msg_len) - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS; + pos = 0; + + while (data_len > 0) + { + recv_len = recv(csm->sock_fd, &data[pos], data_len, 0); + if (recv_len == -1) + { + perror("continue recv(). Error"); + goto recv_err; + } + else if (recv_len == 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Peer disconnect for read error"); + goto recv_err; + } + data_len -= recv_len; + pos += recv_len; + /*usleep(100);*/ + } + + retval = iccp_csm_init_msg(&msg, peer_msg, ntohs(ldp_hdr->msg_len) + MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + if (retval == 0) + { + iccp_csm_enqueue_msg(csm, msg); + ++csm->icc_msg_in_count; + } + else + ++csm->i_msg_in_count; + + return 1; + + recv_err: + scheduler_session_disconnect_handler(csm); + return MCLAG_ERROR; +} + +/* Handle server accept client */ +int scheduler_server_accept() +{ + int new_fd; + int ret = MCLAG_ERROR; + struct CSM* csm = NULL; + struct System* sys = NULL; + struct sockaddr_in client_addr; + socklen_t addr_len; + + if ((sys = system_get_instance()) == NULL ) + { + return MCLAG_ERROR; + } + if (sys->server_fd <= 0) + { + return MCLAG_ERROR; + } + + addr_len = sizeof(struct sockaddr_in); + new_fd = accept(sys->server_fd, (struct sockaddr *)&client_addr, &addr_len); + if (new_fd == -1) + { + goto reject_client; + } + else + { + csm = system_get_csm_by_peer_ip(inet_ntoa(client_addr.sin_addr)); + if (!csm) + { + /* can't find csm with peer ip*/ + ICCPD_LOG_INFO(__FUNCTION__, "csm null with peer ip [%s]", inet_ntoa(client_addr.sin_addr)); + goto reject_client; + } + + if (csm->sock_fd > 0) + { + /* peer already connected*/ + ICCPD_LOG_INFO(__FUNCTION__, "csm sock is connected with peer ip [%s]", inet_ntoa(client_addr.sin_addr)); + goto reject_client; + } + + if ((ret = scheduler_check_csm_config(csm)) < 0) + { + /* csm config error*/ + ICCPD_LOG_INFO(__FUNCTION__, "csm config error with peer ip [%s]", inet_ntoa(client_addr.sin_addr)); + goto reject_client; + } + } + + /* Accept*/ + goto accept_client; + + reject_client: + if (new_fd >= 0) + close(new_fd); + return MCLAG_ERROR; + + accept_client: + session_conn_thread_lock(&csm->conn_mutex); + ICCPD_LOG_INFO(__FUNCTION__, "Server Accept, SocketFD [%d], %p", new_fd, csm); + + struct epoll_event event; + int err; + event.data.fd = new_fd; + event.events = EPOLLIN; + err = epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, new_fd, &event); + if (err) + { + session_conn_thread_unlock(&csm->conn_mutex); + goto reject_client; + } + + csm->sock_fd = new_fd; + csm->current_state = ICCP_NONEXISTENT; + FD_SET(new_fd, &(sys->readfd)); + sys->readfd_count++; + session_conn_thread_unlock(&csm->conn_mutex); + return 0; +} + +void iccp_get_start_type(struct System* sys) +{ + FILE* fp; + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + + fp = fopen("/proc/cmdline", "r"); + if (!fp) + { + ICCPD_LOG_WARN(__FUNCTION__, "Error: Can't open file /proc/cmdline!"); + return; + } + + fread(g_csm_buf, CSM_BUFFER_SIZE, 1, fp); + (void)fclose(fp); + + if (strstr(g_csm_buf, "SONIC_BOOT_TYPE=warm")) + sys->warmboot_start = WARM_REBOOT; + + return; +} + +/* scheduler initialization */ +void scheduler_init() +{ + struct System* sys = NULL; + + if (!(sys = system_get_instance())) + return; + + iccp_get_start_type(sys); + /*Get kernel interface and port */ + iccp_sys_local_if_list_get_init(); + iccp_sys_local_if_list_get_addr(); + /*Interfaces must be created before this func called*/ + iccp_config_from_file(sys->config_file_path); + + /*Get kernel ARP info */ + iccp_arp_get_init(); + + if (iccp_connect_syncd() < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Syncd info socket connect fail"); + } + else + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Syncd info socket connect success"); + } + + if (mclagd_ctl_sock_create() < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Mclagd ctl info socket connect fail"); + } + + return; +} + +extern int mlacp_prepare_for_warm_reboot(struct CSM* csm, char* buf, size_t max_buf_size); +void mlacp_sync_send_warmboot_flag() +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + int msg_len = 0; + + if ((sys = system_get_instance()) == NULL) + return; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_warm_reboot(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, msg_len); + } + } + + return; +} + +int iccp_receive_signal_handler(struct System* sys) +{ + char ctrl_byte; + int err = 0; + + err = read(sys->sig_pipe_r, &ctrl_byte, 1); + if (err == -1) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Read sig_pipe_r fail !"); + return err; + } + + switch (ctrl_byte) + { + case 'w': + /*send packet to peer*/ + mlacp_sync_send_warmboot_flag(); + sys->warmboot_exit = WARM_REBOOT; + break; + + default: + break; + } + + return 0; +} + +/* Thread fetch to call */ +void scheduler_loop() +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + while (1) + { + if (sys->sync_fd <= 0) + { + iccp_connect_syncd(); + } + + /*handle socket slelect event ,If no message received, it will block 0.1s*/ + iccp_handle_events(sys); + /*csm, app state machine transit */ + scheduler_transit_fsm(); + + if (sys->warmboot_exit == WARM_REBOOT) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Warm reboot exit ......"); + return; + } + } + + return; +} + +/***************************************** +* Sync portchannel MAC with kernel +* +* ***************************************/ +int mlacp_sync_with_kernel_callback() +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + { + goto out; + } + + /* traverse all CSM */ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + /* Sync MLAG po state with kernel*/ + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + /* sync system info from one port-channel device*/ + if (memcmp(MLACP(csm).system_id, local_if->mac_addr, ETHER_ADDR_LEN) != 0) + { + memcpy(MLACP(csm).system_id, local_if->mac_addr, ETHER_ADDR_LEN); + MLACP(csm).system_config_changed = 1; + break; + } + } + } + } + + out: + return 0; +} + +/* Scheduler start while loop */ +void scheduler_start() +{ + /*mlacp_sync_with_kernel_callback();*/ + + scheduler_loop(); + + return; +} + +/* Scheduler tear down */ +void scheduler_finalize() +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + syncd_info_close(); + + log_finalize(); + + ICCPD_LOG_INFO(__FUNCTION__, "Scheduler is terminated."); + + return; +} + +void session_client_conn_handler(struct CSM *csm) +{ + struct System* sys = NULL; + struct sockaddr_in peer_addr; + int connFd = -1, connStat = -1; + struct timeval con_tv; + socklen_t len = sizeof(con_tv); + int err = 0; + + struct sockaddr_in src_addr; + bzero(&(src_addr), sizeof(src_addr)); + src_addr.sin_family = PF_INET; + src_addr.sin_port = 0; + src_addr.sin_addr.s_addr = inet_addr(csm->sender_ip); + + /* Lock the thread*/ + session_conn_thread_lock(&csm->conn_mutex); + + sys = system_get_instance(); + if (!sys) + goto conn_fail; + + /* Create sock*/ + connFd = socket(PF_INET, SOCK_STREAM, 0); + bzero(&peer_addr, sizeof(peer_addr)); + peer_addr.sin_family = PF_INET; + peer_addr.sin_port = htons(ICCP_TCP_PORT); + peer_addr.sin_addr.s_addr = inet_addr(csm->peer_ip); + if (connFd == -1) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Peer IP:%s Socket FD creation failed.", + csm->peer_ip); + goto conn_fail; + } + + /* Set connect timeout secs*/ + con_tv.tv_sec = 0; + con_tv.tv_usec = CONNECT_TIMEOUT_MSEC * 1000; + if (setsockopt(connFd, SOL_SOCKET, SO_SNDTIMEO, &con_tv, len) == -1) + { + ICCPD_LOG_INFO(__FUNCTION__, "Set socket timeout fail"); + } + + err = bind(connFd, (struct sockaddr*)&(src_addr), sizeof(src_addr)); + if (err < 0) + { + ICCPD_LOG_INFO(__FUNCTION__, "Bind socket failed. Error = %d errno = %d ",err,errno); + goto conn_fail; + } + + /* Try conn*/ + ICCPD_LOG_INFO(__FUNCTION__, "Connecting. peer ip = [%s], %p", csm->peer_ip, csm); + connStat = connect(connFd, (struct sockaddr*)&(peer_addr), sizeof(peer_addr)); + ICCPD_LOG_INFO(__FUNCTION__, "Connection. fd = [%d], status = [%d], %p", + connFd, connStat, csm); + + if (connStat != 0) + { + /* Conn Fail*/ + goto conn_fail; + } + else + { + /* Conn OK*/ + struct epoll_event event; + int err; + event.data.fd = connFd; + event.events = EPOLLIN; + err = epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, connFd, &event); + if (err) + goto conn_fail; + csm->sock_fd = connFd; + FD_SET(connFd, &(sys->readfd)); + sys->readfd_count++; + ICCPD_LOG_INFO(__FUNCTION__, "Connect to server %s sucess .", csm->peer_ip); + goto conn_ok; + } + + conn_fail: + if (connFd >= 0) + { + csm->sock_fd = -1; + close(connFd); + } + conn_ok: + time(&csm->connTimePrev); + session_conn_thread_unlock(&csm->conn_mutex); + return; +} + +/* Create socket connect to peer */ +int scheduler_prepare_session(struct CSM* csm) +{ + int ret = MCLAG_ERROR; + uint32_t local_ip = 0; + uint32_t peer_ip = 0; + + /* Init time_t*/ + if (csm->connTimePrev == 0) + { + time(&csm->connTimePrev); + } + + /* Don't conn to svr continously*/ + if ((time(NULL) - csm->connTimePrev) < CONNECT_INTERVAL_SEC) + { + goto no_time_update; + } + + /* Already conn?*/ + if (csm->sock_fd > 0) + { + goto time_update; + } + + if ((ret = scheduler_check_csm_config(csm)) < 0) + goto time_update; + + /* Who is client*/ + local_ip = inet_addr(csm->sender_ip); + peer_ip = inet_addr(csm->peer_ip); + if (local_ip > peer_ip) + { + goto time_update; + } + else if (local_ip == peer_ip) + { + ICCPD_LOG_WARN(__FUNCTION__, "Local IP must not be the same as the peer IP."); + goto time_update; + } + + if (session_conn_thread_trylock(&csm->conn_mutex) == 0) + { + session_client_conn_handler(csm); + session_conn_thread_unlock(&csm->conn_mutex); + } + + time_update: + time(&csm->connTimePrev); + return 0; + + no_time_update: + return 0; +} + +/* Server socket initialization */ +void scheduler_server_sock_init() +{ + int optval = 1; + struct System* sys = NULL; + struct sockaddr_in src_addr; + + if ((sys = system_get_instance()) == NULL) + return; + + sys->server_fd = socket(PF_INET, SOCK_STREAM, 0); + bzero(&(src_addr), sizeof(src_addr)); + src_addr.sin_family = PF_INET; + src_addr.sin_port = htons(ICCP_TCP_PORT); + src_addr.sin_addr.s_addr = INADDR_ANY; + + if (sys->server_fd == -1) + { + ICCPD_LOG_ERR(__FUNCTION__, "Server Socket FD creation failed."); + return; + } + + if (setsockopt(sys->server_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) + { + ICCPD_LOG_INFO(__FUNCTION__, "Set socket option failed. Error"); + /*return;*/ + } + + if (bind(sys->server_fd, (struct sockaddr*)&(src_addr), sizeof(src_addr)) < 0) + { + ICCPD_LOG_INFO(__FUNCTION__, "Bind socket failed. Error"); + return; + } + + if (listen(sys->server_fd, MAX_ACCEPT_CONNETIONS) == -1) + { + ICCPD_LOG_INFO(__FUNCTION__, "Listen failed. Error"); + return; + } + + ICCPD_LOG_INFO(__FUNCTION__, "Server socket init done."); + + return; +} + +int iccp_get_server_sock_fd() +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return 0; + + return sys->server_fd; +} + +/* Server socket initialization */ +int scheduler_check_csm_config(struct CSM* csm) +{ + int ret = 1; + struct LocalInterface* lif = NULL; + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + if (csm == NULL ) + return MCLAG_ERROR; + + if (csm->mlag_id <= 0) + ret = MCLAG_ERROR; + else if (strlen(csm->peer_ip) <= 0) + ret = MCLAG_ERROR; + else if (strlen(csm->sender_ip) <= 0) + ret = MCLAG_ERROR; + else if (strlen(csm->peer_itf_name) != 0) + { + lif = local_if_find_by_name(csm->peer_itf_name); + if (lif == NULL) + { + /*if peer-link is configured but the interface is not created, peer connection can not establish*/ + return MCLAG_ERROR; + } + else + { + lif->is_peer_link = 1; + csm->peer_link_if = lif; + } + } + + if (ret == MCLAG_ERROR) + ICCPD_LOG_INFO(__FUNCTION__, "mclag config is not complete or conflicting, please check!"); + + /* Decide STP role*/ + iccp_csm_stp_role_count(csm); + + return ret; +} + +int scheduler_unregister_sock_read_event_callback(struct CSM* csm) +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL ) + return MCLAG_ERROR; + + if (csm == NULL ) + { + return MCLAG_ERROR; + } + + FD_CLR(csm->sock_fd, &(sys->readfd)); + + return 0; +} + +void scheduler_session_disconnect_handler(struct CSM* csm) +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL ) + return; + + struct epoll_event event; + + if (csm == NULL) + return; + + session_conn_thread_lock(&csm->conn_mutex); + scheduler_unregister_sock_read_event_callback(csm); + if (csm->sock_fd > 0) + { + event.data.fd = csm->sock_fd; + event.events = EPOLLIN; + epoll_ctl(sys->epoll_fd, EPOLL_CTL_DEL, csm->sock_fd, &event); + + close(csm->sock_fd); + csm->sock_fd = -1; + } + + mlacp_peer_disconn_handler(csm); + MLACP(csm).current_state = MLACP_STATE_INIT; + iccp_csm_status_reset(csm, 0); + time(&csm->connTimePrev); + session_conn_thread_unlock(&csm->conn_mutex); + + return; +} diff --git a/src/iccpd/src/system.c b/src/iccpd/src/system.c new file mode 100644 index 000000000000..9665b416ca52 --- /dev/null +++ b/src/iccpd/src/system.c @@ -0,0 +1,200 @@ +/* + * system.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include + +#include "../include/iccp_csm.h" +#include "../include/logger.h" +#include "../include/iccp_netlink.h" +#include "../include/scheduler.h" + +/* Singleton */ +struct System* system_get_instance() +{ + static struct System* sys = NULL; + + if (sys == NULL ) + { + sys = (struct System*)malloc(sizeof(struct System)); + if (sys == NULL ) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to obtain system instance."); + return NULL; + } + system_init(sys); + } + + return sys; +} + +/* System instance initialization */ +void system_init(struct System* sys) +{ + if (sys == NULL ) + return; + + sys->server_fd = -1; + sys->sync_fd = -1; + sys->sync_ctrl_fd = -1; + sys->arp_receive_fd = -1; + sys->epoll_fd = -1; + sys->family = -1; + sys->warmboot_start = 0; + sys->warmboot_exit = 0; + LIST_INIT(&(sys->csm_list)); + LIST_INIT(&(sys->lif_list)); + LIST_INIT(&(sys->lif_purge_list)); + + sys->log_file_path = strdup("/var/log/iccpd.log"); + sys->cmd_file_path = strdup("/var/run/iccpd/iccpd.vty"); + sys->config_file_path = strdup("/etc/iccpd/iccpd.conf"); + sys->mclagdctl_file_path = strdup("/var/run/iccpd/mclagdctl.sock"); + sys->pid_file_fd = 0; + sys->telnet_port = 2015; + FD_ZERO(&(sys->readfd)); + sys->readfd_count = 0; + sys->csm_trans_time = 0; + sys->need_sync_team_again = 0; + sys->need_sync_netlink_again = 0; + scheduler_server_sock_init(); + iccp_system_init_netlink_socket(); + iccp_init_netlink_event_fd(sys); +} + +/* System instance tear down */ +void system_finalize() +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL ) + return; + + ICCPD_LOG_INFO(__FUNCTION__, "System resource pool is destructing."); + + while (!LIST_EMPTY(&(sys->csm_list))) + { + csm = LIST_FIRST(&(sys->csm_list)); + iccp_csm_finalize(csm); + } + + /* Release all port objects */ + while (!LIST_EMPTY(&(sys->lif_list))) + { + local_if = LIST_FIRST(&(sys->lif_list)); + LIST_REMOVE(local_if, system_next); + local_if_finalize(local_if); + } + + while (!LIST_EMPTY(&(sys->lif_purge_list))) + { + local_if = LIST_FIRST(&(sys->lif_purge_list)); + LIST_REMOVE(local_if, system_purge_next); + local_if_finalize(local_if); + } + + iccp_system_dinit_netlink_socket(); + + if (sys->log_file_path != NULL ) + free(sys->log_file_path); + if (sys->cmd_file_path != NULL ) + free(sys->cmd_file_path); + if (sys->config_file_path != NULL ) + free(sys->config_file_path); + if (sys->pid_file_fd > 0) + close(sys->pid_file_fd); + if (sys->server_fd > 0) + close(sys->server_fd); + if (sys->sync_fd > 0) + close(sys->sync_fd); + if (sys->sync_ctrl_fd > 0) + close(sys->sync_ctrl_fd); + if (sys->arp_receive_fd > 0) + close(sys->arp_receive_fd); + if (sys->sig_pipe_r > 0) + close(sys->sig_pipe_r); + if (sys->sig_pipe_w > 0) + close(sys->sig_pipe_w); + + if (sys->epoll_fd) + close(sys->epoll_fd); + + free(sys); + ICCPD_LOG_INFO(__FUNCTION__, "System resource pool destructed successfully..."); +} + +struct CSM* system_create_csm() +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + + if ((sys = system_get_instance()) == NULL ) + return NULL; + + /* Create a new csm */ + csm = (struct CSM*)malloc(sizeof(struct CSM)); + if (csm == NULL ) + return NULL; + else + memset(csm, 0, sizeof(struct CSM)); + iccp_csm_init(csm); + LIST_INSERT_HEAD(&(sys->csm_list), csm, next); + + return csm; +} + +/* Get connect state machine instance by peer ip */ +struct CSM* system_get_csm_by_peer_ip(const char* peer_ip) +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + + if ((sys = system_get_instance()) == NULL ) + return NULL; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (strcmp(csm->peer_ip, peer_ip) == 0) + return csm; + } + + return NULL; +} + +struct CSM* system_get_csm_by_mlacp_id(int id) +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + + if ((sys = system_get_instance()) == NULL ) + return NULL; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (csm->app_csm.mlacp.id == id) + return csm; + } + + return NULL; +} From 78b93a88970d00f72cec1eb2791593f6011d79cd Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Sun, 5 Apr 2020 09:17:55 +0800 Subject: [PATCH 0488/1427] [docker-sonic-mgmt]: Fix virtual environment bug (#4370) --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 733f81be2cc8..c19cea4b9727 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -149,7 +149,7 @@ RUN azure-cli_bundle_*/installer RUN ~/lib/azure-cli/bin/python -m pip install azure-keyvault==0.3.7 -U # Install Virtual Environment -RUN python -m virtualenv --system-site-packages env-201803 +RUN python -m virtualenv --system-site-packages env-201811 RUN env-201811/bin/pip install ansible==2.0.0.2 RUN git clone https://github.com/Azure/sonic-mgmt From b9f63537148102cd074d4cadb333fb8ced61db3e Mon Sep 17 00:00:00 2001 From: zhenggen-xu Date: Sat, 4 Apr 2020 22:52:34 -0700 Subject: [PATCH 0489/1427] [Seastone] Add new HWSKU for 48x50G+8x40G (#4156) Add the port_config.ini and sai.profile, leveraging the same bcm file. Signed-off-by: Zhenggen Xu --- .../Seastone-DX010-50-50-40/port_config.ini | 57 +++++++++++++++++++ .../Seastone-DX010-50-50-40/sai.profile | 1 + 2 files changed, 58 insertions(+) create mode 100644 device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/port_config.ini create mode 100644 device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/sai.profile diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/port_config.ini b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/port_config.ini new file mode 100644 index 000000000000..4bc2ce344039 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 65,66 Eth1/1 1 50000 +Ethernet2 67,68 Eth1/2 1 50000 +Ethernet4 69,70 Eth2/1 2 50000 +Ethernet6 71,72 Eth2/2 2 50000 +Ethernet8 73,74 Eth3/1 3 50000 +Ethernet10 75,76 Eth3/2 3 50000 +Ethernet12 77,78 Eth4/1 4 50000 +Ethernet14 79,80 Eth4/2 4 50000 +Ethernet16 33,34 Eth5/1 5 50000 +Ethernet18 35,36 Eth5/2 5 50000 +Ethernet20 37,38 Eth6/1 6 50000 +Ethernet22 39,40 Eth6/2 6 50000 +Ethernet24 41,42 Eth7/1 7 50000 +Ethernet26 43,44 Eth7/2 7 50000 +Ethernet28 45,46 Eth8/1 8 50000 +Ethernet30 47,48 Eth8/2 8 50000 +Ethernet32 49,50 Eth9/1 9 50000 +Ethernet34 51,52 Eth9/2 9 50000 +Ethernet36 53,54 Eth10/1 10 50000 +Ethernet38 55,56 Eth10/2 10 50000 +Ethernet40 57,58 Eth11/1 11 50000 +Ethernet42 59,60 Eth11/2 11 50000 +Ethernet44 61,62 Eth12/1 12 50000 +Ethernet46 63,64 Eth12/2 12 50000 +Ethernet48 81,82 Eth13/1 13 50000 +Ethernet50 83,84 Eth13/2 13 50000 +Ethernet52 85,86 Eth14/1 14 50000 +Ethernet54 87,88 Eth14/2 14 50000 +Ethernet56 89,90 Eth15/1 15 50000 +Ethernet58 91,92 Eth15/2 15 50000 +Ethernet60 93,94 Eth16/1 16 50000 +Ethernet62 95,96 Eth16/2 16 50000 +Ethernet64 97,98 Eth17/1 17 50000 +Ethernet66 99,100 Eth17/2 17 50000 +Ethernet68 101,102 Eth18/1 18 50000 +Ethernet70 103,104 Eth18/2 18 50000 +Ethernet72 105,106 Eth19/1 19 50000 +Ethernet74 107,108 Eth19/2 19 50000 +Ethernet76 109,110 Eth20/1 20 50000 +Ethernet78 111,112 Eth20/2 20 50000 +Ethernet80 1,2 Eth21/1 21 50000 +Ethernet82 3,4 Eth21/2 21 50000 +Ethernet84 5,6 Eth22/1 22 50000 +Ethernet86 7,8 Eth22/2 22 50000 +Ethernet88 9,10 Eth23/1 23 50000 +Ethernet90 11,12 Eth23/2 23 50000 +Ethernet92 13,14 Eth24/1 24 50000 +Ethernet94 15,16 Eth24/2 24 50000 +Ethernet96 17,18,19,20 Eth25 25 40000 +Ethernet100 21,22,23,24 Eth26 26 40000 +Ethernet104 25,26,27,28 Eth27 27 40000 +Ethernet108 29,30,31,32 Eth28 28 40000 +Ethernet112 113,114,115,116 Eth29 29 40000 +Ethernet116 117,118,119,120 Eth30 30 40000 +Ethernet120 121,122,123,124 Eth31 31 40000 +Ethernet124 125,126,127,128 Eth32 32 40000 diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/sai.profile b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/sai.profile new file mode 100644 index 000000000000..7342ae8002e8 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/platform/th-seastone-dx010-config-flex-all.bcm From 60b16495cce3ea64bc436e1f7a875955281e9b97 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sun, 5 Apr 2020 13:29:34 -0700 Subject: [PATCH 0490/1427] [docker-base-stretch]: move common packages into docker-base-stretch (#4371) libpython2.7, libdaemon0, libdbus-1-3, libjansson4 are common across different containers. move them into docker-base-stretch Signed-off-by: Guohan Lu --- dockers/docker-base-stretch/Dockerfile.j2 | 7 ++++++- dockers/docker-fpm-frr/Dockerfile.j2 | 4 ---- dockers/docker-iccpd/Dockerfile.j2 | 16 ++-------------- dockers/docker-nat/Dockerfile.j2 | 9 --------- dockers/docker-orchagent/Dockerfile.j2 | 4 ---- dockers/docker-platform-monitor/Dockerfile.j2 | 1 - dockers/docker-sonic-telemetry/Dockerfile.j2 | 6 +----- dockers/docker-teamd/Dockerfile.j2 | 7 +------ platform/vs/docker-sonic-vs/Dockerfile.j2 | 8 -------- 9 files changed, 10 insertions(+), 52 deletions(-) diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 65b7f9d537ce..17047d13a839 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -54,7 +54,12 @@ RUN apt-get update && \ libjemalloc1 \ liblua5.1-0 \ lua-bitop \ - lua-cjson + lua-cjson \ +# common dependencies + libpython2.7 \ + libdaemon0 \ + libdbus-1-3 \ + libjansson4 # ip and ifconfig utility missing in docker for arm arch RUN apt-get -y install \ diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index 1c670682a342..c382df3c2ba3 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -14,12 +14,8 @@ ENV DEBIAN_FRONTEND=noninteractive # Install required packages RUN apt-get update && \ apt-get install -y \ - libdbus-1-3 \ - libdaemon0 \ - libjansson4 \ libc-ares2 \ iproute2 \ - libpython2.7 \ libjson-c3 \ logrotate \ libunwind8 diff --git a/dockers/docker-iccpd/Dockerfile.j2 b/dockers/docker-iccpd/Dockerfile.j2 index ce3969f29da5..3c7e01ed54e9 100644 --- a/dockers/docker-iccpd/Dockerfile.j2 +++ b/dockers/docker-iccpd/Dockerfile.j2 @@ -7,20 +7,8 @@ RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%s ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && \ - apt-get install -f -y \ - libdbus-1-3 \ - libdaemon0 \ - libpython2.7 \ - # Install redis-tools dependencies - # TODO: implicitly install dependencies - libatomic1 \ - libjemalloc1 \ - liblua5.1-0 \ - lua-bitop \ - lua-cjson - -RUN apt-get -y install ebtables +RUN apt-get update && \ + apt-get install -y ebtables RUN apt-get -y install -f kmod COPY \ diff --git a/dockers/docker-nat/Dockerfile.j2 b/dockers/docker-nat/Dockerfile.j2 index a74147cc26fd..30f4cd1c0cb8 100644 --- a/dockers/docker-nat/Dockerfile.j2 +++ b/dockers/docker-nat/Dockerfile.j2 @@ -13,15 +13,6 @@ ENV DEBIAN_FRONTEND=noninteractive ## TODO: implicitly install dependencies RUN apt-get update \ && apt-get install -f -y \ - libdbus-1-3 \ - libdaemon0 \ - libjansson4 \ - libpython2.7 \ - libatomic1 \ - libjemalloc1 \ - liblua5.1-0 \ - lua-bitop \ - lua-cjson \ libelf1 \ libmnl0 \ bridge-utils \ diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index f95acd48fdbd..43c9d5896f34 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -11,10 +11,6 @@ RUN apt-get update && \ apt-get install -f -y \ ifupdown \ arping \ - libdbus-1-3 \ - libdaemon0 \ - libjansson4 \ - libpython2.7 \ iproute2 \ ndisc6 \ tcpdump \ diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index fd11f628559c..4f5f2b77141b 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -11,7 +11,6 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y \ python-pip \ - libpython2.7 \ ipmitool \ librrd8 \ librrd-dev \ diff --git a/dockers/docker-sonic-telemetry/Dockerfile.j2 b/dockers/docker-sonic-telemetry/Dockerfile.j2 index e94441b4f066..cbc8a1e916fa 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/Dockerfile.j2 @@ -7,11 +7,7 @@ RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%s ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && \ - apt-get install -f -y \ - libdbus-1-3 \ - libdaemon0 \ - libjansson4 +RUN apt-get update {% if docker_sonic_telemetry_debs.strip() -%} # Copy locally-built Debian package dependencies diff --git a/dockers/docker-teamd/Dockerfile.j2 b/dockers/docker-teamd/Dockerfile.j2 index 4282a10d0c86..704f3c2ebbda 100644 --- a/dockers/docker-teamd/Dockerfile.j2 +++ b/dockers/docker-teamd/Dockerfile.j2 @@ -7,12 +7,7 @@ RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%s ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && \ - apt-get install -f -y \ - libdbus-1-3 \ - libdaemon0 \ - libjansson4 \ - libpython2.7 +RUN apt-get update {% if docker_teamd_debs.strip() -%} # Copy locally-built Debian package dependencies diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index ee3858aca647..f7c88c9b833a 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -27,18 +27,10 @@ RUN apt-get install -y net-tools \ libboost-thread1.62.0 \ libgmp10 \ libjudydebian1 \ - libdaemon0 \ - libjansson4 \ - libatomic1 \ - libjemalloc1 \ - liblua5.1-0 \ - lua-bitop \ - lua-cjson \ openssh-client \ openssh-server \ libc-ares2 \ iproute \ - libpython2.7 \ grub2-common \ python-click-default-group \ python-click \ From 296470de2590ad9a6d0fdbab72d3094af3c944cb Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 6 Apr 2020 07:40:24 -0700 Subject: [PATCH 0491/1427] [docker-iccp]: do not mount kernel module into iccp container (#4372) kernel module should be loaded outside container Signed-off-by: Guohan Lu --- files/build_templates/docker_image_ctl.j2 | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 6012ccd8b573..6067c58f41e9 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -231,9 +231,6 @@ start() { {%- if docker_container_name != "database" %} -v /usr/share/sonic/device/$PLATFORM/$HWSKU/$DEV:/usr/share/sonic/hwsku:ro \ {%- endif %} -{%- if docker_container_name == "iccpd" %} - -v /lib/modules:/lib/modules:ro \ -{%- endif %} {%- if sonic_asic_platform != "mellanox" %} --tmpfs /tmp \ {%- endif %} @@ -255,7 +252,7 @@ wait() { stop() { docker stop {{docker_container_name}}$DEV {%- if docker_container_name == "database" %} - if [ "$DEV" ]; then + if [ "$DEV" ]; then ip netns delete "$NET_NS" fi {%- endif %} @@ -266,7 +263,7 @@ DEV=$2 # namespace/device number to operate on if [ "$DEV" ]; then NET_NS="asic$DEV" #name of the network namespace else - NET_NS="" + NET_NS="" fi case "$1" in From 7bc8f1293c4a8ab9d04caeaba090b3f6dd9abb5c Mon Sep 17 00:00:00 2001 From: Santhosh Kumar T <53558409+santhosh-kt@users.noreply.github.com> Date: Mon, 6 Apr 2020 21:57:45 +0530 Subject: [PATCH 0492/1427] [DellEMC] Z9264f Watchdog support (#4192) Co-authored-by: Sujin Kang --- .../z9264f/sonic_platform/chassis.py | 3 + .../z9264f/sonic_platform/watchdog.py | 214 ++++++++++++++++++ 2 files changed, 217 insertions(+) create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/watchdog.py diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py index cefa7ab49561..0eec21c09c28 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py @@ -16,6 +16,7 @@ from sonic_platform.eeprom import Eeprom from sonic_platform.component import Component from sonic_platform.psu import Psu + from sonic_platform.watchdog import Watchdog from sonic_platform.fan import Fan from sonic_platform.thermal import Thermal except ImportError as e: @@ -61,6 +62,8 @@ def __init__(self): self._sfp_list.append(sfp_node) self._eeprom = Eeprom() + + self._watchdog = Watchdog() for i in range(MAX_Z9264F_COMPONENT): component = Component(i) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/watchdog.py new file mode 100644 index 000000000000..d3363067db63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/watchdog.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python + +######################################################################## +# +# DELLEMC Z9264f +# +# Abstract base class for implementing a platform-specific class with +# which to interact with a hardware watchdog module in SONiC +# +######################################################################## + +try: + import sys + import struct + import ctypes + import subprocess + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class _timespec(ctypes.Structure): + _fields_ = [ + ('tv_sec', ctypes.c_long), + ('tv_nsec', ctypes.c_long) + ] + + +class Watchdog(WatchdogBase): + """ + Abstract base class for interfacing with a hardware watchdog module + """ + + TIMERS = [15,20,30,40,50,60,65,70] + + armed_time = 0 + timeout = 0 + CLOCK_MONOTONIC = 1 + + def __init__(self): + self._librt = ctypes.CDLL('librt.so.1', use_errno=True) + self._clock_gettime = self._librt.clock_gettime + self._clock_gettime.argtypes=[ctypes.c_int, ctypes.POINTER(_timespec)] + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_reg_val(self): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cget -y 601 0x31 0x07") + if not value: + return None + else: + return int(value, 16) + + def _set_reg_val(self,val): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cset -y 601 0x31 0x07 %s" + % (val)) + return value + + def _get_time(self): + """ + To get clock monotonic time + """ + ts = _timespec() + if self._clock_gettime(self.CLOCK_MONOTONIC, ctypes.pointer(ts)) != 0: + self._errno = ctypes.get_errno() + return 0 + return ts.tv_sec + ts.tv_nsec * 1e-9 + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* + available value. + + Returns: + An integer specifying the *actual* number of seconds the + watchdog was armed with. On failure returns -1. + """ + timer_offset = -1 + for key,timer_seconds in enumerate(self.TIMERS): + if seconds <= timer_seconds: + timer_offset = key + seconds = timer_seconds + break + + if timer_offset == -1: + return -1 + + # Extracting 5th to 7th bits for WD timer values + # 000 - 15 sec + # 001 - 20 sec + # 010 - 30 sec + # 011 - 40 sec + # 100 - 50 sec + # 101 - 60 sec + # 110 - 65 sec + # 111 - 70 sec + reg_val = self._get_reg_val() + wd_timer_offset = (reg_val >> 4) & 0x7 + + if wd_timer_offset != timer_offset: + # Setting 5th to 7th bits + # value from timer_offset + self.disarm() + self._set_reg_val((reg_val & 0x87) | (timer_offset << 4)) + + if self.is_armed(): + # Setting last bit to WD Timer punch + # Last bit = WD Timer punch + self._set_reg_val(reg_val & 0xFE) + + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + else: + # Setting 4th bit to enable WD + # 4th bit = Enable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val | 0x8) + + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + + return -1 + + def disarm(self): + """ + Disarm the hardware watchdog + + Returns: + A boolean, True if watchdog is disarmed successfully, False + if not + """ + if self.is_armed(): + # Setting 4th bit to disable WD + # 4th bit = Disable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val & 0xF7) + + self.armed_time = 0 + self.timeout = 0 + return True + + return False + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + + Returns: + A boolean, True if watchdog is armed, False if not + """ + + # Extracting 4th bit to get WD Enable/Disable status + # 0 - Disabled WD + # 1 - Enabled WD + reg_val = self._get_reg_val() + wd_offset = (reg_val >> 3) & 1 + + return bool(wd_offset) + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds + remaining on the watchdog timer + + Returns: + An integer specifying the number of seconds remaining on + their watchdog timer. If the watchdog is not armed, returns + -1. + + Z9264 doesnot have hardware support to show remaining time. + Due to this limitation, this API is implemented in software. + This API would return correct software time difference if it + is called from the process which armed the watchdog timer. + If this API called from any other process, it would return + 0. If the watchdog is not armed, this API would return -1. + """ + if not self.is_armed(): + return -1 + + if self.armed_time > 0 and self.timeout != 0: + cur_time = self._get_time() + + if cur_time <= 0: + return 0 + + diff_time = int(cur_time - self.armed_time) + + if diff_time > self.timeout: + return self.timeout + else: + return self.timeout - diff_time + + return 0 + From 2a59551effb272835247c7fef24117074fe5c6c2 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Tue, 7 Apr 2020 00:05:47 -0700 Subject: [PATCH 0493/1427] [sonic-netns-exec]: use "$@" to reflects all positional parameters as they were set initially (#4375) sonic-netns-exec fails to execute below command in swss.sh: sonic-netns-exec "$NET_NS" sonic-db-cli $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) for j,name in ipairs(matches) do redis.call('DEL', name) end end" 0 This command fails with error " redis.exceptions.ResponseError: value is not an integer or out of range" . Root cause: When sonic-netns-exec executes the above function, argument passed to sonic-db-cli is NOT executed as a single script. The argument is passed as separate keywords to sonic-db-cli, as below: ['EVAL', 'local', 'tables', '=', "{'PORT_TABLE*'}", 'for', 'i', '=', '1,', 'table.getn(tables)', 'do', 'local', 'matches', '=', "redis.call('KEYS',", 'tables[i])', 'for', 'j,name', 'in', 'ipairs(matches)', 'do', "redis.call('DEL',", 'name)', 'end', 'end', '0'] - How I did it To make sure that the parameters are passed as they were set initially, fix sonic-netns-exec to use double quoted "$@", where "$@" is "$1" "$2" "$3" ... "${N}" After fix, the argument passed to sonic-db-cli is as below: Argument passed to sonic-db-cli: ['EVAL', "\n local tables = {'PORT_TABLE*'}\n for i = 1, table.getn(tables) do\n local matches = redis.call('KEYS', tables[i])\n for j,name in ipairs(matches) do\n redis.call('DEL', name)\n end\n end", '0'] Signed-off-by: SuvarnaMeenakshi --- files/scripts/sonic-netns-exec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/files/scripts/sonic-netns-exec b/files/scripts/sonic-netns-exec index 166a2c7e4a2f..a0dfc6f9ab07 100755 --- a/files/scripts/sonic-netns-exec +++ b/files/scripts/sonic-netns-exec @@ -5,8 +5,8 @@ # sonic-netns-exec NS="$1" shift -if [ "$NS" != "" ]; then - ip netns exec $NS $@ +if [ ! -z "$NS" ]; then + ip netns exec $NS "$@" else - $@ + "$@" fi From 5299644dc0a817d2d940c9d7c9ef99c1bcb407f1 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 7 Apr 2020 12:31:20 -0700 Subject: [PATCH 0494/1427] [kvmbuild]: print out kvm_log on error (#4384) Signed-off-by: Guohan Lu --- scripts/build_kvm_image.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/build_kvm_image.sh b/scripts/build_kvm_image.sh index 5a56ac46efce..f9cd9490181d 100755 --- a/scripts/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -20,8 +20,11 @@ on_exit() rm -f $kvm_log } -kvm_log=$(mktemp) -trap on_exit EXIT +on_error() +{ + echo "============= kvm_log ==============" + cat $kvm_log +} create_disk() { @@ -56,6 +59,10 @@ if [[ "$vs_build_prepare_mem" == "yes" ]]; then free -m fi +kvm_log=$(mktemp) +trap on_exit EXIT +trap on_error ERR + /usr/bin/kvm -m $MEM \ -name "onie" \ -boot "order=cd,once=d" -cdrom "$ONIE_RECOVERY_ISO" \ From 711445c98e2304d89b3b9e6a2ef443caac0917e5 Mon Sep 17 00:00:00 2001 From: wangshengjun Date: Wed, 8 Apr 2020 03:49:34 +0800 Subject: [PATCH 0495/1427] [lldp]add the excutable mode for 'lldpcli' (#4385) Signed-off-by: wangshengjun --- dockers/docker-lldp-sv2/base_image_files/lldpcli | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 dockers/docker-lldp-sv2/base_image_files/lldpcli diff --git a/dockers/docker-lldp-sv2/base_image_files/lldpcli b/dockers/docker-lldp-sv2/base_image_files/lldpcli old mode 100644 new mode 100755 From f2ffd39587fce8fb9dd73e2d44e0ef4ea7601bd0 Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Tue, 7 Apr 2020 20:57:54 -0700 Subject: [PATCH 0496/1427] [build_debian.sh]: install python{3,}-pip on sonic base image. (#4380) Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com --- build_debian.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build_debian.sh b/build_debian.sh index 80c3823c14f4..fd247bbdf6aa 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -280,7 +280,9 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in ipmitool \ ndisc6 \ makedumpfile \ - conntrack + conntrack \ + python-pip \ + python3-pip if [[ $CONFIGURED_ARCH == amd64 ]]; then From 11da67bce1cf6bc5c1d6a70cbefa4b510fd8dd1a Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Wed, 8 Apr 2020 11:59:14 +0800 Subject: [PATCH 0497/1427] [doc]: Add 201911/201811 status support for Nephos (#4382) Add branch 201911/201811 status support for Nephos platform --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e79e697c70e1..02bb1fb4dff1 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,14 @@ Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/inno Barefoot: [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/) Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/) Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/) +Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201911) VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911) *201811*: Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/) Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/) Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/) +Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811) VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811) *201807*: From de5a04ad182347104502cfb64a47c22f5e337ece Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Tue, 7 Apr 2020 21:01:39 -0700 Subject: [PATCH 0498/1427] [MultiDB] : add persistence field for each redis instance (#4254) - add "persistence" field for each redis instance in database_config.json - we will use this information to decide if saving redis instance data while warm/fast reboot - before multiDB changes, SONiC uses "redis-cli save " to save all the data into rdb file on default instance on port 6379 - with multiDB changes, we plan to implement "sonic-db-cli save" to save all data to corresponding rdb files on all listed redis instances which has "persistence" field set "yes" --- dockers/docker-database/database_config.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dockers/docker-database/database_config.json b/dockers/docker-database/database_config.json index b86ae11bba98..c62bf746acba 100644 --- a/dockers/docker-database/database_config.json +++ b/dockers/docker-database/database_config.json @@ -3,7 +3,8 @@ "redis":{ "hostname" : "127.0.0.1", "port" : 6379, - "unix_socket_path" : "/var/run/redis/redis.sock" + "unix_socket_path" : "/var/run/redis/redis.sock", + "persistence_for_warm_boot" : "yes" } }, "DATABASES" : { From c5c0042a262d7ef668382a3cc96d1e0613df7325 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Tue, 7 Apr 2020 22:45:20 -0700 Subject: [PATCH 0499/1427] Update README.md: improve the style of build badges and add LGTM badges (#4395) * Update README.md: improve build badge style * Update README.md: add LGTM badges --- README.md | 76 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 02bb1fb4dff1..fda75bde93fc 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,45 @@ -*master*: -Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all) -Barefoot: [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all) -Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all) -Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all) -Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-all) -P4: [![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all) -VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all) - -*201911*: -Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/) -Barefoot: [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/) -Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/) -Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/) -Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201911) -VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911) - -*201811*: -Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/) -Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/) -Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/) -Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811) -VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811) - -*201807*: -Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/) -Barefoot: [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/) -Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201807/) - -*201803*: -Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/) -Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/) -Marvell: [![Marvell](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/) -Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/) +*master builds*: + +[![Total alerts](https://img.shields.io/lgtm/alerts/g/Azure/sonic-buildimage.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Azure/sonic-buildimage/alerts/) +[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/Azure/sonic-buildimage.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Azure/sonic-buildimage/context:python) + +[![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all) +[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all) +[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all) +[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all) +[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-all/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-all) +[![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/badge/icon?subject=P4)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all) +[![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all) + +*201911 builds*: + +[![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/) +[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/) +[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/) +[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/) +[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201911/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201911) +[![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911) + +*201811 builds*: + +[![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/) +[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/) +[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/) +[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811) +[![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811) + +*201807 builds*: + +[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/) +[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/) +[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201807/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201807/) + +*201803 builds*: + +[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/) +[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/) +[![Marvell](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/badge/icon?subject=Marvell)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/) +[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/) # sonic-buildimage From 2ecf80855667d0e127447fb7333a7e6355f287dc Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Wed, 8 Apr 2020 08:03:10 +0200 Subject: [PATCH 0500/1427] [submodule] update sairedis (#4379) * f4d9398 2020-04-07 | [vs] Set mto only on tap device (#592) [Kamil Cudnik] * 0ad13f5 2020-04-07 | [lgtm]: add lgtm static analysis configuration (#589) [lguohan] * c961260 2020-04-07 | add swss-common-{inc,lib} to specify the prefix of swss-common library (#590) [lguohan] * 2d68abc 2020-04-06 | [syncd] Load correct global context id (#588) [Kamil Cudnik] * cd82389 2020-04-06 | Return correct error code when port is in use (#565) [Vasant Patil] * 2189c2f 2020-04-02 | [syncd] Pass correct switch RID when staring diag shell (#587) [Kamil Cudnik] * 91792db 2020-04-01 | [syncd] Fix crash during stats polling (#586) [Vitaliy Senchyshyn] * d13521e 2020-04-01 | [meta] Flush fdb entries after flush api success (#581) [Kamil Cudnik] * 54b2510 2020-03-17 | [syncd] Use correct VID when GET will fail to obrain object type (#577) [Kamil Cudnik] * 59b0430 2020-03-16 | [syncd] Unlock vendor api lock if enabling diag shell (#571) [Kamil Cudnik] * 910d45e 2020-03-16 | [vs] Add more logs when setting MTU on port (#576) [Kamil Cudnik] * c0d9947 2020-03-13 | [vs] Fix setting correct port mtu value (#573) [Kamil Cudnik] --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index fe94170c8097..f4d9398c87ae 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit fe94170c809773d86b196bd8d881f78ba71a1d7c +Subproject commit f4d9398c87aee4fa66a0391b0d83f91595bc4480 From de377ebccdc4099dd17c4451b5f25db251eee554 Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Wed, 8 Apr 2020 02:44:50 -0400 Subject: [PATCH 0501/1427] Fix typo in config-setup service (#4388) --- files/image_config/config-setup/config-setup | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index f19abd266e95..afff97806518 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -247,7 +247,7 @@ generate_config() # is created # - If updategraph is enabled and ZTP is disabled, updategraph initializes # configuration -do_config_intialization() +do_config_initialization() { if ! updategraph_is_enabled ; then if ! ztp_is_enabled ; then @@ -350,12 +350,12 @@ boot_config() fi if [ -e /tmp/pending_config_initialization ] || [ -e ${CONFIG_SETUP_INITIALIZATION_FLAG} ]; then - do_config_intialization + do_config_initialization fi # If no startup configuration is found, create a configuration to be used if [ ! -e ${CONFIG_DB_JSON} ]; then - do_config_intialization + do_config_initialization # force ZTP to restart if ztp_is_enabled ; then ztp_status=$(ztp status -c) From 837c13fa63beb362153348b4ca1013b829ac520f Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Wed, 8 Apr 2020 12:39:36 +0300 Subject: [PATCH 0502/1427] [Mellanox] Enable ISSU on MSN2100, MSN2740, MSN3800 (#4387) --- .../mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/sai_2100.xml | 3 +++ .../mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/sai_2740.xml | 3 +++ .../mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/sai_2100.xml b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/sai_2100.xml index c9b844cd4bf8..92150596df64 100644 --- a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/sai_2100.xml +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/sai_2100.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 16 diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/sai_2740.xml b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/sai_2740.xml index 559f2bdd10c8..955ea3f8b1b6 100644 --- a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/sai_2740.xml +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/sai_2740.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 32 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml index 1b3c77ce381c..4d9cc3cf7f8c 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml @@ -5,8 +5,8 @@ 00:02:03:04:05:00 - - 1 + + 1 64 From 444cede11d71202d540844201ef2e47a97e66d81 Mon Sep 17 00:00:00 2001 From: Srideep Date: Wed, 8 Apr 2020 03:41:56 -0600 Subject: [PATCH 0503/1427] [DellEMC] S5232 platform updates (#4360) FPGA driver crash fix for stale buffer in i2c transfer LED firmware load issue fix. 10G port swapfix psu/sfp bug fixes to report correct states/status of hw --- .../DellEMC-S5232f-C32/port_config.ini | 4 +- .../DellEMC-S5232f-C32/sai_preinit_cmd.soc | 2 + .../td3-s5232f-32x100G.config.bcm | 2 + .../DellEMC-S5232f-P-100G/sai_preinit_cmd.soc | 2 + .../td3-s5232f-32x100G.config.bcm | 1 + .../DellEMC-S5232f-P-10G/sai_preinit_cmd.soc | 2 + .../td3-s5232f-96x10G+8x100G.config.bcm | 1 + .../DellEMC-S5232f-P-25G/sai_preinit_cmd.soc | 2 + .../td3-s5232f-96x25G+8x100G.config.bcm | 1 + .../led_proc_init.soc | 4 +- .../plugins/psuutil.py | 86 +- .../plugins/sfputil.py | 9 +- .../pmon_daemon_control.json | 3 +- .../s5232f/modules/dell_s5232f_fpga_ocores.c | 1609 +++++++++-------- .../s5232f/scripts/platform_sensors.py | 112 +- .../s5232f/scripts/s5232f_platform.sh | 44 + 16 files changed, 1034 insertions(+), 850 deletions(-) create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini index 55c8fb3dcf64..2b24bea93107 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini @@ -31,5 +31,5 @@ Ethernet112 113,114,115,116 hundredGigE1/29 29 100000 Ethernet116 117,118,119,120 hundredGigE1/30 30 100000 Ethernet120 121,122,123,124 hundredGigE1/31 31 100000 Ethernet124 125,126,127,128 hundredGigE1/32 32 100000 -Ethernet128 128 tenGigE1/33 33 10000 -Ethernet129 129 tenGigE1/34 34 10000 +Ethernet128 129 tenGigE1/33 33 10000 +Ethernet129 128 tenGigE1/34 34 10000 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm index e5b61b7f1b58..9b1035a942b3 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm @@ -542,3 +542,5 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT-LOSSLESS-P3P4" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm index 533e19aca1c2..e2735ded69e8 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm @@ -542,3 +542,4 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm index 0da20afc2203..0346c47749cb 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm @@ -615,3 +615,4 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm index 47cbb41f4073..ca81379ae512 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm @@ -615,3 +615,4 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc index 7105381ecdbc..098d5d4fd131 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc @@ -2,8 +2,8 @@ # # #Led0 -#led stop -m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +led stop +#m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin #led auto on led start diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py index bf10ef129626..c3e2a6d73bd0 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py @@ -11,12 +11,13 @@ S5232F_MAX_PSUS = 2 -IPMI_PSU_DATA = "docker exec -it pmon ipmitool sdr list" -IPMI_PSU_DATA_DOCKER = "ipmitool sdr list" +IPMI_PSU1_DATA = "docker exec -it pmon ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA = "docker exec -it pmon ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" PSU_PRESENCE = "PSU{0}_stat" # Use this for older firmware # PSU_PRESENCE="PSU{0}_prsnt" -ipmi_sdr_list = "" try: @@ -42,30 +43,26 @@ def isDockerEnv(self): def get_pmc_register(self, reg_name): status = 1 - global ipmi_sdr_list - ipmi_dev_node = "/dev/pmi0" - ipmi_cmd = IPMI_PSU_DATA + ipmi_cmd_1 = IPMI_PSU1_DATA + ipmi_cmd_2 = IPMI_PSU1_DATA dockerenv = self.isDockerEnv() if dockerenv == True: - ipmi_cmd = IPMI_PSU_DATA_DOCKER - - status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) if status: - logging.error('Failed to execute:' + ipmi_sdr_list) - sys.exit(0) - - for item in ipmi_sdr_list.split("\n"): - if reg_name in item: - output = item.strip() - - if not output: - print('\nFailed to fetch: ' + reg_name + ' sensor ') + logging.error('Failed to execute ipmitool') sys.exit(0) - output = output.split('|')[1] + output = ipmi_sdr_list - logging.basicConfig(level=logging.DEBUG) return output def get_num_psus(self): @@ -86,8 +83,26 @@ def get_psu_status(self, index): """ # Until psu_status is implemented this is hardcoded temporarily - status = 1 - return status + psu_status = 'f' + ret_status = 1 + dockerenv = self.isDockerEnv() + if dockerenv == True: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) + + if ret_status: + logging.error('Failed to execute ipmitool : ') + sys.exit(0) + + psu_status = ipmi_sdr_list + return (not int(psu_status, 16) > 1) def get_psu_presence(self, index): """ @@ -96,12 +111,23 @@ def get_psu_presence(self, index): :param index: An integer, index of the PSU of which to query status :return: Boolean, True if PSU is plugged, False if not """ - status = 0 - psu_reg_name = PSU_PRESENCE.format(index) - psu_status = int(self.get_pmc_register(psu_reg_name), 16) - if (psu_status != 'ERR'): - # Check for PSU presence - if (psu_status == 0x00): - status = 1 - return status + psu_status = '0' + ret_status = 1 + dockerenv = self.isDockerEnv() + if dockerenv == True: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) + + if ret_status: + logging.error('Failed to execute ipmitool : ') + sys.exit(0) + psu_status = ipmi_sdr_list + return (int(psu_status, 16) & 1) diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py index be2d31a16afc..978ade1ce319 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py @@ -49,8 +49,8 @@ class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" PORT_START = 1 - PORT_END = 64 - PORTS_IN_BLOCK = 64 + PORT_END = 34 + PORTS_IN_BLOCK = 32 BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" @@ -141,6 +141,11 @@ def get_presence(self, port_num): # Mask off 4th bit for presence mask = (1 << 4) + # Mask off 1st bit for presence 33,34 + if (port_num > 32): + mask = (1 << 0) + + # ModPrsL is active low if reg_value & mask == 0: return True diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json index 94592fa8cebc..44871c057e82 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c index f66f5f18a708..c50d07a05a53 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c @@ -1,25 +1,25 @@ /* - * Copyright (C) 2018 Dell Inc - * - * Licensed under the GNU General Public License Version 2 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ +* Copyright (C) 2018 Dell Inc +* +* Licensed under the GNU General Public License Version 2 +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +*/ -/********************************************************************** - * @file fpga_ocores.c - * @brief This is a driver to interface with Linux Open Cores driver for FPGA i2c access - * - ************************************************************************/ +/** +* @file fpga_i2ccore.c +* @brief This is a driver to interface with Linux Open Cores drivber for FPGA i2c access +* +************************************************************************/ #include #include #include @@ -67,30 +67,29 @@ static const size_t BUF_SIZE = PAGE_SIZE; /* Device data used by this driver. */ struct fpgapci_dev { - /* the kernel pci device data structure */ - struct pci_dev *pci_dev; - - /* upstream root node */ - struct pci_dev *upstream; + /* the kernel pci device data structure */ + struct pci_dev *pci_dev; - /* kernels virtual addr. for the mapped BARs */ - void * __iomem bar[PCI_NUM_BARS]; + /* upstream root node */ + struct pci_dev *upstream; - /* length of each memory region. Used for error checking. */ - size_t bar_length[PCI_NUM_BARS]; + /* kernels virtual addr. for the mapped BARs */ + void * __iomem bar[PCI_NUM_BARS]; - /* Debug data */ - /* number of hw interrupts handled. */ - int num_handled_interrupts; - int num_undelivered_signals; - int pci_gen; - int pci_num_lanes; + /* length of each memory region. Used for error checking. */ + size_t bar_length[PCI_NUM_BARS]; - unsigned int irq_first; - unsigned int irq_length; - unsigned int irq_assigned; - unsigned int xcvr_intr_count; + /* Debug data */ + /* number of hw interrupts handled. */ + int num_handled_interrupts; + int num_undelivered_signals; + int pci_gen; + int pci_num_lanes; + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + unsigned int xcvr_intr_count; }; static int use_irq = 1; @@ -100,7 +99,7 @@ MODULE_PARM_DESC(use_irq, "Get an use_irq value from user...\n"); static uint32_t num_bus = 0; module_param(num_bus, int, 0); MODULE_PARM_DESC(num_bus, - "Number of i2c busses supported by the FPGA on this platform."); + "Number of i2c busses supported by the FPGA on this platform."); /* Xilinx FPGA PCIE info: */ @@ -125,14 +124,14 @@ typedef unsigned long long u64; /* struct to hold data related to the pcie device */ struct pci_data_struct{ - struct pci_dev* dev; - unsigned long long phy_addr_bar0; - unsigned long long phy_len_bar0; - unsigned long long phy_flags_bar0; - unsigned int irq_first; - unsigned int irq_length; - unsigned int irq_assigned; - void * kvirt_addr_bar0; + struct pci_dev* dev; + unsigned long long phy_addr_bar0; + unsigned long long phy_len_bar0; + unsigned long long phy_flags_bar0; + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + void * kvirt_addr_bar0; }; /* global variable declarations */ @@ -147,55 +146,55 @@ static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); struct fpgalogic_i2c { - void __iomem *base; - u32 reg_shift; - u32 reg_io_width; - wait_queue_head_t wait; - struct i2c_msg *msg; - int pos; - int nmsgs; - int state; /* see STATE_ */ - int ip_clock_khz; - int bus_clock_khz; - void (*reg_set)(struct fpgalogic_i2c *i2c, int reg, u8 value); - u8 (*reg_get)(struct fpgalogic_i2c *i2c, int reg); - u32 timeout; - struct mutex lock; + void __iomem *base; + u32 reg_shift; + u32 reg_io_width; + wait_queue_head_t wait; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; /* see STATE_ */ + int ip_clock_khz; + int bus_clock_khz; + void (*reg_set)(struct fpgalogic_i2c *i2c, int reg, u8 value); + u8 (*reg_get)(struct fpgalogic_i2c *i2c, int reg); + u32 timeout; + struct mutex lock; }; /* registers */ -#define FPGAI2C_REG_PRELOW 0 -#define FPGAI2C_REG_PREHIGH 1 -#define FPGAI2C_REG_CONTROL 2 -#define FPGAI2C_REG_DATA 3 -#define FPGAI2C_REG_CMD 4 /* write only */ -#define FPGAI2C_REG_STATUS 4 /* read only, same address as FPGAI2C_REG_CMD */ -#define FPGAI2C_REG_VER 5 +#define FPGAI2C_REG_PRELOW 0 +#define FPGAI2C_REG_PREHIGH 1 +#define FPGAI2C_REG_CONTROL 2 +#define FPGAI2C_REG_DATA 3 +#define FPGAI2C_REG_CMD 4 /* write only */ +#define FPGAI2C_REG_STATUS 4 /* read only, same address as FPGAI2C_REG_CMD */ +#define FPGAI2C_REG_VER 5 -#define FPGAI2C_REG_CTRL_IEN 0x40 -#define FPGAI2C_REG_CTRL_EN 0x80 +#define FPGAI2C_REG_CTRL_IEN 0x40 +#define FPGAI2C_REG_CTRL_EN 0x80 -#define FPGAI2C_REG_CMD_START 0x91 -#define FPGAI2C_REG_CMD_STOP 0x41 -#define FPGAI2C_REG_CMD_READ 0x21 -#define FPGAI2C_REG_CMD_WRITE 0x11 -#define FPGAI2C_REG_CMD_READ_ACK 0x21 -#define FPGAI2C_REG_CMD_READ_NACK 0x29 -#define FPGAI2C_REG_CMD_IACK 0x01 +#define FPGAI2C_REG_CMD_START 0x91 +#define FPGAI2C_REG_CMD_STOP 0x41 +#define FPGAI2C_REG_CMD_READ 0x21 +#define FPGAI2C_REG_CMD_WRITE 0x11 +#define FPGAI2C_REG_CMD_READ_ACK 0x21 +#define FPGAI2C_REG_CMD_READ_NACK 0x29 +#define FPGAI2C_REG_CMD_IACK 0x01 -#define FPGAI2C_REG_STAT_IF 0x01 -#define FPGAI2C_REG_STAT_TIP 0x02 -#define FPGAI2C_REG_STAT_ARBLOST 0x20 -#define FPGAI2C_REG_STAT_BUSY 0x40 -#define FPGAI2C_REG_STAT_NACK 0x80 +#define FPGAI2C_REG_STAT_IF 0x01 +#define FPGAI2C_REG_STAT_TIP 0x02 +#define FPGAI2C_REG_STAT_ARBLOST 0x20 +#define FPGAI2C_REG_STAT_BUSY 0x40 +#define FPGAI2C_REG_STAT_NACK 0x80 /* SR[7:0] - Status register */ -#define FPGAI2C_REG_SR_RXACK (1 << 7) /* Receive acknowledge from slave ‘1’ = No acknowledge received*/ -#define FPGAI2C_REG_SR_BUSY (1 << 6) /* Busy, I2C bus busy (as defined by start / stop bits) */ -#define FPGAI2C_REG_SR_AL (1 << 5) /* Arbitration lost - fpga i2c logic lost arbitration */ -#define FPGAI2C_REG_SR_TIP (1 << 1) /* Transfer in progress */ -#define FPGAI2C_REG_SR_IF (1 << 0) /* Interrupt flag */ +#define FPGAI2C_REG_SR_RXACK (1 << 7) /* Receive acknowledge from slave .1. = No acknowledge received*/ +#define FPGAI2C_REG_SR_BUSY (1 << 6) /* Busy, I2C bus busy (as defined by start / stop bits) */ +#define FPGAI2C_REG_SR_AL (1 << 5) /* Arbitration lost - fpga i2c logic lost arbitration */ +#define FPGAI2C_REG_SR_TIP (1 << 1) /* Transfer in progress */ +#define FPGAI2C_REG_SR_IF (1 << 0) /* Interrupt flag */ enum { STATE_DONE = 0, @@ -205,15 +204,16 @@ enum { STATE_START, STATE_WRITE, STATE_READ, + STATE_STOP, STATE_ERROR, }; -#define TYPE_FPGALOGIC 0 -#define TYPE_GRLIB 1 +#define TYPE_FPGALOGIC 0 +#define TYPE_GRLIB 1 /*I2C_CH1 Offset address from PCIE BAR 0*/ -#define FPGALOGIC_I2C_BASE 0x00006000 -#define FPGALOGIC_CH_OFFSET 0x10 +#define FPGALOGIC_I2C_BASE 0x00006000 +#define FPGALOGIC_CH_OFFSET 0x10 #define i2c_bus_controller_numb 1 #define I2C_PCI_MAX_BUS (16) @@ -316,58 +316,58 @@ enum { static int total_i2c_pci_bus = 0; static uint32_t board_rev_type = 0; -static struct fpgalogic_i2c fpgalogic_i2c[I2C_PCI_MAX_BUS]; -static struct i2c_adapter i2c_pci_adap[I2C_PCI_MAX_BUS]; -static struct mutex i2c_xfer_lock[I2C_PCI_MAX_BUS]; +static struct fpgalogic_i2c fpgalogic_i2c[I2C_PCI_MAX_BUS]; +static struct i2c_adapter i2c_pci_adap[I2C_PCI_MAX_BUS]; +static struct mutex i2c_xfer_lock[I2C_PCI_MAX_BUS]; static void fpgai2c_reg_set_8(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite8(value, i2c->base + (reg << i2c->reg_shift)); + iowrite8(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_16(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite16(value, i2c->base + (reg << i2c->reg_shift)); + iowrite16(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_32(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite32(value, i2c->base + (reg << i2c->reg_shift)); + iowrite32(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_16be(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); + iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_32be(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); + iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_8(struct fpgalogic_i2c *i2c, int reg) { - return ioread8(i2c->base + (reg << i2c->reg_shift)); + return ioread8(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_16(struct fpgalogic_i2c *i2c, int reg) { - return ioread16(i2c->base + (reg << i2c->reg_shift)); + return ioread16(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_32(struct fpgalogic_i2c *i2c, int reg) { - return ioread32(i2c->base + (reg << i2c->reg_shift)); + return ioread32(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_16be(struct fpgalogic_i2c *i2c, int reg) { - return ioread16be(i2c->base + (reg << i2c->reg_shift)); + return ioread16be(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_32be(struct fpgalogic_i2c *i2c, int reg) { - return ioread32be(i2c->base + (reg << i2c->reg_shift)); + return ioread32be(i2c->base + (reg << i2c->reg_shift)); } static inline void fpgai2c_reg_set(struct fpgalogic_i2c *i2c, int reg, u8 value) @@ -384,29 +384,29 @@ static inline u8 fpgai2c_reg_get(struct fpgalogic_i2c *i2c, int reg) static void fpgai2c_dump(struct fpgalogic_i2c *i2c) { - u8 tmp; + u8 tmp; - PRINT("Logic register dump:\n"); + PRINT("Logic register dump:\n"); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PRELOW); - PRINT("FPGAI2C_REG_PRELOW (%d) = 0x%x\n",FPGAI2C_REG_PRELOW,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PRELOW); + PRINT("FPGAI2C_REG_PRELOW (%d) = 0x%x\n",FPGAI2C_REG_PRELOW,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PREHIGH); - PRINT("FPGAI2C_REG_PREHIGH(%d) = 0x%x\n",FPGAI2C_REG_PREHIGH,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PREHIGH); + PRINT("FPGAI2C_REG_PREHIGH(%d) = 0x%x\n",FPGAI2C_REG_PREHIGH,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); - PRINT("FPGAI2C_REG_CONTROL(%d) = 0x%x\n",FPGAI2C_REG_CONTROL,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + PRINT("FPGAI2C_REG_CONTROL(%d) = 0x%x\n",FPGAI2C_REG_CONTROL,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); - PRINT("FPGAI2C_REG_DATA (%d) = 0x%x\n",FPGAI2C_REG_DATA,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + PRINT("FPGAI2C_REG_DATA (%d) = 0x%x\n",FPGAI2C_REG_DATA,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CMD); - PRINT("FPGAI2C_REG_CMD (%d) = 0x%x\n",FPGAI2C_REG_CMD,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CMD); + PRINT("FPGAI2C_REG_CMD (%d) = 0x%x\n",FPGAI2C_REG_CMD,tmp); } static void fpgai2c_stop(struct fpgalogic_i2c *i2c) { - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); } /* @@ -414,117 +414,117 @@ static void fpgai2c_stop(struct fpgalogic_i2c *i2c) */ static int fpgai2c_poll(struct fpgalogic_i2c *i2c) { - u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); - struct i2c_msg *msg = i2c->msg; - u8 addr; - - /* Ready? */ - if (stat & FPGAI2C_REG_STAT_TIP) - return -EBUSY; - - if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { - /* Stop has been sent */ - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); - if (i2c->state == STATE_ERROR) - return -EIO; - return 0; - } - - /* Error? */ - if (stat & FPGAI2C_REG_STAT_ARBLOST) { - i2c->state = STATE_ERROR; - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); - return -EAGAIN; - } - - if (i2c->state == STATE_INIT) { - if (stat & FPGAI2C_REG_STAT_BUSY) - return -EBUSY; - - i2c->state = STATE_ADDR; - } - - if (i2c->state == STATE_ADDR) { - /* 10 bit address? */ - if (i2c->msg->flags & I2C_M_TEN) { - addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6); - i2c->state = STATE_ADDR10; - } else { - addr = (i2c->msg->addr << 1); - i2c->state = STATE_START; - } + u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + struct i2c_msg *msg = i2c->msg; + u8 addr; + + /* Ready? */ + if (stat & FPGAI2C_REG_STAT_TIP) + return -EBUSY; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* Stop has been sent */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (i2c->state == STATE_ERROR) + return -EIO; + return 0; + } + + /* Error? */ + if (stat & FPGAI2C_REG_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -EAGAIN; + } + + if (i2c->state == STATE_INIT) { + if (stat & FPGAI2C_REG_STAT_BUSY) + return -EBUSY; + + i2c->state = STATE_ADDR; + } + + if (i2c->state == STATE_ADDR) { + /* 10 bit address? */ + if (i2c->msg->flags & I2C_M_TEN) { + addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6); + i2c->state = STATE_ADDR10; + } else { + addr = (i2c->msg->addr << 1); + i2c->state = STATE_START; + } - /* Set read bit if necessary */ - addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0; + /* Set read bit if necessary */ + addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0; - fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); - return 0; - } + return 0; + } - /* Second part of 10 bit addressing */ - if (i2c->state == STATE_ADDR10) { - fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, i2c->msg->addr & 0xff); - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + /* Second part of 10 bit addressing */ + if (i2c->state == STATE_ADDR10) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, i2c->msg->addr & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); - i2c->state = STATE_START; - return 0; - } + i2c->state = STATE_START; + return 0; + } - if (i2c->state == STATE_START || i2c->state == STATE_WRITE) { - i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + if (i2c->state == STATE_START || i2c->state == STATE_WRITE) { + i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; - if (stat & FPGAI2C_REG_STAT_NACK) { - i2c->state = STATE_ERROR; - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); - return -ENXIO; - } - } else { - msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); - } - - if (i2c->pos >= msg->len) { - i2c->nmsgs--; - i2c->msg++; - i2c->pos = 0; - msg = i2c->msg; - - if (i2c->nmsgs) { - if (!(msg->flags & I2C_M_NOSTART)) { - i2c->state = STATE_ADDR; - return 0; - } else { - i2c->state = (msg->flags & I2C_M_RD) - ? STATE_READ : STATE_WRITE; - } - } else { - i2c->state = STATE_DONE; - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); - return 0; - } - } + if (stat & FPGAI2C_REG_STAT_NACK) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -ENXIO; + } + } else { + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + } + + if (i2c->pos >= msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { + if (!(msg->flags & I2C_M_NOSTART)) { + i2c->state = STATE_ADDR; + return 0; + } else { + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } + } else { + i2c->state = STATE_DONE; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return 0; + } + } - if (i2c->state == STATE_READ) { - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len - 1) ? - FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); - } else { - fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); - } + if (i2c->state == STATE_READ) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len - 1) ? + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + } else { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + } - return 0; + return 0; } static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, char *buf) { int ind = 0, port_status=0, port_irq_status=0; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); PRINT("%s:xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); for(ind=0;ind<64;ind++) { - port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); } return sprintf(buf,"0x%04x\n",fpgapci->xcvr_intr_count); @@ -532,31 +532,31 @@ static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL); static struct attribute *port_attrs[] = { - &dev_attr_port_msi.attr, - NULL, + &dev_attr_port_msi.attr, + NULL, }; static struct attribute_group port_attr_grp = { - .attrs = port_attrs, + .attrs = port_attrs, }; static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) { struct pci_dev *pdev = dev; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); int ind = 0, port_status=0, port_irq_status=0; for(ind=0;ind<32;ind++) { - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); if(port_irq_status&(IRQ_LTCH_STS|PRSNT_LTCH_STS)) { PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - //write on clear - iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + //write on clear + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); } } - fpgapci->xcvr_intr_count++; + fpgapci->xcvr_intr_count++; PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); return IRQ_HANDLED; @@ -565,19 +565,18 @@ static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) static irqreturn_t fpgaport_33_64_isr(int irq, void *dev) { struct pci_dev *pdev = dev; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); int ind = 0, port_status=0, port_irq_status=0; for(ind=32;ind<64;ind++) { - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); if(port_irq_status| (IRQ_LTCH_STS|PRSNT_LTCH_STS)) { PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - //write on clear - iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); } } - fpgapci->xcvr_intr_count++; + fpgapci->xcvr_intr_count++; PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); return IRQ_HANDLED; @@ -590,10 +589,14 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) PRINT("fpgai2c_process in. status reg :0x%x\n", stat); - if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { + if ((i2c->state == STATE_STOP) || (i2c->state == STATE_ERROR)) { /* stop has been sent */ - PRINT("fpgai2c_process FPGAI2C_REG_CMD_IACK stat = 0x%x Set FPGAI2C_REG_CMD(0%x) FPGAI2C_REG_CMD_IACK = 0x%x\n",stat, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + PRINT("fpgai2c_process FPGAI2C_REG_CMD_IACK stat = 0x%x Set FPGAI2C_REG_CMD(0%x) FPGAI2C_REG_CMD_IACK = 0x%x\n" \ + ,stat, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if(i2c->state == STATE_STOP) { + i2c->state = STATE_DONE; + } wake_up(&i2c->wait); return; } @@ -628,7 +631,7 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) i2c->pos = 0; msg = i2c->msg; - if (i2c->nmsgs) { /* end? */ + if (i2c->nmsgs) { /* end? */ /* send start? */ if (!(msg->flags & I2C_M_NOSTART)) { @@ -647,7 +650,7 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) ? STATE_READ : STATE_WRITE; } } else { - i2c->state = STATE_DONE; + i2c->state = STATE_STOP; fpgai2c_stop(i2c); return; } @@ -655,9 +658,9 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) if (i2c->state == STATE_READ) { PRINT("fpgai2c_poll STATE_READ i2c->pos=%d msg->len-1 = 0x%x set FPGAI2C_REG_CMD = 0x%x\n",i2c->pos, msg->len-1, - i2c->pos == (msg->len-1) ? FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + i2c->pos == (msg->len-1) ? FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len-1) ? - FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); } else { PRINT("fpgai2c_process set FPGAI2C_REG_DATA(0x%x)\n",FPGAI2C_REG_DATA); fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); @@ -667,14 +670,14 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) static irqreturn_t fpgai2c_isr(int irq, void *dev_id) { - struct fpgalogic_i2c *i2c = dev_id; - fpgai2c_process(i2c); + struct fpgalogic_i2c *i2c = dev_id; + fpgai2c_process(i2c); - return IRQ_HANDLED; + return IRQ_HANDLED; } void dell_get_mutex(struct fpgalogic_i2c *i2c) { - mutex_lock(&i2c->lock); + mutex_lock(&i2c->lock); } /** @@ -682,7 +685,7 @@ void dell_get_mutex(struct fpgalogic_i2c *i2c) */ void dell_release_mutex(struct fpgalogic_i2c *i2c) { - mutex_unlock(&i2c->lock); + mutex_unlock(&i2c->lock); } static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) @@ -721,8 +724,9 @@ static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) } else { + ret = -ETIMEDOUT; PRINT("Set FPGAI2C_REG_DATA(0%x) val = 0x%x\n",FPGAI2C_REG_DATA, - (i2c->msg->addr << 1) | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); + (i2c->msg->addr << 1) | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, (i2c->msg->addr << 1) | @@ -731,136 +735,135 @@ static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) /* Interrupt mode */ if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || - (i2c->state == STATE_DONE), HZ)) - return (i2c->state == STATE_DONE) ? num : -EIO; - else - return -ETIMEDOUT; + (i2c->state == STATE_DONE), HZ)) + ret = (i2c->state == STATE_DONE) ? num : -EIO; + return ret; } } static int fpgai2c_init(struct fpgalogic_i2c *i2c) { - int prescale; - int diff; - u8 ctrl; - - if (i2c->reg_io_width == 0) - i2c->reg_io_width = 1; /* Set to default value */ - - if (!i2c->reg_set || !i2c->reg_get) { - bool be = 0; //1:big_endian 0:little_endian - - switch (i2c->reg_io_width) { - case 1: - i2c->reg_set = fpgai2c_reg_set_8; - i2c->reg_get = fpgai2c_reg_get_8; - break; - - case 2: - i2c->reg_set = be ? fpgai2c_reg_set_16be : fpgai2c_reg_set_16; - i2c->reg_get = be ? fpgai2c_reg_get_16be : fpgai2c_reg_get_16; - break; - - case 4: - i2c->reg_set = be ? fpgai2c_reg_set_32be : fpgai2c_reg_set_32; - i2c->reg_get = be ? fpgai2c_reg_get_32be : fpgai2c_reg_get_32; - break; - - default: - PRINT("Unsupported I/O width (%d)\n", - i2c->reg_io_width); - return -EINVAL; - } - } + int prescale; + int diff; + u8 ctrl; + + if (i2c->reg_io_width == 0) + i2c->reg_io_width = 1; /* Set to default value */ + + if (!i2c->reg_set || !i2c->reg_get) { + bool be = 0; //1:big_endian 0:little_endian + + switch (i2c->reg_io_width) { + case 1: + i2c->reg_set = fpgai2c_reg_set_8; + i2c->reg_get = fpgai2c_reg_get_8; + break; + + case 2: + i2c->reg_set = be ? fpgai2c_reg_set_16be : fpgai2c_reg_set_16; + i2c->reg_get = be ? fpgai2c_reg_get_16be : fpgai2c_reg_get_16; + break; + + case 4: + i2c->reg_set = be ? fpgai2c_reg_set_32be : fpgai2c_reg_set_32; + i2c->reg_get = be ? fpgai2c_reg_get_32be : fpgai2c_reg_get_32; + break; + + default: + PRINT("Unsupported I/O width (%d)\n", + i2c->reg_io_width); + return -EINVAL; + } + } - ctrl = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + ctrl = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); - PRINT("%s(), line:%d\n", __func__, __LINE__); - PRINT("i2c->base = 0x%p\n",i2c->base); - - PRINT("ctrl = 0x%x\n",ctrl); - PRINT("set ctrl = 0x%x\n",ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - - /* make sure the device is disabled */ - fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - - /* - * I2C Frequency depends on host clock - * input clock of 100MHz - * prescale to 100MHz / ( 5*100kHz) -1 = 199 = 0x4F 100000/(5*100)-1=199=0xc7 - */ - prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; - prescale = clamp(prescale, 0, 0xffff); - - diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; - if (abs(diff) > i2c->bus_clock_khz / 10) { - PRINT("Unsupported clock settings: core: %d KHz, bus: %d KHz\n", - i2c->ip_clock_khz, i2c->bus_clock_khz); - return -EINVAL; - } + PRINT("%s(), line:%d\n", __func__, __LINE__); + PRINT("i2c->base = 0x%p\n",i2c->base); - fpgai2c_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); - fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); + PRINT("ctrl = 0x%x\n",ctrl); + PRINT("set ctrl = 0x%x\n",ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - /* Init the device */ - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); - if (!use_irq) - fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); - else - fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); + /* make sure the device is disabled */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - fpgai2c_dump(i2c); + /* + * I2C Frequency depends on host clock + * input clock of 100MHz + * prescale to 100MHz / ( 5*100kHz) -1 = 199 = 0x4F 100000/(5*100)-1=199=0xc7 + */ + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); - /* Initialize interrupt handlers if not already done */ - init_waitqueue_head(&i2c->wait); + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + PRINT("Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } - return 0; + fpgai2c_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); + + /* Init the device */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (!use_irq) + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); + else + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); + + fpgai2c_dump(i2c); + + /* Initialize interrupt handlers if not already done */ + init_waitqueue_head(&i2c->wait); + + return 0; } static u32 fpgai2c_func(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } static const struct i2c_algorithm fpgai2c_algorithm = { - .master_xfer = fpgai2c_xfer, - .functionality = fpgai2c_func, + .master_xfer = fpgai2c_xfer, + .functionality = fpgai2c_func, }; static int i2c_pci_add_bus (struct i2c_adapter *adap) { - int ret = 0; - /* Register new adapter */ - adap->algo = &fpgai2c_algorithm; - ret = i2c_add_numbered_adapter(adap); - return ret; + int ret = 0; + /* Register new adapter */ + adap->algo = &fpgai2c_algorithm; + ret = i2c_add_numbered_adapter(adap); + return ret; } static int i2c_init_internal_data(void) { - int i; + int i; PRINT("%s(), line:%d\n", __func__, __LINE__); - for( i = 0; i < total_i2c_pci_bus; i++ ) - { - fpgalogic_i2c[i].reg_shift = 0; /* 8 bit registers */ - fpgalogic_i2c[i].reg_io_width = 1; /* 8 bit read/write */ - fpgalogic_i2c[i].timeout = 500;//1000;//1ms - fpgalogic_i2c[i].ip_clock_khz = 100000;//100000;/* input clock of 100MHz */ - fpgalogic_i2c[i].bus_clock_khz = 100; - fpgalogic_i2c[i].base = fpga_base_addr + i*FPGALOGIC_CH_OFFSET; - mutex_init(&fpgalogic_i2c[i].lock); - fpgai2c_init(&fpgalogic_i2c[i]); - } - - return 0; + for( i = 0; i < total_i2c_pci_bus; i++ ) + { + fpgalogic_i2c[i].reg_shift = 0; /* 8 bit registers */ + fpgalogic_i2c[i].reg_io_width = 1; /* 8 bit read/write */ + fpgalogic_i2c[i].timeout = 500;//1000;//1ms + fpgalogic_i2c[i].ip_clock_khz = 100000;//100000;/* input clock of 100MHz */ + fpgalogic_i2c[i].bus_clock_khz = 100; + fpgalogic_i2c[i].base = fpga_base_addr + i*FPGALOGIC_CH_OFFSET; + mutex_init(&fpgalogic_i2c[i].lock); + fpgai2c_init(&fpgalogic_i2c[i]); + } + + return 0; } static int i2c_pci_init (void) { - int i; + int i; if (num_bus == 0) { board_rev_type = ioread32(fpga_ctl_addr + MB_BRD_REV_TYPE); @@ -868,8 +871,8 @@ static int i2c_pci_init (void) if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { num_bus = I2C_PCI_MAX_BUS_REV00; } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { switch (board_rev_type & MB_BRD_TYPE_MASK){ case BRD_TYPE_S5212_NON_NEBS: case BRD_TYPE_S5212_NEBS: @@ -907,46 +910,46 @@ static int i2c_pci_init (void) } } - printk("board_rev_type 0x%x, num_bus 0x%x\n", board_rev_type, num_bus); - total_i2c_pci_bus = num_bus; + printk("board_rev_type 0x%x, num_bus 0x%x\n", board_rev_type, num_bus); + total_i2c_pci_bus = num_bus; - memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); - memset (&fpgalogic_i2c, 0, sizeof(fpgalogic_i2c)); - for(i=0; i < i2c_bus_controller_numb; i++) - mutex_init(&i2c_xfer_lock[i]); + memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); + memset (&fpgalogic_i2c, 0, sizeof(fpgalogic_i2c)); + for(i=0; i < i2c_bus_controller_numb; i++) + mutex_init(&i2c_xfer_lock[i]); - /* Initialize driver's itnernal data structures */ - i2c_init_internal_data(); + /* Initialize driver's itnernal data structures */ + i2c_init_internal_data(); - for (i = 0 ; i < total_i2c_pci_bus; i ++) { + for (i = 0 ; i < total_i2c_pci_bus; i ++) { - i2c_pci_adap[i].owner = THIS_MODULE; - i2c_pci_adap[i].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + i2c_pci_adap[i].owner = THIS_MODULE; + i2c_pci_adap[i].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; - i2c_pci_adap[i].algo_data = &fpgalogic_i2c[i]; - /* /dev/i2c-600 ~ /dev/i2c-615 for FPGA LOGIC I2C channel controller 1-7 */ - i2c_pci_adap[i].nr = i+600; - sprintf( i2c_pci_adap[ i ].name, "i2c-pci-%d", i ); - /* Add the bus via the algorithm code */ - if( i2c_pci_add_bus( &i2c_pci_adap[ i ] ) != 0 ) - { - PRINT("Cannot add bus %d to algorithm layer\n", i ); - return( -ENODEV ); - } - i2c_set_adapdata(&i2c_pci_adap[i], &fpgalogic_i2c[i]); + i2c_pci_adap[i].algo_data = &fpgalogic_i2c[i]; + /* /dev/i2c-600 ~ /dev/i2c-615 for FPGA LOGIC I2C channel controller 1-7 */ + i2c_pci_adap[i].nr = i+600; + sprintf( i2c_pci_adap[ i ].name, "i2c-pci-%d", i ); + /* Add the bus via the algorithm code */ + if( i2c_pci_add_bus( &i2c_pci_adap[ i ] ) != 0 ) + { + PRINT("Cannot add bus %d to algorithm layer\n", i ); + return( -ENODEV ); + } + i2c_set_adapdata(&i2c_pci_adap[i], &fpgalogic_i2c[i]); - PRINT( "Registered bus id: %s\n", kobject_name(&i2c_pci_adap[ i ].dev.kobj)); - } + PRINT( "Registered bus id: %s\n", kobject_name(&i2c_pci_adap[ i ].dev.kobj)); + } - return 0; + return 0; } static void i2c_pci_deinit(void) { - int i; - for( i = 0; i < total_i2c_pci_bus; i++ ){ - i2c_del_adapter(&i2c_pci_adap[i]); - } + int i; + for( i = 0; i < total_i2c_pci_bus; i++ ){ + i2c_del_adapter(&i2c_pci_adap[i]); + } } @@ -954,61 +957,61 @@ static void i2c_pci_deinit(void) * Used for re-training and disabling AER. */ static struct pci_dev* find_upstream_dev (struct pci_dev *dev) { - struct pci_bus *bus = 0; - struct pci_dev *bridge = 0; - struct pci_dev *cur = 0; - int found_dev = 0; - - bus = dev->bus; - if (bus == 0) { - PRINT ( "Device doesn't have an associated bus!\n"); - return 0; - } - - bridge = bus->self; - if (bridge == 0) { - PRINT ( "Can't get the bridge for the bus!\n"); - return 0; - } - - PRINT ( "Upstream device %x/%x, bus:slot.func %02x:%02x.%02x\n", - bridge->vendor, bridge->device, - bridge->bus->number, PCI_SLOT(bridge->devfn), PCI_FUNC(bridge->devfn)); - - PRINT ( "List of downstream devices:"); - list_for_each_entry (cur, &bus->devices, bus_list) { - if (cur != 0) { - PRINT ( " %x/%x", cur->vendor, cur->device); - if (cur == dev) { - found_dev = 1; - } - } - } - PRINT ( "\n"); - if (found_dev) { - return bridge; - } else { - PRINT ( "Couldn't find upstream device!\n"); - return 0; - } + struct pci_bus *bus = 0; + struct pci_dev *bridge = 0; + struct pci_dev *cur = 0; + int found_dev = 0; + + bus = dev->bus; + if (bus == 0) { + PRINT ( "Device doesn't have an associated bus!\n"); + return 0; + } + + bridge = bus->self; + if (bridge == 0) { + PRINT ( "Can't get the bridge for the bus!\n"); + return 0; + } + + PRINT ( "Upstream device %x/%x, bus:slot.func %02x:%02x.%02x\n", + bridge->vendor, bridge->device, + bridge->bus->number, PCI_SLOT(bridge->devfn), PCI_FUNC(bridge->devfn)); + + PRINT ( "List of downstream devices:"); + list_for_each_entry (cur, &bus->devices, bus_list) { + if (cur != 0) { + PRINT ( " %x/%x", cur->vendor, cur->device); + if (cur == dev) { + found_dev = 1; + } + } + } + PRINT ( "\n"); + if (found_dev) { + return bridge; + } else { + PRINT ( "Couldn't find upstream device!\n"); + return 0; + } } static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) { - int i; - - for (i = 0; i < PCI_NUM_BARS; i++) { - unsigned long bar_start = pci_resource_start(dev, i); - if (bar_start) { - unsigned long bar_end = pci_resource_end(dev, i); - unsigned long bar_flags = pci_resource_flags(dev, i); - PRINT ( "BAR[%d] 0x%08lx-0x%08lx flags 0x%08lx", - i, bar_start, bar_end, bar_flags); - } - } + int i; + + for (i = 0; i < PCI_NUM_BARS; i++) { + unsigned long bar_start = pci_resource_start(dev, i); + if (bar_start) { + unsigned long bar_end = pci_resource_end(dev, i); + unsigned long bar_flags = pci_resource_flags(dev, i); + PRINT ( "BAR[%d] 0x%08lx-0x%08lx flags 0x%08lx", + i, bar_start, bar_end, bar_flags); + } + } - return 0; + return 0; } @@ -1019,64 +1022,64 @@ static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) */ static int map_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) { - int i; + int i; - for (i = 0; i < PCI_NUM_BARS; i++){ - phys_addr_t bar_start = pci_resource_start(dev, i); - phys_addr_t bar_end = pci_resource_end(dev, i); - unsigned long bar_length = bar_end - bar_start + 1; - fpgapci->bar_length[i] = bar_length; + for (i = 0; i < PCI_NUM_BARS; i++){ + phys_addr_t bar_start = pci_resource_start(dev, i); + phys_addr_t bar_end = pci_resource_end(dev, i); + unsigned long bar_length = bar_end - bar_start + 1; + fpgapci->bar_length[i] = bar_length; - if (!bar_start || !bar_end) { - fpgapci->bar_length[i] = 0; - continue; - } + if (!bar_start || !bar_end) { + fpgapci->bar_length[i] = 0; + continue; + } - if (bar_length < 1) { - PRINT ( "BAR #%d length is less than 1 byte\n", i); - continue; - } + if (bar_length < 1) { + PRINT ( "BAR #%d length is less than 1 byte\n", i); + continue; + } - PRINT ( "bar_start=%llx, bar_end=%llx, bar_length=%lx, flag=%lx\n", bar_start, - bar_end, bar_length, pci_resource_flags(dev, i)); + PRINT ( "bar_start=%llx, bar_end=%llx, bar_length=%lx, flag=%lx\n", bar_start, + bar_end, bar_length, pci_resource_flags(dev, i)); - /* map the device memory or IO region into kernel virtual - * address space */ - fpgapci->bar[i] = ioremap_nocache (bar_start + FPGALOGIC_I2C_BASE, I2C_PCI_MAX_BUS * FPGALOGIC_CH_OFFSET); + /* map the device memory or IO region into kernel virtual + * address space */ + fpgapci->bar[i] = ioremap_nocache (bar_start + FPGALOGIC_I2C_BASE, I2C_PCI_MAX_BUS * FPGALOGIC_CH_OFFSET); - if (!fpgapci->bar[i]) { - PRINT ( "Could not map BAR #%d.\n", i); - return -1; - } + if (!fpgapci->bar[i]) { + PRINT ( "Could not map BAR #%d.\n", i); + return -1; + } - PRINT ( "BAR[%d] mapped at 0x%p with length %lu.", i, - fpgapci->bar[i], bar_length); + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.", i, + fpgapci->bar[i], bar_length); - if(i == 0) //FPGA register is in the BAR[0] - { + if(i == 0) //FPGA register is in the BAR[0] + { fpga_phys_addr = bar_start; fpga_ctl_addr = ioremap_nocache (bar_start, FPGA_CTL_REG_SIZE); fpga_base_addr = fpgapci->bar[i]; - } + } - PRINT ( "BAR[%d] mapped at 0x%p with length %lu.\n", i, - fpgapci->bar[i], bar_length); - } - return 0; + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.\n", i, + fpgapci->bar[i], bar_length); + } + return 0; } static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) { - int i; + int i; - for (i = 0; i < PCI_NUM_BARS; i++) { - if (fpgapci->bar[i]) { - pci_iounmap(dev, fpgapci->bar[i]); - fpgapci->bar[i] = NULL; - } - } + for (i = 0; i < PCI_NUM_BARS; i++) { + if (fpgapci->bar[i]) { + pci_iounmap(dev, fpgapci->bar[i]); + fpgapci->bar[i] = NULL; + } + } } #define FPGA_PCI_NAME "FPGA_PCI" @@ -1089,206 +1092,206 @@ static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) * */ static int register_intr_handler(struct pci_dev *dev, int irq_num_id) { - int err = 0; - struct fpgapci_dev *fpgapci = 0; + int err = 0; + struct fpgapci_dev *fpgapci = 0; - fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); - if (fpgapci == 0) { - PRINT ( ": fpgapci_dev is 0\n"); - return err; - } + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return err; + } if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { - /* Request interrupt line for unique function - * alternatively function will be called from free_irq as well + /* Request interrupt line for unique function + * alternatively function will be called from free_irq as well * with flag IRQF_SHARED */ - switch(irq_num_id) { - /* Currently we only support test vector 2 for FPGA Logic I2C channel - * controller 1-7 interrupt*/ - case FPGA_MSI_VECTOR_ID_4: - err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_5: - err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_8: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[0]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_9: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[1]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_10: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[2]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_11: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[3]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_12: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[4]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_13: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[5]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_14: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[6]); - fpgapci->irq_assigned++; - break; - - default: - PRINT("No more interrupt handler for number (%d)\n", - dev->irq + irq_num_id); - break; - } + switch(irq_num_id) { + /* Currently we only support test vector 2 for FPGA Logic I2C channel + * controller 1-7 interrupt*/ + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_14: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; + } } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { - /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ switch (irq_num_id) { - case FPGA_MSI_VECTOR_ID_4: - err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_5: - err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_8: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[0]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_9: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[1]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_10: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[2]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_11: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[3]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_12: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[4]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_13: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[5]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_14: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[6]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_15: - /*it is an external interrupt number. Ignore this case */ - break; - case FPGA_MSI_VECTOR_ID_16: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_7) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[7]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_17: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[8]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_18: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[9]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_19: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[10]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_20: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[11]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_21: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[12]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_22: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[13]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_23: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[14]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_24: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[15]); - fpgapci->irq_assigned++; - } - break; - - default: - PRINT("No more interrupt handler for number (%d)\n", - dev->irq + irq_num_id); - break; + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_14: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_15: + /*it is an external interrupt number. Ignore this case */ + break; + case FPGA_MSI_VECTOR_ID_16: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_7) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[7]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_17: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[8]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_18: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[9]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_19: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[10]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_20: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[11]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_21: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[12]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_22: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[13]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_23: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[14]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_24: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[15]); + fpgapci->irq_assigned++; + } + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; } } - return err; + return err; } /* Mask for MSI Multi message enable bits */ #define MSI_MME 0x70 @@ -1348,33 +1351,33 @@ enum fpga_irq_type { #define CAP_REG 0x34 static void msi_set_enable(struct pci_dev *dev, int enable) { - int pos,maxvec; - u16 control; - int request_private_bits = 4; + int pos,maxvec; + u16 control; + int request_private_bits = 4; - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (pos) { - pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); - maxvec = 1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1); - PRINT("control = 0x%x maxvec = 0x%x\n", control, maxvec); - control &= ~PCI_MSI_FLAGS_ENABLE; + if (pos) { + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); + maxvec = 1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1); + PRINT("control = 0x%x maxvec = 0x%x\n", control, maxvec); + control &= ~PCI_MSI_FLAGS_ENABLE; - /* - * The PCI 2.3 spec mandates that there are at most 32 - * interrupts. If this device asks for more, only give it one. - */ - if (request_private_bits > 5) { - request_private_bits = 0; - } + /* + * The PCI 2.3 spec mandates that there are at most 32 + * interrupts. If this device asks for more, only give it one. + */ + if (request_private_bits > 5) { + request_private_bits = 0; + } - /* Update the number of IRQs the device has available to it */ - control &= ~PCI_MSI_FLAGS_QSIZE; - control |= (request_private_bits << 4); + /* Update the number of IRQs the device has available to it */ + control &= ~PCI_MSI_FLAGS_QSIZE; + control |= (request_private_bits << 4); - pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); - } + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); + } } /** * @brief Enables pcie-device and claims/remaps neccessary bar resources @@ -1383,211 +1386,212 @@ static void msi_set_enable(struct pci_dev *dev, int enable) * */ static int fpgapci_setup_device(struct fpgapci_dev *fpgapci,struct pci_dev *dev) { - int err = 0; + int err = 0; - /* wake up the pci device */ - err = pci_enable_device(dev); - if(err) { - PRINT("failed to enable pci device %d\n", err); - goto error_pci_en; - } + /* wake up the pci device */ + err = pci_enable_device(dev); + if(err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_en; + } - /* on platforms with buggy ACPI, pdev->msi_enabled may be set to - * allow pci_enable_device to work. This indicates INTx was not routed - * and only MSI should be used - */ + /* on platforms with buggy ACPI, pdev->msi_enabled may be set to + * allow pci_enable_device to work. This indicates INTx was not routed + * and only MSI should be used + */ - pci_set_master(dev); + pci_set_master(dev); - /* Setup the BAR memory regions */ - err = pci_request_regions(dev, DRIVER_NAME); - if (err) { - PRINT("failed to enable pci device %d\n", err); - goto error_pci_req; - } + /* Setup the BAR memory regions */ + err = pci_request_regions(dev, DRIVER_NAME); + if (err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_req; + } - scan_bars(fpgapci, dev); + scan_bars(fpgapci, dev); - if (map_bars(fpgapci, dev)) { - goto fail_map_bars; - } + if (map_bars(fpgapci, dev)) { + goto fail_map_bars; + } i2c_pci_init(); - return 0; - /* ERROR HANDLING */ + return 0; + /* ERROR HANDLING */ fail_map_bars: - pci_release_regions(dev); + pci_release_regions(dev); error_pci_req: - pci_disable_device(dev); + pci_disable_device(dev); error_pci_en: - return -ENODEV; + return -ENODEV; } static int fpgapci_configure_msi(struct fpgapci_dev *fpgapci,struct pci_dev *dev) { - int err = 0, i; - int request_vec; + int err = 0, i; + int request_vec; - msi_set_enable(dev,1); - PRINT("Check MSI capability after msi_set_enable\n"); + msi_set_enable(dev,1); + PRINT("Check MSI capability after msi_set_enable\n"); - /*Above 4.1.12*/ - request_vec = total_i2c_pci_bus; - err = pci_alloc_irq_vectors(dev, request_vec, pci_msi_vec_count(dev), - PCI_IRQ_MSI);//PCI_IRQ_AFFINITY | PCI_IRQ_MSI); + /*Above 4.1.12*/ + request_vec = total_i2c_pci_bus; + err = pci_alloc_irq_vectors(dev, request_vec, pci_msi_vec_count(dev), + PCI_IRQ_MSI);//PCI_IRQ_AFFINITY | PCI_IRQ_MSI); - if (err <= 0) { - PRINT("Cannot set MSI vector (%d)\n", err); - goto error_no_msi; - } else { - PRINT("Got %d MSI vectors starting at %d\n", err, dev->irq); + if (err <= 0) { + PRINT("Cannot set MSI vector (%d)\n", err); + goto error_no_msi; + } else { + PRINT("Got %d MSI vectors starting at %d\n", err, dev->irq); if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { if (err < MSI_VECTOR_REV_00) { goto error_disable_msi; } } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { if (err < MSI_VECTOR_REV_01) { goto error_disable_msi; } } - } - fpgapci->irq_first = dev->irq; - fpgapci->irq_length = err; - fpgapci->irq_assigned = 0; + } + fpgapci->irq_first = dev->irq; + fpgapci->irq_length = err; + fpgapci->irq_assigned = 0; - for(i = 0; i < fpgapci->irq_length; i++) { - err = register_intr_handler(dev, i); - if (err) { - PRINT("Cannot request Interrupt number %d\n", i); - goto error_pci_req_irq; - } - } + for(i = 0; i < fpgapci->irq_length; i++) { + err = register_intr_handler(dev, i); + if (err) { + PRINT("Cannot request Interrupt number %d\n", i); + goto error_pci_req_irq; + } + } - return 0; + return 0; error_pci_req_irq: - for(i = 0; i < fpgapci->irq_assigned; i++) - { - PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); if (i < 7) free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); else free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); - } + } error_disable_msi: - pci_disable_msi(fpgapci->pci_dev); + pci_disable_msi(fpgapci->pci_dev); error_no_msi: - return -ENOSPC; + return -ENOSPC; } static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) { - struct fpgapci_dev *fpgapci = 0; - int status = 0; + struct fpgapci_dev *fpgapci = 0; + int status = 0; #ifdef TEST - PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", - dev->vendor, dev->device, dev->class, - dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", + dev->vendor, dev->device, dev->class, + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); #endif - fpgapci = kzalloc(sizeof(struct fpgapci_dev), GFP_KERNEL); + fpgapci = kzalloc(sizeof(struct fpgapci_dev), GFP_KERNEL); - if (!fpgapci) { - PRINT( "Couldn't allocate memory!\n"); - goto fail_kzalloc; - } + if (!fpgapci) { + PRINT( "Couldn't allocate memory!\n"); + goto fail_kzalloc; + } - fpgapci->pci_dev = dev; - dev_set_drvdata(&dev->dev, (void*)fpgapci); + fpgapci->pci_dev = dev; + dev_set_drvdata(&dev->dev, (void*)fpgapci); - fpgapci->upstream = find_upstream_dev (dev); - status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); - if (status) { - printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); - } + status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); + if (status) { + printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); + } - if(fpgapci_setup_device(fpgapci,dev)) { - goto error_no_device; - } + fpgapci->upstream = find_upstream_dev (dev); - if (use_irq) { - if(fpgapci_configure_msi(fpgapci,dev)) { - goto error_cannot_configure; - } - } + if(fpgapci_setup_device(fpgapci,dev)) { + goto error_no_device; + } + if (use_irq) { + if(fpgapci_configure_msi(fpgapci,dev)) { + goto error_cannot_configure; + } + } - return 0; - /* ERROR HANDLING */ + + return 0; + /* ERROR HANDLING */ error_cannot_configure: - printk("error_cannot_configure\n"); - free_bars (fpgapci, dev); - pci_release_regions(dev); - pci_disable_device(dev); + printk("error_cannot_configure\n"); + free_bars (fpgapci, dev); + pci_release_regions(dev); + pci_disable_device(dev); error_no_device: - i2c_pci_deinit(); - printk("error_no_device\n"); + i2c_pci_deinit(); + printk("error_no_device\n"); fail_kzalloc: - return -1; + return -1; } static void fpgapci_remove(struct pci_dev *dev) { - struct fpgapci_dev *fpgapci = 0; - int i; - PRINT (": dev is %p\n", dev); - - if (dev == 0) { - PRINT ( ": dev is 0\n"); - return; - } - - fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); - if (fpgapci == 0) { - PRINT ( ": fpgapci_dev is 0\n"); - return; - } - i2c_pci_deinit(); - // - if (use_irq) - { - for(i = 0; i < fpgapci->irq_assigned; i++) - { - PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + struct fpgapci_dev *fpgapci = 0; + int i; + PRINT (": dev is %p\n", dev); + + if (dev == 0) { + PRINT ( ": dev is 0\n"); + return; + } + + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return; + } + i2c_pci_deinit(); + // + if (use_irq) + { + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); if (i < 7) - free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); + free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); else free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); - } - } - pci_disable_msi(fpgapci->pci_dev); - free_bars (fpgapci, dev); - pci_disable_device(dev); - pci_release_regions(dev); + } + } + pci_disable_msi(fpgapci->pci_dev); + free_bars (fpgapci, dev); + pci_disable_device(dev); + pci_release_regions(dev); - kfree (fpgapci); + kfree (fpgapci); } static const struct pci_device_id fpgapci_ids[] = { - {PCI_DEVICE(PCI_VENDOR_ID_XILINX, DEVICE)}, - {0, }, + {PCI_DEVICE(PCI_VENDOR_ID_XILINX, DEVICE)}, + {0, }, }; MODULE_DEVICE_TABLE(pci, fpgapci_ids); static struct pci_driver fpgapci_driver = { - .name = DRIVER_NAME, - .id_table = fpgapci_ids, - .probe = fpgapci_probe, - .remove = fpgapci_remove, - /* resume, suspend are optional */ + .name = DRIVER_NAME, + .id_table = fpgapci_ids, + .probe = fpgapci_probe, + .remove = fpgapci_remove, + /* resume, suspend are optional */ }; /* Initialize the driver module (but not any device) and register @@ -1595,21 +1599,21 @@ static struct pci_driver fpgapci_driver = { static int __init fpgapci_init(void) { - if (pci_register_driver(&fpgapci_driver)) { - PRINT("pci_unregister_driver\n"); - pci_unregister_driver(&fpgapci_driver); - return -ENODEV; - } + if (pci_register_driver(&fpgapci_driver)) { + PRINT("pci_unregister_driver\n"); + pci_unregister_driver(&fpgapci_driver); + return -ENODEV; + } - return 0; + return 0; } static void __exit fpgapci_exit(void) { - PRINT ("fpgapci_exit"); + PRINT ("fpgapci_exit"); - /* unregister this driver from the PCI bus driver */ - pci_unregister_driver(&fpgapci_driver); + /* unregister this driver from the PCI bus driver */ + pci_unregister_driver(&fpgapci_driver); } @@ -1620,3 +1624,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("joyce_yu@dell.com"); MODULE_DESCRIPTION ("Driver for FPGA Logic I2C bus"); MODULE_SUPPORTED_DEVICE ("FPGA Logic I2C bus"); + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py index 3091d1c9ed44..039a34e5b69b 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py @@ -22,11 +22,15 @@ IPMI_SENSOR_DATA = "ipmitool sdr list" IPMI_SENSOR_DUMP = "/tmp/sdr" -FAN_PRESENCE = "FAN{0}_prsnt" PSU_PRESENCE = "PSU{0}_stat" # Use this for older firmware # PSU_PRESENCE="PSU{0}_prsnt" +IPMI_FAN_PRESENCE = "ipmitool sensor get FAN{0}_prsnt" +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" +IPMI_RAW_STORAGE_READ = "ipmitool raw 0x0a 0x11 {0} 0 0 0xa0" +IPMI_FRU = "ipmitool fru" ipmi_sdr_list = "" # Dump sensor registers @@ -40,9 +44,18 @@ def ipmi_sensor_dump(): status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) if status: - logging.error('Failed to execute:' + ipmi_sdr_list) + logging.error('Failed to execute: ' + ipmi_sdr_list) sys.exit(0) +# Fetch a Fan Status + +def get_fan_status(fan_id): + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_FAN_PRESENCE.format(fan_id)) + if ret_status: + logging.error('Failed to execute : %s'%IPMI_FAN_PRESENCE.format(fan_id)) + sys.exit(0) + return(' ' + ipmi_cmd_ret.splitlines()[5].strip(' ').strip('[]')) + # Fetch a BMC register @@ -62,6 +75,35 @@ def get_pmc_register(reg_name): logging.basicConfig(level=logging.DEBUG) return output +#Fetch FRU Data for given fruid +def get_psu_airflow(psu_id): + fru_id = 'PSU' + str(psu_id) + '_fru' + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_FRU) + if ret_status: + logging.error('Failed to execute ipmitool: '+ IPMI_FRU) + sys.exit(0) + found_fru = False + for line in ipmi_cmd_ret.splitlines(): + if line.startswith('FRU Device Description') and fru_id in line.split(':')[1] : + found_fru = True + if found_fru and line.startswith(' Board Product '): + return ' B2F' if 'PS/IO' in line else ' F2B' + return '' + +# Fetch FRU on given offset +def fetch_raw_fru(dev_id, offset): + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_RAW_STORAGE_READ.format(dev_id)) + if ret_status: + logging.error('Failed to execute ipmitool :' + IPMI_RAW_STORAGE_READ.format(dev_id)) + sys.exit(0) + return int((ipmi_cmd_ret.splitlines()[offset/16]).split(' ')[(offset%16+1)]) + + + + +def get_fan_airflow(fan_id): + Airflow_Direction = [' F2B', ' B2F'] + return Airflow_Direction[fetch_raw_fru(fan_id+2, 0x46)] # Print the information for temperature sensors @@ -93,7 +135,6 @@ def print_temperature_sensors(): def print_fan_tray(tray): Fan_Status = [' Normal', ' Abnormal'] - Airflow_Direction = ['B2F', 'F2B'] print ' Fan Tray ' + str(tray) + ':' @@ -152,16 +193,62 @@ def print_fan_tray(tray): Fan_Status[fan1_status] print ' Fan2 State: ',\ Fan_Status[fan2_status] + print ' Airflow: ',\ + get_fan_airflow(tray) print('\nFan Trays:') for tray in range(1, S5232F_MAX_FAN_TRAYS + 1): - fan_presence = FAN_PRESENCE.format(tray) - if (get_pmc_register(fan_presence)): + if (get_fan_status(tray) == ' Present'): print_fan_tray(tray) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print ' Fan Tray {}: NOT PRESENT'.format(str(tray)) + + def get_psu_presence(index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + ret_status = 1 + + if index == 1: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + + if ret_status: + logging.error('Failed to execute ipmitool :' + IPMI_PSU1_DATA_DOCKER) + sys.exit(0) + + psu_status = ipmi_cmd_ret + return (int(psu_status, 16) & 1) + + def get_psu_status(index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + ret_status = 1 + ipmi_cmd_ret = 'f' + + if index == 1: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + + if ret_status: + logging.error('Failed to execute ipmitool : ' + IPMI_PSU2_DATA_DOCKER) + sys.exit(0) + + psu_status = ipmi_cmd_ret + + return (not int(psu_status, 16) > 1) # Print the information for PSU1, PSU2 @@ -175,7 +262,6 @@ def print_psu(psu): PSU_FAN_AIR_FLOW_BIT = 0 Psu_Fan_Presence = ['Present', 'Absent'] Psu_Fan_Status = ['Normal', 'Abnormal'] - Psu_Fan_Airflow = ['B2F', 'F2B'] # print ' Input: ', Psu_Input_Type[psu_input_type] # print ' Type: ', Psu_Type[psu_type] @@ -233,15 +319,19 @@ def print_psu(psu): get_pmc_register('PSU2_In_amp') print ' Output Current: ',\ get_pmc_register('PSU2_Out_amp') + print ' Airflow: ',\ + get_psu_airflow(psu) print('\nPSUs:') for psu in range(1, S5232F_MAX_PSUS + 1): - psu_presence = PSU_PRESENCE.format(psu) - if (get_pmc_register(psu_presence)): - print_psu(psu) + #psu_presence = PSU_PRESENCE.format(psu) + if not get_psu_presence(psu): + print ' PSU{}: NOT PRESENT'.format(psu) + elif not get_psu_status(psu) : + print ' PSU{}: NOT OK'.format(psu) else: - print '\n PSU ', psu, 'Not present' + print_psu(psu) print '\n Total Power: ',\ get_pmc_register('PSU_Total_watt') diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh index a419b7d22e5f..6f5119044039 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh @@ -113,6 +113,48 @@ switch_board_led_default() { resource="/sys/bus/pci/devices/0000:04:00.0/resource0" python /usr/bin/pcisysfs.py --set --offset 0x24 --val 0x194 --res $resource > /dev/null 2>&1 } + +# Readout firmware version of the system and +# store in /var/log/firmware_versions +platform_firmware_versions() { + FIRMWARE_VERSION_FILE=/var/log/firmware_versions + rm -rf ${FIRMWARE_VERSION_FILE} + echo "BIOS: `dmidecode -s system-version `" > $FIRMWARE_VERSION_FILE + ## Get FPGA version + r=`/usr/bin/pcisysfs.py --get --offset 0x00 --res /sys/bus/pci/devices/0000\:04\:00.0/resource0 | sed '1d; s/.*\(....\)$/\1/; s/\(..\{1\}\)/\1./'` + r_min=$(echo $r | sed 's/.*\(..\)$/0x\1/') + r_maj=$(echo $r | sed 's/^\(..\).*/0x\1/') + echo "FPGA: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + ## Get BMC Firmware Revision + r=`cat /sys/class/ipmi/ipmi0/device/bmc/firmware_revision` + echo "BMC: $r" >> $FIRMWARE_VERSION_FILE + + #System CPLD 0x31 on i2c bus 601 ( physical FPGA I2C-2) + r_min=`/usr/sbin/i2cget -y 601 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 601 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "System CPLD: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 1 0x30 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x30 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x30 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 1: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 2 0x31 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 2: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x32 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x32 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 3: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x33 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x33 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE +} init_devnum if [ "$1" == "init" ]; then @@ -129,10 +171,12 @@ if [ "$1" == "init" ]; then switch_board_modsel switch_board_led_default python /usr/bin/qsfp_irq_enable.py + platform_firmware_versions elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" switch_board_qsfp "delete_device" + switch_board_sfp "delete_device" switch_board_qsfp_mux "delete_device" switch_board_sfp "delete_device" modprobe -r i2c-mux-pca954x From 768d18d45b6c8e85506bcb6497dd759f60471de9 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Wed, 8 Apr 2020 14:24:08 -0700 Subject: [PATCH 0504/1427] Pass image_type to build_debian.sh, so it can do any required customizations. (#4401) --- slave.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/slave.mk b/slave.mk index b1ecc09541ed..3a3fd2421d3f 100644 --- a/slave.mk +++ b/slave.mk @@ -845,6 +845,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ DEBUG_SRC_ARCHIVE_FILE="$(DBG_SRC_ARCHIVE_FILE)" \ USERNAME="$(USERNAME)" \ PASSWORD="$(PASSWORD)" \ + IMAGE_TYPE=$($*_IMAGE_TYPE) \ ./build_debian.sh $(LOG) USERNAME="$(USERNAME)" \ From 36752b8775e6a2e6990d21368f251cf0092c7038 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Thu, 9 Apr 2020 08:49:45 +0300 Subject: [PATCH 0505/1427] [BFN] Update Barefoot SDK packages (#4397) Signed-off-by: Andriy Kokhan --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 622563e09853..1abbedffd6c6 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20200205_deb9.deb +BFN_PLATFORM = bfnplatform_20200407_deb9.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 2f2429845f5d..b58cce6fcf47 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20200205_deb9.deb +BFN_SAI = bfnsdk_20200407_deb9.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) From 9068652cfd2c3731a740ab6904518ddd4e6f7fd6 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 8 Apr 2020 23:01:27 -0700 Subject: [PATCH 0506/1427] [Juniper QFX5210] Fix Python errors (#4394) * [Juniper QFX5210] Fix Python errors * Remove unnecessary 'pass' --- .../qfx5210/utils/juniper_qfx5210_monitor.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py index 97adf9588f9f..dbf0b831248f 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py @@ -587,7 +587,7 @@ def __init__(self, log_file, log_level): masterLED_file = open(MASTER_LED_PATH, 'r+') except IOError as e: logging.error('device_monitor: unable to open Master LED file: %s', str(e)) - return False + return masterLED_file.write(str(master_led_value)) masterLED_file.close() @@ -596,10 +596,9 @@ def __init__(self, log_file, log_level): systemLED_file = open(SYSTEM_LED_PATH, 'r+') except IOError as e: logging.error('device_monitor: unable to open System LED file: %s', str(e)) - return False + return systemLED_file.write(str(system_led_value)) systemLED_file.close() - pass def manage_device(self): thermal = QFX5210_ThermalUtil() From b3558aeea5c85f8cd8a75e1dfc65bf2a01a00700 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 8 Apr 2020 23:03:22 -0700 Subject: [PATCH 0507/1427] [device/accton] Fix Python error for wedge100bf_32x (#4392) Remove undefined export, "constants" --- .../plugins/pltfm_mgr_rpc/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py index 09cb959f2d46..414c3d6389c5 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py @@ -1 +1 @@ -__all__ = ['ttypes', 'constants', 'pltfm_mgr_rpc'] +__all__ = ['ttypes', 'pltfm_mgr_rpc'] From 21aff7fdeb34c9ab5892b4dd7f0e0d89ffc34555 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 8 Apr 2020 23:03:47 -0700 Subject: [PATCH 0508/1427] [device/accton] Fix Python error for as7116-54x (#4391) Fix syntax error --- device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py index 07e0649579ac..be1dbb52a79b 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py @@ -1111,7 +1111,7 @@ def get_presence(self): presence = int(sfp_presence.read(), 16) except IOError: return False - logger.log_info("debug:port_ %s sfp presence is %s" % (str(self.index)), % (str(presence)) + logger.log_info("debug:port_ %s sfp presence is %s" % (str(self.index), str(presence))) return presence def get_model(self): From 7405f8cfea9eae265eb1e92086f31c5a897b78b7 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 8 Apr 2020 23:04:13 -0700 Subject: [PATCH 0509/1427] [Accton AS4630-54PE] Fix Python indentation error (#4393) Fix Python indentation error Add newline at EOF --- .../as4630-54pe/classes/fanutil.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py index 5bcd600d1cb8..d046834ecf33 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py @@ -83,7 +83,7 @@ def _get_fan_node_val(self, fan_num, node_num): device_path = self.get_fan_device_path(fan_num, node_num) try: - val_file = open(device_path, 'r') + val_file = open(device_path, 'r') except IOError as e: logging.error('GET. unable to open file: %s', str(e)) return None @@ -200,4 +200,4 @@ def main(): logging.debug('fan-%d status=%d', i, fan.get_fan_status(i)) if __name__ == '__main__': - main() \ No newline at end of file + main() From a2cc6b65949465f3ea43b7c54d96b1f0d6867efc Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Thu, 9 Apr 2020 21:18:14 -0700 Subject: [PATCH 0510/1427] Update dockers with platform & SONiC version as part of name/tag. (#4337) * Include platform info in name. Get SONiC Version as parameter and use Make additional tag as optional. Avoid repetitions by using function. * Per review comments, make SONIC_VERSION optional and added some comments. * 1) Added additional params are optional 2) Handle DOCKER_IMAGE_TAG only if given 3) Use BUILD_NUMBER only if SONIC_VERSION not given 4) Tag with SONIC_VERSION if given. Current behavior is not changed, unless SONIC_VERSION is given. * Update per review comments 1) Added new args with options 2) Handle PORT possible being empty 3) Exhibit new behavior only if both version & platform are given. * Drop redundant quotes --- push_docker.sh | 91 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/push_docker.sh b/push_docker.sh index 3ba9abfae5bf..3e2da08d0b83 100755 --- a/push_docker.sh +++ b/push_docker.sh @@ -1,42 +1,79 @@ +#! /bin/bash + +sonic_version="" +sonic_platform="" + +while getopts ":v:p:" opt +do + case ${opt} in + v ) # SONiC image version + sonic_version=${OPTARG} + ;; + p ) # Platform info + sonic_platform=${OPTARG} + ;; + \? ) echo "\ +Usage: [-v ] [ -p ] \ + []" + ;; + esac +done + +shift $((OPTIND -1)) + DOCKER_IMAGE_FILE=$1 REGISTRY_SERVER=$2 REGISTRY_PORT=$3 REGISTRY_USERNAME=$4 REGISTRY_PASSWD=$5 DOCKER_IMAGE_TAG=$6 +REGISTRY_SERVER_WITH_PORT=${REGISTRY_SERVER}${REGISTRY_PORT:+:$REGISTRY_PORT} -set -e -docker load < $DOCKER_IMAGE_FILE +push_it() { + # $1 - Given image name + # $2 - Remote image name -## Fetch the Jenkins build number if inside it -[ ${BUILD_NUMBER} ] || { - echo "No BUILD_NUMBER found, setting to 0." - BUILD_NUMBER="0" + docker tag $1 $2 + echo "Pushing $2" + image_sha=$(docker push $2 | sed -n "s/.*: digest: sha256:\([0-9a-f]*\).*/\\1/p") + echo "Remove $2" + docker rmi $2 || true + echo "Image sha256: $image_sha" } -## Prepare tag -docker_image_name=$(basename $DOCKER_IMAGE_FILE | cut -d. -f1) -remote_image_name=$REGISTRY_SERVER:$REGISTRY_PORT/$docker_image_name:$DOCKER_IMAGE_TAG -timestamp="$(date -u +%Y%m%d)" -build_version="${timestamp}.bld-${BUILD_NUMBER}" -build_remote_image_name=$REGISTRY_SERVER:$REGISTRY_PORT/$docker_image_name:$build_version +set -e -## Add registry information as tag, so will push as latest -## Add additional tag with build information -docker tag $docker_image_name $remote_image_name -docker tag $docker_image_name $build_remote_image_name +echo "Loading image ${DOCKER_IMAGE_FILE}" +docker load < ${DOCKER_IMAGE_FILE} ## Login the docker image registry server ## Note: user name and password are passed from command line -docker login -u $REGISTRY_USERNAME -p "$REGISTRY_PASSWD" $REGISTRY_SERVER:$REGISTRY_PORT - -## Push image to registry server -## And get the image digest SHA256 -echo "Pushing $remote_image_name" -image_sha=$(docker push $remote_image_name | sed -n "s/.*: digest: sha256:\([0-9a-f]*\).*/\\1/p") -docker rmi $remote_image_name || true -echo "Image sha256: $image_sha" -echo "Pushing $build_remote_image_name" -docker push $build_remote_image_name -docker rmi $build_remote_image_name || true +docker login -u ${REGISTRY_USERNAME} -p "${REGISTRY_PASSWD}" ${REGISTRY_SERVER_WITH_PORT} + +## Get Docker image name +docker_image_name=$(basename ${DOCKER_IMAGE_FILE} | cut -d. -f1) +remote_image_name=${REGISTRY_SERVER_WITH_PORT}/${docker_image_name} + +[ -z "${DOCKER_IMAGE_TAG}" ] || { + push_it ${docker_image_name} ${remote_image_name}:${DOCKER_IMAGE_TAG} +} + +if [ -n "${sonic_version}" ] && [ -n "${sonic_platform}" ] +then + remote_image_name=${REGISTRY_SERVER_WITH_PORT}/sonic-dockers/${sonic_platform}/${docker_image_name}:${sonic_version} + push_it ${docker_image_name} ${remote_image_name} +else + ## Fetch the Jenkins build number if inside it + [ ${BUILD_NUMBER} ] || { + echo "No BUILD_NUMBER found, setting to 0." + BUILD_NUMBER="0" + } + + timestamp="$(date -u +%Y%m%d)" + build_version="${timestamp}.bld-${BUILD_NUMBER}" + push_it ${docker_image_name} ${remote_image_name}:${build_version} +fi + docker rmi $docker_image_name || true +echo "Job completed" + From 606db589b8865d6ad1ab4f6ccc1626137a3fad7e Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Fri, 10 Apr 2020 12:25:52 -0400 Subject: [PATCH 0511/1427] [brcm-th-svk]: Fix errors in BCM956960K switch (#4390) Fix Broadcom TH SVK boot up crash --- .../broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile | 2 +- .../{config_th_32x100.bcm => th_32x100.config.bcm} | 0 device/broadcom/x86_64-bcm_xlr-r0/plugins/eeprom.py | 10 +++++++--- .../utils/brcm-xlr-gts-create-eeprom-file.py | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) rename device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/{config_th_32x100.bcm => th_32x100.config.bcm} (100%) diff --git a/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile b/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile index 80aa570ddfb3..e80e0d4c89b0 100644 --- a/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile +++ b/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/config_th_32x100.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th_32x100.config.bcm diff --git a/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/config_th_32x100.bcm b/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/th_32x100.config.bcm similarity index 100% rename from device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/config_th_32x100.bcm rename to device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/th_32x100.config.bcm diff --git a/device/broadcom/x86_64-bcm_xlr-r0/plugins/eeprom.py b/device/broadcom/x86_64-bcm_xlr-r0/plugins/eeprom.py index ce122d6fface..25ea4849f7d5 100644 --- a/device/broadcom/x86_64-bcm_xlr-r0/plugins/eeprom.py +++ b/device/broadcom/x86_64-bcm_xlr-r0/plugins/eeprom.py @@ -8,10 +8,12 @@ # - the eeprom format definition # - specific encoder/decoder if there is special need # -# Note: the file /etc/sys_eeprom.bin is generated by the script -# brcm-xlr-gts-create-eeprom-file.py +# Note: the file /usr/share/sonic/platform/sys_eeprom.bin is generated +# by the script brcm-xlr-gts-create-eeprom-file.py ############################################################################# +import os + try: from sonic_eeprom import eeprom_tlvinfo except ImportError, e: @@ -21,7 +23,9 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): - self.eeprom_path = "/etc/sys_eeprom.bin" + self.eeprom_path = "/usr/share/sonic/platform/sys_eeprom.bin" + if os.path.isfile(self.eeprom_path) is False: + self.eeprom_path = "/usr/share/sonic/device/x86_64-bcm_xlr-r0/sys_eeprom.bin" super(board, self).__init__(self.eeprom_path, 0, '', False, True) def serial_number_str(self, e): diff --git a/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/utils/brcm-xlr-gts-create-eeprom-file.py b/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/utils/brcm-xlr-gts-create-eeprom-file.py index 71a99471a99f..d8e7ec0ee138 100755 --- a/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/utils/brcm-xlr-gts-create-eeprom-file.py +++ b/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/utils/brcm-xlr-gts-create-eeprom-file.py @@ -93,13 +93,13 @@ def main(): tlvinfo_header.totallen = len(tlvinfo_data.dump())+4; try: - f = open('/etc/sys_eeprom.bin', 'w+') + f = open('/usr/share/sonic/device/x86_64-bcm_xlr-r0/sys_eeprom.bin', 'w+') f.write(tlvinfo_header.dump()) f.write(tlvinfo_data.dump()) f.write(crc(tlvinfo_header.dump(), tlvinfo_data.dump())) f.close() except: - print('Unable to write file /etc/sys_eeprom.bin') + print('Unable to write file /usr/share/sonic/device/x86_64-bcm_xlr-r0/sys_eeprom.bin') if __name__== "__main__": main() From 195a0a7bf77529c3560cb7070155751a1b4529b0 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 11 Apr 2020 20:43:50 -0700 Subject: [PATCH 0512/1427] [libnss]: fix compiling issue under gcc 8 (#4414) Signed-off-by: Guohan Lu --- ...ling-warning-about-token-dereference.patch | 34 +++++++++++++++++++ src/tacacs/nss/Makefile | 1 + 2 files changed, 35 insertions(+) create mode 100644 src/tacacs/nss/0006-fix-compiling-warning-about-token-dereference.patch diff --git a/src/tacacs/nss/0006-fix-compiling-warning-about-token-dereference.patch b/src/tacacs/nss/0006-fix-compiling-warning-about-token-dereference.patch new file mode 100644 index 000000000000..37d9c37acebc --- /dev/null +++ b/src/tacacs/nss/0006-fix-compiling-warning-about-token-dereference.patch @@ -0,0 +1,34 @@ +From d8300dca720dc17e19d39efa3abbe3c3e5600262 Mon Sep 17 00:00:00 2001 +From: Guohan Lu +Date: Wed, 5 Feb 2020 07:25:13 +0000 +Subject: [PATCH] fix compiling warning about token dereference + +--- + nss_tacplus.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/nss_tacplus.c b/nss_tacplus.c +index 3ff3c35..7feeda6 100644 +--- a/nss_tacplus.c ++++ b/nss_tacplus.c +@@ -87,7 +87,7 @@ static int parse_tac_server(char *srv_buf) + + token = strsep(&srv_buf, delim); + while(token) { +- if('\0' != token) { ++ if('\0' != token[0]) { + if(!strncmp(token, "server=", 7)) { + struct addrinfo hints, *server; + int rv; +@@ -161,7 +161,7 @@ static int parse_user_priv(char *buf) + + token = strsep(&buf, delim); + while(token) { +- if('\0' != token) { ++ if('\0' != token[0]) { + if(!strncmp(token, "user_priv=", 10)) { + priv = (int)strtoul(token + 10, NULL, 0); + if(priv > MAX_TACACS_USER_PRIV || priv < MIN_TACACS_USER_PRIV) +-- +2.17.1 + diff --git a/src/tacacs/nss/Makefile b/src/tacacs/nss/Makefile index a0c42bd2f222..cb9382d07a89 100644 --- a/src/tacacs/nss/Makefile +++ b/src/tacacs/nss/Makefile @@ -23,6 +23,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git $(GIT_APPLY) ../0003-management-vrf-support.patch git $(GIT_APPLY) ../0004-Skip-accessing-tacacs-servers-for-local-non-tacacs-u.patch git $(GIT_APPLY) ../0005-libnss-Modify-parsing-of-IP-addr-and-port-number-str.patch + git $(GIT_APPLY) ../0006-fix-compiling-warning-about-token-dereference.patch dpkg-buildpackage -rfakeroot -b -us -uc popd From e6463352bdab44b88c37bbc3c03eebc20b32527c Mon Sep 17 00:00:00 2001 From: lguohan Date: Sun, 12 Apr 2020 02:30:04 -0700 Subject: [PATCH 0513/1427] [lldpd]: download lldp package from azure storage url (#4415) Signed-off-by: Guohan Lu --- src/lldpd/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lldpd/Makefile b/src/lldpd/Makefile index 285d7fec9911..fa997e3486c8 100644 --- a/src/lldpd/Makefile +++ b/src/lldpd/Makefile @@ -5,7 +5,7 @@ SHELL = /bin/bash MAIN_TARGET = $(LLDPD) DERIVED_TARGETS = $(LIBLLDPCTL) $(LLDPD_DBG) -LLDP_URL = http://ftp.debian.org/debian/pool/main/l/lldpd +LLDP_URL = https://sonicstorage.blob.core.windows.net/debian/pool/main/l/lldpd DSC_FILE = lldpd_$(LLDPD_VERSION_FULL).dsc ORIG_FILE = lldpd_$(LLDPD_VERSION).orig.tar.gz From 4f8f1d45e4bd7167ed16a20fd1508e6ffe3d36ac Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Sun, 12 Apr 2020 13:35:28 -0700 Subject: [PATCH 0514/1427] [docker-sonic-mgmt] Merge spytest dependencies into mgmt docker (#4411) Signed-off-by: Danny Allen --- .../docker-sonic-mgmt-spytest/Dockerfile.j2 | 29 ------------------- dockers/docker-sonic-mgmt/Dockerfile.j2 | 25 ++++++++++++++-- rules/docker-sonic-mgmt-spytest.mk | 6 ---- 3 files changed, 23 insertions(+), 37 deletions(-) delete mode 100644 dockers/docker-sonic-mgmt-spytest/Dockerfile.j2 delete mode 100644 rules/docker-sonic-mgmt-spytest.mk diff --git a/dockers/docker-sonic-mgmt-spytest/Dockerfile.j2 b/dockers/docker-sonic-mgmt-spytest/Dockerfile.j2 deleted file mode 100644 index 4f6b0d8fffac..000000000000 --- a/dockers/docker-sonic-mgmt-spytest/Dockerfile.j2 +++ /dev/null @@ -1,29 +0,0 @@ -FROM docker-sonic-mgmt:latest - -ENV CC=gcc CPP=cpp CXX=c++ LDSHARED="gcc -pthread -shared" PYMSSQL_BUILD_WITH_BUNDLED_FREETDS=1 - -RUN sudo -H pip install \ - "cryptography>=2.5" \ - "future>=0.16.0" \ - gitpython \ - jinja2 \ - jsonpatch \ - "netmiko==2.4.2" \ - prettytable \ - psutil \ - pycryptodome \ - pyfiglet \ - "pylint==1.8.1" \ - pyro4 \ - pytest-repeat \ - "pytest-xdist==1.28.0" \ - "pytest==4.6.5" \ - redis \ - requests \ - rpyc \ - tabulate \ - textfsm - -RUN sudo apt-get update && sudo apt-get install -y \ - inetutils-ping \ - telnet diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index c19cea4b9727..2b3c860461e4 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -24,8 +24,9 @@ RUN apt-get install -y \ cmake \ tcpdump \ snmp \ - python-dev \ - python-scapy + python-scapy \ + inetutils-ping \ + telnet # For JNLP launcher RUN apt-get install -y default-jre @@ -54,6 +55,25 @@ RUN pip install ipaddr \ passlib \ ipython==5.4.1 \ virtualenv \ + "cryptography>=2.5" \ + "future>=0.16.0" \ + gitpython \ + jsonpatch \ + netmiko==2.4.2 \ + prettytable \ + psutil \ + pycryptodome \ + pyfiglet \ + pylint==1.8.1 \ + pyro4 \ + pytest-repeat \ + pytest-xdist==1.28.0 \ + pytest==4.6.5 \ + redis \ + requests \ + rpyc \ + tabulate \ + textfsm \ && git clone https://github.com/p4lang/scapy-vxlan.git \ && cd scapy-vxlan \ && python setup.py install \ @@ -121,6 +141,7 @@ ARG hostname ENV BUILD_HOSTNAME $hostname ENV USER $user +ENV CC=gcc CPP=cpp CXX=c++ LDSHARED="gcc -pthread -shared" PYMSSQL_BUILD_WITH_BUNDLED_FREETDS=1 RUN groupadd -f -r -g $guid g$user diff --git a/rules/docker-sonic-mgmt-spytest.mk b/rules/docker-sonic-mgmt-spytest.mk deleted file mode 100644 index c3906263eff3..000000000000 --- a/rules/docker-sonic-mgmt-spytest.mk +++ /dev/null @@ -1,6 +0,0 @@ -# SPYTest Management Docker - -DOCKER_MGMT_SPYTEST = docker-sonic-mgmt-spytest.gz -$(DOCKER_MGMT_SPYTEST)_PATH = $(DOCKERS_PATH)/docker-sonic-mgmt-spytest -$(DOCKER_MGMT_SPYTEST)_LOAD_DOCKERS += $(DOCKER_SONIC_MGMT) -SONIC_DOCKER_IMAGES += $(DOCKER_MGMT_SPYTEST) From 24231babcab4032c28387af1bcff329c110a71b2 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sun, 12 Apr 2020 20:44:16 -0700 Subject: [PATCH 0515/1427] [submodule]: update sonic-sairedis (#4416) * f972073 2020-04-12 | [vs]: set mtu only on the physical port (#601) (HEAD, origin/master, origin/HEAD) [lguohan] * e566f7a 2020-04-10 | [saiplayer] Convert saiplayer to static library (#600) [Kamil Cudnik] * fc3a413 2020-04-09 | [syncd] Convert syncd_request_shutdown to static library (#599) [Kamil Cudnik] * 027de8f 2020-04-09 | Do not translateVidToRid for processBulkQuadEvent in InitViewMode (#598) [Qi Luo] * b0ee63d 2020-04-08 | [syncd] [vs] [sairedis] Add support for bulk api in init view (#591) [Kamil Cudnik] * 48ef314 2020-04-08 | [sairedis] Add pragma once to lib header (#597) [Kamil Cudnik] * 74af900 2020-04-08 | [build]: allow to use extra inc/lib location to build the package (#595) [lguohan] * 9b8c63e 2020-04-07 | Update README.txt: add LGTM badges (#596) [Qi Luo] * fdd79e6 2020-04-07 | [tests] Update lib order (#594) [Kamil Cudnik] * d89eb59 2020-04-07 | [syncd] Change order of libs in Makefile.am (#593) [Kamil Cudnik] Signed-off-by: Guohan Lu --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index f4d9398c87ae..f972073fae66 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit f4d9398c87aee4fa66a0391b0d83f91595bc4480 +Subproject commit f972073fae66a56e32bfe0a30dac81ceae4c5d75 From 1b8897eec06586831aecffeee61b24dbe2738c74 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Mon, 13 Apr 2020 18:13:19 +0300 Subject: [PATCH 0516/1427] [mellanox]: Add SSD FW update tool (#4351) * [mellanox]: Add SSD FW update tool. Signed-off-by: Nazarii Hnydyn * [mellanox]: Align Platform API. Signed-off-by: Nazarii Hnydyn * [mellanox]: Fix firmware description. Signed-off-by: Nazarii Hnydyn * [mellanox]: Update SSD tool. Signed-off-by: Nazarii Hnydyn --- .../build_templates/sonic_debian_extension.j2 | 3 +- platform/mellanox/fw.mk | 6 +- platform/mellanox/issu-version.mk | 3 +- platform/mellanox/mlnx-ffb.mk | 2 + platform/mellanox/mlnx-onie-fw-update.mk | 9 + ...{onie-fw-update => mlnx-onie-fw-update.sh} | 0 .../sonic_platform/component.py | 8 +- platform/mellanox/mlnx-ssd-fw-update.mk | 9 + platform/mellanox/mlnx-ssd-fw-update.sh | 727 ++++++++++++++++++ platform/mellanox/one-image.mk | 2 +- platform/mellanox/onie-fw-update.mk | 7 - platform/mellanox/rules.mk | 3 +- 12 files changed, 761 insertions(+), 18 deletions(-) create mode 100644 platform/mellanox/mlnx-onie-fw-update.mk rename platform/mellanox/{onie-fw-update => mlnx-onie-fw-update.sh} (100%) create mode 100644 platform/mellanox/mlnx-ssd-fw-update.mk create mode 100755 platform/mellanox/mlnx-ssd-fw-update.sh delete mode 100644 platform/mellanox/onie-fw-update.mk diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index dad1cb9b8906..fb016d885eb4 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -469,7 +469,8 @@ sudo cp $files_path/$MLNX_SPC2_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC2.mfa sudo cp $files_path/$MLNX_SPC3_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC3.mfa sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh -sudo cp $files_path/$ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/onie-fw-update.sh +sudo cp $files_path/$MLNX_ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_ONIE_FW_UPDATE +sudo cp $files_path/$MLNX_SSD_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_SSD_FW_UPDATE j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index dc8243be1e83..3aa1df94a1cd 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -1,4 +1,4 @@ -# mellanox firmware +# mellanox asic firmware MLNX_FW_BASE_PATH = $(MLNX_SDK_BASE_PATH) @@ -34,6 +34,8 @@ else SONIC_ONLINE_FILES += $(MLNX_FW_FILES) endif +MLNX_FILES += $(MLNX_FW_FILES) + export MLNX_SPC_FW_VERSION export MLNX_SPC_FW_FILE @@ -42,5 +44,3 @@ export MLNX_SPC2_FW_FILE export MLNX_SPC3_FW_VERSION export MLNX_SPC3_FW_FILE - -export MLNX_FW_FILES diff --git a/platform/mellanox/issu-version.mk b/platform/mellanox/issu-version.mk index c7ae4296ab7a..db368ffd8c10 100644 --- a/platform/mellanox/issu-version.mk +++ b/platform/mellanox/issu-version.mk @@ -5,5 +5,6 @@ $(ISSU_VERSION_FILE)_SRC_PATH = $(PLATFORM_PATH)/issu-version $(ISSU_VERSION_FILE)_DEPENDS += $(APPLIBS) SONIC_MAKE_FILES += $(ISSU_VERSION_FILE) -export ISSU_VERSION_FILE +MLNX_FILES += $(ISSU_VERSION_FILE) +export ISSU_VERSION_FILE diff --git a/platform/mellanox/mlnx-ffb.mk b/platform/mellanox/mlnx-ffb.mk index dabb995a3658..82d50b7ae3e3 100755 --- a/platform/mellanox/mlnx-ffb.mk +++ b/platform/mellanox/mlnx-ffb.mk @@ -4,4 +4,6 @@ MLNX_FFB_SCRIPT = mlnx-ffb.sh $(MLNX_FFB_SCRIPT)_PATH = platform/mellanox/ SONIC_COPY_FILES += $(MLNX_FFB_SCRIPT) +MLNX_FILES += $(MLNX_FFB_SCRIPT) + export MLNX_FFB_SCRIPT diff --git a/platform/mellanox/mlnx-onie-fw-update.mk b/platform/mellanox/mlnx-onie-fw-update.mk new file mode 100644 index 000000000000..825c12c30ba4 --- /dev/null +++ b/platform/mellanox/mlnx-onie-fw-update.mk @@ -0,0 +1,9 @@ +# onie update tool + +MLNX_ONIE_FW_UPDATE = mlnx-onie-fw-update.sh +$(MLNX_ONIE_FW_UPDATE)_PATH = platform/mellanox/ +SONIC_COPY_FILES += $(MLNX_ONIE_FW_UPDATE) + +MLNX_FILES += $(MLNX_ONIE_FW_UPDATE) + +export MLNX_ONIE_FW_UPDATE diff --git a/platform/mellanox/onie-fw-update b/platform/mellanox/mlnx-onie-fw-update.sh similarity index 100% rename from platform/mellanox/onie-fw-update rename to platform/mellanox/mlnx-onie-fw-update.sh diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 70fd96023b8c..468420eaf0aa 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -114,10 +114,10 @@ class ComponentBIOS(Component): BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' BIOS_PENDING_UPDATE_PATTERN = '([0-9A-Za-z_]*.rom)[\s]*\|[\s]*bios_update' - ONIE_FW_UPDATE_CMD_ADD = '/usr/bin/onie-fw-update.sh add {}' - ONIE_FW_UPDATE_CMD_REMOVE = '/usr/bin/onie-fw-update.sh remove {}' - ONIE_FW_UPDATE_CMD_UPDATE = '/usr/bin/onie-fw-update.sh update' - ONIE_FW_UPDATE_CMD_SHOW = '/usr/bin/onie-fw-update.sh show-pending' + ONIE_FW_UPDATE_CMD_ADD = '/usr/bin/mlnx-onie-fw-update.sh add {}' + ONIE_FW_UPDATE_CMD_REMOVE = '/usr/bin/mlnx-onie-fw-update.sh remove {}' + ONIE_FW_UPDATE_CMD_UPDATE = '/usr/bin/mlnx-onie-fw-update.sh update' + ONIE_FW_UPDATE_CMD_SHOW = '/usr/bin/mlnx-onie-fw-update.sh show-pending' BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' diff --git a/platform/mellanox/mlnx-ssd-fw-update.mk b/platform/mellanox/mlnx-ssd-fw-update.mk new file mode 100644 index 000000000000..f932e57d2521 --- /dev/null +++ b/platform/mellanox/mlnx-ssd-fw-update.mk @@ -0,0 +1,9 @@ +# ssd update tool + +MLNX_SSD_FW_UPDATE = mlnx-ssd-fw-update.sh +$(MLNX_SSD_FW_UPDATE)_PATH = platform/mellanox/ +SONIC_COPY_FILES += $(MLNX_SSD_FW_UPDATE) + +MLNX_FILES += $(MLNX_SSD_FW_UPDATE) + +export MLNX_SSD_FW_UPDATE diff --git a/platform/mellanox/mlnx-ssd-fw-update.sh b/platform/mellanox/mlnx-ssd-fw-update.sh new file mode 100755 index 000000000000..5163c8e7f8f7 --- /dev/null +++ b/platform/mellanox/mlnx-ssd-fw-update.sh @@ -0,0 +1,727 @@ +#!/bin/bash +######################################################################## +# Copyright (c) 2020 Mellanox Technologies. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the names of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# Alternatively, this software may be distributed under the terms of the +# GNU General Public License ("GPL") version 2 as published by the Free +# Software Foundation. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +#==============================================================================# +#= Global variable # +#= +#===== +VERSION="1.3" +#===== +SWITCH_SSD_DEV="/dev/sda" +UTIL_TITLE="This is MLNX SSD firmware update utility to read and write SSD FW. Version ${VERSION}" +DEPENDECIES=("smartctl" "sha256sum" "tar" "/bin/bash" "gpg" "sed" "realpath" "dirname") +TRUE="0" +FALSE="1" +ERR_MSG="ERR_MSG" +INI_PREFIX="ini_section_" +PUBLIC_CERT_NAME="trusted.gpg" +CHECKSUM_NAME="checksum" +SCRIPT_MODE="RELESE" # RELESE -or- DEBUG +DEBUG_MSG="DEBUG" # remove all instance after script is ready. +#===== +PKG_EXTRACTED=$FALSE +LOGGER_UTIL=$FALSE +SSD_FW_VER="" +SSD_DEVICE_MODEL="" +SSD_SERIAL="" +SSD_SIZE="" +SECTIONS=() +#===== +ARG_IMAGE_FLAG=$FALSE +ARG_IMAGE_VAL="" +ARG_QUERY_FLAG=$FALSE +ARG_YES_FLAG=$FALSE +ARG_POWER_CYCLE_FLAG=$FALSE +ARG_HELP_FLAG=$FALSE +ARG_VERSION_FLAG=$FALSE +ARG_PACKAGE_INFO_FLAG=$FALSE +ARG_UPDATE_FLAG=$FALSE + + + +#==============================================================================# +#= usage function. # +#= +function init_script() { +# check if logger utility supported + if [ -x "$(command -v logger)" ]; then + LOGGER_UTIL=$TRUE + else + LOGGER_UTIL=$FALSE + fi +} + +#==============================================================================# +#= usage function. # +#= +function usage() { + echo + echo -e "$UTIL_TITLE" + echo + echo -e "Usage:" + echo -e "\tmlnx_ssd_fw_update.sh [OPTION]" + echo -e "Commands:" + echo -e "\t-i, --image\t\t Path to SSD FW package" + echo -e "\t-q, --query\t\t Print SSD information (SSD model, serial number, version and size)" + echo -e "\t\t\t\t Combined with image, comparison is made if update is required" + echo -e "\t-p, --package-info\t Get package info" + echo -e "\t-u, --update\t\t Upgrade firmware" + echo -e "\t-y --yes\t\t Assume \"yes\" to all questions" + echo -e "\t-V, --version\t\t Print utility version" + echo -e "\t-h, --help\t\t Show this usage" + echo -e "\t --power-cycle\t Execute power cycle at completion, even if not required" + echo + echo -e "Example:" + echo -e "\tmlnx_ssd_fw_update.sh -q" + echo -e "\tmlnx_ssd_fw_update.sh -q -i mlnx_ssd_fw_package.pkg" + echo -e "\tmlnx_ssd_fw_update.sh -p -i mlnx_ssd_fw_package.pkg" + echo -e "\tmlnx_ssd_fw_update.sh -u -i mlnx_ssd_fw_package.pkg" + echo +} + +#==============================================================================# +#= Log function. # +#= +function LOG_MSG() { + if [ $# -gt 0 ]; then + LOG_STR=$1 + if [[ $# -eq 1 ]]; then + [[ "$LOGGER_UTIL" == "$TRUE" && "$LOG_STR" != "" ]] && logger -t mlnx_ssd_fw_update.sh -p user.notice $(echo "$LOG_STR" | sed 's/\\t//g') + echo -e "$LOG_STR" + elif [[ $# -eq 2 && "$2" == "$ERR_MSG" ]]; then + [[ "$LOGGER_UTIL" == "$TRUE" && "$LOG_STR" != "" ]] && logger -t mlnx_ssd_fw_update.sh -p user.err $(echo "$LOG_STR" | sed 's/\\t//g') + echo -e "$LOG_STR" + elif [[ $# -eq 2 && "$2" == "$SCRIPT_MODE" ]]; then + echo -e "DBG: $LOG_STR" + fi + fi +} + +#==============================================================================# +#= Log function. # +#= +function LOG_MSG_AND_EXIT() { + LOG_MSG "$@" "$ERR_MSG" + erase_extract_package "$extraction_path" + LOG_MSG "Exiting..." + exit 1 +} + +#==============================================================================# +#= This function check if given argument is valid and return boolean result. # +#= +function check_usage() { + local argument_count=$# + + LOG_MSG "Number of argument:$argument_count" ${DEBUG_MSG} + + if [ $# -eq 0 ]; then + LOG_MSG "Error: false usage given." + usage + exit 1 + fi + + while [[ $# -gt 0 ]] + do + key="$1" + + case $key in + -i|--image) + ARG_IMAGE_FLAG=$TRUE + ARG_IMAGE_VAL="$2" + shift # past argument + shift # past value + ;; + -q|--query) + ARG_QUERY_FLAG=$TRUE + shift # past argument + ;; + -y|--yes) + ARG_YES_FLAG=$TRUE + shift # past argument + ;; + -h|--help) + ARG_HELP_FLAG=$TRUE + shift # past argument + ;; + -V|--version) + ARG_VERSION_FLAG=$TRUE + shift # past argument + ;; + -u|--update) + ARG_UPDATE_FLAG=$TRUE + shift # past argument + ;; + -p|--package-info) + ARG_PACKAGE_INFO_FLAG=$TRUE + shift # past argument + ;; + --power-cycle) + ARG_POWER_CYCLE_FLAG=$TRUE + shift # past argument + ;; + *) + LOG_MSG "Error: false usage given." + usage + exit 1 + ;; + esac + done + + if [[ ("$ARG_IMAGE_FLAG" == "$TRUE" && ( $argument_count -lt 3 )) || + ("$ARG_IMAGE_FLAG" == "$TRUE" && ( $argument_count -gt 5 )) || + ("$ARG_PACKAGE_INFO_FLAG" == "$TRUE" && ( $argument_count -ne 3 )) || + ("$ARG_QUERY_FLAG" == "$TRUE" && ( $argument_count -lt 1 )) || + ("$ARG_QUERY_FLAG" == "$TRUE" && ( $argument_count -gt 3 )) || + ("$ARG_HELP_FLAG" == "$TRUE" && ( $argument_count -gt 1 )) || + ("$ARG_VERSION_FLAG" == "$TRUE" && ( $argument_count -gt 1 )) || + ("$ARG_IMAGE_FLAG" == "$TRUE" && "$ARG_IMAGE_VAL" == "") || + ("$ARG_UPDATE_FLAG" == "$TRUE" && "$ARG_IMAGE_FLAG" == "$FALSE") || + ("$ARG_PACKAGE_INFO_FLAG" == "$TRUE" && "$ARG_IMAGE_FLAG" == "$FALSE") || + ("$ARG_POWER_CYCLE_FLAG" == "$TRUE" && "$ARG_UPDATE_FLAG" == "$FALSE") || + ("$ARG_UPDATE_FLAG" == "$TRUE" && "$ARG_PACKAGE_INFO_FLAG" == "$TRUE") ]]; then + + LOG_MSG "Error: false usage given." + usage + exit 1 + fi + +### Debug message remove when script is done. + LOG_MSG "ARG_IMAGE_FLAG = ${ARG_IMAGE_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_IMAGE_VAL = ${ARG_IMAGE_VAL}" ${DEBUG_MSG} + LOG_MSG "ARG_QUERY_FLAG = ${ARG_QUERY_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_YES_FLAG = ${ARG_YES_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_HELP_FLAG = ${ARG_HELP_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_VERSION_FLAG = ${ARG_VERSION_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_PACKAGE_INFO_FLAG = ${ARG_PACKAGE_INFO_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_POWER_CYCLE_FLAG = ${ARG_POWER_CYCLE_FLAG}" ${DEBUG_MSG} + +} + +#==============================================================================# +# This function return SSD fw version using hdparm utility # +# +function get_ssd_fw_version() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_fw_version + device_fw_version=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Firmware Version: +\K[^,]+") + LOG_MSG "device_fw_version: $device_fw_version" ${DEBUG_MSG} + eval $1='$device_fw_version' +} + +#==============================================================================# +# This function return SSD device model using hdparm utility # +# +function get_ssd_device_model() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_model_name + device_model_name=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Device Model: +\K[^,]+") + LOG_MSG "device_model_name: $device_model_name" ${DEBUG_MSG} + eval $1='$device_model_name' +} + +#==============================================================================# +# This function return SSD size using hdparm utility # +# +function get_ssd_size() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_size + device_size=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "User Capacity:.+bytes \[\K[^ ]+") + LOG_MSG "device_size: $device_size" ${DEBUG_MSG} + eval $1='$device_size' +} + +#==============================================================================# +# This function return SSD serial using hdparm utility # +# +function get_ssd_serial() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_serial + device_serial=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Serial Number: +\K[^,]+") + LOG_MSG "device_serial: $device_serial" ${DEBUG_MSG} + eval $1='$device_serial' +} + +#==============================================================================# +#= This function check if given argument is valid and return boolean result. # +#= +function get_ssd_info() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + get_ssd_fw_version SSD_FW_VER + get_ssd_device_model SSD_DEVICE_MODEL + get_ssd_serial SSD_SERIAL + get_ssd_size SSD_SIZE +} + +#==============================================================================# +#= This function check if given argument is valid and return boolean result. # +#= +function check_tool_dependencies() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + for i in "${!DEPENDECIES[@]}" + do + if [ ! -x "$(command -v ${DEPENDECIES[$i]})" ]; then + LOG_MSG_AND_EXIT "Error: This tool require the following utils to be installed ${DEPENDECIES[$i]}" + fi + done +} + +#==============================================================================# +#= This function parse package ini file and declare it attributes # +#= +function ini_parser { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local filename="$1" + LOG_MSG "filename:$filename" ${DEBUG_MSG} + + shopt -p extglob &> /dev/null + CHANGE_EXTGLOB=$? + if [ $CHANGE_EXTGLOB = 1 ] + then + shopt -s extglob + fi + ini="$(<$filename)" # read the file + ini=${ini//$'\r'/} # remove linefeed i.e dos2unix + ini="${ini//[/\\[}" + ini="${ini//]/\\]}" + IFS=$'\n' && ini=( ${ini} ) # convert to line-array + ini=( ${ini[*]//\)/\\\)} ) # append / before any parenthesis + ini=( ${ini[*]//\(/\\\(} ) # append / before any parenthesis + ini=( ${ini[*]/#*([[:space:]]);*/} ) + ini=( ${ini[*]/#*([[:space:]])\#*/} ) + ini=( ${ini[*]/#+([[:space:]])/} ) # remove init whitespace + ini=( ${ini[*]/%+([[:space:]])/} ) # remove ending whitespace + ini=( ${ini[*]/*([[:space:]])=*([[:space:]])/=} ) # remove whitespace around = + ini=( ${ini[*]/#\\[/\}$'\n'"$INI_PREFIX"} ) # set section prefix + ini=( ${ini[*]/%\\]/ \(} ) # convert text2function (1) + ini=( ${ini[*]/=/=\( } ) # convert item to array + ini=( ${ini[*]/%/ \)} ) # close array parenthesis + ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick + ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2) + ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis + ini=( ${ini[*]/%\{/\{$'\n''ini_unset ${FUNCNAME/#'$INI_PREFIX'}'$'\n'} ) # clean previous definition of section + ini[0]="" # remove first element + ini[${#ini[*]} + 1]='}' # add the last brace + eval "$(echo "${ini[*]}")" # eval the result + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: failed to parse package content." + SECTIONS="$(echo ${ini[*]} | grep -Po "$INI_PREFIX+\K[\w]+")" + if [ $CHANGE_EXTGLOB = 1 ] + then + shopt -u extglob + fi +} + +#==============================================================================# +#= This function unset parse ini section and variables # +#= +function ini_unset { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + SECTION=$1 + OLDIFS="$IFS" + IFS=' '$'\n' + if [ -z "$SECTION" ] + then + fun="$(declare -F)" + else + fun="$(declare -F $INI_PREFIX$SECTION)" + if [ -z "$fun" ] + then + echo "section $SECTION not found" 1>&2 + return + fi + fi + fun="${fun//declare -f/}" + for f in $fun; do + [ "${f#$INI_PREFIX}" == "${f}" ] && continue + item="$(declare -f ${f})" + item="${item##*\{}" # remove function definition + item="${item##*FUNCNAME*$INI_PREFIX\};}" # remove clear section + item="${item/\}}" # remove function close + item="${item%)*}" # remove everything after parenthesis + item="${item});" # add close parenthesis + vars="" + while [ "$item" != "" ] + do + newvar="${item%%=*}" # get item name + vars="$vars $newvar" # add name to collection + item="${item#*;}" # remove readed line + done + for var in $vars; do + unset $var + done + done + IFS="$OLDIFS" +} + +#==============================================================================# +#= This function check package signing and returns back true or false # +#= +function check_package_signing() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local package_path=$1 + local checksum_unsigned_file="$package_path/$CHECKSUM_NAME" + local checksum_signed_file="$package_path/$CHECKSUM_NAME.sig" + local public_cert_file="$package_path/$PUBLIC_CERT_NAME" + +### Check if unsigned checksum file exists + [ ! -f "$checksum_unsigned_file" ] && LOG_MSG_AND_EXIT "Error: fail to find unsigned checksum file to verify package signing." + +### Check if signed checksum file exists + [ ! -f "$checksum_signed_file" ] && LOG_MSG_AND_EXIT "Error: fail to find sign checksum file to verify package signing." + +### Check if public key exists + [ ! -f "$public_cert_file" ] && LOG_MSG_AND_EXIT "Error: fail to find public certificate to verify package signing." + + + LOG_MSG "public_cert_file: ${public_cert_file}" ${DEBUG_MSG} + LOG_MSG "checksum_signed_file: ${checksum_signed_file}" ${DEBUG_MSG} + LOG_MSG "checksum_unsigned_file: ${checksum_unsigned_file}" ${DEBUG_MSG} + + gpg --keyring "$public_cert_file" --verify "$checksum_signed_file" "$checksum_unsigned_file" > /dev/null 2>&1 + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: fault package signing." + + LOG_MSG "cd into: ${package_path}" ${DEBUG_MSG} + cd $package_path > /dev/null 2>&1 + sha256sum -c $CHECKSUM_NAME > /dev/null 2>&1 + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: fault package SHA signing, file has been compromised" + LOG_MSG "backing back:" ${DEBUG_MSG} + cd - > /dev/null 2>&1 + LOG_MSG "exiting:" ${DEBUG_MSG} + +} + +#==============================================================================# +#= This function prints supported SSD from package ini # +#= +function string_supported_model() { + + local section=$1 + + if [[ ! -z "${Vendor[*]}" ]] && [[ ! -z "${SSD_FW_Model[*]}" ]] && [[ ! -z "${SSD_FW_Version[*]}" ]] \ + && [[ ! -z "${SSD_Size[*]}" ]] && [[ ! -z ${Shutdown_Policy[*]} ]]; then + printf 'o %-10s | %-30s | %-12s | %-6sGB | %-7s |\n' \ + "$( IFS=$'\n'; echo "${Vendor[@]}" )" "$( IFS=$'\n'; echo "${SSD_FW_Model[@]}" )" \ + "${SSD_FW_Version[@]}" "${SSD_Size[@]}" "${Shutdown_Policy[@],,}" + fi + +} + +#==============================================================================# +#= This function extract SSD FW package into /tmp # +#= +function extract_package() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local filename=$1 + LOG_MSG "filename:$filename" ${DEBUG_MSG} +### Check if file exists + [ ! -f $filename ] && LOG_MSG_AND_EXIT "Error: given file ($filename) not found." +### Check if tmp available + [ ! -d "/tmp" ] && LOG_MSG_AND_EXIT "Error: directory /tmp DOES NOT exists." + + local base_filename="${filename##*/}" + local folder_name="/tmp/""${base_filename%%.*}" + +### Check if full path available + if [ -d $folder_name ]; then + LOG_MSG "Path:$folder_name already exists, removing folder." ${DEBUG_MSG} + rm -rf ${folder_name} + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: folder:$folder_name is already in use and can't be overwrite, please remove it and retry." + fi + + mkdir ${folder_name} && tar xf ${filename} -C ${folder_name} --strip-components 1 --warning=no-timestamp > /dev/null 2>&1 + #tar -xf $filename --directory /tmp/ --warning=no-timestamp > /dev/null 2>&1 +### Check if untar succeed. + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: fail to extract given package ($filename)." + +### return the path file extraction is + # local base_filename="${filename##*/}" + # local folder_name="/tmp/""${base_filename%%.*}" + eval $2="$folder_name" + + PKG_EXTRACTED=$TRUE + + check_package_signing $folder_name + + LOG_MSG "successfully untar file." ${DEBUG_MSG} +} + +#==============================================================================# +#= This function extract SSD FW package into /tmp # +#= +function erase_extract_package() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + [[ "$PKG_EXTRACTED" == "$FALSE" ]] && return + + local folder_name=$1 + + LOG_MSG "folder_name: $folder_name" ${DEBUG_MSG} + +### Check if folder exists + if [ ! -d "$folder_name" ]; then + LOG_MSG "Error: directory $folder_name DOES NOT exists." "$ERR_MSG" + LOG_MSG "Exiting..." + exit 1 + fi + rm -rf $folder_name +### Check if untar succeed. + if [ $? -ne 0 ]; then + LOG_MSG "Error: fail to delete $folder_name folder." "$ERR_MSG" + LOG_MSG "Exiting..." + exit 1 + fi + + PKG_EXTRACTED=$FALSE + LOG_MSG "successfully removed folder:$folder_name" ${DEBUG_MSG} +} + + +#==============================================================================# +#= This function returns back ini section array. +#= +function call_ini_section() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local ini_section=$1 + LOG_MSG "ini_section:$ini_section" ${DEBUG_MSG} + + [[ -z "$ini_section" ]] && LOG_MSG_AND_EXIT "Error: given INI section is null." + [[ -z "$(declare -F "$INI_PREFIX$ini_section")" ]] && LOG_MSG_AND_EXIT "Error: $ini_section section is missing in INI file." + + eval "$(echo "$INI_PREFIX$ini_section")" # call given section function. +} + +#==============================================================================# +#= This function prints ssd info +#= +function print_ssd_info() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local argument_count=$# + + if [ $argument_count -eq 2 ]; then + local newer_fw_version=$1 + local power_policy=$2 + LOG_MSG "Device Model\t\t : $SSD_DEVICE_MODEL" + LOG_MSG "Serial Number\t\t : $SSD_SERIAL" + LOG_MSG "User Capacity\t\t : $SSD_SIZE GB" + LOG_MSG "Current Firmware Version : $SSD_FW_VER" + LOG_MSG "Available Firmware Version : $Newer_FW_Version" + LOG_MSG "Power Cycle Required\t : $power_policy" + LOG_MSG "Upgrade Required\t : yes" + elif [ $argument_count -eq 1 ]; then + local _upgrade_require=$1 + LOG_MSG "Device Model\t : $SSD_DEVICE_MODEL" + LOG_MSG "Serial Number\t : $SSD_SERIAL" + LOG_MSG "User Capacity\t : $SSD_SIZE GB" + LOG_MSG "Firmware Version : $SSD_FW_VER" + LOG_MSG "Upgrade Required : $_upgrade_require" + else + LOG_MSG "Device Model\t : $SSD_DEVICE_MODEL" + LOG_MSG "Serial Number\t : $SSD_SERIAL" + LOG_MSG "User Capacity\t : $SSD_SIZE GB" + LOG_MSG "Firmware Version : $SSD_FW_VER" + fi +} + +# Main +# ------------------------------------------------------------------------------ +init_script +check_usage "$@" + +# show help +if [ $ARG_HELP_FLAG == $TRUE ]; then + usage + exit 0 +# show version +elif [ $ARG_VERSION_FLAG == $TRUE ]; then + echo $UTIL_TITLE + exit 0 +# show SSD info +elif [ $ARG_QUERY_FLAG == $TRUE ]; then + match_found=$FALSE + check_tool_dependencies + get_ssd_info + + if [ $ARG_IMAGE_FLAG == $TRUE ]; then + extract_package $ARG_IMAGE_VAL extraction_path + ini_parser "$extraction_path/list.ini" + + for section in $SECTIONS; do + if [[ $section != "main" ]]; then + call_ini_section $section + if [[ "$SSD_DEVICE_MODEL" == "$( IFS=$'\n'; echo "${SSD_FW_Model[@]}" )" ]] && \ + [[ "$SSD_FW_VER" == "${SSD_FW_Version[@]}" ]] && \ + [[ "$SSD_SIZE" == "${SSD_Size[@]}" ]]; then + + match_found=$TRUE + break + fi + ini_unset $section + fi + done + + erase_extract_package "$extraction_path" + if [[ "$match_found" == "$FALSE" ]]; then + #LOG_MSG "SSD FW upgrade not require, based on given package latest version is in used." + print_ssd_info "no" + echo -e "" + exit 0 + fi + fi + + if [[ "$match_found" == "$TRUE" ]]; then + print_ssd_info $Newer_FW_Version ${Shutdown_Policy[0],,} + erase_extract_package "$extraction_path" + else + print_ssd_info + fi + + echo -e "" + + exit 0 +# show package version +elif [ $ARG_PACKAGE_INFO_FLAG == $TRUE ]; then + check_tool_dependencies + extract_package $ARG_IMAGE_VAL extraction_path + # 2. check signing + ini_parser "$extraction_path/list.ini" + + call_ini_section "main" + LOG_MSG "Package Name: $ARG_IMAGE_VAL" + [[ ! -z ${description[@]} ]] && LOG_MSG "Description: ${description[@]}" + [[ ! -z ${version[@]} ]] && LOG_MSG "Version: ${version[@]}" + [[ ! -z ${release_date[@]} ]] && LOG_MSG "Release Date: ${release_date[@]}" + LOG_MSG "Supported SSDs:" + LOG_MSG " Vendor | Model | FW ver | Size | Pwr Cyc Req |" + LOG_MSG "=============|================================|==============|==========|=============|" + for section in $SECTIONS; do + if [[ "$section" != "main" ]]; then + call_ini_section $section + supported_model=$(string_supported_model $section) + LOG_MSG "$supported_model" + ini_unset $section + fi + done + echo -e "" + erase_extract_package "$extraction_path" + exit 0 +# operate SSD fw update +elif [ $ARG_UPDATE_FLAG == $TRUE ]; then + check_tool_dependencies + get_ssd_info + extract_package $ARG_IMAGE_VAL extraction_path + # 2. check signing + UPDATE_DONE=$FALSE + ini_parser "$extraction_path/list.ini" + for section in $SECTIONS; do + if [[ $section != "main" ]]; then + call_ini_section $section + if [[ "$SSD_DEVICE_MODEL" == "$( IFS=$'\n'; echo "${SSD_FW_Model[@]}" )" ]] && \ + [[ "$SSD_FW_VER" == "${SSD_FW_Version[@]}" ]] && \ + [[ "$SSD_SIZE" == "${SSD_Size[@]}" ]]; then + UPDATE_DONE=$TRUE + + power_policy=${Shutdown_Policy[0],,} + LOG_MSG "Power policy:$power_policy" ${DEBUG_MSG} + print_ssd_info $Newer_FW_Version ${Shutdown_Policy[0],,} + echo -e "" + #[[ "yes" == "$power_policy" ]] && LOG_MSG "PLEASE NOTE: System will power-cycle automatically once SSD FW Update complete!" + [[ "yes" == "$power_policy" || "$ARG_POWER_CYCLE_FLAG" == "$TRUE" ]] && LOG_MSG "Please note: Once SSD FW Update process ends, system will power-cycle automaticly and it will take up to 1 minute to access it back." + + # Prompt approval for FW update if ignore in case "yes" flag is on. + if [[ "$ARG_YES_FLAG" == "$FALSE" ]]; then + read -p "Do you want to continue? [Y/N]" -n 1 -r + echo # (optional) move to a new line + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + LOG_MSG_AND_EXIT "Aborting..." + exit 0 + fi + fi + + # Check FWUpgrade scripts exists & if so call it. + ssd_script_name=$Update_Script + ssd_script_path="${extraction_path}/${section}/${ssd_script_name}" + LOG_MSG "ssd_script_path: $ssd_script_path" ${DEBUG_MSG} + if [ ! -f $ssd_script_path ]; then + LOG_MSG_AND_EXIT "Error: fail to call upgrade script ($ssd_script_path)!" + fi + ( + cd "${extraction_path}/${section}" > /dev/null 2>&1 || exit + /bin/bash "$ssd_script_path" "${extraction_path}/${section}" + #cd - > /dev/null 2>&1 || exit + ) + if [ $? -ne 0 ]; then + LOG_MSG_AND_EXIT "Error: SSD FW update failed." + else + LOG_MSG "SSD FW update completed successfully." + + if [ $ARG_POWER_CYCLE_FLAG == $TRUE ]; then + LOG_MSG "Execute power cycle..." + sleep 1 + sync + power_cycle_script="${extraction_path}/common/mlnx_shutdown.sh" + [ ! -f $power_cycle_script ]&& LOG_MSG_AND_EXIT "Error: failed to initiate power cycle." + ($power_cycle_script "-s") + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: failed to power cycle the system automatically." + erase_extract_package "$extraction_path" + + fi + + fi + + break # Exit the for loop + fi + ini_unset $section + fi + done + if [ $UPDATE_DONE == $FALSE ]; then + LOG_MSG "SSD FW upgrade not require, based on given package latest version is in used." + print_ssd_info "no" + fi + + echo -e "" + erase_extract_package "$extraction_path" + exit 0 +fi + +exit 0 diff --git a/platform/mellanox/one-image.mk b/platform/mellanox/one-image.mk index e4723c3bd1b0..0f69b7335bf1 100644 --- a/platform/mellanox/one-image.mk +++ b/platform/mellanox/one-image.mk @@ -11,5 +11,5 @@ $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.g else $(SONIC_ONE_IMAGE)_DOCKERS = $(SONIC_INSTALL_DOCKER_IMAGES) endif -$(SONIC_ONE_IMAGE)_FILES += $(MLNX_FW_FILES) $(MLNX_FFB_SCRIPT) $(ISSU_VERSION_FILE) $(ONIE_FW_UPDATE) +$(SONIC_ONE_IMAGE)_FILES += $(MLNX_FILES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/mellanox/onie-fw-update.mk b/platform/mellanox/onie-fw-update.mk deleted file mode 100644 index 160f1c98f7b1..000000000000 --- a/platform/mellanox/onie-fw-update.mk +++ /dev/null @@ -1,7 +0,0 @@ -# bios update tool - -ONIE_FW_UPDATE= onie-fw-update -$(ONIE_FW_UPDATE)_PATH = platform/mellanox/ -SONIC_COPY_FILES += $(ONIE_FW_UPDATE) - -export ONIE_FW_UPDATE diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index efd0af2c8f4a..bdb4e955c2d4 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -12,7 +12,8 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-mlnx.mk include $(PLATFORM_PATH)/mlnx-ffb.mk include $(PLATFORM_PATH)/issu-version.mk -include $(PLATFORM_PATH)/onie-fw-update.mk +include $(PLATFORM_PATH)/mlnx-onie-fw-update.mk +include $(PLATFORM_PATH)/mlnx-ssd-fw-update.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) From f128153706fea8d9859e6e8be1873aa0f5a35755 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Mon, 13 Apr 2020 08:41:18 -0700 Subject: [PATCH 0517/1427] [baseimage]: Install Kubernetes packages if enabled in image (#4374) * Install kubernetes worker node packages, if enabled. * Minor updates * Added some comments * Updates per review comments. Built a private image to test to work fine. * Remove the removed file. * Update per comments Make a fix, as kubeadm no demands a higher version of kubelet & kubectl. As kubeadm auto install kubectl & kubelet, removing explicit install is an easier/robust fix. * Changes per review comments. * Updates per comments. 1) Dropped helper & pod scripts 2) Made install verbose * Drop creation of pods subdir, as this PR does not use them. * From comments to 'n' per review comments. * 1) kubeadm.conf is created as part of kubeadm package install. Hence dropped explicit copy. --- Makefile.work | 5 +++++ build_debian.sh | 16 ++++++++++++++++ .../build_templates/sonic_debian_extension.j2 | 19 +++++++++++++++++++ files/image_config/kubernetes/kubernetes.list | 4 ++++ rules/config | 14 ++++++++++++++ slave.mk | 2 ++ 6 files changed, 60 insertions(+) create mode 100644 files/image_config/kubernetes/kubernetes.list diff --git a/Makefile.work b/Makefile.work index 579d35a1ed60..5041c36f5ed9 100644 --- a/Makefile.work +++ b/Makefile.work @@ -9,6 +9,7 @@ # through http. # * ENABLE_ZTP: Enables zero touch provisioning. # * SHUTDOWN_BGP_ON_START: Sets admin-down state for all bgp peerings after restart. +# * INSTALL_KUBERNETES: Allows including Kubernetes # * ENABLE_PFCWD_ON_START: Enable PFC Watchdog (PFCWD) on server-facing ports # * by default for TOR switch. # * ENABLE_SYNCD_RPC: Enables rpc-based syncd builds. @@ -176,6 +177,10 @@ SONIC_BUILD_INSTRUCTION := make \ ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \ ENABLE_ZTP=$(ENABLE_ZTP) \ SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \ + INSTALL_KUBERNETES=$(INSTALL_KUBERNETES) \ + KUBERNETES_VERSION=$(KUBERNETES_VERSION) \ + K8s_GCR_IO_PAUSE_VERSION=$(K8s_GCR_IO_PAUSE_VERSION) \ + K8s_CNI_CALICO_VERSION=$(K8s_CNI_CALICO_VERSION) \ SONIC_ENABLE_PFCWD_ON_START=$(ENABLE_PFCWD_ON_START) \ SONIC_ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \ SONIC_INSTALL_DEBUG_TOOLS=$(INSTALL_DEBUG_TOOLS) \ diff --git a/build_debian.sh b/build_debian.sh index fd247bbdf6aa..e0d953b455b2 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -208,6 +208,22 @@ sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 +if [ "$INSTALL_KUBERNETES" == "y" ] +then + ## Install Kubernetes + echo '[INFO] Install kubernetes' + sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -fsSL \ + https://packages.cloud.google.com/apt/doc/apt-key.gpg | \ + sudo LANG=C chroot $FILESYSTEM_ROOT apt-key add - + ## Check out the sources list update matches current Debian version + sudo cp files/image_config/kubernetes/kubernetes.list $FILESYSTEM_ROOT/etc/apt/sources.list.d/ + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubeadm=${KUBERNETES_VERSION}-00 + # kubeadm package auto install kubelet & kubectl +else + echo '[INFO] Skipping Install kubernetes' +fi + ## Add docker config drop-in to specify dockerd command line sudo mkdir -p $FILESYSTEM_ROOT/etc/systemd/system/docker.service.d/ ## Note: $_ means last argument of last command diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index fb016d885eb4..49acd0647ad1 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -245,6 +245,13 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-s sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures +{% if install_kubernetes == "y" %} +# Copy kubelet service files +# Keep it disabled until join, else it continuously restart and as well spew too many +# non-required log lines wasting syslog resources. +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable kubelet.service +{% endif %} + # Copy the buffer configuration template sudo cp $BUILD_TEMPLATES/buffers_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ @@ -401,6 +408,18 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS tag {{imagename}}:latest {{imagebasename}}:latest {% endif %} {% endfor %} + +{% if install_kubernetes == "y" %} +## Pull in kubernetes docker images +echo "pulling universal k8s images ..." +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull k8s.gcr.io/pause:${K8s_GCR_IO_PAUSE_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull k8s.gcr.io/kube-proxy:v${KUBERNETES_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/node:v${K8s_CNI_CALICO_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/pod2daemon-flexvol:v${K8s_CNI_CALICO_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/cni:v${K8s_CNI_CALICO_VERSION} +echo "docker images pull complete" +{% endif %} + sudo umount $FILESYSTEM_ROOT/target sudo rm -r $FILESYSTEM_ROOT/target if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then diff --git a/files/image_config/kubernetes/kubernetes.list b/files/image_config/kubernetes/kubernetes.list new file mode 100644 index 000000000000..5c888b830623 --- /dev/null +++ b/files/image_config/kubernetes/kubernetes.list @@ -0,0 +1,4 @@ +# The following is as recommended by https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ +# Whenever an OS update from Debian stretch is done, make sure to find the matching k8s sources list +# +deb https://apt.kubernetes.io/ kubernetes-xenial main diff --git a/rules/config b/rules/config index e9eb460c4dc1..2e49e4349a00 100644 --- a/rules/config +++ b/rules/config @@ -131,3 +131,17 @@ ENABLE_RESTAPI = n # ENABLE_NAT - build docker-sonic-nat for nat support ENABLE_NAT = y +# INSTALL_KUBERNETES - if set to y kubernetes packages are installed to be able to +# run as worker node in kubernetes cluster. +INSTALL_KUBERNETES = n + +# KUBERNETES_VERSION - Set to the required version. +# K8s_GCR_IO_PAUSE_VERSION - Version of k8s universal pause container image +# K8s_CNI_CALICO_VERSION - Calico used as CNI; Appropriate version for this Kubernetes version +# These are Used *only* when INSTALL_KUBERNETES=y +# NOTE: As a worker node it has to run version compatible to kubernetes master. +# +KUBERNETES_VERSION = 1.18.0 +K8s_GCR_IO_PAUSE_VERSION = 3.2 +K8s_CNI_CALICO_VERSION = 3.12.0 + diff --git a/slave.mk b/slave.mk index 3a3fd2421d3f..01bb5df7de84 100644 --- a/slave.mk +++ b/slave.mk @@ -191,6 +191,7 @@ $(info "USERNAME" : "$(USERNAME)") $(info "PASSWORD" : "$(PASSWORD)") $(info "ENABLE_DHCP_GRAPH_SERVICE" : "$(ENABLE_DHCP_GRAPH_SERVICE)") $(info "SHUTDOWN_BGP_ON_START" : "$(SHUTDOWN_BGP_ON_START)") +$(info "INSTALL_KUBERNETES" : "$(INSTALL_KUBERNETES)") $(info "ENABLE_PFCWD_ON_START" : "$(ENABLE_PFCWD_ON_START)") $(info "INSTALL_DEBUG_TOOLS" : "$(INSTALL_DEBUG_TOOLS)") $(info "ROUTING_STACK" : "$(SONIC_ROUTING_STACK)") @@ -769,6 +770,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_ztp="$(ENABLE_ZTP)" export enable_nat="$(ENABLE_NAT)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" + export install_kubernetes="$(INSTALL_KUBERNETES)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" export installer_debs="$(addprefix $(STRETCH_DEBS_PATH)/,$($*_INSTALLS))" export lazy_installer_debs="$(foreach deb, $($*_LAZY_INSTALLS),$(foreach device, $($(deb)_PLATFORM),$(addprefix $(device)@, $(STRETCH_DEBS_PATH)/$(deb))))" From 48acdf882e23d7d578f8e5d32d7172912478ce7e Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Mon, 13 Apr 2020 19:45:56 +0300 Subject: [PATCH 0518/1427] update SAI 1.16.2 SDK 4.4.0800 FW *.2007.0872 (#4417) --- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 3aa1df94a1cd..faa3b3f239b6 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2007.0322 +MLNX_SPC_FW_VERSION = 13.2007.0872 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2007.0322 +MLNX_SPC2_FW_VERSION = 29.2007.0872 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2007.0322 +MLNX_SPC3_FW_VERSION = 30.2007.0872 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 4f9e3b292465..275445bd80e0 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.1-master +MLNX_SAI_VERSION = SAIRel1.16.2-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index ef47a5592190..5eb3e143e3da 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit ef47a5592190c08d2f127d3fe8fa5a77ee4087ba +Subproject commit 5eb3e143e3da934b30fd9b66126a6ab626f1b15e diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 07425a0957d1..1d7da850581f 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 07425a0957d100405e3781f8bb633c462f37a92c +Subproject commit 1d7da850581ff0dd79990ae1c5bcb174d4272267 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index f2af75cccf2b..3b2e9a8f30c8 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.4.0542 +MLNX_SDK_VERSION = 4.4.0880 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 2beca91c99262ecd50bcf9e7b06c958d1bad9a26 Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 13 Apr 2020 10:35:25 -0700 Subject: [PATCH 0519/1427] [Build]: add build target to build sonic-slave-base (#4373) This is to build sonic-slave-base target for user to download Signed-off-by: Guohan Lu --- Makefile.work | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile.work b/Makefile.work index 5041c36f5ed9..e36166472422 100644 --- a/Makefile.work +++ b/Makefile.work @@ -214,7 +214,7 @@ ifneq ($(BLDENV), ) endif endif @$(OVERLAY_MODULE_CHECK) - + @docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null || \ { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \ $(DOCKER_BASE_BUILD) ; } @@ -231,6 +231,9 @@ else @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) $(SONIC_BUILD_INSTRUCTION) $@ endif +sonic-slave-base-build : + $(DOCKER_BASE_BUILD) + sonic-slave-build : $(DOCKER_BASE_BUILD) $(DOCKER_BUILD) From 2872d802314f3908ce55ea54ce728e12c7fee677 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Mon, 13 Apr 2020 16:56:19 -0700 Subject: [PATCH 0520/1427] [docker-ptf] Add support for spytest to ptf container (#4410) - Install apt and pip dependencies - Define traffic generator service Signed-off-by: Danny Allen --- dockers/docker-ptf/Dockerfile.j2 | 16 ++++++++++------ dockers/docker-ptf/conf.d/ptf_tgen.conf | 10 ++++++++++ dockers/docker-ptf/ptf_tgen.sh | 1 + 3 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 dockers/docker-ptf/conf.d/ptf_tgen.conf create mode 100755 dockers/docker-ptf/ptf_tgen.sh diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index 8d529779ccdb..c9f7be803a20 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -22,6 +22,7 @@ debs/ ENV DEBIAN_FRONTEND=noninteractive ## Set the apt source, update package cache and install necessary packages +## TODO: Clean up this step RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' /etc/apt/sources.list \ && apt-get update \ && apt-get upgrade -y \ @@ -39,7 +40,6 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / unzip \ pkg-config \ binutils \ - net-tools \ build-essential \ libssl-dev \ libffi-dev \ @@ -53,7 +53,6 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / iputils-ping \ hping3 \ curl \ - tcpdump \ tmux \ python \ python-dev \ @@ -64,7 +63,9 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / rsyslog \ ntp \ ntpstat \ - ntpdate + ntpdate \ + arping \ + bridge-utils RUN dpkg -i \ {% for deb in docker_ptf_debs.split(' ') -%} @@ -72,6 +73,7 @@ debs/{{ deb }}{{' '}} {%- endfor %} # Install all python modules from pypi. python-scapy is exception, ptf debian package requires python-scapy +# TODO: Clean up this step RUN rm -rf /debs \ && apt-get -y autoclean \ && apt-get -y autoremove \ @@ -115,6 +117,7 @@ RUN rm -rf /debs \ && pip install flask \ && pip install exabgp==3.4.17\ && pip install pyaml \ + && pip install pybrctl pyro4 rpyc yabgp \ && mkdir -p /opt \ && cd /opt \ && wget https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py @@ -126,8 +129,9 @@ RUN mkdir /var/run/sshd \ && sed -ri '/^#?UsePAM/c\UsePAM no' /etc/ssh/sshd_config \ && sed -ri '/^#?UseDNS/c\UseDNS no' /etc/ssh/sshd_config -COPY ["supervisord.conf", "/etc/supervisor/"] -COPY ["conf.d/supervisord.conf", "conf.d/sshd.conf", "conf.d/ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] +COPY supervisord.conf /etc/supervisor/ +COPY conf.d/ /etc/supervisor/conf.d/ +COPY ptf_tgen.sh /ptf_tgen/ # Move tcpdump into /usr/bin Otherwise it's impossible to run tcpdump due to a docker bug RUN mv /usr/sbin/tcpdump /usr/bin/tcpdump @@ -135,6 +139,6 @@ RUN ln -s /usr/bin/tcpdump /usr/sbin/tcpdump RUN mkdir -p /var/log/supervisor -EXPOSE 22 +EXPOSE 22 8009 ENTRYPOINT ["/usr/local/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] diff --git a/dockers/docker-ptf/conf.d/ptf_tgen.conf b/dockers/docker-ptf/conf.d/ptf_tgen.conf new file mode 100644 index 000000000000..8efd3f1c15f7 --- /dev/null +++ b/dockers/docker-ptf/conf.d/ptf_tgen.conf @@ -0,0 +1,10 @@ +[program:ptf_tgen] +command=/ptf_tgen/ptf_tgen.sh +process_name=ptf_tgen +stdout_logfile=/tmp/ptf_tgen.out.log +stderr_logfile=/tmp/ptf_tgen.err.log +redirect_stderr=false +autostart=false +autorestart=true +startsecs=1 +numprocs=1 diff --git a/dockers/docker-ptf/ptf_tgen.sh b/dockers/docker-ptf/ptf_tgen.sh new file mode 100755 index 000000000000..03593276bdd9 --- /dev/null +++ b/dockers/docker-ptf/ptf_tgen.sh @@ -0,0 +1 @@ +# PLACEHOLDER - This file is intended to be overwritten by SPYTest. From 530c9fc427ff286ba7077a13138ce230861dbc3e Mon Sep 17 00:00:00 2001 From: Myron Sosyak <49795530+msosyak@users.noreply.github.com> Date: Tue, 14 Apr 2020 19:43:35 +0300 Subject: [PATCH 0521/1427] Update Barefoot kdrv (#4355) --- .../barefoot/bfn-modules/modules/bf_ioctl.h | 67 +- .../barefoot/bfn-modules/modules/bf_kdrv.c | 1186 +++++++++-------- .../barefoot/bfn-modules/modules/bf_kdrv.h | 146 ++ 3 files changed, 832 insertions(+), 567 deletions(-) create mode 100644 platform/barefoot/bfn-modules/modules/bf_kdrv.h diff --git a/platform/barefoot/bfn-modules/modules/bf_ioctl.h b/platform/barefoot/bfn-modules/modules/bf_ioctl.h index e14716f50fa3..0644feb7c8c1 100644 --- a/platform/barefoot/bfn-modules/modules/bf_ioctl.h +++ b/platform/barefoot/bfn-modules/modules/bf_ioctl.h @@ -1,25 +1,28 @@ /******************************************************************************* - * BAREFOOT NETWORKS CONFIDENTIAL & PROPRIETARY - * - * Copyright (c) 2018-2018 Barefoot Networks, Inc. - * - * NOTICE: All information contained herein is, and remains the property of - * Barefoot Networks, Inc. and its suppliers, if any. The intellectual and - * technical concepts contained herein are proprietary to Barefoot Networks, - * Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, patents in - * process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material is - * strictly forbidden unless prior written permission is obtained from - * Barefoot Networks, Inc. - * - * No warranty, explicit or implicit is provided, unless granted under a - * written agreement with Barefoot Networks, Inc. - * - * $Id: $ - * - ******************************************************************************/ + Barefoot Networks Switch ASIC Linux driver + Copyright(c) 2015 - 2019 Barefoot Networks, Inc. + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ #ifndef _BF_IOCTL_H_ #define _BF_IOCTL_H_ @@ -35,15 +38,35 @@ typedef uint64_t phys_addr_t; #endif /* __KERNEL__ */ #define BF_IOC_MAGIC 'b' +#define BF_TBUS_MSIX_INDICES_MAX 3 -typedef struct bf_dma_bus_map_s +typedef struct bf_dma_bus_map_s { phys_addr_t phy_addr; void *dma_addr; size_t size; } bf_dma_bus_map_t; +typedef struct bf_tbus_msix_indices_s +{ + int cnt; + int indices[BF_TBUS_MSIX_INDICES_MAX]; +} bf_tbus_msix_indices_t; + +enum bf_intr_mode { + BF_INTR_MODE_NONE = 0, + BF_INTR_MODE_LEGACY, + BF_INTR_MODE_MSI, + BF_INTR_MODE_MSIX, +}; + +typedef struct bf_intr_mode_s { + enum bf_intr_mode intr_mode; +} bf_intr_mode_t; + #define BF_IOCMAPDMAADDR _IOWR(BF_IOC_MAGIC, 0, bf_dma_bus_map_t) -#define BF_IOCUNMAPDMAADDR _IOW(BF_IOC_MAGIC, 0, bf_dma_bus_map_t) +#define BF_IOCUNMAPDMAADDR _IOW(BF_IOC_MAGIC, 1, bf_dma_bus_map_t) +#define BF_TBUS_MSIX_INDEX _IOW(BF_IOC_MAGIC, 2, bf_tbus_msix_indices_t) +#define BF_GET_INTR_MODE _IOR(BF_IOC_MAGIC, 3, bf_intr_mode_t) #endif /* _BF_IOCTL_H_ */ diff --git a/platform/barefoot/bfn-modules/modules/bf_kdrv.c b/platform/barefoot/bfn-modules/modules/bf_kdrv.c index a9e8e65f968b..d4c786c56b75 100644 --- a/platform/barefoot/bfn-modules/modules/bf_kdrv.c +++ b/platform/barefoot/bfn-modules/modules/bf_kdrv.c @@ -1,49 +1,31 @@ /******************************************************************************* - * BAREFOOT NETWORKS CONFIDENTIAL & PROPRIETARY - * - * Copyright (c) 2015-2016 Barefoot Networks, Inc. + Barefoot Networks Switch ASIC Linux driver + Copyright(c) 2015 - 2019 Barefoot Networks, Inc. - * All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains the property of - * Barefoot Networks, Inc. and its suppliers, if any. The intellectual and - * technical concepts contained herein are proprietary to Barefoot Networks, - * Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, patents in - * process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material is - * strictly forbidden unless prior written permission is obtained from - * Barefoot Networks, Inc. - * - * No warranty, explicit or implicit is provided, unless granted under a - * written agreement with Barefoot Networks, Inc. - * - * $Id: $ - * - ******************************************************************************/ -/** - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2015 Barefoot Networks. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the... - * - **/ + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ /* bf_drv kernel module * - * This is kernel mode driver for Tofino chip. + * This is kernel mode driver for Tofino chip. * Provides user space mmap service and user space "wait for interrupt" * and "enable interrupt" services. */ @@ -52,21 +34,18 @@ #include #include #include -#include #include -#include -#include #include #include #include #include "bf_ioctl.h" +#include "bf_kdrv.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) #include #else - #include + #include #endif - #include #include #include @@ -75,104 +54,26 @@ //#error unsupported linux kernel version #endif -/* TBD: Need to build with CONFIG_PCI_MSI */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) -extern int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); -extern int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); -#else -extern int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); -extern int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec); -#endif - -#define PCI_VENDOR_ID_BF 0x1d1c -#define TOFINO_DEV_ID_A0 0x01 -#define TOFINO_DEV_ID_B0 0x10 -#define TOFINO2_DEV_ID_A0 0x0100 - -#ifndef PCI_MSIX_ENTRY_SIZE -#define PCI_MSIX_ENTRY_SIZE 16 -#define PCI_MSIX_ENTRY_LOWER_ADDR 0 -#define PCI_MSIX_ENTRY_UPPER_ADDR 4 -#define PCI_MSIX_ENTRY_DATA 8 -#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 -#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#ifdef BF_INCLUDE_KPKT +/* kernel pkt driver entry/exit APIs */ +extern int bf_kpkt_init(struct pci_dev *pdev, + u8 *bar0_vaddr, + void **adapter_ptr, + int dev_id, + int pci_use_highmem, + unsigned long head_room, + int kpkt_dr_int_en, + unsigned long rx_desc_countp); +extern void bf_kpkt_remove(void *adapter_ptr); +extern void bf_kpkt_irqhandler(int irq, void *adapter_ptr); +extern void bf_kpkt_set_pci_error(void *adapter_ptr, u8 pci_error); #endif -#define BF_CLASS_NAME "bf" -#define BF_MAX_DEVICE_CNT 256 -#define BF_INTR_MODE_NONE_NAME "none" -#define BF_INTR_MODE_LEGACY_NAME "legacy" -#define BF_INTR_MODE_MSI_NAME "msi" -#define BF_INTR_MODE_MSIX_NAME "msix" -#define BF_MAX_BAR_MAPS 6 -#define BF_MSIX_ENTRY_CNT 128 /* TBD make it 512 */ -#define BF_MSI_ENTRY_CNT 2 - -/* interrupt mode */ -enum bf_intr_mode { - BF_INTR_MODE_NONE = 0, - BF_INTR_MODE_LEGACY, - BF_INTR_MODE_MSI, - BF_INTR_MODE_MSIX -}; - -/* device memory */ -struct bf_dev_mem { - const char *name; - phys_addr_t addr; - resource_size_t size; - void __iomem *internal_addr; -}; - -struct bf_listener { - struct bf_pci_dev *bfdev; - s32 event_count[BF_MSIX_ENTRY_CNT]; - int minor; - struct bf_listener *next; -}; - -/* device information */ -struct bf_dev_info { - struct module *owner; - struct device *dev; - int minor; - atomic_t event[BF_MSIX_ENTRY_CNT]; - wait_queue_head_t wait; - const char *version; - struct bf_dev_mem mem[BF_MAX_BAR_MAPS]; - struct msix_entry *msix_entries; - long irq; /* first irq vector */ - int num_irq; /* number of irq vectors */ - unsigned long irq_flags;/* sharable ?? */ - int pci_error_state; /* was there a pci bus error */ -}; - -/* cookie to be passed to IRQ handler, useful especially with MSIX */ -struct bf_int_vector { - struct bf_pci_dev *bf_dev; - int int_vec_offset; -}; - - -/** - * A structure describing the private information for a BF pcie device. - */ -struct bf_pci_dev { - struct bf_dev_info info; - struct pci_dev *pdev; - enum bf_intr_mode mode; - u8 instance; - char name[16]; - struct bf_int_vector bf_int_vec[BF_MSIX_ENTRY_CNT]; - struct bf_listener *listener_head; /* head of a singly linked list of - listeners */ -}; - /* Keep any global information here that must survive even after the * bf_pci_dev is free-ed up. */ struct bf_global { - struct bf_pci_dev *bfdev ; + struct bf_pci_dev *bfdev; struct cdev *bf_cdev; struct fasync_struct *async_queue; }; @@ -181,14 +82,19 @@ static int bf_major; static int bf_minor[BF_MAX_DEVICE_CNT] = {0}; static struct class *bf_class = NULL; static char *intr_mode = NULL; +static int kpkt_mode = 0; +static int kpkt_hd_room = 32; +static int kpkt_rx_count = 256; +static int kpkt_dr_int_en = 1; + static enum bf_intr_mode bf_intr_mode_default = BF_INTR_MODE_MSI; static spinlock_t bf_nonisr_lock; + /* dev->minor should index into this array */ static struct bf_global bf_global[BF_MAX_DEVICE_CNT]; static void bf_add_listener(struct bf_pci_dev *bfdev, - struct bf_listener *listener) -{ + struct bf_listener *listener) { struct bf_listener **cur_listener = &bfdev->listener_head; if (!listener) { @@ -197,7 +103,7 @@ static void bf_add_listener(struct bf_pci_dev *bfdev, spin_lock(&bf_nonisr_lock); while (*cur_listener) { - cur_listener = &((*cur_listener)->next); + cur_listener = &((*cur_listener)->next); } *cur_listener = listener; listener->next = NULL; @@ -206,12 +112,12 @@ static void bf_add_listener(struct bf_pci_dev *bfdev, } static void bf_remove_listener(struct bf_pci_dev *bfdev, - struct bf_listener *listener) -{ + struct bf_listener *listener) { struct bf_listener **cur_listener = &bfdev->listener_head; - /* in case of certain error conditions, this function might be called after bf_pci_remove() - */ + /* in case of certain error conditions, this function might be called after + * bf_pci_remove() + */ if (!bfdev || !listener) { return; } @@ -235,12 +141,11 @@ static void bf_remove_listener(struct bf_pci_dev *bfdev, /* a pool of minor numbers is maintained */ /* return the first available minor number */ -static int bf_get_next_minor_no(int *minor) -{ +static int bf_get_next_minor_no(int *minor) { int i; spin_lock(&bf_nonisr_lock); - for(i = 0; i < BF_MAX_DEVICE_CNT; i++) { + for (i = 0; i < BF_MAX_DEVICE_CNT; i++) { if (bf_minor[i] == 0) { *minor = i; bf_minor[i] = 1; /* mark it as taken */ @@ -254,13 +159,12 @@ static int bf_get_next_minor_no(int *minor) } /* return a minor number back to the pool for recycling */ -static int bf_return_minor_no(int minor) -{ +static int bf_return_minor_no(int minor) { int err; spin_lock(&bf_nonisr_lock); if (bf_minor[minor] == 0) { /* was already returned */ - err = -1; /* don't change anything, but return error */ + err = -1; /* don't change anything, but return error */ } else { bf_minor[minor] = 0; /* mark it as available */ err = 0; @@ -269,31 +173,29 @@ static int bf_return_minor_no(int minor) return err; } -static inline struct bf_pci_dev *bf_get_pci_dev(struct bf_dev_info *info) -{ - return container_of(info, struct bf_pci_dev, info); +static inline struct bf_pci_dev *bf_get_pci_dev(struct bf_dev_info *info) { + return container_of(info, struct bf_pci_dev, info); } /* * It masks the msix on/off of generating MSI-X messages. */ -static void -bf_msix_mask_irq(struct msi_desc *desc, int32_t state) -{ - u32 mask_bits = desc->masked; - unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_VECTOR_CTRL; - - if (state != 0) - mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; - else - mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; - - if (mask_bits != desc->masked) { - writel(mask_bits, desc->mask_base + offset); - readl(desc->mask_base); - desc->masked = mask_bits; - } +static void bf_msix_mask_irq(struct msi_desc *desc, int32_t state) { + u32 mask_bits = desc->masked; + unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL; + + if (state != 0) { + mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; + } else { + mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; + } + + if (mask_bits != desc->masked) { + writel(mask_bits, desc->mask_base + offset); + readl(desc->mask_base); + desc->masked = mask_bits; + } } /** @@ -308,179 +210,217 @@ bf_msix_mask_irq(struct msi_desc *desc, int32_t state) * - On success, 0. * - On failure, a negative value. */ -static int -bf_pci_irqcontrol(struct bf_pci_dev *bfdev, s32 irq_state) -{ - struct pci_dev *pdev = bfdev->pdev; - - pci_cfg_access_lock(pdev); - if (bfdev->mode == BF_INTR_MODE_LEGACY) - pci_intx(pdev, !!irq_state); - - else if (bfdev->mode == BF_INTR_MODE_MSIX) { - struct msi_desc *desc; -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) - list_for_each_entry(desc, &pdev->msi_list, list) - bf_msix_mask_irq(desc, irq_state); +static int bf_pci_irqcontrol(struct bf_pci_dev *bfdev, s32 irq_state) { + struct pci_dev *pdev = bfdev->pdev; + + pci_cfg_access_lock(pdev); + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + pci_intx(pdev, !!irq_state); + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + struct msi_desc *desc; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) + list_for_each_entry(desc, &pdev->msi_list, list) + bf_msix_mask_irq(desc, irq_state); #else - for_each_pci_msi_entry(desc, pdev) - bf_msix_mask_irq(desc, irq_state); + for_each_pci_msi_entry(desc, pdev) bf_msix_mask_irq(desc, irq_state); #endif - } - pci_cfg_access_unlock(pdev); + } + pci_cfg_access_unlock(pdev); - return 0; + return 0; } +#ifdef BF_INCLUDE_KPKT +/* there are three TBUS MSIX vectors */ +static int bf_irq_is_tbus_msix(struct bf_pci_dev *bfdev, int irq) { + struct bf_dev_info *info = &bfdev->info; + + if (!info->tbus_msix_map_enable) { + return 0; + } + if (irq == info->msix_entries[info->tbus_msix_ind[0]].vector || + irq == info->msix_entries[info->tbus_msix_ind[1]].vector) { + return 1; + } else if (irq == info->msix_entries[info->tbus_msix_ind[2]].vector) { + /* log error */ + printk(KERN_ALERT "bf_tbus error msix\n"); + return 1; + } + return 0; +} +#endif + /** * interrupt handler which will check if the interrupt is from the right * device. If so, disable it here and will be enabled later. */ -static irqreturn_t bf_pci_irqhandler(int irq, struct bf_pci_dev *bfdev) -{ - /* Legacy mode need to mask in hardware */ - if (bfdev->mode == BF_INTR_MODE_LEGACY && - !pci_check_and_mask_intx(bfdev->pdev)) - return IRQ_NONE; - - /* NOTE : if bfdev->info.pci_error_state == 1, then do not access the - * device and return IRQ_NOTHANDLED. - */ - /* Message signal mode, no share IRQ and automasked */ - return IRQ_HANDLED; +static irqreturn_t bf_pci_irqhandler(int irq, struct bf_pci_dev *bfdev) { + /* Legacy mode need to mask in hardware */ + if (bfdev->mode == BF_INTR_MODE_LEGACY && + !pci_check_and_mask_intx(bfdev->pdev)) { + return IRQ_NONE; + } + + /* NOTE : if bfdev->info.pci_error_state == 1, then do not access the + * device and return IRQ_NOTHANDLED. + */ +#ifdef BF_INCLUDE_KPKT + /* handle pkt DR interrpt (MSI vect-1) if it has to be in kernel */ + if (kpkt_dr_int_en && bfdev->info.irq != 0) { + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + bf_kpkt_irqhandler(irq, bfdev->adapter_ptr); + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + /* do not process packet unless the MSI interrupt is from tbus */ + /* all BF interrupts arrive on one single MSI if "1" MSI is configured */ + if (bfdev->info.num_irq == 1 || (irq == (bfdev->info.irq + BF_MSI_INT_TBUS))) { + bf_kpkt_irqhandler(irq, bfdev->adapter_ptr); + } + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + if (bfdev->info.tof_type == BF_TOFINO_2 && bf_irq_is_tbus_msix(bfdev,irq)) { + bf_kpkt_irqhandler(irq, bfdev->adapter_ptr); + } + } + } +#endif + /* Message signal mode, no share IRQ and automasked */ + return IRQ_HANDLED; } /* Remap pci resources described by bar #pci_bar */ -static int -bf_pci_setup_iomem(struct pci_dev *dev, struct bf_dev_info *info, - int n, int pci_bar, const char *name) -{ - unsigned long addr, len; - void *internal_addr; - - if (sizeof(info->mem) / sizeof(info->mem[0]) <= n) - return -EINVAL; - - addr = pci_resource_start(dev, pci_bar); - len = pci_resource_len(dev, pci_bar); - if (addr == 0 || len == 0) - return -1; - internal_addr = pci_ioremap_bar(dev, pci_bar); - if (internal_addr == NULL) - return -1; - info->mem[n].name = name; - info->mem[n].addr = addr; - info->mem[n].internal_addr = internal_addr; - info->mem[n].size = len; - return 0; +static int bf_pci_setup_iomem(struct pci_dev *dev, + struct bf_dev_info *info, + int n, + int pci_bar, + const char *name) { + unsigned long addr, len; + void *internal_addr; + + if (sizeof(info->mem) / sizeof(info->mem[0]) <= n) { + return -EINVAL; + } + + addr = pci_resource_start(dev, pci_bar); + len = pci_resource_len(dev, pci_bar); + if (addr == 0 || len == 0) { + return -1; + } + internal_addr = pci_ioremap_bar(dev, pci_bar); + if (internal_addr == NULL) { + return -1; + } + info->mem[n].name = name; + info->mem[n].addr = addr; + info->mem[n].internal_addr = internal_addr; + info->mem[n].size = len; + return 0; } /* Unmap previously ioremap'd resources */ -static void -bf_pci_release_iomem(struct bf_dev_info *info) -{ - int i; +static void bf_pci_release_iomem(struct bf_dev_info *info) { + int i; - for (i = 0; i < BF_MAX_BAR_MAPS; i++) { - if (info->mem[i].internal_addr) - iounmap(info->mem[i].internal_addr); - } + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (info->mem[i].internal_addr) { + iounmap(info->mem[i].internal_addr); + } + } } -static int -bf_setup_bars(struct pci_dev *dev, struct bf_dev_info *info) -{ - int i, iom, ret; - unsigned long flags; - static const char *bar_names[BF_MAX_BAR_MAPS] = { - "BAR0", "BAR1", "BAR2", "BAR3", "BAR4", "BAR5", - }; - - iom = 0; - - for (i = 0; i < BF_MAX_BAR_MAPS; i++) { - if (pci_resource_len(dev, i) != 0 && - pci_resource_start(dev, i) != 0) { - flags = pci_resource_flags(dev, i); - if (flags & IORESOURCE_MEM) { - ret = bf_pci_setup_iomem(dev, info, iom, i, bar_names[i]); - if (ret != 0) - return ret; - iom++; - } - } - } - return (iom != 0) ? ret : -ENOENT; +static int bf_setup_bars(struct pci_dev *dev, struct bf_dev_info *info) { + int i, iom, ret; + unsigned long flags; + static const char *bar_names[BF_MAX_BAR_MAPS] = { + "BAR0", "BAR1", "BAR2", "BAR3", "BAR4", "BAR5", + }; + + iom = 0; + + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (pci_resource_len(dev, i) != 0 && pci_resource_start(dev, i) != 0) { + flags = pci_resource_flags(dev, i); + if (flags & IORESOURCE_MEM) { + ret = bf_pci_setup_iomem(dev, info, iom, i, bar_names[i]); + if (ret != 0) { + return ret; + } + iom++; + } + } + } + return (iom != 0) ? ret : -ENOENT; } -static irqreturn_t bf_interrupt(int irq, void *bfdev_id) -{ +static irqreturn_t bf_interrupt(int irq, void *bfdev_id) { struct bf_pci_dev *bfdev = ((struct bf_int_vector *)bfdev_id)->bf_dev; int vect_off = ((struct bf_int_vector *)bfdev_id)->int_vec_offset; irqreturn_t ret = bf_pci_irqhandler(irq, bfdev); - if (ret == IRQ_HANDLED) + if (ret == IRQ_HANDLED) { atomic_inc(&(bfdev->info.event[vect_off])); - + } return ret; } -static unsigned int bf_poll(struct file *filep, poll_table *wait) -{ +static unsigned int bf_poll(struct file *filep, poll_table *wait) { struct bf_listener *listener = (struct bf_listener *)filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; int i; - + if (!bfdev) { return -ENODEV; } - if (!bfdev->info.irq) + if (!bfdev->info.irq) { return -EIO; - + } + poll_wait(filep, &bfdev->info.wait, wait); - for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) - if (listener->event_count[i] != atomic_read(&bfdev->info.event[i])) + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + if (listener->event_count[i] != atomic_read(&bfdev->info.event[i])) { return POLLIN | POLLRDNORM; + } + } return 0; } -static int bf_find_mem_index(struct vm_area_struct *vma) -{ +static int bf_find_mem_index(struct vm_area_struct *vma) { struct bf_pci_dev *bfdev = vma->vm_private_data; if (vma->vm_pgoff < BF_MAX_BAR_MAPS) { - if (bfdev->info.mem[vma->vm_pgoff].size == 0) + if (bfdev->info.mem[vma->vm_pgoff].size == 0) { return -1; + } return (int)vma->vm_pgoff; } return -1; } - + static const struct vm_operations_struct bf_physical_vm_ops = { #ifdef CONFIG_HAVE_IOREMAP_PROT - .access = generic_access_phys, + .access = generic_access_phys, #endif }; -static int bf_mmap_physical(struct vm_area_struct *vma) -{ +static int bf_mmap_physical(struct vm_area_struct *vma) { struct bf_pci_dev *bfdev = vma->vm_private_data; int bar = bf_find_mem_index(vma); struct bf_dev_mem *mem; - if (bar < 0) + if (bar < 0) { return -EINVAL; + } mem = bfdev->info.mem + bar; - - if (mem->addr & ~PAGE_MASK) + + if (mem->addr & ~PAGE_MASK) { return -ENODEV; - if (vma->vm_end - vma->vm_start > mem->size) + } + if (vma->vm_end - vma->vm_start > mem->size) { return -EINVAL; - + } + vma->vm_ops = &bf_physical_vm_ops; - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + /* * We cannot use the vm_iomap_memory() helper here, * because vma->vm_pgoff is the map index we looked @@ -490,40 +430,45 @@ static int bf_mmap_physical(struct vm_area_struct *vma) * So we just do the physical mmap without a page * offset. */ - return remap_pfn_range(vma, vma->vm_start, mem->addr >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot); + return remap_pfn_range(vma, + vma->vm_start, + mem->addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); } -static int bf_mmap(struct file *filep, struct vm_area_struct *vma) -{ +static int bf_mmap(struct file *filep, struct vm_area_struct *vma) { struct bf_listener *listener = filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; int bar; unsigned long requested_pages, actual_pages; - + if (!bfdev) { return -ENODEV; } - if (vma->vm_end < vma->vm_start) + if (vma->vm_end < vma->vm_start) { return -EINVAL; - + } + vma->vm_private_data = bfdev; - + bar = bf_find_mem_index(vma); - if (bar < 0) + if (bar < 0) { return -EINVAL; - + } + requested_pages = vma_pages(vma); - actual_pages = ((bfdev->info.mem[bar].addr & ~PAGE_MASK) - + bfdev->info.mem[bar].size + PAGE_SIZE -1) >> PAGE_SHIFT; - if (requested_pages > actual_pages) + actual_pages = ((bfdev->info.mem[bar].addr & ~PAGE_MASK) + + bfdev->info.mem[bar].size + PAGE_SIZE - 1) >> + PAGE_SHIFT; + if (requested_pages > actual_pages) { return -EINVAL; - + } + return bf_mmap_physical(vma); } -static int bf_fasync(int fd, struct file *filep, int mode) -{ +static int bf_fasync(int fd, struct file *filep, int mode) { int minor; if (!filep->private_data) { @@ -539,8 +484,7 @@ static int bf_fasync(int fd, struct file *filep, int mode) return (fasync_helper(fd, filep, mode, &bf_global[minor].async_queue)); } -static int bf_open(struct inode *inode, struct file *filep) -{ +static int bf_open(struct inode *inode, struct file *filep) { struct bf_pci_dev *bfdev; struct bf_listener *listener; int i; @@ -550,19 +494,19 @@ static int bf_open(struct inode *inode, struct file *filep) if (listener) { listener->bfdev = bfdev; listener->minor = bfdev->info.minor; - listener->next = NULL; + listener->next = NULL; bf_add_listener(bfdev, listener); - for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { listener->event_count[i] = atomic_read(&bfdev->info.event[i]); + } filep->private_data = listener; return 0; } else { - return(-ENOMEM); + return (-ENOMEM); } } -static int bf_release(struct inode *inode, struct file *filep) -{ +static int bf_release(struct inode *inode, struct file *filep) { struct bf_listener *listener = filep->private_data; bf_fasync(-1, filep, 0); /* empty any process id in the notification list */ @@ -574,42 +518,47 @@ static int bf_release(struct inode *inode, struct file *filep) } /* user space support: make read() system call after poll() of select() */ -static ssize_t bf_read(struct file *filep, char __user *buf, - size_t count, loff_t *ppos) -{ +static ssize_t bf_read(struct file *filep, + char __user *buf, + size_t count, + loff_t *ppos) { struct bf_listener *listener = filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; int retval, event_count[BF_MSIX_ENTRY_CNT]; - int i, mismatch_found = 0; /* OR of per vector mismatch */ + int i, mismatch_found = 0; /* OR of per vector mismatch */ unsigned char cnt_match[BF_MSIX_ENTRY_CNT]; /* per vector mismatch */ if (!bfdev) { return -ENODEV; } /* irq must be setup for read() to work */ - if (!bfdev->info.irq) + if (!bfdev->info.irq) { return -EIO; + } /* ensure that there is enough space on user buffer for the given interrupt * mode */ if (bfdev->mode == BF_INTR_MODE_MSIX) { - if (count < sizeof(s32)*BF_MSIX_ENTRY_CNT) + if (count < sizeof(s32) * BF_MSIX_ENTRY_CNT) { return -EINVAL; - count = sizeof(s32)*BF_MSIX_ENTRY_CNT; + } + count = sizeof(s32) * BF_MSIX_ENTRY_CNT; } else if (bfdev->mode == BF_INTR_MODE_MSI) { - if (count < sizeof(s32)*BF_MSI_ENTRY_CNT) + if (count < sizeof(s32) * BF_MSI_ENTRY_CNT) { return -EINVAL; - count = sizeof(s32)*BF_MSI_ENTRY_CNT; + } + count = sizeof(s32) * BF_MSI_ENTRY_CNT; } else { - if (count < sizeof(s32)) + if (count < sizeof(s32)) { return -EINVAL; + } count = sizeof(s32); } do { set_current_state(TASK_INTERRUPTIBLE); - for (i = 0; i < (count/sizeof(s32)); i++) { + for (i = 0; i < (count / sizeof(s32)); i++) { event_count[i] = atomic_read(&(bfdev->info.event[i])); if (event_count[i] != listener->event_count[i]) { mismatch_found |= 1; @@ -621,10 +570,10 @@ static ssize_t bf_read(struct file *filep, char __user *buf, } if (mismatch_found) { __set_current_state(TASK_RUNNING); - if (copy_to_user(buf, &event_count, count)) + if (copy_to_user(buf, &event_count, count)) { retval = -EFAULT; - else { /* adjust the listener->event_count; */ - for (i = 0 ; i < (count/sizeof(s32)); i++) { + } else { /* adjust the listener->event_count; */ + for (i = 0; i < (count / sizeof(s32)); i++) { if (cnt_match[i]) { listener->event_count[i] = event_count[i]; } @@ -651,25 +600,29 @@ static ssize_t bf_read(struct file *filep, char __user *buf, return retval; } -/* user space is supposed to call this after it is done with interrupt +/* user space is supposed to call this after it is done with interrupt * processing */ -static ssize_t bf_write(struct file *filep, const char __user *buf, - size_t count, loff_t *ppos) -{ +static ssize_t bf_write(struct file *filep, + const char __user *buf, + size_t count, + loff_t *ppos) { struct bf_listener *listener = filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; ssize_t ret; s32 int_en; - if (!bfdev || !bfdev->info.irq) + if (!bfdev || !bfdev->info.irq) { return -EIO; - - if (count != sizeof(s32)) + } + + if (count != sizeof(s32)) { return -EINVAL; + } - if (copy_from_user(&int_en, buf, count)) + if (copy_from_user(&int_en, buf, count)) { return -EFAULT; + } /* clear pci_error_state */ bfdev->info.pci_error_state = 0; @@ -692,7 +645,11 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) } switch(cmd) { case BF_IOCMAPDMAADDR: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) + if (access_ok(addr, sizeof(bf_dma_bus_map_t))) { +#else if (access_ok(VERIFY_WRITE, addr, sizeof(bf_dma_bus_map_t))) { +#endif if (copy_from_user(&dma_map, addr, sizeof(bf_dma_bus_map_t))) { return EFAULT; } @@ -703,7 +660,7 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) if (dma_mapping_error(&bfdev->pdev->dev, dma_hndl)) { return EFAULT; } - dma_map.dma_addr = (void *)dma_hndl; + dma_map.dma_addr = (void *)(uintptr_t)dma_hndl; if (copy_to_user(addr, &dma_map, sizeof(bf_dma_bus_map_t))) { return EFAULT; } @@ -712,18 +669,55 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) } break; case BF_IOCUNMAPDMAADDR: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) + if (access_ok(addr, sizeof(bf_dma_bus_map_t))) { +#else if (access_ok(VERIFY_READ, addr, sizeof(bf_dma_bus_map_t))) { +#endif if (copy_from_user(&dma_map, addr, sizeof(bf_dma_bus_map_t))) { return EFAULT; } if (!dma_map.dma_addr || !dma_map.size) { return EFAULT; } - dma_unmap_single(&bfdev->pdev->dev, (dma_addr_t)dma_map.dma_addr, dma_map.size, DMA_BIDIRECTIONAL); + dma_unmap_single(&bfdev->pdev->dev, (dma_addr_t)(uintptr_t)(dma_map.dma_addr), dma_map.size, DMA_BIDIRECTIONAL); } else { return EFAULT; } break; + case BF_TBUS_MSIX_INDEX: + /* not supported for Tofino-1 */ + if (bfdev->info.tof_type == BF_TOFINO_1) { + return EINVAL; + } else { + int i; + bf_tbus_msix_indices_t msix_ind; + if (copy_from_user(&msix_ind, addr, sizeof(bf_tbus_msix_indices_t))) { + return EFAULT; + } + if (msix_ind.cnt > BF_TBUS_MSIX_INDICES_MAX) { + return EINVAL; + } + for (i = 0; i < msix_ind.cnt; i++) { + if (msix_ind.indices[i] >= BF_MSIX_ENTRY_CNT) { + return EINVAL; + } + } + for (i = 0; i < msix_ind.cnt; i++) { + bfdev->info.tbus_msix_ind[i] = msix_ind.indices[i]; + } + bfdev->info.tbus_msix_map_enable = 1; + } + break; + case BF_GET_INTR_MODE: + { + bf_intr_mode_t i_mode; + i_mode.intr_mode = bfdev->mode; + if (copy_to_user(addr, &i_mode, sizeof(bf_intr_mode_t))) { + return EFAULT; + } + } + break; default: return EINVAL; } @@ -731,27 +725,27 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) } static const struct file_operations bf_fops = { - .owner = THIS_MODULE, - .open = bf_open, - .release = bf_release, - .unlocked_ioctl = bf_ioctl, - .read = bf_read, - .write = bf_write, - .mmap = bf_mmap, - .poll = bf_poll, - .fasync = bf_fasync, + .owner = THIS_MODULE, + .open = bf_open, + .release = bf_release, + .unlocked_ioctl = bf_ioctl, + .read = bf_read, + .write = bf_write, + .mmap = bf_mmap, + .poll = bf_poll, + .fasync = bf_fasync, }; -static int bf_major_init(struct bf_pci_dev *bfdev, int minor) -{ +static int bf_major_init(struct bf_pci_dev *bfdev, int minor) { struct cdev *cdev; static const char name[] = "bf"; dev_t bf_dev = 0; int result; result = alloc_chrdev_region(&bf_dev, 0, BF_MAX_DEVICE_CNT, name); - if (result) + if (result) { return result; + } result = -ENOMEM; cdev = cdev_alloc(); @@ -763,8 +757,9 @@ static int bf_major_init(struct bf_pci_dev *bfdev, int minor) kobject_set_name(&cdev->kobj, "%s", name); result = cdev_add(cdev, bf_dev, BF_MAX_DEVICE_CNT); - if (result) + if (result) { goto fail_dev_add; + } bf_major = MAJOR(bf_dev); bf_global[minor].bf_cdev = cdev; @@ -775,19 +770,16 @@ static int bf_major_init(struct bf_pci_dev *bfdev, int minor) return result; } -static void bf_major_cleanup(struct bf_pci_dev *bfdev, int minor) -{ +static void bf_major_cleanup(struct bf_pci_dev *bfdev, int minor) { unregister_chrdev_region(MKDEV(bf_major, 0), BF_MAX_DEVICE_CNT); cdev_del(bf_global[minor].bf_cdev); } -static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) -{ +static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) { int ret; ret = bf_major_init(bfdev, minor); - if (ret) - return ret; - + if (ret) return ret; + bf_class = class_create(THIS_MODULE, BF_CLASS_NAME); if (!bf_class) { printk(KERN_ERR "create_class failed for bf_dev\n"); @@ -801,28 +793,26 @@ static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) return ret; } -static void bf_remove_cdev(struct bf_pci_dev *bfdev) -{ +static void bf_remove_cdev(struct bf_pci_dev *bfdev) { class_destroy(bf_class); bf_major_cleanup(bfdev, bfdev->info.minor); } - /** * bf_register_device - register a new userspace mem device * @parent: parent device - * @bfdev: bf pci device + * @bfdev: bf pci device * * returns zero on success or a negative error code. */ -int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) -{ +int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) { struct bf_dev_info *info = &bfdev->info; int i, j, ret = 0; int minor; - if (!parent || !info || !info->version) + if (!parent || !info || !info->version) { return -EINVAL; + } init_waitqueue_head(&info->wait); @@ -840,9 +830,8 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) return ret; } - info->dev = device_create(bf_class, parent, - MKDEV(bf_major, minor), bfdev, - "bf%d", minor); + info->dev = device_create( + bf_class, parent, MKDEV(bf_major, minor), bfdev, "bf%d", minor); if (!info->dev) { printk(KERN_ERR "BF: device creation failed\n"); return -ENODEV; @@ -861,19 +850,24 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) * freed until they are released. */ if (bfdev->mode == BF_INTR_MODE_LEGACY) { - ret = request_irq(info->irq, bf_interrupt, - info->irq_flags, bfdev->name, + ret = request_irq(info->irq, + bf_interrupt, + info->irq_flags, + bfdev->name, (void *)&(bfdev->bf_int_vec[0])); if (ret) { printk(KERN_ERR "bf failed to request legacy irq %ld error %d\n", - info->irq, ret); + info->irq, + ret); return ret; } printk(KERN_NOTICE "BF allocating legacy int vector %ld\n", info->irq); } else if (bfdev->mode == BF_INTR_MODE_MSIX) { for (i = 0; i < info->num_irq; i++) { - ret = request_irq(info->msix_entries[i].vector, bf_interrupt, - info->irq_flags, bfdev->name, + ret = request_irq(info->msix_entries[i].vector, + bf_interrupt, + info->irq_flags, + bfdev->name, (void *)&(bfdev->bf_int_vec[i])); if (ret) { /* undo all other previous bindings */ @@ -883,14 +877,17 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) (void *)&(bfdev->bf_int_vec[j])); } return ret; - } + } } printk(KERN_NOTICE "BF allocating %d MSIx vectors from %ld\n", - info->num_irq, info->irq); + info->num_irq, + info->irq); } else if (bfdev->mode == BF_INTR_MODE_MSI) { for (i = 0; i < info->num_irq; i++) { - ret = request_irq(info->irq + i, bf_interrupt, - info->irq_flags, bfdev->name, + ret = request_irq(info->irq + i, + bf_interrupt, + info->irq_flags, + bfdev->name, (void *)&(bfdev->bf_int_vec[i])); if (ret) { /* undo all other previous bindings */ @@ -899,10 +896,11 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) free_irq(info->irq + j, (void *)&(bfdev->bf_int_vec[j])); } return ret; - } + } } printk(KERN_NOTICE "BF allocating %d MSI vectors from %ld\n", - info->num_irq, info->irq); + info->num_irq, + info->irq); } } return 0; @@ -910,12 +908,11 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) /** * bf_unregister_device - register a new userspace mem device - * @bfdev: bf pci device + * @bfdev: bf pci device * * returns none */ -void bf_unregister_device(struct bf_pci_dev *bfdev) -{ +void bf_unregister_device(struct bf_pci_dev *bfdev) { struct bf_dev_info *info = &bfdev->info; int i; @@ -938,8 +935,7 @@ void bf_unregister_device(struct bf_pci_dev *bfdev) return; } -static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) -{ +static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) { return &pdev->dev; } @@ -957,7 +953,7 @@ static void bf_disable_int_dma(struct bf_pci_dev *bfdev) { /* mask interrupt at shadow level */ bf_addr = (u32 *)((u8 *)bf_base_addr + 0xc0); for (i = 0; i < 16; i++) { - *bf_addr = 0xffffffff; + *bf_addr = 0xffffffffUL; bf_addr++; } /* mask DMA */ @@ -967,18 +963,17 @@ static void bf_disable_int_dma(struct bf_pci_dev *bfdev) { *bf_addr = val; } -static int -bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ +static int bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct bf_pci_dev *bfdev; - int err; + int err, pci_use_highmem; int i, num_irq; memset(bf_global, 0, sizeof(bf_global)); bfdev = kzalloc(sizeof(struct bf_pci_dev), GFP_KERNEL); - if (!bfdev) + if (!bfdev) { return -ENOMEM; + } /* init the cookies to be passed to ISRs */ for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { @@ -992,12 +987,32 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* clear pci_error_state */ bfdev->info.pci_error_state = 0; + /* mark pci device_id type */ + bfdev->info.pci_dev_id = pdev->device; + switch (pdev->device) { + case TOFINO2_DEV_ID_A0: + case TOFINO2_DEV_ID_A00: + case TOFINO2_DEV_ID_B0: + bfdev->info.tof_type = BF_TOFINO_2; + break; + default: + bfdev->info.tof_type = BF_TOFINO_1; + break; + } + /* intialize TBUS MSIX indices */ + for (i = 0; i < BF_TBUS_MSIX_INDICES_MAX; i++) { + if (bfdev->info.tof_type == BF_TOFINO_1) { + bfdev->info.tbus_msix_ind[i] = BF_TBUS_MSIX_BASE_INDEX_TOF1 + i; + } else if (bfdev->info.tof_type == BF_TOFINO_2) { + bfdev->info.tbus_msix_ind[i] = BF_TBUS_MSIX_INDEX_INVALID; + } + } /* * enable device */ err = pci_enable_device(pdev); if (err != 0) { - dev_err(&pdev->dev, "Cannot enable PCI device\n"); + printk(KERN_ERR "bf cannot enable PCI device\n"); goto fail_free; } @@ -1007,27 +1022,29 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) */ err = pci_request_regions(pdev, "bf_umem"); if (err != 0) { - dev_err(&pdev->dev, "Cannot request regions\n"); + printk(KERN_ERR "bf Cannot request regions\n"); goto fail_pci_disable; } /* remap IO memory */ err = bf_setup_bars(pdev, &bfdev->info); - if (err != 0) + if (err != 0) { + printk(KERN_ERR "bf Cannot setup BARs\n"); goto fail_release_iomem; + } if (!dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64)) && !dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64))) { + pci_use_highmem = 1; } else { err = dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32)); if (err) { - err = dma_set_coherent_mask(pci_dev_to_dev(pdev), - DMA_BIT_MASK(32)); + err = dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32)); if (err) { - dev_err(pci_dev_to_dev(pdev), "No usable DMA " - "configuration, aborting\n"); - goto fail_release_iomem; + printk(KERN_ERR "bf no usable DMA configuration, aborting\n"); + goto fail_release_iomem; } } + pci_use_highmem = 0; } /* enable pci error reporting */ @@ -1054,126 +1071,142 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) switch (bf_intr_mode_default) { #ifdef CONFIG_PCI_MSI - case BF_INTR_MODE_MSIX: - /* Only 1 msi-x vector needed */ - bfdev->info.msix_entries = kcalloc(BF_MSIX_ENTRY_CNT, - sizeof(struct msix_entry), GFP_KERNEL); - if (!bfdev->info.msix_entries) { - err = -ENOMEM; - goto fail_clear_pci_master; - } - for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { - bfdev->info.msix_entries[i].entry= i; - } + case BF_INTR_MODE_MSIX: + /* Only 1 msi-x vector needed */ + bfdev->info.msix_entries = + kcalloc(BF_MSIX_ENTRY_CNT, sizeof(struct msix_entry), GFP_KERNEL); + if (!bfdev->info.msix_entries) { + err = -ENOMEM; + goto fail_clear_pci_master; + } + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + bfdev->info.msix_entries[i].entry = i; + } #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) - num_irq = pci_enable_msix(pdev, bfdev->info.msix_entries, - BF_MSIX_ENTRY_CNT); - if (num_irq == 0) { - dev_dbg(&pdev->dev, "using MSI-X"); - bfdev->info.num_irq = BF_MSIX_ENTRY_CNT; - bfdev->info.irq = bfdev->info.msix_entries[0].vector; - bfdev->mode = BF_INTR_MODE_MSIX; - printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", num_irq, - bfdev->info.irq); - break; - } + num_irq = pci_enable_msix(pdev, bfdev->info.msix_entries, + BF_MSIX_ENTRY_CNT); + if (num_irq == 0) { + bfdev->info.num_irq = BF_MSIX_ENTRY_CNT; + bfdev->info.irq = bfdev->info.msix_entries[0].vector; + bfdev->mode = BF_INTR_MODE_MSIX; + printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", num_irq, + bfdev->info.irq); + break; + } #else - num_irq = pci_enable_msix_range(pdev, bfdev->info.msix_entries, - BF_MSIX_ENTRY_CNT, BF_MSIX_ENTRY_CNT); - if (num_irq == BF_MSIX_ENTRY_CNT) { - dev_dbg(&pdev->dev, "using MSI-X"); - bfdev->info.num_irq = num_irq; - bfdev->info.irq = bfdev->info.msix_entries[0].vector; - bfdev->mode = BF_INTR_MODE_MSIX; - printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", num_irq, - bfdev->info.irq); - break; - } else { - if (num_irq) - pci_disable_msix(pdev); - kfree(bfdev->info.msix_entries); - bfdev->info.msix_entries = NULL; - printk(KERN_ERR "bf error allocating MSIX vectors. Trying MSI...\n"); - /* and, fall back to MSI */ - } + num_irq = pci_enable_msix_range( + pdev, bfdev->info.msix_entries, BF_MSIX_ENTRY_CNT, BF_MSIX_ENTRY_CNT); + if (num_irq == BF_MSIX_ENTRY_CNT) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = bfdev->info.msix_entries[0].vector; + bfdev->mode = BF_INTR_MODE_MSIX; + printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", + num_irq, + bfdev->info.irq); + break; + } else { + if (num_irq) pci_disable_msix(pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + printk(KERN_ERR "bf error allocating MSIX vectors. Trying MSI...\n"); + /* and, fall back to MSI */ + } #endif /* LINUX_VERSION_CODE */ /* ** intentional no-break */ - case BF_INTR_MODE_MSI: + case BF_INTR_MODE_MSI: #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) - num_irq = pci_enable_msi_block(pdev, BF_MSI_ENTRY_CNT); - /* we must get requested number of MSI vectors enabled */ - if (num_irq == 0) { - dev_dbg(&pdev->dev, "using MSI"); - bfdev->info.num_irq = BF_MSI_ENTRY_CNT; - bfdev->info.irq = pdev->irq; - bfdev->mode = BF_INTR_MODE_MSI; - printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, + num_irq = pci_enable_msi_block(pdev, BF_MSI_ENTRY_CNT); + /* we must get requested number of MSI vectors enabled */ + if (num_irq == 0) { + bfdev->info.num_irq = BF_MSI_ENTRY_CNT; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, bfdev->info.irq); - break; - } + break; + } #elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) - num_irq = pci_enable_msi_range(pdev, BF_MSI_ENTRY_CNT, BF_MSI_ENTRY_CNT); - if (num_irq > 0) { - dev_dbg(&pdev->dev, "using MSI"); - bfdev->info.num_irq = num_irq; - bfdev->info.irq = pdev->irq; - bfdev->mode = BF_INTR_MODE_MSI; - printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, - bfdev->info.irq); - break; - } + num_irq = pci_enable_msi_range(pdev, BF_MSI_ENTRY_CNT, BF_MSI_ENTRY_CNT); + if (num_irq > 0) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", + bfdev->info.num_irq, + bfdev->info.irq); + break; + } #else - num_irq = pci_alloc_irq_vectors_affinity(pdev, BF_MSI_ENTRY_CNT, - BF_MSI_ENTRY_CNT, PCI_IRQ_MSI | PCI_IRQ_AFFINITY, NULL); - if (num_irq > 0) { - dev_dbg(&pdev->dev, "using MSI"); - bfdev->info.num_irq = num_irq; - bfdev->info.irq = pci_irq_vector(pdev, 0); - bfdev->mode = BF_INTR_MODE_MSI; - printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, + num_irq = pci_alloc_irq_vectors_affinity(pdev, BF_MSI_ENTRY_CNT, + BF_MSI_ENTRY_CNT, PCI_IRQ_MSI | PCI_IRQ_AFFINITY, NULL); + if (num_irq > 0) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pci_irq_vector(pdev, 0); + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, bfdev->info.irq); - break; - } + break; + } #endif /* LINUX_VERSION_CODE */ #endif /* CONFIG_PCI_MSI */ /* fall back to Legacy Interrupt, intentional no-break */ - case BF_INTR_MODE_LEGACY: - if (pci_intx_mask_supported(pdev)) { - dev_dbg(&pdev->dev, "using INTX"); - bfdev->info.irq_flags = IRQF_SHARED; - bfdev->info.irq = pdev->irq; - bfdev->mode = BF_INTR_MODE_LEGACY; - printk(KERN_DEBUG "bf using LEGACY irq %ld\n", bfdev->info.irq); - break; - } - dev_notice(&pdev->dev, "PCI INTx mask not supported\n"); + case BF_INTR_MODE_LEGACY: + if (pci_intx_mask_supported(pdev)) { + bfdev->info.irq_flags = IRQF_SHARED; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_LEGACY; + printk(KERN_DEBUG "bf using LEGACY irq %ld\n", bfdev->info.irq); + break; + } + printk(KERN_NOTICE " bf PCI INTx mask not supported\n"); /* fall back to no Interrupt, intentional no-break */ - case BF_INTR_MODE_NONE: - bfdev->info.irq = 0; - bfdev->info.num_irq = 0; - bfdev->mode = BF_INTR_MODE_NONE; - break; + case BF_INTR_MODE_NONE: + bfdev->info.irq = 0; + bfdev->info.num_irq = 0; + bfdev->mode = BF_INTR_MODE_NONE; + break; - default: - dev_err(&pdev->dev, "invalid IRQ mode %u", bf_intr_mode_default); - err = -EINVAL; - goto fail_clear_pci_master; + default: + printk(KERN_DEBUG "bf invalid IRQ mode %u", bf_intr_mode_default); + err = -EINVAL; + goto fail_clear_pci_master; } pci_set_drvdata(pdev, bfdev); sprintf(bfdev->name, "bf_%d", bfdev->info.minor); /* register bf driver */ err = bf_register_device(&pdev->dev, bfdev); - if (err != 0) + if (err != 0) { goto fail_release_irq; + } bf_global[bfdev->info.minor].async_queue = NULL; bf_global[bfdev->info.minor].bfdev = bfdev; - dev_info(&pdev->dev, "bf device %d registered with irq %ld\n", - bfdev->instance, bfdev->info.irq); + dev_info(&pdev->dev, + "bf device %d registered with irq %ld\n", + bfdev->instance, + bfdev->info.irq); printk(KERN_ALERT "bf probe ok\n"); +#ifdef BF_INCLUDE_KPKT + if (kpkt_mode) { + err = bf_kpkt_init(pdev, + bfdev->info.mem[0].internal_addr, + &bfdev->adapter_ptr, + bfdev->info.minor, + pci_use_highmem, + kpkt_hd_room, + kpkt_dr_int_en, + kpkt_rx_count); + if (err == 0) { + printk(KERN_ALERT "bf_kpkt kernel processing enabled\n"); + } else { + printk(KERN_ALERT "error starting bf_kpkt kernel processing\n"); + bfdev->adapter_ptr = NULL; + } + } +#endif return 0; fail_release_irq: @@ -1182,11 +1215,11 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) pci_disable_msix(bfdev->pdev); kfree(bfdev->info.msix_entries); bfdev->info.msix_entries = NULL; - } - else if (bfdev->mode == BF_INTR_MODE_MSI) + } else if (bfdev->mode == BF_INTR_MODE_MSI) { pci_disable_msi(bfdev->pdev); + } fail_clear_pci_master: - pci_clear_master(pdev); + pci_clear_master(pdev); fail_release_iomem: bf_pci_release_iomem(&bfdev->info); pci_release_regions(pdev); @@ -1199,22 +1232,24 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return err; } - -static void -bf_pci_remove(struct pci_dev *pdev) -{ +static void bf_pci_remove(struct pci_dev *pdev) { struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); struct bf_listener *cur_listener; +#ifdef BF_INCLUDE_KPKT + if (kpkt_mode) { + bf_kpkt_remove(bfdev->adapter_ptr); + } +#endif bf_disable_int_dma(bfdev); bf_unregister_device(bfdev); if (bfdev->mode == BF_INTR_MODE_MSIX) { pci_disable_msix(pdev); kfree(bfdev->info.msix_entries); bfdev->info.msix_entries = NULL; - } - else if (bfdev->mode == BF_INTR_MODE_MSI) + } else if (bfdev->mode == BF_INTR_MODE_MSI) { pci_disable_msi(pdev); + } pci_clear_master(pdev); bf_pci_release_iomem(&bfdev->info); pci_release_regions(pdev); @@ -1234,6 +1269,17 @@ bf_pci_remove(struct pci_dev *pdev) kfree(bfdev); } +/* AER support callbacks. Refer to: + * https://www.kernel.org/doc/Documentation/PCI/pcieaer-howto.txt + * and + * https://www.kernel.org/doc/Documentation/PCI/pci-error-recovery.txt + * + * from bf_kdrv point of view, AER uncorrected errors (fatal and non-fatal) + * should not cause pci link reset (upstream port AER callbacks must also + * support this requirements of bf_kdrv) + * Device, however, is not expected to function after uncorrected errors + * but, application has chance to perform diags without resetting pci link + */ /** * bf_pci_error_detected - called when PCI error is detected * @pdev: Pointer to PCI device @@ -1242,10 +1288,8 @@ bf_pci_remove(struct pci_dev *pdev) * called when root complex detects pci error associated with the device */ static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, - pci_channel_state_t state) -{ + pci_channel_state_t state) { struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); - int minor; if (!bfdev) { return PCI_ERS_RESULT_NONE; @@ -1253,15 +1297,35 @@ static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, printk(KERN_ERR "pci_err_detected state %d\n", state); if (state == pci_channel_io_perm_failure || state == pci_channel_io_frozen) { bfdev->info.pci_error_state = 1; +#ifdef BF_INCLUDE_KPKT + if (kpkt_mode) { + bf_kpkt_set_pci_error(bfdev->adapter_ptr, 1); + } +#endif + /* we do not want pci link to go down. The user space application + * should collect the diag info, terminate the application and unload the + * kernel module + */ + return PCI_ERS_RESULT_CAN_RECOVER; /* to prevent pci link down */ + } else { + return PCI_ERS_RESULT_CAN_RECOVER; + } +} + +static pci_ers_result_t bf_pci_mmio_enabled(struct pci_dev *dev) { + struct bf_pci_dev *bfdev = pci_get_drvdata(dev); + + printk(KERN_ERR "BF pci_mmio_enabled invoked after pci error\n"); + pci_cleanup_aer_uncorrect_error_status(dev); + + if (bfdev) { /* send a signal to the user space program of the error */ - minor = bfdev->info.minor; + int minor = bfdev->info.minor; if (minor < BF_MAX_DEVICE_CNT && bf_global[minor].async_queue) { kill_fasync(&bf_global[minor].async_queue, SIGIO, POLL_ERR); } - return PCI_ERS_RESULT_DISCONNECT; - } else { - return PCI_ERS_RESULT_NONE; } + return PCI_ERS_RESULT_RECOVERED; } /** @@ -1270,13 +1334,13 @@ static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, * * Restart the card from scratch, as if from a cold-boot. */ -static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) -{ +static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) { /* nothing to do for now as we do not expect to get backto normal after - * a pcie link reset + * a pcie link reset. Not expected to be invoked. * TBD: fill in this function if tofino can recover after an error */ - return PCI_ERS_RESULT_DISCONNECT; + printk(KERN_ERR "BF pci_slot_reset invoked after pci error\n"); + return PCI_ERS_RESULT_RECOVERED; } /** @@ -1286,22 +1350,13 @@ static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) * This callback is called when the error recovery driver tells us that * its OK to resume normal operation. */ -static void bf_pci_resume(struct pci_dev *pdev) -{ - /* this function should never be called for Tofinoi */ - struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); - +static void bf_pci_resume(struct pci_dev *pdev) { printk(KERN_ERR "BF io_resume invoked after pci error\n"); - if (bfdev) { - bfdev->info.pci_error_state = 0; - } } -static int -bf_config_intr_mode(char *intr_str) -{ +static int bf_config_intr_mode(char *intr_str) { if (!intr_str) { - pr_info("Use MSIX interrupt by default\n"); + pr_info("Use MSI interrupt by default\n"); return 0; } @@ -1314,67 +1369,108 @@ bf_config_intr_mode(char *intr_str) } else if (!strcmp(intr_str, BF_INTR_MODE_LEGACY_NAME)) { bf_intr_mode_default = BF_INTR_MODE_LEGACY; pr_info("Use legacy interrupt\n"); - } else { + } else if (!strcmp(intr_str, BF_INTR_MODE_NONE_NAME)) { bf_intr_mode_default = BF_INTR_MODE_NONE; - pr_info(" No Interrupt \n"); + pr_info("BF interrupt disabled\n"); + } else { + pr_info("Error: bad intr_mode parameter - %s\n", intr_str); + return -EINVAL; } - return 0; } static const struct pci_device_id bf_pci_tbl[] = { - {PCI_VDEVICE(BF, TOFINO_DEV_ID_A0), 0}, - {PCI_VDEVICE(BF, TOFINO_DEV_ID_B0), 0}, - {PCI_VDEVICE(BF, TOFINO2_DEV_ID_A0), 0}, - /* required last entry */ - { .device = 0 } -}; + {PCI_VDEVICE(BF, TOFINO_DEV_ID_A0), 0}, + {PCI_VDEVICE(BF, TOFINO_DEV_ID_B0), 0}, + {PCI_VDEVICE(BF, TOFINO2_DEV_ID_A0), 0}, + {PCI_VDEVICE(BF, TOFINO2_DEV_ID_A00), 0}, + {PCI_VDEVICE(BF, TOFINO2_DEV_ID_B0), 0}, + /* required last entry */ + {.device = 0}}; /* PCI bus error handlers */ static struct pci_error_handlers bf_pci_err_handler = { - .error_detected = bf_pci_error_detected, - .slot_reset = bf_pci_slot_reset, - .resume = bf_pci_resume, + .error_detected = bf_pci_error_detected, + .mmio_enabled = bf_pci_mmio_enabled, + .slot_reset = bf_pci_slot_reset, + .resume = bf_pci_resume, }; -static struct pci_driver bf_pci_driver = { - .name = "bf", - .id_table = bf_pci_tbl, - .probe = bf_pci_probe, - .remove = bf_pci_remove, - .err_handler = &bf_pci_err_handler -}; +static struct pci_driver bf_pci_driver = {.name = "bf", + .id_table = bf_pci_tbl, + .probe = bf_pci_probe, + .remove = bf_pci_remove, + .err_handler = &bf_pci_err_handler}; -static int __init -bfdrv_init(void) -{ +static int __init bfdrv_init(void) { int ret; ret = bf_config_intr_mode(intr_mode); - if (ret < 0) + /* do not enable DR interrupt if not using MSI or not in kpkt mode */ + if ((bf_intr_mode_default != BF_INTR_MODE_MSI && + bf_intr_mode_default != BF_INTR_MODE_LEGACY) || kpkt_mode == 0) { + kpkt_dr_int_en = 0; + } + if (kpkt_mode) { + printk(KERN_NOTICE "kpkt_mode %d hd_room %d dr_int_en %d rx_count %d\n", + kpkt_mode, + kpkt_hd_room, + kpkt_dr_int_en, + kpkt_rx_count); + } + if (ret < 0) { return ret; - + } spin_lock_init(&bf_nonisr_lock); return pci_register_driver(&bf_pci_driver); } -static void __exit -bfdrv_exit(void) -{ +static void __exit bfdrv_exit(void) { pci_unregister_driver(&bf_pci_driver); + intr_mode = NULL; + kpkt_mode = 0; } module_init(bfdrv_init); module_exit(bfdrv_exit); +module_param(kpkt_mode, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_mode, + "bf kernel mode pkt processing (default=off):\n" + " 1 Use kernel mode bf_pkt processing\n" + " 0 Do not use kernel mode bf_pkt processing\n" + "\n"); + +module_param(kpkt_hd_room, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_hd_room, + "head room to reserve when receiving packets (default=32):\n" + "\n"); + +module_param(kpkt_rx_count, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_rx_count, + "number of buffers per rx pkt ring (default=256):\n" + "\n"); +/* dr_int_en is applicable only if MSI interrupt mode is selected */ +module_param(kpkt_dr_int_en, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_dr_int_en, + "bf pkt Interrupt enable (default=1):\n" + " 1 use interrupt\n" + " 0 Do not use interrupt\n" + "\n"); + module_param(intr_mode, charp, S_IRUGO); MODULE_PARM_DESC(intr_mode, -"bf interrupt mode (default=msix):\n" -" " BF_INTR_MODE_MSIX_NAME " Use MSIX interrupt\n" -" " BF_INTR_MODE_MSI_NAME " Use MSI interrupt\n" -" " BF_INTR_MODE_LEGACY_NAME " Use Legacy interrupt\n" -"\n"); + "bf interrupt mode (default=msix):\n" + " " BF_INTR_MODE_MSIX_NAME + " Use MSIX interrupt\n" + " " BF_INTR_MODE_MSI_NAME + " Use MSI interrupt\n" + " " BF_INTR_MODE_LEGACY_NAME + " Use Legacy interrupt\n" + " " BF_INTR_MODE_NONE_NAME + " Use no interrupt\n" + "\n"); MODULE_DEVICE_TABLE(pci, bf_pci_tbl); MODULE_DESCRIPTION("Barefoot Tofino PCI device"); diff --git a/platform/barefoot/bfn-modules/modules/bf_kdrv.h b/platform/barefoot/bfn-modules/modules/bf_kdrv.h new file mode 100644 index 000000000000..de5ca4bbc71c --- /dev/null +++ b/platform/barefoot/bfn-modules/modules/bf_kdrv.h @@ -0,0 +1,146 @@ +/******************************************************************************* + Barefoot Networks Switch ASIC Linux driver + Copyright(c) 2015 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#ifndef _BF_KDRV_H_ +#define _BF_KDRV_H_ + +#include +#include +#include + +#ifndef phys_addr_t +typedef uint64_t phys_addr_t; +#endif + +#define PCI_VENDOR_ID_BF 0x1d1c +#define TOFINO_DEV_ID_A0 0x01 +#define TOFINO_DEV_ID_B0 0x10 +#define TOFINO2_DEV_ID_A0 0x0100 +#define TOFINO2_DEV_ID_A00 0x0000 +#define TOFINO2_DEV_ID_B0 0x0110 + +#ifndef PCI_MSIX_ENTRY_SIZE +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR 4 +#define PCI_MSIX_ENTRY_DATA 8 +#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#endif + +#define BF_CLASS_NAME "bf" +#define BF_MAX_DEVICE_CNT 256 +#define BF_INTR_MODE_NONE_NAME "none" +#define BF_INTR_MODE_LEGACY_NAME "legacy" +#define BF_INTR_MODE_MSI_NAME "msi" +#define BF_INTR_MODE_MSIX_NAME "msix" +#define BF_MAX_BAR_MAPS 6 +#define BF_MSIX_ENTRY_CNT 32 /* 512 for tofino-1 */ +#define BF_MSI_ENTRY_CNT 2 +#define BF_MSI_INT_TBUS 1 + +#define BF_TBUS_MSIX_INDEX_INVALID (0) +#define BF_TBUS_MSIX_BASE_INDEX_TOF1 (32) + +/* Tofino generation type */ +typedef enum { + BF_TOFINO_NONE = 0, + BF_TOFINO_1, + BF_TOFINO_2, +} bf_tof_type; + +/* device memory */ +struct bf_dev_mem { + const char *name; + phys_addr_t addr; + resource_size_t size; + void __iomem *internal_addr; +}; + +struct bf_listener { + struct bf_pci_dev *bfdev; + s32 event_count[BF_MSIX_ENTRY_CNT]; + int minor; + struct bf_listener *next; +}; + +/* device information */ +struct bf_dev_info { + struct module *owner; + struct device *dev; + int minor; + atomic_t event[BF_MSIX_ENTRY_CNT]; + wait_queue_head_t wait; + const char *version; + struct bf_dev_mem mem[BF_MAX_BAR_MAPS]; + struct msix_entry *msix_entries; + long irq; /* first irq vector */ + int num_irq; /* number of irq vectors */ + unsigned long irq_flags; /* sharable ?? */ + uint16_t pci_dev_id; /* generation type of BF ASIC */ + bf_tof_type tof_type; /* Tofino generation type */ + /* msix index assigned to tbus MSIX for Tofino-2 only */ + int tbus_msix_ind[BF_TBUS_MSIX_INDICES_MAX]; + int tbus_msix_map_enable; + int pci_error_state; /* was there a pci bus error */ +}; + +/* cookie to be passed to IRQ handler, useful especially with MSIX */ +struct bf_int_vector { + struct bf_pci_dev *bf_dev; + int int_vec_offset; +}; + +/** + * A structure describing the private information for a BF pcie device. + */ +struct bf_pci_dev { + struct bf_dev_info info; + struct pci_dev *pdev; + enum bf_intr_mode mode; + u8 instance; + char name[16]; + struct bf_int_vector bf_int_vec[BF_MSIX_ENTRY_CNT]; + struct bf_listener * + listener_head; /* head of a singly linked list of listeners */ + void *adapter_ptr; /* pkt processing adapter */ +}; + +/* TBD: Need to build with CONFIG_PCI_MSI */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) +#if defined(RHEL_RELEASE_CODE) +#else +extern int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); +#endif /* defined(RHEL_RELEASE_CODE) */ +extern int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); +#else +extern int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); +extern int pci_enable_msix_range(struct pci_dev *dev, + struct msix_entry *entries, + int minvec, + int maxvec); +#endif + +#endif /* _BF_KDRV_H_ */ From 3c4f3116a0099481983c14bac4c5f19be19d9d17 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Tue, 14 Apr 2020 19:55:08 +0300 Subject: [PATCH 0522/1427] [mellanox]: Enable CPLD update progress bar (#4363) Signed-off-by: Nazarii Hnydyn --- .../sonic_platform/component.py | 37 ++++--------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 468420eaf0aa..13e3953a03ad 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -14,7 +14,6 @@ import io import os import re - import sys except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -243,8 +242,7 @@ class ComponentCPLD(Component): CPLD_PART_NUMBER_DEFAULT = ZERO CPLD_VERSION_MINOR_DEFAULT = ZERO - CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} {}' - CPLD_INSTALL_SUCCESS_FLAG = 'PASS!' + CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} --print-progress {}' MST_DEVICE_PATTERN = '/dev/mst/mt[0-9]*_pci_cr0' @@ -303,7 +301,7 @@ def install_firmware(self, image_path): Details: The command "cpldupdate" is provided to install CPLD. There are two ways to do it: - 1. To burn CPLD via gpio, which is faster but only supported on new systems, like Anaconda, ... + 1. To burn CPLD via gpio, which is faster but only supported on new systems, like SN3700, ... 2. To install CPLD via firmware, which is slower but supported on older systems. This also requires the mst device designated. "cpldupdate --dev " has the logic of testing whether to update via gpio is supported, @@ -326,37 +324,16 @@ def install_firmware(self, image_path): return False cmdline = self.CPLD_UPDATE_COMMAND.format(mst_dev_list[0], image_path) - outputline = "" success_flag = False - try: - proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) - while True: - out = proc.stdout.read(1) - - if out == '' and proc.poll() != None: - break - - if out != '': - sys.stdout.write(out) - sys.stdout.flush() - outputline += out - - if (out == '\n' or out == '\r') and len(outputline): - m = re.search(self.CPLD_INSTALL_SUCCESS_FLAG, outputline) - if m and m.group(0) == self.CPLD_INSTALL_SUCCESS_FLAG: - success_flag = True - if proc.returncode: - print("ERROR: Upgrade CPLD failed, return code {}".format(proc.returncode)) - success_flag = False - - except OSError as e: - raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + try: + subprocess.check_call(cmdline, stderr=subprocess.STDOUT, shell=True) + success_flag = True + except subprocess.CalledProcessError as e: + print("ERROR: Failed to upgrade CPLD: rc={}".format(e.returncode)) if success_flag: print("INFO: Refresh or power cycle is required to finish CPLD installation") - else: - print("ERROR: Failed to install CPLD") return success_flag From cfa112ace8f587e68facecbaf1ffe18379ff6d87 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 14 Apr 2020 20:20:06 +0300 Subject: [PATCH 0523/1427] [Mellanox] Extend mellanox platform API to report SFP error event (#4365) * extend mellanox platform API to report SFP error event * remove unnecessary loop code * install enum34 to pmon to support using Enum --- dockers/docker-platform-monitor/Dockerfile.j2 | 3 +- .../sonic_platform/chassis.py | 15 +-- .../sonic_platform/sfp_event.py | 94 ++++++++++++++++--- 3 files changed, 86 insertions(+), 26 deletions(-) diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index 4f5f2b77141b..c1e86abb5170 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -17,7 +17,8 @@ RUN apt-get update && \ rrdtool \ python-smbus \ ethtool \ - dmidecode + dmidecode && \ + pip install enum34 {% if docker_platform_monitor_debs.strip() -%} # Copy locally-built Debian package dependencies diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 995d5cc8ae57..08c2ccf80a5c 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -448,25 +448,12 @@ def get_change_event(self, timeout=0): timeout = MAX_SELECT_DELAY while True: status = self.sfp_event.check_sfp_status(port_dict, timeout) - if not port_dict == {}: + if bool(port_dict): break else: status = self.sfp_event.check_sfp_status(port_dict, timeout) if status: - # get_change_event has the meaning of retrieving all the notifications through a single call. - # Typically this is implemented via a select framework which requires the underlay file-reading - # interface able to retrieve all notifications without blocking once the fd has been selected. - # However, sdk doesn't provide any interface satisfied the requirement. as a result, - # check_sfp_status returns only one notification may indicate more notifications in its queue. - # In this sense, we have to iterate in a loop to get all the notifications in case that - # the first call returns at least one. - i = 0 - while i < self.MAX_SELECT_EVENT_RETURNED: - status = self.sfp_event.check_sfp_status(port_dict, 0) - if not status: - break - i = i + 1 return True, {'sfp':port_dict} else: return True, {'sfp':{}} diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py index e92884fc3f33..0ed75c26c63a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py @@ -11,15 +11,69 @@ from python_sdk_api.sx_api import * from sonic_daemon_base.daemon_base import Logger -SDK_SFP_STATE_IN = 0x1 +# SFP status from PMAOS register +# 0x1 plug in +# 0x2 plug out +# 0x3 plug in with error +# 0x4 disabled, at this status SFP eeprom is not accessible, +# and presence status also will be not present, +# so treate it as plug out. +SDK_SFP_STATE_IN = 0x1 SDK_SFP_STATE_OUT = 0x2 +SDK_SFP_STATE_ERR = 0x3 +SDK_SFP_STATE_DIS = 0x4 + +# SFP status that will be handled by XCVRD STATUS_PLUGIN = '1' STATUS_PLUGOUT = '0' -STATUS_UNKNOWN = '2' +STATUS_ERR_I2C_STUCK = '2' +STATUS_ERR_BAD_EEPROM = '3' +STATUS_ERR_UNSUPPORTED_CABLE = '4' +STATUS_ERR_HIGH_TEMP = '5' +STATUS_ERR_BAD_CABLE = '6' + +# SFP status used in this file only, will not expose to XCVRD +# STATUS_ERROR will be mapped to different status according to the error code +STATUS_UNKNOWN = '-1' +STATUS_ERROR = '-2' + +# SFP error code, only valid when SFP at SDK_SFP_STATE_ERR status +# Only 0x2, 0x3, 0x5, 0x6 and 0x7 will block the eeprom access, +# so will only report above errors to XCVRD and other errors will be +# printed to syslog. + +''' +0x0: "Power_Budget_Exceeded", +0x1: "Long_Range_for_non_MLNX_cable_or_module", +0x2: "Bus_stuck", +0x3: "bad_or_unsupported_EEPROM", +0x4: "Enforce_part_number_list", +0x5: "unsupported_cable", +0x6: "High_Temperature", +0x7: "bad_cable", +0x8: "PMD_type_is_not_enabled", +0x9: "[internal]Laster_TEC_failure", +0xa: "[internal]High_current", +0xb: "[internal]High_voltage", +0xd: "[internal]High_power", +0xe: "[internal]Module_state_machine_fault", +0xc: "pcie_system_power_slot_Exceeded" +''' + +# SFP errors that will block eeprom accessing +sdk_sfp_err_type_dict = { + 0x2: STATUS_ERR_I2C_STUCK, + 0x3: STATUS_ERR_BAD_EEPROM, + 0x5: STATUS_ERR_UNSUPPORTED_CABLE, + 0x6: STATUS_ERR_HIGH_TEMP, + 0x7: STATUS_ERR_BAD_CABLE +} sfp_value_status_dict = { - SDK_SFP_STATE_IN: STATUS_PLUGIN, - SDK_SFP_STATE_OUT: STATUS_PLUGOUT, + SDK_SFP_STATE_IN: STATUS_PLUGIN, + SDK_SFP_STATE_OUT: STATUS_PLUGOUT, + SDK_SFP_STATE_ERR: STATUS_ERROR, + SDK_SFP_STATE_DIS: STATUS_PLUGOUT, } # system level event/error @@ -174,7 +228,7 @@ def check_sfp_status(self, port_change, timeout): for fd in read: if fd == self.rx_fd_p.fd: - success, port_list, module_state = self.on_pmpe(self.rx_fd_p) + success, port_list, module_state, error_type = self.on_pmpe(self.rx_fd_p) if not success: logger.log_error("failed to read from {}".format(fd)) break @@ -192,15 +246,23 @@ def check_sfp_status(self, port_change, timeout): found += 1 continue + # If get SFP status error(0x3) from SDK, then need to read the error_type to get the detailed error + if sfp_state == STATUS_ERROR: + if error_type in sdk_sfp_err_type_dict.keys(): + # In SFP at error status case, need to overwrite the sfp_state with the exact error code + sfp_state = sdk_sfp_err_type_dict[error_type] + else: + # For errors don't block the eeprom accessing, we don't report it to XCVRD + logger.log_info("SFP error on port but not blocking eeprom read, error_type {}".format(error_type)) + found +=1 + continue + for port in port_list: logger.log_info("SFP on port {} state {}".format(port, sfp_state)) port_change[port] = sfp_state found += 1 - if found == 0: - return False - else: - return True + return found != 0 def on_pmpe(self, fd_p): ''' on port module plug event handler ''' @@ -228,7 +290,17 @@ def on_pmpe(self, fd_p): port_list_size = pmpe_t.list_size logical_port_list = pmpe_t.log_port_list module_state = pmpe_t.module_state - + error_type = pmpe_t.error_type + module_id = pmpe_t.module_id + + if module_state == SDK_SFP_STATE_ERR: + logger.log_error("Receive PMPE error event on module {}: status {} error type {}".format(module_id, module_state, error_type)) + elif module_state == SDK_SFP_STATE_DIS: + logger.log_info("Receive PMPE disable event on module {}: status {}".format(module_id, module_state)) + elif module_state == SDK_SFP_STATE_IN or module_state == SDK_SFP_STATE_OUT: + logger.log_info("Receive PMPE plug in/out event on module {}: status {}".format(module_id, module_state)) + else: + logger.log_error("Receive PMPE unknown event on module {}: status {}".format(module_id, module_state)) for i in xrange(port_list_size): logical_port = sx_port_log_id_t_arr_getitem(logical_port_list, i) rc = sx_api_port_device_get(self.handle, 1 , 0, port_attributes_list, port_cnt_p) @@ -247,4 +319,4 @@ def on_pmpe(self, fd_p): delete_sx_port_attributes_t_arr(port_attributes_list) delete_uint32_t_p(port_cnt_p) - return status, label_port_list, module_state, + return status, label_port_list, module_state, error_type From e04eb806b6be9d7088e5cc488852a7b0475b9398 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 14 Apr 2020 20:27:27 +0300 Subject: [PATCH 0524/1427] [Mellanox] bug fix - adpt sfputil plugin to support ACS-MSN4700 (#4361) --- device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 07dbbe1cc21b..b5f2a335b09c 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -41,7 +41,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4} +hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700': 0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] def log_info(msg, also_print_to_console=False): From a02255e2f49fabca11fb51a2a8d83cbfa3ac9c1b Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Tue, 14 Apr 2020 15:36:02 -0700 Subject: [PATCH 0525/1427] [sonic-yang-models]: First version of yang models for Port, VLan, Interface, PortChannel, loopback and ACL. (#3730) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [sonic-yang-models]: First version of yang models for Port, VLan, Interface, PortChannel, loopback and ACL. YANG models as per Guidelines. Guideline doc: https://github.com/Azure/SONiC/blob/master/doc/mgmt/SONiC_YANG_Model_Guidelines.md [sonic-yang-models/tests]: YANG model test code and JSON input for testing. [sonic-yang-models/setup.py]: Build infra for yang models. **- What I did** Created Yang model for Sonic. Tables: PORT, VLAN, VLAN_INTERFACE, VLAN_MEMBER, ACL_RULE, ACL_TABLE, INTERFACE. Created build infra files using which a new package (sonic-yang-models) can be build and can be deployed on sonic switches. Yang models will be part of this new package. **- How I did it** Wrote yang models based on Guideline doc: https://github.com/Azure/SONiC/blob/master/doc/mgmt/SONiC_YANG_Model_Guidelines.md and https://github.com/Azure/SONiC/wiki/Configuration. Wrote python wheel Package infra which runs test for these Yang models using a json files which consists configuration as per yang models. These configs are for negative tests, which means we want to test that most must condition, pattern and when condition works as expected. **- How to verify it** Build Logs and testing: ——————————————————————————————————— ``` /sonic/src/sonic-yang-models /sonic running test running egg_info writing top-level names to sonic_yang_models.egg-info/top_level.txt writing dependency_links to sonic_yang_models.egg-info/dependency_links.txt writing sonic_yang_models.egg-info/PKG-INFO reading manifest file 'sonic_yang_models.egg-info/SOURCES.txt' writing manifest file 'sonic_yang_models.egg-info/SOURCES.txt' running build_ext ---------------------------------------------------------------------- Ran 0 tests in 0.000s OK running bdist_wheel running build running build_py (Reading database ... 155852 files and directories currently installed.) Preparing to unpack .../libyang_1.0.73_amd64.deb ... Unpacking libyang (1.0.73) over (1.0.73) ... Setting up libyang (1.0.73) ... Processing triggers for libc-bin (2.24-11+deb9u4) ... Processing triggers for man-db (2.7.6.1-2) ... (Reading database ... 155852 files and directories currently installed.) Preparing to unpack .../libyang-cpp_1.0.73_amd64.deb ... Unpacking libyang-cpp (1.0.73) over (1.0.73) ... Setting up libyang-cpp (1.0.73) ... Processing triggers for libc-bin (2.24-11+deb9u4) ... (Reading database ... 155852 files and directories currently installed.) Preparing to unpack .../python3-yang_1.0.73_amd64.deb ... Unpacking python3-yang (1.0.73) over (1.0.73) ... Setting up python3-yang (1.0.73) ... INFO:YANG-TEST:module: sonic-vlan is loaded successfully ERROR:YANG-TEST:Could not get module: sonic-head INFO:YANG-TEST:module: sonic-portchannel is loaded successfully INFO:YANG-TEST:module: sonic-acl is loaded successfully INFO:YANG-TEST:module: sonic-loopback-interface is loaded successfully ERROR:YANG-TEST:Could not get module: sonic-port INFO:YANG-TEST:module: sonic-interface is loaded successfully INFO:YANG-TEST: ------------------- Test 1: Configure a member port in VLAN_MEMBER table which does not exist.--------------------- libyang[0]: Leafref "/sonic-port:sonic-port/sonic-port:PORT/sonic-port:PORT_LIST/sonic-port:port_name" of value "Ethernet156" points to a non -existing leaf. (path: /sonic-vlan:sonic-vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlan_name='Vlan100'][port='Ethernet156']/port) INFO:YANG-TEST:Configure a member port in VLAN_MEMBER table which does not exist. Passed INFO:YANG-TEST: ------------------- Test 2: Configure non-existing ACL_TABLE in ACL_RULE.--------------------- libyang[0]: Leafref "/sonic-acl:sonic-acl/sonic-acl:ACL_TABLE/sonic-acl:ACL_TABLE_LIST/sonic-acl:ACL_TABLE_NAME" of value "NOT-EXIST" points to a non-existing leaf. (path: /sonic-acl:sonic-acl/ACL_RULE/ACL_RULE_LIST[ACL_TABLE_NAME='NOT-EXIST'][RULE_NAME='Rule_20']/ACL_TABLE_NAME) INFO:YANG-TEST:Configure non-existing ACL_TABLE in ACL_RULE. Passed INFO:YANG-TEST: ------------------- Test 3: Configure IP_TYPE as ARP and ICMPV6_CODE in ACL_RULE.--------------------- libyang[0]: When condition "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPv6ANY'])" not satisfied. (path: /sonic-acl:sonic-acl/ACL_RU LE/ACL_RULE_LIST[ACL_TABLE_NAME='NO-NSW-PACL-V4'][RULE_NAME='Rule_40']/ICMPV6_CODE) INFO:YANG-TEST:Configure IP_TYPE as ARP and ICMPV6_CODE in ACL_RULE. Passed INFO:YANG-TEST: INFO:YANG-TEST: ------------------- Test 4: Configure IP_TYPE as ipv4any and SRC_IPV6 in ACL_RULE.--------------------- libyang[0]: When condition "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPv6ANY'])" not satisfied. (path: /sonic-acl:sonic-acl/ACL_RU LE/ACL_RULE_LIST[ACL_TABLE_NAME='NO-NSW-PACL-V4'][RULE_NAME='Rule_20']/SRC_IPV6) INFO:YANG-TEST:Configure IP_TYPE as ipv4any and SRC_IPV6 in ACL_RULE. Passed ------------------- Test 5: Configure l4_src_port_range as 99999-99999 in ACL_RULE--------------------- libyang[0]: Value "99999-99999" does not satisfy the constraint "([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])-([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])" (range, length, or pattern). (path: /sonic-acl:sonic-acl/ACL_RULE/ACL_RULE_LIST[ACL_TABLE_NAME='NO-NSW-PACL-V6'][RULE_NAME='Rule_20']/L4_SRC_PORT_RANGE) INFO:YANG-TEST:Configure l4_src_port_range as 99999-99999 in ACL_RULE Passed INFO:YANG-TEST: ------------------- Test 6: Configure empty string as ip-prefix in INTERFACE table.--------------------- libyang[0]: Invalid value "" in "ip-prefix" element. (path: /sonic-interface:sonic-interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='']/ip-prefix) INFO:YANG-TEST:Configure empty string as ip-prefix in INTERFACE table. Passed INFO:YANG-TEST: ------------------- Test 7: Configure Wrong family with ip-prefix for VLAN_Interface Table--------------------- libyang[0]: Must condition "(contains(../ip-prefix, ':') and current()='IPv6') or (contains(../ip-prefix, '.') and current()='IPv4')" not satisfied. (path: /sonic-vlan:sonic-vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='100'][ip-prefix='2a04:5555:66:7777::1/64']/family) INFO:YANG-TEST:Configure Wrong family with ip-prefix for VLAN_Interface Table Passed INFO:YANG-TEST: ------------------- Test 8: Configure IP_TYPE as ARP and DST_IPV6 in ACL_RULE.--------------------- libyang[0]: When condition "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPV6ANY'])" not satisfied. (path: /sonic-acl:sonic-acl/ACL_RULE/ACL_RULE_LIST[ACL_TABLE_NAME='NO-NS W-PACL-V6'][RULE_NAME='Rule_20']/DST_IPV6) INFO:YANG-TEST:Configure IP_TYPE as ARP and DST_IPV6 in ACL_RULE. Passed INFO:YANG-TEST: ------------------- Test 9: Configure INNER_ETHER_TYPE as 0x080C in ACL_RULE.--------------------- libyang[0]: Value "0x080C" does not satisfy the constraint "(0x88CC|0x8100|0x8915|0x0806|0x0800|0x86DD|0x8847)" (range, length, or pattern). (path: /sonic-acl:sonic-acl/ACL_RULE/ACL_RULE_LIST[ACL_TABLE_NAME='NO-NSW-PACL-V4'][RULE_NAME='Rule_40']/INNER_ETHER_TYPE) INFO:YANG-TEST:Configure INNER_ETHER_TYPE as 0x080C in ACL_RULE. Passed INFO:YANG-TEST: ------------------- Test 10: Add dhcp_server which is not in correct ip-prefix format.--------------------- libyang[0]: Invalid value "10.186.72.566" in "dhcp_servers" element. (path: /sonic-vlan:sonic-vlan/VLAN/VLAN_LIST/dhcp_servers[.='10.186.72.566']) INFO:YANG-TEST:Add dhcp_server which is not in correct ip-prefix format. Passed INFO:YANG-TEST: ------------------- Test 11: Configure undefined acl_table_type in ACL_TABLE table.--------------------- libyang[0]: Invalid value "LAYER3V4" in "type" element. (path: /sonic-acl:sonic-acl/ACL_TABLE/ACL_TABLE_LIST[ACL_TABLE_NAME='NO-NSW-PACL-V6']/type) INFO:YANG-TEST:Configure undefined acl_table_type in ACL_TABLE table. Passed INFO:YANG-TEST: ------------------- Test 12: Configure undefined packet_action in ACL_RULE table.--------------------- libyang[0]: Invalid value "SEND" in "PACKET_ACTION" element. (path: /sonic-acl:sonic-acl/ACL_RULE/ACL_RULE_LIST/PACKET_ACTION) INFO:YANG-TEST:Configure undefined packet_action in ACL_RULE table. Passed INFO:YANG-TEST: ------------------- Test 13: Configure wrong value for tagging_mode.--------------------- libyang[0]: Invalid value "non-tagged" in "tagging_mode" element. (path: /sonic-vlan:sonic-vlan/VLAN_MEMBER/VLAN_MEMBER_LIST/tagging_mode) INFO:YANG-TEST:Configure wrong value for tagging_mode. Passed INFO:YANG-TEST: ------------------- Test 14: Configure vlan-id in VLAN_MEMBER table which does not exist in VLAN table.--------------------- libyang[0]: Leafref "../../../VLAN/VLAN_LIST/vlanid" of value "200" points to a non-existing leaf. (path: /sonic-vlan:sonic-vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='200'][port='Ethernet0']/vlanid) libyang[0]: Leafref "../../../VLAN/VLAN_LIST/vlanid" of value "200" points to a non-existing leaf. (path: /sonic-vlan:sonic-vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='200'][port='Ethernet0']/vlanid) INFO:YANG-TEST:Configure vlan-id in VLAN_MEMBER table which does not exist in VLAN table. Passed INFO:YANG-TEST:All Test Passed ../../target/debs/stretch/libyang0.16_0.16.105-1_amd64.deb installtion failed ../../target/debs/stretch/libyang-cpp0.16_0.16.105-1_amd64.deb installtion failed ../../target/debs/stretch/python2-yang_0.16.105-1_amd64.deb installtion failed YANG Tests passed Passed: pyang -f tree ./yang-models/*.yang > ./yang-models/sonic_yang_tree copying tests/yangModelTesting.py -> build/lib/tests copying tests/test_sonic_yang_models.py -> build/lib/tests copying tests/__init__.py -> build/lib/tests running egg_info writing top-level names to sonic_yang_models.egg-info/top_level.txt writing dependency_links to sonic_yang_models.egg-info/dependency_links.txt writing sonic_yang_models.egg-info/PKG-INFO reading manifest file 'sonic_yang_models.egg-info/SOURCES.txt' writing manifest file 'sonic_yang_models.egg-info/SOURCES.txt' installing to build/bdist.linux-x86_64/wheel running install running install_lib creating build/bdist.linux-x86_64/wheel creating build/bdist.linux-x86_64/wheel/tests copying build/lib/tests/yangModelTesting.py -> build/bdist.linux-x86_64/wheel/tests copying build/lib/tests/test_sonic_yang_models.py -> build/bdist.linux-x86_64/wheel/tests copying build/lib/tests/__init__.py -> build/bdist.linux-x86_64/wheel/tests running install_data creating build/bdist.linux-x86_64/wheel/sonic_yang_models-1.0.data creating build/bdist.linux-x86_64/wheel/sonic_yang_models-1.0.data/data creating build/bdist.linux-x86_64/wheel/sonic_yang_models-1.0.data/data/yang-models copying ./yang-models/sonic-head.yang -> build/bdist.linux-x86_64/wheel/sonic_yang_models-1.0.data/data/yang-models copying ./yang-models/sonic-acl.yang -> build/bdist.linux-x86_64/wheel/sonic_yang_models-1.0.data/data/yang-models copying ./yang-models/sonic-interface.yang -> build/bdist.linux-x86_64/wheel/sonic_yang_models-1.0.data/data/yang-models copying ./yang-models/sonic-loopback-interface.yang -> build/bdist.linux-x86_64/wheel/sonic_yang_models-1.0.data/data/yang-models copying ./yang-models/sonic-port.yang -> build/bdist.linux-x86_64/wheel/sonic_yang_models-1.0.data/data/yang-models copying ./yang-models/sonic-portchannel.yang -> build/bdist.linux-x86_64/wheel/sonic_yang_models-1.0.data/data/yang-models copying ./yang-models/sonic-vlan.yang -> build/bdist.linux-x86_64/wheel/sonic_yang_models-1.0.data/data/yang-models ``` --- .../build_templates/sonic_debian_extension.j2 | 9 + rules/sonic-yang-models-py3.mk | 7 + slave.mk | 9 +- sonic-slave-stretch/Dockerfile.j2 | 7 + src/sonic-yang-models/AUTHORS.rst | 14 + src/sonic-yang-models/LICENSE | 13 + src/sonic-yang-models/README.rst | 4 + src/sonic-yang-models/setup.py | 114 ++ src/sonic-yang-models/tests/__init__.py | 3 + .../tests/test_sonic_yang_models.py | 21 + .../yang_model_tests/yangModelTesting.py | 288 ++++ .../tests/yang_model_tests/yangTest.json | 1284 +++++++++++++++++ .../yang-models/sonic-acl.yang | 283 ++++ .../yang-models/sonic-extension.yang | 23 + .../yang-models/sonic-interface.yang | 122 ++ .../yang-models/sonic-loopback-interface.yang | 98 ++ .../yang-models/sonic-port.yang | 105 ++ .../yang-models/sonic-portchannel.yang | 92 ++ .../yang-models/sonic-types.yang | 92 ++ .../yang-models/sonic-vlan.yang | 209 +++ 20 files changed, 2795 insertions(+), 2 deletions(-) create mode 100644 rules/sonic-yang-models-py3.mk create mode 100644 src/sonic-yang-models/AUTHORS.rst create mode 100644 src/sonic-yang-models/LICENSE create mode 100644 src/sonic-yang-models/README.rst create mode 100644 src/sonic-yang-models/setup.py create mode 100644 src/sonic-yang-models/tests/__init__.py create mode 100644 src/sonic-yang-models/tests/test_sonic_yang_models.py create mode 100644 src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py create mode 100644 src/sonic-yang-models/tests/yang_model_tests/yangTest.json create mode 100644 src/sonic-yang-models/yang-models/sonic-acl.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-extension.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-interface.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-loopback-interface.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-port.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-portchannel.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-types.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-vlan.yang diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 49acd0647ad1..ba9595896022 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -116,6 +116,15 @@ sudo cp {{swsssdk_py2_wheel_path}} $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SWSSSDK_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME +# Install sonic-yang-models py3 package, install dependencies +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang_*.deb +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang-cpp_*.deb +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python2-yang_*.deb +SONIC_YANG_MODEL_PY3_WHEEL_NAME=$(basename {{sonic_yang_models_py3_wheel_path}}) +sudo cp {{sonic_yang_models_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MODEL_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_YANG_MODEL_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MODEL_PY3_WHEEL_NAME + # Install sonic-platform-common Python 2 package PLATFORM_COMMON_PY2_WHEEL_NAME=$(basename {{platform_common_py2_wheel_path}}) sudo cp {{platform_common_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME diff --git a/rules/sonic-yang-models-py3.mk b/rules/sonic-yang-models-py3.mk new file mode 100644 index 000000000000..d2bd01bb9005 --- /dev/null +++ b/rules/sonic-yang-models-py3.mk @@ -0,0 +1,7 @@ +SONIC_YANG_MODELS_PY3 = sonic_yang_models-1.0-py3-none-any.whl +$(SONIC_YANG_MODELS_PY3)_SRC_PATH = $(SRC_PATH)/sonic-yang-models +$(SONIC_YANG_MODELS_PY3)_PYTHON_VERSION = 3 +$(SONIC_YANG_MODELS_PY3)_DEBS_DEPENDS = $(LIBYANG) + +SONIC_PYTHON_WHEELS += $(SONIC_YANG_MODELS_PY3) +export SONIC_YANG_MODELS_PY3 diff --git a/slave.mk b/slave.mk index 01bb5df7de84..f2f2a8605c8b 100644 --- a/slave.mk +++ b/slave.mk @@ -49,6 +49,8 @@ export BUILD_NUMBER export BUILD_TIMESTAMP export CONFIGURED_PLATFORM export CONFIGURED_ARCH +export STRETCH_DEBS_PATH +export PYTHON_WHEELS_PATH ############################################################################### ## Utility rules @@ -525,7 +527,8 @@ SONIC_TARGET_LIST += $(addprefix $(PYTHON_DEBS_PATH)/, $(SONIC_PYTHON_STDEB_DEBS # $(SOME_NEW_WHL)_DEPENDS = $(SOME_OTHER_WHL1) $(SOME_OTHER_WHL2) ... # SONIC_PYTHON_WHEELS += $(SOME_NEW_WHL) $(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) : $(PYTHON_WHEELS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*_DEPENDS))) \ - $(call dpkg_depend,$(PYTHON_WHEELS_PATH)/%.dep) + $(call dpkg_depend,$(PYTHON_WHEELS_PATH)/%.dep) \ + $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEBS_DEPENDS))) $(HEADER) @@ -750,7 +753,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) $(HEADER) # Pass initramfs and linux kernel explicitly. They are used for all platforms export debs_path="$(STRETCH_DEBS_PATH)" @@ -780,6 +784,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" + export sonic_yang_models_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3))" export multi_instance="false" $(foreach docker, $($*_DOCKERS),\ diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index f9e96791464d..af5f441c8842 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -367,6 +367,13 @@ RUN pip install mockredispy==2.9.3 RUN pip install pytest-runner==4.4 RUN pip install setuptools==40.8.0 +# For sonic_yang_mgmt build +RUN pip install ijson==2.6.1 +RUN pip3 install ijson==2.6.1 +RUN pip install jsondiff==1.2.0 +RUN pip install xmltodict==0.12.0 +RUN pip install pyang==2.1.1 + # For mgmt-framework build RUN pip install mmh3 diff --git a/src/sonic-yang-models/AUTHORS.rst b/src/sonic-yang-models/AUTHORS.rst new file mode 100644 index 000000000000..43adb0900334 --- /dev/null +++ b/src/sonic-yang-models/AUTHORS.rst @@ -0,0 +1,14 @@ +======= +Credits +======= + +Development Lead +---------------- + +LNOS-CODERS +MSFT-LINUX-DEV + +Contributors +------------ + +Praveen Chaudhary diff --git a/src/sonic-yang-models/LICENSE b/src/sonic-yang-models/LICENSE new file mode 100644 index 000000000000..cf593b111eab --- /dev/null +++ b/src/sonic-yang-models/LICENSE @@ -0,0 +1,13 @@ +Copyright 2019 Microsoft, Inc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/src/sonic-yang-models/README.rst b/src/sonic-yang-models/README.rst new file mode 100644 index 000000000000..6cb6d091367b --- /dev/null +++ b/src/sonic-yang-models/README.rst @@ -0,0 +1,4 @@ +" +This Package contains YANG models for sonic which are written with guidelines mentioned in +https://github.com/Azure/SONiC/blob/master/doc/mgmt/SONiC_YANG_Model_Guidelines.md. +" diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py new file mode 100644 index 000000000000..d53d5fb901eb --- /dev/null +++ b/src/sonic-yang-models/setup.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""The setup script.""" + +from setuptools import setup, find_packages +from setuptools.command.build_py import build_py +from os import system, environ +from sys import exit + +# find path of pkgs from environment vars +prefix = '/sonic'; debs = environ["STRETCH_DEBS_PATH"] +deps_path = '{}/{}'.format(prefix, debs) +# dependencies +libyang = '{}/{}'.format(deps_path, environ["LIBYANG"]) +libyangCpp = '{}/{}'.format(deps_path, environ["LIBYANG_CPP"]) +libyangPy2 = '{}/{}'.format(deps_path, environ["LIBYANG_PY2"]) +libyangPy3 = '{}/{}'.format(deps_path, environ["LIBYANG_PY3"]) + +# important reuirements parameters +build_requirements = [libyang, libyangCpp, libyangPy2, libyangPy3,] + +setup_requirements = ['pytest-runner'] + +test_requirements = ['pytest>=3'] + +# read me +with open('README.rst') as readme_file: + readme = readme_file.read() + +# class for prerequisites to build this package +class pkgBuild(build_py): + """Custom Build PLY""" + + def run (self): + # install libyang + for req in build_requirements: + if '.deb'in req: + pkg_install_cmd = "sudo dpkg -i {}".format(req) + if (system(pkg_install_cmd)): + print("{} installation failed".format(req)) + exit(1) + else: + print("{} installed".format(req)) + + # json file for YANG model test cases. + test_yangJson_file = './tests/yang_model_tests/yangTest.json' + # YANG models are in below dir + yang_model_dir = './yang-models/' + # yang model tester python module + yang_test_py = './tests/yang_model_tests/yangModelTesting.py' + # run tests for yang models + test_yang_cmd = "python {} -f {} -y {}".format(yang_test_py, test_yangJson_file, yang_model_dir) + if (system(test_yang_cmd)): + print("YANG Tests failed\n") + # below line will be uncommented after libyang python support PR # + exit(1) + else: + print("YANG Tests passed\n") + + # Generate YANG Tree + pyang_tree_cmd = "pyang -f tree ./yang-models/*.yang > ./yang-models/sonic_yang_tree" + if (system(pyang_tree_cmd)): + print("Failed: {}".format(pyang_tree_cmd)) + else: + print("Passed: {}".format(pyang_tree_cmd)) + + # Continue usual build steps + build_py.run(self) + +setup( + cmdclass={ + 'build_py': pkgBuild, + }, + author="lnos-coders", + author_email='lnos-coders@linkedin.com', + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', + classifiers=[ + 'Development Status :: 2 - Pre-Alpha', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', + 'Natural Language :: English', + "Programming Language :: Python :: 2", + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + ], + description="Package contains YANG models for sonic.", + tests_require = test_requirements, + license="GNU General Public License v3", + long_description=readme + '\n\n', + include_package_data=True, + keywords='sonic_yang_models', + name='sonic_yang_models', + py_modules=[], + packages=find_packages(), + setup_requires=setup_requirements, + version='1.0', + data_files=[ + ('yang-models', ['./yang-models/sonic-types.yang', + './yang-models/sonic-extension.yang', + './yang-models/sonic-acl.yang', + './yang-models/sonic-interface.yang', + './yang-models/sonic-loopback-interface.yang', + './yang-models/sonic-port.yang', + './yang-models/sonic-portchannel.yang', + './yang-models/sonic-vlan.yang', + './yang-models/sonic_yang_tree']), + ], + zip_safe=False, +) diff --git a/src/sonic-yang-models/tests/__init__.py b/src/sonic-yang-models/tests/__init__.py new file mode 100644 index 000000000000..c116c5072b34 --- /dev/null +++ b/src/sonic-yang-models/tests/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +"""Unit test package for sonic_yang_models.""" diff --git a/src/sonic-yang-models/tests/test_sonic_yang_models.py b/src/sonic-yang-models/tests/test_sonic_yang_models.py new file mode 100644 index 000000000000..e8acedf9f974 --- /dev/null +++ b/src/sonic-yang-models/tests/test_sonic_yang_models.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Tests for `sonic_yang_models` package.""" + +import pytest + +@pytest.fixture +def response(): + """Sample pytest fixture. + + See more at: http://doc.pytest.org/en/latest/fixture.html + """ + # import requests + # return requests.get('https://github.com/audreyr/cookiecutter-pypackage') + + +def test_content(response): + """Sample pytest test function with the pytest fixture as an argument.""" + # from bs4 import BeautifulSoup + # assert 'GitHub' in BeautifulSoup(response.content).title.string diff --git a/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py b/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py new file mode 100644 index 000000000000..d36416adcae7 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py @@ -0,0 +1,288 @@ +# This script is used to + +import yang as ly +import logging +import argparse +import sys +import ijson +import json +#import sonic_yang as sy +from glob import glob +from os import listdir +from os.path import isfile, join, splitext + +#Globals vars +PASS = 0 +FAIL = 1 +logging.basicConfig(level=logging.DEBUG) +log = logging.getLogger("YANG-TEST") +log.setLevel(logging.INFO) +log.addHandler(logging.NullHandler()) + +# Global functions +def printExceptionDetails(): + try: + excType, excObj, traceBack = sys.exc_info() + fileName = traceBack.tb_frame.f_code.co_filename + lineNumber = traceBack.tb_lineno + log.error(" Exception >{}< in {}:{}".format(excObj, fileName, lineNumber)) + except Exception as e: + log.error(" Exception in printExceptionDetails") + return + +# class for YANG Model YangModelTesting +# Run function will run all the tests +# from a user given list. + +class YangModelTesting: + + def __init__(self, tests, yangDir, jsonFile): + self.defaultYANGFailure = { + 'Must': ['Must condition', 'not satisfied'], + 'InvalidValue': ['Invalid value'], + 'LeafRef': ['Leafref', 'non-existing'], + 'When': ['When condition', 'not satisfied'], + 'Pattern': ['pattern', 'does not satisfy'], + 'None': [''] + } + + self.ExceptionTests = { + 'WRONG_FAMILY_WITH_IP_PREFIX': { + 'desc': 'Configure Wrong family with ip-prefix for VLAN_Interface Table', + 'eStr': self.defaultYANGFailure['Must'] + }, + 'DHCP_SERVER_INCORRECT_FORMAT': { + 'desc': 'Add dhcp_server which is not in correct ip-prefix format.', + 'eStr': self.defaultYANGFailure['InvalidValue'] + ['dhcp_servers'] + }, + 'VLAN_WITH_NON_EXIST_PORT': { + 'desc': 'Configure a member port in VLAN_MEMBER table which does not exist.', + 'eStr': self.defaultYANGFailure['LeafRef'] + }, + 'VLAN_MEMEBER_WITH_NON_EXIST_VLAN': { + 'desc': 'Configure vlan-id in VLAN_MEMBER table which does not exist in VLAN table.', + 'eStr': self.defaultYANGFailure['LeafRef'] + }, + 'TAGGING_MODE_WRONG_VALUE': { + 'desc': 'Configure wrong value for tagging_mode.', + 'eStr': self.defaultYANGFailure['InvalidValue'] + ['tagging_mode'] + }, + 'INTERFACE_IP_PREFIX_EMPTY_STRING': { + 'desc': 'Configure empty string as ip-prefix in INTERFACE table.', + 'eStr': self.defaultYANGFailure['InvalidValue'] + ['ip-prefix'] + }, + 'ACL_RULE_UNDEFINED_PACKET_ACTION': { + 'desc': 'Configure undefined packet_action in ACL_RULE table.', + 'eStr': self.defaultYANGFailure['InvalidValue'] + ['PACKET_ACTION'] + }, + 'ACL_TABLE_UNDEFINED_TABLE_TYPE': { + 'desc': 'Configure undefined acl_table_type in ACL_TABLE table.', + 'eStr': self.defaultYANGFailure['InvalidValue'] + ['type'] + }, + 'ACL_RULE_WITH_NON_EXIST_ACL_TABLE': { + 'desc': 'Configure non-existing ACL_TABLE in ACL_RULE.', + 'eStr': self.defaultYANGFailure['LeafRef'] + }, + 'ACL_RULE_IP_TYPE_SRC_IPV6_MISMATCH': { + 'desc': 'Configure IP_TYPE as ipv4any and SRC_IPV6 in ACL_RULE.', + 'eStr': self.defaultYANGFailure['When'] + ['IP_TYPE'] + }, + 'ACL_RULE_ARP_TYPE_DST_IPV6_MISMATCH': { + 'desc': 'Configure IP_TYPE as ARP and DST_IPV6 in ACL_RULE.', + 'eStr': self.defaultYANGFailure['When'] + ['IP_TYPE'] + }, + 'ACL_RULE_WRONG_L4_SRC_PORT_RANGE': { + 'desc': 'Configure l4_src_port_range as 99999-99999 in ACL_RULE', + 'eStr': self.defaultYANGFailure['Pattern'] + }, + 'ACL_RULE_ARP_TYPE_ICMPV6_CODE_MISMATCH': { + 'desc': 'Configure IP_TYPE as ARP and ICMPV6_CODE in ACL_RULE.', + 'eStr': self.defaultYANGFailure['When'] + ['IP_TYPE'] + }, + 'ACL_RULE_WRONG_INNER_ETHER_TYPE': { + 'desc': 'Configure INNER_ETHER_TYPE as 0x080C in ACL_RULE.', + 'eStr': self.defaultYANGFailure['Pattern'] + }, + 'INTERFACE_IPPREFIX_PORT_MUST_CONDITION_FALSE': { + 'desc': 'Interface Ip-prefix port-name must condition failure.', + 'eStr': self.defaultYANGFailure['Must'] + }, + 'INTERFACE_IPPREFIX_PORT_MUST_CONDITION_TRUE': { + 'desc': 'Interface Ip-prefix port-name must condition pass.', + 'eStr': self.defaultYANGFailure['None'] + }, + 'VLAN_INTERFACE_IPPREFIX_MUST_CONDITION_FALSE': { + 'desc': 'Vlan Interface Ip-prefix must condition failure.', + 'eStr': self.defaultYANGFailure['Must'] + }, + 'LOOPBACK_IPPREFIX_PORT_MUST_CONDITION_FALSE': { + 'desc': 'Loopback Ip-prefix port-name must condition failure.', + 'eStr': self.defaultYANGFailure['Must'] + } + } + + self.tests = tests + if (self.tests == None): + self.tests = self.ExceptionTests.keys() + self.yangDir = yangDir + self.jsonFile = jsonFile + self.testNum = 1 + # other class vars + # self.ctx + return + + """ + load all YANG models before test run + """ + def loadYangModel(self, yangDir): + + try: + # create context + self.ctx = ly.Context(yangDir) + # get all files + yangFiles = glob(yangDir +"/*.yang") + # load yang modules + for file in yangFiles: + log.debug(file) + m = self.ctx.parse_module_path(file, ly.LYS_IN_YANG) + if m is not None: + log.info("module: {} is loaded successfully".format(m.name())) + else: + log.info("Could not load module: {}".format(file)) + + except Exception as e: + printExceptionDetails() + raise e + return + + """ + Run all tests from list self.tests + """ + def run(self): + try: + self.loadYangModel(self.yangDir) + ret = 0 + for test in self.tests: + test = test.strip() + if test in self.ExceptionTests: + ret = ret + self.runExceptionTest(test); + except Exception as e: + printExceptionDetails() + raise e + return ret + + """ + Get the JSON input based on func name + and return jsonInput + """ + def readJsonInput(self, test): + try: + # load test specific Dictionary, using Key = func + # this is to avoid loading very large JSON in memory + log.debug(" Read JSON Section: " + test) + jInput = "" + with open(self.jsonFile, 'rb') as f: + jInst = ijson.items(f, test) + for it in jInst: + jInput = jInput + json.dumps(it) + log.debug(jInput) + except Exception as e: + printExceptionDetails() + return jInput + + """ + Log the start of a test + """ + def logStartTest(self, desc): + log.info("\n------------------- Test "+ str(self.testNum) +\ + ": " + desc + "---------------------") + self.testNum = self.testNum + 1 + return + + """ + Load Config Data and return Exception as String + """ + def loadConfigData(self, jInput): + s = "" + try: + node = self.ctx.parse_data_mem(jInput, ly.LYD_JSON, \ + ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) + except Exception as e: + s = str(e) + log.debug(s) + return s + + """ + Run Exception Test + """ + def runExceptionTest(self, test): + try: + desc = self.ExceptionTests[test]['desc'] + self.logStartTest(desc) + jInput = self.readJsonInput(test) + # load the data, expect a exception with must condition failure + s = self.loadConfigData(jInput) + eStr = self.ExceptionTests[test]['eStr'] + log.debug(eStr) + if (sum(1 for str in eStr if str not in s) == 0): + log.info(desc + " Passed\n") + return PASS + except Exception as e: + printExceptionDetails() + log.info(desc + " Failed\n") + return FAIL + +# End of Class + +""" + Start Here +""" +def main(): + parser = argparse.ArgumentParser(description='Script to run YANG model tests', + formatter_class=argparse.RawTextHelpFormatter, + epilog=""" +Usage: +python yangModelTesting.py -h +""") + parser.add_argument('-t', '--tests', type=str, \ + help='tests to run separated by comma') + parser.add_argument('-f', '--json-file', type=str, \ + help='JSON input for tests ', required=True) + parser.add_argument('-y', '--yang-dir', type=str, \ + help='Path to YANG models', required=True) + parser.add_argument('-v', '--verbose-level', \ + help='Verbose mode', action='store_true') + parser.add_argument('-l', '--list-tests', \ + help='list all tests', action='store_true') + + args = parser.parse_args() + try: + tests = args.tests + jsonFile = args.json_file + yangDir = args.yang_dir + logLevel = args.verbose_level + listTests = args.list_tests + if logLevel: + log.setLevel(logging.DEBUG) + # Make a list + if (tests): + tests = tests.split(",") + + yTest = YangModelTesting(tests, yangDir, jsonFile) + if (listTests): + for key in yTest.ExceptionTests.keys(): + log.info(key) + sys.exit(0) + + ret = yTest.run() + if ret == 0: + log.info("All Test Passed") + sys.exit(ret) + + except Exception as e: + printExceptionDetails() + sys.exit(1) + + return +if __name__ == '__main__': + main() diff --git a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json new file mode 100644 index 000000000000..523eedf3c4b1 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json @@ -0,0 +1,1284 @@ +{ + "WRONG_FAMILY_WITH_IP_PREFIX": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN_INTERFACE": { + "VLAN_INTERFACE_LIST": [{ + "vlan_name": "Vlan100" + }], + "VLAN_INTERFACE_IPPREFIX_LIST": [{ + "vlan_name": "Vlan100", + "ip-prefix": "2a04:5555:66:7777::1/64", + "scope": "global", + "family": "IPv4" + }] + }, + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan" + }] + } + } + }, + + "DHCP_SERVER_INCORRECT_FORMAT": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan", + "dhcp_servers": [ + "10.186.72.566" + ], + "mtu": "9216", + "admin_status": "up" + }] + } + } + }, + + "VLAN_WITH_NON_EXIST_PORT": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [{ + "vlan_name": "Vlan100", + "port": "Ethernet156", + "tagging_mode": "tagged" + }] + }, + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan" + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "VLAN_MEMEBER_WITH_NON_EXIST_VLAN": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [{ + "vlan_name": "Vlan200", + "port": "Ethernet0", + "tagging_mode": "tagged" + }] + }, + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan" + }, + { + "vlan_name": "Vlan300", + "description": "ipmi_vlan" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }] + } + } + }, + + "TAGGING_MODE_WRONG_VALUE": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [{ + "vlan_name": 100, + "port": "Ethernet0", + "tagging_mode": "non-tagged" + }] + }, + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan" + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }] + } + } + }, + + "INTERFACE_IP_PREFIX_EMPTY_STRING": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_LIST": [{ + "port_name": "Ethernet8" + }], + "INTERFACE_IPPREFIX_LIST": [{ + "port_name": "Ethernet8", + "ip-prefix": "", + "scope": "global", + "family": "IPv4" + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet8", + "alias": "eth8", + "description": "Ethernet8", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }] + } + } + }, + + "ACL_RULE_UNDEFINED_PACKET_ACTION": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "SEND", + "DST_IP": "10.186.72.0/26", + "SRC_IP": "10.176.0.0/15", + "PRIORITY": 999980, + "IP_TYPE": "IPV4ANY" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv4", + "type": "L3", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_TABLE_UNDEFINED_TABLE_TYPE": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V6", + "policy_desc": "Filter IPv6", + "type": "LAYER3V4", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_RULE_WITH_NON_EXIST_ACL_TABLE": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NOT-EXIST", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.186.72.0/26", + "SRC_IP": "10.176.0.0/15", + "PRIORITY": 999980, + "IP_TYPE": "IPv4ANY" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv6", + "type": "L3", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_RULE_IP_TYPE_SRC_IPV6_MISMATCH": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "SRC_IPV6": "2001::1/64", + "PRIORITY": 999980, + "IP_TYPE": "IPv4ANY" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv4", + "type": "L3", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_RULE_ARP_TYPE_DST_IPV6_MISMATCH": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V6", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "DST_IPV6": "2001::2/64", + "PRIORITY": 999980, + "IP_TYPE": "ARP" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V6", + "policy_desc": "Filter IPv6", + "type": "L3V6", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_RULE_WRONG_L4_SRC_PORT_RANGE": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V6", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IP", + "SRC_IPV6": "2a04:f547:41::/48", + "PRIORITY": 999980, + "DST_IPV6": "2a04:f547:43:320::/64", + "L4_SRC_PORT_RANGE": "99999-99999" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V6", + "policy_desc": "Filter IPv6", + "type": "L3V6", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "VLAN_INTERFACE_IPPREFIX_MUST_CONDITION_FALSE": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN_INTERFACE": { + "VLAN_INTERFACE_IPPREFIX_LIST": [{ + "vlan_name": "Vlan100", + "ip-prefix": "2a04:5555:66:7777::1/64", + "scope": "global", + "family": "IPv6" + }] + }, + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan" + }] + } + } + }, + + "LOOPBACK_IPPREFIX_PORT_MUST_CONDITION_FALSE": { + "sonic-loopback-interface:sonic-loopback-interface": { + "sonic-loopback-interface:LOOPBACK_INTERFACE": { + "LOOPBACK_INTERFACE_IPPREFIX_LIST": [{ + "loopback_interface_name": "lo1", + "ip-prefix": "2a04:5555:66:7777::1/64", + "scope": "global", + "family": "IPv6" + }] + } + } + }, + + "INTERFACE_IPPREFIX_PORT_MUST_CONDITION_FALSE": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_LIST": [{ + "port_name": "Ethernet9" + }], + "INTERFACE_IPPREFIX_LIST": [{ + "port_name": "Ethernet8", + "ip-prefix": "10.0.0.1/30", + "scope": "global", + "family": "IPv4" + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet8", + "alias": "eth8", + "description": "Ethernet8", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet9", + "alias": "eth9", + "description": "Ethernet9", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }] + } + } + }, + + "INTERFACE_IPPREFIX_PORT_MUST_CONDITION_TRUE": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_LIST": [{ + "port_name": "Ethernet8" + }], + "INTERFACE_IPPREFIX_LIST": [{ + "port_name": "Ethernet8", + "ip-prefix": "10.0.0.1/30", + "scope": "global", + "family": "IPv4" + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet8", + "alias": "eth8", + "description": "Ethernet8", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }] + } + } + }, + + "ACL_RULE_ARP_TYPE_ICMPV6_CODE_MISMATCH": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "RULE_NAME": "Rule_40", + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.186.72.64/26", + "SRC_IP": "10.176.0.0/15", + "PRIORITY": 999960, + "ICMPV6_CODE": 5, + "IP_TYPE": "ARP", + "INNER_ETHER_TYPE": "0x88CC" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv4", + "type": "L3", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_RULE_WRONG_INNER_ETHER_TYPE": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "RULE_NAME": "Rule_40", + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.186.72.64/26", + "SRC_IP": "10.176.0.0/15", + "PRIORITY": 999960, + "IP_TYPE": "ARP", + "INNER_ETHER_TYPE": "0x080C" + + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv4", + "type": "L3", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "SAMPLE_CONFIG_DB_JSON": { + "VLAN_INTERFACE": { + "Vlan111": {}, + "Vlan777": {}, + "Vlan111|2a04:5555:45:6709::1/64": { + "scope": "global", + "family": "IPv6" + }, + "Vlan111|10.222.10.65/26": { + "scope": "global", + "family": "IPv4" + }, + "Vlan111|fe80::1/10": { + "scope": "local", + "family": "IPv6" + }, + "Vlan777|2a04:5555:41:4e9::1/64": { + "scope": "global", + "family": "IPv6" + }, + "Vlan777|10.111.58.65/26": { + "scope": "global", + "family": "IPv4" + }, + "Vlan777|fe80::1/10": { + "scope": "local", + "family": "IPv6" + } + }, + "ACL_RULE": { + "V4-ACL-TABLE|DEFAULT_DENY": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv4ANY", + "PRIORITY": "0" + }, + "V4-ACL-TABLE|Rule_20": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.72.0/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777780", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_40": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.72.64/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777760", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_60": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.80.0/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777740", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_80": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.80.64/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777720", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_111": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.152.17.52/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777700", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_120": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.252.208.41/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777880", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_140": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.148.128.245/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777860", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_160": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.1.245/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777840", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_180": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.252.222.21/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777820", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_9000": { + "PACKET_ACTION": "DROP", + "DST_IP": "0.0.0.0/0", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "991110", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_11100": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "0.0.0.0/0", + "SRC_IP": "0.0.0.0/0", + "PRIORITY": "990000", + "IP_TYPE": "IPv4ANY" + }, + "V6-ACL-TBLE|DEFAULT_DENY": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv6ANY", + "PRIORITY": "0" + }, + "V6-ACL-TBLE|Rule_20": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777780", + "DST_IPV6": "2a04:5555:43:320::/64" + }, + "V6-ACL-TBLE|Rule_40": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777760", + "DST_IPV6": "2a04:5555:43:321::/64" + }, + "V6-ACL-TBLE|Rule_60": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777740", + "DST_IPV6": "2a04:5555:43:340::/64" + }, + "V6-ACL-TBLE|Rule_80": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777720", + "DST_IPV6": "2a04:5555:43:341::/64" + }, + "V6-ACL-TBLE|Rule_111": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777700", + "DST_IPV6": "2a04:5555:32:12::/64" + }, + "V6-ACL-TBLE|Rule_9000": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "991110", + "DST_IPV6": "::/0" + }, + "V6-ACL-TBLE|Rule_11100": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "::/0", + "PRIORITY": "990000", + "DST_IPV6": "::/0" + } + }, + "DEVICE_METADATA": { + "localhost": { + "type": "ToR", + "mac": "00:11:22:33:dd:5a", + "hostname": "asw.dc", + "bgp_asn": "64850", + "hwsku": "Stone" + } + }, + "VLAN": { + "Vlan111": { + "description": "svlan", + "dhcp_servers": [ + "10.222.72.116" + ], + "vlanid": "111", + "mtu": "9216", + "admin_status": "up", + "members": [ + "Ethernet8", + "Ethernet3", + "Ethernet0", + "Ethernet1", + "Ethernet6", + "Ethernet4", + "Ethernet5", + "Ethernet9", + "Ethernet2", + "Ethernet7", + "Ethernet32", + "Ethernet30", + "Ethernet31", + "Ethernet36", + "Ethernet34", + "Ethernet33", + "Ethernet35", + "Ethernet29", + "Ethernet21", + "Ethernet20", + "Ethernet23", + "Ethernet22", + "Ethernet27", + "Ethernet26", + "Ethernet18", + "Ethernet19", + "Ethernet14", + "Ethernet15", + "Ethernet16", + "Ethernet17", + "Ethernet10", + "Ethernet11", + "Ethernet12", + "Ethernet13", + "Ethernet28" + ] + }, + "Vlan777": { + "description": "pvlan", + "dhcp_servers": [ + "10.222.72.116" + ], + "vlanid": "777", + "mtu": "9216", + "admin_status": "up", + "members": [ + "Ethernet9", + "Ethernet2", + "Ethernet8", + "Ethernet27", + "Ethernet14", + "Ethernet35" + ] + } + }, + "DEVICE_NEIGHBOR": { + "Ethernet112": { + "name": "dccsw01.nw", + "port": "Eth18" + }, + "Ethernet114": { + "name": "dccsw02.nw", + "port": "Eth18" + }, + "Ethernet116": { + "name": "dccsw03.nw", + "port": "Eth18" + }, + "Ethernet118": { + "name": "dccsw04.nw", + "port": "Eth18" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1/1", + "lanes": "65", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet1": { + "alias": "Eth1/2", + "lanes": "66", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet2": { + "alias": "Eth1/3", + "lanes": "67", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet3": { + "alias": "Eth1/4", + "lanes": "68", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet4": { + "alias": "Eth2/1", + "lanes": "69", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet5": { + "alias": "Eth2/2", + "lanes": "70", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet6": { + "alias": "Eth2/3", + "lanes": "71", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet7": { + "alias": "Eth2/4", + "lanes": "72", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet8": { + "alias": "Eth3/1", + "lanes": "73", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet9": { + "alias": "Eth3/2", + "lanes": "74", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet10": { + "alias": "Eth3/3", + "lanes": "75", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet11": { + "alias": "Eth3/4", + "lanes": "76", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet12": { + "alias": "Eth4/1", + "lanes": "77", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet13": { + "alias": "Eth4/2", + "lanes": "78", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet14": { + "alias": "Eth4/3", + "lanes": "79", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet15": { + "alias": "Eth4/4", + "lanes": "80", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet16": { + "alias": "Eth5/1", + "lanes": "33", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet17": { + "alias": "Eth5/2", + "lanes": "34", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet18": { + "alias": "Eth5/3", + "lanes": "35", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet19": { + "alias": "Eth5/4", + "lanes": "36", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet20": { + "alias": "Eth6/1", + "lanes": "37", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet21": { + "alias": "Eth6/2", + "lanes": "38", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet22": { + "alias": "Eth6/3", + "lanes": "39", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet23": { + "alias": "Eth6/4", + "lanes": "40", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet24": { + "alias": "Eth7/1", + "lanes": "41", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet25": { + "alias": "Eth7/2", + "lanes": "42", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet26": { + "alias": "Eth7/3", + "lanes": "43", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet27": { + "alias": "Eth7/4", + "lanes": "44", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet28": { + "alias": "Eth8/1", + "lanes": "45", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet29": { + "alias": "Eth8/2", + "lanes": "46", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet30": { + "alias": "Eth8/3", + "lanes": "47", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet31": { + "alias": "Eth8/4", + "lanes": "48", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet32": { + "alias": "Eth9/1", + "lanes": "49", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet33": { + "alias": "Eth9/2", + "lanes": "50", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet34": { + "alias": "Eth9/3", + "lanes": "51", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet35": { + "alias": "Eth9/4", + "lanes": "52", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet36": { + "alias": "Eth10/1", + "lanes": "53", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet112": { + "alias": "Eth29/1", + "lanes": "113,114", + "description": "50G|dccsw01.nw|Eth18", + "fec": "fc", + "speed": "11100", + "admin_status": "up" + } + }, + "ACL_TABLE": { + "V4-ACL-TABLE": { + "type": "L3", + "policy_desc": "V4-ACL-TABLE", + "ports": [ + "Ethernet26", + "Ethernet27", + "Ethernet24" + ] + }, + "V6-ACL-TBLE": { + "type": "L3V6", + "policy_desc": "V6-ACL-TBLE", + "ports": [ + "Ethernet14", + "Ethernet15", + "Ethernet23", + "Ethernet30", + "Ethernet31", + "Ethernet18", + "Ethernet19", + "Ethernet25", + "Ethernet24" + ] + } + }, + "INTERFACE": { + "Ethernet112": {}, + "Ethernet14": {}, + "Ethernet16": {}, + "Ethernet18": {}, + "Ethernet112|2a04:5555:40:a709::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet112|10.184.228.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet14|2a04:5555:40:a749::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet14|10.184.229.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet16|2a04:5555:40:a789::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet16|10.184.230.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet18|2a04:5555:40:a7c9::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet18|10.184.231.211/31": { + "scope": "global", + "family": "IPv4" + } + }, + "VLAN_MEMBER": { + "Vlan111|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet1": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet2": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet3": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet5": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet6": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet29": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet30": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet31": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet32": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet33": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet34": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet35": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet36": { + "tagging_mode": "untagged" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|2a04:5555:40:4::4e9/128": { + "scope": "global", + "family": "IPv6" + }, + "Loopback0|10.184.8.233/32": { + "scope": "global", + "family": "IPv4" + } + }, + "CRM": { + "Config": { + "polling_interval": "0" + } + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-acl.yang b/src/sonic-yang-models/yang-models/sonic-acl.yang new file mode 100644 index 000000000000..ec8a485b4829 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-acl.yang @@ -0,0 +1,283 @@ +module sonic-acl { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-acl"; + prefix acl; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + import sonic-port { + prefix port; + revision-date 2019-07-01; + } + + import sonic-portchannel { + prefix lag; + revision-date 2019-07-01; + } + + description "ACL YANG Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + container sonic-acl { + + container ACL_RULE { + + description "ACL_RULE part of config_db.json"; + + list ACL_RULE_LIST { + + key "ACL_TABLE_NAME RULE_NAME"; + + ext:key-regex-configdb-to-yang "^([a-zA-Z0-9_-]+)|([a-zA-Z0-9_-]+)$"; + + ext:key-regex-yang-to-configdb "|"; + + leaf ACL_TABLE_NAME { + type leafref { + path "/acl:sonic-acl/acl:ACL_TABLE/acl:ACL_TABLE_LIST/acl:ACL_TABLE_NAME"; + } + } + + leaf RULE_NAME { + type string { + length 1..255; + } + } + + leaf PACKET_ACTION { + type stypes:packet_action; + } + + leaf IP_TYPE { + type stypes:ip_type; + } + + leaf PRIORITY { + type uint32 { + range 0..999999; + } + } + + choice ip_prefix { + + case ip4_prefix { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPv4ANY' or .='ARP'])"; + leaf SRC_IP { + type inet:ipv4-prefix; + } + + leaf DST_IP { + type inet:ipv4-prefix; + } + } + + case ip6_prefix { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPv6ANY'])"; + leaf SRC_IPV6 { + type inet:ipv6-prefix; + } + + leaf DST_IPV6 { + type inet:ipv6-prefix; + } + } + } + + leaf-list IN_PORTS { + /* Values in leaf list are UNIQUE */ + type uint16; + } + + leaf-list OUT_PORTS { + /* Values in leaf list are UNIQUE */ + type uint16; + } + + choice src_port { + case l4_src_port { + leaf L4_SRC_PORT { + type uint16; + } + } + + case l4_src_port_range { + leaf L4_SRC_PORT_RANGE { + type string { + pattern '([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])-([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])'; + } + } + } + } + + choice dst_port { + case l4_dst_port { + leaf L4_DST_PORT { + type uint16; + } + } + + case l4_dst_port_range { + leaf L4_DST_PORT_RANGE { + type string { + pattern '([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])-([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])'; + } + } + } + } + + leaf ETHER_TYPE { + type string { + pattern "(0x88CC|0x8100|0x8915|0x0806|0x0800|0x86DD|0x8847)"; + } + } + + leaf IP_PROTOCOL { + type uint8 { + range 1..143; + } + } + + leaf TCP_FLAGS { + type string { + pattern '0[x][0-9a-fA-F]{1,2}|0[X][0-9a-fA-F]{1,2}'; + } + } + + leaf DSCP { + type uint8; + } + + leaf TC { + type uint8; + } + + choice icmp { + + case icmp4 { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPv4ANY' or .='ARP'])"; + leaf ICMP_TYPE { + type uint8 { + range 1..44; + } + } + + leaf ICMP_CODE { + type uint8 { + range 1..16; + } + } + } + + case icmp6 { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPv6ANY'])"; + leaf ICMPV6_TYPE { + type uint8 { + range 1..44; + } + } + + leaf ICMPV6_CODE { + type uint8 { + range 1..16; + } + } + } + } + + leaf INNER_ETHER_TYPE { + type string { + pattern "(0x88CC|0x8100|0x8915|0x0806|0x0800|0x86DD|0x8847)"; + } + } + + leaf INNER_IP_PROTOCOL { + type uint8 { + range 1..143; + } + } + + leaf INNER_L4_SRC_PORT { + type uint16; + } + + leaf INNER_L4_DST_PORT { + type uint16; + } + } + /* end of ACL_RULE_LIST */ + } + /* end of container ACL_RULE */ + + container ACL_TABLE { + + description "ACL_TABLE part of config_db.json"; + + list ACL_TABLE_LIST { + + key "ACL_TABLE_NAME"; + + ext:key-regex-configdb-to-yang "^([a-zA-Z0-9-_]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf ACL_TABLE_NAME { + type string; + } + + leaf policy_desc { + type string { + length 1..255; + } + } + + leaf type { + type stypes:acl_table_type; + } + + leaf stage { + type enumeration { + enum INGRESS; + enum EGRESS; + } + } + + leaf-list ports { + /* union of leafref is allowed in YANG 1.1 */ + type union { + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + type leafref { + path /lag:sonic-portchannel/lag:PORTCHANNEL/lag:PORTCHANNEL_LIST/lag:portchannel_name; + } + } + } + } + /* end of ACL_TABLE_LIST */ + } + /* end of container ACL_TABLE */ + } + /* end of container sonic-acl */ +} +/* end of module sonic-acl */ diff --git a/src/sonic-yang-models/yang-models/sonic-extension.yang b/src/sonic-yang-models/yang-models/sonic-extension.yang new file mode 100644 index 000000000000..5632e893d9ca --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-extension.yang @@ -0,0 +1,23 @@ +module sonic-extension { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-extension"; + prefix sonic-extension; + + description "Extension yang Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + extension key-regex-configdb-to-yang { + description "Key regex used to convert config DB keys to YANG Config"; + argument "value"; + } + + extension key-regex-yang-to-configdb { + description "Key regex used to convert config DB keys to YANG Config"; + argument "value"; + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-interface.yang b/src/sonic-yang-models/yang-models/sonic-interface.yang new file mode 100644 index 000000000000..d47268be69f9 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-interface.yang @@ -0,0 +1,122 @@ +module sonic-interface { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-interface"; + prefix intf; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + import sonic-port { + prefix port; + revision-date 2019-07-01; + } + + description "INTERFACE yang Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + container sonic-interface { + + container INTERFACE { + + description "INTERFACE part of config_db.json"; + + list INTERFACE_LIST { + + description "INTERFACE part of config_db.json with vrf"; + + key "port_name"; + + ext:key-regex-configdb-to-yang "^(Ethernet[0-9]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf port_name { + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf vrf_name { + type string { + pattern "Vrf[a-zA-Z0-9_-]+"; + length 3..255; + } + } + } + /* end of INTERFACE_LIST */ + + list INTERFACE_IPPREFIX_LIST { + + description "INTERFACE part of config_db.json with ip-prefix"; + + key "port_name ip-prefix"; + + ext:key-regex-configdb-to-yang "^(Ethernet[0-9]+)|([a-fA-F0-9:./]+)$"; + + ext:key-regex-yang-to-configdb "|"; + + leaf port_name { + /* This node must be present in INTERFACE_LIST */ + must "(current() = ../../INTERFACE_LIST[port_name=current()]/port_name)" + { + error-message "Must condition not satisfied, Try adding PORT: {}, Example: 'Ethernet0': {}"; + } + + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf ip-prefix { + type union { + type stypes:sonic-ip4-prefix; + type stypes:sonic-ip6-prefix; + } + } + + leaf scope { + type enumeration { + enum global; + enum local; + } + } + + leaf family { + + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6021, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type stypes:ip-family; + } + } + /* end of INTERFACE_IPPREFIX_LIST */ + + } + /* end of INTERFACE container */ + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang b/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang new file mode 100644 index 000000000000..92b059af64ca --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang @@ -0,0 +1,98 @@ +module sonic-loopback-interface { + + namespace "http://github.com/Azure/sonic-loopback-interface"; + prefix lointf; + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + description + "SONIC LOOPBACK INTERFACE"; + + revision 2020-02-05 { + description "First Revision"; + } + + container sonic-loopback-interface { + + container LOOPBACK_INTERFACE { + + list LOOPBACK_INTERFACE_LIST { + key "loopback_interface_name"; + + ext:key-regex-configdb-to-yang "^([a-zA-Z0-9-_]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf loopback_interface_name{ + type string; + } + + leaf vrf_name { + type string { + pattern "Vrf[a-zA-Z0-9_-]+"; + length 3..255; + } + } + } + /* end of LOOPBACK_INTERFACE_LIST */ + + list LOOPBACK_INTERFACE_IPPREFIX_LIST { + + key "loopback_interface_name ip-prefix"; + + ext:key-regex-configdb-to-yang "^([a-zA-Z0-9-_]+)|([a-fA-F0-9:./]+$)"; + + ext:key-regex-yang-to-configdb "|"; + + leaf loopback_interface_name{ + /* This node must be present in LOOPBACK_INTERFACE_LIST */ + must "(current() = ../../LOOPBACK_INTERFACE_LIST[loopback_interface_name=current()]/loopback_interface_name)" + { + error-message "Must condition not satisfied, Try adding lo<>: {}, Example: 'lo1': {}"; + } + type string; + } + + leaf ip-prefix { + type union { + type stypes:sonic-ip4-prefix; + type stypes:sonic-ip6-prefix; + } + } + + leaf scope { + type enumeration { + enum global; + enum local; + } + } + + leaf family { + + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6021, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type stypes:ip-family; + } + } + } + /* end of LOOPBACK_INTERFACE_IPPREFIX_LIST */ + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-port.yang b/src/sonic-yang-models/yang-models/sonic-port.yang new file mode 100644 index 000000000000..88fcf72dadbc --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-port.yang @@ -0,0 +1,105 @@ +module sonic-port{ + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-port"; + prefix port; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + description "PORT yang Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + container sonic-port{ + + container PORT { + + description "PORT part of config_db.json"; + + list PORT_LIST { + + key "port_name"; + + ext:key-regex-configdb-to-yang "^(Ethernet[0-9]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf port_name { + type string { + length 1..128; + } + } + + leaf alias { + type string { + length 1..128; + } + } + + leaf lanes { + mandatory true; + type string { + length 1..128; + } + } + + leaf description { + type string { + length 0..255; + } + } + + leaf speed { + mandatory true; + type uint32 { + range 1..100000; + } + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf index { + type uint16 { + range 0..256; + } + } + + leaf admin_status { + type stypes:admin_status; + } + + leaf fec { + type string { + pattern "rc|fc|None"; + } + } + } /* end of list PORT_LIST */ + + } /* end of container PORT */ + + } /* end of container sonic-port */ + +} /* end of module sonic-port */ diff --git a/src/sonic-yang-models/yang-models/sonic-portchannel.yang b/src/sonic-yang-models/yang-models/sonic-portchannel.yang new file mode 100644 index 000000000000..8f758fd51c81 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-portchannel.yang @@ -0,0 +1,92 @@ +module sonic-portchannel { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-portchannel"; + prefix lag; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + import sonic-port { + prefix port; + revision-date 2019-07-01; + } + + description "PORTCHANNEL yang Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + container sonic-portchannel { + container PORTCHANNEL { + + description "PORTCHANNEL part of config_db.json"; + + list PORTCHANNEL_LIST { + + key "portchannel_name"; + + ext:key-regex-configdb-to-yang "^(Ethernet[0-9]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf portchannel_name { + type string { + length 1..128; + pattern 'PortChannel[0-9]{1,4}'; + } + } + + leaf-list members { + /* leaf-list members are unique by default */ + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf min_links { + type uint8 { + range 1..128; + } + } + + leaf description { + type string { + length 1..255; + } + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf admin_status { + mandatory true; + type stypes:admin_status; + } + } /* end of list PORTCHANNEL_LIST */ + + } /* end of container PORTCHANNEL */ + + } /* end of container sonic-portchannel */ + +} /* end of module sonic-port */ diff --git a/src/sonic-yang-models/yang-models/sonic-types.yang b/src/sonic-yang-models/yang-models/sonic-types.yang new file mode 100644 index 000000000000..fb651847582e --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-types.yang @@ -0,0 +1,92 @@ +module sonic-types { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-head"; + prefix sonic-types; + + description "SONiC type for yang Models of SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + typedef ip-family { + type enumeration { + enum IPv4; + enum IPv6; + } + } + + typedef sonic-ip4-prefix { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '/(([0-9])|([1-2][0-9])|(3[0-2]))'; + } + } + + typedef sonic-ip6-prefix { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(/.+)'; + } + } + + typedef admin_status { + type enumeration { + enum up; + enum down; + } + } + + typedef packet_action{ + type enumeration { + enum DROP; + enum FORWARD; + enum REDIRECT; + } + } + + typedef ip_type { + type enumeration { + enum ANY; + enum IP; + enum NON_IP; + enum IPV4; + enum IPV6; + enum IPv4ANY; + enum NON_IP4; + enum IPv6ANY; + enum NON_IPv6; + enum ARP; + } + } + + typedef acl_table_type { + type enumeration { + enum L2; + enum L3; + enum L3V6; + enum MIRROR; + enum MIRRORV6; + enum MIRROR_DSCP; + enum CTRLPLANE; + } + } + + typedef vlan_tagging_mode { + type enumeration { + enum tagged; + enum untagged; + enum priority_tagged; + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-vlan.yang b/src/sonic-yang-models/yang-models/sonic-vlan.yang new file mode 100644 index 000000000000..4c3aecaf8106 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-vlan.yang @@ -0,0 +1,209 @@ +module sonic-vlan { + + namespace "http://github.com/Azure/sonic-vlan"; + prefix vlan; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + import sonic-port { + prefix port; + revision-date 2019-07-01; + } + + description "VLAN yang Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + container sonic-vlan { + + container VLAN_INTERFACE { + + description "VLAN_INTERFACE part of config_db.json"; + + list VLAN_INTERFACE_LIST { + + description "VLAN INTERFACE part of config_db.json with vrf"; + + key "vlan_name"; + + ext:key-regex-configdb-to-yang "^(Vlan[a-zA-Z0-9_-]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf vlan_name { + type leafref { + path /vlan:sonic-vlan/vlan:VLAN/vlan:VLAN_LIST/vlan:vlan_name; + } + } + + leaf vrf_name { + type string { + pattern "Vrf[a-zA-Z0-9_-]+"; + length 3..255; + } + } + } + /* end of VLAN_INTERFACE_LIST */ + + list VLAN_INTERFACE_IPPREFIX_LIST { + + key "vlan_name ip-prefix"; + + ext:key-regex-configdb-to-yang "^(Vlan[a-zA-Z0-9_-]+)|([a-fA-F0-9:./]+$)"; + + ext:key-regex-yang-to-configdb "|"; + + leaf vlan_name { + /* This node must be present in VLAN_INTERFACE_LIST */ + must "(current() = ../../VLAN_INTERFACE_LIST[vlan_name=current()]/vlan_name)" + { + error-message "Must condition not satisfied, Try adding Vlan: {}, Example: 'Vlan100': {}"; + } + + type leafref { + path "/vlan:sonic-vlan/vlan:VLAN/vlan:VLAN_LIST/vlan:vlan_name"; + } + } + + leaf ip-prefix { + type union { + type stypes:sonic-ip4-prefix; + type stypes:sonic-ip6-prefix; + } + } + + leaf scope { + type enumeration { + enum global; + enum local; + } + } + + leaf family { + + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6021, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type stypes:ip-family; + } + } + /* end of VLAN_INTERFACE_LIST */ + } + /* end of VLAN_INTERFACE container */ + + container VLAN { + + description "VLAN part of config_db.json"; + + list VLAN_LIST { + + key "vlan_name"; + + ext:key-regex-configdb-to-yang "^(Vlan[a-zA-Z0-9_-]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf vlan_name { + type string { + pattern 'Vlan([0-9]{1,3}|[0-3][0-9]{4}|[4][0][0-8][0-9]|[4][0][9][0-4])'; + } + } + + leaf vlanid { + type uint16 { + range 1..4094; + } + } + + leaf description { + type string { + length 1..255; + } + } + + leaf-list dhcp_servers { + type inet:ip-address; + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf admin_status { + type stypes:admin_status; + } + + leaf-list members { + /* leaf-list members are unique by default */ + + type leafref { + path "/port:sonic-port/port:PORT/port:PORT_LIST/port:port_name"; + } + } + } + /* end of VLAN_LIST */ + } + /* end of container VLAN */ + + container VLAN_MEMBER { + + description "VLAN_MEMBER part of config_db.json"; + + list VLAN_MEMBER_LIST { + + key "vlan_name port"; + + ext:key-regex-configdb-to-yang "^(Vlan[a-zA-Z0-9-_]+)|(Ethernet[0-9]+)$"; + + ext:key-regex-yang-to-configdb "|"; + + leaf vlan_name { + type leafref { + path "/vlan:sonic-vlan/vlan:VLAN/vlan:VLAN_LIST/vlan:vlan_name"; + } + } + + leaf port { + /* key elements are mandatory by default */ + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf tagging_mode { + mandatory true; + type stypes:vlan_tagging_mode; + } + } + /* end of list VLAN_MEMBER_LIST */ + } + /* end of container VLAN_MEMBER */ + } + /* end of container sonic-vlan */ +} +/* end of module sonic-vlan */ From 12400a447c974c42c7782e7c8ba0ea26ee1cb998 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Wed, 15 Apr 2020 02:08:45 -0700 Subject: [PATCH 0526/1427] [docker-restapi]: Fix authentication in restapi (#4383) - enabling http/https endpoint and mounting the certificates directory - updating the sonic-restapi submodule --- dockers/docker-sonic-restapi/Dockerfile.j2 | 3 ++ .../base_image_files/monit_restapi | 7 ++++ .../docker-sonic-restapi/critical_processes | 1 + dockers/docker-sonic-restapi/restapi.sh | 38 +++++++++++++++++++ dockers/docker-sonic-restapi/start.sh | 1 - dockers/docker-sonic-restapi/supervisord.conf | 30 +++++++++++++-- rules/docker-restapi.mk | 6 +++ src/sonic-restapi | 2 +- 8 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 dockers/docker-sonic-restapi/base_image_files/monit_restapi create mode 100644 dockers/docker-sonic-restapi/critical_processes create mode 100755 dockers/docker-sonic-restapi/restapi.sh diff --git a/dockers/docker-sonic-restapi/Dockerfile.j2 b/dockers/docker-sonic-restapi/Dockerfile.j2 index de8080880fc7..32904531f1fc 100644 --- a/dockers/docker-sonic-restapi/Dockerfile.j2 +++ b/dockers/docker-sonic-restapi/Dockerfile.j2 @@ -20,6 +20,9 @@ RUN apt-get update ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +COPY ["start.sh", "restapi.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sonic-restapi/base_image_files/monit_restapi b/dockers/docker-sonic-restapi/base_image_files/monit_restapi new file mode 100644 index 000000000000..2e90baf30d57 --- /dev/null +++ b/dockers/docker-sonic-restapi/base_image_files/monit_restapi @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for restapi container +## process list: +## restapi +############################################################################### +check process restapi matching "/usr/sbin/go-server-server" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-restapi/critical_processes b/dockers/docker-sonic-restapi/critical_processes new file mode 100644 index 000000000000..3106eaa9410a --- /dev/null +++ b/dockers/docker-sonic-restapi/critical_processes @@ -0,0 +1 @@ +restapi diff --git a/dockers/docker-sonic-restapi/restapi.sh b/dockers/docker-sonic-restapi/restapi.sh new file mode 100755 index 000000000000..61778e3245d6 --- /dev/null +++ b/dockers/docker-sonic-restapi/restapi.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +RESTAPI_ARGS="" +while true +do + client_auth=`sonic-cfggen -d -v "RESTAPI['config']['client_auth']"` + if [[ $client_auth == 'true' ]]; then + certs=`sonic-cfggen -d -v "RESTAPI['certs']"` + allow_insecure=`sonic-cfggen -d -v "RESTAPI['config']['allow_insecure']"` + if [[ $allow_insecure == 'true' ]]; then + RESTAPI_ARGS=" -enablehttp=true" + else + RESTAPI_ARGS=" -enablehttp=false" + fi + if [[ -n "$certs" ]]; then + SERVER_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['server_crt']"` + SERVER_KEY=`sonic-cfggen -d -v "RESTAPI['certs']['server_key']"` + CLIENT_CA_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['client_ca_crt']"` + CLIENT_CRT_CNAME=`sonic-cfggen -d -v "RESTAPI['certs']['client_crt_cname']"` + if [[ -f $SERVER_CRT && -f $SERVER_KEY && -f $CLIENT_CA_CRT ]]; then + RESTAPI_ARGS+=" -enablehttps=true -servercert=$SERVER_CRT -serverkey=$SERVER_KEY -clientcert=$CLIENT_CA_CRT -clientcertcommonname=$CLIENT_CRT_CNAME" + break + fi + fi + fi + logger "Waiting for certificates..." + sleep 60 +done + +LOG_LEVEL=`sonic-cfggen -d -v "RESTAPI['config']['log_level']"` +if [ ! -z $LOG_LEVEL ]; then + RESTAPI_ARGS+=" -loglevel=$LOG_LEVEL" +else + RESTAPI_ARGS+=" -loglevel=trace" +fi + +logger "RESTAPI_ARGS: $RESTAPI_ARGS" +exec /usr/sbin/go-server-server ${RESTAPI_ARGS} diff --git a/dockers/docker-sonic-restapi/start.sh b/dockers/docker-sonic-restapi/start.sh index 015d246d1200..bff56a8864c1 100755 --- a/dockers/docker-sonic-restapi/start.sh +++ b/dockers/docker-sonic-restapi/start.sh @@ -6,5 +6,4 @@ echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd - supervisorctl start restapi diff --git a/dockers/docker-sonic-restapi/supervisord.conf b/dockers/docker-sonic-restapi/supervisord.conf index 284c8aef423b..58afc6dcd7de 100644 --- a/dockers/docker-sonic-restapi/supervisord.conf +++ b/dockers/docker-sonic-restapi/supervisord.conf @@ -3,10 +3,32 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:restapi] -command=/usr/sbin/go-server-server -loglevel trace +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name restapi +events=PROCESS_STATE_EXITED +autostart=true +autorestart=false + +[program:start.sh] +command=/usr/bin/start.sh priority=1 autostart=true autorestart=false -stdout_logfile=/tmp/rest-api.out.log -stderr_logfile=/tmp/rest-api.err.log +stdout_logfile=syslog +stderr_logfile=syslog + +[program:restapi] +command=/usr/bin/restapi.sh +priority=1 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index 2141dea64d17..09bbd03d8fd8 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -18,5 +18,11 @@ endif $(DOCKER_RESTAPI)_CONTAINER_NAME = restapi $(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t +$(DOCKER_RESTAPI)_RUN_OPT += --network="host" $(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock +$(DOCKER_RESTAPI)_RUN_OPT += -v /etc/sonic/certificates:/etc/sonic/certificates:ro +$(DOCKER_RESTAPI)_RUN_OPT += -p=8081:8081/tcp $(DOCKER_RESTAPI)_RUN_OPT += -p=8090:8090/tcp + +$(DOCKER_RESTAPI)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_RESTAPI)_BASE_IMAGE_FILES += monit_restapi:/etc/monit/conf.d diff --git a/src/sonic-restapi b/src/sonic-restapi index 163ee272ae99..c219e3da28fb 160000 --- a/src/sonic-restapi +++ b/src/sonic-restapi @@ -1 +1 @@ -Subproject commit 163ee272ae992f5885990dcca6552cd86b74391a +Subproject commit c219e3da28fb20b63b065ceb1828125593d73f14 From 89fb1059fa8bfc8706262d81696d492968e73286 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Wed, 15 Apr 2020 13:04:11 +0300 Subject: [PATCH 0527/1427] [Mellanox] Update hw-mgmt package to V.7.0000.3020 (#4362) * update hw-mgmt package to V.7.0000.3020 * update sonic-linux-kernel repo to pick up new patches --- platform/mellanox/hw-management.mk | 2 +- ...-Disable-thermal-policy-running-in-h.patch | 31 ------------------- platform/mellanox/hw-management/hw-mgmt | 2 +- src/sonic-linux-kernel | 2 +- 4 files changed, 3 insertions(+), 34 deletions(-) delete mode 100644 platform/mellanox/hw-management/0002-hw-management.sh-Disable-thermal-policy-running-in-h.patch diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index 692a816a0f4f..31ff9aaca7be 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0000.3012 +MLNX_HW_MANAGEMENT_VERSION = 7.0000.3020 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/0002-hw-management.sh-Disable-thermal-policy-running-in-h.patch b/platform/mellanox/hw-management/0002-hw-management.sh-Disable-thermal-policy-running-in-h.patch deleted file mode 100644 index d1c34fd16ec0..000000000000 --- a/platform/mellanox/hw-management/0002-hw-management.sh-Disable-thermal-policy-running-in-h.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 76b02916794be2e2558fcff1d11609a594f633d7 Mon Sep 17 00:00:00 2001 -From: Stephen Sun -Date: Fri, 14 Feb 2020 13:48:00 +0800 -Subject: [PATCH] Disable thermal policy running in hw-mgmt service SONiC - thermal control algorithm has been supported. - -Signed-off-by: Stephen Sun ---- - usr/usr/bin/hw-management.sh | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh -index 2cdbfb2..48b41d5 100755 ---- a/usr/usr/bin/hw-management.sh -+++ b/usr/usr/bin/hw-management.sh -@@ -799,7 +799,11 @@ do_start() - #disabled for leopard chipless bringup. - echo 1 > $config_path/suspend - -- $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& -+# -+# Disable thermal control algorithm in hw-management service -+# because there has already been that in SONiC -+# -+# $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& - } - - do_stop() --- -1.9.1 - diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 2f659142ab3b..5e0a3410bf21 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 2f659142ab3b4deb58989a2ca38b0b1671600509 +Subproject commit 5e0a3410bf2167af0f63ba85cd4158a0be9f1443 diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 231bebb41b86..32963dab6b6e 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 231bebb41b86c9f744adc86972773d75fd4a2a2a +Subproject commit 32963dab6b6ea9f9fbda9b2b49a77574453fb8ef From df7acdb664b3f909b142919ae14a5d22cb00577f Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Wed, 15 Apr 2020 20:27:04 -0700 Subject: [PATCH 0528/1427] [sonic-yang-models/setup.py]: Making path of pre-installed pacakges relative. (#4430) Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com --- src/sonic-yang-models/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index d53d5fb901eb..784194a2ff4d 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -9,7 +9,7 @@ from sys import exit # find path of pkgs from environment vars -prefix = '/sonic'; debs = environ["STRETCH_DEBS_PATH"] +prefix = '../../'; debs = environ["STRETCH_DEBS_PATH"] deps_path = '{}/{}'.format(prefix, debs) # dependencies libyang = '{}/{}'.format(deps_path, environ["LIBYANG"]) From 2ed716478b48c29224eae2071b885e765c1d00e1 Mon Sep 17 00:00:00 2001 From: Srideep Date: Thu, 16 Apr 2020 04:07:51 -0600 Subject: [PATCH 0529/1427] [DellEMC] s5232f console and sfputil fix (#4424) Remove hardcoding 115K baudrate for console Enhance sfputil api as per spec --- .../installer.conf | 1 - .../plugins/sfputil.py | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf b/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf index 925a32fc0c3a..924e0fb81963 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf @@ -1,3 +1,2 @@ CONSOLE_PORT=0x3f8 CONSOLE_DEV=0 -CONSOLE_SPEED=115200 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py index 978ade1ce319..03bf1585d935 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py @@ -244,6 +244,9 @@ def reset(self, port_num): def get_transceiver_change_event(self, timeout=0): port_dict = {} + sleep_time_ms = 500 # Poll interval, in milliseconds + sleep_time = sleep_time_ms / 1000.0 + elapsed_time_ms = 0 while True: for port_num in range(self.port_start, (self.port_end + 1)): presence = self.get_presence(port_num) @@ -256,9 +259,18 @@ def get_transceiver_change_event(self, timeout=0): port_dict[port_num] = '0' if(len(port_dict) > 0): - return True, port_dict + break + + if len(port_dict) > 0: + break + if timeout != 0: + elapsed_time_ms += sleep_time_ms + if elapsed_time_ms > timeout: + break + time.sleep(sleep_time) + + return True, port_dict - time.sleep(0.5) def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict = {} From 695652c9d1302519fdbe2297fb57c8775471ed1f Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Thu, 16 Apr 2020 15:39:32 +0530 Subject: [PATCH 0530/1427] [platform]: Adding platform support for Juniper QFX5200 (#4376) This is a 1RU switch with 32 QSFP28 (40G/100G) ports on Broadcom Tomahawk I chipset. CPU used in QFX5200-32C-S is Intel Ivy Bridge. The machine has Redundant and hot-swappable Power Supply (1+1) and also has Redundant and hot swappable fans (5). Signed-off-by: Ciju Rajan K Signed-off-by: Ashish Bhensdadia --- .../Juniper-QFX5200-32C-S/port_config.ini | 33 + .../Juniper-QFX5200-32C-S/sai.profile | 1 + .../th-qfx5200-32x100g.config.bcm | 586 +++++++++ .../x86_64-juniper_qfx5200-r0/default_sku | 1 + .../x86_64-juniper_qfx5200-r0/installer.conf | 4 + .../led_proc_init.soc | 49 + .../media_settings.json | 36 + .../plugins/eeprom.py | 63 + .../plugins/led_control.py | 189 +++ .../plugins/psuutil.py | 101 ++ .../plugins/qfx5200_eeprom_data.py | 415 ++++++ .../plugins/qfx5200_sfp_init.py | 103 ++ .../plugins/sfputil.py | 884 +++++++++++++ .../pmon_daemon_control.json | 3 + platform/broadcom/one-image.mk | 3 +- platform/broadcom/platform-modules-juniper.mk | 7 + .../debian/control | 3 + .../debian/rules | 2 +- .../sonic-platform-juniper-qfx5200.install | 5 + .../sonic-platform-juniper-qfx5200.postinst | 31 + .../qfx5200/modules/Makefile | 1 + .../qfx5200/modules/gpio-tmc.c | 661 ++++++++++ .../qfx5200/modules/i2c-tmc.c | 1107 +++++++++++++++++ .../qfx5200/modules/jnx-psu-monitor.c | 325 +++++ .../qfx5200/modules/jnx-refpga-lpcm.c | 116 ++ .../qfx5200/modules/jnx-refpga-tmc.c | 603 +++++++++ .../qfx5200/modules/jnx-tmc-core.c | 477 +++++++ .../qfx5200/modules/jnx-tmc-psu.c | 173 +++ .../qfx5200/modules/jnx-tmc.h | 93 ++ .../qfx5200/modules/leds-jnx-tmc.c | 223 ++++ .../qfx5200/modules/pci_ids.h | 144 +++ .../service/qfx5200-platform-init.service | 15 + .../qfx5200/setup.py | 15 + .../qfx5200/sonic_platform/__init__.py | 1 + .../qfx5200/sonic_platform/chassis.py | 260 ++++ .../qfx5200/sonic_platform/platform.py | 65 + .../qfx5200/utils/README | 117 ++ .../qfx5200/utils/juniper_qfx5200_monitor.py | 929 ++++++++++++++ .../qfx5200/utils/juniper_qfx5200_util.py | 203 +++ 39 files changed, 8045 insertions(+), 2 deletions(-) create mode 100644 device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/port_config.ini create mode 100644 device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile create mode 100644 device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/th-qfx5200-32x100g.config.bcm create mode 100644 device/juniper/x86_64-juniper_qfx5200-r0/default_sku create mode 100644 device/juniper/x86_64-juniper_qfx5200-r0/installer.conf create mode 100644 device/juniper/x86_64-juniper_qfx5200-r0/led_proc_init.soc create mode 100755 device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json create mode 100755 device/juniper/x86_64-juniper_qfx5200-r0/plugins/eeprom.py create mode 100755 device/juniper/x86_64-juniper_qfx5200-r0/plugins/led_control.py create mode 100755 device/juniper/x86_64-juniper_qfx5200-r0/plugins/psuutil.py create mode 100755 device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py create mode 100755 device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py create mode 100755 device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py create mode 100644 device/juniper/x86_64-juniper_qfx5200-r0/pmon_daemon_control.json create mode 100644 platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install create mode 100644 platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst create mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-psu-monitor.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-psu.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h create mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/leds-jnx-tmc.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/pci_ids.h create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/service/qfx5200-platform-init.service create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/__init__.py create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/chassis.py create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/platform.py create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/port_config.ini b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/port_config.ini new file mode 100644 index 000000000000..a7ebdd116fc8 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 49,50,51,52 hundredGigE1/1 0 100000 +Ethernet4 53,54,55,56 hundredGigE1/2 1 100000 +Ethernet8 57,58,59,60 hundredGigE1/3 2 100000 +Ethernet12 61,62,63,64 hundredGigE1/4 3 100000 +Ethernet16 65,66,67,68 hundredGigE1/5 4 100000 +Ethernet20 69,70,71,72 hundredGigE1/6 5 100000 +Ethernet24 73,74,75,76 hundredGigE1/7 6 100000 +Ethernet28 77,78,79,80 hundredGigE1/8 7 100000 +Ethernet32 81,82,83,84 hundredGigE1/9 8 100000 +Ethernet36 85,86,87,88 hundredGigE1/10 9 100000 +Ethernet40 37,38,39,40 hundredGigE1/11 10 100000 +Ethernet44 33,34,35,36 hundredGigE1/12 11 100000 +Ethernet48 41,42,43,44 hundredGigE1/13 12 100000 +Ethernet52 45,46,47,48 hundredGigE1/14 13 100000 +Ethernet56 89,90,91,92 hundredGigE1/15 14 100000 +Ethernet60 93,94,95,96 hundredGigE1/16 15 100000 +Ethernet64 97,98,99,100 hundredGigE1/17 16 100000 +Ethernet68 101,102,103,104 hundredGigE1/18 17 100000 +Ethernet72 17,18,19,20 hundredGigE1/19 18 100000 +Ethernet76 21,22,23,24 hundredGigE1/20 19 100000 +Ethernet80 29,30,31,32 hundredGigE1/21 20 100000 +Ethernet84 25,26,27,28 hundredGigE1/22 21 100000 +Ethernet88 105,106,107,108 hundredGigE1/23 22 100000 +Ethernet92 109,110,111,112 hundredGigE1/24 23 100000 +Ethernet96 113,114,115,116 hundredGigE1/25 24 100000 +Ethernet100 117,118,119,120 hundredGigE1/26 25 100000 +Ethernet104 121,122,123,124 hundredGigE1/27 26 100000 +Ethernet108 125,126,127,128 hundredGigE1/28 27 100000 +Ethernet112 1,2,3,4 hundredGigE1/29 28 100000 +Ethernet116 5,6,7,8 hundredGigE1/30 29 100000 +Ethernet120 9,10,11,12 hundredGigE1/31 30 100000 +Ethernet124 13,14,15,16 hundredGigE1/32 31 100000 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile new file mode 100644 index 000000000000..4bcf21c09c41 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-qfx5200-32x100g.config.bcm diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/th-qfx5200-32x100g.config.bcm b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/th-qfx5200-32x100g.config.bcm new file mode 100644 index 000000000000..7e219ae76048 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/th-qfx5200-32x100g.config.bcm @@ -0,0 +1,586 @@ +phy_xaui_tx_polarity_flip_99=0x01 +portmap_120=115:25:50:i +portmap_112=107:25:50:i +portmap_104=99:25:50:i +portmap_8=8:25:i +xgxs_rx_lane_map_20=0x3120 +xgxs_rx_lane_map_12=0x2301 +l2mod_dma_intr_enable=1 +xgxs_tx_lane_map_40=0x0123 +xgxs_tx_lane_map_32=0x0213 +xgxs_tx_lane_map_24=0x2310 +xgxs_tx_lane_map_16=0x1023 +port_phy_addr_99=0xff +rate_ext_mdio_divisor=0x80 +portmap_121=116:25:i +portmap_113=108:25:i +portmap_105=100:25:i +portmap_9=9:100 +xgxs_rx_lane_map_21=0x3120 +xgxs_rx_lane_map_13=0x0213 +tslam_timeout_usec=10000000 +xgxs_tx_lane_map_41=0x0123 +xgxs_tx_lane_map_25=0x0213 +xgxs_tx_lane_map_17=0x0213 +portmap_130=125:100 +portmap_122=117:100 +portmap_114=109:100 +xgxs_rx_lane_map_30=0x2301 +portmap_106=101:100 +xgxs_rx_lane_map_22=0x3120 +xgxs_rx_lane_map_14=0x0213 +xgxs_tx_lane_map_50=0x0213 +xgxs_tx_lane_map_42=0x2310 +xgxs_tx_lane_map_34=0x0123 +phy_xaui_rx_polarity_flip_20=0x01 +xgxs_tx_lane_map_26=0x0213 +xgxs_tx_lane_map_18=0x0213 +portmap_10=10:25:i +xgxs_tx_lane_map_1=0x3120 +portmap_131=126:25:i +portmap_123=118:25:i +portmap_115=110:25:i +xgxs_rx_lane_map_31=0x2301 +portmap_107=102:25:i +xgxs_rx_lane_map_23=0x3120 +xgxs_rx_lane_map_15=0x0213 +xgxs_tx_lane_map_51=0x0213 +xgxs_tx_lane_map_43=0x2310 +xgxs_tx_lane_map_35=0x0123 +phy_xaui_rx_polarity_flip_21=0x03 +xgxs_tx_lane_map_27=0x0213 +phy_xaui_rx_polarity_flip_13=0x0c +xgxs_tx_lane_map_19=0x0213 +portmap_11=11:25:50:i +xgxs_tx_lane_map_2=0x3120 +xgxs_tx_lane_map_110=0x1203 +xgxs_tx_lane_map_102=0x1203 +parity_correction=1 +portmap_132=127:25:50:i +portmap_124=119:25:50:i +portmap_116=111:25:50:i +xgxs_rx_lane_map_40=0x2310 +xgxs_rx_lane_map_32=0x2301 +portmap_108=103:25:50:i +xgxs_rx_lane_map_24=0x3120 +xgxs_rx_lane_map_16=0x0213 +xgxs_tx_lane_map_60=0x0213 +xgxs_tx_lane_map_52=0x0213 +xgxs_tx_lane_map_44=0x2310 +xgxs_tx_lane_map_36=0x0123 +phy_xaui_rx_polarity_flip_22=0x01 +xgxs_tx_lane_map_28=0x0213 +portmap_20=20:25:i +portmap_12=12:25:i +xgxs_tx_lane_map_3=0x3120 +xgxs_tx_lane_map_111=0x1203 +xgxs_tx_lane_map_103=0x1203 +portmap_133=128:25:i +portmap_125=120:25:i +portmap_117=112:25:i +xgxs_rx_lane_map_41=0x2310 +portmap_109=104:25:i +xgxs_rx_lane_map_25=0x3210 +xgxs_rx_lane_map_17=0x3120 +xgxs_tx_lane_map_61=0x0213 +xgxs_tx_lane_map_53=0x0213 +xgxs_tx_lane_map_45=0x2310 +xgxs_tx_lane_map_37=0x0123 +xgxs_tx_lane_map_29=0x0213 +phy_xaui_rx_polarity_flip_15=0x03 +portmap_21=21:100 +portmap_13=13:100 +xgxs_rx_lane_map_110=0x2301 +xgxs_rx_lane_map_102=0x2301 +xgxs_tx_lane_map_4=0x3120 +xgxs_tx_lane_map_120=0x1203 +xgxs_tx_lane_map_112=0x1203 +xgxs_tx_lane_map_104=0x1203 +bcm_stat_interval=500000 +l2xmsg_hostbuf_size=16384 +portmap_126=121:100 +xgxs_rx_lane_map_50=0x0231 +portmap_118=113:100 +xgxs_rx_lane_map_42=0x3201 +xgxs_rx_lane_map_34=0x3102 +xgxs_rx_lane_map_26=0x3210 +xgxs_rx_lane_map_18=0x3120 +xgxs_tx_lane_map_70=0x3120 +xgxs_tx_lane_map_62=0x2310 +xgxs_tx_lane_map_54=0x2310 +phy_xaui_rx_polarity_flip_40=0x01 +xgxs_tx_lane_map_46=0x2013 +xgxs_tx_lane_map_38=0x0123 +portmap_30=30:25:i +phy_xaui_rx_polarity_flip_16=0x01 +portmap_22=22:25:i +portmap_14=14:25:i +xgxs_rx_lane_map_111=0x2301 +xgxs_rx_lane_map_103=0x2301 +xgxs_tx_lane_map_5=0x1023 +xgxs_tx_lane_map_121=0x1203 +xgxs_tx_lane_map_113=0x1203 +xgxs_tx_lane_map_105=0x1203 +port_phy_addr_10=0xff +mem_check_nocache_override=1 +bcm_stat_flags=1 +portmap_127=122:25:i +xgxs_rx_lane_map_51=0x0231 +portmap_119=114:25:i +xgxs_rx_lane_map_43=0x3201 +xgxs_rx_lane_map_35=0x3102 +xgxs_rx_lane_map_27=0x3210 +xgxs_rx_lane_map_19=0x3120 +xgxs_tx_lane_map_71=0x3120 +xgxs_tx_lane_map_63=0x2310 +phy_xaui_tx_polarity_flip_11=0x02 +xgxs_tx_lane_map_55=0x2310 +xgxs_tx_lane_map_47=0x2013 +xgxs_tx_lane_map_39=0x0123 +phy_xaui_rx_polarity_flip_25=0x0c +portmap_31=31:25:50:i +phy_xaui_rx_polarity_flip_17=0x08 +portmap_23=23:25:50:i +portmap_15=15:25:50:i +xgxs_rx_lane_map_120=0x3120 +xgxs_rx_lane_map_112=0x2301 +xgxs_rx_lane_map_104=0x2301 +xgxs_tx_lane_map_6=0x1023 +xgxs_tx_lane_map_130=0x3201 +xgxs_tx_lane_map_122=0x1023 +xgxs_tx_lane_map_114=0x0132 +xgxs_tx_lane_map_106=0x0132 +port_phy_addr_11=0xff +xgxs_rx_lane_map_60=0x0231 +portmap_128=123:25:50:i +xgxs_rx_lane_map_52=0x0231 +xgxs_rx_lane_map_44=0x3201 +xgxs_rx_lane_map_36=0x3102 +xgxs_rx_lane_map_28=0x3210 +xgxs_tx_lane_map_80=0x3102 +xgxs_tx_lane_map_72=0x2310 +xgxs_tx_lane_map_64=0x2310 +phy_xaui_tx_polarity_flip_12=0x01 +xgxs_tx_lane_map_56=0x2310 +phy_xaui_rx_polarity_flip_42=0x04 +xgxs_tx_lane_map_48=0x2013 +phy_xaui_rx_polarity_flip_34=0x08 +portmap_40=39:25:50:i +xgxs_rx_lane_map_1=0x3201 +portmap_32=32:25:i +portmap_24=24:25:i +portmap_16=16:25:i +xgxs_rx_lane_map_121=0x3120 +xgxs_rx_lane_map_113=0x2301 +xgxs_rx_lane_map_105=0x2301 +xgxs_tx_lane_map_7=0x1023 +xgxs_tx_lane_map_131=0x3201 +xgxs_tx_lane_map_123=0x1023 +xgxs_tx_lane_map_115=0x0132 +xgxs_tx_lane_map_107=0x0132 +port_phy_addr_20=0xff +port_phy_addr_12=0xff +xgxs_rx_lane_map_61=0x0231 +portmap_129=124:25:i +xgxs_rx_lane_map_53=0x0231 +xgxs_rx_lane_map_45=0x3201 +xgxs_rx_lane_map_37=0x3102 +xgxs_rx_lane_map_29=0x2301 +xgxs_tx_lane_map_81=0x3102 +xgxs_tx_lane_map_73=0x2310 +phy_xaui_tx_polarity_flip_21=0x04 +xgxs_tx_lane_map_65=0x2310 +xgxs_tx_lane_map_57=0x2310 +xgxs_tx_lane_map_49=0x2013 +portmap_41=40:25:i +phy_xaui_rx_polarity_flip_27=0x03 +xgxs_rx_lane_map_2=0x3201 +phy_xaui_rx_polarity_flip_19=0x02 +portmap_25=25:100 +portmap_17=17:100 +xgxs_rx_lane_map_130=0x3210 +xgxs_rx_lane_map_122=0x1023 +xgxs_rx_lane_map_114=0x2301 +xgxs_rx_lane_map_106=0x2301 +xgxs_tx_lane_map_8=0x1023 +xgxs_tx_lane_map_132=0x3201 +xgxs_tx_lane_map_124=0x1023 +xgxs_tx_lane_map_116=0x0132 +xgxs_tx_lane_map_108=0x0132 +phy_xaui_rx_polarity_flip_114=0x07 +xgxs_rx_lane_map_70=0x0213 +xgxs_rx_lane_map_62=0x2310 +xgxs_rx_lane_map_54=0x2301 +xgxs_rx_lane_map_46=0x3012 +xgxs_rx_lane_map_38=0x2310 +xgxs_tx_lane_map_90=0x0123 +xgxs_tx_lane_map_82=0x3102 +xgxs_tx_lane_map_74=0x2310 +xgxs_tx_lane_map_58=0x0213 +phy_xaui_rx_polarity_flip_44=0x01 +portmap_50=49:100 +phy_xaui_rx_polarity_flip_36=0x02 +portmap_42=41:100 +phy_xaui_rx_polarity_flip_28=0x01 +xgxs_rx_lane_map_3=0x3201 +portmap_34=33:100 +portmap_26=26:25:i +portmap_18=18:25:i +xgxs_rx_lane_map_131=0x3210 +xgxs_rx_lane_map_123=0x1023 +xgxs_rx_lane_map_115=0x2301 +xgxs_rx_lane_map_107=0x2301 +xgxs_tx_lane_map_9=0x3120 +xgxs_tx_lane_map_133=0x3201 +xgxs_tx_lane_map_125=0x1023 +bcm_linkscan_interval=4000000 +xgxs_tx_lane_map_117=0x0132 +xgxs_tx_lane_map_109=0x0132 +phy_xaui_rx_polarity_flip_115=0x01 +port_phy_addr_30=0xff +port_phy_addr_22=0xff +port_phy_addr_14=0xff +xgxs_rx_lane_map_71=0x0213 +xgxs_rx_lane_map_63=0x2310 +xgxs_rx_lane_map_55=0x2301 +xgxs_rx_lane_map_47=0x3012 +xgxs_rx_lane_map_39=0x2310 +xgxs_tx_lane_map_91=0x0123 +xgxs_tx_lane_map_83=0x3102 +phy_xaui_tx_polarity_flip_31=0x02 +xgxs_tx_lane_map_75=0x2310 +phy_xaui_tx_polarity_flip_23=0x01 +xgxs_tx_lane_map_59=0x0213 +portmap_51=50:25:i +phy_xaui_rx_polarity_flip_37=0x01 +portmap_43=42:25:i +xgxs_rx_lane_map_4=0x3201 +portmap_35=34:25:i +portmap_27=27:25:50:i +portmap_19=19:25:50:i +xgxs_rx_lane_map_132=0x3210 +xgxs_rx_lane_map_124=0x1023 +xgxs_rx_lane_map_116=0x2301 +cdma_timeout_usec=4000000 +xgxs_rx_lane_map_108=0x2301 +xgxs_tx_lane_map_126=0x3120 +xgxs_tx_lane_map_118=0x1203 +phy_xaui_rx_polarity_flip_116=0x01 +port_phy_addr_31=0xff +port_phy_addr_23=0xff +port_phy_addr_15=0xff +xgxs_rx_lane_map_80=0x3210 +xgxs_rx_lane_map_72=0x2310 +xgxs_rx_lane_map_64=0x2310 +xgxs_rx_lane_map_56=0x2301 +xgxs_rx_lane_map_48=0x3012 +xgxs_tx_lane_map_92=0x0213 +phy_xaui_tx_polarity_flip_40=0x01 +xgxs_tx_lane_map_84=0x0213 +phy_xaui_tx_polarity_flip_32=0x01 +xgxs_tx_lane_map_76=0x0213 +xgxs_tx_lane_map_68=0x3120 +portmap_60=59:25:50:i +phy_xaui_rx_polarity_flip_46=0x08 +portmap_52=51:25:50:i +phy_xaui_rx_polarity_flip_38=0x04 +portmap_44=43:25:50:i +xgxs_rx_lane_map_5=0x1023 +portmap_36=35:25:50:i +portmap_28=28:25:i +mdio_output_delay=12 +xgxs_rx_lane_map_133=0x3210 +xgxs_rx_lane_map_125=0x1023 +xgxs_rx_lane_map_117=0x2301 +xgxs_rx_lane_map_109=0x2301 +xgxs_tx_lane_map_127=0x3120 +xgxs_tx_lane_map_119=0x1203 +port_phy_addr_40=0xff +port_phy_addr_32=0xff +port_phy_addr_24=0xff +port_phy_addr_16=0xff +xgxs_rx_lane_map_81=0x3210 +xgxs_rx_lane_map_73=0x2310 +tdma_timeout_usec=10000000 +xgxs_rx_lane_map_65=0x2310 +xgxs_rx_lane_map_57=0x2301 +xgxs_rx_lane_map_49=0x3012 +xgxs_tx_lane_map_93=0x0213 +xgxs_tx_lane_map_85=0x0213 +xgxs_tx_lane_map_77=0x0213 +phy_xaui_tx_polarity_flip_25=0x0d +xgxs_tx_lane_map_69=0x3120 +portmap_61=60:25:i +portmap_53=52:25:i +portmap_45=44:25:i +xgxs_rx_lane_map_6=0x1023 +portmap_37=36:25:i +portmap_29=29:100 +xgxs_rx_lane_map_126=0x2301 +xgxs_rx_lane_map_118=0x3120 +xgxs_tx_lane_map_128=0x3120 +port_phy_addr_41=0xff +ipv6_lpm_128b_enable=1 +xgxs_rx_lane_map_90=0x3210 +xgxs_rx_lane_map_82=0x3210 +xgxs_rx_lane_map_74=0x2310 +xgxs_rx_lane_map_58=0x0231 +fpem_mem_entries=0 +xgxs_tx_lane_map_94=0x0213 +phy_xaui_tx_polarity_flip_42=0x04 +xgxs_tx_lane_map_86=0x0213 +phy_xaui_tx_polarity_flip_34=0x08 +xgxs_tx_lane_map_78=0x0213 +portmap_70=67:25:50:i +portmap_62=61:100 +phy_xaui_rx_polarity_flip_48=0x02 +pbmp_xport_xe=0xfffffffffffffffffffffffffffffffffe +portmap_54=53:100 +portmap_46=45:100 +xgxs_rx_lane_map_7=0x1023 +portmap_38=37:100 +xgxs_rx_lane_map_127=0x2301 +xgxs_rx_lane_map_119=0x3120 +xgxs_tx_lane_map_129=0x3120 +l2_mem_entries=106496 +os=unix +port_phy_addr_26=0xff +port_phy_addr_18=0xff +xgxs_rx_lane_map_91=0x3210 +xgxs_rx_lane_map_83=0x3210 +xgxs_rx_lane_map_75=0x2310 +xgxs_rx_lane_map_59=0x0231 +xgxs_tx_lane_map_95=0x0213 +port_phy_addr_111=0xff +xgxs_tx_lane_map_87=0x0213 +port_phy_addr_103=0xff +xgxs_tx_lane_map_79=0x0213 +phy_xaui_tx_polarity_flip_27=0x03 +portmap_71=68:25:i +portmap_63=62:25:i +phy_xaui_rx_polarity_flip_49=0x01 +portmap_55=54:25:i +portmap_47=46:25:i +xgxs_rx_lane_map_8=0x1023 +portmap_39=38:25:i +xgxs_rx_lane_map_128=0x2301 +port_phy_addr_51=0xff +port_phy_addr_43=0xff +port_phy_addr_35=0xff +port_phy_addr_27=0xff +port_phy_addr_19=0xff +xgxs_rx_lane_map_92=0x2310 +xgxs_rx_lane_map_84=0x3210 +xgxs_rx_lane_map_76=0x0231 +xgxs_rx_lane_map_68=0x0213 +port_phy_addr_120=0xff +xgxs_tx_lane_map_96=0x0123 +phy_xaui_tx_polarity_flip_44=0x01 +port_phy_addr_112=0xff +xgxs_tx_lane_map_88=0x0123 +phy_xaui_tx_polarity_flip_36=0x02 +port_phy_addr_104=0xff +portmap_80=77:100 +phy_xaui_tx_polarity_flip_28=0x01 +portmap_72=69:100 +portmap_64=63:25:50:i +portmap_56=55:25:50:i +portmap_48=47:25:50:i +xgxs_rx_lane_map_9=0x2301 +phy_xaui_rx_polarity_flip_5=4 +xgxs_rx_lane_map_129=0x2301 +port_phy_addr_60=0xff +port_phy_addr_52=0xff +port_phy_addr_44=0xff +port_phy_addr_36=0xff +port_phy_addr_28=0xff +xgxs_rx_lane_map_93=0x2310 +xgxs_rx_lane_map_85=0x3210 +table_dma_enable=1 +xgxs_rx_lane_map_77=0x0231 +xgxs_rx_lane_map_69=0x0213 +port_phy_addr_121=0xff +xgxs_tx_lane_map_97=0x0123 +port_phy_addr_113=0xff +xgxs_tx_lane_map_89=0x0123 +phy_xaui_tx_polarity_flip_37=0x01 +port_phy_addr_105=0xff +portmap_81=78:25:i +phy_xaui_tx_polarity_flip_29=0x08 +portmap_73=70:25:i +portmap_65=64:25:i +portmap_57=56:25:i +portmap_49=48:25:i +port_phy_addr_61=0xff +port_phy_addr_53=0xff +port_phy_addr_45=0xff +port_phy_addr_37=0xff +xgxs_rx_lane_map_94=0x2310 +port_phy_addr_2=0xff +xgxs_rx_lane_map_86=0x3210 +xgxs_rx_lane_map_78=0x0231 +phy_xaui_rx_polarity_flip_92=0x0c +xgxs_tx_lane_map_98=0x0123 +phy_xaui_tx_polarity_flip_46=0x01 +portmap_90=87:25:50:i +phy_xaui_tx_polarity_flip_38=0x05 +portmap_82=79:25:50:i +portmap_74=71:25:50:i +portmap_66=129:1 +portmap_58=57:100 +phy_xaui_rx_polarity_flip_7=1 +port_phy_addr_70=0xff +xgxs_rx_lane_map_95=0x2310 +port_phy_addr_3=0xff +xgxs_rx_lane_map_87=0x3210 +xgxs_rx_lane_map_79=0x0231 +port_phy_addr_131=0xff +port_phy_addr_123=0xff +xgxs_tx_lane_map_99=0x0123 +phy_an_c37=3 +port_phy_addr_115=0xff +portmap_91=88:25:i +port_phy_addr_107=0xff +portmap_83=80:25:i +portmap_75=72:25:i +portmap_59=58:25:i +serdes_firmware_mode=0x1 +schan_intr_enable=0x00 +port_phy_addr_71=0xff +port_phy_addr_63=0xff +port_phy_addr_55=0xff +port_phy_addr_47=0xff +port_phy_addr_39=0xff +l2delete_chunks=128 +xgxs_rx_lane_map_96=0x2130 +port_phy_addr_4=0xff +xgxs_rx_lane_map_88=0x3210 +tslam_intr_enable=0 +port_phy_addr_132=0xff +phy_xaui_rx_polarity_flip_94=0x03 +port_phy_addr_124=0xff +port_phy_addr_116=0xff +portmap_92=89:100 +port_phy_addr_108=0xff +portmap_84=81:100 +portmap_76=73:100 +portmap_68=65:100 +port_phy_addr_64=0xff +mem_cache_enable=1 +port_phy_addr_56=0xff +port_phy_addr_48=0xff +parity_enable=1 +xgxs_rx_lane_map_97=0x2130 +xgxs_rx_lane_map_89=0x3210 +port_phy_addr_133=0xff +phy_xaui_rx_polarity_flip_95=0x01 +port_phy_addr_125=0xff +port_phy_addr_117=0xff +portmap_93=90:25:i +port_phy_addr_109=0xff +portmap_85=82:25:i +portmap_77=74:25:i +portmap_69=66:25:i +port_phy_addr_81=0xff +port_phy_addr_73=0xff +port_phy_addr_65=0xff +port_phy_addr_57=0xff +port_phy_addr_49=0xff +xgxs_rx_lane_map_98=0x2130 +port_phy_addr_6=0xff +phy_xaui_tx_polarity_flip_90=0x03 +phy_xaui_rx_polarity_flip_96=0x0c +portmap_94=91:25:50:i +portmap_86=83:25:50:i +portmap_78=75:25:50:i +port_phy_addr_90=0xff +port_phy_addr_82=0xff +port_phy_addr_74=0xff +load_firmware=0x102 +l2xmsg_mode=1 +xgxs_rx_lane_map_99=0x2130 +port_phy_addr_7=0xff +phy_xaui_tx_polarity_flip_91=0x01 +phy_an_c73=0 +port_phy_addr_127=0xff +port_phy_addr_119=0xff +portmap_95=92:25:i +portmap_87=84:25:i +portmap_79=76:25:i +port_phy_addr_91=0xff +port_phy_addr_83=0xff +port_phy_addr_75=0xff +port_phy_addr_59=0xff +mmu_lossless=0x01 +port_phy_addr_8=0xff +phy_xaui_tx_polarity_flip_92=0x04 +phy_xaui_tx_polarity_flip_84=0x04 +phy_xaui_rx_polarity_flip_98=0x03 +port_phy_addr_128=0xff +portmap_96=93:100 +portmap_1=1:100 +portmap_88=85:100 +phy_xaui_tx_polarity_flip_9=0x08 +phy_xaui_rx_polarity_flip_99=0x01 +port_phy_addr_129=0xff +portmap_97=94:25:i +portmap_2=2:25:i +portmap_89=86:25:i +xgxs_tx_lane_map_10=0x3120 +phy_an_c37_100=1 +port_phy_addr_93=0xff +port_phy_addr_85=0xff +port_phy_addr_77=0xff +port_phy_addr_69=0xff +phy_xaui_tx_polarity_flip_94=0x01 +phy_xaui_tx_polarity_flip_86=0x01 +max_vp_lags=0 +l3_max_ecmp_mode=1 +portmap_98=95:25:50:i +portmap_3=3:25:50:i +miim_intr_enable=0x0 +xgxs_tx_lane_map_11=0x3120 +port_phy_addr_94=0xff +port_phy_addr_86=0xff +port_phy_addr_78=0xff +module_64ports=0 +tdma_intr_enable=0 +portmap_100=131:1 +portmap_99=96:25:i +pbmp_oversubscribe=0xC4444451111111144444444422222222 +portmap_4=4:25:i +l3_mem_entries=40960 +xgxs_tx_lane_map_20=0x0213 +xgxs_tx_lane_map_12=0x3120 +num_ipv6_lpm_128b_entries=1024 +port_phy_addr_95=0xff +port_phy_addr_87=0xff +port_phy_addr_79=0xff +ptp_ts_pll_fref=0 +phy_xaui_tx_polarity_flip_96=0x08 +phy_xaui_tx_polarity_flip_88=0x0c +portmap_5=5:100 +xgxs_tx_lane_map_21=0x2310 +xgxs_tx_lane_map_13=0x1023 +tslam_dma_enable=1 +dport_map_direct=0x01 +portmap_110=105:100 +portmap_102=97:100 +portmap_6=6:25:i +xgxs_rx_lane_map_10=0x2301 +xgxs_tx_lane_map_30=0x0213 +xgxs_tx_lane_map_22=0x2310 +xgxs_tx_lane_map_14=0x1023 +phy_an_c73_100=0 +port_phy_addr_97=0xff +port_phy_addr_89=0xff +phy_xaui_tx_polarity_flip_98=0x02 +portmap_111=106:25:i +portmap_103=98:25:i +portmap_7=7:25:50:i +xgxs_rx_lane_map_11=0x2301 +xgxs_tx_lane_map_31=0x0213 +xgxs_tx_lane_map_23=0x2310 +xgxs_tx_lane_map_15=0x1023 +port_phy_addr_98=0xff + diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/default_sku b/device/juniper/x86_64-juniper_qfx5200-r0/default_sku new file mode 100644 index 000000000000..cf933bb4c87a --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/default_sku @@ -0,0 +1 @@ +Juniper-QFX5200-32C-S t1 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/installer.conf b/device/juniper/x86_64-juniper_qfx5200-r0/installer.conf new file mode 100644 index 000000000000..e86aed7e522b --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=9600 +VAR_LOG_SIZE=1024 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/led_proc_init.soc b/device/juniper/x86_64-juniper_qfx5200-r0/led_proc_init.soc new file mode 100644 index 000000000000..f2b749eeba03 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/led_proc_init.soc @@ -0,0 +1,49 @@ +# LED microprocessor initialization for Tomahawk + + + +setreg CMIC_LEDUP0_CLK_DIV 0x54 +setreg CMIC_LEDUP1_CLK_DIV 0x54 +setreg CMIC_LEDUP2_CLK_DIV 0x54 + +led 0 stop +led 0 prog 02 fd 42 80 02 ff 42 00 02 fe 42 00 02 fb 42 40 67 14 3a 40 06 fe 88 88 88 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 86 fe 06 fe d2 10 74 14 57 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 0x411493 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 0x515597 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 0x30d38f +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 0x20928b +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 0xf3dfbf +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 0xe39ebb +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 0xd35db7 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 0xc31cb3 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 0xb2dbaf +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 0xa29aab +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 0x9259a7 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 0x8218a3 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 0x71d79f +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 0x61969b +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 0x105187 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 0x1083 +led 0 auto on +led 0 start + +led 1 stop +led 1 prog 02 fd 42 80 02 ff 42 00 02 fe 42 00 02 fb 42 40 67 14 3a 40 06 fe 88 88 88 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 86 fe 06 fe d2 10 74 14 57 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 0xb2dbaf +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 0xa29aab +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 0xc31cb3 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 0xd35db7 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 0x1083 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 0x105187 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 0x20928b +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 0x30d38f +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 0x411493 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 0x515597 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 0x61969b +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 0x71d79f +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 0x8218a3 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 0x9259a7 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 0xe39ebb +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 0xf3dfbf +led 1 auto on +led 1 start \ No newline at end of file diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json b/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json new file mode 100755 index 000000000000..aec90682bc09 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json @@ -0,0 +1,36 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "0-31": { + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "FINISAR CORP.-FTL4C1QE1C-J1": { + "preemphasis": { + "lane0":"0x115f00", + "lane1":"0x115f00", + "lane2":"0x115f00", + "lane3":"0x115f00" + }, + "idriver": { + "lane0":"0x0", + "lane1":"0x0", + "lane2":"0x0", + "lane3":"0x0" + } + } + } + }, + "PORT_MEDIA_SETTINGS": { + } +} diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/eeprom.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/eeprom.py new file mode 100755 index 000000000000..49a903290a18 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/eeprom.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# +# Name: eeprom.py version: 1.0 +# +# Description: Platform-specific EEPROM interface for Juniper QFX5200 +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +try: + import os + from sonic_eeprom import eeprom_tlvinfo + import syslog + from array import * + +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +SYSLOG_IDENTIFIER = "eeprom.py" +EEPROM_PATH = "/sys/bus/i2c/devices/0-0051/eeprom" + +def log_error(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + + def __init__(self, name, path, cpld_root, ro): + + if not os.path.exists(EEPROM_PATH): + log_error("Cannot find system eeprom") + raise RuntimeError("No syseeprom found") + + self.eeprom_path = EEPROM_PATH + super(board, self).__init__(self.eeprom_path, 0, '', True) + diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/led_control.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/led_control.py new file mode 100755 index 000000000000..d85b65696d69 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/led_control.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python +# +# Name: led_control.py version: 1.0 +# +# Description: Platform-specific LED control functionality for Juniper QFX5200 +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +try: + from sonic_led.led_control_base import LedControlBase + import os + import syslog + import glob + from socket import * + from select import * +except ImportError, e: + raise ImportError(str(e) + " - required module not found") + + + +def DBG_PRINT(str): + syslog.openlog("ledi_control") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + SONIC_PORT_NAME_PREFIX = "Ethernet" + LED_MODE_OFF = 0 + LED_MODE_GREEN = 1 + PORT_START = 0 + PORT_END = 127 + port_to_gpio_pin_mapping = {} + GPIO_SLAVE0_PORT_START = 0 + GPIO_SLAVE0_PORT_END = 63 + GPIO_SLAVE1_PORT_START = 64 + GPIO_SLAVE1_PORT_END = 127 + + GPIO_LANE0_PORT_LED_OFFSET = 64 + GPIO_LANE1_PORT_LED_OFFSET = 80 + GPIO_LANE2_PORT_LED_OFFSET = 96 + GPIO_LANE3_PORT_LED_OFFSET = 112 + + # Turn OFF all port leds during init + def gpio_create_file(self,gpio_pin): + gpio_export_path = "/sys/class/gpio/export" + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + if not os.path.exists(gpio_pin_path): + try: + gpio_export_file = open(gpio_export_path, 'w') + gpio_export_file.write(str(gpio_pin)) + gpio_export_file.close() + except IOError as e: + print "Error: unable to open export file: %s" % str(e) + return False + + return True + + def gpio_port_led_init(self,gpio_base, port): + port_led_pin = gpio_base + self.GPIO_LANE0_PORT_LED_OFFSET + 16*(port%4) + ((port % 64)/4) + if self.gpio_create_file(port_led_pin): + self.port_to_gpio_pin_mapping[port] = port_led_pin + + + def gpio_port_led_slave_init(self,gpio_base_path, gpio_port_start, gpio_port_end): + flist = glob.glob(gpio_base_path) + if len(flist) == 1: + try: + fp = open(flist[0] + "/base") + gpio_base = int(fp.readline().rstrip()) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return + for port in range(gpio_port_start, gpio_port_end + 1): + self.gpio_port_led_init(gpio_base, port) + + + def gpio_port_led_base_init(self): + self.gpio_port_led_slave_init("/sys/bus/platform/drivers/gpioslave-tmc/gpioslave-tmc.22/gpio/gpio*", + self.GPIO_SLAVE0_PORT_START, self.GPIO_SLAVE0_PORT_END) + self.gpio_port_led_slave_init("/sys/bus/platform/drivers/gpioslave-tmc/gpioslave-tmc.21/gpio/gpio*", + self.GPIO_SLAVE1_PORT_START, self.GPIO_SLAVE1_PORT_END) + + + # Write driver for port led + def gpio_led_write(self,gpio_pin, value): + success = False + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + + try: + gpio_file = open(gpio_pin_path +"/value", 'w') + gpio_file.write(str(value)) + success = True + except IOError as e: + print "error: unable to open file: %s" % str(e) + + return success + + # Read driver for port led + def gpio_led_read(self,gpio_pin): + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + value = 0 + + try: + reg_file = open(gpio_pin_path +"/value") + value = int(reg_file.readline().rstrip()) + except IOError as e: + print "error: unable to open file: %s" % str(e) + + return value + + def _initDefaultConfig(self): + DBG_PRINT("start init led") + + for port in range(self.PORT_START, self.PORT_END): + self._port_led_mode_update(self.port_to_gpio_pin_mapping[port], self.LED_MODE_OFF) + + DBG_PRINT("init led done") + + # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): + # Strip "Ethernet" off port name + if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): + return -1 + + port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) + return port_idx + + # Convert state up/down to Green/OFF which is 1/0 + def _port_state_to_mode(self, state): + if state == "up": + return self.LED_MODE_GREEN + else: + return self.LED_MODE_OFF + + + # Set the port led mode to Green/OFF + def _port_led_mode_update(self, gpio_pin, ledMode): + if ledMode == self.LED_MODE_GREEN: + self.gpio_led_write(gpio_pin, 1) + else: + self.gpio_led_write(gpio_pin, 0) + + + # Concrete implementation of port_link_state_change() method + def port_link_state_change(self, portname, state): + port_idx = self._port_name_to_index(portname) + gpio_pin = self.port_to_gpio_pin_mapping[port_idx] + + ledMode = self._port_state_to_mode(state) + saveMode = self.gpio_led_read(gpio_pin) + + if ledMode == saveMode: + return + + self._port_led_mode_update(gpio_pin, ledMode) + DBG_PRINT("update {} led mode from {} to {}".format(portname, saveMode, ledMode)) + + # Constructor + def __init__(self): + self.gpio_port_led_base_init() + self._initDefaultConfig() diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/psuutil.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/psuutil.py new file mode 100755 index 000000000000..a7fef390b2a0 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/psuutil.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# +# Name: psuutil.py version: 1.0 +# +# Description: Platform-specific PSU status interface for Juniper QFX5200 +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + PSU_DIR = "/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/psu-tmc.15" + + def __init__(self): + PsuBase.__init__(self) + + +# Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return int(retval) + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index (starts from 1) of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + attr_file = 'psu'+ str(index-1) +'_' + 'present' + attr_path = self.PSU_DIR +'/' + attr_file + attr_value = self.get_attr_value(attr_path) + + return attr_value == 1 + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + attr_file ='psu'+ str(index-1) +'_' + 'present' + attr_path = self.PSU_DIR +'/' + attr_file + attr_value = self.get_attr_value(attr_path) + return attr_value == 1 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py new file mode 100755 index 000000000000..a5e3d454350c --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py @@ -0,0 +1,415 @@ +#!/usr/bin/env python +# +# Name: juniper_qfx5200_eepromconv.py version: 1.0 +# +# Description: This file contains the code to store the contents of Main Board EEPROM and CPU Board EEPROM in file +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +import os +import commands +import binascii +from sonic_eeprom import eeprom_tlvinfo + +def main(): + eeprom_qfx5200 = Eeprom() + FAN0_TYPE="cat /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan0_type" + + try: + status,fan0_type=commands.getstatusoutput(FAN0_TYPE) + except Exception as e: + print "Error on refpga-tmc.15 fan0_type e:" + str(e) + return False + + AFO = "1" + + # creating the "/var/run/eeprom" file and storing values of CPU board EEPROM and MAIN Board EEPROM in this file. + eeprom_file = open ("/var/run/eeprom", "a+") + eeprom_file.write("\n") + if fan0_type == AFO: + eeprom_file.write("Fan Type=AFO\r\n") + else: + eeprom_file.write("Fan Type=AFI\r\n") + + eeprom_file.write("\n") + + # Write the contents of CPU Board EEPROM to file + eeprom_file.write("CPU board eeprom (0x51)\r\n") + eeprom_file.write("===============================\r\n") + eeprom_file.write("Product Name=%s\r\n" % eeprom_qfx5200.modelstr()) + eeprom_file.write("Part Number=%s\r\n" % eeprom_qfx5200.part_number_str()) + eeprom_file.write("Serial Number=%s\r\n" % eeprom_qfx5200.serial_number_str()) + eeprom_file.write("MAC Address=%s\r\n" % eeprom_qfx5200.base_mac_address()) + eeprom_file.write("Manufacture Date=%s\r\n" % eeprom_qfx5200.manuDate_str()) + eeprom_file.write("Platform Name=%s\r\n" % eeprom_qfx5200.platform_str()) + eeprom_file.write("Number of MAC Addresses=%s\r\n" % eeprom_qfx5200.MACsize_str()) + eeprom_file.write("Vendor Name=%s\r\n" % eeprom_qfx5200.vendor_name_str()) + eeprom_file.write("Manufacture Name=%s\r\n" % eeprom_qfx5200.manufacture_name_str()) + + eeprom_dict = eeprom_qfx5200.system_eeprom_info() + key = '0x29' + if key in eeprom_dict.keys(): + onie_version_str = eeprom_dict.get('0x29', None) + else: + onie_version_str = "N/A" + eeprom_file.write("ONIE Version=%s\r\n" % onie_version_str) + + vendor_value_formatted, vendor_value_hexvalue = eeprom_qfx5200.vendor_ext_str() + + eeprom_hex = '/etc/init.d/eeprom_qfx5200_hex' + + with open(eeprom_hex, 'wb+') as Hexfile: + Hexfile.write(vendor_value_hexvalue) + + # Assembly ID + ASMID_str = "0D83" + with open(eeprom_hex, 'rb+') as AsmID_Hexfile: + AsmID_Hexfile.seek(24, 0) + AsmID_Hexfile.write(ASMID_str) + AsmID_Hexfile.seek(0, 0) + vendorext_read = AsmID_Hexfile.read(58) + vendorext="" + vendorext += "0x" + vendorext_read[0:2] + for i in range(2,58,2): + vendorext += " 0x" + vendorext_read[i:i+2] + eeprom_file.write("Vendor Extension=%s\r\n" % str(vendorext)) + + with open(eeprom_hex, 'rb') as eeprom_hexfile: + eeprom_hexfile.seek(0, 0) + IANA_position_read = eeprom_hexfile.read(8) + IANA_write = binascii.unhexlify(IANA_position_read) + eeprom_file.write("\t") + eeprom_file.write("IANA=0x%s\r\n" % IANA_write) + + eeprom_hexfile.seek(8, 0) + AssemblyPartRev_position_read = eeprom_hexfile.read(16) + AssemblyPartRev_write = binascii.unhexlify(AssemblyPartRev_position_read) + eeprom_file.write("\t") + eeprom_file.write("Assembly Part Number Revision=0x%s\r\n" % AssemblyPartRev_write) + + eeprom_hexfile.seek(24, 0) + AssemblyID_write = eeprom_hexfile.read(4) + eeprom_file.write("\t") + eeprom_file.write("Assembly ID=0x%s\r\n" % AssemblyID_write) + + + eeprom_hexfile.seek(28, 0) + HWMajorRev_write = eeprom_hexfile.read(2) + eeprom_file.write("\t") + eeprom_file.write("HW Major Revision=0x%s\r\n" % HWMajorRev_write) + + + eeprom_hexfile.seek(30, 0) + HWMinorRev_write = eeprom_hexfile.read(2) + eeprom_file.write("\t") + eeprom_file.write("HW Minor Revision=0x%s\r\n" % HWMinorRev_write) + + + eeprom_hexfile.seek(32, 0) + Deviation_write = eeprom_hexfile.read(10) + eeprom_file.write("\t") + eeprom_file.write("Deviation=0x%s\r\n" % Deviation_write) + + + eeprom_hexfile.seek(52, 0) + JEDC_write = eeprom_hexfile.read(4) + eeprom_file.write("\t") + eeprom_file.write("JEDC=0x%s\r\n" % JEDC_write) + + + eeprom_hexfile.seek(56, 0) + EEPROM_version_write = eeprom_hexfile.read(2) + eeprom_file.write("\t") + eeprom_file.write("EEPROM version=0x%s\r\n" % EEPROM_version_write) + + crc_str = eeprom_dict.get('0xFE', None) + eeprom_file.write("CRC=%s\r\n" % crc_str) + + eeprom_file.write("\n") + eeprom_file.write("\n") + eeprom_file.write("Main board eeprom (0x57)\r\n") + eeprom_file.write("===============================\r\n") + + MainEepromCreate = 'sudo echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device' + # Write the contents of Main Board EEPROM to file + try: + os.system(MainEepromCreate) + except OSError: + print 'Error: Execution of "%s" failed', MainEepromCreate + return False + + MainEepromFileCmd = 'cat /sys/bus/i2c/devices/i2c-0/0-0057/eeprom > /etc/init.d/MainEeprom_qfx5200_ascii' + try: + os.system(MainEepromFileCmd) + except OSError: + print 'Error: Execution of "%s" failed', MainEepromFileCmd + return False + + maineeprom_ascii = '/etc/init.d/MainEeprom_qfx5200_ascii' + + # Read file contents in Hex format + with open(maineeprom_ascii, 'rb') as Hexformat: + content = Hexformat.read() + + Hexformatoutput = binascii.hexlify(content) + eeprom_hex = '/etc/init.d/MainEeprom_qfx5200_hex' + #Write contents of CPU EEPROM to new file in hexa format + with open(eeprom_hex, 'wb+') as Hexfile: + Hexfile.write(Hexformatoutput) + + with open(eeprom_hex, 'rb') as eeprom_hexfile: + eeprom_hexfile.seek(8, 0) + AssemblyID_read = eeprom_hexfile.read(4) + eeprom_file.write("Assembly ID=0x%s\r\n" % AssemblyID_read) + + eeprom_hexfile.seek(12, 0) + MajorHWRev_read = eeprom_hexfile.read(2) + eeprom_file.write("Assembly Major Revision=0x%s\r\n" % str(MajorHWRev_read)) + + eeprom_hexfile.seek(14, 0) + MinorHWRev_read = eeprom_hexfile.read(2) + eeprom_file.write("Assembly Minor Revision=0x%s\r\n" % str(MinorHWRev_read)) + + eeprom_hexfile.seek(24, 0) + AssemblyPNRev_read = eeprom_hexfile.read(16) + AssemblyPNRev_write = binascii.unhexlify(AssemblyPNRev_read) + eeprom_file.write("Assembly Part Number Revision=0x%s\r\n" % str(AssemblyPNRev_write)) + + eeprom_hexfile.seek(40, 0) + AssemblyPN_read = eeprom_hexfile.read(24) + AssemblyPN_write = binascii.unhexlify(AssemblyPN_read) + eeprom_file.write("Assembly Part Number=%s\r\n" % str(AssemblyPN_write)) + + eeprom_hexfile.seek(64, 0) + AssemblySN_read = eeprom_hexfile.read(24) + AssemblySN_write = binascii.unhexlify(AssemblySN_read) + eeprom_file.write("Assembly Serial Number=%s\r\n" % str(AssemblySN_write)) + + eeprom_hexfile.seek(90, 0) + AssemblyMFGDate_read = eeprom_hexfile.read(8) + eeprom_file.write("Manufacture Date=%s\r\n" % str(AssemblyMFGDate_read)) + + eeprom_hexfile.seek(138, 0) + CLEICode_read = eeprom_hexfile.read(20) + CLEI_name = binascii.unhexlify(CLEICode_read) + eeprom_file.write("CLEI Code=%s\r\n" % str(CLEI_name)) + + eeprom_hexfile.seek(158, 0) + FRUModelNumber_read = eeprom_hexfile.read(46) + FRUModelNumber_write = binascii.unhexlify(FRUModelNumber_read) + eeprom_file.write("FRU Model Number=%s\r\n" % str(FRUModelNumber_write)) + + eeprom_hexfile.seek(204, 0) + FRUModelMajorNumber_read = eeprom_hexfile.read(2) + eeprom_file.write("FRU Model Major Number=0x%s\r\n" % str(FRUModelMajorNumber_read)) + + eeprom_hexfile.seek(206, 0) + FRUModelMinorNumber_read = eeprom_hexfile.read(4) + eeprom_file.write("FRU Model Minor Number=0x%s\r\n" % str(FRUModelMinorNumber_read)) + + eeprom_hexfile.seek(210, 0) + Deviation_read = eeprom_hexfile.read(10) + eeprom_file.write("Deviation=0x%s\r\n" % str(Deviation_read)) + + eeprom_hexfile.seek(232, 0) + SerialNumber_read = eeprom_hexfile.read(24) + SerialNumber_write = binascii.unhexlify(SerialNumber_read) + eeprom_file.write("Chassis Serial Number=%s\r\n" % str(SerialNumber_write)) + eeprom_file.close() + return True + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + def __init__(self): + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0051/eeprom" + super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True) + self.__eeprom_tlv_dict = dict() + try: + self.__eeprom_data = self.read_eeprom() + except: + self.__eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.__eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + ord(eeprom[tlv_index + 1])] + code = "0x%02X" % (ord(tlv[0])) + + if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | + (ord(tlv[4]) << 8) | ord(tlv[5])) + value += str(tlv[6:6 + ord(tlv[1])]) + else: + name, value = self.decoder(None, tlv) + + self.__eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+1]) + 2 + + def serial_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2] + + def base_mac_address(self): + (is_valid, t) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(self.__eeprom_data) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def serial_tag_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2] + + def revision_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2] + + def manuDate_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MANUF_DATE) + if not is_valid: + return "N/A" + + return results[2] + + def platform_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PLATFORM_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def MACsize_str(self): + (is_valid, t) = self.get_tlv_field(self.__eeprom_data, self._TLV_CODE_MAC_SIZE) + + if not is_valid: + return "N/A" + + return str((ord(t[2][0]) << 8) | ord(t[2][1])) + + def vendor_name_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_VENDOR_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def manufacture_name_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MANUF_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def onie_version_str(self): + value = "" + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_ONIE_VERSION) + if not is_valid: + return "N/A" + + for c in results[2:2 + ord(results[1])]: + value += "0x%02X " % (ord(c),) + + return value + + def vendor_ext_str(self): + + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_VENDOR_EXT) + + if not is_valid: + return "N/A" + + vendor_value_formatted = ''.join( [ " 0x" + "%02X " % ord( x ) for x in results[2] ] ).strip() + vendor_value_hexvalue = ''.join( ["%02X" % ord( x ) for x in results[2] ] ).strip() + + return vendor_value_formatted, vendor_value_hexvalue + + def crc_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_CRC_32) + if not is_valid: + return "N/A" + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.__eeprom_tlv_dict + +if __name__ == "__main__": + main() diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py new file mode 100755 index 000000000000..c6846ec12a8a --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# +# Name: juniper_sfp_init.py version: 1.0 +# +# Description: Platform-specific SFP Transceiver Initialization for Juniper QFX5200 +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +import time +import os.path +import sfputil as jnpr_sfp +from pprint import pprint + +DEBUG = False + +def i2c_eeprom_dev_update(port, create_eeprom): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + i2c_path = "/sys/class/i2c-adapter/i2c-{0}" + i2c_port = port + jnpr_sfp.SFP_I2C_OFFSET + port_eeprom_path = eeprom_path.format(i2c_port) + port_i2c_path = i2c_path.format(i2c_port) + if create_eeprom: + if not os.path.exists(port_eeprom_path): + try: + i2c_file = open(port_i2c_path + "/new_device", "w") + i2c_file.write("optoe2 0x50") + except IOError as e: + print "Error: unable to write to i2c file: %s" % str(e) + return + else: + if os.path.exists(port_eeprom_path): + try: + i2c_file = open(port_i2c_path + "/delete_device", "w") + i2c_file.write("0x50") + except IOError as e: + print "Error: unable to write to i2c file: %s" % str(e) + return + +def gpio_sfp_init(): + jnpr_sfp.gpio_sfp_base_init() + + time.sleep(2) + + #Reset all ports + for port in range(jnpr_sfp.GPIO_PORT_START, jnpr_sfp.GPIO_PORT_END + 1): + port_inited = False + if jnpr_sfp.gpio_sfp_presence_get(port): + port_inited = jnpr_sfp.gpio_sfp_reset_set(port, 0) + + if port_inited: + i2c_eeprom_dev_update(port, True) + else: + i2c_eeprom_dev_update(port, False) + + time.sleep(2) + + #Enable optics for all ports which have XCVRs present + for port in range(jnpr_sfp.GPIO_PORT_START, jnpr_sfp.GPIO_PORT_END + 1): + if jnpr_sfp.gpio_sfp_presence_get(port): + jnpr_sfp.gpio_sfp_lpmode_set(port, 1) + + time.sleep(2) + + +if __name__ == '__main__': + + if DEBUG == True: + print "Initializing Juniper SFP module" + + gpio_sfp_init() + if DEBUG == True: + print "Juniper GPIO presence pin mapping:" + pprint(jnpr_sfp.gpio_sfp_presence) + print "Juniper GPIO reset pin mapping:" + pprint(jnpr_sfp.gpio_sfp_reset) + print "Juniper GPIO lpmode pin mapping:" + pprint(jnpr_sfp.gpio_sfp_lpmode) diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py new file mode 100755 index 000000000000..2e3e453403a2 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py @@ -0,0 +1,884 @@ +#!/usr/bin/env python +# +# Name: sfputil.py version: 1.0 +# +# Description: Platform-specific SFP transceiver interface for Juniper QFX5200 +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +try: + import time + import os.path + import glob + from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from ctypes import create_string_buffer + +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +qfx5200_qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +qfx5200_sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +qfx5200_sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes','FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia','FibreChannelSpeed') + +qfx5200_qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + + +GPIO_SLAVE0_PORT_START = 0 +GPIO_SLAVE0_PORT_END = 15 +GPIO_SLAVE1_PORT_START = 16 +GPIO_SLAVE1_PORT_END = 31 + +GPIO_PORT_START = 0 +GPIO_PORT_END = 31 + +GPIO_PRESENCE_OFFSET = 16 +GPIO_LPMODE_OFFSET = 48 +GPIO_RESET_OFFSET = 0 + +gpio_sfp_presence = {} +gpio_sfp_lpmode = {} +gpio_sfp_reset = {} + +SFP_I2C_OFFSET = 14 + + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_WIDTH = 1 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 + +#definitions of the offset and width for values in DOM info eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 + + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 + + +def gpio_create_file(gpio_pin): + gpio_export_path = "/sys/class/gpio/export" + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + if not os.path.exists(gpio_pin_path): + try: + gpio_export_file = open(gpio_export_path, 'w') + gpio_export_file.write(str(gpio_pin)) + gpio_export_file.close() + except IOError as e: + print "Error: unable to open export file: %s" % str(e) + return False + + return True + +def gpio_sfp_port_init(gpio_base, port): + presence_pin = gpio_base + GPIO_PRESENCE_OFFSET + (port % 16) + if gpio_create_file(presence_pin): + gpio_sfp_presence[port] = presence_pin + reset_pin = gpio_base + GPIO_RESET_OFFSET + (port % 16) + if gpio_create_file(reset_pin): + gpio_sfp_reset[port] = reset_pin + lpmode_pin = gpio_base + GPIO_LPMODE_OFFSET + (port % 16) + if gpio_create_file(lpmode_pin): + gpio_sfp_lpmode[port] = lpmode_pin + + +def gpio_sfp_slave_init(gpio_base_path, gpio_port_start, gpio_port_end): + flist = glob.glob(gpio_base_path) + if len(flist) == 1: + try: + fp = open(flist[0]+"/base") + gpio_base = int(fp.readline().rstrip()) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return + + for port in range(gpio_port_start, gpio_port_end + 1): + gpio_sfp_port_init(gpio_base, port) + +def gpio_sfp_base_init(): + gpio_sfp_slave_init("/sys/bus/platform/drivers/gpioslave-tmc/gpioslave-tmc.21/gpio/gpio*", + GPIO_SLAVE0_PORT_START, GPIO_SLAVE0_PORT_END) + gpio_sfp_slave_init("/sys/bus/platform/drivers/gpioslave-tmc/gpioslave-tmc.22/gpio/gpio*", + GPIO_SLAVE1_PORT_START, GPIO_SLAVE1_PORT_END) + +def gpio_sfp_read(gpio_pin): + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + value = 0 + + try: + reg_file = open(gpio_pin_path +"/value") + value = int(reg_file.readline().rstrip()) + except IOError as e: + print "error: unable to open file: %s" % str(e) + + return value + +def gpio_sfp_write(gpio_pin, value): + success = False + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + + try: + gpio_file = open(gpio_pin_path +"/value", 'w') + gpio_file.write(str(value)) + success = True + except IOError as e: + print "error: unable to open file: %s" % str(e) + + return success + +def gpio_sfp_presence_get(port): + if port not in gpio_sfp_presence.keys(): + print "Port:" + str(port) + " not in sfp dict" + return 0 + + gpio_pin = gpio_sfp_presence[port] + return gpio_sfp_read(gpio_pin) + +def gpio_sfp_lpmode_get(port): + if port not in gpio_sfp_lpmode.keys(): + return 0 + + gpio_pin = gpio_sfp_lpmode[port] + return gpio_sfp_read(gpio_pin) + +def gpio_sfp_lpmode_set(port, value): + if port not in gpio_sfp_lpmode.keys(): + return False + + gpio_pin = gpio_sfp_lpmode[port] + return gpio_sfp_write(gpio_pin, value) + +def gpio_sfp_reset_set(port, value): + if port not in gpio_sfp_reset.keys(): + return False + + gpio_pin = gpio_sfp_reset[port] + return gpio_sfp_write(gpio_pin, value) + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 31 + PORTS_IN_BLOCK = 32 + QSFP_PORT_START = 0 + QSFP_PORT_END = 31 + + cmd = '/var/run/sfppresence' + + _port_to_eeprom_mapping = {} + port_to_i2cbus_mapping = { + 0: 14, + 1: 15, + 2: 16, + 3: 17, + 4: 18, + 5: 19, + 6: 20, + 7: 21, + 8: 22, + 9: 23, + 10: 24, + 11: 25, + 12: 26, + 13: 27, + 14: 28, + 15: 29, + 16: 30, + 17: 31, + 18: 32, + 19: 33, + 20: 34, + 21: 35, + 22: 36, + 23: 37, + 24: 38, + 25: 39, + 26: 40, + 27: 41, + 28: 42, + 29: 43, + 30: 44, + 31: 45 + } + + port_ctle_settings = { + 0: 7, + 1: 6, + 2: 6, + 3: 6, + 4: 6, + 5: 5, + 6: 6, + 7: 5, + 8: 5, + 9: 5, + 10: 7, + 11: 7, + 12: 6, + 13: 5, + 14: 4, + 15: 3, + 16: 4, + 17: 5, + 18: 6, + 19: 6, + 20: 7, + 21: 6, + 22: 5, + 23: 5, + 24: 5, + 25: 5, + 26: 6, + 27: 5, + 28: 6, + 29: 6, + 30: 7, + 31: 7 + } + + optics_list_100g = { + "AFBR-89CDDZ-JU1", + "FTLC9551REPM-J1", + "LUX42604CO", + "EOLQ-161HG-10-LJ1", + "FTLC1151RDPL-J1", + "TR-FC13R-NJ3", + "SPQ-CE-LR-CDFB-J2" + } + + def is_100g_optics(self,part_num): + ret = part_num in self.optics_list_100g + return ret + + def process_TxCTLE(self, port_num, part_num): + + eeprom = None + + try: + if self.is_100g_optics(part_num): + # Accessing page 3 of optics + regval = 0x3 + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + eeprom = open(self._port_to_eeprom_mapping[port_num], "r+b") + eeprom.seek(127) + eeprom.write(buffer[0]) + + regval = self.port_ctle_settings[port_num] + + eeprom.seek(234) + buffer[0] = eeprom.read(1) + if (buffer[0] != chr(regval)): + buffer[0] = chr(regval) + eeprom.write(buffer[0]) + eeprom.seek(235) + eeprom.write(buffer[0]) + else: + pass + # Moving back the optics page to 0 + regval = 0x0 + buffer[0] = chr(regval) + eeprom.seek(127) + eeprom.write(buffer[0]) + else: + pass + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + finally: + if eeprom is not None: + eeprom.close + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_port_start(self): + return self.QSFP_PORT_START + + @property + def qsfp_port_end(self): + return self.QSFP_PORT_END + + @property + def qsfp_ports(self): + return range(0, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + gpio_sfp_base_init() + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + for x in range(0, self.port_end + 1): + self.port_to_eeprom_mapping[x] = eeprom_path.format(self.port_to_i2cbus_mapping[x]) + + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + reg_value = gpio_sfp_presence_get(port_num) + if reg_value == 1: + return True + + return False + + def get_low_power_mode(self, port_num): + reg_value = gpio_sfp_lpmode_get(port_num) + if reg_value == 1: + return True + + return False + + def set_low_power_mode(self, port_num, lpmode): + + if lpmode == False: + lpmode = 0 + else: + lpmode = 1 + + status = gpio_sfp_lpmode_set(port_num, lpmode) + return status + + def reset(self, port_num): + reset_val = 0 + status = gpio_sfp_reset_set(port_num, reset_val) + return status + + # Writing to a file from a list + def write_to_file(self, file_name, from_list): + try: + fp1 = open(file_name, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + for i in from_list: + fp1.write(i) + fp1.write('\n') + + fp1.close() + return True + + + # Reading from a file to a list + def read_from_file(self, file_name): + try: + fp = open(file_name, 'r') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + to_list = fp.readlines() + to_list = [x.rstrip() for x in to_list] + fp.close() + return to_list + + def sfp_detect(self): + port = 0 + ret_dict = {} + defl_dict = {} + current_sfp_values = [0] * 32 + previous_sfp_values = [0] * 32 + + if not os.path.isfile(self.cmd): + pass + else: + if (self.read_from_file(self.cmd) == False): + return False, defl_dict + else: + previous_sfp_values = self.read_from_file(self.cmd) + + # Read the current values from sysfs + for port in range(GPIO_PORT_START, GPIO_PORT_END + 1): + sfp_present = gpio_sfp_presence_get(port) + current_sfp_values[port] = str(sfp_present) + ret_dict.update({port:current_sfp_values[port]}) + if (current_sfp_values[port] != previous_sfp_values[port]): + ret_dict.update({port:current_sfp_values[port]}) + if(self.write_to_file(self.cmd, current_sfp_values) == True): + return True, ret_dict + else: + return False, defl_dict + + # Read out SFP type, vendor name, PN, REV, SN from eeprom. + def get_transceiver_info_dict(self, port_num): + transceiver_info_dict = {} + compliance_code_dict = {} + + # ToDo: OSFP tranceiver info parsing not fully supported. + # in inf8628.py lack of some memory map definition + # will be implemented when the inf8628 memory map ready + if port_num in self.osfp_ports: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + + sfpi_obj = inf8628InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + print("Error, file not exist %s" % file_path) + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfp_type_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_type_data['data']['type_abbrv_name']['value'] + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + # Below part is added to avoid fail the xcvrd, shall be implemented later + transceiver_info_dict['vendor_oui'] = 'N/A' + transceiver_info_dict['vendor_date'] = 'N/A' + transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['encoding'] = 'N/A' + transceiver_info_dict['ext_identifier'] = 'N/A' + transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' + transceiver_info_dict['cable_type'] = 'N/A' + transceiver_info_dict['cable_length'] = 'N/A' + transceiver_info_dict['specification_compliance'] = 'N/A' + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + + else: + if port_num in self.qsfp_ports: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + print("Error, file not exist %s" % file_path) + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfp_interface_bulk_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) + if sfp_interface_bulk_raw is not None: + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + else: + return None + + sfp_vendor_oui_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + else: + return None + + sfp_vendor_date_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + if sfp_vendor_date_raw is not None: + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + if sfp_type == 'QSFP': + for key in qfx5200_qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + break + else: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = 'N/A' + + for key in qfx5200_qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + if sfp_interface_bulk_data['data'].has_key('Nominal Bit Rate(100Mbs)'): + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + else: + for key in qfx5200_sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + else: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = 'N/A' + + for key in qfx5200_sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + if sfp_interface_bulk_data['data'].has_key('NominalSignallingRate(UnitsOf100Mbd)'): + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + else: + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + + sfp_pn_num = str(sfp_vendor_pn_data['data']['Vendor PN']['value']) + self.process_TxCTLE(port_num,sfp_pn_num) + + return transceiver_info_dict + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + if port_num in self.osfp_ports: + # Below part is added to avoid fail xcvrd, shall be implemented later + transceiver_dom_info_dict['temperature'] = 'N/A' + transceiver_dom_info_dict['voltage'] = 'N/A' + transceiver_dom_info_dict['rx1power'] = 'N/A' + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = 'N/A' + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + elif port_num in self.qsfp_ports: + offset = 0 + offset_xcvr = 128 + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return None + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return None + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + else: + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return None + + transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + else: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + else: + return None + + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return None + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + + def get_transceiver_change_event(self, timeout=2000): + time.sleep(3) + return self.sfp_detect() diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/pmon_daemon_control.json b/device/juniper/x86_64-juniper_qfx5200-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..1863ee2e5190 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_thermalctld": true +} diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index b833f9ee2bc3..11cc40e8fcdc 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -57,7 +57,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(BRCM_XLR_GTS_PLATFORM_MODULE) \ $(DELTA_AG9032V2A_PLATFORM_MODULE) \ $(JUNIPER_QFX5210_PLATFORM_MODULE) \ - $(CEL_SILVERSTONE_PLATFORM_MODULE) + $(CEL_SILVERSTONE_PLATFORM_MODULE) \ + $(JUNIPER_QFX5200_PLATFORM_MODULE) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/broadcom/platform-modules-juniper.mk b/platform/broadcom/platform-modules-juniper.mk index 083dabda6d97..4dcf9c071599 100755 --- a/platform/broadcom/platform-modules-juniper.mk +++ b/platform/broadcom/platform-modules-juniper.mk @@ -1,8 +1,10 @@ # Juniper Platform modules JUNIPER_QFX5210_PLATFORM_MODULE_VERSION = 1.1 +JUNIPER_QFX5200_PLATFORM_MODULE_VERSION = 1.1 export JUNIPER_QFX5210_PLATFORM_MODULE_VERSION +export JUNIPER_QFX5200_PLATFORM_MODULE_VERSION JUNIPER_QFX5210_PLATFORM_MODULE = sonic-platform-juniper-qfx5210_$(JUNIPER_QFX5210_PLATFORM_MODULE_VERSION)_amd64.deb $(JUNIPER_QFX5210_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-juniper @@ -10,4 +12,9 @@ $(JUNIPER_QFX5210_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_C $(JUNIPER_QFX5210_PLATFORM_MODULE)_PLATFORM = x86_64-juniper_qfx5210-r0 SONIC_DPKG_DEBS += $(JUNIPER_QFX5210_PLATFORM_MODULE) +JUNIPER_QFX5200_PLATFORM_MODULE = sonic-platform-juniper-qfx5200_$(JUNIPER_QFX5200_PLATFORM_MODULE_VERSION)_amd64.deb +$(JUNIPER_QFX5200_PLATFORM_MODULE)_PLATFORM = x86_64-juniper_qfx5200-r0 + +$(eval $(call add_extra_package,$(JUNIPER_QFX5210_PLATFORM_MODULE),$(JUNIPER_QFX5200_PLATFORM_MODULE))) + SONIC_STRETCH_DEBS += $(JUNIPER_QFX5210_PLATFORM_MODULE) diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/control b/platform/broadcom/sonic-platform-modules-juniper/debian/control index c9310069f9f9..9c3d12685a47 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/control +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/control @@ -9,3 +9,6 @@ Package: sonic-platform-juniper-qfx5210 Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp +Package: sonic-platform-juniper-qfx5200 +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/rules b/platform/broadcom/sonic-platform-modules-juniper/debian/rules index 2be5594acd3d..d8241eef744d 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/rules +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/rules @@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-juniper KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= qfx5210 +MODULE_DIRS:= qfx5210 qfx5200 MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install new file mode 100644 index 000000000000..53692f8fd21b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install @@ -0,0 +1,5 @@ +qfx5200/utils/juniper_qfx5200_util.py usr/local/bin +qfx5200/utils/juniper_qfx5200_monitor.py usr/local/bin +qfx5200/sonic_platform/chassis.py usr/lib/python2.7/dist-packages/sonic_platform +qfx5200/sonic_platform/platform.py usr/lib/python2.7/dist-packages/sonic_platform +qfx5200/service/qfx5200-platform-init.service etc/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst new file mode 100644 index 000000000000..195f30e66820 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst @@ -0,0 +1,31 @@ +#!/bin/bash + +systemctl enable qfx5200-platform-init.service +systemctl start qfx5200-platform-init.service + +# There are primary and secondary bios in qfx5200 platform. +# There is a problem with bios which prevents the OS booting from the +# secondary bios when the OS was installed using primary bios. +# Secondary bios fails to detect the UEFI partition. Right now +# the workaround is to have a folder structure /EFI/BOOT/BOOT64x.efi + +SONIC_VERSION=$(sonic-cfggen -y /etc/sonic/sonic_version.yml -v build_version) +FIRST_BOOT_FILE="/host/image-${SONIC_VERSION}/platform/firsttime" + +if [ -f $FIRST_BOOT_FILE ]; then + mkdir /tmp/sda1 + mount /dev/sda1 /tmp/sda1 + cd /tmp/sda1/EFI + mkdir BOOT > /dev/null 2>&1 + cp SONiC-OS/grubx64.efi BOOT/BOOTX64.EFI + cd /tmp + umount sda1 + # This code block ensures that no additional entries + # are added. This is applicable during SONiC image + # upgrades. + entries=`efibootmgr -v | grep "BOOTX64"` + if [ -z "$entries" ]; then + # Creating the UEFI entry for the first time. + efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /var/tmp/efi_log 2>&1 + fi +fi diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/Makefile b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/Makefile new file mode 100644 index 000000000000..2b9cc2c22f71 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/Makefile @@ -0,0 +1 @@ +obj-m:=jnx-tmc-core.o i2c-tmc.o jnx-refpga-tmc.o leds-jnx-tmc.o gpio-tmc.o jnx-tmc-psu.o jnx-psu-monitor.o jnx-refpga-lpcm.o diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c new file mode 100644 index 000000000000..7b02e8a5bc74 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c @@ -0,0 +1,661 @@ +/* + * Juniper Networks TMC GPIO driver + * + * Copyright (C) 2020 Juniper Networks + * Author: Ashish Bhensdadia + * + * This driver implement the GPIO set/get functionality + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jnx-tmc.h" + +#define TMC_GPIO_MAX_BITS_PER_REG 16 +#define TMC_GPIO_SFP_MAX_BITS_PER_REG 2 +#define TMC_GPIO_PTPCFG_MAX_BITS_PER_REG 8 + +#define TMC_GPIO_FIND_GROUP(gpio) \ + ((gpio) / TMC_GPIO_MAX_BITS_PER_REG) +#define TMC_GPIO_FIND_GPIO(gpio) \ + ((gpio) % TMC_GPIO_MAX_BITS_PER_REG) + +#define TMC_GPIO_SFP_FIND_GROUP(gpio) \ + ((gpio) / TMC_GPIO_SFP_MAX_BITS_PER_REG) +#define TMC_GPIO_SFP_FIND_GPIO(gpio) \ + ((gpio) % TMC_GPIO_SFP_MAX_BITS_PER_REG) + +#define TMC_GPIO_PTPCFG_FIND_GPIO(gpio) \ + ((gpio) % TMC_GPIO_PTPCFG_MAX_BITS_PER_REG) + +#define TMC_GPIO_MAX_NGPIO_PER_GROUP 320 + +#define TMC_PFE_QSFP_RESET_OFFSET 0x4 +#define TMC_PFE_QSFP_PRESENT_OFFSET 0x8 +#define TMC_PFE_QSFP_PHY_RESET_OFFSET 0x10 +#define TMC_PFE_QSFP_LPMOD_OFFSET 0x78 +#define TMC_PFE_QSFP_LED_CTRL_OFFSET 0x20 + +#define TMC_PFE_LANES_GREEN_LED_VALUE 0x3 +#define TMC_PFE_LANE0_GREEN_LED_BIT_POSITION 0 +#define TMC_PFE_LANE1_GREEN_LED_BIT_POSITION 2 +#define TMC_PFE_LANE2_GREEN_LED_BIT_POSITION 4 +#define TMC_PFE_LANE3_GREEN_LED_BIT_POSITION 6 + +#define TMC_PFE_LANES_BEACON_LED_VALUE 0x2 +#define TMC_PFE_LANE0_BEACON_LED_BIT_POSITION 0 +#define TMC_PFE_LANE1_BEACON_LED_BIT_POSITION 2 +#define TMC_PFE_LANE2_BEACON_LED_BIT_POSITION 4 +#define TMC_PFE_LANE3_BEACON_LED_BIT_POSITION 6 + +#define TMC_PFE_LANES_FAULT_LED_VALUE 0x1 +#define TMC_PFE_LANE0_FAULT_LED_BIT_POSITION 0 +#define TMC_PFE_LANE1_FAULT_LED_BIT_POSITION 2 +#define TMC_PFE_LANE2_FAULT_LED_BIT_POSITION 4 +#define TMC_PFE_LANE3_FAULT_LED_BIT_POSITION 6 + +#define TMC_PFE_SFPSB0_TX_DISABLE_OFFSET 0x0 +#define TMC_PFE_SFPSB0_LED_CTRL_OFFSET 0xC +#define TMC_PFE_SFPSB0_LED_ACTIVITY_OFFSET 0x14 +#define TMC_PFE_SFPSB0_PRESENT_OFFSET 0x18 +#define TMC_PFE_SFPSB0_LOSS_OFFSET 0x1C +#define TMC_PFE_SFPSB0_TX_FAULT_OFFSET 0x20 + +#define TMC_PFE_SFPSB1_TX_DISABLE_OFFSET 0x0 +#define TMC_PFE_SFPSB1_LED_CTRL_OFFSET 0x8 +#define TMC_PFE_SFPSB1_LED_ACTIVITY_OFFSET 0x10 +#define TMC_PFE_SFPSB1_PRESENT_OFFSET 0x14 +#define TMC_PFE_SFPSB1_LOSS_OFFSET 0x18 +#define TMC_PFE_SFPSB1_TX_FAULT_OFFSET 0x1C + +/* + * Index 4 to 15 is used for QSFP starting with + * QSFP_LED_LANE0_GREEN. To keep multibit set/get common + * starting SFP_LED_LANE0_GREEN with 16 which will avoid + * conflict with QSFP enums. + */ +#define SFP_LED_OP_START_INDEX 16 + +/* + * Used for off-setting SFP led op index + */ +#define SFP_LED_OP_OFFSET 0xB + +/* + * SFP slave blocks + */ +#define SFP_SLAVE0_BLOCK 0x1 +#define SFP_SLAVE1_BLOCK 0x2 + +/* + * each group represent the 16 gpios. + * QSFP_RST - QSFP_LPMODE + * each bit represent the one gpio + * exemple: bits[0:15] - bit0 - gpio0 + * QSFP_LED_LANE0_GREEN - QSFP_LED_LANE3_FAULT + * here, number represent the one gpio + * exemple: bits[0:1] + * 00 - gpio off, 01 - gpio on [ gpio0] + * 00 - gpio off, 10 - gpio on [ gpio1] + * 00 - gpio off, 11 - gpio on [ gpio2] + * + */ +enum { + QSFP_RST, + QSFP_PRESENT, + QSFP_PHY_RST, + QSFP_LPMOD, + QSFP_LED_LANE0_GREEN, + QSFP_LED_LANE1_GREEN, + QSFP_LED_LANE2_GREEN, + QSFP_LED_LANE3_GREEN, + QSFP_LED_LANE0_BEACON, + QSFP_LED_LANE1_BEACON, + QSFP_LED_LANE2_BEACON, + QSFP_LED_LANE3_BEACON, + QSFP_LED_LANE0_FAULT, + QSFP_LED_LANE1_FAULT, + QSFP_LED_LANE2_FAULT, + QSFP_LED_LANE3_FAULT, + TMC_PFE_GPIO_GROUP_MAX +}; + +enum sfp_op { + SFP_TX_DISABLE, + SFP_LED_ACTIVITY, + SFP_PRESENT, + SFP_SFP_LOS, + SFP_TX_FAULT, + SFP_LED_LANE0_GREEN = SFP_LED_OP_START_INDEX, + SFP_LED_LANE1_GREEN, + SFP_LED_LANE2_GREEN, + SFP_LED_LANE3_GREEN, + SFP_LED_LANE0_BEACON, + SFP_LED_LANE1_BEACON, + SFP_LED_LANE2_BEACON, + SFP_LED_LANE3_BEACON, + SFP_LED_LANE0_FAULT, + SFP_LED_LANE1_FAULT, + SFP_LED_LANE2_FAULT, + SFP_LED_LANE3_FAULT, + TMC_PFE_SFP_GPIO_GROUP_MAX +}; + +static const u32 group_offset[TMC_PFE_GPIO_GROUP_MAX] = { + TMC_PFE_QSFP_RESET_OFFSET, + TMC_PFE_QSFP_PRESENT_OFFSET, + TMC_PFE_QSFP_PHY_RESET_OFFSET, + TMC_PFE_QSFP_LPMOD_OFFSET, + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 FAULT */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 FAULT */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 FAULT */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 FAULT */ +}; + +static const u32 sfp_slaveb0_group_offset[TMC_PFE_SFP_GPIO_GROUP_MAX] = { + TMC_PFE_SFPSB0_TX_DISABLE_OFFSET, + TMC_PFE_SFPSB0_LED_ACTIVITY_OFFSET, + TMC_PFE_SFPSB0_PRESENT_OFFSET, + TMC_PFE_SFPSB0_LOSS_OFFSET, + TMC_PFE_SFPSB0_TX_FAULT_OFFSET, + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 FAULT */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 FAULT */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 FAULT */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 FAULT */ +}; + +static const u32 sfp_slaveb1_group_offset[TMC_PFE_SFP_GPIO_GROUP_MAX] = { + TMC_PFE_SFPSB1_TX_DISABLE_OFFSET, + TMC_PFE_SFPSB1_LED_ACTIVITY_OFFSET, + TMC_PFE_SFPSB1_PRESENT_OFFSET, + TMC_PFE_SFPSB1_LOSS_OFFSET, + TMC_PFE_SFPSB1_TX_FAULT_OFFSET, + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 FAULT */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 FAULT */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 FAULT */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 FAULT */ +}; + +struct tmc_gpio_info { + int (*get)(struct gpio_chip *, unsigned int); + void (*set)(struct gpio_chip *, unsigned int, int); + int (*dirin)(struct gpio_chip *, unsigned int); + int (*dirout)(struct gpio_chip *, unsigned int, int); +}; + +struct tmc_gpio_chip { + const struct tmc_gpio_info *info; + void __iomem *base; + struct device *dev; + struct gpio_chip gpio; + int ngpio; + spinlock_t gpio_lock; /* gpio lock */ + int sfp_slave_block; +}; + +/* slave gpio max */ +static int gpio_max = 320; +module_param(gpio_max, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(gpio_max, "Maximum number of gpio for SLAVE TMC GPIO"); + +/* + * generic bit operation functions + */ +static u32 tmc_gpio_reset_bits(u32 state, u32 val, u32 shift) +{ + state &= ~(val << shift); + return state; +}; + +static u32 tmc_gpio_set_bits(u32 state, u32 val, u32 shift) +{ + state |= (val << shift); + return state; +}; + +static u32 tmc_gpio_find_bits_val(u32 state, u32 shift, u32 mask) +{ + return ((state >> shift)) & mask; +}; + +#define to_tmc_chip(chip) \ + container_of((chip), struct tmc_gpio_chip, gpio) + +/* + * tmc_gpio_multiple_bitsop - Generic TMC GPIO multiple bits operation + */ +static void tmc_gpio_multiple_bitsop(struct tmc_gpio_chip *chip, + unsigned int gpiono, u32 group, u32 offset, bool set) +{ + u32 gpio_state, led_val, bit_shift; + unsigned long flags; + void __iomem *iobase; + + iobase = chip->base + offset; + + dev_dbg(chip->dev, "TMC GPIO multiple bitop group=%u, " + "gpiono=%u, offet:=%u, set=%u\n", group, gpiono, offset, set); + + spin_lock_irqsave(&chip->gpio_lock, flags); + + switch (group) { + case QSFP_LED_LANE0_GREEN: + case SFP_LED_LANE0_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE0_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE1_GREEN: + case SFP_LED_LANE1_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE1_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE2_GREEN: + case SFP_LED_LANE2_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE2_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE3_GREEN: + case SFP_LED_LANE3_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE3_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE0_BEACON: + case SFP_LED_LANE0_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE0_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE1_BEACON: + case SFP_LED_LANE1_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE1_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE2_BEACON: + case SFP_LED_LANE2_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE2_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE3_BEACON: + case SFP_LED_LANE3_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE3_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE0_FAULT: + case SFP_LED_LANE0_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE0_FAULT_LED_BIT_POSITION; + break; + case QSFP_LED_LANE1_FAULT: + case SFP_LED_LANE1_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE1_FAULT_LED_BIT_POSITION; + break; + case QSFP_LED_LANE2_FAULT: + case SFP_LED_LANE2_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE2_FAULT_LED_BIT_POSITION; + break; + case QSFP_LED_LANE3_FAULT: + case SFP_LED_LANE3_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE3_FAULT_LED_BIT_POSITION; + break; + + default: + spin_unlock_irqrestore(&chip->gpio_lock, flags); + return; + } + + if (set) { + gpio_state = tmc_gpio_reset_bits(gpio_state, 0x3, bit_shift); + gpio_state = tmc_gpio_set_bits(gpio_state, led_val, bit_shift); + } else { + gpio_state = tmc_gpio_reset_bits(gpio_state, 0x3, bit_shift); + } + + iowrite32(gpio_state, (iobase+(0x004*gpiono))); + + spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return; +}; + +/* + * tmc_gpio_one_bitop - Generic TMC GPIO single bit operation + */ +static void tmc_gpio_one_bitop(struct tmc_gpio_chip *chip, + unsigned int bit, u32 offset, bool set) +{ + u32 gpio_state; + unsigned long flags; + void __iomem *iobase; + + iobase = chip->base + offset; + + dev_dbg(chip->dev, "TMC GPIO one bitop bit=%u, offset=%x, " + "set=%u\n", bit, offset, set); + + spin_lock_irqsave(&chip->gpio_lock, flags); + + gpio_state = ioread32(iobase); + if (set) + gpio_state |= BIT(bit); + else + gpio_state &= ~BIT(bit); + + iowrite32(gpio_state, iobase); + + spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return; +} + +/* + * tmc_gpio_get_multiple_bitsop - Generic TMC get GPIO multiple bits operation + */ +static int tmc_gpio_get_multiple_bitsop(struct tmc_gpio_chip *chip, + unsigned int gpiono, u32 group, u32 offset) +{ + u32 gpio_state; + void __iomem *iobase; + + iobase = chip->base + offset; + + dev_dbg(chip->dev, "TMC GPIO get multiple bitsop group=%u, " + "gpiono=%u, offset=%u\n", group, gpiono, offset); + + switch (group) { + case QSFP_LED_LANE0_GREEN: + case SFP_LED_LANE0_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE0_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE1_GREEN: + case SFP_LED_LANE1_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE1_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE2_GREEN: + case SFP_LED_LANE2_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE2_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE3_GREEN: + case SFP_LED_LANE3_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE3_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE0_BEACON: + case SFP_LED_LANE0_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE0_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE1_BEACON: + case SFP_LED_LANE1_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE1_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE2_BEACON: + case SFP_LED_LANE2_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE2_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE3_BEACON: + case SFP_LED_LANE3_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE3_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE0_FAULT: + case SFP_LED_LANE0_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE0_FAULT_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE1_FAULT: + case SFP_LED_LANE1_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE1_FAULT_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE2_FAULT: + case SFP_LED_LANE2_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE2_FAULT_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE3_FAULT: + case SFP_LED_LANE3_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE3_FAULT_LED_BIT_POSITION, 0x3)); + default: + return 0; + } +}; + +/* + * tmc_gpio_get - Read the specified signal of the GPIO device. + */ +static int tmc_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct tmc_gpio_chip *chip = to_tmc_chip(gc); + unsigned int group = TMC_GPIO_FIND_GROUP(gpio); + unsigned int bit = TMC_GPIO_FIND_GPIO(gpio); + + if (group >= TMC_PFE_GPIO_GROUP_MAX) + return 0; + + switch (group) { + case QSFP_RST: + case QSFP_PRESENT: + case QSFP_PHY_RST: + case QSFP_LPMOD: + dev_dbg(chip->dev, "TMC GPIO get one bitop group=%u, gpio=%u, " + "bit=%u\n", group, gpio, bit); + return !!(ioread32(chip->base + group_offset[group]) + & BIT(bit)); + default: + return tmc_gpio_get_multiple_bitsop(chip, bit, group, group_offset[group]); + } +} + +/* + * tmc_gpio_set - Write the specified signal of the GPIO device. + */ +static void tmc_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct tmc_gpio_chip *chip = to_tmc_chip(gc); + unsigned int group = TMC_GPIO_FIND_GROUP(gpio); + unsigned int bit = TMC_GPIO_FIND_GPIO(gpio); + + if (group >= TMC_PFE_GPIO_GROUP_MAX) + return; + + switch (group) { + case QSFP_RST: + case QSFP_PRESENT: + case QSFP_PHY_RST: + case QSFP_LPMOD: + dev_dbg(chip->dev, "TMC GPIO one bitop group=%d\n", group); + tmc_gpio_one_bitop(chip, bit, group_offset[group], val); + break; + default: + tmc_gpio_multiple_bitsop(chip, bit, group, group_offset[group], val); + break; + } +} + +static struct tmc_gpio_info tmc_gpios[] = { + { + .get = tmc_gpio_get, + .set = tmc_gpio_set, + }, +}; + +static void tmc_gpio_setup(struct tmc_gpio_chip *sgc, int id) +{ + struct gpio_chip *chip = &sgc->gpio; + const struct tmc_gpio_info *info = sgc->info; + + chip->get = info->get; + chip->set = info->set; + chip->direction_input = info->dirin; + chip->direction_output = info->dirout; + chip->dbg_show = NULL; + chip->can_sleep = 0; + + if (id == 0) { + chip->base = 0; + } else if (id == 1) { + chip->base = (gpio_max * id); + } else { + chip->base = -1; + } + + chip->ngpio = sgc->ngpio; + chip->label = dev_name(sgc->dev); + chip->parent = sgc->dev; + chip->owner = THIS_MODULE; +} + +static int tmc_gpio_of_init(struct device *dev, + struct tmc_gpio_chip *chip) +{ + chip->info = &tmc_gpios[0]; + chip->ngpio = gpio_max; + + return 0; +} + +static int tmc_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tmc_gpio_chip *chip; + struct resource *res; + int ret; + + const struct mfd_cell *cell = mfd_get_cell(pdev); + + dev_dbg(dev, "TMC GPIO probe\n"); + + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + dev_info(dev, "TMC GPIO resource 0x%llx, %llu\n", + res->start, resource_size(res)); + + chip->base = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!chip->base) + return -ENOMEM; + + ret = tmc_gpio_of_init(dev, chip); + if (ret) + return ret; + + chip->dev = dev; + spin_lock_init(&chip->gpio_lock); + + tmc_gpio_setup(chip, cell->id); + + ret = gpiochip_add(&chip->gpio); + if (ret) { + dev_err(dev, + "Failed to register TMC gpiochip : %d\n", ret); + return ret; + } + + platform_set_drvdata(pdev, chip); + dev_info(dev, "TMC GPIO registered at 0x%lx, gpiobase: %d\n", + (long unsigned)chip->base, chip->gpio.base); + + return 0; +} + +static int tmc_gpio_remove(struct platform_device *pdev) +{ + struct tmc_gpio_chip *chip = platform_get_drvdata(pdev); + + gpiochip_remove(&chip->gpio); + + return 0; +} + +static struct platform_driver tmc_gpio_driver = { + .driver = { + .name = "gpioslave-tmc", + .owner = THIS_MODULE, + }, + .probe = tmc_gpio_probe, + .remove = tmc_gpio_remove, +}; + +module_platform_driver(tmc_gpio_driver); + +MODULE_DESCRIPTION("Juniper Networks TMC FPGA GPIO driver"); +MODULE_AUTHOR("Ashish Bhensdadia "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c new file mode 100644 index 000000000000..afd0311dc130 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c @@ -0,0 +1,1107 @@ +/* + * Juniper Networks TMC I2C Accelerator driver + * + * Copyright (C) 2020 Juniper Networks + * Author: Ashish Bhensdadia + * + * This driver implement the I2C functionality + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jnx-tmc.h" + + +#define TMC_I2C_MASTER_I2C_SCAN_RESET_BIT BIT(31) + +#define TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET 0x0 +#define TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET 0x10 + +#define TMC_I2C_MSTR_AUTOMATION_I2C(adap, offset) \ + ((adap)->membase + offset) + +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0 0x0 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8 0x8 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4 0x4 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C 0xC +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10 0x10 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14 0x14 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18 0x18 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C 0x1C +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_20 0x20 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_24 0x24 + +#define TMC_I2C_MSTR_I2C_DPMEM(adap, offset) \ + ((adap)->dpmbase + offset) + +#define TMC_I2C_TRANS_LEN 2 +#define tmc_iowrite(val, addr) iowrite32((val), (addr)) + +#define TMC_I2C_CTRL_GROUP(g) (((g) & 0xFF) << 8) +#define TMC_I2C_CTRL_WRCNT(w) (((w) & 0x3F) << 16) +#define TMC_I2C_CTRL_RDCNT(r) (((r) & 0x3F) << 16) +#define TMC_I2C_CTRL_DEVADDR(d) (((d) & 0xFF) << 8) +#define TMC_I2C_CTRL_OFFSET(o) ((o) & 0xFF) + + +#define TMC_I2C_MEM_CTRL_VLD BIT(31) + +#define TMC_I2C_CTRL_ERR(s) ((s) & 0x0F000000) +#define TMC_I2C_CTRL_DONE_BIT(s) ((s) & BIT(31)) +#define TMC_I2C_CTRL_STATUS_OK(s) (TMC_I2C_CTRL_DONE_BIT(s) & \ + TMC_I2C_CTRL_ERR(s)) +#define TMC_I2C_CTRL_DONE(s) (TMC_I2C_CTRL_DONE_BIT(s) == BIT(31)) + +#define TMC_I2C_STAT_INC(adap, s) (((adap)->stat.s)++) +#define TMC_I2C_STAT_INCN(adap, s, n) (((adap)->stat.s) += (n)) +#define TMC_I2C_GET_MASTER(tadap) ((tadap)->tctrl) + +#define TMC_I2C_READ 0x1 +#define TMC_I2C_WRITE 0x2 + +#define TMC_I2C_MASTER_LOCK(s, flags) \ +do { \ + spin_lock_irqsave(&(s)->lock, flags); \ +} while (0) + +#define TMC_I2C_MASTER_UNLOCK(s, flags) \ +do { \ + spin_unlock_irqrestore(&(s)->lock, flags); \ +} while (0) + +#define tmc_i2c_dbg(dev, fmt, args...) \ +do { \ + if (tmc_i2c_debug >= 1) \ + dev_err(dev, fmt, ## args); \ +} while (0) + + +/* pfe TMC i2c channel */ +static int pfe_channel = 32; +module_param(pfe_channel, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(pfe_channel, "Maximum number of channel for PFE TMC"); + +/* chassid TMC i2c channel */ +static int chd_channel = 11; +module_param(chd_channel, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(chd_channel, "Maximum number of channel for CHASSID TMC"); + +static u32 wr_index_to_oper[] = {0x01000000, 0x02000000, + 0x84000000, 0x85000000, 0x83000000}; +static u32 rd_index_to_oper[] = {0x08000000, 0x09000000, 0x0A000000, + 0x8B000000, 0x8C000000, 0x8D000000, 0x83000000}; + +struct tmc_i2c_adapter_stats { + u32 abort; + u32 go; + u32 mstr_rdy; + u32 mstr_busy; + u32 trans_compl; + u32 msg_cnt; + u32 rd_cnt; + u32 wr_cnt; + u32 byte_cnt; + u32 slave_timeo; + u32 scl_bus_loss; + u32 sda_bus_loss; + u32 ack_ptimeo; + u32 rd_cnt_0; + u32 rd_cnt_gt32; + u32 rst_tgt; + u32 rst_mstr; +}; + +struct tmc_i2c_adapter { + void __iomem *membase; + void __iomem *dpmbase; + struct i2c_adapter adap; + struct i2c_mux_core *muxc; + struct tmc_i2c_ctrl *tctrl; + int mux_channels; + int mux_select; + u32 i2c_delay; + int entries; + int master; + u32 control; + u32 speed; + bool done; + bool polling; + bool use_block; + wait_queue_head_t wait; + struct tmc_i2c_adapter_stats stat; +}; + +struct tmc_i2c_ctrl { + void __iomem *membase; + void __iomem *dpmbase; + struct i2c_adapter **adap; + struct device *dev; + int num_masters; + int mux_channels; + u32 i2c_delay; + u32 master_mask; + spinlock_t lock; /* master lock */ +}; + +/* + * Reset the Tmc I2C master + */ +static void tmc_i2c_reset_master(struct i2c_adapter *adap) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct tmc_i2c_ctrl *tmc = TMC_I2C_GET_MASTER(tadap); + u32 val, master = tadap->master; + unsigned long flags; + void __iomem *addr; + + dev_warn(&adap->dev, "Re-setting i2c master: %d\n", master); + + TMC_I2C_MASTER_LOCK(tmc, flags); + + addr = tmc->membase + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET; + val = ioread32(addr); + tmc_iowrite(val | (TMC_I2C_MASTER_I2C_SCAN_RESET_BIT), addr); + tmc_iowrite(val & ~(TMC_I2C_MASTER_I2C_SCAN_RESET_BIT), addr); + TMC_I2C_STAT_INC(tadap, rst_mstr); + + TMC_I2C_MASTER_UNLOCK(tmc, flags); +} + +/* + * check if the Tmc I2C master is ready + */ +static int tmc_i2c_mstr_wait_rdy(struct i2c_adapter *adap, u8 rw, u32 delay) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + unsigned long timeout; + u32 val; + + val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + if (val) { + tmc_iowrite(0x80000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + mdelay(5); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + } else { + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + } + + if ((rw == TMC_I2C_READ) && (delay)) { + tmc_iowrite(0x80000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + return 0; + } + + timeout = jiffies + adap->timeout; + do { + val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + if (!val) + return 0; + + if (tadap->polling) { + usleep_range(50, 100); + } else { + tadap->done = false; + wait_event_timeout(tadap->wait, tadap->done, + adap->timeout); + } + } while (time_before(jiffies, timeout)); + + TMC_I2C_STAT_INC(tadap, mstr_busy); + + return -EBUSY; +} + +/* + * Wait for master completion + */ +static u32 tmc_i2c_mstr_wait_completion(struct i2c_adapter *adap, + u32 dp_entry_offset) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + u32 val; + + if (tadap->polling) { + /* Poll for the results */ + unsigned long timeout = jiffies + adap->timeout; + + do { + usleep_range(1000, 1200); + val = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + dp_entry_offset)); + if (TMC_I2C_CTRL_DONE(val)) + break; + } while (time_before(jiffies, timeout)); + } else { + wait_event_timeout(tadap->wait, tadap->done, adap->timeout); + val = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + dp_entry_offset)); + } + + return TMC_I2C_CTRL_STATUS_OK(val); +} + +/* + * TMC I2C delay read/write operation + */ +static int tmc_i2c_delay_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u32 delay, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int err, n; + u32 control = 0, data = 0; + u32 val; + + err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); + if (err < 0) { + tmc_i2c_reset_master(adap); + return err; + } + + TMC_I2C_STAT_INC(tadap, mstr_rdy); + + /* initialize the start address and mux */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); + + tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); + tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); + + /* populate delay */ + if (delay) { + if (delay > 1000) { + delay = delay/1000; + delay |= (1 << 16); + } + } + tmc_iowrite(delay, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + tmc_iowrite(0x86000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); + + /* prepare control command */ + control |= TMC_I2C_CTRL_DEVADDR(addr); + control |= TMC_I2C_CTRL_OFFSET(offset); + + if (rw == TMC_I2C_WRITE) { + for (n = 0; n < len; n++) + data |= (buf[n] << ((len - 1 - n) * 8)); + tmc_iowrite(data, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + control |= TMC_I2C_CTRL_WRCNT(len); + control |= wr_index_to_oper[len-1]; + dev_dbg(dev, "WR Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + + } else { + /* read */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + control |= TMC_I2C_CTRL_RDCNT(len); + control |= rd_index_to_oper[len-1]; + } + + /* + * valid this transaction as well + */ + control |= TMC_I2C_MEM_CTRL_VLD; + + tadap->control = control; + + /* + * operation control command + */ + tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); + + /* + * End commands + */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); + tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_20)); + tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_24)); + + dev_dbg(dev, "Control (%#x): RD_WR_TYPE:%#02x, RD_WR_LEN:%d," + "Addr:%#01x, Offset:%#02x\n", control, + ((control >> 24) & 0x3F), ((control >> 16) & 0x3F), + ((control >> 8) & 0xff), ((control) & 0xff)); + + tadap->done = false; + + /* fire the transaction */ + tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + TMC_I2C_STAT_INC(tadap, go); + + val = tmc_i2c_mstr_wait_completion(adap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10); + if (val) { + dev_err(&adap->dev, + "i2c transaction error (0x%08x)\n", val); + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + return -EIO; + } + + /* + * read a word of data + */ + if (rw == TMC_I2C_READ) { + data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + for (n = 0; n < len; n++) + buf[n] = (data >> (n * 8)) & 0xff; + + dev_dbg(dev, "RD Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + + TMC_I2C_STAT_INC(tadap, rd_cnt); + } else { + /* write */ + TMC_I2C_STAT_INC(tadap, wr_cnt); + } + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + return 0; + +} + +/* + *TMC I2C none delay Read/write opertion + */ +static int tmc_i2c_none_delay_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int err, n; + u32 control = 0, data = 0; + u32 val; + + err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); + if (err < 0) { + tmc_i2c_reset_master(adap); + return err; + } + + TMC_I2C_STAT_INC(tadap, mstr_rdy); + + /* initialize the start address and mux */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); + + tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); + tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); + + + /* prepare control command */ + control |= TMC_I2C_CTRL_DEVADDR(addr); + control |= TMC_I2C_CTRL_OFFSET(offset); + + if (rw == TMC_I2C_WRITE) { + for (n = 0; n < len; n++) + data |= (buf[n] << (n * 8)); + tmc_iowrite(data, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + control |= wr_index_to_oper[len-1]; + dev_dbg(dev, "WR Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + + } else { + /* read */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + control |= rd_index_to_oper[len-1]; + } + + /* + * valid this transaction as well + */ + control |= TMC_I2C_MEM_CTRL_VLD; + + tadap->control = control; + + /* + * operation control command + */ + tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); + + /* + * End commands + */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); + tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); + + dev_dbg(dev, "Control (%#x): RD_WR_TYPE:%#02x, RD_WR_LEN:%d," + "Addr:%#01x, Offset:%#02x\n", control, + ((control >> 24) & 0x3F), ((control >> 16) & 0x3F), + ((control >> 8) & 0xff), ((control) & 0xff)); + + tadap->done = false; + + /* fire the transaction */ + tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + TMC_I2C_STAT_INC(tadap, go); + + /* wait till transaction complete */ + val = tmc_i2c_mstr_wait_completion(adap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8); + if (val) { + dev_err(&adap->dev, + "i2c transaction error (0x%08x)\n", val); + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + return -EIO; + } + + /* + * read a word of data + */ + if (rw == TMC_I2C_READ) { + data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + for (n = 0; n < len; n++) + buf[n] = (data >> (n * 8)) & 0xff; + + dev_dbg(dev, "RD Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + TMC_I2C_STAT_INC(tadap, rd_cnt); + } else { + /* write */ + TMC_I2C_STAT_INC(tadap, wr_cnt); + } + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + return 0; +} + +/* + * TMC I2C read/write operation + */ +static int tmc_i2c_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + u32 i2c_delay = tadap->i2c_delay; + + if (i2c_delay) { + return tmc_i2c_delay_rw_op(adap, rw, mux, addr, offset, + len, i2c_delay, buf); + } else { + return tmc_i2c_none_delay_rw_op(adap, rw, mux, addr, offset, + len, buf); + } +} + +static int tmc_i2c_calc_entries(int msglen) +{ + int entries = msglen / TMC_I2C_TRANS_LEN; + + return (entries += (msglen % TMC_I2C_TRANS_LEN) ? 1 : 0); +} + +static int tmc_i2c_block_read(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int curmsg, entries, len; + int offset = 0; + struct i2c_msg *msg; + int err, n = 0; + u8 rwbuf[4] = {0}; + + dev_dbg(dev, "Read i2c Block\n"); + + for (curmsg = 0, offset = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + len = msg->len; + + if (msg->flags & I2C_M_RECV_LEN) + len = (I2C_SMBUS_BLOCK_MAX + 1); + + entries = tmc_i2c_calc_entries(len); + + if (msg->flags & I2C_M_RD) { + if (curmsg == 1 && ((msg->flags & I2C_M_RECV_LEN && + !(msgs[0].flags & I2C_M_RD)) || + (msg->len > TMC_I2C_TRANS_LEN))) { + offset = msgs[0].buf[0]; + } + + while (entries) { + err = tmc_i2c_rw_op(adap, TMC_I2C_READ, + tadap->mux_select, + msgs[0].addr, offset, + TMC_I2C_TRANS_LEN, rwbuf); + if (err < 0) + return err; + msg = &msgs[num - 1]; + msg->buf[n] = rwbuf[0]; + msg->buf[n+1] = rwbuf[1]; + n = n + TMC_I2C_TRANS_LEN; + offset = offset + TMC_I2C_TRANS_LEN; + entries--; + } + } + } + + return 0; +} + +/* + *TMC I2C SMB Read opertion + */ +static int tmc_i2c_smb_block_read_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + int err, i = 0; + u32 control = 0, data = 0; + u32 start_add; + + err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); + if (err < 0) { + tmc_i2c_reset_master(adap); + return err; + } + + TMC_I2C_STAT_INC(tadap, mstr_rdy); + + /* initialize the start address and mux */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); + + tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); + tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); + + + /* prepare control command */ + control |= TMC_I2C_CTRL_DEVADDR(addr); + control |= TMC_I2C_CTRL_OFFSET(offset); + + /* read */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + control |= TMC_I2C_CTRL_RDCNT(len);; + control |= rd_index_to_oper[6]; + + tadap->control = control; + + /* + * operation control command + */ + tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); + + /* + * End commands + */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); + tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); + + tadap->done = false; + + /* fire the transaction */ + tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + TMC_I2C_STAT_INC(tadap, go); + + /* + * read a block of data + */ + start_add = TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8; + while (len > 0) { + usleep_range(10000, 12000); + data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, start_add)); + buf[i] = data & 0xff; + buf[i + 1] = (data >> 8) & 0xff; + start_add = start_add + 8; + i = i + 2; + len = len - 2; + + TMC_I2C_STAT_INC(tadap, rd_cnt); + } + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + return 0; +} + +static int tmc_i2c_smb_block_read(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + int curmsg, len; + int offset = 0; + struct i2c_msg *msg; + int err, i = 0; + u8 rwbuf[32] = {0}; + + for (curmsg = 0, offset = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + len = msg->len; + + if (msg->flags & I2C_M_RECV_LEN) + len = (I2C_SMBUS_BLOCK_MAX + 1); + + if (msg->flags & I2C_M_RD) { + if ((curmsg == 1) && (msg->flags & I2C_M_RECV_LEN) && + !(msgs[0].flags & I2C_M_RD)) { + offset = msgs[0].buf[0]; + } + + err = tmc_i2c_smb_block_read_op(adap, TMC_I2C_READ, + tadap->mux_select, + msgs[0].addr, offset, + 32, rwbuf); + if (err < 0) { + return err; + } + msg = &msgs[num - 1]; + for (i = 0; i < len - 1; i++) { + msg->buf[i] = rwbuf[i]; + } + } + } + + return 0; +} + +static int tmc_i2c_mstr_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int n, curmsg, len = 0; + int err = 0; + struct i2c_msg *msg; + bool read; + u8 rwbuf[4] = {0}; + + dev_dbg(dev, "Num messages -> %d\n", num); + + /* + * Initialize all vars + */ + tadap->entries = 0; + tadap->use_block = false; + + for (curmsg = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + dev_dbg(dev, "[%02d] %d bytes, flag %#02x buf %#02x\n", + curmsg, msg->len, msg->flags, msg->buf[0]); + if ((msg->len > TMC_I2C_TRANS_LEN) || + ((msg->flags & I2C_M_RD) && + (msg->flags & I2C_M_RECV_LEN))) { + /* If PEC is enabled len will come as 3 for a word read. + * We don't want to use block read for this case. + */ + if ((msg->flags & I2C_CLIENT_PEC) && + (msg->len == TMC_I2C_TRANS_LEN+1)) { + tadap->use_block = false; + } else { + tadap->use_block = true; + } + break; + } + } + + if (tadap->use_block) { + /* Read Block */ + if ((msg->flags & I2C_M_RD) && (msg->flags & I2C_M_RECV_LEN)) { + err = tmc_i2c_smb_block_read(adap, msgs, num); + } else { + err = tmc_i2c_block_read(adap, msgs, num); + } + if (err < 0) + return err; + } else { + read = msgs[num - 1].flags & I2C_M_RD; + for (curmsg = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + len = msg->len; + + dev_dbg(dev, " [%02d] %s %d bytes addr %#02x, " + "flag %#02x, buf[0] %#02x\n", curmsg, + read ? "RD" : "WR", len, msg->addr, + msg->flags, msg->buf[0]); + + /* SMBus quick read/write command */ + if (len == 0 && curmsg == 0 && num == 1) { + if (read) { + len = 1; + } + break; + } + + if (curmsg == 0) { + if (!read) { + for (n = 1; n < len; n++) + rwbuf[n-1] = (msg->buf[n]); + len--; + } else { + /* read operation */ + continue; + } + } + } + + if (!read) { + /* write */ + err = tmc_i2c_rw_op(adap, TMC_I2C_WRITE, + tadap->mux_select, msgs[0].addr, + msgs[0].buf[0], len, rwbuf); + } else { + /* read */ + /* + * If PEC is enabled read only 2 bytes as expected in + * case of a word read instead of 3 to make it compatible + * with word write implementation. + */ + if (msg->flags & I2C_CLIENT_PEC && (len == TMC_I2C_TRANS_LEN + 1)) { + len--; + } + + err = tmc_i2c_rw_op(adap, TMC_I2C_READ, + tadap->mux_select, + msgs[0].addr, msgs[0].buf[0], + len, rwbuf); + msg = &msgs[num - 1]; + len = msg->len; + /* + * To avoid failure in PEC enabled case clear flag. + */ + if (len == TMC_I2C_TRANS_LEN + 1) { + msgs[num - 1].flags &= ~I2C_M_RD; + } + for (n = 0; n < len; n++) + msg->buf[n] = rwbuf[n]; + } + if (err < 0) + return err; + } + + TMC_I2C_STAT_INCN(tadap, msg_cnt, num); + + return num; +} + +static u32 tmc_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL + | I2C_FUNC_SMBUS_READ_BLOCK_DATA; +} + +static const struct i2c_algorithm tmc_i2c_algo = { + .master_xfer = tmc_i2c_mstr_xfer, + .functionality = tmc_i2c_func, +}; + +static int tmc_i2c_mux_group_sel(struct i2c_mux_core *muxc, u32 chan) +{ + struct tmc_i2c_adapter *tadap = i2c_mux_priv(muxc); + + dev_dbg(muxc->dev, "chan = %d\n", chan); + + if (!tadap || chan > TMC_I2C_MSTR_MAX_GROUPS) + return -ENODEV; + tadap->mux_select = chan; + + return 0; +} + +static int tmc_i2c_mux_init(struct i2c_adapter *adap) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + int chan, ret; + + tadap->muxc = i2c_mux_alloc(adap, &adap->dev, tadap->mux_channels, + 0, 0, tmc_i2c_mux_group_sel, NULL); + + if (!tadap->muxc) + return -ENOMEM; + + tadap->muxc->priv = tadap; + for (chan = 0; chan < tadap->mux_channels; chan++) { + ret = i2c_mux_add_adapter(tadap->muxc, 0, chan, 0); + if (ret) { + dev_err(&adap->dev, "Failed to add adapter %d\n", chan); + i2c_mux_del_adapters(tadap->muxc); + return ret; + } + } + + return 0; +} + +static struct i2c_adapter * +tmc_i2c_init_one(struct tmc_i2c_ctrl *tmc, + int master, int id) +{ + struct tmc_i2c_adapter *adapter; + struct device *dev = tmc->dev; + int err; + + adapter = devm_kzalloc(dev, sizeof(*adapter), GFP_KERNEL); + if (!adapter) + return ERR_PTR(-ENOMEM); + + init_waitqueue_head(&adapter->wait); + adapter->adap.owner = THIS_MODULE; + adapter->adap.algo = &tmc_i2c_algo; + adapter->adap.nr = -1; + adapter->adap.timeout = HZ / 5; + adapter->master = master; + adapter->mux_channels = tmc->mux_channels; + adapter->i2c_delay = tmc->i2c_delay; + adapter->membase = tmc->membase; + adapter->dpmbase = tmc->dpmbase; + adapter->polling = 1; + adapter->tctrl = tmc; + + i2c_set_adapdata(&adapter->adap, adapter); + snprintf(adapter->adap.name, sizeof(adapter->adap.name), + "%s:%d", dev_name(dev), master); + + adapter->adap.dev.parent = dev; + err = i2c_add_numbered_adapter(&adapter->adap); + if (err) + goto error; + + err = tmc_i2c_mux_init(&adapter->adap); + if (err) + goto err_remove; + + dev_dbg(dev, "Adapter[%02d-%02d]: " + "dpmbase: 0x%lx\n", id, master, + (unsigned long)adapter->dpmbase); + return &adapter->adap; + +err_remove: + i2c_del_adapter(&adapter->adap); +error: + return ERR_PTR(err); +} + +static void tmc_i2c_cleanup_one(struct i2c_adapter *adap) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + + i2c_mux_del_adapters(tadap->muxc); + i2c_del_adapter(adap); + +} + + +static int tmc_i2c_of_init(struct device *dev, + struct tmc_i2c_ctrl *tmc, int id) +{ + u32 mux_channels, master, num_masters = 0, master_mask = 0; + u32 i2c_delay = 0; + + if (!(master_mask & BIT(master))) + num_masters++; + master_mask |= BIT(master); + + if (id == 0) { + /* chassisd */ + mux_channels = chd_channel; + num_masters = 1; + i2c_delay = 0; + } else if (id == 1) { + /* pfe */ + mux_channels = pfe_channel; + num_masters = 1; + i2c_delay = 20; + } else { + return -EINVAL; + } + + tmc->adap = devm_kcalloc(dev, num_masters, + sizeof(struct i2c_adapter *), + GFP_KERNEL); + if (!tmc->adap) + return -ENOMEM; + + tmc->num_masters = num_masters; + tmc->master_mask = master_mask; + tmc->mux_channels = mux_channels; + tmc->i2c_delay = i2c_delay; + + return 0; +} + +static int tmc_i2c_probe(struct platform_device *pdev) +{ + int i, n, err; + struct resource *res; + struct i2c_adapter *adap; + struct device *dev = &pdev->dev; + struct tmc_i2c_ctrl *tmc; + + const struct mfd_cell *cell = mfd_get_cell(pdev); + + /* + * Allocate memory for the Tmc FPGA + */ + tmc = devm_kzalloc(dev, sizeof(*tmc), GFP_KERNEL); + if (!tmc) + return -ENOMEM; + + platform_set_drvdata(pdev, tmc); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + dev_info(dev, "Tmc I2C Accel resource 0x%llx, %llu\n", + res->start, resource_size(res)); + + tmc->membase = devm_ioremap_nocache(dev, res->start, + resource_size(res)); + if (!tmc->membase) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) + return -ENODEV; + + dev_info(dev, "Tmc I2C Mem resource 0x%llx, %llu\n", + res->start, resource_size(res)); + + tmc->dpmbase = devm_ioremap_nocache(dev, res->start, + resource_size(res)); + if (!tmc->dpmbase) + return -ENOMEM; + + tmc->dev = dev; + spin_lock_init(&tmc->lock); + + err = tmc_i2c_of_init(dev, tmc, cell->id); + if (err) + return err; + + dev_info(dev, "Tmc I2C Masters: %d\n", tmc->num_masters); + dev_info(dev, "Tmc I2C Delay: %d\n", tmc->i2c_delay); + + for (n = 0, i = 0; i < TMC_I2C_MASTER_NR_MSTRS; i++) { + if (tmc->master_mask & BIT(i)) { + adap = tmc_i2c_init_one(tmc, i, n); + if (IS_ERR(adap)) { + err = PTR_ERR(adap); + dev_err(dev, "Failed to initialize master " + "adapter %d: %d\n", i, err); + goto err_remove; + } + tmc->adap[n++] = adap; + } + } + + return 0; + +err_remove: + for (n--; n >= 0; n--) + tmc_i2c_cleanup_one(tmc->adap[n]); + return err; +} + +static int tmc_i2c_remove(struct platform_device *pdev) +{ + struct tmc_i2c_ctrl *tmc = platform_get_drvdata(pdev); + int i; + + /* Disable all masters */ + tmc_iowrite(0, tmc->membase + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET); + + for (i = 0; i < tmc->num_masters; i++) + tmc_i2c_cleanup_one(tmc->adap[i]); + + return 0; +} + +static struct platform_driver tmc_i2c_driver = { + .driver = { + .name = "i2c-tmc", + .owner = THIS_MODULE, + }, + .probe = tmc_i2c_probe, + .remove = tmc_i2c_remove, +}; + +module_platform_driver(tmc_i2c_driver); + +MODULE_DESCRIPTION("Juniper Networks TMC FPGA I2C Accelerator driver"); +MODULE_AUTHOR("Ashish Bhensdadia "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-psu-monitor.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-psu-monitor.c new file mode 100644 index 000000000000..e1604d3d0d51 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-psu-monitor.c @@ -0,0 +1,325 @@ +/* + * A hwmon PSU monitoring driver for Juniper QFX5200 platform + * + * Copyright (C) 2020 Juniper Networks. + * Ciju Rajan K + * + * Based on ym2651.c by Brandon Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEMP_INT_MASK (0xFFC0) +#define V_IN_INT_MASK (0xFFE0) +#define V_OUT_INT_MASK (0xFF00) +#define INVALID_READING (0xFFFF) +#define TEMP_FR_LEN 6 +#define V_IN_FR_LEN 5 +#define V_OUT_FR_LEN 8 + +static const unsigned short normal_i2c[] = { 0x58, 0x58, I2C_CLIENT_END }; + +struct psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u16 v_out; + u16 i_out; + u16 v_in; + u16 i_in; + u16 temp1_input; + u16 temp2_input; + u16 temp3_input; + u16 temp4_input; + u16 fan1_input; + u16 fan2_input; +}; + +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf); + +static struct psu_data *psu_update_device(struct device *dev); + +enum psu_sysfs_attributes { + PSU_V_OUT, + PSU_I_OUT, + PSU_V_IN, + PSU_I_IN, + PSU_TEMP1_INPUT, + PSU_TEMP2_INPUT, + PSU_TEMP3_INPUT, + PSU_TEMP4_INPUT, + PSU_FAN1_RPM, + PSU_FAN2_RPM, +}; + +/* + * sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_word, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_word, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, show_word, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, show_word, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_word, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_word, NULL, PSU_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_word, NULL, PSU_TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_word, NULL, PSU_TEMP4_INPUT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_word, NULL, PSU_FAN1_RPM); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_word, NULL, PSU_FAN2_RPM); + +static struct attribute *psu_attributes[] = { + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + NULL +}; + +static short convert_to_decimal(u16 value, + u16 data_mask, + u8 fr_len) +{ + return (((short)value >= 0) ? ((value & data_mask) >> fr_len) : + (-((((~(value & data_mask)) >> fr_len) + 1)))); +} + +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct psu_data *data = psu_update_device(dev); + u32 value = 0x0000; + + switch (attr->index) { + case PSU_V_OUT: + value = 1000 * convert_to_decimal(data->v_out, + V_OUT_INT_MASK, + V_OUT_FR_LEN); + break; + case PSU_V_IN: + value = convert_to_decimal(data->v_in, + V_IN_INT_MASK, + V_IN_FR_LEN); + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = 1000 * data->i_out / 64; + break; + case PSU_FAN1_RPM: + value = data->fan1_input; + break; + case PSU_FAN2_RPM: + value = data->fan2_input; + break; + case PSU_TEMP1_INPUT: + value = 1000 * convert_to_decimal(data->temp1_input, + TEMP_INT_MASK, + TEMP_FR_LEN); + break; + case PSU_TEMP2_INPUT: + value = 1000 * convert_to_decimal(data->temp2_input, + TEMP_INT_MASK, + TEMP_FR_LEN); + break; + case PSU_TEMP3_INPUT: + value = 1000 * convert_to_decimal(data->temp3_input, + TEMP_INT_MASK, + TEMP_FR_LEN); + break; + case PSU_TEMP4_INPUT: + value = 1000 * convert_to_decimal(data->temp4_input, + TEMP_INT_MASK, + TEMP_FR_LEN); + break; + } + + return sprintf(buf, "%d\n", (int)value); +} + +static const struct attribute_group jnx_psu_group = { + .attrs = psu_attributes, +}; + +static int jnx_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + dev_dbg(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &jnx_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &jnx_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int jnx_psu_remove(struct i2c_client *client) +{ + struct psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &jnx_psu_group); + kfree(data); + + return 0; +} + +enum { + JPSU, +}; + +static const struct i2c_device_id psu_id[] = { + { "jpsu", JPSU }, + {} +}; +MODULE_DEVICE_TABLE(i2c, psu_id); + + +static struct i2c_driver jnx_psu_monitor_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "jnx-psu-monitor", + }, + .probe = jnx_psu_probe, + .remove = jnx_psu_remove, + .id_table = psu_id, + .address_list = normal_i2c, +}; + + +static int psu_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct psu_data *psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; + struct reg_data_word regs_word[] = { + {0x00, &data->temp1_input}, + {0x01, &data->temp2_input}, + {0x02, &data->temp3_input}, + {0x03, &data->temp4_input}, + {0x28, &data->v_out}, + {0x32, &data->v_in}, + {0x33, &data->i_out}, + {0x3D, &data->i_in}, + {0x20, &data->fan1_input}, + {0x21, &data->fan2_input} + }; + + dev_dbg(dev, "Starting psu monitoring update\n"); + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = psu_read_word(client, regs_word[i].reg); + + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + } + else { + u16 value = (u16)status; + (INVALID_READING != value) ? (*(regs_word[i].value) = status) : + (*(regs_word[i].value) = 0); + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(jnx_psu_monitor_driver); + +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_DESCRIPTION("Juniper PSU monitoring driver for QFX5200"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c new file mode 100644 index 000000000000..15972b376298 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c @@ -0,0 +1,116 @@ +/* + * Juniper Networks Re-Fpga lpc module + * + * Copyright (C) 2020 Juniper Networks + * Author: Ciju Rajan K + * + * This module implements: + * - Registering Reboot handler to reset cpu + * - Reset management port + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define REFPGA_LPC_BASE_ADDRESS 0xFED50000 +#define REFPGA_LPC_WINDOW_SIZE 0x00000400 + +#define REFPGA_MRE_LPCM_RST_CTL_REG (0x3) +#define REFPGA_MAJOR_VERSION (0x0) +#define REFPGA_MINOR_VERSION (0x1) + +#define REFPGA_CPU_RESET BIT(0) +#define REFPGA_MGMT1_PHY_RESET BIT(1) + +static void __iomem *fpga = NULL; + +static int qfx5200_cpu_reset(struct notifier_block *nb, + unsigned long action, + void *data) +{ + int ret = 0; + + switch (action) { + case SYS_POWER_OFF: + case SYS_HALT: + printk(KERN_CRIT "System halt/power_off\n"); + break; + case SYS_RESTART: + printk(KERN_CRIT "System restart: qfx5200_cpu_reset\n"); + iowrite8(REFPGA_CPU_RESET, (u8 *)fpga + REFPGA_MRE_LPCM_RST_CTL_REG); + msleep(100); + break; + default: + /* Do Nothing */ + break; + } + return NOTIFY_DONE; +} + +static struct notifier_block qfx5200_nb = { + .notifier_call = qfx5200_cpu_reset, +}; + +static int __init refpga_lpcm_init(void) +{ + u8 major_version = 0x00; + u8 minor_version = 0x00; + + if (!request_mem_region(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE, "refpga-lpc")) { + printk(KERN_ERR "Cannot allocate Re-fpga memory region\n"); + return -ENODEV; + } + + if ((fpga = ioremap(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE)) == NULL) { + release_mem_region(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE); + printk(KERN_ERR "Re-Fpga address mapping failed\n"); + return -1; + } + + major_version = ioread8((u8 *)fpga + REFPGA_MAJOR_VERSION); + minor_version = ioread8((u8 *)fpga + REFPGA_MINOR_VERSION); + printk(KERN_INFO "Re-Fpga major version: %x minor version: %x\n", major_version, minor_version); + + /* + * Register the cpld soft reset handler + */ + if(register_reboot_notifier(&qfx5200_nb)) { + printk(KERN_ALERT "Restart handler registration failed\n"); + } + + iowrite8(REFPGA_MGMT1_PHY_RESET, (u8 *)fpga + REFPGA_MRE_LPCM_RST_CTL_REG); + + return 0; + +} + +static void __exit refpga_lpcm_exit(void) +{ + iounmap(fpga); + release_mem_region(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE); + /* + * Unregister the cpld soft reset handler + */ + if (!unregister_restart_handler(&qfx5200_nb)) { + printk(KERN_CRIT "Failed to uregister restart handler\n"); + } + printk(KERN_INFO "Re-Fpga lpcm module removed\n"); +} + +module_init(refpga_lpcm_init); +module_exit(refpga_lpcm_exit); + +MODULE_DESCRIPTION("Juniper Networks RE-FPGA lpc module"); +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c new file mode 100644 index 000000000000..ef36bca72e9d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c @@ -0,0 +1,603 @@ +/* + * Juniper Networks RE-FPGA qfx platform specific driver + * + * Copyright (C) 2020 Juniper Networks + * Author: Ciju Rajan K + * + * This driver implements various features such as + * - ALARM led driver + * - Fan full speed reset control + * - FAN precense detection + * - FAN type detection + * - Any new QFX specific features which uses RE-FPGA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_LEDS 7 /* Max number of Alarm + FAN LEDs */ + +#define ALARM_MINOR_LED 0 +#define ALARM_MAJOR_LED 1 + +#define REFPGA_PCIE_RESET_CTRL 0x13 +#define REFPGA_PCIE_ALARM 0x33 +#define REFPGA_FAN0_CTRL_STAT 0x28 + +#define REFPGA_RESET_FAN_SPEED BIT(3) +#define REFPGA_OPER_TYPE BIT(0) +#define REFPGA_OPER_START BIT(1) +#define REFPGA_OPER_DONE BIT(2) + +#define TMC_REFPGA_ADDR_REG 0x0 /* TMC offset: 0x228 */ +#define TMC_REFPGA_DATA_REG 0x4 /* TMC offset: 0x22C */ +#define TMC_REFPGA_CTRL_REG 0x8 /* TMC offset: 0x230 */ + +#define TMC_REFPGA_READ_CMD 0x3 +#define TMC_REFPGA_WRITE_CMD 0x2 + +#define REFPGA_INTR_NR_GROUPS 1 +#define REFPGA_INTR_MAX_IRQS_PG 32 + +#define MAX_FANS 5 + +#define REFPGA_IRQ_MAX_BITS_PER_REG 32 + +#define POLL_INTERVAL 5000 + +#define AFI_MASK (0x01) +#define AFO_MASK (0x02) +#define AFI_AFO_MASK (0x03) +/* + * LED specific data structures + */ +struct refpga_led { + struct led_classdev lc; + struct work_struct work; + int blink; + int on; + int bit; + void __iomem *addr; +}; + +struct refpga_led_data { + int num_leds; + struct refpga_led *leds; +}; + +static DEFINE_MUTEX(alarm_led_lock); + +/* + * Common routines + */ +struct refpga_chip { + struct refpga_led_data *led; +}; + +static struct refpga_chip *refpga; + +static DEFINE_MUTEX(refpga_lock); + +static void __iomem *tmc_membase; + +static void wait_for_refpga_oper(void __iomem *base_addr) +{ + volatile u32 done = ~(-1); + unsigned long int timeout; + void __iomem *addr; + + addr = base_addr + (TMC_REFPGA_CTRL_REG); + /* + * Wait till the transaction is complete + */ + timeout = jiffies + msecs_to_jiffies(100); + + do { + usleep_range(50, 100); + done = ioread32(addr); + if (done & (REFPGA_OPER_DONE)) + break; + } while(time_before(jiffies, timeout)); +} +static u32 refpga_read(void __iomem *base_addr, u32 refpga_offset) +{ + u32 value; + + mutex_lock(&refpga_lock); + iowrite32(refpga_offset, base_addr + (TMC_REFPGA_ADDR_REG)); + iowrite32(TMC_REFPGA_READ_CMD, base_addr + (TMC_REFPGA_CTRL_REG)); + wait_for_refpga_oper(base_addr); + value = ioread32(base_addr + (TMC_REFPGA_DATA_REG)); + mutex_unlock(&refpga_lock); + + return value; +} + +static void refpga_write(void __iomem *base_addr, u32 refpga_offset, u32 val) +{ + mutex_lock(&refpga_lock); + iowrite32(refpga_offset, base_addr + (TMC_REFPGA_ADDR_REG)); + iowrite32(val, base_addr + (TMC_REFPGA_DATA_REG)); + iowrite32(TMC_REFPGA_WRITE_CMD, base_addr + (TMC_REFPGA_CTRL_REG)); + wait_for_refpga_oper(base_addr); + mutex_unlock(&refpga_lock); +} + +static bool get_fan_presense(u8 idx) +{ + u8 value = 0x00; + u8 offset = REFPGA_FAN0_CTRL_STAT; + bool ret = 0; + + value = refpga_read(tmc_membase, (offset + (idx * 2))); + /* + * Get the last two bits of REFPGA_FANx_CTRL_STAT. + * REFPGA_FANx_CTRL_STAT register of REFPGA gives the fan airflow + * status. There are 5 fans in QFX5200. Last two bits give the AFI + * & AFO status. If any of these bits are set, fan is present. + */ + value = (value & BIT(0)) | (value & BIT(1)); + if (value) + ret = 1; + + return ret; +} + +static int get_fan_type(u8 idx) +{ + u8 value = 0x00; + u8 offset = REFPGA_FAN0_CTRL_STAT; + int ret = -1; + + value = refpga_read(tmc_membase, (offset + (idx * 2))); + /* + * Get the last two bits of REFPGA_FANx_CTRL_STAT. + * REFPGA_FANx_CTRL_STAT register of REFPGA gives the fan airflow + * status. There are 5 fans in QFX5200. Last two bits give the AFI + * & AFO status. If bit1 is set, it's AFO and if bit 0 is set, + * it's AFI. + * + * This function will return '1' for AFO, '0' for AFI, and '-1' + * if there is no fan or if both AFI & AFO bits are set. + */ + value &= AFI_AFO_MASK; + + switch(value) { + case AFI_MASK: + ret = 0; + break; + case AFO_MASK: + ret = 1; + break; + default: + ret = -1; + break; + }; + + return ret; +} + +enum sysfs_fan_attributes { + FAN0_PRESENT, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, +}; + +enum sysfs_fan_type_attributes { + FAN0_TYPE, + FAN1_TYPE, + FAN2_TYPE, + FAN3_TYPE, + FAN4_TYPE, +}; + +/* + * The sysfs files will be present in this path + * /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan*_present + * /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan*_type + */ + +#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, refpga_fan_presense_show, NULL, FAN##index##_PRESENT) +#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr + +#define DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_type, S_IRUGO, refpga_fan_type_show, NULL, FAN##index##_TYPE) +#define DECLARE_FAN_TYPE_ATTR(index) &sensor_dev_attr_fan##index##_type.dev_attr.attr + +static ssize_t refpga_fan_presense_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); + + return sprintf(buf, "%d\n", get_fan_presense(s_attr->index)); + +} + +static ssize_t refpga_fan_type_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); + + return sprintf(buf, "%d\n", get_fan_type(s_attr->index)); + +} + +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(0); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); + +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(0); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(1); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(2); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(3); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(4); + +static struct attribute *refpga_fan_attrs[] = { + DECLARE_FAN_PRESENT_ATTR(0), + DECLARE_FAN_PRESENT_ATTR(1), + DECLARE_FAN_PRESENT_ATTR(2), + DECLARE_FAN_PRESENT_ATTR(3), + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_TYPE_ATTR(0), + DECLARE_FAN_TYPE_ATTR(1), + DECLARE_FAN_TYPE_ATTR(2), + DECLARE_FAN_TYPE_ATTR(3), + DECLARE_FAN_TYPE_ATTR(4), + NULL +}; + +static struct attribute_group refpga_fan_attr_group = { + .attrs = refpga_fan_attrs, +}; + +/* + * There is only a single ALARM led in QFX5200 and that + * is used for both Major & Minor alarm indicator. + * These are represented by two different bits in RE-FPGA + * PCIE_ALARM register. Only one of the bit (either Red or + * Yellow) should be set a time. If both the bits are set, + * it's an undefined behaviour. + * + * The following table describes how the conditions are + * handled in the driver as there can be both Major & Minor + * alarms can be triggered from userspace. + * + * Major Minor Colour + * + * 0 0 Nil + * 0 1 Yellow + * 1 1 Red + * 1 0 Red + * + */ +static void manage_alarm_led(void __iomem *addr, int led_type, int value) +{ + static int alarm_major = 0, alarm_minor = 0; + u32 reg = 0x0; + + mutex_lock(&alarm_led_lock); + reg = refpga_read(addr, REFPGA_PCIE_ALARM); + + (led_type == ALARM_MAJOR_LED) ? + ((value == 1) ? (alarm_major = 1) : (alarm_major = 0)) : + ((value == 1) ? (alarm_minor = 1) : (alarm_minor = 0)); + if (alarm_major) { + reg &= ~BIT(ALARM_MINOR_LED); + reg |= BIT(ALARM_MAJOR_LED); + } else { + if (alarm_minor) { + reg &= ~BIT(ALARM_MAJOR_LED); + reg |= BIT(ALARM_MINOR_LED); + } else { + reg &= ~BIT(ALARM_MINOR_LED); + reg &= ~BIT(ALARM_MAJOR_LED); + } + } + refpga_write(addr, REFPGA_PCIE_ALARM, reg); + mutex_unlock(&alarm_led_lock); +} + +static void manage_fan_led(void __iomem *addr, int fan_slot, int value) +{ + u8 offset = REFPGA_FAN0_CTRL_STAT + (fan_slot * 2); + u32 reg = 0x0; + + reg = refpga_read(addr, offset); + if(value) { + /* Turn on s/w control */ + reg = reg | BIT(4); + /* Turn off green led */ + reg &= ~BIT(5); + /* Turn on yellow led & make it blink */ + reg |= (BIT(6) | BIT(7)); + } else { + /* Clear yellow led & stop blink */ + reg &= ~(BIT(6) | BIT(7)); + /* Stop s/w control */ + reg &= ~BIT(4); + } + refpga_write(addr, offset, reg); +} + +static void refpga_led_work(struct work_struct *work) +{ + struct refpga_led *led = container_of(work, struct refpga_led, work); + void __iomem *addr; + + addr = led->addr; + + if(strstr(led->lc.name, "fan")) + manage_fan_led(addr, led->bit, led->on); + else + manage_alarm_led(addr, led->bit, led->on); +} + +static void refpga_led_brightness_set(struct led_classdev *lc, + enum led_brightness brightness) +{ + struct refpga_led *led = container_of(lc, struct refpga_led, lc); + + led->on = (brightness != LED_OFF); + led->blink = 0; /* always turn off hw blink on brightness_set() */ + schedule_work(&led->work); +} + +struct led_table +{ + const char *name; + int reg; +}; + +static struct led_table qfx5200_led_data[] = { + { + .name = "alarm-minor", + .reg = 0, + }, + { + .name = "alarm-major", + .reg = 1, + }, + { + .name = "fan0-fault", + .reg = 0, + }, + { + .name = "fan1-fault", + .reg = 1, + }, + { + .name = "fan2-fault", + .reg = 2, + }, + { + .name = "fan3-fault", + .reg = 3, + }, + { + .name = "fan4-fault", + .reg = 4, + } +}; + +static int refpga_led_init_one(struct device *dev, + struct refpga_led_data *ild, + int num) +{ + struct refpga_led *led; + int ret = 0; + + led = &ild->leds[num]; + led->addr = tmc_membase; + + led->lc.name = qfx5200_led_data[num].name; + led->bit = qfx5200_led_data[num].reg; + led->lc.brightness = LED_OFF; + led->lc.brightness_set = refpga_led_brightness_set; + + ret = devm_led_classdev_register(dev, &led->lc); + if (ret) { + dev_err(dev, "devm_led_classdev_register failed\n"); + return ret; + } + + INIT_WORK(&led->work, refpga_led_work); + + return 0; +} + +static int refpga_led_qfx5200_init(struct device *dev, struct refpga_led_data *ild) +{ + int ret = 0, idx = 0; + + + if (!dev->parent) { + dev_err(dev, "dev->parent is null\n"); + return -ENODEV; + } + + ild->num_leds = NUM_LEDS; + ild->leds = devm_kzalloc(dev, sizeof(struct refpga_led) * NUM_LEDS, + GFP_KERNEL); + if (!ild->leds) { + dev_err(dev, "LED allocation failed\n"); + return -ENOMEM; + } + + for(idx=0; idxdev; + struct refpga_led_data *ild; + int ret; + + ild = devm_kzalloc(dev, sizeof(*ild), GFP_KERNEL); + if (!ild) { + dev_err(dev, "ild allocation failed\n"); + return -ENOMEM; + } + + ret = refpga_led_qfx5200_init(dev, ild); + if (ret < 0) + return ret; + + refpga->led = ild; + + return 0; +} + +static int jnx_refpga_led_remove(struct platform_device *pdev) +{ + struct refpga_chip *drv_data = platform_get_drvdata(pdev); + struct refpga_led_data *ild = drv_data->led; + int i; + + for (i = 0; i < ild->num_leds; i++) { + devm_led_classdev_unregister(&pdev->dev, &ild->leds[i].lc); + cancel_work_sync(&ild->leds[i].work); + } + if (ild) { + if (ild->leds) + devm_kfree(&pdev->dev, ild->leds); + devm_kfree(&pdev->dev, ild); + } + return 0; +} + +static void reset_fan_full_speed(struct device *dev) +{ + u32 val = ~(-1), tmp = ~(-1); + + /* + * Reading the REFPGA_PCIE_RESET_CTRL register + */ + val = refpga_read(tmc_membase, REFPGA_PCIE_RESET_CTRL); + /* + * Clearing the fan full_speed bit + */ + val &= ~(REFPGA_RESET_FAN_SPEED); + /* + * Writing the REFPGA_PCIE_RESET_CTRL register + */ + refpga_write(tmc_membase, REFPGA_PCIE_RESET_CTRL, val); + /* + * Reading the REFPGA_PCIE_RESET_CTRL register + */ + tmp = refpga_read(tmc_membase, REFPGA_PCIE_RESET_CTRL); + dev_info(dev, "After resetting fan full speed control: %X\n", tmp); +} + +static int jnx_refpga_tmc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *res; + int ret = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "resource allocation failed\n"); + return -ENODEV; + } + + tmc_membase = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!tmc_membase) { + dev_err(dev, "ioremap failed\n"); + return -ENOMEM; + } + + refpga = devm_kzalloc(dev, sizeof(*refpga), GFP_KERNEL); + if (!refpga) { + dev_err(dev, "refpga memory allocation failed\n"); + return -ENOMEM; + } + + reset_fan_full_speed(dev); + + ret = jnx_refpga_led_probe(pdev); + if (ret != 0) { + dev_err(dev, "Refpga LED probe failed\n"); + return ret; + } + + dev_info(dev, "Refpga LED probe successful: TMC memoy base: %p\n", + tmc_membase); + + ret = sysfs_create_group(&dev->kobj, &refpga_fan_attr_group); + if (ret != 0) { + dev_err(dev, "sysfs_create_group failed: %d\n", ret); + return ret; + } + + platform_set_drvdata(pdev, refpga); + + return 0; +} + +static int jnx_refpga_tmc_remove(struct platform_device *pdev) +{ + jnx_refpga_led_remove(pdev); + sysfs_remove_group(&pdev->dev.kobj, &refpga_fan_attr_group); + + return 0; +} + +static struct platform_driver jnx_refpga_tmc_driver = { + .driver = { + .name = "refpga-tmc", + .owner = THIS_MODULE, + }, + .probe = jnx_refpga_tmc_probe, + .remove = jnx_refpga_tmc_remove, +}; + +static int __init jnx_refpga_tmc_driver_init(void) +{ + int ret = -1; + + ret = platform_driver_register(&jnx_refpga_tmc_driver); + + return ret; + +} + +static void __exit jnx_refpga_tmc_driver_exit(void) +{ + platform_driver_unregister(&jnx_refpga_tmc_driver); +} + +module_init(jnx_refpga_tmc_driver_init); +module_exit(jnx_refpga_tmc_driver_exit); + +MODULE_DESCRIPTION("Juniper Networks REFPGA / TMC driver"); +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c new file mode 100644 index 000000000000..833164bfed63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c @@ -0,0 +1,477 @@ +/* + * Juniper Networks TMC-FPGA MFD Core driver for qfx platform + * + * Copyright (c) 2020, Juniper Networks + * Author: Ashish Bhensdadia + * + * This driver implement the resource publish for below devices + * - I2C + * - GPIO + * - RE FPGA + * - PSU + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jnx-tmc.h" + +#define TMC_DO_SCRATCH_TEST 1 + +/* + * TMC FPGA Device IDs + */ +#define PCI_VENDOR_ID_JUNIPER 0x1304 + +#define PCI_DEVICE_ID_JNX_TMC_CHD 0x007B +#define PCI_DEVICE_ID_JNX_TMC_PFE 0x007C + +/* + * TMC resources + */ +static struct resource tmc_resource_i2c[] = { + /* I2C AUTOMATION Block */ + { + .name = "i2c-tmc", + .start = TMC_I2C_AUTOMATION_I2C_CONTROL_START, + .end = TMC_I2C_AUTOMATION_I2C_CONTROL_END, + .flags = IORESOURCE_MEM, + }, + + /* I2C DPMEM */ + { + .name = "i2c-tmc-mem", + .start = TMC_I2C_DPMEM_ENTRY_START, + .end = TMC_I2C_DPMEM_ENTRY_END, + .flags = IORESOURCE_MEM, + }, +}; + +#define TMC_RES_I2C_NR ARRAY_SIZE(tmc_resource_i2c) + +/* + * LED resources + */ +static struct resource tmc_resource_leds[] = { + { + .name = "leds-tmc", + .start = TMC_LED_CONTROL_START, + .end = TMC_LED_CONTROL_END, + .flags = IORESOURCE_MEM, + }, +}; + +#define TMC_RES_LEDS_NR ARRAY_SIZE(tmc_resource_leds) + +/* + * TMC RE-FPGA devices + */ +static struct resource tmc_resource_refpga[] = { + { + .name = "refpga-tmc", + .start = TMC_REFPGA_ACCESS_START, + .end = TMC_REFPGA_ACCESS_END, + .flags = IORESOURCE_MEM, + }, +}; + +#define TMC_RES_REFPGA_NR ARRAY_SIZE(tmc_resource_refpga) + +static struct resource tmc_resource_gpioslave0[] = { + /* SLAVE0 Block */ + { + .name = "gpioslave-tmc", + .start = TMC_GPIO_SLAVE0_START, + .end = TMC_GPIO_SLAVE0_END, + .flags = IORESOURCE_MEM, + } +}; + +#define TMC_RES_GPIOSLAVE0_NR ARRAY_SIZE(tmc_resource_gpioslave0) + +static struct resource tmc_resource_gpioslave1[] = { + /* SLAVE1 Block */ + { + .name = "gpioslave-tmc", + .start = TMC_GPIO_SLAVE1_START, + .end = TMC_GPIO_SLAVE1_END, + .flags = IORESOURCE_MEM, + } +}; + +#define TMC_RES_GPIOSLAVE1_NR ARRAY_SIZE(tmc_resource_gpioslave1) + +static struct resource tmc_resource_psu[] = { + /* PSU Block */ + { + .name = "psu-tmc", + .start = TMC_PSU_START, + .end = TMC_PSU_END, + .flags = IORESOURCE_MEM, + } +}; + +#define TMC_RES_PSU_NR ARRAY_SIZE(tmc_resource_psu) + +/* + * CHASSISD TMC MFD devices + */ +static struct mfd_cell chassisd_tmc_mfd_devs[] = { + { + .name = "i2c-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_i2c), + .resources = &tmc_resource_i2c[0], + .of_compatible = "jnx,i2c-tmc", + .id = 0, + }, + { + .name = "leds-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_leds), + .resources = &tmc_resource_leds[0], + .of_compatible = "jnx,leds-tmc", + .id = 0, + }, + { + .name = "refpga-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_refpga), + .resources = &tmc_resource_refpga[0], + .of_compatible = "jnx,refpga-tmc", + .id = 0, + }, + { + .name = "psu-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_psu), + .resources = &tmc_resource_psu[0], + .of_compatible = "jnx,psu-tmc", + .id = 0, + }, +}; + +/* + * PFE TMC MFD devices + */ +static struct mfd_cell pfe_tmc_mfd_devs[] = { + { + .name = "i2c-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_i2c), + .resources = &tmc_resource_i2c[0], + .of_compatible = "jnx,i2c-tmc", + .id = 1, + }, + { + .name = "gpioslave-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_gpioslave0), + .resources = &tmc_resource_gpioslave0[0], + .of_compatible = "jnx,gpioslave-tmc", + .id = 0, + }, + { + .name = "gpioslave-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_gpioslave1), + .resources = &tmc_resource_gpioslave1[0], + .of_compatible = "jnx,gpioslave-tmc", + .id = 1, + }, +}; + + +struct tmc_fpga_data { + void __iomem *membase; + struct pci_dev *pdev; + + u32 major; /* Device id & Major version*/ + u32 minor; /* Minor version */ + + u32 optic_cpld_major; /* optic cpld major version */ + u32 optic_cpld_minor; /* optic cpld minor version */ + u32 optic_cpld_devid; /* optic cpld device id */ +}; + +/* sysfs entries */ +static ssize_t major_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "0x%02X_%06X\n", + (tmc->major >> 24) & 0xff, + tmc->major & 0xffffff); +} + +static ssize_t minor_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%02X\n", (tmc->minor) & 0xff); +} + +static ssize_t optic_cpld_major_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%01X\n", tmc->optic_cpld_major & 0xf); +} + +static ssize_t optic_cpld_devid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%01X\n", + (tmc->optic_cpld_major >> 4) & 0xf); +} + +static ssize_t optic_cpld_minor_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%02X\n", tmc->optic_cpld_minor & 0xff); +} + +static ssize_t set_sys_shutdown(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t len) +{ + + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 0, &val); + if (ret < 0) + return ret; + + if (val != 1) + return -EINVAL; + + /* Unlock the shutdown register */ + iowrite32(0x12345678, tmc->membase + TMC_SYS_SHUTDOWN_LOCK); + iowrite32(0x1, tmc->membase + TMC_SYS_SHUTDOWN); + + return len; +} + + +static DEVICE_ATTR(major, S_IRUGO, major_show, NULL); +static DEVICE_ATTR(minor, S_IRUGO, minor_show, NULL); +static DEVICE_ATTR(optic_cpld_major, S_IRUGO, optic_cpld_major_show, NULL); +static DEVICE_ATTR(optic_cpld_devid, S_IRUGO, optic_cpld_devid_show, NULL); +static DEVICE_ATTR(optic_cpld_minor, S_IRUGO, optic_cpld_minor_show, NULL); +static DEVICE_ATTR(shutdown, S_IWUSR, NULL, set_sys_shutdown); + +static struct attribute *tmc_attrs[] = { + &dev_attr_major.attr, + &dev_attr_minor.attr, + &dev_attr_optic_cpld_major.attr, + &dev_attr_optic_cpld_devid.attr, + &dev_attr_optic_cpld_minor.attr, + &dev_attr_shutdown.attr, + NULL, +}; + +static struct attribute_group tmc_attr_group = { + .attrs = tmc_attrs, +}; + +#if defined TMC_DO_SCRATCH_TEST +/* Do a quick scratch access test */ +static int tmc_do_test_scratch(struct tmc_fpga_data *tmc) +{ + struct pci_dev *pdev = tmc->pdev; + struct device *dev = &pdev->dev; + int offset = TMC_SCRATCH; + u32 acc, val = 0xdeadbeaf; + + /* + * Check rw register access -> use the scratch reg. + */ + iowrite32(val, tmc->membase + offset); + acc = ioread32(tmc->membase + offset); + if (acc != val) { + dev_err(dev, "Tmc scratch(0x%x) failed: %08x.%08x!\n", + offset, val, acc); + return -EIO; + } + + for (val = 0; val < 0xf0000000; val += 0x01010101) { + iowrite32(val, tmc->membase + offset); + acc = ioread32(tmc->membase + offset); + if (acc != val) { + dev_err(dev, "Tmc scratch(0x%x) failed: %08x.%08x!\n", + offset, val, acc); + return -EIO; + } + } + + /* + * Write a sig before leaving.. + */ + val = 0xcafebabe; + iowrite32(val, tmc->membase + offset); + dev_dbg(dev, "Tmc scratch result: 0x%08x\n", + ioread32(tmc->membase + offset)); + + return 0; +} +#endif /* TMC_DO_SCRATCH_TEST */ + +static int tmc_fpga_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int err; + struct tmc_fpga_data *tmc; + struct device *dev = &pdev->dev; + + dev_dbg(dev, "Tmc FPGA Probe called\n"); + + tmc = devm_kzalloc(dev, sizeof(*tmc), GFP_KERNEL); + if (!tmc) + return -ENOMEM; + + err = pcim_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "Failed to enable device %d\n", err); + return err; + } + + err = pcim_iomap_regions(pdev, 1 << 0, "tmc-core"); + if (err) { + dev_err(&pdev->dev, "Failed to iomap regions %d\n", err); + goto err_disable; + } + + tmc->membase = pcim_iomap_table(pdev)[0]; + if (IS_ERR(tmc->membase)) { + dev_err(dev, "pci_ioremap_bar() failed\n"); + err = -ENOMEM; + goto err_release; + } + + tmc->pdev = pdev; + pci_set_drvdata(pdev, tmc); + + /* All Tmc uses MSI interrupts - enable bus mastering */ + pci_set_master(pdev); + +#if defined TMC_DO_SCRATCH_TEST + /* Check IO before proceeding */ + dev_dbg(dev, "Tmc FPGA starting scratch test\n"); + err = tmc_do_test_scratch(tmc); + if (err) + goto err_unmap; + + dev_dbg(dev, "Tmc FPGA scratch test passed !!!\n"); +#endif /* TMC_DO_SCRATCH_TEST */ + + switch (id->device) { + case PCI_DEVICE_ID_JNX_TMC_CHD: + err = mfd_add_devices(dev, pdev->bus->number, + &chassisd_tmc_mfd_devs[0], + ARRAY_SIZE(chassisd_tmc_mfd_devs), + &pdev->resource[0], + 0, NULL /* tmc->irq_domain */); + break; + case PCI_DEVICE_ID_JNX_TMC_PFE: + err = mfd_add_devices(dev, pdev->bus->number, + &pfe_tmc_mfd_devs[0], + ARRAY_SIZE(pfe_tmc_mfd_devs), + &pdev->resource[0], + 0, NULL /* tmc->irq_domain */); + break; + default: + dev_err(&pdev->dev, "Invalid PCI Device ID id:%d\n", + id->device); + goto err_unmap; + } + + if (err < 0) { + dev_err(&pdev->dev, "Failed to add mfd devices %d\n", err); + goto err_unmap; + } + + err = sysfs_create_group(&pdev->dev.kobj, &tmc_attr_group); + if (err) { + sysfs_remove_group(&pdev->dev.kobj, &tmc_attr_group); + dev_err(&pdev->dev, "Failed to create attr group\n"); + goto err_remove_mfd; + } + + tmc->major = ioread32(tmc->membase + TMC_REVISION); + tmc->minor = ioread32(tmc->membase + TMC_MINOR); + + tmc->optic_cpld_major = ioread32(tmc->membase + TMC_OPTIC_CPLD_MAJOR); + tmc->optic_cpld_minor = ioread32(tmc->membase + TMC_OPTIC_CPLD_MINOR); + + dev_info(dev, "Tmc FPGA Revision: 0x%02X_%06X, Minor: %02X\n", + (tmc->major >> 24) & 0xff, + tmc->major & 0xffffff, + (tmc->minor) & 0xff); + dev_info(dev, "Tmc FPGA optic cpld Major: 0x%01X, Minor: 0x%02X " + "Devid: 0x%01X\n", (tmc->optic_cpld_major) & 0xf, + (tmc->optic_cpld_minor) & 0xff, + (tmc->optic_cpld_major >> 4) & 0xf); + dev_info(dev, "Tmc FPGA mem:0x%lx\n", + (unsigned long)tmc->membase); + + return 0; + +err_remove_mfd: + mfd_remove_devices(dev); +err_unmap: + pci_iounmap(pdev, tmc->membase); +err_release: + pci_release_regions(pdev); +err_disable: + pci_disable_device(pdev); + + return err; +} + +static void tmc_fpga_remove(struct pci_dev *pdev) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(&pdev->dev); + + sysfs_remove_group(&pdev->dev.kobj, &tmc_attr_group); + mfd_remove_devices(&pdev->dev); +} + +static const struct pci_device_id tmc_fpga_id_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_TMC_CHD) }, + { PCI_DEVICE(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_TMC_PFE) }, + { } +}; +MODULE_DEVICE_TABLE(pci, tmc_fpga_id_tbl); + +static struct pci_driver tmc_fpga_driver = { + .name = "tmc-core", + .id_table = tmc_fpga_id_tbl, + .probe = tmc_fpga_probe, + .remove = tmc_fpga_remove, +}; + +module_pci_driver(tmc_fpga_driver); + +MODULE_DESCRIPTION("Juniper Networks TMC FPGA MFD core driver"); +MODULE_AUTHOR("Ashish Bhensdadia "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-psu.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-psu.c new file mode 100644 index 000000000000..86eeb6f88e45 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-psu.c @@ -0,0 +1,173 @@ +/* + * Juniper Networks TMC fpga PSU driver + * + * This driver is for detecting if the PSU is present or not + * + * Copyright (C) 2020 Juniper Networks + * Author: Ciju Rajan K + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Max PSUs supported by this driver */ +#define NUM_PSU 2 + +struct tmc_psu_data { + int num_psu; + void __iomem *tmc_membase; +}; + +enum sysfs_psu_attributes { + PSU0_PRESENT, + PSU1_PRESENT, +}; + +static bool get_psu_presense(void *addr, u8 idx) +{ + bool ret = 0; + u32 value = ~(-1); + + value = ioread32(addr); + /* + * BIT(6) is for PSU 0 + * BIT(7) is for PSU 1 + * idx will be either 0 (PSU0) or 1 (PSU1) + */ + value &= BIT(idx+6); + + if (value) + ret = 1; + + return ret; +} + +/* + * Sysfs files are present in this path + * /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/psu-tmc.15/psu*_present + */ + +#define DECLARE_PSU_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(psu##index##_present, S_IRUGO, tmc_psu_presense_show, NULL, PSU##index##_PRESENT) +#define DECLARE_PSU_PRESENT_ATTR(index) &sensor_dev_attr_psu##index##_present.dev_attr.attr + +static ssize_t tmc_psu_presense_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); + struct platform_device *pdev = to_platform_device(dev); + struct tmc_psu_data *psu = platform_get_drvdata(pdev); + + return sprintf(buf, "%d\n", get_psu_presense(psu->tmc_membase, s_attr->index)); + +} + +DECLARE_PSU_PRESENT_SENSOR_DEV_ATTR(0); +DECLARE_PSU_PRESENT_SENSOR_DEV_ATTR(1); + +static struct attribute *tmc_psu_attrs[] = { + DECLARE_PSU_PRESENT_ATTR(0), + DECLARE_PSU_PRESENT_ATTR(1), + NULL +}; + +static struct attribute_group tmc_psu_attr_group = { + .attrs = tmc_psu_attrs, +}; + +static int tmc_psu_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tmc_psu_data *psu; + int ret; + struct resource *res; + void __iomem *addr; + + psu = devm_kzalloc(dev, sizeof(*psu), GFP_KERNEL); + if (!psu) { + dev_err(dev, "psu structure allocation failed\n"); + return -ENOMEM; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "res allocation failed\n"); + return -ENODEV; + } + + addr = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!addr) { + dev_err(dev, "ioremap failed\n"); + return -ENOMEM; + } + + psu->tmc_membase = addr; + psu->num_psu = NUM_PSU; + + platform_set_drvdata(pdev, psu); + + ret = sysfs_create_group(&dev->kobj, &tmc_psu_attr_group); + if (ret != 0) { + dev_err(dev, "jnx-tmc-psu: sysfs_create_group failed: %d\n", ret); + return ret; + } + + return 0; +} + +static int tmc_psu_remove(struct platform_device *pdev) +{ + struct tmc_psu_data *psu = platform_get_drvdata(pdev); + + if (psu) { + devm_kfree(&pdev->dev, psu); + } + sysfs_remove_group(&pdev->dev.kobj, &tmc_psu_attr_group); + + return 0; +} + +static struct platform_driver jnx_tmc_psu_driver = { + .driver = { + .name = "psu-tmc", + .owner = THIS_MODULE, + }, + .probe = tmc_psu_probe, + .remove = tmc_psu_remove, +}; + +static int __init jnx_tmc_psu_driver_init(void) +{ + int ret = -1; + + ret = platform_driver_register(&jnx_tmc_psu_driver); + + return ret; + +} + +static void __exit jnx_tmc_psu_driver_exit(void) +{ + platform_driver_unregister(&jnx_tmc_psu_driver); +} + +module_init(jnx_tmc_psu_driver_init); +module_exit(jnx_tmc_psu_driver_exit); + +MODULE_DESCRIPTION("Juniper Networks TMC PSU driver"); +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h new file mode 100644 index 000000000000..dce7d7be3311 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h @@ -0,0 +1,93 @@ +/* + * Juniper Tmc FPGA register definitions + * + * Copyright (C) 2018 Juniper Networks + * Author: Ashish Bhensdadia + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __JNX_TMC_H__ +#define __JNX_TMC_H__ + + +#define TMC_REVISION 0x00064 +#define TMC_MINOR 0x00068 +#define TMC_SCRATCH 0x00098 + +#define TMC_OPTIC_CPLD_MAJOR 0x00104 +#define TMC_OPTIC_CPLD_MINOR 0x00108 + +/* + * I2C Master Block + */ +#define TMC_I2C_AUTOMATION_I2C_CONTROL_START 0x07000 +#define TMC_I2C_AUTOMATION_I2C_CONTROL_END 0x07500 + +#define TMC_I2C_DPMEM_ENTRY_START 0x10000 +#define TMC_I2C_DPMEM_ENTRY_END 0x13FFC + +#define TMC_LED_CONTROL_START 0x58 +#define TMC_LED_CONTROL_END 0x5B + +/* + * RE-FPGA block + */ +#define TMC_REFPGA_ACCESS_START 0x228 +#define TMC_REFPGA_ACCESS_END 0x233 + +#define TMC_I2C_MASTER_NR_MSTRS 16 +#define TMC_I2C_MSTR_MAX_GROUPS 66 + + +/* + * TMC GPIO SLAVE Block + */ +#define TMC_GPIO_PTP_RESET_START 0x94 +#define TMC_GPIO_PTP_RESET_END 0x97 + +#define TMC_GPIO_PTP_CFG_START 0xa4 +#define TMC_GPIO_PTP_CFG_END 0xa7 + +#define TMC_GPIO_PTP_DATA_START 0xa8 +#define TMC_GPIO_PTP_DATA_END 0xab + +#define TMC_GPIO_SLAVE0_START 0xf0 +#define TMC_GPIO_SLAVE0_END 0x16b + +#define TMC_GPIO_SLAVE1_START 0x170 +#define TMC_GPIO_SLAVE1_END 0x1eb + +#define TMC_GPIO_SLAVE2_START 0x1f0 +#define TMC_GPIO_SLAVE2_END 0x213 + +#define TMC_GPIO_SLAVE3_START 0x280 +#define TMC_GPIO_SLAVE3_END 0x2eb + +#define TMC_GPIO_SFP_SLAVE0_START 0x308 +#define TMC_GPIO_SFP_SLAVE0_END 0x32b + +#define TMC_GPIO_SFP_SLAVE1_START 0x32c +#define TMC_GPIO_SFP_SLAVE1_END 0x34b + +/* + * TMC PSU Block + */ +#define TMC_PSU_START 0x240 +#define TMC_PSU_END 0x243 + +/* + * TMC SHUTDOWN REG + */ +#define TMC_SYS_SHUTDOWN_LOCK 0x254 +#define TMC_SYS_SHUTDOWN 0x250 + +/* + * TMC DS100 MUX Block + */ +#define TMC_GPIO_MUX_SLAVE_START 0x26c +#define TMC_GPIO_MUX_SLAVE_END 0x26f + +#endif /* __JNX_TMC_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/leds-jnx-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/leds-jnx-tmc.c new file mode 100644 index 000000000000..134faefd70a3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/leds-jnx-tmc.c @@ -0,0 +1,223 @@ +/* + * Juniper Networks TMC fpga LEDs driver + * + * Copyright (C) 2018 Juniper Networks + * Author: Ciju Rajan K + * + * This driver is based on I2CS fpga LEDs driver by Georgi Vlaev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +/* Max LEDs supported by this driver (2bits of control per LED in 32bit reg) */ +#define NUM_LEDS 3 + +struct tmc_led { + struct led_classdev lc; + struct work_struct work; + int on; + int bit; + void __iomem *addr; +}; + +struct tmc_led_data { + int num_leds; + struct tmc_led *leds; +}; + +struct led_table +{ + const char *name; + int reg; +}; + +static struct led_table qfx5200_tmc_led_data[] = { + { + .name = "system", + .reg = 0, + }, + { + .name = "beacon", + .reg = 3, + }, + { + .name = "master", + .reg = 5, + } +}; + +static void jnx_tmc_leds_work(struct work_struct *work) +{ + struct tmc_led *led = container_of(work, struct tmc_led, work); + u32 value = ~(-1); + + value = ioread32(led->addr); + + if (led->on) { + if (!strncmp(led->lc.name, "beacon", 6)) { + value &= ~BIT(led->bit + 1); + value |= BIT(led->bit); + } else { + value |= BIT(led->bit) | BIT(led->bit + 1); + } + } else { + value &= ~(BIT(led->bit) | BIT(led->bit + 1)); + } + + iowrite32(value, led->addr); +} + +static void jnx_tmc_leds_brightness_set(struct led_classdev *lc, + enum led_brightness brightness) +{ + struct tmc_led *led = container_of(lc, struct tmc_led, lc); + + led->on = (brightness != LED_OFF); + schedule_work(&led->work); +} + +static int jnx_tmc_leds_init_one(struct device *dev, + struct tmc_led_data *ild, + int num, void __iomem *addr) +{ + struct tmc_led *led; + int ret; + + led = &ild->leds[num]; + + led->addr = addr; + + led->lc.name = qfx5200_tmc_led_data[num].name; + led->bit = qfx5200_tmc_led_data[num].reg; + led->lc.brightness_set = jnx_tmc_leds_brightness_set; + + + ret = devm_led_classdev_register(dev, &led->lc); + if (ret) + return ret; + + INIT_WORK(&led->work, jnx_tmc_leds_work); + + return 0; +} + +static int jnx_tmc_leds_init(struct device *dev, struct tmc_led_data *ild, + struct resource *res) +{ + int ret, idx = 0; + void __iomem *addr; + + if (!dev->parent) { + dev_err(dev, "dev->parent is null\n"); + return -ENODEV; + } + + addr = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!addr) { + dev_err(dev, "ioremap failed\n"); + return -ENOMEM; + } + + ild->num_leds = NUM_LEDS; + ild->leds = devm_kzalloc(dev, sizeof(struct tmc_led) * NUM_LEDS, + GFP_KERNEL); + if (!ild->leds) { + dev_err(dev, "LED allocation failed\n"); + return -ENOMEM; + } + + for (idx=0; idxdev; + struct tmc_led_data *ild; + int ret; + struct resource *res; + + ild = devm_kzalloc(dev, sizeof(*ild), GFP_KERNEL); + if (!ild) { + dev_err(dev, "ild allocation failed\n"); + return -ENOMEM; + } + + platform_set_drvdata(pdev, ild); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "res allocation failed\n"); + return -ENODEV; + } + + ret = jnx_tmc_leds_init(dev, ild, res); + if (ret < 0) + return ret; + + return 0; +} + +static int tmc_leds_remove(struct platform_device *pdev) +{ + struct tmc_led_data *ild = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < ild->num_leds; i++) { + devm_led_classdev_unregister(&pdev->dev, &ild->leds[i].lc); + cancel_work_sync(&ild->leds[i].work); + } + + if (ild) { + if (ild->leds) + devm_kfree(&pdev->dev, ild->leds); + devm_kfree(&pdev->dev, ild); + } + + return 0; +} + +static struct platform_driver jnx_tmc_leds_driver = { + .driver = { + .name = "leds-tmc", + .owner = THIS_MODULE, + }, + .probe = tmc_leds_probe, + .remove = tmc_leds_remove, +}; + +static int __init jnx_tmc_leds_driver_init(void) +{ + int ret = -1; + + ret = platform_driver_register(&jnx_tmc_leds_driver); + + return ret; + +} + +static void __exit jnx_tmc_leds_driver_exit(void) +{ + platform_driver_unregister(&jnx_tmc_leds_driver); +} + +module_init(jnx_tmc_leds_driver_init); +module_exit(jnx_tmc_leds_driver_exit); + +MODULE_DESCRIPTION("Juniper Networks TMC leds driver"); +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/pci_ids.h b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/pci_ids.h new file mode 100644 index 000000000000..090707751b2c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/pci_ids.h @@ -0,0 +1,144 @@ +/* + * Juniper PCI ID(s) - for devices on Juniper Boards + * + * Rajat Jain + * Copyright 2014 Juniper Networks + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __JNX_PCI_IDS_H__ +#define __JNX_PCI_IDS_H__ + +#define PCI_VENDOR_ID_JUNIPER 0x1304 +#define PCI_VENDOR_ID_ERICSSON 0x1519 +#define PCI_VENDOR_ID_ERICSSON_AS 0x1a25 + +/* + * PTX SAM FPGA, device ID as present on various Juniper boards, such as + * - Sangria FPC + * - Hendricks FPC + * - Sangria 24x10GE PIC + * - Gladiator FPC + */ +#define PCI_DEVICE_ID_JNX_SAM 0x0004 + +/* Juniper Broadway ASIC family */ +#define PCI_DEVICE_ID_JNX_TF 0x003c +#define PCI_DEVICE_ID_JNX_TL 0x003d +#define PCI_DEVICE_ID_JNX_TQ 0x003e +#define PCI_DEVICE_ID_JNX_OTN_FRAMER 0x0055 +#define PCI_DEVICE_ID_JNX_PE 0x005e +#define PCI_DEVICE_ID_JNX_PF 0x005f /* Juniper Paradise ASIC */ +#define PCI_DEVICE_ID_JNX_ZF 0x008d /* Juniper ZF Fabric ASIC */ +#define PCI_DEVICE_ID_JNX_ZX 0x008e /* Juniper ZX ASIC */ +#define PCI_DEVICE_ID_JNX_ZT 0x0090 /* Juniper ZT ASIC */ +#define PCI_DEVICE_ID_JNX_BT 0x00B2 /* Juniper BT ASIC */ + +/* Juniper SAM FPGA - Omega SIB, Sochu SHAM, Gladiator SIB */ +#define PCI_DEVICE_ID_JNX_SAM_OMEGA 0x006a + +/* Juniper SAM FPGA - present on GLD FPC board */ +#define PCI_DEVICE_ID_JNX_SAM_X 0x006b + +/* Juniper PAM FPGA - present on PTX MLC board */ +#define PCI_DEVICE_ID_JNX_PAM 0x006c +/* Juniper CBC FPGA - present on PTX1K RCB */ +#define PCI_DEVICE_ID_JNX_CBC 0x006e +#define PCI_DEVICE_ID_JNX_CBC_P2 0x0079 +#define PCI_DEVICE_ID_JNX_OMG_CBC 0x0083 + +/* Juniper Summit FPGA */ +#define PCI_DEVICE_ID_JNX_SUMMIT 0x009B + +/* Juniper DOON FPGA */ +#define PCI_DEVICE_ID_JNX_DOON_RCB_CBC 0x0098 + +/* Juniper CBC FPGA in PTX-5K MTRCB */ +#define PCI_DEVICE_ID_JNX_PTX5K_MTRCB_CBC 0x0071 + +/* Other Vendors' devices */ +#define PCI_DEVICE_ID_IDT_PES12NT3_TRANS_AB 0x8058 +#define PCI_DEVICE_ID_IDT_PES12NT3_TRANS_C 0x8059 +#define PCI_DEVICE_ID_IDT_PES12NT3_INT_NTB_C 0x805a +#define PCI_DEVICE_ID_IDT_48H12G2 0x807a +#define PCI_DEVICE_ID_IDT_PES24NT24G2 0x808e +#define PCI_DEVICE_ID_IDT_PES16NT16G2 0x8090 + +#define PCI_DEVICE_ID_PLX_8614 0x8614 +#define PCI_DEVICE_ID_PLX_8618 0x8618 +#define PCI_DEVICE_ID_PLX_8713 0x8713 +#define PCI_DEVICE_ID_PLX_8725 0x8725 +#define PCI_DEVICE_ID_PLX_8749 0x8749 +#define PCI_DEVICE_ID_PLX_8796 0x8796 +#define PCI_DEVICE_ID_PLX_8608 0x8608 + +/* + * Juniper CBD FPGA Device ID(s) + */ +#define JNX_CBD_FPGA_DID_09B3 0x004D +#define JNX_CBD_FPGA_DID_0BA8 0x005A + +/* + * Juniper Brackla FPGA Device IDs + * - UBAM, MBAM, PBAM, QBAM + */ +#define PCI_DEVICE_ID_JNX_UBAM 0x00A7 +#define PCI_DEVICE_ID_JNX_PBAM 0x00A8 +#define PCI_DEVICE_ID_JNX_MBAM 0x00A9 +#define PCI_DEVICE_ID_JNX_QBAM 0x00AA + +/* + * Juniper MPC11E Supercon and WAN FPGA IDs + */ +#define PCI_DEVICE_ID_JNX_MPC11CON 0x00A1 +#define PCI_DEVICE_ID_JNX_MPC11WAN 0x00C4 + +/* + * Juniper Attella TMC and Supercon FPGA IDs + */ +#define PCI_DEVICE_ID_JNX_ARGUS 0x00B0 +#define PCI_DEVICE_ID_JNX_ATIC 0x00C0 +#define PCI_DEVICE_ID_JNX_ATMC_CHD 0x00C1 +#define PCI_DEVICE_ID_JNX_ATMC_PFE 0x00C2 +#define PCI_DEVICE_ID_JNX_AOHIO 0x00C3 + +/* + * Juniper TMC FPGA Device IDs + */ +#define PCI_DEVICE_ID_JNX_TMC_CHD 0x007B +#define PCI_DEVICE_ID_JNX_TMC_PFE 0x007C + +#define PCI_DEVICE_ID_XILINX_1588_FPGA 0x0505 + +/* + * Juniper Scapa SIB/LC Supercon FPGA IDs + */ +#define PCI_DEVICE_ID_JNX_SCAPA_SIB_CTRL 0x00BA +#define PCI_DEVICE_ID_JNX_SDLC_CTRL 0x00BE +#define PCI_DEVICE_ID_JNX_LLC_CTRL 0x00C8 + +/* + * Deanston WANIO FPGA + */ +#define PCI_DEVICE_ID_JNX_DEANSTON_WAN 0x00C6 + +/* + * Juniper Ardbeg Supercon FPGA IDs + */ +#define PCI_DEVICE_ID_JNX_ARDBEG_CTRL 0x00C5 + +/* + * Ericsson CCM FPGA ID used in Bolan (ACX753) + */ +#define PCI_DEVICE_ID_ERIC_CCM_FPGA 0x0020 + +/* + * Ericsson OAM FPGA ID used in Bolan (ACX753) + */ +#define PCI_DEVICE_ID_ERIC_OAM_FPGA 0x7021 + +#endif /* __JNX_PCI_IDS_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/service/qfx5200-platform-init.service b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/service/qfx5200-platform-init.service new file mode 100755 index 000000000000..550a9eda3464 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/service/qfx5200-platform-init.service @@ -0,0 +1,15 @@ +[Unit] +Description=Juniper QFX5200 initialization service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/local/bin/juniper_qfx5200_util.py install +ExecStart=/usr/local/bin/juniper_qfx5200_monitor.py +RemainAfterExit=yes +StandardOutput=syslog+console +StandardError=syslog+console + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/setup.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/setup.py new file mode 100755 index 000000000000..a847e4d8f6c3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Juniper QFX5200-32C-S platforms', + + packages=['sonic_platform'], + package_dir={'sonic_platform': 'qfx5200/sonic_platform'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/__init__.py new file mode 100755 index 000000000000..9e1b2e56b1c4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/__init__.py @@ -0,0 +1 @@ +import platform diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/chassis.py new file mode 100755 index 000000000000..39b6f81c9f59 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/chassis.py @@ -0,0 +1,260 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# which provide the chassis specific details +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. +# + +try: + import commands + import time + from sonic_platform_base.chassis_base import ChassisBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Chassis(ChassisBase): + """ + JUNIPER QFX5200 Platform-specific Chassis class + """ + + def __init__(self): + ChassisBase.__init__(self) + + def get_qfx5200_parameter_value(self,parameter_name): + try: + with open("/var/run/eeprom", "r") as file: + for item in file: + content = item.split('=') + if content[0] == parameter_name: + return content[1:] + return "False" + except IOError: + print "Error: File not found" + return "False" + + def get_product_name(self): + product_name_list = self.get_qfx5200_parameter_value('Product Name') + if product_name_list: + product_name = ''.join(product_name_list) + return product_name + else: + return False + + + def get_part_number(self): + part_number_list = self.get_qfx5200_parameter_value('Part Number') + if part_number_list: + part_number = ''.join(part_number_list) + return part_number + else: + return False + + + def get_serial_number(self): + serial_number_list = self.get_qfx5200_parameter_value('Serial Number') + if serial_number_list: + serial_number = ''.join(serial_number_list) + return serial_number + else: + return False + + + def get_base_mac(self): + mac_list = self.get_qfx5200_parameter_value('MAC Address') + if mac_list: + mac = ''.join(mac_list) + return mac + else: + return False + + + def get_mfg_date(self): + mfgdate_list = self.get_qfx5200_parameter_value('Manufacture Date') + if mfgdate_list: + mfgdate = ''.join(mfgdate_list) + return mfgdate + else: + return False + + + def get_platform_name(self): + platform_name_list = self.get_qfx5200_parameter_value('Platform Name') + if platform_name_list: + platform_name = ''.join(platform_name_list) + return platform_name + else: + return False + + + def get_MACnumber_name(self): + MACnumber_name_list = self.get_qfx5200_parameter_value('Number of MAC Addresses') + if MACnumber_name_list: + MACnumber_name = ''.join(MACnumber_name_list) + return MACnumber_name + else: + return False + + + def get_vendor_name(self): + vendor_name_list = self.get_qfx5200_parameter_value('Vendor Name') + if vendor_name_list: + vendor_name = ''.join(vendor_name_list) + return vendor_name + else: + return False + + def get_mfg_name(self): + mfg_name_list = self.get_qfx5200_parameter_value('Manufacture Name') + if mfg_name_list: + mfg_name = ''.join(mfg_name_list) + return mfg_name + else: + return False + + def get_vendorext_name(self): + vendorext_list = self.get_qfx5200_parameter_value('Vendor Extension') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextIANA_name(self): + vendorext_list = self.get_qfx5200_parameter_value('IANA') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMREV_name(self): + vendorext_list = self.get_qfx5200_parameter_value('Assembly Part Number Revision') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMPartNum_name(self): + vendorext_list = self.get_qfx5200_parameter_value('Assembly Part Number') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMID_name(self): + vendorext_list = self.get_qfx5200_parameter_value('Assembly ID') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMMajNum_name(self): + vendorext_list = self.get_qfx5200_parameter_value('Assembly Major Revision') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMMinNum_name(self): + vendorext_list = self.get_qfx5200_parameter_value('Assembly Minor Revision') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextCLEI_name(self): + vendorext_list = self.get_qfx5200_parameter_value('CLEI code') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_onieversion_name(self): + onieversion_name_list = self.get_qfx5200_parameter_value('ONIE Version') + if onieversion_name_list: + onieversion_name = ''.join(onieversion_name_list) + return onieversion_name + else: + return False + + def get_crc_name(self): + crc_list = self.get_qfx5200_parameter_value('CRC') + if crc_list: + crc_name = ''.join(crc_list) + return crc_name + else: + return False + + def get_fan_type(self): + fantype_list = self.get_qfx5200_parameter_value('Fan Type') + if fantype_list: + fantype_name = ''.join(fantype_list) + return fantype_name + else: + return False + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + """ + status, last_reboot_reason = commands.getstatusoutput("busybox devmem 0xFED50004 8") + if (status == 0): + if last_reboot_reason == "0x80": + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + else: + time.sleep(3) + status, last_reboot_reason = commands.getstatusoutput("busybox devmem 0xFED50004 8") + if last_reboot_reason == "0x80": + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/platform.py new file mode 100755 index 000000000000..a9e70c725195 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/platform.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# which provide the platform specific details +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. +# + + +try: + from sonic_platform_base.platform_base import PlatformBase +except ImportError as e: + raise ImportError("%s - required module not found" % e) + +platformDict = {'platform':'QFX5200-32C'} + +class Platform(PlatformBase): + def __init__(self): + self.platform = self.getPlatform() + + def getPlatformDict(self): + global platformDict + if platformDict: + return platformDict + + def readPlatformName(self): + return self.getPlatformDict().get('platform') + + def getPlatform(self): + platformCls = self.readPlatformName() + return platformCls + + def get_chassis(self): + from chassis import Chassis + chassis = Chassis() + return chassis + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README new file mode 100755 index 000000000000..ec9ebe97f0ee --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README @@ -0,0 +1,117 @@ + +Copyright (c) 2019, Juniper Networks, Inc. +All rights reserved. + +Front panel LEDs +================ +There are 4 system LEDs in the front panel. Master, System, Alarm, & Beacon. +LED controls can be found under /sys/class/leds. The sysfs interface & +colour mappings are as follows: + +For master LED: /sys/class/leds/master/brightness + 0 => off + 1 => green + +For system LED: /sys/class/leds/system/brightness + 0 => off + 1 => green + +For alarm LED: /sys/class/leds/alarm/brightness + 0 => off + 1 => amber + 2 => red + +For beacon LED: /sys/class/leds/beacon/brightness + 0 => off + 1 => blue + +For any of the above LEDs, max_brightness file can tell the maximum value +accepted. + +System FANs +=========== +There are 4 fans and each of the fan has 2 fan modules. Overall there are +8 fans in the system. + +Fan controls can be found in /sys/bus/i2c/devices/17-0068. All the fans +are controlled by one duty cycle value, ranges from 0 to 100 + +Fan duty cycle can be controlled through /sys/bus/i2c/devices/17-0068/pwm1 + +Fan module presence is given by /sys/bus/i2c/devices/17-0068/fan[1-4]_present +file. A value of '1' indicate that fan is present & a value of '0' otherwise. + +Fan rotation direction is given by /sys/bus/i2c/devices/17-0068/fan[1-4]_direction. +A value of '0' indicate the direction is AFO (Front to back airflow) or Airflow +out. A value of '1' indicate that direction is AFI (Back to front airflow) or +Airflow in. + +Fan speed is given by fan[1-4]_input + +Temperature sensors +=================== +There are 6 temperature sensors. The readings are available in +/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input + +System PSUs +=========== +There are two independent PSUs. These are controlled by a dedicated CPLD. +The status registers are mapped under /sys/bus/i2c/devices/9-0050 and +/sys/bus/i2c/devices/10-0053. + +SFPs +==== +There are 64 QSFP+ modules supported in qfx5210 platform. EEPORMs will be +mapped under /sys/bus/i2c/devices/[25-88]-0050/ sysfs directory. + +FEC should be turned on for 100G SR optics and should be turned off for +100G LR optics. If the optic is changed, please update the entry and +reload the configuration. If the FEC mode is not set as per the optic +type the port may not link up or work properly. + +As an example, see this configuration for FEC for 100G SR4 optics in +/etc/sonic/config_db.json + +"Ethernet4": { + "admin_status": "up", + "alias": "Ethernet4", + "fec": "rs", + "index": "1", + "lanes": "65,66,67,68", + "mtu": "9100", + "speed": "100000" + } + +Sensor details +============== +LM75 supported sensor modules will be available under 'sensors' command. +If you want to get all the sensor data including the SFPs & LEDs, you can +invoke 'sudo juniper_qfx5210_util.py show' + +Platform poweroff +================= +Linux poweroff commands such as 'poweroff', 'shutdown', 'halt', etc. will not +power off qfx5210 platform as there are custom CPLDs control the power off +sequences. So acpi poweroff hooks are added for powering off the qfx5210. The +following messages are displayed in the console towards end of poweroff +sequence: + + [ 52.500807] System halt/power_off + [ 52.866331] reboot: Power down + [ 52.903257] pm_power_off: qfx5210_cpld_power_off + +Once the above messages are seen, you can safely remove the power to the system. + +Similarly platform reboot sequences are in place for system reboot. The following +messages are displayed in the console when the system is rebooted: + + [ 6053.163363] System restart: qfx5210_cpld_soft_reset + +Platform monitoring daemon +========================== +“juniper_qfx5210_monitor.py†is the platform monitoring script. +It implements the qfx5210 EM policy. This script will run as system service +and monitor the temperature sensors in every 20 seconds. Based on the EM +policy thresholds, it controls the fan rpm, manage alarm leds, and +shutdown the box. + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py new file mode 100755 index 000000000000..da71c586be43 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py @@ -0,0 +1,929 @@ +#!/usr/bin/env python +# +# Name: juniper_qfx5200_monitor.py version: 1.0 +# +# Description: This file contains the EM implementation for QFX5200 platform +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +try: + import os + import commands + import subprocess + import logging + import logging.config + import logging.handlers + import time + import glob + import re +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = '/var/log/juniper_qfx5200_monitor' +verbose = False +DEBUG = False + +log_file = '%s.log' % FUNCTION_NAME +log_level = logging.DEBUG + + +isPlatformAFI = False +isFireThresholdReached = False +is35PerFlag = True +is55PerFlag = True +is75PerFlag = True +is90PerFlag = True +isFireThresholdPrint = True +FireThresholdSecsRemaining = 120 +PrevASICValue = 0 + +temp_policy_AFI = { + 0: [[35, 0, 30000], [35, 30000, 39000], [55, 39000, 0], [55, 39000, 48000], [75, 48000, 0], [75, 48000, 56000], [90, 56000, 0], [90, 56000, 65000],[100, 66000, 0], + ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 73000], ['Fire Shut Alarm', 73000, 0]], + + 1: [[35, 0, 30000], [35, 30000, 39000], [55, 39000, 0], [55, 39000, 48000], [75, 48000, 0], [75, 48000, 56000], [90, 56000, 0], [90, 56000, 65000],[100, 66000, 0], + ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 73000], ['Fire Shut Alarm', 73000, 0]], + + 2: [[35, 0, 40000], [35, 40000, 47000], [55, 47000, 0], [55, 47000, 55000], [75, 55000, 0], [75, 55000, 63000], [90, 62000, 0], [90, 62000, 69000],[100, 70000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], + + 3: [[35, 0, 36000], [35, 36000, 44000], [55, 44000, 0], [55, 44000, 52000], [75, 52000, 0], [75, 52000, 60000], [90, 60000, 0], [90, 60000, 68000],[100, 69000, 0], + ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], + + 4: [[35, 0, 52000], [35, 52000, 57000], [55, 57000, 0], [55, 57000, 63000], [75, 63000, 0], [75, 63000, 68000], [90, 68000, 0], [90, 68000, 73000],[100, 74000, 0], + ['Yellow Alarm', 72000, 78000], ['Red Alarm', 78000, 81000], ['Fire Shut Alarm', 81000, 0]], + + 5: [[35, 0, 37000], [35, 37000, 45000], [55, 45000, 0], [55, 45000, 53000], [75, 53000, 0], [75, 53000, 61000], [90, 61000, 0], [90, 61000, 69000],[100, 70000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], + + 6: [[35, 0, 37000], [35, 37000, 45000], [55, 45000, 0], [55, 45000, 53000], [75, 53000, 0], [75, 53000, 61000], [90, 61000, 0], [90, 61000, 69000],[100, 69000, 0], + ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], + + 7: [[35, 0, 52000], [35, 52000, 57000], [55, 57000, 0], [55, 57000, 63000], [75, 63000, 0], [75, 63000, 68000], [90, 68000, 0], [90, 68000, 73000],[100, 74000, 0], + ['Yellow Alarm', 72000, 78000], ['Red Alarm', 78000, 81000], ['Fire Shut Alarm', 81000, 0]], + + 8: [[35, 0, 41000], [35, 41000, 48000], [55, 48000, 0], [55, 48000, 55000], [75, 55000, 0], [75, 55000, 62000], [90, 62000, 0], [90, 62000, 69000],[100, 70000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], + + 9: [[35, 0, 42000], [35, 42000, 49000], [55, 49000, 0], [55, 49000, 57000], [75, 57000, 0], [75, 57000, 64000], [90, 64000, 0], [90, 64000, 71000],[100, 72000, 0], + ['Yellow Alarm', 70000, 76000], ['Red Alarm', 76000, 79000], ['Fire Shut Alarm', 79000, 0]], + + 10: [[35, 0, 68000], [35, 68000, 74000], [55, 74000, 0], [55, 74000, 80000], [75, 80000, 0], [75, 80000, 85000], [90, 85000, 0], [90, 85000, 91000],[100, 92000, 0], + ['Yellow Alarm', 99000, 102000], ['Red Alarm', 102000, 105000], ['Fire Shut Alarm', 105000, 0]], + + 11: [[35, 0, 42000], [35, 42000, 50000], [55, 50000, 0], [55, 50000, 58000], [75, 58000, 0], [75, 58000, 66000], [90, 66000, 0], [90, 66000, 74000],[100, 75000, 0], + ['Yellow Alarm', 86000, 92000], ['Red Alarm', 92000, 95000], ['Fire Shut Alarm', 95000, 0]], + } + +temp_policy_AFO = { + 0: [[35, 0, 42000], [35, 42000, 49000], [55, 49000, 0], [55, 49000, 55000], [75, 55000, 0], [75, 55000, 62000], [90, 62000, 0], [90, 62000, 68000],[100, 69000, 0], + ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], + + 1: [[35, 0, 41000], [35, 41000, 48000], [55, 48000, 0], [55, 48000, 55000], [75, 55000, 0], [75, 55000, 61000], [90, 61000, 0], [90, 61000, 68000],[100, 69000, 0], + ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], + + 2: [[35, 0, 44000], [35, 44000, 50000], [55, 50000, 0], [55, 50000, 56000], [75, 56000, 0], [75, 56000, 63000], [90, 63000, 0], [90, 63000, 69000],[100, 70000, 0], + ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 75000], ['Fire Shut Alarm', 75000, 0]], + + 3: [[35, 0, 36000], [35, 36000, 43000], [55, 43000, 0], [55, 43000, 50000], [75, 50000, 0], [75, 50000, 57000], [90, 57000, 0], [90, 57000, 64000],[100, 65000, 0], + ['Yellow Alarm', 63000, 69000], ['Red Alarm', 69000, 72000], ['Fire Shut Alarm', 72000, 0]], + + 4: [[35, 0, 49000], [35, 49000, 54000], [55, 54000, 0], [55, 54000, 60000], [75, 60000, 0], [75, 60000, 65000], [90, 65000, 0], [90, 65000, 70000],[100, 71000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], + + 5: [[35, 0, 46000], [35, 46000, 52000], [55, 52000, 0], [55, 52000, 58000], [75, 58000, 0], [75, 58000, 63000], [90, 63000, 0], [90, 63000, 69000],[100, 70000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], + + 6: [[35, 0, 50000], [35, 50000, 55000], [55, 55000, 0], [55, 55000, 60000], [75, 60000, 0], [75, 60000, 65000], [90, 65000, 0], [90, 65000, 70000],[100, 71000, 0], + ['Yellow Alarm', 65000, 71000], ['Red Alarm', 71000, 78000], ['Fire Shut Alarm', 78000, 0]], + + 7: [[35, 0, 49000], [35, 49000, 55000], [55, 55000, 0], [55, 55000, 60000], [75, 60000, 0], [75, 60000, 66000], [90, 66000, 0], [90, 66000, 71000],[100, 72000, 0], + ['Yellow Alarm', 70000, 76000], ['Red Alarm', 76000, 79000], ['Fire Shut Alarm', 79000, 0]], + + 8: [[35, 0, 41000], [35, 41000, 47000], [55, 47000, 0], [55, 47000, 54000], [75, 54000, 0], [75, 54000, 60000], [90, 60000, 0], [90, 60000, 66000],[100, 67000, 0], + ['Yellow Alarm', 65000, 71000], ['Red Alarm', 71000, 74000], ['Fire Shut Alarm', 74000, 0]], + + 9: [[35, 0, 57000], [35, 57000, 61000], [55, 61000, 0], [55, 61000, 66000], [75, 66000, 0], [75, 66000, 70000], [90, 70000, 0], [90, 70000, 74000],[100, 75000, 0], + ['Yellow Alarm', 73000, 79000], ['Red Alarm', 79000, 82000], ['Fire Shut Alarm', 82000, 0]], + + 10: [[35, 0, 76000], [35, 76000, 79000], [55, 79000, 0], [55, 79000, 83000], [75, 83000, 0], [75, 83000, 86000], [90, 86000, 0], [90, 86000, 89000],[100, 90000, 0], + ['Yellow Alarm', 99000, 102000], ['Red Alarm', 102000, 105000], ['Fire Shut Alarm', 105000, 0]], + + 11: [[35, 0, 51000], [35, 51000, 58000], [55, 58000, 0], [55, 58000, 64000], [75, 64000, 0], [75, 64000, 70000], [90, 70000, 0], [90, 70000, 77000],[100, 78000, 0], + ['Yellow Alarm', 86000, 92000], ['Red Alarm', 92000, 95000], ['Fire Shut Alarm', 95000, 0]], + } + +class QFX5200_FanUtil(object): + """QFX5200 Platform FanUtil class""" + + PWMINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/{1}/pwm{2}' + HWMONINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/' + PWMINPUT_NUM_IDX = 0 + PWMINPUT_NUM = 10 + _pwm_input_path_mapping = {} + _hwmon_input_path_mapping = {} + + # PWM NUMBERS + _pwm_input_node_mapping = ['1','2','3','4','1','2','3','4','1','2'] + + # I2C NUMBERS + _hwmon_input_node_mapping = ['2c','2c','2c','2c','2e','2e','2e','2e','2f','2f'] + def __init__(self): + hwmoninput_path = self.HWMONINPUT_PATH + pwminput_path = self.PWMINPUT_PATH + for x in range(self.PWMINPUT_NUM): + self._hwmon_input_path_mapping[x] = hwmoninput_path.format( + self._hwmon_input_node_mapping[x]) + + hwmon_path = os.listdir(self._hwmon_input_path_mapping[x]) + hwmon_dir = '' + for hwmon_name in hwmon_path: + hwmon_dir = hwmon_name + + self._pwm_input_path_mapping[x] = pwminput_path.format( + self._hwmon_input_node_mapping[x], + hwmon_dir, + self._pwm_input_node_mapping[x]) + def get_fan_duty_cycle(self): + fan_speed = {86: 35, 139: 55, 192: 75, 230: 90,255: 100} + ret_value = 0 + for x in range(self.PWMINPUT_NUM): + pwm_value = 0 + device_path = self._pwm_input_path_mapping[x] + cmd = ("sudo cat %s" %(device_path)) + status, pwm_value = commands.getstatusoutput(cmd) + if int(pwm_value) > 0: + ret_value = fan_speed.get(int(pwm_value)) + break + + return int(ret_value) + + def set_fan_duty_cycle(self, val): + fan_speed = {35: 86, 55: 139, 75: 192, 90: 230,100: 255} + for x in range(self.PWMINPUT_NUM): + device_path = self._pwm_input_path_mapping[x] + pwm_value = fan_speed.get(val) + pwm_value1 = str(pwm_value) + time.sleep(1) + cmd = ("sudo echo %s > %s" %(pwm_value1,device_path)) + os.system(cmd) + return True + +class QFX5200_ThermalUtil(object): + """QFX5200 Platform ThermalUtil class""" + + SENSOR_NUM_ON_MAIN_BOARD = 10 + CORETEMP_INDEX_ON_MAIN_BOARD = 10 + SENSOR_CORETEMP_NUM_ON_MAIN_BOARD = 12 + CORETEMP_NUM_ON_MAIN_BOARD = 5 + THERMAL_NUM_RANGE = 10 + SENSOR_NUM_0_IDX = 0 + SENSORS_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input' + CORETEMP_PATH = '/sys/bus/platform/devices/coretemp.0/hwmon/hwmon*/temp{0}_input' + MAJORALARM_LED_PATH = '/sys/class/leds/alarm-major/brightness' + MINORALARM_LED_PATH = '/sys/class/leds/alarm-minor/brightness' + + """ Dictionary where + key1 = thermal id index (integer) starting from 1 + value = path to fan device file (string) """ + _sensor_to_device_path_mapping = {} + + _sensor_to_device_node_mapping = [ + ['7', '48'], + ['7', '49'], + ['5', '48'], + ['5', '49'], + ['5', '4a'], + ['5', '4b'], + ['6', '48'], + ['6', '49'], + ['6', '4a'], + ['6', '4b'], + ] + + _coretemp_to_device_path_mapping = {} + + _coretemp_to_device_node_mapping = [1, 2, 3, 4, 5] + + def __init__(self): + sensor_path = self.SENSORS_PATH + coretemp_path = self.CORETEMP_PATH + for x in range(self.SENSOR_NUM_ON_MAIN_BOARD): + self._sensor_to_device_path_mapping[x] = sensor_path.format( + self._sensor_to_device_node_mapping[x][0], + self._sensor_to_device_node_mapping[x][1]) + + for x in range(self.CORETEMP_NUM_ON_MAIN_BOARD): + self._coretemp_to_device_path_mapping[x] = coretemp_path.format( + self._coretemp_to_device_node_mapping[x]) + + + """ Function reads the 5 temp inputs in CORETEMP_PATH + and returns the average of these 5 temp readings """ + def get_coretempValue(self): + sum = 0 + for x in range(self.CORETEMP_NUM_ON_MAIN_BOARD): + sum += self._get_coretemp_node_val(x) + avg = sum/self.CORETEMP_NUM_ON_MAIN_BOARD + return int(avg) + + + """ Function takes the Sensor number as input, constructs the device path, + opens sensor file, reads the temp content from the file and returns the value """ + def _get_sensor_node_val(self, thermal_num): + if thermal_num < self.SENSOR_NUM_0_IDX or thermal_num >= self.SENSOR_NUM_ON_MAIN_BOARD: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + return None + + device_path = self.get_thermal_to_device_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('get_sensor_node_val: unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('get_sensor_node_val: content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except IOError as e: + logging.error('get_sensor_node_val: unable to close file. device_path:%s', str(e)) + return None + + return int(content) + + + """ Function takes the coretemp number as input, constructs the device path, + opens sensor file, reads the temp content from the file and returns the value """ + def _get_coretemp_node_val(self, thermal_num): + + device_path = self.get_coretemp_to_device_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('get_coretemp_node_val: unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('get_coretemp_node_val: content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except IOError as e: + logging.error('_get_coretemp_node_val: unable to close file. device_path:%s', str(e)) + return None + + return int(content) + + + def get_thermal_to_device_path(self, thermal_num): + return self._sensor_to_device_path_mapping[thermal_num] + + + def get_coretemp_to_device_path(self, thermal_num): + return self._coretemp_to_device_path_mapping[thermal_num] + + + def get_alarm_led_brightness(self): + try: + val_file = open(self.MAJORALARM_LED_PATH) + except IOError as e: + logging.error('get_alarm_led_brightness: unable to open file: %s', str(e)) + return False + majoralarm_value = val_file.readline().rstrip() + val_file.close() + + try: + val_file = open(self.MINORALARM_LED_PATH) + except IOError as e: + logging.error('get_alarm_led_brightness: unable to open file: %s', str(e)) + return False + minoralarm_value = val_file.readline().rstrip() + val_file.close() + + if (majoralarm_value == str(1)) and (minoralarm_value == str(0)): + content = 2 + elif (majoralarm_value == str(0)) and (minoralarm_value == str(1)): + content = 1 + elif (majoralarm_value == str(0)) and (minoralarm_value == str(0)): + content = 0 + else: + pass + + return int(content) + + def set_alarm_led_brightness(self, val): + + """ Major Alarm set""" + if val == 2: + major_alarm_val = 1 + minor_alarm_val = 0 + + try: + val_file = open(self.MAJORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + + val_file.write(str(major_alarm_val)) + val_file.close() + + try: + val_file = open(self.MINORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + + val_file.write(str(minor_alarm_val)) + val_file.close() + + elif val == 1: + major_alarm_val = 0 + minor_alarm_val = 1 + + try: + val_file = open(self.MAJORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + + val_file.write(str(major_alarm_val)) + val_file.close() + + try: + val_file = open(self.MINORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + val_file.write(str(minor_alarm_val)) + val_file.close() + + else: + major_alarm_val = 0 + minor_alarm_val = 0 + + try: + val_file = open(self.MAJORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + + val_file.write(str(major_alarm_val)) + val_file.close() + + try: + val_file = open(self.MINORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + val_file.write(str(minor_alarm_val)) + val_file.close() + + """ Function is called periodically every 20 secs. It reads the 10 Temp sensors, 1 core Temp sensor and ASIC temp sets + Sensor flags accordingly. Also reads the Fan duty cycle and depending on the FAN duty cycle reading and temp sensor reading, + set the different parameters """ + def getSensorTemp(self): + global isPlatformAFI + global is35PerFlag + global is55PerFlag + global is75PerFlag + global is90PerFlag + global isFireThresholdReached + global FireThresholdSecsRemaining + global isFireThresholdPrint + global PrevASICValue + #AFI + if (isPlatformAFI == True): + temp_policy = temp_policy_AFI + else: + #AFO + temp_policy = temp_policy_AFO + + """ Dictionary where + key = thermal id index starting from 0. 0 is the sensor 1 ... + value = Different temp ranges """ + SensorFlag = { + 0: [0,0,0,0,0,0,0,0,0,0,0,0], + 1: [0,0,0,0,0,0,0,0,0,0,0,0], + 2: [0,0,0,0,0,0,0,0,0,0,0,0], + 3: [0,0,0,0,0,0,0,0,0,0,0,0], + 4: [0,0,0,0,0,0,0,0,0,0,0,0], + 5: [0,0,0,0,0,0,0,0,0,0,0,0], + 6: [0,0,0,0,0,0,0,0,0,0,0,0], + 7: [0,0,0,0,0,0,0,0,0,0,0,0], + 8: [0,0,0,0,0,0,0,0,0,0,0,0], + 9: [0,0,0,0,0,0,0,0,0,0,0,0], + 10: [0,0,0,0,0,0,0,0,0,0,0,0], + 11: [0,0,0,0,0,0,0,0,0,0,0,0], + } + # if the Firethreshold Flag is set and 120 seconds have elapsed, invoking the "poweroff" to shutdown the box + if (isFireThresholdReached == True): + firethr = FireThresholdSecsRemaining - 20 + if firethr == 0: + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown now') + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown now' > /dev/console") + else: + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds', firethr) + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds' > /dev/console" % firethr) + + FireThresholdSecsRemaining = FireThresholdSecsRemaining - 20 + logging.critical('CRITICAL: Value of FireThresholdSecsRemaining %s seconds', FireThresholdSecsRemaining) + + if (FireThresholdSecsRemaining == 0): + isFireThresholdReached == False + time.sleep(20) + cmd = "poweroff" + os.system(cmd) + + for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): + if x < self.SENSOR_NUM_ON_MAIN_BOARD: + value = self._get_sensor_node_val(x) + logging.debug('Sensor value %d : %s', x, value) + elif x == self.CORETEMP_INDEX_ON_MAIN_BOARD: + value = self.get_coretempValue() + logging.debug('Main Board CORE temp: %s', value) + else: + logging.debug('Reading ASIC Temp value using bcmcmd') + proc = subprocess.Popen("bcmcmd \"show temp\" | grep \"maximum peak temperature\" | awk '{ print $5 }' > /var/log/asic_value 2>&1 & ",shell=True) + time.sleep(2) + cmd = "kill -9 %s"%(proc.pid) + commands.getstatusoutput(cmd) + + if os.stat("/var/log/asic_value").st_size == 0: + value = PrevASICValue + logging.debug('No ASIC Temp file, Prev ASIC Temp Value: %s', PrevASICValue) + else: + with open('/var/log/asic_value', 'r') as f: + value1 = f.readline() + value2 = float(value1) + value1 = value2 * 1000 + value = int(value1) + PrevASICValue = value + logging.debug('Reading from ASIC Temp file: %s', value) + logging.debug('Reading from Prev ASIC Temp Value: %s', PrevASICValue) + + os.system('rm /var/log/asic_value') + + # 35% Duty Cycle + if value > temp_policy[x][0][1] and value <= temp_policy[x][0][2]: + SensorFlag[x][0] = True + + # 35% Prev Duty Cycle + elif value > temp_policy[x][1][1] and value < temp_policy[x][1][2]: + SensorFlag[x][1] = True + + # 55% Duty Cycle + elif value == temp_policy[x][2][1]: + SensorFlag[x][2] = True + + # 55% Prev Duty Cycle + elif value > temp_policy[x][3][1] and value < temp_policy[x][3][2]: + SensorFlag[x][3] = True + + # 75% Duty Cycle + elif value == temp_policy[x][4][1]: + SensorFlag[x][4] = True + + # 75% Prev Duty Cycle + elif value > temp_policy[x][5][1] and value < temp_policy[x][5][2]: + SensorFlag[x][5] = True + + # 90% Duty Cycle + elif value == temp_policy[x][6][1]: + SensorFlag[x][6] = True + + # 90% Prev Duty Cycle + elif value > temp_policy[x][7][1] and value < temp_policy[x][7][2]: + SensorFlag[x][7] = True + + #100% Duty Cycle + elif value >= temp_policy[x][8][1]: + SensorFlag[x][8] = True + + else: + pass + + # Yellow Alarm + if value >= temp_policy[x][9][1] and value < temp_policy[x][9][2]: + SensorFlag[x][9] = True + + # Red Alarm + elif value >= temp_policy[x][10][1] and value < temp_policy[x][10][2]: + SensorFlag[x][10] = True + + # Fire Shut down + elif value >= temp_policy[x][11][1]: + SensorFlag[x][11] = True + + fan = QFX5200_FanUtil() + # CHECK IF ANY TEMPERATURE SENSORS HAS SET FIRE SHUTDOWN FLAG + if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] + or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): + + isFireThresholdReached = True + + if (isFireThresholdPrint == True): + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds') + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds' > /dev/console") + isFireThresholdPrint = False + + logging.debug('Temp Sensor is set to FIRE SHUTDOWN Flag') + fan.set_fan_duty_cycle(100) + self.set_alarm_led_brightness(2) + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 'RED' ALARM FLAG, IF YES, SET THE ALARM LED TO 'RED' + elif (SensorFlag[0][10] or SensorFlag[1][10] or SensorFlag[2][10] or SensorFlag[3][10] or SensorFlag[4][10] or SensorFlag[5][10] or SensorFlag[6][10] or SensorFlag[7][10] + or SensorFlag[8][10] or SensorFlag[9][10] or SensorFlag[10][10] or SensorFlag[11][10]): + + fan.set_fan_duty_cycle(100) + self.set_alarm_led_brightness(2) + logging.debug('Temp Sensor is set to Red Alarm Flag') + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 'YELLOW' ALARM FLAG, IF YES, SET THE ALARM LED TO 'YELLOW' + elif (SensorFlag[0][9] or SensorFlag[1][9] or SensorFlag[2][9] or SensorFlag[3][9] or SensorFlag[4][9] or SensorFlag[5][9] or SensorFlag[6][9] or SensorFlag[7][9] + or SensorFlag[8][9] or SensorFlag[9][9] or SensorFlag[10][9] or SensorFlag[11][9]): + + fan.set_fan_duty_cycle(100) + self.set_alarm_led_brightness(1) + logging.debug('Temp Sensor is set to Yellow Alarm Flag') + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + #CHECK IF ANY TEMPERATURE SENSORS HAS SET 100% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 100% + elif (SensorFlag[0][8] or SensorFlag[1][8] or SensorFlag[2][8] or SensorFlag[3][8] or SensorFlag[4][8] or SensorFlag[5][8] or SensorFlag[6][8] or SensorFlag[7][8] + or SensorFlag[8][8] or SensorFlag[9][8] or SensorFlag[10][8] or SensorFlag[11][8]): + + if (fan.get_fan_duty_cycle < 100): + fan.set_fan_duty_cycle(100) + elif (fan.get_fan_duty_cycle == 100): + pass + else: + pass + + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + logging.debug('Temp Sensor is set to 100% Duty Cycle Flag') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 90% PREV DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 90% + elif (SensorFlag[0][7] or SensorFlag[1][7] or SensorFlag[2][7] or SensorFlag[3][7] or SensorFlag[4][7] or SensorFlag[5][7] or SensorFlag[6][7] or SensorFlag[7][7] + or SensorFlag[8][7] or SensorFlag[9][7] or SensorFlag[10][7] or SensorFlag[11][7]): + + if (is90PerFlag == True): + fan.set_fan_duty_cycle(90) + is90PerFlag = False + else: + pass + + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + + logging.debug('Temp Sensor is set to 90% Prev Duty Cycle Flag') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 90% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 90% + elif (SensorFlag[0][6] or SensorFlag[1][6] or SensorFlag[2][6] or SensorFlag[3][6] or SensorFlag[4][6] or SensorFlag[5][6] or SensorFlag[6][6] or SensorFlag[7][6] + or SensorFlag[8][6] or SensorFlag[9][6] or SensorFlag[10][6] or SensorFlag[11][6]): + + if (fan.get_fan_duty_cycle < 90): + fan.set_fan_duty_cycle(90) + elif (fan.get_fan_duty_cycle > 90): + if (SensorFlag[0][6] and SensorFlag[1][6] and SensorFlag[2][6] and SensorFlag[3][6] and SensorFlag[4][6] and SensorFlag[5][6] and SensorFlag[6][6] and SensorFlag[7][6] + and SensorFlag[8][6] and SensorFlag[9][6] and SensorFlag[10][6] and SensorFlag[11][6]): + + fan.set_fan_duty_cycle(90) + else: + pass + + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + is90PerFlag = True + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + logging.debug('Temp Sensor is set to 90% Duty Cycle Flag') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 75% PREV DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 75% + elif (SensorFlag[0][5] or SensorFlag[1][5] or SensorFlag[2][5] or SensorFlag[3][5] or SensorFlag[4][5] or SensorFlag[5][5] or SensorFlag[6][5] or SensorFlag[7][5] + or SensorFlag[8][5] or SensorFlag[9][5] or SensorFlag[10][5] or SensorFlag[11][5]): + + if (is75PerFlag == True): + fan.set_fan_duty_cycle(75) + is75PerFlag = False + else: + pass + + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + logging.debug('Temp Sensor is set to 75% Prev Duty Cycle Flag') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 75% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 75% + elif (SensorFlag[0][4] or SensorFlag[1][4] or SensorFlag[2][4] or SensorFlag[3][4] or SensorFlag[4][4] or SensorFlag[5][4] or SensorFlag[6][4] or SensorFlag[7][4] + or SensorFlag[8][4] or SensorFlag[9][4] or SensorFlag[10][4] or SensorFlag[11][4]): + + if (fan.get_fan_duty_cycle < 75): + fan.set_fan_duty_cycle(75) + elif (fan.get_fan_duty_cycle > 75): + if (SensorFlag[0][4] and SensorFlag[1][4] and SensorFlag[2][4] and SensorFlag[3][4] and SensorFlag[4][4] and SensorFlag[5][4] and SensorFlag[6][4] and SensorFlag[7][4] + and SensorFlag[8][4] and SensorFlag[9][4] and SensorFlag[10][4] and SensorFlag[11][4]): + + fan.set_fan_duty_cycle(75) + else: + pass + + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + is75PerFlag = True + + logging.debug('Temp Sensor is set to 75% Duty Cycle Flag') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 55% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 55% + elif (SensorFlag[0][3] or SensorFlag[1][3] or SensorFlag[2][3] or SensorFlag[3][3] or SensorFlag[4][3] or SensorFlag[5][3] or SensorFlag[6][3] or SensorFlag[7][3] + or SensorFlag[8][3] or SensorFlag[9][3] or SensorFlag[10][3] or SensorFlag[11][3]): + + if (is55PerFlag == True): + fan.set_fan_duty_cycle(55) + is55PerFlag = False + else: + pass + + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + logging.debug('Temp Sensor is set to 55% Prev Duty Cycle Flag') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 55% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 55% + elif (SensorFlag[0][2] or SensorFlag[1][2] or SensorFlag[2][2] or SensorFlag[3][2] or SensorFlag[4][2] or SensorFlag[5][2] or SensorFlag[6][2] or SensorFlag[7][2] + or SensorFlag[8][2] or SensorFlag[9][2] or SensorFlag[10][2] or SensorFlag[11][2]): + if (fan.get_fan_duty_cycle < 55): + fan.set_fan_duty_cycle(55) + elif (fan.get_fan_duty_cycle > 55): + if (SensorFlag[0][2] and SensorFlag[1][2] and SensorFlag[2][2] and SensorFlag[3][2] and SensorFlag[4][2] and SensorFlag[5][2] and SensorFlag[6][2] and SensorFlag[7][2] + and SensorFlag[8][6] and SensorFlag[9][6] and SensorFlag[10][6] and SensorFlag[11][6]): + + fan.set_fan_duty_cycle(55) + else: + pass + + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + is55PerFlag = True + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + logging.debug('Temp Sensor is set to 55% Duty Cycle Flag') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 35% PREV DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 35% + elif (SensorFlag[0][1] or SensorFlag[1][1] or SensorFlag[2][1] or SensorFlag[3][1] or SensorFlag[4][1] or SensorFlag[5][1] or SensorFlag[6][1] or SensorFlag[7][1] + or SensorFlag[8][1] or SensorFlag[9][1] or SensorFlag[10][1] or SensorFlag[11][1]): + + if (is35PerFlag == True): + fan.set_fan_duty_cycle(35) + is35PerFlag = False + else: + pass + + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + logging.debug('Temp Sensor is set to 35% Prev Duty Cycle Flag') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 35% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 35% + elif (SensorFlag[0][0] or SensorFlag[1][0] or SensorFlag[2][0] or SensorFlag[3][0] or SensorFlag[4][0] or SensorFlag[5][0] or SensorFlag[6][0] or SensorFlag[7][0] + or SensorFlag[8][0] or SensorFlag[9][0] or SensorFlag[10][0] or SensorFlag[11][0]): + + if (fan.get_fan_duty_cycle == 35): + fan.set_fan_duty_cycle(35) + elif (fan.get_fan_duty_cycle > 35): + if (SensorFlag[0][0] and SensorFlag[1][0] and SensorFlag[2][0] and SensorFlag[3][0] and SensorFlag[4][0] and SensorFlag[5][0] and SensorFlag[6][0] and SensorFlag[7][0] + and SensorFlag[8][0] and SensorFlag[9][0] and SensorFlag[10][0] and SensorFlag[11][0]): + fan.set_fan_duty_cycle(35) + else: + pass + + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + is35PerFlag = True + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + logging.debug('Temp Sensor is set to 35% Duty Cycle Flag') + + else: + pass + + + # RESET ALL THE SENSOR FLAGS + for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): + for y in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): + SensorFlag[x][y] = 0 + +class device_monitor(object): + + MASTER_LED_PATH = '/sys/class/leds/master/brightness' + SYSTEM_LED_PATH = '/sys/class/leds/system/brightness' + + PWMINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/{1}/pwm{2}' + HWMONINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/' + PWMINPUT_NUM = 10 + _pwm_input_path_mapping = {} + _hwmon_input_path_mapping = {} + + # PWM NUMBERS + _pwm_input_node_mapping = ['1','2','3','4','1','2','3','4','1','2'] + + # I2C NUMBERS + _hwmon_input_node_mapping = ['2c','2c','2c','2c','2e','2e','2e','2e','2f','2f'] + + def __init__(self, log_file, log_level): + global DEBUG + global isPlatformAFI + + hwmoninput_path = self.HWMONINPUT_PATH + pwminput_path = self.PWMINPUT_PATH + for x in range(self.PWMINPUT_NUM): + self._hwmon_input_path_mapping[x] = hwmoninput_path.format( + self._hwmon_input_node_mapping[x]) + + hwmon_path = os.listdir(self._hwmon_input_path_mapping[x]) + hwmon_dir = '' + for hwmon_name in hwmon_path: + hwmon_dir = hwmon_name + + self._pwm_input_path_mapping[x] = pwminput_path.format( + self._hwmon_input_node_mapping[x], + hwmon_dir, + self._pwm_input_node_mapping[x]) + + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + if DEBUG == True: + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + filename = "/var/run/eeprom" + AFO_str = "AFO" + pattern = re.compile(r"Fan Type", re.IGNORECASE) + with open(filename, "rt") as myfile: + for line in myfile: + if pattern.search(line) != None: + fan_type = str(line) + if "=" in fan_type: + user=fan_type[fan_type.find("=")+1:].split()[0] + if user == AFO_str: + isPlatformAFI = False + else: + isPlatformAFI = True + + master_led_value = 1 + + try: + masterLED_file = open(self.MASTER_LED_PATH, 'r+') + except IOError as e: + logging.error('device_monitor: unable to open Master LED file: %s', str(e)) + + masterLED_file.write(str(master_led_value)) + masterLED_file.close() + + system_led_value = 1 + + try: + systemLED_file = open(self.SYSTEM_LED_PATH, 'r+') + except IOError as e: + logging.error('device_monitor: unable to open System LED file: %s', str(e)) + + systemLED_file.write(str(system_led_value)) + systemLED_file.close() + self.set_DefaultFAN_duty_cycle(35) + + + def set_DefaultFAN_duty_cycle(self, val): + fan_speed = {35: 86, 55: 139, 75: 192, 90: 230,100: 255} + for x in range(self.PWMINPUT_NUM): + device_path = self._pwm_input_path_mapping[x] + pwm_value = fan_speed.get(val) + pwm_value1 = str(pwm_value) + time.sleep(1) + cmd = ("sudo echo %s > %s" %(pwm_value1,device_path)) + os.system(cmd) + + return True + + def manage_device(self): + thermal = QFX5200_ThermalUtil() + thermal.getSensorTemp() + +def main(): + #Introducing sleep of 150 seconds to wait for all the docker containers to start before starting the EM policy. + time.sleep(150) + monitor = device_monitor(log_file, log_level) + while True: + monitor.manage_device() + time.sleep(20) + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py new file mode 100755 index 000000000000..d97982d1fec0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python +# +# Description: This file contains the Juniper QFX5200 Platform Initialization routines +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os +import commands +import sys +import logging +import time + +PROJECT_NAME = 'QFX5200-32C' +verbose = False +DEBUG = False +FORCE = 0 + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + +i2c_prefix = '/sys/bus/i2c/devices/' + +kos = [ +'modprobe i2c-mux', +'modprobe mfd-core', +'modprobe tmp401', +'modprobe ads7828', +'modprobe jnx-tmc-core', +'modprobe leds-jnx-tmc', +'modprobe jnx-refpga-tmc', +'modprobe adt7470', +'modprobe i2c-tmc', +'modprobe gpio-tmc', +'modprobe jnx-tmc-psu', +'modprobe jnx-psu-monitor', +'modprobe jnx-refpga-lpcm' +] + +mknod =[ +'echo tmp435 0x48 > /sys/bus/i2c/devices/i2c-5/new_device', +'echo tmp435 0x49 > /sys/bus/i2c/devices/i2c-5/new_device', +'echo tmp435 0x4A > /sys/bus/i2c/devices/i2c-5/new_device', +'echo tmp435 0x4B > /sys/bus/i2c/devices/i2c-5/new_device', +'echo tmp435 0x48 > /sys/bus/i2c/devices/i2c-6/new_device', +'echo tmp435 0x49 > /sys/bus/i2c/devices/i2c-6/new_device', +'echo tmp435 0x4A > /sys/bus/i2c/devices/i2c-6/new_device', +'echo tmp435 0x4B > /sys/bus/i2c/devices/i2c-6/new_device', +'echo tmp435 0x48 > /sys/bus/i2c/devices/i2c-7/new_device', +'echo tmp435 0x49 > /sys/bus/i2c/devices/i2c-7/new_device', +'echo adt7470 0x2C > /sys/bus/i2c/devices/i2c-7/new_device', +'echo adt7470 0x2E > /sys/bus/i2c/devices/i2c-7/new_device', +'echo adt7470 0x2F > /sys/bus/i2c/devices/i2c-7/new_device', +'echo ads7830 0x4A > /sys/bus/i2c/devices/i2c-2/new_device', +'echo jpsu 0x58 > /sys/bus/i2c/devices/i2c-3/new_device', +'echo jpsu 0x58 > /sys/bus/i2c/devices/i2c-4/new_device', +] + +def my_log(txt): + if DEBUG == True: + print txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_install(): + global FORCE + log_os_system("depmod", 1) + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + time.sleep(2) + if status: + if FORCE == 0: + return status + return 0 + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"5-0049", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"7-002c", 0) + + return not(ret1 or ret2) + +def device_install(): + global FORCE + for i in range(0,len(mknod)): + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + +def do_install(): + status = driver_install() + if status: + if FORCE == 0: + return status + + if not device_exist(): + logging.info('No device, installing....') + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def main(): + + # Enabling REFPGA + EnableREFFGACmd = 'busybox devmem 0xFED50011 8 0x53' + try: + os.system(EnableREFFGACmd) + except OSError: + print 'Error: Execution of "%s" failed', EnableREFFGACmd + return False + + time.sleep(2) + + # Create CPU Board EEPROM device + CreateEEPROMdeviceCmd = 'sudo echo 24c02 0x51 > /sys/bus/i2c/devices/i2c-0/new_device' + try: + os.system(CreateEEPROMdeviceCmd) + except OSError: + print 'Error: Execution of "%s" failed', CreateEEPROMdeviceCmd + return False + + time.sleep(1) + + #Retrieve the Base MAC Address from EEPROM + status, macAddress = commands.getstatusoutput("decode-syseeprom -m 0x24") + if status: + print 'Error: Could not retrieve BASE MAC Address from EEPROM' + return False + + #Make eth0 interface down + status, eth0Down = commands.getstatusoutput("ifconfig eth0 down") + if status: + print 'Error: Could not make eth0 interface down' + return False + + #Assign BASE MAC ADDRESS retieved from CPU board EEPROM to eth0 interface + mac_address_prog = "ifconfig eth0 hw ether " + str(macAddress) + + status, MACAddressProg = commands.getstatusoutput(mac_address_prog) + if status: + print 'Error: Could not set up "macAddress" for eth0 interface' + return False + + #Make eth0 interface up + status, eth0UP = commands.getstatusoutput("ifconfig eth0 up") + if status: + print 'Error: Could not make eth0 interface up' + return False + + # Juniper QFX5200 platform drivers install + do_install() + time.sleep(2) + + # Juniper SFP Intialization + JuniperSFPInitCmd = 'python /usr/share/sonic/device/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py' + try: + os.system(JuniperSFPInitCmd) + except OSError: + print 'Error: Execution of "%s" failed', JuniperSFPInitCmd + return False + + time.sleep(1) + # Invoking the script which retrieves the data from CPU Board and Main Board EEPROM and storing in file + EEPROMDataCmd = 'python /usr/share/sonic/device/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py' + try: + os.system(EEPROMDataCmd) + except OSError: + print 'Error: Execution of "%s" failed', EEPROMDataCmd + return False + + return True + +if __name__ == "__main__": + main() From 358d93eeb56e66f6b4fd089ad3ddee0dfc7cdc66 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sun, 2 Feb 2020 20:03:34 +0000 Subject: [PATCH 0531/1427] [sonic-slave-buster]: build sonic-slave-buster docker - add sonic-slave-buster docker - remove debhelper from buster backports debhelper in buster is enough to build smartmontools 6.6 Signed-off-by: Guohan Lu --- Makefile | 3 + Makefile.work | 5 +- sonic-slave-buster/Dockerfile.j2 | 409 ++++++++++++++++++++ sonic-slave-buster/Dockerfile.user | 30 ++ sonic-slave-buster/no-check-valid-until | 4 + sonic-slave-buster/sonic-jenkins-id_rsa.pub | 1 + 6 files changed, 451 insertions(+), 1 deletion(-) create mode 100644 sonic-slave-buster/Dockerfile.j2 create mode 100644 sonic-slave-buster/Dockerfile.user create mode 100644 sonic-slave-buster/no-check-valid-until create mode 100644 sonic-slave-buster/sonic-jenkins-id_rsa.pub diff --git a/Makefile b/Makefile index 13a3f247fc31..43e2b4d527f1 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,9 @@ ifeq ($(NOJESSIE), 0) make -f Makefile.work jessie endif +buster: + BLDENV=buster make -f Makefile.work + clean reset init configure showtag sonic-slave-build sonic-slave-bash : @echo "+++ Making $@ +++" ifeq ($(NOJESSIE), 0) diff --git a/Makefile.work b/Makefile.work index e36166472422..f39c5b27e3e1 100644 --- a/Makefile.work +++ b/Makefile.work @@ -76,11 +76,14 @@ ifeq ($(PLATFORM_ARCH),) override PLATFORM_ARCH = $(CONFIGURED_ARCH) endif -ifeq ($(BLDENV), stretch) +ifeq ($(BLDENV), buster) +SLAVE_DIR = sonic-slave-buster +else ifeq ($(BLDENV), stretch) SLAVE_DIR = sonic-slave-stretch else SLAVE_DIR = sonic-slave-jessie endif + SLAVE_BASE_TAG = $(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) j2 $(SLAVE_DIR)/Dockerfile.j2 > $(SLAVE_DIR)/Dockerfile && sha1sum $(SLAVE_DIR)/Dockerfile | awk '{print substr($$1,0,11);}') SLAVE_TAG = $(shell cat $(SLAVE_DIR)/Dockerfile.user $(SLAVE_DIR)/Dockerfile | sha1sum | awk '{print substr($$1,0,11);}') SLAVE_BASE_IMAGE = $(SLAVE_DIR) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 new file mode 100644 index 000000000000..c010a4980438 --- /dev/null +++ b/sonic-slave-buster/Dockerfile.j2 @@ -0,0 +1,409 @@ +{%- if CONFIGURED_ARCH == "armhf" %} +FROM multiarch/debian-debootstrap:armhf-buster +{%- elif CONFIGURED_ARCH == "arm64" %} +FROM multiarch/debian-debootstrap:arm64-buster +{%- else -%} +FROM debian:buster +{%- endif %} + +MAINTAINER gulv@microsoft.com + +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d/"] + +RUN echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian buster-backports main" >> /etc/apt/sources.list + +{%- if CONFIGURED_ARCH == "armhf" %} +RUN echo "deb [arch=armhf] http://deb.debian.org/debian buster main contrib non-free" > /etc/apt/sources.list && \ + echo "deb-src [arch=armhf] http://deb.debian.org/debian buster main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=armhf] http://security.debian.org buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=armhf] http://security.debian.org buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo 'deb [arch=armhf] http://ftp.debian.org/debian buster-backports main' >> /etc/apt/sources.list +{%- elif CONFIGURED_ARCH == "arm64" %} +RUN echo "deb [arch=arm64] http://deb.debian.org/debian buster main contrib non-free" > /etc/apt/sources.list && \ + echo "deb-src [arch=arm64] http://deb.debian.org/debian buster main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=arm64] http://security.debian.org buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=arm64] http://security.debian.org buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo 'deb [arch=arm64] http://ftp.debian.org/debian buster-backports main' >> /etc/apt/sources.list +{%- endif %} + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y \ + apt-utils \ + default-jre-headless \ + openssh-server \ + curl \ + wget \ + unzip \ + git \ + build-essential \ + libtool \ + lintian \ + sudo \ + dh-make \ + dh-exec \ + kmod \ + libtinyxml2-6a \ + libboost-program-options1.67-dev \ + libtinyxml2-dev \ + python \ + python-pip \ + libncurses5-dev \ + texinfo \ + dh-autoreconf \ + python3-pip \ + doxygen \ + devscripts \ + git-buildpackage \ + perl-modules \ + libswitch-perl \ + dh-systemd \ +# For quagga build + libreadline-dev \ + texlive-latex-base \ + texlive-generic-recommended \ + texlive-fonts-recommended \ + libpam0g-dev \ + libpam-dev \ + libcap-dev \ + imagemagick \ + ghostscript \ + groff \ + libpcre3-dev \ + gawk \ + chrpath \ +# For frr build + libc-ares-dev \ + libsnmp-dev \ + libjson-c3 \ + libjson-c-dev \ + libsystemd-dev \ + python-ipaddr \ + libcmocka-dev \ + python3-all-dev \ + python3-all-dbg \ + install-info \ + logrotate \ +# For libnl3 (local) build + cdbs \ +# For SAI meta build + libxml-simple-perl \ + graphviz \ + aspell \ +# For linux build + bc \ + fakeroot \ + build-essential \ + devscripts \ + quilt \ + stgit \ +# For platform-modules build + module-assistant \ +# For thrift build\ + gem2deb \ + libboost-all-dev \ + libevent-dev \ + libglib2.0-dev \ + libqt4-dev \ + python-all-dev \ + python-twisted \ + phpunit \ + libbit-vector-perl \ + openjdk-11-jdk \ + javahelper \ + maven-debian-helper \ + ant \ + libhttpclient-java \ + libslf4j-java \ + libservlet3.1-java \ + qt5-default \ + pkg-php-tools \ +# For mellanox sdk build + libpcre3 \ + libpcre3-dev \ + byacc \ + flex \ + libglib2.0-dev \ + bison \ + expat \ + libexpat1-dev \ + dpatch \ + libdb-dev \ + iptables-dev \ + ctags \ +# For mellanox sai build + libtool-bin \ + libxml2-dev \ +# For BFN sdk build + libusb-1.0-0-dev \ + libcurl3-nss-dev \ + libunwind8-dev \ + telnet \ + libc-ares2 \ + libgoogle-perftools4 \ +# For build image + cpio \ + squashfs-tools \ + zip \ +# For broadcom sdk build +{%- if CONFIGURED_ARCH == "amd64" %} + linux-compiler-gcc-8-x86 \ +{%- endif %} +{%- if CONFIGURED_ARCH == "armhf" %} + linux-compiler-gcc-8-arm \ +{%- endif %} + linux-kbuild-4.19 \ +# teamd build + libdaemon-dev \ + libdbus-1-dev \ + libjansson-dev \ +# For cavium sdk build + libpcap-dev \ + dnsutils \ + libusb-dev \ +# For debian image reconfiguration + augeas-tools \ +# For p4 build + libyaml-dev \ + libevent-dev \ + libjudy-dev \ + libedit-dev \ + libnanomsg-dev \ + python-stdeb \ +# For redis build + libjemalloc-dev \ + liblua5.1-0-dev \ + lua-bitop-dev \ + lua-cjson-dev \ +# For mft kernel module build + dkms \ +# For python3.5 build + sharutils \ + libncursesw5-dev \ + libbz2-dev \ + liblzma-dev \ + libgdbm-dev \ + tk-dev \ + blt-dev \ + libmpdec-dev \ + libbluetooth-dev \ + locales \ + libsqlite3-dev \ + libgpm2 \ + time \ + net-tools \ + xvfb \ + python-sphinx \ + python3-sphinx \ +# For Jenkins static analysis, unit testing and code coverage + cppcheck \ + clang \ + pylint \ + python-pytest \ + gcovr \ + python-pytest-cov \ + python-parse \ +# For snmpd + default-libmysqlclient-dev \ + libssl-dev \ + libperl-dev \ + libpci-dev \ + libpci3 \ + libsensors5 \ + libsensors4-dev \ + libwrap0-dev \ +# For lldpd + debhelper \ + autotools-dev \ + libbsd-dev \ + pkg-config \ + check \ +# For mpdecimal + docutils-common \ + libjs-sphinxdoc \ + libjs-underscore \ + python-docutils \ + python-jinja2 \ + python-markupsafe \ + python-pygments \ + python-roman \ + python-sphinx \ + sphinx-common \ + python3-sphinx \ +# For sonic config engine testing + python-lxml \ + python-jinja2 \ + python-netaddr \ + python-ipaddr \ + python-yaml \ + python3-yaml \ +# For lockfile + procmail \ +# For gtest + libgtest-dev \ + cmake \ +# For pam_tacplus build + autoconf-archive \ +# For iproute2 + cm-super-minimal \ + libatm1-dev \ + libelf-dev \ + libmnl-dev \ + libselinux1-dev \ + linuxdoc-tools \ + lynx \ + texlive-latex-extra \ + texlive-latex-recommended \ + iproute2 \ +# For python-click build + python-sphinx \ + python-docutils \ + python3-all \ + python3-setuptools \ + python3-sphinx \ + python3-docutils \ + python3-requests \ + python3-pytest \ + python3-colorama \ +# For bash + texi2html \ +# For initramfs + bash-completion \ +{%- if CONFIGURED_ARCH == "amd64" %} +# For sonic vs image build + dosfstools \ + qemu-kvm \ + libvirt-clients \ +{%- endif %} +# For lm-sensors + librrd8 \ + librrd-dev \ + rrdtool \ +# For smartmontools 6.6-1 + automake1.11 \ + libselinux1-dev \ +# For kdump-tools + liblzo2-dev \ +# For iptables + libnetfilter-conntrack-dev \ + libnftnl-dev \ +# For SAI3.7 + libprotobuf-dev \ +# For DHCP Monitor tool + libexplain-dev \ + libevent-dev + +## Config dpkg +## install the configuration file if it’s currently missing +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confmiss" +## combined with confold: overwrite configuration files that you have not modified +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confdef" +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confold" + +# For linux build +RUN apt-get -y build-dep linux + +# For gobgp and telemetry build +RUN export VERSION=1.11.5 \ +{%- if CONFIGURED_ARCH == "armhf" %} + && wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \ + && tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \ +{%- elif CONFIGURED_ARCH == "arm64" %} + && wget https://storage.googleapis.com/golang/go$VERSION.linux-arm64.tar.gz \ + && tar -C /usr/local -xzf go$VERSION.linux-arm64.tar.gz \ +{%- else %} + && wget https://storage.googleapis.com/golang/go$VERSION.linux-amd64.tar.gz \ + && tar -C /usr/local -xzf go$VERSION.linux-amd64.tar.gz \ +{%- endif %} + && echo 'export GOROOT=/usr/local/go' >> /etc/bash.bashrc \ + && echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/bash.bashrc \ + && rm go$VERSION.linux-*.tar.gz + +# For p4 build +RUN pip install \ + ctypesgen==0.r125 \ + crc16 + +# For sonic config engine testing +RUN pip install pyangbind==0.6.0 +# Note: force upgrade debian packaged jinja2, if installed +RUN pip install --force-reinstall --upgrade "jinja2>=2.10" + +# For templating +RUN pip install j2cli==0.3.10 + +# Remove python-click 6.6 +RUN apt-get purge -y python-click +# For sonic utilities testing +RUN pip install click-default-group click natsort tabulate netifaces==0.10.7 fastentrypoints + +# For sonic snmpagent mock testing +RUN pip3 install mockredispy==2.9.3 + +RUN pip3 install "PyYAML>=5.1" + +# For sonic-platform-common testing +RUN pip3 install redis + +# For supervisor build +RUN pip install meld3 mock + +# For vs image build +RUN pip install pexpect==4.6.0 + +# For sonic-utilities build +RUN pip install mockredispy==2.9.3 +RUN pip install pytest-runner==4.4 +RUN pip install setuptools==40.8.0 + +# For mgmt-framework build +RUN pip install mmh3 + +# Install dependencies for isc-dhcp-relay build +RUN apt-get -y build-dep isc-dhcp + +# Install vim +RUN apt-get install -y vim + +# Install rsyslog +RUN apt-get install -y rsyslog + +RUN cd /usr/src/gtest && cmake . && make -C /usr/src/gtest + +RUN mkdir /var/run/sshd +EXPOSE 22 + +# Install depot-tools (for git-retry) +RUN git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git /usr/share/depot_tools +ENV PATH /usr/share/depot_tools:$PATH + +# Install docker engine 17.03.2~ce-0 inside docker and enable experimental feature +RUN apt-get update +RUN apt-get install -y \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg2 \ + software-properties-common +RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - +RUN add-apt-repository \ + "deb [arch={{ CONFIGURED_ARCH }}] https://download.docker.com/linux/debian \ + $(lsb_release -cs) \ + stable" +RUN apt-get update +{%- if CONFIGURED_ARCH == "amd64" %} +RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-buster +{%- else %} +RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian +{%- endif %} +RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker diff --git a/sonic-slave-buster/Dockerfile.user b/sonic-slave-buster/Dockerfile.user new file mode 100644 index 000000000000..e292a8a6776a --- /dev/null +++ b/sonic-slave-buster/Dockerfile.user @@ -0,0 +1,30 @@ +ARG slave_base_tag_ref=latest +FROM sonic-slave-buster:${slave_base_tag_ref} + +# Add user +ARG user +ARG uid +ARG guid +ARG hostname + +ENV BUILD_HOSTNAME $hostname +ENV USER $user + +RUN groupadd -f -r -g $guid g$user + +RUN useradd $user -l -u $uid -g $guid -d /var/$user -m -s /bin/bash + +RUN gpasswd -a $user docker + +# Config git for stg +RUN su $user -c "git config --global user.name $user" +RUN su $user -c "git config --global user.email $user@contoso.com" + +COPY sonic-jenkins-id_rsa.pub /var/$user/.ssh/authorized_keys2 +RUN chown $user /var/$user/.ssh -R +RUN chmod go= /var/$user/.ssh -R + +# Add user to sudoers +RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers + +USER $user diff --git a/sonic-slave-buster/no-check-valid-until b/sonic-slave-buster/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/sonic-slave-buster/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/sonic-slave-buster/sonic-jenkins-id_rsa.pub b/sonic-slave-buster/sonic-jenkins-id_rsa.pub new file mode 100644 index 000000000000..2a19c9e70d3c --- /dev/null +++ b/sonic-slave-buster/sonic-jenkins-id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC769BQUJVeSIOyPsN4/Vo8xTqXQ6RI7ysVyCw/ABP3FIxf+fxmtm8t/Nbp9hq0uLHOjCw8UQbJ+XltsThFWJfH6RJY5NbfvwG7nUDjfjjp+SGEIHaVgIlpiuqiPbZ6QMjZ8Q0Sgi5p5ts1xe/4TFThwOJBHmhwydD5nk3BH7P3DDwlOCov5gjM40uMZJkketlO83zGG+25zu7O0hfDVt1vyK9bNWAhhPmGc79zdetfeFCxjimsff2m31B1KuVXiT5PDB1w+BSrUK6nNzJubnYCRgjg4prVTjA50EhlT2P7EoJAbW3TnTq8vUDkcstsGe/HZpfIB1VHBX97u4fAfGJZ root@acs-jenkins From 01cb7934b0cbfbf9f218e96c0d40386d5b4aa2ca Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sun, 2 Feb 2020 20:04:18 +0000 Subject: [PATCH 0532/1427] [build]: add buster docker as the last step of the build proces - build SONIC_STRETCH_DOCKERS in sonic-slave-stretch docker - build image related module in sonic-slave-buster docker. This includes all kernels modules and some packages Signed-off-by: Guohan Lu --- Makefile | 18 +++- Makefile.work | 2 +- build_debian.sh | 16 +-- files/apt/sources.list.amd64 | 10 +- files/apt/sources.list.arm64 | 10 +- files/apt/sources.list.armhf | 10 +- installer/x86_64/install.sh | 4 +- platform/barefoot/bfn-modules.mk | 2 - platform/barefoot/platform-modules-arista.mk | 2 - .../barefoot/platform-modules-bfn-montara.mk | 2 - .../barefoot/platform-modules-bfn-newport.mk | 2 - platform/barefoot/platform-modules-bfn.mk | 1 - .../barefoot/platform-modules-ingrasys.mk | 1 - .../barefoot/platform-modules-wnc-osw1800.mk | 1 - platform/broadcom/platform-modules-accton.mk | 2 - .../platform-modules-alphanetworks.mk | 1 - platform/broadcom/platform-modules-arista.mk | 1 - .../broadcom/platform-modules-brcm-xlr-gts.mk | 1 - platform/broadcom/platform-modules-cel.mk | 1 - platform/broadcom/platform-modules-dell.mk | 1 - platform/broadcom/platform-modules-delta.mk | 1 - .../broadcom/platform-modules-ingrasys.mk | 1 - .../broadcom/platform-modules-inventec.mk | 1 - platform/broadcom/platform-modules-juniper.mk | 2 - platform/broadcom/platform-modules-mitac.mk | 1 - platform/broadcom/platform-modules-quanta.mk | 1 - platform/broadcom/sai-modules.mk | 1 - platform/cavium/cavm-platform-modules.mk | 1 - platform/cavium/cavm-xpnet.mk | 1 - .../centec/platform-modules-centec-e582.mk | 1 - platform/innovium/invm-sai.mk | 1 - platform/innovium/platform-modules-cel.mk | 1 - platform/innovium/platform-modules-delta.mk | 1 - platform/marvell-arm64/linux-kernel-arm64.mk | 1 - platform/marvell-armhf/linux-kernel-armhf.mk | 1 - platform/marvell-armhf/platform-et6448m.mk | 1 - platform/nephos/nephos-modules.mk | 1 - platform/nephos/platform-modules-accton.mk | 1 - platform/nephos/platform-modules-cig.mk | 3 - platform/nephos/platform-modules-ingrasys.mk | 2 - rules/docker-ptf.mk | 1 + rules/frr.mk | 1 - rules/iccpd.mk | 1 - rules/ifupdown2.mk | 1 - rules/initramfs-tools.mk | 2 - rules/iptables.mk | 1 - rules/isc-dhcp.mk | 2 - rules/ixgbe.mk | 2 - rules/kdump-tools.mk | 3 +- rules/libyang.mk | 1 - rules/monit.mk | 2 - rules/radvd.mk | 1 - rules/sflow.mk | 3 - rules/smartmontools.mk | 1 - rules/sonic-device-data.mk | 1 - rules/sonic-ztp.mk | 1 - rules/swig.mk | 1 - rules/tacacs.mk | 2 - slave.mk | 99 ++++++++++++------- src/sonic-yang-models/setup.py | 2 +- 60 files changed, 106 insertions(+), 134 deletions(-) diff --git a/Makefile b/Makefile index 43e2b4d527f1..b855017f928f 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,17 @@ # SONiC make file NOJESSIE ?= 0 +NOSTRETCH ?= 0 %:: @echo "+++ --- Making $@ --- +++" ifeq ($(NOJESSIE), 0) - EXTRA_JESSIE_TARGETS=$(notdir $@) make -f Makefile.work jessie + EXTRA_DOCKER_TARGETS=$(notdir $@) make -f Makefile.work jessie endif - BLDENV=stretch make -f Makefile.work $@ +ifeq ($(NOSTRETCH), 0) + EXTRA_DOCKER_TARGETS=$(notdir $@) BLDENV=stretch make -f Makefile.work stretch +endif + BLDENV=buster make -f Makefile.work $@ jessie: @echo "+++ Making $@ +++" @@ -15,12 +19,18 @@ ifeq ($(NOJESSIE), 0) make -f Makefile.work jessie endif -buster: - BLDENV=buster make -f Makefile.work +stretch: + @echo "+++ Making $@ +++" +ifeq ($(NOSTRETCH), 0) + make -f Makefile.work stretch +endif clean reset init configure showtag sonic-slave-build sonic-slave-bash : @echo "+++ Making $@ +++" ifeq ($(NOJESSIE), 0) make -f Makefile.work $@ endif +ifeq ($(NOSTRETCH), 0) BLDENV=stretch make -f Makefile.work $@ +endif + BLDENV=buster make -f Makefile.work $@ diff --git a/Makefile.work b/Makefile.work index f39c5b27e3e1..6f63652423a6 100644 --- a/Makefile.work +++ b/Makefile.work @@ -200,7 +200,7 @@ SONIC_BUILD_INSTRUCTION := make \ HTTPS_PROXY=$(https_proxy) \ SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY) \ SONIC_ENABLE_RESTAPI=$(ENABLE_RESTAPI) \ - EXTRA_JESSIE_TARGETS=$(EXTRA_JESSIE_TARGETS) \ + EXTRA_DOCKER_TARGETS=$(EXTRA_DOCKER_TARGETS) \ BUILD_LOG_TIMESTAMP=$(BUILD_LOG_TIMESTAMP) \ $(SONIC_OVERRIDE_BUILD_VARS) diff --git a/build_debian.sh b/build_debian.sh index e0d953b455b2..6981f698a1d8 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -35,9 +35,9 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then # Version name differs between ARCH, copying same version as in sonic-slave docker DOCKER_VERSION=18.06.3~ce~3-0~debian else - DOCKER_VERSION=5:18.09.8~3-0~debian-stretch + DOCKER_VERSION=5:18.09.8~3-0~debian-$IMAGE_DISTRO fi -LINUX_KERNEL_VERSION=4.9.0-11-2 +LINUX_KERNEL_VERSION=4.19.0-6 ## Working directory to prepare the file system FILESYSTEM_ROOT=./fsroot @@ -81,9 +81,9 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then # qemu arm bin executable for cross-building sudo mkdir -p $FILESYSTEM_ROOT/usr/bin sudo cp /usr/bin/qemu*static $FILESYSTEM_ROOT/usr/bin || true - sudo http_proxy=$http_proxy debootstrap --variant=minbase --arch $CONFIGURED_ARCH stretch $FILESYSTEM_ROOT http://deb.debian.org/debian + sudo http_proxy=$http_proxy debootstrap --variant=minbase --arch $CONFIGURED_ARCH $IMAGE_DISTRO $FILESYSTEM_ROOT http://deb.debian.org/debian else - sudo http_proxy=$http_proxy debootstrap --variant=minbase --arch $CONFIGURED_ARCH stretch $FILESYSTEM_ROOT http://debian-archive.trafficmanager.net/debian + sudo http_proxy=$http_proxy debootstrap --variant=minbase --arch $CONFIGURED_ARCH $IMAGE_DISTRO $FILESYSTEM_ROOT http://debian-archive.trafficmanager.net/debian fi ## Config hostname and hosts, otherwise 'sudo ...' will complain 'sudo: unable to resolve host ...' @@ -203,9 +203,9 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -o /tmp/docker sudo LANG=C chroot $FILESYSTEM_ROOT apt-key add /tmp/docker.gpg sudo LANG=C chroot $FILESYSTEM_ROOT rm /tmp/docker.gpg sudo LANG=C chroot $FILESYSTEM_ROOT add-apt-repository \ - "deb [arch=$CONFIGURED_ARCH] https://download.docker.com/linux/debian stretch stable" + "$deb [arch=$CONFIGURED_ARCH] https://download.docker.com/linux/debian $IMAGE_DISTRO stable" sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} docker-ce-cli=${DOCKER_VERSION} sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 if [ "$INSTALL_KUBERNETES" == "y" ] @@ -325,9 +325,9 @@ sudo sed -i '/^#.* en_US.* /s/^#//' $FILESYSTEM_ROOT/etc/locale.gen && \ sudo LANG=en_US.UTF-8 DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT update-locale "LANG=en_US.UTF-8" sudo LANG=C chroot $FILESYSTEM_ROOT bash -c "find /usr/share/i18n/locales/ ! -name 'en_US' -type f -exec rm -f {} +" -# Install certain fundamental packages from stretch-backports in order to get +# Install certain fundamental packages from $IMAGE_DISTRO-backports in order to get # more up-to-date (but potentially less stable) versions -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y -t stretch-backports install \ +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y -t $IMAGE_DISTRO-backports install \ picocom if [[ $CONFIGURED_ARCH == amd64 ]]; then diff --git a/files/apt/sources.list.amd64 b/files/apt/sources.list.amd64 index 752b1bb4fc60..4a94e3161ab1 100644 --- a/files/apt/sources.list.amd64 +++ b/files/apt/sources.list.amd64 @@ -1,8 +1,8 @@ ## Debian mirror on Microsoft Azure ## Ref: http://debian-archive.trafficmanager.net/ -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free -deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free -deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch-backports main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster-backports main contrib non-free diff --git a/files/apt/sources.list.arm64 b/files/apt/sources.list.arm64 index bbe8fe2e9407..dd82c744de1d 100644 --- a/files/apt/sources.list.arm64 +++ b/files/apt/sources.list.arm64 @@ -1,8 +1,8 @@ ## Debian mirror for ARM ## Not the repo mirror site can change in future, and needs to be updated to be in sync -deb [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free -deb-src [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free -deb [arch=arm64] http://deb.debian.org/debian stretch-updates main contrib non-free -deb-src [arch=arm64] http://deb.debian.org/debian stretch-updates main contrib non-free -deb [arch=arm64] http://ftp.debian.org/debian stretch-backports main +deb [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free +deb-src [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free +deb [arch=arm64] http://ftp.debian.org/debian buster-backports main diff --git a/files/apt/sources.list.armhf b/files/apt/sources.list.armhf index 5dd0c306724b..760906188a94 100644 --- a/files/apt/sources.list.armhf +++ b/files/apt/sources.list.armhf @@ -1,8 +1,8 @@ ## Debian mirror for ARM ## Not the repo mirror site can change in future, and needs to be updated to be in sync -deb [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free -deb-src [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free -deb [arch=armhf] http://deb.debian.org/debian stretch-updates main contrib non-free -deb-src [arch=armhf] http://deb.debian.org/debian stretch-updates main contrib non-free -deb [arch=armhf] http://ftp.debian.org/debian stretch-backports main +deb [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free +deb-src [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free +deb [arch=armhf] http://ftp.debian.org/debian buster-backports main diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index d0aa7818df9b..5b87190c44a9 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -606,12 +606,12 @@ menuentry '$demo_grub_entry' { if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 - linux /$image_dir/boot/vmlinuz-4.9.0-11-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ + linux /$image_dir/boot/vmlinuz-4.19.0-6-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ net.ifnames=0 biosdevname=0 \ loop=$image_dir/$FILESYSTEM_SQUASHFS loopfstype=squashfs \ apparmor=1 security=apparmor varlog_size=$VAR_LOG_SIZE usbcore.autosuspend=-1 $ONIE_PLATFORM_EXTRA_CMDLINE_LINUX echo 'Loading $demo_volume_label $demo_type initial ramdisk ...' - initrd /$image_dir/boot/initrd.img-4.9.0-11-2-amd64 + initrd /$image_dir/boot/initrd.img-4.19.0-6-amd64 } EOF diff --git a/platform/barefoot/bfn-modules.mk b/platform/barefoot/bfn-modules.mk index 67b7fa924da1..46d504f56812 100644 --- a/platform/barefoot/bfn-modules.mk +++ b/platform/barefoot/bfn-modules.mk @@ -6,5 +6,3 @@ BFN_MODULE = bfn-modules_$(VERSION)_amd64.deb $(BFN_MODULE)_SRC_PATH = $(PLATFORM_PATH)/bfn-modules $(BFN_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_DPKG_DEBS += $(BFN_MODULE) - -SONIC_STRETCH_DEBS += $(BFN_MODULE) diff --git a/platform/barefoot/platform-modules-arista.mk b/platform/barefoot/platform-modules-arista.mk index 28c893b80713..298bc93d9250 100644 --- a/platform/barefoot/platform-modules-arista.mk +++ b/platform/barefoot/platform-modules-arista.mk @@ -21,5 +21,3 @@ $(eval $(call add_extra_package,$(ARISTA_PLATFORM_MODULE),$(ARISTA_PLATFORM_MODU export ARISTA_PLATFORM_MODULE ARISTA_PLATFORM_MODULE_PYTHON2 ARISTA_PLATFORM_MODULE_PYTHON3 ARISTA_PLATFORM_MODULE_DRIVERS export ARISTA_SCD_DRIVER_CONFIG=m - -SONIC_STRETCH_DEBS += $(ARISTA_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-bfn-montara.mk b/platform/barefoot/platform-modules-bfn-montara.mk index d089218c9454..375f100475cf 100644 --- a/platform/barefoot/platform-modules-bfn-montara.mk +++ b/platform/barefoot/platform-modules-bfn-montara.mk @@ -9,5 +9,3 @@ $(BFN_MONTARA_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-module $(BFN_MONTARA_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(BFN_MONTARA_PLATFORM_MODULE)_PLATFORM = x86_64-accton_wedge100bf_32x-r0 SONIC_DPKG_DEBS += $(BFN_MONTARA_PLATFORM_MODULE) - -SONIC_STRETCH_DEBS += $(BFN_MONTARA_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-bfn-newport.mk b/platform/barefoot/platform-modules-bfn-newport.mk index ff251ed1ddd7..7d0e0a6cc261 100644 --- a/platform/barefoot/platform-modules-bfn-newport.mk +++ b/platform/barefoot/platform-modules-bfn-newport.mk @@ -9,5 +9,3 @@ $(BFN_NEWPORT_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-module $(BFN_NEWPORT_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(BFN_NEWPORT_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9516bf_32d-r0 SONIC_DPKG_DEBS += $(BFN_NEWPORT_PLATFORM_MODULE) - -SONIC_STRETCH_DEBS += $(BFN_NEWPORT_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-bfn.mk b/platform/barefoot/platform-modules-bfn.mk index 1caa92c8f2b3..28b6ec112788 100644 --- a/platform/barefoot/platform-modules-bfn.mk +++ b/platform/barefoot/platform-modules-bfn.mk @@ -10,4 +10,3 @@ $(BFN_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(BFN_PLATFORM_MODULE)_PLATFORM = x86_64-accton_wedge100bf_65x-r0 SONIC_DPKG_DEBS += $(BFN_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(BFN_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-ingrasys.mk b/platform/barefoot/platform-modules-ingrasys.mk index ea8f68c003fc..60153e5dee75 100644 --- a/platform/barefoot/platform-modules-ingrasys.mk +++ b/platform/barefoot/platform-modules-ingrasys.mk @@ -17,4 +17,3 @@ $(INGRASYS_S9280_64X_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s9280_64x-r0 $(eval $(call add_extra_package,$(INGRASYS_S9180_32X_PLATFORM_MODULE),$(INGRASYS_S9280_64X_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-wnc-osw1800.mk b/platform/barefoot/platform-modules-wnc-osw1800.mk index 5703d069c97e..a203aa93f7ec 100644 --- a/platform/barefoot/platform-modules-wnc-osw1800.mk +++ b/platform/barefoot/platform-modules-wnc-osw1800.mk @@ -10,4 +10,3 @@ $(WNC_OSW1800_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMO $(WNC_OSW1800_PLATFORM_MODULE)_PLATFORM = x86_64-wnc_osw1800-r0 SONIC_DPKG_DEBS += $(WNC_OSW1800_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(WNC_OSW1800_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-accton.mk b/platform/broadcom/platform-modules-accton.mk index bab9c5ef9fef..395040d7561d 100755 --- a/platform/broadcom/platform-modules-accton.mk +++ b/platform/broadcom/platform-modules-accton.mk @@ -111,5 +111,3 @@ $(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS ACCTON_AS7315_27XB_PLATFORM_MODULE = sonic-platform-accton-as7315-27xb_$(ACCTON_AS7315_27XB_PLATFORM_MODULE_VERSION)_amd64.deb $(ACCTON_AS7315_27XB_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as7315_27xb-r0 $(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS7315_27XB_PLATFORM_MODULE))) - -SONIC_STRETCH_DEBS += $(ACCTON_AS7712_32X_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-alphanetworks.mk b/platform/broadcom/platform-modules-alphanetworks.mk index 425656e06653..13e5fc4ff9e2 100644 --- a/platform/broadcom/platform-modules-alphanetworks.mk +++ b/platform/broadcom/platform-modules-alphanetworks.mk @@ -16,6 +16,5 @@ ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE = sonic-platform-alphanetworks-snh60b $(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE)_PLATFORM = x86_64-alphanetworks_snh60b0_640f-r0 $(eval $(call add_extra_package,$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE),$(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-arista.mk b/platform/broadcom/platform-modules-arista.mk index 28c893b80713..ac2c65fdf3c5 100644 --- a/platform/broadcom/platform-modules-arista.mk +++ b/platform/broadcom/platform-modules-arista.mk @@ -22,4 +22,3 @@ export ARISTA_PLATFORM_MODULE ARISTA_PLATFORM_MODULE_PYTHON2 ARISTA_PLATFORM_MOD export ARISTA_SCD_DRIVER_CONFIG=m -SONIC_STRETCH_DEBS += $(ARISTA_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-brcm-xlr-gts.mk b/platform/broadcom/platform-modules-brcm-xlr-gts.mk index c35609c39476..28abe890acbd 100644 --- a/platform/broadcom/platform-modules-brcm-xlr-gts.mk +++ b/platform/broadcom/platform-modules-brcm-xlr-gts.mk @@ -12,4 +12,3 @@ SONIC_MAKE_DEBS += $(BRCM_XLR_GTS_PLATFORM_MODULE) export BRCM_XLR_GTS_PLATFORM_MODULE -SONIC_STRETCH_DEBS += $(BRCM_XLR_GTS_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index 9fe4eb7b6932..de021df7e4db 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -28,4 +28,3 @@ CEL_SILVERSTONE_PLATFORM_MODULE = platform-modules-silverstone_$(CEL_SILVERSTONE $(CEL_SILVERSTONE_PLATFORM_MODULE)_PLATFORM = x86_64-cel_silverstone-r0 $(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_SILVERSTONE_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(CEL_DX010_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-dell.mk b/platform/broadcom/platform-modules-dell.mk index 298e3c4f7396..18fafa3c0c8d 100644 --- a/platform/broadcom/platform-modules-dell.mk +++ b/platform/broadcom/platform-modules-dell.mk @@ -46,7 +46,6 @@ $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_Z9332F_PLAT DELL_S5248F_PLATFORM_MODULE = platform-modules-s5248f_$(DELL_S5248F_PLATFORM_MODULE_VERSION)_amd64.deb $(DELL_S5248F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5248f_c3538-r0 $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5248F_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(DELL_Z9100_PLATFORM_MODULE) #flashrom tool $(shell ./$(PLATFORM_PATH)/sonic-platform-modules-dell/tools/flashrom.sh > /dev/null 2>&1) diff --git a/platform/broadcom/platform-modules-delta.mk b/platform/broadcom/platform-modules-delta.mk index 17746488e02f..5375c6ad7a7d 100644 --- a/platform/broadcom/platform-modules-delta.mk +++ b/platform/broadcom/platform-modules-delta.mk @@ -34,4 +34,3 @@ DELTA_AG9032V2A_PLATFORM_MODULE = platform-modules-ag9032v2a_$(DELTA_AG9032V2A_P $(DELTA_AG9032V2A_PLATFORM_MODULE)_PLATFORM = x86_64-delta_ag9032v2a-r0 $(eval $(call add_extra_package,$(DELTA_AG9032V1_PLATFORM_MODULE),$(DELTA_AG9032V2A_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(DELTA_AG9032V1_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-ingrasys.mk b/platform/broadcom/platform-modules-ingrasys.mk index b6195698a1f9..9ce7cdb26487 100644 --- a/platform/broadcom/platform-modules-ingrasys.mk +++ b/platform/broadcom/platform-modules-ingrasys.mk @@ -35,4 +35,3 @@ $(eval $(call add_extra_package,$(INGRASYS_S9100_PLATFORM_MODULE),$(INGRASYS_S89 $(eval $(call add_extra_package,$(INGRASYS_S9100_PLATFORM_MODULE),$(INGRASYS_S8810_32Q_PLATFORM_MODULE))) $(eval $(call add_extra_package,$(INGRASYS_S9100_PLATFORM_MODULE),$(INGRASYS_S9200_64X_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(INGRASYS_S9100_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-inventec.mk b/platform/broadcom/platform-modules-inventec.mk index 871604ce91d9..b947f8a5e7d0 100644 --- a/platform/broadcom/platform-modules-inventec.mk +++ b/platform/broadcom/platform-modules-inventec.mk @@ -40,4 +40,3 @@ INVENTEC_D7264Q28B_PLATFORM_MODULE = platform-modules-d7264q28b_$(INVENTEC_D7264 $(INVENTEC_D7264Q28B_PLATFORM_MODULE)_PLATFORM = x86_64-inventec_d7264q28b-r0 $(eval $(call add_extra_package,$(INVENTEC_D7032Q28B_PLATFORM_MODULE),$(INVENTEC_D7264Q28B_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(INVENTEC_D7032Q28B_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-juniper.mk b/platform/broadcom/platform-modules-juniper.mk index 4dcf9c071599..f6a9b68d70de 100755 --- a/platform/broadcom/platform-modules-juniper.mk +++ b/platform/broadcom/platform-modules-juniper.mk @@ -16,5 +16,3 @@ JUNIPER_QFX5200_PLATFORM_MODULE = sonic-platform-juniper-qfx5200_$(JUNIPER_QFX52 $(JUNIPER_QFX5200_PLATFORM_MODULE)_PLATFORM = x86_64-juniper_qfx5200-r0 $(eval $(call add_extra_package,$(JUNIPER_QFX5210_PLATFORM_MODULE),$(JUNIPER_QFX5200_PLATFORM_MODULE))) - -SONIC_STRETCH_DEBS += $(JUNIPER_QFX5210_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-mitac.mk b/platform/broadcom/platform-modules-mitac.mk index 6e7e05bf6c57..5a0c303f19d4 100644 --- a/platform/broadcom/platform-modules-mitac.mk +++ b/platform/broadcom/platform-modules-mitac.mk @@ -10,4 +10,3 @@ $(MITAC_LY1200_32X_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_ $(MITAC_LY1200_32X_PLATFORM_MODULE)_PLATFORM = x86_64-mitac_ly1200_b32h0_c3-r0 SONIC_DPKG_DEBS += $(MITAC_LY1200_32X_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(MITAC_LY1200_32X_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-quanta.mk b/platform/broadcom/platform-modules-quanta.mk index 456af3019e38..267d3d9e7378 100644 --- a/platform/broadcom/platform-modules-quanta.mk +++ b/platform/broadcom/platform-modules-quanta.mk @@ -34,4 +34,3 @@ QUANTA_IX9_32X_PLATFORM_MODULE = sonic-platform-quanta-ix9-32x_$(QUANTA_IX9_32X_ $(QUANTA_IX9_32X_PLATFORM_MODULE)_PLATFORM = x86_64-quanta_ix9_bwde-r0 $(eval $(call add_extra_package,$(QUANTA_IX1B_32X_PLATFORM_MODULE),$(QUANTA_IX9_32X_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(QUANTA_IX1B_32X_PLATFORM_MODULE) diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index 93132c2287bd..79fb0102820a 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -8,4 +8,3 @@ $(BRCM_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules $(BRCM_OPENNSL_KERNEL)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_DPKG_DEBS += $(BRCM_OPENNSL_KERNEL) -SONIC_STRETCH_DEBS += $(BRCM_OPENNSL_KERNEL) diff --git a/platform/cavium/cavm-platform-modules.mk b/platform/cavium/cavm-platform-modules.mk index 248486313505..4ac72a4c4aab 100644 --- a/platform/cavium/cavm-platform-modules.mk +++ b/platform/cavium/cavm-platform-modules.mk @@ -1,4 +1,3 @@ CAVM_PLATFORM_DEB = cavm_platform_modules.deb $(CAVM_PLATFORM_DEB)_SRC_PATH = $(PLATFORM_PATH)/cavm_platform_modules SONIC_MAKE_DEBS += $(CAVM_PLATFORM_DEB) -SONIC_STRETCH_DEBS += $(CAVM_PLATFORM_DEB) diff --git a/platform/cavium/cavm-xpnet.mk b/platform/cavium/cavm-xpnet.mk index 714a929fb2c1..ed86558a36ae 100644 --- a/platform/cavium/cavm-xpnet.mk +++ b/platform/cavium/cavm-xpnet.mk @@ -4,4 +4,3 @@ CAVM_XPNET_DEB = xp80-Pcie-Endpoint.deb $(CAVM_XPNET_DEB)_URL = $(CAVM_SAI_URL)/netdev/$(CAVM_XPNET_DEB) SONIC_ONLINE_DEBS += $(CAVM_XPNET_DEB) -SONIC_STRETCH_DEBS += $(CAVM_XPNET_DEB) diff --git a/platform/centec/platform-modules-centec-e582.mk b/platform/centec/platform-modules-centec-e582.mk index e22653075ecb..e86c428a7403 100644 --- a/platform/centec/platform-modules-centec-e582.mk +++ b/platform/centec/platform-modules-centec-e582.mk @@ -12,7 +12,6 @@ CENTEC_E582_48X6Q_PLATFORM_MODULE = platform-modules-e582-48x6q_$(CENTEC_E582_48 $(CENTEC_E582_48X6Q_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-e582 $(CENTEC_E582_48X6Q_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CENTEC_E582_48X6Q_PLATFORM_MODULE)_PLATFORM = x86_64-centec_e582_48x6q-r0 -SONIC_STRETCH_DEBS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) SONIC_DPKG_DEBS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) CENTEC_E582_48X2Q4Z_PLATFORM_MODULE = platform-modules-e582-48x2q4z_$(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE_VERSION)_amd64.deb diff --git a/platform/innovium/invm-sai.mk b/platform/innovium/invm-sai.mk index 8c236a8b68d2..9f013208201b 100755 --- a/platform/innovium/invm-sai.mk +++ b/platform/innovium/invm-sai.mk @@ -11,4 +11,3 @@ $(INVM_HSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_HSAI) $(INVM_DRV)_URL = $(INVM_SAI_ONLINE)/$(INVM_DRV) SONIC_ONLINE_DEBS += $(INVM_LIBSAI) $(INVM_HSAI) $(INVM_DRV) -SONIC_STRETCH_DEBS += $(INVM_DRV) diff --git a/platform/innovium/platform-modules-cel.mk b/platform/innovium/platform-modules-cel.mk index b93bea758d71..4b394c36ec88 100755 --- a/platform/innovium/platform-modules-cel.mk +++ b/platform/innovium/platform-modules-cel.mk @@ -9,4 +9,3 @@ $(CEL_MIDSTONE_200I_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform- $(CEL_MIDSTONE_200I_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CEL_MIDSTONE_200I_PLATFORM_MODULE)_PLATFORM = x86_64-cel_midstone-r0 SONIC_DPKG_DEBS += $(CEL_MIDSTONE_200I_PLATFORM_MODULE) -SONIC_STRETCH_DEBS+= $(CEL_MIDSTONE_200I_PLATFORM_MODULE) diff --git a/platform/innovium/platform-modules-delta.mk b/platform/innovium/platform-modules-delta.mk index 68e13fb8a8a4..6a6dc45763eb 100644 --- a/platform/innovium/platform-modules-delta.mk +++ b/platform/innovium/platform-modules-delta.mk @@ -10,4 +10,3 @@ $(DELTA_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(DELTA_PLATFORM_MODULE)_PLATFORM = x86_64-delta_et-c032if-r0 SONIC_DPKG_DEBS += $(DELTA_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(DELTA_PLATFORM_MODULE) diff --git a/platform/marvell-arm64/linux-kernel-arm64.mk b/platform/marvell-arm64/linux-kernel-arm64.mk index 2c5438db982d..a953c908234c 100644 --- a/platform/marvell-arm64/linux-kernel-arm64.mk +++ b/platform/marvell-arm64/linux-kernel-arm64.mk @@ -4,4 +4,3 @@ LINUX_KERNEL_DTB = linux-image-4.9.168-arm64.deb $(LINUX_KERNEL_DTB)_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/arm64/kernel/$(LINUX_KERNEL_DTB) SONIC_ONLINE_DEBS += $(LINUX_KERNEL_DTB) -SONIC_STRETCH_DEBS += $(LINUX_KERNEL_DTB) diff --git a/platform/marvell-armhf/linux-kernel-armhf.mk b/platform/marvell-armhf/linux-kernel-armhf.mk index 4d52beac49d9..ac7aa3faf19a 100644 --- a/platform/marvell-armhf/linux-kernel-armhf.mk +++ b/platform/marvell-armhf/linux-kernel-armhf.mk @@ -4,4 +4,3 @@ LINUX_KERNEL_DTB = linux-image-4.9.189-armhf.deb $(LINUX_KERNEL_DTB)_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/armhf/kernel/$(LINUX_KERNEL_DTB) SONIC_ONLINE_DEBS += $(LINUX_KERNEL_DTB) -SONIC_STRETCH_DEBS += $(LINUX_KERNEL_DTB) diff --git a/platform/marvell-armhf/platform-et6448m.mk b/platform/marvell-armhf/platform-et6448m.mk index eeef04a20ae7..1f0ee201cc76 100644 --- a/platform/marvell-armhf/platform-et6448m.mk +++ b/platform/marvell-armhf/platform-et6448m.mk @@ -6,4 +6,3 @@ $(ET6448M_PLATFORM)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-et6448m $(ET6448M_PLATFORM)_PLATFORM = armhf-marvell_et6448m_52x-r0 SONIC_DPKG_DEBS += $(ET6448M_PLATFORM) -SONIC_STRETCH_DEBS += $(ET6448M_PLATFORM) diff --git a/platform/nephos/nephos-modules.mk b/platform/nephos/nephos-modules.mk index 50a2d0e5c080..0dd7e2971823 100644 --- a/platform/nephos/nephos-modules.mk +++ b/platform/nephos/nephos-modules.mk @@ -23,4 +23,3 @@ $(NEPHOS_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_DPKG_DEBS += $(NEPHOS_MODULE) endif -SONIC_STRETCH_DEBS += $(NEPHOS_MODULE) diff --git a/platform/nephos/platform-modules-accton.mk b/platform/nephos/platform-modules-accton.mk index ebfd77f30fc8..1ecb76a2fbb8 100644 --- a/platform/nephos/platform-modules-accton.mk +++ b/platform/nephos/platform-modules-accton.mk @@ -10,4 +10,3 @@ $(ACCTON_AS7116_54X_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS $(ACCTON_AS7116_54X_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as7116_54x-r0 SONIC_DPKG_DEBS += $(ACCTON_AS7116_54X_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(ACCTON_AS7116_54X_PLATFORM_MODULE) diff --git a/platform/nephos/platform-modules-cig.mk b/platform/nephos/platform-modules-cig.mk index 5cccf1692550..48e7072f6da3 100644 --- a/platform/nephos/platform-modules-cig.mk +++ b/platform/nephos/platform-modules-cig.mk @@ -9,18 +9,15 @@ $(CIG_CS6436_56P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-mod $(CIG_CS6436_56P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CIG_CS6436_56P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs6436_56p-r0 SONIC_DPKG_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE) CIG_CS6436_54P_PLATFORM_MODULE = sonic-platform-cig-cs6436-54p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb $(CIG_CS6436_54P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig $(CIG_CS6436_54P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CIG_CS6436_54P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs6436_54p-r0 SONIC_DPKG_DEBS += $(CIG_CS6436_54P_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(CIG_CS6436_54P_PLATFORM_MODULE) CIG_CS5435_54P_PLATFORM_MODULE = sonic-platform-cig-cs5435-54p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb $(CIG_CS5435_54P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig $(CIG_CS5435_54P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CIG_CS5435_54P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs5435_54p-r0 SONIC_DPKG_DEBS += $(CIG_CS5435_54P_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(CIG_CS5435_54P_PLATFORM_MODULE) diff --git a/platform/nephos/platform-modules-ingrasys.mk b/platform/nephos/platform-modules-ingrasys.mk index 94b8315cd70c..03818ca8465d 100644 --- a/platform/nephos/platform-modules-ingrasys.mk +++ b/platform/nephos/platform-modules-ingrasys.mk @@ -17,5 +17,3 @@ $(INGRASYS_S9230_64X_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s9230_64x-r0 $(eval $(call add_extra_package,$(INGRASYS_S9130_32X_PLATFORM_MODULE),$(INGRASYS_S9230_64X_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(INGRASYS_S9130_32X_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(INGRASYS_S9230_64X_PLATFORM_MODULE) diff --git a/rules/docker-ptf.mk b/rules/docker-ptf.mk index 2782c45339bd..b2d45068334d 100644 --- a/rules/docker-ptf.mk +++ b/rules/docker-ptf.mk @@ -4,3 +4,4 @@ DOCKER_PTF = docker-ptf.gz $(DOCKER_PTF)_PATH = $(DOCKERS_PATH)/docker-ptf $(DOCKER_PTF)_DEPENDS += $(LIBTHRIFT) $(PYTHON_THRIFT) $(PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF) diff --git a/rules/frr.mk b/rules/frr.mk index df924c8af711..321f11feb967 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -12,7 +12,6 @@ $(FRR)_DEPENDS += $(LIBSNMP_DEV) $(LIBYANG_DEV) $(FRR)_RDEPENDS += $(LIBYANG) $(FRR)_SRC_PATH = $(SRC_PATH)/sonic-frr SONIC_MAKE_DEBS += $(FRR) -SONIC_STRETCH_DEBS += $(FRR) FRR_PYTHONTOOLS = frr-pythontools_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_all.deb $(eval $(call add_derived_package,$(FRR),$(FRR_PYTHONTOOLS))) diff --git a/rules/iccpd.mk b/rules/iccpd.mk index d54faaba5b76..1923a9a2a62d 100644 --- a/rules/iccpd.mk +++ b/rules/iccpd.mk @@ -7,7 +7,6 @@ $(ICCPD)_DEPENDS += $(LIBNL_GENL3_DEV) $(LIBNL_CLI_DEV) $(ICCPD)_RDEPENDS += $(LIBNL_GENL3) $(LIBNL_CLI) $(ICCPD)_SRC_PATH = $(SRC_PATH)/iccpd SONIC_MAKE_DEBS += $(ICCPD) -# SONIC_STRETCH_DEBS += $(ICCPD) # Export these variables so they can be used in a sub-make export ICCPD_VERSION diff --git a/rules/ifupdown2.mk b/rules/ifupdown2.mk index b663cc1532d0..f81facd8ff26 100644 --- a/rules/ifupdown2.mk +++ b/rules/ifupdown2.mk @@ -6,6 +6,5 @@ export IFUPDOWN2_VERSION IFUPDOWN2 = ifupdown2_$(IFUPDOWN2_VERSION)_all.deb $(IFUPDOWN2)_SRC_PATH = $(SRC_PATH)/ifupdown2 SONIC_MAKE_DEBS += $(IFUPDOWN2) -SONIC_STRETCH_DEBS += $(IFUPDOWN2) export IFUPDOWN2 diff --git a/rules/initramfs-tools.mk b/rules/initramfs-tools.mk index badc584dd2be..e3e14659ed18 100644 --- a/rules/initramfs-tools.mk +++ b/rules/initramfs-tools.mk @@ -9,5 +9,3 @@ SONIC_MAKE_DEBS += $(INITRAMFS_TOOLS) INITRAMFS_TOOLS_CORE = initramfs-tools-core_$(INITRAMFS_TOOLS_VERSION)_all.deb $(eval $(call add_extra_package,$(INITRAMFS_TOOLS),$(INITRAMFS_TOOLS_CORE))) - -SONIC_STRETCH_DEBS += $(INITRAMFS_TOOLS) $(INITRAMFS_TOOLS_CORE) diff --git a/rules/iptables.mk b/rules/iptables.mk index 4d88c0a224b2..fbd7ccd70c07 100644 --- a/rules/iptables.mk +++ b/rules/iptables.mk @@ -7,7 +7,6 @@ IPTABLES_VERSION_FULL = $(IPTABLES_VERSION)-$(IPTABLES_VERSION_SUFFIX) IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_amd64.deb $(IPTABLES)_SRC_PATH = $(SRC_PATH)/iptables SONIC_MAKE_DEBS += $(IPTABLES) -SONIC_STRETCH_DEBS += $(IPTABLES) IPTABLESIP4TC = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb $(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP4TC))) diff --git a/rules/isc-dhcp.mk b/rules/isc-dhcp.mk index da57d0877104..e4bf23355076 100644 --- a/rules/isc-dhcp.mk +++ b/rules/isc-dhcp.mk @@ -8,7 +8,5 @@ ISC_DHCP_RELAY = isc-dhcp-relay_$(ISC_DHCP_VERSION)_$(CONFIGURED_ARCH).deb $(ISC_DHCP_RELAY)_SRC_PATH = $(SRC_PATH)/isc-dhcp SONIC_MAKE_DEBS += $(ISC_DHCP_RELAY) -SONIC_STRETCH_DEBS += $(ISC_DHCP_RELAY) - ISC_DHCP_RELAY_DBG = isc-dhcp-relay-dbgsym_$(ISC_DHCP_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(ISC_DHCP_RELAY),$(ISC_DHCP_RELAY_DBG))) diff --git a/rules/ixgbe.mk b/rules/ixgbe.mk index 86a0e8453a2b..c1b017905b53 100644 --- a/rules/ixgbe.mk +++ b/rules/ixgbe.mk @@ -7,5 +7,3 @@ IXGBE_DRIVER = ixgbe.ko $(IXGBE_DRIVER)_SRC_PATH = $(SRC_PATH)/ixgbe $(IXGBE_DRIVER)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_MAKE_FILES += $(IXGBE_DRIVER) - -SONIC_STRETCH_FILES += $(IXGBE_DRIVER) diff --git a/rules/kdump-tools.mk b/rules/kdump-tools.mk index d5d2630389f3..c4b0c792b04a 100644 --- a/rules/kdump-tools.mk +++ b/rules/kdump-tools.mk @@ -2,12 +2,11 @@ KDUMP_TOOLS_VERSION_BASE = 1.6.1 KDUMP_TOOLS_VERSION = $(KDUMP_TOOLS_VERSION_BASE)-1 -export KDUMP_TOOLS_VERSION_BASE +export KDUMP_TOOLS_VERSION_BASE export KDUMP_TOOLS_VERSION KDUMP_TOOLS = kdump-tools_$(KDUMP_TOOLS_VERSION)_all.deb $(KDUMP_TOOLS)_SRC_PATH = $(SRC_PATH)/kdump-tools SONIC_MAKE_DEBS += $(KDUMP_TOOLS) -SONIC_STRETCH_DEBS += $(KDUMP_TOOLS) export KDUMP_TOOLS diff --git a/rules/libyang.mk b/rules/libyang.mk index d10c2ea2cc66..f4dc3dc8469f 100644 --- a/rules/libyang.mk +++ b/rules/libyang.mk @@ -12,7 +12,6 @@ LIBYANG = libyang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(LIBYANG)_SRC_PATH = $(SRC_PATH)/libyang $(LIBYANG)_DEPENDS += $(SWIG_BASE) $(SWIG) SONIC_MAKE_DEBS += $(LIBYANG) -SONIC_STRETCH_DEBS += $(LIBYANG) LIBYANG_DEV = libyang-dev_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_DEV))) diff --git a/rules/monit.mk b/rules/monit.mk index d4c73453e4a6..4c15bc0dfab1 100644 --- a/rules/monit.mk +++ b/rules/monit.mk @@ -8,7 +8,5 @@ MONIT = monit_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb $(MONIT)_SRC_PATH = $(SRC_PATH)/monit SONIC_MAKE_DEBS += $(MONIT) -SONIC_STRETCH_DEBS += $(MONIT) - MONIT_DBG = monit-dbgsym_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(MONIT),$(MONIT_DBG))) diff --git a/rules/radvd.mk b/rules/radvd.mk index fcde8c5767b8..12f3066227d0 100644 --- a/rules/radvd.mk +++ b/rules/radvd.mk @@ -7,7 +7,6 @@ export RADVD_VERSION RADVD = radvd_$(RADVD_VERSION)_$(CONFIGURED_ARCH).deb $(RADVD)_SRC_PATH = $(SRC_PATH)/radvd SONIC_MAKE_DEBS += $(RADVD) -SONIC_STRETCH_DEBS += $(RADVD) RADVD_DBG = radvd-dbgsym_$(RADVD_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(RADVD),$(RADVD_DBG))) diff --git a/rules/sflow.mk b/rules/sflow.mk index a7ca1b3b1d0d..39054bad61c2 100644 --- a/rules/sflow.mk +++ b/rules/sflow.mk @@ -9,7 +9,6 @@ $(HSFLOWD)_DEPENDS += $(LIBHIREDIS_DEV) $(HSFLOWD)_SRC_PATH = $(SRC_PATH)/sflow/hsflowd SONIC_MAKE_DEBS += $(HSFLOWD) -SONIC_STRETCH_DEBS += $(HSFLOWD) HSFLOWD_DBG = hsflowd-dbg_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb $(HSFLOWD_DBG)_DEPENDS += $(HSFLOWD) @@ -27,7 +26,6 @@ SFLOWTOOL = sflowtool_$(SFLOWTOOL_VERSION)_$(CONFIGURED_ARCH).deb $(SFLOWTOOL)_SRC_PATH = $(SRC_PATH)/sflow/sflowtool SONIC_MAKE_DEBS += $(SFLOWTOOL) -SONIC_STRETCH_DEBS += $(SFLOWTOOL) export SFLOWTOOL # psample package @@ -40,7 +38,6 @@ PSAMPLE = psample_$(PSAMPLE_VERSION)-$(PSAMPLE_SUBVERSION)_$(CONFIGURED_ARCH).de $(PSAMPLE)_SRC_PATH = $(SRC_PATH)/sflow/psample SONIC_MAKE_DEBS += $(PSAMPLE) -SONIC_STRETCH_DEBS += $(PSAMPLE) export PSAMPLE # The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} diff --git a/rules/smartmontools.mk b/rules/smartmontools.mk index 90072592b954..7cc61eee6feb 100644 --- a/rules/smartmontools.mk +++ b/rules/smartmontools.mk @@ -9,5 +9,4 @@ export SMARTMONTOOLS_VERSION_MAJOR SMARTMONTOOLS_VERSION_FULL SMARTMONTOOLS = smartmontools_$(SMARTMONTOOLS_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(SMARTMONTOOLS)_SRC_PATH = $(SRC_PATH)/smartmontools -SONIC_STRETCH_DEBS += $(SMARTMONTOOLS) SONIC_MAKE_DEBS += $(SMARTMONTOOLS) diff --git a/rules/sonic-device-data.mk b/rules/sonic-device-data.mk index 4a5bff1a6fa6..abf7d0501f93 100644 --- a/rules/sonic-device-data.mk +++ b/rules/sonic-device-data.mk @@ -8,4 +8,3 @@ export SONIC_DEVICE_DATA_VERSION SONIC_DEVICE_DATA_VERSION_FULL SONIC_DEVICE_DATA = sonic-device-data_$(SONIC_DEVICE_DATA_VERSION_FULL)_all.deb $(SONIC_DEVICE_DATA)_SRC_PATH = $(SRC_PATH)/sonic-device-data SONIC_MAKE_DEBS += $(SONIC_DEVICE_DATA) -SONIC_STRETCH_DEBS += $(SONIC_DEVICE_DATA) diff --git a/rules/sonic-ztp.mk b/rules/sonic-ztp.mk index 3f64febd48c0..a848bcca148a 100644 --- a/rules/sonic-ztp.mk +++ b/rules/sonic-ztp.mk @@ -6,7 +6,6 @@ SONIC_ZTP_VERSION = 1.0.0 SONIC_ZTP = sonic-ztp_$(SONIC_ZTP_VERSION)_all.deb $(SONIC_ZTP)_SRC_PATH = $(SRC_PATH)/sonic-ztp SONIC_DPKG_DEBS += $(SONIC_ZTP) -SONIC_STRETCH_DEBS += $(SONIC_ZTP) export SONIC_ZTP_VERSION export SONIC_ZTP diff --git a/rules/swig.mk b/rules/swig.mk index c5c3c27b6f4b..cb964bb49b44 100644 --- a/rules/swig.mk +++ b/rules/swig.mk @@ -11,7 +11,6 @@ export SWIG_SUBVERSION SWIG_BASE = swig$(SWIG_VERSION_BASE)_$(SWIG_VERSION)-$(SWIG_SUBVERSION)_$(CONFIGURED_ARCH).deb $(SWIG_BASE)_SRC_PATH = $(SRC_PATH)/swig SONIC_MAKE_DEBS += $(SWIG_BASE) -SONIC_STRETCH_DEBS += $(SWIG_BASE) SWIG = swig_$(SWIG_VERSION)-$(SWIG_SUBVERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(SWIG_BASE),$(SWIG))) diff --git a/rules/tacacs.mk b/rules/tacacs.mk index c32504f6cd44..1c620ebcedc5 100644 --- a/rules/tacacs.mk +++ b/rules/tacacs.mk @@ -29,8 +29,6 @@ $(LIBNSS_TACPLUS)_RDEPENDS += $(LIBTAC2) $(LIBNSS_TACPLUS)_SRC_PATH = $(SRC_PATH)/tacacs/nss SONIC_MAKE_DEBS += $(LIBNSS_TACPLUS) -SONIC_STRETCH_DEBS += $(LIBPAM_TACPLUS) $(LIBNSS_TACPLUS) - # The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} # are archived into debug one image to facilitate debugging. # diff --git a/slave.mk b/slave.mk index f2f2a8605c8b..6080f273b1df 100644 --- a/slave.mk +++ b/slave.mk @@ -34,8 +34,12 @@ endif PYTHON_DEBS_PATH = $(TARGET_PATH)/python-debs PYTHON_WHEELS_PATH = $(TARGET_PATH)/python-wheels PROJECT_ROOT = $(shell pwd) +JESSIE_DEBS_PATH = $(TARGET_PATH)/debs/jessie +JESSIE_FILES_PATH = $(TARGET_PATH)/files/jessie STRETCH_DEBS_PATH = $(TARGET_PATH)/debs/stretch STRETCH_FILES_PATH = $(TARGET_PATH)/files/stretch +BUSTER_DEBS_PATH = $(TARGET_PATH)/debs/buster +BUSTER_FILES_PATH = $(TARGET_PATH)/files/buster DBG_IMAGE_MARK = dbg DBG_SRC_ARCHIVE_FILE = $(TARGET_PATH)/sonic_src.tar.gz @@ -45,12 +49,17 @@ CONFIGURED_ARCH := $(shell [ -f .arch ] && cat .arch || echo amd64) ifeq ($(PLATFORM_ARCH),) override PLATFORM_ARCH = $(CONFIGURED_ARCH) endif +IMAGE_DISTRO := buster +IMAGE_DISTRO_DEBS_PATH = $(TARGET_PATH)/debs/$(IMAGE_DISTRO) +IMAGE_DISTRO_FILES_PATH = $(TARGET_PATH)/files/$(IMAGE_DISTRO) + export BUILD_NUMBER export BUILD_TIMESTAMP export CONFIGURED_PLATFORM export CONFIGURED_ARCH -export STRETCH_DEBS_PATH export PYTHON_WHEELS_PATH +export IMAGE_DISTRO +export IMAGE_DISTRO_DEBS_PATH ############################################################################### ## Utility rules @@ -64,12 +73,16 @@ ifneq ($(CONFIGURED_PLATFORM),generic) endif configure : - @mkdir -p target/debs - @mkdir -p target/debs/stretch - @mkdir -p target/files - @mkdir -p target/files/stretch - @mkdir -p target/python-debs - @mkdir -p target/python-wheels + @mkdir -p $(DEBS_PATH) + @mkdir -p $(JESSIE_DEBS_PATH) + @mkdir -p $(STRETCH_DEBS_PATH) + @mkdir -p $(BUSTER_DEBS_PATH) + @mkdir -p $(FILES_PATH) + @mkdir -p $(JESSIE_FILES_PATH) + @mkdir -p $(STRETCH_FILES_PATH) + @mkdir -p $(BUSTER_FILES_PATH) + @mkdir -p $(PYTHON_DEBS_PATH) + @mkdir -p $(PYTHON_WHEELS_PATH) @echo $(PLATFORM) > .platform @echo $(PLATFORM_ARCH) > .arch @@ -285,7 +298,7 @@ $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) : $(DEBS_PATH)/% : .platform \ $(foreach deb,$* $($*_DERIVED_DEBS), \ { curl -L -f -o $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || { exit 1 ; } } ; ) - + # Save the target deb into DPKG cache $(call SAVE_CACHE,$*,$@) fi @@ -547,7 +560,7 @@ $(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) : $(PYTHON_WHEELS_PA if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then quilt pop -a -f; fi popd $(LOG_SIMPLE) mv $($*_SRC_PATH)/dist/$* $(PYTHON_WHEELS_PATH) $(LOG) - + # Save the target deb into DPKG cache $(call SAVE_CACHE,$*,$@) fi @@ -602,17 +615,32 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) : $(TARGET_PATH)/%.g SONIC_TARGET_LIST += $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) -# Build jessie docker images only in jessie slave docker, -# jessie docker images only in jessie slave docker +DOCKER_IMAGES_FOR_INSTALLERS := $(sort $(foreach installer,$(SONIC_INSTALLERS),$($(installer)_DOCKERS))) + +$(foreach DOCKER_IMAGE,$(SONIC_JESSIE_DOCKERS), $(eval $(DOCKER_IMAGE)_DEBS_PATH := $(JESSIE_DEBS_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_JESSIE_DOCKERS), $(eval $(DOCKER_IMAGE)_FILES_PATH := $(JESSIE_FILES_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_JESSIE_DBG_DOCKERS), $(eval $(DOCKER_IMAGE)_DEBS_PATH := $(JESSIE_DEBS_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_JESSIE_DBG_DOCKERS), $(eval $(DOCKER_IMAGE)_FILES_PATH := $(JESSIE_FILES_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_STRETCH_DOCKERS), $(eval $(DOCKER_IMAGE)_DEBS_PATH := $(STRETCH_DEBS_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_STRETCH_DOCKERS), $(eval $(DOCKER_IMAGE)_FILES_PATH := $(STRETCH_FILES_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_STRETCH_DBG_DOCKERS), $(eval $(DOCKER_IMAGE)_DEBS_PATH := $(STRETCH_DEBS_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_STRETCH_DBG_DOCKERS), $(eval $(DOCKER_IMAGE)_FILES_PATH := $(STRETCH_FILES_PATH))) + ifeq ($(BLDENV),) - DOCKER_IMAGES_FOR_INSTALLERS := $(sort $(foreach installer,$(SONIC_INSTALLERS),$($(installer)_DOCKERS))) DOCKER_IMAGES := $(SONIC_JESSIE_DOCKERS) DOCKER_DBG_IMAGES := $(SONIC_JESSIE_DBG_DOCKERS) - SONIC_JESSIE_DOCKERS_FOR_INSTALLERS = $(filter $(SONIC_JESSIE_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_JESSIE_TARGETS)) - SONIC_JESSIE_DBG_DOCKERS_FOR_INSTALLERS = $(filter $(SONIC_JESSIE_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(SONIC_JESSIE_DOCKERS_FOR_INSTALLERS))) + JESSIE_DOCKER_IMAGES = $(filter $(SONIC_JESSIE_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) + JESSIE_DBG_DOCKER_IMAGES = $(filter $(SONIC_JESSIE_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(JESSIE_DOCKER_IMAGES))) else - DOCKER_IMAGES := $(filter-out $(SONIC_JESSIE_DOCKERS), $(SONIC_DOCKER_IMAGES)) - DOCKER_DBG_IMAGES := $(filter-out $(SONIC_JESSIE_DBG_DOCKERS), $(SONIC_DOCKER_DBG_IMAGES)) +ifeq ($(BLDENV),stretch) + DOCKER_IMAGES := $(SONIC_STRETCH_DOCKERS) + DOCKER_DBG_IMAGES := $(SONIC_STRETCH_DBG_DOCKERS) + STRETCH_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) + STRETCH_DBG_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(STRETCH_DOCKER_IMAGES))) +else + DOCKER_IMAGES := $(SONIC_DOCKER_IMAGES) + DOCKER_DBG_IMAGES := $(SONIC_DOCKER_DBG_IMAGES) +endif endif # Targets for building docker images @@ -638,8 +666,8 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform mkdir -p $($*.gz_PATH)/files $(LOG) mkdir -p $($*.gz_PATH)/python-debs $(LOG) mkdir -p $($*.gz_PATH)/python-wheels $(LOG) - sudo mount --bind $(DEBS_PATH) $($*.gz_PATH)/debs $(LOG) - sudo mount --bind $(FILES_PATH) $($*.gz_PATH)/files $(LOG) + sudo mount --bind $($*.gz_DEBS_PATH) $($*.gz_PATH)/debs $(LOG) + sudo mount --bind $($*.gz_FILES_PATH) $($*.gz_PATH)/files $(LOG) sudo mount --bind $(PYTHON_DEBS_PATH) $($*.gz_PATH)/python-debs $(LOG) sudo mount --bind $(PYTHON_WHEELS_PATH) $($*.gz_PATH)/python-wheels $(LOG) # Export variables for j2. Use path for unique variable names, e.g. docker_orchagent_debs @@ -663,7 +691,7 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform docker save $* | gzip -c > $@ # Clean up if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; popd; fi - + # Save the target deb into DPKG cache $(call SAVE_CACHE,$*.gz,$@) fi @@ -686,7 +714,7 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_DBG_IMAGES)) : $(TARGET_PATH)/%-$(DBG_IMAG if [ -z '$($*-$(DBG_IMAGE_MARK).gz_CACHE_LOADED)' ] ; then mkdir -p $($*.gz_PATH)/debs $(LOG) - sudo mount --bind $(DEBS_PATH) $($*.gz_PATH)/debs $(LOG) + sudo mount --bind $($*.gz_DEBS_PATH) $($*.gz_PATH)/debs $(LOG) # Export variables for j2. Use path for unique variable names, e.g. docker_orchagent_debs $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbg_debs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_DEPENDS),RDEPENDS))\n" | awk '!a[$$0]++')) $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_image_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_IMAGE_PACKAGES)))\n" | awk '!a[$$0]++')) @@ -733,10 +761,10 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ build_debian.sh \ scripts/dbg_files.sh \ build_image.sh \ - $$(addsuffix -install,$$(addprefix $(STRETCH_DEBS_PATH)/,$$($$*_DEPENDS))) \ - $$(addprefix $(STRETCH_DEBS_PATH)/,$$($$*_INSTALLS)) \ - $$(addprefix $(STRETCH_DEBS_PATH)/,$$($$*_LAZY_INSTALLS)) \ - $(addprefix $(STRETCH_DEBS_PATH)/,$(INITRAMFS_TOOLS) \ + $$(addsuffix -install,$$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$$($$*_DEPENDS))) \ + $$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$$($$*_INSTALLS)) \ + $$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$$($$*_LAZY_INSTALLS)) \ + $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(INITRAMFS_TOOLS) \ $(LINUX_KERNEL) \ $(SONIC_DEVICE_DATA) \ $(PYTHON_CLICK) \ @@ -748,7 +776,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(DEBS_PATH)/,$(SONIC_ZTP))) \ - $(addprefix $(STRETCH_FILES_PATH)/, $(if $(filter $(CONFIGURED_ARCH),amd64), $(IXGBE_DRIVER))) \ + $(addprefix $(IMAGE_DISTRO_FILES_PATH)/, $(if $(filter $(CONFIGURED_ARCH),amd64), $(IXGBE_DRIVER))) \ $(addprefix $(PYTHON_DEBS_PATH)/,$(SONIC_UTILS)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ @@ -757,11 +785,11 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) $(HEADER) # Pass initramfs and linux kernel explicitly. They are used for all platforms - export debs_path="$(STRETCH_DEBS_PATH)" + export debs_path="$(IMAGE_DISTRO_DEBS_PATH)" export files_path="$(FILES_PATH)" export python_debs_path="$(PYTHON_DEBS_PATH)" - export initramfs_tools="$(STRETCH_DEBS_PATH)/$(INITRAMFS_TOOLS)" - export linux_kernel="$(STRETCH_DEBS_PATH)/$(LINUX_KERNEL)" + export initramfs_tools="$(IMAGE_DISTRO_DEBS_PATH)/$(INITRAMFS_TOOLS)" + export linux_kernel="$(IMAGE_DISTRO_DEBS_PATH)/$(LINUX_KERNEL)" export onie_recovery_image="$(FILES_PATH)/$(ONIE_RECOVERY_IMAGE)" export kversion="$(KVERSION)" export image_type="$($*_IMAGE_TYPE)" @@ -776,8 +804,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" export install_kubernetes="$(INSTALL_KUBERNETES)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" - export installer_debs="$(addprefix $(STRETCH_DEBS_PATH)/,$($*_INSTALLS))" - export lazy_installer_debs="$(foreach deb, $($*_LAZY_INSTALLS),$(foreach device, $($(deb)_PLATFORM),$(addprefix $(device)@, $(STRETCH_DEBS_PATH)/$(deb))))" + export installer_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($*_INSTALLS))" + export lazy_installer_debs="$(foreach deb, $($*_LAZY_INSTALLS),$(foreach device, $($(deb)_PLATFORM),$(addprefix $(device)@, $(IMAGE_DISTRO_DEBS_PATH)/$(deb))))" export installer_images="$(addprefix $(TARGET_PATH)/,$($*_DOCKERS))" export config_engine_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE))" export swsssdk_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY2))" @@ -832,7 +860,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ ) ) export installer_services="$(SERVICES)" - + export installer_extra_files="$(foreach docker, $($*_DOCKERS), $(foreach file, $($(docker:-dbg.gz=.gz)_BASE_IMAGE_FILES), $($(docker:-dbg.gz=.gz)_PATH)/base_image_files/$(file)))" j2 -f env files/initramfs-tools/union-mount.j2 onie-image.conf > files/initramfs-tools/union-mount @@ -930,12 +958,11 @@ clean :: .platform clean-logs $$(SONIC_CLEAN_DEBS) $$(SONIC_CLEAN_FILES) $$(SONI all : .platform $$(addprefix $(TARGET_PATH)/,$$(SONIC_ALL)) -stretch : $$(addprefix $(DEBS_PATH)/,$$(SONIC_STRETCH_DEBS)) \ - $$(addprefix $(FILES_PATH)/,$$(SONIC_STRETCH_FILES)) \ - $$(addprefix $(TARGET_PATH)/,$$(SONIC_STRETCH_DOCKERS_FOR_INSTALLERS)) \ - $$(addprefix $(TARGET_PATH)/,$$(SONIC_STRETCH_DBG_DOCKERS_FOR_INSTALLERS)) +stretch : $$(addprefix $(TARGET_PATH)/,$$(STRETCH_DOCKER_IMAGES)) \ + $$(addprefix $(TARGET_PATH)/,$$(STRETCH_DBG_DOCKER_IMAGES)) -jessie : $$(addprefix $(TARGET_PATH)/,$$(SONIC_JESSIE_DOCKERS_FOR_INSTALLERS)) +jessie : $$(addprefix $(TARGET_PATH)/,$$(JESSIE_DOCKER_IMAGES)) \ + $$(addprefix $(TARGET_PATH)/,$$(JESSIE_DBG_DOCKER_IMAGES)) ############################################################################### ## Standard targets diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 784194a2ff4d..d614d9bfedfb 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -9,7 +9,7 @@ from sys import exit # find path of pkgs from environment vars -prefix = '../../'; debs = environ["STRETCH_DEBS_PATH"] +prefix = '../../'; debs = environ["IMAGE_DISTRO_DEBS_PATH"] deps_path = '{}/{}'.format(prefix, debs) # dependencies libyang = '{}/{}'.format(deps_path, environ["LIBYANG"]) From 9d6760c336191f7eb4cdba1e0bae06c7b36d51cd Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sun, 2 Feb 2020 20:27:55 +0000 Subject: [PATCH 0533/1427] [kernel]: build linux kernel 4.19.0-6 Signed-off-by: Guohan Lu --- platform/broadcom/sai-modules.mk | 1 - rules/linux-kernel.mk | 8 ++++---- src/sonic-linux-kernel | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index 79fb0102820a..5f48efefa19a 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,6 +1,5 @@ # Broadcom SAI modules -KVERSION = 4.9.0-11-2-amd64 BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb diff --git a/rules/linux-kernel.mk b/rules/linux-kernel.mk index e6742bdf14cf..0b906a2623ba 100644 --- a/rules/linux-kernel.mk +++ b/rules/linux-kernel.mk @@ -1,9 +1,9 @@ # linux kernel package -KVERSION_SHORT = 4.9.0-11-2 +KVERSION_SHORT = 4.19.0-6 KVERSION = $(KVERSION_SHORT)-$(CONFIGURED_ARCH) -KERNEL_VERSION = 4.9.189 -KERNEL_SUBVERSION = 3+deb9u2 +KERNEL_VERSION = 4.19.67 +KERNEL_SUBVERSION = 2+deb10u2 ifeq ($(CONFIGURED_ARCH), armhf) # Override kernel version for ARMHF as it uses arm MP (multi-platform) for short version KVERSION = $(KVERSION_SHORT)-armmp @@ -18,5 +18,5 @@ SONIC_MAKE_DEBS += $(LINUX_HEADERS_COMMON) LINUX_HEADERS = linux-headers-$(KVERSION)_$(KERNEL_VERSION)-$(KERNEL_SUBVERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LINUX_HEADERS_COMMON),$(LINUX_HEADERS))) -LINUX_KERNEL = linux-image-$(KVERSION)_$(KERNEL_VERSION)-$(KERNEL_SUBVERSION)_$(CONFIGURED_ARCH).deb +LINUX_KERNEL = linux-image-$(KVERSION)-unsigned_$(KERNEL_VERSION)-$(KERNEL_SUBVERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LINUX_HEADERS_COMMON),$(LINUX_KERNEL))) diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 32963dab6b6e..187bb4aa046c 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 32963dab6b6ea9f9fbda9b2b49a77574453fb8ef +Subproject commit 187bb4aa046c26f2fe508e71dc74c230d316838b From 7f7212d8a8fb2f5ce8b05f391a10e61e30d69fed Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sun, 2 Feb 2020 22:56:10 +0000 Subject: [PATCH 0534/1427] [broadcom]: build opennsl-modules for kernel 4.19.0-6 Signed-off-by: Guohan Lu --- platform/broadcom/saibcm-modules/debian/control | 2 +- .../saibcm-modules/debian/opennsl-modules.dirs | 2 +- .../debian/opennsl-modules.install | 10 +++++----- platform/broadcom/saibcm-modules/debian/rules | 16 +++++++++++++--- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/platform/broadcom/saibcm-modules/debian/control b/platform/broadcom/saibcm-modules/debian/control index fafe7dfb9299..eca9977fcd92 100644 --- a/platform/broadcom/saibcm-modules/debian/control +++ b/platform/broadcom/saibcm-modules/debian/control @@ -10,5 +10,5 @@ Standards-Version: 3.9.3 Package: opennsl-modules Architecture: amd64 Section: main -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for broadcom SAI diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs index a32540eadcf5..fe56bc4cf388 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs @@ -1 +1 @@ -lib/modules/4.9.0-11-2-amd64/extra +lib/modules/4.19.0-6-amd64/extra diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index 9802d2f2443a..6d1ffa2fc51e 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -1,6 +1,6 @@ -systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-11-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.9.0-11-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.9.0-11-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.9.0-11-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.19.0-6-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.19.0-6-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.19.0-6-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.19.0-6-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.19.0-6-amd64/extra systemd/opennsl-modules.service lib/systemd/system diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index 636874251aa9..a22bcc4ac6ff 100755 --- a/platform/broadcom/saibcm-modules/debian/rules +++ b/platform/broadcom/saibcm-modules/debian/rules @@ -34,6 +34,7 @@ sname:=opennsl PACKAGE=opennsl-modules # modifieable for experiments or debugging m-a MA_DIR ?= /usr/share/modass +KVERSION ?= 4.19.0-6-amd64 # load generic variable handling -include $(MA_DIR)/include/generic.make # load default rules, including kdist, kdist_image, ... @@ -60,7 +61,10 @@ kdist_config: prep-deb-files kdist_clean: clean dh_testdir dh_clean - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ + KERNDIR=/usr/src/linux-headers-$(KVERSION) \ + KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean # rm -f driver/*.o driver/*.ko # ### end KERNEL SETUP @@ -78,7 +82,10 @@ build-arch-stamp: dh_testdir # Add here command to compile/build the package. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ + KERNDIR=/usr/src/linux-headers-$(KVERSION) \ + KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 touch $@ @@ -103,7 +110,10 @@ clean: rm -f build-arch-stamp build-indep-stamp configure-stamp # Add here commands to clean up after the build process. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ + KERNDIR=/usr/src/linux-headers-$(KVERSION) \ + KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean dh_clean From 6df0e4be0ad0f56ab519b2fdabd5bfdbb68f462f Mon Sep 17 00:00:00 2001 From: "Sheng-Chien, Cheng" <50431361+BrandonCheng0121@users.noreply.github.com> Date: Fri, 17 Apr 2020 05:43:40 +0800 Subject: [PATCH 0535/1427] Correct port mapping. (#4433) --- .../Accton-AS6712-32X/port_config.ini | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/port_config.ini b/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/port_config.ini index 36067bddc1d0..5ad503c619df 100755 --- a/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/port_config.ini +++ b/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/port_config.ini @@ -1,33 +1,33 @@ # name lanes alias index speed -Ethernet0 49,50,51,52 fortyGigE1 1 40000 -Ethernet4 53,54,55,56 fortyGigE2 2 40000 -Ethernet8 57,58,59,60 fortyGigE3 3 40000 -Ethernet12 61,62,63,64 fortyGigE4 4 40000 -Ethernet16 65,66,67,68 fortyGigE5 5 40000 -Ethernet20 69,70,71,72 fortyGigE6 6 40000 -Ethernet24 73,74,75,76 fortyGigE7 7 40000 -Ethernet28 77,78,79,80 fortyGigE8 8 40000 +Ethernet0 1,2,3,4 fortyGigE1 1 40000 +Ethernet4 5,6,7,8 fortyGigE2 2 40000 +Ethernet8 9,10,11,12 fortyGigE3 3 40000 +Ethernet12 13,14,15,16 fortyGigE4 4 40000 +Ethernet16 17,18,19,20 fortyGigE5 5 40000 +Ethernet20 21,22,23,24 fortyGigE6 6 40000 +Ethernet24 25,26,27,28 fortyGigE7 7 40000 +Ethernet28 29,30,31,32 fortyGigE8 8 40000 Ethernet32 33,34,35,36 fortyGigE9 9 40000 Ethernet36 37,38,39,40 fortyGigE10 10 40000 Ethernet40 41,42,43,44 fortyGigE11 11 40000 Ethernet44 45,46,47,48 fortyGigE12 12 40000 -Ethernet48 81,82,83,84 fortyGigE13 13 40000 -Ethernet52 85,86,87,88 fortyGigE14 14 40000 -Ethernet56 89,90,91,92 fortyGigE15 15 40000 -Ethernet60 93,94,95,96 fortyGigE16 16 40000 -Ethernet64 97,98,99,100 fortyGigE17 17 40000 -Ethernet68 101,102,103,104 fortyGigE18 18 40000 -Ethernet72 105,106,107,108 fortyGigE19 19 40000 -Ethernet76 109,110,111,112 fortyGigE20 20 40000 -Ethernet80 17,18,19,20 fortyGigE21 21 40000 -Ethernet84 21,22,23,24 fortyGigE22 22 40000 -Ethernet88 25,26,27,28 fortyGigE23 23 40000 -Ethernet92 29,30,31,32 fortyGigE24 24 40000 -Ethernet96 113,114,115,116 fortyGigE25 25 40000 -Ethernet100 117,118,119,120 fortyGigE26 26 40000 -Ethernet104 121,122,123,124 fortyGigE27 27 40000 -Ethernet108 125,126,127,128 fortyGigE28 28 40000 -Ethernet112 1,2,3,4 fortyGigE29 29 40000 -Ethernet116 5,6,7,8 fortyGigE30 30 40000 -Ethernet120 9,10,11,12 fortyGigE31 31 40000 -Ethernet124 13,14,15,16 fortyGigE32 32 40000 +Ethernet48 49,50,51,52 fortyGigE13 13 40000 +Ethernet52 53,54,55,56 fortyGigE14 14 40000 +Ethernet56 57,58,59,60 fortyGigE15 15 40000 +Ethernet60 61,62,63,64 fortyGigE16 16 40000 +Ethernet64 65,66,67,68 fortyGigE17 17 40000 +Ethernet68 69,70,71,72 fortyGigE18 18 40000 +Ethernet72 73,74,75,76 fortyGigE19 19 40000 +Ethernet76 77,78,79,80 fortyGigE20 20 40000 +Ethernet80 81,82,83,84 fortyGigE21 21 40000 +Ethernet84 85,86,87,88 fortyGigE22 22 40000 +Ethernet88 89,90,91,92 fortyGigE23 23 40000 +Ethernet92 93,94,95,96 fortyGigE24 24 40000 +Ethernet96 97,98,99,100 fortyGigE25 25 40000 +Ethernet100 101,102,103,104 fortyGigE26 26 40000 +Ethernet104 105,106,107,108 fortyGigE27 27 40000 +Ethernet108 109,110,111,112 fortyGigE28 28 40000 +Ethernet112 113,114,115,116 fortyGigE29 29 40000 +Ethernet116 117,118,119,120 fortyGigE30 30 40000 +Ethernet120 121,122,123,124 fortyGigE31 31 40000 +Ethernet124 125,126,127,128 fortyGigE32 32 40000 From 207e32a9f2795aaec2e1ca0f9ec8391912ecfbe3 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 3 Feb 2020 01:01:10 +0000 Subject: [PATCH 0536/1427] [platform-modules]: fix compile issues for platform driver under 4.19 1. undefine led_classdev_register as it is defined in leds.h 2. header file location change a. linux/i2c/pmbus.h -> linux/pmbus.h b. linux/i2c-mux-gpio.h -> linux/platform_data/i2c-mux-gpio.h c. linux/i2c/pca954x.h -> linux/platform_data/pca954x.h --- .../as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c | 1 + .../as5712-54x/modules/leds-accton_as5712_54x.c | 1 - .../as5812-54x/modules/leds-accton_as5812_54x.c | 1 - .../as6712-32x/modules/leds-accton_as6712_32x.c | 1 - .../as7312-54x/modules/accton_as7312_54x_leds.c | 1 - .../as7312-54xs/modules/accton_as7312_54x_leds.c | 1 - .../as7326-56x/modules/accton_as7326_56x_leds.c | 1 - .../as7712-32x/modules/leds-accton_as7712_32x.c | 1 - .../as7716-32x/modules/accton_as7716_32x_leds.c | 1 - .../as7716-32xb/modules/accton_as7716_32xb_leds.c | 1 - .../as7726-32x/modules/accton_as7726_32x_leds.c | 1 - .../as7816-64x/modules/x86-64-accton-as7816-64x-leds.c | 1 - .../common/modules/accton_pmbus_3y.c | 2 +- .../haliburton/modules/dps200.c | 2 +- .../s6000/modules/dell_s6000_platform.c | 2 +- .../z9332f/modules/cls-switchboard.c | 2 +- .../ag5648/modules/delta_ag5648_platform.c | 4 ++-- .../ag9032v1/modules/delta_ag9032v1_platform.c | 4 ++-- .../ag9032v2a/modules/delta_ag9032v2a_platform.c | 2 +- .../ag9064/modules/delta_ag9064_platform.c | 4 ++-- .../ag9064/modules/i2c-mei_main.c | 2 +- .../et-6248brb/modules/delta_et-6248brb_platform.c | 4 ++-- .../s8900-64xc/modules/qsfp_cpld.c | 2 +- .../s9200-64x/modules/cpld.c | 2 +- .../d6254qs/modules/inv_platform.c | 4 ++-- .../d6356/modules/i2c-mux-pca9541.c | 2 +- .../d6356/modules/inv_platform.c | 4 ++-- .../d6356/modules/ucd9000.c | 2 +- .../d6556/modules/inv_platform.c | 4 ++-- .../d7032q28b/modules/inv_platform.c | 4 ++-- .../d7054q28b/modules/inv_platform.c | 4 ++-- .../d7264q28b/modules/inv_platform.c | 4 ++-- .../qfx5200/modules/jnx-refpga-lpcm.c | 9 +++++---- .../qfx5210/modules/x86-64-juniper-qfx5210-64x-leds.c | 1 - .../ly1200-32x/modules/mitac_ly1200_32x_fse000.c | 2 +- .../ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c | 2 +- .../ix1b-32x/modules/qci_platform_ix1b.c | 2 +- .../ix7-32x/modules/quanta_platform_ix7.c | 2 +- .../ix8-56x/modules/qci_platform_ix8.c | 2 +- .../ix8c-56x/modules/qci_platform_ix8c.c | 2 +- .../ix9-32x/modules/qci_platform_ix9.c | 2 +- .../48x2q4z/modules/centec_e582_48x2q4z_platform.c | 2 +- .../48x6q/modules/centec_e582_48x6q_platform.c | 2 +- .../et-c032if/modules/delta_et-c032if_platform.c | 4 ++-- .../cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c | 1 - 45 files changed, 47 insertions(+), 58 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c index 5e25e824d418..d1205516ef53 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c @@ -36,6 +36,7 @@ #include #include #include +#include #include diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c index cdea927368ae..36988aecfc49 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c @@ -34,7 +34,6 @@ extern int as5712_54x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c index 2ebe948612c2..430a16db11e1 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c @@ -34,7 +34,6 @@ extern int as5812_54x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/modules/leds-accton_as6712_32x.c b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/modules/leds-accton_as6712_32x.c index 2b45bc8777c8..6e5c1d2118e4 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/modules/leds-accton_as6712_32x.c +++ b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/modules/leds-accton_as6712_32x.c @@ -33,7 +33,6 @@ extern int as6712_32x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as6712_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c index 1d54517c6243..f53716440107 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c @@ -34,7 +34,6 @@ extern int as7312_54x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as7312_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/modules/accton_as7312_54x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/modules/accton_as7312_54x_leds.c index 1d54517c6243..f53716440107 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/modules/accton_as7312_54x_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/modules/accton_as7312_54x_leds.c @@ -34,7 +34,6 @@ extern int as7312_54x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as7312_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c index 4cb7f1fa25a5..54df5b09eea8 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c @@ -34,7 +34,6 @@ extern int as7326_56x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as7326_56x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c index 5e1a9282db0e..a3238d4b1615 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c @@ -34,7 +34,6 @@ extern int accton_i2c_cpld_read (unsigned short cpld_addr, u8 reg); extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c index da3d9442035f..cb08189e3360 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c @@ -34,7 +34,6 @@ extern int as7716_32x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as7716_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c index 2fa3fd722cb1..4e2162843a9e 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c @@ -31,7 +31,6 @@ #include extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_leds.c index 65b962e628cc..c179fd855bd2 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_leds.c @@ -34,7 +34,6 @@ extern int as7726_32x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as7726_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c index 025f87d692a3..3102e968c93f 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c @@ -34,7 +34,6 @@ extern int accton_i2c_cpld_read (u8 cpld_addr, u8 reg); extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c index ed176189cdcd..76ac4368a8d4 100644 --- a/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "pmbus.h" diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c index 6d5afdfb78b0..6279ca70decf 100644 --- a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include "pmbus.h" diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c b/platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c index e8bcd312168f..cbf506940ac9 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c index 240580e577a3..dc1cf8874e39 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include "cls-i2c-ocore.h" #define MOD_VERSION "2.1.0-1" diff --git a/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c index 16b9ba2fbc4c..1ebcaa39d026 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c @@ -9,9 +9,9 @@ #include #include #include -#include +#include #include -#include +#include #include #define BUS4_DEV_NUM 54 diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c index 9b7a1958c77a..70cd8b581df4 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c @@ -9,9 +9,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c index 85719af7ea94..5345ae86e7f9 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c index 4de9799d4601..bdf4f1e07e3d 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c @@ -3,9 +3,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c index a5dbbd22b4a5..811877fa8ead 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c @@ -28,7 +28,7 @@ #if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ defined CONFIG_DMI #include -#include +#include #endif /* PCI Address Constants */ diff --git a/platform/broadcom/sonic-platform-modules-delta/et-6248brb/modules/delta_et-6248brb_platform.c b/platform/broadcom/sonic-platform-modules-delta/et-6248brb/modules/delta_et-6248brb_platform.c index 72fccd9aa0e8..7cbe161e62b2 100644 --- a/platform/broadcom/sonic-platform-modules-delta/et-6248brb/modules/delta_et-6248brb_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/et-6248brb/modules/delta_et-6248brb_platform.c @@ -9,11 +9,11 @@ #include #include #include -#include +#include #include #include -#include +#include #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c index 8ec03ecea340..66ae8d558507 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c index 7b16f5d3e321..b15ee836b187 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6254qs/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d6254qs/modules/inv_platform.c index e69b526f4555..e6cb4c3d173d 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6254qs/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6254qs/modules/inv_platform.c @@ -6,13 +6,13 @@ */ #include -#include +#include #include #include #include #include -#include +#include struct inv_i2c_board_info { int ch; diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c index 68c44dbc533f..fa78379858e3 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c @@ -24,7 +24,7 @@ #include #include -#include +#include /* * The PCA9541 is a bus master selector. It supports two I2C masters connected diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c index 212388c8e98d..811ed5e18e58 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c @@ -1,11 +1,11 @@ #include -#include +#include #include #include #include #include #include -#include +#include struct inv_i2c_board_info { int ch; diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c index 3e3aa950277f..5beba343b327 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include "pmbus.h" enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 }; diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6556/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d6556/modules/inv_platform.c index 26bd47300dab..ba11c275ce81 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6556/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6556/modules/inv_platform.c @@ -5,13 +5,13 @@ * (at your option) any later version. */ #include -#include +#include #include #include #include #include #include -#include +#include struct inv_i2c_board_info { int ch; diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7032q28b/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d7032q28b/modules/inv_platform.c index 52f6a5691d3e..6a2c7353228d 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d7032q28b/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d7032q28b/modules/inv_platform.c @@ -1,12 +1,12 @@ #include //#include -#include +#include #include #include #include #include -#include +#include #include #include diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/modules/inv_platform.c index ea26970075b0..5988bb55a434 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/modules/inv_platform.c @@ -1,12 +1,12 @@ #include //#include -#include +#include #include #include #include #include -#include +#include //#include //#include diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7264q28b/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d7264q28b/modules/inv_platform.c index 720a4cd2257b..753f8cd3407d 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d7264q28b/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d7264q28b/modules/inv_platform.c @@ -1,12 +1,12 @@ #include //#include -#include +#include #include #include #include #include #include -#include +#include //#include //#include diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c index 15972b376298..26e8b06db3aa 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c @@ -22,6 +22,7 @@ #include #include #include +#include #define REFPGA_LPC_BASE_ADDRESS 0xFED50000 #define REFPGA_LPC_WINDOW_SIZE 0x00000400 @@ -68,10 +69,10 @@ static int __init refpga_lpcm_init(void) u8 minor_version = 0x00; if (!request_mem_region(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE, "refpga-lpc")) { - printk(KERN_ERR "Cannot allocate Re-fpga memory region\n"); + printk(KERN_ERR "Cannot allocate Re-fpga memory region\n"); return -ENODEV; } - + if ((fpga = ioremap(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE)) == NULL) { release_mem_region(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE); printk(KERN_ERR "Re-Fpga address mapping failed\n"); @@ -81,14 +82,14 @@ static int __init refpga_lpcm_init(void) major_version = ioread8((u8 *)fpga + REFPGA_MAJOR_VERSION); minor_version = ioread8((u8 *)fpga + REFPGA_MINOR_VERSION); printk(KERN_INFO "Re-Fpga major version: %x minor version: %x\n", major_version, minor_version); - + /* * Register the cpld soft reset handler */ if(register_reboot_notifier(&qfx5200_nb)) { printk(KERN_ALERT "Restart handler registration failed\n"); } - + iowrite8(REFPGA_MGMT1_PHY_RESET, (u8 *)fpga + REFPGA_MRE_LPCM_RST_CTL_REG); return 0; diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-leds.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-leds.c index 66d097734392..51ce772c5e80 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-leds.c +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-leds.c @@ -37,7 +37,6 @@ extern int juniper_i2c_cpld_read (u8 cpld_addr, u8 reg); extern int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c index 362821706857..69d8c53cd0a9 100644 --- a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include "pmbus.h" #include diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c index e2a9718863ff..6389229581bc 100644 --- a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include "bms_i2c.h" diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c index 925b46256cea..b3e955217a01 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #if LINUX_VERSION_CODE > KERNEL_VERSION(3,12,0) #include #else diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c index a2a0af63af7d..a6e5733199ac 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) #include #else diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c index 26151b0ab24f..d35a56641e38 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) #include #else diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c index f69d3879efb5..f389304a2fbd 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) #include #else diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c index a927e850791f..1b98c4a2f31f 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #if LINUX_VERSION_CODE > KERNEL_VERSION(3,12,0) #include #else diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c index 16bed86593b2..7ad859c6a6e7 100644 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c b/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c index 6ef18ca62f41..f72efee2a0d6 100644 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c +++ b/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/platform/innovium/sonic-platform-modules-delta/et-c032if/modules/delta_et-c032if_platform.c b/platform/innovium/sonic-platform-modules-delta/et-c032if/modules/delta_et-c032if_platform.c index d4e23a166e88..2e9db4278294 100644 --- a/platform/innovium/sonic-platform-modules-delta/et-c032if/modules/delta_et-c032if_platform.c +++ b/platform/innovium/sonic-platform-modules-delta/et-c032if/modules/delta_et-c032if_platform.c @@ -9,9 +9,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c index 4c7c629f3e7b..2f442bac2603 100644 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c @@ -35,7 +35,6 @@ extern int cig_cpld_write_register(u8 reg_off, u8 val); extern int cig_cpld_read_register(u8 reg_off, u8 *val); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); From 4e07c7880a1519643fa86ac566663fd44c6c7b9a Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 3 Feb 2020 08:44:44 +0000 Subject: [PATCH 0537/1427] [baseimage]: update python-click to 7.0-1 to support python3 Signed-off-by: Guohan Lu --- rules/python-click.mk | 3 +-- sonic-slave-buster/Dockerfile.j2 | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/python-click.mk b/rules/python-click.mk index 5d48dc30d604..59e22b371159 100644 --- a/rules/python-click.mk +++ b/rules/python-click.mk @@ -7,11 +7,10 @@ # TODO: If we upgrade to a distro which provides a version >= 6.7 we will no # longer need to build this. -PYTHON_CLICK_VERSION = 6.7-4 +PYTHON_CLICK_VERSION = 7.0-1 export PYTHON_CLICK_VERSION PYTHON_CLICK = python-click_$(PYTHON_CLICK_VERSION)_all.deb $(PYTHON_CLICK)_SRC_PATH = $(SRC_PATH)/python-click SONIC_MAKE_DEBS += $(PYTHON_CLICK) -SONIC_STRETCH_DEBS += $(PYTHON_CLICK) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index c010a4980438..b2b574ec56f9 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -266,6 +266,7 @@ RUN apt-get update && apt-get install -y \ iproute2 \ # For python-click build python-sphinx \ + python3-pallets-sphinx-themes \ python-docutils \ python3-all \ python3-setuptools \ From fc0d4d1bab1403775f5fc3f21b5279a053a9a41c Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 3 Feb 2020 11:31:04 +0000 Subject: [PATCH 0538/1427] [build]: setup correct debs files dependency for docker targets Signed-off-by: Guohan Lu --- slave.mk | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/slave.mk b/slave.mk index 6080f273b1df..a2378462ecd5 100644 --- a/slave.mk +++ b/slave.mk @@ -643,10 +643,15 @@ else endif endif +$(foreach IMAGE,$(SONIC_STRETCH_DOCKERS), $(eval $(IMAGE)_DEBS_PATH := $(STRETCH_DEBS_PATH))) +$(foreach IMAGE,$(SONIC_STRETCH_DOCKERS), $(eval $(IMAGE)_FILES_PATH := $(STRETCH_FILES_PATH))) +$(foreach IMAGE,$(SONIC_STRETCH_DBG_DOCKERS), $(eval $(IMAGE)_DEBS_PATH := $(STRETCH_DEBS_PATH))) +$(foreach IMAGE,$(SONIC_STRETCH_DBG_DOCKERS), $(eval $(IMAGE)_FILES_PATH := $(STRETCH_FILES_PATH))) + # Targets for building docker images $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform docker-start \ - $$(addprefix $(DEBS_PATH)/,$$($$*.gz_DEPENDS)) \ - $$(addprefix $(FILES_PATH)/,$$($$*.gz_FILES)) \ + $$(addprefix $$($$*.gz_DEBS_PATH)/,$$($$*.gz_DEPENDS)) \ + $$(addprefix $$($$*.gz_FILES_PATH)/,$$($$*.gz_FILES)) \ $$(addprefix $(PYTHON_DEBS_PATH)/,$$($$*.gz_PYTHON_DEBS)) \ $$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*.gz_PYTHON_WHEELS)) \ $$(addsuffix -load,$$(addprefix $(TARGET_PATH)/,$$($$*.gz_LOAD_DOCKERS))) \ @@ -702,7 +707,7 @@ SONIC_TARGET_LIST += $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) # Targets for building docker images $(addprefix $(TARGET_PATH)/, $(DOCKER_DBG_IMAGES)) : $(TARGET_PATH)/%-$(DBG_IMAGE_MARK).gz : .platform docker-start \ - $$(addprefix $(DEBS_PATH)/,$$($$*.gz_DBG_DEPENDS)) \ + $$(addprefix $$($$*.gz_DEBS_PATH)/,$$($$*.gz_DBG_DEPENDS)) \ $$(addsuffix -load,$$(addprefix $(TARGET_PATH)/,$$*.gz)) \ $(call dpkg_depend,$(TARGET_PATH)/%-$(DBG_IMAGE_MARK).gz.dep) $(HEADER) @@ -775,7 +780,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(MONIT)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ - $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(DEBS_PATH)/,$(SONIC_ZTP))) \ + $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \ $(addprefix $(IMAGE_DISTRO_FILES_PATH)/, $(if $(filter $(CONFIGURED_ARCH),amd64), $(IXGBE_DRIVER))) \ $(addprefix $(PYTHON_DEBS_PATH)/,$(SONIC_UTILS)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ From 67cc385e3667492f11645b0e2a789b9bea3762ee Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 3 Feb 2020 11:42:13 +0000 Subject: [PATCH 0539/1427] [baseimage]: remove ixgbe.ko as 4.19 has new ixgbe driver Signed-off-by: Guohan Lu --- build_debian.sh | 5 ----- slave.mk | 1 - 2 files changed, 6 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 6981f698a1d8..f1e8a2eb616b 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -184,11 +184,6 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then cat files/initramfs-tools/modules.arm | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null fi -if [[ $CONFIGURED_ARCH == amd64 ]]; then - ## Install latest intel ixgbe driver - sudo cp $files_path/ixgbe.ko $FILESYSTEM_ROOT/lib/modules/${LINUX_KERNEL_VERSION}-amd64/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko -fi - ## Install docker echo '[INFO] Install docker' ## Install apparmor utils since they're missing and apparmor is enabled in the kernel diff --git a/slave.mk b/slave.mk index a2378462ecd5..098a5f12f064 100644 --- a/slave.mk +++ b/slave.mk @@ -781,7 +781,6 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \ - $(addprefix $(IMAGE_DISTRO_FILES_PATH)/, $(if $(filter $(CONFIGURED_ARCH),amd64), $(IXGBE_DRIVER))) \ $(addprefix $(PYTHON_DEBS_PATH)/,$(SONIC_UTILS)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ From fb12b0a6216bf09af60ec870013ac953f26550c1 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 3 Feb 2020 20:31:40 +0000 Subject: [PATCH 0540/1427] [baseimage]: various fixes due to buster changes do mount/umount in the chroot environment install cron explicitly install rasdaemon as a replacement for mcelog switch python package docker-py to docker --- build_debian.sh | 25 ++++++++----------- .../build_templates/sonic_debian_extension.j2 | 6 ++--- ...ian_archive_trafficmanager_net_debian.list | 6 ++--- ...ackages_microsoft_com_repos_sonic_dev.list | 1 - 4 files changed, 16 insertions(+), 22 deletions(-) delete mode 100644 files/image_config/apt/sources.list.d/amd64/packages_microsoft_com_repos_sonic_dev.list diff --git a/build_debian.sh b/build_debian.sh index f1e8a2eb616b..227b3f3c84f9 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -98,12 +98,12 @@ sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c 'echo "sysfs /sys sysfs default ## Setup proxy [ -n "$http_proxy" ] && sudo /bin/bash -c "echo 'Acquire::http::Proxy \"$http_proxy\";' > $FILESYSTEM_ROOT/etc/apt/apt.conf.d/01proxy" +trap_push 'sudo LANG=C chroot $FILESYSTEM_ROOT umount /proc || true' +sudo LANG=C chroot $FILESYSTEM_ROOT mount proc /proc -t proc ## Note: mounting is necessary to makedev and install linux image echo '[INFO] Mount all' ## Output all the mounted device for troubleshooting -mount -trap_push 'sudo umount $FILESYSTEM_ROOT/proc || true' -sudo LANG=C chroot $FILESYSTEM_ROOT mount proc /proc -t proc +sudo LANG=C chroot $FILESYSTEM_ROOT mount ## Pointing apt to public apt mirrors and getting latest packages, needed for latest security updates sudo cp files/apt/sources.list.$CONFIGURED_ARCH $FILESYSTEM_ROOT/etc/apt/sources.list @@ -198,7 +198,7 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -o /tmp/docker sudo LANG=C chroot $FILESYSTEM_ROOT apt-key add /tmp/docker.gpg sudo LANG=C chroot $FILESYSTEM_ROOT rm /tmp/docker.gpg sudo LANG=C chroot $FILESYSTEM_ROOT add-apt-repository \ - "$deb [arch=$CONFIGURED_ARCH] https://download.docker.com/linux/debian $IMAGE_DISTRO stable" + "deb [arch=$CONFIGURED_ARCH] https://download.docker.com/linux/debian $IMAGE_DISTRO stable" sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} docker-ce-cli=${DOCKER_VERSION} sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 @@ -293,14 +293,15 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in makedumpfile \ conntrack \ python-pip \ - python3-pip + python3-pip \ + cron if [[ $CONFIGURED_ARCH == amd64 ]]; then ## Pre-install the fundamental packages for amd64 (x86) sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ flashrom \ - mcelog + rasdaemon fi ## Set /etc/shadow permissions to -rw-------. @@ -420,14 +421,8 @@ set /files/etc/sysctl.conf/net.core.somaxconn 512 " -r $FILESYSTEM_ROOT -if [[ $CONFIGURED_ARCH == amd64 ]]; then - # Configure mcelog to log machine checks to syslog - sudo sed -i 's/^#syslog = yes/syslog = yes/' $FILESYSTEM_ROOT/etc/mcelog/mcelog.conf -fi - -## docker-py is needed by Ansible docker module -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT easy_install pip -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install 'docker-py==1.6.0' +## docker Python API package is needed by Ansible docker module +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install 'docker==4.1.0' ## Note: keep pip installed for maintainance purpose ## Get gcc and python dev pkgs @@ -554,7 +549,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT fuser -vm /proc sudo LANG=C chroot $FILESYSTEM_ROOT fuser -km /proc || true ## Wait fuser fully kill the processes sleep 15 -sudo umount $FILESYSTEM_ROOT/proc || true +sudo LANG=C chroot $FILESYSTEM_ROOT umount /proc || true if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then # Remove qemu arm bin executable used for cross-building diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index ba9595896022..aa6373994e37 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -42,9 +42,9 @@ FILESYSTEM_ROOT_ETC_SONIC="$FILESYSTEM_ROOT_ETC/sonic" GENERATED_SERVICE_FILE="$FILESYSTEM_ROOT/etc/sonic/generated_services.conf" clean_sys() { - sudo umount $FILESYSTEM_ROOT/sys/fs/cgroup/* \ - $FILESYSTEM_ROOT/sys/fs/cgroup \ - $FILESYSTEM_ROOT/sys || true + sudo chroot $FILESYSTEM_ROOT umount /sys/fs/cgroup/* \ + /sys/fs/cgroup \ + /sys || true } trap_push clean_sys sudo LANG=C chroot $FILESYSTEM_ROOT mount sysfs /sys -t sysfs diff --git a/files/image_config/apt/sources.list.d/amd64/debian_archive_trafficmanager_net_debian.list b/files/image_config/apt/sources.list.d/amd64/debian_archive_trafficmanager_net_debian.list index a6a2c2afc607..d35c618112bb 100644 --- a/files/image_config/apt/sources.list.d/amd64/debian_archive_trafficmanager_net_debian.list +++ b/files/image_config/apt/sources.list.d/amd64/debian_archive_trafficmanager_net_debian.list @@ -1,3 +1,3 @@ -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch-backports main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster-backports main contrib non-free diff --git a/files/image_config/apt/sources.list.d/amd64/packages_microsoft_com_repos_sonic_dev.list b/files/image_config/apt/sources.list.d/amd64/packages_microsoft_com_repos_sonic_dev.list deleted file mode 100644 index 468dcccc6eec..000000000000 --- a/files/image_config/apt/sources.list.d/amd64/packages_microsoft_com_repos_sonic_dev.list +++ /dev/null @@ -1 +0,0 @@ -deb [arch=amd64] http://packages.microsoft.com/repos/sonic-dev/ jessie main From e479a56db3d802d4d160e3aea0ccd47f689f4855 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Tue, 4 Feb 2020 01:46:52 +0000 Subject: [PATCH 0541/1427] [baseimage]: setup ebtables.service in buster image ebtables is not enabled by default in buster Signed-off-by: Guohan Lu --- build_debian.sh | 6 +- files/image_config/ebtables/ebtables.default | 35 ++++ files/image_config/ebtables/ebtables.init | 175 +++++++++++++++++++ files/image_config/ebtables/ebtables.service | 19 ++ 4 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 files/image_config/ebtables/ebtables.default create mode 100755 files/image_config/ebtables/ebtables.init create mode 100644 files/image_config/ebtables/ebtables.service diff --git a/build_debian.sh b/build_debian.sh index 227b3f3c84f9..b6e5f86a5bb9 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -487,8 +487,12 @@ if [ "${enable_organization_extensions}" = "y" ]; then fi ## Setup ebtable rules (rule file is in binary format) -sudo sed -i 's/EBTABLES_LOAD_ON_START="no"/EBTABLES_LOAD_ON_START="yes"/g' ${FILESYSTEM_ROOT}/etc/default/ebtables +sudo cp -f files/image_config/ebtables/ebtables.default $FILESYSTEM_ROOT/etc/default/ebtables +sudo cp -f files/image_config/ebtables/ebtables.init $FILESYSTEM_ROOT/etc/init.d/ebtables +sudo cp -f files/image_config/ebtables/ebtables.service $FILESYSTEM_ROOT/lib/systemd/system/ebtables.service sudo cp files/image_config/ebtables/ebtables.filter ${FILESYSTEM_ROOT}/etc +sudo LANG=C chroot $FILESYSTEM_ROOT update-alternatives --set ebtables /usr/sbin/ebtables-legacy +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable ebtables.service ## Debug Image specific changes ## Update motd for debug image diff --git a/files/image_config/ebtables/ebtables.default b/files/image_config/ebtables/ebtables.default new file mode 100644 index 000000000000..93706fe56257 --- /dev/null +++ b/files/image_config/ebtables/ebtables.default @@ -0,0 +1,35 @@ +# Unload modules on restart and stop +# Value: yes|no, default: yes +# This option has to be 'yes' to get to a sane state for a firewall +# restart or stop. Only set to 'no' if there are problems unloading netfilter +# modules. +EBTABLES_MODULES_UNLOAD="yes" + +# Load firewall rules on system startup. +# Value: yes|no, default: no +# Restores the ebtables rulesets from the last saved state when the +# system boots up. +EBTABLES_LOAD_ON_START="yes" + +# Save current firewall rules on stop. +# Value: yes|no, default: no +# Saves all firewall rules if firewall gets stopped +# (e.g. on system shutdown). +EBTABLES_SAVE_ON_STOP="no" + +# Save current firewall rules on restart. +# Value: yes|no, default: no +# Saves all firewall rules if firewall gets restarted. +EBTABLES_SAVE_ON_RESTART="no" + +# Save (and restore) rule counters. +# Value: yes|no, default: no +# Save rule counters when saving a kernel table to a file. If the +# rule counters were saved, they will be restored when restoring the table. +EBTABLES_SAVE_COUNTER="no" + +# Backup suffix for ruleset save files. +# Value: , default: "~" +# Keep one backup level of saved rules. +# Set this variable to the empty string to disable backups. +EBTABLES_BACKUP_SUFFIX="~" diff --git a/files/image_config/ebtables/ebtables.init b/files/image_config/ebtables/ebtables.init new file mode 100755 index 000000000000..12182902319c --- /dev/null +++ b/files/image_config/ebtables/ebtables.init @@ -0,0 +1,175 @@ +#!/bin/bash +# +# init script for the Ethernet Bridge filter tables +# +# Written by Dag Wieers +# Modified by Rok Papez +# Bart De Schuymer +# Adapted to Debian by Jan Christoph Nordholz +# +# chkconfig: - 15 85 +# description: Ethernet Bridge filtering tables +# +### BEGIN INIT INFO +# Provides: ebtables +# Required-Start: +# Required-Stop: +# Should-Start: $local_fs +# Should-Stop: $local_fs +# Default-Start: S +# Default-Stop: 0 1 6 +# Short-Description: ebtables ruleset management +# Description: Saves and restores the state of the ebtables rulesets. +### END INIT INFO + +. /lib/lsb/init-functions + +test -f /sbin/ebtables || exit 0 + +EBTABLES_DUMPFILE_STEM=/etc/ebtables + +RETVAL=0 +prog="ebtables" +desc="Ethernet bridge filtering" +umask 0077 + +#default configuration +EBTABLES_MODULES_UNLOAD="yes" +EBTABLES_LOAD_ON_START="no" +EBTABLES_SAVE_ON_STOP="no" +EBTABLES_SAVE_ON_RESTART="no" +EBTABLES_SAVE_COUNTER="no" +EBTABLES_BACKUP_SUFFIX="~" + +config=/etc/default/$prog +[ -f "$config" ] && . "$config" + +function get_supported_tables() { + EBTABLES_SUPPORTED_TABLES= + /sbin/ebtables -t filter -L 2>&1 1>/dev/null | grep -q permission + if [ $? -eq 0 ]; then + log_failure_msg "Error: insufficient privileges to access the ebtables rulesets." + exit 1 + fi + for table in filter nat broute; do + /sbin/ebtables -t $table -L &> /dev/null + if [ $? -eq 0 ]; then + EBTABLES_SUPPORTED_TABLES="${EBTABLES_SUPPORTED_TABLES} $table" + fi + done +} + +function load() { + RETVAL=0 + get_supported_tables + log_daemon_msg "Restoring ebtables rulesets" + for table in $EBTABLES_SUPPORTED_TABLES; do + log_progress_msg "$table" + if [ -s ${EBTABLES_DUMPFILE_STEM}.$table ]; then + /sbin/ebtables -t $table --atomic-file ${EBTABLES_DUMPFILE_STEM}.$table --atomic-commit + RET=$? + if [ $RET -ne 0 ]; then + log_progress_msg "(failed)" + RETVAL=$RET + fi + else + log_progress_msg "(no saved state)" + fi + done + if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then + log_progress_msg "no kernel support" + else + log_progress_msg "done" + fi + log_end_msg $RETVAL +} + +function clear() { + RETVAL=0 + get_supported_tables + log_daemon_msg "Clearing ebtables rulesets" + for table in $EBTABLES_SUPPORTED_TABLES; do + log_progress_msg "$table" + /sbin/ebtables -t $table --init-table + done + + if [ "$EBTABLES_MODULES_UNLOAD" = "yes" ]; then + for mod in $(grep -E '^(ebt|ebtable)_' /proc/modules | cut -d' ' -f1) ebtables; do + rmmod $mod 2> /dev/null + done + fi + if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then + log_progress_msg "no kernel support" + else + log_progress_msg "done" + fi + log_end_msg $RETVAL +} + +function save() { + RETVAL=0 + get_supported_tables + log_daemon_msg "Saving ebtables rulesets" + for table in $EBTABLES_SUPPORTED_TABLES; do + log_progress_msg "$table" + [ -n "$EBTABLES_BACKUP_SUFFIX" ] && [ -s ${EBTABLES_DUMPFILE_STEM}.$table ] && \ + mv ${EBTABLES_DUMPFILE_STEM}.$table ${EBTABLES_DUMPFILE_STEM}.$table$EBTABLES_BACKUP_SUFFIX + /sbin/ebtables -t $table --atomic-file ${EBTABLES_DUMPFILE_STEM}.$table --atomic-save + RET=$? + if [ $RET -ne 0 ]; then + log_progress_msg "(failed)" + RETVAL=$RET + else + if [ "$EBTABLES_SAVE_COUNTER" = "no" ]; then + /sbin/ebtables -t $table --atomic-file ${EBTABLES_DUMPFILE_STEM}.$table -Z + fi + fi + done + if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then + log_progress_msg "no kernel support" + else + log_progress_msg "done" + fi + log_end_msg $RETVAL +} + +case "$1" in + start) + [ "$EBTABLES_LOAD_ON_START" = "yes" ] && load + ;; + stop) + [ "$EBTABLES_SAVE_ON_STOP" = "yes" ] && save + clear + ;; + restart|reload|force-reload) + [ "$EBTABLES_SAVE_ON_RESTART" = "yes" ] && save + clear + [ "$EBTABLES_LOAD_ON_START" = "yes" ] && load + ;; + load) + load + ;; + save) + save + ;; + status) + get_supported_tables + if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then + log_failure_msg "No kernel support for ebtables." + RETVAL=1 + else + log_daemon_msg "Ebtables support available, number of installed rules" + for table in $EBTABLES_SUPPORTED_TABLES; do + COUNT=$(( $(/sbin/ebtables -t $table -L | sed -e "/^Bridge chain/! d" -e "s/^.*entries: //" -e "s/,.*$/ +/") 0 )) + log_progress_msg "$table($COUNT)" + done + log_end_msg 0 + RETVAL=0 + fi + ;; + *) + echo "Usage: $0 {start|stop|restart|reload|force-reload|load|save|status}" >&2 + RETVAL=1 +esac + +exit $RETVAL diff --git a/files/image_config/ebtables/ebtables.service b/files/image_config/ebtables/ebtables.service new file mode 100644 index 000000000000..bb2cb8fd0a06 --- /dev/null +++ b/files/image_config/ebtables/ebtables.service @@ -0,0 +1,19 @@ +[Unit] +Description=ebtables ruleset management +DefaultDependencies=no +Before=network-pre.target +Wants=network-pre.target +After=local-fs.target +# n.b. use below if we want to tear down rules before shutting down. +#Before=shutdown.target +#Conflicts=shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/etc/init.d/ebtables start +ExecStop=/etc/init.d/ebtables stop +ExecReload=/etc/init.d/ebtables reload + +[Install] +WantedBy=multi-user.target From 124ce22b8ccc50d31a2917b8deb089bd7de23b94 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Tue, 4 Feb 2020 04:19:44 +0000 Subject: [PATCH 0542/1427] [initramfs]: porting loopback file system support patch to v0.133 explicitly install dependency linux-base Signed-off-by: Guohan Lu --- build_debian.sh | 2 +- rules/initramfs-tools.mk | 2 +- sonic-slave-buster/Dockerfile.j2 | 1 + src/initramfs-tools/Makefile | 4 +- .../loopback-file-system-support.patch | 89 ++++++++++++------- 5 files changed, 62 insertions(+), 36 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index b6e5f86a5bb9..258a1e4aa4f6 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -129,7 +129,7 @@ fi ## 2. mount supports squashfs ## However, 'dpkg -i' plus 'apt-get install -f' will ignore the recommended dependency. So ## we install busybox explicitly -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install busybox +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install busybox linux-base echo '[INFO] Install SONiC linux kernel image' ## Note: duplicate apt-get command to ensure every line return zero sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/initramfs-tools-core_*.deb || \ diff --git a/rules/initramfs-tools.mk b/rules/initramfs-tools.mk index e3e14659ed18..2f3e55acac76 100644 --- a/rules/initramfs-tools.mk +++ b/rules/initramfs-tools.mk @@ -1,6 +1,6 @@ # initramfs-tools package -INITRAMFS_TOOLS_VERSION = 0.130 +INITRAMFS_TOOLS_VERSION = 0.133 export INITRAMFS_TOOLS_VERSION INITRAMFS_TOOLS = initramfs-tools_$(INITRAMFS_TOOLS_VERSION)_all.deb diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index b2b574ec56f9..f27a089c2313 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -278,6 +278,7 @@ RUN apt-get update && apt-get install -y \ # For bash texi2html \ # For initramfs + shellcheck \ bash-completion \ {%- if CONFIGURED_ARCH == "amd64" %} # For sonic vs image build diff --git a/src/initramfs-tools/Makefile b/src/initramfs-tools/Makefile index 0b08e4aa431e..faf80b287f0f 100644 --- a/src/initramfs-tools/Makefile +++ b/src/initramfs-tools/Makefile @@ -5,12 +5,12 @@ SHELL = /bin/bash MAIN_TARGET = initramfs-tools_$(INITRAMFS_TOOLS_VERSION)_all.deb DERIVED_TARGETS = initramfs-tools-core_$(INITRAMFS_TOOLS_VERSION)_all.deb -INITRAMFS_TOOLS_REVISION = 18fc98e1b63b012f9bcf06ae3f5477872a5880c0 +INITRAMFS_TOOLS_REVISION = 40e544e13611c1b2690eb99a8096fc16c1b9c74e $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Obtaining the initramfs-tools rm -rf ./initramfs-tools - git clone --branch v0.130 https://salsa.debian.org/kernel-team/initramfs-tools.git ./initramfs-tools + git clone --branch v0.133 https://salsa.debian.org/kernel-team/initramfs-tools.git ./initramfs-tools # Patch pushd ./initramfs-tools diff --git a/src/initramfs-tools/loopback-file-system-support.patch b/src/initramfs-tools/loopback-file-system-support.patch index e5b75478dc96..fbeb347f9d23 100644 --- a/src/initramfs-tools/loopback-file-system-support.patch +++ b/src/initramfs-tools/loopback-file-system-support.patch @@ -13,11 +13,29 @@ And added NFS support! Full patch below... live well, vagrant +--- + init | 12 ++++++++++++ + initramfs-tools.7 | 13 +++++++++++++ + scripts/functions | 40 ++++++++++++++++++++++++++++++++++++++++ + scripts/local | 7 ++++++- + scripts/nfs | 4 ++++ + 5 files changed, 75 insertions(+), 1 deletion(-) + diff --git a/init b/init -index abf7f25..2760bcb 100755 +index 3dc9f6b..fe1005a 100755 --- a/init +++ b/init -@@ -98,6 +98,15 @@ for x in $(cat /proc/cmdline); do +@@ -49,6 +49,9 @@ export ROOT= + export ROOTDELAY= + export ROOTFLAGS= + export ROOTFSTYPE= ++export LOOP= ++export LOOPFLAGS= ++export LOOPFSTYPE= + export IP= + export DEVICE= + export BOOT= +@@ -104,6 +107,15 @@ for x in $(cat /proc/cmdline); do ;; esac ;; @@ -31,16 +49,17 @@ index abf7f25..2760bcb 100755 + LOOPFSTYPE="${x#loopfstype=}" + ;; nfsroot=*) + # shellcheck disable=SC2034 NFSROOT="${x#nfsroot=}" - ;; -diff --git a/initramfs-tools.8 b/initramfs-tools.8 -index ea8c098..ce8e830 100644 ---- a/initramfs-tools.8 -+++ b/initramfs-tools.8 -@@ -42,6 +42,19 @@ The default is 180 seconds. +diff --git a/initramfs-tools.7 b/initramfs-tools.7 +index 45b7de7..745e7a0 100644 +--- a/initramfs-tools.7 ++++ b/initramfs-tools.7 +@@ -53,6 +53,19 @@ The default is 180 seconds. + \fB\fI rootflags set the file system mount option string. - .TP ++.TP +\fB\fI loop +path within the original root file system to loop-mount and use as the +real root file system. @@ -53,15 +72,14 @@ index ea8c098..ce8e830 100644 +\fB\fI loopfstype +set the loop file system type, if applicable. + -+.TP + .TP \fB\fI nfsroot can be either "auto" to try to get the relevant information from DHCP or a - string of the form NFSSERVER:NFSPATH or NFSSERVER:NFSPATH:NFSOPTS. diff --git a/scripts/functions b/scripts/functions -index 8c1bb1f..2ed3ce3 100644 +index 077697f..a17e740 100644 --- a/scripts/functions +++ b/scripts/functions -@@ -426,6 +426,42 @@ mountfs() +@@ -445,6 +445,46 @@ mountfs() ${type}_mount_fs "$1" } @@ -69,14 +87,14 @@ index 8c1bb1f..2ed3ce3 100644 +mount_loop_root() +{ + mkdir -p /host -+ mount -o move ${rootmnt} /host ++ mount -o move "${rootmnt}" /host + loopfile="/host/${LOOP#/}" + + while [ ! -e "$loopfile" ]; do + panic "ALERT! $loopfile does not exist. Dropping to a shell!" + done + -+ if [ ${readonly} = y ]; then ++ if [ "${readonly?}" = "y" ]; then + roflag=-r + else + roflag=-w @@ -91,13 +109,17 @@ index 8c1bb1f..2ed3ce3 100644 + + # FIXME This has no error checking + modprobe loop -+ modprobe ${FSTYPE} ++ modprobe "${FSTYPE}" + + # FIXME This has no error checking -+ mount ${roflag} -o loop -t ${FSTYPE} ${LOOPFLAGS} "$loopfile" ${rootmnt} ++ if [ -z "${LOOPFLAGS}" ]; then ++ mount ${roflag} -o loop -t "${FSTYPE}" "$loopfile" "${rootmnt}" ++ else ++ mount ${roflag} -o loop -t "${FSTYPE}" "${LOOPFLAGS}" "$loopfile" "${rootmnt}" ++ fi + -+ if [ -d ${rootmnt}/host ]; then -+ mount -o move /host ${rootmnt}/host ++ if [ -d "${rootmnt}/host" ]; then ++ mount -o move /host "${rootmnt}/host" + fi +} + @@ -105,22 +127,22 @@ index 8c1bb1f..2ed3ce3 100644 # boot scripts. mountroot() diff --git a/scripts/local b/scripts/local -index f6424f0..072013e 100644 +index a103e68..2ef6413 100644 --- a/scripts/local +++ b/scripts/local -@@ -135,7 +135,8 @@ local_mount_root() +@@ -170,7 +170,8 @@ local_mount_root() - ROOT=$(resolve_device "$ROOT") + local_premount -- if [ "${readonly}" = "y" ]; then -+ if [ "${readonly}" = "y" ] && \ -+ ([ -z "$LOOP" ] || [ "${FSTYPE#ntfs}" = "$FSTYPE" ]); then +- if [ "${readonly?}" = "y" ]; then ++ if [ "${readonly?}" = "y" ] && \ ++ { [ -z "$LOOP" ] || [ "${FSTYPE#ntfs}" = "$FSTYPE" ]; }; then roflag=-r else roflag=-w -@@ -153,6 +154,10 @@ local_mount_root() - else - mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt} +@@ -183,6 +184,10 @@ local_mount_root() + if ! mount ${roflag} ${FSTYPE:+-t "${FSTYPE}"} ${ROOTFLAGS} "${ROOT}" "${rootmnt?}"; then + panic "Failed to mount ${ROOT} as root file system." fi + + if [ "${LOOP}" ]; then @@ -130,13 +152,13 @@ index f6424f0..072013e 100644 local_mount_fs() diff --git a/scripts/nfs b/scripts/nfs -index 1c29850..d382413 100644 +index 40c92c7..dfa8e88 100644 --- a/scripts/nfs +++ b/scripts/nfs -@@ -72,6 +72,10 @@ nfs_mount_root_impl() - fi +@@ -73,6 +73,10 @@ nfs_mount_root_impl() - nfsmount -o nolock ${roflag} ${NFSOPTS} ${NFSROOT} ${rootmnt} + # shellcheck disable=SC2086 + nfsmount -o nolock ${roflag} ${NFSOPTS} "${NFSROOT}" "${rootmnt?}" + + if [ "${LOOP}" ]; then + mount_loop_root @@ -144,3 +166,6 @@ index 1c29850..d382413 100644 } # NFS root mounting +-- +2.17.1 + From d0a3fa448750a257611dbebcedbfbe35dcaad702 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 5 Feb 2020 07:22:36 +0000 Subject: [PATCH 0543/1427] [sshd]: Create /run/sshd under systemd using RuntimeDirectory backport upstream patch https://salsa.debian.org/ssh-team/openssh/commit/4c771b9c7f2f9c5ddd0aefdbfb16441c2d7969a9 Signed-off-by: Guohan Lu --- files/sshd/sshd.service | 2 ++ 1 file changed, 2 insertions(+) diff --git a/files/sshd/sshd.service b/files/sshd/sshd.service index d79c574da516..25d524171c6f 100644 --- a/files/sshd/sshd.service +++ b/files/sshd/sshd.service @@ -10,6 +10,8 @@ ExecStart=/usr/sbin/sshd -D $SSHD_OPTS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure +RuntimeDirectory=sshd +RuntimeDirectoryMode=0755 [Install] WantedBy=multi-user.target From e5e26d9a436b325f1aba5d0b829fc3410c3e25ff Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 5 Feb 2020 07:37:21 +0000 Subject: [PATCH 0544/1427] [platform-modules]: set debian control file to depend on 4.19.0-6 change depends to linux-image-4.19.0-6-amd64 in debian/control Signed-off-by: Guohan Lu --- platform/barefoot/bfn-modules/debian/control | 2 +- .../debian/control | 2 +- .../debian/control | 2 +- .../sonic-platform-modules-bfn/debian/control | 2 +- .../debian/control | 2 +- .../debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 8 ++++---- .../sonic-platform-modules-dell/debian/control | 14 +++++++------- .../sonic-platform-modules-delta/debian/control | 10 +++++----- .../sonic-platform-modules-inventec/debian/control | 12 ++++++------ .../sonic-platform-modules-mitac/debian/control | 2 +- .../cavium/cavm_platform_modules/DEBIAN/control | 2 +- .../sonic-platform-modules-e582/debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 2 +- .../sonic-platform-modules-delta/debian/control | 2 +- platform/nephos/nephos-modules/debian/control | 2 +- .../sonic-platform-modules-accton/debian/control | 2 +- .../sonic-platform-modules-cig/debian/control | 6 +++--- .../sonic-platform-modules-pegatron/debian/control | 2 +- 19 files changed, 41 insertions(+), 41 deletions(-) diff --git a/platform/barefoot/bfn-modules/debian/control b/platform/barefoot/bfn-modules/debian/control index d6f7a991107d..32c161f13320 100644 --- a/platform/barefoot/bfn-modules/debian/control +++ b/platform/barefoot/bfn-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: bfn-modules Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for bfn asic for mmap diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index e3f5356f22db..19e4cdba062c 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-montara Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control index bc6c990efebb..2137d1ef9129 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-newport Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index cca87831f1f1..ff942dc3722d 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control index 6070cf9ad1fc..58628bff07a9 100644 --- a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: platform-modules-wnc-osw1800 Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control index beba5b5f4e62..65333e6a0994 100644 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: sonic-platform-alphanetworks-snh60a0-320fv2 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-alphanetworks-snh60b0-640f Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index d5dd43ee4918..4062cf452d1d 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -7,21 +7,21 @@ Standards-Version: 3.9.3 Package: platform-modules-dx010 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-haliburton Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-seastone2 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as led, sfp Package: platform-modules-silverstone Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as led, sfp. diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index e4d5a24f3542..a052f72f9896 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -7,35 +7,35 @@ Standards-Version: 3.9.3 Package: platform-modules-s6000 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9100 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s6100 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9264f Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5232f Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5248f Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9332f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index e2e9883f9b2b..2974bd42a6a3 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -7,25 +7,25 @@ Standards-Version: 3.9.3 Package: platform-modules-ag9032v1 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9064 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag5648 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-et-6248brb Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9032v2a Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as syseeprom, sfp diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index 86f7e7b20f65..fc9492fe931c 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-d7032q28b Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7054q28b Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6254qs Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6556 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6356 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7264q28b Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/control b/platform/broadcom/sonic-platform-modules-mitac/debian/control index 8e20f8524d74..8f738a42eb43 100644 --- a/platform/broadcom/sonic-platform-modules-mitac/debian/control +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-mitac-ly1200-32x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/cavium/cavm_platform_modules/DEBIAN/control b/platform/cavium/cavm_platform_modules/DEBIAN/control index 75f8adc0cbd2..cac08ec8f4e7 100755 --- a/platform/cavium/cavm_platform_modules/DEBIAN/control +++ b/platform/cavium/cavm_platform_modules/DEBIAN/control @@ -1,6 +1,6 @@ Package: cavm-platform-modules Version: 1.0 Architecture: amd64 -Depends: linux-image-3.16.0-4-amd64 +Depends: linux-image-4.19.0-6-amd64 Maintainer: Nadiya.Stetskovych@cavium.com Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-e582/debian/control b/platform/centec/sonic-platform-modules-e582/debian/control index c449246b2823..44ffddfa0d65 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/control +++ b/platform/centec/sonic-platform-modules-e582/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: platform-modules-e582-48x2q4z Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-e582-48x6q Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/innovium/sonic-platform-modules-cel/debian/control b/platform/innovium/sonic-platform-modules-cel/debian/control index 543d381ab6f7..9794ba7c7ce1 100755 --- a/platform/innovium/sonic-platform-modules-cel/debian/control +++ b/platform/innovium/sonic-platform-modules-cel/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: platform-modules-midstone-200i Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices diff --git a/platform/innovium/sonic-platform-modules-delta/debian/control b/platform/innovium/sonic-platform-modules-delta/debian/control index 3fe3ffc9f526..e4ce62b2f9b5 100644 --- a/platform/innovium/sonic-platform-modules-delta/debian/control +++ b/platform/innovium/sonic-platform-modules-delta/debian/control @@ -7,7 +7,7 @@ Standards-Version: 3.9.3 Package: platform-modules-et-c032if Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/nephos-modules/debian/control b/platform/nephos/nephos-modules/debian/control index 3d06ca971f89..f5799a93fd0c 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: nephos-modules Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for nephos asic diff --git a/platform/nephos/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control index 639534f3edcc..35c3fc19159b 100755 --- a/platform/nephos/sonic-platform-modules-accton/debian/control +++ b/platform/nephos/sonic-platform-modules-accton/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: sonic-platform-accton-as7116-54x Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-cig/debian/control b/platform/nephos/sonic-platform-modules-cig/debian/control index bf40791b24e0..87f0d09fecde 100644 --- a/platform/nephos/sonic-platform-modules-cig/debian/control +++ b/platform/nephos/sonic-platform-modules-cig/debian/control @@ -7,15 +7,15 @@ Standards-Version: 3.9.3 Package: sonic-platform-cig-cs6436-56p Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-cig-cs6436-54p Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-cig-cs5435-54p Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/control b/platform/nephos/sonic-platform-modules-pegatron/debian/control index 18e74be1455d..bb4727a79b61 100755 --- a/platform/nephos/sonic-platform-modules-pegatron/debian/control +++ b/platform/nephos/sonic-platform-modules-pegatron/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-pegatron-porsche Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-4.19.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp From 6f5ac4b282b78e1ce51619afe390f63a7148077c Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 7 Feb 2020 19:43:57 +0000 Subject: [PATCH 0545/1427] [initramfs]: move mke2fs to /usr/local/sbin /usr/sbin/mke2fs is now rom busybox which does not support the operation we need --- files/initramfs-tools/arista-convertfs.j2 | 2 +- files/initramfs-tools/mke2fs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/files/initramfs-tools/arista-convertfs.j2 b/files/initramfs-tools/arista-convertfs.j2 index 56616d2ba04a..0dad56e5776b 100644 --- a/files/initramfs-tools/arista-convertfs.j2 +++ b/files/initramfs-tools/arista-convertfs.j2 @@ -224,7 +224,7 @@ cmd="wait_for_root_dev" run_cmd "$cmd" "$err_msg" err_msg="Error: formatting to ext4 failed" -cmd="mke2fs -t ext4 -F -O '^huge_file,^metadata_csum' $root_dev" +cmd="/usr/local/sbin/mke2fs -t ext4 -F -O '^huge_file,^metadata_csum' $root_dev" run_cmd "$cmd" "$err_msg" err_msg="Error: mounting $root_dev to $root_mnt failed" diff --git a/files/initramfs-tools/mke2fs b/files/initramfs-tools/mke2fs index 52933d644a87..1f98f20c23c4 100644 --- a/files/initramfs-tools/mke2fs +++ b/files/initramfs-tools/mke2fs @@ -17,7 +17,7 @@ esac . /usr/share/initramfs-tools/hook-functions -copy_exec /sbin/mke2fs +copy_exec /usr/sbin/mke2fs /usr/local/sbin/ copy_exec /sbin/sfdisk copy_exec /sbin/fdisk copy_exec /sbin/resize2fs @@ -30,7 +30,7 @@ for type in $fstypes; do if [ -h "$prog" ]; then link=$(readlink -f "$prog") copy_exec "$link" - ln -s "$link" "${DESTDIR}/$prog" + ln -s "/usr/local/sbin/$(basename $link)" "${DESTDIR}/$prog" elif [ -x "$prog" ] ; then copy_exec "$prog" else From f1cc577c7562eb330efb3f0acd3db0c86eb63121 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 8 Feb 2020 02:38:04 +0000 Subject: [PATCH 0546/1427] [build_kvm]: mount /proc to show memory Signed-off-by: Guohan Lu --- scripts/build_kvm_image.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/build_kvm_image.sh b/scripts/build_kvm_image.sh index f9cd9490181d..e0a7ec2feff4 100755 --- a/scripts/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -51,6 +51,7 @@ create_disk prepare_installer_disk echo "Prepare memory for KVM build: $vs_build_prepare_mem" +sudo mount proc /proc -t proc || true free -m if [[ "$vs_build_prepare_mem" == "yes" ]]; then # Force o.s. to drop cache and compact memory so that KVM can get 2G memory From aec51c8aafbbb3d745a6a669ddc532245455148e Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Sun, 15 Mar 2020 16:15:08 +0800 Subject: [PATCH 0547/1427] [docker-wait-any] Use APIClient instead of Client according to API update due to the upgrade from docker-py (1.6.0) to docker (4.1.0) --- files/image_config/misc/docker-wait-any | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/files/image_config/misc/docker-wait-any b/files/image_config/misc/docker-wait-any index 3988a9fbdf57..b6a2d95c8821 100755 --- a/files/image_config/misc/docker-wait-any +++ b/files/image_config/misc/docker-wait-any @@ -11,13 +11,13 @@ stopped running. Here, we spawn multiple threads and wait on one container per thread. If any of the threads exit, the entire application will exit. - NOTE: This script is written against docker-py version 1.6.0. Newer - versions of docker-py have a different API. + NOTE: This script is written against docker Python package 4.1.0. Newer + versions of docker may have a different API. """ import sys import threading -from docker import Client +from docker import APIClient # Instantiate a global event to share among our threads g_thread_exit_event = threading.Event() @@ -40,7 +40,7 @@ def wait_for_container(docker_client, container_name): def main(): thread_list = [] - docker_client = Client(base_url='unix://var/run/docker.sock') + docker_client = APIClient(base_url='unix://var/run/docker.sock') # Ensure we were passed at least one argument if len(sys.argv) < 2: From 65dfe7590329285ebd72e14390a70c429cc59279 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 23 Mar 2020 07:13:29 +0000 Subject: [PATCH 0548/1427] [build]: umount target directory properly Signed-off-by: Guohan Lu --- files/build_templates/sonic_debian_extension.j2 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index aa6373994e37..a7f81592d068 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -403,6 +403,11 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then fi {% if installer_images.strip() -%} +clean_proc() { + sudo umount /proc || true +} +trap_push clean_proc +sudo mount proc /proc -t proc sudo mkdir $FILESYSTEM_ROOT/target sudo mount --bind target $FILESYSTEM_ROOT/target sudo chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS info @@ -431,6 +436,7 @@ echo "docker images pull complete" sudo umount $FILESYSTEM_ROOT/target sudo rm -r $FILESYSTEM_ROOT/target +sudo umount /proc || true if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then sudo umount $FILESYSTEM_ROOT/dockerfs sudo rm -fr $FILESYSTEM_ROOT/dockerfs From 7e0cfcee2c681035d7ef27d45a0034e7e89740cb Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Wed, 11 Mar 2020 16:44:20 +0800 Subject: [PATCH 0549/1427] [Mellanox] build mft/hw-management in buster stage Currently we port SONiC to buster in a way that base image is on buster and other dockers based on stretch. The benefit is that tasks can be carried out simultaneously. The build procedure can be treated as 2 stages. The first stage is to build the stretch-based debs and dockers and the second stage is to build the buster-based ones. One thing we have to pay attention to is some debs depend on kernel should not be built at stretch stage because the kernel isn't available at that time. The idea is to move that kind of debs out of SONIC_STRETCH_DEBS. Meanwhile, any dependency explicitly put on the stretch based dockers on kernel should be removed. --- platform/mellanox/hw-management.mk | 2 -- platform/mellanox/mft.mk | 2 -- platform/mellanox/mft/Makefile | 2 +- platform/mellanox/rules.mk | 3 --- platform/mellanox/sdk.mk | 2 -- 5 files changed, 1 insertion(+), 10 deletions(-) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index 31ff9aaca7be..cc27126cf80e 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -8,5 +8,3 @@ MLNX_HW_MANAGEMENT = hw-management_1.mlnx.$(MLNX_HW_MANAGEMENT_VERSION)_amd64.de $(MLNX_HW_MANAGEMENT)_SRC_PATH = $(PLATFORM_PATH)/hw-management $(MLNX_HW_MANAGEMENT)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_MAKE_DEBS += $(MLNX_HW_MANAGEMENT) - -SONIC_STRETCH_DEBS += $(MLNX_HW_MANAGEMENT) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index 229ba86b4a7b..5795e5acb3a0 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -15,5 +15,3 @@ $(eval $(call add_derived_package,$(MFT),$(KERNEL_MFT))) MFT_OEM = mft-oem_$(MFT_VERSION)-$(MFT_REVISION)_amd64.deb $(eval $(call add_derived_package,$(MFT),$(MFT_OEM))) - -SONIC_STRETCH_DEBS += $(KERNEL_MFT) diff --git a/platform/mellanox/mft/Makefile b/platform/mellanox/mft/Makefile index e18964dd4b91..2e28536c4fd0 100644 --- a/platform/mellanox/mft/Makefile +++ b/platform/mellanox/mft/Makefile @@ -27,6 +27,6 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # fix timestamp because we do not actually build tools, only kernel touch $(MFT_NAME)/DEBS/* - mv $(MFT_NAME)/SDEBS/ubuntu-drivers/4.9.0/kernel-mft-dkms_$(MFT_VERSION)-$(KVERSION)_all.deb $(MFT_NAME)/DEBS/* $(DEST) + mv $(MFT_NAME)/SDEBS/ubuntu-drivers/4.19.0/kernel-mft-dkms_$(MFT_VERSION)-$(KVERSION)_all.deb $(MFT_NAME)/DEBS/* $(DEST) $(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index bdb4e955c2d4..1270579e2942 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -29,6 +29,3 @@ $(SYNCD)_RDEPENDS += $(MLNX_SAI) # Inject mlnx sdk libs to platform monitor $(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(APPLIBS) $(SX_COMPLIB) $(SXD_LIBS) $(SX_GEN_UTILS) $(PYTHON_SDK_API) $(APPLIBS_DEV) $(SX_COMPLIB_DEV) $(SXD_LIBS_DEV) $(SX_GEN_UTILS_DEV) - -# Inject mlnx mlx libs to platform monitor -$(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(MFT) diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 3b2e9a8f30c8..4b6212b147d9 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -152,8 +152,6 @@ else SONIC_COPY_DEBS += $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) endif -SONIC_STRETCH_DEBS += $(SX_KERNEL) - mlnx-sdk-packages: $(addprefix $(DEBS_PATH)/, $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) $(SX_KERNEL)) SONIC_PHONY_TARGETS += mlnx-sdk-packages From 452fc3d99c3f13b459fda76f4cb53d0b158da838 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Fri, 20 Mar 2020 09:30:00 +0800 Subject: [PATCH 0550/1427] [baseimage]: Install haveged to accelerates crng init The initialization of /dev/random (crng init) is responsible for random number generation. On some devices, crng took very long to finish. --- build_debian.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build_debian.sh b/build_debian.sh index 258a1e4aa4f6..f52630334a79 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -294,7 +294,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in conntrack \ python-pip \ python3-pip \ - cron + cron \ + haveged if [[ $CONFIGURED_ARCH == amd64 ]]; then From 2a237c57e6fa29a495d69ac1ff7b9484fb58e262 Mon Sep 17 00:00:00 2001 From: bsun-sudo <56011247+bsun-sudo@users.noreply.github.com> Date: Fri, 13 Mar 2020 11:01:16 -0700 Subject: [PATCH 0551/1427] [mgmt-vrf]: mgmt vrf related change for Buster (#53) Co-authored-by: Bing Sun --- files/image_config/interfaces/interfaces.j2 | 10 ---------- .../tests/sample_output/mvrf_interfaces | 6 ------ 2 files changed, 16 deletions(-) diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 0e852a1150fb..dbedd5e9418a 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -76,10 +76,6 @@ iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static up ip {{ '-4' if prefix | ipv4 else '-6' }} route add default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} metric 201 up ip {{ '-4' if prefix | ipv4 else '-6' }} route add {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} up ip {{ '-4' if prefix | ipv4 else '-6' }} rule add from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} - up cgcreate -g l3mdev:mgmt - up cgset -r l3mdev.master-device=mgmt mgmt -{% endif %} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} up ip rule add to {{ route }} table {{ vrf_table }} {% endfor %} @@ -87,9 +83,6 @@ iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} - down cgdelete -g l3mdev:mgmt -{% endif %} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} pre-down ip rule delete to {{ route }} table {{ vrf_table }} {% endfor %} @@ -100,9 +93,6 @@ iface eth0 inet dhcp metric 202 {% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} vrf mgmt - up cgcreate -g l3mdev:mgmt - up cgset -r l3mdev.master-device=mgmt mgmt - down cgdelete -g l3mdev:mgmt {% endif %} iface eth0 inet6 dhcp up sysctl net.ipv6.conf.eth0.accept_ra=1 diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces index 633d8aa4498d..085f5111c3f5 100644 --- a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces @@ -29,13 +29,10 @@ iface eth0 inet static up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 up ip -4 rule add from 10.0.0.100/32 table 5000 - up cgcreate -g l3mdev:mgmt - up cgset -r l3mdev.master-device=mgmt mgmt # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 pre-down ip -4 rule delete from 10.0.0.100/32 table 5000 - down cgdelete -g l3mdev:mgmt iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 @@ -47,13 +44,10 @@ iface eth0 inet6 static up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table 5000 metric 201 up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table 5000 up ip -6 rule add from 2603:10e2:0:2902::8/128 table 5000 - up cgcreate -g l3mdev:mgmt - up cgset -r l3mdev.master-device=mgmt mgmt # management port down rules pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 - down cgdelete -g l3mdev:mgmt # source /etc/network/interfaces.d/* # From 012c832ce5382971cd85b9ddc936c36cefe3951f Mon Sep 17 00:00:00 2001 From: bsun-sudo <56011247+bsun-sudo@users.noreply.github.com> Date: Tue, 24 Mar 2020 21:21:15 -0700 Subject: [PATCH 0552/1427] [ntp] add ntp support in buster with mgmt vrf (#55) - create a file in files/image_config/ntp/ntp-systemd-wrapper to add mgmt vrf related start cmd for ntp service. So that the default /usr/lib/ntp/ntp-systemd-wrapper can be overriden during build time. - modify build_debian.sh to cp files/image_config/ntp/ntp-systemd-wrapper to /usr/lib/ntp/ntp-systemd-wrapper during build time. Co-authored-by: Bing Sun --- build_debian.sh | 4 +++ files/image_config/ntp/ntp-systemd-wrapper | 38 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 files/image_config/ntp/ntp-systemd-wrapper diff --git a/build_debian.sh b/build_debian.sh index f52630334a79..fa45853e1597 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -451,6 +451,10 @@ if [ -f files/image_config/ntp/ntp ]; then sudo cp ./files/image_config/ntp/ntp $FILESYSTEM_ROOT/etc/init.d/ fi +if [ -f files/image_config/ntp/ntp-systemd-wrapper ]; then + sudo cp ./files/image_config/ntp/ntp-systemd-wrapper $FILESYSTEM_ROOT/usr/lib/ntp/ +fi + ## Version file sudo mkdir -p $FILESYSTEM_ROOT/etc/sonic sudo tee $FILESYSTEM_ROOT/etc/sonic/sonic_version.yml > /dev/null < /dev/null) + if [ "$vrfEnabled" = "true" ] + then + ip vrf exec mgmt start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + else + start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + fi +) 9>$LOCKFILE + From ec85c2e159d4311f62ba95bb1c517cefb96d1c6a Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 3 Apr 2020 10:42:16 +0000 Subject: [PATCH 0553/1427] [rsyslog]: setup correct argument for rsyslog.service in buster, by default, rsyslog service does not create pidfile which breaks monit configuration Signed-off-by: Guohan Lu --- build_debian.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build_debian.sh b/build_debian.sh index fa45853e1597..1b7024a304ee 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -366,6 +366,12 @@ EOF sudo sed -i 's/^ListenAddress ::/#ListenAddress ::/' $FILESYSTEM_ROOT/etc/ssh/sshd_config sudo sed -i 's/^#ListenAddress 0.0.0.0/ListenAddress 0.0.0.0/' $FILESYSTEM_ROOT/etc/ssh/sshd_config +## Config rsyslog +sudo augtool -r $FILESYSTEM_ROOT --autosave " +rm /files/lib/systemd/system/rsyslog.service/Service/ExecStart/arguments +set /files/lib/systemd/system/rsyslog.service/Service/ExecStart/arguments/1 -n +" + ## Config sysctl sudo mkdir -p $FILESYSTEM_ROOT/var/core sudo augtool --autosave " From e95504fe722b9b0f70a52c2c4cf4ab91f1910985 Mon Sep 17 00:00:00 2001 From: Stephen Date: Sun, 15 Mar 2020 07:31:45 +0000 Subject: [PATCH 0554/1427] [Mellanox]WA to avoid fsroot being corrupted by "dpkg --extract" --- files/build_templates/sonic_debian_extension.j2 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index a7f81592d068..9ad2ba5eabae 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -344,7 +344,14 @@ sudo chmod a+x $FILESYSTEM_ROOT/usr/sbin/policy-rc.d {% if installer_debs.strip() -%} {% for deb in installer_debs.strip().split(' ') -%} {% if sonic_asic_platform == "mellanox" %} -sudo dpkg --extract {{deb}} $FILESYSTEM_ROOT +if [ -e tmpdir ] ; +then + rm -rf tmpdir; +fi +sudo mkdir tmpdir +sudo dpkg --extract {{deb}} tmpdir +for subdir in $(ls tmpdir) ; do sudo cp -R tmpdir/$subdir/* $FILESYSTEM_ROOT/$subdir; done +sudo rm -rf tmpdir {% else %} sudo dpkg --root=$FILESYSTEM_ROOT -i {{deb}} || sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f {% endif %} From 3ded45a70d8faccc05c02cd1549a262aa5c37bc8 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Tue, 14 Apr 2020 04:13:15 +0000 Subject: [PATCH 0555/1427] [sonic-slave-buster]: user legacy iptables instead of nftables Signed-off-by: Guohan Lu --- sonic-slave-buster/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index f27a089c2313..6ebc3f24db30 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -409,3 +409,4 @@ RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-buster RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian {%- endif %} RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker +RUN update-alternatives --set iptables /usr/sbin/iptables-legacy From dd49f742bd4886246f34bc3235d5ae468fdedbd3 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 15 Apr 2020 09:51:31 +0000 Subject: [PATCH 0556/1427] [sonic-slave-buster]: add build deps for sonic_yang_mgmt build Signed-off-by: Guohan Lu --- sonic-slave-buster/Dockerfile.j2 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 6ebc3f24db30..4cb0fe102aac 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -368,6 +368,13 @@ RUN pip install mockredispy==2.9.3 RUN pip install pytest-runner==4.4 RUN pip install setuptools==40.8.0 +# For sonic_yang_mgmt build +RUN pip install ijson==2.6.1 +RUN pip3 install ijson==2.6.1 +RUN pip install jsondiff==1.2.0 +RUN pip install xmltodict==0.12.0 +RUN pip install pyang==2.1.1 + # For mgmt-framework build RUN pip install mmh3 From 38a4fddaa9324ec6a4053bd053439df9396c6daa Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 15 Apr 2020 10:35:03 +0000 Subject: [PATCH 0557/1427] [vsimage]: install systemd generator into one image Signed-off-by: Guohan Lu --- platform/vs/one-image.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vs/one-image.mk b/platform/vs/one-image.mk index cf4f535382bc..a0e176df1497 100644 --- a/platform/vs/one-image.mk +++ b/platform/vs/one-image.mk @@ -1,9 +1,9 @@ # sonic vs one image installer SONIC_ONE_IMAGE = sonic-vs.bin -$(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_MACHINE = vs $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie +$(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) From 40d2c79c84b18d8ad6081dc3bf7ca17b6b021a20 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 15 Apr 2020 10:57:04 +0000 Subject: [PATCH 0558/1427] [build]: ensure proc is mounted for raw image build Signed-off-by: Guohan Lu --- build_image.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build_image.sh b/build_image.sh index 9635201ae067..cd8c26da1225 100755 --- a/build_image.sh +++ b/build_image.sh @@ -67,8 +67,11 @@ elif [ "$IMAGE_TYPE" = "raw" ]; then echo "Creating SONiC raw partition : $OUTPUT_RAW_IMAGE of size $RAW_IMAGE_DISK_SIZE MB" fallocate -l "$RAW_IMAGE_DISK_SIZE"M $OUTPUT_RAW_IMAGE + # ensure proc is mounted + sudo mount proc /proc -t proc || true + ## Generate a partition dump that can be used to 'dd' in-lieu of using the onie-nos-installer - ## Run the installer + ## Run the installer ## The 'build' install mode of the installer is used to generate this dump. sudo chmod a+x $OUTPUT_ONIE_IMAGE sudo ./$OUTPUT_ONIE_IMAGE From f3a1156d451ceb6bf28035faf6828f0be1460409 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 15 Apr 2020 11:04:57 +0000 Subject: [PATCH 0559/1427] [vsraw]: build sonic-vs.raw image --- platform/vs/raw-image.dep | 2 ++ platform/vs/raw-image.mk | 8 ++++++++ platform/vs/rules.mk | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 platform/vs/raw-image.dep create mode 100644 platform/vs/raw-image.mk diff --git a/platform/vs/raw-image.dep b/platform/vs/raw-image.dep new file mode 100644 index 000000000000..500ba2a70fef --- /dev/null +++ b/platform/vs/raw-image.dep @@ -0,0 +1,2 @@ +#DPKG FRK +$(SONIC_RAW_IMAGE)_CACHE_MODE := none diff --git a/platform/vs/raw-image.mk b/platform/vs/raw-image.mk new file mode 100644 index 000000000000..becb9012f552 --- /dev/null +++ b/platform/vs/raw-image.mk @@ -0,0 +1,8 @@ +# sonic vs raw image installer + +SONIC_RAW_IMAGE = sonic-vs.raw +$(SONIC_RAW_IMAGE)_MACHINE = vs +$(SONIC_RAW_IMAGE)_IMAGE_TYPE = raw +$(SONIC_RAW_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +$(SONIC_RAW_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) +SONIC_INSTALLERS += $(SONIC_RAW_IMAGE) diff --git a/platform/vs/rules.mk b/platform/vs/rules.mk index 557604d9ec4d..d91f487a5edb 100644 --- a/platform/vs/rules.mk +++ b/platform/vs/rules.mk @@ -5,5 +5,6 @@ include $(PLATFORM_PATH)/docker-syncd-vs.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/onie.mk include $(PLATFORM_PATH)/kvm-image.mk +include $(PLATFORM_PATH)/raw-image.mk -SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_KVM_IMAGE) $(DOCKER_SONIC_VS) +SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_KVM_IMAGE) $(DOCKER_SONIC_VS) $(SONIC_RAW_IMAGE) From d0967f55c1bf2ea313716334b16086e8de1cc107 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 15 Apr 2020 12:25:07 +0000 Subject: [PATCH 0560/1427] [dpkg-cache]: add sonic-slave-buster docker file in common dependency Signed-off-by: Guohan Lu --- Makefile.cache | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Makefile.cache b/Makefile.cache index 78ee4541a861..ec56f7f20af7 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -8,12 +8,12 @@ # # Email : kalimuthu.velappan@broadcom.com # greg.paussa@broadcom.com -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -73,7 +73,8 @@ SONIC_COMMON_FLAGS_LIST := $(CONFIGURED_PLATFORM) \ SONIC_COMMON_DPKG_LIST := debian/control debian/changelog debian/rules \ debian/compat debian/install debian/copyright SONIC_COMMON_BASE_FILES_LIST := sonic-slave-jessie/Dockerfile.j2 sonic-slave-jessie/Dockerfile.user \ - sonic-slave-stretch/Dockerfile.j2 sonic-slave-stretch/Dockerfile.user + sonic-slave-stretch/Dockerfile.j2 sonic-slave-stretch/Dockerfile.user \ + sonic-slave-buster/Dockerfile.j2 sonic-slave-buster/Dockerfile.user @@ -105,7 +106,7 @@ MOD_CACHE_LOCK_TIMEOUT := 3600 SONIC_DPKG_LOCAL_CACHE_DIR=${TARGET_PATH}/cache $(shell test -d $(SONIC_DPKG_LOCAL_CACHE_DIR) || \ mkdir -p $(SONIC_DPKG_LOCAL_CACHE_DIR) && chmod 777 $(SONIC_DPKG_LOCAL_CACHE_DIR) ) -$(shell test -w $(SONIC_DPKG_CACHE_DIR) || sudo chmod 777 $(SONIC_DPKG_CACHE_DIR) ) +$(shell test -w $(SONIC_DPKG_CACHE_DIR) || sudo chmod 777 $(SONIC_DPKG_CACHE_DIR) ) DOCKER_LOCKFILE_SUFFIX := access DOCKER_LOCKFILE_TIMEOUT := 1200 @@ -461,7 +462,7 @@ $(foreach pkg, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONI define FLAGS_DEP_RULES ALL_DEP_FILES_LIST += $(foreach pkg,$(2), $(if $(filter none,$($(1)_CACHE_MODE)),$(addsuffix .$(3),$(addprefix $(pkg)/, $(1))))) $(addsuffix .$(3),$(addprefix $(2)/, $(1))) :: $(2)/%.$(3) : - @$$(eval $$*_FILE_FLAGS := $$(shell test -f $$@ && cat $$@)) + @$$(eval $$*_FILE_FLAGS := $$(shell test -f $$@ && cat $$@)) @echo '$$($$*_DEP_FLAGS)' | cmp -s - $$@ || echo '$$($$*_DEP_FLAGS)' > $$@ $$(eval $$*_FLAGS_DIFF := $$(filter-out $$($$*_FILE_FLAGS),$$($$*_DEP_FLAGS)) $$(filter-out $$($$*_DEP_FLAGS),$$($$*_FILE_FLAGS))) @$$(if $$(MDEBUG), $$(info FLAGS: $$@, DEP:$$?)) @@ -571,7 +572,7 @@ SONIC_CACHE_CLEAN_DEBS = $(addsuffix -clean,$(addprefix $(DEBS_PATH)/, \ $(SONIC_DPKG_DEBS) \ $(SONIC_DERIVED_DEBS) \ $(SONIC_EXTRA_DEBS))) -$(SONIC_CACHE_CLEAN_DEBS) :: $(DEBS_PATH)/%-clean : .platform $$(addsuffix -clean,$$(addprefix $(DEBS_PATH)/,$$($$*_MAIN_DEB))) +$(SONIC_CACHE_CLEAN_DEBS) :: $(DEBS_PATH)/%-clean : .platform $$(addsuffix -clean,$$(addprefix $(DEBS_PATH)/,$$($$*_MAIN_DEB))) @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) @@ -581,7 +582,7 @@ SONIC_CACHE_CLEAN_FILES = $(addsuffix -clean,$(addprefix $(FILES_PATH)/, \ $(SONIC_ONLINE_FILES) \ $(SONIC_COPY_FILES) \ $(SONIC_MAKE_FILES))) -$(SONIC_CACHE_CLEAN_FILES) :: $(FILES_PATH)/%-clean : .platform +$(SONIC_CACHE_CLEAN_FILES) :: $(FILES_PATH)/%-clean : .platform @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) @@ -592,7 +593,7 @@ SONIC_CACHE_CLEAN_TARGETS = $(addsuffix -clean,$(addprefix $(TARGET_PATH)/, \ $(SONIC_DOCKER_DBG_IMAGES) \ $(SONIC_SIMPLE_DOCKER_IMAGES) \ $(SONIC_INSTALLERS))) -$(SONIC_CACHE_CLEAN_TARGETS) :: $(TARGET_PATH)/%-clean : .platform +$(SONIC_CACHE_CLEAN_TARGETS) :: $(TARGET_PATH)/%-clean : .platform @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) @@ -600,7 +601,7 @@ $(SONIC_CACHE_CLEAN_TARGETS) :: $(TARGET_PATH)/%-clean : .platform # Clean all the DEP and SHA files for all the PYTHON DEBS target SONIC_CACHE_CLEAN_STDEB_DEBS = $(addsuffix -clean,$(addprefix $(PYTHON_DEBS_PATH)/, \ $(SONIC_PYTHON_STDEB_DEBS))) -$(SONIC_CACHE_CLEAN_STDEB_DEBS) :: $(PYTHON_DEBS_PATH)/%-clean : .platform +$(SONIC_CACHE_CLEAN_STDEB_DEBS) :: $(PYTHON_DEBS_PATH)/%-clean : .platform @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) @@ -608,7 +609,7 @@ $(SONIC_CACHE_CLEAN_STDEB_DEBS) :: $(PYTHON_DEBS_PATH)/%-clean : .platform # Clean all the DEP and SHA files for all the PYTHON WHEELS target SONIC_CACHE_CLEAN_WHEELS = $(addsuffix -clean,$(addprefix $(PYTHON_WHEELS_PATH)/, \ $(SONIC_PYTHON_WHEELS))) -$(SONIC_CACHE_CLEAN_WHEELS) :: $(PYTHON_WHEELS_PATH)/%-clean : .platform +$(SONIC_CACHE_CLEAN_WHEELS) :: $(PYTHON_WHEELS_PATH)/%-clean : .platform @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) @@ -616,7 +617,7 @@ $(SONIC_CACHE_CLEAN_WHEELS) :: $(PYTHON_WHEELS_PATH)/%-clean : .platform cclean:: $(SONIC_CACHE_CLEAN_DEBS) $(SONIC_CACHE_CLEAN_FILES) $(SONIC_CACHE_CLEAN_TARGETS) \ $(SONIC_CACHE_CLEAN_STDEB_DEBS) $(SONIC_CACHE_CLEAN_WHEELS) -.PHONY: clean +.PHONY: clean clean:: cclean # Clear all the local cache contents @@ -653,7 +654,7 @@ show-%: )\ )\ ) - $(info ) + $(info ) From 744d33d502055e9d0a60123058f084eb9eda9d1f Mon Sep 17 00:00:00 2001 From: taochengyi <54564117+taocy001@users.noreply.github.com> Date: Fri, 17 Apr 2020 15:38:48 +0800 Subject: [PATCH 0561/1427] [devices]: Centec x86 goldengate platforms and devices update (#4248) * Centec x86 goldengate update (#8) --- .../E582-48x2q4z/port_config.ini | 54 +- .../x86_64-centec_e582_48x2q4z-r0/default_sku | 2 +- .../E582-48x6q/port_config.ini | 84 +- .../x86_64-centec_e582_48x6q-r0/default_sku | 2 +- .../ES6428A-X48Q2H4/buffers.json.j2 | 70 + .../ES6428A-X48Q2H4/pg_profile_lookup.ini | 21 + .../ES6428A-X48Q2H4/port_config.ini | 88 +- .../ES6428A-X48Q2H4/qos.json | 133 ++ .../ES6428A-X48Q2H4/sai.profile | 3 +- .../x86_64-ew_es6220_x48q2h4-r0/default_sku | 2 +- .../installer.conf | 3 + .../plugins/eeprom.py | 33 + .../plugins/psuutil.py | 57 + .../plugins/sfputil.py | 187 ++ .../x86_64-ew_es6220_x48q2h4-r0/default_sku | 1 - .../installer.conf | 1 - dockers/docker-orchagent/orchagent.sh | 5 +- platform/centec/docker-ptf-centec.mk | 2 +- platform/centec/docker-syncd-centec-rpc.mk | 2 +- platform/centec/docker-syncd-centec.mk | 4 +- .../centec/docker-syncd-centec/Dockerfile.j2 | 4 +- platform/centec/one-image.mk | 3 +- platform/centec/platform-modules-embedway.mk | 13 + platform/centec/rules.mk | 2 +- platform/centec/sdk.mk | 4 +- .../48x2q4z/cfg/config_db.json | 302 --- .../48x2q4z/cfg/config_db_l2l3.json | 610 ------ .../modules/centec_e582_48x2q4z_platform.c | 2 +- .../48x2q4z/scripts/48x2q4z_platform.sh | 2 +- .../48x6q/cfg/config_db.json | 302 --- .../48x6q/cfg/config_db_l2l3.json | 610 ------ .../platform-modules-e582-48x2q4z.install | 2 - .../platform-modules-e582-48x6q.install | 2 - .../sonic-platform-modules-embedway/LICENSE | 15 + .../sonic-platform-modules-embedway/README.md | 1 + .../debian/changelog | 5 + .../debian/compat | 1 + .../debian/control | 12 + .../platform-modules-embedway-es6220.init | 41 + .../platform-modules-embedway-es6220.install | 5 + .../platform-modules-embedway-es6220.postinst | 3 + .../debian/rules | 35 + .../es6220/modules/Makefile | 2 + .../es6220/modules/dal_kernel.c | 1833 +++++++++++++++++ .../es6220/modules/dal_kernel.h | 171 ++ .../es6220/modules/dal_mpool.c | 350 ++++ .../es6220/modules/dal_mpool.h | 72 + .../scripts/add_crontab_remove_syslog.sh | 12 + .../es6220/scripts/create_eeprom.sh | 18 + .../es6220/scripts/es6220_platform.sh | 30 + .../es6220/scripts/remove_syslog.sh | 9 + .../es6220/service/es6220_platform.service | 13 + src/sonic-config-engine/sonic_device_util.py | 2 +- 53 files changed, 3289 insertions(+), 1953 deletions(-) create mode 100644 device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/buffers.json.j2 create mode 100644 device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/pg_profile_lookup.ini create mode 100644 device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/qos.json create mode 100644 device/centec/x86_64-ew_es6220_x48q2h4-r0/installer.conf create mode 100644 device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/eeprom.py create mode 100644 device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/psuutil.py create mode 100644 device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/sfputil.py delete mode 100644 device/embedway/x86_64-ew_es6220_x48q2h4-r0/default_sku delete mode 100644 device/embedway/x86_64-ew_es6220_x48q2h4-r0/installer.conf create mode 100644 platform/centec/platform-modules-embedway.mk delete mode 100644 platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db.json delete mode 100644 platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db_l2l3.json delete mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db.json delete mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db_l2l3.json create mode 100644 platform/centec/sonic-platform-modules-embedway/LICENSE create mode 100644 platform/centec/sonic-platform-modules-embedway/README.md create mode 100644 platform/centec/sonic-platform-modules-embedway/debian/changelog create mode 100644 platform/centec/sonic-platform-modules-embedway/debian/compat create mode 100644 platform/centec/sonic-platform-modules-embedway/debian/control create mode 100755 platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.init create mode 100644 platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.install create mode 100644 platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.postinst create mode 100755 platform/centec/sonic-platform-modules-embedway/debian/rules create mode 100644 platform/centec/sonic-platform-modules-embedway/es6220/modules/Makefile create mode 100644 platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.c create mode 100644 platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.h create mode 100644 platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.c create mode 100644 platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.h create mode 100755 platform/centec/sonic-platform-modules-embedway/es6220/scripts/add_crontab_remove_syslog.sh create mode 100755 platform/centec/sonic-platform-modules-embedway/es6220/scripts/create_eeprom.sh create mode 100755 platform/centec/sonic-platform-modules-embedway/es6220/scripts/es6220_platform.sh create mode 100755 platform/centec/sonic-platform-modules-embedway/es6220/scripts/remove_syslog.sh create mode 100644 platform/centec/sonic-platform-modules-embedway/es6220/service/es6220_platform.service diff --git a/device/centec/x86_64-centec_e582_48x2q4z-r0/E582-48x2q4z/port_config.ini b/device/centec/x86_64-centec_e582_48x2q4z-r0/E582-48x2q4z/port_config.ini index 78a1df9f051d..5b35cd7f5111 100644 --- a/device/centec/x86_64-centec_e582_48x2q4z-r0/E582-48x2q4z/port_config.ini +++ b/device/centec/x86_64-centec_e582_48x2q4z-r0/E582-48x2q4z/port_config.ini @@ -1,24 +1,24 @@ # name lanes alias speed -Ethernet1 75 eth-0-1 1000 -Ethernet2 73 eth-0-2 1000 -Ethernet3 72 eth-0-3 1000 -Ethernet4 70 eth-0-4 1000 -Ethernet5 69 eth-0-5 1000 -Ethernet6 67 eth-0-6 1000 -Ethernet7 66 eth-0-7 1000 -Ethernet8 64 eth-0-8 1000 -Ethernet9 63 eth-0-9 1000 -Ethernet10 61 eth-0-10 1000 -Ethernet11 60 eth-0-11 1000 -Ethernet12 58 eth-0-12 1000 -Ethernet13 57 eth-0-13 10000 -Ethernet14 56 eth-0-14 10000 -Ethernet15 55 eth-0-15 10000 -Ethernet16 53 eth-0-16 10000 -Ethernet17 52 eth-0-17 10000 -Ethernet18 50 eth-0-18 10000 -Ethernet19 49 eth-0-19 10000 -Ethernet20 48 eth-0-20 10000 +Ethernet1 91 eth-0-1 10000 +Ethernet2 89 eth-0-2 10000 +Ethernet3 88 eth-0-3 10000 +Ethernet4 86 eth-0-4 10000 +Ethernet5 85 eth-0-5 10000 +Ethernet6 83 eth-0-6 10000 +Ethernet7 82 eth-0-7 10000 +Ethernet8 80 eth-0-8 10000 +Ethernet9 79 eth-0-9 10000 +Ethernet10 77 eth-0-10 10000 +Ethernet11 76 eth-0-11 10000 +Ethernet12 74 eth-0-12 10000 +Ethernet13 73 eth-0-13 10000 +Ethernet14 72 eth-0-14 10000 +Ethernet15 71 eth-0-15 10000 +Ethernet16 69 eth-0-16 10000 +Ethernet17 68 eth-0-17 10000 +Ethernet18 66 eth-0-18 10000 +Ethernet19 65 eth-0-19 10000 +Ethernet20 64 eth-0-20 10000 Ethernet21 0 eth-0-21 10000 Ethernet22 1 eth-0-22 10000 Ethernet23 3 eth-0-23 10000 @@ -46,10 +46,10 @@ Ethernet44 30 eth-0-44 10000 Ethernet45 31 eth-0-45 10000 Ethernet46 33 eth-0-46 10000 Ethernet47 34 eth-0-47 10000 -Ethernet48 36 eth-0-48 10000 -Ethernet49 42,41,43,40 eth-0-49 40000 -Ethernet50 45,46,44,47 eth-0-50 40000 -Ethernet51 94,93,95,92 eth-0-51 100000 -Ethernet52 89,90,88,91 eth-0-52 100000 -Ethernet53 85,86,84,87 eth-0-53 100000 -Ethernet54 81,82,80,83 eth-0-54 100000 +Ethernet48 48 eth-0-48 10000 +Ethernet49 38,37,39,36 eth-0-49 100000 +Ethernet50 53,54,52,55 eth-0-50 100000 +Ethernet51 118,117,119,116 eth-0-51 100000 +Ethernet52 101,102,100,103 eth-0-52 100000 +Ethernet53 113,114,112,115 eth-0-53 40000 +Ethernet54 97,98,96,99 eth-0-54 40000 diff --git a/device/centec/x86_64-centec_e582_48x2q4z-r0/default_sku b/device/centec/x86_64-centec_e582_48x2q4z-r0/default_sku index 89c83dc3d0e3..332f7a2b4764 100644 --- a/device/centec/x86_64-centec_e582_48x2q4z-r0/default_sku +++ b/device/centec/x86_64-centec_e582_48x2q4z-r0/default_sku @@ -1 +1 @@ -E582-48x2q4z t1 +E582-48x2q4z l2 diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini index efb24937cec1..5e370ab2f1a3 100644 --- a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini +++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini @@ -1,16 +1,16 @@ # name lanes alias speed -Ethernet1 4 eth-0-1 1000 -Ethernet2 5 eth-0-2 1000 -Ethernet3 6 eth-0-3 1000 -Ethernet4 8 eth-0-4 1000 -Ethernet5 9 eth-0-5 1000 -Ethernet6 10 eth-0-6 1000 -Ethernet7 12 eth-0-7 1000 -Ethernet8 13 eth-0-8 1000 -Ethernet9 14 eth-0-9 1000 -Ethernet10 16 eth-0-10 1000 -Ethernet11 17 eth-0-11 1000 -Ethernet12 18 eth-0-12 1000 +Ethernet1 4 eth-0-1 10000 +Ethernet2 5 eth-0-2 10000 +Ethernet3 6 eth-0-3 10000 +Ethernet4 8 eth-0-4 10000 +Ethernet5 9 eth-0-5 10000 +Ethernet6 10 eth-0-6 10000 +Ethernet7 12 eth-0-7 10000 +Ethernet8 13 eth-0-8 10000 +Ethernet9 14 eth-0-9 10000 +Ethernet10 16 eth-0-10 10000 +Ethernet11 17 eth-0-11 10000 +Ethernet12 18 eth-0-12 10000 Ethernet13 20 eth-0-13 10000 Ethernet14 21 eth-0-14 10000 Ethernet15 22 eth-0-15 10000 @@ -23,33 +23,33 @@ Ethernet21 31 eth-0-21 10000 Ethernet22 32 eth-0-22 10000 Ethernet23 34 eth-0-23 10000 Ethernet24 35 eth-0-24 10000 -Ethernet25 36 eth-0-25 10000 -Ethernet26 37 eth-0-26 10000 -Ethernet27 39 eth-0-27 10000 -Ethernet28 40 eth-0-28 10000 -Ethernet29 41 eth-0-29 10000 -Ethernet30 43 eth-0-30 10000 -Ethernet31 47 eth-0-31 10000 -Ethernet32 46 eth-0-32 10000 -Ethernet33 45 eth-0-33 10000 -Ethernet34 44 eth-0-34 10000 -Ethernet35 92 eth-0-35 10000 -Ethernet36 93 eth-0-36 10000 -Ethernet37 94 eth-0-37 10000 -Ethernet38 95 eth-0-38 10000 -Ethernet39 90 eth-0-39 10000 -Ethernet40 89 eth-0-40 10000 -Ethernet41 88 eth-0-41 10000 -Ethernet42 87 eth-0-42 10000 -Ethernet43 86 eth-0-43 10000 -Ethernet44 85 eth-0-44 10000 -Ethernet45 84 eth-0-45 10000 -Ethernet46 82 eth-0-46 10000 -Ethernet47 81 eth-0-47 10000 -Ethernet48 80 eth-0-48 10000 -Ethernet49 77,78,76,79 eth-0-49 40000 -Ethernet50 73,74,72,75 eth-0-50 40000 -Ethernet51 70,71,69,68 eth-0-51 40000 -Ethernet52 61,63,60,62 eth-0-52 40000 -Ethernet53 59,57,58,56 eth-0-53 40000 -Ethernet54 53,55,54,52 eth-0-54 40000 +Ethernet25 48 eth-0-25 10000 +Ethernet26 49 eth-0-26 10000 +Ethernet27 51 eth-0-27 10000 +Ethernet28 36 eth-0-28 10000 +Ethernet29 37 eth-0-29 10000 +Ethernet30 39 eth-0-30 10000 +Ethernet31 55 eth-0-31 10000 +Ethernet32 54 eth-0-32 10000 +Ethernet33 53 eth-0-33 10000 +Ethernet34 52 eth-0-34 10000 +Ethernet35 116 eth-0-35 10000 +Ethernet36 117 eth-0-36 10000 +Ethernet37 118 eth-0-37 10000 +Ethernet38 119 eth-0-38 10000 +Ethernet39 102 eth-0-39 10000 +Ethernet40 101 eth-0-40 10000 +Ethernet41 100 eth-0-41 10000 +Ethernet42 115 eth-0-42 10000 +Ethernet43 114 eth-0-43 10000 +Ethernet44 113 eth-0-44 10000 +Ethernet45 112 eth-0-45 10000 +Ethernet46 98 eth-0-46 10000 +Ethernet47 97 eth-0-47 10000 +Ethernet48 96 eth-0-48 10000 +Ethernet49 93,94,92,95 eth-0-49 40000 +Ethernet50 89,90,88,91 eth-0-50 40000 +Ethernet51 86,87,85,84 eth-0-51 40000 +Ethernet52 77,79,76,78 eth-0-52 40000 +Ethernet53 75,73,74,72 eth-0-53 40000 +Ethernet54 69,71,70,68 eth-0-54 40000 diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/default_sku b/device/centec/x86_64-centec_e582_48x6q-r0/default_sku index e0f7b24535b6..bad98ce86f83 100644 --- a/device/centec/x86_64-centec_e582_48x6q-r0/default_sku +++ b/device/centec/x86_64-centec_e582_48x6q-r0/default_sku @@ -1 +1 @@ -E582-48x6q t1 +E582-48x6q l2 diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/buffers.json.j2 b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/buffers.json.j2 new file mode 100644 index 000000000000..08e21e428b6c --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/buffers.json.j2 @@ -0,0 +1,70 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(1,default_ports_num+1) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + } +} + diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/pg_profile_lookup.ini b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/pg_profile_lookup.ini new file mode 100644 index 000000000000..a65244e69b5b --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/pg_profile_lookup.ini @@ -0,0 +1,21 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 1000 5m 34816 18432 16384 0 + 10000 5m 34816 18432 16384 0 + 25000 5m 34816 18432 16384 0 + 40000 5m 34816 18432 16384 0 + 50000 5m 34816 18432 16384 0 + 100000 5m 36864 18432 18432 0 + 1000 40m 36864 18432 18432 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 39936 18432 21504 0 + 40000 40m 41984 18432 23552 0 + 50000 40m 41984 18432 23552 0 + 100000 40m 54272 18432 35840 0 + 1000 300m 49152 18432 30720 0 + 10000 300m 49152 18432 30720 0 + 25000 300m 71680 18432 53248 0 + 40000 300m 94208 18432 75776 0 + 50000 300m 94208 18432 75776 0 + 100000 300m 184320 18432 165888 0 + diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/port_config.ini b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/port_config.ini index b9a831f22e8d..5b35cd7f5111 100644 --- a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/port_config.ini +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/port_config.ini @@ -1,33 +1,55 @@ -# name lanes -Ethernet0 1 -Ethernet4 2 -Ethernet8 3 -Ethernet12 4 -Ethernet16 5 -Ethernet20 6 -Ethernet24 7 -Ethernet28 8 -Ethernet32 9 -Ethernet36 10 -Ethernet40 11 -Ethernet44 12 -Ethernet48 13 -Ethernet52 14 -Ethernet56 15 -Ethernet60 16 -Ethernet64 17 -Ethernet68 18 -Ethernet72 19 -Ethernet76 20 -Ethernet80 21 -Ethernet84 22 -Ethernet88 23 -Ethernet92 24 -Ethernet96 25 -Ethernet100 26 -Ethernet104 27 -Ethernet108 28 -Ethernet112 29 -Ethernet116 30 -Ethernet120 31 -Ethernet124 32 +# name lanes alias speed +Ethernet1 91 eth-0-1 10000 +Ethernet2 89 eth-0-2 10000 +Ethernet3 88 eth-0-3 10000 +Ethernet4 86 eth-0-4 10000 +Ethernet5 85 eth-0-5 10000 +Ethernet6 83 eth-0-6 10000 +Ethernet7 82 eth-0-7 10000 +Ethernet8 80 eth-0-8 10000 +Ethernet9 79 eth-0-9 10000 +Ethernet10 77 eth-0-10 10000 +Ethernet11 76 eth-0-11 10000 +Ethernet12 74 eth-0-12 10000 +Ethernet13 73 eth-0-13 10000 +Ethernet14 72 eth-0-14 10000 +Ethernet15 71 eth-0-15 10000 +Ethernet16 69 eth-0-16 10000 +Ethernet17 68 eth-0-17 10000 +Ethernet18 66 eth-0-18 10000 +Ethernet19 65 eth-0-19 10000 +Ethernet20 64 eth-0-20 10000 +Ethernet21 0 eth-0-21 10000 +Ethernet22 1 eth-0-22 10000 +Ethernet23 3 eth-0-23 10000 +Ethernet24 2 eth-0-24 10000 +Ethernet25 4 eth-0-25 10000 +Ethernet26 5 eth-0-26 10000 +Ethernet27 6 eth-0-27 10000 +Ethernet28 7 eth-0-28 10000 +Ethernet29 8 eth-0-29 10000 +Ethernet30 9 eth-0-30 10000 +Ethernet31 10 eth-0-31 10000 +Ethernet32 12 eth-0-32 10000 +Ethernet33 13 eth-0-33 10000 +Ethernet34 15 eth-0-34 10000 +Ethernet35 16 eth-0-35 10000 +Ethernet36 18 eth-0-36 10000 +Ethernet37 19 eth-0-37 10000 +Ethernet38 21 eth-0-38 10000 +Ethernet39 22 eth-0-39 10000 +Ethernet40 24 eth-0-40 10000 +Ethernet41 25 eth-0-41 10000 +Ethernet42 27 eth-0-42 10000 +Ethernet43 28 eth-0-43 10000 +Ethernet44 30 eth-0-44 10000 +Ethernet45 31 eth-0-45 10000 +Ethernet46 33 eth-0-46 10000 +Ethernet47 34 eth-0-47 10000 +Ethernet48 48 eth-0-48 10000 +Ethernet49 38,37,39,36 eth-0-49 100000 +Ethernet50 53,54,52,55 eth-0-50 100000 +Ethernet51 118,117,119,116 eth-0-51 100000 +Ethernet52 101,102,100,103 eth-0-52 100000 +Ethernet53 113,114,112,115 eth-0-53 40000 +Ethernet54 97,98,96,99 eth-0-54 40000 diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/qos.json b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/qos.json new file mode 100644 index 000000000000..b9dc80abb07f --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/qos.json @@ -0,0 +1,133 @@ +{ + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"0", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"2", + "17":"2", + "18":"2", + "19":"2", + "20":"2", + "21":"2", + "22":"2", + "23":"2", + "24":"3", + "25":"3", + "26":"3", + "27":"3", + "28":"3", + "29":"3", + "30":"3", + "31":"3", + "32":"4", + "33":"4", + "34":"4", + "35":"4", + "36":"4", + "37":"4", + "38":"4", + "39":"4", + "40":"5", + "41":"5", + "42":"5", + "43":"5", + "44":"5", + "45":"5", + "46":"5", + "47":"5", + "48":"6", + "49":"6", + "50":"6", + "51":"6", + "52":"6", + "53":"6", + "54":"6", + "55":"6", + "56":"7", + "57":"7", + "58":"7", + "59":"7", + "60":"7", + "61":"7", + "62":"7", + "63":"7" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1": { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2": { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "red_max_threshold":"32760", + "red_min_threshold":"4095", + "yellow_max_threshold":"32760", + "yellow_min_threshold":"4095", + "green_max_threshold": "32760", + "green_min_threshold": "4095" + }, + "AZURE_LOSSLESS": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "red_max_threshold":"32760", + "red_min_threshold":"4095", + "yellow_max_threshold":"32760", + "yellow_min_threshold":"4095", + "green_max_threshold": "32760", + "green_min_threshold": "4095" + } + }, + "QUEUE": { + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": { + "scheduler" : "[SCHEDULER|scheduler.2]" + }, + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|3-4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + } + } +} + + diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/sai.profile b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/sai.profile index 6a5af192a2b7..006512cb0bf9 100644 --- a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/sai.profile +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/sai.profile @@ -1 +1,2 @@ -BOARD_CONFIG_FILE_PATH=/etc/centec/ES6428A-X48Q2H4.json +SAI_INIT_CONFIG_FILE=/etc/centec/ES6428A-X48Q2H4-chip-profile.txt +SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/etc/centec/ES6428A-X48Q2H4-datapath-cfg.txt diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/default_sku b/device/centec/x86_64-ew_es6220_x48q2h4-r0/default_sku index d10e1b46328c..6f0b38195095 100644 --- a/device/centec/x86_64-ew_es6220_x48q2h4-r0/default_sku +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/default_sku @@ -1 +1 @@ -ES6428A-X48Q2H4 t1 +ES6428A-X48Q2H4 l2 diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/installer.conf b/device/centec/x86_64-ew_es6220_x48q2h4-r0/installer.conf new file mode 100644 index 000000000000..5b03827200c5 --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_SPEED=115200 +CONSOLE_DEV=2 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="acpi_enforce_resources=no" diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/eeprom.py b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/eeprom.py new file mode 100644 index 000000000000..8ac693f7cf58 --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/eeprom.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +############################################################################# +# EmbedWay +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + #output = os.popen('i2cdetect -l | grep CP') + #a=output.read() + #b=a[4] + self.eeprom_path = "/home/admin/eeprom.bin" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/psuutil.py b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/psuutil.py new file mode 100644 index 000000000000..643b80c8986e --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/psuutil.py @@ -0,0 +1,57 @@ +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/bus/i2c/devices/{}-0058/" + self.psu_oper_status = "in1_input" + self.psu_presence = "i2cget -y {} 0x50 0x00" + + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + if index is None: + return False + Base_bus_number = 39 + status = 0 + #index from 1, psu attribute bus from 40 + try: + with open(self.psu_path.format(index + Base_bus_number) + self.psu_oper_status, 'r') as power_status: + if int(power_status.read()) == 0 : + return False + else: + status = 1 + except IOError: + return True + return status == 1 + + def get_psu_presence(self, index): + if index is None: + return False + Base_bus_number = 39 + status = 0 + try: + p = os.popen(self.psu_presence.format(index + Base_bus_number)+ "> /dev/null 2>&1") + if p.readline() != None: + status = 1 + p.close() + except IOError: + return False + return status == 1 + + diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/sfputil.py b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/sfputil.py new file mode 100644 index 000000000000..5ac85e067618 --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/sfputil.py @@ -0,0 +1,187 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import os + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 53 + PORTS_IN_BLOCK = 32 + + EEPROM_OFFSET = 20 + + _port_to_eeprom_mapping = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(0, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for x in range(0, self.port_end + 1): + self._port_to_eeprom_mapping[x] = eeprom_path.format(x + self.EEPROM_OFFSET) + + SfpUtilBase.__init__(self) + + def get_presence(self, port_name): + #modify by zhw to get sfp presence + # Check for invalid port_num + port_num = int(port_name[8:]) + + if port_num < (self.port_start+1) or port_num > (self.port_end+1): + return False + + #cpld info from "CPLD Register for es5800A2.2(V1.1)" + cpld_map = {0: '0x82', 1: '0x83', 2: '0x84', 3: '0x85', 4: '0x86', 5: '0x87', 6: '0x8E'} + cpld_key = (port_num - 1)/8 + cpld_mask = (1 << (port_num - 1)%8) + + #use i2cget cmd to get cpld data + output = os.popen('i2cdetect -l | grep CP') + bus_num = output.read()[4] + cmd = "i2cget -y "+bus_num+" 0x5 "+cpld_map[cpld_key] + tmp = os.popen(cmd).read().replace("\n", "") + cpld_value = int(tmp, 16) + + if cpld_value & cpld_mask == 0: + return True + else: + return False + + def get_low_power_mode(self, port_num): + ''' + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/devices/platform/dell-s6000-cpld.0/qsfp_lpmode") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + content = reg_file.readline().rstrip() + + # content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # LPMode is active high + if reg_value & mask == 0: + return False + ''' + return False + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/devices/platform/dell-s6000-cpld.0/qsfp_lpmode", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + + # content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + content = hex(reg_value) + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + def reset(self, port_num): + QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/devices/platform/dell-s6000-cpld.0/qsfp_reset" + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + + # File content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(reg_value)) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = reg_value | mask + reg_file.seek(0) + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def get_transceiver_change_event(self): + """ + TODO: This function need to be implemented + when decide to support monitoring SFP(Xcvrd) + on this platform. + """ + raise NotImplementedError + + diff --git a/device/embedway/x86_64-ew_es6220_x48q2h4-r0/default_sku b/device/embedway/x86_64-ew_es6220_x48q2h4-r0/default_sku deleted file mode 100644 index 0f663505d7a4..000000000000 --- a/device/embedway/x86_64-ew_es6220_x48q2h4-r0/default_sku +++ /dev/null @@ -1 +0,0 @@ -OSW1800-48x6q t1 diff --git a/device/embedway/x86_64-ew_es6220_x48q2h4-r0/installer.conf b/device/embedway/x86_64-ew_es6220_x48q2h4-r0/installer.conf deleted file mode 100644 index 5e62742c11bf..000000000000 --- a/device/embedway/x86_64-ew_es6220_x48q2h4-r0/installer.conf +++ /dev/null @@ -1 +0,0 @@ -CONSOLE_SPEED=115200 diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 3352e5fbb7ec..e4e28a347a34 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -25,10 +25,7 @@ elif [ "$platform" == "cavium" ]; then elif [ "$platform" == "nephos" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "centec" ]; then - last_byte=$(python -c "print '$MAC_ADDRESS'[-2:]") - aligned_last_byte=$(python -c "print format(int(int('$last_byte', 16) + 1), '02x')") # put mask and take away the 0x prefix - ALIGNED_MAC_ADDRESS=$(python -c "print '$MAC_ADDRESS'[:-2] + '$aligned_last_byte'") # put aligned byte into the end of MAC - ORCHAGENT_ARGS+="-m $ALIGNED_MAC_ADDRESS" + ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "barefoot" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "vs" ]; then diff --git a/platform/centec/docker-ptf-centec.mk b/platform/centec/docker-ptf-centec.mk index ff84ed0becb7..3d4fe50e5f1f 100644 --- a/platform/centec/docker-ptf-centec.mk +++ b/platform/centec/docker-ptf-centec.mk @@ -2,6 +2,6 @@ DOCKER_PTF_CENTEC = docker-ptf-centec.gz $(DOCKER_PTF_CENTEC)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift -$(DOCKER_PTF_CENTEC)_DEPENDS += $(PYTHON_SAITHRIFT_CENTEC) +$(DOCKER_PTF_CENTEC)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_CENTEC)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_CENTEC) diff --git a/platform/centec/docker-syncd-centec-rpc.mk b/platform/centec/docker-syncd-centec-rpc.mk index 47c672dd93de..a13a32d4a5b4 100644 --- a/platform/centec/docker-syncd-centec-rpc.mk +++ b/platform/centec/docker-syncd-centec-rpc.mk @@ -17,7 +17,7 @@ SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC_RPC) endif $(DOCKER_SYNCD_CENTEC_RPC)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/platform/centec/docker-syncd-centec.mk b/platform/centec/docker-syncd-centec.mk index a0dbcc629dee..f5cadc0b3f6d 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -10,14 +10,14 @@ $(DOCKER_SYNCD_CENTEC)_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) endif -$(DOCKER_SYNCD_CENTEC)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) +$(DOCKER_SYNCD_CENTEC)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC) ifneq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC) endif $(DOCKER_SYNCD_CENTEC)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_CENTEC)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_CENTEC)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/platform/centec/docker-syncd-centec/Dockerfile.j2 b/platform/centec/docker-syncd-centec/Dockerfile.j2 index b40103a24f28..0dfdd9488247 100755 --- a/platform/centec/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine +FROM docker-config-engine-stretch ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -20,7 +20,7 @@ debs/{{ deb }}{{' '}} {%- endfor %} ## TODO: add kmod into Depends -RUN apt-get install -f kmod +RUN apt-get install -yf kmod COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] diff --git a/platform/centec/one-image.mk b/platform/centec/one-image.mk index 0e057b24df03..a92c97078846 100644 --- a/platform/centec/one-image.mk +++ b/platform/centec/one-image.mk @@ -5,7 +5,8 @@ $(SONIC_ONE_IMAGE)_MACHINE = centec $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS = $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) \ - $(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE) + $(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE) \ + $(EMBEDWAY_ES6220_PLATFORM_MODULE) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/centec/platform-modules-embedway.mk b/platform/centec/platform-modules-embedway.mk new file mode 100644 index 000000000000..366080f04114 --- /dev/null +++ b/platform/centec/platform-modules-embedway.mk @@ -0,0 +1,13 @@ +# embedway es6220 Platform modules + +EMBEDWAY_ES6220_PLATFORM_MODULE_VERSION =1.1 + +export EMBEDWAY_ES6220_PLATFORM_MODULE_VERSION + +EMBEDWAY_ES6220_PLATFORM_MODULE = platform-modules-embedway-es6220_$(EMBEDWAY_ES6220_PLATFORM_MODULE_VERSION)_amd64.deb + +$(EMBEDWAY_ES6220_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-embedway +$(EMBEDWAY_ES6220_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(EMBEDWAY_ES6220_PLATFORM_MODULE)_PLATFORM = x86_64-ew_es6220_x48q2h4-r0 +SONIC_STRETCH_DEBS += $(EMBEDWAY_ES6220_PLATFORM_MODULE) +SONIC_DPKG_DEBS += $(EMBEDWAY_ES6220_PLATFORM_MODULE) \ No newline at end of file diff --git a/platform/centec/rules.mk b/platform/centec/rules.mk index 53759cb67f40..942d98a6556e 100644 --- a/platform/centec/rules.mk +++ b/platform/centec/rules.mk @@ -1,4 +1,5 @@ include $(PLATFORM_PATH)/platform-modules-centec-e582.mk +include $(PLATFORM_PATH)/platform-modules-embedway.mk include $(PLATFORM_PATH)/sdk.mk include $(PLATFORM_PATH)/docker-syncd-centec.mk include $(PLATFORM_PATH)/docker-syncd-centec-rpc.mk @@ -7,7 +8,6 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-centec.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ - $(DOCKER_PTF_CENTEC) \ $(DOCKER_SYNCD_CENTEC_RPC) # Inject centec sai into sairedis diff --git a/platform/centec/sdk.mk b/platform/centec/sdk.mk index c529762dafc8..c2f2023cc8e7 100644 --- a/platform/centec/sdk.mk +++ b/platform/centec/sdk.mk @@ -1,5 +1,5 @@ # Centec SAI -CENTEC_SAI = libsai_1.3.3_amd64.deb -$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/goldengate-sai/raw/master/lib/SONiC_1.3.3/libsai_1.3.3-1.0_amd64.deb +CENTEC_SAI = libsai_1.5.1_amd64.deb +$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/libsai_1.5.1-1.0_amd64.deb SONIC_ONLINE_DEBS += $(CENTEC_SAI) diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db.json b/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db.json deleted file mode 100644 index 3a5c8ba914b5..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db.json +++ /dev/null @@ -1,302 +0,0 @@ -{ - "DEVICE_METADATA": { - "localhost": { - "bgp_asn": 65100, - "deployment_id": null, - "hostname": "switch1", - "type": "LeafRouter", - "hwsku": "E582-48x6q" - - } - }, - "BGP_PEER_RANGE": {}, - "VLAN": {}, - "PORT": { - "Ethernet1": { - "alias": "eth-0-1", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet2": { - "alias": "eth-0-2", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet3": { - "alias": "eth-0-3", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet4": { - "alias": "eth-0-4", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet5": { - "alias": "eth-0-5", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet6": { - "alias": "eth-0-6", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet7": { - "alias": "eth-0-7", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet8": { - "alias": "eth-0-8", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet9": { - "alias": "eth-0-9", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet10": { - "alias": "eth-0-10", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet11": { - "alias": "eth-0-11", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet12": { - "alias": "eth-0-12", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet13": { - "alias": "eth-0-13", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet14": { - "alias": "eth-0-14", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet15": { - "alias": "eth-0-15", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet16": { - "alias": "eth-0-16", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet17": { - "alias": "eth-0-17", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet18": { - "alias": "eth-0-18", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet19": { - "alias": "eth-0-19", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet20": { - "alias": "eth-0-20", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet21": { - "alias": "eth-0-21", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet22": { - "alias": "eth-0-22", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet23": { - "alias": "eth-0-23", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet24": { - "alias": "eth-0-24", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet25": { - "alias": "eth-0-25", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet26": { - "alias": "eth-0-26", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet27": { - "alias": "eth-0-27", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet28": { - "alias": "eth-0-28", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet29": { - "alias": "eth-0-29", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet30": { - "alias": "eth-0-30", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet31": { - "alias": "eth-0-31", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet32": { - "alias": "eth-0-32", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet33": { - "alias": "eth-0-33", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet34": { - "alias": "eth-0-34", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet35": { - "alias": "eth-0-35", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet36": { - "alias": "eth-0-36", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet37": { - "alias": "eth-0-37", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet38": { - "alias": "eth-0-38", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet39": { - "alias": "eth-0-39", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet40": { - "alias": "eth-0-40", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet41": { - "alias": "eth-0-41", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet42": { - "alias": "eth-0-42", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet43": { - "alias": "eth-0-43", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet44": { - "alias": "eth-0-44", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet45": { - "alias": "eth-0-45", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet46": { - "alias": "eth-0-46", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet47": { - "alias": "eth-0-47", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet48": { - "alias": "eth-0-48", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet49": { - "alias": "eth-0-49", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet50": { - "alias": "eth-0-50", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet51": { - "alias": "eth-0-51", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet52": { - "alias": "eth-0-52", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet53": { - "alias": "eth-0-53", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet54": { - "alias": "eth-0-54", - "speed": "100000", - "mtu": "9100" - } - }, - "SYSLOG_SERVER": {}, - "VLAN_INTERFACE": {}, - "PORTCHANNEL_INTERFACE": {}, - "PORTCHANNEL": {}, - "MGMT_INTERFACE": {}, - "DHCP_SERVER": {}, - "LOOPBACK_INTERFACE": { - "Loopback0|127.0.0.1/8": {} - }, - "ACL_TABLE": {}, - "INTERFACE": { - "Ethernet1|192.168.1.1/24": {}, - "Ethernet2|192.168.2.1/24": {}, - "Ethernet3|192.168.3.1/24": {}, - "Ethernet4|192.168.4.1/24": {} - } -} diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db_l2l3.json b/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db_l2l3.json deleted file mode 100644 index dd40332f9049..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db_l2l3.json +++ /dev/null @@ -1,610 +0,0 @@ -{ - "QUEUE": { - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSY]" - }, - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|3-4": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]", - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSY]" - } - }, - "WRED_PROFILE": { - "AZURE_LOSSLESS": { - "red_max_threshold": "32760", - "yellow_max_threshold": "32760", - "green_min_threshold": "4095", - "red_min_threshold": "4095", - "yellow_min_threshold": "4095", - "green_max_threshold": "32760", - "wred_yellow_enable": "true", - "wred_green_enable": "true" - }, - "AZURE_LOSSY": { - "red_max_threshold": "32760", - "yellow_max_threshold": "32760", - "green_min_threshold": "4095", - "red_min_threshold": "4095", - "yellow_min_threshold": "4095", - "green_max_threshold": "32760", - "wred_yellow_enable": "true", - "wred_green_enable": "true" - } - }, - "DSCP_TO_TC_MAP": { - "AZURE": { - "56": "7", - "54": "6", - "28": "3", - "48": "6", - "29": "3", - "60": "7", - "61": "7", - "62": "7", - "63": "7", - "49": "6", - "34": "4", - "24": "3", - "25": "3", - "26": "3", - "27": "3", - "20": "2", - "21": "2", - "22": "2", - "23": "2", - "46": "5", - "47": "5", - "44": "5", - "45": "5", - "42": "5", - "43": "5", - "40": "5", - "41": "5", - "1": "0", - "0": "0", - "3": "0", - "2": "0", - "5": "0", - "4": "0", - "7": "0", - "6": "0", - "9": "1", - "8": "1", - "35": "4", - "13": "1", - "12": "1", - "15": "1", - "58": "7", - "11": "1", - "10": "1", - "39": "4", - "38": "4", - "59": "7", - "14": "1", - "17": "2", - "16": "2", - "19": "2", - "18": "2", - "31": "3", - "30": "3", - "51": "6", - "36": "4", - "53": "6", - "52": "6", - "33": "4", - "55": "6", - "37": "4", - "32": "4", - "57": "7", - "50": "6" - } - }, - "DEVICE_METADATA": { - "localhost": { - "hwsku": "E582-48x6q", - "hostname": "switch1", - "bgp_asn": "None", - "deployment_id": "None", - "type": "LeafRouter" - } - }, - "PORT": { - "Ethernet1": { - "alias": "eth-0-1", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet2": { - "alias": "eth-0-2", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet3": { - "alias": "eth-0-3", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet4": { - "alias": "eth-0-4", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet5": { - "alias": "eth-0-5", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet6": { - "alias": "eth-0-6", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet7": { - "alias": "eth-0-7", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet8": { - "alias": "eth-0-8", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet9": { - "alias": "eth-0-9", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet10": { - "alias": "eth-0-10", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet11": { - "alias": "eth-0-11", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet12": { - "alias": "eth-0-12", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet13": { - "alias": "eth-0-13", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet14": { - "alias": "eth-0-14", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet15": { - "alias": "eth-0-15", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet16": { - "alias": "eth-0-16", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet17": { - "alias": "eth-0-17", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet18": { - "alias": "eth-0-18", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet19": { - "alias": "eth-0-19", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet20": { - "alias": "eth-0-20", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet21": { - "alias": "eth-0-21", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet22": { - "alias": "eth-0-22", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet23": { - "alias": "eth-0-23", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet24": { - "alias": "eth-0-24", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet25": { - "alias": "eth-0-25", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet26": { - "alias": "eth-0-26", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet27": { - "alias": "eth-0-27", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet28": { - "alias": "eth-0-28", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet29": { - "alias": "eth-0-29", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet30": { - "alias": "eth-0-30", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet31": { - "alias": "eth-0-31", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet32": { - "alias": "eth-0-32", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet33": { - "alias": "eth-0-33", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet34": { - "alias": "eth-0-34", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet35": { - "alias": "eth-0-35", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet36": { - "alias": "eth-0-36", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet37": { - "alias": "eth-0-37", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet38": { - "alias": "eth-0-38", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet39": { - "alias": "eth-0-39", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet40": { - "alias": "eth-0-40", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet41": { - "alias": "eth-0-41", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet42": { - "alias": "eth-0-42", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet43": { - "alias": "eth-0-43", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet44": { - "alias": "eth-0-44", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet45": { - "alias": "eth-0-45", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet46": { - "alias": "eth-0-46", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet47": { - "alias": "eth-0-47", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet48": { - "alias": "eth-0-48", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet49": { - "alias": "eth-0-49", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet50": { - "alias": "eth-0-50", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet51": { - "alias": "eth-0-51", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet52": { - "alias": "eth-0-52", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet53": { - "alias": "eth-0-53", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet54": { - "alias": "eth-0-54", - "speed": "100000", - "mtu": "9100" - } - }, - "PORT_QOS_MAP": { - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54": { - "pfc_enable": "3,4", - "dscp_to_tc_map": "[DSCP_TO_TC_MAP|AZURE]" - } - }, - "SCHEDULER": { - "scheduler.0": { - "type": "DWRR", - "weight": "25" - }, - "scheduler.1": { - "type": "DWRR", - "weight": "30" - }, - "scheduler.2": { - "type": "DWRR", - "weight": "20" - } - }, - "VLAN": { - "Vlan500": { - "dhcp_servers": [ - "192.168.5.1", - "192.168.5.2", - "192.168.5.3", - "192.168.5.4" - ], - "members": [ - "Ethernet5", - "Ethernet6", - "Ethernet7", - "Ethernet8" - ], - "vlanid": "500" - }, - "Vlan600": { - "dhcp_servers": [ - "192.168.6.1", - "192.168.6.2", - "192.168.6.3", - "192.168.6.4" - ], - "members": [ - "Ethernet5", - "Ethernet6" - ], - "vlanid": "600" - }, - "Vlan700": { - "dhcp_servers": [ - "192.168.7.1", - "192.168.7.2", - "192.168.7.3", - "192.168.7.4" - ], - "members": [ - "Ethernet5", - "Ethernet7" - ], - "vlanid": "700" - }, - "Vlan800": { - "dhcp_servers": [ - "192.168.8.1", - "192.168.8.2", - "192.168.8.3", - "192.168.8.4" - ], - "members": [ - "Ethernet5", - "Ethernet8" - ], - "vlanid": "800" - } - }, - "VLAN_MEMBER": { - "Vlan500|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan500|Ethernet6": { - "tagging_mode": "untagged" - }, - "Vlan500|Ethernet7": { - "tagging_mode": "untagged" - }, - "Vlan500|Ethernet8": { - "tagging_mode": "untagged" - }, - "Vlan600|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan600|Ethernet6": { - "tagging_mode": "tagged" - }, - "Vlan700|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan700|Ethernet7": { - "tagging_mode": "tagged" - }, - "Vlan800|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan800|Ethernet8": { - "tagging_mode": "tagged" - } - }, - "INTERFACE": { - "Ethernet1|192.168.1.1/24": {}, - "Ethernet2|192.168.2.1/24": {}, - "Ethernet3|192.168.3.1/24": {}, - "Ethernet4|192.168.4.1/24": {} - }, - "VLAN_INTERFACE": { - "Vlan500|192.168.5.1/24": {}, - "Vlan600|192.168.6.1/24": {}, - "Vlan700|192.168.7.1/24": {}, - "Vlan800|192.168.8.1/24": {} - }, - "LOOPBACK_INTERFACE": { - "Loopback0|127.0.0.1/8": {} - }, - "CABLE_LENGTH": { - "AZURE": { - "Ethernet8": "40m", - "Ethernet9": "40m", - "Ethernet2": "40m", - "Ethernet3": "40m", - "Ethernet1": "40m", - "Ethernet6": "40m", - "Ethernet7": "40m", - "Ethernet4": "40m", - "Ethernet5": "40m", - "Ethernet22": "40m", - "Ethernet50": "40m", - "Ethernet51": "40m", - "Ethernet52": "40m", - "Ethernet53": "40m", - "Ethernet54": "40m", - "Ethernet38": "40m", - "Ethernet39": "40m", - "Ethernet18": "40m", - "Ethernet19": "40m", - "Ethernet14": "40m", - "Ethernet15": "40m", - "Ethernet16": "40m", - "Ethernet17": "40m", - "Ethernet10": "40m", - "Ethernet11": "40m", - "Ethernet12": "40m", - "Ethernet35": "40m", - "Ethernet37": "40m", - "Ethernet32": "40m", - "Ethernet33": "40m", - "Ethernet30": "40m", - "Ethernet31": "40m", - "Ethernet49": "40m", - "Ethernet48": "40m", - "Ethernet47": "40m", - "Ethernet36": "40m", - "Ethernet45": "40m", - "Ethernet44": "40m", - "Ethernet43": "40m", - "Ethernet42": "40m", - "Ethernet41": "40m", - "Ethernet40": "40m", - "Ethernet29": "40m", - "Ethernet28": "40m", - "Ethernet34": "40m", - "Ethernet46": "40m", - "Ethernet21": "40m", - "Ethernet20": "40m", - "Ethernet23": "40m", - "Ethernet13": "40m", - "Ethernet25": "40m", - "Ethernet24": "40m", - "Ethernet27": "40m", - "Ethernet26": "40m" - } - }, - "CRM": { - "Config": { - "acl_table_threshold_type": "percentage", - "nexthop_group_threshold_type": "percentage", - "fdb_entry_high_threshold": "85", - "acl_entry_threshold_type": "percentage", - "ipv6_neighbor_low_threshold": "70", - "nexthop_group_member_low_threshold": "70", - "acl_group_high_threshold": "85", - "ipv4_route_high_threshold": "85", - "acl_counter_high_threshold": "85", - "ipv4_route_low_threshold": "70", - "ipv4_route_threshold_type": "percentage", - "ipv4_neighbor_low_threshold": "70", - "acl_group_threshold_type": "percentage", - "ipv4_nexthop_high_threshold": "85", - "ipv6_route_threshold_type": "percentage", - "nexthop_group_low_threshold": "70", - "ipv4_neighbor_high_threshold": "85", - "ipv6_route_high_threshold": "85", - "ipv6_nexthop_threshold_type": "percentage", - "polling_interval": "300", - "ipv4_nexthop_threshold_type": "percentage", - "acl_group_low_threshold": "70", - "acl_entry_low_threshold": "70", - "nexthop_group_member_threshold_type": "percentage", - "ipv4_nexthop_low_threshold": "70", - "acl_counter_threshold_type": "percentage", - "ipv6_neighbor_high_threshold": "85", - "nexthop_group_member_high_threshold": "85", - "acl_table_low_threshold": "70", - "fdb_entry_threshold_type": "percentage", - "ipv6_neighbor_threshold_type": "percentage", - "acl_table_high_threshold": "85", - "ipv6_nexthop_low_threshold": "70", - "acl_counter_low_threshold": "70", - "ipv4_neighbor_threshold_type": "percentage", - "nexthop_group_high_threshold": "85", - "ipv6_route_low_threshold": "70", - "acl_entry_high_threshold": "85", - "fdb_entry_low_threshold": "70", - "ipv6_nexthop_high_threshold": "85" - } - } -} diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c index 16bed86593b2..7a90ac29f369 100644 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c @@ -1249,7 +1249,7 @@ static ssize_t e582_48x2q4z_sfp_write_enable(struct device *dev, struct device_a } else if ((portNum >= 41) && (portNum <= 48)) { - reg_no = portNum - 17;/*8-13*/ + reg_no = portNum - 33;/*8-13*/ i2c_sfp_client = i2c_client_gpio3; } else if ((portNum >= 49) && (portNum <= 54)) diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh b/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh index 2f6583bc487b..0edb50901425 100755 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh @@ -58,7 +58,7 @@ if [ "$1" == "init" ]; then i2cset -y 17 0x22 0x1a 0xff i2cset -y 17 0x22 0x1b 0x0 i2cset -y 17 0x22 0x1c 0xff - i2cset -y 17 0x22 0x9 0x0 + i2cset -y 17 0x22 0x9 0xf0 i2cset -y 17 0x22 0xb 0x0c #start platform monitor diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db.json b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db.json deleted file mode 100644 index 995ac0444b99..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db.json +++ /dev/null @@ -1,302 +0,0 @@ -{ - "DEVICE_METADATA": { - "localhost": { - "bgp_asn": 65100, - "deployment_id": null, - "hostname": "switch1", - "type": "LeafRouter", - "hwsku": "E582-48x6q" - - } - }, - "BGP_PEER_RANGE": {}, - "VLAN": {}, - "PORT": { - "Ethernet1": { - "alias": "eth-0-1", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet2": { - "alias": "eth-0-2", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet3": { - "alias": "eth-0-3", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet4": { - "alias": "eth-0-4", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet5": { - "alias": "eth-0-5", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet6": { - "alias": "eth-0-6", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet7": { - "alias": "eth-0-7", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet8": { - "alias": "eth-0-8", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet9": { - "alias": "eth-0-9", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet10": { - "alias": "eth-0-10", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet11": { - "alias": "eth-0-11", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet12": { - "alias": "eth-0-12", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet13": { - "alias": "eth-0-13", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet14": { - "alias": "eth-0-14", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet15": { - "alias": "eth-0-15", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet16": { - "alias": "eth-0-16", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet17": { - "alias": "eth-0-17", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet18": { - "alias": "eth-0-18", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet19": { - "alias": "eth-0-19", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet20": { - "alias": "eth-0-20", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet21": { - "alias": "eth-0-21", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet22": { - "alias": "eth-0-22", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet23": { - "alias": "eth-0-23", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet24": { - "alias": "eth-0-24", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet25": { - "alias": "eth-0-25", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet26": { - "alias": "eth-0-26", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet27": { - "alias": "eth-0-27", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet28": { - "alias": "eth-0-28", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet29": { - "alias": "eth-0-29", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet30": { - "alias": "eth-0-30", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet31": { - "alias": "eth-0-31", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet32": { - "alias": "eth-0-32", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet33": { - "alias": "eth-0-33", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet34": { - "alias": "eth-0-34", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet35": { - "alias": "eth-0-35", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet36": { - "alias": "eth-0-36", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet37": { - "alias": "eth-0-37", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet38": { - "alias": "eth-0-38", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet39": { - "alias": "eth-0-39", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet40": { - "alias": "eth-0-40", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet41": { - "alias": "eth-0-41", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet42": { - "alias": "eth-0-42", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet43": { - "alias": "eth-0-43", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet44": { - "alias": "eth-0-44", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet45": { - "alias": "eth-0-45", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet46": { - "alias": "eth-0-46", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet47": { - "alias": "eth-0-47", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet48": { - "alias": "eth-0-48", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet49": { - "alias": "eth-0-49", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet50": { - "alias": "eth-0-50", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet51": { - "alias": "eth-0-51", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet52": { - "alias": "eth-0-52", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet53": { - "alias": "eth-0-53", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet54": { - "alias": "eth-0-54", - "speed": "40000", - "mtu": "9100" - } - }, - "SYSLOG_SERVER": {}, - "VLAN_INTERFACE": {}, - "PORTCHANNEL_INTERFACE": {}, - "PORTCHANNEL": {}, - "MGMT_INTERFACE": {}, - "DHCP_SERVER": {}, - "LOOPBACK_INTERFACE": { - "Loopback0|127.0.0.1/8": {} - }, - "ACL_TABLE": {}, - "INTERFACE": { - "Ethernet1|192.168.1.1/24": {}, - "Ethernet2|192.168.2.1/24": {}, - "Ethernet3|192.168.3.1/24": {}, - "Ethernet4|192.168.4.1/24": {} - } -} diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db_l2l3.json b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db_l2l3.json deleted file mode 100644 index ce6909f3a200..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db_l2l3.json +++ /dev/null @@ -1,610 +0,0 @@ -{ - "QUEUE": { - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSY]" - }, - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|3-4": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]", - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSY]" - } - }, - "WRED_PROFILE": { - "AZURE_LOSSLESS": { - "red_max_threshold": "32760", - "yellow_max_threshold": "32760", - "green_min_threshold": "4095", - "red_min_threshold": "4095", - "yellow_min_threshold": "4095", - "green_max_threshold": "32760", - "wred_yellow_enable": "true", - "wred_green_enable": "true" - }, - "AZURE_LOSSY": { - "red_max_threshold": "32760", - "yellow_max_threshold": "32760", - "green_min_threshold": "4095", - "red_min_threshold": "4095", - "yellow_min_threshold": "4095", - "green_max_threshold": "32760", - "wred_yellow_enable": "true", - "wred_green_enable": "true" - } - }, - "DSCP_TO_TC_MAP": { - "AZURE": { - "56": "7", - "54": "6", - "28": "3", - "48": "6", - "29": "3", - "60": "7", - "61": "7", - "62": "7", - "63": "7", - "49": "6", - "34": "4", - "24": "3", - "25": "3", - "26": "3", - "27": "3", - "20": "2", - "21": "2", - "22": "2", - "23": "2", - "46": "5", - "47": "5", - "44": "5", - "45": "5", - "42": "5", - "43": "5", - "40": "5", - "41": "5", - "1": "0", - "0": "0", - "3": "0", - "2": "0", - "5": "0", - "4": "0", - "7": "0", - "6": "0", - "9": "1", - "8": "1", - "35": "4", - "13": "1", - "12": "1", - "15": "1", - "58": "7", - "11": "1", - "10": "1", - "39": "4", - "38": "4", - "59": "7", - "14": "1", - "17": "2", - "16": "2", - "19": "2", - "18": "2", - "31": "3", - "30": "3", - "51": "6", - "36": "4", - "53": "6", - "52": "6", - "33": "4", - "55": "6", - "37": "4", - "32": "4", - "57": "7", - "50": "6" - } - }, - "DEVICE_METADATA": { - "localhost": { - "hwsku": "E582-48x6q", - "hostname": "switch1", - "bgp_asn": "None", - "deployment_id": "None", - "type": "LeafRouter" - } - }, - "PORT": { - "Ethernet1": { - "alias": "eth-0-1", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet2": { - "alias": "eth-0-2", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet3": { - "alias": "eth-0-3", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet4": { - "alias": "eth-0-4", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet5": { - "alias": "eth-0-5", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet6": { - "alias": "eth-0-6", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet7": { - "alias": "eth-0-7", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet8": { - "alias": "eth-0-8", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet9": { - "alias": "eth-0-9", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet10": { - "alias": "eth-0-10", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet11": { - "alias": "eth-0-11", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet12": { - "alias": "eth-0-12", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet13": { - "alias": "eth-0-13", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet14": { - "alias": "eth-0-14", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet15": { - "alias": "eth-0-15", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet16": { - "alias": "eth-0-16", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet17": { - "alias": "eth-0-17", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet18": { - "alias": "eth-0-18", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet19": { - "alias": "eth-0-19", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet20": { - "alias": "eth-0-20", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet21": { - "alias": "eth-0-21", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet22": { - "alias": "eth-0-22", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet23": { - "alias": "eth-0-23", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet24": { - "alias": "eth-0-24", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet25": { - "alias": "eth-0-25", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet26": { - "alias": "eth-0-26", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet27": { - "alias": "eth-0-27", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet28": { - "alias": "eth-0-28", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet29": { - "alias": "eth-0-29", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet30": { - "alias": "eth-0-30", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet31": { - "alias": "eth-0-31", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet32": { - "alias": "eth-0-32", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet33": { - "alias": "eth-0-33", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet34": { - "alias": "eth-0-34", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet35": { - "alias": "eth-0-35", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet36": { - "alias": "eth-0-36", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet37": { - "alias": "eth-0-37", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet38": { - "alias": "eth-0-38", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet39": { - "alias": "eth-0-39", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet40": { - "alias": "eth-0-40", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet41": { - "alias": "eth-0-41", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet42": { - "alias": "eth-0-42", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet43": { - "alias": "eth-0-43", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet44": { - "alias": "eth-0-44", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet45": { - "alias": "eth-0-45", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet46": { - "alias": "eth-0-46", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet47": { - "alias": "eth-0-47", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet48": { - "alias": "eth-0-48", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet49": { - "alias": "eth-0-49", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet50": { - "alias": "eth-0-50", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet51": { - "alias": "eth-0-51", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet52": { - "alias": "eth-0-52", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet53": { - "alias": "eth-0-53", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet54": { - "alias": "eth-0-54", - "speed": "40000", - "mtu": "9100" - } - }, - "PORT_QOS_MAP": { - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54": { - "pfc_enable": "3,4", - "dscp_to_tc_map": "[DSCP_TO_TC_MAP|AZURE]" - } - }, - "SCHEDULER": { - "scheduler.0": { - "type": "DWRR", - "weight": "25" - }, - "scheduler.1": { - "type": "DWRR", - "weight": "30" - }, - "scheduler.2": { - "type": "DWRR", - "weight": "20" - } - }, - "VLAN": { - "Vlan500": { - "dhcp_servers": [ - "192.168.5.1", - "192.168.5.2", - "192.168.5.3", - "192.168.5.4" - ], - "members": [ - "Ethernet5", - "Ethernet6", - "Ethernet7", - "Ethernet8" - ], - "vlanid": "500" - }, - "Vlan600": { - "dhcp_servers": [ - "192.168.6.1", - "192.168.6.2", - "192.168.6.3", - "192.168.6.4" - ], - "members": [ - "Ethernet5", - "Ethernet6" - ], - "vlanid": "600" - }, - "Vlan700": { - "dhcp_servers": [ - "192.168.7.1", - "192.168.7.2", - "192.168.7.3", - "192.168.7.4" - ], - "members": [ - "Ethernet5", - "Ethernet7" - ], - "vlanid": "700" - }, - "Vlan800": { - "dhcp_servers": [ - "192.168.8.1", - "192.168.8.2", - "192.168.8.3", - "192.168.8.4" - ], - "members": [ - "Ethernet5", - "Ethernet8" - ], - "vlanid": "800" - } - }, - "VLAN_MEMBER": { - "Vlan500|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan500|Ethernet6": { - "tagging_mode": "untagged" - }, - "Vlan500|Ethernet7": { - "tagging_mode": "untagged" - }, - "Vlan500|Ethernet8": { - "tagging_mode": "untagged" - }, - "Vlan600|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan600|Ethernet6": { - "tagging_mode": "tagged" - }, - "Vlan700|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan700|Ethernet7": { - "tagging_mode": "tagged" - }, - "Vlan800|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan800|Ethernet8": { - "tagging_mode": "tagged" - } - }, - "INTERFACE": { - "Ethernet1|192.168.1.1/24": {}, - "Ethernet2|192.168.2.1/24": {}, - "Ethernet3|192.168.3.1/24": {}, - "Ethernet4|192.168.4.1/24": {} - }, - "VLAN_INTERFACE": { - "Vlan500|192.168.5.1/24": {}, - "Vlan600|192.168.6.1/24": {}, - "Vlan700|192.168.7.1/24": {}, - "Vlan800|192.168.8.1/24": {} - }, - "LOOPBACK_INTERFACE": { - "Loopback0|127.0.0.1/8": {} - }, - "CABLE_LENGTH": { - "AZURE": { - "Ethernet8": "40m", - "Ethernet9": "40m", - "Ethernet2": "40m", - "Ethernet3": "40m", - "Ethernet1": "40m", - "Ethernet6": "40m", - "Ethernet7": "40m", - "Ethernet4": "40m", - "Ethernet5": "40m", - "Ethernet22": "40m", - "Ethernet50": "40m", - "Ethernet51": "40m", - "Ethernet52": "40m", - "Ethernet53": "40m", - "Ethernet54": "40m", - "Ethernet38": "40m", - "Ethernet39": "40m", - "Ethernet18": "40m", - "Ethernet19": "40m", - "Ethernet14": "40m", - "Ethernet15": "40m", - "Ethernet16": "40m", - "Ethernet17": "40m", - "Ethernet10": "40m", - "Ethernet11": "40m", - "Ethernet12": "40m", - "Ethernet35": "40m", - "Ethernet37": "40m", - "Ethernet32": "40m", - "Ethernet33": "40m", - "Ethernet30": "40m", - "Ethernet31": "40m", - "Ethernet49": "40m", - "Ethernet48": "40m", - "Ethernet47": "40m", - "Ethernet36": "40m", - "Ethernet45": "40m", - "Ethernet44": "40m", - "Ethernet43": "40m", - "Ethernet42": "40m", - "Ethernet41": "40m", - "Ethernet40": "40m", - "Ethernet29": "40m", - "Ethernet28": "40m", - "Ethernet34": "40m", - "Ethernet46": "40m", - "Ethernet21": "40m", - "Ethernet20": "40m", - "Ethernet23": "40m", - "Ethernet13": "40m", - "Ethernet25": "40m", - "Ethernet24": "40m", - "Ethernet27": "40m", - "Ethernet26": "40m" - } - }, - "CRM": { - "Config": { - "acl_table_threshold_type": "percentage", - "nexthop_group_threshold_type": "percentage", - "fdb_entry_high_threshold": "85", - "acl_entry_threshold_type": "percentage", - "ipv6_neighbor_low_threshold": "70", - "nexthop_group_member_low_threshold": "70", - "acl_group_high_threshold": "85", - "ipv4_route_high_threshold": "85", - "acl_counter_high_threshold": "85", - "ipv4_route_low_threshold": "70", - "ipv4_route_threshold_type": "percentage", - "ipv4_neighbor_low_threshold": "70", - "acl_group_threshold_type": "percentage", - "ipv4_nexthop_high_threshold": "85", - "ipv6_route_threshold_type": "percentage", - "nexthop_group_low_threshold": "70", - "ipv4_neighbor_high_threshold": "85", - "ipv6_route_high_threshold": "85", - "ipv6_nexthop_threshold_type": "percentage", - "polling_interval": "300", - "ipv4_nexthop_threshold_type": "percentage", - "acl_group_low_threshold": "70", - "acl_entry_low_threshold": "70", - "nexthop_group_member_threshold_type": "percentage", - "ipv4_nexthop_low_threshold": "70", - "acl_counter_threshold_type": "percentage", - "ipv6_neighbor_high_threshold": "85", - "nexthop_group_member_high_threshold": "85", - "acl_table_low_threshold": "70", - "fdb_entry_threshold_type": "percentage", - "ipv6_neighbor_threshold_type": "percentage", - "acl_table_high_threshold": "85", - "ipv6_nexthop_low_threshold": "70", - "acl_counter_low_threshold": "70", - "ipv4_neighbor_threshold_type": "percentage", - "nexthop_group_high_threshold": "85", - "ipv6_route_low_threshold": "70", - "acl_entry_high_threshold": "85", - "fdb_entry_low_threshold": "70", - "ipv6_nexthop_high_threshold": "85" - } - } -} diff --git a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install index 9bd1181e860f..30a343ff53b1 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install +++ b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install @@ -1,6 +1,4 @@ 48x2q4z/cfg/48x2q4z-modules.conf etc/modules-load.d -48x2q4z/cfg/config_db.json etc/sonic -48x2q4z/cfg/config_db_l2l3.json etc/sonic 48x2q4z/scripts/48x2q4z_platform.sh usr/bin 48x2q4z/scripts/48x2q4z_platform_monitor.py usr/bin 48x2q4z/service/48x2q4z_platform.service lib/systemd/system diff --git a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install index a6d26ce329bc..76254afb3a29 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install +++ b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install @@ -1,6 +1,4 @@ 48x6q/cfg/48x6q-modules.conf etc/modules-load.d -48x6q/cfg/config_db.json etc/sonic -48x6q/cfg/config_db_l2l3.json etc/sonic 48x6q/scripts/48x6q_platform.sh usr/bin 48x6q/scripts/48x6q_platform_monitor.py usr/bin 48x6q/service/48x6q_platform.service lib/systemd/system diff --git a/platform/centec/sonic-platform-modules-embedway/LICENSE b/platform/centec/sonic-platform-modules-embedway/LICENSE new file mode 100644 index 000000000000..99228517bae7 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2017 Centec, Inc + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/centec/sonic-platform-modules-embedway/README.md b/platform/centec/sonic-platform-modules-embedway/README.md new file mode 100644 index 000000000000..61b3ef6c87f4 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/README.md @@ -0,0 +1 @@ +platform drivers for Centec E582 for the SONiC project diff --git a/platform/centec/sonic-platform-modules-embedway/debian/changelog b/platform/centec/sonic-platform-modules-embedway/debian/changelog new file mode 100644 index 000000000000..2a2f05ab70c6 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/changelog @@ -0,0 +1,5 @@ +sonic-platform-modules-embedway (1.1) unstable; urgency=low + + * Initial release + + -- yangbs Mon, 22 Jan 2018 13:43:40 +0800 diff --git a/platform/centec/sonic-platform-modules-embedway/debian/compat b/platform/centec/sonic-platform-modules-embedway/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/centec/sonic-platform-modules-embedway/debian/control b/platform/centec/sonic-platform-modules-embedway/debian/control new file mode 100644 index 000000000000..7c21cda6370d --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/control @@ -0,0 +1,12 @@ +Source: sonic-platform-modules-embedway +Section: main +Priority: extra +Maintainer: yangbs +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-embedway-es6220 +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.init b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.init new file mode 100755 index 000000000000..76d758cf53c0 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.init @@ -0,0 +1,41 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup e582-48x2q4z board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + /usr/bin/es6220_platform.sh init + /usr/bin/add_crontab_remove_syslog.sh + /usr/bin/remove_syslog.sh + /usr/bin/create_eeprom.sh + + echo "done." + ;; + +stop) + /usr/bin/es6220_platform.sh deinit + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: service platform-modules-embedway-es6220 {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.install b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.install new file mode 100644 index 000000000000..004148fe9932 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.install @@ -0,0 +1,5 @@ +es6220/scripts/es6220_platform.sh usr/bin +es6220/scripts/create_eeprom.sh usr/bin +es6220/scripts/add_crontab_remove_syslog.sh usr/bin +es6220/scripts/remove_syslog.sh usr/bin +es6220/service/es6220_platform.service lib/systemd/system diff --git a/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.postinst b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.postinst new file mode 100644 index 000000000000..35f3ee2308a6 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.postinst @@ -0,0 +1,3 @@ +depmod -a +systemctl enable es6220_platform.service +systemctl start es6220_platform.service diff --git a/platform/centec/sonic-platform-modules-embedway/debian/rules b/platform/centec/sonic-platform-modules-embedway/debian/rules new file mode 100755 index 000000000000..fa00b79d4fe2 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/rules @@ -0,0 +1,35 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= es6220 + +%: + dh $@ + +override_dh_auto_build: + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + done) + +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -pplatform-modules-embedway-$${mod} \ + $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp -f $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ + debian/platform-modules-embedway-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) + +override_dh_usrlocal: + +override_dh_clean: + dh_clean + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/modules/*.ko; \ + rm -rf debian/platform-modules-embedway-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)/*.ko; \ + done) + diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/modules/Makefile b/platform/centec/sonic-platform-modules-embedway/es6220/modules/Makefile new file mode 100644 index 000000000000..1140f6b2f93e --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := dal.o +dal-y := dal_kernel.o dal_mpool.o diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.c b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.c new file mode 100644 index 000000000000..32a38f842cfa --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.c @@ -0,0 +1,1833 @@ +/** + @file dal_kernal.c + + @date 2012-10-18 + + @version v2.0 + + +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) +#include +#endif +#include "dal_kernel.h" +#include "dal_mpool.h" +#include +MODULE_AUTHOR("Centec Networks Inc."); +MODULE_DESCRIPTION("DAL kernel module"); +MODULE_LICENSE("GPL"); + +/* DMA memory pool size */ +static char* dma_pool_size; +module_param(dma_pool_size, charp, 0); +MODULE_PARM_DESC(dma_pool_size, + "Specify DMA memory pool size (default 4MB)"); + +/***************************************************************************** + * defines + *****************************************************************************/ +#define MB_SIZE 0x100000 +#define CTC_MAX_INTR_NUM 8 + +#define MEM_MAP_RESERVE SetPageReserved +#define MEM_MAP_UNRESERVE ClearPageReserved + +#define CTC_VENDOR_VID 0xc001 +#define CTC_HUMBER_DEVICE_ID 0x6048 +#define CTC_GOLDENGATE_DEVICE_ID 0xc010 +#define CTC_PCIE_VENDOR_ID 0xcb10 +#define CTC_DUET2_DEVICE_ID 0x7148 + +#define MEM_MAP_RESERVE SetPageReserved +#define MEM_MAP_UNRESERVE ClearPageReserved + +#define CTC_GREATBELT_DEVICE_ID 0x03e8 /* TBD */ +#define DAL_MAX_CHIP_NUM 8 /* [GB] used */ +#define VIRT_TO_PAGE(p) virt_to_page((p)) +#define DAL_UNTAG_BLOCK 0 +#define DAL_DISCARD_BLOCK 1 +#define DAL_MATCHED_BLOCK 2 +#define DAL_CUR_MATCH_BLOCk 3 +/***************************************************************************** + * typedef + *****************************************************************************/ +/* Control Data */ +typedef struct dal_isr_s +{ + int irq; + void (* isr)(void*); + void* isr_data; + int trigger; + int count; + wait_queue_head_t wqh; +} dal_isr_t; + +typedef struct dal_kernel_dev_s +{ + struct list_head list; + struct pci_dev* pci_dev; + + /* PCI I/O mapped base address */ + uintptr logic_address; + + /* Physical address */ + unsigned long long phys_address; +} dal_kern_dev_t; + +typedef struct _dma_segment +{ + struct list_head list; + unsigned long req_size; /* Requested DMA segment size */ + unsigned long blk_size; /* DMA block size */ + unsigned long blk_order; /* DMA block size in alternate format */ + unsigned long seg_size; /* Current DMA segment size */ + unsigned long seg_begin; /* Logical address of segment */ + unsigned long seg_end; /* Logical end address of segment */ + unsigned long* blk_ptr; /* Array of logical DMA block addresses */ + int blk_cnt_max; /* Maximum number of block to allocate */ + int blk_cnt; /* Current number of blocks allocated */ +} dma_segment_t; + +typedef irqreturn_t (*p_func) (int irq, void* dev_id); + +/*************************************************************************** + *declared + ***************************************************************************/ +static unsigned int linux_dal_poll0(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll1(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll2(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll3(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll4(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll5(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll6(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll7(struct file* filp, struct poll_table_struct* p); + +/***************************************************************************** + * global variables + *****************************************************************************/ +static dal_kern_dev_t dal_dev[DAL_MAX_CHIP_NUM]; +static dal_isr_t dal_isr[CTC_MAX_INTR_NUM]; +static int dal_chip_num = 0; +static int dal_version = 0; +static int dal_intr_num = 0; +static int use_high_memory = 0; +static unsigned int* dma_virt_base[DAL_MAX_CHIP_NUM]; +#ifndef DMA_MEM_MODE_PLATFORM +static unsigned int* dma_virt_base_tmp[DAL_MAX_CHIP_NUM]; +#endif +static unsigned long long dma_phy_base[DAL_MAX_CHIP_NUM]; +static unsigned int dma_mem_size = 0xc00000; +static unsigned int msi_irq_base[DAL_MAX_CHIP_NUM]; +static unsigned int msi_irq_num[DAL_MAX_CHIP_NUM]; +static unsigned int msi_used = 0; +static struct class *dal_class; + +static LIST_HEAD(_dma_seg); +static int dal_debug = 0; +module_param(dal_debug, int, 0); +MODULE_PARM_DESC(dal_debug, "Set debug level (default 0)"); + +static struct pci_device_id dal_id_table[] = +{ + {PCI_DEVICE(CTC_VENDOR_VID, CTC_GREATBELT_DEVICE_ID)}, + {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_GOLDENGATE_DEVICE_ID)}, + {PCI_DEVICE((CTC_PCIE_VENDOR_ID+1), (CTC_GOLDENGATE_DEVICE_ID+1))}, + {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_DUET2_DEVICE_ID)}, + {0, }, +}; + +static wait_queue_head_t poll_intr[CTC_MAX_INTR_NUM]; + +p_func intr_handler_fun[CTC_MAX_INTR_NUM]; + +static int poll_intr_trigger[CTC_MAX_INTR_NUM]; + +static struct file_operations dal_intr_fops[CTC_MAX_INTR_NUM] = +{ + { + .owner = THIS_MODULE, + .poll = linux_dal_poll0, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll1, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll2, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll3, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll4, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll5, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll6, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll7, + }, +}; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) +#include +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt +#endif +/***************************************************************************** + * macros + *****************************************************************************/ +#define VERIFY_CHIP_INDEX(n) (n < dal_chip_num) + +#define _KERNEL_INTERUPT_PROCESS +static irqreturn_t +intr0_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + + if(poll_intr_trigger[0]) + { + return IRQ_HANDLED; + } + + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[0] = 1; + wake_up(&poll_intr[0]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr1_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[1]) + { + return IRQ_HANDLED; + } + + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[1] = 1; + wake_up(&poll_intr[1]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr2_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[2]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[2] = 1; + wake_up(&poll_intr[2]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr3_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[3]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[3] = 1; + wake_up(&poll_intr[3]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr4_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[4]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[4] = 1; + wake_up(&poll_intr[4]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr5_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[5]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[5] = 1; + wake_up(&poll_intr[5]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr6_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[6]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[6] = 1; + wake_up(&poll_intr[6]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr7_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[7]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[7] = 1; + wake_up(&poll_intr[7]); + } + } + + return IRQ_HANDLED; +} + +int +dal_interrupt_register(unsigned int irq, int prio, void (* isr)(void*), void* data) +{ + int ret; + unsigned char str[16]; + unsigned char* int_name = NULL; + unsigned int intr_num_tmp = 0; + unsigned int intr_num = CTC_MAX_INTR_NUM; + unsigned long irq_flags = 0; + + if (dal_intr_num >= CTC_MAX_INTR_NUM) + { + printk("Interrupt numbers exceeds max.\n"); + return -1; + } + + if (msi_used) + { + int_name = "dal_msi"; + } + else + { + int_name = "dal_intr"; + } + + + for (intr_num_tmp=0;intr_num_tmp < CTC_MAX_INTR_NUM; intr_num_tmp++) + { + if (irq == dal_isr[intr_num_tmp].irq) + { + if (0 == msi_used) + { + dal_isr[intr_num_tmp].count++; + printk("Interrupt irq %d register count %d.\n", irq, dal_isr[intr_num_tmp].count); + } + return 0; + } + if ((0 == dal_isr[intr_num_tmp].irq) && (CTC_MAX_INTR_NUM == intr_num)) + { + intr_num = intr_num_tmp; + dal_isr[intr_num].count = 0; + } + } + dal_isr[intr_num].irq = irq; + dal_isr[intr_num].isr = isr; + dal_isr[intr_num].isr_data = data; + dal_isr[intr_num].count++; + + init_waitqueue_head(&poll_intr[intr_num]); + + /* only user mode */ + if ((NULL == isr) && (NULL == data)) + { + snprintf(str, 16, "%s%d", "dal_intr", intr_num); + ret = register_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, + str, &dal_intr_fops[intr_num]); + if (ret < 0) + { + printk("Register character device for irq %d failed, ret= %d", irq, ret); + return ret; + } + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + irq_flags = 0; +#else + irq_flags = IRQF_DISABLED; +#endif + if ((ret = request_irq(irq, + intr_handler_fun[intr_num], + irq_flags, + int_name, + &dal_isr[intr_num])) < 0) + { + printk("Cannot request irq %d, ret %d.\n", irq, ret); + unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, str); + } + + if (0 == ret) + { + dal_intr_num++; + } + + return ret; +} + +int +dal_interrupt_unregister(unsigned int irq) +{ + unsigned char str[16]; + int intr_idx = 0; + int find_flag = 0; + + /* get intr device index */ + for (intr_idx = 0; intr_idx < CTC_MAX_INTR_NUM; intr_idx++) + { + if (dal_isr[intr_idx].irq == irq) + { + find_flag = 1; + break; + } + } + + if (find_flag == 0) + { + printk ("irq%d is not registered! unregister failed \n", irq); + return -1; + } + + dal_isr[intr_idx].count--; + if (0 != dal_isr[intr_idx].count) + { + printk("Interrupt irq %d unregister count %d.\n", irq, dal_isr[intr_idx].count); + return -1; + } + snprintf(str, 16, "%s%d", "dal_intr", intr_idx); + + unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_idx, str); + + free_irq(irq, &dal_isr[intr_idx]); + + dal_isr[intr_idx].irq = 0; + + dal_intr_num--; + + return 0; +} + +int +dal_interrupt_set_en(unsigned int irq, unsigned int enable) +{ + enable ? enable_irq(irq) : disable_irq_nosync(irq); + return 0; +} + +static int +_dal_set_msi_enabe(unsigned int lchip, unsigned int irq_num) +{ + int ret = 0; + + if (irq_num == 1) + { + ret = pci_enable_msi(dal_dev[lchip].pci_dev); + if (ret) + { + printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); + pci_disable_msi(dal_dev[lchip].pci_dev); + msi_used = 0; + } + + msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; + msi_irq_num[lchip] = 1; + } + else + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 79)) + ret = pci_enable_msi_exact(dal_dev[lchip].pci_dev, irq_num); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 26, 32)) + ret = pci_enable_msi_block(dal_dev[lchip].pci_dev, irq_num); +#else + ret = -1; +#endif + if (ret) + { + printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); + pci_disable_msi(dal_dev[lchip].pci_dev); + msi_used = 0; + } + + msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; + msi_irq_num[lchip] = irq_num; + } + + return ret; +} + +static int +_dal_set_msi_disable(unsigned int lchip) +{ + + pci_disable_msi(dal_dev[lchip].pci_dev); + + msi_irq_base[lchip] = 0; + msi_irq_num[lchip] = 0; + + return 0; +} + +int +dal_set_msi_cap(unsigned long arg) +{ + int ret = 0; + int index = 0; + dal_msi_info_t msi_info; + + if (copy_from_user(&msi_info, (void*)arg, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + + printk("####dal_set_msi_cap lchip %d base %d num:%d\n", msi_info.lchip, msi_info.irq_base, msi_info.irq_num); + if (msi_info.irq_num > 0) + { + if (0 == msi_used) + { + msi_used = 1; + ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); + } + else if ((1 == msi_used) && (msi_info.irq_num != msi_irq_num[msi_info.lchip])) + { + for (index = 0; index < msi_irq_num[msi_info.lchip]; index++) + { + dal_interrupt_unregister(msi_irq_base[msi_info.lchip]+index); + } + _dal_set_msi_disable(msi_info.lchip); + msi_used = 1; + ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); + } + } + else + { + msi_used = 0; + ret = _dal_set_msi_disable(msi_info.lchip); + } + + return ret; +} + +int +dal_user_interrupt_register(unsigned long arg) +{ + int irq = 0; + if (copy_from_user(&irq, (void*)arg, sizeof(int))) + { + return -EFAULT; + } + printk("####register interrupt irq:%d\n", irq); + return dal_interrupt_register(irq, 0, NULL, NULL); +} + +int +dal_user_interrupt_unregister(unsigned long arg) +{ + int irq = 0; + if (copy_from_user(&irq, (void*)arg, sizeof(int))) + { + return -EFAULT; + } + printk("####unregister interrupt irq:%d\n", irq); + return dal_interrupt_unregister(irq); +} + +int +dal_user_interrupt_set_en(unsigned long arg) +{ + dal_intr_parm_t dal_intr_parm; + + if (copy_from_user(&dal_intr_parm, (void*)arg, sizeof(dal_intr_parm_t))) + { + return -EFAULT; + } + + return dal_interrupt_set_en(dal_intr_parm.irq, dal_intr_parm.enable); +} + +/* + * Function: _dal_dma_segment_free + */ + +/* + * Function: _find_largest_segment + * + * Purpose: + * Find largest contiguous segment from a pool of DMA blocks. + * Parameters: + * dseg - DMA segment descriptor + * Returns: + * 0 on success, < 0 on error. + * Notes: + * Assembly stops if a segment of the requested segment size + * has been obtained. + * + * Lower address bits of the DMA blocks are used as follows: + * 0: Untagged + * 1: Discarded block + * 2: Part of largest contiguous segment + * 3: Part of current contiguous segment + */ +#ifndef DMA_MEM_MODE_PLATFORM +static int +_dal_find_largest_segment(dma_segment_t* dseg) +{ + int i, j, blks, found; + unsigned long seg_begin; + unsigned long seg_end; + unsigned long seg_tmp; + + blks = dseg->blk_cnt; + + /* Clear all block tags */ + for (i = 0; i < blks; i++) + { + dseg->blk_ptr[i] &= ~3; + } + + for (i = 0; i < blks && dseg->seg_size < dseg->req_size; i++) + { + /* First block must be an untagged block */ + if ((dseg->blk_ptr[i] & 3) == DAL_UNTAG_BLOCK) + { + /* Initial segment size is the block size */ + seg_begin = dseg->blk_ptr[i]; + seg_end = seg_begin + dseg->blk_size; + dseg->blk_ptr[i] |= DAL_CUR_MATCH_BLOCk; + + /* Loop looking for adjacent blocks */ + do + { + found = 0; + + for (j = i + 1; j < blks && (seg_end - seg_begin) < dseg->req_size; j++) + { + seg_tmp = dseg->blk_ptr[j]; + /* Check untagged blocks only */ + if ((seg_tmp & 3) == DAL_UNTAG_BLOCK) + { + if (seg_tmp == (seg_begin - dseg->blk_size)) + { + /* Found adjacent block below current segment */ + dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; + seg_begin = seg_tmp; + found = 1; + } + else if (seg_tmp == seg_end) + { + /* Found adjacent block above current segment */ + dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; + seg_end += dseg->blk_size; + found = 1; + } + } + } + } + while (found); + + if ((seg_end - seg_begin) > dseg->seg_size) + { + /* The current block is largest so far */ + dseg->seg_begin = seg_begin; + dseg->seg_end = seg_end; + dseg->seg_size = seg_end - seg_begin; + + /* Re-tag current and previous largest segment */ + for (j = 0; j < blks; j++) + { + if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) + { + /* Tag current segment as the largest */ + dseg->blk_ptr[j] &= ~1; + } + else if ((dseg->blk_ptr[j] & 3) == DAL_MATCHED_BLOCK) + { + /* Discard previous largest segment */ + dseg->blk_ptr[j] ^= 3; + } + } + } + else + { + /* Discard all blocks in current segment */ + for (j = 0; j < blks; j++) + { + if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) + { + dseg->blk_ptr[j] &= ~2; + } + } + } + } + } + + return 0; +} + +/* + * Function: _alloc_dma_blocks + */ +static int +_dal_alloc_dma_blocks(dma_segment_t* dseg, int blks) +{ + int i, start; + unsigned long addr; + + if (dseg->blk_cnt + blks > dseg->blk_cnt_max) + { + printk("No more DMA blocks\n"); + return -1; + } + + start = dseg->blk_cnt; + dseg->blk_cnt += blks; + + for (i = start; i < dseg->blk_cnt; i++) + { + addr = __get_free_pages(GFP_ATOMIC, dseg->blk_order); + if (addr) + { + dseg->blk_ptr[i] = addr; + } + else + { + printk("DMA allocation failed\n"); + return -1; + } + } + + return 0; +} + +/* + * Function: _dal_dma_segment_alloc + */ +static dma_segment_t* +_dal_dma_segment_alloc(unsigned int size, unsigned int blk_size) +{ + dma_segment_t* dseg; + int i, blk_ptr_size; + unsigned long page_addr; + struct sysinfo si; + + /* Sanity check */ + if (size == 0 || blk_size == 0) + { + return NULL; + } + + /* Allocate an initialize DMA segment descriptor */ + if ((dseg = kmalloc(sizeof(dma_segment_t), GFP_ATOMIC)) == NULL) + { + return NULL; + } + + memset(dseg, 0, sizeof(dma_segment_t)); + dseg->req_size = size; + dseg->blk_size = PAGE_ALIGN(blk_size); + + while ((PAGE_SIZE << dseg->blk_order) < dseg->blk_size) + { + dseg->blk_order++; + } + + si_meminfo(&si); + dseg->blk_cnt_max = (si.totalram << PAGE_SHIFT) / dseg->blk_size; + blk_ptr_size = dseg->blk_cnt_max * sizeof(unsigned long); + /* Allocate an initialize DMA block pool */ + dseg->blk_ptr = kmalloc(blk_ptr_size, GFP_KERNEL); + if (dseg->blk_ptr == NULL) + { + kfree(dseg); + return NULL; + } + + memset(dseg->blk_ptr, 0, blk_ptr_size); + /* Allocate minimum number of blocks */ + _dal_alloc_dma_blocks(dseg, dseg->req_size / dseg->blk_size); + + /* Allocate more blocks until we have a complete segment */ + do + { + _dal_find_largest_segment(dseg); + if (dseg->seg_size >= dseg->req_size) + { + break; + } + } + while (_dal_alloc_dma_blocks(dseg, 8) == 0); + + /* Reserve all pages in the DMA segment and free unused blocks */ + for (i = 0; i < dseg->blk_cnt; i++) + { + if ((dseg->blk_ptr[i] & 3) == 2) + { + dseg->blk_ptr[i] &= ~3; + + for (page_addr = dseg->blk_ptr[i]; + page_addr < dseg->blk_ptr[i] + dseg->blk_size; + page_addr += PAGE_SIZE) + { + MEM_MAP_RESERVE(VIRT_TO_PAGE((void*)page_addr)); + } + } + else if (dseg->blk_ptr[i]) + { + dseg->blk_ptr[i] &= ~3; + free_pages(dseg->blk_ptr[i], dseg->blk_order); + dseg->blk_ptr[i] = 0; + } + } + + return dseg; +} + +/* + * Function: _dal_dma_segment_free + */ +static void +_dal_dma_segment_free(dma_segment_t* dseg) +{ + int i; + unsigned long page_addr; + + if (dseg->blk_ptr) + { + for (i = 0; i < dseg->blk_cnt; i++) + { + if (dseg->blk_ptr[i]) + { + for (page_addr = dseg->blk_ptr[i]; + page_addr < dseg->blk_ptr[i] + dseg->blk_size; + page_addr += PAGE_SIZE) + { + MEM_MAP_UNRESERVE(VIRT_TO_PAGE(page_addr)); + } + + free_pages(dseg->blk_ptr[i], dseg->blk_order); + } + } + + kfree(dseg->blk_ptr); + kfree(dseg); + } +} + +/* + * Function: -dal_pgalloc + */ +static void* +_dal_pgalloc(unsigned int size) +{ + dma_segment_t* dseg; + unsigned int blk_size; + + blk_size = (size < DMA_BLOCK_SIZE) ? size : DMA_BLOCK_SIZE; + if ((dseg = _dal_dma_segment_alloc(size, blk_size)) == NULL) + { + return NULL; + } + + if (dseg->seg_size < size) + { + /* If we didn't get the full size then forget it */ + printk("Notice: Can not get enough memory for requset!!\n"); + printk("actual size:0x%lx, request size:0x%x\n", dseg->seg_size, size); + //-_dal_dma_segment_free(dseg); + //-return NULL; + } + + list_add(&dseg->list, &_dma_seg); + return (void*)dseg->seg_begin; +} + +/* + * Function: _dal_pgfree + */ +static int +_dal_pgfree(void* ptr) +{ + struct list_head* pos; + + list_for_each(pos, &_dma_seg) + { + dma_segment_t* dseg = list_entry(pos, dma_segment_t, list); + if (ptr == (void*)dseg->seg_begin) + { + list_del(&dseg->list); + _dal_dma_segment_free(dseg); + return 0; + } + } + return -1; +} +#endif +static void +dal_alloc_dma_pool(int lchip, int size) +{ + if (use_high_memory) + { + dma_phy_base[lchip] = virt_to_bus(high_memory); + dma_virt_base[lchip] = ioremap_nocache(dma_phy_base[lchip], size); + } + else + { +#ifdef DMA_MEM_MODE_PLATFORM + dma_virt_base[lchip] = dma_alloc_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, + &dma_phy_base[lchip], GFP_KERNEL); + + printk(KERN_WARNING "########Using DMA_MEM_MODE_PLATFORM \n"); +#endif + +#ifndef DMA_MEM_MODE_PLATFORM + /* Get DMA memory from kernel */ + dma_virt_base_tmp[lchip] = _dal_pgalloc(size); + dma_phy_base[lchip] = virt_to_bus(dma_virt_base_tmp[lchip]); + dma_virt_base [lchip]= ioremap_nocache(dma_phy_base[lchip], size); +#endif + } +} + +static void +dal_free_dma_pool(int lchip) +{ + int ret = 0; + ret = ret; + if (use_high_memory) + { + iounmap(dma_virt_base[lchip]); + } + else + { +#ifdef DMA_MEM_MODE_PLATFORM + dma_free_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, + dma_virt_base[lchip], dma_phy_base[lchip]); +#endif + +#ifndef DMA_MEM_MODE_PLATFORM + iounmap(dma_virt_base[lchip]); + ret = _dal_pgfree(dma_virt_base_tmp[lchip]); + if(ret<0) + { + printk("Dma free memory fail !!!!!! \n"); + } +#endif + } +} + +#define _KERNEL_DAL_IO +static int +_dal_pci_read(unsigned char lchip, unsigned int offset, unsigned int* value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + *value = *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset); + return 0; +} + +int +dal_create_irq_mapping(unsigned long arg) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) + +#ifndef NO_IRQ +#define NO_IRQ (-1) +#endif + dal_irq_mapping_t irq_map; + + if (copy_from_user(&irq_map, (void*)arg, sizeof(dal_irq_mapping_t))) + { + return -EFAULT; + } + + irq_map.sw_irq = irq_create_mapping(NULL, irq_map.hw_irq); + if (irq_map.sw_irq == NO_IRQ) + { + printk("IRQ mapping fail !!!!!! \n"); + return -1; + } + + if (copy_to_user((dal_irq_mapping_t*)arg, (void*)&irq_map, sizeof(dal_irq_mapping_t))) + { + return -EFAULT; + } +#endif + return 0; +} + +int +dal_pci_read(unsigned long arg) +{ + dal_chip_parm_t cmdpara_chip; + + if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + _dal_pci_read((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, + (unsigned int*)(&(cmdpara_chip.value))); + + if (copy_to_user((dal_chip_parm_t*)arg, (void*)&cmdpara_chip, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + return 0; +} + +static int +_dal_pci_write(unsigned char lchip, unsigned int offset, unsigned int value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset) = value; + return 0; +} + +int +dal_pci_write(unsigned long arg) +{ + dal_chip_parm_t cmdpara_chip; + + if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + _dal_pci_write((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, + (unsigned int)cmdpara_chip.value); + + return 0; +} + +int +dal_pci_conf_read(unsigned char lchip, unsigned int offset, unsigned int* value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + pci_read_config_dword(dal_dev[lchip].pci_dev, offset, value); + return 0; +} + +int +dal_pci_conf_write(unsigned char lchip, unsigned int offset, unsigned int value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + pci_write_config_dword(dal_dev[lchip].pci_dev, offset, value); + return 0; +} +int +dal_user_read_pci_conf(unsigned long arg) +{ + dal_pci_cfg_ioctl_t dal_cfg; + + if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + if (dal_pci_conf_read(dal_cfg.lchip, dal_cfg.offset, &dal_cfg.value)) + { + printk("dal_pci_conf_read failed.\n"); + return -EFAULT; + } + + if (copy_to_user((dal_pci_cfg_ioctl_t*)arg, (void*)&dal_cfg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + return 0; +} + +int +dal_user_write_pci_conf(unsigned long arg) +{ + dal_pci_cfg_ioctl_t dal_cfg; + + if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + return dal_pci_conf_write(dal_cfg.lchip, dal_cfg.offset, dal_cfg.value); +} + +static int +linux_get_device(unsigned long arg) +{ + dal_user_dev_t user_dev; + int lchip = 0; + + if (copy_from_user(&user_dev, (void*)arg, sizeof(user_dev))) + { + return -EFAULT; + } + + user_dev.chip_num = dal_chip_num; + lchip = user_dev.lchip; + + if (lchip < dal_chip_num) + { + user_dev.phy_base0 = (unsigned int)dal_dev[lchip].phys_address; + user_dev.phy_base1 = (unsigned int)(dal_dev[lchip].phys_address >> 32); + + user_dev.bus_no = dal_dev[lchip].pci_dev->bus->number; + user_dev.dev_no = dal_dev[lchip].pci_dev->device; + user_dev.fun_no = dal_dev[lchip].pci_dev->devfn; + } + + if (copy_to_user((dal_user_dev_t*)arg, (void*)&user_dev, sizeof(user_dev))) + { + return -EFAULT; + } + + return 0; +} + +/* set dal version, copy to user */ +static int +linux_get_dal_version(unsigned long arg) +{ + int dal_ver = VERSION_1DOT2; /* set dal version */ + + if (copy_to_user((int*)arg, (void*)&dal_ver, sizeof(dal_ver))) + { + return -EFAULT; + } + + dal_version = dal_ver; /* up sw */ + + return 0; +} + +static int +linux_get_dma_info(unsigned long arg) +{ + dma_info_t dma_para; + + if (copy_from_user(&dma_para, (void*)arg, sizeof(dma_info_t))) + { + return -EFAULT; + } + + dma_para.phy_base = (unsigned int)dma_phy_base[dma_para.lchip]; + dma_para.phy_base_hi = dma_phy_base[dma_para.lchip] >> 32; + dma_para.size = dma_mem_size; + + if (copy_to_user((dma_info_t*)arg, (void*)&dma_para, sizeof(dma_info_t))) + { + return -EFAULT; + } + + return 0; +} + +static int +dal_get_msi_info(unsigned long arg) +{ + dal_msi_info_t msi_para; + unsigned int lchip = 0; + + /* get lchip form user mode */ + if (copy_from_user(&msi_para, (void*)arg, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + lchip = msi_para.lchip; + + msi_para.irq_base = msi_irq_base[lchip]; + msi_para.irq_num = msi_irq_num[lchip]; + + /* send msi info to user mode */ + if (copy_to_user((dal_msi_info_t*)arg, (void*)&msi_para, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + + return 0; +} + + +static int +dal_get_intr_info(unsigned long arg) +{ + dal_intr_info_t intr_para; + unsigned int intr_num = 0; + + /* get lchip form user mode */ + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_intr_info_t))) + { + return -EFAULT; + } + + intr_para.irq_idx = CTC_MAX_INTR_NUM; + for (intr_num=0; intr_num< CTC_MAX_INTR_NUM; intr_num++) + { + if (intr_para.irq == dal_isr[intr_num].irq) + { + intr_para.irq_idx = intr_num; + break; + } + } + + if (CTC_MAX_INTR_NUM == intr_para.irq_idx) + { + printk("Interrupt %d cann't find.\n", intr_para.irq); + } + /* send msi info to user mode */ + if (copy_to_user((dal_intr_info_t*)arg, (void*)&intr_para, sizeof(dal_intr_info_t))) + { + return -EFAULT; + } + + return 0; +} + +static int +dal_cache_inval(unsigned long arg) +{ + dal_dma_cache_info_t intr_para; + + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) + { + return -EFAULT; + } + +#if 0 + dma_cache_wback_inv((unsigned long)intr_para.ptr, intr_para.length); +#endif + +#if 0 + dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); + + + dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); +#endif + return 0; +} + +static int +dal_cache_flush(unsigned long arg) +{ + dal_dma_cache_info_t intr_para; + + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) + { + return -EFAULT; + } + +#if 0 + dma_cache_wback_inv(intr_para.ptr, intr_para.length); +#endif + +#if 0 + dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); + + + dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); +#endif + return 0; +} + +int +linux_dal_probe(struct pci_dev* pdev, const struct pci_device_id* id) +{ + dal_kern_dev_t* dev = NULL; + int bar = 0; + int ret = 0; + unsigned int temp = 0; + unsigned int lchip = 0; + + printk(KERN_WARNING "********found dal device*****\n"); + + for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) + { + if (NULL == dal_dev[lchip].pci_dev) + { + break; + } + } + + if (lchip >= DAL_MAX_CHIP_NUM) + { + printk("Exceed max local chip num\n"); + return -1; + } + + dev = &dal_dev[lchip]; + if (NULL == dev) + { + printk("Cannot obtain PCI resources\n"); + } + + lchip = lchip; + dal_chip_num += 1; + + dev->pci_dev = pdev; + + if (pci_enable_device(pdev) < 0) + { + printk("Cannot enable PCI device: vendor id = %x, device id = %x\n", + pdev->vendor, pdev->device); + } + + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) + { + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) + { + printk("Could not set PCI DMA Mask\n"); + return ret; + } + } + + if (pci_request_regions(pdev, DAL_NAME) < 0) + { + printk("Cannot obtain PCI resources\n"); + } + + dev->phys_address = pci_resource_start(pdev, bar); + dev->logic_address = (uintptr)ioremap_nocache(dev->phys_address, + pci_resource_len(dev->pci_dev, bar)); + + _dal_pci_read(lchip, 0x48, &temp); + if (((temp >> 8) & 0xffff) == 0x3412) + { + printk("Little endian Cpu detected!!! \n"); + _dal_pci_write(lchip, 0x48, 0xFFFFFFFF); + } + + pci_set_master(pdev); + + /* alloc dma_mem_size for every chip */ + if (dma_mem_size) + { + dal_alloc_dma_pool(lchip, dma_mem_size); + + /*add check Dma memory pool cannot cross 4G space*/ + if ((0==(dma_phy_base[lchip]>>32)) && (0!=((dma_phy_base[lchip]+dma_mem_size)>>32))) + { + printk("Dma malloc memory cross 4G space!!!!!! \n"); + return -1; + } + } + + printk(KERN_WARNING "linux_dal_probe end*****\n"); + + return 0; +} + +void +linux_dal_remove(struct pci_dev* pdev) +{ + unsigned int lchip = 0; + unsigned int flag = 0; + + for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) + { + if (pdev == dal_dev[lchip].pci_dev) + { + flag = 1; + break; + } + } + + if (1 == flag) + { + dal_free_dma_pool(lchip); + pci_release_regions(pdev); + pci_disable_device(pdev); + + dal_dev[lchip].pci_dev = NULL; + dal_chip_num--; + } + + +} + +#ifdef CONFIG_COMPAT +static long +linux_dal_ioctl(struct file* file, + unsigned int cmd, unsigned long arg) +#else + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) +static int +linux_dal_ioctl(struct file* file, + unsigned int cmd, unsigned long arg) +#else +static int +linux_dal_ioctl(struct inode* inode, struct file* file, + unsigned int cmd, unsigned long arg) +#endif + +#endif +{ + switch (cmd) + { + + case CMD_READ_CHIP: + return dal_pci_read(arg); + + case CMD_WRITE_CHIP: + return dal_pci_write(arg); + + case CMD_GET_DEVICES: + return linux_get_device(arg); + + case CMD_GET_DAL_VERSION: + return linux_get_dal_version(arg); + + case CMD_GET_DMA_INFO: + return linux_get_dma_info(arg); + + case CMD_PCI_CONFIG_READ: + return dal_user_read_pci_conf(arg); + + case CMD_PCI_CONFIG_WRITE: + return dal_user_write_pci_conf(arg); + + case CMD_REG_INTERRUPTS: + return dal_user_interrupt_register(arg); + + case CMD_UNREG_INTERRUPTS: + return dal_user_interrupt_unregister(arg); + + case CMD_EN_INTERRUPTS: + return dal_user_interrupt_set_en(arg); + + case CMD_SET_MSI_CAP: + return dal_set_msi_cap(arg); + + case CMD_GET_MSI_INFO: + return dal_get_msi_info(arg); + + case CMD_IRQ_MAPPING: + return dal_create_irq_mapping(arg); + + case CMD_GET_INTR_INFO: + return dal_get_intr_info(arg); + + case CMD_CACHE_INVAL: + return dal_cache_inval(arg); + + case CMD_CACHE_FLUSH: + return dal_cache_flush(arg); + + default: + break; + } + + return 0; +} + +static unsigned int +linux_dal_poll0(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[0], p); + local_irq_save(flags); + if (poll_intr_trigger[0]) + { + poll_intr_trigger[0] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll1(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[1], p); + local_irq_save(flags); + if (poll_intr_trigger[1]) + { + poll_intr_trigger[1] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll2(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[2], p); + local_irq_save(flags); + if (poll_intr_trigger[2]) + { + poll_intr_trigger[2] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll3(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[3], p); + local_irq_save(flags); + if (poll_intr_trigger[3]) + { + poll_intr_trigger[3] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll4(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[4], p); + local_irq_save(flags); + if (poll_intr_trigger[4]) + { + poll_intr_trigger[4] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll5(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[5], p); + local_irq_save(flags); + if (poll_intr_trigger[5]) + { + poll_intr_trigger[5] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll6(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[6], p); + local_irq_save(flags); + if (poll_intr_trigger[6]) + { + poll_intr_trigger[6] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll7(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[7], p); + local_irq_save(flags); + if (poll_intr_trigger[7]) + { + poll_intr_trigger[7] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static struct pci_driver linux_dal_driver = +{ + .name = DAL_NAME, + .id_table = dal_id_table, + .probe = linux_dal_probe, + .remove = linux_dal_remove, +}; + +static struct file_operations fops = +{ + .owner = THIS_MODULE, +#ifdef CONFIG_COMPAT + .compat_ioctl = linux_dal_ioctl, + .unlocked_ioctl = linux_dal_ioctl, +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) + .unlocked_ioctl = linux_dal_ioctl, +#else + .ioctl = linux_dal_ioctl, +#endif +#endif +}; + + +static int __init +linux_dal_init(void) +{ + int ret = 0; + + /* Get DMA memory pool size form dal.ok input param, or use default dma_mem_size */ + if (dma_pool_size) + { + if ((dma_pool_size[strlen(dma_pool_size) - 1] & ~0x20) == 'M') + { + dma_mem_size = simple_strtoul(dma_pool_size, NULL, 0); + printk("dma_mem_size: 0x%x \n", dma_mem_size); + + dma_mem_size *= MB_SIZE; + } + else + { + printk("DMA memory pool size must be specified as e.g. dma_pool_size=8M\n"); + } + + if (dma_mem_size & (dma_mem_size - 1)) + { + printk("dma_mem_size must be a power of 2 (1M, 2M, 4M, 8M etc.)\n"); + dma_mem_size = 0; + } + } + + ret = register_chrdev(DAL_DEV_MAJOR, DAL_NAME, &fops); + if (ret < 0) + { + printk(KERN_WARNING "Register linux_dal device, ret %d\n", ret); + return ret; + } + + ret = pci_register_driver(&linux_dal_driver); + if (ret < 0) + { + printk(KERN_WARNING "Register ASIC PCI driver failed, ret %d\n", ret); + return ret; + } + + /* alloc /dev/linux_dal node */ + dal_class = class_create(THIS_MODULE, DAL_NAME); + device_create(dal_class, NULL, MKDEV(DAL_DEV_MAJOR, 0), NULL, DAL_NAME); + + /* init interrupt function */ + intr_handler_fun[0] = intr0_handler; + intr_handler_fun[1] = intr1_handler; + intr_handler_fun[2] = intr2_handler; + intr_handler_fun[3] = intr3_handler; + intr_handler_fun[4] = intr4_handler; + intr_handler_fun[5] = intr5_handler; + intr_handler_fun[6] = intr6_handler; + intr_handler_fun[7] = intr7_handler; + + return ret; +} + +static void __exit +linux_dal_exit(void) +{ + device_destroy(dal_class, MKDEV(DAL_DEV_MAJOR, 0)); + class_destroy(dal_class); + unregister_chrdev(DAL_DEV_MAJOR, "linux_dal"); + pci_unregister_driver(&linux_dal_driver); +} + +module_init(linux_dal_init); +module_exit(linux_dal_exit); + + diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.h b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.h new file mode 100644 index 000000000000..850a4cffa731 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.h @@ -0,0 +1,171 @@ +/** + @file dal_kernel_io.h + + @author Copyright (C) 2012 Centec Networks Inc. All rights reserved. + + @date 2012-4-9 + + @version v2.0 + +*/ +#ifndef _DAL_KERNEL_H_ +#define _DAL_KERNEL_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_RESOURCES_64BIT) || defined(CONFIG_PHYS_ADDR_T_64BIT) +#define PHYS_ADDR_IS_64BIT +#endif + +#ifndef SDK_IN_USERMODE +#ifdef PHYS_ADDR_IS_64BIT +typedef long long intptr; +typedef unsigned long long uintptr; +#else +typedef int intptr; +typedef unsigned int uintptr; +#endif +#endif + +#define DAL_PCI_READ_ADDR 0x0 +#define DAL_PCI_READ_DATA 0xc +#define DAL_PCI_WRITE_ADDR 0x8 +#define DAL_PCI_WRITE_DATA 0x4 +#define DAL_PCI_STATUS 0x10 + +#define DAL_PCI_STATUS_IN_PROCESS 31 +#define DAL_PCI_STATUS_BAD_PARITY 5 +#define DAL_PCI_STATUS_CPU_ACCESS_ERR 4 +#define DAL_PCI_STATUS_READ_CMD 3 +#define DAL_PCI_STATUS_REGISTER_ERR 1 +#define DAL_PCI_STATUS_REGISTER_ACK 0 + +#define DAL_PCI_ACCESS_TIMEOUT 0x64 + +#define DAL_NAME "linux_dal" /* "linux_dal" */ + +#define DAL_DEV_MAJOR 198 + +#define DAL_DEV_INTR_MAJOR_BASE 200 + +#define DAL_DEV_NAME "/dev/" DAL_NAME +#define DAL_ONE_KB 1024 +#define DAL_ONE_MB (1024*1024) +struct dal_chip_parm_s +{ + unsigned int lchip; /*tmp should be uint8*/ + unsigned int fpga_id; /*tmp add*/ + unsigned int reg_addr; + unsigned int value; +}; +typedef struct dal_chip_parm_s dal_chip_parm_t; + +struct dal_intr_parm_s +{ + unsigned int irq; + unsigned int enable; +}; +typedef struct dal_intr_parm_s dal_intr_parm_t; + +struct dal_irq_mapping_s +{ + unsigned int hw_irq; + unsigned int sw_irq; +}; +typedef struct dal_irq_mapping_s dal_irq_mapping_t; + +struct dal_user_dev_s +{ + unsigned int chip_num; /*output: local chip number*/ + unsigned int lchip; /*input: local chip id*/ + unsigned int phy_base0; /* low 32bits physical base address */ + unsigned int phy_base1; /* high 32bits physical base address */ + unsigned int bus_no; + unsigned int dev_no; + unsigned int fun_no; + void* virt_base[2]; /* Virtual base address; this must be last member */ +}; +typedef struct dal_user_dev_s dal_user_dev_t; + +struct dma_info_s +{ + unsigned int lchip; + unsigned int phy_base; + unsigned int phy_base_hi; + unsigned int size; + unsigned int* virt_base; +}; +typedef struct dma_info_s dma_info_t; + +struct dal_pci_cfg_ioctl_s +{ + unsigned int lchip; /* Device ID */ + unsigned int offset; + unsigned int value; +}; +typedef struct dal_pci_cfg_ioctl_s dal_pci_cfg_ioctl_t; + +struct dal_msi_info_s +{ + unsigned int lchip; + unsigned int irq_base; + unsigned int irq_num; +}; +typedef struct dal_msi_info_s dal_msi_info_t; + +struct dal_intr_info_s +{ + unsigned int irq; + unsigned int irq_idx; +}; +typedef struct dal_intr_info_s dal_intr_info_t; + +struct dal_dma_cache_info_s +{ + unsigned long ptr; + unsigned int length; +}; +typedef struct dal_dma_cache_info_s dal_dma_cache_info_t; + +#define CMD_MAGIC 'C' +#define CMD_WRITE_CHIP _IO(CMD_MAGIC, 0) /* for humber ioctrol*/ +#define CMD_READ_CHIP _IO(CMD_MAGIC, 1) /* for humber ioctrol*/ +#define CMD_GET_DEVICES _IO(CMD_MAGIC, 2) +#define CMD_GET_DAL_VERSION _IO(CMD_MAGIC, 3) +#define CMD_PCI_CONFIG_WRITE _IO(CMD_MAGIC, 4) +#define CMD_PCI_CONFIG_READ _IO(CMD_MAGIC, 5) +#define CMD_GET_DMA_INFO _IO(CMD_MAGIC, 6) +#define CMD_REG_INTERRUPTS _IO(CMD_MAGIC, 7) +#define CMD_UNREG_INTERRUPTS _IO(CMD_MAGIC, 8) +#define CMD_EN_INTERRUPTS _IO(CMD_MAGIC, 9) +#define CMD_I2C_READ _IO(CMD_MAGIC, 10) +#define CMD_I2C_WRITE _IO(CMD_MAGIC, 11) +#define CMD_GET_MSI_INFO _IO(CMD_MAGIC, 12) +#define CMD_SET_MSI_CAP _IO(CMD_MAGIC, 13) +#define CMD_IRQ_MAPPING _IO(CMD_MAGIC, 14) +#define CMD_GET_INTR_INFO _IO(CMD_MAGIC, 15) +#define CMD_CACHE_INVAL _IO(CMD_MAGIC, 16) +#define CMD_CACHE_FLUSH _IO(CMD_MAGIC, 17) + +enum dal_version_e +{ + VERSION_MIN, + VERSION_1DOT0, + VERSION_1DOT1, + VERSION_1DOT2, + + VERSION_MAX +}; +typedef enum dal_version_e dal_version_t; + +/* We try to assemble a contiguous segment from chunks of this size */ +#define DMA_BLOCK_SIZE (512 * DAL_ONE_KB) + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.c b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.c new file mode 100644 index 000000000000..5aca222a138f --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.c @@ -0,0 +1,350 @@ +#include "dal_mpool.h" + +#ifdef __KERNEL__ +#include +#include + +#define DAL_MALLOC(x) kmalloc(x, GFP_ATOMIC) +#define DAL_FREE(x) kfree(x) + +static spinlock_t dal_mpool_lock; +#define MPOOL_LOCK_INIT() spin_lock_init(&dal_mpool_lock) +#define MPOOL_LOCK() unsigned long flags; spin_lock_irqsave(&dal_mpool_lock, flags) +#define MPOOL_UNLOCK() spin_unlock_irqrestore(&dal_mpool_lock, flags) +#define DAL_PRINT(fmt,arg...) printk(fmt,##arg) +#else /* !__KERNEL__*/ + +#include +#include "sal.h" +#define DAL_MALLOC(x) malloc(x) +#define DAL_FREE(x) free(x) +static sal_mutex_t* dal_mpool_lock; +#define MPOOL_LOCK_INIT() sal_mutex_create(&dal_mpool_lock) +#define MPOOL_LOCK() sal_mutex_lock(dal_mpool_lock) +#define MPOOL_UNLOCK() sal_mutex_unlock(dal_mpool_lock) +#define DAL_PRINT(fmt,arg...) sal_printf(fmt,##arg) + +#endif /* __KERNEL__ */ + + + +dal_mpool_mem_t* g_free_block_ptr = NULL; + +/* System cache line size */ +#ifndef DAL_CACHE_LINE_BYTES +#define DAL_CACHE_LINE_BYTES 256 +#endif + +#define DAL_MAX_CHIP_NUM 32 +static dal_mpool_mem_t* p_desc_pool[DAL_MAX_CHIP_NUM] = {0}; +static dal_mpool_mem_t* p_data_pool[DAL_MAX_CHIP_NUM] = {0}; + +int +dal_mpool_init(void) +{ + MPOOL_LOCK_INIT(); + return 0; +} + +dal_mpool_mem_t* +_dal_mpool_create(void* base, int size, int type) +{ + dal_mpool_mem_t* head = NULL; + dal_mpool_mem_t* tail = NULL; + + head = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (head == NULL) + { + return NULL; + } + + tail = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (tail == NULL) + { + DAL_FREE(head); + return NULL; + } + + head->size = tail->size = 0; + head->type = type; + head->address = base; + tail->address = head->address + size; + head->next = tail; + tail->next = NULL; + + return head; +} + +dal_mpool_mem_t* +dal_mpool_create(unsigned char lchip, void* base, int size) +{ + dal_mpool_mem_t* head = NULL; + int mod = (int)(((unsigned long)base) & (DAL_CACHE_LINE_BYTES - 1)); + + MPOOL_LOCK(); + + if (mod) + { + base = (char*)base + (DAL_CACHE_LINE_BYTES - mod); + size -= (DAL_CACHE_LINE_BYTES - mod); + } + + size &= ~(DAL_CACHE_LINE_BYTES - 1); + + /* init for common linkptr, only used for GB */ + head = _dal_mpool_create(base, size, DAL_MPOOL_TYPE_USELESS); + if (NULL == head) + { + MPOOL_UNLOCK(); + return NULL; + } + + /* init for desc linkptr */ + p_desc_pool[lchip] = _dal_mpool_create(base, DAL_MPOOL_MAX_DESX_SIZE, DAL_MPOOL_TYPE_DESC); + if (NULL == p_desc_pool[lchip]) + { + MPOOL_UNLOCK(); + DAL_FREE(head->next); + DAL_FREE(head); + return NULL; + } + + /* init for data linkptr */ + p_data_pool[lchip] = _dal_mpool_create(((char*)base+DAL_MPOOL_MAX_DESX_SIZE), (size - DAL_MPOOL_MAX_DESX_SIZE), DAL_MPOOL_TYPE_DATA); + if (NULL == p_data_pool[lchip]) + { + MPOOL_UNLOCK(); + DAL_FREE(head->next); + DAL_FREE(head); + DAL_FREE(p_desc_pool[lchip]->next); + DAL_FREE(p_desc_pool[lchip]); + return NULL; + } + + MPOOL_UNLOCK(); + + return head; +} + +dal_mpool_mem_t* +_dal_mpool_alloc_comon(dal_mpool_mem_t* ptr, int size, int type) +{ + dal_mpool_mem_t* new_ptr = NULL; + + while (ptr && ptr->next) + { + if (ptr->next->address - (ptr->address + ptr->size) >= size) + { + break; + } + + ptr = ptr->next; + } + + if (!(ptr && ptr->next)) + { + return NULL; + } + + new_ptr = DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (!new_ptr) + { + return NULL; + } + + new_ptr->type = type; + new_ptr->address = ptr->address + ptr->size; + new_ptr->size = size; + new_ptr->next = ptr->next; + ptr->next = new_ptr; + + return new_ptr; +} + +void* +dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type) +{ + dal_mpool_mem_t* ptr = NULL; + dal_mpool_mem_t* new_ptr = NULL; + int mod; + + MPOOL_LOCK(); + + mod = size & (DAL_CACHE_LINE_BYTES - 1); + if (mod != 0) + { + size += (DAL_CACHE_LINE_BYTES - mod); + } + + switch(type) + { + case DAL_MPOOL_TYPE_USELESS: + ptr = pool; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + case DAL_MPOOL_TYPE_DESC: + ptr = p_desc_pool[lchip]; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + case DAL_MPOOL_TYPE_DATA: + ptr = p_data_pool[lchip]; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + default: + MPOOL_UNLOCK(); + return NULL; + break; + } + + MPOOL_UNLOCK(); + if( NULL == new_ptr ) + { + return NULL; + } + + return new_ptr->address; +} + +void +_dal_mpool_free(dal_mpool_mem_t* ptr, void* addr, int type) +{ + unsigned char* address = (unsigned char*)addr; + dal_mpool_mem_t* prev = NULL; + + while (ptr && ptr->next) + { + if (ptr->next->address == address) + { + break; + } + + ptr = ptr->next; + } + + if (ptr && ptr->next) + { + prev = ptr; + ptr = ptr->next; + prev->next = ptr->next; + DAL_FREE(ptr); + } + + return; +} + +void +dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr) +{ + dal_mpool_mem_t* ptr = pool; + + MPOOL_LOCK(); + + switch(pool->type) + { + case DAL_MPOOL_TYPE_USELESS: + ptr = pool; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_USELESS); + break; + case DAL_MPOOL_TYPE_DESC: + ptr = p_desc_pool[lchip]; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DESC); + break; + case DAL_MPOOL_TYPE_DATA: + ptr = p_data_pool[lchip]; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DATA); + break; + default: + break; + } + + MPOOL_UNLOCK(); + return; +} + +int +dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool) +{ + dal_mpool_mem_t* ptr, * next; + + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + for (ptr = p_desc_pool[lchip]; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + for (ptr = p_data_pool[lchip]; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + MPOOL_UNLOCK(); + + return 0; +} + +int +dal_mpool_usage(dal_mpool_mem_t* pool, int type) +{ + int usage = 0; + dal_mpool_mem_t* ptr; + + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = ptr->next) + { + if (ptr->type == type || ptr->type == -1) + { + usage += ptr->size; + } + } + + MPOOL_UNLOCK(); + + return usage; +} + +int +dal_mpool_debug(dal_mpool_mem_t* pool) +{ + dal_mpool_mem_t* ptr; + int index = 0; + + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = ptr->next) + { +// DAL_PRINT("%2dst mpool block: address=0x%8x, size=0x%x \n", index, (unsigned int)ptr->address, ptr->size); + DAL_PRINT("%2dst mpool block: address=%p, size=0x%x \n", index, ptr->address, ptr->size); // note + index++; + } + + MPOOL_UNLOCK(); + + return 0; +} + + diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.h b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.h new file mode 100644 index 000000000000..d93f88868136 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.h @@ -0,0 +1,72 @@ +/** + @file dal_mpool.h + + @author Copyright (C) 2011 Centec Networks Inc. All rights reserved. + + @date 2012-5-10 + + @version v2.0 + + This file contains the dma memory init, allocation and free APIs +*/ + +#ifndef _DMA_MPOOL_H +#define _DMA_MPOOL_H +#ifdef __cplusplus +extern "C" { +#endif + +#define DAL_MPOOL_MAX_DESX_SIZE (1024*1024) + +enum dal_mpool_type_e +{ + DAL_MPOOL_TYPE_USELESS, /* just compatible with GB */ + DAL_MPOOL_TYPE_DESC, /* dma mpool op for desc */ + DAL_MPOOL_TYPE_DATA /* dma mpool op for data */ +}; +typedef enum dal_mpool_type_e dal_mpool_type_t; + +struct dal_mpool_mem_s +{ + unsigned char* address; + int size; + int type; + struct dal_mpool_mem_s* next; +}; +typedef struct dal_mpool_mem_s dal_mpool_mem_t; + +/** + @brief This function is to alloc dma memory + + @param[in] size size of memory + + @return NULL + +*/ +extern int +dal_mpool_init(void); + +extern dal_mpool_mem_t* +dal_mpool_create(unsigned char lchip, void* base_ptr, int size); + +extern void* +dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type); + +extern void +dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr); + +extern int +dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool); + +extern int +dal_mpool_usage(dal_mpool_mem_t* pool, int type); + +extern int +dal_mpool_debug(dal_mpool_mem_t* pool); +#ifdef __cplusplus +} +#endif + +#endif /* !_DMA_MPOOL_H */ + + diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/scripts/add_crontab_remove_syslog.sh b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/add_crontab_remove_syslog.sh new file mode 100755 index 000000000000..f5db8f0fc68e --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/add_crontab_remove_syslog.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +#sed -n '7p' /etc/rsyslog.d/99-default.conf +sudo sed -i '7c !user.debug;*.*;cron,auth,authpriv.none -/var/log/syslog' /etc/rsyslog.d/99-default.conf +sudo sed -i '10c user.debug /var/log/sdkdebug' /etc/rsyslog.d/99-default.conf +#sed -n '7p' /etc/rsyslog.d/99-default.conf +sudo service rsyslog restart + +sudo sed -i '9c */5 * * * * root /usr/bin/remove_syslog.sh' /etc/crontab +#echo "*/5 * * * * root /usr/bin/remove_syslog.sh" >> /etc/crontab + +exit 0 diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/scripts/create_eeprom.sh b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/create_eeprom.sh new file mode 100755 index 000000000000..052191a33803 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/create_eeprom.sh @@ -0,0 +1,18 @@ +#! /bin/bash + +#find cache of eeprom and delete, otherwise will dislay cache +cache_file="/var/cache/sonic/decode-syseeprom/syseeprom_cache" +if [ -f $cache_file ]; then + rm -f $cache_file +fi + +#create new device for eeprom +tmp=`i2cdetect -l | grep CP` +bus_num=${tmp:4:1} + +path="/sys/bus/i2c/devices/i2c-${bus_num}" + +cd $path +echo "24c512 0x56" > new_device + +sudo dd if=/sys/bus/i2c/devices/${bus_num}-0056/eeprom of=/home/admin/eeprom.bin bs=1 count=512 diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/scripts/es6220_platform.sh b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/es6220_platform.sh new file mode 100755 index 000000000000..3f6990dc46d9 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/es6220_platform.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +#platform init script for embedway es6220 + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # I801 adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus I801 adapter at '* ]]; then + found=1 + break + fi + done + + [ $found -eq 0 ] && echo "cannot find I801" && exit 1 +} + +init_devnum + +if [ "$1" == "init" ]; then + #install drivers and dependencies + depmod -a + modprobe dal + +elif [ "$1" == "deinit" ]; then + modprobe -r dal +else + echo "e582-48x2q4z_platform : Invalid option !" +fi diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/scripts/remove_syslog.sh b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/remove_syslog.sh new file mode 100755 index 000000000000..1366ffbdd819 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/remove_syslog.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +#remove syslog + +sudo find /var/log/ -mtime +7 -name "syslog.*" | sudo xargs rm -rf + +#echo "remove_syslog.sh crontab is running" >> /home/admin/shell.txt + +exit 0 diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/service/es6220_platform.service b/platform/centec/sonic-platform-modules-embedway/es6220/service/es6220_platform.service new file mode 100644 index 000000000000..111ed4952649 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/service/es6220_platform.service @@ -0,0 +1,13 @@ +[Unit] +Description=embedway es6220 platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-embedway-es6220 start +ExecStop=-/etc/init.d/platform-modules-embedway-es6220 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index 34877600fd13..ba57d22f58e7 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -93,7 +93,7 @@ def get_system_mac(): # Align last byte of MAC if necessary if version_info and version_info['asic_type'] == 'centec': last_byte = mac[-2:] - aligned_last_byte = format(int(int(last_byte, 16) & 0b11000000), '02x') + aligned_last_byte = format(int(int(last_byte, 16) + 1), '02x') mac = mac[:-2] + aligned_last_byte return mac From d8b716681cd27f0131cbbc6b7f7a7be01a2eb5f9 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 17 Apr 2020 10:46:56 -0700 Subject: [PATCH 0562/1427] [sonic-buildimage] libsaibcm Debian package update (#4439) from 3.7.3.3-3 to 3.7.3.3-4 Fixes for PFC WD Signed-off-by: Abhishek Dosi --- platform/broadcom/sai.mk | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 3d38c760d85b..e6e40039caf0 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.3.3-3_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3-3_amd64.deb?sv=2015-04-05&sr=b&sig=1MS77TFH1wpXHIQuxvysznffb8shDJa7QWTCpXX3qH4%3D&se=2033-11-14T01%3A39%3A44Z&sp=r" - -BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3-3_amd64.deb +BRCM_SAI = libsaibcm_3.7.3.3-4_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3-4_amd64.deb?sv=2015-04-05&sr=b&sig=9z7vLhweD%2B%2FZylkr9XsDAJ3DdE5NJlcPTslFYyBuAXU%3D&se=2033-12-25T14%3A52%3A25Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3-4_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3-3_amd64.deb?sv=2015-04-05&sr=b&sig=Y%2FXr6tZPrUQn5bLZqXYr6Nba%2BBbhz8lJdXyNEKZ3Sh8%3D&se=2033-11-14T01%3A44%3A38Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3-4_amd64.deb?sv=2015-04-05&sr=b&sig=SAOoGh2zdljiPuKeDoa%2B1lSJzZ8uXh2Irl2RZX1uAiA%3D&se=2033-12-25T14%3A53%3A44Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 5ce330ad3b311d14a180cbd2877f395175f67c69 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 18 Apr 2020 21:14:05 -0700 Subject: [PATCH 0563/1427] [grub]: use UUID for root partition (#4443) Signed-off-by: Guohan Lu --- installer/x86_64/install.sh | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index d0aa7818df9b..6a347c78db73 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -583,19 +583,22 @@ EOF $onie_root_dir/tools/bin/onie-boot-mode -q -o install fi -# Add a menu entry for the DEMO OS +# Add a menu entry for the SONiC OS # Note: assume that apparmor is supported in the kernel demo_grub_entry="$demo_volume_revision_label" if [ "$install_env" = "sonic" ]; then old_sonic_menuentry=$(cat /host/grub/grub.cfg | sed "/$running_sonic_revision/,/}/!d") - demo_dev=$(echo $old_sonic_menuentry | sed -e "s/.*root\=\(.*\)rw.*/\1/") + grub_cfg_root=$(echo $old_sonic_menuentry | sed -e "s/.*root\=\(.*\)rw.*/\1/") onie_menuentry=$(cat /host/grub/grub.cfg | sed "/menuentry ONIE/,/}/!d") -fi - -if [ "$install_env" = "build" ]; then +elif [ "$install_env" = "build" ]; then grub_cfg_root=%%SONIC_ROOT%% -else - grub_cfg_root=$demo_dev +else # install_env = "onie" + uuid=$(blkid "$demo_dev" | sed -ne 's/.* UUID=\"\([^"]*\)\".*/\1/p') + if [ -z "$uuid" ]; then + grub_cfg_root=$demo_dev + else + grub_cfg_root=UUID=$uuid + fi fi cat <> $grub_cfg From 583bfde439d0c5027db6e17e57b01e36cdd2855e Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Sun, 19 Apr 2020 11:34:30 -0700 Subject: [PATCH 0564/1427] Kubeadm v1.18.0 requires Calico images of version v3.12.1 (#4445) --- rules/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/config b/rules/config index 2e49e4349a00..c893a580b679 100644 --- a/rules/config +++ b/rules/config @@ -143,5 +143,5 @@ INSTALL_KUBERNETES = n # KUBERNETES_VERSION = 1.18.0 K8s_GCR_IO_PAUSE_VERSION = 3.2 -K8s_CNI_CALICO_VERSION = 3.12.0 +K8s_CNI_CALICO_VERSION = 3.12.1 From 87f2dbd75f3f44a0b23414a605ff01a35f78eab2 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sun, 19 Apr 2020 18:46:30 -0700 Subject: [PATCH 0565/1427] [grub]: allow access from both console and serial (#4444) console means the vga port. this is mainly used for virtual environment such as hyper-v or virtualbox where you have the virtual vga port to display the boot up process. Signed-off-by: Guohan Lu --- installer/x86_64/install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index 6a347c78db73..daac4796bc71 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -545,8 +545,8 @@ export GRUB_CMDLINE_LINUX # Add common configuration, like the timeout and serial console. cat < $grub_cfg $GRUB_SERIAL_COMMAND -terminal_input serial -terminal_output serial +terminal_input console serial +terminal_output console serial set timeout=5 From b171960bc1795f25ca71b0f3a8f504dbb1f46a2d Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 18 Apr 2020 21:54:37 +0000 Subject: [PATCH 0566/1427] [dpkg-cache]: add BLDENV in cache flags for binary-based packages add $(BLDENV) in cache flags for following targets: - $(SONIC_MAKE_DEBS) - $(SONIC_DPKG_DEBS) - $(SONIC_ONLINE_DEBS) - $(SONIC_COPY_DEBS) - $(SONIC_MAKE_FILES) This is because we could build a same package for both base image and docker which can be different os distribution, i.e., buster v.s. stretch. - target/debs/buster/swig3.0_3.0.12-2_amd64.deb - target/debs/stretch/swig3.0_3.0.12-2_amd64.deb Signed-off-by: Guohan Lu --- Makefile.cache | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Makefile.cache b/Makefile.cache index ec56f7f20af7..e319898286f5 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -241,7 +241,7 @@ define LOAD_FROM_CACHE # Update the cache_loaded variable $(if $(and $(CACHE_FILE_SELECT),$(filter $(RCACHE_OPTIONS),$(SONIC_DPKG_CACHE_METHOD))), $(if $(LOAD_DRV_DEB), $($(1)_CACHE_USER) tar -C $($(1)_BASE_PATH) -mxzvf $(CACHE_FILE_SELECT) 1>> $($(1)_DST_PATH)/$(1).log ,echo ); - echo "File $(CACHE_FILE_SELECT) is loaded from cache" >> $($(1)_DST_PATH)/$(1).log + echo "File $(CACHE_FILE_SELECT) is loaded from cache into $($(1)_BASE_PATH)" >> $($(1)_DST_PATH)/$(1).log $(eval $(1)_CACHE_LOADED := Yes) $(shell touch $(CACHE_FILE_SELECT)) echo "[ CACHE::LOADED ] $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE)" >> $($(1)_DST_PATH)/$(1).log @@ -316,7 +316,7 @@ define SHOW_WHY $(if $($(1)_PREREQ_PHONY), PHONY PREREQUISITES: $($(1)_PREREQ_PHONY)))" >> $($(1)_DST_PATH)/$(1).log @echo "[ FLAGS FILE ] : [$($(1)_FILE_FLAGS)] " >> $($(1)_DST_PATH)/$(1).log - @echo "[ FLAGS DEPENDS ] : [$($(1)_DEP_FLAGS)] " >> $($(1)_DST_PATH)/$(1).log + @echo "[ FLAGS DEPENDS ] : [$($(1)_DEP_FLAGS_ALL)] " >> $($(1)_DST_PATH)/$(1).log @echo "[ FLAGS DIFF ] : [$($(1)_FLAGS_DIFF)] " >> $($(1)_DST_PATH)/$(1).log @echo "[ DEP DEPENDS ] : [$($(1)_DEP_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log @echo "[ SMDEP DEPENDS ] : [$($(1)_SMDEP_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log @@ -456,6 +456,7 @@ $(foreach pkg, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONI # $(1) => target name # $(2) => target destination folder path # $(3) => target file extension +# $(4) => additional flags # # It updates the _DEP_FLAGS variable if there is any change in the module flags. @@ -463,12 +464,13 @@ define FLAGS_DEP_RULES ALL_DEP_FILES_LIST += $(foreach pkg,$(2), $(if $(filter none,$($(1)_CACHE_MODE)),$(addsuffix .$(3),$(addprefix $(pkg)/, $(1))))) $(addsuffix .$(3),$(addprefix $(2)/, $(1))) :: $(2)/%.$(3) : @$$(eval $$*_FILE_FLAGS := $$(shell test -f $$@ && cat $$@)) - @echo '$$($$*_DEP_FLAGS)' | cmp -s - $$@ || echo '$$($$*_DEP_FLAGS)' > $$@ - $$(eval $$*_FLAGS_DIFF := $$(filter-out $$($$*_FILE_FLAGS),$$($$*_DEP_FLAGS)) $$(filter-out $$($$*_DEP_FLAGS),$$($$*_FILE_FLAGS))) + @$$(eval $$*_DEP_FLAGS_ALL := $$(shell echo '$$($$*_DEP_FLAGS) $(4)' | sed -E 's/[ ]+/ /g' | sed -E 's/[ ]+$$$$//g')) + @echo '$$($$*_DEP_FLAGS_ALL)' | cmp -s - $$@ || echo '$$($$*_DEP_FLAGS_ALL)' > $$@ + $$(eval $$*_FLAGS_DIFF := $$(filter-out $$($$*_FILE_FLAGS),$$($$*_DEP_FLAGS_ALL)) $$(filter-out $$($$*_DEP_FLAGS_ALL),$$($$*_FILE_FLAGS))) @$$(if $$(MDEBUG), $$(info FLAGS: $$@, DEP:$$?)) endef -$(eval $(call FLAGS_DEP_RULES, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONIC_COPY_DEBS), $(DEBS_PATH),flags) ) -$(eval $(call FLAGS_DEP_RULES, $(SONIC_MAKE_FILES), $(FILES_PATH),flags)) +$(eval $(call FLAGS_DEP_RULES, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONIC_COPY_DEBS), $(DEBS_PATH),flags,$(BLDENV)) ) +$(eval $(call FLAGS_DEP_RULES, $(SONIC_MAKE_FILES), $(FILES_PATH),flags,$(BLDENV))) $(eval $(call FLAGS_DEP_RULES, $(SONIC_PYTHON_STDEB_DEBS), $(PYTHON_DEBS_PATH),flags)) $(eval $(call FLAGS_DEP_RULES, $(SONIC_PYTHON_WHEELS), $(PYTHON_WHEELS_PATH),flags)) $(eval $(call FLAGS_DEP_RULES, $(SONIC_DOCKER_IMAGES) $(SONIC_DOCKER_DBG_IMAGES), $(TARGET_PATH),flags)) From e7075907f9c65f0d54c2ffc3ef58f2c4f2fa633b Mon Sep 17 00:00:00 2001 From: byu343 Date: Sun, 19 Apr 2020 10:43:36 -0700 Subject: [PATCH 0567/1427] [arista]: Change kernel param for smartsville (#56) --- files/Aboot/boot0.j2 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 3c61c631af93..6460db61c8e3 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -321,10 +321,14 @@ platform_specific() { echo "iommu=on intel_iommu=on" >>/tmp/append read_system_eeprom fi - if in_array "$platform" "crow" "woodpecker" "magpie"; then + if in_array "$platform" "crow" "magpie"; then echo "amd_iommu=off modprobe.blacklist=snd_hda_intel,hdaudio" >> /tmp/append read_system_eeprom fi + if in_array "$platform" "woodpecker"; then + echo "modprobe.blacklist=snd_hda_intel,hdaudio" >> /tmp/append + read_system_eeprom + fi if [ $flash_size -ge 28000 ]; then varlog_size=4096 From 00957637807c47406826216db42663cb2f9eca75 Mon Sep 17 00:00:00 2001 From: byu343 Date: Sun, 19 Apr 2020 10:50:16 -0700 Subject: [PATCH 0568/1427] [arista]: Update driver submodules to support buster kernel (#57) --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 39860a109853..ab4e8e17e610 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 39860a109853b2f37367dfe68905e019b509d5bf +Subproject commit ab4e8e17e610e23d66b024fbf27bd83b41edf44c diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 39860a109853..ab4e8e17e610 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 39860a109853b2f37367dfe68905e019b509d5bf +Subproject commit ab4e8e17e610e23d66b024fbf27bd83b41edf44c From 7b53ae3b078c391dcf27936ef91cd5bc19772368 Mon Sep 17 00:00:00 2001 From: Kalimuthu-Velappan <53821802+Kalimuthu-Velappan@users.noreply.github.com> Date: Mon, 20 Apr 2020 18:14:25 +0000 Subject: [PATCH 0569/1427] [build]: DPKG caching fix for evaluation bugs (#4425) Added DPKG support for ICCPD package Added warning support for missing dependency files that causes the incorrect SHA generation. --- Makefile.cache | 10 ++++++++-- rules/docker-iccpd.dep | 11 +++++++++++ rules/iccpd.dep | 10 ++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 rules/docker-iccpd.dep create mode 100644 rules/iccpd.dep diff --git a/Makefile.cache b/Makefile.cache index 78ee4541a861..9e075e2db68c 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -172,8 +172,14 @@ define GET_MOD_DEP_SHA $(if $($(dfile)_MAIN_DEB),$($(dfile)_MAIN_DEB),$(dfile))) ) $(if $(MDEBUG), $(info $(1)_MOD_DEP_PKGS: $($(1)_MOD_DEP_PKGS))) - $(eval $(1)_DEP_MOD_SHA := $(shell git hash-object \ - $(foreach dfile,$($(1)_MOD_DEP_PKGS), $($(dfile)_DEP_FLAGS_FILE) $($(dfile)_MOD_HASH_FILE) $($(dfile)_SMOD_HASH_FILE) ) \ + + # Warn if there is any missing dependency files + $(eval $(1)_DEP_MOD_SHA_FILES := $(foreach dfile,$($(1)_MOD_DEP_PKGS), \ + $($(dfile)_DEP_FLAGS_FILE) $($(dfile)_MOD_HASH_FILE) $($(dfile)_SMOD_HASH_FILE)) ) + $(eval $(1)_DEP_FILES_MISSING := $(filter-out $(wildcard $($(1)_DEP_MOD_SHA_FILES)),$($(1)_DEP_MOD_SHA_FILES)) ) + $(if $($(1)_DEP_FILES_MISSING), $(warning "[ DPKG ] Dependecy file(s) are not found for $(1) : $($(1)_DEP_FILES_MISSING))) + + $(eval $(1)_DEP_MOD_SHA := $(shell git hash-object $($(1)_DEP_MOD_SHA_FILES) \ | sha1sum | awk '{print substr($$1,0,23);}')) endef diff --git a/rules/docker-iccpd.dep b/rules/docker-iccpd.dep new file mode 100644 index 000000000000..878d1711c3b1 --- /dev/null +++ b/rules/docker-iccpd.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_ICCPD)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-iccpd.mk rules/docker-iccpd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_ICCPD)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_ICCPD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_ICCPD)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_ICCPD),$(DOCKER_ICCPD_DBG))) diff --git a/rules/iccpd.dep b/rules/iccpd.dep new file mode 100644 index 000000000000..124cc5e421cb --- /dev/null +++ b/rules/iccpd.dep @@ -0,0 +1,10 @@ + +SPATH := $($(ICCPD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/iccpd.mk rules/iccpd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(ICCPD)_CACHE_MODE := GIT_CONTENT_SHA +$(ICCPD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(ICCPD)_DEP_FILES := $(DEP_FILES) + From 13bef09889f7331becad385a02a631785313ebfc Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Tue, 21 Apr 2020 05:02:46 +0300 Subject: [PATCH 0570/1427] [mellanox]: Add DPKG local caching support. (#4441) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/docker-ptf-mlnx.dep | 10 + platform/mellanox/docker-saiserver-mlnx.dep | 10 + platform/mellanox/docker-syncd-mlnx-rpc.dep | 10 + platform/mellanox/docker-syncd-mlnx.dep | 12 + platform/mellanox/fw.dep | 16 ++ platform/mellanox/hw-management.dep | 15 ++ platform/mellanox/issu-version.dep | 10 + platform/mellanox/libsaithrift-dev.dep | 32 +++ platform/mellanox/mft.dep | 18 ++ platform/mellanox/mlnx-ffb.dep | 10 + platform/mellanox/mlnx-ffb.mk | 2 +- platform/mellanox/mlnx-onie-fw-update.dep | 10 + platform/mellanox/mlnx-onie-fw-update.mk | 2 +- platform/mellanox/mlnx-platform-api.dep | 11 + platform/mellanox/mlnx-sai.dep | 21 ++ platform/mellanox/mlnx-ssd-fw-update.dep | 10 + platform/mellanox/mlnx-ssd-fw-update.mk | 2 +- platform/mellanox/one-image.dep | 3 + platform/mellanox/rules.dep | 18 ++ platform/mellanox/sdk.dep | 229 ++++++++++++++++++++ 20 files changed, 448 insertions(+), 3 deletions(-) create mode 100644 platform/mellanox/docker-ptf-mlnx.dep create mode 100644 platform/mellanox/docker-saiserver-mlnx.dep create mode 100644 platform/mellanox/docker-syncd-mlnx-rpc.dep create mode 100644 platform/mellanox/docker-syncd-mlnx.dep create mode 100644 platform/mellanox/fw.dep create mode 100644 platform/mellanox/hw-management.dep create mode 100644 platform/mellanox/issu-version.dep create mode 100644 platform/mellanox/libsaithrift-dev.dep create mode 100644 platform/mellanox/mft.dep create mode 100644 platform/mellanox/mlnx-ffb.dep create mode 100644 platform/mellanox/mlnx-onie-fw-update.dep create mode 100644 platform/mellanox/mlnx-platform-api.dep create mode 100644 platform/mellanox/mlnx-sai.dep create mode 100644 platform/mellanox/mlnx-ssd-fw-update.dep create mode 100644 platform/mellanox/one-image.dep create mode 100644 platform/mellanox/rules.dep create mode 100644 platform/mellanox/sdk.dep diff --git a/platform/mellanox/docker-ptf-mlnx.dep b/platform/mellanox/docker-ptf-mlnx.dep new file mode 100644 index 000000000000..652fe0001c76 --- /dev/null +++ b/platform/mellanox/docker-ptf-mlnx.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(DOCKER_PTF_MLNX)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/docker-ptf-mlnx.mk $(PLATFORM_PATH)/docker-ptf-mlnx.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(DPATH)) + +$(DOCKER_PTF_MLNX)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_PTF_MLNX)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_PTF_MLNX)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/docker-saiserver-mlnx.dep b/platform/mellanox/docker-saiserver-mlnx.dep new file mode 100644 index 000000000000..7a4e4fdcbb34 --- /dev/null +++ b/platform/mellanox/docker-saiserver-mlnx.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(DOCKER_SAISERVER_MLNX)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/docker-saiserver-mlnx.mk $(PLATFORM_PATH)/docker-saiserver-mlnx.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(DPATH)) + +$(DOCKER_SAISERVER_MLNX)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SAISERVER_MLNX)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SAISERVER_MLNX)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.dep b/platform/mellanox/docker-syncd-mlnx-rpc.dep new file mode 100644 index 000000000000..c79c94d2c03a --- /dev/null +++ b/platform/mellanox/docker-syncd-mlnx-rpc.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(DOCKER_SYNCD_MLNX_RPC)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/docker-syncd-mlnx-rpc.mk $(PLATFORM_PATH)/docker-syncd-mlnx-rpc.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(DPATH)) + +$(DOCKER_SYNCD_MLNX_RPC)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SYNCD_MLNX_RPC)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SYNCD_MLNX_RPC)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/docker-syncd-mlnx.dep b/platform/mellanox/docker-syncd-mlnx.dep new file mode 100644 index 000000000000..b8bdfdf625b7 --- /dev/null +++ b/platform/mellanox/docker-syncd-mlnx.dep @@ -0,0 +1,12 @@ +# DPKG FRK + +DPATH := $($(DOCKER_SYNCD_BASE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/docker-syncd-mlnx.mk $(PLATFORM_PATH)/docker-syncd-mlnx.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(DPATH)) + +$(DOCKER_SYNCD_BASE)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SYNCD_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SYNCD_BASE)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_SYNCD_BASE),$(DOCKER_SYNCD_BASE_DBG))) diff --git a/platform/mellanox/fw.dep b/platform/mellanox/fw.dep new file mode 100644 index 000000000000..228f6dc87e36 --- /dev/null +++ b/platform/mellanox/fw.dep @@ -0,0 +1,16 @@ +# DPKG FRK + +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/fw.mk $(PLATFORM_PATH)/fw.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) + +$(MLNX_SPC_FW_FILE)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SPC_FW_FILE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SPC_FW_FILE)_DEP_FILES := $(DEP_FILES) + +$(MLNX_SPC2_FW_FILE)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SPC2_FW_FILE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SPC2_FW_FILE)_DEP_FILES := $(DEP_FILES) + +$(MLNX_SPC3_FW_FILE)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SPC3_FW_FILE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SPC3_FW_FILE)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/hw-management.dep b/platform/mellanox/hw-management.dep new file mode 100644 index 000000000000..b69ca22b4c57 --- /dev/null +++ b/platform/mellanox/hw-management.dep @@ -0,0 +1,15 @@ +# DPKG FRK + +SPATH := $($(MLNX_HW_MANAGEMENT)_SRC_PATH) +SLINKS := $(shell find $(SPATH) -type l -exec echo {} \; | grep -Ev ' ') +SMDEP_PATHS := $(shell git submodule status --recursive -- $(SPATH) | awk '{print $$2}' | grep -Ev ' ') +SMDEP_FILES := $(foreach path,$(SMDEP_PATHS),$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/,$(shell cd $(path) && git ls-files | grep -Ev ' ')))) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/hw-management.mk $(PLATFORM_PATH)/hw-management.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(filter-out $(SMDEP_PATHS),$(shell git ls-files -- $(SPATH) | grep -Ev ' ')) + +$(MLNX_HW_MANAGEMENT)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_HW_MANAGEMENT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_HW_MANAGEMENT)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) +$(MLNX_HW_MANAGEMENT)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(MLNX_HW_MANAGEMENT)_SMDEP_PATHS := $(SMDEP_PATHS) diff --git a/platform/mellanox/issu-version.dep b/platform/mellanox/issu-version.dep new file mode 100644 index 000000000000..c4a178aef712 --- /dev/null +++ b/platform/mellanox/issu-version.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +SPATH := $($(ISSU_VERSION_FILE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/issu-version.mk $(PLATFORM_PATH)/issu-version.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(ISSU_VERSION_FILE)_CACHE_MODE := GIT_CONTENT_SHA +$(ISSU_VERSION_FILE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(ISSU_VERSION_FILE)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/libsaithrift-dev.dep b/platform/mellanox/libsaithrift-dev.dep new file mode 100644 index 000000000000..a6fd20007c77 --- /dev/null +++ b/platform/mellanox/libsaithrift-dev.dep @@ -0,0 +1,32 @@ +# DPKG FRK + +SPATH := $($(LIBSAITHRIFT_DEV)_SRC_PATH) +SLINKS := $(shell find $(SPATH) -type l -exec echo {} \; | grep -Ev ' ') +SMDEP_PATHS := $(SPATH) $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git submodule status --recursive | awk '{print $$2}' | grep -Ev ' ')) +SMDEP_FILES := $(foreach path,$(SMDEP_PATHS),$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/,$(shell cd $(path) && git ls-files | grep -Ev ' ')))) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/libsaithrift-dev.mk $(PLATFORM_PATH)/libsaithrift-dev.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) + +$(LIBSAITHRIFT_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBSAITHRIFT_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBSAITHRIFT_DEV)_DEP_FILES := $(DEP_FILES) +$(LIBSAITHRIFT_DEV)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(LIBSAITHRIFT_DEV)_SMDEP_PATHS := $(SMDEP_PATHS) + +$(PYTHON_SAITHRIFT)_CACHE_MODE := GIT_CONTENT_SHA +$(PYTHON_SAITHRIFT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PYTHON_SAITHRIFT)_DEP_FILES := $(DEP_FILES) +$(PYTHON_SAITHRIFT)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(PYTHON_SAITHRIFT)_SMDEP_PATHS := $(SMDEP_PATHS) + +$(SAISERVER)_CACHE_MODE := GIT_CONTENT_SHA +$(SAISERVER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SAISERVER)_DEP_FILES := $(DEP_FILES) +$(SAISERVER)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(SAISERVER)_SMDEP_PATHS := $(SMDEP_PATHS) + +$(SAISERVER_DBG)_CACHE_MODE := GIT_CONTENT_SHA +$(SAISERVER_DBG)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SAISERVER_DBG)_DEP_FILES := $(DEP_FILES) +$(SAISERVER_DBG)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(SAISERVER_DBG)_SMDEP_PATHS := $(SMDEP_PATHS) diff --git a/platform/mellanox/mft.dep b/platform/mellanox/mft.dep new file mode 100644 index 000000000000..7dcdaf1d305d --- /dev/null +++ b/platform/mellanox/mft.dep @@ -0,0 +1,18 @@ +# DPKG FRK + +SPATH := $($(MFT)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mft.mk $(PLATFORM_PATH)/mft.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(MFT)_CACHE_MODE := GIT_CONTENT_SHA +$(MFT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MFT)_DEP_FILES := $(DEP_FILES) + +$(KERNEL_MFT)_CACHE_MODE := GIT_CONTENT_SHA +$(KERNEL_MFT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(KERNEL_MFT)_DEP_FILES := $(DEP_FILES) + +$(MFT_OEM)_CACHE_MODE := GIT_CONTENT_SHA +$(MFT_OEM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MFT_OEM)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/mlnx-ffb.dep b/platform/mellanox/mlnx-ffb.dep new file mode 100644 index 000000000000..efaadd2767ae --- /dev/null +++ b/platform/mellanox/mlnx-ffb.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(MLNX_FFB_SCRIPT)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mlnx-ffb.mk $(PLATFORM_PATH)/mlnx-ffb.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(addprefix $(DPATH),$(MLNX_FFB_SCRIPT)) + +$(MLNX_FFB_SCRIPT)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_FFB_SCRIPT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_FFB_SCRIPT)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/mlnx-ffb.mk b/platform/mellanox/mlnx-ffb.mk index 82d50b7ae3e3..6c3c925b5996 100755 --- a/platform/mellanox/mlnx-ffb.mk +++ b/platform/mellanox/mlnx-ffb.mk @@ -1,7 +1,7 @@ # mellanox fast fast boot script MLNX_FFB_SCRIPT = mlnx-ffb.sh -$(MLNX_FFB_SCRIPT)_PATH = platform/mellanox/ +$(MLNX_FFB_SCRIPT)_PATH = $(PLATFORM_PATH)/ SONIC_COPY_FILES += $(MLNX_FFB_SCRIPT) MLNX_FILES += $(MLNX_FFB_SCRIPT) diff --git a/platform/mellanox/mlnx-onie-fw-update.dep b/platform/mellanox/mlnx-onie-fw-update.dep new file mode 100644 index 000000000000..f22352ed0cba --- /dev/null +++ b/platform/mellanox/mlnx-onie-fw-update.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(MLNX_ONIE_FW_UPDATE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mlnx-onie-fw-update.mk $(PLATFORM_PATH)/mlnx-onie-fw-update.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(addprefix $(DPATH),$(MLNX_ONIE_FW_UPDATE)) + +$(MLNX_ONIE_FW_UPDATE)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_ONIE_FW_UPDATE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_ONIE_FW_UPDATE)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/mlnx-onie-fw-update.mk b/platform/mellanox/mlnx-onie-fw-update.mk index 825c12c30ba4..13f68ce4671f 100644 --- a/platform/mellanox/mlnx-onie-fw-update.mk +++ b/platform/mellanox/mlnx-onie-fw-update.mk @@ -1,7 +1,7 @@ # onie update tool MLNX_ONIE_FW_UPDATE = mlnx-onie-fw-update.sh -$(MLNX_ONIE_FW_UPDATE)_PATH = platform/mellanox/ +$(MLNX_ONIE_FW_UPDATE)_PATH = $(PLATFORM_PATH)/ SONIC_COPY_FILES += $(MLNX_ONIE_FW_UPDATE) MLNX_FILES += $(MLNX_ONIE_FW_UPDATE) diff --git a/platform/mellanox/mlnx-platform-api.dep b/platform/mellanox/mlnx-platform-api.dep new file mode 100644 index 000000000000..865fe2a7ee4d --- /dev/null +++ b/platform/mellanox/mlnx-platform-api.dep @@ -0,0 +1,11 @@ +# DPKG FRK + +SPATH := $($(SONIC_PLATFORM_API_PY2)_SRC_PATH) +SLINKS := $(shell find $(SPATH) -type l -exec echo {} \; | grep -Ev ' ') +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mlnx-platform-api.mk $(PLATFORM_PATH)/mlnx-platform-api.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH) | grep -Ev ' ') + +$(SONIC_PLATFORM_API_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_PLATFORM_API_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PLATFORM_API_PY2)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) diff --git a/platform/mellanox/mlnx-sai.dep b/platform/mellanox/mlnx-sai.dep new file mode 100644 index 000000000000..2a3862caa8e8 --- /dev/null +++ b/platform/mellanox/mlnx-sai.dep @@ -0,0 +1,21 @@ +# DPKG FRK + +SPATH := $($(MLNX_SAI)_SRC_PATH) +SLINKS := $(shell find $(SPATH) -type l -exec echo {} \; | grep -Ev ' ') +SMDEP_PATHS := $(shell git submodule status --recursive -- $(SPATH) | awk '{print $$2}' | grep -Ev ' ') +SMDEP_FILES := $(foreach path,$(SMDEP_PATHS),$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/,$(shell cd $(path) && git ls-files | grep -Ev ' ')))) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mlnx-sai.mk $(PLATFORM_PATH)/mlnx-sai.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(filter-out $(SMDEP_PATHS),$(shell git ls-files -- $(SPATH) | grep -Ev ' ')) + +$(MLNX_SAI)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SAI)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SAI)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) +$(MLNX_SAI)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(MLNX_SAI)_SMDEP_PATHS := $(SMDEP_PATHS) + +$(MLNX_SAI_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SAI_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SAI_DBGSYM)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) +$(MLNX_SAI_DBGSYM)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(MLNX_SAI_DBGSYM)_SMDEP_PATHS := $(SMDEP_PATHS) diff --git a/platform/mellanox/mlnx-ssd-fw-update.dep b/platform/mellanox/mlnx-ssd-fw-update.dep new file mode 100644 index 000000000000..60e587a64f07 --- /dev/null +++ b/platform/mellanox/mlnx-ssd-fw-update.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(MLNX_SSD_FW_UPDATE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mlnx-ssd-fw-update.mk $(PLATFORM_PATH)/mlnx-ssd-fw-update.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(addprefix $(DPATH),$(MLNX_SSD_FW_UPDATE)) + +$(MLNX_SSD_FW_UPDATE)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SSD_FW_UPDATE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SSD_FW_UPDATE)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/mlnx-ssd-fw-update.mk b/platform/mellanox/mlnx-ssd-fw-update.mk index f932e57d2521..024710efbf9b 100644 --- a/platform/mellanox/mlnx-ssd-fw-update.mk +++ b/platform/mellanox/mlnx-ssd-fw-update.mk @@ -1,7 +1,7 @@ # ssd update tool MLNX_SSD_FW_UPDATE = mlnx-ssd-fw-update.sh -$(MLNX_SSD_FW_UPDATE)_PATH = platform/mellanox/ +$(MLNX_SSD_FW_UPDATE)_PATH = $(PLATFORM_PATH)/ SONIC_COPY_FILES += $(MLNX_SSD_FW_UPDATE) MLNX_FILES += $(MLNX_SSD_FW_UPDATE) diff --git a/platform/mellanox/one-image.dep b/platform/mellanox/one-image.dep new file mode 100644 index 000000000000..c29b43a7bba9 --- /dev/null +++ b/platform/mellanox/one-image.dep @@ -0,0 +1,3 @@ +# DPKG FRK + +$(SONIC_ONE_IMAGE)_CACHE_MODE := none diff --git a/platform/mellanox/rules.dep b/platform/mellanox/rules.dep new file mode 100644 index 000000000000..8986eb2e0808 --- /dev/null +++ b/platform/mellanox/rules.dep @@ -0,0 +1,18 @@ +# DPKG FRK + +include $(PLATFORM_PATH)/sdk.dep +include $(PLATFORM_PATH)/fw.dep +include $(PLATFORM_PATH)/mft.dep +include $(PLATFORM_PATH)/mlnx-sai.dep +include $(PLATFORM_PATH)/hw-management.dep +include $(PLATFORM_PATH)/mlnx-platform-api.dep +include $(PLATFORM_PATH)/docker-syncd-mlnx.dep +include $(PLATFORM_PATH)/docker-syncd-mlnx-rpc.dep +include $(PLATFORM_PATH)/docker-saiserver-mlnx.dep +include $(PLATFORM_PATH)/one-image.dep +include $(PLATFORM_PATH)/libsaithrift-dev.dep +include $(PLATFORM_PATH)/docker-ptf-mlnx.dep +include $(PLATFORM_PATH)/mlnx-ffb.dep +include $(PLATFORM_PATH)/issu-version.dep +include $(PLATFORM_PATH)/mlnx-onie-fw-update.dep +include $(PLATFORM_PATH)/mlnx-ssd-fw-update.dep diff --git a/platform/mellanox/sdk.dep b/platform/mellanox/sdk.dep new file mode 100644 index 000000000000..bf3ecb95d8ae --- /dev/null +++ b/platform/mellanox/sdk.dep @@ -0,0 +1,229 @@ +# DPKG FRK + +# APPLIBS + +SPATH := $($(APPLIBS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(APPLIBS)_CACHE_MODE := GIT_CONTENT_SHA +$(APPLIBS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(APPLIBS)_DEP_FILES := $(DEP_FILES) + +$(APPLIBS_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(APPLIBS_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(APPLIBS_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(APPLIBS_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(APPLIBS_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(APPLIBS_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# IPROUTE2_MLNX + +SPATH := $($(IPROUTE2_MLNX)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(IPROUTE2_MLNX)_CACHE_MODE := GIT_CONTENT_SHA +$(IPROUTE2_MLNX)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(IPROUTE2_MLNX)_DEP_FILES := $(DEP_FILES) + +$(IPROUTE2_MLNX_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(IPROUTE2_MLNX_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(IPROUTE2_MLNX_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(IPROUTE2_MLNX_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(IPROUTE2_MLNX_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(IPROUTE2_MLNX_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_COMPLIB + +SPATH := $($(SX_COMPLIB)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SX_COMPLIB)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_COMPLIB)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_COMPLIB)_DEP_FILES := $(DEP_FILES) + +$(SX_COMPLIB_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_COMPLIB_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_COMPLIB_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SX_COMPLIB_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_COMPLIB_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_COMPLIB_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_EXAMPLES + +SPATH := $($(SX_EXAMPLES)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SX_EXAMPLES)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_EXAMPLES)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_EXAMPLES)_DEP_FILES := $(DEP_FILES) + +$(SX_EXAMPLES_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_EXAMPLES_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_EXAMPLES_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SX_EXAMPLES_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_EXAMPLES_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_EXAMPLES_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_GEN_UTILS + +SPATH := $($(SX_GEN_UTILS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SX_GEN_UTILS)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_GEN_UTILS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_GEN_UTILS)_DEP_FILES := $(DEP_FILES) + +$(SX_GEN_UTILS_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_GEN_UTILS_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_GEN_UTILS_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SX_GEN_UTILS_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_GEN_UTILS_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_GEN_UTILS_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_SCEW + +SPATH := $($(SX_SCEW)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SX_SCEW)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_SCEW)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_SCEW)_DEP_FILES := $(DEP_FILES) + +$(SX_SCEW_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_SCEW_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_SCEW_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SX_SCEW_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_SCEW_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_SCEW_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SXD_LIBS + +SPATH := $($(SXD_LIBS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SXD_LIBS)_CACHE_MODE := GIT_CONTENT_SHA +$(SXD_LIBS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SXD_LIBS)_DEP_FILES := $(DEP_FILES) + +$(SXD_LIBS_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SXD_LIBS_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SXD_LIBS_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SXD_LIBS_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SXD_LIBS_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SXD_LIBS_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# PYTHON_SDK_API + +SPATH := $($(PYTHON_SDK_API)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(PYTHON_SDK_API)_CACHE_MODE := GIT_CONTENT_SHA +$(PYTHON_SDK_API)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PYTHON_SDK_API)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(PYTHON_SDK_API_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(PYTHON_SDK_API_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PYTHON_SDK_API_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_ACL_HELPER + +SPATH := $($(SX_ACL_HELPER)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SX_ACL_HELPER)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_ACL_HELPER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_ACL_HELPER)_DEP_FILES := $(DEP_FILES) + +$(SX_ACL_HELPER_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_ACL_HELPER_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_ACL_HELPER_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SX_ACL_HELPER_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_ACL_HELPER_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_ACL_HELPER_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# WJH_LIBS + +SPATH := $($(WJH_LIBS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(WJH_LIBS)_CACHE_MODE := GIT_CONTENT_SHA +$(WJH_LIBS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(WJH_LIBS)_DEP_FILES := $(DEP_FILES) + +$(WJH_LIBS_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(WJH_LIBS_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(WJH_LIBS_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(WJH_LIBS_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(WJH_LIBS_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(WJH_LIBS_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_KERNEL + +SPATH := $($(SX_KERNEL)_SRC_PATH) +SLINKS := $(shell find $(SPATH) -type l -exec echo {} \; | grep -Ev ' ') +SMDEP_PATHS := $(shell git submodule status --recursive -- $(SPATH) | awk '{print $$2}' | grep -Ev ' ') +SMDEP_FILES := $(foreach path,$(SMDEP_PATHS),$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/,$(shell cd $(path) && git ls-files | grep -Ev ' ')))) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(filter-out $(SMDEP_PATHS),$(shell git ls-files -- $(SPATH) | grep -Ev ' ')) + +$(SX_KERNEL)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_KERNEL)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_KERNEL)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) +$(SX_KERNEL)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(SX_KERNEL)_SMDEP_PATHS := $(SMDEP_PATHS) + +$(SX_KERNEL_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_KERNEL_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_KERNEL_DEV)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) +$(SX_KERNEL_DEV)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(SX_KERNEL_DEV)_SMDEP_PATHS := $(SMDEP_PATHS) From d1940b2cf40f80f3bab764b18e5229d96017c8d9 Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Tue, 21 Apr 2020 14:55:51 +0530 Subject: [PATCH 0571/1427] [Juniper] Re-organizing sonic_platform modules (#4448) This patch set implements the following: - Fixes the conflicts in chassis.py / platform.py in sonic_platfrom - Consolidating the common library files in sonic_platform - Moving QFX5210 specific drivers to qfx5210/modules - Moving Juniper common fpga drivers to common/modules - Cleaning up the platform driver files - Bug fixes in QFX5210 platform monitor & initialiazation script - Fixing the bugs in QFX5210 eeprom parsing Signed-off-by: Ciju Rajan K --- .../media_settings.json | 0 .../plugins/eeprom.py | 0 .../plugins/led_control.py | 0 .../plugins/psuutil.py | 0 .../plugins/qfx5200_eeprom_data.py | 0 .../plugins/qfx5200_sfp_init.py | 0 .../plugins/sfputil.py | 0 .../led_proc_init.soc | 0 .../plugins/psuutil.py | 0 .../plugins/qfx5210_eeprom_data.py | 331 +++++ .../pmon_daemon_control.json | 1 + .../common/modules/gpio-tmc.c | 661 ++++++++++ .../common/modules/i2c-tmc.c | 1107 ++++++++++++++++ .../common/modules/jnx-refpga-tmc.c | 603 +++++++++ .../common/modules/jnx-tmc-core.c | 477 +++++++ .../common/modules/jnx-tmc.h | 93 ++ .../common/modules/juniper_i2c_cpld.c | 892 ------------- .../common/modules/ym2651y.c | 622 --------- .../debian/rules | 5 +- .../sonic-platform-juniper-qfx5200.install | 2 - .../qfx5200/modules/gpio-tmc.c | 662 +--------- .../qfx5200/modules/i2c-tmc.c | 1108 +---------------- .../qfx5200/modules/jnx-refpga-tmc.c | 604 +-------- .../qfx5200/modules/jnx-tmc-core.c | 478 +------ .../qfx5200/modules/jnx-tmc.h | 94 +- .../qfx5200/modules/pci_ids.h | 144 --- .../service/qfx5200-platform-init.service | 0 .../qfx5200/setup.py | 15 - .../qfx5200/sonic_platform/chassis.py | 260 ---- .../qfx5210/modules/juniper_i2c_cpld.c | 893 ++++++++++++- .../qfx5210/modules/ym2651y.c | 623 ++++++++- .../service/qfx5210-platform-init.service | 0 .../qfx5210/sonic_platform/__init__.py | 1 - .../qfx5210/sonic_platform/platform.py | 67 - .../qfx5210/utils/juniper_qfx5210_monitor.py | 69 +- .../qfx5210/utils/juniper_qfx5210_util.py | 145 +-- .../{qfx5210 => }/setup.py | 4 +- .../{qfx5200 => }/sonic_platform/__init__.py | 0 .../{qfx5210 => }/sonic_platform/chassis.py | 154 ++- .../{qfx5200 => }/sonic_platform/platform.py | 31 +- 40 files changed, 4924 insertions(+), 5222 deletions(-) mode change 100755 => 100644 device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json mode change 100755 => 100644 device/juniper/x86_64-juniper_qfx5200-r0/plugins/eeprom.py mode change 100755 => 100644 device/juniper/x86_64-juniper_qfx5200-r0/plugins/led_control.py mode change 100755 => 100644 device/juniper/x86_64-juniper_qfx5200-r0/plugins/psuutil.py mode change 100755 => 100644 device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py mode change 100755 => 100644 device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py mode change 100755 => 100644 device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py mode change 100755 => 100644 device/juniper/x86_64-juniper_qfx5210-r0/led_proc_init.soc mode change 100755 => 100644 device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py create mode 100644 device/juniper/x86_64-juniper_qfx5210-r0/plugins/qfx5210_eeprom_data.py create mode 100644 platform/broadcom/sonic-platform-modules-juniper/common/modules/gpio-tmc.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/common/modules/i2c-tmc.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-refpga-tmc.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc-core.c create mode 100644 platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc.h delete mode 100644 platform/broadcom/sonic-platform-modules-juniper/common/modules/juniper_i2c_cpld.c delete mode 100644 platform/broadcom/sonic-platform-modules-juniper/common/modules/ym2651y.c mode change 100644 => 120000 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c mode change 100644 => 120000 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c mode change 100644 => 120000 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c mode change 100644 => 120000 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c mode change 100644 => 120000 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h delete mode 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/pci_ids.h mode change 100755 => 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5200/service/qfx5200-platform-init.service delete mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/setup.py delete mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/chassis.py mode change 120000 => 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c mode change 120000 => 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c mode change 100755 => 100644 platform/broadcom/sonic-platform-modules-juniper/qfx5210/service/qfx5210-platform-init.service delete mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/__init__.py delete mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py rename platform/broadcom/sonic-platform-modules-juniper/{qfx5210 => }/setup.py (57%) rename platform/broadcom/sonic-platform-modules-juniper/{qfx5200 => }/sonic_platform/__init__.py (100%) rename platform/broadcom/sonic-platform-modules-juniper/{qfx5210 => }/sonic_platform/chassis.py (54%) rename platform/broadcom/sonic-platform-modules-juniper/{qfx5200 => }/sonic_platform/platform.py (73%) diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json b/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json old mode 100755 new mode 100644 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/eeprom.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/eeprom.py old mode 100755 new mode 100644 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/led_control.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/led_control.py old mode 100755 new mode 100644 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/psuutil.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/psuutil.py old mode 100755 new mode 100644 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py old mode 100755 new mode 100644 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py old mode 100755 new mode 100644 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py old mode 100755 new mode 100644 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/led_proc_init.soc b/device/juniper/x86_64-juniper_qfx5210-r0/led_proc_init.soc old mode 100755 new mode 100644 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py old mode 100755 new mode 100644 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/qfx5210_eeprom_data.py b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/qfx5210_eeprom_data.py new file mode 100644 index 000000000000..973a2abe492b --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/qfx5210_eeprom_data.py @@ -0,0 +1,331 @@ +#!/usr/bin/env python +# +# Name: juniper_qfx5210_eepromconv.py version: 1.0 +# +# Description: This file contains the code to store the contents of Board EEPROM in file +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +import os +import commands +import binascii +from sonic_eeprom import eeprom_tlvinfo + +def main(): + eeprom_qfx5210 = Eeprom() + + FANTYPE_PATH = '/sys/bus/i2c/devices/17-0068/fan1_direction' + isPlatformAFO = False + try: + fan_type_file = open(FANTYPE_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + fan_type = -1 + else: + fan_type = fan_type_file.read() + fan_type_file.close() + + if (int(fan_type) == -1 or int(fan_type) == 0): + if (int(fan_type) == -1): + print "unable to open sys file for fan handling, defaulting it to AFO" + + isPlatformAFO = True + else: + isPlatformAFO = False + + # creating the "/var/run/eeprom" file and storing values of CPU board EEPROM in this file. + eeprom_file = open ("/var/run/eeprom", "a+") + eeprom_file.write("\n") + if isPlatformAFO == True: + eeprom_file.write("Fan Type=AFO\r\n") + else: + eeprom_file.write("Fan Type=AFI\r\n") + eeprom_file.write("\n") + + # Write the contents of CPU Board EEPROM to file + eeprom_file.write("CPU Board EEPROM (0x56)\r\n") + eeprom_file.write("===============================\r\n") + eeprom_file.write("Product Name=%s\r\n" % eeprom_qfx5210.modelstr()) + eeprom_file.write("Part Number=%s\r\n" % eeprom_qfx5210.part_number_str()) + eeprom_file.write("Serial Number=%s\r\n" % eeprom_qfx5210.serial_number_str()) + eeprom_file.write("MAC Address=%s\r\n" % eeprom_qfx5210.base_mac_address()) + eeprom_file.write("Manufacture Date=%s\r\n" % eeprom_qfx5210.manuDate_str()) + eeprom_file.write("Platform Name=%s\r\n" % eeprom_qfx5210.platform_str()) + eeprom_file.write("Number of MAC Addresses=%s\r\n" % eeprom_qfx5210.MACsize_str()) + eeprom_file.write("Vendor Name=%s\r\n" % eeprom_qfx5210.vendor_name_str()) + eeprom_file.write("Manufacture Name=%s\r\n" % eeprom_qfx5210.manufacture_name_str()) + + CPUeepromFileCmd = 'cat /sys/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0056/eeprom > /etc/init.d/eeprom_qfx5210_ascii' + # Write the contents of CPU EEPROM to file + try: + os.system(CPUeepromFileCmd) + except OSError: + print 'Error: Execution of "%s" failed', CPUeepromFileCmd + return False + + eeprom_ascii = '/etc/init.d/eeprom_qfx5210_ascii' + # Read file contents in Hex format + with open(eeprom_ascii, 'rb') as Hexformat: + content = Hexformat.read() + Hexformatoutput = binascii.hexlify(content) + + eeprom_hex = '/etc/init.d/eeprom_qfx5210_hex' + with open(eeprom_hex, 'wb+') as Hexfile: + Hexfile.write(Hexformatoutput) + + #Write contents of CPU EEPROM to new file in hexa format + with open(eeprom_hex, 'rb') as eeprom_hexfile: + eeprom_hexfile.seek(350, 0) + vendorext_read = eeprom_hexfile.read(124) + vendorext="" + vendorext += "0x" + vendorext_read[0:2] + for i in range(2,124,2): + vendorext += " 0x" + vendorext_read[i:i+2] + eeprom_file.write("Vendor Extension=%s\r\n" % str(vendorext)) + + eeprom_hexfile.seek(350, 0) + IANA_read = eeprom_hexfile.read(8) + IANAName = binascii.unhexlify(IANA_read) + eeprom_file.write("IANA=%s\r\n" % str(IANAName)) + + eeprom_hexfile.seek(358, 0) + ASMpartrev_read = eeprom_hexfile.read(4) + ASMpartrev = binascii.unhexlify(ASMpartrev_read) + eeprom_file.write("Assembly Part Number Rev=%s\r\n" % str(ASMpartrev)) + + eeprom_hexfile.seek(374, 0) + ASMpartnum_read = eeprom_hexfile.read(20) + ASMpartnum_read = binascii.unhexlify(ASMpartnum_read) + eeprom_file.write("Assembly Part Number=%s\r\n" % str(ASMpartnum_read)) + + eeprom_hexfile.seek(402, 0) + ASMID_read = eeprom_hexfile.read(4) + ASMID_read_upper = ASMID_read.upper() + eeprom_file.write("Assembly ID=0x%s\r\n" % str(ASMID_read_upper)) + + ASMHWMajRev_position = eeprom_hexfile.seek(410, 0) + ASMHWMajRev_read = eeprom_hexfile.read(2) + eeprom_file.write("Assembly Major Revision=0x%s\r\n" % str(ASMHWMajRev_read)) + + eeprom_hexfile.seek(416, 0) + ASMHWMinRev_read = eeprom_hexfile.read(2) + eeprom_file.write("Assembly Minor Revision=0x%s\r\n" % str(ASMHWMinRev_read)) + + eeprom_hexfile.seek(422, 0) + Deviation_read = eeprom_hexfile.read(28) + Deviation_read_upper = Deviation_read.upper() + eeprom_file.write("Deviation=0x%s\r\n" % str(Deviation_read_upper)) + + eeprom_hexfile.seek(450, 0) + CLEI_read = eeprom_hexfile.read(20) + CLEI_name = binascii.unhexlify(CLEI_read) + eeprom_file.write("CLEI code=%s\r\n" % str(CLEI_name)) + + eeprom_dict = eeprom_qfx5210.system_eeprom_info() + key = '0x29' + if key in eeprom_dict.keys(): + onie_version_str = eeprom_dict.get('0x29', None) + else: + onie_version_str = "N/A" + eeprom_file.write("ONIE Version=%s\r\n" % onie_version_str) + + crc_str = eeprom_dict.get('0xFE', None) + eeprom_file.write("CRC=%s\r\n" % crc_str) + eeprom_file.close() + return True + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + def __init__(self): + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom" + super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True) + self.__eeprom_tlv_dict = dict() + try: + self.__eeprom_data = self.read_eeprom() + except: + self.__eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.__eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + ord(eeprom[tlv_index + 1])] + code = "0x%02X" % (ord(tlv[0])) + + if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | + (ord(tlv[4]) << 8) | ord(tlv[5])) + value += str(tlv[6:6 + ord(tlv[1])]) + else: + name, value = self.decoder(None, tlv) + + self.__eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+1]) + 2 + + def serial_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2] + + def base_mac_address(self): + (is_valid, t) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(self.__eeprom_data) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def serial_tag_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2] + + def revision_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2] + + def manuDate_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MANUF_DATE) + if not is_valid: + return "N/A" + + return results[2] + + def platform_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PLATFORM_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def MACsize_str(self): + (is_valid, t) = self.get_tlv_field(self.__eeprom_data, self._TLV_CODE_MAC_SIZE) + + if not is_valid: + return "N/A" + + return str((ord(t[2][0]) << 8) | ord(t[2][1])) + + def vendor_name_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_VENDOR_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def manufacture_name_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MANUF_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def onie_version_str(self): + value = "" + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_ONIE_VERSION) + if not is_valid: + return "N/A" + + for c in results[2:2 + ord(results[1])]: + value += "0x%02X " % (ord(c),) + + return value + + def vendor_ext_str(self): + + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_VENDOR_EXT) + + if not is_valid: + return "N/A" + + vendor_value_formatted = ''.join( [ " 0x" + "%02X " % ord( x ) for x in results[2] ] ).strip() + vendor_value_hexvalue = ''.join( ["%02X" % ord( x ) for x in results[2] ] ).strip() + + return vendor_value_formatted, vendor_value_hexvalue + + def crc_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_CRC_32) + if not is_valid: + return "N/A" + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.__eeprom_tlv_dict + +if __name__ == "__main__": + main() diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json b/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json index 94592fa8cebc..a3ecea34bcc9 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json +++ b/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { + "skip_thermalctld": true, "skip_ledd": true } diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/gpio-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/gpio-tmc.c new file mode 100644 index 000000000000..7b02e8a5bc74 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/modules/gpio-tmc.c @@ -0,0 +1,661 @@ +/* + * Juniper Networks TMC GPIO driver + * + * Copyright (C) 2020 Juniper Networks + * Author: Ashish Bhensdadia + * + * This driver implement the GPIO set/get functionality + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jnx-tmc.h" + +#define TMC_GPIO_MAX_BITS_PER_REG 16 +#define TMC_GPIO_SFP_MAX_BITS_PER_REG 2 +#define TMC_GPIO_PTPCFG_MAX_BITS_PER_REG 8 + +#define TMC_GPIO_FIND_GROUP(gpio) \ + ((gpio) / TMC_GPIO_MAX_BITS_PER_REG) +#define TMC_GPIO_FIND_GPIO(gpio) \ + ((gpio) % TMC_GPIO_MAX_BITS_PER_REG) + +#define TMC_GPIO_SFP_FIND_GROUP(gpio) \ + ((gpio) / TMC_GPIO_SFP_MAX_BITS_PER_REG) +#define TMC_GPIO_SFP_FIND_GPIO(gpio) \ + ((gpio) % TMC_GPIO_SFP_MAX_BITS_PER_REG) + +#define TMC_GPIO_PTPCFG_FIND_GPIO(gpio) \ + ((gpio) % TMC_GPIO_PTPCFG_MAX_BITS_PER_REG) + +#define TMC_GPIO_MAX_NGPIO_PER_GROUP 320 + +#define TMC_PFE_QSFP_RESET_OFFSET 0x4 +#define TMC_PFE_QSFP_PRESENT_OFFSET 0x8 +#define TMC_PFE_QSFP_PHY_RESET_OFFSET 0x10 +#define TMC_PFE_QSFP_LPMOD_OFFSET 0x78 +#define TMC_PFE_QSFP_LED_CTRL_OFFSET 0x20 + +#define TMC_PFE_LANES_GREEN_LED_VALUE 0x3 +#define TMC_PFE_LANE0_GREEN_LED_BIT_POSITION 0 +#define TMC_PFE_LANE1_GREEN_LED_BIT_POSITION 2 +#define TMC_PFE_LANE2_GREEN_LED_BIT_POSITION 4 +#define TMC_PFE_LANE3_GREEN_LED_BIT_POSITION 6 + +#define TMC_PFE_LANES_BEACON_LED_VALUE 0x2 +#define TMC_PFE_LANE0_BEACON_LED_BIT_POSITION 0 +#define TMC_PFE_LANE1_BEACON_LED_BIT_POSITION 2 +#define TMC_PFE_LANE2_BEACON_LED_BIT_POSITION 4 +#define TMC_PFE_LANE3_BEACON_LED_BIT_POSITION 6 + +#define TMC_PFE_LANES_FAULT_LED_VALUE 0x1 +#define TMC_PFE_LANE0_FAULT_LED_BIT_POSITION 0 +#define TMC_PFE_LANE1_FAULT_LED_BIT_POSITION 2 +#define TMC_PFE_LANE2_FAULT_LED_BIT_POSITION 4 +#define TMC_PFE_LANE3_FAULT_LED_BIT_POSITION 6 + +#define TMC_PFE_SFPSB0_TX_DISABLE_OFFSET 0x0 +#define TMC_PFE_SFPSB0_LED_CTRL_OFFSET 0xC +#define TMC_PFE_SFPSB0_LED_ACTIVITY_OFFSET 0x14 +#define TMC_PFE_SFPSB0_PRESENT_OFFSET 0x18 +#define TMC_PFE_SFPSB0_LOSS_OFFSET 0x1C +#define TMC_PFE_SFPSB0_TX_FAULT_OFFSET 0x20 + +#define TMC_PFE_SFPSB1_TX_DISABLE_OFFSET 0x0 +#define TMC_PFE_SFPSB1_LED_CTRL_OFFSET 0x8 +#define TMC_PFE_SFPSB1_LED_ACTIVITY_OFFSET 0x10 +#define TMC_PFE_SFPSB1_PRESENT_OFFSET 0x14 +#define TMC_PFE_SFPSB1_LOSS_OFFSET 0x18 +#define TMC_PFE_SFPSB1_TX_FAULT_OFFSET 0x1C + +/* + * Index 4 to 15 is used for QSFP starting with + * QSFP_LED_LANE0_GREEN. To keep multibit set/get common + * starting SFP_LED_LANE0_GREEN with 16 which will avoid + * conflict with QSFP enums. + */ +#define SFP_LED_OP_START_INDEX 16 + +/* + * Used for off-setting SFP led op index + */ +#define SFP_LED_OP_OFFSET 0xB + +/* + * SFP slave blocks + */ +#define SFP_SLAVE0_BLOCK 0x1 +#define SFP_SLAVE1_BLOCK 0x2 + +/* + * each group represent the 16 gpios. + * QSFP_RST - QSFP_LPMODE + * each bit represent the one gpio + * exemple: bits[0:15] - bit0 - gpio0 + * QSFP_LED_LANE0_GREEN - QSFP_LED_LANE3_FAULT + * here, number represent the one gpio + * exemple: bits[0:1] + * 00 - gpio off, 01 - gpio on [ gpio0] + * 00 - gpio off, 10 - gpio on [ gpio1] + * 00 - gpio off, 11 - gpio on [ gpio2] + * + */ +enum { + QSFP_RST, + QSFP_PRESENT, + QSFP_PHY_RST, + QSFP_LPMOD, + QSFP_LED_LANE0_GREEN, + QSFP_LED_LANE1_GREEN, + QSFP_LED_LANE2_GREEN, + QSFP_LED_LANE3_GREEN, + QSFP_LED_LANE0_BEACON, + QSFP_LED_LANE1_BEACON, + QSFP_LED_LANE2_BEACON, + QSFP_LED_LANE3_BEACON, + QSFP_LED_LANE0_FAULT, + QSFP_LED_LANE1_FAULT, + QSFP_LED_LANE2_FAULT, + QSFP_LED_LANE3_FAULT, + TMC_PFE_GPIO_GROUP_MAX +}; + +enum sfp_op { + SFP_TX_DISABLE, + SFP_LED_ACTIVITY, + SFP_PRESENT, + SFP_SFP_LOS, + SFP_TX_FAULT, + SFP_LED_LANE0_GREEN = SFP_LED_OP_START_INDEX, + SFP_LED_LANE1_GREEN, + SFP_LED_LANE2_GREEN, + SFP_LED_LANE3_GREEN, + SFP_LED_LANE0_BEACON, + SFP_LED_LANE1_BEACON, + SFP_LED_LANE2_BEACON, + SFP_LED_LANE3_BEACON, + SFP_LED_LANE0_FAULT, + SFP_LED_LANE1_FAULT, + SFP_LED_LANE2_FAULT, + SFP_LED_LANE3_FAULT, + TMC_PFE_SFP_GPIO_GROUP_MAX +}; + +static const u32 group_offset[TMC_PFE_GPIO_GROUP_MAX] = { + TMC_PFE_QSFP_RESET_OFFSET, + TMC_PFE_QSFP_PRESENT_OFFSET, + TMC_PFE_QSFP_PHY_RESET_OFFSET, + TMC_PFE_QSFP_LPMOD_OFFSET, + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 FAULT */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 FAULT */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 FAULT */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 FAULT */ +}; + +static const u32 sfp_slaveb0_group_offset[TMC_PFE_SFP_GPIO_GROUP_MAX] = { + TMC_PFE_SFPSB0_TX_DISABLE_OFFSET, + TMC_PFE_SFPSB0_LED_ACTIVITY_OFFSET, + TMC_PFE_SFPSB0_PRESENT_OFFSET, + TMC_PFE_SFPSB0_LOSS_OFFSET, + TMC_PFE_SFPSB0_TX_FAULT_OFFSET, + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 FAULT */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 FAULT */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 FAULT */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 FAULT */ +}; + +static const u32 sfp_slaveb1_group_offset[TMC_PFE_SFP_GPIO_GROUP_MAX] = { + TMC_PFE_SFPSB1_TX_DISABLE_OFFSET, + TMC_PFE_SFPSB1_LED_ACTIVITY_OFFSET, + TMC_PFE_SFPSB1_PRESENT_OFFSET, + TMC_PFE_SFPSB1_LOSS_OFFSET, + TMC_PFE_SFPSB1_TX_FAULT_OFFSET, + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 FAULT */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 FAULT */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 FAULT */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 FAULT */ +}; + +struct tmc_gpio_info { + int (*get)(struct gpio_chip *, unsigned int); + void (*set)(struct gpio_chip *, unsigned int, int); + int (*dirin)(struct gpio_chip *, unsigned int); + int (*dirout)(struct gpio_chip *, unsigned int, int); +}; + +struct tmc_gpio_chip { + const struct tmc_gpio_info *info; + void __iomem *base; + struct device *dev; + struct gpio_chip gpio; + int ngpio; + spinlock_t gpio_lock; /* gpio lock */ + int sfp_slave_block; +}; + +/* slave gpio max */ +static int gpio_max = 320; +module_param(gpio_max, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(gpio_max, "Maximum number of gpio for SLAVE TMC GPIO"); + +/* + * generic bit operation functions + */ +static u32 tmc_gpio_reset_bits(u32 state, u32 val, u32 shift) +{ + state &= ~(val << shift); + return state; +}; + +static u32 tmc_gpio_set_bits(u32 state, u32 val, u32 shift) +{ + state |= (val << shift); + return state; +}; + +static u32 tmc_gpio_find_bits_val(u32 state, u32 shift, u32 mask) +{ + return ((state >> shift)) & mask; +}; + +#define to_tmc_chip(chip) \ + container_of((chip), struct tmc_gpio_chip, gpio) + +/* + * tmc_gpio_multiple_bitsop - Generic TMC GPIO multiple bits operation + */ +static void tmc_gpio_multiple_bitsop(struct tmc_gpio_chip *chip, + unsigned int gpiono, u32 group, u32 offset, bool set) +{ + u32 gpio_state, led_val, bit_shift; + unsigned long flags; + void __iomem *iobase; + + iobase = chip->base + offset; + + dev_dbg(chip->dev, "TMC GPIO multiple bitop group=%u, " + "gpiono=%u, offet:=%u, set=%u\n", group, gpiono, offset, set); + + spin_lock_irqsave(&chip->gpio_lock, flags); + + switch (group) { + case QSFP_LED_LANE0_GREEN: + case SFP_LED_LANE0_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE0_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE1_GREEN: + case SFP_LED_LANE1_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE1_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE2_GREEN: + case SFP_LED_LANE2_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE2_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE3_GREEN: + case SFP_LED_LANE3_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE3_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE0_BEACON: + case SFP_LED_LANE0_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE0_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE1_BEACON: + case SFP_LED_LANE1_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE1_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE2_BEACON: + case SFP_LED_LANE2_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE2_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE3_BEACON: + case SFP_LED_LANE3_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE3_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE0_FAULT: + case SFP_LED_LANE0_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE0_FAULT_LED_BIT_POSITION; + break; + case QSFP_LED_LANE1_FAULT: + case SFP_LED_LANE1_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE1_FAULT_LED_BIT_POSITION; + break; + case QSFP_LED_LANE2_FAULT: + case SFP_LED_LANE2_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE2_FAULT_LED_BIT_POSITION; + break; + case QSFP_LED_LANE3_FAULT: + case SFP_LED_LANE3_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE3_FAULT_LED_BIT_POSITION; + break; + + default: + spin_unlock_irqrestore(&chip->gpio_lock, flags); + return; + } + + if (set) { + gpio_state = tmc_gpio_reset_bits(gpio_state, 0x3, bit_shift); + gpio_state = tmc_gpio_set_bits(gpio_state, led_val, bit_shift); + } else { + gpio_state = tmc_gpio_reset_bits(gpio_state, 0x3, bit_shift); + } + + iowrite32(gpio_state, (iobase+(0x004*gpiono))); + + spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return; +}; + +/* + * tmc_gpio_one_bitop - Generic TMC GPIO single bit operation + */ +static void tmc_gpio_one_bitop(struct tmc_gpio_chip *chip, + unsigned int bit, u32 offset, bool set) +{ + u32 gpio_state; + unsigned long flags; + void __iomem *iobase; + + iobase = chip->base + offset; + + dev_dbg(chip->dev, "TMC GPIO one bitop bit=%u, offset=%x, " + "set=%u\n", bit, offset, set); + + spin_lock_irqsave(&chip->gpio_lock, flags); + + gpio_state = ioread32(iobase); + if (set) + gpio_state |= BIT(bit); + else + gpio_state &= ~BIT(bit); + + iowrite32(gpio_state, iobase); + + spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return; +} + +/* + * tmc_gpio_get_multiple_bitsop - Generic TMC get GPIO multiple bits operation + */ +static int tmc_gpio_get_multiple_bitsop(struct tmc_gpio_chip *chip, + unsigned int gpiono, u32 group, u32 offset) +{ + u32 gpio_state; + void __iomem *iobase; + + iobase = chip->base + offset; + + dev_dbg(chip->dev, "TMC GPIO get multiple bitsop group=%u, " + "gpiono=%u, offset=%u\n", group, gpiono, offset); + + switch (group) { + case QSFP_LED_LANE0_GREEN: + case SFP_LED_LANE0_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE0_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE1_GREEN: + case SFP_LED_LANE1_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE1_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE2_GREEN: + case SFP_LED_LANE2_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE2_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE3_GREEN: + case SFP_LED_LANE3_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE3_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE0_BEACON: + case SFP_LED_LANE0_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE0_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE1_BEACON: + case SFP_LED_LANE1_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE1_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE2_BEACON: + case SFP_LED_LANE2_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE2_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE3_BEACON: + case SFP_LED_LANE3_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE3_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE0_FAULT: + case SFP_LED_LANE0_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE0_FAULT_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE1_FAULT: + case SFP_LED_LANE1_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE1_FAULT_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE2_FAULT: + case SFP_LED_LANE2_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE2_FAULT_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE3_FAULT: + case SFP_LED_LANE3_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE3_FAULT_LED_BIT_POSITION, 0x3)); + default: + return 0; + } +}; + +/* + * tmc_gpio_get - Read the specified signal of the GPIO device. + */ +static int tmc_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct tmc_gpio_chip *chip = to_tmc_chip(gc); + unsigned int group = TMC_GPIO_FIND_GROUP(gpio); + unsigned int bit = TMC_GPIO_FIND_GPIO(gpio); + + if (group >= TMC_PFE_GPIO_GROUP_MAX) + return 0; + + switch (group) { + case QSFP_RST: + case QSFP_PRESENT: + case QSFP_PHY_RST: + case QSFP_LPMOD: + dev_dbg(chip->dev, "TMC GPIO get one bitop group=%u, gpio=%u, " + "bit=%u\n", group, gpio, bit); + return !!(ioread32(chip->base + group_offset[group]) + & BIT(bit)); + default: + return tmc_gpio_get_multiple_bitsop(chip, bit, group, group_offset[group]); + } +} + +/* + * tmc_gpio_set - Write the specified signal of the GPIO device. + */ +static void tmc_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct tmc_gpio_chip *chip = to_tmc_chip(gc); + unsigned int group = TMC_GPIO_FIND_GROUP(gpio); + unsigned int bit = TMC_GPIO_FIND_GPIO(gpio); + + if (group >= TMC_PFE_GPIO_GROUP_MAX) + return; + + switch (group) { + case QSFP_RST: + case QSFP_PRESENT: + case QSFP_PHY_RST: + case QSFP_LPMOD: + dev_dbg(chip->dev, "TMC GPIO one bitop group=%d\n", group); + tmc_gpio_one_bitop(chip, bit, group_offset[group], val); + break; + default: + tmc_gpio_multiple_bitsop(chip, bit, group, group_offset[group], val); + break; + } +} + +static struct tmc_gpio_info tmc_gpios[] = { + { + .get = tmc_gpio_get, + .set = tmc_gpio_set, + }, +}; + +static void tmc_gpio_setup(struct tmc_gpio_chip *sgc, int id) +{ + struct gpio_chip *chip = &sgc->gpio; + const struct tmc_gpio_info *info = sgc->info; + + chip->get = info->get; + chip->set = info->set; + chip->direction_input = info->dirin; + chip->direction_output = info->dirout; + chip->dbg_show = NULL; + chip->can_sleep = 0; + + if (id == 0) { + chip->base = 0; + } else if (id == 1) { + chip->base = (gpio_max * id); + } else { + chip->base = -1; + } + + chip->ngpio = sgc->ngpio; + chip->label = dev_name(sgc->dev); + chip->parent = sgc->dev; + chip->owner = THIS_MODULE; +} + +static int tmc_gpio_of_init(struct device *dev, + struct tmc_gpio_chip *chip) +{ + chip->info = &tmc_gpios[0]; + chip->ngpio = gpio_max; + + return 0; +} + +static int tmc_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tmc_gpio_chip *chip; + struct resource *res; + int ret; + + const struct mfd_cell *cell = mfd_get_cell(pdev); + + dev_dbg(dev, "TMC GPIO probe\n"); + + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + dev_info(dev, "TMC GPIO resource 0x%llx, %llu\n", + res->start, resource_size(res)); + + chip->base = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!chip->base) + return -ENOMEM; + + ret = tmc_gpio_of_init(dev, chip); + if (ret) + return ret; + + chip->dev = dev; + spin_lock_init(&chip->gpio_lock); + + tmc_gpio_setup(chip, cell->id); + + ret = gpiochip_add(&chip->gpio); + if (ret) { + dev_err(dev, + "Failed to register TMC gpiochip : %d\n", ret); + return ret; + } + + platform_set_drvdata(pdev, chip); + dev_info(dev, "TMC GPIO registered at 0x%lx, gpiobase: %d\n", + (long unsigned)chip->base, chip->gpio.base); + + return 0; +} + +static int tmc_gpio_remove(struct platform_device *pdev) +{ + struct tmc_gpio_chip *chip = platform_get_drvdata(pdev); + + gpiochip_remove(&chip->gpio); + + return 0; +} + +static struct platform_driver tmc_gpio_driver = { + .driver = { + .name = "gpioslave-tmc", + .owner = THIS_MODULE, + }, + .probe = tmc_gpio_probe, + .remove = tmc_gpio_remove, +}; + +module_platform_driver(tmc_gpio_driver); + +MODULE_DESCRIPTION("Juniper Networks TMC FPGA GPIO driver"); +MODULE_AUTHOR("Ashish Bhensdadia "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/i2c-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/i2c-tmc.c new file mode 100644 index 000000000000..afd0311dc130 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/modules/i2c-tmc.c @@ -0,0 +1,1107 @@ +/* + * Juniper Networks TMC I2C Accelerator driver + * + * Copyright (C) 2020 Juniper Networks + * Author: Ashish Bhensdadia + * + * This driver implement the I2C functionality + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jnx-tmc.h" + + +#define TMC_I2C_MASTER_I2C_SCAN_RESET_BIT BIT(31) + +#define TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET 0x0 +#define TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET 0x10 + +#define TMC_I2C_MSTR_AUTOMATION_I2C(adap, offset) \ + ((adap)->membase + offset) + +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0 0x0 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8 0x8 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4 0x4 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C 0xC +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10 0x10 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14 0x14 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18 0x18 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C 0x1C +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_20 0x20 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_24 0x24 + +#define TMC_I2C_MSTR_I2C_DPMEM(adap, offset) \ + ((adap)->dpmbase + offset) + +#define TMC_I2C_TRANS_LEN 2 +#define tmc_iowrite(val, addr) iowrite32((val), (addr)) + +#define TMC_I2C_CTRL_GROUP(g) (((g) & 0xFF) << 8) +#define TMC_I2C_CTRL_WRCNT(w) (((w) & 0x3F) << 16) +#define TMC_I2C_CTRL_RDCNT(r) (((r) & 0x3F) << 16) +#define TMC_I2C_CTRL_DEVADDR(d) (((d) & 0xFF) << 8) +#define TMC_I2C_CTRL_OFFSET(o) ((o) & 0xFF) + + +#define TMC_I2C_MEM_CTRL_VLD BIT(31) + +#define TMC_I2C_CTRL_ERR(s) ((s) & 0x0F000000) +#define TMC_I2C_CTRL_DONE_BIT(s) ((s) & BIT(31)) +#define TMC_I2C_CTRL_STATUS_OK(s) (TMC_I2C_CTRL_DONE_BIT(s) & \ + TMC_I2C_CTRL_ERR(s)) +#define TMC_I2C_CTRL_DONE(s) (TMC_I2C_CTRL_DONE_BIT(s) == BIT(31)) + +#define TMC_I2C_STAT_INC(adap, s) (((adap)->stat.s)++) +#define TMC_I2C_STAT_INCN(adap, s, n) (((adap)->stat.s) += (n)) +#define TMC_I2C_GET_MASTER(tadap) ((tadap)->tctrl) + +#define TMC_I2C_READ 0x1 +#define TMC_I2C_WRITE 0x2 + +#define TMC_I2C_MASTER_LOCK(s, flags) \ +do { \ + spin_lock_irqsave(&(s)->lock, flags); \ +} while (0) + +#define TMC_I2C_MASTER_UNLOCK(s, flags) \ +do { \ + spin_unlock_irqrestore(&(s)->lock, flags); \ +} while (0) + +#define tmc_i2c_dbg(dev, fmt, args...) \ +do { \ + if (tmc_i2c_debug >= 1) \ + dev_err(dev, fmt, ## args); \ +} while (0) + + +/* pfe TMC i2c channel */ +static int pfe_channel = 32; +module_param(pfe_channel, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(pfe_channel, "Maximum number of channel for PFE TMC"); + +/* chassid TMC i2c channel */ +static int chd_channel = 11; +module_param(chd_channel, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(chd_channel, "Maximum number of channel for CHASSID TMC"); + +static u32 wr_index_to_oper[] = {0x01000000, 0x02000000, + 0x84000000, 0x85000000, 0x83000000}; +static u32 rd_index_to_oper[] = {0x08000000, 0x09000000, 0x0A000000, + 0x8B000000, 0x8C000000, 0x8D000000, 0x83000000}; + +struct tmc_i2c_adapter_stats { + u32 abort; + u32 go; + u32 mstr_rdy; + u32 mstr_busy; + u32 trans_compl; + u32 msg_cnt; + u32 rd_cnt; + u32 wr_cnt; + u32 byte_cnt; + u32 slave_timeo; + u32 scl_bus_loss; + u32 sda_bus_loss; + u32 ack_ptimeo; + u32 rd_cnt_0; + u32 rd_cnt_gt32; + u32 rst_tgt; + u32 rst_mstr; +}; + +struct tmc_i2c_adapter { + void __iomem *membase; + void __iomem *dpmbase; + struct i2c_adapter adap; + struct i2c_mux_core *muxc; + struct tmc_i2c_ctrl *tctrl; + int mux_channels; + int mux_select; + u32 i2c_delay; + int entries; + int master; + u32 control; + u32 speed; + bool done; + bool polling; + bool use_block; + wait_queue_head_t wait; + struct tmc_i2c_adapter_stats stat; +}; + +struct tmc_i2c_ctrl { + void __iomem *membase; + void __iomem *dpmbase; + struct i2c_adapter **adap; + struct device *dev; + int num_masters; + int mux_channels; + u32 i2c_delay; + u32 master_mask; + spinlock_t lock; /* master lock */ +}; + +/* + * Reset the Tmc I2C master + */ +static void tmc_i2c_reset_master(struct i2c_adapter *adap) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct tmc_i2c_ctrl *tmc = TMC_I2C_GET_MASTER(tadap); + u32 val, master = tadap->master; + unsigned long flags; + void __iomem *addr; + + dev_warn(&adap->dev, "Re-setting i2c master: %d\n", master); + + TMC_I2C_MASTER_LOCK(tmc, flags); + + addr = tmc->membase + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET; + val = ioread32(addr); + tmc_iowrite(val | (TMC_I2C_MASTER_I2C_SCAN_RESET_BIT), addr); + tmc_iowrite(val & ~(TMC_I2C_MASTER_I2C_SCAN_RESET_BIT), addr); + TMC_I2C_STAT_INC(tadap, rst_mstr); + + TMC_I2C_MASTER_UNLOCK(tmc, flags); +} + +/* + * check if the Tmc I2C master is ready + */ +static int tmc_i2c_mstr_wait_rdy(struct i2c_adapter *adap, u8 rw, u32 delay) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + unsigned long timeout; + u32 val; + + val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + if (val) { + tmc_iowrite(0x80000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + mdelay(5); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + } else { + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + } + + if ((rw == TMC_I2C_READ) && (delay)) { + tmc_iowrite(0x80000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + return 0; + } + + timeout = jiffies + adap->timeout; + do { + val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + if (!val) + return 0; + + if (tadap->polling) { + usleep_range(50, 100); + } else { + tadap->done = false; + wait_event_timeout(tadap->wait, tadap->done, + adap->timeout); + } + } while (time_before(jiffies, timeout)); + + TMC_I2C_STAT_INC(tadap, mstr_busy); + + return -EBUSY; +} + +/* + * Wait for master completion + */ +static u32 tmc_i2c_mstr_wait_completion(struct i2c_adapter *adap, + u32 dp_entry_offset) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + u32 val; + + if (tadap->polling) { + /* Poll for the results */ + unsigned long timeout = jiffies + adap->timeout; + + do { + usleep_range(1000, 1200); + val = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + dp_entry_offset)); + if (TMC_I2C_CTRL_DONE(val)) + break; + } while (time_before(jiffies, timeout)); + } else { + wait_event_timeout(tadap->wait, tadap->done, adap->timeout); + val = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + dp_entry_offset)); + } + + return TMC_I2C_CTRL_STATUS_OK(val); +} + +/* + * TMC I2C delay read/write operation + */ +static int tmc_i2c_delay_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u32 delay, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int err, n; + u32 control = 0, data = 0; + u32 val; + + err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); + if (err < 0) { + tmc_i2c_reset_master(adap); + return err; + } + + TMC_I2C_STAT_INC(tadap, mstr_rdy); + + /* initialize the start address and mux */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); + + tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); + tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); + + /* populate delay */ + if (delay) { + if (delay > 1000) { + delay = delay/1000; + delay |= (1 << 16); + } + } + tmc_iowrite(delay, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + tmc_iowrite(0x86000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); + + /* prepare control command */ + control |= TMC_I2C_CTRL_DEVADDR(addr); + control |= TMC_I2C_CTRL_OFFSET(offset); + + if (rw == TMC_I2C_WRITE) { + for (n = 0; n < len; n++) + data |= (buf[n] << ((len - 1 - n) * 8)); + tmc_iowrite(data, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + control |= TMC_I2C_CTRL_WRCNT(len); + control |= wr_index_to_oper[len-1]; + dev_dbg(dev, "WR Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + + } else { + /* read */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + control |= TMC_I2C_CTRL_RDCNT(len); + control |= rd_index_to_oper[len-1]; + } + + /* + * valid this transaction as well + */ + control |= TMC_I2C_MEM_CTRL_VLD; + + tadap->control = control; + + /* + * operation control command + */ + tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); + + /* + * End commands + */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); + tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_20)); + tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_24)); + + dev_dbg(dev, "Control (%#x): RD_WR_TYPE:%#02x, RD_WR_LEN:%d," + "Addr:%#01x, Offset:%#02x\n", control, + ((control >> 24) & 0x3F), ((control >> 16) & 0x3F), + ((control >> 8) & 0xff), ((control) & 0xff)); + + tadap->done = false; + + /* fire the transaction */ + tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + TMC_I2C_STAT_INC(tadap, go); + + val = tmc_i2c_mstr_wait_completion(adap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10); + if (val) { + dev_err(&adap->dev, + "i2c transaction error (0x%08x)\n", val); + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + return -EIO; + } + + /* + * read a word of data + */ + if (rw == TMC_I2C_READ) { + data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + for (n = 0; n < len; n++) + buf[n] = (data >> (n * 8)) & 0xff; + + dev_dbg(dev, "RD Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + + TMC_I2C_STAT_INC(tadap, rd_cnt); + } else { + /* write */ + TMC_I2C_STAT_INC(tadap, wr_cnt); + } + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + return 0; + +} + +/* + *TMC I2C none delay Read/write opertion + */ +static int tmc_i2c_none_delay_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int err, n; + u32 control = 0, data = 0; + u32 val; + + err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); + if (err < 0) { + tmc_i2c_reset_master(adap); + return err; + } + + TMC_I2C_STAT_INC(tadap, mstr_rdy); + + /* initialize the start address and mux */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); + + tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); + tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); + + + /* prepare control command */ + control |= TMC_I2C_CTRL_DEVADDR(addr); + control |= TMC_I2C_CTRL_OFFSET(offset); + + if (rw == TMC_I2C_WRITE) { + for (n = 0; n < len; n++) + data |= (buf[n] << (n * 8)); + tmc_iowrite(data, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + control |= wr_index_to_oper[len-1]; + dev_dbg(dev, "WR Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + + } else { + /* read */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + control |= rd_index_to_oper[len-1]; + } + + /* + * valid this transaction as well + */ + control |= TMC_I2C_MEM_CTRL_VLD; + + tadap->control = control; + + /* + * operation control command + */ + tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); + + /* + * End commands + */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); + tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); + + dev_dbg(dev, "Control (%#x): RD_WR_TYPE:%#02x, RD_WR_LEN:%d," + "Addr:%#01x, Offset:%#02x\n", control, + ((control >> 24) & 0x3F), ((control >> 16) & 0x3F), + ((control >> 8) & 0xff), ((control) & 0xff)); + + tadap->done = false; + + /* fire the transaction */ + tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + TMC_I2C_STAT_INC(tadap, go); + + /* wait till transaction complete */ + val = tmc_i2c_mstr_wait_completion(adap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8); + if (val) { + dev_err(&adap->dev, + "i2c transaction error (0x%08x)\n", val); + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + return -EIO; + } + + /* + * read a word of data + */ + if (rw == TMC_I2C_READ) { + data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + for (n = 0; n < len; n++) + buf[n] = (data >> (n * 8)) & 0xff; + + dev_dbg(dev, "RD Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + TMC_I2C_STAT_INC(tadap, rd_cnt); + } else { + /* write */ + TMC_I2C_STAT_INC(tadap, wr_cnt); + } + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + return 0; +} + +/* + * TMC I2C read/write operation + */ +static int tmc_i2c_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + u32 i2c_delay = tadap->i2c_delay; + + if (i2c_delay) { + return tmc_i2c_delay_rw_op(adap, rw, mux, addr, offset, + len, i2c_delay, buf); + } else { + return tmc_i2c_none_delay_rw_op(adap, rw, mux, addr, offset, + len, buf); + } +} + +static int tmc_i2c_calc_entries(int msglen) +{ + int entries = msglen / TMC_I2C_TRANS_LEN; + + return (entries += (msglen % TMC_I2C_TRANS_LEN) ? 1 : 0); +} + +static int tmc_i2c_block_read(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int curmsg, entries, len; + int offset = 0; + struct i2c_msg *msg; + int err, n = 0; + u8 rwbuf[4] = {0}; + + dev_dbg(dev, "Read i2c Block\n"); + + for (curmsg = 0, offset = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + len = msg->len; + + if (msg->flags & I2C_M_RECV_LEN) + len = (I2C_SMBUS_BLOCK_MAX + 1); + + entries = tmc_i2c_calc_entries(len); + + if (msg->flags & I2C_M_RD) { + if (curmsg == 1 && ((msg->flags & I2C_M_RECV_LEN && + !(msgs[0].flags & I2C_M_RD)) || + (msg->len > TMC_I2C_TRANS_LEN))) { + offset = msgs[0].buf[0]; + } + + while (entries) { + err = tmc_i2c_rw_op(adap, TMC_I2C_READ, + tadap->mux_select, + msgs[0].addr, offset, + TMC_I2C_TRANS_LEN, rwbuf); + if (err < 0) + return err; + msg = &msgs[num - 1]; + msg->buf[n] = rwbuf[0]; + msg->buf[n+1] = rwbuf[1]; + n = n + TMC_I2C_TRANS_LEN; + offset = offset + TMC_I2C_TRANS_LEN; + entries--; + } + } + } + + return 0; +} + +/* + *TMC I2C SMB Read opertion + */ +static int tmc_i2c_smb_block_read_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + int err, i = 0; + u32 control = 0, data = 0; + u32 start_add; + + err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); + if (err < 0) { + tmc_i2c_reset_master(adap); + return err; + } + + TMC_I2C_STAT_INC(tadap, mstr_rdy); + + /* initialize the start address and mux */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); + + tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); + tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); + + + /* prepare control command */ + control |= TMC_I2C_CTRL_DEVADDR(addr); + control |= TMC_I2C_CTRL_OFFSET(offset); + + /* read */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + control |= TMC_I2C_CTRL_RDCNT(len);; + control |= rd_index_to_oper[6]; + + tadap->control = control; + + /* + * operation control command + */ + tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); + + /* + * End commands + */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); + tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); + + tadap->done = false; + + /* fire the transaction */ + tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + TMC_I2C_STAT_INC(tadap, go); + + /* + * read a block of data + */ + start_add = TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8; + while (len > 0) { + usleep_range(10000, 12000); + data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, start_add)); + buf[i] = data & 0xff; + buf[i + 1] = (data >> 8) & 0xff; + start_add = start_add + 8; + i = i + 2; + len = len - 2; + + TMC_I2C_STAT_INC(tadap, rd_cnt); + } + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + return 0; +} + +static int tmc_i2c_smb_block_read(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + int curmsg, len; + int offset = 0; + struct i2c_msg *msg; + int err, i = 0; + u8 rwbuf[32] = {0}; + + for (curmsg = 0, offset = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + len = msg->len; + + if (msg->flags & I2C_M_RECV_LEN) + len = (I2C_SMBUS_BLOCK_MAX + 1); + + if (msg->flags & I2C_M_RD) { + if ((curmsg == 1) && (msg->flags & I2C_M_RECV_LEN) && + !(msgs[0].flags & I2C_M_RD)) { + offset = msgs[0].buf[0]; + } + + err = tmc_i2c_smb_block_read_op(adap, TMC_I2C_READ, + tadap->mux_select, + msgs[0].addr, offset, + 32, rwbuf); + if (err < 0) { + return err; + } + msg = &msgs[num - 1]; + for (i = 0; i < len - 1; i++) { + msg->buf[i] = rwbuf[i]; + } + } + } + + return 0; +} + +static int tmc_i2c_mstr_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int n, curmsg, len = 0; + int err = 0; + struct i2c_msg *msg; + bool read; + u8 rwbuf[4] = {0}; + + dev_dbg(dev, "Num messages -> %d\n", num); + + /* + * Initialize all vars + */ + tadap->entries = 0; + tadap->use_block = false; + + for (curmsg = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + dev_dbg(dev, "[%02d] %d bytes, flag %#02x buf %#02x\n", + curmsg, msg->len, msg->flags, msg->buf[0]); + if ((msg->len > TMC_I2C_TRANS_LEN) || + ((msg->flags & I2C_M_RD) && + (msg->flags & I2C_M_RECV_LEN))) { + /* If PEC is enabled len will come as 3 for a word read. + * We don't want to use block read for this case. + */ + if ((msg->flags & I2C_CLIENT_PEC) && + (msg->len == TMC_I2C_TRANS_LEN+1)) { + tadap->use_block = false; + } else { + tadap->use_block = true; + } + break; + } + } + + if (tadap->use_block) { + /* Read Block */ + if ((msg->flags & I2C_M_RD) && (msg->flags & I2C_M_RECV_LEN)) { + err = tmc_i2c_smb_block_read(adap, msgs, num); + } else { + err = tmc_i2c_block_read(adap, msgs, num); + } + if (err < 0) + return err; + } else { + read = msgs[num - 1].flags & I2C_M_RD; + for (curmsg = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + len = msg->len; + + dev_dbg(dev, " [%02d] %s %d bytes addr %#02x, " + "flag %#02x, buf[0] %#02x\n", curmsg, + read ? "RD" : "WR", len, msg->addr, + msg->flags, msg->buf[0]); + + /* SMBus quick read/write command */ + if (len == 0 && curmsg == 0 && num == 1) { + if (read) { + len = 1; + } + break; + } + + if (curmsg == 0) { + if (!read) { + for (n = 1; n < len; n++) + rwbuf[n-1] = (msg->buf[n]); + len--; + } else { + /* read operation */ + continue; + } + } + } + + if (!read) { + /* write */ + err = tmc_i2c_rw_op(adap, TMC_I2C_WRITE, + tadap->mux_select, msgs[0].addr, + msgs[0].buf[0], len, rwbuf); + } else { + /* read */ + /* + * If PEC is enabled read only 2 bytes as expected in + * case of a word read instead of 3 to make it compatible + * with word write implementation. + */ + if (msg->flags & I2C_CLIENT_PEC && (len == TMC_I2C_TRANS_LEN + 1)) { + len--; + } + + err = tmc_i2c_rw_op(adap, TMC_I2C_READ, + tadap->mux_select, + msgs[0].addr, msgs[0].buf[0], + len, rwbuf); + msg = &msgs[num - 1]; + len = msg->len; + /* + * To avoid failure in PEC enabled case clear flag. + */ + if (len == TMC_I2C_TRANS_LEN + 1) { + msgs[num - 1].flags &= ~I2C_M_RD; + } + for (n = 0; n < len; n++) + msg->buf[n] = rwbuf[n]; + } + if (err < 0) + return err; + } + + TMC_I2C_STAT_INCN(tadap, msg_cnt, num); + + return num; +} + +static u32 tmc_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL + | I2C_FUNC_SMBUS_READ_BLOCK_DATA; +} + +static const struct i2c_algorithm tmc_i2c_algo = { + .master_xfer = tmc_i2c_mstr_xfer, + .functionality = tmc_i2c_func, +}; + +static int tmc_i2c_mux_group_sel(struct i2c_mux_core *muxc, u32 chan) +{ + struct tmc_i2c_adapter *tadap = i2c_mux_priv(muxc); + + dev_dbg(muxc->dev, "chan = %d\n", chan); + + if (!tadap || chan > TMC_I2C_MSTR_MAX_GROUPS) + return -ENODEV; + tadap->mux_select = chan; + + return 0; +} + +static int tmc_i2c_mux_init(struct i2c_adapter *adap) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + int chan, ret; + + tadap->muxc = i2c_mux_alloc(adap, &adap->dev, tadap->mux_channels, + 0, 0, tmc_i2c_mux_group_sel, NULL); + + if (!tadap->muxc) + return -ENOMEM; + + tadap->muxc->priv = tadap; + for (chan = 0; chan < tadap->mux_channels; chan++) { + ret = i2c_mux_add_adapter(tadap->muxc, 0, chan, 0); + if (ret) { + dev_err(&adap->dev, "Failed to add adapter %d\n", chan); + i2c_mux_del_adapters(tadap->muxc); + return ret; + } + } + + return 0; +} + +static struct i2c_adapter * +tmc_i2c_init_one(struct tmc_i2c_ctrl *tmc, + int master, int id) +{ + struct tmc_i2c_adapter *adapter; + struct device *dev = tmc->dev; + int err; + + adapter = devm_kzalloc(dev, sizeof(*adapter), GFP_KERNEL); + if (!adapter) + return ERR_PTR(-ENOMEM); + + init_waitqueue_head(&adapter->wait); + adapter->adap.owner = THIS_MODULE; + adapter->adap.algo = &tmc_i2c_algo; + adapter->adap.nr = -1; + adapter->adap.timeout = HZ / 5; + adapter->master = master; + adapter->mux_channels = tmc->mux_channels; + adapter->i2c_delay = tmc->i2c_delay; + adapter->membase = tmc->membase; + adapter->dpmbase = tmc->dpmbase; + adapter->polling = 1; + adapter->tctrl = tmc; + + i2c_set_adapdata(&adapter->adap, adapter); + snprintf(adapter->adap.name, sizeof(adapter->adap.name), + "%s:%d", dev_name(dev), master); + + adapter->adap.dev.parent = dev; + err = i2c_add_numbered_adapter(&adapter->adap); + if (err) + goto error; + + err = tmc_i2c_mux_init(&adapter->adap); + if (err) + goto err_remove; + + dev_dbg(dev, "Adapter[%02d-%02d]: " + "dpmbase: 0x%lx\n", id, master, + (unsigned long)adapter->dpmbase); + return &adapter->adap; + +err_remove: + i2c_del_adapter(&adapter->adap); +error: + return ERR_PTR(err); +} + +static void tmc_i2c_cleanup_one(struct i2c_adapter *adap) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + + i2c_mux_del_adapters(tadap->muxc); + i2c_del_adapter(adap); + +} + + +static int tmc_i2c_of_init(struct device *dev, + struct tmc_i2c_ctrl *tmc, int id) +{ + u32 mux_channels, master, num_masters = 0, master_mask = 0; + u32 i2c_delay = 0; + + if (!(master_mask & BIT(master))) + num_masters++; + master_mask |= BIT(master); + + if (id == 0) { + /* chassisd */ + mux_channels = chd_channel; + num_masters = 1; + i2c_delay = 0; + } else if (id == 1) { + /* pfe */ + mux_channels = pfe_channel; + num_masters = 1; + i2c_delay = 20; + } else { + return -EINVAL; + } + + tmc->adap = devm_kcalloc(dev, num_masters, + sizeof(struct i2c_adapter *), + GFP_KERNEL); + if (!tmc->adap) + return -ENOMEM; + + tmc->num_masters = num_masters; + tmc->master_mask = master_mask; + tmc->mux_channels = mux_channels; + tmc->i2c_delay = i2c_delay; + + return 0; +} + +static int tmc_i2c_probe(struct platform_device *pdev) +{ + int i, n, err; + struct resource *res; + struct i2c_adapter *adap; + struct device *dev = &pdev->dev; + struct tmc_i2c_ctrl *tmc; + + const struct mfd_cell *cell = mfd_get_cell(pdev); + + /* + * Allocate memory for the Tmc FPGA + */ + tmc = devm_kzalloc(dev, sizeof(*tmc), GFP_KERNEL); + if (!tmc) + return -ENOMEM; + + platform_set_drvdata(pdev, tmc); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + dev_info(dev, "Tmc I2C Accel resource 0x%llx, %llu\n", + res->start, resource_size(res)); + + tmc->membase = devm_ioremap_nocache(dev, res->start, + resource_size(res)); + if (!tmc->membase) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) + return -ENODEV; + + dev_info(dev, "Tmc I2C Mem resource 0x%llx, %llu\n", + res->start, resource_size(res)); + + tmc->dpmbase = devm_ioremap_nocache(dev, res->start, + resource_size(res)); + if (!tmc->dpmbase) + return -ENOMEM; + + tmc->dev = dev; + spin_lock_init(&tmc->lock); + + err = tmc_i2c_of_init(dev, tmc, cell->id); + if (err) + return err; + + dev_info(dev, "Tmc I2C Masters: %d\n", tmc->num_masters); + dev_info(dev, "Tmc I2C Delay: %d\n", tmc->i2c_delay); + + for (n = 0, i = 0; i < TMC_I2C_MASTER_NR_MSTRS; i++) { + if (tmc->master_mask & BIT(i)) { + adap = tmc_i2c_init_one(tmc, i, n); + if (IS_ERR(adap)) { + err = PTR_ERR(adap); + dev_err(dev, "Failed to initialize master " + "adapter %d: %d\n", i, err); + goto err_remove; + } + tmc->adap[n++] = adap; + } + } + + return 0; + +err_remove: + for (n--; n >= 0; n--) + tmc_i2c_cleanup_one(tmc->adap[n]); + return err; +} + +static int tmc_i2c_remove(struct platform_device *pdev) +{ + struct tmc_i2c_ctrl *tmc = platform_get_drvdata(pdev); + int i; + + /* Disable all masters */ + tmc_iowrite(0, tmc->membase + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET); + + for (i = 0; i < tmc->num_masters; i++) + tmc_i2c_cleanup_one(tmc->adap[i]); + + return 0; +} + +static struct platform_driver tmc_i2c_driver = { + .driver = { + .name = "i2c-tmc", + .owner = THIS_MODULE, + }, + .probe = tmc_i2c_probe, + .remove = tmc_i2c_remove, +}; + +module_platform_driver(tmc_i2c_driver); + +MODULE_DESCRIPTION("Juniper Networks TMC FPGA I2C Accelerator driver"); +MODULE_AUTHOR("Ashish Bhensdadia "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-refpga-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-refpga-tmc.c new file mode 100644 index 000000000000..ef36bca72e9d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-refpga-tmc.c @@ -0,0 +1,603 @@ +/* + * Juniper Networks RE-FPGA qfx platform specific driver + * + * Copyright (C) 2020 Juniper Networks + * Author: Ciju Rajan K + * + * This driver implements various features such as + * - ALARM led driver + * - Fan full speed reset control + * - FAN precense detection + * - FAN type detection + * - Any new QFX specific features which uses RE-FPGA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_LEDS 7 /* Max number of Alarm + FAN LEDs */ + +#define ALARM_MINOR_LED 0 +#define ALARM_MAJOR_LED 1 + +#define REFPGA_PCIE_RESET_CTRL 0x13 +#define REFPGA_PCIE_ALARM 0x33 +#define REFPGA_FAN0_CTRL_STAT 0x28 + +#define REFPGA_RESET_FAN_SPEED BIT(3) +#define REFPGA_OPER_TYPE BIT(0) +#define REFPGA_OPER_START BIT(1) +#define REFPGA_OPER_DONE BIT(2) + +#define TMC_REFPGA_ADDR_REG 0x0 /* TMC offset: 0x228 */ +#define TMC_REFPGA_DATA_REG 0x4 /* TMC offset: 0x22C */ +#define TMC_REFPGA_CTRL_REG 0x8 /* TMC offset: 0x230 */ + +#define TMC_REFPGA_READ_CMD 0x3 +#define TMC_REFPGA_WRITE_CMD 0x2 + +#define REFPGA_INTR_NR_GROUPS 1 +#define REFPGA_INTR_MAX_IRQS_PG 32 + +#define MAX_FANS 5 + +#define REFPGA_IRQ_MAX_BITS_PER_REG 32 + +#define POLL_INTERVAL 5000 + +#define AFI_MASK (0x01) +#define AFO_MASK (0x02) +#define AFI_AFO_MASK (0x03) +/* + * LED specific data structures + */ +struct refpga_led { + struct led_classdev lc; + struct work_struct work; + int blink; + int on; + int bit; + void __iomem *addr; +}; + +struct refpga_led_data { + int num_leds; + struct refpga_led *leds; +}; + +static DEFINE_MUTEX(alarm_led_lock); + +/* + * Common routines + */ +struct refpga_chip { + struct refpga_led_data *led; +}; + +static struct refpga_chip *refpga; + +static DEFINE_MUTEX(refpga_lock); + +static void __iomem *tmc_membase; + +static void wait_for_refpga_oper(void __iomem *base_addr) +{ + volatile u32 done = ~(-1); + unsigned long int timeout; + void __iomem *addr; + + addr = base_addr + (TMC_REFPGA_CTRL_REG); + /* + * Wait till the transaction is complete + */ + timeout = jiffies + msecs_to_jiffies(100); + + do { + usleep_range(50, 100); + done = ioread32(addr); + if (done & (REFPGA_OPER_DONE)) + break; + } while(time_before(jiffies, timeout)); +} +static u32 refpga_read(void __iomem *base_addr, u32 refpga_offset) +{ + u32 value; + + mutex_lock(&refpga_lock); + iowrite32(refpga_offset, base_addr + (TMC_REFPGA_ADDR_REG)); + iowrite32(TMC_REFPGA_READ_CMD, base_addr + (TMC_REFPGA_CTRL_REG)); + wait_for_refpga_oper(base_addr); + value = ioread32(base_addr + (TMC_REFPGA_DATA_REG)); + mutex_unlock(&refpga_lock); + + return value; +} + +static void refpga_write(void __iomem *base_addr, u32 refpga_offset, u32 val) +{ + mutex_lock(&refpga_lock); + iowrite32(refpga_offset, base_addr + (TMC_REFPGA_ADDR_REG)); + iowrite32(val, base_addr + (TMC_REFPGA_DATA_REG)); + iowrite32(TMC_REFPGA_WRITE_CMD, base_addr + (TMC_REFPGA_CTRL_REG)); + wait_for_refpga_oper(base_addr); + mutex_unlock(&refpga_lock); +} + +static bool get_fan_presense(u8 idx) +{ + u8 value = 0x00; + u8 offset = REFPGA_FAN0_CTRL_STAT; + bool ret = 0; + + value = refpga_read(tmc_membase, (offset + (idx * 2))); + /* + * Get the last two bits of REFPGA_FANx_CTRL_STAT. + * REFPGA_FANx_CTRL_STAT register of REFPGA gives the fan airflow + * status. There are 5 fans in QFX5200. Last two bits give the AFI + * & AFO status. If any of these bits are set, fan is present. + */ + value = (value & BIT(0)) | (value & BIT(1)); + if (value) + ret = 1; + + return ret; +} + +static int get_fan_type(u8 idx) +{ + u8 value = 0x00; + u8 offset = REFPGA_FAN0_CTRL_STAT; + int ret = -1; + + value = refpga_read(tmc_membase, (offset + (idx * 2))); + /* + * Get the last two bits of REFPGA_FANx_CTRL_STAT. + * REFPGA_FANx_CTRL_STAT register of REFPGA gives the fan airflow + * status. There are 5 fans in QFX5200. Last two bits give the AFI + * & AFO status. If bit1 is set, it's AFO and if bit 0 is set, + * it's AFI. + * + * This function will return '1' for AFO, '0' for AFI, and '-1' + * if there is no fan or if both AFI & AFO bits are set. + */ + value &= AFI_AFO_MASK; + + switch(value) { + case AFI_MASK: + ret = 0; + break; + case AFO_MASK: + ret = 1; + break; + default: + ret = -1; + break; + }; + + return ret; +} + +enum sysfs_fan_attributes { + FAN0_PRESENT, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, +}; + +enum sysfs_fan_type_attributes { + FAN0_TYPE, + FAN1_TYPE, + FAN2_TYPE, + FAN3_TYPE, + FAN4_TYPE, +}; + +/* + * The sysfs files will be present in this path + * /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan*_present + * /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan*_type + */ + +#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, refpga_fan_presense_show, NULL, FAN##index##_PRESENT) +#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr + +#define DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_type, S_IRUGO, refpga_fan_type_show, NULL, FAN##index##_TYPE) +#define DECLARE_FAN_TYPE_ATTR(index) &sensor_dev_attr_fan##index##_type.dev_attr.attr + +static ssize_t refpga_fan_presense_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); + + return sprintf(buf, "%d\n", get_fan_presense(s_attr->index)); + +} + +static ssize_t refpga_fan_type_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); + + return sprintf(buf, "%d\n", get_fan_type(s_attr->index)); + +} + +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(0); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); + +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(0); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(1); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(2); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(3); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(4); + +static struct attribute *refpga_fan_attrs[] = { + DECLARE_FAN_PRESENT_ATTR(0), + DECLARE_FAN_PRESENT_ATTR(1), + DECLARE_FAN_PRESENT_ATTR(2), + DECLARE_FAN_PRESENT_ATTR(3), + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_TYPE_ATTR(0), + DECLARE_FAN_TYPE_ATTR(1), + DECLARE_FAN_TYPE_ATTR(2), + DECLARE_FAN_TYPE_ATTR(3), + DECLARE_FAN_TYPE_ATTR(4), + NULL +}; + +static struct attribute_group refpga_fan_attr_group = { + .attrs = refpga_fan_attrs, +}; + +/* + * There is only a single ALARM led in QFX5200 and that + * is used for both Major & Minor alarm indicator. + * These are represented by two different bits in RE-FPGA + * PCIE_ALARM register. Only one of the bit (either Red or + * Yellow) should be set a time. If both the bits are set, + * it's an undefined behaviour. + * + * The following table describes how the conditions are + * handled in the driver as there can be both Major & Minor + * alarms can be triggered from userspace. + * + * Major Minor Colour + * + * 0 0 Nil + * 0 1 Yellow + * 1 1 Red + * 1 0 Red + * + */ +static void manage_alarm_led(void __iomem *addr, int led_type, int value) +{ + static int alarm_major = 0, alarm_minor = 0; + u32 reg = 0x0; + + mutex_lock(&alarm_led_lock); + reg = refpga_read(addr, REFPGA_PCIE_ALARM); + + (led_type == ALARM_MAJOR_LED) ? + ((value == 1) ? (alarm_major = 1) : (alarm_major = 0)) : + ((value == 1) ? (alarm_minor = 1) : (alarm_minor = 0)); + if (alarm_major) { + reg &= ~BIT(ALARM_MINOR_LED); + reg |= BIT(ALARM_MAJOR_LED); + } else { + if (alarm_minor) { + reg &= ~BIT(ALARM_MAJOR_LED); + reg |= BIT(ALARM_MINOR_LED); + } else { + reg &= ~BIT(ALARM_MINOR_LED); + reg &= ~BIT(ALARM_MAJOR_LED); + } + } + refpga_write(addr, REFPGA_PCIE_ALARM, reg); + mutex_unlock(&alarm_led_lock); +} + +static void manage_fan_led(void __iomem *addr, int fan_slot, int value) +{ + u8 offset = REFPGA_FAN0_CTRL_STAT + (fan_slot * 2); + u32 reg = 0x0; + + reg = refpga_read(addr, offset); + if(value) { + /* Turn on s/w control */ + reg = reg | BIT(4); + /* Turn off green led */ + reg &= ~BIT(5); + /* Turn on yellow led & make it blink */ + reg |= (BIT(6) | BIT(7)); + } else { + /* Clear yellow led & stop blink */ + reg &= ~(BIT(6) | BIT(7)); + /* Stop s/w control */ + reg &= ~BIT(4); + } + refpga_write(addr, offset, reg); +} + +static void refpga_led_work(struct work_struct *work) +{ + struct refpga_led *led = container_of(work, struct refpga_led, work); + void __iomem *addr; + + addr = led->addr; + + if(strstr(led->lc.name, "fan")) + manage_fan_led(addr, led->bit, led->on); + else + manage_alarm_led(addr, led->bit, led->on); +} + +static void refpga_led_brightness_set(struct led_classdev *lc, + enum led_brightness brightness) +{ + struct refpga_led *led = container_of(lc, struct refpga_led, lc); + + led->on = (brightness != LED_OFF); + led->blink = 0; /* always turn off hw blink on brightness_set() */ + schedule_work(&led->work); +} + +struct led_table +{ + const char *name; + int reg; +}; + +static struct led_table qfx5200_led_data[] = { + { + .name = "alarm-minor", + .reg = 0, + }, + { + .name = "alarm-major", + .reg = 1, + }, + { + .name = "fan0-fault", + .reg = 0, + }, + { + .name = "fan1-fault", + .reg = 1, + }, + { + .name = "fan2-fault", + .reg = 2, + }, + { + .name = "fan3-fault", + .reg = 3, + }, + { + .name = "fan4-fault", + .reg = 4, + } +}; + +static int refpga_led_init_one(struct device *dev, + struct refpga_led_data *ild, + int num) +{ + struct refpga_led *led; + int ret = 0; + + led = &ild->leds[num]; + led->addr = tmc_membase; + + led->lc.name = qfx5200_led_data[num].name; + led->bit = qfx5200_led_data[num].reg; + led->lc.brightness = LED_OFF; + led->lc.brightness_set = refpga_led_brightness_set; + + ret = devm_led_classdev_register(dev, &led->lc); + if (ret) { + dev_err(dev, "devm_led_classdev_register failed\n"); + return ret; + } + + INIT_WORK(&led->work, refpga_led_work); + + return 0; +} + +static int refpga_led_qfx5200_init(struct device *dev, struct refpga_led_data *ild) +{ + int ret = 0, idx = 0; + + + if (!dev->parent) { + dev_err(dev, "dev->parent is null\n"); + return -ENODEV; + } + + ild->num_leds = NUM_LEDS; + ild->leds = devm_kzalloc(dev, sizeof(struct refpga_led) * NUM_LEDS, + GFP_KERNEL); + if (!ild->leds) { + dev_err(dev, "LED allocation failed\n"); + return -ENOMEM; + } + + for(idx=0; idxdev; + struct refpga_led_data *ild; + int ret; + + ild = devm_kzalloc(dev, sizeof(*ild), GFP_KERNEL); + if (!ild) { + dev_err(dev, "ild allocation failed\n"); + return -ENOMEM; + } + + ret = refpga_led_qfx5200_init(dev, ild); + if (ret < 0) + return ret; + + refpga->led = ild; + + return 0; +} + +static int jnx_refpga_led_remove(struct platform_device *pdev) +{ + struct refpga_chip *drv_data = platform_get_drvdata(pdev); + struct refpga_led_data *ild = drv_data->led; + int i; + + for (i = 0; i < ild->num_leds; i++) { + devm_led_classdev_unregister(&pdev->dev, &ild->leds[i].lc); + cancel_work_sync(&ild->leds[i].work); + } + if (ild) { + if (ild->leds) + devm_kfree(&pdev->dev, ild->leds); + devm_kfree(&pdev->dev, ild); + } + return 0; +} + +static void reset_fan_full_speed(struct device *dev) +{ + u32 val = ~(-1), tmp = ~(-1); + + /* + * Reading the REFPGA_PCIE_RESET_CTRL register + */ + val = refpga_read(tmc_membase, REFPGA_PCIE_RESET_CTRL); + /* + * Clearing the fan full_speed bit + */ + val &= ~(REFPGA_RESET_FAN_SPEED); + /* + * Writing the REFPGA_PCIE_RESET_CTRL register + */ + refpga_write(tmc_membase, REFPGA_PCIE_RESET_CTRL, val); + /* + * Reading the REFPGA_PCIE_RESET_CTRL register + */ + tmp = refpga_read(tmc_membase, REFPGA_PCIE_RESET_CTRL); + dev_info(dev, "After resetting fan full speed control: %X\n", tmp); +} + +static int jnx_refpga_tmc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *res; + int ret = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "resource allocation failed\n"); + return -ENODEV; + } + + tmc_membase = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!tmc_membase) { + dev_err(dev, "ioremap failed\n"); + return -ENOMEM; + } + + refpga = devm_kzalloc(dev, sizeof(*refpga), GFP_KERNEL); + if (!refpga) { + dev_err(dev, "refpga memory allocation failed\n"); + return -ENOMEM; + } + + reset_fan_full_speed(dev); + + ret = jnx_refpga_led_probe(pdev); + if (ret != 0) { + dev_err(dev, "Refpga LED probe failed\n"); + return ret; + } + + dev_info(dev, "Refpga LED probe successful: TMC memoy base: %p\n", + tmc_membase); + + ret = sysfs_create_group(&dev->kobj, &refpga_fan_attr_group); + if (ret != 0) { + dev_err(dev, "sysfs_create_group failed: %d\n", ret); + return ret; + } + + platform_set_drvdata(pdev, refpga); + + return 0; +} + +static int jnx_refpga_tmc_remove(struct platform_device *pdev) +{ + jnx_refpga_led_remove(pdev); + sysfs_remove_group(&pdev->dev.kobj, &refpga_fan_attr_group); + + return 0; +} + +static struct platform_driver jnx_refpga_tmc_driver = { + .driver = { + .name = "refpga-tmc", + .owner = THIS_MODULE, + }, + .probe = jnx_refpga_tmc_probe, + .remove = jnx_refpga_tmc_remove, +}; + +static int __init jnx_refpga_tmc_driver_init(void) +{ + int ret = -1; + + ret = platform_driver_register(&jnx_refpga_tmc_driver); + + return ret; + +} + +static void __exit jnx_refpga_tmc_driver_exit(void) +{ + platform_driver_unregister(&jnx_refpga_tmc_driver); +} + +module_init(jnx_refpga_tmc_driver_init); +module_exit(jnx_refpga_tmc_driver_exit); + +MODULE_DESCRIPTION("Juniper Networks REFPGA / TMC driver"); +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc-core.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc-core.c new file mode 100644 index 000000000000..833164bfed63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc-core.c @@ -0,0 +1,477 @@ +/* + * Juniper Networks TMC-FPGA MFD Core driver for qfx platform + * + * Copyright (c) 2020, Juniper Networks + * Author: Ashish Bhensdadia + * + * This driver implement the resource publish for below devices + * - I2C + * - GPIO + * - RE FPGA + * - PSU + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jnx-tmc.h" + +#define TMC_DO_SCRATCH_TEST 1 + +/* + * TMC FPGA Device IDs + */ +#define PCI_VENDOR_ID_JUNIPER 0x1304 + +#define PCI_DEVICE_ID_JNX_TMC_CHD 0x007B +#define PCI_DEVICE_ID_JNX_TMC_PFE 0x007C + +/* + * TMC resources + */ +static struct resource tmc_resource_i2c[] = { + /* I2C AUTOMATION Block */ + { + .name = "i2c-tmc", + .start = TMC_I2C_AUTOMATION_I2C_CONTROL_START, + .end = TMC_I2C_AUTOMATION_I2C_CONTROL_END, + .flags = IORESOURCE_MEM, + }, + + /* I2C DPMEM */ + { + .name = "i2c-tmc-mem", + .start = TMC_I2C_DPMEM_ENTRY_START, + .end = TMC_I2C_DPMEM_ENTRY_END, + .flags = IORESOURCE_MEM, + }, +}; + +#define TMC_RES_I2C_NR ARRAY_SIZE(tmc_resource_i2c) + +/* + * LED resources + */ +static struct resource tmc_resource_leds[] = { + { + .name = "leds-tmc", + .start = TMC_LED_CONTROL_START, + .end = TMC_LED_CONTROL_END, + .flags = IORESOURCE_MEM, + }, +}; + +#define TMC_RES_LEDS_NR ARRAY_SIZE(tmc_resource_leds) + +/* + * TMC RE-FPGA devices + */ +static struct resource tmc_resource_refpga[] = { + { + .name = "refpga-tmc", + .start = TMC_REFPGA_ACCESS_START, + .end = TMC_REFPGA_ACCESS_END, + .flags = IORESOURCE_MEM, + }, +}; + +#define TMC_RES_REFPGA_NR ARRAY_SIZE(tmc_resource_refpga) + +static struct resource tmc_resource_gpioslave0[] = { + /* SLAVE0 Block */ + { + .name = "gpioslave-tmc", + .start = TMC_GPIO_SLAVE0_START, + .end = TMC_GPIO_SLAVE0_END, + .flags = IORESOURCE_MEM, + } +}; + +#define TMC_RES_GPIOSLAVE0_NR ARRAY_SIZE(tmc_resource_gpioslave0) + +static struct resource tmc_resource_gpioslave1[] = { + /* SLAVE1 Block */ + { + .name = "gpioslave-tmc", + .start = TMC_GPIO_SLAVE1_START, + .end = TMC_GPIO_SLAVE1_END, + .flags = IORESOURCE_MEM, + } +}; + +#define TMC_RES_GPIOSLAVE1_NR ARRAY_SIZE(tmc_resource_gpioslave1) + +static struct resource tmc_resource_psu[] = { + /* PSU Block */ + { + .name = "psu-tmc", + .start = TMC_PSU_START, + .end = TMC_PSU_END, + .flags = IORESOURCE_MEM, + } +}; + +#define TMC_RES_PSU_NR ARRAY_SIZE(tmc_resource_psu) + +/* + * CHASSISD TMC MFD devices + */ +static struct mfd_cell chassisd_tmc_mfd_devs[] = { + { + .name = "i2c-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_i2c), + .resources = &tmc_resource_i2c[0], + .of_compatible = "jnx,i2c-tmc", + .id = 0, + }, + { + .name = "leds-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_leds), + .resources = &tmc_resource_leds[0], + .of_compatible = "jnx,leds-tmc", + .id = 0, + }, + { + .name = "refpga-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_refpga), + .resources = &tmc_resource_refpga[0], + .of_compatible = "jnx,refpga-tmc", + .id = 0, + }, + { + .name = "psu-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_psu), + .resources = &tmc_resource_psu[0], + .of_compatible = "jnx,psu-tmc", + .id = 0, + }, +}; + +/* + * PFE TMC MFD devices + */ +static struct mfd_cell pfe_tmc_mfd_devs[] = { + { + .name = "i2c-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_i2c), + .resources = &tmc_resource_i2c[0], + .of_compatible = "jnx,i2c-tmc", + .id = 1, + }, + { + .name = "gpioslave-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_gpioslave0), + .resources = &tmc_resource_gpioslave0[0], + .of_compatible = "jnx,gpioslave-tmc", + .id = 0, + }, + { + .name = "gpioslave-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_gpioslave1), + .resources = &tmc_resource_gpioslave1[0], + .of_compatible = "jnx,gpioslave-tmc", + .id = 1, + }, +}; + + +struct tmc_fpga_data { + void __iomem *membase; + struct pci_dev *pdev; + + u32 major; /* Device id & Major version*/ + u32 minor; /* Minor version */ + + u32 optic_cpld_major; /* optic cpld major version */ + u32 optic_cpld_minor; /* optic cpld minor version */ + u32 optic_cpld_devid; /* optic cpld device id */ +}; + +/* sysfs entries */ +static ssize_t major_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "0x%02X_%06X\n", + (tmc->major >> 24) & 0xff, + tmc->major & 0xffffff); +} + +static ssize_t minor_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%02X\n", (tmc->minor) & 0xff); +} + +static ssize_t optic_cpld_major_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%01X\n", tmc->optic_cpld_major & 0xf); +} + +static ssize_t optic_cpld_devid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%01X\n", + (tmc->optic_cpld_major >> 4) & 0xf); +} + +static ssize_t optic_cpld_minor_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%02X\n", tmc->optic_cpld_minor & 0xff); +} + +static ssize_t set_sys_shutdown(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t len) +{ + + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 0, &val); + if (ret < 0) + return ret; + + if (val != 1) + return -EINVAL; + + /* Unlock the shutdown register */ + iowrite32(0x12345678, tmc->membase + TMC_SYS_SHUTDOWN_LOCK); + iowrite32(0x1, tmc->membase + TMC_SYS_SHUTDOWN); + + return len; +} + + +static DEVICE_ATTR(major, S_IRUGO, major_show, NULL); +static DEVICE_ATTR(minor, S_IRUGO, minor_show, NULL); +static DEVICE_ATTR(optic_cpld_major, S_IRUGO, optic_cpld_major_show, NULL); +static DEVICE_ATTR(optic_cpld_devid, S_IRUGO, optic_cpld_devid_show, NULL); +static DEVICE_ATTR(optic_cpld_minor, S_IRUGO, optic_cpld_minor_show, NULL); +static DEVICE_ATTR(shutdown, S_IWUSR, NULL, set_sys_shutdown); + +static struct attribute *tmc_attrs[] = { + &dev_attr_major.attr, + &dev_attr_minor.attr, + &dev_attr_optic_cpld_major.attr, + &dev_attr_optic_cpld_devid.attr, + &dev_attr_optic_cpld_minor.attr, + &dev_attr_shutdown.attr, + NULL, +}; + +static struct attribute_group tmc_attr_group = { + .attrs = tmc_attrs, +}; + +#if defined TMC_DO_SCRATCH_TEST +/* Do a quick scratch access test */ +static int tmc_do_test_scratch(struct tmc_fpga_data *tmc) +{ + struct pci_dev *pdev = tmc->pdev; + struct device *dev = &pdev->dev; + int offset = TMC_SCRATCH; + u32 acc, val = 0xdeadbeaf; + + /* + * Check rw register access -> use the scratch reg. + */ + iowrite32(val, tmc->membase + offset); + acc = ioread32(tmc->membase + offset); + if (acc != val) { + dev_err(dev, "Tmc scratch(0x%x) failed: %08x.%08x!\n", + offset, val, acc); + return -EIO; + } + + for (val = 0; val < 0xf0000000; val += 0x01010101) { + iowrite32(val, tmc->membase + offset); + acc = ioread32(tmc->membase + offset); + if (acc != val) { + dev_err(dev, "Tmc scratch(0x%x) failed: %08x.%08x!\n", + offset, val, acc); + return -EIO; + } + } + + /* + * Write a sig before leaving.. + */ + val = 0xcafebabe; + iowrite32(val, tmc->membase + offset); + dev_dbg(dev, "Tmc scratch result: 0x%08x\n", + ioread32(tmc->membase + offset)); + + return 0; +} +#endif /* TMC_DO_SCRATCH_TEST */ + +static int tmc_fpga_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int err; + struct tmc_fpga_data *tmc; + struct device *dev = &pdev->dev; + + dev_dbg(dev, "Tmc FPGA Probe called\n"); + + tmc = devm_kzalloc(dev, sizeof(*tmc), GFP_KERNEL); + if (!tmc) + return -ENOMEM; + + err = pcim_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "Failed to enable device %d\n", err); + return err; + } + + err = pcim_iomap_regions(pdev, 1 << 0, "tmc-core"); + if (err) { + dev_err(&pdev->dev, "Failed to iomap regions %d\n", err); + goto err_disable; + } + + tmc->membase = pcim_iomap_table(pdev)[0]; + if (IS_ERR(tmc->membase)) { + dev_err(dev, "pci_ioremap_bar() failed\n"); + err = -ENOMEM; + goto err_release; + } + + tmc->pdev = pdev; + pci_set_drvdata(pdev, tmc); + + /* All Tmc uses MSI interrupts - enable bus mastering */ + pci_set_master(pdev); + +#if defined TMC_DO_SCRATCH_TEST + /* Check IO before proceeding */ + dev_dbg(dev, "Tmc FPGA starting scratch test\n"); + err = tmc_do_test_scratch(tmc); + if (err) + goto err_unmap; + + dev_dbg(dev, "Tmc FPGA scratch test passed !!!\n"); +#endif /* TMC_DO_SCRATCH_TEST */ + + switch (id->device) { + case PCI_DEVICE_ID_JNX_TMC_CHD: + err = mfd_add_devices(dev, pdev->bus->number, + &chassisd_tmc_mfd_devs[0], + ARRAY_SIZE(chassisd_tmc_mfd_devs), + &pdev->resource[0], + 0, NULL /* tmc->irq_domain */); + break; + case PCI_DEVICE_ID_JNX_TMC_PFE: + err = mfd_add_devices(dev, pdev->bus->number, + &pfe_tmc_mfd_devs[0], + ARRAY_SIZE(pfe_tmc_mfd_devs), + &pdev->resource[0], + 0, NULL /* tmc->irq_domain */); + break; + default: + dev_err(&pdev->dev, "Invalid PCI Device ID id:%d\n", + id->device); + goto err_unmap; + } + + if (err < 0) { + dev_err(&pdev->dev, "Failed to add mfd devices %d\n", err); + goto err_unmap; + } + + err = sysfs_create_group(&pdev->dev.kobj, &tmc_attr_group); + if (err) { + sysfs_remove_group(&pdev->dev.kobj, &tmc_attr_group); + dev_err(&pdev->dev, "Failed to create attr group\n"); + goto err_remove_mfd; + } + + tmc->major = ioread32(tmc->membase + TMC_REVISION); + tmc->minor = ioread32(tmc->membase + TMC_MINOR); + + tmc->optic_cpld_major = ioread32(tmc->membase + TMC_OPTIC_CPLD_MAJOR); + tmc->optic_cpld_minor = ioread32(tmc->membase + TMC_OPTIC_CPLD_MINOR); + + dev_info(dev, "Tmc FPGA Revision: 0x%02X_%06X, Minor: %02X\n", + (tmc->major >> 24) & 0xff, + tmc->major & 0xffffff, + (tmc->minor) & 0xff); + dev_info(dev, "Tmc FPGA optic cpld Major: 0x%01X, Minor: 0x%02X " + "Devid: 0x%01X\n", (tmc->optic_cpld_major) & 0xf, + (tmc->optic_cpld_minor) & 0xff, + (tmc->optic_cpld_major >> 4) & 0xf); + dev_info(dev, "Tmc FPGA mem:0x%lx\n", + (unsigned long)tmc->membase); + + return 0; + +err_remove_mfd: + mfd_remove_devices(dev); +err_unmap: + pci_iounmap(pdev, tmc->membase); +err_release: + pci_release_regions(pdev); +err_disable: + pci_disable_device(pdev); + + return err; +} + +static void tmc_fpga_remove(struct pci_dev *pdev) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(&pdev->dev); + + sysfs_remove_group(&pdev->dev.kobj, &tmc_attr_group); + mfd_remove_devices(&pdev->dev); +} + +static const struct pci_device_id tmc_fpga_id_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_TMC_CHD) }, + { PCI_DEVICE(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_TMC_PFE) }, + { } +}; +MODULE_DEVICE_TABLE(pci, tmc_fpga_id_tbl); + +static struct pci_driver tmc_fpga_driver = { + .name = "tmc-core", + .id_table = tmc_fpga_id_tbl, + .probe = tmc_fpga_probe, + .remove = tmc_fpga_remove, +}; + +module_pci_driver(tmc_fpga_driver); + +MODULE_DESCRIPTION("Juniper Networks TMC FPGA MFD core driver"); +MODULE_AUTHOR("Ashish Bhensdadia "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc.h b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc.h new file mode 100644 index 000000000000..dce7d7be3311 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc.h @@ -0,0 +1,93 @@ +/* + * Juniper Tmc FPGA register definitions + * + * Copyright (C) 2018 Juniper Networks + * Author: Ashish Bhensdadia + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __JNX_TMC_H__ +#define __JNX_TMC_H__ + + +#define TMC_REVISION 0x00064 +#define TMC_MINOR 0x00068 +#define TMC_SCRATCH 0x00098 + +#define TMC_OPTIC_CPLD_MAJOR 0x00104 +#define TMC_OPTIC_CPLD_MINOR 0x00108 + +/* + * I2C Master Block + */ +#define TMC_I2C_AUTOMATION_I2C_CONTROL_START 0x07000 +#define TMC_I2C_AUTOMATION_I2C_CONTROL_END 0x07500 + +#define TMC_I2C_DPMEM_ENTRY_START 0x10000 +#define TMC_I2C_DPMEM_ENTRY_END 0x13FFC + +#define TMC_LED_CONTROL_START 0x58 +#define TMC_LED_CONTROL_END 0x5B + +/* + * RE-FPGA block + */ +#define TMC_REFPGA_ACCESS_START 0x228 +#define TMC_REFPGA_ACCESS_END 0x233 + +#define TMC_I2C_MASTER_NR_MSTRS 16 +#define TMC_I2C_MSTR_MAX_GROUPS 66 + + +/* + * TMC GPIO SLAVE Block + */ +#define TMC_GPIO_PTP_RESET_START 0x94 +#define TMC_GPIO_PTP_RESET_END 0x97 + +#define TMC_GPIO_PTP_CFG_START 0xa4 +#define TMC_GPIO_PTP_CFG_END 0xa7 + +#define TMC_GPIO_PTP_DATA_START 0xa8 +#define TMC_GPIO_PTP_DATA_END 0xab + +#define TMC_GPIO_SLAVE0_START 0xf0 +#define TMC_GPIO_SLAVE0_END 0x16b + +#define TMC_GPIO_SLAVE1_START 0x170 +#define TMC_GPIO_SLAVE1_END 0x1eb + +#define TMC_GPIO_SLAVE2_START 0x1f0 +#define TMC_GPIO_SLAVE2_END 0x213 + +#define TMC_GPIO_SLAVE3_START 0x280 +#define TMC_GPIO_SLAVE3_END 0x2eb + +#define TMC_GPIO_SFP_SLAVE0_START 0x308 +#define TMC_GPIO_SFP_SLAVE0_END 0x32b + +#define TMC_GPIO_SFP_SLAVE1_START 0x32c +#define TMC_GPIO_SFP_SLAVE1_END 0x34b + +/* + * TMC PSU Block + */ +#define TMC_PSU_START 0x240 +#define TMC_PSU_END 0x243 + +/* + * TMC SHUTDOWN REG + */ +#define TMC_SYS_SHUTDOWN_LOCK 0x254 +#define TMC_SYS_SHUTDOWN 0x250 + +/* + * TMC DS100 MUX Block + */ +#define TMC_GPIO_MUX_SLAVE_START 0x26c +#define TMC_GPIO_MUX_SLAVE_END 0x26f + +#endif /* __JNX_TMC_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/juniper_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/juniper_i2c_cpld.c deleted file mode 100644 index 25860a6ac1f9..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/common/modules/juniper_i2c_cpld.c +++ /dev/null @@ -1,892 +0,0 @@ -/* - * A hwmon driver for the juniper_i2c_cpld - * - * Tested and validated on Juniper QFX5210 - * Ciju Rajan K - * - * Copyright (C) 2013 Accton Technology Corporation. - * Brandon Chuang - * - * Based on ad7414.c - * Copyright 2006 Stefan Roese , DENX Software Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define MAX_PORT_NUM 64 -#define I2C_RW_RETRY_COUNT 10 -#define I2C_RW_RETRY_INTERVAL 60 /* ms */ - -#define I2C_ADDR_CPLD1 0x60 -#define I2C_ADDR_CPLD2 0x62 -#define I2C_ADDR_CPLD3 0x64 -#define CPLD_ADDRS {I2C_ADDR_CPLD1, I2C_ADDR_CPLD2, I2C_ADDR_CPLD3} - - -/* - * Number of additional attribute pointers to allocate - * with each call to krealloc - */ -#define ATTR_ALLOC_SIZE 1 /*For last attribute which is NUll.*/ - -#define NAME_SIZE 24 -#define MAX_RESP_LENGTH 48 - -typedef ssize_t (*show_func)( struct device *dev, - struct device_attribute *attr, - char *buf); -typedef ssize_t (*store_func)(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); - -enum models { - AS7712_32X, - AS7716_32X, - qfx5210_64X, - AS7312_54X, - PLAIN_CPLD, /*No attribute but add i2c addr to the list.*/ - NUM_MODEL -}; - -enum sfp_func { - HAS_SFP = 1<<0 , - HAS_QSFP = 1<<1 , -}; - -enum common_attrs { - CMN_VERSION, - CMN_ACCESS, - CMN_PRESENT_ALL, - NUM_COMMON_ATTR -}; - -enum sfp_attrs { - SFP_PRESENT, - SFP_RESET, - SFP_LP_MODE, - NUM_SFP_ATTR -}; - -struct cpld_sensor { - struct cpld_sensor *next; - char name[NAME_SIZE+1]; /* sysfs sensor name */ - struct device_attribute attribute; - bool update; /* runtime sensor update needed */ - int data; /* Sensor data. Negative if there was a read error */ - - u8 reg; /* register */ - u8 mask; /* bit mask */ - bool invert; /* inverted value*/ - -}; - -#define to_cpld_sensor(_attr) \ - container_of(_attr, struct cpld_sensor, attribute) - -struct cpld_data { - struct device *dev; - struct device *hwmon_dev; - - int num_attributes; - struct attribute_group group; - - enum models model; - struct cpld_sensor *sensors; - struct mutex update_lock; - bool valid; - unsigned long last_updated; /* in jiffies */ - - int attr_index; - u16 sfp_num; - u8 sfp_types; - struct model_attrs *cmn_attr; -}; - -struct cpld_client_node { - struct i2c_client *client; - struct list_head list; -}; - - -struct base_attrs { - const char *name; - umode_t mode; - show_func get; - store_func set; -}; - -struct attrs { - int reg; - bool invert; - struct base_attrs *base; -}; - -struct model_attrs { - struct attrs **cmn; - struct attrs **portly; -}; - - -static ssize_t show_bit(struct device *dev, - struct device_attribute *devattr, char *buf); -static ssize_t show_presnet_all(struct device *dev, - struct device_attribute *devattr, char *buf); -static ssize_t set_1bit(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static ssize_t set_byte(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static ssize_t access(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); - -int juniper_i2c_cpld_read(u8 cpld_addr, u8 reg); -int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); - - -struct base_attrs common_attrs[NUM_COMMON_ATTR] = -{ - [CMN_VERSION] = {"version", S_IRUGO, show_bit, NULL}, - [CMN_ACCESS] = {"access", S_IWUSR, NULL, set_byte}, - [CMN_PRESENT_ALL] = {"module_present_all", S_IRUGO, show_presnet_all, NULL}, -}; - -struct attrs as7712_common[] = { - [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, - [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, - [CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]}, -}; -struct attrs qfx5210_common[] = { - [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, - [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, - [CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]}, -}; -struct attrs as7312_common[] = { - [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, - [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, - [CMN_PRESENT_ALL] = {-1, false, &common_attrs[CMN_PRESENT_ALL]}, -}; -struct attrs plain_common[] = { - [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, -}; - -struct base_attrs portly_attrs[] = -{ - [SFP_PRESENT] = {"module_present", S_IRUGO, show_bit, NULL}, - // Only root user will have the privilege to write to sysfs - // [SFP_RESET] = {"module_reset", S_IRUGO|S_IWUGO, show_bit, set_1bit}, - [SFP_RESET] = {"module_reset", S_IRUGO|S_IWUSR, show_bit, set_1bit}, -}; - -struct attrs as7712_port[] = { - {0x30, true, &portly_attrs[SFP_PRESENT]}, - {0x04, true, &portly_attrs[SFP_RESET]}, -}; - -struct attrs qfx5210_port[] = { - {0x70, true, &portly_attrs[SFP_PRESENT]}, - {0x40, true, &portly_attrs[SFP_RESET]}, -}; - -struct attrs *as7712_cmn_list[] = { - &as7712_common[CMN_VERSION], - &as7712_common[CMN_ACCESS], - &as7712_common[CMN_PRESENT_ALL], - NULL -}; - -struct attrs *qfx5210_cmn_list[] = { - &qfx5210_common[CMN_VERSION], - &qfx5210_common[CMN_ACCESS], - &qfx5210_common[CMN_PRESENT_ALL], - NULL -}; - -struct attrs *as7312_cmn_list[] = { - &as7312_common[CMN_VERSION], - &as7312_common[CMN_ACCESS], - &as7312_common[CMN_PRESENT_ALL], - NULL -}; - -struct attrs *plain_cmn_list[] = { - &plain_common[CMN_VERSION], - NULL -}; - -struct attrs *as7712_port_list[] = { - &as7712_port[SFP_PRESENT], - &as7712_port[SFP_RESET], - NULL -}; -struct attrs *qfx5210_port_list[] = { - &qfx5210_port[SFP_PRESENT], - &qfx5210_port[SFP_RESET], - NULL -}; - -struct model_attrs models_attr[NUM_MODEL] = { - {.cmn = as7712_cmn_list, .portly=as7712_port_list}, - {.cmn = as7712_cmn_list, .portly=as7712_port_list}, /*7716's as 7712*/ - {.cmn = qfx5210_cmn_list, .portly=qfx5210_port_list}, - {.cmn = as7312_cmn_list, .portly=qfx5210_port_list}, - {.cmn = plain_cmn_list, .portly=NULL}, -}; - -static LIST_HEAD(cpld_client_list); -static struct mutex list_lock; -/* Addresses scanned for juniper_i2c_cpld - */ -static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int get_sfp_spec(int model, u16 *num, u8 *types) -{ - switch (model) { - case AS7712_32X: - case AS7716_32X: - *num = 32; - *types = HAS_QSFP; - break; - case qfx5210_64X: - *num = 64; - *types = HAS_QSFP; - break; - case AS7312_54X: - *num = 54; - *types = HAS_QSFP|HAS_SFP; - default: - *types = 0; - *num = 0; - break; - } - - return 0; -} - -static int get_present_reg(int model, u8 port, u8 *cpld_addr, u8 *reg, u8 *num) -{ - u8 cpld_address[] = CPLD_ADDRS; - - switch (model) { - case AS7312_54X: - if (port < 48) { - *cpld_addr = cpld_address[1 + port/24]; - *reg = 0x09 + (port%24)/8; - *num = 8; - } - else - { - *reg = 0x18; - *num = 4; - *cpld_addr = ( port < 52)? cpld_address[1]: cpld_address[2]; - } - break; - default: - return -EINVAL; - } -} - - -/*Assume the bits for ports are listed in-a-row.*/ -static int get_reg_bit(u8 reg_start, int port, - u8 *reg ,u8 *mask) -{ - *reg = reg_start + ((port)/8); - *mask = 1 << ((port)%8); - - return 0; -} - -static int cpld_write_internal( - struct i2c_client *client, u8 reg, u8 value) -{ - int status = 0, retry = I2C_RW_RETRY_COUNT; - - while (retry) { - status = i2c_smbus_write_byte_data(client, reg, value); - if (unlikely(status < 0)) { - msleep(I2C_RW_RETRY_INTERVAL); - retry--; - continue; - } - - break; - } - - return status; -} - -static int cpld_read_internal(struct i2c_client *client, u8 reg) -{ - int status = 0, retry = I2C_RW_RETRY_COUNT; - - while (retry) { - status = i2c_smbus_read_byte_data(client, reg); - if (unlikely(status < 0)) { - msleep(I2C_RW_RETRY_INTERVAL); - retry--; - continue; - } - - break; - } - - return status; -} - - -/*Turn a numberic array into string with " " between each element. - * e.g., {0x11, 0x33, 0xff, 0xf1} => "11 33 ff f1" - */ -static ssize_t array_stringify(char *buf, u8 *input, size_t size) { - - int i; - char t[MAX_RESP_LENGTH+1]; - - buf[0] = '\0'; - for (i = 0; i < size; i++) { - snprintf(t, MAX_RESP_LENGTH, "%x ", input[i]); - strncat(buf, t, MAX_RESP_LENGTH); - } - - if (strlen(buf) > 0) - buf[strlen(buf)-1] = '\0'; /*Remove tailing blank*/ - - return snprintf(buf, MAX_RESP_LENGTH, "%s\n", buf); -} - -static ssize_t show_presnet_all_distinct(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - u8 i, value, reg; - u8 cpld_addr, num; - u8 _value[8]; - u64 *values = (u64 *)_value; - - values = 0; - mutex_lock(&data->update_lock); - while(i < data->sfp_num) - { - get_present_reg(data->model, i, &cpld_addr, ®, &num); - if(cpld_addr == client->addr) - value = cpld_read_internal(client, reg); - else - value = juniper_i2c_cpld_read(cpld_addr, reg); - - if (unlikely(value < 0)) { - goto exit; - } - - *values |= (value&((1<<(num))-1)) << i; - i += num; - } - mutex_unlock(&data->update_lock); - - *values = cpu_to_le64(*values); - return array_stringify(buf, _value, i); -exit: - mutex_unlock(&data->update_lock); - return value; -} - -static ssize_t show_presnet_all(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - struct cpld_sensor *sensor = to_cpld_sensor(devattr); - u8 i, values[MAX_RESP_LENGTH/8]; - - if (sensor->reg < 0) { - return show_presnet_all_distinct(dev, devattr, buf); - } - - mutex_lock(&data->update_lock); - for (i = 0; i < ((data->sfp_num+7)/8); i++) { - values[i] = cpld_read_internal(client, sensor->reg + i); - if (unlikely(values[i] < 0)) { - goto exit; - } - } - mutex_unlock(&data->update_lock); - return array_stringify(buf, values, i); - -exit: - mutex_unlock(&data->update_lock); - return values[i]; -} - -static ssize_t show_bit(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - int value; - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - struct cpld_sensor *sensor = to_cpld_sensor(devattr); - - mutex_lock(&data->update_lock); - value = cpld_read_internal(client, sensor->reg); - value = value & sensor->mask; - if (sensor->invert) - value = !value; - mutex_unlock(&data->update_lock); - - return snprintf(buf, PAGE_SIZE, "%x\n", value); -} - -static ssize_t set_1bit(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - long is_reset; - int value, status; - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - struct cpld_sensor *sensor = to_cpld_sensor(devattr); - u8 cpld_bit, reg; - - status = kstrtol(buf, 10, &is_reset); - if (status) { - return status; - } - reg = sensor->reg; - cpld_bit = sensor->mask; - mutex_lock(&data->update_lock); - value = cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - - if (sensor->invert) - is_reset = !is_reset; - - if (is_reset) { - value |= cpld_bit; - } - else { - value &= ~cpld_bit; - } - - status = cpld_write_internal(client, reg, value); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - return count; - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t set_byte(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - return access(dev, da, buf, count); -} - -static ssize_t access(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - int status; - u32 addr, val; - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - - if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { - return -EINVAL; - } - - if (addr > 0xFF || val > 0xFF) { - return -EINVAL; - } - - mutex_lock(&data->update_lock); - status = cpld_write_internal(client, addr, val); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - return count; - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static void juniper_i2c_cpld_add_client(struct i2c_client *client) -{ - struct cpld_client_node *node = - kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); - - if (!node) { - dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", - client->addr); - return; - } - node->client = client; - - mutex_lock(&list_lock); - list_add(&node->list, &cpld_client_list); - mutex_unlock(&list_lock); -} - -static void juniper_i2c_cpld_remove_client(struct i2c_client *client) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int found = 0; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client == client) { - found = 1; - break; - } - } - - if (found) { - list_del(list_node); - kfree(cpld_node); - } - - mutex_unlock(&list_lock); -} - -static int cpld_add_attribute(struct cpld_data *data, struct attribute *attr) -{ - int new_max_attrs = ++data->num_attributes + ATTR_ALLOC_SIZE; - void *new_attrs = krealloc(data->group.attrs, - new_max_attrs * sizeof(void *), - GFP_KERNEL); - if (!new_attrs) - return -ENOMEM; - data->group.attrs = new_attrs; - - - data->group.attrs[data->num_attributes-1] = attr; - data->group.attrs[data->num_attributes] = NULL; - - return 0; -} - -static void cpld_dev_attr_init(struct device_attribute *dev_attr, - const char *name, umode_t mode, - show_func show, store_func store) -{ - sysfs_attr_init(&dev_attr->attr); - dev_attr->attr.name = name; - dev_attr->attr.mode = mode; - dev_attr->show = show; - dev_attr->store = store; -} - -static struct cpld_sensor * add_sensor(struct cpld_data *data, - const char *name, - u8 reg, u8 mask, bool invert, - bool update, umode_t mode, - show_func get, store_func set) -{ - struct cpld_sensor *sensor; - struct device_attribute *a; - - sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL); - if (!sensor) - return NULL; - a = &sensor->attribute; - - snprintf(sensor->name, sizeof(sensor->name), name); - sensor->reg = reg; - sensor->mask = mask; - sensor->update = update; - sensor->invert = invert; - cpld_dev_attr_init(a, sensor->name, - mode, - get, set); - - if (cpld_add_attribute(data, &a->attr)) - return NULL; - - sensor->next = data->sensors; - data->sensors = sensor; - - return sensor; -} - -static int add_attributes_cmn(struct cpld_data *data, struct attrs **cmn) -{ - u8 reg, i ; - bool invert; - struct attrs *a; - struct base_attrs *b; - - if (NULL == cmn) - return -1; - - for (i = 0; cmn[i]; i++) - { - a = cmn[i]; - - reg = a->reg; - invert = a->invert; - - b = a->base; - if (NULL == b) - break; - - if (add_sensor(data, b->name, - reg, 0xff, invert, - true, b->mode, - b->get, b->set) == NULL) - { - return -ENOMEM; - } - } - return 0; -} - -static int add_attributes_portly(struct cpld_data *data, struct attrs **pa) -{ - char name[NAME_SIZE+1]; - int i, j; - u8 reg, mask, invert; - struct attrs *a; - struct base_attrs *b; - - if (NULL == pa) - return -1; - - - for (i = 0; pa[i]; i++) { - a = pa[i]; - - invert = a->invert; - b = a->base; - if (b == NULL) - break; - - for (j = 0; j < data->sfp_num; j++) - { - snprintf(name, NAME_SIZE, "%s_%d", b->name, j+1); - get_reg_bit(a->reg, j, ®, &mask); - - if (add_sensor(data, name, reg, mask, invert, - true, b->mode, b->get, b->set) == NULL) - { - return -ENOMEM; - } - } - } - return 0; -} - -static int add_attributes(struct i2c_client *client, - struct cpld_data *data) -{ - struct model_attrs *m = data->cmn_attr; - - if (m == NULL) - return -EINVAL; - - /* Common attributes.*/ - add_attributes_cmn(data, m->cmn); - - /* Port-wise attributes.*/ - add_attributes_portly(data, m->portly); - - return 0; -} - -static int juniper_i2c_cpld_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - int status; - struct cpld_data *data = NULL; - struct device *dev = &client->dev; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_dbg(dev, "i2c_check_functionality failed (0x%x)\n", client->addr); - return -EIO; - } - - data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); - if (!data) { - return -ENOMEM; - } - - data->model = dev_id->driver_data; - data->cmn_attr = &models_attr[data->model]; - get_sfp_spec(data->model, &data->sfp_num, &data->sfp_types); - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - data->dev = dev; - dev_info(dev, "chip found\n"); - - status = add_attributes(client, data); - if (status) - goto out_kfree; - - /* - * If there are no attributes, something is wrong. - * Bail out instead of trying to register nothing. - */ - if (!data->num_attributes) { - dev_err(dev, "No attributes found\n"); - status = -ENODEV; - goto out_kfree; - } - - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &data->group); - if (status) { - goto out_kfree; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } - - juniper_i2c_cpld_add_client(client); - dev_info(dev, "%s: cpld '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; -exit_remove: - sysfs_remove_group(&client->dev.kobj, &data->group); -out_kfree: - kfree(data->group.attrs); - return status; - -} - -static int juniper_i2c_cpld_remove(struct i2c_client *client) -{ - struct cpld_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &data->group); - kfree(data->group.attrs); - juniper_i2c_cpld_remove_client(client); - return 0; -} - -int juniper_i2c_cpld_read(u8 cpld_addr, u8 reg) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int ret = -EPERM; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client->addr == cpld_addr) { - ret = i2c_smbus_read_byte_data(cpld_node->client, reg); - break; - } - } - - mutex_unlock(&list_lock); - - return ret; -} -EXPORT_SYMBOL(juniper_i2c_cpld_read); - -int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int ret = -EIO; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client->addr == cpld_addr) { - ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); - break; - } - } - - mutex_unlock(&list_lock); - - return ret; -} -EXPORT_SYMBOL(juniper_i2c_cpld_write); - - -static const struct i2c_device_id juniper_i2c_cpld_id[] = { - { "cpld_as7712", AS7712_32X}, - { "cpld_as7716", AS7716_32X}, - { "cpld_qfx5210", qfx5210_64X}, - { "cpld_as7312", AS7312_54X}, - { "cpld_plain", PLAIN_CPLD}, - { }, -}; -MODULE_DEVICE_TABLE(i2c, juniper_i2c_cpld_id); - -static struct i2c_driver juniper_i2c_cpld_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "juniper_i2c_cpld", - }, - .probe = juniper_i2c_cpld_probe, - .remove = juniper_i2c_cpld_remove, - .id_table = juniper_i2c_cpld_id, - .address_list = normal_i2c, -}; - - -static int __init juniper_i2c_cpld_init(void) -{ - mutex_init(&list_lock); - return i2c_add_driver(&juniper_i2c_cpld_driver); -} - -static void __exit juniper_i2c_cpld_exit(void) -{ - i2c_del_driver(&juniper_i2c_cpld_driver); -} - -module_init(juniper_i2c_cpld_init); -module_exit(juniper_i2c_cpld_exit); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("juniper_i2c_cpld driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/ym2651y.c deleted file mode 100644 index 3ade5684107a..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/common/modules/ym2651y.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - * An hwmon driver for the 3Y Power YM-2651Y Power Module - * - * Tested and validated on Juniper QFX5210 - * Ciju Rajan K - * - * Copyright (C) 2014 Accton Technology Corporation. - * Brandon Chuang - * - * Based on ad7414.c - * Copyright 2006 Stefan Roese , DENX Software Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_FAN_DUTY_CYCLE 100 - -/* Addresses scanned - */ -static const unsigned short normal_i2c[] = { 0x58, 0x5b, I2C_CLIENT_END }; - -enum chips { - YM2651, - YM2401, - YM2851, -}; - -/* Each client has this additional data - */ -struct ym2651y_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 capability; /* Register value */ - u16 status_word; /* Register value */ - u8 fan_fault; /* Register value */ - u8 over_temp; /* Register value */ - u16 v_out; /* Register value */ - u16 i_out; /* Register value */ - u16 p_out; /* Register value */ - u16 temp; /* Register value */ - u16 fan_speed; /* Register value */ - u16 fan_duty_cycle[2]; /* Register value */ - u8 fan_dir[4]; /* Register value */ - u8 pmbus_revision; /* Register value */ - u8 mfr_id[10]; /* Register value */ - u8 mfr_model[10]; /* Register value */ - u8 mfr_revsion[3]; /* Register value */ - u16 mfr_vin_min; /* Register value */ - u16 mfr_vin_max; /* Register value */ - u16 mfr_iin_max; /* Register value */ - u16 mfr_iout_max; /* Register value */ - u16 mfr_pin_max; /* Register value */ - u16 mfr_pout_max; /* Register value */ - u16 mfr_vout_min; /* Register value */ - u16 mfr_vout_max; /* Register value */ -}; - -static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf); -static struct ym2651y_data *ym2651y_update_device(struct device *dev); -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); - -enum ym2651y_sysfs_attributes { - PSU_POWER_ON = 0, - PSU_TEMP_FAULT, - PSU_POWER_GOOD, - PSU_FAN1_FAULT, - PSU_FAN_DIRECTION, - PSU_OVER_TEMP, - PSU_V_OUT, - PSU_I_OUT, - PSU_P_OUT, - PSU_P_OUT_UV, /*In Unit of microVolt, instead of mini.*/ - PSU_TEMP1_INPUT, - PSU_FAN1_SPEED, - PSU_FAN1_DUTY_CYCLE, - PSU_PMBUS_REVISION, - PSU_MFR_ID, - PSU_MFR_MODEL, - PSU_MFR_REVISION, - PSU_MFR_VIN_MIN, - PSU_MFR_VIN_MAX, - PSU_MFR_VOUT_MIN, - PSU_MFR_VOUT_MAX, - PSU_MFR_IIN_MAX, - PSU_MFR_IOUT_MAX, - PSU_MFR_PIN_MAX, - PSU_MFR_POUT_MAX -}; - -/* sysfs attributes for hwmon - */ -static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); -static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); -static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); -static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); -static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); -static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_linear, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); -static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); -static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); -static SENSOR_DEVICE_ATTR(psu_pmbus_revision, S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); -static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); -static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); - -/*Duplicate nodes for lm-sensors.*/ -static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_linear, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_linear, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_linear, NULL, PSU_P_OUT_UV); -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); - -static struct attribute *ym2651y_attributes[] = { - &sensor_dev_attr_psu_power_on.dev_attr.attr, - &sensor_dev_attr_psu_temp_fault.dev_attr.attr, - &sensor_dev_attr_psu_power_good.dev_attr.attr, - &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, - &sensor_dev_attr_psu_over_temp.dev_attr.attr, - &sensor_dev_attr_psu_v_out.dev_attr.attr, - &sensor_dev_attr_psu_i_out.dev_attr.attr, - &sensor_dev_attr_psu_p_out.dev_attr.attr, - &sensor_dev_attr_psu_temp1_input.dev_attr.attr, - &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, - &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, - &sensor_dev_attr_psu_fan_dir.dev_attr.attr, - &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_id.dev_attr.attr, - &sensor_dev_attr_psu_mfr_model.dev_attr.attr, - &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, - /*Duplicate nodes for lm-sensors.*/ - &sensor_dev_attr_curr2_input.dev_attr.attr, - &sensor_dev_attr_in3_input.dev_attr.attr, - &sensor_dev_attr_power2_input.dev_attr.attr, - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_temp1_fault.dev_attr.attr, - NULL -}; - -static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : - sprintf(buf, "0\n"); -} - -static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u16 status = 0; - - switch (attr->index) { - case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ - status = (data->status_word & 0x40) ? 0 : 1; - break; - case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ - status = (data->status_word & 0x4) >> 2; - break; - case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ - status = (data->status_word & 0x800) ? 0 : 1; - break; - } - - return sprintf(buf, "%d\n", status); -} - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask) -{ - u16 valid_data = data & mask; - bool is_negative = valid_data >> (valid_bit - 1); - - return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; -} - -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; - long speed; - int error; - - error = kstrtol(buf, 10, &speed); - if (error) - return error; - - if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) - return -EINVAL; - - mutex_lock(&data->update_lock); - data->fan_duty_cycle[nr] = speed; - ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - u16 value = 0; - int exponent, mantissa; - int multiplier = 1000; - - switch (attr->index) { - case PSU_V_OUT: - value = data->v_out; - break; - case PSU_I_OUT: - value = data->i_out; - break; - case PSU_P_OUT_UV: - multiplier = 1000000; /*For lm-sensors, unit is micro-Volt.*/ - /*Passing through*/ - case PSU_P_OUT: - value = data->p_out; - break; - case PSU_TEMP1_INPUT: - value = data->temp; - break; - case PSU_FAN1_SPEED: - value = data->fan_speed; - multiplier = 1; - break; - case PSU_FAN1_DUTY_CYCLE: - value = data->fan_duty_cycle[0]; - multiplier = 1; - break; - case PSU_MFR_VIN_MIN: - value = data->mfr_vin_min; - break; - case PSU_MFR_VIN_MAX: - value = data->mfr_vin_max; - break; - case PSU_MFR_VOUT_MIN: - value = data->mfr_vout_min; - break; - case PSU_MFR_VOUT_MAX: - value = data->mfr_vout_max; - break; - case PSU_MFR_PIN_MAX: - value = data->mfr_pin_max; - break; - case PSU_MFR_POUT_MAX: - value = data->mfr_pout_max; - break; - case PSU_MFR_IOUT_MAX: - value = data->mfr_iout_max; - break; - case PSU_MFR_IIN_MAX: - value = data->mfr_iin_max; - break; - } - - exponent = two_complement_to_int(value >> 11, 5, 0x1f); - mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); - return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct ym2651y_data *data = ym2651y_update_device(dev); - - return sprintf(buf, "%d\n", data->over_temp >> 7); -} - -static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u8 *ptr = NULL; - - switch (attr->index) { - case PSU_FAN_DIRECTION: /* psu_fan_dir */ - ptr = data->fan_dir; - break; - case PSU_MFR_ID: /* psu_mfr_id */ - ptr = data->mfr_id; - break; - case PSU_MFR_MODEL: /* psu_mfr_model */ - ptr = data->mfr_model; - break; - case PSU_MFR_REVISION: /* psu_mfr_revision */ - ptr = data->mfr_revsion; - break; - default: - return 0; - } - - return sprintf(buf, "%s\n", ptr); -} - -static const struct attribute_group ym2651y_group = { - .attrs = ym2651y_attributes, -}; - -static int ym2651y_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - struct ym2651y_data *data; - int status; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_I2C_BLOCK)) { - status = -EIO; - goto exit; - } - - data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); - if (!data) { - status = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - dev_info(&client->dev, "chip found\n"); - - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); - if (status) { - goto exit_free; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } - - dev_info(&client->dev, "%s: psu '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; - -exit_remove: - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); -exit_free: - kfree(data); -exit: - - return status; -} - -static int ym2651y_remove(struct i2c_client *client) -{ - struct ym2651y_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); - kfree(data); - - return 0; -} - -static const struct i2c_device_id ym2651y_id[] = { - { "ym2651", YM2651 }, - { "ym2401", YM2401 }, - { "ym2851", YM2851 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, ym2651y_id); - -static struct i2c_driver ym2651y_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "ym2651", - }, - .probe = ym2651y_probe, - .remove = ym2651y_remove, - .id_table = ym2651y_id, - .address_list = normal_i2c, -}; - -static int ym2651y_read_byte(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -static int ym2651y_read_word(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_word_data(client, reg); -} - -static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) -{ - return i2c_smbus_write_word_data(client, reg, value); -} - -static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, - int data_len) -{ - int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); - - if (unlikely(result < 0)) - goto abort; - if (unlikely(result != data_len)) { - result = -EIO; - goto abort; - } - - result = 0; - -abort: - return result; -} - -struct reg_data_byte { - u8 reg; - u8 *value; -}; - -struct reg_data_word { - u8 reg; - u16 *value; -}; - -static struct ym2651y_data *ym2651y_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int i, status; - u8 command; - u8 fan_dir[5] = {0}; - struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, - {0x7d, &data->over_temp}, - {0x81, &data->fan_fault}, - {0x98, &data->pmbus_revision} - }; - struct reg_data_word regs_word[] = { {0x79, &data->status_word}, - {0x8b, &data->v_out}, - {0x8c, &data->i_out}, - {0x96, &data->p_out}, - {0x8d, &data->temp}, - {0x3b, &(data->fan_duty_cycle[0])}, - {0x3c, &(data->fan_duty_cycle[1])}, - {0x90, &data->fan_speed}, - {0xa0, &data->mfr_vin_min}, - {0xa1, &data->mfr_vin_max}, - {0xa2, &data->mfr_iin_max}, - {0xa3, &data->mfr_pin_max}, - {0xa4, &data->mfr_vout_min}, - {0xa5, &data->mfr_vout_max}, - {0xa6, &data->mfr_iout_max}, - {0xa7, &data->mfr_pout_max} - }; - - dev_dbg(&client->dev, "Starting ym2651 update\n"); - - /* Read byte data */ - for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { - status = ym2651y_read_byte(client, regs_byte[i].reg); - - if (status < 0) - { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_byte[i].reg, status); - *(regs_byte[i].value) = 0; - } - else { - *(regs_byte[i].value) = status; - } - } - - /* Read word data */ - for (i = 0; i < ARRAY_SIZE(regs_word); i++) { - status = ym2651y_read_word(client, regs_word[i].reg); - - if (status < 0) - { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_word[i].reg, status); - *(regs_word[i].value) = 0; - } - else { - *(regs_word[i].value) = status; - } - } - - /* Read fan_direction */ - command = 0xC3; - status = ym2651y_read_block(client, command, fan_dir, ARRAY_SIZE(fan_dir)-1); - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - - strncpy(data->fan_dir, fan_dir+1, ARRAY_SIZE(data->fan_dir)-1); - data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; - - /* Read mfr_id */ - command = 0x99; - status = ym2651y_read_block(client, command, data->mfr_id, - ARRAY_SIZE(data->mfr_id)-1); - data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; - - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - - /* Read mfr_model */ - command = 0x9a; - status = ym2651y_read_block(client, command, data->mfr_model, - ARRAY_SIZE(data->mfr_model)-1); - data->mfr_model[ARRAY_SIZE(data->mfr_model)-1] = '\0'; - - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - - /* Read mfr_revsion */ - command = 0x9b; - status = ym2651y_read_block(client, command, data->mfr_revsion, - ARRAY_SIZE(data->mfr_revsion)-1); - data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; - - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - -module_i2c_driver(ym2651y_driver); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); -MODULE_LICENSE("GPL"); - - diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/rules b/platform/broadcom/sonic-platform-modules-juniper/debian/rules index d8241eef744d..1a781912a544 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/rules +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/rules @@ -23,7 +23,6 @@ MODULE_DIRS:= qfx5210 qfx5200 MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service -PLATFORM_DIR := sonic_platform CONF_DIR := conf %: @@ -38,7 +37,7 @@ build: #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) (for mod in $(MODULE_DIRS); do \ make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules || exit 1; \ - $(PYTHON) $${mod}/setup.py build; \ + $(PYTHON) setup.py build; \ done) binary: binary-arch binary-indep @@ -65,7 +64,7 @@ binary-indep: cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ - $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + $(PYTHON) setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ done) # Resuming debhelper scripts dh_testroot diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install index 53692f8fd21b..741b6da7b36a 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install @@ -1,5 +1,3 @@ qfx5200/utils/juniper_qfx5200_util.py usr/local/bin qfx5200/utils/juniper_qfx5200_monitor.py usr/local/bin -qfx5200/sonic_platform/chassis.py usr/lib/python2.7/dist-packages/sonic_platform -qfx5200/sonic_platform/platform.py usr/lib/python2.7/dist-packages/sonic_platform qfx5200/service/qfx5200-platform-init.service etc/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c deleted file mode 100644 index 7b02e8a5bc74..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c +++ /dev/null @@ -1,661 +0,0 @@ -/* - * Juniper Networks TMC GPIO driver - * - * Copyright (C) 2020 Juniper Networks - * Author: Ashish Bhensdadia - * - * This driver implement the GPIO set/get functionality - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "jnx-tmc.h" - -#define TMC_GPIO_MAX_BITS_PER_REG 16 -#define TMC_GPIO_SFP_MAX_BITS_PER_REG 2 -#define TMC_GPIO_PTPCFG_MAX_BITS_PER_REG 8 - -#define TMC_GPIO_FIND_GROUP(gpio) \ - ((gpio) / TMC_GPIO_MAX_BITS_PER_REG) -#define TMC_GPIO_FIND_GPIO(gpio) \ - ((gpio) % TMC_GPIO_MAX_BITS_PER_REG) - -#define TMC_GPIO_SFP_FIND_GROUP(gpio) \ - ((gpio) / TMC_GPIO_SFP_MAX_BITS_PER_REG) -#define TMC_GPIO_SFP_FIND_GPIO(gpio) \ - ((gpio) % TMC_GPIO_SFP_MAX_BITS_PER_REG) - -#define TMC_GPIO_PTPCFG_FIND_GPIO(gpio) \ - ((gpio) % TMC_GPIO_PTPCFG_MAX_BITS_PER_REG) - -#define TMC_GPIO_MAX_NGPIO_PER_GROUP 320 - -#define TMC_PFE_QSFP_RESET_OFFSET 0x4 -#define TMC_PFE_QSFP_PRESENT_OFFSET 0x8 -#define TMC_PFE_QSFP_PHY_RESET_OFFSET 0x10 -#define TMC_PFE_QSFP_LPMOD_OFFSET 0x78 -#define TMC_PFE_QSFP_LED_CTRL_OFFSET 0x20 - -#define TMC_PFE_LANES_GREEN_LED_VALUE 0x3 -#define TMC_PFE_LANE0_GREEN_LED_BIT_POSITION 0 -#define TMC_PFE_LANE1_GREEN_LED_BIT_POSITION 2 -#define TMC_PFE_LANE2_GREEN_LED_BIT_POSITION 4 -#define TMC_PFE_LANE3_GREEN_LED_BIT_POSITION 6 - -#define TMC_PFE_LANES_BEACON_LED_VALUE 0x2 -#define TMC_PFE_LANE0_BEACON_LED_BIT_POSITION 0 -#define TMC_PFE_LANE1_BEACON_LED_BIT_POSITION 2 -#define TMC_PFE_LANE2_BEACON_LED_BIT_POSITION 4 -#define TMC_PFE_LANE3_BEACON_LED_BIT_POSITION 6 - -#define TMC_PFE_LANES_FAULT_LED_VALUE 0x1 -#define TMC_PFE_LANE0_FAULT_LED_BIT_POSITION 0 -#define TMC_PFE_LANE1_FAULT_LED_BIT_POSITION 2 -#define TMC_PFE_LANE2_FAULT_LED_BIT_POSITION 4 -#define TMC_PFE_LANE3_FAULT_LED_BIT_POSITION 6 - -#define TMC_PFE_SFPSB0_TX_DISABLE_OFFSET 0x0 -#define TMC_PFE_SFPSB0_LED_CTRL_OFFSET 0xC -#define TMC_PFE_SFPSB0_LED_ACTIVITY_OFFSET 0x14 -#define TMC_PFE_SFPSB0_PRESENT_OFFSET 0x18 -#define TMC_PFE_SFPSB0_LOSS_OFFSET 0x1C -#define TMC_PFE_SFPSB0_TX_FAULT_OFFSET 0x20 - -#define TMC_PFE_SFPSB1_TX_DISABLE_OFFSET 0x0 -#define TMC_PFE_SFPSB1_LED_CTRL_OFFSET 0x8 -#define TMC_PFE_SFPSB1_LED_ACTIVITY_OFFSET 0x10 -#define TMC_PFE_SFPSB1_PRESENT_OFFSET 0x14 -#define TMC_PFE_SFPSB1_LOSS_OFFSET 0x18 -#define TMC_PFE_SFPSB1_TX_FAULT_OFFSET 0x1C - -/* - * Index 4 to 15 is used for QSFP starting with - * QSFP_LED_LANE0_GREEN. To keep multibit set/get common - * starting SFP_LED_LANE0_GREEN with 16 which will avoid - * conflict with QSFP enums. - */ -#define SFP_LED_OP_START_INDEX 16 - -/* - * Used for off-setting SFP led op index - */ -#define SFP_LED_OP_OFFSET 0xB - -/* - * SFP slave blocks - */ -#define SFP_SLAVE0_BLOCK 0x1 -#define SFP_SLAVE1_BLOCK 0x2 - -/* - * each group represent the 16 gpios. - * QSFP_RST - QSFP_LPMODE - * each bit represent the one gpio - * exemple: bits[0:15] - bit0 - gpio0 - * QSFP_LED_LANE0_GREEN - QSFP_LED_LANE3_FAULT - * here, number represent the one gpio - * exemple: bits[0:1] - * 00 - gpio off, 01 - gpio on [ gpio0] - * 00 - gpio off, 10 - gpio on [ gpio1] - * 00 - gpio off, 11 - gpio on [ gpio2] - * - */ -enum { - QSFP_RST, - QSFP_PRESENT, - QSFP_PHY_RST, - QSFP_LPMOD, - QSFP_LED_LANE0_GREEN, - QSFP_LED_LANE1_GREEN, - QSFP_LED_LANE2_GREEN, - QSFP_LED_LANE3_GREEN, - QSFP_LED_LANE0_BEACON, - QSFP_LED_LANE1_BEACON, - QSFP_LED_LANE2_BEACON, - QSFP_LED_LANE3_BEACON, - QSFP_LED_LANE0_FAULT, - QSFP_LED_LANE1_FAULT, - QSFP_LED_LANE2_FAULT, - QSFP_LED_LANE3_FAULT, - TMC_PFE_GPIO_GROUP_MAX -}; - -enum sfp_op { - SFP_TX_DISABLE, - SFP_LED_ACTIVITY, - SFP_PRESENT, - SFP_SFP_LOS, - SFP_TX_FAULT, - SFP_LED_LANE0_GREEN = SFP_LED_OP_START_INDEX, - SFP_LED_LANE1_GREEN, - SFP_LED_LANE2_GREEN, - SFP_LED_LANE3_GREEN, - SFP_LED_LANE0_BEACON, - SFP_LED_LANE1_BEACON, - SFP_LED_LANE2_BEACON, - SFP_LED_LANE3_BEACON, - SFP_LED_LANE0_FAULT, - SFP_LED_LANE1_FAULT, - SFP_LED_LANE2_FAULT, - SFP_LED_LANE3_FAULT, - TMC_PFE_SFP_GPIO_GROUP_MAX -}; - -static const u32 group_offset[TMC_PFE_GPIO_GROUP_MAX] = { - TMC_PFE_QSFP_RESET_OFFSET, - TMC_PFE_QSFP_PRESENT_OFFSET, - TMC_PFE_QSFP_PHY_RESET_OFFSET, - TMC_PFE_QSFP_LPMOD_OFFSET, - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 GREEN */ - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 GREEN */ - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 GREEN */ - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 GREEN */ - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 BEACON */ - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 BEACON */ - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 BEACON */ - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 BEACON */ - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 FAULT */ - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 FAULT */ - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 FAULT */ - TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 FAULT */ -}; - -static const u32 sfp_slaveb0_group_offset[TMC_PFE_SFP_GPIO_GROUP_MAX] = { - TMC_PFE_SFPSB0_TX_DISABLE_OFFSET, - TMC_PFE_SFPSB0_LED_ACTIVITY_OFFSET, - TMC_PFE_SFPSB0_PRESENT_OFFSET, - TMC_PFE_SFPSB0_LOSS_OFFSET, - TMC_PFE_SFPSB0_TX_FAULT_OFFSET, - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 GREEN */ - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 GREEN */ - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 GREEN */ - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 GREEN */ - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 BEACON */ - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 BEACON */ - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 BEACON */ - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 BEACON */ - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 FAULT */ - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 FAULT */ - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 FAULT */ - TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 FAULT */ -}; - -static const u32 sfp_slaveb1_group_offset[TMC_PFE_SFP_GPIO_GROUP_MAX] = { - TMC_PFE_SFPSB1_TX_DISABLE_OFFSET, - TMC_PFE_SFPSB1_LED_ACTIVITY_OFFSET, - TMC_PFE_SFPSB1_PRESENT_OFFSET, - TMC_PFE_SFPSB1_LOSS_OFFSET, - TMC_PFE_SFPSB1_TX_FAULT_OFFSET, - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 GREEN */ - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 GREEN */ - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 GREEN */ - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 GREEN */ - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 BEACON */ - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 BEACON */ - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 BEACON */ - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 BEACON */ - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 FAULT */ - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 FAULT */ - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 FAULT */ - TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 FAULT */ -}; - -struct tmc_gpio_info { - int (*get)(struct gpio_chip *, unsigned int); - void (*set)(struct gpio_chip *, unsigned int, int); - int (*dirin)(struct gpio_chip *, unsigned int); - int (*dirout)(struct gpio_chip *, unsigned int, int); -}; - -struct tmc_gpio_chip { - const struct tmc_gpio_info *info; - void __iomem *base; - struct device *dev; - struct gpio_chip gpio; - int ngpio; - spinlock_t gpio_lock; /* gpio lock */ - int sfp_slave_block; -}; - -/* slave gpio max */ -static int gpio_max = 320; -module_param(gpio_max, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -MODULE_PARM_DESC(gpio_max, "Maximum number of gpio for SLAVE TMC GPIO"); - -/* - * generic bit operation functions - */ -static u32 tmc_gpio_reset_bits(u32 state, u32 val, u32 shift) -{ - state &= ~(val << shift); - return state; -}; - -static u32 tmc_gpio_set_bits(u32 state, u32 val, u32 shift) -{ - state |= (val << shift); - return state; -}; - -static u32 tmc_gpio_find_bits_val(u32 state, u32 shift, u32 mask) -{ - return ((state >> shift)) & mask; -}; - -#define to_tmc_chip(chip) \ - container_of((chip), struct tmc_gpio_chip, gpio) - -/* - * tmc_gpio_multiple_bitsop - Generic TMC GPIO multiple bits operation - */ -static void tmc_gpio_multiple_bitsop(struct tmc_gpio_chip *chip, - unsigned int gpiono, u32 group, u32 offset, bool set) -{ - u32 gpio_state, led_val, bit_shift; - unsigned long flags; - void __iomem *iobase; - - iobase = chip->base + offset; - - dev_dbg(chip->dev, "TMC GPIO multiple bitop group=%u, " - "gpiono=%u, offet:=%u, set=%u\n", group, gpiono, offset, set); - - spin_lock_irqsave(&chip->gpio_lock, flags); - - switch (group) { - case QSFP_LED_LANE0_GREEN: - case SFP_LED_LANE0_GREEN: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_GREEN_LED_VALUE; - bit_shift = TMC_PFE_LANE0_GREEN_LED_BIT_POSITION; - break; - case QSFP_LED_LANE1_GREEN: - case SFP_LED_LANE1_GREEN: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_GREEN_LED_VALUE; - bit_shift = TMC_PFE_LANE1_GREEN_LED_BIT_POSITION; - break; - case QSFP_LED_LANE2_GREEN: - case SFP_LED_LANE2_GREEN: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_GREEN_LED_VALUE; - bit_shift = TMC_PFE_LANE2_GREEN_LED_BIT_POSITION; - break; - case QSFP_LED_LANE3_GREEN: - case SFP_LED_LANE3_GREEN: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_GREEN_LED_VALUE; - bit_shift = TMC_PFE_LANE3_GREEN_LED_BIT_POSITION; - break; - case QSFP_LED_LANE0_BEACON: - case SFP_LED_LANE0_BEACON: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_BEACON_LED_VALUE; - bit_shift = TMC_PFE_LANE0_BEACON_LED_BIT_POSITION; - break; - case QSFP_LED_LANE1_BEACON: - case SFP_LED_LANE1_BEACON: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_BEACON_LED_VALUE; - bit_shift = TMC_PFE_LANE1_BEACON_LED_BIT_POSITION; - break; - case QSFP_LED_LANE2_BEACON: - case SFP_LED_LANE2_BEACON: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_BEACON_LED_VALUE; - bit_shift = TMC_PFE_LANE2_BEACON_LED_BIT_POSITION; - break; - case QSFP_LED_LANE3_BEACON: - case SFP_LED_LANE3_BEACON: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_BEACON_LED_VALUE; - bit_shift = TMC_PFE_LANE3_BEACON_LED_BIT_POSITION; - break; - case QSFP_LED_LANE0_FAULT: - case SFP_LED_LANE0_FAULT: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_FAULT_LED_VALUE; - bit_shift = TMC_PFE_LANE0_FAULT_LED_BIT_POSITION; - break; - case QSFP_LED_LANE1_FAULT: - case SFP_LED_LANE1_FAULT: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_FAULT_LED_VALUE; - bit_shift = TMC_PFE_LANE1_FAULT_LED_BIT_POSITION; - break; - case QSFP_LED_LANE2_FAULT: - case SFP_LED_LANE2_FAULT: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_FAULT_LED_VALUE; - bit_shift = TMC_PFE_LANE2_FAULT_LED_BIT_POSITION; - break; - case QSFP_LED_LANE3_FAULT: - case SFP_LED_LANE3_FAULT: - gpio_state = ioread32(iobase+(0x004*gpiono)); - led_val = TMC_PFE_LANES_FAULT_LED_VALUE; - bit_shift = TMC_PFE_LANE3_FAULT_LED_BIT_POSITION; - break; - - default: - spin_unlock_irqrestore(&chip->gpio_lock, flags); - return; - } - - if (set) { - gpio_state = tmc_gpio_reset_bits(gpio_state, 0x3, bit_shift); - gpio_state = tmc_gpio_set_bits(gpio_state, led_val, bit_shift); - } else { - gpio_state = tmc_gpio_reset_bits(gpio_state, 0x3, bit_shift); - } - - iowrite32(gpio_state, (iobase+(0x004*gpiono))); - - spin_unlock_irqrestore(&chip->gpio_lock, flags); - - return; -}; - -/* - * tmc_gpio_one_bitop - Generic TMC GPIO single bit operation - */ -static void tmc_gpio_one_bitop(struct tmc_gpio_chip *chip, - unsigned int bit, u32 offset, bool set) -{ - u32 gpio_state; - unsigned long flags; - void __iomem *iobase; - - iobase = chip->base + offset; - - dev_dbg(chip->dev, "TMC GPIO one bitop bit=%u, offset=%x, " - "set=%u\n", bit, offset, set); - - spin_lock_irqsave(&chip->gpio_lock, flags); - - gpio_state = ioread32(iobase); - if (set) - gpio_state |= BIT(bit); - else - gpio_state &= ~BIT(bit); - - iowrite32(gpio_state, iobase); - - spin_unlock_irqrestore(&chip->gpio_lock, flags); - - return; -} - -/* - * tmc_gpio_get_multiple_bitsop - Generic TMC get GPIO multiple bits operation - */ -static int tmc_gpio_get_multiple_bitsop(struct tmc_gpio_chip *chip, - unsigned int gpiono, u32 group, u32 offset) -{ - u32 gpio_state; - void __iomem *iobase; - - iobase = chip->base + offset; - - dev_dbg(chip->dev, "TMC GPIO get multiple bitsop group=%u, " - "gpiono=%u, offset=%u\n", group, gpiono, offset); - - switch (group) { - case QSFP_LED_LANE0_GREEN: - case SFP_LED_LANE0_GREEN: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_GREEN_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE0_GREEN_LED_BIT_POSITION, 0x3)); - case QSFP_LED_LANE1_GREEN: - case SFP_LED_LANE1_GREEN: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_GREEN_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE1_GREEN_LED_BIT_POSITION, 0x3)); - case QSFP_LED_LANE2_GREEN: - case SFP_LED_LANE2_GREEN: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_GREEN_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE2_GREEN_LED_BIT_POSITION, 0x3)); - case QSFP_LED_LANE3_GREEN: - case SFP_LED_LANE3_GREEN: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_GREEN_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE3_GREEN_LED_BIT_POSITION, 0x3)); - case QSFP_LED_LANE0_BEACON: - case SFP_LED_LANE0_BEACON: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_BEACON_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE0_BEACON_LED_BIT_POSITION, 0x3)); - case QSFP_LED_LANE1_BEACON: - case SFP_LED_LANE1_BEACON: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_BEACON_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE1_BEACON_LED_BIT_POSITION, 0x3)); - case QSFP_LED_LANE2_BEACON: - case SFP_LED_LANE2_BEACON: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_BEACON_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE2_BEACON_LED_BIT_POSITION, 0x3)); - case QSFP_LED_LANE3_BEACON: - case SFP_LED_LANE3_BEACON: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_BEACON_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE3_BEACON_LED_BIT_POSITION, 0x3)); - case QSFP_LED_LANE0_FAULT: - case SFP_LED_LANE0_FAULT: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_FAULT_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE0_FAULT_LED_BIT_POSITION, 0x3)); - case QSFP_LED_LANE1_FAULT: - case SFP_LED_LANE1_FAULT: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_FAULT_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE1_FAULT_LED_BIT_POSITION, 0x3)); - case QSFP_LED_LANE2_FAULT: - case SFP_LED_LANE2_FAULT: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_FAULT_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE2_FAULT_LED_BIT_POSITION, 0x3)); - case QSFP_LED_LANE3_FAULT: - case SFP_LED_LANE3_FAULT: - gpio_state = ioread32(iobase+(0x004*gpiono)); - return (TMC_PFE_LANES_FAULT_LED_VALUE == - tmc_gpio_find_bits_val(gpio_state, - TMC_PFE_LANE3_FAULT_LED_BIT_POSITION, 0x3)); - default: - return 0; - } -}; - -/* - * tmc_gpio_get - Read the specified signal of the GPIO device. - */ -static int tmc_gpio_get(struct gpio_chip *gc, unsigned int gpio) -{ - struct tmc_gpio_chip *chip = to_tmc_chip(gc); - unsigned int group = TMC_GPIO_FIND_GROUP(gpio); - unsigned int bit = TMC_GPIO_FIND_GPIO(gpio); - - if (group >= TMC_PFE_GPIO_GROUP_MAX) - return 0; - - switch (group) { - case QSFP_RST: - case QSFP_PRESENT: - case QSFP_PHY_RST: - case QSFP_LPMOD: - dev_dbg(chip->dev, "TMC GPIO get one bitop group=%u, gpio=%u, " - "bit=%u\n", group, gpio, bit); - return !!(ioread32(chip->base + group_offset[group]) - & BIT(bit)); - default: - return tmc_gpio_get_multiple_bitsop(chip, bit, group, group_offset[group]); - } -} - -/* - * tmc_gpio_set - Write the specified signal of the GPIO device. - */ -static void tmc_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) -{ - struct tmc_gpio_chip *chip = to_tmc_chip(gc); - unsigned int group = TMC_GPIO_FIND_GROUP(gpio); - unsigned int bit = TMC_GPIO_FIND_GPIO(gpio); - - if (group >= TMC_PFE_GPIO_GROUP_MAX) - return; - - switch (group) { - case QSFP_RST: - case QSFP_PRESENT: - case QSFP_PHY_RST: - case QSFP_LPMOD: - dev_dbg(chip->dev, "TMC GPIO one bitop group=%d\n", group); - tmc_gpio_one_bitop(chip, bit, group_offset[group], val); - break; - default: - tmc_gpio_multiple_bitsop(chip, bit, group, group_offset[group], val); - break; - } -} - -static struct tmc_gpio_info tmc_gpios[] = { - { - .get = tmc_gpio_get, - .set = tmc_gpio_set, - }, -}; - -static void tmc_gpio_setup(struct tmc_gpio_chip *sgc, int id) -{ - struct gpio_chip *chip = &sgc->gpio; - const struct tmc_gpio_info *info = sgc->info; - - chip->get = info->get; - chip->set = info->set; - chip->direction_input = info->dirin; - chip->direction_output = info->dirout; - chip->dbg_show = NULL; - chip->can_sleep = 0; - - if (id == 0) { - chip->base = 0; - } else if (id == 1) { - chip->base = (gpio_max * id); - } else { - chip->base = -1; - } - - chip->ngpio = sgc->ngpio; - chip->label = dev_name(sgc->dev); - chip->parent = sgc->dev; - chip->owner = THIS_MODULE; -} - -static int tmc_gpio_of_init(struct device *dev, - struct tmc_gpio_chip *chip) -{ - chip->info = &tmc_gpios[0]; - chip->ngpio = gpio_max; - - return 0; -} - -static int tmc_gpio_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct tmc_gpio_chip *chip; - struct resource *res; - int ret; - - const struct mfd_cell *cell = mfd_get_cell(pdev); - - dev_dbg(dev, "TMC GPIO probe\n"); - - chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - dev_info(dev, "TMC GPIO resource 0x%llx, %llu\n", - res->start, resource_size(res)); - - chip->base = devm_ioremap_nocache(dev, res->start, resource_size(res)); - if (!chip->base) - return -ENOMEM; - - ret = tmc_gpio_of_init(dev, chip); - if (ret) - return ret; - - chip->dev = dev; - spin_lock_init(&chip->gpio_lock); - - tmc_gpio_setup(chip, cell->id); - - ret = gpiochip_add(&chip->gpio); - if (ret) { - dev_err(dev, - "Failed to register TMC gpiochip : %d\n", ret); - return ret; - } - - platform_set_drvdata(pdev, chip); - dev_info(dev, "TMC GPIO registered at 0x%lx, gpiobase: %d\n", - (long unsigned)chip->base, chip->gpio.base); - - return 0; -} - -static int tmc_gpio_remove(struct platform_device *pdev) -{ - struct tmc_gpio_chip *chip = platform_get_drvdata(pdev); - - gpiochip_remove(&chip->gpio); - - return 0; -} - -static struct platform_driver tmc_gpio_driver = { - .driver = { - .name = "gpioslave-tmc", - .owner = THIS_MODULE, - }, - .probe = tmc_gpio_probe, - .remove = tmc_gpio_remove, -}; - -module_platform_driver(tmc_gpio_driver); - -MODULE_DESCRIPTION("Juniper Networks TMC FPGA GPIO driver"); -MODULE_AUTHOR("Ashish Bhensdadia "); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c new file mode 120000 index 000000000000..257a13181ee9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c @@ -0,0 +1 @@ +../../common/modules/gpio-tmc.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c deleted file mode 100644 index afd0311dc130..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c +++ /dev/null @@ -1,1107 +0,0 @@ -/* - * Juniper Networks TMC I2C Accelerator driver - * - * Copyright (C) 2020 Juniper Networks - * Author: Ashish Bhensdadia - * - * This driver implement the I2C functionality - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "jnx-tmc.h" - - -#define TMC_I2C_MASTER_I2C_SCAN_RESET_BIT BIT(31) - -#define TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET 0x0 -#define TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET 0x10 - -#define TMC_I2C_MSTR_AUTOMATION_I2C(adap, offset) \ - ((adap)->membase + offset) - -#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0 0x0 -#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8 0x8 -#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4 0x4 -#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C 0xC -#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10 0x10 -#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14 0x14 -#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18 0x18 -#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C 0x1C -#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_20 0x20 -#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_24 0x24 - -#define TMC_I2C_MSTR_I2C_DPMEM(adap, offset) \ - ((adap)->dpmbase + offset) - -#define TMC_I2C_TRANS_LEN 2 -#define tmc_iowrite(val, addr) iowrite32((val), (addr)) - -#define TMC_I2C_CTRL_GROUP(g) (((g) & 0xFF) << 8) -#define TMC_I2C_CTRL_WRCNT(w) (((w) & 0x3F) << 16) -#define TMC_I2C_CTRL_RDCNT(r) (((r) & 0x3F) << 16) -#define TMC_I2C_CTRL_DEVADDR(d) (((d) & 0xFF) << 8) -#define TMC_I2C_CTRL_OFFSET(o) ((o) & 0xFF) - - -#define TMC_I2C_MEM_CTRL_VLD BIT(31) - -#define TMC_I2C_CTRL_ERR(s) ((s) & 0x0F000000) -#define TMC_I2C_CTRL_DONE_BIT(s) ((s) & BIT(31)) -#define TMC_I2C_CTRL_STATUS_OK(s) (TMC_I2C_CTRL_DONE_BIT(s) & \ - TMC_I2C_CTRL_ERR(s)) -#define TMC_I2C_CTRL_DONE(s) (TMC_I2C_CTRL_DONE_BIT(s) == BIT(31)) - -#define TMC_I2C_STAT_INC(adap, s) (((adap)->stat.s)++) -#define TMC_I2C_STAT_INCN(adap, s, n) (((adap)->stat.s) += (n)) -#define TMC_I2C_GET_MASTER(tadap) ((tadap)->tctrl) - -#define TMC_I2C_READ 0x1 -#define TMC_I2C_WRITE 0x2 - -#define TMC_I2C_MASTER_LOCK(s, flags) \ -do { \ - spin_lock_irqsave(&(s)->lock, flags); \ -} while (0) - -#define TMC_I2C_MASTER_UNLOCK(s, flags) \ -do { \ - spin_unlock_irqrestore(&(s)->lock, flags); \ -} while (0) - -#define tmc_i2c_dbg(dev, fmt, args...) \ -do { \ - if (tmc_i2c_debug >= 1) \ - dev_err(dev, fmt, ## args); \ -} while (0) - - -/* pfe TMC i2c channel */ -static int pfe_channel = 32; -module_param(pfe_channel, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -MODULE_PARM_DESC(pfe_channel, "Maximum number of channel for PFE TMC"); - -/* chassid TMC i2c channel */ -static int chd_channel = 11; -module_param(chd_channel, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -MODULE_PARM_DESC(chd_channel, "Maximum number of channel for CHASSID TMC"); - -static u32 wr_index_to_oper[] = {0x01000000, 0x02000000, - 0x84000000, 0x85000000, 0x83000000}; -static u32 rd_index_to_oper[] = {0x08000000, 0x09000000, 0x0A000000, - 0x8B000000, 0x8C000000, 0x8D000000, 0x83000000}; - -struct tmc_i2c_adapter_stats { - u32 abort; - u32 go; - u32 mstr_rdy; - u32 mstr_busy; - u32 trans_compl; - u32 msg_cnt; - u32 rd_cnt; - u32 wr_cnt; - u32 byte_cnt; - u32 slave_timeo; - u32 scl_bus_loss; - u32 sda_bus_loss; - u32 ack_ptimeo; - u32 rd_cnt_0; - u32 rd_cnt_gt32; - u32 rst_tgt; - u32 rst_mstr; -}; - -struct tmc_i2c_adapter { - void __iomem *membase; - void __iomem *dpmbase; - struct i2c_adapter adap; - struct i2c_mux_core *muxc; - struct tmc_i2c_ctrl *tctrl; - int mux_channels; - int mux_select; - u32 i2c_delay; - int entries; - int master; - u32 control; - u32 speed; - bool done; - bool polling; - bool use_block; - wait_queue_head_t wait; - struct tmc_i2c_adapter_stats stat; -}; - -struct tmc_i2c_ctrl { - void __iomem *membase; - void __iomem *dpmbase; - struct i2c_adapter **adap; - struct device *dev; - int num_masters; - int mux_channels; - u32 i2c_delay; - u32 master_mask; - spinlock_t lock; /* master lock */ -}; - -/* - * Reset the Tmc I2C master - */ -static void tmc_i2c_reset_master(struct i2c_adapter *adap) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - struct tmc_i2c_ctrl *tmc = TMC_I2C_GET_MASTER(tadap); - u32 val, master = tadap->master; - unsigned long flags; - void __iomem *addr; - - dev_warn(&adap->dev, "Re-setting i2c master: %d\n", master); - - TMC_I2C_MASTER_LOCK(tmc, flags); - - addr = tmc->membase + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET; - val = ioread32(addr); - tmc_iowrite(val | (TMC_I2C_MASTER_I2C_SCAN_RESET_BIT), addr); - tmc_iowrite(val & ~(TMC_I2C_MASTER_I2C_SCAN_RESET_BIT), addr); - TMC_I2C_STAT_INC(tadap, rst_mstr); - - TMC_I2C_MASTER_UNLOCK(tmc, flags); -} - -/* - * check if the Tmc I2C master is ready - */ -static int tmc_i2c_mstr_wait_rdy(struct i2c_adapter *adap, u8 rw, u32 delay) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - unsigned long timeout; - u32 val; - - val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - if (val) { - tmc_iowrite(0x80000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - mdelay(5); - tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - } else { - tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - } - - if ((rw == TMC_I2C_READ) && (delay)) { - tmc_iowrite(0x80000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - return 0; - } - - timeout = jiffies + adap->timeout; - do { - val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - if (!val) - return 0; - - if (tadap->polling) { - usleep_range(50, 100); - } else { - tadap->done = false; - wait_event_timeout(tadap->wait, tadap->done, - adap->timeout); - } - } while (time_before(jiffies, timeout)); - - TMC_I2C_STAT_INC(tadap, mstr_busy); - - return -EBUSY; -} - -/* - * Wait for master completion - */ -static u32 tmc_i2c_mstr_wait_completion(struct i2c_adapter *adap, - u32 dp_entry_offset) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - u32 val; - - if (tadap->polling) { - /* Poll for the results */ - unsigned long timeout = jiffies + adap->timeout; - - do { - usleep_range(1000, 1200); - val = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, - dp_entry_offset)); - if (TMC_I2C_CTRL_DONE(val)) - break; - } while (time_before(jiffies, timeout)); - } else { - wait_event_timeout(tadap->wait, tadap->done, adap->timeout); - val = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, - dp_entry_offset)); - } - - return TMC_I2C_CTRL_STATUS_OK(val); -} - -/* - * TMC I2C delay read/write operation - */ -static int tmc_i2c_delay_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, - u32 addr, u32 offset, u32 len, u32 delay, u8 *buf) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - struct device *dev = &adap->dev; - int err, n; - u32 control = 0, data = 0; - u32 val; - - err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); - if (err < 0) { - tmc_i2c_reset_master(adap); - return err; - } - - TMC_I2C_STAT_INC(tadap, mstr_rdy); - - /* initialize the start address and mux */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); - - tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); - tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); - - /* populate delay */ - if (delay) { - if (delay > 1000) { - delay = delay/1000; - delay |= (1 << 16); - } - } - tmc_iowrite(delay, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); - tmc_iowrite(0x86000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); - - /* prepare control command */ - control |= TMC_I2C_CTRL_DEVADDR(addr); - control |= TMC_I2C_CTRL_OFFSET(offset); - - if (rw == TMC_I2C_WRITE) { - for (n = 0; n < len; n++) - data |= (buf[n] << ((len - 1 - n) * 8)); - tmc_iowrite(data, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); - control |= TMC_I2C_CTRL_WRCNT(len); - control |= wr_index_to_oper[len-1]; - dev_dbg(dev, "WR Data: [%#04x, %#04x, %#04x, %#04x]\n", - ((data >> 24) & 0xff), ((data >> 16) & 0xff), - ((data >> 8) & 0xff), (data & 0xff)); - - } else { - /* read */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); - control |= TMC_I2C_CTRL_RDCNT(len); - control |= rd_index_to_oper[len-1]; - } - - /* - * valid this transaction as well - */ - control |= TMC_I2C_MEM_CTRL_VLD; - - tadap->control = control; - - /* - * operation control command - */ - tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); - - /* - * End commands - */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); - tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); - tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_20)); - tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_24)); - - dev_dbg(dev, "Control (%#x): RD_WR_TYPE:%#02x, RD_WR_LEN:%d," - "Addr:%#01x, Offset:%#02x\n", control, - ((control >> 24) & 0x3F), ((control >> 16) & 0x3F), - ((control >> 8) & 0xff), ((control) & 0xff)); - - tadap->done = false; - - /* fire the transaction */ - tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - - TMC_I2C_STAT_INC(tadap, go); - - val = tmc_i2c_mstr_wait_completion(adap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10); - if (val) { - dev_err(&adap->dev, - "i2c transaction error (0x%08x)\n", val); - - /* stop the transaction */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - return -EIO; - } - - /* - * read a word of data - */ - if (rw == TMC_I2C_READ) { - data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); - for (n = 0; n < len; n++) - buf[n] = (data >> (n * 8)) & 0xff; - - dev_dbg(dev, "RD Data: [%#04x, %#04x, %#04x, %#04x]\n", - ((data >> 24) & 0xff), ((data >> 16) & 0xff), - ((data >> 8) & 0xff), (data & 0xff)); - - TMC_I2C_STAT_INC(tadap, rd_cnt); - } else { - /* write */ - TMC_I2C_STAT_INC(tadap, wr_cnt); - } - - /* stop the transaction */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - - return 0; - -} - -/* - *TMC I2C none delay Read/write opertion - */ -static int tmc_i2c_none_delay_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, - u32 addr, u32 offset, u32 len, u8 *buf) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - struct device *dev = &adap->dev; - int err, n; - u32 control = 0, data = 0; - u32 val; - - err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); - if (err < 0) { - tmc_i2c_reset_master(adap); - return err; - } - - TMC_I2C_STAT_INC(tadap, mstr_rdy); - - /* initialize the start address and mux */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); - - tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); - tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); - - - /* prepare control command */ - control |= TMC_I2C_CTRL_DEVADDR(addr); - control |= TMC_I2C_CTRL_OFFSET(offset); - - if (rw == TMC_I2C_WRITE) { - for (n = 0; n < len; n++) - data |= (buf[n] << (n * 8)); - tmc_iowrite(data, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); - control |= wr_index_to_oper[len-1]; - dev_dbg(dev, "WR Data: [%#04x, %#04x, %#04x, %#04x]\n", - ((data >> 24) & 0xff), ((data >> 16) & 0xff), - ((data >> 8) & 0xff), (data & 0xff)); - - } else { - /* read */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); - control |= rd_index_to_oper[len-1]; - } - - /* - * valid this transaction as well - */ - control |= TMC_I2C_MEM_CTRL_VLD; - - tadap->control = control; - - /* - * operation control command - */ - tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); - - /* - * End commands - */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); - tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); - tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); - tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); - - dev_dbg(dev, "Control (%#x): RD_WR_TYPE:%#02x, RD_WR_LEN:%d," - "Addr:%#01x, Offset:%#02x\n", control, - ((control >> 24) & 0x3F), ((control >> 16) & 0x3F), - ((control >> 8) & 0xff), ((control) & 0xff)); - - tadap->done = false; - - /* fire the transaction */ - tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - - TMC_I2C_STAT_INC(tadap, go); - - /* wait till transaction complete */ - val = tmc_i2c_mstr_wait_completion(adap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8); - if (val) { - dev_err(&adap->dev, - "i2c transaction error (0x%08x)\n", val); - - /* stop the transaction */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - return -EIO; - } - - /* - * read a word of data - */ - if (rw == TMC_I2C_READ) { - data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); - for (n = 0; n < len; n++) - buf[n] = (data >> (n * 8)) & 0xff; - - dev_dbg(dev, "RD Data: [%#04x, %#04x, %#04x, %#04x]\n", - ((data >> 24) & 0xff), ((data >> 16) & 0xff), - ((data >> 8) & 0xff), (data & 0xff)); - TMC_I2C_STAT_INC(tadap, rd_cnt); - } else { - /* write */ - TMC_I2C_STAT_INC(tadap, wr_cnt); - } - - /* stop the transaction */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - - return 0; -} - -/* - * TMC I2C read/write operation - */ -static int tmc_i2c_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, - u32 addr, u32 offset, u32 len, u8 *buf) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - u32 i2c_delay = tadap->i2c_delay; - - if (i2c_delay) { - return tmc_i2c_delay_rw_op(adap, rw, mux, addr, offset, - len, i2c_delay, buf); - } else { - return tmc_i2c_none_delay_rw_op(adap, rw, mux, addr, offset, - len, buf); - } -} - -static int tmc_i2c_calc_entries(int msglen) -{ - int entries = msglen / TMC_I2C_TRANS_LEN; - - return (entries += (msglen % TMC_I2C_TRANS_LEN) ? 1 : 0); -} - -static int tmc_i2c_block_read(struct i2c_adapter *adap, - struct i2c_msg *msgs, int num) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - struct device *dev = &adap->dev; - int curmsg, entries, len; - int offset = 0; - struct i2c_msg *msg; - int err, n = 0; - u8 rwbuf[4] = {0}; - - dev_dbg(dev, "Read i2c Block\n"); - - for (curmsg = 0, offset = 0; curmsg < num; curmsg++) { - msg = &msgs[curmsg]; - len = msg->len; - - if (msg->flags & I2C_M_RECV_LEN) - len = (I2C_SMBUS_BLOCK_MAX + 1); - - entries = tmc_i2c_calc_entries(len); - - if (msg->flags & I2C_M_RD) { - if (curmsg == 1 && ((msg->flags & I2C_M_RECV_LEN && - !(msgs[0].flags & I2C_M_RD)) || - (msg->len > TMC_I2C_TRANS_LEN))) { - offset = msgs[0].buf[0]; - } - - while (entries) { - err = tmc_i2c_rw_op(adap, TMC_I2C_READ, - tadap->mux_select, - msgs[0].addr, offset, - TMC_I2C_TRANS_LEN, rwbuf); - if (err < 0) - return err; - msg = &msgs[num - 1]; - msg->buf[n] = rwbuf[0]; - msg->buf[n+1] = rwbuf[1]; - n = n + TMC_I2C_TRANS_LEN; - offset = offset + TMC_I2C_TRANS_LEN; - entries--; - } - } - } - - return 0; -} - -/* - *TMC I2C SMB Read opertion - */ -static int tmc_i2c_smb_block_read_op(struct i2c_adapter *adap, u8 rw, u32 mux, - u32 addr, u32 offset, u32 len, u8 *buf) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - int err, i = 0; - u32 control = 0, data = 0; - u32 start_add; - - err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); - if (err < 0) { - tmc_i2c_reset_master(adap); - return err; - } - - TMC_I2C_STAT_INC(tadap, mstr_rdy); - - /* initialize the start address and mux */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); - - tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); - tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); - - - /* prepare control command */ - control |= TMC_I2C_CTRL_DEVADDR(addr); - control |= TMC_I2C_CTRL_OFFSET(offset); - - /* read */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); - control |= TMC_I2C_CTRL_RDCNT(len);; - control |= rd_index_to_oper[6]; - - tadap->control = control; - - /* - * operation control command - */ - tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); - - /* - * End commands - */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); - tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); - tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); - tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, - TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); - - tadap->done = false; - - /* fire the transaction */ - tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - - TMC_I2C_STAT_INC(tadap, go); - - /* - * read a block of data - */ - start_add = TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8; - while (len > 0) { - usleep_range(10000, 12000); - data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, start_add)); - buf[i] = data & 0xff; - buf[i + 1] = (data >> 8) & 0xff; - start_add = start_add + 8; - i = i + 2; - len = len - 2; - - TMC_I2C_STAT_INC(tadap, rd_cnt); - } - - /* stop the transaction */ - tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, - TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); - - return 0; -} - -static int tmc_i2c_smb_block_read(struct i2c_adapter *adap, - struct i2c_msg *msgs, int num) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - int curmsg, len; - int offset = 0; - struct i2c_msg *msg; - int err, i = 0; - u8 rwbuf[32] = {0}; - - for (curmsg = 0, offset = 0; curmsg < num; curmsg++) { - msg = &msgs[curmsg]; - len = msg->len; - - if (msg->flags & I2C_M_RECV_LEN) - len = (I2C_SMBUS_BLOCK_MAX + 1); - - if (msg->flags & I2C_M_RD) { - if ((curmsg == 1) && (msg->flags & I2C_M_RECV_LEN) && - !(msgs[0].flags & I2C_M_RD)) { - offset = msgs[0].buf[0]; - } - - err = tmc_i2c_smb_block_read_op(adap, TMC_I2C_READ, - tadap->mux_select, - msgs[0].addr, offset, - 32, rwbuf); - if (err < 0) { - return err; - } - msg = &msgs[num - 1]; - for (i = 0; i < len - 1; i++) { - msg->buf[i] = rwbuf[i]; - } - } - } - - return 0; -} - -static int tmc_i2c_mstr_xfer(struct i2c_adapter *adap, - struct i2c_msg *msgs, int num) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - struct device *dev = &adap->dev; - int n, curmsg, len = 0; - int err = 0; - struct i2c_msg *msg; - bool read; - u8 rwbuf[4] = {0}; - - dev_dbg(dev, "Num messages -> %d\n", num); - - /* - * Initialize all vars - */ - tadap->entries = 0; - tadap->use_block = false; - - for (curmsg = 0; curmsg < num; curmsg++) { - msg = &msgs[curmsg]; - dev_dbg(dev, "[%02d] %d bytes, flag %#02x buf %#02x\n", - curmsg, msg->len, msg->flags, msg->buf[0]); - if ((msg->len > TMC_I2C_TRANS_LEN) || - ((msg->flags & I2C_M_RD) && - (msg->flags & I2C_M_RECV_LEN))) { - /* If PEC is enabled len will come as 3 for a word read. - * We don't want to use block read for this case. - */ - if ((msg->flags & I2C_CLIENT_PEC) && - (msg->len == TMC_I2C_TRANS_LEN+1)) { - tadap->use_block = false; - } else { - tadap->use_block = true; - } - break; - } - } - - if (tadap->use_block) { - /* Read Block */ - if ((msg->flags & I2C_M_RD) && (msg->flags & I2C_M_RECV_LEN)) { - err = tmc_i2c_smb_block_read(adap, msgs, num); - } else { - err = tmc_i2c_block_read(adap, msgs, num); - } - if (err < 0) - return err; - } else { - read = msgs[num - 1].flags & I2C_M_RD; - for (curmsg = 0; curmsg < num; curmsg++) { - msg = &msgs[curmsg]; - len = msg->len; - - dev_dbg(dev, " [%02d] %s %d bytes addr %#02x, " - "flag %#02x, buf[0] %#02x\n", curmsg, - read ? "RD" : "WR", len, msg->addr, - msg->flags, msg->buf[0]); - - /* SMBus quick read/write command */ - if (len == 0 && curmsg == 0 && num == 1) { - if (read) { - len = 1; - } - break; - } - - if (curmsg == 0) { - if (!read) { - for (n = 1; n < len; n++) - rwbuf[n-1] = (msg->buf[n]); - len--; - } else { - /* read operation */ - continue; - } - } - } - - if (!read) { - /* write */ - err = tmc_i2c_rw_op(adap, TMC_I2C_WRITE, - tadap->mux_select, msgs[0].addr, - msgs[0].buf[0], len, rwbuf); - } else { - /* read */ - /* - * If PEC is enabled read only 2 bytes as expected in - * case of a word read instead of 3 to make it compatible - * with word write implementation. - */ - if (msg->flags & I2C_CLIENT_PEC && (len == TMC_I2C_TRANS_LEN + 1)) { - len--; - } - - err = tmc_i2c_rw_op(adap, TMC_I2C_READ, - tadap->mux_select, - msgs[0].addr, msgs[0].buf[0], - len, rwbuf); - msg = &msgs[num - 1]; - len = msg->len; - /* - * To avoid failure in PEC enabled case clear flag. - */ - if (len == TMC_I2C_TRANS_LEN + 1) { - msgs[num - 1].flags &= ~I2C_M_RD; - } - for (n = 0; n < len; n++) - msg->buf[n] = rwbuf[n]; - } - if (err < 0) - return err; - } - - TMC_I2C_STAT_INCN(tadap, msg_cnt, num); - - return num; -} - -static u32 tmc_i2c_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL - | I2C_FUNC_SMBUS_READ_BLOCK_DATA; -} - -static const struct i2c_algorithm tmc_i2c_algo = { - .master_xfer = tmc_i2c_mstr_xfer, - .functionality = tmc_i2c_func, -}; - -static int tmc_i2c_mux_group_sel(struct i2c_mux_core *muxc, u32 chan) -{ - struct tmc_i2c_adapter *tadap = i2c_mux_priv(muxc); - - dev_dbg(muxc->dev, "chan = %d\n", chan); - - if (!tadap || chan > TMC_I2C_MSTR_MAX_GROUPS) - return -ENODEV; - tadap->mux_select = chan; - - return 0; -} - -static int tmc_i2c_mux_init(struct i2c_adapter *adap) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - int chan, ret; - - tadap->muxc = i2c_mux_alloc(adap, &adap->dev, tadap->mux_channels, - 0, 0, tmc_i2c_mux_group_sel, NULL); - - if (!tadap->muxc) - return -ENOMEM; - - tadap->muxc->priv = tadap; - for (chan = 0; chan < tadap->mux_channels; chan++) { - ret = i2c_mux_add_adapter(tadap->muxc, 0, chan, 0); - if (ret) { - dev_err(&adap->dev, "Failed to add adapter %d\n", chan); - i2c_mux_del_adapters(tadap->muxc); - return ret; - } - } - - return 0; -} - -static struct i2c_adapter * -tmc_i2c_init_one(struct tmc_i2c_ctrl *tmc, - int master, int id) -{ - struct tmc_i2c_adapter *adapter; - struct device *dev = tmc->dev; - int err; - - adapter = devm_kzalloc(dev, sizeof(*adapter), GFP_KERNEL); - if (!adapter) - return ERR_PTR(-ENOMEM); - - init_waitqueue_head(&adapter->wait); - adapter->adap.owner = THIS_MODULE; - adapter->adap.algo = &tmc_i2c_algo; - adapter->adap.nr = -1; - adapter->adap.timeout = HZ / 5; - adapter->master = master; - adapter->mux_channels = tmc->mux_channels; - adapter->i2c_delay = tmc->i2c_delay; - adapter->membase = tmc->membase; - adapter->dpmbase = tmc->dpmbase; - adapter->polling = 1; - adapter->tctrl = tmc; - - i2c_set_adapdata(&adapter->adap, adapter); - snprintf(adapter->adap.name, sizeof(adapter->adap.name), - "%s:%d", dev_name(dev), master); - - adapter->adap.dev.parent = dev; - err = i2c_add_numbered_adapter(&adapter->adap); - if (err) - goto error; - - err = tmc_i2c_mux_init(&adapter->adap); - if (err) - goto err_remove; - - dev_dbg(dev, "Adapter[%02d-%02d]: " - "dpmbase: 0x%lx\n", id, master, - (unsigned long)adapter->dpmbase); - return &adapter->adap; - -err_remove: - i2c_del_adapter(&adapter->adap); -error: - return ERR_PTR(err); -} - -static void tmc_i2c_cleanup_one(struct i2c_adapter *adap) -{ - struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); - - i2c_mux_del_adapters(tadap->muxc); - i2c_del_adapter(adap); - -} - - -static int tmc_i2c_of_init(struct device *dev, - struct tmc_i2c_ctrl *tmc, int id) -{ - u32 mux_channels, master, num_masters = 0, master_mask = 0; - u32 i2c_delay = 0; - - if (!(master_mask & BIT(master))) - num_masters++; - master_mask |= BIT(master); - - if (id == 0) { - /* chassisd */ - mux_channels = chd_channel; - num_masters = 1; - i2c_delay = 0; - } else if (id == 1) { - /* pfe */ - mux_channels = pfe_channel; - num_masters = 1; - i2c_delay = 20; - } else { - return -EINVAL; - } - - tmc->adap = devm_kcalloc(dev, num_masters, - sizeof(struct i2c_adapter *), - GFP_KERNEL); - if (!tmc->adap) - return -ENOMEM; - - tmc->num_masters = num_masters; - tmc->master_mask = master_mask; - tmc->mux_channels = mux_channels; - tmc->i2c_delay = i2c_delay; - - return 0; -} - -static int tmc_i2c_probe(struct platform_device *pdev) -{ - int i, n, err; - struct resource *res; - struct i2c_adapter *adap; - struct device *dev = &pdev->dev; - struct tmc_i2c_ctrl *tmc; - - const struct mfd_cell *cell = mfd_get_cell(pdev); - - /* - * Allocate memory for the Tmc FPGA - */ - tmc = devm_kzalloc(dev, sizeof(*tmc), GFP_KERNEL); - if (!tmc) - return -ENOMEM; - - platform_set_drvdata(pdev, tmc); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - dev_info(dev, "Tmc I2C Accel resource 0x%llx, %llu\n", - res->start, resource_size(res)); - - tmc->membase = devm_ioremap_nocache(dev, res->start, - resource_size(res)); - if (!tmc->membase) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!res) - return -ENODEV; - - dev_info(dev, "Tmc I2C Mem resource 0x%llx, %llu\n", - res->start, resource_size(res)); - - tmc->dpmbase = devm_ioremap_nocache(dev, res->start, - resource_size(res)); - if (!tmc->dpmbase) - return -ENOMEM; - - tmc->dev = dev; - spin_lock_init(&tmc->lock); - - err = tmc_i2c_of_init(dev, tmc, cell->id); - if (err) - return err; - - dev_info(dev, "Tmc I2C Masters: %d\n", tmc->num_masters); - dev_info(dev, "Tmc I2C Delay: %d\n", tmc->i2c_delay); - - for (n = 0, i = 0; i < TMC_I2C_MASTER_NR_MSTRS; i++) { - if (tmc->master_mask & BIT(i)) { - adap = tmc_i2c_init_one(tmc, i, n); - if (IS_ERR(adap)) { - err = PTR_ERR(adap); - dev_err(dev, "Failed to initialize master " - "adapter %d: %d\n", i, err); - goto err_remove; - } - tmc->adap[n++] = adap; - } - } - - return 0; - -err_remove: - for (n--; n >= 0; n--) - tmc_i2c_cleanup_one(tmc->adap[n]); - return err; -} - -static int tmc_i2c_remove(struct platform_device *pdev) -{ - struct tmc_i2c_ctrl *tmc = platform_get_drvdata(pdev); - int i; - - /* Disable all masters */ - tmc_iowrite(0, tmc->membase + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET); - - for (i = 0; i < tmc->num_masters; i++) - tmc_i2c_cleanup_one(tmc->adap[i]); - - return 0; -} - -static struct platform_driver tmc_i2c_driver = { - .driver = { - .name = "i2c-tmc", - .owner = THIS_MODULE, - }, - .probe = tmc_i2c_probe, - .remove = tmc_i2c_remove, -}; - -module_platform_driver(tmc_i2c_driver); - -MODULE_DESCRIPTION("Juniper Networks TMC FPGA I2C Accelerator driver"); -MODULE_AUTHOR("Ashish Bhensdadia "); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c new file mode 120000 index 000000000000..6fc8e5f3b47b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c @@ -0,0 +1 @@ +../../common/modules/i2c-tmc.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c deleted file mode 100644 index ef36bca72e9d..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Juniper Networks RE-FPGA qfx platform specific driver - * - * Copyright (C) 2020 Juniper Networks - * Author: Ciju Rajan K - * - * This driver implements various features such as - * - ALARM led driver - * - Fan full speed reset control - * - FAN precense detection - * - FAN type detection - * - Any new QFX specific features which uses RE-FPGA - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NUM_LEDS 7 /* Max number of Alarm + FAN LEDs */ - -#define ALARM_MINOR_LED 0 -#define ALARM_MAJOR_LED 1 - -#define REFPGA_PCIE_RESET_CTRL 0x13 -#define REFPGA_PCIE_ALARM 0x33 -#define REFPGA_FAN0_CTRL_STAT 0x28 - -#define REFPGA_RESET_FAN_SPEED BIT(3) -#define REFPGA_OPER_TYPE BIT(0) -#define REFPGA_OPER_START BIT(1) -#define REFPGA_OPER_DONE BIT(2) - -#define TMC_REFPGA_ADDR_REG 0x0 /* TMC offset: 0x228 */ -#define TMC_REFPGA_DATA_REG 0x4 /* TMC offset: 0x22C */ -#define TMC_REFPGA_CTRL_REG 0x8 /* TMC offset: 0x230 */ - -#define TMC_REFPGA_READ_CMD 0x3 -#define TMC_REFPGA_WRITE_CMD 0x2 - -#define REFPGA_INTR_NR_GROUPS 1 -#define REFPGA_INTR_MAX_IRQS_PG 32 - -#define MAX_FANS 5 - -#define REFPGA_IRQ_MAX_BITS_PER_REG 32 - -#define POLL_INTERVAL 5000 - -#define AFI_MASK (0x01) -#define AFO_MASK (0x02) -#define AFI_AFO_MASK (0x03) -/* - * LED specific data structures - */ -struct refpga_led { - struct led_classdev lc; - struct work_struct work; - int blink; - int on; - int bit; - void __iomem *addr; -}; - -struct refpga_led_data { - int num_leds; - struct refpga_led *leds; -}; - -static DEFINE_MUTEX(alarm_led_lock); - -/* - * Common routines - */ -struct refpga_chip { - struct refpga_led_data *led; -}; - -static struct refpga_chip *refpga; - -static DEFINE_MUTEX(refpga_lock); - -static void __iomem *tmc_membase; - -static void wait_for_refpga_oper(void __iomem *base_addr) -{ - volatile u32 done = ~(-1); - unsigned long int timeout; - void __iomem *addr; - - addr = base_addr + (TMC_REFPGA_CTRL_REG); - /* - * Wait till the transaction is complete - */ - timeout = jiffies + msecs_to_jiffies(100); - - do { - usleep_range(50, 100); - done = ioread32(addr); - if (done & (REFPGA_OPER_DONE)) - break; - } while(time_before(jiffies, timeout)); -} -static u32 refpga_read(void __iomem *base_addr, u32 refpga_offset) -{ - u32 value; - - mutex_lock(&refpga_lock); - iowrite32(refpga_offset, base_addr + (TMC_REFPGA_ADDR_REG)); - iowrite32(TMC_REFPGA_READ_CMD, base_addr + (TMC_REFPGA_CTRL_REG)); - wait_for_refpga_oper(base_addr); - value = ioread32(base_addr + (TMC_REFPGA_DATA_REG)); - mutex_unlock(&refpga_lock); - - return value; -} - -static void refpga_write(void __iomem *base_addr, u32 refpga_offset, u32 val) -{ - mutex_lock(&refpga_lock); - iowrite32(refpga_offset, base_addr + (TMC_REFPGA_ADDR_REG)); - iowrite32(val, base_addr + (TMC_REFPGA_DATA_REG)); - iowrite32(TMC_REFPGA_WRITE_CMD, base_addr + (TMC_REFPGA_CTRL_REG)); - wait_for_refpga_oper(base_addr); - mutex_unlock(&refpga_lock); -} - -static bool get_fan_presense(u8 idx) -{ - u8 value = 0x00; - u8 offset = REFPGA_FAN0_CTRL_STAT; - bool ret = 0; - - value = refpga_read(tmc_membase, (offset + (idx * 2))); - /* - * Get the last two bits of REFPGA_FANx_CTRL_STAT. - * REFPGA_FANx_CTRL_STAT register of REFPGA gives the fan airflow - * status. There are 5 fans in QFX5200. Last two bits give the AFI - * & AFO status. If any of these bits are set, fan is present. - */ - value = (value & BIT(0)) | (value & BIT(1)); - if (value) - ret = 1; - - return ret; -} - -static int get_fan_type(u8 idx) -{ - u8 value = 0x00; - u8 offset = REFPGA_FAN0_CTRL_STAT; - int ret = -1; - - value = refpga_read(tmc_membase, (offset + (idx * 2))); - /* - * Get the last two bits of REFPGA_FANx_CTRL_STAT. - * REFPGA_FANx_CTRL_STAT register of REFPGA gives the fan airflow - * status. There are 5 fans in QFX5200. Last two bits give the AFI - * & AFO status. If bit1 is set, it's AFO and if bit 0 is set, - * it's AFI. - * - * This function will return '1' for AFO, '0' for AFI, and '-1' - * if there is no fan or if both AFI & AFO bits are set. - */ - value &= AFI_AFO_MASK; - - switch(value) { - case AFI_MASK: - ret = 0; - break; - case AFO_MASK: - ret = 1; - break; - default: - ret = -1; - break; - }; - - return ret; -} - -enum sysfs_fan_attributes { - FAN0_PRESENT, - FAN1_PRESENT, - FAN2_PRESENT, - FAN3_PRESENT, - FAN4_PRESENT, -}; - -enum sysfs_fan_type_attributes { - FAN0_TYPE, - FAN1_TYPE, - FAN2_TYPE, - FAN3_TYPE, - FAN4_TYPE, -}; - -/* - * The sysfs files will be present in this path - * /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan*_present - * /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan*_type - */ - -#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ - static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, refpga_fan_presense_show, NULL, FAN##index##_PRESENT) -#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr - -#define DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(index) \ - static SENSOR_DEVICE_ATTR(fan##index##_type, S_IRUGO, refpga_fan_type_show, NULL, FAN##index##_TYPE) -#define DECLARE_FAN_TYPE_ATTR(index) &sensor_dev_attr_fan##index##_type.dev_attr.attr - -static ssize_t refpga_fan_presense_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); - - return sprintf(buf, "%d\n", get_fan_presense(s_attr->index)); - -} - -static ssize_t refpga_fan_type_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); - - return sprintf(buf, "%d\n", get_fan_type(s_attr->index)); - -} - -DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(0); -DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); -DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); -DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); -DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); - -DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(0); -DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(1); -DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(2); -DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(3); -DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(4); - -static struct attribute *refpga_fan_attrs[] = { - DECLARE_FAN_PRESENT_ATTR(0), - DECLARE_FAN_PRESENT_ATTR(1), - DECLARE_FAN_PRESENT_ATTR(2), - DECLARE_FAN_PRESENT_ATTR(3), - DECLARE_FAN_PRESENT_ATTR(4), - DECLARE_FAN_TYPE_ATTR(0), - DECLARE_FAN_TYPE_ATTR(1), - DECLARE_FAN_TYPE_ATTR(2), - DECLARE_FAN_TYPE_ATTR(3), - DECLARE_FAN_TYPE_ATTR(4), - NULL -}; - -static struct attribute_group refpga_fan_attr_group = { - .attrs = refpga_fan_attrs, -}; - -/* - * There is only a single ALARM led in QFX5200 and that - * is used for both Major & Minor alarm indicator. - * These are represented by two different bits in RE-FPGA - * PCIE_ALARM register. Only one of the bit (either Red or - * Yellow) should be set a time. If both the bits are set, - * it's an undefined behaviour. - * - * The following table describes how the conditions are - * handled in the driver as there can be both Major & Minor - * alarms can be triggered from userspace. - * - * Major Minor Colour - * - * 0 0 Nil - * 0 1 Yellow - * 1 1 Red - * 1 0 Red - * - */ -static void manage_alarm_led(void __iomem *addr, int led_type, int value) -{ - static int alarm_major = 0, alarm_minor = 0; - u32 reg = 0x0; - - mutex_lock(&alarm_led_lock); - reg = refpga_read(addr, REFPGA_PCIE_ALARM); - - (led_type == ALARM_MAJOR_LED) ? - ((value == 1) ? (alarm_major = 1) : (alarm_major = 0)) : - ((value == 1) ? (alarm_minor = 1) : (alarm_minor = 0)); - if (alarm_major) { - reg &= ~BIT(ALARM_MINOR_LED); - reg |= BIT(ALARM_MAJOR_LED); - } else { - if (alarm_minor) { - reg &= ~BIT(ALARM_MAJOR_LED); - reg |= BIT(ALARM_MINOR_LED); - } else { - reg &= ~BIT(ALARM_MINOR_LED); - reg &= ~BIT(ALARM_MAJOR_LED); - } - } - refpga_write(addr, REFPGA_PCIE_ALARM, reg); - mutex_unlock(&alarm_led_lock); -} - -static void manage_fan_led(void __iomem *addr, int fan_slot, int value) -{ - u8 offset = REFPGA_FAN0_CTRL_STAT + (fan_slot * 2); - u32 reg = 0x0; - - reg = refpga_read(addr, offset); - if(value) { - /* Turn on s/w control */ - reg = reg | BIT(4); - /* Turn off green led */ - reg &= ~BIT(5); - /* Turn on yellow led & make it blink */ - reg |= (BIT(6) | BIT(7)); - } else { - /* Clear yellow led & stop blink */ - reg &= ~(BIT(6) | BIT(7)); - /* Stop s/w control */ - reg &= ~BIT(4); - } - refpga_write(addr, offset, reg); -} - -static void refpga_led_work(struct work_struct *work) -{ - struct refpga_led *led = container_of(work, struct refpga_led, work); - void __iomem *addr; - - addr = led->addr; - - if(strstr(led->lc.name, "fan")) - manage_fan_led(addr, led->bit, led->on); - else - manage_alarm_led(addr, led->bit, led->on); -} - -static void refpga_led_brightness_set(struct led_classdev *lc, - enum led_brightness brightness) -{ - struct refpga_led *led = container_of(lc, struct refpga_led, lc); - - led->on = (brightness != LED_OFF); - led->blink = 0; /* always turn off hw blink on brightness_set() */ - schedule_work(&led->work); -} - -struct led_table -{ - const char *name; - int reg; -}; - -static struct led_table qfx5200_led_data[] = { - { - .name = "alarm-minor", - .reg = 0, - }, - { - .name = "alarm-major", - .reg = 1, - }, - { - .name = "fan0-fault", - .reg = 0, - }, - { - .name = "fan1-fault", - .reg = 1, - }, - { - .name = "fan2-fault", - .reg = 2, - }, - { - .name = "fan3-fault", - .reg = 3, - }, - { - .name = "fan4-fault", - .reg = 4, - } -}; - -static int refpga_led_init_one(struct device *dev, - struct refpga_led_data *ild, - int num) -{ - struct refpga_led *led; - int ret = 0; - - led = &ild->leds[num]; - led->addr = tmc_membase; - - led->lc.name = qfx5200_led_data[num].name; - led->bit = qfx5200_led_data[num].reg; - led->lc.brightness = LED_OFF; - led->lc.brightness_set = refpga_led_brightness_set; - - ret = devm_led_classdev_register(dev, &led->lc); - if (ret) { - dev_err(dev, "devm_led_classdev_register failed\n"); - return ret; - } - - INIT_WORK(&led->work, refpga_led_work); - - return 0; -} - -static int refpga_led_qfx5200_init(struct device *dev, struct refpga_led_data *ild) -{ - int ret = 0, idx = 0; - - - if (!dev->parent) { - dev_err(dev, "dev->parent is null\n"); - return -ENODEV; - } - - ild->num_leds = NUM_LEDS; - ild->leds = devm_kzalloc(dev, sizeof(struct refpga_led) * NUM_LEDS, - GFP_KERNEL); - if (!ild->leds) { - dev_err(dev, "LED allocation failed\n"); - return -ENOMEM; - } - - for(idx=0; idxdev; - struct refpga_led_data *ild; - int ret; - - ild = devm_kzalloc(dev, sizeof(*ild), GFP_KERNEL); - if (!ild) { - dev_err(dev, "ild allocation failed\n"); - return -ENOMEM; - } - - ret = refpga_led_qfx5200_init(dev, ild); - if (ret < 0) - return ret; - - refpga->led = ild; - - return 0; -} - -static int jnx_refpga_led_remove(struct platform_device *pdev) -{ - struct refpga_chip *drv_data = platform_get_drvdata(pdev); - struct refpga_led_data *ild = drv_data->led; - int i; - - for (i = 0; i < ild->num_leds; i++) { - devm_led_classdev_unregister(&pdev->dev, &ild->leds[i].lc); - cancel_work_sync(&ild->leds[i].work); - } - if (ild) { - if (ild->leds) - devm_kfree(&pdev->dev, ild->leds); - devm_kfree(&pdev->dev, ild); - } - return 0; -} - -static void reset_fan_full_speed(struct device *dev) -{ - u32 val = ~(-1), tmp = ~(-1); - - /* - * Reading the REFPGA_PCIE_RESET_CTRL register - */ - val = refpga_read(tmc_membase, REFPGA_PCIE_RESET_CTRL); - /* - * Clearing the fan full_speed bit - */ - val &= ~(REFPGA_RESET_FAN_SPEED); - /* - * Writing the REFPGA_PCIE_RESET_CTRL register - */ - refpga_write(tmc_membase, REFPGA_PCIE_RESET_CTRL, val); - /* - * Reading the REFPGA_PCIE_RESET_CTRL register - */ - tmp = refpga_read(tmc_membase, REFPGA_PCIE_RESET_CTRL); - dev_info(dev, "After resetting fan full speed control: %X\n", tmp); -} - -static int jnx_refpga_tmc_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct resource *res; - int ret = 0; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "resource allocation failed\n"); - return -ENODEV; - } - - tmc_membase = devm_ioremap_nocache(dev, res->start, resource_size(res)); - if (!tmc_membase) { - dev_err(dev, "ioremap failed\n"); - return -ENOMEM; - } - - refpga = devm_kzalloc(dev, sizeof(*refpga), GFP_KERNEL); - if (!refpga) { - dev_err(dev, "refpga memory allocation failed\n"); - return -ENOMEM; - } - - reset_fan_full_speed(dev); - - ret = jnx_refpga_led_probe(pdev); - if (ret != 0) { - dev_err(dev, "Refpga LED probe failed\n"); - return ret; - } - - dev_info(dev, "Refpga LED probe successful: TMC memoy base: %p\n", - tmc_membase); - - ret = sysfs_create_group(&dev->kobj, &refpga_fan_attr_group); - if (ret != 0) { - dev_err(dev, "sysfs_create_group failed: %d\n", ret); - return ret; - } - - platform_set_drvdata(pdev, refpga); - - return 0; -} - -static int jnx_refpga_tmc_remove(struct platform_device *pdev) -{ - jnx_refpga_led_remove(pdev); - sysfs_remove_group(&pdev->dev.kobj, &refpga_fan_attr_group); - - return 0; -} - -static struct platform_driver jnx_refpga_tmc_driver = { - .driver = { - .name = "refpga-tmc", - .owner = THIS_MODULE, - }, - .probe = jnx_refpga_tmc_probe, - .remove = jnx_refpga_tmc_remove, -}; - -static int __init jnx_refpga_tmc_driver_init(void) -{ - int ret = -1; - - ret = platform_driver_register(&jnx_refpga_tmc_driver); - - return ret; - -} - -static void __exit jnx_refpga_tmc_driver_exit(void) -{ - platform_driver_unregister(&jnx_refpga_tmc_driver); -} - -module_init(jnx_refpga_tmc_driver_init); -module_exit(jnx_refpga_tmc_driver_exit); - -MODULE_DESCRIPTION("Juniper Networks REFPGA / TMC driver"); -MODULE_AUTHOR("Ciju Rajan K "); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c new file mode 120000 index 000000000000..355eda2afdf7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c @@ -0,0 +1 @@ +../../common/modules/jnx-refpga-tmc.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c deleted file mode 100644 index 833164bfed63..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Juniper Networks TMC-FPGA MFD Core driver for qfx platform - * - * Copyright (c) 2020, Juniper Networks - * Author: Ashish Bhensdadia - * - * This driver implement the resource publish for below devices - * - I2C - * - GPIO - * - RE FPGA - * - PSU - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "jnx-tmc.h" - -#define TMC_DO_SCRATCH_TEST 1 - -/* - * TMC FPGA Device IDs - */ -#define PCI_VENDOR_ID_JUNIPER 0x1304 - -#define PCI_DEVICE_ID_JNX_TMC_CHD 0x007B -#define PCI_DEVICE_ID_JNX_TMC_PFE 0x007C - -/* - * TMC resources - */ -static struct resource tmc_resource_i2c[] = { - /* I2C AUTOMATION Block */ - { - .name = "i2c-tmc", - .start = TMC_I2C_AUTOMATION_I2C_CONTROL_START, - .end = TMC_I2C_AUTOMATION_I2C_CONTROL_END, - .flags = IORESOURCE_MEM, - }, - - /* I2C DPMEM */ - { - .name = "i2c-tmc-mem", - .start = TMC_I2C_DPMEM_ENTRY_START, - .end = TMC_I2C_DPMEM_ENTRY_END, - .flags = IORESOURCE_MEM, - }, -}; - -#define TMC_RES_I2C_NR ARRAY_SIZE(tmc_resource_i2c) - -/* - * LED resources - */ -static struct resource tmc_resource_leds[] = { - { - .name = "leds-tmc", - .start = TMC_LED_CONTROL_START, - .end = TMC_LED_CONTROL_END, - .flags = IORESOURCE_MEM, - }, -}; - -#define TMC_RES_LEDS_NR ARRAY_SIZE(tmc_resource_leds) - -/* - * TMC RE-FPGA devices - */ -static struct resource tmc_resource_refpga[] = { - { - .name = "refpga-tmc", - .start = TMC_REFPGA_ACCESS_START, - .end = TMC_REFPGA_ACCESS_END, - .flags = IORESOURCE_MEM, - }, -}; - -#define TMC_RES_REFPGA_NR ARRAY_SIZE(tmc_resource_refpga) - -static struct resource tmc_resource_gpioslave0[] = { - /* SLAVE0 Block */ - { - .name = "gpioslave-tmc", - .start = TMC_GPIO_SLAVE0_START, - .end = TMC_GPIO_SLAVE0_END, - .flags = IORESOURCE_MEM, - } -}; - -#define TMC_RES_GPIOSLAVE0_NR ARRAY_SIZE(tmc_resource_gpioslave0) - -static struct resource tmc_resource_gpioslave1[] = { - /* SLAVE1 Block */ - { - .name = "gpioslave-tmc", - .start = TMC_GPIO_SLAVE1_START, - .end = TMC_GPIO_SLAVE1_END, - .flags = IORESOURCE_MEM, - } -}; - -#define TMC_RES_GPIOSLAVE1_NR ARRAY_SIZE(tmc_resource_gpioslave1) - -static struct resource tmc_resource_psu[] = { - /* PSU Block */ - { - .name = "psu-tmc", - .start = TMC_PSU_START, - .end = TMC_PSU_END, - .flags = IORESOURCE_MEM, - } -}; - -#define TMC_RES_PSU_NR ARRAY_SIZE(tmc_resource_psu) - -/* - * CHASSISD TMC MFD devices - */ -static struct mfd_cell chassisd_tmc_mfd_devs[] = { - { - .name = "i2c-tmc", - .num_resources = ARRAY_SIZE(tmc_resource_i2c), - .resources = &tmc_resource_i2c[0], - .of_compatible = "jnx,i2c-tmc", - .id = 0, - }, - { - .name = "leds-tmc", - .num_resources = ARRAY_SIZE(tmc_resource_leds), - .resources = &tmc_resource_leds[0], - .of_compatible = "jnx,leds-tmc", - .id = 0, - }, - { - .name = "refpga-tmc", - .num_resources = ARRAY_SIZE(tmc_resource_refpga), - .resources = &tmc_resource_refpga[0], - .of_compatible = "jnx,refpga-tmc", - .id = 0, - }, - { - .name = "psu-tmc", - .num_resources = ARRAY_SIZE(tmc_resource_psu), - .resources = &tmc_resource_psu[0], - .of_compatible = "jnx,psu-tmc", - .id = 0, - }, -}; - -/* - * PFE TMC MFD devices - */ -static struct mfd_cell pfe_tmc_mfd_devs[] = { - { - .name = "i2c-tmc", - .num_resources = ARRAY_SIZE(tmc_resource_i2c), - .resources = &tmc_resource_i2c[0], - .of_compatible = "jnx,i2c-tmc", - .id = 1, - }, - { - .name = "gpioslave-tmc", - .num_resources = ARRAY_SIZE(tmc_resource_gpioslave0), - .resources = &tmc_resource_gpioslave0[0], - .of_compatible = "jnx,gpioslave-tmc", - .id = 0, - }, - { - .name = "gpioslave-tmc", - .num_resources = ARRAY_SIZE(tmc_resource_gpioslave1), - .resources = &tmc_resource_gpioslave1[0], - .of_compatible = "jnx,gpioslave-tmc", - .id = 1, - }, -}; - - -struct tmc_fpga_data { - void __iomem *membase; - struct pci_dev *pdev; - - u32 major; /* Device id & Major version*/ - u32 minor; /* Minor version */ - - u32 optic_cpld_major; /* optic cpld major version */ - u32 optic_cpld_minor; /* optic cpld minor version */ - u32 optic_cpld_devid; /* optic cpld device id */ -}; - -/* sysfs entries */ -static ssize_t major_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct tmc_fpga_data *tmc = dev_get_drvdata(dev); - - return sprintf(buf, "0x%02X_%06X\n", - (tmc->major >> 24) & 0xff, - tmc->major & 0xffffff); -} - -static ssize_t minor_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct tmc_fpga_data *tmc = dev_get_drvdata(dev); - - return sprintf(buf, "%02X\n", (tmc->minor) & 0xff); -} - -static ssize_t optic_cpld_major_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct tmc_fpga_data *tmc = dev_get_drvdata(dev); - - return sprintf(buf, "%01X\n", tmc->optic_cpld_major & 0xf); -} - -static ssize_t optic_cpld_devid_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct tmc_fpga_data *tmc = dev_get_drvdata(dev); - - return sprintf(buf, "%01X\n", - (tmc->optic_cpld_major >> 4) & 0xf); -} - -static ssize_t optic_cpld_minor_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct tmc_fpga_data *tmc = dev_get_drvdata(dev); - - return sprintf(buf, "%02X\n", tmc->optic_cpld_minor & 0xff); -} - -static ssize_t set_sys_shutdown(struct device *dev, - struct device_attribute *devattr, - const char *buf, - size_t len) -{ - - struct tmc_fpga_data *tmc = dev_get_drvdata(dev); - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - - if (val != 1) - return -EINVAL; - - /* Unlock the shutdown register */ - iowrite32(0x12345678, tmc->membase + TMC_SYS_SHUTDOWN_LOCK); - iowrite32(0x1, tmc->membase + TMC_SYS_SHUTDOWN); - - return len; -} - - -static DEVICE_ATTR(major, S_IRUGO, major_show, NULL); -static DEVICE_ATTR(minor, S_IRUGO, minor_show, NULL); -static DEVICE_ATTR(optic_cpld_major, S_IRUGO, optic_cpld_major_show, NULL); -static DEVICE_ATTR(optic_cpld_devid, S_IRUGO, optic_cpld_devid_show, NULL); -static DEVICE_ATTR(optic_cpld_minor, S_IRUGO, optic_cpld_minor_show, NULL); -static DEVICE_ATTR(shutdown, S_IWUSR, NULL, set_sys_shutdown); - -static struct attribute *tmc_attrs[] = { - &dev_attr_major.attr, - &dev_attr_minor.attr, - &dev_attr_optic_cpld_major.attr, - &dev_attr_optic_cpld_devid.attr, - &dev_attr_optic_cpld_minor.attr, - &dev_attr_shutdown.attr, - NULL, -}; - -static struct attribute_group tmc_attr_group = { - .attrs = tmc_attrs, -}; - -#if defined TMC_DO_SCRATCH_TEST -/* Do a quick scratch access test */ -static int tmc_do_test_scratch(struct tmc_fpga_data *tmc) -{ - struct pci_dev *pdev = tmc->pdev; - struct device *dev = &pdev->dev; - int offset = TMC_SCRATCH; - u32 acc, val = 0xdeadbeaf; - - /* - * Check rw register access -> use the scratch reg. - */ - iowrite32(val, tmc->membase + offset); - acc = ioread32(tmc->membase + offset); - if (acc != val) { - dev_err(dev, "Tmc scratch(0x%x) failed: %08x.%08x!\n", - offset, val, acc); - return -EIO; - } - - for (val = 0; val < 0xf0000000; val += 0x01010101) { - iowrite32(val, tmc->membase + offset); - acc = ioread32(tmc->membase + offset); - if (acc != val) { - dev_err(dev, "Tmc scratch(0x%x) failed: %08x.%08x!\n", - offset, val, acc); - return -EIO; - } - } - - /* - * Write a sig before leaving.. - */ - val = 0xcafebabe; - iowrite32(val, tmc->membase + offset); - dev_dbg(dev, "Tmc scratch result: 0x%08x\n", - ioread32(tmc->membase + offset)); - - return 0; -} -#endif /* TMC_DO_SCRATCH_TEST */ - -static int tmc_fpga_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - int err; - struct tmc_fpga_data *tmc; - struct device *dev = &pdev->dev; - - dev_dbg(dev, "Tmc FPGA Probe called\n"); - - tmc = devm_kzalloc(dev, sizeof(*tmc), GFP_KERNEL); - if (!tmc) - return -ENOMEM; - - err = pcim_enable_device(pdev); - if (err) { - dev_err(&pdev->dev, "Failed to enable device %d\n", err); - return err; - } - - err = pcim_iomap_regions(pdev, 1 << 0, "tmc-core"); - if (err) { - dev_err(&pdev->dev, "Failed to iomap regions %d\n", err); - goto err_disable; - } - - tmc->membase = pcim_iomap_table(pdev)[0]; - if (IS_ERR(tmc->membase)) { - dev_err(dev, "pci_ioremap_bar() failed\n"); - err = -ENOMEM; - goto err_release; - } - - tmc->pdev = pdev; - pci_set_drvdata(pdev, tmc); - - /* All Tmc uses MSI interrupts - enable bus mastering */ - pci_set_master(pdev); - -#if defined TMC_DO_SCRATCH_TEST - /* Check IO before proceeding */ - dev_dbg(dev, "Tmc FPGA starting scratch test\n"); - err = tmc_do_test_scratch(tmc); - if (err) - goto err_unmap; - - dev_dbg(dev, "Tmc FPGA scratch test passed !!!\n"); -#endif /* TMC_DO_SCRATCH_TEST */ - - switch (id->device) { - case PCI_DEVICE_ID_JNX_TMC_CHD: - err = mfd_add_devices(dev, pdev->bus->number, - &chassisd_tmc_mfd_devs[0], - ARRAY_SIZE(chassisd_tmc_mfd_devs), - &pdev->resource[0], - 0, NULL /* tmc->irq_domain */); - break; - case PCI_DEVICE_ID_JNX_TMC_PFE: - err = mfd_add_devices(dev, pdev->bus->number, - &pfe_tmc_mfd_devs[0], - ARRAY_SIZE(pfe_tmc_mfd_devs), - &pdev->resource[0], - 0, NULL /* tmc->irq_domain */); - break; - default: - dev_err(&pdev->dev, "Invalid PCI Device ID id:%d\n", - id->device); - goto err_unmap; - } - - if (err < 0) { - dev_err(&pdev->dev, "Failed to add mfd devices %d\n", err); - goto err_unmap; - } - - err = sysfs_create_group(&pdev->dev.kobj, &tmc_attr_group); - if (err) { - sysfs_remove_group(&pdev->dev.kobj, &tmc_attr_group); - dev_err(&pdev->dev, "Failed to create attr group\n"); - goto err_remove_mfd; - } - - tmc->major = ioread32(tmc->membase + TMC_REVISION); - tmc->minor = ioread32(tmc->membase + TMC_MINOR); - - tmc->optic_cpld_major = ioread32(tmc->membase + TMC_OPTIC_CPLD_MAJOR); - tmc->optic_cpld_minor = ioread32(tmc->membase + TMC_OPTIC_CPLD_MINOR); - - dev_info(dev, "Tmc FPGA Revision: 0x%02X_%06X, Minor: %02X\n", - (tmc->major >> 24) & 0xff, - tmc->major & 0xffffff, - (tmc->minor) & 0xff); - dev_info(dev, "Tmc FPGA optic cpld Major: 0x%01X, Minor: 0x%02X " - "Devid: 0x%01X\n", (tmc->optic_cpld_major) & 0xf, - (tmc->optic_cpld_minor) & 0xff, - (tmc->optic_cpld_major >> 4) & 0xf); - dev_info(dev, "Tmc FPGA mem:0x%lx\n", - (unsigned long)tmc->membase); - - return 0; - -err_remove_mfd: - mfd_remove_devices(dev); -err_unmap: - pci_iounmap(pdev, tmc->membase); -err_release: - pci_release_regions(pdev); -err_disable: - pci_disable_device(pdev); - - return err; -} - -static void tmc_fpga_remove(struct pci_dev *pdev) -{ - struct tmc_fpga_data *tmc = dev_get_drvdata(&pdev->dev); - - sysfs_remove_group(&pdev->dev.kobj, &tmc_attr_group); - mfd_remove_devices(&pdev->dev); -} - -static const struct pci_device_id tmc_fpga_id_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_TMC_CHD) }, - { PCI_DEVICE(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_TMC_PFE) }, - { } -}; -MODULE_DEVICE_TABLE(pci, tmc_fpga_id_tbl); - -static struct pci_driver tmc_fpga_driver = { - .name = "tmc-core", - .id_table = tmc_fpga_id_tbl, - .probe = tmc_fpga_probe, - .remove = tmc_fpga_remove, -}; - -module_pci_driver(tmc_fpga_driver); - -MODULE_DESCRIPTION("Juniper Networks TMC FPGA MFD core driver"); -MODULE_AUTHOR("Ashish Bhensdadia "); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c new file mode 120000 index 000000000000..623e7a0188c6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c @@ -0,0 +1 @@ +../../common/modules/jnx-tmc-core.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h deleted file mode 100644 index dce7d7be3311..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Juniper Tmc FPGA register definitions - * - * Copyright (C) 2018 Juniper Networks - * Author: Ashish Bhensdadia - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __JNX_TMC_H__ -#define __JNX_TMC_H__ - - -#define TMC_REVISION 0x00064 -#define TMC_MINOR 0x00068 -#define TMC_SCRATCH 0x00098 - -#define TMC_OPTIC_CPLD_MAJOR 0x00104 -#define TMC_OPTIC_CPLD_MINOR 0x00108 - -/* - * I2C Master Block - */ -#define TMC_I2C_AUTOMATION_I2C_CONTROL_START 0x07000 -#define TMC_I2C_AUTOMATION_I2C_CONTROL_END 0x07500 - -#define TMC_I2C_DPMEM_ENTRY_START 0x10000 -#define TMC_I2C_DPMEM_ENTRY_END 0x13FFC - -#define TMC_LED_CONTROL_START 0x58 -#define TMC_LED_CONTROL_END 0x5B - -/* - * RE-FPGA block - */ -#define TMC_REFPGA_ACCESS_START 0x228 -#define TMC_REFPGA_ACCESS_END 0x233 - -#define TMC_I2C_MASTER_NR_MSTRS 16 -#define TMC_I2C_MSTR_MAX_GROUPS 66 - - -/* - * TMC GPIO SLAVE Block - */ -#define TMC_GPIO_PTP_RESET_START 0x94 -#define TMC_GPIO_PTP_RESET_END 0x97 - -#define TMC_GPIO_PTP_CFG_START 0xa4 -#define TMC_GPIO_PTP_CFG_END 0xa7 - -#define TMC_GPIO_PTP_DATA_START 0xa8 -#define TMC_GPIO_PTP_DATA_END 0xab - -#define TMC_GPIO_SLAVE0_START 0xf0 -#define TMC_GPIO_SLAVE0_END 0x16b - -#define TMC_GPIO_SLAVE1_START 0x170 -#define TMC_GPIO_SLAVE1_END 0x1eb - -#define TMC_GPIO_SLAVE2_START 0x1f0 -#define TMC_GPIO_SLAVE2_END 0x213 - -#define TMC_GPIO_SLAVE3_START 0x280 -#define TMC_GPIO_SLAVE3_END 0x2eb - -#define TMC_GPIO_SFP_SLAVE0_START 0x308 -#define TMC_GPIO_SFP_SLAVE0_END 0x32b - -#define TMC_GPIO_SFP_SLAVE1_START 0x32c -#define TMC_GPIO_SFP_SLAVE1_END 0x34b - -/* - * TMC PSU Block - */ -#define TMC_PSU_START 0x240 -#define TMC_PSU_END 0x243 - -/* - * TMC SHUTDOWN REG - */ -#define TMC_SYS_SHUTDOWN_LOCK 0x254 -#define TMC_SYS_SHUTDOWN 0x250 - -/* - * TMC DS100 MUX Block - */ -#define TMC_GPIO_MUX_SLAVE_START 0x26c -#define TMC_GPIO_MUX_SLAVE_END 0x26f - -#endif /* __JNX_TMC_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h new file mode 120000 index 000000000000..bfacb7ae018d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h @@ -0,0 +1 @@ +../../common/modules/jnx-tmc.h \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/pci_ids.h b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/pci_ids.h deleted file mode 100644 index 090707751b2c..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/pci_ids.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Juniper PCI ID(s) - for devices on Juniper Boards - * - * Rajat Jain - * Copyright 2014 Juniper Networks - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __JNX_PCI_IDS_H__ -#define __JNX_PCI_IDS_H__ - -#define PCI_VENDOR_ID_JUNIPER 0x1304 -#define PCI_VENDOR_ID_ERICSSON 0x1519 -#define PCI_VENDOR_ID_ERICSSON_AS 0x1a25 - -/* - * PTX SAM FPGA, device ID as present on various Juniper boards, such as - * - Sangria FPC - * - Hendricks FPC - * - Sangria 24x10GE PIC - * - Gladiator FPC - */ -#define PCI_DEVICE_ID_JNX_SAM 0x0004 - -/* Juniper Broadway ASIC family */ -#define PCI_DEVICE_ID_JNX_TF 0x003c -#define PCI_DEVICE_ID_JNX_TL 0x003d -#define PCI_DEVICE_ID_JNX_TQ 0x003e -#define PCI_DEVICE_ID_JNX_OTN_FRAMER 0x0055 -#define PCI_DEVICE_ID_JNX_PE 0x005e -#define PCI_DEVICE_ID_JNX_PF 0x005f /* Juniper Paradise ASIC */ -#define PCI_DEVICE_ID_JNX_ZF 0x008d /* Juniper ZF Fabric ASIC */ -#define PCI_DEVICE_ID_JNX_ZX 0x008e /* Juniper ZX ASIC */ -#define PCI_DEVICE_ID_JNX_ZT 0x0090 /* Juniper ZT ASIC */ -#define PCI_DEVICE_ID_JNX_BT 0x00B2 /* Juniper BT ASIC */ - -/* Juniper SAM FPGA - Omega SIB, Sochu SHAM, Gladiator SIB */ -#define PCI_DEVICE_ID_JNX_SAM_OMEGA 0x006a - -/* Juniper SAM FPGA - present on GLD FPC board */ -#define PCI_DEVICE_ID_JNX_SAM_X 0x006b - -/* Juniper PAM FPGA - present on PTX MLC board */ -#define PCI_DEVICE_ID_JNX_PAM 0x006c -/* Juniper CBC FPGA - present on PTX1K RCB */ -#define PCI_DEVICE_ID_JNX_CBC 0x006e -#define PCI_DEVICE_ID_JNX_CBC_P2 0x0079 -#define PCI_DEVICE_ID_JNX_OMG_CBC 0x0083 - -/* Juniper Summit FPGA */ -#define PCI_DEVICE_ID_JNX_SUMMIT 0x009B - -/* Juniper DOON FPGA */ -#define PCI_DEVICE_ID_JNX_DOON_RCB_CBC 0x0098 - -/* Juniper CBC FPGA in PTX-5K MTRCB */ -#define PCI_DEVICE_ID_JNX_PTX5K_MTRCB_CBC 0x0071 - -/* Other Vendors' devices */ -#define PCI_DEVICE_ID_IDT_PES12NT3_TRANS_AB 0x8058 -#define PCI_DEVICE_ID_IDT_PES12NT3_TRANS_C 0x8059 -#define PCI_DEVICE_ID_IDT_PES12NT3_INT_NTB_C 0x805a -#define PCI_DEVICE_ID_IDT_48H12G2 0x807a -#define PCI_DEVICE_ID_IDT_PES24NT24G2 0x808e -#define PCI_DEVICE_ID_IDT_PES16NT16G2 0x8090 - -#define PCI_DEVICE_ID_PLX_8614 0x8614 -#define PCI_DEVICE_ID_PLX_8618 0x8618 -#define PCI_DEVICE_ID_PLX_8713 0x8713 -#define PCI_DEVICE_ID_PLX_8725 0x8725 -#define PCI_DEVICE_ID_PLX_8749 0x8749 -#define PCI_DEVICE_ID_PLX_8796 0x8796 -#define PCI_DEVICE_ID_PLX_8608 0x8608 - -/* - * Juniper CBD FPGA Device ID(s) - */ -#define JNX_CBD_FPGA_DID_09B3 0x004D -#define JNX_CBD_FPGA_DID_0BA8 0x005A - -/* - * Juniper Brackla FPGA Device IDs - * - UBAM, MBAM, PBAM, QBAM - */ -#define PCI_DEVICE_ID_JNX_UBAM 0x00A7 -#define PCI_DEVICE_ID_JNX_PBAM 0x00A8 -#define PCI_DEVICE_ID_JNX_MBAM 0x00A9 -#define PCI_DEVICE_ID_JNX_QBAM 0x00AA - -/* - * Juniper MPC11E Supercon and WAN FPGA IDs - */ -#define PCI_DEVICE_ID_JNX_MPC11CON 0x00A1 -#define PCI_DEVICE_ID_JNX_MPC11WAN 0x00C4 - -/* - * Juniper Attella TMC and Supercon FPGA IDs - */ -#define PCI_DEVICE_ID_JNX_ARGUS 0x00B0 -#define PCI_DEVICE_ID_JNX_ATIC 0x00C0 -#define PCI_DEVICE_ID_JNX_ATMC_CHD 0x00C1 -#define PCI_DEVICE_ID_JNX_ATMC_PFE 0x00C2 -#define PCI_DEVICE_ID_JNX_AOHIO 0x00C3 - -/* - * Juniper TMC FPGA Device IDs - */ -#define PCI_DEVICE_ID_JNX_TMC_CHD 0x007B -#define PCI_DEVICE_ID_JNX_TMC_PFE 0x007C - -#define PCI_DEVICE_ID_XILINX_1588_FPGA 0x0505 - -/* - * Juniper Scapa SIB/LC Supercon FPGA IDs - */ -#define PCI_DEVICE_ID_JNX_SCAPA_SIB_CTRL 0x00BA -#define PCI_DEVICE_ID_JNX_SDLC_CTRL 0x00BE -#define PCI_DEVICE_ID_JNX_LLC_CTRL 0x00C8 - -/* - * Deanston WANIO FPGA - */ -#define PCI_DEVICE_ID_JNX_DEANSTON_WAN 0x00C6 - -/* - * Juniper Ardbeg Supercon FPGA IDs - */ -#define PCI_DEVICE_ID_JNX_ARDBEG_CTRL 0x00C5 - -/* - * Ericsson CCM FPGA ID used in Bolan (ACX753) - */ -#define PCI_DEVICE_ID_ERIC_CCM_FPGA 0x0020 - -/* - * Ericsson OAM FPGA ID used in Bolan (ACX753) - */ -#define PCI_DEVICE_ID_ERIC_OAM_FPGA 0x7021 - -#endif /* __JNX_PCI_IDS_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/service/qfx5200-platform-init.service b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/service/qfx5200-platform-init.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/setup.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/setup.py deleted file mode 100755 index a847e4d8f6c3..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/setup.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python - -import os -from setuptools import setup -os.listdir - -setup( - name='sonic_platform', - version='1.0', - description='Module to initialize Juniper QFX5200-32C-S platforms', - - packages=['sonic_platform'], - package_dir={'sonic_platform': 'qfx5200/sonic_platform'}, -) - diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/chassis.py deleted file mode 100755 index 39b6f81c9f59..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/chassis.py +++ /dev/null @@ -1,260 +0,0 @@ -#!/usr/bin/env python -# -# Name: chassis.py, version: 1.0 -# -# Description: Module contains the definitions of SONiC platform APIs -# which provide the chassis specific details -# -# Copyright (c) 2020, Juniper Networks, Inc. -# All rights reserved. -# -# Notice and Disclaimer: This code is licensed to you under the GNU General -# Public License as published by the Free Software Foundation, version 3 or -# any later version. This code is not an official Juniper product. You can -# obtain a copy of the License at -# -# OSS License: -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Third-Party Code: This code may depend on other components under separate -# copyright notice and license terms. Your use of the source code for those -# components is subject to the terms and conditions of the respective license -# as noted in the Third-Party source code file. -# - -try: - import commands - import time - from sonic_platform_base.chassis_base import ChassisBase -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Chassis(ChassisBase): - """ - JUNIPER QFX5200 Platform-specific Chassis class - """ - - def __init__(self): - ChassisBase.__init__(self) - - def get_qfx5200_parameter_value(self,parameter_name): - try: - with open("/var/run/eeprom", "r") as file: - for item in file: - content = item.split('=') - if content[0] == parameter_name: - return content[1:] - return "False" - except IOError: - print "Error: File not found" - return "False" - - def get_product_name(self): - product_name_list = self.get_qfx5200_parameter_value('Product Name') - if product_name_list: - product_name = ''.join(product_name_list) - return product_name - else: - return False - - - def get_part_number(self): - part_number_list = self.get_qfx5200_parameter_value('Part Number') - if part_number_list: - part_number = ''.join(part_number_list) - return part_number - else: - return False - - - def get_serial_number(self): - serial_number_list = self.get_qfx5200_parameter_value('Serial Number') - if serial_number_list: - serial_number = ''.join(serial_number_list) - return serial_number - else: - return False - - - def get_base_mac(self): - mac_list = self.get_qfx5200_parameter_value('MAC Address') - if mac_list: - mac = ''.join(mac_list) - return mac - else: - return False - - - def get_mfg_date(self): - mfgdate_list = self.get_qfx5200_parameter_value('Manufacture Date') - if mfgdate_list: - mfgdate = ''.join(mfgdate_list) - return mfgdate - else: - return False - - - def get_platform_name(self): - platform_name_list = self.get_qfx5200_parameter_value('Platform Name') - if platform_name_list: - platform_name = ''.join(platform_name_list) - return platform_name - else: - return False - - - def get_MACnumber_name(self): - MACnumber_name_list = self.get_qfx5200_parameter_value('Number of MAC Addresses') - if MACnumber_name_list: - MACnumber_name = ''.join(MACnumber_name_list) - return MACnumber_name - else: - return False - - - def get_vendor_name(self): - vendor_name_list = self.get_qfx5200_parameter_value('Vendor Name') - if vendor_name_list: - vendor_name = ''.join(vendor_name_list) - return vendor_name - else: - return False - - def get_mfg_name(self): - mfg_name_list = self.get_qfx5200_parameter_value('Manufacture Name') - if mfg_name_list: - mfg_name = ''.join(mfg_name_list) - return mfg_name - else: - return False - - def get_vendorext_name(self): - vendorext_list = self.get_qfx5200_parameter_value('Vendor Extension') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextIANA_name(self): - vendorext_list = self.get_qfx5200_parameter_value('IANA') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextASMREV_name(self): - vendorext_list = self.get_qfx5200_parameter_value('Assembly Part Number Revision') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextASMPartNum_name(self): - vendorext_list = self.get_qfx5200_parameter_value('Assembly Part Number') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextASMID_name(self): - vendorext_list = self.get_qfx5200_parameter_value('Assembly ID') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextASMMajNum_name(self): - vendorext_list = self.get_qfx5200_parameter_value('Assembly Major Revision') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextASMMinNum_name(self): - vendorext_list = self.get_qfx5200_parameter_value('Assembly Minor Revision') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextCLEI_name(self): - vendorext_list = self.get_qfx5200_parameter_value('CLEI code') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_onieversion_name(self): - onieversion_name_list = self.get_qfx5200_parameter_value('ONIE Version') - if onieversion_name_list: - onieversion_name = ''.join(onieversion_name_list) - return onieversion_name - else: - return False - - def get_crc_name(self): - crc_list = self.get_qfx5200_parameter_value('CRC') - if crc_list: - crc_name = ''.join(crc_list) - return crc_name - else: - return False - - def get_fan_type(self): - fantype_list = self.get_qfx5200_parameter_value('Fan Type') - if fantype_list: - fantype_name = ''.join(fantype_list) - return fantype_name - else: - return False - - def get_reboot_cause(self): - """ - Retrieves the cause of the previous reboot - """ - status, last_reboot_reason = commands.getstatusoutput("busybox devmem 0xFED50004 8") - if (status == 0): - if last_reboot_reason == "0x80": - return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) - elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": - return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) - elif last_reboot_reason == "0x20": - return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) - elif last_reboot_reason == "0x10": - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") - else: - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") - else: - time.sleep(3) - status, last_reboot_reason = commands.getstatusoutput("busybox devmem 0xFED50004 8") - if last_reboot_reason == "0x80": - return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) - elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": - return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) - elif last_reboot_reason == "0x20": - return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) - elif last_reboot_reason == "0x10": - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") - else: - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c deleted file mode 120000 index 843ce05a4313..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c +++ /dev/null @@ -1 +0,0 @@ -../../common/modules/juniper_i2c_cpld.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c new file mode 100644 index 000000000000..25860a6ac1f9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c @@ -0,0 +1,892 @@ +/* + * A hwmon driver for the juniper_i2c_cpld + * + * Tested and validated on Juniper QFX5210 + * Ciju Rajan K + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define MAX_PORT_NUM 64 +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +#define I2C_ADDR_CPLD1 0x60 +#define I2C_ADDR_CPLD2 0x62 +#define I2C_ADDR_CPLD3 0x64 +#define CPLD_ADDRS {I2C_ADDR_CPLD1, I2C_ADDR_CPLD2, I2C_ADDR_CPLD3} + + +/* + * Number of additional attribute pointers to allocate + * with each call to krealloc + */ +#define ATTR_ALLOC_SIZE 1 /*For last attribute which is NUll.*/ + +#define NAME_SIZE 24 +#define MAX_RESP_LENGTH 48 + +typedef ssize_t (*show_func)( struct device *dev, + struct device_attribute *attr, + char *buf); +typedef ssize_t (*store_func)(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); + +enum models { + AS7712_32X, + AS7716_32X, + qfx5210_64X, + AS7312_54X, + PLAIN_CPLD, /*No attribute but add i2c addr to the list.*/ + NUM_MODEL +}; + +enum sfp_func { + HAS_SFP = 1<<0 , + HAS_QSFP = 1<<1 , +}; + +enum common_attrs { + CMN_VERSION, + CMN_ACCESS, + CMN_PRESENT_ALL, + NUM_COMMON_ATTR +}; + +enum sfp_attrs { + SFP_PRESENT, + SFP_RESET, + SFP_LP_MODE, + NUM_SFP_ATTR +}; + +struct cpld_sensor { + struct cpld_sensor *next; + char name[NAME_SIZE+1]; /* sysfs sensor name */ + struct device_attribute attribute; + bool update; /* runtime sensor update needed */ + int data; /* Sensor data. Negative if there was a read error */ + + u8 reg; /* register */ + u8 mask; /* bit mask */ + bool invert; /* inverted value*/ + +}; + +#define to_cpld_sensor(_attr) \ + container_of(_attr, struct cpld_sensor, attribute) + +struct cpld_data { + struct device *dev; + struct device *hwmon_dev; + + int num_attributes; + struct attribute_group group; + + enum models model; + struct cpld_sensor *sensors; + struct mutex update_lock; + bool valid; + unsigned long last_updated; /* in jiffies */ + + int attr_index; + u16 sfp_num; + u8 sfp_types; + struct model_attrs *cmn_attr; +}; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + + +struct base_attrs { + const char *name; + umode_t mode; + show_func get; + store_func set; +}; + +struct attrs { + int reg; + bool invert; + struct base_attrs *base; +}; + +struct model_attrs { + struct attrs **cmn; + struct attrs **portly; +}; + + +static ssize_t show_bit(struct device *dev, + struct device_attribute *devattr, char *buf); +static ssize_t show_presnet_all(struct device *dev, + struct device_attribute *devattr, char *buf); +static ssize_t set_1bit(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_byte(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + +int juniper_i2c_cpld_read(u8 cpld_addr, u8 reg); +int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + + +struct base_attrs common_attrs[NUM_COMMON_ATTR] = +{ + [CMN_VERSION] = {"version", S_IRUGO, show_bit, NULL}, + [CMN_ACCESS] = {"access", S_IWUSR, NULL, set_byte}, + [CMN_PRESENT_ALL] = {"module_present_all", S_IRUGO, show_presnet_all, NULL}, +}; + +struct attrs as7712_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, + [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, + [CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]}, +}; +struct attrs qfx5210_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, + [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, + [CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]}, +}; +struct attrs as7312_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, + [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, + [CMN_PRESENT_ALL] = {-1, false, &common_attrs[CMN_PRESENT_ALL]}, +}; +struct attrs plain_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, +}; + +struct base_attrs portly_attrs[] = +{ + [SFP_PRESENT] = {"module_present", S_IRUGO, show_bit, NULL}, + // Only root user will have the privilege to write to sysfs + // [SFP_RESET] = {"module_reset", S_IRUGO|S_IWUGO, show_bit, set_1bit}, + [SFP_RESET] = {"module_reset", S_IRUGO|S_IWUSR, show_bit, set_1bit}, +}; + +struct attrs as7712_port[] = { + {0x30, true, &portly_attrs[SFP_PRESENT]}, + {0x04, true, &portly_attrs[SFP_RESET]}, +}; + +struct attrs qfx5210_port[] = { + {0x70, true, &portly_attrs[SFP_PRESENT]}, + {0x40, true, &portly_attrs[SFP_RESET]}, +}; + +struct attrs *as7712_cmn_list[] = { + &as7712_common[CMN_VERSION], + &as7712_common[CMN_ACCESS], + &as7712_common[CMN_PRESENT_ALL], + NULL +}; + +struct attrs *qfx5210_cmn_list[] = { + &qfx5210_common[CMN_VERSION], + &qfx5210_common[CMN_ACCESS], + &qfx5210_common[CMN_PRESENT_ALL], + NULL +}; + +struct attrs *as7312_cmn_list[] = { + &as7312_common[CMN_VERSION], + &as7312_common[CMN_ACCESS], + &as7312_common[CMN_PRESENT_ALL], + NULL +}; + +struct attrs *plain_cmn_list[] = { + &plain_common[CMN_VERSION], + NULL +}; + +struct attrs *as7712_port_list[] = { + &as7712_port[SFP_PRESENT], + &as7712_port[SFP_RESET], + NULL +}; +struct attrs *qfx5210_port_list[] = { + &qfx5210_port[SFP_PRESENT], + &qfx5210_port[SFP_RESET], + NULL +}; + +struct model_attrs models_attr[NUM_MODEL] = { + {.cmn = as7712_cmn_list, .portly=as7712_port_list}, + {.cmn = as7712_cmn_list, .portly=as7712_port_list}, /*7716's as 7712*/ + {.cmn = qfx5210_cmn_list, .portly=qfx5210_port_list}, + {.cmn = as7312_cmn_list, .portly=qfx5210_port_list}, + {.cmn = plain_cmn_list, .portly=NULL}, +}; + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; +/* Addresses scanned for juniper_i2c_cpld + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static int get_sfp_spec(int model, u16 *num, u8 *types) +{ + switch (model) { + case AS7712_32X: + case AS7716_32X: + *num = 32; + *types = HAS_QSFP; + break; + case qfx5210_64X: + *num = 64; + *types = HAS_QSFP; + break; + case AS7312_54X: + *num = 54; + *types = HAS_QSFP|HAS_SFP; + default: + *types = 0; + *num = 0; + break; + } + + return 0; +} + +static int get_present_reg(int model, u8 port, u8 *cpld_addr, u8 *reg, u8 *num) +{ + u8 cpld_address[] = CPLD_ADDRS; + + switch (model) { + case AS7312_54X: + if (port < 48) { + *cpld_addr = cpld_address[1 + port/24]; + *reg = 0x09 + (port%24)/8; + *num = 8; + } + else + { + *reg = 0x18; + *num = 4; + *cpld_addr = ( port < 52)? cpld_address[1]: cpld_address[2]; + } + break; + default: + return -EINVAL; + } +} + + +/*Assume the bits for ports are listed in-a-row.*/ +static int get_reg_bit(u8 reg_start, int port, + u8 *reg ,u8 *mask) +{ + *reg = reg_start + ((port)/8); + *mask = 1 << ((port)%8); + + return 0; +} + +static int cpld_write_internal( + struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + + +/*Turn a numberic array into string with " " between each element. + * e.g., {0x11, 0x33, 0xff, 0xf1} => "11 33 ff f1" + */ +static ssize_t array_stringify(char *buf, u8 *input, size_t size) { + + int i; + char t[MAX_RESP_LENGTH+1]; + + buf[0] = '\0'; + for (i = 0; i < size; i++) { + snprintf(t, MAX_RESP_LENGTH, "%x ", input[i]); + strncat(buf, t, MAX_RESP_LENGTH); + } + + if (strlen(buf) > 0) + buf[strlen(buf)-1] = '\0'; /*Remove tailing blank*/ + + return snprintf(buf, MAX_RESP_LENGTH, "%s\n", buf); +} + +static ssize_t show_presnet_all_distinct(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 i, value, reg; + u8 cpld_addr, num; + u8 _value[8]; + u64 *values = (u64 *)_value; + + values = 0; + mutex_lock(&data->update_lock); + while(i < data->sfp_num) + { + get_present_reg(data->model, i, &cpld_addr, ®, &num); + if(cpld_addr == client->addr) + value = cpld_read_internal(client, reg); + else + value = juniper_i2c_cpld_read(cpld_addr, reg); + + if (unlikely(value < 0)) { + goto exit; + } + + *values |= (value&((1<<(num))-1)) << i; + i += num; + } + mutex_unlock(&data->update_lock); + + *values = cpu_to_le64(*values); + return array_stringify(buf, _value, i); +exit: + mutex_unlock(&data->update_lock); + return value; +} + +static ssize_t show_presnet_all(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + struct cpld_sensor *sensor = to_cpld_sensor(devattr); + u8 i, values[MAX_RESP_LENGTH/8]; + + if (sensor->reg < 0) { + return show_presnet_all_distinct(dev, devattr, buf); + } + + mutex_lock(&data->update_lock); + for (i = 0; i < ((data->sfp_num+7)/8); i++) { + values[i] = cpld_read_internal(client, sensor->reg + i); + if (unlikely(values[i] < 0)) { + goto exit; + } + } + mutex_unlock(&data->update_lock); + return array_stringify(buf, values, i); + +exit: + mutex_unlock(&data->update_lock); + return values[i]; +} + +static ssize_t show_bit(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int value; + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + struct cpld_sensor *sensor = to_cpld_sensor(devattr); + + mutex_lock(&data->update_lock); + value = cpld_read_internal(client, sensor->reg); + value = value & sensor->mask; + if (sensor->invert) + value = !value; + mutex_unlock(&data->update_lock); + + return snprintf(buf, PAGE_SIZE, "%x\n", value); +} + +static ssize_t set_1bit(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + long is_reset; + int value, status; + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + struct cpld_sensor *sensor = to_cpld_sensor(devattr); + u8 cpld_bit, reg; + + status = kstrtol(buf, 10, &is_reset); + if (status) { + return status; + } + reg = sensor->reg; + cpld_bit = sensor->mask; + mutex_lock(&data->update_lock); + value = cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + if (sensor->invert) + is_reset = !is_reset; + + if (is_reset) { + value |= cpld_bit; + } + else { + value &= ~cpld_bit; + } + + status = cpld_write_internal(client, reg, value); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_byte(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + return access(dev, da, buf, count); +} + +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int status; + u32 addr, val; + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + + if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { + return -EINVAL; + } + + if (addr > 0xFF || val > 0xFF) { + return -EINVAL; + } + + mutex_lock(&data->update_lock); + status = cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static void juniper_i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = + kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", + client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void juniper_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int cpld_add_attribute(struct cpld_data *data, struct attribute *attr) +{ + int new_max_attrs = ++data->num_attributes + ATTR_ALLOC_SIZE; + void *new_attrs = krealloc(data->group.attrs, + new_max_attrs * sizeof(void *), + GFP_KERNEL); + if (!new_attrs) + return -ENOMEM; + data->group.attrs = new_attrs; + + + data->group.attrs[data->num_attributes-1] = attr; + data->group.attrs[data->num_attributes] = NULL; + + return 0; +} + +static void cpld_dev_attr_init(struct device_attribute *dev_attr, + const char *name, umode_t mode, + show_func show, store_func store) +{ + sysfs_attr_init(&dev_attr->attr); + dev_attr->attr.name = name; + dev_attr->attr.mode = mode; + dev_attr->show = show; + dev_attr->store = store; +} + +static struct cpld_sensor * add_sensor(struct cpld_data *data, + const char *name, + u8 reg, u8 mask, bool invert, + bool update, umode_t mode, + show_func get, store_func set) +{ + struct cpld_sensor *sensor; + struct device_attribute *a; + + sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL); + if (!sensor) + return NULL; + a = &sensor->attribute; + + snprintf(sensor->name, sizeof(sensor->name), name); + sensor->reg = reg; + sensor->mask = mask; + sensor->update = update; + sensor->invert = invert; + cpld_dev_attr_init(a, sensor->name, + mode, + get, set); + + if (cpld_add_attribute(data, &a->attr)) + return NULL; + + sensor->next = data->sensors; + data->sensors = sensor; + + return sensor; +} + +static int add_attributes_cmn(struct cpld_data *data, struct attrs **cmn) +{ + u8 reg, i ; + bool invert; + struct attrs *a; + struct base_attrs *b; + + if (NULL == cmn) + return -1; + + for (i = 0; cmn[i]; i++) + { + a = cmn[i]; + + reg = a->reg; + invert = a->invert; + + b = a->base; + if (NULL == b) + break; + + if (add_sensor(data, b->name, + reg, 0xff, invert, + true, b->mode, + b->get, b->set) == NULL) + { + return -ENOMEM; + } + } + return 0; +} + +static int add_attributes_portly(struct cpld_data *data, struct attrs **pa) +{ + char name[NAME_SIZE+1]; + int i, j; + u8 reg, mask, invert; + struct attrs *a; + struct base_attrs *b; + + if (NULL == pa) + return -1; + + + for (i = 0; pa[i]; i++) { + a = pa[i]; + + invert = a->invert; + b = a->base; + if (b == NULL) + break; + + for (j = 0; j < data->sfp_num; j++) + { + snprintf(name, NAME_SIZE, "%s_%d", b->name, j+1); + get_reg_bit(a->reg, j, ®, &mask); + + if (add_sensor(data, name, reg, mask, invert, + true, b->mode, b->get, b->set) == NULL) + { + return -ENOMEM; + } + } + } + return 0; +} + +static int add_attributes(struct i2c_client *client, + struct cpld_data *data) +{ + struct model_attrs *m = data->cmn_attr; + + if (m == NULL) + return -EINVAL; + + /* Common attributes.*/ + add_attributes_cmn(data, m->cmn); + + /* Port-wise attributes.*/ + add_attributes_portly(data, m->portly); + + return 0; +} + +static int juniper_i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct cpld_data *data = NULL; + struct device *dev = &client->dev; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + return -EIO; + } + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + data->model = dev_id->driver_data; + data->cmn_attr = &models_attr[data->model]; + get_sfp_spec(data->model, &data->sfp_num, &data->sfp_types); + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->dev = dev; + dev_info(dev, "chip found\n"); + + status = add_attributes(client, data); + if (status) + goto out_kfree; + + /* + * If there are no attributes, something is wrong. + * Bail out instead of trying to register nothing. + */ + if (!data->num_attributes) { + dev_err(dev, "No attributes found\n"); + status = -ENODEV; + goto out_kfree; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &data->group); + if (status) { + goto out_kfree; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + juniper_i2c_cpld_add_client(client); + dev_info(dev, "%s: cpld '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->group); +out_kfree: + kfree(data->group.attrs); + return status; + +} + +static int juniper_i2c_cpld_remove(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->group); + kfree(data->group.attrs); + juniper_i2c_cpld_remove_client(client); + return 0; +} + +int juniper_i2c_cpld_read(u8 cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(juniper_i2c_cpld_read); + +int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(juniper_i2c_cpld_write); + + +static const struct i2c_device_id juniper_i2c_cpld_id[] = { + { "cpld_as7712", AS7712_32X}, + { "cpld_as7716", AS7716_32X}, + { "cpld_qfx5210", qfx5210_64X}, + { "cpld_as7312", AS7312_54X}, + { "cpld_plain", PLAIN_CPLD}, + { }, +}; +MODULE_DEVICE_TABLE(i2c, juniper_i2c_cpld_id); + +static struct i2c_driver juniper_i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "juniper_i2c_cpld", + }, + .probe = juniper_i2c_cpld_probe, + .remove = juniper_i2c_cpld_remove, + .id_table = juniper_i2c_cpld_id, + .address_list = normal_i2c, +}; + + +static int __init juniper_i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&juniper_i2c_cpld_driver); +} + +static void __exit juniper_i2c_cpld_exit(void) +{ + i2c_del_driver(&juniper_i2c_cpld_driver); +} + +module_init(juniper_i2c_cpld_init); +module_exit(juniper_i2c_cpld_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("juniper_i2c_cpld driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c deleted file mode 120000 index f4d67640ccc3..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c +++ /dev/null @@ -1 +0,0 @@ -../../common/modules/ym2651y.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c new file mode 100644 index 000000000000..3ade5684107a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c @@ -0,0 +1,622 @@ +/* + * An hwmon driver for the 3Y Power YM-2651Y Power Module + * + * Tested and validated on Juniper QFX5210 + * Ciju Rajan K + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x58, 0x5b, I2C_CLIENT_END }; + +enum chips { + YM2651, + YM2401, + YM2851, +}; + +/* Each client has this additional data + */ +struct ym2651y_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 capability; /* Register value */ + u16 status_word; /* Register value */ + u8 fan_fault; /* Register value */ + u8 over_temp; /* Register value */ + u16 v_out; /* Register value */ + u16 i_out; /* Register value */ + u16 p_out; /* Register value */ + u16 temp; /* Register value */ + u16 fan_speed; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u8 fan_dir[4]; /* Register value */ + u8 pmbus_revision; /* Register value */ + u8 mfr_id[10]; /* Register value */ + u8 mfr_model[10]; /* Register value */ + u8 mfr_revsion[3]; /* Register value */ + u16 mfr_vin_min; /* Register value */ + u16 mfr_vin_max; /* Register value */ + u16 mfr_iin_max; /* Register value */ + u16 mfr_iout_max; /* Register value */ + u16 mfr_pin_max; /* Register value */ + u16 mfr_pout_max; /* Register value */ + u16 mfr_vout_min; /* Register value */ + u16 mfr_vout_max; /* Register value */ +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf); +static struct ym2651y_data *ym2651y_update_device(struct device *dev); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); + +enum ym2651y_sysfs_attributes { + PSU_POWER_ON = 0, + PSU_TEMP_FAULT, + PSU_POWER_GOOD, + PSU_FAN1_FAULT, + PSU_FAN_DIRECTION, + PSU_OVER_TEMP, + PSU_V_OUT, + PSU_I_OUT, + PSU_P_OUT, + PSU_P_OUT_UV, /*In Unit of microVolt, instead of mini.*/ + PSU_TEMP1_INPUT, + PSU_FAN1_SPEED, + PSU_FAN1_DUTY_CYCLE, + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_REVISION, + PSU_MFR_VIN_MIN, + PSU_MFR_VIN_MAX, + PSU_MFR_VOUT_MIN, + PSU_MFR_VOUT_MAX, + PSU_MFR_IIN_MAX, + PSU_MFR_IOUT_MAX, + PSU_MFR_PIN_MAX, + PSU_MFR_POUT_MAX +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_linear, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); +static SENSOR_DEVICE_ATTR(psu_pmbus_revision, S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); + +/*Duplicate nodes for lm-sensors.*/ +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_linear, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_linear, NULL, PSU_P_OUT_UV); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); + +static struct attribute *ym2651y_attributes[] = { + &sensor_dev_attr_psu_power_on.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_over_temp.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, + /*Duplicate nodes for lm-sensors.*/ + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_temp1_fault.dev_attr.attr, + NULL +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : + sprintf(buf, "0\n"); +} + +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u16 status = 0; + + switch (attr->index) { + case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ + status = (data->status_word & 0x40) ? 0 : 1; + break; + case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ + status = (data->status_word & 0x4) >> 2; + break; + case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ + status = (data->status_word & 0x800) ? 0 : 1; + break; + } + + return sprintf(buf, "%d\n", status); +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_OUT: + value = data->v_out; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_OUT_UV: + multiplier = 1000000; /*For lm-sensors, unit is micro-Volt.*/ + /*Passing through*/ + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp; + break; + case PSU_FAN1_SPEED: + value = data->fan_speed; + multiplier = 1; + break; + case PSU_FAN1_DUTY_CYCLE: + value = data->fan_duty_cycle[0]; + multiplier = 1; + break; + case PSU_MFR_VIN_MIN: + value = data->mfr_vin_min; + break; + case PSU_MFR_VIN_MAX: + value = data->mfr_vin_max; + break; + case PSU_MFR_VOUT_MIN: + value = data->mfr_vout_min; + break; + case PSU_MFR_VOUT_MAX: + value = data->mfr_vout_max; + break; + case PSU_MFR_PIN_MAX: + value = data->mfr_pin_max; + break; + case PSU_MFR_POUT_MAX: + value = data->mfr_pout_max; + break; + case PSU_MFR_IOUT_MAX: + value = data->mfr_iout_max; + break; + case PSU_MFR_IIN_MAX: + value = data->mfr_iin_max; + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct ym2651y_data *data = ym2651y_update_device(dev); + + return sprintf(buf, "%d\n", data->over_temp >> 7); +} + +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 *ptr = NULL; + + switch (attr->index) { + case PSU_FAN_DIRECTION: /* psu_fan_dir */ + ptr = data->fan_dir; + break; + case PSU_MFR_ID: /* psu_mfr_id */ + ptr = data->mfr_id; + break; + case PSU_MFR_MODEL: /* psu_mfr_model */ + ptr = data->mfr_model; + break; + case PSU_MFR_REVISION: /* psu_mfr_revision */ + ptr = data->mfr_revsion; + break; + default: + return 0; + } + + return sprintf(buf, "%s\n", ptr); +} + +static const struct attribute_group ym2651y_group = { + .attrs = ym2651y_attributes, +}; + +static int ym2651y_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct ym2651y_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int ym2651y_remove(struct i2c_client *client) +{ + struct ym2651y_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id ym2651y_id[] = { + { "ym2651", YM2651 }, + { "ym2401", YM2401 }, + { "ym2851", YM2851 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, ym2651y_id); + +static struct i2c_driver ym2651y_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ym2651", + }, + .probe = ym2651y_probe, + .remove = ym2651y_remove, + .id_table = ym2651y_id, + .address_list = normal_i2c, +}; + +static int ym2651y_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int ym2651y_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_word_data(client, reg, value); +} + +static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct ym2651y_data *ym2651y_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; + u8 command; + u8 fan_dir[5] = {0}; + struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, + {0x7d, &data->over_temp}, + {0x81, &data->fan_fault}, + {0x98, &data->pmbus_revision} + }; + struct reg_data_word regs_word[] = { {0x79, &data->status_word}, + {0x8b, &data->v_out}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x8d, &data->temp}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &data->fan_speed}, + {0xa0, &data->mfr_vin_min}, + {0xa1, &data->mfr_vin_max}, + {0xa2, &data->mfr_iin_max}, + {0xa3, &data->mfr_pin_max}, + {0xa4, &data->mfr_vout_min}, + {0xa5, &data->mfr_vout_max}, + {0xa6, &data->mfr_iout_max}, + {0xa7, &data->mfr_pout_max} + }; + + dev_dbg(&client->dev, "Starting ym2651 update\n"); + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = ym2651y_read_byte(client, regs_byte[i].reg); + + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + } + else { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = ym2651y_read_word(client, regs_word[i].reg); + + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + } + else { + *(regs_word[i].value) = status; + } + } + + /* Read fan_direction */ + command = 0xC3; + status = ym2651y_read_block(client, command, fan_dir, ARRAY_SIZE(fan_dir)-1); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + } + + strncpy(data->fan_dir, fan_dir+1, ARRAY_SIZE(data->fan_dir)-1); + data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; + + /* Read mfr_id */ + command = 0x99; + status = ym2651y_read_block(client, command, data->mfr_id, + ARRAY_SIZE(data->mfr_id)-1); + data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + /* Read mfr_model */ + command = 0x9a; + status = ym2651y_read_block(client, command, data->mfr_model, + ARRAY_SIZE(data->mfr_model)-1); + data->mfr_model[ARRAY_SIZE(data->mfr_model)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + /* Read mfr_revsion */ + command = 0x9b; + status = ym2651y_read_block(client, command, data->mfr_revsion, + ARRAY_SIZE(data->mfr_revsion)-1); + data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(ym2651y_driver); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); +MODULE_LICENSE("GPL"); + + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/service/qfx5210-platform-init.service b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/service/qfx5210-platform-init.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/__init__.py deleted file mode 100755 index 9e1b2e56b1c4..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/__init__.py +++ /dev/null @@ -1 +0,0 @@ -import platform diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py deleted file mode 100755 index 5620fec54f65..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python -# -# Name: platform.py, version: 1.0 -# -# Description: Module contains the definitions of SONiC platform APIs -# which provide the platform specific details -# -# Copyright (c) 2019, Juniper Networks, Inc. -# All rights reserved. -# -# Notice and Disclaimer: This code is licensed to you under the GNU General -# Public License as published by the Free Software Foundation, version 3 or -# any later version. This code is not an official Juniper product. You can -# obtain a copy of the License at -# -# OSS License: -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Third-Party Code: This code may depend on other components under separate -# copyright notice and license terms. Your use of the source code for those -# components is subject to the terms and conditions of the respective license -# as noted in the Third-Party source code file. -# - - -import sys - -try: - from sonic_platform_base.platform_base import PlatformBase -except ImportError as e: - raise ImportError("%s - required module not found" % e) - -platformDict = {'platform':'QFX5210-64C'} - -class Platform(PlatformBase): - def __init__(self): - self.platform = self.getPlatform() - - def getPlatformDict(self): - global platformDict - if platformDict: - return platformDict - - def readPlatformName(self): - return self.getPlatformDict().get('platform') - - def getPlatform(self): - platformCls = self.readPlatformName() - return platformCls - - def get_chassis(self): - from chassis import Chassis - chassis = Chassis() - return chassis - diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py index dbf0b831248f..77eac5234257 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py @@ -35,20 +35,12 @@ try: import os import commands - import sys, getopt import subprocess - import click - import imp import logging import logging.config import logging.handlers - import types import time - import traceback import glob - import collections - import StringIO - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) @@ -58,17 +50,16 @@ verbose = False DEBUG = False -global log_file -global log_level +log_file = '%s.log' % FUNCTION_NAME +log_level = logging.DEBUG - -global isPlatformAFI -global is80PerFlag -global is60PerFlag -global isFireThresholdReached -global isFireThresholdPrint -global PrevASICValue -global FireThresholdSecsRemaining +isPlatformAFI = False +is80PerFlag = True +is60PerFlag = True +isFireThresholdReached = False +isFireThresholdPrint = True +PrevASICValue = 0 +FireThresholdSecsRemaining = 120 temp_policy_AFI = { 0: [[70, 0, 48000], [70, 48000, 53000], [80, 53000, 0], [80, 53000, 58000], [100, 58000, 0], ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 75000], ['Fire Shut Alarm', 75000, 0]], @@ -201,7 +192,7 @@ def _get_sensor_node_val(self, thermal_num): try: val_file.close() - except: + except IOError as e: logging.debug('get_sensor_node_val: unable to close file. device_path:%s', device_path) return None @@ -227,8 +218,8 @@ def _get_coretemp_node_val(self, thermal_num): return None try: - val_file.close() - except: + val_file.close() + except IOError as e: logging.debug('get_coretemp_node_val: unable to close file. device_path:%s', device_path) return None @@ -326,7 +317,7 @@ def getSensorTemp(self): isFireThresholdReached == False time.sleep(20) cmd = "poweroff" - returned_value = os.system(cmd) + os.system(cmd) for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): if x < self.SENSOR_NUM_ON_MAIN_BOARD: @@ -340,7 +331,7 @@ def getSensorTemp(self): proc = subprocess.Popen("bcmcmd \"show temp\" | grep \"maximum peak temperature\" | awk '{ print $5 }' > /var/log/asic_value 2>&1 & ",shell=True) time.sleep(2) cmd = "kill -9 %s"%(proc.pid) - status, cmd_out = commands.getstatusoutput(cmd) + commands.getstatusoutput(cmd) if os.stat("/var/log/asic_value").st_size == 0: value = PrevASICValue @@ -531,13 +522,6 @@ class device_monitor(object): def __init__(self, log_file, log_level): global DEBUG - global isPlatformAFI - global isFireThresholdReached - global is80PerFlag - global is60PerFlag - global isFireThresholdPrint - global PrevASICValue - global FireThresholdSecsRemaining MASTER_LED_PATH = '/sys/class/leds/master/brightness' SYSTEM_LED_PATH = '/sys/class/leds/system/brightness' FANTYPE_PATH = '/sys/bus/i2c/devices/17-0068/fan1_direction' @@ -561,27 +545,26 @@ def __init__(self, log_file, log_level): console.setFormatter(formatter) logging.getLogger('').addHandler(console) - import sonic_platform - platform = sonic_platform.platform.Platform() - chassis = platform.get_chassis() - fan_type = chassis.get_fan_type(FANTYPE_PATH) + try: + fan_type_file = open(FANTYPE_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + fan_type = -1 + else: + fan_type = fan_type_file.read() + fan_type_file.close() + # the return value of get_fan_type is AFO = 0, AFI = 1 and for error condition it is -1 # In the error condition also, we are making default platform as AFO, to continue with Energy Monitoring if (int(fan_type) == -1 or int(fan_type) == 0): + logging.debug('FANTYPE_PATH. fan_type %d', int(fan_type)) if (int(fan_type) == -1): logging.error('device_monitor: unable to open sys file for fan handling, defaulting it to AFO') isPlatformAFI = False else: isPlatformAFI = True - isFireThresholdReached = False - is80PerFlag = True - is60PerFlag = True - isFireThresholdPrint = True - FireThresholdSecsRemaining = 120 - PrevASICValue = 0 - master_led_value = 1 try: masterLED_file = open(MASTER_LED_PATH, 'r+') @@ -605,9 +588,7 @@ def manage_device(self): thermal.getSensorTemp() def main(): - log_file = '%s.log' % FUNCTION_NAME - log_level = logging.DEBUG - + #Introducing sleep of 150 seconds to wait for all the docker containers to start before starting the EM policy. time.sleep(150) monitor = device_monitor(log_file, log_level) diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py index b3f130af41c0..26eed74c944a 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py @@ -39,11 +39,7 @@ import sys, getopt import binascii import logging -import re import time -import random -import optparse -from collections import namedtuple @@ -138,145 +134,16 @@ def main(): except OSError: print 'Error: Execution of "%s" failed', DisableWatchDogCmd return False - - - CPUeepromFileCmd = 'cat /sys/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0056/eeprom > /etc/init.d/eeprom_qfx5210_ascii' - # Write the contents of CPU EEPROM to file + + time.sleep(1) + # Invoking the script which retrieves the data from Board EEPROM and storing in file + EEPROMDataCmd = 'python /usr/share/sonic/device/x86_64-juniper_qfx5210-r0/plugins/qfx5210_eeprom_data.py' try: - os.system(CPUeepromFileCmd) + os.system(EEPROMDataCmd) except OSError: - print 'Error: Execution of "%s" failed', CPUeepromFileCmd + print 'Error: Execution of "%s" failed', EEPROMDataCmd return False - eeprom_ascii = '/etc/init.d/eeprom_qfx5210_ascii' - # Read file contents in Hex format - with open(eeprom_ascii, 'rb') as Hexformat: - content = Hexformat.read() - Hexformatoutput = binascii.hexlify(content) - - eeprom_hex = '/etc/init.d/eeprom_qfx5210_hex' - #Write contents of CPU EEPROM to new file in hexa format - with open(eeprom_hex, 'wb+') as Hexfile: - Hexfile.write(Hexformatoutput) - - # Read from EEPROM Hex file and extract the different fields like Product name, - # Part Number, Serial Number MAC Address, Mfg Date ... etc and store in /var/run/eeprom file - with open(eeprom_hex, 'rb') as eeprom_hexfile: - # moving the file pointer to required position where product name is stored in EEPROM file and reading the required bytes from this position - - product_position = eeprom_hexfile.seek(26, 0) - product_read = eeprom_hexfile.read(36) - product_name = binascii.unhexlify(product_read) - - # creating the "/var/run/eeprom" file and storing all the values of different fields in this file. - eeprom_file = open ("/var/run/eeprom", "a+") - eeprom_file.write("Product Name=%s\r\n" % str(product_name)) - - # like wise we are moving the file pointer to respective position where other fields are stored and extract these fields and store in /var/run/eeprom file - partnumber_position = eeprom_hexfile.seek(66, 0) - partnumber_read = eeprom_hexfile.read(20) - partnumber_name = binascii.unhexlify(partnumber_read) - eeprom_file.write("Part Number=%s\r\n" % str(partnumber_name)) - - serialnumber_position = eeprom_hexfile.seek(90, 0) - serialnumber_read = eeprom_hexfile.read(24) - serialnumber_name = binascii.unhexlify(serialnumber_read) - eeprom_file.write("Serial Number=%s\r\n" % str(serialnumber_name)) - - macaddress_position = eeprom_hexfile.seek(118, 0) - macaddress_read = eeprom_hexfile.read(12) - macaddress_name="" - for i in range(0,12,2): - macaddress_name += macaddress_read[i:i+2] + ":" - macaddress_name=macaddress_name[:-1] - eeprom_file.write("MAC Address=%s\r\n" % str(macaddress_name)) - - mfgdate_position = eeprom_hexfile.seek(132, 0) - mfgdate_read = eeprom_hexfile.read(40) - mfgdate_name = binascii.unhexlify(mfgdate_read) - eeprom_file.write("Manufacture Date=%s\r\n" % str(mfgdate_name)) - - devversion_position = eeprom_hexfile.seek(176, 0) - devversion_read = eeprom_hexfile.read(2) - eeprom_file.write("Device Version=%s\r\n" % str(devversion_read)) - - platform_position = eeprom_hexfile.seek(182, 0) - platform_read = eeprom_hexfile.read(68) - platform_name = binascii.unhexlify(platform_read) - eeprom_file.write("Platform Name=%s\r\n" % str(platform_name)) - - MACnumber_position = eeprom_hexfile.seek(254, 0) - MACnumber_read = eeprom_hexfile.read(4) - MACnumber = int(MACnumber_read, 16) - eeprom_file.write("Number of MAC Addresses=%s\r\n" % str(MACnumber)) - - vendorName_position = eeprom_hexfile.seek(262, 0) - vendorName_read = eeprom_hexfile.read(40) - vendorName = binascii.unhexlify(vendorName_read) - eeprom_file.write("Vendor Name=%s\r\n" % str(vendorName)) - - mfgname_position = eeprom_hexfile.seek(306, 0) - mfgname_read = eeprom_hexfile.read(40) - mfgname = binascii.unhexlify(mfgname_read) - eeprom_file.write("Manufacture Name=%s\r\n" % str(mfgname)) - - vendorext_position = eeprom_hexfile.seek(350, 0) - vendorext_read = eeprom_hexfile.read(124) - vendorext="" - vendorext += "0x" + vendorext_read[0:2] - for i in range(2,124,2): - vendorext += " 0x" + vendorext_read[i:i+2] - eeprom_file.write("Vendor Extension=%s\r\n" % str(vendorext)) - - IANA_position = eeprom_hexfile.seek(350, 0) - IANA_read = eeprom_hexfile.read(8) - IANAName = binascii.unhexlify(IANA_read) - eeprom_file.write("IANA=%s\r\n" % str(IANAName)) - - ASMpartrev_position = eeprom_hexfile.seek(358, 0) - ASMpartrev_read = eeprom_hexfile.read(4) - ASMpartrev = binascii.unhexlify(ASMpartrev_read) - eeprom_file.write("Assembly Part Number Rev=%s\r\n" % str(ASMpartrev)) - - ASMpartnum_position = eeprom_hexfile.seek(374, 0) - ASMpartnum_read = eeprom_hexfile.read(20) - ASMpartnum_read = binascii.unhexlify(ASMpartnum_read) - eeprom_file.write("Assembly Part Number=%s\r\n" % str(ASMpartnum_read)) - - ASMID_position = eeprom_hexfile.seek(402, 0) - ASMID_read = eeprom_hexfile.read(4) - ASMID_read_upper = ASMID_read.upper() - eeprom_file.write("Assembly ID=0x%s\r\n" % str(ASMID_read_upper)) - - ASMHWMajRev_position = eeprom_hexfile.seek(410, 0) - ASMHWMajRev_read = eeprom_hexfile.read(2) - eeprom_file.write("Assembly Major Revision=0x%s\r\n" % str(ASMHWMajRev_read)) - - ASMHWMinRev_position = eeprom_hexfile.seek(416, 0) - ASMHWMinRev_read = eeprom_hexfile.read(2) - eeprom_file.write("Assembly Minor Revision=0x%s\r\n" % str(ASMHWMinRev_read)) - - Deviation_position = eeprom_hexfile.seek(422, 0) - Deviation_read = eeprom_hexfile.read(28) - Deviation_read_upper = Deviation_read.upper() - eeprom_file.write("Deviation=0x%s\r\n" % str(Deviation_read_upper)) - - CLEI_position = eeprom_hexfile.seek(450, 0) - CLEI_read = eeprom_hexfile.read(20) - CLEI_name = binascii.unhexlify(CLEI_read) - eeprom_file.write("CLEI code=%s\r\n" % str(CLEI_name)) - - ONIEversion_position = eeprom_hexfile.seek(478, 0) - ONIEversion_read = eeprom_hexfile.read(22) - ONIEversion = binascii.unhexlify(ONIEversion_read) - eeprom_file.write("ONIE Version=%s\r\n" % str(ONIEversion)) - - CRC_position = eeprom_hexfile.seek(504, 0) - CRC = eeprom_hexfile.read(8) - eeprom_file.write("CRC=%s\r\n" % str(CRC)) - - eeprom_file.close() - return True def show_help(): diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py b/platform/broadcom/sonic-platform-modules-juniper/setup.py similarity index 57% rename from platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py rename to platform/broadcom/sonic-platform-modules-juniper/setup.py index 536f814a3509..283c00d3860f 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py +++ b/platform/broadcom/sonic-platform-modules-juniper/setup.py @@ -8,9 +8,9 @@ setup( name='sonic_platform', version='1.0', - description='Module to initialize Juniper QFX5210-64X platforms', + description='Module to initialize Juniper platforms', packages=['sonic_platform'], - package_dir={'sonic_platform': 'qfx5210/sonic_platform'}, + package_dir={'sonic_platform': 'sonic_platform'}, ) diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/__init__.py similarity index 100% rename from platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/__init__.py rename to platform/broadcom/sonic-platform-modules-juniper/sonic_platform/__init__.py diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py similarity index 54% rename from platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py rename to platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py index 674d9184df3c..0e3d43fa07e4 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py @@ -5,7 +5,7 @@ # Description: Module contains the definitions of SONiC platform APIs # which provide the chassis specific details # -# Copyright (c) 2019, Juniper Networks, Inc. +# Copyright (c) 2020, Juniper Networks, Inc. # All rights reserved. # # Notice and Disclaimer: This code is licensed to you under the GNU General @@ -39,26 +39,24 @@ import commands import sys import time + import syslog from sonic_platform_base.chassis_base import ChassisBase except ImportError as e: raise ImportError(str(e) + "- required module not found") +SYSLOG_IDENTIFIER = "Juniper-Chassis" -class Chassis(ChassisBase): - """ - JUNIPER QFX5210 Platform-specific Chassis class - """ +def log_info(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_INFO, msg) + syslog.closelog() - # Find the last reboot reason out of following - # CPLD_WATCHDOG_RESET 0x08 - # POWER_ON_RESET 0x20 - # CPU_WATCHDOG_RESET 0x40 - # SOFTWARE_RESET 0x80 +class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) - def get_qfx5210_parameter_value(self,parameter_name): + def get_parameter_value(self,parameter_name): try: with open("/var/run/eeprom", "r") as file: for item in file: @@ -71,7 +69,7 @@ def get_qfx5210_parameter_value(self,parameter_name): return "False" def get_product_name(self): - product_name_list = self.get_qfx5210_parameter_value('Product Name') + product_name_list = self.get_parameter_value('Product Name') if product_name_list: product_name = ''.join(product_name_list) return product_name @@ -80,7 +78,7 @@ def get_product_name(self): def get_part_number(self): - part_number_list = self.get_qfx5210_parameter_value('Part Number') + part_number_list = self.get_parameter_value('Part Number') if part_number_list: part_number = ''.join(part_number_list) return part_number @@ -89,7 +87,7 @@ def get_part_number(self): def get_serial_number(self): - serial_number_list = self.get_qfx5210_parameter_value('Serial Number') + serial_number_list = self.get_parameter_value('Serial Number') if serial_number_list: serial_number = ''.join(serial_number_list) return serial_number @@ -98,7 +96,7 @@ def get_serial_number(self): def get_base_mac(self): - mac_list = self.get_qfx5210_parameter_value('MAC') + mac_list = self.get_parameter_value('MAC') if mac_list: mac = ''.join(mac_list) return mac @@ -107,7 +105,7 @@ def get_base_mac(self): def get_mfg_date(self): - mfgdate_list = self.get_qfx5210_parameter_value('Manufacture Date') + mfgdate_list = self.get_parameter_value('Manufacture Date') if mfgdate_list: mfgdate = ''.join(mfgdate_list) return mfgdate @@ -115,7 +113,7 @@ def get_mfg_date(self): return False def get_deviceversion_name(self): - device_version_list = self.get_qfx5210_parameter_value('Device Version') + device_version_list = self.get_parameter_value('Device Version') if device_version_list: deviceversion_name = ''.join(device_version_list) return deviceversion_name @@ -123,7 +121,7 @@ def get_deviceversion_name(self): return False def get_platform_name(self): - platform_name_list = self.get_qfx5210_parameter_value('Platform Name') + platform_name_list = self.get_parameter_value('Platform Name') if platform_name_list: platform_name = ''.join(platform_name_list) return platform_name @@ -131,7 +129,7 @@ def get_platform_name(self): return False def get_MACnumber_name(self): - MACnumber_name_list = self.get_qfx5210_parameter_value('Number of MAC Addresses') + MACnumber_name_list = self.get_parameter_value('Number of MAC Addresses') if MACnumber_name_list: MACnumber_name = ''.join(MACnumber_name_list) return MACnumber_name @@ -139,7 +137,7 @@ def get_MACnumber_name(self): return False def get_vendor_name(self): - vendor_name_list = self.get_qfx5210_parameter_value('Vendor Name') + vendor_name_list = self.get_parameter_value('Vendor Name') if vendor_name_list: vendor_name = ''.join(vendor_name_list) return vendor_name @@ -147,7 +145,7 @@ def get_vendor_name(self): return False def get_mfg_name(self): - mfg_name_list = self.get_qfx5210_parameter_value('Manufacture Name') + mfg_name_list = self.get_parameter_value('Manufacture Name') if mfg_name_list: mfg_name = ''.join(mfg_name_list) return mfg_name @@ -155,7 +153,7 @@ def get_mfg_name(self): return False def get_vendorext_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Vendor Extension') + vendorext_list = self.get_parameter_value('Vendor Extension') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -163,7 +161,7 @@ def get_vendorext_name(self): return False def get_vendorextIANA_name(self): - vendorext_list = self.get_qfx5210_parameter_value('IANA') + vendorext_list = self.get_parameter_value('IANA') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -171,7 +169,7 @@ def get_vendorextIANA_name(self): return False def get_vendorextASMREV_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Part Number Rev') + vendorext_list = self.get_parameter_value('Assembly Part Number Rev') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -179,7 +177,7 @@ def get_vendorextASMREV_name(self): return False def get_vendorextASMPartNum_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Part Number') + vendorext_list = self.get_parameter_value('Assembly Part Number') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -187,7 +185,7 @@ def get_vendorextASMPartNum_name(self): return False def get_vendorextASMID_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly ID') + vendorext_list = self.get_parameter_value('Assembly ID') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -195,7 +193,7 @@ def get_vendorextASMID_name(self): return False def get_vendorextASMMajNum_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Major Revision') + vendorext_list = self.get_parameter_value('Assembly Major Revision') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -203,7 +201,7 @@ def get_vendorextASMMajNum_name(self): return False def get_vendorextASMMinNum_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Minor Revision') + vendorext_list = self.get_parameter_value('Assembly Minor Revision') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -211,7 +209,7 @@ def get_vendorextASMMinNum_name(self): return False def get_vendorextCLEI_name(self): - vendorext_list = self.get_qfx5210_parameter_value('CLEI code') + vendorext_list = self.get_parameter_value('CLEI code') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -219,7 +217,7 @@ def get_vendorextCLEI_name(self): return False def get_onieversion_name(self): - onieversion_name_list = self.get_qfx5210_parameter_value('ONIE Version') + onieversion_name_list = self.get_parameter_value('ONIE Version') if onieversion_name_list: onieversion_name = ''.join(onieversion_name_list) return onieversion_name @@ -227,51 +225,75 @@ def get_onieversion_name(self): return False def get_crc_name(self): - crc_list = self.get_qfx5210_parameter_value('CRC') + crc_list = self.get_parameter_value('CRC') if crc_list: crc_name = ''.join(crc_list) return crc_name else: return False - def get_fan_type(self, fantype_path): - try: - fan_type_file = open(fantype_path) - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return "-1" - else: - fan_type = fan_type_file.read() - fan_type_file.close() - return str(fan_type) - - def get_reboot_cause(self): """ Retrieves the cause of the previous reboot """ - status, last_reboot_reason = commands.getstatusoutput("i2cget -y 0 0x65 0x24") - if (status == 0): - if last_reboot_reason == "0x80": - return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) - elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": - return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) - elif last_reboot_reason == "0x20": - return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) - elif last_reboot_reason == "0x10": - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + platform_name = self.get_platform_name() + platform_name = platform_name.replace("\r","") + platform_name = platform_name.replace("\n","") + log_info("Juniper Platform name: {} and {}".format(self.get_platform_name(), platform_name)) + if str(platform_name) == "x86_64-juniper_networks_qfx5210-r0": + log_info("Juniper Platform QFX5210 ") + status, last_reboot_reason = commands.getstatusoutput("i2cget -f -y 0 0x65 0x24") + if (status == 0): + if last_reboot_reason == "0x80": + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") else: - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + time.sleep(3) + status, last_reboot_reason = commands.getstatusoutput("i2cget -f -y 0 0x65 0x24") + if last_reboot_reason == "0x80": + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + + elif str(platform_name) == "x86_64-juniper_networks_qfx5200-r0" : + log_info("Juniper Platform QFX5200 ") + status, last_reboot_reason = commands.getstatusoutput("busybox devmem 0xFED50004 8") + if (status == 0): + if last_reboot_reason == "0x80": + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + else: + time.sleep(3) + status, last_reboot_reason = commands.getstatusoutput("busybox devmem 0xFED50004 8") + if last_reboot_reason == "0x80": + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") else: - time.sleep(3) - status, last_reboot_reason = commands.getstatusoutput("i2cget -y 0 0x65 0x24") - if last_reboot_reason == "0x80": - return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) - elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": - return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) - elif last_reboot_reason == "0x20": - return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) - elif last_reboot_reason == "0x10": - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") - else: - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + log_info("Juniper QFX5200 and QFX5210 platforms are supported") diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/platform.py similarity index 73% rename from platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/platform.py rename to platform/broadcom/sonic-platform-modules-juniper/sonic_platform/platform.py index a9e70c725195..c3a596111d38 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/sonic_platform/platform.py +++ b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/platform.py @@ -2,7 +2,7 @@ # # Name: platform.py, version: 1.0 # -# Description: Module contains the definitions of SONiC platform APIs +# Description: Module contains the definition of SONiC platform API # which provide the platform specific details # # Copyright (c) 2020, Juniper Networks, Inc. @@ -35,31 +35,18 @@ # +import sys + try: from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis except ImportError as e: raise ImportError("%s - required module not found" % e) -platformDict = {'platform':'QFX5200-32C'} - class Platform(PlatformBase): + """ + Juniper Platform-specific class + """ def __init__(self): - self.platform = self.getPlatform() - - def getPlatformDict(self): - global platformDict - if platformDict: - return platformDict - - def readPlatformName(self): - return self.getPlatformDict().get('platform') - - def getPlatform(self): - platformCls = self.readPlatformName() - return platformCls - - def get_chassis(self): - from chassis import Chassis - chassis = Chassis() - return chassis - + PlatformBase.__init__(self) + self._chassis = Chassis() From 860cb265ac70aa718941756cdaf85274857e6698 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 21 Apr 2020 18:00:48 +0300 Subject: [PATCH 0572/1427] [PMON] Extend pmon daemon start control to lm-sensors and fancontrol (#4447) --- .../mellanox/x86_64-mlnx_msn2700-r0/pmon_daemon_control.json | 3 ++- .../docker-platform-monitor/docker-pmon.supervisord.conf.j2 | 4 ++++ dockers/docker-platform-monitor/start.sh.j2 | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn2700-r0/pmon_daemon_control.json index 44bad6494229..d12b2100eea8 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/pmon_daemon_control.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_fancontrol": true } diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index 21b508ab8f05..87b6808a744c 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -26,6 +26,7 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog +{% if not skip_sensors %} [program:lm-sensors] command=/usr/bin/lm-sensors.sh priority=3 @@ -34,7 +35,9 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +{% endif %} +{% if not skip_fancontrol %} [program:fancontrol] command=/usr/sbin/fancontrol priority=4 @@ -43,6 +46,7 @@ autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog startsecs=10 +{% endif %} {% if not skip_ledd %} [program:ledd] diff --git a/dockers/docker-platform-monitor/start.sh.j2 b/dockers/docker-platform-monitor/start.sh.j2 index a72f4fa8eb85..03e0b49b8c4d 100644 --- a/dockers/docker-platform-monitor/start.sh.j2 +++ b/dockers/docker-platform-monitor/start.sh.j2 @@ -19,6 +19,7 @@ if [ -e /usr/share/sonic/platform/platform_wait ]; then fi fi +{% if not skip_sensors %} # If this platform has an lm-sensors config file, copy it to it's proper place # and start lm-sensors if [ -e /usr/share/sonic/platform/sensors.conf ]; then @@ -26,7 +27,9 @@ if [ -e /usr/share/sonic/platform/sensors.conf ]; then /bin/cp -f /usr/share/sonic/platform/sensors.conf /etc/sensors.d/ supervisorctl start lm-sensors fi +{% endif %} +{% if not skip_fancontrol %} # If this platform has a fancontrol config file, copy it to it's proper place # and start fancontrol if [ -e /usr/share/sonic/platform/fancontrol ]; then @@ -36,6 +39,7 @@ if [ -e /usr/share/sonic/platform/fancontrol ]; then /bin/cp -f /usr/share/sonic/platform/fancontrol /etc/ supervisorctl start fancontrol fi +{% endif %} # If the sonic-platform package is not installed, try to install it From c730f3e2079ddae78f5db3401eab35046e21dd4f Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Tue, 21 Apr 2020 23:09:53 +0800 Subject: [PATCH 0573/1427] [Mellanox] thermal control enhancement for dynamic minimum fan speed and PSU fan speed policy (#4403) --- .../thermal_policy.json | 27 ++- dockers/docker-platform-monitor/Dockerfile.j2 | 3 +- .../sonic_platform/chassis.py | 12 +- .../sonic_platform/device_data.py | 101 ++++++++ .../mlnx-platform-api/sonic_platform/fan.py | 104 +++++++-- .../mlnx-platform-api/sonic_platform/psu.py | 4 +- .../sonic_platform/thermal.py | 148 +++++++++++- .../sonic_platform/thermal_actions.py | 114 ++++++++- .../sonic_platform/thermal_conditions.py | 68 ++++++ .../sonic_platform/thermal_infos.py | 22 +- .../sonic_platform/thermal_manager.py | 55 +++-- .../mlnx-platform-api/tests/mock_platform.py | 14 +- .../tests/test_thermal_policy.py | 217 +++++++++++++++++- .../tests/thermal_policy.json | 25 ++ 14 files changed, 849 insertions(+), 65 deletions(-) create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json index 054d797be951..f16f68dd002e 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json @@ -1,6 +1,6 @@ { "thermal_control_algorithm": { - "run_at_boot_up": "false", + "run_at_boot_up": "true", "fan_speed_when_suspend": "60" }, "info_types": [ @@ -51,6 +51,24 @@ } ] }, + { + "name": "any fan broken", + "conditions": [ + { + "type": "fan.any.fault" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, { "name": "all fan and psu presence", "conditions": [ @@ -59,12 +77,15 @@ }, { "type": "psu.all.presence" + }, + { + "type": "fan.all.good" } ], "actions": [ { - "type": "fan.all.set_speed", - "speed": "60" + "type": "thermal_control.control", + "status": "true" } ] } diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index c1e86abb5170..d1b6d7dfc779 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -17,7 +17,8 @@ RUN apt-get update && \ rrdtool \ python-smbus \ ethtool \ - dmidecode && \ + dmidecode \ + i2c-tools && \ pip install enum34 {% if docker_platform_monitor_debs.strip() -%} diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 08c2ccf80a5c..d47110ed8f45 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -29,6 +29,7 @@ MLNX_NUM_PSU = 2 GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" +GET_PLATFORM_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.platform" EEPROM_CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' EEPROM_CACHE_FILE = 'syseeprom_cache' @@ -60,6 +61,7 @@ def __init__(self): # Initialize SKU name self.sku_name = self._get_sku_name() + self.platform_name = self._get_platform_name() mi = get_machine_info() if mi is not None: self.name = mi['onie_platform'] @@ -110,9 +112,9 @@ def initialize_fan(self): for index in range(num_of_fan): if multi_rotor_in_drawer: - fan = Fan(has_fan_dir, index, index/2, False, self.sku_name) + fan = Fan(has_fan_dir, index, index/2, False, self.platform_name) else: - fan = Fan(has_fan_dir, index, index, False, self.sku_name) + fan = Fan(has_fan_dir, index, index, False, self.platform_name) self._fan_list.append(fan) @@ -245,6 +247,12 @@ def _get_sku_name(self): return out.rstrip('\n') + def _get_platform_name(self): + p = subprocess.Popen(GET_PLATFORM_CMD, shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + return out.rstrip('\n') + + def _get_port_position_tuple_by_sku_name(self): position_tuple = port_position_tuple_list[hwsku_dict_port[self.sku_name]] return position_tuple diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py new file mode 100644 index 000000000000..f006281c511f --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py @@ -0,0 +1,101 @@ +DEVICE_DATA = { + 'x86_64-mlnx_msn2700-r0': { + 'thermal': { + 'minimum_table': { + "p2c_trust": {"-127:40":13, "41:120":15}, + "p2c_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16}, + "c2p_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, + "c2p_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, + "unk_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, + "unk_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16} + } + } + }, + 'x86_64-mlnx_msn2740-r0': { + 'thermal': { + 'minimum_table': { + "p2c_trust": {"-127:120":13}, + "p2c_untrust": {"-127:35":13, "36:40":14 , "41:120":15}, + "c2p_trust": {"-127:120":13}, + "c2p_untrust": {"-127:15":13, "16:30":14 , "31:35":15, "36:120":17}, + "unk_trust": {"-127:120":13}, + "unk_untrust": {"-127:15":13, "16:30":14 , "31:35":15, "36:120":17}, + } + } + }, + 'x86_64-mlnx_msn2100-r0': { + 'thermal': { + 'minimum_table': { + "p2c_trust": {"-127:120":12}, + "p2c_untrust": {"-127:15":12, "16:25":13, "26:30":14, "31:35":15, "36:120":16}, + "c2p_trust": {"-127:40":12, "41:120":13}, + "c2p_untrust": {"-127:40":12, "41:120":13}, + "unk_trust": {"-127:40":12, "41:120":13}, + "unk_untrust": {"-127:15":12, "16:25":13, "26:30":14, "31:35":15, "36:120":16} + } + } + }, + 'x86_64-mlnx_msn2410-r0': { + 'thermal': { + 'minimum_table': { + "p2c_trust": {"-127:40":13, "41:120":15}, + "p2c_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16}, + "c2p_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, + "c2p_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, + "unk_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, + "unk_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16} + } + } + }, + 'x86_64-mlnx_msn2010-r0': { + 'thermal': { + 'minimum_table': { + "p2c_trust": {"-127:120":12}, + "p2c_untrust": {"-127:15":12, "16:20":13, "21:30":14, "31:35":15, "36:120":16}, + "c2p_trust": {"-127:120":12}, + "c2p_untrust": {"-127:20":12, "21:25":13 , "26:30":14, "31:35":15, "36:120":16}, + "unk_trust": {"-127:120":12}, + "unk_untrust": {"-127:15":12, "16:20":13 , "21:30":14, "31:35":15, "36:120":16} + } + } + }, + 'x86_64-mlnx_msn3700-r0': { + 'thermal': { + 'minimum_table': { + "p2c_trust": {"-127:25":12, "26:40":13 , "41:120":14}, + "p2c_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, + "c2p_trust": {"-127:25":12, "26:40":13 , "41:120":14}, + "c2p_untrust": {"-127:25":12, "26:40":13 , "41:120":14}, + "unk_trust": {"-127:25":12, "26:40":13 , "41:120":14}, + "unk_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, + } + } + }, + 'x86_64-mlnx_msn3700c-r0': { + 'thermal': { + 'minimum_table': { + "p2c_trust": {"-127:25":12, "26:40":13 , "41:120":14}, + "p2c_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, + "c2p_trust": {"-127:25":12, "26:40":13 , "41:120":14}, + "c2p_untrust": {"-127:25":12, "26:40":13 , "41:120":14}, + "unk_trust": {"-127:25":12, "26:40":13 , "41:120":14}, + "unk_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, + } + } + }, + 'x86_64-mlnx_msn3800-r0': { + 'thermal': { + 'minimum_table': { + "p2c_trust": {"-127:35":12, "36:120":13}, + "p2c_untrust": {"-127:0":12, "1:10":13 , "11:15":14, "16:20":15, "21:35":16, "36:120":17}, + "c2p_trust": {"-127:30":12, "31:40":13 , "41:120":14}, + "c2p_untrust": {"-127:20":12, "21:30":13 , "31:35":14, "36:40":15, "41:120":16}, + "unk_trust": {"-127:30":12, "31:40":13 , "41:120":14}, + "unk_untrust": {"-127:0":12, "1:10":13 , "11:15":14, "16:20":15, "21:35":16, "36:120":17}, + } + } + }, + 'x86_64-mlnx_msn4700-r0': { + + } +} \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py index 9ce65d1e2f98..adca48befbc6 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py @@ -9,6 +9,7 @@ ############################################################################# import os.path +import subprocess try: from sonic_platform_base.fan_base import FanBase @@ -22,25 +23,34 @@ FAN_PATH = "/var/run/hw-management/thermal/" LED_PATH = "/var/run/hw-management/led/" +CONFIG_PATH = "/var/run/hw-management/config" # fan_dir isn't supported on Spectrum 1. It is supported on Spectrum 2 and later switches FAN_DIR = "/var/run/hw-management/system/fan_dir" +COOLING_STATE_PATH = "/var/run/hw-management/thermal/cooling_cur_state" -# SKUs with unplugable FANs: +# Platforms with unplugable FANs: # 1. don't have fanX_status and should be treated as always present -hwsku_dict_with_unplugable_fan = ['ACS-MSN2010', 'ACS-MSN2100'] +platform_with_unplugable_fan = ['x86_64-mlnx_msn2010-r0', 'x86_64-mlnx_msn2100-r0'] + class Fan(FanBase): """Platform-specific Fan class""" STATUS_LED_COLOR_ORANGE = "orange" - - def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False, sku = None): + min_cooling_level = 2 + MIN_VALID_COOLING_LEVEL = 1 + MAX_VALID_COOLING_LEVEL = 10 + # PSU fan speed vector + PSU_FAN_SPEED = ['0x3c', '0x3c', '0x3c', '0x3c', '0x3c', + '0x3c', '0x3c', '0x46', '0x50', '0x5a', '0x64'] + + def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False, platform = None): # API index is starting from 0, Mellanox platform index is starting from 1 self.index = fan_index + 1 self.drawer_index = drawer_index + 1 self.is_psu_fan = psu_fan - self.always_presence = False if sku not in hwsku_dict_with_unplugable_fan else True + self.always_presence = False if platform not in platform_with_unplugable_fan else True self.fan_min_speed_path = "fan{}_min".format(self.index) if not self.is_psu_fan: @@ -54,6 +64,10 @@ def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False, sk self.fan_presence_path = "psu{}_fan1_speed_get".format(self.index) self._name = 'psu_{}_fan_{}'.format(self.index, 1) self.fan_max_speed_path = None + self.psu_i2c_bus_path = os.path.join(CONFIG_PATH, 'psu{0}_i2c_bus'.format(self.index)) + self.psu_i2c_addr_path = os.path.join(CONFIG_PATH, 'psu{0}_i2c_addr'.format(self.index)) + self.psu_i2c_command_path = os.path.join(CONFIG_PATH, 'fan_command') + self.fan_status_path = "fan{}_fault".format(self.index) self.fan_green_led_path = "led_fan{}_green".format(self.drawer_index) self.fan_red_led_path = "led_fan{}_red".format(self.drawer_index) @@ -90,7 +104,7 @@ def get_direction(self): try: with open(os.path.join(self.fan_dir), 'r') as fan_dir: - fan_dir_bits = int(fan_dir.read()) + fan_dir_bits = int(fan_dir.read().strip()) fan_mask = 1 << self.drawer_index - 1 if fan_dir_bits & fan_mask: return self.FAN_DIRECTION_INTAKE @@ -116,7 +130,7 @@ def get_status(self): else: try: with open(os.path.join(FAN_PATH, self.fan_status_path), 'r') as fault_status: - status = int(fault_status.read()) + status = int(fault_status.read().strip()) except (ValueError, IOError): status = 1 @@ -142,7 +156,7 @@ def get_presence(self): else: try: with open(os.path.join(FAN_PATH, self.fan_presence_path), 'r') as presence_status: - status = int(presence_status.read()) + status = int(presence_status.read().strip()) except (ValueError, IOError): status = 0 @@ -164,7 +178,7 @@ def _get_max_speed_in_rpm(self): speed = 0 try: with open(os.path.join(FAN_PATH, self.fan_max_speed_path), 'r') as max_fan_speed: - speed = int(max_fan_speed.read()) + speed = int(max_fan_speed.read().strip()) except (ValueError, IOError): speed = 0 @@ -181,7 +195,7 @@ def get_speed(self): speed = 0 try: with open(os.path.join(FAN_PATH, self.fan_speed_get_path), 'r') as fan_curr_speed: - speed_in_rpm = int(fan_curr_speed.read()) + speed_in_rpm = int(fan_curr_speed.read().strip()) except (ValueError, IOError): speed_in_rpm = 0 @@ -210,7 +224,7 @@ def get_target_speed(self): try: with open(os.path.join(FAN_PATH, self.fan_speed_set_path), 'r') as fan_pwm: - pwm = int(fan_pwm.read()) + pwm = int(fan_pwm.read().strip()) except (ValueError, IOError): pwm = 0 @@ -231,13 +245,34 @@ def set_speed(self, speed): bool: True if set success, False if fail. """ status = True - pwm = int(round(PWM_MAX*speed/100.0)) if self.is_psu_fan: - #PSU fan speed is not setable. - return False - + from .thermal import logger + try: + with open(self.psu_i2c_bus_path, 'r') as f: + bus = f.read().strip() + with open(self.psu_i2c_addr_path, 'r') as f: + addr = f.read().strip() + with open(self.psu_i2c_command_path, 'r') as f: + command = f.read().strip() + speed = Fan.PSU_FAN_SPEED[int(speed / 10)] + command = "i2cset -f -y {0} {1} {2} {3} wp".format(bus, addr, command, speed) + subprocess.check_call(command, shell = True) + return True + except subprocess.CalledProcessError as ce: + logger.log_error('Failed to call command {}, return code={}, command output={}'.format(ce.cmd, ce.returncode, ce.output)) + return False + except Exception as e: + logger.log_error('Failed to set PSU FAN speed - {}'.format(e)) + return False + try: + cooling_level = int(speed / 10) + if cooling_level < self.min_cooling_level: + cooling_level = self.min_cooling_level + speed = self.min_cooling_level * 10 + self.set_cooling_level(cooling_level, cooling_level) + pwm = int(round(PWM_MAX*speed/100.0)) with open(os.path.join(FAN_PATH, self.fan_speed_set_path), 'w') as fan_pwm: fan_pwm.write(str(pwm)) except (ValueError, IOError): @@ -352,3 +387,42 @@ def get_speed_tolerance(self): """ # The tolerance value is fixed as 20% for all the Mellanox platform return 20 + + @classmethod + def set_cooling_level(cls, level, cur_state): + """ + Change cooling level. The input level should be an integer value [1, 10]. + 1 means 10%, 2 means 20%, 10 means 100%. + """ + if not isinstance(level, int): + raise RuntimeError("Failed to set cooling level, input parameter must be integer") + + if level < cls.MIN_VALID_COOLING_LEVEL or level > cls.MAX_VALID_COOLING_LEVEL: + raise RuntimeError("Failed to set cooling level, level value must be in range [{}, {}], got {}".format( + cls.MIN_VALID_COOLING_LEVEL, + cls.MAX_VALID_COOLING_LEVEL, + level + )) + + try: + # Reset FAN cooling level vector. According to low level team, + # if we need set cooling level to X, we need first write a (10+X) + # to cooling_cur_state file to reset the cooling level vector. + with open(COOLING_STATE_PATH, 'w') as cooling_state: + cooling_state.write(str(level + 10)) + + # We need set cooling level after resetting the cooling level vector + with open(COOLING_STATE_PATH, 'w') as cooling_state: + cooling_state.write(str(cur_state)) + except (ValueError, IOError) as e: + raise RuntimeError("Failed to set cooling level - {}".format(e)) + + @classmethod + def get_cooling_level(cls): + try: + with open(COOLING_STATE_PATH, 'r') as cooling_state: + cooling_level = int(cooling_state.read().strip()) + return cooling_level + except (ValueError, IOError) as e: + raise RuntimeError("Failed to get cooling level - {}".format(e)) + diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 1dfcf54baf17..3f2fee433faf 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -101,7 +101,7 @@ def __init__(self, psu_index, sku): # unplugable PSU has no FAN if sku not in hwsku_dict_with_unplugable_psu: - fan = Fan(sku, psu_index, psu_index, True) + fan = Fan(False, psu_index, psu_index, True) self._fan_list.append(fan) self.psu_green_led_path = "led_psu_green" @@ -121,7 +121,7 @@ def _read_generic_file(self, filename, len): result = 0 try: with open(filename, 'r') as fileobj: - result = int(fileobj.read()) + result = int(fileobj.read().strip()) except Exception as e: logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) return result diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index a5faa5ea793a..39f91913fe1e 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -42,6 +42,16 @@ HW_MGMT_THERMAL_ROOT = "/var/run/hw-management/thermal/" +THERMAL_ZONE_ASIC_PATH = "/var/run/hw-management/thermal/mlxsw/" +THERMAL_ZONE_MODULE_PATH = "/var/run/hw-management/thermal/mlxsw-module{}/" +THERMAL_ZONE_GEARBOX_PATH = "/var/run/hw-management/thermal/mlxsw-gearbox{}/" +THERMAL_ZONE_MODE = "thermal_zone_mode" +THERMAL_ZONE_POLICY = "thermal_zone_policy" +THERMAL_ZONE_TEMPERATURE = "thermal_zone_temp" +THERMAL_ZONE_NORMAL_TEMPERATURE = "temp_trip_norm" + +MODULE_TEMPERATURE_FAULT_PATH = "/var/run/hw-management/thermal/module{}_temp_fault" + thermal_api_handler_cpu_core = { THERMAL_API_GET_TEMPERATURE:"cpu_core{}", THERMAL_API_GET_HIGH_THRESHOLD:"cpu_core{}_max", @@ -262,6 +272,7 @@ def initialize_thermals(sku, thermal_list, psu_list): # create thermal objects for all categories of sensors tp_index = hwsku_dict_thermal[sku] thermal_profile = thermal_profile_list[tp_index] + Thermal.thermal_profile = thermal_profile for category in thermal_device_categories_all: if category == THERMAL_DEV_CATEGORY_AMBIENT: count, ambient_list = thermal_profile[category] @@ -290,6 +301,9 @@ def initialize_thermals(sku, thermal_list, psu_list): class Thermal(ThermalBase): + thermal_profile = None + thermal_algorithm_status = False + def __init__(self, category, index, has_index, dependency = None): """ index should be a string for category ambient and int for other categories @@ -321,14 +335,15 @@ def get_name(self): return self.name - def _read_generic_file(self, filename, len): + @classmethod + def _read_generic_file(cls, filename, len): """ Read a generic file, returns the contents of the file """ result = None try: with open(filename, 'r') as fileobj: - result = fileobj.read() + result = fileobj.read().strip() except Exception as e: logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) return result @@ -420,3 +435,132 @@ def get_high_critical_threshold(self): if self.category == THERMAL_DEV_CATEGORY_MODULE and value_float == THERMAL_API_INVALID_HIGH_THRESHOLD: return None return value_float / 1000.0 + + + @classmethod + def _write_generic_file(cls, filename, content): + """ + Generic functions to write content to a specified file path if + the content has changed. + """ + try: + with open(filename, 'w+') as file_obj: + origin_content = file_obj.read() + if origin_content != content: + file_obj.write(content) + except Exception as e: + logger.log_info("Fail to write file {} due to {}".format(filename, repr(e))) + + @classmethod + def set_thermal_algorithm_status(cls, status, force=True): + """ + Enable/disable kernel thermal algorithm. + When enable kernel thermal algorithm, kernel will adjust fan speed + according to thermal zones temperature. Please note that kernel will + only adjust fan speed when temperature across some "edge", e.g temperature + changes to exceed high threshold. + When disable kernel thermal algorithm, kernel no longer adjust fan speed. + We usually disable the algorithm when we want to set a fix speed. E.g, when + a fan unit is removed from system, we will set fan speed to 100% and disable + the algorithm to avoid it adjust the speed. + """ + if not cls.thermal_profile: + raise Exception("Fail to get thermal profile for this switch") + + if not force and cls.thermal_algorithm_status == status: + return + + cls.thermal_algorithm_status = status + content = "enabled" if status else "disabled" + policy = "step_wise" if status else "user_space" + cls._write_generic_file(join(THERMAL_ZONE_ASIC_PATH, THERMAL_ZONE_MODE), content) + cls._write_generic_file(join(THERMAL_ZONE_ASIC_PATH, THERMAL_ZONE_POLICY), policy) + + if THERMAL_DEV_CATEGORY_MODULE in cls.thermal_profile: + start, count = cls.thermal_profile[THERMAL_DEV_CATEGORY_MODULE] + if count != 0: + for index in range(count): + cls._write_generic_file(join(THERMAL_ZONE_MODULE_PATH.format(start + index), THERMAL_ZONE_MODE), content) + cls._write_generic_file(join(THERMAL_ZONE_MODULE_PATH.format(start + index), THERMAL_ZONE_POLICY), policy) + + if THERMAL_DEV_CATEGORY_GEARBOX in cls.thermal_profile: + start, count = cls.thermal_profile[THERMAL_DEV_CATEGORY_GEARBOX] + if count != 0: + for index in range(count): + cls._write_generic_file(join(THERMAL_ZONE_GEARBOX_PATH.format(start + index), THERMAL_ZONE_MODE), content) + cls._write_generic_file(join(THERMAL_ZONE_GEARBOX_PATH.format(start + index), THERMAL_ZONE_POLICY), policy) + + @classmethod + def check_thermal_zone_temperature(cls): + """ + Check thermal zone current temperature with normal temperature + + Returns: + True if all thermal zones current temperature less or equal than normal temperature + """ + if not cls.thermal_profile: + raise Exception("Fail to get thermal profile for this switch") + + if not cls._check_thermal_zone_temperature(THERMAL_ZONE_ASIC_PATH): + return False + + if THERMAL_DEV_CATEGORY_MODULE in cls.thermal_profile: + start, count = cls.thermal_profile[THERMAL_DEV_CATEGORY_MODULE] + if count != 0: + for index in range(count): + if not cls._check_thermal_zone_temperature(THERMAL_ZONE_MODULE_PATH.format(start + index)): + return False + + if THERMAL_DEV_CATEGORY_GEARBOX in cls.thermal_profile: + start, count = cls.thermal_profile[THERMAL_DEV_CATEGORY_GEARBOX] + if count != 0: + for index in range(count): + if not cls._check_thermal_zone_temperature(THERMAL_ZONE_GEARBOX_PATH.format(start + index)): + return False + + return True + + @classmethod + def _check_thermal_zone_temperature(cls, thermal_zone_path): + normal_temp_path = join(thermal_zone_path, THERMAL_ZONE_NORMAL_TEMPERATURE) + current_temp_path = join(thermal_zone_path, THERMAL_ZONE_TEMPERATURE) + normal = None + current = None + try: + with open(normal_temp_path, 'r') as file_obj: + normal = float(file_obj.read()) + + with open(current_temp_path, 'r') as file_obj: + current = float(file_obj.read()) + + return current <= normal + except Exception as e: + logger.log_info("Fail to check thermal zone temperature for file {} due to {}".format(thermal_zone_path, repr(e))) + + @classmethod + def check_module_temperature_trustable(cls): + if not cls.thermal_profile: + raise Exception("Fail to get thermal profile for this switch") + + start, count = cls.thermal_profile[THERMAL_DEV_CATEGORY_MODULE] + for index in range(count): + fault_file_path = MODULE_TEMPERATURE_FAULT_PATH.format(index + start) + fault = cls._read_generic_file(fault_file_path, 0) + if fault.strip() != '0': + return 'untrust' + return 'trust' + + @classmethod + def get_air_flow_direction(cls): + fan_ambient_path = join(HW_MGMT_THERMAL_ROOT, THERMAL_DEV_FAN_AMBIENT) + port_ambient_path = join(HW_MGMT_THERMAL_ROOT, THERMAL_DEV_PORT_AMBIENT) + + # if there is any exception, let it raise + fan_ambient_temp = int(cls._read_generic_file(fan_ambient_path, 0)) + port_ambient_temp = int(cls._read_generic_file(port_ambient_path, 0)) + if fan_ambient_temp > port_ambient_temp: + return 'p2c', fan_ambient_temp + elif fan_ambient_temp < port_ambient_temp: + return 'c2p', port_ambient_temp + else: + return 'unk', fan_ambient_temp diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py index 72729287d1c5..1f8292763ddd 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py @@ -1,5 +1,6 @@ from sonic_platform_base.sonic_thermal_control.thermal_action_base import ThermalPolicyActionBase from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object +from .thermal import logger class SetFanSpeedAction(ThermalPolicyActionBase): @@ -52,7 +53,38 @@ def execute(self, thermal_info_dict): fan_info_obj = thermal_info_dict[FanInfo.INFO_NAME] for fan in fan_info_obj.get_presence_fans(): fan.set_speed(self.speed) + logger.log_info('Set all system FAN speed to {}'.format(self.speed)) + SetAllFanSpeedAction.set_psu_fan_speed(thermal_info_dict, self.speed) + + @classmethod + def set_psu_fan_speed(cls, thermal_info_dict, speed): + from .thermal_infos import ChassisInfo + if ChassisInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[ChassisInfo.INFO_NAME], ChassisInfo): + chassis = thermal_info_dict[ChassisInfo.INFO_NAME].get_chassis() + for psu in chassis.get_all_psus(): + for psu_fan in psu.get_all_fans(): + psu_fan.set_speed(speed) + + logger.log_info('Updated PSU FAN speed to {}%'.format(speed)) + + + +@thermal_json_object('fan.all.check_and_set_speed') +class CheckAndSetAllFanSpeedAction(SetAllFanSpeedAction): + """ + Action to check thermal zone temperature and recover speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Check thermal zone and set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + from .thermal import Thermal + if Thermal.check_thermal_zone_temperature(): + SetAllFanSpeedAction.execute(self, thermal_info_dict) + @thermal_json_object('thermal_control.control') class ControlThermalAlgoAction(ThermalPolicyActionBase): @@ -95,14 +127,80 @@ def execute(self, thermal_info_dict): :param thermal_info_dict: A dictionary stores all thermal information. :return: """ + from .thermal_infos import FanInfo + from .thermal import Thermal + from .thermal_conditions import UpdateCoolingLevelToMinCondition + from .fan import Fan + Thermal.set_thermal_algorithm_status(self.status, False) + if self.status: + # Check thermal zone temperature, if all thermal zone temperature + # back to normal, set it to minimum allowed speed to + # save power + UpdateCoolingLevelToMinAction.update_cooling_level_to_minimum(thermal_info_dict) + + logger.log_info('Changed thermal algorithm status to {}'.format(self.status)) + + +class ChangeMinCoolingLevelAction(ThermalPolicyActionBase): + UNKNOWN_SKU_COOLING_LEVEL = 6 + def execute(self, thermal_info_dict): + from .device_data import DEVICE_DATA + from .fan import Fan from .thermal_infos import ChassisInfo - if ChassisInfo.INFO_NAME in thermal_info_dict: - chassis_info_obj = thermal_info_dict[ChassisInfo.INFO_NAME] - chassis = chassis_info_obj.get_chassis() - thermal_manager = chassis.get_thermal_manager() - if self.status: - thermal_manager.start_thermal_control_algorithm() - else: - thermal_manager.stop_thermal_control_algorithm() + from .thermal_conditions import MinCoolingLevelChangeCondition + from .thermal_conditions import UpdateCoolingLevelToMinCondition + chassis = thermal_info_dict[ChassisInfo.INFO_NAME].get_chassis() + if chassis.platform_name not in DEVICE_DATA or 'thermal' not in DEVICE_DATA[chassis.platform_name] or 'minimum_table' not in DEVICE_DATA[chassis.platform_name]['thermal']: + Fan.min_cooling_level = ChangeMinCoolingLevelAction.UNKNOWN_SKU_COOLING_LEVEL + else: + air_flow_dir = MinCoolingLevelChangeCondition.air_flow_dir + trust_state = MinCoolingLevelChangeCondition.trust_state + temperature = MinCoolingLevelChangeCondition.temperature + minimum_table = DEVICE_DATA[chassis.platform_name]['thermal']['minimum_table']['{}_{}'.format(air_flow_dir, trust_state)] + + for key, cooling_level in minimum_table.items(): + temp_range = key.split(':') + temp_min = int(temp_range[0].strip()) + temp_max = int(temp_range[1].strip()) + if temp_min <= temperature <= temp_max: + Fan.min_cooling_level = cooling_level - 10 + break + + current_cooling_level = Fan.get_cooling_level() + if current_cooling_level < Fan.min_cooling_level: + Fan.set_cooling_level(Fan.min_cooling_level, Fan.min_cooling_level) + SetAllFanSpeedAction.set_psu_fan_speed(thermal_info_dict, Fan.min_cooling_level * 10) + else: + Fan.set_cooling_level(Fan.min_cooling_level, current_cooling_level) + UpdateCoolingLevelToMinAction.update_cooling_level_to_minimum(thermal_info_dict) + + logger.log_info('Changed minimum cooling level to {}'.format(Fan.min_cooling_level)) + + +class UpdatePsuFanSpeedAction(ThermalPolicyActionBase): + def execute(self, thermal_info_dict): + from .thermal_conditions import CoolingLevelChangeCondition + SetAllFanSpeedAction.set_psu_fan_speed(thermal_info_dict, CoolingLevelChangeCondition.cooling_level * 10) + + +class UpdateCoolingLevelToMinAction(ThermalPolicyActionBase): + def execute(self, thermal_info_dict): + self.update_cooling_level_to_minimum(thermal_info_dict) + + @classmethod + def update_cooling_level_to_minimum(cls, thermal_info_dict): + from .fan import Fan + from .thermal import Thermal + from .thermal_conditions import UpdateCoolingLevelToMinCondition + from .thermal_infos import FanInfo + if Thermal.check_thermal_zone_temperature(): + fan_info_obj = thermal_info_dict[FanInfo.INFO_NAME] + speed = Fan.min_cooling_level * 10 + for fan in fan_info_obj.get_presence_fans(): + fan.set_speed(speed) + SetAllFanSpeedAction.set_psu_fan_speed(thermal_info_dict, speed) + UpdateCoolingLevelToMinCondition.enable = False + else: + UpdateCoolingLevelToMinCondition.enable = True diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py index 2df59acc9bf1..6bd2d282862b 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py @@ -32,6 +32,20 @@ def is_match(self, thermal_info_dict): return len(fan_info_obj.get_absence_fans()) == 0 if fan_info_obj else False +@thermal_json_object('fan.any.fault') +class AnyFanFaultCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_fault_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.good') +class AllFanGoodCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_fault_fans()) == 0 if fan_info_obj else False + + class PsuCondition(ThermalPolicyConditionBase): def get_psu_info(self, thermal_info_dict): from .thermal_infos import PsuInfo @@ -61,3 +75,57 @@ def is_match(self, thermal_info_dict): psu_info_obj = self.get_psu_info(thermal_info_dict) return len(psu_info_obj.get_absence_psus()) == 0 if psu_info_obj else False + +class MinCoolingLevelChangeCondition(ThermalPolicyConditionBase): + trust_state = None + air_flow_dir = None + temperature = None + + def is_match(self, thermal_info_dict): + from .thermal import Thermal + + trust_state = Thermal.check_module_temperature_trustable() + air_flow_dir, temperature = Thermal.get_air_flow_direction() + temperature = temperature / 1000 + + change_cooling_level = False + if trust_state != MinCoolingLevelChangeCondition.trust_state: + MinCoolingLevelChangeCondition.trust_state = trust_state + change_cooling_level = True + + if air_flow_dir != MinCoolingLevelChangeCondition.air_flow_dir: + MinCoolingLevelChangeCondition.air_flow_dir = air_flow_dir + change_cooling_level = True + + if temperature != MinCoolingLevelChangeCondition.temperature: + MinCoolingLevelChangeCondition.temperature = temperature + change_cooling_level = True + + return change_cooling_level + + +class CoolingLevelChangeCondition(ThermalPolicyConditionBase): + cooling_level = None + + def is_match(self, thermal_info_dict): + from .fan import Fan + current_cooling_level = Fan.get_cooling_level() + if current_cooling_level != CoolingLevelChangeCondition.cooling_level: + CoolingLevelChangeCondition.cooling_level = current_cooling_level + return True + else: + return False + + +class UpdateCoolingLevelToMinCondition(ThermalPolicyConditionBase): + enable = False + def is_match(self, thermal_info_dict): + if not UpdateCoolingLevelToMinCondition.enable: + return False + + from .fan import Fan + current_cooling_level = Fan.get_cooling_level() + if current_cooling_level == Fan.min_cooling_level: + UpdateCoolingLevelToMinCondition.enable = False + return False + return True diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py index 82c186495f5e..e810a5646456 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py @@ -14,6 +14,7 @@ class FanInfo(ThermalPolicyInfoBase): def __init__(self): self._absence_fans = set() self._presence_fans = set() + self._fault_fans = set() self._status_changed = False def collect(self, chassis): @@ -24,17 +25,27 @@ def collect(self, chassis): """ self._status_changed = False for fan in chassis.get_all_fans(): - if fan.get_presence() and fan not in self._presence_fans: + presence = fan.get_presence() + status = fan.get_status() + if presence and fan not in self._presence_fans: self._presence_fans.add(fan) self._status_changed = True if fan in self._absence_fans: self._absence_fans.remove(fan) - elif not fan.get_presence() and fan not in self._absence_fans: + elif not presence and fan not in self._absence_fans: self._absence_fans.add(fan) self._status_changed = True if fan in self._presence_fans: self._presence_fans.remove(fan) + if not status and fan not in self._fault_fans: + self._fault_fans.add(fan) + self._status_changed = True + elif status and fan in self._fault_fans: + self._fault_fans.remove(fan) + self._status_changed = True + + def get_absence_fans(self): """ Retrieves absence fans @@ -49,6 +60,13 @@ def get_presence_fans(self): """ return self._presence_fans + def get_fault_fans(self): + """ + Retrieves fault fans + :return: A set of fault fans + """ + return self._fault_fans + def is_status_changed(self): """ Retrieves if the status of fan information changed diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py index 133bb078ca20..914eec79816c 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py @@ -1,12 +1,29 @@ import os from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase +from sonic_platform_base.sonic_thermal_control.thermal_policy import ThermalPolicy from .thermal_actions import * from .thermal_conditions import * from .thermal_infos import * class ThermalManager(ThermalManagerBase): - THERMAL_ALGORITHM_CONTROL_PATH = '/var/run/hw-management/config/suspend' + @classmethod + def initialize(cls): + """ + Initialize thermal manager, including register thermal condition types and thermal action types + and any other vendor specific initialization. + :return: + """ + cls._add_private_thermal_policy() + + @classmethod + def deinitialize(cls): + """ + Destroy thermal manager, including any vendor specific cleanup. The default behavior of this function + is a no-op. + :return: + """ + cls.start_thermal_control_algorithm() @classmethod def start_thermal_control_algorithm(cls): @@ -16,7 +33,8 @@ def start_thermal_control_algorithm(cls): Returns: bool: True if set success, False if fail. """ - cls._control_thermal_control_algorithm(False) + from .thermal import Thermal + Thermal.set_thermal_algorithm_status(True) @classmethod def stop_thermal_control_algorithm(cls): @@ -26,25 +44,22 @@ def stop_thermal_control_algorithm(cls): Returns: bool: True if set success, False if fail. """ - cls._control_thermal_control_algorithm(True) + from .thermal import Thermal + Thermal.set_thermal_algorithm_status(False) @classmethod - def _control_thermal_control_algorithm(cls, suspend): - """ - Control thermal control algorithm - - Args: - suspend: Bool, indicate suspend the algorithm or not + def _add_private_thermal_policy(cls): + dynamic_min_speed_policy = ThermalPolicy() + dynamic_min_speed_policy.conditions[MinCoolingLevelChangeCondition] = MinCoolingLevelChangeCondition() + dynamic_min_speed_policy.actions[ChangeMinCoolingLevelAction] = ChangeMinCoolingLevelAction() + cls._policy_dict['DynamicMinCoolingLevelPolicy'] = dynamic_min_speed_policy - Returns: - bool: True if set success, False if fail. - """ - status = True - write_value = 1 if suspend else 0 - try: - with open(cls.THERMAL_ALGORITHM_CONTROL_PATH, 'w') as control_file: - control_file.write(str(write_value)) - except (ValueError, IOError): - status = False + update_psu_fan_speed_policy = ThermalPolicy() + update_psu_fan_speed_policy.conditions[CoolingLevelChangeCondition] = CoolingLevelChangeCondition() + update_psu_fan_speed_policy.actions[UpdatePsuFanSpeedAction] = UpdatePsuFanSpeedAction() + cls._policy_dict['UpdatePsuFanSpeedPolicy'] = update_psu_fan_speed_policy - return status + update_cooling_level_policy = ThermalPolicy() + update_cooling_level_policy.conditions[UpdateCoolingLevelToMinCondition] = UpdateCoolingLevelToMinCondition() + update_cooling_level_policy.actions[UpdateCoolingLevelToMinAction] = UpdateCoolingLevelToMinAction() + cls._policy_dict['UpdateCoolingLevelPolicy'] = update_cooling_level_policy diff --git a/platform/mellanox/mlnx-platform-api/tests/mock_platform.py b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py index f34ace97968d..c53480584889 100644 --- a/platform/mellanox/mlnx-platform-api/tests/mock_platform.py +++ b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py @@ -1,13 +1,20 @@ class MockFan: + speed = 60 def __init__(self): self.presence = True - self.speed = 60 + self.status = True def get_presence(self): return self.presence def set_speed(self, speed): - self.speed = speed + MockFan.speed = speed + + def get_status(self): + return self.status + + def get_target_speed(self): + return MockFan.speed class MockPsu: @@ -21,6 +28,9 @@ def get_presence(self): def get_powergood_status(self): return self.powergood + def get_all_fans(self): + return [] + class MockChassis: def __init__(self): diff --git a/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py index 843244e937fa..835d7a495bbb 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py @@ -11,6 +11,11 @@ from sonic_platform.thermal_manager import ThermalManager from sonic_platform.thermal_infos import FanInfo, PsuInfo +from sonic_platform.fan import Fan +from sonic_platform.thermal import Thermal + +Thermal.check_thermal_zone_temperature = MagicMock() +Thermal.set_thermal_algorithm_status = MagicMock() @pytest.fixture(scope='session', autouse=True) @@ -27,6 +32,7 @@ def test_load_policy(thermal_manager): assert 'any fan absence' in thermal_manager._policy_dict assert 'any psu absence' in thermal_manager._policy_dict + assert 'any fan broken' in thermal_manager._policy_dict assert 'all fan and psu presence' in thermal_manager._policy_dict assert thermal_manager._fan_speed_when_suspend == 60 @@ -40,6 +46,7 @@ def test_fan_info(): fan_info.collect(chassis) assert len(fan_info.get_absence_fans()) == 1 assert len(fan_info.get_presence_fans()) == 0 + assert len(fan_info.get_fault_fans()) == 0 assert fan_info.is_status_changed() fan_list = chassis.get_all_fans() @@ -47,8 +54,15 @@ def test_fan_info(): fan_info.collect(chassis) assert len(fan_info.get_absence_fans()) == 0 assert len(fan_info.get_presence_fans()) == 1 + assert len(fan_info.get_fault_fans()) == 0 assert fan_info.is_status_changed() + fan_list[0].status = False + fan_info.collect(chassis) + assert len(fan_info.get_absence_fans()) == 0 + assert len(fan_info.get_presence_fans()) == 1 + assert len(fan_info.get_fault_fans()) == 1 + assert fan_info.is_status_changed() def test_psu_info(): chassis = MockChassis() @@ -77,35 +91,47 @@ def test_fan_policy(thermal_manager): chassis = MockChassis() chassis.make_fan_absence() chassis.fan_list.append(MockFan()) - thermal_manager.start_thermal_control_algorithm = MagicMock() - thermal_manager.stop_thermal_control_algorithm = MagicMock() thermal_manager.run_policy(chassis) fan_list = chassis.get_all_fans() assert fan_list[1].speed == 100 - thermal_manager.stop_thermal_control_algorithm.assert_called_once() + Thermal.set_thermal_algorithm_status.assert_called_with(False, False) fan_list[0].presence = True + Thermal.check_thermal_zone_temperature = MagicMock(return_value=True) + thermal_manager.run_policy(chassis) + Thermal.set_thermal_algorithm_status.assert_called_with(True, False) + assert Thermal.check_thermal_zone_temperature.call_count == 2 + assert fan_list[0].speed == 60 + assert fan_list[1].speed == 60 + + fan_list[0].status = False + thermal_manager.run_policy(chassis) + Thermal.set_thermal_algorithm_status.assert_called_with(False, False) + + fan_list[0].status = True + Thermal.check_thermal_zone_temperature = MagicMock(return_value=False) thermal_manager.run_policy(chassis) - thermal_manager.start_thermal_control_algorithm.assert_called_once() + Thermal.set_thermal_algorithm_status.assert_called_with(True, False) + assert Thermal.check_thermal_zone_temperature.call_count == 2 + assert fan_list[0].speed == 100 + assert fan_list[1].speed == 100 def test_psu_policy(thermal_manager): chassis = MockChassis() chassis.make_psu_absence() chassis.fan_list.append(MockFan()) - thermal_manager.start_thermal_control_algorithm = MagicMock() - thermal_manager.stop_thermal_control_algorithm = MagicMock() thermal_manager.run_policy(chassis) fan_list = chassis.get_all_fans() assert fan_list[0].speed == 100 - thermal_manager.stop_thermal_control_algorithm.assert_called_once() + Thermal.set_thermal_algorithm_status.assert_called_with(False, False) psu_list = chassis.get_all_psus() psu_list[0].presence = True thermal_manager.run_policy(chassis) - thermal_manager.start_thermal_control_algorithm.assert_called_once() + Thermal.set_thermal_algorithm_status.assert_called_with(True, False) def test_any_fan_absence_condition(): @@ -159,6 +185,44 @@ def test_all_fan_presence_condition(): fan_info.collect(chassis) assert condition.is_match({'fan_info': fan_info}) +def test_any_fan_fault_condition(): + chassis = MockChassis() + fan = MockFan() + fan_list = chassis.get_all_fans() + fan_list.append(fan) + fault_fan = MockFan() + fault_fan.status = False + fan_list.append(fault_fan) + fan_info = FanInfo() + fan_info.collect(chassis) + + from sonic_platform.thermal_conditions import AnyFanFaultCondition + condition = AnyFanFaultCondition() + assert condition.is_match({'fan_info': fan_info}) + + fault_fan.status = True + fan_info.collect(chassis) + assert not condition.is_match({'fan_info': fan_info}) + +def test_all_fan_good_condition(): + chassis = MockChassis() + fan = MockFan() + fan_list = chassis.get_all_fans() + fan_list.append(fan) + fault_fan = MockFan() + fault_fan.status = False + fan_list.append(fault_fan) + fan_info = FanInfo() + fan_info.collect(chassis) + + from sonic_platform.thermal_conditions import AllFanGoodCondition + condition = AllFanGoodCondition() + assert not condition.is_match({'fan_info': fan_info}) + + fault_fan.status = True + fan_info.collect(chassis) + assert condition.is_match({'fan_info': fan_info}) + def test_any_psu_absence_condition(): chassis = MockChassis() @@ -275,6 +339,53 @@ def test_load_control_thermal_algo_action(): with pytest.raises(ValueError): action.load_from_json(json_obj) +def test_load_check_and_set_speed_action(): + from sonic_platform.thermal_actions import CheckAndSetAllFanSpeedAction + action = CheckAndSetAllFanSpeedAction() + json_str = '{\"speed\": \"40\"}' + json_obj = json.loads(json_str) + action.load_from_json(json_obj) + assert action.speed == 40 + + json_str = '{\"speed\": \"-1\"}' + json_obj = json.loads(json_str) + with pytest.raises(ValueError): + action.load_from_json(json_obj) + + json_str = '{\"speed\": \"101\"}' + json_obj = json.loads(json_str) + with pytest.raises(ValueError): + action.load_from_json(json_obj) + + json_str = '{\"invalid\": \"60\"}' + json_obj = json.loads(json_str) + with pytest.raises(ValueError): + action.load_from_json(json_obj) + +def test_execute_check_and_set_fan_speed_action(): + chassis = MockChassis() + fan_list = chassis.get_all_fans() + fan_list.append(MockFan()) + fan_list.append(MockFan()) + fan_info = FanInfo() + fan_info.collect(chassis) + Thermal.check_thermal_zone_temperature = MagicMock(return_value=True) + + from sonic_platform.thermal_actions import CheckAndSetAllFanSpeedAction + action = CheckAndSetAllFanSpeedAction() + action.speed = 99 + action.execute({'fan_info': fan_info}) + assert fan_list[0].speed == 99 + assert fan_list[1].speed == 99 + + Thermal.check_thermal_zone_temperature = MagicMock(return_value=False) + fan_list[0].speed = 100 + fan_list[1].speed = 100 + action.speed = 60 + action.execute({'fan_info': fan_info}) + assert fan_list[0].speed == 100 + assert fan_list[1].speed == 100 + def test_load_duplicate_condition(): from sonic_platform_base.sonic_thermal_control.thermal_policy import ThermalPolicy with open(os.path.join(test_path, 'duplicate_condition.json')) as f: @@ -315,4 +426,94 @@ class MockThermalManager(ThermalManagerBase): with pytest.raises(Exception): MockThermalManager.load(os.path.join(test_path, 'policy_with_same_conditions.json')) +def test_dynamic_minimum_table_data(): + from sonic_platform.device_data import DEVICE_DATA + for platform, platform_data in DEVICE_DATA.items(): + if 'thermal' in platform_data and 'minimum_table' in platform_data['thermal']: + minimum_table = platform_data['thermal']['minimum_table'] + check_minimum_table_data(platform, minimum_table) + +def check_minimum_table_data(platform, minimum_table): + valid_dir = ['p2c', 'c2p', 'unk'] + valid_trust_state = ['trust', 'untrust'] + + for category, data in minimum_table.items(): + key_data = category.split('_') + assert key_data[0] in valid_dir + assert key_data[1] in valid_trust_state + + data_list = [(value, key) for key, value in data.items()] + data_list.sort(key=lambda x : x[0]) + + previous_edge = None + previous_cooling_level = None + for item in data_list: + cooling_level = item[0] + range_str = item[1] + + ranges = range_str.split(':') + low = int(ranges[0]) + high = int(ranges[1]) + assert low < high + + if previous_edge is None: + assert low == -127 + else: + assert low - previous_edge == 1, '{}-{}-{} error, item={}'.format(platform, key_data[0], key_data[1], item) + previous_edge = high + + assert 10 <= cooling_level <= 20 + if previous_cooling_level is not None: + assert cooling_level > previous_cooling_level + previous_cooling_level = cooling_level + +def test_dynamic_minimum_policy(thermal_manager): + from sonic_platform.thermal_conditions import MinCoolingLevelChangeCondition + from sonic_platform.thermal_actions import ChangeMinCoolingLevelAction + from sonic_platform.thermal_infos import ChassisInfo + from sonic_platform.thermal import Thermal + from sonic_platform.fan import Fan + ThermalManager.initialize() + assert 'DynamicMinCoolingLevelPolicy' in thermal_manager._policy_dict + policy = thermal_manager._policy_dict['DynamicMinCoolingLevelPolicy'] + assert MinCoolingLevelChangeCondition in policy.conditions + assert ChangeMinCoolingLevelAction in policy.actions + + condition = policy.conditions[MinCoolingLevelChangeCondition] + action = policy.actions[ChangeMinCoolingLevelAction] + Thermal.check_module_temperature_trustable = MagicMock(return_value='trust') + Thermal.get_air_flow_direction = MagicMock(return_value=('p2c', 35000)) + assert condition.is_match(None) + assert MinCoolingLevelChangeCondition.trust_state == 'trust' + assert MinCoolingLevelChangeCondition.air_flow_dir == 'p2c' + assert MinCoolingLevelChangeCondition.temperature == 35 + assert not condition.is_match(None) + + Thermal.check_module_temperature_trustable = MagicMock(return_value='untrust') + assert condition.is_match(None) + assert MinCoolingLevelChangeCondition.trust_state == 'untrust' + + Thermal.get_air_flow_direction = MagicMock(return_value=('c2p', 35000)) + assert condition.is_match(None) + assert MinCoolingLevelChangeCondition.air_flow_dir == 'c2p' + + Thermal.get_air_flow_direction = MagicMock(return_value=('c2p', 25000)) + assert condition.is_match(None) + assert MinCoolingLevelChangeCondition.temperature == 25 + chassis = MockChassis() + chassis.platform_name = 'invalid' + info = ChassisInfo() + info._chassis = chassis + thermal_info_dict = {ChassisInfo.INFO_NAME: info} + Fan.get_cooling_level = MagicMock(return_value=5) + Fan.set_cooling_level = MagicMock() + action.execute(thermal_info_dict) + assert Fan.min_cooling_level == 6 + Fan.set_cooling_level.assert_called_with(6, 6) + Fan.set_cooling_level.call_count = 0 + + chassis.platform_name = 'x86_64-mlnx_msn2700-r0' + action.execute(thermal_info_dict) + assert Fan.min_cooling_level == 4 + Fan.set_cooling_level.assert_called_with(4, 5) diff --git a/platform/mellanox/mlnx-platform-api/tests/thermal_policy.json b/platform/mellanox/mlnx-platform-api/tests/thermal_policy.json index 5d31b2abd875..413211b21220 100644 --- a/platform/mellanox/mlnx-platform-api/tests/thermal_policy.json +++ b/platform/mellanox/mlnx-platform-api/tests/thermal_policy.json @@ -51,6 +51,24 @@ } ] }, + { + "name": "any fan broken", + "conditions": [ + { + "type": "fan.any.fault" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, { "name": "all fan and psu presence", "conditions": [ @@ -59,12 +77,19 @@ }, { "type": "psu.all.presence" + }, + { + "type": "fan.all.good" } ], "actions": [ { "type": "thermal_control.control", "status": "true" + }, + { + "type": "fan.all.check_and_set_speed", + "speed": "60" } ] } From bddd0d1e53b886925270d51b87f24aa0a28ff313 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 21 Apr 2020 09:57:57 -0700 Subject: [PATCH 0574/1427] [docker-sonic-mgmt]: set docker-sonic-mgmt as stretch docker (#4450) Signed-off-by: Guohan Lu --- rules/docker-sonic-mgmt.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/rules/docker-sonic-mgmt.mk b/rules/docker-sonic-mgmt.mk index b1aaad348734..8d6901755f8a 100644 --- a/rules/docker-sonic-mgmt.mk +++ b/rules/docker-sonic-mgmt.mk @@ -3,3 +3,4 @@ DOCKER_SONIC_MGMT = docker-sonic-mgmt.gz $(DOCKER_SONIC_MGMT)_PATH = $(DOCKERS_PATH)/docker-sonic-mgmt $(DOCKER_SONIC_MGMT)_DEPENDS += $(SONIC_DEVICE_DATA) $(PTF) SONIC_DOCKER_IMAGES += $(DOCKER_SONIC_MGMT) +SONIC_STRETCH_DOCKERS += $(DOCKER_SONIC_MGMT) From 3a82ade3ef59270aefc28ada260342f4d273b275 Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Tue, 21 Apr 2020 17:09:41 -0700 Subject: [PATCH 0575/1427] [docker]: Enabled ipv6 in dockers when using docker bridge network (#4426) Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- files/build_templates/docker_image_ctl.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 6067c58f41e9..c48d72ea1f47 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -74,6 +74,7 @@ function postStartAction() { {%- if docker_container_name == "database" %} if [ "$DEV" ]; then + docker exec -i database$DEV sysctl -w net.ipv6.conf.all.disable_ipv6=0 link_namespace $DEV fi # Wait until redis starts From 43e80f7c2a54591fcbdce22651a7932413ffa527 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 22 Apr 2020 11:02:38 -0700 Subject: [PATCH 0576/1427] [doc]: ask the motivation of the PR (#4462) it is important to understand the motivation of the PR. what I did is usually the PR title, so remove. Signed-off-by: Guohan Lu --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2ac7d9e47730..b86fef4c0aef 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,7 +10,7 @@ If this is a bug fix, make sure your description includes "fixes #xxxx", or Please provide the following information: --> -**- What I did** +**- Why I did it** **- How I did it** From 45c88d128749bb646b44f6a0c5ace42f5b3b548a Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 22 Apr 2020 11:03:16 -0700 Subject: [PATCH 0577/1427] [kvm]: disable pmon daemons on kvm vs platform (#4461) hardware daemons are not supported in kvm vs platform now admin@vlab-01:/usr/share/sonic/device/x86_64-kvm_x86_64-r0$ docker exec -it pmon bash root@vlab-01:/# supervisorctl status fancontrol STOPPED Not started lm-sensors STOPPED Not started rsyslogd RUNNING pid 23, uptime 0:03:09 start.sh EXITED Apr 22 09:07 AM supervisor-proc-exit-listener RUNNING pid 17, uptime 0:03:10 Signed-off-by: Guohan Lu --- .../virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json diff --git a/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json b/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..c6a21eb19fc5 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json @@ -0,0 +1,7 @@ +{ + "skip_ledd": true, + "skip_xcvrd": true, + "skip_psud": true, + "skip_syseepromd": true, + "skip_thermalctld": true +} From c5e98443ba84a9a0c667f83572c2074dbf01b4a7 Mon Sep 17 00:00:00 2001 From: chihhan123 <56335706+chihhan123@users.noreply.github.com> Date: Thu, 23 Apr 2020 02:47:04 +0800 Subject: [PATCH 0578/1427] [device/acction] Support AS9716-32D(R0BA) (#4449) - add led_proc_init.soc - update config.bcm --- .../Accton-AS9716-32D/sai.profile | 2 +- .../th3-as9716-32x400G.config.bcm | 1287 +++++++++++++++++ .../custom_led.bin | Bin 0 -> 2044 bytes .../led_proc_init.soc | 3 + 4 files changed, 1291 insertions(+), 1 deletion(-) create mode 100644 device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/th3-as9716-32x400G.config.bcm create mode 100644 device/accton/x86_64-accton_as9716_32d-r0/custom_led.bin create mode 100644 device/accton/x86_64-accton_as9716_32d-r0/led_proc_init.soc diff --git a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile index be39b1f961f2..b366aeaa93c9 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile +++ b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/th3-as9716-32x400G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-as9716-32x400G.config.bcm \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/th3-as9716-32x400G.config.bcm b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/th3-as9716-32x400G.config.bcm new file mode 100644 index 000000000000..5850f4ce4d72 --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/th3-as9716-32x400G.config.bcm @@ -0,0 +1,1287 @@ +pbmp_xport_xe.0=0x3ffffffffffffffffffffffffffffffffffffffe + +# Reference specfic +parity_correction=1 +parity_enable=1 +phy_null=1 +#pll_bypass=1 +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 +l2xmsg_mode.0=1 +l2_mem_entries.0=8192 +l3_alpm_enable.0=2 +l3_mem_entries.0=16384 +mmu_port_num_mc_queue.0=1 +module_64ports.0=1 +multicast_l2_range.0=511 +oversubscribe_mode=1 + +# Platform specfic +arl_clean_timeout_usec=15000000 +asf_mem_profile.0=2 +bcm_num_cos.0=8 +bcm_stat_flags=1 +bcm_stat_jumbo.0=9236 +cdma_timeout_usec.0=15000000 +dma_desc_timeout_usec.0=15000000 +dpr_clock_frequency.0=1000 +max_vp_lags.0=0 +miim_intr_enable.0=0 +sram_scan_enable.0=0 +tdma_timeout_usec.0=15000000 +tslam_timeout_usec.0=15000000 + +#BC0# +dport_map_port_1=81 +dport_map_port_2=82 +dport_map_port_3=83 +dport_map_port_4=84 +portmap_1=1:400 +phy_chain_rx_lane_map_physical{1.0}=0x45301726 +phy_chain_rx_lane_map_physical{2.0}=0x45301726 +phy_chain_rx_lane_map_physical{3.0}=0x45301726 +phy_chain_rx_lane_map_physical{4.0}=0x45301726 +phy_chain_rx_lane_map_physical{5.0}=0x45301726 +phy_chain_rx_lane_map_physical{6.0}=0x45301726 +phy_chain_rx_lane_map_physical{7.0}=0x45301726 +phy_chain_rx_lane_map_physical{8.0}=0x45301726 +phy_chain_tx_lane_map_physical{1.0}=0x23761450 +phy_chain_tx_lane_map_physical{2.0}=0x23761450 +phy_chain_tx_lane_map_physical{3.0}=0x23761450 +phy_chain_tx_lane_map_physical{4.0}=0x23761450 +phy_chain_tx_lane_map_physical{5.0}=0x23761450 +phy_chain_tx_lane_map_physical{6.0}=0x23761450 +phy_chain_tx_lane_map_physical{7.0}=0x23761450 +phy_chain_tx_lane_map_physical{8.0}=0x23761450 +serdes_core_rx_polarity_flip_physical{1}=0xA9 +serdes_core_rx_polarity_flip_physical{2}=0xA9 +serdes_core_rx_polarity_flip_physical{3}=0xA9 +serdes_core_rx_polarity_flip_physical{4}=0xA9 +serdes_core_rx_polarity_flip_physical{5}=0xA9 +serdes_core_rx_polarity_flip_physical{6}=0xA9 +serdes_core_rx_polarity_flip_physical{7}=0xA9 +serdes_core_rx_polarity_flip_physical{8}=0xA9 +serdes_core_tx_polarity_flip_physical{1}=0x7E +serdes_core_tx_polarity_flip_physical{2}=0x7E +serdes_core_tx_polarity_flip_physical{3}=0x7E +serdes_core_tx_polarity_flip_physical{4}=0x7E +serdes_core_tx_polarity_flip_physical{5}=0x7E +serdes_core_tx_polarity_flip_physical{6}=0x7E +serdes_core_tx_polarity_flip_physical{7}=0x7E +serdes_core_tx_polarity_flip_physical{8}=0x7E + +#BC1# +dport_map_port_5=85 +dport_map_port_6=86 +dport_map_port_7=87 +dport_map_port_8=88 +portmap_5=9:400 +phy_chain_rx_lane_map_physical{9.0}=0x12650374 +phy_chain_rx_lane_map_physical{10.0}=0x12650374 +phy_chain_rx_lane_map_physical{11.0}=0x12650374 +phy_chain_rx_lane_map_physical{12.0}=0x12650374 +phy_chain_rx_lane_map_physical{13.0}=0x12650374 +phy_chain_rx_lane_map_physical{14.0}=0x12650374 +phy_chain_rx_lane_map_physical{15.0}=0x12650374 +phy_chain_rx_lane_map_physical{16.0}=0x12650374 +phy_chain_tx_lane_map_physical{9.0}=0x70146253 +phy_chain_tx_lane_map_physical{10.0}=0x70146253 +phy_chain_tx_lane_map_physical{11.0}=0x70146253 +phy_chain_tx_lane_map_physical{12.0}=0x70146253 +phy_chain_tx_lane_map_physical{13.0}=0x70146253 +phy_chain_tx_lane_map_physical{14.0}=0x70146253 +phy_chain_tx_lane_map_physical{15.0}=0x70146253 +phy_chain_tx_lane_map_physical{16.0}=0x70146253 +serdes_core_rx_polarity_flip_physical{9}=0x5A +serdes_core_rx_polarity_flip_physical{10}=0x5A +serdes_core_rx_polarity_flip_physical{11}=0x5A +serdes_core_rx_polarity_flip_physical{12}=0x5A +serdes_core_rx_polarity_flip_physical{13}=0x5A +serdes_core_rx_polarity_flip_physical{14}=0x5A +serdes_core_rx_polarity_flip_physical{15}=0x5A +serdes_core_rx_polarity_flip_physical{16}=0x5A +serdes_core_tx_polarity_flip_physical{9}=0x76 +serdes_core_tx_polarity_flip_physical{10}=0x76 +serdes_core_tx_polarity_flip_physical{11}=0x76 +serdes_core_tx_polarity_flip_physical{12}=0x76 +serdes_core_tx_polarity_flip_physical{13}=0x76 +serdes_core_tx_polarity_flip_physical{14}=0x76 +serdes_core_tx_polarity_flip_physical{15}=0x76 +serdes_core_tx_polarity_flip_physical{16}=0x76 + +#BC2# +dport_map_port_9=89 +dport_map_port_10=90 +dport_map_port_11=91 +dport_map_port_12=92 +portmap_9=17:400 +phy_chain_rx_lane_map_physical{17.0}=0x40572136 +phy_chain_rx_lane_map_physical{18.0}=0x40572136 +phy_chain_rx_lane_map_physical{19.0}=0x40572136 +phy_chain_rx_lane_map_physical{20.0}=0x40572136 +phy_chain_rx_lane_map_physical{21.0}=0x40572136 +phy_chain_rx_lane_map_physical{22.0}=0x40572136 +phy_chain_rx_lane_map_physical{23.0}=0x40572136 +phy_chain_rx_lane_map_physical{24.0}=0x40572136 +phy_chain_tx_lane_map_physical{17.0}=0x75324160 +phy_chain_tx_lane_map_physical{18.0}=0x75324160 +phy_chain_tx_lane_map_physical{19.0}=0x75324160 +phy_chain_tx_lane_map_physical{20.0}=0x75324160 +phy_chain_tx_lane_map_physical{21.0}=0x75324160 +phy_chain_tx_lane_map_physical{22.0}=0x75324160 +phy_chain_tx_lane_map_physical{23.0}=0x75324160 +phy_chain_tx_lane_map_physical{24.0}=0x75324160 +serdes_core_rx_polarity_flip_physical{17}=0x78 +serdes_core_rx_polarity_flip_physical{18}=0x78 +serdes_core_rx_polarity_flip_physical{19}=0x78 +serdes_core_rx_polarity_flip_physical{20}=0x78 +serdes_core_rx_polarity_flip_physical{21}=0x78 +serdes_core_rx_polarity_flip_physical{22}=0x78 +serdes_core_rx_polarity_flip_physical{23}=0x78 +serdes_core_rx_polarity_flip_physical{24}=0x78 +serdes_core_tx_polarity_flip_physical{17}=0x3B +serdes_core_tx_polarity_flip_physical{18}=0x3B +serdes_core_tx_polarity_flip_physical{19}=0x3B +serdes_core_tx_polarity_flip_physical{20}=0x3B +serdes_core_tx_polarity_flip_physical{21}=0x3B +serdes_core_tx_polarity_flip_physical{22}=0x3B +serdes_core_tx_polarity_flip_physical{23}=0x3B +serdes_core_tx_polarity_flip_physical{24}=0x3B + +#BC3# +dport_map_port_13=93 +dport_map_port_14=94 +dport_map_port_15=95 +dport_map_port_16=96 +portmap_13=25:400 +phy_chain_rx_lane_map_physical{25.0}=0x20576143 +phy_chain_rx_lane_map_physical{26.0}=0x20576143 +phy_chain_rx_lane_map_physical{27.0}=0x20576143 +phy_chain_rx_lane_map_physical{28.0}=0x20576143 +phy_chain_rx_lane_map_physical{29.0}=0x20576143 +phy_chain_rx_lane_map_physical{30.0}=0x20576143 +phy_chain_rx_lane_map_physical{31.0}=0x20576143 +phy_chain_rx_lane_map_physical{32.0}=0x20576143 +phy_chain_tx_lane_map_physical{25.0}=0x43716520 +phy_chain_tx_lane_map_physical{26.0}=0x43716520 +phy_chain_tx_lane_map_physical{27.0}=0x43716520 +phy_chain_tx_lane_map_physical{28.0}=0x43716520 +phy_chain_tx_lane_map_physical{29.0}=0x43716520 +phy_chain_tx_lane_map_physical{30.0}=0x43716520 +phy_chain_tx_lane_map_physical{31.0}=0x43716520 +phy_chain_tx_lane_map_physical{32.0}=0x43716520 +serdes_core_rx_polarity_flip_physical{25}=0xF8 +serdes_core_rx_polarity_flip_physical{26}=0xF8 +serdes_core_rx_polarity_flip_physical{27}=0xF8 +serdes_core_rx_polarity_flip_physical{28}=0xF8 +serdes_core_rx_polarity_flip_physical{29}=0xF8 +serdes_core_rx_polarity_flip_physical{30}=0xF8 +serdes_core_rx_polarity_flip_physical{31}=0xF8 +serdes_core_rx_polarity_flip_physical{32}=0xF8 +serdes_core_tx_polarity_flip_physical{25}=0x6E +serdes_core_tx_polarity_flip_physical{26}=0x6E +serdes_core_tx_polarity_flip_physical{27}=0x6E +serdes_core_tx_polarity_flip_physical{28}=0x6E +serdes_core_tx_polarity_flip_physical{29}=0x6E +serdes_core_tx_polarity_flip_physical{30}=0x6E +serdes_core_tx_polarity_flip_physical{31}=0x6E +serdes_core_tx_polarity_flip_physical{32}=0x6E + +#BC4# +dport_map_port_24=37 +dport_map_port_25=38 +dport_map_port_26=39 +dport_map_port_27=40 +portmap_24=33:400 +phy_chain_rx_lane_map_physical{33.0}=0x47205361 +phy_chain_rx_lane_map_physical{34.0}=0x47205361 +phy_chain_rx_lane_map_physical{35.0}=0x47205361 +phy_chain_rx_lane_map_physical{36.0}=0x47205361 +phy_chain_rx_lane_map_physical{37.0}=0x47205361 +phy_chain_rx_lane_map_physical{38.0}=0x47205361 +phy_chain_rx_lane_map_physical{39.0}=0x47205361 +phy_chain_rx_lane_map_physical{40.0}=0x47205361 +phy_chain_tx_lane_map_physical{33.0}=0x01452736 +phy_chain_tx_lane_map_physical{34.0}=0x01452736 +phy_chain_tx_lane_map_physical{35.0}=0x01452736 +phy_chain_tx_lane_map_physical{36.0}=0x01452736 +phy_chain_tx_lane_map_physical{37.0}=0x01452736 +phy_chain_tx_lane_map_physical{38.0}=0x01452736 +phy_chain_tx_lane_map_physical{39.0}=0x01452736 +phy_chain_tx_lane_map_physical{40.0}=0x01452736 +serdes_core_rx_polarity_flip_physical{33}=0x87 +serdes_core_rx_polarity_flip_physical{34}=0x87 +serdes_core_rx_polarity_flip_physical{35}=0x87 +serdes_core_rx_polarity_flip_physical{36}=0x87 +serdes_core_rx_polarity_flip_physical{37}=0x87 +serdes_core_rx_polarity_flip_physical{38}=0x87 +serdes_core_rx_polarity_flip_physical{39}=0x87 +serdes_core_rx_polarity_flip_physical{40}=0x87 +serdes_core_tx_polarity_flip_physical{33}=0x27 +serdes_core_tx_polarity_flip_physical{34}=0x27 +serdes_core_tx_polarity_flip_physical{35}=0x27 +serdes_core_tx_polarity_flip_physical{36}=0x27 +serdes_core_tx_polarity_flip_physical{37}=0x27 +serdes_core_tx_polarity_flip_physical{38}=0x27 +serdes_core_tx_polarity_flip_physical{39}=0x27 +serdes_core_tx_polarity_flip_physical{40}=0x27 + +#BC5# +dport_map_port_20=33 +dport_map_port_21=34 +dport_map_port_22=35 +dport_map_port_23=36 +portmap_20=41:400 +phy_chain_rx_lane_map_physical{41.0}=0x45013726 +phy_chain_rx_lane_map_physical{42.0}=0x45013726 +phy_chain_rx_lane_map_physical{43.0}=0x45013726 +phy_chain_rx_lane_map_physical{44.0}=0x45013726 +phy_chain_rx_lane_map_physical{45.0}=0x45013726 +phy_chain_rx_lane_map_physical{46.0}=0x45013726 +phy_chain_rx_lane_map_physical{47.0}=0x45013726 +phy_chain_rx_lane_map_physical{48.0}=0x45013726 +phy_chain_tx_lane_map_physical{41.0}=0x10273564 +phy_chain_tx_lane_map_physical{42.0}=0x10273564 +phy_chain_tx_lane_map_physical{43.0}=0x10273564 +phy_chain_tx_lane_map_physical{44.0}=0x10273564 +phy_chain_tx_lane_map_physical{45.0}=0x10273564 +phy_chain_tx_lane_map_physical{46.0}=0x10273564 +phy_chain_tx_lane_map_physical{47.0}=0x10273564 +phy_chain_tx_lane_map_physical{48.0}=0x10273564 +serdes_core_rx_polarity_flip_physical{41}=0x99 +serdes_core_rx_polarity_flip_physical{42}=0x99 +serdes_core_rx_polarity_flip_physical{43}=0x99 +serdes_core_rx_polarity_flip_physical{44}=0x99 +serdes_core_rx_polarity_flip_physical{45}=0x99 +serdes_core_rx_polarity_flip_physical{46}=0x99 +serdes_core_rx_polarity_flip_physical{47}=0x99 +serdes_core_rx_polarity_flip_physical{48}=0x99 +serdes_core_tx_polarity_flip_physical{41}=0xA8 +serdes_core_tx_polarity_flip_physical{42}=0xA8 +serdes_core_tx_polarity_flip_physical{43}=0xA8 +serdes_core_tx_polarity_flip_physical{44}=0xA8 +serdes_core_tx_polarity_flip_physical{45}=0xA8 +serdes_core_tx_polarity_flip_physical{46}=0xA8 +serdes_core_tx_polarity_flip_physical{47}=0xA8 +serdes_core_tx_polarity_flip_physical{48}=0xA8 + +#BC6# +dport_map_port_28=41 +dport_map_port_29=42 +dport_map_port_30=43 +dport_map_port_31=44 +portmap_28=49:400 +phy_chain_rx_lane_map_physical{49.0}=0x04571326 +phy_chain_rx_lane_map_physical{50.0}=0x04571326 +phy_chain_rx_lane_map_physical{51.0}=0x04571326 +phy_chain_rx_lane_map_physical{52.0}=0x04571326 +phy_chain_rx_lane_map_physical{53.0}=0x04571326 +phy_chain_rx_lane_map_physical{54.0}=0x04571326 +phy_chain_rx_lane_map_physical{55.0}=0x04571326 +phy_chain_rx_lane_map_physical{56.0}=0x04571326 +phy_chain_tx_lane_map_physical{49.0}=0x51230764 +phy_chain_tx_lane_map_physical{50.0}=0x51230764 +phy_chain_tx_lane_map_physical{51.0}=0x51230764 +phy_chain_tx_lane_map_physical{52.0}=0x51230764 +phy_chain_tx_lane_map_physical{53.0}=0x51230764 +phy_chain_tx_lane_map_physical{54.0}=0x51230764 +phy_chain_tx_lane_map_physical{55.0}=0x51230764 +phy_chain_tx_lane_map_physical{56.0}=0x51230764 +serdes_core_rx_polarity_flip_physical{49}=0xB2 +serdes_core_rx_polarity_flip_physical{50}=0xB2 +serdes_core_rx_polarity_flip_physical{51}=0xB2 +serdes_core_rx_polarity_flip_physical{52}=0xB2 +serdes_core_rx_polarity_flip_physical{53}=0xB2 +serdes_core_rx_polarity_flip_physical{54}=0xB2 +serdes_core_rx_polarity_flip_physical{55}=0xB2 +serdes_core_rx_polarity_flip_physical{56}=0xB2 +serdes_core_tx_polarity_flip_physical{49}=0x88 +serdes_core_tx_polarity_flip_physical{50}=0x88 +serdes_core_tx_polarity_flip_physical{51}=0x88 +serdes_core_tx_polarity_flip_physical{52}=0x88 +serdes_core_tx_polarity_flip_physical{53}=0x88 +serdes_core_tx_polarity_flip_physical{54}=0x88 +serdes_core_tx_polarity_flip_physical{55}=0x88 +serdes_core_tx_polarity_flip_physical{56}=0x88 + +#BC7# +dport_map_port_32=45 +dport_map_port_33=46 +dport_map_port_34=47 +dport_map_port_35=48 +portmap_32=57:400 +phy_chain_rx_lane_map_physical{57.0}=0x01675243 +phy_chain_rx_lane_map_physical{58.0}=0x01675243 +phy_chain_rx_lane_map_physical{59.0}=0x01675243 +phy_chain_rx_lane_map_physical{60.0}=0x01675243 +phy_chain_rx_lane_map_physical{61.0}=0x01675243 +phy_chain_rx_lane_map_physical{62.0}=0x01675243 +phy_chain_rx_lane_map_physical{63.0}=0x01675243 +phy_chain_rx_lane_map_physical{64.0}=0x01675243 +phy_chain_tx_lane_map_physical{57.0}=0x37106425 +phy_chain_tx_lane_map_physical{58.0}=0x37106425 +phy_chain_tx_lane_map_physical{59.0}=0x37106425 +phy_chain_tx_lane_map_physical{60.0}=0x37106425 +phy_chain_tx_lane_map_physical{61.0}=0x37106425 +phy_chain_tx_lane_map_physical{62.0}=0x37106425 +phy_chain_tx_lane_map_physical{63.0}=0x37106425 +phy_chain_tx_lane_map_physical{64.0}=0x37106425 +serdes_core_rx_polarity_flip_physical{57}=0x9C +serdes_core_rx_polarity_flip_physical{58}=0x9C +serdes_core_rx_polarity_flip_physical{59}=0x9C +serdes_core_rx_polarity_flip_physical{60}=0x9C +serdes_core_rx_polarity_flip_physical{61}=0x9C +serdes_core_rx_polarity_flip_physical{62}=0x9C +serdes_core_rx_polarity_flip_physical{63}=0x9C +serdes_core_rx_polarity_flip_physical{64}=0x9C +serdes_core_tx_polarity_flip_physical{57}=0x4F +serdes_core_tx_polarity_flip_physical{58}=0x4F +serdes_core_tx_polarity_flip_physical{59}=0x4F +serdes_core_tx_polarity_flip_physical{60}=0x4F +serdes_core_tx_polarity_flip_physical{61}=0x4F +serdes_core_tx_polarity_flip_physical{62}=0x4F +serdes_core_tx_polarity_flip_physical{63}=0x4F +serdes_core_tx_polarity_flip_physical{64}=0x4F + +#BC8# +dport_map_port_44=5 +dport_map_port_45=6 +dport_map_port_46=7 +dport_map_port_47=8 +portmap_44=65:400 +phy_chain_rx_lane_map_physical{65.0}=0x56024713 +phy_chain_rx_lane_map_physical{66.0}=0x56024713 +phy_chain_rx_lane_map_physical{67.0}=0x56024713 +phy_chain_rx_lane_map_physical{68.0}=0x56024713 +phy_chain_rx_lane_map_physical{69.0}=0x56024713 +phy_chain_rx_lane_map_physical{70.0}=0x56024713 +phy_chain_rx_lane_map_physical{71.0}=0x56024713 +phy_chain_rx_lane_map_physical{72.0}=0x56024713 +phy_chain_tx_lane_map_physical{65.0}=0x12673504 +phy_chain_tx_lane_map_physical{66.0}=0x12673504 +phy_chain_tx_lane_map_physical{67.0}=0x12673504 +phy_chain_tx_lane_map_physical{68.0}=0x12673504 +phy_chain_tx_lane_map_physical{69.0}=0x12673504 +phy_chain_tx_lane_map_physical{70.0}=0x12673504 +phy_chain_tx_lane_map_physical{71.0}=0x12673504 +phy_chain_tx_lane_map_physical{72.0}=0x12673504 +serdes_core_rx_polarity_flip_physical{65}=0x4B +serdes_core_rx_polarity_flip_physical{66}=0x4B +serdes_core_rx_polarity_flip_physical{67}=0x4B +serdes_core_rx_polarity_flip_physical{68}=0x4B +serdes_core_rx_polarity_flip_physical{69}=0x4B +serdes_core_rx_polarity_flip_physical{70}=0x4B +serdes_core_rx_polarity_flip_physical{71}=0x4B +serdes_core_rx_polarity_flip_physical{72}=0x4B +serdes_core_tx_polarity_flip_physical{65}=0xB7 +serdes_core_tx_polarity_flip_physical{66}=0xB7 +serdes_core_tx_polarity_flip_physical{67}=0xB7 +serdes_core_tx_polarity_flip_physical{68}=0xB7 +serdes_core_tx_polarity_flip_physical{69}=0xB7 +serdes_core_tx_polarity_flip_physical{70}=0xB7 +serdes_core_tx_polarity_flip_physical{71}=0xB7 +serdes_core_tx_polarity_flip_physical{72}=0xB7 + +#BC9# +dport_map_port_40=1 +dport_map_port_41=2 +dport_map_port_42=3 +dport_map_port_43=4 +portmap_40=73:400 +phy_chain_rx_lane_map_physical{73.0}=0x45231607 +phy_chain_rx_lane_map_physical{74.0}=0x45231607 +phy_chain_rx_lane_map_physical{75.0}=0x45231607 +phy_chain_rx_lane_map_physical{76.0}=0x45231607 +phy_chain_rx_lane_map_physical{77.0}=0x45231607 +phy_chain_rx_lane_map_physical{78.0}=0x45231607 +phy_chain_rx_lane_map_physical{79.0}=0x45231607 +phy_chain_rx_lane_map_physical{80.0}=0x45231607 +phy_chain_tx_lane_map_physical{73.0}=0x04273165 +phy_chain_tx_lane_map_physical{74.0}=0x04273165 +phy_chain_tx_lane_map_physical{75.0}=0x04273165 +phy_chain_tx_lane_map_physical{76.0}=0x04273165 +phy_chain_tx_lane_map_physical{77.0}=0x04273165 +phy_chain_tx_lane_map_physical{78.0}=0x04273165 +phy_chain_tx_lane_map_physical{79.0}=0x04273165 +phy_chain_tx_lane_map_physical{80.0}=0x04273165 +serdes_core_rx_polarity_flip_physical{73}=0x9C +serdes_core_rx_polarity_flip_physical{74}=0x9C +serdes_core_rx_polarity_flip_physical{75}=0x9C +serdes_core_rx_polarity_flip_physical{76}=0x9C +serdes_core_rx_polarity_flip_physical{77}=0x9C +serdes_core_rx_polarity_flip_physical{78}=0x9C +serdes_core_rx_polarity_flip_physical{79}=0x9C +serdes_core_rx_polarity_flip_physical{80}=0x9C +serdes_core_tx_polarity_flip_physical{73}=0xAC +serdes_core_tx_polarity_flip_physical{74}=0xAC +serdes_core_tx_polarity_flip_physical{75}=0xAC +serdes_core_tx_polarity_flip_physical{76}=0xAC +serdes_core_tx_polarity_flip_physical{77}=0xAC +serdes_core_tx_polarity_flip_physical{78}=0xAC +serdes_core_tx_polarity_flip_physical{79}=0xAC +serdes_core_tx_polarity_flip_physical{80}=0xAC + +#BC10# +dport_map_port_48=9 +dport_map_port_49=10 +dport_map_port_50=11 +dport_map_port_51=12 +portmap_48=81:400 +phy_chain_rx_lane_map_physical{81.0}=0x20563147 +phy_chain_rx_lane_map_physical{82.0}=0x20563147 +phy_chain_rx_lane_map_physical{83.0}=0x20563147 +phy_chain_rx_lane_map_physical{84.0}=0x20563147 +phy_chain_rx_lane_map_physical{85.0}=0x20563147 +phy_chain_rx_lane_map_physical{86.0}=0x20563147 +phy_chain_rx_lane_map_physical{87.0}=0x20563147 +phy_chain_rx_lane_map_physical{88.0}=0x20563147 +phy_chain_tx_lane_map_physical{81.0}=0x53216704 +phy_chain_tx_lane_map_physical{82.0}=0x53216704 +phy_chain_tx_lane_map_physical{83.0}=0x53216704 +phy_chain_tx_lane_map_physical{84.0}=0x53216704 +phy_chain_tx_lane_map_physical{85.0}=0x53216704 +phy_chain_tx_lane_map_physical{86.0}=0x53216704 +phy_chain_tx_lane_map_physical{87.0}=0x53216704 +phy_chain_tx_lane_map_physical{88.0}=0x53216704 +serdes_core_rx_polarity_flip_physical{81}=0xE1 +serdes_core_rx_polarity_flip_physical{82}=0xE1 +serdes_core_rx_polarity_flip_physical{83}=0xE1 +serdes_core_rx_polarity_flip_physical{84}=0xE1 +serdes_core_rx_polarity_flip_physical{85}=0xE1 +serdes_core_rx_polarity_flip_physical{86}=0xE1 +serdes_core_rx_polarity_flip_physical{87}=0xE1 +serdes_core_rx_polarity_flip_physical{88}=0xE1 +serdes_core_tx_polarity_flip_physical{81}=0xA2 +serdes_core_tx_polarity_flip_physical{82}=0xA2 +serdes_core_tx_polarity_flip_physical{83}=0xA2 +serdes_core_tx_polarity_flip_physical{84}=0xA2 +serdes_core_tx_polarity_flip_physical{85}=0xA2 +serdes_core_tx_polarity_flip_physical{86}=0xA2 +serdes_core_tx_polarity_flip_physical{87}=0xA2 +serdes_core_tx_polarity_flip_physical{88}=0xA2 + +#BC11# +dport_map_port_52=13 +dport_map_port_53=14 +dport_map_port_54=15 +dport_map_port_55=16 +portmap_52=89:400 +phy_chain_rx_lane_map_physical{89.0}=0x02514376 +phy_chain_rx_lane_map_physical{90.0}=0x02514376 +phy_chain_rx_lane_map_physical{91.0}=0x02514376 +phy_chain_rx_lane_map_physical{92.0}=0x02514376 +phy_chain_rx_lane_map_physical{93.0}=0x02514376 +phy_chain_rx_lane_map_physical{94.0}=0x02514376 +phy_chain_rx_lane_map_physical{95.0}=0x02514376 +phy_chain_rx_lane_map_physical{96.0}=0x02514376 +phy_chain_tx_lane_map_physical{89.0}=0x64012735 +phy_chain_tx_lane_map_physical{90.0}=0x64012735 +phy_chain_tx_lane_map_physical{91.0}=0x64012735 +phy_chain_tx_lane_map_physical{92.0}=0x64012735 +phy_chain_tx_lane_map_physical{93.0}=0x64012735 +phy_chain_tx_lane_map_physical{94.0}=0x64012735 +phy_chain_tx_lane_map_physical{95.0}=0x64012735 +phy_chain_tx_lane_map_physical{96.0}=0x64012735 +serdes_core_rx_polarity_flip_physical{89}=0xE2 +serdes_core_rx_polarity_flip_physical{90}=0xE2 +serdes_core_rx_polarity_flip_physical{91}=0xE2 +serdes_core_rx_polarity_flip_physical{92}=0xE2 +serdes_core_rx_polarity_flip_physical{93}=0xE2 +serdes_core_rx_polarity_flip_physical{94}=0xE2 +serdes_core_rx_polarity_flip_physical{95}=0xE2 +serdes_core_rx_polarity_flip_physical{96}=0xE2 +serdes_core_tx_polarity_flip_physical{89}=0xCF +serdes_core_tx_polarity_flip_physical{90}=0xCF +serdes_core_tx_polarity_flip_physical{91}=0xCF +serdes_core_tx_polarity_flip_physical{92}=0xCF +serdes_core_tx_polarity_flip_physical{93}=0xCF +serdes_core_tx_polarity_flip_physical{94}=0xCF +serdes_core_tx_polarity_flip_physical{95}=0xCF +serdes_core_tx_polarity_flip_physical{96}=0xCF + +#BC12# +dport_map_port_60=17 +dport_map_port_61=18 +dport_map_port_62=19 +dport_map_port_63=20 +portmap_60=97:400 +phy_chain_rx_lane_map_physical{97.0}=0x51276034 +phy_chain_rx_lane_map_physical{98.0}=0x51276034 +phy_chain_rx_lane_map_physical{99.0}=0x51276034 +phy_chain_rx_lane_map_physical{100.0}=0x51276034 +phy_chain_rx_lane_map_physical{101.0}=0x51276034 +phy_chain_rx_lane_map_physical{102.0}=0x51276034 +phy_chain_rx_lane_map_physical{103.0}=0x51276034 +phy_chain_rx_lane_map_physical{104.0}=0x51276034 +phy_chain_tx_lane_map_physical{97.0}=0x05476321 +phy_chain_tx_lane_map_physical{98.0}=0x05476321 +phy_chain_tx_lane_map_physical{99.0}=0x05476321 +phy_chain_tx_lane_map_physical{100.0}=0x05476321 +phy_chain_tx_lane_map_physical{101.0}=0x05476321 +phy_chain_tx_lane_map_physical{102.0}=0x05476321 +phy_chain_tx_lane_map_physical{103.0}=0x05476321 +phy_chain_tx_lane_map_physical{104.0}=0x05476321 +serdes_core_rx_polarity_flip_physical{97}=0x8E +serdes_core_rx_polarity_flip_physical{98}=0x8E +serdes_core_rx_polarity_flip_physical{99}=0x8E +serdes_core_rx_polarity_flip_physical{100}=0x8E +serdes_core_rx_polarity_flip_physical{101}=0x8E +serdes_core_rx_polarity_flip_physical{102}=0x8E +serdes_core_rx_polarity_flip_physical{103}=0x8E +serdes_core_rx_polarity_flip_physical{104}=0x8E +serdes_core_tx_polarity_flip_physical{97}=0xC8 +serdes_core_tx_polarity_flip_physical{98}=0xC8 +serdes_core_tx_polarity_flip_physical{99}=0xC8 +serdes_core_tx_polarity_flip_physical{100}=0xC8 +serdes_core_tx_polarity_flip_physical{101}=0xC8 +serdes_core_tx_polarity_flip_physical{102}=0xC8 +serdes_core_tx_polarity_flip_physical{103}=0xC8 +serdes_core_tx_polarity_flip_physical{104}=0xC8 + +#BC13# +dport_map_port_64=21 +dport_map_port_65=22 +dport_map_port_66=23 +dport_map_port_67=24 +portmap_64=105:400 +phy_chain_rx_lane_map_physical{105.0}=0x74126503 +phy_chain_rx_lane_map_physical{106.0}=0x74126503 +phy_chain_rx_lane_map_physical{107.0}=0x74126503 +phy_chain_rx_lane_map_physical{108.0}=0x74126503 +phy_chain_rx_lane_map_physical{109.0}=0x74126503 +phy_chain_rx_lane_map_physical{110.0}=0x74126503 +phy_chain_rx_lane_map_physical{111.0}=0x74126503 +phy_chain_rx_lane_map_physical{112.0}=0x74126503 +phy_chain_tx_lane_map_physical{105.0}=0x75236140 +phy_chain_tx_lane_map_physical{106.0}=0x75236140 +phy_chain_tx_lane_map_physical{107.0}=0x75236140 +phy_chain_tx_lane_map_physical{108.0}=0x75236140 +phy_chain_tx_lane_map_physical{109.0}=0x75236140 +phy_chain_tx_lane_map_physical{110.0}=0x75236140 +phy_chain_tx_lane_map_physical{111.0}=0x75236140 +phy_chain_tx_lane_map_physical{112.0}=0x75236140 +serdes_core_rx_polarity_flip_physical{105}=0x96 +serdes_core_rx_polarity_flip_physical{106}=0x96 +serdes_core_rx_polarity_flip_physical{107}=0x96 +serdes_core_rx_polarity_flip_physical{108}=0x96 +serdes_core_rx_polarity_flip_physical{109}=0x96 +serdes_core_rx_polarity_flip_physical{110}=0x96 +serdes_core_rx_polarity_flip_physical{111}=0x96 +serdes_core_rx_polarity_flip_physical{112}=0x96 +serdes_core_tx_polarity_flip_physical{105}=0xE1 +serdes_core_tx_polarity_flip_physical{106}=0xE1 +serdes_core_tx_polarity_flip_physical{107}=0xE1 +serdes_core_tx_polarity_flip_physical{108}=0xE1 +serdes_core_tx_polarity_flip_physical{109}=0xE1 +serdes_core_tx_polarity_flip_physical{110}=0xE1 +serdes_core_tx_polarity_flip_physical{111}=0xE1 +serdes_core_tx_polarity_flip_physical{112}=0xE1 + +#BC14# +dport_map_port_68=25 +dport_map_port_69=26 +dport_map_port_70=27 +dport_map_port_71=28 +portmap_68=113:400 +phy_chain_rx_lane_map_physical{113.0}=0x32461057 +phy_chain_rx_lane_map_physical{114.0}=0x32461057 +phy_chain_rx_lane_map_physical{115.0}=0x32461057 +phy_chain_rx_lane_map_physical{116.0}=0x32461057 +phy_chain_rx_lane_map_physical{117.0}=0x32461057 +phy_chain_rx_lane_map_physical{118.0}=0x32461057 +phy_chain_rx_lane_map_physical{119.0}=0x32461057 +phy_chain_rx_lane_map_physical{120.0}=0x32461057 +phy_chain_tx_lane_map_physical{113.0}=0x54107362 +phy_chain_tx_lane_map_physical{114.0}=0x54107362 +phy_chain_tx_lane_map_physical{115.0}=0x54107362 +phy_chain_tx_lane_map_physical{116.0}=0x54107362 +phy_chain_tx_lane_map_physical{117.0}=0x54107362 +phy_chain_tx_lane_map_physical{118.0}=0x54107362 +phy_chain_tx_lane_map_physical{119.0}=0x54107362 +phy_chain_tx_lane_map_physical{120.0}=0x54107362 +serdes_core_rx_polarity_flip_physical{113}=0x47 +serdes_core_rx_polarity_flip_physical{114}=0x47 +serdes_core_rx_polarity_flip_physical{115}=0x47 +serdes_core_rx_polarity_flip_physical{116}=0x47 +serdes_core_rx_polarity_flip_physical{117}=0x47 +serdes_core_rx_polarity_flip_physical{118}=0x47 +serdes_core_rx_polarity_flip_physical{119}=0x47 +serdes_core_rx_polarity_flip_physical{120}=0x47 +serdes_core_tx_polarity_flip_physical{113}=0xBD +serdes_core_tx_polarity_flip_physical{114}=0xBD +serdes_core_tx_polarity_flip_physical{115}=0xBD +serdes_core_tx_polarity_flip_physical{116}=0xBD +serdes_core_tx_polarity_flip_physical{117}=0xBD +serdes_core_tx_polarity_flip_physical{118}=0xBD +serdes_core_tx_polarity_flip_physical{119}=0xBD +serdes_core_tx_polarity_flip_physical{120}=0xBD + +#BC15# +dport_map_port_72=29 +dport_map_port_73=30 +dport_map_port_74=31 +dport_map_port_75=32 +portmap_72=121:400 +phy_chain_rx_lane_map_physical{121.0}=0x75342610 +phy_chain_rx_lane_map_physical{122.0}=0x75342610 +phy_chain_rx_lane_map_physical{123.0}=0x75342610 +phy_chain_rx_lane_map_physical{124.0}=0x75342610 +phy_chain_rx_lane_map_physical{125.0}=0x75342610 +phy_chain_rx_lane_map_physical{126.0}=0x75342610 +phy_chain_rx_lane_map_physical{127.0}=0x75342610 +phy_chain_rx_lane_map_physical{128.0}=0x75342610 +phy_chain_tx_lane_map_physical{121.0}=0x24617350 +phy_chain_tx_lane_map_physical{122.0}=0x24617350 +phy_chain_tx_lane_map_physical{123.0}=0x24617350 +phy_chain_tx_lane_map_physical{124.0}=0x24617350 +phy_chain_tx_lane_map_physical{125.0}=0x24617350 +phy_chain_tx_lane_map_physical{126.0}=0x24617350 +phy_chain_tx_lane_map_physical{127.0}=0x24617350 +phy_chain_tx_lane_map_physical{128.0}=0x24617350 +serdes_core_rx_polarity_flip_physical{121}=0x36 +serdes_core_rx_polarity_flip_physical{122}=0x36 +serdes_core_rx_polarity_flip_physical{123}=0x36 +serdes_core_rx_polarity_flip_physical{124}=0x36 +serdes_core_rx_polarity_flip_physical{125}=0x36 +serdes_core_rx_polarity_flip_physical{126}=0x36 +serdes_core_rx_polarity_flip_physical{127}=0x36 +serdes_core_rx_polarity_flip_physical{128}=0x36 +serdes_core_tx_polarity_flip_physical{121}=0x7F +serdes_core_tx_polarity_flip_physical{122}=0x7F +serdes_core_tx_polarity_flip_physical{123}=0x7F +serdes_core_tx_polarity_flip_physical{124}=0x7F +serdes_core_tx_polarity_flip_physical{125}=0x7F +serdes_core_tx_polarity_flip_physical{126}=0x7F +serdes_core_tx_polarity_flip_physical{127}=0x7F +serdes_core_tx_polarity_flip_physical{128}=0x7F + +#BC16# +dport_map_port_80=49 +dport_map_port_81=50 +dport_map_port_82=51 +dport_map_port_83=52 +portmap_80=129:400 +phy_chain_rx_lane_map_physical{129.0}=0x45302716 +phy_chain_rx_lane_map_physical{130.0}=0x45302716 +phy_chain_rx_lane_map_physical{131.0}=0x45302716 +phy_chain_rx_lane_map_physical{132.0}=0x45302716 +phy_chain_rx_lane_map_physical{133.0}=0x45302716 +phy_chain_rx_lane_map_physical{134.0}=0x45302716 +phy_chain_rx_lane_map_physical{135.0}=0x45302716 +phy_chain_rx_lane_map_physical{136.0}=0x45302716 +phy_chain_tx_lane_map_physical{129.0}=0x24763150 +phy_chain_tx_lane_map_physical{130.0}=0x24763150 +phy_chain_tx_lane_map_physical{131.0}=0x24763150 +phy_chain_tx_lane_map_physical{132.0}=0x24763150 +phy_chain_tx_lane_map_physical{133.0}=0x24763150 +phy_chain_tx_lane_map_physical{134.0}=0x24763150 +phy_chain_tx_lane_map_physical{135.0}=0x24763150 +phy_chain_tx_lane_map_physical{136.0}=0x24763150 +serdes_core_rx_polarity_flip_physical{129}=0xA3 +serdes_core_rx_polarity_flip_physical{130}=0xA3 +serdes_core_rx_polarity_flip_physical{131}=0xA3 +serdes_core_rx_polarity_flip_physical{132}=0xA3 +serdes_core_rx_polarity_flip_physical{133}=0xA3 +serdes_core_rx_polarity_flip_physical{134}=0xA3 +serdes_core_rx_polarity_flip_physical{135}=0xA3 +serdes_core_rx_polarity_flip_physical{136}=0xA3 +serdes_core_tx_polarity_flip_physical{129}=0x5C +serdes_core_tx_polarity_flip_physical{130}=0x5C +serdes_core_tx_polarity_flip_physical{131}=0x5C +serdes_core_tx_polarity_flip_physical{132}=0x5C +serdes_core_tx_polarity_flip_physical{133}=0x5C +serdes_core_tx_polarity_flip_physical{134}=0x5C +serdes_core_tx_polarity_flip_physical{135}=0x5C +serdes_core_tx_polarity_flip_physical{136}=0x5C + +#BC17# +dport_map_port_84=53 +dport_map_port_85=54 +dport_map_port_86=55 +dport_map_port_87=56 +portmap_84=137:400 +phy_chain_rx_lane_map_physical{137.0}=0x12460357 +phy_chain_rx_lane_map_physical{138.0}=0x12460357 +phy_chain_rx_lane_map_physical{139.0}=0x12460357 +phy_chain_rx_lane_map_physical{140.0}=0x12460357 +phy_chain_rx_lane_map_physical{141.0}=0x12460357 +phy_chain_rx_lane_map_physical{142.0}=0x12460357 +phy_chain_rx_lane_map_physical{143.0}=0x12460357 +phy_chain_rx_lane_map_physical{144.0}=0x12460357 +phy_chain_tx_lane_map_physical{137.0}=0x70135462 +phy_chain_tx_lane_map_physical{138.0}=0x70135462 +phy_chain_tx_lane_map_physical{139.0}=0x70135462 +phy_chain_tx_lane_map_physical{140.0}=0x70135462 +phy_chain_tx_lane_map_physical{141.0}=0x70135462 +phy_chain_tx_lane_map_physical{142.0}=0x70135462 +phy_chain_tx_lane_map_physical{143.0}=0x70135462 +phy_chain_tx_lane_map_physical{144.0}=0x70135462 +serdes_core_rx_polarity_flip_physical{137}=0x4B +serdes_core_rx_polarity_flip_physical{138}=0x4B +serdes_core_rx_polarity_flip_physical{139}=0x4B +serdes_core_rx_polarity_flip_physical{140}=0x4B +serdes_core_rx_polarity_flip_physical{141}=0x4B +serdes_core_rx_polarity_flip_physical{142}=0x4B +serdes_core_rx_polarity_flip_physical{143}=0x4B +serdes_core_rx_polarity_flip_physical{144}=0x4B +serdes_core_tx_polarity_flip_physical{137}=0xF8 +serdes_core_tx_polarity_flip_physical{138}=0xF8 +serdes_core_tx_polarity_flip_physical{139}=0xF8 +serdes_core_tx_polarity_flip_physical{140}=0xF8 +serdes_core_tx_polarity_flip_physical{141}=0xF8 +serdes_core_tx_polarity_flip_physical{142}=0xF8 +serdes_core_tx_polarity_flip_physical{143}=0xF8 +serdes_core_tx_polarity_flip_physical{144}=0xF8 + +#BC18# +dport_map_port_88=57 +dport_map_port_89=58 +dport_map_port_90=59 +dport_map_port_91=60 +portmap_88=145:400 +phy_chain_rx_lane_map_physical{145.0}=0x20563147 +phy_chain_rx_lane_map_physical{146.0}=0x20563147 +phy_chain_rx_lane_map_physical{147.0}=0x20563147 +phy_chain_rx_lane_map_physical{148.0}=0x20563147 +phy_chain_rx_lane_map_physical{149.0}=0x20563147 +phy_chain_rx_lane_map_physical{150.0}=0x20563147 +phy_chain_rx_lane_map_physical{151.0}=0x20563147 +phy_chain_rx_lane_map_physical{152.0}=0x20563147 +phy_chain_tx_lane_map_physical{145.0}=0x54126073 +phy_chain_tx_lane_map_physical{146.0}=0x54126073 +phy_chain_tx_lane_map_physical{147.0}=0x54126073 +phy_chain_tx_lane_map_physical{148.0}=0x54126073 +phy_chain_tx_lane_map_physical{149.0}=0x54126073 +phy_chain_tx_lane_map_physical{150.0}=0x54126073 +phy_chain_tx_lane_map_physical{151.0}=0x54126073 +phy_chain_tx_lane_map_physical{152.0}=0x54126073 +serdes_core_rx_polarity_flip_physical{145}=0xE1 +serdes_core_rx_polarity_flip_physical{146}=0xE1 +serdes_core_rx_polarity_flip_physical{147}=0xE1 +serdes_core_rx_polarity_flip_physical{148}=0xE1 +serdes_core_rx_polarity_flip_physical{149}=0xE1 +serdes_core_rx_polarity_flip_physical{150}=0xE1 +serdes_core_rx_polarity_flip_physical{151}=0xE1 +serdes_core_rx_polarity_flip_physical{152}=0xE1 +serdes_core_tx_polarity_flip_physical{145}=0xD5 +serdes_core_tx_polarity_flip_physical{146}=0xD5 +serdes_core_tx_polarity_flip_physical{147}=0xD5 +serdes_core_tx_polarity_flip_physical{148}=0xD5 +serdes_core_tx_polarity_flip_physical{149}=0xD5 +serdes_core_tx_polarity_flip_physical{150}=0xD5 +serdes_core_tx_polarity_flip_physical{151}=0xD5 +serdes_core_tx_polarity_flip_physical{152}=0xD5 + +#BC19# +dport_map_port_92=61 +dport_map_port_93=62 +dport_map_port_94=63 +dport_map_port_95=64 +portmap_92=153:400 +phy_chain_rx_lane_map_physical{153.0}=0x10652473 +phy_chain_rx_lane_map_physical{154.0}=0x10652473 +phy_chain_rx_lane_map_physical{155.0}=0x10652473 +phy_chain_rx_lane_map_physical{156.0}=0x10652473 +phy_chain_rx_lane_map_physical{157.0}=0x10652473 +phy_chain_rx_lane_map_physical{158.0}=0x10652473 +phy_chain_rx_lane_map_physical{159.0}=0x10652473 +phy_chain_rx_lane_map_physical{160.0}=0x10652473 +phy_chain_tx_lane_map_physical{153.0}=0x15036427 +phy_chain_tx_lane_map_physical{154.0}=0x15036427 +phy_chain_tx_lane_map_physical{155.0}=0x15036427 +phy_chain_tx_lane_map_physical{156.0}=0x15036427 +phy_chain_tx_lane_map_physical{157.0}=0x15036427 +phy_chain_tx_lane_map_physical{158.0}=0x15036427 +phy_chain_tx_lane_map_physical{159.0}=0x15036427 +phy_chain_tx_lane_map_physical{160.0}=0x15036427 +serdes_core_rx_polarity_flip_physical{153}=0xB1 +serdes_core_rx_polarity_flip_physical{154}=0xB1 +serdes_core_rx_polarity_flip_physical{155}=0xB1 +serdes_core_rx_polarity_flip_physical{156}=0xB1 +serdes_core_rx_polarity_flip_physical{157}=0xB1 +serdes_core_rx_polarity_flip_physical{158}=0xB1 +serdes_core_rx_polarity_flip_physical{159}=0xB1 +serdes_core_rx_polarity_flip_physical{160}=0xB1 +serdes_core_tx_polarity_flip_physical{153}=0x5E +serdes_core_tx_polarity_flip_physical{154}=0x5E +serdes_core_tx_polarity_flip_physical{155}=0x5E +serdes_core_tx_polarity_flip_physical{156}=0x5E +serdes_core_tx_polarity_flip_physical{157}=0x5E +serdes_core_tx_polarity_flip_physical{158}=0x5E +serdes_core_tx_polarity_flip_physical{159}=0x5E +serdes_core_tx_polarity_flip_physical{160}=0x5E + +#BC20# +dport_map_port_104=69 +dport_map_port_105=70 +dport_map_port_106=71 +dport_map_port_107=72 +portmap_104=161:400 +phy_chain_rx_lane_map_physical{161.0}=0x70125643 +phy_chain_rx_lane_map_physical{162.0}=0x70125643 +phy_chain_rx_lane_map_physical{163.0}=0x70125643 +phy_chain_rx_lane_map_physical{164.0}=0x70125643 +phy_chain_rx_lane_map_physical{165.0}=0x70125643 +phy_chain_rx_lane_map_physical{166.0}=0x70125643 +phy_chain_rx_lane_map_physical{167.0}=0x70125643 +phy_chain_rx_lane_map_physical{168.0}=0x70125643 +phy_chain_tx_lane_map_physical{161.0}=0x21073456 +phy_chain_tx_lane_map_physical{162.0}=0x21073456 +phy_chain_tx_lane_map_physical{163.0}=0x21073456 +phy_chain_tx_lane_map_physical{164.0}=0x21073456 +phy_chain_tx_lane_map_physical{165.0}=0x21073456 +phy_chain_tx_lane_map_physical{166.0}=0x21073456 +phy_chain_tx_lane_map_physical{167.0}=0x21073456 +phy_chain_tx_lane_map_physical{168.0}=0x21073456 +serdes_core_rx_polarity_flip_physical{161}=0x27 +serdes_core_rx_polarity_flip_physical{162}=0x27 +serdes_core_rx_polarity_flip_physical{163}=0x27 +serdes_core_rx_polarity_flip_physical{164}=0x27 +serdes_core_rx_polarity_flip_physical{165}=0x27 +serdes_core_rx_polarity_flip_physical{166}=0x27 +serdes_core_rx_polarity_flip_physical{167}=0x27 +serdes_core_rx_polarity_flip_physical{168}=0x27 +serdes_core_tx_polarity_flip_physical{161}=0x5 +serdes_core_tx_polarity_flip_physical{162}=0x5 +serdes_core_tx_polarity_flip_physical{163}=0x5 +serdes_core_tx_polarity_flip_physical{164}=0x5 +serdes_core_tx_polarity_flip_physical{165}=0x5 +serdes_core_tx_polarity_flip_physical{166}=0x5 +serdes_core_tx_polarity_flip_physical{167}=0x5 +serdes_core_tx_polarity_flip_physical{168}=0x5 + +#BC21# +dport_map_port_100=65 +dport_map_port_101=66 +dport_map_port_102=67 +dport_map_port_103=68 +portmap_100=169:400 +phy_chain_rx_lane_map_physical{169.0}=0x27416350 +phy_chain_rx_lane_map_physical{170.0}=0x27416350 +phy_chain_rx_lane_map_physical{171.0}=0x27416350 +phy_chain_rx_lane_map_physical{172.0}=0x27416350 +phy_chain_rx_lane_map_physical{173.0}=0x27416350 +phy_chain_rx_lane_map_physical{174.0}=0x27416350 +phy_chain_rx_lane_map_physical{175.0}=0x27416350 +phy_chain_rx_lane_map_physical{176.0}=0x27416350 +phy_chain_tx_lane_map_physical{169.0}=0x36570412 +phy_chain_tx_lane_map_physical{170.0}=0x36570412 +phy_chain_tx_lane_map_physical{171.0}=0x36570412 +phy_chain_tx_lane_map_physical{172.0}=0x36570412 +phy_chain_tx_lane_map_physical{173.0}=0x36570412 +phy_chain_tx_lane_map_physical{174.0}=0x36570412 +phy_chain_tx_lane_map_physical{175.0}=0x36570412 +phy_chain_tx_lane_map_physical{176.0}=0x36570412 +serdes_core_rx_polarity_flip_physical{169}=0x3C +serdes_core_rx_polarity_flip_physical{170}=0x3C +serdes_core_rx_polarity_flip_physical{171}=0x3C +serdes_core_rx_polarity_flip_physical{172}=0x3C +serdes_core_rx_polarity_flip_physical{173}=0x3C +serdes_core_rx_polarity_flip_physical{174}=0x3C +serdes_core_rx_polarity_flip_physical{175}=0x3C +serdes_core_rx_polarity_flip_physical{176}=0x3C +serdes_core_tx_polarity_flip_physical{169}=0x7D +serdes_core_tx_polarity_flip_physical{170}=0x7D +serdes_core_tx_polarity_flip_physical{171}=0x7D +serdes_core_tx_polarity_flip_physical{172}=0x7D +serdes_core_tx_polarity_flip_physical{173}=0x7D +serdes_core_tx_polarity_flip_physical{174}=0x7D +serdes_core_tx_polarity_flip_physical{175}=0x7D +serdes_core_tx_polarity_flip_physical{176}=0x7D + +#BC22# +dport_map_port_108=73 +dport_map_port_109=74 +dport_map_port_110=75 +dport_map_port_111=76 +portmap_108=177:400 +phy_chain_rx_lane_map_physical{177.0}=0x04153726 +phy_chain_rx_lane_map_physical{178.0}=0x04153726 +phy_chain_rx_lane_map_physical{179.0}=0x04153726 +phy_chain_rx_lane_map_physical{180.0}=0x04153726 +phy_chain_rx_lane_map_physical{181.0}=0x04153726 +phy_chain_rx_lane_map_physical{182.0}=0x04153726 +phy_chain_rx_lane_map_physical{183.0}=0x04153726 +phy_chain_rx_lane_map_physical{184.0}=0x04153726 +phy_chain_tx_lane_map_physical{177.0}=0x47305162 +phy_chain_tx_lane_map_physical{178.0}=0x47305162 +phy_chain_tx_lane_map_physical{179.0}=0x47305162 +phy_chain_tx_lane_map_physical{180.0}=0x47305162 +phy_chain_tx_lane_map_physical{181.0}=0x47305162 +phy_chain_tx_lane_map_physical{182.0}=0x47305162 +phy_chain_tx_lane_map_physical{183.0}=0x47305162 +phy_chain_tx_lane_map_physical{184.0}=0x47305162 +serdes_core_rx_polarity_flip_physical{177}=0x96 +serdes_core_rx_polarity_flip_physical{178}=0x96 +serdes_core_rx_polarity_flip_physical{179}=0x96 +serdes_core_rx_polarity_flip_physical{180}=0x96 +serdes_core_rx_polarity_flip_physical{181}=0x96 +serdes_core_rx_polarity_flip_physical{182}=0x96 +serdes_core_rx_polarity_flip_physical{183}=0x96 +serdes_core_rx_polarity_flip_physical{184}=0x96 +serdes_core_tx_polarity_flip_physical{177}=0xE9 +serdes_core_tx_polarity_flip_physical{178}=0xE9 +serdes_core_tx_polarity_flip_physical{179}=0xE9 +serdes_core_tx_polarity_flip_physical{180}=0xE9 +serdes_core_tx_polarity_flip_physical{181}=0xE9 +serdes_core_tx_polarity_flip_physical{182}=0xE9 +serdes_core_tx_polarity_flip_physical{183}=0xE9 +serdes_core_tx_polarity_flip_physical{184}=0xE9 + +#BC23# +dport_map_port_112=77 +dport_map_port_113=78 +dport_map_port_114=79 +dport_map_port_115=80 +portmap_112=185:400 +phy_chain_rx_lane_map_physical{185.0}=0x02561347 +phy_chain_rx_lane_map_physical{186.0}=0x02561347 +phy_chain_rx_lane_map_physical{187.0}=0x02561347 +phy_chain_rx_lane_map_physical{188.0}=0x02561347 +phy_chain_rx_lane_map_physical{189.0}=0x02561347 +phy_chain_rx_lane_map_physical{190.0}=0x02561347 +phy_chain_rx_lane_map_physical{191.0}=0x02561347 +phy_chain_rx_lane_map_physical{192.0}=0x02561347 +phy_chain_tx_lane_map_physical{185.0}=0x50327614 +phy_chain_tx_lane_map_physical{186.0}=0x50327614 +phy_chain_tx_lane_map_physical{187.0}=0x50327614 +phy_chain_tx_lane_map_physical{188.0}=0x50327614 +phy_chain_tx_lane_map_physical{189.0}=0x50327614 +phy_chain_tx_lane_map_physical{190.0}=0x50327614 +phy_chain_tx_lane_map_physical{191.0}=0x50327614 +phy_chain_tx_lane_map_physical{192.0}=0x50327614 +serdes_core_rx_polarity_flip_physical{185}=0xE1 +serdes_core_rx_polarity_flip_physical{186}=0xE1 +serdes_core_rx_polarity_flip_physical{187}=0xE1 +serdes_core_rx_polarity_flip_physical{188}=0xE1 +serdes_core_rx_polarity_flip_physical{189}=0xE1 +serdes_core_rx_polarity_flip_physical{190}=0xE1 +serdes_core_rx_polarity_flip_physical{191}=0xE1 +serdes_core_rx_polarity_flip_physical{192}=0xE1 +serdes_core_tx_polarity_flip_physical{185}=0x0 +serdes_core_tx_polarity_flip_physical{186}=0x0 +serdes_core_tx_polarity_flip_physical{187}=0x0 +serdes_core_tx_polarity_flip_physical{188}=0x0 +serdes_core_tx_polarity_flip_physical{189}=0x0 +serdes_core_tx_polarity_flip_physical{190}=0x0 +serdes_core_tx_polarity_flip_physical{191}=0x0 +serdes_core_tx_polarity_flip_physical{192}=0x0 + +#BC24# +dport_map_port_124=101 +dport_map_port_125=102 +dport_map_port_126=103 +dport_map_port_127=104 +portmap_124=193:400 +phy_chain_rx_lane_map_physical{193.0}=0x74126503 +phy_chain_rx_lane_map_physical{194.0}=0x74126503 +phy_chain_rx_lane_map_physical{195.0}=0x74126503 +phy_chain_rx_lane_map_physical{196.0}=0x74126503 +phy_chain_rx_lane_map_physical{197.0}=0x74126503 +phy_chain_rx_lane_map_physical{198.0}=0x74126503 +phy_chain_rx_lane_map_physical{199.0}=0x74126503 +phy_chain_rx_lane_map_physical{200.0}=0x74126503 +phy_chain_tx_lane_map_physical{193.0}=0x43571620 +phy_chain_tx_lane_map_physical{194.0}=0x43571620 +phy_chain_tx_lane_map_physical{195.0}=0x43571620 +phy_chain_tx_lane_map_physical{196.0}=0x43571620 +phy_chain_tx_lane_map_physical{197.0}=0x43571620 +phy_chain_tx_lane_map_physical{198.0}=0x43571620 +phy_chain_tx_lane_map_physical{199.0}=0x43571620 +phy_chain_tx_lane_map_physical{200.0}=0x43571620 +serdes_core_rx_polarity_flip_physical{193}=0x69 +serdes_core_rx_polarity_flip_physical{194}=0x69 +serdes_core_rx_polarity_flip_physical{195}=0x69 +serdes_core_rx_polarity_flip_physical{196}=0x69 +serdes_core_rx_polarity_flip_physical{197}=0x69 +serdes_core_rx_polarity_flip_physical{198}=0x69 +serdes_core_rx_polarity_flip_physical{199}=0x69 +serdes_core_rx_polarity_flip_physical{200}=0x69 +serdes_core_tx_polarity_flip_physical{193}=0xC4 +serdes_core_tx_polarity_flip_physical{194}=0xC4 +serdes_core_tx_polarity_flip_physical{195}=0xC4 +serdes_core_tx_polarity_flip_physical{196}=0xC4 +serdes_core_tx_polarity_flip_physical{197}=0xC4 +serdes_core_tx_polarity_flip_physical{198}=0xC4 +serdes_core_tx_polarity_flip_physical{199}=0xC4 +serdes_core_tx_polarity_flip_physical{200}=0xC4 + +#BC25# +dport_map_port_120=97 +dport_map_port_121=98 +dport_map_port_122=99 +dport_map_port_123=100 +portmap_120=201:400 +phy_chain_rx_lane_map_physical{201.0}=0x45031726 +phy_chain_rx_lane_map_physical{202.0}=0x45031726 +phy_chain_rx_lane_map_physical{203.0}=0x45031726 +phy_chain_rx_lane_map_physical{204.0}=0x45031726 +phy_chain_rx_lane_map_physical{205.0}=0x45031726 +phy_chain_rx_lane_map_physical{206.0}=0x45031726 +phy_chain_rx_lane_map_physical{207.0}=0x45031726 +phy_chain_rx_lane_map_physical{208.0}=0x45031726 +phy_chain_tx_lane_map_physical{201.0}=0x23761450 +phy_chain_tx_lane_map_physical{202.0}=0x23761450 +phy_chain_tx_lane_map_physical{203.0}=0x23761450 +phy_chain_tx_lane_map_physical{204.0}=0x23761450 +phy_chain_tx_lane_map_physical{205.0}=0x23761450 +phy_chain_tx_lane_map_physical{206.0}=0x23761450 +phy_chain_tx_lane_map_physical{207.0}=0x23761450 +phy_chain_tx_lane_map_physical{208.0}=0x23761450 +serdes_core_rx_polarity_flip_physical{201}=0x99 +serdes_core_rx_polarity_flip_physical{202}=0x99 +serdes_core_rx_polarity_flip_physical{203}=0x99 +serdes_core_rx_polarity_flip_physical{204}=0x99 +serdes_core_rx_polarity_flip_physical{205}=0x99 +serdes_core_rx_polarity_flip_physical{206}=0x99 +serdes_core_rx_polarity_flip_physical{207}=0x99 +serdes_core_rx_polarity_flip_physical{208}=0x99 +serdes_core_tx_polarity_flip_physical{201}=0x7F +serdes_core_tx_polarity_flip_physical{202}=0x7F +serdes_core_tx_polarity_flip_physical{203}=0x7F +serdes_core_tx_polarity_flip_physical{204}=0x7F +serdes_core_tx_polarity_flip_physical{205}=0x7F +serdes_core_tx_polarity_flip_physical{206}=0x7F +serdes_core_tx_polarity_flip_physical{207}=0x7F +serdes_core_tx_polarity_flip_physical{208}=0x7F + +#BC26# +dport_map_port_132=109 +dport_map_port_133=110 +dport_map_port_134=111 +dport_map_port_135=112 +portmap_132=209:400 +phy_chain_rx_lane_map_physical{209.0}=0x46150723 +phy_chain_rx_lane_map_physical{210.0}=0x46150723 +phy_chain_rx_lane_map_physical{211.0}=0x46150723 +phy_chain_rx_lane_map_physical{212.0}=0x46150723 +phy_chain_rx_lane_map_physical{213.0}=0x46150723 +phy_chain_rx_lane_map_physical{214.0}=0x46150723 +phy_chain_rx_lane_map_physical{215.0}=0x46150723 +phy_chain_rx_lane_map_physical{216.0}=0x46150723 +phy_chain_tx_lane_map_physical{209.0}=0x12603754 +phy_chain_tx_lane_map_physical{210.0}=0x12603754 +phy_chain_tx_lane_map_physical{211.0}=0x12603754 +phy_chain_tx_lane_map_physical{212.0}=0x12603754 +phy_chain_tx_lane_map_physical{213.0}=0x12603754 +phy_chain_tx_lane_map_physical{214.0}=0x12603754 +phy_chain_tx_lane_map_physical{215.0}=0x12603754 +phy_chain_tx_lane_map_physical{216.0}=0x12603754 +serdes_core_rx_polarity_flip_physical{209}=0xE1 +serdes_core_rx_polarity_flip_physical{210}=0xE1 +serdes_core_rx_polarity_flip_physical{211}=0xE1 +serdes_core_rx_polarity_flip_physical{212}=0xE1 +serdes_core_rx_polarity_flip_physical{213}=0xE1 +serdes_core_rx_polarity_flip_physical{214}=0xE1 +serdes_core_rx_polarity_flip_physical{215}=0xE1 +serdes_core_rx_polarity_flip_physical{216}=0xE1 +serdes_core_tx_polarity_flip_physical{209}=0x29 +serdes_core_tx_polarity_flip_physical{210}=0x29 +serdes_core_tx_polarity_flip_physical{211}=0x29 +serdes_core_tx_polarity_flip_physical{212}=0x29 +serdes_core_tx_polarity_flip_physical{213}=0x29 +serdes_core_tx_polarity_flip_physical{214}=0x29 +serdes_core_tx_polarity_flip_physical{215}=0x29 +serdes_core_tx_polarity_flip_physical{216}=0x29 + +#BC27# +dport_map_port_128=105 +dport_map_port_129=106 +dport_map_port_130=107 +dport_map_port_131=108 +portmap_128=217:400 +phy_chain_rx_lane_map_physical{217.0}=0x46127503 +phy_chain_rx_lane_map_physical{218.0}=0x46127503 +phy_chain_rx_lane_map_physical{219.0}=0x46127503 +phy_chain_rx_lane_map_physical{220.0}=0x46127503 +phy_chain_rx_lane_map_physical{221.0}=0x46127503 +phy_chain_rx_lane_map_physical{222.0}=0x46127503 +phy_chain_rx_lane_map_physical{223.0}=0x46127503 +phy_chain_rx_lane_map_physical{224.0}=0x46127503 +phy_chain_tx_lane_map_physical{217.0}=0x54273016 +phy_chain_tx_lane_map_physical{218.0}=0x54273016 +phy_chain_tx_lane_map_physical{219.0}=0x54273016 +phy_chain_tx_lane_map_physical{220.0}=0x54273016 +phy_chain_tx_lane_map_physical{221.0}=0x54273016 +phy_chain_tx_lane_map_physical{222.0}=0x54273016 +phy_chain_tx_lane_map_physical{223.0}=0x54273016 +phy_chain_tx_lane_map_physical{224.0}=0x54273016 +serdes_core_rx_polarity_flip_physical{217}=0xE1 +serdes_core_rx_polarity_flip_physical{218}=0xE1 +serdes_core_rx_polarity_flip_physical{219}=0xE1 +serdes_core_rx_polarity_flip_physical{220}=0xE1 +serdes_core_rx_polarity_flip_physical{221}=0xE1 +serdes_core_rx_polarity_flip_physical{222}=0xE1 +serdes_core_rx_polarity_flip_physical{223}=0xE1 +serdes_core_rx_polarity_flip_physical{224}=0xE1 +serdes_core_tx_polarity_flip_physical{217}=0x5B +serdes_core_tx_polarity_flip_physical{218}=0x5B +serdes_core_tx_polarity_flip_physical{219}=0x5B +serdes_core_tx_polarity_flip_physical{220}=0x5B +serdes_core_tx_polarity_flip_physical{221}=0x5B +serdes_core_tx_polarity_flip_physical{222}=0x5B +serdes_core_tx_polarity_flip_physical{223}=0x5B +serdes_core_tx_polarity_flip_physical{224}=0x5B + +#BC28# +dport_map_port_144=117 +dport_map_port_145=118 +dport_map_port_146=119 +dport_map_port_147=120 +portmap_144=225:400 +phy_chain_rx_lane_map_physical{225.0}=0x52761340 +phy_chain_rx_lane_map_physical{226.0}=0x52761340 +phy_chain_rx_lane_map_physical{227.0}=0x52761340 +phy_chain_rx_lane_map_physical{228.0}=0x52761340 +phy_chain_rx_lane_map_physical{229.0}=0x52761340 +phy_chain_rx_lane_map_physical{230.0}=0x52761340 +phy_chain_rx_lane_map_physical{231.0}=0x52761340 +phy_chain_rx_lane_map_physical{232.0}=0x52761340 +phy_chain_tx_lane_map_physical{225.0}=0x53462107 +phy_chain_tx_lane_map_physical{226.0}=0x53462107 +phy_chain_tx_lane_map_physical{227.0}=0x53462107 +phy_chain_tx_lane_map_physical{228.0}=0x53462107 +phy_chain_tx_lane_map_physical{229.0}=0x53462107 +phy_chain_tx_lane_map_physical{230.0}=0x53462107 +phy_chain_tx_lane_map_physical{231.0}=0x53462107 +phy_chain_tx_lane_map_physical{232.0}=0x53462107 +serdes_core_rx_polarity_flip_physical{225}=0x3C +serdes_core_rx_polarity_flip_physical{226}=0x3C +serdes_core_rx_polarity_flip_physical{227}=0x3C +serdes_core_rx_polarity_flip_physical{228}=0x3C +serdes_core_rx_polarity_flip_physical{229}=0x3C +serdes_core_rx_polarity_flip_physical{230}=0x3C +serdes_core_rx_polarity_flip_physical{231}=0x3C +serdes_core_rx_polarity_flip_physical{232}=0x3C +serdes_core_tx_polarity_flip_physical{225}=0x71 +serdes_core_tx_polarity_flip_physical{226}=0x71 +serdes_core_tx_polarity_flip_physical{227}=0x71 +serdes_core_tx_polarity_flip_physical{228}=0x71 +serdes_core_tx_polarity_flip_physical{229}=0x71 +serdes_core_tx_polarity_flip_physical{230}=0x71 +serdes_core_tx_polarity_flip_physical{231}=0x71 +serdes_core_tx_polarity_flip_physical{232}=0x71 + +#BC29# +dport_map_port_140=113 +dport_map_port_141=114 +dport_map_port_142=115 +dport_map_port_143=116 +portmap_140=233:400 +phy_chain_rx_lane_map_physical{233.0}=0x45021736 +phy_chain_rx_lane_map_physical{234.0}=0x45021736 +phy_chain_rx_lane_map_physical{235.0}=0x45021736 +phy_chain_rx_lane_map_physical{236.0}=0x45021736 +phy_chain_rx_lane_map_physical{237.0}=0x45021736 +phy_chain_rx_lane_map_physical{238.0}=0x45021736 +phy_chain_rx_lane_map_physical{239.0}=0x45021736 +phy_chain_rx_lane_map_physical{240.0}=0x45021736 +phy_chain_tx_lane_map_physical{233.0}=0x20465371 +phy_chain_tx_lane_map_physical{234.0}=0x20465371 +phy_chain_tx_lane_map_physical{235.0}=0x20465371 +phy_chain_tx_lane_map_physical{236.0}=0x20465371 +phy_chain_tx_lane_map_physical{237.0}=0x20465371 +phy_chain_tx_lane_map_physical{238.0}=0x20465371 +phy_chain_tx_lane_map_physical{239.0}=0x20465371 +phy_chain_tx_lane_map_physical{240.0}=0x20465371 +serdes_core_rx_polarity_flip_physical{233}=0x8B +serdes_core_rx_polarity_flip_physical{234}=0x8B +serdes_core_rx_polarity_flip_physical{235}=0x8B +serdes_core_rx_polarity_flip_physical{236}=0x8B +serdes_core_rx_polarity_flip_physical{237}=0x8B +serdes_core_rx_polarity_flip_physical{238}=0x8B +serdes_core_rx_polarity_flip_physical{239}=0x8B +serdes_core_rx_polarity_flip_physical{240}=0x8B +serdes_core_tx_polarity_flip_physical{233}=0x35 +serdes_core_tx_polarity_flip_physical{234}=0x35 +serdes_core_tx_polarity_flip_physical{235}=0x35 +serdes_core_tx_polarity_flip_physical{236}=0x35 +serdes_core_tx_polarity_flip_physical{237}=0x35 +serdes_core_tx_polarity_flip_physical{238}=0x35 +serdes_core_tx_polarity_flip_physical{239}=0x35 +serdes_core_tx_polarity_flip_physical{240}=0x35 + +#BC30# +dport_map_port_152=125 +dport_map_port_153=126 +dport_map_port_154=127 +dport_map_port_155=128 +portmap_152=241:400 +phy_chain_rx_lane_map_physical{241.0}=0x65721403 +phy_chain_rx_lane_map_physical{242.0}=0x65721403 +phy_chain_rx_lane_map_physical{243.0}=0x65721403 +phy_chain_rx_lane_map_physical{244.0}=0x65721403 +phy_chain_rx_lane_map_physical{245.0}=0x65721403 +phy_chain_rx_lane_map_physical{246.0}=0x65721403 +phy_chain_rx_lane_map_physical{247.0}=0x65721403 +phy_chain_rx_lane_map_physical{248.0}=0x65721403 +phy_chain_tx_lane_map_physical{241.0}=0x32647150 +phy_chain_tx_lane_map_physical{242.0}=0x32647150 +phy_chain_tx_lane_map_physical{243.0}=0x32647150 +phy_chain_tx_lane_map_physical{244.0}=0x32647150 +phy_chain_tx_lane_map_physical{245.0}=0x32647150 +phy_chain_tx_lane_map_physical{246.0}=0x32647150 +phy_chain_tx_lane_map_physical{247.0}=0x32647150 +phy_chain_tx_lane_map_physical{248.0}=0x32647150 +serdes_core_rx_polarity_flip_physical{241}=0x8D +serdes_core_rx_polarity_flip_physical{242}=0x8D +serdes_core_rx_polarity_flip_physical{243}=0x8D +serdes_core_rx_polarity_flip_physical{244}=0x8D +serdes_core_rx_polarity_flip_physical{245}=0x8D +serdes_core_rx_polarity_flip_physical{246}=0x8D +serdes_core_rx_polarity_flip_physical{247}=0x8D +serdes_core_rx_polarity_flip_physical{248}=0x8D +serdes_core_tx_polarity_flip_physical{241}=0x35 +serdes_core_tx_polarity_flip_physical{242}=0x35 +serdes_core_tx_polarity_flip_physical{243}=0x35 +serdes_core_tx_polarity_flip_physical{244}=0x35 +serdes_core_tx_polarity_flip_physical{245}=0x35 +serdes_core_tx_polarity_flip_physical{246}=0x35 +serdes_core_tx_polarity_flip_physical{247}=0x35 +serdes_core_tx_polarity_flip_physical{248}=0x35 + +#BC31# +dport_map_port_148=121 +dport_map_port_149=122 +dport_map_port_150=123 +dport_map_port_151=124 +portmap_148=249:400 +phy_chain_rx_lane_map_physical{249.0}=0x13560247 +phy_chain_rx_lane_map_physical{250.0}=0x13560247 +phy_chain_rx_lane_map_physical{251.0}=0x13560247 +phy_chain_rx_lane_map_physical{252.0}=0x13560247 +phy_chain_rx_lane_map_physical{253.0}=0x13560247 +phy_chain_rx_lane_map_physical{254.0}=0x13560247 +phy_chain_rx_lane_map_physical{255.0}=0x13560247 +phy_chain_rx_lane_map_physical{256.0}=0x13560247 +phy_chain_tx_lane_map_physical{249.0}=0x10456273 +phy_chain_tx_lane_map_physical{250.0}=0x10456273 +phy_chain_tx_lane_map_physical{251.0}=0x10456273 +phy_chain_tx_lane_map_physical{252.0}=0x10456273 +phy_chain_tx_lane_map_physical{253.0}=0x10456273 +phy_chain_tx_lane_map_physical{254.0}=0x10456273 +phy_chain_tx_lane_map_physical{255.0}=0x10456273 +phy_chain_tx_lane_map_physical{256.0}=0x10456273 +serdes_core_rx_polarity_flip_physical{249}=0x2D +serdes_core_rx_polarity_flip_physical{250}=0x2D +serdes_core_rx_polarity_flip_physical{251}=0x2D +serdes_core_rx_polarity_flip_physical{252}=0x2D +serdes_core_rx_polarity_flip_physical{253}=0x2D +serdes_core_rx_polarity_flip_physical{254}=0x2D +serdes_core_rx_polarity_flip_physical{255}=0x2D +serdes_core_rx_polarity_flip_physical{256}=0x2D +serdes_core_tx_polarity_flip_physical{249}=0xD6 +serdes_core_tx_polarity_flip_physical{250}=0xD6 +serdes_core_tx_polarity_flip_physical{251}=0xD6 +serdes_core_tx_polarity_flip_physical{252}=0xD6 +serdes_core_tx_polarity_flip_physical{253}=0xD6 +serdes_core_tx_polarity_flip_physical{254}=0xD6 +serdes_core_tx_polarity_flip_physical{255}=0xD6 +serdes_core_tx_polarity_flip_physical{256}=0xD6 + +#dport_map_port_38=129 +#portmap_38=257:10 +#dport_map_port_118=130 +#portmap_118=258:10 diff --git a/device/accton/x86_64-accton_as9716_32d-r0/custom_led.bin b/device/accton/x86_64-accton_as9716_32d-r0/custom_led.bin new file mode 100644 index 0000000000000000000000000000000000000000..07cfab044f60a214db558d0c7b274a5ad359d5a9 GIT binary patch literal 2044 zcmZA23s_TS9LMqZYy&1Lf>**Lo^6V#sN50_im}(7nq9WaTBS9~(ku%t)393Kp;ETz`8@A`=lu73-}CM{&)ZZ#T1vTX z^PF0f+Flhlq0O=`7L)X`UQ^Z*M{~gA5!Mo4l24?#JymkV=vrAP+`}}ruPT~OG@A#{ z&<$BLd`_9`vkyELuzNbwEv%9Ld{?FHss6Wre`|k%9NN;K?MZFz&n7?py!@T5{pa#i zM-8z}^NBt=zEsyd8LKLp;Y_ijWi>X@RCwB`I%E{r6pL7NW{ty7=kbdi*3-jd&Z?5# z&YNLr>kQ{sq*xm#35%t)gRQKzy{)FSv9z#vC2G>Hzb+{fkU9D{G8+xHPQqTvf$Ur8tkc|s5 z7&#aMwp*~>g6$S;x8N@jmmnW@+=tnigZnWT58y$}LnR)ahhc z;}yJ$*YG;Fq5*HBb#1B@^s3ekvx8Ep`YwrGd;h(ia&BLN-J37ydeUC|ARxByA$ z4i!C+jGoY-umB@=Q@@8jcpo3&Lwp23-oo41jvd&EcknKD;R}3;udomM@io3d2mySI zPw*-B;xl}XAb!9R{D_}$6hGq^G~oam@huMGJA98rIE+8gjMMlNf8lS05!vKp49D>+ ze!~g;j*~crbD#M7*}5{cXnaiWzB-|q(s~AKM28XE$F7x%t;*?598=+Rj4iN>P9Y=T zixS6GD4OWsE>M(MT_O6L1BHpZS~`?;L&&I!kU@)Y*pW~A*<538u+E&?GdM>iw4@p| zHPo7%yt2SxOHBGV+wi~aJryO6qJnKnXR?JR8iHgu)lZbga-Np_jZqg#MVlpg zT{Y2ry_{vMmM*iBvcPFvo~sU*E2R=rvXvZ{G-Xsu(@^_v;{anI#%guM`P+sJ)JB`l zVfM#|6l%p{aTxruAu+%lu*(cJd~#|yNA0 zhwvM#jcNUYUHl>~I^dQ4oQq|OJ3%*OB=~x{V)fe7{r=_D4*1>VTXX9&d%62X~=qH6P6&V+Sx1Ls0G9L|rN4X5f& zY6mr0?V|VPIa9)Mo}-Byg-t(FB6@d Date: Wed, 22 Apr 2020 19:41:48 -0700 Subject: [PATCH 0579/1427] [platform-modules]: set debian control depends on unsigned kernel package (#4466) Signed-off-by: Guohan Lu --- platform/barefoot/bfn-modules/debian/control | 2 +- .../debian/control | 2 +- .../debian/control | 2 +- .../sonic-platform-modules-bfn/debian/control | 2 +- .../debian/control | 2 +- platform/broadcom/saibcm-modules/debian/control | 2 +- .../debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 8 ++++---- .../sonic-platform-modules-dell/debian/control | 14 +++++++------- .../sonic-platform-modules-delta/debian/control | 10 +++++----- .../sonic-platform-modules-inventec/debian/control | 12 ++++++------ .../sonic-platform-modules-mitac/debian/control | 2 +- .../cavium/cavm_platform_modules/DEBIAN/control | 2 +- .../sonic-platform-modules-e582/debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 2 +- .../sonic-platform-modules-delta/debian/control | 2 +- platform/nephos/nephos-modules/debian/control | 2 +- .../sonic-platform-modules-accton/debian/control | 2 +- .../sonic-platform-modules-cig/debian/control | 6 +++--- .../sonic-platform-modules-pegatron/debian/control | 2 +- 20 files changed, 42 insertions(+), 42 deletions(-) diff --git a/platform/barefoot/bfn-modules/debian/control b/platform/barefoot/bfn-modules/debian/control index 32c161f13320..13a3b72a03b7 100644 --- a/platform/barefoot/bfn-modules/debian/control +++ b/platform/barefoot/bfn-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: bfn-modules Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for bfn asic for mmap diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index 19e4cdba062c..9a512bd0e143 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-montara Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control index 2137d1ef9129..1538a7041800 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-newport Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index ff942dc3722d..639db9110df5 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control index 58628bff07a9..63857c093532 100644 --- a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: platform-modules-wnc-osw1800 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/saibcm-modules/debian/control b/platform/broadcom/saibcm-modules/debian/control index eca9977fcd92..72542564abf7 100644 --- a/platform/broadcom/saibcm-modules/debian/control +++ b/platform/broadcom/saibcm-modules/debian/control @@ -10,5 +10,5 @@ Standards-Version: 3.9.3 Package: opennsl-modules Architecture: amd64 Section: main -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for broadcom SAI diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control index 65333e6a0994..55533f735a53 100644 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: sonic-platform-alphanetworks-snh60a0-320fv2 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-alphanetworks-snh60b0-640f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 4062cf452d1d..b69c44beab63 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -7,21 +7,21 @@ Standards-Version: 3.9.3 Package: platform-modules-dx010 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-haliburton Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-seastone2 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as led, sfp Package: platform-modules-silverstone Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as led, sfp. diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index a052f72f9896..6a0ab0e7d2ac 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -7,35 +7,35 @@ Standards-Version: 3.9.3 Package: platform-modules-s6000 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9100 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s6100 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9264f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5232f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5248f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9332f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index 2974bd42a6a3..6ab0f3cf2f4c 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -7,25 +7,25 @@ Standards-Version: 3.9.3 Package: platform-modules-ag9032v1 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9064 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag5648 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-et-6248brb Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9032v2a Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as syseeprom, sfp diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index fc9492fe931c..31a6e67d0982 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-d7032q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7054q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6254qs Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6556 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6356 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7264q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/control b/platform/broadcom/sonic-platform-modules-mitac/debian/control index 8f738a42eb43..b693fb382a89 100644 --- a/platform/broadcom/sonic-platform-modules-mitac/debian/control +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-mitac-ly1200-32x Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/cavium/cavm_platform_modules/DEBIAN/control b/platform/cavium/cavm_platform_modules/DEBIAN/control index cac08ec8f4e7..233aa9ec7baf 100755 --- a/platform/cavium/cavm_platform_modules/DEBIAN/control +++ b/platform/cavium/cavm_platform_modules/DEBIAN/control @@ -1,6 +1,6 @@ Package: cavm-platform-modules Version: 1.0 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Maintainer: Nadiya.Stetskovych@cavium.com Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-e582/debian/control b/platform/centec/sonic-platform-modules-e582/debian/control index 44ffddfa0d65..1c31c94244ec 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/control +++ b/platform/centec/sonic-platform-modules-e582/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: platform-modules-e582-48x2q4z Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-e582-48x6q Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/innovium/sonic-platform-modules-cel/debian/control b/platform/innovium/sonic-platform-modules-cel/debian/control index 9794ba7c7ce1..30baa323c36a 100755 --- a/platform/innovium/sonic-platform-modules-cel/debian/control +++ b/platform/innovium/sonic-platform-modules-cel/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: platform-modules-midstone-200i Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices diff --git a/platform/innovium/sonic-platform-modules-delta/debian/control b/platform/innovium/sonic-platform-modules-delta/debian/control index e4ce62b2f9b5..7395157d35f8 100644 --- a/platform/innovium/sonic-platform-modules-delta/debian/control +++ b/platform/innovium/sonic-platform-modules-delta/debian/control @@ -7,7 +7,7 @@ Standards-Version: 3.9.3 Package: platform-modules-et-c032if Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/nephos-modules/debian/control b/platform/nephos/nephos-modules/debian/control index f5799a93fd0c..8450eeae1e01 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: nephos-modules Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for nephos asic diff --git a/platform/nephos/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control index 35c3fc19159b..a1068b7a7c5c 100755 --- a/platform/nephos/sonic-platform-modules-accton/debian/control +++ b/platform/nephos/sonic-platform-modules-accton/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: sonic-platform-accton-as7116-54x Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-cig/debian/control b/platform/nephos/sonic-platform-modules-cig/debian/control index 87f0d09fecde..0c70d57ddbf2 100644 --- a/platform/nephos/sonic-platform-modules-cig/debian/control +++ b/platform/nephos/sonic-platform-modules-cig/debian/control @@ -7,15 +7,15 @@ Standards-Version: 3.9.3 Package: sonic-platform-cig-cs6436-56p Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-cig-cs6436-54p Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-cig-cs5435-54p Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/control b/platform/nephos/sonic-platform-modules-pegatron/debian/control index bb4727a79b61..4fed2d1aa15e 100755 --- a/platform/nephos/sonic-platform-modules-pegatron/debian/control +++ b/platform/nephos/sonic-platform-modules-pegatron/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-pegatron-porsche Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp From 91293780971a16a12b4a7b232437bcd8496869ac Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Thu, 23 Apr 2020 13:54:48 +0800 Subject: [PATCH 0580/1427] [accton/as9716-32d] add support get_transceiver_change_event (#4105) Co-authored-by: Jostar Yang --- .../plugins/sfputil.py | 97 +++++++++++++++++-- .../modules/accton_as9716_32d_cpld.c | 74 ++++++++++++++ 2 files changed, 164 insertions(+), 7 deletions(-) diff --git a/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py index bc3297471c5c..9cec97c44fb1 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py @@ -5,6 +5,8 @@ try: import time + import os + import sys, getopt from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -141,10 +143,91 @@ def reset(self, port_num): return True - def get_transceiver_change_event(self): - """ - TODO: This function need to be implemented - when decide to support monitoring SFP(Xcvrd) - on this platform. - """ - raise NotImplementedError \ No newline at end of file + def get_cpld_interrupt(self): + port_dict={} + for i in range(0,4): + if i==0 or i==1: + cpld_i2c_path = self.BASE_CPLD1_PATH + "cpld_intr_" + str(i+1) + else: + cpld_i2c_path = self.BASE_CPLD2_PATH + "cpld_intr_" +str(i+1) + + start_i=(i*8) + end_i=(i*8+8) + try: + val_file = open(cpld_i2c_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + for k in range (start_i, end_i): + port_dict[k]=0 + return port_dict + + status = val_file.readline().rstrip() + val_file.close() + status=status.strip() + status= int(status, 16) + + interrupt_status = ~(status & 0xff) + if interrupt_status: + port_shift=0 + for k in range (start_i, end_i): + if interrupt_status & (0x1< 0: + timeout = timeout / float(1000) # Convert to secs + else: + print "get_transceiver_change_event:Invalid timeout value", timeout + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print 'get_transceiver_change_event:' \ + 'time wrap / invalid timeout value', timeout + + return False, {} # Time wrap or possibly incorrect timeout + + #for i in range(self.port_start, self.port_end+1): + # ori_present[i]=self.get_presence(i) + + while timeout >= 0: + change_status=0 + + port_dict = self.get_cpld_interrupt() + present=0 + for key, value in port_dict.iteritems(): + if value==1: + present=self.get_presence(key) + change_status=1 + if present: + port_dict[key]='1' + else: + port_dict[key]='0' + + if change_status: + return True, port_dict + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, {} + print "get_evt_change_event: Should not reach here." + return False, {} \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c index 874bdc33bea4..d473bb452411 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c @@ -72,6 +72,7 @@ MODULE_DEVICE_TABLE(i2c, as9716_32d_cpld_id); #define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index #define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index #define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index +#define CPLD_INTR_ATTR_ID(index) CPLD_INTR_##index enum as9716_32d_cpld_sysfs_attributes { CPLD_VERSION, @@ -149,10 +150,17 @@ enum as9716_32d_cpld_sysfs_attributes { TRANSCEIVER_RESET_ATTR_ID(30), TRANSCEIVER_RESET_ATTR_ID(31), TRANSCEIVER_RESET_ATTR_ID(32), + CPLD_INTR_ATTR_ID(1), + CPLD_INTR_ATTR_ID(2), + CPLD_INTR_ATTR_ID(3), + CPLD_INTR_ATTR_ID(4), + }; /* sysfs attributes for hwmon */ +static ssize_t show_interrupt(struct device *dev, struct device_attribute *da, + char *buf); static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, @@ -188,6 +196,11 @@ static int as9716_32d_cpld_write_internal(struct i2c_client *client, u8 reg, u8 static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, get_mode_reset, set_mode_reset, MODULE_RESET_##index) #define DECLARE_TRANSCEIVER_RESET_ATTR(index) &sensor_dev_attr_module_reset_##index.dev_attr.attr +/*cpld interrupt*/ +#define DECLARE_CPLD_DEVICE_INTR_ATTR(index) \ + static SENSOR_DEVICE_ATTR(cpld_intr_##index, S_IRUGO, show_interrupt, NULL, CPLD_INTR_##index) +#define DECLARE_CPLD_INTR_ATTR(index) &sensor_dev_attr_cpld_intr_##index.dev_attr.attr + static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); @@ -261,6 +274,10 @@ DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(29); DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(30); DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(31); DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(32); +DECLARE_CPLD_DEVICE_INTR_ATTR(1); +DECLARE_CPLD_DEVICE_INTR_ATTR(2); +DECLARE_CPLD_DEVICE_INTR_ATTR(3); +DECLARE_CPLD_DEVICE_INTR_ATTR(4); @@ -309,6 +326,8 @@ static struct attribute *as9716_32d_cpld1_attributes[] = { DECLARE_TRANSCEIVER_RESET_ATTR(14), DECLARE_TRANSCEIVER_RESET_ATTR(15), DECLARE_TRANSCEIVER_RESET_ATTR(16), + DECLARE_CPLD_INTR_ATTR(1), + DECLARE_CPLD_INTR_ATTR(2), NULL }; @@ -355,6 +374,8 @@ static struct attribute *as9716_32d_cpld2_attributes[] = { DECLARE_TRANSCEIVER_RESET_ATTR(30), DECLARE_TRANSCEIVER_RESET_ATTR(31), DECLARE_TRANSCEIVER_RESET_ATTR(32), + DECLARE_CPLD_INTR_ATTR(3), + DECLARE_CPLD_INTR_ATTR(4), NULL }; @@ -363,6 +384,47 @@ static const struct attribute_group as9716_32d_cpld2_group = { }; +static ssize_t show_interrupt(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as9716_32d_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0; + + switch (attr->index) + { + case CPLD_INTR_1: + reg = 0x10; + break; + case CPLD_INTR_3: + reg = 0x10; + break; + case CPLD_INTR_2: + reg = 0x11; + break; + case CPLD_INTR_4: + reg = 0x11; + break; + default: + return -ENODEV; + } + mutex_lock(&data->update_lock); + status = as9716_32d_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "0x%x\n", status); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + + static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf) { @@ -723,9 +785,21 @@ static int as9716_32d_cpld_probe(struct i2c_client *client, break; case as9716_32d_cpld1: group = &as9716_32d_cpld1_group; + /*Set interrupt mask to 0, and then can get intr from 0x8*/ + status=as9716_32d_cpld_write_internal(client, 0x9, 0x0); + if (status < 0) + { + dev_dbg(&client->dev, "cpld1 reg 0x9 err %d\n", status); + } break; case as9716_32d_cpld2: group = &as9716_32d_cpld2_group; + /*Set interrupt mask to 0, and then can get intr from 0x8*/ + status=as9716_32d_cpld_write_internal(client, 0x9, 0x0); + if (status < 0) + { + dev_dbg(&client->dev, "cpld2 reg 0x65 err %d\n", status); + } break; case as9716_32d_cpld_cpu: /* Disable CPLD reset to avoid DUT will be reset. From 057ced03910a78f02402828a6d7000f513fc2a30 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 23 Apr 2020 09:42:22 -0700 Subject: [PATCH 0581/1427] [bgpcfgd]: Split one bgp mega-template to chunks. (#4143) The one big bgp configuration template was splitted into chunks. Currently we have three types of bgp neighbor peers: general bgp peers. They are represented by CONFIG_DB::BGP_NEIGHBOR table entries dynamic bgp peers. They are represented by CONFIG_DB::BGP_PEER_RANGE table entries monitors bgp peers. They are represented by CONFIG_DB::BGP_MONITORS table entries This PR introduces three templates for each peer type: bgp policies: represent policieas that will be applied to the bgp peer-group (ip prefix-lists, route-maps, etc) bgp peer-group: represent bgp peer group which has common configuration for the bgp peer type and uses bgp routing policy from the previous item bgp peer-group instance: represent bgp configuration, which will be used to instatiate a bgp peer-group for the bgp peer-type. Usually this one is simple, consist of the referral to the bgp peer-group, bgp peer description and bgp peer ip address. This PR redefined constant.yml file. Now this file has a setting for to use or don't use bgp_neighbor metadata. This file has more parameters for now, which are not used. They will be used in the next iteration of bgpcfgd. Currently all tests have been disabled. I'm going to create next PR with the tests right after this PR is merged. I'm going to introduce better bgpcfgd in a short time. It will include support of dynamic changes for the templates. FIX:: #4231 --- dockers/docker-fpm-frr/Dockerfile.j2 | 2 +- dockers/docker-fpm-frr/TSA | 44 +- dockers/docker-fpm-frr/TSB | 39 +- dockers/docker-fpm-frr/TSC | 51 +- dockers/docker-fpm-frr/bgpcfgd | 1235 ++++++++++++----- dockers/docker-fpm-frr/bgpd.conf.default.j2 | 180 --- .../docker-fpm-frr/bgpd.tsa.isolate.conf.j2 | 10 - .../docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 | 6 - dockers/docker-fpm-frr/frr.conf.j2 | 18 - .../{ => frr/bgpd}/bgpd.conf.j2 | 12 +- .../docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 81 ++ ...gpd.spine_chassis_frontend_router.conf.j2} | 0 .../bgpd/templates/dynamic/instance.conf.j2 | 38 + .../bgpd/templates/dynamic/peer-group.conf.j2 | 7 + .../bgpd/templates/dynamic/policies.conf.j2 | 9 + .../bgpd/templates/general/instance.conf.j2} | 27 +- .../bgpd/templates/general/peer-group.conf.j2 | 24 + .../bgpd/templates/general/policies.conf.j2 | 30 + .../bgpd/templates/monitors/instance.conf.j2 | 13 + .../templates/monitors/peer-group.conf.j2 | 12 + .../bgpd/templates/monitors/policies.conf.j2 | 9 + .../frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 | 5 + .../frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 | 3 + .../{ => frr/common}/daemons.common.conf.j2 | 2 + .../frr/common/functions.conf.j2 | 23 + dockers/docker-fpm-frr/frr/frr.conf.j2 | 19 + dockers/docker-fpm-frr/{ => frr}/isolate.j2 | 0 .../{ => frr/staticd}/staticd.conf.j2 | 2 +- .../staticd}/staticd.default_route.conf.j2 | 0 dockers/docker-fpm-frr/{ => frr}/unisolate.j2 | 0 .../{ => frr/zebra}/zebra.conf.j2 | 4 +- .../frr/zebra/zebra.interfaces.conf.j2 | 25 + .../frr/zebra/zebra.set_src.conf.j2 | 8 + dockers/docker-fpm-frr/start.sh | 6 +- .../docker-fpm-frr/zebra.interfaces.conf.j2 | 60 - files/image_config/constants/constants.yml | 32 +- src/sonic-config-engine/.gitignore | 2 + src/sonic-config-engine/sonic-cfggen | 6 +- .../tests/sample_output/bgpd_frr.conf | 68 +- .../tests/sample_output/frr.conf | 78 +- .../tests/sample_output/staticd_frr.conf | 4 +- .../sample_output/t2-chassis-fe-bgpd.conf | 48 +- .../t2-chassis-fe-vni-zebra.conf | 13 +- .../sample_output/t2-chassis-fe-zebra.conf | 13 +- .../tests/sample_output/zebra_frr.conf | 19 +- src/sonic-config-engine/tests/test_frr.py | 13 +- .../tests/test_j2files_t2_chassis_fe.py | 13 +- 47 files changed, 1463 insertions(+), 850 deletions(-) delete mode 100644 dockers/docker-fpm-frr/bgpd.conf.default.j2 delete mode 100644 dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 delete mode 100644 dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 delete mode 100644 dockers/docker-fpm-frr/frr.conf.j2 rename dockers/docker-fpm-frr/{ => frr/bgpd}/bgpd.conf.j2 (50%) create mode 100644 dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 rename dockers/docker-fpm-frr/{bgpd.conf.spine_chassis_frontend_router.j2 => frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2} (100%) create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/peer-group.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/policies.conf.j2 rename dockers/docker-fpm-frr/{bgpd.peer.conf.j2 => frr/bgpd/templates/general/instance.conf.j2} (64%) mode change 100755 => 100644 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/monitors/instance.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/monitors/peer-group.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/monitors/policies.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 rename dockers/docker-fpm-frr/{ => frr/common}/daemons.common.conf.j2 (71%) create mode 100644 dockers/docker-fpm-frr/frr/common/functions.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/frr.conf.j2 rename dockers/docker-fpm-frr/{ => frr}/isolate.j2 (100%) rename dockers/docker-fpm-frr/{ => frr/staticd}/staticd.conf.j2 (85%) rename dockers/docker-fpm-frr/{ => frr/staticd}/staticd.default_route.conf.j2 (100%) rename dockers/docker-fpm-frr/{ => frr}/unisolate.j2 (100%) rename dockers/docker-fpm-frr/{ => frr/zebra}/zebra.conf.j2 (63%) create mode 100644 dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/zebra/zebra.set_src.conf.j2 delete mode 100644 dockers/docker-fpm-frr/zebra.interfaces.conf.j2 create mode 100644 src/sonic-config-engine/.gitignore diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index c382df3c2ba3..21318c7a63a3 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -39,8 +39,8 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs ~/.cache +COPY ["frr", "/usr/share/sonic/templates"] COPY ["bgpcfgd", "start.sh", "/usr/bin/"] -COPY ["*.j2", "/usr/share/sonic/templates/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["snmp.conf", "/etc/snmp/frr.conf"] COPY ["TSA", "/usr/bin/TSA"] diff --git a/dockers/docker-fpm-frr/TSA b/dockers/docker-fpm-frr/TSA index 1d74757b2d5f..441765694a4f 100755 --- a/dockers/docker-fpm-frr/TSA +++ b/dockers/docker-fpm-frr/TSA @@ -1,22 +1,38 @@ #!/bin/bash -c=0 -config=$(vtysh -c "show run") -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$((c+$?)) +function check_not_installed() +{ + c=0 + config=$(vtysh -c "show run") + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + c=$((c+$?)) + done + return $c +} -if [[ $c -eq 4 ]]; +check_not_installed +not_installed=$? +if [[ $not_installed -ne 0 ]]; then TSA_FILE=$(mktemp) - sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.tsa.isolate.conf.j2 > "$TSA_FILE" - vtysh -f "$TSA_FILE" - rm -f "$TSA_FILE" + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + case "$route_map_name" in + *V4*) + ip_version=V4 + ;; + *V6*) + ip_version=V6 + ;; + esac + sonic-cfggen -d -a "{\"route_map_name\":\"$route_map_name\", \"ip_version\": \"$ip_version\"}" -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd/tsa/bgpd.tsa.isolate.conf.j2 > "$TSA_FILE" + vtysh -f "$TSA_FILE" + rm -f "$TSA_FILE" + done echo "System Mode: Normal -> Maintenance" else echo "System is already in Maintenance mode" diff --git a/dockers/docker-fpm-frr/TSB b/dockers/docker-fpm-frr/TSB index 83ead86952c3..84a3c183e659 100755 --- a/dockers/docker-fpm-frr/TSB +++ b/dockers/docker-fpm-frr/TSB @@ -1,22 +1,33 @@ #!/bin/bash -c=0 -config=$(vtysh -c "show run") -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$((c+$?)) +function check_installed() +{ + c=0 + e=0 + config=$(vtysh -c "show run") + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + e=$((e+1)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + c=$((c+$?)) + e=$((e+1)) + done + return $((e-c)) +} -if [[ $c -eq 0 ]]; +check_installed +installed=$? +if [[ $installed -ne 0 ]]; then TSB_FILE=$(mktemp) - sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.tsa.unisolate.conf.j2 > "$TSB_FILE" - vtysh -f "$TSB_FILE" - rm -f "$TSB_FILE" + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + sonic-cfggen -d -a "{\"route_map_name\":\"$route_map_name\"}" -t /usr/share/sonic/templates/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 > "$TSB_FILE" + vtysh -f "$TSB_FILE" + rm -f "$TSB_FILE" + done echo "System Mode: Maintenance -> Normal" else echo "System is already in Normal mode" diff --git a/dockers/docker-fpm-frr/TSC b/dockers/docker-fpm-frr/TSC index c79f4bb2a41b..3a3ad73d00b4 100755 --- a/dockers/docker-fpm-frr/TSC +++ b/dockers/docker-fpm-frr/TSC @@ -1,21 +1,48 @@ #!/bin/bash +function check_not_installed() +{ + c=0 + config=$(vtysh -c "show run") + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + c=$((c+$?)) + done + return $c +} + +function check_installed() +{ + c=0 + e=0 + config=$(vtysh -c "show run") + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + e=$((e+1)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + c=$((c+$?)) + e=$((e+1)) + done + return $((e-c)) +} + echo "Traffic Shift Check:" -c=0 -config=$(vtysh -c "show run") -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$((c+$?)) -if [[ $c -eq 4 ]]; +check_not_installed +not_installed=$? + +check_installed +installed=$? + +if [[ $installed -eq 0 ]]; then echo "System Mode: Normal" -elif [[ $c -eq 0 ]]; +elif [[ $not_installed -eq 0 ]]; then echo "System Mode: Maintenance" else diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 4e638def47b7..be290dfc41cc 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -10,10 +10,11 @@ import traceback import os import tempfile import json -from collections import defaultdict +from collections import defaultdict, OrderedDict from pprint import pprint -from pprint import pformat +from functools import partial +import yaml import jinja2 import netaddr from swsscommon import swsscommon @@ -23,35 +24,178 @@ g_run = True g_debug = False -def run_command(command, shell=False): - str_cmd = " ".join(command) +def log_debug(msg): + """ Send a message msg to the syslog as DEBUG """ if g_debug: - syslog.syslog(syslog.LOG_DEBUG, "execute command {}.".format(str_cmd)) + syslog.syslog(syslog.LOG_DEBUG, msg) + +def log_notice(msg): + """ Send a message msg to the syslog as NOTICE """ + syslog.syslog(syslog.LOG_NOTICE, msg) + +def log_info(msg): + """ Send a message msg to the syslog as INFO """ + syslog.syslog(syslog.LOG_INFO, msg) + +def log_warn(msg): + """ Send a message msg to the syslog as WARNING """ + syslog.syslog(syslog.LOG_WARNING, msg) + +def log_err(msg): + """ Send a message msg to the syslog as ERR """ + syslog.syslog(syslog.LOG_ERR, msg) + +def log_crit(msg): + """ Send a message msg to the syslog as CRIT """ + syslog.syslog(syslog.LOG_CRIT, msg) + + +def run_command(command, shell=False, hide_errors=False): + """ + Run a linux command. The command is defined as a list. See subprocess.Popen documentation on format + :param command: command to execute. Type: List of strings + :param shell: execute the command through shell when True. Type: Boolean + :param hide_errors: don't report errors to syslog when True. Type: Boolean + :return: Tuple: integer exit code from the command, stdout as a string, stderr as a string + """ + log_debug("execute command '%s'." % str(command)) p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() if p.returncode != 0: - syslog.syslog(syslog.LOG_ERR, 'command execution returned {}. Command: "{}", stdout: "{}", stderr: "{}"'.format(p.returncode, str_cmd, stdout, stderr)) + if not hide_errors: + print_tuple = p.returncode, str(command), stdout, stderr + log_err("command execution returned %d. Command: '%s', stdout: '%s', stderr: '%s'" % print_tuple) return p.returncode, stdout, stderr +class ConfigMgr(object): + """ The class represents frr configuration """ + def __init__(self): + self.current_config = None + + def reset(self): + """ Reset stored config """ + self.current_config = None + + def update(self): + """ Read current config from FRR """ + self.current_config = None + ret_code, out, err = run_command(["vtysh", "-c", "show running-config"]) + if ret_code != 0: + log_crit("can't update running config: rc=%d out='%s' err='%s'" % (ret_code, out, err)) + return + self.current_config = self.to_canonical(out) + + def push(self, cmd): + """ + Push new changes to FRR + :param cmd: configuration change for FRR. Type: String + :return: True if change was applied successfully, False otherwise + """ + return self.write(cmd) + + def write(self, cmd): + """ + Write configuration change to FRR. + :param cmd: new configuration to write into FRR. Type: String + :return: True if change was applied successfully, False otherwise + """ + fd, tmp_filename = tempfile.mkstemp(dir='/tmp') + os.close(fd) + with open(tmp_filename, 'w') as fp: + fp.write("%s\n" % cmd) + command = ["vtysh", "-f", tmp_filename] + ret_code, out, err = run_command(command) + if not g_debug: + os.remove(tmp_filename) + if ret_code != 0: + err_tuple = str(cmd), ret_code, out, err + log_err("ConfigMgr::push(): can't push configuration '%s', rc='%d', stdout='%s', stderr='%s'" % err_tuple) + if ret_code == 0: + self.current_config = None # invalidate config + return ret_code == 0 + + @staticmethod + def to_canonical(raw_config): + """ + Convert FRR config into canonical format + :param raw_config: config in frr format + :return: frr config in canonical format + """ + parsed_config = [] + cur_offset = 0 + lines = raw_config.split("\n") + cur_path = [lines[0]] + for line in lines: + if line.strip().startswith('!') or line.strip() == '': + continue + n_spaces = ConfigMgr.count_spaces(line) + s_line = line.strip() + assert(n_spaces == cur_offset or (n_spaces + 1) == cur_offset or (n_spaces - 1) == cur_offset) + if n_spaces == cur_offset: + cur_path[-1] = s_line + elif n_spaces > cur_offset: + cur_path.append(s_line) + elif n_spaces < cur_offset: + cur_path = cur_path[:-2] + cur_path.append(s_line) + parsed_config.append(cur_path[:]) + cur_offset = n_spaces + return parsed_config + + @staticmethod + def count_spaces(line): + """ Count leading spaces in the line """ + return len(line) - len(line.lstrip()) + + @staticmethod + def from_canonical(canonical_config): + """ + Convert config from canonical format into FRR raw format + :param canonical_config: config in a canonical format + :return: config in the FRR raw format + """ + out = "" + for lines in canonical_config: + spaces = len(lines) - 1 + out += " " * spaces + lines[-1] + "\n" + + return out + + class TemplateFabric(object): + """ Fabric for rendering jinja2 templates """ def __init__(self): j2_template_paths = ['/usr/share/sonic/templates'] j2_loader = jinja2.FileSystemLoader(j2_template_paths) - j2_env = jinja2.Environment(loader=j2_loader, trim_blocks=True) + j2_env = jinja2.Environment(loader=j2_loader, trim_blocks=False) j2_env.filters['ipv4'] = self.is_ipv4 j2_env.filters['ipv6'] = self.is_ipv6 + j2_env.filters['pfx_filter'] = self.pfx_filter + for attr in ['ip', 'network', 'prefixlen', 'netmask']: + j2_env.filters[attr] = partial(self.prefix_attr, attr) self.env = j2_env def from_file(self, filename): + """ + Read a template from a file + :param filename: filename of the file. Type String + :return: Jinja2 template object + """ return self.env.get_template(filename) def from_string(self, tmpl): + """ + Read a template from a string + :param tmpl: Text representation of Jinja2 template + :return: Jinja2 template object + """ return self.env.from_string(tmpl) @staticmethod def is_ipv4(value): + """ Return True if the value is an ipv4 address """ if not value: return False if isinstance(value, netaddr.IPNetwork): @@ -59,12 +203,13 @@ class TemplateFabric(object): else: try: addr = netaddr.IPNetwork(str(value)) - except: + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): return False return addr.version == 4 @staticmethod def is_ipv6(value): + """ Return True if the value is an ipv6 address """ if not value: return False if isinstance(value, netaddr.IPNetwork): @@ -72,56 +217,70 @@ class TemplateFabric(object): else: try: addr = netaddr.IPNetwork(str(value)) - except: + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): return False return addr.version == 6 + @staticmethod + def prefix_attr(attr, value): + """ + Extract attribute from IPNetwork object + :param attr: attribute to extract + :param value: the string representation of ip prefix which will be converted to IPNetwork. + :return: the value of the extracted attribute + """ + if not value: + return None + else: + try: + prefix = netaddr.IPNetwork(str(value)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + return None + return str(getattr(prefix, attr)) -class Daemon(object): - SELECT_TIMEOUT = 1000 - - def __init__(self): - self.db_connectors = {} - self.selector = swsscommon.Select() - self.callbacks = defaultdict(lambda : defaultdict(list)) # db -> table -> [] - self.subscribers = set() - - def add_manager(self, db_name, table_name, callback): - db = swsscommon.SonicDBConfig.getDbId(db_name) - if db not in self.db_connectors: - self.db_connectors[db] = swsscommon.DBConnector(db_name, 0) + @staticmethod + def pfx_filter(value): + """INTERFACE Table can have keys in one of the two formats: + string or tuple - This filter skips the string keys and only + take into account the tuple. + For eg - VLAN_INTERFACE|Vlan1000 vs VLAN_INTERFACE|Vlan1000|192.168.0.1/21 + """ + table = OrderedDict() - if table_name not in self.callbacks[db]: - conn = self.db_connectors[db] - subscriber = swsscommon.SubscriberStateTable(conn, table_name) - self.subscribers.add(subscriber) - self.selector.addSelectable(subscriber) - self.callbacks[db][table_name].append(callback) + if not value: + return table - def run(self): - while g_run: - state, _ = self.selector.select(Daemon.SELECT_TIMEOUT) - if state == self.selector.TIMEOUT: + for key, val in value.items(): + if not isinstance(key, tuple): continue - elif state == self.selector.ERROR: - raise Exception("Received error from select") - - for subscriber in self.subscribers: - key, op, fvs = subscriber.pop() - if not key: - continue - if g_debug: - syslog.syslog(syslog.LOG_DEBUG, "Received message : {}".format((key, op, fvs))) - for callback in self.callbacks[subscriber.getDbConnector().getDbId()][subscriber.getTableName()]: - callback(key, op, dict(fvs)) + table[key] = val + return table class Directory(object): + """ This class stores values and notifies callbacks which were registered to be executed as soon + as some value is changed. This class works as DB cache mostly """ def __init__(self): - self.data = defaultdict(dict) - self.notify = defaultdict(lambda: defaultdict(list)) + self.data = defaultdict(dict) # storage. A key is a slot name, a value is a dictionary with data + self.notify = defaultdict(lambda: defaultdict(list)) # registered callbacks: slot -> path -> handlers[] + + @staticmethod + def get_slot_name(db, table): + """ Convert db, table pair into a slot name """ + return db + "__" + table def path_traverse(self, slot, path): + """ + Traverse a path in the storage. + If the path is an empty string, it returns a value as it is. + If the path is not an empty string, the method will traverse through the dictionary value. + Example: + self.data["key_1"] = { "abc": { "cde": { "fgh": "val_1", "ijk": "val_2" } } } + self.path_traverse("key_1", "abc/cde") will return True, { "fgh": "val_1", "ijk": "val_2" } + :param slot: storage key + :param path: storage path as a string where each internal key is separated by '/' + :return: a pair: True if the path was found, object if it was found + """ if slot not in self.data: return False, None elif path == '': @@ -133,77 +292,229 @@ class Directory(object): d = d[p] return True, d - def path_exist(self, slot, path): + def path_exist(self, db, table, path): + """ + Check if the path exists in the storage + :param db: db name + :param table: table name + :param path: requested path + :return: True if the path is available, False otherwise + """ + slot = self.get_slot_name(db, table) return self.path_traverse(slot, path)[0] - def get_path(self, slot, path): + def get_path(self, db, table, path): + """ + Return the requested path from the storage + :param db: db name + :param table: table name + :param path: requested path + :return: object if the path was found, None otherwise + """ + slot = self.get_slot_name(db, table) return self.path_traverse(slot, path)[1] - def put(self, slot, key, value): + def put(self, db, table, key, value): + """ + Put information into the storage. Notify handlers which are dependant to the information + :param db: db name + :param table: table name + :param key: key to change + :param value: value to put + :return: + """ + slot = self.get_slot_name(db, table) self.data[slot][key] = value if slot in self.notify: for path in self.notify[slot].keys(): - if self.path_exist(slot, path): + if self.path_exist(db, table, path): for handler in self.notify[slot][path]: handler() - def get(self, slot, key): + def get(self, db, table, key): + """ + Get a value from the storage + :param db: db name + :param table: table name + :param key: ket to get + :return: value for the key + """ + slot = self.get_slot_name(db, table) return self.data[slot][key] - def remove(self, slot, key): + def get_slot(self, db, table): + """ + Get an object from the storage + :param db: db name + :param table: table name + :return: object for the slot + """ + slot = self.get_slot_name(db, table) + return self.data[slot] + + def remove(self, db, table, key): + """ + Remove a value from the storage + :param db: db name + :param table: table name + :param key: key to remove + """ + slot = self.get_slot_name(db, table) if slot in self.data: if key in self.data[slot]: del self.data[slot][key] else: - syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) + log_err("Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) else: - syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) + log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) - def remove_slot(self, slot, key): + def remove_slot(self, db, table): + """ + Remove an object from the storage + :param db: db name + :param table: table name + """ + slot = self.get_slot_name(db, table) if slot in self.data: del self.data[slot] else: - syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) - - def get_slot(self, slot): - return self.data[slot] + log_err("Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) - def available_slot(self, slot): + def available(self, db, table): + """ + Check if the table is available + :param db: db name + :param table: table name + :return: True if the slot is available, False if not + """ + slot = self.get_slot_name(db, table) return slot in self.data def available_deps(self, deps): + """ + Check if all items from the deps list is available in the storage + :param deps: list of dependencies + :return: True if all dependencies are presented, False otherwise + """ res = True - for slot, path in deps: - res = res and self.path_exist(slot, path) + for db, table, path in deps: + res = res and self.path_exist(db, table, path) return res def subscribe(self, deps, handler): - for slot, path in deps: + """ + Subscribe the handler to be run as soon as all dependencies are presented + :param deps: + :param handler: + :return: + """ + for db, table, path in deps: + slot = self.get_slot_name(db, table) self.notify[slot][path].append(handler) +class Runner(object): + """ Implements main io-loop of the application + It will run event handlers inside of Manager objects + when corresponding db/table is updated + """ + SELECT_TIMEOUT = 1000 + + def __init__(self): + """ Constructor """ + self.db_connectors = {} + self.selector = swsscommon.Select() + self.callbacks = defaultdict(lambda: defaultdict(list)) # db -> table -> handlers[] + self.subscribers = set() + + def add_manager(self, manager): + """ + Add a manager to the Runner. + As soon as new events will be receiving by Runner, + handlers of corresponding objects will be executed + :param manager: an object implementing Manager + """ + db_name = manager.get_database() + table_name = manager.get_table_name() + db = swsscommon.SonicDBConfig.getDbId(db_name) + if db not in self.db_connectors: + self.db_connectors[db] = swsscommon.DBConnector(db_name, 0) + + if table_name not in self.callbacks[db]: + conn = self.db_connectors[db] + subscriber = swsscommon.SubscriberStateTable(conn, table_name) + self.subscribers.add(subscriber) + self.selector.addSelectable(subscriber) + self.callbacks[db][table_name].append(manager.handler) + + def run(self): + """ Main loop """ + while g_run: + state, _ = self.selector.select(Runner.SELECT_TIMEOUT) + if state == self.selector.TIMEOUT: + continue + elif state == self.selector.ERROR: + raise Exception("Received error from select") + + for subscriber in self.subscribers: + key, op, fvs = subscriber.pop() + if not key: + continue + log_debug("Received message : '%s'" % str((key, op, fvs))) + for callback in self.callbacks[subscriber.getDbConnector().getDbId()][subscriber.getTableName()]: + callback(key, op, dict(fvs)) + + class Manager(object): - def __init__(self, daemon, directory, deps, database, table_name): - self.directory = directory + """ This class represents a SONiC DB table """ + def __init__(self, common_objs, deps, database, table_name): + """ + Initialize class + :param common_objs: common object dictionary + :param deps: dependencies list + :param database: database name + :param table_name: table name + """ + self.directory = common_objs['directory'] + self.cfg_mgr = common_objs['cfg_mgr'] + self.constants = common_objs['constants'] self.deps = deps + self.db_name = database + self.table_name = table_name self.set_queue = [] - daemon.add_manager(database, table_name, self.handler) - directory.subscribe(deps, self.on_deps_change) + self.directory.subscribe(deps, self.on_deps_change) # subscribe this class method on directory changes + + def get_database(self): + """ Return associated database """ + return self.db_name + + def get_table_name(self): + """ Return associated table name""" + return self.table_name def handler(self, key, op, data): + """ + This method is executed on each add/remove event on the table. + :param key: key of the table entry + :param op: operation on the table entry. Could be either 'SET' or 'DEL' + :param data: associated data of the event. Empty for 'DEL' operation. + """ if op == swsscommon.SET_COMMAND: - if self.directory.available_deps(self.deps): + if self.directory.available_deps(self.deps): # all required dependencies are set in the Directory? res = self.set_handler(key, data) - if not res: + if not res: # set handler returned False, which means it is not ready to process is. Save it for later. + log_debug("'SET' handler returned NOT_READY for the Manager: %s" % self.__class__) self.set_queue.append((key, data)) else: + log_debug("Not all dependencies are met for the Manager: %s" % self.__class__) self.set_queue.append((key, data)) elif op == swsscommon.DEL_COMMAND: self.del_handler(key) else: - syslog.syslog(syslog.LOG_ERR, 'Invalid operation "%s" for key "%s"' % (op, key)) + log_err("Invalid operation '%s' for key '%s'" % (op, key)) def on_deps_change(self): + """ This method is being executed on every dependency change """ if not self.directory.available_deps(self.deps): return new_queue = [] @@ -214,286 +525,407 @@ class Manager(object): self.set_queue = new_queue def set_handler(self, key, data): - syslog.syslog(syslog.LOG_ERR, "%s wasn't implemented for %s" % (self.__name__, self.__class__)) + """ Placeholder for 'SET' command """ + log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) def del_handler(self, key): - syslog.syslog(syslog.LOG_ERR, "%s wasn't implemented for %s" % (self.__name__, self.__class__)) + """ Placeholder for 'DEL' command """ + log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) -class BGPDeviceMetaMgr(Manager): - def __init__(self, daemon, directory): - super(BGPDeviceMetaMgr, self).__init__( - daemon, - directory, +class BGPDataBaseMgr(Manager): + """ This class updates the Directory object when db table is updated """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(BGPDataBaseMgr, self).__init__( + common_objs, [], - "CONFIG_DB", - swsscommon.CFG_DEVICE_METADATA_TABLE_NAME + db, + table, ) def set_handler(self, key, data): - if key != "localhost" or "bgp_asn" not in data: - return - if self.directory.path_exist("meta", "localhost/bgp_asn"): - bgp_asn = self.directory.get_path("meta", "localhost/bgp_asn") - if bgp_asn == data["bgp_asn"]: - return - self.directory.put("meta", key, data) + """ Implementation of 'SET' command for this class """ + self.directory.put(self.db_name, self.table_name, key, data) return True def del_handler(self, key): - self.directory.remove("meta", key) + """ Implementation of 'DEL' command for this class """ + self.directory.remove(self.db_name, self.table_name, key) -class BGPNeighborMetaMgr(Manager): - def __init__(self, daemon, directory): - super(BGPNeighborMetaMgr, self).__init__( - daemon, - directory, +class InterfaceMgr(Manager): + """ This class updates the Directory object when interface-related table is updated """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(InterfaceMgr, self).__init__( + common_objs, [], - "CONFIG_DB", - swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME + db, + table, ) def set_handler(self, key, data): - self.directory.put("neigmeta", key, data) - + """ Implementation of 'SET' command. + Similar to BGPDataBaseMgr but enriches data object with additional data """ + # Interface table can have two keys, + # one with ip prefix and one without ip prefix + if '|' in key: + interface_name, network_str = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network_str)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + log_warn("Subnet '%s' format is wrong for interface '%s'" % (network_str, data["interface"])) + return True + data["interface"] = interface_name + data["prefixlen"] = str(network.prefixlen) + ip = str(network.ip) + self.directory.put("LOCAL", "local_addresses", ip, data) + self.directory.put(self.db_name, self.table_name, key, data) + self.directory.put("LOCAL", "interfaces", key, data) return True def del_handler(self, key): - self.directory.remove("neigmeta", key) - - -class BGPPeerMgr(Manager): - def __init__(self, daemon, directory): - super(BGPPeerMgr, self).__init__( - daemon, - directory, - [ - ("meta", "localhost/bgp_asn"), - ("neigmeta", ""), - ("local_addresses", ""), - ("interfaces", ""), - ], - "CONFIG_DB", - swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME - ) - self.peers = self.load_peers() - fabric = TemplateFabric() - self.templates = { - "add": fabric.from_file('bgpd.peer.conf.j2'), - "delete": fabric.from_string('no neighbor {{ neighbor_addr }}'), - "shutdown": fabric.from_string('neighbor {{ neighbor_addr }} shutdown'), - "no shutdown": fabric.from_string('no neighbor {{ neighbor_addr }} shutdown'), - } + """ Implementation of 'DEL' command + Also removes data object enrichment """ + if '|' in key: + interface, network = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + log_warn("Subnet '%s' format is wrong for interface '%s'" % (network, interface)) + return + ip = str(network.ip) + self.directory.remove("LOCAL", "local_addresses", ip) + self.directory.remove(self.db_name, self.table_name, key) + self.directory.remove("LOCAL", "interfaces", key) - def set_handler(self, key, data): - key = self.normalize_key(key) - vrf, nbr = key.split('|', 1) - if key not in self.peers: - cmd = None - if "local_addr" not in data: - syslog.syslog(syslog.LOG_WARNING, 'Peer {}. Error in missing required attribute "local_addr"'.format(key)) - else: - # The bgp session that belongs to a vnet cannot be advertised as the default BGP session. - # So we need to check whether this bgp session belongs to a vnet. - interface = InterfaceMgr.get_local_interface(self.directory, data["local_addr"]) - if not interface: - syslog.syslog(syslog.LOG_INFO, - 'Peer {} with local address {} wait for the corresponding interface to be set'.format( - key, - data["local_addr"] - ) - ) - return False - vnet = InterfaceMgr.get_vnet(interface) - if vnet: - # Ignore the bgp session that is in a vnet - syslog.syslog( - syslog.LOG_INFO, - 'Ignore the BGP peer {} as the interface {} is in vnet {}'.format( - key, - interface, - vnet - ) - ) - return True +class BGPPeerGroupMgr(object): + """ This class represents peer-group and routing policy for the peer_type """ + def __init__(self, common_objs, base_template): + """ + Construct the object + :param common_objs: common objects + :param base_template: path to the directory with Jinja2 templates + """ + self.cfg_mgr = common_objs['cfg_mgr'] + self.constants = common_objs['constants'] + tf = common_objs['tf'] + self.policy_template = tf.from_file(base_template + "policies.conf.j2") + self.peergroup_template = tf.from_file(base_template + "peer-group.conf.j2") - neigmeta = self.directory.get_slot("neigmeta") - if 'name' in data and data["name"] not in neigmeta: - syslog.syslog(syslog.LOG_INFO, - 'Peer {} with neighbor name {} wait for the corresponding neighbor metadata to be set'.format( - key, - data["name"] - ) - ) - return False - try: - cmd = self.templates["add"].render( - DEVICE_METADATA=self.directory.get_slot("meta"), - DEVICE_NEIGHBOR_METADATA=neigmeta, - neighbor_addr=nbr, - bgp_session=data - ) - except: - syslog.syslog(syslog.LOG_ERR, 'Peer {}. Error in rendering the template for "SET" command {}'.format(key, data)) - return True - if cmd is not None: - rc = self.apply_op(cmd, vrf) - if rc: - self.peers.add(key) - syslog.syslog(syslog.LOG_INFO, 'Peer {} added with attributes {}'.format(key, data)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} wasn't added.".format(key)) - else: - # when the peer is already configured we support "shutdown/no shutdown" - # commands for the peers only - if "admin_status" in data: - if data['admin_status'] == 'up': - rc = self.apply_op(self.templates["no shutdown"].render(neighbor_addr=nbr), vrf) - if rc: - syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "up"'.format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'up'.".format(key)) - elif data['admin_status'] == 'down': - rc = self.apply_op(self.templates["shutdown"].render(neighbor_addr=nbr), vrf) - if rc: - syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "down"'.format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'down'.".format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. has wrong attribute value attr['admin_status'] = '{}'".format(key, data['admin_status'])) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. No 'admin_status' attribute in the request".format(key)) - return True + def update(self, name, **kwargs): + """ + Update peer-group and routing policy for the peer with the name + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + rc_policy = self.update_policy(name, **kwargs) + rc_pg = self.update_pg(name, **kwargs) + return rc_policy and rc_pg - def del_handler(self, key): - key = self.normalize_key(key) - vrf, nbr = key.split('|', 1) - if key not in self.peers: - syslog.syslog(syslog.LOG_WARNING, 'Peer {} has not been found'.format(key)) - return - cmd = self.templates["delete"].render(neighbor_addr=nbr) - rc = self.apply_op(cmd, vrf) - if rc: - syslog.syslog(syslog.LOG_INFO, 'Peer {} has been removed'.format(key)) - self.peers.remove(key) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} hasn't been removed".format(key)) + def update_policy(self, name, **kwargs): + """ + Update routing policy for the peer + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + try: + policy = self.policy_template.render(**kwargs) + except jinja2.TemplateError as e: + log_err("Can't render policy template name: '%s': %s" % (name, str(e))) + return False - def apply_op(self, cmd, vrf): - bgp_asn = self.directory.get_slot("meta")["localhost"]["bgp_asn"] - fd, tmp_filename = tempfile.mkstemp(dir='/tmp') - os.close(fd) - with open(tmp_filename, 'w') as fp: - if vrf == 'default': - fp.write('router bgp %s\n' % bgp_asn) - else: - fp.write('router bgp %s vrf %s\n' % (bgp_asn, vrf)) - fp.write("%s\n" % cmd) + return self.update_entity(policy, "Routing policy for peer '%s'" % name) - command = ["vtysh", "-f", tmp_filename] - rc, _, _ = run_command(command) - os.remove(tmp_filename) - return rc == 0 + def update_pg(self, name, **kwargs): + """ + Update peer-group for the peer + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + try: + pg = self.peergroup_template.render(**kwargs) + except jinja2.TemplateError as e: + log_err("Can't render peer-group template: '%s': %s" % (name, str(e))) + return False - @staticmethod - def normalize_key(key): - if '|' not in key: - return 'default|' + key + if kwargs['vrf'] == 'default': + cmd = ('router bgp %s\n' % kwargs['bgp_asn']) + pg else: - return key + cmd = ('router bgp %s vrf %s\n' % (kwargs['bgp_asn'], kwargs['vrf'])) + pg - @staticmethod - def load_peers(): - vrfs = [] - command = ["vtysh", "-c", "show bgp vrfs json"] - rc, out, err = run_command(command) - if rc == 0: - js_vrf = json.loads(out) - vrfs = js_vrf['vrfs'].keys() + return self.update_entity(cmd, "Peer-group for peer '%s'" % name) - peers = set() - for vrf in vrfs: - command = ["vtysh", "-c", 'show bgp vrf {} neighbors json'.format(vrf)] - rc, out, err = run_command(command) - if rc == 0: - js_bgp = json.loads(out) - for nbr in js_bgp.keys(): - peers.add((vrf, nbr)) + def update_entity(self, cmd, txt): + """ + Send commands to FRR + :param cmd: commands to send in a raw form + :param txt: text for the syslog output + :return: + """ + ret_code = self.cfg_mgr.push(cmd) + if ret_code: + log_info("%s was updated" % txt) + else: + log_err("Can't update %s" % txt) + return ret_code - return peers +class BGPPeerMgrBase(Manager): + """ Manager of BGP peers """ + def __init__(self, common_objs, db_name, table_name, peer_type): + """ + Initialize the object + :param common_objs: common objects + :param table_name: name of the table with peers + :param peer_type: type of the peers. It is used to find right templates + """ + self.common_objs = common_objs + self.constants = self.common_objs["constants"] + self.fabric = common_objs['tf'] + self.peer_type = peer_type -class InterfaceMgr(Manager): - def __init__(self, daemon, directory, interface_table = swsscommon.CFG_INTF_TABLE_NAME): - super(InterfaceMgr, self).__init__( - daemon, - directory, - [], - "CONFIG_DB", - interface_table + base_template = "bgpd/templates/" + self.constants["bgp"]["peers"][peer_type]["template_dir"] + "/" + self.templates = { + "add": self.fabric.from_file(base_template + "instance.conf.j2"), + "delete": self.fabric.from_string('no neighbor {{ neighbor_addr }}'), + "shutdown": self.fabric.from_string('neighbor {{ neighbor_addr }} shutdown'), + "no shutdown": self.fabric.from_string('no neighbor {{ neighbor_addr }} shutdown'), + } + + deps = [ + ("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"), + ("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME, "Loopback0"), + ("LOCAL", "local_addresses", ""), + ("LOCAL", "interfaces", ""), + ] + + self.check_neig_meta = 'bgp' in self.constants \ + and 'use_neighbors_meta' in self.constants['bgp'] \ + and self.constants['bgp']['use_neighbors_meta'] + self.check_deployment_id = 'bgp' in self.constants \ + and 'use_deployment_id' in self.constants['bgp'] \ + and self.constants['bgp']['use_deployment_id'] + + if self.check_neig_meta: + deps.append(("CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME, "")) + + if self.check_deployment_id: + deps.append(("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/deployment_id")) + + super(BGPPeerMgrBase, self).__init__( + common_objs, + deps, + db_name, + table_name, ) + self.peers = self.load_peers() + self.peer_group_mgr = BGPPeerGroupMgr(self.common_objs, base_template) + return + def set_handler(self, key, data): - # Interface table can have two keys, - # one with ip prefix and one without ip prefix - if '|' in key: - data = {} - data["interface"], network = key.split('|', 1) - try: - network = netaddr.IPNetwork(str(network)) - except: - syslog.syslog( - syslog.LOG_WARNING, - 'Subnet {} format is wrong for interface {}'.format( - network, - data["interface"] - ) - ) + """ + It runs on 'SET' command + :param key: key of the changed table + :param data: the data associated with the change + """ + vrf, nbr = self.split_key(key) + if key not in self.peers: + return self.add_peer(vrf, nbr, data) + else: + return self.update_peer(vrf, nbr, data) + + def add_peer(self, vrf, nbr, data): + """ + Add a peer into FRR. This is used if the peer is not existed in FRR yet + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + print_data = vrf, nbr, data + bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + # + lo0_ipv4 = self.get_lo0_ipv4() + if lo0_ipv4 is None: + log_warn("Loopback0 ipv4 address is not presented yet") + return False + # + if "local_addr" not in data: + log_warn("Peer %s. Missing attribute 'local_addr'" % nbr) + else: + # The bgp session that belongs to a vnet cannot be advertised as the default BGP session. + # So we need to check whether this bgp session belongs to a vnet. + interface = self.get_local_interface(data["local_addr"]) + if not interface: + print_data = nbr, data["local_addr"] + log_debug("Peer '%s' with local address '%s' wait for the corresponding interface to be set" % print_data) return False - data["prefixlen"] = str(network.prefixlen) - ip = str(network.ip) - self.directory.put("local_addresses", ip, data) + vnet = self.get_vnet(interface) + if vnet: + # Ignore the bgp session that is in a vnet + log_info("Ignore the BGP peer '%s' as the interface '%s' is in vnet '%s'" % (nbr, interface, vnet)) + return True + + kwargs = { + 'CONFIG_DB__DEVICE_METADATA': self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME), + 'constants': self.constants, + 'bgp_asn': bgp_asn, + 'vrf': vrf, + 'neighbor_addr': nbr, + 'bgp_session': data, + 'loopback0_ipv4': lo0_ipv4, + } + if self.check_neig_meta: + neigmeta = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME) + if 'name' in data and data["name"] not in neigmeta: + log_info("DEVICE_NEIGHBOR_METADATA is not ready for neighbor '%s' - '%s'" % (nbr, data['name'])) + return False + kwargs['CONFIG_DB__DEVICE_NEIGHBOR_METADATA'] = neigmeta + + tag = data['name'] if 'name' in data else nbr + self.peer_group_mgr.update(tag, **kwargs) + + try: + cmd = self.templates["add"].render(**kwargs) + except jinja2.TemplateError as e: + msg = "Peer '(%s|%s)'. Error in rendering the template for 'SET' command '%s'" % print_data + log_err("%s: %s" % (msg, str(e))) + return True + if cmd is not None: + ret_code = self.apply_op(cmd, vrf) + key = (vrf, nbr) + if ret_code: + self.peers.add(key) + log_info("Peer '(%s|%s)' added with attributes '%s'" % print_data) + else: + log_err("Peer '(%s|%s)' wasn't added." % (vrf, nbr)) + + return True + + def update_peer(self, vrf, nbr, data): + """ + Update a peer. This is used when the peer is already in the FRR + Update support only "admin_status" for now + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + if "admin_status" in data: + self.change_admin_status(vrf, nbr, data) else: - self.directory.put("interfaces", key, data) + log_err("Peer '(%s|%s)': Can't update the peer. Only 'admin_status' attribute is supported" % (vrf, nbr)) + return True + def change_admin_status(self, vrf, nbr, data): + """ + Change admin status of a peer + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + if data['admin_status'] == 'up': + self.apply_admin_status(vrf, nbr, "no shutdown", "up") + elif data['admin_status'] == 'down': + self.apply_admin_status(vrf, nbr, "shutdown", "down") + else: + print_data = vrf, nbr, data['admin_status'] + log_err("Peer '%s|%s': Can't update the peer. It has wrong attribute value attr['admin_status'] = '%s'" % print_data) + + def apply_admin_status(self, vrf, nbr, template_name, admin_state): + """ + Render admin state template and apply the command to the FRR + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param template_name: name of the template to render + :param admin_state: desired admin state + :return: True if this adding was successful, False otherwise + """ + print_data = vrf, nbr, admin_state + ret_code = self.apply_op(self.templates[template_name].render(neighbor_addr=nbr), vrf) + if ret_code: + log_info("Peer '%s|%s' admin state is set to '%s'" % print_data) + else: + log_err("Can't set peer '%s|%s' admin state to '%s'." % print_data) + def del_handler(self, key): - if '|' in key: - interface, network = key.split('|', 1) - try: - network = netaddr.IPNetwork(str(network)) - except: - syslog.syslog( - syslog.LOG_WARNING, - 'Subnet {} format is wrong for interface {}'.format( - network, - interface - ) - ) - return False - ip = str(network.ip) - self.directory.remove("local_addresses", ip) + """ + 'DEL' handler for the BGP PEER tables + :param key: key of the neighbor + """ + vrf, nbr = self.split_key(key) + if key not in self.peers: + log_warn("Peer '(%s|%s)' has not been found" % (vrf, nbr)) + return + cmd = self.templates["delete"].render(neighbor_addr=nbr) + ret_code = self.apply_op(cmd, vrf) + if ret_code: + log_info("Peer '(%s|%s)' has been removed" % (vrf, nbr)) + self.peers.remove(key) else: - self.directory.remove("interfaces", key) + log_err("Peer '(%s|%s)' hasn't been removed" % (vrf, nbr)) - @staticmethod - def get_local_interface(directory, local_addr): + def apply_op(self, cmd, vrf): + """ + Push commands cmd into FRR + :param cmd: commands in raw format + :param vrf: vrf where the commands should be applied + :return: True if no errors, False if there are errors + """ + bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + if vrf == 'default': + cmd = ('router bgp %s\n' % bgp_asn) + cmd + else: + cmd = ('router bgp %s vrf %s\n' % (bgp_asn, vrf)) + cmd + return self.cfg_mgr.push(cmd) + + def get_lo0_ipv4(self): """ - @summary: Get interface according to the local address from the directory - @param directory: Directory object that stored metadata of interfaces - @param local_addr: Local address of the interface - @return: Return the metadata of the interface with the local address + Extract Loopback0 ipv4 address from the Directory + :return: ipv4 address for Loopback0, None if nothing found + """ + loopback0_ipv4 = None + for loopback in self.directory.get_slot("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME).iterkeys(): + if loopback.startswith("Loopback0|"): + loopback0_prefix_str = loopback.replace("Loopback0|", "") + loopback0_ip_str = loopback0_prefix_str[:loopback0_prefix_str.find('/')] + if TemplateFabric.is_ipv4(loopback0_ip_str): + loopback0_ipv4 = loopback0_ip_str + break + + return loopback0_ipv4 + + def get_local_interface(self, local_addr): + """ + Get interface according to the local address from the directory + :param: directory: Directory object that stored metadata of interfaces + :param: local_addr: Local address of the interface + :return: Return the metadata of the interface with the local address If the interface has not been set, return None """ - local_addresses = directory.get_slot("local_addresses") + local_addresses = self.directory.get_slot("LOCAL", "local_addresses") # Check if the local address of this bgp session has been set if local_addr not in local_addresses: return None local_address = local_addresses[local_addr] - interfaces = directory.get_slot("interfaces") + interfaces = self.directory.get_slot("LOCAL", "interfaces") # Check if the information for the interface of this local address has been set if local_address.has_key("interface") and local_address["interface"] in interfaces: return interfaces[local_address["interface"]] @@ -503,9 +935,9 @@ class InterfaceMgr(Manager): @staticmethod def get_vnet(interface): """ - @summary: Get the VNet name of the interface - @param interface: The metadata of the interface - @return: Return the vnet name of the interface if this interface belongs to a vnet, + Get the VNet name of the interface + :param: interface: The metadata of the interface + :return: Return the vnet name of the interface if this interface belongs to a vnet, Otherwise return None """ if interface.has_key("vnet_name") and interface["vnet_name"]: @@ -513,65 +945,166 @@ class InterfaceMgr(Manager): else: return None + @staticmethod + def split_key(key): + """ + Split key into ip address and vrf name. If there is no vrf, "default" would be return for vrf + :param key: key to split + :return: vrf name extracted from the key, peer ip address extracted from the key + """ + if '|' not in key: + return 'default', key + else: + return tuple(key.split('|', 1)) -class LoopbackInterfaceMgr(InterfaceMgr): - def __init__(self, daemon, directory): - super(LoopbackInterfaceMgr, self).__init__( - daemon, - directory, - swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME - ) - + @staticmethod + def load_peers(): + """ + Load peers from FRR. + :return: set of peers, which are already installed in FRR + """ + command = ["vtysh", "-c", "show bgp vrfs json"] + ret_code, out, err = run_command(command) + if ret_code == 0: + js_vrf = json.loads(out) + vrfs = js_vrf['vrfs'].keys() + else: + log_crit("Can't read bgp vrfs: %s" % err) + raise Exception("Can't read bgp vrfs: %s" % err) + peers = set() + for vrf in vrfs: + command = ["vtysh", "-c", 'show bgp vrf %s neighbors json' % str(vrf)] + ret_code, out, err = run_command(command) + if ret_code == 0: + js_bgp = json.loads(out) + for nbr in js_bgp.keys(): + peers.add((vrf, nbr)) + else: + log_crit("Can't read vrf '%s' neighbors: %s" % (vrf, str(err))) + raise Exception("Can't read vrf '%s' neighbors: %s" % (vrf, str(err))) -class VlanInterfaceMgr(InterfaceMgr): - def __init__(self, daemon, directory): - super(VlanInterfaceMgr, self).__init__( - daemon, - directory, - swsscommon.CFG_VLAN_INTF_TABLE_NAME - ) + return peers -class PortChannelInterfaceMgr(InterfaceMgr): - def __init__(self, daemon, directory): - super(PortChannelInterfaceMgr, self).__init__( - daemon, - directory, - swsscommon.CFG_LAG_INTF_TABLE_NAME +class ZebraSetSrc(Manager): + """ This class initialize "set src" settings for zebra """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(ZebraSetSrc, self).__init__( + common_objs, + [], + db, + table, ) + tf = common_objs['tf'] + self.zebra_set_src_template = tf.from_file("zebra/zebra.set_src.conf.j2") + self.lo_ipv4 = None + self.lo_ipv6 = None + def set_handler(self, key, data): + """ Implementation of 'SET' command for this class """ + self.directory.put(self.db_name, self.table_name, key, data) + # + if key.startswith("Loopback0|") and "state" in data and data["state"] == "ok": + ip_addr_w_mask = key.replace("Loopback0|", "") + slash_pos = ip_addr_w_mask.rfind("/") + if slash_pos == -1: + log_err("Wrong Loopback0 ip address: '%s'" % ip_addr_w_mask) + return True + ip_addr = ip_addr_w_mask[:slash_pos] + try: + if TemplateFabric.is_ipv4(ip_addr) and self.lo_ipv4 is None: + self.lo_ipv4 = ip_addr + txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC", lo_ip=ip_addr, ip_proto="") + elif TemplateFabric.is_ipv6(ip_addr) and self.lo_ipv6 is None: + self.lo_ipv6 = ip_addr + txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC6", lo_ip=ip_addr, ip_proto="v6") + else: + log_err("Got ambiguous ip address '%s'" % ip_addr) + return True + except jinja2.TemplateError as e: + log_err("Error while rendering 'set src' template: %s" % str(e)) + return True + if self.cfg_mgr.push(txt): + log_info("The 'set src' configuration with Loopback0 ip '%s' was pushed" % ip_addr) + else: + log_err("The 'set src' configuration with Loopback0 ip '%s' wasn't pushed" % ip_addr) + return True -def wait_for_bgpd(): - # wait for 20 seconds - stop_time = datetime.datetime.now() + datetime.timedelta(seconds=20) - syslog.syslog(syslog.LOG_INFO, "Start waiting for bgpd: %s" % str(datetime.datetime.now())) + def del_handler(self, key): + """ Implementation of 'DEL' command for this class """ + self.directory.remove(self.db_name, self.table_name, key) + log_warn("Delete command is not supported for 'zebra set src' templates") + + +def wait_for_daemons(daemons, seconds): + """ + Wait until FRR daemons are ready for requests + :param daemons: list of FRR daemons to wait + :param seconds: number of seconds to wait, until raise an error + """ + stop_time = datetime.datetime.now() + datetime.timedelta(seconds=seconds) + log_info("Start waiting for FRR daemons: %s" % str(datetime.datetime.now())) while datetime.datetime.now() < stop_time: - rc, out, err = run_command(["vtysh", "-c", "show daemons"]) - if rc == 0 and "bgpd" in out: - syslog.syslog(syslog.LOG_INFO, "bgpd connected to vtysh: %s" % str(datetime.datetime.now())) + ret_code, out, err = run_command(["vtysh", "-c", "show daemons"], hide_errors=True) + if ret_code == 0 and all(daemon in out for daemon in daemons): + log_info("All required daemons have connected to vtysh: %s" % str(datetime.datetime.now())) return - time.sleep(0.1) # sleep 100 ms - raise RuntimeError("bgpd hasn't been started in 20 seconds") + else: + log_warn("Can't read daemon status from FRR: %s" % str(err)) + time.sleep(0.1) # sleep 100 ms + raise RuntimeError("FRR daemons hasn't been started in %d seconds" % seconds) + + +def read_constants(): + """ Read file with constants values from /etc/sonic/constants.yml """ + with open('/etc/sonic/constants.yml') as fp: + content = yaml.load(fp) + if "constants" not in content: + log_crit("/etc/sonic/constants.yml doesn't have 'constants' key") + raise Exception("/etc/sonic/constants.yml doesn't have 'constants' key") + return content["constants"] def main(): + """ Main function """ + wait_for_daemons(["bgpd", "zebra", "staticd"], seconds=20) + # + common_objs = { + 'directory': Directory(), + 'cfg_mgr': ConfigMgr(), + 'tf': TemplateFabric(), + 'constants': read_constants(), + } managers = [ - BGPDeviceMetaMgr, - BGPNeighborMetaMgr, - BGPPeerMgr, - InterfaceMgr, - LoopbackInterfaceMgr, - VlanInterfaceMgr, - PortChannelInterfaceMgr, + # Config DB managers + BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME), + BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME), + # Interface managers + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_INTF_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VLAN_INTF_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LAG_INTF_TABLE_NAME), + # State DB managers + ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME), + # Peer Managers + BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general"), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors"), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic"), ] - wait_for_bgpd() - daemon = Daemon() - directory = Directory() - manager_instanses = [ manager(daemon, directory) for manager in managers ] - daemon.run() + runner = Runner() + for mgr in managers: + runner.add_manager(mgr) + runner.run() -def signal_handler(signum, frame): +def signal_handler(_, __): # signal_handler(signum, frame) + """ signal handler """ global g_run g_run = False @@ -584,13 +1117,17 @@ if __name__ == '__main__': signal.signal(signal.SIGINT, signal_handler) main() except KeyboardInterrupt: - syslog.syslog(syslog.LOG_NOTICE, "Keyboard interrupt") - except RuntimeError as e: - syslog.syslog(syslog.LOG_CRIT, "%s" % str(e)) + log_notice("Keyboard interrupt") + except RuntimeError as exc: + log_crit(str(exc)) rc = -2 - except Exception as e: - syslog.syslog(syslog.LOG_CRIT, "Got an exception %s: Traceback: %s" % (str(e), traceback.format_exc())) + if g_debug: + raise + except Exception as exc: + log_crit("Got an exception %s: Traceback: %s" % (str(exc), traceback.format_exc())) rc = -1 + if g_debug: + raise finally: syslog.closelog() try: diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 deleted file mode 100644 index 2bf80b80a787..000000000000 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ /dev/null @@ -1,180 +0,0 @@ -! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} -{% block bgp_init %} -! -! bgp multiple-instance -! -route-map FROM_BGP_SPEAKER_V4 permit 10 -! -route-map TO_BGP_SPEAKER_V4 deny 10 -! -{# generate loopback prefix-lists #} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} -ip prefix-list PL_LoopbackV4 permit {{ prefix | ip }}/32 -{% elif prefix | ipv6 and name == 'Loopback0' %} -ipv6 prefix-list PL_LoopbackV6 permit {{ prefix | replace('/128', '/64') | ip_network }}/64 -{% endif %} -{% endfor %} -! -{# generate default peer route-maps #} -! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} -route-map HIDE_INTERNAL permit 10 - set community local-AS -! -{% endif %} -{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} -route-map OVERRIDE_ORIGINATOR_ID permit 10 -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - set originator-id {{ prefix | ip }} -{% endif %} -{% endfor %} -! -{% endif %} -{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} -route-map FROM_BGPMON deny 10 -! -route-map TO_BGPMON permit 10 -! -{% endif %} -! -route-map ISOLATE permit 10 - set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }} -! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global -! -router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} -{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} - redistribute connected route-map HIDE_INTERNAL -{% endif %} - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - bgp graceful-restart restart-time 240 - bgp graceful-restart -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - bgp graceful-restart preserve-fw-state -{% endif %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - bgp router-id {{ prefix | ip }} -{% endif %} -{% endfor %} -{# advertise loopback #} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - network {{ prefix | ip }}/32 -{% elif prefix | ipv6 and name == 'Loopback0' %} - address-family ipv6 - network {{ prefix | ip }}/64 - exit-address-family -{% endif %} -{% endfor %} -{% endblock bgp_init %} -{% endif %} -{% block vlan_advertisement %} -{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} -{% if prefix | ipv4 %} - network {{ prefix }} -{% elif prefix | ipv6 %} - address-family ipv6 - network {{ prefix }} - exit-address-family -{% endif %} -{% endfor %} -{% endblock vlan_advertisement %} -{% block maximum_paths %} - address-family ipv4 - maximum-paths 64 - exit-address-family - address-family ipv6 - maximum-paths 64 - exit-address-family -{% endblock maximum_paths %} -{% block peers_peer_group %} - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor PEER_V4 allowas-in 1 -{% endif %} - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor PEER_V6 allowas-in 1 -{% endif %} - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family -{% endblock peers_peer_group %} -{% block bgp_peers_with_range %} -{% if BGP_PEER_RANGE %} -{% for bgp_peer in BGP_PEER_RANGE.values() %} - neighbor {{ bgp_peer['name'] }} peer-group - neighbor {{ bgp_peer['name'] }} passive -{% if bgp_peer['peer_asn'] is defined %} - neighbor {{ bgp_peer['name'] }} remote-as {{ bgp_peer['peer_asn'] }} -{% else %} - neighbor {{ bgp_peer['name'] }} remote-as {{ constants.deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} -{% endif %} - neighbor {{ bgp_peer['name'] }} ebgp-multihop 255 - neighbor {{ bgp_peer['name'] }} soft-reconfiguration inbound -{% if bgp_peer['src_address'] is defined %} - neighbor {{ bgp_peer['name'] }} update-source {{ bgp_peer['src_address'] | ip }} -{% else %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if name == 'Loopback1' %} - neighbor {{ bgp_peer['name'] }} update-source {{ prefix | ip }} -{% endif %} -{% endfor %} -{% endif %} - neighbor {{ bgp_peer['name'] }} route-map FROM_BGP_SPEAKER_V4 in - neighbor {{ bgp_peer['name'] }} route-map TO_BGP_SPEAKER_V4 out -{% for ip_range in bgp_peer['ip_range'] %} - bgp listen range {{ip_range}} peer-group {{ bgp_peer['name'] }} -{% endfor %} - address-family ipv4 - neighbor {{ bgp_peer['name'] }} activate - exit-address-family - address-family ipv6 - neighbor {{ bgp_peer['name'] }} activate - exit-address-family -{% endfor %} -{% endif %} -{% endblock bgp_peers_with_range %} -{% block bgp_monitors %} -{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} - neighbor BGPMON peer-group -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - neighbor BGPMON update-source {{ prefix | ip }} -{% endif %} -{% endfor %} - neighbor BGPMON route-map FROM_BGPMON in - neighbor BGPMON route-map TO_BGPMON out - neighbor BGPMON send-community - neighbor BGPMON maximum-prefix 1 -{% for neighbor_addr, bgp_session in BGP_MONITORS.items() %} - neighbor {{ neighbor_addr }} remote-as {{ DEVICE_METADATA['localhost']['bgp_asn'] }} - neighbor {{ neighbor_addr }} peer-group BGPMON - neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} - neighbor {{ neighbor_addr }} activate -{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} - neighbor {{ neighbor_addr }} route-map OVERRIDE_ORIGINATOR_ID in -{% endif %} - address-family ipv6 - neighbor {{ neighbor_addr }} activate - exit-address-family -{% endfor %} -{% endif %} -{% endblock bgp_monitors %} -! diff --git a/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 b/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 deleted file mode 100644 index 9cd61b899071..000000000000 --- a/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 +++ /dev/null @@ -1,10 +0,0 @@ -route-map TO_BGP_PEER_V4 permit 2 - match ip address prefix-list PL_LoopbackV4 - set community {{ constants.traffic_shift_community }} -route-map TO_BGP_PEER_V4 deny 3 -! -route-map TO_BGP_PEER_V6 permit 2 - match ipv6 address prefix-list PL_LoopbackV6 - set community {{ constants.traffic_shift_community }} -route-map TO_BGP_PEER_V6 deny 3 -! diff --git a/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 b/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 deleted file mode 100644 index 25d7c49125e1..000000000000 --- a/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 +++ /dev/null @@ -1,6 +0,0 @@ -no route-map TO_BGP_PEER_V4 permit 2 -no route-map TO_BGP_PEER_V4 deny 3 -! -no route-map TO_BGP_PEER_V6 permit 2 -no route-map TO_BGP_PEER_V6 deny 3 -! diff --git a/dockers/docker-fpm-frr/frr.conf.j2 b/dockers/docker-fpm-frr/frr.conf.j2 deleted file mode 100644 index afa40ad8ba75..000000000000 --- a/dockers/docker-fpm-frr/frr.conf.j2 +++ /dev/null @@ -1,18 +0,0 @@ -! -{% block banner %} -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/frr/frr.conf.j2 with config DB data -! file: frr.conf -! -{% endblock banner %} -! -{% include "daemons.common.conf.j2" %} -! -agentx -! -{% include "zebra.interfaces.conf.j2" %} -! -{% include "staticd.default_route.conf.j2" %} -! -{% include "bgpd.conf.default.j2" %} -! diff --git a/dockers/docker-fpm-frr/bgpd.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 similarity index 50% rename from dockers/docker-fpm-frr/bgpd.conf.j2 rename to dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 index b4b2cd59c9b9..85182e5430e8 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 @@ -1,4 +1,8 @@ ! +! template: bgpd/bgpd.conf.j2 +! +{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address %} +! {% block banner %} ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== ! generated by templates/quagga/bgpd.conf.j2 with config DB data @@ -6,13 +10,15 @@ ! {% endblock banner %} ! -{% include "daemons.common.conf.j2" %} +{% include "common/daemons.common.conf.j2" %} ! agentx ! {% if DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} -{% include "bgpd.conf.spine_chassis_frontend_router.j2" %} +{% include "bgpd.spine_chassis_frontend_router.conf.j2" %} {% endif %} ! -{% include "bgpd.conf.default.j2" %} +{% include "bgpd.main.conf.j2" %} +! +! end of template: bgpd/bgpd.conf.j2 ! diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 new file mode 100644 index 000000000000..4a4f06b0d0f2 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -0,0 +1,81 @@ +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 +! +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} +ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | replace('/128', '/64') | ip_network }}/64 +{% endif %} +! +! +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +{% endif %} +! +router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} +! +{% block bgp_init %} + bgp log-neighbor-changes + no bgp default ipv4-unicast +! +{% if constants.bgp.multipath_relax.enabled is defined and constants.bgp.multipath_relax.enabled %} + bgp bestpath as-path multipath-relax +{% endif %} +! +{% if constants.bgp.graceful_restart.enabled is defined and constants.bgp.graceful_restart.enabled %} + bgp graceful-restart restart-time {{ constants.bgp.graceful_restart.restart_time | default(240) }} + bgp graceful-restart + bgp graceful-restart preserve-fw-state +{% endif %} +! +{# set router-id #} + bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }} +! +{# advertise loopback #} + network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 +! +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} + address-family ipv6 + network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/64 + exit-address-family +{% endif %} +{% endblock bgp_init %} +! +{% block vlan_advertisement %} +{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} + network {{ prefix }} +{% elif prefix | ipv6 %} + address-family ipv6 + network {{ prefix }} + exit-address-family +{% endif %} +{% endfor %} +{% endblock vlan_advertisement %} +! +! +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} + redistribute connected route-map HIDE_INTERNAL +{% endif %} +! +{% if constants.bgp.maximum_paths.enabled is defined and constants.bgp.maximum_paths.enabled %} +{% block maximum_paths %} + address-family ipv4 + maximum-paths {{ constants.bgp.maximum_paths.ipv4 | default(64) }} + exit-address-family + address-family ipv6 + maximum-paths {{ constants.bgp.maximum_paths.ipv6 | default(64) }} + exit-address-family +{% endblock maximum_paths %} +{% endif %} +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 similarity index 100% rename from dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 rename to dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 new file mode 100644 index 000000000000..efb1546dac4b --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 @@ -0,0 +1,38 @@ +! +! template: bgpd/templates/dynamic/instance.conf.j2 +! +{% from "common/functions.conf.j2" import get_ipv4_loopback_address %} +! + neighbor {{ bgp_session['name'] }} peer-group + neighbor {{ bgp_session['name'] }} passive + neighbor {{ bgp_session['name'] }} ebgp-multihop 255 + neighbor {{ bgp_session['name'] }} soft-reconfiguration inbound + neighbor {{ bgp_session['name'] }} route-map FROM_BGP_SPEAKER in + neighbor {{ bgp_session['name'] }} route-map TO_BGP_SPEAKER out +! +{% if bgp_session['peer_asn'] is defined %} + neighbor {{ bgp_session['name'] }} remote-as {{ bgp_session['peer_asn'] }} +{% else %} + neighbor {{ bgp_session['name'] }} remote-as {{ constants.deployment_id_asn_map[CONFIG_DB__DEVICE_METADATA['localhost']['deployment_id']] }} +{% endif %} +! +{# FIXME: bgp_session['ip_range'] check the type #} +{% for ip_range in bgp_session['ip_range'].split(',') %} + bgp listen range {{ ip_range }} peer-group {{ bgp_session['name'] }} +{% endfor %} +! +{% if bgp_session['src_address'] is defined %} + neighbor {{ bgp_session['name'] }} update-source {{ bgp_session['src_address'] | ip }} +{% else %} + neighbor {{ bgp_session['name'] }} update-source {{ get_ipv4_loopback_address(CONFIG_DB__LOOPBACK_INTERFACE, "Loopback1") | ip }} +{% endif %} +! + address-family ipv4 + neighbor {{ bgp_session['name'] }} activate + exit-address-family + address-family ipv6 + neighbor {{ bgp_session['name'] }} activate + exit-address-family +! +! end of template: bgpd/templates/BGP_SPEAKER/instance.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/peer-group.conf.j2 new file mode 100644 index 000000000000..86d5c0297227 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/peer-group.conf.j2 @@ -0,0 +1,7 @@ +! +! template: bgpd/templates/BGP_SPEAKER/peer-group.conf.j2 +! +! nothing is here +! +! end of template: bgpd/templates/BGP_SPEAKER/peer-group.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/policies.conf.j2 new file mode 100644 index 000000000000..17ca09ec2a36 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/policies.conf.j2 @@ -0,0 +1,9 @@ +! +! template: bgpd/templates/BGP_SPEAKER/policies.conf.j2 +! +route-map FROM_BGP_SPEAKER permit 10 +! +route-map TO_BGP_SPEAKER deny 1 +! +! end of template: bgpd/templates/BGP_SPEAKER/policies.conf.j2 +! diff --git a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 old mode 100755 new mode 100644 similarity index 64% rename from dockers/docker-fpm-frr/bgpd.peer.conf.j2 rename to dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 index bcc520f6b2df..7abeabba0a77 --- a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 @@ -1,4 +1,6 @@ -{% block bgp_peer %} +! +! template: bgpd/templates/general/instance.conf.j2 +! neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} {# set the bgp neighbor timers if they have not default values #} @@ -6,27 +8,34 @@ or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} {% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} +! +{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and CONFIG_DB__DEVICE_METADATA['localhost'].has_key('default_bgp_status') and CONFIG_DB__DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} neighbor {{ neighbor_addr }} shutdown {% endif %} +! {% if neighbor_addr | ipv4 %} address-family ipv4 neighbor {{ neighbor_addr }} peer-group PEER_V4 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} + neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V4_INT in +{% endif %} {% elif neighbor_addr | ipv6 %} address-family ipv6 -{% if bgp_session['asn'] != DEVICE_METADATA['localhost']['bgp_asn'] %} - neighbor {{ neighbor_addr }} route-map set-next-hop-global-v6 in -{% endif %} neighbor {{ neighbor_addr }} peer-group PEER_V6 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} + neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V6_INT in +{% endif %} {% endif %} +! {% if bgp_session['rrclient'] | int != 0 %} neighbor {{ neighbor_addr }} route-reflector-client {% endif %} +! {% if bgp_session['nhopself'] | int != 0 %} neighbor {{ neighbor_addr }} next-hop-self {% endif %} -{% if bgp_session["asn"] == DEVICE_METADATA['localhost']['bgp_asn'] - and DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} +! +{% if bgp_session["asn"] == bgp_asn and CONFIG_DB__DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} address-family l2vpn evpn neighbor {{ neighbor_addr }} activate advertise-all-vni @@ -34,4 +43,6 @@ {% endif %} neighbor {{ neighbor_addr }} activate exit-address-family -{% endblock bgp_peer %} +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 new file mode 100644 index 000000000000..551274902de8 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -0,0 +1,24 @@ +! +! template: bgpd/templates/general/peer-group.conf.j2 +! + neighbor PEER_V4 peer-group + neighbor PEER_V6 peer-group + address-family ipv4 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor PEER_V4 allowas-in 1 +{% endif %} + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out + exit-address-family + address-family ipv6 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor PEER_V6 allowas-in 1 +{% endif %} + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/general/peer-group.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 new file mode 100644 index 000000000000..0c7b17c207bc --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -0,0 +1,30 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +! +! +route-map FROM_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V4 permit 100 +! +! +route-map FROM_BGP_PEER_V6 permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} +route-map FROM_BGP_PEER_V4_INT permit 2 + set originator-id {{ loopback0_ipv4 | ip }} +! +route-map FROM_BGP_PEER_V6_INT permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6_INT permit 2 + set originator-id {{ loopback0_ipv4 | ip }} +{% endif %} +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/instance.conf.j2 new file mode 100644 index 000000000000..0aa22a3a7f87 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/instance.conf.j2 @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/monitors/instance.conf.j2 +! + neighbor {{ neighbor_addr }} remote-as {{ bgp_asn }} + neighbor {{ neighbor_addr }} peer-group BGPMON + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} + neighbor {{ neighbor_addr }} activate + address-family ipv6 + neighbor {{ neighbor_addr }} activate + exit-address-family +! +! end of template: bgpd/templates/BGPMON/instance.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/peer-group.conf.j2 new file mode 100644 index 000000000000..a36278619015 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/peer-group.conf.j2 @@ -0,0 +1,12 @@ +! +! template: bgpd/templates/BGPMON/peer-group.conf.j2 +! + neighbor BGPMON peer-group + neighbor BGPMON update-source {{ loopback0_ipv4 | ip }} + neighbor BGPMON route-map FROM_BGPMON in + neighbor BGPMON route-map TO_BGPMON out + neighbor BGPMON send-community + neighbor BGPMON maximum-prefix 1 +! +! end of template: bgpd/templates/BGPMON/peer-group.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/policies.conf.j2 new file mode 100644 index 000000000000..8d53991064de --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/policies.conf.j2 @@ -0,0 +1,9 @@ +! +! template: bgpd/templates/BGPMON/policies.conf.j2 +! +route-map FROM_BGPMON deny 10 +! +route-map TO_BGPMON permit 10 +! +! end of template: bgpd/templates/BGPMON/policies.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 new file mode 100644 index 000000000000..88b1c5acb2eb --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 @@ -0,0 +1,5 @@ +route-map {{ route_map_name }} permit 2 + match ip address prefix-list PL_Loopback{{ ip_version }} + set community {{ constants.bgp.traffic_shift_community }} +route-map {{ route_map_name }} deny 3 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 new file mode 100644 index 000000000000..22244b3ac883 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 @@ -0,0 +1,3 @@ +no route-map {{ route_map_name }} permit 2 +no route-map {{ route_map_name }} deny 3 +! diff --git a/dockers/docker-fpm-frr/daemons.common.conf.j2 b/dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 similarity index 71% rename from dockers/docker-fpm-frr/daemons.common.conf.j2 rename to dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 index 23eb5184f5e0..1c3efdfa72fb 100644 --- a/dockers/docker-fpm-frr/daemons.common.conf.j2 +++ b/dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 @@ -1,3 +1,4 @@ +! template: common/daemons.common.conf.j2 ! {% block sys_init %} hostname {{ DEVICE_METADATA['localhost']['hostname'] }} @@ -10,3 +11,4 @@ log syslog informational log facility local4 {% endblock logging %} ! +! end of template: common/daemons.common.conf.j2 diff --git a/dockers/docker-fpm-frr/frr/common/functions.conf.j2 b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 new file mode 100644 index 000000000000..9857f068fe93 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 @@ -0,0 +1,23 @@ +{% macro get_ipv4_loopback_address(interfaces, loopbackname) -%} +{% set L = namespace(ip=None) %} +{% for name, prefix in interfaces|pfx_filter %} +{% if name == loopbackname %} +{% if prefix | ipv4 %} +{% set L.ip = prefix %} +{% endif %} +{% endif %} +{% endfor %} +{{ L.ip }} +{%- endmacro %} + +{% macro get_ipv6_loopback_address(interfaces, loopbackname) -%} +{% set L = namespace(ip=None) %} +{% for name, prefix in interfaces|pfx_filter %} +{% if name == loopbackname %} +{% if prefix | ipv6 %} +{% set L.ip = prefix %} +{% endif %} +{% endif %} +{% endfor %} +{{ L.ip }} +{%- endmacro %} diff --git a/dockers/docker-fpm-frr/frr/frr.conf.j2 b/dockers/docker-fpm-frr/frr/frr.conf.j2 new file mode 100644 index 000000000000..9e5def4ba013 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/frr.conf.j2 @@ -0,0 +1,19 @@ +! +{% block banner %} +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr.conf.j2 with config DB data +! file: frr.conf +! +{% endblock banner %} +! +{% include "common/daemons.common.conf.j2" %} +{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address %} +! +agentx +! +{% include "zebra/zebra.interfaces.conf.j2" %} +! +{% include "staticd/staticd.default_route.conf.j2" %} +! +{% include "bgpd/bgpd.main.conf.j2" %} +! diff --git a/dockers/docker-fpm-frr/isolate.j2 b/dockers/docker-fpm-frr/frr/isolate.j2 similarity index 100% rename from dockers/docker-fpm-frr/isolate.j2 rename to dockers/docker-fpm-frr/frr/isolate.j2 diff --git a/dockers/docker-fpm-frr/staticd.conf.j2 b/dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 similarity index 85% rename from dockers/docker-fpm-frr/staticd.conf.j2 rename to dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 index 4e39e17d7dbf..932871dfce4b 100644 --- a/dockers/docker-fpm-frr/staticd.conf.j2 +++ b/dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 @@ -6,7 +6,7 @@ ! {% endblock banner %} ! -{% include "daemons.common.conf.j2" %} +{% include "common/daemons.common.conf.j2" %} ! {% include "staticd.default_route.conf.j2" %} ! diff --git a/dockers/docker-fpm-frr/staticd.default_route.conf.j2 b/dockers/docker-fpm-frr/frr/staticd/staticd.default_route.conf.j2 similarity index 100% rename from dockers/docker-fpm-frr/staticd.default_route.conf.j2 rename to dockers/docker-fpm-frr/frr/staticd/staticd.default_route.conf.j2 diff --git a/dockers/docker-fpm-frr/unisolate.j2 b/dockers/docker-fpm-frr/frr/unisolate.j2 similarity index 100% rename from dockers/docker-fpm-frr/unisolate.j2 rename to dockers/docker-fpm-frr/frr/unisolate.j2 diff --git a/dockers/docker-fpm-frr/zebra.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 similarity index 63% rename from dockers/docker-fpm-frr/zebra.conf.j2 rename to dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 index 8c1c6f96484b..51d998e90d36 100644 --- a/dockers/docker-fpm-frr/zebra.conf.j2 +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 @@ -1,12 +1,12 @@ ! {% block banner %} ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! {% endblock banner %} ! -{% include "daemons.common.conf.j2" %} +{% include "common/daemons.common.conf.j2" %} ! {% include "zebra.interfaces.conf.j2" %} ! diff --git a/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 new file mode 100644 index 000000000000..484efeba5850 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 @@ -0,0 +1,25 @@ +! +{% block vrf %} +{% if VNET is defined %} +{% for vnet_name, vnet_metadata in VNET.iteritems() %} +vrf {{ vnet_name }} +vni {{ vnet_metadata['vni'] }} +! +{% endfor %} +{% endif %} +{% endblock vrf %} +! +{% block interfaces %} +! Enable link-detect (default disabled) +{% for (name, prefix) in INTERFACE|pfx_filter %} +interface {{ name }} +link-detect +! +{% endfor %} +{% for pc in PORTCHANNEL %} +interface {{ pc }} +link-detect +! +{% endfor %} +{% endblock interfaces %} +! diff --git a/dockers/docker-fpm-frr/frr/zebra/zebra.set_src.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.set_src.conf.j2 new file mode 100644 index 000000000000..4dce3250ed1b --- /dev/null +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.set_src.conf.j2 @@ -0,0 +1,8 @@ +! +! Set ip source to loopback for bgp learned routes +! +route-map {{ rm_name }} permit 10 + set src {{ lo_ip }} +! +ip{{ ip_proto }} protocol bgp route-map {{ rm_name }} +! diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/start.sh index b3cef5e63244..aa72b36e5ce3 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/start.sh @@ -5,9 +5,9 @@ mkdir -p /etc/frr CONFIG_TYPE=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["docker_routing_config_mode"]'` if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then - sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/frr/bgpd.conf - sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/frr/zebra.conf - sonic-cfggen -d -t /usr/share/sonic/templates/staticd.conf.j2 > /etc/frr/staticd.conf + sonic-cfggen -d -t /usr/share/sonic/templates/bgpd/bgpd.conf.j2 -y /etc/sonic/constants.yml > /etc/frr/bgpd.conf + sonic-cfggen -d -t /usr/share/sonic/templates/zebra/zebra.conf.j2 > /etc/frr/zebra.conf + sonic-cfggen -d -t /usr/share/sonic/templates/staticd/staticd.conf.j2 > /etc/frr/staticd.conf echo "no service integrated-vtysh-config" > /etc/frr/vtysh.conf rm -f /etc/frr/frr.conf elif [ "$CONFIG_TYPE" == "unified" ]; then diff --git a/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 deleted file mode 100644 index 4a089e4dc726..000000000000 --- a/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 +++ /dev/null @@ -1,60 +0,0 @@ -! -{% block vrf %} -{% if VNET is defined %} -{% for vnet_name, vnet_metadata in VNET.iteritems() %} -vrf {{ vnet_name }} -vni {{ vnet_metadata['vni'] }} -! -{% endfor %} -{% endif %} -{% endblock vrf %} -! -{% block interfaces %} -! Enable link-detect (default disabled) -{% for (name, prefix) in INTERFACE|pfx_filter %} -interface {{ name }} -link-detect -! -{% endfor %} -{% for pc in PORTCHANNEL %} -interface {{ pc }} -link-detect -! -{% endfor %} -{% endblock interfaces %} -! -{% block source_loopback %} -{% set lo_ipv4_addrs = [] %} -{% set lo_ipv6_addrs = [] %} -{% if LOOPBACK_INTERFACE %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if name == 'Loopback0' %} -{% if prefix | ipv6 %} -{% if lo_ipv6_addrs.append(prefix) %} -{% endif %} -{% else %} -{% if lo_ipv4_addrs.append(prefix) %} -{% endif %} -{% endif %} -{% endif %} -{% endfor %} -{% endif %} -! Set ip source to loopback for bgp learned routes -{% if lo_ipv4_addrs|length > 0 -%} -route-map RM_SET_SRC permit 10 - set src {{ lo_ipv4_addrs[0] | ip }} -! -{% endif %} -{% if lo_ipv6_addrs|length > 0 %} -route-map RM_SET_SRC6 permit 10 - set src {{ lo_ipv6_addrs[0] | ip }} -! -{% endif %} -ip protocol bgp route-map RM_SET_SRC -! -{% if lo_ipv6_addrs|length > 0 %} -ipv6 protocol bgp route-map RM_SET_SRC6 -! -{% endif %} -{% endblock source_loopback %} -! diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 3834717a8bfc..3e1b76be0157 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -1,4 +1,34 @@ constants: deployment_id_asn_map: "1" : 65432 - traffic_shift_community: 12345:12345 + "2" : 65433 + bgp: + traffic_shift_community: 12345:12345 + families: + - ipv4 + - ipv6 + use_deployment_id: false + use_neighbors_meta: false + graceful_restart: + enabled: true + restart_time: 240 + multipath_relax: + enabled: true + maximum_paths: + enabled: true + ipv4: 64 + ipv6: 64 + peers: + general: # peer_type + db_table: "BGP_NEIGHBOR" + template_dir: "general" + monitors: # peer_type + enabled: true + db_table: "BGP_MONITORS" + peer_group: "BGPMON" + template_dir: "monitors" + dynamic: # peer_type + enabled: true + db_table: "BGP_PEER_RANGE" + peer_group: "BGP_SPEAKER" + template_dir: "dynamic" diff --git a/src/sonic-config-engine/.gitignore b/src/sonic-config-engine/.gitignore new file mode 100644 index 000000000000..e41d5b085e5b --- /dev/null +++ b/src/sonic-config-engine/.gitignore @@ -0,0 +1,2 @@ +dist/ +tests/output diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index dddfde32428b..1a94a47c0f9c 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -204,6 +204,7 @@ def main(): parser.add_argument("-s", "--redis-unix-sock-file", help="unix sock file for redis connection") group = parser.add_mutually_exclusive_group() group.add_argument("-t", "--template", help="render the data with the template file") + parser.add_argument("-T", "--template_dir", help="search base for the template files", action='store') group.add_argument("-v", "--var", help="print the value of a variable, support jinja2 expression") group.add_argument("--var-json", help="print the value of a variable, in json format") group.add_argument("-w", "--write-to-db", help="write config into configdb", action='store_true') @@ -273,9 +274,12 @@ def main(): }}} deep_update(data, hardware_data) - if args.template != None: + if args.template is not None: template_file = os.path.abspath(args.template) paths = ['/', '/usr/share/sonic/templates', os.path.dirname(template_file)] + if args.template_dir is not None: + template_dir = os.path.abspath(args.template_dir) + paths.append(template_dir) loader = jinja2.FileSystemLoader(paths) redis_bcc = RedisBytecodeCache(SonicV2Connector(host='127.0.0.1')) diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf index 566d6384fcfd..1f0f97e2ff57 100644 --- a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf @@ -1,9 +1,13 @@ ! +! template: bgpd/bgpd.conf.j2 +! +! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== ! generated by templates/quagga/bgpd.conf.j2 with config DB data ! file: bgpd.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname switch-t0 password zebra @@ -11,79 +15,57 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! agentx ! ! ! +! template: bgpd/bgpd.main.conf.j2 ! ! bgp multiple-instance ! -route-map FROM_BGP_SPEAKER_V4 permit 10 +! BGP configuration ! -route-map TO_BGP_SPEAKER_V4 deny 10 +! TSA configuration ! ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 -ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 -! -! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -route-map FROM_BGPMON deny 10 -! -route-map TO_BGPMON permit 10 ! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! -route-map ISOLATE permit 10 - set as-path prepend 65100 ! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global ! router bgp 65100 +! bgp log-neighbor-changes - bgp bestpath as-path multipath-relax no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! bgp graceful-restart restart-time 240 bgp graceful-restart bgp graceful-restart preserve-fw-state +! bgp router-id 10.1.0.32 +! network 10.1.0.32/32 +! address-family ipv6 network fc00:1::32/64 exit-address-family +! network 192.168.0.1/27 +! +! +! address-family ipv4 maximum-paths 64 exit-address-family address-family ipv6 maximum-paths 64 exit-address-family - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 - neighbor PEER_V4 allowas-in 1 - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 - neighbor PEER_V6 allowas-in 1 - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family - neighbor BGPMON peer-group - neighbor BGPMON update-source 10.1.0.32 - neighbor BGPMON route-map FROM_BGPMON in - neighbor BGPMON route-map TO_BGPMON out - neighbor BGPMON send-community - neighbor BGPMON maximum-prefix 1 - neighbor 10.20.30.40 remote-as 65100 - neighbor 10.20.30.40 peer-group BGPMON - neighbor 10.20.30.40 description BGPMonitor - neighbor 10.20.30.40 activate - address-family ipv6 - neighbor 10.20.30.40 activate - exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 !! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-config-engine/tests/sample_output/frr.conf b/src/sonic-config-engine/tests/sample_output/frr.conf index 47855ce7c841..07354c6cf656 100644 --- a/src/sonic-config-engine/tests/sample_output/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/frr.conf @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/frr/frr.conf.j2 with config DB data +! generated by templates/frr.conf.j2 with config DB data ! file: frr.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname switch-t0 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! agentx ! ! @@ -29,93 +31,55 @@ link-detect interface PortChannel04 link-detect ! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 10.1.0.32 -! - -route-map RM_SET_SRC6 permit 10 - set src fc00:1::32 -! -ip protocol bgp route-map RM_SET_SRC -! -ipv6 protocol bgp route-map RM_SET_SRC6 -! !! ! ! set static default route to mgmt gateway as a backup to learned default ip route 0.0.0.0/0 10.0.0.1 200 !! ! +! template: bgpd/bgpd.main.conf.j2 ! ! bgp multiple-instance ! -route-map FROM_BGP_SPEAKER_V4 permit 10 +! BGP configuration ! -route-map TO_BGP_SPEAKER_V4 deny 10 +! TSA configuration ! ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 -ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 -! -! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -route-map FROM_BGPMON deny 10 -! -route-map TO_BGPMON permit 10 ! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! -route-map ISOLATE permit 10 - set as-path prepend 65100 ! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global ! router bgp 65100 +! bgp log-neighbor-changes - bgp bestpath as-path multipath-relax no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! bgp graceful-restart restart-time 240 bgp graceful-restart bgp graceful-restart preserve-fw-state +! bgp router-id 10.1.0.32 +! network 10.1.0.32/32 +! address-family ipv6 network fc00:1::32/64 exit-address-family +! network 192.168.0.1/27 +! +! +! address-family ipv4 maximum-paths 64 exit-address-family address-family ipv6 maximum-paths 64 exit-address-family - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 - neighbor PEER_V4 allowas-in 1 - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 - neighbor PEER_V6 allowas-in 1 - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family - neighbor BGPMON peer-group - neighbor BGPMON update-source 10.1.0.32 - neighbor BGPMON route-map FROM_BGPMON in - neighbor BGPMON route-map TO_BGPMON out - neighbor BGPMON send-community - neighbor BGPMON maximum-prefix 1 - neighbor 10.20.30.40 remote-as 65100 - neighbor 10.20.30.40 peer-group BGPMON - neighbor 10.20.30.40 description BGPMonitor - neighbor 10.20.30.40 activate - address-family ipv6 - neighbor 10.20.30.40 activate - exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 !! diff --git a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/staticd_frr.conf index 12a81de82125..31a11d8578aa 100644 --- a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/staticd_frr.conf @@ -4,6 +4,7 @@ ! file: staticd.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname switch-t0 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! ! ! set static default route to mgmt gateway as a backup to learned default ip route 0.0.0.0/0 10.0.0.1 200 diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf index b0b5e2cb1192..dd79ae3950bb 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf @@ -1,9 +1,13 @@ ! +! template: bgpd/bgpd.conf.j2 +! +! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== ! generated by templates/quagga/bgpd.conf.j2 with config DB data ! file: bgpd.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname SpineFront01 password zebra @@ -11,7 +15,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! agentx ! ! @@ -37,49 +42,46 @@ router bgp 4000 vrf VnetFE exit-address-family !! ! +! template: bgpd/bgpd.main.conf.j2 ! ! bgp multiple-instance ! -route-map FROM_BGP_SPEAKER_V4 permit 10 +! BGP configuration ! -route-map TO_BGP_SPEAKER_V4 deny 10 +! TSA configuration ! ip prefix-list PL_LoopbackV4 permit 4.0.0.0/32 ! ! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -! -route-map ISOLATE permit 10 - set as-path prepend 4000 ! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global ! router bgp 4000 +! bgp log-neighbor-changes - bgp bestpath as-path multipath-relax no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! bgp graceful-restart restart-time 240 bgp graceful-restart + bgp graceful-restart preserve-fw-state +! bgp router-id 4.0.0.0 +! network 4.0.0.0/32 +! +! +! +! +! address-family ipv4 maximum-paths 64 exit-address-family address-family ipv6 maximum-paths 64 exit-address-family - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 !! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf index bd2b5c84f471..180a0e9fab89 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname SpineFront01 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! ! vrf VnetFE vni 9000 @@ -27,11 +29,4 @@ link-detect interface Ethernet8 link-detect ! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 4.0.0.0 -! -ip protocol bgp route-map RM_SET_SRC -! !! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf index e047fcd64f29..661b27268255 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname SpineFront01 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! ! vrf VnetFE vni 8000 @@ -27,11 +29,4 @@ link-detect interface Ethernet8 link-detect ! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 4.0.0.0 -! -ip protocol bgp route-map RM_SET_SRC -! !! diff --git a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf index 690f609dafcf..e3d0c2d55bc3 100644 --- a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname switch-t0 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! ! ! ! Enable link-detect (default disabled) @@ -27,17 +29,4 @@ link-detect interface PortChannel04 link-detect ! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 10.1.0.32 -! - -route-map RM_SET_SRC6 permit 10 - set src fc00:1::32 -! -ip protocol bgp route-map RM_SET_SRC -! -ipv6 protocol bgp route-map RM_SET_SRC6 -! !! diff --git a/src/sonic-config-engine/tests/test_frr.py b/src/sonic-config-engine/tests/test_frr.py index fcbff063b13b..dd41e1711760 100644 --- a/src/sonic-config-engine/tests/test_frr.py +++ b/src/sonic-config-engine/tests/test_frr.py @@ -37,8 +37,11 @@ def run_diff(self, file1, file2): return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) def run_case(self, template, target): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', template) - cmd = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file + template_dir = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', "frr") + conf_template = os.path.join(template_dir, template) + constants = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'constants', 'constants.yml') + cmd_args = self.t0_minigraph, self.t0_port_config, constants, conf_template, template_dir, self.output_file + cmd = "-m %s -p %s -y %s -t %s -T %s > %s" % cmd_args self.run_script(cmd) original_filename = os.path.join(self.test_dir, 'sample_output', target) @@ -52,11 +55,11 @@ def test_config_frr(self): self.assertTrue(*self.run_case('frr.conf.j2', 'frr.conf')) def test_bgpd_frr(self): - self.assertTrue(*self.run_case('bgpd.conf.j2', 'bgpd_frr.conf')) + self.assertTrue(*self.run_case('bgpd/bgpd.conf.j2', 'bgpd_frr.conf')) def test_zebra_frr(self): - self.assertTrue(*self.run_case('zebra.conf.j2', 'zebra_frr.conf')) + self.assertTrue(*self.run_case('zebra/zebra.conf.j2', 'zebra_frr.conf')) def test_staticd_frr(self): - self.assertTrue(*self.run_case('staticd.conf.j2', 'staticd_frr.conf')) + self.assertTrue(*self.run_case('staticd/staticd.conf.j2', 'staticd_frr.conf')) diff --git a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py index 41ac347e2b18..a3c50b8a263d 100644 --- a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py +++ b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py @@ -30,8 +30,11 @@ def run_diff(self, file1, file2): return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) def run_case(self, minigraph, template, target): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', template) - cmd = '-m ' + minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file + template_dir = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', "frr") + conf_template = os.path.join(template_dir, template) + constants = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'constants', 'constants.yml') + cmd_args = minigraph, self.t2_chassis_fe_port_config, constants, conf_template, template_dir, self.output_file + cmd = "-m %s -p %s -y %s -t %s -T %s > %s" % cmd_args self.run_script(cmd) original_filename = os.path.join(self.test_dir, 'sample_output', target) @@ -42,13 +45,13 @@ def run_case(self, minigraph, template, target): # Test zebra.conf in FRR docker for a T2 chassis frontend (fe) def test_t2_chassis_fe_zebra_frr(self): - self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'zebra.conf.j2', 't2-chassis-fe-zebra.conf')) + self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'zebra/zebra.conf.j2', 't2-chassis-fe-zebra.conf')) # Test zebra.conf in FRR docker for a T2 chassis frontend (fe) switch with specified VNI def test_t2_chassis_fe_vni_zebra_frr(self): - self.assertTrue(*self.run_case(self.t2_chassis_fe_vni_minigraph, 'zebra.conf.j2', 't2-chassis-fe-vni-zebra.conf')) + self.assertTrue(*self.run_case(self.t2_chassis_fe_vni_minigraph, 'zebra/zebra.conf.j2', 't2-chassis-fe-vni-zebra.conf')) # Test bgpd.conf in FRR docker for a T2 chassis frontend (fe) def test_t2_chassis_frontend_bgpd_frr(self): - self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'bgpd.conf.j2', 't2-chassis-fe-bgpd.conf')) + self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'bgpd/bgpd.conf.j2', 't2-chassis-fe-bgpd.conf')) From 4adf243260b19f7a80f595a1b8aa99981f3a1e4c Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Fri, 24 Apr 2020 12:43:56 -0700 Subject: [PATCH 0582/1427] Fix docker restapi start issue, undefined error (#4475) --- dockers/docker-sonic-restapi/restapi.sh | 5 ++++- rules/docker-restapi.mk | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dockers/docker-sonic-restapi/restapi.sh b/dockers/docker-sonic-restapi/restapi.sh index 61778e3245d6..d009507a7bc3 100755 --- a/dockers/docker-sonic-restapi/restapi.sh +++ b/dockers/docker-sonic-restapi/restapi.sh @@ -3,7 +3,10 @@ RESTAPI_ARGS="" while true do - client_auth=`sonic-cfggen -d -v "RESTAPI['config']['client_auth']"` + has_client_auth=$(sonic-cfggen -d -v "1 if RESTAPI and RESTAPI['config']") + if [ "$has_client_auth" == "1" ]; then + client_auth=$(sonic-cfggen -d -v "RESTAPI['config']['client_auth']") + fi if [[ $client_auth == 'true' ]]; then certs=`sonic-cfggen -d -v "RESTAPI['certs']"` allow_insecure=`sonic-cfggen -d -v "RESTAPI['config']['allow_insecure']"` diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index 09bbd03d8fd8..b472e00491de 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -18,7 +18,6 @@ endif $(DOCKER_RESTAPI)_CONTAINER_NAME = restapi $(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t -$(DOCKER_RESTAPI)_RUN_OPT += --network="host" $(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock $(DOCKER_RESTAPI)_RUN_OPT += -v /etc/sonic/certificates:/etc/sonic/certificates:ro $(DOCKER_RESTAPI)_RUN_OPT += -p=8081:8081/tcp From c56752a5f8b6e39e1cdd8754d1db0f536109018e Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 25 Apr 2020 10:52:38 -0700 Subject: [PATCH 0583/1427] [build]: add sonic-slave-run target to run any cmds inside sonic-slave-docekr (#4481) example: ``` SONIC_RUN_CMDS="gzip -d -c target/sonic-vs.img.gz > target/sonic-vs.img;\ qemu-img convert target/sonic-vs.img -O vhdx -o subformat=dynamic target/sonic-vs.vhdx"\ BLDENV=buster make -f Makefile.work sonic-slave-run ``` Signed-off-by: Guohan Lu --- Makefile.work | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Makefile.work b/Makefile.work index 6f63652423a6..d9703000ddb6 100644 --- a/Makefile.work +++ b/Makefile.work @@ -251,6 +251,16 @@ sonic-slave-bash : $(DOCKER_BUILD) ; } @$(DOCKER_RUN) -t $(SLAVE_IMAGE):$(SLAVE_TAG) bash +sonic-slave-run : + @$(OVERLAY_MODULE_CHECK) + @docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null || \ + { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \ + $(DOCKER_BASE_BUILD) ; } + @docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null || \ + { echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \ + $(DOCKER_BUILD) ; } + @$(DOCKER_RUN) -t $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_RUN_CMDS)" + showtag: @echo $(SLAVE_IMAGE):$(SLAVE_TAG) @echo $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) From e75da77f35815947ea39c66e4c21a5077f168f51 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Sun, 26 Apr 2020 01:54:45 +0700 Subject: [PATCH 0584/1427] [device/celestica]: Fix sfp index on dx010 platform api (#4346) --- .../sonic_platform/chassis.py | 24 +++++++++++++++++-- .../sonic_platform/sfp.py | 12 +++++----- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index 7db46e55bd8c..91e3dc0bf464 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -56,8 +56,7 @@ def __init__(self): thermal = Thermal(index) self._thermal_list.append(thermal) # sfp index start from 1 - self._sfp_list.append(None) - for index in range(1, NUM_SFP+1): + for index in range(0, NUM_SFP): sfp = Sfp(index) self._sfp_list.append(sfp) for index in range(0, NUM_COMPONENT): @@ -159,3 +158,24 @@ def get_watchdog(self): self._watchdog = Watchdog() return self._watchdog + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 1. + For example, 1 for Ethernet0, 2 for Ethernet4 and so on. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + # The index will start from 1 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py index 04fb36b72b8f..330d925fd8a2 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py @@ -100,7 +100,7 @@ class Sfp(SfpBase): def __init__(self, sfp_index): # Init index self.index = sfp_index - self.port_num = self.index + self.port_num = self.index + 1 # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' @@ -593,7 +593,7 @@ def get_lpmode(self): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -710,7 +710,7 @@ def reset(self): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -823,7 +823,7 @@ def set_lpmode(self, lpmode): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -907,7 +907,7 @@ def get_presence(self): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -942,4 +942,4 @@ def get_status(self): Returns: A boolean value, True if device is operating properly, False if not """ - return self.get_presence() and self.get_transceiver_bulk_status() + return self.get_presence() and not self.get_reset_status() From ac6cfb115fe37c6f7878595995619e80045f7c7b Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Sun, 26 Apr 2020 14:39:55 +0300 Subject: [PATCH 0585/1427] [Mellanox] Add a new Mellanox platform x86_64-mlnx_msn3420 and new SKU ACS-MSN3420 (#4436) * New SKU support for MSN3420 Signed-off-by: Shlomi Bitton Conflicts: device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py * Add CPLD's * Symlink fixes and semantics * Adding new platform at end of lines --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 4 +- .../ACS-MSN3420/buffers.json.j2 | 1 + .../ACS-MSN3420/buffers_defaults_t0.j2 | 1 + .../ACS-MSN3420/buffers_defaults_t1.j2 | 1 + .../ACS-MSN3420/pg_profile_lookup.ini | 1 + .../ACS-MSN3420/port_config.ini | 61 +++ .../ACS-MSN3420/qos.json.j2 | 1 + .../ACS-MSN3420/sai.profile | 1 + .../ACS-MSN3420/sai_3420.xml | 442 ++++++++++++++++++ .../x86_64-mlnx_msn3420-r0/default_sku | 1 + .../platform_components.json | 12 + .../x86_64-mlnx_msn3420-r0/platform_reboot | 1 + .../x86_64-mlnx_msn3420-r0/platform_wait | 1 + .../x86_64-mlnx_msn3420-r0/plugins/eeprom.py | 1 + .../x86_64-mlnx_msn3420-r0/plugins/psuutil.py | 1 + .../plugins/sfplpmget.py | 1 + .../plugins/sfplpmset.py | 1 + .../plugins/sfpreset.py | 1 + .../x86_64-mlnx_msn3420-r0/plugins/sfputil.py | 1 + .../pmon_daemon_control.json | 1 + .../x86_64-mlnx_msn3420-r0/sensors.conf | 113 +++++ .../sonic_platform/chassis.py | 4 +- .../mlnx-platform-api/sonic_platform/psu.py | 4 +- .../sonic_platform/thermal.py | 18 +- 24 files changed, 667 insertions(+), 7 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t1.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/qos.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai.profile create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai_3420.xml create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/default_sku create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/platform_reboot create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/platform_wait create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/eeprom.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/psuutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmget.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmset.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfpreset.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfputil.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/pmon_daemon_control.json create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index b5f2a335b09c..9e5ca4083264 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -41,8 +41,8 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700': 0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0} -port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] +hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5} +port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1), (0, 48, 59, 60, 1)] def log_info(msg, also_print_to_console=False): syslog.openlog("sfputil") diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers.json.j2 new file mode 120000 index 000000000000..7888381852d8 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..85f0b6b6b354 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..3bb496a5103b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/pg_profile_lookup.ini new file mode 120000 index 000000000000..252ae8d4149b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/pg_profile_lookup.ini @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini new file mode 100644 index 000000000000..df63cbe39ac3 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini @@ -0,0 +1,61 @@ +# name lanes alias index +Ethernet0 0 etp1 0 +Ethernet4 4 etp2 1 +Ethernet8 8 etp3 2 +Ethernet12 12 etp4 3 +Ethernet16 16 etp5 4 +Ethernet20 20 etp6 5 +Ethernet24 24 etp7 6 +Ethernet28 28 etp8 7 +Ethernet32 32 etp9 8 +Ethernet36 36 etp10 9 +Ethernet40 40 etp11 10 +Ethernet44 44 etp12 11 +Ethernet48 48 etp13 12 +Ethernet52 52 etp14 13 +Ethernet56 56 etp15 14 +Ethernet60 60 etp16 15 +Ethernet64 64 etp17 16 +Ethernet68 68 etp18 17 +Ethernet72 72 etp19 18 +Ethernet76 76 etp20 19 +Ethernet80 80 etp21 20 +Ethernet84 84 etp22 21 +Ethernet88 88 etp23 22 +Ethernet92 92 etp24 23 +Ethernet96 96 etp25 24 +Ethernet100 100 etp26 25 +Ethernet104 104 etp27 26 +Ethernet108 108 etp28 27 +Ethernet112 112 etp29 28 +Ethernet116 116 etp30 29 +Ethernet120 120 etp31 30 +Ethernet124 124 etp32 31 +Ethernet128 128 etp33 32 +Ethernet132 132 etp34 33 +Ethernet136 136 etp35 34 +Ethernet140 140 etp36 35 +Ethernet144 144 etp37 36 +Ethernet148 148 etp38 37 +Ethernet152 152 etp39 38 +Ethernet156 156 etp40 39 +Ethernet160 160 etp41 40 +Ethernet164 164 etp42 41 +Ethernet168 168 etp43 42 +Ethernet172 172 etp44 43 +Ethernet176 176 etp45 44 +Ethernet180 180 etp46 45 +Ethernet184 184 etp47 46 +Ethernet188 188 etp48 47 +Ethernet192 192,193,194,195 etp49 48 +Ethernet196 196,197,198,199 etp50 49 +Ethernet200 200,201,202,203 etp51 50 +Ethernet204 204,205,206,207 etp52 51 +Ethernet208 208,209,210,211 etp53 52 +Ethernet212 212,213,214,215 etp54 53 +Ethernet216 216,217,218,219 etp55 54 +Ethernet220 220,221,222,223 etp56 55 +Ethernet224 224,225,226,227 etp57 56 +Ethernet228 228,229,230,231 etp58 57 +Ethernet232 232,233,234,235 etp59 58 +Ethernet236 236,237,238,239 etp60 59 diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/qos.json.j2 new file mode 120000 index 000000000000..379f542893f3 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai.profile b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai.profile new file mode 100644 index 000000000000..a30106c8674d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3420.xml diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai_3420.xml b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai_3420.xml new file mode 100644 index 000000000000..5064ee3ef81b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai_3420.xml @@ -0,0 +1,442 @@ + + + + + + 00:02:03:04:05:80 + + + 1 + + + 60 + + + + + 105 + 1 + 0 + + + 0 + + + 64 + + + 106 + 1 + 1 + 0 + 64 + + + 49 + 1 + 2 + 0 + 64 + + + 113 + 1 + 3 + 0 + 64 + + + 114 + 1 + 4 + 0 + 64 + + + 50 + 1 + 5 + 0 + 64 + + + 115 + 1 + 6 + 0 + 64 + + + 116 + 1 + 7 + 0 + 64 + + + 41 + 1 + 8 + 0 + 64 + + + 121 + 1 + 9 + 0 + 64 + + + 122 + 1 + 10 + 0 + 64 + + + 42 + 1 + 11 + 0 + 64 + + + 123 + 1 + 12 + 0 + 64 + + + 124 + 1 + 13 + 0 + 64 + + + 43 + 1 + 14 + 0 + 64 + + + 57 + 1 + 15 + 0 + 64 + + + 58 + 1 + 16 + 0 + 64 + + + 44 + 1 + 17 + 0 + 64 + + + 59 + 1 + 18 + 0 + 64 + + + 60 + 1 + 19 + 0 + 64 + + + 33 + 1 + 20 + 0 + 64 + + + 51 + 1 + 21 + 0 + 64 + + + 52 + 1 + 22 + 0 + 64 + + + 34 + 1 + 23 + 0 + 64 + + + 53 + 1 + 24 + 0 + 64 + + + 54 + 1 + 25 + 0 + 64 + + + 35 + 1 + 26 + 0 + 64 + + + 45 + 1 + 27 + 0 + 64 + + + 46 + 1 + 28 + 0 + 64 + + + 36 + 1 + 29 + 0 + 64 + + + 47 + 1 + 30 + 0 + 64 + + + 48 + 1 + 31 + 0 + 64 + + + 1 + 1 + 32 + 0 + 64 + + + 37 + 1 + 33 + 0 + 64 + + + 38 + 1 + 34 + 0 + 64 + + + 2 + 1 + 35 + 0 + 64 + + + 39 + 1 + 36 + 0 + 64 + + + 40 + 1 + 37 + 0 + 64 + + + 3 + 1 + 38 + 0 + 64 + + + 4 + 1 + 39 + 0 + 64 + + + 5 + 1 + 40 + 0 + 64 + + + 6 + 1 + 41 + 0 + 64 + + + 7 + 1 + 42 + 0 + 64 + + + 8 + 1 + 43 + 0 + 64 + + + 9 + 1 + 44 + 0 + 64 + + + 10 + 1 + 45 + 0 + 64 + + + 11 + 1 + 46 + 0 + 64 + + + 12 + 1 + 47 + 0 + 64 + + + 17 + 4 + 48 + 3 + 1536 + + + 21 + 4 + 49 + 3 + 1536 + + + 25 + 4 + 50 + 3 + 1536 + + + 29 + 4 + 51 + 3 + 1536 + + + 89 + 4 + 52 + 3 + 1536 + + + 93 + 4 + 53 + 3 + 1536 + + + 81 + 4 + 54 + 3 + 1536 + + + 85 + 4 + 55 + 3 + 1536 + + + 73 + 4 + 56 + 3 + 1536 + + + 77 + 4 + 57 + 3 + 1536 + + + 65 + 4 + 58 + 3 + 1536 + + + 69 + 4 + 59 + 3 + 1536 + + + + \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/default_sku b/device/mellanox/x86_64-mlnx_msn3420-r0/default_sku new file mode 100644 index 000000000000..a572bdce4e5e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/default_sku @@ -0,0 +1 @@ +ACS-MSN3420 t1 diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json new file mode 100644 index 000000000000..f3ea5918a09f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json @@ -0,0 +1,12 @@ +{ + "chassis": { + "x86_64-mlnx_msn3420-r0": { + "component": { + "BIOS": { }, + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_reboot new file mode 120000 index 000000000000..43c8ea567493 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_reboot @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_wait new file mode 120000 index 000000000000..4b30bd429854 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_wait @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_wait \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/eeprom.py new file mode 120000 index 000000000000..b4e2a6a61671 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/eeprom.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/psuutil.py new file mode 120000 index 000000000000..9f724238a8d5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/psuutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmget.py new file mode 120000 index 000000000000..2e84f435abd9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmget.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmset.py new file mode 120000 index 000000000000..6a88bac30467 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfpreset.py new file mode 120000 index 000000000000..fef2063e3496 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfpreset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfpreset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfputil.py new file mode 120000 index 000000000000..45909b880fc9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfputil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn3420-r0/pmon_daemon_control.json new file mode 120000 index 000000000000..435a2ce7c0ba --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pmon_daemon_control.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf new file mode 100644 index 000000000000..5718ff99518b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf @@ -0,0 +1,113 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN3420 +################################################################################ + +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" + +bus "i2c-7" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-*-49" + label temp1 "Ambient Fan Side Temp (air intake)" + chip "tmp102-i2c-*-4a" + label temp1 "Ambient Port Side Temp (air exhaust)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-15-49" + label temp1 "Ambient COMEX Temp" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 4)" + chip "tps53679-i2c-*-70" + label in1 "PMIC-1 PSU 12V Rail (in)" + label in2 "PMIC-1 PSU 12V Rail (in)" + label in3 "PMIC-1 COMEX 1.8V Rail (out)" + label in4 "PMIC-1 COMEX 1.05V Rail (out)" + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-1 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-1 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-1 COMEX 1.05V Rail Curr (out)" + chip "tps53679-i2c-*-71" + label in1 "PMIC-2 PSU 12V Rail (in)" + label in2 "PMIC-2 PSU 12V Rail (in)" + label in3 "PMIC-2 COMEX 1.8V Rail (out)" + label in4 "PMIC-2 COMEX 1.05V Rail (out)" + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-2 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-2 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-2 COMEX 1.05V Rail Curr (out)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tps53679-i2c-*-58" + label in1 "PMIC-3 PSU 12V Rail (in)" + label in2 "PMIC-3 PSU 12V Rail (in)" + label in3 "PMIC-3 COMEX 1.8V Rail (out)" + label in4 "PMIC-3 COMEX 1.05V Rail (out)" + label temp1 "PMIC-3 Temp 1" + label temp2 "PMIC-3 Temp 2" + label power1 "PMIC-3 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-3 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-3 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-3 COMEX 1.05V Rail Curr (out)" + chip "tps53679-i2c-*-61" + label in1 "PMIC-4 PSU 12V Rail (in)" + label in2 "PMIC-4 PSU 12V Rail (in)" + label in3 "PMIC-4 COMEX 1.8V Rail (out)" + label in4 "PMIC-4 COMEX 1.05V Rail (out)" + label temp1 "PMIC-4 Temp 1" + label temp2 "PMIC-4 Temp 2" + label power1 "PMIC-4 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-4 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-4 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-4 COMEX 1.05V Rail Curr (out)" + +# Power supplies +bus "i2c-4" "i2c-1-mux (chan_id 3)" + chip "dps460-i2c-*-58" + label in1 "PSU-1 220V Rail (in)" + label in2 "PSU-1 12V Rail (out)" + label fan1 "PSU-1 Fan 1" + label temp1 "PSU-1 Temp 1" + label temp2 "PSU-1 Temp 2" + label temp3 "PSU-1 Temp 3" + label power1 "PSU-1 220V Rail Pwr (in)" + label power2 "PSU-1 12V Rail Pwr (out)" + label curr1 "PSU-1 220V Rail Curr (in)" + label curr2 "PSU-1 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-2 220V Rail (in)" + label in2 "PSU-2 12V Rail (out)" + label fan1 "PSU-2 Fan 1" + label temp1 "PSU-2 Temp 1" + label temp2 "PSU-2 Temp 2" + label temp3 "PSU-2 Temp 3" + label power1 "PSU-2 220V Rail Pwr (in)" + label power2 "PSU-2 12V Rail Pwr (out)" + label curr1 "PSU-2 220V Rail Curr (in)" + label curr2 "PSU-2 12V Rail Curr (out)" + +# Chassis fans +chip "mlxreg_fan-isa-*" + label fan1 "Chassis Fan Drawer-1 Tach 1" + label fan2 "Chassis Fan Drawer-1 Tach 2" + label fan3 "Chassis Fan Drawer-2 Tach 1" + label fan4 "Chassis Fan Drawer-2 Tach 2" + label fan5 "Chassis Fan Drawer-3 Tach 1" + label fan6 "Chassis Fan Drawer-3 Tach 2" + label fan7 "Chassis Fan Drawer-4 Tach 1" + label fan8 "Chassis Fan Drawer-4 Tach 2" + label fan9 "Chassis Fan Drawer-5 Tach 1" + label fan10 "Chassis Fan Drawer-5 Tach 2" + label fan11 "Chassis Fan Drawer-6 Tach 1" + label fan12 "Chassis Fan Drawer-6 Tach 2" + +# Miscellaneous +chip "*-virtual-*" + ignore temp1 diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index d47110ed8f45..c3642331d19b 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -50,8 +50,8 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0} -port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] +hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5} +port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1), (0, 48, 59, 60, 1)] class Chassis(ChassisBase): """Platform-specific Chassis class""" diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 3f2fee433faf..6931cc0657c8 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -37,7 +37,7 @@ # in most SKUs the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. # but there are exceptions which will be handled by the following dictionary -hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1} +hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1, 'ACS-MSN3420': 1} psu_profile_list = [ # default filename convention { @@ -45,7 +45,7 @@ PSU_VOLTAGE : "power/psu{}_volt", PSU_POWER : "power/psu{}_power" }, - # for 3700, 3700c, 3800, 4700 + # for 3420, 3700, 3700c, 3800, 4700 { PSU_CURRENT : "power/psu{}_curr", PSU_VOLTAGE : "power/psu{}_volt_out2", diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 39f91913fe1e..a9c11848f5dc 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -124,7 +124,7 @@ THERMAL_API_GET_HIGH_THRESHOLD ] -hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8} +hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8, 'ACS-MSN3420': 9} thermal_profile_list = [ # 2700 { @@ -264,6 +264,22 @@ THERMAL_DEV_FAN_AMBIENT ] ) + }, + # 3420 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 60), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_COMEX_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) } ] From e363293ac0a03e0db7785c89f6fb71c13ff56831 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Tue, 28 Apr 2020 03:47:44 +0800 Subject: [PATCH 0586/1427] [Mellanox]Mellanox-SN3800-D112C8 support warm-reboot (#4482) --- .../Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml index 102842d72275..a72edb85633d 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 64 From b26814f6434ecaa00918216a492ac90b32a0e841 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Tue, 28 Apr 2020 11:52:57 +0800 Subject: [PATCH 0587/1427] [Mellanox] Adjust dynamic minimum fan speed algorithm (#4476) * remove air flow direction from dynamic minimum algorithm * adjust minimum table according to thermal data --- .../sonic_platform/device_data.py | 53 +++++-------------- .../sonic_platform/thermal.py | 9 +--- .../sonic_platform/thermal_actions.py | 3 +- .../sonic_platform/thermal_conditions.py | 7 +-- .../tests/test_thermal_policy.py | 13 ++--- 5 files changed, 21 insertions(+), 64 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py index f006281c511f..35b1f14d5bf9 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py @@ -2,34 +2,22 @@ 'x86_64-mlnx_msn2700-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:40":13, "41:120":15}, - "p2c_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16}, - "c2p_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "c2p_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "unk_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "unk_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16} + "unk_trust": {"-127:30":13, "31:40":14 , "41:120":15}, + "unk_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16} } } }, 'x86_64-mlnx_msn2740-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:120":13}, - "p2c_untrust": {"-127:35":13, "36:40":14 , "41:120":15}, - "c2p_trust": {"-127:120":13}, - "c2p_untrust": {"-127:15":13, "16:30":14 , "31:35":15, "36:120":17}, "unk_trust": {"-127:120":13}, - "unk_untrust": {"-127:15":13, "16:30":14 , "31:35":15, "36:120":17}, + "unk_untrust": {"-127:15":13, "16:25":14 , "26:30":15, "31:120":17}, } } }, 'x86_64-mlnx_msn2100-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:120":12}, - "p2c_untrust": {"-127:15":12, "16:25":13, "26:30":14, "31:35":15, "36:120":16}, - "c2p_trust": {"-127:40":12, "41:120":13}, - "c2p_untrust": {"-127:40":12, "41:120":13}, "unk_trust": {"-127:40":12, "41:120":13}, "unk_untrust": {"-127:15":12, "16:25":13, "26:30":14, "31:35":15, "36:120":16} } @@ -38,22 +26,14 @@ 'x86_64-mlnx_msn2410-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:40":13, "41:120":15}, - "p2c_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16}, - "c2p_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "c2p_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "unk_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "unk_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16} + "unk_trust": {"-127:30":13, "31:40":14 , "41:120":15}, + "unk_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16} } } }, 'x86_64-mlnx_msn2010-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:120":12}, - "p2c_untrust": {"-127:15":12, "16:20":13, "21:30":14, "31:35":15, "36:120":16}, - "c2p_trust": {"-127:120":12}, - "c2p_untrust": {"-127:20":12, "21:25":13 , "26:30":14, "31:35":15, "36:120":16}, "unk_trust": {"-127:120":12}, "unk_untrust": {"-127:15":12, "16:20":13 , "21:30":14, "31:35":15, "36:120":16} } @@ -62,10 +42,6 @@ 'x86_64-mlnx_msn3700-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:25":12, "26:40":13 , "41:120":14}, - "p2c_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, - "c2p_trust": {"-127:25":12, "26:40":13 , "41:120":14}, - "c2p_untrust": {"-127:25":12, "26:40":13 , "41:120":14}, "unk_trust": {"-127:25":12, "26:40":13 , "41:120":14}, "unk_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, } @@ -74,28 +50,25 @@ 'x86_64-mlnx_msn3700c-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:25":12, "26:40":13 , "41:120":14}, - "p2c_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, - "c2p_trust": {"-127:25":12, "26:40":13 , "41:120":14}, - "c2p_untrust": {"-127:25":12, "26:40":13 , "41:120":14}, - "unk_trust": {"-127:25":12, "26:40":13 , "41:120":14}, - "unk_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, + "unk_trust": {"-127:40":12, "41:120":13}, + "unk_untrust": {"-127:10":12, "11:20":13 , "21:30":14, "31:35":15, "36:120":16}, } } }, 'x86_64-mlnx_msn3800-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:35":12, "36:120":13}, - "p2c_untrust": {"-127:0":12, "1:10":13 , "11:15":14, "16:20":15, "21:35":16, "36:120":17}, - "c2p_trust": {"-127:30":12, "31:40":13 , "41:120":14}, - "c2p_untrust": {"-127:20":12, "21:30":13 , "31:35":14, "36:40":15, "41:120":16}, "unk_trust": {"-127:30":12, "31:40":13 , "41:120":14}, "unk_untrust": {"-127:0":12, "1:10":13 , "11:15":14, "16:20":15, "21:35":16, "36:120":17}, } } }, 'x86_64-mlnx_msn4700-r0': { - + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:120":16}, + "unk_untrust": {"-127:120":16}, + } + } } } \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index a9c11848f5dc..d4b9d56dc192 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -567,16 +567,11 @@ def check_module_temperature_trustable(cls): return 'trust' @classmethod - def get_air_flow_direction(cls): + def get_min_amb_temperature(cls): fan_ambient_path = join(HW_MGMT_THERMAL_ROOT, THERMAL_DEV_FAN_AMBIENT) port_ambient_path = join(HW_MGMT_THERMAL_ROOT, THERMAL_DEV_PORT_AMBIENT) # if there is any exception, let it raise fan_ambient_temp = int(cls._read_generic_file(fan_ambient_path, 0)) port_ambient_temp = int(cls._read_generic_file(port_ambient_path, 0)) - if fan_ambient_temp > port_ambient_temp: - return 'p2c', fan_ambient_temp - elif fan_ambient_temp < port_ambient_temp: - return 'c2p', port_ambient_temp - else: - return 'unk', fan_ambient_temp + return fan_ambient_temp if fan_ambient_temp < port_ambient_temp else port_ambient_temp diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py index 1f8292763ddd..3a4d5f2a8a68 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py @@ -154,10 +154,9 @@ def execute(self, thermal_info_dict): if chassis.platform_name not in DEVICE_DATA or 'thermal' not in DEVICE_DATA[chassis.platform_name] or 'minimum_table' not in DEVICE_DATA[chassis.platform_name]['thermal']: Fan.min_cooling_level = ChangeMinCoolingLevelAction.UNKNOWN_SKU_COOLING_LEVEL else: - air_flow_dir = MinCoolingLevelChangeCondition.air_flow_dir trust_state = MinCoolingLevelChangeCondition.trust_state temperature = MinCoolingLevelChangeCondition.temperature - minimum_table = DEVICE_DATA[chassis.platform_name]['thermal']['minimum_table']['{}_{}'.format(air_flow_dir, trust_state)] + minimum_table = DEVICE_DATA[chassis.platform_name]['thermal']['minimum_table']['unk_{}'.format(trust_state)] for key, cooling_level in minimum_table.items(): temp_range = key.split(':') diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py index 6bd2d282862b..94e18a2e00b0 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py @@ -78,14 +78,13 @@ def is_match(self, thermal_info_dict): class MinCoolingLevelChangeCondition(ThermalPolicyConditionBase): trust_state = None - air_flow_dir = None temperature = None def is_match(self, thermal_info_dict): from .thermal import Thermal trust_state = Thermal.check_module_temperature_trustable() - air_flow_dir, temperature = Thermal.get_air_flow_direction() + temperature = Thermal.get_min_amb_temperature() temperature = temperature / 1000 change_cooling_level = False @@ -93,10 +92,6 @@ def is_match(self, thermal_info_dict): MinCoolingLevelChangeCondition.trust_state = trust_state change_cooling_level = True - if air_flow_dir != MinCoolingLevelChangeCondition.air_flow_dir: - MinCoolingLevelChangeCondition.air_flow_dir = air_flow_dir - change_cooling_level = True - if temperature != MinCoolingLevelChangeCondition.temperature: MinCoolingLevelChangeCondition.temperature = temperature change_cooling_level = True diff --git a/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py index 835d7a495bbb..87fac359b2fd 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py @@ -482,10 +482,9 @@ def test_dynamic_minimum_policy(thermal_manager): condition = policy.conditions[MinCoolingLevelChangeCondition] action = policy.actions[ChangeMinCoolingLevelAction] Thermal.check_module_temperature_trustable = MagicMock(return_value='trust') - Thermal.get_air_flow_direction = MagicMock(return_value=('p2c', 35000)) + Thermal.get_min_amb_temperature = MagicMock(return_value=35000) assert condition.is_match(None) assert MinCoolingLevelChangeCondition.trust_state == 'trust' - assert MinCoolingLevelChangeCondition.air_flow_dir == 'p2c' assert MinCoolingLevelChangeCondition.temperature == 35 assert not condition.is_match(None) @@ -493,11 +492,7 @@ def test_dynamic_minimum_policy(thermal_manager): assert condition.is_match(None) assert MinCoolingLevelChangeCondition.trust_state == 'untrust' - Thermal.get_air_flow_direction = MagicMock(return_value=('c2p', 35000)) - assert condition.is_match(None) - assert MinCoolingLevelChangeCondition.air_flow_dir == 'c2p' - - Thermal.get_air_flow_direction = MagicMock(return_value=('c2p', 25000)) + Thermal.get_min_amb_temperature = MagicMock(return_value=25000) assert condition.is_match(None) assert MinCoolingLevelChangeCondition.temperature == 25 @@ -515,5 +510,5 @@ def test_dynamic_minimum_policy(thermal_manager): chassis.platform_name = 'x86_64-mlnx_msn2700-r0' action.execute(thermal_info_dict) - assert Fan.min_cooling_level == 4 - Fan.set_cooling_level.assert_called_with(4, 5) + assert Fan.min_cooling_level == 3 + Fan.set_cooling_level.assert_called_with(3, 5) From 72af55564556119a72e6f10a554cdf34baf7cfdf Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Mon, 27 Apr 2020 21:48:09 -0700 Subject: [PATCH 0588/1427] Parse Device region field in Minigraph (#4486) --- src/sonic-config-engine/minigraph.py | 9 +++++++-- .../tests/simple-sample-graph-metadata.xml | 5 +++++ src/sonic-config-engine/tests/test_cfggen.py | 5 +++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index c640d1378614..71f6bb9fc72c 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -419,6 +419,7 @@ def parse_meta(meta, hname): mgmt_routes = [] erspan_dst = [] deployment_id = None + region = None device_metas = meta.find(str(QName(ns, "Devices"))) for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower(): @@ -441,7 +442,9 @@ def parse_meta(meta, hname): erspan_dst = value_group elif name == "DeploymentId": deployment_id = value - return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id + elif name == "Region": + region = value + return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region def parse_deviceinfo(meta, hwsku): port_speeds = {} @@ -599,6 +602,7 @@ def parse_xml(filename, platform=None, port_config_file=None): erspan_dst = [] bgp_peers_with_range = None deployment_id = None + region = None hwsku_qn = QName(ns, "HwSku") hostname_qn = QName(ns, "Hostname") @@ -623,7 +627,7 @@ def parse_xml(filename, platform=None, port_config_file=None): elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): - (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id) = parse_meta(child, hostname) + (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) @@ -632,6 +636,7 @@ def parse_xml(filename, platform=None, port_config_file=None): results['DEVICE_METADATA'] = {'localhost': { 'bgp_asn': bgp_asn, 'deployment_id': deployment_id, + 'region': region, 'docker_routing_config_mode': docker_routing_config_mode, 'hostname': hostname, 'hwsku': hwsku, diff --git a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml index 1b1da1ff1787..db103e13480d 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml @@ -215,6 +215,11 @@ 1 + + Region + + usfoo + ErspanDestinationIpv4 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 7f5eb155092f..07769e0bf613 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -53,6 +53,11 @@ def test_minigraph_sku(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'Force10-Z9100') + def test_minigraph_region(self): + argument = '-v "DEVICE_METADATA[\'localhost\'][\'region\']" -m "' + self.sample_graph_metadata + '"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'usfoo') + def test_print_data(self): argument = '-m "' + self.sample_graph + '" --print-data' output = self.run_script(argument) From a60a203b75b02a1a83694a9bf2273ad3dc72be7f Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Tue, 28 Apr 2020 00:57:59 -0700 Subject: [PATCH 0589/1427] [dhcpmon] Filter DHCP O/A Messages of Neighboring Vlans (#4469) * [dhcpmon] Filter DHCP O/A Messages of Neighboring Vlans This code fixes a bug where two or more vlans exist. Cross contamination happens for DHCP packets Offer/Ack when received on shared northbound links. The code filters out those packet based on dst IP equal Vlan loopback IP. signed-off-by: Tamer Ahmed --- src/dhcpmon/src/dhcp_device.c | 185 ++++++++++++++++++++++++---------- src/dhcpmon/src/dhcp_device.h | 38 +++++-- src/dhcpmon/src/dhcp_devman.c | 33 +++++- src/dhcpmon/src/dhcp_devman.h | 19 +++- src/dhcpmon/src/dhcp_mon.c | 10 +- src/dhcpmon/src/dhcp_mon.h | 2 +- src/dhcpmon/src/main.c | 4 +- 7 files changed, 212 insertions(+), 79 deletions(-) diff --git a/src/dhcpmon/src/dhcp_device.c b/src/dhcpmon/src/dhcp_device.c index aa0c0f835cbd..554a1dcf0a97 100644 --- a/src/dhcpmon/src/dhcp_device.c +++ b/src/dhcpmon/src/dhcp_device.c @@ -33,6 +33,23 @@ #define DHCP_START_OFFSET (UDP_START_OFFSET + sizeof(struct udphdr)) /** Start of DHCP Options segment of a captured frame */ #define DHCP_OPTIONS_HEADER_SIZE 240 +/** Offset of DHCP GIADDR */ +#define DHCP_GIADDR_OFFSET 24 + +/** + * DHCP message types + **/ +typedef enum +{ + DHCP_MESSAGE_TYPE_DISCOVER = 1, + DHCP_MESSAGE_TYPE_OFFER = 2, + DHCP_MESSAGE_TYPE_REQUEST = 3, + DHCP_MESSAGE_TYPE_DECLINE = 4, + DHCP_MESSAGE_TYPE_ACK = 5, + DHCP_MESSAGE_TYPE_NAK = 6, + DHCP_MESSAGE_TYPE_RELEASE = 7, + DHCP_MESSAGE_TYPE_INFORM = 8 +} dhcp_message_type; #define OP_LDHA (BPF_LD | BPF_H | BPF_ABS) /** bpf ldh Abs */ #define OP_LDHI (BPF_LD | BPF_H | BPF_IND) /** bpf ldh Ind */ @@ -43,8 +60,9 @@ #define OP_JSET (BPF_JMP | BPF_JSET | BPF_K) /** bpf jset */ #define OP_LDXB (BPF_LDX | BPF_B | BPF_MSH) /** bpf ldxb */ -/** Berkley Packet Fitler program for "udp and (port 67 or port 68)". This program is obtained suing the following - * tcpdump command: 'tcpdump -dd "udp and (port 67 or port 68)"' +/** Berkeley Packet Filter program for "udp and (port 67 or port 68)". + * This program is obtained using the following command tcpdump: + * `tcpdump -dd "udp and (port 67 or port 68)"` */ static struct sock_filter dhcp_bpf_code[] = { {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x0000000c}, // (000) ldh [12] @@ -90,47 +108,63 @@ static dhcp_device_counters_t glob_counters_snapshot[DHCP_DIR_COUNT] = { }; /** - * @code handle_dhcp_option_53(context, dhcp_option, dir); + * @code handle_dhcp_option_53(context, dhcp_option, dir, iphdr, dhcphdr); * * @brief handle the logic related to DHCP option 53 * * @param context Device (interface) context * @param dhcp_option pointer to DHCP option buffer space * @param dir packet direction + * @param iphdr pointer to packet IP header + * @param dhcphdr pointer to DHCP header * * @return none */ -static void handle_dhcp_option_53(dhcp_device_context_t *context, const u_char *dhcp_option, dhcp_packet_direction_t dir) +static void handle_dhcp_option_53(dhcp_device_context_t *context, + const u_char *dhcp_option, + dhcp_packet_direction_t dir, + struct ip *iphdr, + uint8_t *dhcphdr) { + in_addr_t giaddr; switch (dhcp_option[2]) { - case 1: + case DHCP_MESSAGE_TYPE_DISCOVER: + giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 | + dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]); context->counters[dir].discover++; - if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == giaddr && context->is_uplink && dir == DHCP_TX) || + (!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) { glob_counters[dir].discover++; } break; - case 2: + case DHCP_MESSAGE_TYPE_OFFER: context->counters[dir].offer++; - if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) || + (!context->is_uplink && dir == DHCP_TX)) { glob_counters[dir].offer++; } break; - case 3: + case DHCP_MESSAGE_TYPE_REQUEST: + giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 | + dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]); context->counters[dir].request++; - if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == giaddr && context->is_uplink && dir == DHCP_TX) || + (!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) { glob_counters[dir].request++; } break; - case 5: + case DHCP_MESSAGE_TYPE_ACK: context->counters[dir].ack++; - if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) || + (!context->is_uplink && dir == DHCP_TX)) { glob_counters[dir].ack++; } break; - case 4: // type: Decline - case 6 ... 8: - // type: NAK, Release, Inform + case DHCP_MESSAGE_TYPE_DECLINE: + case DHCP_MESSAGE_TYPE_NAK: + case DHCP_MESSAGE_TYPE_RELEASE: + case DHCP_MESSAGE_TYPE_INFORM: break; default: syslog(LOG_WARNING, "handle_dhcp_option_53(%s): Unknown DHCP option 53 type %d", context->intf, dhcp_option[2]); @@ -146,7 +180,6 @@ static void handle_dhcp_option_53(dhcp_device_context_t *context, const u_char * * @param fd socket to read from * @param event libevent triggered event * @param arg user provided argument for callback (interface context) - * @param packet pointer to packet data * * @return none */ @@ -158,7 +191,9 @@ static void read_callback(int fd, short event, void *arg) while ((event == EV_READ) && ((buffer_sz = recv(fd, context->buffer, context->snaplen, MSG_DONTWAIT)) > 0)) { struct ether_header *ethhdr = (struct ether_header*) context->buffer; + struct ip *iphdr = (struct ip*) (context->buffer + IP_START_OFFSET); struct udphdr *udp = (struct udphdr*) (context->buffer + UDP_START_OFFSET); + uint8_t *dhcphdr = context->buffer + DHCP_START_OFFSET; int dhcp_option_offset = DHCP_START_OFFSET + DHCP_OPTIONS_HEADER_SIZE; if ((buffer_sz > UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) && @@ -181,7 +216,7 @@ static void read_callback(int fd, short event, void *arg) { case 53: if (offset < (dhcp_option_sz + 2)) { - handle_dhcp_option_53(context, &dhcp_option[offset], dir); + handle_dhcp_option_53(context, &dhcp_option[offset], dir, iphdr, dhcphdr); } stop_dhcp_processing = 1; // break while loop since we are only interested in Option 53 break; @@ -260,31 +295,21 @@ static void dhcp_print_counters(dhcp_device_counters_t *counters) } /** - * @code init_socket(context, intf, snaplen, base); + * @code init_socket(context, intf); * * @brief initializes socket, bind it to interface and bpf prgram, and * associate with libevent base * * @param context pointer to device (interface) context * @param intf interface name - * @param snaplen length of packet capture - * @param base libevent base * * @return 0 on success, otherwise for failure */ -static int init_socket(dhcp_device_context_t *context, - const char *intf, - size_t snaplen, - struct event_base *base) +static int init_socket(dhcp_device_context_t *context, const char *intf) { int rv = -1; do { - if (snaplen < UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) { - syslog(LOG_ALERT, "init_socket(%s): snap length is too low to capture DHCP options", intf); - break; - } - context->sock = socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, htons(ETH_P_ALL)); if (context->sock < 0) { syslog(LOG_ALERT, "socket: failed to open socket with '%s'\n", strerror(errno)); @@ -301,25 +326,6 @@ static int init_socket(dhcp_device_context_t *context, break; } - if (setsockopt(context->sock, SOL_SOCKET, SO_ATTACH_FILTER, &dhcp_sock_bfp, sizeof(dhcp_sock_bfp)) != 0) { - syslog(LOG_ALERT, "setsockopt: failed to attach filter with '%s'\n", strerror(errno)); - break; - } - - context->buffer = (uint8_t *) malloc(snaplen); - if (context->buffer == NULL) { - syslog(LOG_ALERT, "malloc: failed to allocate memory for socket buffer '%s'\n", strerror(errno)); - break; - } - context->snaplen = snaplen; - - struct event *ev = event_new(base, context->sock, EV_READ | EV_PERSIST, read_callback, context); - if (ev == NULL) { - syslog(LOG_ALERT, "event_new: failed to allocate memory for libevent event '%s'\n", strerror(errno)); - break; - } - event_add(ev, NULL); - strncpy(context->intf, intf, sizeof(context->intf) - 1); context->intf[sizeof(context->intf) - 1] = '\0'; @@ -377,15 +383,32 @@ static int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context) } /** - * @code dhcp_device_init(context, intf, snaplen, is_uplink, base); + * @code dhcp_device_get_ip(context); + * + * @brief Accessor method + * + * @param context pointer to device (interface) context + * + * @return interface IP + */ +int dhcp_device_get_ip(dhcp_device_context_t *context, in_addr_t *ip) +{ + int rv = -1; + + if (context != NULL && ip != NULL) { + *ip = context->ip; + rv = 0; + } + + return rv; +} + +/** + * @code dhcp_device_init(context, intf, is_uplink); * * @brief initializes device (interface) that handles packet capture per interface. */ -int dhcp_device_init(dhcp_device_context_t **context, - const char *intf, - int snaplen, - uint8_t is_uplink, - struct event_base *base) +int dhcp_device_init(dhcp_device_context_t **context, const char *intf, uint8_t is_uplink) { int rv = -1; dhcp_device_context_t *dev_context = NULL; @@ -394,8 +417,8 @@ int dhcp_device_init(dhcp_device_context_t **context, dev_context = (dhcp_device_context_t *) malloc(sizeof(dhcp_device_context_t)); if (dev_context != NULL) { - if ((init_socket(dev_context, intf, snaplen, base) == 0) && - (initialize_intf_mac_and_ip_addr(dev_context) == 0 ) ) { + if ((init_socket(dev_context, intf) == 0) && + (initialize_intf_mac_and_ip_addr(dev_context) == 0)) { dev_context->is_uplink = is_uplink; @@ -414,6 +437,56 @@ int dhcp_device_init(dhcp_device_context_t **context, return rv; } +/** + * @code dhcp_device_start_capture(context, snaplen, base, vlan_ip); + * + * @brief starts packet capture on this interface + */ +int dhcp_device_start_capture(dhcp_device_context_t *context, + size_t snaplen, + struct event_base *base, + in_addr_t vlan_ip) +{ + int rv = -1; + + do { + if (context == NULL) { + syslog(LOG_ALERT, "NULL interface context pointer'\n"); + break; + } + + if (snaplen < UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) { + syslog(LOG_ALERT, "dhcp_device_start_capture(%s): snap length is too low to capture DHCP options", context->intf); + break; + } + + context->vlan_ip = vlan_ip; + + context->buffer = (uint8_t *) malloc(snaplen); + if (context->buffer == NULL) { + syslog(LOG_ALERT, "malloc: failed to allocate memory for socket buffer '%s'\n", strerror(errno)); + break; + } + context->snaplen = snaplen; + + if (setsockopt(context->sock, SOL_SOCKET, SO_ATTACH_FILTER, &dhcp_sock_bfp, sizeof(dhcp_sock_bfp)) != 0) { + syslog(LOG_ALERT, "setsockopt: failed to attach filter with '%s'\n", strerror(errno)); + break; + } + + struct event *ev = event_new(base, context->sock, EV_READ | EV_PERSIST, read_callback, context); + if (ev == NULL) { + syslog(LOG_ALERT, "event_new: failed to allocate memory for libevent event '%s'\n", strerror(errno)); + break; + } + event_add(ev, NULL); + + rv = 0; + } while (0); + + return rv; +} + /** * @code dhcp_device_shutdown(context); * diff --git a/src/dhcpmon/src/dhcp_device.h b/src/dhcpmon/src/dhcp_device.h index 04113eeabdc0..bc1582d46a82 100644 --- a/src/dhcpmon/src/dhcp_device.h +++ b/src/dhcpmon/src/dhcp_device.h @@ -49,6 +49,7 @@ typedef struct int sock; /** Raw socket associated with this device/interface */ in_addr_t ip; /** network address of this device (interface) */ uint8_t mac[ETHER_ADDR_LEN]; /** hardware address of this device (interface) */ + in_addr_t vlan_ip; /** Vlan IP address */ uint8_t is_uplink; /** north interface? */ char intf[IF_NAMESIZE]; /** device (interface) name */ uint8_t *buffer; /** buffer used to read socket data */ @@ -60,23 +61,48 @@ typedef struct } dhcp_device_context_t; /** - * @code dhcp_device_init(context, intf, snaplen, timeout_ms, is_uplink, base); + * @code dhcp_device_get_ip(context, ip); + * + * @brief Accessor method + * + * @param context pointer to device (interface) context + * @param ip(out) pointer to device IP + * + * @return 0 on success, otherwise for failure + */ +int dhcp_device_get_ip(dhcp_device_context_t *context, in_addr_t *ip); + +/** + * @code dhcp_device_init(context, intf, is_uplink); * * @brief initializes device (interface) that handles packet capture per interface. * * @param context(inout) pointer to device (interface) context * @param intf interface name - * @param snaplen length of packet capture * @param is_uplink uplink interface - * @param base pointer to libevent base * * @return 0 on success, otherwise for failure */ int dhcp_device_init(dhcp_device_context_t **context, const char *intf, - int snaplen, - uint8_t is_uplink, - struct event_base *base); + uint8_t is_uplink); + +/** + * @code dhcp_device_start_capture(context, snaplen, base, vlan_ip); + * + * @brief starts packet capture on this interface + * + * @param context pointer to device (interface) context + * @param snaplen length of packet capture + * @param base pointer to libevent base + * @param vlan_ip vlan IP address + * + * @return 0 on success, otherwise for failure + */ +int dhcp_device_start_capture(dhcp_device_context_t *context, + size_t snaplen, + struct event_base *base, + in_addr_t vlan_ip); /** * @code dhcp_device_shutdown(context); diff --git a/src/dhcpmon/src/dhcp_devman.c b/src/dhcpmon/src/dhcp_devman.c index c19cbde591b8..077ed210a299 100644 --- a/src/dhcpmon/src/dhcp_devman.c +++ b/src/dhcpmon/src/dhcp_devman.c @@ -28,6 +28,23 @@ static uint32_t dhcp_num_south_intf = 0; /** dhcp_num_north_intf number of north interfaces */ static uint32_t dhcp_num_north_intf = 0; +/** On Device vlan interface IP address corresponding vlan downlink IP + * This IP is used to filter Offer/Ack packet coming from DHCP server */ +static in_addr_t vlan_ip = 0; + +/** vlan interface name */ +static char vlan_intf[IF_NAMESIZE] = "Undefined"; + +/** + * @code dhcp_devman_get_vlan_intf(); + * + * Accessor method + */ +const char* dhcp_devman_get_vlan_intf() +{ + return vlan_intf; +} + /** * @code dhcp_devman_init(); * @@ -65,7 +82,7 @@ void dhcp_devman_shutdown() } /** - * @code dhcp_devman_add_intf(name, uplink); + * @code dhcp_devman_add_intf(name, is_uplink); * * @brief adds interface to the device manager. */ @@ -84,9 +101,15 @@ int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) assert(dhcp_num_south_intf <= 1); } - LIST_INSERT_HEAD(&intfs, dev, entry); + rv = dhcp_device_init(&dev->dev_context, dev->name, dev->is_uplink); + if (rv == 0 && !is_uplink) { + rv = dhcp_device_get_ip(dev->dev_context, &vlan_ip); - rv = 0; + strncpy(vlan_intf, name, sizeof(vlan_intf) - 1); + vlan_intf[sizeof(vlan_intf) - 1] = '\0'; + } + + LIST_INSERT_HEAD(&intfs, dev, entry); } else { syslog(LOG_ALERT, "malloc: failed to allocate memory for intf '%s'\n", name); @@ -100,14 +123,14 @@ int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) * * @brief start packet capture on the devman interface list */ -int dhcp_devman_start_capture(int snaplen, struct event_base *base) +int dhcp_devman_start_capture(size_t snaplen, struct event_base *base) { int rv = -1; struct intf *int_ptr; if ((dhcp_num_south_intf == 1) && (dhcp_num_north_intf >= 1)) { LIST_FOREACH(int_ptr, &intfs, entry) { - rv = dhcp_device_init(&int_ptr->dev_context, int_ptr->name, snaplen, int_ptr->is_uplink, base); + rv = dhcp_device_start_capture(int_ptr->dev_context, snaplen, base, vlan_ip); if (rv == 0) { syslog(LOG_INFO, "Capturing DHCP packets on interface %s, ip: 0x%08x, mac [%02x:%02x:%02x:%02x:%02x:%02x] \n", diff --git a/src/dhcpmon/src/dhcp_devman.h b/src/dhcpmon/src/dhcp_devman.h index a0753b4b93a1..2f66fa407ca2 100644 --- a/src/dhcpmon/src/dhcp_devman.h +++ b/src/dhcpmon/src/dhcp_devman.h @@ -31,29 +31,38 @@ void dhcp_devman_init(); */ void dhcp_devman_shutdown(); +/** + * @code dhcp_devman_get_vlan_intf(); + * + * @brief Accessor method + * + * @return pointer to vlan ip interface name + */ +const char* dhcp_devman_get_vlan_intf(); + /** * @code dhcp_devman_add_intf(name, uplink); * * @brief adds interface to the device manager. * - * @param name interface name - * @param is_uplink true for uplink (north) interface + * @param name interface name + * @param is_uplink true for uplink (north) interface * * @return 0 on success, nonzero otherwise */ int dhcp_devman_add_intf(const char *name, uint8_t is_uplink); /** - * @code dhcp_devman_start_capture(snaplen, timeout_ms); + * @code dhcp_devman_start_capture(snaplen, base); * * @brief start packet capture on the devman interface list * - * @param snaplen packet capture snap length + * @param snaplen packet packet capture snap length * @param base libevent base * * @return 0 on success, nonzero otherwise */ -int dhcp_devman_start_capture(int snaplen, struct event_base *base); +int dhcp_devman_start_capture(size_t snaplen, struct event_base *base); /** * @code dhcp_devman_get_status(); diff --git a/src/dhcpmon/src/dhcp_mon.c b/src/dhcpmon/src/dhcp_mon.c index dc0a7d94f149..623bc46f5276 100644 --- a/src/dhcpmon/src/dhcp_mon.c +++ b/src/dhcpmon/src/dhcp_mon.c @@ -36,13 +36,13 @@ static struct event *ev_sigterm; * * @param fd libevent socket * @param event event triggered - * @param arg pointer user provided context (libevent base) + * @param arg pointer to user provided context (libevent base) * * @return none */ static void signal_callback(evutil_socket_t fd, short event, void *arg) { - syslog(LOG_ALERT, "Received signal %d\n", event); + syslog(LOG_ALERT, "Received signal %s\n", strsignal(fd)); dhcp_devman_print_status(); dhcp_mon_stop(); } @@ -67,7 +67,9 @@ static void timeout_callback(evutil_socket_t fd, short event, void *arg) { case DHCP_MON_STATUS_UNHEALTHY: if (++count > dhcp_unhealthy_max_count) { - syslog(LOG_ALERT, "DHCP Relay is not healthy after %d health checks\n", count); + syslog(LOG_ALERT, "dhcpmon detected disparity in DHCP Relay behavior. Failure count: %d for vlan: '%s'\n", + count, dhcp_devman_get_vlan_intf()); + dhcp_devman_print_status(); } break; case DHCP_MON_STATUS_HEALTHY: @@ -151,7 +153,7 @@ void dhcp_mon_shutdown() * * @brief start monitoring DHCP Relay */ -int dhcp_mon_start(int snaplen) +int dhcp_mon_start(size_t snaplen) { int rv = -1; diff --git a/src/dhcpmon/src/dhcp_mon.h b/src/dhcpmon/src/dhcp_mon.h index 44d361b32ec0..ae8911ab51fc 100644 --- a/src/dhcpmon/src/dhcp_mon.h +++ b/src/dhcpmon/src/dhcp_mon.h @@ -40,7 +40,7 @@ void dhcp_mon_shutdown(); * * @return 0 upon success, otherwise upon failure */ -int dhcp_mon_start(int snaplen); +int dhcp_mon_start(size_t snaplen); /** * @code dhcp_mon_stop(); diff --git a/src/dhcpmon/src/main.c b/src/dhcpmon/src/main.c index 11eab6ee9ea1..9d155393a6e6 100644 --- a/src/dhcpmon/src/main.c +++ b/src/dhcpmon/src/main.c @@ -21,7 +21,7 @@ #include "dhcp_devman.h" /** dhcpmon_default_snaplen: default snap length of packet being captured */ -static const uint32_t dhcpmon_default_snaplen = 65535; +static const size_t dhcpmon_default_snaplen = 65535; /** dhcpmon_default_health_check_window: default value for a time window, during which DHCP DORA packet counts are being * collected */ static const uint32_t dhcpmon_default_health_check_window = 12; @@ -109,7 +109,7 @@ int main(int argc, char **argv) int i; int window_interval = dhcpmon_default_health_check_window; int max_unhealthy_count = dhcpmon_default_unhealthy_max_count; - uint32_t snaplen = dhcpmon_default_snaplen; + size_t snaplen = dhcpmon_default_snaplen; int make_daemon = 0; setlogmask(LOG_UPTO(LOG_INFO)); From 0409a32abe6591142e6819ff10eaf91044f39c1b Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Tue, 28 Apr 2020 18:15:19 +0300 Subject: [PATCH 0590/1427] [mellanox]: Align CPLD component with latest hw-mgmt. (#4485) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/mlnx-platform-api/sonic_platform/component.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 13e3953a03ad..d5937b63286d 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -232,7 +232,7 @@ class ComponentCPLD(Component): CPLD_NUMBER_FILE = '/var/run/hw-management/config/cpld_num' CPLD_PART_NUMBER_FILE = '/var/run/hw-management/system/cpld{}_pn' CPLD_VERSION_FILE = '/var/run/hw-management/system/cpld{}_version' - CPLD_VERSION_MINOR_FILE = '/var/run/hw-management/system/cpld{}_version_minor' + CPLD_VERSION_MINOR_FILE = '/var/run/hw-management/system/cpld{}_version_min' CPLD_NUMBER_MAX_LENGTH = 1 CPLD_PART_NUMBER_MAX_LENGTH = 6 From a40fe3ba15c38719dfa8b7010eade6be138fed23 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Wed, 29 Apr 2020 01:46:19 +0530 Subject: [PATCH 0591/1427] [DellEMC] S6100-Fix i2C ISMT issue (#4330) * [DellEMC] S6100-Fix i2C ISMT issue * Modified the retry condition for bit bang --- .../s6100/scripts/fast-reboot_plugin | 1 + .../s6100/scripts/pcisysfs.py | 91 +++++++++++++++++++ .../s6100/scripts/s6100_bitbang_reset.sh | 59 ++++++++++++ .../s6100/scripts/s6100_i2c_enumeration.sh | 1 + 4 files changed, 152 insertions(+) create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin index d385be3bc685..e32747c7fed5 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin @@ -4,3 +4,4 @@ if [[ -d /sys/devices/platform/SMF.512/hwmon/ ]]; then cd /sys/devices/platform/SMF.512/hwmon/* echo 0xcc > mb_poweron_reason fi +/usr/local/bin/s6100_i2c_enumeration.sh deinit & > /dev/null diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py new file mode 100755 index 000000000000..767b66f43b63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py @@ -0,0 +1,91 @@ +#! /usr/bin/python + +import struct +import sys +import getopt +from os import * +from mmap import * + +def usage(): + ''' This is the Usage Method ''' + + print '\t\t pcisysfs.py --get --offset --res ' + print '\t\t pcisysfs.py --set --val --offset --res ' + sys.exit(1) + +def pci_mem_read(mm,offset): + mm.seek(offset) + read_data_stream=mm.read(4) + print "" + reg_val=struct.unpack('I',read_data_stream) + print "reg_val read:%x"%reg_val + return reg_val + +def pci_mem_write(mm,offset,data): + mm.seek(offset) + #print "data to write:%x"%data + mm.write(struct.pack('I',data)) + +def pci_set_value(resource,val,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_write(mm,offset,val) + close(fd) + +def pci_get_value(resource,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_read(mm,offset) + close(fd) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resource = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgsv:" , \ + ["val=","res=","offset=","help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt,arg in opts: + + if opt in ('-h','--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--res': + resource = arg + + elif opt == '--val': + val = int(arg,16) + + elif opt == '--offset': + offset = int(arg,16) + + if choice == 'set' and val != '' and offset !='' and resource !='': + pci_set_value(resource,val,offset) + + elif choice == 'get' and offset != '' and resource !='': + pci_get_value(resource,offset) + + else: + usage() + +#Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh new file mode 100644 index 000000000000..ff49c0a0f788 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# Script to unfreeze a stuck I2C controller, by bit-banging a STOP cycle on the bus + +bit_bang_recovery() +{ + +# Clear the ERRSTS +pcisysfs.py --set --val 0xffffffff --offset 0x018 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + +#Enable I2C bit-banging +pcisysfs.py --set --val 0x80000000 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + +count=1 +while [ $count -le 9 ]; +do + # Bit-bang an I2C STOP cycle + + # SCL=0, SDA=0 + pcisysfs.py --set --val 0x80000000 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + + sleep 0.01 + + # SCL=1, SDA=0 + pcisysfs.py --set --val 0x80000002 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + + sleep 0.01 + + # SCL=1, SDA=1 + pcisysfs.py --set --val 0x80000003 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + + sleep 1 + + # Check I2C DBSTS register + mctrl=$((`pcisysfs.py --get --offset 0x108 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) + msts=$((`pcisysfs.py --get --offset 0x10c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) + dbsts=$((`pcisysfs.py --get --offset 0x38c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) + msts_ip=$((msts&0x1)) + + mctrl=$((10#$mctrl)) + if [ $msts_ip = 0 ]; then + logger -p NOTICE "I2C_bitbang-Bit banging done on I2C bus" + logger -p NOTICE "After I2C_bitbang- MCTRL:$(printf "0x%x" $mctrl)","MSTS:$(printf "0x%x" $msts)","DBSTS:$(printf "0x%x" $dbsts)" + break + fi + count=$(( $count + 1 )) +done + +#Disable I2C bit-banging +pcisysfs.py --set --val 0x00000003 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + +} + +mctrl=$((`pcisysfs.py --get --offset 0x108 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) +msts=$((`pcisysfs.py --get --offset 0x10c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) +dbsts=$((`pcisysfs.py --get --offset 0x38c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) +logger -p NOTICE "Before I2C_bitbang- MCTRL:$(printf "0x%x" $mctrl)","MSTS:$(printf "0x%x" $msts)","DBSTS:$(printf "0x%x" $dbsts)" +sleep 2 +bit_bang_recovery diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh index 04cff29ea7af..af91f378339e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh @@ -245,6 +245,7 @@ if [[ "$1" == "init" ]]; then sys_eeprom "new_device" switch_board_eeprom "new_device" switch_board_cpld "new_device" + /usr/local/bin/s6100_bitbang_reset.sh switch_board_qsfp_mux "new_device" switch_board_sfp "new_device" switch_board_qsfp "new_device" From fc55329b220e21a25dd145197002a356ef271641 Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Tue, 28 Apr 2020 15:57:13 -0700 Subject: [PATCH 0592/1427] [mgmt-framework]: convert mgmt-framework to use buster docker (#4480) This change adds support to build dockers using buster as base. - Define docker-base-buster using docker-base-stretch as starting point - Define docker-config-engine-buster using docker-config-engine-stretch as starting point. - sonic-mgmt-framework docker is updated to build using buster as base Signed-off-by: Joyas Joseph --- dockers/docker-base-buster/Dockerfile.j2 | 98 +++++++++++++++++++ dockers/docker-base-buster/LICENSE | 13 +++ dockers/docker-base-buster/dpkg_01_drop | 30 ++++++ dockers/docker-base-buster/etc/rsyslog.conf | 76 ++++++++++++++ .../etc/rsyslog.d/supervisor.conf | 9 ++ .../etc/supervisor/supervisord.conf | 33 +++++++ .../docker-base-buster/no-check-valid-until | 4 + .../no_install_recommend_suggest | 5 + dockers/docker-base-buster/root/.vimrc | 2 + dockers/docker-base-buster/sources.list | 8 ++ dockers/docker-base-buster/sources.list.arm64 | 7 ++ dockers/docker-base-buster/sources.list.armhf | 7 ++ .../docker-config-engine-buster/Dockerfile.j2 | 50 ++++++++++ .../docker-sonic-mgmt-framework/Dockerfile.j2 | 8 +- rules/docker-base-buster.dep | 10 ++ rules/docker-base-buster.mk | 17 ++++ rules/docker-config-engine-buster.dep | 10 ++ rules/docker-config-engine-buster.mk | 13 +++ rules/docker-sonic-mgmt-framework.mk | 8 +- slave.mk | 12 +-- 20 files changed, 402 insertions(+), 18 deletions(-) create mode 100644 dockers/docker-base-buster/Dockerfile.j2 create mode 100644 dockers/docker-base-buster/LICENSE create mode 100644 dockers/docker-base-buster/dpkg_01_drop create mode 100644 dockers/docker-base-buster/etc/rsyslog.conf create mode 100644 dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf create mode 100644 dockers/docker-base-buster/etc/supervisor/supervisord.conf create mode 100644 dockers/docker-base-buster/no-check-valid-until create mode 100644 dockers/docker-base-buster/no_install_recommend_suggest create mode 100644 dockers/docker-base-buster/root/.vimrc create mode 100644 dockers/docker-base-buster/sources.list create mode 100644 dockers/docker-base-buster/sources.list.arm64 create mode 100644 dockers/docker-base-buster/sources.list.armhf create mode 100644 dockers/docker-config-engine-buster/Dockerfile.j2 create mode 100644 rules/docker-base-buster.dep create mode 100644 rules/docker-base-buster.mk create mode 100644 rules/docker-config-engine-buster.dep create mode 100644 rules/docker-config-engine-buster.mk diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 new file mode 100644 index 000000000000..de78845c62b3 --- /dev/null +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -0,0 +1,98 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +{% if CONFIGURED_ARCH == "armhf" %} +FROM multiarch/debian-debootstrap:armhf-buster +{% elif CONFIGURED_ARCH == "arm64" %} +FROM multiarch/debian-debootstrap:arm64-buster +{% else %} +FROM debian:buster +{% endif %} + +# Clean documentation in FROM image +RUN find /usr/share/doc -depth \( -type f -o -type l \) ! -name copyright | xargs rm || true + +# Clean doc directories that are empty or only contain empty directories +RUN while [ -n "$(find /usr/share/doc -depth -type d -empty -print -exec rmdir {} +)" ]; do :; done && \ + rm -rf \ + /usr/share/man/* \ + /usr/share/groff/* \ + /usr/share/info/* \ + /usr/share/lintian/* \ + /usr/share/linda/* \ + /var/cache/man/* \ + /usr/share/locale/* + +# Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +# Configure data sources for apt/dpkg +COPY ["dpkg_01_drop", "/etc/dpkg/dpkg.cfg.d/01_drop"] +{% if CONFIGURED_ARCH == "armhf" %} +COPY ["sources.list.armhf", "/etc/apt/sources.list"] +{% elif CONFIGURED_ARCH == "arm64" %} +COPY ["sources.list.arm64", "/etc/apt/sources.list"] +{% else %} +COPY ["sources.list", "/etc/apt/sources.list"] +{% endif %} +COPY ["no_install_recommend_suggest", "/etc/apt/apt.conf.d"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] + +# Update apt cache and +# pre-install fundamental packages +RUN apt-get update && \ + apt-get -y install \ + less \ + perl \ + procps \ + python \ + rsyslog \ + vim-tiny \ +# Install dependencies of supervisor + python-pkg-resources \ + python-meld3 \ +# dependencies of redis-tools + libatomic1 \ + libjemalloc2 \ + liblua5.1-0 \ + lua-bitop \ + lua-cjson \ +# common dependencies + libpython2.7 \ + libdaemon0 \ + libdbus-1-3 \ + libjansson4 + +# ip and ifconfig utility missing in docker for arm arch +RUN apt-get -y install \ + iproute2 \ + net-tools + +RUN mkdir -p /etc/supervisor /var/log/supervisor + +RUN apt-get -y purge \ + exim4 \ + exim4-base \ + exim4-config \ + exim4-daemon-light + +{% if docker_base_buster_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_base_buster_debs.split(' '), "/debs/") }} + +# Install built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_base_buster_debs.split(' ')) }} +{%- endif %} + +# Clean up apt +# Remove /var/lib/apt/lists/*, could be obsoleted for derived images +RUN apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /var/lib/apt/lists/* /tmp/* + +COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"] +COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"] +COPY ["root/.vimrc", "/root/.vimrc"] + +RUN ln /usr/bin/vim.tiny /usr/bin/vim + +COPY ["etc/supervisor/supervisord.conf", "/etc/supervisor/"] diff --git a/dockers/docker-base-buster/LICENSE b/dockers/docker-base-buster/LICENSE new file mode 100644 index 000000000000..03d8f31e513c --- /dev/null +++ b/dockers/docker-base-buster/LICENSE @@ -0,0 +1,13 @@ +Copyright 2016 Microsoft, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/dockers/docker-base-buster/dpkg_01_drop b/dockers/docker-base-buster/dpkg_01_drop new file mode 100644 index 000000000000..d749943797d9 --- /dev/null +++ b/dockers/docker-base-buster/dpkg_01_drop @@ -0,0 +1,30 @@ +## Drop unnecessary files +## ref: https://wiki.ubuntu.com/ReducingDiskFootprint + +## Documentation +path-exclude /usr/share/doc/* +# we need to keep copyright files for legal reasons +path-include /usr/share/doc/*/copyright +path-exclude /usr/share/man/* +path-exclude /usr/share/groff/* +path-exclude /usr/share/info/* +# lintian stuff is small, but really unnecessary +path-exclude /usr/share/lintian/* +path-exclude /usr/share/linda/* + +## Translations +path-exclude /usr/share/locale/* + +## Landscape +path-exclude /usr/share/pyshared/twisted/test* +path-exclude /usr/lib/python*/dist-packages/twisted/test* +path-exclude /usr/share/pyshared/twisted/*/test* +path-exclude /usr/lib/python*/dist-packages/twisted/*/test* + +## install the configuration file if it’s currently missing +force-confmiss +## combined with confold: overwrite configuration files that you have not modified +force-confdef +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +force-confold + diff --git a/dockers/docker-base-buster/etc/rsyslog.conf b/dockers/docker-base-buster/etc/rsyslog.conf new file mode 100644 index 000000000000..ef249229ab1e --- /dev/null +++ b/dockers/docker-base-buster/etc/rsyslog.conf @@ -0,0 +1,76 @@ +# +# /etc/rsyslog.conf Configuration file for rsyslog. +# +# For more information see +# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html + + +################# +#### MODULES #### +################# + +$ModLoad imuxsock # provides support for local system logging + +# +# Set a rate limit on messages from the container +# +$SystemLogRateLimitInterval 300 +$SystemLogRateLimitBurst 20000 + +#$ModLoad imklog # provides kernel logging support +#$ModLoad immark # provides --MARK-- message capability + +# provides UDP syslog reception +#$ModLoad imudp +#$UDPServerRun 514 + +# provides TCP syslog reception +#$ModLoad imtcp +#$InputTCPServerRun 514 + + +########################### +#### GLOBAL DIRECTIVES #### +########################### + +# Set remote syslog server +template (name="ForwardFormatInContainer" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%") +*.* action(type="omfwd" target="127.0.0.1" port="514" protocol="udp" Template="ForwardFormatInContainer") + +# +# Use traditional timestamp format. +# To enable high precision timestamps, comment out the following line. +# +#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat + +# Define a custom template +$template SONiCFileFormat,"%TIMESTAMP%.%timestamp:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" +$ActionFileDefaultTemplate SONiCFileFormat + +# +# Set the default permissions for all log files. +# +$FileOwner root +$FileGroup adm +$FileCreateMode 0640 +$DirCreateMode 0755 +$Umask 0022 + +# +# Where to place spool and state files +# +$WorkDirectory /var/spool/rsyslog + +# +# Include all config files in /etc/rsyslog.d/ +# +$IncludeConfig /etc/rsyslog.d/*.conf + +# +# Suppress duplicate messages and report "message repeated n times" +# +$RepeatedMsgReduction on + +############### +#### RULES #### +############### diff --git a/dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf b/dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf new file mode 100644 index 000000000000..7c7a64d7afe0 --- /dev/null +++ b/dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf @@ -0,0 +1,9 @@ +$ModLoad imfile + +$InputFileName /var/log/supervisor/supervisord.log +$InputFileTag supervisord +$InputFileStateFile state-supervisor +$InputFileSeverity info +$InputFileFacility local0 +$InputFilePersistStateInterval 1 +$InputRunFileMonitor diff --git a/dockers/docker-base-buster/etc/supervisor/supervisord.conf b/dockers/docker-base-buster/etc/supervisor/supervisord.conf new file mode 100644 index 000000000000..5d1010e8fa4e --- /dev/null +++ b/dockers/docker-base-buster/etc/supervisor/supervisord.conf @@ -0,0 +1,33 @@ +; supervisor config file + +[unix_http_server] +file=/var/run/supervisor.sock ; (the path to the socket file) +chmod=0700 ; socket file mode (default 0700) +username=dummy +password=dummy + +[supervisord] +logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) +pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) +user=root + +; the below section must remain in the config file for RPC +; (supervisorctl/web interface) to work, additional interfaces may be +; added by defining them in separate rpcinterface: sections +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket +username=dummy +password=dummy + +; The [include] section can just contain the "files" setting. This +; setting can list multiple files (separated by whitespace or +; newlines). It can also contain wildcards. The filenames are +; interpreted as relative to this file. Included files *cannot* +; include files themselves. + +[include] +files = /etc/supervisor/conf.d/*.conf diff --git a/dockers/docker-base-buster/no-check-valid-until b/dockers/docker-base-buster/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/dockers/docker-base-buster/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/dockers/docker-base-buster/no_install_recommend_suggest b/dockers/docker-base-buster/no_install_recommend_suggest new file mode 100644 index 000000000000..b5bca577de1e --- /dev/null +++ b/dockers/docker-base-buster/no_install_recommend_suggest @@ -0,0 +1,5 @@ +# Instruct apt-get to NOT install "recommended" or "suggested" packages by +# default when installing a package. + +APT::Install-Recommends "false"; +APT::Install-Suggests "false"; diff --git a/dockers/docker-base-buster/root/.vimrc b/dockers/docker-base-buster/root/.vimrc new file mode 100644 index 000000000000..5c1ba8a04f47 --- /dev/null +++ b/dockers/docker-base-buster/root/.vimrc @@ -0,0 +1,2 @@ +" enable vim features +set nocompatible diff --git a/dockers/docker-base-buster/sources.list b/dockers/docker-base-buster/sources.list new file mode 100644 index 000000000000..4a94e3161ab1 --- /dev/null +++ b/dockers/docker-base-buster/sources.list @@ -0,0 +1,8 @@ +## Debian mirror on Microsoft Azure +## Ref: http://debian-archive.trafficmanager.net/ + +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster-backports main contrib non-free diff --git a/dockers/docker-base-buster/sources.list.arm64 b/dockers/docker-base-buster/sources.list.arm64 new file mode 100644 index 000000000000..b92971dccead --- /dev/null +++ b/dockers/docker-base-buster/sources.list.arm64 @@ -0,0 +1,7 @@ +## Debian mirror for ARM repo + +# ARM repo +deb [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb [arch=arm64] http://security.debian.org buster/updates main contrib non-free +deb-src [arch=arm64] http://security.debian.org buster/updates main contrib non-free diff --git a/dockers/docker-base-buster/sources.list.armhf b/dockers/docker-base-buster/sources.list.armhf new file mode 100644 index 000000000000..e28fd605678f --- /dev/null +++ b/dockers/docker-base-buster/sources.list.armhf @@ -0,0 +1,7 @@ +## Debian mirror for ARM repo + +# ARM repo +deb [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb [arch=armhf] http://security.debian.org buster/updates main contrib non-free +deb-src [arch=armhf] http://security.debian.org buster/updates main contrib non-free diff --git a/dockers/docker-config-engine-buster/Dockerfile.j2 b/dockers/docker-config-engine-buster/Dockerfile.j2 new file mode 100644 index 000000000000..e24414a0fc26 --- /dev/null +++ b/dockers/docker-config-engine-buster/Dockerfile.j2 @@ -0,0 +1,50 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-base-buster + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y \ + # Dependencies for sonic-cfggen + python-lxml \ + python-yaml \ + python-bitarray \ + python-pip \ + python-dev \ + python-natsort \ + apt-utils \ + python-setuptools + +RUN pip install --upgrade pip + +RUN pip install \ + netaddr \ + ipaddr \ + jinja2 \ + pyangbind==0.6.0 + +{% if docker_config_engine_buster_debs.strip() %} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_config_engine_buster_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_config_engine_buster_debs.split(' ')) }} +{% endif %} + +{% if docker_config_engine_buster_whls.strip() %} +# Copy locally-built Python wheel dependencies +{{ copy_files("python-wheels/", docker_config_engine_buster_whls.split(' '), "/python-wheels/") }} + +# Install locally-built Python wheel dependencies +{{ install_python_wheels(docker_config_engine_buster_whls.split(' ')) }} +{% endif %} + +## Clean up +RUN apt-get purge -y \ + python-pip \ + python-dev && \ + apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /debs /python-wheels diff --git a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 index 08c819c1cc14..f581a5bc4b67 100644 --- a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -10,18 +10,12 @@ RUN apt-get update RUN pip install connexion==1.1.15 \ setuptools==21.0.0 \ grpcio-tools==1.20.0 \ - pyangbind==0.6.0 \ certifi==2017.4.17 \ python-dateutil==2.6.0 \ six==1.11.0 \ urllib3==1.21.1 - -## Install redis-tools dependencies -## TODO: implicitly install dependencies -RUN apt-get -y install libjemalloc1 libatomic1 liblua5.1-0 lua-bitop lua-cjson - COPY \ {% for deb in docker_sonic_mgmt_framework_debs.split(' ') -%} debs/{{ deb }}{{' '}} diff --git a/rules/docker-base-buster.dep b/rules/docker-base-buster.dep new file mode 100644 index 000000000000..2cfd2403f7fe --- /dev/null +++ b/rules/docker-base-buster.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_BASE_BUSTER)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-base-buster.mk rules/docker-base-buster.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_BASE_BUSTER)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_BASE_BUSTER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_BASE_BUSTER)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-base-buster.mk b/rules/docker-base-buster.mk new file mode 100644 index 000000000000..e1f02d19f30e --- /dev/null +++ b/rules/docker-base-buster.mk @@ -0,0 +1,17 @@ +# Docker base image (based on Debian Buster) + +DOCKER_BASE_BUSTER = docker-base-buster.gz +$(DOCKER_BASE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-base-buster + +$(DOCKER_BASE_BUSTER)_DEPENDS += $(SUPERVISOR) $(REDIS_TOOLS) +$(DOCKER_BASE_BUSTER)_DEPENDS += $(SOCAT) + +GDB = gdb +GDBSERVER = gdbserver +VIM = vim +OPENSSH = openssh-client +SSHPASS = sshpass +STRACE = strace +$(DOCKER_BASE_BUSTER)_DBG_IMAGE_PACKAGES += $(GDB) $(GDBSERVER) $(VIM) $(OPENSSH) $(SSHPASS) $(STRACE) + +SONIC_DOCKER_IMAGES += $(DOCKER_BASE_BUSTER) diff --git a/rules/docker-config-engine-buster.dep b/rules/docker-config-engine-buster.dep new file mode 100644 index 000000000000..ae1ec40ccc9e --- /dev/null +++ b/rules/docker-config-engine-buster.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_CONFIG_ENGINE_BUSTER)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-config-engine-buster.mk rules/docker-config-engine-buster.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_CONFIG_ENGINE_BUSTER)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_CONFIG_ENGINE_BUSTER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_CONFIG_ENGINE_BUSTER)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-config-engine-buster.mk b/rules/docker-config-engine-buster.mk new file mode 100644 index 000000000000..cd4703e578a6 --- /dev/null +++ b/rules/docker-config-engine-buster.mk @@ -0,0 +1,13 @@ +# docker image for sonic config engine + +DOCKER_CONFIG_ENGINE_BUSTER = docker-config-engine-buster.gz +$(DOCKER_CONFIG_ENGINE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-config-engine-buster + +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SWSSSDK_PY2) +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +$(DOCKER_CONFIG_ENGINE_BUSTER)_LOAD_DOCKERS += $(DOCKER_BASE_BUSTER) + +$(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS = $($(DOCKER_BASE_BUSTER)_DBG_DEPENDS) +$(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES = $($(DOCKER_BASE_BUSTER)_DBG_IMAGE_PACKAGES) + +SONIC_DOCKER_IMAGES += $(DOCKER_CONFIG_ENGINE_BUSTER) diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk index f07b8d023d2d..b0e11c89f510 100644 --- a/rules/docker-sonic-mgmt-framework.mk +++ b/rules/docker-sonic-mgmt-framework.mk @@ -7,22 +7,20 @@ DOCKER_MGMT_FRAMEWORK_DBG = $(DOCKER_MGMT_FRAMEWORK_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_MGMT_FRAMEWORK)_PATH = $(DOCKERS_PATH)/$(DOCKER_MGMT_FRAMEWORK_STEM) $(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK) -$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK_DBG) SONIC_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) -$(DOCKER_MGMT_FRAMEWORK)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) -$(DOCKER_MGMT_FRAMEWORK)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_MGMT_FRAMEWORK)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) +$(DOCKER_MGMT_FRAMEWORK)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) ifeq ($(ENABLE_MGMT_FRAMEWORK), y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) -SONIC_STRETCH_DOCKERS += $(DOCKER_MGMT_FRAMEWORK) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) ifeq ($(ENABLE_MGMT_FRAMEWORK), y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_MGMT_FRAMEWORK_DBG) endif $(DOCKER_MGMT_FRAMEWORK)_CONTAINER_NAME = mgmt-framework diff --git a/slave.mk b/slave.mk index 098a5f12f064..eff78eba7da5 100644 --- a/slave.mk +++ b/slave.mk @@ -638,15 +638,15 @@ ifeq ($(BLDENV),stretch) STRETCH_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) STRETCH_DBG_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(STRETCH_DOCKER_IMAGES))) else - DOCKER_IMAGES := $(SONIC_DOCKER_IMAGES) - DOCKER_DBG_IMAGES := $(SONIC_DOCKER_DBG_IMAGES) + DOCKER_IMAGES = $(filter-out $(SONIC_JESSIE_DOCKERS) $(SONIC_STRETCH_DOCKERS),$(SONIC_DOCKER_IMAGES)) + DOCKER_DBG_IMAGES = $(filter-out $(SONIC_JESSIE_DBG_DOCKERS) $(SONIC_STRETCH_DBG_DOCKERS), $(SONIC_DOCKER_DBG_IMAGES)) endif endif -$(foreach IMAGE,$(SONIC_STRETCH_DOCKERS), $(eval $(IMAGE)_DEBS_PATH := $(STRETCH_DEBS_PATH))) -$(foreach IMAGE,$(SONIC_STRETCH_DOCKERS), $(eval $(IMAGE)_FILES_PATH := $(STRETCH_FILES_PATH))) -$(foreach IMAGE,$(SONIC_STRETCH_DBG_DOCKERS), $(eval $(IMAGE)_DEBS_PATH := $(STRETCH_DEBS_PATH))) -$(foreach IMAGE,$(SONIC_STRETCH_DBG_DOCKERS), $(eval $(IMAGE)_FILES_PATH := $(STRETCH_FILES_PATH))) +$(foreach IMAGE,$(DOCKER_IMAGES), $(eval $(IMAGE)_DEBS_PATH := $(DEBS_PATH))) +$(foreach IMAGE,$(DOCKER_IMAGES), $(eval $(IMAGE)_FILES_PATH := $(FILES_PATH))) +$(foreach IMAGE,$(DOCKER_DBG_IMAGES), $(eval $(IMAGE)_DEBS_PATH := $(DEBS_PATH))) +$(foreach IMAGE,$(DOCKER_DBG_IMAGES), $(eval $(IMAGE)_FILES_PATH := $(FILES_PATH))) # Targets for building docker images $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform docker-start \ From 93ade1d96b167af67adf3cedc818d92b252a3b46 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Tue, 28 Apr 2020 20:32:22 -0700 Subject: [PATCH 0593/1427] [Multi-ASIC] To pass the asic instance ID to orchagent, Advance the swss, swss-common submodules. (#4465) * Multi-ASIC platforms will have the ID field in the DEVICE_METADATA, which will be pulled and will be used when starting the orchagent process with the new option [-i INST_ID] This is currently added only for Broadcom ASIC based platforms * Making the asic instance ID passing global across asics/platforms. Also changed the config DB id field to asic_id * Minor updates * Advance sonic-swss submodule * Advance swss_common submodule as well due to dependencies --- dockers/docker-orchagent/orchagent.sh | 16 ++++++++++++++++ src/sonic-swss | 2 +- src/sonic-swss-common | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index e4e28a347a34..917205f3ebf2 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -17,6 +17,22 @@ ORCHAGENT_ARGS="-d /var/log/swss " # Set orchagent pop batch size to 8192 ORCHAGENT_ARGS+="-b 8192 " +# Check if there is an "asic_id field" in the DEVICE_METADATA in configDB. +#"DEVICE_METADATA": { +# "localhost": { +# .... +# "asic_id": "0", +# } +#}, +# ID field could be integers just to denote the asic instance like 0,1,2... +# OR could be PCI device ID's which will be strings like "03:00.0" +# depending on what the SAI/SDK expects. +asic_id=`sonic-cfggen -d -v DEVICE_METADATA.localhost.asic_id` +if [ -n "$asic_id" ] +then + ORCHAGENT_ARGS+="-i $asic_id " +fi + # Add platform specific arguments if necessary if [ "$platform" == "broadcom" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" diff --git a/src/sonic-swss b/src/sonic-swss index 412c5ebd1762..382905381d54 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 412c5ebd1762f94afc51b1129f54a27a53f132bb +Subproject commit 382905381d547a3c050ec23ef9bd611bb2dea67a diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 7ee11792342f..6889c0aba53c 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 7ee11792342f2673ea6905952d556e3f9a27234d +Subproject commit 6889c0aba53c96c1935374e5a442e12a97941eee From 0895033ee67e9559f2f21e246224d58cd43ea91a Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 29 Apr 2020 00:19:29 -0700 Subject: [PATCH 0594/1427] [sonic-utilities] Update submodule (#4492) * src/sonic-utilities 798ce2f...7ce5b62 (19): > [utility] Filter FDB entries (#890) > [fast reboot] set a fast-reboot DB flag (#887) > [show] Add 'ip/ipv6 bgp network' commands (#888) > [Vxlan] : adding show vnet/vxlan cmds (#880) > [show][bgp] Use only 'show ip bgp' as the base and use bgp_frr_v4 file for FRR routing stack (#884) > Revert "[config] Implement a process level lock (#857)" (#882) > [generate_dump] Dump systemd specific information (#602) > [config] Implement a process level lock (#857) > [fwutil]: Update Command-Reference.md. (#876) > Add platform options to 'show techsupport' command (#865) > [doc]: add ltgm and jenkins badge (#875) > Fix even more Python warnings (#873) > [showtech]: dump docker stats (#864) > Fix more Python warnings (#869) > Fix Python warnings (#867) > Fixes bug for PFCWD feature parameters (#838) > Explicitly specify command names with underscores (continued) (#852) > [watermarkstat] Fix issue of fields overwritten before display (#862) > [pfc] Add command line to enable/disable/show PFC (#796) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 798ce2fa0b1b..7ce5b62404b1 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 798ce2fa0b1b9a6e12deaa141c39a92c17b809e8 +Subproject commit 7ce5b62404b150782fd4a275ab3460566fa32a49 From 087e5fbf784593398e110be47d027de2e19af361 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 29 Apr 2020 11:07:08 -0700 Subject: [PATCH 0595/1427] [build]: build missing stretch dockers when debug build is enabled (#4494) $DOCKER_IMAGES_FOR_INSTALLERS contains all dockers to be included in the image. If INSTALL_DEBUG_TOOLS=y, then it contains debug docker images as well non-debug docker images when there is no debug version of that docker image. $STRETCH_DOCKER_IMAGES will have the non-debug docker images needed by the image. $STRETCH_DBG_DOCKER_IMAGES should contain the debug version of the docker images. Signed-off-by: Guohan Lu --- slave.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slave.mk b/slave.mk index eff78eba7da5..f30260157ffe 100644 --- a/slave.mk +++ b/slave.mk @@ -630,13 +630,13 @@ ifeq ($(BLDENV),) DOCKER_IMAGES := $(SONIC_JESSIE_DOCKERS) DOCKER_DBG_IMAGES := $(SONIC_JESSIE_DBG_DOCKERS) JESSIE_DOCKER_IMAGES = $(filter $(SONIC_JESSIE_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) - JESSIE_DBG_DOCKER_IMAGES = $(filter $(SONIC_JESSIE_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(JESSIE_DOCKER_IMAGES))) + JESSIE_DBG_DOCKER_IMAGES = $(filter $(SONIC_JESSIE_DBG_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) else ifeq ($(BLDENV),stretch) DOCKER_IMAGES := $(SONIC_STRETCH_DOCKERS) DOCKER_DBG_IMAGES := $(SONIC_STRETCH_DBG_DOCKERS) STRETCH_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) - STRETCH_DBG_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(STRETCH_DOCKER_IMAGES))) + STRETCH_DBG_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DBG_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) else DOCKER_IMAGES = $(filter-out $(SONIC_JESSIE_DOCKERS) $(SONIC_STRETCH_DOCKERS),$(SONIC_DOCKER_IMAGES)) DOCKER_DBG_IMAGES = $(filter-out $(SONIC_JESSIE_DBG_DOCKERS) $(SONIC_STRETCH_DBG_DOCKERS), $(SONIC_DOCKER_DBG_IMAGES)) From 4c55adfd6ea3663d885540dadabd2daff57df32c Mon Sep 17 00:00:00 2001 From: jianjundong <47590965+jianjundong@users.noreply.github.com> Date: Thu, 30 Apr 2020 02:10:35 +0800 Subject: [PATCH 0596/1427] [iccpd]: ICCPD support IPv6 ND (#4422) accomplish it according MCLAG HLD document, the principle is similar to IPv4 ARP. --- src/iccpd/include/iccp_cmd_show.h | 1 + src/iccpd/include/iccp_csm.h | 4 +- src/iccpd/include/iccp_ifm.h | 3 +- src/iccpd/include/iccp_netlink.h | 20 + src/iccpd/include/mlacp_fsm.h | 3 + src/iccpd/include/mlacp_link_handler.h | 12 +- src/iccpd/include/mlacp_sync_prepare.h | 1 + src/iccpd/include/mlacp_sync_update.h | 3 +- src/iccpd/include/mlacp_tlv.h | 27 +- src/iccpd/include/msg_format.h | 3 +- src/iccpd/include/port.h | 3 + src/iccpd/include/system.h | 1 + src/iccpd/src/iccp_cmd_show.c | 68 +++- src/iccpd/src/iccp_ifm.c | 496 +++++++++++++++++------ src/iccpd/src/iccp_netlink.c | 528 +++++++++++++++++++------ src/iccpd/src/mclagdctl/mclagdctl.c | 58 +++ src/iccpd/src/mclagdctl/mclagdctl.h | 12 + src/iccpd/src/mlacp_fsm.c | 92 ++++- src/iccpd/src/mlacp_link_handler.c | 372 ++++++++--------- src/iccpd/src/mlacp_sync_prepare.c | 63 ++- src/iccpd/src/mlacp_sync_update.c | 304 +++++++++++--- src/iccpd/src/port.c | 3 +- src/iccpd/src/scheduler.c | 2 +- src/iccpd/src/system.c | 3 + 24 files changed, 1604 insertions(+), 478 deletions(-) diff --git a/src/iccpd/include/iccp_cmd_show.h b/src/iccpd/include/iccp_cmd_show.h index 0fedca7cdddd..a41fbadf8c77 100644 --- a/src/iccpd/include/iccp_cmd_show.h +++ b/src/iccpd/include/iccp_cmd_show.h @@ -29,6 +29,7 @@ extern int iccp_mclag_config_dump(char * *buf, int *num, int mclag_id); extern int iccp_arp_dump(char * *buf, int *num, int mclag_id); +extern int iccp_ndisc_dump(char * *buf, int *num, int mclag_id); extern int iccp_mac_dump(char * *buf, int *num, int mclag_id); extern int iccp_local_if_dump(char * *buf, int *num, int mclag_id); extern int iccp_peer_if_dump(char * *buf, int *num, int mclag_id); diff --git a/src/iccpd/include/iccp_csm.h b/src/iccpd/include/iccp_csm.h index 9cf1022dd10c..96e366371933 100644 --- a/src/iccpd/include/iccp_csm.h +++ b/src/iccpd/include/iccp_csm.h @@ -45,7 +45,9 @@ #ifndef INET_ADDRSTRLEN #define INET_ADDRSTRLEN 16 #endif /* INET_ADDRSTRLEN */ - +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif /* INET6_ADDRSTRLEN */ /* For socket binding */ #define ICCP_TCP_PORT 8888 #define MAX_ACCEPT_CONNETIONS 20 diff --git a/src/iccpd/include/iccp_ifm.h b/src/iccpd/include/iccp_ifm.h index 7fbb1a8cf4f9..bbb1af67ee90 100644 --- a/src/iccpd/include/iccp_ifm.h +++ b/src/iccpd/include/iccp_ifm.h @@ -28,9 +28,10 @@ int iccp_sys_local_if_list_get_init(); -int iccp_arp_get_init(); +int iccp_neigh_get_init(); void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, uint8_t mac_addr[ETHER_ADDR_LEN]); +void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, uint8_t mac_addr[ETHER_ADDR_LEN]); int do_one_neigh_request(struct nlmsghdr *n); diff --git a/src/iccpd/include/iccp_netlink.h b/src/iccpd/include/iccp_netlink.h index 612a1859591b..a4f321736d0c 100644 --- a/src/iccpd/include/iccp_netlink.h +++ b/src/iccpd/include/iccp_netlink.h @@ -31,6 +31,25 @@ #include "../include/system.h" #include "../include/port.h" +#include +#include + +#define NDISC_NEIGHBOUR_ADVERTISEMENT 136 +#define ND_OPT_TARGET_LL_ADDR 2 +#define NEXTHDR_ICMP 58 + +struct nd_msg +{ + struct icmp6_hdr icmph; + struct in6_addr target; + __u8 opt[0]; +}; + +struct in6_pktinfo +{ + struct in6_addr ipi6_addr; /* src/dst IPv6 address */ + unsigned int ipi6_ifindex; /* send/recv interface index */ +}; int iccp_get_port_member_list(struct LocalInterface* lif); void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg); @@ -41,6 +60,7 @@ int iccp_init_netlink_event_fd(struct System *sys); int iccp_handle_events(struct System * sys); void update_if_ipmac_on_standby(struct LocalInterface* lif_po); int iccp_sys_local_if_list_get_addr(); +int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *mac, char *portname); int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInterface *lif); #endif diff --git a/src/iccpd/include/mlacp_fsm.h b/src/iccpd/include/mlacp_fsm.h index 6442d9ff560d..b335e78cd007 100644 --- a/src/iccpd/include/mlacp_fsm.h +++ b/src/iccpd/include/mlacp_fsm.h @@ -53,6 +53,7 @@ enum MLACP_SYNC_STATE MLACP_SYNC_AGGINFO, MLACP_SYNC_PEERLINKINFO, MLACP_SYNC_ARP_INFO, + MLACP_SYNC_NDISC_INFO, MLACP_SYNC_DONE, }; @@ -85,6 +86,8 @@ struct mLACP TAILQ_HEAD(mlacp_msg_list, Msg) mlacp_msg_list; TAILQ_HEAD(arp_msg_list, Msg) arp_msg_list; TAILQ_HEAD(arp_info_list, Msg) arp_list; + TAILQ_HEAD(ndisc_msg_list, Msg) ndisc_msg_list; + TAILQ_HEAD(ndisc_info_list, Msg) ndisc_list; TAILQ_HEAD(mac_msg_list, Msg) mac_msg_list; TAILQ_HEAD(mac_info_list, Msg) mac_list; diff --git a/src/iccpd/include/mlacp_link_handler.h b/src/iccpd/include/mlacp_link_handler.h index 55892d1861c8..624b4111a7ee 100644 --- a/src/iccpd/include/mlacp_link_handler.h +++ b/src/iccpd/include/mlacp_link_handler.h @@ -43,17 +43,17 @@ void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable); void peerlink_port_isolate_cleanup(struct CSM* csm); void update_peerlink_isolate_from_all_csm_lif(struct CSM* csm); -int mlacp_fsm_arp_set(char *ifname, uint32_t ip, char *mac); -int mlacp_fsm_arp_del(char *ifname, uint32_t ip); -void del_mac_from_chip(struct MACMsg* mac_msg); -void add_mac_to_chip(struct MACMsg* mac_msg, uint8_t mac_type); -uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg* mac_msg, uint8_t set ); -void iccp_get_fdb_change_from_syncd( void); +void del_mac_from_chip(struct MACMsg *mac_msg); +void add_mac_to_chip(struct MACMsg *mac_msg, uint8_t mac_type); +uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg *mac_msg, uint8_t set); +void iccp_get_fdb_change_from_syncd(void); extern int mclagd_ctl_sock_create(); extern int mclagd_ctl_sock_accept(int fd); extern int mclagd_ctl_interactive_process(int client_fd); +extern int parseMacString(const char *str_mac, uint8_t *bin_mac); char *show_ip_str(uint32_t ipv4_addr); +char *show_ipv6_str(char *ipv6_addr); void syncd_info_close(); int iccp_connect_syncd(); diff --git a/src/iccpd/include/mlacp_sync_prepare.h b/src/iccpd/include/mlacp_sync_prepare.h index f4ea7a419f51..17cd8f260155 100644 --- a/src/iccpd/include/mlacp_sync_prepare.h +++ b/src/iccpd/include/mlacp_sync_prepare.h @@ -46,6 +46,7 @@ int mlacp_prepare_for_sync_data_tlv(struct CSM* csm, char* buf, size_t max_buf_s int mlacp_prepare_for_sys_config(struct CSM* csm, char* buf, size_t max_buf_size); int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_buf_size, struct MACMsg* mac_msg, int count); int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, struct ARPMsg* arp_msg, int count); +int mlacp_prepare_for_ndisc_info(struct CSM *csm, char *buf, size_t max_buf_size, struct NDISCMsg *ndisc_msg, int count); int mlacp_prepare_for_heartbeat(struct CSM* csm, char* buf, size_t max_buf_size); int mlacp_prepare_for_Aggport_state(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* local_if); int mlacp_prepare_for_Aggport_config(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* lif, int purge_flag); diff --git a/src/iccpd/include/mlacp_sync_update.h b/src/iccpd/include/mlacp_sync_update.h index d42abe216af6..2a5d5b598d05 100644 --- a/src/iccpd/include/mlacp_sync_update.h +++ b/src/iccpd/include/mlacp_sync_update.h @@ -36,12 +36,13 @@ int mlacp_fsm_update_system_conf(struct CSM* csm, mLACPSysConfigTLV* tlv); int mlacp_fsm_update_Aggport_state(struct CSM* csm, mLACPAggPortStateTLV* tlv); int mlacp_fsm_update_arp_info(struct CSM* csm, struct mLACPARPInfoTLV* tlv); +int mlacp_fsm_update_ndisc_info(struct CSM *csm, struct mLACPNDISCInfoTLV* tlv); int mlacp_fsm_update_heartbeat(struct CSM* csm, struct mLACPHeartbeatTLV* tlv); int mlacp_fsm_update_warmboot(struct CSM* csm, struct mLACPWarmbootTLV* tlv); void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg); - +void mlacp_enqueue_ndisc(struct CSM *csm, struct Msg* msg); int mlacp_fsm_update_Agg_conf(struct CSM* csm, mLACPAggConfigTLV* portconf); int mlacp_fsm_update_port_channel_info(struct CSM* csm, struct mLACPPortChannelInfoTLV* tlv); int mlacp_fsm_update_peerlink_info(struct CSM* csm, struct mLACPPeerLinkInfoTLV* tlv); diff --git a/src/iccpd/include/mlacp_tlv.h b/src/iccpd/include/mlacp_tlv.h index 86bce2e0e943..7d3a4e18e4e2 100644 --- a/src/iccpd/include/mlacp_tlv.h +++ b/src/iccpd/include/mlacp_tlv.h @@ -374,6 +374,14 @@ struct ARPMsg uint8_t mac_addr[ETHER_ADDR_LEN]; }; +struct NDISCMsg +{ + uint8_t op_type; + char ifname[MAX_L_PORT_NAME]; + uint32_t ipv6_addr[4]; + uint8_t mac_addr[ETHER_ADDR_LEN]; +}; + /* * ARP Information TLV */ @@ -385,6 +393,17 @@ struct mLACPARPInfoTLV struct ARPMsg ArpEntry[0]; } __attribute__ ((packed)); +/* + * NDISC Information TLV + */ +struct mLACPNDISCInfoTLV +{ + ICCParameter icc_parameter; + /* Local Interface ID */ + uint16_t num_of_entry; + struct NDISCMsg NdiscEntry[0]; +} __attribute__ ((packed)); + /* * NOS: STP Information TLV */ @@ -413,11 +432,11 @@ struct mLACPWarmbootTLV uint8_t warmboot; } __attribute__ ((packed)); -enum ARP_OP_TYPE +enum NEIGH_OP_TYPE { - ARP_SYNC_LIF, - ARP_SYNC_ADD, - ARP_SYNC_DEL, + NEIGH_SYNC_LIF, + NEIGH_SYNC_ADD, + NEIGH_SYNC_DEL, }; enum MAC_AGE_TYPE diff --git a/src/iccpd/include/msg_format.h b/src/iccpd/include/msg_format.h index 5f4deb18772b..1af8bf8a46a8 100644 --- a/src/iccpd/include/msg_format.h +++ b/src/iccpd/include/msg_format.h @@ -98,7 +98,8 @@ #define TLV_T_MLACP_STP_INFO 0x1037//no support #define TLV_T_MLACP_MAC_INFO 0x1038 #define TLV_T_MLACP_WARMBOOT_FLAG 0x1039 -#define TLV_T_MLACP_LIST_END 0x104a //list end +#define TLV_T_MLACP_NDISC_INFO 0x103A +#define TLV_T_MLACP_LIST_END 0x104a // list end /* Debug */ static char* get_tlv_type_string(int type) diff --git a/src/iccpd/include/port.h b/src/iccpd/include/port.h index bdcaf66a68ad..dbd9d45fa83d 100644 --- a/src/iccpd/include/port.h +++ b/src/iccpd/include/port.h @@ -102,6 +102,8 @@ struct LocalInterface uint8_t state; uint32_t ipv4_addr; uint8_t prefixlen; + uint32_t ipv6_addr[4]; + uint8_t prefixlen_v6; uint8_t l3_mode; uint8_t l3_mac_addr[ETHER_ADDR_LEN]; @@ -139,6 +141,7 @@ int local_if_is_l3_mode(struct LocalInterface* local_if); void local_if_init(struct LocalInterface*); void local_if_finalize(struct LocalInterface*); +void ether_mac_set_addr_with_if_name(char *name, uint8_t* mac); struct PeerInterface* peer_if_create(struct CSM* csm, int peer_if_number, int type); struct PeerInterface* peer_if_find_by_name(struct CSM* csm, char* name); diff --git a/src/iccpd/include/system.h b/src/iccpd/include/system.h index bb89dbb2f3c2..3ee314d253aa 100644 --- a/src/iccpd/include/system.h +++ b/src/iccpd/include/system.h @@ -58,6 +58,7 @@ struct System int sync_fd; int sync_ctrl_fd; int arp_receive_fd; + int ndisc_receive_fd; int epoll_fd; struct nl_sock * genric_sock; diff --git a/src/iccpd/src/iccp_cmd_show.c b/src/iccpd/src/iccp_cmd_show.c index e25a653e74b3..b0a60fb5f49c 100644 --- a/src/iccpd/src/iccp_cmd_show.c +++ b/src/iccpd/src/iccp_cmd_show.c @@ -177,7 +177,7 @@ int iccp_arp_dump(char * *buf, int *num, int mclag_id) mclagd_arp.op_type = iccpd_arp->op_type; memcpy(mclagd_arp.ifname, iccpd_arp->ifname, strlen(iccpd_arp->ifname)); - memcpy(mclagd_arp.ipv4_addr, show_ip_str(htonl(iccpd_arp->ipv4_addr)), 16); + memcpy(mclagd_arp.ipv4_addr, show_ip_str(iccpd_arp->ipv4_addr), 16); memcpy(mclagd_arp.mac_addr, iccpd_arp->mac_addr, 6); memcpy(arp_buf + MCLAGD_REPLY_INFO_HDR + arp_num * sizeof(struct mclagd_arp_msg), @@ -204,6 +204,72 @@ int iccp_arp_dump(char * *buf, int *num, int mclag_id) return EXEC_TYPE_SUCCESS; } +int iccp_ndisc_dump(char * *buf, int *num, int mclag_id) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct NDISCMsg *iccpd_ndisc = NULL; + struct mclagd_ndisc_msg mclagd_ndisc; + int ndisc_num = 0; + int id_exist = 0; + char *ndisc_buf = NULL; + int ndisc_buf_size = MCLAGDCTL_CMD_SIZE; + + if (!(sys = system_get_instance())) + { + ICCPD_LOG_INFO(__FUNCTION__, "cannot find sys!\n"); + return EXEC_TYPE_NO_EXIST_SYS; + } + + ndisc_buf = (char *)malloc(ndisc_buf_size); + if (!ndisc_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + memset(&mclagd_ndisc, 0, sizeof(struct mclagd_ndisc_msg)); + iccpd_ndisc = (struct NDISCMsg *)msg->buf; + + mclagd_ndisc.op_type = iccpd_ndisc->op_type; + memcpy(mclagd_ndisc.ifname, iccpd_ndisc->ifname, strlen(iccpd_ndisc->ifname)); + memcpy(mclagd_ndisc.ipv6_addr, show_ipv6_str((char *)iccpd_ndisc->ipv6_addr), 46); + memcpy(mclagd_ndisc.mac_addr, iccpd_ndisc->mac_addr, 6); + + memcpy(ndisc_buf + MCLAGD_REPLY_INFO_HDR + ndisc_num * sizeof(struct mclagd_ndisc_msg), + &mclagd_ndisc, sizeof(struct mclagd_ndisc_msg)); + + ndisc_num++; + + if ((ndisc_num + 1) * sizeof(struct mclagd_ndisc_msg) > (ndisc_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + ndisc_buf_size += MCLAGDCTL_CMD_SIZE; + ndisc_buf = (char *)realloc(ndisc_buf, ndisc_buf_size); + if (!ndisc_buf) + return EXEC_TYPE_FAILED; + } + } + } + + *buf = ndisc_buf; + *num = ndisc_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + int iccp_mac_dump(char * *buf, int *num, int mclag_id) { struct System *sys = NULL; diff --git a/src/iccpd/src/iccp_ifm.c b/src/iccpd/src/iccp_ifm.c index cf874366b97b..5cfbfe81ffd3 100644 --- a/src/iccpd/src/iccp_ifm.c +++ b/src/iccpd/src/iccp_ifm.c @@ -137,34 +137,21 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int memset(buf, 0, MAX_BUFSIZE); msg_len = sizeof(struct ARPMsg); arp_msg = (struct ARPMsg*)&buf; - arp_msg->op_type = ARP_SYNC_LIF; + arp_msg->op_type = NEIGH_SYNC_LIF; sprintf(arp_msg->ifname, "%s", arp_lif->name); if (tb[NDA_DST]) memcpy(&arp_msg->ipv4_addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); if (tb[NDA_LLADDR]) memcpy(arp_msg->mac_addr, RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR])); - arp_msg->ipv4_addr = ntohl(arp_msg->ipv4_addr); + arp_msg->ipv4_addr = arp_msg->ipv4_addr; - ICCPD_LOG_DEBUG(__FUNCTION__, "ARP type %s, state (%04X)(%d) ifindex [%d] (%s) ip %s, mac [%02X:%02X:%02X:%02X:%02X:%02X]", + ICCPD_LOG_NOTICE(__FUNCTION__, "ARP type %s, state (%04X)(%d) ifindex [%d] (%s) ip %s, mac [%02X:%02X:%02X:%02X:%02X:%02X]", msgtype == RTM_NEWNEIGH ? "New":"Del", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state), ndm->ndm_ifindex, arp_lif->name, - show_ip_str(htonl(arp_msg->ipv4_addr)), - arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - - /*Debug*/ - #if 0 - /* dump receive kernel ARP req*/ - fprintf(stderr, "\n======== Kernel ARP ==========\n"); - fprintf(stderr, " Type = [%d] (New=%d, Del=%d)\n", msgtype, RTM_NEWNEIGH, RTM_DELNEIGH); - fprintf(stderr, " State = (%04X)(%d)\n", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state)); - fprintf(stderr, " ifindex = [%d] (%s)\n", ndm->ndm_ifindex, arp_msg->ifname); - fprintf(stderr, " IP = [%s]\n", show_ip_str(htonl(arp_msg->ipv4_addr))); - fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", - arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], - arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - fprintf(stderr, "==============================\n"); - #endif + show_ip_str(arp_msg->ipv4_addr), + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], + arp_msg->mac_addr[5]); /* Find MLACP itf, member of port-channel*/ LIST_FOREACH(csm, &(sys->csm_list), next) @@ -228,7 +215,7 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int free(msg->buf); free(msg); msg = NULL; - ICCPD_LOG_DEBUG(__FUNCTION__, "Delete ARP %s", show_ip_str(htonl(arp_msg->ipv4_addr))); + ICCPD_LOG_DEBUG(__FUNCTION__, "Delete ARP %s", show_ip_str(arp_msg->ipv4_addr)); } else { @@ -242,7 +229,7 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int arp_info->op_type = arp_msg->op_type; sprintf(arp_info->ifname, "%s", arp_msg->ifname); memcpy(arp_info->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); - ICCPD_LOG_DEBUG(__FUNCTION__, "Update ARP for %s", show_ip_str(htonl(arp_msg->ipv4_addr))); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update ARP for %s", show_ip_str(arp_msg->ipv4_addr)); } } break; @@ -256,31 +243,31 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int /* enquene lif_msg (add)*/ if (!msg) { - arp_msg->op_type = ARP_SYNC_LIF; + arp_msg->op_type = NEIGH_SYNC_LIF; if (iccp_csm_init_msg(&msg, (char*)arp_msg, msg_len) == 0) { mlacp_enqueue_arp(csm, msg); /*ICCPD_LOG_DEBUG(__FUNCTION__, "ARP-list enqueue: %s, add %s", - arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP-list: %s, add %s", - arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr))); + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr)); } /* enqueue iccp_msg (add)*/ if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) { - arp_msg->op_type = ARP_SYNC_ADD; + arp_msg->op_type = NEIGH_SYNC_ADD; if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) { TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[ADD] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + show_ip_str(arp_msg->ipv4_addr)); } } @@ -289,58 +276,218 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int /* enqueue iccp_msg (delete)*/ if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) { - arp_msg->op_type = ARP_SYNC_DEL; + arp_msg->op_type = NEIGH_SYNC_DEL; if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) { TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[DEL] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[DEL] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + show_ip_str(arp_msg->ipv4_addr)); } } - /*Debug: dump for dequeue ARP Info*/ - #if 0 - fprintf(stderr, "\n======== ARP Info List ========\n"); - TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + return; +} + +static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int msgtype) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, *ndisc_info = NULL; + struct VLAN_ID *vlan_id_list = NULL; + struct Msg *msg_send = NULL; + + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + + struct LocalInterface *lif_po = NULL, *ndisc_lif = NULL; + + int verify_neigh = 0; + int neigh_update = 0; + + if (!(sys = system_get_instance())) + return; + + /* Find local itf */ + if (!(ndisc_lif = local_if_find_by_ifindex(ndm->ndm_ifindex))) + return; + + /* create NDISC msg */ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct NDISCMsg); + ndisc_msg = (struct NDISCMsg *)&buf; + ndisc_msg->op_type = NEIGH_SYNC_LIF; + sprintf(ndisc_msg->ifname, "%s", ndisc_lif->name); + if (tb[NDA_DST]) + memcpy(&ndisc_msg->ipv6_addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); + if (tb[NDA_LLADDR]) + memcpy(ndisc_msg->mac_addr, RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR])); + + ICCPD_LOG_NOTICE(__FUNCTION__, "ndisc type %s, state (%04X)(%d), ifindex [%d] (%s), ip %s, mac [%02X:%02X:%02X:%02X:%02X:%02X]", + msgtype == RTM_NEWNEIGH ? "New" : "Del", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state), + ndm->ndm_ifindex, ndisc_lif->name, + show_ipv6_str((char *)ndisc_msg->ipv6_addr), + ndisc_msg->mac_addr[0], ndisc_msg->mac_addr[1], ndisc_msg->mac_addr[2], ndisc_msg->mac_addr[3], ndisc_msg->mac_addr[4], + ndisc_msg->mac_addr[5]); + + /* Find MLACP itf, member of port-channel */ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (!local_if_is_l3_mode(lif_po)) + { + /* Is the L2 MLAG itf belong to a vlan? */ + LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next) + { + if (!(vlan_id_list->vlan_itf && vlan_id_list->vlan_itf->ifindex == ndm->ndm_ifindex)) + continue; + break; + } + + if (!vlan_id_list) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled member port of vlan %s", vlan_id_list->vlan_itf->name); + } + else + { + /* Is the ND belong to a L3 mode MLAG itf? */ + if (ndm->ndm_ifindex != lif_po->ifindex) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled intf %s", lif_po->name); + } + + verify_neigh = 1; + + break; + } + + if (lif_po) + break; + } + + if (!(csm && lif_po)) + return; + if (!verify_neigh) + return; + + /* update lif ND */ + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) { - arp_msg = (struct ARPMsg*)msg->buf; - fprintf(stderr, "type %d,ifname %s , ip %s\n", arp_msg->op_type, arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr))); + ndisc_info = (struct NDISCMsg *)msg->buf; + + if (memcmp(&ndisc_info->ipv6_addr, &ndisc_msg->ipv6_addr, 16) != 0) + continue; + + if (msgtype == RTM_DELNEIGH) + { + /* delete ND */ + TAILQ_REMOVE(&MLACP(csm).ndisc_list, msg, tail); + free(msg->buf); + free(msg); + msg = NULL; + ICCPD_LOG_DEBUG(__FUNCTION__, "Delete neighbor %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + else + { + /* update ND */ + if (ndisc_info->op_type != ndisc_info->op_type + || strcmp(ndisc_info->ifname, ndisc_info->ifname) != 0 + || memcmp(ndisc_info->mac_addr, ndisc_info->mac_addr, ETHER_ADDR_LEN) != 0) + { + neigh_update = 1; + ndisc_info->op_type = ndisc_msg->op_type; + sprintf(ndisc_info->ifname, "%s", ndisc_msg->ifname); + memcpy(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update neighbor for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + } + break; } - fprintf(stderr, "==============================\n"); - #endif - /*TEST dump for dequeue ARP message*/ - #if 0 + if (msg && !neigh_update) + return; - while (MLACP(csm).arp_updated && !TAILQ_EMPTY(&(MLACP(csm).arp_msg_list))) + if (msgtype != RTM_DELNEIGH) { - msg = TAILQ_FIRST(&(MLACP(csm).arp_msg_list)); - TAILQ_REMOVE(&(MLACP(csm).arp_msg_list), msg, tail); - arp_msg = (struct ARPMsg *)msg->buf; - fprintf(stderr, "\n======== Dequeue ARP ========\n"); - fprintf(stderr, " Type = [%d]\n", arp_msg->op_type); - fprintf(stderr, " State = (%04X)(%d)\n", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state)); - fprintf(stderr, " ifname = [%s]\n", arp_msg->ifname); - fprintf(stderr, " IP = [%s]\n", show_ip_str(arp_msg->ipv4_addr)); - fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", - arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], - arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - fprintf(stderr, "==============================\n"); - free(msg->buf); - free(msg); + /* enquene lif_msg (add) */ + if (!msg) + { + ndisc_msg->op_type = NEIGH_SYNC_LIF; + if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, msg_len) == 0) + { + mlacp_enqueue_ndisc(csm, msg); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Ndisc-list enqueue: %s, add %s", ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc-list: %s, add %s", + ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + + /* enqueue iccp_msg (add) */ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + ndisc_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue Ndisc[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc[ADD] message for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + + } } + else + { + /* enqueue iccp_msg (delete) */ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + ndisc_msg->op_type = NEIGH_SYNC_DEL; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue Ndisc[DEL] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc[DEL] message for [%x:%x:%x:%x]", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); - MLACP(csm).arp_updated = 0; - #endif + } + } return; } +int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta, int len, unsigned short flags) +{ + unsigned short type; + + memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); + while (RTA_OK(rta, len)) + { + type = rta->rta_type & ~flags; + if ((type <= max) && (!tb[type])) + tb[type] = rta; + rta = RTA_NEXT(rta, len); + } + return 0; +} + +int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) +{ + return parse_rtattr_flags(tb, max, rta, len, 0); +} + void ifm_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len) { while (RTA_OK(rta, len)) @@ -392,11 +539,14 @@ int do_one_neigh_request(struct nlmsghdr *n) do_arp_learn_from_kernel(ndm, tb, n->nlmsg_type); } + if (ndm->ndm_family == AF_INET6) + { + do_ndisc_learn_from_kernel(ndm, tb, n->nlmsg_type); + } return(0); } -/*Handle arp received from kernel*/ -static int iccp_arp_valid_handler(struct nl_msg *msg, void *arg) +static int iccp_neigh_valid_handler(struct nl_msg *msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); @@ -405,8 +555,7 @@ static int iccp_arp_valid_handler(struct nl_msg *msg, void *arg) return 0; } -/*Get kernel arp information during initialization*/ -int iccp_arp_get_init() +int iccp_neigh_get_init() { struct System *sys = NULL; struct nl_cb *cb; @@ -440,7 +589,7 @@ int iccp_arp_get_init() return -ENOMEM; } - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_arp_valid_handler, sys); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_neigh_valid_handler, sys); ret = nl_recvmsgs(sys->route_sock, cb); nl_cb_put(cb); @@ -485,27 +634,16 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui memset(buf, 0, MAX_BUFSIZE); msg_len = sizeof(struct ARPMsg); arp_msg = (struct ARPMsg*)&buf; - arp_msg->op_type = ARP_SYNC_LIF; + arp_msg->op_type = NEIGH_SYNC_LIF; sprintf(arp_msg->ifname, "%s", arp_lif->name); memcpy(&arp_msg->ipv4_addr, &addr, 4); memcpy(arp_msg->mac_addr, mac_addr, 6); ICCPD_LOG_DEBUG(__FUNCTION__, "ARP ifindex [%d] (%s) ip %s mac [%02X:%02X:%02X:%02X:%02X:%02X]", ifindex, arp_lif->name, - show_ip_str(htonl(arp_msg->ipv4_addr)), - arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - /*Debug*/ - #if 0 - /* dump receive kernel ARP req*/ - fprintf(stderr, "\n======== Kernel ARP Update==========\n"); - fprintf(stderr, " Type = (New=%d)\n", RTM_NEWNEIGH); - fprintf(stderr, " ifindex = [%d] (%s)\n", ifindex, arp_lif->name); - fprintf(stderr, " IP = [%s]\n", show_ip_str(htonl(arp_msg->ipv4_addr))); - fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", - arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], - arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - fprintf(stderr, "==============================\n"); - #endif + show_ip_str(arp_msg->ipv4_addr), + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], + arp_msg->mac_addr[5]); /* Find MLACP itf, member of port-channel*/ LIST_FOREACH(csm, &(sys->csm_list), next) @@ -556,7 +694,7 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui if (iccp_check_if_addr_from_netlink(AF_INET, &addr, arp_lif)) { ICCPD_LOG_DEBUG(__FUNCTION__, "ARP %s is identical with the ip address of interface %s", - show_ip_str(htonl(arp_msg->ipv4_addr)), arp_lif->name); + show_ip_str(arp_msg->ipv4_addr), arp_lif->name); return; } @@ -576,8 +714,9 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui arp_info->op_type = arp_msg->op_type; sprintf(arp_info->ifname, "%s", arp_msg->ifname); memcpy(arp_info->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); - ICCPD_LOG_DEBUG(__FUNCTION__, "Update ARP for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + ICCPD_LOG_NOTICE(__FUNCTION__, "Update ARP for %s by ARP reply, intf %s mac [%02X:%02X:%02X:%02X:%02X:%02X]", + show_ip_str(arp_msg->ipv4_addr), arp_msg->ifname, + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); } break; } @@ -585,36 +724,196 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui /* enquene lif_msg (add)*/ if (!msg) { - arp_msg->op_type = ARP_SYNC_LIF; + arp_msg->op_type = NEIGH_SYNC_LIF; if (iccp_csm_init_msg(&msg, (char*)arp_msg, msg_len) == 0) { mlacp_enqueue_arp(csm, msg); /*ICCPD_LOG_DEBUG(__FUNCTION__, "ARP-list enqueue: %s, add %s", - arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP-list: %s, add %s", - arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr))); + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr)); } /* enqueue iccp_msg (add)*/ if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) { - arp_msg->op_type = ARP_SYNC_ADD; + arp_msg->op_type = NEIGH_SYNC_ADD; if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) { TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[ADD] for %s", - show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + show_ip_str(arp_msg->ipv4_addr)); } return; } +void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, uint8_t mac_addr[ETHER_ADDR_LEN]) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, *ndisc_info = NULL; + struct VLAN_ID *vlan_id_list = NULL; + struct Msg *msg_send = NULL; + char mac_str[18] = ""; + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + + struct LocalInterface *lif_po = NULL, *ndisc_lif = NULL; + + int verify_ndisc = 0; + + if (!(sys = system_get_instance())) + return; + + /* Find local itf */ + if (!(ndisc_lif = local_if_find_by_ifindex(ifindex))) + return; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + + /* create Ndisc msg */ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct NDISCMsg); + ndisc_msg = (struct NDISCMsg *)&buf; + ndisc_msg->op_type = NEIGH_SYNC_LIF; + sprintf(ndisc_msg->ifname, "%s", ndisc_lif->name); + memcpy((char *)ndisc_msg->ipv6_addr, ipv6_addr, 16); + memcpy(ndisc_msg->mac_addr, mac_addr, ETHER_ADDR_LEN); + + ICCPD_LOG_DEBUG(__FUNCTION__, "nd ifindex [%d] (%s) ip %s mac %s", + ifindex, ndisc_lif->name, show_ipv6_str(ipv6_addr), mac_str); + + /* Find MLACP itf, member of port-channel */ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (!local_if_is_l3_mode(lif_po)) + { + /* Is the L2 MLAG itf belong to a vlan? */ + LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next) + { + if (!(vlan_id_list->vlan_itf && vlan_id_list->vlan_itf->ifindex == ifindex)) + continue; + break; + } + + if (!vlan_id_list) + continue; + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled port %s of vlan %s", lif_po->name, vlan_id_list->vlan_itf->name); + } + else + { + /* Is the ND belong to a L3 mode MLAG itf? */ + if (ifindex != lif_po->ifindex) + continue; + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled port %s", lif_po->name); + } + + verify_ndisc = 1; + + break; + } + + if (lif_po) + break; + } + + if (!(csm && lif_po)) + return; + if (!verify_ndisc) + return; + + if (iccp_check_if_addr_from_netlink(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, ndisc_lif)) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "NA %s is identical with the ipv6 address of interface %s", + show_ipv6_str((char *)ndisc_msg->ipv6_addr), ndisc_lif->name); + return; + } + + /* update lif ND */ + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_info = (struct NDISCMsg *)msg->buf; + + if (memcmp((char *)ndisc_info->ipv6_addr, (char *)ndisc_msg->ipv6_addr, 16) != 0) + continue; + + /* If MAC addr is NULL, use the old one */ + if (memcmp(mac_addr, null_mac, ETHER_ADDR_LEN) == 0) + { + memcpy(ndisc_msg->mac_addr, ndisc_info->mac_addr, ETHER_ADDR_LEN); + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", ndisc_info->mac_addr[0], ndisc_info->mac_addr[1], + ndisc_info->mac_addr[2], ndisc_info->mac_addr[3], ndisc_info->mac_addr[4], ndisc_info->mac_addr[5]); + } + + /* update ND */ + if (ndisc_info->op_type != ndisc_msg->op_type + || strcmp(ndisc_info->ifname, ndisc_msg->ifname) != 0 + || memcmp(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN) != 0) + { + ndisc_info->op_type = ndisc_msg->op_type; + sprintf(ndisc_info->ifname, "%s", ndisc_msg->ifname); + memcpy(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update ND for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + break; + } + + /* enquene lif_msg (add) */ + if (!msg) + { + /* If MAC addr is NULL, and same ipv6 item is not exist in ndisc_list */ + if (memcmp(mac_addr, null_mac, ETHER_ADDR_LEN) == 0) + { + return; + } + + ndisc_msg->op_type = NEIGH_SYNC_LIF; + if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, msg_len) == 0) + { + mlacp_enqueue_ndisc(csm, msg); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "NDISC-list enqueue: %s, add %s", ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue NDISC-list: %s, add %s", ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + + if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 1, ndisc_msg->mac_addr, ndisc_msg->ifname) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to add ND entry(%s, %s, %s) to kernel", + ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr), mac_str); + return; + } + + /* enqueue iccp_msg (add) */ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + ndisc_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ND[ADD] message for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + + return; +} void iccp_from_netlink_port_state_handler( char * ifname, int state) { struct CSM *csm = NULL; @@ -656,29 +955,6 @@ void iccp_from_netlink_port_state_handler( char * ifname, int state) return; } -int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta, - int len, unsigned short flags) -{ - unsigned short type; - - memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); - - while (RTA_OK(rta, len)) - { - type = rta->rta_type & ~flags; - if ((type <= max) && (!tb[type])) - tb[type] = rta; - rta = RTA_NEXT(rta, len); - } - - return 0; -} - -int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) -{ - return parse_rtattr_flags(tb, max, rta, len, 0); -} - void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n) { struct LocalInterface *lif = NULL; @@ -759,4 +1035,4 @@ void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n) n = NLMSG_NEXT(n, msglen); } -} \ No newline at end of file +} diff --git a/src/iccpd/src/iccp_netlink.c b/src/iccpd/src/iccp_netlink.c index ec8971d0ceee..002c254ae9c1 100644 --- a/src/iccpd/src/iccp_netlink.c +++ b/src/iccpd/src/iccp_netlink.c @@ -35,15 +35,18 @@ #include #include #include +#include +#include #include #include -#include #include #include #include #include #include +#include +#include #include "../include/system.h" #include "../include/iccp_ifm.h" @@ -53,6 +56,8 @@ #include "../include/scheduler.h" #include "../include/mlacp_link_handler.h" #include "../include/msg_format.h" +#include "../include/iccp_netlink.h" + /** * SECTION: Netlink helpers */ @@ -324,13 +329,6 @@ int iccp_get_portchannel_member_list_handler(struct nl_msg *msg, void * arg) { memset(local_if->portchannel_member_buf, 0, 512); memcpy(local_if->portchannel_member_buf, temp_buf, sizeof(local_if->portchannel_member_buf) - 1); - #if 0 - if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) - { - /*peerlink portchannel member changed*/ - update_peerlink_isolate_from_all_csm_lif(csm); - } - #endif } } } @@ -491,7 +489,7 @@ void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr ) dst_len = strlen(mac_addr); memcpy(sub_msg->data, mac_addr, dst_len); - ICCPD_LOG_DEBUG(__FUNCTION__, "If name %s ip %s mac %s", lif->name, show_ip_str(htonl(lif->ipv4_addr)), sub_msg->data); + ICCPD_LOG_NOTICE(__FUNCTION__, "If name %s ip %s mac %s", lif->name, show_ip_str(htonl(lif->ipv4_addr)), sub_msg->data); sub_msg->op_len = dst_len; msg_hdr->len += sizeof(mclag_sub_option_hdr_t); @@ -504,6 +502,51 @@ void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr ) return; } +int iccp_netlink_if_startup_set(uint32_t ifindex) +{ + struct rtnl_link *link; + int err; + struct System *sys = NULL; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + link = rtnl_link_alloc(); + if (!link) + return -ENOMEM; + + rtnl_link_set_ifindex(link, ifindex); + rtnl_link_set_flags(link, IFF_UP); + + err = rtnl_link_change(sys->route_sock, link, link, 0); + +errout: + rtnl_link_put(link); + return err; +} + +int iccp_netlink_if_shutdown_set(uint32_t ifindex) +{ + struct rtnl_link *link; + int err; + struct System *sys = NULL; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + link = rtnl_link_alloc(); + if (!link) + return -ENOMEM; + + rtnl_link_set_ifindex(link, ifindex); + rtnl_link_unset_flags(link, IFF_UP); + + err = rtnl_link_change(sys->route_sock, link, link, 0); + +errout: + rtnl_link_put(link); + return err; +} void update_if_ipmac_on_standby(struct LocalInterface* lif_po) { struct CSM* csm; @@ -535,7 +578,7 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po) /*Backup old sysmac*/ memcpy(lif_po->mac_addr_ori, lif_po->mac_addr, ETHER_ADDR_LEN); - ICCPD_LOG_DEBUG(__FUNCTION__, + ICCPD_LOG_NOTICE(__FUNCTION__, "%s Change the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X].", (csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active", lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2], lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5], @@ -546,6 +589,10 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po) { ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", lif_po->name, ret); } + + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(lif_po->ifindex); + iccp_netlink_if_startup_set(lif_po->ifindex); } /*Set portchannel ip mac */ @@ -576,8 +623,12 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po) { ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret); } - - iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr ); + + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(vlan->vlan_itf->ifindex); + iccp_netlink_if_startup_set(vlan->vlan_itf->ifindex); + + iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr); memcpy(vlan->vlan_itf->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN); } } @@ -611,7 +662,7 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) /*Recover mac to origin mac, it is the 'mac' value in 'localhost' currently*/ if (memcmp( lif_po->mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN) != 0) { - ICCPD_LOG_DEBUG(__FUNCTION__, + ICCPD_LOG_NOTICE(__FUNCTION__, "%s Recover the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X].", (csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active", lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2], lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5], @@ -622,6 +673,10 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) { ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", lif_po->name, ret); } + + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(lif_po->ifindex); + iccp_netlink_if_startup_set(lif_po->ifindex); } /*Set portchannel ip mac */ @@ -648,6 +703,10 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret); } + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(vlan->vlan_itf->ifindex); + iccp_netlink_if_startup_set(vlan->vlan_itf->ifindex); + iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr); memcpy(vlan->vlan_itf->l3_mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN); } @@ -657,6 +716,80 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) return; } +int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *mac, char *portname) +{ + struct System *sys = NULL; + struct rtnl_neigh *neigh = NULL; + struct nl_addr *nl_addr_mac = NULL; + struct nl_addr *nl_addr_dst = NULL; + struct LocalInterface *lif = NULL; + struct nl_cache *link_cache; + char mac_str[18] = ""; + int err = 0; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + lif = local_if_find_by_name(portname); + if (!lif) + return MCLAG_ERROR; + + neigh = rtnl_neigh_alloc(); + if (!neigh) + { + ICCPD_LOG_INFO(__FUNCTION__, "Unable to allocate neighbour object"); + return MCLAG_ERROR; + } + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Notify kernel %s %s entry(ip:%s, mac:%s, intf:%s)", + add ? "add" : "del", (family == AF_INET) ? "ARP" : "ND", + (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, portname); + + nl_addr_mac = nl_addr_build(AF_LLC, (void *)mac, ETHER_ADDR_LEN); + if (!nl_addr_mac) + { + err = MCLAG_ERROR; + goto errout; + } + + if (family == AF_INET) + nl_addr_dst = nl_addr_build(family, (void *)addr, 4); + else + nl_addr_dst = nl_addr_build(family, (void *)addr, 16); + + if (!nl_addr_dst) + { + err = MCLAG_ERROR; + goto errout; + } + + rtnl_neigh_set_lladdr(neigh, nl_addr_mac); + rtnl_neigh_set_dst(neigh, nl_addr_dst); + rtnl_neigh_set_ifindex(neigh, lif->ifindex); + rtnl_neigh_set_state(neigh, NUD_REACHABLE); + + if (add) + { + if ((err = rtnl_neigh_add(sys->route_sock, neigh, NLM_F_REPLACE | NLM_F_CREATE)) < 0) + ICCPD_LOG_WARN(__FUNCTION__, "Add %s (ip:%s, mac:%s) error, err = %d", (family == AF_INET) ? "ARP" : "ND", + (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, err); + } + else + { + if ((err = rtnl_neigh_delete(sys->route_sock, neigh, 0)) < 0) + ICCPD_LOG_WARN(__FUNCTION__, "Del %s (ip:%s, mac:%s) error, err = %d", (family == AF_INET) ? "ARP" : "ND", + (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, err); + } + +errout: + nl_addr_put(nl_addr_mac); + nl_addr_put(nl_addr_dst); + rtnl_neigh_put(neigh); + return err; +} + void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg) { struct rtnl_link *link; @@ -789,6 +922,103 @@ void iccp_event_handler_obj_input_dellink(struct nl_object *obj, void *arg) return; } +void iccp_event_handler_obj_input_newaddr(struct nl_object *obj, void *arg) +{ + struct rtnl_addr *addr; + struct nl_addr *nl_addr; + struct LocalInterface *lif; + uint32_t ifindex; + char addrStr[65] = { 0 }; + char addr_null[16] = { 0 }; + addr = (struct rtnl_addr *)obj; + + ifindex = rtnl_addr_get_ifindex(addr); + nl_addr = rtnl_addr_get_local(addr); + + if (!(lif = local_if_find_by_ifindex(ifindex))) + return; + + if (rtnl_addr_get_family(addr) == AF_INET) + { + lif->ipv4_addr = *(uint32_t *) nl_addr_get_binary_addr(nl_addr); + lif->prefixlen = nl_addr_get_prefixlen(nl_addr); + lif->l3_mode = 1; + lif->port_config_sync = 1; + if (memcmp((char *)lif->ipv6_addr, addr_null, 16) == 0) + update_if_ipmac_on_standby(lif); + ICCPD_LOG_DEBUG(__FUNCTION__, "Ifname %s index %d address %s", lif->name, lif->ifindex, show_ip_str(lif->ipv4_addr)); + } + else if (rtnl_addr_get_family(addr) == AF_INET6) + { + if (memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "FE80", 4) == 0 + || memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "fe80", 4) == 0) + return; + + memcpy((char *)lif->ipv6_addr, nl_addr_get_binary_addr(nl_addr), 16); + lif->prefixlen = nl_addr_get_prefixlen(nl_addr); + lif->l3_mode = 1; + lif->port_config_sync = 1; + if (lif->ipv4_addr == 0) + update_if_ipmac_on_standby(lif); + ICCPD_LOG_DEBUG(__FUNCTION__, "Ifname %s index %d address %s", lif->name, lif->ifindex, show_ipv6_str((char *)lif->ipv6_addr)); + } + + return; +} + +void iccp_event_handler_obj_input_deladdr(struct nl_object *obj, void *arg) +{ + struct rtnl_addr *addr; + struct nl_addr *nl_addr; + struct LocalInterface *lif; + uint32_t ifindex; + char addr_null[16] = { 0 }; + + addr = (struct rtnl_addr *)obj; + + ifindex = rtnl_addr_get_ifindex(addr); + nl_addr = rtnl_addr_get_local(addr); + + if (!(lif = local_if_find_by_ifindex(ifindex))) + return; + + if (rtnl_addr_get_family(addr) == AF_INET) + { + lif->ipv4_addr = 0; + lif->prefixlen = 0; + } + else if (rtnl_addr_get_family(addr) == AF_INET6) + { + if (memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "FE80", 4) == 0 + || memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "fe80", 4) == 0) + return; + + memset((char *)lif->ipv6_addr, 0, 16); + lif->prefixlen_v6 = 0; + } + + if (lif->ipv4_addr == 0 && memcmp((char *)lif->ipv6_addr, addr_null, 16) == 0) + { + lif->l3_mode = 0; + memset(lif->l3_mac_addr, 0, ETHER_ADDR_LEN); + } + + return; +} + +int iccp_addr_valid_handler(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + unsigned int event = 0; + if (nlh->nlmsg_type != RTM_NEWADDR) + return 0; + + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newaddr, &event) < 0) + ICCPD_LOG_ERR(__FUNCTION__, "Unknown message type."); + + return 0; +} + int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInterface *lif) { struct @@ -893,61 +1123,6 @@ int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInter return 0; } -int iccp_local_if_addr_update(struct nl_msg *msg, void *arg) -{ - int len; - struct ifaddrmsg *ifa; - struct LocalInterface *lif; - - struct nlmsghdr *n = nlmsg_hdr(msg); - - if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) - return 0; - - ifa = NLMSG_DATA(n); - - if (ifa->ifa_family != AF_INET ) - return 0; - - lif = local_if_find_by_ifindex(ifa->ifa_index); - if (!lif) - { - return 0; - } - - if (n->nlmsg_type == RTM_DELADDR) - { - lif->ipv4_addr = 0; - lif->prefixlen = 0; - lif->l3_mode = 0; - memset(lif->l3_mac_addr, 0, ETHER_ADDR_LEN); - } - - len = n->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - if (len < 0) - return 0; - - struct rtattr *rth = IFA_RTA(ifa); - int rtl = IFA_PAYLOAD(n); - - while (rtl && RTA_OK(rth, rtl)) - { - if (rth->rta_type == IFA_ADDRESS) - { - uint32_t ipaddr = ntohl(*((uint32_t *)RTA_DATA(rth))); - lif->ipv4_addr = ipaddr; - lif->prefixlen = ifa->ifa_prefixlen; - lif->l3_mode = 1; - lif->port_config_sync = 1; - update_if_ipmac_on_standby(lif); - ICCPD_LOG_DEBUG(__FUNCTION__, "If name %s index %d ip %s", lif->name, lif->ifindex, show_ip_str(htonl(lif->ipv4_addr))); - } - rth = RTA_NEXT(rth, rtl); - } - - return 0; -} - int iccp_sys_local_if_list_get_addr() { struct System *sys = NULL; @@ -983,7 +1158,7 @@ int iccp_sys_local_if_list_get_addr() return -ENOMEM; } - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_local_if_addr_update, sys); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_addr_valid_handler, sys); ret = nl_recvmsgs(sys->route_sock, cb); nl_cb_put(cb); if (ret < 0) @@ -1022,9 +1197,13 @@ static int iccp_route_event_handler(struct nl_msg *msg, void *arg) break; case RTM_NEWADDR: - iccp_local_if_addr_update(msg, NULL); + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newaddr, NULL) < 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_NEWADDR)."); + break; + case RTM_DELADDR: + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_deladdr, NULL) < 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_DELADDR)."); break; - default: return NL_OK; } @@ -1048,6 +1227,53 @@ static int iccp_genric_event_handler(struct nl_msg *msg, void *arg) return NL_SKIP; } +int iccp_make_nd_socket(void) +{ + int sock; + int ret; + int val; + struct icmp6_filter filter; + + sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + + if (sock < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to create nd socket"); + return MCLAG_ERROR; + } + + val = 1; +#ifdef IPV6_RECVPKTINFO /* 2292bis-01 */ + if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val)) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set IPV6_RECVPKTINFO for nd socket"); + close(sock); + return MCLAG_ERROR; + } +#else /* RFC2292 */ + if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, &val, sizeof(val)) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set IPV6_PKTINFO for nd socket"); + close(sock); + return MCLAG_ERROR; + } +#endif + + ICMP6_FILTER_SETBLOCKALL(&filter); + ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter); + + ret = setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(struct icmp6_filter)); + + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set ICMP6_FILTER"); + close(sock); + return MCLAG_ERROR; + } + + return sock; +} + /*init netlink socket*/ int iccp_system_init_netlink_socket() { @@ -1135,45 +1361,7 @@ int iccp_system_init_netlink_socket() ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink event sock."); goto err_return; } -#if 0 - sys->family = genl_ctrl_resolve(sys->genric_sock, TEAM_GENL_NAME); - while (sys->family < 0) - { - sleep(1); - log_err_period++; - /*If no portchannel configuration, teamd will not started, genl_ctrl_resolve() will return <0 forever */ - /*Only log error message 5 times*/ - if (log_err_period == 1 && log_err_time < 5) - { - ICCPD_LOG_ERR(__FUNCTION__, "Failed to resolve netlink family. %d of TEAM_GENL_NAME %s ", sys->family, TEAM_GENL_NAME); - log_err_time++; - } - else - { - /*Log error message every 30s per time*/ - if (log_err_period == 30) - log_err_period = 0; - } - - sys->family = genl_ctrl_resolve(sys->genric_sock, TEAM_GENL_NAME); - } - - grp_id = genl_ctrl_resolve_grp(sys->genric_sock, TEAM_GENL_NAME, - TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME); - if (grp_id < 0) - { - ICCPD_LOG_ERR(__FUNCTION__, "Failed to resolve netlink multicast groups. %d", grp_id); - goto err_return; - } - - err = nl_socket_add_membership(sys->genric_event_sock, grp_id); - if (err < 0) - { - ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); - goto err_return; - } -#endif nl_socket_disable_seq_check(sys->genric_event_sock); nl_socket_modify_cb(sys->genric_event_sock, NL_CB_VALID, NL_CB_CUSTOM, iccp_genric_event_handler, sys); @@ -1202,8 +1390,13 @@ int iccp_system_init_netlink_socket() ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); goto err_return; } - - /*receive arp packet socket*/ + err = nl_socket_add_membership(sys->route_event_sock, RTNLGRP_IPV6_IFADDR); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + goto err_return; + } + /* receive arp packet socket */ sys->arp_receive_fd = socket(PF_PACKET, SOCK_DGRAM, 0); if (sys->arp_receive_fd < 0) { @@ -1225,6 +1418,13 @@ int iccp_system_init_netlink_socket() } } + sys->ndisc_receive_fd = iccp_make_nd_socket(); + + if (sys->ndisc_receive_fd < 0) + { + goto err_return; + } + goto succes_return; err_return: @@ -1295,6 +1495,11 @@ static int iccp_get_receive_arp_packet_sock_fd(struct System *sys) return sys->arp_receive_fd; } +static int iccp_get_receive_ndisc_packet_sock_fd(struct System *sys) +{ + return sys->ndisc_receive_fd; +} + static int iccp_receive_arp_packet_handler(struct System *sys) { unsigned char buf[1024]; @@ -1328,7 +1533,100 @@ static int iccp_receive_arp_packet_handler(struct System *sys) memcpy(mac_addr, (char*)(a + 1), ETHER_ADDR_LEN); memcpy(&addr, (char*)(a + 1) + a->ar_hln, 4); - do_arp_update_from_reply_packet(ifindex, ntohl(addr), mac_addr); + do_arp_update_from_reply_packet(ifindex, addr, mac_addr); + + return 0; +} + +int iccp_receive_ndisc_packet_handler(struct System *sys) +{ + uint8_t buf[4096]; + uint8_t adata[1024]; + struct sockaddr_in6 from; + unsigned int ifindex = 0; + struct msghdr msg; + struct iovec iov; + struct cmsghdr *cmsgptr; + struct nd_msg *ndmsg = NULL; + struct nd_opt_hdr *nd_opt = NULL; + struct in6_addr target; + uint8_t mac_addr[ETHER_ADDR_LEN]; + int8_t *opt = NULL; + int opt_len = 0, l = 0; + int len; + + memset(mac_addr, 0, ETHER_ADDR_LEN); + + /* Fill in message and iovec. */ + msg.msg_name = (void *)(&from); + msg.msg_namelen = sizeof(struct sockaddr_in6); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = (void *)adata; + msg.msg_controllen = sizeof adata; + iov.iov_base = buf; + iov.iov_len = 4096; + + len = recvmsg(sys->ndisc_receive_fd, &msg, 0); + + if (len < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Ndisc recvmsg error!"); + return MCLAG_ERROR; + } + + if (msg.msg_controllen >= sizeof(struct cmsghdr)) + for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) + { + /* I want interface index which this packet comes from. */ + if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO) + { + struct in6_pktinfo *ptr; + + ptr = (struct in6_pktinfo *)CMSG_DATA(cmsgptr); + ifindex = ptr->ipi6_ifindex; + } + } + + ndmsg = (struct nd_msg *)buf; + + if (ndmsg->icmph.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT) + return 0; + + memcpy((char *)(&target), (char *)(&ndmsg->target), sizeof(struct in6_addr)); + + opt = (char *)ndmsg->opt; + + opt_len = len - sizeof(struct nd_msg); + + if (opt && opt_len > 0) + { + while (opt_len) + { + if (opt_len < sizeof(struct nd_opt_hdr)) + return 0; + + nd_opt = (struct nd_opt_hdr *)opt; + + l = nd_opt->nd_opt_len << 3; + + if (l == 0) + return 0; + + if (nd_opt->nd_opt_type == ND_OPT_TARGET_LL_ADDR) + { + memcpy(mac_addr, (char *)((char *)nd_opt + sizeof(struct nd_opt_hdr)), ETHER_ADDR_LEN); + break; + } + + opt += l; + opt_len -= l; + } + } + + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Recv na pkt(%s,%02X:%02X:%02X:%02X:%02X:%02X)!", show_ipv6_str((char *)&target), mac_addr[0], mac_addr[1], + mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); */ + do_ndisc_update_from_reply_packet(ifindex, (char *)&target, mac_addr); return 0; } @@ -1412,7 +1710,11 @@ static const struct iccp_eventfd iccp_eventfds[] = { { .get_fd = iccp_get_receive_arp_packet_sock_fd, .event_handler = iccp_receive_arp_packet_handler, - } + }, + { + .get_fd = iccp_get_receive_ndisc_packet_sock_fd, + .event_handler = iccp_receive_ndisc_packet_handler, + } }; /* \cond HIDDEN_SYMBOLS */ diff --git a/src/iccpd/src/mclagdctl/mclagdctl.c b/src/iccpd/src/mclagdctl/mclagdctl.c index 7c5d7284066d..6e897727887a 100644 --- a/src/iccpd/src/mclagdctl/mclagdctl.c +++ b/src/iccpd/src/mclagdctl/mclagdctl.c @@ -65,6 +65,14 @@ static struct command_type command_types[] = .enca_msg = mclagdctl_enca_dump_arp, .parse_msg = mclagdctl_parse_dump_arp, }, + { + .id = ID_CMDTYPE_D_A, + .parent_id = ID_CMDTYPE_D, + .info_type = INFO_TYPE_DUMP_NDISC, + .name = "nd", + .enca_msg = mclagdctl_enca_dump_ndisc, + .parse_msg = mclagdctl_parse_dump_ndisc, + }, { .id = ID_CMDTYPE_D_A, .parent_id = ID_CMDTYPE_D, @@ -290,6 +298,24 @@ int mclagdctl_enca_dump_arp(char *msg, int mclag_id, int argc, char **argv) return 1; } +int mclagdctl_enca_dump_ndisc(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + if (mclag_id <= 0) + { + fprintf(stderr, "Need to specify mclag-id through the parameter i !\n"); + return MCLAG_ERROR; + } + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_NDISC; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + int mclagdctl_parse_dump_arp(char *msg, int data_len) { struct mclagd_arp_msg * arp_info = NULL; @@ -322,6 +348,38 @@ int mclagdctl_parse_dump_arp(char *msg, int data_len) return 0; } +int mclagdctl_parse_dump_ndisc(char *msg, int data_len) +{ + struct mclagd_ndisc_msg *ndisc_info = NULL; + int len = 0; + int count = 0; + + fprintf(stdout, "%-6s", "No."); + fprintf(stdout, "%-52s", "IPv6"); + fprintf(stdout, "%-20s", "MAC"); + fprintf(stdout, "%-20s", "DEV"); + fprintf(stdout, "\n"); + + len = sizeof(struct mclagd_ndisc_msg); + + for (; data_len >= len; data_len -= len, count++) + { + ndisc_info = (struct mclagd_ndisc_msg *)(msg + len * count); + + fprintf(stdout, "%-6d", count + 1); + fprintf(stdout, "%-52s", ndisc_info->ipv6_addr); + fprintf(stdout, "%02x:%02x:%02x:%02x:%02x:%02x", + ndisc_info->mac_addr[0], ndisc_info->mac_addr[1], + ndisc_info->mac_addr[2], ndisc_info->mac_addr[3], + ndisc_info->mac_addr[4], ndisc_info->mac_addr[5]); + fprintf(stdout, " "); + fprintf(stdout, "%-20s", ndisc_info->ifname); + fprintf(stdout, "\n"); + } + + return 0; +} + int mclagdctl_enca_dump_mac(char *msg, int mclag_id, int argc, char **argv) { struct mclagdctl_req_hdr req; diff --git a/src/iccpd/src/mclagdctl/mclagdctl.h b/src/iccpd/src/mclagdctl/mclagdctl.h index 1b8c6f278cc5..91155ecb7321 100644 --- a/src/iccpd/src/mclagdctl/mclagdctl.h +++ b/src/iccpd/src/mclagdctl/mclagdctl.h @@ -25,6 +25,7 @@ #define MCLAGDCTL_MAX_L_PORT_NANE 32 #define MCLAGDCTL_INET_ADDR_LEN 32 +#define MCLAGDCTL_INET6_ADDR_LEN 64 #define MCLAGDCTL_ETHER_ADDR_LEN 6 #define MCLAGDCTL_PORT_MEMBER_BUF_LEN 512 #define ETHER_ADDR_STR_LEN 18 @@ -62,6 +63,7 @@ enum mclagdctl_notify_peer_type INFO_TYPE_NONE = 0, INFO_TYPE_DUMP_STATE, INFO_TYPE_DUMP_ARP, + INFO_TYPE_DUMP_NDISC, INFO_TYPE_DUMP_MAC, INFO_TYPE_DUMP_LOCAL_PORTLIST, INFO_TYPE_DUMP_PEER_PORTLIST, @@ -137,6 +139,14 @@ struct mclagd_arp_msg unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN]; }; +struct mclagd_ndisc_msg +{ + char op_type; + char ifname[MCLAGDCTL_MAX_L_PORT_NANE]; + char ipv6_addr[MCLAGDCTL_INET6_ADDR_LEN]; + unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN]; +}; + struct mclagd_mac_msg { unsigned char op_type;/*add or del*/ @@ -186,7 +196,9 @@ struct mclagd_peer_if extern int mclagdctl_enca_dump_state(char *msg, int mclag_id, int argc, char **argv); extern int mclagdctl_parse_dump_state(char *msg, int data_len); extern int mclagdctl_enca_dump_arp(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_enca_dump_ndisc(char *msg, int mclag_id, int argc, char **argv); extern int mclagdctl_parse_dump_arp(char *msg, int data_len); +extern int mclagdctl_parse_dump_ndisc(char *msg, int data_len); extern int mclagdctl_enca_dump_mac(char *msg, int mclag_id, int argc, char **argv); extern int mclagdctl_parse_dump_mac(char *msg, int data_len); extern int mclagdctl_enca_dump_local_portlist(char *msg, int mclag_id, int argc, char **argv); diff --git a/src/iccpd/src/mlacp_fsm.c b/src/iccpd/src/mlacp_fsm.c index f479b75f36cc..c56eb9051736 100644 --- a/src/iccpd/src/mlacp_fsm.c +++ b/src/iccpd/src/mlacp_fsm.c @@ -101,12 +101,14 @@ * ***************************************/ static char *mlacp_state(struct CSM* csm); static void mlacp_resync_arp(struct CSM* csm); +static void mlacp_resync_ndisc(struct CSM* csm); static void mlacp_resync_mac(struct CSM* csm); /* Sync Sender APIs*/ static void mlacp_sync_send_sysConf(struct CSM* csm); static void mlacp_sync_send_aggConf(struct CSM* csm); static void mlacp_sync_send_aggState(struct CSM* csm); static void mlacp_sync_send_syncArpInfo(struct CSM* csm); +static void mlacp_sync_send_syncNdiscInfo(struct CSM* csm); static void mlacp_sync_send_heartbeat(struct CSM* csm); static void mlacp_sync_send_syncDoneData(struct CSM* csm); /* Sync Reciever APIs*/ @@ -204,7 +206,7 @@ static void mlacp_sync_send_aggState(struct CSM* csm) return; } #define MAX_MAC_ENTRY_NUM 30 -#define MAX_ARP_ENTRY_NUM 40 +#define MAX_NEIGH_ENTRY_NUM 40 static void mlacp_sync_send_syncMacInfo(struct CSM* csm) { int msg_len = 0; @@ -253,7 +255,7 @@ static void mlacp_sync_send_syncArpInfo(struct CSM* csm) count++; free(msg->buf); free(msg); - if (count >= MAX_ARP_ENTRY_NUM) + if (count >= MAX_NEIGH_ENTRY_NUM) { iccp_csm_send(csm, g_csm_buf, msg_len); count = 0; @@ -268,6 +270,37 @@ static void mlacp_sync_send_syncArpInfo(struct CSM* csm) return; } +static void mlacp_sync_send_syncNdiscInfo(struct CSM *csm) +{ + int msg_len = 0; + struct Msg *msg = NULL; + int count = 0; + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + + while (!TAILQ_EMPTY(&(MLACP(csm).ndisc_msg_list))) + { + msg = TAILQ_FIRST(&(MLACP(csm).ndisc_msg_list)); + TAILQ_REMOVE(&(MLACP(csm).ndisc_msg_list), msg, tail); + + msg_len = mlacp_prepare_for_ndisc_info(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct NDISCMsg *)msg->buf, count); + count++; + free(msg->buf); + free(msg); + if (count >= MAX_NEIGH_ENTRY_NUM) + { + iccp_csm_send(csm, g_csm_buf, msg_len); + count = 0; + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + } + /* ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] NDInfo,len=[%d]", msg_len); */ + } + + if (count) + iccp_csm_send(csm, g_csm_buf, msg_len); + + return; +} static void mlacp_sync_send_syncPortChannelInfo(struct CSM* csm) { struct System* sys = NULL; @@ -353,7 +386,7 @@ static void mlacp_sync_recv_sysConf(struct CSM* csm, struct Msg* msg) if (mlacp_fsm_update_system_conf(csm, sysconf) == MCLAG_ERROR) { /*NOTE: we just change the node ID local side without sending NAK msg*/ - ICCPD_LOG_DEBUG(__FUNCTION__, "Same Node ID = %d, send NAK", MLACP(csm).remote_system.node_id); + ICCPD_LOG_WARN(__FUNCTION__, "Same Node ID = %d, send NAK", MLACP(csm).remote_system.node_id); mlacp_sync_send_nak_handler(csm, msg); } @@ -476,6 +509,15 @@ static void mlacp_sync_recv_arpInfo(struct CSM* csm, struct Msg* msg) return; } +static void mlacp_sync_recv_ndiscInfo(struct CSM *csm, struct Msg *msg) +{ + struct mLACPNDISCInfoTLV *ndisc_info = NULL; + + ndisc_info = (struct mLACPNDISCInfoTLV *)&(msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_ndisc_info(csm, ndisc_info); + + return; +} static void mlacp_sync_recv_stpInfo(struct CSM* csm, struct Msg* msg) { /*Don't support currently*/ @@ -520,6 +562,7 @@ void mlacp_init(struct CSM* csm, int all) MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); PIF_QUEUE_REINIT(MLACP(csm).pif_list); LIF_PURGE_QUEUE_REINIT(MLACP(csm).lif_purge_list); @@ -528,6 +571,7 @@ void mlacp_init(struct CSM* csm, int all) { /* if no clean all, keep the arp info & local interface info for next connection*/ MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_list); LIF_QUEUE_REINIT(MLACP(csm).lif_list); @@ -551,8 +595,10 @@ void mlacp_finalize(struct CSM* csm) /* msg destroy*/ MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_list); /* remove lif & lif-purge queue */ @@ -590,6 +636,7 @@ void mlacp_fsm_transit(struct CSM* csm) { MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); MLACP(csm).current_state = MLACP_STATE_INIT; } @@ -651,6 +698,7 @@ void mlacp_fsm_transit(struct CSM* csm) MLACP(csm).wait_for_sync_data = 0; MLACP(csm).current_state = MLACP_STATE_STAGE1; mlacp_resync_arp(csm); + mlacp_resync_ndisc(csm); } switch (MLACP(csm).current_state) @@ -788,7 +836,7 @@ static void mlacp_resync_arp(struct CSM* csm) TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) { arp_msg = (struct ARPMsg*)msg->buf; - arp_msg->op_type = ARP_SYNC_ADD; + arp_msg->op_type = NEIGH_SYNC_ADD; if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) { TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); @@ -797,6 +845,31 @@ static void mlacp_resync_arp(struct CSM* csm) } } +/****************************************** +* When peerlink ready, prepare the NDISCMsg +* +******************************************/ +static void mlacp_resync_ndisc(struct CSM *csm) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL; + struct Msg *msg_send = NULL; + + /* recover ndisc info sync from peer */ + if (!TAILQ_EMPTY(&(MLACP(csm).ndisc_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + ndisc_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + } + } + } +} + /***************************************** * NAK handler * @@ -928,6 +1001,10 @@ static void mlacp_sync_receiver_handler(struct CSM* csm, struct Msg* msg) mlacp_sync_recv_arpInfo(csm, msg); break; + case TLV_T_MLACP_NDISC_INFO: + mlacp_sync_recv_ndiscInfo(csm, msg); + break; + case TLV_T_MLACP_STP_INFO: mlacp_sync_recv_stpInfo(csm, msg); break; @@ -980,6 +1057,10 @@ static void mlacp_sync_sender_handler(struct CSM* csm) mlacp_sync_send_syncArpInfo(csm); break; + case MLACP_SYNC_NDISC_INFO: + mlacp_sync_send_syncNdiscInfo(csm); + break; + case MLACP_SYNC_DONE: mlacp_sync_send_syncDoneData(csm); break; @@ -1194,6 +1275,9 @@ static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg) /* Send ARP info if any*/ mlacp_sync_send_syncArpInfo(csm); + /* Send Ndisc info if any */ + mlacp_sync_send_syncNdiscInfo(csm); + /*If peer is warm reboot*/ if (csm->peer_warm_reboot_time != 0) { diff --git a/src/iccpd/src/mlacp_link_handler.c b/src/iccpd/src/mlacp_link_handler.c index 66a75c4b8620..8bc533e387bd 100644 --- a/src/iccpd/src/mlacp_link_handler.c +++ b/src/iccpd/src/mlacp_link_handler.c @@ -39,6 +39,7 @@ #include "../include/iccp_csm.h" #include "mclagdctl/mclagdctl.h" #include "../include/iccp_cmd_show.h" +#include "../include/iccp_netlink.h" /***************************************** * Enum * @@ -50,12 +51,12 @@ typedef enum route_manipulate_type ROUTE_DEL } ROUTE_MANIPULATE_TYPE_E; - /***************************************** * Global * * ***************************************/ char g_ipv4_str[INET_ADDRSTRLEN]; +char g_ipv6_str[INET6_ADDRSTRLEN]; /***************************************** * Tool : show ip string @@ -72,6 +73,14 @@ char *show_ip_str(uint32_t ipv4_addr) return g_ipv4_str; } +char *show_ipv6_str(char *ipv6_addr) +{ + memset(g_ipv6_str, 0, sizeof(g_ipv6_str)); + inet_ntop(AF_INET6, ipv6_addr, g_ipv6_str, INET6_ADDRSTRLEN); + + return g_ipv6_str; +} + static int getHwAddr(char *buff, char *mac) { int i = 0; @@ -95,107 +104,6 @@ static int getHwAddr(char *buff, char *mac) return 0; } -/* Set an entry in the ARP cache. */ -int mlacp_fsm_arp_set(char *ifname, uint32_t ip, char *mac) -{ - struct arpreq arpreq; - struct sockaddr_in *sin; - struct in_addr ina; - int flags; - int rc; - int sock_fd = 0; - - ICCPD_LOG_DEBUG(__FUNCTION__, "Set arp entry for IP:%s MAC:%s ifname:%s", show_ip_str(htonl(ip)), mac, ifname); - - if (ifname == NULL || ip == 0 || mac == NULL) - { - return MCLAG_ERROR; - } - - /*you must add this becasue some system will return "Invlid argument" - because some argument isn't zero */ - memset(&arpreq, 0, sizeof(struct arpreq)); - sin = (struct sockaddr_in *)&arpreq.arp_pa; - memset(sin, 0, sizeof(struct sockaddr_in)); - sin->sin_family = AF_INET; - ina.s_addr = htonl(ip); - memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr)); - - if (getHwAddr((char *)arpreq.arp_ha.sa_data, mac) < 0) - { - return MCLAG_ERROR; - } - - strncpy(arpreq.arp_dev, ifname, 15); - - flags = ATF_COM; //note, must set flag, if not,you will get error - - arpreq.arp_flags = flags; - - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - { - return MCLAG_ERROR; - } - - rc = ioctl(sock_fd, SIOCSARP, &arpreq); - if (rc < 0) - { - close(sock_fd); - return MCLAG_ERROR; - } - - close(sock_fd); - - return 0; -} - -/* Delete an entry from the ARP cache. */ -int mlacp_fsm_arp_del(char *ifname, uint32_t ip) -{ - struct arpreq arpreq; - struct sockaddr_in *sin; - struct in_addr ina; - int rc; - int sock_fd = 0; - - ICCPD_LOG_DEBUG(__FUNCTION__, "Del arp entry for IP : %s ifname:%s", show_ip_str(htonl(ip)), ifname); - - if (ifname == NULL || ip == 0) - { - return MCLAG_ERROR; - } - - /*you must add this becasue some system will return "Invlid argument" - because some argument isn't zero */ - memset(&arpreq, 0, sizeof(struct arpreq)); - - sin = (struct sockaddr_in *)&arpreq.arp_pa; - memset(sin, 0, sizeof(struct sockaddr_in)); - sin->sin_family = AF_INET; - ina.s_addr = htonl(ip); - memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr)); - - strncpy(arpreq.arp_dev, ifname, 15); - - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - { - return MCLAG_ERROR; - } - - rc = ioctl(sock_fd, SIOCDARP, &arpreq); - if (rc < 0) - { - close(sock_fd); - return MCLAG_ERROR; - } - - close(sock_fd); - - return 0; -} - static int arp_set_handler(struct CSM* csm, struct LocalInterface* lif, int add) @@ -223,7 +131,7 @@ static int arp_set_handler(struct CSM* csm, arp_msg = (struct ARPMsg*)msg->buf; /* only process add*/ - if (arp_msg->op_type == ARP_SYNC_DEL) + if (arp_msg->op_type == NEIGH_SYNC_DEL) continue; /* find the ARP for lif_list*/ @@ -233,9 +141,9 @@ static int arp_set_handler(struct CSM* csm, sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - mlacp_fsm_arp_set(arp_msg->ifname, arp_msg->ipv4_addr, mac_str); + iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_msg->ipv4_addr, 1, arp_msg->mac_addr, arp_msg->ifname); /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add dynamic ARP to kernel [%s]", - show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } goto done; @@ -250,19 +158,82 @@ static int arp_set_handler(struct CSM* csm, continue; /* don't process del*/ - if (arp_msg->op_type == ARP_SYNC_DEL) + if (arp_msg->op_type == NEIGH_SYNC_DEL) continue; /* link broken, del all dynamic arp on the lif*/ - mlacp_fsm_arp_del(arp_msg->ifname, arp_msg->ipv4_addr); + iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_msg->ipv4_addr, 0, arp_msg->mac_addr, arp_msg->ifname); /*ICCPD_LOG_DEBUG(__FUNCTION__, "Del dynamic ARP [%s]", - show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } done: return 0; } +static int ndisc_set_handler(struct CSM *csm, struct LocalInterface *lif, int add) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL; + char mac_str[18] = ""; + + if (!csm || !lif) + return 0; + + if (add) + goto add_ndisc; + else + goto del_ndisc; + + /* Process Add */ +add_ndisc: + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return 0; + + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + mac_str[0] = '\0'; + ndisc_msg = (struct NDISCMsg *)msg->buf; + + /* only process add */ + if (ndisc_msg->op_type == NEIGH_SYNC_DEL) + continue; + + /* find the ND for lif_list */ + if (strcmp(lif->name, ndisc_msg->ifname) != 0) + continue; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", ndisc_msg->mac_addr[0], ndisc_msg->mac_addr[1], ndisc_msg->mac_addr[2], + ndisc_msg->mac_addr[3], ndisc_msg->mac_addr[4], ndisc_msg->mac_addr[5]); + + iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 1, ndisc_msg->mac_addr, ndisc_msg->ifname); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add dynamic ND to kernel [%s]", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/ + } + goto done; + +del_ndisc: + /* Process Del */ + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + + /* find the ND for lif_list */ + if (strcmp(lif->name, ndisc_msg->ifname) != 0) + continue; + + /* don't process del */ + if (ndisc_msg->op_type == NEIGH_SYNC_DEL) + continue; + + /* link broken, del all dynamic ndisc on the lif */ + iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 0, ndisc_msg->mac_addr, ndisc_msg->ifname); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Del dynamic ND [%s]", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/ + } + +done: + return 0; +} + /***************************************** * Port-Channel Status Handler * @@ -286,20 +257,13 @@ static void set_route_by_linux_route(struct CSM* csm, return; sprintf(ipv4_dest_str, "%s", show_ip_str(htonl(local_if->ipv4_addr))); - ptr = strrchr(ipv4_dest_str, '.'); strcpy(ptr, ".0\0"); + ptr = strrchr(ipv4_dest_str, '.'); + strcpy(ptr, ".0\0"); -#if 1 - /* set gw route*/ - /*sprintf(syscmd, "ip route %s %s/%d proto static metric 200 nexthop via %s > /dev/null 2>&1",*/ + /* set gw route */ + /* sprintf(syscmd, "ip route %s %s/%d proto static metric 200 nexthop via %s > /dev/null 2>&1", */ sprintf(syscmd, "ip route %s %s/%d metric 200 nexthop via %s > /dev/null 2>&1", - (is_add) ? "add" : "del", ipv4_dest_str, local_if->prefixlen, - csm->peer_ip); -#else - // set interface route - sprintf(syscmd, "route %s -net %s/%d %s > /dev/null 2>&1", - (is_add) ? "add" : "del", ipv4_dest_str, local_if->prefixlen, - local_if->name); -#endif + (is_add) ? "add" : "del", ipv4_dest_str, local_if->prefixlen, csm->peer_ip); ret = system(syscmd); ICCPD_LOG_DEBUG(__FUNCTION__, "%s ret = %d", syscmd, ret); @@ -374,12 +338,14 @@ static void set_l3_itf_state(struct CSM *csm, if (strncmp(set_l3_local_if->name, VLAN_PREFIX, 4) != 0) { arp_set_handler(csm, set_l3_local_if, 0); /* del arp*/ + ndisc_set_handler(csm, set_l3_local_if, 0); /* del nd */ } } else if (route_type == ROUTE_DEL) { /*set_route_by_linux_route(csm, set_l3_local_if, 0);*/ /*del static route by linux route tool*/ arp_set_handler(csm, set_l3_local_if, 1); /* add arp*/ + ndisc_set_handler(csm, set_l3_local_if, 1); /* add nd */ } } @@ -428,7 +394,7 @@ static void mlacp_clean_fdb(void) if (sys->sync_fd) write(sys->sync_fd, msg_buf, msg_hdr->len); - ICCPD_LOG_DEBUG(__FUNCTION__, "Notify mclagsyncd to clear FDB"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Notify mclagsyncd to clear FDB"); return; } @@ -467,7 +433,7 @@ void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable) msg_hdr->len += sizeof(mclag_sub_option_hdr_t); msg_hdr->len += sub_msg->op_len; - ICCPD_LOG_DEBUG(__FUNCTION__, "Send %s port MAC learn msg to mclagsyncd for %s", + ICCPD_LOG_NOTICE(__FUNCTION__, "Send %s port MAC learn msg to mclagsyncd for %s", sub_msg->op_type == MCLAG_SUB_OPTION_TYPE_MAC_LEARN_DISABLE ? "DISABLE":"ENABLE", lif->name); /*send msg*/ @@ -489,12 +455,12 @@ static void set_peerlink_mlag_port_kernel_forward( sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP", "-D", csm->peer_link_if->name, lif->name); - ICCPD_LOG_DEBUG(__FUNCTION__, " ebtable cmd %s", cmd ); + ICCPD_LOG_NOTICE(__FUNCTION__, " ebtable cmd %s", cmd ); system(cmd); sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP", (enable) ? "-A" : "-D", csm->peer_link_if->name, lif->name); - ICCPD_LOG_DEBUG(__FUNCTION__, " ebtable cmd %s", cmd ); + ICCPD_LOG_NOTICE(__FUNCTION__, " ebtable cmd %s", cmd ); system(cmd); return; @@ -600,11 +566,11 @@ void update_peerlink_isolate_from_all_csm_lif( if (dst_len) { memcpy(sub_msg->data, mlag_po_buf, dst_len); - ICCPD_LOG_DEBUG(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port %s", csm->peer_link_if->name, mlag_po_buf); + ICCPD_LOG_NOTICE(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port %s", csm->peer_link_if->name, mlag_po_buf); } else { - ICCPD_LOG_DEBUG(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port is NULL", csm->peer_link_if->name); + ICCPD_LOG_NOTICE(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port is NULL", csm->peer_link_if->name); } /*send msg*/ @@ -902,7 +868,7 @@ void syn_arp_info_to_peer(struct CSM *csm, struct LocalInterface *local_if) continue; arp_msg = (struct ARPMsg*)msg->buf; - arp_msg->op_type = ARP_SYNC_ADD; + arp_msg->op_type = NEIGH_SYNC_ADD; if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) { @@ -912,13 +878,46 @@ void syn_arp_info_to_peer(struct CSM *csm, struct LocalInterface *local_if) } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + show_ip_str(arp_msg->ipv4_addr)); } } return; } +void syn_ndisc_info_to_peer(struct CSM *csm, struct LocalInterface *local_if) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, *ndisc_info = NULL; + struct Msg *msg_send = NULL; + + if (!csm || !local_if) + return; + + if (!TAILQ_EMPTY(&(MLACP(csm).ndisc_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_info = (struct NDISCMsg *)msg->buf; + + if (strcmp(ndisc_info->ifname, local_if->name) != 0) + continue; + + ndisc_msg = (struct NDISCMsg *)msg->buf; + ndisc_msg->op_type = NEIGH_SYNC_ADD; + + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + } + + return; +} void update_stp_peer_link(struct CSM *csm, struct PeerInterface *pif, int po_state, int new_create) @@ -948,6 +947,7 @@ void update_stp_peer_link(struct CSM *csm, if (po_state == 1 && lif->po_active == 1) { syn_arp_info_to_peer(csm, lif); + syn_ndisc_info_to_peer(csm, lif); } } else @@ -972,6 +972,7 @@ void update_stp_peer_link(struct CSM *csm, if (po_state == 1 && lif->po_active == 1) { syn_arp_info_to_peer(csm, vlan->vlan_itf); + syn_ndisc_info_to_peer(csm, vlan->vlan_itf); } } } @@ -1034,7 +1035,7 @@ void iccp_send_fdb_entry_to_syncd( struct MACMsg* mac_msg, uint8_t mac_type) mac_info->op_type = mac_msg->op_type; msg_hdr->len = sizeof(struct IccpSyncdHDr) + sizeof(struct mclag_fdb_info); - ICCPD_LOG_DEBUG(__FUNCTION__, "Send mac %s msg to mclagsyncd, vid %d ; ifname %s ; mac %s; type %s", + ICCPD_LOG_NOTICE(__FUNCTION__, "Send mac %s msg to mclagsyncd, vid %d ; ifname %s ; mac %s; type %s", mac_info->op_type == MAC_SYNC_ADD ? "add" : "del", mac_info->vid, mac_info->port_name, mac_info->mac, mac_info->type == MAC_TYPE_STATIC ? "static" : "dynamic"); /*send msg*/ @@ -1141,7 +1142,7 @@ static void update_l2_mac_state(struct CSM *csm, /*portchannel down*/ if (po_state == 0) { - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, age local MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, age local MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); @@ -1180,7 +1181,7 @@ static void update_l2_mac_state(struct CSM *csm, memcpy(mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); } - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, redirect MAC %s vlan-id %d to peer-link %s", + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, redirect MAC %s vlan-id %d to peer-link %s", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, csm->peer_itf_name); } else @@ -1188,7 +1189,7 @@ static void update_l2_mac_state(struct CSM *csm, /*peer-link is not configured, del mac from ASIC, mac still in mac_list*/ del_mac_from_chip(mac_msg); - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, peer-link is not configured: MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, peer-link is not configured: MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); } } @@ -1199,7 +1200,7 @@ static void update_l2_mac_state(struct CSM *csm, /*when this portchannel up, recover the mac back*/ if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0) { - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s up, redirect MAC %s vlan-id %d from peerlink to %s", + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s up, redirect MAC %s vlan-id %d from peerlink to %s", mac_msg->origin_ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->origin_ifname); /*Remove MAC_AGE_LOCAL flag*/ @@ -1215,7 +1216,7 @@ static void update_l2_mac_state(struct CSM *csm, { /*this may be peerlink is not configured and portchannel is down*/ /*when this portchannel up, add the mac back to ASIC*/ - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s up, add MAC %s vlan-id %d to ASIC", + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s up, add MAC %s vlan-id %d to ASIC", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); /*Remove MAC_AGE_LOCAL flag*/ @@ -1319,7 +1320,7 @@ static void mlacp_fix_bridge_mac(struct CSM* csm) /*The Bridge mac can not be the same as peer system id, so fix the Bridge MAC address here.*/ sprintf(syscmd, "ip link set dev Bridge address %s > /dev/null 2>&1", macaddr); ret = system(syscmd); - ICCPD_LOG_DEBUG(__FUNCTION__, " %s ret = %d", syscmd, ret); + ICCPD_LOG_NOTICE(__FUNCTION__, " %s ret = %d", syscmd, ret); } return; @@ -1345,7 +1346,7 @@ void mlacp_peer_conn_handler(struct CSM* csm) { /*If peer reconnected, reset peer disconnect time*/ csm->warm_reboot_disconn_time = 0; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer warm reboot and reconnect, reset peer disconnect time!"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot and reconnect, reset peer disconnect time!"); } if (csm->peer_link_if) @@ -1368,36 +1369,10 @@ void mlacp_peer_conn_handler(struct CSM* csm) mlacp_conn_handler_fdb(csm); -#if 0 - // When peer-link ready, suppose all MLAG link are alive - LIST_FOREACH(pif, &(MLACP(csm).pif_list), mlacp_next) - { - pif->po_active = 1; - } -#endif LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) { if (lif->type == IF_T_PORT_CHANNEL) { -#if 0 - if (local_if_is_l3_mode(lif)) - { - set_route_by_linux_route( csm, lif, 1); - } - else - { - LIST_FOREACH(vlan, &(lif->vlan_list), port_next) - { - if (!vlan->vlan_itf) - continue; - if (!local_if_is_l3_mode(vlan->vlan_itf)) - continue; - - set_route_by_linux_route(csm, vlan->vlan_itf, 1); /* add static route by linux route tool*/ - } - } -#endif - mlacp_portchannel_state_handler(csm, lif, (lif->state == PORT_STATE_UP) ? 1 : 0); } } @@ -1432,7 +1407,7 @@ void mlacp_peer_disconn_handler(struct CSM* csm) /*peer connection must be establised again within 90s from last disconnection for peer warm reboot*/ time(&csm->warm_reboot_disconn_time); - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer warm reboot and disconnect, recover to normal reboot for next time!"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot and disconnect, recover to normal reboot for next time!"); return; } @@ -1448,7 +1423,7 @@ void mlacp_peer_disconn_handler(struct CSM* csm) if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0 && mac_msg->age_flag != (MAC_AGE_LOCAL | MAC_AGE_PEER)) continue; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer disconnect, del MAC for peer-link: %s, MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer disconnect, del MAC for peer-link: %s, MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); /*Send mac del message to mclagsyncd, may be already deleted*/ @@ -1493,7 +1468,7 @@ void mlacp_peerlink_up_handler(struct CSM* csm) if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) continue; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer link up, add MAC to ASIC for peer-link: %s, MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer link up, add MAC to ASIC for peer-link: %s, MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); /*Send mac add message to mclagsyncd, local age flag is already set*/ @@ -1520,7 +1495,7 @@ void mlacp_peerlink_down_handler(struct CSM* csm) if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) continue; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer link down, del MAC for peer-link: %s, MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer link down, del MAC for peer-link: %s, MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); @@ -1686,17 +1661,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch mac_msg->age_flag = 0; - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC msg from mclagsyncd, vid %d mac %s port %s optype %s ", vid, mac_str, ifname, op_type == MAC_SYNC_ADD ? "add" : "del"); - /*Debug*/ - #if 0 - /* dump receive MAC info*/ - fprintf(stderr, "\n======== MAC Update==========\n"); - fprintf(stderr, " MAC = %s\n", mac_str); - fprintf(stderr, " vlan id = %d\n", vid); - fprintf(stderr, " fdb type = %s\n", fdb_type == MAC_TYPE_STATIC ? "static" : "dynamic"); - fprintf(stderr, " op type = %s\n", op_type == MAC_SYNC_ADD ? "add" : "del"); - fprintf(stderr, "==============================\n"); - #endif + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC msg from mclagsyncd, vid %d mac %s port %s optype %s ", vid, mac_str, ifname, op_type == MAC_SYNC_ADD ? "add" : "del"); /* Find MLACP itf, may be mclag enabled port-channel*/ LIST_FOREACH(csm, &(sys->csm_list), next) @@ -1868,7 +1833,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch /*peer-link learn mac is control by iccpd, ignore the chip del info*/ add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s(peer-link is up), add back %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s(peer-link is up), add back %s vlan-id %d", mac_info->ifname, mac_info->mac_str, mac_info->vid); } @@ -1890,7 +1855,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch } else { - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s, del %s vlan-id %d, peer is not age, add back to chip", + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s, del %s vlan-id %d, peer is not age, add back to chip", mac_info->ifname, mac_info->mac_str, mac_info->vid); mac_info->fdb_type = MAC_TYPE_DYNAMIC; @@ -1905,7 +1870,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP) { add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s(down), del %s vlan-id %d, redirect to peer-link", + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s(down), del %s vlan-id %d, redirect to peer-link", mac_info->ifname, mac_info->mac_str, mac_info->vid); } } @@ -1984,6 +1949,9 @@ char * mclagd_ctl_cmd_str(int req_type) case INFO_TYPE_DUMP_ARP: return "dump arp"; + case INFO_TYPE_DUMP_NDISC: + return "dump nd"; + case INFO_TYPE_DUMP_MAC: return "dump mac"; @@ -2205,6 +2173,46 @@ void mclagd_ctl_handle_dump_arp(int client_fd, int mclag_id) return; } +void mclagd_ctl_handle_dump_ndisc(int client_fd, int mclag_id) +{ + char *Pbuf = NULL; + char buf[512] = { 0 }; + int ndisc_num = 0; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_ndisc_dump(&Pbuf, &ndisc_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_NDISC; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_NDISC; + hd->data_len = ndisc_num * sizeof(struct mclagd_ndisc_msg); + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + void mclagd_ctl_handle_dump_mac(int client_fd, int mclag_id) { char * Pbuf = NULL; @@ -2375,6 +2383,10 @@ int mclagd_ctl_interactive_process(int client_fd) mclagd_ctl_handle_dump_arp(client_fd, req->mclag_id); break; + case INFO_TYPE_DUMP_NDISC: + mclagd_ctl_handle_dump_ndisc(client_fd, req->mclag_id); + break; + case INFO_TYPE_DUMP_MAC: mclagd_ctl_handle_dump_mac(client_fd, req->mclag_id); break; diff --git a/src/iccpd/src/mlacp_sync_prepare.c b/src/iccpd/src/mlacp_sync_prepare.c index f40a59884e49..a278af51928c 100644 --- a/src/iccpd/src/mlacp_sync_prepare.c +++ b/src/iccpd/src/mlacp_sync_prepare.c @@ -326,7 +326,7 @@ int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_bu sprintf(MacData->ifname, "%s", mac_msg->origin_ifname); MacData->vid = htons(mac_msg->vid); - ICCPD_LOG_DEBUG(__FUNCTION__, "Send MAC messge to peer, port %s mac = %s, vid = %d, type = %s count %d ", mac_msg->origin_ifname, + ICCPD_LOG_NOTICE(__FUNCTION__, "Send MAC messge to peer, port %s mac = %s, vid = %d, type = %s count %d ", mac_msg->origin_ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type == MAC_SYNC_ADD ? "add" : "del", count); return msg_len; @@ -374,11 +374,64 @@ int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, ArpData->op_type = arp_msg->op_type; sprintf(ArpData->ifname, "%s", arp_msg->ifname); - ArpData->ipv4_addr = htonl(arp_msg->ipv4_addr); + ArpData->ipv4_addr = arp_msg->ipv4_addr; memcpy(ArpData->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); - ICCPD_LOG_DEBUG(__FUNCTION__, "Send ARP messge to peer, if name %s mac %02x:%02x:%02x:%02x:%02x:%02x IP %s", ArpData->ifname, ArpData->mac_addr[0], ArpData->mac_addr[1], ArpData->mac_addr[2], - ArpData->mac_addr[3], ArpData->mac_addr[4], ArpData->mac_addr[5], show_ip_str( ArpData->ipv4_addr)); + ICCPD_LOG_NOTICE(__FUNCTION__, "Send ARP messge to peer, if name %s mac %02x:%02x:%02x:%02x:%02x:%02x IP %s", ArpData->ifname, ArpData->mac_addr[0], ArpData->mac_addr[1], ArpData->mac_addr[2], + ArpData->mac_addr[3], ArpData->mac_addr[4], ArpData->mac_addr[5], show_ip_str(ArpData->ipv4_addr)); + + return msg_len; +} + +/***************************************** +* Preprare Sync NDISC-Info TLV +* +* ***************************************/ +int mlacp_prepare_for_ndisc_info(struct CSM *csm, char *buf, size_t max_buf_size, struct NDISCMsg *ndisc_msg, int count) +{ + + struct mLACPNDISCInfoTLV *tlv = NULL; + size_t msg_len = 0; + size_t tlv_len = 0; + ICCHdr *icc_hdr = NULL; + struct NDISCMsg *NdiscData; + + if (!csm) + return -1; + if (!buf) + return -1; + + tlv_len = sizeof(struct mLACPNDISCInfoTLV) + sizeof(struct NDISCMsg) * (count + 1); + + if ((msg_len = sizeof(ICCHdr) + tlv_len) > max_buf_size) + return -1; + + /* ICC header */ + icc_hdr = (ICCHdr *)buf; + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Prepare for ND information TLV */ + tlv = (struct mLACPNDISCInfoTLV *)&buf[sizeof(ICCHdr)]; + tlv->icc_parameter.len = htons(tlv_len - sizeof(ICCParameter)); + tlv->num_of_entry = htons(count + 1); + + if (count == 0) + { + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_NDISC_INFO); + } + + NdiscData = (struct mLACPMACData *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPNDISCInfoTLV) + sizeof(struct NDISCMsg) * count]; + + NdiscData->op_type = ndisc_msg->op_type; + sprintf(NdiscData->ifname, "%s", ndisc_msg->ifname); + memcpy(NdiscData->ipv6_addr, ndisc_msg->ipv6_addr, 32); + memcpy(NdiscData->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Send ND messge to peer, if name %s mac =%02x:%02x:%02x:%02x:%02x:%02x IPv6 %s", NdiscData->ifname, + NdiscData->mac_addr[0], NdiscData->mac_addr[1], NdiscData->mac_addr[2], NdiscData->mac_addr[3], NdiscData->mac_addr[4], + NdiscData->mac_addr[5], show_ipv6_str((char *)NdiscData->ipv6_addr)); return msg_len; } @@ -597,7 +650,7 @@ int mlacp_prepare_for_warm_reboot(struct CSM* csm, char* buf, size_t max_buf_siz tlv->icc_parameter.len = htons(sizeof(struct mLACPWarmbootTLV) - sizeof(ICCParameter)); tlv->warmboot = 0x1; - ICCPD_LOG_DEBUG(__FUNCTION__, "Send warm reboot notification to peer!"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Send warm reboot notification to peer!"); return msg_len; } diff --git a/src/iccpd/src/mlacp_sync_update.c b/src/iccpd/src/mlacp_sync_update.c index 40dc33187885..b82fc1c16cb9 100644 --- a/src/iccpd/src/mlacp_sync_update.c +++ b/src/iccpd/src/mlacp_sync_update.c @@ -33,6 +33,7 @@ #include "../include/mlacp_link_handler.h" #include "../include/iccp_consistency_check.h" #include "../include/port.h" +#include "../include/iccp_netlink.h" /***************************************** * Port-Conf Update * @@ -166,7 +167,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * struct LocalInterface* local_if = NULL; uint8_t from_mclag_intf = 0;/*0: orphan port, 1: MCLAG port*/ - ICCPD_LOG_INFO(__FUNCTION__, + ICCPD_LOG_NOTICE(__FUNCTION__, "Received MAC Info, port[%s] vid[%d] MAC[%s] type[%s]", MacData->ifname, ntohs(MacData->vid), MacData->mac_str, MacData->type == MAC_SYNC_ADD ? "add" : "del"); @@ -266,27 +267,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC); } } - - #if 0 - mac_msg->op_type = MAC_SYNC_ACK; - if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) - { - /*Reply mac ack message to peer, peer will clean MAC_AGE_PEER flag*/ - TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ADD, MAC-msg-list enqueue: %s, add %s vlan-id %d, op_type %d", - mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); - } - #endif - } - #if 0 - else if (tlv->type == MAC_SYNC_ACK) - { - /*Clean the MAC_AGE_PEER flag*/ - mac_msg->age_flag &= ~MAC_AGE_PEER; - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ACK, Remove peer age flag:%d ifname %s, add %s vlan-id %d, op_type %d", - mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); } - #endif break; } @@ -332,7 +313,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * if (strlen(csm->peer_itf_name) == 0) { - ICCPD_LOG_DEBUG(__FUNCTION__, "From orphan port or portchannel is down, but peer-link is not configured: ifname %s, MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "From orphan port or portchannel is down, but peer-link is not configured: ifname %s, MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); /*if orphan port mac but no peerlink, don't keep this mac*/ @@ -344,7 +325,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * /*Redirect the mac to peer-link*/ memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); - ICCPD_LOG_DEBUG(__FUNCTION__, "Redirect to peerlink for orphan port or portchannel is down, Add local age flag: %d ifname %s, MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Redirect to peerlink for orphan port or portchannel is down, Add local age flag: %d ifname %s, MAC %s vlan-id %d", mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); } } @@ -371,17 +352,6 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * /*from MCLAG port and the local port is up*/ add_mac_to_chip(mac_msg, mac_msg->fdb_type); } - - #if 0 - mac_msg->op_type = MAC_SYNC_ACK; - if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) - { - /*Reply mac ack message to peer, peer will clean MAC_AGE_PEER flag*/ - TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); - ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, op_type %d", - mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); - } - #endif } } @@ -422,7 +392,7 @@ void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg) return; arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->op_type != ARP_SYNC_DEL) + if (arp_msg->op_type != NEIGH_SYNC_DEL) { TAILQ_INSERT_TAIL(&(MLACP(csm).arp_list), msg, tail); } @@ -430,6 +400,32 @@ void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg) return; } +/***************************************** + * Tool : Add Ndisc Info into ndisc list + * + ****************************************/ +void mlacp_enqueue_ndisc(struct CSM *csm, struct Msg *msg) +{ + struct NDISCMsg *ndisc_msg = NULL; + + if (!csm) + { + if (msg) + free(msg); + return; + } + if (!msg) + return; + + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (ndisc_msg->op_type != NEIGH_SYNC_DEL) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_list), msg, tail); + } + + return; +} + /***************************************** * ARP-Info Update * ***************************************/ @@ -449,7 +445,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", arp_entry->mac_addr[0], arp_entry->mac_addr[1], arp_entry->mac_addr[2], arp_entry->mac_addr[3], arp_entry->mac_addr[4], arp_entry->mac_addr[5]); - ICCPD_LOG_INFO(__FUNCTION__, + ICCPD_LOG_NOTICE(__FUNCTION__, "Received ARP Info, intf[%s] IP[%s], MAC[%02x:%02x:%02x:%02x:%02x:%02x]", arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), arp_entry->mac_addr[0], arp_entry->mac_addr[1], arp_entry->mac_addr[2], @@ -537,9 +533,9 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) /* set dynamic ARP*/ if (set_arp_flag == 1) { - if (arp_entry->op_type == ARP_SYNC_ADD) + if (arp_entry->op_type == NEIGH_SYNC_ADD) { - if (mlacp_fsm_arp_set(arp_entry->ifname, ntohl(arp_entry->ipv4_addr), mac_str) < 0) + if (iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_entry->ipv4_addr, 1, arp_entry->mac_addr, arp_entry->ifname) < 0) { ICCPD_LOG_WARN(__FUNCTION__, "ARP add failure for %s %s %s", arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str); @@ -548,7 +544,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) } else { - if (mlacp_fsm_arp_del(arp_entry->ifname, ntohl(arp_entry->ipv4_addr)) < 0) + if (iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_entry->ipv4_addr, 0, arp_entry->mac_addr, arp_entry->ifname) < 0) { ICCPD_LOG_WARN(__FUNCTION__, "ARP delete failure for %s %s %s", arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str); @@ -561,7 +557,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) } else { - ICCPD_LOG_DEBUG(__FUNCTION__, "Failure: port-channel is not alive"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Failure: port-channel is not alive"); /*TODO Set static route through peer-link or just skip it?*/ } @@ -569,7 +565,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) TAILQ_FOREACH(msg, &(MLACP(csm).arp_list), tail) { arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) { /*arp_msg->op_type = tlv->type;*/ sprintf(arp_msg->ifname, "%s", arp_entry->ifname); @@ -579,18 +575,18 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) } /* delete/add ARP list*/ - if (msg && arp_entry->op_type == ARP_SYNC_DEL) + if (msg && arp_entry->op_type == NEIGH_SYNC_DEL) { TAILQ_REMOVE(&(MLACP(csm).arp_list), msg, tail); free(msg->buf); free(msg); /*ICCPD_LOG_INFO(__FUNCTION__, "Del arp queue successfully");*/ } - else if (!msg && arp_entry->op_type == ARP_SYNC_ADD) + else if (!msg && arp_entry->op_type == NEIGH_SYNC_ADD) { arp_msg = (struct ARPMsg*)&arp_data; sprintf(arp_msg->ifname, "%s", arp_entry->ifname); - arp_msg->ipv4_addr = ntohl(arp_entry->ipv4_addr); + arp_msg->ipv4_addr = arp_entry->ipv4_addr; arp_msg->op_type = arp_entry->op_type; memcpy(arp_msg->mac_addr, arp_entry->mac_addr, ETHER_ADDR_LEN); if (iccp_csm_init_msg(&msg, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) @@ -604,7 +600,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) TAILQ_FOREACH(msg, &(MLACP(csm).arp_msg_list), tail) { arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) break; } @@ -617,7 +613,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) TAILQ_FOREACH(msg, &(MLACP(csm).arp_msg_list), tail) { arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) break; } } @@ -641,6 +637,216 @@ int mlacp_fsm_update_arp_info(struct CSM* csm, struct mLACPARPInfoTLV* tlv) } } +/***************************************** +* NDISC-Info Update +* ***************************************/ +int mlacp_fsm_update_ndisc_entry(struct CSM *csm, struct NDISCMsg *ndisc_entry) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, ndisc_data; + struct LocalInterface *local_if; + struct LocalInterface *peer_link_if = NULL; + struct VLAN_ID *vlan_id_list = NULL; + int set_ndisc_flag = 0; + char mac_str[18] = ""; + + if (!csm || !ndisc_entry) + return MCLAG_ERROR; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", ndisc_entry->mac_addr[0], ndisc_entry->mac_addr[1], ndisc_entry->mac_addr[2], + ndisc_entry->mac_addr[3], ndisc_entry->mac_addr[4], ndisc_entry->mac_addr[5]); + + ICCPD_LOG_NOTICE(__FUNCTION__, + "Received ND Info, intf[%s] IP[%s], MAC[%s]", ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); + + if (strncmp(ndisc_entry->ifname, "Vlan", 4) == 0) + { + peer_link_if = local_if_find_by_name(csm->peer_itf_name); + + if (peer_link_if && !local_if_is_l3_mode(peer_link_if)) + { + /* Is peer-linlk itf belong to a vlan the same as peer? */ + LIST_FOREACH(vlan_id_list, &(peer_link_if->vlan_list), port_next) + { + if (!vlan_id_list->vlan_itf) + continue; + if (strcmp(vlan_id_list->vlan_itf->name, ndisc_entry->ifname) != 0) + continue; + if (!local_if_is_l3_mode(vlan_id_list->vlan_itf)) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, + "ND is learnt from intf %s, peer-link %s is the member of this vlan", + vlan_id_list->vlan_itf->name, peer_link_if->name); + + /* Peer-link belong to L3 vlan is alive, set the NDISC info */ + set_ndisc_flag = 1; + + break; + } + } + } + + if (set_ndisc_flag == 0) + { + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + if (!local_if_is_l3_mode(local_if)) + { + /* Is the L2 MLAG itf belong to a vlan the same as peer? */ + LIST_FOREACH(vlan_id_list, &(local_if->vlan_list), port_next) + { + if (!vlan_id_list->vlan_itf) + continue; + if (strcmp(vlan_id_list->vlan_itf->name, ndisc_entry->ifname) != 0) + continue; + if (!local_if_is_l3_mode(vlan_id_list->vlan_itf)) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, + "ND is learnt from intf %s, %s is the member of this vlan", vlan_id_list->vlan_itf->name, local_if->name); + break; + } + + if (vlan_id_list && local_if->po_active == 1) + { + /* Any po of L3 vlan is alive, set the NDISC info */ + set_ndisc_flag = 1; + break; + } + } + else + { + /* Is the ARP belong to a L3 mode MLAG itf? */ + if (strcmp(local_if->name, ndisc_entry->ifname) == 0) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is learnt from mclag L3 intf %s", local_if->name); + if (local_if->po_active == 1) + { + /* po is alive, set the NDISC info */ + set_ndisc_flag = 1; + break; + } + } + else + { + continue; + } + } + } + } + } + + /* set dynamic Ndisc */ + if (set_ndisc_flag == 1) + { + if (ndisc_entry->op_type == NEIGH_SYNC_ADD) + { + if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_entry->ipv6_addr, 1, ndisc_entry->mac_addr, ndisc_entry->ifname) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to add nd entry(%s %s %s) to kernel", + ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); + return MCLAG_ERROR; + } + + } + else + { + if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_entry->ipv6_addr, 0, ndisc_entry->mac_addr, ndisc_entry->ifname) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to delete nd entry(%s %s %s) from kernel", + ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); + return MCLAG_ERROR; + } + + } + + /* ICCPD_LOG_DEBUG(__FUNCTION__, "NDISC update for %s %s %s", ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); */ + } + else + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Failure: port-channel is not alive"); + /* TODO Set static route through peer-link or just skip it? */ + } + + /* update NDISC list */ + TAILQ_FOREACH(msg, &(MLACP(csm).ndisc_list), tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16) == 0) + { + /* ndisc_msg->op_type = tlv->type; */ + sprintf(ndisc_msg->ifname, "%s", ndisc_entry->ifname); + memcpy(ndisc_msg->mac_addr, ndisc_entry->mac_addr, ETHER_ADDR_LEN); + break; + } + } + + /* delete/add NDISC list */ + if (msg && ndisc_entry->op_type == NEIGH_SYNC_DEL) + { + TAILQ_REMOVE(&(MLACP(csm).ndisc_list), msg, tail); + free(msg->buf); + free(msg); + /* ICCPD_LOG_INFO(__FUNCTION__, "Del ndisc queue successfully"); */ + } + else if (!msg && ndisc_entry->op_type == NEIGH_SYNC_ADD) + { + ndisc_msg = (struct NDISCMsg *)&ndisc_data; + sprintf(ndisc_msg->ifname, "%s", ndisc_entry->ifname); + memcpy((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16); + ndisc_msg->op_type = ndisc_entry->op_type; + memcpy(ndisc_msg->mac_addr, ndisc_entry->mac_addr, ETHER_ADDR_LEN); + if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0) + { + mlacp_enqueue_ndisc(csm, msg); + /* ICCPD_LOG_INFO(__FUNCTION__, "Add ndisc queue successfully"); */ + } + } + + /* remove all NDISC msg queue, when receive peer's NDISC list at the same time */ + TAILQ_FOREACH(msg, &(MLACP(csm).ndisc_msg_list), tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16) == 0) + break; + } + + while (msg) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + TAILQ_REMOVE(&(MLACP(csm).ndisc_msg_list), msg, tail); + free(msg->buf); + free(msg); + TAILQ_FOREACH(msg, &(MLACP(csm).ndisc_msg_list), tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16) == 0) + break; + } + } + + return 0; +} + +int mlacp_fsm_update_ndisc_info(struct CSM *csm, struct mLACPNDISCInfoTLV *tlv) +{ + int count = 0; + int i; + + if (!csm || !tlv) + return MCLAG_ERROR; + count = ntohs(tlv->num_of_entry); + ICCPD_LOG_INFO(__FUNCTION__, "Received NDISC Info count %d ", count); + + for (i = 0; i < count; i++) + { + mlacp_fsm_update_ndisc_entry(csm, &(tlv->NdiscEntry[i])); + } +} + /***************************************** * Port-Channel-Info Update * ***************************************/ @@ -703,10 +909,10 @@ int mlacp_fsm_update_peerlink_info(struct CSM* csm, } if (csm->peer_link_if->type != tlv->port_type) - ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port type of peer %d is not same with local %d !", tlv->port_type, csm->peer_link_if->type); + ICCPD_LOG_NOTICE(__FUNCTION__, "Peerlink port type of peer %d is not same with local %d !", tlv->port_type, csm->peer_link_if->type); if (tlv->port_type == IF_T_VXLAN && strncmp(csm->peer_itf_name, tlv->if_name, strlen(csm->peer_itf_name))) - ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port is vxlan port, but peerlink port of peer %s is not same with local %s !", tlv->if_name, csm->peer_itf_name); + ICCPD_LOG_NOTICE(__FUNCTION__, "Peerlink port is vxlan port, but peerlink port of peer %s is not same with local %s !", tlv->if_name, csm->peer_itf_name); return 0; } @@ -733,7 +939,7 @@ int mlacp_fsm_update_warmboot(struct CSM* csm, struct mLACPWarmbootTLV* tlv) return MCLAG_ERROR; time(&csm->peer_warm_reboot_time); - ICCPD_LOG_DEBUG(__FUNCTION__, "Receive warm reboot notification from peer!"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Receive warm reboot notification from peer!"); return 0; } diff --git a/src/iccpd/src/port.c b/src/iccpd/src/port.c index 1414a1f86c87..ce23515a00c8 100644 --- a/src/iccpd/src/port.c +++ b/src/iccpd/src/port.c @@ -329,11 +329,12 @@ void local_if_destroy(char *ifname) int local_if_is_l3_mode(struct LocalInterface* local_if) { int ret = 0; + char addr_null[16] = { 0 }; if (local_if == NULL) return 0; - if (local_if->ipv4_addr != 0) + if (local_if->ipv4_addr != 0 || memcmp(local_if->ipv6_addr, addr_null, 16) != 0) ret = 1; return ret; diff --git a/src/iccpd/src/scheduler.c b/src/iccpd/src/scheduler.c index 9d08e137dce0..c1a1532ccfe7 100644 --- a/src/iccpd/src/scheduler.c +++ b/src/iccpd/src/scheduler.c @@ -312,7 +312,7 @@ void scheduler_init() iccp_config_from_file(sys->config_file_path); /*Get kernel ARP info */ - iccp_arp_get_init(); + iccp_neigh_get_init(); if (iccp_connect_syncd() < 0) { diff --git a/src/iccpd/src/system.c b/src/iccpd/src/system.c index 9665b416ca52..33aca67f8079 100644 --- a/src/iccpd/src/system.c +++ b/src/iccpd/src/system.c @@ -57,6 +57,7 @@ void system_init(struct System* sys) sys->sync_fd = -1; sys->sync_ctrl_fd = -1; sys->arp_receive_fd = -1; + sys->ndisc_receive_fd = -1; sys->epoll_fd = -1; sys->family = -1; sys->warmboot_start = 0; @@ -132,6 +133,8 @@ void system_finalize() close(sys->sync_ctrl_fd); if (sys->arp_receive_fd > 0) close(sys->arp_receive_fd); + if (sys->ndisc_receive_fd > 0) + close(sys->ndisc_receive_fd); if (sys->sig_pipe_r > 0) close(sys->sig_pipe_r); if (sys->sig_pipe_w > 0) From 00383051f434aca23cf7d02c1db160479a7ac4d6 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 29 Apr 2020 22:45:46 -0700 Subject: [PATCH 0597/1427] [docker-iccpd]: disable iccpd build by default (#4502) Signed-off-by: Guohan Lu --- rules/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/config b/rules/config index c893a580b679..ab8a6941426d 100644 --- a/rules/config +++ b/rules/config @@ -117,7 +117,7 @@ DEFAULT_VS_PREPARE_MEM = yes # ENABLE_ICCPD - build docker-iccpd for mclag support -ENABLE_ICCPD = y +ENABLE_ICCPD = n # ENABLE_SYSTEM_SFLOW - build docker-sonic-sflow for sFlow support ENABLE_SFLOW = y From a539cf2f4694190a631f848e67da57f1c52b306d Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 30 Apr 2020 05:58:03 +0000 Subject: [PATCH 0598/1427] [build]: remove -t for non-tty terminal Signed-off-by: Guohan Lu --- Makefile.work | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.work b/Makefile.work index d9703000ddb6..ca98222c1699 100644 --- a/Makefile.work +++ b/Makefile.work @@ -259,7 +259,7 @@ sonic-slave-run : @docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null || \ { echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \ $(DOCKER_BUILD) ; } - @$(DOCKER_RUN) -t $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_RUN_CMDS)" + @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_RUN_CMDS)" showtag: @echo $(SLAVE_IMAGE):$(SLAVE_TAG) From e1ba5b0f5fa64b2eecebf9056f2cd075428ceaf6 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Thu, 30 Apr 2020 00:25:49 -0700 Subject: [PATCH 0599/1427] [docker-restapi]: add restapi config to config Db (#4495) --- rules/docker-restapi.mk | 2 +- src/sonic-config-engine/minigraph.py | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index b472e00491de..bd91aabd86c5 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -19,7 +19,7 @@ endif $(DOCKER_RESTAPI)_CONTAINER_NAME = restapi $(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t $(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock -$(DOCKER_RESTAPI)_RUN_OPT += -v /etc/sonic/certificates:/etc/sonic/certificates:ro +$(DOCKER_RESTAPI)_RUN_OPT += -v /etc/sonic/credentials:/etc/sonic/credentials:ro $(DOCKER_RESTAPI)_RUN_OPT += -p=8081:8081/tcp $(DOCKER_RESTAPI)_RUN_OPT += -p=8090:8090/tcp diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 71f6bb9fc72c..8f91fbe5c318 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -836,7 +836,19 @@ def parse_xml(filename, platform=None, port_config_file=None): 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' } } - + results['RESTAPI'] = { + 'config': { + 'client_auth': 'true', + 'allow_insecure': 'false', + 'log_level': 'trace' + }, + 'certs': { + 'server_crt': '/etc/sonic/credentials/restapiserver.crt', + 'server_key': '/etc/sonic/credentials/restapiserver.key', + 'client_ca_crt': '/etc/sonic/credentials/restapiclient.crt', + 'client_crt_cname': 'client.restapi.sonic' + } + } # Do not configure the minigraph's mirror session, which is currently unused # mirror_sessions = {} # if erspan_dst: From b6291372d98e47f9aaa5dd6c393ee4e02d3aa1ac Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Thu, 30 Apr 2020 10:30:11 +0300 Subject: [PATCH 0600/1427] [Mellanox] Add a new Mellanox platform x86_64-mlnx_msn4600c and new SKU ACS-MSN4600C (#4483) * New SKU support for MSN4600C Signed-off-by: Shlomi Bitton --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 2 +- .../ACS-MSN4600C/buffers.json.j2 | 1 + .../ACS-MSN4600C/buffers_defaults_t0.j2 | 1 + .../ACS-MSN4600C/buffers_defaults_t1.j2 | 1 + .../ACS-MSN4600C/pg_profile_lookup.ini | 1 + .../ACS-MSN4600C/port_config.ini | 65 +++ .../ACS-MSN4600C/qos.json.j2 | 1 + .../ACS-MSN4600C/sai.profile | 1 + .../ACS-MSN4600C/sai_4600C.xml | 470 ++++++++++++++++++ .../x86_64-mlnx_msn4600c-r0/default_sku | 1 + .../platform_components.json | 12 + .../x86_64-mlnx_msn4600c-r0/platform_reboot | 1 + .../x86_64-mlnx_msn4600c-r0/platform_wait | 1 + .../x86_64-mlnx_msn4600c-r0/plugins/eeprom.py | 1 + .../plugins/psuutil.py | 1 + .../plugins/sfplpmget.py | 1 + .../plugins/sfplpmset.py | 1 + .../plugins/sfpreset.py | 1 + .../plugins/sfputil.py | 1 + .../pmon_daemon_control.json | 1 + .../x86_64-mlnx_msn4600c-r0/sensors.conf | 193 +++++++ .../sonic_platform/chassis.py | 2 +- .../mlnx-platform-api/sonic_platform/psu.py | 2 +- .../sonic_platform/thermal.py | 18 +- 24 files changed, 776 insertions(+), 4 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t1.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/qos.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai.profile create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai_4600C.xml create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/default_sku create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/platform_reboot create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/platform_wait create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/eeprom.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/psuutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmget.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmset.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfpreset.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfputil.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/pmon_daemon_control.json create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 9e5ca4083264..647d967f84a1 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -41,7 +41,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5} +hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5, 'ACS-MSN4600C': 4} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1), (0, 48, 59, 60, 1)] def log_info(msg, also_print_to_console=False): diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers.json.j2 new file mode 120000 index 000000000000..f46e9600153b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..ddb883a1daa4 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..f8bbb6e631e7 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/pg_profile_lookup.ini new file mode 120000 index 000000000000..88e51ceae044 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/pg_profile_lookup.ini @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini new file mode 100644 index 000000000000..7ccff5a8da4b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini @@ -0,0 +1,65 @@ +# name lanes alias index +Ethernet0 0,1,2,3 etp1 0 +Ethernet8 8,9,10,11 etp2 1 +Ethernet16 16,17,18,19 etp3 2 +Ethernet24 24,25,26,27 etp4 3 +Ethernet32 32,33,34,35 etp5 4 +Ethernet40 40,41,42,43 etp6 5 +Ethernet48 48,49,50,51 etp7 6 +Ethernet56 56,57,58,59 etp8 7 +Ethernet64 64,65,66,67 etp9 8 +Ethernet72 72,73,74,75 etp10 9 +Ethernet80 80,81,82,83 etp11 10 +Ethernet88 88,89,90,91 etp12 11 +Ethernet96 96,97,98,99 etp13 12 +Ethernet104 104,105,106,107 etp14 13 +Ethernet112 112,113,114,115 etp15 14 +Ethernet120 120,121,122,123 etp16 15 +Ethernet128 128,129,130,131 etp17 16 +Ethernet136 136,137,138,139 etp18 17 +Ethernet144 144,145,146,147 etp19 18 +Ethernet152 152,153,154,155 etp20 19 +Ethernet160 160,161,162,163 etp21 20 +Ethernet168 168,169,170,171 etp22 21 +Ethernet176 176,177,178,179 etp23 22 +Ethernet184 184,185,186,187 etp24 23 +Ethernet192 192,193,194,195 etp25 24 +Ethernet200 200,201,202,203 etp26 25 +Ethernet208 208,209,210,211 etp27 26 +Ethernet216 216,217,218,219 etp28 27 +Ethernet224 224,225,226,227 etp29 28 +Ethernet232 232,233,234,235 etp30 29 +Ethernet240 240,241,242,243 etp31 30 +Ethernet248 248,249,250,251 etp32 31 +Ethernet256 256,257,258,259 etp33 32 +Ethernet264 264,265,266,267 etp34 33 +Ethernet272 272,273,274,275 etp35 34 +Ethernet280 280,281,282,283 etp36 35 +Ethernet288 288,289,290,291 etp37 36 +Ethernet296 296,297,298,299 etp38 37 +Ethernet304 304,305,306,307 etp39 38 +Ethernet312 312,313,314,315 etp40 39 +Ethernet320 320,321,322,323 etp41 40 +Ethernet328 328,329,330,331 etp42 41 +Ethernet336 336,337,338,339 etp43 42 +Ethernet344 344,345,346,347 etp44 43 +Ethernet352 352,353,354,355 etp45 44 +Ethernet360 360,361,362,363 etp46 45 +Ethernet368 368,369,370,371 etp47 46 +Ethernet376 376,377,378,379 etp48 47 +Ethernet384 384,385,386,387 etp49 48 +Ethernet392 392,393,394,395 etp50 49 +Ethernet400 400,401,402,403 etp51 50 +Ethernet408 408,409,410,411 etp52 51 +Ethernet416 416,417,418,419 etp53 52 +Ethernet424 424,425,426,427 etp54 53 +Ethernet432 432,433,434,435 etp55 54 +Ethernet440 440,441,442,443 etp56 55 +Ethernet448 448,449,450,451 etp57 56 +Ethernet456 456,457,458,459 etp58 57 +Ethernet464 464,465,466,467 etp59 58 +Ethernet472 472,473,474,475 etp60 59 +Ethernet480 480,481,482,483 etp61 60 +Ethernet488 488,489,490,491 etp62 61 +Ethernet496 496,497,498,499 etp63 62 +Ethernet504 504,505,506,507 etp64 63 diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/qos.json.j2 new file mode 120000 index 000000000000..8633303ece77 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai.profile b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai.profile new file mode 100644 index 000000000000..e9d1e3e5f591 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4600C.xml diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai_4600C.xml b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai_4600C.xml new file mode 100644 index 000000000000..02d0ed6ccd8e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai_4600C.xml @@ -0,0 +1,470 @@ + + + + + + 00:02:03:04:05:80 + + + 1 + + + 64 + + + + + 105 + 4 + 0 + + + 3 + + + 1536 + + + 107 + 4 + 1 + 3 + 1536 + + + 109 + 4 + 2 + 3 + 1536 + + + 111 + 4 + 3 + 3 + 1536 + + + 97 + 4 + 4 + 3 + 1536 + + + 99 + 4 + 5 + 3 + 1536 + + + 101 + 4 + 6 + 3 + 1536 + + + 103 + 4 + 7 + 3 + 1536 + + + 121 + 4 + 8 + 3 + 1536 + + + 123 + 4 + 9 + 3 + 1536 + + + 125 + 4 + 10 + 3 + 1536 + + + 127 + 4 + 11 + 3 + 1536 + + + 113 + 4 + 12 + 3 + 1536 + + + 115 + 4 + 13 + 3 + 1536 + + + 117 + 4 + 14 + 3 + 1536 + + + 119 + 4 + 15 + 3 + 1536 + + + 89 + 4 + 16 + 3 + 1536 + + + 91 + 4 + 17 + 3 + 1536 + + + 93 + 4 + 18 + 3 + 1536 + + + 95 + 4 + 19 + 3 + 1536 + + + 81 + 4 + 20 + 3 + 1536 + + + 83 + 4 + 21 + 3 + 1536 + + + 85 + 4 + 22 + 3 + 1536 + + + 87 + 4 + 23 + 3 + 1536 + + + 73 + 4 + 24 + 3 + 1536 + + + 75 + 4 + 25 + 3 + 1536 + + + 77 + 4 + 26 + 3 + 1536 + + + 79 + 4 + 27 + 3 + 1536 + + + 65 + 4 + 28 + 3 + 1536 + + + 67 + 4 + 29 + 3 + 1536 + + + 69 + 4 + 30 + 3 + 1536 + + + 71 + 4 + 31 + 3 + 1536 + + + 5 + 4 + 32 + 3 + 1536 + + + 7 + 4 + 33 + 3 + 1536 + + + 1 + 4 + 34 + 3 + 1536 + + + 3 + 4 + 35 + 3 + 1536 + + + 13 + 4 + 36 + 3 + 1536 + + + 15 + 4 + 37 + 3 + 1536 + + + 9 + 4 + 38 + 3 + 1536 + + + 11 + 4 + 39 + 3 + 1536 + + + 21 + 4 + 40 + 3 + 1536 + + + 23 + 4 + 41 + 3 + 1536 + + + 17 + 4 + 42 + 3 + 1536 + + + 19 + 4 + 43 + 3 + 1536 + + + 29 + 4 + 44 + 3 + 1536 + + + 31 + 4 + 45 + 3 + 1536 + + + 25 + 4 + 46 + 3 + 1536 + + + 27 + 4 + 47 + 3 + 1536 + + + 53 + 4 + 48 + 3 + 1536 + + + 55 + 4 + 49 + 3 + 1536 + + + 49 + 4 + 50 + 3 + 1536 + + + 51 + 4 + 51 + 3 + 1536 + + + 61 + 4 + 52 + 3 + 1536 + + + 63 + 4 + 53 + 3 + 1536 + + + 57 + 4 + 54 + 3 + 1536 + + + 59 + 4 + 55 + 3 + 1536 + + + 37 + 4 + 56 + 3 + 1536 + + + 39 + 4 + 57 + 3 + 1536 + + + 33 + 4 + 58 + 3 + 1536 + + + 35 + 4 + 59 + 3 + 1536 + + + 45 + 4 + 60 + 3 + 1536 + + + 47 + 4 + 61 + 3 + 1536 + + + 41 + 4 + 62 + 3 + 1536 + + + 43 + 4 + 63 + 3 + 1536 + + + + \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/default_sku b/device/mellanox/x86_64-mlnx_msn4600c-r0/default_sku new file mode 100644 index 000000000000..451382f6d8b8 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/default_sku @@ -0,0 +1 @@ +ACS-MSN4600C t1 diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json new file mode 100644 index 000000000000..300a3827a0c4 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json @@ -0,0 +1,12 @@ +{ + "chassis": { + "x86_64-mlnx_msn4600c-r0": { + "component": { + "BIOS": { }, + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_reboot new file mode 120000 index 000000000000..43c8ea567493 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_reboot @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_wait new file mode 120000 index 000000000000..4b30bd429854 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_wait @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_wait \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/eeprom.py new file mode 120000 index 000000000000..b4e2a6a61671 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/eeprom.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/psuutil.py new file mode 120000 index 000000000000..9f724238a8d5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/psuutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmget.py new file mode 120000 index 000000000000..2e84f435abd9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmget.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmset.py new file mode 120000 index 000000000000..6a88bac30467 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfpreset.py new file mode 120000 index 000000000000..fef2063e3496 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfpreset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfpreset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfputil.py new file mode 120000 index 000000000000..45909b880fc9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfputil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/pmon_daemon_control.json new file mode 120000 index 000000000000..435a2ce7c0ba --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pmon_daemon_control.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf new file mode 100644 index 000000000000..b2f942ffa5f8 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf @@ -0,0 +1,193 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN4600C +################################################################################ + +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" + +bus "i2c-7" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-*-49" + label temp1 "Ambient Fan Side Temp (air intake)" + chip "tmp102-i2c-*-4a" + label temp1 "Ambient Port Side Temp (air exhaust)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-15-49" + label temp1 "Ambient COMEX Temp" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 4)" + chip "xdpe12284-i2c-*-62" + label in1 "PMIC-1 PSU 12V Rail (in)" + label in2 "PMIC-1 PSU 12V Rail (in)" + label in3 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail (out)" + ignore in4 + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 ASIC 12V VCORE_MAIN Rail Pwr (in)" + ignore power2 + label power3 "PMIC-1 ASIC 12V VCORE_MAIN Rail Pwr (out)" + ignore power4 + label curr1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (in)" + ignore curr2 + label curr3 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (out)" + ignore curr4 + chip "xdpe12284-i2c-*-64" + label in1 "PMIC-2 PSU 12V Rail (in)" + label in2 "PMIC-2 PSU 12V Rail (in)" + label in3 "PMIC-2 ASIC 1.8V MAIN Rail (out)" + label in4 "PMIC-2 ASIC 1.2V MAIN Rail (out)" + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 ASIC 1.8V MAIN Rail Pwr (in)" + label power2 "PMIC-2 ASIC 1.2V MAIN Rail Pwr (in)" + label power3 "PMIC-2 ASIC 1.8V MAIN Rail Pwr (out)" + label power4 "PMIC-2 ASIC 1.2V MAIN Rail Pwr (out)" + label curr1 "PMIC-2 ASIC 1.8V MAIN Rail Curr (in)" + label curr2 "PMIC-2 ASIC 1.2V MAIN Rail Curr (in)" + label curr3 "PMIC-2 ASIC 1.8V MAIN Rail Curr (out)" + label curr4 "PMIC-2 ASIC 1.2V MAIN Rail Curr (out)" + chip "xdpe12284-i2c-*-66" + label in1 "PMIC-3 PSU 12V Rail (in)" + label in2 "PMIC-3 PSU 12V Rail (in)" + label in3 "PMIC-3 ASIC 0.85V MAIN Rail (out)" + label in4 "PMIC-3 ASIC 1.8V MAIN Rail (out)" + label temp1 "PMIC-3 Temp 1" + label temp2 "PMIC-3 Temp 2" + label power1 "PMIC-3 ASIC 12V MAIN Rail Pwr (in)" + label power2 "PMIC-3 ASIC 12V MAIN Rail Pwr (in)" + label power3 "PMIC-3 ASIC 0.85V MAIN Rail Pwr (out)" + label power4 "PMIC-3 ASIC 1.8V MAIN Rail Pwr (out)" + label curr1 "PMIC-3 ASIC 12V MAIN Rail Curr (in)" + label curr2 "PMIC-3 ASIC 12V MAIN Rail Curr (in)" + label curr3 "PMIC-3 ASIC 0.85V MAIN Rail Curr (out)" + label curr4 "PMIC-3 ASIC 1.8V MAIN Rail Curr (out)" + chip "xdpe12284-i2c-*-68" + label in1 "PMIC-4 PSU 12V Rail (in)" + label in2 "PMIC-4 PSU 12V Rail (in)" + label in3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-4 ASIC 1.8V T6_7 Rail (out)" + label temp1 "PMIC-4 Temp 1" + label temp2 "PMIC-4 Temp 2" + label power1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-4 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-4 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-6a" + label in1 "PMIC-5 PSU 12V Rail (in)" + label in2 "PMIC-5 PSU 12V Rail (in)" + label in3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-5 ASIC 1.8V T6_7 Rail (out)" + label temp1 "PMIC-5 Temp 1" + label temp2 "PMIC-5 Temp 2" + label power1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-5 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-5 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-6c" + label in1 "PMIC-6 PSU 12V Rail (in)" + label in2 "PMIC-6 PSU 12V Rail (in)" + label in3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-6 ASIC 1.8V T6_7 Rail (out)" + label temp1 "PMIC-6 Temp 1" + label temp2 "PMIC-6 Temp 2" + label power1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-6e" + label in1 "PMIC-7 PSU 12V Rail (in)" + label in2 "PMIC-7 PSU 12V Rail (in)" + label in3 "PMIC-7 ASIC 1.2V VCORE_T6_7 Rail (out)" + label in4 "PMIC-7 ASIC 1.2V T6_7 Rail (out)" + label temp1 "PMIC-7 Temp 1" + label temp2 "PMIC-7 Temp 2" + label power1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (out)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tps53679-i2c-*-58" + label in1 "PMIC-8 PSU 12V Rail (in)" + label in2 "PMIC-8 PSU 12V Rail (in)" + label in3 "PMIC-8 COMEX 1.8V Rail (out)" + label in4 "PMIC-8 COMEX 1.05V Rail (out)" + label temp1 "PMIC-8 Temp 1" + label temp2 "PMIC-8 Temp 2" + label power1 "PMIC-8 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-8 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-8 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-8 COMEX 1.05V Rail Curr (out)" + chip "tps53679-i2c-*-61" + label in1 "PMIC-9 PSU 12V Rail (in)" + label in2 "PMIC-9 PSU 12V Rail (in)" + label in3 "PMIC-9 COMEX 1.2V Rail (out)" + ignore in4 + label temp1 "PMIC-9 Temp 1" + label temp2 "PMIC-9 Temp 2" + label power1 "PMIC-9 COMEX 1.2V Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-9 COMEX 1.2V Rail Curr (out)" + ignore curr2 + +# Power supplies +bus "i2c-4" "i2c-1-mux (chan_id 3)" + chip "dps460-i2c-*-58" + label in1 "PSU-2(R) 220V Rail (in)" + label in2 "PSU-2(R) 220V Rail (in)" + label in3 "PSU-2(R) 12V Rail (out)" + label fan1 "PSU-2(R) Fan 1" + ignore fan2 + ignore fan3 + label temp1 "PSU-2(R) Temp 1" + label temp2 "PSU-2(R) Temp 2" + label temp3 "PSU-2(R) Temp 3" + label power1 "PSU-2(R) 220V Rail Pwr (in)" + label power2 "PSU-2(R) 12V Rail Pwr (out)" + label curr1 "PSU-2(R) 220V Rail Curr (in)" + label curr2 "PSU-2(R) 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-1(L) 220V Rail (in)" + label in2 "PSU-1(L) 220V Rail (in)" + label in3 "PSU-1(L) 12V Rail (out)" + label fan1 "PSU-1(L) Fan 1" + ignore fan2 + ignore fan3 + label temp1 "PSU-1(L) Temp 1" + label temp2 "PSU-1(L) Temp 2" + label temp3 "PSU-1(L) Temp 3" + label power1 "PSU-1(L) 220V Rail Pwr (in)" + label power2 "PSU-1(L) 12V Rail Pwr (out)" + label curr1 "PSU-1(L) 220V Rail Curr (in)" + label curr2 "PSU-1(L) 12V Rail Curr (out)" + +# Chassis fans +chip "mlxreg_fan-isa-*" + label fan1 "Chassis Fan Drawer-1" + label fan2 "Chassis Fan Drawer-2" + label fan3 "Chassis Fan Drawer-3" + +# Miscellaneous +chip "*-virtual-*" + ignore temp1 diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index c3642331d19b..5ecf3c150de9 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -50,7 +50,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5} +hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5, 'ACS-MSN4600C': 4} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1), (0, 48, 59, 60, 1)] class Chassis(ChassisBase): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 6931cc0657c8..158be0c059e6 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -37,7 +37,7 @@ # in most SKUs the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. # but there are exceptions which will be handled by the following dictionary -hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1, 'ACS-MSN3420': 1} +hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1, 'ACS-MSN3420': 1, 'ACS-MSN4600C': 1} psu_profile_list = [ # default filename convention { diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index d4b9d56dc192..be91cf9d523e 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -124,7 +124,7 @@ THERMAL_API_GET_HIGH_THRESHOLD ] -hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8, 'ACS-MSN3420': 9} +hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8, 'ACS-MSN3420': 9, 'ACS-MSN4600C': 9} thermal_profile_list = [ # 2700 { @@ -280,6 +280,22 @@ THERMAL_DEV_FAN_AMBIENT ] ) + }, + # 4600C + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 64), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_COMEX_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) } ] From 799f22d4c72b92637cc2be6f5f7dcde81e7b1a94 Mon Sep 17 00:00:00 2001 From: Olivier Singla <47356901+olivier-singla@users.noreply.github.com> Date: Thu, 30 Apr 2020 03:33:20 -0400 Subject: [PATCH 0601/1427] [baseimage]: Run fsck filesystem check support prior mounting filesystem (#4431) * Run fsck filesystem check support prior mounting filesystem If the filesystem become non clean ("dirty"), SONiC does not run fsck to repair and mark it as clean again. This patch adds the functionality to run fsck on each boot, prior to the filesystem being mounted. This allows the filesystem to be repaired if needed. Note that if the filesystem is maked as clean, fsck does nothing and simply return so this is perfectly fine to call fsck every time prior to mount the filesystem. How to verify this patch (using bash): Using an image without this patch: Make the filesystem "dirty" (not clean) [we are making the assumption that filesystem is stored in /dev/sda3 - Please adjust depending of the platform] [do this only on a test platform!] dd if=/dev/sda3 of=superblock bs=1 count=2048 printf "$(printf '\\x%02X' 2)" | dd of="superblock" bs=1 seek=1082 count=1 conv=notrunc &> /dev/null dd of=/dev/sda3 if=superblock bs=1 count=2048 Verify that filesystem is not clean tune2fs -l /dev/sda3 | grep "Filesystem state:" reboot and verify that the filesystem is still not clean Redo the same test with an image with this patch, and verify that at next reboot the filesystem is repaired and becomes clean. fsck log is stored on syslog, using the string FSCK as markup. --- build_debian.sh | 4 ++++ files/image_config/platform/rc.local | 6 +++++ files/initramfs-tools/fsck-rootfs | 34 ++++++++++++++++++++++++++++ files/initramfs-tools/union-mount.j2 | 7 ++++++ 4 files changed, 51 insertions(+) create mode 100644 files/initramfs-tools/fsck-rootfs diff --git a/build_debian.sh b/build_debian.sh index 1b7024a304ee..a805d34b9391 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -165,6 +165,10 @@ sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/arista- sudo cp files/initramfs-tools/resize-rootfs $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/resize-rootfs sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/resize-rootfs +# Hook into initramfs: run fsck to repair a non-clean filesystem prior to be mounted +sudo cp files/initramfs-tools/fsck-rootfs $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/fsck-rootfs +sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/fsck-rootfs + ## Hook into initramfs: after partition mount and loop file mount ## 1. Prepare layered file system ## 2. Bind-mount docker working directory (docker overlay storage cannot work over overlay rootfs) diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index 2884270b7870..ad67f0ff425a 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -340,4 +340,10 @@ if [ -f $FIRST_BOOT_FILE ]; then firsttime_exit fi +# Copy the fsck log into syslog +if [ -f /var/log/fsck.log.gz ]; then + gunzip -d -c /var/log/fsck.log.gz | logger -t "FSCK" + rm -f /var/log/fsck.log.gz +fi + exit 0 diff --git a/files/initramfs-tools/fsck-rootfs b/files/initramfs-tools/fsck-rootfs new file mode 100644 index 000000000000..25b1c096aa5b --- /dev/null +++ b/files/initramfs-tools/fsck-rootfs @@ -0,0 +1,34 @@ +#!/bin/sh + +case $1 in + prereqs) + exit 0 + ;; +esac + +# Extract kernel parameters +root_val="" +set -- $(cat /proc/cmdline) +for x in "$@"; do + case "$x" in + root=*) + root_val="${x#root=}" + ;; + esac +done + +# Check the filesystem we are using +if [ ! -z $root_val ]; then + fstype=$(blkid -o value -s TYPE $root_val) + case "$fstype" in + ext4) + cmd="fsck.ext4 -v -p" + ;; + ext3) + cmd="fsck.ext3 -v -p" + ;; + esac + if [ ! -z "$cmd" ]; then + $cmd $root_val 2>&1 | gzip -c > /tmp/fsck.log.gz + fi +fi diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index 0fadb9a73edb..5e33e1760874 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -85,5 +85,12 @@ then mount -t tmpfs -o rw,nosuid,nodev,size=${varlogsize}M tmpfs ${rootmnt}/var/log [ -f ${rootmnt}/host/disk-img/var-log.ext4 ] && rm -rf ${rootmnt}/host/disk-img/var-log.ext4 else + [ -f ${rootmnt}/host/disk-img/var-log.ext4 ] && fsck.ext4 -v -p ${rootmnt}/host/disk-img/var-log.ext4 2>&1 \ + | gzip -c >> /tmp/fsck.log.gz [ -f ${rootmnt}/host/disk-img/var-log.ext4 ] && mount -t ext4 -o loop,rw ${rootmnt}/host/disk-img/var-log.ext4 ${rootmnt}/var/log fi + +## fscklog file: /tmp will be lost when overlayfs is mounted +if [ -f /tmp/fsck.log.gz ]; then + mv /tmp/fsck.log.gz ${rootmnt}/var/log +fi From 685064464002add5b6b20c6ca4f9d59975c51955 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 30 Apr 2020 17:17:58 +0000 Subject: [PATCH 0602/1427] [vs]: add missing dvslib link for the vs test Signed-off-by: Guohan Lu --- platform/vs/tests/dvslib | 1 + 1 file changed, 1 insertion(+) create mode 120000 platform/vs/tests/dvslib diff --git a/platform/vs/tests/dvslib b/platform/vs/tests/dvslib new file mode 120000 index 000000000000..4bab298a1800 --- /dev/null +++ b/platform/vs/tests/dvslib @@ -0,0 +1 @@ +../../../src/sonic-swss/tests/dvslib \ No newline at end of file From a87bf4df838d67ba92ace223e50b0e9cd288c698 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Fri, 1 May 2020 01:30:58 +0800 Subject: [PATCH 0603/1427] [Mellanox] Fix error in sensors.conf for 3700/3700c/3800 (#4506) --- .../x86_64-mlnx_msn3700-r0/sensors.conf | 30 +++++++------ .../x86_64-mlnx_msn3700c-r0/sensors.conf | 30 +++++++------ .../x86_64-mlnx_msn3800-r0/sensors.conf | 42 +++++++++++-------- 3 files changed, 58 insertions(+), 44 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf index 376d079390a6..28a889aa27d2 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf @@ -22,9 +22,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "tps53679-i2c-*-70" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 ASIC 0.8V VCORE Rail (out)" - label in3 "PMIC-1 ASIC 1.2V Rail (out)" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 ASIC 0.8V VCORE Rail (out)" + label in4 "PMIC-1 ASIC 1.2V Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" label power1 "PMIC-1 ASIC 0.8V VCORE Rail Pwr (out)" @@ -32,10 +33,11 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-1 ASIC 0.8V VCORE Rail Curr (out)" label curr2 "PMIC-1 ASIC 1.2V Rail Curr (out)" chip "tps53679-i2c-*-71" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 ASIC 3.3V Rail (out)" - compute in2 (1.5)*@, @/(1.5) - label in3 "PMIC-2 ASIC 1.8V Rail (out)" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 ASIC 3.3V Rail (out)" + compute in3 (1.5)*@, @/(1.5) + label in4 "PMIC-2 ASIC 1.8V Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" label power1 "PMIC-2 ASIC 3.3V Rail Pwr (out)" @@ -45,9 +47,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 COMEX 1.8V Rail (out)" - label in3 "PMIC-3 COMEX 1.05V Rail (out)" + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 COMEX 1.8V Rail (out)" + label in4 "PMIC-3 COMEX 1.05V Rail (out)" label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" label power1 "PMIC-3 COMEX 1.8V Rail Pwr (out)" @@ -55,9 +58,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-3 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-3 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 COMEX 1.2V Rail (out)" - ignore in3 + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 COMEX 1.2V Rail (out)" + ignore in4 label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" label power1 "PMIC-4 COMEX 1.2V Rail Pwr (out)" diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf index 7efcefc5f740..3c58e27f3e68 100644 --- a/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf @@ -22,9 +22,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "tps53679-i2c-*-70" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 ASIC 0.8V VCORE Rail (out)" - label in3 "PMIC-1 ASIC 1.2V Rail (out)" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 ASIC 0.8V VCORE Rail (out)" + label in4 "PMIC-1 ASIC 1.2V Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" label power1 "PMIC-1 ASIC 0.8V VCORE Rail Pwr (out)" @@ -32,10 +33,11 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-1 ASIC 0.8V VCORE Rail Curr (out)" label curr2 "PMIC-1 ASIC 1.2V Rail Curr (out)" chip "tps53679-i2c-*-71" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 ASIC 3.3V Rail (out)" - compute in2 (1.5)*@, @/(1.5) - label in3 "PMIC-2 ASIC 1.8V Rail (out)" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 ASIC 3.3V Rail (out)" + compute in3 (1.5)*@, @/(1.5) + label in4 "PMIC-2 ASIC 1.8V Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" label power1 "PMIC-2 ASIC 3.3V Rail Pwr (out)" @@ -45,9 +47,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 COMEX 1.8V Rail (out)" - label in3 "PMIC-3 COMEX 1.05V Rail (out)" + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 COMEX 1.8V Rail (out)" + label in4 "PMIC-3 COMEX 1.05V Rail (out)" label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" label power1 "PMIC-3 COMEX 1.8V Rail Pwr (out)" @@ -55,9 +58,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-3 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-3 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 COMEX 1.2V Rail (out)" - ignore in3 + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 COMEX 1.2V Rail (out)" + ignore in4 label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" label power1 "PMIC-4 COMEX 1.2V Rail Pwr (out)" diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf index fab58890adfb..9777c5e84398 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf @@ -22,9 +22,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "tps53679-i2c-*-70" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 ASIC 0.8V VCORE Rail (out)" - label in3 "PMIC-1 ASIC 1.2V Rail (out)" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 ASIC 0.8V VCORE Rail (out)" + label in4 "PMIC-1 ASIC 1.2V Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" label power1 "PMIC-1 ASIC 0.8V VCORE Rail Pwr (out)" @@ -32,9 +33,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-1 ASIC 0.8V VCORE Rail Curr (out)" label curr2 "PMIC-1 ASIC 1.2V Rail Curr (out)" chip "tps53679-i2c-*-71" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 GB 0.8V Rail (out)" - label in3 "PMIC-2 GB 1.125V Rail (out)" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 GB 0.8V Rail (out)" + label in4 "PMIC-2 GB 1.125V Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" label power1 "PMIC-2 GB 0.8V Rail Pwr (out)" @@ -42,9 +44,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-2 GB 0.8V Rail Curr (out)" label curr2 "PMIC-2 GB 1.125V Rail Curr (out)" chip "tps53679-i2c-*-72" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 ASIC 1.8V Rail (out)" - ignore in3 + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 ASIC 1.8V Rail (out)" + ignore in4 label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" label power1 "PMIC-3 ASIC 1.8V Rail Pwr (out)" @@ -52,9 +55,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-3 ASIC 1.8V Rail Curr (out)" ignore curr2 chip "tps53679-i2c-*-73" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 GB 0.8V Rail (out)" - label in3 "PMIC-4 GB 1.125V Rail (out)" + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 GB 0.8V Rail (out)" + label in4 "PMIC-4 GB 1.125V Rail (out)" label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" label power1 "PMIC-4 GB 0.8V Rail Pwr (out)" @@ -64,9 +68,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-5 PSU 12V Rail (in)" - label in2 "PMIC-5 COMEX 1.8V Rail (out)" - label in3 "PMIC-5 COMEX 1.05V Rail (out)" + label in1 "PMIC-5 PSU 12V Rail (in1)" + label in2 "PMIC-5 PSU 12V Rail (in2)" + label in3 "PMIC-5 COMEX 1.8V Rail (out)" + label in4 "PMIC-5 COMEX 1.05V Rail (out)" label temp1 "PMIC-5 Temp 1" label temp2 "PMIC-5 Temp 2" label power1 "PMIC-5 COMEX 1.8V Rail Pwr (out)" @@ -74,9 +79,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-5 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-5 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-6 PSU 12V Rail (in)" - label in2 "PMIC-6 COMEX 1.2V Rail (out)" - ignore in3 + label in1 "PMIC-6 PSU 12V Rail (in1)" + label in2 "PMIC-6 PSU 12V Rail (in2)" + label in3 "PMIC-6 COMEX 1.2V Rail (out)" + ignore in4 label temp1 "PMIC-6 Temp 1" label temp2 "PMIC-6 Temp 2" label power1 "PMIC-6 COMEX 1.2V Rail Pwr (out)" From 80a025a7c20f5d04112352a48fd049e687be76e0 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Thu, 30 Apr 2020 12:06:19 -0700 Subject: [PATCH 0604/1427] [arista] update platform driver submodules (#4512) - Add Makefile rules to build debug containers for SWI images - Fix some platform API implementation for xcvrd and thermalctld - Improvements to arista diag command - Miscellaneous refactors Co-authored-by: Maxime Lorrillere --- platform/barefoot/one-aboot.mk | 5 +++++ platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/one-aboot.mk | 5 +++++ platform/broadcom/sonic-platform-modules-arista | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/one-aboot.mk b/platform/barefoot/one-aboot.mk index 4e5e808d2ab9..a2cdf2ac0391 100644 --- a/platform/barefoot/one-aboot.mk +++ b/platform/barefoot/one-aboot.mk @@ -11,5 +11,10 @@ $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(ARISTA_PLATFORM_MODULE_DRIVERS) \ $(ARISTA_PLATFORM_MODULE_PYTHON2) \ $(ARISTA_PLATFORM_MODULE_PYTHON3) \ $(ARISTA_PLATFORM_MODULE) +ifeq ($(INSTALL_DEBUG_TOOLS),y) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) +else $(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) +endif SONIC_INSTALLERS += $(SONIC_ONE_ABOOT_IMAGE) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index ab4e8e17e610..c52f43edbe2e 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit ab4e8e17e610e23d66b024fbf27bd83b41edf44c +Subproject commit c52f43edbe2ec842d5a807c71a4aba453ce60490 diff --git a/platform/broadcom/one-aboot.mk b/platform/broadcom/one-aboot.mk index f68319ab6449..959cda20907e 100644 --- a/platform/broadcom/one-aboot.mk +++ b/platform/broadcom/one-aboot.mk @@ -6,5 +6,10 @@ $(SONIC_ONE_ABOOT_IMAGE)_IMAGE_TYPE = aboot $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(BRCM_OPENNSL_KERNEL) $(ARISTA_PLATFORM_MODULE_DRIVERS) $(ARISTA_PLATFORM_MODULE_PYTHON2) $(ARISTA_PLATFORM_MODULE_PYTHON3) $(ARISTA_PLATFORM_MODULE) $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(PHY_CREDO) $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +ifeq ($(INSTALL_DEBUG_TOOLS),y) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) +else $(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) +endif SONIC_INSTALLERS += $(SONIC_ONE_ABOOT_IMAGE) diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index ab4e8e17e610..c52f43edbe2e 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit ab4e8e17e610e23d66b024fbf27bd83b41edf44c +Subproject commit c52f43edbe2ec842d5a807c71a4aba453ce60490 From 4c210f0d02d7dc5a8ca54a4a6c526c0c1c5b0fb0 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Fri, 1 May 2020 03:42:01 +0800 Subject: [PATCH 0605/1427] [Mellanox] Enhancement for support PSU LED management (#4467) --- .../mlnx-platform-api/sonic_platform/psu.py | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 158be0c059e6..1486dc0bc854 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -81,6 +81,8 @@ def __init__(self, psu_index, sku): self.psu_current = None self.psu_power = None self.psu_presence = None + self.psu_temp = None + self.psu_temp_threshold = None else: self.always_presence = False psu_voltage = filemap[PSU_VOLTAGE].format(self.index) @@ -99,6 +101,9 @@ def __init__(self, psu_index, sku): psu_presence = os.path.join(self.psu_path, psu_presence) self.psu_presence = psu_presence + self.psu_temp = os.path.join(self.psu_path, 'thermal/psu{}_temp'.format(self.index)) + self.psu_temp_threshold = os.path.join(self.psu_path, 'thermal/psu{}_temp_max'.format(self.index)) + # unplugable PSU has no FAN if sku not in hwsku_dict_with_unplugable_psu: fan = Fan(False, psu_index, psu_index, True) @@ -307,3 +312,59 @@ def get_power_available_status(self): else: return True, "" + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + if self.psu_temp is not None and self.get_powergood_status(): + try: + temp = self._read_generic_file(self.psu_temp, 0) + return float(temp) / 1000 + except Exception as e: + logger.log_info("Fail to get temperature for PSU {} due to - {}".format(self._name, repr(e))) + + return None + + def get_temperature_high_threshold(self): + """ + Retrieves the high threshold temperature of PSU + + Returns: + A float number, the high threshold temperature of PSU in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + if self.psu_temp_threshold is not None and self.get_powergood_status(): + try: + temp_threshold = self._read_generic_file(self.psu_temp_threshold, 0) + return float(temp_threshold) / 1000 + except Exception as e: + logger.log_info("Fail to get temperature threshold for PSU {} due to - {}".format(self._name, repr(e))) + + return None + + def get_voltage_high_threshold(self): + """ + Retrieves the high threshold PSU voltage output + + Returns: + A float number, the high threshold output voltage in volts, + e.g. 12.1 + """ + # hw-management doesn't expose those sysfs for now + raise NotImplementedError + + def get_voltage_low_threshold(self): + """ + Retrieves the low threshold PSU voltage output + + Returns: + A float number, the low threshold output voltage in volts, + e.g. 12.1 + """ + # hw-management doesn't expose those sysfs for now + raise NotImplementedError + From 2153caef59bb940097d4060e02fd5841fa5a0b7b Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Thu, 30 Apr 2020 22:45:12 +0300 Subject: [PATCH 0606/1427] [submodule]: Advance sonic-platform-common. (#4513) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commits on Mar 20, 2020 SFP(sff8472 attributes) transciever eeprom attribute support. (#74) 9b1dea5 Commits on Mar 22, 2020 Detect an SFP adapter in a QSFP port, and instantiate an SFP object i… 116eeec Commits on Apr 13, 2020 [component]: Introduce new firmware management API. 2632a59 Commits on Apr 16, 2020 [Chassis base] Add sfp error event definition (#80) f1f00ec Commits on Apr 24, 2020 [component]: Update firmware management API. 777901f [component]: Extend docstrings for firmware management API. b066ec7 Commits on Apr 30, 2020 [component]: Fix review comments. d96344e Merge pull request #82 from nazariig/master-component-firmware-api 28c39c5 Signed-off-by: Nazarii Hnydyn --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index dc59b105ff23..28c39c55666d 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit dc59b105ff234bd89b9042c934b17c10b9b261f7 +Subproject commit 28c39c55666dcaef10f62492906c1399eec4ccba From 86bc8aec5f3fda41c1fc9ae5d14deddec9d3ee6d Mon Sep 17 00:00:00 2001 From: lguohan Date: Thu, 30 Apr 2020 12:50:59 -0700 Subject: [PATCH 0607/1427] [vs]: dynamically create front panel ports in vs docker (#4499) currently, vs docker always create 32 front panel ports. when vs docker starts, it first detects the peer links in the namespace and then setup equal number of front panel interfaces as the peer links. Signed-off-by: Guohan Lu --- files/build_templates/buffers_config.j2 | 2 +- platform/vs/README.vsdocker.md | 40 ++++--------------------- platform/vs/create_vnet.sh | 30 +++++++++++++++---- platform/vs/docker-sonic-vs/start.sh | 19 +++++++++++- 4 files changed, 50 insertions(+), 41 deletions(-) diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index a5212d979fcb..ba4dcf49e813 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -7,7 +7,7 @@ def {%- endmacro -%} {# Determine device topology and filename postfix #} -{%- if DEVICE_METADATA is defined %} +{%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost']['type'] is defined %} {%- set switch_role = DEVICE_METADATA['localhost']['type'] %} {%- if switch_role.lower() == 'torrouter' %} {%- set filename_postfix = 't0' %} diff --git a/platform/vs/README.vsdocker.md b/platform/vs/README.vsdocker.md index 42e1cafc8469..694631f095db 100644 --- a/platform/vs/README.vsdocker.md +++ b/platform/vs/README.vsdocker.md @@ -1,42 +1,12 @@ HOWTO Use Virtual Switch (Docker) -1. Create a docker with 32 front panel port +1. Create a docker with two front panel ports ``` $ docker run -id --name sw debian bash -$ sudo ./create_vnet.sh sw +$ sudo ./create_vnet.sh -n 2 sw $ ip netns list -sw-srv31 (id: 37) -sw-srv30 (id: 35) -sw-srv29 (id: 34) -sw-srv28 (id: 33) -sw-srv27 (id: 32) -sw-srv26 (id: 31) -sw-srv25 (id: 30) -sw-srv24 (id: 29) -sw-srv23 (id: 28) -sw-srv22 (id: 27) -sw-srv21 (id: 26) -sw-srv20 (id: 25) -sw-srv19 (id: 24) -sw-srv18 (id: 23) -sw-srv17 (id: 22) -sw-srv16 (id: 21) -sw-srv15 (id: 20) -sw-srv14 (id: 19) -sw-srv13 (id: 18) -sw-srv12 (id: 17) -sw-srv11 (id: 16) -sw-srv10 (id: 15) -sw-srv9 (id: 14) -sw-srv8 (id: 13) -sw-srv7 (id: 12) -sw-srv6 (id: 11) -sw-srv5 (id: 10) -sw-srv4 (id: 9) -sw-srv3 (id: 8) -sw-srv2 (id: 7) sw-srv1 (id: 6) sw-srv0 (id: 5) ``` @@ -51,8 +21,10 @@ $ docker run --privileged --network container:sw --name vs -d docker-sonic-vs ``` $ docker exec -it vs bash -root@2e9b5c2dc2a2:/# ifconfig Ethernet0 10.0.0.0/31 up -root@2e9b5c2dc2a2:/# ifconfig Ethernet4 10.0.0.2/31 up +root@2e9b5c2dc2a2:/# config interface ip add Ethernet0 10.0.0.0/31 +root@2e9b5c2dc2a2:/# config interface ip add Ethernet4 10.0.0.2/31 +root@2e9b5c2dc2a2:/# config interface startup Ethernet0 +root@2e9b5c2dc2a2:/# config interface startup Ethernet4 ``` 4. Setup IP in the server network namespace diff --git a/platform/vs/create_vnet.sh b/platform/vs/create_vnet.sh index 4746e16cbbaf..2217bbbd0220 100755 --- a/platform/vs/create_vnet.sh +++ b/platform/vs/create_vnet.sh @@ -1,4 +1,24 @@ -#!/bin/bash +#!/bin/bash -e + +usage() { + echo "Usage: $0 [-n ] swname" 1>&2 + exit 1 +} + +SERVERS=2 + +while getopts ":n:" opt; do + case $opt in + n) + SERVERS=$((OPTARG)) + ;; + *) + usage + ;; + esac +done + +shift $((OPTIND-1)) SWNAME=$1 @@ -6,9 +26,8 @@ pid=$(docker inspect --format '{{.State.Pid}}' $SWNAME) echo Seting up servers -SERVERS=31 -for srv in `seq 0 $SERVERS`; do +for srv in `seq 0 $((SERVERS-1))`; do SRV="$SWNAME-srv$srv" @@ -24,9 +43,10 @@ for srv in `seq 0 $SERVERS`; do IF="eth$((srv+1))" - ip link add ${SRV}eth0 type veth peer name $IF + ip link add ${SRV}eth0 type veth peer name $SWNAME-$IF ip link set ${SRV}eth0 netns $SRV - ip link set $IF netns ${pid} + ip link set $SWNAME-$IF netns ${pid} + nsenter -t $pid -n ip link set dev $SWNAME-$IF name $IF echo "Bring ${SRV}eth0 up" $NSS ip link set dev ${SRV}eth0 name eth0 diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index f8fcf974b65c..54d585f29e23 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -7,6 +7,23 @@ HWSKU=Force10-S6000 ln -sf /usr/share/sonic/device/$PLATFORM/$HWSKU /usr/share/sonic/hwsku +pushd /usr/share/sonic/hwsku + +# filter available front panel ports in lanemap.ini +[ -f lanemap.ini.orig ] || cp lanemap.ini lanemap.ini.orig +for p in $(ip link show | grep -oE "eth[0-9]+" | grep -v eth0); do + grep ^$p: lanemap.ini.orig +done > lanemap.ini + +# filter available sonic front panel ports in port_config.ini +[ -f port_config.ini.orig ] || cp port_config.ini port_config.ini.orig +grep ^# port_config.ini.orig > port_config.ini +for lanes in $(awk -F ':' '{print $2}' lanemap.ini); do + grep -E "\s$lanes\s" port_config.ini.orig +done >> port_config.ini + +popd + [ -d /etc/sonic ] || mkdir -p /etc/sonic SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') @@ -17,7 +34,7 @@ if [ -f /etc/sonic/config_db.json ]; then mv /tmp/config_db.json /etc/sonic/config_db.json else # generate and merge buffers configuration into config file - sonic-cfggen -t /usr/share/sonic/hwsku/buffers.json.j2 > /tmp/buffers.json + sonic-cfggen -k $HWSKU -p /usr/share/sonic/hwsku/port_config.ini -t /usr/share/sonic/hwsku/buffers.json.j2 > /tmp/buffers.json sonic-cfggen -j /etc/sonic/init_cfg.json -t /usr/share/sonic/hwsku/qos.json.j2 > /tmp/qos.json sonic-cfggen -p /usr/share/sonic/hwsku/port_config.ini -k $HWSKU --print-data > /tmp/ports.json sonic-cfggen -j /etc/sonic/init_cfg.json -j /tmp/buffers.json -j /tmp/qos.json -j /tmp/ports.json --print-data > /etc/sonic/config_db.json From aca5bec842a7ab1e530a54239e96debce74fb147 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Thu, 30 Apr 2020 13:09:24 -0700 Subject: [PATCH 0608/1427] [sonic-py-swsssdk/snmpagent] update submodule for sonic-py-swsssdk / snmpagent (#4421) * [sonic-py-swsssdk] update submodule for sonic-py-swsssdk * update snmpagent submodule * [sonic-py-swsssdk] update submodule for namespace changes --- src/sonic-py-swsssdk | 2 +- src/sonic-snmpagent | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index df617345d807..b9cee360c2a1 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit df617345d807bc01e3f5740fdfdc4b9799f1cf63 +Subproject commit b9cee360c2a1b64f46dbc035579bd7cbd9959878 diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 862e51ab85d4..7632ee89caa8 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 862e51ab85d48290082adfcbb801bfbbe3a95bf3 +Subproject commit 7632ee89caa8a485d68ce389f60f202fce197579 From 352a39742a733296141f6529dcf68fe9f0aa2823 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Fri, 1 May 2020 01:46:21 +0300 Subject: [PATCH 0609/1427] [mellanox]: MSN4700 support 8 lanes 400G with new SAI/SDK/FW (#4509) Update SAI/SDK/FW and MSN4700 device files to support 8 lanes 400G Update SAI to 1.16.3 Update SDK to 4.4.0914 Update FW to *.2007.1112 Update MSN4700 device files to support 8 lanes 400G --- .../ACS-MSN4700/port_config.ini | 66 +++++++++---------- .../ACS-MSN4700/sai.profile | 2 +- .../{sai_4700_100G.xml => sai_4700.xml} | 64 +++++++++--------- platform/mellanox/fw.mk | 6 +- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- .../sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 8 files changed, 73 insertions(+), 73 deletions(-) rename device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/{sai_4700_100G.xml => sai_4700.xml} (88%) diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini index 1e1906ff0ef5..2a14b4a79eb6 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini @@ -1,33 +1,33 @@ -# name lanes alias -Ethernet0 0,1,2,3 etp1 -Ethernet4 4,5,6,7 etp2 -Ethernet8 8,9,10,11 etp3 -Ethernet12 12,13,14,15 etp4 -Ethernet16 16,17,18,19 etp5 -Ethernet20 20,21,22,23 etp6 -Ethernet24 24,25,26,27 etp7 -Ethernet28 28,29,30,31 etp8 -Ethernet32 32,33,34,35 etp9 -Ethernet36 36,37,38,39 etp10 -Ethernet40 40,41,42,43 etp11 -Ethernet44 44,45,46,47 etp12 -Ethernet48 48,49,50,51 etp13 -Ethernet52 52,53,54,55 etp14 -Ethernet56 56,57,58,59 etp15 -Ethernet60 60,61,62,63 etp16 -Ethernet64 64,65,66,67 etp17 -Ethernet68 68,69,70,71 etp18 -Ethernet72 72,73,74,75 etp19 -Ethernet76 76,77,78,79 etp20 -Ethernet80 80,81,82,83 etp21 -Ethernet84 84,85,86,87 etp22 -Ethernet88 88,89,90,91 etp23 -Ethernet92 92,93,94,95 etp24 -Ethernet96 96,97,98,99 etp25 -Ethernet100 100,101,102,103 etp26 -Ethernet104 104,105,106,107 etp27 -Ethernet108 108,109,110,111 etp28 -Ethernet112 112,113,114,115 etp29 -Ethernet116 116,117,118,119 etp30 -Ethernet120 120,121,122,123 etp31 -Ethernet124 124,125,126,127 etp32 +# name lanes alias index +Ethernet0 0,1,2,3,4,5,6,7 etp1 0 +Ethernet8 8,9,10,11,12,13,14,15 etp2 1 +Ethernet16 16,17,18,19,20,21,22,23 etp3 2 +Ethernet24 24,25,26,27,28,29,30,31 etp4 3 +Ethernet32 32,33,34,35,36,37,38,39 etp5 4 +Ethernet40 40,41,42,43,44,45,46,47 etp6 5 +Ethernet48 48,49,50,51,52,53,54,55 etp7 6 +Ethernet56 56,57,58,59,60,61,62,63 etp8 7 +Ethernet64 64,65,66,67,68,69,70,71 etp9 8 +Ethernet72 72,73,74,75,76,77,78,79 etp10 9 +Ethernet80 80,81,82,83,84,85,86,87 etp11 10 +Ethernet88 88,89,90,91,92,93,94,95 etp12 11 +Ethernet96 96,97,98,99,100,101,102,103 etp13 12 +Ethernet104 104,105,106,107,108,109,110,111 etp14 13 +Ethernet112 112,113,114,115,116,117,118,119 etp15 14 +Ethernet120 120,121,122,123,124,125,126,127 etp16 15 +Ethernet128 128,129,130,131,132,133,134,135 etp17 16 +Ethernet136 136,137,138,139,140,141,142,143 etp18 17 +Ethernet144 144,145,146,147,148,149,150,151 etp19 18 +Ethernet152 152,153,154,155,156,157,158,159 etp20 19 +Ethernet160 160,161,162,163,164,165,166,167 etp21 20 +Ethernet168 168,169,170,171,172,173,174,175 etp22 21 +Ethernet176 176,177,178,179,180,181,182,183 etp23 22 +Ethernet184 184,185,186,187,188,189,190,191 etp24 23 +Ethernet192 192,193,194,195,196,197,198,199 etp25 24 +Ethernet200 200,201,202,203,204,205,206,207 etp26 25 +Ethernet208 208,209,210,211,212,213,214,215 etp27 26 +Ethernet216 216,217,218,219,220,221,222,223 etp28 27 +Ethernet224 224,225,226,227,228,229,230,231 etp29 28 +Ethernet232 232,233,234,235,236,237,238,239 etp30 29 +Ethernet240 240,241,242,243,244,245,246,247 etp31 30 +Ethernet248 248,249,250,251,252,253,254,255 etp32 31 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile index 31b3fd09ddd9..d145093cab96 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4700_100G.xml +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4700.xml diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml similarity index 88% rename from device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml rename to device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml index a76e23d5d119..177a79d13d6f 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml @@ -12,189 +12,189 @@ 1 - 4 + 8 17 3 1536 5 - 4 + 8 16 3 1536 9 - 4 + 8 19 3 1536 13 - 4 + 8 18 3 1536 17 - 4 + 8 21 3 1536 21 - 4 + 8 20 3 1536 25 - 4 + 8 23 3 1536 29 - 4 + 8 22 3 1536 33 - 4 + 8 29 3 1536 37 - 4 + 8 28 3 1536 41 - 4 + 8 31 3 1536 45 - 4 + 8 30 3 1536 49 - 4 + 8 25 3 1536 53 - 4 + 8 24 3 1536 57 - 4 + 8 27 3 1536 61 - 4 + 8 26 3 1536 65 - 4 + 8 14 3 1536 69 - 4 + 8 15 3 1536 73 - 4 + 8 12 3 1536 77 - 4 + 8 13 3 1536 81 - 4 + 8 10 3 1536 85 - 4 + 8 11 3 1536 89 - 4 + 8 8 3 1536 93 - 4 + 8 9 3 1536 97 - 4 + 8 2 3 1536 101 - 4 + 8 3 3 1536 105 - 4 + 8 0 @@ -205,35 +205,35 @@ 109 - 4 + 8 1 3 1536 113 - 4 + 8 6 3 1536 117 - 4 + 8 7 3 1536 121 - 4 + 8 4 3 1536 125 - 4 + 8 5 3 1536 diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index faa3b3f239b6..c8f4b225857b 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2007.0872 +MLNX_SPC_FW_VERSION = 13.2007.1112 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2007.0872 +MLNX_SPC2_FW_VERSION = 29.2007.1112 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2007.0872 +MLNX_SPC3_FW_VERSION = 30.2007.1112 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 275445bd80e0..65b0e47ae7fa 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.2-master +MLNX_SAI_VERSION = SAIRel1.16.3-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 5eb3e143e3da..57b07cbbeea8 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 5eb3e143e3da934b30fd9b66126a6ab626f1b15e +Subproject commit 57b07cbbeea8953c2df96cbd7f0d022691c9eaa5 diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 1d7da850581f..3160d980ff76 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 1d7da850581ff0dd79990ae1c5bcb174d4272267 +Subproject commit 3160d980ff766addb459e1ff0f81778516eb55a0 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 4b6212b147d9..c63c327cc40d 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.4.0880 +MLNX_SDK_VERSION = 4.4.0914 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 81f4c81f0ce98471992a55a2170a9ad0eda9dd1a Mon Sep 17 00:00:00 2001 From: Sabareesh-Kumar-Anandan <59681634+Sabareesh-Kumar-Anandan@users.noreply.github.com> Date: Fri, 1 May 2020 04:17:03 +0530 Subject: [PATCH 0610/1427] [build]: changing debian names based on Architecture (#4508) Replacing "amd64" with $PLATFORM_ARCH variable Fix for compiling marvell-armhf arch Signed-off-by: Sabareesh Kumar Anandan --- rules/iccpd.mk | 2 +- rules/iptables.mk | 10 +++++----- rules/sonic-mgmt-framework.mk | 4 ++-- src/iccpd/Makefile | 4 +++- src/iptables/Makefile | 8 ++++---- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/rules/iccpd.mk b/rules/iccpd.mk index 1923a9a2a62d..26d3adf1dd62 100644 --- a/rules/iccpd.mk +++ b/rules/iccpd.mk @@ -2,7 +2,7 @@ ICCPD_VERSION = 0.0.5 -ICCPD = iccpd_$(ICCPD_VERSION)_amd64.deb +ICCPD = iccpd_$(ICCPD_VERSION)_$(CONFIGURED_ARCH).deb $(ICCPD)_DEPENDS += $(LIBNL_GENL3_DEV) $(LIBNL_CLI_DEV) $(ICCPD)_RDEPENDS += $(LIBNL_GENL3) $(LIBNL_CLI) $(ICCPD)_SRC_PATH = $(SRC_PATH)/iccpd diff --git a/rules/iptables.mk b/rules/iptables.mk index fbd7ccd70c07..a166f5817a8b 100644 --- a/rules/iptables.mk +++ b/rules/iptables.mk @@ -4,20 +4,20 @@ IPTABLES_VERSION = 1.6.0+snapshot20161117 IPTABLES_VERSION_SUFFIX = 6 IPTABLES_VERSION_FULL = $(IPTABLES_VERSION)-$(IPTABLES_VERSION_SUFFIX) -IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(IPTABLES)_SRC_PATH = $(SRC_PATH)/iptables SONIC_MAKE_DEBS += $(IPTABLES) -IPTABLESIP4TC = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLESIP4TC = libip4tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP4TC))) -IPTABLESIP6TC = libip6tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLESIP6TC = libip6tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP6TC))) -IPTABLESIPTC = libiptc0_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLESIPTC = libiptc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIPTC))) -IPXTABLES12 = libxtables12_$(IPTABLES_VERSION_FULL)_amd64.deb +IPXTABLES12 = libxtables12_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPXTABLES12))) # Export these variables so they can be used in a sub-make diff --git a/rules/sonic-mgmt-framework.mk b/rules/sonic-mgmt-framework.mk index a57ce6b1b083..d3536edcfb65 100644 --- a/rules/sonic-mgmt-framework.mk +++ b/rules/sonic-mgmt-framework.mk @@ -2,13 +2,13 @@ ifeq ($(ENABLE_MGMT_FRAMEWORK), y) -SONIC_MGMT_FRAMEWORK = sonic-mgmt-framework_1.0-01_amd64.deb +SONIC_MGMT_FRAMEWORK = sonic-mgmt-framework_1.0-01_$(CONFIGURED_ARCH).deb $(SONIC_MGMT_FRAMEWORK)_SRC_PATH = $(SRC_PATH)/sonic-mgmt-framework $(SONIC_MGMT_FRAMEWORK)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) $(SONIC_MGMT_FRAMEWORK)_RDEPENDS = $(LIBYANG) SONIC_DPKG_DEBS += $(SONIC_MGMT_FRAMEWORK) -SONIC_MGMT_FRAMEWORK_DBG = sonic-mgmt-framework-dbg_1.0-01_amd64.deb +SONIC_MGMT_FRAMEWORK_DBG = sonic-mgmt-framework-dbg_1.0-01_$(CONFIGURED_ARCH).deb $(SONIC_MGMT_FRAMEWORK_DBG)_DEPENDS += $(SONIC_MGMT_FRAMEWORK) $(SONIC_MGMT_FRAMEWORK_DBG)_RDEPENDS += $(SONIC_MGMT_FRAMEWORK) $(eval $(call add_derived_package,$(SONIC_MGMT_FRAMEWORK),$(SONIC_MGMT_FRAMEWORK_DBG))) diff --git a/src/iccpd/Makefile b/src/iccpd/Makefile index 401ff394d145..b8f5c19ddf5f 100644 --- a/src/iccpd/Makefile +++ b/src/iccpd/Makefile @@ -2,7 +2,7 @@ SHELL = /bin/bash .SHELLFLAGS += -e -MAIN_TARGET = iccpd_$(ICCPD_VERSION)_amd64.deb +MAIN_TARGET = iccpd_$(ICCPD_VERSION)_$(CONFIGURED_ARCH).deb DEB_PATH = debian all: iccpd-build mclagdctl-build @@ -24,6 +24,8 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : chmod +x $(DEB_PATH)/usr/bin/mclagdctl md5sum $(DEB_PATH)/usr/bin/iccpd > $(DEB_PATH)/DEBIAN/md5sums md5sum $(DEB_PATH)/usr/bin/mclagdctl >> $(DEB_PATH)/DEBIAN/md5sums + sed -i "s/Package: .*/Package: iccpd-$(ICCPD_VERSION)-$(CONFIGURED_ARCH)/g" $(DEB_PATH)/DEBIAN/control + sed -i "s/Architecture: .*/Architecture: $(CONFIGURED_ARCH)/g" $(DEB_PATH)/DEBIAN/control dpkg-deb -b $(DEB_PATH) $(DEST)/$(MAIN_TARGET) clean: iccpd-clean mclagdctl-clean diff --git a/src/iptables/Makefile b/src/iptables/Makefile index 60154c19ddb1..3268ab5afea3 100644 --- a/src/iptables/Makefile +++ b/src/iptables/Makefile @@ -3,10 +3,10 @@ SHELL = /bin/bash .SHELLFLAGS += -e MAIN_TARGET = $(IPTABLES) -DERIVED_TARGETS = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ - libip6tc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ - libiptc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ - libxtables12_$(IPTABLES_VERSION_FULL)_amd64.deb +DERIVED_TARGETS = libip4tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ + libip6tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ + libiptc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ + libxtables12_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb IPTABLES_URL = http://deb.debian.org/debian/pool/main/i/iptables From 46161ca0e091e8298e529d04aa136d744507398e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 30 Apr 2020 15:48:42 -0700 Subject: [PATCH 0611/1427] [sonic-utilities][sonic-ztp] Update submodules (#4501) * src/sonic-utilities 7ce5b62...3471926 (4): > Make `config` command support abbreviation. (#893) > [fwutil]: Fix firmware update command. (#895) > [doc]: ZTP configuration and show commands (#866) > Allow show ztp to display non-sensitive information visible to > non-root user (#872) * src/sonic-ztp 374c9e8...c959371 (2): > Fix ztp profile unit test (#14) > Create a shadow ZTP data json file accessible to non-root user (#13) --- src/sonic-utilities | 2 +- src/sonic-ztp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 7ce5b62404b1..3471926f6e49 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 7ce5b62404b150782fd4a275ab3460566fa32a49 +Subproject commit 3471926f6e49f801676183f01f62fc8d0b64eeb4 diff --git a/src/sonic-ztp b/src/sonic-ztp index 374c9e804a9f..c959371ece3b 160000 --- a/src/sonic-ztp +++ b/src/sonic-ztp @@ -1 +1 @@ -Subproject commit 374c9e804a9f434cdb58fa7afe0c3f6201bfe56f +Subproject commit c959371ece3baebff2d3d748aba863de87b1d0a8 From cbc75fe4c85fd01aded0bacb283c8bbf62adf2f8 Mon Sep 17 00:00:00 2001 From: Sujin Kang Date: Thu, 30 Apr 2020 15:51:34 -0700 Subject: [PATCH 0612/1427] [pmon]: Fix the continous syseepromd autorestart issue on 201911 (#4478) - Remove syseepromd from the critical process of pmon docker - Fix supervisor autorestart configuration of syseepromd --- dockers/docker-platform-monitor/critical_processes | 1 - .../docker-pmon.supervisord.conf.j2 | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/dockers/docker-platform-monitor/critical_processes b/dockers/docker-platform-monitor/critical_processes index 788ba53f3ec4..9798dffc4c27 100644 --- a/dockers/docker-platform-monitor/critical_processes +++ b/dockers/docker-platform-monitor/critical_processes @@ -1,4 +1,3 @@ ledd xcvrd psud -syseepromd diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index 87b6808a744c..c79a13005f3f 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -86,10 +86,10 @@ startsecs=0 command=/usr/bin/syseepromd priority=8 autostart=false -autorestart=true +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog -startsecs=0 +startsecs=10 {% endif %} {% if not skip_thermalctld %} @@ -97,8 +97,8 @@ startsecs=0 command=/usr/bin/thermalctld priority=9 autostart=false -autorestart=true +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog -startsecs=0 +startsecs=10 {% endif %} From 451121678928a4c0f0ea8a0743ffe9a2beb7371b Mon Sep 17 00:00:00 2001 From: rkdevi27 <54701695+rkdevi27@users.noreply.github.com> Date: Fri, 1 May 2020 11:28:09 +0530 Subject: [PATCH 0613/1427] Ssd mitigation changes (#4214) * ssd_mitigation_changes * ssd_mitigation_changes * ssd_mitigation_changes * ssd_mitigation_changes --- files/image_config/fstrim/fstrim.service | 1 + 1 file changed, 1 insertion(+) diff --git a/files/image_config/fstrim/fstrim.service b/files/image_config/fstrim/fstrim.service index cf740d3af34d..0383b5fa010b 100644 --- a/files/image_config/fstrim/fstrim.service +++ b/files/image_config/fstrim/fstrim.service @@ -3,4 +3,5 @@ Description=Discard unused blocks [Service] Type=oneshot +ExecStartPre=/usr/bin/log_ssd_health ExecStart=/sbin/fstrim -av From 506e9546c9d38a5e0e17c12e7e769e29d17e8849 Mon Sep 17 00:00:00 2001 From: dereksun01 <52683998+dereksun01@users.noreply.github.com> Date: Fri, 1 May 2020 20:27:32 +0800 Subject: [PATCH 0614/1427] [device] Upgrade as4630_54pe for new platform (#4268) - Add port auto-negotiation attribute. - Add CPLD command to disable mode. --- .../Accton-AS4630-54PE/port_config.ini | 110 +++++++++--------- .../utils/accton_as4630_54pe_util.py | 14 ++- 2 files changed, 67 insertions(+), 57 deletions(-) diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini index aabb372bf649..f8965dfe41d0 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini +++ b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini @@ -1,55 +1,55 @@ -# name lanes alias index speed -Ethernet0 26 thousandE1 1 1000 -Ethernet1 25 thousandE2 2 1000 -Ethernet2 28 thousandE3 3 1000 -Ethernet3 27 thousandE4 4 1000 -Ethernet4 30 thousandE5 5 1000 -Ethernet5 29 thousandE6 6 1000 -Ethernet6 32 thousandE7 7 1000 -Ethernet7 31 thousandE8 8 1000 -Ethernet8 38 thousandE9 9 1000 -Ethernet9 37 thousandE10 10 1000 -Ethernet10 40 thousandE11 11 1000 -Ethernet11 39 thousandE12 12 1000 -Ethernet12 34 thousandE13 13 1000 -Ethernet13 33 thousandE14 14 1000 -Ethernet14 36 thousandE15 15 1000 -Ethernet15 35 thousandE16 16 1000 -Ethernet16 46 thousandE17 17 1000 -Ethernet17 45 thousandE18 18 1000 -Ethernet18 48 thousandE19 19 1000 -Ethernet19 47 thousandE20 20 1000 -Ethernet20 42 thousandE21 21 1000 -Ethernet21 41 thousandE22 22 1000 -Ethernet22 44 thousandE23 23 1000 -Ethernet23 43 thousandE24 24 1000 -Ethernet24 2 thousandE25 25 1000 -Ethernet25 1 thousandE26 26 1000 -Ethernet26 4 thousandE27 27 1000 -Ethernet27 3 thousandE28 28 1000 -Ethernet28 6 thousandE29 29 1000 -Ethernet29 5 thousandE30 30 1000 -Ethernet30 8 thousandE31 31 1000 -Ethernet31 7 thousandE32 32 1000 -Ethernet32 10 thousandE33 33 1000 -Ethernet33 9 thousandE34 34 1000 -Ethernet34 12 thousandE35 35 1000 -Ethernet35 11 thousandE36 36 1000 -Ethernet36 14 thousandE37 37 1000 -Ethernet37 13 thousandE38 38 1000 -Ethernet38 16 thousandE39 39 1000 -Ethernet39 15 thousandE40 40 1000 -Ethernet40 18 thousandE41 41 1000 -Ethernet41 17 thousandE42 42 1000 -Ethernet42 20 thousandE43 43 1000 -Ethernet43 19 thousandE44 44 1000 -Ethernet44 22 thousandE45 45 1000 -Ethernet45 21 thousandE46 46 1000 -Ethernet46 24 thousandE47 47 1000 -Ethernet47 23 thousandE48 48 1000 -Ethernet48 67 twentyfiveGigE49 49 25000 -Ethernet49 66 twentyfiveGigE50 50 25000 -Ethernet50 65 twentyfiveGigE51 51 25000 -Ethernet51 68 twentyfiveGigE52 52 25000 -Ethernet52 73,74,75,76 hundredGigE53 53 100000 -Ethernet56 69,70,71,72 hundredGigE54 54 100000 +# name lanes alias index speed autoneg +Ethernet0 26 thousandE1 1 1000 1 +Ethernet1 25 thousandE2 2 1000 1 +Ethernet2 28 thousandE3 3 1000 1 +Ethernet3 27 thousandE4 4 1000 1 +Ethernet4 30 thousandE5 5 1000 1 +Ethernet5 29 thousandE6 6 1000 1 +Ethernet6 32 thousandE7 7 1000 1 +Ethernet7 31 thousandE8 8 1000 1 +Ethernet8 38 thousandE9 9 1000 1 +Ethernet9 37 thousandE10 10 1000 1 +Ethernet10 40 thousandE11 11 1000 1 +Ethernet11 39 thousandE12 12 1000 1 +Ethernet12 34 thousandE13 13 1000 1 +Ethernet13 33 thousandE14 14 1000 1 +Ethernet14 36 thousandE15 15 1000 1 +Ethernet15 35 thousandE16 16 1000 1 +Ethernet16 46 thousandE17 17 1000 1 +Ethernet17 45 thousandE18 18 1000 1 +Ethernet18 48 thousandE19 19 1000 1 +Ethernet19 47 thousandE20 20 1000 1 +Ethernet20 42 thousandE21 21 1000 1 +Ethernet21 41 thousandE22 22 1000 1 +Ethernet22 44 thousandE23 23 1000 1 +Ethernet23 43 thousandE24 24 1000 1 +Ethernet24 2 thousandE25 25 1000 1 +Ethernet25 1 thousandE26 26 1000 1 +Ethernet26 4 thousandE27 27 1000 1 +Ethernet27 3 thousandE28 28 1000 1 +Ethernet28 6 thousandE29 29 1000 1 +Ethernet29 5 thousandE30 30 1000 1 +Ethernet30 8 thousandE31 31 1000 1 +Ethernet31 7 thousandE32 32 1000 1 +Ethernet32 10 thousandE33 33 1000 1 +Ethernet33 9 thousandE34 34 1000 1 +Ethernet34 12 thousandE35 35 1000 1 +Ethernet35 11 thousandE36 36 1000 1 +Ethernet36 14 thousandE37 37 1000 1 +Ethernet37 13 thousandE38 38 1000 1 +Ethernet38 16 thousandE39 39 1000 1 +Ethernet39 15 thousandE40 40 1000 1 +Ethernet40 18 thousandE41 41 1000 1 +Ethernet41 17 thousandE42 42 1000 1 +Ethernet42 20 thousandE43 43 1000 1 +Ethernet43 19 thousandE44 44 1000 1 +Ethernet44 22 thousandE45 45 1000 1 +Ethernet45 21 thousandE46 46 1000 1 +Ethernet46 24 thousandE47 47 1000 1 +Ethernet47 23 thousandE48 48 1000 1 +Ethernet48 67 twentyfiveGigE49 49 25000 0 +Ethernet49 66 twentyfiveGigE50 50 25000 0 +Ethernet50 65 twentyfiveGigE51 51 25000 0 +Ethernet51 68 twentyfiveGigE52 52 25000 0 +Ethernet52 73,74,75,76 hundredGigE53 53 100000 0 +Ethernet56 69,70,71,72 hundredGigE54 54 100000 0 diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py index 2f73726f846d..fbfa46377fa2 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py @@ -17,7 +17,6 @@ """ Usage: %(scriptName)s [options] command object - options: -h | --help : this help message -d | --debug : run with debug mode @@ -108,7 +107,12 @@ 'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', ] - +# Disable CPLD debug mode +cpld_set =[ +'i2cset -y -f 3 0x60 0x2a 0xff', +'i2cset -y -f 3 0x60 0x2b 0xff', +'i2cset -y -f 3 0x60 0x86 0x89' +] FORCE = 0 logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) @@ -353,6 +357,12 @@ def do_install(): return status else: print PROJECT_NAME.upper()+" devices detected...." + + for i in range(len(cpld_set)): + status, output = log_os_system(cpld_set[i], 1) + if status: + if FORCE == 0: + return status return def do_uninstall(): From 3f1c3dda991b318c8d3a93c26b7e88d8135401f5 Mon Sep 17 00:00:00 2001 From: dereksun01 <52683998+dereksun01@users.noreply.github.com> Date: Fri, 1 May 2020 20:36:04 +0800 Subject: [PATCH 0615/1427] [device/accton] Modify as8000 configuration (#4446) --- .../config_16Q_FEC544_EVTA_100G.bcm | 4 +++ .../config_16Q_FEC544_EVTB_100G.bcm | 26 +++---------------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm index 9f4066cc736d..a9dfbd4797e1 100755 --- a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm +++ b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm @@ -15,6 +15,10 @@ dpr_clock_frequency=1000 device_clock_frequency=1325 port_flex_enable=1 +l3_alpm_enable=2 +l3_mem_entries=983040 +ipv6_lpm_128b_enable=1 + #firmware load method, use fast load load_firmware=0x2 diff --git a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm index a72f22bbfd98..676dcdd89bd1 100755 --- a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm +++ b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm @@ -15,6 +15,10 @@ dpr_clock_frequency=1000 device_clock_frequency=1325 port_flex_enable=1 +l3_alpm_enable=2 +l3_mem_entries=983040 +ipv6_lpm_128b_enable=1 + #firmware load method, use fast load load_firmware=0x2 @@ -1463,25 +1467,3 @@ serdes_core_tx_polarity_flip_physical{254}=0x7E serdes_core_tx_polarity_flip_physical{255}=0x7E serdes_core_tx_polarity_flip_physical{256}=0x7E -dport_map_port_38=299 -portmap_38=257:10 - -dport_map_port_118=300 -portmap_118=258:10 - -portmap_19=259:10 - -portmap_39=260:10 - -portmap_59=261:10 - -portmap_79=262:10 - -portmap_99=263:10 - -portmap_119=264:10 - -portmap_139=265:10 - -portmap_159=266:10 - From 34cad97f30fe136d4d9685a9a6ac33250fcbd571 Mon Sep 17 00:00:00 2001 From: dereksun01 <52683998+dereksun01@users.noreply.github.com> Date: Fri, 1 May 2020 21:34:54 +0800 Subject: [PATCH 0616/1427] [device] Modify configuration and add led_proc_init.soc (#4418) - Modify configuration file path in sai.profile. - Modify configuration file for as7726_32x. - Add led_proc_init.soc and custom_led.bin --- .../Accton-AS7726-32X/sai.profile | 2 +- .../td3-as7726-32x100G.config.bcm | 16 +++++++++------- .../x86_64-accton_as7726_32x-r0/custom_led.bin | Bin 0 -> 1212 bytes .../led_proc_init.soc | 4 ++++ 4 files changed, 14 insertions(+), 8 deletions(-) create mode 100755 device/accton/x86_64-accton_as7726_32x-r0/custom_led.bin create mode 100644 device/accton/x86_64-accton_as7726_32x-r0/led_proc_init.soc diff --git a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile index 46f5cb3bf850..461cdd76c4d5 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile +++ b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as7726-32x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7726-32x100G.config.bcm diff --git a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm index 16cbb8d341e8..49838f4b0bec 100755 --- a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm +++ b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm @@ -11,26 +11,28 @@ mem_cache_enable=0 l2_mem_entries=32768 l3_mem_entries=16384 -fpem_mem_entries=131072 +fpem_mem_entries=16384 l2xmsg_mode=1 # Platform specfic bcm_num_cos=8 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 +ifp_inports_support_enable=1 ipv6_lpm_128b_enable=0x1 l3_max_ecmp_mode=1 -#l3_alpm_enable=2 +l3_alpm_enable=2 lpm_scaling_enable=0 max_vp_lags=0 miim_intr_enable=0 module_64ports=1 +port_flex_enable=1 schan_intr_enable=0 stable_size=0x5500000 tdma_timeout_usec=3000000 skip_L2_USER_ENTRY=0 bcm_tunnel_term_compatible_mode=1 - +l3_alpm_ipv6_128b_bkt_rsvd=1 phy_an_c73=1 dport_map_port_1=1 @@ -100,10 +102,10 @@ portmap_115=113:100 portmap_119=117:100 portmap_123=121:100 portmap_127=125:100 -portmap_66=129:10:m -portmap_130=128:10:m -portmap_65=130:10 -portmap_131=131:10 +#portmap_66=129:10:m +#portmap_130=128:10:m +#portmap_65=130:10 +#portmap_131=131:10 phy_chain_rx_lane_map_physical{1.0}=0x1320 phy_chain_rx_lane_map_physical{5.0}=0x0123 diff --git a/device/accton/x86_64-accton_as7726_32x-r0/custom_led.bin b/device/accton/x86_64-accton_as7726_32x-r0/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..73dcf0e085dca7dd6a5ed729da4bf9b1ef737e34 GIT binary patch literal 1212 zcmZwE&2JM&7{~FMwegxjfRF+S8DO0SN-zyjQ<{VVjyH@8fu^y6lDI(Z(AF(&ao^nl=ElmiEZWQj@$F3Z<(sG#cMqtVPW^Za&Zt5+wc z{Hjq2TZHoMzlo9T&4fQvh&^+~`sD+E1x3M99jZq~l&B6q^>2@M{zIjSN;L9v&6%w| zc4g@Ph_LPS;`U5>QTwIz{d6=G$_#|knM;|O%*^P_3Ex!p#qE`qJgM&Wo zfkqtfVlVcgANz3t?_mJ%V-N`>aS(@a7$4vWhA@m2KEzQR!*PrtjSNO{0w3XHe1a@K z#b-E)&+!Gm#3|(P6~4wd_!i&cd;EYg{D{*ygR?k?^SFRKBnCcJ@8Y{nLB z#hZv=8{WcpybXS_;1`P??7%zNiCx%@C?>K)EwVc}=B&Qhn~P8D`h3AyFdQh)4;y7+ znPHzREm<)v??Ep9q8T!Ko@6nYj<5Q-RzZUc# z;^5Gz+FA}N@5wDsZm`^3|4d6s^kj>}({@TUsn)2l#`R>Z!Chh(b-@gj4OO8rWu&9rr3SV4 zb=!v4C4Jjj}A2O!;@-R!)8Y8PfcY=nS~^`Ggmhe#fXdIwh4;>tCAf z-#ynqMgJDJ=YRT}|MoZNe^0zf*f*CDoJ&Y}!XS}*HC2pGb8a>6jccEw9FycW##&u+ z&!Rrs_b7W(Z6Uvd*J+#0U)lfgKQB8OYkVcY#MjqPG`w`fT8E|HH2FcYeQr|UBdd1X c+ITwKP%4Sv6ULOf{);Z^KXvtn=XtxI0}9Fx{r~^~ literal 0 HcmV?d00001 diff --git a/device/accton/x86_64-accton_as7726_32x-r0/led_proc_init.soc b/device/accton/x86_64-accton_as7726_32x-r0/led_proc_init.soc new file mode 100644 index 000000000000..1b1e6403d902 --- /dev/null +++ b/device/accton/x86_64-accton_as7726_32x-r0/led_proc_init.soc @@ -0,0 +1,4 @@ + +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on +led start From c55603f494736b1464823e32520438af11e89dcc Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 1 May 2020 11:20:33 -0700 Subject: [PATCH 0617/1427] [build]: add docker-ptf-* as stretch docker targets (#4516) Signed-off-by: Guohan Lu --- platform/barefoot/docker-ptf-bfn.mk | 1 + platform/broadcom/docker-ptf-brcm.mk | 1 + platform/cavium/docker-ptf-cavm.mk | 1 + platform/centec/docker-ptf-centec.mk | 1 + platform/innovium/docker-ptf-invm.mk | 1 + platform/marvell-arm64/docker-ptf-mrvl.mk | 1 + platform/marvell-armhf/docker-ptf-mrvl.mk | 1 + platform/mellanox/docker-ptf-mlnx.mk | 1 + platform/nephos/docker-ptf-nephos.mk | 1 + 9 files changed, 9 insertions(+) diff --git a/platform/barefoot/docker-ptf-bfn.mk b/platform/barefoot/docker-ptf-bfn.mk index 573e9cd9cffa..752e7345752a 100644 --- a/platform/barefoot/docker-ptf-bfn.mk +++ b/platform/barefoot/docker-ptf-bfn.mk @@ -3,3 +3,4 @@ DOCKER_PTF_BFN = docker-ptf-bfn.gz $(DOCKER_PTF_BFN)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_BFN)_LOAD_DOCKERS += $(DOCKER_PTF) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_BFN) diff --git a/platform/broadcom/docker-ptf-brcm.mk b/platform/broadcom/docker-ptf-brcm.mk index 510f21e8a436..35780aea76ca 100644 --- a/platform/broadcom/docker-ptf-brcm.mk +++ b/platform/broadcom/docker-ptf-brcm.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_BRCM)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_BRCM)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_BRCM)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_BRCM) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_BRCM) diff --git a/platform/cavium/docker-ptf-cavm.mk b/platform/cavium/docker-ptf-cavm.mk index 4665345586a8..ea96fd050bfe 100644 --- a/platform/cavium/docker-ptf-cavm.mk +++ b/platform/cavium/docker-ptf-cavm.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_CAVM)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_CAVM)_DEPENDS += $(PYTHON_SAITHRIFT_CAVM) $(DOCKER_PTF_CAVM)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_CAVM) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_CAVM) diff --git a/platform/centec/docker-ptf-centec.mk b/platform/centec/docker-ptf-centec.mk index 3d4fe50e5f1f..47284f71756c 100644 --- a/platform/centec/docker-ptf-centec.mk +++ b/platform/centec/docker-ptf-centec.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_CENTEC)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_CENTEC)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_CENTEC)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_CENTEC) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_CENTEC) diff --git a/platform/innovium/docker-ptf-invm.mk b/platform/innovium/docker-ptf-invm.mk index 6c81734676fd..53ba41e9d386 100755 --- a/platform/innovium/docker-ptf-invm.mk +++ b/platform/innovium/docker-ptf-invm.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_INVM)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_INVM)_DEPENDS += $(PYTHON_SAITHRIFT_INVM) $(DOCKER_PTF_INVM)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_INVM) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_INVM) diff --git a/platform/marvell-arm64/docker-ptf-mrvl.mk b/platform/marvell-arm64/docker-ptf-mrvl.mk index 69dff4a90dd4..72c860aec868 100644 --- a/platform/marvell-arm64/docker-ptf-mrvl.mk +++ b/platform/marvell-arm64/docker-ptf-mrvl.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_MRVL)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_MRVL)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_MRVL)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_MRVL) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_MRVL) diff --git a/platform/marvell-armhf/docker-ptf-mrvl.mk b/platform/marvell-armhf/docker-ptf-mrvl.mk index 69dff4a90dd4..72c860aec868 100644 --- a/platform/marvell-armhf/docker-ptf-mrvl.mk +++ b/platform/marvell-armhf/docker-ptf-mrvl.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_MRVL)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_MRVL)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_MRVL)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_MRVL) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_MRVL) diff --git a/platform/mellanox/docker-ptf-mlnx.mk b/platform/mellanox/docker-ptf-mlnx.mk index f6d17e72fcfe..eaaa54897d80 100644 --- a/platform/mellanox/docker-ptf-mlnx.mk +++ b/platform/mellanox/docker-ptf-mlnx.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_MLNX)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_MLNX)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_MLNX)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_MLNX) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_MLNX) diff --git a/platform/nephos/docker-ptf-nephos.mk b/platform/nephos/docker-ptf-nephos.mk index 7fbbd271cf65..15855bc89a1f 100644 --- a/platform/nephos/docker-ptf-nephos.mk +++ b/platform/nephos/docker-ptf-nephos.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_NEPHOS)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_NEPHOS)_DEPENDS += $(PYTHON_SAITHRIFT_NEPHOS) $(DOCKER_PTF_NEPHOS)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_NEPHOS) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_NEPHOS) From 30bbbbf24f0ce2a063259a27511a8babf45f546e Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Sat, 2 May 2020 20:37:14 +0300 Subject: [PATCH 0618/1427] hw-mgmt_V.7.0000.3034 integration (#4519) Signed-off-by: Shlomi Bitton --- platform/mellanox/hw-management.mk | 2 +- platform/mellanox/hw-management/hw-mgmt | 2 +- src/sonic-linux-kernel | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index cc27126cf80e..3fa1667fec18 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0000.3020 +MLNX_HW_MANAGEMENT_VERSION = 7.0000.3034 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 5e0a3410bf21..39f66b8e1997 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 5e0a3410bf2167af0f63ba85cd4158a0be9f1443 +Subproject commit 39f66b8e1997868bbec297d7ae38f4e4ccc9009d diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 187bb4aa046c..57f0a4e05396 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 187bb4aa046c26f2fe508e71dc74c230d316838b +Subproject commit 57f0a4e053960db216232b6f3b15c0f5b41b88c2 From e8748ebf1bc1e6e6a25b6d6ca5200c2cea5f83ef Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Mon, 4 May 2020 09:34:35 -0700 Subject: [PATCH 0619/1427] [submodule]: advance sonic-utilities submodule (#4523) c2facd8 [show] Fix abbreviations for 'show ip bgp ...' commands (#901) cb68e7d Add support for multi-ASIC devices (#877) 44ed6e9 Improved route_check tool and adopt to 20191130 image. (#898) 6fba8db [psushow] Add a column to display LED color to show platform psustatus output (#886) e747456 ssd_mitigation_changes (#829) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 3471926f6e49..c2facd8488f0 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 3471926f6e49f801676183f01f62fc8d0b64eeb4 +Subproject commit c2facd8488f023f98cab2c06d849c21cefc6fcf5 From 86e13907b423928e06ae72500cac090712304b01 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Mon, 4 May 2020 15:00:07 -0700 Subject: [PATCH 0620/1427] Update golang version for 1.11.5 to 1.14.2 (#4520) --- sonic-slave-buster/Dockerfile.j2 | 2 +- sonic-slave-jessie/Dockerfile.j2 | 2 +- sonic-slave-stretch/Dockerfile.j2 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 4cb0fe102aac..cf6d61f4b12f 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -316,7 +316,7 @@ RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confold" RUN apt-get -y build-dep linux # For gobgp and telemetry build -RUN export VERSION=1.11.5 \ +RUN export VERSION=1.14.2 \ {%- if CONFIGURED_ARCH == "armhf" %} && wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \ && tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \ diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index 0e59310fc30c..b2626f33ce98 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -278,7 +278,7 @@ RUN apt-get -y build-dep linux {%- endif %} # For gobgp and telemetry build -RUN export VERSION=1.11.5 \ +RUN export VERSION=1.14.2 \ {%- if CONFIGURED_ARCH == "armhf" %} && wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \ && tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \ diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index af5f441c8842..a02a39ed93c5 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -315,7 +315,7 @@ RUN apt-get -t stretch-backports install -y debhelper RUN apt-get -y build-dep linux # For gobgp and telemetry build -RUN export VERSION=1.11.5 \ +RUN export VERSION=1.14.2 \ {%- if CONFIGURED_ARCH == "armhf" %} && wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \ && tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \ From 8ac1c60b2a3d1c902b12dc174f3afb13a710cda9 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Mon, 4 May 2020 16:15:15 -0700 Subject: [PATCH 0621/1427] [config engine] Parser changes to support parsing of multi-asic device minigraph (#4222) - Changes to minigraph.py to parse minigraph.xml of a multi asic platform - Changes to portconfig.py to parse additional column "asic_port_name" in port_config.ini - Add a new option -n to sonic-cfggen for multi asic platforms - Add unit tests for config generation for multi asic platforms Signed-off-by: SuvarnaMeenakshi Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-config-engine/minigraph.py | 223 ++- src/sonic-config-engine/portconfig.py | 22 +- src/sonic-config-engine/sonic-cfggen | 35 +- src/sonic-config-engine/sonic_device_util.py | 49 +- .../tests/multi_npu_data/sample-minigraph.xml | 1214 +++++++++++++++++ .../multi_npu_data/sample_port_config-0.ini | 9 + .../multi_npu_data/sample_port_config-1.ini | 9 + .../multi_npu_data/sample_port_config-2.ini | 9 + .../multi_npu_data/sample_port_config-3.ini | 9 + .../tests/test_multinpu_cfggen.py | 221 +++ 10 files changed, 1753 insertions(+), 47 deletions(-) create mode 100644 src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml create mode 100644 src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini create mode 100644 src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini create mode 100644 src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini create mode 100644 src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini create mode 100644 src/sonic-config-engine/tests/test_multinpu_cfggen.py diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 8f91fbe5c318..8ff4944c5d13 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -14,6 +14,7 @@ from lxml.etree import QName from portconfig import get_port_config +from sonic_device_util import get_npu_id_from_name """minigraph.py version_added: "1.9" @@ -118,14 +119,13 @@ def parse_png(png, hname): startport = link.find(str(QName(ns, "StartPort"))).text bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) bandwidth = bandwidth_node.text if bandwidth_node is not None else None - if enddevice.lower() == hname.lower(): if port_alias_map.has_key(endport): endport = port_alias_map[endport] neighbors[endport] = {'name': startdevice, 'port': startport} if bandwidth: port_speeds[endport] = bandwidth - else: + elif startdevice.lower() == hname.lower(): if port_alias_map.has_key(startport): startport = port_alias_map[startport] neighbors[startport] = {'name': enddevice, 'port': endport} @@ -159,9 +159,103 @@ def parse_png(png, hname): return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports) +def parse_asic_external_link(link, asic_name, hostname): + neighbors = {} + port_speeds = {} + enddevice = link.find(str(QName(ns, "EndDevice"))).text + endport = link.find(str(QName(ns, "EndPort"))).text + startdevice = link.find(str(QName(ns, "StartDevice"))).text + startport = link.find(str(QName(ns, "StartPort"))).text + bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) + bandwidth = bandwidth_node.text if bandwidth_node is not None else None + # if chassis internal is false, the interface name will be + # interface alias which should be converted to asic port name + if (enddevice.lower() == hostname.lower()): + if ((port_alias_asic_map.has_key(endport)) and + (asic_name.lower() in port_alias_asic_map[endport].lower())): + endport = port_alias_asic_map[endport] + neighbors[port_alias_map[endport]] = {'name': startdevice, 'port': startport} + if bandwidth: + port_speeds[port_alias_map[endport]] = bandwidth + elif (startdevice.lower() == hostname.lower()): + if ((port_alias_asic_map.has_key(startport)) and + (asic_name.lower() in port_alias_asic_map[startport].lower())): + startport = port_alias_asic_map[startport] + neighbors[port_alias_map[startport]] = {'name': enddevice, 'port': endport} + if bandwidth: + port_speeds[port_alias_map[startport]] = bandwidth + + return neighbors, port_speeds + +def parse_asic_internal_link(link, asic_name, hostname): + neighbors = {} + port_speeds = {} + enddevice = link.find(str(QName(ns, "EndDevice"))).text + endport = link.find(str(QName(ns, "EndPort"))).text + startdevice = link.find(str(QName(ns, "StartDevice"))).text + startport = link.find(str(QName(ns, "StartPort"))).text + bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) + bandwidth = bandwidth_node.text if bandwidth_node is not None else None + if ((enddevice.lower() == asic_name.lower()) and + (startdevice.lower() != hostname.lower())): + if port_alias_map.has_key(endport): + endport = port_alias_map[endport] + neighbors[endport] = {'name': startdevice, 'port': startport} + if bandwidth: + port_speeds[endport] = bandwidth + elif ((startdevice.lower() == asic_name.lower()) and + (enddevice.lower() != hostname.lower())): + if port_alias_map.has_key(startport): + startport = port_alias_map[startport] + neighbors[startport] = {'name': enddevice, 'port': endport} + if bandwidth: + port_speeds[startport] = bandwidth + + return neighbors, port_speeds + +def parse_asic_png(png, asic_name, hostname): + neighbors = {} + devices = {} + port_speeds = {} + for child in png: + if child.tag == str(QName(ns, "DeviceInterfaceLinks")): + for link in child.findall(str(QName(ns, "DeviceLinkBase"))): + # Chassis internal node is used in multi-asic device or chassis minigraph + # where the minigraph will contain the internal asic connectivity and + # external neighbor information. The ChassisInternal node will be used to + # determine if the link is internal to the device or chassis. + chassis_internal_node = link.find(str(QName(ns, "ChassisInternal"))) + chassis_internal = chassis_internal_node.text if chassis_internal_node is not None else "false" + + # If the link is an external link include the external neighbor + # information in ASIC ports table + if chassis_internal.lower() == "false": + ext_neighbors, ext_port_speeds = parse_asic_external_link(link, asic_name, hostname) + neighbors.update(ext_neighbors) + port_speeds.update(ext_port_speeds) + else: + int_neighbors, int_port_speeds = parse_asic_internal_link(link, asic_name, hostname) + neighbors.update(int_neighbors) + port_speeds.update(int_port_speeds) + + if child.tag == str(QName(ns, "Devices")): + for device in child.findall(str(QName(ns, "Device"))): + (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) + device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } + if deployment_id: + device_data['deployment_id'] = deployment_id + devices[name] = device_data + return (neighbors, devices, port_speeds) def parse_dpg(dpg, hname): for child in dpg: + """In Multi-NPU platforms the acl intfs are defined only for the host not for individual asic. + There is just one aclintf node in the minigraph + Get the aclintfs node first. + """ + if child.find(str(QName(ns, "AclInterfaces"))) is not None: + aclintfs = child.find(str(QName(ns, "AclInterfaces"))) + hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue @@ -254,7 +348,6 @@ def parse_dpg(dpg, hname): vlan_attributes['alias'] = vintfname vlans[sonic_vlan_name] = vlan_attributes - aclintfs = child.find(str(QName(ns, "AclInterfaces"))) acls = {} for aclintf in aclintfs.findall(str(QName(ns, "AclInterface"))): if aclintf.find(str(QName(ns, "InAcl"))) is not None: @@ -369,7 +462,7 @@ def parse_cpg(cpg, hname): 'keepalive': keepalive, 'nhopself': nhopself } - else: + elif start_router.lower() == hname.lower(): bgp_sessions[end_peer.lower()] = { 'name': end_router, 'local_addr': start_peer.lower(), @@ -446,6 +539,19 @@ def parse_meta(meta, hname): region = value return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region +def parse_asic_meta(meta, hname): + sub_role = None + device_metas = meta.find(str(QName(ns, "Devices"))) + for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): + if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower(): + properties = device.find(str(QName(ns1, "Properties"))) + for device_property in properties.findall(str(QName(ns1, "DeviceProperty"))): + name = device_property.find(str(QName(ns1, "Name"))).text + value = device_property.find(str(QName(ns1, "Value"))).text + if name == "SubRole": + sub_role = value + return sub_role + def parse_deviceinfo(meta, hwsku): port_speeds = {} port_descriptions = {} @@ -480,8 +586,7 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m lo_network = ipaddress.IPNetwork(lo[1]) if lo_network.version == 4: lo_addr = str(lo_network.ip) - break - + break results['VXLAN_TUNNEL'] = {chassis_vxlan_tunnel: { 'src_ip': lo_addr }} @@ -520,7 +625,7 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m for pc_member in pc_members: if pc_member[0] == pc_intf: intf_name = pc_member[1] - break + break if intf_name == None: print >> sys.stderr, 'Warning: cannot find any interfaces that belong to %s' % (pc_intf) @@ -567,8 +672,16 @@ def filter_acl_mirror_table_bindings(acls, neighbors, port_channels): # Main functions # ############################################################################### - -def parse_xml(filename, platform=None, port_config_file=None): +def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): + """ Parse minigraph xml file. + + Keyword arguments: + filename -- minigraph file name + platform -- device platform + port_config_file -- port config file name + asic_name -- asic name; to parse multi-asic device minigraph to + generate asic specific configuration. + """ root = ET.parse(filename).getroot() mini_graph_path = filename @@ -588,7 +701,7 @@ def parse_xml(filename, platform=None, port_config_file=None): lo_intfs = None neighbors = None devices = None - hostname = None + sub_role = None docker_routing_config_mode = "separated" port_speeds_default = {} port_speed_png = {} @@ -603,6 +716,13 @@ def parse_xml(filename, platform=None, port_config_file=None): bgp_peers_with_range = None deployment_id = None region = None + hostname = None + + #hostname is the asic_name, get the asic_id from the asic_name + if asic_name is not None: + asic_id = get_npu_id_from_name(asic_name) + else: + asic_id = None hwsku_qn = QName(ns, "HwSku") hostname_qn = QName(ns, "Hostname") @@ -615,34 +735,59 @@ def parse_xml(filename, platform=None, port_config_file=None): if child.tag == str(docker_routing_config_mode_qn): docker_routing_config_mode = child.text - (ports, alias_map) = get_port_config(hwsku, platform, port_config_file) + (ports, alias_map, alias_asic_map) = get_port_config(hwsku=hwsku, platform=platform, port_config_file=port_config_file, asic=asic_id) port_alias_map.update(alias_map) + port_alias_asic_map.update(alias_asic_map) + for child in root: - if child.tag == str(QName(ns, "DpgDec")): - (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) - elif child.tag == str(QName(ns, "CpgDec")): - (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) - elif child.tag == str(QName(ns, "PngDec")): - (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports) = parse_png(child, hostname) - elif child.tag == str(QName(ns, "UngDec")): - (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) - elif child.tag == str(QName(ns, "MetadataDeclaration")): - (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname) - elif child.tag == str(QName(ns, "DeviceInfos")): - (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) - - current_device = [devices[key] for key in devices if key.lower() == hostname.lower()][0] + if asic_name is None: + if child.tag == str(QName(ns, "DpgDec")): + (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) + elif child.tag == str(QName(ns, "CpgDec")): + (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) + elif child.tag == str(QName(ns, "PngDec")): + (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports) = parse_png(child, hostname) + elif child.tag == str(QName(ns, "UngDec")): + (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, device_hostname) + elif child.tag == str(QName(ns, "MetadataDeclaration")): + (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname) + elif child.tag == str(QName(ns, "DeviceInfos")): + (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) + else: + if child.tag == str(QName(ns, "DpgDec")): + (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) + elif child.tag == str(QName(ns, "CpgDec")): + (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) + elif child.tag == str(QName(ns, "PngDec")): + (neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname) + elif child.tag == str(QName(ns, "MetadataDeclaration")): + (sub_role) = parse_asic_meta(child, asic_name) + elif child.tag == str(QName(ns, "DeviceInfos")): + (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) + + if asic_name is None: + current_device = [devices[key] for key in devices if key.lower() == hostname.lower()][0] + name = hostname + else: + current_device = [devices[key] for key in devices if key.lower() == asic_name.lower()][0] + name = asic_name + results = {} results['DEVICE_METADATA'] = {'localhost': { 'bgp_asn': bgp_asn, 'deployment_id': deployment_id, 'region': region, 'docker_routing_config_mode': docker_routing_config_mode, - 'hostname': hostname, + 'hostname': name, 'hwsku': hwsku, 'type': current_device['type'] } } + # for this hostname, if sub_role is defined, add sub_role in + # device_metadata + if sub_role is not None: + current_device['sub_role'] = sub_role + results['DEVICE_METADATA']['localhost']['sub_role'] = sub_role results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range @@ -703,9 +848,11 @@ def parse_xml(filename, platform=None, port_config_file=None): for port_name in port_speed_png: # not consider port not in port_config.ini - if port_name not in ports: - print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name - continue + #If no port_config_file is found ports is empty so ignore this error + if port_config_file is not None: + if port_name not in ports: + print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name + continue ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name] @@ -809,11 +956,14 @@ def parse_xml(filename, platform=None, port_config_file=None): for nghbr in neighbors.keys(): # remove port not in port_config.ini if nghbr not in ports: - print >> sys.stderr, "Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr + if port_config_file is not None: + print >> sys.stderr, "Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr del neighbors[nghbr] - results['DEVICE_NEIGHBOR'] = neighbors - results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key.lower() != hostname.lower() } + if asic_name is None: + results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key.lower() != hostname.lower() } + else: + results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key in {device['name'] for device in neighbors.values()} } results['SYSLOG_SERVER'] = dict((item, {}) for item in syslog_servers) results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers) results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers) @@ -890,8 +1040,17 @@ def parse_device_desc_xml(filename): return results +def parse_asic_sub_role(filename, asic_name): + if not os.path.isfile(filename): + return None + root = ET.parse(filename).getroot() + for child in root: + if child.tag == str(QName(ns, "MetadataDeclaration")): + sub_role = parse_asic_meta(child, asic_name) + return sub_role port_alias_map = {} +port_alias_asic_map = {} def print_parse_xml(filename): diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py index db2baa308174..87e13687ed55 100644 --- a/src/sonic-config-engine/portconfig.py +++ b/src/sonic-config-engine/portconfig.py @@ -3,11 +3,13 @@ import sys -def get_port_config_file_name(hwsku=None, platform=None): +def get_port_config_file_name(hwsku=None, platform=None, asic=None): port_config_candidates = [] port_config_candidates.append('/usr/share/sonic/hwsku/port_config.ini') if hwsku: if platform: + if asic: + port_config_candidates.append(os.path.join('/usr/share/sonic/device', platform, hwsku, asic,'port_config.ini')) port_config_candidates.append(os.path.join('/usr/share/sonic/device', platform, hwsku, 'port_config.ini')) port_config_candidates.append(os.path.join('/usr/share/sonic/platform', hwsku, 'port_config.ini')) port_config_candidates.append(os.path.join('/usr/share/sonic', hwsku, 'port_config.ini')) @@ -17,17 +19,19 @@ def get_port_config_file_name(hwsku=None, platform=None): return None -def get_port_config(hwsku=None, platform=None, port_config_file=None): + +def get_port_config(hwsku=None, platform=None, port_config_file=None, asic=None): if not port_config_file: - port_config_file = get_port_config_file_name(hwsku, platform) + port_config_file = get_port_config_file_name(hwsku, platform, asic) if not port_config_file: - return ({}, {}) + return ({}, {}, {}) return parse_port_config_file(port_config_file) def parse_port_config_file(port_config_file): ports = {} port_alias_map = {} + port_alias_asic_map = {} # Default column definition titles = ['name', 'lanes', 'alias', 'index'] with open(port_config_file) as data: @@ -49,6 +53,14 @@ def parse_port_config_file(port_config_file): data.setdefault('alias', name) ports[name] = data port_alias_map[data['alias']] = name - return (ports, port_alias_map) + # asic_port_name to sonic_name mapping also included in + # port_alias_map + if (('asic_port_name' in data) and + (data['asic_port_name'] != name)): + port_alias_map[data['asic_port_name']] = name + # alias to asic_port_name mapping + if 'asic_port_name' in data: + port_alias_asic_map[data['alias']] = data['asic_port_name'].strip() + return (ports, port_alias_map, port_alias_asic_map) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 1a94a47c0f9c..d8936a83f72c 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -37,10 +37,12 @@ from functools import partial from minigraph import minigraph_encoder from minigraph import parse_xml from minigraph import parse_device_desc_xml +from minigraph import parse_asic_sub_role from portconfig import get_port_config from sonic_device_util import get_machine_info from sonic_device_util import get_platform_info from sonic_device_util import get_system_mac +from sonic_device_util import get_npu_id_from_name from config_samples import generate_sample_config from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector @@ -195,6 +197,7 @@ def main(): group.add_argument("-m", "--minigraph", help="minigraph xml file", nargs='?', const='/etc/sonic/minigraph.xml') group.add_argument("-M", "--device-description", help="device description xml file") group.add_argument("-k", "--hwsku", help="HwSKU") + parser.add_argument("-n", "--namespace", help="namespace name, used with -m or -k", nargs='?', const=None) parser.add_argument("-p", "--port-config", help="port config file, used with -m or -k", nargs='?', const=None) parser.add_argument("-y", "--yaml", help="yaml file that contains additional variables", action='append', default=[]) parser.add_argument("-j", "--json", help="json file that contains additional variables", action='append', default=[]) @@ -222,13 +225,18 @@ def main(): data = {} hwsku = args.hwsku + asic_name = args.namespace + asic_id = None + if asic_name is not None: + asic_id = get_npu_id_from_name(asic_name) + if hwsku is not None: hardware_data = {'DEVICE_METADATA': {'localhost': { 'hwsku': hwsku }}} deep_update(data, hardware_data) - (ports, _) = get_port_config(hwsku, platform, args.port_config) + (ports, _, _) = get_port_config(hwsku, platform, args.port_config, asic_id) if not ports: print('Failed to get port config', file=sys.stderr) sys.exit(1) @@ -242,11 +250,11 @@ def main(): minigraph = args.minigraph if platform: if args.port_config != None: - deep_update(data, parse_xml(minigraph, platform, args.port_config)) + deep_update(data, parse_xml(minigraph, platform, args.port_config, asic_name=asic_name)) else: - deep_update(data, parse_xml(minigraph, platform)) + deep_update(data, parse_xml(minigraph, platform, asic_name=asic_name)) else: - deep_update(data, parse_xml(minigraph, port_config_file=args.port_config)) + deep_update(data, parse_xml(minigraph, port_config_file=args.port_config, asic_name=asic_name)) if args.device_description != None: deep_update(data, parse_device_desc_xml(args.device_description)) @@ -267,11 +275,28 @@ def main(): configdb.connect() deep_update(data, FormatConverter.db_to_output(configdb.get_config())) + + # the minigraph file must be provided to get the mac address for backend asics if args.platform_info: + asic_role = None + if asic_name is not None: + if args.minigraph is not None: + asic_role = parse_asic_sub_role(args.minigraph, asic_name) + + if asic_role is not None and asic_role.lower() == "backend": + mac = get_system_mac(namespace=asic_name) + else: + mac = get_system_mac() + else: + mac = get_system_mac() + hardware_data = {'DEVICE_METADATA': {'localhost': { 'platform': platform, - 'mac': get_system_mac() + 'mac': mac, }}} + # The ID needs to be passed to the SAI to identify the asic. + if asic_name is not None: + hardware_data['DEVICE_METADATA']['localhost'].update(asic_id=asic_id) deep_update(data, hardware_data) if args.template is not None: diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index ba57d22f58e7..03bd7027a46e 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -3,7 +3,8 @@ import yaml import subprocess import re - +from natsort import natsorted +import glob DOCUMENTATION = ''' --- module: sonic_device_util @@ -17,6 +18,9 @@ TODO: this file shall be renamed and moved to other places in future to have it shared with multiple applications. ''' +SONIC_DEVICE_PATH = '/usr/share/sonic/device' +NPU_NAME_PREFIX = 'asic' +NAMESPACE_PATH_GLOB = '/run/netns/*' def get_machine_info(): if not os.path.isfile('/host/machine.conf'): return None @@ -27,7 +31,38 @@ def get_machine_info(): if len(tokens) < 2: continue machine_vars[tokens[0]] = tokens[1].strip() - return machine_vars + return machine_vars + +def get_npu_id_from_name(npu_name): + if npu_name.startswith(NPU_NAME_PREFIX): + return npu_name[len(NPU_NAME_PREFIX):] + else: + return None + +def get_num_npus(): + platform = get_platform_info(get_machine_info()) + asic_conf_file_path = os.path.join(SONIC_DEVICE_PATH, platform, 'asic.conf') + if not os.path.isfile(asic_conf_file_path): + return 1 + with open(asic_conf_file_path) as asic_conf_file: + for line in asic_conf_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + if tokens[0].lower() == 'num_asic': + num_npus = tokens[1].strip() + return num_npus + +def get_namespaces(): + """ + In a multi NPU platform, each NPU is in a Linux Namespace. + This method returns list of all the Namespace present on the device + """ + ns_list = [] + for path in glob.glob(NAMESPACE_PATH_GLOB): + ns = os.path.basename(path) + ns_list.append(ns) + return natsorted(ns_list) def get_platform_info(machine_info): if machine_info != None: @@ -51,7 +86,7 @@ def get_sonic_version_info(): def valid_mac_address(mac): return bool(re.match("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", mac)) -def get_system_mac(): +def get_system_mac(namespace=None): version_info = get_sonic_version_info() if (version_info['asic_type'] == 'mellanox'): @@ -73,10 +108,14 @@ def get_system_mac(): # Try valid mac in eeprom, else fetch it from eth0 platform = get_platform_info(get_machine_info()) hwsku = get_machine_info()['onie_machine'] - profile_cmd = 'cat /usr/share/sonic/device/' + platform +'/'+ hwsku +'/profile.ini | cut -f2 -d=' + profile_cmd = 'cat' + SONIC_DEVICE_PATH + '/' + platform +'/'+ hwsku +'/profile.ini | cut -f2 -d=' hw_mac_entry_cmds = [ profile_cmd, "sudo decode-syseeprom -m", "ip link show eth0 | grep ether | awk '{print $2}'" ] else: - hw_mac_entry_cmds = [ "ip link show eth0 | grep ether | awk '{print $2}'" ] + mac_address_cmd = "cat /sys/class/net/eth0/address" + if namespace is not None: + mac_address_cmd = "sudo ip netns exec {} {}".format(namespace, mac_address_cmd) + + hw_mac_entry_cmds = [mac_address_cmd] for get_mac_cmd in hw_mac_entry_cmds: proc = subprocess.Popen(get_mac_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml new file mode 100644 index 000000000000..118202d9b52e --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml @@ -0,0 +1,1214 @@ + + + + + + false + multi_npu_platform_01 + 10.0.0.0 + 01T2 + 10.0.0.1 + 1 + 10 + 3 + + + multi_npu_platform_01 + FC00::1 + 01T2 + FC00::2 + 1 + 10 + 3 + + + false + multi_npu_platform_01 + 10.0.0.8 + 05T2 + 10.0.0.9 + 1 + 10 + 3 + + + multi_npu_platform_01 + FC00::9 + 05T2 + FC00::A + 1 + 10 + 3 + + + BGPSession + false + ASIC2 + 10.1.0.0 + ASIC0 + 10.1.0.1 + 1 + 0 + 0 + + + BGPSession + false + ASIC2 + 10.1.0.4 + ASIC1 + 10.1.0.5 + 1 + 0 + 0 + + + BGPSession + false + ASIC3 + 10.1.0.2 + ASIC0 + 10.1.0.3 + 1 + 0 + 0 + + + BGPSession + false + ASIC3 + 10.1.0.6 + ASIC1 + 10.1.0.7 + 1 + 0 + 0 + + + false + ASIC0 + 10.0.0.0 + 01T2 + 10.0.0.1 + 1 + 10 + 3 + + + ASIC0 + FC00::1 + 01T2 + FC00::2 + 1 + 10 + 3 + + + false + ASIC1 + 10.0.0.8 + 05T2 + 10.0.0.9 + 1 + 10 + 3 + + + ASIC1 + FC00::9 + 05T2 + FC00::A + 1 + 10 + 3 + + + + + 65100 + multi_npu_platform_01 + + +
10.0.0.1
+ + + +
+ +
10.0.0.9
+ + + +
+
+ +
+ + 65100 + + ASIC0 + + + BGPPeer +
10.1.0.1
+ + + +
+ + BGPPeer +
10.1.0.3
+ + + +
+ + BGPPeer +
10.0.0.1
+ + + +
+ + BGPPeer +
FC00::1
+ + + +
+
+ +
+ + 65100 + + ASIC1 + + + BGPPeer +
10.1.0.5
+ + + +
+ + BGPPeer +
10.1.0.7
+ + + +
+ + BGPPeer +
10.0.0.9
+ + + +
+ + BGPPeer +
FC00::A
+ + + +
+
+ +
+ + 65100 + + ASIC2 + + + BGPPeer +
10.1.0.0
+ + + +
+ + BGPPeer +
10.1.0.4
+ + + +
+
+ +
+ + 65100 + + ASIC3 + + + BGPPeer +
10.1.0.2
+ + + +
+ + BGPPeer +
10.1.0.6
+ + + +
+
+ +
+ + 65200 + 01T2 + + + + 65200 + 05T2 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + + + HostIP + eth0 + + 3.10.147.150/23 + + 3.10.147.150/23 + + + V6HostIP + eth0 + + FC00:2::32/64 + + FC00:2::32/64 + + + + + + + multi_npu_platform_01 + + + PortChannel0002 + Ethernet1/1;Ethernet1/2 + + + + PortChannel0008 + Ethernet1/5;Ethernet1/6 + + + + + + + + PortChannel0002 + 10.0.0.0/31 + + + + PortChannel0002 + FC00::1/126 + + + + PortChannel0008 + 10.0.0.8/31 + + + + PortChannel0008 + FC00::9/126 + + + + + + SNMP_ACL + SNMP + SNMP + + + ERSPAN + Everflow + Everflow + + + ERSPANV6 + EverflowV6 + EverflowV6 + + + VTY_LINE + ssh-only + SSH + + + ;PortChannel0002;PortChannel0008 + DataAcl + DataPlane + + + + + + + + + + LoopbackInterface + HostIP + Loopback0 + + 8.0.0.0/32 + + 8.0.0.0/32 + + + + + + + + ASIC0 + + + PortChannelInterface + PortChannel4001 + Eth4-ASIC0;Eth5-ASIC0 + + + + PortChannelInterface + PortChannel4002 + Eth6-ASIC0;Eth7-ASIC0 + + + + PortChannelInterface + PortChannel0002 + Eth0-ASIC0;Eth1-ASIC0 + + + + + + + + IPInterface + + PortChannel4001 + 10.1.0.1/31 + + + IPInterface + + PortChannel4002 + 10.1.0.3/31 + + + + PortChannel0002 + 10.0.0.0/31 + + + + PortChannel0002 + FC00::1/126 + + + + + + + + + + + + LoopbackInterface + HostIP + Loopback0 + + 8.0.0.1/32 + + 8.0.0.1/32 + + + + + + + + ASIC1 + + + PortChannelInterface + PortChannel4003 + Eth4-ASIC1;Eth5-ASIC1 + + + + PortChannelInterface + PortChannel4004 + Eth6-ASIC1;Eth7-ASIC1 + + + + PortChannel0008 + Eth0-ASIC1;Eth1-ASIC1 + + + + + + + + IPInterface + + PortChannel4003 + 10.1.0.5/31 + + + IPInterface + + PortChannel4004 + 10.1.0.7/31 + + + + PortChannel0008 + 10.0.0.8/31 + + + + PortChannel0008 + FC00::9/126 + + + + + + + + + + + + LoopbackInterface + HostIP + Loopback0 + + 8.0.0.4/32 + + 8.0.0.4/32 + + + + + + + + ASIC2 + + + PortChannelInterface + PortChannel4009 + Eth0-ASIC2;Eth1-ASIC2 + + + + PortChannelInterface + PortChannel4010 + Eth2-ASIC2;Eth3-ASIC2 + + + + + + + + IPInterface + + PortChannel4009 + 10.1.0.0/31 + + + IPInterface + + PortChannel4010 + 10.1.0.4/31 + + + + + + + + + + + + LoopbackInterface + HostIP + Loopback0 + + 8.0.0.5/32 + + 8.0.0.5/32 + + + + + + + + ASIC3 + + + PortChannelInterface + PortChannel4013 + Eth0-ASIC3;Eth1-ASIC3 + + + + PortChannelInterface + PortChannel4014 + Eth2-ASIC3;Eth3-ASIC3 + + + + + + + + IPInterface + + PortChannel4013 + 10.1.0.2/31 + + + IPInterface + + PortChannel4014 + 10.1.0.6/31 + + + + + + + + + + + + DeviceInterfaceLink + 01T2 + Ethernet1 + multi_npu_platform_01 + Ethernet1/1 + + + DeviceInterfaceLink + 01T2 + Ethernet2 + multi_npu_platform_01 + Ethernet1/2 + + + DeviceInterfaceLink + 05T2 + Ethernet1 + multi_npu_platform_01 + Ethernet1/8 + + + DeviceInterfaceLink + 05T2 + Ethernet2 + multi_npu_platform_01 + Ethernet1/9 + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth0-ASIC2 + true + ASIC0 + Eth4-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth1-ASIC2 + true + ASIC0 + Eth5-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth0-ASIC3 + true + ASIC0 + Eth6-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth1-ASIC3 + true + ASIC0 + Eth7-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth2-ASIC2 + true + ASIC1 + Eth4-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth3-ASIC2 + true + ASIC1 + Eth5-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth2-ASIC3 + true + ASIC1 + Eth6-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth3-ASIC3 + true + ASIC1 + Eth7-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth0-ASIC0 + true + multi_npu_platform_01 + Ethernet1/1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth1-ASIC0 + true + multi_npu_platform_01 + Ethernet1/2 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth2-ASIC0 + true + multi_npu_platform_01 + Ethernet1/3 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth3-ASIC0 + true + multi_npu_platform_01 + Ethernet1/4 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth0-ASIC1 + true + multi_npu_platform_01 + Ethernet1/5 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth1-ASIC1 + true + multi_npu_platform_01 + Ethernet1/6 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth2-ASIC1 + true + multi_npu_platform_01 + Ethernet1/7 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth3-ASIC1 + true + multi_npu_platform_01 + Ethernet1/8 + true + + + + + multi_npu_platform_01 + multi-npu-01 + + 3.10.147.150 + + + + 07T2 + + 89.139.132.43 + + VM + + + 01T2 + + 89.139.132.40 + + VM + + + 05T2 + + 89.139.132.42 + + VM + + + 03T2 + + 89.139.132.41 + + VM + + + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC0 + multi-npu-asic +
+ + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC1 + multi-npu-asic +
+ + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC2 + multi-npu-asic +
+ + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC3 + multi-npu-asic +
+
+
+ + + true + + + DeviceInterface + + true + true + 1 + Ethernet1/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/2 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/3 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/4 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/5 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/6 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/7 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/8 + + false + 0 + 0 + 40000 + + + true + 0 + multi-npu-01 + + + + + + + multi_npu_platform_01 + + + DeploymentId + + 1 + + + QosProfile + + Profile0 + + + DhcpResources + + 169.118.23.1;169.118.23.2;169.118.23.3;169.118.23.4;169.118.23.5;169.118.23.6;169.118.23.7;169.118.23.8;169.118.23.9;169.118.23.10;169.118.23.11;169.118.23.12;169.118.23.13;169.118.23.14;169.118.23.15;169.118.23.16;169.118.23.17;169.118.23.18;169.118.23.19;169.118.23.20;169.118.23.21;169.118.23.22;169.118.23.23;169.118.23.24;169.118.23.25;169.118.23.26;169.118.23.27;169.118.23.28;169.118.23.29;169.118.23.30;169.118.23.31;169.118.23.32;169.118.23.33;169.118.23.34;169.118.23.35;169.118.23.36;169.118.23.37;169.118.23.38;169.118.23.39;169.118.23.40;169.118.23.41;169.118.23.42;169.118.23.43;169.118.23.44;169.118.23.45;169.118.23.46;169.118.23.47;169.118.23.48 + + + NtpResources + + 17.39.1.129;17.39.1.130 + + + SnmpResources + + 71.49.219.98 + + + SyslogResources + + 71.49.219.8;123.46.98.21 + + + TacacsGroup + + Starlab + + + TacacsServer + + 123.46.98.21 + + + ForcedMgmtRoutes + + 71.49.219.98/31;71.49.219.8;123.46.98.16/28;10.3.149.170/31;40.122.216.24;13.91.48.226;71.49.219.14 + + + ErspanDestinationIpv4 + + 10.20.6.16 + + + + + ASIC0 + + + SubRole + + FrontEnd + + + + + ASIC1 + + + SubRole + + FrontEnd + + + + + ASIC2 + + + SubRole + + FrontEnd + + + + + ASIC3 + + + SubRole + + FrontEnd + + + + + ASIC2 + + + SubRole + + BackEnd + + + + + ASIC3 + + + SubRole + + BackEnd + + + + + + + multi_npu_platform_01 + multi-npu-01 +
diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini new file mode 100644 index 000000000000..3fe912c98c45 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet0 33,34,35,36 Ethernet1/1 Eth0-ASIC0 +Ethernet4 29,30,31,32 Ethernet1/2 Eth1-ASIC0 +Ethernet8 41,42,43,44 Ethernet1/3 Eth2-ASIC0 +Ethernet12 37,38,39,40 Ethernet1/4 Eth3-ASIC0 +Ethernet-BP0 13,14,15,16 Ethernet-BP0 Eth4-ASIC0 +Ethernet-BP4 17,18,19,20 Ethernet-BP4 Eth5-ASIC0 +Ethernet-BP8 21,22,23,24 Ethernet-BP8 Eth6-ASIC0 +Ethernet-BP12 25,26,27,28 Ethernet-BP12 Eth7-ASIC0 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini new file mode 100644 index 000000000000..c496e0712a49 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet16 33,34,35,36 Ethernet1/5 Eth0-ASIC1 +Ethernet20 29,30,31,32 Ethernet1/6 Eth1-ASIC1 +Ethernet24 41,42,43,44 Ethernet1/7 Eth2-ASIC1 +Ethernet28 37,38,39,40 Ethernet1/8 Eth3-ASIC1 +Ethernet-BP16 13,14,15,16 Ethernet-BP16 Eth4-ASIC1 +Ethernet-BP20 17,18,19,20 Ethernet-BP20 Eth5-ASIC1 +Ethernet-BP24 21,22,23,24 Ethernet-BP24 Eth6-ASIC1 +Ethernet-BP28 25,26,27,28 Ethernet-BP28 Eth7-ASIC1 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini new file mode 100644 index 000000000000..4ae0575835a7 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet-BP256 61,62,63,64 Ethernet-BP256 Eth0-ASIC2 +Ethernet-BP260 57,58,59,60 Ethernet-BP260 Eth1-ASIC2 +Ethernet-BP264 53,54,55,56 Ethernet-BP264 Eth2-ASIC2 +Ethernet-BP268 49,50,51,52 Ethernet-BP268 Eth3-ASIC2 +Ethernet-BP272 45,46,47,48 Ethernet-BP272 Eth4-ASIC2 +Ethernet-BP276 41,42,43,44 Ethernet-BP276 Eth5-ASIC2 +Ethernet-BP280 37,38,39,40 Ethernet-BP280 Eth6-ASIC2 +Ethernet-BP284 33,34,35,36 Ethernet-BP284 Eth7-ASIC2 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini new file mode 100644 index 000000000000..8f45ed14946e --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet-BP384 29,30,31,32 Ethernet-BP384 Eth0-ASIC3 +Ethernet-BP388 25,26,27,28 Ethernet-BP388 Eth1-ASIC3 +Ethernet-BP392 21,22,23,24 Ethernet-BP392 Eth2-ASIC3 +Ethernet-BP396 17,18,19,20 Ethernet-BP396 Eth3-ASIC3 +Ethernet-BP400 13,14,15,16 Ethernet-BP400 Eth4-ASIC3 +Ethernet-BP404 9,10,11,12 Ethernet-BP404 Eth5-ASIC3 +Ethernet-BP408 5,6,7,8 Ethernet-BP408 Eth6-ASIC3 +Ethernet-BP412 1,2,3,4 Ethernet-BP412 Eth7-ASIC3 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py new file mode 100644 index 000000000000..6facae0451db --- /dev/null +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -0,0 +1,221 @@ +import unittest +from unittest import TestCase +import subprocess +import os +import json +import yaml + +SKU = 'multi-npu-01' +ASIC_SKU = 'multi-npu-asic' +NUM_ASIC = 4 +HOSTNAME = 'multi_npu_platform_01' + + +class TestMultiNpuCfgGen(TestCase): + + def setUp(self): + self.test_dir = os.path.dirname(os.path.realpath(__file__)) + self.test_data_dir = os.path.join(self.test_dir, 'multi_npu_data') + self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.sample_graph = os.path.join(self.test_data_dir, 'sample-minigraph.xml') + self.port_config = [] + for asic in range(NUM_ASIC): + self.port_config.append(os.path.join(self.test_data_dir, "sample_port_config-{}.ini".format(asic))) + + def run_script(self, argument, check_stderr=False): + print '\n Running sonic-cfggen ' + argument + if check_stderr: + output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + linecount = output.strip().count('\n') + if linecount <= 0: + print ' Output: ' + output.strip() + else: + print ' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output)) + return output + + def run_diff(self, file1, file2): + return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) + + def run_script_for_asic(self,argument,asic, port_config=None): + argument = "{} -n asic{} ".format(argument, asic) + if port_config: + argument += "-p {}".format(port_config) + output = self.run_script(argument) + return output + + def test_dummy_run(self): + argument = '' + output = self.run_script(argument) + self.assertEqual(output, '') + + def test_hwsku(self): + argument = "-v \"DEVICE_METADATA[\'localhost\'][\'hwsku\']\" -m \"{}\"".format(self.sample_graph) + output = self.run_script(argument) + self.assertEqual(output.strip(), SKU) + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertEqual(output.strip(), SKU) + + def test_print_data(self): + argument = "-m \"{}\" --print-data".format(self.sample_graph) + output = self.run_script(argument) + self.assertGreater(len(output.strip()) , 0) + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertGreater(len(output.strip()) , 0) + + def test_additional_json_data(self): + argument = '-a \'{"key1":"value1"}\' -v key1' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'value1') + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertEqual(output.strip(), 'value1') + + def test_read_yaml(self): + argument = '-v yml_item -y ' + os.path.join(self.test_dir, 'test.yml') + output = yaml.load(self.run_script(argument)) + self.assertListEqual(output, ['value1', 'value2']) + for asic in range(NUM_ASIC): + output = yaml.load(self.run_script_for_asic(argument, asic)) + self.assertListEqual(output, ['value1', 'value2']) + + def test_render_template(self): + argument = '-y ' + os.path.join(self.test_dir, 'test.yml') + ' -t ' + os.path.join(self.test_dir, 'test.j2') + output = self.run_script(argument) + self.assertEqual(output.strip(), 'value1\nvalue2') + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertEqual(output.strip(), 'value1\nvalue2') + + def test_metadata_tacacs(self): + argument = '-m "' + self.sample_graph + '" --var-json "TACPLUS_SERVER"' + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {'123.46.98.21': {'priority': '1', 'tcp_port': '49'}}) + #TACPLUS_SERVER not present in the asic configuration. + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic, self.port_config[asic])) + self.assertDictEqual(output, {}) + + def test_metadata_ntp(self): + argument = '-m "' + self.sample_graph + '" --var-json "NTP_SERVER"' + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {'17.39.1.130': {}, '17.39.1.129': {}}) + #NTP data is present only in the host config + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic, self.port_config[asic])) + print "Log:asic{} sku {}".format(asic,output) + self.assertDictEqual(output, {}) + + def test_mgmt_port(self): + argument = '-m "' + self.sample_graph + '" --var-json "MGMT_PORT"' + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {'eth0': {'alias': 'eth0', 'admin_status': 'up'}}) + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic, self.port_config[asic])) + self.assertDictEqual(output, {}) + + def test_frontend_asic_portchannels(self): + argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'PortChannel0002': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet0', 'Ethernet4'], 'mtu': '9100'}, + 'PortChannel4001': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP0', 'Ethernet-BP4'], 'mtu': '9100'}, + 'PortChannel4002': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP8', 'Ethernet-BP12'], 'mtu': '9100'}}) + + def test_backend_asic_portchannels(self): + argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'PortChannel4013': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP384', 'Ethernet-BP388'], 'mtu': '9100'}, + 'PortChannel4014': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP392', 'Ethernet-BP396'], 'mtu': '9100'}}) + + def test_frontend_asic_portchannel_mem(self): + argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL_MEMBER\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['PortChannel4002|Ethernet-BP8', 'PortChannel0002|Ethernet0', 'PortChannel0002|Ethernet4', 'PortChannel4002|Ethernet-BP12', 'PortChannel4001|Ethernet-BP0', 'PortChannel4001|Ethernet-BP4']) + + def test_backend_asic_portchannels_mem(self): + argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL_MEMBER\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['PortChannel4013|Ethernet-BP384', 'PortChannel4014|Ethernet-BP392', 'PortChannel4014|Ethernet-BP396', 'PortChannel4013|Ethernet-BP388']) + + def test_frontend_asic_portchannel_intf(self): + argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['PortChannel4001|10.1.0.1/31', 'PortChannel0002|FC00::1/126', 'PortChannel4002|10.1.0.3/31', 'PortChannel0002', 'PortChannel0002|10.0.0.0/31', 'PortChannel4001', 'PortChannel4002']) + + def test_backend_asic_portchannel_intf(self): + argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['PortChannel4013', 'PortChannel4013|10.1.0.2/31', 'PortChannel4014', 'PortChannel4014|10.1.0.6/31']) + + def test_frontend_asic_device_neigh(self): + argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'Ethernet0': {'name': '01T2', 'port': 'Ethernet1'}, + 'Ethernet4': {'name': '01T2', 'port': 'Ethernet2'}, + 'Ethernet-BP4': {'name': 'ASIC2', 'port': 'Eth1-ASIC2'}, + 'Ethernet-BP12': {'name': 'ASIC3', 'port': 'Eth1-ASIC3'}, + 'Ethernet-BP0': {'name': 'ASIC2', 'port': 'Eth0-ASIC2'}, + 'Ethernet-BP8': {'name': 'ASIC3', 'port': 'Eth0-ASIC3'}}) + + def test_frontend_asic_device_neigh_metadata(self): + argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR_METADATA\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'01T2': {'lo_addr': None, 'mgmt_addr': '89.139.132.40', 'hwsku': 'VM', 'type': 'SpineRouter'}, + 'ASIC3': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, + 'ASIC2': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) + + def test_backend_asic_device_neigh(self): + argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'Ethernet-BP396': {'name': 'ASIC1', 'port': 'Eth7-ASIC1'}, + 'Ethernet-BP384': {'name': 'ASIC0', 'port': 'Eth6-ASIC0'}, + 'Ethernet-BP392': {'name': 'ASIC1', 'port': 'Eth6-ASIC1'}, + 'Ethernet-BP388': {'name': 'ASIC0', 'port': 'Eth7-ASIC0'}}) + + def test_backend_device_neigh_metadata(self): + argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR_METADATA\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'ASIC1': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, + 'ASIC0': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) + + def test_frontend_bgp_neighbor(self): + argument = "-m {} -p {} -n asic0 --var-json \"BGP_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'10.0.0.1': {'rrclient': 0, 'name': '01T2', 'local_addr': '10.0.0.0', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}, + '10.1.0.0': {'rrclient': 0, 'name': 'ASIC2', 'local_addr': '10.1.0.1', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}, + 'fc00::2': {'rrclient': 0, 'name': '01T2', 'local_addr': 'fc00::1', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}, + '10.1.0.2': {'rrclient': 0, 'name': 'ASIC3', 'local_addr': '10.1.0.3', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}}) + + def test_backend_asic_bgp_neighbor(self): + argument = "-m {} -p {} -n asic3 --var-json \"BGP_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'10.1.0.7': {'rrclient': 0, 'name': 'ASIC1', 'local_addr': '10.1.0.6', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}, + '10.1.0.3': {'rrclient': 0, 'name': 'ASIC0', 'local_addr': '10.1.0.2', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}}) + + def test_device_asic_metadata(self): + argument = "-m {} --var-json DEVICE_METADATA".format(self.sample_graph) + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic,self.port_config[asic])) + asic_name = "asic{}".format(asic) + self.assertEqual(output['localhost']['hostname'], asic_name) + self.assertEqual(output['localhost']['type'], 'Asic') + if asic == 0 or asic == 1: + self.assertEqual(output['localhost']['sub_role'], 'FrontEnd') + else: + self.assertEqual(output['localhost']['sub_role'], 'BackEnd') From 6c9dd7674d1105e01a134c79c86210ecd0823444 Mon Sep 17 00:00:00 2001 From: Srideep Date: Tue, 5 May 2020 01:22:10 -0600 Subject: [PATCH 0622/1427] [device] DellEMC s5232f 50G hwsku support (#4525) * [device] DellEmc S5232 support for new hwsku C8D48 8 100G ports and 48 50G ports * 10G ports update for S5232 hwsku-C8D48 Signed-off-by: Srideep Devireddy --- .../DellEMC-S5232f-C8D48/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 37 ++ .../buffers_defaults_t1.j2 | 37 ++ .../DellEMC-S5232f-C8D48/custom_led.bin | Bin 0 -> 468 bytes .../DellEMC-S5232f-C8D48/linkscan_led_fw.bin | Bin 0 -> 4752 bytes .../pg_profile_lookup.ini | 17 + .../DellEMC-S5232f-C8D48/port_config.ini | 59 ++ .../DellEMC-S5232f-C8D48/qos.json.j2 | 1 + .../DellEMC-S5232f-C8D48/sai.profile | 1 + .../DellEMC-S5232f-C8D48/sai_preinit_cmd.soc | 2 + .../td3-s5232f-8x100G+48x50G.config.bcm | 572 ++++++++++++++++++ 11 files changed, 728 insertions(+) create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/custom_led.bin create mode 100755 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/linkscan_led_fw.bin create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/pg_profile_lookup.ini create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/qos.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers.json.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..98ec91a9b694 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 @@ -0,0 +1,37 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "28550336", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_pool": { + "size": "28550336", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "static", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..98ec91a9b694 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 @@ -0,0 +1,37 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "28550336", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_pool": { + "size": "28550336", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "static", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/custom_led.bin b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..49e559cd9813f2cb9191012b36a295f1f3f54b97 GIT binary patch literal 468 zcmeycHQp`E&DYJv?ZcMV4W8ai8Bz%z-mV$42_8NSN*?|U%8Y7T+!|C@xiPD4a7%UL zbzq+A;J49@<$;1W<3$#8pu7pAkzxhY#7+j*3{OeE4#sJTZZjS1GWeX>E;s^B&dp%Z zmAR1UCiTD(XcOaHJtxr%6E`(z+TUbR+w7L;#-bYMX6oc{p*4eP-pW{3OJAoyO=_v{QgZSITm-V92!5~4F0w3#l*ct<5LJz!Ll z0@9M+voaWsW+gBxA5LISbWn0iWKwEMJe=sL%$(Gu?3~n;#GrgQ>2UJl6yXOD8`(73 zFES}IJYZ6Ebz_`o>U8Mh(dQ5uPR%bD4!f;=&bq;7&jh!bZj0PjyM5Su!0n191H%a* zb^+oQ8yFZE7@3$^SlQS)IJvlac=`AR1cih}M8(7Lc_u%BBP>XV&mcy p5|ffsQq$5iGPAOCa`W;F3X6(MO3TVCDyyn%YU}D7nt*OV0sz^yjTHa@ literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/linkscan_led_fw.bin new file mode 100755 index 0000000000000000000000000000000000000000..c2fa94a2d8cb11161cc337d00971e7267f08d32e GIT binary patch literal 4752 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 X`cUsHXR!vGk^Z4y?GFw9z}SBSTZoUr literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/pg_profile_lookup.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/pg_profile_lookup.ini new file mode 100644 index 000000000000..aedda37a8878 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 90272 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 53248 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 96096 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini new file mode 100644 index 000000000000..b7a336827ffe --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini @@ -0,0 +1,59 @@ +# name lanes alias index speed +Ethernet0 1,2 fiftyGigE1/1/1 1 50000 +Ethernet2 3,4 fiftyGigE1/1/2 1 50000 +Ethernet4 5,6 fiftyGigE1/2/1 2 50000 +Ethernet6 7,8 fiftyGigE1/2/2 2 50000 +Ethernet8 9,10 fiftyGigE1/3/1 3 50000 +Ethernet10 11,12 fiftyGigE1/3/2 3 50000 +Ethernet12 13,14 fiftyGigE1/4/1 4 50000 +Ethernet14 15,16 fiftyGigE1/4/2 4 50000 +Ethernet16 17,18 fiftyGigE1/5/1 5 50000 +Ethernet18 19,20 fiftyGigE1/5/2 5 50000 +Ethernet20 21,22 fiftyGigE1/6/1 6 50000 +Ethernet22 23,24 fiftyGigE1/6/2 6 50000 +Ethernet24 25,26,27,28 hundredGigE1/7 7 100000 +Ethernet28 29,30,31,32 hundredGigE1/8 8 100000 +Ethernet32 33,34,35,36 hundredGigE1/9 9 100000 +Ethernet36 37,38,39,40 hundredGigE1/10 10 100000 +Ethernet40 41,42 fiftyGigE1/11/1 11 50000 +Ethernet42 43,44 fiftyGigE1/11/2 11 50000 +Ethernet44 45,46 fiftyGigE1/12/1 12 50000 +Ethernet46 47,48 fiftyGigE1/12/2 12 50000 +Ethernet48 49,50 fiftyGigE1/13/1 13 50000 +Ethernet50 51,52 fiftyGigE1/13/2 13 50000 +Ethernet52 53,54 fiftyGigE1/14/1 14 50000 +Ethernet54 55,56 fiftyGigE1/14/2 14 50000 +Ethernet56 57,58 fiftyGigE1/15/1 15 50000 +Ethernet58 59,60 fiftyGigE1/15/2 15 50000 +Ethernet60 61,62 fiftyGigE1/16/1 16 50000 +Ethernet62 63,64 fiftyGigE1/16/2 16 50000 +Ethernet64 65,66 fiftyGigE1/17/1 17 50000 +Ethernet66 67,68 fiftyGigE1/17/2 17 50000 +Ethernet68 69,70 fiftyGigE1/18/1 18 50000 +Ethernet70 71,72 fiftyGigE1/18/2 18 50000 +Ethernet72 73,74 fiftyGigE1/19/1 19 50000 +Ethernet74 75,76 fiftyGigE1/19/2 19 50000 +Ethernet76 77,78 fiftyGigE1/20/1 20 50000 +Ethernet78 79,80 fiftyGigE1/20/2 20 50000 +Ethernet80 81,82 fiftyGigE1/21/1 21 50000 +Ethernet82 83,84 fiftyGigE1/21/2 21 50000 +Ethernet84 85,86 fiftyGigE1/22/1 22 50000 +Ethernet86 87,88 fiftyGigE1/22/2 22 50000 +Ethernet88 89,90 fiftyGigE1/23/1 23 50000 +Ethernet90 91,92 fiftyGigE1/23/2 23 50000 +Ethernet92 93,94 fiftyGigE1/24/1 24 50000 +Ethernet94 95,96 fiftyGigE1/24/2 24 50000 +Ethernet96 97,98 fiftyGigE1/25/1 25 50000 +Ethernet98 99,100 fiftyGigE1/25/2 25 50000 +Ethernet100 101,102 fiftyGigE1/26/1 26 50000 +Ethernet102 103,104 fiftyGigE1/26/2 26 50000 +Ethernet104 105,106,107,108 hundredGigE1/27 27 100000 +Ethernet108 109,110,111,112 hundredGigE1/28 28 100000 +Ethernet112 113,114,115,116 hundredGigE1/29 29 100000 +Ethernet116 117,118,119,120 hundredGigE1/30 30 100000 +Ethernet120 121,122 fiftyGigE1/31/1 31 50000 +Ethernet122 123,124 fiftyGigE1/31/2 31 50000 +Ethernet124 125,126 fiftyGigE1/32/1 32 50000 +Ethernet126 127,128 fiftyGigE1/32/2 32 50000 +Ethernet128 129 tenGigE1/33 33 10000 +Ethernet129 128 tenGigE1/34 34 10000 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/qos.json.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile new file mode 100644 index 000000000000..0daed30c3bc2 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-8x100G+48x50G.config.bcm diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm new file mode 100644 index 000000000000..cf0bfd043ee0 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm @@ -0,0 +1,572 @@ +os=unix + +core_clock_frequency=1525 +dpp_clock_ratio=2:3 + +parity_enable=1 +parity_correction=1 +tdma_intr_enable=1 +schan_intr_enable=0 +tdma_intr_enable=1 +miim_intr_enable=1 +stat_if_parity_enable=1 + +port_flex_enable=1 +port_flex_enable_66=0 +port_flex_enable_130=0 +phy_an_c73=3 +phy_an_c73_66=0 +phy_an_c73_130=0 + +module_64ports=0 +table_dma_enable=1 +tdma_timeout_usec=5000000 +mmu_lossless=0 +pdma_descriptor_prefetch_enable=1 +pktdma_poll_mode_channel_bitmap=1 + +l2xmsg_mode=1 +l2xmsg_hostbuf_size=8192 +ipv6_lpm_128b_enable=1 +max_vp_lags=0 + +l3_alpm_enable=2 +l2_mem_entries=32768 +l3_mem_entries=16384 +l3_max_ecmp_mode=1 + +bcm_tunnel_term_compatible_mode=1 +ifp_inports_support_enable=1 + +stable_size=0x5500000 + +oversubscribe_mode=1 +pbmp_oversubscribe=0x6fffffffffffffffdfffffffffffffffe +pbmp_xport_xe=0x6fffffffffffffffdfffffffffffffffe + + +portmap_1.0=1:50:2 +portmap_3.0=3:50:2 +portmap_5.0=5:50:2 +portmap_7.0=7:50:2 +portmap_9.0=9:50:2 +portmap_11.0=11:50:2 +portmap_13.0=13:50:2 +portmap_15.0=15:50:2 +portmap_17.0=17:50:2 +portmap_19.0=19:50:2 +portmap_21.0=21:50:2 +portmap_23.0=23:50:2 +portmap_25.0=25:100 +portmap_29.0=29:100 +portmap_33.0=33:100 +portmap_37.0=37:100 +portmap_41.0=41:50:2 +portmap_43.0=43:50:2 +portmap_45.0=45:50:2 +portmap_47.0=47:50:2 +portmap_49.0=49:50:2 +portmap_51.0=51:50:2 +portmap_53.0=53:50:2 +portmap_55.0=55:50:2 +portmap_57.0=57:50:2 +portmap_59.0=59:50:2 +portmap_61.0=61:50:2 +portmap_63.0=63:50:2 +portmap_67.0=65:50:2 +portmap_69.0=67:50:2 +portmap_71.0=69:50:2 +portmap_73.0=71:50:2 +portmap_75.0=73:50:2 +portmap_77.0=75:50:2 +portmap_79.0=77:50:2 +portmap_81.0=79:50:2 +portmap_83.0=81:50:2 +portmap_85.0=83:50:2 +portmap_87.0=85:50:2 +portmap_89.0=87:50:2 +portmap_91.0=89:50:2 +portmap_93.0=91:50:2 +portmap_95.0=93:50:2 +portmap_97.0=95:50:2 +portmap_99.0=97:50:2 +portmap_101.0=99:50:2 +portmap_103.0=101:50:2 +portmap_105.0=103:50:2 +portmap_107.0=105:100 +portmap_111.0=109:100 +portmap_115.0=113:100 +portmap_119.0=117:100 +portmap_123.0=121:50:2 +portmap_125.0=123:50:2 +portmap_127.0=125:50:2 +portmap_129.0=127:50:2 +portmap_130.0=128:10:m +portmap_66.0=129:10:m + + +phy_chain_tx_lane_map_physical{1.0}=0x0132 +phy_chain_rx_lane_map_physical{1.0}=0x3210 +phy_chain_tx_lane_map_physical{5.0}=0x2301 +phy_chain_rx_lane_map_physical{5.0}=0x2031 +phy_chain_tx_lane_map_physical{9.0}=0x0132 +phy_chain_rx_lane_map_physical{9.0}=0x3210 +phy_chain_tx_lane_map_physical{13.0}=0x3201 +phy_chain_rx_lane_map_physical{13.0}=0x2031 +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x3210 +phy_chain_tx_lane_map_physical{21.0}=0x2301 +phy_chain_rx_lane_map_physical{21.0}=0x2031 +phy_chain_tx_lane_map_physical{25.0}=0x0123 +phy_chain_rx_lane_map_physical{25.0}=0x3210 +phy_chain_tx_lane_map_physical{29.0}=0x3201 +phy_chain_rx_lane_map_physical{29.0}=0x2031 +phy_chain_tx_lane_map_physical{33.0}=0x0213 +phy_chain_rx_lane_map_physical{33.0}=0x1302 +phy_chain_tx_lane_map_physical{37.0}=0x1302 +phy_chain_rx_lane_map_physical{37.0}=0x2031 +phy_chain_tx_lane_map_physical{41.0}=0x0231 +phy_chain_rx_lane_map_physical{41.0}=0x3120 +phy_chain_tx_lane_map_physical{45.0}=0x1302 +phy_chain_rx_lane_map_physical{45.0}=0x2031 +phy_chain_tx_lane_map_physical{49.0}=0x2103 +phy_chain_rx_lane_map_physical{49.0}=0x3120 +phy_chain_tx_lane_map_physical{53.0}=0x2301 +phy_chain_rx_lane_map_physical{53.0}=0x2031 +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x2301 +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x1032 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x1023 +phy_chain_tx_lane_map_physical{69.0}=0x0123 +phy_chain_rx_lane_map_physical{69.0}=0x1302 +phy_chain_tx_lane_map_physical{73.0}=0x2301 +phy_chain_rx_lane_map_physical{73.0}=0x1032 +phy_chain_tx_lane_map_physical{77.0}=0x2013 +phy_chain_rx_lane_map_physical{77.0}=0x3120 +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_rx_lane_map_physical{81.0}=0x2031 +phy_chain_tx_lane_map_physical{85.0}=0x0123 +phy_chain_rx_lane_map_physical{85.0}=0x2130 +phy_chain_tx_lane_map_physical{89.0}=0x2301 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_tx_lane_map_physical{93.0}=0x0312 +phy_chain_rx_lane_map_physical{93.0}=0x2310 +phy_chain_tx_lane_map_physical{97.0}=0x2301 +phy_chain_rx_lane_map_physical{97.0}=0x1032 +phy_chain_tx_lane_map_physical{101.0}=0x0123 +phy_chain_rx_lane_map_physical{101.0}=0x3210 +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_rx_lane_map_physical{105.0}=0x1032 +phy_chain_tx_lane_map_physical{109.0}=0x0123 +phy_chain_rx_lane_map_physical{109.0}=0x3210 +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{113.0}=0x2031 +phy_chain_tx_lane_map_physical{117.0}=0x0123 +phy_chain_rx_lane_map_physical{117.0}=0x3210 +phy_chain_tx_lane_map_physical{121.0}=0x2301 +phy_chain_rx_lane_map_physical{121.0}=0x1032 +phy_chain_tx_lane_map_physical{125.0}=0x0123 +phy_chain_rx_lane_map_physical{125.0}=0x3210 +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_lane_map_physical{129.0}=0x0231 +phy_chain_tx_lane_map_physical{128.0}=0x3210 +phy_chain_rx_lane_map_physical{128.0}=0x0231 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x0 +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_rx_polarity_flip_physical{112.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 +phy_chain_tx_polarity_flip_physical{129.0}=0x1 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_tx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_rx_polarity_flip_physical{131.0}=0x1 +phy_chain_tx_polarity_flip_physical{132.0}=0x0 +phy_chain_rx_polarity_flip_physical{132.0}=0x1 +dport_map_enable=1 +dport_map_port_1=1 +dport_map_port_2=2 +dport_map_port_3=3 +dport_map_port_4=4 +dport_map_port_5=5 +dport_map_port_6=6 +dport_map_port_7=7 +dport_map_port_8=8 +dport_map_port_9=9 +dport_map_port_10=10 +dport_map_port_11=11 +dport_map_port_12=12 +dport_map_port_13=13 +dport_map_port_14=14 +dport_map_port_15=15 +dport_map_port_16=16 +dport_map_port_17=17 +dport_map_port_18=18 +dport_map_port_19=19 +dport_map_port_20=20 +dport_map_port_21=21 +dport_map_port_22=22 +dport_map_port_23=23 +dport_map_port_24=24 +dport_map_port_25=25 +dport_map_port_26=26 +dport_map_port_27=27 +dport_map_port_28=28 +dport_map_port_29=29 +dport_map_port_30=30 +dport_map_port_31=31 +dport_map_port_32=32 +dport_map_port_33=33 +dport_map_port_34=34 +dport_map_port_35=35 +dport_map_port_36=36 +dport_map_port_37=37 +dport_map_port_38=38 +dport_map_port_39=39 +dport_map_port_40=40 +dport_map_port_41=41 +dport_map_port_42=42 +dport_map_port_43=43 +dport_map_port_44=44 +dport_map_port_45=45 +dport_map_port_46=46 +dport_map_port_47=47 +dport_map_port_48=48 +dport_map_port_49=49 +dport_map_port_50=50 +dport_map_port_51=51 +dport_map_port_52=52 +dport_map_port_53=53 +dport_map_port_54=54 +dport_map_port_55=55 +dport_map_port_56=56 +dport_map_port_57=57 +dport_map_port_58=58 +dport_map_port_59=59 +dport_map_port_60=60 +dport_map_port_61=61 +dport_map_port_62=62 +dport_map_port_63=63 +dport_map_port_64=64 +dport_map_port_67=65 +dport_map_port_68=66 +dport_map_port_69=67 +dport_map_port_70=68 +dport_map_port_71=69 +dport_map_port_72=70 +dport_map_port_73=71 +dport_map_port_74=72 +dport_map_port_75=73 +dport_map_port_76=74 +dport_map_port_77=75 +dport_map_port_78=76 +dport_map_port_79=77 +dport_map_port_80=78 +dport_map_port_81=79 +dport_map_port_82=80 +dport_map_port_83=81 +dport_map_port_84=82 +dport_map_port_85=83 +dport_map_port_86=84 +dport_map_port_87=85 +dport_map_port_88=86 +dport_map_port_89=87 +dport_map_port_90=88 +dport_map_port_91=89 +dport_map_port_92=90 +dport_map_port_93=91 +dport_map_port_94=92 +dport_map_port_95=93 +dport_map_port_96=94 +dport_map_port_97=95 +dport_map_port_98=96 +dport_map_port_99=97 +dport_map_port_100=98 +dport_map_port_101=99 +dport_map_port_102=100 +dport_map_port_103=101 +dport_map_port_104=102 +dport_map_port_105=103 +dport_map_port_106=104 +dport_map_port_107=105 +dport_map_port_108=106 +dport_map_port_109=107 +dport_map_port_110=108 +dport_map_port_111=109 +dport_map_port_112=110 +dport_map_port_113=111 +dport_map_port_114=112 +dport_map_port_115=113 +dport_map_port_116=114 +dport_map_port_117=115 +dport_map_port_118=116 +dport_map_port_119=117 +dport_map_port_120=118 +dport_map_port_121=119 +dport_map_port_122=120 +dport_map_port_123=121 +dport_map_port_124=122 +dport_map_port_125=123 +dport_map_port_126=124 +dport_map_port_127=125 +dport_map_port_129=126 +dport_map_port_66=127 +dport_map_port_130=128 + +mmu_init_config="TD3-DEFAULT-LOSSLESS-P3P4" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc + From 5307f9448e2090a3b8a61c64ea2faf0e2f4a262a Mon Sep 17 00:00:00 2001 From: Myron Sosyak <49795530+msosyak@users.noreply.github.com> Date: Tue, 5 May 2020 12:05:17 +0300 Subject: [PATCH 0623/1427] [devices] skip_fancontrol for wedge 100 barefoot platforms (#4528) --- .../x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json index d00d924bcd17..ae8601e866b4 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json @@ -1,7 +1,8 @@ { + "skip_fancontrol": true, "skip_thermalctld": true, "skip_ledd": true, "skip_xcvrd": false, "skip_psud": false, - "skip_syseepromd": false + "skip_syseepromd": false } diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json index d00d924bcd17..ae8601e866b4 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json @@ -1,7 +1,8 @@ { + "skip_fancontrol": true, "skip_thermalctld": true, "skip_ledd": true, "skip_xcvrd": false, "skip_psud": false, - "skip_syseepromd": false + "skip_syseepromd": false } From 46ef6defa7c1308acc14837728465c23a5ce4fbf Mon Sep 17 00:00:00 2001 From: Wei Bai Date: Tue, 5 May 2020 18:40:20 -0700 Subject: [PATCH 0624/1427] [docker-sonic-mgmt] Add IxNetwork python client (#4533) * Add IxNetwork python client to sonic mgmt docker --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 2b3c860461e4..d606749948d0 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -74,6 +74,7 @@ RUN pip install ipaddr \ rpyc \ tabulate \ textfsm \ + ixnetwork-restpy==1.0.52 \ && git clone https://github.com/p4lang/scapy-vxlan.git \ && cd scapy-vxlan \ && python setup.py install \ From fd953a437e5d3397154d59de518b23427cf03777 Mon Sep 17 00:00:00 2001 From: Kalimuthu-Velappan <53821802+Kalimuthu-Velappan@users.noreply.github.com> Date: Wed, 6 May 2020 05:17:08 +0000 Subject: [PATCH 0625/1427] Fix for missing dependency in the sonic device package and added .dep file for yang module (#4471) --- rules/sonic-device-data.dep | 1 + rules/sonic-yang-models-py3.dep | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 rules/sonic-yang-models-py3.dep diff --git a/rules/sonic-device-data.dep b/rules/sonic-device-data.dep index c6105f939f67..325b1492ab49 100644 --- a/rules/sonic-device-data.dep +++ b/rules/sonic-device-data.dep @@ -3,6 +3,7 @@ SPATH := $($(SONIC_DEVICE_DATA)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-device-data.mk rules/sonic-device-data.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) DEP_FILES += $(shell git ls-files $(SPATH)) +DEP_FILES += $(shell find device -type l -prune -o -type f -print ) $(SONIC_DEVICE_DATA)_CACHE_MODE := GIT_CONTENT_SHA $(SONIC_DEVICE_DATA)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) diff --git a/rules/sonic-yang-models-py3.dep b/rules/sonic-yang-models-py3.dep new file mode 100644 index 000000000000..34b8c785f4bf --- /dev/null +++ b/rules/sonic-yang-models-py3.dep @@ -0,0 +1,9 @@ +SPATH := $($(SONIC_YANG_MODELS_PY3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-yang-models-py3.mk rules/sonic-yang-models-py3.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_YANG_MODELS_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_YANG_MODELS_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_YANG_MODELS_PY3)_DEP_FILES := $(DEP_FILES) + From 767bc5c8c0e0c530a85b44d75bf504d4ebb39124 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 6 May 2020 10:23:38 +0000 Subject: [PATCH 0626/1427] [build]: add docker-saiserver-* as stretch docker targets Signed-off-by: Guohan Lu --- platform/broadcom/docker-saiserver-brcm.mk | 1 + platform/marvell-arm64/docker-saiserver-mrvl.mk | 1 + platform/marvell-armhf/docker-saiserver-mrvl.mk | 1 + platform/mellanox/docker-saiserver-mlnx.mk | 1 + 4 files changed, 4 insertions(+) diff --git a/platform/broadcom/docker-saiserver-brcm.mk b/platform/broadcom/docker-saiserver-brcm.mk index b754ab679884..d587a39ba22c 100644 --- a/platform/broadcom/docker-saiserver-brcm.mk +++ b/platform/broadcom/docker-saiserver-brcm.mk @@ -6,6 +6,7 @@ $(DOCKER_SAISERVER_BRCM)_DEPENDS += $(SAISERVER) $(DOCKER_SAISERVER_BRCM)_FILES += $(DSSERVE) $(BCMCMD) $(DOCKER_SAISERVER_BRCM)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_BRCM) +SONIC_STRETCH_DOCKERS += $(DOCKER_SAISERVER_BRCM) $(DOCKER_SAISERVER_BRCM)_CONTAINER_NAME = saiserver $(DOCKER_SAISERVER_BRCM)_RUN_OPT += --net=host --privileged -t diff --git a/platform/marvell-arm64/docker-saiserver-mrvl.mk b/platform/marvell-arm64/docker-saiserver-mrvl.mk index 07dac2a4610d..a449e3e83e45 100644 --- a/platform/marvell-arm64/docker-saiserver-mrvl.mk +++ b/platform/marvell-arm64/docker-saiserver-mrvl.mk @@ -5,6 +5,7 @@ $(DOCKER_SAISERVER_MRVL)_PATH = $(PLATFORM_PATH)/docker-saiserver-mrvl $(DOCKER_SAISERVER_MRVL)_DEPENDS += $(SAISERVER) $(DOCKER_SAISERVER_MRVL)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_MRVL) +SONIC_STRETCH_DOCKERS += $(DOCKER_SAISERVER_MRVL) $(DOCKER_SAISERVER_MRVL)_CONTAINER_NAME = saiserver $(DOCKER_SAISERVER_MRVL)_RUN_OPT += --net=host --privileged -t diff --git a/platform/marvell-armhf/docker-saiserver-mrvl.mk b/platform/marvell-armhf/docker-saiserver-mrvl.mk index 398902961da8..8720e3364688 100644 --- a/platform/marvell-armhf/docker-saiserver-mrvl.mk +++ b/platform/marvell-armhf/docker-saiserver-mrvl.mk @@ -6,6 +6,7 @@ $(DOCKER_SAISERVER_MRVL)_DEPENDS += $(SAISERVER) $(DOCKER_SAISERVER_MRVL)_FILES += $(DSSERVE) $(BCMCMD) $(DOCKER_SAISERVER_MRVL)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_MRVL) +SONIC_STRETCH_DOCKERS += $(DOCKER_SAISERVER_MRVL) $(DOCKER_SAISERVER_MRVL)_CONTAINER_NAME = saiserver $(DOCKER_SAISERVER_MRVL)_RUN_OPT += --net=host --privileged -t diff --git a/platform/mellanox/docker-saiserver-mlnx.mk b/platform/mellanox/docker-saiserver-mlnx.mk index d91756a1f239..6515fa9846b1 100644 --- a/platform/mellanox/docker-saiserver-mlnx.mk +++ b/platform/mellanox/docker-saiserver-mlnx.mk @@ -6,6 +6,7 @@ $(DOCKER_SAISERVER_MLNX)_DEPENDS += $(SAISERVER) $(PYTHON_SDK_API) $(DOCKER_SAISERVER_MLNX)_PYTHON_DEBS += $(MLNX_SFPD) $(DOCKER_SAISERVER_MLNX)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_MLNX) +SONIC_STRETCH_DOCKERS += $(DOCKER_SAISERVER_MLNX) $(DOCKER_SAISERVER_MLNX)_CONTAINER_NAME = saiserver $(DOCKER_SAISERVER_MLNX)_RUN_OPT += --net=host --privileged -t From 2db87669c2e6b58b49dc86f8a11fadfe4a222435 Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Wed, 6 May 2020 14:58:02 -0700 Subject: [PATCH 0627/1427] [bgp]: align the bgp templates with new minigraph for multi NPU platforms (#4488) - change the references to 'type' field to 'sub_role' - change the references to 'InternalFrontend' and 'InternalBackend' to 'FrontEnd' and 'BackEnd' respectively - add a statement to reflect route-reflector for backend asics - add a change to set "next-hop-self force" configuration for internal BGP session in multi asic platform. Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 4 ++-- .../frr/bgpd/templates/general/instance.conf.j2 | 7 +++++-- .../frr/bgpd/templates/general/peer-group.conf.j2 | 6 ++++++ .../frr/bgpd/templates/general/policies.conf.j2 | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index 4a4f06b0d0f2..a29569191651 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -14,7 +14,7 @@ ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTE {% endif %} ! ! -{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} +{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %} route-map HIDE_INTERNAL permit 10 set community local-AS ! @@ -62,7 +62,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endblock vlan_advertisement %} ! ! -{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} +{% if DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} redistribute connected route-map HIDE_INTERNAL {% endif %} ! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 index 7abeabba0a77..148cfa390e01 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 @@ -16,13 +16,13 @@ {% if neighbor_addr | ipv4 %} address-family ipv4 neighbor {{ neighbor_addr }} peer-group PEER_V4 -{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V4_INT in {% endif %} {% elif neighbor_addr | ipv6 %} address-family ipv6 neighbor {{ neighbor_addr }} peer-group PEER_V6 -{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V6_INT in {% endif %} {% endif %} @@ -34,6 +34,9 @@ {% if bgp_session['nhopself'] | int != 0 %} neighbor {{ neighbor_addr }} next-hop-self {% endif %} +{% if 'ASIC' in bgp_session['name'] %} + neighbor {{ neighbor_addr }} next-hop-self force +{% endif %} ! {% if bgp_session["asn"] == bgp_asn and CONFIG_DB__DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} address-family l2vpn evpn diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 index 551274902de8..8c02eeacbdb4 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -6,6 +6,9 @@ address-family ipv4 {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V4 allowas-in 1 +{% endif %} +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor PEER_V4 route-reflector-client {% endif %} neighbor PEER_V4 soft-reconfiguration inbound neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in @@ -14,6 +17,9 @@ address-family ipv6 {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V6 allowas-in 1 + {% endif %} +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor PEER_V6 route-reflector-client {% endif %} neighbor PEER_V6 soft-reconfiguration inbound neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 index 0c7b17c207bc..c545cf272892 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -15,7 +15,7 @@ route-map FROM_BGP_PEER_V6 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! -{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} route-map FROM_BGP_PEER_V4_INT permit 2 set originator-id {{ loopback0_ipv4 | ip }} ! From 340cf826a6fa7dd750eaa3f2731675fe9af803e2 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 6 May 2020 15:41:28 -0700 Subject: [PATCH 0628/1427] [MultiDB] use sonic-db-cli PING and fix wrong multiDB API in NAT (#4541) --- dockers/docker-database/Dockerfile.j2 | 1 - dockers/docker-database/ping_pong_db_insts | 40 ------------------- dockers/docker-nat/restore_nat_entries.py | 3 +- files/build_templates/docker_image_ctl.j2 | 6 ++- .../warmboot-finalizer/finalize-warmboot.sh | 4 +- files/scripts/configdb-load.sh | 2 +- files/scripts/swss.sh | 5 ++- files/scripts/syncd.sh | 5 ++- 8 files changed, 18 insertions(+), 48 deletions(-) delete mode 100755 dockers/docker-database/ping_pong_db_insts diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index 8cd181614672..5dc644ae573f 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -34,7 +34,6 @@ RUN apt-get clean -y && \ COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["docker-database-init.sh", "/usr/local/bin/"] -COPY ["ping_pong_db_insts", "/usr/local/bin/"] COPY ["database_config.json", "/etc/default/sonic-db/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] diff --git a/dockers/docker-database/ping_pong_db_insts b/dockers/docker-database/ping_pong_db_insts deleted file mode 100755 index 484d4da0cfb0..000000000000 --- a/dockers/docker-database/ping_pong_db_insts +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/python -import json -import os -import subprocess -import time -import syslog - -def ping_redis(cmd): - output = '' - while True: - try: - output = subprocess.check_output(cmd, shell=True) - except subprocess.CalledProcessError as e: - syslog.syslog(syslog.LOG_ERR, 'ping redis failed, cmd : {}'.format(cmd)) - - if 'PONG' in output: - break - syslog.syslog(syslog.LOG_ERR, 'ping response : {}'.format(output)) - time.sleep(1) - -database_config_file = "/var/run/redis/sonic-db/database_config.json" - -data = {} -while True: - if os.path.isfile(database_config_file): - with open(database_config_file, "r") as read_file: - data = json.load(read_file) - break - time.sleep(1) - syslog.syslog(syslog.LOG_ERR, 'config file {} does not exist right now'.format(database_config_file)) - -while True: - if 'INSTANCES' in data: - for inst in data["INSTANCES"]: - port = data["INSTANCES"][inst]["port"] - cmd = "redis-cli -p " + str(port) + " ping" - ping_redis(cmd) - break - time.sleep(1) - syslog.syslog(syslog.LOG_ERR, 'config file {} does not have INSTANCES'.format(database_config_file)) diff --git a/dockers/docker-nat/restore_nat_entries.py b/dockers/docker-nat/restore_nat_entries.py index 9fb62e82f573..d07facab290b 100755 --- a/dockers/docker-nat/restore_nat_entries.py +++ b/dockers/docker-nat/restore_nat_entries.py @@ -24,7 +24,6 @@ IP_PROTO_TCP = '6' MATCH_CONNTRACK_ENTRY = '^(\w+)\s+(\d+).*src=([\d.]+)\s+dst=([\d.]+)\s+sport=(\d+)\s+dport=(\d+).*src=([\d.]+)\s+dst=([\d.]+)\s+sport=(\d+)\s+dport=(\d+)' -REDIS_SOCK = "/var/run/redis/redis.sock" logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) @@ -44,7 +43,7 @@ def add_nat_conntrack_entry_in_kernel(ipproto, srcip, dstip, srcport, dstport, n # Set the statedb "NAT_RESTORE_TABLE|Flags", so natsyncd can start reconciliation def set_statedb_nat_restore_done(): - statedb = swsscommon.DBConnector(swsscommon.STATE_DB, REDIS_SOCK, 0) + statedb = swsscommon.DBConnector("STATE_DB", 0) tbl = swsscommon.Table(statedb, "NAT_RESTORE_TABLE") fvs = swsscommon.FieldValuePairs([("restored", "true")]) tbl.set("Flags", fvs) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index c48d72ea1f47..d071cbe93cb4 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -78,7 +78,11 @@ function postStartAction() link_namespace $DEV fi # Wait until redis starts - /usr/bin/docker exec database$DEV ping_pong_db_insts + # TODO: should use $SONIC_DB_CLI if Judy's PR 4477 is in first, otherwise PR 4477 should change this part + until [[ $(/usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli PING | grep -c PONG) -gt 0 ]]; do + sleep 1; + done + if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index 0f9e0f7da299..01ad921137b6 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -29,7 +29,9 @@ function wait_for_database_service() debug "Wait for database to become ready..." # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + until [[ $(sonic-db-cli PING | grep -c PONG) -gt 0 ]]; do + sleep 1; + done # Wait for configDB initialization until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; diff --git a/files/scripts/configdb-load.sh b/files/scripts/configdb-load.sh index b1bf761371bf..fde2de5c6f2b 100755 --- a/files/scripts/configdb-load.sh +++ b/files/scripts/configdb-load.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Wait until redis starts -until [[ $(redis-cli ping | grep -c PONG) -gt 0 ]]; do +until [[ $(sonic-db-cli PING | grep -c PONG) -gt 0 ]]; do sleep 1; done diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 360e331f3636..df0debf21d99 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -51,7 +51,10 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database$DEV ping_pong_db_insts + # TODO: should use $SONIC_DB_CLI if Judy's PR 4477 is in first, otherwise PR 4477 should change this part + until [[ $(/usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli PING | grep -c PONG) -gt 0 ]]; do + sleep 1; + done # Wait for configDB initialization until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 9847cfec9406..04a6f5d52826 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -39,7 +39,10 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database$DEV ping_pong_db_insts + # TODO: should use $SONIC_DB_CLI if Judy's PR 4477 is in first, otherwise PR 4477 should change this part + until [[ $(/usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli PING | grep -c PONG) -gt 0 ]]; do + sleep 1; + done # Wait for configDB initialization until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; From 3ae5945cfcdcda5aaf770ef13a24f45341134056 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Wed, 6 May 2020 15:43:29 -0700 Subject: [PATCH 0629/1427] [minigraph] Add tags for egress mirror tables (#4526) Signed-off-by: Danny Allen --- src/sonic-config-engine/minigraph.py | 4 ++-- src/sonic-config-engine/tests/t0-sample-graph.xml | 5 +++++ src/sonic-config-engine/tests/test_cfggen.py | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 8ff4944c5d13..960520cedd6c 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -380,8 +380,8 @@ def parse_dpg(dpg, hname): # Give a warning if trying to attach ACL to a LAG member interface, correct way is to attach ACL to the LAG interface if port_alias_map[member] in intfs_inpc: print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a LAG member interface " + port_alias_map[member] + ", instead of LAG interface" - elif member.lower().startswith('erspan'): - if member.lower().startswith('erspanv6'): + elif member.lower().startswith('erspan') or member.lower().startswith('egress_erspan'): + if member.lower().startswith('erspanv6') or member.lower().startswith('egress_erspanv6'): is_mirror_v6 = True else: is_mirror = True diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index 47985f870e50..ce12435b4039 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -303,6 +303,11 @@ everflowV6 Everflow
+ + EGRESS_ERSPAN + everflow_egress + Everflow + PortChannel01;PortChannel02;PortChannel03;PortChannel04 DataAclIngress diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 07769e0bf613..2570aa7386b0 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -111,6 +111,7 @@ def test_minigraph_acl(self): "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" "{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, " "'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW'}, " + "'EVERFLOW_EGRESS': {'stage': 'egress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW_EGRESS'}, " "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT', 'stage': 'ingress'}, " "'DATAACLINGRESS': {'stage': 'ingress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04'], 'policy_desc': 'DATAACLINGRESS'}, " "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL', 'stage': 'ingress'}, " From fc28af7ce9fbee9008414d0b49b3805e44a52bbf Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 6 May 2020 19:30:31 -0700 Subject: [PATCH 0630/1427] [bgpcfgd]: Fix for BGP peer not coming up even after config BGP startup all (#4547) Issue was key not correct to look into self.peer. It need to be tuple of (vrf,nbr). Updated for both add/del --- dockers/docker-fpm-frr/bgpcfgd | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index be290dfc41cc..adc142c109d2 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -744,7 +744,8 @@ class BGPPeerMgrBase(Manager): :param data: the data associated with the change """ vrf, nbr = self.split_key(key) - if key not in self.peers: + peer_key = (vrf, nbr) + if peer_key not in self.peers: return self.add_peer(vrf, nbr, data) else: return self.update_peer(vrf, nbr, data) @@ -871,7 +872,8 @@ class BGPPeerMgrBase(Manager): :param key: key of the neighbor """ vrf, nbr = self.split_key(key) - if key not in self.peers: + peer_key = (vrf, nbr) + if peer_key not in self.peers: log_warn("Peer '(%s|%s)' has not been found" % (vrf, nbr)) return cmd = self.templates["delete"].render(neighbor_addr=nbr) From bed4a799df347ee82684235bf31158f26f5cc07c Mon Sep 17 00:00:00 2001 From: wangshengjun Date: Thu, 7 May 2020 11:03:09 +0800 Subject: [PATCH 0631/1427] [ebtables]add the filter rule for ARP packets with vlan tag: (#3945) 1. ebtables -t filter -A FORWARD -p 802_1Q --vlan-encap 0806 -j DROP The ARP packet with vlan tag can't match the default rule. Signed-off-by: wangshengjun --- files/image_config/ebtables/ebtables.filter | Bin 616 -> 840 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/files/image_config/ebtables/ebtables.filter b/files/image_config/ebtables/ebtables.filter index 4faad1f5f4bdbe57c1bb0378a4b959e209067ed9..dfe55672769d11ab45ac86336eb0db9bf5050126 100644 GIT binary patch literal 840 zcmYex%qdANVqo}@t1thio&f{!0Y#XBcmWea%FRD0JYZA9p5>to3=L5Fz!nG}rs_Ws zfb@Yd2so^Q$iwu3#60~1LPJ0dAW%!(0JfhI!iAF{b6^~hy^cXHFfN!j;(>7Of%-u# zn7zUfVL0i7!+aB{{urn{TmzJ03YCX&85<4(86Z1At||bsL3jZW7ndaFr6d-m0GU_; z2UPSQSSJGm%%2==5D9&OOA6S+--H(;?~6m;6e literal 616 zcmYex%qdANVql2SJ|?SE&wv5=fFevle1Q=nRcO3Y9;B||+^xtpp$rTQptQgR2)_<0 z4^=5pDpuHd# zNIl5C!VqCNc@WKAFbQ+0e(m&=V1L2f4U;$IfU!U{W5XdJ39+0V%G?Js#y>O!6hUCn QhQ)qRI731Lq6Qxc07O|=rvLx| From dfdd94d8ad6235019239a4d9469a04bdaf63068a Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 6 May 2020 22:48:33 -0700 Subject: [PATCH 0632/1427] [process-reboot-cause] If software reboot cause is unknown add note if first boot into new image (#4538) --- .../process-reboot-cause/process-reboot-cause | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause index 409deb7d6859..c9d57fd77b0a 100755 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -12,6 +12,8 @@ try: import sys import syslog import re + + import sonic_device_util except ImportError as err: raise ImportError("%s - required module not found" % str(err)) @@ -34,7 +36,7 @@ REBOOT_TYPE_KEXEC_FILE = "/proc/cmdline" REBOOT_TYPE_KEXEC_PATTERN_WARM = ".*SONIC_BOOT_TYPE=(warm|fastfast).*" REBOOT_TYPE_KEXEC_PATTERN_FAST = ".*SONIC_BOOT_TYPE=(fast|fast-reboot).*" -UNKNOWN_REBOOT_CAUSE = "Unknown" +REBOOT_CAUSE_UNKNOWN = "Unknown" # ========================== Syslog wrappers ========================== @@ -72,7 +74,7 @@ def parse_warmfast_reboot_from_proc_cmdline(): def find_software_reboot_cause(): - software_reboot_cause = UNKNOWN_REBOOT_CAUSE + software_reboot_cause = REBOOT_CAUSE_UNKNOWN if os.path.isfile(REBOOT_CAUSE_FILE): with open(REBOOT_CAUSE_FILE, "r") as cause_file: @@ -82,6 +84,10 @@ def find_software_reboot_cause(): log_info("Reboot cause file {} not found".format(REBOOT_CAUSE_FILE)) if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): + if software_reboot_cause == REBOOT_CAUSE_UNKNOWN: + version_info = sonic_device_util.get_sonic_version_info() + build_version = version_info['build_version'] if version_info else "unknown" + software_reboot_cause += " (First boot of SONiC version {})".format(build_version) os.remove(FIRST_BOOT_PLATFORM_FILE) return software_reboot_cause @@ -148,7 +154,7 @@ def main(): os.remove(PREVIOUS_REBOOT_CAUSE_FILE) # Set a default previous reboot cause - previous_reboot_cause = UNKNOWN_REBOOT_CAUSE + previous_reboot_cause = REBOOT_CAUSE_UNKNOWN # 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline proc_cmdline_reboot_cause = find_proc_cmdline_reboot_cause() @@ -188,7 +194,7 @@ def main(): # Write a new default reboot cause file for the next reboot with open(REBOOT_CAUSE_FILE, "w") as cause_file: - cause_file.write(UNKNOWN_REBOOT_CAUSE) + cause_file.write(REBOOT_CAUSE_UNKNOWN) if __name__ == "__main__": From d9210d7ace0da1ec75edfe8f04298306ef011876 Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Thu, 7 May 2020 16:15:13 +0300 Subject: [PATCH 0633/1427] [Mellanox] Fix SN3420 'sensors.conf' label names (#4544) Signed-off-by: Shlomi Bitton --- .../mellanox/x86_64-mlnx_msn3420-r0/sensors.conf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf index 5718ff99518b..4519b4841700 100644 --- a/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf @@ -22,8 +22,8 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "tps53679-i2c-*-70" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 PSU 12V Rail (in)" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" label in3 "PMIC-1 COMEX 1.8V Rail (out)" label in4 "PMIC-1 COMEX 1.05V Rail (out)" label temp1 "PMIC-1 Temp 1" @@ -33,8 +33,8 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-1 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-1 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-71" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 PSU 12V Rail (in)" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" label in3 "PMIC-2 COMEX 1.8V Rail (out)" label in4 "PMIC-2 COMEX 1.05V Rail (out)" label temp1 "PMIC-2 Temp 1" @@ -46,8 +46,8 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 PSU 12V Rail (in)" + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" label in3 "PMIC-3 COMEX 1.8V Rail (out)" label in4 "PMIC-3 COMEX 1.05V Rail (out)" label temp1 "PMIC-3 Temp 1" @@ -57,8 +57,8 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-3 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-3 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 PSU 12V Rail (in)" + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" label in3 "PMIC-4 COMEX 1.8V Rail (out)" label in4 "PMIC-4 COMEX 1.05V Rail (out)" label temp1 "PMIC-4 Temp 1" From 404ae85e2cd2e8421327b2a953c3d4dc1e9bf3fc Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Thu, 7 May 2020 16:19:51 +0300 Subject: [PATCH 0634/1427] [Mellanox] Fix 'sensors.conf' mapping for MSN4700 (#4511) * [Mellanox] Fix 'sensors.conf' mapping for SN4700 Signed-off-by: Shlomi Bitton * Fix some labels name --- .../x86_64-mlnx_msn4700-r0/sensors.conf | 170 +++++++++++------- 1 file changed, 103 insertions(+), 67 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf index b4eaf76f2ec0..067287f3bbef 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf @@ -21,83 +21,118 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" - chip "tps53679-i2c-*-62" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail (out)" - ignore in3 + chip "xdpe12284-i2c-*-62" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-1 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" - label power1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Pwr (out)" - ignore power2 - label curr1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (out)" - ignore curr2 - chip "tps53679-i2c-*-64" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 ASIC 1.8V MAIN Rail (out)" - compute in2 (1.5)*@, @/(1.5) - label in3 "PMIC-2 ASIC 1.2V MAIN Rail (out)" + label power1 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-1 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-1 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-1 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-1 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-64" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-2 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" - label power1 "PMIC-2 ASIC 1.8V MAIN Rail Pwr (out)" - label power2 "PMIC-2 ASIC 1.2V MAIN Rail Pwr (out)" - label curr1 "PMIC-2 ASIC 1.8V MAIN Rail Curr (out)" - label curr2 "PMIC-2 ASIC 1.2V MAIN Rail Curr (out)" - chip "tps53679-i2c-*-66" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail (out)" - label in3 "PMIC-3 ASIC 1.8V T0_1 Rail (out)" + label power1 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-2 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-2 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-2 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-2 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-66" + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-3 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" - label power1 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail Pwr (out)" - label power2 "PMIC-3 ASIC 1.8V T0_1 Rail Pwr (out)" - label curr1 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail Curr (out)" - label curr2 "PMIC-3 ASIC 1.8V T0_1 Rail Curr (out)" - chip "tps53679-i2c-*-68" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail (out)" - label in3 "PMIC-4 ASIC 1.8V T2_3 Rail (out)" + label power1 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-3 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-3 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-3 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-3 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-68" + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-4 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" - label power1 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail Pwr (out)" - label power2 "PMIC-4 ASIC 1.8V T2_3 Rail Pwr (out)" - label curr1 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail Curr (out)" - label curr2 "PMIC-4 ASIC 1.8V T2_3 Rail Curr (out)" - chip "tps53679-i2c-*-6a" - label in1 "PMIC-5 PSU 12V Rail (in)" - label in2 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail (out)" - label in3 "PMIC-5 ASIC 1.8V T4_5 Rail (out)" + label power1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-4 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-4 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-6a" + label in1 "PMIC-5 PSU 12V Rail (in1)" + label in2 "PMIC-5 PSU 12V Rail (in2)" + label in3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-5 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-5 Temp 1" label temp2 "PMIC-5 Temp 2" - label power1 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail Pwr (out)" - label power2 "PMIC-5 ASIC 1.8V T4_5 Rail Pwr (out)" - label curr1 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail Curr (out)" - label curr2 "PMIC-5 ASIC 1.8V T4_5 Rail Curr (out)" - chip "tps53679-i2c-*-6c" - label in1 "PMIC-6 PSU 12V Rail (in)" - label in2 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail (out)" - label in3 "PMIC-6 ASIC 1.8V T6_7 Rail (out)" + label power1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-5 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-5 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-6c" + label in1 "PMIC-6 PSU 12V Rail (in1)" + label in2 "PMIC-6 PSU 12V Rail (in2)" + label in3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-6 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-6 Temp 1" label temp2 "PMIC-6 Temp 2" - label power1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power2 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr2 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (out)" - chip "tps53679-i2c-*-6e" - label in1 "PMIC-7 PSU 12V Rail (in)" - label in2 "PMIC-7 ASIC 1.2V T0_3 Rail (out)" - label in3 "PMIC-7 ASIC 1.2V T4_7 Rail (out)" + label power1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-6e" + label in1 "PMIC-7 PSU 12V Rail (in1)" + label in2 "PMIC-7 PSU 12V Rail (in2)" + label in3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-7 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-7 Temp 1" label temp2 "PMIC-7 Temp 2" - label power1 "PMIC-7 ASIC 1.2V T0_3 Rail Pwr (out)" - label power2 "PMIC-7 ASIC 1.2V T4_7 Rail Pwr (out)" - label curr1 "PMIC-7 ASIC 1.2V T0_3 Rail Curr (out)" - label curr2 "PMIC-7 ASIC 1.2V T4_7 Rail Curr (out)" + label power1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (out)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-8 PSU 12V Rail (in)" - label in2 "PMIC-8 COMEX 1.8V Rail (out)" - label in3 "PMIC-8 COMEX 1.05V Rail (out)" + label in1 "PMIC-8 PSU 12V Rail (in1)" + label in2 "PMIC-8 PSU 12V Rail (in2)" + label in3 "PMIC-8 COMEX 1.8V Rail (out)" + label in4 "PMIC-8 COMEX 1.05V Rail (out)" label temp1 "PMIC-8 Temp 1" label temp2 "PMIC-8 Temp 2" label power1 "PMIC-8 COMEX 1.8V Rail Pwr (out)" @@ -105,15 +140,16 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-8 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-8 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-9 PSU 12V Rail (in)" - label in2 "PMIC-9 COMEX 1.2V Rail (out)" - ignore in3 + label in1 "PMIC-9 PSU 12V Rail (in1)" + label in2 "PMIC-9 PSU 12V Rail (in2)" + label in3 "PMIC-9 COMEX 1.8V Rail (out)" + label in4 "PMIC-9 COMEX 1.05V Rail (out)" label temp1 "PMIC-9 Temp 1" label temp2 "PMIC-9 Temp 2" - label power1 "PMIC-9 COMEX 1.2V Rail Pwr (out)" - ignore power2 - label curr1 "PMIC-9 COMEX 1.2V Rail Curr (out)" - ignore curr2 + label power1 "PMIC-9 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-9 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-9 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-9 COMEX 1.05V Rail Curr (out)" # Power supplies bus "i2c-4" "i2c-1-mux (chan_id 3)" From 1cdcb2c62dc74664726e6ad2047116dcaaa05d03 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Fri, 8 May 2020 03:35:48 +0800 Subject: [PATCH 0635/1427] [Mellanox] Add patch to disable hw-management thermal control shell script (#4550) * [Mellanox] Add patch to disable hw-management thermal control shell script * Remove SimX patch since https://github.com/Azure/sonic-buildimage/pull/4364/files has already handle it --- ...agement-thermal-control-shell-script.patch | 28 ++++++++++ .../0001-Make-hw-mgmt-SimX-compatiable.patch | 53 ------------------- 2 files changed, 28 insertions(+), 53 deletions(-) create mode 100644 platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch delete mode 100644 platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch diff --git a/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch b/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch new file mode 100644 index 000000000000..eef970ed23c7 --- /dev/null +++ b/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch @@ -0,0 +1,28 @@ +From 3bce9e33132a86c0a53a7b0a49ee1932d65bfb7f Mon Sep 17 00:00:00 2001 +From: junchao +Date: Wed, 6 May 2020 11:37:56 +0800 +Subject: [PATCH] Disable hw-management thermal control shell script + +--- + usr/usr/bin/hw-management.sh | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh +index 65e5d39..cffff7a 100755 +--- a/usr/usr/bin/hw-management.sh ++++ b/usr/usr/bin/hw-management.sh +@@ -832,7 +832,10 @@ do_start() + if [ -f $config_path/max_tachos ]; then + max_tachos=$(<$config_path/max_tachos) + fi +- $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& ++ ++ # Disable thermal control shell script in hw-management ++ # because there has already been that in SONiC ++ # $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& + } + + do_stop() +-- +1.9.1 + diff --git a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch deleted file mode 100644 index ccbd6322d2e6..000000000000 --- a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 6aecc8fed8cc78c1fb5c6b52bdfa3d07ca66e652 Mon Sep 17 00:00:00 2001 -From: Mykola Faryma -Date: Fri, 21 Feb 2020 12:28:54 +0200 -Subject: [PATCH 1/1] Make hw-mgmt SimX compatiable - -Signed-off-by: Mykola Faryma ---- - usr/usr/bin/hw-management.sh | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh -index cff10fe..7f3c295 100755 ---- a/usr/usr/bin/hw-management.sh -+++ b/usr/usr/bin/hw-management.sh -@@ -737,6 +737,35 @@ do_chip_down() - /usr/bin/hw-management-thermal-events.sh change hotplug_asic down %S %p - } - -+handle_simx() -+{ -+ local -r onie_platform="$(cat /host/machine.conf | grep onie_platform | cut -d= -f2)" -+ -+ local -r syseeprom_cache_path="/var/cache/sonic/decode-syseeprom/syseeprom_cache" -+ local -r syseeprom_hex_path="/usr/share/sonic/device/${onie_platform}/syseeprom.hex" -+ local -r syseeprom_vpd_path="/var/run/hw-management/eeprom/vpd_info" -+ -+ case $ACTION in -+ start) -+ /bin/bash -c "/bin/rm -f ${syseeprom_cache_path}" -+ /bin/bash -c "/bin/mkdir -p ${eeprom_path}" -+ /bin/bash -c "/usr/bin/xxd -r -p ${syseeprom_hex_path} ${syseeprom_vpd_path}" -+ ;; -+ stop) -+ /bin/bash -c "/bin/rm -fr ${hw_management_path}" -+ ;; -+ *) -+ echo "Usage: `basename $0` {start|stop}" -+ exit 1 -+ ;; -+ esac -+} -+ -+if [[ "$(cat /sys/devices/virtual/dmi/id/sys_vendor)" = "QEMU" ]]; then -+ handle_simx -+ exit 0 -+fi -+ - case $ACTION in - start) - if [ -d /var/run/hw-management ]; then --- -1.9.1 - From 7f14acbf030d836c0b4f02901e659ad830cad8d0 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Thu, 7 May 2020 23:17:22 -0700 Subject: [PATCH 0636/1427] [minigraph.py]: Fix undefined variable error. (#4555) Signed-off-by: SuvarnaMeenakshi --- src/sonic-config-engine/minigraph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 960520cedd6c..f5c311571ed2 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -748,7 +748,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): - (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, device_hostname) + (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): From 86627dfd350ab4f69597b9cd09b34a659983185b Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni <47657796+AkhileshSamineni@users.noreply.github.com> Date: Fri, 8 May 2020 12:31:48 +0530 Subject: [PATCH 0637/1427] [NAT] : Removed requires dependency on swss (#4551) Signed-off-by: Akhilesh Samineni --- files/build_templates/nat.service.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/nat.service.j2 b/files/build_templates/nat.service.j2 index 79a56f67ca89..4a0e20efaee8 100644 --- a/files/build_templates/nat.service.j2 +++ b/files/build_templates/nat.service.j2 @@ -1,6 +1,6 @@ [Unit] Description=NAT container -Requires=updategraph.service swss.service +Requires=updategraph.service After=updategraph.service swss.service syncd.service Before=ntp-config.service StartLimitIntervalSec=1200 From d0099ed43eb88af27e1e8c83f124c6746b976241 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 8 May 2020 19:47:05 -0700 Subject: [PATCH 0638/1427] [minigraph] Support FECDisabled in minigraph parser (#4556) Signed-off-by: Qi Luo --- src/sonic-config-engine/minigraph.py | 54 +++++++++++++++++-- .../tests/t0-sample-graph.xml | 31 ++++++++++- src/sonic-config-engine/tests/test_cfggen.py | 15 ++++-- 3 files changed, 90 insertions(+), 10 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index f5c311571ed2..45397215d003 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -35,7 +35,7 @@ VLAN_SUB_INTERFACE_SEPARATOR = '.' VLAN_SUB_INTERFACE_VLAN_ID = '10' -# Default Virtual Network Index (VNI) +# Default Virtual Network Index (VNI) vni_default = 8000 ############################################################################### @@ -539,6 +539,39 @@ def parse_meta(meta, hname): region = value return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region + +def parse_linkmeta(meta, hname): + link = meta.find(str(QName(ns, "Link"))) + linkmetas = {} + for linkmeta in link.findall(str(QName(ns1, "LinkMetadata"))): + port = None + fec_disabled = None + + # Sample: ARISTA05T1:Ethernet1/33;switch-t0:fortyGigE0/4 + key = linkmeta.find(str(QName(ns1, "Key"))).text + endpoints = key.split(';') + for endpoint in endpoints: + t = endpoint.split(':') + if len(t) == 2 and t[0].lower() == hname.lower(): + port = t[1] + break + else: + # Cannot find a matching hname, something went wrong + continue + + properties = linkmeta.find(str(QName(ns1, "Properties"))) + for device_property in properties.findall(str(QName(ns1, "DeviceProperty"))): + name = device_property.find(str(QName(ns1, "Name"))).text + value = device_property.find(str(QName(ns1, "Value"))).text + if name == "FECDisabled": + fec_disabled = value + + linkmetas[port] = {} + if fec_disabled: + linkmetas[port]["FECDisabled"] = fec_disabled + return linkmetas + + def parse_asic_meta(meta, hname): sub_role = None device_metas = meta.find(str(QName(ns, "Devices"))) @@ -683,7 +716,6 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): generate asic specific configuration. """ root = ET.parse(filename).getroot() - mini_graph_path = filename u_neighbors = None u_devices = None @@ -717,8 +749,9 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): deployment_id = None region = None hostname = None + linkmetas = {} - #hostname is the asic_name, get the asic_id from the asic_name + # hostname is the asic_name, get the asic_id from the asic_name if asic_name is not None: asic_id = get_npu_id_from_name(asic_name) else: @@ -751,6 +784,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname) + elif child.tag == str(QName(ns, "LinkMetadataDeclaration")): + linkmetas = parse_linkmeta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) else: @@ -762,6 +797,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): (neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): (sub_role) = parse_asic_meta(child, asic_name) + elif child.tag == str(QName(ns, "LinkMetadataDeclaration")): + linkmetas = parse_linkmeta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) @@ -848,7 +885,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): for port_name in port_speed_png: # not consider port not in port_config.ini - #If no port_config_file is found ports is empty so ignore this error + # If no port_config_file is found ports is empty so ignore this error if port_config_file is not None: if port_name not in ports: print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name @@ -857,7 +894,14 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name] for port_name, port in ports.items(): - if port.get('speed') == '100000': + # get port alias from port_config.ini + if port_config_file: + alias = port.get('alias') + else: + alias = port_name + # generate default 100G FEC + # Note: FECDisabled only be effective on 100G port right now + if port.get('speed') == '100000' and linkmetas.get(alias, {}).get('FECDisabled', '').lower() != 'true': port['fec'] = 'rs' # set port description if parsed from deviceinfo diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index ce12435b4039..5e4a68db0e87 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -381,13 +381,14 @@ Ethernet1/1 switch-t0 fortyGigE0/124 + 100000 DeviceInterfaceLink true - 10000 + 100000 switch-t0 - fortyGigE0/2 + fortyGigE0/4 true ARISTA05T1 Ethernet1/33 @@ -439,6 +440,32 @@ + + + + + + + FECDisabled + + True + + + ARISTA05T1:Ethernet1/33;switch-t0:fortyGigE0/4 + + + + + + FECDisabled + + True + + + ARISTA06T1:Ethernet1/34;switch-t0:fortyGigE0/8 + + + switch-t0 Force10-S6000 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 2570aa7386b0..816575f84171 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -107,8 +107,6 @@ def test_minigraph_acl(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE' output = self.run_script(argument, True) self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n" - "Warning: ignore interface 'fortyGigE0/2' as it is not in the port_config.ini\n" - "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" "{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, " "'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW'}, " "'EVERFLOW_EGRESS': {'stage': 'egress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW_EGRESS'}, " @@ -191,7 +189,18 @@ def test_minigraph_extra_neighbors(self): def test_minigraph_port_description(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'description': 'ARISTA04T1:Ethernet1/1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up'}") + self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") + + def test_minigraph_port_fec_disabled(self): + # Test for FECDisabled + argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet4\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'lanes': '25,26,27,28', 'description': 'Servers0:eth0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '100000'}") + + def test_minigraph_port_rs(self): + argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") def test_minigraph_bgp(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "BGP_NEIGHBOR[\'10.0.0.59\']"' From acf465b43bec3ad663e885fde3b3c1e7f33745aa Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Fri, 8 May 2020 21:24:05 -0700 Subject: [PATCH 0639/1427] =?UTF-8?q?Multi=20DB=20with=20namespace=20suppo?= =?UTF-8?q?rt,=20Introducing=20the=20database=5Fglobal.json=E2=80=A6=20(#4?= =?UTF-8?q?477)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Multi DB with namespace support, Introducing the database_global.json file for supporting accessing DB's in other namespaces for service running in linux host * Updates based on comments * Adding the j2 templates for database_config and database_global files. * Updating to retrieve the redis DIR's to be mounted from database_global.json file. * Additional check to see if asic.conf file exists before sourcing it. * Updates based on PR comments discussion. * Review comments update * Updates to the argument "-n" for namespace used in both context of parsing minigraph and multi DB access. * Update with the attribute "persistence_for_warm_boot" that was added to database_config.json file earlier. * Removing the database_config.json file to avioid confusion in future. We use the database_config.json.j2 file to generate database_config.json files dynamically. * Update the comments for sudo usage in docker_image_ctrl.j2 * Update with the new logic in PING PONG tests using sonic-db-cli. With this we wait till the PONG response is received when redis server is up. * Similar changes in swss and syncd scripts for the PING tests with sonic-db-cli * Updated with a missing , in the database_config.json.j2 file, Do pip install of j2cli in docker-base-buster. --- dockers/docker-base-buster/Dockerfile.j2 | 4 + dockers/docker-base-stretch/Dockerfile.j2 | 4 + dockers/docker-database/Dockerfile.j2 | 3 +- ...se_config.json => database_config.json.j2} | 2 +- .../docker-database/database_global.json.j2 | 21 ++++ .../docker-database/docker-database-init.sh | 21 +++- files/build_templates/docker_image_ctl.j2 | 99 ++++++++++++++++--- files/scripts/swss.sh | 28 +++--- files/scripts/syncd.sh | 16 +-- src/sonic-config-engine/sonic-cfggen | 20 +++- 10 files changed, 174 insertions(+), 44 deletions(-) rename dockers/docker-database/{database_config.json => database_config.json.j2} (94%) create mode 100644 dockers/docker-database/database_global.json.j2 diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index de78845c62b3..35016faf89a2 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -44,6 +44,7 @@ RUN apt-get update && \ perl \ procps \ python \ + python-pip \ rsyslog \ vim-tiny \ # Install dependencies of supervisor @@ -66,6 +67,9 @@ RUN apt-get -y install \ iproute2 \ net-tools +# For templating +RUN pip install j2cli + RUN mkdir -p /etc/supervisor /var/log/supervisor RUN apt-get -y purge \ diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 17047d13a839..a65413164db8 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -44,6 +44,7 @@ RUN apt-get update && \ perl \ procps \ python \ + python-pip \ rsyslog \ vim-tiny \ # Install dependencies of supervisor @@ -66,6 +67,9 @@ RUN apt-get -y install \ iproute2 \ net-tools +# For templating +RUN pip install j2cli + RUN mkdir -p /etc/supervisor /var/log/supervisor RUN apt-get -y purge \ diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index 5dc644ae573f..bea4f17f2afc 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -34,7 +34,8 @@ RUN apt-get clean -y && \ COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["docker-database-init.sh", "/usr/local/bin/"] -COPY ["database_config.json", "/etc/default/sonic-db/"] +COPY ["database_config.json.j2", "/usr/share/sonic/templates/"] +COPY ["database_global.json.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] diff --git a/dockers/docker-database/database_config.json b/dockers/docker-database/database_config.json.j2 similarity index 94% rename from dockers/docker-database/database_config.json rename to dockers/docker-database/database_config.json.j2 index c62bf746acba..3383ec161144 100644 --- a/dockers/docker-database/database_config.json +++ b/dockers/docker-database/database_config.json.j2 @@ -3,7 +3,7 @@ "redis":{ "hostname" : "127.0.0.1", "port" : 6379, - "unix_socket_path" : "/var/run/redis/redis.sock", + "unix_socket_path" : "/var/run/redis{{NAMESPACE_ID}}/redis.sock", "persistence_for_warm_boot" : "yes" } }, diff --git a/dockers/docker-database/database_global.json.j2 b/dockers/docker-database/database_global.json.j2 new file mode 100644 index 000000000000..777bce43b324 --- /dev/null +++ b/dockers/docker-database/database_global.json.j2 @@ -0,0 +1,21 @@ +{% set namespace_cnt = NAMESPACE_COUNT|int %} +{ + "INCLUDES" : [ + { + "include" : "../../redis/sonic-db/database_config.json" + }, +{% if namespace_cnt > 1 %} +{% for ns in range(namespace_cnt) %} + { + "namespace" : "{{NAMESPACE_PREFIX}}{{ns}}", + "include" : "../../redis{{ns}}/sonic-db/database_config.json" +{% if ns == namespace_cnt-1 %} + } +{% else %} + }, +{% endif %} +{% endfor %} + ], + "VERSION" : "1.0" +} +{% endif %} diff --git a/dockers/docker-database/docker-database-init.sh b/dockers/docker-database/docker-database-init.sh index ebdcc6abb694..5dae34d8f616 100755 --- a/dockers/docker-database/docker-database-init.sh +++ b/dockers/docker-database/docker-database-init.sh @@ -1,13 +1,26 @@ #!/usr/bin/env bash -mkdir -p /var/run/redis/sonic-db -if [ -f /etc/sonic/database_config.json ]; then - cp /etc/sonic/database_config.json /var/run/redis/sonic-db +REDIS_DIR=/var/run/redis$NAMESPACE_ID +mkdir -p $REDIS_DIR/sonic-db + +if [ -f /etc/sonic/database_config$NAMESPACE_ID.json ]; then + cp /etc/sonic/database_config$NAMESPACE_ID.json $REDIS_DIR/sonic-db/database_config.json else - cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db + j2 /usr/share/sonic/templates/database_config.json.j2 > $REDIS_DIR/sonic-db/database_config.json fi mkdir -p /etc/supervisor/conf.d/ + +# copy/generate the database_global.json file if this is global database service in multi asic platform. +if [[ $NAMESPACE_ID == "" ]] && [[ $NAMESPACE_COUNT -gt 1 ]] +then + if [ -f /etc/sonic/database_global.json ]; then + cp /etc/sonic/database_global.json $REDIS_DIR/sonic-db/database_global.json + else + j2 /usr/share/sonic/templates/database_global.json.j2 > $REDIS_DIR/sonic-db/database_global.json + fi +fi + # generate all redis server supervisord configuration file sonic-cfggen -j /var/run/redis/sonic-db/database_config.json -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index d071cbe93cb4..90a234c009eb 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -64,7 +64,7 @@ function preStartAction() docker cp /tmp/dump.rdb database$DEV:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + $SONIC_DB_CLI STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) {%- else %} : # nothing {%- endif %} @@ -77,9 +77,9 @@ function postStartAction() docker exec -i database$DEV sysctl -w net.ipv6.conf.all.disable_ipv6=0 link_namespace $DEV fi + # Wait until redis starts - # TODO: should use $SONIC_DB_CLI if Judy's PR 4477 is in first, otherwise PR 4477 should change this part - until [[ $(/usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli PING | grep -c PONG) -gt 0 ]]; do + until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do sleep 1; done @@ -89,23 +89,25 @@ function postStartAction() # If there is a config_db.json dump file, load it. if [ -r /etc/sonic/config_db$DEV.json ]; then if [ -r /etc/sonic/init_cfg.json ]; then - sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db$DEV.json --write-to-db + $SONIC_CFGGEN -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db$DEV.json --write-to-db else - sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/config_db$DEV.json --write-to-db + $SONIC_CFGGEN -j /etc/sonic/config_db$DEV.json --write-to-db fi fi if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" + $SONIC_DB_CLI STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" fi - /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + $SONIC_DB_CLI CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then # Migrate the DB to the latest schema version if needed - /usr/bin/db_migrator.py -o migrate + if [ -z "$DEV" ]; then + /usr/bin/db_migrator.py -o migrate + fi fi {%- elif docker_container_name == "swss" %} docker exec swss$DEV rm -f /ready # remove cruft @@ -137,14 +139,20 @@ start() { BOOT_TYPE=`getBootType` # Obtain our platform as we will mount directories with these names in each docker - PLATFORM=`sonic-netns-exec "$NET_NS" sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PLATFORM=`$SONIC_CFGGEN -H -v DEVICE_METADATA.localhost.platform` + + # Parse the device specific asic conf file, if it exists + ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf + if [ -f "$ASIC_CONF" ]; then + source $ASIC_CONF + fi {%- if docker_container_name == "database" %} # Don't mount HWSKU in {{docker_container_name}} container. HWSKU="" {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker - HWSKU=`sonic-netns-exec "$NET_NS" sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + HWSKU=`$SONIC_CFGGEN -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` {%- endif %} DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` @@ -173,18 +181,64 @@ start() { {%- if docker_container_name == "database" %} echo "Creating new {{docker_container_name}}$DEV container" + if [ -z "$DEV" ]; then + # if database_global exists in old_config, use it; otherwise use the default one in new image + if [ -f /etc/sonic/old_config/database_global.json ]; then + echo "Use database_global.json from old system..." + mv /etc/sonic/old_config/database_global.json /etc/sonic/ + fi + fi # if database_config exists in old_config, use it; otherwise use the default one in new image - if [ -f /etc/sonic/old_config/database_config.json ]; then + if [ -f /etc/sonic/old_config/database_config$DEV.json ]; then echo "Use database_config.json from old system..." - mv /etc/sonic/old_config/database_config.json /etc/sonic/ + mv /etc/sonic/old_config/database_config$DEV.json /etc/sonic/ fi {%- else %} echo "Creating new {{docker_container_name}}$DEV container with HWSKU $HWSKU" {%- endif %} + # In Multi ASIC platforms the global database config file database_global.json will exist. + # Parse the file and get the include path for the database_config.json files used in + # various namesapces. The database_config paths are relative to the DIR of SONIC_DB_GLOBAL_JSON. + SONIC_DB_GLOBAL_JSON="/var/run/redis/sonic-db/database_global.json" + if [ -f "$SONIC_DB_GLOBAL_JSON" ]; then + # TODO Create a separate python script with the below logic and invoke it here. + redis_dir_list=`/usr/bin/python -c "import sys; import os; import json; f=open(sys.argv[1]); \ + global_db_dir = os.path.dirname(sys.argv[1]); data=json.load(f); \ + print(\" \".join([os.path.normpath(global_db_dir+'/'+elem['include']).partition('sonic-db')[0]\ + for elem in data['INCLUDES'] if 'namespace' in elem])); f.close()" $SONIC_DB_GLOBAL_JSON` + fi + if [ -z "$DEV" ]; then NET="host" + + # For Multi-ASIC platform we have to mount the redis paths for database instances running in different + # namespaces, into the single instance dockers like snmp, pmon on linux host. These global dockers + # will need to get/set tables from databases in different namespaces. + # /var/run/redis0 ---> mounted as --> /var/run/redis0 + # /var/run/redis1 ---> mounted as --> /var/run/redis1 .. etc + # The below logic extracts the base DIR's where database_config.json's for various namespaces exist. + # redis_dir_list is a string of form "/var/run/redis0/ /var/run/redis1/ /var/run/redis2/" + + {%- if docker_container_name != "database" %} + if [ -n "$redis_dir_list" ]; then + for redis_dir in $redis_dir_list + do + REDIS_MNT=$REDIS_MNT" -v $redis_dir:$redis_dir:rw " + done + fi + {%- endif %} else + # This part of code is applicable for Multi-ASIC platforms. Here we mount the namespace specific + # redis directory into the docker running in that namespace. Below eg: is for namespace "asic1" + # /var/run/redis1 ---> mounted as --> /var/run/redis1 + # redis_dir_list is a string of form "/var/run/redis0/ /var/run/redis1/ /var/run/redis2/" + if [ -n "$redis_dir_list" ]; then + id=`expr $DEV + 1` + redis_dir=`echo $redis_dir_list | cut -d " " -f $id` + REDIS_MNT=" -v $redis_dir:$redis_dir:rw " + fi + {%- if docker_container_name == "database" %} NET="bridge" {%- else %} @@ -232,6 +286,7 @@ start() { -v /etc/sonic/frr/$DEV:/etc/frr:rw \ {%- endif %} -v /var/run/redis$DEV:/var/run/redis:rw \ + $REDIS_MNT \ -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ {%- if docker_container_name != "database" %} -v /usr/share/sonic/device/$PLATFORM/$HWSKU/$DEV:/usr/share/sonic/hwsku:ro \ @@ -240,6 +295,11 @@ start() { --tmpfs /tmp \ {%- endif %} --tmpfs /var/tmp \ +{%- if docker_container_name == "database" %} + --env "NAMESPACE_ID"="$DEV" \ + --env "NAMESPACE_PREFIX"="$NAMESPACE_PREFIX" \ + --env "NAMESPACE_COUNT"=$NUM_ASIC \ +{%- endif %} --name={{docker_container_name}}$DEV {{docker_image_name}}:latest || { echo "Failed to docker run" >&1 exit 4 @@ -265,10 +325,21 @@ stop() { OP=$1 DEV=$2 # namespace/device number to operate on +NAMESPACE_PREFIX="asic" if [ "$DEV" ]; then - NET_NS="asic$DEV" #name of the network namespace -else + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + + # While using -n (namespace) argument, sonic-cfggen/sonic-db-cli uses redis UNIX socket + # for accessing redis DB in a namespace. This unix socket has permission restrictions since + # it is created by systemd database.servce started with [User] as [root]. + # sudo is needed here for services which are started by systemd with [User] as [admin] + # and needs to override this unix socket permission restrictions. + SONIC_CFGGEN="sudo sonic-cfggen -n $NET_NS" + SONIC_DB_CLI="sudo sonic-db-cli -n $NET_NS" + else NET_NS="" + SONIC_CFGGEN="sonic-cfggen" + SONIC_DB_CLI="sonic-db-cli" fi case "$1" in diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index df0debf21d99..74828c740fe1 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -28,8 +28,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -40,7 +40,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -51,13 +51,12 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - # TODO: should use $SONIC_DB_CLI if Judy's PR 4477 is in first, otherwise PR 4477 should change this part - until [[ $(/usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli PING | grep -c PONG) -gt 0 ]]; do + until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do sleep 1; done # Wait for configDB initialization - until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $($SONIC_DB_CLI CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -67,7 +66,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - sonic-netns-exec "$NET_NS" sonic-db-cli $1 EVAL " + $SONIC_DB_CLI $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -135,10 +134,10 @@ start() { # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - sonic-netns-exec "$NET_NS" sonic-db-cli APPL_DB FLUSHDB - sonic-netns-exec "$NET_NS" sonic-db-cli ASIC_DB FLUSHDB - sonic-netns-exec "$NET_NS" sonic-db-cli COUNTERS_DB FLUSHDB - sonic-netns-exec "$NET_NS" sonic-db-cli FLEX_COUNTER_DB FLUSHDB + $SONIC_DB_CLI APPL_DB FLUSHDB + $SONIC_DB_CLI ASIC_DB FLUSHDB + $SONIC_DB_CLI COUNTERS_DB FLUSHDB + $SONIC_DB_CLI FLEX_COUNTER_DB FLUSHDB clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi @@ -209,10 +208,13 @@ SERVICE="swss" PEER="syncd" DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" LOCKFILE="/tmp/swss-syncd-lock$DEV" +NAMESPACE_PREFIX="asic" if [ "$DEV" ]; then - NET_NS="asic$DEV" #name of the network namespace + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" else - NET_NS="" + NET_NS="" + SONIC_DB_CLI="sonic-db-cli" fi case "$1" in diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 04a6f5d52826..4ebc35d379ed 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -26,8 +26,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -39,13 +39,12 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - # TODO: should use $SONIC_DB_CLI if Judy's PR 4477 is in first, otherwise PR 4477 should change this part - until [[ $(/usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli PING | grep -c PONG) -gt 0 ]]; do + until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do sleep 1; done # Wait for configDB initialization - until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $($SONIC_DB_CLI CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -62,7 +61,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' @@ -198,10 +197,13 @@ SERVICE="syncd" PEER="swss" DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" LOCKFILE="/tmp/swss-syncd-lock$DEV" +NAMESPACE_PREFIX="asic" if [ "$DEV" ]; then - NET_NS="asic$DEV" #name of the network namespace + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" else NET_NS="" + SONIC_DB_CLI="sonic-db-cli" fi case "$1" in diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index d8936a83f72c..c247d85abec3 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -45,7 +45,7 @@ from sonic_device_util import get_system_mac from sonic_device_util import get_npu_id_from_name from config_samples import generate_sample_config from config_samples import get_available_config -from swsssdk import SonicV2Connector, ConfigDBConnector +from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig from redis_bcc import RedisBytecodeCache from collections import OrderedDict from natsort import natsorted @@ -197,7 +197,7 @@ def main(): group.add_argument("-m", "--minigraph", help="minigraph xml file", nargs='?', const='/etc/sonic/minigraph.xml') group.add_argument("-M", "--device-description", help="device description xml file") group.add_argument("-k", "--hwsku", help="HwSKU") - parser.add_argument("-n", "--namespace", help="namespace name, used with -m or -k", nargs='?', const=None) + parser.add_argument("-n", "--namespace", help="namespace name", nargs='?', const=None, default=None) parser.add_argument("-p", "--port-config", help="port config file, used with -m or -k", nargs='?', const=None) parser.add_argument("-y", "--yaml", help="yaml file that contains additional variables", action='append', default=[]) parser.add_argument("-j", "--json", help="json file that contains additional variables", action='append', default=[]) @@ -231,6 +231,10 @@ def main(): asic_id = get_npu_id_from_name(asic_name) + # Load the database config for the namespace from global database json + if args.namespace is not None: + SonicDBConfig.load_sonic_global_db_config(namespace=args.namespace) + if hwsku is not None: hardware_data = {'DEVICE_METADATA': {'localhost': { 'hwsku': hwsku @@ -271,7 +275,11 @@ def main(): deep_update(data, json.loads(args.additional_data)) if args.from_db: - configdb = ConfigDBConnector(**db_kwargs) + if args.namespace is None: + configdb = ConfigDBConnector(**db_kwargs) + else: + configdb = ConfigDBConnector(use_unix_socket_path=True, namespace=args.namespace, **db_kwargs) + configdb.connect() deep_update(data, FormatConverter.db_to_output(configdb.get_config())) @@ -331,7 +339,11 @@ def main(): print(json.dumps(FormatConverter.to_serialized(data[args.var_json]), indent=4, cls=minigraph_encoder)) if args.write_to_db: - configdb = ConfigDBConnector(**db_kwargs) + if args.namespace is None: + configdb = ConfigDBConnector(**db_kwargs) + else: + configdb = ConfigDBConnector(use_unix_socket_path=True, namespace=args.namespace, **db_kwargs) + configdb.connect(False) configdb.mod_config(FormatConverter.output_to_db(data)) From 286aa35ac6342c7e1fe7acb8c90f0b46b917fef9 Mon Sep 17 00:00:00 2001 From: Neetha John Date: Sat, 9 May 2020 11:21:18 -0700 Subject: [PATCH 0640/1427] [qos]: Alpha and ECN settings change for Th (#4564) Dynamic threshold setting changed to 0 and WRED profile green min threshold set to 250000 for Tomahawk devices Changed the dynamic threshold settings in pg_profile_lookup.ini Added a macro for WRED profiles in qos.json.j2 for Tomahawk devices Necessary changes made in qos.config.j2 to use the macro if present Signed-off-by: Neetha John --- .../pg_profile_lookup.ini | 30 +- .../Arista-7060CX-32S-C32/qos.json.j2 | 20 + .../pg_profile_lookup.ini | 30 +- .../Arista-7060CX-32S-D48C8/qos.json.j2 | 20 + .../pg_profile_lookup.ini | 30 +- .../Arista-7060CX-32S-Q32/qos.json.j2 | 20 + .../Celestica-DX010-C32/pg_profile_lookup.ini | 30 +- .../Celestica-DX010-C32/qos.json.j2 | 20 + .../pg_profile_lookup.ini | 30 +- .../Celestica-DX010-D48C8/qos.json.j2 | 20 + .../Force10-S6100/pg_profile_lookup.ini | 30 +- .../Force10-S6100/qos.json.j2 | 20 + files/build_templates/qos_config.j2 | 4 + .../tests/sample-arista-7050-t0-minigraph.xml | 907 ++++++++++++++++ .../tests/sample_output/qos-arista7050.json | 977 ++++++++++++++++++ .../tests/sample_output/qos-dell6100.json | 2 +- src/sonic-config-engine/tests/test_j2files.py | 20 + 17 files changed, 2119 insertions(+), 91 deletions(-) create mode 100644 src/sonic-config-engine/tests/sample-arista-7050-t0-minigraph.xml create mode 100644 src/sonic-config-engine/tests/sample_output/qos-arista7050.json diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini index aedda37a8878..673df369a9bb 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 90272 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 53248 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 96096 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 90272 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 53248 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 96096 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini index dc05d0a100a3..0b5d680edda7 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 79872 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 56160 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 85696 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 79872 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 56160 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 85696 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini index aedda37a8878..673df369a9bb 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 90272 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 53248 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 96096 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 90272 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 53248 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 96096 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/pg_profile_lookup.ini b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/pg_profile_lookup.ini index aedda37a8878..673df369a9bb 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/pg_profile_lookup.ini +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 90272 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 53248 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 96096 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 90272 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 53248 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 96096 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/qos.json.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/qos.json.j2 +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/pg_profile_lookup.ini b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/pg_profile_lookup.ini index aedda37a8878..673df369a9bb 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/pg_profile_lookup.ini +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 90272 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 53248 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 96096 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 90272 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 53248 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 96096 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/qos.json.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/qos.json.j2 +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini index dc05d0a100a3..0b5d680edda7 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 79872 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 56160 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 85696 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 79872 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 56160 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 85696 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/files/build_templates/qos_config.j2 b/files/build_templates/qos_config.j2 index 2a9a5be8d83c..9420be7a0671 100644 --- a/files/build_templates/qos_config.j2 +++ b/files/build_templates/qos_config.j2 @@ -193,6 +193,9 @@ {% endfor %} }, +{% if generate_wred_profiles is defined %} + {{- generate_wred_profiles() }} +{% else %} "WRED_PROFILE": { "AZURE_LOSSLESS" : { "wred_green_enable" : "true", @@ -210,6 +213,7 @@ "red_drop_probability" : "5" } }, +{% endif %} "QUEUE": { {% for port in PORT_ACTIVE %} "{{ port }}|3": { diff --git a/src/sonic-config-engine/tests/sample-arista-7050-t0-minigraph.xml b/src/sonic-config-engine/tests/sample-arista-7050-t0-minigraph.xml new file mode 100644 index 000000000000..4fd1ba9ba128 --- /dev/null +++ b/src/sonic-config-engine/tests/sample-arista-7050-t0-minigraph.xml @@ -0,0 +1,907 @@ + + + + + + s7050-dev-1 + 10.0.0.56 + ARISTA01T1 + 10.0.0.57 + 1 + 10 + 3 + + + s7050-dev-1 + FC00::71 + ARISTA01T1 + FC00::72 + 1 + 10 + 3 + + + s7050-dev-1 + 10.0.0.58 + ARISTA02T1 + 10.0.0.59 + 1 + 10 + 3 + + + s7050-dev-1 + FC00::75 + ARISTA02T1 + FC00::76 + 1 + 10 + 3 + + + s7050-dev-1 + 10.0.0.60 + ARISTA03T1 + 10.0.0.61 + 1 + 10 + 3 + + + s7050-dev-1 + FC00::79 + ARISTA03T1 + FC00::7A + 1 + 10 + 3 + + + s7050-dev-1 + 10.0.0.62 + ARISTA04T1 + 10.0.0.63 + 1 + 10 + 3 + + + s7050-dev-1 + FC00::7D + ARISTA04T1 + FC00::7E + 1 + 10 + 3 + + + + + 65100 + s7050-dev-1 + + +
10.0.0.57
+ + + +
+ +
10.0.0.59
+ + + +
+ +
10.0.0.61
+ + + +
+ +
10.0.0.63
+ + + +
+
+ +
+ + 64600 + ARISTA01T1 + + + + 64600 + ARISTA02T1 + + + + 64600 + ARISTA03T1 + + + + 64600 + ARISTA04T1 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + + + HostIP + eth0 + + 10.0.0.243/23 + + 10.0.0.243/23 + + + + + + s7050-dev-1 + + + PortChannel0001 + Ethernet33 + + + + PortChannel0002 + Ethernet34 + + + + PortChannel0003 + Ethernet35 + + + + PortChannel0004 + Ethernet36 + + + + + + Vlan1000 + Ethernet6/1;Ethernet7/1;Ethernet8/1;Ethernet9/1;Ethernet10/1;Ethernet11/1;Ethernet12/1;Ethernet13/1;Ethernet14/1;Ethernet15/1;Ethernet16/1;Ethernet17/1;Ethernet18/1;Ethernet19/1;Ethernet20/1;Ethernet21/1;Ethernet22/1;Ethernet23/1;Ethernet24/1;Ethernet25/1;Ethernet26/1;Ethernet27/1;Ethernet28/1;Ethernet29 + False + 0.0.0.0/0 + + 1000 + 1000 + 192.168.0.0/21 + + + + + + PortChannel0001 + 10.0.0.56/31 + + + + PortChannel0001 + FC00::71/126 + + + + PortChannel0002 + 10.0.0.58/31 + + + + PortChannel0002 + FC00::75/126 + + + + PortChannel0003 + 10.0.0.60/31 + + + + PortChannel0003 + FC00::79/126 + + + + PortChannel0004 + 10.0.0.62/31 + + + + PortChannel0004 + FC00::7D/126 + + + + Vlan1000 + 192.168.0.1/21 + + + + + + + + + + + + DeviceInterfaceLink + ARISTA01T1 + Ethernet1 + s7050-dev-1 + Ethernet33 + + + DeviceInterfaceLink + ARISTA02T1 + Ethernet1 + s7050-dev-1 + Ethernet34 + + + DeviceInterfaceLink + ARISTA03T1 + Ethernet1 + s7050-dev-1 + Ethernet35 + + + DeviceInterfaceLink + ARISTA04T1 + Ethernet1 + s7050-dev-1 + Ethernet36 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet6/1 + Servers0 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet7/1 + Servers1 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet8/1 + Servers2 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet9/1 + Servers3 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet10/1 + Servers4 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet11/1 + Servers5 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet12/1 + Servers6 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet13/1 + Servers7 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet14/1 + Servers8 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet15/1 + Servers9 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet16/1 + Servers10 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet17/1 + Servers11 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet18/1 + Servers12 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet19/1 + Servers13 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet20/1 + Servers14 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet21/1 + Servers15 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet22/1 + Servers16 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet23/1 + Servers17 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet24/1 + Servers18 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet25/1 + Servers19 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet26/1 + Servers20 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet27/1 + Servers21 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet28/1 + Servers22 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet29 + Servers23 + eth0 + + + + + s7050-dev-1 + Arista-7050-QX-32S + + 10.0.0.243 + + + + + + + true + + + DeviceInterface + + true + true + 1 + Ethernet5/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet6/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet7/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet8/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet9/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet10/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet11/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet12/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet13/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet14/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet15/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet16/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet17/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet18/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet19/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet20/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet21/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet22/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet23/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet24/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet25/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet26/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet27/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet28/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet29 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet30 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet31 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet32 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet33 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet34 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet35 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet36 + + false + 0 + 0 + 40000 + + + true + 0 + Arista-7050-QX-32S + + + + + + + s7050-dev-1 + + + ErspanDestinationIpv4 + + 10.0.0.16 + + + + + + + s7050-dev-1 + Arista-7050-QX-32S +
diff --git a/src/sonic-config-engine/tests/sample_output/qos-arista7050.json b/src/sonic-config-engine/tests/sample_output/qos-arista7050.json new file mode 100644 index 000000000000..aa05ef4ec36c --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/qos-arista7050.json @@ -0,0 +1,977 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0" : "1", + "1" : "1", + "2" : "1", + "3" : "3", + "4" : "4", + "5" : "2", + "6" : "1", + "7" : "1", + "8" : "0", + "9" : "1", + "10": "1", + "11": "1", + "12": "1", + "13": "1", + "14": "1", + "15": "1", + "16": "1", + "17": "1", + "18": "1", + "19": "1", + "20": "1", + "21": "1", + "22": "1", + "23": "1", + "24": "1", + "25": "1", + "26": "1", + "27": "1", + "28": "1", + "29": "1", + "30": "1", + "31": "1", + "32": "1", + "33": "1", + "34": "1", + "35": "1", + "36": "1", + "37": "1", + "38": "1", + "39": "1", + "40": "1", + "41": "1", + "42": "1", + "43": "1", + "44": "1", + "45": "1", + "46": "5", + "47": "1", + "48": "6", + "49": "1", + "50": "1", + "51": "1", + "52": "1", + "53": "1", + "54": "1", + "55": "1", + "56": "1", + "57": "1", + "58": "1", + "59": "1", + "60": "1", + "61": "1", + "62": "1", + "63": "1" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "14" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "15" + } + }, + "PORT_QOS_MAP": { + "Ethernet4": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet8": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet12": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet16": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet20": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet24": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet28": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet32": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet36": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet40": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet44": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet48": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet52": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet56": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet60": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet64": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet68": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet72": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet76": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet80": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet84": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet88": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet92": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet96": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet112": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet116": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet120": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet124": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "1048576", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, + "QUEUE": { + "Ethernet4|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet44|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet60|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet64|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet68|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet72|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet76|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet80|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet84|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet88|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet92|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet96|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet112|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet116|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet120|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet124|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet44|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet60|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet64|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet68|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet72|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet76|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet80|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet84|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet88|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet92|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet96|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet112|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet116|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet120|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet124|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/qos-dell6100.json b/src/sonic-config-engine/tests/sample_output/qos-dell6100.json index 680ca6232e11..75d9b3a87eee 100644 --- a/src/sonic-config-engine/tests/sample_output/qos-dell6100.json +++ b/src/sonic-config-engine/tests/sample_output/qos-dell6100.json @@ -430,7 +430,7 @@ "wred_red_enable" : "true", "ecn" : "ecn_all", "green_max_threshold" : "2097152", - "green_min_threshold" : "1048576", + "green_min_threshold" : "250000", "yellow_max_threshold" : "2097152", "yellow_min_threshold" : "1048576", "red_max_threshold" : "2097152", diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index c3585a41d44e..d4de26406cdc 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -18,6 +18,7 @@ def setUp(self): self.t1_mlnx_minigraph = os.path.join(self.test_dir, 't1-sample-graph-mlnx.xml') self.mlnx_port_config = os.path.join(self.test_dir, 'sample-port-config-mlnx.ini') self.dell6100_t0_minigraph = os.path.join(self.test_dir, 'sample-dell-6100-t0-minigraph.xml') + self.arista7050_t0_minigraph = os.path.join(self.test_dir, 'sample-arista-7050-t0-minigraph.xml') self.output_file = os.path.join(self.test_dir, 'output') def run_script(self, argument): @@ -93,6 +94,25 @@ def test_l2switch_template(self): self.assertTrue(filecmp.cmp(sample_output_file, self.output_file)) + def test_qos_arista7050_render_template(self): + arista_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'arista', 'x86_64-arista_7050_qx32s', 'Arista-7050-QX-32S') + qos_file = os.path.join(arista_dir_path, 'qos.json.j2') + port_config_ini_file = os.path.join(arista_dir_path, 'port_config.ini') + + # copy qos_config.j2 to the Arista 7050 directory to have all templates in one directory + qos_config_file = os.path.join(self.test_dir, '..', '..', '..', 'files', 'build_templates', 'qos_config.j2') + shutil.copy2(qos_config_file, arista_dir_path) + + argument = '-m ' + self.arista7050_t0_minigraph + ' -p ' + port_config_ini_file + ' -t ' + qos_file + ' > ' + self.output_file + self.run_script(argument) + + # cleanup + qos_config_file_new = os.path.join(arista_dir_path, 'qos_config.j2') + os.remove(qos_config_file_new) + + sample_output_file = os.path.join(self.test_dir, 'sample_output', 'qos-arista7050.json') + assert filecmp.cmp(sample_output_file, self.output_file) + def test_qos_dell6100_render_template(self): dell_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'dell', 'x86_64-dell_s6100_c2538-r0', 'Force10-S6100') qos_file = os.path.join(dell_dir_path, 'qos.json.j2') From cbe948e0870da8eb639cd46ea08be98d1af0fa82 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 11 May 2020 07:34:57 +0000 Subject: [PATCH 0641/1427] [build]: increase raw image disk size to 3GB Signed-off-by: Guohan Lu --- onie-image-arm64.conf | 4 ++-- onie-image-armhf.conf | 4 ++-- onie-image.conf | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/onie-image-arm64.conf b/onie-image-arm64.conf index 2bbadb3aeac4..0a800c43b322 100644 --- a/onie-image-arm64.conf +++ b/onie-image-arm64.conf @@ -18,7 +18,7 @@ FILESYSTEM_SQUASHFS=fs.squashfs ## Filename for onie installer payload, will be the main part of onie installer ONIE_INSTALLER_PAYLOAD=fs.zip -## Filename for docker file system +## Filename for docker file system FILESYSTEM_DOCKERFS=dockerfs.tar.gz ## docker directory on the root filesystem @@ -34,7 +34,7 @@ OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin OUTPUT_RAW_IMAGE=target/sonic-$TARGET_MACHINE.raw ## Raw image size in MB -RAW_IMAGE_DISK_SIZE=2048 +RAW_IMAGE_DISK_SIZE=3072 ## Output file name for kvm image OUTPUT_KVM_IMAGE=target/sonic-$TARGET_MACHINE.img diff --git a/onie-image-armhf.conf b/onie-image-armhf.conf index bbff03f64041..e396ce2298ec 100644 --- a/onie-image-armhf.conf +++ b/onie-image-armhf.conf @@ -18,7 +18,7 @@ FILESYSTEM_SQUASHFS=fs.squashfs ## Filename for onie installer payload, will be the main part of onie installer ONIE_INSTALLER_PAYLOAD=fs.zip -## Filename for docker file system +## Filename for docker file system FILESYSTEM_DOCKERFS=dockerfs.tar.gz ## docker directory on the root filesystem @@ -34,7 +34,7 @@ OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin OUTPUT_RAW_IMAGE=target/sonic-$TARGET_MACHINE.raw ## Raw image size in MB -RAW_IMAGE_DISK_SIZE=2048 +RAW_IMAGE_DISK_SIZE=3072 ## Output file name for kvm image OUTPUT_KVM_IMAGE=target/sonic-$TARGET_MACHINE.img diff --git a/onie-image.conf b/onie-image.conf index 2ca0a68484e2..830d6880ea8c 100644 --- a/onie-image.conf +++ b/onie-image.conf @@ -18,7 +18,7 @@ FILESYSTEM_SQUASHFS=fs.squashfs ## Filename for onie installer payload, will be the main part of onie installer ONIE_INSTALLER_PAYLOAD=fs.zip -## Filename for docker file system +## Filename for docker file system FILESYSTEM_DOCKERFS=dockerfs.tar.gz ## docker directory on the root filesystem @@ -34,7 +34,7 @@ OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin OUTPUT_RAW_IMAGE=target/sonic-$TARGET_MACHINE.raw ## Raw image size in MB -RAW_IMAGE_DISK_SIZE=2048 +RAW_IMAGE_DISK_SIZE=3072 ## Output file name for kvm image OUTPUT_KVM_IMAGE=target/sonic-$TARGET_MACHINE.img From a96f9ecee9eef00559beefa77fc32e4aaa111a1e Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 11 May 2020 11:05:44 -0700 Subject: [PATCH 0642/1427] Changes for LLDP docker to support multi-npu platforms (#4530) * Changes for LLDP for Multi NPU Platoforms:- a) Enable LLDP for Host namespace for Management Port b) Make sure Management IP is avaliable in per asic namespace needed for LLDP Chassis configuration c) Make sure chassis mac-address is correct in per asic namespace d) Do not run lldp on eth0 of per asic namespace and avoid chassis configuration for same e) Use Linux hostname instead from Device Metadata for lldp chassis configuration since in multi-npu platforms device metadata hostname will be differnt Signed-off-by: Abhishek Dosi * Address Review Comment with following changes: a) Use Device Metadata hostname even in per namespace conatiner. updated minigraph parsing for same to have hostname as system hostname and add new key for asic name b) Minigraph changes to have MGMT_INTERFACE Key in per asic/namespace config also as needed for LLDP for setting chassis management IP. Signed-off-by: Abhishek Dosi * Address Review Comments --- dockers/docker-lldp-sv2/Dockerfile.j2 | 5 ++-- dockers/docker-lldp-sv2/docker-lldp-init.sh | 5 ++++ .../{supervisord.conf => supervisord.conf.j2} | 4 ++++ files/build_templates/lldp.service.j2 | 1 + src/sonic-config-engine/minigraph.py | 24 ++++++++++++------- .../tests/test_multinpu_cfggen.py | 5 ++-- 6 files changed, 32 insertions(+), 12 deletions(-) create mode 100755 dockers/docker-lldp-sv2/docker-lldp-init.sh rename dockers/docker-lldp-sv2/{supervisord.conf => supervisord.conf.j2} (87%) create mode 120000 files/build_templates/lldp.service.j2 diff --git a/dockers/docker-lldp-sv2/Dockerfile.j2 b/dockers/docker-lldp-sv2/Dockerfile.j2 index 6a720514ef9b..af2b0373c373 100644 --- a/dockers/docker-lldp-sv2/Dockerfile.j2 +++ b/dockers/docker-lldp-sv2/Dockerfile.j2 @@ -35,12 +35,13 @@ RUN apt-get purge -y python-pip && \ /python-wheels \ ~/.cache +COPY ["docker-lldp-init.sh", "/usr/bin/"] COPY ["start.sh", "/usr/bin/"] -COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["lldpd.conf.j2", "/usr/share/sonic/templates/"] COPY ["lldpd", "/etc/default/"] COPY ["lldpmgrd", "/usr/bin/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/bin/docker-lldp-init.sh"] diff --git a/dockers/docker-lldp-sv2/docker-lldp-init.sh b/dockers/docker-lldp-sv2/docker-lldp-init.sh new file mode 100755 index 000000000000..ae507e8f506a --- /dev/null +++ b/dockers/docker-lldp-sv2/docker-lldp-init.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#Generate supervisord.conf based on device metadata +mkdir -p /etc/supervisor/conf.d/ +sonic-cfggen -d -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf +exec /usr/bin/supervisord diff --git a/dockers/docker-lldp-sv2/supervisord.conf b/dockers/docker-lldp-sv2/supervisord.conf.j2 similarity index 87% rename from dockers/docker-lldp-sv2/supervisord.conf rename to dockers/docker-lldp-sv2/supervisord.conf.j2 index 73ff52f4420e..beae3aa9425e 100644 --- a/dockers/docker-lldp-sv2/supervisord.conf +++ b/dockers/docker-lldp-sv2/supervisord.conf.j2 @@ -31,7 +31,11 @@ stderr_logfile=syslog # - `-dd` means to stay in foreground, log warnings to console # - `-ddd` means to stay in foreground, log warnings and info to console # - `-dddd` means to stay in foreground, log all to console +{% if DEVICE_METADATA['localhost']['sub_role'] is defined and DEVICE_METADATA['localhost']['sub_role']|length %} +command=/usr/sbin/lldpd -d -I Ethernet* -C Ethernet* +{% else %} command=/usr/sbin/lldpd -d -I Ethernet*,eth0 -C eth0 +{% endif %} priority=3 autostart=false autorestart=false diff --git a/files/build_templates/lldp.service.j2 b/files/build_templates/lldp.service.j2 new file mode 120000 index 000000000000..1adb318b9154 --- /dev/null +++ b/files/build_templates/lldp.service.j2 @@ -0,0 +1 @@ +per_namespace/lldp.service.j2 \ No newline at end of file diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 45397215d003..fb462dada594 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -248,14 +248,24 @@ def parse_asic_png(png, asic_name, hostname): return (neighbors, devices, port_speeds) def parse_dpg(dpg, hname): + aclintfs = None + mgmtintfs = None for child in dpg: - """In Multi-NPU platforms the acl intfs are defined only for the host not for individual asic. + """ + In Multi-NPU platforms the acl intfs are defined only for the host not for individual asic. There is just one aclintf node in the minigraph - Get the aclintfs node first. + Get the aclintfs node first. """ - if child.find(str(QName(ns, "AclInterfaces"))) is not None: + if aclintfs is None and child.find(str(QName(ns, "AclInterfaces"))) is not None: aclintfs = child.find(str(QName(ns, "AclInterfaces"))) - + """ + In Multi-NPU platforms the mgmt intfs are defined only for the host not for individual asic + There is just one mgmtintf node in the minigraph + Get the mgmtintfs node first. We need mgmt intf to get mgmt ip in per asic dockers. + """ + if mgmtintfs is None and child.find(str(QName(ns, "ManagementIPInterfaces"))) is not None: + mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) + hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue @@ -291,7 +301,6 @@ def parse_dpg(dpg, hname): mvrf_en_flag = mv.find(str(QName(ns, "mgmtVrfEnabled"))).text mvrf["vrf_global"] = {"mgmtVrfEnabled": mvrf_en_flag} - mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) mgmt_intf = {} for mgmtintf in mgmtintfs.findall(str(QName(ns1, "ManagementIPInterface"))): intfname = mgmtintf.find(str(QName(ns, "AttachTo"))).text @@ -804,10 +813,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): if asic_name is None: current_device = [devices[key] for key in devices if key.lower() == hostname.lower()][0] - name = hostname else: current_device = [devices[key] for key in devices if key.lower() == asic_name.lower()][0] - name = asic_name results = {} results['DEVICE_METADATA'] = {'localhost': { @@ -815,7 +822,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): 'deployment_id': deployment_id, 'region': region, 'docker_routing_config_mode': docker_routing_config_mode, - 'hostname': name, + 'hostname': hostname, 'hwsku': hwsku, 'type': current_device['type'] } @@ -825,6 +832,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): if sub_role is not None: current_device['sub_role'] = sub_role results['DEVICE_METADATA']['localhost']['sub_role'] = sub_role + results['DEVICE_METADATA']['localhost']['asic_name'] = asic_name results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 6facae0451db..4aefbb78fc61 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -116,7 +116,7 @@ def test_mgmt_port(self): self.assertDictEqual(output, {'eth0': {'alias': 'eth0', 'admin_status': 'up'}}) for asic in range(NUM_ASIC): output = json.loads(self.run_script_for_asic(argument, asic, self.port_config[asic])) - self.assertDictEqual(output, {}) + self.assertDictEqual(output, {'eth0': {'alias': 'eth0', 'admin_status': 'up'}}) def test_frontend_asic_portchannels(self): argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL\"".format(self.sample_graph, self.port_config[0]) @@ -213,7 +213,8 @@ def test_device_asic_metadata(self): for asic in range(NUM_ASIC): output = json.loads(self.run_script_for_asic(argument, asic,self.port_config[asic])) asic_name = "asic{}".format(asic) - self.assertEqual(output['localhost']['hostname'], asic_name) + self.assertEqual(output['localhost']['hostname'], 'multi_npu_platform_01') + self.assertEqual(output['localhost']['asic_name'], asic_name) self.assertEqual(output['localhost']['type'], 'Asic') if asic == 0 or asic == 1: self.assertEqual(output['localhost']['sub_role'], 'FrontEnd') From c95db04f120a0771266cba428a8407d06e338b96 Mon Sep 17 00:00:00 2001 From: paavaanan Date: Mon, 11 May 2020 23:36:53 +0530 Subject: [PATCH 0643/1427] DellEMC S6000 updated sensors.conf (#4568) Change PSU MAX temperature to 80 degree Change tmp75 sensors default temperature value from 25/50 to 70/80 degree. --- device/dell/x86_64-dell_s6000_s1220-r0/sensors.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/sensors.conf b/device/dell/x86_64-dell_s6000_s1220-r0/sensors.conf index c87af11afacc..f74a2b3d40ac 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/sensors.conf +++ b/device/dell/x86_64-dell_s6000_s1220-r0/sensors.conf @@ -7,8 +7,8 @@ # tmp75-i2c-11-4e is an ambient temperature sensor. chip "tmp75-*" - set temp1_max 50 - set temp1_max_hyst 25 + set temp1_max 80 + set temp1_max_hyst 70 # emc1403-i2c-10-4d has following temperature sensors: # temp1: CPU0 external Temp Sensor @@ -32,5 +32,5 @@ chip "jc42-*" set temp1_crit 85 chip "dni_dps460-*" - set temp1_max 50 - set temp2_max 50 + set temp1_max 80 + set temp2_max 80 From 5e8e0d76fc2a6426be889e834860552ae27f2bd2 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 11 May 2020 12:36:47 -0700 Subject: [PATCH 0644/1427] [caclmgrd] Add some default ACCEPT rules and lastly drop all incoming packets (#4412) Modified caclmgrd behavior to enhance control plane security as follows: Upon starting or receiving notification of ACL table/rule changes in Config DB: 1. Add iptables/ip6tables commands to allow all incoming packets from established TCP sessions or new TCP sessions which are related to established TCP sessions 2. Add iptables/ip6tables commands to allow bidirectional ICMPv4 ping and traceroute 3. Add iptables/ip6tables commands to allow bidirectional ICMPv6 ping and traceroute 4. Add iptables/ip6tables commands to allow all incoming Neighbor Discovery Protocol (NDP) NS/NA/RS/RA messages 5. Add iptables/ip6tables commands to allow all incoming IPv4 DHCP packets 6. Add iptables/ip6tables commands to allow all incoming IPv6 DHCP packets 7. Add iptables/ip6tables commands to allow all incoming BGP traffic 8. Add iptables/ip6tables commands for all ACL rules for recognized services (currently SSH, SNMP, NTP) 9. For all services which we did not find configured ACL rules, add iptables/ip6tables commands to allow all incoming packets for those services (allows the device to accept SSH connections before the device is configured) 10. Add iptables rules to drop all packets destined for loopback interface IP addresses 11. Add iptables rules to drop all packets destined for management interface IP addresses 12. Add iptables rules to drop all packets destined for point-to-point interface IP addresses 13. Add iptables rules to drop all packets destined for our VLAN interface gateway IP addresses 14. Add iptables/ip6tables commands to allow all incoming packets with TTL of 0 or 1 (This allows the device to respond to tools like tcptraceroute) 15. If we found control plane ACLs in the configuration and applied them, we lastly add iptables/ip6tables commands to drop all other incoming packets --- files/image_config/caclmgrd/caclmgrd | 152 +++++++++++++++++++++++++-- 1 file changed, 145 insertions(+), 7 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index e5744c7ca65b..16e8bda4f40b 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -11,7 +11,7 @@ # try: - import ipaddr as ipaddress + import ipaddress import os import subprocess import sys @@ -61,12 +61,21 @@ class ControlPlaneAclManager(object): ACL_TABLE_TYPE_CTRLPLANE = "CTRLPLANE" - # To specify a port range, use iptables format: separate start and end - # ports with a colon, e.g., "1000:2000" + # To specify a port range instead of a single port, use iptables format: + # separate start and end ports with a colon, e.g., "1000:2000" ACL_SERVICES = { - "NTP": {"ip_protocols": ["udp"], "dst_ports": ["123"]}, - "SNMP": {"ip_protocols": ["tcp", "udp"], "dst_ports": ["161"]}, - "SSH": {"ip_protocols": ["tcp"], "dst_ports": ["22"]} + "NTP": { + "ip_protocols": ["udp"], + "dst_ports": ["123"] + }, + "SNMP": { + "ip_protocols": ["tcp", "udp"], + "dst_ports": ["161"] + }, + "SSH": { + "ip_protocols": ["tcp"], + "dst_ports": ["22"] + } } def __init__(self): @@ -115,6 +124,78 @@ class ControlPlaneAclManager(object): tcp_flags_str = tcp_flags_str[:-1] return tcp_flags_str + def generate_block_ip2me_traffic_iptables_commands(self): + LOOPBACK_INTERFACE_TABLE_NAME = "LOOPBACK_INTERFACE" + MGMT_INTERFACE_TABLE_NAME = "MGMT_INTERFACE" + VLAN_INTERFACE_TABLE_NAME = "VLAN_INTERFACE" + PORTCHANNEL_INTERFACE_TABLE_NAME = "PORTCHANNEL_INTERFACE" + INTERFACE_TABLE_NAME = "INTERFACE" + + block_ip2me_cmds = [] + + # Add iptables rules to drop all packets destined for loopback interface IP addresses + loopback_iface_table = self.config_db.get_table(LOOPBACK_INTERFACE_TABLE_NAME) + if loopback_iface_table: + for ((iface_name, iface_cidr), _) in loopback_iface_table.iteritems(): + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + elif isinstance(ip_ntwrk, ipaddress.IPv6Network): + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + else: + log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + + # Add iptables rules to drop all packets destined for management interface IP addresses + mgmt_iface_table = self.config_db.get_table(MGMT_INTERFACE_TABLE_NAME) + if mgmt_iface_table: + for ((iface_name, iface_cidr), _) in mgmt_iface_table.iteritems(): + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + elif isinstance(ip_ntwrk, ipaddress.IPv6Network): + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + else: + log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + + # Add iptables rules to drop all packets destined for our VLAN interface gateway IP addresses + vlan_iface_table = self.config_db.get_table(VLAN_INTERFACE_TABLE_NAME) + if vlan_iface_table: + for ((iface_name, iface_cidr), _) in vlan_iface_table.iteritems(): + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(list(ip_ntwrk.hosts())[0], ip_ntwrk.max_prefixlen)) + elif isinstance(ip_ntwrk, ipaddress.IPv6Network): + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(list(ip_ntwrk.hosts())[0], ip_ntwrk.max_prefixlen)) + else: + log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + + # Add iptables rules to drop all packets destined for point-to-point interface IP addresses + # (All portchannel interfaces and configured front-panel interfaces) + portchannel_iface_table = self.config_db.get_table(PORTCHANNEL_INTERFACE_TABLE_NAME) + if portchannel_iface_table: + for ((iface_name, iface_cidr), _) in portchannel_iface_table.iteritems(): + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + elif isinstance(ip_ntwrk, ipaddress.IPv6Network): + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + else: + log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + + iface_table = self.config_db.get_table(INTERFACE_TABLE_NAME) + if iface_table: + for ((iface_name, iface_cidr), _) in iface_table.iteritems(): + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + elif isinstance(ip_ntwrk, ipaddress.IPv6Network): + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + else: + log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + + return block_ip2me_cmds + + def get_acl_rules_and_translate_to_iptables_commands(self): """ Retrieves current ACL tables and rules from Config DB, translates @@ -147,14 +228,54 @@ class ControlPlaneAclManager(object): iptables_cmds.append("ip6tables -F") iptables_cmds.append("ip6tables -X") - # Add iptables commands to allow all IPv4 and IPv6 traffic from localhost + # Add iptables/ip6tables commands to allow all traffic from localhost iptables_cmds.append("iptables -A INPUT -s 127.0.0.1 -i lo -j ACCEPT") iptables_cmds.append("ip6tables -A INPUT -s ::1 -i lo -j ACCEPT") + # Add iptables/ip6tables commands to allow all incoming packets from established + # TCP sessions or new TCP sessions which are related to established TCP sessions + iptables_cmds.append("iptables -A INPUT -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") + + # Add iptables/ip6tables commands to allow bidirectional ICMPv4 ping and traceroute + # TODO: Support processing ICMPv4 service ACL rules, and remove this blanket acceptance + iptables_cmds.append("iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT") + iptables_cmds.append("iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT") + + # Add iptables/ip6tables commands to allow bidirectional ICMPv6 ping and traceroute + # TODO: Support processing ICMPv6 service ACL rules, and remove this blanket acceptance + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-reply -j ACCEPT") + + # Add iptables/ip6tables commands to allow all incoming Neighbor Discovery Protocol (NDP) NS/NA/RS/RA messages + # TODO: Support processing NDP service ACL rules, and remove this blanket acceptance + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT") + + # Add iptables/ip6tables commands to allow all incoming IPv4 DHCP packets + iptables_cmds.append("iptables -A INPUT -p udp --dport 67:68 --sport 67:68 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p udp --dport 67:68 --sport 67:68 -j ACCEPT") + + # Add iptables/ip6tables commands to allow all incoming IPv6 DHCP packets + iptables_cmds.append("iptables -A INPUT -p udp --dport 546:547 --sport 546:547 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p udp --dport 546:547 --sport 546:547 -j ACCEPT") + + # Add iptables/ip6tables commands to allow all incoming BGP traffic + # TODO: Determine BGP ACLs based on configured device sessions, and remove this blanket acceptance + iptables_cmds.append("iptables -A INPUT -p tcp --dport 179 -j ACCEPT") + iptables_cmds.append("iptables -A INPUT -p tcp --sport 179 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p tcp --dport 179 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p tcp --sport 179 -j ACCEPT") + + # Get current ACL tables and rules from Config DB self._tables_db_info = self.config_db.get_table(self.ACL_TABLE) self._rules_db_info = self.config_db.get_table(self.ACL_RULE) + num_ctrl_plane_acl_rules = 0 + # Walk the ACL tables for (table_name, table_data) in self._tables_db_info.iteritems(): @@ -246,6 +367,23 @@ class ControlPlaneAclManager(object): rule_cmd += " -j {}".format(rule_props["PACKET_ACTION"]) iptables_cmds.append(rule_cmd) + num_ctrl_plane_acl_rules += 1 + + # Add iptables commands to block ip2me traffic + iptables_cmds += self.generate_block_ip2me_traffic_iptables_commands() + + # Add iptables/ip6tables commands to allow all incoming packets with TTL of 0 or 1 + # This allows the device to respond to tools like tcptraceroute + iptables_cmds.append("iptables -A INPUT -m ttl --ttl-lt 2 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p tcp -m hl --hl-lt 2 -j ACCEPT") + + # Finally, if the device has control plane ACLs configured, + # add iptables/ip6tables commands to drop all other incoming packets + if num_ctrl_plane_acl_rules > 0: + iptables_cmds.append("iptables -A INPUT -j DROP") + iptables_cmds.append("iptables -A FORWARD -j DROP") + iptables_cmds.append("ip6tables -A INPUT -j DROP") + iptables_cmds.append("ip6tables -A FORWARD -j DROP") return iptables_cmds From 61c304d00a8d82f605df79c60e641521707dbac4 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 12 May 2020 00:11:05 +0300 Subject: [PATCH 0645/1427] [mellanox]: Update SAI to 1.16.4, SDK to 4.4.0918, FW to *.2007.1140 (#4571) - mgmt buffer issue on 400G port - high CPU utilization issue caused by some counter reading --- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index c8f4b225857b..57cf8d6ecd06 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2007.1112 +MLNX_SPC_FW_VERSION = 13.2007.1140 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2007.1112 +MLNX_SPC2_FW_VERSION = 29.2007.1140 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2007.1112 +MLNX_SPC3_FW_VERSION = 30.2007.1140 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 65b0e47ae7fa..deff67e39968 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.3-master +MLNX_SAI_VERSION = SAIRel1.16.4-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 57b07cbbeea8..8cbb3aaaa2d3 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 57b07cbbeea8953c2df96cbd7f0d022691c9eaa5 +Subproject commit 8cbb3aaaa2d3ff3d5770d5d2452a0ebe32149206 diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 3160d980ff76..0115fcd6b6de 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 3160d980ff766addb459e1ff0f81778516eb55a0 +Subproject commit 0115fcd6b6dea3dd9faf957389885a7ed40b671d diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index c63c327cc40d..14d3f79e0a89 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.4.0914 +MLNX_SDK_VERSION = 4.4.0918 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 1066f238ba2a2ad80000bd8a233856dffc3352b2 Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 11 May 2020 23:17:47 -0700 Subject: [PATCH 0646/1427] [baseimage]: pin down package version for azure-storage, watchdog and futures (#4575) Signed-off-by: Guohan Lu --- files/build_templates/sonic_debian_extension.j2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 9ad2ba5eabae..3fa789ff60c9 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -250,9 +250,9 @@ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable core_uploader.service sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.py $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/corefile_uploader/core_analyzer.rc.json $FILESYSTEM_ROOT_ETC_SONIC/ sudo chmod og-rw $FILESYSTEM_ROOT_ETC_SONIC/core_analyzer.rc.json -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage==0.36.0 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog==0.10.2 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures==3.3.0 {% if install_kubernetes == "y" %} # Copy kubelet service files From 40ed75c2cb8f30139a2bd049cf9b17fdfb014e33 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Tue, 12 May 2020 09:21:05 +0300 Subject: [PATCH 0647/1427] [BFN] Updated Barefoot SDK to 2020-05-07 (#4566) Signed-off-by: Andriy Kokhan --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 1abbedffd6c6..d2bc97d1496c 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20200407_deb9.deb +BFN_PLATFORM = bfnplatform_20200507_deb9.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index b58cce6fcf47..d899779025df 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20200407_deb9.deb +BFN_SAI = bfnsdk_20200507_deb9.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) From 6889fd14acfecf6ca1b8e1c27160ea3306a97453 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Tue, 12 May 2020 09:23:34 +0300 Subject: [PATCH 0648/1427] [BFN] Fixed Barefoot platform image build. (#4565) - Updated bf_tun kernel driver; - Temporarily disabled WNC modules build; Signed-off-by: Andriy Kokhan --- .../barefoot/bfn-modules/modules/bf_tun.c | 1558 +++++++++++++---- platform/barefoot/one-image.mk | 2 +- platform/barefoot/rules.mk | 8 +- 3 files changed, 1261 insertions(+), 307 deletions(-) diff --git a/platform/barefoot/bfn-modules/modules/bf_tun.c b/platform/barefoot/bfn-modules/modules/bf_tun.c index 45913a681a9a..a20f5e4db585 100644 --- a/platform/barefoot/bfn-modules/modules/bf_tun.c +++ b/platform/barefoot/bfn-modules/modules/bf_tun.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -69,13 +70,21 @@ #include #include #include +#include #include #include #include +#include +#include +#include -#include +#include +#include -#define TUN_MINOR1 201 +#define BF_TUN_MINOR 201 + +static void tun_default_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *cmd); /* Uncomment to enable debugging */ /* #define TUN_DEBUG 1 */ @@ -106,6 +115,9 @@ do { \ } while (0) #endif +#define TUN_HEADROOM 256 +#define TUN_RX_PAD (NET_IP_ALIGN + NET_SKB_PAD) + /* TUN device flags */ /* IFF_ATTACH_QUEUE is never stored in device flags, @@ -117,7 +129,8 @@ do { \ #define TUN_VNET_BE 0x40000000 #define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \ - IFF_MULTI_QUEUE) + IFF_MULTI_QUEUE | IFF_NAPI | IFF_NAPI_FRAGS) + #define GOODCOPY_LEN 128 #define FLT_EXACT_COUNT 8 @@ -168,9 +181,14 @@ struct tun_file { u16 queue_index; unsigned int ifindex; }; + struct napi_struct napi; + bool napi_enabled; + bool napi_frags_enabled; + struct mutex napi_mutex; /* Protects access to the above napi */ struct list_head next; struct tun_struct *detached; - struct skb_array tx_array; + struct ptr_ring tx_ring; + struct xdp_rxq_info xdp_rxq; }; struct tun_flow_entry { @@ -185,6 +203,12 @@ struct tun_flow_entry { }; #define TUN_NUM_FLOW_ENTRIES 1024 +#define TUN_MASK_FLOW_ENTRIES (TUN_NUM_FLOW_ENTRIES - 1) + +struct tun_prog { + struct rcu_head rcu; + struct bpf_prog *prog; +}; /* Since the socket were moved to tun_file, to preserve the behavior of persist * device, socket filter, sndbuf and vnet header size were restore when the @@ -200,7 +224,7 @@ struct tun_struct { struct net_device *dev; netdev_features_t set_features; #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ - NETIF_F_TSO6|NETIF_F_UFO) + NETIF_F_TSO6) int align; int vnet_hdr_sz; @@ -220,9 +244,106 @@ struct tun_struct { struct list_head disabled; void *security; u32 flow_count; + u32 rx_batched; struct tun_pcpu_stats __percpu *pcpu_stats; + struct bpf_prog __rcu *xdp_prog; + struct tun_prog __rcu *steering_prog; + struct tun_prog __rcu *filter_prog; + struct ethtool_link_ksettings link_ksettings; }; +struct veth { + __be16 h_vlan_proto; + __be16 h_vlan_TCI; +}; + +bool tun_is_xdp_frame(void *ptr) +{ + return (unsigned long)ptr & TUN_XDP_FLAG; +} +EXPORT_SYMBOL(tun_is_xdp_frame); + +void *tun_xdp_to_ptr(void *ptr) +{ + return (void *)((unsigned long)ptr | TUN_XDP_FLAG); +} +EXPORT_SYMBOL(tun_xdp_to_ptr); + +void *tun_ptr_to_xdp(void *ptr) +{ + return (void *)((unsigned long)ptr & ~TUN_XDP_FLAG); +} +EXPORT_SYMBOL(tun_ptr_to_xdp); + +static int tun_napi_receive(struct napi_struct *napi, int budget) +{ + struct tun_file *tfile = container_of(napi, struct tun_file, napi); + struct sk_buff_head *queue = &tfile->sk.sk_write_queue; + struct sk_buff_head process_queue; + struct sk_buff *skb; + int received = 0; + + __skb_queue_head_init(&process_queue); + + spin_lock(&queue->lock); + skb_queue_splice_tail_init(queue, &process_queue); + spin_unlock(&queue->lock); + + while (received < budget && (skb = __skb_dequeue(&process_queue))) { + napi_gro_receive(napi, skb); + ++received; + } + + if (!skb_queue_empty(&process_queue)) { + spin_lock(&queue->lock); + skb_queue_splice(&process_queue, queue); + spin_unlock(&queue->lock); + } + + return received; +} + +static int tun_napi_poll(struct napi_struct *napi, int budget) +{ + unsigned int received; + + received = tun_napi_receive(napi, budget); + + if (received < budget) + napi_complete_done(napi, received); + + return received; +} + +static void tun_napi_init(struct tun_struct *tun, struct tun_file *tfile, + bool napi_en, bool napi_frags) +{ + tfile->napi_enabled = napi_en; + tfile->napi_frags_enabled = napi_en && napi_frags; + if (napi_en) { + netif_napi_add(tun->dev, &tfile->napi, tun_napi_poll, + NAPI_POLL_WEIGHT); + napi_enable(&tfile->napi); + } +} + +static void tun_napi_disable(struct tun_file *tfile) +{ + if (tfile->napi_enabled) + napi_disable(&tfile->napi); +} + +static void tun_napi_del(struct tun_file *tfile) +{ + if (tfile->napi_enabled) + netif_napi_del(&tfile->napi); +} + +static bool tun_napi_frags_enabled(const struct tun_file *tfile) +{ + return tfile->napi_frags_enabled; +} + #ifdef CONFIG_TUN_VNET_CROSS_LE static inline bool tun_legacy_is_little_endian(struct tun_struct *tun) { @@ -289,7 +410,7 @@ static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val) static inline u32 tun_hashfn(u32 rxhash) { - return rxhash & 0x3ff; + return rxhash & TUN_MASK_FLOW_ENTRIES; } static struct tun_flow_entry *tun_flow_find(struct hlist_head *head, u32 rxhash) @@ -364,9 +485,9 @@ static void tun_flow_delete_by_queue(struct tun_struct *tun, u16 queue_index) spin_unlock_bh(&tun->lock); } -static void tun_flow_cleanup(unsigned long data) +static void tun_flow_cleanup(struct timer_list *t) { - struct tun_struct *tun = (struct tun_struct *)data; + struct tun_struct *tun = from_timer(tun, t, flow_gc_timer); unsigned long delay = tun->ageing_time; unsigned long next_timer = jiffies + delay; unsigned long count = 0; @@ -374,25 +495,28 @@ static void tun_flow_cleanup(unsigned long data) tun_debug(KERN_INFO, tun, "tun_flow_cleanup\n"); - spin_lock_bh(&tun->lock); + spin_lock(&tun->lock); for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) { struct tun_flow_entry *e; struct hlist_node *n; hlist_for_each_entry_safe(e, n, &tun->flows[i], hash_link) { unsigned long this_timer; - count++; + this_timer = e->updated + delay; - if (time_before_eq(this_timer, jiffies)) + if (time_before_eq(this_timer, jiffies)) { tun_flow_delete(tun, e); - else if (time_before(this_timer, next_timer)) + continue; + } + count++; + if (time_before(this_timer, next_timer)) next_timer = this_timer; } } if (count) mod_timer(&tun->flow_gc_timer, round_jiffies_up(next_timer)); - spin_unlock_bh(&tun->lock); + spin_unlock(&tun->lock); } static void tun_flow_update(struct tun_struct *tun, u32 rxhash, @@ -410,11 +534,6 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash, rcu_read_lock(); - /* We may get a very small possibility of OOO during switching, not - * worth to optimize.*/ - if (tun->numqueues == 1 || tfile->detached) - goto unlock; - e = tun_flow_find(head, rxhash); if (likely(e)) { /* TODO: keep queueing to old queue until it's empty? */ @@ -433,7 +552,6 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash, spin_unlock_bh(&tun->lock); } -unlock: rcu_read_unlock(); } @@ -454,18 +572,15 @@ static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash) * different rxq no. here. If we could not get rxhash, then we would * hope the rxq no. may help here. */ -static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, - void *accel_priv, select_queue_fallback_t fallback) +static u16 tun_automq_select_queue(struct tun_struct *tun, struct sk_buff *skb) { - struct tun_struct *tun = netdev_priv(dev); struct tun_flow_entry *e; u32 txq = 0; u32 numqueues = 0; - rcu_read_lock(); - numqueues = ACCESS_ONCE(tun->numqueues); + numqueues = READ_ONCE(tun->numqueues); - txq = skb_get_hash(skb); + txq = __skb_get_hash_symmetric(skb); if (txq) { e = tun_flow_find(&tun->flows[tun_hashfn(txq)], txq); if (e) { @@ -480,10 +595,43 @@ static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, txq -= numqueues; } - rcu_read_unlock(); return txq; } +static u16 tun_ebpf_select_queue(struct tun_struct *tun, struct sk_buff *skb) +{ + struct tun_prog *prog; + u32 numqueues; + u16 ret = 0; + + numqueues = READ_ONCE(tun->numqueues); + if (!numqueues) + return 0; + + prog = rcu_dereference(tun->steering_prog); + if (prog) + ret = bpf_prog_run_clear_cb(prog->prog, skb); + + return ret % numqueues; +} + +static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev, + select_queue_fallback_t fallback) +{ + struct tun_struct *tun = netdev_priv(dev); + u16 ret; + + rcu_read_lock(); + if (rcu_dereference(tun->steering_prog)) + ret = tun_ebpf_select_queue(tun, skb); + else + ret = tun_automq_select_queue(tun, skb); + rcu_read_unlock(); + + return ret; +} + static inline bool tun_not_capable(struct tun_struct *tun) { const struct cred *cred = current_cred(); @@ -517,22 +665,29 @@ static struct tun_struct *tun_enable_queue(struct tun_file *tfile) return tun; } -static void tun_queue_purge(struct tun_file *tfile) +void tun_ptr_free(void *ptr) { - struct sk_buff *skb; - - while ((skb = skb_array_consume(&tfile->tx_array)) != NULL) - kfree_skb(skb); + if (!ptr) + return; + if (tun_is_xdp_frame(ptr)) { + struct xdp_frame *xdpf = tun_ptr_to_xdp(ptr); - skb_queue_purge(&tfile->sk.sk_error_queue); + xdp_return_frame(xdpf); + } else { + __skb_array_destroy_skb(ptr); + } } +EXPORT_SYMBOL_GPL(tun_ptr_free); -static void tun_cleanup_tx_array(struct tun_file *tfile) +static void tun_queue_purge(struct tun_file *tfile) { - if (tfile->tx_array.ring.queue) { - skb_array_cleanup(&tfile->tx_array); - memset(&tfile->tx_array, 0, sizeof(tfile->tx_array)); - } + void *ptr; + + while ((ptr = ptr_ring_consume(&tfile->tx_ring)) != NULL) + tun_ptr_free(ptr); + + skb_queue_purge(&tfile->sk.sk_write_queue); + skb_queue_purge(&tfile->sk.sk_error_queue); } static void __tun_detach(struct tun_file *tfile, bool clean) @@ -542,6 +697,11 @@ static void __tun_detach(struct tun_file *tfile, bool clean) tun = rtnl_dereference(tfile->tun); + if (tun && clean) { + tun_napi_disable(tfile); + tun_napi_del(tfile); + } + if (tun && !tfile->detached) { u16 index = tfile->queue_index; BUG_ON(index >= tun->numqueues); @@ -550,6 +710,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) tun->tfiles[tun->numqueues - 1]); ntfile = rtnl_dereference(tun->tfiles[index]); ntfile->queue_index = index; + rcu_assign_pointer(tun->tfiles[tun->numqueues - 1], + NULL); --tun->numqueues; if (clean) { @@ -576,15 +738,24 @@ static void __tun_detach(struct tun_file *tfile, bool clean) tun->dev->reg_state == NETREG_REGISTERED) unregister_netdevice(tun->dev); } - tun_cleanup_tx_array(tfile); + if (tun) + xdp_rxq_info_unreg(&tfile->xdp_rxq); + ptr_ring_cleanup(&tfile->tx_ring, tun_ptr_free); sock_put(&tfile->sk); } } static void tun_detach(struct tun_file *tfile, bool clean) { + struct tun_struct *tun; + struct net_device *dev; + rtnl_lock(); + tun = rtnl_dereference(tfile->tun); + dev = tun ? tun->dev : NULL; __tun_detach(tfile, clean); + if (dev) + netdev_state_change(dev); rtnl_unlock(); } @@ -597,6 +768,7 @@ static void tun_detach_all(struct net_device *dev) for (i = 0; i < n; i++) { tfile = rtnl_dereference(tun->tfiles[i]); BUG_ON(!tfile); + tun_napi_disable(tfile); tfile->socket.sk->sk_shutdown = RCV_SHUTDOWN; tfile->socket.sk->sk_data_ready(tfile->socket.sk); RCU_INIT_POINTER(tfile->tun, NULL); @@ -612,16 +784,17 @@ static void tun_detach_all(struct net_device *dev) synchronize_net(); for (i = 0; i < n; i++) { tfile = rtnl_dereference(tun->tfiles[i]); + tun_napi_del(tfile); /* Drop read queue */ tun_queue_purge(tfile); + xdp_rxq_info_unreg(&tfile->xdp_rxq); sock_put(&tfile->sk); - tun_cleanup_tx_array(tfile); } list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { tun_enable_queue(tfile); tun_queue_purge(tfile); + xdp_rxq_info_unreg(&tfile->xdp_rxq); sock_put(&tfile->sk); - tun_cleanup_tx_array(tfile); } BUG_ON(tun->numdisabled != 0); @@ -629,7 +802,8 @@ static void tun_detach_all(struct net_device *dev) module_put(THIS_MODULE); } -static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filter) +static int tun_attach(struct tun_struct *tun, struct file *file, + bool skip_filter, bool napi, bool napi_frags) { struct tun_file *tfile = file->private_data; struct net_device *dev = tun->dev; @@ -664,33 +838,60 @@ static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filte } if (!tfile->detached && - skb_array_init(&tfile->tx_array, dev->tx_queue_len, GFP_KERNEL)) { + ptr_ring_resize(&tfile->tx_ring, dev->tx_queue_len, + GFP_KERNEL, tun_ptr_free)) { err = -ENOMEM; goto out; } tfile->queue_index = tun->numqueues; tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN; - rcu_assign_pointer(tfile->tun, tun); - rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); - tun->numqueues++; - if (tfile->detached) + if (tfile->detached) { + /* Re-attach detached tfile, updating XDP queue_index */ + WARN_ON(!xdp_rxq_info_is_reg(&tfile->xdp_rxq)); + + if (tfile->xdp_rxq.queue_index != tfile->queue_index) + tfile->xdp_rxq.queue_index = tfile->queue_index; + } else { + /* Setup XDP RX-queue info, for new tfile getting attached */ + err = xdp_rxq_info_reg(&tfile->xdp_rxq, + tun->dev, tfile->queue_index); + if (err < 0) + goto out; + err = xdp_rxq_info_reg_mem_model(&tfile->xdp_rxq, + MEM_TYPE_PAGE_SHARED, NULL); + if (err < 0) { + xdp_rxq_info_unreg(&tfile->xdp_rxq); + goto out; + } + err = 0; + } + + if (tfile->detached) { tun_enable_queue(tfile); - else + } else { sock_hold(&tfile->sk); - - tun_set_real_num_queues(tun); + tun_napi_init(tun, tfile, napi, napi_frags); + } /* device is allowed to go away first, so no need to hold extra * refcnt. */ + /* Publish tfile->tun and tun->tfiles only after we've fully + * initialized tfile; otherwise we risk using half-initialized + * object. + */ + rcu_assign_pointer(tfile->tun, tun); + rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); + tun->numqueues++; + tun_set_real_num_queues(tun); out: return err; } -static struct tun_struct *__tun_get(struct tun_file *tfile) +static struct tun_struct *tun_get(struct tun_file *tfile) { struct tun_struct *tun; @@ -703,11 +904,6 @@ static struct tun_struct *__tun_get(struct tun_file *tfile) return tun; } -static struct tun_struct *tun_get(struct file *file) -{ - return __tun_get(file->private_data); -} - static void tun_put(struct tun_struct *tun) { dev_put(tun->dev); @@ -830,18 +1026,8 @@ static void tun_net_uninit(struct net_device *dev) /* Net device open. */ static int tun_net_open(struct net_device *dev) { - struct tun_struct *tun = netdev_priv(dev); - int i; - netif_tx_start_all_queues(dev); - for (i = 0; i < tun->numqueues; i++) { - struct tun_file *tfile; - - tfile = rtnl_dereference(tun->tfiles[i]); - tfile->socket.sk->sk_write_space(tfile->socket.sk); - } - return 0; } @@ -853,29 +1039,16 @@ static int tun_net_close(struct net_device *dev) } /* Net device start xmit */ -static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) +static void tun_automq_xmit(struct tun_struct *tun, struct sk_buff *skb) { - struct tun_struct *tun = netdev_priv(dev); - int txq = skb->queue_mapping; - struct tun_file *tfile; - u32 numqueues = 0; - - rcu_read_lock(); - tfile = rcu_dereference(tun->tfiles[txq]); - numqueues = ACCESS_ONCE(tun->numqueues); - - /* Drop packet if interface is not attached */ - if (txq >= numqueues) - goto drop; - #ifdef CONFIG_RPS - if (numqueues == 1 && static_key_false(&rps_needed)) { + if (tun->numqueues == 1 && static_key_false(&rps_needed)) { /* Select queue was not called for the skbuff, so we extract the * RPS hash and save it into the flow_table here. */ __u32 rxhash; - rxhash = skb_get_hash(skb); + rxhash = __skb_get_hash_symmetric(skb); if (rxhash) { struct tun_flow_entry *e; e = tun_flow_find(&tun->flows[tun_hashfn(rxhash)], @@ -885,6 +1058,37 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) } } #endif +} + +static unsigned int run_ebpf_filter(struct tun_struct *tun, + struct sk_buff *skb, + int len) +{ + struct tun_prog *prog = rcu_dereference(tun->filter_prog); + + if (prog) + len = bpf_prog_run_clear_cb(prog->prog, skb); + + return len; +} + +/* Net device start xmit */ +static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + int txq = skb->queue_mapping; + struct tun_file *tfile; + int len = skb->len; + + rcu_read_lock(); + tfile = rcu_dereference(tun->tfiles[txq]); + + /* Drop packet if interface is not attached */ + if (!tfile) + goto drop; + + if (!rcu_dereference(tun->steering_prog)) + tun_automq_xmit(tun, skb); tun_debug(KERN_INFO, tun, "tun_net_xmit %d\n", skb->len); @@ -900,14 +1104,11 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) sk_filter(tfile->socket.sk, skb)) goto drop; - /* Limit the number of packets queued by dividing txq length with the - * number of queues. - */ - if (skb_queue_len(&tfile->socket.sk->sk_receive_queue) * numqueues - >= dev->tx_queue_len) + len = run_ebpf_filter(tun, skb, len); + if (len == 0 || pskb_trim(skb, len)) goto drop; - if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) + if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC))) goto drop; skb_tx_timestamp(skb); @@ -919,7 +1120,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) nf_reset(skb); - if (skb_array_produce(&tfile->tx_array, skb)) + if (ptr_ring_produce(&tfile->tx_ring, skb)) goto drop; /* Notify and wake up reader process */ @@ -947,18 +1148,6 @@ static void tun_net_mclist(struct net_device *dev) */ } -#define MIN_MTU 68 -#define MAX_MTU 65535 - -static int -tun_net_change_mtu(struct net_device *dev, int new_mtu) -{ - if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU) - return -EINVAL; - dev->mtu = new_mtu; - return 0; -} - static netdev_features_t tun_net_fix_features(struct net_device *dev, netdev_features_t features) { @@ -966,23 +1155,6 @@ static netdev_features_t tun_net_fix_features(struct net_device *dev, return (features & tun->set_features) | (features & ~TUN_USER_FEATURES); } -#ifdef CONFIG_NET_POLL_CONTROLLER -static void tun_poll_controller(struct net_device *dev) -{ - /* - * Tun only receives frames when: - * 1) the char device endpoint gets data from user space - * 2) the tun socket gets a sendmsg call from user space - * Since both of those are synchronous operations, we are guaranteed - * never to have pending data when we poll for it - * so there is nothing to do here but return. - * We need this though so netpoll recognizes us as an interface that - * supports polling, which enables bridge devices in virt setups to - * still use netconsole - */ - return; -} -#endif static void tun_set_headroom(struct net_device *dev, int new_hr) { @@ -994,7 +1166,7 @@ static void tun_set_headroom(struct net_device *dev, int new_hr) tun->align = new_hr; } -static struct rtnl_link_stats64 * +static void tun_net_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { u32 rx_dropped = 0, tx_dropped = 0, rx_frame_errors = 0; @@ -1028,16 +1200,66 @@ tun_net_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) stats->rx_dropped = rx_dropped; stats->rx_frame_errors = rx_frame_errors; stats->tx_dropped = tx_dropped; - return stats; } -static int -tun_change_carrier(struct net_device *dev, bool new_carrier) { - if (new_carrier) - netif_carrier_on(dev); - else - netif_carrier_off(dev); - return 0; +static int tun_xdp_set(struct net_device *dev, struct bpf_prog *prog, + struct netlink_ext_ack *extack) +{ + struct tun_struct *tun = netdev_priv(dev); + struct bpf_prog *old_prog; + + old_prog = rtnl_dereference(tun->xdp_prog); + rcu_assign_pointer(tun->xdp_prog, prog); + if (old_prog) + bpf_prog_put(old_prog); + + return 0; +} + +static u32 tun_xdp_query(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + const struct bpf_prog *xdp_prog; + + xdp_prog = rtnl_dereference(tun->xdp_prog); + if (xdp_prog) + return xdp_prog->aux->id; + + return 0; +} + +static int tun_xdp(struct net_device *dev, struct netdev_bpf *xdp) +{ + switch (xdp->command) { + case XDP_SETUP_PROG: + return tun_xdp_set(dev, xdp->prog, xdp->extack); + case XDP_QUERY_PROG: + xdp->prog_id = tun_xdp_query(dev); + return 0; + default: + return -EINVAL; + } +} + +static int tun_net_change_carrier(struct net_device *dev, bool new_carrier) +{ + if (new_carrier) { + netif_carrier_on(dev); + } else { + netif_carrier_off(dev); + } + return 0; +} + +#define MIN_MTU 68 +#define MAX_MTU 65535 + +static int tun_net_change_mtu(struct net_device *dev, int new_mtu) +{ + if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU) + return -EINVAL; + dev->mtu = new_mtu; + return 0; } static const struct net_device_ops tun_netdev_ops = { @@ -1045,35 +1267,99 @@ static const struct net_device_ops tun_netdev_ops = { .ndo_open = tun_net_open, .ndo_stop = tun_net_close, .ndo_start_xmit = tun_net_xmit, - .ndo_change_mtu = tun_net_change_mtu, .ndo_fix_features = tun_net_fix_features, .ndo_select_queue = tun_select_queue, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = tun_poll_controller, -#endif .ndo_set_rx_headroom = tun_set_headroom, .ndo_get_stats64 = tun_net_get_stats64, - .ndo_change_carrier = tun_change_carrier, + .ndo_change_carrier = tun_net_change_carrier, + .ndo_change_mtu = tun_net_change_mtu, }; +static void __tun_xdp_flush_tfile(struct tun_file *tfile) +{ + /* Notify and wake up reader process */ + if (tfile->flags & TUN_FASYNC) + kill_fasync(&tfile->fasync, SIGIO, POLL_IN); + tfile->socket.sk->sk_data_ready(tfile->socket.sk); +} + +static int tun_xdp_xmit(struct net_device *dev, int n, + struct xdp_frame **frames, u32 flags) +{ + struct tun_struct *tun = netdev_priv(dev); + struct tun_file *tfile; + u32 numqueues; + int drops = 0; + int cnt = n; + int i; + + if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) + return -EINVAL; + + rcu_read_lock(); + +resample: + numqueues = READ_ONCE(tun->numqueues); + if (!numqueues) { + rcu_read_unlock(); + return -ENXIO; /* Caller will free/return all frames */ + } + + tfile = rcu_dereference(tun->tfiles[smp_processor_id() % + numqueues]); + if (unlikely(!tfile)) + goto resample; + + spin_lock(&tfile->tx_ring.producer_lock); + for (i = 0; i < n; i++) { + struct xdp_frame *xdp = frames[i]; + /* Encode the XDP flag into lowest bit for consumer to differ + * XDP buffer from sk_buff. + */ + void *frame = tun_xdp_to_ptr(xdp); + + if (__ptr_ring_produce(&tfile->tx_ring, frame)) { + this_cpu_inc(tun->pcpu_stats->tx_dropped); + xdp_return_frame_rx_napi(xdp); + drops++; + } + } + spin_unlock(&tfile->tx_ring.producer_lock); + + if (flags & XDP_XMIT_FLUSH) + __tun_xdp_flush_tfile(tfile); + + rcu_read_unlock(); + return cnt - drops; +} + +static int tun_xdp_tx(struct net_device *dev, struct xdp_buff *xdp) +{ + struct xdp_frame *frame = convert_to_xdp_frame(xdp); + + if (unlikely(!frame)) + return -EOVERFLOW; + + return tun_xdp_xmit(dev, 1, &frame, XDP_XMIT_FLUSH); +} + static const struct net_device_ops tap_netdev_ops = { .ndo_uninit = tun_net_uninit, .ndo_open = tun_net_open, .ndo_stop = tun_net_close, .ndo_start_xmit = tun_net_xmit, - .ndo_change_mtu = tun_net_change_mtu, .ndo_fix_features = tun_net_fix_features, .ndo_set_rx_mode = tun_net_mclist, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_select_queue = tun_select_queue, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = tun_poll_controller, -#endif .ndo_features_check = passthru_features_check, .ndo_set_rx_headroom = tun_set_headroom, .ndo_get_stats64 = tun_net_get_stats64, - .ndo_change_carrier = tun_change_carrier, + .ndo_bpf = tun_xdp, + .ndo_xdp_xmit = tun_xdp_xmit, + .ndo_change_carrier = tun_net_change_carrier, + .ndo_change_mtu = tun_net_change_mtu, }; static void tun_flow_init(struct tun_struct *tun) @@ -1084,7 +1370,7 @@ static void tun_flow_init(struct tun_struct *tun) INIT_HLIST_HEAD(&tun->flows[i]); tun->ageing_time = TUN_FLOW_EXPIRE; - setup_timer(&tun->flow_gc_timer, tun_flow_cleanup, (unsigned long)tun); + timer_setup(&tun->flow_gc_timer, tun_flow_cleanup, 0); mod_timer(&tun->flow_gc_timer, round_jiffies_up(jiffies + tun->ageing_time)); } @@ -1095,6 +1381,9 @@ static void tun_flow_uninit(struct tun_struct *tun) tun_flow_flush(tun); } +#define MIN_MTU 68 +#define MAX_MTU 65535 + /* Initialize net device. */ static void tun_net_init(struct net_device *dev) { @@ -1125,20 +1414,30 @@ static void tun_net_init(struct net_device *dev) break; } + + dev->min_mtu = MIN_MTU; + dev->max_mtu = MAX_MTU - dev->hard_header_len; +} + +static bool tun_sock_writeable(struct tun_struct *tun, struct tun_file *tfile) +{ + struct sock *sk = tfile->socket.sk; + + return (tun->dev->flags & IFF_UP) && sock_writeable(sk); } /* Character device part */ /* Poll */ -static unsigned int tun_chr_poll(struct file *file, poll_table *wait) +static __poll_t tun_chr_poll(struct file *file, poll_table *wait) { struct tun_file *tfile = file->private_data; - struct tun_struct *tun = __tun_get(tfile); + struct tun_struct *tun = tun_get(tfile); struct sock *sk; - unsigned int mask = 0; + __poll_t mask = 0; if (!tun) - return POLLERR; + return EPOLLERR; sk = tfile->socket.sk; @@ -1146,53 +1445,292 @@ static unsigned int tun_chr_poll(struct file *file, poll_table *wait) poll_wait(file, sk_sleep(sk), wait); - if (!skb_array_empty(&tfile->tx_array)) - mask |= POLLIN | POLLRDNORM; + if (!ptr_ring_empty(&tfile->tx_ring)) + mask |= EPOLLIN | EPOLLRDNORM; - if (tun->dev->flags & IFF_UP && - (sock_writeable(sk) || - (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) && - sock_writeable(sk)))) - mask |= POLLOUT | POLLWRNORM; + /* Make sure SOCKWQ_ASYNC_NOSPACE is set if not writable to + * guarantee EPOLLOUT to be raised by either here or + * tun_sock_write_space(). Then process could get notification + * after it writes to a down device and meets -EIO. + */ + if (tun_sock_writeable(tun, tfile) || + (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) && + tun_sock_writeable(tun, tfile))) + mask |= EPOLLOUT | EPOLLWRNORM; if (tun->dev->reg_state != NETREG_REGISTERED) - mask = POLLERR; + mask = EPOLLERR; tun_put(tun); return mask; } -/* prepad is the amount to reserve at front. len is length after that. - * linear is a hint as to how much to copy (usually headers). */ -static struct sk_buff *tun_alloc_skb(struct tun_file *tfile, - size_t prepad, size_t len, - size_t linear, int noblock) +static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile, + size_t len, + const struct iov_iter *it) +{ + struct sk_buff *skb; + size_t linear; + int err; + int i; + + if (it->nr_segs > MAX_SKB_FRAGS + 1) + return ERR_PTR(-ENOMEM); + + local_bh_disable(); + skb = napi_get_frags(&tfile->napi); + local_bh_enable(); + if (!skb) + return ERR_PTR(-ENOMEM); + + linear = iov_iter_single_seg_count(it); + err = __skb_grow(skb, linear); + if (err) + goto free; + + skb->len = len; + skb->data_len = len - linear; + skb->truesize += skb->data_len; + + for (i = 1; i < it->nr_segs; i++) { + struct page_frag *pfrag = ¤t->task_frag; + size_t fragsz = it->iov[i].iov_len; + + if (fragsz == 0 || fragsz > PAGE_SIZE) { + err = -EINVAL; + goto free; + } + + if (!skb_page_frag_refill(fragsz, pfrag, GFP_KERNEL)) { + err = -ENOMEM; + goto free; + } + + skb_fill_page_desc(skb, i - 1, pfrag->page, + pfrag->offset, fragsz); + page_ref_inc(pfrag->page); + pfrag->offset += fragsz; + } + + return skb; +free: + /* frees skb and all frags allocated with napi_alloc_frag() */ + napi_free_frags(&tfile->napi); + return ERR_PTR(err); +} + +/* prepad is the amount to reserve at front. len is length after that. + * linear is a hint as to how much to copy (usually headers). */ +static struct sk_buff *tun_alloc_skb(struct tun_file *tfile, + size_t prepad, size_t len, + size_t linear, int noblock) +{ + struct sock *sk = tfile->socket.sk; + struct sk_buff *skb; + int err; + + /* Under a page? Don't bother with paged skb. */ + if (prepad + len < PAGE_SIZE || !linear) + linear = len; + + skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, + &err, 0); + if (!skb) + return ERR_PTR(err); + + skb_reserve(skb, prepad); + skb_put(skb, linear); + skb->data_len = len - linear; + skb->len += len - linear; + + return skb; +} + +static void tun_rx_batched(struct tun_struct *tun, struct tun_file *tfile, + struct sk_buff *skb, int more) +{ + struct sk_buff_head *queue = &tfile->sk.sk_write_queue; + struct sk_buff_head process_queue; + u32 rx_batched = tun->rx_batched; + bool rcv = false; + + if (!rx_batched || (!more && skb_queue_empty(queue))) { + local_bh_disable(); + skb_record_rx_queue(skb, tfile->queue_index); + netif_receive_skb(skb); + local_bh_enable(); + return; + } + + spin_lock(&queue->lock); + if (!more || skb_queue_len(queue) == rx_batched) { + __skb_queue_head_init(&process_queue); + skb_queue_splice_tail_init(queue, &process_queue); + rcv = true; + } else { + __skb_queue_tail(queue, skb); + } + spin_unlock(&queue->lock); + + if (rcv) { + struct sk_buff *nskb; + + local_bh_disable(); + while ((nskb = __skb_dequeue(&process_queue))) { + skb_record_rx_queue(nskb, tfile->queue_index); + netif_receive_skb(nskb); + } + skb_record_rx_queue(skb, tfile->queue_index); + netif_receive_skb(skb); + local_bh_enable(); + } +} + +static bool tun_can_build_skb(struct tun_struct *tun, struct tun_file *tfile, + int len, int noblock, bool zerocopy) +{ + if ((tun->flags & TUN_TYPE_MASK) != IFF_TAP) + return false; + + if (tfile->socket.sk->sk_sndbuf != INT_MAX) + return false; + + if (!noblock) + return false; + + if (zerocopy) + return false; + + if (SKB_DATA_ALIGN(len + TUN_RX_PAD) + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) > PAGE_SIZE) + return false; + + return true; +} + +static struct sk_buff *tun_build_skb(struct tun_struct *tun, + struct tun_file *tfile, + struct iov_iter *from, + struct virtio_net_hdr *hdr, + int len, int *skb_xdp) { - struct sock *sk = tfile->socket.sk; + struct page_frag *alloc_frag = ¤t->task_frag; struct sk_buff *skb; - int err; + struct bpf_prog *xdp_prog; + int buflen = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + unsigned int delta = 0; + char *buf; + size_t copied; + int err, pad = TUN_RX_PAD; - /* Under a page? Don't bother with paged skb. */ - if (prepad + len < PAGE_SIZE || !linear) - linear = len; + rcu_read_lock(); + xdp_prog = rcu_dereference(tun->xdp_prog); + if (xdp_prog) + pad += TUN_HEADROOM; + buflen += SKB_DATA_ALIGN(len + pad); + rcu_read_unlock(); - skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, - &err, 0); - if (!skb) - return ERR_PTR(err); + alloc_frag->offset = ALIGN((u64)alloc_frag->offset, SMP_CACHE_BYTES); + if (unlikely(!skb_page_frag_refill(buflen, alloc_frag, GFP_KERNEL))) + return ERR_PTR(-ENOMEM); - skb_reserve(skb, prepad); - skb_put(skb, linear); - skb->data_len = len - linear; - skb->len += len - linear; + buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset; + copied = copy_page_from_iter(alloc_frag->page, + alloc_frag->offset + pad, + len, from); + if (copied != len) + return ERR_PTR(-EFAULT); + + /* There's a small window that XDP may be set after the check + * of xdp_prog above, this should be rare and for simplicity + * we do XDP on skb in case the headroom is not enough. + */ + if (hdr->gso_type || !xdp_prog) + *skb_xdp = 1; + else + *skb_xdp = 0; + + local_bh_disable(); + rcu_read_lock(); + xdp_prog = rcu_dereference(tun->xdp_prog); + if (xdp_prog && !*skb_xdp) { + struct xdp_buff xdp; + void *orig_data; + u32 act; + + xdp.data_hard_start = buf; + xdp.data = buf + pad; + xdp_set_data_meta_invalid(&xdp); + xdp.data_end = xdp.data + len; + xdp.rxq = &tfile->xdp_rxq; + orig_data = xdp.data; + act = bpf_prog_run_xdp(xdp_prog, &xdp); + + switch (act) { + case XDP_REDIRECT: + get_page(alloc_frag->page); + alloc_frag->offset += buflen; + err = xdp_do_redirect(tun->dev, &xdp, xdp_prog); + xdp_do_flush_map(); + if (err) + goto err_redirect; + rcu_read_unlock(); + local_bh_enable(); + return NULL; + case XDP_TX: + get_page(alloc_frag->page); + alloc_frag->offset += buflen; + if (tun_xdp_tx(tun->dev, &xdp) < 0) + goto err_redirect; + rcu_read_unlock(); + local_bh_enable(); + return NULL; + case XDP_PASS: + delta = orig_data - xdp.data; + len = xdp.data_end - xdp.data; + break; + default: + bpf_warn_invalid_xdp_action(act); + /* fall through */ + case XDP_ABORTED: + trace_xdp_exception(tun->dev, xdp_prog, act); + /* fall through */ + case XDP_DROP: + goto err_xdp; + } + } + + skb = build_skb(buf, buflen); + if (!skb) { + rcu_read_unlock(); + local_bh_enable(); + return ERR_PTR(-ENOMEM); + } + + skb_reserve(skb, pad - delta); + skb_put(skb, len); + skb_set_owner_w(skb, tfile->socket.sk); + get_page(alloc_frag->page); + alloc_frag->offset += buflen; + + rcu_read_unlock(); + local_bh_enable(); return skb; + +err_redirect: + put_page(alloc_frag->page); +err_xdp: + rcu_read_unlock(); + local_bh_enable(); + this_cpu_inc(tun->pcpu_stats->rx_dropped); + return NULL; } /* Get packet from user space buffer */ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, void *msg_control, struct iov_iter *from, - int noblock) + int noblock, bool more) { struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; struct sk_buff *skb; @@ -1204,19 +1742,16 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, int copylen; bool zerocopy = false; int err; - u32 rxhash; - ssize_t n; - - if (!(tun->dev->flags & IFF_UP)) - return -EIO; + u32 rxhash = 0; + int skb_xdp = 1; + bool frags = tun_napi_frags_enabled(tfile); if (!(tun->flags & IFF_NO_PI)) { if (len < sizeof(pi)) return -EINVAL; len -= sizeof(pi); - n = copy_from_iter(&pi, sizeof(pi), from); - if (n != sizeof(pi)) + if (!copy_from_iter_full(&pi, sizeof(pi), from)) return -EFAULT; } @@ -1227,8 +1762,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, return -EINVAL; len -= vnet_hdr_sz; - n = copy_from_iter(&gso, sizeof(gso), from); - if (n != sizeof(gso)) + if (!copy_from_iter_full(&gso, sizeof(gso), from)) return -EFAULT; if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && @@ -1265,36 +1799,75 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, zerocopy = true; } - if (!zerocopy) { - copylen = len; - if (tun16_to_cpu(tun, gso.hdr_len) > good_linear) - linear = good_linear; + if (!frags && tun_can_build_skb(tun, tfile, len, noblock, zerocopy)) { + /* For the packet that is not easy to be processed + * (e.g gso or jumbo packet), we will do it at after + * skb was created with generic XDP routine. + */ + skb = tun_build_skb(tun, tfile, from, &gso, len, &skb_xdp); + if (IS_ERR(skb)) { + this_cpu_inc(tun->pcpu_stats->rx_dropped); + return PTR_ERR(skb); + } + if (!skb) + return total_len; + } else { + if (!zerocopy) { + copylen = len; + if (tun16_to_cpu(tun, gso.hdr_len) > good_linear) + linear = good_linear; + else + linear = tun16_to_cpu(tun, gso.hdr_len); + } + + if (frags) { + mutex_lock(&tfile->napi_mutex); + skb = tun_napi_alloc_frags(tfile, copylen, from); + /* tun_napi_alloc_frags() enforces a layout for the skb. + * If zerocopy is enabled, then this layout will be + * overwritten by zerocopy_sg_from_iter(). + */ + zerocopy = false; + } else { + skb = tun_alloc_skb(tfile, align, copylen, linear, + noblock); + } + + if (IS_ERR(skb)) { + if (PTR_ERR(skb) != -EAGAIN) + this_cpu_inc(tun->pcpu_stats->rx_dropped); + if (frags) + mutex_unlock(&tfile->napi_mutex); + return PTR_ERR(skb); + } + + if (zerocopy) + err = zerocopy_sg_from_iter(skb, from); else - linear = tun16_to_cpu(tun, gso.hdr_len); - } + err = skb_copy_datagram_from_iter(skb, 0, from, len); - skb = tun_alloc_skb(tfile, align, copylen, linear, noblock); - if (IS_ERR(skb)) { - if (PTR_ERR(skb) != -EAGAIN) + if (err) { + err = -EFAULT; +drop: this_cpu_inc(tun->pcpu_stats->rx_dropped); - return PTR_ERR(skb); - } - - if (zerocopy) - err = zerocopy_sg_from_iter(skb, from); - else - err = skb_copy_datagram_from_iter(skb, 0, from, len); + kfree_skb(skb); + if (frags) { + tfile->napi.skb = NULL; + mutex_unlock(&tfile->napi_mutex); + } - if (err) { - this_cpu_inc(tun->pcpu_stats->rx_dropped); - kfree_skb(skb); - return -EFAULT; + return err; + } } - err = virtio_net_hdr_to_skb(skb, &gso, tun_is_little_endian(tun)); - if (err) { + if (virtio_net_hdr_to_skb(skb, &gso, tun_is_little_endian(tun))) { this_cpu_inc(tun->pcpu_stats->rx_frame_errors); kfree_skb(skb); + if (frags) { + tfile->napi.skb = NULL; + mutex_unlock(&tfile->napi_mutex); + } + return -EINVAL; } @@ -1322,7 +1895,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, skb->dev = tun->dev; break; case IFF_TAP: - skb->protocol = eth_type_trans(skb, tun->dev); + if (!frags) + skb->protocol = eth_type_trans(skb, tun->dev); break; } @@ -1339,8 +1913,76 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, skb_reset_network_header(skb); skb_probe_transport_header(skb, 0); - rxhash = skb_get_hash(skb); - netif_rx_ni(skb); + if (skb_xdp) { + struct bpf_prog *xdp_prog; + int ret; + + local_bh_disable(); + rcu_read_lock(); + xdp_prog = rcu_dereference(tun->xdp_prog); + if (xdp_prog) { + ret = do_xdp_generic(xdp_prog, skb); + if (ret != XDP_PASS) { + rcu_read_unlock(); + local_bh_enable(); + return total_len; + } + } + rcu_read_unlock(); + local_bh_enable(); + } + + /* Compute the costly rx hash only if needed for flow updates. + * We may get a very small possibility of OOO during switching, not + * worth to optimize. + */ + if (!rcu_access_pointer(tun->steering_prog) && tun->numqueues > 1 && + !tfile->detached) + rxhash = __skb_get_hash_symmetric(skb); + + rcu_read_lock(); + if (unlikely(!(tun->dev->flags & IFF_UP))) { + err = -EIO; + rcu_read_unlock(); + goto drop; + } + + if (frags) { + /* Exercise flow dissector code path. */ + u32 headlen = eth_get_headlen(skb->data, skb_headlen(skb)); + + if (unlikely(headlen > skb_headlen(skb))) { + this_cpu_inc(tun->pcpu_stats->rx_dropped); + napi_free_frags(&tfile->napi); + rcu_read_unlock(); + mutex_unlock(&tfile->napi_mutex); + WARN_ON(1); + return -ENOMEM; + } + + local_bh_disable(); + napi_gro_frags(&tfile->napi); + local_bh_enable(); + mutex_unlock(&tfile->napi_mutex); + } else if (tfile->napi_enabled) { + struct sk_buff_head *queue = &tfile->sk.sk_write_queue; + int queue_len; + + spin_lock_bh(&queue->lock); + __skb_queue_tail(queue, skb); + queue_len = skb_queue_len(queue); + spin_unlock(&queue->lock); + + if (!more || queue_len > NAPI_POLL_WEIGHT) + napi_schedule(&tfile->napi); + + local_bh_enable(); + } else if (!IS_ENABLED(CONFIG_4KSTACKS)) { + tun_rx_batched(tun, tfile, skb, more); + } else { + netif_rx_ni(skb); + } + rcu_read_unlock(); stats = get_cpu_ptr(tun->pcpu_stats); u64_stats_update_begin(&stats->syncp); @@ -1349,26 +1991,63 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, u64_stats_update_end(&stats->syncp); put_cpu_ptr(stats); - tun_flow_update(tun, rxhash, tfile); + if (rxhash) + tun_flow_update(tun, rxhash, tfile); + return total_len; } static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; - struct tun_struct *tun = tun_get(file); struct tun_file *tfile = file->private_data; + struct tun_struct *tun = tun_get(tfile); ssize_t result; if (!tun) return -EBADFD; - result = tun_get_user(tun, tfile, NULL, from, file->f_flags & O_NONBLOCK); + result = tun_get_user(tun, tfile, NULL, from, + file->f_flags & O_NONBLOCK, false); tun_put(tun); return result; } +static ssize_t tun_put_user_xdp(struct tun_struct *tun, + struct tun_file *tfile, + struct xdp_frame *xdp_frame, + struct iov_iter *iter) +{ + int vnet_hdr_sz = 0; + size_t size = xdp_frame->len; + struct tun_pcpu_stats *stats; + size_t ret; + + if (tun->flags & IFF_VNET_HDR) { + struct virtio_net_hdr gso = { 0 }; + + vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz); + if (unlikely(iov_iter_count(iter) < vnet_hdr_sz)) + return -EINVAL; + if (unlikely(copy_to_iter(&gso, sizeof(gso), iter) != + sizeof(gso))) + return -EFAULT; + iov_iter_advance(iter, vnet_hdr_sz - sizeof(gso)); + } + + ret = copy_to_iter(xdp_frame->data, size, iter) + vnet_hdr_sz; + + stats = get_cpu_ptr(tun->pcpu_stats); + u64_stats_update_begin(&stats->syncp); + stats->tx_packets++; + stats->tx_bytes += ret; + u64_stats_update_end(&stats->syncp); + put_cpu_ptr(tun->pcpu_stats); + + return ret; +} + /* Put packet to the user space buffer */ static ssize_t tun_put_user(struct tun_struct *tun, struct tun_file *tfile, @@ -1405,15 +2084,14 @@ static ssize_t tun_put_user(struct tun_struct *tun, } if (vnet_hdr_sz) { - struct virtio_net_hdr gso = { 0 }; /* no info leak */ - int ret; + struct virtio_net_hdr gso; if (iov_iter_count(iter) < vnet_hdr_sz) return -EINVAL; - ret = virtio_net_hdr_from_skb(skb, &gso, - tun_is_little_endian(tun), true); - if (ret) { + if (virtio_net_hdr_from_skb(skb, &gso, + tun_is_little_endian(tun), true, + vlan_hlen)) { struct skb_shared_info *sinfo = skb_shinfo(skb); pr_err("unexpected GSO type: " "0x%x, gso_size %d, hdr_len %d\n", @@ -1435,10 +2113,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, if (vlan_hlen) { int ret; - struct { - __be16 h_vlan_proto; - __be16 h_vlan_TCI; - } veth; + struct veth veth; veth.h_vlan_proto = skb->vlan_proto; veth.h_vlan_TCI = htons(skb_vlan_tag_get(skb)); @@ -1468,15 +2143,14 @@ static ssize_t tun_put_user(struct tun_struct *tun, return total; } -static struct sk_buff *tun_ring_recv(struct tun_file *tfile, int noblock, - int *err) +static void *tun_ring_recv(struct tun_file *tfile, int noblock, int *err) { DECLARE_WAITQUEUE(wait, current); - struct sk_buff *skb = NULL; + void *ptr = NULL; int error = 0; - skb = skb_array_consume(&tfile->tx_array); - if (skb) + ptr = ptr_ring_consume(&tfile->tx_ring); + if (ptr) goto out; if (noblock) { error = -EAGAIN; @@ -1484,11 +2158,11 @@ static struct sk_buff *tun_ring_recv(struct tun_file *tfile, int noblock, } add_wait_queue(&tfile->wq.wait, &wait); - current->state = TASK_INTERRUPTIBLE; while (1) { - skb = skb_array_consume(&tfile->tx_array); - if (skb) + set_current_state(TASK_INTERRUPTIBLE); + ptr = ptr_ring_consume(&tfile->tx_ring); + if (ptr) break; if (signal_pending(current)) { error = -ERESTARTSYS; @@ -1502,37 +2176,49 @@ static struct sk_buff *tun_ring_recv(struct tun_file *tfile, int noblock, schedule(); } - current->state = TASK_RUNNING; + __set_current_state(TASK_RUNNING); remove_wait_queue(&tfile->wq.wait, &wait); out: *err = error; - return skb; + return ptr; } static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, struct iov_iter *to, - int noblock) + int noblock, void *ptr) { - struct sk_buff *skb; ssize_t ret; int err; tun_debug(KERN_INFO, tun, "tun_do_read\n"); - if (!iov_iter_count(to)) + if (!iov_iter_count(to)) { + tun_ptr_free(ptr); return 0; + } - /* Read frames from ring */ - skb = tun_ring_recv(tfile, noblock, &err); - if (!skb) - return err; + if (!ptr) { + /* Read frames from ring */ + ptr = tun_ring_recv(tfile, noblock, &err); + if (!ptr) + return err; + } - ret = tun_put_user(tun, tfile, skb, to); - if (unlikely(ret < 0)) - kfree_skb(skb); - else - consume_skb(skb); + if (tun_is_xdp_frame(ptr)) { + struct xdp_frame *xdpf = tun_ptr_to_xdp(ptr); + + ret = tun_put_user_xdp(tun, tfile, xdpf, to); + xdp_return_frame(xdpf); + } else { + struct sk_buff *skb = ptr; + + ret = tun_put_user(tun, tfile, skb, to); + if (unlikely(ret < 0)) + kfree_skb(skb); + else + consume_skb(skb); + } return ret; } @@ -1541,12 +2227,12 @@ static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to) { struct file *file = iocb->ki_filp; struct tun_file *tfile = file->private_data; - struct tun_struct *tun = __tun_get(tfile); + struct tun_struct *tun = tun_get(tfile); ssize_t len = iov_iter_count(to), ret; if (!tun) return -EBADFD; - ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK); + ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK, NULL); ret = min_t(ssize_t, ret, len); if (ret > 0) iocb->ki_pos = ret; @@ -1554,6 +2240,39 @@ static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to) return ret; } +static void tun_prog_free(struct rcu_head *rcu) +{ + struct tun_prog *prog = container_of(rcu, struct tun_prog, rcu); + + bpf_prog_destroy(prog->prog); + kfree(prog); +} + +static int __tun_set_ebpf(struct tun_struct *tun, + struct tun_prog __rcu **prog_p, + struct bpf_prog *prog) +{ + struct tun_prog *old, *new = NULL; + + if (prog) { + new = kmalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return -ENOMEM; + new->prog = prog; + } + + spin_lock_bh(&tun->lock); + old = rcu_dereference_protected(*prog_p, + lockdep_is_held(&tun->lock)); + rcu_assign_pointer(*prog_p, new); + spin_unlock_bh(&tun->lock); + + if (old) + call_rcu(&old->rcu, tun_prog_free); + + return 0; +} + static void tun_free_netdev(struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); @@ -1562,7 +2281,8 @@ static void tun_free_netdev(struct net_device *dev) free_percpu(tun->pcpu_stats); tun_flow_uninit(tun); security_tun_dev_free_security(tun->security); - free_netdev(dev); + __tun_set_ebpf(tun, &tun->steering_prog, NULL); + __tun_set_ebpf(tun, &tun->filter_prog, NULL); } static void tun_setup(struct net_device *dev) @@ -1571,9 +2291,11 @@ static void tun_setup(struct net_device *dev) tun->owner = INVALID_UID; tun->group = INVALID_GID; + tun_default_link_ksettings(dev, &tun->link_ksettings); dev->ethtool_ops = &tun_ethtool_ops; - dev->destructor = tun_free_netdev; + dev->needs_free_netdev = true; + dev->priv_destructor = tun_free_netdev; /* We prefer our own queue length */ dev->tx_queue_len = TUN_READQ_SIZE; } @@ -1581,9 +2303,66 @@ static void tun_setup(struct net_device *dev) /* Trivial set of netlink ops to allow deleting tun or tap * device with netlink. */ -static int tun_validate(struct nlattr *tb[], struct nlattr *data[]) +static int tun_validate(struct nlattr *tb[], struct nlattr *data[], + struct netlink_ext_ack *extack) { - return -EINVAL; + NL_SET_ERR_MSG(extack, + "tun/tap creation via rtnetlink is not supported."); + return -EOPNOTSUPP; +} + +static size_t tun_get_size(const struct net_device *dev) +{ + BUILD_BUG_ON(sizeof(u32) != sizeof(uid_t)); + BUILD_BUG_ON(sizeof(u32) != sizeof(gid_t)); + + return nla_total_size(sizeof(uid_t)) + /* OWNER */ + nla_total_size(sizeof(gid_t)) + /* GROUP */ + nla_total_size(sizeof(u8)) + /* TYPE */ + nla_total_size(sizeof(u8)) + /* PI */ + nla_total_size(sizeof(u8)) + /* VNET_HDR */ + nla_total_size(sizeof(u8)) + /* PERSIST */ + nla_total_size(sizeof(u8)) + /* MULTI_QUEUE */ + nla_total_size(sizeof(u32)) + /* NUM_QUEUES */ + nla_total_size(sizeof(u32)) + /* NUM_DISABLED_QUEUES */ + 0; +} + +static int tun_fill_info(struct sk_buff *skb, const struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + + if (nla_put_u8(skb, IFLA_TUN_TYPE, tun->flags & TUN_TYPE_MASK)) + goto nla_put_failure; + if (uid_valid(tun->owner) && + nla_put_u32(skb, IFLA_TUN_OWNER, + from_kuid_munged(current_user_ns(), tun->owner))) + goto nla_put_failure; + if (gid_valid(tun->group) && + nla_put_u32(skb, IFLA_TUN_GROUP, + from_kgid_munged(current_user_ns(), tun->group))) + goto nla_put_failure; + if (nla_put_u8(skb, IFLA_TUN_PI, !(tun->flags & IFF_NO_PI))) + goto nla_put_failure; + if (nla_put_u8(skb, IFLA_TUN_VNET_HDR, !!(tun->flags & IFF_VNET_HDR))) + goto nla_put_failure; + if (nla_put_u8(skb, IFLA_TUN_PERSIST, !!(tun->flags & IFF_PERSIST))) + goto nla_put_failure; + if (nla_put_u8(skb, IFLA_TUN_MULTI_QUEUE, + !!(tun->flags & IFF_MULTI_QUEUE))) + goto nla_put_failure; + if (tun->flags & IFF_MULTI_QUEUE) { + if (nla_put_u32(skb, IFLA_TUN_NUM_QUEUES, tun->numqueues)) + goto nla_put_failure; + if (nla_put_u32(skb, IFLA_TUN_NUM_DISABLED_QUEUES, + tun->numdisabled)) + goto nla_put_failure; + } + + return 0; + +nla_put_failure: + return -EMSGSIZE; } static struct rtnl_link_ops tun_link_ops __read_mostly = { @@ -1591,6 +2370,8 @@ static struct rtnl_link_ops tun_link_ops __read_mostly = { .priv_size = sizeof(struct tun_struct), .setup = tun_setup, .validate = tun_validate, + .get_size = tun_get_size, + .fill_info = tun_fill_info, }; static void tun_sock_write_space(struct sock *sk) @@ -1606,8 +2387,8 @@ static void tun_sock_write_space(struct sock *sk) wqueue = sk_sleep(sk); if (wqueue && waitqueue_active(wqueue)) - wake_up_interruptible_sync_poll(wqueue, POLLOUT | - POLLWRNORM | POLLWRBAND); + wake_up_interruptible_sync_poll(wqueue, EPOLLOUT | + EPOLLWRNORM | EPOLLWRBAND); tfile = container_of(sk, struct tun_file, sk); kill_fasync(&tfile->fasync, SIGIO, POLL_OUT); @@ -1617,13 +2398,14 @@ static int tun_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len) { int ret; struct tun_file *tfile = container_of(sock, struct tun_file, socket); - struct tun_struct *tun = __tun_get(tfile); + struct tun_struct *tun = tun_get(tfile); if (!tun) return -EBADFD; ret = tun_get_user(tun, tfile, m->msg_control, &m->msg_iter, - m->msg_flags & MSG_DONTWAIT); + m->msg_flags & MSG_DONTWAIT, + m->msg_flags & MSG_MORE); tun_put(tun); return ret; } @@ -1632,22 +2414,25 @@ static int tun_recvmsg(struct socket *sock, struct msghdr *m, size_t total_len, int flags) { struct tun_file *tfile = container_of(sock, struct tun_file, socket); - struct tun_struct *tun = __tun_get(tfile); + struct tun_struct *tun = tun_get(tfile); + void *ptr = m->msg_control; int ret; - if (!tun) - return -EBADFD; + if (!tun) { + ret = -EBADFD; + goto out_free; + } if (flags & ~(MSG_DONTWAIT|MSG_TRUNC|MSG_ERRQUEUE)) { ret = -EINVAL; - goto out; + goto out_put_tun; } if (flags & MSG_ERRQUEUE) { ret = sock_recv_errqueue(sock->sk, m, total_len, SOL_PACKET, TUN_TX_TIMESTAMP); goto out; } - ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT); + ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT, ptr); if (ret > (ssize_t)total_len) { m->msg_flags |= MSG_TRUNC; ret = flags & MSG_TRUNC ? ret : total_len; @@ -1655,6 +2440,26 @@ static int tun_recvmsg(struct socket *sock, struct msghdr *m, size_t total_len, out: tun_put(tun); return ret; + +out_put_tun: + tun_put(tun); +out_free: + tun_ptr_free(ptr); + return ret; +} + +static int tun_ptr_peek_len(void *ptr) +{ + if (likely(ptr)) { + if (tun_is_xdp_frame(ptr)) { + struct xdp_frame *xdpf = tun_ptr_to_xdp(ptr); + + return xdpf->len; + } + return __skb_array_len_with_tag(ptr); + } else { + return 0; + } } static int tun_peek_len(struct socket *sock) @@ -1663,11 +2468,11 @@ static int tun_peek_len(struct socket *sock) struct tun_struct *tun; int ret = 0; - tun = __tun_get(tfile); + tun = tun_get(tfile); if (!tun) return 0; - ret = skb_array_peek_len(&tfile->tx_array); + ret = PTR_RING_PEEK_CALL(&tfile->tx_ring, tun_ptr_peek_len); tun_put(tun); return ret; @@ -1743,6 +2548,15 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (tfile->detached) return -EINVAL; + if ((ifr->ifr_flags & IFF_NAPI_FRAGS)) { + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (!(ifr->ifr_flags & IFF_NAPI) || + (ifr->ifr_flags & TUN_TYPE_MASK) != IFF_TAP) + return -EINVAL; + } + dev = __dev_get_by_name(net, ifr->ifr_name); if (dev) { if (ifr->ifr_flags & IFF_TUN_EXCL) @@ -1764,7 +2578,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (err < 0) return err; - err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER); + err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER, + ifr->ifr_flags & IFF_NAPI, + ifr->ifr_flags & IFF_NAPI_FRAGS); if (err < 0) return err; @@ -1773,10 +2589,15 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) /* One or more queue has already been attached, no need * to initialize the device again. */ + netdev_state_change(dev); return 0; } - } - else { + + tun->flags = (tun->flags & ~TUN_FEATURES) | + (ifr->ifr_flags & TUN_FEATURES); + + netdev_state_change(dev); + } else { char *name; unsigned long flags = 0; int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ? @@ -1809,11 +2630,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (!dev) return -ENOMEM; -#if 0 err = dev_get_valid_name(net, dev, name); if (err < 0) goto err_free_dev; -#endif + dev_net_set(dev, net); dev->rtnl_link_ops = &tun_link_ops; dev->ifindex = tfile->ifindex; @@ -1828,6 +2648,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun->align = NET_SKB_PAD; tun->filter_attached = false; tun->sndbuf = tfile->socket.sk->sk_sndbuf; + tun->rx_batched = 0; + RCU_INIT_POINTER(tun->steering_prog, NULL); tun->pcpu_stats = netdev_alloc_pcpu_stats(struct tun_pcpu_stats); if (!tun->pcpu_stats) { @@ -1852,8 +2674,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX); + tun->flags = (tun->flags & ~TUN_FEATURES) | + (ifr->ifr_flags & TUN_FEATURES); + INIT_LIST_HEAD(&tun->disabled); - err = tun_attach(tun, file, false); + err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI, + ifr->ifr_flags & IFF_NAPI_FRAGS); if (err < 0) goto err_free_flow; @@ -1866,9 +2692,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun_debug(KERN_INFO, tun, "tun_set_iff\n"); - tun->flags = (tun->flags & ~TUN_FEATURES) | - (ifr->ifr_flags & TUN_FEATURES); - /* Make sure persistent devices do not get stuck in * xoff state. */ @@ -1880,6 +2703,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) err_detach: tun_detach_all(dev); + /* register_netdevice() already called tun_free_netdev() */ + goto err_free_dev; + err_free_flow: tun_flow_uninit(tun); security_tun_dev_free_security(tun->security); @@ -1923,10 +2749,7 @@ static int set_offload(struct tun_struct *tun, unsigned long arg) arg &= ~(TUN_F_TSO4|TUN_F_TSO6); } - if (arg & TUN_F_UFO) { - features |= NETIF_F_UFO; - arg &= ~TUN_F_UFO; - } + arg &= ~TUN_F_UFO; } /* This gives the user a way to test for new features in future by @@ -1935,6 +2758,8 @@ static int set_offload(struct tun_struct *tun, unsigned long arg) return -EINVAL; tun->set_features = features; + tun->dev->wanted_features &= ~TUN_USER_FEATURES; + tun->dev->wanted_features |= features; netdev_update_features(tun->dev); return 0; @@ -2003,7 +2828,8 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) ret = security_tun_dev_attach_queue(tun->security); if (ret < 0) goto unlock; - ret = tun_attach(tun, file, false); + ret = tun_attach(tun, file, false, tun->flags & IFF_NAPI, + tun->flags & IFF_NAPI_FRAGS); } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { tun = rtnl_dereference(tfile->tun); if (!tun || !(tun->flags & IFF_MULTI_QUEUE) || tfile->detached) @@ -2013,15 +2839,39 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) } else ret = -EINVAL; + if (ret >= 0) + netdev_state_change(tun->dev); + unlock: rtnl_unlock(); return ret; } +static int tun_set_ebpf(struct tun_struct *tun, struct tun_prog **prog_p, + void __user *data) +{ + struct bpf_prog *prog; + int fd; + + if (copy_from_user(&fd, data, sizeof(fd))) + return -EFAULT; + + if (fd == -1) { + prog = NULL; + } else { + prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_SOCKET_FILTER); + if (IS_ERR(prog)) + return PTR_ERR(prog); + } + + return __tun_set_ebpf(tun, prog_p, prog); +} + static long __tun_chr_ioctl(struct file *file, unsigned int cmd, unsigned long arg, int ifreq_len) { struct tun_file *tfile = file->private_data; + struct net *net = sock_net(&tfile->sk); struct tun_struct *tun; void __user* argp = (void __user*)arg; struct ifreq ifr; @@ -2032,8 +2882,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, unsigned int ifindex; int le; int ret; + bool do_notify = false; - if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == 0x89) { + if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || + (_IOC_TYPE(cmd) == SOCK_IOC_TYPE && cmd != SIOCGSKNS)) { if (copy_from_user(&ifr, argp, ifreq_len)) return -EFAULT; } else { @@ -2046,17 +2898,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, */ return put_user(IFF_TUN | IFF_TAP | TUN_FEATURES, (unsigned int __user*)argp); - } else if (cmd == TUNSETQUEUE) + } else if (cmd == TUNSETQUEUE) { return tun_set_queue(file, &ifr); + } else if (cmd == SIOCGSKNS) { + if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) + return -EPERM; + return open_related_ns(&net->ns, get_net_ns); + } ret = 0; rtnl_lock(); - tun = __tun_get(tfile); - if (cmd == TUNSETIFF && !tun) { + tun = tun_get(tfile); + if (cmd == TUNSETIFF) { + ret = -EEXIST; + if (tun) + goto unlock; + ifr.ifr_name[IFNAMSIZ-1] = '\0'; - ret = tun_set_iff(sock_net(&tfile->sk), file, &ifr); + ret = tun_set_iff(net, file, &ifr); if (ret) goto unlock; @@ -2114,10 +2975,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, if (arg && !(tun->flags & IFF_PERSIST)) { tun->flags |= IFF_PERSIST; __module_get(THIS_MODULE); + do_notify = true; } if (!arg && (tun->flags & IFF_PERSIST)) { tun->flags &= ~IFF_PERSIST; module_put(THIS_MODULE); + do_notify = true; } tun_debug(KERN_INFO, tun, "persist %s\n", @@ -2132,6 +2995,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, break; } tun->owner = owner; + do_notify = true; tun_debug(KERN_INFO, tun, "owner set to %u\n", from_kuid(&init_user_ns, tun->owner)); break; @@ -2144,6 +3008,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, break; } tun->group = group; + do_notify = true; tun_debug(KERN_INFO, tun, "group set to %u\n", from_kgid(&init_user_ns, tun->group)); break; @@ -2290,11 +3155,22 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, ret = 0; break; + case TUNSETSTEERINGEBPF: + ret = tun_set_ebpf(tun, &tun->steering_prog, argp); + break; + + case TUNSETFILTEREBPF: + ret = tun_set_ebpf(tun, &tun->filter_prog, argp); + break; + default: ret = -EINVAL; break; } + if (do_notify) + netdev_state_change(tun->dev); + unlock: rtnl_unlock(); if (tun) @@ -2346,7 +3222,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on) goto out; if (on) { - __f_setown(file, task_pid(current), PIDTYPE_PID, 0); + __f_setown(file, task_pid(current), PIDTYPE_TGID, 0); tfile->flags |= TUN_FASYNC; } else tfile->flags &= ~TUN_FASYNC; @@ -2366,6 +3242,12 @@ static int tun_chr_open(struct inode *inode, struct file * file) &tun_proto, 0); if (!tfile) return -ENOMEM; + if (ptr_ring_init(&tfile->tx_ring, 0, GFP_KERNEL)) { + sk_free(&tfile->sk); + return -ENOMEM; + } + + mutex_init(&tfile->napi_mutex); RCU_INIT_POINTER(tfile->tun, NULL); tfile->flags = 0; tfile->ifindex = 0; @@ -2386,8 +3268,6 @@ static int tun_chr_open(struct inode *inode, struct file * file) sock_set_flag(&tfile->sk, SOCK_ZEROCOPY); - memset(&tfile->tx_array, 0, sizeof(tfile->tx_array)); - return 0; } @@ -2401,15 +3281,16 @@ static int tun_chr_close(struct inode *inode, struct file *file) } #ifdef CONFIG_PROC_FS -static void tun_chr_show_fdinfo(struct seq_file *m, struct file *f) +static void tun_chr_show_fdinfo(struct seq_file *m, struct file *file) { + struct tun_file *tfile = file->private_data; struct tun_struct *tun; struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); rtnl_lock(); - tun = tun_get(f); + tun = tun_get(tfile); if (tun) tun_get_iff(current->nsproxy->net_ns, tun, &ifr); rtnl_unlock(); @@ -2440,7 +3321,7 @@ static const struct file_operations tun_fops = { }; static struct miscdevice tun_miscdev = { - .minor = TUN_MINOR1, + .minor = BF_TUN_MINOR, .name = "bf_tun", .nodename = "net/bf_tun", .fops = &tun_fops, @@ -2448,18 +3329,33 @@ static struct miscdevice tun_miscdev = { /* ethtool interface */ -static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - cmd->supported = 0; - cmd->advertising = 0; - ethtool_cmd_speed_set(cmd, SPEED_10); - cmd->duplex = DUPLEX_FULL; - cmd->port = PORT_TP; - cmd->phy_address = 0; - cmd->transceiver = XCVR_INTERNAL; - cmd->autoneg = AUTONEG_DISABLE; - cmd->maxtxpkt = 0; - cmd->maxrxpkt = 0; +static void tun_default_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *cmd) +{ + ethtool_link_ksettings_zero_link_mode(cmd, supported); + ethtool_link_ksettings_zero_link_mode(cmd, advertising); + cmd->base.speed = SPEED_10; + cmd->base.duplex = DUPLEX_FULL; + cmd->base.port = PORT_TP; + cmd->base.phy_address = 0; + cmd->base.autoneg = AUTONEG_DISABLE; +} + +static int tun_get_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *cmd) +{ + struct tun_struct *tun = netdev_priv(dev); + + memcpy(cmd, &tun->link_ksettings, sizeof(*cmd)); + return 0; +} + +static int tun_set_link_ksettings(struct net_device *dev, + const struct ethtool_link_ksettings *cmd) +{ + struct tun_struct *tun = netdev_priv(dev); + + memcpy(&tun->link_ksettings, cmd, sizeof(*cmd)); return 0; } @@ -2498,38 +3394,65 @@ static void tun_set_msglevel(struct net_device *dev, u32 value) #endif } +static int tun_get_coalesce(struct net_device *dev, + struct ethtool_coalesce *ec) +{ + struct tun_struct *tun = netdev_priv(dev); + + ec->rx_max_coalesced_frames = tun->rx_batched; + + return 0; +} + +static int tun_set_coalesce(struct net_device *dev, + struct ethtool_coalesce *ec) +{ + struct tun_struct *tun = netdev_priv(dev); + + if (ec->rx_max_coalesced_frames > NAPI_POLL_WEIGHT) + tun->rx_batched = NAPI_POLL_WEIGHT; + else + tun->rx_batched = ec->rx_max_coalesced_frames; + + return 0; +} + static const struct ethtool_ops tun_ethtool_ops = { - .get_settings = tun_get_settings, .get_drvinfo = tun_get_drvinfo, .get_msglevel = tun_get_msglevel, .set_msglevel = tun_set_msglevel, .get_link = ethtool_op_get_link, .get_ts_info = ethtool_op_get_ts_info, + .get_coalesce = tun_get_coalesce, + .set_coalesce = tun_set_coalesce, + .get_link_ksettings = tun_get_link_ksettings, + .set_link_ksettings = tun_set_link_ksettings, }; static int tun_queue_resize(struct tun_struct *tun) { struct net_device *dev = tun->dev; struct tun_file *tfile; - struct skb_array **arrays; + struct ptr_ring **rings; int n = tun->numqueues + tun->numdisabled; int ret, i; - arrays = kmalloc(sizeof *arrays * n, GFP_KERNEL); - if (!arrays) + rings = kmalloc_array(n, sizeof(*rings), GFP_KERNEL); + if (!rings) return -ENOMEM; for (i = 0; i < tun->numqueues; i++) { tfile = rtnl_dereference(tun->tfiles[i]); - arrays[i] = &tfile->tx_array; + rings[i] = &tfile->tx_ring; } list_for_each_entry(tfile, &tun->disabled, next) - arrays[i++] = &tfile->tx_array; + rings[i++] = &tfile->tx_ring; - ret = skb_array_resize_multiple(arrays, n, - dev->tx_queue_len, GFP_KERNEL); + ret = ptr_ring_resize_multiple(rings, n, + dev->tx_queue_len, GFP_KERNEL, + tun_ptr_free); - kfree(arrays); + kfree(rings); return ret; } @@ -2538,6 +3461,7 @@ static int tun_device_event(struct notifier_block *unused, { struct net_device *dev = netdev_notifier_info_to_dev(ptr); struct tun_struct *tun = netdev_priv(dev); + int i; if (dev->rtnl_link_ops != &tun_link_ops) return NOTIFY_DONE; @@ -2547,6 +3471,14 @@ static int tun_device_event(struct notifier_block *unused, if (tun_queue_resize(tun)) return NOTIFY_BAD; break; + case NETDEV_UP: + for (i = 0; i < tun->numqueues; i++) { + struct tun_file *tfile; + + tfile = rtnl_dereference(tun->tfiles[i]); + tfile->socket.sk->sk_write_space(tfile->socket.sk); + } + break; default: break; } @@ -2563,7 +3495,6 @@ static int __init tun_init(void) int ret = 0; pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); - pr_info("%s\n", DRV_COPYRIGHT); ret = rtnl_link_register(&tun_link_ops); if (ret) { @@ -2573,12 +3504,20 @@ static int __init tun_init(void) ret = misc_register(&tun_miscdev); if (ret) { - pr_err("Can't register misc device %d\n", TUN_MINOR1); + pr_err("Can't register misc device %d\n", BF_TUN_MINOR); goto err_misc; } - register_netdevice_notifier(&tun_notifier_block); + ret = register_netdevice_notifier(&tun_notifier_block); + if (ret) { + pr_err("Can't register netdevice notifier\n"); + goto err_notifier; + } + return 0; + +err_notifier: + misc_deregister(&tun_miscdev); err_misc: rtnl_link_unregister(&tun_link_ops); err_linkops: @@ -2608,10 +3547,23 @@ struct socket *tun_get_socket(struct file *file) } EXPORT_SYMBOL_GPL(tun_get_socket); +struct ptr_ring *tun_get_tx_ring(struct file *file) +{ + struct tun_file *tfile; + + if (file->f_op != &tun_fops) + return ERR_PTR(-EINVAL); + tfile = file->private_data; + if (!tfile) + return ERR_PTR(-EBADFD); + return &tfile->tx_ring; +} +EXPORT_SYMBOL_GPL(tun_get_tx_ring); + module_init(tun_init); module_exit(tun_cleanup); MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(TUN_MINOR1); +MODULE_ALIAS_MISCDEV(BF_TUN_MINOR); MODULE_ALIAS("devname:net/bf_tun"); diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index 0147b62d00a1..31abd3f96c99 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -8,7 +8,7 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_NEWPORT_PLATFORM_MODULE) -$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) +#$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9280_64X_PLATFORM_MODULE) ifeq ($(INSTALL_DEBUG_TOOLS),y) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index e9294dd81399..b94939228692 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -2,7 +2,7 @@ include $(PLATFORM_PATH)/platform-modules-arista.mk include $(PLATFORM_PATH)/platform-modules-bfn.mk include $(PLATFORM_PATH)/platform-modules-bfn-montara.mk include $(PLATFORM_PATH)/platform-modules-bfn-newport.mk -include $(PLATFORM_PATH)/platform-modules-wnc-osw1800.mk +#include $(PLATFORM_PATH)/platform-modules-wnc-osw1800.mk include $(PLATFORM_PATH)/platform-modules-ingrasys.mk include $(PLATFORM_PATH)/bfn-sai.mk include $(PLATFORM_PATH)/docker-syncd-bfn.mk @@ -20,11 +20,13 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_ONE_ABOOT) \ $(DOCKER_FPM) # Inject sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +#$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) ifeq ($(ENABLE_SYNCD_RPC),y) $(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on sai is set only for syncd -$(SYNCD)_RDEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +#$(SYNCD)_RDEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) From e3be45f2da025a8cbf7fe6f8dc5796dd1cea787d Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Tue, 12 May 2020 14:49:15 -0700 Subject: [PATCH 0649/1427] [sonic-buildimage] updated minigraph for ACL Table data and ACL Interface Binding for Multi-NPU platforms (#4491) * [sonic-buildimage] updated minigraph for ACL Table data and ACL Interface binding update for multu-npu platform based on subrole as "Frontend" or "Backend". For backend npu no ACL table is associated. For frontend npu only front-panel interface are associated. Updated with test case and fix typo in sample-mingraph for npu Address Review comments Signed-off-by: Abhishek Dosi * Fixed the logic as per preview comment. Interface Filter logic only applies to Everflow/Mirror tables. * Address Review Comments. --- src/sonic-config-engine/minigraph.py | 66 +++++++++++++++---- .../tests/multi_npu_data/sample-minigraph.xml | 4 +- .../tests/test_multinpu_cfggen.py | 25 +++++++ 3 files changed, 80 insertions(+), 15 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index fb462dada594..1f99bb16c8cd 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -35,7 +35,11 @@ VLAN_SUB_INTERFACE_SEPARATOR = '.' VLAN_SUB_INTERFACE_VLAN_ID = '10' -# Default Virtual Network Index (VNI) +FRONTEND_ASIC_SUB_ROLE = 'FrontEnd' +BACKEND_ASIC_SUB_ROLE = 'BackEnd' +BACKEND_ASIC_INTERFACE_NAME_PREFIX = 'Ethernet-BP' + +# Default Virtual Network Index (VNI) vni_default = 8000 ############################################################################### @@ -401,7 +405,9 @@ def parse_dpg(dpg, hname): # later after the rest of the minigraph has been parsed. acl_intfs = pc_intfs[:] for panel_port in port_alias_map.values(): - if panel_port not in intfs_inpc: + # because of port_alias_asic_map we can have duplicate in port_alias_map + # so check if already present do not add + if panel_port not in intfs_inpc and panel_port not in acl_intfs: acl_intfs.append(panel_port) break if acl_intfs: @@ -687,27 +693,61 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m # ############################################################################### -def filter_acl_mirror_table_bindings(acls, neighbors, port_channels): - """ - Filters out inactive front-panel ports from the binding list for mirror - ACL tables. We define an "active" port as one that is a member of a - port channel or one that is connected to a neighboring device. - """ +def filter_acl_table_bindings(acls, neighbors, port_channels, sub_role): + filter_acls = {} + + # If the asic role is BackEnd no ACL Table (Ctrl/Data/Everflow) is binded. + # This will be applicable in Multi-NPU Platforms. + + if sub_role == BACKEND_ASIC_SUB_ROLE: + return filter_acls + + front_port_channel_intf = [] + + # Get the front panel port channel. It will use port_alias_asic_map + # which will get populated from port_config.ini for Multi-NPU + # architecture + for port_channel_intf in port_channels: + backend_port_channel = any(lag_member in port_alias_asic_map \ + and lag_member.startswith(BACKEND_ASIC_INTERFACE_NAME_PREFIX) \ + for lag_member in port_channels[port_channel_intf]['members']) + if not backend_port_channel: + front_port_channel_intf.append(port_channel_intf) for acl_table, group_params in acls.iteritems(): group_type = group_params.get('type', None) + filter_acls[acl_table] = acls[acl_table] + # For Control Plane and Data ACL no filtering is needed + # Control Plane ACL has no Interface associated and + # Data Plane ACL Interface are attached via minigraph + # AclInterface. if group_type != 'MIRROR' and group_type != 'MIRRORV6': continue - active_ports = [ port for port in group_params.get('ports', []) if port in neighbors.keys() or port in port_channels ] - + # Filters out back-panel ports from the binding list for Everflow (Mirror) + # ACL tables. We define an "back-panel" port as one that is a member of a + # port channel connected to back asic or directly connected to back asic. + # This will be applicable in Multi-NPU Platforms. + front_panel_ports = [] + for port in group_params.get('ports', []): + if port in port_alias_asic_map and port.startswith(BACKEND_ASIC_INTERFACE_NAME_PREFIX): + continue + if port in port_channels and port not in front_port_channel_intf: + continue + front_panel_ports.append(port) + + # Filters out inactive front-panel ports from the binding list for mirror + # ACL tables. We define an "active" port as one that is a member of a + # front pannel port channel or one that is connected to a neighboring device via front panel port. + active_ports = [port for port in front_panel_ports if port in neighbors.keys() or port in front_port_channel_intf] + if not active_ports: print >> sys.stderr, 'Warning: mirror table {} in ACL_TABLE does not have any ports bound to it'.format(acl_table) - acls[acl_table]['ports'] = active_ports + filter_acls[acl_table]['ports'] = active_ports - return acls + return filter_acls ############################################################################### # @@ -1020,7 +1060,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers) results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers) results['TACPLUS_SERVER'] = dict((item, {'priority': '1', 'tcp_port': '49'}) for item in tacacs_servers) - results['ACL_TABLE'] = filter_acl_mirror_table_bindings(acls, neighbors, pcs) + results['ACL_TABLE'] = filter_acl_table_bindings(acls, neighbors, pcs, sub_role) results['FEATURE'] = { 'telemetry': { 'status': 'enabled' diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml index 118202d9b52e..8ca17925c6ec 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml +++ b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml @@ -650,14 +650,14 @@ 05T2 Ethernet1 multi_npu_platform_01 - Ethernet1/8 + Ethernet1/5
DeviceInterfaceLink 05T2 Ethernet2 multi_npu_platform_01 - Ethernet1/9 + Ethernet1/6 DeviceInterfaceLink diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 4aefbb78fc61..0ef29eb6d9b4 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -220,3 +220,28 @@ def test_device_asic_metadata(self): self.assertEqual(output['localhost']['sub_role'], 'FrontEnd') else: self.assertEqual(output['localhost']['sub_role'], 'BackEnd') + + def test_global_asic_acl(self): + argument = "-m {} --var-json \"ACL_TABLE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + 'DATAACL': {'policy_desc': 'DATAACL', 'ports': ['PortChannel0002','PortChannel0008'], 'stage': 'ingress', 'type': 'L3'}, + 'EVERFLOW': {'policy_desc': 'EVERFLOW', 'ports': ['PortChannel0002','PortChannel0008'], 'stage': 'ingress', 'type': 'MIRROR'}, + 'EVERFLOWV6':{'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel0002','PortChannel0008'], 'stage': 'ingress', 'type': 'MIRRORV6'}, + 'SNMP_ACL': {'policy_desc': 'SNMP_ACL', 'services': ['SNMP'], 'stage': 'ingress', 'type': 'CTRLPLANE'}, + 'SSH_ONLY': {'policy_desc': 'SSH_ONLY', 'services': ['SSH'], 'stage': 'ingress', 'type': 'CTRLPLANE'}}) + + def test_front_end_asic_acl(self): + argument = "-m {} -p {} -n asic0 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + 'DATAACL': {'policy_desc': 'DATAACL', 'ports': ['PortChannel0002'], 'stage': 'ingress', 'type': 'L3'}, + 'EVERFLOW': {'policy_desc': 'EVERFLOW', 'ports': ['PortChannel0002'], 'stage': 'ingress', 'type': 'MIRROR'}, + 'EVERFLOWV6':{'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel0002'], 'stage': 'ingress', 'type': 'MIRRORV6'}, + 'SNMP_ACL': {'policy_desc': 'SNMP_ACL', 'services': ['SNMP'], 'stage': 'ingress', 'type': 'CTRLPLANE'}, + 'SSH_ONLY': {'policy_desc': 'SSH_ONLY', 'services': ['SSH'], 'stage': 'ingress', 'type': 'CTRLPLANE'}}) + + def test_back_end_asic_acl(self): + argument = "-m {} -p {} -n asic3 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {}) From 5fe2216ea34aec6c86685a10ba3752a0d4c20a33 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Tue, 12 May 2020 14:49:56 -0700 Subject: [PATCH 0650/1427] Fix for issue where image is compile with flag ENABLE_DHCP_GRAPH_SERVICE (#4573) and then we load image and reboot even if there was existing config_db.json we will look for DHCP Service. we should disbale update_graph in such cases. This behaviour is silimar to what we have in 201811 image. --- files/image_config/config-setup/config-setup | 2 ++ 1 file changed, 2 insertions(+) diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index afff97806518..0b385028a21f 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -310,6 +310,8 @@ do_config_migration() # Migrate the DB to the latest schema version if needed /usr/bin/db_migrator.py -o migrate fi + # Disable updategraph + disable_updategraph elif [ -r ${MINGRAPH_FILE} ]; then echo "Use minigraph.xml from old system..." reload_minigraph From 60a0471aa5493e3009844138d2617e671c4463d7 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Tue, 12 May 2020 17:27:56 -0700 Subject: [PATCH 0651/1427] Advance sonic-py-swsssdk pointer (#4496) --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index b9cee360c2a1..03748ce070d9 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit b9cee360c2a1b64f46dbc035579bd7cbd9959878 +Subproject commit 03748ce070d9ca4b827e9fc679a18983a7656f1c From 5150e7b6555f107a281302c47c9fdd13bacaa8b0 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 12 May 2020 18:16:55 -0700 Subject: [PATCH 0652/1427] [caclmgrd] Ignore keys in interface-related tables if no IP prefix is present (#4581) Since the introduction of VRF, interface-related tables in ConfigDB will have multiple entries, one of which only contains the interface name and no IP prefix. Thus, when iterating over the keys in the tables, we need to ignore the entries which do not contain IP prefixes. --- files/image_config/caclmgrd/caclmgrd | 34 ++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 16e8bda4f40b..b2fc3c92a0c0 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -44,6 +44,15 @@ def log_error(msg): syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() +# ========================== Helper Functions ========================= + +def _ip_prefix_in_key(key): + """ + Function to check if IP prefix is present in a Redis database key. + If it is present, then the key will be a tuple. Otherwise, the + key will be a string. + """ + return (isinstance(key, tuple)) # ============================== Classes ============================== @@ -136,7 +145,10 @@ class ControlPlaneAclManager(object): # Add iptables rules to drop all packets destined for loopback interface IP addresses loopback_iface_table = self.config_db.get_table(LOOPBACK_INTERFACE_TABLE_NAME) if loopback_iface_table: - for ((iface_name, iface_cidr), _) in loopback_iface_table.iteritems(): + for key, _ in loopback_iface_table.iteritems(): + if not _ip_prefix_in_key(key): + continue + iface_name, iface_cidr = key ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) if isinstance(ip_ntwrk, ipaddress.IPv4Network): block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) @@ -148,7 +160,10 @@ class ControlPlaneAclManager(object): # Add iptables rules to drop all packets destined for management interface IP addresses mgmt_iface_table = self.config_db.get_table(MGMT_INTERFACE_TABLE_NAME) if mgmt_iface_table: - for ((iface_name, iface_cidr), _) in mgmt_iface_table.iteritems(): + for key, _ in mgmt_iface_table.iteritems(): + if not _ip_prefix_in_key(key): + continue + iface_name, iface_cidr = key ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) if isinstance(ip_ntwrk, ipaddress.IPv4Network): block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) @@ -160,7 +175,10 @@ class ControlPlaneAclManager(object): # Add iptables rules to drop all packets destined for our VLAN interface gateway IP addresses vlan_iface_table = self.config_db.get_table(VLAN_INTERFACE_TABLE_NAME) if vlan_iface_table: - for ((iface_name, iface_cidr), _) in vlan_iface_table.iteritems(): + for key, _ in vlan_iface_table.iteritems(): + if not _ip_prefix_in_key(key): + continue + iface_name, iface_cidr = key ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) if isinstance(ip_ntwrk, ipaddress.IPv4Network): block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(list(ip_ntwrk.hosts())[0], ip_ntwrk.max_prefixlen)) @@ -173,7 +191,10 @@ class ControlPlaneAclManager(object): # (All portchannel interfaces and configured front-panel interfaces) portchannel_iface_table = self.config_db.get_table(PORTCHANNEL_INTERFACE_TABLE_NAME) if portchannel_iface_table: - for ((iface_name, iface_cidr), _) in portchannel_iface_table.iteritems(): + for key, _ in portchannel_iface_table.iteritems(): + if not _ip_prefix_in_key(key): + continue + iface_name, iface_cidr = key ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) if isinstance(ip_ntwrk, ipaddress.IPv4Network): block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) @@ -184,7 +205,10 @@ class ControlPlaneAclManager(object): iface_table = self.config_db.get_table(INTERFACE_TABLE_NAME) if iface_table: - for ((iface_name, iface_cidr), _) in iface_table.iteritems(): + for key, _ in iface_table.iteritems(): + if not _ip_prefix_in_key(key): + continue + iface_name, iface_cidr = key ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) if isinstance(ip_ntwrk, ipaddress.IPv4Network): block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) From d3c28a45d9a76c21cd071b420341d13a753d4cbe Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Wed, 13 May 2020 08:56:01 -0700 Subject: [PATCH 0653/1427] Change to enable redistribute connected on Frontend asics instead of backend asics (#4588) Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index a29569191651..503c37e9be14 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -62,7 +62,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endblock vlan_advertisement %} ! ! -{% if DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} +{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %} redistribute connected route-map HIDE_INTERNAL {% endif %} ! From 5e6c20481d3396acd87565a3e9f0b918eaeade1f Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Thu, 14 May 2020 01:01:32 +0800 Subject: [PATCH 0654/1427] [Mellanox] Enhancement for fan led management (#4437) --- .../thermal_policy.json | 1 + .../thermal_policy.json | 1 + .../thermal_policy.json | 1 + .../sonic_platform/chassis.py | 49 ++--- .../sonic_platform/device_data.py | 159 ++++++++++++++ .../mlnx-platform-api/sonic_platform/fan.py | 138 ++---------- .../sonic_platform/fan_drawer.py | 104 +++++++++ .../mlnx-platform-api/sonic_platform/led.py | 201 ++++++++++++++++++ .../mlnx-platform-api/sonic_platform/psu.py | 133 +++--------- .../sonic_platform/thermal.py | 4 +- .../mlnx-platform-api/tests/mock_platform.py | 4 + .../mlnx-platform-api/tests/test_fan_api.py | 46 +++- src/sonic-platform-common | 2 +- 13 files changed, 593 insertions(+), 250 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/thermal_policy.json create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/thermal_policy.json create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/thermal_policy.json create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/led.py diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn3420-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn4700-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 5ecf3c150de9..2e9ad7210ab8 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -12,10 +12,10 @@ from sonic_platform_base.chassis_base import ChassisBase from sonic_platform_base.component_base import ComponentBase from sonic_device_util import get_machine_info + from sonic_device_util import get_platform_info from sonic_daemon_base.daemon_base import Logger from os import listdir from os.path import isfile, join - from glob import glob import sys import io import re @@ -61,12 +61,14 @@ def __init__(self): # Initialize SKU name self.sku_name = self._get_sku_name() - self.platform_name = self._get_platform_name() + mi = get_machine_info() if mi is not None: self.name = mi['onie_platform'] + self.platform_name = get_platform_info(mi) else: self.name = self.sku_name + self.platform_name = self._get_platform_name() # move the initialization of each components to their dedicated initializer # which will be called from platform @@ -86,36 +88,29 @@ def initialize_psu(self): # Initialize PSU list self.psu_module = Psu for index in range(MLNX_NUM_PSU): - psu = Psu(index, self.sku_name) + psu = Psu(index, self.platform_name) self._psu_list.append(psu) def initialize_fan(self): + from .device_data import DEVICE_DATA from sonic_platform.fan import Fan - from sonic_platform.fan import FAN_PATH - self.fan_module = Fan - self.fan_path = FAN_PATH - # Initialize FAN list - multi_rotor_in_drawer = False - num_of_fan, num_of_drawer = self._extract_num_of_fans_and_fan_drawers() - multi_rotor_in_drawer = num_of_fan > num_of_drawer - - # Fan's direction isn't supported on spectrum 1 devices for now - mst_dev_list = glob(MST_DEVICE_NAME_PATTERN) - if not mst_dev_list: - raise RuntimeError("Can't get chip type due to {} not found".format(MST_DEVICE_NAME_PATTERN)) - m = re.search(MST_DEVICE_RE_PATTERN, mst_dev_list[0]) - if m.group(1) == SPECTRUM1_CHIP_ID: - has_fan_dir = False - else: - has_fan_dir = True - - for index in range(num_of_fan): - if multi_rotor_in_drawer: - fan = Fan(has_fan_dir, index, index/2, False, self.platform_name) - else: - fan = Fan(has_fan_dir, index, index, False, self.platform_name) - self._fan_list.append(fan) + from .fan_drawer import RealDrawer, VirtualDrawer + + fan_data = DEVICE_DATA[self.platform_name]['fans'] + drawer_num = fan_data['drawer_num'] + drawer_type = fan_data['drawer_type'] + fan_num_per_drawer = fan_data['fan_num_per_drawer'] + drawer_ctor = RealDrawer if drawer_type == 'real' else VirtualDrawer + fan_index = 0 + for drawer_index in range(drawer_num): + drawer = drawer_ctor(drawer_index, fan_data) + self._fan_drawer_list.append(drawer) + for index in range(fan_num_per_drawer): + fan = Fan(fan_index, drawer) + fan_index += 1 + drawer._fan_list.append(fan) + self._fan_list.append(fan) def initialize_sfp(self): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py index 35b1f14d5bf9..fd3c7ad50e23 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py @@ -5,6 +5,19 @@ "unk_trust": {"-127:30":13, "31:40":14 , "41:120":15}, "unk_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16} } + }, + 'fans': { + 'drawer_num': 4, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': False, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 } }, 'x86_64-mlnx_msn2740-r0': { @@ -13,6 +26,19 @@ "unk_trust": {"-127:120":13}, "unk_untrust": {"-127:15":13, "16:25":14 , "26:30":15, "31:120":17}, } + }, + 'fans': { + 'drawer_num': 4, + 'drawer_type': 'real', + 'fan_num_per_drawer': 1, + 'support_fan_direction': False, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 } }, 'x86_64-mlnx_msn2100-r0': { @@ -21,6 +47,19 @@ "unk_trust": {"-127:40":12, "41:120":13}, "unk_untrust": {"-127:15":12, "16:25":13, "26:30":14, "31:35":15, "36:120":16} } + }, + 'fans': { + 'drawer_num': 1, + 'drawer_type': 'virtual', + 'fan_num_per_drawer': 4, + 'support_fan_direction': False, + 'hot_swappable': False + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': False, + 'led_num': 2 } }, 'x86_64-mlnx_msn2410-r0': { @@ -29,6 +68,19 @@ "unk_trust": {"-127:30":13, "31:40":14 , "41:120":15}, "unk_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16} } + }, + 'fans': { + 'drawer_num': 4, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': False, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 } }, 'x86_64-mlnx_msn2010-r0': { @@ -37,6 +89,19 @@ "unk_trust": {"-127:120":12}, "unk_untrust": {"-127:15":12, "16:20":13 , "21:30":14, "31:35":15, "36:120":16} } + }, + 'fans': { + 'drawer_num': 1, + 'drawer_type': 'virtual', + 'fan_num_per_drawer': 4, + 'support_fan_direction': False, + 'hot_swappable': False + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': False, + 'led_num': 2 } }, 'x86_64-mlnx_msn3700-r0': { @@ -45,6 +110,19 @@ "unk_trust": {"-127:25":12, "26:40":13 , "41:120":14}, "unk_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, } + }, + 'fans': { + 'drawer_num': 6, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 } }, 'x86_64-mlnx_msn3700c-r0': { @@ -53,6 +131,19 @@ "unk_trust": {"-127:40":12, "41:120":13}, "unk_untrust": {"-127:10":12, "11:20":13 , "21:30":14, "31:35":15, "36:120":16}, } + }, + 'fans': { + 'drawer_num': 4, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 } }, 'x86_64-mlnx_msn3800-r0': { @@ -61,14 +152,82 @@ "unk_trust": {"-127:30":12, "31:40":13 , "41:120":14}, "unk_untrust": {"-127:0":12, "1:10":13 , "11:15":14, "16:20":15, "21:35":16, "36:120":17}, } + }, + 'fans': { + 'drawer_num': 3, + 'drawer_type': 'real', + 'fan_num_per_drawer': 1, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 } }, 'x86_64-mlnx_msn4700-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:120":16}, + "unk_untrust": {"-127:120":16}, + } + }, + 'fans': { + 'drawer_num': 6, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + }, + 'x86_64-mlnx_msn3420-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:120":16}, + "unk_untrust": {"-127:120":16}, + } + }, + 'fans': { + 'drawer_num': 5, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + }, + 'x86_64-mlnx_msn4600c-r0': { 'thermal': { 'minimum_table': { "unk_trust": {"-127:120":16}, "unk_untrust": {"-127:120":16}, } + }, + 'fans': { + 'drawer_num': 3, + 'drawer_type': 'real', + 'fan_num_per_drawer': 1, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 } } } \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py index adca48befbc6..d123b6c6c3a3 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py @@ -13,25 +13,18 @@ try: from sonic_platform_base.fan_base import FanBase + from .led import FanLed, ComponentFaultyIndicator except ImportError as e: raise ImportError (str(e) + "- required module not found") -LED_ON = '1' -LED_OFF = '0' - PWM_MAX = 255 FAN_PATH = "/var/run/hw-management/thermal/" -LED_PATH = "/var/run/hw-management/led/" CONFIG_PATH = "/var/run/hw-management/config" # fan_dir isn't supported on Spectrum 1. It is supported on Spectrum 2 and later switches FAN_DIR = "/var/run/hw-management/system/fan_dir" COOLING_STATE_PATH = "/var/run/hw-management/thermal/cooling_cur_state" -# Platforms with unplugable FANs: -# 1. don't have fanX_status and should be treated as always present -platform_with_unplugable_fan = ['x86_64-mlnx_msn2010-r0', 'x86_64-mlnx_msn2100-r0'] - class Fan(FanBase): """Platform-specific Fan class""" @@ -44,21 +37,28 @@ class Fan(FanBase): PSU_FAN_SPEED = ['0x3c', '0x3c', '0x3c', '0x3c', '0x3c', '0x3c', '0x3c', '0x46', '0x50', '0x5a', '0x64'] - def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False, platform = None): + def __init__(self, fan_index, fan_drawer, psu_fan = False): + super(Fan, self).__init__() + # API index is starting from 0, Mellanox platform index is starting from 1 self.index = fan_index + 1 - self.drawer_index = drawer_index + 1 + self.fan_drawer = fan_drawer self.is_psu_fan = psu_fan - self.always_presence = False if platform not in platform_with_unplugable_fan else True + if self.fan_drawer: + self.led = ComponentFaultyIndicator(self.fan_drawer.get_led()) + elif self.is_psu_fan: + from .psu import Psu + self.led = ComponentFaultyIndicator(Psu.get_shared_led()) + else: + self.led = FanLed(self.index) self.fan_min_speed_path = "fan{}_min".format(self.index) if not self.is_psu_fan: self.fan_speed_get_path = "fan{}_speed_get".format(self.index) self.fan_speed_set_path = "fan{}_speed_set".format(self.index) - self.fan_presence_path = "fan{}_status".format(self.drawer_index) self.fan_max_speed_path = "fan{}_max".format(self.index) - self._name = "fan{}".format(fan_index + 1) + self._name = "fan{}".format(self.index) else: self.fan_speed_get_path = "psu{}_fan1_speed_get".format(self.index) self.fan_presence_path = "psu{}_fan1_speed_get".format(self.index) @@ -69,15 +69,7 @@ def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False, pl self.psu_i2c_command_path = os.path.join(CONFIG_PATH, 'fan_command') self.fan_status_path = "fan{}_fault".format(self.index) - self.fan_green_led_path = "led_fan{}_green".format(self.drawer_index) - self.fan_red_led_path = "led_fan{}_red".format(self.drawer_index) - self.fan_orange_led_path = "led_fan{}_orange".format(self.drawer_index) self.fan_pwm_path = "pwm1" - self.fan_led_cap_path = "led_fan{}_capability".format(self.drawer_index) - if has_fan_dir: - self.fan_dir = FAN_DIR - else: - self.fan_dir = None def get_direction(self): @@ -99,20 +91,10 @@ def get_direction(self): 1 stands for forward, in other words intake 0 stands for reverse, in other words exhaust """ - if not self.fan_dir or self.is_psu_fan or not self.get_presence(): + if self.is_psu_fan: return self.FAN_DIRECTION_NOT_APPLICABLE - - try: - with open(os.path.join(self.fan_dir), 'r') as fan_dir: - fan_dir_bits = int(fan_dir.read().strip()) - fan_mask = 1 << self.drawer_index - 1 - if fan_dir_bits & fan_mask: - return self.FAN_DIRECTION_INTAKE - else: - return self.FAN_DIRECTION_EXHAUST - except (ValueError, IOError) as e: - raise RuntimeError("Failed to read fan direction status to {}".format(repr(e))) - + else: + return self.fan_drawer.get_direction() def get_name(self): return self._name @@ -150,17 +132,9 @@ def get_presence(self): status = 1 else: status = 0 + return status == 1 else: - if self.always_presence: - status = 1 - else: - try: - with open(os.path.join(FAN_PATH, self.fan_presence_path), 'r') as presence_status: - status = int(presence_status.read().strip()) - except (ValueError, IOError): - status = 0 - - return status == 1 + return self.fan_drawer.get_presence() def _get_min_speed_in_rpm(self): @@ -281,18 +255,6 @@ def set_speed(self, speed): return status - def _get_led_capability(self): - cap_list = None - try: - with open(os.path.join(LED_PATH, self.fan_led_cap_path), 'r') as fan_led_cap: - caps = fan_led_cap.read() - cap_list = caps.split() - except (ValueError, IOError): - status = 0 - - return cap_list - - def set_status_led(self, color): """ Set led to expected color @@ -304,48 +266,7 @@ def set_status_led(self, color): Returns: bool: True if set success, False if fail. """ - led_cap_list = self._get_led_capability() - if led_cap_list is None: - return False - - if self.is_psu_fan: - # PSU fan led status is not able to set - return False - status = False - try: - if color == self.STATUS_LED_COLOR_GREEN: - with open(os.path.join(LED_PATH, self.fan_green_led_path), 'w') as fan_led: - fan_led.write(LED_ON) - status = True - elif color == self.STATUS_LED_COLOR_RED: - # Some fan don't support red led but support orange led, in this case we set led to orange - if self.STATUS_LED_COLOR_RED in led_cap_list: - led_path = os.path.join(LED_PATH, self.fan_red_led_path) - elif self.STATUS_LED_COLOR_ORANGE in led_cap_list: - led_path = os.path.join(LED_PATH, self.fan_orange_led_path) - else: - return False - with open(led_path, 'w') as fan_led: - fan_led.write(LED_ON) - status = True - elif color == self.STATUS_LED_COLOR_OFF: - if self.STATUS_LED_COLOR_GREEN in led_cap_list: - with open(os.path.join(LED_PATH, self.fan_green_led_path), 'w') as fan_led: - fan_led.write(str(LED_OFF)) - if self.STATUS_LED_COLOR_RED in led_cap_list: - with open(os.path.join(LED_PATH, self.fan_red_led_path), 'w') as fan_led: - fan_led.write(str(LED_OFF)) - if self.STATUS_LED_COLOR_ORANGE in led_cap_list: - with open(os.path.join(LED_PATH, self.fan_orange_led_path), 'w') as fan_led: - fan_led.write(str(LED_OFF)) - - status = True - else: - status = False - except (ValueError, IOError): - status = False - - return status + return self.led.set_status(color) def get_status_led(self): @@ -355,26 +276,7 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings above """ - led_cap_list = self._get_led_capability() - if led_cap_list is None: - return self.STATUS_LED_COLOR_OFF - - try: - with open(os.path.join(LED_PATH, self.fan_green_led_path), 'r') as fan_led: - if LED_OFF != fan_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_GREEN - if self.STATUS_LED_COLOR_RED in led_cap_list: - with open(os.path.join(LED_PATH, self.fan_red_led_path), 'r') as fan_led: - if LED_OFF != fan_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_RED - if self.STATUS_LED_COLOR_ORANGE in led_cap_list: - with open(os.path.join(LED_PATH, self.fan_orange_led_path), 'r') as fan_led: - if LED_OFF != fan_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_RED - except (ValueError, IOError) as e: - raise RuntimeError("Failed to read led status for fan {} due to {}".format(self.index, repr(e))) - - return self.STATUS_LED_COLOR_OFF + return self.led.get_status() def get_speed_tolerance(self): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..bed6c7ab042a --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan Drawer status which are available in the platform +# +############################################################################# + +import os + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform_base.fan_base import FanBase + from .led import FanLed, SharedLed +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +class MellanoxFanDrawer(FanDrawerBase): + def __init__(self, index, fan_data): + from .fan import FAN_PATH + super(MellanoxFanDrawer, self).__init__() + self._index = index + 1 + self._fan_data = fan_data + self._presence_path = os.path.join(FAN_PATH, 'fan{}_status'.format(self._index)) + self._led = None + + def get_index(self): + return self._index + + def get_led(self): + return self._led + + def get_presence(self): + if not self._fan_data['hot_swappable']: + return True + + status = 0 + try: + with open(self._presence_path, 'r') as presence_status: + status = int(presence_status.read()) + except (ValueError, IOError) as e: + status = 0 + + return status == 1 + + def get_direction(self): + if not self._fan_data['support_fan_direction'] or not self.get_presence(): + return FanBase.FAN_DIRECTION_NOT_APPLICABLE + + try: + from .fan import FAN_DIR + with open(FAN_DIR, 'r') as fan_dir: + fan_dir_bits = int(fan_dir.read()) + fan_mask = 1 << self._index - 1 + if fan_dir_bits & fan_mask: + return FanBase.FAN_DIRECTION_INTAKE + else: + return FanBase.FAN_DIRECTION_EXHAUST + except (ValueError, IOError) as e: + raise RuntimeError("Failed to read fan direction status to {}".format(repr(e))) + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + + Args: + color: A string representing the color with which to set the + fan drawer status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + return True + + def get_status_led(self): + """ + Gets the state of the fan drawer LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + return self._led.get_status() + + +class RealDrawer(MellanoxFanDrawer): + def __init__(self, index, fan_data): + super(RealDrawer, self).__init__(index, fan_data) + self._name = 'drawer{}'.format(self._index) + self._led = SharedLed(FanLed(self._index)) + + def get_name(self): + return self._name + + +class VirtualDrawer(MellanoxFanDrawer): + def __init__(self, index, fan_data): + super(VirtualDrawer, self).__init__(index, fan_data) + self._led = SharedLed(FanLed(None)) + + def get_name(self): + return 'N/A' diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/led.py b/platform/mellanox/mlnx-platform-api/sonic_platform/led.py new file mode 100644 index 000000000000..ebc2de25a5c1 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/led.py @@ -0,0 +1,201 @@ +import os + + +class Led(object): + STATUS_LED_COLOR_GREEN = 'green' + STATUS_LED_COLOR_RED = 'red' + STATUS_LED_COLOR_ORANGE = 'orange' + STATUS_LED_COLOR_OFF = 'off' + + LED_ON = '1' + LED_OFF = '0' + + LED_PATH = "/var/run/hw-management/led/" + + def set_status(self, color): + led_cap_list = self.get_capability() + if led_cap_list is None: + return False + + status = False + try: + if color == Led.STATUS_LED_COLOR_GREEN: + with open(self.get_green_led_path(), 'w') as led: + led.write(Led.LED_ON) + status = True + elif color == Led.STATUS_LED_COLOR_RED: + # Some led don't support red led but support orange led, in this case we set led to orange + if Led.STATUS_LED_COLOR_RED in led_cap_list: + led_path = self.get_red_led_path() + elif Led.STATUS_LED_COLOR_ORANGE in led_cap_list: + led_path = self.get_orange_led_path() + else: + return False + + with open(led_path, 'w') as led: + led.write(Led.LED_ON) + status = True + elif color == Led.STATUS_LED_COLOR_OFF: + if Led.STATUS_LED_COLOR_GREEN in led_cap_list: + with open(self.get_green_led_path(), 'w') as led: + led.write(Led.LED_OFF) + if Led.STATUS_LED_COLOR_RED in led_cap_list: + with open(self.get_red_led_path(), 'w') as led: + led.write(Led.LED_OFF) + if Led.STATUS_LED_COLOR_ORANGE in led_cap_list: + with open(self.get_orange_led_path(), 'w') as led: + led.write(Led.LED_OFF) + + status = True + else: + status = False + except (ValueError, IOError): + status = False + + return status + + def get_status(self): + led_cap_list = self.get_capability() + if led_cap_list is None: + return Led.STATUS_LED_COLOR_OFF + + try: + with open(self.get_green_led_path(), 'r') as led: + if Led.LED_OFF != led.read().rstrip('\n'): + return Led.STATUS_LED_COLOR_GREEN + + if Led.STATUS_LED_COLOR_RED in led_cap_list: + with open(self.get_red_led_path(), 'r') as led: + if Led.LED_OFF != led.read().rstrip('\n'): + return Led.STATUS_LED_COLOR_RED + if Led.STATUS_LED_COLOR_ORANGE in led_cap_list: + with open(self.get_orange_led_path(), 'r') as led: + if Led.LED_OFF != led.read().rstrip('\n'): + return Led.STATUS_LED_COLOR_RED + except (ValueError, IOError) as e: + raise RuntimeError("Failed to read led status due to {}".format(repr(e))) + + return Led.STATUS_LED_COLOR_OFF + + def get_capability(self): + cap_list = None + try: + with open(self.get_led_cap_path(), 'r') as led_cap: + caps = led_cap.read() + cap_list = caps.split() + except (ValueError, IOError): + pass + + return cap_list + + def get_green_led_path(self): + pass + + def get_red_led_path(self): + pass + + def get_orange_led_path(self): + pass + + def get_led_cap_path(self): + pass + + +class FanLed(Led): + LED_PATH = "/var/run/hw-management/led/" + + def __init__(self, index): + if index is not None: + self._green_led_path = os.path.join(Led.LED_PATH, "led_fan{}_green".format(index)) + self._red_led_path = os.path.join(Led.LED_PATH, "led_fan{}_red".format(index)) + self._orange_led_path = os.path.join(Led.LED_PATH, "led_fan{}_orange".format(index)) + self._led_cap_path = os.path.join(Led.LED_PATH, "led_fan{}_capability".format(index)) + else: + self._green_led_path = os.path.join(Led.LED_PATH, "led_fan_green") + self._red_led_path = os.path.join(Led.LED_PATH, "led_fan_red") + self._orange_led_path = os.path.join(Led.LED_PATH, "led_fan_orange") + self._led_cap_path = os.path.join(Led.LED_PATH, "led_fan_capability") + + self.set_status(Led.STATUS_LED_COLOR_GREEN) + + def get_green_led_path(self): + return self._green_led_path + + def get_red_led_path(self): + return self._red_led_path + + def get_orange_led_path(self): + return self._orange_led_path + + def get_led_cap_path(self): + return self._led_cap_path + + +class PsuLed(Led): + def __init__(self, index): + if index is not None: + self._green_led_path = os.path.join(Led.LED_PATH, "led_psu{}_green".format(index)) + self._red_led_path = os.path.join(Led.LED_PATH, "led_psu{}_red".format(index)) + self._orange_led_path = os.path.join(Led.LED_PATH, "led_psu{}_orange".format(index)) + self._led_cap_path = os.path.join(Led.LED_PATH, "led_psu{}_capability".format(index)) + else: + self._green_led_path = os.path.join(Led.LED_PATH, "led_psu_green") + self._red_led_path = os.path.join(Led.LED_PATH, "led_psu_red") + self._orange_led_path = os.path.join(Led.LED_PATH, "led_psu_orange") + self._led_cap_path = os.path.join(Led.LED_PATH, "led_psu_capability") + + self.set_status(Led.STATUS_LED_COLOR_GREEN) + + def get_green_led_path(self): + return self._green_led_path + + def get_red_led_path(self): + return self._red_led_path + + def get_orange_led_path(self): + return self._orange_led_path + + def get_led_cap_path(self): + return self._led_cap_path + + +class SharedLed(object): + LED_PRIORITY = { + Led.STATUS_LED_COLOR_RED: 0, + Led.STATUS_LED_COLOR_GREEN: 1 + } + + def __init__(self, led): + self._led = led + self._virtual_leds = [] + + def add_virtual_leds(self, led): + self._virtual_leds.append(led) + + def update_status_led(self): + target_color = Led.STATUS_LED_COLOR_GREEN + for virtual_led in self._virtual_leds: + if SharedLed.LED_PRIORITY[virtual_led.get_led_color()] < SharedLed.LED_PRIORITY[target_color]: + target_color = virtual_led.get_led_color() + + return self._led.set_status(target_color) + + def get_status(self): + return self._led.get_status() + + +class ComponentFaultyIndicator(object): + def __init__(self, shared_led): + self._color = Led.STATUS_LED_COLOR_GREEN + self._shared_led = shared_led + self._shared_led.add_virtual_leds(self) + + def set_status(self, color): + self._color = color + return self._shared_led.update_status_led() + + def get_led_color(self): + return self._color + + def get_status(self): + return self._shared_led.get_status() diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 1486dc0bc854..a323132faf97 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -13,11 +13,11 @@ from sonic_platform_base.psu_base import PsuBase from sonic_daemon_base.daemon_base import Logger from sonic_platform.fan import Fan + from .led import PsuLed, SharedLed, ComponentFaultyIndicator + from .device_data import DEVICE_DATA except ImportError as e: raise ImportError (str(e) + "- required module not found") -LED_ON = '1' -LED_OFF = '0' # Global logger class instance logger = Logger() @@ -28,16 +28,11 @@ PSU_VOLTAGE = "voltage" PSU_POWER = "power" -LED_PATH = "/var/run/hw-management/led/" +# in most platforms the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. +# but there are exceptions which will be handled by the following dictionary -# SKUs with unplugable PSUs: -# 1. don't have psuX_status and should be treated as always present -# 2. don't have voltage, current and power values -hwsku_dict_with_unplugable_psu = ['ACS-MSN2010', 'ACS-MSN2100'] +platform_dict_psu = {'x86_64-mlnx_msn3700-r0': 1, 'x86_64-mlnx_msn3700c-r0': 1, 'x86_64-mlnx_msn3800-r0': 1, 'x86_64-mlnx_msn4700-r0': 1} -# in most SKUs the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. -# but there are exceptions which will be handled by the following dictionary -hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1, 'ACS-MSN3420': 1, 'ACS-MSN4600C': 1} psu_profile_list = [ # default filename convention { @@ -56,9 +51,9 @@ class Psu(PsuBase): """Platform-specific Psu class""" - STATUS_LED_COLOR_ORANGE = "orange" + shared_led = None - def __init__(self, psu_index, sku): + def __init__(self, psu_index, platform): global psu_list PsuBase.__init__(self) # PSU is 1-based on Mellanox platform @@ -66,17 +61,19 @@ def __init__(self, psu_index, sku): psu_list.append(self.index) self.psu_path = "/var/run/hw-management/" psu_oper_status = "thermal/psu{}_pwr_status".format(self.index) - #psu_oper_status should always be present for all SKUs + #psu_oper_status should always be present for all platforms self.psu_oper_status = os.path.join(self.psu_path, psu_oper_status) self._name = "PSU{}".format(psu_index + 1) - if sku in hwsku_dict_psu: - filemap = psu_profile_list[hwsku_dict_psu[sku]] + if platform in platform_dict_psu: + filemap = psu_profile_list[platform_dict_psu[platform]] else: filemap = psu_profile_list[0] - if sku in hwsku_dict_with_unplugable_psu: - self.always_presence = True + self.psu_data = DEVICE_DATA[platform]['psus'] + + if not self.psu_data['hot_swappable']: + self.always_present = True self.psu_voltage = None self.psu_current = None self.psu_power = None @@ -84,7 +81,7 @@ def __init__(self, psu_index, sku): self.psu_temp = None self.psu_temp_threshold = None else: - self.always_presence = False + self.always_present = False psu_voltage = filemap[PSU_VOLTAGE].format(self.index) psu_voltage = os.path.join(self.psu_path, psu_voltage) self.psu_voltage = psu_voltage @@ -105,14 +102,14 @@ def __init__(self, psu_index, sku): self.psu_temp_threshold = os.path.join(self.psu_path, 'thermal/psu{}_temp_max'.format(self.index)) # unplugable PSU has no FAN - if sku not in hwsku_dict_with_unplugable_psu: - fan = Fan(False, psu_index, psu_index, True) + if self.psu_data['hot_swappable']: + fan = Fan(psu_index, None, True) self._fan_list.append(fan) - self.psu_green_led_path = "led_psu_green" - self.psu_red_led_path = "led_psu_red" - self.psu_orange_led_path = "led_psu_orange" - self.psu_led_cap_path = "led_psu_capability" + if self.psu_data['led_num'] == 1: + self.led = ComponentFaultyIndicator(Psu.get_shared_led()) + else: # 2010/2100 + self.led = PsuLed(self.index) def get_name(self): @@ -151,8 +148,8 @@ def get_presence(self): Returns: bool: True if PSU is present, False if not """ - if self.always_presence: - return self.always_presence + if self.always_present: + return self.always_present else: status = self._read_generic_file(self.psu_presence, 0) return status == 1 @@ -199,19 +196,6 @@ def get_power(self): else: return None - - def _get_led_capability(self): - cap_list = None - try: - with open(os.path.join(LED_PATH, self.psu_led_cap_path), 'r') as psu_led_cap: - caps = psu_led_cap.read() - cap_list = caps.split() - except (ValueError, IOError): - status = 0 - - return cap_list - - def set_status_led(self, color): """ Sets the state of the PSU status LED @@ -226,45 +210,7 @@ def set_status_led(self, color): Notes: Only one led for all PSUs. """ - led_cap_list = self._get_led_capability() - if led_cap_list is None: - return False - - status = False - try: - if color == self.STATUS_LED_COLOR_GREEN: - with open(os.path.join(LED_PATH, self.psu_green_led_path), 'w') as psu_led: - psu_led.write(LED_ON) - status = True - elif color == self.STATUS_LED_COLOR_RED: - # Some fan don't support red led but support orange led, in this case we set led to orange - if self.STATUS_LED_COLOR_RED in led_cap_list: - led_path = os.path.join(LED_PATH, self.psu_red_led_path) - elif self.STATUS_LED_COLOR_ORANGE in led_cap_list: - led_path = os.path.join(LED_PATH, self.psu_orange_led_path) - else: - return False - with open(led_path, 'w') as psu_led: - psu_led.write(LED_ON) - status = True - elif color == self.STATUS_LED_COLOR_OFF: - if self.STATUS_LED_COLOR_GREEN in led_cap_list: - with open(os.path.join(LED_PATH, self.psu_green_led_path), 'w') as psu_led: - psu_led.write(str(LED_OFF)) - if self.STATUS_LED_COLOR_RED in led_cap_list: - with open(os.path.join(LED_PATH, self.psu_red_led_path), 'w') as psu_led: - psu_led.write(str(LED_OFF)) - if self.STATUS_LED_COLOR_ORANGE in led_cap_list: - with open(os.path.join(LED_PATH, self.psu_orange_led_path), 'w') as psu_led: - psu_led.write(str(LED_OFF)) - - status = True - else: - status = False - except (ValueError, IOError): - status = False - - return status + return self.led.set_status(color) def get_status_led(self): @@ -274,26 +220,10 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings above """ - led_cap_list = self._get_led_capability() - if led_cap_list is None: - return self.STATUS_LED_COLOR_OFF - - try: - with open(os.path.join(LED_PATH, self.psu_green_led_path), 'r') as psu_led: - if LED_OFF != psu_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_GREEN - if self.STATUS_LED_COLOR_RED in led_cap_list: - with open(os.path.join(LED_PATH, self.psu_red_led_path), 'r') as psu_led: - if LED_OFF != psu_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_RED - if self.STATUS_LED_COLOR_ORANGE in led_cap_list: - with open(os.path.join(LED_PATH, self.psu_orange_led_path), 'r') as psu_led: - if LED_OFF != psu_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_RED - except (ValueError, IOError) as e: - raise RuntimeError("Failed to read led status for psu due to {}".format(repr(e))) - - return self.STATUS_LED_COLOR_OFF + if self.psu_data['led_num'] == 1: + return Psu.get_shared_led().get_status() + else: + return self.led.get_status() def get_power_available_status(self): @@ -312,6 +242,12 @@ def get_power_available_status(self): else: return True, "" + @classmethod + def get_shared_led(cls): + if not cls.shared_led: + cls.shared_led = SharedLed(PsuLed(None)) + return cls.shared_led + def get_temperature(self): """ Retrieves current temperature reading from PSU @@ -367,4 +303,3 @@ def get_voltage_low_threshold(self): """ # hw-management doesn't expose those sysfs for now raise NotImplementedError - diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index be91cf9d523e..3c25ebb642e8 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -124,7 +124,7 @@ THERMAL_API_GET_HIGH_THRESHOLD ] -hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8, 'ACS-MSN3420': 9, 'ACS-MSN4600C': 9} +hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8, 'ACS-MSN3420': 9, 'ACS-MSN4600C': 10} thermal_profile_list = [ # 2700 { @@ -267,7 +267,7 @@ }, # 3420 { - THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 2), THERMAL_DEV_CATEGORY_MODULE:(1, 60), THERMAL_DEV_CATEGORY_PSU:(1, 2), THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), diff --git a/platform/mellanox/mlnx-platform-api/tests/mock_platform.py b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py index c53480584889..8edb9d4fb163 100644 --- a/platform/mellanox/mlnx-platform-api/tests/mock_platform.py +++ b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py @@ -2,6 +2,7 @@ class MockFan: speed = 60 def __init__(self): self.presence = True + self.name = None self.status = True def get_presence(self): @@ -16,6 +17,9 @@ def get_status(self): def get_target_speed(self): return MockFan.speed + def get_name(self): + return self.name + class MockPsu: def __init__(self): diff --git a/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py b/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py index 381260163c0f..24158997abf7 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py @@ -1,17 +1,57 @@ import os import sys +import pytest from mock import MagicMock +from .mock_platform import MockFan test_path = os.path.dirname(os.path.abspath(__file__)) modules_path = os.path.dirname(test_path) sys.path.insert(0, modules_path) from sonic_platform.fan import Fan +from sonic_platform.led import FanLed +from sonic_platform.fan_drawer import RealDrawer +from sonic_platform.device_data import DEVICE_DATA def test_get_absence_fan_direction(): - fan = Fan(True, 0, 0) - fan.get_presence = MagicMock(return_value=False) - assert fan.fan_dir is not None + fan_drawer = RealDrawer(0, DEVICE_DATA['x86_64-mlnx_msn2700-r0']['fans']) + fan = Fan(0, fan_drawer) + fan_drawer.get_presence = MagicMock(return_value=False) + assert not fan.is_psu_fan assert fan.get_direction() == Fan.FAN_DIRECTION_NOT_APPLICABLE + + +def test_fan_drawer_set_status_led(): + fan_drawer = RealDrawer(0, DEVICE_DATA['x86_64-mlnx_msn2700-r0']['fans']) + with pytest.raises(Exception): + fan_drawer.set_status_led(None, 'Invalid color') + + with pytest.raises(Exception): + fan_drawer.set_status_led(None, Fan.STATUS_LED_COLOR_RED) + + fan1 = Fan(0, fan_drawer) + fan2 = Fan(1, fan_drawer) + fan_list = fan_drawer.get_all_fans() + fan_list.append(fan1) + fan_list.append(fan2) + + FanLed.set_status = MagicMock() + + fan1.set_status_led(Fan.STATUS_LED_COLOR_RED) + fan_drawer.set_status_led(Fan.STATUS_LED_COLOR_RED) + FanLed.set_status.assert_called_with(Fan.STATUS_LED_COLOR_RED) + + fan2.set_status_led(Fan.STATUS_LED_COLOR_GREEN) + fan_drawer.set_status_led(Fan.STATUS_LED_COLOR_GREEN) + FanLed.set_status.assert_called_with(Fan.STATUS_LED_COLOR_RED) + + fan1.set_status_led(Fan.STATUS_LED_COLOR_GREEN) + fan_drawer.set_status_led(Fan.STATUS_LED_COLOR_GREEN) + FanLed.set_status.assert_called_with(Fan.STATUS_LED_COLOR_GREEN) + + fan1.set_status_led(Fan.STATUS_LED_COLOR_RED) + fan_drawer.set_status_led(Fan.STATUS_LED_COLOR_RED) + FanLed.set_status.assert_called_with(Fan.STATUS_LED_COLOR_RED) + diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 28c39c55666d..75698a8dd8f5 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 28c39c55666dcaef10f62492906c1399eec4ccba +Subproject commit 75698a8dd8f5a9ea2a0e72c5f7e2b3196d22571a From 40bc4875a8c3f322fef463ba29db577376b65284 Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Wed, 13 May 2020 22:32:15 +0530 Subject: [PATCH 0655/1427] [Juniper][QFX5200] EM policy updates (#4543) This patchset implement the following: - Setting the FAN frequency - Corrections to the EM policy with respect to platform defined temperature / fan values - Updates to the platform monitorng script logging - Fixes to platform initialization script Signed-off-by: Ciju Rajan K --- .../qfx5200/utils/juniper_qfx5200_monitor.py | 574 +++++++++++------- .../qfx5200/utils/juniper_qfx5200_util.py | 42 +- 2 files changed, 376 insertions(+), 240 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py index da71c586be43..9620b4e9de43 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py @@ -57,88 +57,84 @@ isPlatformAFI = False isFireThresholdReached = False -is35PerFlag = True -is55PerFlag = True -is75PerFlag = True -is90PerFlag = True isFireThresholdPrint = True FireThresholdSecsRemaining = 120 PrevASICValue = 0 temp_policy_AFI = { - 0: [[35, 0, 30000], [35, 30000, 39000], [55, 39000, 0], [55, 39000, 48000], [75, 48000, 0], [75, 48000, 56000], [90, 56000, 0], [90, 56000, 65000],[100, 66000, 0], + 0: [[35, 0, 30000], [35, 30000, 39000], [55, 39000, 0], [55, 39000, 48000], [75, 48000, 0], [75, 48000, 56000], [90, 56000, 0], [90, 56000, 66000],[100, 66000, 0], ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 73000], ['Fire Shut Alarm', 73000, 0]], - 1: [[35, 0, 30000], [35, 30000, 39000], [55, 39000, 0], [55, 39000, 48000], [75, 48000, 0], [75, 48000, 56000], [90, 56000, 0], [90, 56000, 65000],[100, 66000, 0], + 1: [[35, 0, 30000], [35, 30000, 39000], [55, 39000, 0], [55, 39000, 48000], [75, 48000, 0], [75, 48000, 56000], [90, 56000, 0], [90, 56000, 66000],[100, 66000, 0], ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 73000], ['Fire Shut Alarm', 73000, 0]], - 2: [[35, 0, 40000], [35, 40000, 47000], [55, 47000, 0], [55, 47000, 55000], [75, 55000, 0], [75, 55000, 63000], [90, 62000, 0], [90, 62000, 69000],[100, 70000, 0], + 2: [[35, 0, 40000], [35, 40000, 47000], [55, 47000, 0], [55, 47000, 55000], [75, 55000, 0], [75, 55000, 62000], [90, 62000, 0], [90, 62000, 70000],[100, 70000, 0], ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], - 3: [[35, 0, 36000], [35, 36000, 44000], [55, 44000, 0], [55, 44000, 52000], [75, 52000, 0], [75, 52000, 60000], [90, 60000, 0], [90, 60000, 68000],[100, 69000, 0], + 3: [[35, 0, 36000], [35, 36000, 44000], [55, 44000, 0], [55, 44000, 52000], [75, 52000, 0], [75, 52000, 60000], [90, 60000, 0], [90, 60000, 69000],[100, 69000, 0], ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], - 4: [[35, 0, 52000], [35, 52000, 57000], [55, 57000, 0], [55, 57000, 63000], [75, 63000, 0], [75, 63000, 68000], [90, 68000, 0], [90, 68000, 73000],[100, 74000, 0], + 4: [[35, 0, 52000], [35, 52000, 57000], [55, 57000, 0], [55, 57000, 63000], [75, 63000, 0], [75, 63000, 68000], [90, 68000, 0], [90, 68000, 74000],[100, 74000, 0], ['Yellow Alarm', 72000, 78000], ['Red Alarm', 78000, 81000], ['Fire Shut Alarm', 81000, 0]], - 5: [[35, 0, 37000], [35, 37000, 45000], [55, 45000, 0], [55, 45000, 53000], [75, 53000, 0], [75, 53000, 61000], [90, 61000, 0], [90, 61000, 69000],[100, 70000, 0], + 5: [[35, 0, 37000], [35, 37000, 45000], [55, 45000, 0], [55, 45000, 53000], [75, 53000, 0], [75, 53000, 61000], [90, 61000, 0], [90, 61000, 70000],[100, 70000, 0], ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], - 6: [[35, 0, 37000], [35, 37000, 45000], [55, 45000, 0], [55, 45000, 53000], [75, 53000, 0], [75, 53000, 61000], [90, 61000, 0], [90, 61000, 69000],[100, 69000, 0], + 6: [[35, 0, 37000], [35, 37000, 45000], [55, 45000, 0], [55, 45000, 53000], [75, 53000, 0], [75, 53000, 60000], [90, 60000, 0], [90, 60000, 69000],[100, 69000, 0], ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], - 7: [[35, 0, 52000], [35, 52000, 57000], [55, 57000, 0], [55, 57000, 63000], [75, 63000, 0], [75, 63000, 68000], [90, 68000, 0], [90, 68000, 73000],[100, 74000, 0], + 7: [[35, 0, 52000], [35, 52000, 57000], [55, 57000, 0], [55, 57000, 63000], [75, 63000, 0], [75, 63000, 68000], [90, 68000, 0], [90, 68000, 74000],[100, 74000, 0], ['Yellow Alarm', 72000, 78000], ['Red Alarm', 78000, 81000], ['Fire Shut Alarm', 81000, 0]], - 8: [[35, 0, 41000], [35, 41000, 48000], [55, 48000, 0], [55, 48000, 55000], [75, 55000, 0], [75, 55000, 62000], [90, 62000, 0], [90, 62000, 69000],[100, 70000, 0], + 8: [[35, 0, 41000], [35, 41000, 48000], [55, 48000, 0], [55, 48000, 55000], [75, 55000, 0], [75, 55000, 62000], [90, 62000, 0], [90, 62000, 70000],[100, 70000, 0], ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], - 9: [[35, 0, 42000], [35, 42000, 49000], [55, 49000, 0], [55, 49000, 57000], [75, 57000, 0], [75, 57000, 64000], [90, 64000, 0], [90, 64000, 71000],[100, 72000, 0], + 9: [[35, 0, 42000], [35, 42000, 49000], [55, 49000, 0], [55, 49000, 57000], [75, 57000, 0], [75, 57000, 64000], [90, 64000, 0], [90, 64000, 72000],[100, 72000, 0], ['Yellow Alarm', 70000, 76000], ['Red Alarm', 76000, 79000], ['Fire Shut Alarm', 79000, 0]], - 10: [[35, 0, 68000], [35, 68000, 74000], [55, 74000, 0], [55, 74000, 80000], [75, 80000, 0], [75, 80000, 85000], [90, 85000, 0], [90, 85000, 91000],[100, 92000, 0], - ['Yellow Alarm', 99000, 102000], ['Red Alarm', 102000, 105000], ['Fire Shut Alarm', 105000, 0]], + 10: [[35, 0, 42000], [35, 42000, 50000], [55, 50000, 0], [55, 50000, 58000], [75, 58000, 0], [75, 58000, 66000], [90, 66000, 0], [90, 66000, 75000],[100, 75000, 0], + ['Yellow Alarm', 86000, 92000], ['Red Alarm', 92000, 95000], ['Fire Shut Alarm', 95000, 0]], - 11: [[35, 0, 42000], [35, 42000, 50000], [55, 50000, 0], [55, 50000, 58000], [75, 58000, 0], [75, 58000, 66000], [90, 66000, 0], [90, 66000, 74000],[100, 75000, 0], - ['Yellow Alarm', 86000, 92000], ['Red Alarm', 92000, 95000], ['Fire Shut Alarm', 95000, 0]], + 11: [[35, 0, 68000], [35, 68000, 74000], [55, 74000, 0], [55, 74000, 80000], [75, 80000, 0], [75, 80000, 85000], [90, 85000, 0], [90, 85000, 92000],[100, 92000, 0], + ['Yellow Alarm', 99000, 102000], ['Red Alarm', 102000, 105000], ['Fire Shut Alarm', 105000, 0]], } temp_policy_AFO = { - 0: [[35, 0, 42000], [35, 42000, 49000], [55, 49000, 0], [55, 49000, 55000], [75, 55000, 0], [75, 55000, 62000], [90, 62000, 0], [90, 62000, 68000],[100, 69000, 0], + 0: [[35, 0, 42000], [35, 42000, 49000], [55, 49000, 0], [55, 49000, 55000], [75, 55000, 0], [75, 55000, 62000], [90, 62000, 0], [90, 62000, 69000],[100, 69000, 0], ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], - 1: [[35, 0, 41000], [35, 41000, 48000], [55, 48000, 0], [55, 48000, 55000], [75, 55000, 0], [75, 55000, 61000], [90, 61000, 0], [90, 61000, 68000],[100, 69000, 0], + 1: [[35, 0, 41000], [35, 41000, 48000], [55, 48000, 0], [55, 48000, 55000], [75, 55000, 0], [75, 55000, 61000], [90, 61000, 0], [90, 61000, 69000],[100, 69000, 0], ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], - 2: [[35, 0, 44000], [35, 44000, 50000], [55, 50000, 0], [55, 50000, 56000], [75, 56000, 0], [75, 56000, 63000], [90, 63000, 0], [90, 63000, 69000],[100, 70000, 0], - ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 75000], ['Fire Shut Alarm', 75000, 0]], + 2: [[35, 0, 44000], [35, 44000, 50000], [55, 50000, 0], [55, 50000, 56000], [75, 56000, 0], [75, 56000, 63000], [90, 63000, 0], [90, 63000, 70000],[100, 70000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], - 3: [[35, 0, 36000], [35, 36000, 43000], [55, 43000, 0], [55, 43000, 50000], [75, 50000, 0], [75, 50000, 57000], [90, 57000, 0], [90, 57000, 64000],[100, 65000, 0], + 3: [[35, 0, 36000], [35, 36000, 43000], [55, 43000, 0], [55, 43000, 50000], [75, 50000, 0], [75, 50000, 57000], [90, 57000, 0], [90, 57000, 65000],[100, 65000, 0], ['Yellow Alarm', 63000, 69000], ['Red Alarm', 69000, 72000], ['Fire Shut Alarm', 72000, 0]], - 4: [[35, 0, 49000], [35, 49000, 54000], [55, 54000, 0], [55, 54000, 60000], [75, 60000, 0], [75, 60000, 65000], [90, 65000, 0], [90, 65000, 70000],[100, 71000, 0], + 4: [[35, 0, 49000], [35, 49000, 54000], [55, 54000, 0], [55, 54000, 60000], [75, 60000, 0], [75, 60000, 65000], [90, 65000, 0], [90, 65000, 71000],[100, 71000, 0], ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], - 5: [[35, 0, 46000], [35, 46000, 52000], [55, 52000, 0], [55, 52000, 58000], [75, 58000, 0], [75, 58000, 63000], [90, 63000, 0], [90, 63000, 69000],[100, 70000, 0], + 5: [[35, 0, 46000], [35, 46000, 52000], [55, 52000, 0], [55, 52000, 58000], [75, 58000, 0], [75, 58000, 63000], [90, 63000, 0], [90, 63000, 70000],[100, 70000, 0], ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], - 6: [[35, 0, 50000], [35, 50000, 55000], [55, 55000, 0], [55, 55000, 60000], [75, 60000, 0], [75, 60000, 65000], [90, 65000, 0], [90, 65000, 70000],[100, 71000, 0], + 6: [[35, 0, 50000], [35, 50000, 55000], [55, 55000, 0], [55, 55000, 60000], [75, 60000, 0], [75, 60000, 65000], [90, 65000, 0], [90, 65000, 71000],[100, 71000, 0], ['Yellow Alarm', 65000, 71000], ['Red Alarm', 71000, 78000], ['Fire Shut Alarm', 78000, 0]], - 7: [[35, 0, 49000], [35, 49000, 55000], [55, 55000, 0], [55, 55000, 60000], [75, 60000, 0], [75, 60000, 66000], [90, 66000, 0], [90, 66000, 71000],[100, 72000, 0], + 7: [[35, 0, 49000], [35, 49000, 55000], [55, 55000, 0], [55, 55000, 60000], [75, 60000, 0], [75, 60000, 66000], [90, 66000, 0], [90, 66000, 72000],[100, 72000, 0], ['Yellow Alarm', 70000, 76000], ['Red Alarm', 76000, 79000], ['Fire Shut Alarm', 79000, 0]], - 8: [[35, 0, 41000], [35, 41000, 47000], [55, 47000, 0], [55, 47000, 54000], [75, 54000, 0], [75, 54000, 60000], [90, 60000, 0], [90, 60000, 66000],[100, 67000, 0], + 8: [[35, 0, 41000], [35, 41000, 47000], [55, 47000, 0], [55, 47000, 54000], [75, 54000, 0], [75, 54000, 60000], [90, 60000, 0], [90, 60000, 67000],[100, 67000, 0], ['Yellow Alarm', 65000, 71000], ['Red Alarm', 71000, 74000], ['Fire Shut Alarm', 74000, 0]], - 9: [[35, 0, 57000], [35, 57000, 61000], [55, 61000, 0], [55, 61000, 66000], [75, 66000, 0], [75, 66000, 70000], [90, 70000, 0], [90, 70000, 74000],[100, 75000, 0], + 9: [[35, 0, 57000], [35, 57000, 61000], [55, 61000, 0], [55, 61000, 66000], [75, 66000, 0], [75, 66000, 70000], [90, 70000, 0], [90, 70000, 75000],[100, 75000, 0], ['Yellow Alarm', 73000, 79000], ['Red Alarm', 79000, 82000], ['Fire Shut Alarm', 82000, 0]], - 10: [[35, 0, 76000], [35, 76000, 79000], [55, 79000, 0], [55, 79000, 83000], [75, 83000, 0], [75, 83000, 86000], [90, 86000, 0], [90, 86000, 89000],[100, 90000, 0], - ['Yellow Alarm', 99000, 102000], ['Red Alarm', 102000, 105000], ['Fire Shut Alarm', 105000, 0]], - - 11: [[35, 0, 51000], [35, 51000, 58000], [55, 58000, 0], [55, 58000, 64000], [75, 64000, 0], [75, 64000, 70000], [90, 70000, 0], [90, 70000, 77000],[100, 78000, 0], + 10: [[35, 0, 51000], [35, 51000, 58000], [55, 58000, 0], [55, 58000, 64000], [75, 64000, 0], [75, 64000, 70000], [90, 70000, 0], [90, 70000, 78000],[100, 78000, 0], ['Yellow Alarm', 86000, 92000], ['Red Alarm', 92000, 95000], ['Fire Shut Alarm', 95000, 0]], + + 11: [[35, 0, 76000], [35, 76000, 79000], [55, 79000, 0], [55, 79000, 83000], [75, 83000, 0], [75, 83000, 86000], [90, 86000, 0], [90, 86000, 90000],[100, 90000, 0], + ['Yellow Alarm', 99000, 102000], ['Red Alarm', 102000, 105000], ['Fire Shut Alarm', 105000, 0]], } class QFX5200_FanUtil(object): @@ -172,31 +168,48 @@ def __init__(self): self._hwmon_input_node_mapping[x], hwmon_dir, self._pwm_input_node_mapping[x]) - def get_fan_duty_cycle(self): + def get_fan_dutycycle(self): fan_speed = {86: 35, 139: 55, 192: 75, 230: 90,255: 100} ret_value = 0 for x in range(self.PWMINPUT_NUM): pwm_value = 0 + pwm_value1 = 0 device_path = self._pwm_input_path_mapping[x] cmd = ("sudo cat %s" %(device_path)) status, pwm_value = commands.getstatusoutput(cmd) - if int(pwm_value) > 0: + pwm_value1 = int(pwm_value) + time.sleep(0.25) + if int(pwm_value1) > 0: ret_value = fan_speed.get(int(pwm_value)) break return int(ret_value) - def set_fan_duty_cycle(self, val): + def set_fan_dutycycle(self, val): fan_speed = {35: 86, 55: 139, 75: 192, 90: 230,100: 255} for x in range(self.PWMINPUT_NUM): device_path = self._pwm_input_path_mapping[x] pwm_value = fan_speed.get(val) pwm_value1 = str(pwm_value) - time.sleep(1) cmd = ("sudo echo %s > %s" %(pwm_value1,device_path)) os.system(cmd) + time.sleep(0.25) + logging.debug('Setting PWM value: %s to all fans', pwm_value1) return True + def get_check_fan_dutycycle(self): + pwm_str = '' + for x in range(self.PWMINPUT_NUM): + device_path = self._pwm_input_path_mapping[x] + cmd = ("sudo cat %s" %(device_path)) + status, pwm_value = commands.getstatusoutput(cmd) + pwm_str += pwm_value + if (x != self.PWMINPUT_NUM -1): + pwm_str += ', ' + time.sleep(0.25) + logging.debug('Current PWM values set in all fans: %s', pwm_str) + + class QFX5200_ThermalUtil(object): """QFX5200 Platform ThermalUtil class""" @@ -418,17 +431,31 @@ def set_alarm_led_brightness(self, val): """ Function is called periodically every 20 secs. It reads the 10 Temp sensors, 1 core Temp sensor and ASIC temp sets Sensor flags accordingly. Also reads the Fan duty cycle and depending on the FAN duty cycle reading and temp sensor reading, - set the different parameters """ + set the different parameters + + Below is the Sensor Mapping(Refer AFI/AFO EM Policy Specification) to the I2C devices + + /sys/bus/i2c/devices/7-0048/hwmon/hwmon* --> Sensor# 2 + /sys/bus/i2c/devices/7-0049/hwmon/hwmon* --> Sensor# 3 + /sys/bus/i2c/devices/5-0048/hwmon/hwmon* --> Sensor# 5 + /sys/bus/i2c/devices/5-0049/hwmon/hwmon* --> Sensor# 6 + /sys/bus/i2c/devices/5-004a/hwmon/hwmon* --> Sensor# 7 + /sys/bus/i2c/devices/5-004b/hwmon/hwmon* --> Sensor# 8 + /sys/bus/i2c/devices/6-0048/hwmon/hwmon* --> Sensor# 9 + /sys/bus/i2c/devices/6-0049/hwmon/hwmon* --> Sensor# 10 + /sys/bus/i2c/devices/6-004a/hwmon/hwmon* --> Sensor# 11 + /sys/bus/i2c/devices/6-004b/hwmon/hwmon* --> Sensor# 12 + """ + def getSensorTemp(self): global isPlatformAFI - global is35PerFlag - global is55PerFlag - global is75PerFlag - global is90PerFlag global isFireThresholdReached global FireThresholdSecsRemaining global isFireThresholdPrint - global PrevASICValue + global PrevASICValue + + sensor_str = '' + #AFI if (isPlatformAFI == True): temp_policy = temp_policy_AFI @@ -469,18 +496,27 @@ def getSensorTemp(self): if (FireThresholdSecsRemaining == 0): isFireThresholdReached == False time.sleep(20) + logging.debug('Executing poweroff command') cmd = "poweroff" - os.system(cmd) + os.system(cmd) for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): + SEN_str = 'SEN' + if x < self.SENSOR_NUM_ON_MAIN_BOARD: value = self._get_sensor_node_val(x) - logging.debug('Sensor value %d : %s', x, value) + if ( x < 2): + SEN_str += `x + 2` + else: + SEN_str += `x + 3` + + sensor_str += SEN_str + ':' + str(value) + ', ' + elif x == self.CORETEMP_INDEX_ON_MAIN_BOARD: value = self.get_coretempValue() - logging.debug('Main Board CORE temp: %s', value) + sensor_str += 'CPU:' + str(value) + ', ' + else: - logging.debug('Reading ASIC Temp value using bcmcmd') proc = subprocess.Popen("bcmcmd \"show temp\" | grep \"maximum peak temperature\" | awk '{ print $5 }' > /var/log/asic_value 2>&1 & ",shell=True) time.sleep(2) cmd = "kill -9 %s"%(proc.pid) @@ -488,7 +524,6 @@ def getSensorTemp(self): if os.stat("/var/log/asic_value").st_size == 0: value = PrevASICValue - logging.debug('No ASIC Temp file, Prev ASIC Temp Value: %s', PrevASICValue) else: with open('/var/log/asic_value', 'r') as f: value1 = f.readline() @@ -496,11 +531,9 @@ def getSensorTemp(self): value1 = value2 * 1000 value = int(value1) PrevASICValue = value - logging.debug('Reading from ASIC Temp file: %s', value) - logging.debug('Reading from Prev ASIC Temp Value: %s', PrevASICValue) - - os.system('rm /var/log/asic_value') + sensor_str += 'BRCM TH:' + str(value) + # 35% Duty Cycle if value > temp_policy[x][0][1] and value <= temp_policy[x][0][2]: SensorFlag[x][0] = True @@ -552,8 +585,9 @@ def getSensorTemp(self): elif value >= temp_policy[x][11][1]: SensorFlag[x][11] = True + logging.debug('Sensor values : %s', sensor_str) fan = QFX5200_FanUtil() - # CHECK IF ANY TEMPERATURE SENSORS HAS SET FIRE SHUTDOWN FLAG + # CHECK IF ANY TEMPERATURE SENSORS is running at Soft shutdown temperature if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): @@ -564,241 +598,295 @@ def getSensorTemp(self): os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds' > /dev/console") isFireThresholdPrint = False - logging.debug('Temp Sensor is set to FIRE SHUTDOWN Flag') - fan.set_fan_duty_cycle(100) self.set_alarm_led_brightness(2) + logging.debug('Setting Red Alarm as one temp sensor is running at soft shutdown temp value') - # CHECK IF ANY TEMPERATURE SENSORS HAS SET 'RED' ALARM FLAG, IF YES, SET THE ALARM LED TO 'RED' + # CHECK IF ANY TEMPERATURE SENSORS is running at RED warning , IF YES, SET THE ALARM LED TO 'RED' elif (SensorFlag[0][10] or SensorFlag[1][10] or SensorFlag[2][10] or SensorFlag[3][10] or SensorFlag[4][10] or SensorFlag[5][10] or SensorFlag[6][10] or SensorFlag[7][10] or SensorFlag[8][10] or SensorFlag[9][10] or SensorFlag[10][10] or SensorFlag[11][10]): - fan.set_fan_duty_cycle(100) - self.set_alarm_led_brightness(2) - logging.debug('Temp Sensor is set to Red Alarm Flag') if (isFireThresholdReached == True): - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + self.set_alarm_led_brightness(2) - # CHECK IF ANY TEMPERATURE SENSORS HAS SET 'YELLOW' ALARM FLAG, IF YES, SET THE ALARM LED TO 'YELLOW' + logging.debug('Setting Red Alarm') + + # CHECK IF ANY TEMPERATURE SENSORS is running at Yellow warning, IF YES, SET THE ALARM LED TO 'YELLOW' elif (SensorFlag[0][9] or SensorFlag[1][9] or SensorFlag[2][9] or SensorFlag[3][9] or SensorFlag[4][9] or SensorFlag[5][9] or SensorFlag[6][9] or SensorFlag[7][9] or SensorFlag[8][9] or SensorFlag[9][9] or SensorFlag[10][9] or SensorFlag[11][9]): - fan.set_fan_duty_cycle(100) - self.set_alarm_led_brightness(1) - logging.debug('Temp Sensor is set to Yellow Alarm Flag') if (isFireThresholdReached == True): - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False - #CHECK IF ANY TEMPERATURE SENSORS HAS SET 100% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 100% - elif (SensorFlag[0][8] or SensorFlag[1][8] or SensorFlag[2][8] or SensorFlag[3][8] or SensorFlag[4][8] or SensorFlag[5][8] or SensorFlag[6][8] or SensorFlag[7][8] - or SensorFlag[8][8] or SensorFlag[9][8] or SensorFlag[10][8] or SensorFlag[11][8]): - - if (fan.get_fan_duty_cycle < 100): - fan.set_fan_duty_cycle(100) - elif (fan.get_fan_duty_cycle == 100): - pass - else: - pass + self.set_alarm_led_brightness(1) + logging.debug('Setting Yellow Alarm') + else: value = self.get_alarm_led_brightness() - if ( value > 0): - self.set_alarm_led_brightness(0) + if ( value == 2): + logging.debug('Clearing Red Alarm') + elif ( value == 1): + logging.debug('Clearing Yellow Alarm') + + self.set_alarm_led_brightness(0) - logging.debug('Temp Sensor is set to 100% Duty Cycle Flag') + #CHECK IF ANY TEMPERATURE SENSORS HAS SET 100% DUTY CYCLE FLAG + if (SensorFlag[0][8] or SensorFlag[1][8] or SensorFlag[2][8] or SensorFlag[3][8] or SensorFlag[4][8] or SensorFlag[5][8] or SensorFlag[6][8] or SensorFlag[7][8] + or SensorFlag[8][8] or SensorFlag[9][8] or SensorFlag[10][8] or SensorFlag[11][8]): - # CHECK IF ANY TEMPERATURE SENSORS HAS SET 90% PREV DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 90% + if (isFireThresholdReached == True): + if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] + or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + fan.get_check_fan_dutycycle() + if (fan.get_fan_dutycycle() < 100): + time.sleep(0.50) + fan.set_fan_dutycycle(100) + + logging.debug('Fan set to 100% dutycycle') + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 90% PREV DUTY CYCLE FLAG elif (SensorFlag[0][7] or SensorFlag[1][7] or SensorFlag[2][7] or SensorFlag[3][7] or SensorFlag[4][7] or SensorFlag[5][7] or SensorFlag[6][7] or SensorFlag[7][7] or SensorFlag[8][7] or SensorFlag[9][7] or SensorFlag[10][7] or SensorFlag[11][7]): - if (is90PerFlag == True): - fan.set_fan_duty_cycle(90) - is90PerFlag = False - else: - pass - - value = self.get_alarm_led_brightness() - if ( value > 0): - self.set_alarm_led_brightness(0) - if (isFireThresholdReached == True): - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - - logging.debug('Temp Sensor is set to 90% Prev Duty Cycle Flag') + if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] + or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() == 100): + logging.debug('Fan set to 100% dutycycle') + elif (fan.get_fan_dutycycle() != 90): + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') + else: + logging.debug('Fan set to 90% dutycycle') - # CHECK IF ANY TEMPERATURE SENSORS HAS SET 90% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 90% + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 90% DUTY CYCLE FLAG elif (SensorFlag[0][6] or SensorFlag[1][6] or SensorFlag[2][6] or SensorFlag[3][6] or SensorFlag[4][6] or SensorFlag[5][6] or SensorFlag[6][6] or SensorFlag[7][6] or SensorFlag[8][6] or SensorFlag[9][6] or SensorFlag[10][6] or SensorFlag[11][6]): - if (fan.get_fan_duty_cycle < 90): - fan.set_fan_duty_cycle(90) - elif (fan.get_fan_duty_cycle > 90): - if (SensorFlag[0][6] and SensorFlag[1][6] and SensorFlag[2][6] and SensorFlag[3][6] and SensorFlag[4][6] and SensorFlag[5][6] and SensorFlag[6][6] and SensorFlag[7][6] - and SensorFlag[8][6] and SensorFlag[9][6] and SensorFlag[10][6] and SensorFlag[11][6]): - - fan.set_fan_duty_cycle(90) - else: - pass - - value = self.get_alarm_led_brightness() - if ( value > 0): - self.set_alarm_led_brightness(0) - - is90PerFlag = True - if (isFireThresholdReached == True): - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - - logging.debug('Temp Sensor is set to 90% Duty Cycle Flag') + if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] + or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() < 90): + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') + elif (fan.get_fan_dutycycle() == 90): + logging.debug('Fan set to 90% dutycycle') + else: + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') - # CHECK IF ANY TEMPERATURE SENSORS HAS SET 75% PREV DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 75% + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 75% PREV DUTY CYCLE FLAG elif (SensorFlag[0][5] or SensorFlag[1][5] or SensorFlag[2][5] or SensorFlag[3][5] or SensorFlag[4][5] or SensorFlag[5][5] or SensorFlag[6][5] or SensorFlag[7][5] or SensorFlag[8][5] or SensorFlag[9][5] or SensorFlag[10][5] or SensorFlag[11][5]): - if (is75PerFlag == True): - fan.set_fan_duty_cycle(75) - is75PerFlag = False - else: - pass - - value = self.get_alarm_led_brightness() - if ( value > 0): - self.set_alarm_led_brightness(0) - if (isFireThresholdReached == True): - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - - logging.debug('Temp Sensor is set to 75% Prev Duty Cycle Flag') - - # CHECK IF ANY TEMPERATURE SENSORS HAS SET 75% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 75% + if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] + or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() > 75): + if (fan.get_fan_dutycycle() == 100): + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') + else: + logging.debug('Fan set to 90% dutycycle') + elif (fan.get_fan_dutycycle() != 75): + time.sleep(0.25) + fan.set_fan_dutycycle(75) + logging.debug('Fan set to 75% dutycycle') + else: + logging.debug('Fan set to 75% dutycycle') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 75% DUTY CYCLE FLAG elif (SensorFlag[0][4] or SensorFlag[1][4] or SensorFlag[2][4] or SensorFlag[3][4] or SensorFlag[4][4] or SensorFlag[5][4] or SensorFlag[6][4] or SensorFlag[7][4] or SensorFlag[8][4] or SensorFlag[9][4] or SensorFlag[10][4] or SensorFlag[11][4]): - if (fan.get_fan_duty_cycle < 75): - fan.set_fan_duty_cycle(75) - elif (fan.get_fan_duty_cycle > 75): - if (SensorFlag[0][4] and SensorFlag[1][4] and SensorFlag[2][4] and SensorFlag[3][4] and SensorFlag[4][4] and SensorFlag[5][4] and SensorFlag[6][4] and SensorFlag[7][4] - and SensorFlag[8][4] and SensorFlag[9][4] and SensorFlag[10][4] and SensorFlag[11][4]): + if (isFireThresholdReached == True): + if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] + or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + fan.get_check_fan_dutycycle() + if (fan.get_fan_dutycycle() < 75): + time.sleep(0.25) + fan.set_fan_dutycycle(75) + logging.debug('Fan set to 75% dutycycle') + + elif (fan.get_fan_dutycycle() == 75): + logging.debug('Fan set to 75% dutycycle') - fan.set_fan_duty_cycle(75) else: - pass - - value = self.get_alarm_led_brightness() - if ( value > 0): - self.set_alarm_led_brightness(0) + time.sleep(0.25) + fan.set_fan_dutycycle(75) + logging.debug('Fan set to 75% dutycycle') - is75PerFlag = True - logging.debug('Temp Sensor is set to 75% Duty Cycle Flag') - - # CHECK IF ANY TEMPERATURE SENSORS HAS SET 55% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 55% + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 55% DUTY CYCLE PREV FLAG elif (SensorFlag[0][3] or SensorFlag[1][3] or SensorFlag[2][3] or SensorFlag[3][3] or SensorFlag[4][3] or SensorFlag[5][3] or SensorFlag[6][3] or SensorFlag[7][3] or SensorFlag[8][3] or SensorFlag[9][3] or SensorFlag[10][3] or SensorFlag[11][3]): - if (is55PerFlag == True): - fan.set_fan_duty_cycle(55) - is55PerFlag = False - else: - pass - - value = self.get_alarm_led_brightness() - if ( value > 0): - self.set_alarm_led_brightness(0) - if (isFireThresholdReached == True): - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - logging.debug('Temp Sensor is set to 55% Prev Duty Cycle Flag') - - # CHECK IF ANY TEMPERATURE SENSORS HAS SET 55% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 55% - elif (SensorFlag[0][2] or SensorFlag[1][2] or SensorFlag[2][2] or SensorFlag[3][2] or SensorFlag[4][2] or SensorFlag[5][2] or SensorFlag[6][2] or SensorFlag[7][2] - or SensorFlag[8][2] or SensorFlag[9][2] or SensorFlag[10][2] or SensorFlag[11][2]): - if (fan.get_fan_duty_cycle < 55): - fan.set_fan_duty_cycle(55) - elif (fan.get_fan_duty_cycle > 55): - if (SensorFlag[0][2] and SensorFlag[1][2] and SensorFlag[2][2] and SensorFlag[3][2] and SensorFlag[4][2] and SensorFlag[5][2] and SensorFlag[6][2] and SensorFlag[7][2] - and SensorFlag[8][6] and SensorFlag[9][6] and SensorFlag[10][6] and SensorFlag[11][6]): - - fan.set_fan_duty_cycle(55) + if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] + or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() > 55): + if (fan.get_fan_dutycycle() == 100): + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') + elif (fan.get_fan_dutycycle() == 90): + time.sleep(0.25) + fan.set_fan_dutycycle(75) + logging.debug('Fan set to 75% dutycycle') + else: + logging.debug('Fan set to 75% dutycycle') + elif (fan.get_fan_dutycycle() != 55): + time.sleep(0.25) + fan.set_fan_dutycycle(55) + logging.debug('Fan set to 55% dutycycle') else: - pass + logging.debug('Fan set to 55% dutycycle') - value = self.get_alarm_led_brightness() - if ( value > 0): - self.set_alarm_led_brightness(0) - is55PerFlag = True + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 55% DUTY CYCLE FLAG + elif (SensorFlag[0][2] or SensorFlag[1][2] or SensorFlag[2][2] or SensorFlag[3][2] or SensorFlag[4][2] or SensorFlag[5][2] or SensorFlag[6][2] or SensorFlag[7][2] + or SensorFlag[8][2] or SensorFlag[9][2] or SensorFlag[10][2] or SensorFlag[11][2]): if (isFireThresholdReached == True): - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - - logging.debug('Temp Sensor is set to 55% Duty Cycle Flag') + if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] + or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() < 55): + time.sleep(0.25) + fan.set_fan_dutycycle(55) + logging.debug('Fan set to 55% dutycycle') + elif (fan.get_fan_dutycycle() == 55): + logging.debug('Fan set to 55% dutycycle') + else: + time.sleep(0.25) + fan.set_fan_dutycycle(55) + logging.debug('Fan set to 55% dutycycle') - # CHECK IF ANY TEMPERATURE SENSORS HAS SET 35% PREV DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 35% + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 35% PREV DUTY CYCLE FLAG elif (SensorFlag[0][1] or SensorFlag[1][1] or SensorFlag[2][1] or SensorFlag[3][1] or SensorFlag[4][1] or SensorFlag[5][1] or SensorFlag[6][1] or SensorFlag[7][1] or SensorFlag[8][1] or SensorFlag[9][1] or SensorFlag[10][1] or SensorFlag[11][1]): - if (is35PerFlag == True): - fan.set_fan_duty_cycle(35) - is35PerFlag = False - else: - pass - - value = self.get_alarm_led_brightness() - if ( value > 0): - self.set_alarm_led_brightness(0) - if (isFireThresholdReached == True): - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - - logging.debug('Temp Sensor is set to 35% Prev Duty Cycle Flag') - # CHECK IF ANY TEMPERATURE SENSORS HAS SET 35% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 35% + if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] + or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() > 35): + if (fan.get_fan_dutycycle() == 100): + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') + elif (fan.get_fan_dutycycle() == 90): + time.sleep(0.25) + fan.set_fan_dutycycle(75) + logging.debug('Fan set to 75% dutycycle') + elif (fan.get_fan_dutycycle() == 75): + time.sleep(0.25) + fan.set_fan_dutycycle(55) + logging.debug('Fan set to 55% dutycycle') + else: + logging.debug('Fan set to 55% dutycycle') + elif (fan.get_fan_dutycycle() == 35): + logging.debug('Fan set to 35% dutycycle') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 35% DUTY CYCLE FLAG elif (SensorFlag[0][0] or SensorFlag[1][0] or SensorFlag[2][0] or SensorFlag[3][0] or SensorFlag[4][0] or SensorFlag[5][0] or SensorFlag[6][0] or SensorFlag[7][0] or SensorFlag[8][0] or SensorFlag[9][0] or SensorFlag[10][0] or SensorFlag[11][0]): - if (fan.get_fan_duty_cycle == 35): - fan.set_fan_duty_cycle(35) - elif (fan.get_fan_duty_cycle > 35): - if (SensorFlag[0][0] and SensorFlag[1][0] and SensorFlag[2][0] and SensorFlag[3][0] and SensorFlag[4][0] and SensorFlag[5][0] and SensorFlag[6][0] and SensorFlag[7][0] - and SensorFlag[8][0] and SensorFlag[9][0] and SensorFlag[10][0] and SensorFlag[11][0]): - fan.set_fan_duty_cycle(35) - else: - pass + if (isFireThresholdReached == True): + + if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] + or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False - value = self.get_alarm_led_brightness() - if ( value > 0): - self.set_alarm_led_brightness(0) + fan.get_check_fan_dutycycle() - is35PerFlag = True + if (fan.get_fan_dutycycle() > 35): + time.sleep(0.25) + fan.set_fan_dutycycle(35) - if (isFireThresholdReached == True): - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - logging.debug('Temp Sensor is set to 35% Duty Cycle Flag') + logging.debug('Fan set to 35% dutycycle') else: pass @@ -813,9 +901,10 @@ class device_monitor(object): MASTER_LED_PATH = '/sys/class/leds/master/brightness' SYSTEM_LED_PATH = '/sys/class/leds/system/brightness' - + PWMINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/{1}/pwm{2}' HWMONINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/' + PWMINPUT_NUM = 10 _pwm_input_path_mapping = {} _hwmon_input_path_mapping = {} @@ -897,22 +986,37 @@ def __init__(self, log_file, log_level): logging.error('device_monitor: unable to open System LED file: %s', str(e)) systemLED_file.write(str(system_led_value)) - systemLED_file.close() - self.set_DefaultFAN_duty_cycle(35) + systemLED_file.close() + self.get_Initial_fan_dutycycle() + self.set_Default_fan_dutycycle(35) - def set_DefaultFAN_duty_cycle(self, val): + def set_Default_fan_dutycycle(self, val): fan_speed = {35: 86, 55: 139, 75: 192, 90: 230,100: 255} for x in range(self.PWMINPUT_NUM): device_path = self._pwm_input_path_mapping[x] pwm_value = fan_speed.get(val) pwm_value1 = str(pwm_value) - time.sleep(1) + time.sleep(0.25) cmd = ("sudo echo %s > %s" %(pwm_value1,device_path)) os.system(cmd) + logging.debug('Setting Default PWM value: 86 to all fans') return True + def get_Initial_fan_dutycycle(self): + pwm_str = '' + for x in range(self.PWMINPUT_NUM): + device_path = self._pwm_input_path_mapping[x] + cmd = ("sudo cat %s" %(device_path)) + status, pwm_value = commands.getstatusoutput(cmd) + pwm_str += pwm_value + if (x != self.PWMINPUT_NUM -1): + pwm_str += ', ' + time.sleep(0.25) + logging.debug('Initial PWM values read: %s', pwm_str) + return True + def manage_device(self): thermal = QFX5200_ThermalUtil() thermal.getSensorTemp() diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py index d97982d1fec0..2e6171d99180 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py @@ -39,16 +39,15 @@ 'modprobe i2c-mux', 'modprobe mfd-core', 'modprobe tmp401', -'modprobe ads7828', 'modprobe jnx-tmc-core', 'modprobe leds-jnx-tmc', -'modprobe jnx-refpga-tmc', -'modprobe adt7470', +'modprobe jnx-refpga-tmc', 'modprobe i2c-tmc', 'modprobe gpio-tmc', 'modprobe jnx-tmc-psu', 'modprobe jnx-psu-monitor', -'modprobe jnx-refpga-lpcm' +'modprobe jnx-refpga-lpcm', +'modprobe adt7470' ] mknod =[ @@ -65,7 +64,6 @@ 'echo adt7470 0x2C > /sys/bus/i2c/devices/i2c-7/new_device', 'echo adt7470 0x2E > /sys/bus/i2c/devices/i2c-7/new_device', 'echo adt7470 0x2F > /sys/bus/i2c/devices/i2c-7/new_device', -'echo ads7830 0x4A > /sys/bus/i2c/devices/i2c-2/new_device', 'echo jpsu 0x58 > /sys/bus/i2c/devices/i2c-3/new_device', 'echo jpsu 0x58 > /sys/bus/i2c/devices/i2c-4/new_device', ] @@ -130,6 +128,16 @@ def do_install(): def main(): + hwmon_input_node_mapping = ['2c','2e','2f'] + PWM1FREQ_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/{1}/pwm1_freq' + NUMSENSORS_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/{1}/num_temp_sensors' + HWMONINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/' + PWMINPUT_NUM = 3 + hwmon_input_path_mapping = {} + pwm_input_path_mapping = {} + numsensors_input_path_mapping = {} + + # Enabling REFPGA EnableREFFGACmd = 'busybox devmem 0xFED50011 8 0x53' try: @@ -197,6 +205,30 @@ def main(): print 'Error: Execution of "%s" failed', EEPROMDataCmd return False + for x in range(PWMINPUT_NUM): + hwmon_input_path_mapping[x] = HWMONINPUT_PATH.format(hwmon_input_node_mapping[x]) + + hwmon_path = os.listdir(hwmon_input_path_mapping[x]) + hwmon_dir = '' + for hwmon_name in hwmon_path: + hwmon_dir = hwmon_name + + pwm_input_path_mapping[x] = PWM1FREQ_PATH.format( + hwmon_input_node_mapping[x], + hwmon_dir) + device_path = pwm_input_path_mapping[x] + time.sleep(1) + cmd = ("sudo echo 22500 > %s" %device_path) + os.system(cmd) + + numsensors_input_path_mapping[x] = NUMSENSORS_PATH.format( + hwmon_input_node_mapping[x], + hwmon_dir) + numsensors_path = numsensors_input_path_mapping[x] + time.sleep(1) + cmd = ("sudo echo 0 > %s" %numsensors_path) + os.system(cmd) + return True if __name__ == "__main__": From 0542afb619d5975a8c4bff13eecf2dbba0cf3557 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 13 May 2020 10:24:16 -0700 Subject: [PATCH 0656/1427] Moved utility functions for multi-npu platforms from sonic-utilities to sonic_device_util.py (#4559) * Moved utility functions for multi-npu platforms from sonic-utilities config/main.py to here so that they can be used any module * Fix the issue with test run during compilation with acl-uploader PR#908 of sonic-utilities. * Fix get_num_npu as it was retuning string and not int * Address Review Comments * Address Review Comments --- src/sonic-config-engine/sonic_device_util.py | 57 +++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index 03bd7027a46e..cb9263ce0345 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -5,6 +5,8 @@ import re from natsort import natsorted import glob +from swsssdk import ConfigDBConnector, SonicDBConfig + DOCUMENTATION = ''' --- module: sonic_device_util @@ -21,6 +23,9 @@ SONIC_DEVICE_PATH = '/usr/share/sonic/device' NPU_NAME_PREFIX = 'asic' NAMESPACE_PATH_GLOB = '/run/netns/*' +ASIC_CONF_FILENAME = 'asic.conf' +FRONTEND_ASIC_SUB_ROLE = 'FrontEnd' +BACKEND_ASIC_SUB_ROLE = 'BackEnd' def get_machine_info(): if not os.path.isfile('/host/machine.conf'): return None @@ -41,7 +46,9 @@ def get_npu_id_from_name(npu_name): def get_num_npus(): platform = get_platform_info(get_machine_info()) - asic_conf_file_path = os.path.join(SONIC_DEVICE_PATH, platform, 'asic.conf') + if not platform: + return 1 + asic_conf_file_path = os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME) if not os.path.isfile(asic_conf_file_path): return 1 with open(asic_conf_file_path) as asic_conf_file: @@ -51,7 +58,7 @@ def get_num_npus(): continue if tokens[0].lower() == 'num_asic': num_npus = tokens[1].strip() - return num_npus + return int(num_npus) def get_namespaces(): """ @@ -64,6 +71,52 @@ def get_namespaces(): ns_list.append(ns) return natsorted(ns_list) +def get_hwsku(): + config_db = ConfigDBConnector() + config_db.connect() + metadata = config_db.get_table('DEVICE_METADATA') + return metadata['localhost']['hwsku'] + +def get_platform(): + if not os.path.isfile('/host/machine.conf'): + return '' + + with open('/host/machine.conf') as machine_conf: + for line in machine_conf: + tokens = line.split('=') + if tokens[0].strip() == 'onie_platform' or tokens[0].strip() == 'aboot_platform': + return tokens[1].strip() + return '' + +def is_multi_npu(): + num_npus = get_num_npus() + return (num_npus > 1) + +def get_all_namespaces(): + """ + In case of Multi-Asic platform, Each ASIC will have a linux network namespace created. + So we loop through the databases in different namespaces and depending on the sub_role + decide whether this is a front end ASIC/namespace or a back end one. + """ + front_ns = [] + back_ns = [] + num_npus = get_num_npus() + SonicDBConfig.load_sonic_global_db_config() + + if is_multi_npu(): + for npu in range(num_npus): + namespace = "{}{}".format(NPU_NAME_PREFIX, npu) + config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=namespace) + config_db.connect() + + metadata = config_db.get_table('DEVICE_METADATA') + if metadata['localhost']['sub_role'] == FRONTEND_ASIC_SUB_ROLE: + front_ns.append(namespace) + elif metadata['localhost']['sub_role'] == BACKEND_ASIC_SUB_ROLE: + back_ns.append(namespace) + + return {'front_ns':front_ns, 'back_ns':back_ns} + def get_platform_info(machine_info): if machine_info != None: if machine_info.has_key('onie_platform'): From 9dea816532f65fec1ee3c8593d5475a7d9a90cfc Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Thu, 14 May 2020 10:23:37 -0700 Subject: [PATCH 0657/1427] Convert docker-snmp-sv2 to buster (#4529) * Fix libsnmp-base compilation failure * Convert docker-snmp-sv2 to buster * Define install_python3_wheels * Address review comments * Address review comments * Advance snmpagent submodule * Bump net-snmp to the Buster version * Revert "Fix libsnmp-base compilation failure" * use azure storage url --- dockers/docker-snmp-sv2/Dockerfile.j2 | 19 +- dockers/docker-snmp-sv2/supervisord.conf | 2 +- dockers/dockerfile-macros.j2 | 4 + rules/docker-snmp-sv2.mk | 10 +- rules/python3.mk | 35 ---- rules/snmpd.mk | 2 +- src/snmpd/Makefile | 5 +- ...OpenSSL-1.1.0-with-support-for-1.0.2.patch | 184 ------------------ ..._BUILD_ARCH_OS-in-order-to-build-ipv.patch | 6 +- src/snmpd/patch-5.7.3+dfsg/series | 2 - src/sonic-snmpagent | 2 +- 11 files changed, 24 insertions(+), 247 deletions(-) delete mode 100644 rules/python3.mk delete mode 100644 src/snmpd/patch-5.7.3+dfsg/0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch diff --git a/dockers/docker-snmp-sv2/Dockerfile.j2 b/dockers/docker-snmp-sv2/Dockerfile.j2 index b62ff61eaf95..304c7fb44a9f 100644 --- a/dockers/docker-snmp-sv2/Dockerfile.j2 +++ b/dockers/docker-snmp-sv2/Dockerfile.j2 @@ -1,5 +1,5 @@ -{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python3_wheels, copy_files %} +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -18,7 +18,9 @@ ENV DEBIAN_FRONTEND=noninteractive # The file referenced (`/usr/share/dpkg/no-pie-compile.specs`) is in the `libdpkg-perl` package on Debian RUN apt-get update && \ apt-get install -y \ - curl \ + python3 \ + python3-pip \ + python3-dev \ ca-certificates \ gcc \ make \ @@ -43,11 +45,11 @@ RUN sed -i '/^#.* en_US.* /s/^#//' /etc/locale.gen RUN locale-gen # Install up-to-date version of pip -RUN curl https://bootstrap.pypa.io/get-pip.py | python3.6 +RUN pip3 install --no-cache-dir setuptools wheel # Install pyyaml dependency for use by some plugins # Install smbus dependency for use by some plugins -RUN python3.6 -m pip install --no-cache-dir \ +RUN python3 -m pip install --no-cache-dir \ hiredis \ pyyaml \ smbus @@ -57,15 +59,14 @@ RUN python3.6 -m pip install --no-cache-dir \ {{ copy_files("python-wheels/", docker_snmp_sv2_whls.split(' '), "/python-wheels/") }} # Install locally-built Python wheel dependencies -{{ install_python_wheels(docker_snmp_sv2_whls.split(' ')) }} +{{ install_python3_wheels(docker_snmp_sv2_whls.split(' ')) }} {% endif %} -RUN python3.6 -m sonic_ax_impl install +RUN python3 -m sonic_ax_impl install # Clean up RUN apt-get -y purge \ - libpython3.6-dev \ - libpython3.6 \ + python3-dev \ curl \ gcc \ make \ diff --git a/dockers/docker-snmp-sv2/supervisord.conf b/dockers/docker-snmp-sv2/supervisord.conf index 992292330552..6af6ae965b17 100644 --- a/dockers/docker-snmp-sv2/supervisord.conf +++ b/dockers/docker-snmp-sv2/supervisord.conf @@ -34,7 +34,7 @@ stdout_logfile=syslog stderr_logfile=syslog [program:snmp-subagent] -command=/usr/bin/env python3.6 -m sonic_ax_impl +command=/usr/bin/env python3 -m sonic_ax_impl priority=4 autostart=false autorestart=false diff --git a/dockers/dockerfile-macros.j2 b/dockers/dockerfile-macros.j2 index 408ee9fec622..8a4a3ae01411 100644 --- a/dockers/dockerfile-macros.j2 +++ b/dockers/dockerfile-macros.j2 @@ -9,6 +9,10 @@ RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return RUN cd /python-wheels/ && pip install {{ packages | join(' ') }} {%- endmacro %} +{% macro install_python3_wheels(packages) -%} +RUN cd /python-wheels/ && pip3 install {{ packages | join(' ') }} +{%- endmacro %} + {% macro copy_files(prefix, files, dest) -%} COPY \ {%- for file in files %} diff --git a/rules/docker-snmp-sv2.mk b/rules/docker-snmp-sv2.mk index 59f99ac78bc7..7eebf0c56ff1 100644 --- a/rules/docker-snmp-sv2.mk +++ b/rules/docker-snmp-sv2.mk @@ -7,23 +7,21 @@ DOCKER_SNMP_SV2_DBG = $(DOCKER_SNMP_SV2_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_SNMP_SV2)_PATH = $(DOCKERS_PATH)/docker-snmp-sv2 ## TODO: remove LIBPY3_DEV if we can get pip3 directly -$(DOCKER_SNMP_SV2)_DEPENDS += $(SNMP) $(SNMPD) $(PY3) $(LIBPY3_DEV) +$(DOCKER_SNMP_SV2)_DEPENDS += $(SNMP) $(SNMPD) -$(DOCKER_SNMP_SV2)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_SNMP_SV2)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_SNMP_SV2)_DBG_DEPENDS += $(SNMP_DBG) $(SNMPD_DBG) $(LIBSNMP_DBG) -$(DOCKER_SNMP_SV2)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_SNMP_SV2)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) $(DOCKER_SNMP_SV2)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3) $(SWSSSDK_PY3) $(ASYNCSNMP_PY3) -$(DOCKER_SNMP_SV2)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_SNMP_SV2)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_SNMP_SV2) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SNMP_SV2) -SONIC_STRETCH_DOCKERS += $(DOCKER_SNMP_SV2) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_SV2_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_SV2_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SNMP_SV2_DBG) $(DOCKER_SNMP_SV2)_CONTAINER_NAME = snmp $(DOCKER_SNMP_SV2)_RUN_OPT += --privileged -t diff --git a/rules/python3.mk b/rules/python3.mk deleted file mode 100644 index d9d19d8d1f97..000000000000 --- a/rules/python3.mk +++ /dev/null @@ -1,35 +0,0 @@ -PYTHON_VER=3.6.0-1 -PYTHON_PNAME=python3.6 - -export PYTHON_VER -export PYTHON_PNAME - -LIBPY3_MIN = lib$(PYTHON_PNAME)-minimal_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(LIBPY3_MIN)_SRC_PATH = $(SRC_PATH)/python3 -$(LIBPY3_MIN)_DEPENDS += -$(LIBPY3_MIN)_RDEPENDS += -SONIC_MAKE_DEBS += $(LIBPY3_MIN) - -LIBPY3_STD = lib$(PYTHON_PNAME)-stdlib_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBPY3_MIN),$(LIBPY3_STD))) -$(LIBPY3_STD)_DEPENDS += $(LIBMPDECIMAL) -$(LIBPY3_STD)_RDEPENDS += $(LIBPY3_MIN) $(LIBMPDECIMAL) - -LIBPY3 = lib$(PYTHON_PNAME)_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBPY3_MIN),$(LIBPY3))) -$(LIBPY3)_DEPENDS += $(LIBPY3_STD) -$(LIBPY3)_RDEPENDS += $(LIBPY3_MIN) $(LIBPY3_STD) - -PY3_MIN = $(PYTHON_PNAME)-minimal_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBPY3_MIN),$(PY3_MIN))) -$(PY3_MIN)_RDEPENDS += $(LIBPY3_MIN) - -PY3 = $(PYTHON_PNAME)_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBPY3_MIN),$(PY3))) -$(PY3)_DEPENDS += $(PY3_MIN) $(LIBPY3_STD) -$(PY3)_RDEPENDS += $(PY3_MIN) $(LIBPY3_STD) - -LIBPY3_DEV = lib$(PYTHON_PNAME)-dev_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBPY3_MIN),$(LIBPY3_DEV))) -$(LIBPY3_DEV)_DEPENDS += $(LIBPY3) $($(LIBPY3)_DEPENDS) -$(LIBPY3_DEV)_RDEPENDS += $(LIBPY3) $($(LIBPY3)_RDEPENDS) diff --git a/rules/snmpd.mk b/rules/snmpd.mk index 168cad70ef2a..cc340e92e6bb 100644 --- a/rules/snmpd.mk +++ b/rules/snmpd.mk @@ -1,7 +1,7 @@ # snmpd package SNMPD_VERSION = 5.7.3+dfsg -SNMPD_VERSION_FULL = $(SNMPD_VERSION)-1.5 +SNMPD_VERSION_FULL = $(SNMPD_VERSION)-5 export SNMPD_VERSION SNMPD_VERSION_FULL diff --git a/src/snmpd/Makefile b/src/snmpd/Makefile index 77084594d8ba..5e5c2a88098a 100644 --- a/src/snmpd/Makefile +++ b/src/snmpd/Makefile @@ -19,10 +19,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf net-snmp-$(SNMPD_VERSION) # download debian net-snmp - wget -NO net-snmp_$(SNMPD_VERSION_FULL).dsc "https://sonicstorage.blob.core.windows.net/packages/net-snmp_5.7.3+dfsg-1.5.dsc?sv=2015-04-05&sr=b&sig=vDAYAKlwi7JjF%2FesdJUyf4VIEXPsCfLhqqTqNr75zBs%3D&se=2030-10-12T13%3A59%3A45Z&sp=r" - wget -NO net-snmp_$(SNMPD_VERSION).orig.tar.xz "https://sonicstorage.blob.core.windows.net/packages/net-snmp_5.7.3+dfsg.orig.tar.xz?sv=2015-04-05&sr=b&sig=UjIh%2FTcHrIEzEV7a%2BV2ZP4ks3xHlAA3wqyxkyV7Ms8I%3D&se=2030-10-12T13%3A58%3A19Z&sp=r" - wget -NO net-snmp_$(SNMPD_VERSION_FULL).debian.tar.xz "https://sonicstorage.blob.core.windows.net/packages/net-snmp_5.7.3+dfsg-1.5.debian.tar.xz?sv=2015-04-05&sr=b&sig=xJkmxjtKXYcPe4yR%2FuCA0TXUfT40rj4XUMBaiK9CjsA%3D&se=2030-10-12T14%3A00%3A15Z&sp=r" - dpkg-source -x net-snmp_$(SNMPD_VERSION_FULL).dsc + dget -u https://sonicstorage.blob.core.windows.net/debian/pool/main/n/net-snmp/net-snmp_$(SNMPD_VERSION_FULL).dsc pushd net-snmp-$(SNMPD_VERSION) git init diff --git a/src/snmpd/patch-5.7.3+dfsg/0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch b/src/snmpd/patch-5.7.3+dfsg/0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch deleted file mode 100644 index b4a5e4a351dd..000000000000 --- a/src/snmpd/patch-5.7.3+dfsg/0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch +++ /dev/null @@ -1,184 +0,0 @@ -From: Andreas Henriksson -Date: Sat, 23 Dec 2017 22:25:41 +0000 -Subject: [PATCH] Port OpenSSL 1.1.0 with support for 1.0.2 - -Initial support for OpenSSL 1.1.0 - -Changes by sebastian@breakpoint.cc: -- added OpenSSL 1.0.2 glue layer for backwarts compatibility -- dropped HAVE_EVP_MD_CTX_CREATE + DESTROY and added a check for OpenSSL - version instead (and currently 1.0.2 is the only one supported). - -BTS: https://bugs.debian.org/828449 -Signed-off-by: Sebastian Andrzej Siewior ---- - apps/snmpusm.c | 43 ++++++++++++++++++++++++++++++++++++------- - configure.d/config_os_libs2 | 6 ------ - snmplib/keytools.c | 13 ++++++------- - snmplib/scapi.c | 17 +++++------------ - 4 files changed, 47 insertions(+), 32 deletions(-) - ---- a/apps/snmpusm.c -+++ b/apps/snmpusm.c -@@ -183,6 +183,31 @@ setup_oid(oid * it, size_t * len, u_char - } - - #if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO) -+ -+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) -+ -+static void DH_get0_pqg(const DH *dh, -+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) -+{ -+ if (p != NULL) -+ *p = dh->p; -+ if (q != NULL) -+ *q = dh->q; -+ if (g != NULL) -+ *g = dh->g; -+} -+ -+static void DH_get0_key(const DH *dh, const BIGNUM **pub_key, -+ const BIGNUM **priv_key) -+{ -+ if (pub_key != NULL) -+ *pub_key = dh->pub_key; -+ if (priv_key != NULL) -+ *priv_key = dh->priv_key; -+} -+ -+#endif -+ - int - get_USM_DH_key(netsnmp_variable_list *vars, netsnmp_variable_list *dhvar, - size_t outkey_len, -@@ -190,7 +215,7 @@ get_USM_DH_key(netsnmp_variable_list *va - oid *keyoid, size_t keyoid_len) { - u_char *dhkeychange; - DH *dh; -- BIGNUM *other_pub; -+ const BIGNUM *p, *g, *pub_key, *other_pub; - u_char *key; - size_t key_len; - -@@ -205,25 +230,29 @@ get_USM_DH_key(netsnmp_variable_list *va - dh = d2i_DHparams(NULL, &cp, dhvar->val_len); - } - -- if (!dh || !dh->g || !dh->p) { -+ if (dh) -+ DH_get0_pqg(dh, &p, NULL, &g); -+ -+ if (!dh || !g || !p) { - SNMP_FREE(dhkeychange); - return SNMPERR_GENERR; - } - -- DH_generate_key(dh); -- if (!dh->pub_key) { -+ if (!DH_generate_key(dh)) { - SNMP_FREE(dhkeychange); - return SNMPERR_GENERR; - } - -- if (vars->val_len != (unsigned int)BN_num_bytes(dh->pub_key)) { -+ DH_get0_key(dh, &pub_key, NULL); -+ -+ if (vars->val_len != (unsigned int)BN_num_bytes(pub_key)) { - SNMP_FREE(dhkeychange); - fprintf(stderr,"incorrect diffie-helman lengths (%lu != %d)\n", -- (unsigned long)vars->val_len, BN_num_bytes(dh->pub_key)); -+ (unsigned long)vars->val_len, BN_num_bytes(pub_key)); - return SNMPERR_GENERR; - } - -- BN_bn2bin(dh->pub_key, dhkeychange + vars->val_len); -+ BN_bn2bin(pub_key, dhkeychange + vars->val_len); - - key_len = DH_size(dh); - if (!key_len) { ---- a/configure.d/config_os_libs2 -+++ b/configure.d/config_os_libs2 -@@ -291,12 +291,6 @@ if test "x$tryopenssl" != "xno" -a "x$tr - AC_CHECK_LIB(${CRYPTO}, AES_cfb128_encrypt, - AC_DEFINE(HAVE_AES_CFB128_ENCRYPT, 1, - [Define to 1 if you have the `AES_cfb128_encrypt' function.])) -- -- AC_CHECK_LIB(${CRYPTO}, EVP_MD_CTX_create, -- AC_DEFINE([HAVE_EVP_MD_CTX_CREATE], [], -- [Define to 1 if you have the `EVP_MD_CTX_create' function.]) -- AC_DEFINE([HAVE_EVP_MD_CTX_DESTROY], [], -- [Define to 1 if you have the `EVP_MD_CTX_destroy' function.])) - fi - if echo " $transport_result_list " | $GREP "DTLS" > /dev/null; then - AC_CHECK_LIB(ssl, DTLSv1_method, ---- a/snmplib/keytools.c -+++ b/snmplib/keytools.c -@@ -149,13 +149,13 @@ generate_Ku(const oid * hashtype, u_int - */ - #ifdef NETSNMP_USE_OPENSSL - --#ifdef HAVE_EVP_MD_CTX_CREATE -+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) - ctx = EVP_MD_CTX_create(); - #else -- ctx = malloc(sizeof(*ctx)); -- if (!EVP_MD_CTX_init(ctx)) -- return SNMPERR_GENERR; -+ ctx = EVP_MD_CTX_new(); - #endif -+ if (!ctx) -+ return SNMPERR_GENERR; - #ifndef NETSNMP_DISABLE_MD5 - if (ISTRANSFORM(hashtype, HMACMD5Auth)) { - if (!EVP_DigestInit(ctx, EVP_md5())) -@@ -259,11 +259,10 @@ generate_Ku(const oid * hashtype, u_int - memset(buf, 0, sizeof(buf)); - #ifdef NETSNMP_USE_OPENSSL - if (ctx) { --#ifdef HAVE_EVP_MD_CTX_DESTROY -+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) - EVP_MD_CTX_destroy(ctx); - #else -- EVP_MD_CTX_cleanup(ctx); -- free(ctx); -+ EVP_MD_CTX_free(ctx); - #endif - } - #endif ---- a/snmplib/scapi.c -+++ b/snmplib/scapi.c -@@ -486,15 +486,10 @@ sc_hash(const oid * hashtype, size_t has - } - - /** initialize the pointer */ --#ifdef HAVE_EVP_MD_CTX_CREATE -+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) - cptr = EVP_MD_CTX_create(); - #else -- cptr = malloc(sizeof(*cptr)); --#if defined(OLD_DES) -- memset(cptr, 0, sizeof(*cptr)); --#else -- EVP_MD_CTX_init(cptr); --#endif -+ cptr = EVP_MD_CTX_new(); - #endif - if (!EVP_DigestInit(cptr, hashfn)) { - /* requested hash function is not available */ -@@ -507,13 +502,11 @@ sc_hash(const oid * hashtype, size_t has - /** do the final pass */ - EVP_DigestFinal(cptr, MAC, &tmp_len); - *MAC_len = tmp_len; --#ifdef HAVE_EVP_MD_CTX_DESTROY -+ -+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) - EVP_MD_CTX_destroy(cptr); - #else --#if !defined(OLD_DES) -- EVP_MD_CTX_cleanup(cptr); --#endif -- free(cptr); -+ EVP_MD_CTX_free(cptr); - #endif - return (rval); diff --git a/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch b/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch index f3e878077ff5..c41b5b5a6638 100644 --- a/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch +++ b/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch @@ -11,14 +11,12 @@ diff --git a/debian/rules b/debian/rules index 4c3b5b6..1fab6a4 100755 --- a/debian/rules +++ b/debian/rules -@@ -5,6 +5,7 @@ - # without -pie build fails during perl module build somehow... - export DEB_BUILD_MAINT_OPTIONS := hardening=+all,-pie +@@ -4,4 +4,5 @@ + export DEB_BUILD_MAINT_OPTIONS := hardening=+all DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) +DEB_BUILD_ARCH_OS ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS) LIB_VERSION = 30 - UPSTREAM_VERSION = $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ':' | sed 's/ //' | sed 's/~dfsg.*$$//') -- 2.18.0 diff --git a/src/snmpd/patch-5.7.3+dfsg/series b/src/snmpd/patch-5.7.3+dfsg/series index 428a81eb6b22..31b251845dea 100644 --- a/src/snmpd/patch-5.7.3+dfsg/series +++ b/src/snmpd/patch-5.7.3+dfsg/series @@ -1,7 +1,5 @@ 0001-SNMP-Stop-spamming-logs-with-statfs-permission-denie.patch 0002-at.c-properly-check-return-status-from-realloc.-Than.patch -0003-CHANGES-BUG-2743-snmpd-crashes-when-receiving-a-GetN.patch -0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch 0006-From-Jiri-Cervenka-snmpd-Fixed-agentx-crashing-and-or-freezing-on-timeout.patch 0007-Linux-VRF-5.7.3-Support.patch 0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 7632ee89caa8..c8e5757b7f54 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 7632ee89caa8a485d68ce389f60f202fce197579 +Subproject commit c8e5757b7f5495607bbf13d936f106991c13ddf5 From d90fdbf3f97a2c92604b2615697bff93a3473ff1 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar T <53558409+santhosh-kt@users.noreply.github.com> Date: Thu, 14 May 2020 22:59:43 +0530 Subject: [PATCH 0658/1427] [DellEMC] S6000 Disable Low power mode by default (#4592) --- .../s6000/scripts/s6000_platform.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh index bf6c730425e7..98fb13b1522f 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh @@ -60,6 +60,20 @@ remove_i2c_devices() { done } +# Enable/Disable low power mode on all QSFP ports +switch_board_qsfp_lpmode() { + case $1 in + "enable") value=0xffff + ;; + "disable") value=0x0 + ;; + *) echo "s6000_platform: switch_board_qsfp_lpmode: invalid command $1!" + return + ;; + esac + echo $value > /sys/bus/platform/devices/dell-s6000-cpld.0/qsfp_lpmode +} + install_python_api_package() { device="/usr/share/sonic/device" platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) @@ -86,6 +100,7 @@ if [[ "$1" == "init" ]]; then add_i2c_devices /usr/local/bin/set-fan-speed 15000 + switch_board_qsfp_lpmode "disable" /usr/local/bin/reset-qsfp elif [[ "$1" == "deinit" ]]; then remove_i2c_devices From edde1222b0893b20369e566db0c6d537e63335ec Mon Sep 17 00:00:00 2001 From: taochengyi <54564117+taocy001@users.noreply.github.com> Date: Sat, 16 May 2020 05:49:22 +0800 Subject: [PATCH 0659/1427] [CENTEC] Fix compile issues for centec x86 platform image build under 4.19 (#4605) * centec x86 update for buster * optimize dal code --- .../es6220/modules => centec-dal}/Makefile | 0 .../modules => centec-dal}/dal_kernel.c | 19 - .../modules => centec-dal}/dal_kernel.h | 0 .../modules => centec-dal}/dal_mpool.c | 0 .../modules => centec-dal}/dal_mpool.h | 0 platform/centec/docker-syncd-centec-rpc.mk | 3 +- platform/centec/docker-syncd-centec.mk | 18 +- platform/centec/rules.mk | 3 +- .../48x2q4z/modules/Makefile | 3 +- .../48x6q/modules/Makefile | 3 +- .../48x6q/modules/dal_kernel.c | 1833 ----------------- .../48x6q/modules/dal_kernel.h | 171 -- .../48x6q/modules/dal_mpool.c | 350 ---- .../48x6q/modules/dal_mpool.h | 72 - .../sonic-platform-modules-e582/debian/rules | 2 +- .../debian/control | 2 +- .../debian/rules | 2 +- .../es6220/modules/dal_kernel.c | 1833 ----------------- .../es6220/modules/dal_kernel.h | 171 -- .../es6220/modules/dal_mpool.c | 350 ---- .../es6220/modules/dal_mpool.h | 72 - 21 files changed, 14 insertions(+), 4893 deletions(-) rename platform/centec/{sonic-platform-modules-embedway/es6220/modules => centec-dal}/Makefile (100%) rename platform/centec/{sonic-platform-modules-e582/48x2q4z/modules => centec-dal}/dal_kernel.c (98%) rename platform/centec/{sonic-platform-modules-e582/48x2q4z/modules => centec-dal}/dal_kernel.h (100%) rename platform/centec/{sonic-platform-modules-e582/48x2q4z/modules => centec-dal}/dal_mpool.c (100%) rename platform/centec/{sonic-platform-modules-e582/48x2q4z/modules => centec-dal}/dal_mpool.h (100%) delete mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.c delete mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.h delete mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.c delete mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.h delete mode 100644 platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.c delete mode 100644 platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.h delete mode 100644 platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.c delete mode 100644 platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.h diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/modules/Makefile b/platform/centec/centec-dal/Makefile similarity index 100% rename from platform/centec/sonic-platform-modules-embedway/es6220/modules/Makefile rename to platform/centec/centec-dal/Makefile diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c b/platform/centec/centec-dal/dal_kernel.c similarity index 98% rename from platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c rename to platform/centec/centec-dal/dal_kernel.c index 32a38f842cfa..e47178d1496f 100644 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c +++ b/platform/centec/centec-dal/dal_kernel.c @@ -580,25 +580,6 @@ _dal_set_msi_enabe(unsigned int lchip, unsigned int irq_num) msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; msi_irq_num[lchip] = 1; } - else - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 79)) - ret = pci_enable_msi_exact(dal_dev[lchip].pci_dev, irq_num); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 26, 32)) - ret = pci_enable_msi_block(dal_dev[lchip].pci_dev, irq_num); -#else - ret = -1; -#endif - if (ret) - { - printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); - pci_disable_msi(dal_dev[lchip].pci_dev); - msi_used = 0; - } - - msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; - msi_irq_num[lchip] = irq_num; - } return ret; } diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.h b/platform/centec/centec-dal/dal_kernel.h similarity index 100% rename from platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.h rename to platform/centec/centec-dal/dal_kernel.h diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.c b/platform/centec/centec-dal/dal_mpool.c similarity index 100% rename from platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.c rename to platform/centec/centec-dal/dal_mpool.c diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.h b/platform/centec/centec-dal/dal_mpool.h similarity index 100% rename from platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.h rename to platform/centec/centec-dal/dal_mpool.h diff --git a/platform/centec/docker-syncd-centec-rpc.mk b/platform/centec/docker-syncd-centec-rpc.mk index a13a32d4a5b4..8915f1c35679 100644 --- a/platform/centec/docker-syncd-centec-rpc.mk +++ b/platform/centec/docker-syncd-centec-rpc.mk @@ -10,8 +10,9 @@ $(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) endif -$(DOCKER_SYNCD_CENTEC_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_CENTEC) +$(DOCKER_SYNCD_CENTEC_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC_RPC) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_CENTEC_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC_RPC) endif diff --git a/platform/centec/docker-syncd-centec.mk b/platform/centec/docker-syncd-centec.mk index f5cadc0b3f6d..9d512b12b459 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -1,22 +1,16 @@ # docker image for centec syncd -DOCKER_SYNCD_CENTEC = docker-syncd-centec.gz -$(DOCKER_SYNCD_CENTEC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec -$(DOCKER_SYNCD_CENTEC)_DEPENDS += $(SYNCD) -$(DOCKER_SYNCD_CENTEC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) -ifeq ($(INSTALL_DEBUG_TOOLS), y) +DOCKER_SYNCD_PLATFORM_CODE = centec +include $(PLATFORM_PATH)/../template/docker-syncd-base.mk + +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) + $(DOCKER_SYNCD_CENTEC)_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) -endif -$(DOCKER_SYNCD_CENTEC)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) -SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC) -ifneq ($(ENABLE_SYNCD_RPC),y) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC) -endif -$(DOCKER_SYNCD_CENTEC)_CONTAINER_NAME = syncd + $(DOCKER_SYNCD_CENTEC)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd diff --git a/platform/centec/rules.mk b/platform/centec/rules.mk index 942d98a6556e..873380c04467 100644 --- a/platform/centec/rules.mk +++ b/platform/centec/rules.mk @@ -7,8 +7,7 @@ include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-centec.mk -SONIC_ALL += $(SONIC_ONE_IMAGE) \ - $(DOCKER_SYNCD_CENTEC_RPC) +SONIC_ALL += $(SONIC_ONE_IMAGE) # Inject centec sai into sairedis $(LIBSAIREDIS)_DEPENDS += $(CENTEC_SAI) diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile index d1ca9824aa9e..645ca1c2e9e1 100644 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile @@ -1,2 +1 @@ -obj-m := centec_e582_48x2q4z_platform.o dal.o centec_at24c64.o -dal-y := dal_kernel.o dal_mpool.o +obj-m := centec_e582_48x2q4z_platform.o centec_at24c64.o diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile b/platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile index 25df81bba426..2462555c8714 100644 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile +++ b/platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile @@ -1,2 +1 @@ -obj-m := centec_e582_48x6q_platform.o dal.o centec_at24c64.o -dal-y := dal_kernel.o dal_mpool.o +obj-m := centec_e582_48x6q_platform.o centec_at24c64.o diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.c b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.c deleted file mode 100644 index 32a38f842cfa..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.c +++ /dev/null @@ -1,1833 +0,0 @@ -/** - @file dal_kernal.c - - @date 2012-10-18 - - @version v2.0 - - -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) -#include -#endif -#include "dal_kernel.h" -#include "dal_mpool.h" -#include -MODULE_AUTHOR("Centec Networks Inc."); -MODULE_DESCRIPTION("DAL kernel module"); -MODULE_LICENSE("GPL"); - -/* DMA memory pool size */ -static char* dma_pool_size; -module_param(dma_pool_size, charp, 0); -MODULE_PARM_DESC(dma_pool_size, - "Specify DMA memory pool size (default 4MB)"); - -/***************************************************************************** - * defines - *****************************************************************************/ -#define MB_SIZE 0x100000 -#define CTC_MAX_INTR_NUM 8 - -#define MEM_MAP_RESERVE SetPageReserved -#define MEM_MAP_UNRESERVE ClearPageReserved - -#define CTC_VENDOR_VID 0xc001 -#define CTC_HUMBER_DEVICE_ID 0x6048 -#define CTC_GOLDENGATE_DEVICE_ID 0xc010 -#define CTC_PCIE_VENDOR_ID 0xcb10 -#define CTC_DUET2_DEVICE_ID 0x7148 - -#define MEM_MAP_RESERVE SetPageReserved -#define MEM_MAP_UNRESERVE ClearPageReserved - -#define CTC_GREATBELT_DEVICE_ID 0x03e8 /* TBD */ -#define DAL_MAX_CHIP_NUM 8 /* [GB] used */ -#define VIRT_TO_PAGE(p) virt_to_page((p)) -#define DAL_UNTAG_BLOCK 0 -#define DAL_DISCARD_BLOCK 1 -#define DAL_MATCHED_BLOCK 2 -#define DAL_CUR_MATCH_BLOCk 3 -/***************************************************************************** - * typedef - *****************************************************************************/ -/* Control Data */ -typedef struct dal_isr_s -{ - int irq; - void (* isr)(void*); - void* isr_data; - int trigger; - int count; - wait_queue_head_t wqh; -} dal_isr_t; - -typedef struct dal_kernel_dev_s -{ - struct list_head list; - struct pci_dev* pci_dev; - - /* PCI I/O mapped base address */ - uintptr logic_address; - - /* Physical address */ - unsigned long long phys_address; -} dal_kern_dev_t; - -typedef struct _dma_segment -{ - struct list_head list; - unsigned long req_size; /* Requested DMA segment size */ - unsigned long blk_size; /* DMA block size */ - unsigned long blk_order; /* DMA block size in alternate format */ - unsigned long seg_size; /* Current DMA segment size */ - unsigned long seg_begin; /* Logical address of segment */ - unsigned long seg_end; /* Logical end address of segment */ - unsigned long* blk_ptr; /* Array of logical DMA block addresses */ - int blk_cnt_max; /* Maximum number of block to allocate */ - int blk_cnt; /* Current number of blocks allocated */ -} dma_segment_t; - -typedef irqreturn_t (*p_func) (int irq, void* dev_id); - -/*************************************************************************** - *declared - ***************************************************************************/ -static unsigned int linux_dal_poll0(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll1(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll2(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll3(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll4(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll5(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll6(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll7(struct file* filp, struct poll_table_struct* p); - -/***************************************************************************** - * global variables - *****************************************************************************/ -static dal_kern_dev_t dal_dev[DAL_MAX_CHIP_NUM]; -static dal_isr_t dal_isr[CTC_MAX_INTR_NUM]; -static int dal_chip_num = 0; -static int dal_version = 0; -static int dal_intr_num = 0; -static int use_high_memory = 0; -static unsigned int* dma_virt_base[DAL_MAX_CHIP_NUM]; -#ifndef DMA_MEM_MODE_PLATFORM -static unsigned int* dma_virt_base_tmp[DAL_MAX_CHIP_NUM]; -#endif -static unsigned long long dma_phy_base[DAL_MAX_CHIP_NUM]; -static unsigned int dma_mem_size = 0xc00000; -static unsigned int msi_irq_base[DAL_MAX_CHIP_NUM]; -static unsigned int msi_irq_num[DAL_MAX_CHIP_NUM]; -static unsigned int msi_used = 0; -static struct class *dal_class; - -static LIST_HEAD(_dma_seg); -static int dal_debug = 0; -module_param(dal_debug, int, 0); -MODULE_PARM_DESC(dal_debug, "Set debug level (default 0)"); - -static struct pci_device_id dal_id_table[] = -{ - {PCI_DEVICE(CTC_VENDOR_VID, CTC_GREATBELT_DEVICE_ID)}, - {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_GOLDENGATE_DEVICE_ID)}, - {PCI_DEVICE((CTC_PCIE_VENDOR_ID+1), (CTC_GOLDENGATE_DEVICE_ID+1))}, - {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_DUET2_DEVICE_ID)}, - {0, }, -}; - -static wait_queue_head_t poll_intr[CTC_MAX_INTR_NUM]; - -p_func intr_handler_fun[CTC_MAX_INTR_NUM]; - -static int poll_intr_trigger[CTC_MAX_INTR_NUM]; - -static struct file_operations dal_intr_fops[CTC_MAX_INTR_NUM] = -{ - { - .owner = THIS_MODULE, - .poll = linux_dal_poll0, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll1, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll2, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll3, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll4, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll5, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll6, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll7, - }, -}; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) -#include -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt -#endif -/***************************************************************************** - * macros - *****************************************************************************/ -#define VERIFY_CHIP_INDEX(n) (n < dal_chip_num) - -#define _KERNEL_INTERUPT_PROCESS -static irqreturn_t -intr0_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - - if(poll_intr_trigger[0]) - { - return IRQ_HANDLED; - } - - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[0] = 1; - wake_up(&poll_intr[0]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr1_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[1]) - { - return IRQ_HANDLED; - } - - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[1] = 1; - wake_up(&poll_intr[1]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr2_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[2]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[2] = 1; - wake_up(&poll_intr[2]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr3_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[3]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[3] = 1; - wake_up(&poll_intr[3]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr4_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[4]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[4] = 1; - wake_up(&poll_intr[4]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr5_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[5]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[5] = 1; - wake_up(&poll_intr[5]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr6_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[6]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[6] = 1; - wake_up(&poll_intr[6]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr7_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[7]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[7] = 1; - wake_up(&poll_intr[7]); - } - } - - return IRQ_HANDLED; -} - -int -dal_interrupt_register(unsigned int irq, int prio, void (* isr)(void*), void* data) -{ - int ret; - unsigned char str[16]; - unsigned char* int_name = NULL; - unsigned int intr_num_tmp = 0; - unsigned int intr_num = CTC_MAX_INTR_NUM; - unsigned long irq_flags = 0; - - if (dal_intr_num >= CTC_MAX_INTR_NUM) - { - printk("Interrupt numbers exceeds max.\n"); - return -1; - } - - if (msi_used) - { - int_name = "dal_msi"; - } - else - { - int_name = "dal_intr"; - } - - - for (intr_num_tmp=0;intr_num_tmp < CTC_MAX_INTR_NUM; intr_num_tmp++) - { - if (irq == dal_isr[intr_num_tmp].irq) - { - if (0 == msi_used) - { - dal_isr[intr_num_tmp].count++; - printk("Interrupt irq %d register count %d.\n", irq, dal_isr[intr_num_tmp].count); - } - return 0; - } - if ((0 == dal_isr[intr_num_tmp].irq) && (CTC_MAX_INTR_NUM == intr_num)) - { - intr_num = intr_num_tmp; - dal_isr[intr_num].count = 0; - } - } - dal_isr[intr_num].irq = irq; - dal_isr[intr_num].isr = isr; - dal_isr[intr_num].isr_data = data; - dal_isr[intr_num].count++; - - init_waitqueue_head(&poll_intr[intr_num]); - - /* only user mode */ - if ((NULL == isr) && (NULL == data)) - { - snprintf(str, 16, "%s%d", "dal_intr", intr_num); - ret = register_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, - str, &dal_intr_fops[intr_num]); - if (ret < 0) - { - printk("Register character device for irq %d failed, ret= %d", irq, ret); - return ret; - } - } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) - irq_flags = 0; -#else - irq_flags = IRQF_DISABLED; -#endif - if ((ret = request_irq(irq, - intr_handler_fun[intr_num], - irq_flags, - int_name, - &dal_isr[intr_num])) < 0) - { - printk("Cannot request irq %d, ret %d.\n", irq, ret); - unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, str); - } - - if (0 == ret) - { - dal_intr_num++; - } - - return ret; -} - -int -dal_interrupt_unregister(unsigned int irq) -{ - unsigned char str[16]; - int intr_idx = 0; - int find_flag = 0; - - /* get intr device index */ - for (intr_idx = 0; intr_idx < CTC_MAX_INTR_NUM; intr_idx++) - { - if (dal_isr[intr_idx].irq == irq) - { - find_flag = 1; - break; - } - } - - if (find_flag == 0) - { - printk ("irq%d is not registered! unregister failed \n", irq); - return -1; - } - - dal_isr[intr_idx].count--; - if (0 != dal_isr[intr_idx].count) - { - printk("Interrupt irq %d unregister count %d.\n", irq, dal_isr[intr_idx].count); - return -1; - } - snprintf(str, 16, "%s%d", "dal_intr", intr_idx); - - unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_idx, str); - - free_irq(irq, &dal_isr[intr_idx]); - - dal_isr[intr_idx].irq = 0; - - dal_intr_num--; - - return 0; -} - -int -dal_interrupt_set_en(unsigned int irq, unsigned int enable) -{ - enable ? enable_irq(irq) : disable_irq_nosync(irq); - return 0; -} - -static int -_dal_set_msi_enabe(unsigned int lchip, unsigned int irq_num) -{ - int ret = 0; - - if (irq_num == 1) - { - ret = pci_enable_msi(dal_dev[lchip].pci_dev); - if (ret) - { - printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); - pci_disable_msi(dal_dev[lchip].pci_dev); - msi_used = 0; - } - - msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; - msi_irq_num[lchip] = 1; - } - else - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 79)) - ret = pci_enable_msi_exact(dal_dev[lchip].pci_dev, irq_num); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 26, 32)) - ret = pci_enable_msi_block(dal_dev[lchip].pci_dev, irq_num); -#else - ret = -1; -#endif - if (ret) - { - printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); - pci_disable_msi(dal_dev[lchip].pci_dev); - msi_used = 0; - } - - msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; - msi_irq_num[lchip] = irq_num; - } - - return ret; -} - -static int -_dal_set_msi_disable(unsigned int lchip) -{ - - pci_disable_msi(dal_dev[lchip].pci_dev); - - msi_irq_base[lchip] = 0; - msi_irq_num[lchip] = 0; - - return 0; -} - -int -dal_set_msi_cap(unsigned long arg) -{ - int ret = 0; - int index = 0; - dal_msi_info_t msi_info; - - if (copy_from_user(&msi_info, (void*)arg, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - - printk("####dal_set_msi_cap lchip %d base %d num:%d\n", msi_info.lchip, msi_info.irq_base, msi_info.irq_num); - if (msi_info.irq_num > 0) - { - if (0 == msi_used) - { - msi_used = 1; - ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); - } - else if ((1 == msi_used) && (msi_info.irq_num != msi_irq_num[msi_info.lchip])) - { - for (index = 0; index < msi_irq_num[msi_info.lchip]; index++) - { - dal_interrupt_unregister(msi_irq_base[msi_info.lchip]+index); - } - _dal_set_msi_disable(msi_info.lchip); - msi_used = 1; - ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); - } - } - else - { - msi_used = 0; - ret = _dal_set_msi_disable(msi_info.lchip); - } - - return ret; -} - -int -dal_user_interrupt_register(unsigned long arg) -{ - int irq = 0; - if (copy_from_user(&irq, (void*)arg, sizeof(int))) - { - return -EFAULT; - } - printk("####register interrupt irq:%d\n", irq); - return dal_interrupt_register(irq, 0, NULL, NULL); -} - -int -dal_user_interrupt_unregister(unsigned long arg) -{ - int irq = 0; - if (copy_from_user(&irq, (void*)arg, sizeof(int))) - { - return -EFAULT; - } - printk("####unregister interrupt irq:%d\n", irq); - return dal_interrupt_unregister(irq); -} - -int -dal_user_interrupt_set_en(unsigned long arg) -{ - dal_intr_parm_t dal_intr_parm; - - if (copy_from_user(&dal_intr_parm, (void*)arg, sizeof(dal_intr_parm_t))) - { - return -EFAULT; - } - - return dal_interrupt_set_en(dal_intr_parm.irq, dal_intr_parm.enable); -} - -/* - * Function: _dal_dma_segment_free - */ - -/* - * Function: _find_largest_segment - * - * Purpose: - * Find largest contiguous segment from a pool of DMA blocks. - * Parameters: - * dseg - DMA segment descriptor - * Returns: - * 0 on success, < 0 on error. - * Notes: - * Assembly stops if a segment of the requested segment size - * has been obtained. - * - * Lower address bits of the DMA blocks are used as follows: - * 0: Untagged - * 1: Discarded block - * 2: Part of largest contiguous segment - * 3: Part of current contiguous segment - */ -#ifndef DMA_MEM_MODE_PLATFORM -static int -_dal_find_largest_segment(dma_segment_t* dseg) -{ - int i, j, blks, found; - unsigned long seg_begin; - unsigned long seg_end; - unsigned long seg_tmp; - - blks = dseg->blk_cnt; - - /* Clear all block tags */ - for (i = 0; i < blks; i++) - { - dseg->blk_ptr[i] &= ~3; - } - - for (i = 0; i < blks && dseg->seg_size < dseg->req_size; i++) - { - /* First block must be an untagged block */ - if ((dseg->blk_ptr[i] & 3) == DAL_UNTAG_BLOCK) - { - /* Initial segment size is the block size */ - seg_begin = dseg->blk_ptr[i]; - seg_end = seg_begin + dseg->blk_size; - dseg->blk_ptr[i] |= DAL_CUR_MATCH_BLOCk; - - /* Loop looking for adjacent blocks */ - do - { - found = 0; - - for (j = i + 1; j < blks && (seg_end - seg_begin) < dseg->req_size; j++) - { - seg_tmp = dseg->blk_ptr[j]; - /* Check untagged blocks only */ - if ((seg_tmp & 3) == DAL_UNTAG_BLOCK) - { - if (seg_tmp == (seg_begin - dseg->blk_size)) - { - /* Found adjacent block below current segment */ - dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; - seg_begin = seg_tmp; - found = 1; - } - else if (seg_tmp == seg_end) - { - /* Found adjacent block above current segment */ - dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; - seg_end += dseg->blk_size; - found = 1; - } - } - } - } - while (found); - - if ((seg_end - seg_begin) > dseg->seg_size) - { - /* The current block is largest so far */ - dseg->seg_begin = seg_begin; - dseg->seg_end = seg_end; - dseg->seg_size = seg_end - seg_begin; - - /* Re-tag current and previous largest segment */ - for (j = 0; j < blks; j++) - { - if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) - { - /* Tag current segment as the largest */ - dseg->blk_ptr[j] &= ~1; - } - else if ((dseg->blk_ptr[j] & 3) == DAL_MATCHED_BLOCK) - { - /* Discard previous largest segment */ - dseg->blk_ptr[j] ^= 3; - } - } - } - else - { - /* Discard all blocks in current segment */ - for (j = 0; j < blks; j++) - { - if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) - { - dseg->blk_ptr[j] &= ~2; - } - } - } - } - } - - return 0; -} - -/* - * Function: _alloc_dma_blocks - */ -static int -_dal_alloc_dma_blocks(dma_segment_t* dseg, int blks) -{ - int i, start; - unsigned long addr; - - if (dseg->blk_cnt + blks > dseg->blk_cnt_max) - { - printk("No more DMA blocks\n"); - return -1; - } - - start = dseg->blk_cnt; - dseg->blk_cnt += blks; - - for (i = start; i < dseg->blk_cnt; i++) - { - addr = __get_free_pages(GFP_ATOMIC, dseg->blk_order); - if (addr) - { - dseg->blk_ptr[i] = addr; - } - else - { - printk("DMA allocation failed\n"); - return -1; - } - } - - return 0; -} - -/* - * Function: _dal_dma_segment_alloc - */ -static dma_segment_t* -_dal_dma_segment_alloc(unsigned int size, unsigned int blk_size) -{ - dma_segment_t* dseg; - int i, blk_ptr_size; - unsigned long page_addr; - struct sysinfo si; - - /* Sanity check */ - if (size == 0 || blk_size == 0) - { - return NULL; - } - - /* Allocate an initialize DMA segment descriptor */ - if ((dseg = kmalloc(sizeof(dma_segment_t), GFP_ATOMIC)) == NULL) - { - return NULL; - } - - memset(dseg, 0, sizeof(dma_segment_t)); - dseg->req_size = size; - dseg->blk_size = PAGE_ALIGN(blk_size); - - while ((PAGE_SIZE << dseg->blk_order) < dseg->blk_size) - { - dseg->blk_order++; - } - - si_meminfo(&si); - dseg->blk_cnt_max = (si.totalram << PAGE_SHIFT) / dseg->blk_size; - blk_ptr_size = dseg->blk_cnt_max * sizeof(unsigned long); - /* Allocate an initialize DMA block pool */ - dseg->blk_ptr = kmalloc(blk_ptr_size, GFP_KERNEL); - if (dseg->blk_ptr == NULL) - { - kfree(dseg); - return NULL; - } - - memset(dseg->blk_ptr, 0, blk_ptr_size); - /* Allocate minimum number of blocks */ - _dal_alloc_dma_blocks(dseg, dseg->req_size / dseg->blk_size); - - /* Allocate more blocks until we have a complete segment */ - do - { - _dal_find_largest_segment(dseg); - if (dseg->seg_size >= dseg->req_size) - { - break; - } - } - while (_dal_alloc_dma_blocks(dseg, 8) == 0); - - /* Reserve all pages in the DMA segment and free unused blocks */ - for (i = 0; i < dseg->blk_cnt; i++) - { - if ((dseg->blk_ptr[i] & 3) == 2) - { - dseg->blk_ptr[i] &= ~3; - - for (page_addr = dseg->blk_ptr[i]; - page_addr < dseg->blk_ptr[i] + dseg->blk_size; - page_addr += PAGE_SIZE) - { - MEM_MAP_RESERVE(VIRT_TO_PAGE((void*)page_addr)); - } - } - else if (dseg->blk_ptr[i]) - { - dseg->blk_ptr[i] &= ~3; - free_pages(dseg->blk_ptr[i], dseg->blk_order); - dseg->blk_ptr[i] = 0; - } - } - - return dseg; -} - -/* - * Function: _dal_dma_segment_free - */ -static void -_dal_dma_segment_free(dma_segment_t* dseg) -{ - int i; - unsigned long page_addr; - - if (dseg->blk_ptr) - { - for (i = 0; i < dseg->blk_cnt; i++) - { - if (dseg->blk_ptr[i]) - { - for (page_addr = dseg->blk_ptr[i]; - page_addr < dseg->blk_ptr[i] + dseg->blk_size; - page_addr += PAGE_SIZE) - { - MEM_MAP_UNRESERVE(VIRT_TO_PAGE(page_addr)); - } - - free_pages(dseg->blk_ptr[i], dseg->blk_order); - } - } - - kfree(dseg->blk_ptr); - kfree(dseg); - } -} - -/* - * Function: -dal_pgalloc - */ -static void* -_dal_pgalloc(unsigned int size) -{ - dma_segment_t* dseg; - unsigned int blk_size; - - blk_size = (size < DMA_BLOCK_SIZE) ? size : DMA_BLOCK_SIZE; - if ((dseg = _dal_dma_segment_alloc(size, blk_size)) == NULL) - { - return NULL; - } - - if (dseg->seg_size < size) - { - /* If we didn't get the full size then forget it */ - printk("Notice: Can not get enough memory for requset!!\n"); - printk("actual size:0x%lx, request size:0x%x\n", dseg->seg_size, size); - //-_dal_dma_segment_free(dseg); - //-return NULL; - } - - list_add(&dseg->list, &_dma_seg); - return (void*)dseg->seg_begin; -} - -/* - * Function: _dal_pgfree - */ -static int -_dal_pgfree(void* ptr) -{ - struct list_head* pos; - - list_for_each(pos, &_dma_seg) - { - dma_segment_t* dseg = list_entry(pos, dma_segment_t, list); - if (ptr == (void*)dseg->seg_begin) - { - list_del(&dseg->list); - _dal_dma_segment_free(dseg); - return 0; - } - } - return -1; -} -#endif -static void -dal_alloc_dma_pool(int lchip, int size) -{ - if (use_high_memory) - { - dma_phy_base[lchip] = virt_to_bus(high_memory); - dma_virt_base[lchip] = ioremap_nocache(dma_phy_base[lchip], size); - } - else - { -#ifdef DMA_MEM_MODE_PLATFORM - dma_virt_base[lchip] = dma_alloc_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, - &dma_phy_base[lchip], GFP_KERNEL); - - printk(KERN_WARNING "########Using DMA_MEM_MODE_PLATFORM \n"); -#endif - -#ifndef DMA_MEM_MODE_PLATFORM - /* Get DMA memory from kernel */ - dma_virt_base_tmp[lchip] = _dal_pgalloc(size); - dma_phy_base[lchip] = virt_to_bus(dma_virt_base_tmp[lchip]); - dma_virt_base [lchip]= ioremap_nocache(dma_phy_base[lchip], size); -#endif - } -} - -static void -dal_free_dma_pool(int lchip) -{ - int ret = 0; - ret = ret; - if (use_high_memory) - { - iounmap(dma_virt_base[lchip]); - } - else - { -#ifdef DMA_MEM_MODE_PLATFORM - dma_free_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, - dma_virt_base[lchip], dma_phy_base[lchip]); -#endif - -#ifndef DMA_MEM_MODE_PLATFORM - iounmap(dma_virt_base[lchip]); - ret = _dal_pgfree(dma_virt_base_tmp[lchip]); - if(ret<0) - { - printk("Dma free memory fail !!!!!! \n"); - } -#endif - } -} - -#define _KERNEL_DAL_IO -static int -_dal_pci_read(unsigned char lchip, unsigned int offset, unsigned int* value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - *value = *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset); - return 0; -} - -int -dal_create_irq_mapping(unsigned long arg) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) - -#ifndef NO_IRQ -#define NO_IRQ (-1) -#endif - dal_irq_mapping_t irq_map; - - if (copy_from_user(&irq_map, (void*)arg, sizeof(dal_irq_mapping_t))) - { - return -EFAULT; - } - - irq_map.sw_irq = irq_create_mapping(NULL, irq_map.hw_irq); - if (irq_map.sw_irq == NO_IRQ) - { - printk("IRQ mapping fail !!!!!! \n"); - return -1; - } - - if (copy_to_user((dal_irq_mapping_t*)arg, (void*)&irq_map, sizeof(dal_irq_mapping_t))) - { - return -EFAULT; - } -#endif - return 0; -} - -int -dal_pci_read(unsigned long arg) -{ - dal_chip_parm_t cmdpara_chip; - - if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - _dal_pci_read((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, - (unsigned int*)(&(cmdpara_chip.value))); - - if (copy_to_user((dal_chip_parm_t*)arg, (void*)&cmdpara_chip, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -_dal_pci_write(unsigned char lchip, unsigned int offset, unsigned int value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset) = value; - return 0; -} - -int -dal_pci_write(unsigned long arg) -{ - dal_chip_parm_t cmdpara_chip; - - if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - _dal_pci_write((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, - (unsigned int)cmdpara_chip.value); - - return 0; -} - -int -dal_pci_conf_read(unsigned char lchip, unsigned int offset, unsigned int* value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - pci_read_config_dword(dal_dev[lchip].pci_dev, offset, value); - return 0; -} - -int -dal_pci_conf_write(unsigned char lchip, unsigned int offset, unsigned int value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - pci_write_config_dword(dal_dev[lchip].pci_dev, offset, value); - return 0; -} -int -dal_user_read_pci_conf(unsigned long arg) -{ - dal_pci_cfg_ioctl_t dal_cfg; - - if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - if (dal_pci_conf_read(dal_cfg.lchip, dal_cfg.offset, &dal_cfg.value)) - { - printk("dal_pci_conf_read failed.\n"); - return -EFAULT; - } - - if (copy_to_user((dal_pci_cfg_ioctl_t*)arg, (void*)&dal_cfg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - return 0; -} - -int -dal_user_write_pci_conf(unsigned long arg) -{ - dal_pci_cfg_ioctl_t dal_cfg; - - if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - return dal_pci_conf_write(dal_cfg.lchip, dal_cfg.offset, dal_cfg.value); -} - -static int -linux_get_device(unsigned long arg) -{ - dal_user_dev_t user_dev; - int lchip = 0; - - if (copy_from_user(&user_dev, (void*)arg, sizeof(user_dev))) - { - return -EFAULT; - } - - user_dev.chip_num = dal_chip_num; - lchip = user_dev.lchip; - - if (lchip < dal_chip_num) - { - user_dev.phy_base0 = (unsigned int)dal_dev[lchip].phys_address; - user_dev.phy_base1 = (unsigned int)(dal_dev[lchip].phys_address >> 32); - - user_dev.bus_no = dal_dev[lchip].pci_dev->bus->number; - user_dev.dev_no = dal_dev[lchip].pci_dev->device; - user_dev.fun_no = dal_dev[lchip].pci_dev->devfn; - } - - if (copy_to_user((dal_user_dev_t*)arg, (void*)&user_dev, sizeof(user_dev))) - { - return -EFAULT; - } - - return 0; -} - -/* set dal version, copy to user */ -static int -linux_get_dal_version(unsigned long arg) -{ - int dal_ver = VERSION_1DOT2; /* set dal version */ - - if (copy_to_user((int*)arg, (void*)&dal_ver, sizeof(dal_ver))) - { - return -EFAULT; - } - - dal_version = dal_ver; /* up sw */ - - return 0; -} - -static int -linux_get_dma_info(unsigned long arg) -{ - dma_info_t dma_para; - - if (copy_from_user(&dma_para, (void*)arg, sizeof(dma_info_t))) - { - return -EFAULT; - } - - dma_para.phy_base = (unsigned int)dma_phy_base[dma_para.lchip]; - dma_para.phy_base_hi = dma_phy_base[dma_para.lchip] >> 32; - dma_para.size = dma_mem_size; - - if (copy_to_user((dma_info_t*)arg, (void*)&dma_para, sizeof(dma_info_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -dal_get_msi_info(unsigned long arg) -{ - dal_msi_info_t msi_para; - unsigned int lchip = 0; - - /* get lchip form user mode */ - if (copy_from_user(&msi_para, (void*)arg, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - lchip = msi_para.lchip; - - msi_para.irq_base = msi_irq_base[lchip]; - msi_para.irq_num = msi_irq_num[lchip]; - - /* send msi info to user mode */ - if (copy_to_user((dal_msi_info_t*)arg, (void*)&msi_para, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - - return 0; -} - - -static int -dal_get_intr_info(unsigned long arg) -{ - dal_intr_info_t intr_para; - unsigned int intr_num = 0; - - /* get lchip form user mode */ - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_intr_info_t))) - { - return -EFAULT; - } - - intr_para.irq_idx = CTC_MAX_INTR_NUM; - for (intr_num=0; intr_num< CTC_MAX_INTR_NUM; intr_num++) - { - if (intr_para.irq == dal_isr[intr_num].irq) - { - intr_para.irq_idx = intr_num; - break; - } - } - - if (CTC_MAX_INTR_NUM == intr_para.irq_idx) - { - printk("Interrupt %d cann't find.\n", intr_para.irq); - } - /* send msi info to user mode */ - if (copy_to_user((dal_intr_info_t*)arg, (void*)&intr_para, sizeof(dal_intr_info_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -dal_cache_inval(unsigned long arg) -{ - dal_dma_cache_info_t intr_para; - - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) - { - return -EFAULT; - } - -#if 0 - dma_cache_wback_inv((unsigned long)intr_para.ptr, intr_para.length); -#endif - -#if 0 - dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); - - - dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); -#endif - return 0; -} - -static int -dal_cache_flush(unsigned long arg) -{ - dal_dma_cache_info_t intr_para; - - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) - { - return -EFAULT; - } - -#if 0 - dma_cache_wback_inv(intr_para.ptr, intr_para.length); -#endif - -#if 0 - dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); - - - dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); -#endif - return 0; -} - -int -linux_dal_probe(struct pci_dev* pdev, const struct pci_device_id* id) -{ - dal_kern_dev_t* dev = NULL; - int bar = 0; - int ret = 0; - unsigned int temp = 0; - unsigned int lchip = 0; - - printk(KERN_WARNING "********found dal device*****\n"); - - for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) - { - if (NULL == dal_dev[lchip].pci_dev) - { - break; - } - } - - if (lchip >= DAL_MAX_CHIP_NUM) - { - printk("Exceed max local chip num\n"); - return -1; - } - - dev = &dal_dev[lchip]; - if (NULL == dev) - { - printk("Cannot obtain PCI resources\n"); - } - - lchip = lchip; - dal_chip_num += 1; - - dev->pci_dev = pdev; - - if (pci_enable_device(pdev) < 0) - { - printk("Cannot enable PCI device: vendor id = %x, device id = %x\n", - pdev->vendor, pdev->device); - } - - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); - if (ret) - { - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (ret) - { - printk("Could not set PCI DMA Mask\n"); - return ret; - } - } - - if (pci_request_regions(pdev, DAL_NAME) < 0) - { - printk("Cannot obtain PCI resources\n"); - } - - dev->phys_address = pci_resource_start(pdev, bar); - dev->logic_address = (uintptr)ioremap_nocache(dev->phys_address, - pci_resource_len(dev->pci_dev, bar)); - - _dal_pci_read(lchip, 0x48, &temp); - if (((temp >> 8) & 0xffff) == 0x3412) - { - printk("Little endian Cpu detected!!! \n"); - _dal_pci_write(lchip, 0x48, 0xFFFFFFFF); - } - - pci_set_master(pdev); - - /* alloc dma_mem_size for every chip */ - if (dma_mem_size) - { - dal_alloc_dma_pool(lchip, dma_mem_size); - - /*add check Dma memory pool cannot cross 4G space*/ - if ((0==(dma_phy_base[lchip]>>32)) && (0!=((dma_phy_base[lchip]+dma_mem_size)>>32))) - { - printk("Dma malloc memory cross 4G space!!!!!! \n"); - return -1; - } - } - - printk(KERN_WARNING "linux_dal_probe end*****\n"); - - return 0; -} - -void -linux_dal_remove(struct pci_dev* pdev) -{ - unsigned int lchip = 0; - unsigned int flag = 0; - - for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) - { - if (pdev == dal_dev[lchip].pci_dev) - { - flag = 1; - break; - } - } - - if (1 == flag) - { - dal_free_dma_pool(lchip); - pci_release_regions(pdev); - pci_disable_device(pdev); - - dal_dev[lchip].pci_dev = NULL; - dal_chip_num--; - } - - -} - -#ifdef CONFIG_COMPAT -static long -linux_dal_ioctl(struct file* file, - unsigned int cmd, unsigned long arg) -#else - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) -static int -linux_dal_ioctl(struct file* file, - unsigned int cmd, unsigned long arg) -#else -static int -linux_dal_ioctl(struct inode* inode, struct file* file, - unsigned int cmd, unsigned long arg) -#endif - -#endif -{ - switch (cmd) - { - - case CMD_READ_CHIP: - return dal_pci_read(arg); - - case CMD_WRITE_CHIP: - return dal_pci_write(arg); - - case CMD_GET_DEVICES: - return linux_get_device(arg); - - case CMD_GET_DAL_VERSION: - return linux_get_dal_version(arg); - - case CMD_GET_DMA_INFO: - return linux_get_dma_info(arg); - - case CMD_PCI_CONFIG_READ: - return dal_user_read_pci_conf(arg); - - case CMD_PCI_CONFIG_WRITE: - return dal_user_write_pci_conf(arg); - - case CMD_REG_INTERRUPTS: - return dal_user_interrupt_register(arg); - - case CMD_UNREG_INTERRUPTS: - return dal_user_interrupt_unregister(arg); - - case CMD_EN_INTERRUPTS: - return dal_user_interrupt_set_en(arg); - - case CMD_SET_MSI_CAP: - return dal_set_msi_cap(arg); - - case CMD_GET_MSI_INFO: - return dal_get_msi_info(arg); - - case CMD_IRQ_MAPPING: - return dal_create_irq_mapping(arg); - - case CMD_GET_INTR_INFO: - return dal_get_intr_info(arg); - - case CMD_CACHE_INVAL: - return dal_cache_inval(arg); - - case CMD_CACHE_FLUSH: - return dal_cache_flush(arg); - - default: - break; - } - - return 0; -} - -static unsigned int -linux_dal_poll0(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[0], p); - local_irq_save(flags); - if (poll_intr_trigger[0]) - { - poll_intr_trigger[0] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll1(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[1], p); - local_irq_save(flags); - if (poll_intr_trigger[1]) - { - poll_intr_trigger[1] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll2(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[2], p); - local_irq_save(flags); - if (poll_intr_trigger[2]) - { - poll_intr_trigger[2] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll3(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[3], p); - local_irq_save(flags); - if (poll_intr_trigger[3]) - { - poll_intr_trigger[3] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll4(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[4], p); - local_irq_save(flags); - if (poll_intr_trigger[4]) - { - poll_intr_trigger[4] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll5(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[5], p); - local_irq_save(flags); - if (poll_intr_trigger[5]) - { - poll_intr_trigger[5] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll6(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[6], p); - local_irq_save(flags); - if (poll_intr_trigger[6]) - { - poll_intr_trigger[6] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll7(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[7], p); - local_irq_save(flags); - if (poll_intr_trigger[7]) - { - poll_intr_trigger[7] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static struct pci_driver linux_dal_driver = -{ - .name = DAL_NAME, - .id_table = dal_id_table, - .probe = linux_dal_probe, - .remove = linux_dal_remove, -}; - -static struct file_operations fops = -{ - .owner = THIS_MODULE, -#ifdef CONFIG_COMPAT - .compat_ioctl = linux_dal_ioctl, - .unlocked_ioctl = linux_dal_ioctl, -#else -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) - .unlocked_ioctl = linux_dal_ioctl, -#else - .ioctl = linux_dal_ioctl, -#endif -#endif -}; - - -static int __init -linux_dal_init(void) -{ - int ret = 0; - - /* Get DMA memory pool size form dal.ok input param, or use default dma_mem_size */ - if (dma_pool_size) - { - if ((dma_pool_size[strlen(dma_pool_size) - 1] & ~0x20) == 'M') - { - dma_mem_size = simple_strtoul(dma_pool_size, NULL, 0); - printk("dma_mem_size: 0x%x \n", dma_mem_size); - - dma_mem_size *= MB_SIZE; - } - else - { - printk("DMA memory pool size must be specified as e.g. dma_pool_size=8M\n"); - } - - if (dma_mem_size & (dma_mem_size - 1)) - { - printk("dma_mem_size must be a power of 2 (1M, 2M, 4M, 8M etc.)\n"); - dma_mem_size = 0; - } - } - - ret = register_chrdev(DAL_DEV_MAJOR, DAL_NAME, &fops); - if (ret < 0) - { - printk(KERN_WARNING "Register linux_dal device, ret %d\n", ret); - return ret; - } - - ret = pci_register_driver(&linux_dal_driver); - if (ret < 0) - { - printk(KERN_WARNING "Register ASIC PCI driver failed, ret %d\n", ret); - return ret; - } - - /* alloc /dev/linux_dal node */ - dal_class = class_create(THIS_MODULE, DAL_NAME); - device_create(dal_class, NULL, MKDEV(DAL_DEV_MAJOR, 0), NULL, DAL_NAME); - - /* init interrupt function */ - intr_handler_fun[0] = intr0_handler; - intr_handler_fun[1] = intr1_handler; - intr_handler_fun[2] = intr2_handler; - intr_handler_fun[3] = intr3_handler; - intr_handler_fun[4] = intr4_handler; - intr_handler_fun[5] = intr5_handler; - intr_handler_fun[6] = intr6_handler; - intr_handler_fun[7] = intr7_handler; - - return ret; -} - -static void __exit -linux_dal_exit(void) -{ - device_destroy(dal_class, MKDEV(DAL_DEV_MAJOR, 0)); - class_destroy(dal_class); - unregister_chrdev(DAL_DEV_MAJOR, "linux_dal"); - pci_unregister_driver(&linux_dal_driver); -} - -module_init(linux_dal_init); -module_exit(linux_dal_exit); - - diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.h b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.h deleted file mode 100644 index 850a4cffa731..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - @file dal_kernel_io.h - - @author Copyright (C) 2012 Centec Networks Inc. All rights reserved. - - @date 2012-4-9 - - @version v2.0 - -*/ -#ifndef _DAL_KERNEL_H_ -#define _DAL_KERNEL_H_ -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(CONFIG_RESOURCES_64BIT) || defined(CONFIG_PHYS_ADDR_T_64BIT) -#define PHYS_ADDR_IS_64BIT -#endif - -#ifndef SDK_IN_USERMODE -#ifdef PHYS_ADDR_IS_64BIT -typedef long long intptr; -typedef unsigned long long uintptr; -#else -typedef int intptr; -typedef unsigned int uintptr; -#endif -#endif - -#define DAL_PCI_READ_ADDR 0x0 -#define DAL_PCI_READ_DATA 0xc -#define DAL_PCI_WRITE_ADDR 0x8 -#define DAL_PCI_WRITE_DATA 0x4 -#define DAL_PCI_STATUS 0x10 - -#define DAL_PCI_STATUS_IN_PROCESS 31 -#define DAL_PCI_STATUS_BAD_PARITY 5 -#define DAL_PCI_STATUS_CPU_ACCESS_ERR 4 -#define DAL_PCI_STATUS_READ_CMD 3 -#define DAL_PCI_STATUS_REGISTER_ERR 1 -#define DAL_PCI_STATUS_REGISTER_ACK 0 - -#define DAL_PCI_ACCESS_TIMEOUT 0x64 - -#define DAL_NAME "linux_dal" /* "linux_dal" */ - -#define DAL_DEV_MAJOR 198 - -#define DAL_DEV_INTR_MAJOR_BASE 200 - -#define DAL_DEV_NAME "/dev/" DAL_NAME -#define DAL_ONE_KB 1024 -#define DAL_ONE_MB (1024*1024) -struct dal_chip_parm_s -{ - unsigned int lchip; /*tmp should be uint8*/ - unsigned int fpga_id; /*tmp add*/ - unsigned int reg_addr; - unsigned int value; -}; -typedef struct dal_chip_parm_s dal_chip_parm_t; - -struct dal_intr_parm_s -{ - unsigned int irq; - unsigned int enable; -}; -typedef struct dal_intr_parm_s dal_intr_parm_t; - -struct dal_irq_mapping_s -{ - unsigned int hw_irq; - unsigned int sw_irq; -}; -typedef struct dal_irq_mapping_s dal_irq_mapping_t; - -struct dal_user_dev_s -{ - unsigned int chip_num; /*output: local chip number*/ - unsigned int lchip; /*input: local chip id*/ - unsigned int phy_base0; /* low 32bits physical base address */ - unsigned int phy_base1; /* high 32bits physical base address */ - unsigned int bus_no; - unsigned int dev_no; - unsigned int fun_no; - void* virt_base[2]; /* Virtual base address; this must be last member */ -}; -typedef struct dal_user_dev_s dal_user_dev_t; - -struct dma_info_s -{ - unsigned int lchip; - unsigned int phy_base; - unsigned int phy_base_hi; - unsigned int size; - unsigned int* virt_base; -}; -typedef struct dma_info_s dma_info_t; - -struct dal_pci_cfg_ioctl_s -{ - unsigned int lchip; /* Device ID */ - unsigned int offset; - unsigned int value; -}; -typedef struct dal_pci_cfg_ioctl_s dal_pci_cfg_ioctl_t; - -struct dal_msi_info_s -{ - unsigned int lchip; - unsigned int irq_base; - unsigned int irq_num; -}; -typedef struct dal_msi_info_s dal_msi_info_t; - -struct dal_intr_info_s -{ - unsigned int irq; - unsigned int irq_idx; -}; -typedef struct dal_intr_info_s dal_intr_info_t; - -struct dal_dma_cache_info_s -{ - unsigned long ptr; - unsigned int length; -}; -typedef struct dal_dma_cache_info_s dal_dma_cache_info_t; - -#define CMD_MAGIC 'C' -#define CMD_WRITE_CHIP _IO(CMD_MAGIC, 0) /* for humber ioctrol*/ -#define CMD_READ_CHIP _IO(CMD_MAGIC, 1) /* for humber ioctrol*/ -#define CMD_GET_DEVICES _IO(CMD_MAGIC, 2) -#define CMD_GET_DAL_VERSION _IO(CMD_MAGIC, 3) -#define CMD_PCI_CONFIG_WRITE _IO(CMD_MAGIC, 4) -#define CMD_PCI_CONFIG_READ _IO(CMD_MAGIC, 5) -#define CMD_GET_DMA_INFO _IO(CMD_MAGIC, 6) -#define CMD_REG_INTERRUPTS _IO(CMD_MAGIC, 7) -#define CMD_UNREG_INTERRUPTS _IO(CMD_MAGIC, 8) -#define CMD_EN_INTERRUPTS _IO(CMD_MAGIC, 9) -#define CMD_I2C_READ _IO(CMD_MAGIC, 10) -#define CMD_I2C_WRITE _IO(CMD_MAGIC, 11) -#define CMD_GET_MSI_INFO _IO(CMD_MAGIC, 12) -#define CMD_SET_MSI_CAP _IO(CMD_MAGIC, 13) -#define CMD_IRQ_MAPPING _IO(CMD_MAGIC, 14) -#define CMD_GET_INTR_INFO _IO(CMD_MAGIC, 15) -#define CMD_CACHE_INVAL _IO(CMD_MAGIC, 16) -#define CMD_CACHE_FLUSH _IO(CMD_MAGIC, 17) - -enum dal_version_e -{ - VERSION_MIN, - VERSION_1DOT0, - VERSION_1DOT1, - VERSION_1DOT2, - - VERSION_MAX -}; -typedef enum dal_version_e dal_version_t; - -/* We try to assemble a contiguous segment from chunks of this size */ -#define DMA_BLOCK_SIZE (512 * DAL_ONE_KB) - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.c b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.c deleted file mode 100644 index 5aca222a138f..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.c +++ /dev/null @@ -1,350 +0,0 @@ -#include "dal_mpool.h" - -#ifdef __KERNEL__ -#include -#include - -#define DAL_MALLOC(x) kmalloc(x, GFP_ATOMIC) -#define DAL_FREE(x) kfree(x) - -static spinlock_t dal_mpool_lock; -#define MPOOL_LOCK_INIT() spin_lock_init(&dal_mpool_lock) -#define MPOOL_LOCK() unsigned long flags; spin_lock_irqsave(&dal_mpool_lock, flags) -#define MPOOL_UNLOCK() spin_unlock_irqrestore(&dal_mpool_lock, flags) -#define DAL_PRINT(fmt,arg...) printk(fmt,##arg) -#else /* !__KERNEL__*/ - -#include -#include "sal.h" -#define DAL_MALLOC(x) malloc(x) -#define DAL_FREE(x) free(x) -static sal_mutex_t* dal_mpool_lock; -#define MPOOL_LOCK_INIT() sal_mutex_create(&dal_mpool_lock) -#define MPOOL_LOCK() sal_mutex_lock(dal_mpool_lock) -#define MPOOL_UNLOCK() sal_mutex_unlock(dal_mpool_lock) -#define DAL_PRINT(fmt,arg...) sal_printf(fmt,##arg) - -#endif /* __KERNEL__ */ - - - -dal_mpool_mem_t* g_free_block_ptr = NULL; - -/* System cache line size */ -#ifndef DAL_CACHE_LINE_BYTES -#define DAL_CACHE_LINE_BYTES 256 -#endif - -#define DAL_MAX_CHIP_NUM 32 -static dal_mpool_mem_t* p_desc_pool[DAL_MAX_CHIP_NUM] = {0}; -static dal_mpool_mem_t* p_data_pool[DAL_MAX_CHIP_NUM] = {0}; - -int -dal_mpool_init(void) -{ - MPOOL_LOCK_INIT(); - return 0; -} - -dal_mpool_mem_t* -_dal_mpool_create(void* base, int size, int type) -{ - dal_mpool_mem_t* head = NULL; - dal_mpool_mem_t* tail = NULL; - - head = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (head == NULL) - { - return NULL; - } - - tail = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (tail == NULL) - { - DAL_FREE(head); - return NULL; - } - - head->size = tail->size = 0; - head->type = type; - head->address = base; - tail->address = head->address + size; - head->next = tail; - tail->next = NULL; - - return head; -} - -dal_mpool_mem_t* -dal_mpool_create(unsigned char lchip, void* base, int size) -{ - dal_mpool_mem_t* head = NULL; - int mod = (int)(((unsigned long)base) & (DAL_CACHE_LINE_BYTES - 1)); - - MPOOL_LOCK(); - - if (mod) - { - base = (char*)base + (DAL_CACHE_LINE_BYTES - mod); - size -= (DAL_CACHE_LINE_BYTES - mod); - } - - size &= ~(DAL_CACHE_LINE_BYTES - 1); - - /* init for common linkptr, only used for GB */ - head = _dal_mpool_create(base, size, DAL_MPOOL_TYPE_USELESS); - if (NULL == head) - { - MPOOL_UNLOCK(); - return NULL; - } - - /* init for desc linkptr */ - p_desc_pool[lchip] = _dal_mpool_create(base, DAL_MPOOL_MAX_DESX_SIZE, DAL_MPOOL_TYPE_DESC); - if (NULL == p_desc_pool[lchip]) - { - MPOOL_UNLOCK(); - DAL_FREE(head->next); - DAL_FREE(head); - return NULL; - } - - /* init for data linkptr */ - p_data_pool[lchip] = _dal_mpool_create(((char*)base+DAL_MPOOL_MAX_DESX_SIZE), (size - DAL_MPOOL_MAX_DESX_SIZE), DAL_MPOOL_TYPE_DATA); - if (NULL == p_data_pool[lchip]) - { - MPOOL_UNLOCK(); - DAL_FREE(head->next); - DAL_FREE(head); - DAL_FREE(p_desc_pool[lchip]->next); - DAL_FREE(p_desc_pool[lchip]); - return NULL; - } - - MPOOL_UNLOCK(); - - return head; -} - -dal_mpool_mem_t* -_dal_mpool_alloc_comon(dal_mpool_mem_t* ptr, int size, int type) -{ - dal_mpool_mem_t* new_ptr = NULL; - - while (ptr && ptr->next) - { - if (ptr->next->address - (ptr->address + ptr->size) >= size) - { - break; - } - - ptr = ptr->next; - } - - if (!(ptr && ptr->next)) - { - return NULL; - } - - new_ptr = DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (!new_ptr) - { - return NULL; - } - - new_ptr->type = type; - new_ptr->address = ptr->address + ptr->size; - new_ptr->size = size; - new_ptr->next = ptr->next; - ptr->next = new_ptr; - - return new_ptr; -} - -void* -dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type) -{ - dal_mpool_mem_t* ptr = NULL; - dal_mpool_mem_t* new_ptr = NULL; - int mod; - - MPOOL_LOCK(); - - mod = size & (DAL_CACHE_LINE_BYTES - 1); - if (mod != 0) - { - size += (DAL_CACHE_LINE_BYTES - mod); - } - - switch(type) - { - case DAL_MPOOL_TYPE_USELESS: - ptr = pool; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - case DAL_MPOOL_TYPE_DESC: - ptr = p_desc_pool[lchip]; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - case DAL_MPOOL_TYPE_DATA: - ptr = p_data_pool[lchip]; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - default: - MPOOL_UNLOCK(); - return NULL; - break; - } - - MPOOL_UNLOCK(); - if( NULL == new_ptr ) - { - return NULL; - } - - return new_ptr->address; -} - -void -_dal_mpool_free(dal_mpool_mem_t* ptr, void* addr, int type) -{ - unsigned char* address = (unsigned char*)addr; - dal_mpool_mem_t* prev = NULL; - - while (ptr && ptr->next) - { - if (ptr->next->address == address) - { - break; - } - - ptr = ptr->next; - } - - if (ptr && ptr->next) - { - prev = ptr; - ptr = ptr->next; - prev->next = ptr->next; - DAL_FREE(ptr); - } - - return; -} - -void -dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr) -{ - dal_mpool_mem_t* ptr = pool; - - MPOOL_LOCK(); - - switch(pool->type) - { - case DAL_MPOOL_TYPE_USELESS: - ptr = pool; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_USELESS); - break; - case DAL_MPOOL_TYPE_DESC: - ptr = p_desc_pool[lchip]; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DESC); - break; - case DAL_MPOOL_TYPE_DATA: - ptr = p_data_pool[lchip]; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DATA); - break; - default: - break; - } - - MPOOL_UNLOCK(); - return; -} - -int -dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool) -{ - dal_mpool_mem_t* ptr, * next; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - for (ptr = p_desc_pool[lchip]; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - for (ptr = p_data_pool[lchip]; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - MPOOL_UNLOCK(); - - return 0; -} - -int -dal_mpool_usage(dal_mpool_mem_t* pool, int type) -{ - int usage = 0; - dal_mpool_mem_t* ptr; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = ptr->next) - { - if (ptr->type == type || ptr->type == -1) - { - usage += ptr->size; - } - } - - MPOOL_UNLOCK(); - - return usage; -} - -int -dal_mpool_debug(dal_mpool_mem_t* pool) -{ - dal_mpool_mem_t* ptr; - int index = 0; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = ptr->next) - { -// DAL_PRINT("%2dst mpool block: address=0x%8x, size=0x%x \n", index, (unsigned int)ptr->address, ptr->size); - DAL_PRINT("%2dst mpool block: address=%p, size=0x%x \n", index, ptr->address, ptr->size); // note - index++; - } - - MPOOL_UNLOCK(); - - return 0; -} - - diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.h b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.h deleted file mode 100644 index d93f88868136..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - @file dal_mpool.h - - @author Copyright (C) 2011 Centec Networks Inc. All rights reserved. - - @date 2012-5-10 - - @version v2.0 - - This file contains the dma memory init, allocation and free APIs -*/ - -#ifndef _DMA_MPOOL_H -#define _DMA_MPOOL_H -#ifdef __cplusplus -extern "C" { -#endif - -#define DAL_MPOOL_MAX_DESX_SIZE (1024*1024) - -enum dal_mpool_type_e -{ - DAL_MPOOL_TYPE_USELESS, /* just compatible with GB */ - DAL_MPOOL_TYPE_DESC, /* dma mpool op for desc */ - DAL_MPOOL_TYPE_DATA /* dma mpool op for data */ -}; -typedef enum dal_mpool_type_e dal_mpool_type_t; - -struct dal_mpool_mem_s -{ - unsigned char* address; - int size; - int type; - struct dal_mpool_mem_s* next; -}; -typedef struct dal_mpool_mem_s dal_mpool_mem_t; - -/** - @brief This function is to alloc dma memory - - @param[in] size size of memory - - @return NULL - -*/ -extern int -dal_mpool_init(void); - -extern dal_mpool_mem_t* -dal_mpool_create(unsigned char lchip, void* base_ptr, int size); - -extern void* -dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type); - -extern void -dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr); - -extern int -dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool); - -extern int -dal_mpool_usage(dal_mpool_mem_t* pool, int type); - -extern int -dal_mpool_debug(dal_mpool_mem_t* pool); -#ifdef __cplusplus -} -#endif - -#endif /* !_DMA_MPOOL_H */ - - diff --git a/platform/centec/sonic-platform-modules-e582/debian/rules b/platform/centec/sonic-platform-modules-e582/debian/rules index 9f5d67b1af5c..90a9c5642bae 100755 --- a/platform/centec/sonic-platform-modules-e582/debian/rules +++ b/platform/centec/sonic-platform-modules-e582/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= 48x6q 48x2q4z +MODULE_DIRS:= 48x6q 48x2q4z ../centec-dal %: dh $@ diff --git a/platform/centec/sonic-platform-modules-embedway/debian/control b/platform/centec/sonic-platform-modules-embedway/debian/control index 7c21cda6370d..044c847ddad6 100644 --- a/platform/centec/sonic-platform-modules-embedway/debian/control +++ b/platform/centec/sonic-platform-modules-embedway/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: platform-modules-embedway-es6220 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-embedway/debian/rules b/platform/centec/sonic-platform-modules-embedway/debian/rules index fa00b79d4fe2..20716d0620c6 100755 --- a/platform/centec/sonic-platform-modules-embedway/debian/rules +++ b/platform/centec/sonic-platform-modules-embedway/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= es6220 +MODULE_DIRS:= ../centec-dal %: dh $@ diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.c b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.c deleted file mode 100644 index 32a38f842cfa..000000000000 --- a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.c +++ /dev/null @@ -1,1833 +0,0 @@ -/** - @file dal_kernal.c - - @date 2012-10-18 - - @version v2.0 - - -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) -#include -#endif -#include "dal_kernel.h" -#include "dal_mpool.h" -#include -MODULE_AUTHOR("Centec Networks Inc."); -MODULE_DESCRIPTION("DAL kernel module"); -MODULE_LICENSE("GPL"); - -/* DMA memory pool size */ -static char* dma_pool_size; -module_param(dma_pool_size, charp, 0); -MODULE_PARM_DESC(dma_pool_size, - "Specify DMA memory pool size (default 4MB)"); - -/***************************************************************************** - * defines - *****************************************************************************/ -#define MB_SIZE 0x100000 -#define CTC_MAX_INTR_NUM 8 - -#define MEM_MAP_RESERVE SetPageReserved -#define MEM_MAP_UNRESERVE ClearPageReserved - -#define CTC_VENDOR_VID 0xc001 -#define CTC_HUMBER_DEVICE_ID 0x6048 -#define CTC_GOLDENGATE_DEVICE_ID 0xc010 -#define CTC_PCIE_VENDOR_ID 0xcb10 -#define CTC_DUET2_DEVICE_ID 0x7148 - -#define MEM_MAP_RESERVE SetPageReserved -#define MEM_MAP_UNRESERVE ClearPageReserved - -#define CTC_GREATBELT_DEVICE_ID 0x03e8 /* TBD */ -#define DAL_MAX_CHIP_NUM 8 /* [GB] used */ -#define VIRT_TO_PAGE(p) virt_to_page((p)) -#define DAL_UNTAG_BLOCK 0 -#define DAL_DISCARD_BLOCK 1 -#define DAL_MATCHED_BLOCK 2 -#define DAL_CUR_MATCH_BLOCk 3 -/***************************************************************************** - * typedef - *****************************************************************************/ -/* Control Data */ -typedef struct dal_isr_s -{ - int irq; - void (* isr)(void*); - void* isr_data; - int trigger; - int count; - wait_queue_head_t wqh; -} dal_isr_t; - -typedef struct dal_kernel_dev_s -{ - struct list_head list; - struct pci_dev* pci_dev; - - /* PCI I/O mapped base address */ - uintptr logic_address; - - /* Physical address */ - unsigned long long phys_address; -} dal_kern_dev_t; - -typedef struct _dma_segment -{ - struct list_head list; - unsigned long req_size; /* Requested DMA segment size */ - unsigned long blk_size; /* DMA block size */ - unsigned long blk_order; /* DMA block size in alternate format */ - unsigned long seg_size; /* Current DMA segment size */ - unsigned long seg_begin; /* Logical address of segment */ - unsigned long seg_end; /* Logical end address of segment */ - unsigned long* blk_ptr; /* Array of logical DMA block addresses */ - int blk_cnt_max; /* Maximum number of block to allocate */ - int blk_cnt; /* Current number of blocks allocated */ -} dma_segment_t; - -typedef irqreturn_t (*p_func) (int irq, void* dev_id); - -/*************************************************************************** - *declared - ***************************************************************************/ -static unsigned int linux_dal_poll0(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll1(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll2(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll3(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll4(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll5(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll6(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll7(struct file* filp, struct poll_table_struct* p); - -/***************************************************************************** - * global variables - *****************************************************************************/ -static dal_kern_dev_t dal_dev[DAL_MAX_CHIP_NUM]; -static dal_isr_t dal_isr[CTC_MAX_INTR_NUM]; -static int dal_chip_num = 0; -static int dal_version = 0; -static int dal_intr_num = 0; -static int use_high_memory = 0; -static unsigned int* dma_virt_base[DAL_MAX_CHIP_NUM]; -#ifndef DMA_MEM_MODE_PLATFORM -static unsigned int* dma_virt_base_tmp[DAL_MAX_CHIP_NUM]; -#endif -static unsigned long long dma_phy_base[DAL_MAX_CHIP_NUM]; -static unsigned int dma_mem_size = 0xc00000; -static unsigned int msi_irq_base[DAL_MAX_CHIP_NUM]; -static unsigned int msi_irq_num[DAL_MAX_CHIP_NUM]; -static unsigned int msi_used = 0; -static struct class *dal_class; - -static LIST_HEAD(_dma_seg); -static int dal_debug = 0; -module_param(dal_debug, int, 0); -MODULE_PARM_DESC(dal_debug, "Set debug level (default 0)"); - -static struct pci_device_id dal_id_table[] = -{ - {PCI_DEVICE(CTC_VENDOR_VID, CTC_GREATBELT_DEVICE_ID)}, - {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_GOLDENGATE_DEVICE_ID)}, - {PCI_DEVICE((CTC_PCIE_VENDOR_ID+1), (CTC_GOLDENGATE_DEVICE_ID+1))}, - {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_DUET2_DEVICE_ID)}, - {0, }, -}; - -static wait_queue_head_t poll_intr[CTC_MAX_INTR_NUM]; - -p_func intr_handler_fun[CTC_MAX_INTR_NUM]; - -static int poll_intr_trigger[CTC_MAX_INTR_NUM]; - -static struct file_operations dal_intr_fops[CTC_MAX_INTR_NUM] = -{ - { - .owner = THIS_MODULE, - .poll = linux_dal_poll0, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll1, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll2, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll3, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll4, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll5, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll6, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll7, - }, -}; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) -#include -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt -#endif -/***************************************************************************** - * macros - *****************************************************************************/ -#define VERIFY_CHIP_INDEX(n) (n < dal_chip_num) - -#define _KERNEL_INTERUPT_PROCESS -static irqreturn_t -intr0_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - - if(poll_intr_trigger[0]) - { - return IRQ_HANDLED; - } - - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[0] = 1; - wake_up(&poll_intr[0]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr1_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[1]) - { - return IRQ_HANDLED; - } - - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[1] = 1; - wake_up(&poll_intr[1]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr2_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[2]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[2] = 1; - wake_up(&poll_intr[2]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr3_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[3]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[3] = 1; - wake_up(&poll_intr[3]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr4_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[4]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[4] = 1; - wake_up(&poll_intr[4]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr5_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[5]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[5] = 1; - wake_up(&poll_intr[5]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr6_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[6]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[6] = 1; - wake_up(&poll_intr[6]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr7_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[7]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[7] = 1; - wake_up(&poll_intr[7]); - } - } - - return IRQ_HANDLED; -} - -int -dal_interrupt_register(unsigned int irq, int prio, void (* isr)(void*), void* data) -{ - int ret; - unsigned char str[16]; - unsigned char* int_name = NULL; - unsigned int intr_num_tmp = 0; - unsigned int intr_num = CTC_MAX_INTR_NUM; - unsigned long irq_flags = 0; - - if (dal_intr_num >= CTC_MAX_INTR_NUM) - { - printk("Interrupt numbers exceeds max.\n"); - return -1; - } - - if (msi_used) - { - int_name = "dal_msi"; - } - else - { - int_name = "dal_intr"; - } - - - for (intr_num_tmp=0;intr_num_tmp < CTC_MAX_INTR_NUM; intr_num_tmp++) - { - if (irq == dal_isr[intr_num_tmp].irq) - { - if (0 == msi_used) - { - dal_isr[intr_num_tmp].count++; - printk("Interrupt irq %d register count %d.\n", irq, dal_isr[intr_num_tmp].count); - } - return 0; - } - if ((0 == dal_isr[intr_num_tmp].irq) && (CTC_MAX_INTR_NUM == intr_num)) - { - intr_num = intr_num_tmp; - dal_isr[intr_num].count = 0; - } - } - dal_isr[intr_num].irq = irq; - dal_isr[intr_num].isr = isr; - dal_isr[intr_num].isr_data = data; - dal_isr[intr_num].count++; - - init_waitqueue_head(&poll_intr[intr_num]); - - /* only user mode */ - if ((NULL == isr) && (NULL == data)) - { - snprintf(str, 16, "%s%d", "dal_intr", intr_num); - ret = register_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, - str, &dal_intr_fops[intr_num]); - if (ret < 0) - { - printk("Register character device for irq %d failed, ret= %d", irq, ret); - return ret; - } - } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) - irq_flags = 0; -#else - irq_flags = IRQF_DISABLED; -#endif - if ((ret = request_irq(irq, - intr_handler_fun[intr_num], - irq_flags, - int_name, - &dal_isr[intr_num])) < 0) - { - printk("Cannot request irq %d, ret %d.\n", irq, ret); - unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, str); - } - - if (0 == ret) - { - dal_intr_num++; - } - - return ret; -} - -int -dal_interrupt_unregister(unsigned int irq) -{ - unsigned char str[16]; - int intr_idx = 0; - int find_flag = 0; - - /* get intr device index */ - for (intr_idx = 0; intr_idx < CTC_MAX_INTR_NUM; intr_idx++) - { - if (dal_isr[intr_idx].irq == irq) - { - find_flag = 1; - break; - } - } - - if (find_flag == 0) - { - printk ("irq%d is not registered! unregister failed \n", irq); - return -1; - } - - dal_isr[intr_idx].count--; - if (0 != dal_isr[intr_idx].count) - { - printk("Interrupt irq %d unregister count %d.\n", irq, dal_isr[intr_idx].count); - return -1; - } - snprintf(str, 16, "%s%d", "dal_intr", intr_idx); - - unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_idx, str); - - free_irq(irq, &dal_isr[intr_idx]); - - dal_isr[intr_idx].irq = 0; - - dal_intr_num--; - - return 0; -} - -int -dal_interrupt_set_en(unsigned int irq, unsigned int enable) -{ - enable ? enable_irq(irq) : disable_irq_nosync(irq); - return 0; -} - -static int -_dal_set_msi_enabe(unsigned int lchip, unsigned int irq_num) -{ - int ret = 0; - - if (irq_num == 1) - { - ret = pci_enable_msi(dal_dev[lchip].pci_dev); - if (ret) - { - printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); - pci_disable_msi(dal_dev[lchip].pci_dev); - msi_used = 0; - } - - msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; - msi_irq_num[lchip] = 1; - } - else - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 79)) - ret = pci_enable_msi_exact(dal_dev[lchip].pci_dev, irq_num); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 26, 32)) - ret = pci_enable_msi_block(dal_dev[lchip].pci_dev, irq_num); -#else - ret = -1; -#endif - if (ret) - { - printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); - pci_disable_msi(dal_dev[lchip].pci_dev); - msi_used = 0; - } - - msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; - msi_irq_num[lchip] = irq_num; - } - - return ret; -} - -static int -_dal_set_msi_disable(unsigned int lchip) -{ - - pci_disable_msi(dal_dev[lchip].pci_dev); - - msi_irq_base[lchip] = 0; - msi_irq_num[lchip] = 0; - - return 0; -} - -int -dal_set_msi_cap(unsigned long arg) -{ - int ret = 0; - int index = 0; - dal_msi_info_t msi_info; - - if (copy_from_user(&msi_info, (void*)arg, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - - printk("####dal_set_msi_cap lchip %d base %d num:%d\n", msi_info.lchip, msi_info.irq_base, msi_info.irq_num); - if (msi_info.irq_num > 0) - { - if (0 == msi_used) - { - msi_used = 1; - ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); - } - else if ((1 == msi_used) && (msi_info.irq_num != msi_irq_num[msi_info.lchip])) - { - for (index = 0; index < msi_irq_num[msi_info.lchip]; index++) - { - dal_interrupt_unregister(msi_irq_base[msi_info.lchip]+index); - } - _dal_set_msi_disable(msi_info.lchip); - msi_used = 1; - ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); - } - } - else - { - msi_used = 0; - ret = _dal_set_msi_disable(msi_info.lchip); - } - - return ret; -} - -int -dal_user_interrupt_register(unsigned long arg) -{ - int irq = 0; - if (copy_from_user(&irq, (void*)arg, sizeof(int))) - { - return -EFAULT; - } - printk("####register interrupt irq:%d\n", irq); - return dal_interrupt_register(irq, 0, NULL, NULL); -} - -int -dal_user_interrupt_unregister(unsigned long arg) -{ - int irq = 0; - if (copy_from_user(&irq, (void*)arg, sizeof(int))) - { - return -EFAULT; - } - printk("####unregister interrupt irq:%d\n", irq); - return dal_interrupt_unregister(irq); -} - -int -dal_user_interrupt_set_en(unsigned long arg) -{ - dal_intr_parm_t dal_intr_parm; - - if (copy_from_user(&dal_intr_parm, (void*)arg, sizeof(dal_intr_parm_t))) - { - return -EFAULT; - } - - return dal_interrupt_set_en(dal_intr_parm.irq, dal_intr_parm.enable); -} - -/* - * Function: _dal_dma_segment_free - */ - -/* - * Function: _find_largest_segment - * - * Purpose: - * Find largest contiguous segment from a pool of DMA blocks. - * Parameters: - * dseg - DMA segment descriptor - * Returns: - * 0 on success, < 0 on error. - * Notes: - * Assembly stops if a segment of the requested segment size - * has been obtained. - * - * Lower address bits of the DMA blocks are used as follows: - * 0: Untagged - * 1: Discarded block - * 2: Part of largest contiguous segment - * 3: Part of current contiguous segment - */ -#ifndef DMA_MEM_MODE_PLATFORM -static int -_dal_find_largest_segment(dma_segment_t* dseg) -{ - int i, j, blks, found; - unsigned long seg_begin; - unsigned long seg_end; - unsigned long seg_tmp; - - blks = dseg->blk_cnt; - - /* Clear all block tags */ - for (i = 0; i < blks; i++) - { - dseg->blk_ptr[i] &= ~3; - } - - for (i = 0; i < blks && dseg->seg_size < dseg->req_size; i++) - { - /* First block must be an untagged block */ - if ((dseg->blk_ptr[i] & 3) == DAL_UNTAG_BLOCK) - { - /* Initial segment size is the block size */ - seg_begin = dseg->blk_ptr[i]; - seg_end = seg_begin + dseg->blk_size; - dseg->blk_ptr[i] |= DAL_CUR_MATCH_BLOCk; - - /* Loop looking for adjacent blocks */ - do - { - found = 0; - - for (j = i + 1; j < blks && (seg_end - seg_begin) < dseg->req_size; j++) - { - seg_tmp = dseg->blk_ptr[j]; - /* Check untagged blocks only */ - if ((seg_tmp & 3) == DAL_UNTAG_BLOCK) - { - if (seg_tmp == (seg_begin - dseg->blk_size)) - { - /* Found adjacent block below current segment */ - dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; - seg_begin = seg_tmp; - found = 1; - } - else if (seg_tmp == seg_end) - { - /* Found adjacent block above current segment */ - dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; - seg_end += dseg->blk_size; - found = 1; - } - } - } - } - while (found); - - if ((seg_end - seg_begin) > dseg->seg_size) - { - /* The current block is largest so far */ - dseg->seg_begin = seg_begin; - dseg->seg_end = seg_end; - dseg->seg_size = seg_end - seg_begin; - - /* Re-tag current and previous largest segment */ - for (j = 0; j < blks; j++) - { - if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) - { - /* Tag current segment as the largest */ - dseg->blk_ptr[j] &= ~1; - } - else if ((dseg->blk_ptr[j] & 3) == DAL_MATCHED_BLOCK) - { - /* Discard previous largest segment */ - dseg->blk_ptr[j] ^= 3; - } - } - } - else - { - /* Discard all blocks in current segment */ - for (j = 0; j < blks; j++) - { - if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) - { - dseg->blk_ptr[j] &= ~2; - } - } - } - } - } - - return 0; -} - -/* - * Function: _alloc_dma_blocks - */ -static int -_dal_alloc_dma_blocks(dma_segment_t* dseg, int blks) -{ - int i, start; - unsigned long addr; - - if (dseg->blk_cnt + blks > dseg->blk_cnt_max) - { - printk("No more DMA blocks\n"); - return -1; - } - - start = dseg->blk_cnt; - dseg->blk_cnt += blks; - - for (i = start; i < dseg->blk_cnt; i++) - { - addr = __get_free_pages(GFP_ATOMIC, dseg->blk_order); - if (addr) - { - dseg->blk_ptr[i] = addr; - } - else - { - printk("DMA allocation failed\n"); - return -1; - } - } - - return 0; -} - -/* - * Function: _dal_dma_segment_alloc - */ -static dma_segment_t* -_dal_dma_segment_alloc(unsigned int size, unsigned int blk_size) -{ - dma_segment_t* dseg; - int i, blk_ptr_size; - unsigned long page_addr; - struct sysinfo si; - - /* Sanity check */ - if (size == 0 || blk_size == 0) - { - return NULL; - } - - /* Allocate an initialize DMA segment descriptor */ - if ((dseg = kmalloc(sizeof(dma_segment_t), GFP_ATOMIC)) == NULL) - { - return NULL; - } - - memset(dseg, 0, sizeof(dma_segment_t)); - dseg->req_size = size; - dseg->blk_size = PAGE_ALIGN(blk_size); - - while ((PAGE_SIZE << dseg->blk_order) < dseg->blk_size) - { - dseg->blk_order++; - } - - si_meminfo(&si); - dseg->blk_cnt_max = (si.totalram << PAGE_SHIFT) / dseg->blk_size; - blk_ptr_size = dseg->blk_cnt_max * sizeof(unsigned long); - /* Allocate an initialize DMA block pool */ - dseg->blk_ptr = kmalloc(blk_ptr_size, GFP_KERNEL); - if (dseg->blk_ptr == NULL) - { - kfree(dseg); - return NULL; - } - - memset(dseg->blk_ptr, 0, blk_ptr_size); - /* Allocate minimum number of blocks */ - _dal_alloc_dma_blocks(dseg, dseg->req_size / dseg->blk_size); - - /* Allocate more blocks until we have a complete segment */ - do - { - _dal_find_largest_segment(dseg); - if (dseg->seg_size >= dseg->req_size) - { - break; - } - } - while (_dal_alloc_dma_blocks(dseg, 8) == 0); - - /* Reserve all pages in the DMA segment and free unused blocks */ - for (i = 0; i < dseg->blk_cnt; i++) - { - if ((dseg->blk_ptr[i] & 3) == 2) - { - dseg->blk_ptr[i] &= ~3; - - for (page_addr = dseg->blk_ptr[i]; - page_addr < dseg->blk_ptr[i] + dseg->blk_size; - page_addr += PAGE_SIZE) - { - MEM_MAP_RESERVE(VIRT_TO_PAGE((void*)page_addr)); - } - } - else if (dseg->blk_ptr[i]) - { - dseg->blk_ptr[i] &= ~3; - free_pages(dseg->blk_ptr[i], dseg->blk_order); - dseg->blk_ptr[i] = 0; - } - } - - return dseg; -} - -/* - * Function: _dal_dma_segment_free - */ -static void -_dal_dma_segment_free(dma_segment_t* dseg) -{ - int i; - unsigned long page_addr; - - if (dseg->blk_ptr) - { - for (i = 0; i < dseg->blk_cnt; i++) - { - if (dseg->blk_ptr[i]) - { - for (page_addr = dseg->blk_ptr[i]; - page_addr < dseg->blk_ptr[i] + dseg->blk_size; - page_addr += PAGE_SIZE) - { - MEM_MAP_UNRESERVE(VIRT_TO_PAGE(page_addr)); - } - - free_pages(dseg->blk_ptr[i], dseg->blk_order); - } - } - - kfree(dseg->blk_ptr); - kfree(dseg); - } -} - -/* - * Function: -dal_pgalloc - */ -static void* -_dal_pgalloc(unsigned int size) -{ - dma_segment_t* dseg; - unsigned int blk_size; - - blk_size = (size < DMA_BLOCK_SIZE) ? size : DMA_BLOCK_SIZE; - if ((dseg = _dal_dma_segment_alloc(size, blk_size)) == NULL) - { - return NULL; - } - - if (dseg->seg_size < size) - { - /* If we didn't get the full size then forget it */ - printk("Notice: Can not get enough memory for requset!!\n"); - printk("actual size:0x%lx, request size:0x%x\n", dseg->seg_size, size); - //-_dal_dma_segment_free(dseg); - //-return NULL; - } - - list_add(&dseg->list, &_dma_seg); - return (void*)dseg->seg_begin; -} - -/* - * Function: _dal_pgfree - */ -static int -_dal_pgfree(void* ptr) -{ - struct list_head* pos; - - list_for_each(pos, &_dma_seg) - { - dma_segment_t* dseg = list_entry(pos, dma_segment_t, list); - if (ptr == (void*)dseg->seg_begin) - { - list_del(&dseg->list); - _dal_dma_segment_free(dseg); - return 0; - } - } - return -1; -} -#endif -static void -dal_alloc_dma_pool(int lchip, int size) -{ - if (use_high_memory) - { - dma_phy_base[lchip] = virt_to_bus(high_memory); - dma_virt_base[lchip] = ioremap_nocache(dma_phy_base[lchip], size); - } - else - { -#ifdef DMA_MEM_MODE_PLATFORM - dma_virt_base[lchip] = dma_alloc_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, - &dma_phy_base[lchip], GFP_KERNEL); - - printk(KERN_WARNING "########Using DMA_MEM_MODE_PLATFORM \n"); -#endif - -#ifndef DMA_MEM_MODE_PLATFORM - /* Get DMA memory from kernel */ - dma_virt_base_tmp[lchip] = _dal_pgalloc(size); - dma_phy_base[lchip] = virt_to_bus(dma_virt_base_tmp[lchip]); - dma_virt_base [lchip]= ioremap_nocache(dma_phy_base[lchip], size); -#endif - } -} - -static void -dal_free_dma_pool(int lchip) -{ - int ret = 0; - ret = ret; - if (use_high_memory) - { - iounmap(dma_virt_base[lchip]); - } - else - { -#ifdef DMA_MEM_MODE_PLATFORM - dma_free_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, - dma_virt_base[lchip], dma_phy_base[lchip]); -#endif - -#ifndef DMA_MEM_MODE_PLATFORM - iounmap(dma_virt_base[lchip]); - ret = _dal_pgfree(dma_virt_base_tmp[lchip]); - if(ret<0) - { - printk("Dma free memory fail !!!!!! \n"); - } -#endif - } -} - -#define _KERNEL_DAL_IO -static int -_dal_pci_read(unsigned char lchip, unsigned int offset, unsigned int* value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - *value = *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset); - return 0; -} - -int -dal_create_irq_mapping(unsigned long arg) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) - -#ifndef NO_IRQ -#define NO_IRQ (-1) -#endif - dal_irq_mapping_t irq_map; - - if (copy_from_user(&irq_map, (void*)arg, sizeof(dal_irq_mapping_t))) - { - return -EFAULT; - } - - irq_map.sw_irq = irq_create_mapping(NULL, irq_map.hw_irq); - if (irq_map.sw_irq == NO_IRQ) - { - printk("IRQ mapping fail !!!!!! \n"); - return -1; - } - - if (copy_to_user((dal_irq_mapping_t*)arg, (void*)&irq_map, sizeof(dal_irq_mapping_t))) - { - return -EFAULT; - } -#endif - return 0; -} - -int -dal_pci_read(unsigned long arg) -{ - dal_chip_parm_t cmdpara_chip; - - if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - _dal_pci_read((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, - (unsigned int*)(&(cmdpara_chip.value))); - - if (copy_to_user((dal_chip_parm_t*)arg, (void*)&cmdpara_chip, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -_dal_pci_write(unsigned char lchip, unsigned int offset, unsigned int value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset) = value; - return 0; -} - -int -dal_pci_write(unsigned long arg) -{ - dal_chip_parm_t cmdpara_chip; - - if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - _dal_pci_write((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, - (unsigned int)cmdpara_chip.value); - - return 0; -} - -int -dal_pci_conf_read(unsigned char lchip, unsigned int offset, unsigned int* value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - pci_read_config_dword(dal_dev[lchip].pci_dev, offset, value); - return 0; -} - -int -dal_pci_conf_write(unsigned char lchip, unsigned int offset, unsigned int value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - pci_write_config_dword(dal_dev[lchip].pci_dev, offset, value); - return 0; -} -int -dal_user_read_pci_conf(unsigned long arg) -{ - dal_pci_cfg_ioctl_t dal_cfg; - - if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - if (dal_pci_conf_read(dal_cfg.lchip, dal_cfg.offset, &dal_cfg.value)) - { - printk("dal_pci_conf_read failed.\n"); - return -EFAULT; - } - - if (copy_to_user((dal_pci_cfg_ioctl_t*)arg, (void*)&dal_cfg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - return 0; -} - -int -dal_user_write_pci_conf(unsigned long arg) -{ - dal_pci_cfg_ioctl_t dal_cfg; - - if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - return dal_pci_conf_write(dal_cfg.lchip, dal_cfg.offset, dal_cfg.value); -} - -static int -linux_get_device(unsigned long arg) -{ - dal_user_dev_t user_dev; - int lchip = 0; - - if (copy_from_user(&user_dev, (void*)arg, sizeof(user_dev))) - { - return -EFAULT; - } - - user_dev.chip_num = dal_chip_num; - lchip = user_dev.lchip; - - if (lchip < dal_chip_num) - { - user_dev.phy_base0 = (unsigned int)dal_dev[lchip].phys_address; - user_dev.phy_base1 = (unsigned int)(dal_dev[lchip].phys_address >> 32); - - user_dev.bus_no = dal_dev[lchip].pci_dev->bus->number; - user_dev.dev_no = dal_dev[lchip].pci_dev->device; - user_dev.fun_no = dal_dev[lchip].pci_dev->devfn; - } - - if (copy_to_user((dal_user_dev_t*)arg, (void*)&user_dev, sizeof(user_dev))) - { - return -EFAULT; - } - - return 0; -} - -/* set dal version, copy to user */ -static int -linux_get_dal_version(unsigned long arg) -{ - int dal_ver = VERSION_1DOT2; /* set dal version */ - - if (copy_to_user((int*)arg, (void*)&dal_ver, sizeof(dal_ver))) - { - return -EFAULT; - } - - dal_version = dal_ver; /* up sw */ - - return 0; -} - -static int -linux_get_dma_info(unsigned long arg) -{ - dma_info_t dma_para; - - if (copy_from_user(&dma_para, (void*)arg, sizeof(dma_info_t))) - { - return -EFAULT; - } - - dma_para.phy_base = (unsigned int)dma_phy_base[dma_para.lchip]; - dma_para.phy_base_hi = dma_phy_base[dma_para.lchip] >> 32; - dma_para.size = dma_mem_size; - - if (copy_to_user((dma_info_t*)arg, (void*)&dma_para, sizeof(dma_info_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -dal_get_msi_info(unsigned long arg) -{ - dal_msi_info_t msi_para; - unsigned int lchip = 0; - - /* get lchip form user mode */ - if (copy_from_user(&msi_para, (void*)arg, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - lchip = msi_para.lchip; - - msi_para.irq_base = msi_irq_base[lchip]; - msi_para.irq_num = msi_irq_num[lchip]; - - /* send msi info to user mode */ - if (copy_to_user((dal_msi_info_t*)arg, (void*)&msi_para, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - - return 0; -} - - -static int -dal_get_intr_info(unsigned long arg) -{ - dal_intr_info_t intr_para; - unsigned int intr_num = 0; - - /* get lchip form user mode */ - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_intr_info_t))) - { - return -EFAULT; - } - - intr_para.irq_idx = CTC_MAX_INTR_NUM; - for (intr_num=0; intr_num< CTC_MAX_INTR_NUM; intr_num++) - { - if (intr_para.irq == dal_isr[intr_num].irq) - { - intr_para.irq_idx = intr_num; - break; - } - } - - if (CTC_MAX_INTR_NUM == intr_para.irq_idx) - { - printk("Interrupt %d cann't find.\n", intr_para.irq); - } - /* send msi info to user mode */ - if (copy_to_user((dal_intr_info_t*)arg, (void*)&intr_para, sizeof(dal_intr_info_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -dal_cache_inval(unsigned long arg) -{ - dal_dma_cache_info_t intr_para; - - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) - { - return -EFAULT; - } - -#if 0 - dma_cache_wback_inv((unsigned long)intr_para.ptr, intr_para.length); -#endif - -#if 0 - dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); - - - dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); -#endif - return 0; -} - -static int -dal_cache_flush(unsigned long arg) -{ - dal_dma_cache_info_t intr_para; - - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) - { - return -EFAULT; - } - -#if 0 - dma_cache_wback_inv(intr_para.ptr, intr_para.length); -#endif - -#if 0 - dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); - - - dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); -#endif - return 0; -} - -int -linux_dal_probe(struct pci_dev* pdev, const struct pci_device_id* id) -{ - dal_kern_dev_t* dev = NULL; - int bar = 0; - int ret = 0; - unsigned int temp = 0; - unsigned int lchip = 0; - - printk(KERN_WARNING "********found dal device*****\n"); - - for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) - { - if (NULL == dal_dev[lchip].pci_dev) - { - break; - } - } - - if (lchip >= DAL_MAX_CHIP_NUM) - { - printk("Exceed max local chip num\n"); - return -1; - } - - dev = &dal_dev[lchip]; - if (NULL == dev) - { - printk("Cannot obtain PCI resources\n"); - } - - lchip = lchip; - dal_chip_num += 1; - - dev->pci_dev = pdev; - - if (pci_enable_device(pdev) < 0) - { - printk("Cannot enable PCI device: vendor id = %x, device id = %x\n", - pdev->vendor, pdev->device); - } - - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); - if (ret) - { - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (ret) - { - printk("Could not set PCI DMA Mask\n"); - return ret; - } - } - - if (pci_request_regions(pdev, DAL_NAME) < 0) - { - printk("Cannot obtain PCI resources\n"); - } - - dev->phys_address = pci_resource_start(pdev, bar); - dev->logic_address = (uintptr)ioremap_nocache(dev->phys_address, - pci_resource_len(dev->pci_dev, bar)); - - _dal_pci_read(lchip, 0x48, &temp); - if (((temp >> 8) & 0xffff) == 0x3412) - { - printk("Little endian Cpu detected!!! \n"); - _dal_pci_write(lchip, 0x48, 0xFFFFFFFF); - } - - pci_set_master(pdev); - - /* alloc dma_mem_size for every chip */ - if (dma_mem_size) - { - dal_alloc_dma_pool(lchip, dma_mem_size); - - /*add check Dma memory pool cannot cross 4G space*/ - if ((0==(dma_phy_base[lchip]>>32)) && (0!=((dma_phy_base[lchip]+dma_mem_size)>>32))) - { - printk("Dma malloc memory cross 4G space!!!!!! \n"); - return -1; - } - } - - printk(KERN_WARNING "linux_dal_probe end*****\n"); - - return 0; -} - -void -linux_dal_remove(struct pci_dev* pdev) -{ - unsigned int lchip = 0; - unsigned int flag = 0; - - for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) - { - if (pdev == dal_dev[lchip].pci_dev) - { - flag = 1; - break; - } - } - - if (1 == flag) - { - dal_free_dma_pool(lchip); - pci_release_regions(pdev); - pci_disable_device(pdev); - - dal_dev[lchip].pci_dev = NULL; - dal_chip_num--; - } - - -} - -#ifdef CONFIG_COMPAT -static long -linux_dal_ioctl(struct file* file, - unsigned int cmd, unsigned long arg) -#else - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) -static int -linux_dal_ioctl(struct file* file, - unsigned int cmd, unsigned long arg) -#else -static int -linux_dal_ioctl(struct inode* inode, struct file* file, - unsigned int cmd, unsigned long arg) -#endif - -#endif -{ - switch (cmd) - { - - case CMD_READ_CHIP: - return dal_pci_read(arg); - - case CMD_WRITE_CHIP: - return dal_pci_write(arg); - - case CMD_GET_DEVICES: - return linux_get_device(arg); - - case CMD_GET_DAL_VERSION: - return linux_get_dal_version(arg); - - case CMD_GET_DMA_INFO: - return linux_get_dma_info(arg); - - case CMD_PCI_CONFIG_READ: - return dal_user_read_pci_conf(arg); - - case CMD_PCI_CONFIG_WRITE: - return dal_user_write_pci_conf(arg); - - case CMD_REG_INTERRUPTS: - return dal_user_interrupt_register(arg); - - case CMD_UNREG_INTERRUPTS: - return dal_user_interrupt_unregister(arg); - - case CMD_EN_INTERRUPTS: - return dal_user_interrupt_set_en(arg); - - case CMD_SET_MSI_CAP: - return dal_set_msi_cap(arg); - - case CMD_GET_MSI_INFO: - return dal_get_msi_info(arg); - - case CMD_IRQ_MAPPING: - return dal_create_irq_mapping(arg); - - case CMD_GET_INTR_INFO: - return dal_get_intr_info(arg); - - case CMD_CACHE_INVAL: - return dal_cache_inval(arg); - - case CMD_CACHE_FLUSH: - return dal_cache_flush(arg); - - default: - break; - } - - return 0; -} - -static unsigned int -linux_dal_poll0(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[0], p); - local_irq_save(flags); - if (poll_intr_trigger[0]) - { - poll_intr_trigger[0] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll1(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[1], p); - local_irq_save(flags); - if (poll_intr_trigger[1]) - { - poll_intr_trigger[1] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll2(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[2], p); - local_irq_save(flags); - if (poll_intr_trigger[2]) - { - poll_intr_trigger[2] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll3(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[3], p); - local_irq_save(flags); - if (poll_intr_trigger[3]) - { - poll_intr_trigger[3] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll4(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[4], p); - local_irq_save(flags); - if (poll_intr_trigger[4]) - { - poll_intr_trigger[4] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll5(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[5], p); - local_irq_save(flags); - if (poll_intr_trigger[5]) - { - poll_intr_trigger[5] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll6(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[6], p); - local_irq_save(flags); - if (poll_intr_trigger[6]) - { - poll_intr_trigger[6] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll7(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[7], p); - local_irq_save(flags); - if (poll_intr_trigger[7]) - { - poll_intr_trigger[7] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static struct pci_driver linux_dal_driver = -{ - .name = DAL_NAME, - .id_table = dal_id_table, - .probe = linux_dal_probe, - .remove = linux_dal_remove, -}; - -static struct file_operations fops = -{ - .owner = THIS_MODULE, -#ifdef CONFIG_COMPAT - .compat_ioctl = linux_dal_ioctl, - .unlocked_ioctl = linux_dal_ioctl, -#else -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) - .unlocked_ioctl = linux_dal_ioctl, -#else - .ioctl = linux_dal_ioctl, -#endif -#endif -}; - - -static int __init -linux_dal_init(void) -{ - int ret = 0; - - /* Get DMA memory pool size form dal.ok input param, or use default dma_mem_size */ - if (dma_pool_size) - { - if ((dma_pool_size[strlen(dma_pool_size) - 1] & ~0x20) == 'M') - { - dma_mem_size = simple_strtoul(dma_pool_size, NULL, 0); - printk("dma_mem_size: 0x%x \n", dma_mem_size); - - dma_mem_size *= MB_SIZE; - } - else - { - printk("DMA memory pool size must be specified as e.g. dma_pool_size=8M\n"); - } - - if (dma_mem_size & (dma_mem_size - 1)) - { - printk("dma_mem_size must be a power of 2 (1M, 2M, 4M, 8M etc.)\n"); - dma_mem_size = 0; - } - } - - ret = register_chrdev(DAL_DEV_MAJOR, DAL_NAME, &fops); - if (ret < 0) - { - printk(KERN_WARNING "Register linux_dal device, ret %d\n", ret); - return ret; - } - - ret = pci_register_driver(&linux_dal_driver); - if (ret < 0) - { - printk(KERN_WARNING "Register ASIC PCI driver failed, ret %d\n", ret); - return ret; - } - - /* alloc /dev/linux_dal node */ - dal_class = class_create(THIS_MODULE, DAL_NAME); - device_create(dal_class, NULL, MKDEV(DAL_DEV_MAJOR, 0), NULL, DAL_NAME); - - /* init interrupt function */ - intr_handler_fun[0] = intr0_handler; - intr_handler_fun[1] = intr1_handler; - intr_handler_fun[2] = intr2_handler; - intr_handler_fun[3] = intr3_handler; - intr_handler_fun[4] = intr4_handler; - intr_handler_fun[5] = intr5_handler; - intr_handler_fun[6] = intr6_handler; - intr_handler_fun[7] = intr7_handler; - - return ret; -} - -static void __exit -linux_dal_exit(void) -{ - device_destroy(dal_class, MKDEV(DAL_DEV_MAJOR, 0)); - class_destroy(dal_class); - unregister_chrdev(DAL_DEV_MAJOR, "linux_dal"); - pci_unregister_driver(&linux_dal_driver); -} - -module_init(linux_dal_init); -module_exit(linux_dal_exit); - - diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.h b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.h deleted file mode 100644 index 850a4cffa731..000000000000 --- a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_kernel.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - @file dal_kernel_io.h - - @author Copyright (C) 2012 Centec Networks Inc. All rights reserved. - - @date 2012-4-9 - - @version v2.0 - -*/ -#ifndef _DAL_KERNEL_H_ -#define _DAL_KERNEL_H_ -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(CONFIG_RESOURCES_64BIT) || defined(CONFIG_PHYS_ADDR_T_64BIT) -#define PHYS_ADDR_IS_64BIT -#endif - -#ifndef SDK_IN_USERMODE -#ifdef PHYS_ADDR_IS_64BIT -typedef long long intptr; -typedef unsigned long long uintptr; -#else -typedef int intptr; -typedef unsigned int uintptr; -#endif -#endif - -#define DAL_PCI_READ_ADDR 0x0 -#define DAL_PCI_READ_DATA 0xc -#define DAL_PCI_WRITE_ADDR 0x8 -#define DAL_PCI_WRITE_DATA 0x4 -#define DAL_PCI_STATUS 0x10 - -#define DAL_PCI_STATUS_IN_PROCESS 31 -#define DAL_PCI_STATUS_BAD_PARITY 5 -#define DAL_PCI_STATUS_CPU_ACCESS_ERR 4 -#define DAL_PCI_STATUS_READ_CMD 3 -#define DAL_PCI_STATUS_REGISTER_ERR 1 -#define DAL_PCI_STATUS_REGISTER_ACK 0 - -#define DAL_PCI_ACCESS_TIMEOUT 0x64 - -#define DAL_NAME "linux_dal" /* "linux_dal" */ - -#define DAL_DEV_MAJOR 198 - -#define DAL_DEV_INTR_MAJOR_BASE 200 - -#define DAL_DEV_NAME "/dev/" DAL_NAME -#define DAL_ONE_KB 1024 -#define DAL_ONE_MB (1024*1024) -struct dal_chip_parm_s -{ - unsigned int lchip; /*tmp should be uint8*/ - unsigned int fpga_id; /*tmp add*/ - unsigned int reg_addr; - unsigned int value; -}; -typedef struct dal_chip_parm_s dal_chip_parm_t; - -struct dal_intr_parm_s -{ - unsigned int irq; - unsigned int enable; -}; -typedef struct dal_intr_parm_s dal_intr_parm_t; - -struct dal_irq_mapping_s -{ - unsigned int hw_irq; - unsigned int sw_irq; -}; -typedef struct dal_irq_mapping_s dal_irq_mapping_t; - -struct dal_user_dev_s -{ - unsigned int chip_num; /*output: local chip number*/ - unsigned int lchip; /*input: local chip id*/ - unsigned int phy_base0; /* low 32bits physical base address */ - unsigned int phy_base1; /* high 32bits physical base address */ - unsigned int bus_no; - unsigned int dev_no; - unsigned int fun_no; - void* virt_base[2]; /* Virtual base address; this must be last member */ -}; -typedef struct dal_user_dev_s dal_user_dev_t; - -struct dma_info_s -{ - unsigned int lchip; - unsigned int phy_base; - unsigned int phy_base_hi; - unsigned int size; - unsigned int* virt_base; -}; -typedef struct dma_info_s dma_info_t; - -struct dal_pci_cfg_ioctl_s -{ - unsigned int lchip; /* Device ID */ - unsigned int offset; - unsigned int value; -}; -typedef struct dal_pci_cfg_ioctl_s dal_pci_cfg_ioctl_t; - -struct dal_msi_info_s -{ - unsigned int lchip; - unsigned int irq_base; - unsigned int irq_num; -}; -typedef struct dal_msi_info_s dal_msi_info_t; - -struct dal_intr_info_s -{ - unsigned int irq; - unsigned int irq_idx; -}; -typedef struct dal_intr_info_s dal_intr_info_t; - -struct dal_dma_cache_info_s -{ - unsigned long ptr; - unsigned int length; -}; -typedef struct dal_dma_cache_info_s dal_dma_cache_info_t; - -#define CMD_MAGIC 'C' -#define CMD_WRITE_CHIP _IO(CMD_MAGIC, 0) /* for humber ioctrol*/ -#define CMD_READ_CHIP _IO(CMD_MAGIC, 1) /* for humber ioctrol*/ -#define CMD_GET_DEVICES _IO(CMD_MAGIC, 2) -#define CMD_GET_DAL_VERSION _IO(CMD_MAGIC, 3) -#define CMD_PCI_CONFIG_WRITE _IO(CMD_MAGIC, 4) -#define CMD_PCI_CONFIG_READ _IO(CMD_MAGIC, 5) -#define CMD_GET_DMA_INFO _IO(CMD_MAGIC, 6) -#define CMD_REG_INTERRUPTS _IO(CMD_MAGIC, 7) -#define CMD_UNREG_INTERRUPTS _IO(CMD_MAGIC, 8) -#define CMD_EN_INTERRUPTS _IO(CMD_MAGIC, 9) -#define CMD_I2C_READ _IO(CMD_MAGIC, 10) -#define CMD_I2C_WRITE _IO(CMD_MAGIC, 11) -#define CMD_GET_MSI_INFO _IO(CMD_MAGIC, 12) -#define CMD_SET_MSI_CAP _IO(CMD_MAGIC, 13) -#define CMD_IRQ_MAPPING _IO(CMD_MAGIC, 14) -#define CMD_GET_INTR_INFO _IO(CMD_MAGIC, 15) -#define CMD_CACHE_INVAL _IO(CMD_MAGIC, 16) -#define CMD_CACHE_FLUSH _IO(CMD_MAGIC, 17) - -enum dal_version_e -{ - VERSION_MIN, - VERSION_1DOT0, - VERSION_1DOT1, - VERSION_1DOT2, - - VERSION_MAX -}; -typedef enum dal_version_e dal_version_t; - -/* We try to assemble a contiguous segment from chunks of this size */ -#define DMA_BLOCK_SIZE (512 * DAL_ONE_KB) - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.c b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.c deleted file mode 100644 index 5aca222a138f..000000000000 --- a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.c +++ /dev/null @@ -1,350 +0,0 @@ -#include "dal_mpool.h" - -#ifdef __KERNEL__ -#include -#include - -#define DAL_MALLOC(x) kmalloc(x, GFP_ATOMIC) -#define DAL_FREE(x) kfree(x) - -static spinlock_t dal_mpool_lock; -#define MPOOL_LOCK_INIT() spin_lock_init(&dal_mpool_lock) -#define MPOOL_LOCK() unsigned long flags; spin_lock_irqsave(&dal_mpool_lock, flags) -#define MPOOL_UNLOCK() spin_unlock_irqrestore(&dal_mpool_lock, flags) -#define DAL_PRINT(fmt,arg...) printk(fmt,##arg) -#else /* !__KERNEL__*/ - -#include -#include "sal.h" -#define DAL_MALLOC(x) malloc(x) -#define DAL_FREE(x) free(x) -static sal_mutex_t* dal_mpool_lock; -#define MPOOL_LOCK_INIT() sal_mutex_create(&dal_mpool_lock) -#define MPOOL_LOCK() sal_mutex_lock(dal_mpool_lock) -#define MPOOL_UNLOCK() sal_mutex_unlock(dal_mpool_lock) -#define DAL_PRINT(fmt,arg...) sal_printf(fmt,##arg) - -#endif /* __KERNEL__ */ - - - -dal_mpool_mem_t* g_free_block_ptr = NULL; - -/* System cache line size */ -#ifndef DAL_CACHE_LINE_BYTES -#define DAL_CACHE_LINE_BYTES 256 -#endif - -#define DAL_MAX_CHIP_NUM 32 -static dal_mpool_mem_t* p_desc_pool[DAL_MAX_CHIP_NUM] = {0}; -static dal_mpool_mem_t* p_data_pool[DAL_MAX_CHIP_NUM] = {0}; - -int -dal_mpool_init(void) -{ - MPOOL_LOCK_INIT(); - return 0; -} - -dal_mpool_mem_t* -_dal_mpool_create(void* base, int size, int type) -{ - dal_mpool_mem_t* head = NULL; - dal_mpool_mem_t* tail = NULL; - - head = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (head == NULL) - { - return NULL; - } - - tail = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (tail == NULL) - { - DAL_FREE(head); - return NULL; - } - - head->size = tail->size = 0; - head->type = type; - head->address = base; - tail->address = head->address + size; - head->next = tail; - tail->next = NULL; - - return head; -} - -dal_mpool_mem_t* -dal_mpool_create(unsigned char lchip, void* base, int size) -{ - dal_mpool_mem_t* head = NULL; - int mod = (int)(((unsigned long)base) & (DAL_CACHE_LINE_BYTES - 1)); - - MPOOL_LOCK(); - - if (mod) - { - base = (char*)base + (DAL_CACHE_LINE_BYTES - mod); - size -= (DAL_CACHE_LINE_BYTES - mod); - } - - size &= ~(DAL_CACHE_LINE_BYTES - 1); - - /* init for common linkptr, only used for GB */ - head = _dal_mpool_create(base, size, DAL_MPOOL_TYPE_USELESS); - if (NULL == head) - { - MPOOL_UNLOCK(); - return NULL; - } - - /* init for desc linkptr */ - p_desc_pool[lchip] = _dal_mpool_create(base, DAL_MPOOL_MAX_DESX_SIZE, DAL_MPOOL_TYPE_DESC); - if (NULL == p_desc_pool[lchip]) - { - MPOOL_UNLOCK(); - DAL_FREE(head->next); - DAL_FREE(head); - return NULL; - } - - /* init for data linkptr */ - p_data_pool[lchip] = _dal_mpool_create(((char*)base+DAL_MPOOL_MAX_DESX_SIZE), (size - DAL_MPOOL_MAX_DESX_SIZE), DAL_MPOOL_TYPE_DATA); - if (NULL == p_data_pool[lchip]) - { - MPOOL_UNLOCK(); - DAL_FREE(head->next); - DAL_FREE(head); - DAL_FREE(p_desc_pool[lchip]->next); - DAL_FREE(p_desc_pool[lchip]); - return NULL; - } - - MPOOL_UNLOCK(); - - return head; -} - -dal_mpool_mem_t* -_dal_mpool_alloc_comon(dal_mpool_mem_t* ptr, int size, int type) -{ - dal_mpool_mem_t* new_ptr = NULL; - - while (ptr && ptr->next) - { - if (ptr->next->address - (ptr->address + ptr->size) >= size) - { - break; - } - - ptr = ptr->next; - } - - if (!(ptr && ptr->next)) - { - return NULL; - } - - new_ptr = DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (!new_ptr) - { - return NULL; - } - - new_ptr->type = type; - new_ptr->address = ptr->address + ptr->size; - new_ptr->size = size; - new_ptr->next = ptr->next; - ptr->next = new_ptr; - - return new_ptr; -} - -void* -dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type) -{ - dal_mpool_mem_t* ptr = NULL; - dal_mpool_mem_t* new_ptr = NULL; - int mod; - - MPOOL_LOCK(); - - mod = size & (DAL_CACHE_LINE_BYTES - 1); - if (mod != 0) - { - size += (DAL_CACHE_LINE_BYTES - mod); - } - - switch(type) - { - case DAL_MPOOL_TYPE_USELESS: - ptr = pool; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - case DAL_MPOOL_TYPE_DESC: - ptr = p_desc_pool[lchip]; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - case DAL_MPOOL_TYPE_DATA: - ptr = p_data_pool[lchip]; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - default: - MPOOL_UNLOCK(); - return NULL; - break; - } - - MPOOL_UNLOCK(); - if( NULL == new_ptr ) - { - return NULL; - } - - return new_ptr->address; -} - -void -_dal_mpool_free(dal_mpool_mem_t* ptr, void* addr, int type) -{ - unsigned char* address = (unsigned char*)addr; - dal_mpool_mem_t* prev = NULL; - - while (ptr && ptr->next) - { - if (ptr->next->address == address) - { - break; - } - - ptr = ptr->next; - } - - if (ptr && ptr->next) - { - prev = ptr; - ptr = ptr->next; - prev->next = ptr->next; - DAL_FREE(ptr); - } - - return; -} - -void -dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr) -{ - dal_mpool_mem_t* ptr = pool; - - MPOOL_LOCK(); - - switch(pool->type) - { - case DAL_MPOOL_TYPE_USELESS: - ptr = pool; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_USELESS); - break; - case DAL_MPOOL_TYPE_DESC: - ptr = p_desc_pool[lchip]; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DESC); - break; - case DAL_MPOOL_TYPE_DATA: - ptr = p_data_pool[lchip]; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DATA); - break; - default: - break; - } - - MPOOL_UNLOCK(); - return; -} - -int -dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool) -{ - dal_mpool_mem_t* ptr, * next; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - for (ptr = p_desc_pool[lchip]; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - for (ptr = p_data_pool[lchip]; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - MPOOL_UNLOCK(); - - return 0; -} - -int -dal_mpool_usage(dal_mpool_mem_t* pool, int type) -{ - int usage = 0; - dal_mpool_mem_t* ptr; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = ptr->next) - { - if (ptr->type == type || ptr->type == -1) - { - usage += ptr->size; - } - } - - MPOOL_UNLOCK(); - - return usage; -} - -int -dal_mpool_debug(dal_mpool_mem_t* pool) -{ - dal_mpool_mem_t* ptr; - int index = 0; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = ptr->next) - { -// DAL_PRINT("%2dst mpool block: address=0x%8x, size=0x%x \n", index, (unsigned int)ptr->address, ptr->size); - DAL_PRINT("%2dst mpool block: address=%p, size=0x%x \n", index, ptr->address, ptr->size); // note - index++; - } - - MPOOL_UNLOCK(); - - return 0; -} - - diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.h b/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.h deleted file mode 100644 index d93f88868136..000000000000 --- a/platform/centec/sonic-platform-modules-embedway/es6220/modules/dal_mpool.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - @file dal_mpool.h - - @author Copyright (C) 2011 Centec Networks Inc. All rights reserved. - - @date 2012-5-10 - - @version v2.0 - - This file contains the dma memory init, allocation and free APIs -*/ - -#ifndef _DMA_MPOOL_H -#define _DMA_MPOOL_H -#ifdef __cplusplus -extern "C" { -#endif - -#define DAL_MPOOL_MAX_DESX_SIZE (1024*1024) - -enum dal_mpool_type_e -{ - DAL_MPOOL_TYPE_USELESS, /* just compatible with GB */ - DAL_MPOOL_TYPE_DESC, /* dma mpool op for desc */ - DAL_MPOOL_TYPE_DATA /* dma mpool op for data */ -}; -typedef enum dal_mpool_type_e dal_mpool_type_t; - -struct dal_mpool_mem_s -{ - unsigned char* address; - int size; - int type; - struct dal_mpool_mem_s* next; -}; -typedef struct dal_mpool_mem_s dal_mpool_mem_t; - -/** - @brief This function is to alloc dma memory - - @param[in] size size of memory - - @return NULL - -*/ -extern int -dal_mpool_init(void); - -extern dal_mpool_mem_t* -dal_mpool_create(unsigned char lchip, void* base_ptr, int size); - -extern void* -dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type); - -extern void -dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr); - -extern int -dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool); - -extern int -dal_mpool_usage(dal_mpool_mem_t* pool, int type); - -extern int -dal_mpool_debug(dal_mpool_mem_t* pool); -#ifdef __cplusplus -} -#endif - -#endif /* !_DMA_MPOOL_H */ - - From 9814da1e21a7e40ba824e849278ad2a6f78f91a2 Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Fri, 15 May 2020 14:51:53 -0700 Subject: [PATCH 0660/1427] [docker-lldp-sv2]: upgrade docker-lldp-sv2 to buster (#4598) Signed-off-by: Joyas Joseph --- dockers/docker-lldp-sv2/Dockerfile.j2 | 2 +- rules/docker-lldp-sv2.mk | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dockers/docker-lldp-sv2/Dockerfile.j2 b/dockers/docker-lldp-sv2/Dockerfile.j2 index af2b0373c373..f45e1c0df8bb 100644 --- a/dockers/docker-lldp-sv2/Dockerfile.j2 +++ b/dockers/docker-lldp-sv2/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-lldp-sv2.mk b/rules/docker-lldp-sv2.mk index a39b307d5063..460bdc2ff38b 100644 --- a/rules/docker-lldp-sv2.mk +++ b/rules/docker-lldp-sv2.mk @@ -8,21 +8,19 @@ $(DOCKER_LLDP_SV2)_PATH = $(DOCKERS_PATH)/docker-lldp-sv2 $(DOCKER_LLDP_SV2)_DEPENDS += $(LLDPD) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) -$(DOCKER_LLDP_SV2)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_LLDP_SV2)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_LLDP_SV2)_DBG_DEPENDS += $(LLDPD_DBG) $(LIBSWSSCOMMON_DBG) -$(DOCKER_LLDP_SV2)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_LLDP_SV2)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) $(DOCKER_LLDP_SV2)_PYTHON_WHEELS += $(DBSYNCD_PY2) -$(DOCKER_LLDP_SV2)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_LLDP_SV2)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_LLDP_SV2) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_LLDP_SV2) -SONIC_STRETCH_DOCKERS += $(DOCKER_LLDP_SV2) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_SV2_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_SV2_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_LLDP_SV2_DBG) $(DOCKER_LLDP_SV2)_CONTAINER_NAME = lldp $(DOCKER_LLDP_SV2)_RUN_OPT += --privileged -t From af95d57fa9448fce4b270051cd38ed6e4ae450e9 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Sun, 17 May 2020 04:26:50 -0700 Subject: [PATCH 0661/1427] [docker-base-buster]: Install python 3.7 into docker-base-buster (#4603) * Install python3 in docker-base-buster, so all derived image will benefit Signed-off-by: Qi Luo --- dockers/docker-base-buster/Dockerfile.j2 | 2 ++ dockers/docker-snmp-sv2/Dockerfile.j2 | 23 ++++------------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index 35016faf89a2..a8df37aaf2a5 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -45,6 +45,8 @@ RUN apt-get update && \ procps \ python \ python-pip \ + python3 \ + python3-pip \ rsyslog \ vim-tiny \ # Install dependencies of supervisor diff --git a/dockers/docker-snmp-sv2/Dockerfile.j2 b/dockers/docker-snmp-sv2/Dockerfile.j2 index 304c7fb44a9f..a7e46a58668d 100644 --- a/dockers/docker-snmp-sv2/Dockerfile.j2 +++ b/dockers/docker-snmp-sv2/Dockerfile.j2 @@ -11,20 +11,12 @@ ENV PYTHONOPTIMIZE 1 ENV DEBIAN_FRONTEND=noninteractive # Update apt's cache of available packages -# Install curl so we can download and install pip later -# Also install major root CA certificates for curl to reference -# Install gcc which is required for installing hiredis -# Install libdpkg-perl which is required for python3.6-3.6.0 as one of its specs i.e. no-pie-compile.specs -# The file referenced (`/usr/share/dpkg/no-pie-compile.specs`) is in the `libdpkg-perl` package on Debian +# Install make/gcc which is required for installing hiredis RUN apt-get update && \ apt-get install -y \ - python3 \ - python3-pip \ python3-dev \ - ca-certificates \ gcc \ make \ - libdpkg-perl \ ipmitool {% if docker_snmp_sv2_debs.strip() -%} @@ -36,7 +28,7 @@ RUN apt-get update && \ {%- endif %} # Fix for hiredis compilation issues for ARM -# python will throw for missing locale +# python will throw for missing locale RUN apt-get install -y locales RUN locale-gen "en_US.UTF-8" RUN dpkg-reconfigure --frontend noninteractive locales @@ -66,16 +58,9 @@ RUN python3 -m sonic_ax_impl install # Clean up RUN apt-get -y purge \ - python3-dev \ - curl \ + python3-dev \ gcc \ - make \ - libdpkg-perl \ - # Note: these packages should be removed with autoremove but actually not, so explicitly purged - libldap-2.4-2 \ - libsasl2-2 \ - libsasl2-modules \ - libsasl2-modules-db && \ + make && \ apt-get clean -y && \ apt-get autoclean -y && \ apt-get autoremove -y --purge && \ From 6706e5ab120e5a7e11d0d499257642a719934222 Mon Sep 17 00:00:00 2001 From: dereksun01 <52683998+dereksun01@users.noreply.github.com> Date: Tue, 19 May 2020 00:55:30 +0800 Subject: [PATCH 0662/1427] [device/accton] Add pre-emphasis parameters for as4630_54pe (#4604) --- .../media_settings.json | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 device/accton/x86_64-accton_as4630_54pe-r0/media_settings.json diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/media_settings.json b/device/accton/x86_64-accton_as4630_54pe-r0/media_settings.json new file mode 100644 index 000000000000..656f12355205 --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/media_settings.json @@ -0,0 +1,52 @@ +{ + "PORT_MEDIA_SETTINGS": { + "49": { + "Default": { + "preemphasis": { + "lane0":"0x124106" + } + } + }, + "50": { + "Default": { + "preemphasis": { + "lane0":"0x124106" + } + } + }, + "51": { + "Default": { + "preemphasis": { + "lane0":"0x124106" + } + } + }, + "52": { + "Default": { + "preemphasis": { + "lane0":"0x124106" + } + } + }, + "53": { + "Default": { + "preemphasis": { + "lane0":"0x124106", + "lane1":"0x124106", + "lane2":"0x124106", + "lane3":"0x124106" + } + } + }, + "54": { + "Default": { + "preemphasis": { + "lane0":"0x124106", + "lane1":"0x124106", + "lane2":"0x124106", + "lane3":"0x124106" + } + } + } + } +} From cb5221a452f6b73cd8123d4dfb530d982f56aeae Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 18 May 2020 09:55:41 -0700 Subject: [PATCH 0663/1427] [Submodule update] sonic-utilities (#4601) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix is_mgmt_vrf_enabled when MGMT_VRF_CONFIG is not present the config (#885) Changes to support acl-loader command for multi-npu platforms. (#908) Stop/Start restapi server upon config reload (#911) [fanshow] Add column drawer name and led status to output of show platform(#991) [MultiDB] use sonic-db-cli instead of redis-cli in new added codes (#907) [show] Add `ntpstat` output to `show ntp` (#861) [config] Log invocation of config commands to syslog (#259) Remove dependency on click-default-group package (#903) [config] Add 'interface transceiver' subgroup with 'lpmode' and 'rese…' (#904) [show] Add 'errors' and 'rates' subcommands to 'show interfaces count…(#900) [config] Support load_minigraph command for multi NPU platform (#896) [Vnet] Fix NameError for 'swsssdk' and align output (#902) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index c2facd8488f0..c52e26805d76 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit c2facd8488f023f98cab2c06d849c21cefc6fcf5 +Subproject commit c52e26805d76d0050e7cc80f25e91d6eae588ad9 From e83d06c78dfadf92f8369fe9f9b0c236c212a34f Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Tue, 19 May 2020 05:18:50 +0000 Subject: [PATCH 0664/1427] [sonic-slave-stretch]: install same version for docker-ce and docker-ce-cli difference versions can cause compatibility issue between the server and client Signed-off-by: Guohan Lu --- sonic-slave-stretch/Dockerfile.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index a02a39ed93c5..1844053d5278 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -427,8 +427,8 @@ RUN add-apt-repository \ stable" RUN apt-get update {%- if CONFIGURED_ARCH == "amd64" %} -RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-stretch +RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-stretch docker-ce-cli=5:18.09.5~3-0~debian-stretch {%- else %} -RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian +RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian docker-ce-cli=18.06.3~ce~3-0~debian {%- endif %} RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker From f243934b7e0fdccbfdbc42e8697441343ad933ff Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Tue, 19 May 2020 05:38:23 +0000 Subject: [PATCH 0665/1427] [sonic-slave-buster]: install same version for docker-ce and docker-ce-cli Signed-off-by: Guohan Lu --- sonic-slave-buster/Dockerfile.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index cf6d61f4b12f..dcd0f9ea5450 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -411,9 +411,9 @@ RUN add-apt-repository \ stable" RUN apt-get update {%- if CONFIGURED_ARCH == "amd64" %} -RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-buster +RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-buster docker-ce-cli=5:18.09.5~3-0~debian-buster {%- else %} -RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian +RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian docker-ce-cli=18.06.3~ce~3-0~debian {%- endif %} RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker RUN update-alternatives --set iptables /usr/sbin/iptables-legacy From e0f8aa71d6a8d0fa73c47c482f96716c8052378a Mon Sep 17 00:00:00 2001 From: Kelly Chen Date: Tue, 19 May 2020 17:52:48 +0800 Subject: [PATCH 0666/1427] [lldpmgrd] only log error in is_port_up() after port init done (#4606) lldpmgrd listens for changes to the PORT table in the CONFIG_DB and APP_DB in order to handle alias/description config change. It checks if port is up or down by looking into the oper-status for in APP_DB PORT TABLE. If it cannot find it in the App DB, it will log error. During initializing, it is possible that there is a port change in CONFIG_DB and but the not ready in APP_DB. The change here is to only log error in is_port_up() after port init done. --- dockers/docker-lldp-sv2/lldpmgrd | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd index 7e9ef1642a06..a0dff5d402f8 100755 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ b/dockers/docker-lldp-sv2/lldpmgrd @@ -119,7 +119,11 @@ class LldpManager(object): else: return False else: - log_error("Port '{}' not found in {} table in App DB".format(port_name, swsscommon.APP_PORT_TABLE_NAME)) + # Retrieve PortInitDone entry from the Port table + (init_status, init_fvp) = port_table.get("PortInitDone") + #The initialization procedure is done, but don't have this port entry + if init_status: + log_error("Port '{}' not found in {} table in App DB".format(port_name, swsscommon.APP_PORT_TABLE_NAME)) return False def generate_pending_lldp_config_cmd_for_port(self, port_name): From 9084ac50fbac66e9d9af0963cfd37c9637c3ba6d Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Tue, 19 May 2020 03:12:50 -0700 Subject: [PATCH 0667/1427] [docker-telemetry]: upgrade telemetry docker to buster (#4515) Signed-off-by: Joyas Joseph --- dockers/docker-sonic-telemetry/Dockerfile.j2 | 2 +- rules/docker-telemetry.mk | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dockers/docker-sonic-telemetry/Dockerfile.j2 b/dockers/docker-sonic-telemetry/Dockerfile.j2 index cbc8a1e916fa..d3b95c3b4002 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 04f1871f334b..e4c689bde5d1 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -7,21 +7,19 @@ DOCKER_TELEMETRY_DBG = $(DOCKER_TELEMETRY_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_TELEMETRY)_PATH = $(DOCKERS_PATH)/$(DOCKER_TELEMETRY_STEM) $(DOCKER_TELEMETRY)_DEPENDS += $(REDIS_TOOLS) $(SONIC_TELEMETRY) -$(DOCKER_TELEMETRY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_TELEMETRY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) -$(DOCKER_TELEMETRY)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) -$(DOCKER_TELEMETRY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_TELEMETRY)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) +$(DOCKER_TELEMETRY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) SONIC_DOCKER_IMAGES += $(DOCKER_TELEMETRY) ifeq ($(ENABLE_SYSTEM_TELEMETRY), y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_TELEMETRY) -SONIC_STRETCH_DOCKERS += $(DOCKER_TELEMETRY) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_TELEMETRY_DBG) ifeq ($(ENABLE_SYSTEM_TELEMETRY), y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_TELEMETRY_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_TELEMETRY_DBG) endif $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry From cde69bafa95c6edcc3178e3f81f14a3138376d11 Mon Sep 17 00:00:00 2001 From: taochengyi <54564117+taocy001@users.noreply.github.com> Date: Wed, 20 May 2020 00:22:35 +0800 Subject: [PATCH 0668/1427] [centec]: Adding missing changes for centec x86 platform (#4611) PR #4605 has two changes that are missing, fix them. --- .../sonic-platform-modules-e582/debian/rules | 6 ++++- .../debian/rules | 22 +++++-------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/platform/centec/sonic-platform-modules-e582/debian/rules b/platform/centec/sonic-platform-modules-e582/debian/rules index 90a9c5642bae..b726f62c8c68 100755 --- a/platform/centec/sonic-platform-modules-e582/debian/rules +++ b/platform/centec/sonic-platform-modules-e582/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= 48x6q 48x2q4z ../centec-dal +MODULE_DIRS:= 48x6q 48x2q4z %: dh $@ @@ -14,6 +14,7 @@ override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ done) + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal override_dh_auto_install: (for mod in $(MODULE_DIRS); do \ @@ -21,6 +22,7 @@ override_dh_auto_install: $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ cp -f $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp -f $(MOD_SRC_DIR)/../centec-dal/*.ko debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ done) override_dh_usrlocal: @@ -32,4 +34,6 @@ override_dh_clean: rm -rf $(MOD_SRC_DIR)/$${mod}/modules/*.ko; \ rm -rf debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)/*.ko; \ done) + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal clean; \ + rm -rf $(MOD_SRC_DIR)/../centec-dal/*.ko diff --git a/platform/centec/sonic-platform-modules-embedway/debian/rules b/platform/centec/sonic-platform-modules-embedway/debian/rules index 20716d0620c6..250c0861e196 100755 --- a/platform/centec/sonic-platform-modules-embedway/debian/rules +++ b/platform/centec/sonic-platform-modules-embedway/debian/rules @@ -5,31 +5,21 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= ../centec-dal %: dh $@ override_dh_auto_build: - (for mod in $(MODULE_DIRS); do \ - make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ - done) + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal override_dh_auto_install: - (for mod in $(MODULE_DIRS); do \ - dh_installdirs -pplatform-modules-embedway-$${mod} \ - $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - cp -f $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ - debian/platform-modules-embedway-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - done) + dh_installdirs -pplatform-modules-embedway-es6220 \ + $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp -f $(MOD_SRC_DIR)/../centec-dal/*.ko debian/platform-modules-embedway-es6220/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) override_dh_usrlocal: override_dh_clean: dh_clean - (for mod in $(MODULE_DIRS); do \ - make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ - rm -rf $(MOD_SRC_DIR)/$${mod}/modules/*.ko; \ - rm -rf debian/platform-modules-embedway-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)/*.ko; \ - done) - + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal clean; \ + rm -rf $(MOD_SRC_DIR)/../centec-dal/*.ko From 9c7105b5f3b7200529bc3b312b8de4bc9f808f11 Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Tue, 19 May 2020 14:15:05 -0400 Subject: [PATCH 0669/1427] Install swsssdk-py3 in the base Debian image for python3 based apps (#4542) Signed-off-by: Rajendra Dendukuri --- files/build_templates/sonic_debian_extension.j2 | 8 ++++++++ rules/sonic-ztp.mk | 1 + slave.mk | 1 + 3 files changed, 10 insertions(+) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 3fa789ff60c9..654c70155390 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -116,6 +116,14 @@ sudo cp {{swsssdk_py2_wheel_path}} $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SWSSSDK_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME +# Install SwSS SDK Python 3 package +if [ -e {{swsssdk_py3_wheel_path}} ]; then + SWSSSDK_PY3_WHEEL_NAME=$(basename {{swsssdk_py3_wheel_path}}) + sudo cp {{swsssdk_py3_wheel_path}} $FILESYSTEM_ROOT/$SWSSSDK_PY3_WHEEL_NAME + sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SWSSSDK_PY3_WHEEL_NAME + sudo rm -rf $FILESYSTEM_ROOT/$SWSSSDK_PY3_WHEEL_NAME +fi + # Install sonic-yang-models py3 package, install dependencies sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang_*.deb sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang-cpp_*.deb diff --git a/rules/sonic-ztp.mk b/rules/sonic-ztp.mk index a848bcca148a..0c4819ec6004 100644 --- a/rules/sonic-ztp.mk +++ b/rules/sonic-ztp.mk @@ -5,6 +5,7 @@ SONIC_ZTP_VERSION = 1.0.0 SONIC_ZTP = sonic-ztp_$(SONIC_ZTP_VERSION)_all.deb $(SONIC_ZTP)_SRC_PATH = $(SRC_PATH)/sonic-ztp +$(SONIC_ZTP)_WHEEL_DEPENDS += $(SWSSSDK_PY3) SONIC_DPKG_DEBS += $(SONIC_ZTP) export SONIC_ZTP_VERSION diff --git a/slave.mk b/slave.mk index f30260157ffe..6f7d53475e6a 100644 --- a/slave.mk +++ b/slave.mk @@ -813,6 +813,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export installer_images="$(addprefix $(TARGET_PATH)/,$($*_DOCKERS))" export config_engine_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE))" export swsssdk_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY2))" + export swsssdk_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY3))" export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" From cdfb1ced44d09fe075be3be047d2bd715b218f97 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Wed, 20 May 2020 10:57:21 -0700 Subject: [PATCH 0670/1427] [ntp] enable/disable NTP long jump according to reboot type (#4577) * [ntp] enable/disable NTP long jump according to reboot type - Enable NTP long jump after cold reboot. - Disable NTP long jump after warrm/fast reboot. Signed-off-by: Ying Xie * fix typo * further refactoring * use sonic-db-cli instead --- files/image_config/ntp/ntp-config.sh | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/files/image_config/ntp/ntp-config.sh b/files/image_config/ntp/ntp-config.sh index 601b7bd421f0..7ab84174dcaa 100755 --- a/files/image_config/ntp/ntp-config.sh +++ b/files/image_config/ntp/ntp-config.sh @@ -1,5 +1,37 @@ #!/bin/bash +ntp_default_file='/etc/default/ntp' +ntp_temp_file='/tmp/ntp.orig' + +reboot_type='cold' + +function get_database_reboot_type() +{ + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SYSTEM_FAST_START=`sonic-db-cli STATE_DB get "FAST_REBOOT|system"` + + if [[ x"${SYSTEM_WARM_START}" == x"true" ]]; then + reboot_type='warm' + elif [[ x"${SYSTEM_FAST_START}" == x"1" ]]; then + reboot_type='fast' + fi +} + +function modify_ntp_default +{ + cp ${ntp_default_file} ${ntp_temp_file} + sed -e "$1" ${ntp_temp_file} >${ntp_default_file} +} + sonic-cfggen -d -t /usr/share/sonic/templates/ntp.conf.j2 >/etc/ntp.conf +get_database_reboot_type +if [[ x"${reboot_type}" == x"cold" ]]; then + echo "Enabling NTP long jump for reboot type ${reboot_type} ..." + modify_ntp_default "s/NTPD_OPTS='-x'/NTPD_OPTS='-g'/" +else + echo "Disabling NTP long jump for reboot type ${reboot_type} ..." + modify_ntp_default "s/NTPD_OPTS='-g'/NTPD_OPTS='-x'/" +fi + systemctl restart ntp From 32f58b586444bd359a7973546893d892cb564097 Mon Sep 17 00:00:00 2001 From: rkdevi27 <54701695+rkdevi27@users.noreply.github.com> Date: Wed, 20 May 2020 23:48:11 +0530 Subject: [PATCH 0671/1427] Fix "/host unmount failure" during reboot (#4558) --- .../build_templates/sonic_debian_extension.j2 | 5 +++ files/image_config/syslog/host_umount.sh | 31 +++++++++++++++++++ files/image_config/syslog/override.conf | 6 ++++ 3 files changed, 42 insertions(+) create mode 100755 files/image_config/syslog/host_umount.sh create mode 100644 files/image_config/syslog/override.conf diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 654c70155390..97cd199eceae 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -224,6 +224,11 @@ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.d/* $FILESYSTEM_ROOT/etc/rsyslog.d/ echo "rsyslog-config.service" | sudo tee -a $GENERATED_SERVICE_FILE +# Copy syslog override files +sudo mkdir -p $FILESYSTEM_ROOT/etc/systemd/system/syslog.socket.d +sudo cp $IMAGE_CONFIGS/syslog/override.conf $FILESYSTEM_ROOT/etc/systemd/system/syslog.socket.d/override.conf +sudo cp $IMAGE_CONFIGS/syslog/host_umount.sh $FILESYSTEM_ROOT/usr/bin/ + # Copy logrotate.d configuration files sudo cp -f $IMAGE_CONFIGS/logrotate/logrotate.d/* $FILESYSTEM_ROOT/etc/logrotate.d/ diff --git a/files/image_config/syslog/host_umount.sh b/files/image_config/syslog/host_umount.sh new file mode 100755 index 000000000000..cedbb5b11107 --- /dev/null +++ b/files/image_config/syslog/host_umount.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# This script is invoked at the closure of syslog socket during reboot +# This will stop journal services, unmount /var/log and delete loop device +# associated to /host to ensure proper unmount of /host + +journal_stop() { + systemctl stop systemd-journald.service + systemctl stop systemd-journald.socket + systemctl stop systemd-journald-audit.socket + systemctl stop systemd-journald-dev-log.socket +} + +delete_loop_device() { + umount /var/log + if [[ $? -ne 0 ]] + then + exit 0 + fi + losetup -d /dev/loop1 +} + +case "$1" in + journal_stop|delete_loop_device) + $1 + ;; + *) + echo "Usage: $0 {journal_stop|delete_loop_device}" >&2 + exit 1 + ;; +esac + diff --git a/files/image_config/syslog/override.conf b/files/image_config/syslog/override.conf new file mode 100644 index 000000000000..74f7aea9f076 --- /dev/null +++ b/files/image_config/syslog/override.conf @@ -0,0 +1,6 @@ +[Unit] +After=var-log.mount host.mount + +[Socket] +ExecStopPre=/usr/bin/host_umount.sh journal_stop +ExecStopPost=/usr/bin/host_umount.sh delete_loop_device From de4fa1874a5d9b3a03888c41f231954472b992a7 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Wed, 20 May 2020 12:44:48 -0700 Subject: [PATCH 0672/1427] [arista]: remove the soc property disabling sram scan (#4623) --- .../Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm | 1 - .../Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm | 1 - .../Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm | 1 - 3 files changed, 3 deletions(-) diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm index 217d15b4e579..e66e2e98416e 100644 --- a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm @@ -35,7 +35,6 @@ port_phy_addr=0xff robust_hash_disable_egress_vlan=1 robust_hash_disable_mpls=1 robust_hash_disable_vlan=1 -sram_scan_enable=0 stable_size=0x5500000 tdma_timeout_usec=15000000 tslam_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm index 5002d29045ab..f4450ebac53f 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm @@ -872,7 +872,6 @@ port_phy_addr_147.0=0xff robust_hash_disable_egress_vlan.0=1 robust_hash_disable_mpls.0=1 robust_hash_disable_vlan.0=1 -sram_scan_enable.0=0 tdma_timeout_usec.0=15000000 tslam_timeout_usec.0=15000000 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm index d3a66dee635f..cdbc4f4430b4 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm @@ -744,7 +744,6 @@ port_phy_addr_143.0=0xff robust_hash_disable_egress_vlan.0=1 robust_hash_disable_mpls.0=1 robust_hash_disable_vlan.0=1 -sram_scan_enable.0=0 tdma_timeout_usec.0=15000000 tslam_timeout_usec.0=15000000 From 9b48f5746c3a17ecb50c3620371ad235d9b3a363 Mon Sep 17 00:00:00 2001 From: chihhan123 <56335706+chihhan123@users.noreply.github.com> Date: Thu, 21 May 2020 03:47:55 +0800 Subject: [PATCH 0673/1427] [device/accton] Modify interface name of port_config.ini on AS9716-32D (#4507) --- .../Accton-AS9716-32D/port_config.ini | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/port_config.ini b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/port_config.ini index a13514fcd909..ab5ba53d280e 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/port_config.ini +++ b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/port_config.ini @@ -1,33 +1,33 @@ # name lanes alias index speed -Ethernet0 73,74,75,76,77,78,79,80 fourHundredGigE1 0 400000 -Ethernet4 65,66,67,68,69,70,71,72 fourHundredGigE2 1 400000 -Ethernet8 81,82,83,84,85,86,87,88 fourHundredGigE3 2 400000 -Ethernet12 89,90,91,92,93,94,95,96 fourHundredGigE4 3 400000 -Ethernet16 97,98,99,100,101,102,103,104 fourHundredGigE5 4 400000 -Ethernet20 105,106,107,108,109,110,111,112 fourHundredGigE6 5 400000 -Ethernet24 113,114,115,116,117,118,119,120 fourHundredGigE7 6 400000 -Ethernet28 121,122,123,124,125,126,127,128 fourHundredGigE8 7 400000 -Ethernet32 41,42,43,44,45,46,47,48 fourHundredGigE9 8 400000 -Ethernet36 33,34,35,36,37,38,39,40 fourHundredGigE10 9 400000 -Ethernet40 49,50,51,52,53,54,55,56 fourHundredGigE11 10 400000 -Ethernet44 57,58,59,60,61,62,63,64 fourHundredGigE12 11 400000 -Ethernet48 129,130,131,132,133,134,135,136 fourHundredGigE13 12 400000 -Ethernet52 137,138,139,140,141,142,143,144 fourHundredGigE14 13 400000 -Ethernet56 145,146,147,148,149,150,151,152 fourHundredGigE15 14 400000 -Ethernet60 153,154,155,156,157,158,159,160 fourHundredGigE16 15 400000 -Ethernet64 169,170,171,172,173,174,175,176 fourHundredGigE17 16 400000 -Ethernet68 161,162,163,164,165,166,167,168 fourHundredGigE18 17 400000 -Ethernet72 177,178,179,180,181,182,183,184 fourHundredGigE19 18 400000 -Ethernet76 185,186,187,188,189,190,191,192 fourHundredGigE20 19 400000 -Ethernet80 1,2,3,4,5,6,7,8 fourHundredGigE21 20 400000 -Ethernet84 9,10,11,12,13,14,15,16 fourHundredGigE22 21 400000 -Ethernet88 17,18,19,20,21,22,23,24 fourHundredGigE23 22 400000 -Ethernet92 25,26,27,28,29,30,31,32 fourHundredGigE24 23 400000 -Ethernet96 201,202,203,204,205,206,207,208 fourHundredGigE25 24 400000 -Ethernet100 193,194,195,196,197,198,199,200 fourHundredGigE26 25 400000 -Ethernet104 217,218,219,220,221,222,223,224 fourHundredGigE27 26 400000 -Ethernet108 209,210,211,212,213,214,215,216 fourHundredGigE28 27 400000 -Ethernet112 233,234,235,236,237,238,239,240 fourHundredGigE29 28 400000 -Ethernet116 225,226,227,228,229,230,231,232 fourHundredGigE30 29 400000 -Ethernet120 249,250,251,252,253,254,255,256 fourHundredGigE31 30 400000 -Ethernet124 241,242,243,244,245,246,247,248 fourHundredGigE32 31 400000 +Ethernet0 73,74,75,76,77,78,79,80 fourHundredGigE1 0 400000 +Ethernet8 65,66,67,68,69,70,71,72 fourHundredGigE2 1 400000 +Ethernet16 81,82,83,84,85,86,87,88 fourHundredGigE3 2 400000 +Ethernet24 89,90,91,92,93,94,95,96 fourHundredGigE4 3 400000 +Ethernet32 97,98,99,100,101,102,103,104 fourHundredGigE5 4 400000 +Ethernet40 105,106,107,108,109,110,111,112 fourHundredGigE6 5 400000 +Ethernet48 113,114,115,116,117,118,119,120 fourHundredGigE7 6 400000 +Ethernet56 121,122,123,124,125,126,127,128 fourHundredGigE8 7 400000 +Ethernet64 41,42,43,44,45,46,47,48 fourHundredGigE9 8 400000 +Ethernet72 33,34,35,36,37,38,39,40 fourHundredGigE10 9 400000 +Ethernet80 49,50,51,52,53,54,55,56 fourHundredGigE11 10 400000 +Ethernet88 57,58,59,60,61,62,63,64 fourHundredGigE12 11 400000 +Ethernet96 129,130,131,132,133,134,135,136 fourHundredGigE13 12 400000 +Ethernet104 137,138,139,140,141,142,143,144 fourHundredGigE14 13 400000 +Ethernet112 145,146,147,148,149,150,151,152 fourHundredGigE15 14 400000 +Ethernet120 153,154,155,156,157,158,159,160 fourHundredGigE16 15 400000 +Ethernet128 169,170,171,172,173,174,175,176 fourHundredGigE17 16 400000 +Ethernet136 161,162,163,164,165,166,167,168 fourHundredGigE18 17 400000 +Ethernet144 177,178,179,180,181,182,183,184 fourHundredGigE19 18 400000 +Ethernet152 185,186,187,188,189,190,191,192 fourHundredGigE20 19 400000 +Ethernet160 1,2,3,4,5,6,7,8 fourHundredGigE21 20 400000 +Ethernet168 9,10,11,12,13,14,15,16 fourHundredGigE22 21 400000 +Ethernet176 17,18,19,20,21,22,23,24 fourHundredGigE23 22 400000 +Ethernet184 25,26,27,28,29,30,31,32 fourHundredGigE24 23 400000 +Ethernet192 201,202,203,204,205,206,207,208 fourHundredGigE25 24 400000 +Ethernet200 193,194,195,196,197,198,199,200 fourHundredGigE26 25 400000 +Ethernet208 217,218,219,220,221,222,223,224 fourHundredGigE27 26 400000 +Ethernet216 209,210,211,212,213,214,215,216 fourHundredGigE28 27 400000 +Ethernet224 233,234,235,236,237,238,239,240 fourHundredGigE29 28 400000 +Ethernet232 225,226,227,228,229,230,231,232 fourHundredGigE30 29 400000 +Ethernet240 249,250,251,252,253,254,255,256 fourHundredGigE31 30 400000 +Ethernet248 241,242,243,244,245,246,247,248 fourHundredGigE32 31 400000 From 19b224be1409853d085a0f1b636392a88cb00a20 Mon Sep 17 00:00:00 2001 From: dereksun01 <52683998+dereksun01@users.noreply.github.com> Date: Thu, 21 May 2020 03:51:51 +0800 Subject: [PATCH 0674/1427] [device/accton] as4630_54pe add custom_led.bin file (#4534) --- .../x86_64-accton_as4630_54pe-r0/custom_led.bin | Bin 0 -> 952 bytes .../led_proc_init.soc | 1 + 2 files changed, 1 insertion(+) create mode 100644 device/accton/x86_64-accton_as4630_54pe-r0/custom_led.bin diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/custom_led.bin b/device/accton/x86_64-accton_as4630_54pe-r0/custom_led.bin new file mode 100644 index 0000000000000000000000000000000000000000..b402867a7d204e5575047e5a148a3d4f471d3a71 GIT binary patch literal 952 zcma*lPe_w-7zgm@xA%3M&T9F0bN+d^cW(aw!xTvaU*B!NYEG#YqARFPgBR-HAxf}= zAs9u6a1hK543h-CNam@6or3bR(Iq-f6zaI6bg}Q&kU9h%KF{+UzQ2d(9n0TFt^Q_@aeZquCF{P+&P;ajJ}u$v6ZJ1)2v{S_I(`79qv-(Cfv1vDrQrttWdX%2~v4TTMdc*lrVcJ*3(JpiSJ!wN2-nk|2k9rOMJ?s`p;yQ(D7GHjeC$ zT2@Hz9tm=wn6r3^iQajm;`x0+GNcOF)>_>)s?NMEC zB)S$oh#pKI%m~}(-#_PZzQ(tB?!)ClqV;W}++KiGdE4Z5KRI-v_>aDp8i;D#1x1{XAe1P#y#HmCSFCtRjr~m)} literal 0 HcmV?d00001 diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc b/device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc index 4fa004f5d130..5bef973ed2ae 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc +++ b/device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc @@ -1,2 +1,3 @@ +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin led start led auto on From e976b70e74d22c05eebc8d29dfaca5d87fabc492 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Thu, 21 May 2020 01:22:50 +0530 Subject: [PATCH 0675/1427] DellEMC: get_change_event Platform API implementation for S6000, S6100 and Z9100 (#4593) For detecting transceiver change events through xcvrd in DellEMC S6000, S6100 and Z9100 platforms. - In S6000, rename 'get_transceiver_change_event' in chassis.py to 'get_change_event' and return appropriate values. - In S6100, implement 'get_change_event' through polling method (poll interval = 1 second) in chassis.py (Transceiver insertion/removal does not generate interrupts due to a CPLD bug) - In Z9100, implement 'get_change_event' through interrupt method using select.epoll(). --- .../s6000/sonic_platform/chassis.py | 31 +++- .../s6100/sonic_platform/chassis.py | 120 +++++++++++++ .../z9100/sonic_platform/chassis.py | 163 +++++++++++++++++- 3 files changed, 305 insertions(+), 9 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index 8bb95cac1d63..0a6cac372676 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -237,13 +237,32 @@ def _get_transceiver_status(self): return int(content, 16) - def get_transceiver_change_event(self, timeout=0): + def get_change_event(self, timeout=0): """ - Returns a dictionary containing sfp changes which have + Returns a nested dictionary containing all devices which have experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the + format of {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. """ start_time = time.time() port_dict = {} + ret_dict = {"sfp": port_dict} port = self.PORT_START forever = False @@ -256,7 +275,7 @@ def get_transceiver_change_event(self, timeout=0): end_time = start_time + timeout if (start_time > end_time): - return False, {} # Time wrap or possibly incorrect timeout + return False, ret_dict # Time wrap or possibly incorrect timeout while (timeout >= 0): # Check for OIR events and return updated port_dict @@ -276,7 +295,7 @@ def get_transceiver_change_event(self, timeout=0): # Update reg value self.modprs_register = reg_value - return True, port_dict + return True, ret_dict if forever: time.sleep(1) @@ -287,7 +306,7 @@ def get_transceiver_change_event(self, timeout=0): else: if timeout > 0: time.sleep(timeout) - return True, {} - return False, {} + return True, ret_dict + return False, ret_dict diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py index a1c7692b5f6e..3284e671bfe0 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py @@ -39,6 +39,7 @@ class Chassis(ChassisBase): HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" HWMON_NODE = os.listdir(HWMON_DIR)[0] MAILBOX_DIR = HWMON_DIR + HWMON_NODE + POLL_INTERVAL = 1 # Poll interval in seconds reset_reason_dict = {} reset_reason_dict[11] = ChassisBase.REBOOT_CAUSE_POWER_LOSS @@ -81,6 +82,7 @@ def __init__(self): self._component_list.append(component) self._watchdog = Watchdog() + self._transceiver_presence = self._get_transceiver_presence() def _get_reboot_reason_smf_register(self): # In S6100, mb_poweron_reason register will @@ -111,6 +113,24 @@ def _get_pmc_register(self, reg_name): rv = rv.lstrip(" ") return rv + def _get_register(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + def get_name(self): """ Retrieves the name of the chassis @@ -215,3 +235,103 @@ def get_reboot_cause(self): return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") + + def _get_transceiver_presence(self): + + cpld2_modprs = self._get_register( + "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_modprs") + cpld3_modprs = self._get_register( + "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_modprs") + cpld4_modprs = self._get_register( + "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_modprs") + cpld5_modprs = self._get_register( + "/sys/class/i2c-adapter/i2c-17/17-003e/qsfp_modprs") + + # If IOM is not present, register read will fail. + # Handle the scenario gracefully + if (cpld2_modprs == 'read error') or (cpld2_modprs == 'ERR'): + cpld2_modprs = '0x0' + if (cpld3_modprs == 'read error') or (cpld3_modprs == 'ERR'): + cpld3_modprs = '0x0' + if (cpld4_modprs == 'read error') or (cpld4_modprs == 'ERR'): + cpld4_modprs = '0x0' + if (cpld5_modprs == 'read error') or (cpld5_modprs == 'ERR'): + cpld5_modprs = '0x0' + + # Make it contiguous + transceiver_presence = (int(cpld2_modprs, 16) & 0xffff) |\ + ((int(cpld4_modprs, 16) & 0xffff) << 16) |\ + ((int(cpld3_modprs, 16) & 0xffff) << 32) |\ + ((int(cpld5_modprs, 16) & 0xffff) << 48) + + return transceiver_presence + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the + format of {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + port_dict = {} + ret_dict = {'sfp': port_dict} + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + return False, ret_dict # Incorrect timeout + + while True: + if forever: + timer = self.POLL_INTERVAL + else: + timer = min(timeout, self.POLL_INTERVAL) + start_time = time.time() + + time.sleep(timer) + cur_presence = self._get_transceiver_presence() + + # Update dict only if a change has been detected + if cur_presence != self._transceiver_presence: + changed_ports = self._transceiver_presence ^ cur_presence + for port in range(self.get_num_sfps()): + # Mask off the bit corresponding to particular port + mask = 1 << port + if changed_ports & mask: + # qsfp_modprs 1 => optics is removed + if cur_presence & mask: + port_dict[port] = '0' + # qsfp_modprs 0 => optics is inserted + else: + port_dict[port] = '1' + + # Update current presence + self._transceiver_presence = cur_presence + break + + if not forever: + elapsed_time = time.time() - start_time + timeout = round(timeout - elapsed_time, 3) + if timeout <= 0: + break + + return True, ret_dict diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index 3e070d54004e..3f03f9671f91 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py @@ -10,8 +10,8 @@ try: import os - import subprocess - import re + import select + import sys from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.fan import Fan @@ -60,6 +60,8 @@ class Chassis(ChassisBase): 28: [16, 6], 29: [16, 7], 30: [16, 8], 31: [16, 9] } + OIR_FD_PATH = "/sys/devices/platform/dell_ich.0/sci_int_gpio_sus6" + reset_reason_dict = {} reset_reason_dict[11] = ChassisBase.REBOOT_CAUSE_POWER_LOSS reset_reason_dict[33] = ChassisBase.REBOOT_CAUSE_WATCHDOG @@ -74,6 +76,8 @@ class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) + self.oir_fd = -1 + self.epoll = -1 PORT_START = 0 PORT_END = 31 PORTS_IN_BLOCK = (PORT_END + 1) @@ -112,6 +116,12 @@ def __init__(self): component = Component(i) self._component_list.append(component) + def __del__(self): + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + def _get_pmc_register(self, reg_name): # On successful read, returns the value read from given # reg_name and on failure returns 'ERR' @@ -131,6 +141,24 @@ def _get_pmc_register(self, reg_name): rv = rv.lstrip(" ") return rv + def _get_register(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + def get_name(self): """ Retrieves the name of the chassis @@ -162,7 +190,7 @@ def get_serial(self): string: Serial number of chassis """ return self._eeprom.serial_str() - + def get_sfp(self, index): """ Retrieves sfp represented by (1-based) index @@ -252,3 +280,132 @@ def get_reboot_cause(self): return (self.reset_reason_dict[reset_reason], None) return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") + + def _check_interrupts(self, port_dict): + is_port_dict_updated = False + + cpld2_abs_int = self._get_register( + "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_int") + cpld2_abs_sta = self._get_register( + "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_sta") + cpld3_abs_int = self._get_register( + "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_int") + cpld3_abs_sta = self._get_register( + "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_sta") + cpld4_abs_int = self._get_register( + "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_int") + cpld4_abs_sta = self._get_register( + "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_sta") + + if (cpld2_abs_int == 'ERR' or cpld2_abs_sta == 'ERR' or + cpld3_abs_int == 'ERR' or cpld3_abs_sta == 'ERR' or + cpld4_abs_int == 'ERR' or cpld4_abs_sta == 'ERR'): + return False, is_port_dict_updated + + cpld2_abs_int = int(cpld2_abs_int, 16) + cpld2_abs_sta = int(cpld2_abs_sta, 16) + cpld3_abs_int = int(cpld3_abs_int, 16) + cpld3_abs_sta = int(cpld3_abs_sta, 16) + cpld4_abs_int = int(cpld4_abs_int, 16) + cpld4_abs_sta = int(cpld4_abs_sta, 16) + + # Make it contiguous (discard reserved bits) + interrupt_reg = (cpld2_abs_int & 0xfff) |\ + ((cpld3_abs_int & 0x3ff) << 12) |\ + ((cpld4_abs_int & 0x3ff) << 22) + status_reg = (cpld2_abs_sta & 0xfff) |\ + ((cpld3_abs_sta & 0x3ff) << 12) |\ + ((cpld4_abs_sta & 0x3ff) << 22) + + for port in range(self.get_num_sfps()): + if interrupt_reg & (1 << port): + # update only if atleast one port has generated + # interrupt + is_port_dict_updated = True + if status_reg & (1 << port): + # status reg 1 => optics is removed + port_dict[port+1] = '0' + else: + # status reg 0 => optics is inserted + port_dict[port+1] = '1' + + return True, is_port_dict_updated + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the + format of {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + port_dict = {} + ret_dict = {'sfp': port_dict} + if timeout != 0: + timeout = timeout / 1000 + try: + # We get notified when there is an SCI interrupt from GPIO SUS6 + # Open the sysfs file and register the epoll object + self.oir_fd = open(self.OIR_FD_PATH, "r") + if self.oir_fd != -1: + # Do a dummy read before epoll register + self.oir_fd.read() + self.epoll = select.epoll() + self.epoll.register(self.oir_fd.fileno(), + select.EPOLLIN & select.EPOLLET) + else: + return False, ret_dict + + # Check for missed interrupts by invoking self.check_interrupts + # which will update the port_dict. + while True: + interrupt_count_start = self._get_register(self.OIR_FD_PATH) + + retval, is_port_dict_updated = \ + self._check_interrupts(port_dict) + if (retval is True) and (is_port_dict_updated is True): + return True, ret_dict + + interrupt_count_end = self._get_register(self.OIR_FD_PATH) + + if (interrupt_count_start == 'ERR' or + interrupt_count_end == 'ERR'): + break + + # check_interrupts() itself may take upto 100s of msecs. + # We detect a missed interrupt based on the count + if interrupt_count_start == interrupt_count_end: + break + + # Block until an xcvr is inserted or removed with timeout = -1 + events = self.epoll.poll(timeout=timeout if timeout != 0 else -1) + if events: + # check interrupts and return the port_dict + retval, is_port_dict_updated = \ + self._check_interrupts(port_dict) + + return retval, ret_dict + except Exception: + return False, ret_dict + finally: + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + self.oir_fd = -1 + self.epoll = -1 From 2cd9f74d21d6d49cd2eeb4ee7191d5722a35a23f Mon Sep 17 00:00:00 2001 From: Srideep Date: Wed, 20 May 2020 15:40:39 -0600 Subject: [PATCH 0676/1427] [platform] Add DellEMC s5232f API 2.0 support (#4552) --- .../common/dell_pmc.c | 12 + .../common/ipmihelper.py | 35 +- .../common/sonic_platform/hwaccess.py | 24 + .../debian/platform-modules-s5232f.install | 1 + .../sonic-platform-modules-dell/debian/rules | 10 + .../s5232f/scripts/s5232f_platform.sh | 18 +- .../s5232f/setup.py | 1 + .../s5232f/sonic_platform/__init__.py | 1 + .../s5232f/sonic_platform/chassis.py | 231 ++++ .../s5232f/sonic_platform/component.py | 123 ++ .../s5232f/sonic_platform/eeprom.py | 141 +++ .../s5232f/sonic_platform/fan.py | 182 +++ .../s5232f/sonic_platform/hwaccess.py | 1 + .../s5232f/sonic_platform/platform.py | 24 + .../s5232f/sonic_platform/psu.py | 179 +++ .../s5232f/sonic_platform/sfp.py | 1045 +++++++++++++++++ .../s5232f/sonic_platform/thermal.py | 155 +++ .../s5232f/sonic_platform/watchdog.py | 210 ++++ 18 files changed, 2380 insertions(+), 13 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-dell/common/sonic_platform/hwaccess.py create mode 120000 platform/broadcom/sonic-platform-modules-dell/s5232f/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py create mode 120000 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/hwaccess.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/platform.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/sfp.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/watchdog.py diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c index e8cddf4fad11..da4f451700eb 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -1785,6 +1785,16 @@ static ssize_t show_psu(struct device *dev, } ret = pow/10; break; + case 11: + psu_status = smf_read_reg(data, PSU_1_STATUS); + if (psu_status &(2)) + ret=1; + break; + case 12: + psu_status = smf_read_reg(data, PSU_2_STATUS); + if (psu_status &(2)) + ret=1; + break; default: return ret; } @@ -2027,6 +2037,8 @@ static SENSOR_DEVICE_ATTR(psu1_presence, S_IRUGO, show_psu, NULL, 1); static SENSOR_DEVICE_ATTR(psu2_presence, S_IRUGO, show_psu, NULL, 6); static SENSOR_DEVICE_ATTR(psu1_serialno, S_IRUGO, show_ppid, NULL, 10); static SENSOR_DEVICE_ATTR(psu2_serialno, S_IRUGO, show_ppid, NULL, 11); +static SENSOR_DEVICE_ATTR(psu1_type, S_IRUGO, show_psu, NULL, 11); +static SENSOR_DEVICE_ATTR(psu2_type, S_IRUGO, show_psu, NULL, 12); static SENSOR_DEVICE_ATTR(current_total_power, S_IRUGO, show_psu, NULL, 10); /* SMF Version */ diff --git a/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py b/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py index 182d74c218cf..046ca21938db 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py +++ b/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py @@ -185,33 +185,44 @@ def _get_ipmitool_fru_print(self): return result - def get_board_serial(self): + def _get_from_fru(self, info): """ - Returns a string containing the Serial Number of the device. + Returns a string containing the info from FRU """ fru_output = self._get_ipmitool_fru_print() if not fru_output: return "NA" - board_serial = re.search(r'Board Serial\s*:(.*)', fru_output) - if not board_serial: + info_req = re.search(r"%s\s*:(.*)"%info, fru_output) + if not info_req: return "NA" - return board_serial.group(1).strip() + return info_req.group(1).strip() + + def get_board_serial(self): + """ + Returns a string containing the Serial Number of the device. + """ + return self._get_from_fru('Board Serial') def get_board_part_number(self): """ Returns a string containing the Part Number of the device. """ - fru_output = self._get_ipmitool_fru_print() - if not fru_output: - return "NA" + return self._get_from_fru('Board Part Number') - board_pn = re.search(r'Board Part Number\s*:(.*)', fru_output) - if not board_pn: - return "NA" + def get_board_mfr_id(self): + """ + Returns a string containing the manufacturer id of the FRU. + """ + return self._get_from_fru('Board Mfg') + + def get_board_product(self): + """ + Returns a string containing the manufacturer id of the FRU. + """ + return self._get_from_fru('Board Product') - return board_pn.group(1).strip() def get_fru_data(self, offset, count=1): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/common/sonic_platform/hwaccess.py b/platform/broadcom/sonic-platform-modules-dell/common/sonic_platform/hwaccess.py new file mode 100644 index 000000000000..b0020144a4fb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/sonic_platform/hwaccess.py @@ -0,0 +1,24 @@ +# Helper functions to access hardware + +import struct +import mmap +import subprocess + +# Read PCI device + +def pci_mem_read(mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + return struct.unpack('I',read_data_stream)[0] + +def pci_get_value(resource, offset): + with open(resource, 'r+b') as fd: + mm = mmap.mmap(fd.fileno(), 0) + val = pci_mem_read(mm, offset) + mm.close() + return val + +# Read I2C device + +def i2c_get(bus, i2caddr, ofs): + return int(subprocess.check_output(['/usr/sbin/i2cget', '-y', str(bus), str(i2caddr), str(ofs)]), 16) diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install index 303e978848db..74b8bc380199 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install @@ -6,6 +6,7 @@ s5232f/scripts/pcisysfs.py usr/bin s5232f/scripts/qsfp_irq_enable.py usr/bin s5232f/cfg/s5232f-modules.conf etc/modules-load.d s5232f/systemd/platform-modules-s5232f.service etc/systemd/system +s5232f/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index 3f0f79979886..17627fd4d44e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -35,6 +35,11 @@ override_dh_auto_build: cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ + elif [ $$mod = "s5232f" ]; then \ + cp $(COMMON_DIR)/ipmihelper.py $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + cd $(MOD_SRC_DIR); \ fi; \ echo "making man page alias $$mod -> $$mod APIs";\ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ @@ -82,6 +87,11 @@ override_dh_clean: rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ rm -rf $(MOD_SRC_DIR)/$${mod}/build; \ rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ + elif [ $$mod = "s5232f" ]; then \ + rm -f $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ + rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/build; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ fi; \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ done); \ diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh index 6f5119044039..7079da825adc 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh @@ -155,6 +155,21 @@ platform_firmware_versions() { r_maj=`/usr/sbin/i2cget -y 600 0x33 0x1 | sed ' s/.*\(0x..\)$/\1/'` echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE } + +install_python_api_package() { + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + + rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) +} + +remove_python_api_package() { + rv=$(pip show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi +} + init_devnum if [ "$1" == "init" ]; then @@ -170,6 +185,7 @@ if [ "$1" == "init" ]; then switch_board_sfp "new_device" switch_board_modsel switch_board_led_default + install_python_api_package python /usr/bin/qsfp_irq_enable.py platform_firmware_versions @@ -178,9 +194,9 @@ elif [ "$1" == "deinit" ]; then switch_board_qsfp "delete_device" switch_board_sfp "delete_device" switch_board_qsfp_mux "delete_device" - switch_board_sfp "delete_device" modprobe -r i2c-mux-pca954x modprobe -r i2c-dev + remove_python_api_package else echo "s5232f_platform : Invalid option !" fi diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/setup.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/setup.py new file mode 120000 index 000000000000..4f6de9941d96 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/setup.py @@ -0,0 +1 @@ +../s6100/setup.py \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py @@ -0,0 +1 @@ + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py new file mode 100644 index 000000000000..6acd54d3934b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import sys + from __future__ import division + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Eeprom + from sonic_platform.component import Component + from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal + from sonic_platform.watchdog import Watchdog + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +MAX_S5232F_COMPONENT = 6 # BIOS,BMC,FPGA,SYSTEM CPLD,4 SLAVE CPLDs +MAX_S5232F_FANTRAY =4 +MAX_S5232F_FAN = 2 +MAX_S5232F_PSU = 2 +MAX_S5232F_THERMAL = 8 + + +class Chassis(ChassisBase): + """ + DELLEMC Platform-specific Chassis class + """ + + oir_fd = -1 + epoll = -1 + + _global_port_pres_dict = {} + + def __init__(self): + ChassisBase.__init__(self) + # sfp.py will read eeprom contents and retrive the eeprom data. + # We pass the eeprom path from chassis.py + self.PORT_START = 1 + self.PORT_END = 34 + self.PORTS_IN_BLOCK = (self.PORT_END + 1) + _sfp_port = range(33, self.PORT_END + 1) + eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for index in range(self.PORT_START, self.PORTS_IN_BLOCK): + port_num = index + 1 + eeprom_path = eeprom_base.format(port_num) + if index not in _sfp_port: + sfp_node = Sfp(index, 'QSFP', eeprom_path) + else: + sfp_node = Sfp(index, 'SFP', eeprom_path) + self._sfp_list.append(sfp_node) + + self._eeprom = Eeprom() + self._watchdog = Watchdog() + self._num_sfps = self.PORT_END + self._num_fans = MAX_S5232F_FANTRAY * MAX_S5232F_FAN + self._fan_list = [Fan(i, j) for i in range(MAX_S5232F_FANTRAY) \ + for j in range(MAX_S5232F_FAN)] + self._psu_list = [Psu(i) for i in range(MAX_S5232F_PSU)] + self._thermal_list = [Thermal(i) for i in range(MAX_S5232F_THERMAL)] + self._component_list = [Component(i) for i in range(MAX_S5232F_COMPONENT)] + + for port_num in range(self.PORT_START, self.PORTS_IN_BLOCK): + # sfp get uses zero-indexing, but port numbers start from 1 + presence = self.get_sfp(port_num).get_presence() + self._global_port_pres_dict[port_num] = '1' if presence else '0' + + def __del__(self): + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + +# check for this event change for sfp / do we need to handle timeout/sleep + + def get_change_event(self, timeout=0): + from time import sleep + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + """ + port_dict = {} + change_dict = {} + change_dict['sfp'] = port_dict + elapsed_time_ms = 0 + sleep_time_ms = 500 + sleep_time = sleep_time_ms / 1000 + + while True: + for port_num in range(self.PORT_START, (self.PORT_END + 1)): + presence = self.get_sfp(port_num).get_presence() + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, change_dict + if timeout != 0: + elapsed_time_ms += sleep_time_ms + if elapsed_time_ms > timeout: + break + + time.sleep(sleep_time) + return True, change_dict + + def get_sfp(self, index): + """ + Retrieves sfp represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 0. + For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + # The index will start from 0 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (0-{})\n".format( + index, len(self._sfp_list)-1)) + return sfp + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr('') + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.system_eeprom_info() + + def get_eeprom(self): + """ + Retrieves the Sys Eeprom instance for the chassis. + Returns : + The instance of the Sys Eeprom + """ + return self._eeprom + + def get_num_fans(self): + """ + Retrives the number of Fans on the chassis. + Returns : + An integer represents the number of Fans on the chassis. + """ + return self._num_fans + + def get_num_sfps(self): + """ + Retrives the numnber of Media on the chassis. + Returns: + An integer represences the number of SFPs on the chassis. + """ + return self._num_sfps diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py new file mode 100644 index 000000000000..bf33bd043d83 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python + +######################################################################## +# DELLEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, BMC etc.) available in +# the platform +# +######################################################################## + +try: + import subprocess + from sonic_platform_base.component_base import ComponentBase + import sonic_platform.hwaccess as hwaccess + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +def get_bios_version(): + return subprocess.check_output(['dmidecode', '-s', 'system-version']).strip() + +def get_fpga_version(): + val = hwaccess.pci_get_value('/sys/bus/pci/devices/0000:04:00.0/resource0', 0) + return '{}.{}'.format((val >> 8) & 0xff, val & 0xff) + +def get_bmc_version(): + return subprocess.check_output( + ['cat', '/sys/class/ipmi/ipmi0/device/bmc/firmware_revision'] + ).strip() + +def get_cpld_version(bus, i2caddr): + return '{}.{}'.format(hwaccess.i2c_get(bus, i2caddr, 1), + hwaccess.i2c_get(bus, i2caddr, 0) + ) + +def get_cpld0_version(): + return get_cpld_version(601, 0x31) + +def get_cpld1_version(): + return get_cpld_version(600, 0x30) + +def get_cpld2_version(): + return get_cpld_version(600, 0x31) + + +class Component(ComponentBase): + """DellEMC Platform-specific Component class""" + + CHASSIS_COMPONENTS = [ + ['BIOS', + 'Performs initialization of hardware components during booting', + get_bios_version + ], + + ['FPGA', + 'Used for managing the system LEDs', + get_fpga_version + ], + + ['BMC', + 'Platform management controller for on-board temperature ', + 'monitoring, in-chassis power, Fan and LED control', + get_bmc_version + ], + + ['System CPLD', + 'Used for managing the CPU power sequence and CPU states', + get_cpld0_version + ], + + ['Slave CPLD 1', + 'Used for managing SFP28/QSFP28 port transceivers (SFP28 1-24, QSFP28 1-4)', + get_cpld1_version + ], + + ['Slave CPLD 2', + 'Used for managing SFP28/QSFP28 port transceivers (SFP28 25-48, QSFP28 5-8)', + get_cpld2_version + ], + + ] + + def __init__(self, component_index = 0): + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + self.version = self.CHASSIS_COMPONENTS[self.index][2]() + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + Returns: + A string containing the firmware version of the component + """ + return self.version + + def install_firmware(self, image_path): + """ + Installs firmware to the component + Args: + image_path: A string, path to firmware image + Returns: + A boolean, True if install was successful, False if not + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py new file mode 100644 index 000000000000..eb4a7978fdb3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python + +############################################################################# +# DellEmc S5248F +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# +try: + import os.path + from sonic_eeprom import eeprom_tlvinfo + import binascii +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self): + self.eeprom_path = None + for b in (0, 1): + f = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'.format(b) + if os.path.exists(f): + self.eeprom_path = f + break + if self.eeprom_path is None: + return + super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_tlv_dict = dict() + try: + self.eeprom_data = self.read_eeprom() + except: + self.eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + + eeprom = self.eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + ord(eeprom[tlv_index + 1])] + code = "0x%02X" % (ord(tlv[0])) + + if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | + (ord(tlv[4]) << 8) | ord(tlv[5])) + value += str(tlv[6:6 + ord(tlv[1])]) + else: + name, value = self.decoder(None, tlv) + + self.eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+1]) + 2 + + def serial_number_str(self): + """ + Returns the serial number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2] + + def base_mac_addr(self, e): + """ + Returns the base mac address found in the system EEPROM + """ + (is_valid, t) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(t) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + """ + Returns the Model name + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def part_number_str(self): + """ + Returns the part number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def serial_str(self): + """ + Returns the servicetag number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2] + + def revision_str(self): + """ + Returns the device revision + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2] + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.eeprom_tlv_dict + + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py new file mode 100644 index 000000000000..41acae72d88e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_base import FanBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +FAN1_MAX_SPEED_OFFSET = 71 +FAN2_MAX_SPEED_OFFSET = 73 +PSU_FAN_MAX_SPEED_OFFSET = 50 +FAN_DIRECTION_OFFSET = 69 +PSU_FAN_DIRECTION_OFFSET = 47 + + +class Fan(FanBase): + """DellEMC Platform-specific Fan class""" + # { FAN-ID: { Sensor-Name: Sensor-ID } } + FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x51, "State": 0x64, "Speed": 0x24}, + 2: {"Prsnt": 0x51, "State": 0x60, "Speed": 0x20}, + 3: {"Prsnt": 0x52, "State": 0x65, "Speed": 0x25}, + 4: {"Prsnt": 0x52, "State": 0x61, "Speed": 0x21}, + 5: {"Prsnt": 0x53, "State": 0x66, "Speed": 0x26}, + 6: {"Prsnt": 0x53, "State": 0x62, "Speed": 0x22}, + 7: {"Prsnt": 0x54, "State": 0x67, "Speed": 0x27}, + 8: {"Prsnt": 0x54, "State": 0x63, "Speed": 0x23} } + PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x46, "Speed": 0x2e}, + 2: {"State": 0x47, "Speed": 0x2f} } + + # { FANTRAY-ID: FRU-ID } + FAN_FRU_MAPPING = { 1: 3, 2: 4, 3: 5, 4: 6 } + PSU_FRU_MAPPING = { 1: 1, 2: 2 } + + def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, + dependency=None): + self.is_psu_fan = psu_fan + if not self.is_psu_fan: + # API index is starting from 0, DellEMC platform index is + # starting from 1 + self.fantrayindex = fantray_index + 1 + self.fanindex = fan_index + 1 + if (self.fanindex == 1): + self.max_speed_offset = FAN1_MAX_SPEED_OFFSET + else: + self.max_speed_offset = FAN2_MAX_SPEED_OFFSET + self.fan_direction_offset = FAN_DIRECTION_OFFSET + self.index = (self.fantrayindex - 1) * 2 + self.fanindex + self.prsnt_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], + is_discrete=True) + self.state_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["State"], + is_discrete=True) + self.speed_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Speed"]) + self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) + else: + self.dependency = dependency + self.fanindex = fan_index + self.state_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], + is_discrete=True) + self.speed_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) + self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) + self.max_speed_offset = PSU_FAN_MAX_SPEED_OFFSET + self.fan_direction_offset = PSU_FAN_DIRECTION_OFFSET + self.max_speed = self.fru.get_fru_data(self.max_speed_offset,2)[1] + self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] + + def get_name(self): + """ + Retrieves the name of the device + Returns: + String: The name of the device + """ + if self.is_psu_fan: + return "PSU{} Fan".format(self.fanindex) + else: + return "FanTray{}-Fan{}".format(self.fantrayindex, self.fanindex) + + def get_model(self): + """ + Retrieves the part number of the FAN + Returns: + String: Part number of FAN + """ + if self.is_psu_fan: + return 'NA' + else: + return self.fru.get_board_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the FAN + Returns: + String: Serial number of FAN + """ + if self.is_psu_fan: + return 'NA' + else: + return self.fru.get_board_serial() + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if fan is present, False if not + """ + presence = False + if self.is_psu_fan: + return self.dependency.get_presence() + else: + is_valid, state = self.prsnt_sensor.get_reading() + if is_valid: + if (state & 0b1): + presence = True + return presence + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state == 0x00): + status = True + return status + + def get_direction(self): + """ + Retrieves the fan airfow direction + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. + """ + direction = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE] + fan_status = self.get_status() + if not fan_status: + return 'NA' + is_valid, fan_direction = self.fru.get_fru_data(self.fan_direction_offset) + if is_valid: + return direction[fan_direction[0]] + else: + return 'NA' + + def get_speed(self): + """ + Retrieves the speed of the fan + Returns: + int: percentage of the max fan speed + """ + if self.max_speed == 0: + self.max_speed = self.fru.get_fru_data(self.max_speed_offset,2)[1] + self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] + is_valid, fan_speed = self.speed_sensor.get_reading() + if not is_valid or self.max_speed == 0: + speed = 0 + else: + speed = (100 * fan_speed)/self.max_speed + return speed + + def get_speed_rpm(self): + """ + Retrieves the speed of the fan + Returns: + int: percentage of the max fan speed + """ + fan_speed = 0 + is_valid, fan_speed = self.speed_sensor.get_reading() + return fan_speed diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/hwaccess.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/hwaccess.py new file mode 120000 index 000000000000..e8fa340a444d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/hwaccess.py @@ -0,0 +1 @@ +../../common/sonic_platform/hwaccess.py \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/platform.py new file mode 100644 index 000000000000..996d94cf5a6e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/platform.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """ + DELLEMC Platform-specific class + """ + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/psu.py new file mode 100644 index 000000000000..e7f05a0a17b6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/psu.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + + +try: + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Psu(PsuBase): + """DellEMC Platform-specific PSU class""" + + # { PSU-ID: { Sensor-Name: Sensor-ID } } + SENSOR_MAPPING = { 1: { "State": 0x31, "Current": 0x39, + "Power": 0x37, "Voltage": 0x38 }, + 2: { "State": 0x32, "Current": 0x3F, + "Power": 0x3D, "Voltage": 0x3E } } + # ( PSU-ID: FRU-ID } + FRU_MAPPING = { 1: 1, 2: 2 } + + def __init__(self, psu_index): + PsuBase.__init__(self) + # PSU is 1-based in DellEMC platforms + self.index = psu_index + 1 + self.state_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["State"], + is_discrete=True) + self.voltage_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Voltage"]) + self.current_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Current"]) + self.power_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Power"]) + self.fru = IpmiFru(self.FRU_MAPPING[self.index]) + + self._fan_list.append(Fan(fan_index=self.index, psu_fan=True, + dependency=self)) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Power Supply Unit (PSU) + + Returns: + bool: True if PSU is present, False if not + """ + presence = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state & 0b1): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + return self.fru.get_board_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + return self.fru.get_board_serial() + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state == 0x01): + status = True + + return status + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + is_valid, voltage = self.voltage_sensor.get_reading() + if not is_valid: + voltage = 0 + + return "{:.1f}".format(voltage) + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + is_valid, current = self.current_sensor.get_reading() + if not is_valid: + current = 0 + + return "{:.1f}".format(current) + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + is_valid, power = self.power_sensor.get_reading() + if not is_valid: + power = 0 + + return "{:.1f}".format(power) + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and + passed all its internal self-tests, False if not. + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state == 0x01): + status = True + + return status + + def get_mfr_id(self): + """ + Retrives the Manufacturer Id of PSU + + Returns: + A string, the manunfacturer id. + """ + return self.fru.get_board_mfr_id() + + def get_type(self): + """ + Retrives the Power Type of PSU + + Returns : + A string, PSU power type + """ + info = self.fru.get_board_product().split(',') + if 'AC' in info : return 'AC' + if 'DC' in info : return 'DC' + return 'Unknown' diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/sfp.py new file mode 100644 index 000000000000..adb61113d41e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/sfp.py @@ -0,0 +1,1045 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import os + import time + import struct + import mmap + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PAGE_OFFSET = 0 +KEY_OFFSET = 1 +KEY_WIDTH = 2 +FUNC_NAME = 3 + +QSFP_INFO_OFFSET = 128 +QSFP_DOM_OFFSET = 0 +QSFP_DOM_OFFSET1 = 384 + +SFP_INFO_OFFSET = 0 +SFP_DOM_OFFSET = 256 + +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 7 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', + 'Length OM1(m)', 'Length Cable Assembly(m)') + +qsfp_compliance_code_tup = ( + '10/40G Ethernet Compliance Code', + 'SONET Compliance codes', + 'SAS/SATA compliance codes', + 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', + 'Fibre Channel Speed') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthOM3(UnitsOf10m)', 'LengthCable(UnitsOfm)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +info_dict_keys = ['type', 'hardwarerev', 'serialnum', + 'manufacturename', 'modelname', 'Connector', + 'encoding', 'ext_identifier', 'ext_rateselect_compliance', + 'cable_type', 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'type_abbrv_name','vendor_date', 'vendor_oui'] + +dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', + 'power_lpmode', 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power'] + +threshold_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning'] + +sff8436_parser = { + 'reset_status': [QSFP_DOM_OFFSET, 2, 1, 'parse_dom_status_indicator'], + 'rx_los': [QSFP_DOM_OFFSET, 3, 1, 'parse_dom_tx_rx_los'], + 'tx_fault': [QSFP_DOM_OFFSET, 4, 1, 'parse_dom_tx_fault'], + 'tx_disable': [QSFP_DOM_OFFSET, 86, 1, 'parse_dom_tx_disable'], + 'power_lpmode': [QSFP_DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'power_override': [QSFP_DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'Temperature': [QSFP_DOM_OFFSET, 22, 2, 'parse_temperature'], + 'Voltage': [QSFP_DOM_OFFSET, 26, 2, 'parse_voltage'], + 'ChannelMonitor': [QSFP_DOM_OFFSET, 34, 16, 'parse_channel_monitor_params'], + 'ChannelMonitor_TxPower': + [QSFP_DOM_OFFSET, 34, 24, 'parse_channel_monitor_params_with_tx_power'], + + 'cable_type': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'cable_length': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'Connector': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'encoding': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_identifier': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_rateselect_compliance': + [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'nominal_bit_rate': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'specification_compliance': + [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type_abbrv_name': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'manufacturename': [QSFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'vendor_oui': [QSFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], + 'modelname': [QSFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardwarerev': [QSFP_INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serialnum': [QSFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'vendor_date': [QSFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], + 'dom_capability': [QSFP_INFO_OFFSET, 92, 1, 'parse_qsfp_dom_capability'], + 'dom_rev': [QSFP_DOM_OFFSET, 1, 1, 'parse_sfp_dom_rev'], + 'ModuleThreshold': [QSFP_DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], + 'ChannelThreshold': [QSFP_DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], +} + +sff8472_parser = { + 'Temperature': [SFP_DOM_OFFSET, 96, 2, 'parse_temperature'], + 'Voltage': [SFP_DOM_OFFSET, 98, 2, 'parse_voltage'], + 'ChannelMonitor': [SFP_DOM_OFFSET, 100, 6, 'parse_channel_monitor_params'], + + 'cable_type': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'cable_length': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'Connector': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'type': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'encoding': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'ext_identifier': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'ext_rateselect_compliance': + [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'nominal_bit_rate': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'specification_compliance': + [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'type_abbrv_name': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'manufacturename': [SFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'vendor_oui': [SFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], + 'modelname': [SFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardwarerev': [SFP_INFO_OFFSET, 56, 4, 'parse_vendor_rev'], + 'serialnum': [SFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'vendor_date': [SFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], + 'ModuleThreshold': [SFP_DOM_OFFSET, 0, 56, 'parse_alarm_warning_threshold'], +} + + +class Sfp(SfpBase): + """ + DELLEMC Platform-specific Sfp class + """ + BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" + + def __init__(self, index=0, sfp_type=0, eeprom_path=''): + SfpBase.__init__(self) + self.sfp_type = sfp_type + self.index = index + self.eeprom_path = eeprom_path + self.qsfpInfo = sff8436InterfaceId() + self.qsfpDomInfo = sff8436Dom() + self.sfpInfo = sff8472InterfaceId() + self.sfpDomInfo = sff8472Dom(None,1) + + def pci_mem_read(self, mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + reg_val = struct.unpack('I', read_data_stream) + mem_val = str(reg_val)[1:-2] + # print "reg_val read:%x"%reg_val + return mem_val + + def pci_mem_write(self, mm, offset, data): + mm.seek(offset) + # print "data to write:%x"%data + mm.write(struct.pack('I', data)) + + def pci_set_value(self, resource, val, offset): + fd = os.open(resource, os.O_RDWR) + mm = mmap.mmap(fd, 0) + val = self.pci_mem_write(mm, offset, val) + mm.close() + os.close(fd) + return val + + def pci_get_value(self, resource, offset): + fd = os.open(resource, os.O_RDWR) + mm = mmap.mmap(fd, 0) + val = self.pci_mem_read(mm, offset) + mm.close() + os.close(fd) + return val + + def _read_eeprom_bytes(self, eeprom_path, offset, num_bytes): + eeprom_raw = [] + try: + eeprom = open(eeprom_path, mode="rb", buffering=0) + except IOError: + return None + + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + eeprom.seek(offset) + raw = eeprom.read(num_bytes) + except IOError: + eeprom.close() + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except BaseException: + eeprom.close() + return None + + eeprom.close() + return eeprom_raw + + def _get_eeprom_data(self, eeprom_key): + eeprom_data = None + page_offset = None + + if(self.sfp_type == 'QSFP'): + page_offset = sff8436_parser[eeprom_key][PAGE_OFFSET] + eeprom_data_raw = self._read_eeprom_bytes( + self.eeprom_path, + (sff8436_parser[eeprom_key][PAGE_OFFSET] + + sff8436_parser[eeprom_key][KEY_OFFSET]), + sff8436_parser[eeprom_key][KEY_WIDTH]) + if (eeprom_data_raw is not None): + # Offset 128 is used to retrieve sff8436InterfaceId Info + # Offset 0 is used to retrieve sff8436Dom Info + if (page_offset == 128): + if ( self.qsfpInfo is None): + return None + eeprom_data = getattr( + self.qsfpInfo, sff8436_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + if ( self.qsfpDomInfo is None): + return None + eeprom_data = getattr( + self.qsfpDomInfo, sff8436_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + page_offset = sff8472_parser[eeprom_key][PAGE_OFFSET] + eeprom_data_raw = self._read_eeprom_bytes( + self.eeprom_path, + (sff8472_parser[eeprom_key][PAGE_OFFSET] + + sff8472_parser[eeprom_key][KEY_OFFSET]), + sff8472_parser[eeprom_key][KEY_WIDTH]) + if (eeprom_data_raw is not None): + # Offset 0 is used to retrieve sff8472InterfaceId Info + # Offset 256 is used to retrieve sff8472Dom Info + if (page_offset == 0): + if ( self.sfpInfo is None): + return None + eeprom_data = getattr( + self.sfpInfo, sff8472_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + if ( self.sfpDomInfo is None): + return None + eeprom_data = getattr( + self.sfpDomInfo, sff8472_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + + return eeprom_data + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + """ + transceiver_info_dict = {} + compliance_code_dict = {} + transceiver_info_dict = dict.fromkeys(info_dict_keys, 'N/A') + # BaseInformation + iface_data = self._get_eeprom_data('type') + if (iface_data is not None): + connector = iface_data['data']['Connector']['value'] + encoding = iface_data['data']['EncodingCodes']['value'] + ext_id = iface_data['data']['Extended Identifier']['value'] + rate_identifier = iface_data['data']['RateIdentifier']['value'] + identifier = iface_data['data']['type']['value'] + type_abbrv_name=iface_data['data']['type_abbrv_name']['value'] + if(self.sfp_type == 'QSFP'): + bit_rate = str( + iface_data['data']['Nominal Bit Rate(100Mbs)']['value']) + for key in qsfp_compliance_code_tup: + if key in iface_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value'] + for key in qsfp_cable_length_tup: + if key in iface_data['data']: + cable_type = key + cable_length = str(iface_data['data'][key]['value']) + else: + bit_rate = str( + iface_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + for key in sfp_compliance_code_tup: + if key in iface_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value'] + for key in sfp_cable_length_tup: + if key in iface_data['data']: + cable_type = key + cable_length = str(iface_data['data'][key]['value']) + else: + return transceiver_info_dict + + # Vendor Date + vendor_date_data = self._get_eeprom_data('vendor_date') + if (vendor_date_data is not None): + vendor_date = vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + else: + return transceiver_info_dict + + # Vendor Name + vendor_name_data = self._get_eeprom_data('manufacturename') + if (vendor_name_data is not None): + vendor_name = vendor_name_data['data']['Vendor Name']['value'] + else: + return transceiver_info_dict + + # Vendor OUI + vendor_oui_data = self._get_eeprom_data('vendor_oui') + if (vendor_oui_data is not None): + vendor_oui = vendor_oui_data['data']['Vendor OUI']['value'] + else: + return transceiver_info_dict + + # Vendor PN + vendor_pn_data = self._get_eeprom_data('modelname') + if (vendor_pn_data is not None): + vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] + else: + return transceiver_info_dict + + # Vendor Revision + vendor_rev_data = self._get_eeprom_data('hardwarerev') + if (vendor_rev_data is not None): + vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] + else: + return transceiver_info_dict + + # Vendor Serial Number + vendor_sn_data = self._get_eeprom_data('serialnum') + if (vendor_sn_data is not None): + vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] + else: + return transceiver_info_dict + + # Fill The Dictionary and return + transceiver_info_dict['type'] = identifier + transceiver_info_dict['hardwarerev'] = vendor_rev + transceiver_info_dict['serialnum'] = vendor_sn + transceiver_info_dict['manufacturename'] = vendor_name + transceiver_info_dict['modelname'] = vendor_pn + transceiver_info_dict['Connector'] = connector + transceiver_info_dict['encoding'] = encoding + transceiver_info_dict['ext_identifier'] = ext_id + transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier + transceiver_info_dict['cable_type'] = cable_type + transceiver_info_dict['cable_length'] = cable_length + transceiver_info_dict['nominal_bit_rate'] = bit_rate + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + transceiver_info_dict['vendor_date'] = vendor_date + transceiver_info_dict['vendor_oui'] = vendor_oui + transceiver_info_dict['type_abbrv_name']=type_abbrv_name + + return transceiver_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + """ + transceiver_dom_threshold_dict = {} + transceiver_dom_threshold_dict = dict.fromkeys( + threshold_dict_keys, 'N/A') + + # Module Threshold + module_threshold_data = self._get_eeprom_data('ModuleThreshold') + if (self.sfp_type == 'QSFP'): + # Channel Threshold + channel_threshold_data = self._get_eeprom_data('ChannelThreshold') + + if (channel_threshold_data is not None and module_threshold_data is not None): + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + return transceiver_dom_threshold_dict + else: + #SFP + if (module_threshold_data is not None): + #Threshold Data + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_dict['txbiashighalarm'] = module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['txpowerlowalarm'] = module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['txpowerhighwarning'] = module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_dict['txpowerlowwarning'] = module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_dict['rxpowerhighalarm'] = module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = module_threshold_data['data']['RXPowerLowWarning']['value'] + else: + return transceiver_dom_threshold_dict + + return transceiver_dom_threshold_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + """ + tx_bias_list = [] + rx_power_list = [] + transceiver_dom_dict = {} + transceiver_dom_dict = dict.fromkeys(dom_dict_keys, 'N/A') + + # RxLos + rx_los = self.get_rx_los() + + # TxFault + tx_fault = self.get_tx_fault() + + # ResetStatus + reset_state = self.get_reset_status() + + # LowPower Mode + lp_mode = self.get_lpmode() + + # TxDisable + tx_disable = self.get_tx_disable() + + # TxDisable Channel + tx_disable_channel = self.get_tx_disable_channel() + + # Temperature + temperature = self.get_temperature() + + # Voltage + voltage = self.get_voltage() + + # Channel Monitor + tx_power_list = self.get_tx_power() + + # tx bias + tx_bias_list = self.get_tx_bias() + + # rx power + rx_power_list = self.get_rx_power() + + if (len(tx_bias_list) != 0): + transceiver_dom_dict['tx1bias'] = tx_bias_list[0] + transceiver_dom_dict['tx2bias'] = tx_bias_list[1] + transceiver_dom_dict['tx3bias'] = tx_bias_list[2] + transceiver_dom_dict['tx4bias'] = tx_bias_list[3] + + if (len(rx_power_list) != 0): + transceiver_dom_dict['rx1power'] = rx_power_list[0] + transceiver_dom_dict['rx2power'] = rx_power_list[1] + transceiver_dom_dict['rx3power'] = rx_power_list[2] + transceiver_dom_dict['rx4power'] = rx_power_list[3] + + if (len(tx_power_list) != 0): + transceiver_dom_dict['tx1power'] = tx_power_list[0] + transceiver_dom_dict['tx2power'] = tx_power_list[1] + transceiver_dom_dict['tx3power'] = tx_power_list[2] + transceiver_dom_dict['tx4power'] = tx_power_list[3] + + transceiver_dom_dict['rx_los'] = rx_los + transceiver_dom_dict['tx_fault'] = tx_fault + transceiver_dom_dict['reset_status'] = reset_state + transceiver_dom_dict['power_lpmode'] = lp_mode + transceiver_dom_dict['tx_disable'] = tx_disable + transceiver_dom_dict['tx_disable_channel'] = tx_disable_channel + transceiver_dom_dict['temperature'] = temperature + transceiver_dom_dict['voltage'] = voltage + + return transceiver_dom_dict + + def get_name(self): + """ + Retrieves the name of the sfp + Returns : QSFP or QSFP+ or QSFP28 + """ + + iface_data = self._get_eeprom_data('type') + if (iface_data is not None): + identifier = iface_data['data']['type']['value'] + else: + return None + + return identifier + + def get_presence(self): + """ + Retrieves the presence of the sfp + Returns : True if sfp is present and false if it is absent + """ + # Check for invalid port_num + + # Port offset starts with 0x4004 + port_offset = 16388 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + if(self.sfp_type == 'QSFP'): + mask = (1 << 4) + + # Mask off 1st bit for presence 65,66 + if (self.sfp_type == 'SFP'): + mask = (1 << 0) + # ModPrsL is active low + if reg_value & mask == 0: + return True + + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the sfp + """ + vendor_pn_data = self._get_eeprom_data('modelname') + if (vendor_pn_data is not None): + vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] + else: + return None + + return vendor_pn + + def get_serial(self): + """ + Retrieves the serial number of the sfp + """ + vendor_sn_data = self._get_eeprom_data('serialnum') + if (vendor_sn_data is not None): + vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] + else: + return None + + return vendor_sn + + def get_reset_status(self): + """ + Retrives the reset status of SFP + """ + reset_status = False + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return reset_status + + # Mask off 4th bit for reset status + mask = (1 << 4) + + if ((reg_value & mask) == 0): + reset_status = True + else: + reset_status = False + + return reset_status + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + """ + rx_los = None + rx_los_list = [] + if (self.sfp_type == 'QSFP'): + rx_los_data = self._get_eeprom_data('rx_los') + if (rx_los_data is not None): + rx_los = rx_los_data['data']['Rx1LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + rx_los = rx_los_data['data']['Rx2LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + rx_los = rx_los_data['data']['Rx3LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + rx_los = rx_los_data['data']['Rx4LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + + if (rx_los_list[0] and rx_los_list[1] + and rx_los_list[2] and rx_los_list[3]): + rx_los = True + else: + rx_los = False + else: + rx_los_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if (rx_los_data is not None): + data = int(rx_los_data[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + """ + tx_fault = None + tx_fault_list = [] + if (self.sfp_type == 'QSFP'): + tx_fault_data = self._get_eeprom_data('tx_fault') + if (tx_fault_data is not None): + tx_fault = tx_fault_data['data']['Tx1Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + tx_fault = tx_fault_data['data']['Tx2Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + tx_fault = tx_fault_data['data']['Tx3Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + tx_fault = tx_fault_data['data']['Tx4Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + + if (tx_fault_list[0] and tx_fault_list[1] + and tx_fault_list[2] and tx_fault_list[3]): + tx_fault = True + else: + tx_fault = False + + else: + tx_fault_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if (tx_fault_data is not None): + data = int(tx_fault_data[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + """ + tx_disable = None + tx_disable_list = [] + if (self.sfp_type == 'QSFP'): + tx_disable_data = self._get_eeprom_data('tx_disable') + if (tx_disable_data is not None): + tx_disable = tx_disable_data['data']['Tx1Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + tx_disable = tx_disable_data['data']['Tx2Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + tx_disable = tx_disable_data['data']['Tx3Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + tx_disable = tx_disable_data['data']['Tx4Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + + if (tx_disable_list[0] and tx_disable_list[1] + and tx_disable_list[2] and tx_disable_list[3]): + tx_disable = True + else: + tx_disable = False + + else: + tx_disable_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if (tx_disable_data is not None): + data = int(tx_disable_data[0], 16) + tx_disable_hard = (sffbase().test_bit(data, SFP_TX_DISABLE_HARD_BIT) != 0) + tx_disable_soft = (sffbase().test_bit(data, SFP_TX_DISABLE_SOFT_BIT) != 0) + tx_disable = tx_disable_hard | tx_disable_soft + + + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + """ + tx_disable = None + tx_disable_list = [] + tx_disable_channel = 0 + + if (self.sfp_type == 'QSFP'): + tx_disable_data = self._get_eeprom_data('tx_disable') + if (tx_disable_data is not None): + tx_disable = tx_disable_data['data']['Tx1Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + tx_disable = tx_disable_data['data']['Tx2Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + tx_disable = tx_disable_data['data']['Tx3Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + tx_disable = tx_disable_data['data']['Tx4Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + + bit4 = int(tx_disable_list[3]) * 8 + bit3 = int(tx_disable_list[2]) * 4 + bit2 = int(tx_disable_list[1]) * 2 + bit1 = int(tx_disable_list[0]) * 1 + + tx_disable_channel = hex(bit4 + bit3 + bit2 + bit1) + + return tx_disable_channel + + def get_lpmode(self): + """ + Retrieves the lpmode(low power mode) of this SFP + """ + lpmode_state = False + if (self.sfp_type == 'QSFP'): + + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return lpmode_state + + # Mask off 6th bit for lpmode + mask = (1 << 6) + + # LPMode is active high + if reg_value & mask == 0: + lpmode_state = False + else: + lpmode_state = True + + return lpmode_state + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + """ + power_override_state = False + + if (self.sfp_type == 'QSFP'): + power_override_data = self._get_eeprom_data('power_override') + if (power_override_data is not None): + power_override = power_override_data['data']['PowerOverRide']['value'] + if (power_override is 'On'): + power_override_state = True + else: + power_override_state = False + + return power_override_state + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + """ + temperature = None + + temperature_data = self._get_eeprom_data('Temperature') + if (temperature_data is not None): + temperature = temperature_data['data']['Temperature']['value'] + + return temperature + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + """ + voltage = None + + voltage_data = self._get_eeprom_data('Voltage') + if (voltage_data is not None): + voltage = voltage_data['data']['Vcc']['value'] + + return voltage + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + """ + tx_bias = None + tx_bias_list = [] + + tx_bias_data = self._get_eeprom_data('ChannelMonitor') + if (tx_bias_data is not None): + if (self.sfp_type == 'QSFP'): + tx_bias = tx_bias_data['data']['TX1Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = tx_bias_data['data']['TX2Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = tx_bias_data['data']['TX3Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = tx_bias_data['data']['TX4Bias']['value'] + tx_bias_list.append(tx_bias) + else: + tx1_bias = tx_bias_data['data']['TXBias']['value'] + return [tx1_bias, "N/A", "N/A", "N/A"] + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + """ + rx_power = None + rx_power_list = [] + + rx_power_data = self._get_eeprom_data('ChannelMonitor') + if (rx_power_data is not None): + if (self.sfp_type == 'QSFP'): + rx_power = rx_power_data['data']['RX1Power']['value'] + rx_power_list.append(rx_power) + rx_power = rx_power_data['data']['RX2Power']['value'] + rx_power_list.append(rx_power) + rx_power = rx_power_data['data']['RX3Power']['value'] + rx_power_list.append(rx_power) + rx_power = rx_power_data['data']['RX4Power']['value'] + rx_power_list.append(rx_power) + else: + rx1_pw = rx_power_data['data']['RXPower']['value'] + return [rx1_pw, "N/A", "N/A", "N/A"] + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + """ + tx_power_list = [] + if(self.sfp_type == 'QSFP'): + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qspf_dom_capability_data = self._get_eeprom_data('dom_capability') + qsfp_dom_rev_data = self._get_eeprom_data('dom_rev') + if (qspf_dom_capability_data is not None and qsfp_dom_rev_data is not None): + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + else: + return tx_power_list + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + return tx_power_list + else: + channel_monitor_data = self._get_eeprom_data('ChannelMonitor_TxPower') + if (channel_monitor_data is not None): + tx1_pw = channel_monitor_data['data']['TX1Power']['value'] + tx2_pw = channel_monitor_data['data']['TX2Power']['value'] + tx3_pw = channel_monitor_data['data']['TX3Power']['value'] + tx4_pw = channel_monitor_data['data']['TX4Power']['value'] + else: + return tx_power_list + + else: + channel_monitor_data = self._get_eeprom_data('ChannelMonitor') + if (channel_monitor_data is not None): + tx1_pw = channel_monitor_data['data']['TXPower']['value'] + tx2_pw = 'N/A' + tx3_pw = 'N/A' + tx4_pw = 'N/A' + else: + return tx_power_list + + tx_power_list.append(tx1_pw) + tx_power_list.append(tx2_pw) + tx_power_list.append(tx3_pw) + tx_power_list.append(tx4_pw) + + return tx_power_list + + def reset(self): + """ + Reset the SFP and returns all user settings to their default state + """ + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for reset + mask = (1 << 4) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + # Sleep 1 second to allow it to settle + time.sleep(1) + + reg_value = reg_value | mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + else: + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode(low power mode) of this SFP + """ + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 6th bit for lowpower mode + mask = (1 << 6) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + else: + return False + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + """ + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + """ + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + """ + return False + + def get_status(self): + """ + Retrieves the operational status of the device + """ + reset = self.get_reset_status() + + if (reset == True): + status = False + else: + status = True + + return status diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py new file mode 100644 index 000000000000..cc7867917345 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + from sonic_platform_base.thermal_base import ThermalBase + from sonic_platform.ipmihelper import IpmiSensor +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """DellEMC Platform-specific Thermal class""" + + # [ Sensor-Name, Sensor-ID ] + SENSOR_MAPPING = [ + ['CPU On-board', 0xe], + ['ASIC On-board', 0x2], + ['System Front Left', 0x3], + ['System Front Middle', 0x1], + ['System Front Right', 0x4], + ['Inlet Airflow Sensor', 0x5], + ['PSU1 Airflow Sensor', 0x7], + ['PSU2 Airflow Sensor', 0x8] + ] + + def __init__(self, thermal_index=0): + ThermalBase.__init__(self) + self.index = thermal_index + 1 + self.sensor = IpmiSensor(self.SENSOR_MAPPING[self.index - 1][1]) + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + return self.SENSOR_MAPPING[self.index - 1][0] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + Returns: + bool: True if thermal is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the Thermal + + Returns: + string: Model/part number of Thermal + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the Thermal + + Returns: + string: Serial number of Thermal + """ + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the thermal + + Returns: + A boolean value, True if thermal is operating properly, + False if not + """ + return True + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + is_valid, temperature = self.sensor.get_reading() + if not is_valid: + temperature = 0 + + return "{:.3f}".format(temperature) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + is_valid, high_threshold = self.sensor.get_threshold("UpperNonRecoverable") + if not is_valid: + high_threshold = 0 + + return "{:.3f}".format(high_threshold) + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + is_valid, low_threshold = self.sensor.get_threshold("LowerNonRecoverable") + if not is_valid: + low_threshold = 0 + + return "{:.3f}".format(low_threshold) + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/watchdog.py new file mode 100644 index 000000000000..878d5f4f952d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/watchdog.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python + +######################################################################## +# +# DELLEMC S5232f +# +# Abstract base class for implementing a platform-specific class with +# which to interact with a hardware watchdog module in SONiC +# +######################################################################## + +try: + import ctypes + import subprocess + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class _timespec(ctypes.Structure): + _fields_ = [ + ('tv_sec', ctypes.c_long), + ('tv_nsec', ctypes.c_long) + ] + + +class Watchdog(WatchdogBase): + """ + Abstract base class for interfacing with a hardware watchdog module + """ + + TIMERS = [15,20,30,40,50,60,65,70] + + armed_time = 0 + timeout = 0 + CLOCK_MONOTONIC = 1 + + def __init__(self): + self._librt = ctypes.CDLL('librt.so.1', use_errno=True) + self._clock_gettime = self._librt.clock_gettime + self._clock_gettime.argtypes=[ctypes.c_int, ctypes.POINTER(_timespec)] + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_reg_val(self): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cget -y 601 0x31 0x07") + if not value: + return None + else: + return int(value, 16) + + def _set_reg_val(self,val): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cset -y 601 0x31 0x07 %s" + % (val)) + return value + + def _get_time(self): + """ + To get clock monotonic time + """ + ts = _timespec() + if self._clock_gettime(self.CLOCK_MONOTONIC, ctypes.pointer(ts)) != 0: + self._errno = ctypes.get_errno() + return 0 + return ts.tv_sec + ts.tv_nsec * 1e-9 + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* + available value. + + Returns: + An integer specifying the *actual* number of seconds the + watchdog was armed with. On failure returns -1. + """ + timer_offset = -1 + for key,timer_seconds in enumerate(self.TIMERS): + if seconds <= timer_seconds: + timer_offset = key + seconds = timer_seconds + break + + if timer_offset == -1: + return -1 + + # Extracting 5th to 7th bits for WD timer values + # 000 - 15 sec + # 001 - 20 sec + # 010 - 30 sec + # 011 - 40 sec + # 100 - 50 sec + # 101 - 60 sec + # 110 - 65 sec + # 111 - 70 sec + reg_val = self._get_reg_val() + wd_timer_offset = (reg_val >> 4) & 0x7 + + if wd_timer_offset != timer_offset: + # Setting 5th to 7th bits + # value from timer_offset + self.disarm() + self._set_reg_val(reg_val | (timer_offset << 4)) + + if self.is_armed(): + # Setting last bit to WD Timer punch + # Last bit = WD Timer punch + self._set_reg_val(reg_val & 0xFE) + + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + else: + # Setting 4th bit to enable WD + # 4th bit = Enable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val | 0x8) + + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + + def disarm(self): + """ + Disarm the hardware watchdog + + Returns: + A boolean, True if watchdog is disarmed successfully, False + if not + """ + if self.is_armed(): + # Setting 4th bit to disable WD + # 4th bit = Disable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val & 0xF7) + + self.armed_time = 0 + self.timeout = 0 + return True + + return False + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + + Returns: + A boolean, True if watchdog is armed, False if not + """ + + # Extracting 4th bit to get WD Enable/Disable status + # 0 - Disabled WD + # 1 - Enabled WD + reg_val = self._get_reg_val() + wd_offset = (reg_val >> 3) & 1 + + return bool(wd_offset) + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds + remaining on the watchdog timer + + Returns: + An integer specifying the number of seconds remaining on + their watchdog timer. If the watchdog is not armed, returns + -1. + + S5232 doesnot have hardware support to show remaining time. + Due to this limitation, this API is implemented in software. + This API would return correct software time difference if it + is called from the process which armed the watchdog timer. + If this API called from any other process, it would return + 0. If the watchdog is not armed, this API would return -1. + """ + if not self.is_armed(): + return -1 + + if self.armed_time > 0 and self.timeout != 0: + cur_time = self._get_time() + + if cur_time <= 0: + return 0 + + diff_time = int(cur_time - self.armed_time) + + if diff_time > self.timeout: + return self.timeout + else: + return self.timeout - diff_time + + return 0 + From 6d1545dc7919a3f69e93996a19d29a76bfbf909d Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 20 May 2020 14:53:08 -0700 Subject: [PATCH 0677/1427] [submodule update] sonic-utilities with PR (#4622) Changes to commands config reload/load-minigraph (#919) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index c52e26805d76..9bd3b9e83c72 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit c52e26805d76d0050e7cc80f25e91d6eae588ad9 +Subproject commit 9bd3b9e83c726b96145fe50df36f2b44abe2a560 From a44fc07e780436732700202bdb12de336fe50abd Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 20 May 2020 16:32:33 -0700 Subject: [PATCH 0678/1427] Changes to support config-setup service for multi-npu (#4609) * Changes to support config-setup service for multi-npu platforms. For Multi-npu we are not supporting as of now config initializtion and ZTP. It will support creating config db from minigraph or using config db from previous file system Signed-off-by: Abhishek Dosi * Address Review Comments. * Address Review comments * Address Review Comments of using pyhton based config load_minigraph/ config save/config reload from shell scripts so that we don't duplicate code. Also while running from shell we will skip stop/start services done by those commands. * Updated to use python command so no code duplication. --- files/image_config/config-setup/config-setup | 90 ++++++++++++++------ files/image_config/updategraph/updategraph | 22 +---- 2 files changed, 66 insertions(+), 46 deletions(-) diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index 0b385028a21f..1f95a10bb053 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -26,7 +26,11 @@ # Initialize constants UPDATEGRAPH_CONF=/etc/sonic/updategraph.conf +INIT_CFG_JSON=/etc/sonic/init_cfg.json CONFIG_DB_JSON=/etc/sonic/config_db.json +CONFIG_DB_PATH=/etc/sonic/ +CONFIG_DB_PREFIX=config_db +CONFIG_DB_SUFFIX=.json MINGRAPH_FILE=/etc/sonic/minigraph.xml TMP_ZTP_CONFIG_DB_JSON=/tmp/ztp_config_db.json FACTORY_DEFAULT_HOOKS=/etc/config-setup/factory-default-hooks.d @@ -103,24 +107,16 @@ run_hookdir() { reload_minigraph() { echo "Reloading minigraph..." - if [ ! -f /etc/sonic/init_cfg.json ]; then - echo "{}" > /etc/sonic/init_cfg.json - fi - sonic-db-cli CONFIG_DB FLUSHDB - sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" - if [ -f /etc/sonic/acl.json ]; then - acl-loader update full /etc/sonic/acl.json - fi - config qos reload - pfcwd start_default - - if [[ -x /usr/bin/db_migrator.py ]]; then - # Set latest version number - /usr/bin/db_migrator.py -o set_version - fi + config load_minigraph -y -n + config save -y } +# Reload exisitng config db file on disk +reload_configdb() +{ + echo "Reloading existing config db..." + config reload -y -n +} # Restore SONiC configuration from a backup copy function copy_config_files_and_directories() { @@ -281,15 +277,49 @@ copy_post_migration_hooks() fi } +# Get the list of config db for both +# single and multi-npu platforms +get_config_db_file_list() +{ + config_db_file_list=${CONFIG_DB_PREFIX}${CONFIG_DB_SUFFIX} + asic_num=0 + while [[ ($asic_num -lt $NUM_ASIC) && ($NUM_ASIC -gt 1) ]]; do + config_db_file_list+=' '${CONFIG_DB_PREFIX}$asic_num${CONFIG_DB_SUFFIX} + ((asic_num = asic_num + 1)) + done + + echo $config_db_file_list +} +# Check if all needed config db are prsesnt for both +# single and multi-npu platforms +check_all_config_db_present() +{ + if [[ ! -r ${CONFIG_DB_JSON} ]]; then + return 1 + fi + asic_num=0 + while [[ ($asic_num -lt $NUM_ASIC) && ($NUM_ASIC -gt 1) ]]; do + if [[ ! -r ${CONFIG_DB_PATH}${CONFIG_DB_PREFIX}$asic_num${CONFIG_DB_SUFFIX} ]]; then + return 1 + fi + ((asic_num = asic_num + 1)) + done + + return 0 +} + # Perform configuration migration from backup copy. # - This step is performed when a new image is installed and SONiC switch boots into it do_config_migration() { # Identify list of files to migrate - copy_list="minigraph.xml snmp.yml acl.json config_db.json frr" + copy_list="minigraph.xml snmp.yml acl.json frr" # Migrate all configuration files from old to new copy_config_files_and_directories $copy_list + + # Migrate all config_db from old to new + copy_config_files_and_directories $(get_config_db_file_list) # Migrate post-migration hooks copy_post_migration_hooks @@ -302,21 +332,14 @@ do_config_migration() disable_updategraph rm -f /tmp/pending_config_migration exit 0 - elif [ -r ${CONFIG_DB_JSON} ]; then + elif check_all_config_db_present; then echo "Use config_db.json from old system..." - sonic-cfggen -j ${CONFIG_DB_JSON} --write-to-db - - if [[ -x /usr/bin/db_migrator.py ]]; then - # Migrate the DB to the latest schema version if needed - /usr/bin/db_migrator.py -o migrate - fi + reload_configdb # Disable updategraph disable_updategraph elif [ -r ${MINGRAPH_FILE} ]; then echo "Use minigraph.xml from old system..." reload_minigraph - sonic-cfggen -d --print-data > ${CONFIG_DB_JSON} - # Disable updategraph disable_updategraph else @@ -351,6 +374,14 @@ boot_config() do_config_migration fi + # For multi-npu platfrom we don't support config initlaiztion. Assumption + # is there should be existing minigraph or config_db from previous image + # file system to trigger. pending_config_initialization will remain set + # for multi-npu platforms if we reach this case. + if [[ ($NUM_ASIC -gt 1) ]]; then + return 0 + fi + if [ -e /tmp/pending_config_initialization ] || [ -e ${CONFIG_SETUP_INITIALIZATION_FLAG} ]; then do_config_initialization fi @@ -373,6 +404,13 @@ boot_config() } ### Execution starts here ### +PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +if [[ -f "$ASIC_CONF" ]]; then + source $ASIC_CONF +fi + CMD=$1 # Default command is boot diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index a24d452b1ad2..86ee8a800ae1 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -3,25 +3,8 @@ reload_minigraph() { echo "Reloading minigraph..." - if [ ! -f /etc/sonic/init_cfg.json ]; then - echo "{}" > /etc/sonic/init_cfg.json - fi - sonic-db-cli CONFIG_DB FLUSHDB - sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" - if [ -f /etc/sonic/acl.json ]; then - acl-loader update full /etc/sonic/acl.json - fi - config qos reload - DEVICE_TYPE=`sonic-cfggen -m -v DEVICE_METADATA.localhost.type` - if [ "${DEVICE_TYPE}" != "MgmtToRRouter" ]; then - pfcwd start_default - fi - - if [[ -x /usr/bin/db_migrator.py ]]; then - # Set latest version number - /usr/bin/db_migrator.py -o set_version - fi + config load_minigraph -y -n + config save -y } if [ ! -f /etc/sonic/updategraph.conf ]; then @@ -141,7 +124,6 @@ else fi reload_minigraph -sonic-cfggen -d --print-data > /etc/sonic/config_db.json # Mark as disabled after graph is successfully downloaded sed -i "/enabled=/d" /etc/sonic/updategraph.conf From bce42a75959303619c7b7d91d7c9e2cd3475c83a Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 20 May 2020 17:45:07 -0700 Subject: [PATCH 0679/1427] [caclmgrd] Allow more ICMP types (#4625) --- files/image_config/caclmgrd/caclmgrd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index b2fc3c92a0c0..784218617c92 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -265,11 +265,15 @@ class ControlPlaneAclManager(object): # TODO: Support processing ICMPv4 service ACL rules, and remove this blanket acceptance iptables_cmds.append("iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT") iptables_cmds.append("iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT") + iptables_cmds.append("iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT") + iptables_cmds.append("iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT") # Add iptables/ip6tables commands to allow bidirectional ICMPv6 ping and traceroute # TODO: Support processing ICMPv6 service ACL rules, and remove this blanket acceptance iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT") iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-reply -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type time-exceeded -j ACCEPT") # Add iptables/ip6tables commands to allow all incoming Neighbor Discovery Protocol (NDP) NS/NA/RS/RA messages # TODO: Support processing NDP service ACL rules, and remove this blanket acceptance From eb97dccb884a688169e777ef0b8dc91a329d0666 Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Wed, 20 May 2020 18:10:05 -0700 Subject: [PATCH 0680/1427] [config]: Fix the device type and internal bgp session status for multi NPU platforms (#4600) * The following changes for multi-npu platforms are done - Set the type in device_metadata for asic configuration to be same as host - Set the admin-status of internal bgp sessions as up Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-config-engine/minigraph.py | 20 ++++++++++++++++++- .../tests/test_multinpu_cfggen.py | 12 +++++------ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 1f99bb16c8cd..3ead38080920 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -749,6 +749,21 @@ def filter_acl_table_bindings(acls, neighbors, port_channels, sub_role): return filter_acls +def enable_internal_bgp_session(bgp_sessions, filename, asic_name): + ''' + In Multi-NPU session the internal sessions will always be up. + So adding the admin-status 'up' configuration to bgp sessions + BGP session between FrontEnd and BackEnd Asics are internal bgp sessions + ''' + local_sub_role = parse_asic_sub_role(filename, asic_name) + + for peer_ip in bgp_sessions.keys(): + peer_name = bgp_sessions[peer_ip]['name'] + peer_sub_role = parse_asic_sub_role(filename, peer_name) + if ((local_sub_role == FRONTEND_ASIC_SUB_ROLE and peer_sub_role == BACKEND_ASIC_SUB_ROLE) or + (local_sub_role == BACKEND_ASIC_SUB_ROLE and peer_sub_role == FRONTEND_ASIC_SUB_ROLE)): + bgp_sessions[peer_ip].update({'admin_status': 'up'}) + ############################################################################### # # Main functions @@ -842,6 +857,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) + enable_internal_bgp_session(bgp_sessions, filename, asic_name) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): @@ -851,6 +867,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): elif child.tag == str(QName(ns, "DeviceInfos")): (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) + # set the host device type in asic metadata also + device_type = [devices[key]['type'] for key in devices if key.lower() == hostname.lower()][0] if asic_name is None: current_device = [devices[key] for key in devices if key.lower() == hostname.lower()][0] else: @@ -864,7 +882,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): 'docker_routing_config_mode': docker_routing_config_mode, 'hostname': hostname, 'hwsku': hwsku, - 'type': current_device['type'] + 'type': device_type } } # for this hostname, if sub_role is defined, add sub_role in diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 0ef29eb6d9b4..c3307b482b79 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -9,7 +9,7 @@ ASIC_SKU = 'multi-npu-asic' NUM_ASIC = 4 HOSTNAME = 'multi_npu_platform_01' - +DEVICE_TYPE = 'LeafRouter' class TestMultiNpuCfgGen(TestCase): @@ -197,16 +197,16 @@ def test_frontend_bgp_neighbor(self): output = json.loads(self.run_script(argument)) self.assertDictEqual(output, \ {'10.0.0.1': {'rrclient': 0, 'name': '01T2', 'local_addr': '10.0.0.0', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}, - '10.1.0.0': {'rrclient': 0, 'name': 'ASIC2', 'local_addr': '10.1.0.1', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}, + '10.1.0.0': {'rrclient': 0, 'name': 'ASIC2', 'local_addr': '10.1.0.1', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}, 'fc00::2': {'rrclient': 0, 'name': '01T2', 'local_addr': 'fc00::1', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}, - '10.1.0.2': {'rrclient': 0, 'name': 'ASIC3', 'local_addr': '10.1.0.3', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}}) + '10.1.0.2': {'rrclient': 0, 'name': 'ASIC3', 'local_addr': '10.1.0.3', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}}) def test_backend_asic_bgp_neighbor(self): argument = "-m {} -p {} -n asic3 --var-json \"BGP_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) output = json.loads(self.run_script(argument)) self.assertDictEqual(output, \ - {'10.1.0.7': {'rrclient': 0, 'name': 'ASIC1', 'local_addr': '10.1.0.6', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}, - '10.1.0.3': {'rrclient': 0, 'name': 'ASIC0', 'local_addr': '10.1.0.2', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}}) + {'10.1.0.7': {'rrclient': 0, 'name': 'ASIC1', 'local_addr': '10.1.0.6', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}, + '10.1.0.3': {'rrclient': 0, 'name': 'ASIC0', 'local_addr': '10.1.0.2', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}}) def test_device_asic_metadata(self): argument = "-m {} --var-json DEVICE_METADATA".format(self.sample_graph) @@ -215,7 +215,7 @@ def test_device_asic_metadata(self): asic_name = "asic{}".format(asic) self.assertEqual(output['localhost']['hostname'], 'multi_npu_platform_01') self.assertEqual(output['localhost']['asic_name'], asic_name) - self.assertEqual(output['localhost']['type'], 'Asic') + self.assertEqual(output['localhost']['type'], DEVICE_TYPE) if asic == 0 or asic == 1: self.assertEqual(output['localhost']['sub_role'], 'FrontEnd') else: From 984150a9a559c6f919162b9ab83849429ee205b6 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 21 May 2020 03:33:50 +0000 Subject: [PATCH 0681/1427] [sonic-slave-buster]: add xsltproc for mgmt-framework build Signed-off-by: Guohan Lu --- sonic-slave-buster/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index dcd0f9ea5450..cdf2476ca50b 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -377,6 +377,7 @@ RUN pip install pyang==2.1.1 # For mgmt-framework build RUN pip install mmh3 +RUN apt-get install -y xsltproc # Install dependencies for isc-dhcp-relay build RUN apt-get -y build-dep isc-dhcp From 34586032dc20662d1edd13d7e991cdedf0278295 Mon Sep 17 00:00:00 2001 From: anand-kumar-subramanian <51383315+anand-kumar-subramanian@users.noreply.github.com> Date: Wed, 20 May 2020 20:47:09 -0700 Subject: [PATCH 0682/1427] [mgmt-framework] removed requires dependency on swss (#4548) fixes #4473 --- files/build_templates/mgmt-framework.service.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/build_templates/mgmt-framework.service.j2 b/files/build_templates/mgmt-framework.service.j2 index acc938c13d90..bd4d28a2ee55 100644 --- a/files/build_templates/mgmt-framework.service.j2 +++ b/files/build_templates/mgmt-framework.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=Management Framework container -Requires=swss.service -After=swss.service syncd.service +Requires=database.service +After=database.service swss.service syncd.service Before=ntp-config.service [Service] From 4ba2f608c13e586ccddca68f6b3fa36cf69f4a78 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Wed, 20 May 2020 20:52:11 -0700 Subject: [PATCH 0683/1427] Adding new BGP peer groups PEER_V4_INT and PEER_V6_INT. (#4620) * Adding new BGP peer groups PEER_V4_INT and PEER_V6_INT. The internal BGP sessions will be added to this peer group while the external BGP sessions will be added to the exising PEER_V4 and PEER_V6 peer group. * Check for "ASIC" keyword in the hostname to identify the internal neighbors. --- .../frr/bgpd/templates/general/instance.conf.j2 | 8 ++++++++ .../frr/bgpd/templates/general/peer-group.conf.j2 | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 index 148cfa390e01..aed32d291c76 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 @@ -15,13 +15,21 @@ ! {% if neighbor_addr | ipv4 %} address-family ipv4 +{% if 'ASIC' in bgp_session['name'] %} + neighbor {{ neighbor_addr }} peer-group PEER_V4_INT +{% else %} neighbor {{ neighbor_addr }} peer-group PEER_V4 +{% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V4_INT in {% endif %} {% elif neighbor_addr | ipv6 %} address-family ipv6 +{% if 'ASIC' in bgp_session['name'] %} + neighbor {{ neighbor_addr }} peer-group PEER_V6_INT +{% else %} neighbor {{ neighbor_addr }} peer-group PEER_V6 +{% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V6_INT in {% endif %} diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 index 8c02eeacbdb4..b0acd1b2a460 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -2,28 +2,38 @@ ! template: bgpd/templates/general/peer-group.conf.j2 ! neighbor PEER_V4 peer-group + neighbor PEER_V4_INT peer-group neighbor PEER_V6 peer-group + neighbor PEER_V6_INT peer-group address-family ipv4 {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V4 allowas-in 1 + neighbor PEER_V4_INT allowas-in 1 {% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} - neighbor PEER_V4 route-reflector-client + neighbor PEER_V4_INT route-reflector-client {% endif %} neighbor PEER_V4 soft-reconfiguration inbound neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in neighbor PEER_V4 route-map TO_BGP_PEER_V4 out + neighbor PEER_V4_INT soft-reconfiguration inbound + neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in + neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out exit-address-family address-family ipv6 {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V6 allowas-in 1 + neighbor PEER_V6_INT allowas-in 1 {% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} - neighbor PEER_V6 route-reflector-client + neighbor PEER_V6_INT route-reflector-client {% endif %} neighbor PEER_V6 soft-reconfiguration inbound neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in neighbor PEER_V6 route-map TO_BGP_PEER_V6 out + neighbor PEER_V6_INT soft-reconfiguration inbound + neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in + neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out exit-address-family ! ! end of template: bgpd/templates/general/peer-group.conf.j2 From be2558106344acb4bce9904316ab63f94da4ed42 Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Thu, 21 May 2020 13:17:48 +0530 Subject: [PATCH 0684/1427] [Platform] [Marvell] SFP util changes to support GPIO mux over i2c_mux_gpio (#4522) SFP util changes to support GPIO mux over i2c_mux_gpio Signed-off-by: Antony Rheneus --- .../plugins/sfputil.py | 192 ++++++++++-------- 1 file changed, 102 insertions(+), 90 deletions(-) diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py index 92a1604f311a..431d2bc615aa 100755 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py @@ -4,10 +4,17 @@ import os import time import re + import sys + import glob from sonic_sfp.sfputilbase import SfpUtilBase except ImportError, e: raise ImportError (str(e) + "- required module not found") +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + smbus_present = 1 try: @@ -24,40 +31,45 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} port_to_i2c_mapping = { - 49 : 0, - 50 : 0, - 51 : 0, - 52 : 0 + 49 : 2, + 50 : 3, + 51 : 4, + 52 : 5 } _qsfp_ports = range(_port_start, ports_in_block + 1) - + _changed_ports = [0,0,0,0] def __init__(self): - # Override port_to_eeprom_mapping for class initialization - if not os.path.exists("/sys/class/gpio/gpio50/") : - os.system("echo 50 > /sys/class/gpio/gpiochip32/subsystem/export") - if not os.path.exists("/sys/class/gpio/gpio52/") : - os.system("echo 52 > /sys/class/gpio/gpiochip32/subsystem/export") - os.system("echo out > /sys/class/gpio/gpio50/direction") - os.system("echo out > /sys/class/gpio/gpio52/direction ") - - if not os.path.exists("/sys/bus/i2c/devices/0-0050") : - os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") - - eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' - for x in range(self.port_start, self.port_end + 1): - port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) - self.port_to_eeprom_mapping[x] = port_eeprom_path + # Enable optical SFP Tx if smbus_present == 0 : os.system("i2cset -y -m 0x0f 0 0x41 0x5 0x00") else : bus = smbus.SMBus(0) DEVICE_ADDRESS = 0x41 - DEVICEREG = 0x5 + DEVICEREG = 0x5 OPTIC_E = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) OPTIC_E = OPTIC_E & 0xf0 - bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, OPTIC_E) + bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, OPTIC_E) + + # Mux Ordering + mux_dev = sorted(glob.glob("/sys/class/i2c-adapter/i2c-0/i2c-[0-9]")) + + # Enable optoe2 Driver + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + bus_path = "/sys/class/i2c-adapter/i2c-{0}/" + y = 0 + for x in range(self.port_start, self.port_end + 1): + mux_dev_num = mux_dev[y] + self.port_to_i2c_mapping[x] = mux_dev_num[-1] + y = y + 1 + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + #print port_eeprom_path + if not os.path.exists(port_eeprom_path): + bus_dev_path = bus_path.format(self.port_to_i2c_mapping[x]) + os.system("echo optoe2 0x50 > " + bus_dev_path + "/new_device") + self.port_to_eeprom_mapping[x] = port_eeprom_path + self._port_to_eeprom_mapping[x] = port_eeprom_path SfpUtilBase.__init__(self) def reset(self, port_num): @@ -65,9 +77,9 @@ def reset(self, port_num): if port_num < self._port_start or port_num > self._port_end: return False - path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset" - port_ps = path.format(self.port_to_i2c_mapping[port_num+1]) - + path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/sfp_port_reset" + port_ps = path.format(self.port_to_i2c_mapping[port_num]) + try: reg_file = open(port_ps, 'w') except IOError as e: @@ -88,53 +100,35 @@ def set_low_power_mode(self, port_nuM, lpmode): def get_low_power_mode(self, port_num): raise NotImplementedError - + def get_presence(self, port_num): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: return False - prt = port_num % 49 - prt = "{0:02b}".format(prt) - p = prt[0] - q = prt[1] - cmd1 = "echo " + q + " > /sys/class/gpio/gpio50/value" - cmd2 = "echo " + p + " > /sys/class/gpio/gpio52/value" - os.system(cmd1) - os.system(cmd2) - - '''if port_num == 49 : - os.system("echo 0 > /sys/class/gpio/gpio50/value") - os.system("echo 0 > /sys/class/gpio/gpio52/value") - if port_num == 50 : - os.system("echo 0 > /sys/class/gpio/gpio50/value") - os.system("echo 0 > /sys/class/gpio/gpio52/value") - if port_num == 51 : - os.system("echo 0 > /sys/class/gpio/gpio50/value") - os.system("echo 0 > /sys/class/gpio/gpio52/value") - if port_num == 52: - os.system("echo 0 > /sys/class/gpio/gpio50/value") - os.system("echo 0 > /sys/class/gpio/gpio52/value")''' - path = "/sys/bus/i2c/devices/0-0050/eeprom" - #port_ps = path.format(self.port_to_i2c_mapping[port_num+1]) - - try: - reg_file = open(path) - reg_file.seek(01) - reg_file.read(02) - except IOError as e: - #print "Error: unable to open file: %s" % str(e) - - return False - - #reg_value = reg_file.readline().rstrip() - #if reg_value == '1': - # return True - - return True - + prt = port_num % 49 + sel = "{0:02b}".format(prt) + p = sel[0] + q = sel[1] + + pos = [1,2,4,8] + bit_pos = pos[prt] + if smbus_present == 0: + cmdstatus, sfpstatus = cmd.getstatusoutput('i2cget -y 0 0x41 0x3') #need to verify the cpld register logic + sfpstatus = int(sfpstatus, 16) + else : + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x3 + sfpstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + sfpstatus = sfpstatus&(bit_pos) + if sfpstatus == 0: + #print("Port " + str(port_num) + "present") + return True + + return False + def read_porttab_mappings(self, porttabfile): logical = [] - logical_to_bcm = {} logical_to_physical = {} physical_to_logical = {} last_fp_port_index = 0 @@ -166,14 +160,8 @@ def read_porttab_mappings(self, porttabfile): # Parsing logic for 'port_config.ini' file if (parse_fmt_port_config_ini): - # bcm_port is not explicitly listed in port_config.ini format - # Currently we assume ports are listed in numerical order according to bcm_port - # so we use the port's position in the file (zero-based) as bcm_port portname = line.split()[0] - bcm_port = str(port_pos_in_file) - #print("portname " + portname) - if "index" in title: fp_port_index = int(line.split()[title.index("index")]) # Leave the old code for backward compatibility @@ -182,10 +170,8 @@ def read_porttab_mappings(self, porttabfile): else: fp_port_index = portname.split("Ethernet").pop() fp_port_index = int(fp_port_index.split("s").pop(0))+1 - #print(fp_port_index) + #print(fp_port_index) else: # Parsing logic for older 'portmap.ini' file - (portname, bcm_port) = line.split("=")[1].split(",")[:2] - fp_port_index = portname.split("Ethernet").pop() fp_port_index = int(fp_port_index.split("s").pop(0))+1 @@ -201,7 +187,6 @@ def read_porttab_mappings(self, porttabfile): logical.append(portname) - logical_to_bcm[portname] = "xe" + bcm_port logical_to_physical[portname] = [fp_port_index] if physical_to_logical.get(fp_port_index) is None: physical_to_logical[fp_port_index] = [portname] @@ -224,17 +209,9 @@ def read_porttab_mappings(self, porttabfile): port_pos_in_file += 1 self.logical = logical - self.logical_to_bcm = logical_to_bcm self.logical_to_physical = logical_to_physical self.physical_to_logical = physical_to_logical - - #print(self.logical_to_physical) - '''print("logical: " + self.logical) - print("logical to bcm: " + self.logical_to_bcm) - print("logical to physical: " + self.logical_to_physical) - print("physical to logical: " + self.physical_to_logical)''' - @property @@ -244,15 +221,50 @@ def port_start(self): @property def port_end(self): return self._port_end - + @property def qsfp_ports(self): return self._qsfp_ports - @property + @property def port_to_eeprom_mapping(self): return self._port_to_eeprom_mapping - - @property - def get_transceiver_change_event(self): - raise NotImplementedError + + def get_transceiver_change_event(self, timeout): + port_dict = {} + port = 0 + + if timeout == 0: + cd_ms = sys.maxint + else: + cd_ms = timeout + changed_port = 0 + #poll per second + while cd_ms > 0: + for port_num in range(49,53): + prt = port_num % 49 + sfpstatus = self.get_presence(port_num) + if sfpstatus : + port_dict[str(port_num)]= '1' + if self._changed_ports[prt] == 0: + changed_port = 1 + self._changed_ports[prt] = 1 + else : + port_dict[str(port_num)] = '0' + if self._changed_ports[prt] == 1: + changed_port = 1 + self._changed_ports[prt] = 0 + + if changed_port != 0: + break + time.sleep(1) + cd_ms = cd_ms - 1000 + + if changed_port: + return True, port_dict + else: + return True, {} + return False, {} + + + From 3edb28516c8104f2b3ed93070f4b19f5cfa7f311 Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Thu, 21 May 2020 17:14:51 +0800 Subject: [PATCH 0685/1427] [device] set the port state to default down for device cig and ingrasys s9130 and s9230 (#4618) The default state of the port at startup is admin up, which can cause the port's state to be inconsistent with the actual state --- .../Cig-CS5435-54P/port_config.nps | 58 +----------------- .../Cig-CS6436-54P/port_config.nps | 58 +----------------- .../Cig-CS6436-56P/port_config.nps | 60 +------------------ .../INGRASYS-S9130-32X/port_config.nps | 3 +- .../INGRASYS-S9230-64X/port_config.nps | 3 +- 5 files changed, 10 insertions(+), 172 deletions(-) diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps index 9c6a5af8e5f0..e7f4fc78221c 100644 --- a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps @@ -620,59 +620,5 @@ port set property unit=0 portlist=129 medium-type=kr port set property unit=0 portlist=130 medium-type=x port advertise unit=0 portlist=129 speed-10g-kr port set property unit=0 portlist=129 an=enable -port set property unit=0 portlist=0 admin=enable -port set property unit=0 portlist=1 admin=enable -port set property unit=0 portlist=2 admin=enable -port set property unit=0 portlist=3 admin=enable -port set property unit=0 portlist=4 admin=enable -port set property unit=0 portlist=5 admin=enable -port set property unit=0 portlist=6 admin=enable -port set property unit=0 portlist=7 admin=enable -port set property unit=0 portlist=8 admin=enable -port set property unit=0 portlist=9 admin=enable -port set property unit=0 portlist=10 admin=enable -port set property unit=0 portlist=11 admin=enable -port set property unit=0 portlist=12 admin=enable -port set property unit=0 portlist=13 admin=enable -port set property unit=0 portlist=14 admin=enable -port set property unit=0 portlist=15 admin=enable -port set property unit=0 portlist=16 admin=enable -port set property unit=0 portlist=17 admin=enable -port set property unit=0 portlist=18 admin=enable -port set property unit=0 portlist=19 admin=enable -port set property unit=0 portlist=20 admin=enable -port set property unit=0 portlist=21 admin=enable -port set property unit=0 portlist=22 admin=enable -port set property unit=0 portlist=23 admin=enable -port set property unit=0 portlist=24 admin=enable -port set property unit=0 portlist=25 admin=enable -port set property unit=0 portlist=26 admin=enable -port set property unit=0 portlist=27 admin=enable -port set property unit=0 portlist=28 admin=enable -port set property unit=0 portlist=29 admin=enable -port set property unit=0 portlist=30 admin=enable -port set property unit=0 portlist=31 admin=enable -port set property unit=0 portlist=32 admin=enable -port set property unit=0 portlist=33 admin=enable -port set property unit=0 portlist=34 admin=enable -port set property unit=0 portlist=35 admin=enable -port set property unit=0 portlist=36 admin=enable -port set property unit=0 portlist=37 admin=enable -port set property unit=0 portlist=38 admin=enable -port set property unit=0 portlist=39 admin=enable -port set property unit=0 portlist=40 admin=enable -port set property unit=0 portlist=41 admin=enable -port set property unit=0 portlist=42 admin=enable -port set property unit=0 portlist=43 admin=enable -port set property unit=0 portlist=44 admin=enable -port set property unit=0 portlist=45 admin=enable -port set property unit=0 portlist=46 admin=enable -port set property unit=0 portlist=47 admin=enable -port set property unit=0 portlist=48 admin=enable -port set property unit=0 portlist=49 admin=enable -port set property unit=0 portlist=50 admin=enable -port set property unit=0 portlist=51 admin=enable -port set property unit=0 portlist=52 admin=enable -port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=129 admin=disable -port set property unit=0 portlist=130 admin=disable +port set property unit=0 portlist=0-53 admin=disable +port set property unit=0 portlist=129-130 admin=disable diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps index aca222f5962d..120b7f398871 100644 --- a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps @@ -620,59 +620,5 @@ port set property unit=0 portlist=129 medium-type=kr port set property unit=0 portlist=130 medium-type=x port advertise unit=0 portlist=129 speed-10g-kr port set property unit=0 portlist=129 an=enable -port set property unit=0 portlist=0 admin=enable -port set property unit=0 portlist=1 admin=enable -port set property unit=0 portlist=2 admin=enable -port set property unit=0 portlist=3 admin=enable -port set property unit=0 portlist=4 admin=enable -port set property unit=0 portlist=5 admin=enable -port set property unit=0 portlist=6 admin=enable -port set property unit=0 portlist=7 admin=enable -port set property unit=0 portlist=8 admin=enable -port set property unit=0 portlist=9 admin=enable -port set property unit=0 portlist=10 admin=enable -port set property unit=0 portlist=11 admin=enable -port set property unit=0 portlist=12 admin=enable -port set property unit=0 portlist=13 admin=enable -port set property unit=0 portlist=14 admin=enable -port set property unit=0 portlist=15 admin=enable -port set property unit=0 portlist=16 admin=enable -port set property unit=0 portlist=17 admin=enable -port set property unit=0 portlist=18 admin=enable -port set property unit=0 portlist=19 admin=enable -port set property unit=0 portlist=20 admin=enable -port set property unit=0 portlist=21 admin=enable -port set property unit=0 portlist=22 admin=enable -port set property unit=0 portlist=23 admin=enable -port set property unit=0 portlist=24 admin=enable -port set property unit=0 portlist=25 admin=enable -port set property unit=0 portlist=26 admin=enable -port set property unit=0 portlist=27 admin=enable -port set property unit=0 portlist=28 admin=enable -port set property unit=0 portlist=29 admin=enable -port set property unit=0 portlist=30 admin=enable -port set property unit=0 portlist=31 admin=enable -port set property unit=0 portlist=32 admin=enable -port set property unit=0 portlist=33 admin=enable -port set property unit=0 portlist=34 admin=enable -port set property unit=0 portlist=35 admin=enable -port set property unit=0 portlist=36 admin=enable -port set property unit=0 portlist=37 admin=enable -port set property unit=0 portlist=38 admin=enable -port set property unit=0 portlist=39 admin=enable -port set property unit=0 portlist=40 admin=enable -port set property unit=0 portlist=41 admin=enable -port set property unit=0 portlist=42 admin=enable -port set property unit=0 portlist=43 admin=enable -port set property unit=0 portlist=44 admin=enable -port set property unit=0 portlist=45 admin=enable -port set property unit=0 portlist=46 admin=enable -port set property unit=0 portlist=47 admin=enable -port set property unit=0 portlist=48 admin=enable -port set property unit=0 portlist=49 admin=enable -port set property unit=0 portlist=50 admin=enable -port set property unit=0 portlist=51 admin=enable -port set property unit=0 portlist=52 admin=enable -port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=129 admin=disable -port set property unit=0 portlist=130 admin=disable +port set property unit=0 portlist=0-53 admin=disable +port set property unit=0 portlist=129-130 admin=disable diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps index ec5f0273b9b5..c0067a3b56af 100644 --- a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps +++ b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps @@ -642,61 +642,5 @@ port set property unit=0 portlist=129 medium-type=kr port set property unit=0 portlist=130 medium-type=x port advertise unit=0 portlist=129 speed-10g-kr port set property unit=0 portlist=129 an=enable -port set property unit=0 portlist=0 admin=enable -port set property unit=0 portlist=1 admin=enable -port set property unit=0 portlist=2 admin=enable -port set property unit=0 portlist=3 admin=enable -port set property unit=0 portlist=4 admin=enable -port set property unit=0 portlist=5 admin=enable -port set property unit=0 portlist=6 admin=enable -port set property unit=0 portlist=7 admin=enable -port set property unit=0 portlist=8 admin=enable -port set property unit=0 portlist=9 admin=enable -port set property unit=0 portlist=10 admin=enable -port set property unit=0 portlist=11 admin=enable -port set property unit=0 portlist=12 admin=enable -port set property unit=0 portlist=13 admin=enable -port set property unit=0 portlist=14 admin=enable -port set property unit=0 portlist=15 admin=enable -port set property unit=0 portlist=16 admin=enable -port set property unit=0 portlist=17 admin=enable -port set property unit=0 portlist=18 admin=enable -port set property unit=0 portlist=19 admin=enable -port set property unit=0 portlist=20 admin=enable -port set property unit=0 portlist=21 admin=enable -port set property unit=0 portlist=22 admin=enable -port set property unit=0 portlist=23 admin=enable -port set property unit=0 portlist=24 admin=enable -port set property unit=0 portlist=25 admin=enable -port set property unit=0 portlist=26 admin=enable -port set property unit=0 portlist=27 admin=enable -port set property unit=0 portlist=28 admin=enable -port set property unit=0 portlist=29 admin=enable -port set property unit=0 portlist=30 admin=enable -port set property unit=0 portlist=31 admin=enable -port set property unit=0 portlist=32 admin=enable -port set property unit=0 portlist=33 admin=enable -port set property unit=0 portlist=34 admin=enable -port set property unit=0 portlist=35 admin=enable -port set property unit=0 portlist=36 admin=enable -port set property unit=0 portlist=37 admin=enable -port set property unit=0 portlist=38 admin=enable -port set property unit=0 portlist=39 admin=enable -port set property unit=0 portlist=40 admin=enable -port set property unit=0 portlist=41 admin=enable -port set property unit=0 portlist=42 admin=enable -port set property unit=0 portlist=43 admin=enable -port set property unit=0 portlist=44 admin=enable -port set property unit=0 portlist=45 admin=enable -port set property unit=0 portlist=46 admin=enable -port set property unit=0 portlist=47 admin=enable -port set property unit=0 portlist=48 admin=enable -port set property unit=0 portlist=49 admin=enable -port set property unit=0 portlist=50 admin=enable -port set property unit=0 portlist=51 admin=enable -port set property unit=0 portlist=52 admin=enable -port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=54 admin=enable -port set property unit=0 portlist=55 admin=enable -port set property unit=0 portlist=129 admin=disable -port set property unit=0 portlist=130 admin=disable +port set property unit=0 portlist=0-55 admin=disable +port set property unit=0 portlist=129-130 admin=disable diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps index 49068859b25c..6d49c6720882 100644 --- a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps +++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps @@ -349,4 +349,5 @@ port set property unit=0 portlist=129-130 medium-type=kr port set property unit=0 portlist=0-31 fec=disable port set adver unit=0 portlist=129-130 speed-10g-kr port set property unit=0 portlist=129-130 an=enable -port set property unit=0 portlist=0-31,129-130 admin=enable +port set property unit=0 portlist=129-130 admin=enable +port set property unit=0 portlist=0-31 admin=disable diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps index 0e14b9ced3fe..4f89209537f8 100644 --- a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps +++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps @@ -678,4 +678,5 @@ port set property portlist=0-63 fec=disable port set adver portlist=129-130 speed-10g-kr port set property portlist=129-130 an=enable -port set property portlist=0-63,129-130 admin=enable +port set property portlist=129-130 admin=enable +port set property portlist=0-63 admin=disable From d4b89b1909eb180a50d176f4d8477a7a4345981a Mon Sep 17 00:00:00 2001 From: dereksun01 <52683998+dereksun01@users.noreply.github.com> Date: Thu, 21 May 2020 17:17:54 +0800 Subject: [PATCH 0686/1427] [device/accton] Remove linkscan_led_fw.bin file on as7326_56x (#4408) --- device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc b/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc index 01b49772c0ba..cb549f2773f9 100755 --- a/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc +++ b/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc @@ -1,6 +1,6 @@ #led auto off #led stop -m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin +#m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin led auto on led start From 0b6253baa1bbd8c65e68ba7b5f2400341f300d5e Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Thu, 21 May 2020 17:21:07 +0800 Subject: [PATCH 0687/1427] [platform/nephos] Optimize the code to reduce changes due to the kernel upgrade (#4332) - bug fix : Fixed an issue which the nps ko file was not loaded due to the wrong service file name - Optimize the code to reduce changes due to the kernel upgrade - Remove nephos ko file loaded in swss.service.j2 because it has loaded at syncd.service.j2 --- .../per_namespace/swss.service.j2 | 2 -- .../per_namespace/syncd.service.j2 | 4 ++-- platform/nephos/nephos-modules.mk | 20 ++----------------- .../{nps-modules-4.9-amd64 => nps-modules} | 2 +- ...-4.9-amd64.service => nps-modules.service} | 4 ++-- 5 files changed, 7 insertions(+), 25 deletions(-) rename platform/nephos/nephos-modules/modules/init.d/{nps-modules-4.9-amd64 => nps-modules} (92%) rename platform/nephos/nephos-modules/modules/service/{nps-modules-4.9-amd64.service => nps-modules.service} (63%) diff --git a/files/build_templates/per_namespace/swss.service.j2 b/files/build_templates/per_namespace/swss.service.j2 index 53d6b4497df7..352d1593a60b 100644 --- a/files/build_templates/per_namespace/swss.service.j2 +++ b/files/build_templates/per_namespace/swss.service.j2 @@ -8,8 +8,6 @@ After=topology.service {% endif %} {% if sonic_asic_platform == 'broadcom' %} Requires=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service {% endif %} Requires=updategraph.service After=updategraph.service diff --git a/files/build_templates/per_namespace/syncd.service.j2 b/files/build_templates/per_namespace/syncd.service.j2 index b2922e0d12b6..0c9bf073e940 100644 --- a/files/build_templates/per_namespace/syncd.service.j2 +++ b/files/build_templates/per_namespace/syncd.service.j2 @@ -11,8 +11,8 @@ After=topology.service Requires=opennsl-modules.service After=opennsl-modules.service {% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service -After=nps-modules-4.9.0-11-2-amd64.service +Requires=nps-modules.service +After=nps-modules.service {% endif %} Requires=updategraph.service After=updategraph.service diff --git a/platform/nephos/nephos-modules.mk b/platform/nephos/nephos-modules.mk index 0dd7e2971823..5e055537a428 100644 --- a/platform/nephos/nephos-modules.mk +++ b/platform/nephos/nephos-modules.mk @@ -1,25 +1,9 @@ # Nephos Platform modules -VERSION = 1.0.1 +NPS_PLATFORM_MODULE_VERSION = 1.0.1 -ifneq ($(NEPHOS_SAI_DEB_LOCAL_URL), ) -SDK_FROM_LOCAL = y -else -SDK_FROM_LOCAL = n -endif - -SDK_VERSION = 3.0.0 -LINUX_VER = 4.9.0-11-2 -SDK_COMMIT_ID = 529202 - -ifeq ($(SAI_FROM_LOCAL), y) -NEPHOS_MODULE = nps-modules-$(LINUX_VER)_$(SDK_VERSION)_$(SDK_COMMIT_ID)_amd64.deb -$(NEPHOS_MODULE)_PATH = $(NEPHOS_SAI_DEB_LOCAL_URL) -SONIC_COPY_DEBS += $(NEPHOS_MODULE) -else -NEPHOS_MODULE = nephos-modules_$(VERSION)_amd64.deb +NEPHOS_MODULE = nephos-modules_$(NPS_PLATFORM_MODULE_VERSION)_amd64.deb $(NEPHOS_MODULE)_SRC_PATH = $(PLATFORM_PATH)/nephos-modules $(NEPHOS_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_DPKG_DEBS += $(NEPHOS_MODULE) -endif diff --git a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 b/platform/nephos/nephos-modules/modules/init.d/nps-modules similarity index 92% rename from platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 rename to platform/nephos/nephos-modules/modules/init.d/nps-modules index a6deb4217a95..d6f841ee02e7 100755 --- a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 +++ b/platform/nephos/nephos-modules/modules/init.d/nps-modules @@ -45,7 +45,7 @@ force-reload|restart) ;; *) - echo "Usage: /etc/init.d/nps-modules-4.9.0-11-2-amd64.init {start|stop}" + echo "Usage: /etc/init.d/nps-modules {start|stop}" exit 1 ;; esac diff --git a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service b/platform/nephos/nephos-modules/modules/service/nps-modules.service similarity index 63% rename from platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service rename to platform/nephos/nephos-modules/modules/service/nps-modules.service index fc45a597d74c..22aa9a7510c6 100644 --- a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service +++ b/platform/nephos/nephos-modules/modules/service/nps-modules.service @@ -5,8 +5,8 @@ Before=syncd.service [Service] Type=oneshot -ExecStart=-/etc/init.d/nps-modules-4.9-amd64 start -ExecStop=-/etc/init.d/nps-modules-4.9-amd64 stop +ExecStart=-/etc/init.d/nps-modules start +ExecStop=-/etc/init.d/nps-modules stop RemainAfterExit=yes [Install] From 3f061da48faf32436da930f87fc8c786a11d7972 Mon Sep 17 00:00:00 2001 From: ChiouRung Haung Date: Thu, 21 May 2020 17:23:39 +0800 Subject: [PATCH 0688/1427] [device/accton]: rename the config.bcm due to that it just allow 1st row of TH2 to be breakout (#4295) - What I did 1. Rename the config.bcm to th2-as7816-64x25G-48x100G_row1.config.bcm, due to that it just allow 1st row of TH2 to be breakout 2. Add port_flex_enable to support dynamic port breakout. 3. Remove the loopback port due to it would make syncd terminate. => The port_config.ini doesn't include the loopback ports. When portsorch start, it would compare the ports in SDK and port_config.ini. Portsorch would remove the loopback ports due to the loopback ports didn't been defined in port_config.ini But the broadcom SAI doesn't support remove port for th2. So it would return fail and syncd would terminate. - How I did it - How to verify it Run with the new SONiC image and syncd would not terminate Signed-off-by: chiourung_huang --- .../Accton-AS7816-64X/sai.profile | 2 +- ...cm => th2-as7816-64x25G-48x100G_row1.config.bcm} | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) rename device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/{th2-as7816-64x100G.config.bcm => th2-as7816-64x25G-48x100G_row1.config.bcm} (99%) diff --git a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile index e2f945e9a073..30fc08adde62 100644 --- a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile +++ b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-as7816-64x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-as7816-64x25G-48x100G_row1.config.bcm diff --git a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x100G.config.bcm b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm similarity index 99% rename from device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x100G.config.bcm rename to device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm index 2a440fbfe07c..0b19742ffe3f 100644 --- a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x100G.config.bcm +++ b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm @@ -26,20 +26,21 @@ max_vp_lags=0 miim_intr_enable=0 module_64ports=1 oversubscribe_mode=1 +port_flex_enable=1 #add loopback port # port 33 is the first loopback port -portmap_33=260:10 +#portmap_33=260:10 # port 66 is the first management port -portmap_66=257:10 +#portmap_66=257:10 # port 67 is the second loopback port -portmap_67=261:10 +#portmap_67=261:10 # port 100 is the second management port -portmap_100=259:10 +#portmap_100=259:10 # port 101 is the third loopback port -portmap_101=262:10 +#portmap_101=262:10 # port 135 is the fourth loopback port -portmap_135=263:10 +#portmap_135=263:10 #Port0 #FC18 From 5fefee67d783c2a7d957e6c6556c319ab34682cf Mon Sep 17 00:00:00 2001 From: Polly Hsu Date: Thu, 21 May 2020 17:35:48 +0800 Subject: [PATCH 0689/1427] [device][accton]: Update for AS5835-54T (#3272) * [device][accton]: Update for AS5835-54T * [device][accton]: Update for AS5835-54T to delete its config.bcm off-loading to the self-brought up of the Broadcom SAI version, 3.5.2.3 due to SONiC not supported. * [device][accton]: Add config.bcm for AS5835-54T * Ran config_checker passed on our config.bcm, however, we off-loaded the needed MV2 SDK config setting to our self-brought up SAI libraries due to the compatibility of config_check among SONiC different branches. [-] help_cli_enable=1 [-] ifp_inports_support_enable=1 [-] memlist_enable=1 [-] port_flex_enable=1 [-] reglist_enable=1 * [device][accton]: Update config.bcm for AS5835-54T based on the latest config_checker Co-authored-by: Polly Hsu --- ...m => mv2-as5835t-48x10G+6x100G.config.bcm} | 23 +++++++++++++++++-- .../Accton-AS5835-54T/port_config.ini | 10 ++++---- .../Accton-AS5835-54T/sai.profile | 3 ++- 3 files changed, 28 insertions(+), 8 deletions(-) rename device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/{td3-as5835t-48x10G+6x100G.config.bcm => mv2-as5835t-48x10G+6x100G.config.bcm} (97%) mode change 100644 => 100755 mode change 100644 => 100755 device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/port_config.ini mode change 100644 => 100755 device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile diff --git a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/td3-as5835t-48x10G+6x100G.config.bcm b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm old mode 100644 new mode 100755 similarity index 97% rename from device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/td3-as5835t-48x10G+6x100G.config.bcm rename to device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm index 4b73e8c29db3..1a575bd18a69 --- a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/td3-as5835t-48x10G+6x100G.config.bcm +++ b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm @@ -14,10 +14,29 @@ parity_enable=0 mem_cache_enable=0 l2_mem_entries=32768 -#l3_mem_entries=49152 -#fpem_mem_entries=16384 +l3_mem_entries=16384 +fpem_mem_entries=16384 l2xmsg_mode=1 +# Platform specfic +bcm_num_cos=8 +bcm_stat_interval=2000000 +cdma_timeout_usec=3000000 +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=0x1 +l3_alpm_enable=2 +l3_max_ecmp_mode=1 +max_vp_lags=0 +miim_intr_enable=0 +module_64ports=1 +port_flex_enable=1 +schan_intr_enable=0 +stable_size=0x5500000 ;Specify the stable cache size in bytes used for Warm boot operations +tdma_timeout_usec=3000000 +skip_L2_USER_ENTRY=0 +bcm_tunnel_term_compatible_mode=1 +l3_alpm_ipv6_128b_bkt_rsvd=1 + #FC0 dport_map_port_1=2 dport_map_port_2=1 diff --git a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/port_config.ini b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/port_config.ini old mode 100644 new mode 100755 index 2e128a4fde65..119fe814fee1 --- a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/port_config.ini +++ b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/port_config.ini @@ -47,9 +47,9 @@ Ethernet44 74 tenGigE45 45 10000 Ethernet45 73 tenGigE46 46 10000 Ethernet46 76 tenGigE47 47 10000 Ethernet47 75 tenGigE48 48 10000 -Ethernet48 29,30,31,32 hundredGigE49 49 100000 -Ethernet52 33,34,35,36 hundredGigE50 53 100000 -Ethernet56 37,38,39,40 hundredGigE51 57 100000 -Ethernet60 41,42,43,44 hundredGigE52 61 100000 +Ethernet48 37,38,39,40 hundredGigE49 49 100000 +Ethernet52 29,30,31,32 hundredGigE50 53 100000 +Ethernet56 33,34,35,36 hundredGigE51 57 100000 +Ethernet60 49,50,51,52 hundredGigE52 61 100000 Ethernet64 45,46,47,48 hundredGigE53 65 100000 -Ethernet68 49,50,51,52 hundredGigE54 69 100000 +Ethernet68 41,42,43,44 hundredGigE54 69 100000 diff --git a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile old mode 100644 new mode 100755 index 952c87a00eeb..44dc691640be --- a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile +++ b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile @@ -1 +1,2 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as5835t-48x10G+6x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/mv2-as5835t-48x10G+6x100G.config.bcm +SAI_BOARD_CONFIG_PATH=/etc/accton From 2398992d52df0dd6e33114c4246932a49ac51249 Mon Sep 17 00:00:00 2001 From: Tyler Li Date: Fri, 22 May 2020 00:12:51 +0800 Subject: [PATCH 0690/1427] [iccpd] build iccpd deb by auto tools (#4540) * [iccpd] build iccpd deb by auto tools --- dockers/docker-iccpd/Dockerfile.j2 | 1 - rules/docker-iccpd.mk | 12 +++++-- rules/iccpd.mk | 14 +++++--- src/iccpd/Makefile | 37 ------------------- src/iccpd/Makefile.am | 1 + src/iccpd/autogen.sh | 6 ++++ src/iccpd/configure.ac | 32 +++++++++++++++++ src/iccpd/debian/DEBIAN/control | 12 ------- src/iccpd/debian/changelog | 6 ++++ src/iccpd/debian/compat | 1 + src/iccpd/debian/control | 18 ++++++++++ src/iccpd/debian/rules | 34 ++++++++++++++++++ src/iccpd/include/iccp_csm.h | 1 + src/iccpd/include/scheduler.h | 1 + src/iccpd/src/Makefile | 55 ----------------------------- src/iccpd/src/Makefile.am | 22 ++++++++++++ src/iccpd/src/iccp_ifm.c | 2 +- src/iccpd/src/mclagdctl/Makefile | 28 --------------- src/iccpd/src/mclagdctl/Makefile.am | 10 ++++++ src/iccpd/src/mclagdctl/mclagdctl.c | 4 ++- src/iccpd/src/mlacp_sync_prepare.c | 2 +- src/iccpd/src/port.c | 2 ++ src/iccpd/src/scheduler.c | 5 ++- 23 files changed, 163 insertions(+), 143 deletions(-) delete mode 100644 src/iccpd/Makefile create mode 100644 src/iccpd/Makefile.am create mode 100755 src/iccpd/autogen.sh create mode 100644 src/iccpd/configure.ac delete mode 100644 src/iccpd/debian/DEBIAN/control create mode 100644 src/iccpd/debian/changelog create mode 100644 src/iccpd/debian/compat create mode 100644 src/iccpd/debian/control create mode 100755 src/iccpd/debian/rules delete mode 100644 src/iccpd/src/Makefile create mode 100644 src/iccpd/src/Makefile.am delete mode 100644 src/iccpd/src/mclagdctl/Makefile create mode 100644 src/iccpd/src/mclagdctl/Makefile.am diff --git a/dockers/docker-iccpd/Dockerfile.j2 b/dockers/docker-iccpd/Dockerfile.j2 index 3c7e01ed54e9..3424c0e97fc9 100644 --- a/dockers/docker-iccpd/Dockerfile.j2 +++ b/dockers/docker-iccpd/Dockerfile.j2 @@ -9,7 +9,6 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y ebtables -RUN apt-get -y install -f kmod COPY \ {% for deb in docker_iccpd_debs.split(' ') -%} diff --git a/rules/docker-iccpd.mk b/rules/docker-iccpd.mk index da661e9a2244..106da8e589d8 100644 --- a/rules/docker-iccpd.mk +++ b/rules/docker-iccpd.mk @@ -1,14 +1,22 @@ # docker image for iccpd agent -DOCKER_ICCPD = docker-iccpd.gz -$(DOCKER_ICCPD)_PATH = $(DOCKERS_PATH)/docker-iccpd +DOCKER_ICCPD_STEM = docker-iccpd +DOCKER_ICCPD = $(DOCKER_ICCPD_STEM).gz +DOCKER_ICCPD_DBG = $(DOCKER_ICCPD_STEM)-$(DBG_IMAGE_MARK).gz +$(DOCKER_ICCPD)_PATH = $(DOCKERS_PATH)/$(DOCKER_ICCPD_STEM) $(DOCKER_ICCPD)_DEPENDS += $(SWSS) $(REDIS_TOOLS) $(ICCPD) +$(DOCKER_ICCPD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_ICCPD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) $(ICCPD_DBG) +$(DOCKER_ICCPD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) $(DOCKER_ICCPD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) ifeq ($(ENABLE_ICCPD), y) SONIC_DOCKER_IMAGES += $(DOCKER_ICCPD) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ICCPD) SONIC_STRETCH_DOCKERS += $(DOCKER_ICCPD) +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_ICCPD_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ICCPD_DBG) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ICCPD_DBG) endif $(DOCKER_ICCPD)_CONTAINER_NAME = iccpd diff --git a/rules/iccpd.mk b/rules/iccpd.mk index 26d3adf1dd62..eb97efc52b9f 100644 --- a/rules/iccpd.mk +++ b/rules/iccpd.mk @@ -6,8 +6,14 @@ ICCPD = iccpd_$(ICCPD_VERSION)_$(CONFIGURED_ARCH).deb $(ICCPD)_DEPENDS += $(LIBNL_GENL3_DEV) $(LIBNL_CLI_DEV) $(ICCPD)_RDEPENDS += $(LIBNL_GENL3) $(LIBNL_CLI) $(ICCPD)_SRC_PATH = $(SRC_PATH)/iccpd -SONIC_MAKE_DEBS += $(ICCPD) +SONIC_DPKG_DEBS += $(ICCPD) -# Export these variables so they can be used in a sub-make -export ICCPD_VERSION -export ICCPD +ICCPD_DBG = iccpd-dbg_$(ICCPD_VERSION)_$(CONFIGURED_ARCH).deb +$(ICCPD_DBG)_DEPENDS += $(ICCPD) +$(ICCPD_DBG)_RDEPENDS += $(ICCPD) +$(eval $(call add_derived_package,$(ICCPD),$(ICCPD_DBG))) + +# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} +# are archived into debug one image to facilitate debugging. +# +DBG_SRC_ARCHIVE += iccpd diff --git a/src/iccpd/Makefile b/src/iccpd/Makefile deleted file mode 100644 index b8f5c19ddf5f..000000000000 --- a/src/iccpd/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -.ONESHELL: -SHELL = /bin/bash -.SHELLFLAGS += -e - -MAIN_TARGET = iccpd_$(ICCPD_VERSION)_$(CONFIGURED_ARCH).deb -DEB_PATH = debian - -all: iccpd-build mclagdctl-build - -iccpd-build: - make -C src - -mclagdctl-build: - make -C src/mclagdctl - -$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : - make all - if [ ! -d $(DEB_PATH)/usr/bin ]; then - mkdir -p $(DEB_PATH)/usr/bin - fi - cp iccpd $(DEB_PATH)/usr/bin/iccpd - cp src/mclagdctl/mclagdctl $(DEB_PATH)/usr/bin/mclagdctl - chmod +x $(DEB_PATH)/usr/bin/iccpd - chmod +x $(DEB_PATH)/usr/bin/mclagdctl - md5sum $(DEB_PATH)/usr/bin/iccpd > $(DEB_PATH)/DEBIAN/md5sums - md5sum $(DEB_PATH)/usr/bin/mclagdctl >> $(DEB_PATH)/DEBIAN/md5sums - sed -i "s/Package: .*/Package: iccpd-$(ICCPD_VERSION)-$(CONFIGURED_ARCH)/g" $(DEB_PATH)/DEBIAN/control - sed -i "s/Architecture: .*/Architecture: $(CONFIGURED_ARCH)/g" $(DEB_PATH)/DEBIAN/control - dpkg-deb -b $(DEB_PATH) $(DEST)/$(MAIN_TARGET) - -clean: iccpd-clean mclagdctl-clean - -iccpd-clean: - make -C src clean - -mclagdctl-clean: - make -C src/mclagdctl clean diff --git a/src/iccpd/Makefile.am b/src/iccpd/Makefile.am new file mode 100644 index 000000000000..af437a64d6d8 --- /dev/null +++ b/src/iccpd/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src diff --git a/src/iccpd/autogen.sh b/src/iccpd/autogen.sh new file mode 100755 index 000000000000..c8d0bbe4a251 --- /dev/null +++ b/src/iccpd/autogen.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +libtoolize --force --copy && +autoreconf --force --install -I m4 +rm -Rf autom4te.cache + diff --git a/src/iccpd/configure.ac b/src/iccpd/configure.ac new file mode 100644 index 000000000000..9567d2b5cd7d --- /dev/null +++ b/src/iccpd/configure.ac @@ -0,0 +1,32 @@ +AC_INIT([iccpd],[0.5]) +AC_CONFIG_SRCDIR([]) +AC_CONFIG_AUX_DIR(config) +AM_CONFIG_HEADER(config.h) +AM_INIT_AUTOMAKE([foreign]) +AC_LANG_C +AC_PROG_CC +AC_PROG_LIBTOOL +AC_HEADER_STDC + +AC_ARG_ENABLE(debug, +[ --enable-debug Compile with debugging flags], +[case "${enableval}" in + yes) debug=true ;; + no) debug=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;; +esac],[debug=false]) +AM_CONDITIONAL(DEBUG, test x$debug = xtrue) + +CPPFLAGS="-D_FORTIFY_SOURCE=2" + +CFLAGS_COMMON="-Wno-unused-result" + +AC_SUBST(CFLAGS_COMMON) + +AC_CONFIG_FILES([ + Makefile + src/Makefile + src/mclagdctl/Makefile +]) + +AC_OUTPUT diff --git a/src/iccpd/debian/DEBIAN/control b/src/iccpd/debian/DEBIAN/control deleted file mode 100644 index cedfa03f37c0..000000000000 --- a/src/iccpd/debian/DEBIAN/control +++ /dev/null @@ -1,12 +0,0 @@ -Package: iccpd-0.0.5-amd64 -Source: nps -Version: 0.0.5 -Architecture: amd64 -Maintainer: Simon Ji -Installed-Size: 1508 -Depends: -Section: main -Priority: extra -Homepage: https://github.com/NephosInc/SONiC -Description: - diff --git a/src/iccpd/debian/changelog b/src/iccpd/debian/changelog new file mode 100644 index 000000000000..a2b3b066bc82 --- /dev/null +++ b/src/iccpd/debian/changelog @@ -0,0 +1,6 @@ +sonic (0.0.5) stable; urgency=medium + + * Initial release. + + -- Tyler Li Thu, 23 Apr 2020 10:00:00 +0800 + diff --git a/src/iccpd/debian/compat b/src/iccpd/debian/compat new file mode 100644 index 000000000000..f599e28b8ab0 --- /dev/null +++ b/src/iccpd/debian/compat @@ -0,0 +1 @@ +10 diff --git a/src/iccpd/debian/control b/src/iccpd/debian/control new file mode 100644 index 000000000000..3c9334af0a65 --- /dev/null +++ b/src/iccpd/debian/control @@ -0,0 +1,18 @@ +Source: sonic +Maintainer: Tyler Li +Section: net +Priority: optional +Build-Depends: dh-exec (>=0.3), debhelper (>= 9), autotools-dev +Standards-Version: 0.0.5 + +Package: iccpd +Architecture: any +Depends: ${shlibs:Depends} +Description: This package contains Inter-Chassis Control Protocol for SONiC project. + +Package: iccpd-dbg +Architecture: any +Section: debug +Priority: extra +Depends: iccpd (=${binary:Version}) +Description: debugging symbols for iccpd diff --git a/src/iccpd/debian/rules b/src/iccpd/debian/rules new file mode 100755 index 000000000000..81f48423874e --- /dev/null +++ b/src/iccpd/debian/rules @@ -0,0 +1,34 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + +# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* +DPKG_EXPORT_BUILDFLAGS = 1 +include /usr/share/dpkg/default.mk + +# see FEATURE AREAS in dpkg-buildflags(1) +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# see ENVIRONMENT in dpkg-buildflags(1) +# package maintainers to append CFLAGS +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# package maintainers to append LDFLAGS +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + + +# main packaging script based on dh7 syntax +%: + dh $@ --with autotools-dev + +# dh_make generated override targets +# This is example for Cmake (See https://bugs.debian.org/641051 ) +#override_dh_auto_configure: +# dh_auto_configure -- \ +# -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) + +override_dh_auto_install: + dh_auto_install --destdir=debian/iccpd + +override_dh_strip: + dh_strip --dbg-package=iccpd-dbg diff --git a/src/iccpd/include/iccp_csm.h b/src/iccpd/include/iccp_csm.h index 96e366371933..01e424d13271 100644 --- a/src/iccpd/include/iccp_csm.h +++ b/src/iccpd/include/iccp_csm.h @@ -31,6 +31,7 @@ #include #include #include +#include #include "../include/app_csm.h" #include "../include/msg_format.h" diff --git a/src/iccpd/include/scheduler.h b/src/iccpd/include/scheduler.h index b3be274282c8..a1b31039d794 100644 --- a/src/iccpd/include/scheduler.h +++ b/src/iccpd/include/scheduler.h @@ -35,6 +35,7 @@ #include struct CSM; +struct System; #define CONNECT_INTERVAL_SEC 1 #define CONNECT_TIMEOUT_MSEC 100 diff --git a/src/iccpd/src/Makefile b/src/iccpd/src/Makefile deleted file mode 100644 index 5e8cebc703c0..000000000000 --- a/src/iccpd/src/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -LIBNL_CFLAGS = -I/usr/include/libnl3 -LIBNL_LIBS = -lnl-cli-3 -lnl-genl-3 -lnl-nf-3 -lnl-route-3 -lnl-3 - -CC = gcc -SOURCES = app_csm.c cmd_option.c iccp_cli.c iccp_cmd_show.c iccp_cmd.c \ -iccp_csm.c iccp_ifm.c iccp_main.c logger.c \ -port.c scheduler.c system.c iccp_consistency_check.c \ -mlacp_link_handler.c \ -mlacp_sync_prepare.c mlacp_sync_update.c\ -mlacp_fsm.c \ -iccp_netlink.c - -OBJECTS = app_csm.o cmd_option.o iccp_cli.o iccp_cmd_show.o iccp_cmd.o \ -iccp_csm.o iccp_ifm.o iccp_main.o logger.o \ -port.o scheduler.o system.o iccp_consistency_check.o\ -mlacp_link_handler.o \ -mlacp_sync_prepare.o mlacp_sync_update.o \ -mlacp_fsm.o \ -iccp_netlink.o - -HEADERS = ../include/app_csm.h ../include/cmd_option.h ../include/iccp_cli.h \ -../include/iccp_cmd_show.h \ -../include/iccp_csm.h ../include/iccp_ifm.h \ -../include/logger.h ../include/mlacp_fsm.h \ -../include/mlacp_tlv.h ../include/msg_format.h ../include/port.h \ -../include/scheduler.h ../include/system.h \ -../include/iccp_consistency_check.h ../include/route_info.h \ -../include/iccp_netlink.h - -//CFLAGS = -g -O2 -fstack-protector-strong -Wformat -Werror=format-security $(LIBNL_CFLAGS) -I../include/ -CFLAGS = -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -I../include/ $(LIBNL_CFLAGS) -LDFLAGS = $(LIBNL_LIBS) -lpthread -LDADD = $(LIBZEBRA_BIN) - -all: iccpd - -%.o: %.c $(HEADERS) - -iccpd: $(OBJECTS) - $(CC) -o ../iccpd $(OBJECTS) $(LDFLAGS) - -DEPS = $(patsubst %.o, %.d, $(OBJECTS)) - --include $(DEPS) -%.d:%.c - @set -e; rm -f $@; \ - gcc -MM $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - - - -.PHONY: clean -clean: - -rm -f $(OBJECTS) $(DEPS) ../iccpd diff --git a/src/iccpd/src/Makefile.am b/src/iccpd/src/Makefile.am new file mode 100644 index 000000000000..9d19dbb5285c --- /dev/null +++ b/src/iccpd/src/Makefile.am @@ -0,0 +1,22 @@ +SUBDIRS = mclagdctl + +INCLUDES = -I$(top_srcdir)/include -I/usr/include/libnl3 + +bin_PROGRAMS = iccpd + +if DEBUG +DBGFLAGS = -ggdb -DDEBUG +else +DBGFLAGS = -g -DNDEBUG +endif + +iccpd_SOURCES = \ + app_csm.c cmd_option.c iccp_cli.c iccp_cmd_show.c iccp_cmd.c \ + iccp_csm.c iccp_ifm.c iccp_main.c logger.c \ + port.c scheduler.c system.c iccp_consistency_check.c \ + mlacp_link_handler.c \ + mlacp_sync_prepare.c mlacp_sync_update.c\ + mlacp_fsm.c \ + iccp_netlink.c +iccpd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) +iccpd_LDADD = -lnl-genl-3 -lnl-route-3 -lnl-3 -lpthread diff --git a/src/iccpd/src/iccp_ifm.c b/src/iccpd/src/iccp_ifm.c index 5cfbfe81ffd3..ea8ce20f05c3 100644 --- a/src/iccpd/src/iccp_ifm.c +++ b/src/iccpd/src/iccp_ifm.c @@ -691,7 +691,7 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui if (!verify_arp) return; - if (iccp_check_if_addr_from_netlink(AF_INET, &addr, arp_lif)) + if (iccp_check_if_addr_from_netlink(AF_INET, (uint8_t *)&addr, arp_lif)) { ICCPD_LOG_DEBUG(__FUNCTION__, "ARP %s is identical with the ip address of interface %s", show_ip_str(arp_msg->ipv4_addr), arp_lif->name); diff --git a/src/iccpd/src/mclagdctl/Makefile b/src/iccpd/src/mclagdctl/Makefile deleted file mode 100644 index 5520da22cee2..000000000000 --- a/src/iccpd/src/mclagdctl/Makefile +++ /dev/null @@ -1,28 +0,0 @@ - - -C = gcc -SOURCES = \ -mclagdctl.c - -OBJECTS = \ -mclagdctl.o - -HEADERS = \ -mclagdctl.h - -CFLAGS = -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -LDFLAGS = -LDADD = - -all: mclagdctl - -%.o: %.c $(HEADERS) - -mclagdctl: $(OBJECTS) - $(CC) -o ./mclagdctl $(OBJECTS) $(LDFLAGS) - -.PHONY: clean -clean: - -rm -f $(OBJECTS) ./mclagdctl - - diff --git a/src/iccpd/src/mclagdctl/Makefile.am b/src/iccpd/src/mclagdctl/Makefile.am new file mode 100644 index 000000000000..124129c5d18e --- /dev/null +++ b/src/iccpd/src/mclagdctl/Makefile.am @@ -0,0 +1,10 @@ +bin_PROGRAMS = mclagdctl + +if DEBUG +DBGFLAGS = -ggdb -DDEBUG +else +DBGFLAGS = -g -DNDEBUG +endif + +mclagdctl_SOURCES = mclagdctl.c +mclagdctl_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) diff --git a/src/iccpd/src/mclagdctl/mclagdctl.c b/src/iccpd/src/mclagdctl/mclagdctl.c index 6e897727887a..630e333be6ed 100644 --- a/src/iccpd/src/mclagdctl/mclagdctl.c +++ b/src/iccpd/src/mclagdctl/mclagdctl.c @@ -1,5 +1,5 @@ /* - /* Copyright(c) 2016-2019 Nephos. + * Copyright(c) 2016-2019 Nephos. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include #include diff --git a/src/iccpd/src/mlacp_sync_prepare.c b/src/iccpd/src/mlacp_sync_prepare.c index a278af51928c..ef1cd244a90a 100644 --- a/src/iccpd/src/mlacp_sync_prepare.c +++ b/src/iccpd/src/mlacp_sync_prepare.c @@ -370,7 +370,7 @@ int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, tlv->icc_parameter.type = htons(TLV_T_MLACP_ARP_INFO); } - ArpData = (struct mLACPMACData *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPARPInfoTLV) + sizeof(struct ARPMsg) * count]; + ArpData = (struct ARPMsg *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPARPInfoTLV) + sizeof(struct ARPMsg) * count]; ArpData->op_type = arp_msg->op_type; sprintf(ArpData->ifname, "%s", arp_msg->ifname); diff --git a/src/iccpd/src/port.c b/src/iccpd/src/port.c index ce23515a00c8..e63429a77c2e 100644 --- a/src/iccpd/src/port.c +++ b/src/iccpd/src/port.c @@ -28,6 +28,8 @@ #include "../include/port.h" #include "../include/system.h" #include "../include/iccp_csm.h" +#include "../include/iccp_netlink.h" +#include "../include/scheduler.h" void local_if_init(struct LocalInterface* local_if) { diff --git a/src/iccpd/src/scheduler.c b/src/iccpd/src/scheduler.c index c1a1532ccfe7..0ff9d4f5e083 100644 --- a/src/iccpd/src/scheduler.c +++ b/src/iccpd/src/scheduler.c @@ -731,7 +731,10 @@ int scheduler_unregister_sock_read_event_callback(struct CSM* csm) return MCLAG_ERROR; } - FD_CLR(csm->sock_fd, &(sys->readfd)); + if (csm->sock_fd > 0) + { + FD_CLR(csm->sock_fd, &(sys->readfd)); + } return 0; } From 0ccdd706718835218fd043f2b53e6a84558c3c09 Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Thu, 21 May 2020 16:27:57 -0700 Subject: [PATCH 0691/1427] [sonic-yang-mgmt]: sonic-yang-mgmt package for configuration validation. (#3861) **- What I did** #### wheel package Makefiles - wheel package Makefiles for sonic-yang-mgmt package. #### libyang Python APIs: - python APIs based on libyang - functions to load/merge yang models and Yang data files - function to validate data trees based on Yang models - functions to merge yang data files/trees - add/set/delete node in schema and data trees - find data/schema nodes from xpath from the Yang data/schema tree in memory - find dependencies - dump the data tree in json/xml #### Extension of libyang Python APIs: -- Cropping input config based on Yang Model. -- Translate input config based on Yang Model. -- rev Translate input config based on Yang Model. -- Find xpath of port, portleaf and a yang list. -- Find if node is key of a list while deletion if yes, then delete the parent. Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com Signed-off-by: Ping Mao pmao@linkedin.com --- .../build_templates/sonic_debian_extension.j2 | 5 + rules/sonic-yang-mgmt-py2.dep | 10 + rules/sonic-yang-mgmt-py2.mk | 9 + slave.mk | 5 +- src/sonic-yang-mgmt/AUTHORS.rst | 15 + src/sonic-yang-mgmt/LICENSE | 13 + src/sonic-yang-mgmt/README.rst | 6 + src/sonic-yang-mgmt/setup.py | 98 +++ src/sonic-yang-mgmt/sonic_yang.py | 659 +++++++++++++++ src/sonic-yang-mgmt/sonic_yang_ext.py | 756 ++++++++++++++++++ src/sonic-yang-mgmt/tests/__init__.py | 3 + .../libyang-python-tests/config_data.json | 260 ++++++ .../config_data_merge.json | 154 ++++ .../sample-yang-models/test-acl.yang | 268 +++++++ .../sample-yang-models/test-head.yang | 66 ++ .../sample-yang-models/test-interface.yang | 72 ++ .../sample-yang-models/test-port.yang | 78 ++ .../sample-yang-models/test-portchannel.yang | 79 ++ .../sample-yang-models/test-vlan.yang | 144 ++++ .../sample_config_db.json | 648 +++++++++++++++ .../libyang-python-tests/test_SonicYang.json | 144 ++++ .../libyang-python-tests/test_sonic_yang.py | 324 ++++++++ .../tests/test_sonic_yang_mgmt.py | 21 + .../tests/yang_model_tests/yangTest.json | 78 +- 24 files changed, 3907 insertions(+), 8 deletions(-) create mode 100644 rules/sonic-yang-mgmt-py2.dep create mode 100644 rules/sonic-yang-mgmt-py2.mk create mode 100644 src/sonic-yang-mgmt/AUTHORS.rst create mode 100644 src/sonic-yang-mgmt/LICENSE create mode 100644 src/sonic-yang-mgmt/README.rst create mode 100644 src/sonic-yang-mgmt/setup.py create mode 100644 src/sonic-yang-mgmt/sonic_yang.py create mode 100644 src/sonic-yang-mgmt/sonic_yang_ext.py create mode 100644 src/sonic-yang-mgmt/tests/__init__.py create mode 100644 src/sonic-yang-mgmt/tests/libyang-python-tests/config_data.json create mode 100644 src/sonic-yang-mgmt/tests/libyang-python-tests/config_data_merge.json create mode 100644 src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-acl.yang create mode 100644 src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-head.yang create mode 100644 src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-interface.yang create mode 100644 src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-port.yang create mode 100644 src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-portchannel.yang create mode 100644 src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-vlan.yang create mode 100644 src/sonic-yang-mgmt/tests/libyang-python-tests/sample_config_db.json create mode 100644 src/sonic-yang-mgmt/tests/libyang-python-tests/test_SonicYang.json create mode 100644 src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py create mode 100644 src/sonic-yang-mgmt/tests/test_sonic_yang_mgmt.py diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 97cd199eceae..81463d20731b 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -132,6 +132,11 @@ SONIC_YANG_MODEL_PY3_WHEEL_NAME=$(basename {{sonic_yang_models_py3_wheel_path}}) sudo cp {{sonic_yang_models_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MODEL_PY3_WHEEL_NAME sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_YANG_MODEL_PY3_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MODEL_PY3_WHEEL_NAME +# Install sonic-yang-mgmt Python package +SONIC_YANG_MGMT_PY_WHEEL_NAME=$(basename {{sonic_yang_mgmt_py_wheel_path}}) +sudo cp {{sonic_yang_mgmt_py_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SONIC_YANG_MGMT_PY_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY_WHEEL_NAME # Install sonic-platform-common Python 2 package PLATFORM_COMMON_PY2_WHEEL_NAME=$(basename {{platform_common_py2_wheel_path}}) diff --git a/rules/sonic-yang-mgmt-py2.dep b/rules/sonic-yang-mgmt-py2.dep new file mode 100644 index 000000000000..a4ec4264b49a --- /dev/null +++ b/rules/sonic-yang-mgmt-py2.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SONIC_YANG_MGMT_PY)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-yang-mgmt-py2.mk rules/sonic-yang-mgmt-py2.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_YANG_MGMT_PY)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_YANG_MGMT_PY)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_YANG_MGMT_PY)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic-yang-mgmt-py2.mk b/rules/sonic-yang-mgmt-py2.mk new file mode 100644 index 000000000000..f438a6bd5116 --- /dev/null +++ b/rules/sonic-yang-mgmt-py2.mk @@ -0,0 +1,9 @@ +# sonic-yang-mgmt python2 wheel + +SONIC_YANG_MGMT_PY = sonic_yang_mgmt-1.0-py2-none-any.whl +$(SONIC_YANG_MGMT_PY)_SRC_PATH = $(SRC_PATH)/sonic-yang-mgmt +$(SONIC_YANG_MGMT_PY)_PYTHON_VERSION = 2 +$(SONIC_YANG_MGMT_PY)_DEBS_DEPENDS = $(LIBYANG) +$(SONIC_YANG_MGMT_PY)_DEPENDS = $(SONIC_YANG_MODELS_PY3) + +SONIC_PYTHON_WHEELS += $(SONIC_YANG_MGMT_PY) diff --git a/slave.mk b/slave.mk index 6f7d53475e6a..34395848a319 100644 --- a/slave.mk +++ b/slave.mk @@ -542,7 +542,6 @@ SONIC_TARGET_LIST += $(addprefix $(PYTHON_DEBS_PATH)/, $(SONIC_PYTHON_STDEB_DEBS $(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) : $(PYTHON_WHEELS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*_DEPENDS))) \ $(call dpkg_depend,$(PYTHON_WHEELS_PATH)/%.dep) \ $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEBS_DEPENDS))) - $(HEADER) # Load the target deb from DPKG cache @@ -786,7 +785,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY)) $(HEADER) # Pass initramfs and linux kernel explicitly. They are used for all platforms export debs_path="$(IMAGE_DISTRO_DEBS_PATH)" @@ -818,6 +818,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" export sonic_yang_models_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3))" + export sonic_yang_mgmt_py_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY))" export multi_instance="false" $(foreach docker, $($*_DOCKERS),\ diff --git a/src/sonic-yang-mgmt/AUTHORS.rst b/src/sonic-yang-mgmt/AUTHORS.rst new file mode 100644 index 000000000000..b5530bc13df3 --- /dev/null +++ b/src/sonic-yang-mgmt/AUTHORS.rst @@ -0,0 +1,15 @@ +======= +Credits +======= + +Development Lead +---------------- + +LNOS-CODERS +MSFT-LINUX-DEV + +Contributors +------------ + +Praveen Chaudhary +Ping Mao diff --git a/src/sonic-yang-mgmt/LICENSE b/src/sonic-yang-mgmt/LICENSE new file mode 100644 index 000000000000..cf593b111eab --- /dev/null +++ b/src/sonic-yang-mgmt/LICENSE @@ -0,0 +1,13 @@ +Copyright 2019 Microsoft, Inc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/src/sonic-yang-mgmt/README.rst b/src/sonic-yang-mgmt/README.rst new file mode 100644 index 000000000000..4d6c90640de8 --- /dev/null +++ b/src/sonic-yang-mgmt/README.rst @@ -0,0 +1,6 @@ +" +This package includes python yang libraries which will be used with sonic utilities +pacakge to validate the config. This python libraries are written on top of libyang +and also provides functionality to translate the config from SONiC ConfigDB to SONiC +YANG and vice-versa. +" diff --git a/src/sonic-yang-mgmt/setup.py b/src/sonic-yang-mgmt/setup.py new file mode 100644 index 000000000000..ab8fafa1ebfb --- /dev/null +++ b/src/sonic-yang-mgmt/setup.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""The setup script.""" + +from setuptools import setup, find_packages +from setuptools.command.build_py import build_py +from os import system, environ +from sys import exit +import pytest + +# find path of pkgs from os environment vars +prefix = '../../'; debs = environ["IMAGE_DISTRO_DEBS_PATH"] +wheels = environ["PYTHON_WHEELS_PATH"] +wheels_path = '{}/{}'.format(prefix, wheels) +deps_path = '{}/{}'.format(prefix, debs) +# dependencies +libyang = '{}/{}'.format(deps_path, environ["LIBYANG"]) +libyangCpp = '{}/{}'.format(deps_path, environ["LIBYANG_CPP"]) +libyangPy2 = '{}/{}'.format(deps_path, environ["LIBYANG_PY2"]) +libyangPy3 = '{}/{}'.format(deps_path, environ["LIBYANG_PY3"]) +sonicYangModels = '{}/{}'.format(wheels_path, environ["SONIC_YANG_MODELS_PY3"]) + +# important reuirements parameters +build_requirements = [libyang, libyangCpp, libyangPy2, libyangPy3, sonicYangModels,] + +setup_requirements = ['pytest-runner'] + +test_requirements = ['pytest>=3'] + +# read me +with open('README.rst') as readme_file: + readme = readme_file.read() + +# class for prerequisites to build this package +class pkgBuild(build_py): + """Custom Build PLY""" + + def run (self): + # install libyang and sonic_yang_models + for req in build_requirements: + if '.deb' in req: + pkg_install_cmd = "sudo dpkg -i {}".format(req) + if (system(pkg_install_cmd)): + print("{} installation failed".format(req)) + exit(1) + else: + print("{} installed".format(req)) + elif '.whl' in req: + pkg_install_cmd = "pip3 install {}".format(req) + if (system(pkg_install_cmd)): + print("{} installation failed".format(req)) + exit(1) + else: + print("{} installed".format(req)) + + # run pytest for libyang python APIs + self.pytest_args = [] + errno = pytest.main(self.pytest_args) + if (errno): + exit(errno) + + # Continue usual build steps + build_py.run(self) + +setup( + cmdclass={ + 'build_py': pkgBuild, + }, + author="lnos-coders", + author_email='lnos-coders@linkedin.com', + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', + classifiers=[ + 'Development Status :: 2 - Pre-Alpha', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', + 'Natural Language :: English', + "Programming Language :: Python :: 2", + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + ], + description="Package contains Python Library for YANG for sonic.", + tests_require = test_requirements, + license="GNU General Public License v3", + long_description=readme + '\n\n', + include_package_data=True, + keywords='sonic_yang_mgmt', + name='sonic_yang_mgmt', + py_modules=['sonic_yang', 'sonic_yang_ext'], + packages=find_packages(), + setup_requires=setup_requirements, + version='1.0', + zip_safe=False, +) diff --git a/src/sonic-yang-mgmt/sonic_yang.py b/src/sonic-yang-mgmt/sonic_yang.py new file mode 100644 index 000000000000..a9ec2f0ad63e --- /dev/null +++ b/src/sonic-yang-mgmt/sonic_yang.py @@ -0,0 +1,659 @@ +import yang as ly +import syslog + +from json import dump +from glob import glob +from sonic_yang_ext import SonicYangExtMixin, SonicYangException + +""" +Yang schema and data tree python APIs based on libyang python +Here, sonic_yang_ext_mixin extends funtionality of sonic_yang, +i.e. it is mixin not parent class. +""" +class SonicYang(SonicYangExtMixin): + + def __init__(self, yang_dir, debug=False): + self.yang_dir = yang_dir + self.ctx = None + self.module = None + self.root = None + + # logging vars + self.SYSLOG_IDENTIFIER = "sonic_yang" + self.DEBUG = debug + + # yang model files, need this map it to module + self.yangFiles = list() + # map from TABLE in config DB to container and module + self.confDbYangMap = dict() + # JSON format of yang model [similar to pyang conversion] + self.yJson = list() + # config DB json input, will be cropped as yang models + self.jIn = dict() + # YANG JSON, this is traslated from config DB json + self.xlateJson = dict() + # reverse translation from yang JSON, == config db json + self.revXlateJson = dict() + # below dict store the input config tables which have no YANG models + self.tablesWithOutYang = dict() + + try: + self.ctx = ly.Context(yang_dir) + except Exception as e: + self.fail(e) + + return + + def __del__(self): + pass + + def sysLog(self, debug=syslog.LOG_INFO, msg=None): + + # log debug only if enabled + if self.DEBUG == False and debug == syslog.LOG_DEBUG: + return + syslog.openlog(self.SYSLOG_IDENTIFIER) + syslog.syslog(debug, msg) + syslog.closelog() + + return + + def fail(self, e): + print(e) + raise e + + """ + load_schema_module(): load a Yang model file + input: yang_file - full path of a Yang model file + returns: Exception if error + """ + def _load_schema_module(self, yang_file): + try: + return self.ctx.parse_module_path(yang_file, ly.LYS_IN_YANG) + except Exception as e: + print("Failed to load yang module file: " + yang_file) + self.fail(e) + + """ + load_schema_module_list(): load all Yang model files in the list + input: yang_files - a list of Yang model file full path + returns: Exception if error + """ + def _load_schema_module_list(self, yang_files): + for file in yang_files: + try: + self._load_schema_module(file) + except Exception as e: + self.fail(e) + + """ + load_schema_modules(): load all Yang model files in the directory + input: yang_dir - the directory of the yang model files to be loaded + returns: Exception if error + """ + def _load_schema_modules(self, yang_dir): + py = glob(yang_dir+"/*.yang") + for file in py: + try: + self._load_schema_module(file) + except Exception as e: + self.fail(e) + + """ + load_schema_modules_ctx(): load all Yang model files in the directory to context: ctx + input: yang_dir, context + returns: Exception if error, returrns context object if no error + """ + def _load_schema_modules_ctx(self, yang_dir=None): + if not yang_dir: + yang_dir = self.yang_dir + + ctx = ly.Context(yang_dir) + + py = glob(yang_dir+"/*.yang") + for file in py: + try: + ctx.parse_module_path(str(file), ly.LYS_IN_YANG) + except Exception as e: + print("Failed to parse yang module file: " + file) + self.fail(e) + + return ctx + + """ + load_data_file(): load a Yang data json file + input: data_file - the full path of the yang json data file to be loaded + returns: Exception if error + """ + def _load_data_file(self, data_file): + try: + data_node = self.ctx.parse_data_path(data_file, ly.LYD_JSON, ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) + except Exception as e: + print("Failed to load data file: " + str(data_file)) + self.fail(e) + else: + self.root = data_node + + """ + get module name from xpath + input: path + returns: module name + """ + def _get_module_name(self, schema_xpath): + module_name = schema_xpath.split(':')[0].strip('/') + return module_name + + """ + get_module(): get module object from Yang module name + input: yang module name + returns: Schema_Node object + """ + def _get_module(self, module_name): + mod = self.ctx.get_module(module_name) + return mod + + """ + load_data_model(): load both Yang module fileis and data json files + input: yang directory, list of yang files and list of data files (full path) + returns: returns (context, root) if no error, or Exception if failed + """ + def _load_data_model(self, yang_dir, yang_files, data_files, output=None): + if (self.ctx is None): + self.ctx = ly.Context(yang_dir) + + try: + self._load_schema_module_list(yang_files) + if len(data_files) == 0: + return (self.ctx, self.root) + + self._load_data_file(data_files[0]) + + for i in range(1, len(data_files)): + self._merge_data(data_files[i]) + except Exception as e: + print("Failed to load data files") + self.fail(e) + return + + if output is not None: + self._print_data_mem(output) + + return (self.ctx, self.root) + + """ + print_data_mem(): print the data tree + input: option: "JSON" or "XML" + """ + def _print_data_mem(self, option): + if (option == "JSON"): + mem = self.root.print_mem(ly.LYD_JSON, ly.LYP_WITHSIBLINGS | ly.LYP_FORMAT) + else: + mem = self.root.print_mem(ly.LYD_XML, ly.LYP_WITHSIBLINGS | ly.LYP_FORMAT) + + return mem + + """ + save_data_file_json(): save the data tree in memory into json file + input: outfile - full path of the file to save the data tree to + """ + def _save_data_file_json(self, outfile): + mem = self.root.print_mem(ly.LYD_JSON, ly.LYP_FORMAT) + with open(outfile, 'w') as out: + dump(mem, out, indent=4) + + """ + get_module_tree(): get yang module tree in JSON or XMAL format + input: module name + returns: JSON or XML format of the input yang module schema tree + """ + def _get_module_tree(self, module_name, format): + result = None + + try: + module = self.ctx.get_module(str(module_name)) + except Exception as e: + print("Cound not get module: " + str(module_name)) + self.fail(e) + else: + if (module is not None): + if (format == "XML"): + #libyang bug with format + result = module.print_mem(ly.LYD_JSON, ly.LYP_FORMAT) + else: + result = module.print_mem(ly.LYD_XML, ly.LYP_FORMAT) + + return result + + """ + validate_data(): validate data tree + input: + node: root of the data tree + ctx: context + returns: Exception if failed + """ + def _validate_data(self, node=None, ctx=None): + if not node: + node = self.root + + if not ctx: + ctx = self.ctx + + try: + node.validate(ly.LYD_OPT_CONFIG, ctx) + except Exception as e: + self.fail(e) + + """ + validate_data_tree(): validate the data tree. (Public) + returns: Exception if failed + """ + def validate_data_tree(self): + try: + self._validate_data(self.root, self.ctx) + except Exception as e: + print("Failed to validate data tree") + raise SonicYangException("Failed to validate data tree\n{}".\ + format(str(e))) + + """ + find_parent_data_node(): find the parent node object + input: data_xpath - xpath of the data node + returns: parent node + """ + def _find_parent_data_node(self, data_xpath): + if (self.root is None): + print("data not loaded") + return None + try: + data_node = self._find_data_node(data_xpath) + except Exception as e: + print("Failed to find data node from xpath: " + str(data_xpath)) + self.fail(e) + else: + if data_node is not None: + return data_node.parent() + + return None + + """ + get_parent_data_xpath(): find the parent data node's xpath + input: data_xpath - xpathof the data node + returns: - xpath of parent data node + - Exception if error + """ + def _get_parent_data_xpath(self, data_xpath): + path="" + try: + data_node = self._find_parent_data_node(data_xpath) + except Exception as e: + print("Failed to find parent node from xpath: " + str(data_xpath)) + self.fail(e) + else: + if data_node is not None: + path = data_node.path() + return path + + """ + new_data_node(): create a new data node in the data tree + input: + xpath: xpath of the new node + value: value of the new node + returns: new Data_Node object if success, Exception if falied + """ + def _new_data_node(self, xpath, value): + val = str(value) + try: + data_node = self.root.new_path(self.ctx, xpath, val, 0, 0) + except Exception as e: + print("Failed to add data node for path: " + str(xpath)) + self.fail(e) + else: + return data_node + + """ + find_data_node(): find the data node from xpath + input: data_xpath: xpath of the data node + returns - Data_Node object if found + - None if not exist + - Exception if there is error + """ + def _find_data_node(self, data_xpath): + try: + set = self.root.find_path(data_xpath) + except Exception as e: + print("Failed to find data node from xpath: " + str(data_xpath)) + self.fail(e) + else: + if set is not None: + for data_node in set.data(): + if (data_xpath == data_node.path()): + return data_node + return None + """ + find_schema_node(): find the schema node from schema xpath + example schema xpath: + "/sonic-port:sonic-port/sonic-port:PORT/sonic-port:PORT_LIST/sonic-port:port_name" + input: xpath of the node + returns: Schema_Node oject or None if not found + """ + def _find_schema_node(self, schema_xpath): + try: + schema_set = self.ctx.find_path(schema_xpath) + for schema_node in schema_set.schema(): + if (schema_xpath == schema_node.path()): + return schema_node + except Exception as e: + self.fail(e) + return None + else: + for schema_node in schema_set.schema(): + if schema_xapth == schema_node.path(): + return schema_node + return None + """ + find_data_node_schema_xpath(): find the xpath of the schema node from data xpath + data xpath example: + "/sonic-port:sonic-port/PORT/PORT_LIST[port_name='Ethernet0']/port_name" + input: data_xpath - xpath of the data node + returns: - xpath of the schema node if success + - Exception if error + """ + def _find_data_node_schema_xpath(self, data_xpath): + path = "" + try: + set = self.root.find_path(data_xpath) + except Exception as e: + self.fail(e) + else: + for data_node in set.data(): + if data_xpath == data_node.path(): + return data_node.schema().path() + return path + + """ + add_node(): add a node to Yang schema or data tree + input: xpath and value of the node to be added + returns: Exception if failed + """ + def _add_data_node(self, data_xpath, value): + try: + self._new_data_node(data_xpath, value) + #check if the node added to the data tree + self._find_data_node(data_xpath) + except Exception as e: + print("add_node(): Failed to add data node for xpath: " + str(data_xpath)) + self.fail(e) + + """ + merge_data(): merge a data file to the existing data tree + input: yang model directory and full path of the data json file to be merged + returns: Exception if failed + """ + def _merge_data(self, data_file, yang_dir=None): + #load all yang models to ctx + if not yang_dir: + yang_dir = self.yang_dir + + try: + ctx = self._load_schema_modules_ctx(yang_dir) + + #source data node + source_node = ctx.parse_data_path(str(data_file), ly.LYD_JSON, ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) + + #merge + self.root.merge(source_node, 0) + except Exception as e: + self.fail(e) + + """ + _deleteNode(): delete a node from the schema/data tree, internal function + input: xpath of the schema/data node + returns: True - success False - failed + """ + def _deleteNode(self, xpath=None, node=None): + if node is None: + node = self._find_data_node(xpath) + + if (node): + node.unlink() + dnode = self._find_data_node(xpath) + if (dnode is None): + #deleted node not found + return True + else: + print('Could not delete Node') + return False + else: + print("failed to find node, xpath: " + xpath) + + return False + + """ + find_data_node_value(): find the value of a node from the data tree + input: data_xpath of the data node + returns: value string of the node + """ + def _find_data_node_value(self, data_xpath): + output = "" + try: + data_node = self._find_data_node(data_xpath) + except Exception as e: + print("find_data_node_value(): Failed to find data node from xpath: {}".format(data_xpath)) + self.fail(e) + else: + if (data_node is not None): + subtype = data_node.subtype() + if (subtype is not None): + value = subtype.value_str() + return value + return output + + """ + set the value of a node in the data tree + input: xpath of the data node + returns: Exception if failed + """ + def _set_data_node_value(self, data_xpath, value): + try: + self.root.new_path(self.ctx, data_xpath, str(value), ly.LYD_ANYDATA_STRING, ly.LYD_PATH_OPT_UPDATE) + except Exception as e: + print("set data node value failed for xpath: " + str(data_xpath)) + self.fail(e) + + """ + find_data_nodes(): find the set of nodes for the xpath + input: xpath of the data node + returns: list of xpath of the dataset + """ + def _find_data_nodes(self, data_xpath): + list = [] + node = self.root.child() + try: + node_set = node.find_path(data_xpath); + except Exception as e: + self.fail(e) + else: + if node_set is None: + raise Exception('data node not found') + + for data_set in node_set.data(): + data_set.schema() + list.append(data_set.path()) + return list + + """ + find_schema_dependencies(): find the schema dependencies from schema xpath + input: schema_xpath of the schema node + returns: - list of xpath of the dependencies + - Exception if schema node not found + """ + def _find_schema_dependencies(self, schema_xpath): + ref_list = [] + try: + schema_node = self._find_schema_node(schema_xpath) + except Exception as e: + print("Cound not find the schema node from xpath: " + str(schema_xpath)) + self.fail(e) + return ref_list + + schema_node = ly.Schema_Node_Leaf(schema_node) + backlinks = schema_node.backlinks() + if backlinks.number() > 0: + for link in backlinks.schema(): + print("backlink schema: {}".format(link.path())) + ref_list.append(link.path()) + return ref_list + + """ + find_data_dependencies(): find the data dependencies from data xpath + input: data_xpath - xpath of data node. (Public) + returns: - list of xpath + - Exception if error + """ + def find_data_dependencies(self, data_xpath): + ref_list = [] + node = self.root + try: + data_node = self._find_data_node(data_xpath) + except Exception as e: + print("find_data_dependencies(): Failed to find data node from xpath: {}".format(data_xapth)) + return ref_list + + try: + value = str(self._find_data_node_value(data_xpath)) + + schema_node = ly.Schema_Node_Leaf(data_node.schema()) + backlinks = schema_node.backlinks() + if backlinks.number() > 0: + for link in backlinks.schema(): + node_set = node.find_path(link.path()) + for data_set in node_set.data(): + data_set.schema() + casted = data_set.subtype() + if value == casted.value_str(): + ref_list.append(data_set.path()) + except Exception as e: + print('Failed to find node or dependencies for {}'.format(data_xpath)) + raise SonicYangException("Failed to find node or dependencies for \ + {}\n{}".format(data_xpath, str(e))) + + return ref_list + + """ + get_module_prefix: get the prefix of a Yang module + input: name of the Yang module + output: prefix of the Yang module + """ + def _get_module_prefix(self, module_name): + prefix = "" + try: + module = self._get_module(module_name) + except Exception as e: + self.fail(e) + return prefix + else: + return module.prefix() + + """ + str_to_type: map string to type of node + input: string + output: type + """ + def _str_to_type(self, type_str): + mapped_type = { + "LY_TYPE_DER":ly.LY_TYPE_DER, + "LY_TYPE_BINARY":ly.LY_TYPE_BINARY, + "LY_TYPE_BITS":ly.LY_TYPE_BITS, + "LY_TYPE_BOOL":ly.LY_TYPE_BOOL, + "LY_TYPE_DEC64":ly.LY_TYPE_DEC64, + "LY_TYPE_EMPTY":ly.LY_TYPE_EMPTY, + "LY_TYPE_ENUM":ly.LY_TYPE_ENUM, + "LY_TYPE_IDENT":ly.LY_TYPE_IDENT, + "LY_TYPE_INST":ly.LY_TYPE_INST, + "LY_TYPE_LEAFREF":ly.LY_TYPE_LEAFREF, + "LY_TYPE_STRING":ly.LY_TYPE_STRING, + "LY_TYPE_UNION":ly.LY_TYPE_UNION, + "LY_TYPE_INT8":ly.LY_TYPE_INT8, + "LY_TYPE_UINT8":ly.LY_TYPE_UINT8, + "LY_TYPE_INT16":ly.LY_TYPE_INT16, + "LY_TYPE_UINT16":ly.LY_TYPE_UINT16, + "LY_TYPE_INT32":ly.LY_TYPE_INT32, + "LY_TYPE_UINT32":ly.LY_TYPE_UINT32, + "LY_TYPE_INT64":ly.LY_TYPE_INT64, + "LY_TYPE_UINT64":ly.LY_TYPE_UINT64, + "LY_TYPE_UNKNOWN":ly.LY_TYPE_UNKNOWN + } + + if type_str not in mapped_type: + return ly.LY_TYPE_UNKNOWN + + return mapped_type[type_str] + + def _get_data_type(self, schema_xpath): + try: + schema_node = self._find_schema_node(schema_xpath) + except Exception as e: + print("get_data_type(): Failed to find schema node from xpath: {}".format(schema_xpath)) + self.fail(e) + return None + + if (schema_node is not None): + return schema_node.subtype().type().base() + + return ly.LY_TYPE_UNKNOWN + + """ + get_leafref_type: find the type of node that leafref references to + input: data_xpath - xpath of a data node + output: type of the node this leafref references to + """ + def _get_leafref_type(self, data_xpath): + data_node = self._find_data_node(data_xpath) + if (data_node is not None): + subtype = data_node.subtype() + if (subtype is not None): + if data_node.schema().subtype().type().base() != ly.LY_TYPE_LEAFREF: + print("get_leafref_type() node type for data xpath: {} is not LEAFREF".format(data_xpath)) + return ly.LY_TYPE_UNKNOWN + else: + return subtype.value_type() + + return ly.LY_TYPE_UNKNOWN + + """ + get_leafref_path(): find the leafref path + input: schema_xpath - xpath of a schema node + output: path value of the leafref node + """ + def _get_leafref_path(self, schema_xpath): + schema_node = self._find_schema_node(schema_xpath) + if (schema_node is not None): + subtype = schema_node.subtype() + if (subtype is not None): + if subtype.type().base() != ly.LY_TYPE_LEAFREF: + return None + else: + return subtype.type().info().lref().path() + + return None + + """ + get_leafref_type_schema: find the type of node that leafref references to + input: schema_xpath - xpath of a schema node + output: type of the node this leafref references to + """ + def _get_leafref_type_schema(self, schema_xpath): + schema_node = self._find_schema_node(schema_xpath) + if (schema_node is not None): + subtype = schema_node.subtype() + if (subtype is not None): + if subtype.type().base() != ly.LY_TYPE_LEAFREF: + return None + else: + subtype.type().info().lref().path() + target = subtype.type().info().lref().target() + target_path = target.path() + target_type = self._get_data_type(target_path) + return target_type + + return None diff --git a/src/sonic-yang-mgmt/sonic_yang_ext.py b/src/sonic-yang-mgmt/sonic_yang_ext.py new file mode 100644 index 000000000000..3cfad3aaaf63 --- /dev/null +++ b/src/sonic-yang-mgmt/sonic_yang_ext.py @@ -0,0 +1,756 @@ +# This script is used as extension of sonic_yang class. It has methods of +# class sonic_yang. A separate file is used to avoid a single large file. + +from __future__ import print_function +import yang as ly +import re +import syslog + +from json import dump, dumps, loads +from xmltodict import parse +from glob import glob + +""" +This is the Exception thrown out of all public function of this class. +""" +class SonicYangException(Exception): + pass + +# class sonic_yang methods, use mixin to extend sonic_yang +class SonicYangExtMixin: + + """ + load all YANG models, create JSON of yang models. (Public function) + """ + def loadYangModel(self): + + try: + # get all files + self.yangFiles = glob(self.yang_dir +"/*.yang") + # load yang modules + for file in self.yangFiles: + m = self._load_schema_module(file) + if m is not None: + self.sysLog(msg="module: {} is loaded successfully".format(m.name())) + else: + raise(Exception("Could not load module {}".format(file))) + + # keep only modules name in self.yangFiles + self.yangFiles = [f.split('/')[-1] for f in self.yangFiles] + self.yangFiles = [f.split('.')[0] for f in self.yangFiles] + print('Loaded below Yang Models') + print(self.yangFiles) + + # load json for each yang model + self._loadJsonYangModel() + # create a map from config DB table to yang container + self._createDBTableToModuleMap() + + except Exception as e: + print("Yang Models Load failed") + raise SonicYangException("Yang Models Load failed\n{}".format(str(e))) + + return True + + """ + load JSON schema format from yang models + """ + def _loadJsonYangModel(self): + + try: + for f in self.yangFiles: + m = self.ctx.get_module(f) + if m is not None: + xml = m.print_mem(ly.LYD_JSON, ly.LYP_FORMAT) + self.yJson.append(parse(xml)) + self.sysLog(msg="Parsed Json for {}".format(m.name())) + except Exception as e: + raise e + + return + + """ + Create a map from config DB tables to container in yang model + This module name and topLevelContainer are fetched considering YANG models are + written using below Guidelines: + https://github.com/Azure/SONiC/blob/master/doc/mgmt/SONiC_YANG_Model_Guidelines.md. + """ + def _createDBTableToModuleMap(self): + + for j in self.yJson: + # get module name + moduleName = j['module']['@name'] + # get top level container + topLevelContainer = j['module'].get('container') + # if top level container is none, this is common yang files, which may + # have definitions. Store module. + if topLevelContainer is None: + self.confDbYangMap[moduleName] = j['module'] + continue + + # top level container must exist for rest of the yang files and it should + # have same name as module name. + assert topLevelContainer['@name'] == moduleName + + # Each container inside topLevelContainer maps to a sonic config table. + container = topLevelContainer['container'] + # container is a list + if isinstance(container, list): + for c in container: + self.confDbYangMap[c['@name']] = { + "module" : moduleName, + "topLevelContainer": topLevelContainer['@name'], + "container": c + } + # container is a dict + else: + self.confDbYangMap[container['@name']] = { + "module" : moduleName, + "topLevelContainer": topLevelContainer['@name'], + "container": container + } + return + + """ + Get module, topLevelContainer(TLC) and json container for a config DB table + """ + def _getModuleTLCcontainer(self, table): + cmap = self.confDbYangMap + m = cmap[table]['module'] + t = cmap[table]['topLevelContainer'] + c = cmap[table]['container'] + return m, t, c + + """ + Crop config as per yang models, + This Function crops from config only those TABLEs, for which yang models is + provided. The Tables without YANG models are stored in + self.tablesWithOutYangModels. + """ + def _cropConfigDB(self, croppedFile=None): + + for table in self.jIn.keys(): + if table not in self.confDbYangMap: + # store in tablesWithOutYang + self.tablesWithOutYang[table] = self.jIn[table] + del self.jIn[table] + + if len(self.tablesWithOutYang): + print("Note: Below table(s) have no YANG models:") + for table in self.tablesWithOutYang.keys(): + print(unicode(table), end=", ") + print() + + if croppedFile: + with open(croppedFile, 'w') as f: + dump(self.jIn, f, indent=4) + + return + + """ + Extract keys from table entry in Config DB and return in a dict + + Input: + tableKey: Config DB Primary Key, Example tableKey = "Vlan111|2a04:5555:45:6709::1/64" + keys: key string from YANG list, i.e. 'vlan_name ip-prefix'. + regex: A regex to extract keys from tableKeys, good to have it as accurate as possible. + + Return: + KeyDict = {"vlan_name": "Vlan111", "ip-prefix": "2a04:5555:45:6709::1/64"} + """ + def _extractKey(self, tableKey, keys, regex): + + keyList = keys.split() + # get the value groups + value = re.match(regex, tableKey) + # create the keyDict + i = 1 + keyDict = dict() + for k in keyList: + if value.group(i): + keyDict[k] = value.group(i) + else: + raise Exception("Value not found for {} in {}".format(k, tableKey)) + i = i + 1 + + return keyDict + + """ + Fill the dict based on leaf as a list or dict @model yang model object + """ + def _fillLeafDict(self, leafs, leafDict, isleafList=False): + + if leafs is None: + return + + # fill default values + def _fillSteps(leaf): + leaf['__isleafList'] = isleafList + leafDict[leaf['@name']] = leaf + return + + if isinstance(leafs, list): + for leaf in leafs: + #print("{}:{}".format(leaf['@name'], leaf)) + _fillSteps(leaf) + else: + #print("{}:{}".format(leaf['@name'], leaf)) + _fillSteps(leafs) + + return + + """ + create a dict to map each key under primary key with a dict yang model. + This is done to improve performance of mapping from values of TABLEs in + config DB to leaf in YANG LIST. + """ + def _createLeafDict(self, model): + + leafDict = dict() + #Iterate over leaf, choices and leaf-list. + self._fillLeafDict(model.get('leaf'), leafDict) + + #choices, this is tricky, since leafs are under cases in tree. + choices = model.get('choice') + if choices: + for choice in choices: + cases = choice['case'] + for case in cases: + self._fillLeafDict(case.get('leaf'), leafDict) + + # leaf-lists + self._fillLeafDict(model.get('leaf-list'), leafDict, True) + + return leafDict + + """ + Convert a string from Config DB value to Yang Value based on type of the + key in Yang model. + @model : A List of Leafs in Yang model list + """ + def _findYangTypedValue(self, key, value, leafDict): + + # convert config DB string to yang Type + def _yangConvert(val): + # Convert everything to string + val = str(val) + # find type of this key from yang leaf + type = leafDict[key]['type']['@name'] + + if 'uint' in type: + vValue = int(val, 10) + # TODO: find type of leafref from schema node + elif 'leafref' in type: + vValue = val + #TODO: find type in sonic-head, as of now, all are enumeration + elif 'head:' in type: + vValue = val + else: + vValue = val + return vValue + + # if it is a leaf-list do it for each element + if leafDict[key]['__isleafList']: + vValue = list() + for v in value: + vValue.append(_yangConvert(v)) + else: + vValue = _yangConvert(value) + + return vValue + + """ + Xlate a list + This function will xlate from a dict in config DB to a Yang JSON list + using yang model. Output will be go in self.xlateJson + """ + def _xlateList(self, model, yang, config, table): + + #create a dict to map each key under primary key with a dict yang model. + #This is done to improve performance of mapping from values of TABLEs in + #config DB to leaf in YANG LIST. + leafDict = self._createLeafDict(model) + + # fetch regex from YANG models. + keyRegEx = model['ext:key-regex-configdb-to-yang']['@value'] + # seperator `|` has special meaning in regex, so change it appropriately. + keyRegEx = re.sub('\|', '\\|', keyRegEx) + # get keys from YANG model list itself + listKeys = model['key']['@value'] + self.sysLog(msg="xlateList regex:{} keyList:{}".\ + format(keyRegEx, listKeys)) + + for pkey in config.keys(): + try: + vKey = None + self.sysLog(syslog.LOG_DEBUG, "xlateList Extract pkey:{}".\ + format(pkey)) + # Find and extracts key from each dict in config + keyDict = self._extractKey(pkey, listKeys, keyRegEx) + # fill rest of the values in keyDict + for vKey in config[pkey]: + self.sysLog(syslog.LOG_DEBUG, "xlateList vkey {}".format(vKey)) + keyDict[vKey] = self._findYangTypedValue(vKey, \ + config[pkey][vKey], leafDict) + yang.append(keyDict) + # delete pkey from config, done to match one key with one list + del config[pkey] + + except Exception as e: + # log debug, because this exception may occur with multilists + self.sysLog(syslog.LOG_DEBUG, "xlateList Exception {}".format(e)) + # with multilist, we continue matching other keys. + continue + + return + + """ + Process list inside a Container. + This function will call xlateList based on list(s) present in Container. + """ + def _xlateListInContainer(self, model, yang, configC, table): + clist = model + #print(clist['@name']) + yang[clist['@name']] = list() + self.sysLog(msg="xlateProcessListOfContainer: {}".format(clist['@name'])) + self._xlateList(clist, yang[clist['@name']], configC, table) + # clean empty lists + if len(yang[clist['@name']]) == 0: + del yang[clist['@name']] + + return + + """ + Process container inside a Container. + This function will call xlateContainer based on Container(s) present + in outer Container. + """ + def _xlateContainerInContainer(self, model, yang, configC, table): + ccontainer = model + #print(ccontainer['@name']) + yang[ccontainer['@name']] = dict() + if not configC.get(ccontainer['@name']): + return + self.sysLog(msg="xlateProcessListOfContainer: {}".format(ccontainer['@name'])) + self._xlateContainer(ccontainer, yang[ccontainer['@name']], \ + configC[ccontainer['@name']], table) + # clean empty container + if len(yang[ccontainer['@name']]) == 0: + del yang[ccontainer['@name']] + # remove copy after processing + del configC[ccontainer['@name']] + + return + + """ + Xlate a container + This function will xlate from a dict in config DB to a Yang JSON container + using yang model. Output will be stored in self.xlateJson + """ + def _xlateContainer(self, model, yang, config, table): + + # To Handle multiple Lists, Make a copy of config, because we delete keys + # from config after each match. This is done to match one pkey with one list. + configC = config.copy() + + clist = model.get('list') + # If single list exists in container, + if clist and isinstance(clist, dict) and \ + clist['@name'] == model['@name']+"_LIST" and bool(configC): + self._xlateListInContainer(clist, yang, configC, table) + # If multi-list exists in container, + elif clist and isinstance(clist, list) and bool(configC): + for modelList in clist: + self._xlateListInContainer(modelList, yang, configC, table) + + # Handle container(s) in container + ccontainer = model.get('container') + # If single list exists in container, + if ccontainer and isinstance(ccontainer, dict) and bool(configC): + self._xlateContainerInContainer(ccontainer, yang, configC, table) + # If multi-list exists in container, + elif ccontainer and isinstance(ccontainer, list) and bool(configC): + for modelContainer in ccontainer: + self._xlateContainerInContainer(modelContainer, yang, configC, table) + + ## Handle other leaves in container, + leafDict = self._createLeafDict(model) + for vKey in configC.keys(): + #vkey must be a leaf\leaf-list\choice in container + if leafDict.get(vKey): + self.sysLog(syslog.LOG_DEBUG, "xlateContainer vkey {}".format(vKey)) + yang[vKey] = self._findYangTypedValue(vKey, configC[vKey], leafDict) + # delete entry from copy of config + del configC[vKey] + + # All entries in copy of config must have been parsed. + if len(configC): + self.sysLog(syslog.LOG_ERR, "Alert: Remaining keys in Config") + raise(Exception("All Keys are not parsed in {}\n{}".format(table, \ + configC.keys()))) + + return + + """ + xlate ConfigDB json to Yang json + """ + def _xlateConfigDBtoYang(self, jIn, yangJ): + + # find top level container for each table, and run the xlate_container. + for table in jIn.keys(): + cmap = self.confDbYangMap[table] + # create top level containers + key = cmap['module']+":"+cmap['topLevelContainer'] + subkey = cmap['topLevelContainer']+":"+cmap['container']['@name'] + # Add new top level container for first table in this container + yangJ[key] = dict() if yangJ.get(key) is None else yangJ[key] + yangJ[key][subkey] = dict() + self.sysLog(msg="xlateConfigDBtoYang {}:{}".format(key, subkey)) + self._xlateContainer(cmap['container'], yangJ[key][subkey], \ + jIn[table], table) + + return + + """ + Read config file and crop it as per yang models + """ + def _xlateConfigDB(self, xlateFile=None): + + jIn= self.jIn + yangJ = self.xlateJson + # xlation is written in self.xlateJson + self._xlateConfigDBtoYang(jIn, yangJ) + + if xlateFile: + with open(xlateFile, 'w') as f: + dump(self.xlateJson, f, indent=4) + + return + + """ + create config DB table key from entry in yang JSON + """ + def _createKey(self, entry, regex): + + keyDict = dict() + keyV = regex + # get the keys from regex of key extractor + keyList = re.findall(r'<(.*?)>', regex) + for key in keyList: + val = entry.get(key) + if val: + #print("pair: {} {}".format(key, val)) + keyDict[key] = sval = str(val) + keyV = re.sub(r'<'+key+'>', sval, keyV) + #print("VAL: {} {}".format(regex, keyV)) + else: + raise Exception("key {} not found in entry".format(key)) + #print("kDict {}".format(keyDict)) + return keyV, keyDict + + """ + Convert a string from Config DB value to Yang Value based on type of the + key in Yang model. + @model : A List of Leafs in Yang model list + """ + def _revFindYangTypedValue(self, key, value, leafDict): + + # convert yang Type to config DB string + def _revYangConvert(val): + # config DB has only strings, thank god for that :), wait not yet!!! + return str(val) + + # if it is a leaf-list do it for each element + if leafDict[key]['__isleafList']: + vValue = list() + for v in value: + vValue.append(_revYangConvert(v)) + else: + vValue = _revYangConvert(value) + + return vValue + + """ + Rev xlate from _LIST to table in config DB + """ + def _revXlateList(self, model, yang, config, table): + + # fetch regex from YANG models + keyRegEx = model['ext:key-regex-yang-to-configdb']['@value'] + self.sysLog(msg="revXlateList regex:{}".format(keyRegEx)) + + # create a dict to map each key under primary key with a dict yang model. + # This is done to improve performance of mapping from values of TABLEs in + # config DB to leaf in YANG LIST. + leafDict = self._createLeafDict(model) + + # list with name _LIST should be removed, + if "_LIST" in model['@name']: + for entry in yang: + # create key of config DB table + pkey, pkeydict = self._createKey(entry, keyRegEx) + self.sysLog(syslog.LOG_DEBUG, "revXlateList pkey:{}".format(pkey)) + config[pkey]= dict() + # fill rest of the entries + for key in entry: + if key not in pkeydict: + config[pkey][key] = self._revFindYangTypedValue(key, \ + entry[key], leafDict) + + return + + """ + Rev xlate a list inside a yang container + """ + def _revXlateListInContainer(self, model, yang, config, table): + modelList = model + # Pass matching list from Yang Json if exist + if yang.get(modelList['@name']): + self.sysLog(msg="revXlateListInContainer {}".format(modelList['@name'])) + self._revXlateList(modelList, yang[modelList['@name']], config, table) + return + + """ + Rev xlate a container inside a yang container + """ + def _revXlateContainerInContainer(self, model, yang, config, table): + modelContainer = model + # Pass matching list from Yang Json if exist + if yang.get(modelContainer['@name']): + config[modelContainer['@name']] = dict() + self.sysLog(msg="revXlateContainerInContainer {}".format(modelContainer['@name'])) + self._revXlateContainer(modelContainer, yang[modelContainer['@name']], \ + config[modelContainer['@name']], table) + return + + """ + Rev xlate from yang container to table in config DB + """ + def _revXlateContainer(self, model, yang, config, table): + + # IF container has only one list + clist = model.get('list') + if isinstance(clist, dict): + self._revXlateListInContainer(clist, yang, config, table) + # IF container has lists + elif isinstance(clist, list): + for modelList in clist: + self._revXlateListInContainer(modelList, yang, config, table) + + ccontainer = model.get('container') + # IF container has only one inner container + if isinstance(ccontainer, dict): + self._revXlateContainerInContainer(ccontainer, yang, config, table) + # IF container has only many inner container + elif isinstance(ccontainer, list): + for modelContainer in ccontainer: + self._revXlateContainerInContainer(modelContainer, yang, config, table) + + ## Handle other leaves in container, + leafDict = self._createLeafDict(model) + for vKey in yang: + #vkey must be a leaf\leaf-list\choice in container + if leafDict.get(vKey): + self.sysLog(syslog.LOG_DEBUG, "revXlateContainer vkey {}".format(vKey)) + config[vKey] = self._revFindYangTypedValue(vKey, yang[vKey], leafDict) + + return + + """ + rev xlate ConfigDB json to Yang json + """ + def _revXlateYangtoConfigDB(self, yangJ, cDbJson): + + yangJ = self.xlateJson + cDbJson = self.revXlateJson + + # find table in config DB, use name as a KEY + for module_top in yangJ.keys(): + # module _top will be of from module:top + for container in yangJ[module_top].keys(): + #table = container.split(':')[1] + table = container + #print("revXlate " + table) + cmap = self.confDbYangMap[table] + cDbJson[table] = dict() + #print(key + "--" + subkey) + self.sysLog(msg="revXlateYangtoConfigDB {}".format(table)) + self._revXlateContainer(cmap['container'], yangJ[module_top][container], \ + cDbJson[table], table) + + return + + """ + Reverse Translate tp config DB + """ + def _revXlateConfigDB(self, revXlateFile=None): + + yangJ = self.xlateJson + cDbJson = self.revXlateJson + # xlation is written in self.xlateJson + self._revXlateYangtoConfigDB(yangJ, cDbJson) + + if revXlateFile: + with open(revXlateFile, 'w') as f: + dump(self.revXlateJson, f, indent=4) + + return + + """ + Find a list in YANG Container + c = container + l = list name + return: list if found else None + """ + def _findYangList(self, container, listName): + + if isinstance(container['list'], dict): + clist = container['list'] + if clist['@name'] == listName: + return clist + + elif isinstance(container['list'], list): + clist = [l for l in container['list'] if l['@name'] == listName] + return clist[0] + + return None + + """ + Find xpath of the PORT Leaf in PORT container/list. Xpath of Leaf is needed, + because only leaf can have leafrefs depend on them. (Public) + """ + def findXpathPortLeaf(self, portName): + + try: + table = "PORT" + xpath = self.findXpathPort(portName) + module, topc, container = self._getModuleTLCcontainer(table) + list = self._findYangList(container, table+"_LIST") + xpath = xpath + "/" + list['key']['@value'].split()[0] + except Exception as e: + print("find xpath of port Leaf failed") + raise SonicYangException("find xpath of port Leaf failed\n{}".format(str(e))) + + return xpath + + """ + Find xpath of PORT. (Public) + """ + def findXpathPort(self, portName): + + try: + table = "PORT" + module, topc, container = self._getModuleTLCcontainer(table) + xpath = "/" + module + ":" + topc + "/" + table + + list = self._findYangList(container, table+"_LIST") + xpath = self._findXpathList(xpath, list, [portName]) + except Exception as e: + print("find xpath of port failed") + raise SonicYangException("find xpath of port failed\n{}".format(str(e))) + + return xpath + + """ + Find xpath of a YANG LIST from keys, + xpath: xpath till list + list: YANG List + keys: list of keys in YANG LIST + """ + def _findXpathList(self, xpath, list, keys): + + try: + # add list name in xpath + xpath = xpath + "/" + list['@name'] + listKeys = list['key']['@value'].split() + i = 0; + for listKey in listKeys: + xpath = xpath + '['+listKey+'=\''+keys[i]+'\']' + i = i + 1 + except Exception as e: + raise e + + return xpath + + """ + load_data: load Config DB, crop, xlate and create data tree from it. (Public) + input: data + returns: True - success False - failed + """ + def loadData(self, configdbJson): + + try: + self.jIn = configdbJson + # reset xlate and tablesWithOutYang + self.xlateJson = dict() + self.tablesWithOutYang = dict() + # self.jIn will be cropped + self._cropConfigDB() + # xlated result will be in self.xlateJson + self._xlateConfigDB() + #print(self.xlateJson) + self.sysLog(msg="Try to load Data in the tree") + self.root = self.ctx.parse_data_mem(dumps(self.xlateJson), \ + ly.LYD_JSON, ly.LYD_OPT_CONFIG|ly.LYD_OPT_STRICT) + + except Exception as e: + self.root = None + print("Data Loading Failed") + raise SonicYangException("Data Loading Failed\n{}".format(str(e))) + + return True + + """ + Get data from Data tree, data tree will be assigned in self.xlateJson. (Public) + """ + def getData(self): + + try: + self.xlateJson = loads(self._print_data_mem('JSON')) + # reset reverse xlate + self.revXlateJson = dict() + # result will be stored self.revXlateJson + self._revXlateConfigDB() + + except Exception as e: + print("Get Data Tree Failed") + raise SonicYangException("Get Data Tree Failed\n{}".format(str(e))) + + return self.revXlateJson + + """ + Delete a node from data tree, if this is LEAF and KEY Delete the Parent. + (Public) + """ + def deleteNode(self, xpath): + + # These MACROS used only here, can we get it from Libyang Header ? + try: + LYS_LEAF = 4 + node = self._find_data_node(xpath) + if node is None: + raise('Node {} not found'.format(xpath)) + + snode = node.schema() + # check for a leaf if it is a key. If yes delete the parent + if (snode.nodetype() == LYS_LEAF): + leaf = ly.Schema_Node_Leaf(snode) + if leaf.is_key(): + # try to delete parent + nodeP = self._find_parent_data_node(xpath) + xpathP = nodeP.path() + if self._deleteNode(xpath=xpathP, node=nodeP) == False: + raise Exception('_deleteNode failed') + else: + return True + + # delete non key element + if self._deleteNode(xpath=xpath, node=node) == False: + raise Exception('_deleteNode failed') + except Exception as e: + raise SonicYangException("Failed to delete node {}\n{}".\ + format( xpath, str(e))) + + return True + + # End of class sonic_yang diff --git a/src/sonic-yang-mgmt/tests/__init__.py b/src/sonic-yang-mgmt/tests/__init__.py new file mode 100644 index 000000000000..ec983d6590c7 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +"""Unit test package for sonic_yang_mgmt.""" diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data.json b/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data.json new file mode 100644 index 000000000000..8a4eaed176d2 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data.json @@ -0,0 +1,260 @@ +{ + "test-vlan:vlan": { + "test-vlan:VLAN_INTERFACE": { + "VLAN_INTERFACE_LIST": [{ + "vlanid": 111, + "ip-prefix": "2000:f500:45:6709::1/64", + "scope": "global", + "family": "IPv6" + }, + { + "vlanid": 111, + "ip-prefix": "10.1.1.65/26", + "scope": "global", + "family": "IPv4" + }, + { + "vlanid": 111, + "ip-prefix": "fe80::1/10", + "scope": "local", + "family": "IPv6" + }, + { + "vlanid": 555, + "ip-prefix": "2000:f500:41:4e9::1/64", + "scope": "global", + "family": "IPv6" + }, + { + "vlanid": 555, + "ip-prefix": "10.1.5.65/26", + "scope": "global", + "family": "IPv4" + }, + { + "vlanid": 555, + "ip-prefix": "fe80::1/10", + "scope": "local", + "family": "IPv6" + } + ] + }, + + "test-vlan:VLAN": { + "VLAN_LIST": [{ + "vlanid": 111, + "description": "server_vlan", + "dhcp_servers": [ + "10.1.7.116" + ], + "mtu": "9216", + "admin_status": "up" + }, + { + "vlanid": 555, + "description": "ipmi_vlan", + "dhcp_servers": [ + "10.1.7.116" + ], + "mtu": "9216", + "admin_status": "up" + } + ] + }, + + "test-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [{ + "vlanid": 111, + "port": "Ethernet0", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet1", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet2", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet3", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet4", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet5", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet6", + "tagging_mode": "tagged" + } + ] + } + }, + "test-port:port": { + "test-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet2", + "alias": "eth2", + "description": "Ethernet2", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet3", + "alias": "eth2", + "description": "Ethernet3", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet4", + "alias": "eth4", + "description": "Ethernet4", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet5", + "alias": "eth5", + "description": "Ethernet5", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet6", + "alias": "eth6", + "description": "Ethernet6", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet7", + "alias": "eth7", + "description": "Ethernet7", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet8", + "alias": "eth8", + "description": "Ethernet8", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet9", + "alias": "eth9", + "description": "Ethernet9", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + }, + + "test-acl:acl": { + "test-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "PACL-V4", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.1.72.0/26", + "SRC_IP": "10.1.0.0/15", + "PRIORITY": "999980", + "IP_TYPE": "IPV4ANY" + }, + { + "ACL_TABLE_NAME": "PACL-V4", + "RULE_NAME": "Rule_40", + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.1.72.64/26", + "SRC_IP": "10.1.0.0/15", + "PRIORITY": "999960", + "IP_TYPE": "IPV4ANY", + "INNER_ETHER_TYPE": "0x88CC" + }, + { + "ACL_TABLE_NAME": "PACL-V6", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IP", + "SRC_IPV6": "2000:f500:41::/48", + "PRIORITY": "999980", + "DST_IPV6": "2000:f500:43:320::/64", + "L4_SRC_PORT_RANGE": "653-1053" + } + ] + }, + + "test-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "PACL-V6", + "policy_desc": "Filter IPv6", + "type": "L3V6", + "stage": "EGRESS", + "ports": ["Ethernet7", "Ethernet9", "Ethernet8"] + }, + { + "ACL_TABLE_NAME": "PACL-V4", + "policy_desc": "Filter IPv6", + "type": "L3", + "stage": "INGRESS", + "ports": ["Ethernet2", "Ethernet0", "Ethernet1"] + } + ] + } + }, + + "test-interface:interface": { + "test-interface:INTERFACE": { + "INTERFACE_LIST": [{ + "interface": "Ethernet8", + "ip-prefix": "10.1.1.65/26", + "scope": "global", + "family": "IPv4" + }, + { + "interface": "Ethernet8", + "ip-prefix": "2000:f500:40:a749::2/126", + "scope": "global", + "family": "IPv6" + } + ] + } + } +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data_merge.json b/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data_merge.json new file mode 100644 index 000000000000..73838a157c4a --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data_merge.json @@ -0,0 +1,154 @@ +{ + "test-vlan:vlan": { + "test-vlan:VLAN_INTERFACE": { + "VLAN_INTERFACE_LIST": [{ + "vlanid": 111, + "ip-prefix": "2000:f500:45:6709::1/64", + "scope": "global", + "family": "IPv6" + }, + { + "vlanid": 111, + "ip-prefix": "10.1.1.64/26", + "scope": "global", + "family": "IPv4" + }, + { + "vlanid": 200, + "ip-prefix": "2000:f500:45:6708::1/64", + "scope": "global", + "family": "IPv6" + }, + { + "vlanid": 200, + "ip-prefix": "2000:f500:45:6709::1/64", + "scope": "global", + "family": "IPv6" + } + ] + }, + + "test-vlan:VLAN": { + "VLAN_LIST": [{ + "vlanid": 200, + "description": "server_vlan", + "dhcp_servers": [ + "10.1.72.116" + ], + "mtu": "9216", + "admin_status": "up" + }, + { + "vlanid": 111, + "description": "server_vlan", + "dhcp_servers": [ + "10.1.72.116" + ], + "mtu": "9216", + "admin_status": "up" + } + ] + }, + + "test-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [{ + "vlanid": 200, + "port": "Ethernet0", + "tagging_mode": "tagged" + }] + } + }, + "test-port:port": { + "test-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet2", + "alias": "eth2", + "description": "Ethernet2", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet3", + "alias": "eth2", + "description": "Ethernet3", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet4", + "alias": "eth4", + "description": "Ethernet4", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet5", + "alias": "eth5", + "description": "Ethernet5", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet6", + "alias": "eth6", + "description": "Ethernet6", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet7", + "alias": "eth7", + "description": "Ethernet7", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet8", + "alias": "eth8", + "description": "Ethernet8", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet9", + "alias": "eth9", + "description": "Ethernet9", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet10", + "alias": "eth10", + "description": "Ethernet10", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-acl.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-acl.yang new file mode 100644 index 000000000000..0d7d93a1429a --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-acl.yang @@ -0,0 +1,268 @@ +module test-acl { + + yang-version 1.1; + + namespace "http://github.com/Azure/acl"; + prefix acl; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import test-head { + prefix head; + revision-date 2019-07-01; + } + + import test-port { + prefix port; + revision-date 2019-07-01; + } + + import test-portchannel { + prefix lag; + revision-date 2019-07-01; + } + + revision 2019-07-01 { + description "First Revision"; + } + + container acl { + + container ACL_RULE { + + description "ACL_RULE part of config_db.json"; + + list ACL_RULE_LIST { + + key "ACL_TABLE_NAME RULE_NAME"; + + leaf ACL_TABLE_NAME { + type leafref { + path "/acl:acl/acl:ACL_TABLE/acl:ACL_TABLE_LIST/acl:ACL_TABLE_NAME"; + } + } + + leaf RULE_NAME { + type string { + length 1..255; + } + } + + leaf PACKET_ACTION { + type head:packet_action; + } + + leaf IP_TYPE { + type head:ip_type; + } + + leaf PRIORITY { + type uint32 { + range 0..999999; + } + } + + choice ip_prefix { + + case ip4_prefix { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPV4ANY' or .='ARP'])"; + leaf SRC_IP { + type inet:ipv4-prefix; + } + + leaf DST_IP { + type inet:ipv4-prefix; + } + } + + case ip6_prefix { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPV6ANY'])"; + leaf SRC_IPV6 { + type inet:ipv6-prefix; + } + + leaf DST_IPV6 { + type inet:ipv6-prefix; + } + } + } + + leaf-list IN_PORTS { + /* Values in leaf list are UNIQUE */ + type uint16; + } + + leaf-list OUT_PORTS { + /* Values in leaf list are UNIQUE */ + type uint16; + } + + choice src_port { + case l4_src_port { + leaf L4_SRC_PORT { + type uint16; + } + } + + case l4_src_port_range { + leaf L4_SRC_PORT_RANGE { + type string { + pattern '([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])-([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])'; + } + } + } + } + + choice dst_port { + case l4_dst_port { + leaf L4_DST_PORT { + type uint16; + } + } + + case l4_dst_port_range { + leaf L4_DST_PORT_RANGE { + type string { + pattern '([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])-([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])'; + } + } + } + } + + leaf ETHER_TYPE { + type string { + pattern "(0x88CC|0x8100|0x8915|0x0806|0x0800|0x86DD|0x8847)"; + } + } + + leaf IP_PROTOCOL { + type uint8 { + range 1..143; + } + } + + leaf TCP_FLAGS { + type string { + pattern '0[x][0-9a-fA-F]{1,2}|0[X][0-9a-fA-F]{1,2}'; + } + } + + leaf DSCP { + type uint8; + } + + leaf TC { + type uint8; + } + + choice icmp { + + case icmp4 { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPV4ANY' or .='ARP'])"; + leaf ICMP_TYPE { + type uint8 { + range 1..44; + } + } + + leaf ICMP_CODE { + type uint8 { + range 1..16; + } + } + } + + case icmp6 { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPV6ANY'])"; + leaf ICMPV6_TYPE { + type uint8 { + range 1..44; + } + } + + leaf ICMPV6_CODE { + type uint8 { + range 1..16; + } + } + } + } + + leaf INNER_ETHER_TYPE { + type string { + pattern "(0x88CC|0x8100|0x8915|0x0806|0x0800|0x86DD|0x8847)"; + } + } + + leaf INNER_IP_PROTOCOL { + type uint8 { + range 1..143; + } + } + + leaf INNER_L4_SRC_PORT { + type uint16; + } + + leaf INNER_L4_DST_PORT { + type uint16; + } + } + /* end of ACL_RULE_LIST */ + } + /* end of container ACL_RULE */ + + container ACL_TABLE { + + description "ACL_TABLE part of config_db.json"; + + list ACL_TABLE_LIST { + + key "ACL_TABLE_NAME"; + + leaf ACL_TABLE_NAME { + type string; + } + + leaf policy_desc { + type string { + length 1..255; + } + } + + leaf type { + type head:acl_table_type; + } + + leaf stage { + type enumeration { + enum INGRESS; + enum EGRESS; + } + } + + leaf-list ports { + /* union of leafref is allowed in YANG 1.1 */ + type union { + type leafref { + path /port:port/port:PORT/port:PORT_LIST/port:port_name; + } + type leafref { + path /lag:portchannel/lag:PORTCHANNEL/lag:PORTCHANNEL_LIST/lag:portchannel_name; + } + } + } + } + /* end of ACL_TABLE_LIST */ + } + /* end of container ACL_TABLE */ + } + /* end of container acl */ +} +/* end of module acl */ diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-head.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-head.yang new file mode 100644 index 000000000000..cdb45a3d0d15 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-head.yang @@ -0,0 +1,66 @@ +module test-head { + + namespace "http://head"; + prefix head; + + revision 2019-07-01 { + description "First Revision"; + } + + typedef ip-family { + type enumeration { + enum IPv4; + enum IPv6; + } + } + + typedef admin_status { + type enumeration { + enum up; + enum down; + } + } + + typedef packet_action{ + type enumeration { + enum DROP; + enum FORWARD; + enum REDIRECT; + } + } + + typedef ip_type { + type enumeration { + enum ANY; + enum IP; + enum NON_IP; + enum IPV4; + enum IPV6; + enum IPV4ANY; + enum NON_IPv4; + enum IPV6ANY; + enum NON_IPv6; + enum ARP; + } + } + + typedef acl_table_type { + type enumeration { + enum L2; + enum L3; + enum L3V6; + enum MIRROR; + enum MIRRORV6; + enum MIRROR_DSCP; + enum CTRLPLANE; + } + } + + typedef vlan_tagging_mode { + type enumeration { + enum tagged; + enum untagged; + enum priority_tagged; + } + } +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-interface.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-interface.yang new file mode 100644 index 000000000000..2f453ac6e278 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-interface.yang @@ -0,0 +1,72 @@ +module test-interface { + + namespace "http://github.com/Azure/interface"; + prefix intf; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import test-head { + prefix head; + revision-date 2019-07-01; + } + + import test-port { + prefix port; + revision-date 2019-07-01; + } + + revision 2019-07-01 { + description "First Revision"; + } + + container interface { + container INTERFACE { + + description "INTERFACE part of config_db.json"; + + list INTERFACE_LIST { + + key "interface ip-prefix"; + + leaf interface { + type leafref { + path /port:port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf ip-prefix { + type inet:ip-prefix; + } + + leaf scope { + type enumeration { + enum global; + enum local; + } + } + + leaf family { + + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6021, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type head:ip-family; + } + } + /* end of INTERFACE_LIST */ + + } + /* end of INTERFACE container */ + } +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-port.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-port.yang new file mode 100644 index 000000000000..5e2bf68f7914 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-port.yang @@ -0,0 +1,78 @@ +module test-port{ + + namespace "http://github.com/Azure/port"; + prefix port; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import test-head { + prefix head; + revision-date 2019-07-01; + } + + revision 2019-07-01 { + description "First Revision"; + } + + container port{ + container PORT { + + description "PORT part of config_db.json"; + + list PORT_LIST { + + key "port_name"; + + leaf port_name { + type string { + length 1..128; + } + } + + leaf alias { + type string { + length 1..128; + } + } + + leaf lanes { + type string { + length 1..128; + } + } + + leaf description { + type string { + length 1..255; + } + } + + leaf speed { + type uint32 { + range 1..100000; + } + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf admin_status { + mandatory true; + type head:admin_status; + } + } /* end of list PORT_LIST */ + + } /* end of container PORT */ + + } /* end of container port */ + +} /* end of module port */ diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-portchannel.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-portchannel.yang new file mode 100644 index 000000000000..2081383aeda8 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-portchannel.yang @@ -0,0 +1,79 @@ +module test-portchannel { + + namespace "http://github.com/Azure/portchannel"; + prefix lag; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import test-head { + prefix head; + revision-date 2019-07-01; + } + + import test-port { + prefix port; + revision-date 2019-07-01; + } + + revision 2019-07-01 { + description "First Revision"; + } + + container portchannel { + container PORTCHANNEL { + + description "PORTCHANNEL part of config_db.json"; + + list PORTCHANNEL_LIST { + + key "portchannel_name"; + + leaf portchannel_name { + type string { + length 1..128; + pattern 'PortChannel[0-9]{1,4}'; + } + } + + leaf-list members { + /* leaf-list members are unique by default */ + type leafref { + path /port:port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf min_links { + type uint8 { + range 1..128; + } + } + + leaf description { + type string { + length 1..255; + } + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf admin_status { + mandatory true; + type head:admin_status; + } + } /* end of list PORTCHANNEL_LIST */ + + } /* end of container PORTCHANNEL */ + + } /* end of container portchannel */ + +} /* end of module port */ diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-vlan.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-vlan.yang new file mode 100644 index 000000000000..2ca80607b410 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-vlan.yang @@ -0,0 +1,144 @@ +module test-vlan { + + namespace "http://github.com/Azure/vlan"; + prefix vlan; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import test-head { + prefix head; + revision-date 2019-07-01; + } + + import test-port { + prefix port; + revision-date 2019-07-01; + } + + revision 2019-07-01 { + description "First Revision"; + } + + container vlan { + container VLAN_INTERFACE { + + description "VLAN_INTERFACE part of config_db.json"; + + list VLAN_INTERFACE_LIST { + + key "vlanid ip-prefix"; + + leaf vlanid { + type leafref { + path ../../../VLAN/VLAN_LIST/vlanid; + } + } + + leaf ip-prefix { + mandatory true; + type inet:ip-prefix; + } + + leaf scope { + type enumeration { + enum global; + enum local; + } + } + + leaf family { + + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6021, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type head:ip-family; + } + } + /* end of VLAN_INTERFACE_LIST */ + } + /* end of VLAN_INTERFACE container */ + + container VLAN { + + description "VLAN part of config_db.json"; + + list VLAN_LIST { + + key "vlanid"; + + leaf vlanid { + type uint16 { + range 1..4094; + } + } + + leaf description { + type string { + length 1..255; + } + } + + leaf-list dhcp_servers { + type inet:ip-address; + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf admin_status { + mandatory true; + type head:admin_status; + } + } + /* end of VLAN_LIST */ + } + /* end of container VLAN */ + + container VLAN_MEMBER { + + description "VLAN_MEMBER part of config_db.json"; + + list VLAN_MEMBER_LIST { + + key "vlanid port"; + + leaf vlanid { + type leafref { + path ../../../VLAN/VLAN_LIST/vlanid; + } + } + + leaf port { + /* key elements are mandatory by default */ + mandatory true; + type leafref { + path /port:port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf tagging_mode { + mandatory true; + type head:vlan_tagging_mode; + } + } + /* end of list VLAN_MEMBER_LIST */ + } + /* end of container VLAN_MEMBER */ + } + /* end of container vlan */ +} +/* end of module vlan */ diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample_config_db.json b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample_config_db.json new file mode 100644 index 000000000000..a37639fb4b73 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample_config_db.json @@ -0,0 +1,648 @@ +{ + "VLAN_INTERFACE": { + "Vlan111|2a04:5555:45:6709::1/64": { + "scope": "global", + "family": "IPv6" + }, + "Vlan111|10.222.10.65/26": { + "scope": "global", + "family": "IPv4" + }, + "Vlan111|fe80::1/10": { + "scope": "local", + "family": "IPv6" + }, + "Vlan777|2a04:5555:41:4e9::1/64": { + "scope": "global", + "family": "IPv6" + }, + "Vlan777|10.111.58.65/26": { + "scope": "global", + "family": "IPv4" + }, + "Vlan777|fe80::1/10": { + "scope": "local", + "family": "IPv6" + } + }, + "ACL_RULE": { + "V4-ACL-TABLE|DEFAULT_DENY": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv4ANY", + "PRIORITY": "0" + }, + "V4-ACL-TABLE|Rule_20": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.72.0/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777780", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_40": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.72.64/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777760", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_60": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.80.0/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777740", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_80": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.80.64/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777720", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_111": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.152.17.52/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777700", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_120": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.252.208.41/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777880", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_140": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.148.128.245/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777860", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_160": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.1.245/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777840", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_180": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.252.222.21/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777820", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_9000": { + "PACKET_ACTION": "DROP", + "DST_IP": "0.0.0.0/0", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "991110", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_11100": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "0.0.0.0/0", + "SRC_IP": "0.0.0.0/0", + "PRIORITY": "990000", + "IP_TYPE": "IPv4ANY" + }, + "V6-ACL-TBLE|DEFAULT_DENY": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv6ANY", + "PRIORITY": "0" + }, + "V6-ACL-TBLE|Rule_20": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777780", + "DST_IPV6": "2a04:5555:43:320::/64" + }, + "V6-ACL-TBLE|Rule_40": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777760", + "DST_IPV6": "2a04:5555:43:321::/64" + }, + "V6-ACL-TBLE|Rule_60": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777740", + "DST_IPV6": "2a04:5555:43:340::/64" + }, + "V6-ACL-TBLE|Rule_80": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777720", + "DST_IPV6": "2a04:5555:43:341::/64" + }, + "V6-ACL-TBLE|Rule_111": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777700", + "DST_IPV6": "2a04:5555:32:12::/64" + }, + "V6-ACL-TBLE|Rule_9000": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "991110", + "DST_IPV6": "::/0" + }, + "V6-ACL-TBLE|Rule_11100": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "::/0", + "PRIORITY": "990000", + "DST_IPV6": "::/0" + } + }, + "DEVICE_METADATA": { + "localhost": { + "mg_type": "ToR", + "mac": "00:11:22:33:dd:5a", + "hostname": "asw.dc", + "bgp_asn": "64850", + "hwsku": "Stone" + } + }, + "VLAN": { + "Vlan111": { + "description": "svlan", + "dhcp_servers": [ + "10.222.72.116" + ], + "vlanid": "111", + "mtu": "9216", + "admin_status": "up", + "members": [ + "Ethernet8", + "Ethernet3", + "Ethernet0", + "Ethernet1", + "Ethernet6", + "Ethernet4", + "Ethernet5", + "Ethernet9", + "Ethernet2", + "Ethernet7", + "Ethernet32", + "Ethernet30", + "Ethernet31", + "Ethernet36", + "Ethernet34", + "Ethernet33", + "Ethernet35", + "Ethernet29", + "Ethernet21", + "Ethernet20", + "Ethernet23", + "Ethernet22", + "Ethernet27", + "Ethernet26", + "Ethernet18", + "Ethernet19", + "Ethernet14", + "Ethernet15", + "Ethernet16", + "Ethernet17", + "Ethernet10", + "Ethernet11", + "Ethernet12", + "Ethernet13", + "Ethernet28" + ] + }, + "Vlan777": { + "description": "pvlan", + "dhcp_servers": [ + "10.222.72.116" + ], + "vlanid": "777", + "mtu": "9216", + "admin_status": "up", + "members": [ + "Ethernet9", + "Ethernet2", + "Ethernet8", + "Ethernet27", + "Ethernet14", + "Ethernet35" + ] + } + }, + "DEVICE_NEIGHBOR": { + "Ethernet112": { + "name": "dccsw01.nw", + "port": "Eth18" + }, + "Ethernet114": { + "name": "dccsw02.nw", + "port": "Eth18" + }, + "Ethernet116": { + "name": "dccsw03.nw", + "port": "Eth18" + }, + "Ethernet118": { + "name": "dccsw04.nw", + "port": "Eth18" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1/1", + "lanes": "65", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet1": { + "alias": "Eth1/2", + "lanes": "66", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet2": { + "alias": "Eth1/3", + "lanes": "67", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet3": { + "alias": "Eth1/4", + "lanes": "68", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet4": { + "alias": "Eth2/1", + "lanes": "69", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet5": { + "alias": "Eth2/2", + "lanes": "70", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet6": { + "alias": "Eth2/3", + "lanes": "71", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet7": { + "alias": "Eth2/4", + "lanes": "72", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet8": { + "alias": "Eth3/1", + "lanes": "73", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet9": { + "alias": "Eth3/2", + "lanes": "74", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet10": { + "alias": "Eth3/3", + "lanes": "75", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet11": { + "alias": "Eth3/4", + "lanes": "76", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet12": { + "alias": "Eth4/1", + "lanes": "77", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet13": { + "alias": "Eth4/2", + "lanes": "78", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet14": { + "alias": "Eth4/3", + "lanes": "79", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet15": { + "alias": "Eth4/4", + "lanes": "80", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet16": { + "alias": "Eth5/1", + "lanes": "33", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet17": { + "alias": "Eth5/2", + "lanes": "34", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet18": { + "alias": "Eth5/3", + "lanes": "35", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet19": { + "alias": "Eth5/4", + "lanes": "36", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet20": { + "alias": "Eth6/1", + "lanes": "37", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet21": { + "alias": "Eth6/2", + "lanes": "38", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet22": { + "alias": "Eth6/3", + "lanes": "39", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet23": { + "alias": "Eth6/4", + "lanes": "40", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet24": { + "alias": "Eth7/1", + "lanes": "41", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet25": { + "alias": "Eth7/2", + "lanes": "42", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet26": { + "alias": "Eth7/3", + "lanes": "43", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet27": { + "alias": "Eth7/4", + "lanes": "44", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet28": { + "alias": "Eth8/1", + "lanes": "45", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet29": { + "alias": "Eth8/2", + "lanes": "46", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet30": { + "alias": "Eth8/3", + "lanes": "47", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet31": { + "alias": "Eth8/4", + "lanes": "48", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet32": { + "alias": "Eth9/1", + "lanes": "49", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet33": { + "alias": "Eth9/2", + "lanes": "50", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet34": { + "alias": "Eth9/3", + "lanes": "51", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet35": { + "alias": "Eth9/4", + "lanes": "52", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet36": { + "alias": "Eth10/1", + "lanes": "53", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet112": { + "alias": "Eth29/1", + "lanes": "113,114", + "description": "50G|dccsw01.nw|Eth18", + "fec": "fc", + "admin_status": "up" + } + }, + "ACL_TABLE": { + "V4-ACL-TABLE": { + "type": "L3", + "policy_desc": "V4-ACL-TABLE", + "ports": [ + "Ethernet26", + "Ethernet27", + "Ethernet24" + ] + }, + "V6-ACL-TBLE": { + "type": "L3V6", + "policy_desc": "V6-ACL-TBLE", + "ports": [ + "Ethernet14", + "Ethernet15", + "Ethernet23", + "Ethernet30", + "Ethernet31", + "Ethernet18", + "Ethernet19", + "Ethernet25", + "Ethernet24" + ] + } + }, + "INTERFACE": { + "Ethernet112|2a04:5555:40:a709::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet112|10.184.228.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet14|2a04:5555:40:a749::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet14|10.184.229.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet16|2a04:5555:40:a789::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet16|10.184.230.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet18|2a04:5555:40:a7c9::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet18|10.184.231.211/31": { + "scope": "global", + "family": "IPv4" + } + }, + "VLAN_MEMBER": { + "Vlan111|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet1": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet2": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet3": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet5": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet6": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet29": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet30": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet31": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet32": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet33": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet34": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet35": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet36": { + "tagging_mode": "untagged" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|2a04:5555:40:4::4e9/128": { + "scope": "global", + "family": "IPv6" + }, + "Loopback0|10.184.8.233/32": { + "scope": "global", + "family": "IPv4" + } + }, + "CRM": { + "Config": { + "polling_interval": "0" + } + } +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_SonicYang.json b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_SonicYang.json new file mode 100644 index 000000000000..f3e0c46f76b2 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_SonicYang.json @@ -0,0 +1,144 @@ +{ + "yang_dir":"./tests/libyang-python-tests/sample-yang-models/", + "data_file":"./tests/libyang-python-tests/config_data.json", + "data_merge_file":"./tests/libyang-python-tests/config_data_merge.json", + "modules":[ + {"file":"test-head.yang", "module":"test-head"}, + {"file":"test-port.yang", "module":"test-port"}, + {"file":"test-acl.yang", "module":"test-acl"}, + {"file":"test-interface.yang", "module":"test-interface"}, + {"file":"test-portchannel.yang", "module":"test-portchannel"}, + {"file":"test-vlan.yang", "module":"test-vlan"} + ], + + "merged_nodes":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed", "value":"25000"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='200'][ip-prefix='2000:f500:45:6708::/64']/family", + "value":"IPv6"} + ], + + "new_nodes":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']/alias", "value":"Ethernet10_alias"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']/speed", "value":"5000"}, + {"xpath":"/test-acl:acl/ACL_RULE/ACL_RULE_LIST[ACL_TABLE_NAME='PACL-test'][RULE_NAME='rule_20']/RULE_NAME", + "value":"rule_20"} + ], + + "data_nodes":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/alias", "valid":"True"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet20']/alias", "valid":"False"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE", "valid":"True"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST", "valid":"False"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']", "valid":"True"} + ], + + "set_nodes":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed", "value":"10000"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/mtu", "value":"1500"}, + {"xpath":"/test-vlan:vlan/VLAN/VLAN_LIST[vlanid='111']/description", "value":"server_vlan111"} + ], + + "node_values":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed", "value":"25000"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/family", + "value":"IPv6"} + ], + + "schema_nodes":[ + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/family", + "value":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:family"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed", + "value":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:speed"} + ], + + "delete_nodes":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed", "valid":"False"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/mtu", "valid":"True"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet20']/mtu", "valid":"False"} + ], + + "dependencies":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet8']/port_name", + "dependencies": + ["/test-acl:acl/ACL_TABLE/ACL_TABLE_LIST[ACL_TABLE_NAME='PACL-V6']/ports[.='Ethernet8']", + "/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='10.1.1.64/26']/interface", + "/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='2000:f500:40:a749::/126']/interface"]} + ], + "schema_dependencies":[ + {"xpath":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name", + "schema_dependencies": + ["/test-acl:acl/test-acl:ACL_TABLE/test-acl:ACL_TABLE_LIST/test-acl:ports", + "/test-portchannel:portchannel/test-portchannel:PORTCHANNEL/test-portchannel:PORTCHANNEL_LIST/test-portchannel:members", + "/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface", + "/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port"]} + ], + "members":[ + {"xpath":"/test-port:port/PORT/PORT_LIST", + "members": + ["/test-port:port/PORT/PORT_LIST[port_name='Ethernet0']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet1']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet2']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet3']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet4']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet5']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet6']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet7']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet8']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']"]} + ], + + "parents":[ + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/family", + "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/scope", + "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/vlanid", + "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/ip-prefix", + "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/family", + "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed", + "parent":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']"} + ], + "prefix":[ + {"module_name":"test-head", "module_prefix":"head"}, + {"module_name":"test-port", "module_prefix":"port"}, + {"module_name":"test-acl", "module_prefix":"acl"}, + {"module_name":"test-interface", "module_prefix":"intf"}, + {"module_name":"test-portchannel", "module_prefix":"lag"}, + {"module_name":"test-vlan", "module_prefix":"vlan"} + ], + "data_type":[ + {"xpath":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name", "data_type":"LY_TYPE_STRING"}, + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid", "data_type":"LY_TYPE_LEAFREF"} + ], + "leafref_type":[ + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/vlanid", "data_type":"LY_TYPE_UINT16"}, + {"xpath":"/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='2000:f500:40:a749::/126']/interface", "data_type":"LY_TYPE_STRING"}, + {"xpath":"/test-vlan:vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='111'][port='Ethernet0']/port", "data_type":"LY_TYPE_STRING"}, + {"xpath":"/test-vlan:vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='111'][port='Ethernet0']/vlanid", "data_type":"LY_TYPE_UINT16"} + ], + "leafref_type_schema":[ + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid", + "data_type":"LY_TYPE_UINT16"}, + {"xpath":"/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface", + "data_type":"LY_TYPE_STRING"}, + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port", + "data_type":"LY_TYPE_STRING"}, + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:vlanid", + "data_type":"LY_TYPE_UINT16"} + ], + "leafref_path":[ + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid", + "leafref_path":"../../../VLAN/VLAN_LIST/vlanid"}, + {"xpath":"/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface", + "leafref_path":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name"}, + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port", + "leafref_path":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name"}, + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:vlanid", + "leafref_path":"../../../VLAN/VLAN_LIST/vlanid"} + ] +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py new file mode 100644 index 000000000000..b5fa35842990 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py @@ -0,0 +1,324 @@ +import sys +import os +import pytest +import sonic_yang as sy +import json +import glob +import logging +from ijson import items as ijson_itmes + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +sys.path.insert(0, modules_path) + +logging.basicConfig(level=logging.DEBUG) +log = logging.getLogger("YANG-TEST") +log.setLevel(logging.INFO) +log.addHandler(logging.NullHandler()) + +class Test_SonicYang(object): + # class vars + + @pytest.fixture(autouse=True, scope='class') + def data(self): + test_file = "./tests/libyang-python-tests/test_SonicYang.json" + data = self.jsonTestParser(test_file) + return data + + @pytest.fixture(autouse=True, scope='class') + def yang_s(self, data): + yang_dir = str(data['yang_dir']) + yang_s = sy.SonicYang(yang_dir) + return yang_s + + def jsonTestParser(self, file): + """ + Open the json test file + """ + with open(file) as data_file: + data = json.load(data_file) + return data + + """ + Get the JSON input based on func name + and return jsonInput + """ + def readIjsonInput(self, yang_test_file, test): + try: + # load test specific Dictionary, using Key = func + # this is to avoid loading very large JSON in memory + print(" Read JSON Section: " + test) + jInput = "" + with open(yang_test_file, 'rb') as f: + jInst = ijson_itmes(f, test) + for it in jInst: + jInput = jInput + json.dumps(it) + except Exception as e: + print("Reading Ijson failed") + raise(e) + return jInput + + def setup_class(self): + pass + + def load_yang_model_file(self, yang_s, yang_dir, yang_file, module_name): + yfile = yang_dir + yang_file + try: + yang_s._load_schema_module(str(yfile)) + except Exception as e: + print(e) + raise + + #test load and get yang module + def test_load_yang_model_files(self, data, yang_s): + yang_dir = data['yang_dir'] + for module in data['modules']: + file = str(module['file']) + module = str(module['module']) + + self.load_yang_model_file(yang_s, yang_dir, file, module) + assert yang_s._get_module(module) is not None + + #test load non-exist yang module file + def test_load_invalid_model_files(self, data, yang_s): + yang_dir = data['yang_dir'] + file = "invalid.yang" + module = "invalid" + + with pytest.raises(Exception): + assert self.load_yang_model_file(yang_s, yang_dir, file, module) + + #test load yang modules in directory + def test_load_yang_model_dir(self, data, yang_s): + yang_dir = data['yang_dir'] + yang_s._load_schema_modules(str(yang_dir)) + + for module_name in data['modules']: + assert yang_s._get_module(str(module_name['module'])) is not None + + #test load yang modules and data files + def test_load_yang_model_data(self, data, yang_s): + yang_dir = str(data['yang_dir']) + yang_files = glob.glob(yang_dir+"/*.yang") + data_file = str(data['data_file']) + data_merge_file = str(data['data_merge_file']) + + data_files = [] + data_files.append(data_file) + data_files.append(data_merge_file) + print(yang_files) + yang_s._load_data_model(yang_dir, yang_files, data_files) + + #validate the data tree from data_merge_file is loaded + for node in data['merged_nodes']: + xpath = str(node['xpath']) + value = str(node['value']) + val = yang_s._find_data_node_value(xpath) + assert str(val) == str(value) + + #test load data file + def test_load_data_file(self, data, yang_s): + data_file = str(data['data_file']) + yang_s._load_data_file(data_file) + + #test_validate_data_tree(): + def test_validate_data_tree(self, data, yang_s): + yang_s.validate_data_tree() + + #test find node + def test_find_node(self, data, yang_s): + for node in data['data_nodes']: + expected = node['valid'] + xpath = str(node['xpath']) + dnode = yang_s._find_data_node(xpath) + + if(expected == "True"): + assert dnode is not None + assert dnode.path() == xpath + else: + assert dnode is None + + #test add node + def test_add_node(self, data, yang_s): + for node in data['new_nodes']: + xpath = str(node['xpath']) + value = node['value'] + yang_s._add_data_node(xpath, str(value)) + + data_node = yang_s._find_data_node(xpath) + assert data_node is not None + + #test find node value + def test_find_data_node_value(self, data, yang_s): + for node in data['node_values']: + xpath = str(node['xpath']) + value = str(node['value']) + print(xpath) + print(value) + val = yang_s._find_data_node_value(xpath) + assert str(val) == str(value) + + #test delete data node + def test_delete_node(self, data, yang_s): + for node in data['delete_nodes']: + xpath = str(node['xpath']) + yang_s._deleteNode(xpath) + + #test set node's value + def test_set_datanode_value(self, data, yang_s): + for node in data['set_nodes']: + xpath = str(node['xpath']) + value = node['value'] + yang_s._set_data_node_value(xpath, value) + + val = yang_s._find_data_node_value(xpath) + assert str(val) == str(value) + + #test list of members + def test_find_members(self, yang_s, data): + for node in data['members']: + members = node['members'] + xpath = str(node['xpath']) + list = yang_s._find_data_nodes(xpath) + assert list.sort() == members.sort() + + #get parent xpath + def test_get_parent_data_xpath(self, yang_s, data): + for node in data['parents']: + xpath = str(node['xpath']) + expected_xpath = str(node['parent']) + path = yang_s._get_parent_data_xpath(xpath) + assert path == expected_xpath + + #test find_data_node_schema_xpath + def test_find_data_node_schema_xpath(self, yang_s, data): + for node in data['schema_nodes']: + xpath = str(node['xpath']) + schema_xpath = str(node['value']) + path = yang_s._find_data_node_schema_xpath(xpath) + assert path == schema_xpath + + #test data dependencies + def test_find_data_dependencies(self, yang_s, data): + for node in data['dependencies']: + xpath = str(node['xpath']) + list = node['dependencies'] + depend = yang_s.find_data_dependencies(xpath) + assert set(depend) == set(list) + + #test data dependencies + def test_find_schema_dependencies(self, yang_s, data): + for node in data['schema_dependencies']: + xpath = str(node['xpath']) + list = node['schema_dependencies'] + depend = yang_s._find_schema_dependencies(xpath) + assert set(depend) == set(list) + + #test merge data tree + def test_merge_data_tree(self, data, yang_s): + data_merge_file = data['data_merge_file'] + yang_dir = str(data['yang_dir']) + yang_s._merge_data(data_merge_file, yang_dir) + #yang_s.root.print_mem(ly.LYD_JSON, ly.LYP_FORMAT) + + #test get module prefix + def test_get_module_prefix(self, yang_s, data): + for node in data['prefix']: + xpath = str(node['module_name']) + expected = node['module_prefix'] + prefix = yang_s._get_module_prefix(xpath) + assert expected == prefix + + #test get data type + def test_get_data_type(self, yang_s, data): + for node in data['data_type']: + xpath = str(node['xpath']) + expected = node['data_type'] + expected_type = yang_s._str_to_type(expected) + data_type = yang_s._get_data_type(xpath) + assert expected_type == data_type + + def test_get_leafref_type(self, yang_s, data): + for node in data['leafref_type']: + xpath = str(node['xpath']) + expected = node['data_type'] + expected_type = yang_s._str_to_type(expected) + data_type = yang_s._get_leafref_type(xpath) + assert expected_type == data_type + + def test_get_leafref_path(self, yang_s, data): + for node in data['leafref_path']: + xpath = str(node['xpath']) + expected_path = node['leafref_path'] + path = yang_s._get_leafref_path(xpath) + assert expected_path == path + + def test_get_leafref_type_schema(self, yang_s, data): + for node in data['leafref_type_schema']: + xpath = str(node['xpath']) + expected = node['data_type'] + expected_type = yang_s._str_to_type(expected) + data_type = yang_s._get_leafref_type_schema(xpath) + assert expected_type == data_type + + """ + This is helper function to load YANG models for tests cases, which works + on Real SONiC Yang models. Mainly tests for translation and reverse + translation. + """ + @pytest.fixture(autouse=True, scope='class') + def sonic_yang_data(self): + sonic_yang_dir = "../sonic-yang-models/yang-models/" + sonic_yang_test_file = "../sonic-yang-models/tests/yang_model_tests/yangTest.json" + + syc = sy.SonicYang(sonic_yang_dir) + syc.loadYangModel() + + sonic_yang_data = dict() + sonic_yang_data['yang_dir'] = sonic_yang_dir + sonic_yang_data['test_file'] = sonic_yang_test_file + sonic_yang_data['syc'] = syc + + return sonic_yang_data + + def test_xlate_rev_xlate(self, sonic_yang_data): + # In this test, xlation and revXlation is tested with latest Sonic + # YANG model. + test_file = sonic_yang_data['test_file'] + syc = sonic_yang_data['syc'] + + jIn = self.readIjsonInput(test_file, 'SAMPLE_CONFIG_DB_JSON') + + syc.loadData(json.loads(jIn)) + + # TODO: Make sure no extra table is loaded + + syc.getData() + + if syc.jIn and syc.jIn == syc.revXlateJson: + print("Xlate and Rev Xlate Passed") + else: + print("Xlate and Rev Xlate failed") + # make it fail + assert False == True + + return + + def test_table_with_no_yang(self, sonic_yang_data): + # in this test, tables with no YANG models must be stored seperately + # by this library. + test_file = sonic_yang_data['test_file'] + syc = sonic_yang_data['syc'] + + jIn = self.readIjsonInput(test_file, 'SAMPLE_CONFIG_DB_JSON_1') + + syc.loadData(json.loads(jIn)) + + ty = syc.tablesWithOutYang + + assert (len(ty) and "UNKNOWN_TABLE" in ty) + + return + + def teardown_class(self): + pass diff --git a/src/sonic-yang-mgmt/tests/test_sonic_yang_mgmt.py b/src/sonic-yang-mgmt/tests/test_sonic_yang_mgmt.py new file mode 100644 index 000000000000..e5364fb172a9 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/test_sonic_yang_mgmt.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Tests for `sonic_yang_mgmt` package.""" + +import pytest + +@pytest.fixture +def response(): + """Sample pytest fixture. + + See more at: http://doc.pytest.org/en/latest/fixture.html + """ + # import requests + # return requests.get('https://github.com/audreyr/cookiecutter-pypackage') + + +def test_content(response): + """Sample pytest test function with the pytest fixture as an argument.""" + # from bs4 import BeautifulSoup + # assert 'GitHub' in BeautifulSoup(response.content).title.string diff --git a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json index 523eedf3c4b1..2f85d0259bfa 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json +++ b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json @@ -1275,10 +1275,76 @@ "family": "IPv4" } }, - "CRM": { - "Config": { - "polling_interval": "0" - } - } - } + "BREAKOUT_CFG": { + "Ethernet0": { + "brkout_mode": "1x100G[40G]" + }, + "Ethernet4": { + "brkout_mode": "4x25G" + }, + "Ethernet8": { + "brkout_mode": "1x100G[40G]" + } + }, + "VERSIONS": { + "DATABASE": { + "VERSION": "version_1_0_3" + } + }, + "FLEX_COUNTER_TABLE": { + "PFCWD": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PG_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PORT": { + "FLEX_COUNTER_STATUS": "enable" + }, + "QUEUE": { + "FLEX_COUNTER_STATUS": "enable" + }, + "QUEUE_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + } + }, + "CRM": { + "Config": { + "acl_counter_high_threshold": "85", + "acl_counter_low_threshold": "70", + "acl_counter_threshold_type": "percentage", + "polling_interval": "0" + } + } + }, + "SAMPLE_CONFIG_DB_JSON_1": { + "FLEX_COUNTER_TABLE": { + "PFCWD": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PG_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PORT": { + "FLEX_COUNTER_STATUS": "enable" + }, + "QUEUE": { + "FLEX_COUNTER_STATUS": "enable" + }, + "QUEUE_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + } + }, + "CRM": { + "Config": { + "acl_counter_high_threshold": "85", + "acl_counter_low_threshold": "70", + "acl_counter_threshold_type": "percentage", + "polling_interval": "0" + } + }, + "UNKNOWN_TABLE": { + "Error": "This Table is for testing, This Table does not have YANG models." + } + } } From 5e5e9ec41708fbc02889de5fe35cd53c52641eb3 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Fri, 22 May 2020 17:50:43 +0700 Subject: [PATCH 0692/1427] [device/celestica]: DX010 platform API update (#4608) - Fix fancontrol.service path - Fix return temp format in thermal API - Improve init time in chassis API - Upgrade sfp API --- .../sonic_platform/chassis.py | 177 ++- .../sonic_platform/component.py | 23 +- .../sonic_platform/fan.py | 73 +- .../sonic_platform/helper.py | 121 ++ .../sonic_platform/psu.py | 25 +- .../sonic_platform/sfp.py | 1176 +++++++++++------ .../sonic_platform/thermal.py | 14 +- .../debian/platform-modules-dx010.install | 2 +- .../platform-modules-haliburton.install | 2 +- .../dx010/scripts/fancontrol.service | 12 + .../script}/fancontrol.service | 0 11 files changed, 1129 insertions(+), 496 deletions(-) create mode 100644 device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py create mode 100755 platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service rename platform/broadcom/sonic-platform-modules-cel/{services/fancontrol => haliburton/script}/fancontrol.service (100%) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index 91e3dc0bf464..421d03c82bb4 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -8,20 +8,10 @@ # ############################################################################# -import sys -import re -import os -import subprocess -import json - try: + import sys from sonic_platform_base.chassis_base import ChassisBase - from sonic_platform.fan import Fan - from sonic_platform.psu import Psu - from sonic_platform.component import Component - from sonic_platform.thermal import Thermal - from sonic_platform.sfp import Sfp - from sonic_platform.eeprom import Tlv + from helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -44,38 +34,53 @@ class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) - self.config_data = {} + self._api_helper = APIHelper() + self.sfp_module_initialized = False + self.__initialize_eeprom() + self.is_host = self._api_helper.is_host() + + if not self.is_host: + self.__initialize_fan() + self.__initialize_psu() + self.__initialize_thermals() + else: + self.__initialize_components() + + def __initialize_sfp(self): + from sonic_platform.sfp import Sfp + for index in range(0, NUM_SFP): + sfp = Sfp(index) + self._sfp_list.append(sfp) + self.sfp_module_initialized = True + + def __initialize_psu(self): + from sonic_platform.psu import Psu + for index in range(0, NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) + + def __initialize_fan(self): + from sonic_platform.fan import Fan for fant_index in range(0, NUM_FAN_TRAY): for fan_index in range(0, NUM_FAN): fan = Fan(fant_index, fan_index) self._fan_list.append(fan) - for index in range(0, NUM_PSU): - psu = Psu(index) - self._psu_list.append(psu) + + def __initialize_thermals(self): + from sonic_platform.thermal import Thermal for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) - # sfp index start from 1 - for index in range(0, NUM_SFP): - sfp = Sfp(index) - self._sfp_list.append(sfp) - for index in range(0, NUM_COMPONENT): - component = Component(index) - self._component_list.append(component) + def __initialize_eeprom(self): + from sonic_platform.eeprom import Tlv self._eeprom = Tlv() - def __is_host(self): - return os.system(HOST_CHK_CMD) == 0 - - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return None + def __initialize_components(self): + from sonic_platform.component import Component + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) def get_base_mac(self): """ @@ -107,7 +112,6 @@ def get_system_eeprom_info(self): def get_reboot_cause(self): """ Retrieves the cause of the previous reboot - Returns: A tuple (string, string) where the first element is a string containing the cause of the previous reboot. This string must be @@ -118,16 +122,14 @@ def get_reboot_cause(self): description = 'None' reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER - reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) if self.__is_host( - ) else PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE - prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) if self.__is_host( - ) else PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE + reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) if self.is_host else PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE + prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) if self.is_host else PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE hw_reboot_cause = self._component_list[0].get_register_value(RESET_REGISTER) - sw_reboot_cause = self.__read_txt_file( + sw_reboot_cause = self._api_helper.read_txt_file( reboot_cause_path) or "Unknown" - prev_sw_reboot_cause = self.__read_txt_file( + prev_sw_reboot_cause = self._api_helper.read_txt_file( prev_reboot_cause_path) or "Unknown" if sw_reboot_cause == "Unknown" and (prev_sw_reboot_cause == "Unknown" or prev_sw_reboot_cause == self.REBOOT_CAUSE_POWER_LOSS) and hw_reboot_cause == "0x11": @@ -146,18 +148,32 @@ def get_reboot_cause(self): return (reboot_cause, description) - def get_watchdog(self): + ############################################################## + ######################## SFP methods ######################### + ############################################################## + + def get_num_sfps(self): """ - Retreives hardware watchdog device on this chassis + Retrieves the number of sfps available on this chassis Returns: - An object derived from WatchdogBase representing the hardware - watchdog device + An integer, the number of sfps available on this chassis """ - if self._watchdog is None: - from sonic_platform.watchdog import Watchdog - self._watchdog = Watchdog() + if not self.sfp_module_initialized: + self.__initialize_sfp() - return self._watchdog + return len(self._sfp_list) + + def get_all_sfps(self): + """ + Retrieves all sfps available on this chassis + Returns: + A list of objects derived from SfpBase representing all sfps + available on this chassis + """ + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return self._sfp_list def get_sfp(self, index): """ @@ -171,6 +187,8 @@ def get_sfp(self, index): An object dervied from SfpBase representing the specified sfp """ sfp = None + if not self.sfp_module_initialized: + self.__initialize_sfp() try: # The index will start from 1 @@ -179,3 +197,64 @@ def get_sfp(self, index): sys.stderr.write("SFP index {} out of range (1-{})\n".format( index, len(self._sfp_list))) return sfp + + ############################################################## + ####################### Other methods ######################## + ############################################################## + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return self._api_helper.hwsku + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._eeprom.get_pn() + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self.get_serial_number() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py index d94a93474452..e51cd639a2ef 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py @@ -8,14 +8,13 @@ # ############################################################################# -import json import os.path import shutil -import shlex import subprocess try: from sonic_platform_base.component_base import ComponentBase + from helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -29,7 +28,8 @@ GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg" BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" COMPONENT_NAME_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "BIOS"] -COMPONENT_DES_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "Basic Input/Output System"] +COMPONENT_DES_LIST = ["Used for managing the CPU", + "Used for managing QSFP+ ports (1-10)", "Used for managing QSFP+ ports (11-20)", "Used for managing QSFP+ ports (22-32)", "Basic Input/Output System"] class Component(ComponentBase): @@ -40,24 +40,9 @@ class Component(ComponentBase): def __init__(self, component_index): ComponentBase.__init__(self) self.index = component_index + self._api_helper = APIHelper() self.name = self.get_name() - def __run_command(self, command): - # Run bash command and print output to stdout - try: - process = subprocess.Popen( - shlex.split(command), stdout=subprocess.PIPE) - while True: - output = process.stdout.readline() - if output == '' and process.poll() is not None: - break - rc = process.poll() - if rc != 0: - return False - except: - return False - return True - def __get_bios_version(self): # Retrieves the BIOS firmware version try: diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py index c0724e9bb688..c38b57f83cd9 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py @@ -14,6 +14,7 @@ try: from sonic_platform_base.fan_base import FanBase + from helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -38,13 +39,16 @@ "addr": "5b" }, } +NULL_VAL = "N/A" class Fan(FanBase): """Platform-specific Fan class""" def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): + FanBase.__init__(self) self.fan_index = fan_index + self._api_helper = APIHelper() self.fan_tray_index = fan_tray_index self.is_psu_fan = is_psu_fan if self.is_psu_fan: @@ -75,16 +79,6 @@ def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): {'prs': 14, 'dir': 19, 'color': {'red': 37, 'green': 38}}, # 4 {'prs': 12, 'dir': 17, 'color': {'red': 33, 'green': 34}}, # 5 ] - FanBase.__init__(self) - - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" def __write_txt_file(self, file_path, value): try: @@ -105,7 +99,7 @@ def __search_file_by_name(self, directory, file_name): def __get_gpio_base(self): for r in os.listdir(GPIO_DIR): label_path = os.path.join(GPIO_DIR, r, "label") - if "gpiochip" in r and GPIO_LABEL in self.__read_txt_file(label_path): + if "gpiochip" in r and GPIO_LABEL in self._api_helper.read_txt_file(label_path): return int(r[8:], 10) return 216 # Reserve @@ -113,7 +107,7 @@ def __get_gpio_value(self, pinnum): gpio_base = self.dx010_fan_gpio[0]['base'] gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum) gpio_file = gpio_dir + "/value" - retval = self.__read_txt_file(gpio_file) + retval = self._api_helper.read_txt_file(gpio_file) return retval.rstrip('\r\n') def __set_gpio_value(self, pinnum, value=0): @@ -154,7 +148,8 @@ def get_speed(self): fan_speed_sysfs_name = "fan{}_input".format(self.fan_index+1) fan_speed_sysfs_path = self.__search_file_by_name( self.psu_hwmon_path, fan_speed_sysfs_name) - fan_speed_rpm = self.__read_txt_file(fan_speed_sysfs_path) or 0 + fan_speed_rpm = self._api_helper.read_txt_file( + fan_speed_sysfs_path) or 0 fan_speed_raw = float(fan_speed_rpm)/PSU_FAN_MAX_RPM * 100 speed = math.ceil(float(fan_speed_rpm) * 100 / PSU_FAN_MAX_RPM) elif self.get_presence(): @@ -164,7 +159,7 @@ def get_speed(self): sysfs_path = "%s%s/%s" % ( EMC2305_PATH, device, EMC2305_FAN_INPUT) sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index]) - raw = self.__read_txt_file(sysfs_path).strip('\r\n') + raw = self._api_helper.read_txt_file(sysfs_path).strip('\r\n') pwm = int(raw, 10) if raw else 0 speed = math.ceil(float(pwm * 100 / EMC2305_MAX_PWM)) @@ -183,19 +178,7 @@ def get_target_speed(self): 0 : when PWM mode is use pwm : when pwm mode is not use """ - target = 0 - if not self.is_psu_fan: - chip = self.emc2305_chip_mapping[self.fan_index] - device = chip['device'] - fan_index = chip['index_map'] - sysfs_path = "%s%s/%s" % ( - EMC2305_PATH, device, EMC2305_FAN_TARGET) - sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index]) - raw = self.__read_txt_file(sysfs_path).strip('\r\n') - pwm = int(raw, 10) if raw else 0 - target = math.ceil(float(pwm) * 100 / EMC2305_MAX_PWM) - - return target + return 'N/A' def get_speed_tolerance(self): """ @@ -284,11 +267,43 @@ def get_name(self): def get_presence(self): """ - Retrieves the presence of the PSU + Retrieves the presence of the FAN Returns: - bool: True if PSU is present, False if not + bool: True if FAN is present, False if not """ present_str = self.__get_gpio_value( self.dx010_fan_gpio[self.fan_tray_index+1]['prs']) return int(present_str, 10) == 0 if not self.is_psu_fan else True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + if self.is_psu_fan: + return NULL_VAL + + model = NULL_VAL + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + if self.is_psu_fan: + return NULL_VAL + + serial = NULL_VAL + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and self.get_speed() > 0 diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py new file mode 100644 index 000000000000..86fc5ea726ef --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python + +import os +import struct +import subprocess +from sonic_daemon_base.daemon_base import DaemonBase +from mmap import * + +HOST_CHK_CMD = "docker > /dev/null 2>&1" +EMPTY_STRING = "" + + +class APIHelper(): + + def __init__(self): + (self.platform, self.hwsku) = DaemonBase().get_platform_and_hwsku() + + def is_host(self): + return os.system(HOST_CHK_CMD) == 0 + + def pci_get_value(self, resource, offset): + status = True + result = "" + try: + fd = os.open(resource, os.O_RDWR) + mm = mmap(fd, 0) + mm.seek(int(offset)) + read_data_stream = mm.read(4) + result = struct.unpack('I', read_data_stream) + except: + status = False + return status, result + + def run_command(self, cmd): + status = True + result = "" + try: + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + except: + status = False + return status, result + + def run_interactive_command(self, cmd): + try: + os.system(cmd) + except: + return False + return True + + def read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + def read_one_line_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.readline() + return data.strip() + except IOError: + pass + return None + + def ipmi_raw(self, netfn, cmd): + status = True + result = "" + try: + cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd)) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except: + status = False + return status, result + + def ipmi_fru_id(self, id, key=None): + status = True + result = "" + try: + cmd = "ipmitool fru print {}".format(str( + id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key)) + + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except: + status = False + return status, result + + def ipmi_set_ss_thres(self, id, threshold_key, value): + status = True + result = "" + try: + cmd = "ipmitool sensor thresh '{}' {} {}".format( + str(id), str(threshold_key), str(value)) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except: + status = False + return status, result diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py index 8558b0b0cadd..d34c130dd4be 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py @@ -14,6 +14,7 @@ try: from sonic_platform_base.psu_base import PsuBase from sonic_platform.fan import Fan + from helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -41,6 +42,7 @@ class Psu(PsuBase): def __init__(self, psu_index): PsuBase.__init__(self) self.index = psu_index + self._api_helper = APIHelper() self.green_led_path = GREEN_LED_PATH.format(self.index+1) self.dx010_psu_gpio = [ {'base': self.__get_gpio_base()}, @@ -54,27 +56,18 @@ def __init__(self, psu_index): fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index) self._fan_list.append(fan) - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" - def __search_file_by_contain(self, directory, search_str, file_start): for dirpath, dirnames, files in os.walk(directory): for name in files: file_path = os.path.join(dirpath, name) - if name.startswith(file_start) and search_str in self.__read_txt_file(file_path): + if name.startswith(file_start) and search_str in self._api_helper.read_txt_file(file_path): return file_path return None def __get_gpio_base(self): for r in os.listdir(GPIO_DIR): label_path = os.path.join(GPIO_DIR, r, "label") - if "gpiochip" in r and GPIO_LABEL in self.__read_txt_file(label_path): + if "gpiochip" in r and GPIO_LABEL in self._api_helper.read_txt_file(label_path): return int(r[8:], 10) return 216 # Reserve @@ -82,7 +75,7 @@ def __get_gpio_value(self, pinnum): gpio_base = self.dx010_psu_gpio[0]['base'] gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum) gpio_file = gpio_dir + "/value" - retval = self.__read_txt_file(gpio_file) + retval = self._api_helper.read_txt_file(gpio_file) return retval.rstrip('\r\n') def get_voltage(self): @@ -104,7 +97,7 @@ def get_voltage(self): in_num = filter(str.isdigit, basename) vout_path = os.path.join( dir_name, voltage_name.format(in_num)) - vout_val = self.__read_txt_file(vout_path) + vout_val = self._api_helper.read_txt_file(vout_path) psu_voltage = float(vout_val) / 1000 return psu_voltage @@ -127,7 +120,7 @@ def get_current(self): cur_num = filter(str.isdigit, basename) cur_path = os.path.join( dir_name, current_name.format(cur_num)) - cur_val = self.__read_txt_file(cur_path) + cur_val = self._api_helper.read_txt_file(cur_path) psu_current = float(cur_val) / 1000 return psu_current @@ -150,7 +143,7 @@ def get_power(self): pw_num = filter(str.isdigit, basename) pw_path = os.path.join( dir_name, current_name.format(pw_num)) - pw_val = self.__read_txt_file(pw_path) + pw_val = self._api_helper.read_txt_file(pw_path) psu_power = float(pw_val) / 1000000 return psu_power @@ -196,7 +189,7 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings above """ - status = self.__read_txt_file(self.green_led_path) + status = self._api_helper.read_txt_file(self.green_led_path) status_str = { '255': self.STATUS_LED_COLOR_GREEN, '0': self.STATUS_LED_COLOR_OFF diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py index 330d925fd8a2..c4bfbdfafb2e 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py @@ -8,7 +8,6 @@ # ############################################################################# -import os import time import subprocess import sonic_device_util @@ -16,19 +15,40 @@ try: from sonic_platform_base.sfp_base import SfpBase - from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") INFO_OFFSET = 128 DOM_OFFSET = 0 +# definitions of the offset and width for values in XCVR info eeprom XCVR_INTFACE_BULK_OFFSET = 0 XCVR_INTFACE_BULK_WIDTH_QSFP = 20 -XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 XCVR_VENDOR_NAME_OFFSET = 20 XCVR_VENDOR_NAME_WIDTH = 16 XCVR_VENDOR_OUI_OFFSET = 37 @@ -37,13 +57,29 @@ XCVR_VENDOR_PN_WIDTH = 16 XCVR_HW_REV_OFFSET = 56 XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 XCVR_HW_REV_WIDTH_SFP = 4 XCVR_VENDOR_SN_OFFSET = 68 XCVR_VENDOR_SN_WIDTH = 16 XCVR_VENDOR_DATE_OFFSET = 84 XCVR_VENDOR_DATE_WIDTH = 8 XCVR_DOM_CAPABILITY_OFFSET = 92 -XCVR_DOM_CAPABILITY_WIDTH = 1 +XCVR_DOM_CAPABILITY_WIDTH = 2 + +XCVR_INTERFACE_DATA_START = 0 +XCVR_INTERFACE_DATA_SIZE = 92 + +QSFP_DOM_BULK_DATA_START = 22 +QSFP_DOM_BULK_DATA_SIZE = 36 +SFP_DOM_BULK_DATA_START = 96 +SFP_DOM_BULK_DATA_SIZE = 10 + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 # Offset for values in QSFP eeprom QSFP_DOM_REV_OFFSET = 1 @@ -52,62 +88,110 @@ QSFP_TEMPE_WIDTH = 2 QSFP_VOLT_OFFSET = 26 QSFP_VOLT_WIDTH = 2 +QSFP_VERSION_COMPLIANCE_OFFSET = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 2 QSFP_CHANNL_MON_OFFSET = 34 QSFP_CHANNL_MON_WIDTH = 16 QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 -QSFP_CONTROL_OFFSET = 86 -QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1 QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_MODULE_MONITOR_OFFSET = 0 +QSFP_MODULE_MONITOR_WIDTH = 9 QSFP_POWEROVERRIDE_OFFSET = 93 QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_POWEROVERRIDE_BIT = 0 +QSFP_POWERSET_BIT = 1 +QSFP_OPTION_VALUE_OFFSET = 192 +QSFP_OPTION_VALUE_WIDTH = 4 +QSFP_MODULE_UPPER_PAGE3_START = 384 QSFP_MODULE_THRESHOLD_OFFSET = 128 QSFP_MODULE_THRESHOLD_WIDTH = 24 -QSFP_CHANNEL_THRESHOLD_OFFSET = 176 -QSFP_CHANNEL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 24 + +SFP_MODULE_ADDRA2_OFFSET = 256 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_CHANNL_STATUS_OFFSET = 110 +SFP_CHANNL_STATUS_WIDTH = 1 + qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', 'Fibre Channel link length/Transmitter Technology', 'Fibre Channel transmission media', 'Fibre Channel Speed') +SFP_TYPE = "SFP" +QSFP_TYPE = "QSFP" +OSFP_TYPE = "OSFP" + +PORT_START = 1 +PORT_END = 56 +QSFP_PORT_START = 1 +QSFP_PORT_END = 32 + +SFP_I2C_START = 26 class Sfp(SfpBase): """Platform-specific Sfp class""" - # Port number - PORT_START = 1 - PORT_END = 32 - # Path to QSFP sysfs RESET_PATH = "/sys/devices/platform/dx010_cpld/qsfp_reset" LP_PATH = "/sys/devices/platform/dx010_cpld/qsfp_lpmode" PRS_PATH = "/sys/devices/platform/dx010_cpld/qsfp_modprs" PLATFORM_ROOT_PATH = "/usr/share/sonic/device" PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" - HOST_CHK_CMD = "docker > /dev/null 2>&1" - - PLATFORM = "x86_64-cel_seastone-r0" - HWSKU = "Seastone-DX010" def __init__(self, sfp_index): + SfpBase.__init__(self) # Init index self.index = sfp_index self.port_num = self.index + 1 + self.dom_supported = False + self.sfp_type, self.port_name = self.__get_sfp_info() + self._api_helper = APIHelper() + self.platform = self._api_helper.platform + self.hwsku = self._api_helper.hwsku # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' self.port_to_eeprom_mapping = {} - for x in range(self.PORT_START, self.PORT_END + 1): - p_num = x - 1 if self.PORT_START == 1 else x - self.port_to_eeprom_mapping[x] = eeprom_path.format(p_num + 26) + self.port_to_i2c_mapping = {} + + for x in range(PORT_START, PORT_END + 1): + self.port_to_i2c_mapping[x] = (SFP_I2C_START + x) - 1 + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] @@ -118,9 +202,21 @@ def __init__(self, sfp_index): self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] - SfpBase.__init__(self) + self._dom_capability_detect() + + def __get_sfp_info(self): + port_name = "Unknown" + sfp_type = "Unknown" - def _convert_string_to_num(self, value_str): + if self.port_num >= QSFP_PORT_START and self.port_num <= QSFP_TYPE: + sfp_type = QSFP_TYPE + port_name = "QSFP" + str(self.port_num - QSFP_PORT_START + 1) + elif self.port_num >= SFP_PORT_START and self.port_num <= SFP_PORT_END: + sfp_type = SFP_TYPE + port_name = "SFP" + str(self.port_num - SFP_PORT_START + 1) + return sfp_type, port_name + + def __convert_string_to_num(self, value_str): if "-inf" in value_str: return 'N/A' elif "Unknown" in value_str: @@ -140,22 +236,10 @@ def _convert_string_to_num(self, value_str): else: return 'N/A' - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" - - def __is_host(self): - return os.system(self.HOST_CHK_CMD) == 0 - def __get_path_to_port_config_file(self): - platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) - hwsku_path = "/".join([platform_path, self.HWSKU] - ) if self.__is_host() else self.PMON_HWSKU_PATH + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.platform]) + hwsku_path = "/".join([platform_path, self.hwsku] + ) if self._api_helper.is_host() else self.PMON_HWSKU_PATH return "/".join([hwsku_path, "port_config.ini"]) def __read_eeprom_specific_bytes(self, offset, num_bytes): @@ -180,6 +264,106 @@ def __read_eeprom_specific_bytes(self, offset, num_bytes): return eeprom_raw + def _dom_capability_detect(self): + if not self.get_presence(): + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + return + + if self.sfp_type == "QSFP": + self.calibration = 1 + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + offset = 128 + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qsfp_version_compliance_raw = self.__read_eeprom_specific_bytes( + QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH) + qsfp_version_compliance = int( + qsfp_version_compliance_raw[0], 16) + dom_capability = sfpi_obj.parse_qsfp_dom_capability( + qsfp_dom_capability_raw, 0) + if qsfp_version_compliance >= 0x08: + self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On' + self.dom_volt_supported = dom_capability['data']['Voltage_support']['value'] == 'On' + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' + self.dom_tx_power_supported = dom_capability['data']['Tx_power_support']['value'] == 'On' + else: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' + self.dom_tx_power_supported = True + + self.dom_supported = True + self.calibration = 1 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + qsfp_option_value_raw = self.__read_eeprom_specific_bytes( + QSFP_OPTION_VALUE_OFFSET, QSFP_OPTION_VALUE_WIDTH) + if qsfp_option_value_raw is not None: + optional_capability = sfpd_obj.parse_option_params( + qsfp_option_value_raw, 0) + self.dom_tx_disable_supported = optional_capability[ + 'data']['TxDisable']['value'] == 'On' + dom_status_indicator = sfpd_obj.parse_dom_status_indicator( + qsfp_version_compliance_raw, 1) + self.qsfp_page3_available = dom_status_indicator['data']['FlatMem']['value'] == 'Off' + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.qsfp_page3_available = False + + elif self.sfp_type == "SFP": + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + return None + sfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) + self.dom_supported = (sfp_dom_capability & 0x40 != 0) + if self.dom_supported: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + if sfp_dom_capability & 0x20 != 0: + self.calibration = 1 + elif sfp_dom_capability & 0x10 != 0: + self.calibration = 2 + else: + self.calibration = 0 + else: + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.dom_tx_disable_supported = ( + int(sfp_dom_capability_raw[1], 16) & 0x40 != 0) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + def get_transceiver_info(self): """ Retrieves transceiver info of this SFP @@ -203,85 +387,183 @@ def get_transceiver_info(self): vendor_date |1*255VCHAR |vendor date vendor_oui |1*255VCHAR |vendor OUI ======================================================================== - """ - # check present status - sfpi_obj = sff8436InterfaceId() - if not self.get_presence() or not sfpi_obj: - return {} - - offset = INFO_OFFSET - - sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP) - sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( - sfp_interface_bulk_raw, 0) - - sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) - sfp_vendor_name_data = sfpi_obj.parse_vendor_name( - sfp_vendor_name_raw, 0) - - sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) - sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( - sfp_vendor_pn_raw, 0) - - sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP) - sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( - sfp_vendor_rev_raw, 0) - - sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) - sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( - sfp_vendor_sn_raw, 0) - - sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) - if sfp_vendor_oui_raw is not None: - sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( - sfp_vendor_oui_raw, 0) - - sfp_vendor_date_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) - sfp_vendor_date_data = sfpi_obj.parse_vendor_date( - sfp_vendor_date_raw, 0) - + """ + compliance_code_dict = {} transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') - compliance_code_dict = dict() + if not self.get_presence(): + return transceiver_info_dict + + # ToDo: OSFP tranceiver info parsing not fully supported. + # in inf8628.py lack of some memory map definition + # will be implemented when the inf8628 memory map ready + if self.sfp_type == OSFP_TYPE: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + + sfpi_obj = inf8628InterfaceId() + if sfpi_obj is None: + return None + + sfp_type_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + else: + return None + + transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = 'N/A' + transceiver_info_dict['vendor_date'] = 'N/A' + transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['encoding'] = 'N/A' + transceiver_info_dict['ext_identifier'] = 'N/A' + transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' + transceiver_info_dict['cable_type'] = 'N/A' + transceiver_info_dict['cable_length'] = 'N/A' + transceiver_info_dict['specification_compliance'] = '{}' + transceiver_info_dict['nominal_bit_rate'] = 'N/A' - if sfp_interface_bulk_data: + else: + if self.sfp_type == QSFP_TYPE: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) + if sfp_interface_bulk_raw is None: + return None + + start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START + end = start + interface_info_bulk_width + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_NAME_WIDTH + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_PN_WIDTH + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START + end = start + vendor_rev_width + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_SN_WIDTH + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_OUI_WIDTH + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_DATE_WIDTH + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_interface_bulk_raw[start: end], 0) transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] - transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] - - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[ - 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' - transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' - transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ - 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' - transceiver_info_dict['cable_type'] = "Unknown" - transceiver_info_dict['cable_length'] = "Unknown" - - for key in qsfp_cable_length_tup: - if key in sfp_interface_bulk_data['data']: - transceiver_info_dict['cable_type'] = key - transceiver_info_dict['cable_length'] = str( - sfp_interface_bulk_data['data'][key]['value']) - - for key in qsfp_compliance_code_tup: - if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: - compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] - transceiver_info_dict['specification_compliance'] = str( - compliance_code_dict) - transceiver_info_dict['nominal_bit_rate'] = str( - sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + + + if self.sfp_type == QSFP_TYPE: + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) return transceiver_info_dict @@ -310,84 +592,117 @@ def get_transceiver_bulk_status(self): | |for example, tx2power stands for tx power of channel 2. ======================================================================== """ - # check present status - sfpd_obj = sff8436Dom() - sfpi_obj = sff8436InterfaceId() + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') - if not self.get_presence() or not sfpi_obj or not sfpd_obj: - return {} + if self.sfp_type == OSFP_TYPE: + pass + + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported: + return transceiver_dom_info_dict + + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_data_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_DOM_BULK_DATA_START), QSFP_DOM_BULK_DATA_SIZE) + if dom_data_raw is None: + return transceiver_dom_info_dict + + if self.dom_temp_supported: + start = QSFP_TEMPE_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + temp = self.__convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + if temp is not None: + transceiver_dom_info_dict['temperature'] = temp + + if self.dom_volt_supported: + start = QSFP_VOLT_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + volt = self.__convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + if volt is not None: + transceiver_dom_info_dict['voltage'] = volt + + start = QSFP_CHANNL_MON_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_data_raw[start: end], 0) + + if self.dom_tx_power_supported: + transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX1Power']['value']) + transceiver_dom_info_dict['tx2power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX2Power']['value']) + transceiver_dom_info_dict['tx3power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX3Power']['value']) + transceiver_dom_info_dict['tx4power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX4Power']['value']) + + if self.dom_rx_power_supported: + transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX1Power']['value']) + transceiver_dom_info_dict['rx2power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX2Power']['value']) + transceiver_dom_info_dict['rx3power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX3Power']['value']) + transceiver_dom_info_dict['rx4power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX4Power']['value']) + + transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX1Bias']['value']) + transceiver_dom_info_dict['tx2bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX2Bias']['value']) + transceiver_dom_info_dict['tx3bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX3Bias']['value']) + transceiver_dom_info_dict['tx4bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX4Bias']['value']) - transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') - offset = DOM_OFFSET - offset_xcvr = INFO_OFFSET - - # QSFP capability byte parse, through this byte can know whether it support tx_power or not. - # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, - # need to add more code for determining the capability and version compliance - # in SFF-8636 dom capability definitions evolving with the versions. - qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( - (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) - if qsfp_dom_capability_raw is not None: - qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability( - qsfp_dom_capability_raw, 0) else: - return None + if not self.dom_supported: + return transceiver_dom_info_dict - dom_temperature_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) - if dom_temperature_raw is not None: - dom_temperature_data = sfpd_obj.parse_temperature( - dom_temperature_raw, 0) - transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] - - dom_voltage_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) - if dom_voltage_raw is not None: - dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) - transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] - - qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) - if qsfp_dom_rev_raw is not None: - qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) - qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] - - # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 - # and claimed that it support tx_power with one indicator bit. - dom_channel_monitor_data = {} - dom_channel_monitor_raw = None - qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] - if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) - if dom_channel_monitor_raw is not None: - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( - dom_channel_monitor_raw, 0) + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + sfpd_obj._calibration_type = self.calibration - else: - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) - if dom_channel_monitor_raw is not None: - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( - dom_channel_monitor_raw, 0) - transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] - transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] - transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] - transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] - - if dom_channel_monitor_raw: - transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] - transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] - transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] - transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] - transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] - transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] - transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] - transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] - - for key in transceiver_dom_info_dict: - transceiver_dom_info_dict[key] = self._convert_string_to_num( - transceiver_dom_info_dict[key]) + dom_data_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE) + + start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + + start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + + start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_CHANNL_MON_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_data_raw[start: end], 0) + + transceiver_dom_info_dict['temperature'] = self.__convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + transceiver_dom_info_dict['voltage'] = self.__convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value']) + transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXBias']['value']) + transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value']) transceiver_dom_info_dict['rx_los'] = self.get_rx_los() transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() @@ -426,55 +741,106 @@ def get_transceiver_threshold_info(self): txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. ======================================================================== """ - # check present status - sfpd_obj = sff8436Dom() + transceiver_dom_threshold_info_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') - if not self.get_presence() or not sfpd_obj: - return {} + if self.sfp_type == OSFP_TYPE: + pass - transceiver_dom_threshold_dict = dict.fromkeys( - self.threshold_dict_keys, 'N/A') - dom_thres_raw = self.__read_eeprom_specific_bytes( - QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None - - if dom_thres_raw: - module_threshold_values = sfpd_obj.parse_module_threshold_values( - dom_thres_raw, 0) - module_threshold_data = module_threshold_values.get('data') - if module_threshold_data: - transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] - transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] - transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] - transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] - transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] - transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] - transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] - transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] - - dom_thres_raw = self.__read_eeprom_specific_bytes( - QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None - channel_threshold_values = sfpd_obj.parse_channel_threshold_values( - dom_thres_raw, 0) - channel_threshold_data = channel_threshold_values.get('data') - if channel_threshold_data: - transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] - transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] - transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] - transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] - transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" - transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" - transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" - transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" - transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] - transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] - transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] - transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] - - for key in transceiver_dom_threshold_dict: - transceiver_dom_threshold_dict[key] = self._convert_string_to_num( - transceiver_dom_threshold_dict[key]) - - return transceiver_dom_threshold_dict + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported or not self.qsfp_page3_available: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = QSFP_MODULE_UPPER_PAGE3_START + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values( + dom_module_threshold_raw, 0) + + dom_channel_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is None: + return transceiver_dom_threshold_info_dict + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values( + dom_channel_threshold_raw, 0) + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + + else: + offset = SFP_MODULE_ADDRA2_OFFSET + + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = sff8472Dom(None, self.calibration) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[ + 'data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num( + transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict def get_reset_status(self): """ @@ -482,7 +848,7 @@ def get_reset_status(self): Returns: A Boolean, True if reset enabled, False if disabled """ - reset_status_raw = self.__read_txt_file(self.RESET_PATH).rstrip() + reset_status_raw = self._api_helper.read_txt_file(self.RESET_PATH).rstrip() if not reset_status_raw: return False @@ -498,16 +864,28 @@ def get_rx_los(self): Note : RX LOS status is latched until a call to get_rx_los or a reset. """ rx_los = False - rx_los_list = [] - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) if self.get_presence() else None - if dom_channel_monitor_raw is not None: - rx_los_data = int(dom_channel_monitor_raw[0], 16) - rx_los_list.append(rx_los_data & 0x01 != 0) - rx_los_list.append(rx_los_data & 0x02 != 0) - rx_los_list.append(rx_los_data & 0x04 != 0) - rx_los_list.append(rx_los_data & 0x08 != 0) - rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3] + if self.sfp_type == OSFP_TYPE: + return False + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx1_los = (rx_los_data & 0x01 != 0) + rx2_los = (rx_los_data & 0x02 != 0) + rx3_los = (rx_los_data & 0x04 != 0) + rx4_los = (rx_los_data & 0x08 != 0) + rx_los = (rx1_los and rx2_los and rx3_los and rx4_los) + else: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los = (rx_los_data & 0x02 != 0) + return rx_los def get_tx_fault(self): @@ -517,19 +895,32 @@ def get_tx_fault(self): A Boolean, True if SFP has TX fault, False if not Note : TX fault status is lached until a call to get_tx_fault or a reset. """ - tx_fault = False - tx_fault_list = [] - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) if self.get_presence() else None - if dom_channel_monitor_raw is not None: - tx_fault_data = int(dom_channel_monitor_raw[0], 16) - tx_fault_list.append(tx_fault_data & 0x01 != 0) - tx_fault_list.append(tx_fault_data & 0x02 != 0) - tx_fault_list.append(tx_fault_data & 0x04 != 0) - tx_fault_list.append(tx_fault_data & 0x08 != 0) - tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3] + tx4_fault = False + + if self.sfp_type == OSFP_TYPE or not self.dom_supported: + return False + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx1_fault = (tx_fault_data & 0x01 != 0) + tx2_fault = (tx_fault_data & 0x02 != 0) + tx3_fault = (tx_fault_data & 0x04 != 0) + tx4_fault = (tx_fault_data & 0x08 != 0) + tx4_fault = ( + tx1_fault and tx2_fault and tx3_fault and tx4_fault) + else: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx4_fault = (tx_fault_data & 0x04 != 0) - return tx_fault + return tx4_fault def get_tx_disable(self): """ @@ -537,26 +928,33 @@ def get_tx_disable(self): Returns: A Boolean, True if tx_disable is enabled, False if disabled """ - tx_disable_list = [] - sfpd_obj = sff8436Dom() - if sfpd_obj is None: + tx_disable = False + + if self.sfp_type == OSFP_TYPE and not self.dom_supported: return False - dom_control_raw = self.__read_eeprom_specific_bytes( - QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None - if dom_control_raw is not None: - dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) - tx_disable_list.append( - 'On' == dom_control_data['data']['TX1Disable']['value']) - tx_disable_list.append( - 'On' == dom_control_data['data']['TX2Disable']['value']) - tx_disable_list.append( - 'On' == dom_control_data['data']['TX3Disable']['value']) - tx_disable_list.append( - 'On' == dom_control_data['data']['TX4Disable']['value']) - - return tx_disable_list + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx1_disable = (tx_disable_data & 0x01 != 0) + tx2_disable = (tx_disable_data & 0x02 != 0) + tx3_disable = (tx_disable_data & 0x04 != 0) + tx4_disable = (tx_disable_data & 0x08 != 0) + tx_disable = ( + tx1_disable and tx2_disable and tx3_disable and tx4_disable) + else: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable = (tx_disable_data & 0xC0 != 0) + + return tx_disable def get_tx_disable_channel(self): """ @@ -567,9 +965,29 @@ def get_tx_disable_channel(self): As an example, a returned value of 0x5 indicates that channel 0 and channel 2 have been disabled. """ - tx_disable_list = self.get_tx_disable() - if tx_disable_list is None: - return 0 + tx_disable_list = [False, False, False, False] + + if self.sfp_type == OSFP_TYPE: + pass + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list[0] = (tx_disable_data & 0x01 != 0) + tx_disable_list[1] = (tx_disable_data & 0x02 != 0) + tx_disable_list[2] = (tx_disable_data & 0x04 != 0) + tx_disable_list[3] = (tx_disable_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list[0] = (tx_disable_data & 0xC0 != 0) + tx_disabled = 0 for i in range(len(tx_disable_list)): if tx_disable_list[i]: @@ -610,30 +1028,31 @@ def get_power_override(self): Returns: A Boolean, True if power-override is enabled, False if disabled """ - power_override = False - - offset = 0 - sfpd_obj = sff8436Dom() - if sfpd_obj is None: + if self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes( + dom_control_raw, 0) + power_override = ( + 'On' == dom_control_data['data']['PowerOverride']['value']) + return power_override + else: return False - dom_control_raw = self.__read_eeprom_specific_bytes( - QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None - if dom_control_raw is not None: - dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) - power_override = ( - 'On' == dom_control_data['data']['PowerOverride']['value']) - - return power_override - def get_temperature(self): """ Retrieves the temperature of this SFP Returns: An integer number of current temperature in Celsius """ - transceiver_dom_info_dict = self.get_transceiver_bulk_status() - return transceiver_dom_info_dict.get("temperature", "N/A") + transceiver_bulk_status = self.get_transceiver_bulk_status() + return transceiver_bulk_status.get("temperature", "N/A") def get_voltage(self): """ @@ -641,8 +1060,8 @@ def get_voltage(self): Returns: An integer number of supply voltage in mV """ - transceiver_dom_info_dict = self.get_transceiver_bulk_status() - return transceiver_dom_info_dict.get("voltage", "N/A") + transceiver_bulk_status = self.get_transceiver_bulk_status() + return transceiver_bulk_status.get("voltage", "N/A") def get_tx_bias(self): """ @@ -652,12 +1071,13 @@ def get_tx_bias(self): for channel 0 to channel 4. Ex. ['110.09', '111.12', '108.21', '112.09'] """ - transceiver_dom_info_dict = self.get_transceiver_bulk_status() - tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") - tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A") - tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A") - tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A") - return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else [] + transceiver_bulk_status = self.get_transceiver_bulk_status() + tx1_bs = transceiver_bulk_status.get("tx1bias", "N/A") + tx2_bs = transceiver_bulk_status.get("tx2bias", "N/A") + tx3_bs = transceiver_bulk_status.get("tx3bias", "N/A") + tx4_bs = transceiver_bulk_status.get("tx4bias", "N/A") + tx_bias_list = [tx1_bs, tx2_bs, tx3_bs, tx4_bs] + return tx_bias_list def get_rx_power(self): """ @@ -667,12 +1087,14 @@ def get_rx_power(self): power in mW for channel 0 to channel 4. Ex. ['1.77', '1.71', '1.68', '1.70'] """ - transceiver_dom_info_dict = self.get_transceiver_bulk_status() - rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") - rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A") - rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A") - rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A") - return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else [] + rx_power_list = [] + transceiver_bulk_status = self.get_transceiver_bulk_status() + rx1_p = transceiver_bulk_status.get("rx1power", "N/A") + rx2_p = transceiver_bulk_status.get("rx2power", "N/A") + rx3_p = transceiver_bulk_status.get("rx3power", "N/A") + rx4_p = transceiver_bulk_status.get("rx4power", "N/A") + rx_power_list = [rx1_p, rx2_p, rx3_p, rx4_p] + return rx_power_list def get_tx_power(self): """ @@ -682,12 +1104,14 @@ def get_tx_power(self): for channel 0 to channel 4. Ex. ['1.86', '1.86', '1.86', '1.86'] """ - transceiver_dom_info_dict = self.get_transceiver_bulk_status() - tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") - tx2_pw = transceiver_dom_info_dict.get("tx2power", "N/A") - tx3_pw = transceiver_dom_info_dict.get("tx3power", "N/A") - tx4_pw = transceiver_dom_info_dict.get("tx4power", "N/A") - return [tx1_pw, tx2_pw, tx3_pw, tx4_pw] + tx_power_list = [] + transceiver_bulk_status = self.get_transceiver_bulk_status() + tx1_p = transceiver_bulk_status.get("tx1power", "N/A") + tx2_p = transceiver_bulk_status.get("tx2power", "N/A") + tx3_p = transceiver_bulk_status.get("tx3power", "N/A") + tx4_p = transceiver_bulk_status.get("tx4power", "N/A") + tx_power_list = [tx1_p, tx2_p, tx3_p, tx4_p] + return tx_power_list def reset(self): """ @@ -749,24 +1173,26 @@ def tx_disable(self, tx_disable): Returns: A boolean, True if tx_disable is set successfully, False if not """ - sysfsfile_eeprom = None - try: - tx_disable_ctl = 0xf if tx_disable else 0x0 - buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) - # Write to eeprom - sysfsfile_eeprom = open( - self.port_to_eeprom_mapping[self.port_num], "r+b") - sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) - sysfsfile_eeprom.write(buffer[0]) - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return False - finally: - if sysfsfile_eeprom is not None: - sysfsfile_eeprom.close() - time.sleep(0.01) - return True + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + tx_disable_ctl = 0xf if tx_disable else 0x0 + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + #print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False def tx_disable_channel(self, channel, disable): """ @@ -779,28 +1205,30 @@ def tx_disable_channel(self, channel, disable): Returns: A boolean, True if successful, False if not """ - sysfsfile_eeprom = None - try: - channel_state = self.get_tx_disable_channel() - tx_enable_mask = [0xe, 0xd, 0xb, 0x7] - tx_disable_mask = [0x1, 0x3, 0x7, 0xf] - tx_disable_ctl = channel_state | tx_disable_mask[ - channel] if disable else channel_state & tx_enable_mask[channel] - buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) - # Write to eeprom - sysfsfile_eeprom = open( - self.port_to_eeprom_mapping[self.port_num], "r+b") - sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) - sysfsfile_eeprom.write(buffer[0]) - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return False - finally: - if sysfsfile_eeprom is not None: - sysfsfile_eeprom.close() - time.sleep(0.01) - return True + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + channel_state = self.get_tx_disable_channel() + tx_enable_mask = [0xe, 0xd, 0xb, 0x7] + tx_disable_mask = [0x1, 0x3, 0x7, 0xf] + tx_disable_ctl = channel_state | tx_disable_mask[ + channel] if disable else channel_state & tx_enable_mask[channel] + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + #print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False def set_lpmode(self, lpmode): """ @@ -856,30 +1284,36 @@ def set_power_override(self, power_override, power_set): A boolean, True if power-override and power_set are set successfully, False if not """ - try: - power_override_bit = 0 - if power_override: - power_override_bit |= 1 << 0 - - power_set_bit = 0 - if power_set: - power_set_bit |= 1 << 1 + if self.sfp_type == QSFP_TYPE: + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + #print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False - buffer = create_string_buffer(1) - buffer[0] = chr(power_override_bit | power_set_bit) - # Write to eeprom - sysfsfile_eeprom = open( - self.port_to_eeprom_mapping[self.port_num], "r+b") - sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) - sysfsfile_eeprom.write(buffer[0]) - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return False - finally: - if sysfsfile_eeprom is not None: - sysfsfile_eeprom.close() - time.sleep(0.01) - return True + ############################################################## + ###################### Device methods ######################## + ############################################################## def get_name(self): """ @@ -899,7 +1333,7 @@ def get_presence(self): Returns: bool: True if PSU is present, False if not """ - presence_status_raw = self.__read_txt_file(self.PRS_PATH).rstrip() + presence_status_raw = self._api_helper.read_txt_file(self.PRS_PATH).rstrip() if not presence_status_raw: return False diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py index 1e0a2c4b5645..18c2bd30c03e 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py @@ -14,6 +14,7 @@ try: from sonic_platform_base.thermal_base import ThermalBase + from helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -27,6 +28,7 @@ class Thermal(ThermalBase): def __init__(self, thermal_index): self.index = thermal_index + self._api_helper = APIHelper() # Add thermal name self.THERMAL_NAME_LIST.append("Front-panel temp sensor 1") @@ -48,19 +50,11 @@ def __init__(self, thermal_index): self.ss_key = self.THERMAL_NAME_LIST[self.index] self.ss_index = 1 - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - def __get_temp(self, temp_file): temp_file_path = os.path.join(self.hwmon_path, temp_file) - raw_temp = self.__read_txt_file(temp_file_path) + raw_temp = self._api_helper.read_txt_file(temp_file_path) temp = float(raw_temp)/1000 - return "{:.3f}".format(temp) + return float("{:.3f}".format(temp)) def __set_threshold(self, file_name, temperature): temp_file_path = os.path.join(self.hwmon_path, file_name) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install index 9b456a7c9112..a36e2cd1377c 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install @@ -2,7 +2,7 @@ dx010/scripts/dx010_check_qsfp.sh usr/local/bin dx010/cfg/dx010-modules.conf etc/modules-load.d dx010/systemd/platform-modules-dx010.service lib/systemd/system dx010/scripts/fancontrol.sh etc/init.d -services/fancontrol/fancontrol.service lib/systemd/system +dx010/scripts/fancontrol.service lib/systemd/system services/fancontrol/fancontrol usr/local/bin dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install index df78b7a34ea4..4fdfd33f1ec3 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install @@ -1,7 +1,7 @@ haliburton/cfg/haliburton-modules.conf etc/modules-load.d haliburton/systemd/platform-modules-haliburton.service lib/systemd/system haliburton/script/fancontrol.sh etc/init.d -services/fancontrol/fancontrol.service lib/systemd/system +haliburton/script/fancontrol.service lib/systemd/system services/fancontrol/fancontrol usr/local/bin haliburton/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_e1031-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service new file mode 100755 index 000000000000..25b9f34df2d0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service @@ -0,0 +1,12 @@ +[Unit] +Description=fan speed regulator +After=platform-modules-dx010.service +Before=pmon.service + +[Service] +ExecStart=-/etc/init.d/fancontrol.sh start +ExecStop=-/etc/init.d/fancontrol.sh stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol.service b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/fancontrol.service similarity index 100% rename from platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol.service rename to platform/broadcom/sonic-platform-modules-cel/haliburton/script/fancontrol.service From 2f7924b196b5b6b517750d6b7d1e690f78b76e27 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Fri, 22 May 2020 09:42:46 -0700 Subject: [PATCH 0693/1427] Update submodule [sonic-restapi] (#4630) --- src/sonic-restapi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-restapi b/src/sonic-restapi index c219e3da28fb..95e6bf8dcbf9 160000 --- a/src/sonic-restapi +++ b/src/sonic-restapi @@ -1 +1 @@ -Subproject commit c219e3da28fb20b63b065ceb1828125593d73f14 +Subproject commit 95e6bf8dcbf9a3052c01cb8264f0a750eda91625 From 75fe8888d2b40d68cd3230e56e22418a39238a9f Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 14 May 2020 16:42:58 +0000 Subject: [PATCH 0694/1427] [docker-base]: add supervisord-dependent-startup plugin for supervisord --- dockers/docker-base-buster/Dockerfile.j2 | 3 +++ dockers/docker-base-stretch/Dockerfile.j2 | 3 +++ 2 files changed, 6 insertions(+) diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index a8df37aaf2a5..5056d9c72485 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -88,6 +88,9 @@ RUN apt-get -y purge \ {{ install_debian_packages(docker_base_buster_debs.split(' ')) }} {%- endif %} +# Add support for supervisord to handle startup dependencies +RUN pip install supervisord-dependent-startup==1.4.0 + # Clean up apt # Remove /var/lib/apt/lists/*, could be obsoleted for derived images RUN apt-get clean -y && \ diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index a65413164db8..8907a77e6b67 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -86,6 +86,9 @@ RUN apt-get -y purge \ {{ install_debian_packages(docker_base_stretch_debs.split(' ')) }} {%- endif %} +# Add support for supervisord to handle startup dependencies +RUN pip install supervisord-dependent-startup==1.4.0 + # Clean up apt # Remove /var/lib/apt/lists/*, could be obsoleted for derived images RUN apt-get clean -y && \ From c915c3cbd6dc3a8547100fc393fb7e052c025554 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 14 May 2020 17:39:44 +0000 Subject: [PATCH 0695/1427] [docker-base]: remove dummy password for supervisord control Signed-off-by: Guohan Lu --- dockers/docker-base-buster/etc/supervisor/supervisord.conf | 4 ---- dockers/docker-base-stretch/etc/supervisor/supervisord.conf | 4 ---- 2 files changed, 8 deletions(-) diff --git a/dockers/docker-base-buster/etc/supervisor/supervisord.conf b/dockers/docker-base-buster/etc/supervisor/supervisord.conf index 5d1010e8fa4e..6d7d7390e854 100644 --- a/dockers/docker-base-buster/etc/supervisor/supervisord.conf +++ b/dockers/docker-base-buster/etc/supervisor/supervisord.conf @@ -3,8 +3,6 @@ [unix_http_server] file=/var/run/supervisor.sock ; (the path to the socket file) chmod=0700 ; socket file mode (default 0700) -username=dummy -password=dummy [supervisord] logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) @@ -20,8 +18,6 @@ supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket -username=dummy -password=dummy ; The [include] section can just contain the "files" setting. This ; setting can list multiple files (separated by whitespace or diff --git a/dockers/docker-base-stretch/etc/supervisor/supervisord.conf b/dockers/docker-base-stretch/etc/supervisor/supervisord.conf index 5d1010e8fa4e..6d7d7390e854 100644 --- a/dockers/docker-base-stretch/etc/supervisor/supervisord.conf +++ b/dockers/docker-base-stretch/etc/supervisor/supervisord.conf @@ -3,8 +3,6 @@ [unix_http_server] file=/var/run/supervisor.sock ; (the path to the socket file) chmod=0700 ; socket file mode (default 0700) -username=dummy -password=dummy [supervisord] logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) @@ -20,8 +18,6 @@ supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket -username=dummy -password=dummy ; The [include] section can just contain the "files" setting. This ; setting can list multiple files (separated by whitespace or From 2c7e55ae98cfa4d9d1b5d3c0dd4e22af947f2b1e Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 14 May 2020 21:58:43 +0000 Subject: [PATCH 0696/1427] [docker-frr]: use service dependency in supervisord to start services Signed-off-by: Guohan Lu --- dockers/docker-fpm-frr/Dockerfile.j2 | 5 +- .../{start.sh => docker_init.sh} | 26 ++------ .../supervisord/supervisord.conf.j2} | 66 ++++++++++++------- 3 files changed, 48 insertions(+), 49 deletions(-) rename dockers/docker-fpm-frr/{start.sh => docker_init.sh} (74%) rename dockers/docker-fpm-frr/{supervisord.conf => frr/supervisord/supervisord.conf.j2} (60%) diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index 21318c7a63a3..9499cc1ed51a 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -40,8 +40,7 @@ RUN apt-get clean -y && \ rm -rf /debs ~/.cache COPY ["frr", "/usr/share/sonic/templates"] -COPY ["bgpcfgd", "start.sh", "/usr/bin/"] -COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["bgpcfgd", "docker_init.sh", "/usr/bin/"] COPY ["snmp.conf", "/etc/snmp/frr.conf"] COPY ["TSA", "/usr/bin/TSA"] COPY ["TSB", "/usr/bin/TSB"] @@ -52,4 +51,4 @@ RUN chmod a+x /usr/bin/TSA && \ chmod a+x /usr/bin/TSB && \ chmod a+x /usr/bin/TSC -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/docker_init.sh similarity index 74% rename from dockers/docker-fpm-frr/start.sh rename to dockers/docker-fpm-frr/docker_init.sh index aa72b36e5ce3..a4db7d3cf3c6 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/docker_init.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash mkdir -p /etc/frr +mkdir -p /etc/supervisor/conf.d -CONFIG_TYPE=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["docker_routing_config_mode"]'` +sonic-cfggen -d -t /usr/share/sonic/templates/supervisord/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf +CONFIG_TYPE=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["docker_routing_config_mode"]'` if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then sonic-cfggen -d -t /usr/share/sonic/templates/bgpd/bgpd.conf.j2 -y /etc/sonic/constants.yml > /etc/frr/bgpd.conf sonic-cfggen -d -t /usr/share/sonic/templates/zebra/zebra.conf.j2 > /etc/frr/zebra.conf @@ -29,24 +31,4 @@ chmod 0755 /usr/sbin/bgp-unisolate mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -# start eoiu pulling, only if configured so -if [[ $(sonic-cfggen -d -v 'WARM_RESTART.bgp.bgp_eoiu') == 'true' ]]; then - supervisorctl start bgp_eoiu_marker -fi - -# Start Quagga processes -supervisorctl start zebra -supervisorctl start staticd -supervisorctl start bgpd - -if [ "$CONFIG_TYPE" == "unified" ]; then - supervisorctl start vtysh_b -fi - -supervisorctl start fpmsyncd - -supervisorctl start bgpcfgd +exec /usr/bin/supervisord diff --git a/dockers/docker-fpm-frr/supervisord.conf b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 similarity index 60% rename from dockers/docker-fpm-frr/supervisord.conf rename to dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 index 3e544b64b296..31af4bad43e3 100644 --- a/dockers/docker-fpm-frr/supervisord.conf +++ b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 @@ -3,38 +3,29 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name bgp events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -startsecs=0 -stdout_logfile=syslog -stderr_logfile=syslog - -[program:bgpcfgd] -command=/usr/bin/bgpcfgd -priority=2 -autostart=false -autorestart=false -startsecs=0 -stdout_logfile=syslog -stderr_logfile=syslog - [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=3 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=unexpected startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:zebra] command=/usr/lib/frr/zebra -A 127.0.0.1 -s 90000000 -M fpm -M snmp @@ -44,6 +35,8 @@ autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:staticd] command=/usr/lib/frr/staticd -A 127.0.0.1 @@ -53,6 +46,8 @@ autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:bgpd] command=/usr/lib/frr/bgpd -A 127.0.0.1 -M snmp @@ -63,25 +58,45 @@ autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running -[program:vtysh_b] -command=/usr/bin/vtysh -b +[program:fpmsyncd] +command=fpmsyncd priority=6 autostart=false autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=bgpd:running -[program:fpmsyncd] -command=fpmsyncd +[program:bgpcfgd] +command=/usr/bin/bgpcfgd +priority=6 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=bgpd:running + +{% if DEVICE_METADATA.localhost.docker_routing_config_mode is defined and DEVICE_METADATA.localhost.docker_routing_config_mode == "unified" %} +[program:vtysh_b] +command=/usr/bin/vtysh -b priority=6 autostart=false autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running +{% endif %} +{% if WARM_RESTART is defined and WARM_RESTART.bgp is defined and WARM_RESTART.bgp.bgp_eoiu is defined and WARM_RESTART.bgp.bgp_eoiu == "true" %} [program:bgp_eoiu_marker] command=/usr/bin/bgp_eoiu_marker.py priority=7 @@ -91,3 +106,6 @@ startsecs=0 startretries=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running +{% endif %} From 0c005fdb1c25a2e97ce55692a4a98d2930ac0eac Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 14 May 2020 22:42:23 +0000 Subject: [PATCH 0697/1427] [docker-nat]: use service dependency in supervisord to start servicesx Signed-off-by: Guohan Lu --- dockers/docker-nat/start.sh | 10 --------- dockers/docker-nat/supervisord.conf | 33 ++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/dockers/docker-nat/start.sh b/dockers/docker-nat/start.sh index e1f303fee6f2..68603d007a51 100755 --- a/dockers/docker-nat/start.sh +++ b/dockers/docker-nat/start.sh @@ -1,15 +1,5 @@ #!/usr/bin/env bash -rm -f /var/run/rsyslogd.pid rm -f /var/run/nat/* mkdir -p /var/warmboot/nat - -supervisorctl start rsyslogd - -supervisorctl start natmgrd - -supervisorctl start natsyncd - -supervisorctl start restore_nat_entries - diff --git a/dockers/docker-nat/supervisord.conf b/dockers/docker-nat/supervisord.conf index 839d6f59ab3c..a6fb78aa1bc1 100644 --- a/dockers/docker-nat/supervisord.conf +++ b/dockers/docker-nat/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name nat events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true -autorestart=false +autostart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false -autorestart=unexpected +autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:natmgrd] command=/usr/bin/natmgrd @@ -32,6 +44,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited [program:natsyncd] command=/usr/bin/natsyncd @@ -40,6 +54,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=natmgrd:running [program:restore_nat_entries] command=/usr/bin/restore_nat_entries.py @@ -50,4 +66,5 @@ startsecs=0 startretries=0 stdout_logfile=syslog stderr_logfile=syslog - +dependent_startup=true +dependent_startup_wait_for=natsyncd:running From 267b0b7aa8ed6c732fafa59e0ee862526110a96c Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 14 May 2020 22:44:41 +0000 Subject: [PATCH 0698/1427] [docker-iccpd]: use service dependency in supervisord to start services Signed-off-by: Guohan Lu --- dockers/docker-iccpd/start.sh | 6 ------ dockers/docker-iccpd/supervisord.conf | 25 +++++++++++++++++++------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/dockers/docker-iccpd/start.sh b/dockers/docker-iccpd/start.sh index d17634cb836a..f2e9807f314f 100644 --- a/dockers/docker-iccpd/start.sh +++ b/dockers/docker-iccpd/start.sh @@ -10,9 +10,3 @@ sonic-cfggen -d -t /usr/share/sonic/templates/iccpd.j2 > $ICCPD_CONF_PATH/iccpd. mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start iccpd diff --git a/dockers/docker-iccpd/supervisord.conf b/dockers/docker-iccpd/supervisord.conf index dc71f07c6c30..38d1ee56e643 100644 --- a/dockers/docker-iccpd/supervisord.conf +++ b/dockers/docker-iccpd/supervisord.conf @@ -3,21 +3,33 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:iccpd] command=/usr/bin/iccpd.sh @@ -26,4 +38,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - +dependent_startup=true +dependent_startup_wait_for=start:exited From 1f7602b2750473cedec3e4570f73a4c6aaabfc9a Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 15 May 2020 00:43:46 +0000 Subject: [PATCH 0699/1427] [docker-lldp-sv2]: use service dependency in supervisord to start services --- dockers/docker-lldp-sv2/Dockerfile.j2 | 1 + dockers/docker-lldp-sv2/start.sh | 30 -------------- dockers/docker-lldp-sv2/supervisord.conf.j2 | 39 ++++++++++++++++--- dockers/docker-lldp-sv2/waitfor_lldp_ready.sh | 24 ++++++++++++ 4 files changed, 59 insertions(+), 35 deletions(-) create mode 100755 dockers/docker-lldp-sv2/waitfor_lldp_ready.sh diff --git a/dockers/docker-lldp-sv2/Dockerfile.j2 b/dockers/docker-lldp-sv2/Dockerfile.j2 index f45e1c0df8bb..15e755e6c6ed 100644 --- a/dockers/docker-lldp-sv2/Dockerfile.j2 +++ b/dockers/docker-lldp-sv2/Dockerfile.j2 @@ -37,6 +37,7 @@ RUN apt-get purge -y python-pip && \ COPY ["docker-lldp-init.sh", "/usr/bin/"] COPY ["start.sh", "/usr/bin/"] +COPY ["waitfor_lldp_ready.sh", "/usr/bin/"] COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["lldpd.conf.j2", "/usr/share/sonic/templates/"] COPY ["lldpd", "/etc/default/"] diff --git a/dockers/docker-lldp-sv2/start.sh b/dockers/docker-lldp-sv2/start.sh index 76666e77aca2..5cb6042cee58 100755 --- a/dockers/docker-lldp-sv2/start.sh +++ b/dockers/docker-lldp-sv2/start.sh @@ -5,34 +5,4 @@ sonic-cfggen -d -t /usr/share/sonic/templates/lldpd.conf.j2 > /etc/lldpd.conf mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status -rm -f /var/run/rsyslogd.pid rm -f /var/run/lldpd.socket - -supervisorctl start rsyslogd -supervisorctl start lldpd - -# Current lldpd version has a bug. -# When lldpd starts it is in the pause state by default -# But then it execute 'lldpcli resume' to configure and unpause itself. -# When lldpd execute lldpcli, it doesn't check the return code -# Sometimes lldpcli returns failure, but lldpd doesn't catch it -# and keeps working paused and unconfigured -# -# The fix below addresses the issue. -# - -# wait until lldpd started -until [[ -e /var/run/lldpd.socket ]]; -do - sleep 1; -done - -# Manually try to resume lldpd, until it's successful -while /bin/true; -do - lldpcli -u /var/run/lldpd.socket -c /etc/lldpd.conf -c /etc/lldpd.d resume > /dev/null && break - sleep 1 -done - -supervisorctl start lldp-syncd -supervisorctl start lldpmgrd diff --git a/dockers/docker-lldp-sv2/supervisord.conf.j2 b/dockers/docker-lldp-sv2/supervisord.conf.j2 index beae3aa9425e..776dcd029621 100644 --- a/dockers/docker-lldp-sv2/supervisord.conf.j2 +++ b/dockers/docker-lldp-sv2/supervisord.conf.j2 @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name lldp events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:lldpd] # https://github.com/vincentbernat/lldpd/commit/9856f2792c301116cc4a3fcfba91b9672ee5db1f @@ -41,6 +53,19 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + +[program:waitfor_lldp_ready] +command=/usr/bin/waitfor_lldp_ready.sh +priority=3 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=lldpd:running [program:lldp-syncd] command=/usr/bin/env python2 -m lldp_syncd @@ -49,6 +74,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=waitfor_lldp_ready:exited [program:lldpmgrd] command=/usr/bin/lldpmgrd @@ -57,3 +84,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=lldp-syncd:running diff --git a/dockers/docker-lldp-sv2/waitfor_lldp_ready.sh b/dockers/docker-lldp-sv2/waitfor_lldp_ready.sh new file mode 100755 index 000000000000..ecb16dc2e5f0 --- /dev/null +++ b/dockers/docker-lldp-sv2/waitfor_lldp_ready.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Current lldpd version has a bug. +# When lldpd starts it is in the pause state by default +# But then it execute 'lldpcli resume' to configure and unpause itself. +# When lldpd execute lldpcli, it doesn't check the return code +# Sometimes lldpcli returns failure, but lldpd doesn't catch it +# and keeps working paused and unconfigured +# +# The fix below addresses the issue. +# + +# wait until lldpd started +until [[ -e /var/run/lldpd.socket ]]; +do + sleep 1; +done + +# Manually try to resume lldpd, until it's successful +while /bin/true; +do + lldpcli -u /var/run/lldpd.socket -c /etc/lldpd.conf -c /etc/lldpd.d resume > /dev/null && break + sleep 1 +done From 7ea6d9dc8fffb67823593a729dfed8686f215a2e Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 15 May 2020 04:05:35 +0000 Subject: [PATCH 0700/1427] [docker-radvd]: use service dependency in supervisord to start services --- .../docker-router-advertiser/Dockerfile.j2 | 7 +- .../docker-router-advertiser/docker-init.sh | 13 ++++ .../docker-router-advertiser.supervisord.conf | 35 ---------- ...cker-router-advertiser.supervisord.conf.j2 | 65 +++++++++++++++++++ dockers/docker-router-advertiser/start.sh | 32 --------- 5 files changed, 81 insertions(+), 71 deletions(-) create mode 100755 dockers/docker-router-advertiser/docker-init.sh delete mode 100644 dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf create mode 100644 dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 delete mode 100755 dockers/docker-router-advertiser/start.sh diff --git a/dockers/docker-router-advertiser/Dockerfile.j2 b/dockers/docker-router-advertiser/Dockerfile.j2 index 39e7b28effc1..1b372c401964 100644 --- a/dockers/docker-router-advertiser/Dockerfile.j2 +++ b/dockers/docker-router-advertiser/Dockerfile.j2 @@ -24,10 +24,9 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs -COPY ["start.sh", "/usr/bin/"] -COPY ["docker-router-advertiser.supervisord.conf", "/etc/supervisor/conf.d/"] -COPY ["radvd.conf.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"] +COPY ["docker-init.sh", "/usr/bin/"] +COPY ["radvd.conf.j2", "wait_for_intf.sh.j2", "docker-router-advertiser.supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/bin/docker-init.sh"] diff --git a/dockers/docker-router-advertiser/docker-init.sh b/dockers/docker-router-advertiser/docker-init.sh new file mode 100755 index 000000000000..f93544e7cb64 --- /dev/null +++ b/dockers/docker-router-advertiser/docker-init.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +mkdir -p /etc/supervisor/conf.d +sonic-cfggen -d -t /usr/share/sonic/templates/docker-router-advertiser.supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf + +# Generate /etc/radvd.conf config file +sonic-cfggen -d -t /usr/share/sonic/templates/radvd.conf.j2 > /etc/radvd.conf + +# Generate the script that waits for pertinent interfaces to come up and make it executable +sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh +chmod +x /usr/bin/wait_for_intf.sh + +exec /usr/bin/supervisord diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf deleted file mode 100644 index bf9320acc776..000000000000 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf +++ /dev/null @@ -1,35 +0,0 @@ -[supervisord] -logfile_maxbytes=1MB -logfile_backups=2 -nodaemon=true - -[eventlistener:supervisor-proc-exit-script] -command=/usr/bin/supervisor-proc-exit-listener --container-name radv -events=PROCESS_STATE_EXITED -autostart=true -autorestart=unexpected - -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -startsecs=0 -stdout_logfile=syslog -stderr_logfile=syslog - -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:radvd] -command=/usr/sbin/radvd -n -priority=3 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 new file mode 100644 index 000000000000..146e7c1b67db --- /dev/null +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 @@ -0,0 +1,65 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + +[eventlistener:supervisor-proc-exit-script] +command=/usr/bin/supervisor-proc-exit-listener --container-name radv +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +{# Router advertiser should only run on ToR (T0) devices #} +{% if DEVICE_METADATA.localhost.type == "ToRRouter" %} + + {% if VLAN_INTERFACE %} + {% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} + {# If this VLAN has an IPv6 address... #} + {% if prefix | ipv6 %} + {% set ipv6_found = true %} + {% endif %} + {% endfor %} + {% endif %} + + {# Enusre at least one ipv6 vlan interface #} + {% if ipv6_found == true %} +[program:wait_for_link] +command=/usr/bin/wait_for_link.sh +priority=3 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[program:radvd] +command=/usr/sbin/radvd -n +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=wait_for_link:exited + {% endif %} + +{% endif %} diff --git a/dockers/docker-router-advertiser/start.sh b/dockers/docker-router-advertiser/start.sh deleted file mode 100755 index 8d5f73a8bcb0..000000000000 --- a/dockers/docker-router-advertiser/start.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -# Router advertiser should only run on ToR (T0) devices -DEVICE_ROLE=$(sonic-cfggen -d -v "DEVICE_METADATA.localhost.type") -if [ "$DEVICE_ROLE" != "ToRRouter" ]; then - echo "Device role is not ToRRouter. Not starting router advertiser process." - exit 0 -fi - -# Generate /etc/radvd.conf config file -sonic-cfggen -d -t /usr/share/sonic/templates/radvd.conf.j2 > /etc/radvd.conf - -# Enusre at least one interface is specified in radvd.conf -NUM_IFACES=$(grep -c "^interface " /etc/radvd.conf) -if [ $NUM_IFACES -eq 0 ]; then - echo "No interfaces specified in radvd.conf. Not starting router advertiser process." - exit 0 -fi - -# Generate the script that waits for pertinent interfaces to come up and make it executable -sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh -chmod +x /usr/bin/wait_for_intf.sh - -# Wait for pertinent interfaces to come up -/usr/bin/wait_for_intf.sh - -# Start the router advertiser -supervisorctl start radvd From b8da6c35887b56e607312bf0036d121b20bf8d24 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 00:09:16 +0000 Subject: [PATCH 0701/1427] [docker-orchagent]: use service dependency in supervisord to start services --- dockers/docker-orchagent/Dockerfile.j2 | 5 +- dockers/docker-orchagent/arp_update.conf | 9 ++ .../{start.sh => docker-init.sh} | 36 +----- dockers/docker-orchagent/supervisord.conf | 103 +++++++++++------- 4 files changed, 76 insertions(+), 77 deletions(-) create mode 100644 dockers/docker-orchagent/arp_update.conf rename dockers/docker-orchagent/{start.sh => docker-init.sh} (52%) diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 43c9d5896f34..d08ecdb49d48 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -59,8 +59,9 @@ RUN apt-get clean -y && \ rm -rf /debs COPY ["files/arp_update", "/usr/bin"] +COPY ["arp_update.conf", "/usr/share/sonic/templates/"] COPY ["enable_counters.py", "/usr/bin"] -COPY ["start.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"] +COPY ["docker-init.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor/"] @@ -68,4 +69,4 @@ COPY ["critical_processes", "/etc/supervisor/"] ## Copy all Jinja2 template files into the templates folder COPY ["*.j2", "/usr/share/sonic/templates/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/bin/docker-init.sh"] diff --git a/dockers/docker-orchagent/arp_update.conf b/dockers/docker-orchagent/arp_update.conf new file mode 100644 index 000000000000..a27a3b391cd2 --- /dev/null +++ b/dockers/docker-orchagent/arp_update.conf @@ -0,0 +1,9 @@ +[program:arp_update] +command=/usr/bin/arp_update +priority=7 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited diff --git a/dockers/docker-orchagent/start.sh b/dockers/docker-orchagent/docker-init.sh similarity index 52% rename from dockers/docker-orchagent/start.sh rename to dockers/docker-orchagent/docker-init.sh index b7357ad58f67..82ae41b117bf 100755 --- a/dockers/docker-orchagent/start.sh +++ b/dockers/docker-orchagent/docker-init.sh @@ -11,40 +11,10 @@ if [ -x /usr/share/sonic/hwsku/hwsku-init ]; then /usr/share/sonic/hwsku/hwsku-init fi -export platform=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start orchagent - -supervisorctl start restore_neighbors - -supervisorctl start portsyncd - -supervisorctl start neighsyncd - -supervisorctl start swssconfig - -supervisorctl start vrfmgrd - -supervisorctl start vlanmgrd - -supervisorctl start intfmgrd - -supervisorctl start portmgrd - -supervisorctl start buffermgrd - -supervisorctl start enable_counters - -supervisorctl start nbrmgrd - -supervisorctl start vxlanmgrd - # Start arp_update when VLAN exists VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` if [ "$VLAN" != "" ]; then - supervisorctl start arp_update + cp /usr/share/sonic/templates/arp_update.conf /etc/supervisord/conf.d/ fi + +exec /usr/bin/supervisord diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 6b21d73f3c81..cefbce98c64a 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -3,27 +3,28 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name swss events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:orchagent] command=/usr/bin/orchagent.sh @@ -32,22 +33,20 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running -[program:portsyncd] -command=/usr/bin/portsyncd +[program:restore_neighbors] +command=/usr/bin/restore_neighbors.py priority=4 autostart=false autorestart=false +startsecs=0 +startretries=0 stdout_logfile=syslog stderr_logfile=syslog - -[program:neighsyncd] -command=/usr/bin/neighsyncd -priority=5 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=orchagent:running [program:swssconfig] command=/usr/bin/swssconfig.sh @@ -58,14 +57,28 @@ startretries=0 startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=orchagent:running -[program:arp_update] -command=/usr/bin/arp_update -priority=7 +[program:portsyncd] +command=/usr/bin/portsyncd +priority=4 autostart=false -autorestart=unexpected +autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited + +[program:neighsyncd] +command=/usr/bin/neighsyncd +priority=5 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited [program:vlanmgrd] command=/usr/bin/vlanmgrd @@ -74,6 +87,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited [program:intfmgrd] command=/usr/bin/intfmgrd @@ -82,6 +97,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited [program:portmgrd] command=/usr/bin/portmgrd @@ -90,6 +107,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited [program:buffermgrd] command=/usr/bin/buffermgrd -l /usr/share/sonic/hwsku/pg_profile_lookup.ini @@ -98,14 +117,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - -[program:enable_counters] -command=/usr/bin/enable_counters.py -priority=12 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited [program:vrfmgrd] command=/usr/bin/vrfmgrd @@ -114,16 +127,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - -[program:restore_neighbors] -command=/usr/bin/restore_neighbors.py -priority=14 -autostart=false -autorestart=false -startsecs=0 -startretries=0 -stdout_logfile=syslog -stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited [program:nbrmgrd] command=/usr/bin/nbrmgrd @@ -132,6 +137,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited [program:vxlanmgrd] command=/usr/bin/vxlanmgrd @@ -140,3 +147,15 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited + +[program:enable_counters] +command=/usr/bin/enable_counters.py +priority=12 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited From 1636be4b681bf5256627f98ec326450206217a5d Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 00:12:01 +0000 Subject: [PATCH 0702/1427] [docker-sflow]: use service dependency in supervisord to start services --- dockers/docker-sflow/Dockerfile.j2 | 1 - dockers/docker-sflow/start.sh | 7 ------- dockers/docker-sflow/supervisord.conf | 25 ++++++++++++++----------- 3 files changed, 14 insertions(+), 19 deletions(-) delete mode 100755 dockers/docker-sflow/start.sh diff --git a/dockers/docker-sflow/Dockerfile.j2 b/dockers/docker-sflow/Dockerfile.j2 index 75da64e02e4d..f532a4040e07 100644 --- a/dockers/docker-sflow/Dockerfile.j2 +++ b/dockers/docker-sflow/Dockerfile.j2 @@ -27,7 +27,6 @@ RUN apt-get clean -y && \ RUN sed -ri '/^DAEMON_ARGS=""/c DAEMON_ARGS="-c /var/log/hsflowd.crash"' /etc/init.d/hsflowd -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] diff --git a/dockers/docker-sflow/start.sh b/dockers/docker-sflow/start.sh deleted file mode 100755 index aaefb4d6d004..000000000000 --- a/dockers/docker-sflow/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start sflowmgrd diff --git a/dockers/docker-sflow/supervisord.conf b/dockers/docker-sflow/supervisord.conf index 8eb1bdc05e57..3605e50318dc 100644 --- a/dockers/docker-sflow/supervisord.conf +++ b/dockers/docker-sflow/supervisord.conf @@ -3,32 +3,35 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name sflow events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:sflowmgrd] command=/usr/bin/sflowmgrd -priority=3 +priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running From 8da46d26c3dd3135e97eaaedb0cbfab614ae6409 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 01:00:47 +0000 Subject: [PATCH 0703/1427] [docker-pmon]: use service dependency in supervisord to start services --- dockers/docker-platform-monitor/Dockerfile.j2 | 4 +- .../docker-pmon.supervisord.conf.j2 | 41 ++++++++-- .../docker-platform-monitor/docker_init.sh | 40 +++++++-- dockers/docker-platform-monitor/start.sh | 33 ++++++++ dockers/docker-platform-monitor/start.sh.j2 | 81 ------------------- 5 files changed, 100 insertions(+), 99 deletions(-) create mode 100755 dockers/docker-platform-monitor/start.sh delete mode 100644 dockers/docker-platform-monitor/start.sh.j2 diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index d1b6d7dfc779..b167dea0085e 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -55,8 +55,8 @@ RUN apt-get purge -y \ /python-wheels \ ~/.cache -COPY ["docker_init.sh", "lm-sensors.sh", "/usr/bin/"] -COPY ["docker-pmon.supervisord.conf.j2", "start.sh.j2", "/usr/share/sonic/templates/"] +COPY ["docker_init.sh", "lm-sensors.sh", "start.sh", "/usr/bin/"] +COPY ["docker-pmon.supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["ssd_tools/*", "/usr/bin/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index c79a13005f3f..a002d2bded83 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -3,30 +3,41 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name pmon events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog -startsecs=0 +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +startsecs=0 +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running -{% if not skip_sensors %} +{% if not skip_sensors and HAVE_SENSORS_CONF == 1 %} [program:lm-sensors] command=/usr/bin/lm-sensors.sh priority=3 @@ -35,9 +46,11 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} -{% if not skip_fancontrol %} +{% if not skip_fancontrol and HAVE_FANCONTROL_CONF == 1 %} [program:fancontrol] command=/usr/sbin/fancontrol priority=4 @@ -46,6 +59,8 @@ autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog startsecs=10 +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} {% if not skip_ledd %} @@ -57,6 +72,8 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} {% if not skip_xcvrd %} @@ -68,6 +85,8 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} {% if not skip_psud %} @@ -79,6 +98,8 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} {% if not skip_syseepromd %} @@ -90,6 +111,8 @@ autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog startsecs=10 +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} {% if not skip_thermalctld %} @@ -101,4 +124,6 @@ autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog startsecs=10 +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} diff --git a/dockers/docker-platform-monitor/docker_init.sh b/dockers/docker-platform-monitor/docker_init.sh index a2be49f49dd3..3485c6e9767a 100755 --- a/dockers/docker-platform-monitor/docker_init.sh +++ b/dockers/docker-platform-monitor/docker_init.sh @@ -3,16 +3,40 @@ # Generate supervisord config file and the start.sh scripts mkdir -p /etc/supervisor/conf.d/ -if [ -e /usr/share/sonic/platform/pmon_daemon_control.json ]; + +HAVE_SENSORS_CONF=0 +HAVE_FANCONTROL_CONF=0 + +if [ -e /usr/share/sonic/platform/sensors.conf ]; then + HAVE_SENSORS_CONF=1 +fi + +if [ -e /usr/share/sonic/platform/fancontrol ]; then + HAVE_FANCONTROL_CONF=1 +fi + +confvar="{\"HAVE_SENSORS_CONF\":$HAVE_SENSORS_CONF, \"HAVE_FANCONTROL_CONF\":$HAVE_FANCONTROL_CONF}" + +if [ -e /usr/share/sonic/platform/pmon_daemon_control.json ]; then - sonic-cfggen -j /usr/share/sonic/platform/pmon_daemon_control.json -t /usr/share/sonic/templates/docker-pmon.supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf - sonic-cfggen -j /usr/share/sonic/platform/pmon_daemon_control.json -t /usr/share/sonic/templates/start.sh.j2 > /usr/bin/start.sh - chmod +x /usr/bin/start.sh + sonic-cfggen -j /usr/share/sonic/platform/pmon_daemon_control.json -a "$confvar" -t /usr/share/sonic/templates/docker-pmon.supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf else - sonic-cfggen -t /usr/share/sonic/templates/docker-pmon.supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf - sonic-cfggen -t /usr/share/sonic/templates/start.sh.j2 > /usr/bin/start.sh - chmod +x /usr/bin/start.sh + sonic-cfggen -a "$confvar" -t /usr/share/sonic/templates/docker-pmon.supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf fi -exec /usr/bin/supervisord +# If this platform has an lm-sensors config file, copy it to it's proper place. +if [ -e /usr/share/sonic/platform/sensors.conf ]; then + mkdir -p /etc/sensors.d + /bin/cp -f /usr/share/sonic/platform/sensors.conf /etc/sensors.d/ +fi + +# If this platform has a fancontrol config file, copy it to it's proper place +# and start fancontrol +if [ -e /usr/share/sonic/platform/fancontrol ]; then + # Remove stale pid file if it exists + rm -f /var/run/fancontrol.pid + /bin/cp -f /usr/share/sonic/templates/fancontrol.conf /etc/supervisord/conf.d/ +fi + +exec /usr/bin/supervisord diff --git a/dockers/docker-platform-monitor/start.sh b/dockers/docker-platform-monitor/start.sh new file mode 100755 index 000000000000..58e481476b93 --- /dev/null +++ b/dockers/docker-platform-monitor/start.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +declare -r EXIT_SUCCESS="0" + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +# If this platform has synchronization script, run it +if [ -e /usr/share/sonic/platform/platform_wait ]; then + /usr/share/sonic/platform/platform_wait + EXIT_CODE="$?" + if [ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]; then + supervisorctl shutdown + exit "${EXIT_CODE}" + fi +fi + +# If the sonic-platform package is not installed, try to install it +pip show sonic-platform > /dev/null 2>&1 +if [ $? -ne 0 ]; then + SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py2-none-any.whl" + echo "sonic-platform package not installed, attempting to install..." + if [ -e ${SONIC_PLATFORM_WHEEL} ]; then + pip install ${SONIC_PLATFORM_WHEEL} + if [ $? -eq 0 ]; then + echo "Successfully installed ${SONIC_PLATFORM_WHEEL}" + else + echo "Error: Failed to install ${SONIC_PLATFORM_WHEEL}" + fi + else + echo "Error: Unable to locate ${SONIC_PLATFORM_WHEEL}" + fi +fi diff --git a/dockers/docker-platform-monitor/start.sh.j2 b/dockers/docker-platform-monitor/start.sh.j2 deleted file mode 100644 index 03e0b49b8c4d..000000000000 --- a/dockers/docker-platform-monitor/start.sh.j2 +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env bash - -declare -r EXIT_SUCCESS="0" - -mkdir -p /var/sonic -echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -# If this platform has synchronization script, run it -if [ -e /usr/share/sonic/platform/platform_wait ]; then - /usr/share/sonic/platform/platform_wait - EXIT_CODE="$?" - if [ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]; then - supervisorctl shutdown - exit "${EXIT_CODE}" - fi -fi - -{% if not skip_sensors %} -# If this platform has an lm-sensors config file, copy it to it's proper place -# and start lm-sensors -if [ -e /usr/share/sonic/platform/sensors.conf ]; then - mkdir -p /etc/sensors.d - /bin/cp -f /usr/share/sonic/platform/sensors.conf /etc/sensors.d/ - supervisorctl start lm-sensors -fi -{% endif %} - -{% if not skip_fancontrol %} -# If this platform has a fancontrol config file, copy it to it's proper place -# and start fancontrol -if [ -e /usr/share/sonic/platform/fancontrol ]; then - # Remove stale pid file if it exists - rm -f /var/run/fancontrol.pid - - /bin/cp -f /usr/share/sonic/platform/fancontrol /etc/ - supervisorctl start fancontrol -fi -{% endif %} - - -# If the sonic-platform package is not installed, try to install it -pip show sonic-platform > /dev/null 2>&1 -if [ $? -ne 0 ]; then - SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py2-none-any.whl" - echo "sonic-platform package not installed, attempting to install..." - if [ -e ${SONIC_PLATFORM_WHEEL} ]; then - pip install ${SONIC_PLATFORM_WHEEL} - if [ $? -eq 0 ]; then - echo "Successfully installed ${SONIC_PLATFORM_WHEEL}" - else - echo "Error: Failed to install ${SONIC_PLATFORM_WHEEL}" - fi - else - echo "Error: Unable to locate ${SONIC_PLATFORM_WHEEL}" - fi -fi - -{% if not skip_ledd %} -supervisorctl start ledd -{% endif %} - -{% if not skip_xcvrd %} -supervisorctl start xcvrd -{% endif %} - -{% if not skip_psud %} -supervisorctl start psud -{% endif %} - -{% if not skip_syseepromd %} -supervisorctl start syseepromd -{% endif %} - -{% if not skip_thermalctld %} -supervisorctl start thermalctld -{% endif %} - From 15c6282eacf30085b78bbfbd9e89e656cd41c543 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 01:04:04 +0000 Subject: [PATCH 0704/1427] [docker-restapi]: use service dependency in supervisord to start services --- dockers/docker-sonic-restapi/start.sh | 5 --- dockers/docker-sonic-restapi/supervisord.conf | 36 +++++++++++++------ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/dockers/docker-sonic-restapi/start.sh b/dockers/docker-sonic-restapi/start.sh index bff56a8864c1..d6722a27fc77 100755 --- a/dockers/docker-sonic-restapi/start.sh +++ b/dockers/docker-sonic-restapi/start.sh @@ -2,8 +2,3 @@ mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd -supervisorctl start restapi diff --git a/dockers/docker-sonic-restapi/supervisord.conf b/dockers/docker-sonic-restapi/supervisord.conf index 58afc6dcd7de..6f907a0ab082 100644 --- a/dockers/docker-sonic-restapi/supervisord.conf +++ b/dockers/docker-sonic-restapi/supervisord.conf @@ -3,19 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name restapi events=PROCESS_STATE_EXITED autostart=true autorestart=false -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:restapi] command=/usr/bin/restapi.sh @@ -24,11 +44,7 @@ autostart=false autorestart=true stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 -autostart=false -autorestart=true -stdout_logfile=syslog -stderr_logfile=syslog From 1cf417ed1b2bddd1a12dcd0c81d67cdaf30a2316 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 01:08:00 +0000 Subject: [PATCH 0705/1427] [docker-telemetry]: use service dependency in supervisord to start services Signed-off-by: Guohan Lu --- dockers/docker-sonic-telemetry/start.sh | 7 ----- .../docker-sonic-telemetry/supervisord.conf | 30 ++++++++++++++----- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/dockers/docker-sonic-telemetry/start.sh b/dockers/docker-sonic-telemetry/start.sh index b307e387d557..d6722a27fc77 100755 --- a/dockers/docker-sonic-telemetry/start.sh +++ b/dockers/docker-sonic-telemetry/start.sh @@ -2,10 +2,3 @@ mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start telemetry -supervisorctl start dialout diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index 54f4c5b2348d..d968983cddca 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name telemetry events=PROCESS_STATE_EXITED autostart=true autorestart=false -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true -autorestart=false +autostart=false +autorestart=true stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false -autorestart=true +autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:telemetry] command=/usr/bin/telemetry.sh @@ -32,6 +44,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited [program:dialout] command=/usr/bin/dialout.sh @@ -40,3 +54,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=telemetry:running From 38499ab0f8e58950c4e537c5dab4bca0d8748ac1 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 01:09:51 +0000 Subject: [PATCH 0706/1427] [docker-mgmt-framework]: use service dependency in supervisord to start services Signed-off-by: Guohan Lu --- dockers/docker-sonic-mgmt-framework/start.sh | 6 ----- .../supervisord.conf | 26 ++++++++++++++----- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/dockers/docker-sonic-mgmt-framework/start.sh b/dockers/docker-sonic-mgmt-framework/start.sh index 24d355670e87..d6722a27fc77 100755 --- a/dockers/docker-sonic-mgmt-framework/start.sh +++ b/dockers/docker-sonic-mgmt-framework/start.sh @@ -2,9 +2,3 @@ mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start rest-server diff --git a/dockers/docker-sonic-mgmt-framework/supervisord.conf b/dockers/docker-sonic-mgmt-framework/supervisord.conf index e26f815f5fb9..f78d0ec84121 100644 --- a/dockers/docker-sonic-mgmt-framework/supervisord.conf +++ b/dockers/docker-sonic-mgmt-framework/supervisord.conf @@ -3,21 +3,33 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 -autostart=false +autostart=true autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:rest-server] command=/usr/bin/rest-server.sh @@ -26,3 +38,5 @@ autostart=false autorestart=true stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited From 448d1cdd497f3d0910a1f1a2752bb1ce85a2e3bd Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 01:12:26 +0000 Subject: [PATCH 0707/1427] [docker-teamd]: use service dependency in supervisord to start services --- dockers/docker-teamd/start.sh | 7 ------ dockers/docker-teamd/supervisord.conf | 34 ++++++++++++++++++++------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/dockers/docker-teamd/start.sh b/dockers/docker-teamd/start.sh index 4cbc65ab0cc3..d67bc4e925c8 100755 --- a/dockers/docker-teamd/start.sh +++ b/dockers/docker-teamd/start.sh @@ -1,12 +1,5 @@ #!/usr/bin/env bash -rm -f /var/run/rsyslogd.pid rm -f /var/run/teamd/* mkdir -p /var/warmboot/teamd - -supervisorctl start rsyslogd - -supervisorctl start teammgrd - -supervisorctl start teamsyncd diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index 0c3071bbfdda..166b0be0f7dc 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name teamd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true -autorestart=false +autostart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 -autostart=false -autorestart=unexpected +autostart=true +autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:teammgrd] command=/usr/bin/teammgrd @@ -32,12 +44,16 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited [program:teamsyncd] command=/usr/bin/teamsyncd -priority=3 +priority=4 startsecs=5 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=teammgrd:running From 2e42a4ba0f29e4145cc78e6de3f46b61c342c160 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 15:27:31 +0000 Subject: [PATCH 0708/1427] [docker-dhcp-relay]: use service dependency in supervisord to start services --- .../docker-dhcp-relay.supervisord.conf.j2 | 26 +++++++++++++++---- dockers/docker-dhcp-relay/start.sh | 15 ----------- .../docker-dhcp-relay.supervisord.conf | 26 +++++++++++++++---- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index d52400480775..97de4f360428 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running {# If our configuration has VLANs... #} {% if VLAN %} @@ -81,6 +93,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} {% endif %} @@ -128,6 +142,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=isc-dhcp-relay-{{ vlan_name }}:running {% endif %} {% endif %} diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index dbbf32251080..86ba91147ef5 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -1,11 +1,5 @@ #!/usr/bin/env bash -# Remove stale rsyslog PID file if it exists -rm -f /var/run/rsyslogd.pid - -# Start rsyslog -supervisorctl start rsyslogd - # If our supervisor config has entries in the "isc-dhcp-relay" group... if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then # Wait for all interfaces to come up and be assigned IPv4 addresses before @@ -15,13 +9,4 @@ if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then # relay agent starts, it will not listen or send on that interface for the # lifetime of the process. /usr/bin/wait_for_intf.sh - - # Start all DHCP relay agent(s) - supervisorctl start isc-dhcp-relay:* -fi - -# If our supervisor config has entries in the "dhcpmon" group... -if [ $(supervisorctl status | grep -c "^dhcpmon:") -gt 0 ]; then - # Start all DHCP Monitor daemon(s) - supervisorctl start dhcpmon:* fi diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index fde1d6c7714d..6eeba48fe9af 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [group:isc-dhcp-relay] programs=isc-dhcp-relay-Vlan1000 @@ -35,6 +47,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited [group:dhcpmon] @@ -47,6 +61,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=isc-dhcp-relay-Vlan1000:running From ecde1fe1aad4d2460c383069659547a25b0dee3a Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 15:33:46 +0000 Subject: [PATCH 0709/1427] [docker-syncd-vs]: use service dependency in supervisord to start services --- platform/vs/docker-syncd-vs/start.sh | 31 -------------------- platform/vs/docker-syncd-vs/supervisord.conf | 28 +++++++++++++----- 2 files changed, 21 insertions(+), 38 deletions(-) diff --git a/platform/vs/docker-syncd-vs/start.sh b/platform/vs/docker-syncd-vs/start.sh index 98c7d9c15a0d..40178f13e004 100755 --- a/platform/vs/docker-syncd-vs/start.sh +++ b/platform/vs/docker-syncd-vs/start.sh @@ -1,30 +1,7 @@ #!/usr/bin/env bash -PLATFORM_DIR=/usr/share/sonic/platform HWSKU_DIR=/usr/share/sonic/hwsku -SYNCD_SOCKET_FILE=/var/run/sswsyncd/sswsyncd.socket - -# Function: wait until syncd has created the socket for bcmcmd to connect to -wait_syncd() { - while true; do - if [ -e ${SYNCD_SOCKET_FILE} ]; then - break - fi - sleep 1 - done - - # wait until bcm sdk is ready to get a request - sleep 3 -} - - -# Remove stale files if they exist -rm -f /var/run/rsyslogd.pid -rm -f ${SYNCD_SOCKET_FILE} - -supervisorctl start rsyslogd - mkdir -p /etc/sai.d/ # Create/Copy the sai.profile to /etc/sai.d/sai.profile @@ -35,11 +12,3 @@ else cp $HWSKU_DIR/sai.profile /etc/sai.d/sai.profile fi fi - -supervisorctl start syncd - -# If this platform has an initialization file for the Broadcom LED microprocessor, load it -if [ -r ${PLATFORM_DIR}/led_proc_init.soc ]; then - wait_syncd - supervisorctl start ledinit -fi diff --git a/platform/vs/docker-syncd-vs/supervisord.conf b/platform/vs/docker-syncd-vs/supervisord.conf index 0c6285d46ae0..b097d1aa8c10 100644 --- a/platform/vs/docker-syncd-vs/supervisord.conf +++ b/platform/vs/docker-syncd-vs/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true -autorestart=false +autostart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false -autorestart=unexpected +autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:syncd] command=/usr/bin/syncd_start.sh @@ -32,3 +44,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited From bb40300cade9452b37384b315901b9c2e3245192 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 15:43:23 +0000 Subject: [PATCH 0710/1427] [docker-syncd-brcm]: use service dependency in supervisord to start services --- .../broadcom/docker-syncd-brcm/Dockerfile.j2 | 2 +- platform/broadcom/docker-syncd-brcm/start.sh | 39 ------------------- .../broadcom/docker-syncd-brcm/start_led.sh | 37 ++++++++++++++++++ .../docker-syncd-brcm/supervisord.conf | 32 +++++++++++---- 4 files changed, 62 insertions(+), 48 deletions(-) create mode 100755 platform/broadcom/docker-syncd-brcm/start_led.sh diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index 1ef1c588777c..ae517eac08ef 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -21,7 +21,7 @@ debs/ ## TODO: add kmod into Depends RUN apt-get install -yf kmod -COPY ["files/dsserve", "files/bcmcmd", "start.sh", "bcmsh", "/usr/bin/"] +COPY ["files/dsserve", "files/bcmcmd", "start.sh", "start_led.sh", "bcmsh", "/usr/bin/"] RUN chmod +x /usr/bin/dsserve /usr/bin/bcmcmd COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] diff --git a/platform/broadcom/docker-syncd-brcm/start.sh b/platform/broadcom/docker-syncd-brcm/start.sh index 146b2efa7406..9927b877a619 100755 --- a/platform/broadcom/docker-syncd-brcm/start.sh +++ b/platform/broadcom/docker-syncd-brcm/start.sh @@ -1,43 +1,12 @@ #!/usr/bin/env bash -PLATFORM_DIR=/usr/share/sonic/platform HWSKU_DIR=/usr/share/sonic/hwsku SYNCD_SOCKET_FILE=/var/run/sswsyncd/sswsyncd.socket -# Function: wait until syncd has created the socket for bcmcmd to connect to -wait_syncd() { - while true; do - if [ -e ${SYNCD_SOCKET_FILE} ]; then - break - fi - sleep 1 - done - - # wait until bcm sdk is ready to get a request - counter=0 - while true; do - /usr/bin/bcmcmd -t 1 "show unit" | grep BCM >/dev/null 2>&1 - rv=$? - if [ $rv -eq 0 ]; then - break - fi - counter=$((counter+1)) - if [ $counter -ge 60 ]; then - echo "syncd is not ready to take commands after $counter re-tries; Exiting!" - break - fi - sleep 1 - done -} - - # Remove stale files if they exist -rm -f /var/run/rsyslogd.pid rm -f ${SYNCD_SOCKET_FILE} -supervisorctl start rsyslogd - mkdir -p /etc/sai.d/ # Create/Copy the sai.profile to /etc/sai.d/sai.profile @@ -48,11 +17,3 @@ else cp $HWSKU_DIR/sai.profile /etc/sai.d/sai.profile fi fi - -supervisorctl start syncd - -# If this platform has an initialization file for the Broadcom LED microprocessor, load it -if [[ -r ${PLATFORM_DIR}/led_proc_init.soc && ! -f /var/warmboot/warm-starting ]]; then - wait_syncd - supervisorctl start ledinit -fi diff --git a/platform/broadcom/docker-syncd-brcm/start_led.sh b/platform/broadcom/docker-syncd-brcm/start_led.sh new file mode 100755 index 000000000000..01d25cded8ea --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/start_led.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +PLATFORM_DIR=/usr/share/sonic/platform +SYNCD_SOCKET_FILE=/var/run/sswsyncd/sswsyncd.socket + +# Function: wait until syncd has created the socket for bcmcmd to connect to +wait_syncd() { + while true; do + if [ -e ${SYNCD_SOCKET_FILE} ]; then + break + fi + sleep 1 + done + + # wait until bcm sdk is ready to get a request + counter=0 + while true; do + /usr/bin/bcmcmd -t 1 "show unit" | grep BCM >/dev/null 2>&1 + rv=$? + if [ $rv -eq 0 ]; then + break + fi + counter=$((counter+1)) + if [ $counter -ge 60 ]; then + echo "syncd is not ready to take commands after $counter re-tries; Exiting!" + break + fi + sleep 1 + done +} + +# If this platform has an initialization file for the Broadcom LED microprocessor, load it +if [[ -r ${PLATFORM_DIR}/led_proc_init.soc && ! -f /var/warmboot/warm-starting ]]; then + wait_syncd +fi + +/usr/bin/bcmcmd -t 60 "rcload /usr/share/sonic/platform/led_proc_init.soc" diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index 3fa8febb85d8..e0ac48c0a243 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true -autorestart=false +autostart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false -autorestart=unexpected +autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:syncd] command=/usr/bin/syncd_start.sh @@ -32,12 +44,16 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited [program:ledinit] -command=/usr/bin/bcmcmd -t 60 "rcload /usr/share/sonic/platform/led_proc_init.soc" +command=/usr/bin/start_led.sh priority=4 autostart=false autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=syncd:running From 5664f68bb70c9de871589fcf4816382a3d57ba4e Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 15:46:18 +0000 Subject: [PATCH 0711/1427] [docker-syncd-mlnx]: use service dependency in supervisord to start services --- .../mellanox/docker-syncd-mlnx/Dockerfile.j2 | 1 - platform/mellanox/docker-syncd-mlnx/start.sh | 8 ------ .../docker-syncd-mlnx/supervisord.conf | 25 +++++++++++-------- 3 files changed, 14 insertions(+), 20 deletions(-) delete mode 100755 platform/mellanox/docker-syncd-mlnx/start.sh diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index 6953933735fa..c2cfc9edbbdd 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -35,7 +35,6 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor/"] diff --git a/platform/mellanox/docker-syncd-mlnx/start.sh b/platform/mellanox/docker-syncd-mlnx/start.sh deleted file mode 100755 index 96e2a9128081..000000000000 --- a/platform/mellanox/docker-syncd-mlnx/start.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd - diff --git a/platform/mellanox/docker-syncd-mlnx/supervisord.conf b/platform/mellanox/docker-syncd-mlnx/supervisord.conf index 0c6285d46ae0..dc6977ed4710 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -3,32 +3,35 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh -priority=3 +priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running From 82dc8ace12863cff08f80bb06dc418fa0e9edab7 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 16:06:05 +0000 Subject: [PATCH 0712/1427] [docker-syncd-bfn]: use service dependency in supervisord to start services --- platform/barefoot/docker-syncd-bfn/start.sh | 5 ---- .../docker-syncd-bfn/supervisord.conf | 26 ++++++++++++++----- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/platform/barefoot/docker-syncd-bfn/start.sh b/platform/barefoot/docker-syncd-bfn/start.sh index 1a39db4a9d83..0fcdef4a961e 100755 --- a/platform/barefoot/docker-syncd-bfn/start.sh +++ b/platform/barefoot/docker-syncd-bfn/start.sh @@ -1,9 +1,4 @@ #!/usr/bin/env bash -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - . /opt/bfn/install/bin/dma_setup.sh # . /opt/bfn/install/bin/bf_kdrv_mod_load /opt/bfn/install -LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/bfn/install/lib supervisorctl start syncd diff --git a/platform/barefoot/docker-syncd-bfn/supervisord.conf b/platform/barefoot/docker-syncd-bfn/supervisord.conf index 1744d6ffefb5..7083a174c59b 100644 --- a/platform/barefoot/docker-syncd-bfn/supervisord.conf +++ b/platform/barefoot/docker-syncd-bfn/supervisord.conf @@ -3,33 +3,47 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:syncd] +environment=LD_LIBRARY_PATH="/opt/bfn/install/lib" command=/usr/bin/syncd_start.sh priority=3 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - +dependent_startup=true +dependent_startup_wait_for=start:exited From 745f58cde7d2253a7567707ee071c8c44c283e1e Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 16:09:05 +0000 Subject: [PATCH 0713/1427] [docker-syncd-invm]: use service dependency in supervisord to start services --- .../innovium/docker-syncd-invm/Dockerfile.j2 | 1 - platform/innovium/docker-syncd-invm/start.sh | 7 ------- .../docker-syncd-invm/supervisord.conf | 21 +++++++++++-------- 3 files changed, 12 insertions(+), 17 deletions(-) delete mode 100755 platform/innovium/docker-syncd-invm/start.sh diff --git a/platform/innovium/docker-syncd-invm/Dockerfile.j2 b/platform/innovium/docker-syncd-invm/Dockerfile.j2 index 6f6f5eca9b60..27054e23e472 100755 --- a/platform/innovium/docker-syncd-invm/Dockerfile.j2 +++ b/platform/innovium/docker-syncd-invm/Dockerfile.j2 @@ -24,7 +24,6 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] ## Clean up diff --git a/platform/innovium/docker-syncd-invm/start.sh b/platform/innovium/docker-syncd-invm/start.sh deleted file mode 100755 index 623316050475..000000000000 --- a/platform/innovium/docker-syncd-invm/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd diff --git a/platform/innovium/docker-syncd-invm/supervisord.conf b/platform/innovium/docker-syncd-invm/supervisord.conf index 1af5d70a1d0c..a614d68f2890 100755 --- a/platform/innovium/docker-syncd-invm/supervisord.conf +++ b/platform/innovium/docker-syncd-invm/supervisord.conf @@ -3,26 +3,29 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh -priority=3 +priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running From 7ae67d0dcfb53e7daf8c24b0c91d0b497b213447 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 16:11:24 +0000 Subject: [PATCH 0714/1427] [docker-syncd-centec]: use service dependency in supervisord to start services Signed-off-by: Guohan Lu --- .../centec/docker-syncd-centec/Dockerfile.j2 | 3 +-- platform/centec/docker-syncd-centec/start.sh | 7 ------ .../docker-syncd-centec/supervisord.conf | 25 +++++++++++-------- 3 files changed, 15 insertions(+), 20 deletions(-) delete mode 100755 platform/centec/docker-syncd-centec/start.sh diff --git a/platform/centec/docker-syncd-centec/Dockerfile.j2 b/platform/centec/docker-syncd-centec/Dockerfile.j2 index 0dfdd9488247..f6c875bab1cc 100755 --- a/platform/centec/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec/Dockerfile.j2 @@ -22,9 +22,8 @@ debs/{{ deb }}{{' '}} ## TODO: add kmod into Depends RUN apt-get install -yf kmod -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin/"] COPY ["critical_processes", "/etc/supervisor/"] ## Clean up diff --git a/platform/centec/docker-syncd-centec/start.sh b/platform/centec/docker-syncd-centec/start.sh deleted file mode 100755 index 623316050475..000000000000 --- a/platform/centec/docker-syncd-centec/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd diff --git a/platform/centec/docker-syncd-centec/supervisord.conf b/platform/centec/docker-syncd-centec/supervisord.conf index 0c6285d46ae0..dc6977ed4710 100644 --- a/platform/centec/docker-syncd-centec/supervisord.conf +++ b/platform/centec/docker-syncd-centec/supervisord.conf @@ -3,32 +3,35 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh -priority=3 +priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running From 918cf632f46b3a97f42bec60da61eb34e1f1c242 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 16:17:37 +0000 Subject: [PATCH 0715/1427] [docker-syncd-mrvl]: use service dependency in supervisord to start services --- .../docker-syncd-mrvl/Dockerfile.j2 | 3 +-- .../marvell-arm64/docker-syncd-mrvl/start.sh | 7 ------ .../docker-syncd-mrvl/supervisord.conf | 23 +++++++++-------- .../docker-syncd-mrvl/Dockerfile.j2 | 3 +-- .../marvell-armhf/docker-syncd-mrvl/start.sh | 7 ------ .../docker-syncd-mrvl/supervisord.conf | 25 +++++++++++-------- .../marvell/docker-syncd-mrvl/Dockerfile.j2 | 2 +- platform/marvell/docker-syncd-mrvl/start.sh | 8 ------ .../docker-syncd-mrvl/supervisord.conf | 24 ++++++++++-------- 9 files changed, 43 insertions(+), 59 deletions(-) delete mode 100755 platform/marvell-arm64/docker-syncd-mrvl/start.sh delete mode 100755 platform/marvell-armhf/docker-syncd-mrvl/start.sh delete mode 100755 platform/marvell/docker-syncd-mrvl/start.sh diff --git a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 index 410911e6a4f8..5f5097f4b4aa 100755 --- a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 @@ -26,9 +26,8 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin/"] COPY ["critical_processes", "/etc/supervisor/"] ## Clean up diff --git a/platform/marvell-arm64/docker-syncd-mrvl/start.sh b/platform/marvell-arm64/docker-syncd-mrvl/start.sh deleted file mode 100755 index 623316050475..000000000000 --- a/platform/marvell-arm64/docker-syncd-mrvl/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd diff --git a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf index b11e045fac7e..e1fd242b4e6d 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf @@ -3,27 +3,28 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh @@ -32,3 +33,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 index 410911e6a4f8..5f5097f4b4aa 100755 --- a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 @@ -26,9 +26,8 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin/"] COPY ["critical_processes", "/etc/supervisor/"] ## Clean up diff --git a/platform/marvell-armhf/docker-syncd-mrvl/start.sh b/platform/marvell-armhf/docker-syncd-mrvl/start.sh deleted file mode 100755 index 623316050475..000000000000 --- a/platform/marvell-armhf/docker-syncd-mrvl/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd diff --git a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf index b11e045fac7e..0adb188ce329 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf @@ -3,32 +3,35 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh -priority=3 +priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 index 40973653e8d3..5679fb38e338 100755 --- a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 @@ -21,7 +21,7 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -COPY ["start.sh", "syncd.sh", "/usr/bin/"] +COPY ["syncd.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor/"] diff --git a/platform/marvell/docker-syncd-mrvl/start.sh b/platform/marvell/docker-syncd-mrvl/start.sh deleted file mode 100755 index 96e2a9128081..000000000000 --- a/platform/marvell/docker-syncd-mrvl/start.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd - diff --git a/platform/marvell/docker-syncd-mrvl/supervisord.conf b/platform/marvell/docker-syncd-mrvl/supervisord.conf index 43de2426f981..12752786ebba 100644 --- a/platform/marvell/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell/docker-syncd-mrvl/supervisord.conf @@ -3,27 +3,28 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh @@ -32,4 +33,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running From 40cb10d2dd8149d427e826177f3dc905583328cb Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 16:21:25 +0000 Subject: [PATCH 0716/1427] [docker-syncd-nephos]: use service dependency in supervisord to start services --- .../nephos/docker-syncd-nephos/Dockerfile.j2 | 2 +- platform/nephos/docker-syncd-nephos/start.sh | 7 ------ .../docker-syncd-nephos/supervisord.conf | 25 +++++++++++-------- 3 files changed, 15 insertions(+), 19 deletions(-) delete mode 100755 platform/nephos/docker-syncd-nephos/start.sh diff --git a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 index f891ace1e8e4..967dad316967 100755 --- a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 @@ -32,7 +32,7 @@ debs/{{ deb }}{{' '}} ##debs/{{ deb }}{{' '}} ##{%- endfor %} -COPY ["files/dsserve", "files/npx_diag", "start.sh", "/usr/bin/"] +COPY ["files/dsserve", "files/npx_diag", "/usr/bin/"] RUN chmod +x /usr/bin/npx_diag /usr/bin/dsserve COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] diff --git a/platform/nephos/docker-syncd-nephos/start.sh b/platform/nephos/docker-syncd-nephos/start.sh deleted file mode 100755 index 623316050475..000000000000 --- a/platform/nephos/docker-syncd-nephos/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd diff --git a/platform/nephos/docker-syncd-nephos/supervisord.conf b/platform/nephos/docker-syncd-nephos/supervisord.conf index 0c6285d46ae0..dc6977ed4710 100644 --- a/platform/nephos/docker-syncd-nephos/supervisord.conf +++ b/platform/nephos/docker-syncd-nephos/supervisord.conf @@ -3,32 +3,35 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh -priority=3 +priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running From 6cd8d5bb68dba16bbd04b1ab6e2e621aba5a5c30 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 19:03:35 +0000 Subject: [PATCH 0717/1427] [docker-snmp-sv2]: use service dependency in supervisord to start services Signed-off-by: Guohan Lu --- dockers/docker-snmp-sv2/start.sh | 6 ----- dockers/docker-snmp-sv2/supervisord.conf | 34 +++++++++++++++++------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/dockers/docker-snmp-sv2/start.sh b/dockers/docker-snmp-sv2/start.sh index 6ec3379df58f..c4929738f9d8 100755 --- a/dockers/docker-snmp-sv2/start.sh +++ b/dockers/docker-snmp-sv2/start.sh @@ -8,9 +8,3 @@ sonic-cfggen -d -y /etc/sonic/snmp.yml -t /usr/share/sonic/templates/snmpd.conf. mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd -supervisorctl start snmpd -supervisorctl start snmp-subagent diff --git a/dockers/docker-snmp-sv2/supervisord.conf b/dockers/docker-snmp-sv2/supervisord.conf index 6af6ae965b17..2ca3686dcd11 100644 --- a/dockers/docker-snmp-sv2/supervisord.conf +++ b/dockers/docker-snmp-sv2/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name snmp events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true -autorestart=false +autostart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 -autostart=false -autorestart=unexpected +[program:start] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:snmpd] command=/usr/sbin/snmpd -f -LS4d -u Debian-snmp -g Debian-snmp -I -smux,mteTrigger,mteTriggerConf,ifTable,ifXTable,inetCidrRouteTable,ipCidrRouteTable,ip,disk_hw -p /run/snmpd.pid @@ -32,6 +44,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited [program:snmp-subagent] command=/usr/bin/env python3 -m sonic_ax_impl @@ -40,3 +54,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=snmpd:running From ddd6368e641c3bf638aecba61d68c22e8b9fb7cd Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 May 2020 19:05:55 +0000 Subject: [PATCH 0718/1427] [docker-database]: do not generate pidfile for rsyslogd Signed-off-by: Guohan Lu --- dockers/docker-database/supervisord.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index 9e855527edba..44268274cdad 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -10,7 +10,7 @@ autostart=true autorestart=unexpected [program:rsyslogd] -command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n" +command=/usr/sbin/rsyslogd -n -iNONE priority=1 autostart=true autorestart=false From 00e7e14927196d7e3d526fe319ee0780413fb8e2 Mon Sep 17 00:00:00 2001 From: taocy Date: Thu, 21 May 2020 07:22:19 +0000 Subject: [PATCH 0719/1427] Install the libraries that j2cli relies on from source, for arm arch. --- dockers/docker-base-buster/Dockerfile.j2 | 9 +++++---- dockers/docker-base-stretch/Dockerfile.j2 | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index 5056d9c72485..fcf983229504 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -62,12 +62,13 @@ RUN apt-get update && \ libpython2.7 \ libdaemon0 \ libdbus-1-3 \ - libjansson4 - + libjansson4 \ # ip and ifconfig utility missing in docker for arm arch -RUN apt-get -y install \ iproute2 \ - net-tools + net-tools \ +# for arm arch: Installing j2cli dependency package MarkupSafe from source relies on weeksetuptools and wheel + python-setuptools \ + python-wheel # For templating RUN pip install j2cli diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 8907a77e6b67..30e59eccf705 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -60,12 +60,13 @@ RUN apt-get update && \ libpython2.7 \ libdaemon0 \ libdbus-1-3 \ - libjansson4 - + libjansson4 \ # ip and ifconfig utility missing in docker for arm arch -RUN apt-get -y install \ iproute2 \ - net-tools + net-tools \ +# for arm arch: Installing j2cli dependency package MarkupSafe from source relies on weeksetuptools and wheel + python-setuptools \ + python-wheel # For templating RUN pip install j2cli From dc0f01006620b86dedc554864a8a25c4fd28a1bc Mon Sep 17 00:00:00 2001 From: taocy Date: Thu, 21 May 2020 07:37:07 +0000 Subject: [PATCH 0720/1427] install crossbuild in buster slave for arm arch kernel compile --- sonic-slave-buster/Dockerfile.j2 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index cdf2476ca50b..c855521374cf 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -315,6 +315,11 @@ RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confold" # For linux build RUN apt-get -y build-dep linux +# For march kernel compile +RUN apt-get install -y crossbuild-essential-amd64 \ + crossbuild-essential-arm64 \ + crossbuild-essential-armhf + # For gobgp and telemetry build RUN export VERSION=1.14.2 \ {%- if CONFIGURED_ARCH == "armhf" %} From 3be2fc56ba12aa0e6f6b8349581a12325885b81e Mon Sep 17 00:00:00 2001 From: taocy Date: Thu, 21 May 2020 12:09:06 +0000 Subject: [PATCH 0721/1427] Versions before 18.09 do not install docker-ce-cli --- build_debian.sh | 7 ++++++- sonic-slave-buster/Dockerfile.j2 | 2 +- sonic-slave-stretch/Dockerfile.j2 | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index a805d34b9391..8d1db8ca37c1 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -204,7 +204,12 @@ sudo LANG=C chroot $FILESYSTEM_ROOT rm /tmp/docker.gpg sudo LANG=C chroot $FILESYSTEM_ROOT add-apt-repository \ "deb [arch=$CONFIGURED_ARCH] https://download.docker.com/linux/debian $IMAGE_DISTRO stable" sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} docker-ce-cli=${DOCKER_VERSION} +if dpkg --compare-versions ${DOCKER_VERSION} ge "18.09"; then + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} docker-ce-cli=${DOCKER_VERSION} +else + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} +fi + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 if [ "$INSTALL_KUBERNETES" == "y" ] diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index c855521374cf..315befbd2b6e 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -419,7 +419,7 @@ RUN apt-get update {%- if CONFIGURED_ARCH == "amd64" %} RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-buster docker-ce-cli=5:18.09.5~3-0~debian-buster {%- else %} -RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian docker-ce-cli=18.06.3~ce~3-0~debian +RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian {%- endif %} RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker RUN update-alternatives --set iptables /usr/sbin/iptables-legacy diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 1844053d5278..2f700a024ac1 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -429,6 +429,6 @@ RUN apt-get update {%- if CONFIGURED_ARCH == "amd64" %} RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-stretch docker-ce-cli=5:18.09.5~3-0~debian-stretch {%- else %} -RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian docker-ce-cli=18.06.3~ce~3-0~debian +RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian {%- endif %} RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker From ea2dd9541d502ec4761ebd7c815be8c55712651d Mon Sep 17 00:00:00 2001 From: taocy Date: Sat, 23 May 2020 18:21:28 +0000 Subject: [PATCH 0722/1427] change image apt source list from stretch to buster for arm --- .../arm64/debian_mirror_arm64.list | 16 ++++++++-------- .../armhf/debian_mirror_armhf.list | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/files/image_config/apt/sources.list.d/arm64/debian_mirror_arm64.list b/files/image_config/apt/sources.list.d/arm64/debian_mirror_arm64.list index 773f58882ae1..9e7dec92d39e 100644 --- a/files/image_config/apt/sources.list.d/arm64/debian_mirror_arm64.list +++ b/files/image_config/apt/sources.list.d/arm64/debian_mirror_arm64.list @@ -1,9 +1,9 @@ -deb [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free -deb-src [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free -deb [arch=arm64] http://deb.debian.org/debian stretch-updates main contrib non-free -deb-src [arch=arm64] http://deb.debian.org/debian stretch-updates main contrib non-free -deb [arch=arm64] http://security.debian.org stretch/updates main contrib non-free -deb-src [arch=arm64] http://security.debian.org stretch/updates main contrib non-free -deb [arch=arm64] https://download.docker.com/linux/debian stretch stable -deb [arch=arm64] http://ftp.debian.org/debian stretch-backports main +deb [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free +deb-src [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free +deb [arch=arm64] http://security.debian.org buster/updates main contrib non-free +deb-src [arch=arm64] http://security.debian.org buster/updates main contrib non-free +deb [arch=arm64] https://download.docker.com/linux/debian buster stable +deb [arch=arm64] http://ftp.debian.org/debian buster-backports main diff --git a/files/image_config/apt/sources.list.d/armhf/debian_mirror_armhf.list b/files/image_config/apt/sources.list.d/armhf/debian_mirror_armhf.list index 501419c6735f..a7b831ef301c 100644 --- a/files/image_config/apt/sources.list.d/armhf/debian_mirror_armhf.list +++ b/files/image_config/apt/sources.list.d/armhf/debian_mirror_armhf.list @@ -1,9 +1,9 @@ -deb [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free -deb-src [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free -deb [arch=armhf] http://deb.debian.org/debian stretch-updates main contrib non-free -deb-src [arch=armhf] http://deb.debian.org/debian stretch-updates main contrib non-free -deb [arch=armhf] http://security.debian.org stretch/updates main contrib non-free -deb-src [arch=armhf] http://security.debian.org stretch/updates main contrib non-free -deb [arch=armhf] https://download.docker.com/linux/debian stretch stable -deb [arch=armhf] http://ftp.debian.org/debian stretch-backports main +deb [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free +deb-src [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free +deb [arch=armhf] http://security.debian.org buster/updates main contrib non-free +deb-src [arch=armhf] http://security.debian.org buster/updates main contrib non-free +deb [arch=armhf] https://download.docker.com/linux/debian buster stable +deb [arch=armhf] http://ftp.debian.org/debian buster-backports main From 4cd36175ceb450b752313c6f0db90991e30f332c Mon Sep 17 00:00:00 2001 From: taocy Date: Sun, 24 May 2020 02:37:24 +0000 Subject: [PATCH 0723/1427] arm arch: 1. install required libraries; 2. umount /proc after dockerfs. --- files/build_templates/sonic_debian_extension.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 81463d20731b..398fa173e346 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -268,6 +268,8 @@ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable core_uploader.service sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.py $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/corefile_uploader/core_analyzer.rc.json $FILESYSTEM_ROOT_ETC_SONIC/ sudo chmod og-rw $FILESYSTEM_ROOT_ETC_SONIC/core_analyzer.rc.json + +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install libffi-dev libssl-dev sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage==0.36.0 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog==0.10.2 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures==3.3.0 @@ -461,7 +463,6 @@ echo "docker images pull complete" sudo umount $FILESYSTEM_ROOT/target sudo rm -r $FILESYSTEM_ROOT/target -sudo umount /proc || true if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then sudo umount $FILESYSTEM_ROOT/dockerfs sudo rm -fr $FILESYSTEM_ROOT/dockerfs @@ -469,6 +470,7 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then else sudo chroot $FILESYSTEM_ROOT service docker stop fi +sudo umount /proc || true sudo rm $FILESYSTEM_ROOT/etc/init.d/docker {% for script in installer_start_scripts.split(' ') -%} sudo cp {{script}} $FILESYSTEM_ROOT/usr/bin/ From 3d0b65d5e22ee059d64af68280e9a0a42ac38739 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Tue, 26 May 2020 14:56:08 +0530 Subject: [PATCH 0724/1427] [devices/dell]: Dell S6000-Q20S48 new HWSKU support (#4628) Added support for S6000 new HWSKU-Q20S48 Modified port_config.ini, TD2 settings to bring the ports UP. Added support for S6000 new HWSKU-Q20S48(20x40G-48x10G) This HWSKU is applicable for S6000 platform, not S6000-ON platform --- .../Force10-S6000-Q20S48/buffers.json.j2 | 3 + .../buffers_defaults_t0.j2 | 63 ++ .../buffers_defaults_t1.j2 | 63 ++ .../pg_profile_lookup.ini | 17 + .../Force10-S6000-Q20S48/port_config.ini | 69 ++ .../Force10-S6000-Q20S48/qos.json.j2 | 1 + .../Force10-S6000-Q20S48/sai.profile | 2 + .../td2-s6000-20x40G-48x10G.config.bcm | 755 ++++++++++++++++++ 8 files changed, 973 insertions(+) create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers.json.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t0.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/pg_profile_lookup.ini create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/port_config.ini create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/qos.json.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/sai.profile create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers.json.j2 new file mode 100755 index 000000000000..e6e9e844469b --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t0.j2 new file mode 100755 index 000000000000..8243498dd31c --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t0.j2 @@ -0,0 +1,63 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,8) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(8,14) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(14,18) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(18,24) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(24,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t1.j2 new file mode 100755 index 000000000000..8243498dd31c --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t1.j2 @@ -0,0 +1,63 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,8) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(8,14) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(14,18) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(18,24) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(24,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/pg_profile_lookup.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/pg_profile_lookup.ini new file mode 100755 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/port_config.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/port_config.ini new file mode 100755 index 000000000000..d999be87623e --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/port_config.ini @@ -0,0 +1,69 @@ +# name lanes alias index speed +Ethernet0 29,30,31,32 fortyGigE0/0 0 40000 +Ethernet4 25,26,27,28 fortyGigE0/4 1 40000 +Ethernet8 37,38,39,40 fortyGigE0/8 2 40000 +Ethernet12 33,34,35,36 fortyGigE0/12 3 40000 +Ethernet16 41,42,43,44 fortyGigE0/16 4 40000 +Ethernet20 45,46,47,48 fortyGigE0/20 5 40000 +Ethernet24 5,6,7,8 fortyGigE0/24 6 40000 +Ethernet28 1,2,3,4 fortyGigE0/28 7 40000 +Ethernet32 9 tenGigE0/32 8 10000 +Ethernet33 10 tenGigE0/33 8 10000 +Ethernet34 11 tenGigE0/34 8 10000 +Ethernet35 12 tenGigE0/35 8 10000 +Ethernet36 13 tenGigE0/36 9 10000 +Ethernet37 14 tenGigE0/37 9 10000 +Ethernet38 15 tenGigE0/38 9 10000 +Ethernet39 16 tenGigE0/39 9 10000 +Ethernet40 21 tenGigE0/40 10 10000 +Ethernet41 22 tenGigE0/41 10 10000 +Ethernet42 23 tenGigE0/42 10 10000 +Ethernet43 24 tenGigE0/43 10 10000 +Ethernet44 17 tenGigE0/44 11 10000 +Ethernet45 18 tenGigE0/45 11 10000 +Ethernet46 19 tenGigE0/46 11 10000 +Ethernet47 20 tenGigE0/47 11 10000 +Ethernet48 49 tenGigE0/48 12 10000 +Ethernet49 50 tenGigE0/49 12 10000 +Ethernet50 51 tenGigE0/50 12 10000 +Ethernet51 52 tenGigE0/51 12 10000 +Ethernet52 53 tenGigE0/52 13 10000 +Ethernet53 54 tenGigE0/53 13 10000 +Ethernet54 55 tenGigE0/54 13 10000 +Ethernet55 56 tenGigE0/55 13 10000 +Ethernet56 61,62,63,64 fortyGigE0/56 14 40000 +Ethernet60 57,58,59,60 fortyGigE0/60 15 40000 +Ethernet64 65,66,67,68 fortyGigE0/64 16 40000 +Ethernet68 69,70,71,72 fortyGigE0/68 17 40000 +Ethernet72 77 tenGigE0/72 18 10000 +Ethernet73 78 tenGigE0/73 18 10000 +Ethernet74 79 tenGigE0/74 18 10000 +Ethernet75 80 tenGigE0/75 18 10000 +Ethernet76 73 tenGigE0/76 19 10000 +Ethernet77 74 tenGigE0/77 19 10000 +Ethernet78 75 tenGigE0/78 19 10000 +Ethernet79 76 tenGigE0/79 19 10000 +Ethernet80 105 tenGigE0/80 20 10000 +Ethernet81 106 tenGigE0/81 20 10000 +Ethernet82 107 tenGigE0/82 20 10000 +Ethernet83 108 tenGigE0/83 20 10000 +Ethernet84 109 tenGigE0/84 21 10000 +Ethernet85 110 tenGigE0/85 21 10000 +Ethernet86 111 tenGigE0/86 21 10000 +Ethernet87 112 tenGigE0/87 21 10000 +Ethernet88 117 tenGigE0/88 22 10000 +Ethernet89 118 tenGigE0/89 22 10000 +Ethernet90 119 tenGigE0/90 22 10000 +Ethernet91 120 tenGigE0/91 22 10000 +Ethernet92 113 tenGigE0/92 23 10000 +Ethernet93 114 tenGigE0/93 23 10000 +Ethernet94 115 tenGigE0/94 23 10000 +Ethernet95 116 tenGigE0/95 23 10000 +Ethernet96 121,122,123,124 fortyGigE0/96 24 40000 +Ethernet100 125,126,127,128 fortyGigE0/100 25 40000 +Ethernet104 85,86,87,88 fortyGigE0/104 26 40000 +Ethernet108 81,82,83,84 fortyGigE0/108 27 40000 +Ethernet112 89,90,91,92 fortyGigE0/112 28 40000 +Ethernet116 93,94,95,96 fortyGigE0/116 29 40000 +Ethernet120 97,98,99,100 fortyGigE0/120 30 40000 +Ethernet124 101,102,103,104 fortyGigE0/124 31 40000 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/qos.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/qos.json.j2 new file mode 100755 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/sai.profile b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/sai.profile new file mode 100755 index 000000000000..22e114e6af26 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-20x40G-48x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm new file mode 100755 index 000000000000..273dfdbe98bb --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm @@ -0,0 +1,755 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000000000000001fffffffffffffffff +pbmp_xport_xe=0x000000000000001fffffffffffffffff + +# Ports configuration +# xe0 (40G) +portmap_1=29:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x213 +phy_xaui_rx_polarity_flip_1=0xc +phy_xaui_tx_polarity_flip_1=0x9 +serdes_driver_current_lane0_1=0x6 +serdes_driver_current_lane1_1=0x7 +serdes_driver_current_lane2_1=0x6 +serdes_driver_current_lane3_1=0x6 +serdes_pre_driver_current_lane0_1=0x6 +serdes_pre_driver_current_lane1_1=0x7 +serdes_pre_driver_current_lane2_1=0x6 +serdes_pre_driver_current_lane3_1=0x6 +serdes_preemphasis_lane0_1=0xc2f0 +serdes_preemphasis_lane1_1=0xd2b0 +serdes_preemphasis_lane2_1=0xc6e0 +serdes_preemphasis_lane3_1=0xc2f0 + +# xe1 (40G) +portmap_2=25:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x2031 +phy_xaui_rx_polarity_flip_2=0xe +phy_xaui_tx_polarity_flip_2=0x2 +serdes_driver_current_lane0_2=0x5 +serdes_driver_current_lane1_2=0x5 +serdes_driver_current_lane2_2=0x5 +serdes_driver_current_lane3_2=0x5 +serdes_pre_driver_current_lane0_2=0x5 +serdes_pre_driver_current_lane1_2=0x5 +serdes_pre_driver_current_lane2_2=0x5 +serdes_pre_driver_current_lane3_2=0x5 +serdes_preemphasis_lane0_2=0xcad0 +serdes_preemphasis_lane1_2=0xc6e0 +serdes_preemphasis_lane2_2=0xc6e0 +serdes_preemphasis_lane3_2=0xd2b0 + +# xe2 (40G) +portmap_3=37:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x1203 +phy_xaui_rx_polarity_flip_3=0x3 +phy_xaui_tx_polarity_flip_3=0xe +serdes_driver_current_lane0_3=0x4 +serdes_driver_current_lane1_3=0x4 +serdes_driver_current_lane2_3=0x4 +serdes_driver_current_lane3_3=0x4 +serdes_pre_driver_current_lane0_3=0x4 +serdes_pre_driver_current_lane1_3=0x4 +serdes_pre_driver_current_lane2_3=0x4 +serdes_pre_driver_current_lane3_3=0x4 +serdes_preemphasis_lane0_3=0xcad0 +serdes_preemphasis_lane1_3=0xcad0 +serdes_preemphasis_lane2_3=0xc2f0 +serdes_preemphasis_lane3_3=0xc2f0 + +# xe3 (40G) +portmap_4=33:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x132 +phy_xaui_rx_polarity_flip_4=0xe +phy_xaui_tx_polarity_flip_4=0x2 +serdes_driver_current_lane0_4=0x4 +serdes_driver_current_lane1_4=0x4 +serdes_driver_current_lane2_4=0x4 +serdes_driver_current_lane3_4=0x4 +serdes_pre_driver_current_lane0_4=0x4 +serdes_pre_driver_current_lane1_4=0x4 +serdes_pre_driver_current_lane2_4=0x4 +serdes_pre_driver_current_lane3_4=0x4 +serdes_preemphasis_lane0_4=0xc6e0 +serdes_preemphasis_lane1_4=0xc6e0 +serdes_preemphasis_lane2_4=0xc6e0 +serdes_preemphasis_lane3_4=0xc6e0 + +# xe4 (40G) +portmap_5=41:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x3021 +phy_xaui_rx_polarity_flip_5=0x3 +phy_xaui_tx_polarity_flip_5=0xb +serdes_driver_current_lane0_5=0x4 +serdes_driver_current_lane1_5=0x4 +serdes_driver_current_lane2_5=0x4 +serdes_driver_current_lane3_5=0x4 +serdes_pre_driver_current_lane0_5=0x4 +serdes_pre_driver_current_lane1_5=0x4 +serdes_pre_driver_current_lane2_5=0x4 +serdes_pre_driver_current_lane3_5=0x4 +serdes_preemphasis_lane0_5=0xc6e0 +serdes_preemphasis_lane1_5=0xc2f0 +serdes_preemphasis_lane2_5=0xc2f0 +serdes_preemphasis_lane3_5=0xcad0 + +# xe5 (40G) +portmap_6=45:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x213 +phy_xaui_rx_polarity_flip_6=0xe +phy_xaui_tx_polarity_flip_6=0x8 +serdes_driver_current_lane0_6=0x4 +serdes_driver_current_lane1_6=0x4 +serdes_driver_current_lane2_6=0x4 +serdes_driver_current_lane3_6=0x4 +serdes_pre_driver_current_lane0_6=0x4 +serdes_pre_driver_current_lane1_6=0x4 +serdes_pre_driver_current_lane2_6=0x4 +serdes_pre_driver_current_lane3_6=0x4 +serdes_preemphasis_lane0_6=0xc2f0 +serdes_preemphasis_lane1_6=0xc2f0 +serdes_preemphasis_lane2_6=0xc2f0 +serdes_preemphasis_lane3_6=0xc2f0 + +# xe6 (40G) +portmap_7=5:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x1203 +phy_xaui_rx_polarity_flip_7=0xc +phy_xaui_tx_polarity_flip_7=0x1 +serdes_driver_current_lane0_7=0x4 +serdes_driver_current_lane1_7=0x4 +serdes_driver_current_lane2_7=0x4 +serdes_driver_current_lane3_7=0x4 +serdes_pre_driver_current_lane0_7=0x4 +serdes_pre_driver_current_lane1_7=0x4 +serdes_pre_driver_current_lane2_7=0x4 +serdes_pre_driver_current_lane3_7=0x4 +serdes_preemphasis_lane0_7=0xc6e0 +serdes_preemphasis_lane1_7=0xc6e0 +serdes_preemphasis_lane2_7=0xc6e0 +serdes_preemphasis_lane3_7=0xc6e0 + +# xe7 (40G) +portmap_8=1:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x2031 +phy_xaui_rx_polarity_flip_8=0xe +phy_xaui_tx_polarity_flip_8=0xd +serdes_driver_current_lane0_8=0x5 +serdes_driver_current_lane1_8=0x5 +serdes_driver_current_lane2_8=0x5 +serdes_driver_current_lane3_8=0x5 +serdes_pre_driver_current_lane0_8=0x5 +serdes_pre_driver_current_lane1_8=0x5 +serdes_pre_driver_current_lane2_8=0x5 +serdes_pre_driver_current_lane3_8=0x5 +serdes_preemphasis_lane0_8=0xc6e0 +serdes_preemphasis_lane1_8=0xcad0 +serdes_preemphasis_lane2_8=0xc6e0 +serdes_preemphasis_lane3_8=0xcad0 + +# xe8 (4x10G) +portmap_9=9:10 +portmap_10=10:10 +portmap_11=11:10 +portmap_12=12:10 +xgxs_rx_lane_map_9=0x3120 +xgxs_tx_lane_map_9=0x3021 +phy_xaui_rx_polarity_flip_9=0x0 +phy_xaui_tx_polarity_flip_9=0x4 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x0 +phy_xaui_rx_polarity_flip_11=0x0 +phy_xaui_tx_polarity_flip_11=0x1 +phy_xaui_rx_polarity_flip_12=0x0 +phy_xaui_tx_polarity_flip_12=0x0 +serdes_driver_current_lane0_9=0x3 +serdes_driver_current_lane1_9=0x3 +serdes_driver_current_lane2_9=0x3 +serdes_driver_current_lane3_9=0x3 +serdes_pre_driver_current_lane0_9=0x3 +serdes_pre_driver_current_lane1_9=0x3 +serdes_pre_driver_current_lane2_9=0x3 +serdes_pre_driver_current_lane3_9=0x3 +serdes_preemphasis_lane0_9=0xc2f0 +serdes_preemphasis_lane1_9=0xc6e0 +serdes_preemphasis_lane2_9=0xbf00 +serdes_preemphasis_lane3_9=0xc2f0 + +# xe9 (4x10G) +portmap_13=13:10 +portmap_14=14:10 +portmap_15=15:10 +portmap_16=16:10 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x132 +phy_xaui_rx_polarity_flip_13=0xe +phy_xaui_tx_polarity_flip_13=0x0 +phy_xaui_rx_polarity_flip_14=0x1 +phy_xaui_tx_polarity_flip_14=0x0 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +phy_xaui_rx_polarity_flip_16=0x1 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_13=0x2 +serdes_driver_current_lane1_13=0x3 +serdes_driver_current_lane2_13=0x2 +serdes_driver_current_lane3_13=0x2 +serdes_pre_driver_current_lane0_13=0x2 +serdes_pre_driver_current_lane1_13=0x3 +serdes_pre_driver_current_lane2_13=0x2 +serdes_pre_driver_current_lane3_13=0x2 +serdes_preemphasis_lane0_13=0xb270 +serdes_preemphasis_lane1_13=0xbb10 +serdes_preemphasis_lane2_13=0xb720 +serdes_preemphasis_lane3_13=0xb720 + +# xe10 (4x10G) +portmap_17=21:10 +portmap_18=22:10 +portmap_19=23:10 +portmap_20=24:10 +xgxs_rx_lane_map_17=0x123 +xgxs_tx_lane_map_17=0x1203 +phy_xaui_rx_polarity_flip_17=0xc +phy_xaui_tx_polarity_flip_17=0xe +phy_xaui_rx_polarity_flip_18=0x0 +phy_xaui_tx_polarity_flip_18=0x1 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x1 +phy_xaui_rx_polarity_flip_20=0x1 +phy_xaui_tx_polarity_flip_20=0x1 +serdes_driver_current_lane0_17=0x2 +serdes_driver_current_lane1_17=0x2 +serdes_driver_current_lane2_17=0x2 +serdes_driver_current_lane3_17=0x2 +serdes_pre_driver_current_lane0_17=0x2 +serdes_pre_driver_current_lane1_17=0x2 +serdes_pre_driver_current_lane2_17=0x2 +serdes_pre_driver_current_lane3_17=0x2 +serdes_preemphasis_lane0_17=0xb330 +serdes_preemphasis_lane1_17=0xb330 +serdes_preemphasis_lane2_17=0xb330 +serdes_preemphasis_lane3_17=0xb330 + +# xe11 (4x10G) +portmap_21=17:10 +portmap_22=18:10 +portmap_23=19:10 +portmap_24=20:10 +xgxs_rx_lane_map_21=0x213 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0xe +phy_xaui_tx_polarity_flip_21=0x0 +phy_xaui_rx_polarity_flip_22=0x1 +phy_xaui_tx_polarity_flip_22=0x0 +phy_xaui_rx_polarity_flip_23=0x1 +phy_xaui_tx_polarity_flip_23=0x0 +phy_xaui_rx_polarity_flip_24=0x1 +phy_xaui_tx_polarity_flip_24=0x0 +serdes_driver_current_lane0_21=0x2 +serdes_driver_current_lane1_21=0x2 +serdes_driver_current_lane2_21=0x2 +serdes_driver_current_lane3_21=0x2 +serdes_pre_driver_current_lane0_21=0x2 +serdes_pre_driver_current_lane1_21=0x2 +serdes_pre_driver_current_lane2_21=0x2 +serdes_pre_driver_current_lane3_21=0x2 +serdes_preemphasis_lane0_21=0xb330 +serdes_preemphasis_lane1_21=0xbb10 +serdes_preemphasis_lane2_21=0xbb10 +serdes_preemphasis_lane3_21=0xbb10 + +# xe12 (4x10G) +portmap_25=49:10 +portmap_26=50:10 +portmap_27=51:10 +portmap_28=52:10 +xgxs_rx_lane_map_25=0x1302 +xgxs_tx_lane_map_25=0x2031 +phy_xaui_rx_polarity_flip_25=0xb +phy_xaui_tx_polarity_flip_25=0x3 +phy_xaui_rx_polarity_flip_26=0x1 +phy_xaui_tx_polarity_flip_26=0x1 +phy_xaui_rx_polarity_flip_27=0x0 +phy_xaui_tx_polarity_flip_27=0x0 +phy_xaui_rx_polarity_flip_28=0x1 +phy_xaui_tx_polarity_flip_28=0x0 +serdes_driver_current_lane0_25=0x2 +serdes_driver_current_lane1_25=0x2 +serdes_driver_current_lane2_25=0x2 +serdes_driver_current_lane3_25=0x2 +serdes_pre_driver_current_lane0_25=0x2 +serdes_pre_driver_current_lane1_25=0x2 +serdes_pre_driver_current_lane2_25=0x2 +serdes_pre_driver_current_lane3_25=0x2 +serdes_preemphasis_lane0_25=0xa760 +serdes_preemphasis_lane1_25=0xa760 +serdes_preemphasis_lane2_25=0xa760 +serdes_preemphasis_lane3_25=0xa760 + +# xe13 (4x10G) +portmap_29=53:10 +portmap_30=54:10 +portmap_31=55:10 +portmap_32=56:10 +xgxs_rx_lane_map_29=0x213 +xgxs_tx_lane_map_29=0x231 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x0 +phy_xaui_rx_polarity_flip_30=0x0 +phy_xaui_tx_polarity_flip_30=0x0 +phy_xaui_rx_polarity_flip_31=0x0 +phy_xaui_tx_polarity_flip_31=0x0 +phy_xaui_rx_polarity_flip_32=0x0 +phy_xaui_tx_polarity_flip_32=0x0 +serdes_driver_current_lane0_29=0x2 +serdes_driver_current_lane1_29=0x2 +serdes_driver_current_lane2_29=0x2 +serdes_driver_current_lane3_29=0x2 +serdes_pre_driver_current_lane0_29=0x2 +serdes_pre_driver_current_lane1_29=0x2 +serdes_pre_driver_current_lane2_29=0x2 +serdes_pre_driver_current_lane3_29=0x2 +serdes_preemphasis_lane0_29=0xaf40 +serdes_preemphasis_lane1_29=0xaf40 +serdes_preemphasis_lane2_29=0xaf40 +serdes_preemphasis_lane3_29=0xaf40 + +# xe14 (40G) +portmap_33=61:40 +xgxs_rx_lane_map_33=0x132 +xgxs_tx_lane_map_33=0x213 +phy_xaui_rx_polarity_flip_33=0x0 +phy_xaui_tx_polarity_flip_33=0x0 +serdes_driver_current_lane0_33=0x2 +serdes_driver_current_lane1_33=0x2 +serdes_driver_current_lane2_33=0x2 +serdes_driver_current_lane3_33=0x2 +serdes_pre_driver_current_lane0_33=0x2 +serdes_pre_driver_current_lane1_33=0x2 +serdes_pre_driver_current_lane2_33=0x2 +serdes_pre_driver_current_lane3_33=0x2 +serdes_preemphasis_lane0_33=0xa760 +serdes_preemphasis_lane1_33=0xa760 +serdes_preemphasis_lane2_33=0xa760 +serdes_preemphasis_lane3_33=0xa760 + +# xe15 (40G) +portmap_34=57:40 +xgxs_rx_lane_map_34=0x213 +xgxs_tx_lane_map_34=0x2031 +phy_xaui_rx_polarity_flip_34=0x1 +phy_xaui_tx_polarity_flip_34=0x0 +serdes_driver_current_lane0_34=0x1 +serdes_driver_current_lane1_34=0x1 +serdes_driver_current_lane2_34=0x1 +serdes_driver_current_lane3_34=0x1 +serdes_pre_driver_current_lane0_34=0x1 +serdes_pre_driver_current_lane1_34=0x1 +serdes_pre_driver_current_lane2_34=0x1 +serdes_pre_driver_current_lane3_34=0x1 +serdes_preemphasis_lane0_34=0xa760 +serdes_preemphasis_lane1_34=0xa760 +serdes_preemphasis_lane2_34=0xa760 +serdes_preemphasis_lane3_34=0xa760 + +# xe16 (40G) +portmap_35=65:40 +xgxs_rx_lane_map_35=0x132 +xgxs_tx_lane_map_35=0x2031 +phy_xaui_rx_polarity_flip_35=0x3 +phy_xaui_tx_polarity_flip_35=0x9 +serdes_driver_current_lane0_35=0x1 +serdes_driver_current_lane1_35=0x1 +serdes_driver_current_lane2_35=0x1 +serdes_driver_current_lane3_35=0x1 +serdes_pre_driver_current_lane0_35=0x1 +serdes_pre_driver_current_lane1_35=0x1 +serdes_pre_driver_current_lane2_35=0x1 +serdes_pre_driver_current_lane3_35=0x1 +serdes_preemphasis_lane0_35=0xa370 +serdes_preemphasis_lane1_35=0xa370 +serdes_preemphasis_lane2_35=0xa370 +serdes_preemphasis_lane3_35=0xa370 + +# xe17 (40G) +portmap_36=69:40 +xgxs_rx_lane_map_36=0x213 +xgxs_tx_lane_map_36=0x2130 +phy_xaui_rx_polarity_flip_36=0x1 +phy_xaui_tx_polarity_flip_36=0xf +serdes_driver_current_lane0_36=0x1 +serdes_driver_current_lane1_36=0x1 +serdes_driver_current_lane2_36=0x1 +serdes_driver_current_lane3_36=0x1 +serdes_pre_driver_current_lane0_36=0x1 +serdes_pre_driver_current_lane1_36=0x1 +serdes_pre_driver_current_lane2_36=0x1 +serdes_pre_driver_current_lane3_36=0x1 +serdes_preemphasis_lane0_36=0xa760 +serdes_preemphasis_lane1_36=0xa760 +serdes_preemphasis_lane2_36=0xa760 +serdes_preemphasis_lane3_36=0xa760 + +# xe18 (4x10G) +portmap_37=77:10 +portmap_38=78:10 +portmap_39=79:10 +portmap_40=80:10 +xgxs_rx_lane_map_37=0x123 +xgxs_tx_lane_map_37=0x1203 +phy_xaui_rx_polarity_flip_37=0x3 +phy_xaui_tx_polarity_flip_37=0xe +phy_xaui_rx_polarity_flip_38=0x1 +phy_xaui_tx_polarity_flip_38=0x1 +phy_xaui_rx_polarity_flip_39=0x0 +phy_xaui_tx_polarity_flip_39=0x1 +phy_xaui_rx_polarity_flip_40=0x0 +phy_xaui_tx_polarity_flip_40=0x1 +serdes_driver_current_lane0_37=0x2 +serdes_driver_current_lane1_37=0x2 +serdes_driver_current_lane2_37=0x2 +serdes_driver_current_lane3_37=0x2 +serdes_pre_driver_current_lane0_37=0x2 +serdes_pre_driver_current_lane1_37=0x2 +serdes_pre_driver_current_lane2_37=0x2 +serdes_pre_driver_current_lane3_37=0x2 +serdes_preemphasis_lane0_37=0xaf40 +serdes_preemphasis_lane1_37=0xaf40 +serdes_preemphasis_lane2_37=0xaf40 +serdes_preemphasis_lane3_37=0xaf40 + +# xe19 (4x10G) +portmap_41=73:10 +portmap_42=74:10 +portmap_43=75:10 +portmap_44=76:10 +xgxs_rx_lane_map_41=0x213 +xgxs_tx_lane_map_41=0x2031 +phy_xaui_rx_polarity_flip_41=0x1 +phy_xaui_tx_polarity_flip_41=0x0 +phy_xaui_rx_polarity_flip_42=0x0 +phy_xaui_tx_polarity_flip_42=0x0 +phy_xaui_rx_polarity_flip_43=0x0 +phy_xaui_tx_polarity_flip_43=0x0 +phy_xaui_rx_polarity_flip_44=0x0 +phy_xaui_tx_polarity_flip_44=0x0 +serdes_driver_current_lane0_41=0x2 +serdes_driver_current_lane1_41=0x2 +serdes_driver_current_lane2_41=0x2 +serdes_driver_current_lane3_41=0x2 +serdes_pre_driver_current_lane0_41=0x2 +serdes_pre_driver_current_lane1_41=0x2 +serdes_pre_driver_current_lane2_41=0x2 +serdes_pre_driver_current_lane3_41=0x2 +serdes_preemphasis_lane0_41=0xa760 +serdes_preemphasis_lane1_41=0xa760 +serdes_preemphasis_lane2_41=0xa760 +serdes_preemphasis_lane3_41=0xa760 + +# xe20 (4x10G) +portmap_45=105:10 +portmap_46=106:10 +portmap_47=107:10 +portmap_48=108:10 +xgxs_rx_lane_map_45=0x1320 +xgxs_tx_lane_map_45=0x3021 +phy_xaui_rx_polarity_flip_45=0xd +phy_xaui_tx_polarity_flip_45=0xb +phy_xaui_rx_polarity_flip_46=0x0 +phy_xaui_tx_polarity_flip_46=0x1 +phy_xaui_rx_polarity_flip_47=0x1 +phy_xaui_tx_polarity_flip_47=0x0 +phy_xaui_rx_polarity_flip_48=0x1 +phy_xaui_tx_polarity_flip_48=0x1 +serdes_driver_current_lane0_45=0x1 +serdes_driver_current_lane1_45=0x1 +serdes_driver_current_lane2_45=0x1 +serdes_driver_current_lane3_45=0x1 +serdes_pre_driver_current_lane0_45=0x1 +serdes_pre_driver_current_lane1_45=0x1 +serdes_pre_driver_current_lane2_45=0x1 +serdes_pre_driver_current_lane3_45=0x1 +serdes_preemphasis_lane0_45=0xb330 +serdes_preemphasis_lane1_45=0xb330 +serdes_preemphasis_lane2_45=0xb330 +serdes_preemphasis_lane3_45=0xb330 + +# xe21 (4x10G) +portmap_49=109:10 +portmap_50=110:10 +portmap_51=111:10 +portmap_52=112:10 +xgxs_rx_lane_map_49=0x132 +xgxs_tx_lane_map_49=0x132 +phy_xaui_rx_polarity_flip_49=0x8 +phy_xaui_tx_polarity_flip_49=0x0 +phy_xaui_rx_polarity_flip_50=0x0 +phy_xaui_tx_polarity_flip_50=0x0 +phy_xaui_rx_polarity_flip_51=0x0 +phy_xaui_tx_polarity_flip_51=0x0 +phy_xaui_rx_polarity_flip_52=0x1 +phy_xaui_tx_polarity_flip_52=0x0 +serdes_driver_current_lane0_49=0x1 +serdes_driver_current_lane1_49=0x1 +serdes_driver_current_lane2_49=0x1 +serdes_driver_current_lane3_49=0x2 +serdes_pre_driver_current_lane0_49=0x1 +serdes_pre_driver_current_lane1_49=0x1 +serdes_pre_driver_current_lane2_49=0x1 +serdes_pre_driver_current_lane3_49=0x2 +serdes_preemphasis_lane0_49=0xb330 +serdes_preemphasis_lane1_49=0xb330 +serdes_preemphasis_lane2_49=0xb330 +serdes_preemphasis_lane3_49=0xbff0 + +# xe22 (4x10G) +portmap_53=117:10 +portmap_54=118:10 +portmap_55=119:10 +portmap_56=120:10 +xgxs_rx_lane_map_53=0x231 +xgxs_tx_lane_map_53=0x1203 +phy_xaui_rx_polarity_flip_53=0x3 +phy_xaui_tx_polarity_flip_53=0xe +phy_xaui_rx_polarity_flip_54=0x1 +phy_xaui_tx_polarity_flip_54=0x1 +phy_xaui_rx_polarity_flip_55=0x0 +phy_xaui_tx_polarity_flip_55=0x1 +phy_xaui_rx_polarity_flip_56=0x0 +phy_xaui_tx_polarity_flip_56=0x1 +serdes_driver_current_lane0_53=0x3 +serdes_driver_current_lane1_53=0x5 +serdes_driver_current_lane2_53=0x3 +serdes_driver_current_lane3_53=0x3 +serdes_pre_driver_current_lane0_53=0x3 +serdes_pre_driver_current_lane1_53=0x5 +serdes_pre_driver_current_lane2_53=0x3 +serdes_pre_driver_current_lane3_53=0x3 +serdes_preemphasis_lane0_53=0xc6e0 +serdes_preemphasis_lane1_53=0xc6e0 +serdes_preemphasis_lane2_53=0xc6e0 +serdes_preemphasis_lane3_53=0xc6e0 + +# xe23 (4x10G) +portmap_57=113:10 +portmap_58=114:10 +portmap_59=115:10 +portmap_60=116:10 +xgxs_rx_lane_map_57=0x132 +xgxs_tx_lane_map_57=0x132 +phy_xaui_rx_polarity_flip_57=0x8 +phy_xaui_tx_polarity_flip_57=0x0 +phy_xaui_rx_polarity_flip_58=0x0 +phy_xaui_tx_polarity_flip_58=0x0 +phy_xaui_rx_polarity_flip_59=0x0 +phy_xaui_tx_polarity_flip_59=0x0 +phy_xaui_rx_polarity_flip_60=0x1 +phy_xaui_tx_polarity_flip_60=0x0 +serdes_driver_current_lane0_57=0x1 +serdes_driver_current_lane1_57=0x1 +serdes_driver_current_lane2_57=0x1 +serdes_driver_current_lane3_57=0x1 +serdes_pre_driver_current_lane0_57=0x1 +serdes_pre_driver_current_lane1_57=0x1 +serdes_pre_driver_current_lane2_57=0x1 +serdes_pre_driver_current_lane3_57=0x1 +serdes_preemphasis_lane0_57=0xbb10 +serdes_preemphasis_lane1_57=0xbb10 +serdes_preemphasis_lane2_57=0xbb10 +serdes_preemphasis_lane3_57=0xc2f0 + +# xe24 (40G) +portmap_61=121:40 +xgxs_rx_lane_map_61=0x1320 +xgxs_tx_lane_map_61=0x3021 +phy_xaui_rx_polarity_flip_61=0xd +phy_xaui_tx_polarity_flip_61=0xb +serdes_driver_current_lane0_61=0x4 +serdes_driver_current_lane1_61=0x4 +serdes_driver_current_lane2_61=0x4 +serdes_driver_current_lane3_61=0x4 +serdes_pre_driver_current_lane0_61=0x4 +serdes_pre_driver_current_lane1_61=0x4 +serdes_pre_driver_current_lane2_61=0x4 +serdes_pre_driver_current_lane3_61=0x4 +serdes_preemphasis_lane0_61=0xc6e0 +serdes_preemphasis_lane1_61=0xc6e0 +serdes_preemphasis_lane2_61=0xc6e0 +serdes_preemphasis_lane3_61=0xc6e0 + +# xe25 (40G) +portmap_62=125:40 +xgxs_rx_lane_map_62=0x132 +xgxs_tx_lane_map_62=0x132 +phy_xaui_rx_polarity_flip_62=0x8 +phy_xaui_tx_polarity_flip_62=0x0 +serdes_driver_current_lane0_62=0x4 +serdes_driver_current_lane1_62=0x4 +serdes_driver_current_lane2_62=0x4 +serdes_driver_current_lane3_62=0x4 +serdes_pre_driver_current_lane0_62=0x4 +serdes_pre_driver_current_lane1_62=0x4 +serdes_pre_driver_current_lane2_62=0x4 +serdes_pre_driver_current_lane3_62=0x4 +serdes_preemphasis_lane0_62=0xc6e0 +serdes_preemphasis_lane1_62=0xc6e0 +serdes_preemphasis_lane2_62=0xc6e0 +serdes_preemphasis_lane3_62=0xcec0 + +# xe26 (40G) +portmap_63=85:40 +xgxs_rx_lane_map_63=0x213 +xgxs_tx_lane_map_63=0x1203 +phy_xaui_rx_polarity_flip_63=0xc +phy_xaui_tx_polarity_flip_63=0xe +serdes_driver_current_lane0_63=0x4 +serdes_driver_current_lane1_63=0x5 +serdes_driver_current_lane2_63=0x4 +serdes_driver_current_lane3_63=0x5 +serdes_pre_driver_current_lane0_63=0x4 +serdes_pre_driver_current_lane1_63=0x5 +serdes_pre_driver_current_lane2_63=0x4 +serdes_pre_driver_current_lane3_63=0x5 +serdes_preemphasis_lane0_63=0xc2f0 +serdes_preemphasis_lane1_63=0xc6e0 +serdes_preemphasis_lane2_63=0xc6e0 +serdes_preemphasis_lane3_63=0xc6e0 + +# xe27 (40G) +portmap_64=81:40 +xgxs_rx_lane_map_64=0x1320 +xgxs_tx_lane_map_64=0x2031 +phy_xaui_rx_polarity_flip_64=0x1 +phy_xaui_tx_polarity_flip_64=0x2 +serdes_driver_current_lane0_64=0x2 +serdes_driver_current_lane1_64=0x2 +serdes_driver_current_lane2_64=0x2 +serdes_driver_current_lane3_64=0x2 +serdes_pre_driver_current_lane0_64=0x2 +serdes_pre_driver_current_lane1_64=0x2 +serdes_pre_driver_current_lane2_64=0x2 +serdes_pre_driver_current_lane3_64=0x2 +serdes_preemphasis_lane0_64=0xbb10 +serdes_preemphasis_lane1_64=0xbb10 +serdes_preemphasis_lane2_64=0xbf00 +serdes_preemphasis_lane3_64=0xbb10 + +# xe28 (40G) +portmap_65=89:40 +xgxs_rx_lane_map_65=0x1320 +xgxs_tx_lane_map_65=0x3021 +phy_xaui_rx_polarity_flip_65=0x2 +phy_xaui_tx_polarity_flip_65=0xb +serdes_driver_current_lane0_65=0x4 +serdes_driver_current_lane1_65=0x4 +serdes_driver_current_lane2_65=0x4 +serdes_driver_current_lane3_65=0x4 +serdes_pre_driver_current_lane0_65=0x4 +serdes_pre_driver_current_lane1_65=0x4 +serdes_pre_driver_current_lane2_65=0x4 +serdes_pre_driver_current_lane3_65=0x4 +serdes_preemphasis_lane0_65=0xcad0 +serdes_preemphasis_lane1_65=0xc6e0 +serdes_preemphasis_lane2_65=0xc6e0 +serdes_preemphasis_lane3_65=0xc6e0 + +# xe29 (40G) +portmap_66=93:40 +xgxs_rx_lane_map_66=0x1320 +xgxs_tx_lane_map_66=0x2031 +phy_xaui_rx_polarity_flip_66=0x1 +phy_xaui_tx_polarity_flip_66=0x2 +serdes_driver_current_lane0_66=0x4 +serdes_driver_current_lane1_66=0x4 +serdes_driver_current_lane2_66=0x4 +serdes_driver_current_lane3_66=0x4 +serdes_pre_driver_current_lane0_66=0x4 +serdes_pre_driver_current_lane1_66=0x4 +serdes_pre_driver_current_lane2_66=0x4 +serdes_pre_driver_current_lane3_66=0x4 +serdes_preemphasis_lane0_66=0xc2f0 +serdes_preemphasis_lane1_66=0xc2f0 +serdes_preemphasis_lane2_66=0xc2f0 +serdes_preemphasis_lane3_66=0xc2f0 + +# xe30 (40G) +portmap_67=97:40 +xgxs_rx_lane_map_67=0x213 +xgxs_tx_lane_map_67=0x2031 +phy_xaui_rx_polarity_flip_67=0xc +phy_xaui_tx_polarity_flip_67=0x3 +serdes_driver_current_lane0_67=0x5 +serdes_driver_current_lane1_67=0x5 +serdes_driver_current_lane2_67=0x5 +serdes_driver_current_lane3_67=0x5 +serdes_pre_driver_current_lane0_67=0x5 +serdes_pre_driver_current_lane1_67=0x5 +serdes_pre_driver_current_lane2_67=0x5 +serdes_pre_driver_current_lane3_67=0x5 +serdes_preemphasis_lane0_67=0xcad0 +serdes_preemphasis_lane1_67=0xcad0 +serdes_preemphasis_lane2_67=0xcad0 +serdes_preemphasis_lane3_67=0xcad0 + +# xe31 (40G) +portmap_68=101:40 +xgxs_rx_lane_map_68=0x1320 +xgxs_tx_lane_map_68=0x1203 +phy_xaui_rx_polarity_flip_68=0x1 +phy_xaui_tx_polarity_flip_68=0x6 +serdes_driver_current_lane0_68=0x6 +serdes_driver_current_lane1_68=0x6 +serdes_driver_current_lane2_68=0x6 +serdes_driver_current_lane3_68=0x7 +serdes_pre_driver_current_lane0_68=0x6 +serdes_pre_driver_current_lane1_68=0x6 +serdes_pre_driver_current_lane2_68=0x6 +serdes_pre_driver_current_lane3_68=0x7 +serdes_preemphasis_lane0_68=0xcec0 +serdes_preemphasis_lane1_68=0xcec0 +serdes_preemphasis_lane2_68=0xcad0 +serdes_preemphasis_lane3_68=0xc6e0 + From 767152f09bb7e1e7bbd4824118ad5b31e6033809 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Tue, 26 May 2020 10:29:13 +0000 Subject: [PATCH 0725/1427] [docker-sonic-mgmt]: fix pip version to 20.1.1 Signed-off-by: Guohan Lu --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index d606749948d0..78d5996f8571 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -39,7 +39,7 @@ RUN apt-get purge -y python-cffi python-cffi-backend # Remove pycparser 2.14, will install >=2.17 by pip later RUN apt-get purge -y python-ply python-pycparser -RUN easy_install pip +RUN easy_install pip==20.1.1 RUN pip install ipaddr \ lxml \ From f277d13cd678b4f3cd212f447afdc407b829aaaa Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Wed, 27 May 2020 01:45:25 +0800 Subject: [PATCH 0726/1427] [Mellanox] Adjust log level to avoid too many thermal logs (#4631) * Trigger thermal action log only if thermal condition changes * test file existence before read file content * fix error for set psu fan speed * Remove logs because it print too frequently --- .../mlnx-platform-api/sonic_platform/fan.py | 2 ++ .../mlnx-platform-api/sonic_platform/psu.py | 2 ++ .../sonic_platform/thermal.py | 6 ++++- .../sonic_platform/thermal_actions.py | 22 +++++++++---------- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py index d123b6c6c3a3..491be834aa2e 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py @@ -221,6 +221,8 @@ def set_speed(self, speed): status = True if self.is_psu_fan: + if not self.get_presence(): + return False from .thermal import logger try: with open(self.psu_i2c_bus_path, 'r') as f: diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index a323132faf97..5541402916a0 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -122,6 +122,8 @@ def _read_generic_file(self, filename, len): """ result = 0 try: + if not os.path.exists(filename): + return result with open(filename, 'r') as fileobj: result = int(fileobj.read().strip()) except Exception as e: diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 3c25ebb642e8..54e2d1a478c0 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -495,12 +495,15 @@ def set_thermal_algorithm_status(cls, status, force=True): We usually disable the algorithm when we want to set a fix speed. E.g, when a fan unit is removed from system, we will set fan speed to 100% and disable the algorithm to avoid it adjust the speed. + + Returns: + True if thermal algorithm status changed. """ if not cls.thermal_profile: raise Exception("Fail to get thermal profile for this switch") if not force and cls.thermal_algorithm_status == status: - return + return False cls.thermal_algorithm_status = status content = "enabled" if status else "disabled" @@ -521,6 +524,7 @@ def set_thermal_algorithm_status(cls, status, force=True): for index in range(count): cls._write_generic_file(join(THERMAL_ZONE_GEARBOX_PATH.format(start + index), THERMAL_ZONE_MODE), content) cls._write_generic_file(join(THERMAL_ZONE_GEARBOX_PATH.format(start + index), THERMAL_ZONE_POLICY), policy) + return True @classmethod def check_thermal_zone_temperature(cls): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py index 3a4d5f2a8a68..9a4cde05b842 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py @@ -66,9 +66,6 @@ def set_psu_fan_speed(cls, thermal_info_dict, speed): for psu_fan in psu.get_all_fans(): psu_fan.set_speed(speed) - logger.log_info('Updated PSU FAN speed to {}%'.format(speed)) - - @thermal_json_object('fan.all.check_and_set_speed') class CheckAndSetAllFanSpeedAction(SetAllFanSpeedAction): @@ -131,14 +128,17 @@ def execute(self, thermal_info_dict): from .thermal import Thermal from .thermal_conditions import UpdateCoolingLevelToMinCondition from .fan import Fan - Thermal.set_thermal_algorithm_status(self.status, False) - if self.status: - # Check thermal zone temperature, if all thermal zone temperature - # back to normal, set it to minimum allowed speed to - # save power - UpdateCoolingLevelToMinAction.update_cooling_level_to_minimum(thermal_info_dict) + status_changed = Thermal.set_thermal_algorithm_status(self.status, False) - logger.log_info('Changed thermal algorithm status to {}'.format(self.status)) + # Only update cooling level if thermal algorithm status changed + if status_changed: + if self.status: + # Check thermal zone temperature, if all thermal zone temperature + # back to normal, set it to minimum allowed speed to + # save power + UpdateCoolingLevelToMinAction.update_cooling_level_to_minimum(thermal_info_dict) + + logger.log_info('Changed thermal algorithm status to {}'.format(self.status)) class ChangeMinCoolingLevelAction(ThermalPolicyActionBase): @@ -174,8 +174,6 @@ def execute(self, thermal_info_dict): Fan.set_cooling_level(Fan.min_cooling_level, current_cooling_level) UpdateCoolingLevelToMinAction.update_cooling_level_to_minimum(thermal_info_dict) - logger.log_info('Changed minimum cooling level to {}'.format(Fan.min_cooling_level)) - class UpdatePsuFanSpeedAction(ThermalPolicyActionBase): def execute(self, thermal_info_dict): From e25c2d984f9b1a26e2dd3d069897de2666e0c86c Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Wed, 27 May 2020 01:46:29 +0800 Subject: [PATCH 0727/1427] [Mellanox] Never disable kernel thermal algorithm at real-time (#4638) --- .../x86_64-mlnx_msn2700-r0/thermal_policy.json | 15 +-------------- .../sonic_platform/thermal_actions.py | 6 ++++++ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json index f16f68dd002e..1e23d6c8b2bd 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json @@ -23,10 +23,6 @@ } ], "actions": [ - { - "type": "thermal_control.control", - "status": "false" - }, { "type": "fan.all.set_speed", "speed": "100" @@ -41,10 +37,6 @@ } ], "actions": [ - { - "type": "thermal_control.control", - "status": "false" - }, { "type": "fan.all.set_speed", "speed": "100" @@ -59,10 +51,6 @@ } ], "actions": [ - { - "type": "thermal_control.control", - "status": "false" - }, { "type": "fan.all.set_speed", "speed": "100" @@ -84,8 +72,7 @@ ], "actions": [ { - "type": "thermal_control.control", - "status": "true" + "type": "thermal.recover" } ] } diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py index 9a4cde05b842..e7436bd0a5b7 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py @@ -141,6 +141,12 @@ def execute(self, thermal_info_dict): logger.log_info('Changed thermal algorithm status to {}'.format(self.status)) +@thermal_json_object('thermal.recover') +class ThermalRecoverAction(ThermalPolicyActionBase): + def execute(self, thermal_info_dict): + UpdateCoolingLevelToMinAction.update_cooling_level_to_minimum(thermal_info_dict) + + class ChangeMinCoolingLevelAction(ThermalPolicyActionBase): UNKNOWN_SKU_COOLING_LEVEL = 6 def execute(self, thermal_info_dict): From 40481f01af06f42b8aa777e61d8ea8026c6275cf Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Tue, 26 May 2020 10:59:56 -0700 Subject: [PATCH 0728/1427] Read cloudtype info from minigraph (#4642) --- src/sonic-config-engine/minigraph.py | 9 +++++++-- .../tests/simple-sample-graph-metadata.xml | 5 +++++ src/sonic-config-engine/tests/test_cfggen.py | 5 +++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 3ead38080920..b560df3332cd 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -528,6 +528,7 @@ def parse_meta(meta, hname): erspan_dst = [] deployment_id = None region = None + cloudtype = None device_metas = meta.find(str(QName(ns, "Devices"))) for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower(): @@ -552,7 +553,9 @@ def parse_meta(meta, hname): deployment_id = value elif name == "Region": region = value - return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region + elif name == "CloudType": + cloudtype = value + return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype def parse_linkmeta(meta, hname): @@ -812,6 +815,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): bgp_peers_with_range = None deployment_id = None region = None + cloudtype = None hostname = None linkmetas = {} @@ -847,7 +851,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): - (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname) + (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "LinkMetadataDeclaration")): linkmetas = parse_linkmeta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): @@ -879,6 +883,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): 'bgp_asn': bgp_asn, 'deployment_id': deployment_id, 'region': region, + 'cloudtype': cloudtype, 'docker_routing_config_mode': docker_routing_config_mode, 'hostname': hostname, 'hwsku': hwsku, diff --git a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml index db103e13480d..4bde42cdda3a 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml @@ -220,6 +220,11 @@ usfoo + + CloudType + + Public + ErspanDestinationIpv4 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 816575f84171..66ca26f3250e 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -58,6 +58,11 @@ def test_minigraph_region(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'usfoo') + def test_minigraph_cloudtype(self): + argument = '-v "DEVICE_METADATA[\'localhost\'][\'cloudtype\']" -m "' + self.sample_graph_metadata + '"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'Public') + def test_print_data(self): argument = '-m "' + self.sample_graph + '" --print-data' output = self.run_script(argument) From bf54f48df3655adfb55b1a4973b31a2b046f16b5 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Wed, 27 May 2020 02:04:21 +0800 Subject: [PATCH 0729/1427] [thermalctld] Update submodule pointer for sonic-platform-daemons (#4637) --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 97e40cefae31..6e975f5f6111 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 97e40cefae31928fe8faf0a0995c8263e7f62465 +Subproject commit 6e975f5f61111d399f5f5b44177bba8b4be8162c From f532fb95a9f58ac69b18f22420cd4af1f7409c7b Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Wed, 27 May 2020 03:49:51 +0800 Subject: [PATCH 0730/1427] [accton/as4630-54pe] Fix ypeb-1200am psu_fan dir issue (#4626) 3y Power YPEB-1200am PSU doens't support read fan_dir from pmbus register Check with vendor this PUS type only support F2B fan direction. So add to show "F2B" when red psu_fan_dir sysfs. --- .../sonic-platform-modules-accton/common/modules/ym2651y.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c index 5e9d858fa689..5834b1d4ef8b 100755 --- a/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c @@ -355,6 +355,11 @@ static ssize_t show_ascii(struct device *dev, struct device_attribute *da, switch (attr->index) { case PSU_FAN_DIRECTION: /* psu_fan_dir */ + if (data->chip==YPEB1200AM) + { + memcpy(data->fan_dir, "F2B", 3); + data->fan_dir[3]='\0'; + } ptr = data->fan_dir; break; case PSU_MFR_ID: /* psu_mfr_id */ From 17904969b6e2f31a79b3ce044a690eff0780ef8d Mon Sep 17 00:00:00 2001 From: Sabareesh-Kumar-Anandan <59681634+Sabareesh-Kumar-Anandan@users.noreply.github.com> Date: Wed, 27 May 2020 14:32:19 +0530 Subject: [PATCH 0731/1427] [sonic-config-engine][marvell] read mac address fix (#4649) Signed-off-by: Sabareesh Kumar Anandan --- src/sonic-config-engine/sonic_device_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index cb9263ce0345..5984a7047fe7 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -161,7 +161,7 @@ def get_system_mac(namespace=None): # Try valid mac in eeprom, else fetch it from eth0 platform = get_platform_info(get_machine_info()) hwsku = get_machine_info()['onie_machine'] - profile_cmd = 'cat' + SONIC_DEVICE_PATH + '/' + platform +'/'+ hwsku +'/profile.ini | cut -f2 -d=' + profile_cmd = 'cat' + SONIC_DEVICE_PATH + '/' + platform +'/'+ hwsku +'/profile.ini | grep switchMacAddress | cut -f2 -d=' hw_mac_entry_cmds = [ profile_cmd, "sudo decode-syseeprom -m", "ip link show eth0 | grep ether | awk '{print $2}'" ] else: mac_address_cmd = "cat /sys/class/net/eth0/address" From 8aaadc2ffb4b7fa739c9468b5bc18ce177d6256d Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 27 May 2020 02:21:58 -0700 Subject: [PATCH 0732/1427] [sonic-slave]: Install pympler to find the memory leaks in python (#4652) --- sonic-slave-buster/Dockerfile.j2 | 3 +++ sonic-slave-jessie/Dockerfile.j2 | 3 +++ sonic-slave-stretch/Dockerfile.j2 | 3 +++ 3 files changed, 9 insertions(+) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 315befbd2b6e..a642a09d2297 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -373,6 +373,9 @@ RUN pip install mockredispy==2.9.3 RUN pip install pytest-runner==4.4 RUN pip install setuptools==40.8.0 +# For sonic-swss-common testing +RUN pip install Pympler==0.8 + # For sonic_yang_mgmt build RUN pip install ijson==2.6.1 RUN pip3 install ijson==2.6.1 diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index b2626f33ce98..49c330495ae0 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -324,6 +324,9 @@ RUN pip install mockredispy==2.9.3 RUN pip install pytest-runner==4.4 RUN pip install setuptools==40.8.0 +# For sonic-swss-common testing +RUN pip install Pympler==0.8 + # Install dependencies for isc-dhcp-relay build RUN apt-get -y build-dep isc-dhcp diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 2f700a024ac1..40bc7da1bf57 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -367,6 +367,9 @@ RUN pip install mockredispy==2.9.3 RUN pip install pytest-runner==4.4 RUN pip install setuptools==40.8.0 +# For sonic-swss-common testing +RUN pip install Pympler==0.8 + # For sonic_yang_mgmt build RUN pip install ijson==2.6.1 RUN pip3 install ijson==2.6.1 From a406fdb57cd89b0787393a9e8abb0681468e8294 Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Wed, 27 May 2020 06:15:43 -0400 Subject: [PATCH 0733/1427] [sonic-py-swsssdk] Advance submodule (#4636) **- Why I did it** Advance sonic-py-swsssdk submodule to fix #4632 **- How I did it** In py3, the response from redis connector is encoded as byte array. They need to be decoded before accessing them as strings. Use following commands to test sonic-db-cli CONFIG_DB "keys *" sonic-db-cli CONFIG_DB "hget PORT|Ethernet0 admin_status" **- How to verify it** sonic-db-cli CONFIG_DB "keys *" sonic-db-cli CONFIG_DB "hget PORT|Ethernet0 admin_status" Signed-off-by: Rajendra Dendukuri --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 03748ce070d9..9fab7297cd4a 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 03748ce070d9ca4b827e9fc679a18983a7656f1c +Subproject commit 9fab7297cd4a577ffceb50df99139942879108f1 From fa809c86dc2fa1ced2d319b71308f66c2374652b Mon Sep 17 00:00:00 2001 From: zoe-kuan <64390642+zoe-kuan@users.noreply.github.com> Date: Thu, 28 May 2020 00:33:02 +0800 Subject: [PATCH 0734/1427] [platform/delta]: Add a new supported platform, Delta-agc032 (#4602) * [platform]: Add a new supported platform, Delta-agc032 Switch Vendor: Delta Switch SKU: Delta-agc032 CPU: BROADWELL-DE ASIC Vendor: Broadcom Switch ASIC: Tomahawk3, BCM56980 Port Configuration: 32x400G + 2x10G - What I did Add a new Delta platform Delta-agc032. - How I did it Add files by following SONiC Porting Guide. - How to verify it 1. decode-syseeprom 2. sensors 3. psuutil 4. sfputil 5. show interface status 6. bcmcmd Signed-off-by: zoe-kuan --- .../Delta-agc032/port_config.ini | 35 + .../Delta-agc032/sai.profile | 1 + .../th3-agc032-32x400G.config.bcm | 280 ++ .../x86_64-delta_agc032-r0/custom_led.bin | Bin 0 -> 1000 bytes .../delta/x86_64-delta_agc032-r0/default_sku | 1 + .../delta/x86_64-delta_agc032-r0/fancontrol | 10 + .../x86_64-delta_agc032-r0/fancontrol.service | 295 ++ .../x86_64-delta_agc032-r0/installer.conf | 3 + .../x86_64-delta_agc032-r0/led_proc_init.soc | 5 + .../x86_64-delta_agc032-r0/platform_env.conf | 1 + .../x86_64-delta_agc032-r0/plugins/eeprom.py | 12 + .../x86_64-delta_agc032-r0/plugins/psuutil.py | 62 + .../x86_64-delta_agc032-r0/plugins/sfputil.py | 241 ++ .../pmon_daemon_control.json | 6 + .../delta/x86_64-delta_agc032-r0/sensors.conf | 47 + platform/broadcom/one-image.mk | 3 +- platform/broadcom/platform-modules-delta.mk | 7 + .../agc032/cfg/agc032-modules.conf | 13 + .../agc032/modules/Makefile | 1 + .../agc032/modules/delta_agc032_cpupld.c | 746 +++++ .../agc032/modules/delta_agc032_platform.c | 299 ++ .../agc032/modules/delta_agc032_qsfp.c | 819 +++++ .../agc032/modules/delta_agc032_swpld.c | 2841 +++++++++++++++++ .../agc032/modules/dni_agc032_psu.c | 549 ++++ .../agc032/modules/dni_emc2302.c | 363 +++ .../agc032/modules/dni_emc2305.c | 1 + .../agc032/scripts/agc032_platform_init.sh | 22 + .../debian/control | 5 + .../debian/platform-modules-agc032.init | 62 + .../debian/platform-modules-agc032.install | 3 + .../sonic-platform-modules-delta/debian/rules | 2 +- .../systemd/platform-modules-agc032.service | 13 + src/sonic-device-data/tests/permitted_list | 1 + 33 files changed, 6747 insertions(+), 2 deletions(-) create mode 100644 device/delta/x86_64-delta_agc032-r0/Delta-agc032/port_config.ini create mode 100644 device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile create mode 100644 device/delta/x86_64-delta_agc032-r0/Delta-agc032/th3-agc032-32x400G.config.bcm create mode 100644 device/delta/x86_64-delta_agc032-r0/custom_led.bin create mode 100644 device/delta/x86_64-delta_agc032-r0/default_sku create mode 100644 device/delta/x86_64-delta_agc032-r0/fancontrol create mode 100755 device/delta/x86_64-delta_agc032-r0/fancontrol.service create mode 100644 device/delta/x86_64-delta_agc032-r0/installer.conf create mode 100644 device/delta/x86_64-delta_agc032-r0/led_proc_init.soc create mode 100644 device/delta/x86_64-delta_agc032-r0/platform_env.conf create mode 100644 device/delta/x86_64-delta_agc032-r0/plugins/eeprom.py create mode 100644 device/delta/x86_64-delta_agc032-r0/plugins/psuutil.py create mode 100644 device/delta/x86_64-delta_agc032-r0/plugins/sfputil.py create mode 100644 device/delta/x86_64-delta_agc032-r0/pmon_daemon_control.json create mode 100644 device/delta/x86_64-delta_agc032-r0/sensors.conf create mode 100644 platform/broadcom/sonic-platform-modules-delta/agc032/cfg/agc032-modules.conf create mode 100644 platform/broadcom/sonic-platform-modules-delta/agc032/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_cpupld.c create mode 100644 platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_platform.c create mode 100644 platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_qsfp.c create mode 100644 platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_swpld.c create mode 100644 platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_agc032_psu.c create mode 100644 platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2302.c create mode 120000 platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2305.c create mode 100755 platform/broadcom/sonic-platform-modules-delta/agc032/scripts/agc032_platform_init.sh create mode 100644 platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.init create mode 100644 platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.install create mode 100644 platform/broadcom/sonic-platform-modules-delta/systemd/platform-modules-agc032.service diff --git a/device/delta/x86_64-delta_agc032-r0/Delta-agc032/port_config.ini b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/port_config.ini new file mode 100644 index 000000000000..e081ee55aea7 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias speed index +Ethernet0 17,18,19,20,21,22,23,24 fourhundredGigE1/1 400000 0 +Ethernet4 25,26,27,28,29,30,31,32 fourhundredGigE1/2 400000 1 +Ethernet8 1,2,3,4,5,6,7,8, fourhundredGigE1/3 400000 2 +Ethernet12 9,10,11,12,13,14,15,16 fourhundredGigE1/4 400000 3 +Ethernet16 49,50,51,52,53,54,55,56 fourhundredGigE1/5 400000 4 +Ethernet20 57,58,59,60,61,62,63,64 fourhundredGigE1/6 400000 5 +Ethernet24 33,34,35,36,37,38,39,40 fourhundredGigE1/7 400000 6 +Ethernet28 41,42,43,44,45,46,47,48 fourhundredGigE1/8 400000 7 +Ethernet32 81,82,83,84,85,86,87,88 fourhundredGigE1/9 400000 8 +Ethernet36 89,90,91,92,93,94,95,96 fourhundredGigE1/10 400000 9 +Ethernet40 65,66,67,68,69,70,71,72 fourhundredGigE1/11 400000 10 +Ethernet44 73,74,75,76,77,78,79,80 fourhundredGigE1/12 400000 11 +Ethernet48 113,114,115,116,117,118,119,120 fourhundredGigE1/13 400000 12 +Ethernet52 121,122,123,124,125,126,127,128 fourhundredGigE1/14 400000 13 +Ethernet56 97,98,99,100,101,102,103,104 fourhundredGigE1/15 400000 14 +Ethernet60 105,106,107,108,109,110,111,112 fourhundredGigE1/16 400000 15 +Ethernet64 129,130,131,132,133,134,135,136 fourhundredGigE1/17 400000 16 +Ethernet68 137,138,139,140,141,142,143,144 fourhundredGigE1/18 400000 17 +Ethernet72 145,146,147,148,149,150,151,152 fourhundredGigE1/19 400000 18 +Ethernet76 153,154,155,156,157,158,159,160 fourhundredGigE1/20 400000 19 +Ethernet80 161,162,163,164,165,166,167,168 fourhundredGigE1/21 400000 20 +Ethernet84 169,170,171,172,173,174,175,176 fourhundredGigE1/22 400000 21 +Ethernet88 177,178,179,180,181,182,183,184 fourhundredGigE1/23 400000 22 +Ethernet92 185,186,187,188,189,190,191,192 fourhundredGigE1/24 400000 23 +Ethernet96 193,194,195,196,197,198,199,200 fourhundredGigE1/25 400000 24 +Ethernet100 201,202,203,204,205,206,207,208 fourhundredGigE1/26 400000 25 +Ethernet104 209,210,211,212,213,214,215,216 fourhundredGigE1/27 400000 26 +Ethernet108 217,218,219,220,221,222,223,224 fourhundredGigE1/28 400000 27 +Ethernet112 225,226,227,228,229,230,231,232 fourhundredGigE1/29 400000 28 +Ethernet116 233,234,235,236,237,238,239,240 fourhundredGigE1/30 400000 29 +Ethernet120 241,242,243,244,245,246,247,248 fourhundredGigE1/31 400000 30 +Ethernet124 249,250,251,252,253,254,255,256 fourhundredGigE1/32 400000 31 +Ethernet128 257 tenGigE1/33 10000 32 +Ethernet132 258 tenGigE1/34 10000 33 diff --git a/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile new file mode 100644 index 000000000000..9d3f2cccc2da --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-agc032-32x400G.config.bcm diff --git a/device/delta/x86_64-delta_agc032-r0/Delta-agc032/th3-agc032-32x400G.config.bcm b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/th3-agc032-32x400G.config.bcm new file mode 100644 index 000000000000..d3dfd269ff1b --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/th3-agc032-32x400G.config.bcm @@ -0,0 +1,280 @@ +######################################### +## cfg for AGC032 +######################################### +pbmp_xport_xe=0x8000f8000fc000f8000f8000f8000fc000f8001e +ccm_dma_enable=0 +ccmdma_intr_enable=0 +ctr_evict_enable=0 +mem_cache_enable=0 +parity_correction=0 +parity_enable=0 +phy_enable=0 +phy_null=1 +pll_bypass=1 +init_all_modules=0 +################################################################################ +# Pipe 0 +portmap_1=1:400 +portmap_2=9:400 +portmap_3=17:400 +portmap_4=25:400 + +#loopback port +portmap_19=259:10 +################################################################################ +# Pipe 1 +portmap_20=33:400 +portmap_21=41:400 +portmap_22=49:400 +portmap_23=57:400 + +#management port +portmap_38=257:10 + +#loopback port +portmap_39=260:10 +################################################################################ +# Pipe 2 +portmap_40=65:400 +portmap_41=73:400 +portmap_42=81:400 +portmap_43=89:400 + +#loopback port +portmap_59=261:10 +################################################################################ +# Pipe 3 +portmap_60=97:400 +portmap_61=105:400 +portmap_62=113:400 +portmap_63=121:400 + +#loopback port +portmap_79=262:10 +################################################################################ +# Pipe 4 +portmap_80=129:400 +portmap_81=137:400 +portmap_82=145:400 +portmap_83=153:400 + +#loopback port +portmap_99=263:10 +################################################################################ +# Pipe 5 +portmap_100=161:400 +portmap_101=169:400 +portmap_102=177:400 +portmap_103=185:400 + +#management port +portmap_118=258:10 + +#loopback port +portmap_119=264:10 +################################################################################ +# Pipe 6 +portmap_120=193:400 +portmap_121=201:400 +portmap_122=209:400 +portmap_123=217:400 + +#loopback port +portmap_139=265:10 +################################################################################ +# Pipe 7 +portmap_140=225:400 +portmap_141=233:400 +portmap_142=241:400 +portmap_143=249:400 + +#loopback port +portmap_159=266:10 +################################################################################ +dport_map_enable=1 + +dport_map_port_1=3 +dport_map_port_2=4 +dport_map_port_3=1 +dport_map_port_4=2 +dport_map_port_20=7 +dport_map_port_21=8 +dport_map_port_22=5 +dport_map_port_23=6 +dport_map_port_40=11 +dport_map_port_41=12 +dport_map_port_42=9 +dport_map_port_43=10 +dport_map_port_60=15 +dport_map_port_61=16 +dport_map_port_62=13 +dport_map_port_63=14 +dport_map_port_80=17 +dport_map_port_81=18 +dport_map_port_82=19 +dport_map_port_83=20 +dport_map_port_100=21 +dport_map_port_101=22 +dport_map_port_102=23 +dport_map_port_103=24 +dport_map_port_120=25 +dport_map_port_121=26 +dport_map_port_122=27 +dport_map_port_123=28 +dport_map_port_140=29 +dport_map_port_141=30 +dport_map_port_142=31 +dport_map_port_143=32 + +dport_map_port_38=33 +dport_map_port_118=34 +################################################################################ +# tx_lane map +phy_chain_tx_lane_map_physical{1.0}=0x14762350 +phy_chain_tx_lane_map_physical{9.0}=0x36104527 +phy_chain_tx_lane_map_physical{17.0}=0x17053624 +phy_chain_tx_lane_map_physical{25.0}=0x57314602 +phy_chain_tx_lane_map_physical{33.0}=0x46302517 +phy_chain_tx_lane_map_physical{41.0}=0x76203514 +phy_chain_tx_lane_map_physical{49.0}=0x26143507 +phy_chain_tx_lane_map_physical{57.0}=0x74236510 +phy_chain_tx_lane_map_physical{65.0}=0x75021436 +phy_chain_tx_lane_map_physical{73.0}=0x67210435 +phy_chain_tx_lane_map_physical{81.0}=0x26143507 +phy_chain_tx_lane_map_physical{89.0}=0x75436120 +phy_chain_tx_lane_map_physical{97.0}=0x54621730 +phy_chain_tx_lane_map_physical{105.0}=0x64310725 +phy_chain_tx_lane_map_physical{113.0}=0x07352416 +phy_chain_tx_lane_map_physical{121.0}=0x13762054 +phy_chain_tx_lane_map_physical{129.0}=0x13427506 +phy_chain_tx_lane_map_physical{137.0}=0x54307612 +phy_chain_tx_lane_map_physical{145.0}=0x76103524 +phy_chain_tx_lane_map_physical{153.0}=0x67103425 +phy_chain_tx_lane_map_physical{161.0}=0x15402637 +phy_chain_tx_lane_map_physical{169.0}=0x76135420 +phy_chain_tx_lane_map_physical{177.0}=0x67052431 +phy_chain_tx_lane_map_physical{185.0}=0x57103624 +phy_chain_tx_lane_map_physical{193.0}=0x15402637 +phy_chain_tx_lane_map_physical{201.0}=0x54137620 +phy_chain_tx_lane_map_physical{209.0}=0x56012734 +phy_chain_tx_lane_map_physical{217.0}=0x57301426 +phy_chain_tx_lane_map_physical{225.0}=0x07352641 +phy_chain_tx_lane_map_physical{233.0}=0x57236401 +phy_chain_tx_lane_map_physical{241.0}=0x16543720 +phy_chain_tx_lane_map_physical{249.0}=0x50273416 + +# rx_lane_map +phy_chain_rx_lane_map_physical{1.0}=0x42305761 +phy_chain_rx_lane_map_physical{9.0}=0x13605472 +phy_chain_rx_lane_map_physical{17.0}=0x41730652 +phy_chain_rx_lane_map_physical{25.0}=0x71206534 +phy_chain_rx_lane_map_physical{33.0}=0x62170453 +phy_chain_rx_lane_map_physical{41.0}=0x27641305 +phy_chain_rx_lane_map_physical{49.0}=0x53604271 +phy_chain_rx_lane_map_physical{57.0}=0x31607425 +phy_chain_rx_lane_map_physical{65.0}=0x47612350 +phy_chain_rx_lane_map_physical{73.0}=0x23471605 +phy_chain_rx_lane_map_physical{81.0}=0x43710265 +phy_chain_rx_lane_map_physical{89.0}=0x31706425 +phy_chain_rx_lane_map_physical{97.0}=0x60317425 +phy_chain_rx_lane_map_physical{105.0}=0x40635172 +phy_chain_rx_lane_map_physical{113.0}=0x20573146 +phy_chain_rx_lane_map_physical{121.0}=0x51204637 +phy_chain_rx_lane_map_physical{129.0}=0x34102567 +phy_chain_rx_lane_map_physical{137.0}=0x70143526 +phy_chain_rx_lane_map_physical{145.0}=0x20316574 +phy_chain_rx_lane_map_physical{153.0}=0x13572046 +phy_chain_rx_lane_map_physical{161.0}=0x61253074 +phy_chain_rx_lane_map_physical{169.0}=0x61043527 +phy_chain_rx_lane_map_physical{177.0}=0x43617250 +phy_chain_rx_lane_map_physical{185.0}=0x31067425 +phy_chain_rx_lane_map_physical{193.0}=0x35162074 +phy_chain_rx_lane_map_physical{201.0}=0x30146527 +phy_chain_rx_lane_map_physical{209.0}=0x73506241 +phy_chain_rx_lane_map_physical{217.0}=0x73241605 +phy_chain_rx_lane_map_physical{225.0}=0x26573140 +phy_chain_rx_lane_map_physical{233.0}=0x46213750 +phy_chain_rx_lane_map_physical{241.0}=0x13650274 +phy_chain_rx_lane_map_physical{249.0}=0x42305167 + +# tx polarity +serdes_core_tx_polarity_flip_physical{1}=0x5d +serdes_core_tx_polarity_flip_physical{9}=0x9c +serdes_core_tx_polarity_flip_physical{17}=0x72 +serdes_core_tx_polarity_flip_physical{25}=0xad +serdes_core_tx_polarity_flip_physical{33}=0x38 +serdes_core_tx_polarity_flip_physical{41}=0x86 +serdes_core_tx_polarity_flip_physical{49}=0xaf +serdes_core_tx_polarity_flip_physical{57}=0xc6 +serdes_core_tx_polarity_flip_physical{65}=0x70 +serdes_core_tx_polarity_flip_physical{73}=0xc7 +serdes_core_tx_polarity_flip_physical{81}=0xae +serdes_core_tx_polarity_flip_physical{89}=0xe0 +serdes_core_tx_polarity_flip_physical{97}=0xf1 +serdes_core_tx_polarity_flip_physical{105}=0x0c +serdes_core_tx_polarity_flip_physical{113}=0xc8 +serdes_core_tx_polarity_flip_physical{121}=0x3f +serdes_core_tx_polarity_flip_physical{129}=0x8b +serdes_core_tx_polarity_flip_physical{137}=0x77 +serdes_core_tx_polarity_flip_physical{145}=0x39 +serdes_core_tx_polarity_flip_physical{153}=0xa5 +serdes_core_tx_polarity_flip_physical{161}=0xd8 +serdes_core_tx_polarity_flip_physical{169}=0x8b +serdes_core_tx_polarity_flip_physical{177}=0x29 +serdes_core_tx_polarity_flip_physical{185}=0x30 +serdes_core_tx_polarity_flip_physical{193}=0xf8 +serdes_core_tx_polarity_flip_physical{201}=0x8a +serdes_core_tx_polarity_flip_physical{209}=0xb8 +serdes_core_tx_polarity_flip_physical{217}=0x08 +serdes_core_tx_polarity_flip_physical{225}=0xb3 +serdes_core_tx_polarity_flip_physical{233}=0x62 +serdes_core_tx_polarity_flip_physical{241}=0x70 +serdes_core_tx_polarity_flip_physical{249}=0xd2 + +# rx poplarity +serdes_core_rx_polarity_flip_physical{1}=0x18 +serdes_core_rx_polarity_flip_physical{9}=0xa0 +serdes_core_rx_polarity_flip_physical{17}=0x9c +serdes_core_rx_polarity_flip_physical{25}=0x47 +serdes_core_rx_polarity_flip_physical{33}=0xf5 +serdes_core_rx_polarity_flip_physical{41}=0x38 +serdes_core_rx_polarity_flip_physical{49}=0x87 +serdes_core_rx_polarity_flip_physical{57}=0x1a +serdes_core_rx_polarity_flip_physical{65}=0xf0 +serdes_core_rx_polarity_flip_physical{73}=0x68 +serdes_core_rx_polarity_flip_physical{81}=0x96 +serdes_core_rx_polarity_flip_physical{89}=0x32 +serdes_core_rx_polarity_flip_physical{97}=0x5a +serdes_core_rx_polarity_flip_physical{105}=0xb4 +serdes_core_rx_polarity_flip_physical{113}=0xe1 +serdes_core_rx_polarity_flip_physical{121}=0x4a +serdes_core_rx_polarity_flip_physical{129}=0xf3 +serdes_core_rx_polarity_flip_physical{137}=0xc3 +serdes_core_rx_polarity_flip_physical{145}=0x12 +serdes_core_rx_polarity_flip_physical{153}=0xb4 +serdes_core_rx_polarity_flip_physical{161}=0xf0 +serdes_core_rx_polarity_flip_physical{169}=0xa7 +serdes_core_rx_polarity_flip_physical{177}=0xe1 +serdes_core_rx_polarity_flip_physical{185}=0x90 +serdes_core_rx_polarity_flip_physical{193}=0x0a +serdes_core_rx_polarity_flip_physical{201}=0x4e +serdes_core_rx_polarity_flip_physical{209}=0x5a +serdes_core_rx_polarity_flip_physical{217}=0x98 +serdes_core_rx_polarity_flip_physical{225}=0x2f +serdes_core_rx_polarity_flip_physical{233}=0x5b +serdes_core_rx_polarity_flip_physical{241}=0xf4 +serdes_core_rx_polarity_flip_physical{249}=0x1d +################################################################################ +#firmware load, use fast load +load_firmware=0x2 + +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 + + +################################################################################ +serdes_tx_taps_cd=pam4:-36:118:0:8:6:0 + + diff --git a/device/delta/x86_64-delta_agc032-r0/custom_led.bin b/device/delta/x86_64-delta_agc032-r0/custom_led.bin new file mode 100644 index 0000000000000000000000000000000000000000..e91edee198155915d4b993cfb58ff472c3ad23a3 GIT binary patch literal 1000 zcmZwFTWkzb7y#gZE@yVOw%aaE>{gZCZfCMKT9;HPYIN6WR7&cWuvpucOeKg1NhQcg zT^5PU3W+rCJXC3GDG{a7cpzS8M1w>)jl_loB_Z)Z{X2vglYBY^)a{hyq4+w3A8lNH^pvDdG`-~}iigJ}H5cDTrDCwr{)RS~o zgVo9Q>J>%Hq9456?1?SX?2lS*+l|%3nNY)7dfk9^t$#cax*QkHT0174Wo@vrID_WOSs8W=#2$!q&+vODLs)(k@X8Jv|Pja z--`F_ig`uOIWc-idmZV+ig9{a8^-8gMfabIb;< zD@lhh=`rT&8@ys=EIG;$r^yvHwI`~S8W6hvld; zbE^^?p^7X|Pr?<3w>CqWb+}L{;6O|msD>9Q5 zi3y6x9172f0!&sgzwB>**QZ!7T}^wm&h+=U(U|}y8vZ#v{1C?nD0@evBnDLfvX~3> zuf;zgkyjE)I7?a+{fYdb*f1^_ZD?)iZx|mG8_R>y#@5FE#z_IbNefgrwKm;va&*t? zJwi{?^R$Bw-35F+$cH%OM3d1B +# Copyright (C) 2007-2009 Jean Delvare +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA. +# +# + +PIDFILE="/var/run/fancontrol.pid" + +#DEBUG=1 +MAX=255 + +function LoadConfig +{ + local fcvcount fcv + + echo "Loading configuration from $1 ..." + if [ ! -r "$1" ] + then + echo "Error: Can't read configuration file" >&2 + exit 1 + fi + + # grep configuration from file + INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'` + DEVPATH=`egrep '^DEVPATH=.*$' $1 | sed -e 's/DEVPATH= *//g'` + DEVNAME=`egrep '^DEVNAME=.*$' $1 | sed -e 's/DEVNAME= *//g'` + FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'` + MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'` + MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'` + MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'` + MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'` + HWMON=$( echo "$DEVPATH" | sed 's/=.*$//g') + FCDEVPATH=$( echo "$DEVPATH" | sed 's/^.*=//g') + FCMINTEMP=$MINTEMP + FCMAXTEMP=$MAXTEMP + FCMINSTART=$MINSTART + FCMINSTOP=$MINSTOP + AFCTEMP_1_LOWER=(00 39 36 41 46 55) + AFCTEMP_1_UPPER=(39 39 44 49 54 150) + AFCTEMP_2_LOWER=(00 61 65 69 73 82) + AFCTEMP_2_UPPER=(63 67 71 75 79 150) + AFCTEMP_3_LOWER=(00 51 55 59 63 71) + AFCTEMP_3_UPPER=(53 57 61 65 69 150) + AFCTEMP_4_LOWER=(00 46 50 54 58 65) + AFCTEMP_4_UPPER=(45 52 56 60 64 150) + AFCTEMP_5_LOWER=(00 46 50 54 58 65) + AFCTEMP_5_UPPER=(45 52 56 60 64 150) + + + FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS=//g'` + + # Check whether all mandatory settings are set + if [[ -z ${INTERVAL} || -z ${FCTEMPS} || -z ${MINTEMP} || -z ${MAXTEMP} || -z ${MINSTART} || -z ${MINSTOP} ]] + then + echo "Some mandatory settings missing, please check your config file!" >&2 + exit 1 + fi + if [ "$INTERVAL" -le 0 ] + then + echo "Error in configuration file:" >&2 + echo "INTERVAL must be at least 1" >&2 + exit 1 + fi + + # write settings to arrays for easier use and print them + echo + echo "Common settings:" + + temp_string=$FCTEMPS + + let fcvcount=0 + for fcv in $FCTEMPS + do + fcvcount=$((fcvcount+1)) + AFCTEMP[$fcvcount]=$( echo "$temp_string" | cut -d" " -f $fcvcount ) + AFCTEMP[$fcvcount]=$( echo "${AFCTEMP[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + AFCTEMP_PATH[$fcvcount]=$( echo "${AFCTEMP[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + AFCTEMP[$fcvcount]=$( cat ${AFCTEMP[$fcvcount]} ) + AFCTEMP[$fcvcount]=$(( AFCTEMP[$fcvcount]/1000 )) + done + + fan_string=$FCFANS + fcvcount=0 + zero=0 + for fcv in $FCFANS + do + fcvcount=$((fcvcount+1)) + AFCFAN[$fcvcount]=$( echo "$fan_string" | cut -d" " -f $fcvcount ) + AFCFAN_PATH[$fcvcount]=$( echo "${AFCFAN[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + AFCFAN_TARGET[$fcvcount]=$( echo "${AFCFAN_PATH[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + AFCFAN_TARGET[$fcvcount]=$( echo "${AFCFAN_TARGET[$fcvcount]}" | sed 's/$/_percentage/g') + AFCFAN[$fcvcount]=$( cat ${AFCFAN_PATH[$fcvcount]} ) + if [ "${AFCFAN[$fcvcount]}" == 960 ] + then + AFCFAN[$fcvcount]=$zero + fi + done +} + +# Check that all referenced sysfs files exist +function CheckFiles +{ + local outdated=0 fcvcount tsen fan + if [ $outdated -eq 1 ] + then + echo >&2 + echo "At least one referenced file is missing. Either some required kernel" >&2 + echo "modules haven't been loaded, or your configuration file is outdated." >&2 + echo "In the latter case, you should run pwmconfig again." >&2 + fi + return $outdated +} + +#LoadConfig $1 +if [ -f "$1" ] +then + LoadConfig $1 +else + LoadConfig /etc/fancontrol +fi + +# Detect path to sensors +if [ ! -d $DIR ] +then + echo $0: 'No sensors found! (did you load the necessary modules?)' >&2 + exit 1 +fi +cd $DIR + +# Check for configuration change +if [ "$DIR" != "/" ] && [ -z "$DEVPATH" -o -z "$DEVNAME" ] +then + echo "Configuration is too old, please run pwmconfig again" >&2 + exit 1 +fi +if [ "$DIR" = "/" -a -n "$DEVPATH" ] +then + echo "Unneeded DEVPATH with absolute device paths" >&2 + exit 1 +fi +CheckFiles || exit 1 + +if [ -f "$PIDFILE" ] +then + echo "File $PIDFILE exists, is fancontrol already running?" >&2 + exit 1 +fi +echo $$ > "$PIDFILE" + +# main function +function UpdateThermalSensors +{ + fcvcount=0 + for fcv in $FCTEMPS + do + fcvcount=$((fcvcount+1)) + AFCTEMP[$fcvcount]=$( cat ${AFCTEMP_PATH[$fcvcount]} ) + AFCTEMP[$fcvcount]=$(( AFCTEMP[$fcvcount]/1000 )) + done +} + +function UpdateThermalLevel +{ + AFCTEMP_NUM=$((6-${AFCTEMP_LEVEL[$i]})) + AFCTEMP_UPPER_BUF=AFCTEMP_"$i"_UPPER["$AFCTEMP_NUM"] + AFCTEMP_LOWER_BUF=AFCTEMP_"$i"_LOWER["$AFCTEMP_NUM"] + + AFCTEMP_UPPER=${!AFCTEMP_UPPER_BUF} + AFCTEMP_LOWER=${!AFCTEMP_LOWER_BUF} + + + if (( ("${AFCTEMP[$i]}" <= "$AFCTEMP_UPPER") && ("${AFCTEMP[$i]}" >= "$AFCTEMP_LOWER") )) ; then + FLAG=2 + elif (( "${AFCTEMP[$i]}" > "$AFCTEMP_UPPER" )); then + AFCTEMP_LEVEL[$i]=$((${AFCTEMP_LEVEL[$i]} - 1)) + FLAG=1 + elif (( "${AFCTEMP[$i]}" < "$AFCTEMP_LOWER" )); then + AFCTEMP_LEVEL[$i]=$((${AFCTEMP_LEVEL[$i]} + 1)) + FLAG=1 + else + AFCTEMP_LEVEL[$i]=1 + FLAG=2 + fi +} + +function UpdateFanSpeeds +{ + #echo "num tmp lev F L H" + #Update level + for i in 1 2 3 4 5 + do + #echo "----------------------" + FLAG=0 + #FLAG=0 : initial flag + #FLAG=1 : update level + #FLAG=2 : final level + while [ $FLAG -ne 2 ] + do + UpdateThermalLevel + #echo " $i ${AFCTEMP[$i]} ${AFCTEMP_LEVEL[$i]} $FLAG $AFCTEMP_LOWER $AFCTEMP_UPPER " + done + done + + min=${AFCTEMP_LEVEL[0]} + for j in "${AFCTEMP_LEVEL[@]}"; do + (( j < min )) && min=$j + done + + if (($min == 1 || $min == 2)); then + FAN_PERCENTAGE=100 + elif (($min == 3)); then + FAN_PERCENTAGE=80 + elif (($min == 4)); then + FAN_PERCENTAGE=60 + elif (($min == 5)); then + FAN_PERCENTAGE=50 + elif (($min == 6)); then + FAN_PERCENTAGE=40 + else + FAN_PERCENTAGE=100 + fi + echo "The lowest level of thermal sensors: $min " + echo "Trying to set fan speed to $FAN_PERCENTAGE %" + #Set speed to fan1~fan10 + let fcvcount=0 + for fcv in $FCFANS + do + fcvcount=$(( fcvcount + 1 )) + echo $FAN_PERCENTAGE > ${AFCFAN_TARGET[$fcvcount]} + AFCFAN[$fcvcount]=$( cat ${AFCFAN_PATH[$fcvcount]} ) + + if [ "${AFCFAN[$fcvcount]}" == 960 ] + then + AFCFAN[$fcvcount]=$zero + fi + echo "FAN fan$fcvcount = ${AFCFAN[$fcvcount]} (rpm)" + done + + FAN_ON_PSU_PERCENTAGE=$FAN_PERCENTAGE + #Set speed to PSU_FAN1 + echo "$FAN_ON_PSU_PERCENTAGE" > '/sys/bus/i2c/devices/1-0058/fan1_set_percentage' + echo "PSU fan1 =$( cat '/sys/bus/i2c/devices/1-0058/fan1_input' ) (rpm)" + #Set speed to PSU_FAN2 + echo "$FAN_ON_PSU_PERCENTAGE" > '/sys/bus/i2c/devices/2-0058/fan1_set_percentage' + echo "PSU fan2 =$( cat '/sys/bus/i2c/devices/2-0058/fan1_input' ) (rpm)" + + rm -f "$PIDFILE" +} + +# main loop calling the main function at specified intervals +AFCTEMP_LEVEL=(9 4 4 4 4 4) #inttial level +while true +do + UpdateThermalSensors + UpdateFanSpeeds + echo "Sleep $INTERVAL seconds ..." + echo + # Sleep while still handling signals + sleep $INTERVAL & + wait $! +done diff --git a/device/delta/x86_64-delta_agc032-r0/installer.conf b/device/delta/x86_64-delta_agc032-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/delta/x86_64-delta_agc032-r0/led_proc_init.soc b/device/delta/x86_64-delta_agc032-r0/led_proc_init.soc new file mode 100644 index 000000000000..5dcf85ea7956 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/led_proc_init.soc @@ -0,0 +1,5 @@ +led auto off +led stop +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on +led start diff --git a/device/delta/x86_64-delta_agc032-r0/platform_env.conf b/device/delta/x86_64-delta_agc032-r0/platform_env.conf new file mode 100644 index 000000000000..283e1c0ce710 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/platform_env.conf @@ -0,0 +1 @@ +usemsi=1 diff --git a/device/delta/x86_64-delta_agc032-r0/plugins/eeprom.py b/device/delta/x86_64-delta_agc032-r0/plugins/eeprom.py new file mode 100644 index 000000000000..631adbfc6bbd --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/plugins/eeprom.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0053/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/delta/x86_64-delta_agc032-r0/plugins/psuutil.py b/device/delta/x86_64-delta_agc032-r0/plugins/psuutil.py new file mode 100644 index 000000000000..0636417def1f --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/plugins/psuutil.py @@ -0,0 +1,62 @@ +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/bus/i2c/devices/{}-0058/" + self.psu_oper_status = "in1_input" + self.psu_oper_status2 = "in2_input" + self.psu_presence = "i2cget -y {} 0x50 0x00" + + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + if index is None: + return False + Base_bus_number = 0 + status = 0 + #index from 1, psu attribute bus from 40 + try: + with open(self.psu_path.format(index + Base_bus_number) + self.psu_oper_status, 'r') as power_status: + if int(power_status.read()) == 0 : + return False + else: + with open(self.psu_path.format(index + Base_bus_number) + self.psu_oper_status2, 'r') as power_status2: + if int(power_status2.read()) == 0 : + return False + else: + status = 1 + except IOError: + return False + return status == 1 + + def get_psu_presence(self, index): + if index is None: + return False + Base_bus_number = 0 + status = 0 + try: + p = os.popen(self.psu_presence.format(index + Base_bus_number)+ "> /dev/null 2>&1") + if p.readline() != None: + status = 1 + p.close() + except IOError: + return False + return status == 1 + + diff --git a/device/delta/x86_64-delta_agc032-r0/plugins/sfputil.py b/device/delta/x86_64-delta_agc032-r0/plugins/sfputil.py new file mode 100644 index 000000000000..a448d4101939 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/plugins/sfputil.py @@ -0,0 +1,241 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_sfp.sff8436 import sff8436Dom +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 33 + PORTS_IN_BLOCK = 32 + + EEPROM_OFFSET = 1 + + CPLD_SWITCH = 0 + + _port_to_eeprom_mapping = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(0, self.PORTS_IN_BLOCK) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = "/sys/bus/i2c/devices/{0}-0050/eeprom" + + for x in range(0, self.port_end + 1): + self._port_to_eeprom_mapping[x] = eeprom_path.format(x + self.EEPROM_OFFSET) + + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + # Retrieve file path of presence + port = (str(port_num + 1)).zfill(2) + + # SWPLD2 for port 1~16, SWPLD3 for port 17~34 + if port_num < 16: + present_path = "SWPLD2/qsfp_p{}_modprs".format(port) + elif port_num < self.PORTS_IN_BLOCK: + present_path = "SWPLD3/qsfp_p{}_modprs".format(port) + else: + present_path = "SWPLD3/sfp_p{}_modprs".format(str(port_num - self.PORTS_IN_BLOCK)) + + try: + with open("/sys/devices/platform/delta-agc032-swpld.0/" + present_path, 'r') as present: + if int(present.readline()) == 0: + return True + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num >= self.PORTS_IN_BLOCK: + return False + + # Retrieve file path of presence + port = (str(port_num + 1)).zfill(2) + + # SWPLD2 for port 1~16, SWPLD3 for port 17~32 + if port_num < 16: + lpmode_path = "SWPLD2/qsfp_p{}_lpmode".format(port) + else: + lpmode_path = "SWPLD3/qsfp_p{}_lpmode".format(port) + + try: + with open("/sys/devices/platform/delta-agc032-swpld.0/" + lpmode_path, 'r') as lpmode: + if int(lpmode.readline()) == 1: + return True + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + return False + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num >= self.PORTS_IN_BLOCK: + return False + + # Retrieve file path of presence + port = (str(port_num + 1)).zfill(2) + + # SWPLD2 for port 1~16, SWPLD3 for port 17~32 + if port_num < 16: + lpmode_path = "SWPLD2/qsfp_p{}_lpmode".format(port) + else: + lpmode_path = "SWPLD3/qsfp_p{}_lpmode".format(port) + + try: + file = open("/sys/devices/platform/delta-agc032-swpld.0/" + lpmode_path, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + file.seek(0) + if lpmode is True: + # "1" for lpmode on + file.write('1') + else: + # "0" for lpmode off + file.write('0') + file.close() + + return True + + def reset(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num >= self.PORTS_IN_BLOCK: + return False + + # Retrieve file path of presence + port = (str(port_num + 1)).zfill(2) + + # SWPLD2 for port 1~16, SWPLD3 for port 17~32 + if port_num < 16: + reset_path = "SWPLD2/qsfp_p{}_rst".format(port) + else: + reset_path = "SWPLD3/qsfp_p{}_rst".format(port) + + try: + file = open("/sys/devices/platform/delta-agc032-swpld.0/" + reset_path, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + file.seek(0) + file.write('0') + file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + file = open("/sys/devices/platform/delta-agc032-swpld.0/" + reset_path, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + file.seek(0) + file.write('1') + file.close() + + return True + + def get_eeprom_dict(self, port_num): + sfp_data = {} + + try: + file = open("/sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel", 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Switch CPLD to FRONT-PORT EEPROM MUX + file.seek(0) + file.write('3') + file.close() + + eeprom_ifraw = self.get_eeprom_raw(port_num) + eeprom_domraw = self.get_eeprom_dom_raw(port_num) + + try: + file = open("/sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel", 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Switch CPLD to FRONT-PORT EEPROM MUX + file.seek(0) + file.write('1') + file.close() + + if eeprom_ifraw is None: + return None + + if port_num in self.osfp_ports: + sfpi_obj = inf8628InterfaceId(eeprom_ifraw) + if sfpi_obj is not None: + sfp_data['interface'] = sfpi_obj.get_data_pretty() + return sfp_data + elif port_num in self.qsfp_ports: + sfpi_obj = sff8436InterfaceId(eeprom_ifraw) + if sfpi_obj is not None: + sfp_data['interface'] = sfpi_obj.get_data_pretty() + # For Qsfp's the dom data is part of eeprom_if_raw + # The first 128 bytes + + sfpd_obj = sff8436Dom(eeprom_ifraw) + if sfpd_obj is not None: + sfp_data['dom'] = sfpd_obj.get_data_pretty() + + return sfp_data + else: + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + if sfpi_obj is not None: + sfp_data['interface'] = sfpi_obj.get_data_pretty() + cal_type = sfpi_obj.get_calibration_type() + + if eeprom_domraw is not None: + sfpd_obj = sff8472Dom(eeprom_domraw, cal_type) + if sfpd_obj is not None: + sfp_data['dom'] = sfpd_obj.get_data_pretty() + + return sfp_data + + def get_transceiver_change_event(self): + """ + TODO: This function need to be implemented + when decide to support monitoring SFP(Xcvrd) + on this platform. + """ + raise NotImplementedError diff --git a/device/delta/x86_64-delta_agc032-r0/pmon_daemon_control.json b/device/delta/x86_64-delta_agc032-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..d5784cc779f7 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/pmon_daemon_control.json @@ -0,0 +1,6 @@ +{ + "skip_thermalctld": true, + "skip_syseepromd": true, + "skip_fancontrol": true, + "skip_xcvrd": true +} diff --git a/device/delta/x86_64-delta_agc032-r0/sensors.conf b/device/delta/x86_64-delta_agc032-r0/sensors.conf new file mode 100644 index 000000000000..7df258da28c1 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/sensors.conf @@ -0,0 +1,47 @@ +# libsensors configuration file for DCS-7060CX-32S +# ------------------------------------------------ +# + +bus "i2c-4" "i2c-0-mux (chan_id 3)" +bus "i2c-5" "i2c-0-mux (chan_id 4)" + +chip "tmp75-i2c-4-4f" + label temp1 "Wind thermal sensor" + set temp1_max 65 + set temp1_max_hyst 60 +chip "tmp75-i2c-5-4d" + label temp1 "CPU below side thermal sensor" + set temp1_max 60 + set temp1_max_hyst 55 +chip "tmp75-i2c-5-49" + label temp1 "Surroundings thermal sensor1" + set temp1_max 65 + set temp1_max_hyst 60 +chip "tmp75-i2c-5-4a" + label temp1 "Surroundings thermal sensor2" + set temp1_max 65 + set temp1_max_hyst 60 +chip "tmp75-i2c-5-4b" + label temp1 "Surroundings thermal sensor3" + set temp1_max 65 + set temp1_max_hyst 60 +chip "tmp75-i2c-5-4d" + label temp1 "Surroundings thermal sensor4" + set temp1_max 65 + set temp1_max_hyst 60 + +chip "emc2305-i2c-4-4c" + label fan1 "FANTRAY 1 FRONT" + label fan2 "FANTRAY 2 REAR" + label fan3 "FANTRAY 3 FRONT" + label fan4 "FANTRAY 4 REAR" + label fan5 "FANTRAY 5 FRONT" +chip "emc2305-i2c-4-2d" + label fan1 "FANTRAY 1 REAR" + label fan2 "FANTRAY 2 FRONT" + label fan3 "FANTRAY 3 REAR" + label fan4 "FANTRAY 4 FRONT" + label fan5 "FANTRAY 5 REAR" +chip "emc2302-i2c-4-2e" + label fan1 "FANTRAY 1 FRONT" + label fan2 "FANTRAY 2 REAR" diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 11cc40e8fcdc..86ac56b750b2 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -58,7 +58,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(DELTA_AG9032V2A_PLATFORM_MODULE) \ $(JUNIPER_QFX5210_PLATFORM_MODULE) \ $(CEL_SILVERSTONE_PLATFORM_MODULE) \ - $(JUNIPER_QFX5200_PLATFORM_MODULE) + $(JUNIPER_QFX5200_PLATFORM_MODULE) \ + $(DELTA_AGC032_PLATFORM_MODULE) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/broadcom/platform-modules-delta.mk b/platform/broadcom/platform-modules-delta.mk index 5375c6ad7a7d..a524f2592fa8 100644 --- a/platform/broadcom/platform-modules-delta.mk +++ b/platform/broadcom/platform-modules-delta.mk @@ -5,12 +5,14 @@ DELTA_AG9064_PLATFORM_MODULE_VERSION = 1.1 DELTA_AG5648_PLATFORM_MODULE_VERSION = 1.1 DELTA_ET6248BRB_PLATFORM_MODULE_VERSION = 1.1 DELTA_AG9032V2A_PLATFORM_MODULE_VERSION = 1.1 +DELTA_AGC032_PLATFORM_MODULE_VERSION = 1.1 export DELTA_AG9032V1_PLATFORM_MODULE_VERSION export DELTA_AG9064_PLATFORM_MODULE_VERSION export DELTA_AG5648_PLATFORM_MODULE_VERSION export DELTA_ET6248BRB_PLATFORM_MODULE_VERSION export DELTA_AG9032V2A_PLATFORM_MODULE_VERSION +export DELTA_AGC032_PLATFORM_MODULE_VERSION DELTA_AG9032V1_PLATFORM_MODULE = platform-modules-ag9032v1_$(DELTA_AG9032V1_PLATFORM_MODULE_VERSION)_amd64.deb $(DELTA_AG9032V1_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-delta @@ -34,3 +36,8 @@ DELTA_AG9032V2A_PLATFORM_MODULE = platform-modules-ag9032v2a_$(DELTA_AG9032V2A_P $(DELTA_AG9032V2A_PLATFORM_MODULE)_PLATFORM = x86_64-delta_ag9032v2a-r0 $(eval $(call add_extra_package,$(DELTA_AG9032V1_PLATFORM_MODULE),$(DELTA_AG9032V2A_PLATFORM_MODULE))) +DELTA_AGC032_PLATFORM_MODULE = platform-modules-agc032_$(DELTA_AGC032_PLATFORM_MODULE_VERSION)_amd64.deb +$(DELTA_AGC032_PLATFORM_MODULE)_PLATFORM = x86_64-delta_agc032-r0 +$(eval $(call add_extra_package,$(DELTA_AG9032V1_PLATFORM_MODULE),$(DELTA_AGC032_PLATFORM_MODULE))) + +SONIC_STRETCH_DEBS += $(DELTA_AG9032V1_PLATFORM_MODULE) diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/cfg/agc032-modules.conf b/platform/broadcom/sonic-platform-modules-delta/agc032/cfg/agc032-modules.conf new file mode 100644 index 000000000000..552b4103ed02 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/cfg/agc032-modules.conf @@ -0,0 +1,13 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus +i2c-mux-gpio +i2c-mux-pca954x diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/Makefile b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/Makefile new file mode 100644 index 000000000000..93bd96998409 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/Makefile @@ -0,0 +1 @@ +obj-m := dni_agc032_psu.o dni_emc2305.o delta_agc032_platform.o delta_agc032_cpupld.o dni_emc2302.o delta_agc032_swpld.o delta_agc032_qsfp.o diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_cpupld.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_cpupld.c new file mode 100644 index 000000000000..76ae53d314de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_cpupld.c @@ -0,0 +1,746 @@ +#include +#include +#include +#include +#include +#include + +#define CPUPLD_I2C_ADDR 0x31 + +enum cpld_type { + cpld, +}; + +struct platform_data { + int reg_addr; + struct i2c_client *client; +}; + +enum{ + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, + BUS8, +}; + +enum{ + CPU_PCB_NUM = 0, + CPUPLD_VER_TYPE, + CPUPLD_VER, + BDXDE_PLAT_RST, + BDXDE_SLP3_STAT, + BDXDE_SLP4_STAT, + BDXDE_CPU_RST, + CPLD_DEBUG_MODE, + APWROK_STAT, + EDGE_PROCHOT_SIG_DIS, + PSU_THERMAL_STAT, + PR_THERMAL_STAT, + ME_DRIVE_SIG_EN, + CPU_THERMAL_STAT, + DDR_THERMAL_STAT, + SYS_THERMAL_STAT, + DEBUG_LED3_EN, + DEBUG_LED2_EN, + DEBUG_LED1_EN, + DEBUG_LED0_EN, + CPU_STANDBY_MODE, + CPLD_RST, + MB_POWER_STAT, + BIOS1_SPI_WP, + BIOS2_SPI_WP, + BIOS_MUX_SEL, + GBE_SPI_WP, + PCH_THERMTRIP_EN, + ID_EEPROM_EN, + CPU_I2C_MUX_EN, + CPU_I2C_MUX_SEL, + PSU_FAN_INTR, + WD_TIMER, + WD_EN, + WD_CLEAR_FLAG, +}; + + +static unsigned char cpupld_reg_addr; + +static ssize_t cpupld_reg_value_show(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + struct platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[cpld].client, cpupld_reg_addr); + + return scnprintf(buf, PAGE_SIZE, "0x%02x\n", ret); +} + +static ssize_t cpupld_reg_value_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + struct platform_data *pdata = dev->platform_data; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + i2c_smbus_write_byte_data(pdata[cpld].client, cpupld_reg_addr, data); + + return count; +} + +static ssize_t cpupld_reg_addr_show(struct device *dev, struct device_attribute *devattr, char *buf) +{ + + return scnprintf(buf, PAGE_SIZE, "0x%02x\n", cpupld_reg_addr); +} + +static ssize_t cpupld_reg_addr_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + cpupld_reg_addr = data; + + return count; +} + + +static ssize_t cpupld_data_show(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct platform_data *pdata = dev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + bool hex_fmt = 0; + char desc[256] = {0}; + + select = attr->index; + switch(select) { + case CPU_PCB_NUM: + offset = 0x0; + hex_fmt = 1; + scnprintf(desc, PAGE_SIZE, "\nCPU Borad PCB Number.\n"); + break; + case CPUPLD_VER_TYPE: + offset = 0x1; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nCPUPLD Version Type.\n"); + break; + case CPUPLD_VER: + offset = 0x1; + mask = 0x7F; + scnprintf(desc, PAGE_SIZE, "\nCPUPLD Version.\n"); + break; + case BDXDE_PLAT_RST: + offset = 0x9; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Platform Reset State\n“0†= Platform Not Reset State.\n"); + break; + case BDXDE_SLP3_STAT: + offset = 0x9; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= CPU at S3 State\n“0†= CPU Not at S3 State.\n"); + break; + case BDXDE_SLP4_STAT: + offset = 0x9; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= CPU at S4Sstate\n“0†= CPU Not at S4 State.\n"); + break; + case BDXDE_CPU_RST: + offset = 0x9; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= CPU Not Reset State\n“0†= CPU Reset State.\n"); + break; + case CPLD_DEBUG_MODE: + offset = 0x9; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nCPLD Power Sequence\n“1†= Debug Mode\n“0†= Normal Mode.\n"); + break; + case APWROK_STAT: + offset = 0xA; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= APWROK Stable\n“0†= APWROK Unstable.\n"); + break; + case EDGE_PROCHOT_SIG_DIS: + offset = 0xB; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Power Supply Thermal Signal\n“0†= Enable Power Supply Thermal Signal.\n"); + break; + case PSU_THERMAL_STAT: + offset = 0xB; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Power Supply Normal Temperature\n“0†= Power Supply Over Temperature.\n"); + break; + case PR_THERMAL_STAT: + offset = 0xB; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Power Rail Normal Temperature\n“0†= Power Rail Over Temperature.\n"); + break; + case ME_DRIVE_SIG_EN: + offset = 0xB; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable System Thermal Alarm to CPU\n“0†= System Thermal Alarm to CPU.\n"); + break; + case CPU_THERMAL_STAT: + offset = 0xB; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= CPU Disomic Normal Temperature\n“0†= CPU Disomic Over Temperatur.\n"); + break; + case DDR_THERMAL_STAT: + offset = 0xB; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= DDR Normal Temperature\n“0†= DDR Over Temperature.\n"); + break; + case SYS_THERMAL_STAT: + offset = 0xC; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= System Normal Temperature.\n“0†= System Over Temperature.\n"); + break; + case DEBUG_LED3_EN: + offset = 0xD; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Debug LED3\n“0†= Enable Debug LED3.\n"); + break; + case DEBUG_LED2_EN: + offset = 0xD; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Debug LED2\n“0†= Enable Debug LED2.\n"); + break; + case DEBUG_LED1_EN: + offset = 0xD; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Debug LED1\n“0†= Enable Debug LED1.\n"); + break; + case DEBUG_LED0_EN: + offset = 0xD; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Debug LED0\n“0†= Enable Debug LED0.\n"); + break; + case CPU_STANDBY_MODE: + offset = 0x11; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= CPU Power Stanby Not Ready\n“0†= CPU Power Stanby Ready.\n"); + break; + case CPLD_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation\n“0†= CPLD Reset.\n"); + break; + case MB_POWER_STAT: + offset = 0x12; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Power Rail Good\n“0†= Power Rail Failed.\n"); + break; + case BIOS2_SPI_WP: + offset = 0x13; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable BIOS2 SPI Write Protect\n“0†= Enable BIOS2 SPI Write Protect.\n"); + break; + case BIOS1_SPI_WP: + offset = 0x13; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable BIOS1 SPI Write Protect\n“0†= Enable BIOS1 SPI Write Protect.\n"); + break; + case BIOS_MUX_SEL: + offset = 0x13; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Primary BIOS\n“0†= Backup BIOS.\n"); + break; + case GBE_SPI_WP: + offset = 0x13; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable GBE SPI Write Protect\n“0†= Enable GBE SPI Write Protect.\n"); + break; + case PCH_THERMTRIP_EN: + offset = 0x14; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Thermal Trip Not Occured\n“0†= Thermal Trip Occured.\n"); + break; + case ID_EEPROM_EN: + offset = 0x14; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable ID EEPROM Write Protect\n“0†= Enable ID EEPROM Write Protect.\n"); + break; + case CPU_I2C_MUX_EN: + offset = 0x14; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable CPU I2C Mux\n“0†= Disable CPU I2C Mux.\n"); + break; + case CPU_I2C_MUX_SEL: + offset = 0x14; + shift = 0; + mask = 0x3; + scnprintf(desc, PAGE_SIZE, "\n“3†= Select MB Panel Port.\n“2†= Select MB SWPLD.\n“1†= Select MB Mux.\n“0†= Select ONIE EEPROM.\n"); + break; + case PSU_FAN_INTR: + offset = 0x15; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU Fan Interrupt Occured\n“0†= PSU Fan Interrupt Not Occured.\n"); + break; + case WD_TIMER: + offset = 0x1E; + shift = 3; + mask = 0x38; + scnprintf(desc, PAGE_SIZE, "\n“5†= Timer 60 sec.\n“4†= Timer 50 sec.\n“3†= Timer 40 sec.\n“2†= Timer 30 sec.\n“1†= Timer 20 sec.\n“0†= Timer 15 sec.\n"); + break; + case WD_EN: + offset = 0x1E; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Watchdog Function\n“0†= Enable Watchdog Function.\n"); + break; + case WD_CLEAR_FLAG: + offset = 0x1E; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Watchdog Timer Flag Clear\n“0†= Watchdog Timer Flag Not Clear.\n"); + break; + } + + value = i2c_smbus_read_byte_data(pdata[cpld].client, offset); + value = (value & mask) >> shift; + if(hex_fmt) { + return scnprintf(buf, PAGE_SIZE, "0x%02x%s", value, desc); + } else { + return scnprintf(buf, PAGE_SIZE, "%d%s", value, desc); + } +} + +static ssize_t cpupld_data_store(struct device *dev, struct device_attribute *dev_attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct platform_data *pdata = dev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + int err = 0; + unsigned long data; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + switch (attr->index) { + case DEBUG_LED3_EN: + offset = 0xD; + shift = 3; + mask = (1 << shift); + break; + case DEBUG_LED2_EN: + offset = 0xD; + shift = 2; + mask = (1 << shift); + break; + case DEBUG_LED1_EN: + offset = 0xD; + shift = 1; + mask = (1 << shift); + break; + case DEBUG_LED0_EN: + offset = 0xD; + shift = 0; + mask = (1 << shift); + break; + case CPLD_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + break; + case MB_POWER_STAT: + offset = 0x12; + shift = 2; + mask = (1 << shift); + break; + case BIOS2_SPI_WP: + offset = 0x13; + shift = 3; + mask = (1 << shift); + break; + case BIOS1_SPI_WP: + offset = 0x13; + shift = 2; + mask = (1 << shift); + break; + case BIOS_MUX_SEL: + offset = 0x13; + shift = 1; + mask = (1 << shift); + break; + case GBE_SPI_WP: + offset = 0x13; + shift = 0; + mask = (1 << shift); + break; + case PCH_THERMTRIP_EN: + offset = 0x14; + shift = 4; + mask = (1 << shift); + break; + case ID_EEPROM_EN: + offset = 0x14; + shift = 3; + mask = (1 << shift); + break; + case CPU_I2C_MUX_EN: + offset = 0x14; + shift = 2; + mask = (1 << shift); + break; + case CPU_I2C_MUX_SEL: + offset = 0x14; + shift = 0; + mask = 0x3; + break; + case WD_TIMER: + offset = 0x1E; + shift = 3; + mask = 0x38; + break; + case WD_EN: + offset = 0x1E; + shift = 2; + mask = (1 << shift); + break; + case WD_CLEAR_FLAG: + offset = 0x1E; + shift = 0; + mask = (1 << shift); + break; + } + + value = i2c_smbus_read_byte_data(pdata[cpld].client, offset); + data = (value & ~mask) | (data << shift); + i2c_smbus_write_byte_data(pdata[cpld].client, offset, data); + + return count; +} + +static DEVICE_ATTR(cpupld_reg_value, S_IRUGO | S_IWUSR, cpupld_reg_value_show, cpupld_reg_value_store); +static DEVICE_ATTR(cpupld_reg_addr, S_IRUGO | S_IWUSR, cpupld_reg_addr_show, cpupld_reg_addr_store); + +/* offset 0x0 */ +static SENSOR_DEVICE_ATTR(cpu_pcb_num, S_IRUGO, cpupld_data_show, NULL, CPU_PCB_NUM ); +/* offset 0x1 */ +static SENSOR_DEVICE_ATTR(cpupld_ver_type, S_IRUGO, cpupld_data_show, NULL, CPUPLD_VER_TYPE ); +static SENSOR_DEVICE_ATTR(cpupld_ver, S_IRUGO, cpupld_data_show, NULL, CPUPLD_VER ); +#if 0 +/* offset 0x5 */ +static SENSOR_DEVICE_ATTR(p1v2_vddq_en, S_IRUGO, cpupld_data_show, NULL, P1V2_VDDQ_EN ); +static SENSOR_DEVICE_ATTR(p1v5_pch_en, S_IRUGO, cpupld_data_show, NULL, P1V5_PCH_EN ); +static SENSOR_DEVICE_ATTR(p2v5_vpp_en, S_IRUGO, cpupld_data_show, NULL, P2V5_VPP_EN ); +static SENSOR_DEVICE_ATTR(pvccin_en, S_IRUGO, cpupld_data_show, NULL, PVCCIN_EN ); +static SENSOR_DEVICE_ATTR(pvccioin_en, S_IRUGO, cpupld_data_show, NULL, PVCCIOIN_EN ); +static SENSOR_DEVICE_ATTR(pvcckrhv_en, S_IRUGO, cpupld_data_show, NULL, PVCCKRHV_EN ); +static SENSOR_DEVICE_ATTR(pvccscfusesus_en, S_IRUGO, cpupld_data_show, NULL, PVCCSCFUSESUS_EN ); +static SENSOR_DEVICE_ATTR(vr_p3v3_en, S_IRUGO, cpupld_data_show, NULL, VR_P3V3_EN ); +/* offset 0x6 */ +static SENSOR_DEVICE_ATTR(cpu_sys_power, S_IRUGO, cpupld_data_show, NULL, CPU_SYS_POWER ); +static SENSOR_DEVICE_ATTR(p0v6_vtt_dimm_en, S_IRUGO, cpupld_data_show, NULL, P0V6_VTT_DIMM_EN ); +static SENSOR_DEVICE_ATTR(p1v05_pch_en, S_IRUGO, cpupld_data_show, NULL, P1V05_PCH_EN ); +/* offser 0x7 */ +static SENSOR_DEVICE_ATTR(p1v5_pch_pwrgd, S_IRUGO, cpupld_data_show, NULL, P1V5_PCH_GOOD ); +static SENSOR_DEVICE_ATTR(p2v5_vpp_pwrgd, S_IRUGO, cpupld_data_show, NULL, P2V5_VPP_GOOD ); +static SENSOR_DEVICE_ATTR(pch_pwr_pwrgd, S_IRUGO, cpupld_data_show, NULL, PCH_PWR_GOOD ); +static SENSOR_DEVICE_ATTR(pvccin_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCIN_GOOD ); +static SENSOR_DEVICE_ATTR(pvccioin_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCIOIN_GOOD ); +static SENSOR_DEVICE_ATTR(pvcckrhv_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCKRHV_GOOD ); +static SENSOR_DEVICE_ATTR(pvccscfusesus_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCSCFUSESUS_GOOD ); +static SENSOR_DEVICE_ATTR(vr_p3v3_pwrgd, S_IRUGO, cpupld_data_show, NULL, VR_P3V3_GOOD ); +/* offset 0x8 */ +static SENSOR_DEVICE_ATTR(bdxde_lan_pwrgd, S_IRUGO, cpupld_data_show, NULL, BDXDE_LAN_GOOD ); +static SENSOR_DEVICE_ATTR(CPU0_pwrgd, S_IRUGO, cpupld_data_show, NULL, CPU0_GOOD ); +static SENSOR_DEVICE_ATTR(p0v6_vtt_dimm_pwrgd, S_IRUGO, cpupld_data_show, NULL, P0V6_VTT_DIMM_GOOD ); +static SENSOR_DEVICE_ATTR(p1v05_procio_pwrgd, S_IRUGO, cpupld_data_show, NULL, P1V05_PROCIO_GOOD ); +static SENSOR_DEVICE_ATTR(p1v2_vddq_pwrgd, S_IRUGO, cpupld_data_show, NULL, P1V2_VDDQ_GOOD ); +#endif +/* offset 0x9 */ +static SENSOR_DEVICE_ATTR(bdxde_plat_rst, S_IRUGO, cpupld_data_show, NULL, BDXDE_PLAT_RST ); +static SENSOR_DEVICE_ATTR(bdxde_slp3_stat, S_IRUGO, cpupld_data_show, NULL, BDXDE_SLP3_STAT ); +static SENSOR_DEVICE_ATTR(bdxde_slp4_stat, S_IRUGO, cpupld_data_show, NULL, BDXDE_SLP4_STAT ); +static SENSOR_DEVICE_ATTR(bdxde_cpu_rst, S_IRUGO, cpupld_data_show, NULL, BDXDE_CPU_RST ); +static SENSOR_DEVICE_ATTR(cpld_debug_mode, S_IRUGO, cpupld_data_show, NULL, CPLD_DEBUG_MODE ); +/* offset 0xA */ +static SENSOR_DEVICE_ATTR(apwrok_stat, S_IRUGO, cpupld_data_show, NULL, APWROK_STAT ); +//static SENSOR_DEVICE_ATTR(cpu_standby_mode, S_IRUGO, cpupld_data_show, NULL, CPU_STANDBY_MODE ); +/* offset 0xB */ +static SENSOR_DEVICE_ATTR(edge_prochot_sig_dis, S_IRUGO, cpupld_data_show, NULL, EDGE_PROCHOT_SIG_DIS ); +static SENSOR_DEVICE_ATTR(psu_thermal_stat, S_IRUGO, cpupld_data_show, NULL, PSU_THERMAL_STAT ); +static SENSOR_DEVICE_ATTR(pr_thermal_stat, S_IRUGO, cpupld_data_show, NULL, PR_THERMAL_STAT ); +static SENSOR_DEVICE_ATTR(me_drv_sig_en, S_IRUGO, cpupld_data_show, NULL, ME_DRIVE_SIG_EN ); +static SENSOR_DEVICE_ATTR(cpu_thermal_stat, S_IRUGO, cpupld_data_show, NULL, CPU_THERMAL_STAT ); +static SENSOR_DEVICE_ATTR(ddr_thermal_stat, S_IRUGO, cpupld_data_show, NULL, DDR_THERMAL_STAT ); +/* offset 0xC */ +static SENSOR_DEVICE_ATTR(sys_thermal_stat, S_IRUGO, cpupld_data_show, NULL, SYS_THERMAL_STAT ); +/* offset 0xD */ +static SENSOR_DEVICE_ATTR(debug_led3_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED3_EN ); +static SENSOR_DEVICE_ATTR(debug_led2_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED2_EN ); +static SENSOR_DEVICE_ATTR(debug_led1_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED1_EN ); +static SENSOR_DEVICE_ATTR(debug_led0_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED0_EN ); +/* offset 0x11 */ +static SENSOR_DEVICE_ATTR(cpu_standby_mode, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPU_STANDBY_MODE ); +static SENSOR_DEVICE_ATTR(cpld_rst, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPLD_RST ); +/* offset 0x12 */ +static SENSOR_DEVICE_ATTR(mb_power_stat, S_IRUGO, cpupld_data_show, NULL, MB_POWER_STAT ); +/* offset 0x13 */ +static SENSOR_DEVICE_ATTR(bios1_spi_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, BIOS1_SPI_WP ); +static SENSOR_DEVICE_ATTR(bios2_spi_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, BIOS2_SPI_WP ); +static SENSOR_DEVICE_ATTR(bios_mux_sel, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, BIOS_MUX_SEL ); +static SENSOR_DEVICE_ATTR(gbe_spi_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, GBE_SPI_WP ); +/* offset 0x14 */ +static SENSOR_DEVICE_ATTR(pch_thermtrip_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, PCH_THERMTRIP_EN ); +static SENSOR_DEVICE_ATTR(id_eeprom_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, ID_EEPROM_EN ); +static SENSOR_DEVICE_ATTR(cpu_i2c_mux_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPU_I2C_MUX_EN ); +static SENSOR_DEVICE_ATTR(cpu_i2c_mux_sel, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPU_I2C_MUX_SEL ); +/* offset 0x15 */ +static SENSOR_DEVICE_ATTR(psu_fan_intr, S_IRUGO, cpupld_data_show, NULL, PSU_FAN_INTR ); +/* offset 0x1E */ +static SENSOR_DEVICE_ATTR(wd_timer, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, WD_TIMER ); +static SENSOR_DEVICE_ATTR(wd_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, WD_EN ); +static SENSOR_DEVICE_ATTR(wd_clear_flag, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, WD_CLEAR_FLAG ); + + +static struct attribute *agc032_cpupld_attrs[] = { + &dev_attr_cpupld_reg_value.attr, + &dev_attr_cpupld_reg_addr.attr, + &sensor_dev_attr_cpu_pcb_num.dev_attr.attr, + &sensor_dev_attr_cpupld_ver_type.dev_attr.attr, + &sensor_dev_attr_cpupld_ver.dev_attr.attr, + &sensor_dev_attr_bdxde_plat_rst.dev_attr.attr, + &sensor_dev_attr_bdxde_slp3_stat.dev_attr.attr, + &sensor_dev_attr_bdxde_slp4_stat.dev_attr.attr, + &sensor_dev_attr_bdxde_cpu_rst.dev_attr.attr, + &sensor_dev_attr_cpld_debug_mode.dev_attr.attr, + &sensor_dev_attr_apwrok_stat.dev_attr.attr, + &sensor_dev_attr_edge_prochot_sig_dis.dev_attr.attr, + &sensor_dev_attr_psu_thermal_stat.dev_attr.attr, + &sensor_dev_attr_pr_thermal_stat.dev_attr.attr, + &sensor_dev_attr_me_drv_sig_en.dev_attr.attr, + &sensor_dev_attr_cpu_thermal_stat.dev_attr.attr, + &sensor_dev_attr_ddr_thermal_stat.dev_attr.attr, + &sensor_dev_attr_sys_thermal_stat.dev_attr.attr, + &sensor_dev_attr_debug_led3_en.dev_attr.attr, + &sensor_dev_attr_debug_led2_en.dev_attr.attr, + &sensor_dev_attr_debug_led1_en.dev_attr.attr, + &sensor_dev_attr_debug_led0_en.dev_attr.attr, + &sensor_dev_attr_cpu_standby_mode.dev_attr.attr, + &sensor_dev_attr_cpld_rst.dev_attr.attr, + &sensor_dev_attr_mb_power_stat.dev_attr.attr, + &sensor_dev_attr_bios1_spi_wp.dev_attr.attr, + &sensor_dev_attr_bios2_spi_wp.dev_attr.attr, + &sensor_dev_attr_bios_mux_sel.dev_attr.attr, + &sensor_dev_attr_gbe_spi_wp.dev_attr.attr, + &sensor_dev_attr_pch_thermtrip_en.dev_attr.attr, + &sensor_dev_attr_id_eeprom_wp.dev_attr.attr, + &sensor_dev_attr_cpu_i2c_mux_en.dev_attr.attr, + &sensor_dev_attr_cpu_i2c_mux_sel.dev_attr.attr, + &sensor_dev_attr_psu_fan_intr.dev_attr.attr, + &sensor_dev_attr_wd_timer.dev_attr.attr, + &sensor_dev_attr_wd_en.dev_attr.attr, + &sensor_dev_attr_wd_clear_flag.dev_attr.attr, + NULL, +}; + +static struct attribute_group agc032_cpupld_attr_group = { + .attrs = agc032_cpupld_attrs, +}; + +static int __init cpupld_probe(struct platform_device *pdev) +{ + struct platform_data *pdata; + struct i2c_adapter *parent; + int rv; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPUPLD platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(BUS0); + if (!parent) { + printk(KERN_ERR "Parent adapter (%d) not found\n",BUS0); + return -ENODEV; + } + + pdata[cpld].client = i2c_new_dummy(parent, pdata[cpld].reg_addr); + if (!pdata[cpld].client) { + printk(KERN_ERR "Fail to create dummy i2c client for addr %d\n", pdata[cpld].reg_addr); + goto error; + } +#if 0 + /* set default cpu_i2c_mux 0x14 be 0x1 */ + rv = i2c_smbus_write_byte_data(pdata[cpld].client, 0x14, 0x1); + if (rv < 0) { + printk(KERN_WARNING, "Error: Failed to set addr 0x14.\n"); + goto error; + } +#endif + /* /sys/device/platform */ + rv = sysfs_create_group(&pdev->dev.kobj, &agc032_cpupld_attr_group); + if (rv){ + printk(KERN_ERR "Fail to create cpupld attribute group"); + goto error; + } + return 0; + +error: + i2c_unregister_device(pdata[cpld].client); + i2c_put_adapter(parent); + return -ENODEV; +} + + +static int __exit cpupld_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &agc032_cpupld_attr_group); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[cpld].client) { + if (!parent) { + parent = (pdata[cpld].client)->adapter; + } + i2c_unregister_device(pdata[cpld].client); + } + } + i2c_put_adapter(parent); + return 0; +} + + +static struct platform_driver cpupld_driver = { + .probe = cpupld_probe, + .remove = __exit_p(cpupld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-cpupld", + }, +}; + + +static struct platform_data agc032_cpupld_platform_data[] = { + [cpld] = { + .reg_addr = CPUPLD_I2C_ADDR, + }, +}; + +static void device_release(struct device *dev) +{ + return; +} + +static struct platform_device cpupld_agc032 = { + .name = "delta-agc032-cpupld", + .id = 0, + .dev = { + .platform_data = agc032_cpupld_platform_data, + .release = device_release + }, +}; + +/* module initialization */ +static int __init delta_agc032_cpupld_init(void) +{ + int rc = 0; + printk(KERN_INFO "CPUPLD module initializating\n"); + + /* register CPUPLD driver */ + rc = platform_driver_register(&cpupld_driver); + if (rc < 0) { + printk(KERN_ERR "Fail to register CPUPLD driver, rc = %d\n", rc); + goto error_register_driver; + } + + /* register CPUPLD device */ + rc = platform_device_register(&cpupld_agc032); + if (rc) { + printk(KERN_ERR "Fail to create cpupld device, rc = %d\n", rc); + goto error_register_device; + } + return 0; + +error_register_device: + platform_driver_unregister(&cpupld_driver); +error_register_driver: + return rc; +} + +static void __exit delta_agc032_cpupld_exit(void) +{ + platform_device_unregister(&cpupld_agc032); + platform_driver_unregister(&cpupld_driver); +} + +module_init(delta_agc032_cpupld_init); +module_exit(delta_agc032_cpupld_exit); + +MODULE_DESCRIPTION("DNI agc032 CPLD Platform Support"); +MODULE_AUTHOR("James Ke "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_platform.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_platform.c new file mode 100644 index 000000000000..121ccc4d8b2d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_platform.c @@ -0,0 +1,299 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define agc032_i2c_device_num(c){ \ + .name = "delta-agc032-i2c-device", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_platform_data[c], \ + .release = device_release, \ + }, \ +} + + + +/* Define struct to get client of i2c_new_deivce at 0x70 */ +struct i2c_client * i2c_client_9548; + +enum{ + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, + BUS8, +}; + +struct i2c_device_platform_data { + int parent; + struct i2c_board_info info; + struct i2c_client *client; +}; + +/* pca9548 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode[] = { + { .adap_id = 1, + .deselect_on_exit = 1, + }, + { .adap_id = 2, + .deselect_on_exit = 1, + }, + { .adap_id = 3, + .deselect_on_exit = 1, + }, + { .adap_id = 4, + .deselect_on_exit = 1, + }, + { .adap_id = 5, + .deselect_on_exit = 1, + }, + { .adap_id = 6, + .deselect_on_exit = 1, + }, + { .adap_id = 7, + .deselect_on_exit = 1, + }, + { .adap_id = 8, + .deselect_on_exit = 1, + }, +}; + +static struct pca954x_platform_data pca954x_data = { + .modes = pca954x_mode, + .num_modes = ARRAY_SIZE(pca954x_mode), +}; + +static struct i2c_board_info __initdata i2c_info_pca9548[] = +{ + { + I2C_BOARD_INFO("pca9548", 0x70), + .platform_data = &pca954x_data, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_platform_data[] = { + { + /* psu 1 (0x58) */ + .parent = 1, + .info = { .type = "dni_agc032_psu", .addr = 0x58, .platform_data = (void *) 0 }, + .client = NULL, + }, + { + /* psu 2 (0x58) */ + .parent = 2, + .info = { .type = "dni_agc032_psu", .addr = 0x58, .platform_data = (void *) 1 }, + .client = NULL, + }, + { + /* FAN 1 Controller (0x2e) */ + .parent = 4, + .info = { I2C_BOARD_INFO("emc2302", 0x2e) }, + .client = NULL, + }, + { + /* FAN 2 Controller (0x4c) */ + .parent = 4, + .info = { I2C_BOARD_INFO("emc2305", 0x4c) }, + .client = NULL, + }, + { + /* FAN 3 Controller (0x2d) */ + .parent = 4, + .info = { I2C_BOARD_INFO("emc2305", 0x2d) }, + .client = NULL, + }, + { + /* tmp75 (0x4f) */ + .parent = 4, + .info = { I2C_BOARD_INFO("tmp75", 0x4f) }, + .client = NULL, + }, + { + /* tmp75 (0x49) */ + .parent = 5, + .info = { I2C_BOARD_INFO("tmp75", 0x49) }, + .client = NULL, + }, + { + /* tmp75 (0x4a) */ + .parent = 5, + .info = { I2C_BOARD_INFO("tmp75", 0x4a) }, + .client = NULL, + }, + { + /* tmp75 (0x4b) */ + .parent = 5, + .info = { I2C_BOARD_INFO("tmp75", 0x4b) }, + .client = NULL, + }, + { + /* tmp75 (0x4d) */ + .parent = 5, + .info = { I2C_BOARD_INFO("tmp75", 0x4d) }, + .client = NULL, + }, + { + /* tmp75 (0x4e) */ + .parent = 5, + .info = { I2C_BOARD_INFO("tmp75", 0x4e) }, + .client = NULL, + }, +}; + +static void device_release(struct device *dev) +{ + return; +} + +static struct platform_device agc032_i2c_device[] = { + agc032_i2c_device_num(0), + agc032_i2c_device_num(1), + agc032_i2c_device_num(2), + agc032_i2c_device_num(3), + agc032_i2c_device_num(4), + agc032_i2c_device_num(5), + agc032_i2c_device_num(6), + agc032_i2c_device_num(7), + agc032_i2c_device_num(8), + agc032_i2c_device_num(9), + agc032_i2c_device_num(10), +}; + +static int __init i2c_device_probe(struct platform_device *pdev) +{ + struct i2c_device_platform_data *pdata; + struct i2c_adapter *parent; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", + pdata->parent); + return -ENODEV; + } + + pdata->client = i2c_new_device(parent, &pdata->info); + if (!pdata->client) { + dev_err(&pdev->dev, "Failed to create i2c client %s at %d\n", + pdata->info.type, pdata->parent); + return -ENODEV; + } + + return 0; +} + +static int __exit i2c_deivce_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent; + struct i2c_device_platform_data *pdata; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + if (pdata->client) { + parent = (pdata->client)->adapter; + i2c_unregister_device(pdata->client); + i2c_put_adapter(parent); + } + + return 0; +} + + +static struct platform_driver i2c_device_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-device", + } +}; + +static int __init delta_agc032_platform_init(void) +{ + struct i2c_adapter *adapter; + struct cpld_platform_data *cpld_pdata; + int ret = 0; + int cnt = 0; + + printk("agc032_platform module initialization\n"); + + adapter = i2c_get_adapter(BUS0); +// i2c_client_9548 = i2c_new_device(adapter, &i2c_info_pca9548[0]); + + i2c_put_adapter(adapter); + + /* register the i2c devices */ + ret = platform_driver_register(&i2c_device_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_driver; + } + + for (cnt = 0; cnt < ARRAY_SIZE(agc032_i2c_device); cnt++) + { + ret = platform_device_register(&agc032_i2c_device[cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", cnt); + goto error_agc032_i2c_device; + } + } + + return 0; + +error_agc032_i2c_device: + for (; cnt >= 0; cnt--) { + platform_device_unregister(&agc032_i2c_device[cnt]); + } + platform_driver_unregister(&i2c_device_driver); +error_i2c_device_driver: + return ret; +} + +static void __exit delta_agc032_platform_exit(void) +{ + int i = 0; + + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device); i++ ) { + platform_device_unregister(&agc032_i2c_device[i]); + } + + platform_driver_unregister(&i2c_device_driver); +// i2c_unregister_device(i2c_client_9548); +} + + +module_init(delta_agc032_platform_init); +module_exit(delta_agc032_platform_exit); + +MODULE_DESCRIPTION("DNI agc032 Platform Support"); +MODULE_AUTHOR("James Ke "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_qsfp.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_qsfp.c new file mode 100644 index 000000000000..df58430b6aa6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_qsfp.c @@ -0,0 +1,819 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define agc032_i2c_device1_num(c){ \ + .name = "delta-agc032-i2c-pca9548-1", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_pca9548_1_data[c], \ + .release = device_release, \ + }, \ +} + +#define agc032_i2c_device2_num(c){ \ + .name = "delta-agc032-i2c-pca9548-2", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_pca9548_2_data[c], \ + .release = device_release, \ + }, \ +} + +#define agc032_i2c_device3_num(c){ \ + .name = "delta-agc032-i2c-pca9548-3", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_pca9548_3_data[c], \ + .release = device_release, \ + }, \ +} + +#define agc032_i2c_device4_num(c){ \ + .name = "delta-agc032-i2c-pca9548-4", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_pca9548_4_data[c], \ + .release = device_release, \ + }, \ +} + +#define agc032_i2c_device5_num(c){ \ + .name = "delta-agc032-i2c-pca9548-5", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_pca9548_5_data[c], \ + .release = device_release, \ + }, \ +} + +/* Define struct to get client of i2c_new_deivce at 0x70, 0x71, 0x72, 0x73 */ +struct i2c_client * i2c_client_9548_1; +struct i2c_client * i2c_client_9548_2; +struct i2c_client * i2c_client_9548_3; +struct i2c_client * i2c_client_9548_4; +struct i2c_client * i2c_client_9548_5; + +enum{ + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, + BUS8, +}; + +struct i2c_device_platform_data { + int parent; + struct i2c_board_info info; + struct i2c_client *client; +}; + +/* pca9548-1 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode[] = { + { .adap_id = 1, + .deselect_on_exit = 1, + }, + { .adap_id = 2, + .deselect_on_exit = 1, + }, + { .adap_id = 3, + .deselect_on_exit = 1, + }, + { .adap_id = 4, + .deselect_on_exit = 1, + }, + { .adap_id = 5, + .deselect_on_exit = 1, + }, + { .adap_id = 6, + .deselect_on_exit = 1, + }, + { .adap_id = 7, + .deselect_on_exit = 1, + }, + { .adap_id = 8, + .deselect_on_exit = 1, + }, +}; + +/* pca9548-2 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode2[] = { + { .adap_id = 9, + .deselect_on_exit = 1, + }, + { .adap_id = 10, + .deselect_on_exit = 1, + }, + { .adap_id = 11, + .deselect_on_exit = 1, + }, + { .adap_id = 12, + .deselect_on_exit = 1, + }, + { .adap_id = 13, + .deselect_on_exit = 1, + }, + { .adap_id = 14, + .deselect_on_exit = 1, + }, + { .adap_id = 15, + .deselect_on_exit = 1, + }, + { .adap_id = 16, + .deselect_on_exit = 1, + }, +}; + +/* pca9548-3 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode3[] = { + { .adap_id = 17, + .deselect_on_exit = 1, + }, + { .adap_id = 18, + .deselect_on_exit = 1, + }, + { .adap_id = 19, + .deselect_on_exit = 1, + }, + { .adap_id = 20, + .deselect_on_exit = 1, + }, + { .adap_id = 21, + .deselect_on_exit = 1, + }, + { .adap_id = 22, + .deselect_on_exit = 1, + }, + { .adap_id = 23, + .deselect_on_exit = 1, + }, + { .adap_id = 24, + .deselect_on_exit = 1, + }, +}; + +/* pca9548-4 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode4[] = { + { .adap_id = 25, + .deselect_on_exit = 1, + }, + { .adap_id = 26, + .deselect_on_exit = 1, + }, + { .adap_id = 27, + .deselect_on_exit = 1, + }, + { .adap_id = 28, + .deselect_on_exit = 1, + }, + { .adap_id = 29, + .deselect_on_exit = 1, + }, + { .adap_id = 30, + .deselect_on_exit = 1, + }, + { .adap_id = 31, + .deselect_on_exit = 1, + }, + { .adap_id = 32, + .deselect_on_exit = 1, + }, +}; + +/* pca9548-5 - add 2 bus */ +static struct pca954x_platform_mode pca954x_mode5[] = { + { .adap_id = 33, + .deselect_on_exit = 1, + }, + { .adap_id = 34, + .deselect_on_exit = 1, + }, +}; + +static struct pca954x_platform_data pca954x_data = { + .modes = pca954x_mode, + .num_modes = ARRAY_SIZE(pca954x_mode), +}; + +static struct pca954x_platform_data pca954x_data2 = { + .modes = pca954x_mode2, + .num_modes = ARRAY_SIZE(pca954x_mode2), +}; + +static struct pca954x_platform_data pca954x_data3 = { + .modes = pca954x_mode3, + .num_modes = ARRAY_SIZE(pca954x_mode3), +}; + +static struct pca954x_platform_data pca954x_data4 = { + .modes = pca954x_mode4, + .num_modes = ARRAY_SIZE(pca954x_mode4), +}; + +static struct pca954x_platform_data pca954x_data5 = { + .modes = pca954x_mode5, + .num_modes = ARRAY_SIZE(pca954x_mode5), +}; + +static struct i2c_board_info __initdata i2c_info_pca9548[] = +{ + { + I2C_BOARD_INFO("pca9548", 0x70), + .platform_data = &pca954x_data, + }, + { + I2C_BOARD_INFO("pca9548", 0x71), + .platform_data = &pca954x_data2, + }, + { + I2C_BOARD_INFO("pca9548", 0x72), + .platform_data = &pca954x_data3, + }, + { + I2C_BOARD_INFO("pca9548", 0x73), + .platform_data = &pca954x_data4, + }, + { + I2C_BOARD_INFO("pca9548", 0x74), + .platform_data = &pca954x_data5, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_pca9548_1_data[] = { + { + // qsfp 1 (0x50) + .parent = 1, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 2 (0x50) + .parent = 2, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 3 (0x50) + .parent = 3, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 4 (0x50) + .parent = 4, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 5 (0x50) + .parent = 5, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 6 (0x50) + .parent = 6, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 7 (0x50) + .parent = 7, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 8 (0x50) + .parent = 8, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_pca9548_2_data[] = { + { + // qsfp 9 (0x50) + .parent = 9, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 10 (0x50) + .parent = 10, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 11 (0x50) + .parent = 11, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 12 (0x50) + .parent = 12, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 13 (0x50) + .parent = 13, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 14 (0x50) + .parent = 14, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 15 (0x50) + .parent = 15, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 16 (0x50) + .parent = 16, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_pca9548_3_data[] = { + { + // qsfp 17 (0x50) + .parent = 17, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 18 (0x50) + .parent = 18, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 19 (0x50) + .parent = 19, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 20 (0x50) + .parent = 20, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 21 (0x50) + .parent = 21, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 22 (0x50) + .parent = 22, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 23 (0x50) + .parent = 23, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 24 (0x50) + .parent = 24, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_pca9548_4_data[] = { + { + // qsfp 25 (0x50) + .parent = 25, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 26 (0x50) + .parent = 26, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 27 (0x50) + .parent = 27, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 28 (0x50) + .parent = 28, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 29 (0x50) + .parent = 29, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 30 (0x50) + .parent = 30, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 31 (0x50) + .parent = 31, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 32 (0x50) + .parent = 32, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_pca9548_5_data[] = { + { + // qsfp 33 (0x50) + .parent = 33, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 34 (0x50) + .parent = 34, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, +}; + +static void device_release(struct device *dev) +{ + return; +} + +static struct platform_device agc032_i2c_device1[] = { + agc032_i2c_device1_num(0), + agc032_i2c_device1_num(1), + agc032_i2c_device1_num(2), + agc032_i2c_device1_num(3), + agc032_i2c_device1_num(4), + agc032_i2c_device1_num(5), + agc032_i2c_device1_num(6), + agc032_i2c_device1_num(7), +}; + +static struct platform_device agc032_i2c_device2[] = { + agc032_i2c_device2_num(0), + agc032_i2c_device2_num(1), + agc032_i2c_device2_num(2), + agc032_i2c_device2_num(3), + agc032_i2c_device2_num(4), + agc032_i2c_device2_num(5), + agc032_i2c_device2_num(6), + agc032_i2c_device2_num(7), +}; + +static struct platform_device agc032_i2c_device3[] = { + agc032_i2c_device3_num(0), + agc032_i2c_device3_num(1), + agc032_i2c_device3_num(2), + agc032_i2c_device3_num(3), + agc032_i2c_device3_num(4), + agc032_i2c_device3_num(5), + agc032_i2c_device3_num(6), + agc032_i2c_device3_num(7), +}; + +static struct platform_device agc032_i2c_device4[] = { + agc032_i2c_device4_num(0), + agc032_i2c_device4_num(1), + agc032_i2c_device4_num(2), + agc032_i2c_device4_num(3), + agc032_i2c_device4_num(4), + agc032_i2c_device4_num(5), + agc032_i2c_device4_num(6), + agc032_i2c_device4_num(7), +}; + +static struct platform_device agc032_i2c_device5[] = { + agc032_i2c_device5_num(0), + agc032_i2c_device5_num(1), +}; + + +static int __init i2c_device_probe(struct platform_device *pdev) +{ + struct i2c_device_platform_data *pdata; + struct i2c_adapter *parent; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", + pdata->parent); + return -ENODEV; + } + + pdata->client = i2c_new_device(parent, &pdata->info); + if (!pdata->client) { + dev_err(&pdev->dev, "Failed to create i2c client %s at %d\n", + pdata->info.type, pdata->parent); + return -ENODEV; + } + + return 0; +} + +static int __exit i2c_deivce_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent; + struct i2c_device_platform_data *pdata; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + if (pdata->client) { + parent = (pdata->client)->adapter; + i2c_unregister_device(pdata->client); + i2c_put_adapter(parent); + } + + return 0; +} + + +static struct platform_driver i2c_device_pca9548_1_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-pca9548-1", + } +}; + +static struct platform_driver i2c_device_pca9548_2_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-pca9548-2", + } +}; + +static struct platform_driver i2c_device_pca9548_3_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-pca9548-3", + } +}; + +static struct platform_driver i2c_device_pca9548_4_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-pca9548-4", + } +}; + +static struct platform_driver i2c_device_pca9548_5_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-pca9548-5", + } +}; + +static int __init delta_agc032_platform_init(void) +{ + struct i2c_adapter *adapter; + int ret = 0; + int device1_cnt = 0; + int device2_cnt = 0; + int device3_cnt = 0; + int device4_cnt = 0; + int device5_cnt = 0; + + printk("agc032_qsfp module initialization\n"); + + adapter = i2c_get_adapter(BUS0); + i2c_client_9548_1 = i2c_new_device(adapter, &i2c_info_pca9548[0]); + i2c_client_9548_2 = i2c_new_device(adapter, &i2c_info_pca9548[1]); + i2c_client_9548_3 = i2c_new_device(adapter, &i2c_info_pca9548[2]); + i2c_client_9548_4 = i2c_new_device(adapter, &i2c_info_pca9548[3]); + i2c_client_9548_5 = i2c_new_device(adapter, &i2c_info_pca9548[4]); + i2c_put_adapter(adapter); + + /* pca9548-0x70 */ + ret = platform_driver_register(&i2c_device_pca9548_1_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_pca9548_1_driver; + } + + for (device1_cnt = 0; device1_cnt < ARRAY_SIZE(agc032_i2c_device1); device1_cnt++) + { + ret = platform_device_register(&agc032_i2c_device1[device1_cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", device1_cnt); + goto error_agc032_i2c_device; + } + } + + + /* pca9548-0x71 */ + ret = platform_driver_register(&i2c_device_pca9548_2_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_pca9548_2_driver; + } + + for (device2_cnt = 0; device2_cnt < ARRAY_SIZE(agc032_i2c_device2); device2_cnt++) + { + ret = platform_device_register(&agc032_i2c_device2[device2_cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", device2_cnt); + goto error_agc032_i2c_device2; + } + } + + /* pca9548-0x72 */ + ret = platform_driver_register(&i2c_device_pca9548_3_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_pca9548_3_driver; + } + + for (device3_cnt = 0; device3_cnt < ARRAY_SIZE(agc032_i2c_device3); device3_cnt++) + { + ret = platform_device_register(&agc032_i2c_device3[device3_cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", device3_cnt); + goto error_agc032_i2c_device3; + } + } + + /* pca9548-0x73 */ + ret = platform_driver_register(&i2c_device_pca9548_4_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_pca9548_4_driver; + } + + for (device4_cnt = 0; device4_cnt < ARRAY_SIZE(agc032_i2c_device4); device4_cnt++) + { + ret = platform_device_register(&agc032_i2c_device4[device4_cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", device4_cnt); + goto error_agc032_i2c_device4; + } + } + + /* pca9548-0x74 */ + ret = platform_driver_register(&i2c_device_pca9548_5_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_pca9548_5_driver; + } + + for (device5_cnt = 0; device5_cnt < ARRAY_SIZE(agc032_i2c_device5); device5_cnt++) + { + ret = platform_device_register(&agc032_i2c_device5[device5_cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", device5_cnt); + goto error_agc032_i2c_device5; + } + } + + + return 0; + +/* Error handling */ +error_agc032_i2c_device5: + for (; device5_cnt >= 0; device5_cnt--) { + platform_device_unregister(&agc032_i2c_device5[device5_cnt]); + } + platform_driver_unregister(&i2c_device_pca9548_5_driver); +error_i2c_device_pca9548_5_driver: +error_agc032_i2c_device4: + for (; device4_cnt >= 0; device4_cnt--) { + platform_device_unregister(&agc032_i2c_device4[device4_cnt]); + } + platform_driver_unregister(&i2c_device_pca9548_4_driver); +error_i2c_device_pca9548_4_driver: +error_agc032_i2c_device3: + for (; device3_cnt >= 0; device3_cnt--) { + platform_device_unregister(&agc032_i2c_device3[device3_cnt]); + } + platform_driver_unregister(&i2c_device_pca9548_3_driver); +error_i2c_device_pca9548_3_driver: +error_agc032_i2c_device2: + for (; device2_cnt >= 0; device2_cnt--) { + platform_device_unregister(&agc032_i2c_device2[device2_cnt]); + } + platform_driver_unregister(&i2c_device_pca9548_2_driver); +error_i2c_device_pca9548_2_driver: +error_agc032_i2c_device: + for (; device1_cnt >= 0; device1_cnt--) { + platform_device_unregister(&agc032_i2c_device1[device1_cnt]); + } + platform_driver_unregister(&i2c_device_pca9548_1_driver); +error_i2c_device_pca9548_1_driver: + return ret; +} + +static void __exit delta_agc032_platform_exit(void) +{ + int i = 0; + + // unregister pca9548-1 (0x70) + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device1); i++ ) { + platform_device_unregister(&agc032_i2c_device1[i]); + } + + platform_driver_unregister(&i2c_device_pca9548_1_driver); + i2c_unregister_device(i2c_client_9548_1); + + // unregister pca9548-2 (0x71) + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device2); i++ ) { + platform_device_unregister(&agc032_i2c_device2[i]); + } + + platform_driver_unregister(&i2c_device_pca9548_2_driver); + i2c_unregister_device(i2c_client_9548_2); + + // unregister pca9548-3 (0x72) + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device3); i++ ) { + platform_device_unregister(&agc032_i2c_device3[i]); + } + + platform_driver_unregister(&i2c_device_pca9548_3_driver); + i2c_unregister_device(i2c_client_9548_3); + + // unregister pca9548-4 (0x73) + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device4); i++ ) { + platform_device_unregister(&agc032_i2c_device4[i]); + } + + platform_driver_unregister(&i2c_device_pca9548_4_driver); + i2c_unregister_device(i2c_client_9548_4); + + // unregister pca9548-5 (0x74) + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device5); i++ ) { + platform_device_unregister(&agc032_i2c_device5[i]); + } + + platform_driver_unregister(&i2c_device_pca9548_5_driver); + i2c_unregister_device(i2c_client_9548_5); +} + + +module_init(delta_agc032_platform_init); +module_exit(delta_agc032_platform_exit); + +MODULE_DESCRIPTION("Delta agc032 QSFP-DD eeprom Support"); +MODULE_AUTHOR("Zoe Kuan "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_swpld.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_swpld.c new file mode 100644 index 000000000000..2396dfff8b48 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_swpld.c @@ -0,0 +1,2841 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define SWPLD1_ADDR 0x32 +#define SWPLD2_ADDR 0x34 +#define SWPLD3_ADDR 0x35 + + + +enum cpld_type { + swpld1 = 0, + swpld2, + swpld3, +}; + +enum { + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, + BUS8, +}; + +enum swpld1_attr{ + BOARD_ID = 0, + BOARD_VER, + SWPLD1_VER_TYPE, + SWPLD1_VER, + USB_HUB_RST, + SYNCE_RST, + BMC_RST, + LPC_RST, + OOB_PCIE_RST, + MAC_PCIE_RST, + MAC_RST, + VR_3V3_RST, + VR_0V8_RST, + FAN_MUX_RST, + QSFP5_MUX_RST, + QSFP4_MUX_RST, + QSFP3_MUX_RST, + QSFP2_MUX_RST, + QSFP1_MUX_RST, + PSU1_PRESENT, + PSU1_STATE, + PSU1_ALERT, + PSU2_PRESENT, + PSU2_STATE, + PSU2_ALERT, + PSU1_EN, + PSU1_EEPROM_WP, + PSU2_EN, + PSU2_EEPROM_WP, + VCC_5V_EN, + VCC_3V3_EN, + VCC_VCORE_EN, + VCC_MAC_1V8_EN, + VCC_MAC_1V2_EN, + VCC_MAC_0V8_EN, + VCC_PLL_0V8_EN, + VCC_SYS_EN, + OOB_PWR_STATE, + OOB_OP_EN, + USB1_OP_EN, + PSU_INTR, + FAN_ALERT, + SWPLD2_INTR, + SWPLD3_INTR, + PSU1_LED, + PSU2_LED, + SYS_LED, + FAN_LED, + FAN1_LED, + FAN2_LED, + FAN3_LED, + FAN4_LED, + FAN5_LED, + FAN6_LED, + SYNCE_EEPROM_WB, + CONSOLE_SEL, + SYS_EEPROM_WB, +}; + +/* SWPLD2 */ +enum swpld2_attr{ + SWPLD2_VER_TYPE = 0, + SWPLD2_VER, + QSFP_P01_RST, + QSFP_P02_RST, + QSFP_P03_RST, + QSFP_P04_RST, + QSFP_P05_RST, + QSFP_P06_RST, + QSFP_P07_RST, + QSFP_P08_RST, + QSFP_P09_RST, + QSFP_P10_RST, + QSFP_P11_RST, + QSFP_P12_RST, + QSFP_P13_RST, + QSFP_P14_RST, + QSFP_P15_RST, + QSFP_P16_RST, + QSFP_P01_LPMODE, + QSFP_P02_LPMODE, + QSFP_P03_LPMODE, + QSFP_P04_LPMODE, + QSFP_P05_LPMODE, + QSFP_P06_LPMODE, + QSFP_P07_LPMODE, + QSFP_P08_LPMODE, + QSFP_P09_LPMODE, + QSFP_P10_LPMODE, + QSFP_P11_LPMODE, + QSFP_P12_LPMODE, + QSFP_P13_LPMODE, + QSFP_P14_LPMODE, + QSFP_P15_LPMODE, + QSFP_P16_LPMODE, + QSFP_P01_MODPRS, + QSFP_P02_MODPRS, + QSFP_P03_MODPRS, + QSFP_P04_MODPRS, + QSFP_P05_MODPRS, + QSFP_P06_MODPRS, + QSFP_P07_MODPRS, + QSFP_P08_MODPRS, + QSFP_P09_MODPRS, + QSFP_P10_MODPRS, + QSFP_P11_MODPRS, + QSFP_P12_MODPRS, + QSFP_P13_MODPRS, + QSFP_P14_MODPRS, + QSFP_P15_MODPRS, + QSFP_P16_MODPRS, + QSFP_P01_INTR, + QSFP_P02_INTR, + QSFP_P03_INTR, + QSFP_P04_INTR, + QSFP_P05_INTR, + QSFP_P06_INTR, + QSFP_P07_INTR, + QSFP_P08_INTR, + QSFP_P09_INTR, + QSFP_P10_INTR, + QSFP_P11_INTR, + QSFP_P12_INTR, + QSFP_P13_INTR, + QSFP_P14_INTR, + QSFP_P15_INTR, + QSFP_P16_INTR, +}; + +/* SWPLD3 */ +enum swpld3_attr{ + SWPLD3_VER_TYPE = 160, + SWPLD3_VER, + QSFP_P17_RST, + QSFP_P18_RST, + QSFP_P19_RST, + QSFP_P20_RST, + QSFP_P21_RST, + QSFP_P22_RST, + QSFP_P23_RST, + QSFP_P24_RST, + QSFP_P25_RST, + QSFP_P26_RST, + QSFP_P27_RST, + QSFP_P28_RST, + QSFP_P29_RST, + QSFP_P30_RST, + QSFP_P31_RST, + QSFP_P32_RST, + QSFP_P17_LPMODE, + QSFP_P18_LPMODE, + QSFP_P19_LPMODE, + QSFP_P20_LPMODE, + QSFP_P21_LPMODE, + QSFP_P22_LPMODE, + QSFP_P23_LPMODE, + QSFP_P24_LPMODE, + QSFP_P25_LPMODE, + QSFP_P26_LPMODE, + QSFP_P27_LPMODE, + QSFP_P28_LPMODE, + QSFP_P29_LPMODE, + QSFP_P30_LPMODE, + QSFP_P31_LPMODE, + QSFP_P32_LPMODE, + QSFP_P17_MODPRS, + QSFP_P18_MODPRS, + QSFP_P19_MODPRS, + QSFP_P20_MODPRS, + QSFP_P21_MODPRS, + QSFP_P22_MODPRS, + QSFP_P23_MODPRS, + QSFP_P24_MODPRS, + QSFP_P25_MODPRS, + QSFP_P26_MODPRS, + QSFP_P27_MODPRS, + QSFP_P28_MODPRS, + QSFP_P29_MODPRS, + QSFP_P30_MODPRS, + QSFP_P31_MODPRS, + QSFP_P32_MODPRS, + QSFP_P17_INTR, + QSFP_P18_INTR, + QSFP_P19_INTR, + QSFP_P20_INTR, + QSFP_P21_INTR, + QSFP_P22_INTR, + QSFP_P23_INTR, + QSFP_P24_INTR, + QSFP_P25_INTR, + QSFP_P26_INTR, + QSFP_P27_INTR, + QSFP_P28_INTR, + QSFP_P29_INTR, + QSFP_P30_INTR, + QSFP_P31_INTR, + QSFP_P32_INTR, + SFP_P0_MODPRS, + SFP_P0_RXLOS, + SFP_P0_TXFAULT, + SFP_P1_MODPRS, + SFP_P1_RXLOS, + SFP_P1_TXFAULT, + SFP_P0_TXDIS, + SFP_P1_TXDIS, +}; + + +struct platform_data { + int reg_addr; + struct i2c_client *client; +}; + +struct cpld_platform_data { + int reg_addr; + struct i2c_client *client; +}; + +static struct kobject *kobj_swpld1; +static struct kobject *kobj_swpld2; +static struct kobject *kobj_swpld3; + +static struct kobject *kobj_test1; +static struct kobject *kobj_test2; + +unsigned char swpld1_reg_addr; +unsigned char swpld2_reg_addr; +unsigned char swpld3_reg_addr; + + + +static ssize_t swpld1_data_show(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev = kobj_to_dev(kobj_swpld1->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + bool hex_fmt = 0; + char desc[256] = {0}; + + select = attr->index; + switch(select) { + case BOARD_ID: + offset = 0x1; + hex_fmt = 1; + scnprintf(desc, PAGE_SIZE, "\nBorad ID.\n"); + break; + case BOARD_VER: + offset = 0x2; + hex_fmt = 1; + scnprintf(desc, PAGE_SIZE, "\nBorad Version.\n"); + break; + case SWPLD1_VER_TYPE: + offset = 0x3; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nSWPLD1 Version Type.\n"); + break; + case SWPLD1_VER: + offset = 0x3; + mask = 0x7f; + scnprintf(desc, PAGE_SIZE, "\nSWPLD1 Version.\n"); + break; + case USB_HUB_RST: + offset = 0x6; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nUSB Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case SYNCE_RST: + offset = 0x6; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nSynce Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case BMC_RST: + offset = 0x6; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nBMC Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case LPC_RST: + offset = 0x6; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nBMC LPC Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case OOB_PCIE_RST: + offset = 0x6; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nOOB PCIE Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case MAC_PCIE_RST: + offset = 0x6; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nMAC PCIE Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case MAC_RST: + offset = 0x6; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nMAC Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case VR_3V3_RST: + offset = 0x7; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nVR 3V3 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case VR_0V8_RST: + offset = 0x7; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nVR 0V8 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case FAN_MUX_RST: + offset = 0x8; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nFAN I2C Mux Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case QSFP5_MUX_RST: + offset = 0x8; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nQSFP5 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case QSFP4_MUX_RST: + offset = 0x8; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nQSFP4 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case QSFP3_MUX_RST: + offset = 0x8; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nQSFP3 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case QSFP2_MUX_RST: + offset = 0x8; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nQSFP2 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case QSFP1_MUX_RST: + offset = 0x8; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nQSFP1 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case PSU1_PRESENT: + offset = 0x11; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU1 Not Present.\n“0†= PSU1 Present.\n"); + break; + case PSU1_STATE: + offset = 0x11; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU1 Power Not Good.\n“0†= PSU1 Power Good.\n"); + break; + case PSU1_ALERT: + offset = 0x11; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU1 Alert Active.\n“0†= PSU1 Alert Not Active.\n"); + break; + case PSU2_PRESENT: + offset = 0x11; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU2 Not Present.\n“0†= PSU2 Present.\n"); + break; + case PSU2_STATE: + offset = 0x11; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case PSU2_ALERT: + offset = 0x11; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU2 Alert Active.\n“0†= PSU2 Alert Not Active.\n"); + break; + case PSU1_EN: + offset = 0x12; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable PSU1.\n“0†= Enable PSU1.\n"); + break; + case PSU1_EEPROM_WP: + offset = 0x12; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable PSU1 EEPROM Write Protect.\n“0†= Disable PSU1 EEPROM Write Protect.\n"); + break; + case PSU2_EN: + offset = 0x12; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable PSU2.\n“0†= Enable PSU2.\n"); + break; + case PSU2_EEPROM_WP: + offset = 0x12; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable PSU2 EEPROM Write Protect.\n“0†= Disable PSU2 EEPROM Write Protect.\n"); + break; + case VCC_5V_EN: + offset = 0x23; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable VCC 5V.\n“0†= Disable VCC 5V.\n"); + break; + case VCC_3V3_EN: + offset = 0x23; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable VCC 3V3.\n“0†= Disable VCC 3V3.\n"); + break; + case VCC_VCORE_EN: + offset = 0x23; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable AVS 0V91.\n“0†= Disable AVS 0V91.\n"); + break; + case VCC_MAC_1V8_EN: + offset = 0x23; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable MAC 1V8.\n“0†= Disable MAC 1V8.\n"); + break; + case VCC_MAC_1V2_EN: + offset = 0x23; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable MAC 1V2.\n“0†= Disable MAC 1V2.\n"); + break; + case VCC_MAC_0V8_EN: + offset = 0x23; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable MAC 0V8.\n“0†= Disable MAC 0V8.\n"); + break; + case VCC_PLL_0V8_EN: + offset = 0x23; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable PLL 0V8.\n“0†= Disable PLL 0V8.\n"); + break; + case VCC_SYS_EN: + offset = 0x23; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable System Power.\n“0†= Disable System Power.\n"); + break; + case OOB_PWR_STATE: + offset = 0x24; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= OOB Power Rail Good.\n“0†= OOB Power Rail Not Good.\n"); + break; + case OOB_OP_EN: + offset = 0x24; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable OOB Operation.\n“0†= Disable OOB Operation.\n"); + break; + case USB1_OP_EN: + offset = 0x24; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable USB Operation.\n“0†= Enable USB Operation.\n"); + break; + case PSU_INTR: + offset = 0x26; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU Interrupt Not Occured.\n“0†= PSU Interrupt Occured.\n"); + break; + case FAN_ALERT: + offset = 0x26; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Fan Interrupt Not Occured.\n“0†= Fan Interrupt Occured.\n"); + break; + case SWPLD2_INTR: + offset = 0x27; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= SWPLD2 Interrupt Not Occured.\n“0†= SWPLD2 Interrupt Occured.\n"); + break; + case SWPLD3_INTR: + offset = 0x27; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= SWPLD3 Interrupt Not Occured.\n“0†= SWPLD3 Interrupt Occured.\n)"); + break; + case PSU1_LED: + offset = 0x41; + shift = 2; + mask = 0x0C; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= Auto.\n"); + break; + case PSU2_LED: + offset = 0x41; + shift = 0; + mask = 0x03; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= Auto.\n"); + break; + case SYS_LED: + offset = 0x42; + shift = 2; + mask = 0x0C; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Red\n“2†= LED Blink Green.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN_LED: + offset = 0x42; + shift = 0; + mask = 0x03; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Amber.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN1_LED: + offset = 0x46; + shift = 6; + mask = 0xc0; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN2_LED: + offset = 0x46; + shift = 4; + mask = 0x30; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN3_LED: + offset = 0x46; + shift = 2; + mask = 0x0c; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN4_LED: + offset = 0x46; + shift = 0; + mask = 0x03; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN5_LED: + offset = 0x47; + shift = 6; + mask = 0xc0; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN6_LED: + offset = 0x47; + shift = 4; + mask = 0x30; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case SYNCE_EEPROM_WB: + offset = 0x51; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case CONSOLE_SEL: + offset = 0x51; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case SYS_EEPROM_WB: + offset = 0x51; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + } + + value = i2c_smbus_read_byte_data(pdata[swpld1].client, offset); + value = (value & mask) >> shift; + if(hex_fmt) { + return scnprintf(buf, PAGE_SIZE, "0x%02x%s", value, desc); + } else { + return scnprintf(buf, PAGE_SIZE, "%d%s", value, desc); + } +} + + +static ssize_t swpld1_data_store(struct device *dev, struct device_attribute *dev_attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev = kobj_to_dev(kobj_swpld1->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + int err = 0; + unsigned long data; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + switch (attr->index) { + case USB_HUB_RST: + offset = 0x6; + shift = 6; + mask = (1 << shift); + break; + case SYNCE_RST: + offset = 0x6; + shift = 5; + mask = (1 << shift); + break; + case BMC_RST: + offset = 0x6; + shift = 4; + mask = (1 << shift); + break; + case LPC_RST: + offset = 0x6; + shift = 3; + mask = (1 << shift); + break; + case OOB_PCIE_RST: + offset = 0x6; + shift = 2; + mask = (1 << shift); + break; + case MAC_PCIE_RST: + offset = 0x6; + shift = 1; + mask = (1 << shift); + break; + case MAC_RST: + offset = 0x6; + shift = 0; + mask = (1 << shift); + break; + case VR_3V3_RST: + offset = 0x7; + shift = 3; + mask = (1 << shift); + break; + case VR_0V8_RST: + offset = 0x7; + shift = 2; + mask = (1 << shift); + break; + case FAN_MUX_RST: + offset = 0x8; + shift = 6; + mask = (1 << shift); + break; + case QSFP5_MUX_RST: + offset = 0x8; + shift = 5; + mask = (1 << shift); + break; + case QSFP4_MUX_RST: + offset = 0x8; + shift = 4; + mask = (1 << shift); + break; + case QSFP3_MUX_RST: + offset = 0x8; + shift = 3; + mask = (1 << shift); + break; + case QSFP2_MUX_RST: + offset = 0x8; + shift = 2; + mask = (1 << shift); + break; + case QSFP1_MUX_RST: + offset = 0x8; + shift = 1; + mask = (1 << shift); + break; + case PSU1_EN: + offset = 0x12; + shift = 7; + mask = (1 << shift); + break; + case PSU1_EEPROM_WP: + offset = 0x12; + shift = 6; + mask = (1 << shift); + break; + case PSU2_EN: + offset = 0x12; + shift = 3; + mask = (1 << shift); + break; + case PSU2_EEPROM_WP: + offset = 0x12; + shift = 2; + mask = (1 << shift); + break; + case VCC_5V_EN: + offset = 0x23; + shift = 7; + mask = (1 << shift); + break; + case VCC_3V3_EN: + offset = 0x23; + shift = 6; + mask = (1 << shift); + break; + case VCC_VCORE_EN: + offset = 0x23; + shift = 5; + mask = (1 << shift); + break; + case VCC_MAC_1V8_EN: + offset = 0x23; + shift = 4; + mask = (1 << shift); + break; + case VCC_MAC_1V2_EN: + offset = 0x23; + shift = 3; + mask = (1 << shift); + break; + case VCC_MAC_0V8_EN: + offset = 0x23; + shift = 2; + mask = (1 << shift); + break; + case VCC_PLL_0V8_EN: + offset = 0x23; + shift = 1; + mask = (1 << shift); + break; + case VCC_SYS_EN: + offset = 0x23; + shift = 0; + mask = (1 << shift); + break; + case OOB_OP_EN: + offset = 0x24; + shift = 6; + mask = (1 << shift); + break; + case USB1_OP_EN: + offset = 0x24; + shift = 1; + mask = (1 << shift); + break; + case PSU1_LED: + offset = 0x41; + shift = 2; + mask = 0x0C; + break; + case PSU2_LED: + offset = 0x41; + shift = 0; + mask = 0x03; + break; + case SYS_LED: + offset = 0x42; + shift = 2; + mask = 0x0C; + break; + case FAN_LED: + offset = 0x42; + shift = 0; + mask = 0x03; + break; + case FAN1_LED: + offset = 0x46; + shift = 6; + mask = 0xc0; + break; + case FAN2_LED: + offset = 0x46; + shift = 4; + mask = 0x30; + break; + case FAN3_LED: + offset = 0x46; + shift = 2; + mask = 0x0c; + break; + case FAN4_LED: + offset = 0x46; + shift = 0; + mask = 0x03; + break; + case FAN5_LED: + offset = 0x47; + shift = 6; + mask = 0xc0; + break; + case FAN6_LED: + offset = 0x47; + shift = 4; + mask = 0x30; + break; + case SYNCE_EEPROM_WB: + offset = 0x51; + shift = 5; + mask = (1 << shift); + break; + case CONSOLE_SEL: + offset = 0x51; + shift = 5; + mask = (1 << shift); + break; + case SYS_EEPROM_WB: + offset = 0x51; + shift = 5; + mask = (1 << shift); + break; + } + + value = i2c_smbus_read_byte_data(pdata[swpld1].client, offset); + data = (value & ~mask) | (data << shift); + i2c_smbus_write_byte_data(pdata[swpld1].client, offset, data); + + return count; +} + + +/* offset 0x01 */ +static SENSOR_DEVICE_ATTR(board_id, S_IRUGO, swpld1_data_show, NULL, BOARD_ID); +/* offser 0x02 */ +static SENSOR_DEVICE_ATTR(board_ver, S_IRUGO, swpld1_data_show, NULL, BOARD_VER); +/* offset 0x03 */ +static SENSOR_DEVICE_ATTR(swpld1_ver_type, S_IRUGO, swpld1_data_show, NULL, SWPLD1_VER_TYPE); +static SENSOR_DEVICE_ATTR(swpld1_ver, S_IRUGO, swpld1_data_show, NULL, SWPLD1_VER); +/* offset 0x06 */ +static SENSOR_DEVICE_ATTR(usb_hub_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, USB_HUB_RST); +static SENSOR_DEVICE_ATTR(synce_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, SYNCE_RST); +static SENSOR_DEVICE_ATTR(bmc_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, BMC_RST); +static SENSOR_DEVICE_ATTR(lpc_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, LPC_RST); +static SENSOR_DEVICE_ATTR(oob_pcie_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, OOB_PCIE_RST); +static SENSOR_DEVICE_ATTR(mac_pcie_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, MAC_PCIE_RST); +static SENSOR_DEVICE_ATTR(mac_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, MAC_RST); +/* offset 0x07 */ +static SENSOR_DEVICE_ATTR(vr_3v3_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VR_3V3_RST); +static SENSOR_DEVICE_ATTR(vr_0v8_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VR_0V8_RST); +/* offset 0x08 */ +static SENSOR_DEVICE_ATTR(fan_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN_MUX_RST); +static SENSOR_DEVICE_ATTR(qsfp5_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, QSFP5_MUX_RST); +static SENSOR_DEVICE_ATTR(qsfp4_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, QSFP4_MUX_RST); +static SENSOR_DEVICE_ATTR(qsfp3_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, QSFP3_MUX_RST); +static SENSOR_DEVICE_ATTR(qsfp2_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, QSFP2_MUX_RST); +static SENSOR_DEVICE_ATTR(qsfp1_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, QSFP1_MUX_RST); +/* offset 0x11 */ +static SENSOR_DEVICE_ATTR(psu1_present, S_IRUGO, swpld1_data_show, NULL, PSU1_PRESENT); +static SENSOR_DEVICE_ATTR(psu1_state, S_IRUGO, swpld1_data_show, NULL, PSU1_STATE); +static SENSOR_DEVICE_ATTR(psu1_alert, S_IRUGO, swpld1_data_show, NULL, PSU1_ALERT); +static SENSOR_DEVICE_ATTR(psu2_present, S_IRUGO, swpld1_data_show, NULL, PSU2_PRESENT); +static SENSOR_DEVICE_ATTR(psu2_state, S_IRUGO, swpld1_data_show, NULL, PSU2_STATE); +static SENSOR_DEVICE_ATTR(psu2_alert, S_IRUGO, swpld1_data_show, NULL, PSU2_ALERT); +/* offset 0x12 */ +static SENSOR_DEVICE_ATTR(psu1_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU1_EN); +static SENSOR_DEVICE_ATTR(psu1_eeprom_wp, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU1_EEPROM_WP); +static SENSOR_DEVICE_ATTR(psu2_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU2_EN); +static SENSOR_DEVICE_ATTR(psu2_eeprom_wp, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU2_EEPROM_WP); +/* offset 0x23 */ +static SENSOR_DEVICE_ATTR(vcc_5v_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_5V_EN); +static SENSOR_DEVICE_ATTR(vcc_3v3_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_3V3_EN); +static SENSOR_DEVICE_ATTR(vcc_vcore_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_VCORE_EN); +static SENSOR_DEVICE_ATTR(vcc_mac_1v8_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_MAC_1V8_EN); +static SENSOR_DEVICE_ATTR(vcc_mac_1v2_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_MAC_1V2_EN); +static SENSOR_DEVICE_ATTR(vcc_mac_0v8_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_MAC_0V8_EN); +static SENSOR_DEVICE_ATTR(vcc_pll_0v8_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_PLL_0V8_EN); +static SENSOR_DEVICE_ATTR(vcc_sys_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_SYS_EN); +/* offset 0x24 */ +static SENSOR_DEVICE_ATTR(oob_pwr_state, S_IRUGO, swpld1_data_show, NULL, OOB_PWR_STATE); +static SENSOR_DEVICE_ATTR(oob_op_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, OOB_OP_EN); +static SENSOR_DEVICE_ATTR(usb1_op_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, USB1_OP_EN); +/* offset 0x26 */ +static SENSOR_DEVICE_ATTR(psu_intr, S_IRUGO, swpld1_data_show, NULL, PSU_INTR); +static SENSOR_DEVICE_ATTR(fan_alert, S_IRUGO, swpld1_data_show, NULL, FAN_ALERT); +/* offset 0x27 */ +static SENSOR_DEVICE_ATTR(swpld2_intr, S_IRUGO, swpld1_data_show, NULL, SWPLD2_INTR); +static SENSOR_DEVICE_ATTR(swpld3_intr, S_IRUGO, swpld1_data_show, NULL, SWPLD3_INTR); +/* offset 0x41 */ +static SENSOR_DEVICE_ATTR(psu1_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU1_LED); +static SENSOR_DEVICE_ATTR(psu2_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU2_LED); +/* offset 0x42 */ +static SENSOR_DEVICE_ATTR(sys_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, SYS_LED); +static SENSOR_DEVICE_ATTR(fan_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN_LED); +/* offset 0x46 */ +static SENSOR_DEVICE_ATTR(fan1_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN1_LED); +static SENSOR_DEVICE_ATTR(fan2_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN2_LED); +static SENSOR_DEVICE_ATTR(fan3_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN3_LED); +static SENSOR_DEVICE_ATTR(fan4_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN4_LED); +/* offset 0x47 */ +static SENSOR_DEVICE_ATTR(fan5_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN5_LED); +static SENSOR_DEVICE_ATTR(fan6_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN6_LED); +/* offset 0x51*/ +static SENSOR_DEVICE_ATTR(synce_eeprom_wb, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, SYNCE_EEPROM_WB); +static SENSOR_DEVICE_ATTR(console_sel, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, CONSOLE_SEL); +static SENSOR_DEVICE_ATTR(sys_eeprom_wb, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, SYS_EEPROM_WB); + +static struct attribute *swpld1_device_attrs[] = { + &sensor_dev_attr_board_id.dev_attr.attr, + &sensor_dev_attr_board_ver.dev_attr.attr, + &sensor_dev_attr_swpld1_ver_type.dev_attr.attr, + &sensor_dev_attr_swpld1_ver.dev_attr.attr, + &sensor_dev_attr_usb_hub_rst.dev_attr.attr, + &sensor_dev_attr_synce_rst.dev_attr.attr, + &sensor_dev_attr_bmc_rst.dev_attr.attr, + &sensor_dev_attr_lpc_rst.dev_attr.attr, + &sensor_dev_attr_oob_pcie_rst.dev_attr.attr, + &sensor_dev_attr_mac_pcie_rst.dev_attr.attr, + &sensor_dev_attr_mac_rst.dev_attr.attr, + &sensor_dev_attr_vr_3v3_rst.dev_attr.attr, + &sensor_dev_attr_vr_0v8_rst.dev_attr.attr, + &sensor_dev_attr_fan_mux_rst.dev_attr.attr, + &sensor_dev_attr_qsfp5_mux_rst.dev_attr.attr, + &sensor_dev_attr_qsfp4_mux_rst.dev_attr.attr, + &sensor_dev_attr_qsfp3_mux_rst.dev_attr.attr, + &sensor_dev_attr_qsfp2_mux_rst.dev_attr.attr, + &sensor_dev_attr_qsfp1_mux_rst.dev_attr.attr, + &sensor_dev_attr_psu1_present.dev_attr.attr, + &sensor_dev_attr_psu1_state.dev_attr.attr, + &sensor_dev_attr_psu1_alert.dev_attr.attr, + &sensor_dev_attr_psu2_present.dev_attr.attr, + &sensor_dev_attr_psu2_state.dev_attr.attr, + &sensor_dev_attr_psu2_alert.dev_attr.attr, + &sensor_dev_attr_psu1_en.dev_attr.attr, + &sensor_dev_attr_psu1_eeprom_wp.dev_attr.attr, + &sensor_dev_attr_psu2_en.dev_attr.attr, + &sensor_dev_attr_psu2_eeprom_wp.dev_attr.attr, + &sensor_dev_attr_vcc_5v_en.dev_attr.attr, + &sensor_dev_attr_vcc_3v3_en.dev_attr.attr, + &sensor_dev_attr_vcc_vcore_en.dev_attr.attr, + &sensor_dev_attr_vcc_mac_1v8_en.dev_attr.attr, + &sensor_dev_attr_vcc_mac_1v2_en.dev_attr.attr, + &sensor_dev_attr_vcc_mac_0v8_en.dev_attr.attr, + &sensor_dev_attr_vcc_pll_0v8_en.dev_attr.attr, + &sensor_dev_attr_vcc_sys_en.dev_attr.attr, + &sensor_dev_attr_oob_pwr_state.dev_attr.attr, + &sensor_dev_attr_oob_op_en.dev_attr.attr, + &sensor_dev_attr_usb1_op_en.dev_attr.attr, + &sensor_dev_attr_psu_intr.dev_attr.attr, + &sensor_dev_attr_fan_alert.dev_attr.attr, + &sensor_dev_attr_swpld2_intr.dev_attr.attr, + &sensor_dev_attr_swpld3_intr.dev_attr.attr, + &sensor_dev_attr_psu1_led.dev_attr.attr, + &sensor_dev_attr_psu2_led.dev_attr.attr, + &sensor_dev_attr_sys_led.dev_attr.attr, + &sensor_dev_attr_fan_led.dev_attr.attr, + &sensor_dev_attr_fan1_led.dev_attr.attr, + &sensor_dev_attr_fan2_led.dev_attr.attr, + &sensor_dev_attr_fan3_led.dev_attr.attr, + &sensor_dev_attr_fan4_led.dev_attr.attr, + &sensor_dev_attr_fan5_led.dev_attr.attr, + &sensor_dev_attr_fan6_led.dev_attr.attr, + &sensor_dev_attr_synce_eeprom_wb.dev_attr.attr, + &sensor_dev_attr_console_sel.dev_attr.attr, + &sensor_dev_attr_sys_eeprom_wb.dev_attr.attr, +}; + + +static ssize_t swpld2_data_show(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev = kobj_to_dev(kobj_swpld2->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + bool hex_fmt = 0; + char desc[256] = {0}; + + select = attr->index; + switch(select) { + case SWPLD2_VER_TYPE: + offset = 0x1; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nSWPLD2 Version Type.\n"); + break; + case SWPLD2_VER: + offset = 0x1; + mask = 0x7f; + scnprintf(desc, PAGE_SIZE, "\nSWPLD2 Version.\n"); + break; + case QSFP_P01_RST: + offset = 0x11; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P02_RST: + offset = 0x11; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P03_RST: + offset = 0x11; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P04_RST: + offset = 0x11; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P05_RST: + offset = 0x11; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P06_RST: + offset = 0x11; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P07_RST: + offset = 0x11; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P08_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P09_RST: + offset = 0x12; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P10_RST: + offset = 0x12; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P11_RST: + offset = 0x12; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P12_RST: + offset = 0x12; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P13_RST: + offset = 0x12; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P14_RST: + offset = 0x12; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P15_RST: + offset = 0x12; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P16_RST: + offset = 0x12; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P01_LPMODE: + offset = 0x21; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P02_LPMODE: + offset = 0x21; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P03_LPMODE: + offset = 0x21; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P04_LPMODE: + offset = 0x21; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P05_LPMODE: + offset = 0x21; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P06_LPMODE: + offset = 0x21; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P07_LPMODE: + offset = 0x21; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P08_LPMODE: + offset = 0x21; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P09_LPMODE: + offset = 0x22; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P10_LPMODE: + offset = 0x22; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P11_LPMODE: + offset = 0x22; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P12_LPMODE: + offset = 0x22; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P13_LPMODE: + offset = 0x22; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P14_LPMODE: + offset = 0x22; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P15_LPMODE: + offset = 0x22; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P16_LPMODE: + offset = 0x22; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P01_MODPRS: + offset = 0x51; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P02_MODPRS: + offset = 0x51; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P03_MODPRS: + offset = 0x51; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P04_MODPRS: + offset = 0x51; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P05_MODPRS: + offset = 0x51; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P06_MODPRS: + offset = 0x51; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P07_MODPRS: + offset = 0x51; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P08_MODPRS: + offset = 0x51; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P09_MODPRS: + offset = 0x52; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P10_MODPRS: + offset = 0x52; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P11_MODPRS: + offset = 0x52; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P12_MODPRS: + offset = 0x52; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P13_MODPRS: + offset = 0x52; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P14_MODPRS: + offset = 0x52; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P15_MODPRS: + offset = 0x52; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P16_MODPRS: + offset = 0x52; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P01_INTR: + offset = 0x61; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P02_INTR: + offset = 0x61; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P03_INTR: + offset = 0x61; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P04_INTR: + offset = 0x61; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P05_INTR: + offset = 0x61; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P06_INTR: + offset = 0x61; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P07_INTR: + offset = 0x61; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P08_INTR: + offset = 0x61; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P09_INTR: + offset = 0x62; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P10_INTR: + offset = 0x62; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P11_INTR: + offset = 0x62; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P12_INTR: + offset = 0x62; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P13_INTR: + offset = 0x62; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P14_INTR: + offset = 0x62; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P15_INTR: + offset = 0x62; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P16_INTR: + offset = 0x62; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + } + + value = i2c_smbus_read_byte_data(pdata[swpld2].client, offset); + value = (value & mask) >> shift; + if(hex_fmt) { + return scnprintf(buf, PAGE_SIZE, "0x%02x%s", value, desc); + } else { + return scnprintf(buf, PAGE_SIZE, "%d%s", value, desc); + } +} + +static ssize_t swpld2_data_store(struct device *dev, struct device_attribute *dev_attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev = kobj_to_dev(kobj_swpld2->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + int err = 0; + unsigned long data; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + switch (attr->index) { + case QSFP_P01_RST: + offset = 0x11; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P02_RST: + offset = 0x11; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P03_RST: + offset = 0x11; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P04_RST: + offset = 0x11; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P05_RST: + offset = 0x11; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P06_RST: + offset = 0x11; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P07_RST: + offset = 0x11; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P08_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P09_RST: + offset = 0x12; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P10_RST: + offset = 0x12; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P11_RST: + offset = 0x12; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P12_RST: + offset = 0x12; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P13_RST: + offset = 0x12; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P14_RST: + offset = 0x12; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P15_RST: + offset = 0x12; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P16_RST: + offset = 0x12; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P01_LPMODE: + offset = 0x21; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P02_LPMODE: + offset = 0x21; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P03_LPMODE: + offset = 0x21; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P04_LPMODE: + offset = 0x21; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P05_LPMODE: + offset = 0x21; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P06_LPMODE: + offset = 0x21; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P07_LPMODE: + offset = 0x21; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P08_LPMODE: + offset = 0x21; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P09_LPMODE: + offset = 0x22; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P10_LPMODE: + offset = 0x22; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P11_LPMODE: + offset = 0x22; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P12_LPMODE: + offset = 0x22; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P13_LPMODE: + offset = 0x22; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P14_LPMODE: + offset = 0x22; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P15_LPMODE: + offset = 0x22; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P16_LPMODE: + offset = 0x22; + shift = 0; + mask = (1 << shift); + break; + } + + value = i2c_smbus_read_byte_data(pdata[swpld2].client, offset); + data = (value & ~mask) | (data << shift); + i2c_smbus_write_byte_data(pdata[swpld2].client, offset, data); + + return count; +} + + +/* offset 0x01 */ +static SENSOR_DEVICE_ATTR(swpld2_ver_type, S_IRUGO, swpld2_data_show, NULL, SWPLD2_VER_TYPE); +static SENSOR_DEVICE_ATTR(swpld2_ver, S_IRUGO, swpld2_data_show, NULL, SWPLD2_VER); +/* offset 0x11 */ +static SENSOR_DEVICE_ATTR(qsfp_p01_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P01_RST); +static SENSOR_DEVICE_ATTR(qsfp_p02_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P02_RST); +static SENSOR_DEVICE_ATTR(qsfp_p03_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P03_RST); +static SENSOR_DEVICE_ATTR(qsfp_p04_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P04_RST); +static SENSOR_DEVICE_ATTR(qsfp_p05_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P05_RST); +static SENSOR_DEVICE_ATTR(qsfp_p06_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P06_RST); +static SENSOR_DEVICE_ATTR(qsfp_p07_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P07_RST); +static SENSOR_DEVICE_ATTR(qsfp_p08_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P08_RST); +/* offset 0x12 */ +static SENSOR_DEVICE_ATTR(qsfp_p09_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P09_RST); +static SENSOR_DEVICE_ATTR(qsfp_p10_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P10_RST); +static SENSOR_DEVICE_ATTR(qsfp_p11_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P11_RST); +static SENSOR_DEVICE_ATTR(qsfp_p12_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P12_RST); +static SENSOR_DEVICE_ATTR(qsfp_p13_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P13_RST); +static SENSOR_DEVICE_ATTR(qsfp_p14_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P14_RST); +static SENSOR_DEVICE_ATTR(qsfp_p15_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P15_RST); +static SENSOR_DEVICE_ATTR(qsfp_p16_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P16_RST); +/* offset 0x21 */ +static SENSOR_DEVICE_ATTR(qsfp_p01_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P01_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p02_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P02_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p03_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P03_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p04_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P04_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p05_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P05_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p06_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P06_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p07_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P07_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p08_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P08_LPMODE); +/* offset 0x22 */ +static SENSOR_DEVICE_ATTR(qsfp_p09_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P09_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p10_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P10_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p11_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P11_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p12_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P12_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p13_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P13_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p14_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P14_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p15_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P15_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p16_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P16_LPMODE); +/* offset 0x51 */ +static SENSOR_DEVICE_ATTR(qsfp_p01_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P01_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p02_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P02_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p03_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P03_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p04_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P04_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p05_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P05_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p06_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P06_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p07_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P07_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p08_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P08_MODPRS); +/* offset 0x52 */ +static SENSOR_DEVICE_ATTR(qsfp_p09_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P09_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p10_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P10_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p11_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P11_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p12_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P12_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p13_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P13_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p14_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P14_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p15_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P15_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p16_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P16_MODPRS); +/* offset 0x61 */ +static SENSOR_DEVICE_ATTR(qsfp_p01_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P01_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p02_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P02_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p03_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P03_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p04_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P04_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p05_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P05_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p06_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P06_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p07_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P07_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p08_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P08_INTR); +/* offset 0x62 */ +static SENSOR_DEVICE_ATTR(qsfp_p09_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P09_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p10_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P10_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p11_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P11_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p12_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P12_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p13_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P13_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p14_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P14_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p15_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P15_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p16_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P16_INTR); + + +static struct attribute *swpld2_device_attrs[] = { + &sensor_dev_attr_swpld2_ver_type.dev_attr.attr, + &sensor_dev_attr_swpld2_ver.dev_attr.attr, + &sensor_dev_attr_qsfp_p01_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p02_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p03_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p04_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p05_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p06_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p07_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p08_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p09_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p10_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p11_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p12_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p13_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p14_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p15_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p16_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p01_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p02_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p03_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p04_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p05_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p06_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p07_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p08_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p09_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p10_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p11_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p12_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p13_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p14_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p15_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p16_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p01_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p02_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p03_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p04_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p05_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p06_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p07_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p08_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p09_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p10_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p11_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p12_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p13_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p14_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p15_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p16_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p01_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p02_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p03_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p04_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p05_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p06_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p07_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p08_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p09_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p10_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p11_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p12_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p13_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p14_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p15_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p16_intr.dev_attr.attr, +}; + + +static ssize_t swpld3_data_show(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev = kobj_to_dev(kobj_swpld3->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + bool hex_fmt = 0; + char desc[256] = {0}; + + select = attr->index; + switch(select) { + case SWPLD3_VER_TYPE: + offset = 0x1; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nSWPLD3 Version Type.\n"); + break; + case SWPLD3_VER: + offset = 0x1; + mask = 0x7f; + scnprintf(desc, PAGE_SIZE, "\nSWPLD3 Version.\n"); + break; + case QSFP_P17_RST: + offset = 0x11; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P18_RST: + offset = 0x11; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P19_RST: + offset = 0x11; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P20_RST: + offset = 0x11; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P21_RST: + offset = 0x11; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P22_RST: + offset = 0x11; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P23_RST: + offset = 0x11; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P24_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P25_RST: + offset = 0x12; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P26_RST: + offset = 0x12; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P27_RST: + offset = 0x12; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P28_RST: + offset = 0x12; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P29_RST: + offset = 0x12; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P30_RST: + offset = 0x12; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P31_RST: + offset = 0x12; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P32_RST: + offset = 0x12; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P17_LPMODE: + offset = 0x21; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P18_LPMODE: + offset = 0x21; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P19_LPMODE: + offset = 0x21; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P20_LPMODE: + offset = 0x21; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P21_LPMODE: + offset = 0x21; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P22_LPMODE: + offset = 0x21; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P23_LPMODE: + offset = 0x21; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P24_LPMODE: + offset = 0x21; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P25_LPMODE: + offset = 0x22; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P26_LPMODE: + offset = 0x22; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P27_LPMODE: + offset = 0x22; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P28_LPMODE: + offset = 0x22; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P29_LPMODE: + offset = 0x22; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P30_LPMODE: + offset = 0x22; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P31_LPMODE: + offset = 0x22; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P32_LPMODE: + offset = 0x22; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P17_MODPRS: + offset = 0x51; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P18_MODPRS: + offset = 0x51; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P19_MODPRS: + offset = 0x51; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P20_MODPRS: + offset = 0x51; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P21_MODPRS: + offset = 0x51; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P22_MODPRS: + offset = 0x51; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P23_MODPRS: + offset = 0x51; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P24_MODPRS: + offset = 0x51; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P25_MODPRS: + offset = 0x52; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P26_MODPRS: + offset = 0x52; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P27_MODPRS: + offset = 0x52; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P28_MODPRS: + offset = 0x52; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P29_MODPRS: + offset = 0x52; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P30_MODPRS: + offset = 0x52; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P31_MODPRS: + offset = 0x52; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P32_MODPRS: + offset = 0x52; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P17_INTR: + offset = 0x61; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P18_INTR: + offset = 0x61; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P19_INTR: + offset = 0x61; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P20_INTR: + offset = 0x61; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P21_INTR: + offset = 0x61; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P22_INTR: + offset = 0x61; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P23_INTR: + offset = 0x61; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P24_INTR: + offset = 0x61; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P25_INTR: + offset = 0x62; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P26_INTR: + offset = 0x62; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P27_INTR: + offset = 0x62; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P28_INTR: + offset = 0x62; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P29_INTR: + offset = 0x62; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P30_INTR: + offset = 0x62; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P31_INTR: + offset = 0x62; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P32_INTR: + offset = 0x62; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case SFP_P0_MODPRS: + offset = 0x71; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Absent.\n“0†= Present.\n"); + break; + case SFP_P0_RXLOS: + offset = 0x71; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Receive Loss.\n“0†= Normal Operation.\n"); + break; + case SFP_P0_TXFAULT: + offset = 0x71; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Transmit Fault.\n“0†= Normal Operation.\n"); + break; + case SFP_P1_MODPRS: + offset = 0x71; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Absent.\n“0†= Present.\n"); + break; + case SFP_P1_RXLOS: + offset = 0x71; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Receive Loss.\n“0†= Normal Operation.\n"); + break; + case SFP_P1_TXFAULT: + offset = 0x71; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Transmit Fault.\n“0†= Normal Operation.\n"); + break; + case SFP_P0_TXDIS: + offset = 0x72; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable.\n“0†= Normal Operation.\n"); + break; + case SFP_P1_TXDIS: + offset = 0x72; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable.\n“0†= Normal Operation.\n"); + break; + } + + value = i2c_smbus_read_byte_data(pdata[swpld3].client, offset); + value = (value & mask) >> shift; + if(hex_fmt) { + return scnprintf(buf, PAGE_SIZE, "0x%02x%s", value, desc); + } else { + return scnprintf(buf, PAGE_SIZE, "%d%s", value, desc); + } +} + + +static ssize_t swpld3_data_store(struct device *dev, struct device_attribute *dev_attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev = kobj_to_dev(kobj_swpld3->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + int err = 0; + unsigned long data; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + switch (attr->index) { + case QSFP_P17_RST: + offset = 0x11; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P18_RST: + offset = 0x11; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P19_RST: + offset = 0x11; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P20_RST: + offset = 0x11; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P21_RST: + offset = 0x11; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P22_RST: + offset = 0x11; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P23_RST: + offset = 0x11; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P24_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P25_RST: + offset = 0x12; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P26_RST: + offset = 0x12; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P27_RST: + offset = 0x12; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P28_RST: + offset = 0x12; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P29_RST: + offset = 0x12; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P30_RST: + offset = 0x12; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P31_RST: + offset = 0x12; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P32_RST: + offset = 0x12; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P17_LPMODE: + offset = 0x21; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P18_LPMODE: + offset = 0x21; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P19_LPMODE: + offset = 0x21; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P20_LPMODE: + offset = 0x21; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P21_LPMODE: + offset = 0x21; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P22_LPMODE: + offset = 0x21; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P23_LPMODE: + offset = 0x21; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P24_LPMODE: + offset = 0x21; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P25_LPMODE: + offset = 0x22; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P26_LPMODE: + offset = 0x22; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P27_LPMODE: + offset = 0x22; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P28_LPMODE: + offset = 0x22; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P29_LPMODE: + offset = 0x22; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P30_LPMODE: + offset = 0x22; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P31_LPMODE: + offset = 0x22; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P32_LPMODE: + offset = 0x22; + shift = 0; + mask = (1 << shift); + break; + case SFP_P0_TXDIS: + offset = 0x72; + shift = 7; + break; + case SFP_P1_TXDIS: + offset = 0x72; + shift = 3; + mask = (1 << shift); + break; + + } + + value = i2c_smbus_read_byte_data(pdata[swpld3].client, offset); + data = (value & ~mask) | (data << shift); + i2c_smbus_write_byte_data(pdata[swpld3].client, offset, data); + + return count; +} + +/* offset 0x01 */ +static SENSOR_DEVICE_ATTR(swpld3_ver_type, S_IRUGO, swpld3_data_show, NULL, SWPLD3_VER_TYPE); +static SENSOR_DEVICE_ATTR(swpld3_ver, S_IRUGO, swpld3_data_show, NULL, SWPLD3_VER); +/* offset 0x11 */ +static SENSOR_DEVICE_ATTR(qsfp_p17_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P17_RST); +static SENSOR_DEVICE_ATTR(qsfp_p18_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P18_RST); +static SENSOR_DEVICE_ATTR(qsfp_p19_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P19_RST); +static SENSOR_DEVICE_ATTR(qsfp_p20_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P20_RST); +static SENSOR_DEVICE_ATTR(qsfp_p21_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P21_RST); +static SENSOR_DEVICE_ATTR(qsfp_p22_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P22_RST); +static SENSOR_DEVICE_ATTR(qsfp_p23_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P23_RST); +static SENSOR_DEVICE_ATTR(qsfp_p24_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P24_RST); +/* offset 0x12 */ +static SENSOR_DEVICE_ATTR(qsfp_p25_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P25_RST); +static SENSOR_DEVICE_ATTR(qsfp_p26_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P26_RST); +static SENSOR_DEVICE_ATTR(qsfp_p27_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P27_RST); +static SENSOR_DEVICE_ATTR(qsfp_p28_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P28_RST); +static SENSOR_DEVICE_ATTR(qsfp_p29_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P29_RST); +static SENSOR_DEVICE_ATTR(qsfp_p30_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P30_RST); +static SENSOR_DEVICE_ATTR(qsfp_p31_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P31_RST); +static SENSOR_DEVICE_ATTR(qsfp_p32_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P32_RST); +/* offset 0x21 */ +static SENSOR_DEVICE_ATTR(qsfp_p17_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P17_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p18_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P18_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p19_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P19_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p20_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P20_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p21_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P21_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p22_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P22_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p23_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P23_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p24_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P24_LPMODE); +/* offset 0x22 */ +static SENSOR_DEVICE_ATTR(qsfp_p25_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P25_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p26_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P26_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p27_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P27_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p28_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P28_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p29_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P29_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p30_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P30_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p31_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P31_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p32_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P32_LPMODE); +/* offset 0x51 */ +static SENSOR_DEVICE_ATTR(qsfp_p17_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P17_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p18_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P18_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p19_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P19_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p20_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P20_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p21_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P21_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p22_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P22_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p23_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P23_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p24_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P24_MODPRS); +/* offset 0x52 */ +static SENSOR_DEVICE_ATTR(qsfp_p25_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P25_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p26_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P26_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p27_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P27_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p28_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P28_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p29_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P29_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p30_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P30_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p31_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P31_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p32_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P32_MODPRS); +/* offset 0x61 */ +static SENSOR_DEVICE_ATTR(qsfp_p17_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P17_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p18_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P18_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p19_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P19_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p20_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P20_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p21_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P21_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p22_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P22_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p23_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P23_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p24_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P24_INTR); +/* offset 0x62 */ +static SENSOR_DEVICE_ATTR(qsfp_p25_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P25_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p26_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P26_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p27_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P27_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p28_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P28_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p29_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P29_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p30_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P30_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p31_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P31_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p32_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P32_INTR); +/* offset 0x71 */ +static SENSOR_DEVICE_ATTR(sfp_p0_modprs, S_IRUGO, swpld3_data_show, NULL, SFP_P0_MODPRS); +static SENSOR_DEVICE_ATTR(sfp_p0_rxlos, S_IRUGO, swpld3_data_show, NULL, SFP_P0_RXLOS); +static SENSOR_DEVICE_ATTR(sfp_p0_txfault, S_IRUGO, swpld3_data_show, NULL, SFP_P0_TXFAULT); +static SENSOR_DEVICE_ATTR(sfp_p1_modprs, S_IRUGO, swpld3_data_show, NULL, SFP_P1_MODPRS); +static SENSOR_DEVICE_ATTR(sfp_p1_rxlos, S_IRUGO, swpld3_data_show, NULL, SFP_P1_RXLOS); +static SENSOR_DEVICE_ATTR(sfp_p1_txfault, S_IRUGO, swpld3_data_show, NULL, SFP_P1_TXFAULT); +/* offset 0x72 */ +static SENSOR_DEVICE_ATTR(sfp_p0_txdis, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, SFP_P0_TXDIS); +static SENSOR_DEVICE_ATTR(sfp_p1_txdis, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, SFP_P1_TXDIS); + +static struct attribute *swpld3_device_attrs[] = { + &sensor_dev_attr_swpld3_ver_type.dev_attr.attr, + &sensor_dev_attr_swpld3_ver.dev_attr.attr, + &sensor_dev_attr_qsfp_p17_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p18_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p19_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p20_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p21_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p22_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p23_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p24_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p25_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p26_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p27_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p28_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p29_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p30_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p31_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p32_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p17_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p18_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p19_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p20_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p21_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p22_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p23_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p24_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p25_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p26_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p27_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p28_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p29_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p30_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p31_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p32_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p17_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p18_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p19_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p20_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p21_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p22_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p23_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p24_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p25_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p26_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p27_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p28_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p29_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p30_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p31_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p32_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p17_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p18_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p19_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p20_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p21_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p22_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p23_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p24_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p25_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p26_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p27_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p28_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p29_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p30_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p31_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p32_intr.dev_attr.attr, + &sensor_dev_attr_sfp_p0_modprs.dev_attr.attr, + &sensor_dev_attr_sfp_p0_rxlos.dev_attr.attr, + &sensor_dev_attr_sfp_p0_txfault.dev_attr.attr, + &sensor_dev_attr_sfp_p1_modprs.dev_attr.attr, + &sensor_dev_attr_sfp_p1_rxlos.dev_attr.attr, + &sensor_dev_attr_sfp_p1_txfault.dev_attr.attr, + &sensor_dev_attr_sfp_p0_txdis.dev_attr.attr, + &sensor_dev_attr_sfp_p1_txdis.dev_attr.attr, +}; + +static struct attribute_group swpld1_device_attr_group = { + .attrs = swpld1_device_attrs, +}; + +static struct attribute_group swpld2_device_attr_group = { + .attrs = swpld2_device_attrs, +}; + +static struct attribute_group swpld3_device_attr_group = { + .attrs = swpld3_device_attrs, +}; + + +static struct cpld_platform_data agc032_swpld_platform_data[] = { + [swpld1] = { + .reg_addr = SWPLD1_ADDR, + }, + [swpld2] = { + .reg_addr = SWPLD2_ADDR, + }, + [swpld3] = { + .reg_addr = SWPLD3_ADDR, + }, +}; + +static void device_release(struct device *dev) +{ + return; +} + + +static struct platform_device swpld_device = { + .name = "delta-agc032-swpld", + .id = 0, + .dev = { + .platform_data = agc032_swpld_platform_data, + .release = device_release + }, +}; + + +static int __init swpld_probe(struct platform_device *pdev) +{ + int ret; + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPLD platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(BUS8); + if (!parent) { + printk(KERN_ERR "Parent adapter (%d) not found\n", BUS8); + return -ENODEV; + } + + pdata[swpld1].client = i2c_new_dummy(parent, pdata[swpld1].reg_addr); + if (!pdata[swpld1].client) { + printk(KERN_ERR "Fail to create dummy i2c client for addr %d\n", pdata[swpld1].reg_addr); + goto error_swpld1; + } + + pdata[swpld2].client = i2c_new_dummy(parent, pdata[swpld2].reg_addr); + if (!pdata[swpld2].client) { + printk(KERN_ERR "Fail to create dummy i2c client for addr %d\n", pdata[swpld2].reg_addr); + goto error_swpld2; + } + + pdata[swpld3].client = i2c_new_dummy(parent, pdata[swpld3].reg_addr); + if (!pdata[swpld3].client) { + printk(KERN_ERR "Fail to create dummy i2c client for addr %d\n", pdata[swpld3].reg_addr); + goto error_swpld3; + } +#if 1 + kobj_swpld1 = kobject_create_and_add("SWPLD1", &pdev->dev.kobj); + if (!kobj_swpld1){ + printk(KERN_ERR "Fail to create directory"); + goto error_swpld3; + } + + kobj_swpld2 = kobject_create_and_add("SWPLD2", &pdev->dev.kobj); + if (!kobj_swpld2){ + printk(KERN_ERR "Fail to create directory"); + goto error_swpld3; + } + + kobj_swpld3 = kobject_create_and_add("SWPLD3", &pdev->dev.kobj); + if (!kobj_swpld3){ + printk(KERN_ERR "Fail to create directory"); + goto error_swpld3; + } +#endif +#if 1 + ret = sysfs_create_group(kobj_swpld1, &swpld1_device_attr_group); + if (ret) { + printk(KERN_ERR "Fail to create SWPLD1 attribute group"); + goto error_add_swpld1; + } +#endif +#if 1 + ret = sysfs_create_group(kobj_swpld2, &swpld2_device_attr_group); + if (ret) { + printk(KERN_ERR "Fail to create SWPLD2 attribute group"); + goto error_add_swpld2; + } +#endif +#if 1 + ret = sysfs_create_group(kobj_swpld3, &swpld3_device_attr_group); + if (ret) { + printk(KERN_ERR "Fail to create SWPLD3 attribute group"); + goto error_add_swpld3; + } +#endif + return 0; + +error_add_swpld3: + kobject_put(kobj_swpld2); +error_add_swpld2: + kobject_put(kobj_swpld1); +error_add_swpld1: + i2c_unregister_device(pdata[swpld3].client); +error_swpld3: + i2c_unregister_device(pdata[swpld2].client); +error_swpld2: + i2c_unregister_device(pdata[swpld1].client); +error_swpld1: + i2c_put_adapter(parent); +} + +static int __exit swpld_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + + if (!kobj_swpld1){ + sysfs_remove_group(kobj_swpld1, &swpld1_device_attr_group); + } + if (!kobj_swpld2){ + sysfs_remove_group(kobj_swpld2, &swpld2_device_attr_group); + } + if (!kobj_swpld3){ + sysfs_remove_group(kobj_swpld3, &swpld3_device_attr_group); + } + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[swpld1].client) { + if (!parent) { + parent = (pdata[swpld1].client)->adapter; + } + i2c_unregister_device(pdata[swpld1].client); + } + if (pdata[swpld2].client) { + if (!parent) { + parent = (pdata[swpld2].client)->adapter; + } + i2c_unregister_device(pdata[swpld2].client); + } + if (pdata[swpld3].client) { + if (!parent) { + parent = (pdata[swpld3].client)->adapter; + } + i2c_unregister_device(pdata[swpld3].client); + } + } + i2c_put_adapter(parent); + + return 0; +} + +static struct platform_driver swpld_driver = { + .probe = swpld_probe, + .remove = __exit_p(swpld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-swpld", + }, +}; + +static int __init delta_agc032_swpld_init(void) +{ + int ret; + int i = 0; + + printk(KERN_INFO "agc032_platform_swpld module initialization\n"); + + /* Register SWPLD driver */ + ret = platform_driver_register(&swpld_driver); + if (ret) { + printk(KERN_ERR "Fail to register swpld driver\n"); + goto error_swpld1_driver; + } + + /* Register SWPLD Device */ + ret = platform_device_register(&swpld_device); + if (ret) { + printk(KERN_ERR "Fail to create swpld device\n"); + goto error_swpld1_device; + } + + return 0; + +error_swpld1_device: + platform_driver_unregister(&swpld_driver); +error_swpld1_driver: + return ret; +} + +static void __exit delta_agc032_swpld_exit(void) +{ + + platform_device_unregister(&swpld_device); + platform_driver_unregister(&swpld_driver); +} + +module_init(delta_agc032_swpld_init); +module_exit(delta_agc032_swpld_exit); + +MODULE_DESCRIPTION("DNI agc032 SWPLD Platform Support"); +MODULE_AUTHOR("James Ke "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_agc032_psu.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_agc032_psu.c new file mode 100644 index 000000000000..ee46769fd311 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_agc032_psu.c @@ -0,0 +1,549 @@ +/* + * An hwmon driver for delta AGC032 PSU + * dps_1600ab_29_a.c - Support for DPS-1600AB-29 A Power Supply Module + * + * Copyright (C) 2016 Delta Network Technology Corporation + * + * DNI + * + * Based on ym2651y.c + * Based on ad7414.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 +#define SWPLD_REG 0x31 +#define SWPLD_PSU_MUX_REG 0x21 +#define SELECT_PSU1_EEPROM 0x00 +#define SELECT_PSU2_EEPROM 0x20 + +u8 psu_member_data = 0x00; + + +/* Address scanned */ +static const unsigned short normal_i2c[] = { 0x58, I2C_CLIENT_END }; + +/* This is additional data */ +struct dps_1600ab_29_a_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 in1_input; + u16 in2_input; + u16 curr1_input; + u16 curr2_input; + u16 power1_input; + u16 power2_input; + u16 temp_input[2]; + u8 fan_target; + u16 fan_duty_cycle_input[2]; + u16 fan_speed_input[2]; + u8 mfr_model[16]; + u8 mfr_serial[16]; +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle_input(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static ssize_t for_fan_target(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static int dps_1600ab_29_a_read_byte(struct i2c_client *client, u8 reg); +static int dps_1600ab_29_a_read_word(struct i2c_client *client, u8 reg); +static int dps_1600ab_29_a_write_word(struct i2c_client *client, u8 reg, \ + u16 value); +static int dps_1600ab_29_a_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len); +static struct dps_1600ab_29_a_data *dps_1600ab_29_a_update_device( \ + struct device *dev); +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static ssize_t set_w_member_data(struct device *dev, struct device_attribute \ + *dev_att, const char *buf, size_t count); +static ssize_t for_r_member_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); + +enum dps_1600ab_29_a_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_FAN1_FAULT, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, + PSU_SELECT_MEMBER, +}; + +static ssize_t set_w_member_data(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + long data; + int error; + if (attr->index == PSU_SELECT_MEMBER) { + error = kstrtol(buf, 16, &data); + if (error) + return error; + if (SELECT_PSU1_EEPROM == data) { + psu_member_data = SELECT_PSU1_EEPROM; + } else if (SELECT_PSU2_EEPROM == data) { + psu_member_data = SELECT_PSU2_EEPROM; + } else { + return -EINVAL; + } + } + return count; +} + +static ssize_t for_r_member_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + return sprintf(buf, "0x%02X\n", psu_member_data); +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle_input(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); + struct dps_1600ab_29_a_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + /* Select SWPLD PSU offset */ + + mutex_lock(&data->update_lock); + data->fan_duty_cycle_input[nr] = speed; + dps_1600ab_29_a_write_word(client, 0x3B + nr, data->fan_duty_cycle_input[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_IN: + value = data->in1_input; + break; + case PSU_I_IN: + value = data->curr1_input; + break; + case PSU_I_OUT: + value = data->curr2_input; + break; + case PSU_P_IN: + value = data->power1_input; + multiplier = 1000*1000; + break; + case PSU_P_OUT: + value = data->power2_input; + multiplier = 1000*1000; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle_input[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed_input[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_fan_target(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_target >> shift); +} + +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->in2_input; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa * multiplier) / (1 << exponent)): \ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev); + u8 *ptr = NULL; + + if (!data->valid) + return 0; + + switch (attr->index) { + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} +static int dps_1600ab_29_a_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int dps_1600ab_29_a_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int dps_1600ab_29_a_write_word(struct i2c_client *client, u8 reg, \ + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + +static int dps_1600ab_29_a_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, + data); + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; +abort: + return result; + +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct dps_1600ab_29_a_data *dps_1600ab_29_a_update_device( \ + struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct dps_1600ab_29_a_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + /* Select SWPLD PSU offset */ + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_target} + }; + struct reg_data_word regs_word[] = { + {0x88, &data->in1_input}, + {0x8b, &data->in2_input}, + {0x89, &data->curr1_input}, + {0x8c, &data->curr2_input}, + {0x96, &data->power2_input}, + {0x97, &data->power1_input}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle_input[0])}, + {0x90, &(data->fan_speed_input[0])}, + }; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = dps_1600ab_29_a_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = dps_1600ab_29_a_read_word(client, + regs_word[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + } else { + *(regs_word[i].value) = status; + } + } + + command = 0x9a; /* PSU mfr_model */ + //data->mfr_model[1] = '\0'; + status = dps_1600ab_29_a_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command,status); + data->mfr_model[1] = '\0'; + } + + command = 0x9e; /* PSU mfr_serial */ + //data->mfr_serial[1] = '\0'; + status = dps_1600ab_29_a_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command,status); + data->mfr_serial[1] = '\0'; + } + + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(temp1_input, \ + S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(fan1_target, \ + S_IRUGO, for_fan_target, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(fan1_set_percentage, S_IWUSR | S_IRUGO, \ + for_linear_data, set_fan_duty_cycle_input, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(fan1_input, \ + S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_model, \ + S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, \ + S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); +static SENSOR_DEVICE_ATTR(psu_select_member, S_IWUSR | S_IRUGO, \ + for_r_member_data, set_w_member_data, PSU_SELECT_MEMBER); + +static struct attribute *dps_1600ab_29_a_attributes[] = { + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_curr1_input.dev_attr.attr, + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_target.dev_attr.attr, + &sensor_dev_attr_fan1_set_percentage.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_select_member.dev_attr.attr, + NULL +}; + +static const struct attribute_group dps_1600ab_29_a_group = { + .attrs = dps_1600ab_29_a_attributes, +}; + +static int dps_1600ab_29_a_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct dps_1600ab_29_a_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "new chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &dps_1600ab_29_a_group); + if (status) + goto exit_sysfs_create_group; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + return 0; + +exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &dps_1600ab_29_a_group); +exit_sysfs_create_group: + kfree(data); +exit: + return status; +} + +static int dps_1600ab_29_a_remove(struct i2c_client *client) +{ + struct dps_1600ab_29_a_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &dps_1600ab_29_a_group); + kfree(data); + + return 0; +} + +enum id_name { + dni_agc032_psu, + dps_1600ab_29_a +}; + +static const struct i2c_device_id dps_1600ab_29_a_id[] = { + { "dni_agc032_psu", dni_agc032_psu }, + { "dps_1600ab_29_a", dps_1600ab_29_a }, + {} +}; +MODULE_DEVICE_TABLE(i2c, dps_1600ab_29_a_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver dps_1600ab_29_a_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "dps_1600ab_29_a", + }, + .probe = dps_1600ab_29_a_probe, + .remove = dps_1600ab_29_a_remove, + .id_table = dps_1600ab_29_a_id, + .address_list = normal_i2c, +}; + +static int __init dps_1600ab_29_a_init(void) +{ + return i2c_add_driver(&dps_1600ab_29_a_driver); +} + +static void __exit dps_1600ab_29_a_exit(void) +{ + i2c_del_driver(&dps_1600ab_29_a_driver); +} + + +MODULE_DESCRIPTION("DPS_1600AB_29_A Driver"); +MODULE_LICENSE("GPL"); + +module_init(dps_1600ab_29_a_init); +module_exit(dps_1600ab_29_a_exit); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2302.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2302.c new file mode 100644 index 000000000000..c947db1e96c5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2302.c @@ -0,0 +1,363 @@ +/* + * + * + * Copyright (C) 2017 Delta Networks, Inc. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms ofthe GNU General Public License as + * published by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * + * + * + * + * A hwmon driver for the SMSC EMC2302 fan controller + * Complete datasheet is available (6/2013) at: + * + */ + +#include +#include +#include +#include +#include + + +static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf); +static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf); +static ssize_t set_fan_percentage(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_fan_percentage(struct device *dev, struct device_attribute * devattr, + char *buf); +static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, 0x2F, 0x4C, + 0x4D, I2C_CLIENT_END + }; + + +#define EMC2302_REG_DEVICE 0xFD +#define EMC2302_REG_VENDOR 0xFE + +//#define FAN_MINIMUN 0x33 /*20%*/ +#define FAN_MINIMUN 0x0 /*0%*/ +#define FAN_RPM_BASED 0xAB + +#define EMC2302_REG_FAN_DRIVE(n) (0x30 + 0x10 * n) +#define EMC2302_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * n) +#define EMC2302_REG_FAN_TACH(n) (0x3E + 0x10 * n) +#define EMC2302_REG_FAN_CONF(n) (0x32 + 0x10 * n) +#define EMC2302_REG_FAN_REAR_H_RPM(n) (0x3D + 0x10 * n) +#define EMC2302_REG_FAN_REAR_L_RPM(n) (0x3C + 0x10 * n) + +#define EMC2302_DEVICE 0x36 +#define EMC2302_VENDOR 0x5D +#define MAX_FAN_SPEED 23000 + +struct emc2302_data +{ + struct device *hwmon_dev; + struct attribute_group attrs; + struct mutex lock; +}; + +static int emc2302_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int emc2302_detect(struct i2c_client *client, + struct i2c_board_info *info); +static int emc2302_remove(struct i2c_client *client); + +static const struct i2c_device_id emc2302_id[] = +{ + { "emc2302", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, emc2302_id); + +static struct i2c_driver emc2302_driver = +{ + .class = I2C_CLASS_HWMON, + .driver = { + .name = "emc2302", + }, + .probe = emc2302_probe, + .remove = emc2302_remove, + .id_table = emc2302_id, + .detect = emc2302_detect, + .address_list = normal_i2c, +}; + +static SENSOR_DEVICE_ATTR(fan1_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 1); +static SENSOR_DEVICE_ATTR(fan1_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 0); +static SENSOR_DEVICE_ATTR(fan2_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 1); +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); + +static struct attribute *emc2302_attr[] = +{ + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan1_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan2_input_percentage.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + NULL +}; + +static ssize_t show_fan_percentage(struct device *dev, struct device_attribute * devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + int val; + + mutex_lock(&data->lock); + val = i2c_smbus_read_word_swapped(client, + EMC2302_REG_FAN_TACH(attr->index)); + mutex_unlock(&data->lock); + /* Left shift 3 bits for showing correct RPM */ + val = val >> 3; + if ((int)(3932160 * 2 / (val > 0 ? val : 1) == 960))return sprintf(buf, "%d\n", 0); + return sprintf(buf, "%d\n", (int)(3932160 * 2 / (val > 0 ? val : 1) * 100 / MAX_FAN_SPEED)); +} + + +static ssize_t set_fan_percentage(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + unsigned long hsb, lsb; + unsigned long tech; + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 100) + { + return -EINVAL; + } + + if (val <= 5) + { + hsb = 0xff; /*high bit*/ + lsb = 0xe0; /*low bit*/ + } + else + { + val = val * 230; + tech = (3932160 * 2) / (val > 0 ? val : 1); + hsb = (uint8_t)(((tech << 3) >> 8) & 0x0ff); + lsb = (uint8_t)((tech << 3) & 0x0f8); + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_H_RPM(attr->index), hsb); + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_L_RPM(attr->index), lsb); + mutex_unlock(&data->lock); + return count; +} + + +static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + int val; + + + mutex_lock(&data->lock); + val = i2c_smbus_read_word_swapped(client, + EMC2302_REG_FAN_TACH(attr->index)); + mutex_unlock(&data->lock); + /* Left shift 3 bits for showing correct RPM */ + val = val >> 3; + return sprintf(buf, "%d\n", 3932160 * 2 / (val > 0 ? val : 1)); +} + +static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + unsigned long hsb, lsb; + unsigned long tech; + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 23000) + { + return -EINVAL; + } + + if (val <= 960) + { + hsb = 0xff; /*high bit*/ + lsb = 0xe0; /*low bit*/ + } + else + { + tech = (3932160 * 2) / (val > 0 ? val : 1); + hsb = (uint8_t)(((tech << 3) >> 8) & 0x0ff); + lsb = (uint8_t)((tech << 3) & 0x0f8); + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_H_RPM(attr->index), hsb); + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_L_RPM(attr->index), lsb); + mutex_unlock(&data->lock); + return count; +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + int val; + + mutex_lock(&data->lock); + val = i2c_smbus_read_byte_data(client, + EMC2302_REG_FAN_DRIVE(attr->index)); + mutex_unlock(&data->lock); + return sprintf(buf, "%d\n", val); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 255) + { + return -EINVAL; + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, + EMC2302_REG_FAN_DRIVE(attr->index), + val); + mutex_unlock(&data->lock); + return count; +} + +static int emc2302_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + int vendor, device; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + { + return -ENODEV; + } + + vendor = i2c_smbus_read_byte_data(client, EMC2302_REG_VENDOR); + if (vendor != EMC2302_VENDOR) + { + return -ENODEV; + } + + device = i2c_smbus_read_byte_data(client, EMC2302_REG_DEVICE); + if (device != EMC2302_DEVICE) + { + return -ENODEV; + } + + strlcpy(info->type, "emc2302", I2C_NAME_SIZE); + + return 0; +} + +static int emc2302_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct emc2302_data *data; + int err; + int i; + + data = devm_kzalloc(&client->dev, sizeof(struct emc2302_data), + GFP_KERNEL); + if (!data) + { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->lock); + + dev_info(&client->dev, "%s chip found\n", client->name); + + data->attrs.attrs = emc2302_attr; + err = sysfs_create_group(&client->dev.kobj, &data->attrs); + if (err) + { + return err; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) + { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + for (i = 0; i < 2; i++) + { + /* set minimum drive to 0% */ + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_MIN_DRIVE(i), FAN_MINIMUN); + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_CONF(i), FAN_RPM_BASED); + } + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->attrs); + return err; +} + +static int emc2302_remove(struct i2c_client *client) +{ + struct emc2302_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->attrs); + return 0; +} + +module_i2c_driver(emc2302_driver); + +MODULE_AUTHOR("Zoe Kuan"); +MODULE_DESCRIPTION("SMSC EMC2302 fan controller driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2305.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2305.c new file mode 120000 index 000000000000..e8f7ae6b3f4d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2305.c @@ -0,0 +1 @@ +../../common/modules/dni_emc2305.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/scripts/agc032_platform_init.sh b/platform/broadcom/sonic-platform-modules-delta/agc032/scripts/agc032_platform_init.sh new file mode 100755 index 000000000000..e14470a4c908 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/scripts/agc032_platform_init.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +#platform init script for Delta agc032 + +#fan speed monitor start +/usr/share/sonic/device/x86_64-delta_agc032-r0/fancontrol.service /usr/share/sonic/device/x86_64-delta_agc032-r0/fancontrol & + +# On Delta-agc032 platform, +# syseeprom is on the different mux with main board after CPLD, +# we have to switch CPLD mux from main board to syseeprom before getting syseeprom data. +# +# The purpose of switching CPLD mux and getting syseeprom information here +# is to store data in syseeprom_cache. +# After that, we can read "syseeprom_cache" directly when executing command +# "show platform syseeprom", "sudo decode-syseeprom", "show version". + +echo 0 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel +decode-syseeprom +echo 1 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel + +exit 0 + diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index 6ab0f3cf2f4c..e4d4946cce29 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -29,3 +29,8 @@ Package: platform-modules-ag9032v2a Architecture: amd64 Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as syseeprom, sfp + +Package: platform-modules-agc032 +Architecture: amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.init b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.init new file mode 100644 index 000000000000..5c106f87f919 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.init @@ -0,0 +1,62 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup agc032 board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + depmod -a + rmmod i2c-i801 + rmmod i2c-ismt + modprobe i2c-dev + modprobe i2c-i801 + modprobe i2c-ismt + modprobe i2c-mux-pca954x + modprobe dni_agc032_psu + modprobe dni_emc2305 + modprobe dni_emc2302 + modprobe at24 + modprobe optoe + modprobe delta_agc032_cpupld +# Switch CPUPLD to ONIE EEPROM Mux + echo 0 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel + modprobe eeprom + +# Switch CPUPLD to Front Port Mux + echo 3 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel + modprobe delta_agc032_qsfp + +# Switch CPUPLD to MainBoard Mux + echo 1 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel + modprobe delta_agc032_platform + modprobe delta_agc032_swpld + + /usr/local/bin/agc032_platform_init.sh + echo "done." + ;; + +stop) + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-agc032.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.install b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.install new file mode 100644 index 000000000000..e05e3694fd3e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.install @@ -0,0 +1,3 @@ +agc032/scripts/agc032_platform_init.sh usr/local/bin +agc032/cfg/agc032-modules.conf etc/modules-load.d +systemd/platform-modules-agc032.service lib/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/rules b/platform/broadcom/sonic-platform-modules-delta/debian/rules index b8c34c326fde..39126ff76729 100755 --- a/platform/broadcom/sonic-platform-modules-delta/debian/rules +++ b/platform/broadcom/sonic-platform-modules-delta/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= ag9032v1 ag9064 ag5648 et-6248brb ag9032v2a +MODULE_DIRS:= ag9032v1 ag9064 ag5648 et-6248brb ag9032v2a agc032 %: dh $@ --with=systemd diff --git a/platform/broadcom/sonic-platform-modules-delta/systemd/platform-modules-agc032.service b/platform/broadcom/sonic-platform-modules-delta/systemd/platform-modules-agc032.service new file mode 100644 index 000000000000..b84b6fba0aeb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/systemd/platform-modules-agc032.service @@ -0,0 +1,13 @@ +[Unit] +Description=Delta agc032 Platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-agc032 start +ExecStop=-/etc/init.d/platform-modules-agc032 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index 7740da96aa2d..9585c19301d4 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -133,6 +133,7 @@ serdes_pre_driver_current serdes_preemphasis serdes_rx_los serdes_sgmii_m +serdes_tx_taps_cd serdes_tx_taps skip_L2_USER_ENTRY sram_scan_enable From d7df56872b4f35b2d2e5c00fa9fa40cf7aa66311 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 27 May 2020 11:12:33 -0700 Subject: [PATCH 0735/1427] [sonic-quagga] update submodule with multiDB Changes (#4557) --- src/sonic-quagga | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-quagga b/src/sonic-quagga index 7101eeda1a1c..e3b3b634e76b 160000 --- a/src/sonic-quagga +++ b/src/sonic-quagga @@ -1 +1 @@ -Subproject commit 7101eeda1a1ccef2e951e4bea5a2f15d9a43e3b5 +Subproject commit e3b3b634e76b53cc4dce9301839451846eea7415 From f0eb1dbc931fb77422d45fdcbae2fff40d8dd0e1 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Thu, 28 May 2020 00:52:55 +0530 Subject: [PATCH 0736/1427] DellEMC: Skip thermalctld (S6000, S6100, Z9100 and Z9264) and thermal platform API changes (#4644) - Skip thermalctld in DellEMC S6000, S6100, Z9100 and Z9264 platforms. - Change the return type of thermal Platform APIs in DellEMC S6000, S6100, Z9100 and Z9264 platforms to 'float'. --- .../pmon_daemon_control.json | 3 ++- .../pmon_daemon_control.json | 3 ++- .../pmon_daemon_control.json | 3 ++- .../pmon_daemon_control.json | 3 ++- .../s6000/sonic_platform/thermal.py | 12 ++++++------ .../s6100/sonic_platform/thermal.py | 12 ++++++------ .../z9100/sonic_platform/thermal.py | 12 ++++++------ .../z9264f/sonic_platform/thermal.py | 6 +++--- 8 files changed, 29 insertions(+), 25 deletions(-) diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json b/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json index 94592fa8cebc..44871c057e82 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json b/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json index 94592fa8cebc..44871c057e82 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json b/device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json index 94592fa8cebc..44871c057e82 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json index 94592fa8cebc..44871c057e82 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py index a54336d40f1c..2f130ebabbb3 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py @@ -179,11 +179,11 @@ def get_temperature(self): thermal_temperature = self._read_sysfs_file( self.thermal_temperature_file) if (thermal_temperature != 'ERR'): - thermal_temperature = float(thermal_temperature) / 1000 + thermal_temperature = float(thermal_temperature) else: thermal_temperature = 0 - return "{:.3f}".format(thermal_temperature) + return thermal_temperature / 1000.0 def get_high_threshold(self): """ @@ -197,11 +197,11 @@ def get_high_threshold(self): thermal_high_threshold = self._read_sysfs_file( self.thermal_high_threshold_file) if (thermal_high_threshold != 'ERR'): - thermal_high_threshold = float(thermal_high_threshold) / 1000 + thermal_high_threshold = float(thermal_high_threshold) else: thermal_high_threshold = 0 - return "{:.3f}".format(thermal_high_threshold) + return thermal_high_threshold / 1000.0 def get_low_threshold(self): """ @@ -215,11 +215,11 @@ def get_low_threshold(self): thermal_low_threshold = self._read_sysfs_file( self.thermal_low_threshold_file) if (thermal_low_threshold != 'ERR'): - thermal_low_threshold = float(thermal_low_threshold) / 1000 + thermal_low_threshold = float(thermal_low_threshold) else: thermal_low_threshold = 0 - return "{:.3f}".format(thermal_low_threshold) + return thermal_low_threshold / 1000.0 def set_high_threshold(self, temperature): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py index 3947f4c84957..c6f6314dcb6d 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py @@ -138,11 +138,11 @@ def get_temperature(self): thermal_temperature = self._read_sysfs_file( self.thermal_temperature_file) if (thermal_temperature != 'ERR'): - thermal_temperature = float(thermal_temperature) / 1000 + thermal_temperature = float(thermal_temperature) else: thermal_temperature = 0 - return "{:.3f}".format(thermal_temperature) + return thermal_temperature / 1000.0 def get_high_threshold(self): """ @@ -156,11 +156,11 @@ def get_high_threshold(self): thermal_high_threshold = self._read_sysfs_file( self.thermal_high_threshold_file) if (thermal_high_threshold != 'ERR'): - thermal_high_threshold = float(thermal_high_threshold) / 1000 + thermal_high_threshold = float(thermal_high_threshold) else: thermal_high_threshold = 0 - return "{:.3f}".format(thermal_high_threshold) + return thermal_high_threshold / 1000.0 def get_low_threshold(self): """ @@ -174,11 +174,11 @@ def get_low_threshold(self): thermal_low_threshold = self._read_sysfs_file( self.thermal_low_threshold_file) if (thermal_low_threshold != 'ERR'): - thermal_low_threshold = float(thermal_low_threshold) / 1000 + thermal_low_threshold = float(thermal_low_threshold) else: thermal_low_threshold = 0 - return "{:.3f}".format(thermal_low_threshold) + return thermal_low_threshold / 1000.0 def set_high_threshold(self, temperature): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py index 05d012b114c0..e781a545e8ea 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py @@ -134,11 +134,11 @@ def get_temperature(self): thermal_temperature = self._read_sysfs_file( self.thermal_temperature_file) if (thermal_temperature != 'ERR'): - thermal_temperature = float(thermal_temperature) / 1000 + thermal_temperature = float(thermal_temperature) else: thermal_temperature = 0 - return "{:.3f}".format(thermal_temperature) + return thermal_temperature / 1000.0 def get_high_threshold(self): """ @@ -152,11 +152,11 @@ def get_high_threshold(self): thermal_high_threshold = self._read_sysfs_file( self.thermal_high_threshold_file) if (thermal_high_threshold != 'ERR'): - thermal_high_threshold = float(thermal_high_threshold) / 1000 + thermal_high_threshold = float(thermal_high_threshold) else: thermal_high_threshold = 0 - return "{:.3f}".format(thermal_high_threshold) + return thermal_high_threshold / 1000.0 def get_low_threshold(self): """ @@ -170,11 +170,11 @@ def get_low_threshold(self): thermal_low_threshold = self._read_sysfs_file( self.thermal_low_threshold_file) if (thermal_low_threshold != 'ERR'): - thermal_low_threshold = float(thermal_low_threshold) / 1000 + thermal_low_threshold = float(thermal_low_threshold) else: thermal_low_threshold = 0 - return "{:.3f}".format(thermal_low_threshold) + return thermal_low_threshold / 1000.0 def set_high_threshold(self, temperature): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py index 58a39005b54e..ab66c59b8600 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py @@ -94,7 +94,7 @@ def get_temperature(self): if not is_valid: temperature = 0 - return "{:.3f}".format(temperature) + return float(temperature) def get_high_threshold(self): """ @@ -109,7 +109,7 @@ def get_high_threshold(self): if not is_valid: high_threshold = 0 - return "{:.3f}".format(high_threshold) + return float(high_threshold) def get_low_threshold(self): """ @@ -124,7 +124,7 @@ def get_low_threshold(self): if not is_valid: low_threshold = 0 - return "{:.3f}".format(low_threshold) + return float(low_threshold) def set_high_threshold(self, temperature): """ From 7c5b6d4611f792efd7da518bc881a9d08f890432 Mon Sep 17 00:00:00 2001 From: Myron Sosyak <49795530+msosyak@users.noreply.github.com> Date: Wed, 27 May 2020 23:18:27 +0300 Subject: [PATCH 0737/1427] [BFN] Update sfputil plugin (#4640) --- .../plugins/sfputil.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py index 1daee453573e..00ab0f94ec1a 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py @@ -35,6 +35,8 @@ class SfpUtil(SfpUtilBase): QSFP_PORT_END = 0 EEPROM_OFFSET = 0 QSFP_CHECK_INTERVAL = 4 + THRIFT_RETRIES = 5 + THRIFT_TIMEOUT = 5 @property def port_start(self): @@ -94,7 +96,20 @@ def thrift_setup(self): pltfm_mgr_protocol = TMultiplexedProtocol.TMultiplexedProtocol(bprotocol, "pltfm_mgr_rpc") pltfm_mgr = pltfm_mgr_client_module.Client(pltfm_mgr_protocol) - transport.open() + for i in range(self.THRIFT_RETRIES): + try: + transport.open() + if i: + # The main thrift server is starded without platform api + # Platform api is added later during syncd initialization + # So we need to wait a little bit before do any platform api call + # Just in case when can't connect from the first try (warm-reboot case) + time.sleep(self.THRIFT_TIMEOUT) + break + except TTransport.TTransportException as e: + if e.type != TTransport.TTransportException.NOT_OPEN or i >= self.THRIFT_RETRIES - 1: + raise e + time.sleep(self.THRIFT_TIMEOUT) def thrift_teardown(self): global transport From 6d0f8dcb87fbe500164496af30dc0b20c3d66a3d Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 27 May 2020 18:12:42 -0700 Subject: [PATCH 0738/1427] [doc]: Update README.md: move LGTM badges above Jenkins badges (#4658) --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fda75bde93fc..82ac09e4b536 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ -*master builds*: - [![Total alerts](https://img.shields.io/lgtm/alerts/g/Azure/sonic-buildimage.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Azure/sonic-buildimage/alerts/) [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/Azure/sonic-buildimage.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Azure/sonic-buildimage/context:python) + +*master builds*: + [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all) [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all) [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all) From 87201929d3163a97e9dbba5b747b306fb70655a2 Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Thu, 28 May 2020 12:16:25 -0700 Subject: [PATCH 0739/1427] [sonic-yang-mgmt/setup.py]: Removing the part where build dependencies are installed in setup.py. (#4657) Changes: -- Removing the part where build dependencies are installed in setup.py. -- Adding build dependencies in corresponsing rules\..*.mk file. Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com --- rules/sonic-yang-mgmt-py2.mk | 7 +++++-- rules/sonic-yang-models-py3.mk | 3 ++- src/sonic-yang-mgmt/setup.py | 34 +--------------------------------- src/sonic-yang-models/setup.py | 25 +------------------------ 4 files changed, 9 insertions(+), 60 deletions(-) diff --git a/rules/sonic-yang-mgmt-py2.mk b/rules/sonic-yang-mgmt-py2.mk index f438a6bd5116..0b85d7eb9bdc 100644 --- a/rules/sonic-yang-mgmt-py2.mk +++ b/rules/sonic-yang-mgmt-py2.mk @@ -3,7 +3,10 @@ SONIC_YANG_MGMT_PY = sonic_yang_mgmt-1.0-py2-none-any.whl $(SONIC_YANG_MGMT_PY)_SRC_PATH = $(SRC_PATH)/sonic-yang-mgmt $(SONIC_YANG_MGMT_PY)_PYTHON_VERSION = 2 -$(SONIC_YANG_MGMT_PY)_DEBS_DEPENDS = $(LIBYANG) -$(SONIC_YANG_MGMT_PY)_DEPENDS = $(SONIC_YANG_MODELS_PY3) +$(SONIC_YANG_MGMT_PY)_DEBS_DEPENDS = $(LIBYANG) $(LIBYANG_CPP) $(LIBYANG_PY2) \ + $(LIBYANG_PY3) +$(SONIC_YANG_MGMT_PY)_DEPENDS = $(SONIC_YANG_MODELS_PY3) +$(SONIC_YANG_MGMT_PY)_RDEPENDS = $(SONIC_YANG_MODELS_PY3) $(LIBYANG) \ + $(LIBYANG_CPP) $(LIBYANG_PY2) SONIC_PYTHON_WHEELS += $(SONIC_YANG_MGMT_PY) diff --git a/rules/sonic-yang-models-py3.mk b/rules/sonic-yang-models-py3.mk index d2bd01bb9005..8c11a921a979 100644 --- a/rules/sonic-yang-models-py3.mk +++ b/rules/sonic-yang-models-py3.mk @@ -1,7 +1,8 @@ SONIC_YANG_MODELS_PY3 = sonic_yang_models-1.0-py3-none-any.whl $(SONIC_YANG_MODELS_PY3)_SRC_PATH = $(SRC_PATH)/sonic-yang-models $(SONIC_YANG_MODELS_PY3)_PYTHON_VERSION = 3 -$(SONIC_YANG_MODELS_PY3)_DEBS_DEPENDS = $(LIBYANG) +$(SONIC_YANG_MODELS_PY3)_DEBS_DEPENDS = $(LIBYANG) $(LIBYANG_CPP) \ + $(LIBYANG_PY2) $(LIBYANG_PY3) SONIC_PYTHON_WHEELS += $(SONIC_YANG_MODELS_PY3) export SONIC_YANG_MODELS_PY3 diff --git a/src/sonic-yang-mgmt/setup.py b/src/sonic-yang-mgmt/setup.py index ab8fafa1ebfb..63ea0640f899 100644 --- a/src/sonic-yang-mgmt/setup.py +++ b/src/sonic-yang-mgmt/setup.py @@ -5,25 +5,10 @@ from setuptools import setup, find_packages from setuptools.command.build_py import build_py -from os import system, environ +from os import system from sys import exit import pytest -# find path of pkgs from os environment vars -prefix = '../../'; debs = environ["IMAGE_DISTRO_DEBS_PATH"] -wheels = environ["PYTHON_WHEELS_PATH"] -wheels_path = '{}/{}'.format(prefix, wheels) -deps_path = '{}/{}'.format(prefix, debs) -# dependencies -libyang = '{}/{}'.format(deps_path, environ["LIBYANG"]) -libyangCpp = '{}/{}'.format(deps_path, environ["LIBYANG_CPP"]) -libyangPy2 = '{}/{}'.format(deps_path, environ["LIBYANG_PY2"]) -libyangPy3 = '{}/{}'.format(deps_path, environ["LIBYANG_PY3"]) -sonicYangModels = '{}/{}'.format(wheels_path, environ["SONIC_YANG_MODELS_PY3"]) - -# important reuirements parameters -build_requirements = [libyang, libyangCpp, libyangPy2, libyangPy3, sonicYangModels,] - setup_requirements = ['pytest-runner'] test_requirements = ['pytest>=3'] @@ -37,23 +22,6 @@ class pkgBuild(build_py): """Custom Build PLY""" def run (self): - # install libyang and sonic_yang_models - for req in build_requirements: - if '.deb' in req: - pkg_install_cmd = "sudo dpkg -i {}".format(req) - if (system(pkg_install_cmd)): - print("{} installation failed".format(req)) - exit(1) - else: - print("{} installed".format(req)) - elif '.whl' in req: - pkg_install_cmd = "pip3 install {}".format(req) - if (system(pkg_install_cmd)): - print("{} installation failed".format(req)) - exit(1) - else: - print("{} installed".format(req)) - # run pytest for libyang python APIs self.pytest_args = [] errno = pytest.main(self.pytest_args) diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index d614d9bfedfb..6add4c22bffa 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -5,21 +5,9 @@ from setuptools import setup, find_packages from setuptools.command.build_py import build_py -from os import system, environ +from os import system from sys import exit -# find path of pkgs from environment vars -prefix = '../../'; debs = environ["IMAGE_DISTRO_DEBS_PATH"] -deps_path = '{}/{}'.format(prefix, debs) -# dependencies -libyang = '{}/{}'.format(deps_path, environ["LIBYANG"]) -libyangCpp = '{}/{}'.format(deps_path, environ["LIBYANG_CPP"]) -libyangPy2 = '{}/{}'.format(deps_path, environ["LIBYANG_PY2"]) -libyangPy3 = '{}/{}'.format(deps_path, environ["LIBYANG_PY3"]) - -# important reuirements parameters -build_requirements = [libyang, libyangCpp, libyangPy2, libyangPy3,] - setup_requirements = ['pytest-runner'] test_requirements = ['pytest>=3'] @@ -33,16 +21,6 @@ class pkgBuild(build_py): """Custom Build PLY""" def run (self): - # install libyang - for req in build_requirements: - if '.deb'in req: - pkg_install_cmd = "sudo dpkg -i {}".format(req) - if (system(pkg_install_cmd)): - print("{} installation failed".format(req)) - exit(1) - else: - print("{} installed".format(req)) - # json file for YANG model test cases. test_yangJson_file = './tests/yang_model_tests/yangTest.json' # YANG models are in below dir @@ -53,7 +31,6 @@ def run (self): test_yang_cmd = "python {} -f {} -y {}".format(yang_test_py, test_yangJson_file, yang_model_dir) if (system(test_yang_cmd)): print("YANG Tests failed\n") - # below line will be uncommented after libyang python support PR # exit(1) else: print("YANG Tests passed\n") From d35a8a380003745278998b66114baf776f7e0584 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Thu, 28 May 2020 14:59:00 -0700 Subject: [PATCH 0740/1427] [arista]: Add SmartsvilleDDBK and SmartsvilleBkMs (#4662) Co-authored-by: Boyang Yu --- device/arista/x86_64-arista_7280cr3_32d4 | 1 - .../jr2-a7280cr3-32d4-40x100G.config.bcm | 769 ++++++++++++++++++ .../Arista-7280CR3-C40/port_config.ini | 41 + .../Arista-7280CR3-C40/sai.profile | 1 + .../x86_64-arista_7280cr3_32d4/default_sku | 1 + .../x86_64-arista_7280cr3_32d4/fancontrol | 1 + .../platform_reboot | 1 + .../arista/x86_64-arista_7280cr3_32d4/plugins | 1 + .../x86_64-arista_7280cr3_32d4/sensors.conf | 1 + device/arista/x86_64-arista_7280cr3k_32d4 | 1 + files/Aboot/boot0.j2 | 4 + 11 files changed, 821 insertions(+), 1 deletion(-) delete mode 120000 device/arista/x86_64-arista_7280cr3_32d4 create mode 100644 device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/jr2-a7280cr3-32d4-40x100G.config.bcm create mode 100644 device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/port_config.ini create mode 100644 device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile create mode 100644 device/arista/x86_64-arista_7280cr3_32d4/default_sku create mode 120000 device/arista/x86_64-arista_7280cr3_32d4/fancontrol create mode 120000 device/arista/x86_64-arista_7280cr3_32d4/platform_reboot create mode 120000 device/arista/x86_64-arista_7280cr3_32d4/plugins create mode 120000 device/arista/x86_64-arista_7280cr3_32d4/sensors.conf create mode 120000 device/arista/x86_64-arista_7280cr3k_32d4 diff --git a/device/arista/x86_64-arista_7280cr3_32d4 b/device/arista/x86_64-arista_7280cr3_32d4 deleted file mode 120000 index d6e2ddbb64bd..000000000000 --- a/device/arista/x86_64-arista_7280cr3_32d4 +++ /dev/null @@ -1 +0,0 @@ -x86_64-arista_7280cr3_32p4 \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/jr2-a7280cr3-32d4-40x100G.config.bcm b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/jr2-a7280cr3-32d4-40x100G.config.bcm new file mode 100644 index 000000000000..4467d5d033ce --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/jr2-a7280cr3-32d4-40x100G.config.bcm @@ -0,0 +1,769 @@ +soc_family.BCM8869X=BCM8869X + +custom_feature_ucode_path=u_code_db2pem.txt +system_headers_mode=1 +suppress_unknown_prop_warnings=1 +l4_protocols_load_balancing_enable=1 +fabric_logical_port_base=512 +trunk_group_max_members=128 +num_olp_tm_ports.BCM8869X=1 + +ucode_port_0.BCM8869X=CPU.0:core_0.0 +ucode_port_200.BCM8869X=CPU.8:core_1.200 +ucode_port_201.BCM8869X=CPU.16:core_0.201 +ucode_port_202.BCM8869X=CPU.24:core_1.202 +ucode_port_203.BCM8869X=CPU.32:core_0.203 + +port_init_speed_xe.BCM8869X=10000 +port_init_speed_xl.BCM8869X=40000 +port_init_speed_le.BCM8869X=50000 +port_init_speed_ce.BCM8869X=100000 +port_init_speed_cc.BCM8869X=200000 +port_init_speed_cd.BCM8869X=400000 +port_init_speed_il.BCM8869X=10312 + +port_init_cl72=0 + +serdes_tx_taps_1=pam4:-16:64:0:3:0:0 +serdes_tx_taps_2=pam4:-16:64:0:3:0:0 +serdes_tx_taps_3=pam4:-16:64:0:3:0:0 +serdes_tx_taps_4=pam4:-16:64:0:3:0:0 +serdes_tx_taps_5=pam4:-16:64:0:3:0:0 +serdes_tx_taps_6=pam4:-16:64:0:3:0:0 +serdes_tx_taps_7=pam4:-16:64:0:3:0:0 +serdes_tx_taps_8=pam4:-16:64:0:3:0:0 +serdes_tx_taps_9=pam4:-8:60:0:0:0:0 +serdes_tx_taps_10=pam4:-8:60:0:0:0:0 +serdes_tx_taps_11=pam4:-8:60:0:0:0:0 +serdes_tx_taps_12=pam4:-8:60:0:0:0:0 +serdes_tx_taps_13=pam4:-8:60:0:0:0:0 +serdes_tx_taps_14=pam4:-8:60:0:0:0:0 +serdes_tx_taps_15=pam4:-8:60:0:0:0:0 +serdes_tx_taps_16=pam4:-8:60:0:0:0:0 +serdes_tx_taps_17=pam4:-8:60:0:0:0:0 +serdes_tx_taps_18=pam4:-8:60:0:0:0:0 +serdes_tx_taps_19=pam4:-8:60:0:0:0:0 +serdes_tx_taps_20=pam4:-8:60:0:0:0:0 +serdes_tx_taps_21=pam4:-8:60:0:0:0:0 +serdes_tx_taps_22=pam4:-8:60:0:0:0:0 +serdes_tx_taps_23=pam4:-8:60:0:0:0:0 +serdes_tx_taps_24=pam4:-8:60:0:0:0:0 +serdes_tx_taps_25=pam4:-8:60:0:0:0:0 +serdes_tx_taps_26=pam4:-8:60:0:0:0:0 +serdes_tx_taps_27=pam4:-8:60:0:0:0:0 +serdes_tx_taps_28=pam4:-8:60:0:0:0:0 +serdes_tx_taps_29=pam4:-16:60:0:3:0:0 +serdes_tx_taps_30=pam4:-16:60:0:3:0:0 +serdes_tx_taps_31=pam4:-16:60:0:3:0:0 +serdes_tx_taps_32=pam4:-16:60:0:3:0:0 +serdes_tx_taps_33=nrz:0:71:-16:-5:0:0 +serdes_tx_taps_34=nrz:0:71:-16:-5:0:0 +serdes_tx_taps_35=nrz:0:78:-22:-4:0:0 +serdes_tx_taps_36=nrz:0:78:-22:-4:0:0 +serdes_tx_taps_37=nrz:0:72:-18:-5:0:0 +serdes_tx_taps_38=nrz:0:72:-18:-5:0:0 +serdes_tx_taps_39=nrz:0:68:-17:-6:0:0 +serdes_tx_taps_40=nrz:0:68:-17:-6:0:0 + +ucode_port_100.BCM8869X=RCY_MIRROR.0:core_0.100 +ucode_port_101.BCM8869X=RCY_MIRROR.1:core_0.101 +ucode_port_102.BCM8869X=RCY_MIRROR.2:core_0.102 +ucode_port_103.BCM8869X=RCY_MIRROR.3:core_0.103 +ucode_port_104.BCM8869X=RCY_MIRROR.4:core_0.104 +ucode_port_105.BCM8869X=RCY_MIRROR.5:core_0.105 +ucode_port_106.BCM8869X=RCY_MIRROR.6:core_0.106 +ucode_port_107.BCM8869X=RCY_MIRROR.7:core_0.107 +ucode_port_108.BCM8869X=RCY_MIRROR.8:core_0.108 +ucode_port_109.BCM8869X=RCY_MIRROR.9:core_0.109 +ucode_port_110.BCM8869X=RCY_MIRROR.10:core_0.110 +ucode_port_111.BCM8869X=RCY_MIRROR.11:core_0.111 +ucode_port_112.BCM8869X=RCY_MIRROR.12:core_0.112 +ucode_port_113.BCM8869X=RCY_MIRROR.13:core_0.113 +ucode_port_114.BCM8869X=RCY_MIRROR.14:core_0.114 +ucode_port_115.BCM8869X=RCY_MIRROR.15:core_0.115 +ucode_port_116.BCM8869X=RCY_MIRROR.16:core_0.116 +ucode_port_117.BCM8869X=RCY_MIRROR.17:core_0.117 +ucode_port_118.BCM8869X=RCY_MIRROR.18:core_0.118 +ucode_port_119.BCM8869X=RCY_MIRROR.19:core_0.119 +ucode_port_120.BCM8869X=RCY_MIRROR.0:core_1.120 +ucode_port_121.BCM8869X=RCY_MIRROR.1:core_1.121 +ucode_port_122.BCM8869X=RCY_MIRROR.2:core_1.122 +ucode_port_123.BCM8869X=RCY_MIRROR.3:core_1.123 +ucode_port_124.BCM8869X=RCY_MIRROR.4:core_1.124 +ucode_port_125.BCM8869X=RCY_MIRROR.5:core_1.125 +ucode_port_126.BCM8869X=RCY_MIRROR.6:core_1.126 +ucode_port_127.BCM8869X=RCY_MIRROR.7:core_1.127 +ucode_port_128.BCM8869X=RCY_MIRROR.8:core_1.128 +ucode_port_129.BCM8869X=RCY_MIRROR.9:core_1.129 +ucode_port_130.BCM8869X=RCY_MIRROR.10:core_1.130 +ucode_port_131.BCM8869X=RCY_MIRROR.11:core_1.131 +ucode_port_132.BCM8869X=RCY_MIRROR.12:core_1.132 +ucode_port_133.BCM8869X=RCY_MIRROR.13:core_1.133 +ucode_port_134.BCM8869X=RCY_MIRROR.14:core_1.134 +ucode_port_135.BCM8869X=RCY_MIRROR.15:core_1.135 +ucode_port_136.BCM8869X=RCY_MIRROR.16:core_1.136 +ucode_port_137.BCM8869X=RCY_MIRROR.17:core_1.137 +ucode_port_138.BCM8869X=RCY_MIRROR.18:core_1.138 +ucode_port_139.BCM8869X=RCY_MIRROR.19:core_1.139 + +port_priorities.BCM8869X=8 + +ucode_port_240.BCM8869X=OLP:core_0.240 + +sw_state_max_size.BCM8869X=750000000 + +stable_location.BCM8869X=4 +stable_location.BCM8869X_ADAPTER=3 + +stable_filename.BCM8869X_ADAPTER=warmboot_data_0 +stable_filename=/dev/shm/warmboot_data_0 +stable_filename.1=/dev/shm/warmboot_data_1 +stable_filename.2=/dev/shm/warmboot_data_2 + +stable_size.BCM8869X=800000000 + +tm_port_header_type_in_0.BCM8869X=INJECTED_2 +tm_port_header_type_out_0.BCM8869X=CPU + +tm_port_header_type_in_200.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_200.BCM8869X=ETH +tm_port_header_type_in_201.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_201.BCM8869X=ETH +tm_port_header_type_in_202.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_202.BCM8869X=ETH +tm_port_header_type_in_203.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_203.BCM8869X=ETH + +sat_enable.BCM8869X=1 +tm_port_header_type_out_218.BCM8869X=CPU +tm_port_header_type_in_218.BCM8869X=INJECTED_2 + +tm_port_header_type_in_232.BCM8869X=INJECTED_2 +tm_port_header_type_out_232.BCM8869X=CPU +tm_port_header_type_in_233.BCM8869X=INJECTED_2 +tm_port_header_type_out_233.BCM8869X=CPU + +tm_port_header_type_in_240.BCM8869X=INJECTED_2 +tm_port_header_type_out_240.BCM8869X=RAW + +dtm_flow_mapping_mode_region_64.BCM8869X=3 +dtm_flow_mapping_mode_region_65.BCM8869X=3 +dtm_flow_mapping_mode_region_66.BCM8869X=3 +dtm_flow_mapping_mode_region_67.BCM8869X=3 +dtm_flow_mapping_mode_region_68.BCM8869X=3 +dtm_flow_mapping_mode_region_69.BCM8869X=3 +dtm_flow_mapping_mode_region_70.BCM8869X=3 +dtm_flow_mapping_mode_region_71.BCM8869X=3 +dtm_flow_mapping_mode_region_72.BCM8869X=3 +dtm_flow_mapping_mode_region_73.BCM8869X=3 +dtm_flow_mapping_mode_region_74.BCM8869X=3 +dtm_flow_mapping_mode_region_75.BCM8869X=3 +dtm_flow_mapping_mode_region_76.BCM8869X=3 +dtm_flow_mapping_mode_region_77.BCM8869X=3 +dtm_flow_mapping_mode_region_78.BCM8869X=3 +dtm_flow_mapping_mode_region_79.BCM8869X=7 +dtm_flow_mapping_mode_region_80.BCM8869X=3 +dtm_flow_mapping_mode_region_81.BCM8869X=1 +dtm_flow_mapping_mode_region_82.BCM8869X=3 +dtm_flow_mapping_mode_region_83.BCM8869X=3 +dtm_flow_mapping_mode_region_84.BCM8869X=3 +dtm_flow_mapping_mode_region_85.BCM8869X=3 +dtm_flow_mapping_mode_region_86.BCM8869X=3 +dtm_flow_mapping_mode_region_87.BCM8869X=3 +dtm_flow_mapping_mode_region_88.BCM8869X=3 +dtm_flow_mapping_mode_region_89.BCM8869X=3 +dtm_flow_mapping_mode_region_90.BCM8869X=3 +dtm_flow_mapping_mode_region_91.BCM8869X=3 +dtm_flow_mapping_mode_region_92.BCM8869X=3 +dtm_flow_mapping_mode_region_93.BCM8869X=3 +dtm_flow_mapping_mode_region_94.BCM8869X=3 + +dtm_flow_nof_remote_cores_region_1.BCM8869X=2 +dtm_flow_nof_remote_cores_region_2.BCM8869X=2 +dtm_flow_nof_remote_cores_region_3.BCM8869X=2 +dtm_flow_nof_remote_cores_region_4.BCM8869X=2 +dtm_flow_nof_remote_cores_region_5.BCM8869X=2 +dtm_flow_nof_remote_cores_region_6.BCM8869X=2 +dtm_flow_nof_remote_cores_region_7.BCM8869X=2 +dtm_flow_nof_remote_cores_region_8.BCM8869X=2 +dtm_flow_nof_remote_cores_region_9.BCM8869X=2 +dtm_flow_nof_remote_cores_region_10.BCM8869X=2 +dtm_flow_nof_remote_cores_region_11.BCM8869X=2 +dtm_flow_nof_remote_cores_region_12.BCM8869X=2 +dtm_flow_nof_remote_cores_region_13.BCM8869X=2 +dtm_flow_nof_remote_cores_region_14.BCM8869X=2 +dtm_flow_nof_remote_cores_region_15.BCM8869X=2 +dtm_flow_nof_remote_cores_region_16.BCM8869X=2 +dtm_flow_nof_remote_cores_region_17.BCM8869X=2 +dtm_flow_nof_remote_cores_region_18.BCM8869X=2 +dtm_flow_nof_remote_cores_region_19.BCM8869X=2 +dtm_flow_nof_remote_cores_region_20.BCM8869X=2 +dtm_flow_nof_remote_cores_region_21.BCM8869X=2 +dtm_flow_nof_remote_cores_region_22.BCM8869X=2 +dtm_flow_nof_remote_cores_region_23.BCM8869X=2 +dtm_flow_nof_remote_cores_region_24.BCM8869X=2 +dtm_flow_nof_remote_cores_region_25.BCM8869X=2 +dtm_flow_nof_remote_cores_region_26.BCM8869X=2 +dtm_flow_nof_remote_cores_region_27.BCM8869X=2 +dtm_flow_nof_remote_cores_region_28.BCM8869X=2 +dtm_flow_nof_remote_cores_region_29.BCM8869X=2 +dtm_flow_nof_remote_cores_region_30.BCM8869X=2 +dtm_flow_nof_remote_cores_region_31.BCM8869X=2 +dtm_flow_nof_remote_cores_region_32.BCM8869X=2 +dtm_flow_nof_remote_cores_region_33.BCM8869X=2 +dtm_flow_nof_remote_cores_region_34.BCM8869X=2 +dtm_flow_nof_remote_cores_region_35.BCM8869X=2 +dtm_flow_nof_remote_cores_region_36.BCM8869X=2 +dtm_flow_nof_remote_cores_region_37.BCM8869X=2 +dtm_flow_nof_remote_cores_region_38.BCM8869X=2 +dtm_flow_nof_remote_cores_region_39.BCM8869X=2 +dtm_flow_nof_remote_cores_region_40.BCM8869X=2 +dtm_flow_nof_remote_cores_region_41.BCM8869X=2 +dtm_flow_nof_remote_cores_region_42.BCM8869X=2 +dtm_flow_nof_remote_cores_region_43.BCM8869X=2 +dtm_flow_nof_remote_cores_region_44.BCM8869X=2 +dtm_flow_nof_remote_cores_region_45.BCM8869X=2 +dtm_flow_nof_remote_cores_region_46.BCM8869X=2 +dtm_flow_nof_remote_cores_region_47.BCM8869X=2 +dtm_flow_nof_remote_cores_region_48.BCM8869X=2 +dtm_flow_nof_remote_cores_region_49.BCM8869X=2 +dtm_flow_nof_remote_cores_region_50.BCM8869X=2 +dtm_flow_nof_remote_cores_region_51.BCM8869X=2 +dtm_flow_nof_remote_cores_region_52.BCM8869X=2 +dtm_flow_nof_remote_cores_region_53.BCM8869X=2 +dtm_flow_nof_remote_cores_region_54.BCM8869X=2 +dtm_flow_nof_remote_cores_region_55.BCM8869X=2 +dtm_flow_nof_remote_cores_region_56.BCM8869X=2 +dtm_flow_nof_remote_cores_region_57.BCM8869X=2 +dtm_flow_nof_remote_cores_region_58.BCM8869X=2 +dtm_flow_nof_remote_cores_region_59.BCM8869X=2 +dtm_flow_nof_remote_cores_region_60.BCM8869X=2 + +mdb_profile.BCM8869X=l3-xl + +outlif_logical_to_physical_phase_map_1=S1 +outlif_logical_to_physical_phase_map_2=L1 +outlif_logical_to_physical_phase_map_3=XL +outlif_logical_to_physical_phase_map_4=L2 +outlif_logical_to_physical_phase_map_5=M1 +outlif_logical_to_physical_phase_map_6=M2 +outlif_logical_to_physical_phase_map_7=M3 +outlif_logical_to_physical_phase_map_8=S2 + +outlif_physical_phase_data_granularity_S1=60 +outlif_physical_phase_data_granularity_S2=60 +outlif_physical_phase_data_granularity_M1=60 +outlif_physical_phase_data_granularity_M2=60 +outlif_physical_phase_data_granularity_M3=60 +outlif_physical_phase_data_granularity_L1=60 +outlif_physical_phase_data_granularity_L2=60 +outlif_physical_phase_data_granularity_XL=60 + +port_init_speed_fabric.BCM8869X=53125 + +fabric_connect_mode.BCM8869X=SINGLE_FAP +protocol_traps_mode.BCM8869X=IN_LIF + +schan_intr_enable.BCM8869X=0 +tdma_intr_enable.BCM8869X=0 +tslam_intr_enable.BCM8869X=0 +miim_intr_enable.BCM8869X=0 +schan_timeout_usec.BCM8869X=300000 +tdma_timeout_usec.BCM8869X=1000000 +tslam_timeout_usec.BCM8869X=1000000 + +appl_enable_intr_init.BCM8869X=1 +polled_irq_mode.BCM8869X=1 +polled_irq_delay.BCM8869X=1000 + +bcm_stat_interval.BCM8869X=1000 + +mem_cache_enable_ecc.BCM8869X=1 +mem_cache_enable_parity.BCM8869X=1 + +serdes_nif_clk_freq_in.BCM8869X_A0=2 +serdes_nif_clk_freq_out.BCM8869X_A0=1 +serdes_fabric_clk_freq_in.BCM8869X_A0=2 +serdes_fabric_clk_freq_out.BCM8869X_A0=1 + +serdes_nif_clk_freq_in.BCM8869X=1 +serdes_nif_clk_freq_out.BCM8869X=bypass +serdes_fabric_clk_freq_in.BCM8869X=1 +serdes_fabric_clk_freq_out.BCM8869X=bypass + +dram_phy_tune_mode_on_init.BCM8869X=RUN_TUNE + +dport_map_direct.BCM8869X=1 + +pmf_sexem3_stage.BCM8869X=IPMF3 + +lane_to_serdes_map_fabric_lane0.0=rx0:tx0 +lane_to_serdes_map_fabric_lane1.0=rx1:tx1 +lane_to_serdes_map_fabric_lane2.0=rx2:tx2 +lane_to_serdes_map_fabric_lane3.0=rx3:tx3 +lane_to_serdes_map_fabric_lane4.0=rx4:tx4 +lane_to_serdes_map_fabric_lane5.0=rx5:tx5 +lane_to_serdes_map_fabric_lane6.0=rx6:tx6 +lane_to_serdes_map_fabric_lane7.0=rx7:tx7 +lane_to_serdes_map_fabric_lane8.0=rx8:tx8 +lane_to_serdes_map_fabric_lane9.0=rx9:tx9 +lane_to_serdes_map_fabric_lane10.0=rx10:tx10 +lane_to_serdes_map_fabric_lane11.0=rx11:tx11 +lane_to_serdes_map_fabric_lane12.0=rx12:tx12 +lane_to_serdes_map_fabric_lane13.0=rx13:tx13 +lane_to_serdes_map_fabric_lane14.0=rx14:tx14 +lane_to_serdes_map_fabric_lane15.0=rx15:tx15 +lane_to_serdes_map_fabric_lane16.0=rx16:tx16 +lane_to_serdes_map_fabric_lane17.0=rx17:tx17 +lane_to_serdes_map_fabric_lane18.0=rx18:tx18 +lane_to_serdes_map_fabric_lane19.0=rx19:tx19 +lane_to_serdes_map_fabric_lane20.0=rx20:tx20 +lane_to_serdes_map_fabric_lane21.0=rx21:tx21 +lane_to_serdes_map_fabric_lane22.0=rx22:tx22 +lane_to_serdes_map_fabric_lane23.0=rx23:tx23 +lane_to_serdes_map_fabric_lane24.0=rx24:tx24 +lane_to_serdes_map_fabric_lane25.0=rx25:tx25 +lane_to_serdes_map_fabric_lane26.0=rx26:tx26 +lane_to_serdes_map_fabric_lane27.0=rx27:tx27 +lane_to_serdes_map_fabric_lane28.0=rx28:tx28 +lane_to_serdes_map_fabric_lane29.0=rx29:tx29 +lane_to_serdes_map_fabric_lane30.0=rx30:tx30 +lane_to_serdes_map_fabric_lane31.0=rx31:tx31 +lane_to_serdes_map_fabric_lane32.0=rx32:tx32 +lane_to_serdes_map_fabric_lane33.0=rx33:tx33 +lane_to_serdes_map_fabric_lane34.0=rx34:tx34 +lane_to_serdes_map_fabric_lane35.0=rx35:tx35 +lane_to_serdes_map_fabric_lane36.0=rx36:tx36 +lane_to_serdes_map_fabric_lane37.0=rx37:tx37 +lane_to_serdes_map_fabric_lane38.0=rx38:tx38 +lane_to_serdes_map_fabric_lane39.0=rx39:tx39 +lane_to_serdes_map_fabric_lane40.0=rx40:tx40 +lane_to_serdes_map_fabric_lane41.0=rx41:tx41 +lane_to_serdes_map_fabric_lane42.0=rx42:tx42 +lane_to_serdes_map_fabric_lane43.0=rx43:tx43 +lane_to_serdes_map_fabric_lane44.0=rx44:tx44 +lane_to_serdes_map_fabric_lane45.0=rx45:tx45 +lane_to_serdes_map_fabric_lane46.0=rx46:tx46 +lane_to_serdes_map_fabric_lane47.0=rx47:tx47 +lane_to_serdes_map_fabric_lane48.0=rx48:tx48 +lane_to_serdes_map_fabric_lane49.0=rx49:tx49 +lane_to_serdes_map_fabric_lane50.0=rx50:tx50 +lane_to_serdes_map_fabric_lane51.0=rx51:tx51 +lane_to_serdes_map_fabric_lane52.0=rx52:tx52 +lane_to_serdes_map_fabric_lane53.0=rx53:tx53 +lane_to_serdes_map_fabric_lane54.0=rx54:tx54 +lane_to_serdes_map_fabric_lane55.0=rx55:tx55 +lane_to_serdes_map_fabric_lane56.0=rx56:tx56 +lane_to_serdes_map_fabric_lane57.0=rx57:tx57 +lane_to_serdes_map_fabric_lane58.0=rx58:tx58 +lane_to_serdes_map_fabric_lane59.0=rx59:tx59 +lane_to_serdes_map_fabric_lane60.0=rx60:tx60 +lane_to_serdes_map_fabric_lane61.0=rx61:tx61 +lane_to_serdes_map_fabric_lane62.0=rx62:tx62 +lane_to_serdes_map_fabric_lane63.0=rx63:tx63 +lane_to_serdes_map_fabric_lane64.0=rx64:tx64 +lane_to_serdes_map_fabric_lane65.0=rx65:tx65 +lane_to_serdes_map_fabric_lane66.0=rx66:tx66 +lane_to_serdes_map_fabric_lane67.0=rx67:tx67 +lane_to_serdes_map_fabric_lane68.0=rx68:tx68 +lane_to_serdes_map_fabric_lane69.0=rx69:tx69 +lane_to_serdes_map_fabric_lane70.0=rx70:tx70 +lane_to_serdes_map_fabric_lane71.0=rx71:tx71 +lane_to_serdes_map_fabric_lane72.0=rx72:tx72 +lane_to_serdes_map_fabric_lane73.0=rx73:tx73 +lane_to_serdes_map_fabric_lane74.0=rx74:tx74 +lane_to_serdes_map_fabric_lane75.0=rx75:tx75 +lane_to_serdes_map_fabric_lane76.0=rx76:tx76 +lane_to_serdes_map_fabric_lane77.0=rx77:tx77 +lane_to_serdes_map_fabric_lane78.0=rx78:tx78 +lane_to_serdes_map_fabric_lane79.0=rx79:tx79 +lane_to_serdes_map_fabric_lane80.0=rx80:tx80 +lane_to_serdes_map_fabric_lane81.0=rx81:tx81 +lane_to_serdes_map_fabric_lane82.0=rx82:tx82 +lane_to_serdes_map_fabric_lane83.0=rx83:tx83 +lane_to_serdes_map_fabric_lane84.0=rx84:tx84 +lane_to_serdes_map_fabric_lane85.0=rx85:tx85 +lane_to_serdes_map_fabric_lane86.0=rx86:tx86 +lane_to_serdes_map_fabric_lane87.0=rx87:tx87 +lane_to_serdes_map_fabric_lane88.0=rx88:tx88 +lane_to_serdes_map_fabric_lane89.0=rx89:tx89 +lane_to_serdes_map_fabric_lane90.0=rx90:tx90 +lane_to_serdes_map_fabric_lane91.0=rx91:tx91 +lane_to_serdes_map_fabric_lane92.0=rx92:tx92 +lane_to_serdes_map_fabric_lane93.0=rx93:tx93 +lane_to_serdes_map_fabric_lane94.0=rx94:tx94 +lane_to_serdes_map_fabric_lane95.0=rx95:tx95 +lane_to_serdes_map_fabric_lane96.0=rx96:tx96 +lane_to_serdes_map_fabric_lane97.0=rx97:tx97 +lane_to_serdes_map_fabric_lane98.0=rx98:tx98 +lane_to_serdes_map_fabric_lane99.0=rx99:tx99 +lane_to_serdes_map_fabric_lane100.0=rx100:tx100 +lane_to_serdes_map_fabric_lane101.0=rx101:tx101 +lane_to_serdes_map_fabric_lane102.0=rx102:tx102 +lane_to_serdes_map_fabric_lane103.0=rx103:tx103 +lane_to_serdes_map_fabric_lane104.0=rx104:tx104 +lane_to_serdes_map_fabric_lane105.0=rx105:tx105 +lane_to_serdes_map_fabric_lane106.0=rx106:tx106 +lane_to_serdes_map_fabric_lane107.0=rx107:tx107 +lane_to_serdes_map_fabric_lane108.0=rx108:tx108 +lane_to_serdes_map_fabric_lane109.0=rx109:tx109 +lane_to_serdes_map_fabric_lane110.0=rx110:tx110 +lane_to_serdes_map_fabric_lane111.0=rx111:tx111 + +lane_to_serdes_map_nif_lane0.0=rx5:tx7 +lane_to_serdes_map_nif_lane1.0=rx7:tx6 +lane_to_serdes_map_nif_lane2.0=rx4:tx5 +lane_to_serdes_map_nif_lane3.0=rx6:tx4 +lane_to_serdes_map_nif_lane4.0=rx0:tx0 +lane_to_serdes_map_nif_lane5.0=rx1:tx1 +lane_to_serdes_map_nif_lane6.0=rx2:tx3 +lane_to_serdes_map_nif_lane7.0=rx3:tx2 +lane_to_serdes_map_nif_lane8.0=rx13:tx15 +lane_to_serdes_map_nif_lane9.0=rx12:tx14 +lane_to_serdes_map_nif_lane10.0=rx15:tx13 +lane_to_serdes_map_nif_lane11.0=rx14:tx12 +lane_to_serdes_map_nif_lane12.0=rx10:tx10 +lane_to_serdes_map_nif_lane13.0=rx8:tx9 +lane_to_serdes_map_nif_lane14.0=rx9:tx11 +lane_to_serdes_map_nif_lane15.0=rx11:tx8 +lane_to_serdes_map_nif_lane16.0=rx23:tx23 +lane_to_serdes_map_nif_lane17.0=rx21:tx22 +lane_to_serdes_map_nif_lane18.0=rx22:tx21 +lane_to_serdes_map_nif_lane19.0=rx20:tx20 +lane_to_serdes_map_nif_lane20.0=rx16:tx18 +lane_to_serdes_map_nif_lane21.0=rx17:tx17 +lane_to_serdes_map_nif_lane22.0=rx18:tx16 +lane_to_serdes_map_nif_lane23.0=rx19:tx19 +lane_to_serdes_map_nif_lane24.0=rx31:tx31 +lane_to_serdes_map_nif_lane25.0=rx30:tx30 +lane_to_serdes_map_nif_lane26.0=rx29:tx29 +lane_to_serdes_map_nif_lane27.0=rx28:tx28 +lane_to_serdes_map_nif_lane28.0=rx24:tx26 +lane_to_serdes_map_nif_lane29.0=rx26:tx25 +lane_to_serdes_map_nif_lane30.0=rx25:tx24 +lane_to_serdes_map_nif_lane31.0=rx27:tx27 +lane_to_serdes_map_nif_lane32.0=rx38:tx34 +lane_to_serdes_map_nif_lane33.0=rx34:tx39 +lane_to_serdes_map_nif_lane34.0=rx39:tx33 +lane_to_serdes_map_nif_lane35.0=rx32:tx38 +lane_to_serdes_map_nif_lane36.0=rx36:tx35 +lane_to_serdes_map_nif_lane37.0=rx33:tx37 +lane_to_serdes_map_nif_lane38.0=rx37:tx32 +lane_to_serdes_map_nif_lane39.0=rx35:tx36 +lane_to_serdes_map_nif_lane40.0=rx46:tx41 +lane_to_serdes_map_nif_lane41.0=rx41:tx46 +lane_to_serdes_map_nif_lane42.0=rx45:tx42 +lane_to_serdes_map_nif_lane43.0=rx40:tx47 +lane_to_serdes_map_nif_lane44.0=rx47:tx40 +lane_to_serdes_map_nif_lane45.0=rx43:tx44 +lane_to_serdes_map_nif_lane46.0=rx44:tx43 +lane_to_serdes_map_nif_lane47.0=rx42:tx45 +lane_to_serdes_map_nif_lane48.0=rx55:tx55 +lane_to_serdes_map_nif_lane49.0=rx54:tx54 +lane_to_serdes_map_nif_lane50.0=rx53:tx53 +lane_to_serdes_map_nif_lane51.0=rx52:tx52 +lane_to_serdes_map_nif_lane52.0=rx48:tx48 +lane_to_serdes_map_nif_lane53.0=rx49:tx49 +lane_to_serdes_map_nif_lane54.0=rx50:tx50 +lane_to_serdes_map_nif_lane55.0=rx51:tx51 +lane_to_serdes_map_nif_lane56.0=rx60:tx60 +lane_to_serdes_map_nif_lane57.0=rx61:tx61 +lane_to_serdes_map_nif_lane58.0=rx62:tx63 +lane_to_serdes_map_nif_lane59.0=rx63:tx62 +lane_to_serdes_map_nif_lane60.0=rx58:tx59 +lane_to_serdes_map_nif_lane61.0=rx59:tx56 +lane_to_serdes_map_nif_lane62.0=rx57:tx58 +lane_to_serdes_map_nif_lane63.0=rx56:tx57 +lane_to_serdes_map_nif_lane64.0=rx68:tx69 +lane_to_serdes_map_nif_lane65.0=rx69:tx68 +lane_to_serdes_map_nif_lane66.0=rx70:tx71 +lane_to_serdes_map_nif_lane67.0=rx71:tx70 +lane_to_serdes_map_nif_lane68.0=rx67:tx64 +lane_to_serdes_map_nif_lane69.0=rx66:tx67 +lane_to_serdes_map_nif_lane70.0=rx65:tx65 +lane_to_serdes_map_nif_lane71.0=rx64:tx66 +lane_to_serdes_map_nif_lane72.0=rx78:tx76 +lane_to_serdes_map_nif_lane73.0=rx76:tx77 +lane_to_serdes_map_nif_lane74.0=rx79:tx78 +lane_to_serdes_map_nif_lane75.0=rx77:tx79 +lane_to_serdes_map_nif_lane76.0=rx75:tx72 +lane_to_serdes_map_nif_lane77.0=rx74:tx75 +lane_to_serdes_map_nif_lane78.0=rx73:tx73 +lane_to_serdes_map_nif_lane79.0=rx72:tx74 +lane_to_serdes_map_nif_lane80.0=rx83:tx84 +lane_to_serdes_map_nif_lane81.0=rx87:tx80 +lane_to_serdes_map_nif_lane82.0=rx82:tx85 +lane_to_serdes_map_nif_lane83.0=rx84:tx83 +lane_to_serdes_map_nif_lane84.0=rx80:tx86 +lane_to_serdes_map_nif_lane85.0=rx85:tx81 +lane_to_serdes_map_nif_lane86.0=rx81:tx87 +lane_to_serdes_map_nif_lane87.0=rx86:tx82 +lane_to_serdes_map_nif_lane88.0=rx90:tx93 +lane_to_serdes_map_nif_lane89.0=rx88:tx91 +lane_to_serdes_map_nif_lane90.0=rx91:tx92 +lane_to_serdes_map_nif_lane91.0=rx95:tx88 +lane_to_serdes_map_nif_lane92.0=rx94:tx95 +lane_to_serdes_map_nif_lane93.0=rx93:tx90 +lane_to_serdes_map_nif_lane94.0=rx89:tx94 +lane_to_serdes_map_nif_lane95.0=rx92:tx89 + +phy_rx_polarity_flip_phy0=0 +phy_rx_polarity_flip_phy1=1 +phy_rx_polarity_flip_phy2=0 +phy_rx_polarity_flip_phy3=0 +phy_rx_polarity_flip_phy4=0 +phy_rx_polarity_flip_phy5=0 +phy_rx_polarity_flip_phy6=0 +phy_rx_polarity_flip_phy7=0 +phy_rx_polarity_flip_phy8=1 +phy_rx_polarity_flip_phy9=1 +phy_rx_polarity_flip_phy10=1 +phy_rx_polarity_flip_phy11=1 +phy_rx_polarity_flip_phy12=0 +phy_rx_polarity_flip_phy13=1 +phy_rx_polarity_flip_phy14=1 +phy_rx_polarity_flip_phy15=1 +phy_rx_polarity_flip_phy16=0 +phy_rx_polarity_flip_phy17=1 +phy_rx_polarity_flip_phy18=1 +phy_rx_polarity_flip_phy19=0 +phy_rx_polarity_flip_phy20=0 +phy_rx_polarity_flip_phy21=0 +phy_rx_polarity_flip_phy22=0 +phy_rx_polarity_flip_phy23=0 +phy_rx_polarity_flip_phy24=1 +phy_rx_polarity_flip_phy25=1 +phy_rx_polarity_flip_phy26=1 +phy_rx_polarity_flip_phy27=0 +phy_rx_polarity_flip_phy28=0 +phy_rx_polarity_flip_phy29=1 +phy_rx_polarity_flip_phy30=1 +phy_rx_polarity_flip_phy31=0 +phy_rx_polarity_flip_phy32=1 +phy_rx_polarity_flip_phy33=0 +phy_rx_polarity_flip_phy34=0 +phy_rx_polarity_flip_phy35=0 +phy_rx_polarity_flip_phy36=0 +phy_rx_polarity_flip_phy37=1 +phy_rx_polarity_flip_phy38=0 +phy_rx_polarity_flip_phy39=1 + +phy_rx_polarity_flip_phy40=1 +phy_rx_polarity_flip_phy41=1 +phy_rx_polarity_flip_phy42=0 +phy_rx_polarity_flip_phy43=0 +phy_rx_polarity_flip_phy44=1 +phy_rx_polarity_flip_phy45=0 +phy_rx_polarity_flip_phy46=1 +phy_rx_polarity_flip_phy47=0 + +phy_rx_polarity_flip_phy48=1 +phy_rx_polarity_flip_phy49=1 +phy_rx_polarity_flip_phy50=1 +phy_rx_polarity_flip_phy51=1 +phy_rx_polarity_flip_phy52=0 +phy_rx_polarity_flip_phy53=0 +phy_rx_polarity_flip_phy54=0 +phy_rx_polarity_flip_phy55=0 +phy_rx_polarity_flip_phy56=0 +phy_rx_polarity_flip_phy57=0 +phy_rx_polarity_flip_phy58=0 +phy_rx_polarity_flip_phy59=0 +phy_rx_polarity_flip_phy60=1 +phy_rx_polarity_flip_phy61=1 +phy_rx_polarity_flip_phy62=1 +phy_rx_polarity_flip_phy63=1 +phy_rx_polarity_flip_phy64=1 +phy_rx_polarity_flip_phy65=1 +phy_rx_polarity_flip_phy66=1 +phy_rx_polarity_flip_phy67=1 +phy_rx_polarity_flip_phy68=1 +phy_rx_polarity_flip_phy69=1 +phy_rx_polarity_flip_phy70=1 +phy_rx_polarity_flip_phy71=1 +phy_rx_polarity_flip_phy72=1 +phy_rx_polarity_flip_phy73=0 +phy_rx_polarity_flip_phy74=0 +phy_rx_polarity_flip_phy75=1 +phy_rx_polarity_flip_phy76=1 +phy_rx_polarity_flip_phy77=1 +phy_rx_polarity_flip_phy78=1 +phy_rx_polarity_flip_phy79=1 + +phy_rx_polarity_flip_phy80=1 +phy_rx_polarity_flip_phy81=1 +phy_rx_polarity_flip_phy82=1 +phy_rx_polarity_flip_phy83=0 +phy_rx_polarity_flip_phy84=1 +phy_rx_polarity_flip_phy85=0 +phy_rx_polarity_flip_phy86=1 +phy_rx_polarity_flip_phy87=0 + +phy_rx_polarity_flip_phy88=1 +phy_rx_polarity_flip_phy89=0 +phy_rx_polarity_flip_phy90=0 +phy_rx_polarity_flip_phy91=1 +phy_rx_polarity_flip_phy92=1 +phy_rx_polarity_flip_phy93=0 +phy_rx_polarity_flip_phy94=0 +phy_rx_polarity_flip_phy95=1 + +phy_tx_polarity_flip_phy0=1 +phy_tx_polarity_flip_phy1=1 +phy_tx_polarity_flip_phy2=1 +phy_tx_polarity_flip_phy3=1 +phy_tx_polarity_flip_phy4=1 +phy_tx_polarity_flip_phy5=1 +phy_tx_polarity_flip_phy6=0 +phy_tx_polarity_flip_phy7=0 +phy_tx_polarity_flip_phy8=1 +phy_tx_polarity_flip_phy9=1 +phy_tx_polarity_flip_phy10=1 +phy_tx_polarity_flip_phy11=1 +phy_tx_polarity_flip_phy12=1 +phy_tx_polarity_flip_phy13=1 +phy_tx_polarity_flip_phy14=0 +phy_tx_polarity_flip_phy15=0 +phy_tx_polarity_flip_phy16=0 +phy_tx_polarity_flip_phy17=0 +phy_tx_polarity_flip_phy18=0 +phy_tx_polarity_flip_phy19=0 +phy_tx_polarity_flip_phy20=0 +phy_tx_polarity_flip_phy21=0 +phy_tx_polarity_flip_phy22=0 +phy_tx_polarity_flip_phy23=0 +phy_tx_polarity_flip_phy24=0 +phy_tx_polarity_flip_phy25=0 +phy_tx_polarity_flip_phy26=0 +phy_tx_polarity_flip_phy27=0 +phy_tx_polarity_flip_phy28=0 +phy_tx_polarity_flip_phy29=0 +phy_tx_polarity_flip_phy30=0 +phy_tx_polarity_flip_phy31=0 +phy_tx_polarity_flip_phy32=1 +phy_tx_polarity_flip_phy33=0 +phy_tx_polarity_flip_phy34=0 +phy_tx_polarity_flip_phy35=1 +phy_tx_polarity_flip_phy36=1 +phy_tx_polarity_flip_phy37=0 +phy_tx_polarity_flip_phy38=1 +phy_tx_polarity_flip_phy39=0 + +phy_tx_polarity_flip_phy40=0 +phy_tx_polarity_flip_phy41=1 +phy_tx_polarity_flip_phy42=1 +phy_tx_polarity_flip_phy43=0 +phy_tx_polarity_flip_phy44=1 +phy_tx_polarity_flip_phy45=0 +phy_tx_polarity_flip_phy46=1 +phy_tx_polarity_flip_phy47=0 + +phy_tx_polarity_flip_phy48=0 +phy_tx_polarity_flip_phy49=0 +phy_tx_polarity_flip_phy50=0 +phy_tx_polarity_flip_phy51=0 +phy_tx_polarity_flip_phy52=0 +phy_tx_polarity_flip_phy53=0 +phy_tx_polarity_flip_phy54=0 +phy_tx_polarity_flip_phy55=0 +phy_tx_polarity_flip_phy56=1 +phy_tx_polarity_flip_phy57=1 +phy_tx_polarity_flip_phy58=0 +phy_tx_polarity_flip_phy59=0 +phy_tx_polarity_flip_phy60=1 +phy_tx_polarity_flip_phy61=1 +phy_tx_polarity_flip_phy62=0 +phy_tx_polarity_flip_phy63=0 +phy_tx_polarity_flip_phy64=0 +phy_tx_polarity_flip_phy65=0 +phy_tx_polarity_flip_phy66=0 +phy_tx_polarity_flip_phy67=0 +phy_tx_polarity_flip_phy68=0 +phy_tx_polarity_flip_phy69=0 +phy_tx_polarity_flip_phy70=1 +phy_tx_polarity_flip_phy71=1 +phy_tx_polarity_flip_phy72=1 +phy_tx_polarity_flip_phy73=1 +phy_tx_polarity_flip_phy74=1 +phy_tx_polarity_flip_phy75=1 +phy_tx_polarity_flip_phy76=0 +phy_tx_polarity_flip_phy77=0 +phy_tx_polarity_flip_phy78=1 +phy_tx_polarity_flip_phy79=1 + +phy_tx_polarity_flip_phy80=1 +phy_tx_polarity_flip_phy81=1 +phy_tx_polarity_flip_phy82=0 +phy_tx_polarity_flip_phy83=0 +phy_tx_polarity_flip_phy84=1 +phy_tx_polarity_flip_phy85=1 +phy_tx_polarity_flip_phy86=1 +phy_tx_polarity_flip_phy87=1 + +phy_tx_polarity_flip_phy88=0 +phy_tx_polarity_flip_phy89=0 +phy_tx_polarity_flip_phy90=1 +phy_tx_polarity_flip_phy91=1 +phy_tx_polarity_flip_phy92=1 +phy_tx_polarity_flip_phy93=1 +phy_tx_polarity_flip_phy94=1 +phy_tx_polarity_flip_phy95=1 + +ucode_port_1=CGE2_0:core_0.1 +ucode_port_2=CGE2_1:core_0.2 +ucode_port_3=CGE2_2:core_0.3 +ucode_port_4=CGE2_3:core_0.4 +ucode_port_5=CGE2_4:core_0.5 +ucode_port_6=CGE2_5:core_0.6 +ucode_port_7=CGE2_6:core_0.7 +ucode_port_8=CGE2_7:core_0.8 +ucode_port_9=CGE2_8:core_0.9 +ucode_port_10=CGE2_9:core_0.10 +ucode_port_11=CGE2_10:core_0.11 +ucode_port_12=CGE2_11:core_0.12 +ucode_port_13=CGE2_12:core_0.13 +ucode_port_14=CGE2_13:core_0.14 +ucode_port_15=CGE2_14:core_0.15 +ucode_port_16=CGE2_15:core_0.16 +ucode_port_17=CGE2_36:core_1.17 +ucode_port_18=CGE2_37:core_1.18 +ucode_port_19=CGE2_38:core_1.19 +ucode_port_20=CGE2_39:core_1.20 +ucode_port_21=CGE2_32:core_1.21 +ucode_port_22=CGE2_33:core_1.22 +ucode_port_23=CGE2_34:core_1.23 +ucode_port_24=CGE2_35:core_1.24 +ucode_port_25=CGE2_28:core_1.25 +ucode_port_26=CGE2_29:core_1.26 +ucode_port_27=CGE2_30:core_1.27 +ucode_port_28=CGE2_31:core_1.28 +ucode_port_29=CGE2_24:core_1.29 +ucode_port_30=CGE2_25:core_1.30 +ucode_port_31=CGE2_26:core_1.31 +ucode_port_32=CGE2_27:core_1.32 + +port_fec_33=2 +port_fec_34=2 +port_fec_35=2 +port_fec_36=2 +port_fec_37=2 +port_fec_38=2 +port_fec_39=2 +port_fec_40=2 + +ucode_port_33=CGE8:core_0.33 +ucode_port_34=CGE9:core_0.34 +ucode_port_35=CGE10:core_0.35 +ucode_port_36=CGE11:core_0.36 +ucode_port_37=CGE22:core_1.37 +ucode_port_38=CGE23:core_1.38 +ucode_port_39=CGE20:core_1.39 +ucode_port_40=CGE21:core_1.40 + +rif_id_max=0x4000 + +dma_desc_aggregator_chain_length_max.BCM8869X=1000 +dma_desc_aggregator_buff_size_kb.BCM8869X=100 +dma_desc_aggregator_timeout_usec.BCM8869X=1000 +dma_desc_aggregator_enable_specific_MDB_LPM.BCM8869X=1 +dma_desc_aggregator_enable_specific_MDB_FEC.BCM8869X=1 diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/port_config.ini b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/port_config.ini new file mode 100644 index 000000000000..2ba638aee50d --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/port_config.ini @@ -0,0 +1,41 @@ +# name lanes alias index speed +Ethernet0 0,1 Ethernet1/1 1 100000 +Ethernet4 2,3 Ethernet2/1 2 100000 +Ethernet8 4,5 Ethernet3/1 3 100000 +Ethernet12 6,7 Ethernet4/1 4 100000 +Ethernet16 8,9 Ethernet5/1 5 100000 +Ethernet20 10,11 Ethernet6/1 6 100000 +Ethernet24 12,13 Ethernet7/1 7 100000 +Ethernet28 14,15 Ethernet8/1 8 100000 +Ethernet32 16,17 Ethernet9/1 9 100000 +Ethernet36 18,19 Ethernet10/1 10 100000 +Ethernet40 20,21 Ethernet11/1 11 100000 +Ethernet44 22,23 Ethernet12/1 12 100000 +Ethernet48 24,25 Ethernet13/1 13 100000 +Ethernet52 26,27 Ethernet14/1 14 100000 +Ethernet56 28,29 Ethernet15/1 15 100000 +Ethernet60 30,31 Ethernet16/1 16 100000 +Ethernet64 72,73 Ethernet17/1 17 100000 +Ethernet68 74,75 Ethernet18/1 18 100000 +Ethernet72 76,77 Ethernet19/1 19 100000 +Ethernet76 78,79 Ethernet20/1 20 100000 +Ethernet80 64,65 Ethernet21/1 21 100000 +Ethernet84 66,67 Ethernet22/1 22 100000 +Ethernet88 68,69 Ethernet23/1 23 100000 +Ethernet92 70,71 Ethernet24/1 24 100000 +Ethernet96 56,57 Ethernet25/1 25 100000 +Ethernet100 58,59 Ethernet26/1 26 100000 +Ethernet104 60,61 Ethernet27/1 27 100000 +Ethernet108 62,63 Ethernet28/1 28 100000 +Ethernet112 48,49 Ethernet29/1 29 100000 +Ethernet116 50,51 Ethernet30/1 30 100000 +Ethernet120 52,53 Ethernet31/1 31 100000 +Ethernet124 54,55 Ethernet32/1 32 100000 +Ethernet128 32,33,34,35 Ethernet33/1 33 100000 +Ethernet132 36,37,38,39 Ethernet33/5 33 100000 +Ethernet136 40,41,42,43 Ethernet34/1 34 100000 +Ethernet140 44,45,46,47 Ethernet34/5 34 100000 +Ethernet144 88,89,90,91 Ethernet35/1 35 100000 +Ethernet148 92,93,94,95 Ethernet35/5 35 100000 +Ethernet152 80,81,82,83 Ethernet36/1 36 100000 +Ethernet156 84,85,86,87 Ethernet36/5 36 100000 diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile new file mode 100644 index 000000000000..bf99bb0ad4d2 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32d4-40x100G.config.bcm diff --git a/device/arista/x86_64-arista_7280cr3_32d4/default_sku b/device/arista/x86_64-arista_7280cr3_32d4/default_sku new file mode 100644 index 000000000000..a65e1f845ad3 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/default_sku @@ -0,0 +1 @@ +Arista-7280CR3-C32P4 t1 diff --git a/device/arista/x86_64-arista_7280cr3_32d4/fancontrol b/device/arista/x86_64-arista_7280cr3_32d4/fancontrol new file mode 120000 index 000000000000..6a53b7541071 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/fancontrol @@ -0,0 +1 @@ +../x86_64-arista_7280cr3_32p4/fancontrol \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/platform_reboot b/device/arista/x86_64-arista_7280cr3_32d4/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/plugins b/device/arista/x86_64-arista_7280cr3_32d4/plugins new file mode 120000 index 000000000000..5fbbf98a6284 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/sensors.conf b/device/arista/x86_64-arista_7280cr3_32d4/sensors.conf new file mode 120000 index 000000000000..0b3f7a039764 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7280cr3_32p4/sensors.conf \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3k_32d4 b/device/arista/x86_64-arista_7280cr3k_32d4 new file mode 120000 index 000000000000..50478132d933 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3k_32d4 @@ -0,0 +1 @@ +x86_64-arista_7280cr3_32d4 \ No newline at end of file diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 6460db61c8e3..a6856f9cabd2 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -312,6 +312,10 @@ platform_specific() { aboot_machine=arista_7280cr3_32d4 flash_size=7382 fi + if [ "$sid" = "SmartsvilleDDBK" ]; then + aboot_machine=arista_7280cr3k_32d4 + flash_size=7382 + fi if in_array "$platform" "rook" "magpie" "woodpecker"; then echo "tsc=reliable pcie_ports=native" >>/tmp/append echo "rhash_entries=1 usb-storage.delay_use=0" >>/tmp/append From 8cfb3a0a2290860745e932bd9f8816a92b826d7c Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Fri, 29 May 2020 08:23:21 +0300 Subject: [PATCH 0741/1427] [submodule update] sonic-utilities (#4648) Add 'hw-management-generate-dump.sh' to 'show techsupport' command (#923) Add common PCIe diag tool (#771) Multi-asic changes for config bgp commands and utilities. (#910) Loopback interface configuration CLIs (#879) Signed-off-by: Shlomi Bitton --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 9bd3b9e83c72..57655708e12b 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 9bd3b9e83c726b96145fe50df36f2b44abe2a560 +Subproject commit 57655708e12b878668e16a5ac1fab8d6694fc91c From 9863b76fc8000fb4fab0eaf016a0797e8c629c4b Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 29 May 2020 03:29:21 -0700 Subject: [PATCH 0742/1427] [build] Increase size of dockerfs ramdisk to accomodate more containers (#4666) Images built from master branch and installed on devices where we mount /var/lib/docker in RAM (because the HDD is small) were failing to boot properly. The Docker service failed to start because /var/lib/docker was filled to 100%. This is due to the increase in total number of containers in the image. As of today, /var/lib/docker contains 1.3 GB of data. Therefore, this PR increases the size of the ramdisk to 1.5 GB to accommodate all the containers. Example output below from an Arista-7050-QX32 SKU: ``` admin@sonic:~$ df -h Filesystem Size Used Avail Use% Mounted on ... tmpfs 1.5G 1.3G 172M 89% /var/lib/docker ... ``` --- onie-image-arm64.conf | 2 +- onie-image-armhf.conf | 2 +- onie-image.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/onie-image-arm64.conf b/onie-image-arm64.conf index 0a800c43b322..ff280207e192 100644 --- a/onie-image-arm64.conf +++ b/onie-image-arm64.conf @@ -25,7 +25,7 @@ FILESYSTEM_DOCKERFS=dockerfs.tar.gz DOCKERFS_DIR=docker ## docker ramfs disk space -DOCKER_RAMFS_SIZE=900M +DOCKER_RAMFS_SIZE=1500M ## Output file name for onie installer OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin diff --git a/onie-image-armhf.conf b/onie-image-armhf.conf index e396ce2298ec..48fe793c768c 100644 --- a/onie-image-armhf.conf +++ b/onie-image-armhf.conf @@ -25,7 +25,7 @@ FILESYSTEM_DOCKERFS=dockerfs.tar.gz DOCKERFS_DIR=docker ## docker ramfs disk space -DOCKER_RAMFS_SIZE=900M +DOCKER_RAMFS_SIZE=1500M ## Output file name for onie installer OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin diff --git a/onie-image.conf b/onie-image.conf index 830d6880ea8c..419095b24470 100644 --- a/onie-image.conf +++ b/onie-image.conf @@ -25,7 +25,7 @@ FILESYSTEM_DOCKERFS=dockerfs.tar.gz DOCKERFS_DIR=docker ## docker ramfs disk space -DOCKER_RAMFS_SIZE=900M +DOCKER_RAMFS_SIZE=1500M ## Output file name for onie installer OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin From cae67728f5f233211c499365cb92b9e32b947b8a Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Fri, 29 May 2020 03:29:49 -0700 Subject: [PATCH 0743/1427] [docker-database]: Upgrade docker-database to buster (#4665) Signed-off-by: Joyas Joseph --- dockers/docker-database/Dockerfile.j2 | 2 +- rules/docker-database.mk | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index bea4f17f2afc..24416c838db5 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 7e372048afab..9fb15855c247 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -7,20 +7,18 @@ DOCKER_DATABASE_DBG = $(DOCKER_DATABASE_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_DATABASE)_PATH = $(DOCKERS_PATH)/$(DOCKER_DATABASE_STEM) $(DOCKER_DATABASE)_DEPENDS += $(REDIS_TOOLS) $(REDIS_SERVER) -$(DOCKER_DATABASE)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_DATABASE)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_DATABASE)_DBG_DEPENDS += $(REDIS_TOOLS_DBG) -$(DOCKER_DATABASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_DATABASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_DATABASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_DATABASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_DATABASE) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_DATABASE) -SONIC_STRETCH_DOCKERS += $(DOCKER_DATABASE) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_DATABASE_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DATABASE_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DATABASE_DBG) $(DOCKER_DATABASE)_CONTAINER_NAME = database $(DOCKER_DATABASE)_RUN_OPT += --privileged -t From d86af98930f1fec7cd2f2d782d4fa1f428e2f5da Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Fri, 29 May 2020 16:49:20 -0700 Subject: [PATCH 0744/1427] [rules/libyang.mk]: Fix the dependencies among libyang PKGs. (#4669) This changes is needed to support parallel build Jobs. Made LIBYANG_PY2 and LIBYANG_PY3 depend on LIBYANG and LIBYANG_CPP. Also LIBYANG_CPP depends on LIBYANG. Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com --- rules/libyang.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rules/libyang.mk b/rules/libyang.mk index f4dc3dc8469f..fc739a30bc39 100644 --- a/rules/libyang.mk +++ b/rules/libyang.mk @@ -20,12 +20,15 @@ LIBYANG_DBG = libyang-dbg_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_DBG))) LIBYANG_CPP = libyang-cpp_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(LIBYANG_CPP)_DEPENDS += $(LIBYANG) $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_CPP))) LIBYANG_PY3 = python3-yang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(LIBYANG_PY3)_DEPENDS += $(LIBYANG) $(LIBYANG_CPP) $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_PY3))) LIBYANG_PY2 = python2-yang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(LIBYANG_PY2)_DEPENDS += $(LIBYANG) $(LIBYANG_CPP) $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_PY2))) export LIBYANG LIBYANG_DBG LIBYANG_DEV LIBYANG_CPP LIBYANG_PY3 LIBYANG_PY2 From 65e7a84509d39ee14fd7e4d20ddfff56921359d3 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Sat, 30 May 2020 05:52:27 -0700 Subject: [PATCH 0745/1427] [baseimage]: Build and install redis-dump-load Python 3 package in host image (#4661) Fix #4656 --- .../build_templates/sonic_debian_extension.j2 | 20 +++++++++++++------ rules/redis-dump-load-py3.mk | 9 +++++++++ rules/swss-common.mk | 2 +- rules/swsssdk-py2.mk | 1 + rules/swsssdk-py3.mk | 2 +- slave.mk | 1 + .../0001-Use-pipelines-when-dumping-52.patch | 9 +++++---- 7 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 rules/redis-dump-load-py3.mk diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 398fa173e346..e88c54692f49 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -101,6 +101,13 @@ sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_WHEEL_NAME # Install Python client for Redis sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install "redis==2.10.6" +# Install redis-dump-load Python 3 package +# Note: the scripts will be overwritten by corresponding Python 2 package +REDIS_DUMP_LOAD_PY3_WHEEL_NAME=$(basename {{redis_dump_load_py3_wheel_path}}) +sudo cp {{redis_dump_load_py3_wheel_path}} $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $REDIS_DUMP_LOAD_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY3_WHEEL_NAME + # Install redis-dump-load Python 2 package REDIS_DUMP_LOAD_PY2_WHEEL_NAME=$(basename {{redis_dump_load_py2_wheel_path}}) sudo cp {{redis_dump_load_py2_wheel_path}} $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY2_WHEEL_NAME @@ -110,13 +117,8 @@ sudo rm -rf $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY2_WHEEL_NAME # Install Python module for ipaddress sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install ipaddress -# Install SwSS SDK Python 2 package -SWSSSDK_PY2_WHEEL_NAME=$(basename {{swsssdk_py2_wheel_path}}) -sudo cp {{swsssdk_py2_wheel_path}} $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SWSSSDK_PY2_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME - # Install SwSS SDK Python 3 package +# Note: the scripts will be overwritten by corresponding Python 2 package if [ -e {{swsssdk_py3_wheel_path}} ]; then SWSSSDK_PY3_WHEEL_NAME=$(basename {{swsssdk_py3_wheel_path}}) sudo cp {{swsssdk_py3_wheel_path}} $FILESYSTEM_ROOT/$SWSSSDK_PY3_WHEEL_NAME @@ -124,6 +126,12 @@ if [ -e {{swsssdk_py3_wheel_path}} ]; then sudo rm -rf $FILESYSTEM_ROOT/$SWSSSDK_PY3_WHEEL_NAME fi +# Install SwSS SDK Python 2 package +SWSSSDK_PY2_WHEEL_NAME=$(basename {{swsssdk_py2_wheel_path}}) +sudo cp {{swsssdk_py2_wheel_path}} $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SWSSSDK_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME + # Install sonic-yang-models py3 package, install dependencies sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang_*.deb sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang-cpp_*.deb diff --git a/rules/redis-dump-load-py3.mk b/rules/redis-dump-load-py3.mk new file mode 100644 index 000000000000..875b5e1c8132 --- /dev/null +++ b/rules/redis-dump-load-py3.mk @@ -0,0 +1,9 @@ +# redis_dump_load python3 wheel + +REDIS_DUMP_LOAD_PY3 = redis_dump_load-1.1-py3-none-any.whl +$(REDIS_DUMP_LOAD_PY3)_SRC_PATH = $(SRC_PATH)/redis-dump-load +$(REDIS_DUMP_LOAD_PY3)_PYTHON_VERSION = 3 +# Synthetic dependency just to avoid race condition +$(REDIS_DUMP_LOAD_PY3)_DEPENDS += $(REDIS_DUMP_LOAD_PY2) +$(REDIS_DUMP_LOAD_PY3)_TEST = n +SONIC_PYTHON_WHEELS += $(REDIS_DUMP_LOAD_PY3) diff --git a/rules/swss-common.mk b/rules/swss-common.mk index 2d49867f9392..12d91e73fb8f 100644 --- a/rules/swss-common.mk +++ b/rules/swss-common.mk @@ -4,7 +4,7 @@ LIBSWSSCOMMON = libswsscommon_1.0.0_$(CONFIGURED_ARCH).deb $(LIBSWSSCOMMON)_SRC_PATH = $(SRC_PATH)/sonic-swss-common $(LIBSWSSCOMMON)_DEPENDS += $(LIBHIREDIS_DEV) $(LIBNL3_DEV) $(LIBNL_GENL3_DEV) \ $(LIBNL_ROUTE3_DEV) $(LIBNL_NF3_DEV) \ - $(LIBNL_CLI_DEV) $(SWIG) + $(LIBNL_CLI_DEV) $(SWIG) $(LIBSWSSCOMMON)_RDEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ $(LIBNL_ROUTE3) $(LIBNL_NF3) $(LIBNL_CLI) SONIC_DPKG_DEBS += $(LIBSWSSCOMMON) diff --git a/rules/swsssdk-py2.mk b/rules/swsssdk-py2.mk index a45677ae5882..8a98d1feda0a 100644 --- a/rules/swsssdk-py2.mk +++ b/rules/swsssdk-py2.mk @@ -3,4 +3,5 @@ SWSSSDK_PY2 = swsssdk-2.0.1-py2-none-any.whl $(SWSSSDK_PY2)_SRC_PATH = $(SRC_PATH)/sonic-py-swsssdk $(SWSSSDK_PY2)_PYTHON_VERSION = 2 +$(SWSSSDK_PY2)_DEPENDS += $(REDIS_DUMP_LOAD_PY2) SONIC_PYTHON_WHEELS += $(SWSSSDK_PY2) diff --git a/rules/swsssdk-py3.mk b/rules/swsssdk-py3.mk index e2f3519e00ca..681ba72f85b7 100644 --- a/rules/swsssdk-py3.mk +++ b/rules/swsssdk-py3.mk @@ -4,5 +4,5 @@ SWSSSDK_PY3 = swsssdk-2.0.1-py3-none-any.whl $(SWSSSDK_PY3)_SRC_PATH = $(SRC_PATH)/sonic-py-swsssdk $(SWSSSDK_PY3)_PYTHON_VERSION = 3 # Synthetic dependency just to avoid race condition -$(SWSSSDK_PY3)_DEPENDS += $(SWSSSDK_PY2) +$(SWSSSDK_PY3)_DEPENDS += $(SWSSSDK_PY2) $(REDIS_DUMP_LOAD_PY3) SONIC_PYTHON_WHEELS += $(SWSSSDK_PY3) diff --git a/slave.mk b/slave.mk index 34395848a319..06736eafe42e 100644 --- a/slave.mk +++ b/slave.mk @@ -816,6 +816,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export swsssdk_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY3))" export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" + export redis_dump_load_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY3))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" export sonic_yang_models_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3))" export sonic_yang_mgmt_py_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY))" diff --git a/src/redis-dump-load.patch/0001-Use-pipelines-when-dumping-52.patch b/src/redis-dump-load.patch/0001-Use-pipelines-when-dumping-52.patch index 5eea3faba2c3..c37cbd9f4bf1 100644 --- a/src/redis-dump-load.patch/0001-Use-pipelines-when-dumping-52.patch +++ b/src/redis-dump-load.patch/0001-Use-pipelines-when-dumping-52.patch @@ -33,7 +33,7 @@ index df2870b..1b6063b 100755 if pretty: # hack to avoid implementing pretty printing fp.write(dumps(host=host, port=port, password=password, db=db, -@@ -276,28 +276,76 @@ def _read_key(key, r, pretty, encoding): +@@ -276,28 +276,77 @@ def _read_key(key, r, pretty, encoding): return (type, ttl, value) def _reader(r, pretty, encoding, keys='*'): @@ -68,7 +68,7 @@ index df2870b..1b6063b 100755 + i += 10000 + +def _read_keys(r, encoded_keys, pretty, encoding): -+ decoded_keys = [encoded_key.decode() for encoded_key in encoded_keys] ++ decoded_keys = [encoded_key.decode(encoding) for encoded_key in encoded_keys] + do_keys = decoded_keys + retries = 5 + type_results = None @@ -84,12 +84,13 @@ index df2870b..1b6063b 100755 + p = r.pipeline() + for key in do_keys: + p.type(key) -+ type_results = p.execute() ++ encoded_type_results = p.execute() ++ type_results = [encoded_type_result.decode('ascii') for encoded_type_result in encoded_type_results] + + p = r.pipeline() + for i in range(len(do_keys)): + key = decoded_keys[i] -+ type = type_results[i].decode('ascii') ++ type = type_results[i] + if type == 'none': + # key was deleted by a concurrent operation on the data store. + # issue noops so that the number of results does not change From 59db60bd8eb72b6f6e7dbd94e2da999f72d04d04 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Sat, 30 May 2020 13:44:19 -0700 Subject: [PATCH 0746/1427] [sonic-slave]: add debian packages needed to compile BRCM SAI3.7 (#4672) both for sonic-slave-stretch and sonic-slave-buster --- sonic-slave-buster/Dockerfile.j2 | 2 ++ sonic-slave-stretch/Dockerfile.j2 | 2 ++ 2 files changed, 4 insertions(+) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index a642a09d2297..7e0ea1096e14 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -299,7 +299,9 @@ RUN apt-get update && apt-get install -y \ libnetfilter-conntrack-dev \ libnftnl-dev \ # For SAI3.7 + protobuf-compiler \ libprotobuf-dev \ + xxd \ # For DHCP Monitor tool libexplain-dev \ libevent-dev diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 40bc7da1bf57..9d80560e5b4c 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -295,7 +295,9 @@ RUN apt-get update && apt-get install -y \ libnetfilter-conntrack-dev \ libnftnl-dev \ # For SAI3.7 + protobuf-compiler \ libprotobuf-dev \ + xxd \ # For DHCP Monitor tool libexplain-dev \ libevent-dev From 1e369b09980953cd2dc8fd808ffe8a7b6c29337d Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 30 May 2020 13:46:44 -0700 Subject: [PATCH 0747/1427] [systemd] Relocate all SONiC unit files to /usr/lib/systemd/system (#4673) This will allow us to disable services and have it persist across reboots by using the `systemctl mask` operation --- .../build_templates/sonic_debian_extension.j2 | 39 ++++++++++--------- .../systemd-sonic-generator.c | 2 +- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index e88c54692f49..0f371f98bd0a 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -33,6 +33,7 @@ SCRIPTS_DIR=files/scripts # Define target fold macro FILESYSTEM_ROOT_USR="$FILESYSTEM_ROOT/usr" +FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM="$FILESYSTEM_ROOT/usr/lib/systemd/system" FILESYSTEM_ROOT_USR_SHARE="$FILESYSTEM_ROOT_USR/share" FILESYSTEM_ROOT_USR_SHARE_SONIC="$FILESYSTEM_ROOT_USR_SHARE/sonic" FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES="$FILESYSTEM_ROOT_USR_SHARE_SONIC/templates" @@ -220,18 +221,18 @@ sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/conf.d/* sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ # Copy NTP configuration files and templates -sudo cp $IMAGE_CONFIGS/ntp/ntp-config.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/ntp/ntp-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "ntp-config.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/ntp/ntp-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/ntp/ntp.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ # Copy warmboot-finalizer files sudo LANG=C cp $IMAGE_CONFIGS/warmboot-finalizer/finalize-warmboot.sh $FILESYSTEM_ROOT/usr/local/bin/finalize-warmboot.sh -sudo LANG=C cp $IMAGE_CONFIGS/warmboot-finalizer/warmboot-finalizer.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C cp $IMAGE_CONFIGS/warmboot-finalizer/warmboot-finalizer.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "warmboot-finalizer.service" | sudo tee -a $GENERATED_SERVICE_FILE # Copy rsyslog configuration files and templates -sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.d/* $FILESYSTEM_ROOT/etc/rsyslog.d/ @@ -249,7 +250,7 @@ sudo cp -f $IMAGE_CONFIGS/logrotate/logrotate.d/* $FILESYSTEM_ROOT/etc/logrotate sudo cp -f $IMAGE_CONFIGS/systemd/journald.conf $FILESYSTEM_ROOT/etc/systemd/ # Copy interfaces configuration files and templates -sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/interfaces/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ echo "interfaces-config.service" | sudo tee -a $GENERATED_SERVICE_FILE @@ -265,13 +266,13 @@ sudo cp $IMAGE_CONFIGS/interfaces/init_interfaces $FILESYSTEM_ROOT/etc/network/i sudo mkdir -p $FILESYSTEM_ROOT/etc/network/interfaces.d # Copy hostcfgd files -sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "hostcfgd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/hostcfgd/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ # copy core file uploader files -sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable core_uploader.service sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.py $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/corefile_uploader/core_analyzer.rc.json $FILESYSTEM_ROOT_ETC_SONIC/ @@ -296,7 +297,7 @@ sudo cp $BUILD_TEMPLATES/buffers_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMP sudo cp $BUILD_TEMPLATES/qos_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ # Copy hostname configuration scripts -sudo cp $IMAGE_CONFIGS/hostname/hostname-config.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/hostname/hostname-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "hostname-config.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/ @@ -305,13 +306,13 @@ sudo cp $IMAGE_CONFIGS/misc/docker-wait-any $FILESYSTEM_ROOT/usr/bin/ # Copy internal topology configuration scripts {%- if sonic_asic_platform == "vs" %} -sudo cp $IMAGE_CONFIGS/topology/topology.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/topology/topology.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "topology.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/topology/topology.sh $FILESYSTEM_ROOT/usr/bin {%- endif %} # Copy updategraph script and service file -j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/updategraph.service +j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM/updategraph.service sudo cp $IMAGE_CONFIGS/updategraph/updategraph $FILESYSTEM_ROOT/usr/bin/ echo "updategraph.service" | sudo tee -a $GENERATED_SERVICE_FILE {% if enable_dhcp_graph_service == "y" %} @@ -326,7 +327,7 @@ sudo bash -c "echo enabled=false > $FILESYSTEM_ROOT/etc/sonic/updategraph.conf" j2 files/build_templates/init_cfg.json.j2 | sudo tee $FILESYSTEM_ROOT/etc/sonic/init_cfg.json # Copy config-setup script and service file -j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/config-setup.service +j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM/config-setup.service sudo cp $IMAGE_CONFIGS/config-setup/config-setup $FILESYSTEM_ROOT/usr/bin/config-setup echo "config-setup.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-setup.service @@ -342,22 +343,22 @@ sudo cp $IMAGE_CONFIGS/sudoers/sudoers $FILESYSTEM_ROOT/etc/ sudo cp $IMAGE_CONFIGS/sudoers/sudoers.lecture $FILESYSTEM_ROOT/etc/ # Copy control plane ACL management daemon files -sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "caclmgrd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd $FILESYSTEM_ROOT/usr/bin/ # Copy process/docker cpu/memory utilization data export daemon -sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "procdockerstatsd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd $FILESYSTEM_ROOT/usr/bin/ # Copy systemd timer configuration # It implements delayed start of services -sudo cp $BUILD_TEMPLATES/process-reboot-cause.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $BUILD_TEMPLATES/process-reboot-cause.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable process-reboot-cause.timer # Copy process-reboot-cause service files -sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "process-reboot-cause.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause $FILESYSTEM_ROOT/usr/bin/ @@ -414,7 +415,7 @@ sudo dpkg --root=$FILESYSTEM_ROOT -P {{ debname }} sudo rm -f $FILESYSTEM_ROOT/usr/sbin/policy-rc.d # Copy fstrim service and timer file, enable fstrim timer -sudo cp $IMAGE_CONFIGS/fstrim/* $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/fstrim/* $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable fstrim.timer ## copy platform rc.local @@ -485,12 +486,12 @@ sudo cp {{script}} $FILESYSTEM_ROOT/usr/bin/ {% endfor %} {% for service in installer_services.split(' ') -%} if [ -f {{service}} ]; then - sudo cp {{service}} $FILESYSTEM_ROOT/etc/systemd/system/ + sudo cp {{service}} $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM {% if "@" in service %} MULTI_INSTANCE="{{service}}" SINGLE_INSTANCE=${MULTI_INSTANCE/"@"} - sudo cp $SINGLE_INSTANCE $FILESYSTEM_ROOT/etc/systemd/system/ + sudo cp $SINGLE_INSTANCE $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM {% endif %} echo "{{service}}" | sudo tee -a $GENERATED_SERVICE_FILE @@ -512,10 +513,10 @@ sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netn # Copy systemd timer configuration # It implements delayed start of services -sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer {% if enable_system_telemetry == 'y' %} -sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable telemetry.timer {% endif %} diff --git a/src/systemd-sonic-generator/systemd-sonic-generator.c b/src/systemd-sonic-generator/systemd-sonic-generator.c index 566d37ff0a4c..9a5fabd33484 100644 --- a/src/systemd-sonic-generator/systemd-sonic-generator.c +++ b/src/systemd-sonic-generator/systemd-sonic-generator.c @@ -14,7 +14,7 @@ #define MAX_NUM_UNITS 128 #define MAX_BUF_SIZE 512 -static const char* UNIT_FILE_PREFIX = "/etc/systemd/system/"; +static const char* UNIT_FILE_PREFIX = "/usr/lib/systemd/system/"; static const char* CONFIG_FILE = "/etc/sonic/generated_services.conf"; static const char* MACHINE_CONF_FILE = "/host/machine.conf"; static int num_asics; From c37c94934292dba90839574d90dc89f539908c55 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 30 May 2020 21:17:22 +0000 Subject: [PATCH 0748/1427] Revert "install crossbuild in buster slave for arm arch kernel compile" This reverts commit dc0f01006620b86dedc554864a8a25c4fd28a1bc. --- sonic-slave-buster/Dockerfile.j2 | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 7e0ea1096e14..05dc07410ae2 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -317,11 +317,6 @@ RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confold" # For linux build RUN apt-get -y build-dep linux -# For march kernel compile -RUN apt-get install -y crossbuild-essential-amd64 \ - crossbuild-essential-arm64 \ - crossbuild-essential-armhf - # For gobgp and telemetry build RUN export VERSION=1.14.2 \ {%- if CONFIGURED_ARCH == "armhf" %} From fb6916f88bacefed71b466cff53d5b59f0b4fc45 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Sat, 30 May 2020 14:23:34 -0700 Subject: [PATCH 0749/1427] Update packages and pointers to use SAI1.6 headers. (#4597) * Update sonic-sairedis (sairedis with SAI 1.6 headers) * Update SAIBCM to 3.7.4.2, which is built upon SAI1.6 headers * missed updating BRCM_SAI variable, fixed it * Update SAIBCM to 3.7.4.2, updated link to libsaibcm * [Mellanox] Update SAI (release:v1.16.3; API:v1.6) Signed-off-by: Volodymyr Samotiy * Update sonic-sairedis pointer to include SAI1.6 headers * [Mellanox] Update SDK to 4.4.0914 and FW to xx.2007.1112 to match SAI 1.16.3 (API:v1.6) Signed-off-by: Volodymyr Samotiy * ensure the veth link is up in docker VS container * ensure the veth link is up in docker VS container * [Mellanox] Update SAI (release:v1.16.3.2; API:v1.6) Signed-off-by: Volodymyr Samotiy * use 'config interface startup' instead of using ifconfig command, also undid the previous change' Co-authored-by: Volodymyr Samotiy --- platform/broadcom/sai.mk | 8 ++++---- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- platform/vs/tests/bgp/test_gr_livelock.py | 4 ++-- platform/vs/tests/bgp/test_invalid_nexthop.py | 2 +- platform/vs/tests/bgp/test_no_export.py | 4 ++-- src/sonic-sairedis | 2 +- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index e6e40039caf0..76934d37ee1b 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,8 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.3.3-4_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3-4_amd64.deb?sv=2015-04-05&sr=b&sig=9z7vLhweD%2B%2FZylkr9XsDAJ3DdE5NJlcPTslFYyBuAXU%3D&se=2033-12-25T14%3A52%3A25Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3-4_amd64.deb +BRCM_SAI = libsaibcm_3.7.4.2_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.4.2_amd64.deb?sv=2015-04-05&sr=b&sig=Iqgd1HDmXOa%2F2OEnez1D4dQ4wVICZlnvVOYao1FYlio%3D&se=2034-01-14T18%3A51%3A07Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_3.7.4.2_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3-4_amd64.deb?sv=2015-04-05&sr=b&sig=SAOoGh2zdljiPuKeDoa%2B1lSJzZ8uXh2Irl2RZX1uAiA%3D&se=2033-12-25T14%3A53%3A44Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.4.2_amd64.deb?sv=2015-04-05&sr=b&sig=cbQJOwQcILWYbjuI3LObY6H7bvCNijKfEkdAIrm3Q64%3D&se=2034-01-14T18%3A49%3A15Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 57cf8d6ecd06..c8f4b225857b 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2007.1140 +MLNX_SPC_FW_VERSION = 13.2007.1112 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2007.1140 +MLNX_SPC2_FW_VERSION = 29.2007.1112 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2007.1140 +MLNX_SPC3_FW_VERSION = 30.2007.1112 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index deff67e39968..0b04ae0de850 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.4-master +MLNX_SAI_VERSION = SAIRel1.16.3.2-sai16 export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 8cbb3aaaa2d3..aa5a09b71260 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 8cbb3aaaa2d3ff3d5770d5d2452a0ebe32149206 +Subproject commit aa5a09b712609d7c903fbacd63a87deeab922a2b diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 0115fcd6b6de..3160d980ff76 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 0115fcd6b6dea3dd9faf957389885a7ed40b671d +Subproject commit 3160d980ff766addb459e1ff0f81778516eb55a0 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 14d3f79e0a89..c63c327cc40d 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.4.0918 +MLNX_SDK_VERSION = 4.4.0914 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) diff --git a/platform/vs/tests/bgp/test_gr_livelock.py b/platform/vs/tests/bgp/test_gr_livelock.py index f269f1e8eee4..aff0afdb02b4 100644 --- a/platform/vs/tests/bgp/test_gr_livelock.py +++ b/platform/vs/tests/bgp/test_gr_livelock.py @@ -86,10 +86,10 @@ def test_gr_livelock(dvs, testlog): time.sleep(5) dvs.runcmd("supervisorctl start bgpd") dvs.runcmd("ip addr add 10.0.0.0/31 dev Ethernet0") - dvs.runcmd("ifconfig Ethernet0 up") + dvs.runcmd("config interface startup Ethernet0") dvs.runcmd("ip addr add 10.0.0.2/31 dev Ethernet4") - dvs.runcmd("ifconfig Ethernet4 up") + dvs.runcmd("config interface startup Ethernet4") dvs.servers[0].runcmd("ip addr add 10.0.0.1/31 dev eth0") dvs.servers[0].runcmd("ifconfig eth0 up") diff --git a/platform/vs/tests/bgp/test_invalid_nexthop.py b/platform/vs/tests/bgp/test_invalid_nexthop.py index 021e3bfea002..24f3d8790b9c 100644 --- a/platform/vs/tests/bgp/test_invalid_nexthop.py +++ b/platform/vs/tests/bgp/test_invalid_nexthop.py @@ -10,7 +10,7 @@ def test_InvalidNexthop(dvs, testlog): dvs.copy_file("/etc/frr/", "bgp/files/invalid_nexthop/bgpd.conf") dvs.runcmd("supervisorctl start bgpd") dvs.runcmd("ip addr add fc00::1/126 dev Ethernet0") - dvs.runcmd("ifconfig Ethernet0 up") + dvs.runcmd("config interface startup Ethernet0") dvs.servers[0].runcmd("ip addr add fc00::2/126 dev eth0") dvs.servers[0].runcmd("ifconfig eth0 up") diff --git a/platform/vs/tests/bgp/test_no_export.py b/platform/vs/tests/bgp/test_no_export.py index efbc5331fef8..92bece320c1c 100644 --- a/platform/vs/tests/bgp/test_no_export.py +++ b/platform/vs/tests/bgp/test_no_export.py @@ -9,10 +9,10 @@ def test_bounce(dvs, testlog): dvs.copy_file("/etc/frr/", "bgp/files/no_export/bgpd.conf") dvs.runcmd("supervisorctl start bgpd") dvs.runcmd("ip addr add 10.0.0.0/31 dev Ethernet0") - dvs.runcmd("ifconfig Ethernet0 up") + dvs.runcmd("config interface startup Ethernet0") dvs.runcmd("ip addr add 10.0.0.2/31 dev Ethernet4") - dvs.runcmd("ifconfig Ethernet4 up") + dvs.runcmd("config interface startup Ethernet4") dvs.servers[0].runcmd("ip addr add 10.0.0.1/31 dev eth0") dvs.servers[0].runcmd("ifconfig eth0 up") diff --git a/src/sonic-sairedis b/src/sonic-sairedis index f972073fae66..ebdf4fff1ce4 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit f972073fae66a56e32bfe0a30dac81ceae4c5d75 +Subproject commit ebdf4fff1ce4db87886629ef7a9e251ee41390d1 From 8863a11bfb98b8772d99476e660b4576dbc11311 Mon Sep 17 00:00:00 2001 From: Srideep Date: Sun, 31 May 2020 02:58:05 -0600 Subject: [PATCH 0750/1427] [DellEmc] Changes to suppot new portmap for s5232f t0 config (#4670) To support t0 config --- .../DellEMC-S5232f-C8D48/port_config.ini | 24 +++++++++---------- .../td3-s5232f-8x100G+48x50G.config.bcm | 24 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini index b7a336827ffe..3fc2ef699913 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini @@ -39,18 +39,18 @@ Ethernet80 81,82 fiftyGigE1/21/1 21 50000 Ethernet82 83,84 fiftyGigE1/21/2 21 50000 Ethernet84 85,86 fiftyGigE1/22/1 22 50000 Ethernet86 87,88 fiftyGigE1/22/2 22 50000 -Ethernet88 89,90 fiftyGigE1/23/1 23 50000 -Ethernet90 91,92 fiftyGigE1/23/2 23 50000 -Ethernet92 93,94 fiftyGigE1/24/1 24 50000 -Ethernet94 95,96 fiftyGigE1/24/2 24 50000 -Ethernet96 97,98 fiftyGigE1/25/1 25 50000 -Ethernet98 99,100 fiftyGigE1/25/2 25 50000 -Ethernet100 101,102 fiftyGigE1/26/1 26 50000 -Ethernet102 103,104 fiftyGigE1/26/2 26 50000 -Ethernet104 105,106,107,108 hundredGigE1/27 27 100000 -Ethernet108 109,110,111,112 hundredGigE1/28 28 100000 -Ethernet112 113,114,115,116 hundredGigE1/29 29 100000 -Ethernet116 117,118,119,120 hundredGigE1/30 30 100000 +Ethernet88 89,90,91,92 hundredGigE1/23 23 100000 +Ethernet92 93,94,95,96 hundredGigE1/24 24 100000 +Ethernet96 97,98,99,100 hundredGigE1/25 25 100000 +Ethernet100 101,102,103,104 hundredGigE1/26 26 100000 +Ethernet104 105,106 fiftyGigE1/27/1 27 50000 +Ethernet106 107,108 fiftyGigE1/27/2 27 50000 +Ethernet108 109,110 fiftyGigE1/28/1 28 50000 +Ethernet110 111,112 fiftyGigE1/28/2 28 50000 +Ethernet112 113,114 fiftyGigE1/29/1 29 50000 +Ethernet114 115,116 fiftyGigE1/29/2 29 50000 +Ethernet116 117,118 fiftyGigE1/30/1 30 50000 +Ethernet118 119,120 fiftyGigE1/30/2 30 50000 Ethernet120 121,122 fiftyGigE1/31/1 31 50000 Ethernet122 123,124 fiftyGigE1/31/2 31 50000 Ethernet124 125,126 fiftyGigE1/32/1 32 50000 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm index cf0bfd043ee0..b9762a712d94 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm @@ -85,18 +85,18 @@ portmap_83.0=81:50:2 portmap_85.0=83:50:2 portmap_87.0=85:50:2 portmap_89.0=87:50:2 -portmap_91.0=89:50:2 -portmap_93.0=91:50:2 -portmap_95.0=93:50:2 -portmap_97.0=95:50:2 -portmap_99.0=97:50:2 -portmap_101.0=99:50:2 -portmap_103.0=101:50:2 -portmap_105.0=103:50:2 -portmap_107.0=105:100 -portmap_111.0=109:100 -portmap_115.0=113:100 -portmap_119.0=117:100 +portmap_91.0=89:100 +portmap_95.0=93:100 +portmap_99.0=97:100 +portmap_103.0=101:100 +portmap_107.0=105:50:2 +portmap_109.0=107:50:2 +portmap_111.0=109:50:2 +portmap_113.0=111:50:2 +portmap_115.0=113:50:2 +portmap_117.0=115:50:2 +portmap_119.0=117:50:2 +portmap_121.0=119:50:2 portmap_123.0=121:50:2 portmap_125.0=123:50:2 portmap_127.0=125:50:2 From ccd08f10ddc7e0d386f840d59fface82d183e76c Mon Sep 17 00:00:00 2001 From: taochengyi <54564117+taocy001@users.noreply.github.com> Date: Sun, 31 May 2020 18:09:39 +0800 Subject: [PATCH 0751/1427] [build]: fix mgmt-framework build failure on ARM64 (#4674) PIP installs grpcio-tools via source code Co-authored-by: taocy --- dockers/docker-sonic-mgmt-framework/Dockerfile.j2 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 index f581a5bc4b67..37675dbc33ff 100644 --- a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 @@ -6,7 +6,9 @@ RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%s ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update +RUN apt-get update && \ + apt-get install -y g++ python-dev + RUN pip install connexion==1.1.15 \ setuptools==21.0.0 \ grpcio-tools==1.20.0 \ @@ -15,7 +17,6 @@ RUN pip install connexion==1.1.15 \ six==1.11.0 \ urllib3==1.21.1 - COPY \ {% for deb in docker_sonic_mgmt_framework_debs.split(' ') -%} debs/{{ deb }}{{' '}} @@ -30,6 +31,7 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "rest-server.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +RUN apt-get remove -y g++ python-dev RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs From 336cf2a3c54f569131835da45e567f51ddfc4dd8 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 1 Jun 2020 13:28:03 -0700 Subject: [PATCH 0752/1427] [build] 'make reset' target will continue recursive operations if any fail (#4675) This change allows the recursive `git clean` and `git reset` commands to continue even if they encounter an error in one of the submodules. Previously, if an error was encountered, the operation would terminate with a message similar to the following: Stopping at 'src/sonic-mgmt-framework'; script returned non-zero status. --- Makefile.work | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.work b/Makefile.work index ca98222c1699..11e79f6b81ab 100644 --- a/Makefile.work +++ b/Makefile.work @@ -283,8 +283,8 @@ reset : fi git clean -xfdf; git reset --hard; - git submodule foreach --recursive git clean -xfdf; - git submodule foreach --recursive git reset --hard; + git submodule foreach --recursive 'git clean -xfdf || true'; + git submodule foreach --recursive 'git reset --hard || true'; git submodule update --init --recursive; echo "Reset complete!"; else From eff8a895237159c0e6d4d1e04170f02373672fc6 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 2 Jun 2020 02:07:22 -0700 Subject: [PATCH 0753/1427] [hostcfgd] Get service enable/disable feature working (#4676) Fix hostcfgd so that changes to the "FEATURE" table in ConfigDB are properly handled. Three changes here: 1. Fix indenting such that the handling of each key actually occurs in the for key in status_data.keys(): loop 2. Add calls to sudo systemctl mask and sudo systemctl unmask as appropriate to ensure changes persist across reboots 3. Substitute returns with continues so that even if one service fails, we still try to handle the others Note that the masking is persistent, even if the configuration is not saved. We may want to consider only calling systemctl enable/disable in hostcfgd when the DB table changes, and only call systemctl mask/unmask upon calling config save. --- files/image_config/hostcfgd/hostcfgd | 69 +++++++++++++++------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index edbbacca86c2..6d4615d85823 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -267,39 +267,42 @@ class HostConfigDaemon: for key in status_data.keys(): if not key: syslog.syslog(syslog.LOG_WARNING, "FEATURE key is missing") - return - status = status_data[key]['status'] - if not status: - syslog.syslog(syslog.LOG_WARNING, "status is missing for {}".format(key)) - return - if status == "enabled": - start_cmds=[] - start_cmds.append("sudo systemctl enable {}".format(key)) - start_cmds.append("sudo systemctl start {}".format(key)) - for cmd in start_cmds: - syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) - return - syslog.syslog(syslog.LOG_INFO, "Feature '{}' is enabled and started".format(key)) - elif status == "disabled": - stop_cmds=[] - stop_cmds.append("sudo systemctl stop {}".format(key)) - stop_cmds.append("sudo systemctl disable {}".format(key)) - for cmd in stop_cmds: - syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) - return - syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Unexpected status value '{}' for '{}'".format(status, key)) + continue + + status = status_data[key]['status'] + if not status: + syslog.syslog(syslog.LOG_WARNING, "status is missing for {}".format(key)) + continue + if status == "enabled": + start_cmds=[] + start_cmds.append("sudo systemctl unmask {}.service".format(key)) + start_cmds.append("sudo systemctl enable {}.service".format(key)) + start_cmds.append("sudo systemctl start {}.service".format(key)) + for cmd in start_cmds: + syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + continue + syslog.syslog(syslog.LOG_INFO, "Feature '{}' is enabled and started".format(key)) + elif status == "disabled": + stop_cmds=[] + stop_cmds.append("sudo systemctl stop {}.service".format(key)) + stop_cmds.append("sudo systemctl disable {}.service".format(key)) + stop_cmds.append("sudo systemctl mask {}.service".format(key)) + for cmd in stop_cmds: + syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + continue + syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(key)) + else: + syslog.syslog(syslog.LOG_ERR, "Unexpected status value '{}' for '{}'".format(status, key)) def start(self): self.config_db.subscribe('AAA', lambda table, key, data: self.aaa_handler(key, data)) From 7b8037770d3794c9c8fc24a41878f7becc705107 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 2 Jun 2020 02:11:21 -0700 Subject: [PATCH 0754/1427] [caclmgrd] Get first VLAN host IP address via next() (#4685) I found that with IPv4Network types, calling list(ip_ntwrk.hosts()) is reliable. However, when doing the same with an IPv6Network, I found that the conversion to a list can hang indefinitely. This appears to me to be a bug in the ipaddress.IPv6Network implementation. However, I could not find any other reports on the web. This patch changes the behavior to call next() on the ip_ntwrk.hosts() generator instead, which returns the IP address of the first host. --- files/image_config/caclmgrd/caclmgrd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 784218617c92..ce60ebc9d40b 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -180,10 +180,11 @@ class ControlPlaneAclManager(object): continue iface_name, iface_cidr = key ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + first_host = next(ip_ntwrk.hosts()) if isinstance(ip_ntwrk, ipaddress.IPv4Network): - block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(list(ip_ntwrk.hosts())[0], ip_ntwrk.max_prefixlen)) + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(first_host, ip_ntwrk.max_prefixlen)) elif isinstance(ip_ntwrk, ipaddress.IPv6Network): - block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(list(ip_ntwrk.hosts())[0], ip_ntwrk.max_prefixlen)) + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(first_host, ip_ntwrk.max_prefixlen)) else: log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) From 3e110fb0c1f59f9b3e77c891457c3da90054b495 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Tue, 2 Jun 2020 15:35:26 -0700 Subject: [PATCH 0755/1427] Update sonic-restapi (#4692) Auto restart restapi server after cert rollover --- src/sonic-restapi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-restapi b/src/sonic-restapi index 95e6bf8dcbf9..2094f5505644 160000 --- a/src/sonic-restapi +++ b/src/sonic-restapi @@ -1 +1 @@ -Subproject commit 95e6bf8dcbf9a3052c01cb8264f0a750eda91625 +Subproject commit 2094f5505644dc42085f593483719f94ba0bcd76 From 49a93743a4f4749a152c17305f689f94b19b4768 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Thu, 4 Jun 2020 19:52:43 +0300 Subject: [PATCH 0756/1427] [enable counters] enable RIF flex counter by default (#4655) **- Why I did it** We need RIF counters to be enabled by default. Flex Counter does probe for supported counters. If a platform does not support RIF counters, SAI will return NOT_SUPPORTED and Flex Counter will stop polling the counter. **- How to verify it** After fresh install rif counter gropup is enabled by default: $ counterpoll show Type Interval (in ms) Status -------------------- ------------------ -------- QUEUE_STAT default (10000) enable PORT_STAT default (1000) enable RIF_STAT default (1000) enable QUEUE_WATERMARK_STAT default (10000) enable PG_WATERMARK_STAT default (10000) enable Signed-off-by: Mykola Faryma --- dockers/docker-orchagent/enable_counters.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-orchagent/enable_counters.py b/dockers/docker-orchagent/enable_counters.py index 75f8ef82cb4c..b2ec4b85a202 100755 --- a/dockers/docker-orchagent/enable_counters.py +++ b/dockers/docker-orchagent/enable_counters.py @@ -12,6 +12,7 @@ def enable_counters(): db = swsssdk.ConfigDBConnector() db.connect() enable_counter_group(db, 'PORT') + enable_counter_group(db, 'RIF') enable_counter_group(db, 'QUEUE') enable_counter_group(db, 'PFCWD') enable_counter_group(db, 'PG_WATERMARK') From 3a0de981ca8f5f866c030ef72fb0ca07848be47e Mon Sep 17 00:00:00 2001 From: Masaru OKI Date: Fri, 5 Jun 2020 05:29:36 +0900 Subject: [PATCH 0757/1427] [kvmimae]: Update sonic-gns3a.sh (#4694) Cleanup description string First port (management port) are excluded from general port naming scheme. Management port are excluded from general port naming scheme. before: |on GNS3 |in SONiC | |---------|---------| |Ethernet0|eth0 | |Ethernet1|Ethernet0| |Ethernet2|Ethernet4| |Ethernet3|Ethernet8| after: |on GNS3 |in SONiC | |---------|---------| |eth0 |eth0 | |Ethernet0|Ethernet0| |Ethernet1|Ethernet4| |Ethernet2|Ethernet8| Signed-off-by: Masaru OKI --- platform/vs/sonic-gns3a.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/vs/sonic-gns3a.sh b/platform/vs/sonic-gns3a.sh index 57c63fb75f32..41e39cd8686a 100644 --- a/platform/vs/sonic-gns3a.sh +++ b/platform/vs/sonic-gns3a.sh @@ -39,7 +39,7 @@ echo " { \"name\": \"SONiC\", \"category\": \"router\", - \"description\": \"SONiC Virtual Switch/Router\n\", + \"description\": \"SONiC Virtual Switch/Router\", \"vendor_name\": \"SONiC\", \"vendor_url\": \"https://azure.github.io/SONiC/\", \"product_name\": \"SONiC\", @@ -49,6 +49,7 @@ echo " \"maintainer\": \"SONiC\", \"maintainer_email\": \"sonicproject@googlegroups.com\", \"usage\": \"Supports SONiC release: ${RELEASE}\", + \"first_port_name\": \"eth0\", \"qemu\": { \"adapter_type\": \"e1000\", \"adapters\": 10, From c8bd640ae53a80f2752feaffa59a4d77def0701e Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Thu, 4 Jun 2020 13:33:33 -0700 Subject: [PATCH 0758/1427] [arista] Update drivers submodules (#4693) - Sensor and Fan information added to primary platforms for thermal API. - Refactors involving better abstractions, code reuse and dead code removal. - Improvements to the diag capabilities - Pylintrc added to improve code quality. Will become fatal at a later time. Co-authored-by: Baptiste Covolato --- device/arista/x86_64-arista_7280cr3_32p4/fancontrol | 6 +++--- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/device/arista/x86_64-arista_7280cr3_32p4/fancontrol b/device/arista/x86_64-arista_7280cr3_32p4/fancontrol index 1c0415b7e464..55a48e095084 100644 --- a/device/arista/x86_64-arista_7280cr3_32p4/fancontrol +++ b/device/arista/x86_64-arista_7280cr3_32p4/fancontrol @@ -1,7 +1,7 @@ INTERVAL=5 -DEVPATH=hwmon2=devices/pci0000:00/0000:00:09.0 hwmon4=devices/pci0000:00/0000:00:09.0/i2c-56/56-004c -DEVNAME=hwmon2=scd_fan_p3 hwmon4=max6658 -FCTEMPS=hwmon2/pwm6=hwmon4/temp1_input hwmon2/pwm5=hwmon4/temp1_input hwmon2/pwm4=hwmon4/temp1_input hwmon2/pwm4=hwmon4/temp1_input hwmon2/pwm2=hwmon4/temp1_input hwmon2/pwm1=hwmon4/temp1_input +DEVPATH=hwmon2=devices/pci0000:00/0000:00:09.0 hwmon3=devices/pci0000:00/0000:00:09.0/i2c-56/56-004c +DEVNAME=hwmon2=scd_fan_p3 hwmon3=max6658 +FCTEMPS=hwmon2/pwm6=hwmon3/temp1_input hwmon2/pwm5=hwmon3/temp1_input hwmon2/pwm4=hwmon3/temp1_input hwmon2/pwm3=hwmon3/temp1_input hwmon2/pwm2=hwmon3/temp1_input hwmon2/pwm1=hwmon3/temp1_input FCFANS=hwmon2/pwm6=hwmon2/fan6_input hwmon2/pwm5=hwmon2/fan5_input hwmon2/pwm4=hwmon2/fan4_input hwmon2/pwm3=hwmon2/fan3_input hwmon2/pwm2=hwmon2/fan2_input hwmon2/pwm1=hwmon2/fan1_input MINTEMP=hwmon2/pwm6=50 hwmon2/pwm5=50 hwmon2/pwm4=50 hwmon2/pwm3=50 hwmon2/pwm2=50 hwmon2/pwm1=50 MINPWM=hwmon2/pwm6=128 hwmon2/pwm5=128 hwmon2/pwm4=128 hwmon2/pwm3=128 hwmon2/pwm2=128 hwmon2/pwm1=128 diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index c52f43edbe2e..9ea7795ac085 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit c52f43edbe2ec842d5a807c71a4aba453ce60490 +Subproject commit 9ea7795ac085452bd14e4146a446ef842152e7de diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index c52f43edbe2e..9ea7795ac085 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit c52f43edbe2ec842d5a807c71a4aba453ce60490 +Subproject commit 9ea7795ac085452bd14e4146a446ef842152e7de From 4ea2e5e6dc36197f827d5b4d332953bf03512c65 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Thu, 4 Jun 2020 15:17:28 -0700 Subject: [PATCH 0759/1427] [docker-syncd] Add timeout to force stop syncd container (#4617) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **- Why I did it** When I tested auto-restart feature of swss container by manually killing one of critical processes in it, swss will be stopped. Then syncd container as the peer container should also be stopped as expected. However, I found sometimes syncd container can be stopped, sometimes it can not be stopped. The reason why syncd container can not be stopped is the process (/usr/local/bin/syncd.sh stop) to execute the stop() function will be stuck between the lines 164 –167. Systemd will wait for 90 seconds and then kill this process. 164 # wait until syncd quit gracefully 165 while docker top syncd$DEV | grep -q /usr/bin/syncd; do 166 sleep 0.1 167 done The first thing I did is to profile how long this while loop will spin if syncd container can be normally stopped after swss container is stopped. The result is 5 seconds or 6 seconds. If syncd container can be normally stopped, two messages will be written into syslog: str-a7050-acs-3 NOTICE syncd#dsserve: child /usr/bin/syncd exited status: 134 str-a7050-acs-3 INFO syncd#supervisord: syncd [5] child /usr/bin/syncd exited status: 134 The second thing I did was to add a timer in the condition of while loop to ensure this while loop will be forced to exit after 20 seconds: After that, the testing result is that syncd container can be normally stopped if swss is stopped first. One more thing I want to mention is that if syncd container is stopped during 5 seconds or 6 seconds, then the two log messages can be still seen in syslog. However, if the execution time of while loop is longer than 20 seconds and is forced to exit, although syncd container can be stopped, I did not see these two messages in syslog. Further, although I observed the auto-restart feature of swss container can work correctly right now, I can not make sure the issue which syncd container can not stopped will occur in future. **- How I did it** I added a timer around the while loop in stop() function. This while loop will exit after spinning 20 seconds. Signed-off-by: Yong Zhao --- files/scripts/syncd.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 4ebc35d379ed..045b8a22bfb8 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -163,11 +163,21 @@ stop() { debug "${TYPE} shutdown syncd process ..." /usr/bin/docker exec -i syncd$DEV /usr/bin/syncd_request_shutdown --${TYPE} - # wait until syncd quits gracefully - while docker top syncd$DEV | grep -q /usr/bin/syncd; do + # wait until syncd quits gracefully or force syncd to exit after + # waiting for 20 seconds + start_in_secs=${SECONDS} + end_in_secs=${SECONDS} + timer_threshold=20 + while docker top syncd$DEV | grep -q /usr/bin/syncd \ + && [[ $((end_in_secs - start_in_secs)) -le $timer_threshold ]]; do sleep 0.1 + end_in_secs=${SECONDS} done + if [[ $((end_in_secs - start_in_secs)) -gt $timer_threshold ]]; then + debug "syncd process in container syncd$DEV did not exit gracefully" + fi + /usr/bin/docker exec -i syncd$DEV /bin/sync debug "Finished ${TYPE} shutdown syncd process ..." fi From 65fa874ec561da349f4c69c9f359b598f78367cd Mon Sep 17 00:00:00 2001 From: Sangita Maity Date: Thu, 4 Jun 2020 16:11:15 -0700 Subject: [PATCH 0760/1427] [test] Adding platform.json configuration file unit test (#3911) - What I did In order to allow the SONiC community to check in platform capability file i.e. platform.json file directly under device folder. We need to add this test to make sure the contents of the this file is compliant with platform capability design specified in DPB HLD doc - How I did it Added platformJson_checker.py file in Test folder. Signed-off-by: Sangita Maity --- src/sonic-device-data/src/Makefile | 3 + src/sonic-device-data/tests/media_checker | 2 +- .../tests/platform_json_checker | 99 +++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100755 src/sonic-device-data/tests/platform_json_checker diff --git a/src/sonic-device-data/src/Makefile b/src/sonic-device-data/src/Makefile index aca0cbea2a4d..10525fdeb27e 100644 --- a/src/sonic-device-data/src/Makefile +++ b/src/sonic-device-data/src/Makefile @@ -11,4 +11,7 @@ test: for f in $$(find ../../../device -name media_settings.json); do ./media_checker $$f done + for f in $$(find ../../../device -name platform.json); do + ./platform_json_checker $$f + done popd diff --git a/src/sonic-device-data/tests/media_checker b/src/sonic-device-data/tests/media_checker index 6b4139585a24..132756cb4b77 100755 --- a/src/sonic-device-data/tests/media_checker +++ b/src/sonic-device-data/tests/media_checker @@ -138,7 +138,7 @@ def main(argv): # Load target file if len(argv) == 0: - files = glob.glob('*.json') + files = glob.glob('*media_settings.json') else: files = argv diff --git a/src/sonic-device-data/tests/platform_json_checker b/src/sonic-device-data/tests/platform_json_checker new file mode 100755 index 000000000000..c0257a27e80c --- /dev/null +++ b/src/sonic-device-data/tests/platform_json_checker @@ -0,0 +1,99 @@ +#!/usr/bin/env python +try: + import re + import sys + import glob + import json +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +# TODO: need to remove basestring once migrate to Python 3 and just change to str +try: + basestring +except NameError: + basestring = str + +# Global variable +PORT_ATTRIBUTES = ["index", "lanes", "alias_at_lanes", "breakout_modes"] +ATTR_LEN = len(PORT_ATTRIBUTES) +PORT_REG = "Ethernet(\d+)" +PLATFORM_JSON = '*platform.json' +INTF_KEY = "interfaces" + +def usage(): + print "Usage: " + sys.argv[0] + " " + sys.exit(1) + +def check_port_attr(port_attr): + for each_key in port_attr: + if each_key not in PORT_ATTRIBUTES: + print "Error: "+ each_key + " is not the correct Port attribute." + return False + if not port_attr[each_key]: + print "Error: "+ each_key + " has no value." + return False + # TODO: need to remove basestring once migrate to Python 3 and just change to str + if not isinstance(port_attr[each_key], basestring): + print "Error:value type of "+ each_key + " must be string." + return False + return True + +def check_file(platform_json_file): + try: + platform_cap_file = open(platform_json_file,"r") + platform_file_data = platform_cap_file.read() + port_dict = json.loads(platform_file_data) + + for each_port in port_dict[INTF_KEY]: + # Validate port at top level + port_id = re.search(PORT_REG, each_port) + if port_id is None: + print "Error: Unknown Interface " + str(each_port) + " at top level" + return False + + total_attr = len(port_dict[INTF_KEY][each_port].keys()) + port_attr = port_dict[INTF_KEY][each_port] + + if total_attr != ATTR_LEN: + missing_attr = ', '.join(set(PORT_ATTRIBUTES).difference(list(port_attr))) + print "Error: " + missing_attr + " of " + each_port + " is/are missing" + return False + + #Validate port attributes for each port + if not check_port_attr(port_attr): + return False + except IOError: + print "Error: Cannot open file " + platform_json_file + return False + except ValueError,e: + print "Error in parsing json file " + platform_json_file + " " + print str(e) + return False + return True + +def main(argv): + if len(argv) > 0 and argv[0] == "-h": + usage() + + # Load target file + if len(argv) == 0: + files = glob.glob(PLATFORM_JSON) + else: + files = argv + + all_good = True + + for f in files: + good = check_file(f) + if good: + print "File " + f + " passed validity check" + else: + print "File " + f + " failed validity check" + + all_good = all_good and good + + if not all_good: + sys.exit(-1) + +if __name__ == "__main__": + main(sys.argv[1:]) From 6b332f74a028087abee01cd28ac16ed1ffc3aa74 Mon Sep 17 00:00:00 2001 From: taochengyi <54564117+taocy001@users.noreply.github.com> Date: Sat, 6 Jun 2020 03:56:35 +0800 Subject: [PATCH 0761/1427] [centec_syncd_rpc] fix build failure when set ENABLE_SYNCD_RPC=y (#4690) --- platform/centec/rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/centec/rules.mk b/platform/centec/rules.mk index 873380c04467..6f3ac98ecab4 100644 --- a/platform/centec/rules.mk +++ b/platform/centec/rules.mk @@ -12,7 +12,7 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) # Inject centec sai into sairedis $(LIBSAIREDIS)_DEPENDS += $(CENTEC_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV_CENTEC) +$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on centec sai is set only for syncd From d491c0229439134f57a3b9dfb3face9518f825a8 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Mon, 8 Jun 2020 09:48:10 -0700 Subject: [PATCH 0762/1427] [submodule]: update submodules sonic-sairedis, sonic-swss-common (#4722) [sonic-sairedis] * 322dd01 2020-06-05 | Fix debian/rules makefile: use shell commands instead of dollar replacements (#621) (HEAD -> master, origin/master, origin/HEAD) [Qi Luo] * 6d55a75 2020-06-04 | Update SAI pointer to 1.6.1 (#620) [Mahesh Maddikayala] * d6c40e5 2020-06-01 | [MultiDB] use get API to obtain dbid instead of hardcode value (#618) [Dong Zhang] * bd132ec 2020-06-01 | Add synchronous mode to sairedis library (#617) [Kamil Cudnik] * 0a77a09 2020-06-01 | [meta] Fix tests to be backward compatible (#619) [Kamil Cudnik] [sonic-swss-common] * 35bc01a 2020-06-05 | EVPN VXLAN DB support (#339) (HEAD -> master, origin/master, origin/HEAD) [Rajesh Sankaran] * 2c7354b 2020-05-30 | Add modifyRedis flag to consumer table object (#344) [Kamil Cudnik] * 5a32636 2020-05-27 | Fix memory leak in pyext when Selectable is returned to Python (#343) [pavel-shirshov] --- src/sonic-sairedis | 2 +- src/sonic-swss-common | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index ebdf4fff1ce4..322dd01db434 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit ebdf4fff1ce4db87886629ef7a9e251ee41390d1 +Subproject commit 322dd01db434d00394898d4d1ac34433e95447cd diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 6889c0aba53c..35bc01a70946 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 6889c0aba53c96c1935374e5a442e12a97941eee +Subproject commit 35bc01a709464ad19eda2ae35a605987fe689fa1 From 7525fea666d31522434a5259aa8b62b9162bc67b Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Mon, 8 Jun 2020 13:36:56 -0700 Subject: [PATCH 0763/1427] [MultiDB] daemon base should use multiDB DBConnector (#4549) * [MultiDB] daemon base should use multiDB DBConnector * [sonic-platform-daemon] update submodule for multiDB changes --- .../sonic_daemon_base/daemon_base.py | 14 ++++---------- src/sonic-platform-daemons | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index d3807bf91524..0d532a85c1dd 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -14,11 +14,6 @@ # Constants ==================================================================== # -# Redis DB information -REDIS_HOSTNAME = 'localhost' -REDIS_PORT = 6379 -REDIS_TIMEOUT_MSECS = 0 - # Platform root directory inside docker PLATFORM_ROOT_DOCKER = '/usr/share/sonic/platform' SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' @@ -36,12 +31,11 @@ # Helper functions ============================================================= # -def db_connect(db): +def db_connect(db_name): from swsscommon import swsscommon - return swsscommon.DBConnector(db, - REDIS_HOSTNAME, - REDIS_PORT, - REDIS_TIMEOUT_MSECS) + return swsscommon.DBConnector(db_name, + REDIS_TIMEOUT_MSECS, + True) # # Helper classes =============================================================== diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 6e975f5f6111..0f4fd835f324 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 6e975f5f61111d399f5f5b44177bba8b4be8162c +Subproject commit 0f4fd835f324cb754a8b955f9a5fad6b54d7d6dc From af81b8ebcd4413067ea1ee921b10d6012b192515 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Mon, 8 Jun 2020 17:03:09 -0700 Subject: [PATCH 0764/1427] [libsaibcm] Update pointer to Broadcom SAI debian package (#4725) --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 76934d37ee1b..572ae0a70f68 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,8 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.4.2_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.4.2_amd64.deb?sv=2015-04-05&sr=b&sig=Iqgd1HDmXOa%2F2OEnez1D4dQ4wVICZlnvVOYao1FYlio%3D&se=2034-01-14T18%3A51%3A07Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.4.2_amd64.deb +BRCM_SAI = libsaibcm_3.7.4.2-2_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.4.2-2_amd64.deb?sv=2015-04-05&sr=b&sig=sl819d71a%2BcgrDtOt%2BmywfSL9N2EQS58qMJFq0aKqo8%3D&se=2034-02-11T20%3A28%3A46Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_3.7.4.2-2_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.4.2_amd64.deb?sv=2015-04-05&sr=b&sig=cbQJOwQcILWYbjuI3LObY6H7bvCNijKfEkdAIrm3Q64%3D&se=2034-01-14T18%3A49%3A15Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.4.2-2_amd64.deb?sv=2015-04-05&sr=b&sig=cvOpP0PWFVmBNeYLMkxyI4BFBQf1DopD32t%2B3AkJHRg%3D&se=2034-02-11T20%3A27%3A46Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From e28cb8f58ec28f02a47724e66b46285788cf870d Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Tue, 9 Jun 2020 15:25:17 +0800 Subject: [PATCH 0765/1427] [Secure Boot] Support to sign swi image (#4627) * [secure boot] Support to sign swi image * Fix build issue * fix tab format issue * Fix typing issue * Change the sign_image.sh command line * Remove SONIC_CETIFICATE_PATH * Fix bugs --- Makefile.work | 1 + build_image.sh | 6 +++ rules/config | 7 ++++ scripts/sign_image.sh | 69 +++++++++++++++++++++++++++++++ slave.mk | 5 +++ sonic-slave-buster/Dockerfile.j2 | 7 +++- sonic-slave-jessie/Dockerfile.j2 | 3 ++ sonic-slave-stretch/Dockerfile.j2 | 7 +++- 8 files changed, 103 insertions(+), 2 deletions(-) create mode 100755 scripts/sign_image.sh diff --git a/Makefile.work b/Makefile.work index 11e79f6b81ab..ad8231326a18 100644 --- a/Makefile.work +++ b/Makefile.work @@ -202,6 +202,7 @@ SONIC_BUILD_INSTRUCTION := make \ SONIC_ENABLE_RESTAPI=$(ENABLE_RESTAPI) \ EXTRA_DOCKER_TARGETS=$(EXTRA_DOCKER_TARGETS) \ BUILD_LOG_TIMESTAMP=$(BUILD_LOG_TIMESTAMP) \ + SONIC_ENABLE_IMAGE_SIGNATURE=$(ENABLE_IMAGE_SIGNATURE) \ $(SONIC_OVERRIDE_BUILD_VARS) .PHONY: sonic-slave-build sonic-slave-bash init reset diff --git a/build_image.sh b/build_image.sh index cd8c26da1225..2768c0eeee24 100755 --- a/build_image.sh +++ b/build_image.sh @@ -146,6 +146,12 @@ elif [ "$IMAGE_TYPE" = "aboot" ]; then zip -g $OUTPUT_ABOOT_IMAGE $ABOOT_BOOT_IMAGE rm $ABOOT_BOOT_IMAGE + if [ "$SONIC_ENABLE_IMAGE_SIGNATURE" = "y" ]; then + TARGET_CA_CERT="$TARGET_PATH/ca.cert" + rm -f "$TARGET_CA_CERT" + [ -f "$CA_CERT" ] && cp "$CA_CERT" "$TARGET_CA_CERT" + ./scripts/sign_image.sh -i "$OUTPUT_ABOOT_IMAGE" -k "$SIGNING_KEY" -c "$SIGNING_CERT" -a "$TARGET_CA_CERT" + fi else echo "Error: Non supported image type $IMAGE_TYPE" exit 1 diff --git a/rules/config b/rules/config index ab8a6941426d..9b5f27d765b1 100644 --- a/rules/config +++ b/rules/config @@ -145,3 +145,10 @@ KUBERNETES_VERSION = 1.18.0 K8s_GCR_IO_PAUSE_VERSION = 3.2 K8s_CNI_CALICO_VERSION = 3.12.1 +# SONIC_ENABLE_IMAGE_SIGNATURE - enable image signature +# To not use the auto-generated self-signed certificate, the required files to sign the image as below: +# SIGNING_KEY = +# SIGNING_CERT = +# CA_CERT = +# The relative path is build root folder. +SONIC_ENABLE_IMAGE_SIGNATURE ?= n diff --git a/scripts/sign_image.sh b/scripts/sign_image.sh new file mode 100755 index 000000000000..f726ad130cb8 --- /dev/null +++ b/scripts/sign_image.sh @@ -0,0 +1,69 @@ +#!/bin/bash -ex + + +IMAGE="" +SIGNING_KEY="" +SIGNING_CERT="" +CA_CERT="" + +usage() +{ + echo "Usage: $0 -i [-k -c -a ]" + exit 1 +} + +generate_signing_key() +{ + TMP_CERT_PATH=$(mktemp -d) + SIGNING_KEY="${TMP_CERT_PATH}/signing.key" + SIGNING_CERT="${TMP_CERT_PATH}/signing.crt" + SIGNING_CSR="${TMP_CERT_PATH}/signing.csr" + CA_KEY="${TMP_CERT_PATH}/ca.key" + + # Generate the CA key and certificate + openssl genrsa -out $CA_KEY 4096 + openssl req -x509 -new -nodes -key $CA_KEY -sha256 -days 3650 -subj "/C=US/ST=Test/L=Test/O=Test/CN=Test" -out $CA_CERT + + # Generate the signing key, certificate request and certificate + openssl genrsa -out $SIGNING_KEY 4096 + openssl req -new -key $SIGNING_KEY -subj "/C=US/ST=Test/L=Test/O=Test/CN=Test" -out $SIGNING_CSR + openssl x509 -req -in $SIGNING_CSR -CA $CA_CERT -CAkey $CA_KEY -CAcreateserial -out $SIGNING_CERT -days 1825 -sha256 +} + +while getopts "i:k:c:a:t:" opt; do + case $opt in + i) + IMAGE=$OPTARG + ;; + k) + SIGNING_KEY=$OPTARG + ;; + c) + SIGNING_CERT=$OPTARG + ;; + a) + CA_CERT=$OPTARG + ;; + *) + usage + ;; + esac +done + +[ -z $CA_CERT ] && echo "Not to sign the image since the CA certificate not provided" 1>&2 && exit 1 + +# Generate the self signed cert if not provided by input +[ ! -f $CA_CERT ] && generate_signing_key + +# Verify the required files existing +[ ! -f $SIGNING_KEY ] && echo "$SIGNING_KEY not exist" && exit 1 +[ ! -f $SIGNING_CERT ] && echo "$SIGNING_CERT not exist" && exit 1 +[ ! -f $CA_CERT ] && echo "$CA_CERT not exist" && exit 1 + +# Prepare the image +swi-signature prepare $IMAGE + +# Sign the image +swi-signature sign $IMAGE $SIGNING_CERT $CA_CERT --key $SIGNING_KEY + +exit 0 diff --git a/slave.mk b/slave.mk index 06736eafe42e..4b14f4fea227 100644 --- a/slave.mk +++ b/slave.mk @@ -894,6 +894,11 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ PASSWORD="$(PASSWORD)" \ TARGET_MACHINE=$($*_MACHINE) \ IMAGE_TYPE=$($*_IMAGE_TYPE) \ + SONIC_ENABLE_IMAGE_SIGNATURE="$(SONIC_ENABLE_IMAGE_SIGNATURE)" \ + SIGNING_KEY="$(SIGNING_KEY)" \ + SIGNING_CERT="$(SIGNING_CERT)" \ + CA_CERT="$(CA_CERT)" \ + TARGET_PATH="$(TARGET_PATH)" \ ./build_image.sh $(LOG) $(foreach docker, $($*_DOCKERS), \ diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 05dc07410ae2..3e3191264790 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -304,7 +304,9 @@ RUN apt-get update && apt-get install -y \ xxd \ # For DHCP Monitor tool libexplain-dev \ - libevent-dev + libevent-dev \ +# For SWI Tools + python-m2crypto ## Config dpkg ## install the configuration file if it’s currently missing @@ -423,3 +425,6 @@ RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian {%- endif %} RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker RUN update-alternatives --set iptables /usr/sbin/iptables-legacy + +# Install swi tools +RUN python -m pip install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index 49c330495ae0..f4278bf5c299 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -372,3 +372,6 @@ RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/d RUN echo "deb [arch={{ CONFIGURED_ARCH }}] http://archive.debian.org/debian jessie-backports main" >> /etc/apt/sources.list RUN apt-get -o Acquire::Check-Valid-Until=false update RUN apt-get -y -o Acquire::Check-Valid-Until=false install ca-certificates-java=20161107~bpo8+1 openjdk-8-jdk + +# Install swi tools +RUN python -m pip install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 9d80560e5b4c..a7266806437a 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -300,7 +300,9 @@ RUN apt-get update && apt-get install -y \ xxd \ # For DHCP Monitor tool libexplain-dev \ - libevent-dev + libevent-dev \ +# For SWI Tools + python-m2crypto ## Config dpkg ## install the configuration file if it’s currently missing @@ -437,3 +439,6 @@ RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-stretch docker-ce-cli=5:18 RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian {%- endif %} RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker + +# Install swi tools +RUN python -m pip install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 From 9505bdb91093e5f3b3defbdd68b855dd68af850f Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Tue, 9 Jun 2020 09:07:25 -0700 Subject: [PATCH 0766/1427] [docker-syncd-vs]: Convert syncd-vs docker to buster (#4726) Signed-off-by: Joyas Joseph --- platform/barefoot/docker-syncd-bfn.mk | 3 +++ platform/broadcom/docker-syncd-brcm.mk | 3 +++ platform/centec/docker-syncd-centec.mk | 2 ++ platform/innovium/docker-syncd-invm.mk | 3 +++ platform/marvell-arm64/docker-syncd-mrvl.mk | 3 +++ platform/marvell-armhf/docker-syncd-mrvl.mk | 3 +++ platform/marvell/docker-syncd-mrvl.mk | 3 +++ platform/mellanox/docker-syncd-mlnx.mk | 3 +++ platform/nephos/docker-syncd-nephos.mk | 3 +++ platform/template/docker-syncd-base.mk | 11 ++++++++--- platform/vs/docker-syncd-vs/Dockerfile.j2 | 4 ++-- 11 files changed, 36 insertions(+), 5 deletions(-) diff --git a/platform/barefoot/docker-syncd-bfn.mk b/platform/barefoot/docker-syncd-bfn.mk index 3a5c693e2fa8..ae4ca9d9f272 100644 --- a/platform/barefoot/docker-syncd-bfn.mk +++ b/platform/barefoot/docker-syncd-bfn.mk @@ -10,5 +10,8 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/broadcom/docker-syncd-brcm.mk b/platform/broadcom/docker-syncd-brcm.mk index d3a6d67c5cbc..71a834ab67df 100644 --- a/platform/broadcom/docker-syncd-brcm.mk +++ b/platform/broadcom/docker-syncd-brcm.mk @@ -11,6 +11,9 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd diff --git a/platform/centec/docker-syncd-centec.mk b/platform/centec/docker-syncd-centec.mk index 9d512b12b459..ada63a218d4a 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -10,6 +10,8 @@ $(DOCKER_SYNCD_CENTEC)_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) $(DOCKER_SYNCD_CENTEC)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf diff --git a/platform/innovium/docker-syncd-invm.mk b/platform/innovium/docker-syncd-invm.mk index 3ba35c5edb97..52c11b90911d 100755 --- a/platform/innovium/docker-syncd-invm.mk +++ b/platform/innovium/docker-syncd-invm.mk @@ -10,4 +10,7 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/marvell-arm64/docker-syncd-mrvl.mk b/platform/marvell-arm64/docker-syncd-mrvl.mk index 841e3b4b165f..dd01caab687b 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl.mk @@ -10,5 +10,8 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell-armhf/docker-syncd-mrvl.mk b/platform/marvell-armhf/docker-syncd-mrvl.mk index 841e3b4b165f..dd01caab687b 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl.mk +++ b/platform/marvell-armhf/docker-syncd-mrvl.mk @@ -10,5 +10,8 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell/docker-syncd-mrvl.mk b/platform/marvell/docker-syncd-mrvl.mk index 97b7eab19895..d6d7d032b8ac 100644 --- a/platform/marvell/docker-syncd-mrvl.mk +++ b/platform/marvell/docker-syncd-mrvl.mk @@ -10,6 +10,9 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/mellanox/docker-syncd-mlnx.mk b/platform/mellanox/docker-syncd-mlnx.mk index 9bdc5a8ad8ec..c89d8dbc4ddc 100644 --- a/platform/mellanox/docker-syncd-mlnx.mk +++ b/platform/mellanox/docker-syncd-mlnx.mk @@ -14,5 +14,8 @@ ifeq ($(SDK_FROM_SRC), y) $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(MLNX_SDK_DBG_DEBS) $(MLNX_SAI_DBGSYM) endif +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/nephos/docker-syncd-nephos.mk b/platform/nephos/docker-syncd-nephos.mk index 67bad252870a..146523ec1c64 100644 --- a/platform/nephos/docker-syncd-nephos.mk +++ b/platform/nephos/docker-syncd-nephos.mk @@ -11,6 +11,9 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd diff --git a/platform/template/docker-syncd-base.mk b/platform/template/docker-syncd-base.mk index d0407beee8a0..d95d7a141920 100644 --- a/platform/template/docker-syncd-base.mk +++ b/platform/template/docker-syncd-base.mk @@ -9,25 +9,30 @@ $(DOCKER_SYNCD_BASE)_PATH = $(PLATFORM_PATH)/docker-syncd-$(DOCKER_SYNCD_PLATFOR $(DOCKER_SYNCD_BASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +ifeq ($(BLDENV),stretch) $(DOCKER_SYNCD_BASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_SYNCD_BASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +else +$(DOCKER_SYNCD_BASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) + +$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) + +$(DOCKER_SYNCD_BASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) +endif SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BASE) -SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) ifneq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BASE) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_SYNCD_BASE_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) ifneq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SYNCD_BASE_DBG) endif - $(DOCKER_SYNCD_BASE)_CONTAINER_NAME = syncd $(DOCKER_SYNCD_BASE)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf diff --git a/platform/vs/docker-syncd-vs/Dockerfile.j2 b/platform/vs/docker-syncd-vs/Dockerfile.j2 index 25d82499edf1..fea26b2f103e 100644 --- a/platform/vs/docker-syncd-vs/Dockerfile.j2 +++ b/platform/vs/docker-syncd-vs/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -8,7 +8,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update -RUN apt-get install -f -y iproute2=4.20.0-2~bpo9+1 libcap2-bin=1:2.25-1 +RUN apt-get install -f -y iproute2=4.20.0-2 libcap2-bin=1:2.25-2 COPY \ {% for deb in docker_syncd_vs_debs.split(' ') -%} From 54b284f4b0eb94f466c7dd561d468dda7be27967 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Tue, 9 Jun 2020 21:38:15 +0530 Subject: [PATCH 0767/1427] [DellEMC]: EEPROM decoder for S6000, S6000-ON (#4718) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **- Why I did it** For decoding system EEPROM of S6000 based on Dell offset format and S6000-ON’s system EEPROM in ONIE TLV format. **- How I did it** - Differentiate between S6000 and S6000-ON using the product name available in ‘dmi’ ( “/sys/class/dmi/id/product_name†) - For decoding S6000 system EEPROM in Dell offset format and updating the redis DB with the EEPROM contents, added a new class ‘EepromS6000’ in eeprom.py, - Renamed certain methods in both Eeprom, EepromS6000 classes to accommodate the plugin-specific methods. **- How to verify it** - Use 'decode-syseeprom' command to list the system EEPROM details. - Wrote a python script to load chassis class and call the appropriate methods. UT Logs: [S6000_eeprom_logs.txt](https://github.com/Azure/sonic-buildimage/files/4735515/S6000_eeprom_logs.txt), [S6000-ON_eeprom_logs.txt](https://github.com/Azure/sonic-buildimage/files/4735461/S6000-ON_eeprom_logs.txt) Test script: [eeprom_test_py.txt](https://github.com/Azure/sonic-buildimage/files/4735509/eeprom_test_py.txt) --- .../plugins/eeprom.py | 22 +- .../s6000/sonic_platform/chassis.py | 21 +- .../s6000/sonic_platform/eeprom.py | 264 +++++++++++++++++- .../s6000/sonic_platform/fan.py | 4 +- .../s6000/sonic_platform/psu.py | 4 +- 5 files changed, 292 insertions(+), 23 deletions(-) diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/eeprom.py b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/eeprom.py index b326d24f6d44..10364c2c9f8e 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/eeprom.py @@ -10,13 +10,21 @@ ############################################################################# try: - from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + from sonic_eeprom.eeprom_tlvinfo import TlvInfoDecoder + from sonic_platform.eeprom import EepromS6000 +except ImportError as e: + raise ImportError(str(e) + "- required module not found") -class board(eeprom_tlvinfo.TlvInfoDecoder): +class board(object): - def __init__(self, name, path, cpld_root, ro): - self.eeprom_path = "/sys/class/i2c-adapter/i2c-10/10-0053/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) + def __new__(cls, name, path, cpld_root, ro): + eeprom_path = "/sys/class/i2c-adapter/i2c-10/10-0053/eeprom" + + with open("/sys/class/dmi/id/product_name", "r") as fd: + board_type = fd.read() + + if 'S6000-ON' in board_type: + return TlvInfoDecoder(eeprom_path, 0, '', True) + else: + return EepromS6000(is_plugin=True) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index 0a6cac372676..06fb6c2ff0e9 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -15,7 +15,7 @@ import subprocess from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp - from sonic_platform.eeprom import Eeprom + from sonic_platform.eeprom import Eeprom, EepromS6000 from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal @@ -68,7 +68,14 @@ def __init__(self): # Get Transceiver status self.modprs_register = self._get_transceiver_status() - self._eeprom = Eeprom() + with open("/sys/class/dmi/id/product_name", "r") as fd: + board_type = fd.read() + + if 'S6000-ON' in board_type: + self._eeprom = Eeprom() + else: + self._eeprom = EepromS6000() + for i in range(MAX_S6000_FAN): fan = Fan(i) self._fan_list.append(fan) @@ -138,7 +145,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self._eeprom.modelstr() + return self._eeprom.get_model() def get_presence(self): """ @@ -154,7 +161,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self._eeprom.part_number_str() + return self._eeprom.get_part_number() def get_serial(self): """ @@ -162,7 +169,7 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self._eeprom.serial_str() + return self._eeprom.get_serial() def get_status(self): """ @@ -181,7 +188,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self._eeprom.base_mac_addr() + return self._eeprom.get_base_mac() def get_serial_number(self): """ @@ -191,7 +198,7 @@ def get_serial_number(self): A string containing the hardware serial number for this chassis. """ - return self._eeprom.serial_number_str() + return self._eeprom.get_serial_number() def get_system_eeprom_info(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py index a82fd6a70201..1a8a3a84b601 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py @@ -17,12 +17,17 @@ try: + import binascii import os + import redis + import struct + from collections import OrderedDict from sonic_platform_base.sonic_eeprom.eeprom_base import EepromDecoder from sonic_platform_base.sonic_eeprom.eeprom_tlvinfo import TlvInfoDecoder except ImportError as e: raise ImportError(str(e) + "- required module not found") +STATE_DB_INDEX = 6 # PSU eeprom fields in format required by EepromDecoder psu_eeprom_format = [ @@ -200,13 +205,13 @@ def _get_eeprom_field(self, field_name): return (False, None) - def serial_number_str(self): + def get_serial_number(self): """ Returns the serial number. """ return self.serial_number - def part_number_str(self): + def get_part_number(self): """ Returns the part number. """ @@ -222,19 +227,19 @@ def airflow_fan_type(self): return int(self.fan_type.encode('hex'), 16) # System EEPROM specific methods - def base_mac_addr(self): + def get_base_mac(self): """ Returns the base MAC address found in the system EEPROM. """ return self.base_mac - def modelstr(self): + def get_model(self): """ Returns the Model name. """ return self.model_str - def serial_str(self): + def get_serial(self): """ Returns the servicetag number. """ @@ -247,3 +252,252 @@ def system_eeprom_info(self): found in the system EEPROM. """ return self.eeprom_tlv_dict + + +class EepromS6000(EepromDecoder): + + _EEPROM_MAX_LEN = 128 + + _BLK_HDR_LEN = 6 + _BLK_HDR_MAGIC = '\x3a\x29' + _BLK_HDR_REVID = 1 + + _BLK_CODE_MFG = 0x20 + _BLK_CODE_SW = 0x1F + _BLK_CODE_MAC = 0x21 + + _BLK_MFG_FORMAT = [ + ("PPID", 20), ("DPN Rev", 3), ("Service Tag", 7), ("Part Number", 10), + ("Part Number Rev", 3), ("Mfg Test Results", 2) + ] + + _BLK_SW_FORMAT = [("Card ID", 4), ("Module ID", 2)] + _BLK_MAC_FORMAT = [("Base MAC address", 6)] + + _BLK_INFO = OrderedDict([ + (_BLK_CODE_MFG, {"name": "MFG BLOCK", "size": 64, + "offset": 0x0, "format": _BLK_MFG_FORMAT}), + (_BLK_CODE_SW, {"name": "SW BLOCK", "size": 48, + "offset": 0x40, "format": _BLK_SW_FORMAT}), + (_BLK_CODE_MAC, {"name": "MAC BLOCK", "size": 16, + "offset": 0x70, "format": _BLK_MAC_FORMAT}) + ]) + + def __init__(self, is_plugin=False): + self.eeprom_path = "/sys/bus/i2c/devices/i2c-10/10-0053/eeprom" + super(EepromS6000, self).__init__(self.eeprom_path, None, 0, '', True) + + if not is_plugin: + self.eeprom_data = self.read_eeprom() + + def _is_valid_block_checksum(self, e): + crc = self.compute_dell_crc(e[:-2]) + return crc == struct.unpack('3d} {:3d} {: Date: Tue, 9 Jun 2020 09:09:14 -0700 Subject: [PATCH 0768/1427] [submodule update]: Advance sonic-snmpagent and sonic-py-swsssdk (#4713) Update sonic-snmpagent submodule with PRs: 89b7b2c [Multi-asic]: Namespace support for LLDP and Sensor tables (#131) fcb8955 Simplify test code (#132) a677876 [Multi-asic]: Support multi-asic platform (#126) update sonic-py-swsssdk submodule with PRs: 132f8d5 [MultiDB]: use python class composition to avoid confusion in base class (#74) Signed-off-by: SuvarnaMeenakshi --- src/sonic-py-swsssdk | 2 +- src/sonic-snmpagent | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 9fab7297cd4a..132f8d5f1b00 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 9fab7297cd4a577ffceb50df99139942879108f1 +Subproject commit 132f8d5f1b00fb8a1b3cdbd7a5c69bb89cfff0e3 diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index c8e5757b7f54..89b7b2c90099 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit c8e5757b7f5495607bbf13d936f106991c13ddf5 +Subproject commit 89b7b2c90099bc3404edeb1210b0aa90070a6a80 From 9b27efdcc23d059a5c2c2f4b85c70e8416b8c466 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 9 Jun 2020 09:09:56 -0700 Subject: [PATCH 0769/1427] [dockers] Rename 'docker-lldp-sv2' to 'docker-lldp' (#4700) The -sv2 suffix was used to differentiate SNMP Dockers when we transitioned from "SONiCv1" to "SONiCv2", about four years ago. The old Docker materials were removed long ago; there is no need to keep this suffix. Removing it aligns the name with all the other Dockers. --- .../Dockerfile.j2 | 12 +++---- .../base_image_files/lldpcli | 0 .../base_image_files/lldpctl | 0 .../base_image_files/monit_lldp | 0 .../critical_processes | 0 .../docker-lldp-init.sh | 0 .../{docker-lldp-sv2 => docker-lldp}/lldpd | 0 .../lldpd.conf.j2 | 0 .../{docker-lldp-sv2 => docker-lldp}/lldpmgrd | 0 .../{docker-lldp-sv2 => docker-lldp}/start.sh | 0 .../supervisord.conf.j2 | 0 .../waitfor_lldp_ready.sh | 0 platform/generic/rules.mk | 2 +- rules/docker-lldp-sv2.dep | 11 ------- rules/docker-lldp-sv2.mk | 32 ------------------- rules/docker-lldp.dep | 11 +++++++ rules/docker-lldp.mk | 32 +++++++++++++++++++ src/sonic-config-engine/tests/test_j2files.py | 2 +- 18 files changed, 51 insertions(+), 51 deletions(-) rename dockers/{docker-lldp-sv2 => docker-lldp}/Dockerfile.j2 (79%) rename dockers/{docker-lldp-sv2 => docker-lldp}/base_image_files/lldpcli (100%) rename dockers/{docker-lldp-sv2 => docker-lldp}/base_image_files/lldpctl (100%) rename dockers/{docker-lldp-sv2 => docker-lldp}/base_image_files/monit_lldp (100%) rename dockers/{docker-lldp-sv2 => docker-lldp}/critical_processes (100%) rename dockers/{docker-lldp-sv2 => docker-lldp}/docker-lldp-init.sh (100%) rename dockers/{docker-lldp-sv2 => docker-lldp}/lldpd (100%) rename dockers/{docker-lldp-sv2 => docker-lldp}/lldpd.conf.j2 (100%) rename dockers/{docker-lldp-sv2 => docker-lldp}/lldpmgrd (100%) rename dockers/{docker-lldp-sv2 => docker-lldp}/start.sh (100%) rename dockers/{docker-lldp-sv2 => docker-lldp}/supervisord.conf.j2 (100%) rename dockers/{docker-lldp-sv2 => docker-lldp}/waitfor_lldp_ready.sh (100%) delete mode 100644 rules/docker-lldp-sv2.dep delete mode 100644 rules/docker-lldp-sv2.mk create mode 100644 rules/docker-lldp.dep create mode 100644 rules/docker-lldp.mk diff --git a/dockers/docker-lldp-sv2/Dockerfile.j2 b/dockers/docker-lldp/Dockerfile.j2 similarity index 79% rename from dockers/docker-lldp-sv2/Dockerfile.j2 rename to dockers/docker-lldp/Dockerfile.j2 index 15e755e6c6ed..6024e844f1e0 100644 --- a/dockers/docker-lldp-sv2/Dockerfile.j2 +++ b/dockers/docker-lldp/Dockerfile.j2 @@ -10,20 +10,20 @@ ENV DEBIAN_FRONTEND=noninteractive # Update apt's cache of available packages RUN apt-get update -{% if docker_lldp_sv2_debs.strip() -%} +{% if docker_lldp_debs.strip() -%} # Copy locally-built Debian package dependencies -{{ copy_files("debs/", docker_lldp_sv2_debs.split(' '), "/debs/") }} +{{ copy_files("debs/", docker_lldp_debs.split(' '), "/debs/") }} # Install locally-built Debian packages and implicitly install their dependencies -{{ install_debian_packages(docker_lldp_sv2_debs.split(' ')) }} +{{ install_debian_packages(docker_lldp_debs.split(' ')) }} {%- endif %} -{% if docker_lldp_sv2_whls.strip() -%} +{% if docker_lldp_whls.strip() -%} # Copy locally-built Python wheel dependencies -{{ copy_files("python-wheels/", docker_lldp_sv2_whls.split(' '), "/python-wheels/") }} +{{ copy_files("python-wheels/", docker_lldp_whls.split(' '), "/python-wheels/") }} # Install locally-built Python wheel dependencies -{{ install_python_wheels(docker_lldp_sv2_whls.split(' ')) }} +{{ install_python_wheels(docker_lldp_whls.split(' ')) }} {% endif %} # Clean up diff --git a/dockers/docker-lldp-sv2/base_image_files/lldpcli b/dockers/docker-lldp/base_image_files/lldpcli similarity index 100% rename from dockers/docker-lldp-sv2/base_image_files/lldpcli rename to dockers/docker-lldp/base_image_files/lldpcli diff --git a/dockers/docker-lldp-sv2/base_image_files/lldpctl b/dockers/docker-lldp/base_image_files/lldpctl similarity index 100% rename from dockers/docker-lldp-sv2/base_image_files/lldpctl rename to dockers/docker-lldp/base_image_files/lldpctl diff --git a/dockers/docker-lldp-sv2/base_image_files/monit_lldp b/dockers/docker-lldp/base_image_files/monit_lldp similarity index 100% rename from dockers/docker-lldp-sv2/base_image_files/monit_lldp rename to dockers/docker-lldp/base_image_files/monit_lldp diff --git a/dockers/docker-lldp-sv2/critical_processes b/dockers/docker-lldp/critical_processes similarity index 100% rename from dockers/docker-lldp-sv2/critical_processes rename to dockers/docker-lldp/critical_processes diff --git a/dockers/docker-lldp-sv2/docker-lldp-init.sh b/dockers/docker-lldp/docker-lldp-init.sh similarity index 100% rename from dockers/docker-lldp-sv2/docker-lldp-init.sh rename to dockers/docker-lldp/docker-lldp-init.sh diff --git a/dockers/docker-lldp-sv2/lldpd b/dockers/docker-lldp/lldpd similarity index 100% rename from dockers/docker-lldp-sv2/lldpd rename to dockers/docker-lldp/lldpd diff --git a/dockers/docker-lldp-sv2/lldpd.conf.j2 b/dockers/docker-lldp/lldpd.conf.j2 similarity index 100% rename from dockers/docker-lldp-sv2/lldpd.conf.j2 rename to dockers/docker-lldp/lldpd.conf.j2 diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp/lldpmgrd similarity index 100% rename from dockers/docker-lldp-sv2/lldpmgrd rename to dockers/docker-lldp/lldpmgrd diff --git a/dockers/docker-lldp-sv2/start.sh b/dockers/docker-lldp/start.sh similarity index 100% rename from dockers/docker-lldp-sv2/start.sh rename to dockers/docker-lldp/start.sh diff --git a/dockers/docker-lldp-sv2/supervisord.conf.j2 b/dockers/docker-lldp/supervisord.conf.j2 similarity index 100% rename from dockers/docker-lldp-sv2/supervisord.conf.j2 rename to dockers/docker-lldp/supervisord.conf.j2 diff --git a/dockers/docker-lldp-sv2/waitfor_lldp_ready.sh b/dockers/docker-lldp/waitfor_lldp_ready.sh similarity index 100% rename from dockers/docker-lldp-sv2/waitfor_lldp_ready.sh rename to dockers/docker-lldp/waitfor_lldp_ready.sh diff --git a/platform/generic/rules.mk b/platform/generic/rules.mk index bc2507740277..5ba91194090a 100644 --- a/platform/generic/rules.mk +++ b/platform/generic/rules.mk @@ -2,7 +2,7 @@ include $(PLATFORM_PATH)/aboot-image.mk include $(PLATFORM_PATH)/onie-image.mk SONIC_ALL += $(DOCKER_DATABASE) \ - $(DOCKER_LLDP_SV2) \ + $(DOCKER_LLDP) \ $(DOCKER_SNMP_SV2) \ $(DOCKER_PLATFORM_MONITOR) \ $(DOCKER_DHCP_RELAY) \ diff --git a/rules/docker-lldp-sv2.dep b/rules/docker-lldp-sv2.dep deleted file mode 100644 index 185d85032d49..000000000000 --- a/rules/docker-lldp-sv2.dep +++ /dev/null @@ -1,11 +0,0 @@ - -DPATH := $($(DOCKER_LLDP_SV2)_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-lldp-sv2.mk rules/docker-lldp-sv2.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(DPATH)) - -$(DOCKER_LLDP_SV2)_CACHE_MODE := GIT_CONTENT_SHA -$(DOCKER_LLDP_SV2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(DOCKER_LLDP_SV2)_DEP_FILES := $(DEP_FILES) - -$(eval $(call add_dbg_docker,$(DOCKER_LLDP_SV2),$(DOCKER_LLDP_SV2_DBG))) diff --git a/rules/docker-lldp-sv2.mk b/rules/docker-lldp-sv2.mk deleted file mode 100644 index 460bdc2ff38b..000000000000 --- a/rules/docker-lldp-sv2.mk +++ /dev/null @@ -1,32 +0,0 @@ -# docker image for lldp agent - -DOCKER_LLDP_SV2_STEM = docker-lldp-sv2 -DOCKER_LLDP_SV2 = $(DOCKER_LLDP_SV2_STEM).gz -DOCKER_LLDP_SV2_DBG = $(DOCKER_LLDP_SV2_STEM)-$(DBG_IMAGE_MARK).gz - -$(DOCKER_LLDP_SV2)_PATH = $(DOCKERS_PATH)/docker-lldp-sv2 - -$(DOCKER_LLDP_SV2)_DEPENDS += $(LLDPD) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) - -$(DOCKER_LLDP_SV2)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) -$(DOCKER_LLDP_SV2)_DBG_DEPENDS += $(LLDPD_DBG) $(LIBSWSSCOMMON_DBG) - -$(DOCKER_LLDP_SV2)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) - -$(DOCKER_LLDP_SV2)_PYTHON_WHEELS += $(DBSYNCD_PY2) -$(DOCKER_LLDP_SV2)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) - -SONIC_DOCKER_IMAGES += $(DOCKER_LLDP_SV2) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_LLDP_SV2) - -SONIC_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_SV2_DBG) -SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_SV2_DBG) - -$(DOCKER_LLDP_SV2)_CONTAINER_NAME = lldp -$(DOCKER_LLDP_SV2)_RUN_OPT += --privileged -t -$(DOCKER_LLDP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro - -$(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpctl:/usr/bin/lldpctl -$(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpcli:/usr/bin/lldpcli -$(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += monit_lldp:/etc/monit/conf.d -$(DOCKER_LLDP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-lldp.dep b/rules/docker-lldp.dep new file mode 100644 index 000000000000..ee7935ea9222 --- /dev/null +++ b/rules/docker-lldp.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_LLDP)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-lldp.mk rules/docker-lldp.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_LLDP)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_LLDP)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_LLDP)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_LLDP),$(DOCKER_LLDP_DBG))) diff --git a/rules/docker-lldp.mk b/rules/docker-lldp.mk new file mode 100644 index 000000000000..af3d77a1c8c1 --- /dev/null +++ b/rules/docker-lldp.mk @@ -0,0 +1,32 @@ +# docker image for lldp agent + +DOCKER_LLDP_STEM = docker-lldp +DOCKER_LLDP = $(DOCKER_LLDP_STEM).gz +DOCKER_LLDP_DBG = $(DOCKER_LLDP_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_LLDP)_PATH = $(DOCKERS_PATH)/docker-lldp + +$(DOCKER_LLDP)_DEPENDS += $(LLDPD) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) + +$(DOCKER_LLDP)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) +$(DOCKER_LLDP)_DBG_DEPENDS += $(LLDPD_DBG) $(LIBSWSSCOMMON_DBG) + +$(DOCKER_LLDP)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) + +$(DOCKER_LLDP)_PYTHON_WHEELS += $(DBSYNCD_PY2) +$(DOCKER_LLDP)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) + +SONIC_DOCKER_IMAGES += $(DOCKER_LLDP) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_LLDP) + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_DBG) + +$(DOCKER_LLDP)_CONTAINER_NAME = lldp +$(DOCKER_LLDP)_RUN_OPT += --privileged -t +$(DOCKER_LLDP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro + +$(DOCKER_LLDP)_BASE_IMAGE_FILES += lldpctl:/usr/bin/lldpctl +$(DOCKER_LLDP)_BASE_IMAGE_FILES += lldpcli:/usr/bin/lldpcli +$(DOCKER_LLDP)_BASE_IMAGE_FILES += monit_lldp:/etc/monit/conf.d +$(DOCKER_LLDP)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index d4de26406cdc..1cdfcc91fccb 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -58,7 +58,7 @@ def test_dhcp_relay(self): self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'docker-dhcp-relay.supervisord.conf'), self.output_file)) def test_lldp(self): - lldpd_conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-lldp-sv2', 'lldpd.conf.j2') + lldpd_conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-lldp', 'lldpd.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + lldpd_conf_template + ' > ' + self.output_file self.run_script(argument) self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'lldpd.conf'), self.output_file)) From e2ebe996652cfa60aa12d0acad8c63db5597f3ec Mon Sep 17 00:00:00 2001 From: YaoTien Date: Wed, 10 Jun 2020 00:19:45 +0800 Subject: [PATCH 0770/1427] [devices]: Fixed OSW1800 build problem (#4647) * Enable to build osw1800 * Modify wnc-eeprom which base on debian buster's eeprom.c Co-authored-by: Brand.huang --- platform/barefoot/one-image.mk | 2 +- platform/barefoot/rules.mk | 2 +- .../modules/wnc_eeprom.c | 36 +++++-------------- 3 files changed, 11 insertions(+), 29 deletions(-) diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index 31abd3f96c99..0147b62d00a1 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -8,7 +8,7 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_NEWPORT_PLATFORM_MODULE) -#$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9280_64X_PLATFORM_MODULE) ifeq ($(INSTALL_DEBUG_TOOLS),y) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index b94939228692..2e45dce8e78b 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -2,7 +2,7 @@ include $(PLATFORM_PATH)/platform-modules-arista.mk include $(PLATFORM_PATH)/platform-modules-bfn.mk include $(PLATFORM_PATH)/platform-modules-bfn-montara.mk include $(PLATFORM_PATH)/platform-modules-bfn-newport.mk -#include $(PLATFORM_PATH)/platform-modules-wnc-osw1800.mk +include $(PLATFORM_PATH)/platform-modules-wnc-osw1800.mk include $(PLATFORM_PATH)/platform-modules-ingrasys.mk include $(PLATFORM_PATH)/bfn-sai.mk include $(PLATFORM_PATH)/docker-syncd-bfn.mk diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c index 8ddf1f2af279..8f05e5c09ada 100644 --- a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c @@ -18,7 +18,8 @@ #include #include -#include +#include +#include #include #include #include @@ -59,7 +60,6 @@ static void eeprom_update_client(struct i2c_client *client, u8 slice) dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { - //for (i = slice << 5; i < (slice + 1) << 5; i += 32) for (i = slice << 5; i < (slice + 1) << 5; i += 24) if (i2c_smbus_read_i2c_block_data(client, i, 24, data->data + i) @@ -85,17 +85,10 @@ static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct i2c_client *client = to_i2c_client(kobj_to_dev(kobj)); struct eeprom_data *data = i2c_get_clientdata(client); u8 slice; - data->valid = 0; - - if (off > EEPROM_SIZE) - return 0; - if (off + count > EEPROM_SIZE) - count = EEPROM_SIZE - off; - /* Only refresh slices which contain requested bytes */ for (slice = off >> 5; slice <= (off + count - 1) >> 5; slice++) eeprom_update_client(client, slice); @@ -125,7 +118,7 @@ static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct i2c_client *client = to_i2c_client(kobj_to_dev(kobj)); struct eeprom_data *data = i2c_get_clientdata(client); u8 temp; int error, reg; @@ -208,12 +201,11 @@ static int eeprom_probe(struct i2c_client *client, { struct i2c_adapter *adapter = client->adapter; struct eeprom_data *data; - int err; - if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct eeprom_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; memset(data->data, 0xff, EEPROM_SIZE); i2c_set_clientdata(client, data); @@ -239,22 +231,12 @@ static int eeprom_probe(struct i2c_client *client, } /* create the sysfs eeprom file */ - err = sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr); - if (err) - goto exit_kfree; - - return 0; - -exit_kfree: - kfree(data); -exit: - return err; + return sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr); } static int eeprom_remove(struct i2c_client *client) { sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr); - kfree(i2c_get_clientdata(client)); return 0; } From 9f94572abe9fa26de05272a3723870e308fec806 Mon Sep 17 00:00:00 2001 From: Sabareesh-Kumar-Anandan <59681634+Sabareesh-Kumar-Anandan@users.noreply.github.com> Date: Tue, 9 Jun 2020 21:50:51 +0530 Subject: [PATCH 0771/1427] [marvell] skip thermal control daemon for marvell device (#4703) Signed-off-by: Sabareesh Kumar Anandan --- .../armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json | 1 + 1 file changed, 1 insertion(+) diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json b/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json index 94592fa8cebc..a3ecea34bcc9 100644 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { + "skip_thermalctld": true, "skip_ledd": true } From 23ddfb866e6b7f66aa566c0c52bd0bb83b97197b Mon Sep 17 00:00:00 2001 From: chihhan123 <56335706+chihhan123@users.noreply.github.com> Date: Wed, 10 Jun 2020 00:56:53 +0800 Subject: [PATCH 0772/1427] [accton]: Update AS7312-54X, AS7312-54XS, AS7315-27XB config.bcm file (#4702) Update AS7312-54X,AS7312-54XS,AS7315-27XB config.bcm file to make sure there is no the following error message. configuration: format error in /usr/share/sonic/hwsku/th-as7312-48x25G+6x100G.config.bcm on line 110 (ignored)#15 --- .../Accton-AS7312-54X/th-as7312-48x25G+6x100G.config.bcm | 2 +- .../Accton-AS7312-54XS/th-as7312-48x25G+6x100G.config.bcm | 2 +- .../qax-as7315-20x10G+4x25G+3x100G.config.bcm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/th-as7312-48x25G+6x100G.config.bcm b/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/th-as7312-48x25G+6x100G.config.bcm index eef4d987e8ed..0ac6051b1ad4 100644 --- a/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/th-as7312-48x25G+6x100G.config.bcm +++ b/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/th-as7312-48x25G+6x100G.config.bcm @@ -107,7 +107,7 @@ dport_map_port_122=54 #dport_map_port_66=55 #dport_map_port_100=56 -/* Port Map */ +#/* Port Map */ ## FC10 ## portmap_42=41:25 portmap_43=42:25 diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/th-as7312-48x25G+6x100G.config.bcm b/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/th-as7312-48x25G+6x100G.config.bcm index eef4d987e8ed..0ac6051b1ad4 100644 --- a/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/th-as7312-48x25G+6x100G.config.bcm +++ b/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/th-as7312-48x25G+6x100G.config.bcm @@ -107,7 +107,7 @@ dport_map_port_122=54 #dport_map_port_66=55 #dport_map_port_100=56 -/* Port Map */ +#/* Port Map */ ## FC10 ## portmap_42=41:25 portmap_43=42:25 diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/qax-as7315-20x10G+4x25G+3x100G.config.bcm b/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/qax-as7315-20x10G+4x25G+3x100G.config.bcm index eef4d987e8ed..0ac6051b1ad4 100644 --- a/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/qax-as7315-20x10G+4x25G+3x100G.config.bcm +++ b/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/qax-as7315-20x10G+4x25G+3x100G.config.bcm @@ -107,7 +107,7 @@ dport_map_port_122=54 #dport_map_port_66=55 #dport_map_port_100=56 -/* Port Map */ +#/* Port Map */ ## FC10 ## portmap_42=41:25 portmap_43=42:25 From 7f07865ac261a5f67d2fe828d70f55989446a533 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Tue, 9 Jun 2020 22:35:52 +0530 Subject: [PATCH 0773/1427] [Dell] Force10-S6000-Q28S16 new HWSKU support (#4679) **How I did it** - Modified port_config.ini, TD2 settings to bring the ports UP. **How to verify it** - Check LLDP neighbors,LLDP table, interface status,EEPROM and other show commands. - Do OIR, LED, Traffic testings. --- .../Force10-S6000-Q28S16/buffers.json.j2 | 3 + .../buffers_defaults_t0.j2 | 78 ++ .../buffers_defaults_t1.j2 | 78 ++ .../pg_profile_lookup.ini | 17 + .../Force10-S6000-Q28S16/port_config.ini | 45 ++ .../Force10-S6000-Q28S16/qos.json.j2 | 1 + .../Force10-S6000-Q28S16/sai.profile | 2 + .../td2-s6000-28x40G-16x10G.config.bcm | 683 ++++++++++++++++++ 8 files changed, 907 insertions(+) create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers.json.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t0.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/pg_profile_lookup.ini create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/port_config.ini create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/qos.json.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/sai.profile create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers.json.j2 new file mode 100755 index 000000000000..e6e9e844469b --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t0.j2 new file mode 100755 index 000000000000..b5a7336e0511 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t0.j2 @@ -0,0 +1,78 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,1) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(1,2) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(2,3) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(3,4) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(4,5) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(5,6) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(6,7) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(7,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t1.j2 new file mode 100755 index 000000000000..b5a7336e0511 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t1.j2 @@ -0,0 +1,78 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,1) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(1,2) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(2,3) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(3,4) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(4,5) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(5,6) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(6,7) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(7,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/pg_profile_lookup.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/pg_profile_lookup.ini new file mode 100755 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/port_config.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/port_config.ini new file mode 100755 index 000000000000..5cf518be64a1 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/port_config.ini @@ -0,0 +1,45 @@ +# name lanes alias index speed +Ethernet0 29 tenGigE0/0 0 10000 +Ethernet1 30 tenGigE0/1 0 10000 +Ethernet2 31 tenGigE0/2 0 10000 +Ethernet3 32 tenGigE0/3 0 10000 +Ethernet4 25,26,27,28 fortyGigE0/4 1 40000 +Ethernet8 37 tenGigE0/8 2 10000 +Ethernet9 38 tenGigE0/9 2 10000 +Ethernet10 39 tenGigE0/10 2 10000 +Ethernet11 40 tenGigE0/11 2 10000 +Ethernet12 33,34,35,36 fortyGigE0/12 3 40000 +Ethernet16 41 tenGigE0/16 4 10000 +Ethernet17 42 tenGigE0/17 4 10000 +Ethernet18 43 tenGigE0/18 4 10000 +Ethernet19 44 tenGigE0/19 4 10000 +Ethernet20 45,46,47,48 fortyGigE0/20 5 40000 +Ethernet24 5 tenGigE0/24 6 10000 +Ethernet25 6 tenGigE0/25 6 10000 +Ethernet26 7 tenGigE0/26 6 10000 +Ethernet27 8 tenGigE0/27 6 10000 +Ethernet28 1,2,3,4 fortyGigE0/28 7 40000 +Ethernet32 9,10,11,12 fortyGigE0/32 8 40000 +Ethernet36 13,14,15,16 fortyGigE0/36 9 40000 +Ethernet40 21,22,23,24 fortyGigE0/40 10 40000 +Ethernet44 17,18,19,20 fortyGigE0/44 11 40000 +Ethernet48 49,50,51,52 fortyGigE0/48 12 40000 +Ethernet52 53,54,55,56 fortyGigE0/52 13 40000 +Ethernet56 61,62,63,64 fortyGigE0/56 14 40000 +Ethernet60 57,58,59,60 fortyGigE0/60 15 40000 +Ethernet64 65,66,67,68 fortyGigE0/64 16 40000 +Ethernet68 69,70,71,72 fortyGigE0/68 17 40000 +Ethernet72 77,78,79,80 fortyGigE0/72 18 40000 +Ethernet76 73,74,75,76 fortyGigE0/76 19 40000 +Ethernet80 105,106,107,108 fortyGigE0/80 20 40000 +Ethernet84 109,110,111,112 fortyGigE0/84 21 40000 +Ethernet88 117,118,119,120 fortyGigE0/88 22 40000 +Ethernet92 113,114,115,116 fortyGigE0/92 23 40000 +Ethernet96 121,122,123,124 fortyGigE0/96 24 40000 +Ethernet100 125,126,127,128 fortyGigE0/100 25 40000 +Ethernet104 85,86,87,88 fortyGigE0/104 26 40000 +Ethernet108 81,82,83,84 fortyGigE0/108 27 40000 +Ethernet112 89,90,91,92 fortyGigE0/112 28 40000 +Ethernet116 93,94,95,96 fortyGigE0/116 29 40000 +Ethernet120 97,98,99,100 fortyGigE0/120 30 40000 +Ethernet124 101,102,103,104 fortyGigE0/124 31 40000 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/qos.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/qos.json.j2 new file mode 100755 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/sai.profile b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/sai.profile new file mode 100755 index 000000000000..394d163e30c3 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-28x40G-16x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm new file mode 100755 index 000000000000..8d8be86636b8 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm @@ -0,0 +1,683 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x0000000000000000000001fffffffffff +pbmp_xport_xe=0x0000000000000000000001fffffffffff + + +# Ports configuration +# xe0 (4x10G) +portmap_1=29:10 +portmap_2=30:10 +portmap_3=31:10 +portmap_4=32:10 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x213 +phy_xaui_rx_polarity_flip_1=0xc +phy_xaui_tx_polarity_flip_1=0x9 +phy_xaui_rx_polarity_flip_2=0x0 +phy_xaui_tx_polarity_flip_2=0x0 +phy_xaui_rx_polarity_flip_3=0x1 +phy_xaui_tx_polarity_flip_3=0x0 +phy_xaui_rx_polarity_flip_4=0x1 +phy_xaui_tx_polarity_flip_4=0x1 +serdes_driver_current_lane0_1=0x6 +serdes_driver_current_lane1_1=0x7 +serdes_driver_current_lane2_1=0x6 +serdes_driver_current_lane3_1=0x6 +serdes_pre_driver_current_lane0_1=0x6 +serdes_pre_driver_current_lane1_1=0x7 +serdes_pre_driver_current_lane2_1=0x6 +serdes_pre_driver_current_lane3_1=0x6 +serdes_preemphasis_lane0_1=0xc2f0 +serdes_preemphasis_lane1_1=0xd2b0 +serdes_preemphasis_lane2_1=0xc6e0 +serdes_preemphasis_lane3_1=0xc2f0 + +# xe1 (40G) +portmap_5=25:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x2031 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x2 +serdes_driver_current_lane0_5=0x5 +serdes_driver_current_lane1_5=0x5 +serdes_driver_current_lane2_5=0x5 +serdes_driver_current_lane3_5=0x5 +serdes_pre_driver_current_lane0_5=0x5 +serdes_pre_driver_current_lane1_5=0x5 +serdes_pre_driver_current_lane2_5=0x5 +serdes_pre_driver_current_lane3_5=0x5 +serdes_preemphasis_lane0_5=0xcad0 +serdes_preemphasis_lane1_5=0xc6e0 +serdes_preemphasis_lane2_5=0xc6e0 +serdes_preemphasis_lane3_5=0xd2b0 + +# xe2 (4x10G) +portmap_6=37:10 +portmap_7=38:10 +portmap_8=39:10 +portmap_9=40:10 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x1203 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xe +phy_xaui_rx_polarity_flip_7=0x1 +phy_xaui_tx_polarity_flip_7=0x1 +phy_xaui_rx_polarity_flip_8=0x0 +phy_xaui_tx_polarity_flip_8=0x1 +phy_xaui_rx_polarity_flip_9=0x0 +phy_xaui_tx_polarity_flip_9=0x1 +serdes_driver_current_lane0_6=0x4 +serdes_driver_current_lane1_6=0x4 +serdes_driver_current_lane2_6=0x4 +serdes_driver_current_lane3_6=0x4 +serdes_pre_driver_current_lane0_6=0x4 +serdes_pre_driver_current_lane1_6=0x4 +serdes_pre_driver_current_lane2_6=0x4 +serdes_pre_driver_current_lane3_6=0x4 +serdes_preemphasis_lane0_6=0xcad0 +serdes_preemphasis_lane1_6=0xcad0 +serdes_preemphasis_lane2_6=0xc2f0 +serdes_preemphasis_lane3_6=0xc2f0 + +# xe3 (40G) +portmap_10=33:40 +xgxs_rx_lane_map_10=0x213 +xgxs_tx_lane_map_10=0x132 +phy_xaui_rx_polarity_flip_10=0xe +phy_xaui_tx_polarity_flip_10=0x2 +serdes_driver_current_lane0_10=0x4 +serdes_driver_current_lane1_10=0x4 +serdes_driver_current_lane2_10=0x4 +serdes_driver_current_lane3_10=0x4 +serdes_pre_driver_current_lane0_10=0x4 +serdes_pre_driver_current_lane1_10=0x4 +serdes_pre_driver_current_lane2_10=0x4 +serdes_pre_driver_current_lane3_10=0x4 +serdes_preemphasis_lane0_10=0xc6e0 +serdes_preemphasis_lane1_10=0xc6e0 +serdes_preemphasis_lane2_10=0xc6e0 +serdes_preemphasis_lane3_10=0xc6e0 + +# xe4 (4x10G) +portmap_11=41:10 +portmap_12=42:10 +portmap_13=43:10 +portmap_14=44:10 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x3021 +phy_xaui_rx_polarity_flip_11=0x3 +phy_xaui_tx_polarity_flip_11=0xb +phy_xaui_rx_polarity_flip_12=0x1 +phy_xaui_tx_polarity_flip_12=0x1 +phy_xaui_rx_polarity_flip_13=0x0 +phy_xaui_tx_polarity_flip_13=0x0 +phy_xaui_rx_polarity_flip_14=0x0 +phy_xaui_tx_polarity_flip_14=0x1 +serdes_driver_current_lane0_11=0x4 +serdes_driver_current_lane1_11=0x4 +serdes_driver_current_lane2_11=0x4 +serdes_driver_current_lane3_11=0x4 +serdes_pre_driver_current_lane0_11=0x4 +serdes_pre_driver_current_lane1_11=0x4 +serdes_pre_driver_current_lane2_11=0x4 +serdes_pre_driver_current_lane3_11=0x4 +serdes_preemphasis_lane0_11=0xc6e0 +serdes_preemphasis_lane1_11=0xc2f0 +serdes_preemphasis_lane2_11=0xc2f0 +serdes_preemphasis_lane3_11=0xcad0 + +# xe5 (40G) +portmap_15=45:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x213 +phy_xaui_rx_polarity_flip_15=0xe +phy_xaui_tx_polarity_flip_15=0x8 +serdes_driver_current_lane0_15=0x4 +serdes_driver_current_lane1_15=0x4 +serdes_driver_current_lane2_15=0x4 +serdes_driver_current_lane3_15=0x4 +serdes_pre_driver_current_lane0_15=0x4 +serdes_pre_driver_current_lane1_15=0x4 +serdes_pre_driver_current_lane2_15=0x4 +serdes_pre_driver_current_lane3_15=0x4 +serdes_preemphasis_lane0_15=0xc2f0 +serdes_preemphasis_lane1_15=0xc2f0 +serdes_preemphasis_lane2_15=0xc2f0 +serdes_preemphasis_lane3_15=0xc2f0 + +# xe6 (4x10G) +portmap_16=5:10 +portmap_17=6:10 +portmap_18=7:10 +portmap_19=8:10 +xgxs_rx_lane_map_16=0x213 +xgxs_tx_lane_map_16=0x1203 +phy_xaui_rx_polarity_flip_16=0xc +phy_xaui_tx_polarity_flip_16=0x1 +phy_xaui_rx_polarity_flip_17=0x0 +phy_xaui_tx_polarity_flip_17=0x0 +phy_xaui_rx_polarity_flip_18=0x1 +phy_xaui_tx_polarity_flip_18=0x0 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_16=0x4 +serdes_driver_current_lane1_16=0x4 +serdes_driver_current_lane2_16=0x4 +serdes_driver_current_lane3_16=0x4 +serdes_pre_driver_current_lane0_16=0x4 +serdes_pre_driver_current_lane1_16=0x4 +serdes_pre_driver_current_lane2_16=0x4 +serdes_pre_driver_current_lane3_16=0x4 +serdes_preemphasis_lane0_16=0xc6e0 +serdes_preemphasis_lane1_16=0xc6e0 +serdes_preemphasis_lane2_16=0xc6e0 +serdes_preemphasis_lane3_16=0xc6e0 + +# xe7 (40G) +portmap_20=1:40 +xgxs_rx_lane_map_20=0x213 +xgxs_tx_lane_map_20=0x2031 +phy_xaui_rx_polarity_flip_20=0xe +phy_xaui_tx_polarity_flip_20=0xd +serdes_driver_current_lane0_20=0x5 +serdes_driver_current_lane1_20=0x5 +serdes_driver_current_lane2_20=0x5 +serdes_driver_current_lane3_20=0x5 +serdes_pre_driver_current_lane0_20=0x5 +serdes_pre_driver_current_lane1_20=0x5 +serdes_pre_driver_current_lane2_20=0x5 +serdes_pre_driver_current_lane3_20=0x5 +serdes_preemphasis_lane0_20=0xc6e0 +serdes_preemphasis_lane1_20=0xcad0 +serdes_preemphasis_lane2_20=0xc6e0 +serdes_preemphasis_lane3_20=0xcad0 + +# xe8 (40G) +portmap_21=9:40 +xgxs_rx_lane_map_21=0x3120 +xgxs_tx_lane_map_21=0x3021 +phy_xaui_rx_polarity_flip_21=0x0 +phy_xaui_tx_polarity_flip_21=0x4 +serdes_driver_current_lane0_21=0x3 +serdes_driver_current_lane1_21=0x3 +serdes_driver_current_lane2_21=0x3 +serdes_driver_current_lane3_21=0x3 +serdes_pre_driver_current_lane0_21=0x3 +serdes_pre_driver_current_lane1_21=0x3 +serdes_pre_driver_current_lane2_21=0x3 +serdes_pre_driver_current_lane3_21=0x3 +serdes_preemphasis_lane0_21=0xc2f0 +serdes_preemphasis_lane1_21=0xc6e0 +serdes_preemphasis_lane2_21=0xbf00 +serdes_preemphasis_lane3_21=0xc2f0 + +# xe9 (40G) +portmap_22=13:40 +xgxs_rx_lane_map_22=0x213 +xgxs_tx_lane_map_22=0x132 +phy_xaui_rx_polarity_flip_22=0xe +phy_xaui_tx_polarity_flip_22=0x0 +serdes_driver_current_lane0_22=0x2 +serdes_driver_current_lane1_22=0x3 +serdes_driver_current_lane2_22=0x2 +serdes_driver_current_lane3_22=0x2 +serdes_pre_driver_current_lane0_22=0x2 +serdes_pre_driver_current_lane1_22=0x3 +serdes_pre_driver_current_lane2_22=0x2 +serdes_pre_driver_current_lane3_22=0x2 +serdes_preemphasis_lane0_22=0xb270 +serdes_preemphasis_lane1_22=0xbb10 +serdes_preemphasis_lane2_22=0xb720 +serdes_preemphasis_lane3_22=0xb720 + +# xe10 (40G) +portmap_23=21:40 +xgxs_rx_lane_map_23=0x123 +xgxs_tx_lane_map_23=0x1203 +phy_xaui_rx_polarity_flip_23=0xc +phy_xaui_tx_polarity_flip_23=0xe +serdes_driver_current_lane0_23=0x2 +serdes_driver_current_lane1_23=0x2 +serdes_driver_current_lane2_23=0x2 +serdes_driver_current_lane3_23=0x2 +serdes_pre_driver_current_lane0_23=0x2 +serdes_pre_driver_current_lane1_23=0x2 +serdes_pre_driver_current_lane2_23=0x2 +serdes_pre_driver_current_lane3_23=0x2 +serdes_preemphasis_lane0_23=0xb330 +serdes_preemphasis_lane1_23=0xb330 +serdes_preemphasis_lane2_23=0xb330 +serdes_preemphasis_lane3_23=0xb330 + +# xe11 (40G) +portmap_24=17:40 +xgxs_rx_lane_map_24=0x213 +xgxs_tx_lane_map_24=0x132 +phy_xaui_rx_polarity_flip_24=0xe +phy_xaui_tx_polarity_flip_24=0x0 +serdes_driver_current_lane0_24=0x2 +serdes_driver_current_lane1_24=0x2 +serdes_driver_current_lane2_24=0x2 +serdes_driver_current_lane3_24=0x2 +serdes_pre_driver_current_lane0_24=0x2 +serdes_pre_driver_current_lane1_24=0x2 +serdes_pre_driver_current_lane2_24=0x2 +serdes_pre_driver_current_lane3_24=0x2 +serdes_preemphasis_lane0_24=0xb330 +serdes_preemphasis_lane1_24=0xbb10 +serdes_preemphasis_lane2_24=0xbb10 +serdes_preemphasis_lane3_24=0xbb10 + +# xe12 (40G) +portmap_25=49:40 +xgxs_rx_lane_map_25=0x1302 +xgxs_tx_lane_map_25=0x2031 +phy_xaui_rx_polarity_flip_25=0xb +phy_xaui_tx_polarity_flip_25=0x3 +serdes_driver_current_lane0_25=0x2 +serdes_driver_current_lane1_25=0x2 +serdes_driver_current_lane2_25=0x2 +serdes_driver_current_lane3_25=0x2 +serdes_pre_driver_current_lane0_25=0x2 +serdes_pre_driver_current_lane1_25=0x2 +serdes_pre_driver_current_lane2_25=0x2 +serdes_pre_driver_current_lane3_25=0x2 +serdes_preemphasis_lane0_25=0xa760 +serdes_preemphasis_lane1_25=0xa760 +serdes_preemphasis_lane2_25=0xa760 +serdes_preemphasis_lane3_25=0xa760 + +# xe13 (40G) +portmap_26=53:40 +xgxs_rx_lane_map_26=0x213 +xgxs_tx_lane_map_26=0x231 +phy_xaui_rx_polarity_flip_26=0x1 +phy_xaui_tx_polarity_flip_26=0x0 +serdes_driver_current_lane0_26=0x2 +serdes_driver_current_lane1_26=0x2 +serdes_driver_current_lane2_26=0x2 +serdes_driver_current_lane3_26=0x2 +serdes_pre_driver_current_lane0_26=0x2 +serdes_pre_driver_current_lane1_26=0x2 +serdes_pre_driver_current_lane2_26=0x2 +serdes_pre_driver_current_lane3_26=0x2 +serdes_preemphasis_lane0_26=0xaf40 +serdes_preemphasis_lane1_26=0xaf40 +serdes_preemphasis_lane2_26=0xaf40 +serdes_preemphasis_lane3_26=0xaf40 + +# xe14 (40G) +portmap_27=61:40 +xgxs_rx_lane_map_27=0x132 +xgxs_tx_lane_map_27=0x213 +phy_xaui_rx_polarity_flip_27=0x0 +phy_xaui_tx_polarity_flip_27=0x0 +serdes_driver_current_lane0_27=0x2 +serdes_driver_current_lane1_27=0x2 +serdes_driver_current_lane2_27=0x2 +serdes_driver_current_lane3_27=0x2 +serdes_pre_driver_current_lane0_27=0x2 +serdes_pre_driver_current_lane1_27=0x2 +serdes_pre_driver_current_lane2_27=0x2 +serdes_pre_driver_current_lane3_27=0x2 +serdes_preemphasis_lane0_27=0xa760 +serdes_preemphasis_lane1_27=0xa760 +serdes_preemphasis_lane2_27=0xa760 +serdes_preemphasis_lane3_27=0xa760 + +# xe15 (40G) +portmap_28=57:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x2031 +phy_xaui_rx_polarity_flip_28=0x1 +phy_xaui_tx_polarity_flip_28=0x0 +serdes_driver_current_lane0_28=0x1 +serdes_driver_current_lane1_28=0x1 +serdes_driver_current_lane2_28=0x1 +serdes_driver_current_lane3_28=0x1 +serdes_pre_driver_current_lane0_28=0x1 +serdes_pre_driver_current_lane1_28=0x1 +serdes_pre_driver_current_lane2_28=0x1 +serdes_pre_driver_current_lane3_28=0x1 +serdes_preemphasis_lane0_28=0xa760 +serdes_preemphasis_lane1_28=0xa760 +serdes_preemphasis_lane2_28=0xa760 +serdes_preemphasis_lane3_28=0xa760 + +# xe16 (40G) +portmap_29=65:40 +xgxs_rx_lane_map_29=0x132 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x3 +phy_xaui_tx_polarity_flip_29=0x9 +serdes_driver_current_lane0_29=0x1 +serdes_driver_current_lane1_29=0x1 +serdes_driver_current_lane2_29=0x1 +serdes_driver_current_lane3_29=0x1 +serdes_pre_driver_current_lane0_29=0x1 +serdes_pre_driver_current_lane1_29=0x1 +serdes_pre_driver_current_lane2_29=0x1 +serdes_pre_driver_current_lane3_29=0x1 +serdes_preemphasis_lane0_29=0xa370 +serdes_preemphasis_lane1_29=0xa370 +serdes_preemphasis_lane2_29=0xa370 +serdes_preemphasis_lane3_29=0xa370 + +# xe17 (40G) +portmap_30=69:40 +xgxs_rx_lane_map_30=0x213 +xgxs_tx_lane_map_30=0x2130 +phy_xaui_rx_polarity_flip_30=0x1 +phy_xaui_tx_polarity_flip_30=0xf +serdes_driver_current_lane0_30=0x1 +serdes_driver_current_lane1_30=0x1 +serdes_driver_current_lane2_30=0x1 +serdes_driver_current_lane3_30=0x1 +serdes_pre_driver_current_lane0_30=0x1 +serdes_pre_driver_current_lane1_30=0x1 +serdes_pre_driver_current_lane2_30=0x1 +serdes_pre_driver_current_lane3_30=0x1 +serdes_preemphasis_lane0_30=0xa760 +serdes_preemphasis_lane1_30=0xa760 +serdes_preemphasis_lane2_30=0xa760 +serdes_preemphasis_lane3_30=0xa760 + +# xe18 (40G) +portmap_31=77:40 +xgxs_rx_lane_map_31=0x123 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x3 +phy_xaui_tx_polarity_flip_31=0xe +serdes_driver_current_lane0_31=0x2 +serdes_driver_current_lane1_31=0x2 +serdes_driver_current_lane2_31=0x2 +serdes_driver_current_lane3_31=0x2 +serdes_pre_driver_current_lane0_31=0x2 +serdes_pre_driver_current_lane1_31=0x2 +serdes_pre_driver_current_lane2_31=0x2 +serdes_pre_driver_current_lane3_31=0x2 +serdes_preemphasis_lane0_31=0xaf40 +serdes_preemphasis_lane1_31=0xaf40 +serdes_preemphasis_lane2_31=0xaf40 +serdes_preemphasis_lane3_31=0xaf40 + +# xe19 (40G) +portmap_32=73:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0x1 +phy_xaui_tx_polarity_flip_32=0x0 +serdes_driver_current_lane0_32=0x2 +serdes_driver_current_lane1_32=0x2 +serdes_driver_current_lane2_32=0x2 +serdes_driver_current_lane3_32=0x2 +serdes_pre_driver_current_lane0_32=0x2 +serdes_pre_driver_current_lane1_32=0x2 +serdes_pre_driver_current_lane2_32=0x2 +serdes_pre_driver_current_lane3_32=0x2 +serdes_preemphasis_lane0_32=0xa760 +serdes_preemphasis_lane1_32=0xa760 +serdes_preemphasis_lane2_32=0xa760 +serdes_preemphasis_lane3_32=0xa760 + +# xe20 (40G) +portmap_33=105:40 +xgxs_rx_lane_map_33=0x1320 +xgxs_tx_lane_map_33=0x3021 +phy_xaui_rx_polarity_flip_33=0xd +phy_xaui_tx_polarity_flip_33=0xb +serdes_driver_current_lane0_33=0x1 +serdes_driver_current_lane1_33=0x1 +serdes_driver_current_lane2_33=0x1 +serdes_driver_current_lane3_33=0x1 +serdes_pre_driver_current_lane0_33=0x1 +serdes_pre_driver_current_lane1_33=0x1 +serdes_pre_driver_current_lane2_33=0x1 +serdes_pre_driver_current_lane3_33=0x1 +serdes_preemphasis_lane0_33=0xb330 +serdes_preemphasis_lane1_33=0xb330 +serdes_preemphasis_lane2_33=0xb330 +serdes_preemphasis_lane3_33=0xb330 + +# xe21 (40G) +portmap_34=109:40 +xgxs_rx_lane_map_34=0x132 +xgxs_tx_lane_map_34=0x132 +phy_xaui_rx_polarity_flip_34=0x8 +phy_xaui_tx_polarity_flip_34=0x0 +serdes_driver_current_lane0_34=0x1 +serdes_driver_current_lane1_34=0x1 +serdes_driver_current_lane2_34=0x1 +serdes_driver_current_lane3_34=0x2 +serdes_pre_driver_current_lane0_34=0x1 +serdes_pre_driver_current_lane1_34=0x1 +serdes_pre_driver_current_lane2_34=0x1 +serdes_pre_driver_current_lane3_34=0x2 +serdes_preemphasis_lane0_34=0xb330 +serdes_preemphasis_lane1_34=0xb330 +serdes_preemphasis_lane2_34=0xb330 +serdes_preemphasis_lane3_34=0xbff0 + +# xe22 (40G) +portmap_35=117:40 +xgxs_rx_lane_map_35=0x231 +xgxs_tx_lane_map_35=0x1203 +phy_xaui_rx_polarity_flip_35=0x3 +phy_xaui_tx_polarity_flip_35=0xe +serdes_driver_current_lane0_35=0x3 +serdes_driver_current_lane1_35=0x5 +serdes_driver_current_lane2_35=0x3 +serdes_driver_current_lane3_35=0x3 +serdes_pre_driver_current_lane0_35=0x3 +serdes_pre_driver_current_lane1_35=0x5 +serdes_pre_driver_current_lane2_35=0x3 +serdes_pre_driver_current_lane3_35=0x3 +serdes_preemphasis_lane0_35=0xc6e0 +serdes_preemphasis_lane1_35=0xc6e0 +serdes_preemphasis_lane2_35=0xc6e0 +serdes_preemphasis_lane3_35=0xc6e0 + +# xe23 (40G) +portmap_36=113:40 +xgxs_rx_lane_map_36=0x132 +xgxs_tx_lane_map_36=0x132 +phy_xaui_rx_polarity_flip_36=0x8 +phy_xaui_tx_polarity_flip_36=0x0 +serdes_driver_current_lane0_36=0x1 +serdes_driver_current_lane1_36=0x1 +serdes_driver_current_lane2_36=0x1 +serdes_driver_current_lane3_36=0x1 +serdes_pre_driver_current_lane0_36=0x1 +serdes_pre_driver_current_lane1_36=0x1 +serdes_pre_driver_current_lane2_36=0x1 +serdes_pre_driver_current_lane3_36=0x1 +serdes_preemphasis_lane0_36=0xbb10 +serdes_preemphasis_lane1_36=0xbb10 +serdes_preemphasis_lane2_36=0xbb10 +serdes_preemphasis_lane3_36=0xc2f0 + +# xe24 (40G) +portmap_37=121:40 +xgxs_rx_lane_map_37=0x1320 +xgxs_tx_lane_map_37=0x3021 +phy_xaui_rx_polarity_flip_37=0xd +phy_xaui_tx_polarity_flip_37=0xb +serdes_driver_current_lane0_37=0x4 +serdes_driver_current_lane1_37=0x4 +serdes_driver_current_lane2_37=0x4 +serdes_driver_current_lane3_37=0x4 +serdes_pre_driver_current_lane0_37=0x4 +serdes_pre_driver_current_lane1_37=0x4 +serdes_pre_driver_current_lane2_37=0x4 +serdes_pre_driver_current_lane3_37=0x4 +serdes_preemphasis_lane0_37=0xc6e0 +serdes_preemphasis_lane1_37=0xc6e0 +serdes_preemphasis_lane2_37=0xc6e0 +serdes_preemphasis_lane3_37=0xc6e0 + +# xe25 (40G) +portmap_38=125:40 +xgxs_rx_lane_map_38=0x132 +xgxs_tx_lane_map_38=0x132 +phy_xaui_rx_polarity_flip_38=0x8 +phy_xaui_tx_polarity_flip_38=0x0 +serdes_driver_current_lane0_38=0x4 +serdes_driver_current_lane1_38=0x4 +serdes_driver_current_lane2_38=0x4 +serdes_driver_current_lane3_38=0x4 +serdes_pre_driver_current_lane0_38=0x4 +serdes_pre_driver_current_lane1_38=0x4 +serdes_pre_driver_current_lane2_38=0x4 +serdes_pre_driver_current_lane3_38=0x4 +serdes_preemphasis_lane0_38=0xc6e0 +serdes_preemphasis_lane1_38=0xc6e0 +serdes_preemphasis_lane2_38=0xc6e0 +serdes_preemphasis_lane3_38=0xcec0 + +# xe26 (40G) +portmap_39=85:40 +xgxs_rx_lane_map_39=0x213 +xgxs_tx_lane_map_39=0x1203 +phy_xaui_rx_polarity_flip_39=0xc +phy_xaui_tx_polarity_flip_39=0xe +serdes_driver_current_lane0_39=0x4 +serdes_driver_current_lane1_39=0x5 +serdes_driver_current_lane2_39=0x4 +serdes_driver_current_lane3_39=0x5 +serdes_pre_driver_current_lane0_39=0x4 +serdes_pre_driver_current_lane1_39=0x5 +serdes_pre_driver_current_lane2_39=0x4 +serdes_pre_driver_current_lane3_39=0x5 +serdes_preemphasis_lane0_39=0xc2f0 +serdes_preemphasis_lane1_39=0xc6e0 +serdes_preemphasis_lane2_39=0xc6e0 +serdes_preemphasis_lane3_39=0xc6e0 + +# xe27 (40G) +portmap_40=81:40 +xgxs_rx_lane_map_40=0x1320 +xgxs_tx_lane_map_40=0x2031 +phy_xaui_rx_polarity_flip_40=0x1 +phy_xaui_tx_polarity_flip_40=0x2 +serdes_driver_current_lane0_40=0x2 +serdes_driver_current_lane1_40=0x2 +serdes_driver_current_lane2_40=0x2 +serdes_driver_current_lane3_40=0x2 +serdes_pre_driver_current_lane0_40=0x2 +serdes_pre_driver_current_lane1_40=0x2 +serdes_pre_driver_current_lane2_40=0x2 +serdes_pre_driver_current_lane3_40=0x2 +serdes_preemphasis_lane0_40=0xbb10 +serdes_preemphasis_lane1_40=0xbb10 +serdes_preemphasis_lane2_40=0xbf00 +serdes_preemphasis_lane3_40=0xbb10 + +# xe28 (40G) +portmap_41=89:40 +xgxs_rx_lane_map_41=0x1320 +xgxs_tx_lane_map_41=0x3021 +phy_xaui_rx_polarity_flip_41=0x2 +phy_xaui_tx_polarity_flip_41=0xb +serdes_driver_current_lane0_41=0x4 +serdes_driver_current_lane1_41=0x4 +serdes_driver_current_lane2_41=0x4 +serdes_driver_current_lane3_41=0x4 +serdes_pre_driver_current_lane0_41=0x4 +serdes_pre_driver_current_lane1_41=0x4 +serdes_pre_driver_current_lane2_41=0x4 +serdes_pre_driver_current_lane3_41=0x4 +serdes_preemphasis_lane0_41=0xcad0 +serdes_preemphasis_lane1_41=0xc6e0 +serdes_preemphasis_lane2_41=0xc6e0 +serdes_preemphasis_lane3_41=0xc6e0 + +# xe29 (40G) +portmap_42=93:40 +xgxs_rx_lane_map_42=0x1320 +xgxs_tx_lane_map_42=0x2031 +phy_xaui_rx_polarity_flip_42=0x1 +phy_xaui_tx_polarity_flip_42=0x2 +serdes_driver_current_lane0_42=0x4 +serdes_driver_current_lane1_42=0x4 +serdes_driver_current_lane2_42=0x4 +serdes_driver_current_lane3_42=0x4 +serdes_pre_driver_current_lane0_42=0x4 +serdes_pre_driver_current_lane1_42=0x4 +serdes_pre_driver_current_lane2_42=0x4 +serdes_pre_driver_current_lane3_42=0x4 +serdes_preemphasis_lane0_42=0xc2f0 +serdes_preemphasis_lane1_42=0xc2f0 +serdes_preemphasis_lane2_42=0xc2f0 +serdes_preemphasis_lane3_42=0xc2f0 + +# xe30 (40G) +portmap_43=97:40 +xgxs_rx_lane_map_43=0x213 +xgxs_tx_lane_map_43=0x2031 +phy_xaui_rx_polarity_flip_43=0xc +phy_xaui_tx_polarity_flip_43=0x3 +serdes_driver_current_lane0_43=0x5 +serdes_driver_current_lane1_43=0x5 +serdes_driver_current_lane2_43=0x5 +serdes_driver_current_lane3_43=0x5 +serdes_pre_driver_current_lane0_43=0x5 +serdes_pre_driver_current_lane1_43=0x5 +serdes_pre_driver_current_lane2_43=0x5 +serdes_pre_driver_current_lane3_43=0x5 +serdes_preemphasis_lane0_43=0xcad0 +serdes_preemphasis_lane1_43=0xcad0 +serdes_preemphasis_lane2_43=0xcad0 +serdes_preemphasis_lane3_43=0xcad0 + +# xe31 (40G) +portmap_44=101:40 +xgxs_rx_lane_map_44=0x1320 +xgxs_tx_lane_map_44=0x1203 +phy_xaui_rx_polarity_flip_44=0x1 +phy_xaui_tx_polarity_flip_44=0x6 +serdes_driver_current_lane0_44=0x6 +serdes_driver_current_lane1_44=0x6 +serdes_driver_current_lane2_44=0x6 +serdes_driver_current_lane3_44=0x7 +serdes_pre_driver_current_lane0_44=0x6 +serdes_pre_driver_current_lane1_44=0x6 +serdes_pre_driver_current_lane2_44=0x6 +serdes_pre_driver_current_lane3_44=0x7 +serdes_preemphasis_lane0_44=0xcec0 +serdes_preemphasis_lane1_44=0xcec0 +serdes_preemphasis_lane2_44=0xcad0 +serdes_preemphasis_lane3_44=0xc6e0 From f31eabb5ee65f7d37d57d0da85dacf39d3b5fad1 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Tue, 9 Jun 2020 22:37:14 +0530 Subject: [PATCH 0774/1427] [Dell] Force10-S6000-Q24S32 new HWSKU support (#4680) **Why I did it** - Added support for S6000 new HWSKU-Q24S32 **How I did it** - Modified port_config.ini, TD2 settings to bring the ports UP. **How to verify it** - Check LLDP neighbors,LLDP table, interface status,EEPROM and other show commands. - Do OIR, LED, Traffic testings. --- .../Force10-S6000-Q24S32/buffers.json.j2 | 3 + .../buffers_defaults_t0.j2 | 55 ++ .../buffers_defaults_t1.j2 | 55 ++ .../pg_profile_lookup.ini | 17 + .../Force10-S6000-Q24S32/port_config.ini | 57 ++ .../Force10-S6000-Q24S32/qos.json.j2 | 1 + .../Force10-S6000-Q24S32/sai.profile | 2 + .../td2-s6000-24x40G-32x10G.config.bcm | 719 ++++++++++++++++++ 8 files changed, 909 insertions(+) create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers.json.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t0.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/pg_profile_lookup.ini create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/port_config.ini create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/qos.json.j2 create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/sai.profile create mode 100755 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers.json.j2 new file mode 100755 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t0.j2 new file mode 100755 index 000000000000..9d37f8a579db --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t0.j2 @@ -0,0 +1,55 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,16) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(16,25) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + + {% endfor %} + {% for port_idx in range(25,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t1.j2 new file mode 100755 index 000000000000..9d37f8a579db --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t1.j2 @@ -0,0 +1,55 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,16) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(16,25) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + + {% endfor %} + {% for port_idx in range(25,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/pg_profile_lookup.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/pg_profile_lookup.ini new file mode 100755 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/port_config.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/port_config.ini new file mode 100755 index 000000000000..b238104455f7 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 29,30,31,32 fortyGigE0/0 0 40000 +Ethernet4 25,26,27,28 fortyGigE0/4 1 40000 +Ethernet8 37,38,39,40 fortyGigE0/8 2 40000 +Ethernet12 33,34,35,36 fortyGigE0/12 3 40000 +Ethernet16 41,42,43,44 fortyGigE0/16 4 40000 +Ethernet20 45,46,47,48 fortyGigE0/20 5 40000 +Ethernet24 5,6,7,8 fortyGigE0/24 6 40000 +Ethernet28 1,2,3,4 fortyGigE0/28 7 40000 +Ethernet32 9,10,11,12 fortyGigE0/32 8 40000 +Ethernet36 13,14,15,16 fortyGigE0/36 9 40000 +Ethernet40 21,22,23,24 fortyGigE0/40 10 40000 +Ethernet44 17,18,19,20 fortyGigE0/44 11 40000 +Ethernet48 49,50,51,52 fortyGigE0/48 12 40000 +Ethernet52 53,54,55,56 fortyGigE0/52 13 40000 +Ethernet56 61,62,63,64 fortyGigE0/56 14 40000 +Ethernet60 57,58,59,60 fortyGigE0/60 15 40000 +Ethernet64 65 tenGigE0/64 16 10000 +Ethernet65 66 tenGigE0/65 16 10000 +Ethernet66 67 tenGigE0/66 16 10000 +Ethernet67 68 tenGigE0/67 16 10000 +Ethernet68 69 tenGigE0/68 17 10000 +Ethernet69 70 tenGigE0/69 17 10000 +Ethernet70 71 tenGigE0/70 17 10000 +Ethernet71 72 tenGigE0/71 17 10000 +Ethernet72 77 tenGigE0/72 18 10000 +Ethernet73 78 tenGigE0/73 18 10000 +Ethernet74 79 tenGigE0/74 18 10000 +Ethernet75 80 tenGigE0/75 18 10000 +Ethernet76 73 tenGigE0/76 19 10000 +Ethernet77 74 tenGigE0/77 19 10000 +Ethernet78 75 tenGigE0/78 19 10000 +Ethernet79 76 tenGigE0/79 19 10000 +Ethernet80 105 tenGigE0/80 20 10000 +Ethernet81 106 tenGigE0/81 20 10000 +Ethernet82 107 tenGigE0/82 20 10000 +Ethernet83 108 tenGigE0/83 20 10000 +Ethernet84 109 tenGigE0/84 21 10000 +Ethernet85 110 tenGigE0/85 21 10000 +Ethernet86 111 tenGigE0/86 21 10000 +Ethernet87 112 tenGigE0/87 21 10000 +Ethernet88 117 tenGigE0/88 22 10000 +Ethernet89 118 tenGigE0/89 22 10000 +Ethernet90 119 tenGigE0/90 22 10000 +Ethernet91 120 tenGigE0/91 22 10000 +Ethernet92 113 tenGigE0/92 23 10000 +Ethernet93 114 tenGigE0/93 23 10000 +Ethernet94 115 tenGigE0/94 23 10000 +Ethernet95 116 tenGigE0/95 23 10000 +Ethernet96 121,122,123,124 fortyGigE0/96 24 40000 +Ethernet100 125,126,127,128 fortyGigE0/100 25 40000 +Ethernet104 85,86,87,88 fortyGigE0/104 26 40000 +Ethernet108 81,82,83,84 fortyGigE0/108 27 40000 +Ethernet112 89,90,91,92 fortyGigE0/112 28 40000 +Ethernet116 93,94,95,96 fortyGigE0/116 29 40000 +Ethernet120 97,98,99,100 fortyGigE0/120 30 40000 +Ethernet124 101,102,103,104 fortyGigE0/124 31 40000 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/qos.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/qos.json.j2 new file mode 100755 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/sai.profile b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/sai.profile new file mode 100755 index 000000000000..3335af4b9bf5 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-24x40G-32x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm new file mode 100755 index 000000000000..be36c1eb832f --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm @@ -0,0 +1,719 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000001fffffffffffffffffffff +pbmp_xport_xe=0x000001fffffffffffffffffffff + +# Ports configuration +# xe0 (40G) +portmap_1=29:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x213 +phy_xaui_rx_polarity_flip_1=0xc +phy_xaui_tx_polarity_flip_1=0x9 +serdes_driver_current_lane0_1=0x6 +serdes_driver_current_lane1_1=0x7 +serdes_driver_current_lane2_1=0x6 +serdes_driver_current_lane3_1=0x6 +serdes_pre_driver_current_lane0_1=0x6 +serdes_pre_driver_current_lane1_1=0x7 +serdes_pre_driver_current_lane2_1=0x6 +serdes_pre_driver_current_lane3_1=0x6 +serdes_preemphasis_lane0_1=0xc2f0 +serdes_preemphasis_lane1_1=0xd2b0 +serdes_preemphasis_lane2_1=0xc6e0 +serdes_preemphasis_lane3_1=0xc2f0 + +# xe1 (40G) +portmap_2=25:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x2031 +phy_xaui_rx_polarity_flip_2=0xe +phy_xaui_tx_polarity_flip_2=0x2 +serdes_driver_current_lane0_2=0x5 +serdes_driver_current_lane1_2=0x5 +serdes_driver_current_lane2_2=0x5 +serdes_driver_current_lane3_2=0x5 +serdes_pre_driver_current_lane0_2=0x5 +serdes_pre_driver_current_lane1_2=0x5 +serdes_pre_driver_current_lane2_2=0x5 +serdes_pre_driver_current_lane3_2=0x5 +serdes_preemphasis_lane0_2=0xcad0 +serdes_preemphasis_lane1_2=0xc6e0 +serdes_preemphasis_lane2_2=0xc6e0 +serdes_preemphasis_lane3_2=0xd2b0 + +# xe2 (40G) +portmap_3=37:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x1203 +phy_xaui_rx_polarity_flip_3=0x3 +phy_xaui_tx_polarity_flip_3=0xe +serdes_driver_current_lane0_3=0x4 +serdes_driver_current_lane1_3=0x4 +serdes_driver_current_lane2_3=0x4 +serdes_driver_current_lane3_3=0x4 +serdes_pre_driver_current_lane0_3=0x4 +serdes_pre_driver_current_lane1_3=0x4 +serdes_pre_driver_current_lane2_3=0x4 +serdes_pre_driver_current_lane3_3=0x4 +serdes_preemphasis_lane0_3=0xcad0 +serdes_preemphasis_lane1_3=0xcad0 +serdes_preemphasis_lane2_3=0xc2f0 +serdes_preemphasis_lane3_3=0xc2f0 + +# xe3 (40G) +portmap_4=33:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x132 +phy_xaui_rx_polarity_flip_4=0xe +phy_xaui_tx_polarity_flip_4=0x2 +serdes_driver_current_lane0_4=0x4 +serdes_driver_current_lane1_4=0x4 +serdes_driver_current_lane2_4=0x4 +serdes_driver_current_lane3_4=0x4 +serdes_pre_driver_current_lane0_4=0x4 +serdes_pre_driver_current_lane1_4=0x4 +serdes_pre_driver_current_lane2_4=0x4 +serdes_pre_driver_current_lane3_4=0x4 +serdes_preemphasis_lane0_4=0xc6e0 +serdes_preemphasis_lane1_4=0xc6e0 +serdes_preemphasis_lane2_4=0xc6e0 +serdes_preemphasis_lane3_4=0xc6e0 + +# xe4 (40G) +portmap_5=41:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x3021 +phy_xaui_rx_polarity_flip_5=0x3 +phy_xaui_tx_polarity_flip_5=0xb +serdes_driver_current_lane0_5=0x4 +serdes_driver_current_lane1_5=0x4 +serdes_driver_current_lane2_5=0x4 +serdes_driver_current_lane3_5=0x4 +serdes_pre_driver_current_lane0_5=0x4 +serdes_pre_driver_current_lane1_5=0x4 +serdes_pre_driver_current_lane2_5=0x4 +serdes_pre_driver_current_lane3_5=0x4 +serdes_preemphasis_lane0_5=0xc6e0 +serdes_preemphasis_lane1_5=0xc2f0 +serdes_preemphasis_lane2_5=0xc2f0 +serdes_preemphasis_lane3_5=0xcad0 + +# xe5 (40G) +portmap_6=45:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x213 +phy_xaui_rx_polarity_flip_6=0xe +phy_xaui_tx_polarity_flip_6=0x8 +serdes_driver_current_lane0_6=0x4 +serdes_driver_current_lane1_6=0x4 +serdes_driver_current_lane2_6=0x4 +serdes_driver_current_lane3_6=0x4 +serdes_pre_driver_current_lane0_6=0x4 +serdes_pre_driver_current_lane1_6=0x4 +serdes_pre_driver_current_lane2_6=0x4 +serdes_pre_driver_current_lane3_6=0x4 +serdes_preemphasis_lane0_6=0xc2f0 +serdes_preemphasis_lane1_6=0xc2f0 +serdes_preemphasis_lane2_6=0xc2f0 +serdes_preemphasis_lane3_6=0xc2f0 + +# xe6 (40G) +portmap_7=5:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x1203 +phy_xaui_rx_polarity_flip_7=0xc +phy_xaui_tx_polarity_flip_7=0x1 +serdes_driver_current_lane0_7=0x4 +serdes_driver_current_lane1_7=0x4 +serdes_driver_current_lane2_7=0x4 +serdes_driver_current_lane3_7=0x4 +serdes_pre_driver_current_lane0_7=0x4 +serdes_pre_driver_current_lane1_7=0x4 +serdes_pre_driver_current_lane2_7=0x4 +serdes_pre_driver_current_lane3_7=0x4 +serdes_preemphasis_lane0_7=0xc6e0 +serdes_preemphasis_lane1_7=0xc6e0 +serdes_preemphasis_lane2_7=0xc6e0 +serdes_preemphasis_lane3_7=0xc6e0 + +# xe7 (40G) +portmap_8=1:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x2031 +phy_xaui_rx_polarity_flip_8=0xe +phy_xaui_tx_polarity_flip_8=0xd +serdes_driver_current_lane0_8=0x5 +serdes_driver_current_lane1_8=0x5 +serdes_driver_current_lane2_8=0x5 +serdes_driver_current_lane3_8=0x5 +serdes_pre_driver_current_lane0_8=0x5 +serdes_pre_driver_current_lane1_8=0x5 +serdes_pre_driver_current_lane2_8=0x5 +serdes_pre_driver_current_lane3_8=0x5 +serdes_preemphasis_lane0_8=0xc6e0 +serdes_preemphasis_lane1_8=0xcad0 +serdes_preemphasis_lane2_8=0xc6e0 +serdes_preemphasis_lane3_8=0xcad0 + +# xe9 (40G) +portmap_9=9:40 +xgxs_rx_lane_map_9=0x3120 +xgxs_tx_lane_map_9=0x3021 +phy_xaui_rx_polarity_flip_9=0x0 +phy_xaui_tx_polarity_flip_9=0x4 +serdes_driver_current_lane0_9=0x3 +serdes_driver_current_lane1_9=0x3 +serdes_driver_current_lane2_9=0x3 +serdes_driver_current_lane3_9=0x3 +serdes_pre_driver_current_lane0_9=0x3 +serdes_pre_driver_current_lane1_9=0x3 +serdes_pre_driver_current_lane2_9=0x3 +serdes_pre_driver_current_lane3_9=0x3 +serdes_preemphasis_lane0_9=0xc2f0 +serdes_preemphasis_lane1_9=0xc6e0 +serdes_preemphasis_lane2_9=0xbf00 +serdes_preemphasis_lane3_9=0xc2f0 + +# xe9 (40G) +portmap_10=13:40 +xgxs_rx_lane_map_10=0x213 +xgxs_tx_lane_map_10=0x132 +phy_xaui_rx_polarity_flip_10=0xe +phy_xaui_tx_polarity_flip_10=0x0 +serdes_driver_current_lane0_10=0x2 +serdes_driver_current_lane1_10=0x3 +serdes_driver_current_lane2_10=0x2 +serdes_driver_current_lane3_10=0x2 +serdes_pre_driver_current_lane0_10=0x2 +serdes_pre_driver_current_lane1_10=0x3 +serdes_pre_driver_current_lane2_10=0x2 +serdes_pre_driver_current_lane3_10=0x2 +serdes_preemphasis_lane0_10=0xb270 +serdes_preemphasis_lane1_10=0xbb10 +serdes_preemphasis_lane2_10=0xb720 +serdes_preemphasis_lane3_10=0xb720 + +# xe10 (40G) +portmap_11=21:40 +xgxs_rx_lane_map_11=0x123 +xgxs_tx_lane_map_11=0x1203 +phy_xaui_rx_polarity_flip_11=0xc +phy_xaui_tx_polarity_flip_11=0xe +serdes_driver_current_lane0_11=0x2 +serdes_driver_current_lane1_11=0x2 +serdes_driver_current_lane2_11=0x2 +serdes_driver_current_lane3_11=0x2 +serdes_pre_driver_current_lane0_11=0x2 +serdes_pre_driver_current_lane1_11=0x2 +serdes_pre_driver_current_lane2_11=0x2 +serdes_pre_driver_current_lane3_11=0x2 +serdes_preemphasis_lane0_11=0xb330 +serdes_preemphasis_lane1_11=0xb330 +serdes_preemphasis_lane2_11=0xb330 +serdes_preemphasis_lane3_11=0xb330 + +# xe11 (40G) +portmap_12=17:40 +xgxs_rx_lane_map_12=0x213 +xgxs_tx_lane_map_12=0x132 +phy_xaui_rx_polarity_flip_12=0xe +phy_xaui_tx_polarity_flip_12=0x0 +serdes_driver_current_lane0_12=0x2 +serdes_driver_current_lane1_12=0x2 +serdes_driver_current_lane2_12=0x2 +serdes_driver_current_lane3_12=0x2 +serdes_pre_driver_current_lane0_12=0x2 +serdes_pre_driver_current_lane1_12=0x2 +serdes_pre_driver_current_lane2_12=0x2 +serdes_pre_driver_current_lane3_12=0x2 +serdes_preemphasis_lane0_12=0xb330 +serdes_preemphasis_lane1_12=0xbb10 +serdes_preemphasis_lane2_12=0xbb10 +serdes_preemphasis_lane3_12=0xbb10 + +# xe12 (40G) +portmap_13=49:40 +xgxs_rx_lane_map_13=0x1302 +xgxs_tx_lane_map_13=0x2031 +phy_xaui_rx_polarity_flip_13=0xb +phy_xaui_tx_polarity_flip_13=0x3 +serdes_driver_current_lane0_13=0x2 +serdes_driver_current_lane1_13=0x2 +serdes_driver_current_lane2_13=0x2 +serdes_driver_current_lane3_13=0x2 +serdes_pre_driver_current_lane0_13=0x2 +serdes_pre_driver_current_lane1_13=0x2 +serdes_pre_driver_current_lane2_13=0x2 +serdes_pre_driver_current_lane3_13=0x2 +serdes_preemphasis_lane0_13=0xa760 +serdes_preemphasis_lane1_13=0xa760 +serdes_preemphasis_lane2_13=0xa760 +serdes_preemphasis_lane3_13=0xa760 + +# xe13 (40G) +portmap_14=53:40 +xgxs_rx_lane_map_14=0x213 +xgxs_tx_lane_map_14=0x231 +phy_xaui_rx_polarity_flip_14=0x1 +phy_xaui_tx_polarity_flip_14=0x0 +serdes_driver_current_lane0_14=0x2 +serdes_driver_current_lane1_14=0x2 +serdes_driver_current_lane2_14=0x2 +serdes_driver_current_lane3_14=0x2 +serdes_pre_driver_current_lane0_14=0x2 +serdes_pre_driver_current_lane1_14=0x2 +serdes_pre_driver_current_lane2_14=0x2 +serdes_pre_driver_current_lane3_14=0x2 +serdes_preemphasis_lane0_14=0xaf40 +serdes_preemphasis_lane1_14=0xaf40 +serdes_preemphasis_lane2_14=0xaf40 +serdes_preemphasis_lane3_14=0xaf40 + +# xe14 (40G) +portmap_15=61:40 +xgxs_rx_lane_map_15=0x132 +xgxs_tx_lane_map_15=0x213 +phy_xaui_rx_polarity_flip_15=0x0 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_15=0x2 +serdes_driver_current_lane1_15=0x2 +serdes_driver_current_lane2_15=0x2 +serdes_driver_current_lane3_15=0x2 +serdes_pre_driver_current_lane0_15=0x2 +serdes_pre_driver_current_lane1_15=0x2 +serdes_pre_driver_current_lane2_15=0x2 +serdes_pre_driver_current_lane3_15=0x2 +serdes_preemphasis_lane0_15=0xa760 +serdes_preemphasis_lane1_15=0xa760 +serdes_preemphasis_lane2_15=0xa760 +serdes_preemphasis_lane3_15=0xa760 + +# xe15 (40G) +portmap_16=57:40 +xgxs_rx_lane_map_16=0x213 +xgxs_tx_lane_map_16=0x2031 +phy_xaui_rx_polarity_flip_16=0x1 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_16=0x1 +serdes_driver_current_lane1_16=0x1 +serdes_driver_current_lane2_16=0x1 +serdes_driver_current_lane3_16=0x1 +serdes_pre_driver_current_lane0_16=0x1 +serdes_pre_driver_current_lane1_16=0x1 +serdes_pre_driver_current_lane2_16=0x1 +serdes_pre_driver_current_lane3_16=0x1 +serdes_preemphasis_lane0_16=0xa760 +serdes_preemphasis_lane1_16=0xa760 +serdes_preemphasis_lane2_16=0xa760 +serdes_preemphasis_lane3_16=0xa760 + +# xe16 (4x10G) +portmap_17=65:10 +portmap_18=66:10 +portmap_19=67:10 +portmap_20=68:10 +xgxs_rx_lane_map_17=0x132 +xgxs_tx_lane_map_17=0x2031 +phy_xaui_rx_polarity_flip_17=0x3 +phy_xaui_tx_polarity_flip_17=0x9 +phy_xaui_rx_polarity_flip_18=0x1 +phy_xaui_tx_polarity_flip_18=0x0 +phy_xaui_rx_polarity_flip_19=0x0 +phy_xaui_tx_polarity_flip_19=0x0 +phy_xaui_rx_polarity_flip_20=0x0 +phy_xaui_tx_polarity_flip_20=0x1 +serdes_driver_current_lane0_17=0x1 +serdes_driver_current_lane1_17=0x1 +serdes_driver_current_lane2_17=0x1 +serdes_driver_current_lane3_17=0x1 +serdes_pre_driver_current_lane0_17=0x1 +serdes_pre_driver_current_lane1_17=0x1 +serdes_pre_driver_current_lane2_17=0x1 +serdes_pre_driver_current_lane3_17=0x1 +serdes_preemphasis_lane0_17=0xa370 +serdes_preemphasis_lane1_17=0xa370 +serdes_preemphasis_lane2_17=0xa370 +serdes_preemphasis_lane3_17=0xa370 + +# xe17 (4x10G) +portmap_21=69:10 +portmap_22=70:10 +portmap_23=71:10 +portmap_24=72:10 +xgxs_rx_lane_map_21=0x213 +xgxs_tx_lane_map_21=0x2130 +phy_xaui_rx_polarity_flip_21=0x1 +phy_xaui_tx_polarity_flip_21=0xf +phy_xaui_rx_polarity_flip_22=0x0 +phy_xaui_tx_polarity_flip_22=0x1 +phy_xaui_rx_polarity_flip_23=0x0 +phy_xaui_tx_polarity_flip_23=0x1 +phy_xaui_rx_polarity_flip_24=0x0 +phy_xaui_tx_polarity_flip_24=0x1 +serdes_driver_current_lane0_21=0x1 +serdes_driver_current_lane1_21=0x1 +serdes_driver_current_lane2_21=0x1 +serdes_driver_current_lane3_21=0x1 +serdes_pre_driver_current_lane0_21=0x1 +serdes_pre_driver_current_lane1_21=0x1 +serdes_pre_driver_current_lane2_21=0x1 +serdes_pre_driver_current_lane3_21=0x1 +serdes_preemphasis_lane0_21=0xa760 +serdes_preemphasis_lane1_21=0xa760 +serdes_preemphasis_lane2_21=0xa760 +serdes_preemphasis_lane3_21=0xa760 + +# xe18 (4x10G) +portmap_25=77:10 +portmap_26=78:10 +portmap_27=79:10 +portmap_28=80:10 +xgxs_rx_lane_map_25=0x123 +xgxs_tx_lane_map_25=0x1203 +phy_xaui_rx_polarity_flip_25=0x3 +phy_xaui_tx_polarity_flip_25=0xe +phy_xaui_rx_polarity_flip_26=0x1 +phy_xaui_tx_polarity_flip_26=0x1 +phy_xaui_rx_polarity_flip_27=0x0 +phy_xaui_tx_polarity_flip_27=0x1 +phy_xaui_rx_polarity_flip_28=0x0 +phy_xaui_tx_polarity_flip_28=0x1 +serdes_driver_current_lane0_25=0x2 +serdes_driver_current_lane1_25=0x2 +serdes_driver_current_lane2_25=0x2 +serdes_driver_current_lane3_25=0x2 +serdes_pre_driver_current_lane0_25=0x2 +serdes_pre_driver_current_lane1_25=0x2 +serdes_pre_driver_current_lane2_25=0x2 +serdes_pre_driver_current_lane3_25=0x2 +serdes_preemphasis_lane0_25=0xaf40 +serdes_preemphasis_lane1_25=0xaf40 +serdes_preemphasis_lane2_25=0xaf40 +serdes_preemphasis_lane3_25=0xaf40 + +# xe19 (4x10G) +portmap_29=73:10 +portmap_30=74:10 +portmap_31=75:10 +portmap_32=76:10 +xgxs_rx_lane_map_29=0x213 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x0 +phy_xaui_rx_polarity_flip_30=0x0 +phy_xaui_tx_polarity_flip_30=0x0 +phy_xaui_rx_polarity_flip_31=0x0 +phy_xaui_tx_polarity_flip_31=0x0 +phy_xaui_rx_polarity_flip_32=0x0 +phy_xaui_tx_polarity_flip_32=0x0 +serdes_driver_current_lane0_29=0x2 +serdes_driver_current_lane1_29=0x2 +serdes_driver_current_lane2_29=0x2 +serdes_driver_current_lane3_29=0x2 +serdes_pre_driver_current_lane0_29=0x2 +serdes_pre_driver_current_lane1_29=0x2 +serdes_pre_driver_current_lane2_29=0x2 +serdes_pre_driver_current_lane3_29=0x2 +serdes_preemphasis_lane0_29=0xa760 +serdes_preemphasis_lane1_29=0xa760 +serdes_preemphasis_lane2_29=0xa760 +serdes_preemphasis_lane3_29=0xa760 + +# xe20 (4x10G) +portmap_33=105:10 +portmap_34=106:10 +portmap_35=107:10 +portmap_36=108:10 +xgxs_rx_lane_map_33=0x1320 +xgxs_tx_lane_map_33=0x3021 +phy_xaui_rx_polarity_flip_33=0xd +phy_xaui_tx_polarity_flip_33=0xb +phy_xaui_rx_polarity_flip_34=0x0 +phy_xaui_tx_polarity_flip_34=0x1 +phy_xaui_rx_polarity_flip_35=0x1 +phy_xaui_tx_polarity_flip_35=0x0 +phy_xaui_rx_polarity_flip_36=0x1 +phy_xaui_tx_polarity_flip_36=0x1 +serdes_driver_current_lane0_33=0x1 +serdes_driver_current_lane1_33=0x1 +serdes_driver_current_lane2_33=0x1 +serdes_driver_current_lane3_33=0x1 +serdes_pre_driver_current_lane0_33=0x1 +serdes_pre_driver_current_lane1_33=0x1 +serdes_pre_driver_current_lane2_33=0x1 +serdes_pre_driver_current_lane3_33=0x1 +serdes_preemphasis_lane0_33=0xb330 +serdes_preemphasis_lane1_33=0xb330 +serdes_preemphasis_lane2_33=0xb330 +serdes_preemphasis_lane3_33=0xb330 + +# xe21 (4x10G) +portmap_37=109:10 +portmap_38=110:10 +portmap_39=111:10 +portmap_40=112:10 +xgxs_rx_lane_map_37=0x132 +xgxs_tx_lane_map_37=0x132 +phy_xaui_rx_polarity_flip_37=0x8 +phy_xaui_tx_polarity_flip_37=0x0 +phy_xaui_rx_polarity_flip_38=0x0 +phy_xaui_tx_polarity_flip_38=0x0 +phy_xaui_rx_polarity_flip_39=0x0 +phy_xaui_tx_polarity_flip_39=0x0 +phy_xaui_rx_polarity_flip_40=0x1 +phy_xaui_tx_polarity_flip_40=0x0 +serdes_driver_current_lane0_37=0x1 +serdes_driver_current_lane1_37=0x1 +serdes_driver_current_lane2_37=0x1 +serdes_driver_current_lane3_37=0x2 +serdes_pre_driver_current_lane0_37=0x1 +serdes_pre_driver_current_lane1_37=0x1 +serdes_pre_driver_current_lane2_37=0x1 +serdes_pre_driver_current_lane3_37=0x2 +serdes_preemphasis_lane0_37=0xb330 +serdes_preemphasis_lane1_37=0xb330 +serdes_preemphasis_lane2_37=0xb330 +serdes_preemphasis_lane3_37=0xbff0 + +# xe22 (4x10G) +portmap_41=117:10 +portmap_42=118:10 +portmap_43=119:10 +portmap_44=120:10 +xgxs_rx_lane_map_41=0x231 +xgxs_tx_lane_map_41=0x1203 +phy_xaui_rx_polarity_flip_41=0x3 +phy_xaui_tx_polarity_flip_41=0xe +phy_xaui_rx_polarity_flip_42=0x1 +phy_xaui_tx_polarity_flip_42=0x1 +phy_xaui_rx_polarity_flip_43=0x0 +phy_xaui_tx_polarity_flip_43=0x1 +phy_xaui_rx_polarity_flip_44=0x0 +phy_xaui_tx_polarity_flip_44=0x1 +serdes_driver_current_lane0_41=0x3 +serdes_driver_current_lane1_41=0x5 +serdes_driver_current_lane2_41=0x3 +serdes_driver_current_lane3_41=0x3 +serdes_pre_driver_current_lane0_41=0x3 +serdes_pre_driver_current_lane1_41=0x5 +serdes_pre_driver_current_lane2_41=0x3 +serdes_pre_driver_current_lane3_41=0x3 +serdes_preemphasis_lane0_41=0xc6e0 +serdes_preemphasis_lane1_41=0xc6e0 +serdes_preemphasis_lane2_41=0xc6e0 +serdes_preemphasis_lane3_41=0xc6e0 + +# xe23 (40x10G) +portmap_45=113:10 +portmap_46=114:10 +portmap_47=115:10 +portmap_48=116:10 +xgxs_rx_lane_map_45=0x132 +xgxs_tx_lane_map_45=0x132 +phy_xaui_rx_polarity_flip_45=0x8 +phy_xaui_tx_polarity_flip_45=0x0 +phy_xaui_rx_polarity_flip_46=0x0 +phy_xaui_tx_polarity_flip_46=0x0 +phy_xaui_rx_polarity_flip_47=0x0 +phy_xaui_tx_polarity_flip_47=0x0 +phy_xaui_rx_polarity_flip_48=0x1 +phy_xaui_tx_polarity_flip_48=0x0 +serdes_driver_current_lane0_45=0x1 +serdes_driver_current_lane1_45=0x1 +serdes_driver_current_lane2_45=0x1 +serdes_driver_current_lane3_45=0x1 +serdes_pre_driver_current_lane0_45=0x1 +serdes_pre_driver_current_lane1_45=0x1 +serdes_pre_driver_current_lane2_45=0x1 +serdes_pre_driver_current_lane3_45=0x1 +serdes_preemphasis_lane0_45=0xbb10 +serdes_preemphasis_lane1_45=0xbb10 +serdes_preemphasis_lane2_45=0xbb10 +serdes_preemphasis_lane3_45=0xc2f0 + +# xe24 (40G) +portmap_49=121:40 +xgxs_rx_lane_map_49=0x1320 +xgxs_tx_lane_map_49=0x3021 +phy_xaui_rx_polarity_flip_49=0xd +phy_xaui_tx_polarity_flip_49=0xb +serdes_driver_current_lane0_49=0x4 +serdes_driver_current_lane1_49=0x4 +serdes_driver_current_lane2_49=0x4 +serdes_driver_current_lane3_49=0x4 +serdes_pre_driver_current_lane0_49=0x4 +serdes_pre_driver_current_lane1_49=0x4 +serdes_pre_driver_current_lane2_49=0x4 +serdes_pre_driver_current_lane3_49=0x4 +serdes_preemphasis_lane0_49=0xc6e0 +serdes_preemphasis_lane1_49=0xc6e0 +serdes_preemphasis_lane2_49=0xc6e0 +serdes_preemphasis_lane3_49=0xc6e0 + +# xe25 (40G) +portmap_50=125:40 +xgxs_rx_lane_map_50=0x132 +xgxs_tx_lane_map_50=0x132 +phy_xaui_rx_polarity_flip_50=0x8 +phy_xaui_tx_polarity_flip_50=0x0 +serdes_driver_current_lane0_50=0x4 +serdes_driver_current_lane1_50=0x4 +serdes_driver_current_lane2_50=0x4 +serdes_driver_current_lane3_50=0x4 +serdes_pre_driver_current_lane0_50=0x4 +serdes_pre_driver_current_lane1_50=0x4 +serdes_pre_driver_current_lane2_50=0x4 +serdes_pre_driver_current_lane3_50=0x4 +serdes_preemphasis_lane0_50=0xc6e0 +serdes_preemphasis_lane1_50=0xc6e0 +serdes_preemphasis_lane2_50=0xc6e0 +serdes_preemphasis_lane3_50=0xcec0 + +# xe26 (40G) +portmap_51=85:40 +xgxs_rx_lane_map_51=0x213 +xgxs_tx_lane_map_51=0x1203 +phy_xaui_rx_polarity_flip_51=0xc +phy_xaui_tx_polarity_flip_51=0xe +serdes_driver_current_lane0_51=0x4 +serdes_driver_current_lane1_51=0x5 +serdes_driver_current_lane2_51=0x4 +serdes_driver_current_lane3_51=0x5 +serdes_pre_driver_current_lane0_51=0x4 +serdes_pre_driver_current_lane1_51=0x5 +serdes_pre_driver_current_lane2_51=0x4 +serdes_pre_driver_current_lane3_51=0x5 +serdes_preemphasis_lane0_51=0xc2f0 +serdes_preemphasis_lane1_51=0xc6e0 +serdes_preemphasis_lane2_51=0xc6e0 +serdes_preemphasis_lane3_51=0xc6e0 + +# xe27 (40G) +portmap_52=81:40 +xgxs_rx_lane_map_52=0x1320 +xgxs_tx_lane_map_52=0x2031 +phy_xaui_rx_polarity_flip_52=0x1 +phy_xaui_tx_polarity_flip_52=0x2 +serdes_driver_current_lane0_52=0x2 +serdes_driver_current_lane1_52=0x2 +serdes_driver_current_lane2_52=0x2 +serdes_driver_current_lane3_52=0x2 +serdes_pre_driver_current_lane0_52=0x2 +serdes_pre_driver_current_lane1_52=0x2 +serdes_pre_driver_current_lane2_52=0x2 +serdes_pre_driver_current_lane3_52=0x2 +serdes_preemphasis_lane0_52=0xbb10 +serdes_preemphasis_lane1_52=0xbb10 +serdes_preemphasis_lane2_52=0xbf00 +serdes_preemphasis_lane3_52=0xbb10 + +# xe28 (40G) +portmap_53=89:40 +xgxs_rx_lane_map_53=0x1320 +xgxs_tx_lane_map_53=0x3021 +phy_xaui_rx_polarity_flip_53=0x2 +phy_xaui_tx_polarity_flip_53=0xb +serdes_driver_current_lane0_53=0x4 +serdes_driver_current_lane1_53=0x4 +serdes_driver_current_lane2_53=0x4 +serdes_driver_current_lane3_53=0x4 +serdes_pre_driver_current_lane0_53=0x4 +serdes_pre_driver_current_lane1_53=0x4 +serdes_pre_driver_current_lane2_53=0x4 +serdes_pre_driver_current_lane3_53=0x4 +serdes_preemphasis_lane0_53=0xcad0 +serdes_preemphasis_lane1_53=0xc6e0 +serdes_preemphasis_lane2_53=0xc6e0 +serdes_preemphasis_lane3_53=0xc6e0 + +# xe29 (40G) +portmap_54=93:40 +xgxs_rx_lane_map_54=0x1320 +xgxs_tx_lane_map_54=0x2031 +phy_xaui_rx_polarity_flip_54=0x1 +phy_xaui_tx_polarity_flip_54=0x2 +serdes_driver_current_lane0_54=0x4 +serdes_driver_current_lane1_54=0x4 +serdes_driver_current_lane2_54=0x4 +serdes_driver_current_lane3_54=0x4 +serdes_pre_driver_current_lane0_54=0x4 +serdes_pre_driver_current_lane1_54=0x4 +serdes_pre_driver_current_lane2_54=0x4 +serdes_pre_driver_current_lane3_54=0x4 +serdes_preemphasis_lane0_54=0xc2f0 +serdes_preemphasis_lane1_54=0xc2f0 +serdes_preemphasis_lane2_54=0xc2f0 +serdes_preemphasis_lane3_54=0xc2f0 + +# xe30 (40G) +portmap_55=97:40 +xgxs_rx_lane_map_55=0x213 +xgxs_tx_lane_map_55=0x2031 +phy_xaui_rx_polarity_flip_55=0xc +phy_xaui_tx_polarity_flip_55=0x3 +serdes_driver_current_lane0_55=0x5 +serdes_driver_current_lane1_55=0x5 +serdes_driver_current_lane2_55=0x5 +serdes_driver_current_lane3_55=0x5 +serdes_pre_driver_current_lane0_55=0x5 +serdes_pre_driver_current_lane1_55=0x5 +serdes_pre_driver_current_lane2_55=0x5 +serdes_pre_driver_current_lane3_55=0x5 +serdes_preemphasis_lane0_55=0xcad0 +serdes_preemphasis_lane1_55=0xcad0 +serdes_preemphasis_lane2_55=0xcad0 +serdes_preemphasis_lane3_55=0xcad0 + +# xe31 (40G) +portmap_56=101:40 +xgxs_rx_lane_map_56=0x1320 +xgxs_tx_lane_map_56=0x1203 +phy_xaui_rx_polarity_flip_56=0x1 +phy_xaui_tx_polarity_flip_56=0x6 +serdes_driver_current_lane0_56=0x6 +serdes_driver_current_lane1_56=0x6 +serdes_driver_current_lane2_56=0x6 +serdes_driver_current_lane3_56=0x7 +serdes_pre_driver_current_lane0_56=0x6 +serdes_pre_driver_current_lane1_56=0x6 +serdes_pre_driver_current_lane2_56=0x6 +serdes_pre_driver_current_lane3_56=0x7 +serdes_preemphasis_lane0_56=0xcec0 +serdes_preemphasis_lane1_56=0xcec0 +serdes_preemphasis_lane2_56=0xcad0 +serdes_preemphasis_lane3_56=0xc6e0 + From c6365e7abeaf8616a19291addd248afdabd324cc Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 9 Jun 2020 21:04:55 -0700 Subject: [PATCH 0775/1427] Reorganize .gitignore files (#4707) - Add .gitignore files in each subdirectory of src/, so as to reduce the size of the .gitignore file in the project root, and also make it easier to maintain (i.e., if a directory in src/ is removed, there will not be outdated entries in the root .gitignore file. - Also add missing .gitignore entries and remove outdated entries and duplicates. --- .gitignore | 90 +------------------ platform/broadcom/saibcm-modules/.gitignore | 6 ++ .../sonic-platform-modules-dell/.gitignore | 3 + src/bash/.gitignore | 3 + src/dhcpmon/.gitignore | 5 ++ src/hiredis/.gitignore | 3 + src/ifupdown2/.gitignore | 1 + src/initramfs-tools/.gitignore | 3 + src/iproute2/.gitignore | 3 + src/iptables/.gitignore | 4 + src/isc-dhcp/.gitignore | 4 + src/ixgbe/.gitignore | 3 + src/kdump-tools/.gitignore | 4 + src/libnl3/.gitignore | 5 ++ src/libteam/.gitignore | 3 + src/libyang/.gitignore | 3 + src/lldpd/.gitignore | 4 + src/lm-sensors/.gitignore | 3 + src/monit/.gitignore | 4 + src/mpdecimal/.gitignore | 3 + src/python-click/.gitignore | 3 + src/python3/.gitignore | 3 + src/radvd/.gitignore | 4 + src/redis/.gitignore | 3 + src/sflow/hsflowd/.gitignore | 4 + src/sflow/psample/.gitignore | 8 ++ src/sflow/sflowtool/.gitignore | 8 ++ src/smartmontools/.gitignore | 3 + src/snmpd/.gitignore | 3 + src/socat/.gitignore | 4 + src/sonic-device-data/.gitignore | 2 + src/sonic-yang-mgmt/.gitignore | 57 ++++++++++++ src/sonic-yang-models/.gitignore | 59 ++++++++++++ src/supervisor/.gitignore | 4 + src/swig/.gitignore | 3 + src/systemd-sonic-generator/.gitignore | 6 ++ src/tacacs/.gitignore | 8 ++ src/thrift/.gitignore | 4 + 38 files changed, 255 insertions(+), 88 deletions(-) create mode 100644 src/bash/.gitignore create mode 100644 src/dhcpmon/.gitignore create mode 100644 src/hiredis/.gitignore create mode 100644 src/ifupdown2/.gitignore create mode 100644 src/initramfs-tools/.gitignore create mode 100644 src/iproute2/.gitignore create mode 100644 src/iptables/.gitignore create mode 100644 src/isc-dhcp/.gitignore create mode 100644 src/ixgbe/.gitignore create mode 100644 src/kdump-tools/.gitignore create mode 100644 src/libnl3/.gitignore create mode 100644 src/libteam/.gitignore create mode 100644 src/libyang/.gitignore create mode 100644 src/lldpd/.gitignore create mode 100644 src/lm-sensors/.gitignore create mode 100644 src/monit/.gitignore create mode 100644 src/mpdecimal/.gitignore create mode 100644 src/python-click/.gitignore create mode 100644 src/python3/.gitignore create mode 100644 src/radvd/.gitignore create mode 100644 src/redis/.gitignore create mode 100644 src/sflow/hsflowd/.gitignore create mode 100644 src/sflow/psample/.gitignore create mode 100644 src/sflow/sflowtool/.gitignore create mode 100644 src/smartmontools/.gitignore create mode 100644 src/snmpd/.gitignore create mode 100644 src/socat/.gitignore create mode 100644 src/sonic-device-data/.gitignore create mode 100644 src/sonic-yang-mgmt/.gitignore create mode 100644 src/sonic-yang-models/.gitignore create mode 100644 src/supervisor/.gitignore create mode 100644 src/swig/.gitignore create mode 100644 src/systemd-sonic-generator/.gitignore create mode 100644 src/tacacs/.gitignore create mode 100644 src/thrift/.gitignore diff --git a/.gitignore b/.gitignore index d9ca023fedc3..9c32299fdd61 100644 --- a/.gitignore +++ b/.gitignore @@ -20,94 +20,6 @@ target/ *dbg.j2 *.img -# Subdirectories in src -src/bash/* -!src/bash/Makefile -src/dhcpmon/debian/* -!src/dhcpmon/debian/changelog -!src/dhcpmon/debian/compat -!src/dhcpmon/debian/control -!src/dhcpmon/debian/rules -src/ixgbe/* -!src/ixgbe/Makefile -src/isc-dhcp/* -!src/isc-dhcp/Makefile -!src/isc-dhcp/patch -src/socat/* -!src/socat/Makefile -!src/socat/*.patch -src/tacacs/* -src/tacacs/nsm/* -src/tacacs/pam/* -!src/tacacs/nsm/Makefile -!src/tacacs/nsm/*.patch -!src/tacacs/pam/Makefile -!src/tacacs/pam/*.patch -src/hiredis/* -!src/hiredis/Makefile -src/igb/* -!src/igb/Makefile -src/initramfs-tools/* -!src/initramfs-tools/Makefile -src/iproute2/* -!src/iproute2/Makefile -src/isc-dhcp/* -!src/isc-dhcp/Makefile -!src/isc-dhcp/patch/ -src/libnl3/* -!src/libnl3/debian -src/libnl3/debian/libnl-*/ -!src/libnl3/Makefile -src/libteam/* -!src/libteam/Makefile -src/libyang/* -!src/libyang/Makefile -src/lldpd/* -!src/lldpd/Makefile -!src/lldpd/patch/ -src/lm-sensors/* -!src/lm-sensors/Makefile -src/monit/* -!src/monit/Makefile -!src/monit/patch/ -src/mpdecimal/* -!src/mpdecimal/Makefile -src/python-click/* -!src/python-click/Makefile -src/python3/* -!src/python3/Makefile -src/radvd/* -!src/radvd/Makefile -!src/radvd/patch/ -src/redis/* -!src/redis/Makefile -src/smartmontools/* -!src/smartmontools/Makefile -src/snmpd/* -!src/snmpd/Makefile -src/sonic-device-data/src/device/ -src/sonic-device-data/src/debian/ -src/supervisor/* -!src/supervisor/Makefile -!src/supervisor/patch/ -src/swig/* -!src/swig/Makefile -src/systemd-sonic-generator/systemd-sonic-generator -src/systemd-sonic-generator/debian/* -!src/systemd-sonic-generator/debian/changelog -!src/systemd-sonic-generator/debian/compat -!src/systemd-sonic-generator/debian/control -!src/systemd-sonic-generator/debian/rules -src/telemetry/debian/* -!src/telemetry/debian/changelog -!src/telemetry/debian/compat -!src/telemetry/debian/control -!src/telemetry/debian/rules -!src/telemetry/debian/telemetry.init.d -src/thrift/* -!src/thrift/patch/ -!src/thrift/Makefile - # Autogenerated Dockerfiles sonic-slave*/Dockerfile dockers/*/Dockerfile @@ -125,6 +37,8 @@ src/sonic-daemon-base/build src/sonic-daemon-base/sonic_daemon_base.egg-info # Misc. files +asic_config_checksum +files/Aboot/boot0 files/initramfs-tools/arista-convertfs files/initramfs-tools/union-mount diff --git a/platform/broadcom/saibcm-modules/.gitignore b/platform/broadcom/saibcm-modules/.gitignore index 338005f50ce9..f2e54da55c5f 100644 --- a/platform/broadcom/saibcm-modules/.gitignore +++ b/platform/broadcom/saibcm-modules/.gitignore @@ -2,3 +2,9 @@ *.debhelper *.substvars *.ko + +build-arch-stamp +build/ +configure-stamp +debian/files +debian/opennsl-modules/ diff --git a/platform/broadcom/sonic-platform-modules-dell/.gitignore b/platform/broadcom/sonic-platform-modules-dell/.gitignore index 7f287d538227..f62ae4876450 100644 --- a/platform/broadcom/sonic-platform-modules-dell/.gitignore +++ b/platform/broadcom/sonic-platform-modules-dell/.gitignore @@ -48,3 +48,6 @@ dkms.conf *.postrm.debhelper *.prerm.debhelper *.substvars + +# Cloned source repositories +tools/flashrom/ diff --git a/src/bash/.gitignore b/src/bash/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/bash/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/dhcpmon/.gitignore b/src/dhcpmon/.gitignore new file mode 100644 index 000000000000..9d09ae6b3f1a --- /dev/null +++ b/src/dhcpmon/.gitignore @@ -0,0 +1,5 @@ +debian/* +!debian/changelog +!debian/compat +!debian/control +!debian/rules diff --git a/src/hiredis/.gitignore b/src/hiredis/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/hiredis/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/ifupdown2/.gitignore b/src/ifupdown2/.gitignore new file mode 100644 index 000000000000..d1cfec62d283 --- /dev/null +++ b/src/ifupdown2/.gitignore @@ -0,0 +1 @@ +ifupdown2-1.2.8-1/ diff --git a/src/initramfs-tools/.gitignore b/src/initramfs-tools/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/initramfs-tools/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/iproute2/.gitignore b/src/iproute2/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/iproute2/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/iptables/.gitignore b/src/iptables/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/iptables/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/isc-dhcp/.gitignore b/src/isc-dhcp/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/isc-dhcp/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/ixgbe/.gitignore b/src/ixgbe/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/ixgbe/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/kdump-tools/.gitignore b/src/kdump-tools/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/kdump-tools/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/libnl3/.gitignore b/src/libnl3/.gitignore new file mode 100644 index 000000000000..906fc0b87997 --- /dev/null +++ b/src/libnl3/.gitignore @@ -0,0 +1,5 @@ +* +!.gitignore +!debian/ +debian/libnl-*/ +!Makefile diff --git a/src/libteam/.gitignore b/src/libteam/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/libteam/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/libyang/.gitignore b/src/libyang/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/libyang/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/lldpd/.gitignore b/src/lldpd/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/lldpd/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/lm-sensors/.gitignore b/src/lm-sensors/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/lm-sensors/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/monit/.gitignore b/src/monit/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/monit/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/mpdecimal/.gitignore b/src/mpdecimal/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/mpdecimal/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/python-click/.gitignore b/src/python-click/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/python-click/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/python3/.gitignore b/src/python3/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/python3/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/radvd/.gitignore b/src/radvd/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/radvd/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/redis/.gitignore b/src/redis/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/redis/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/sflow/hsflowd/.gitignore b/src/sflow/hsflowd/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/sflow/hsflowd/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/sflow/psample/.gitignore b/src/sflow/psample/.gitignore new file mode 100644 index 000000000000..eec3a10fb01e --- /dev/null +++ b/src/sflow/psample/.gitignore @@ -0,0 +1,8 @@ +* +!.gitignore +!debian/changelog +!debian/compat +!debian/control +!debian/psample.install +!debian/rules +!Makefile diff --git a/src/sflow/sflowtool/.gitignore b/src/sflow/sflowtool/.gitignore new file mode 100644 index 000000000000..138e705d63f0 --- /dev/null +++ b/src/sflow/sflowtool/.gitignore @@ -0,0 +1,8 @@ +* +!.gitignore +!debian/changelog +!debian/compat +!debian/control +!debian/sflowtool.install +!debian/rules +!Makefile diff --git a/src/smartmontools/.gitignore b/src/smartmontools/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/smartmontools/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/snmpd/.gitignore b/src/snmpd/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/snmpd/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/socat/.gitignore b/src/socat/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/socat/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/sonic-device-data/.gitignore b/src/sonic-device-data/.gitignore new file mode 100644 index 000000000000..963a3ac55363 --- /dev/null +++ b/src/sonic-device-data/.gitignore @@ -0,0 +1,2 @@ +src/debian +src/device diff --git a/src/sonic-yang-mgmt/.gitignore b/src/sonic-yang-mgmt/.gitignore new file mode 100644 index 000000000000..ba74660506d9 --- /dev/null +++ b/src/sonic-yang-mgmt/.gitignore @@ -0,0 +1,57 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ diff --git a/src/sonic-yang-models/.gitignore b/src/sonic-yang-models/.gitignore new file mode 100644 index 000000000000..c5522334f759 --- /dev/null +++ b/src/sonic-yang-models/.gitignore @@ -0,0 +1,59 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +yang-models/sonic_yang_tree diff --git a/src/supervisor/.gitignore b/src/supervisor/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/supervisor/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/swig/.gitignore b/src/swig/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/swig/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/systemd-sonic-generator/.gitignore b/src/systemd-sonic-generator/.gitignore new file mode 100644 index 000000000000..06e13f381b69 --- /dev/null +++ b/src/systemd-sonic-generator/.gitignore @@ -0,0 +1,6 @@ +systemd-sonic-generator +debian/* +!debian/changelog +!debian/compat +!debian/control +!debian/rules diff --git a/src/tacacs/.gitignore b/src/tacacs/.gitignore new file mode 100644 index 000000000000..3e483805dfe3 --- /dev/null +++ b/src/tacacs/.gitignore @@ -0,0 +1,8 @@ +* +!.gitignore +nsm/* +!nsm/Makefile +!nsm/*.patch +pam/* +!pam/Makefile +!pam/*.patch diff --git a/src/thrift/.gitignore b/src/thrift/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/thrift/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ From 830c9eabd41a8541683b0512b669984a39fa010e Mon Sep 17 00:00:00 2001 From: taochengyi <54564117+taocy001@users.noreply.github.com> Date: Wed, 10 Jun 2020 16:32:08 +0800 Subject: [PATCH 0776/1427] [centec]: update SAI to v1.6.1 for centec x86 platform (#4730) --- platform/centec/sdk.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/centec/sdk.mk b/platform/centec/sdk.mk index c2f2023cc8e7..5a5c888e0b09 100644 --- a/platform/centec/sdk.mk +++ b/platform/centec/sdk.mk @@ -1,5 +1,5 @@ # Centec SAI -CENTEC_SAI = libsai_1.5.1_amd64.deb -$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/libsai_1.5.1-1.0_amd64.deb +CENTEC_SAI = libsai_1.6.1_amd64.deb +$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/libsai_1.6.1-1.0_amd64.deb SONIC_ONLINE_DEBS += $(CENTEC_SAI) From 814cbe0066038a4dc778154b10f8353b8013ebf5 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Wed, 10 Jun 2020 16:39:06 -0700 Subject: [PATCH 0777/1427] [submodule] Update swss submodule (#4737) Signed-off-by: Danny Allen --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 382905381d54..a3a010af7283 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 382905381d547a3c050ec23ef9bd611bb2dea67a +Subproject commit a3a010af728345b085d8a6e344b60b16c32815fd From 36419978b7dc2f44e7c18548aaa45d18531d4c80 Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Thu, 11 Jun 2020 09:01:01 +0300 Subject: [PATCH 0778/1427] [Mellanox] Update SAI, SDK 4.4.0928 and FW xx.2007.1208 - master branch (#4723) Signed-off-by: Noa Or --- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index c8f4b225857b..22354d530660 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2007.1112 +MLNX_SPC_FW_VERSION = 13.2007.1208 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2007.1112 +MLNX_SPC2_FW_VERSION = 29.2007.1208 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2007.1112 +MLNX_SPC3_FW_VERSION = 30.2007.1208 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 0b04ae0de850..ba954beb7ae0 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.3.2-sai16 +MLNX_SAI_VERSION = SAIRel1.16.4.1-sai16 export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index aa5a09b71260..b318bb380ac1 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit aa5a09b712609d7c903fbacd63a87deeab922a2b +Subproject commit b318bb380ac13dba98c94b163fbe644ab7eb236e diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 3160d980ff76..0a7d3be15378 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 3160d980ff766addb459e1ff0f81778516eb55a0 +Subproject commit 0a7d3be153787c1b18e4b51fff3354cc5c91d4bb diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index c63c327cc40d..ea6742269e93 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.4.0914 +MLNX_SDK_VERSION = 4.4.0928 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 4da4955b2fee32bcf067fdf0447070ea5e36113d Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Thu, 11 Jun 2020 14:02:44 +0800 Subject: [PATCH 0779/1427] [Mellanox] Upgrade mft to 4.14.1-8 (#4701) --- platform/mellanox/mft.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index 5795e5acb3a0..605944cd5074 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -1,7 +1,7 @@ # Mellanox SAI -MFT_VERSION = 4.14.0 -MFT_REVISION = 500 +MFT_VERSION = 4.14.1 +MFT_REVISION = 8 export MFT_VERSION MFT_REVISION From ddd60bfec1689e002553d736cce6fbceb9b48517 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Thu, 11 Jun 2020 12:51:42 -0700 Subject: [PATCH 0780/1427] [MultiDB] Add REDIS_TIMEOUT_MSECS back which is removed by mistake (#4757) --- src/sonic-daemon-base/sonic_daemon_base/daemon_base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index 0d532a85c1dd..c74f9bed15e7 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -13,6 +13,7 @@ # # Constants ==================================================================== # +REDIS_TIMEOUT_MSECS = 0 # Platform root directory inside docker PLATFORM_ROOT_DOCKER = '/usr/share/sonic/platform' From ae7bf3db5238c72f76d0a00047edc5428f72bb20 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 11 Jun 2020 13:01:21 -0700 Subject: [PATCH 0781/1427] [ntp] disable ntp long jump (#4748) Found another syncd timing issue related to clock going backwards. To be safe disable the ntp long jump. Signed-off-by: Ying Xie --- files/image_config/ntp/ntp-config.sh | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/files/image_config/ntp/ntp-config.sh b/files/image_config/ntp/ntp-config.sh index 7ab84174dcaa..0cec0f7af2db 100755 --- a/files/image_config/ntp/ntp-config.sh +++ b/files/image_config/ntp/ntp-config.sh @@ -26,12 +26,7 @@ function modify_ntp_default sonic-cfggen -d -t /usr/share/sonic/templates/ntp.conf.j2 >/etc/ntp.conf get_database_reboot_type -if [[ x"${reboot_type}" == x"cold" ]]; then - echo "Enabling NTP long jump for reboot type ${reboot_type} ..." - modify_ntp_default "s/NTPD_OPTS='-x'/NTPD_OPTS='-g'/" -else - echo "Disabling NTP long jump for reboot type ${reboot_type} ..." - modify_ntp_default "s/NTPD_OPTS='-g'/NTPD_OPTS='-x'/" -fi +echo "Disabling NTP long jump for reboot type ${reboot_type} ..." +modify_ntp_default "s/NTPD_OPTS='-g'/NTPD_OPTS='-x'/" systemctl restart ntp From 2e93a92bd951b529e5990393bd768dd18fb1b1fa Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 11 Jun 2020 14:04:51 -0700 Subject: [PATCH 0782/1427] [sonic-mgmt] upgrade paramilo to version 2.7.1 (#4750) spytest requires higher paramiko version. Fix it to 2.7.1. Signed-off-by: Ying Xie --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 78d5996f8571..dc10e94f6cb1 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -51,7 +51,7 @@ RUN pip install ipaddr \ pysnmp==4.2.5 \ jinja2==2.7.2 \ cffi==1.10.0 \ - paramiko==2.1.2 \ + paramiko==2.7.1 \ passlib \ ipython==5.4.1 \ virtualenv \ From 5d5d5739c2d80feb08cae2d3baaaeb0b745bc836 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 11 Jun 2020 16:04:23 -0700 Subject: [PATCH 0783/1427] [dockers] Rename 'docker-snmp-sv2' to 'docker-snmp' (#4699) The `-sv2` suffix was used to differentiate SNMP Dockers when we transitioned from "SONiCv1" to "SONiCv2", about four years ago. The old Docker materials were removed long ago; there is no need to keep this suffix. Removing it aligns the name with all the other Dockers. Also edit Monit configuration to detect proper snmp-subagent command line in Buster, and make snmpd command line matching more robust. --- .../Dockerfile.j2 | 12 +++---- .../base_image_files/monit_snmp | 4 +-- .../critical_processes | 0 .../snmpd.conf.j2 | 0 .../{docker-snmp-sv2 => docker-snmp}/start.sh | 0 .../supervisord.conf | 0 .../sysDescription.j2 | 0 platform/generic/rules.mk | 2 +- rules/docker-snmp-sv2.dep | 11 ------- rules/docker-snmp-sv2.mk | 32 ------------------- rules/docker-snmp.dep | 11 +++++++ rules/docker-snmp.mk | 32 +++++++++++++++++++ 12 files changed, 52 insertions(+), 52 deletions(-) rename dockers/{docker-snmp-sv2 => docker-snmp}/Dockerfile.j2 (86%) rename dockers/{docker-snmp-sv2 => docker-snmp}/base_image_files/monit_snmp (76%) rename dockers/{docker-snmp-sv2 => docker-snmp}/critical_processes (100%) rename dockers/{docker-snmp-sv2 => docker-snmp}/snmpd.conf.j2 (100%) rename dockers/{docker-snmp-sv2 => docker-snmp}/start.sh (100%) rename dockers/{docker-snmp-sv2 => docker-snmp}/supervisord.conf (100%) rename dockers/{docker-snmp-sv2 => docker-snmp}/sysDescription.j2 (100%) delete mode 100644 rules/docker-snmp-sv2.dep delete mode 100644 rules/docker-snmp-sv2.mk create mode 100644 rules/docker-snmp.dep create mode 100644 rules/docker-snmp.mk diff --git a/dockers/docker-snmp-sv2/Dockerfile.j2 b/dockers/docker-snmp/Dockerfile.j2 similarity index 86% rename from dockers/docker-snmp-sv2/Dockerfile.j2 rename to dockers/docker-snmp/Dockerfile.j2 index a7e46a58668d..213d941c58f6 100644 --- a/dockers/docker-snmp-sv2/Dockerfile.j2 +++ b/dockers/docker-snmp/Dockerfile.j2 @@ -19,12 +19,12 @@ RUN apt-get update && \ make \ ipmitool -{% if docker_snmp_sv2_debs.strip() -%} +{% if docker_snmp_debs.strip() -%} # Copy locally-built Debian package dependencies -{{ copy_files("debs/", docker_snmp_sv2_debs.split(' '), "/debs/") }} +{{ copy_files("debs/", docker_snmp_debs.split(' '), "/debs/") }} # Install locally-built Debian packages and implicitly install their dependencies -{{ install_debian_packages(docker_snmp_sv2_debs.split(' ')) }} +{{ install_debian_packages(docker_snmp_debs.split(' ')) }} {%- endif %} # Fix for hiredis compilation issues for ARM @@ -46,12 +46,12 @@ RUN python3 -m pip install --no-cache-dir \ pyyaml \ smbus -{% if docker_snmp_sv2_whls.strip() -%} +{% if docker_snmp_whls.strip() -%} # Copy locally-built Python wheel dependencies -{{ copy_files("python-wheels/", docker_snmp_sv2_whls.split(' '), "/python-wheels/") }} +{{ copy_files("python-wheels/", docker_snmp_whls.split(' '), "/python-wheels/") }} # Install locally-built Python wheel dependencies -{{ install_python3_wheels(docker_snmp_sv2_whls.split(' ')) }} +{{ install_python3_wheels(docker_snmp_whls.split(' ')) }} {% endif %} RUN python3 -m sonic_ax_impl install diff --git a/dockers/docker-snmp-sv2/base_image_files/monit_snmp b/dockers/docker-snmp/base_image_files/monit_snmp similarity index 76% rename from dockers/docker-snmp-sv2/base_image_files/monit_snmp rename to dockers/docker-snmp/base_image_files/monit_snmp index 811f9d14b3d4..cfb1a2b66831 100644 --- a/dockers/docker-snmp-sv2/base_image_files/monit_snmp +++ b/dockers/docker-snmp/base_image_files/monit_snmp @@ -4,8 +4,8 @@ ## snmpd ## snmpd_subagent ############################################################################### -check process snmpd matching "/usr/sbin/snmpd -f" +check process snmpd matching "/usr/sbin/snmpd\s" if does not exist for 5 times within 5 cycles then alert -check process snmp_subagent matching "python3.6 -m sonic_ax_impl" +check process snmp_subagent matching "python3 -m sonic_ax_impl" if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-snmp-sv2/critical_processes b/dockers/docker-snmp/critical_processes similarity index 100% rename from dockers/docker-snmp-sv2/critical_processes rename to dockers/docker-snmp/critical_processes diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp/snmpd.conf.j2 similarity index 100% rename from dockers/docker-snmp-sv2/snmpd.conf.j2 rename to dockers/docker-snmp/snmpd.conf.j2 diff --git a/dockers/docker-snmp-sv2/start.sh b/dockers/docker-snmp/start.sh similarity index 100% rename from dockers/docker-snmp-sv2/start.sh rename to dockers/docker-snmp/start.sh diff --git a/dockers/docker-snmp-sv2/supervisord.conf b/dockers/docker-snmp/supervisord.conf similarity index 100% rename from dockers/docker-snmp-sv2/supervisord.conf rename to dockers/docker-snmp/supervisord.conf diff --git a/dockers/docker-snmp-sv2/sysDescription.j2 b/dockers/docker-snmp/sysDescription.j2 similarity index 100% rename from dockers/docker-snmp-sv2/sysDescription.j2 rename to dockers/docker-snmp/sysDescription.j2 diff --git a/platform/generic/rules.mk b/platform/generic/rules.mk index 5ba91194090a..c836c1faec1a 100644 --- a/platform/generic/rules.mk +++ b/platform/generic/rules.mk @@ -2,8 +2,8 @@ include $(PLATFORM_PATH)/aboot-image.mk include $(PLATFORM_PATH)/onie-image.mk SONIC_ALL += $(DOCKER_DATABASE) \ + $(DOCKER_SNMP) \ $(DOCKER_LLDP) \ - $(DOCKER_SNMP_SV2) \ $(DOCKER_PLATFORM_MONITOR) \ $(DOCKER_DHCP_RELAY) \ $(DOCKER_PTF) \ diff --git a/rules/docker-snmp-sv2.dep b/rules/docker-snmp-sv2.dep deleted file mode 100644 index 38d46e1fbb03..000000000000 --- a/rules/docker-snmp-sv2.dep +++ /dev/null @@ -1,11 +0,0 @@ - -DPATH := $($(DOCKER_SNMP_SV2)_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-snmp-sv2.mk rules/docker-snmp-sv2.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(DPATH)) - -$(DOCKER_SNMP_SV2)_CACHE_MODE := GIT_CONTENT_SHA -$(DOCKER_SNMP_SV2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(DOCKER_SNMP_SV2)_DEP_FILES := $(DEP_FILES) - -$(eval $(call add_dbg_docker,$(DOCKER_SNMP_SV2),$(DOCKER_SNMP_SV2_DBG))) diff --git a/rules/docker-snmp-sv2.mk b/rules/docker-snmp-sv2.mk deleted file mode 100644 index 7eebf0c56ff1..000000000000 --- a/rules/docker-snmp-sv2.mk +++ /dev/null @@ -1,32 +0,0 @@ -# docker image for snmp agent - -DOCKER_SNMP_SV2_STEM = docker-snmp-sv2 -DOCKER_SNMP_SV2 = $(DOCKER_SNMP_SV2_STEM).gz -DOCKER_SNMP_SV2_DBG = $(DOCKER_SNMP_SV2_STEM)-$(DBG_IMAGE_MARK).gz - -$(DOCKER_SNMP_SV2)_PATH = $(DOCKERS_PATH)/docker-snmp-sv2 - -## TODO: remove LIBPY3_DEV if we can get pip3 directly -$(DOCKER_SNMP_SV2)_DEPENDS += $(SNMP) $(SNMPD) - -$(DOCKER_SNMP_SV2)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) -$(DOCKER_SNMP_SV2)_DBG_DEPENDS += $(SNMP_DBG) $(SNMPD_DBG) $(LIBSNMP_DBG) - -$(DOCKER_SNMP_SV2)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) - -$(DOCKER_SNMP_SV2)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3) $(SWSSSDK_PY3) $(ASYNCSNMP_PY3) -$(DOCKER_SNMP_SV2)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) - -SONIC_DOCKER_IMAGES += $(DOCKER_SNMP_SV2) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SNMP_SV2) - -SONIC_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_SV2_DBG) -SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_SV2_DBG) - -$(DOCKER_SNMP_SV2)_CONTAINER_NAME = snmp -$(DOCKER_SNMP_SV2)_RUN_OPT += --privileged -t -$(DOCKER_SNMP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro -# mount Arista platform python libraries to support corresponding platforms SNMP power status query -$(DOCKER_SNMP_SV2)_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro -$(DOCKER_SNMP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) -$(DOCKER_SNMP_SV2)_BASE_IMAGE_FILES += monit_snmp:/etc/monit/conf.d diff --git a/rules/docker-snmp.dep b/rules/docker-snmp.dep new file mode 100644 index 000000000000..580ee65d53fe --- /dev/null +++ b/rules/docker-snmp.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_SNMP)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-snmp.mk rules/docker-snmp.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_SNMP)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SNMP)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SNMP)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_SNMP),$(DOCKER_SNMP_DBG))) diff --git a/rules/docker-snmp.mk b/rules/docker-snmp.mk new file mode 100644 index 000000000000..39d5f2584b36 --- /dev/null +++ b/rules/docker-snmp.mk @@ -0,0 +1,32 @@ +# docker image for snmp agent + +DOCKER_SNMP_STEM = docker-snmp +DOCKER_SNMP = $(DOCKER_SNMP_STEM).gz +DOCKER_SNMP_DBG = $(DOCKER_SNMP_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_SNMP)_PATH = $(DOCKERS_PATH)/docker-snmp + +## TODO: remove LIBPY3_DEV if we can get pip3 directly +$(DOCKER_SNMP)_DEPENDS += $(SNMP) $(SNMPD) + +$(DOCKER_SNMP)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) +$(DOCKER_SNMP)_DBG_DEPENDS += $(SNMP_DBG) $(SNMPD_DBG) $(LIBSNMP_DBG) + +$(DOCKER_SNMP)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) + +$(DOCKER_SNMP)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3) $(SWSSSDK_PY3) $(ASYNCSNMP_PY3) +$(DOCKER_SNMP)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) + +SONIC_DOCKER_IMAGES += $(DOCKER_SNMP) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SNMP) + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_DBG) + +$(DOCKER_SNMP)_CONTAINER_NAME = snmp +$(DOCKER_SNMP)_RUN_OPT += --privileged -t +$(DOCKER_SNMP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +# mount Arista platform python libraries to support corresponding platforms SNMP power status query +$(DOCKER_SNMP)_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro +$(DOCKER_SNMP)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_SNMP)_BASE_IMAGE_FILES += monit_snmp:/etc/monit/conf.d From 4b39193a130dc2a62d23e6879984ecd43e179bb8 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 11 Jun 2020 23:23:27 -0700 Subject: [PATCH 0784/1427] [sonic-mgmt] upgrade ansible to 2.7.12 (#4751) Signed-off-by: Ying Xie --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index dc10e94f6cb1..a623a5b102a4 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -127,7 +127,7 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -RUN pip install ansible==2.8.7 +RUN pip install ansible==2.8.12 RUN pip install pysubnettree From 6acd64d00510e6ec588ca8c36f87737afbe8fafc Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Thu, 11 Jun 2020 23:24:49 -0700 Subject: [PATCH 0785/1427] [BFN] Updated SDK packages to SAI v1.6.1 (#4744) Signed-off-by: Andriy Kokhan --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index d2bc97d1496c..57acf3e95d0f 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20200507_deb9.deb +BFN_PLATFORM = bfnplatform_20200610_deb9.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index d899779025df..232c37e7492d 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20200507_deb9.deb +BFN_SAI = bfnsdk_20200610_deb9.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) From ea63f3e4b2bf2c80c22579f6e7231fffeabfc62f Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Sat, 13 Jun 2020 02:08:27 +0300 Subject: [PATCH 0786/1427] [mellanox]: Fix for MSN4600C sensors (#4754) Signed-off-by: Shlomi Bitton --- .../x86_64-mlnx_msn4600c-r0/sensors.conf | 192 +++++++++--------- 1 file changed, 94 insertions(+), 98 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf index b2f942ffa5f8..9c80350e19ad 100644 --- a/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf @@ -23,114 +23,114 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "xdpe12284-i2c-*-62" label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 PSU 12V Rail (in)" + ignore in2 label in3 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail (out)" ignore in4 label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" label power1 "PMIC-1 ASIC 12V VCORE_MAIN Rail Pwr (in)" ignore power2 - label power3 "PMIC-1 ASIC 12V VCORE_MAIN Rail Pwr (out)" + label power3 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Pwr (out)" ignore power4 - label curr1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (in)" + label curr1 "PMIC-1 ASIC 12V VCORE_MAIN Rail Curr (in)" ignore curr2 label curr3 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (out)" ignore curr4 chip "xdpe12284-i2c-*-64" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 PSU 12V Rail (in)" - label in3 "PMIC-2 ASIC 1.8V MAIN Rail (out)" - label in4 "PMIC-2 ASIC 1.2V MAIN Rail (out)" + label in1 "PMIC-2 PSU 12V Rail_1 (in)" + label in2 "PMIC-2 PSU 12V Rail_2 (in)" + label in3 "PMIC-2 ASIC 1.8V Rail_1 (out)" + label in4 "PMIC-2 ASIC 1.2V Rail_2 (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" - label power1 "PMIC-2 ASIC 1.8V MAIN Rail Pwr (in)" - label power2 "PMIC-2 ASIC 1.2V MAIN Rail Pwr (in)" - label power3 "PMIC-2 ASIC 1.8V MAIN Rail Pwr (out)" - label power4 "PMIC-2 ASIC 1.2V MAIN Rail Pwr (out)" - label curr1 "PMIC-2 ASIC 1.8V MAIN Rail Curr (in)" - label curr2 "PMIC-2 ASIC 1.2V MAIN Rail Curr (in)" - label curr3 "PMIC-2 ASIC 1.8V MAIN Rail Curr (out)" - label curr4 "PMIC-2 ASIC 1.2V MAIN Rail Curr (out)" + label power1 "PMIC-2 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-2 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-2 ASIC 1.8V Rail_1 Pwr (out)" + label power4 "PMIC-2 ASIC 1.2V Rail_2 Pwr (out)" + label curr1 "PMIC-2 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-2 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-2 ASIC 1.8V Rail_1 Curr (out)" + label curr4 "PMIC-2 ASIC 1.2V Rail_2 Curr (out)" chip "xdpe12284-i2c-*-66" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 PSU 12V Rail (in)" - label in3 "PMIC-3 ASIC 0.85V MAIN Rail (out)" - label in4 "PMIC-3 ASIC 1.8V MAIN Rail (out)" + label in1 "PMIC-3 PSU 12V Rail_1 (in)" + label in2 "PMIC-3 PSU 12V Rail_2 (in)" + label in3 "PMIC-3 ASIC 0.85V Rail_1 T0_1 (out)" + label in4 "PMIC-3 ASIC 1.8V Rail_2 T0_1 (out)" label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" - label power1 "PMIC-3 ASIC 12V MAIN Rail Pwr (in)" - label power2 "PMIC-3 ASIC 12V MAIN Rail Pwr (in)" - label power3 "PMIC-3 ASIC 0.85V MAIN Rail Pwr (out)" - label power4 "PMIC-3 ASIC 1.8V MAIN Rail Pwr (out)" - label curr1 "PMIC-3 ASIC 12V MAIN Rail Curr (in)" - label curr2 "PMIC-3 ASIC 12V MAIN Rail Curr (in)" - label curr3 "PMIC-3 ASIC 0.85V MAIN Rail Curr (out)" - label curr4 "PMIC-3 ASIC 1.8V MAIN Rail Curr (out)" + label power1 "PMIC-3 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-3 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-3 ASIC 0.85V Rail_1 T0_1 Pwr (out)" + label power4 "PMIC-3 ASIC 1.8V Rail_2 T0_1 Pwr (out)" + label curr1 "PMIC-3 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-3 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-3 ASIC 0.85V Rail_1 T0_1 Curr (out)" + label curr4 "PMIC-3 ASIC 1.8V Rail_2 T0_1 Curr (out)" chip "xdpe12284-i2c-*-68" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 PSU 12V Rail (in)" - label in3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail (out)" - label in4 "PMIC-4 ASIC 1.8V T6_7 Rail (out)" + label in1 "PMIC-4 PSU 12V Rail_1 (in)" + label in2 "PMIC-4 PSU 12V Rail_2 (in)" + label in3 "PMIC-4 ASIC 0.85V Rail_1 T2_3 (out)" + label in4 "PMIC-4 ASIC 1.8V Rail_2 T2_3 (out)" label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" - label power1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" - label power2 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (in)" - label power3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power4 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" - label curr2 "PMIC-4 ASIC 1.8V T6_7 Rail Curr (in)" - label curr3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr4 "PMIC-4 ASIC 1.8V T6_7 Rail Curr (out)" + label power1 "PMIC-4 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-4 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-4 ASIC 0.85V Rail_1 T2_3 Pwr (out)" + label power4 "PMIC-4 ASIC 1.8V Rail_2 T2_3 Pwr (out)" + label curr1 "PMIC-4 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-4 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-4 ASIC 0.85V Rail_1 T2_3 Curr (out)" + label curr4 "PMIC-4 ASIC 1.8V Rail_2 T2_3 Curr (out)" chip "xdpe12284-i2c-*-6a" - label in1 "PMIC-5 PSU 12V Rail (in)" - label in2 "PMIC-5 PSU 12V Rail (in)" - label in3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail (out)" - label in4 "PMIC-5 ASIC 1.8V T6_7 Rail (out)" + label in1 "PMIC-5 PSU 12V Rail_1 (in)" + label in2 "PMIC-5 PSU 12V Rail_2 (in)" + label in3 "PMIC-5 ASIC 0.85V Rail_1 T4_5 (out)" + label in4 "PMIC-5 ASIC 1.8V Rail_2 T4_5 (out)" label temp1 "PMIC-5 Temp 1" label temp2 "PMIC-5 Temp 2" - label power1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" - label power2 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (in)" - label power3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power4 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" - label curr2 "PMIC-5 ASIC 1.8V T6_7 Rail Curr (in)" - label curr3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr4 "PMIC-5 ASIC 1.8V T6_7 Rail Curr (out)" + label power1 "PMIC-5 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-5 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-5 ASIC 0.85V Rail_1 T4_5 Pwr (out)" + label power4 "PMIC-5 ASIC 1.8V Rail_2 T4_5 Pwr (out)" + label curr1 "PMIC-5 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-5 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-5 ASIC 0.85V Rail_1 T4_5 Curr (out)" + label curr4 "PMIC-5 ASIC 1.8V Rail_2 T4_5 Curr (out)" chip "xdpe12284-i2c-*-6c" - label in1 "PMIC-6 PSU 12V Rail (in)" - label in2 "PMIC-6 PSU 12V Rail (in)" - label in3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail (out)" - label in4 "PMIC-6 ASIC 1.8V T6_7 Rail (out)" + label in1 "PMIC-6 PSU 12V Rail_1 (in)" + label in2 "PMIC-6 PSU 12V Rail_2 (in)" + label in3 "PMIC-6 ASIC 0.85V Rail_1 T6_7 (out)" + label in4 "PMIC-6 ASIC 1.8V Rail_2 T6_7 (out)" label temp1 "PMIC-6 Temp 1" label temp2 "PMIC-6 Temp 2" - label power1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" - label power2 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (in)" - label power3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power4 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" - label curr2 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (in)" - label curr3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr4 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (out)" + label power1 "PMIC-6 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-6 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-6 ASIC 0.85V Rail_1 T6_7 Pwr (out)" + label power4 "PMIC-6 ASIC 1.8V Rail_2 T6_7 Pwr (out)" + label curr1 "PMIC-6 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-6 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-6 ASIC 0.85V Rail_1 T6_7 Curr (out)" + label curr4 "PMIC-6 ASIC 1.8V Rail_2 T6_7 Curr (out)" chip "xdpe12284-i2c-*-6e" - label in1 "PMIC-7 PSU 12V Rail (in)" - label in2 "PMIC-7 PSU 12V Rail (in)" - label in3 "PMIC-7 ASIC 1.2V VCORE_T6_7 Rail (out)" - label in4 "PMIC-7 ASIC 1.2V T6_7 Rail (out)" + label in1 "PMIC-7 PSU 12V Rail_1 (in)" + label in2 "PMIC-7 PSU 12V Rail_2 (in)" + label in3 "PMIC-7 ASIC 1.2V Rail_1 T0_3 (out)" + label in4 "PMIC-7 ASIC 1.2V Rail_2 T4_7 (out)" label temp1 "PMIC-7 Temp 1" label temp2 "PMIC-7 Temp 2" - label power1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" - label power2 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (in)" - label power3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power4 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" - label curr2 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (in)" - label curr3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr4 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (out)" + label power1 "PMIC-7 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-7 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-7 ASIC 1.2V Rail_1 T0_3 Pwr (out)" + label power4 "PMIC-7 ASIC 1.2V Rail_2 T4_7 Pwr (out)" + label curr1 "PMIC-7 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-7 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-7 ASIC 1.2V Rail_1 T0_3 Curr (out)" + label curr4 "PMIC-7 ASIC 1.2V Rail_2 T4_7 Curr (out)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-8 PSU 12V Rail (in)" - label in2 "PMIC-8 PSU 12V Rail (in)" + label in1 "PMIC-8 PSU 12V Rail (in1)" + label in2 "PMIC-8 PSU 12V Rail (in2)" label in3 "PMIC-8 COMEX 1.8V Rail (out)" label in4 "PMIC-8 COMEX 1.05V Rail (out)" label temp1 "PMIC-8 Temp 1" @@ -140,8 +140,8 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-8 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-8 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-9 PSU 12V Rail (in)" - label in2 "PMIC-9 PSU 12V Rail (in)" + label in1 "PMIC-9 PSU 12V Rail (in1)" + label in2 "PMIC-9 PSU 12V Rail (in2)" label in3 "PMIC-9 COMEX 1.2V Rail (out)" ignore in4 label temp1 "PMIC-9 Temp 1" @@ -154,22 +154,8 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power supplies bus "i2c-4" "i2c-1-mux (chan_id 3)" chip "dps460-i2c-*-58" - label in1 "PSU-2(R) 220V Rail (in)" - label in2 "PSU-2(R) 220V Rail (in)" - label in3 "PSU-2(R) 12V Rail (out)" - label fan1 "PSU-2(R) Fan 1" - ignore fan2 - ignore fan3 - label temp1 "PSU-2(R) Temp 1" - label temp2 "PSU-2(R) Temp 2" - label temp3 "PSU-2(R) Temp 3" - label power1 "PSU-2(R) 220V Rail Pwr (in)" - label power2 "PSU-2(R) 12V Rail Pwr (out)" - label curr1 "PSU-2(R) 220V Rail Curr (in)" - label curr2 "PSU-2(R) 12V Rail Curr (out)" - chip "dps460-i2c-*-59" label in1 "PSU-1(L) 220V Rail (in)" - label in2 "PSU-1(L) 220V Rail (in)" + ignore in2 label in3 "PSU-1(L) 12V Rail (out)" label fan1 "PSU-1(L) Fan 1" ignore fan2 @@ -181,13 +167,23 @@ bus "i2c-4" "i2c-1-mux (chan_id 3)" label power2 "PSU-1(L) 12V Rail Pwr (out)" label curr1 "PSU-1(L) 220V Rail Curr (in)" label curr2 "PSU-1(L) 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-2(R) 220V Rail (in)" + ignore in2 + label in3 "PSU-2(R) 12V Rail (out)" + label fan1 "PSU-2(R) Fan 1" + ignore fan2 + ignore fan3 + label temp1 "PSU-2(R) Temp 1" + label temp2 "PSU-2(R) Temp 2" + label temp3 "PSU-2(R) Temp 3" + label power1 "PSU-2(R) 220V Rail Pwr (in)" + label power2 "PSU-2(R) 12V Rail Pwr (out)" + label curr1 "PSU-2(R) 220V Rail Curr (in)" + label curr2 "PSU-2(R) 12V Rail Curr (out)" # Chassis fans chip "mlxreg_fan-isa-*" label fan1 "Chassis Fan Drawer-1" label fan2 "Chassis Fan Drawer-2" label fan3 "Chassis Fan Drawer-3" - -# Miscellaneous -chip "*-virtual-*" - ignore temp1 From 1714e621be5841abe51024eae4a8c5038efa05da Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Fri, 12 Jun 2020 16:10:23 -0700 Subject: [PATCH 0787/1427] [docker-radv]: Convert radv docker to buster (#4727) * Set radvd version to match buster version(2.17-2) Signed-off-by: Joyas Joseph --- dockers/docker-router-advertiser/Dockerfile.j2 | 2 +- rules/docker-router-advertiser.mk | 8 +++----- rules/radvd.mk | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/dockers/docker-router-advertiser/Dockerfile.j2 b/dockers/docker-router-advertiser/Dockerfile.j2 index 1b372c401964..7f57ade4fade 100644 --- a/dockers/docker-router-advertiser/Dockerfile.j2 +++ b/dockers/docker-router-advertiser/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk index ec3fcf6e1fa3..c7efe7c1f560 100644 --- a/rules/docker-router-advertiser.mk +++ b/rules/docker-router-advertiser.mk @@ -7,20 +7,18 @@ DOCKER_ROUTER_ADVERTISER_DBG = $(DOCKER_ROUTER_ADVERTISER_STEM)-$(DBG_IMAGE_MARK $(DOCKER_ROUTER_ADVERTISER)_PATH = $(DOCKERS_PATH)/$(DOCKER_ROUTER_ADVERTISER_STEM) $(DOCKER_ROUTER_ADVERTISER)_DEPENDS += $(RADVD) $(REDIS_TOOLS) -$(DOCKER_ROUTER_ADVERTISER)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_ROUTER_ADVERTISER)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_ROUTER_ADVERTISER)_DBG_DEPENDS += $(RADVD_DBG) -$(DOCKER_ROUTER_ADVERTISER)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_ROUTER_ADVERTISER)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_ROUTER_ADVERTISER)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_ROUTER_ADVERTISER)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_ROUTER_ADVERTISER) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ROUTER_ADVERTISER) -SONIC_STRETCH_DOCKERS += $(DOCKER_ROUTER_ADVERTISER) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_ROUTER_ADVERTISER_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ROUTER_ADVERTISER_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ROUTER_ADVERTISER_DBG) $(DOCKER_ROUTER_ADVERTISER)_CONTAINER_NAME = radv $(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += --privileged -t diff --git a/rules/radvd.mk b/rules/radvd.mk index 12f3066227d0..f0a048280443 100644 --- a/rules/radvd.mk +++ b/rules/radvd.mk @@ -1,6 +1,6 @@ # radvd package -RADVD_VERSION = 2.17-2~bpo9+1 +RADVD_VERSION = 2.17-2 export RADVD_VERSION From 4e482c16badb13c10ded6c2879791b36b735103f Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 12 Jun 2020 16:20:31 -0700 Subject: [PATCH 0788/1427] [build] Enable telemetry service by default (#4760) **- Why I did it** To ensure telemetry service is enabled by default after installing a fresh SONiC image **- How I did it** Set telemetry feature status to "enabled" when generating init_cfg.json file --- files/build_templates/init_cfg.json.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index c187e02762b8..7a0a8d15880d 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -18,9 +18,9 @@ } }, "FEATURE": { -{%- for feature in ["sflow", "telemetry"] %} +{%- for feature, status in [("sflow", "disabled"), ("telemetry", "enabled")] %} "{{feature}}": { - "status": "disabled" + "status": "{{status}}" }{% if not loop.last %},{% endif -%} {% endfor %} }, From a748daeaedeeec55f0384b2c81853d8d764734a6 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Sat, 13 Jun 2020 04:51:10 +0530 Subject: [PATCH 0789/1427] [docker-sonic-mgmt]: import patch to support 'become' and 'become_user' arguments in pytest-ansible (#4681) --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index a623a5b102a4..c30fa3d33559 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -111,9 +111,7 @@ RUN apt-get update \ RUN pip install azure-kusto-data==0.0.13 \ azure-kusto-ingest==0.0.13 -# Install pytest-ansible module RUN pip install wheel==0.33.6 -RUN pip install pytest-ansible==2.2.2 ## Copy and install sonic-mgmt docker dependencies COPY \ @@ -131,6 +129,14 @@ RUN pip install ansible==2.8.12 RUN pip install pysubnettree +# Install pytest-ansible module with 'become', 'become_user' parameters support +RUN git clone https://github.com/ansible/pytest-ansible.git \ + && cd pytest-ansible \ + && git checkout d33c025f070a9c870220a157cc5a999fda68de44 \ + && python setup.py install \ + && cd .. \ + && rm -fr pytest-ansible + RUN mkdir /var/run/sshd EXPOSE 22 From edeb40ffcf812b1415d3fa953ac1860db6a948d7 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Fri, 12 Jun 2020 18:06:08 -0700 Subject: [PATCH 0790/1427] [k8s]: switching to Flannel from Calico. (#4768) Switching to Flannel from Calico which brings down the image size by around 500+MB. --- Makefile.work | 2 +- files/build_templates/sonic_debian_extension.j2 | 5 ++--- rules/config | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Makefile.work b/Makefile.work index ad8231326a18..ac87eef87937 100644 --- a/Makefile.work +++ b/Makefile.work @@ -183,7 +183,7 @@ SONIC_BUILD_INSTRUCTION := make \ INSTALL_KUBERNETES=$(INSTALL_KUBERNETES) \ KUBERNETES_VERSION=$(KUBERNETES_VERSION) \ K8s_GCR_IO_PAUSE_VERSION=$(K8s_GCR_IO_PAUSE_VERSION) \ - K8s_CNI_CALICO_VERSION=$(K8s_CNI_CALICO_VERSION) \ + K8s_CNI_FLANNEL_VERSION=$(K8s_CNI_FLANNEL_VERSION) \ SONIC_ENABLE_PFCWD_ON_START=$(ENABLE_PFCWD_ON_START) \ SONIC_ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \ SONIC_INSTALL_DEBUG_TOOLS=$(INSTALL_DEBUG_TOOLS) \ diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0f371f98bd0a..2afc17024337 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -462,11 +462,10 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta {% if install_kubernetes == "y" %} ## Pull in kubernetes docker images echo "pulling universal k8s images ..." +FLANNEL_ARCH=$([ "${CONFIGURED_ARCH}" == "armhf" ] && echo "arm64" || echo "${CONFIGURED_ARCH}") sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull k8s.gcr.io/pause:${K8s_GCR_IO_PAUSE_VERSION} sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull k8s.gcr.io/kube-proxy:v${KUBERNETES_VERSION} -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/node:v${K8s_CNI_CALICO_VERSION} -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/pod2daemon-flexvol:v${K8s_CNI_CALICO_VERSION} -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/cni:v${K8s_CNI_CALICO_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull quay.io/coreos/flannel:${K8s_CNI_FLANNEL_VERSION}-${FLANNEL_ARCH} echo "docker images pull complete" {% endif %} diff --git a/rules/config b/rules/config index 9b5f27d765b1..f20708bbd2b9 100644 --- a/rules/config +++ b/rules/config @@ -137,13 +137,13 @@ INSTALL_KUBERNETES = n # KUBERNETES_VERSION - Set to the required version. # K8s_GCR_IO_PAUSE_VERSION - Version of k8s universal pause container image -# K8s_CNI_CALICO_VERSION - Calico used as CNI; Appropriate version for this Kubernetes version +# K8s_CNI_FLANNEL_VERSION - Flannel used as CNI; Appropriate version for this Kubernetes version # These are Used *only* when INSTALL_KUBERNETES=y # NOTE: As a worker node it has to run version compatible to kubernetes master. # KUBERNETES_VERSION = 1.18.0 K8s_GCR_IO_PAUSE_VERSION = 3.2 -K8s_CNI_CALICO_VERSION = 3.12.1 +K8s_CNI_FLANNEL_VERSION = v0.12.0 # SONIC_ENABLE_IMAGE_SIGNATURE - enable image signature # To not use the auto-generated self-signed certificate, the required files to sign the image as below: From 76a395cdbf911738ba3c384cd9b096819fcb275d Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Sat, 13 Jun 2020 15:10:13 +0800 Subject: [PATCH 0791/1427] [secure boot] Support rw files allowlist (#4585) * Support rw files allowlist for Sonic Secure Boot * Improve the performance * fix bug * Move the config description into a md file * Change to use a simple way to remove the blank line * Support chmod a-x in rw folder * Change function name * Change some unnecessary words --- build_image.sh | 1 + files/Aboot/boot0.j2 | 3 ++ .../secureboot/allowlist_paths.conf | 35 +++++++++++++++++++ .../secureboot/allowlist_paths.md | 11 ++++++ files/initramfs-tools/union-mount.j2 | 33 +++++++++++++++++ 5 files changed, 83 insertions(+) create mode 100644 files/image_config/secureboot/allowlist_paths.conf create mode 100644 files/image_config/secureboot/allowlist_paths.md diff --git a/build_image.sh b/build_image.sh index 2768c0eeee24..4fd9f7315a25 100755 --- a/build_image.sh +++ b/build_image.sh @@ -133,6 +133,7 @@ elif [ "$IMAGE_TYPE" = "aboot" ]; then sed -i -e "s/%%IMAGE_VERSION%%/$IMAGE_VERSION/g" files/Aboot/boot0 pushd files/Aboot && zip -g $OLDPWD/$OUTPUT_ABOOT_IMAGE boot0; popd pushd files/Aboot && zip -g $OLDPWD/$ABOOT_BOOT_IMAGE boot0; popd + pushd files/image_config/secureboot && zip -g $OLDPWD/$OUTPUT_ABOOT_IMAGE allowlist_paths.conf; popd echo "$IMAGE_VERSION" >> .imagehash zip -g $OUTPUT_ABOOT_IMAGE .imagehash zip -g $ABOOT_BOOT_IMAGE .imagehash diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index a6856f9cabd2..0ac7d8e12a9d 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -399,6 +399,9 @@ write_boot_configs() { fi fi + # setting secure_boot_enable=y when secure boot enabled + [ -f /bin/securebootctl ] && securebootctl secureboot -display | grep -i "Secure Boot enable" -q && echo "secure_boot_enable=y" >> /tmp/append + mkdir -p "$image_path" cat /tmp/append > $cmdline_image [ -s ${target_path}/machine.conf ] || write_machine_config diff --git a/files/image_config/secureboot/allowlist_paths.conf b/files/image_config/secureboot/allowlist_paths.conf new file mode 100644 index 000000000000..fe5b890e0678 --- /dev/null +++ b/files/image_config/secureboot/allowlist_paths.conf @@ -0,0 +1,35 @@ +home/.* +var/core/.* +var/log/.* +etc/adjtime +etc/default/ntp +etc/dhcp/dhclient.conf +etc/ebtables.filter +etc/group +etc/gshadow +etc/hostname +etc/hosts +etc/machine-id +etc/network/interfaces +etc/nsswitch.conf +etc/ntp.conf +etc/pam.d/common-auth-sonic +etc/pam.d/sshd +etc/pam.d/login +etc/pam.d/sshd.old +etc/passwd +etc/rsyslog.conf +etc/shadow +etc/sonic/acl.json +etc/sonic/config_db.json +etc/sonic/minigraph.xml +etc/sonic/old_config/.* +etc/sonic/snmp.yml +etc/sonic/updategraph.conf +etc/ssh/ssh_host_rsa_key.pub +etc/ssh/ssh_host_rsa_key +etc/subgid +etc/subuid +etc/tacplus_nss.conf +etc/tacplus_user +lib/systemd/system/serial-getty@.service diff --git a/files/image_config/secureboot/allowlist_paths.md b/files/image_config/secureboot/allowlist_paths.md new file mode 100644 index 000000000000..7ce86b9bc90c --- /dev/null +++ b/files/image_config/secureboot/allowlist_paths.md @@ -0,0 +1,11 @@ +# Configuration Guide +It is the patterns of the relative paths in /host/image-{{hash}}/rw folder. +The patterns will not be used if the Sonic Secure Boot feature is not enabled. +The files that are not in the allowlist will be removed when the Sonic System cold reboot. + +### Example config to add all the files in a folder to allowlist +home/.* + +### Example config to add a file to allowlist +etc/nsswitch.conf + diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index 5e33e1760874..8c8bb926444d 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -39,10 +39,43 @@ set_tmpfs_log_partition_size() [ $maxsize -le $varlogsize ] && varlogsize=$maxsize } +remove_not_in_allowlist_files() +{ + image_dir=$1 + allowlist_file=${rootmnt}/host/$image_dir/allowlist_paths.conf + + # Return if the secure_boot_enable option is not set + if ! (cat /proc/cmdline | grep -i -q "secure_boot_enable=[y1]"); then + return + fi + + # Return if the allowlist file does not exist + if ! test -f "${allowlist_file}"; then + echo "The file ${allowlist_file} is missing, failed to mount rw folder." 1>&2 + exit 1 + fi + + rw_dir=${rootmnt}/host/$image_dir/rw + + # Set the grep pattern file, remove the blank line in config file + allowlist_pattern_file=${rootmnt}/host/$image_dir/allowlist_paths.pattern + awk -v rw_dir="$rw_dir" 'NF {print rw_dir"/"$0"$"}' ${allowlist_file} > $allowlist_pattern_file + + # Find the files in the rw folder, and remove the files not in the allowlist + find ${rw_dir} -type f | grep -v -f $allowlist_pattern_file | xargs /bin/rm -f + rm -f $allowlist_pattern_file +} + ## Mount the overlay file system: rw layer over squashfs image_dir=$(cat /proc/cmdline | sed -e 's/.*loop=\(\S*\)\/.*/\1/') mkdir -p ${rootmnt}/host/$image_dir/rw mkdir -p ${rootmnt}/host/$image_dir/work +## Remove the files not in allowlist in the rw folder +remove_not_in_allowlist_files "$image_dir" +## Remove the executable permission for all the files in rw folder except home folder +rw_dir=${rootmnt}/host/$image_dir/rw +find ${rw_dir} -type f -not -path ${rw_dir}/home -exec chmod a-x {} + + mount -n -o lowerdir=${rootmnt},upperdir=${rootmnt}/host/$image_dir/rw,workdir=${rootmnt}/host/$image_dir/work -t overlay root-overlay ${rootmnt} ## Check if the root block device is still there [ -b ${ROOT} ] || mdev -s From 0a750a6b548a482538b5e9092244a5befacaa93c Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 13 Jun 2020 13:32:13 -0700 Subject: [PATCH 0792/1427] [sonic-utilities] Update submodule (#4770) * src/sonic-utilities 5765570...a21e01a (13): > [config] Don't attempt to restart disabled services (#944) > [crm] Use swsssdk API instead of redis-cli for getting keys from redis DB (#943) > Fixed fast-reboot for BFN platform (#871) > [sfputil] Add support of platform.json (#767) > [show] Add support for SONiC Gearbox Manager via new gearboxutil utility (#931) > [warm-reboot]: added pre-check for ISSU file (#915) > Add_intf_range (#913) > add fec config/show option (#764) > Make sure db_migrator is run after all config are loaded during (#926) > Changes to make lldp show command for multi-npu platforms. (#914) > [showtech]: add knet dump information in show tech (#925) > Vnet alias mapping (#924) > Revert the change to kdump reboot (#916) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 57655708e12b..a21e01a2f07c 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 57655708e12b878668e16a5ac1fab8d6694fc91c +Subproject commit a21e01a2f07c1567c3b8ada7b00f00a2dc7bf428 From 1db64a3bc1661ba6c8ca67a73e02c72ef982c548 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Mon, 15 Jun 2020 14:25:49 +0300 Subject: [PATCH 0793/1427] [Mellanox] Add ONIE and SSD platform components. (#4758) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/mlnx-onie-fw-update.sh | 253 ++++-- .../sonic_platform/chassis.py | 4 +- .../sonic_platform/component.py | 728 +++++++++++++----- platform/mellanox/mlnx-ssd-fw-update.sh | 12 +- 4 files changed, 731 insertions(+), 266 deletions(-) diff --git a/platform/mellanox/mlnx-onie-fw-update.sh b/platform/mellanox/mlnx-onie-fw-update.sh index 314f4ed70268..5a62e74b647b 100755 --- a/platform/mellanox/mlnx-onie-fw-update.sh +++ b/platform/mellanox/mlnx-onie-fw-update.sh @@ -1,120 +1,205 @@ -#!/bin/sh +#!/bin/bash # Copyright (C) 2019 Mellanox Technologies Ltd. # Copyright (C) 2019 Michael Shych # # SPDX-License-Identifier: GPL-2.0 -this_script=${ONIE_FWPKG_PROGRAM_NAME:-$(basename $(realpath $0))} +this_script="$(basename $(realpath ${0}))" +lock_file="/var/run/${this_script%.*}.lock" onie_mount=/mnt/onie-boot +onie_lib=/lib/onie os_boot=/host -onie_partition= -export ONIE_FWPKG_PROGRAM_NAME=$(basename $(realpath $0)) - -usage() -{ +print_help() { cat <${lock_file} + /usr/bin/flock -x ${lock_fd} + register_unlock_handler ${lock_fd} +} + +# Multiprocessing synchronization +lock_script_state_change + # Process command arguments -cmd=$1 -# optional argument -name="$2" +cmd="${1}" + +# Optional argument +arg="${2}" -if [ -z "$cmd" ] ; then - # Default to 'show' if no command is specified. - cmd="show" +if [[ -z "${cmd}" ]]; then + # Default to 'show' if no command is specified. + cmd="show" fi -case "$cmd" in - add | remove) - [ -z "$name" ] && { - echo "ERROR: This command requires a firmware update file name." - echo "Run '$this_script help' for complete details." - exit 1 - } - ;; - update) - enable_onie_access - show_pending - rc=$? - if [ $rc -ne 0 ]; then - change_grub_boot_order - rc=$? - clean_onie_access - exit $rc - else - echo "ERROR: NO FW images for update." - echo "Run: $this_script add before update." - clean_onie_access - exit 1 - fi - ;; - purge | show | show-results | show-log | show-pending | help) - ;; - *) - echo "Unknown command: $cmd" - exit 1 - ;; +case "${cmd}" in + add|remove) + if [[ -z "${arg}" ]]; then + echo "ERROR: This command requires a firmware update file name" + echo "Run: '${this_script} help' for complete details" + exit 1 + fi + ;; + update) + enable_onie_access + show_pending + rc=$? + if [[ ${rc} -ne 0 ]]; then + enable_onie_fw_update_mode + rc=$? + disable_onie_access + if [[ ${rc} -eq 0 ]]; then + system_reboot + else + echo "ERROR: failed to enable ONIE firmware update mode" + exit ${rc} + fi + else + echo "ERROR: No firmware images for update" + echo "Run: '${this_script} add ' before update" + disable_onie_access + exit 1 + fi + ;; + purge|show-pending|show-results|show|show-log|help) + ;; + *) + echo "ERROR: Unknown command: ${cmd}" + exit 1 + ;; esac enable_onie_access -$onie_mount/onie/tools/bin/onie-fwpkg "$@" +${onie_mount}/onie/tools/bin/onie-fwpkg "$@" rc=$? -if [ $cmd = "help" ]; then - usage +if [[ "${cmd}" = "help" ]]; then + print_help fi -clean_onie_access +disable_onie_access -exit $rc +exit ${rc} diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 2e9ad7210ab8..0625eba4f1b1 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -149,7 +149,9 @@ def initialize_eeprom(self): def initialize_components(self): # Initialize component list - from sonic_platform.component import ComponentBIOS, ComponentCPLD + from sonic_platform.component import ComponentONIE, ComponentSSD, ComponentBIOS, ComponentCPLD + self._component_list.append(ComponentONIE()) + self._component_list.append(ComponentSSD()) self._component_list.append(ComponentBIOS()) self._component_list.extend(ComponentCPLD.get_component_list()) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index d5937b63286d..0552e09ae5f5 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -6,19 +6,308 @@ # implementation of new platform api ############################################################################# from __future__ import print_function + + try: - from sonic_platform_base.component_base import ComponentBase - from sonic_device_util import get_machine_info - from glob import glob - import subprocess - import io import os + import io import re + import glob + import tempfile + import subprocess + import ConfigParser + + from sonic_platform_base.component_base import ComponentBase except ImportError as e: raise ImportError(str(e) + "- required module not found") -ZERO = '0' -NEWLINE = '\n' + +class MPFAManager(object): + MPFA_EXTENSION = '.mpfa' + + MPFA_EXTRACT_COMMAND = 'tar xzf {} -C {}' + MPFA_CLEANUP_COMMAND = 'rm -rf {}' + + def __init__(self, mpfa_path): + self.__mpfa_path = mpfa_path + self.__contents_path = None + self.__metadata = None + + def __enter__(self): + self.extract() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.cleanup() + + def __validate_path(self, mpfa_path): + if not os.path.isfile(mpfa_path): + raise RuntimeError("MPFA doesn't exist: path={}".format(mpfa_path)) + + name, ext = os.path.splitext(mpfa_path) + if ext != self.MPFA_EXTENSION: + raise RuntimeError("MPFA doesn't have valid extension: path={}".format(mpfa_path)) + + def __extract_contents(self, mpfa_path): + contents_path = tempfile.mkdtemp(prefix='mpfa-') + + cmd = self.MPFA_EXTRACT_COMMAND.format(mpfa_path, contents_path) + subprocess.check_call(cmd.split()) + + self.__contents_path = contents_path + + def __parse_metadata(self, contents_path): + metadata_path = os.path.join(contents_path, 'metadata.ini') + + if not os.path.isfile(metadata_path): + raise RuntimeError("MPFA metadata doesn't exist: path={}".format(metadata_path)) + + cp = ConfigParser.ConfigParser() + with io.open(metadata_path, 'r') as metadata_ini: + cp.readfp(metadata_ini) + + self.__metadata = cp + + def extract(self): + if self.is_extracted(): + return + + self.__validate_path(self.__mpfa_path) + self.__extract_contents(self.__mpfa_path) + self.__parse_metadata(self.__contents_path) + + def cleanup(self): + if os.path.exists(self.__contents_path): + cmd = self.MPFA_CLEANUP_COMMAND.format(self.__contents_path) + subprocess.check_call(cmd.split()) + + self.__contents_path = None + self.__metadata = None + + def get_path(self): + return self.__contents_path + + def get_metadata(self): + return self.__metadata + + def is_extracted(self): + return self.__contents_path is not None and os.path.exists(self.__contents_path) + + +class ONIEUpdater(object): + ONIE_FW_UPDATE_CMD_ADD = '/usr/bin/mlnx-onie-fw-update.sh add {}' + ONIE_FW_UPDATE_CMD_REMOVE = '/usr/bin/mlnx-onie-fw-update.sh remove {}' + ONIE_FW_UPDATE_CMD_UPDATE = '/usr/bin/mlnx-onie-fw-update.sh update' + ONIE_FW_UPDATE_CMD_SHOW_PENDING = '/usr/bin/mlnx-onie-fw-update.sh show-pending' + + ONIE_VERSION_PARSE_PATTERN = '([0-9]{4})\.([0-9]{2})-([0-9]+)\.([0-9]+)\.([0-9]+)-([0-9]+)' + ONIE_VERSION_BASE_PARSE_PATTERN = '([0-9]+)\.([0-9]+)\.([0-9]+)' + ONIE_VERSION_REQUIRED = '5.2.0016' + + ONIE_VERSION_ATTR = 'onie_version' + ONIE_NO_PENDING_UPDATES_ATTR = 'No pending firmware updates present' + + ONIE_IMAGE_INFO_COMMAND = '/bin/bash {} -q -i' + + def __mount_onie_fs(self): + fs_mountpoint = '/mnt/onie-fs' + onie_path = '/lib/onie' + + if os.path.lexists(onie_path) or os.path.exists(fs_mountpoint): + self.__umount_onie_fs() + + cmd = "fdisk -l | grep 'ONIE boot' | awk '{print $1}'" + fs_path = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).rstrip('\n') + + os.mkdir(fs_mountpoint) + cmd = "mount -n -r -t ext4 {} {}".format(fs_path, fs_mountpoint) + subprocess.check_call(cmd, shell=True) + + fs_onie_path = os.path.join(fs_mountpoint, 'onie/tools/lib/onie') + os.symlink(fs_onie_path, onie_path) + + return fs_mountpoint + + def __umount_onie_fs(self): + fs_mountpoint = '/mnt/onie-fs' + onie_path = '/lib/onie' + + if os.path.islink(onie_path): + os.unlink(onie_path) + + if os.path.ismount(fs_mountpoint): + cmd = "umount -rf {}".format(fs_mountpoint) + subprocess.check_call(cmd, shell=True) + + if os.path.exists(fs_mountpoint): + os.rmdir(fs_mountpoint) + + def __stage_update(self, image_path): + cmd = self.ONIE_FW_UPDATE_CMD_ADD.format(image_path) + + try: + subprocess.check_call(cmd.split()) + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to stage firmware update: {}".format(str(e))) + + def __unstage_update(self, image_path): + cmd = self.ONIE_FW_UPDATE_CMD_REMOVE.format(os.path.basename(image_path)) + + try: + subprocess.check_call(cmd.split()) + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to unstage firmware update: {}".format(str(e))) + + def __trigger_update(self): + cmd = self.ONIE_FW_UPDATE_CMD_UPDATE + + try: + subprocess.check_call(cmd.split()) + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to trigger firmware update: {}".format(str(e))) + + def __is_update_staged(self, image_path): + cmd = self.ONIE_FW_UPDATE_CMD_SHOW_PENDING + + try: + output = subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get pending firmware updates: {}".format(str(e))) + + basename = os.path.basename(image_path) + + for line in output.splitlines(): + if line.startswith(basename): + return True + + return False + + def parse_onie_version(self, version, is_base=False): + onie_year = None + onie_month = None + onie_major = None + onie_minor = None + onie_release = None + onie_baudrate = None + + if is_base: + pattern = self.ONIE_VERSION_BASE_PARSE_PATTERN + + m = re.search(pattern, version) + if not m: + raise RuntimeError("Failed to parse ONIE version: pattern={}, version={}".format(pattern, version)) + + onie_major = m.group(1) + onie_minor = m.group(2) + onie_release = m.group(3) + + return onie_year, onie_month, onie_major, onie_minor, onie_release, onie_baudrate + + pattern = self.ONIE_VERSION_PARSE_PATTERN + + m = re.search(pattern, version) + if not m: + raise RuntimeError("Failed to parse ONIE version: pattern={}, version={}".format(pattern, version)) + + onie_year = m.group(1) + onie_month = m.group(2) + onie_major = m.group(3) + onie_minor = m.group(4) + onie_release = m.group(5) + onie_baudrate = m.group(6) + + return onie_year, onie_month, onie_major, onie_minor, onie_release, onie_baudrate + + def get_onie_required_version(self): + return self.ONIE_VERSION_REQUIRED + + def get_onie_version(self): + version = None + + try: + fs_mountpoint = self.__mount_onie_fs() + machine_conf_path = os.path.join(fs_mountpoint, 'onie/grub/grub-machine.cfg') + + with open(machine_conf_path, 'r') as machine_conf: + for line in machine_conf: + if line.startswith(self.ONIE_VERSION_ATTR): + items = line.rstrip('\n').split('=') + + if len(items) != 2: + raise RuntimeError("Failed to parse ONIE info: line={}".format(line)) + + version = items[1] + break + + if version is None: + raise RuntimeError("Failed to parse ONIE version") + finally: + self.__umount_onie_fs() + + return version + + def get_onie_firmware_info(self, image_path): + firmware_info = { } + + try: + self.__mount_onie_fs() + + cmd = self.ONIE_IMAGE_INFO_COMMAND.format(image_path) + + try: + output = subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get ONIE firmware info: {}".format(str(e))) + + for line in output.splitlines(): + items = line.split('=') + + if len(items) != 2: + raise RuntimeError("Failed to parse ONIE firmware info: line={}".format(line)) + + firmware_info[items[0]] = items[1] + finally: + self.__umount_onie_fs() + + return firmware_info + + def update_firmware(self, image_path): + cmd = self.ONIE_FW_UPDATE_CMD_SHOW_PENDING + + try: + output = subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get pending firmware updates: {}".format(str(e))) + + no_pending_updates = False + + for line in output.splitlines(): + if line.startswith(self.ONIE_NO_PENDING_UPDATES_ATTR): + no_pending_updates = True + break + + if not no_pending_updates: + raise RuntimeError("Failed to complete firmware update: pending updates are present") + + try: + self.__stage_update(image_path) + self.__trigger_update() + except: + if self.__is_update_staged(image_path): + self.__unstage_update(image_path) + raise + + def is_non_onie_firmware_update_supported(self): + current_version = self.get_onie_version() + _, _, major1, minor1, release1, _ = self.parse_onie_version(current_version) + version1 = int("{}{}{}".format(major1, minor1, release1)) + + required_version = self.get_onie_required_version() + _, _, major2, minor2, release2, _ = self.parse_onie_version(required_version, True) + version2 = int("{}{}{}".format(major2, minor2, release2)) + + return version1 >= version2 + class Component(ComponentBase): def __init__(self): @@ -26,27 +315,12 @@ def __init__(self): self.description = None self.image_ext_name = None - def get_name(self): - """ - Retrieves the name of the component - - Returns: - A string containing the name of the component - """ return self.name - def get_description(self): - """ - Retrieves the description of the component - - Returns: - A string containing the description of the component - """ return self.description - @staticmethod def _read_generic_file(filename, len, ignore_errors=False): """ @@ -63,7 +337,6 @@ def _read_generic_file(filename, len, ignore_errors=False): return result - @staticmethod def _get_command_result(cmdline): try: @@ -79,149 +352,246 @@ def _get_command_result(cmdline): return result - def _check_file_validity(self, image_path): - # check whether the image file exists if not os.path.isfile(image_path): print("ERROR: File {} doesn't exist or is not a file".format(image_path)) return False + name_list = os.path.splitext(image_path) if self.image_ext_name is not None: - name_list = os.path.splitext(image_path) if name_list[1] != self.image_ext_name: print("ERROR: Extend name of file {} is wrong. Image for {} should have extend name {}".format(image_path, self.name, self.image_ext_name)) return False + else: + if name_list[1]: + print("ERROR: Extend name of file {} is wrong. Image for {} shouldn't have extension".format(image_path, self.name)) + return False return True +class ComponentONIE(Component): + COMPONENT_NAME = 'ONIE' + COMPONENT_DESCRIPTION = 'ONIE - Open Network Install Environment' -class ComponentBIOS(Component): - COMPONENT_NAME = 'BIOS' - COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' - COMPONENT_FIRMWARE_EXTENSION = '.rom' + ONIE_IMAGE_VERSION_ATTR = 'image_version' - # To update BIOS requires the ONIE with version 5.2.0016 or upper - ONIE_VERSION_PARSE_PATTERN = '[0-9]{4}\.[0-9]{2}-([0-9]+)\.([0-9]+)\.([0-9]+)' - ONIE_VERSION_MAJOR_OFFSET = 1 - ONIE_VERSION_MINOR_OFFSET = 2 - ONIE_VERSION_RELEASE_OFFSET = 3 - ONIE_REQUIRED_MAJOR = '5' - ONIE_REQUIRED_MINOR = '2' - ONIE_REQUIRED_RELEASE = '0016' + def __init__(self): + super(ComponentONIE, self).__init__() - BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' - BIOS_PENDING_UPDATE_PATTERN = '([0-9A-Za-z_]*.rom)[\s]*\|[\s]*bios_update' + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + self.onie_updater = ONIEUpdater() - ONIE_FW_UPDATE_CMD_ADD = '/usr/bin/mlnx-onie-fw-update.sh add {}' - ONIE_FW_UPDATE_CMD_REMOVE = '/usr/bin/mlnx-onie-fw-update.sh remove {}' - ONIE_FW_UPDATE_CMD_UPDATE = '/usr/bin/mlnx-onie-fw-update.sh update' - ONIE_FW_UPDATE_CMD_SHOW = '/usr/bin/mlnx-onie-fw-update.sh show-pending' + def __install_firmware(self, image_path): + if not self._check_file_validity(image_path): + return False + + try: + print("INFO: Staging {} firmware update with ONIE updater".format(self.name)) + self.onie_updater.update_firmware(image_path) + except Exception as e: + print("ERROR: Failed to update {} firmware: {}".format(self.name, str(e))) + return False - BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' + return True + + def get_firmware_version(self): + return self.onie_updater.get_onie_version() + + def get_available_firmware_version(self, image_path): + firmware_info = self.onie_updater.get_onie_firmware_info(image_path) + if self.ONIE_IMAGE_VERSION_ATTR not in firmware_info: + raise RuntimeError("Failed to get {} available firmware version".format(self.name)) + + return firmware_info[self.ONIE_IMAGE_VERSION_ATTR] + + def get_firmware_update_notification(self, image_path): + return "Immediate cold reboot is required to complete {} firmware update".format(self.name) + + def install_firmware(self, image_path): + return self.__install_firmware(image_path) + + def update_firmware(self, image_path): + self.__install_firmware(image_path) + + +class ComponentSSD(Component): + COMPONENT_NAME = 'SSD' + COMPONENT_DESCRIPTION = 'SSD - Solid-State Drive' + COMPONENT_FIRMWARE_EXTENSION = '.pkg' + + FIRMWARE_VERSION_ATTR = 'Firmware Version' + AVAILABLE_FIRMWARE_VERSION_ATTR = 'Available Firmware Version' + POWER_CYCLE_REQUIRED_ATTR = 'Power Cycle Required' + UPGRADE_REQUIRED_ATTR = 'Upgrade Required' + + SSD_INFO_COMMAND = "/usr/bin/mlnx-ssd-fw-update.sh -q" + SSD_FIRMWARE_INFO_COMMAND = "/usr/bin/mlnx-ssd-fw-update.sh -q -i {}" + SSD_FIRMWARE_UPDATE_COMMAND = "/usr/bin/mlnx-ssd-fw-update.sh -y -u -i {}" def __init__(self): + super(ComponentSSD, self).__init__() + self.name = self.COMPONENT_NAME self.description = self.COMPONENT_DESCRIPTION self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION + def __install_firmware(self, image_path): + if not self._check_file_validity(image_path): + return False + + cmd = self.SSD_FIRMWARE_UPDATE_COMMAND.format(image_path) + + try: + print("INFO: Installing {} firmware update".format(self.name)) + subprocess.check_call(cmd.split()) + except subprocess.CalledProcessError as e: + print("ERROR: Failed to update {} firmware: {}".format(self.name, str(e))) + return False + + return True def get_firmware_version(self): - """ - Retrieves the firmware version of the component + cmd = self.SSD_INFO_COMMAND - Returns: - A string containing the firmware version of the component + try: + output = subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get {} info: {}".format(self.name, str(e))) - BIOS version is retrieved via command 'dmidecode -t 11' - which should return result in the following convention - # dmidecode 3.0 - Getting SMBIOS data from sysfs. - SMBIOS 2.7 present. + for line in output.splitlines(): + if line.startswith(self.FIRMWARE_VERSION_ATTR): + return line.split(':')[1].lstrip(' \t') - Handle 0x0022, DMI type 11, 5 bytes - OEM Strings - String 1:*0ABZS017_02.02.002* - String 2: To Be Filled By O.E.M. + raise RuntimeError("Failed to parse {} version".format(self.name)) + + def get_available_firmware_version(self, image_path): + cmd = self.SSD_FIRMWARE_INFO_COMMAND.format(image_path) - By using regular expression 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' - we can extrace the version string which is marked with * in the above context - """ try: - bios_ver_str = self._get_command_result(self.BIOS_QUERY_VERSION_COMMAND) - m = re.search(self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str) - result = m.group(1) - except (AttributeError, RuntimeError) as e: - raise RuntimeError("Failed to parse BIOS version due to {}".format(repr(e))) + output = subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get {} firmware info: {}".format(self.name, str(e))) - return result + current_firmware_version = None + available_firmware_version = None + upgrade_required = None + for line in output.splitlines(): + if line.startswith(self.FIRMWARE_VERSION_ATTR): + current_firmware_version = line.split(':')[1].lstrip(' \t') + if line.startswith(self.AVAILABLE_FIRMWARE_VERSION_ATTR): + available_firmware_version = line.split(':')[1].lstrip(' \t') + if line.startswith(self.UPGRADE_REQUIRED_ATTR): + upgrade_required = line.split(':')[1].lstrip(' \t') + + if upgrade_required is None or upgrade_required not in ['yes', 'no']: + raise RuntimeError("Failed to parse {} firmware upgrade status".format(self.name)) + + if upgrade_required == 'no': + if current_firmware_version is None: + raise RuntimeError("Failed to parse {} current firmware version".format(self.name)) + return current_firmware_version + + if available_firmware_version is None: + raise RuntimeError("Failed to parse {} available firmware version".format(self.name)) + + return available_firmware_version + + def get_firmware_update_notification(self, image_path): + cmd = self.SSD_FIRMWARE_INFO_COMMAND.format(image_path) - def _check_onie_version(self): - # check ONIE version. To update ONIE requires version 5.2.0016 or later. try: - machine_info = get_machine_info() - onie_version_string = machine_info['onie_version'] - m = re.search(self.ONIE_VERSION_PARSE_PATTERN, onie_version_string) - onie_major = m.group(self.ONIE_VERSION_MAJOR_OFFSET) - onie_minor = m.group(self.ONIE_VERSION_MINOR_OFFSET) - onie_release = m.group(self.ONIE_VERSION_RELEASE_OFFSET) - except AttributeError as e: - print("ERROR: Failed to parse ONIE version by {} from {} due to {}".format( - self.ONIE_VERSION_PARSE_PATTERN, machine_conf, repr(e))) - return False + output = subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get {} firmware info: {}".format(self.name, str(e))) - if onie_major < self.ONIE_REQUIRED_MAJOR or onie_minor < self.ONIE_REQUIRED_MINOR or onie_release < self.ONIE_REQUIRED_RELEASE: - print("ERROR: ONIE {}.{}.{} or later is required".format(self.ONIE_REQUIRED_MAJOR, self.ONIE_REQUIRED_MINOR, self.ONIE_REQUIRED_RELEASE)) - return False + power_cycle_required = None + upgrade_required = None - return True + for line in output.splitlines(): + if line.startswith(self.POWER_CYCLE_REQUIRED_ATTR): + power_cycle_required = line.split(':')[1].lstrip(' \t') + if line.startswith(self.UPGRADE_REQUIRED_ATTR): + upgrade_required = line.split(':')[1].lstrip(' \t') + + if upgrade_required is None or upgrade_required not in ['yes', 'no']: + raise RuntimeError("Failed to parse {} firmware upgrade status".format(self.name)) + + if upgrade_required == 'no': + return None + + if power_cycle_required is None or power_cycle_required not in ['yes', 'no']: + raise RuntimeError("Failed to parse {} firmware power policy".format(self.name)) + + notification = None + + if power_cycle_required == 'yes': + notification = "Immediate power cycle is required to complete {} firmware update".format(self.name) + return notification def install_firmware(self, image_path): - """ - Installs firmware to the component + return self.__install_firmware(image_path) - Args: - image_path: A string, path to firmware image + def update_firmware(self, image_path): + self.__install_firmware(image_path) - Returns: - A boolean, True if install was successful, False if not - """ - # check ONIE version requirement - if not self._check_onie_version(): + +class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + COMPONENT_FIRMWARE_EXTENSION = '.rom' + + BIOS_VERSION_COMMAND = 'dmidecode --oem-string 1' + + def __init__(self): + super(ComponentBIOS, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION + self.onie_updater = ONIEUpdater() + + def __install_firmware(self, image_path): + if not self.onie_updater.is_non_onie_firmware_update_supported(): + print("ERROR: ONIE {} or later is required".format(self.onie_updater.get_onie_required_version())) return False - # check whether the file exists if not self._check_file_validity(image_path): return False - # do the real work try: - # check whether there has already been some images pending - # if yes, remove them - result = self._get_command_result(self.ONIE_FW_UPDATE_CMD_SHOW) - pending_list = result.split("\n") - for pending in pending_list: - m = re.match(self.BIOS_PENDING_UPDATE_PATTERN, pending) - if m is not None: - pending_image = m.group(1) - self._get_command_result(self.ONIE_FW_UPDATE_CMD_REMOVE.format(pending_image)) - print("WARNING: Image {} which is already pending to upgrade has been removed".format(pending_image)) - - result = subprocess.check_call(self.ONIE_FW_UPDATE_CMD_ADD.format(image_path).split()) - if result: - return False - result = subprocess.check_call(self.ONIE_FW_UPDATE_CMD_UPDATE.split()) - if result: - return False + print("INFO: Staging {} firmware update with ONIE updater".format(self.name)) + self.onie_updater.update_firmware(image_path) except Exception as e: - print("ERROR: Installing BIOS failed due to {}".format(repr(e))) + print("ERROR: Failed to update {} firmware: {}".format(self.name, str(e))) return False - print("INFO: Reboot is required to finish BIOS installation") return True + def get_firmware_version(self): + cmd = self.BIOS_VERSION_COMMAND + + try: + version = subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get {} version: {}".format(self.name, str(e))) + + return version + + def get_available_firmware_version(self, image_path): + raise NotImplementedError("{} component doesn't support firmware version query".format(self.name)) + + def get_firmware_update_notification(self, image_path): + return "Immediate cold reboot is required to complete {} firmware update".format(self.name) + + def install_firmware(self, image_path): + return self.__install_firmware(image_path) + + def update_firmware(self, image_path): + self.__install_firmware(image_path) class ComponentCPLD(Component): @@ -229,6 +599,9 @@ class ComponentCPLD(Component): COMPONENT_DESCRIPTION = 'CPLD - Complex Programmable Logic Device' COMPONENT_FIRMWARE_EXTENSION = '.vme' + MST_DEVICE_PATH = '/dev/mst' + MST_DEVICE_PATTERN = 'mt[0-9]*_pci_cr0' + CPLD_NUMBER_FILE = '/var/run/hw-management/config/cpld_num' CPLD_PART_NUMBER_FILE = '/var/run/hw-management/system/cpld{}_pn' CPLD_VERSION_FILE = '/var/run/hw-management/system/cpld{}_version' @@ -239,28 +612,54 @@ class ComponentCPLD(Component): CPLD_VERSION_MAX_LENGTH = 2 CPLD_VERSION_MINOR_MAX_LENGTH = 2 - CPLD_PART_NUMBER_DEFAULT = ZERO - CPLD_VERSION_MINOR_DEFAULT = ZERO - - CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} --print-progress {}' + CPLD_PART_NUMBER_DEFAULT = '0' + CPLD_VERSION_MINOR_DEFAULT = '0' - MST_DEVICE_PATTERN = '/dev/mst/mt[0-9]*_pci_cr0' + CPLD_FIRMWARE_UPDATE_COMMAND = 'cpldupdate --dev {} --print-progress {}' def __init__(self, idx): + super(ComponentCPLD, self).__init__() + self.idx = idx self.name = self.COMPONENT_NAME.format(self.idx) self.description = self.COMPONENT_DESCRIPTION self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION + def __get_mst_device(self): + if not os.path.exists(self.MST_DEVICE_PATH): + print("ERROR: mst driver is not loaded") + return None - def get_firmware_version(self): - """ - Retrieves the firmware version of the component + pattern = os.path.join(self.MST_DEVICE_PATH, self.MST_DEVICE_PATTERN) - Returns: - A string containing the firmware version of the component - """ + mst_dev_list = glob.glob(pattern) + if not mst_dev_list or len(mst_dev_list) != 1: + devices = str(os.listdir(self.MST_DEVICE_PATH)) + print("ERROR: Failed to get mst device: pattern={}, devices={}".format(pattern, devices)) + return None + + return mst_dev_list[0] + + def __install_firmware(self, image_path): + if not self._check_file_validity(image_path): + return False + + mst_dev = self.__get_mst_device() + if mst_dev is None: + return False + + cmd = self.CPLD_FIRMWARE_UPDATE_COMMAND.format(mst_dev, image_path) + + try: + print("INFO: Installing {} firmware update: path={}".format(self.name, image_path)) + subprocess.check_call(cmd.split()) + except subprocess.CalledProcessError as e: + print("ERROR: Failed to update {} firmware: {}".format(self.name, str(e))) + return False + + return True + def get_firmware_version(self): part_number_file = self.CPLD_PART_NUMBER_FILE.format(self.idx) version_file = self.CPLD_VERSION_FILE.format(self.idx) version_minor_file = self.CPLD_VERSION_MINOR_FILE.format(self.idx) @@ -275,75 +674,52 @@ def get_firmware_version(self): if version_minor is None: version_minor = self.CPLD_VERSION_MINOR_DEFAULT - part_number = part_number.rstrip(NEWLINE).zfill(self.CPLD_PART_NUMBER_MAX_LENGTH) - version = version.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MAX_LENGTH) - version_minor = version_minor.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH) + part_number = part_number.rstrip('\n').zfill(self.CPLD_PART_NUMBER_MAX_LENGTH) + version = version.rstrip('\n').zfill(self.CPLD_VERSION_MAX_LENGTH) + version_minor = version_minor.rstrip('\n').zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH) return "CPLD{}_REV{}{}".format(part_number, version, version_minor) + def get_available_firmware_version(self, image_path): + with MPFAManager(image_path) as mpfa: + if not mpfa.get_metadata().has_option('version', self.name): + raise RuntimeError("Failed to get {} available firmware version".format(self.name)) - def _get_mst_device(self): - mst_dev_list = glob(self.MST_DEVICE_PATTERN) - if mst_dev_list is None or len(mst_dev_list) != 1: - return None - return mst_dev_list + return mpfa.get_metadata().get('version', self.name) + def get_firmware_update_notification(self, image_path): + name, ext = os.path.splitext(os.path.basename(image_path)) + if ext == self.COMPONENT_FIRMWARE_EXTENSION: + return "Power cycle (with 30 sec delay) or refresh image is required to complete {} firmware update".format(self.name) - def install_firmware(self, image_path): - """ - Installs firmware to the component - - Args: - image_path: A string, path to firmware image - - Returns: - A boolean, True if install was successful, False if not - - Details: - The command "cpldupdate" is provided to install CPLD. There are two ways to do it: - 1. To burn CPLD via gpio, which is faster but only supported on new systems, like SN3700, ... - 2. To install CPLD via firmware, which is slower but supported on older systems. - This also requires the mst device designated. - "cpldupdate --dev " has the logic of testing whether to update via gpio is supported, - and if so then go this way, otherwise tries updating software via fw. So we take advantage of it to update the CPLD. - By doing so we don't have to mind whether to update via gpio supported, which belongs to hardware details. - - So the procedure should be: - 1. Test whether the file exists - 2. Fetch the mst device name - 3. Update CPLD via executing "cpldupdate --dev " - 4. Check the result - """ - # check whether the image file exists - if not self._check_file_validity(image_path): - return False - - mst_dev_list = self._get_mst_device() - if mst_dev_list is None: - print("ERROR: Failed to get mst device which is required for CPLD updating or multiple device files matched") - return False + return "Immediate power cycle is required to complete {} firmware update".format(self.name) - cmdline = self.CPLD_UPDATE_COMMAND.format(mst_dev_list[0], image_path) - success_flag = False + def install_firmware(self, image_path): + return self.__install_firmware(image_path) - try: - subprocess.check_call(cmdline, stderr=subprocess.STDOUT, shell=True) - success_flag = True - except subprocess.CalledProcessError as e: - print("ERROR: Failed to upgrade CPLD: rc={}".format(e.returncode)) + def update_firmware(self, image_path): + with MPFAManager(image_path) as mpfa: + if not mpfa.get_metadata().has_option('firmware', 'burn'): + raise RuntimeError("Failed to get {} burn firmware".format(self.name)) + if not mpfa.get_metadata().has_option('firmware', 'refresh'): + raise RuntimeError("Failed to get {} refresh firmware".format(self.name)) - if success_flag: - print("INFO: Refresh or power cycle is required to finish CPLD installation") + burn_firmware = mpfa.get_metadata().get('firmware', 'burn') + refresh_firmware = mpfa.get_metadata().get('firmware', 'refresh') - return success_flag + print("INFO: Processing {} burn file: firmware install".format(self.name)) + if not self.__install_firmware(os.path.join(mpfa.get_path(), burn_firmware)): + return + print("INFO: Processing {} refresh file: firmware update".format(self.name)) + self.__install_firmware(os.path.join(mpfa.get_path(), refresh_firmware)) @classmethod def get_component_list(cls): component_list = [ ] cpld_number = cls._read_generic_file(cls.CPLD_NUMBER_FILE, cls.CPLD_NUMBER_MAX_LENGTH) - cpld_number = cpld_number.rstrip(NEWLINE) + cpld_number = cpld_number.rstrip('\n') for cpld_idx in xrange(1, int(cpld_number) + 1): component_list.append(cls(cpld_idx)) diff --git a/platform/mellanox/mlnx-ssd-fw-update.sh b/platform/mellanox/mlnx-ssd-fw-update.sh index 5163c8e7f8f7..4a2204adacf8 100755 --- a/platform/mellanox/mlnx-ssd-fw-update.sh +++ b/platform/mellanox/mlnx-ssd-fw-update.sh @@ -35,7 +35,7 @@ #= Global variable # #= #===== -VERSION="1.3" +VERSION="1.5" #===== SWITCH_SSD_DEV="/dev/sda" UTIL_TITLE="This is MLNX SSD firmware update utility to read and write SSD FW. Version ${VERSION}" @@ -79,6 +79,8 @@ function init_script() { else LOGGER_UTIL=$FALSE fi + export LC_ALL= + export LANG="en_US.UTF-8" } #==============================================================================# @@ -415,7 +417,7 @@ function check_package_signing() { LOG_MSG "checksum_signed_file: ${checksum_signed_file}" ${DEBUG_MSG} LOG_MSG "checksum_unsigned_file: ${checksum_unsigned_file}" ${DEBUG_MSG} - gpg --keyring "$public_cert_file" --verify "$checksum_signed_file" "$checksum_unsigned_file" > /dev/null 2>&1 + gpg --ignore-time-conflict --keyring "$public_cert_file" --verify "$checksum_signed_file" "$checksum_unsigned_file" > /dev/null 2>&1 [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: fault package signing." LOG_MSG "cd into: ${package_path}" ${DEBUG_MSG} @@ -559,7 +561,7 @@ function print_ssd_info() { LOG_MSG "Device Model\t : $SSD_DEVICE_MODEL" LOG_MSG "Serial Number\t : $SSD_SERIAL" LOG_MSG "User Capacity\t : $SSD_SIZE GB" - LOG_MSG "Firmware Version : $SSD_FW_VER" + LOG_MSG "Firmware Version : $SSD_FW_VER" fi } @@ -695,7 +697,7 @@ elif [ $ARG_UPDATE_FLAG == $TRUE ]; then else LOG_MSG "SSD FW update completed successfully." - if [ $ARG_POWER_CYCLE_FLAG == $TRUE ]; then + if [[ "yes" == "$power_policy" || $ARG_POWER_CYCLE_FLAG == $TRUE ]]; then LOG_MSG "Execute power cycle..." sleep 1 sync @@ -715,7 +717,7 @@ elif [ $ARG_UPDATE_FLAG == $TRUE ]; then fi done if [ $UPDATE_DONE == $FALSE ]; then - LOG_MSG "SSD FW upgrade not require, based on given package latest version is in used." + LOG_MSG "SSD FW upgrade is not required, latest version based on given package is in use." print_ssd_info "no" fi From 734b1c69693c89f2ca700244bc1295350da4d356 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Mon, 15 Jun 2020 15:08:22 -0700 Subject: [PATCH 0794/1427] Submodule update - sonic-restapi (#4749) --- src/sonic-restapi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-restapi b/src/sonic-restapi index 2094f5505644..ed640ac1f917 160000 --- a/src/sonic-restapi +++ b/src/sonic-restapi @@ -1 +1 @@ -Subproject commit 2094f5505644dc42085f593483719f94ba0bcd76 +Subproject commit ed640ac1f917f52c2298c0b799fb6a6cfbecccb4 From 0029d366c4aa59b76f90b4bfa13c4422bb8d102c Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Tue, 16 Jun 2020 15:39:27 +0300 Subject: [PATCH 0795/1427] Fix MSN4700 sensors (#4753) Signed-off-by: Shlomi Bitton --- device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf index 067287f3bbef..39fa9a5f93d3 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf @@ -142,14 +142,14 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-61" label in1 "PMIC-9 PSU 12V Rail (in1)" label in2 "PMIC-9 PSU 12V Rail (in2)" - label in3 "PMIC-9 COMEX 1.8V Rail (out)" - label in4 "PMIC-9 COMEX 1.05V Rail (out)" + label in3 "PMIC-9 COMEX 1.2V Rail (out)" + ignore in4 label temp1 "PMIC-9 Temp 1" label temp2 "PMIC-9 Temp 2" - label power1 "PMIC-9 COMEX 1.8V Rail Pwr (out)" - label power2 "PMIC-9 COMEX 1.05V Rail Pwr (out)" - label curr1 "PMIC-9 COMEX 1.8V Rail Curr (out)" - label curr2 "PMIC-9 COMEX 1.05V Rail Curr (out)" + label power1 "PMIC-9 COMEX 1.2V Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-9 COMEX 1.2V Rail Curr (out)" + ignore curr2 # Power supplies bus "i2c-4" "i2c-1-mux (chan_id 3)" From 80298fae1f2aa6443b4a5cf2a77215f015fe789d Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Tue, 16 Jun 2020 06:45:45 -0700 Subject: [PATCH 0796/1427] [bgp]:Add redistribution connected for ipv6 also for Frontend ASICs (#4767) * fix redistribution connected for ipv6 also Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index 503c37e9be14..051cfa4e9dd9 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -63,7 +63,12 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} ! ! {% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %} - redistribute connected route-map HIDE_INTERNAL + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family {% endif %} ! {% if constants.bgp.maximum_paths.enabled is defined and constants.bgp.maximum_paths.enabled %} From 1e7e6b952120f6291544a5468f012f959b068567 Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Tue, 16 Jun 2020 20:28:10 +0300 Subject: [PATCH 0797/1427] [Mellanox] Update SDK 4.4.0940 and FW xx.2007.1244 (#4776) --- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 22354d530660..115d3e5f4726 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2007.1208 +MLNX_SPC_FW_VERSION = 13.2007.1244 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2007.1208 +MLNX_SPC2_FW_VERSION = 29.2007.1244 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2007.1208 +MLNX_SPC3_FW_VERSION = 30.2007.1244 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 0a7d3be15378..bf5651d92c21 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 0a7d3be153787c1b18e4b51fff3354cc5c91d4bb +Subproject commit bf5651d92c21e62837aea2970488a01b0ff94768 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index ea6742269e93..28700ff40b71 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.4.0928 +MLNX_SDK_VERSION = 4.4.0940 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 91a1f131a178a879bb9e7c3bc7905cd897924f3e Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 16 Jun 2020 21:01:41 +0300 Subject: [PATCH 0798/1427] [Mellanox] Update hw-mgmt package to V.7.0010.1000 for master (#4687) * [Mellanox] Update hw-mgmt package to V.7.0010.1000 * update sonic-linux-kernel pointer to pick up new patch --- platform/mellanox/hw-management.mk | 2 +- platform/mellanox/hw-management/hw-mgmt | 2 +- src/sonic-linux-kernel | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index 3fa1667fec18..eb90cf16d4f2 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0000.3034 +MLNX_HW_MANAGEMENT_VERSION = 7.0010.1000 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 39f66b8e1997..cdacf1e932f9 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 39f66b8e1997868bbec297d7ae38f4e4ccc9009d +Subproject commit cdacf1e932f929c8dedde6c7e14759a2083aac66 diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 57f0a4e05396..1573762bfa36 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 57f0a4e053960db216232b6f3b15c0f5b41b88c2 +Subproject commit 1573762bfa36e32867e911a730aa7ce18b762eb0 From 364511aa3631e1bfde8fda36ab3150f8c31d1989 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Tue, 16 Jun 2020 11:32:25 -0700 Subject: [PATCH 0799/1427] [mgmt docker] Clean up docker-sonic-mgmt dockerfile (#4759) - Alphabetize dependencies to prevent duplicates - Remove unneccesary git clone Signed-off-by: Danny Allen --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 93 +++++++++++-------------- 1 file changed, 40 insertions(+), 53 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index c30fa3d33559..acb4417636ec 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -2,79 +2,68 @@ FROM ubuntu:16.04 ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update -RUN apt-get install -y \ - openssh-server \ - gcc \ - vim \ - make \ - git \ - sudo \ - python \ - python-dev \ - python-cffi \ - libffi-dev \ - libssl-dev \ - sshpass \ - libxml2 \ - libxslt1-dev \ - python-setuptools \ - build-essential \ - curl \ - cmake \ - tcpdump \ - snmp \ - python-scapy \ - inetutils-ping \ - telnet - -# For JNLP launcher -RUN apt-get install -y default-jre - -# For syslog test -RUN apt-get install -y rsyslog psmisc - -# Remove cffi 1.5.2, will install 1.10.0 by pip later -RUN apt-get purge -y python-cffi python-cffi-backend -# Remove pycparser 2.14, will install >=2.17 by pip later -RUN apt-get purge -y python-ply python-pycparser +RUN apt-get update && apt-get install -y build-essential \ + cmake \ + curl \ + default-jre \ + gcc \ + git \ + inetutils-ping \ + libffi-dev \ + libssl-dev \ + libxml2 \ + libxslt1-dev \ + make \ + openssh-server \ + psmisc \ + python \ + python-dev \ + python-scapy \ + python-setuptools \ + rsyslog \ + snmp \ + sshpass \ + sudo \ + tcpdump \ + telnet \ + vim RUN easy_install pip==20.1.1 -RUN pip install ipaddr \ - lxml \ - netaddr \ - natsort \ - six \ - pexpect \ - pyasn1==0.1.9 \ - pysnmp==4.2.5 \ - jinja2==2.7.2 \ - cffi==1.10.0 \ - paramiko==2.7.1 \ - passlib \ - ipython==5.4.1 \ - virtualenv \ +RUN pip install cffi==1.10.0 \ "cryptography>=2.5" \ "future>=0.16.0" \ gitpython \ + ipaddr \ + ipython==5.4.1 \ + ixnetwork-restpy==1.0.52 \ + jinja2==2.7.2 \ jsonpatch \ + lxml \ + natsort \ + netaddr \ netmiko==2.4.2 \ + paramiko==2.7.1 \ + passlib \ + pexpect \ prettytable \ psutil \ + pyasn1==0.1.9 \ pycryptodome \ pyfiglet \ pylint==1.8.1 \ pyro4 \ + pysnmp==4.2.5 \ pytest-repeat \ pytest-xdist==1.28.0 \ pytest==4.6.5 \ redis \ requests \ rpyc \ + six \ tabulate \ textfsm \ - ixnetwork-restpy==1.0.52 \ + virtualenv \ && git clone https://github.com/p4lang/scapy-vxlan.git \ && cd scapy-vxlan \ && python setup.py install \ @@ -179,5 +168,3 @@ RUN ~/lib/azure-cli/bin/python -m pip install azure-keyvault==0.3.7 -U # Install Virtual Environment RUN python -m virtualenv --system-site-packages env-201811 RUN env-201811/bin/pip install ansible==2.0.0.2 - -RUN git clone https://github.com/Azure/sonic-mgmt From 30d7ce00042964e2b1ff0df91fc75b801d49b665 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 17 Jun 2020 09:16:58 -0700 Subject: [PATCH 0800/1427] [build] Ensure /usr/lib/systemd/system/ directory exists before referencing (#4788) * Fix the Build on 201911 (Stretch) where the directory /usr/lib/systemd/system/ does not exist so creating manually. Change should not harm Master (buster) where the directory is created by Linux * Fix as per review comments --- files/build_templates/sonic_debian_extension.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 2afc17024337..f1d6cc924a8c 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -77,6 +77,9 @@ sudo mkdir -p $FILESYSTEM_ROOT/etc/sonic/ sudo mkdir -p $FILESYSTEM_ROOT/etc/modprobe.d/ sudo mkdir -p $FILESYSTEM_ROOT/var/cache/sonic/ sudo mkdir -p $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +# This is needed for Stretch and might not be needed for Buster where Linux create this directory by default. +# Keeping it generic. It should not harm anyways. +sudo mkdir -p $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM # Install a more recent version of ifupdown2 (and its dependencies via 'apt-get -y install -f') sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/ifupdown2_*.deb || \ From 6014773ac9931738df3171b348c3ed4a1082c066 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 17 Jun 2020 20:03:07 +0300 Subject: [PATCH 0801/1427] [Mellanox] Update MFT to v4.14.5-2. (#4784) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/mft.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index 605944cd5074..0adfec10c3f6 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -1,7 +1,7 @@ # Mellanox SAI -MFT_VERSION = 4.14.1 -MFT_REVISION = 8 +MFT_VERSION = 4.14.5 +MFT_REVISION = 2 export MFT_VERSION MFT_REVISION From edf3160224eaba2991b0244c24d3e2d62573bd44 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 17 Jun 2020 12:12:07 -0700 Subject: [PATCH 0802/1427] Fix bug: check port alias even when port_config_file parameter is not provided (#4787) --- src/sonic-config-engine/minigraph.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index b560df3332cd..c6b29cc9ecc0 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -966,10 +966,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): for port_name, port in ports.items(): # get port alias from port_config.ini - if port_config_file: - alias = port.get('alias') - else: - alias = port_name + alias = port.get('alias', port_name) # generate default 100G FEC # Note: FECDisabled only be effective on 100G port right now if port.get('speed') == '100000' and linkmetas.get(alias, {}).get('FECDisabled', '').lower() != 'true': From 6960477cc24541907c9b5270057478b2ac503e9d Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 18 Jun 2020 00:18:20 -0700 Subject: [PATCH 0803/1427] [caclmgrd] Don't limit connection tracking to TCP (#4796) Don't limit iptables connection tracking to TCP protocol; allow connection tracking for all protocols. This allows services like NTP, which is UDP-based, to receive replies from an NTP server even if the port is blocked, as long as it is in reply to a request sent from the device itself. --- files/image_config/caclmgrd/caclmgrd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index ce60ebc9d40b..37a86418967e 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -258,9 +258,9 @@ class ControlPlaneAclManager(object): iptables_cmds.append("ip6tables -A INPUT -s ::1 -i lo -j ACCEPT") # Add iptables/ip6tables commands to allow all incoming packets from established - # TCP sessions or new TCP sessions which are related to established TCP sessions - iptables_cmds.append("iptables -A INPUT -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") - iptables_cmds.append("ip6tables -A INPUT -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") + # connections or new connections which are related to established connections + iptables_cmds.append("iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") # Add iptables/ip6tables commands to allow bidirectional ICMPv4 ping and traceroute # TODO: Support processing ICMPv4 service ACL rules, and remove this blanket acceptance From f2af8aa8a962f0c0aa02ec9b7600cf0752452e38 Mon Sep 17 00:00:00 2001 From: kuanyu99 Date: Fri, 19 Jun 2020 01:52:06 +0800 Subject: [PATCH 0804/1427] [accton/as5835-54x] Fix sfp related function like tx_disable (#4763) **- Why I did it** The tx_disable function isn't work for the accton_ax5835-54x device. **- How I did it** Fix the incorrect path of the sfp node path inside the util file. **- How to verify it** Test with "sudo accton_as5835_54x_util.py show" "sudo accton_as5835_54x_util.py set sfp" There should see correct value for module_present and module_tx_disable. And should able to set it. Signed-off-by: kuanyu_chen --- .../as5835-54x/utils/accton_as5835_54x_util.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py index fbe3866ad566..b712b8c940ac 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py @@ -213,6 +213,10 @@ def driver_uninstall(): qsfp_start = 48 +#For sideband signals of SFP/QSFP modules. +cpld_of_module = {'3-0061': list(range(0,38)), + '3-0062': list(range(38,54)) } + mknod =[ 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-1/new_device', 'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-2/new_device' , @@ -427,10 +431,12 @@ def devices_info(): ALL_DEVICE[key][node].append(path) elif 'sfp' == key: for k in range(0,DEVICE_NO[key]): - node = key+str(k+1) - path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] - my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) + for lk in cpld_of_module: + if k in cpld_of_module[lk]: + node = key+str(k+1) + path = i2c_prefix + lk + "/"+ nodes[j] + str(k+1) + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) else: node = key+str(i+1) path = i2c_prefix+ buses[i]+"/"+ nodes[j] From 7c2f5a05440e53b21938eb50820ee15cc74b6187 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 18 Jun 2020 11:29:44 -0700 Subject: [PATCH 0805/1427] Update .gitignore for platform (#4803) --- .gitignore | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.gitignore b/.gitignore index 9c32299fdd61..948a266ba451 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,16 @@ src/**/debian/stamp-autotools-files # .o files src/**/*.o + +# platform +platform/**/*.egg-info +platform/**/*-none-any.whl +platform/**/.pybuild +platform/**/debian/* +platform/**/build +platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/ipmihelper.py +platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_ich.c +platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_lpc.c +platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_ich.c +platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_mailbox.c +platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/ipmihelper.py From 7f9523887da4b17ed3a8046782a8f8ba8ada7621 Mon Sep 17 00:00:00 2001 From: Sangita Maity Date: Thu, 18 Jun 2020 16:26:09 -0700 Subject: [PATCH 0806/1427] [buildImage] Add support of platform.json parsing to portconfig.py file (#3909) **- What I did** Add support of **platform.json** parsing to **portconfig.py** file which is being used by **_sonic-cfggen_** and ***minigraph.py*** file under ***src/sonic-config-engine*** folder to get port config via get_port_config function. **- How I did it** 1. **portconfig.py** file will first check whether the **platform.json** file is there or not. if not then whether port_config.ini file is there or not. Modified **get_port_config_file_name** for this purpose. 2. Added two separate functions i.e. **parse_platform_json_file** to get port attributes from **platform.json** and **gen_port_config** to generate port attributes. 3. Added another two functions i.e get_breakout_mode parse_breakout_mode to get breakout mode and parse breakout mode from platform.json respectively. **- How to verify it** rebuilt "sonic_config_engine-1.0" wheel package with all the test cases.All the below-mentioned test cases passed. ``` # Check whether all interfaces present or not as per platform.json def test_platform_json_interfaces_keys(self): # Check specific Interface with it's proper configuration as per platform.json def test_platform_json_specific_ethernet_interfaces(self): # Check all Interface with it's proper configuration as per platform.json def test_platform_json_all_ethernet_interfaces(self): ``` Signed-off-by: Sangita Maity --- src/sonic-config-engine/minigraph.py | 5 +- src/sonic-config-engine/portconfig.py | 271 +++++- src/sonic-config-engine/sonic-cfggen | 13 +- .../tests/sample_hwsku.json | 100 +++ .../tests/sample_output/platform_output.json | 819 ++++++++++++++++++ .../tests/sample_platform.json | 196 +++++ .../tests/test_cfggen_platformJson.py | 76 ++ .../sonic_daemon_base/daemon_base.py | 11 +- 8 files changed, 1470 insertions(+), 21 deletions(-) create mode 100644 src/sonic-config-engine/tests/sample_hwsku.json create mode 100644 src/sonic-config-engine/tests/sample_output/platform_output.json create mode 100644 src/sonic-config-engine/tests/sample_platform.json create mode 100644 src/sonic-config-engine/tests/test_cfggen_platformJson.py diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index c6b29cc9ecc0..64ce96182529 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -772,7 +772,7 @@ def enable_internal_bgp_session(bgp_sessions, filename, asic_name): # Main functions # ############################################################################### -def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): +def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hwsku_config_file=None): """ Parse minigraph xml file. Keyword arguments: @@ -782,6 +782,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): asic_name -- asic name; to parse multi-asic device minigraph to generate asic specific configuration. """ + root = ET.parse(filename).getroot() u_neighbors = None @@ -836,7 +837,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): if child.tag == str(docker_routing_config_mode_qn): docker_routing_config_mode = child.text - (ports, alias_map, alias_asic_map) = get_port_config(hwsku=hwsku, platform=platform, port_config_file=port_config_file, asic=asic_id) + (ports, alias_map, alias_asic_map) = get_port_config(hwsku=hwsku, platform=platform, port_config_file=port_config_file, asic=asic_id, hwsku_config_file=hwsku_config_file) port_alias_map.update(alias_map) port_alias_asic_map.update(alias_asic_map) diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py index 87e13687ed55..9b2d798aef57 100644 --- a/src/sonic-config-engine/portconfig.py +++ b/src/sonic-config-engine/portconfig.py @@ -1,33 +1,144 @@ #!/usr/bin/env python -import os -import sys +try: + import os + import sys + import json + import ast + import re + from collections import OrderedDict + from swsssdk import ConfigDBConnector +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) +# Global Variable +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +PLATFORM_ROOT_PATH_DOCKER = '/usr/share/sonic/platform' +SONIC_ROOT_PATH = '/usr/share/sonic' +HWSKU_ROOT_PATH = '/usr/share/sonic/hwsku' + +PLATFORM_JSON = 'platform.json' +PORT_CONFIG_INI = 'port_config.ini' +HWSKU_JSON = 'hwsku.json' + +PORT_STR = "Ethernet" +BRKOUT_MODE = "default_brkout_mode" +CUR_BRKOUT_MODE = "brkout_mode" +INTF_KEY = "interfaces" + +BRKOUT_PATTERN = r'(\d{1,3})x(\d{1,3}G)(\[\d{1,3}G\])?(\((\d{1,3})\))?' + + +# +# Helper Functions +# +def readJson(filename): + # Read 'platform.json' or 'hwsku.json' file + try: + with open(filename) as fp: + try: + data = json.load(fp) + except json.JSONDecodeError: + print("Json file does not exist") + data_dict = ast.literal_eval(json.dumps(data)) + return data_dict + except Exception as e: + print("error occurred while parsing json:", sys.exc_info()[1]) + return None + +def db_connect_configdb(): + """ + Connect to configdb + """ + config_db = ConfigDBConnector() + if config_db is None: + return None + try: + """ + This could be blocking during the config load_minigraph phase, + as the CONFIG_DB_INITIALIZED is not yet set in the configDB. + We can ignore the check by using config_db.db_connect('CONFIG_DB') instead + """ + # Connect only if available & initialized + config_db.connect(wait_for_init=False) + except Exception as e: + config_db = None + return config_db def get_port_config_file_name(hwsku=None, platform=None, asic=None): + + # check 'platform.json' file presence + port_config_candidates_Json = [] + port_config_candidates_Json.append(os.path.join(PLATFORM_ROOT_PATH_DOCKER, PLATFORM_JSON)) + if platform: + port_config_candidates_Json.append(os.path.join(PLATFORM_ROOT_PATH, platform, PLATFORM_JSON)) + + # check 'portconfig.ini' file presence port_config_candidates = [] - port_config_candidates.append('/usr/share/sonic/hwsku/port_config.ini') + port_config_candidates.append(os.path.join(HWSKU_ROOT_PATH, PORT_CONFIG_INI)) if hwsku: if platform: if asic: - port_config_candidates.append(os.path.join('/usr/share/sonic/device', platform, hwsku, asic,'port_config.ini')) - port_config_candidates.append(os.path.join('/usr/share/sonic/device', platform, hwsku, 'port_config.ini')) - port_config_candidates.append(os.path.join('/usr/share/sonic/platform', hwsku, 'port_config.ini')) - port_config_candidates.append(os.path.join('/usr/share/sonic', hwsku, 'port_config.ini')) - for candidate in port_config_candidates: + port_config_candidates.append(os.path.join(PLATFORM_ROOT_PATH, platform, hwsku, asic, PORT_CONFIG_INI)) + port_config_candidates.append(os.path.join(PLATFORM_ROOT_PATH, platform, hwsku, PORT_CONFIG_INI)) + port_config_candidates.append(os.path.join(PLATFORM_ROOT_PATH_DOCKER, hwsku, PORT_CONFIG_INI)) + port_config_candidates.append(os.path.join(SONIC_ROOT_PATH, hwsku, PORT_CONFIG_INI)) + + elif platform and not hwsku: + port_config_candidates.append(os.path.join(PLATFORM_ROOT_PATH, platform, PORT_CONFIG_INI)) + + for candidate in port_config_candidates_Json + port_config_candidates: + if os.path.isfile(candidate): + return candidate + return None + +def get_hwsku_file_name(hwsku=None, platform=None): + hwsku_candidates_Json = [] + hwsku_candidates_Json.append(os.path.join(HWSKU_ROOT_PATH, HWSKU_JSON)) + if hwsku: + if platform: + hwsku_candidates_Json.append(os.path.join(PLATFORM_ROOT_PATH, platform, hwsku, HWSKU_JSON)) + hwsku_candidates_Json.append(os.path.join(PLATFORM_ROOT_PATH_DOCKER, hwsku, HWSKU_JSON)) + hwsku_candidates_Json.append(os.path.join(SONIC_ROOT_PATH, hwsku, HWSKU_JSON)) + for candidate in hwsku_candidates_Json: if os.path.isfile(candidate): return candidate return None - +def get_port_config(hwsku=None, platform=None, port_config_file=None, hwsku_config_file=None, asic=None): + config_db = db_connect_configdb() + # If available, Read from CONFIG DB first + if config_db is not None and port_config_file is None: + + port_data = config_db.get_table("PORT") + if bool(port_data): + ports = ast.literal_eval(json.dumps(port_data)) + port_alias_map = {} + port_alias_asic_map = {} + for intf_name in ports.keys(): + port_alias_map[ports[intf_name]["alias"]] = intf_name + return (ports, port_alias_map, port_alias_asic_map) -def get_port_config(hwsku=None, platform=None, port_config_file=None, asic=None): if not port_config_file: port_config_file = get_port_config_file_name(hwsku, platform, asic) if not port_config_file: return ({}, {}, {}) - return parse_port_config_file(port_config_file) + # Read from 'platform.json' file + if port_config_file.endswith('.json'): + if not hwsku_config_file: + hwsku_json_file = get_hwsku_file_name(hwsku, platform) + if not hwsku_json_file: + return ({}, {}, {}) + else: + hwsku_json_file = hwsku_config_file + + return parse_platform_json_file(hwsku_json_file, port_config_file) + + # If 'platform.json' file is not available, read from 'port_config.ini' + else: + return parse_port_config_file(port_config_file) + def parse_port_config_file(port_config_file): ports = {} port_alias_map = {} @@ -63,4 +174,142 @@ def parse_port_config_file(port_config_file): port_alias_asic_map[data['alias']] = data['asic_port_name'].strip() return (ports, port_alias_map, port_alias_asic_map) +# Generate configs (i.e. alias, lanes, speed, index) for port +def gen_port_config(ports, parent_intf_id, index, alias_at_lanes, lanes, k, offset): + if k is not None: + num_lane_used, speed, alt_speed, _ , assigned_lane = k[0], k[1], k[2], k[3], k[4] + + # In case of symmetric mode + if assigned_lane is None: + assigned_lane = len(lanes.split(",")) + + parent_intf_id = int(offset)+int(parent_intf_id) + alias_start = 0 + offset + + step = int(assigned_lane)//int(num_lane_used) + for i in range(0,int(assigned_lane), step): + intf_name = PORT_STR + str(parent_intf_id) + ports[intf_name] = {} + ports[intf_name]['alias'] = alias_at_lanes.split(",")[alias_start] + ports[intf_name]['lanes'] = ','.join(lanes.split(",")[alias_start:alias_start+step]) + if speed: + speed_pat = re.search("^((\d+)G|\d+)$", speed.upper()) + if speed_pat is None: + raise Exception('{} speed is not Supported...'.format(speed)) + speed_G, speed_orig = speed_pat.group(2), speed_pat.group(1) + if speed_G: + conv_speed = int(speed_G)*1000 + else: + conv_speed = int(speed_orig) + ports[intf_name]['speed'] = str(conv_speed) + else: + raise Exception('Regex return for speed is None...') + + ports[intf_name]['index'] = index.split(",")[alias_start] + ports[intf_name]['admin_status'] = "up" + + parent_intf_id += step + alias_start += step + + offset = int(assigned_lane) + int(offset) + return offset + else: + raise Exception('Regex return for k is None...') + +""" +Given a port and breakout mode, this method returns +the list of child ports using platform_json file +""" +def get_child_ports(interface, breakout_mode, platform_json_file): + child_ports = {} + + port_dict = readJson(platform_json_file) + + index = port_dict[INTF_KEY][interface]['index'] + alias_at_lanes = port_dict[INTF_KEY][interface]['alias_at_lanes'] + lanes = port_dict[INTF_KEY][interface]['lanes'] + + """ + Example of match_list for some breakout_mode using regex + Breakout Mode -------> Match_list + ----------------------------- + 2x25G(2)+1x50G(2) ---> [('2', '25G', None, '(2)', '2'), ('1', '50G', None, '(2)', '2')] + 1x50G(2)+2x25G(2) ---> [('1', '50G', None, '(2)', '2'), ('2', '25G', None, '(2)', '2')] + 1x100G[40G] ---------> [('1', '100G', '[40G]', None, None)] + 2x50G ---------------> [('2', '50G', None, None, None)] + """ + # Asymmetric breakout mode + if re.search("\+",breakout_mode) is not None: + breakout_parts = breakout_mode.split("+") + match_list = [re.match(BRKOUT_PATTERN, i).groups() for i in breakout_parts] + + # Symmetric breakout mode + else: + match_list = [re.match(BRKOUT_PATTERN, breakout_mode).groups()] + + offset = 0 + parent_intf_id = int(re.search("Ethernet(\d+)", interface).group(1)) + for k in match_list: + offset = gen_port_config(child_ports, parent_intf_id, index, alias_at_lanes, lanes, k, offset) + return child_ports + +def parse_platform_json_file(hwsku_json_file, platform_json_file): + ports = {} + port_alias_map = {} + port_alias_asic_map = {} + + port_dict = readJson(platform_json_file) + hwsku_dict = readJson(hwsku_json_file) + + if not port_dict: + raise Exception("port_dict is none") + if not hwsku_dict: + raise Exception("hwsku_dict is none") + + if INTF_KEY not in port_dict or INTF_KEY not in hwsku_dict: + raise Exception("INTF_KEY is not present in appropriate file") + + for intf in port_dict[INTF_KEY]: + if intf not in hwsku_dict[INTF_KEY]: + raise Exception("{} is not available in hwsku_dict".format(intf)) + + # take default_brkout_mode from hwsku.json + brkout_mode = hwsku_dict[INTF_KEY][intf][BRKOUT_MODE] + + child_ports = get_child_ports(intf, brkout_mode, platform_json_file) + ports.update(child_ports) + + if not ports: + raise Exception("Ports dictionary is empty") + + for i in ports.keys(): + port_alias_map[ports[i]["alias"]]= i + return (ports, port_alias_map, port_alias_asic_map) + + +def get_breakout_mode(hwsku=None, platform=None, port_config_file=None): + if not port_config_file: + port_config_file = get_port_config_file_name(hwsku, platform) + if not port_config_file: + return None + if port_config_file.endswith('.json'): + hwsku_json_file = get_hwsku_file_name(hwsku, platform) + if not hwsku_json_file: + raise Exception("'hwsku_json' file does not exist!!! This file is necessary to proceed forward.") + + return parse_breakout_mode(hwsku_json_file) + else: + return None + +def parse_breakout_mode(hwsku_json_file): + brkout_table = {} + hwsku_dict = readJson(hwsku_json_file) + if not hwsku_dict: + raise Exception("hwsku_dict is empty") + if INTF_KEY not in hwsku_dict: + raise Exception("INTF_KEY is not present in hwsku_dict") + for intf in hwsku_dict[INTF_KEY]: + brkout_table[intf] = {} + brkout_table[intf][CUR_BRKOUT_MODE] = hwsku_dict[INTF_KEY][intf][BRKOUT_MODE] + return brkout_table diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index c247d85abec3..c0f61d8a95f9 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -38,7 +38,7 @@ from minigraph import minigraph_encoder from minigraph import parse_xml from minigraph import parse_device_desc_xml from minigraph import parse_asic_sub_role -from portconfig import get_port_config +from portconfig import get_port_config, get_port_config_file_name, get_breakout_mode from sonic_device_util import get_machine_info from sonic_device_util import get_platform_info from sonic_device_util import get_system_mac @@ -199,6 +199,7 @@ def main(): group.add_argument("-k", "--hwsku", help="HwSKU") parser.add_argument("-n", "--namespace", help="namespace name", nargs='?', const=None, default=None) parser.add_argument("-p", "--port-config", help="port config file, used with -m or -k", nargs='?', const=None) + parser.add_argument("-S", "--hwsku-config", help="hwsku config file, used with -p and -m or -k", nargs='?', const=None) parser.add_argument("-y", "--yaml", help="yaml file that contains additional variables", action='append', default=[]) parser.add_argument("-j", "--json", help="json file that contains additional variables", action='append', default=[]) parser.add_argument("-a", "--additional-data", help="addition data, in json string") @@ -240,12 +241,18 @@ def main(): 'hwsku': hwsku }}} deep_update(data, hardware_data) + if args.port_config is None: + args.port_config = get_port_config_file_name(hwsku, platform) (ports, _, _) = get_port_config(hwsku, platform, args.port_config, asic_id) if not ports: print('Failed to get port config', file=sys.stderr) sys.exit(1) deep_update(data, {'PORT': ports}) + brkout_table = get_breakout_mode(hwsku, platform, args.port_config) + if brkout_table is not None: + deep_update(data, {'BREAKOUT_CFG': brkout_table}) + for json_file in args.json: with open(json_file, 'r') as stream: deep_update(data, FormatConverter.to_deserialized(json.load(stream))) @@ -254,11 +261,11 @@ def main(): minigraph = args.minigraph if platform: if args.port_config != None: - deep_update(data, parse_xml(minigraph, platform, args.port_config, asic_name=asic_name)) + deep_update(data, parse_xml(minigraph, platform, args.port_config, asic_name=asic_name, hwsku_config_file=args.hwsku_config)) else: deep_update(data, parse_xml(minigraph, platform, asic_name=asic_name)) else: - deep_update(data, parse_xml(minigraph, port_config_file=args.port_config, asic_name=asic_name)) + deep_update(data, parse_xml(minigraph, port_config_file=args.port_config, asic_name=asic_name, hwsku_config_file=args.hwsku_config)) if args.device_description != None: deep_update(data, parse_device_desc_xml(args.device_description)) diff --git a/src/sonic-config-engine/tests/sample_hwsku.json b/src/sonic-config-engine/tests/sample_hwsku.json new file mode 100644 index 000000000000..5b450932c238 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet4": { + "default_brkout_mode": "2x50G" + }, + "Ethernet8": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet12": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet16": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet24": { + "default_brkout_mode": "2x50G" + }, + "Ethernet28": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet32": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet36": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet44": { + "default_brkout_mode": "2x50G" + }, + "Ethernet48": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet52": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet56": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet64": { + "default_brkout_mode": "2x50G" + }, + "Ethernet68": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet72": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet76": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet84": { + "default_brkout_mode": "2x50G" + }, + "Ethernet88": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet92": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet96": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G" + }, + "Ethernet108": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet112": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet116": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet124": { + "default_brkout_mode": "2x50G" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/platform_output.json b/src/sonic-config-engine/tests/sample_output/platform_output.json new file mode 100644 index 000000000000..f4e031fbe536 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/platform_output.json @@ -0,0 +1,819 @@ +{ + "Ethernet8": { + "index": "3", + "lanes": "8", + "description": "Eth3/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth3/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet9": { + "index": "3", + "lanes": "9", + "description": " Eth3/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth3/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet36": { + "index": "10", + "lanes": "36,37", + "description": "Eth10/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth10/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet98": { + "index": "25", + "lanes": "98", + "description": " Eth25/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth25/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet0": { + "index": "1", + "lanes": "0,1,2,3", + "fec": "rs", + "description": "Eth1/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth1/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet6": { + "index": "2", + "lanes": "6,7", + "description": " Eth2/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth2/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet4": { + "index": "2", + "lanes": "4,5", + "description": "Eth2/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth2/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet109": { + "index": "28", + "lanes": "109", + "description": " Eth28/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth28/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet108": { + "index": "28", + "lanes": "108", + "description": "Eth28/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth28/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet18": { + "index": "5", + "lanes": "18", + "description": " Eth5/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth5/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet100": { + "index": "26", + "lanes": "100,101,102,103", + "fec": "rs", + "description": "Eth26/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth26/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet34": { + "index": "9", + "lanes": "34,35", + "description": " Eth9/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth9/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet104": { + "index": "27", + "lanes": "104,105", + "description": "Eth27/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth27/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet106": { + "index": "27", + "lanes": "106,107", + "description": " Eth27/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth27/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet94": { + "index": "24", + "lanes": "94,95", + "description": " Eth24/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth24/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet126": { + "index": "32", + "lanes": "126,127", + "description": " Eth32/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth32/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet96": { + "index": "25", + "lanes": "96,97", + "description": "Eth25/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth25/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet124": { + "index": "32", + "lanes": "124,125", + "description": "Eth32/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth32/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet90": { + "index": "23", + "lanes": "90", + "description": " Eth23/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth23/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet91": { + "index": "23", + "lanes": "91", + "description": " Eth23/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth23/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet92": { + "index": "24", + "lanes": "92", + "description": "Eth24/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth24/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet93": { + "index": "24", + "lanes": "93", + "description": " Eth24/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth24/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet50": { + "index": "13", + "lanes": "50", + "description": " Eth13/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth13/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet51": { + "index": "13", + "lanes": "51", + "description": " Eth13/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth13/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet52": { + "index": "14", + "lanes": "52", + "description": "Eth14/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth14/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet53": { + "index": "14", + "lanes": "53", + "description": " Eth14/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth14/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet54": { + "index": "14", + "lanes": "54,55", + "description": " Eth14/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth14/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet99": { + "index": "25", + "lanes": "99", + "description": " Eth25/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth25/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet56": { + "index": "15", + "lanes": "56,57", + "description": "Eth15/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth15/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet113": { + "index": "29", + "lanes": "113", + "description": " Eth29/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth29/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet76": { + "index": "20", + "lanes": "76,77", + "description": "Eth20/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth20/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet74": { + "index": "19", + "lanes": "74,75", + "description": " Eth19/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth19/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet39": { + "index": "10", + "lanes": "39", + "description": " Eth10/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth10/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet72": { + "index": "19", + "lanes": "72", + "description": "Eth19/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth19/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet73": { + "index": "19", + "lanes": "73", + "description": " Eth19/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth19/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet70": { + "index": "18", + "lanes": "70", + "description": " Eth18/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth18/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet71": { + "index": "18", + "lanes": "71", + "description": " Eth18/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth18/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet32": { + "index": "9", + "lanes": "32", + "description": "Eth9/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth9/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet33": { + "index": "9", + "lanes": "33", + "description": " Eth9/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth9/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet16": { + "index": "5", + "lanes": "16,17", + "description": "Eth5/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth5/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet111": { + "index": "28", + "lanes": "111", + "description": " Eth28/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth28/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet10": { + "index": "3", + "lanes": "10", + "description": " Eth3/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth3/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet11": { + "index": "3", + "lanes": "11", + "description": " Eth3/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth3/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet12": { + "index": "4", + "lanes": "12", + "description": "Eth4/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth4/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet13": { + "index": "4", + "lanes": "13", + "description": " Eth4/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth4/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet58": { + "index": "15", + "lanes": "58", + "description": " Eth15/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth15/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet19": { + "index": "5", + "lanes": "19", + "description": " Eth5/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth5/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet59": { + "index": "15", + "lanes": "59", + "description": " Eth15/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth15/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet38": { + "index": "10", + "lanes": "38", + "description": " Eth10/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth10/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet78": { + "index": "20", + "lanes": "78", + "description": " Eth20/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth20/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet68": { + "index": "18", + "lanes": "68", + "description": "Eth18/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth18/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet14": { + "index": "4", + "lanes": "14,15", + "description": " Eth4/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth4/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet89": { + "index": "23", + "lanes": "89", + "description": " Eth23/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth23/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet88": { + "index": "23", + "lanes": "88", + "description": "Eth23/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth23/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet118": { + "index": "30", + "lanes": "118", + "description": " Eth30/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth30/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet119": { + "index": "30", + "lanes": "119", + "description": " Eth30/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth30/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet116": { + "index": "30", + "lanes": "116,117", + "description": "Eth30/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth30/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet114": { + "index": "29", + "lanes": "114,115", + "description": " Eth29/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth29/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet80": { + "index": "21", + "lanes": "80,81,82,83", + "fec": "rs", + "description": "Eth21/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth21/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet112": { + "index": "29", + "lanes": "112", + "description": "Eth29/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth29/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet86": { + "index": "22", + "lanes": "86,87", + "description": " Eth22/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth22/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet110": { + "index": "28", + "lanes": "110", + "description": " Eth28/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth28/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet84": { + "index": "22", + "lanes": "84,85", + "description": "Eth22/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth22/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet31": { + "index": "8", + "lanes": "31", + "description": " Eth8/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth8/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet49": { + "index": "13", + "lanes": "49", + "description": " Eth13/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth13/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet48": { + "index": "13", + "lanes": "48", + "description": "Eth13/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth13/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet46": { + "index": "12", + "lanes": "46,47", + "description": " Eth12/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth12/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet30": { + "index": "8", + "lanes": "30", + "description": " Eth8/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth8/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet29": { + "index": "8", + "lanes": "29", + "description": " Eth8/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth8/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet40": { + "index": "11", + "lanes": "40,41,42,43", + "fec": "rs", + "description": "Eth11/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth11/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet120": { + "index": "31", + "lanes": "120,121,122,123", + "fec": "rs", + "description": "Eth31/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth31/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet28": { + "index": "8", + "lanes": "28", + "description": "Eth8/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth8/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet66": { + "index": "17", + "lanes": "66,67", + "description": " Eth17/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth17/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet60": { + "index": "16", + "lanes": "60,61,62,63", + "fec": "rs", + "description": "Eth16/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth16/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet64": { + "index": "17", + "lanes": "64,65", + "description": "Eth17/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth17/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet44": { + "index": "12", + "lanes": "44,45", + "description": "Eth12/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth12/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet20": { + "index": "6", + "lanes": "20,21,22,23", + "fec": "rs", + "description": "Eth6/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth6/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet79": { + "index": "20", + "lanes": "79", + "description": " Eth20/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth20/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet69": { + "index": "18", + "lanes": "69", + "description": " Eth18/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth18/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet24": { + "index": "7", + "lanes": "24,25", + "description": "Eth7/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth7/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet26": { + "index": "7", + "lanes": "26,27", + "description": " Eth7/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth7/3", + "pfc_asym": "off", + "speed": "50000" + } +} diff --git a/src/sonic-config-engine/tests/sample_platform.json b/src/sonic-config-engine/tests/sample_platform.json new file mode 100644 index 000000000000..fd11a49ed0a0 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_platform.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "Eth1/1, Eth1/2, Eth1/3, Eth1/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "4,5,6,7", + "alias_at_lanes": "Eth2/1, Eth2/2, Eth2/3, Eth2/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "8,9,10,11", + "alias_at_lanes": "Eth3/1, Eth3/2, Eth3/3, Eth3/4", + "breakout_modes": "1x100G[40G],2x50G,2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "12,13,14,15", + "alias_at_lanes": "Eth4/1, Eth4/2, Eth4/3, Eth4/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "16,17,18,19", + "alias_at_lanes": "Eth5/1, Eth5/2, Eth5/3, Eth5/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "20,21,22,23", + "alias_at_lanes": "Eth6/1, Eth6/2, Eth6/3, Eth6/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "24,25,26,27", + "alias_at_lanes": "Eth7/1, Eth7/2, Eth7/3, Eth7/4", + "breakout_modes": "1x100G[40G],4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "28,29,30,31", + "alias_at_lanes": "Eth8/1, Eth8/2, Eth8/3, Eth8/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "32,33,34,35", + "alias_at_lanes": "Eth9/1, Eth9/2, Eth9/3, Eth9/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "36,37,38,39", + "alias_at_lanes": "Eth10/1, Eth10/2, Eth10/3, Eth10/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "40,41,42,43", + "alias_at_lanes": "Eth11/1, Eth11/2, Eth11/3, Eth11/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "44,45,46,47", + "alias_at_lanes": "Eth12/1, Eth12/2, Eth12/3, Eth12/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "48,49,50,51", + "alias_at_lanes": "Eth13/1, Eth13/2, Eth13/3, Eth13/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "52,53,54,55", + "alias_at_lanes": "Eth14/1, Eth14/2, Eth14/3, Eth14/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "56,57,58,59", + "alias_at_lanes": "Eth15/1, Eth15/2, Eth15/3, Eth15/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "60,61,62,63", + "alias_at_lanes": "Eth16/1, Eth16/2, Eth16/3, Eth16/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "64,65,66,67", + "alias_at_lanes": "Eth17/1, Eth17/2, Eth17/3, Eth17/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "68,69,70,71", + "alias_at_lanes": "Eth18/1, Eth18/2, Eth18/3, Eth18/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "72,73,74,75", + "alias_at_lanes": "Eth19/1, Eth19/2, Eth19/3, Eth19/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "76,77,78,79", + "alias_at_lanes": "Eth20/1, Eth20/2, Eth20/3, Eth20/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "80,81,82,83", + "alias_at_lanes": "Eth21/1, Eth21/2, Eth21/3, Eth21/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "84,85,86,87", + "alias_at_lanes": "Eth22/1, Eth22/2, Eth22/3, Eth22/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "88,89,90,91", + "alias_at_lanes": "Eth23/1, Eth23/2, Eth23/3, Eth23/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "92,93,94,95", + "alias_at_lanes": "Eth24/1, Eth24/2, Eth24/3, Eth24/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "96,97,98,99", + "alias_at_lanes": "Eth25/1, Eth25/2, Eth25/3, Eth25/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "100,101,102,103", + "alias_at_lanes": "Eth26/1, Eth26/2, Eth26/3, Eth26/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "104,105,106,107", + "alias_at_lanes": "Eth27/1, Eth27/2, Eth27/3, Eth27/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "108,109,110,111", + "alias_at_lanes": "Eth28/1, Eth28/2, Eth28/3, Eth28/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "112,113,114,115", + "alias_at_lanes": "Eth29/1, Eth29/2, Eth29/3, Eth29/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "116,117,118,119", + "alias_at_lanes": "Eth30/1, Eth30/2, Eth30/3, Eth30/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "120,121,122,123", + "alias_at_lanes": "Eth31/1, Eth31/2, Eth31/3, Eth31/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "124,125,126,127", + "alias_at_lanes": "Eth32/1, Eth32/2, Eth32/3, Eth32/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + } + } +} diff --git a/src/sonic-config-engine/tests/test_cfggen_platformJson.py b/src/sonic-config-engine/tests/test_cfggen_platformJson.py new file mode 100644 index 000000000000..f94fcb4ab89b --- /dev/null +++ b/src/sonic-config-engine/tests/test_cfggen_platformJson.py @@ -0,0 +1,76 @@ +from unittest import TestCase +import subprocess +import os +import json +import ast + +# Global Variable +PLATFORM_OUTPUT_FILE = "platform_output.json" + +class TestCfgGenPlatformJson(TestCase): + + def setUp(self): + self.test_dir = os.path.dirname(os.path.realpath(__file__)) + self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.sample_graph_simple = os.path.join(self.test_dir, 'simple-sample-graph.xml') + self.platform_json = os.path.join(self.test_dir, 'sample_platform.json') + self.hwsku_json = os.path.join(self.test_dir, 'sample_hwsku.json') + + def run_script(self, argument, check_stderr=False): + print '\n Running sonic-cfggen ' + argument + if check_stderr: + output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + linecount = output.strip().count('\n') + if linecount <= 0: + print ' Output: ' + output.strip() + else: + print ' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output)) + return output + + def test_dummy_run(self): + argument = '' + output = self.run_script(argument) + self.assertEqual(output, '') + + def test_print_data(self): + argument = '-m "' + self.sample_graph_simple + '" --print-data' + output = self.run_script(argument) + self.assertTrue(len(output.strip()) > 0) + + # Check whether all interfaces present or not as per platform.json + def test_platform_json_interfaces_keys(self): + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT.keys()"' + output = self.run_script(argument) + expected = "['Ethernet8', 'Ethernet9', 'Ethernet36', 'Ethernet98', 'Ethernet0', 'Ethernet6', 'Ethernet4', 'Ethernet109', 'Ethernet108', 'Ethernet18', 'Ethernet100', 'Ethernet34', 'Ethernet104', 'Ethernet106', 'Ethernet94', 'Ethernet126', 'Ethernet96', 'Ethernet124', 'Ethernet90', 'Ethernet91', 'Ethernet92', 'Ethernet93', 'Ethernet50', 'Ethernet51', 'Ethernet52', 'Ethernet53', 'Ethernet54', 'Ethernet99', 'Ethernet56', 'Ethernet113', 'Ethernet76', 'Ethernet74', 'Ethernet39', 'Ethernet72', 'Ethernet73', 'Ethernet70', 'Ethernet71', 'Ethernet32', 'Ethernet33', 'Ethernet16', 'Ethernet111', 'Ethernet10', 'Ethernet11', 'Ethernet12', 'Ethernet13', 'Ethernet58', 'Ethernet19', 'Ethernet59', 'Ethernet38', 'Ethernet78', 'Ethernet68', 'Ethernet14', 'Ethernet89', 'Ethernet88', 'Ethernet118', 'Ethernet119', 'Ethernet116', 'Ethernet114', 'Ethernet80', 'Ethernet112', 'Ethernet86', 'Ethernet110', 'Ethernet84', 'Ethernet31', 'Ethernet49', 'Ethernet48', 'Ethernet46', 'Ethernet30', 'Ethernet29', 'Ethernet40', 'Ethernet120', 'Ethernet28', 'Ethernet66', 'Ethernet60', 'Ethernet64', 'Ethernet44', 'Ethernet20', 'Ethernet79', 'Ethernet69', 'Ethernet24', 'Ethernet26']" + + self.assertEqual(sorted(output.strip()), sorted(expected)) + + # Check specific Interface with it's proper configuration as per platform.json + def test_platform_json_specific_ethernet_interfaces(self): + + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT[\'Ethernet8\']"' + output = self.run_script(argument) + expected = "{'index': '3', 'lanes': '8', 'description': 'Eth3/1', 'admin_status': 'up', 'mtu': '9100', 'alias': 'Eth3/1', 'pfc_asym': 'off', 'speed': '25000'}" + self.assertEqual(output.strip(), expected) + + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT[\'Ethernet112\']"' + output = self.run_script(argument) + expected = "{'index': '29', 'lanes': '112', 'description': 'Eth29/1', 'admin_status': 'up', 'mtu': '9100', 'alias': 'Eth29/1', 'pfc_asym': 'off', 'speed': '25000'}" + self.assertEqual(output.strip(), expected) + + # Check all Interface with it's proper configuration as per platform.json + def test_platform_json_all_ethernet_interfaces(self): + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT"' + output = self.run_script(argument) + + sample_file = os.path.join(self.test_dir, 'sample_output', PLATFORM_OUTPUT_FILE) + fh = open(sample_file, 'rb') + fh_data = json.load(fh) + fh.close() + + output_dict = ast.literal_eval(output.strip()) + expected = ast.literal_eval(json.dumps(fh_data)) + self.assertDictEqual(output_dict, expected) diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index c74f9bed15e7..0e579515365c 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -23,7 +23,7 @@ # Port config information PORT_CONFIG = 'port_config.ini' -PORTMAP = 'portmap.ini' +PLATFORM_JSON = 'platform.json' EEPROM_MODULE_NAME = 'eeprom' EEPROM_CLASS_NAME = 'board' @@ -146,11 +146,12 @@ def get_path_to_port_config_file(self): # Get platform and hwsku path (platform_path, hwsku_path) = self.get_path_to_platform_and_hwsku() - # First check for the presence of the new 'port_config.ini' file - port_config_file_path = "/".join([hwsku_path, PORT_CONFIG]) + # First check for the presence of the new 'platform.json' file + port_config_file_path = "/".join([platform_path, PLATFORM_JSON]) if not os.path.isfile(port_config_file_path): - # port_config.ini doesn't exist. Try loading the legacy 'portmap.ini' file - port_config_file_path = "/".join([hwsku_path, PORTMAP]) + + # platform.json doesn't exist. Try loading the legacy 'port_config.ini' file + port_config_file_path = "/".join([hwsku_path, PORT_CONFIG]) if not os.path.isfile(port_config_file_path): raise IOError("Failed to detect port config file: %s" % (port_config_file_path)) From 88c5d2233bc09cad5456bc4983a7f99ce5db3031 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Thu, 18 Jun 2020 23:16:00 -0700 Subject: [PATCH 0807/1427] kubeadm package apt-get install has unmet dependency error (#4804) to other packages so intsalling them explicitly. --- build_debian.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build_debian.sh b/build_debian.sh index 8d1db8ca37c1..2cae3eacef25 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -222,6 +222,14 @@ then ## Check out the sources list update matches current Debian version sudo cp files/image_config/kubernetes/kubernetes.list $FILESYSTEM_ROOT/etc/apt/sources.list.d/ sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update + if [[ $KUBERNETES_VERSION == 1.18.0 ]]; then + # kubeadm 1.18.0 package auto install has some dependency error so install + # those package explicitly. + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubernetes-cni=0.7.5-00 + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubelet=1.18.3-00 + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubectl=1.18.3-00 + fi + # else kubeadm package auto install kubelet & kubectl sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubeadm=${KUBERNETES_VERSION}-00 # kubeadm package auto install kubelet & kubectl else From 3dc7992a6e6a4bc908edb4e77866030217650b25 Mon Sep 17 00:00:00 2001 From: Sachin Holla <51310506+sachinholla@users.noreply.github.com> Date: Fri, 19 Jun 2020 13:16:03 +0530 Subject: [PATCH 0808/1427] [mgmt-framework]: REST server cert configurations (#4799) REST and telemetry servers were using "DEVICE_METADATA|x509" table for server certificate configurations. This table has been deprecated now. Enhanced REST server startup script to read server certificate file path configurations from REST_SERVER table. Three more attributes - server_crt, server_key and ca_crt are introduced as described in https://github.com/Azure/SONiC/pull/550. For backard compatibility, certificate configurations are read from old "DEVICE_METADATA|x509" table if they (server_crt, server_key and ca_crt) are not present in REST_SERVER table. Fixes bug https://github.com/Azure/sonic-buildimage/issues/4291 Signed-off-by: Sachin Holla --- .../docker-sonic-mgmt-framework/rest-server.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dockers/docker-sonic-mgmt-framework/rest-server.sh b/dockers/docker-sonic-mgmt-framework/rest-server.sh index e450f707dfd1..6e551d7c6143 100755 --- a/dockers/docker-sonic-mgmt-framework/rest-server.sh +++ b/dockers/docker-sonic-mgmt-framework/rest-server.sh @@ -2,23 +2,23 @@ # Startup script for SONiC Management REST Server -SERVER_PORT= -LOG_LEVEL= -CLIENT_AUTH= -SERVER_CRT= -SERVER_KEY= -CA_CERT= - # Read basic server settings from REST_SERVER|default entry HAS_REST_CONFIG=$(sonic-cfggen -d -v "1 if REST_SERVER and REST_SERVER['default']") if [ "$HAS_REST_CONFIG" == "1" ]; then SERVER_PORT=$(sonic-cfggen -d -v "REST_SERVER['default']['port']") CLIENT_AUTH=$(sonic-cfggen -d -v "REST_SERVER['default']['client_auth']") LOG_LEVEL=$(sonic-cfggen -d -v "REST_SERVER['default']['log_level']") + + SERVER_CRT=$(sonic-cfggen -d -v "REST_SERVER['default']['server_crt']") + SERVER_KEY=$(sonic-cfggen -d -v "REST_SERVER['default']['server_key']") + CA_CRT=$(sonic-cfggen -d -v "REST_SERVER['default']['ca_crt']") +fi + +if [[ -z $SERVER_CRT ]] && [[ -z $SERVER_KEY ]] && [[ -z $CA_CRT ]]; then + HAS_X509_CONFIG=$(sonic-cfggen -d -v "1 if DEVICE_METADATA and DEVICE_METADATA['x509']") fi # Read certificate file paths from DEVICE_METADATA|x509 entry. -HAS_X509_CONFIG=$(sonic-cfggen -d -v "1 if DEVICE_METADATA and DEVICE_METADATA['x509']") if [ "$HAS_X509_CONFIG" == "1" ]; then SERVER_CRT=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']") SERVER_KEY=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']") From 7306de41fd2bc100e1ca22810c5fc9404e3999bc Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Fri, 19 Jun 2020 07:35:56 -0700 Subject: [PATCH 0809/1427] [rules/sonic-utilities.mk] Add sonic-yang-mgmt as build time dependency (#4798) To run the unit test for sonic-utilities/config/config_mgmt.py, we need sonic-yang-mgmt. It is decided to not mock sonic-yang-mgmt because config_mgmt is highly dependent on sonic-yang-mgmt. So It is good to catch any compatibility issues during build time rather than run time. Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com --- rules/sonic-utilities.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index eba618d051dc..c9185596d794 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -12,5 +12,5 @@ SONIC_UTILS = python-sonic-utilities_1.2-1_all.deb $(SONIC_UTILS)_SRC_PATH = $(SRC_PATH)/sonic-utilities -$(SONIC_UTILS)_WHEEL_DEPENDS = $(SONIC_CONFIG_ENGINE) +$(SONIC_UTILS)_WHEEL_DEPENDS += $(SONIC_CONFIG_ENGINE) $(SONIC_YANG_MGMT_PY) SONIC_PYTHON_STDEB_DEBS += $(SONIC_UTILS) From 1f8a78cef178a1c79eb0908ea049dcb39f2aa9f8 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 19 Jun 2020 10:54:10 -0700 Subject: [PATCH 0810/1427] [build] No longer install Python 'click-default-group' package (#4811) All dependencies upon the Python 'click-default-group' package have been removed from sonic-utilities as of https://github.com/Azure/sonic-utilities/pull/903. The submodule was updated to include this patch as of https://github.com/Azure/sonic-buildimage/pull/4601, therefore we no longer need to install this package in the SONiC image. --- files/build_templates/sonic_debian_extension.j2 | 2 -- platform/p4/docker-sonic-p4/Dockerfile.j2 | 1 - platform/vs/docker-sonic-vs/Dockerfile.j2 | 1 - sonic-slave-buster/Dockerfile.j2 | 2 +- sonic-slave-jessie/Dockerfile.j2 | 2 +- sonic-slave-stretch/Dockerfile.j2 | 2 +- 6 files changed, 3 insertions(+), 7 deletions(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index f1d6cc924a8c..2488da1c2061 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -171,8 +171,6 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python-click*_all.deb || \ # Install python pexpect used by sonic-utilities consutil # using pip install instead to get a more recent version than is available through debian sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install pexpect -# Install python click-default-group by sonic-utilities -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install click-default-group==1.2 # Install tabulate >= 0.8.1 via pip in order to support multi-line row output for sonic-utilities sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install tabulate==0.8.2 diff --git a/platform/p4/docker-sonic-p4/Dockerfile.j2 b/platform/p4/docker-sonic-p4/Dockerfile.j2 index 0f918821dea2..22621b985465 100644 --- a/platform/p4/docker-sonic-p4/Dockerfile.j2 +++ b/platform/p4/docker-sonic-p4/Dockerfile.j2 @@ -39,7 +39,6 @@ RUN apt-get install -y net-tools \ iproute \ libpython2.7 \ grub2-common \ - python-click-default-group \ python-click \ python-natsort \ python-tabulate \ diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index f7c88c9b833a..0e129884aab9 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -32,7 +32,6 @@ RUN apt-get install -y net-tools \ libc-ares2 \ iproute \ grub2-common \ - python-click-default-group \ python-click \ python-natsort \ python-tabulate \ diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 3e3191264790..87f39c10b9b3 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -351,7 +351,7 @@ RUN pip install j2cli==0.3.10 # Remove python-click 6.6 RUN apt-get purge -y python-click # For sonic utilities testing -RUN pip install click-default-group click natsort tabulate netifaces==0.10.7 fastentrypoints +RUN pip install click natsort tabulate netifaces==0.10.7 fastentrypoints # For sonic snmpagent mock testing RUN pip3 install mockredispy==2.9.3 diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index f4278bf5c299..2df3828c4096 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -311,7 +311,7 @@ RUN pip install --force-reinstall --upgrade "jinja2>=2.10" RUN pip install j2cli==0.3.10 # For sonic utilities testing -RUN pip install click-default-group click natsort tabulate netifaces==0.10.7 fastentrypoints +RUN pip install click natsort tabulate netifaces==0.10.7 fastentrypoints # For supervisor build RUN pip install meld3 mock diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index a7266806437a..c145465bb191 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -350,7 +350,7 @@ RUN pip install j2cli==0.3.10 # Remove python-click 6.6 RUN apt-get purge -y python-click # For sonic utilities testing -RUN pip install click-default-group click natsort tabulate netifaces==0.10.7 fastentrypoints +RUN pip install click natsort tabulate netifaces==0.10.7 fastentrypoints # For sonic snmpagent mock testing RUN pip3 install mockredispy==2.9.3 From 603b2955e640cb79d9946f7d626afb06e0006dd8 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Fri, 19 Jun 2020 21:00:44 +0300 Subject: [PATCH 0811/1427] [BFN] Update SAI and platform packages to 20200618 (#4817) Signed-off-by: Volodymyr Boyko --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 57acf3e95d0f..99ee7592f372 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20200610_deb9.deb +BFN_PLATFORM = bfnplatform_20200618_deb9.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 232c37e7492d..39b8f3691811 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20200610_deb9.deb +BFN_SAI = bfnsdk_20200618_deb9.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) From 95e3cda5da43eedacafe763e0a2a6cf99167a362 Mon Sep 17 00:00:00 2001 From: padmanarayana Date: Fri, 19 Jun 2020 11:02:08 -0700 Subject: [PATCH 0812/1427] [DELL]: FTOS to SONiC fast conversion fixes (#4807) While migrating to SONiC 20181130, identified a couple of issues: 1. union-mount needs /host/machine.conf parameters for vendor specific checks : however, in case of migration, the /host/machine.conf is extracted from ONIE only in https://github.com/Azure/sonic-buildimage/blob/master/files/image_config/platform/rc.local#L127. 2. Since grub.cfg is updated to have net.ifnames=0 biosdevname=0, 70-persistent-net.rules changes are no longer required. --- files/image_config/platform/rc.local | 4 ---- files/initramfs-tools/union-mount.j2 | 5 ++++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index ad67f0ff425a..2beec7500cfd 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -82,10 +82,6 @@ update_mgmt_interface_macaddr() { log_migration "eth0 mac in EEPROM after update:" ethtool -e eth0 offset $ethtool_offset length 6 >> /host/migration/migration.log - - # Update the 70-persistent-net.rules with the new mac for eth0 - log_migration "/etc/udev/rules.d/70-persistent-net.rules : replacing $old_mac with $new_mac for eth0" - sed -i "/eth0/ s/ATTR{address}==\"$old_mac\"/ATTR{address}==\"$new_mac\"/g" /etc/udev/rules.d/70-persistent-net.rules } firsttime_exit() { diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index 8c8bb926444d..81d35dd8345d 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -109,7 +109,10 @@ mount --bind ${rootmnt}/host/$image_dir/boot ${rootmnt}/boot ## Mount loop device or tmpfs for /var/log onie_platform="" aboot_platform="" -. ${rootmnt}/host/machine.conf +if [ -f ${rootmnt}/host/machine.conf ]; then + . ${rootmnt}/host/machine.conf +fi + if [ X"$aboot_platform" = X"x86_64-arista_7050_qx32" ] || [ X"$aboot_platform" = X"x86_64-arista_7050_qx32s" ] || [ X"$aboot_platform" = X"x86_64-arista_7060_cx32s" ] From 531d1ad89aa8c7c970eb7c6df3052fcfc99695c7 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 19 Jun 2020 11:03:02 -0700 Subject: [PATCH 0813/1427] [Submodule update] sonic-dbsyncd (#4801) lldp: For multi-npu platforms make sure to add Backplane Interface also as Interface Match List. --- src/sonic-dbsyncd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-dbsyncd b/src/sonic-dbsyncd index ffb3bad2f355..399ac217c6d0 160000 --- a/src/sonic-dbsyncd +++ b/src/sonic-dbsyncd @@ -1 +1 @@ -Subproject commit ffb3bad2f355c28be201d5f27ac4564c46047593 +Subproject commit 399ac217c6d0c6e2397cb690e6d30b7c56aa52d3 From 4d2d95e8e6cdad7cdfb62ad61b8dda584c98b9f8 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 20 Jun 2020 12:09:29 -0700 Subject: [PATCH 0814/1427] [hostcfgd] Synchronize all feature statuses once upon start (#4714) - Ensure all features (services) are in the configured state when hostcfgd starts - Better functionalization of code - Also replace calls to deprecated `has_key()` method in `tacacs_server_handler()` and `tacacs_global_handler()` with `in` keyword. This PR depends on https://github.com/Azure/sonic-utilities/pull/944, otherwise `config load_minigraph` will fail when trying to restart disabled services. --- files/image_config/hostcfgd/hostcfgd | 109 ++++++++++++++++----------- 1 file changed, 66 insertions(+), 43 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 6d4615d85823..b950345d3d9b 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -40,6 +40,40 @@ def obfuscate(data): else: return data + +def update_feature_status(feature_name, status): + if status == "enabled": + start_cmds = [] + start_cmds.append("sudo systemctl unmask {}.service".format(feature_name)) + start_cmds.append("sudo systemctl enable {}.service".format(feature_name)) + start_cmds.append("sudo systemctl start {}.service".format(feature_name)) + for cmd in start_cmds: + syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" + .format(err.cmd, err.returncode, err.output)) + continue + syslog.syslog(syslog.LOG_INFO, "Feature '{}' is enabled and started".format(feature_name)) + elif status == "disabled": + stop_cmds = [] + stop_cmds.append("sudo systemctl stop {}.service".format(feature_name)) + stop_cmds.append("sudo systemctl disable {}.service".format(feature_name)) + stop_cmds.append("sudo systemctl mask {}.service".format(feature_name)) + for cmd in stop_cmds: + syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" + .format(err.cmd, err.returncode, err.output)) + continue + syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(feature_name)) + else: + syslog.syslog(syslog.LOG_ERR, "Unexpected status value '{}' for feature '{}'".format(status, feature_name)) + + class Iptables(object): def __init__(self): ''' @@ -114,7 +148,7 @@ class Iptables(object): try: subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" .format(err.cmd, err.returncode, err.output)) class AaaCfg(object): @@ -234,26 +268,40 @@ class HostConfigDaemon: self.iptables = Iptables() self.iptables.load(lpbk_table) + def update_all_feature_statuses(self): + feature_table = self.config_db.get_table('FEATURE') + for feature_name in feature_table.keys(): + if not feature_name: + syslog.syslog(syslog.LOG_WARNING, "Feature is None") + continue + + status = feature_table[feature_name]['status'] + if not status: + syslog.syslog(syslog.LOG_WARNING, "Status of feature '{}' is None".format(feature_name)) + continue + + update_feature_status(feature_name, status) + def aaa_handler(self, key, data): self.aaacfg.aaa_update(key, data) def tacacs_server_handler(self, key, data): self.aaacfg.tacacs_server_update(key, data) log_data = copy.deepcopy(data) - if log_data.has_key('passkey'): + if 'passkey' in log_data: log_data['passkey'] = obfuscate(log_data['passkey']) syslog.syslog(syslog.LOG_INFO, 'value of {} changed to {}'.format(key, log_data)) def tacacs_global_handler(self, key, data): self.aaacfg.tacacs_global_update(key, data) log_data = copy.deepcopy(data) - if log_data.has_key('passkey'): + if 'passkey' in log_data: log_data['passkey'] = obfuscate(log_data['passkey']) syslog.syslog(syslog.LOG_INFO, 'value of {} changed to {}'.format(key, log_data)) def lpbk_handler(self, key, data): key = ConfigDBConnector.deserialize_key(key) - #Check if delete operation by fetch existing keys + # Check if delete operation by fetch existing keys keys = self.config_db.get_keys('LOOPBACK_INTERFACE') if key in keys: add = True @@ -263,48 +311,23 @@ class HostConfigDaemon: self.iptables.iptables_handler(key, data, add) def feature_status_handler(self, key, data): - status_data = self.config_db.get_table('FEATURE') - for key in status_data.keys(): - if not key: - syslog.syslog(syslog.LOG_WARNING, "FEATURE key is missing") - continue + feature_name = key + feature_table = self.config_db.get_table('FEATURE') + if feature_name not in feature_table.keys(): + syslog.syslog(syslog.LOG_WARNING, "Feature '{}' not in FEATURE table".format(feature_name)) + return - status = status_data[key]['status'] - if not status: - syslog.syslog(syslog.LOG_WARNING, "status is missing for {}".format(key)) - continue - if status == "enabled": - start_cmds=[] - start_cmds.append("sudo systemctl unmask {}.service".format(key)) - start_cmds.append("sudo systemctl enable {}.service".format(key)) - start_cmds.append("sudo systemctl start {}.service".format(key)) - for cmd in start_cmds: - syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) - continue - syslog.syslog(syslog.LOG_INFO, "Feature '{}' is enabled and started".format(key)) - elif status == "disabled": - stop_cmds=[] - stop_cmds.append("sudo systemctl stop {}.service".format(key)) - stop_cmds.append("sudo systemctl disable {}.service".format(key)) - stop_cmds.append("sudo systemctl mask {}.service".format(key)) - for cmd in stop_cmds: - syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) - continue - syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Unexpected status value '{}' for '{}'".format(status, key)) + status = feature_table[feature_name]['status'] + if not status: + syslog.syslog(syslog.LOG_WARNING, "Status of feature '{}' is None".format(feature_name)) + return + + update_feature_status(feature_name, status) def start(self): + # Update all feature statuses once upon starting + self.update_all_feature_statuses() + self.config_db.subscribe('AAA', lambda table, key, data: self.aaa_handler(key, data)) self.config_db.subscribe('TACPLUS_SERVER', lambda table, key, data: self.tacacs_server_handler(key, data)) self.config_db.subscribe('TACPLUS', lambda table, key, data: self.tacacs_global_handler(key, data)) From 211d1e7e2eec247c027abf9bde7c8a2945bfdd4c Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Sat, 20 Jun 2020 15:30:53 -0700 Subject: [PATCH 0815/1427] [fast-reboot] Back up FDB/ARP/Default routes (#4795) FDB/ARP/Default routes files are deleted after swssconfig. This makes debugging/validation of device conversion hard. This PR saves those files in order to facilitate debugging of device conversion. signed-off-by: Tamer Ahmed --- dockers/docker-orchagent/swssconfig.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index 856b3bcd0e41..0743d95f8eb6 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -8,19 +8,19 @@ function fast_reboot { if [[ -f /fdb.json ]]; then swssconfig /fdb.json - rm -f /fdb.json + mv -f /fdb.json /fdb.json.1 fi if [[ -f /arp.json ]]; then swssconfig /arp.json - rm -f /arp.json + mv -f /arp.json /arp.json.1 fi if [[ -f /default_routes.json ]]; then swssconfig /default_routes.json - rm -f /default_routes.json + mv -f /default_routes.json /default_routes.json.1 fi ;; From 0d863c39acb03dcd0310a9ce483bb3b8a1f0c5a5 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Sat, 20 Jun 2020 21:01:24 -0700 Subject: [PATCH 0816/1427] [bgpcfgd]: make a package for bgpcfgd (#4813) --- dockers/docker-fpm-frr/Dockerfile.j2 | 12 ++++++++++-- dockers/docker-fpm-frr/base_image_files/monit_bgp | 2 +- .../frr/supervisord/supervisord.conf.j2 | 2 +- rules/docker-fpm-frr.mk | 1 + rules/sonic_bgpcfgd.dep | 10 ++++++++++ rules/sonic_bgpcfgd.mk | 7 +++++++ src/sonic-bgpcfgd/.gitignore | 6 ++++++ .../docker-fpm-frr => src/sonic-bgpcfgd}/bgpcfgd | 0 src/sonic-bgpcfgd/setup.cfg | 5 +++++ src/sonic-bgpcfgd/setup.py | 14 ++++++++++++++ src/sonic-bgpcfgd/tests/__init__.py | 0 src/sonic-bgpcfgd/tests/test_sample.py | 4 ++++ 12 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 rules/sonic_bgpcfgd.dep create mode 100644 rules/sonic_bgpcfgd.mk create mode 100644 src/sonic-bgpcfgd/.gitignore rename {dockers/docker-fpm-frr => src/sonic-bgpcfgd}/bgpcfgd (100%) create mode 100644 src/sonic-bgpcfgd/setup.cfg create mode 100755 src/sonic-bgpcfgd/setup.py create mode 100644 src/sonic-bgpcfgd/tests/__init__.py create mode 100644 src/sonic-bgpcfgd/tests/test_sample.py diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index 9499cc1ed51a..38bef392e5bf 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -31,16 +31,24 @@ RUN useradd -u ${frr_user_uid} -g ${frr_user_gid} -M -s /bin/false frr {{ install_debian_packages(docker_fpm_frr_debs.split(' ')) }} {%- endif %} +{% if docker_fpm_frr_whls.strip() %} +# Copy locally-built Python wheel dependencies +{{ copy_files("python-wheels/", docker_fpm_frr_whls.split(' '), "/python-wheels/") }} + +# Install locally-built Python wheel dependencies +{{ install_python_wheels(docker_fpm_frr_whls.split(' ')) }} +{% endif %} + RUN chown -R ${frr_user_uid}:${frr_user_gid} /etc/frr/ # Clean up RUN apt-get clean -y && \ apt-get autoclean -y && \ apt-get autoremove -y && \ - rm -rf /debs ~/.cache + rm -rf /debs ~/.cache /python-wheels COPY ["frr", "/usr/share/sonic/templates"] -COPY ["bgpcfgd", "docker_init.sh", "/usr/bin/"] +COPY ["docker_init.sh", "/usr/bin/"] COPY ["snmp.conf", "/etc/snmp/frr.conf"] COPY ["TSA", "/usr/bin/TSA"] COPY ["TSB", "/usr/bin/TSB"] diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp index 5b943ea7c0bb..5dbb794c346b 100644 --- a/dockers/docker-fpm-frr/base_image_files/monit_bgp +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -19,5 +19,5 @@ check process bgpd matching "/usr/lib/frr/bgpd" check process staticd matching "/usr/lib/frr/staticd" if does not exist for 5 times within 5 cycles then alert -check process bgpcfgd matching "python /usr/bin/bgpcfgd" +check process bgpcfgd matching "python /usr/local/bin/bgpcfgd" if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 index 31af4bad43e3..2a1930d8399f 100644 --- a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 +++ b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 @@ -73,7 +73,7 @@ dependent_startup=true dependent_startup_wait_for=bgpd:running [program:bgpcfgd] -command=/usr/bin/bgpcfgd +command=/usr/local/bin/bgpcfgd priority=6 autostart=false autorestart=false diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 45a755a9289f..ad6613a685c6 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -5,6 +5,7 @@ DOCKER_FPM_FRR = $(DOCKER_FPM_FRR_STEM).gz DOCKER_FPM_FRR_DBG = $(DOCKER_FPM_FRR_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_FPM_FRR)_PATH = $(DOCKERS_PATH)/$(DOCKER_FPM_FRR_STEM) +$(DOCKER_FPM_FRR)_PYTHON_WHEELS += $(SONIC_BGPCFGD) $(DOCKER_FPM_FRR)_DEPENDS += $(FRR) $(FRR_SNMP) $(SWSS) $(LIBYANG) $(DOCKER_FPM_FRR)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) diff --git a/rules/sonic_bgpcfgd.dep b/rules/sonic_bgpcfgd.dep new file mode 100644 index 000000000000..abd51062b8bb --- /dev/null +++ b/rules/sonic_bgpcfgd.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SONIC_BGPCFGD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic_bgpcfgd.mk rules/sonic_bgpcfgd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_BGPCFGD)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_BGPCFGD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_BGPCFGD)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic_bgpcfgd.mk b/rules/sonic_bgpcfgd.mk new file mode 100644 index 000000000000..650874b619c9 --- /dev/null +++ b/rules/sonic_bgpcfgd.mk @@ -0,0 +1,7 @@ +# sonic-bgpcfgd package + +SONIC_BGPCFGD = sonic_bgpcfgd-1.0-py2-none-any.whl +$(SONIC_BGPCFGD)_SRC_PATH = $(SRC_PATH)/sonic-bgpcfgd +$(SONIC_BGPCFGD)_DEPENDS += $(SWSSSDK_PY2) +$(SONIC_BGPCFGD)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_BGPCFGD) diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore new file mode 100644 index 000000000000..013f58816544 --- /dev/null +++ b/src/sonic-bgpcfgd/.gitignore @@ -0,0 +1,6 @@ +.eggs/ +build/ +dist/ +*.egg-info/ +tests/*.pyc +tests/__pycache__/ diff --git a/dockers/docker-fpm-frr/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd similarity index 100% rename from dockers/docker-fpm-frr/bgpcfgd rename to src/sonic-bgpcfgd/bgpcfgd diff --git a/src/sonic-bgpcfgd/setup.cfg b/src/sonic-bgpcfgd/setup.cfg new file mode 100644 index 000000000000..00ed5efbcbad --- /dev/null +++ b/src/sonic-bgpcfgd/setup.cfg @@ -0,0 +1,5 @@ +[aliases] +test=pytest +[tool:pytest] +addopts = --verbose +python_files = tests/*.py diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py new file mode 100755 index 000000000000..2aea5cdb0c5a --- /dev/null +++ b/src/sonic-bgpcfgd/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +from setuptools import setup + +setup(name='sonic-bgpcfgd', + version='1.0', + description='Utility to dynamically generate BGP configuration for FRR', + author='Pavel Shirshov', + author_email='pavelsh@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + scripts=['bgpcfgd'], + install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], + setup_requires=['pytest-runner', 'pytest'], +) diff --git a/src/sonic-bgpcfgd/tests/__init__.py b/src/sonic-bgpcfgd/tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-bgpcfgd/tests/test_sample.py b/src/sonic-bgpcfgd/tests/test_sample.py new file mode 100644 index 000000000000..3adfe439d29c --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_sample.py @@ -0,0 +1,4 @@ +import pytest + +def test_sample(): + assert True From 697193543fa752ba83ad401f7e14669de16cdfbf Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Sun, 21 Jun 2020 15:51:29 +0300 Subject: [PATCH 0817/1427] [submodule]: Advance sonic-utilities submodule. (#4785) Signed-off-by: Nazarii Hnydyn --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index a21e01a2f07c..fd7781b52d6b 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit a21e01a2f07c1567c3b8ada7b00f00a2dc7bf428 +Subproject commit fd7781b52d6b70d90505ca128277ce864cee7ab2 From 2b568ec136942c5345b98e6c63f8963920811af3 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sun, 21 Jun 2020 16:27:05 +0300 Subject: [PATCH 0818/1427] Add with_i2cdev for mst start to have I2C device loaded properly (#4790) --- files/scripts/syncd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 045b8a22bfb8..797aaec21990 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -113,7 +113,7 @@ start() { /usr/bin/hw-management.sh chipupdis fi - /usr/bin/mst start + /usr/bin/mst start --with_i2cdev /usr/bin/mlnx-fw-upgrade.sh /etc/init.d/sxdkernel start fi From 68576bc2f95921060c78f847ee381e92a243de8d Mon Sep 17 00:00:00 2001 From: Olivier Singla <47356901+olivier-singla@users.noreply.github.com> Date: Sun, 21 Jun 2020 09:41:23 -0400 Subject: [PATCH 0819/1427] [kerne]: kernel update from 4.19.0-6 to 4.19.0-6-2 (#4711) --- build_debian.sh | 2 +- installer/x86_64/install.sh | 4 ++-- platform/barefoot/bfn-modules/debian/control | 2 +- .../debian/control | 2 +- .../debian/control | 2 +- .../sonic-platform-modules-bfn/debian/control | 2 +- .../debian/control | 2 +- platform/broadcom/saibcm-modules/debian/control | 2 +- .../saibcm-modules/debian/opennsl-modules.dirs | 2 +- .../saibcm-modules/debian/opennsl-modules.install | 10 +++++----- platform/broadcom/saibcm-modules/debian/rules | 2 +- .../debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 8 ++++---- .../sonic-platform-modules-dell/debian/control | 14 +++++++------- .../sonic-platform-modules-delta/debian/control | 12 ++++++------ .../sonic-platform-modules-inventec/debian/control | 12 ++++++------ .../sonic-platform-modules-mitac/debian/control | 2 +- .../cavium/cavm_platform_modules/DEBIAN/control | 2 +- .../sonic-platform-modules-e582/debian/control | 4 ++-- .../sonic-platform-modules-embedway/debian/control | 2 +- .../sonic-platform-modules-cel/debian/control | 2 +- .../sonic-platform-modules-delta/debian/control | 2 +- platform/nephos/nephos-modules/debian/control | 2 +- .../sonic-platform-modules-accton/debian/control | 2 +- .../sonic-platform-modules-cig/debian/control | 6 +++--- .../sonic-platform-modules-pegatron/debian/control | 2 +- rules/linux-kernel.mk | 2 +- src/sonic-linux-kernel | 2 +- 28 files changed, 56 insertions(+), 56 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 2cae3eacef25..dd4e59f7512b 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -37,7 +37,7 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then else DOCKER_VERSION=5:18.09.8~3-0~debian-$IMAGE_DISTRO fi -LINUX_KERNEL_VERSION=4.19.0-6 +LINUX_KERNEL_VERSION=4.19.0-6-2 ## Working directory to prepare the file system FILESYSTEM_ROOT=./fsroot diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index 29e6e7776615..993992e295fd 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -609,12 +609,12 @@ menuentry '$demo_grub_entry' { if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 - linux /$image_dir/boot/vmlinuz-4.19.0-6-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ + linux /$image_dir/boot/vmlinuz-4.19.0-6-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ net.ifnames=0 biosdevname=0 \ loop=$image_dir/$FILESYSTEM_SQUASHFS loopfstype=squashfs \ apparmor=1 security=apparmor varlog_size=$VAR_LOG_SIZE usbcore.autosuspend=-1 $ONIE_PLATFORM_EXTRA_CMDLINE_LINUX echo 'Loading $demo_volume_label $demo_type initial ramdisk ...' - initrd /$image_dir/boot/initrd.img-4.19.0-6-amd64 + initrd /$image_dir/boot/initrd.img-4.19.0-6-2-amd64 } EOF diff --git a/platform/barefoot/bfn-modules/debian/control b/platform/barefoot/bfn-modules/debian/control index 13a3b72a03b7..da1f2c64a030 100644 --- a/platform/barefoot/bfn-modules/debian/control +++ b/platform/barefoot/bfn-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: bfn-modules Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for bfn asic for mmap diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index 9a512bd0e143..f3daec7458ed 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-montara Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control index 1538a7041800..9d8b6b5b2438 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-newport Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index 639db9110df5..98395d3e84a0 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control index 63857c093532..d9059da93500 100644 --- a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: platform-modules-wnc-osw1800 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/saibcm-modules/debian/control b/platform/broadcom/saibcm-modules/debian/control index 72542564abf7..2a6423cf15f0 100644 --- a/platform/broadcom/saibcm-modules/debian/control +++ b/platform/broadcom/saibcm-modules/debian/control @@ -10,5 +10,5 @@ Standards-Version: 3.9.3 Package: opennsl-modules Architecture: amd64 Section: main -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for broadcom SAI diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs index fe56bc4cf388..64136958bbdf 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs @@ -1 +1 @@ -lib/modules/4.19.0-6-amd64/extra +lib/modules/4.19.0-6-2-amd64/extra diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index 6d1ffa2fc51e..5016ea0367ab 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -1,6 +1,6 @@ -systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.19.0-6-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.19.0-6-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.19.0-6-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.19.0-6-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.19.0-6-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.19.0-6-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.19.0-6-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.19.0-6-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.19.0-6-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.19.0-6-2-amd64/extra systemd/opennsl-modules.service lib/systemd/system diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index a22bcc4ac6ff..b7e35f2aef08 100755 --- a/platform/broadcom/saibcm-modules/debian/rules +++ b/platform/broadcom/saibcm-modules/debian/rules @@ -34,7 +34,7 @@ sname:=opennsl PACKAGE=opennsl-modules # modifieable for experiments or debugging m-a MA_DIR ?= /usr/share/modass -KVERSION ?= 4.19.0-6-amd64 +KVERSION ?= 4.19.0-6-2-amd64 # load generic variable handling -include $(MA_DIR)/include/generic.make # load default rules, including kdist, kdist_image, ... diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control index 55533f735a53..d26493bfaaae 100644 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: sonic-platform-alphanetworks-snh60a0-320fv2 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-alphanetworks-snh60b0-640f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index b69c44beab63..0c3f18621c1f 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -7,21 +7,21 @@ Standards-Version: 3.9.3 Package: platform-modules-dx010 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-haliburton Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-seastone2 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as led, sfp Package: platform-modules-silverstone Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as led, sfp. diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index 6a0ab0e7d2ac..d59fd646e7d7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -7,35 +7,35 @@ Standards-Version: 3.9.3 Package: platform-modules-s6000 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9100 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s6100 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9264f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5232f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5248f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9332f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index e4d4946cce29..a7475cabd1b8 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-ag9032v1 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9064 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag5648 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-et-6248brb Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9032v2a Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as syseeprom, sfp Package: platform-modules-agc032 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index 31a6e67d0982..cf7c2ff9f2e1 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-d7032q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7054q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6254qs Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6556 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6356 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7264q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/control b/platform/broadcom/sonic-platform-modules-mitac/debian/control index b693fb382a89..4f3a3281f6ed 100644 --- a/platform/broadcom/sonic-platform-modules-mitac/debian/control +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-mitac-ly1200-32x Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/cavium/cavm_platform_modules/DEBIAN/control b/platform/cavium/cavm_platform_modules/DEBIAN/control index 233aa9ec7baf..483ad94a5553 100755 --- a/platform/cavium/cavm_platform_modules/DEBIAN/control +++ b/platform/cavium/cavm_platform_modules/DEBIAN/control @@ -1,6 +1,6 @@ Package: cavm-platform-modules Version: 1.0 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Maintainer: Nadiya.Stetskovych@cavium.com Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-e582/debian/control b/platform/centec/sonic-platform-modules-e582/debian/control index 1c31c94244ec..aefb642a673f 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/control +++ b/platform/centec/sonic-platform-modules-e582/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: platform-modules-e582-48x2q4z Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-e582-48x6q Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-embedway/debian/control b/platform/centec/sonic-platform-modules-embedway/debian/control index 044c847ddad6..78053927ea9a 100644 --- a/platform/centec/sonic-platform-modules-embedway/debian/control +++ b/platform/centec/sonic-platform-modules-embedway/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: platform-modules-embedway-es6220 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/innovium/sonic-platform-modules-cel/debian/control b/platform/innovium/sonic-platform-modules-cel/debian/control index 30baa323c36a..13681358e307 100755 --- a/platform/innovium/sonic-platform-modules-cel/debian/control +++ b/platform/innovium/sonic-platform-modules-cel/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: platform-modules-midstone-200i Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices diff --git a/platform/innovium/sonic-platform-modules-delta/debian/control b/platform/innovium/sonic-platform-modules-delta/debian/control index 7395157d35f8..44cb905419c4 100644 --- a/platform/innovium/sonic-platform-modules-delta/debian/control +++ b/platform/innovium/sonic-platform-modules-delta/debian/control @@ -7,7 +7,7 @@ Standards-Version: 3.9.3 Package: platform-modules-et-c032if Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/nephos-modules/debian/control b/platform/nephos/nephos-modules/debian/control index 8450eeae1e01..f13c9ce5ceaa 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: nephos-modules Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for nephos asic diff --git a/platform/nephos/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control index a1068b7a7c5c..27d678a4f82d 100755 --- a/platform/nephos/sonic-platform-modules-accton/debian/control +++ b/platform/nephos/sonic-platform-modules-accton/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: sonic-platform-accton-as7116-54x Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-cig/debian/control b/platform/nephos/sonic-platform-modules-cig/debian/control index 0c70d57ddbf2..a8cbc4903166 100644 --- a/platform/nephos/sonic-platform-modules-cig/debian/control +++ b/platform/nephos/sonic-platform-modules-cig/debian/control @@ -7,15 +7,15 @@ Standards-Version: 3.9.3 Package: sonic-platform-cig-cs6436-56p Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-cig-cs6436-54p Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-cig-cs5435-54p Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/control b/platform/nephos/sonic-platform-modules-pegatron/debian/control index 4fed2d1aa15e..694e2a16a537 100755 --- a/platform/nephos/sonic-platform-modules-pegatron/debian/control +++ b/platform/nephos/sonic-platform-modules-pegatron/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-pegatron-porsche Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64-unsigned +Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/rules/linux-kernel.mk b/rules/linux-kernel.mk index 0b906a2623ba..359b24e31f88 100644 --- a/rules/linux-kernel.mk +++ b/rules/linux-kernel.mk @@ -1,6 +1,6 @@ # linux kernel package -KVERSION_SHORT = 4.19.0-6 +KVERSION_SHORT = 4.19.0-6-2 KVERSION = $(KVERSION_SHORT)-$(CONFIGURED_ARCH) KERNEL_VERSION = 4.19.67 KERNEL_SUBVERSION = 2+deb10u2 diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 1573762bfa36..0776e9f66dc3 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 1573762bfa36e32867e911a730aa7ce18b762eb0 +Subproject commit 0776e9f66dc31ee61e808d076f97818c19735214 From 2c830f4074fd2af0e390d9ad6a142d3bb0474fc2 Mon Sep 17 00:00:00 2001 From: madhanmellanox <62459540+madhanmellanox@users.noreply.github.com> Date: Sun, 21 Jun 2020 12:15:23 -0700 Subject: [PATCH 0820/1427] Modified SKU based utils to Platform based utils (#4786) Co-authored-by: Madhan Babu --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 14 +++++++------- .../mlnx-platform-api/sonic_platform/chassis.py | 16 ++++++++-------- .../mlnx-platform-api/sonic_platform/fan.py | 1 - .../mlnx-platform-api/sonic_platform/psu.py | 4 ++-- .../mlnx-platform-api/sonic_platform/thermal.py | 6 +++--- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 647d967f84a1..9b937225b6ff 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -33,15 +33,15 @@ SYSTEM_READY = 'system_become_ready' SYSTEM_FAIL = 'system_fail' -GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" +GET_PLATFORM_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.platform" # Ethernet <=> sfp SFP_PORT_NAME_OFFSET = 1 SFP_PORT_NAME_CONVENTION = "sfp{}" -# magic code defnition for port number, qsfp port position of each hwsku +# magic code defnition for port number, qsfp port position of each platform # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5, 'ACS-MSN4600C': 4} +platform_dict = {'x86_64-mlnx_msn2700-r0': 0, 'x86_64-mlnx_msn2740-r0': 0, 'x86_64-mlnx_msn2100-r0': 1, 'x86_64-mlnx_msn2410-r0': 2, 'x86_64-mlnx_msn2010-r0': 3, 'x86_64-mlnx_msn3420-r0':5, 'x86_64-mlnx_msn3700-r0': 0, 'x86_64-mlnx_msn3700c-r0': 0, 'x86_64-mlnx_msn3800-r0': 4, 'x86_64-mlnx_msn4600c':4, 'x86_64-mlnx_msn4700-r0': 0} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1), (0, 48, 59, 60, 1)] def log_info(msg, also_print_to_console=False): @@ -86,14 +86,14 @@ def port_to_eeprom_mapping(self): print "dependency on sysfs has been removed" raise Exception() - def get_port_position_tuple_by_sku_name(self): - p = subprocess.Popen(GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) + def get_port_position_tuple_by_platform_name(self): + p = subprocess.Popen(GET_PLATFORM_CMD, shell=True, stdout=subprocess.PIPE) out, err = p.communicate() - position_tuple = port_position_tuple_list[hwsku_dict[out.rstrip('\n')]] + position_tuple = port_position_tuple_list[platform_dict[out.rstrip('\n')]] return position_tuple def __init__(self): - port_position_tuple = self.get_port_position_tuple_by_sku_name() + port_position_tuple = self.get_port_position_tuple_by_platform_name() self.PORT_START = port_position_tuple[0] self.QSFP_PORT_START = port_position_tuple[1] self.PORT_END = port_position_tuple[2] diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 0625eba4f1b1..567f5f0c541d 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -48,9 +48,9 @@ # Global logger class instance logger = Logger() -# magic code defnition for port number, qsfp port position of each hwsku +# magic code defnition for port number, qsfp port position of each Platform # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5, 'ACS-MSN4600C': 4} +platform_dict_port = {'x86_64-mlnx_msn2010-r0': 3, 'x86_64-mlnx_msn2100-r0': 1, 'x86_64-mlnx_msn2410-r0': 2, 'x86_64-mlnx_msn2700-r0': 0, 'x86_64-mlnx_lssn2700':0, 'x86_64-mlnx_msn2740-r0': 0, 'x86_64-mlnx_msn3420-r0':5, 'x86_64-mlnx_msn3700-r0': 0, 'x86_64-mlnx_msn3700C-r0': 0, 'x86_64-mlnx_msn3800-r0': 4, 'x86_64-mlnx_msn4600c-r0':4, 'x86_64-mlnx_msn4700-r0': 0} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1), (0, 48, 59, 60, 1)] class Chassis(ChassisBase): @@ -59,8 +59,9 @@ class Chassis(ChassisBase): def __init__(self): super(Chassis, self).__init__() - # Initialize SKU name + # Initialize SKU name and Platform name self.sku_name = self._get_sku_name() + self.platform_name = self._get_platform_name() mi = get_machine_info() if mi is not None: @@ -119,7 +120,7 @@ def initialize_sfp(self): self.sfp_module = SFP # Initialize SFP list - port_position_tuple = self._get_port_position_tuple_by_sku_name() + port_position_tuple = self._get_port_position_tuple_by_platform_name() self.PORT_START = port_position_tuple[0] self.QSFP_PORT_START = port_position_tuple[1] self.PORT_END = port_position_tuple[2] @@ -138,7 +139,7 @@ def initialize_sfp(self): def initialize_thermals(self): from sonic_platform.thermal import initialize_thermals # Initialize thermals - initialize_thermals(self.sku_name, self._thermal_list, self._psu_list) + initialize_thermals(self.platform_name, self._thermal_list, self._psu_list) def initialize_eeprom(self): @@ -249,9 +250,8 @@ def _get_platform_name(self): out, err = p.communicate() return out.rstrip('\n') - - def _get_port_position_tuple_by_sku_name(self): - position_tuple = port_position_tuple_list[hwsku_dict_port[self.sku_name]] + def _get_port_position_tuple_by_platform_name(self): + position_tuple = port_position_tuple_list[platform_dict_port[self.platform_name]] return position_tuple diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py index 491be834aa2e..5b843749f0ee 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py @@ -25,7 +25,6 @@ FAN_DIR = "/var/run/hw-management/system/fan_dir" COOLING_STATE_PATH = "/var/run/hw-management/thermal/cooling_cur_state" - class Fan(FanBase): """Platform-specific Fan class""" diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 5541402916a0..6279f2d9e349 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -31,7 +31,7 @@ # in most platforms the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. # but there are exceptions which will be handled by the following dictionary -platform_dict_psu = {'x86_64-mlnx_msn3700-r0': 1, 'x86_64-mlnx_msn3700c-r0': 1, 'x86_64-mlnx_msn3800-r0': 1, 'x86_64-mlnx_msn4700-r0': 1} +platform_dict_psu = {'x86_64-mlnx_msn3420-r0':1, 'x86_64-mlnx_msn3700-r0': 1, 'x86_64-mlnx_msn3700c-r0': 1, 'x86_64-mlnx_msn3800-r0': 1, 'x86_64-mlnx_msn4600c-r0':1, 'x86_64-mlnx_msn4700-r0': 1} psu_profile_list = [ # default filename convention @@ -40,7 +40,7 @@ PSU_VOLTAGE : "power/psu{}_volt", PSU_POWER : "power/psu{}_power" }, - # for 3420, 3700, 3700c, 3800, 4700 + # for 3420, 3700, 3700c, 3800, 4600c, 4700 { PSU_CURRENT : "power/psu{}_curr", PSU_VOLTAGE : "power/psu{}_volt_out2", diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 54e2d1a478c0..3525220a4035 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -124,7 +124,7 @@ THERMAL_API_GET_HIGH_THRESHOLD ] -hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8, 'ACS-MSN3420': 9, 'ACS-MSN4600C': 10} +platform_dict_thermal = {'x86_64-mlnx_msn2700-r0': 0, 'x86_64-mlnx_lssn2700-r0':0, 'x86_64-mlnx_msn2740-r0': 3, 'x86_64-mlnx_msn2100-r0': 1, 'x86_64-mlnx_msn2410-r0': 2, 'x86_64-mlnx_msn2010-r0': 4, 'x86_64-mlnx_msn3420-r0':9, 'x86_64-mlnx_msn3700-r0': 5, 'x86_64-mlnx_msn3700c-r0': 6, 'x86_64-mlnx_msn3800-r0': 7, 'x86_64-mlnx_msn4600c-r0':9, 'x86_64-mlnx_msn4700-r0': 8} thermal_profile_list = [ # 2700 { @@ -300,9 +300,9 @@ ] -def initialize_thermals(sku, thermal_list, psu_list): +def initialize_thermals(platform, thermal_list, psu_list): # create thermal objects for all categories of sensors - tp_index = hwsku_dict_thermal[sku] + tp_index = platform_dict_thermal[platform] thermal_profile = thermal_profile_list[tp_index] Thermal.thermal_profile = thermal_profile for category in thermal_device_categories_all: From b5d0bada1950311087848b05da77ca24d1fdb363 Mon Sep 17 00:00:00 2001 From: madhanmellanox <62459540+madhanmellanox@users.noreply.github.com> Date: Sun, 21 Jun 2020 12:16:16 -0700 Subject: [PATCH 0821/1427] modified files relevant to SKU Mellanox-SN3800-D112C8 (#4810) * modified files relevant to SKU Mellanox-SN3800-D112C8 Co-authored-by: Madhan Babu --- .../Mellanox-SN3800-D112C8/port_config.ini | 226 ++++++++++-------- 1 file changed, 121 insertions(+), 105 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini index 9559119c7e38..7cb69a141f28 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini @@ -1,105 +1,121 @@ -# name lanes alias index speed fec -Ethernet0 0,1 etp1a 0 50000 none -Ethernet2 2,3 etp1b 0 50000 none -Ethernet4 4,5 etp2a 1 50000 none -Ethernet6 6,7 etp2b 1 50000 none -Ethernet8 8,9 etp3a 2 50000 none -Ethernet10 10,11 etp3b 2 50000 none -Ethernet12 12,13,14,15 etp4 3 50000 none -Ethernet16 16,17 etp5a 4 50000 none -Ethernet18 18,19 etp5b 4 50000 none -Ethernet20 20,21 etp6a 5 50000 none -Ethernet22 22,23 etp6b 5 50000 none -Ethernet24 24,25 etp7a 6 50000 none -Ethernet26 26,27 etp7b 6 50000 none -Ethernet28 28,29,30,31 etp8 7 50000 none -Ethernet32 32,33 etp9a 8 50000 none -Ethernet34 34,35 etp9b 8 50000 none -Ethernet36 36,37 etp10a 9 50000 none -Ethernet38 38,39 etp10b 9 50000 none -Ethernet40 40,41 etp11a 10 50000 none -Ethernet42 42,43 etp11b 10 50000 none -Ethernet44 44,45,46,47 etp12 11 50000 none -Ethernet48 48,49 etp13a 12 50000 none -Ethernet50 50,51 etp13b 12 50000 none -Ethernet52 52,53 etp14a 13 50000 none -Ethernet54 54,55 etp14b 13 50000 none -Ethernet56 56,57 etp15a 14 50000 none -Ethernet58 58,59 etp15b 14 50000 none -Ethernet60 60,61,62,63 etp16 15 50000 none -Ethernet64 64,65 etp17a 16 50000 none -Ethernet66 66,67 etp17b 16 50000 none -Ethernet68 68,69 etp18a 17 50000 none -Ethernet70 70,71 etp18b 17 50000 none -Ethernet72 72,73 etp19a 18 50000 none -Ethernet74 74,75 etp19b 18 50000 none -Ethernet76 76,77,78,79 etp20 19 50000 none -Ethernet80 80,81 etp21a 20 50000 none -Ethernet82 82,83 etp21b 20 50000 none -Ethernet84 84,85 etp22a 21 50000 none -Ethernet86 86,87 etp22b 21 50000 none -Ethernet88 88,89 etp23a 22 50000 none -Ethernet90 90,91 etp23b 22 50000 none -Ethernet92 92,93,94,95 etp24 23 50000 none -Ethernet96 96,97,98,99 etp25 24 100000 rs -Ethernet100 100,101,102,103 etp26 25 100000 rs -Ethernet104 104,105 etp27a 26 50000 none -Ethernet106 106,107 etp27b 26 50000 none -Ethernet108 108,109,110,111 etp28 27 50000 none -Ethernet112 112,113,114,115 etp29 28 100000 rs -Ethernet116 116,117,118,119 etp30 29 100000 rs -Ethernet120 120,121 etp31a 30 50000 none -Ethernet122 122,123 etp31b 30 50000 none -Ethernet124 124,125,126,127 etp32 31 50000 none -Ethernet128 128,129,130,131 etp33 32 100000 rs -Ethernet132 132,133,134,135 etp34 33 100000 rs -Ethernet136 136,137 etp35a 34 50000 none -Ethernet138 138,139 etp35b 34 50000 none -Ethernet140 140,141,142,143 etp36 35 50000 none -Ethernet144 144,145,146,147 etp37 36 100000 rs -Ethernet148 148,149,150,151 etp38 37 100000 rs -Ethernet152 152,153 etp39a 38 50000 none -Ethernet154 154,155 etp39b 38 50000 none -Ethernet156 156,157,158,159 etp40 39 50000 none -Ethernet160 160,161 etp41a 40 50000 none -Ethernet162 162,163 etp41b 40 50000 none -Ethernet164 164,165 etp42a 41 50000 none -Ethernet166 166,167 etp42b 41 50000 none -Ethernet168 168,169 etp43a 42 50000 none -Ethernet170 170,171 etp43b 42 50000 none -Ethernet172 172,173,174,175 etp44 43 50000 none -Ethernet176 176,177 etp45a 44 50000 none -Ethernet178 178,179 etp45b 44 50000 none -Ethernet180 180,181 etp46a 45 50000 none -Ethernet182 182,183 etp46b 45 50000 none -Ethernet184 184,185 etp47a 46 50000 none -Ethernet186 186,187 etp47b 46 50000 none -Ethernet188 188,189,190,191 etp48 47 50000 none -Ethernet192 192,193 etp49a 48 50000 none -Ethernet194 194,195 etp49b 48 50000 none -Ethernet196 196,197 etp50a 49 50000 none -Ethernet198 198,199 etp50b 49 50000 none -Ethernet200 200,201 etp51a 50 50000 none -Ethernet202 202,203 etp51b 50 50000 none -Ethernet204 204,205,206,207 etp52 51 50000 none -Ethernet208 208,209 etp53a 52 50000 none -Ethernet210 210,211 etp53b 52 50000 none -Ethernet212 212,213 etp54a 53 50000 none -Ethernet214 214,215 etp54b 53 50000 none -Ethernet216 216,217 etp55a 54 50000 none -Ethernet218 218,219 etp55b 54 50000 none -Ethernet220 220,221,222,223 etp56 55 50000 none -Ethernet224 224,225 etp57a 56 50000 none -Ethernet226 226,227 etp57b 56 50000 none -Ethernet228 228,229 etp58a 57 50000 none -Ethernet230 230,231 etp58b 57 50000 none -Ethernet232 232,233 etp59a 58 50000 none -Ethernet234 234,235 etp59b 58 50000 none -Ethernet236 236,237,238,239 etp60 59 50000 none -Ethernet240 240,241 etp61a 60 50000 none -Ethernet242 242,243 etp61b 60 50000 none -Ethernet244 244,245 etp62a 61 50000 none -Ethernet246 246,247 etp62b 61 50000 none -Ethernet248 248,249 etp63a 62 50000 none -Ethernet250 250,251 etp63b 62 50000 none -Ethernet252 252,253,254,255 etp64 63 50000 none +# name lanes alias index speed +Ethernet0 0,1 etp1a 0 50000 +Ethernet2 2,3 etp1b 0 50000 +Ethernet4 4,5 etp2a 1 50000 +Ethernet6 6,7 etp2b 1 50000 +Ethernet8 8,9 etp3a 2 50000 +Ethernet10 10,11 etp3b 2 50000 +Ethernet12 12,13 etp4a 3 50000 +Ethernet14 14,15 etp4b 3 50000 +Ethernet16 16,17 etp5a 4 50000 +Ethernet18 18,19 etp5b 4 50000 +Ethernet20 20,21 etp6a 5 50000 +Ethernet22 22,23 etp6b 5 50000 +Ethernet24 24,25 etp7a 6 50000 +Ethernet26 26,27 etp7b 6 50000 +Ethernet28 28,29 etp8a 7 50000 +Ethernet30 30,31 etp8b 7 50000 +Ethernet32 32,33 etp9a 8 50000 +Ethernet34 34,35 etp9b 8 50000 +Ethernet36 36,37 etp10a 9 50000 +Ethernet38 38,39 etp10b 9 50000 +Ethernet40 40,41 etp11a 10 50000 +Ethernet42 42,43 etp11b 10 50000 +Ethernet44 44,45 etp12a 11 50000 +Ethernet46 46,47 etp12b 11 50000 +Ethernet48 48,49 etp13a 12 50000 +Ethernet50 50,51 etp13b 12 50000 +Ethernet52 52,53 etp14a 13 50000 +Ethernet54 54,55 etp14b 13 50000 +Ethernet56 56,57 etp15a 14 50000 +Ethernet58 58,59 etp15b 14 50000 +Ethernet60 60,61 etp16a 15 50000 +Ethernet62 62,63 etp16b 15 50000 +Ethernet64 64,65 etp17a 16 50000 +Ethernet66 66,67 etp17b 16 50000 +Ethernet68 68,69 etp18a 17 50000 +Ethernet70 70,71 etp18b 17 50000 +Ethernet72 72,73 etp19a 18 50000 +Ethernet74 74,75 etp19b 18 50000 +Ethernet76 76,77 etp20a 19 50000 +Ethernet78 78,79 etp20b 19 50000 +Ethernet80 80,81 etp21a 20 50000 +Ethernet82 82,83 etp21b 20 50000 +Ethernet84 84,85 etp22a 21 50000 +Ethernet86 86,87 etp22b 21 50000 +Ethernet88 88,89 etp23a 22 50000 +Ethernet90 90,91 etp23b 22 50000 +Ethernet92 92,93 etp24a 23 50000 +Ethernet94 94,95 etp24b 23 50000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105 etp27a 26 50000 +Ethernet106 106,107 etp27b 26 50000 +Ethernet108 108,109 etp28a 27 50000 +Ethernet110 110,111 etp28b 27 50000 +Ethernet112 112,113,114,115 etp29 28 100000 +Ethernet116 116,117,118,119 etp30 29 100000 +Ethernet120 120,121 etp31a 30 50000 +Ethernet122 122,123 etp31b 30 50000 +Ethernet124 124,125 etp32a 31 50000 +Ethernet126 126,127 etp32b 31 50000 +Ethernet128 128,129,130,131 etp33 32 100000 +Ethernet132 132,133,134,135 etp34 33 100000 +Ethernet136 136,137 etp35a 34 50000 +Ethernet138 138,139 etp35b 34 50000 +Ethernet140 140,141 etp36a 35 50000 +Ethernet142 142,143 etp36b 35 50000 +Ethernet144 144,145,146,147 etp37 36 100000 +Ethernet148 148,149,150,151 etp38 37 100000 +Ethernet152 152,153 etp39a 38 50000 +Ethernet154 154,155 etp39b 38 50000 +Ethernet156 156,157 etp40a 39 50000 +Ethernet158 158,159 etp40b 39 50000 +Ethernet160 160,161 etp41a 40 50000 +Ethernet162 162,163 etp41b 40 50000 +Ethernet164 164,165 etp42a 41 50000 +Ethernet166 166,167 etp42b 41 50000 +Ethernet168 168,169 etp43a 42 50000 +Ethernet170 170,171 etp43b 42 50000 +Ethernet172 172,173 etp44a 43 50000 +Ethernet174 174,175 etp44b 43 50000 +Ethernet176 176,177 etp45a 44 50000 +Ethernet178 178,179 etp45b 44 50000 +Ethernet180 180,181 etp46a 45 50000 +Ethernet182 182,183 etp46b 45 50000 +Ethernet184 184,185 etp47a 46 50000 +Ethernet186 186,187 etp47b 46 50000 +Ethernet188 188,189 etp48a 47 50000 +Ethernet190 190,191 etp48b 47 50000 +Ethernet192 192,193 etp49a 48 50000 +Ethernet194 194,195 etp49b 48 50000 +Ethernet196 196,197 etp50a 49 50000 +Ethernet198 198,199 etp50b 49 50000 +Ethernet200 200,201 etp51a 50 50000 +Ethernet202 202,203 etp51b 50 50000 +Ethernet204 204,205 etp52a 51 50000 +Ethernet206 206,207 etp52b 51 50000 +Ethernet208 208,209 etp53a 52 50000 +Ethernet210 210,211 etp53b 52 50000 +Ethernet212 212,213 etp54a 53 50000 +Ethernet214 214,215 etp54b 53 50000 +Ethernet216 216,217 etp55a 54 50000 +Ethernet218 218,219 etp55b 54 50000 +Ethernet220 220,221 etp56a 55 50000 +Ethernet222 222,223 etp56b 55 50000 +Ethernet224 224,225 etp57a 56 50000 +Ethernet226 226,227 etp57b 56 50000 +Ethernet228 228,229 etp58a 57 50000 +Ethernet230 230,231 etp58b 57 50000 +Ethernet232 232,233 etp59a 58 50000 +Ethernet234 234,235 etp59b 58 50000 +Ethernet236 236,237 etp60a 59 50000 +Ethernet238 238,239 etp60b 59 50000 +Ethernet240 240,241 etp61a 60 50000 +Ethernet242 242,243 etp61b 60 50000 +Ethernet244 244,245 etp62a 61 50000 +Ethernet246 246,247 etp62b 61 50000 +Ethernet248 248,249 etp63a 62 50000 +Ethernet250 250,251 etp63b 62 50000 +Ethernet252 252,253 etp64a 63 50000 +Ethernet254 254,255 etp64b 63 50000 \ No newline at end of file From 5efd1e7527c5638b67efcd9a86b24296cb8b2f9e Mon Sep 17 00:00:00 2001 From: madhanmellanox <62459540+madhanmellanox@users.noreply.github.com> Date: Sun, 21 Jun 2020 12:17:56 -0700 Subject: [PATCH 0822/1427] added files to create SKU Mellanox-SN3800-D28C50 (#4809) * added files to create SKU Mellanox-SN3800-D28C50 Co-authored-by: Madhan Babu --- .../Mellanox-SN3800-D28C50/buffers.json.j2 | 1 + .../buffers_defaults_t0.j2 | 1 + .../buffers_defaults_t1.j2 | 1 + .../pg_profile_lookup.ini | 1 + .../Mellanox-SN3800-D28C50/port_config.ini | 79 +++ .../Mellanox-SN3800-D28C50/qos.json.j2 | 1 + .../Mellanox-SN3800-D28C50/sai.profile | 1 + .../sai_3800_28x50g_52x100g.xml | 470 ++++++++++++++++++ 8 files changed, 555 insertions(+) create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/port_config.ini create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/qos.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai.profile create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai_3800_28x50g_52x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers.json.j2 new file mode 120000 index 000000000000..dc17caa0aa32 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers.json.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..0987f6724863 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..119460bfa556 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/pg_profile_lookup.ini new file mode 120000 index 000000000000..db2f74508aad --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/pg_profile_lookup.ini @@ -0,0 +1 @@ +../ACS-MSN3800/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/port_config.ini new file mode 100644 index 000000000000..2c0c25ec0564 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/port_config.ini @@ -0,0 +1,79 @@ +# name lanes alias index speed +Ethernet0 0,1,2,3 etp1 0 100000 +Ethernet4 4,5,6,7 etp2 1 100000 +Ethernet8 8,9,10,11 etp3 2 100000 +Ethernet12 12,13,14,15 etp4 3 100000 +Ethernet16 16,17,18,19 etp5 4 100000 +Ethernet20 20,21,22,23 etp6 5 100000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32,33 etp9a 8 50000 +Ethernet34 34,35 etp9b 8 50000 +Ethernet36 36,37 etp10a 9 50000 +Ethernet38 38,39 etp10b 9 50000 +Ethernet40 40,41 etp11a 10 50000 +Ethernet42 42,43 etp11b 10 50000 +Ethernet44 44,45 etp12a 11 50000 +Ethernet46 46,47 etp12b 11 50000 +Ethernet48 48,49,50,51 etp13 12 100000 +Ethernet52 52,53,54,55 etp14 13 100000 +Ethernet56 56,57,58,59 etp15 14 100000 +Ethernet60 60,61,62,63 etp16 15 100000 +Ethernet64 64,65,66,67 etp17 16 100000 +Ethernet68 68,69,70,71 etp18 17 100000 +Ethernet72 72,73,74,75 etp19 18 100000 +Ethernet76 76,77,78,79 etp20 19 100000 +Ethernet80 80,81,82,83 etp21 20 100000 +Ethernet84 84,85,86,87 etp22 21 100000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105 etp27a 26 50000 +Ethernet106 106,107 etp27b 26 50000 +Ethernet108 108,109 etp28a 27 50000 +Ethernet110 110,111 etp28b 27 50000 +Ethernet112 112,113,114,115 etp29 28 100000 +Ethernet116 116,117,118,119 etp30 29 100000 +Ethernet120 120,121,122,123 etp31 30 100000 +Ethernet124 124,125,126,127 etp32 31 100000 +Ethernet128 128,129,130,131 etp33 32 100000 +Ethernet132 132,133,134,135 etp34 33 100000 +Ethernet136 136,137,138,139 etp35 34 100000 +Ethernet140 140,141,142,143 etp36 35 100000 +Ethernet144 144,145,146,147 etp37 36 100000 +Ethernet148 148,149,150,151 etp38 37 100000 +Ethernet152 152,153,154,155 etp39 38 100000 +Ethernet156 156,157,158,159 etp40 39 100000 +Ethernet160 160,161,162,163 etp41 40 100000 +Ethernet164 164,165,166,167 etp42 41 100000 +Ethernet168 168,169,170,171 etp43 42 100000 +Ethernet172 172,173,174,175 etp44 43 100000 +Ethernet176 176,177 etp45a 44 50000 +Ethernet178 178,179 etp45b 44 50000 +Ethernet180 180,181 etp46a 45 50000 +Ethernet182 182,183 etp46b 45 50000 +Ethernet184 184,185 etp47a 46 50000 +Ethernet186 186,187 etp47b 46 50000 +Ethernet188 188,189 etp48a 47 50000 +Ethernet190 190,191 etp48b 47 50000 +Ethernet192 192,193,194,195 etp49 48 100000 +Ethernet196 196,197,198,199 etp50 49 100000 +Ethernet200 200,201,202,203 etp51 50 100000 +Ethernet204 204,205,206,207 etp52 51 100000 +Ethernet208 208,209,210,211 etp53 52 100000 +Ethernet212 212,213,214,215 etp54 53 100000 +Ethernet216 216,217,218,219 etp55 54 100000 +Ethernet220 220,221,222,223 etp56 55 100000 +Ethernet224 224,225,226,227 etp57 56 100000 +Ethernet228 228,229,230,231 etp58 57 100000 +Ethernet232 232,233,234,235 etp59 58 100000 +Ethernet236 236,237,238,239 etp60 59 100000 +Ethernet240 240,241 etp61a 60 50000 +Ethernet242 242,243 etp61b 60 50000 +Ethernet244 244,245 etp62a 61 50000 +Ethernet246 246,247 etp62b 61 50000 +Ethernet248 248,249 etp63a 62 50000 +Ethernet250 250,251 etp63b 62 50000 +Ethernet252 252,253 etp64a 63 50000 +Ethernet254 254,255 etp64b 63 50000 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/qos.json.j2 new file mode 120000 index 000000000000..26b0dac51846 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/qos.json.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai.profile b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai.profile new file mode 100644 index 000000000000..aa37fb30dbd0 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3800_28x50g_52x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai_3800_28x50g_52x100g.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai_3800_28x50g_52x100g.xml new file mode 100644 index 000000000000..1b3c77ce381c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai_3800_28x50g_52x100g.xml @@ -0,0 +1,470 @@ + + + + + + 00:02:03:04:05:00 + + + 1 + + + 64 + + + + + 1 + 4 + 48 + + + 3 + + + 1536 + + + 3 + 4 + 49 + 3 + 1536 + + + 5 + 4 + 50 + 3 + 1536 + + + 7 + 4 + 51 + 3 + 1536 + + + 9 + 4 + 52 + 3 + 1536 + + + 11 + 4 + 53 + 3 + 1536 + + + 13 + 4 + 54 + 3 + 1536 + + + 15 + 4 + 55 + 3 + 1536 + + + 17 + 4 + 56 + 3 + 1536 + + + 19 + 4 + 57 + 3 + 1536 + + + 21 + 4 + 58 + 3 + 1536 + + + 23 + 4 + 59 + 3 + 1536 + + + 25 + 4 + 60 + 3 + 1536 + + + 27 + 4 + 61 + 3 + 1536 + + + 29 + 4 + 62 + 3 + 1536 + + + 31 + 4 + 63 + 3 + 1536 + + + 33 + 4 + 12 + 3 + 1536 + + + 35 + 4 + 13 + 3 + 1536 + + + 37 + 4 + 14 + 3 + 1536 + + + 39 + 4 + 15 + 3 + 1536 + + + 41 + 4 + 8 + 3 + 1536 + + + 43 + 4 + 9 + 3 + 1536 + + + 45 + 4 + 10 + 3 + 1536 + + + 47 + 4 + 11 + 3 + 1536 + + + 49 + 4 + 4 + 3 + 1536 + + + 51 + 4 + 5 + 3 + 1536 + + + 53 + 4 + 6 + 3 + 1536 + + + 55 + 4 + 7 + 3 + 1536 + + + 57 + 4 + 0 + 3 + 1536 + + + 59 + 4 + 1 + 3 + 1536 + + + 61 + 4 + 2 + 3 + 1536 + + + 63 + 4 + 3 + 3 + 1536 + + + 65 + 4 + 44 + 3 + 1536 + + + 67 + 4 + 45 + 3 + 1536 + + + 69 + 4 + 46 + 3 + 1536 + + + 71 + 4 + 47 + 3 + 1536 + + + 73 + 4 + 40 + 3 + 1536 + + + 75 + 4 + 41 + 3 + 1536 + + + 77 + 4 + 42 + 3 + 1536 + + + 79 + 4 + 43 + 3 + 1536 + + + 81 + 4 + 36 + 3 + 1536 + + + 83 + 4 + 37 + 3 + 1536 + + + 85 + 4 + 38 + 3 + 1536 + + + 87 + 4 + 39 + 3 + 1536 + + + 89 + 4 + 32 + 3 + 1536 + + + 91 + 4 + 33 + 3 + 1536 + + + 93 + 4 + 34 + 3 + 1536 + + + 95 + 4 + 35 + 3 + 1536 + + + 97 + 4 + 16 + 3 + 1536 + + + 99 + 4 + 17 + 3 + 1536 + + + 101 + 4 + 18 + 3 + 1536 + + + 103 + 4 + 19 + 3 + 1536 + + + 105 + 4 + 20 + 3 + 1536 + + + 107 + 4 + 21 + 3 + 1536 + + + 109 + 4 + 22 + 3 + 1536 + + + 111 + 4 + 23 + 3 + 1536 + + + 113 + 4 + 24 + 3 + 1536 + + + 115 + 4 + 25 + 3 + 1536 + + + 117 + 4 + 26 + 3 + 1536 + + + 119 + 4 + 27 + 3 + 1536 + + + 121 + 4 + 28 + 3 + 1536 + + + 123 + 4 + 29 + 3 + 1536 + + + 125 + 4 + 30 + 3 + 1536 + + + 127 + 4 + 31 + 3 + 1536 + + + + From b5f1b37386021e7fd2efe72fbcd0048243fed705 Mon Sep 17 00:00:00 2001 From: madhanmellanox <62459540+madhanmellanox@users.noreply.github.com> Date: Sun, 21 Jun 2020 12:19:11 -0700 Subject: [PATCH 0823/1427] added files to create SKU Mellanox-SN3800-D24C52 (#4808) * added files to create SKU Mellanox-SN3800-D24C52 Co-authored-by: Madhan Babu --- .../Mellanox-SN3800-D24C52/buffers.json.j2 | 1 + .../buffers_defaults_t0.j2 | 1 + .../buffers_defaults_t1.j2 | 1 + .../pg_profile_lookup.ini | 1 + .../Mellanox-SN3800-D24C52/port_config.ini | 77 +++ .../Mellanox-SN3800-D24C52/qos.json.j2 | 1 + .../Mellanox-SN3800-D24C52/sai.profile | 1 + .../sai_3800_24x50g_52x100g.xml | 470 ++++++++++++++++++ 8 files changed, 553 insertions(+) create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/port_config.ini create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/qos.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai.profile create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai_3800_24x50g_52x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers.json.j2 new file mode 120000 index 000000000000..dc17caa0aa32 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers.json.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..0987f6724863 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..119460bfa556 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/pg_profile_lookup.ini new file mode 120000 index 000000000000..db2f74508aad --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/pg_profile_lookup.ini @@ -0,0 +1 @@ +../ACS-MSN3800/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/port_config.ini new file mode 100644 index 000000000000..34cd64b90cec --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/port_config.ini @@ -0,0 +1,77 @@ +# name lanes alias index speed +Ethernet0 0,1,2,3 etp1 0 100000 +Ethernet4 4,5,6,7 etp2 1 100000 +Ethernet8 8,9,10,11 etp3 2 100000 +Ethernet12 12,13,14,15 etp4 3 100000 +Ethernet16 16,17,18,19 etp5 4 100000 +Ethernet20 20,21,22,23 etp6 5 100000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32,33 etp9a 8 50000 +Ethernet34 34,35 etp9b 8 50000 +Ethernet36 36,37 etp10a 9 50000 +Ethernet38 38,39 etp10b 9 50000 +Ethernet40 40,41 etp11a 10 50000 +Ethernet42 42,43 etp11b 10 50000 +Ethernet44 44,45 etp12a 11 50000 +Ethernet46 46,47 etp12b 11 50000 +Ethernet48 48,49,50,51 etp13 12 100000 +Ethernet52 52,53,54,55 etp14 13 100000 +Ethernet56 56,57,58,59 etp15 14 100000 +Ethernet60 60,61,62,63 etp16 15 100000 +Ethernet64 64,65,66,67 etp17 16 100000 +Ethernet68 68,69,70,71 etp18 17 100000 +Ethernet72 72,73,74,75 etp19 18 100000 +Ethernet76 76,77,78,79 etp20 19 100000 +Ethernet80 80,81,82,83 etp21 20 100000 +Ethernet84 84,85,86,87 etp22 21 100000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105 etp27a 26 50000 +Ethernet106 106,107 etp27b 26 50000 +Ethernet108 108,109 etp28a 27 50000 +Ethernet110 110,111 etp28b 27 50000 +Ethernet112 112,113,114,115 etp29 28 100000 +Ethernet116 116,117,118,119 etp30 29 100000 +Ethernet120 120,121,122,123 etp31 30 100000 +Ethernet124 124,125,126,127 etp32 31 100000 +Ethernet128 128,129,130,131 etp33 32 100000 +Ethernet132 132,133,134,135 etp34 33 100000 +Ethernet136 136,137,138,139 etp35 34 100000 +Ethernet140 140,141,142,143 etp36 35 100000 +Ethernet144 144,145,146,147 etp37 36 100000 +Ethernet148 148,149,150,151 etp38 37 100000 +Ethernet152 152,153,154,155 etp39 38 100000 +Ethernet156 156,157,158,159 etp40 39 100000 +Ethernet160 160,161,162,163 etp41 40 100000 +Ethernet164 164,165,166,167 etp42 41 100000 +Ethernet168 168,169,170,171 etp43 42 100000 +Ethernet172 172,173,174,175 etp44 43 100000 +Ethernet176 176,177 etp45a 44 50000 +Ethernet178 178,179 etp45b 44 50000 +Ethernet180 180,181 etp46a 45 50000 +Ethernet182 182,183 etp46b 45 50000 +Ethernet184 184,185 etp47a 46 50000 +Ethernet186 186,187 etp47b 46 50000 +Ethernet188 188,189 etp48a 47 50000 +Ethernet190 190,191 etp48b 47 50000 +Ethernet192 192,193,194,195 etp49 48 100000 +Ethernet196 196,197,198,199 etp50 49 100000 +Ethernet200 200,201,202,203 etp51 50 100000 +Ethernet204 204,205,206,207 etp52 51 100000 +Ethernet208 208,209,210,211 etp53 52 100000 +Ethernet212 212,213,214,215 etp54 53 100000 +Ethernet216 216,217,218,219 etp55 54 100000 +Ethernet220 220,221,222,223 etp56 55 100000 +Ethernet224 224,225,226,227 etp57 56 100000 +Ethernet228 228,229,230,231 etp58 57 100000 +Ethernet232 232,233,234,235 etp59 58 100000 +Ethernet236 236,237,238,239 etp60 59 100000 +Ethernet240 240,241 etp61a 60 50000 +Ethernet242 242,243 etp61b 60 50000 +Ethernet244 244,245 etp62a 61 50000 +Ethernet246 246,247 etp62b 61 50000 +Ethernet248 248,249,250,251 etp63 62 100000 +Ethernet252 252,253,254,255 etp64 63 100000 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/qos.json.j2 new file mode 120000 index 000000000000..26b0dac51846 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/qos.json.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai.profile b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai.profile new file mode 100644 index 000000000000..7c632389b58c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3800_24x50g_52x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai_3800_24x50g_52x100g.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai_3800_24x50g_52x100g.xml new file mode 100644 index 000000000000..1b3c77ce381c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai_3800_24x50g_52x100g.xml @@ -0,0 +1,470 @@ + + + + + + 00:02:03:04:05:00 + + + 1 + + + 64 + + + + + 1 + 4 + 48 + + + 3 + + + 1536 + + + 3 + 4 + 49 + 3 + 1536 + + + 5 + 4 + 50 + 3 + 1536 + + + 7 + 4 + 51 + 3 + 1536 + + + 9 + 4 + 52 + 3 + 1536 + + + 11 + 4 + 53 + 3 + 1536 + + + 13 + 4 + 54 + 3 + 1536 + + + 15 + 4 + 55 + 3 + 1536 + + + 17 + 4 + 56 + 3 + 1536 + + + 19 + 4 + 57 + 3 + 1536 + + + 21 + 4 + 58 + 3 + 1536 + + + 23 + 4 + 59 + 3 + 1536 + + + 25 + 4 + 60 + 3 + 1536 + + + 27 + 4 + 61 + 3 + 1536 + + + 29 + 4 + 62 + 3 + 1536 + + + 31 + 4 + 63 + 3 + 1536 + + + 33 + 4 + 12 + 3 + 1536 + + + 35 + 4 + 13 + 3 + 1536 + + + 37 + 4 + 14 + 3 + 1536 + + + 39 + 4 + 15 + 3 + 1536 + + + 41 + 4 + 8 + 3 + 1536 + + + 43 + 4 + 9 + 3 + 1536 + + + 45 + 4 + 10 + 3 + 1536 + + + 47 + 4 + 11 + 3 + 1536 + + + 49 + 4 + 4 + 3 + 1536 + + + 51 + 4 + 5 + 3 + 1536 + + + 53 + 4 + 6 + 3 + 1536 + + + 55 + 4 + 7 + 3 + 1536 + + + 57 + 4 + 0 + 3 + 1536 + + + 59 + 4 + 1 + 3 + 1536 + + + 61 + 4 + 2 + 3 + 1536 + + + 63 + 4 + 3 + 3 + 1536 + + + 65 + 4 + 44 + 3 + 1536 + + + 67 + 4 + 45 + 3 + 1536 + + + 69 + 4 + 46 + 3 + 1536 + + + 71 + 4 + 47 + 3 + 1536 + + + 73 + 4 + 40 + 3 + 1536 + + + 75 + 4 + 41 + 3 + 1536 + + + 77 + 4 + 42 + 3 + 1536 + + + 79 + 4 + 43 + 3 + 1536 + + + 81 + 4 + 36 + 3 + 1536 + + + 83 + 4 + 37 + 3 + 1536 + + + 85 + 4 + 38 + 3 + 1536 + + + 87 + 4 + 39 + 3 + 1536 + + + 89 + 4 + 32 + 3 + 1536 + + + 91 + 4 + 33 + 3 + 1536 + + + 93 + 4 + 34 + 3 + 1536 + + + 95 + 4 + 35 + 3 + 1536 + + + 97 + 4 + 16 + 3 + 1536 + + + 99 + 4 + 17 + 3 + 1536 + + + 101 + 4 + 18 + 3 + 1536 + + + 103 + 4 + 19 + 3 + 1536 + + + 105 + 4 + 20 + 3 + 1536 + + + 107 + 4 + 21 + 3 + 1536 + + + 109 + 4 + 22 + 3 + 1536 + + + 111 + 4 + 23 + 3 + 1536 + + + 113 + 4 + 24 + 3 + 1536 + + + 115 + 4 + 25 + 3 + 1536 + + + 117 + 4 + 26 + 3 + 1536 + + + 119 + 4 + 27 + 3 + 1536 + + + 121 + 4 + 28 + 3 + 1536 + + + 123 + 4 + 29 + 3 + 1536 + + + 125 + 4 + 30 + 3 + 1536 + + + 127 + 4 + 31 + 3 + 1536 + + + + From d2366d4ff7e5df51ce85db53aab77bf964add2c5 Mon Sep 17 00:00:00 2001 From: madhanmellanox <62459540+madhanmellanox@users.noreply.github.com> Date: Mon, 22 Jun 2020 08:42:30 -0700 Subject: [PATCH 0824/1427] added files to create SKU Mellanox-SN3800-C64 (#4812) * added files to create SKU Mellanox-SN3800-C64 Co-authored-by: Madhan Babu --- device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64 | 1 + 1 file changed, 1 insertion(+) create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64 new file mode 120000 index 000000000000..65b8f3c8ec9d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64 @@ -0,0 +1 @@ +ACS-MSN3800/ \ No newline at end of file From 67987e9c0eb0d6f8679131a9b169fe9a954aa27e Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Mon, 22 Jun 2020 09:30:31 -0700 Subject: [PATCH 0825/1427] [secureboot] Add secureboot support for Arista devices (#4741) * Add secureboot support in boot0 * Initramfs changes for secureboot on Aboot devices * Do not compress squashfs and gz in fs.zip It doesn't make much sense to do so since these files are already compressed. Also not compressing the squashfs has the advantage of making it mountable via a loop device. * Add loopoffset parameter to initramfs-tools --- build_debian.sh | 2 +- files/Aboot/boot0.j2 | 503 +++++++++++++----- files/initramfs-tools/union-mount.j2 | 102 ++-- src/initramfs-tools/Makefile | 2 +- .../loopback-file-offset-support.patch | 73 +++ src/initramfs-tools/series | 2 + 6 files changed, 502 insertions(+), 182 deletions(-) create mode 100644 src/initramfs-tools/loopback-file-offset-support.patch create mode 100644 src/initramfs-tools/series diff --git a/build_debian.sh b/build_debian.sh index dd4e59f7512b..550585c176ec 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -605,4 +605,4 @@ pushd $FILESYSTEM_ROOT && sudo tar czf $OLDPWD/$FILESYSTEM_DOCKERFS -C ${DOCKERF ## Compress together with /boot, /var/lib/docker and $PLATFORM_DIR as an installer payload zip file pushd $FILESYSTEM_ROOT && sudo zip $OLDPWD/$ONIE_INSTALLER_PAYLOAD -r boot/ $PLATFORM_DIR/; popd -sudo zip -g $ONIE_INSTALLER_PAYLOAD $FILESYSTEM_SQUASHFS $FILESYSTEM_DOCKERFS +sudo zip -g -n .squashfs:.gz $ONIE_INSTALLER_PAYLOAD $FILESYSTEM_SQUASHFS $FILESYSTEM_DOCKERFS diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 0ac7d8e12a9d..7672919056c3 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -38,10 +38,18 @@ # Options can be provided to only run some features of this script. # # Extra kernel parameters can be provided at runtime by the user by adding them -# into a kernel-params file. +# into the kernel-params file. +# +# Secureboot of SONiC SWI images is also supported. +# In such cases, there will only be a partial install on the flash. +# SONiC will be mostly booting in RAM as a live operating system. +# All templated variables should be declared here image_name="image-%%IMAGE_VERSION%%" dockerfs="{{ FILESYSTEM_DOCKERFS }}" +boot_image="{{ ABOOT_BOOT_IMAGE }}" +installer_image="sonic.swi" +docker_dir="{{ DOCKERFS_DIR }}" do_not_clean="do-not-clean" kernel_params="kernel-params" @@ -52,6 +60,11 @@ info() { printf "%04.2f: $@\n" "$(cut -f1 -d' ' /proc/uptime)"; } err() { info "Error: $@"; } warn() { info "Warning: $@"; } +if [ $# -ne 0 ]; then + echo "usage: $0 (see code)" + exit 1 +fi + # extract mount point from the swi path, e.g., /mnt/flash/sonic.swi --> /mnt/flash if [ -z "$target_path" ]; then if [ -z "$swipath" ]; then @@ -63,26 +76,29 @@ fi image_path="$target_path/$image_name" hook_path="$image_path/platform/hooks" data_path="$image_path/platform/data" +installer_image_path="$image_path/$installer_image" -cmdline_base="$target_path/kernel-params-base" -cmdline_image="$image_path/kernel-cmdline" boot_config="$target_path/boot-config" -swi_tmpfs="/tmp/tmp-swi" - -bootconfigvars="KERNEL INITRD CONSOLESPEED PASSWORD NETDEV NETAUTO NETIP NETMASK NETGW NETDOMAIN NETDNS NETHW memtest" flash_re=" /mnt/flash| /host" +cmdline_allowlist='crashkernel' # for backward compatibility with the sonic_upgrade= behavior install="${install:-${sonic_upgrade:-}}" -parse_environment_config() { - for n in ${bootconfigvars}; do - eval v="\$$n" - if [ "$v" ]; then - echo "$n=$v" +is_secureboot_enabled() { + if $in_aboot; then + if [ -x /bin/securebootctl ] && securebootctl sb -display | grep -q "Secure Boot enabled"; then + return 0 fi - done + return 1 + else + if grep -q aboot.secureboot /proc/cmdline; then + return 0 + fi + # FIXME: EOS is not handled here + return 1 + fi } clean_flash() { @@ -91,7 +107,6 @@ clean_flash() { if [ $f != "${swipath##*/}" ] && [ $f != "boot-config" ] && [ $f != "$kernel_params" ] && - [ $f != "$cmdline_base" ] && [ $f != "aquota.user" ] && [ $f != "old_config" ] && [ $f != "minigraph.xml" ] && @@ -103,6 +118,19 @@ clean_flash() { done } +in_array() { + local value="$1" + shift + + for other in $@; do + if [ "$value" = "$other" ]; then + return 0 + fi + done + + return 1 +} + update_boot_config() { local key="$1" local value="$2" @@ -126,19 +154,96 @@ update_next_boot() { if [ -z "$default" ]; then warn "boot-config has no variable SWI_DEFAULT" else + info "Next reboot will use $default" update_boot_config SWI "$default" fi } -move_swi_to_tmpfs() { - local oldswi="$1" - local newswi="$swi_tmpfs/$(basename $oldswi)" +get_sorted_hooks() { + echo $(find "$1" -name '[0-9][0-9]-*' -type f) +} + +run_hooks() { + if [ -d "$hook_path/$1" ]; then + for hook in $(get_sorted_hooks "$hook_path/$1"); do + if [ ! -z "$hook" ]; then + info "Running hook $(basename $hook)" + . "$hook" + fi + done + fi +} - mkdir -p "$swi_tmpfs" +get_uuid_for() { + local dev="$1" + + if type lsblk 2>&1 > /dev/null; then + lsblk "$dev" -n --output UUID + elif type blkid 2>&1 > /dev/null; then + blkid | grep "^$dev" | sed -n 's/^.* UUID="//p' | sed 's/".*$//' + fi +} + +cmdline_append() { + cat >> /tmp/append +} + +cmdline_clear() { + echo -n > /tmp/append +} + +cmdline_add() { + echo "$@" >> /tmp/append +} + +cmdline_has() { + grep -q "$1" /tmp/append +} + +cmdline_echo() { + # echo trims and remove whitespace duplicates + echo $(cat /tmp/append | tr '\n' ' ') +} + +cmdline_get() { + # extract last matching value for key + sed -nr "s/.*$1=([^ ]+).*/\1/p" /tmp/append | tail -n 1 +} + +find_first_kernel_under() { + local path="$1" + find "$path" -name 'vmlinuz-*' -type f | head -n 1 +} + +find_first_initrd_under() { + local path="$1" + find "$path" -name 'initrd.img-*' -type f | head -n 1 +} + +get_tmpfs() { + local tmpfs="${1:-$(mktemp -d)}" + + mkdir -p "$tmpfs" if ! $in_aboot && ! mount | grep -q ' /tmp type tmpfs'; then - # mount a real tmpfs on /tmp/tmp-swi if /tmp is not one already. - mount -t tmpfs tmp-swi "$swi_tmpfs" + # mount a real tmpfs on /tmp/xxx if /tmp is not one already. + mount -t tmpfs "$(dirname $tmpfs)" "$tmpfs" fi + echo "$tmpfs" +} + +clean_tmpfs() { + local tmpfs="$1" + if mount | grep -q "$tmpfs"; then + umount "$tmpfs" || : + else + rm -rf "$tmpfs" + fi +} + +move_swi_to_tmpfs() { + local oldswi="$1" + local tmpfs="$(get_tmpfs "$swi_tmpfs")" + local newswi="$tmpfs/$(basename "$oldswi")" mv "$oldswi" "$newswi" echo "$newswi" @@ -146,9 +251,7 @@ move_swi_to_tmpfs() { cleanup_swi_tmpfs() { rm -f "$swipath" - if mount | grep -q "$swi_tmpfs"; then - umount "$swi_tmpfs" || : - fi + clean_tmpfs "$(dirname "$swipath")" } extract_image() { @@ -156,7 +259,7 @@ extract_image() { info "Moving swi to a tmpfs" ## Avoid problematic flash usage spike on older systems, also improves I/O - swipath="$(move_swi_to_tmpfs $swipath)" + swipath="$(move_swi_to_tmpfs "$swipath")" info "Extracting swi content" ## Unzip the image except boot0 and dockerfs archive @@ -169,15 +272,15 @@ extract_image() { ## Unpacking dockerfs delayed ## 1. when disk is vfat as it does not support symbolic link ## 2. when disk is small, expand it into ramfs during initrd - if [ "$rootfs_type" != "vfat" -a x"$docker_inram" != x"on" ]; then - mkdir -p "$image_path/{{ DOCKERFS_DIR }}" + if [ "$rootfs_type" != "vfat" ] && ! cmdline_has docker_inram=on; then + mkdir -p "$image_path/$docker_dir" if [ -n "$install" ]; then TAR_EXTRA_OPTION="--numeric-owner --warning=no-timestamp" fi ## extract docker archive - unzip -oqp "$swipath" "$dockerfs" | tar xzf - -C "$image_path/{{ DOCKERFS_DIR }}" $TAR_EXTRA_OPTION + unzip -oqp "$swipath" "$dockerfs" | tar xzf - -C "$image_path/$docker_dir" $TAR_EXTRA_OPTION else ## save dockerfs archive in the image directory unzip -oq "$swipath" "$dockerfs" -d "$image_path" @@ -185,11 +288,17 @@ extract_image() { fi ## remove installer since it's not needed anymore - info "Remove installer" - cleanup_swi_tmpfs + if $preserve_installer; then + info "Preserving installer under $installer_image_path" + mv "$swipath" "$installer_image_path" + chmod a+r "$installer_image_path" + else + info "Remove installer" + cleanup_swi_tmpfs "$(basename "$swipath")" + fi ## use new reduced-size boot swi - local swi_boot_path="flash:$image_name/{{ ABOOT_BOOT_IMAGE }}" + local swi_boot_path="flash:$image_name/$boot_image" update_boot_config SWI "$swi_boot_path" update_boot_config SWI_DEFAULT "$swi_boot_path" @@ -197,9 +306,43 @@ extract_image() { sync } +extract_image_secureboot() { + info "Extracting necessary swi content" + mkdir "$image_path" + unzip -oq "$swipath" platform/firsttime .imagehash -d "$image_path" + + info "Installing image as $installer_image_path" + mv "$swipath" "$installer_image_path" + chmod a+r "$installer_image_path" + swipath="$installer_image_path" + + local swi_boot_path="flash:$image_name/$installer_image" + update_boot_config SWI "$swi_boot_path" + update_boot_config SWI_DEFAULT "$swi_boot_path" + + sync +} + +prepare_image_secureboot() { + local boot_tmpfs="$(get_tmpfs)" + + info "Extracting boot content in tmpfs" + unzip -oq "$swipath" 'boot/*' -d "$boot_tmpfs" + + info "Generating machine.conf and cmdline" + write_secureboot_configs + + sync + + # override environment variables preventing external tamper on kernel execution + CMDLINE="$(cmdline_echo)" + KERNEL="$(find_first_kernel_under "$boot_tmpfs")" + INITRD="$(find_first_initrd_under "$boot_tmpfs")" +} + write_machine_config() { ## Detect SKU and create a hardware description file - aboot_version=$(grep ^Aboot "$cmdline_base" | sed 's/^.*norcal.-//' | tail -n 1) + aboot_version=$(cmdline_get Aboot | sed 's/^.*norcal.-//') if [ -x /bin/sysinit ]; then aboot_build_date=$(stat -c %y /bin/sysinit | sed 's/ /T/') else @@ -216,21 +359,8 @@ EOF chmod a+r "${target_path}/machine.conf" } -in_array() { - local value="$1" - shift - - for other in $@; do - if [ "$value" = "$other" ]; then - return 0 - fi - done - - return 1 -} - read_system_eeprom() { - if [ -x /bin/readprefdl ]; then + if [ -x /bin/readprefdl ] && [ -f /tmp/.system-prefdl ]; then readprefdl -f /tmp/.system-prefdl -d > $target_path/.system-prefdl elif [ -f /etc/prefdl ]; then cp /etc/prefdl $target_path/.system-prefdl @@ -238,9 +368,9 @@ read_system_eeprom() { fi } -platform_specific() { - local platform="$(sed -nr 's/.*platform=([^ ]+).*/\1/p' "$cmdline_base")" - local sid="$(sed -nr 's/.*sid=([^ ]+).*/\1/p' "$cmdline_base" | sed 's/Ssd$//')" +write_platform_specific_cmdline() { + local platform="$(cmdline_get platform)" + local sid="$(cmdline_get sid | sed 's/Ssd$//')" # set varlog size to 100MB local varlog_size=100 @@ -252,14 +382,14 @@ platform_specific() { # Assuming sid=Cloverdale aboot_machine=arista_7050_qx32 flash_size=2000 - docker_inram=on - echo "modprobe.blacklist=radeon,sp5100_tco acpi=off docker_inram=on" >>/tmp/append + cmdline_add modprobe.blacklist=radeon,sp5100_tco + cmdline_add acpi=off fi if [ "$platform" = "crow" ]; then # Assuming sid=Clearlake aboot_machine=arista_7050_qx32s flash_size=3700 - echo "modprobe.blacklist=radeon,sp5100_tco" >>/tmp/append + cmdline_add modprobe.blacklist=radeon,sp5100_tco fi if [ "$sid" = "Upperlake" ] || [ "$sid" = "UpperlakeES" ]; then aboot_machine=arista_7060_cx32s @@ -276,17 +406,17 @@ platform_specific() { if [ "$sid" = "Alhambra" ]; then aboot_machine=arista_7170_64c flash_size=28000 - echo "hugepages=128" >> /tmp/append + cmdline_add hugepages=128 fi if [ "$sid" = "Mineral" ]; then aboot_machine=arista_7170_32c flash_size=28000 - echo "hugepages=128" >> /tmp/append + cmdline_add hugepages=128 fi if [ "$sid" = "MineralD" ]; then aboot_machine=arista_7170_32cd flash_size=28000 - echo "hugepages=128" >> /tmp/append + cmdline_add hugepages=128 fi if [ "$sid" = "Lodoga" ]; then aboot_machine=arista_7050cx3_32s @@ -317,20 +447,24 @@ platform_specific() { flash_size=7382 fi if in_array "$platform" "rook" "magpie" "woodpecker"; then - echo "tsc=reliable pcie_ports=native" >>/tmp/append - echo "rhash_entries=1 usb-storage.delay_use=0" >>/tmp/append - echo "reassign_prefmem" >> /tmp/append + cmdline_add tsc=reliable + cmdline_add pcie_ports=native + cmdline_add rhash_entries=1 + cmdline_add usb-storage.delay_use=0 + cmdline_add reassign_prefmem fi if in_array "$platform" "rook"; then - echo "iommu=on intel_iommu=on" >>/tmp/append + cmdline_add iommu=on + cmdline_add intel_iommu=on read_system_eeprom fi if in_array "$platform" "crow" "magpie"; then - echo "amd_iommu=off modprobe.blacklist=snd_hda_intel,hdaudio" >> /tmp/append + cmdline_add amd_iommu=off + cmdline_add modprobe.blacklist=snd_hda_intel,hdaudio read_system_eeprom fi if in_array "$platform" "woodpecker"; then - echo "modprobe.blacklist=snd_hda_intel,hdaudio" >> /tmp/append + cmdline_add modprobe.blacklist=snd_hda_intel,hdaudio read_system_eeprom fi @@ -338,90 +472,133 @@ platform_specific() { varlog_size=4096 elif [ $flash_size -ge 3700 ]; then varlog_size=400 + elif [ $flash_size -le 2000 ]; then + # enable docker_inram for switches with less than 2G of flash + cmdline_add docker_inram=on + cmdline_add logs_inram=on fi - echo "varlog_size=$varlog_size" >>/tmp/append - # disable deterministic interface naming - echo "net.ifnames=0" >>/tmp/append + cmdline_add "varlog_size=$varlog_size" } -get_uuid_for() { - local dev="$1" - - if type lsblk 2>&1 > /dev/null; then - lsblk "$dev" -n --output UUID - elif type blkid 2>&1 > /dev/null; then - blkid | grep "^$dev" | sed -n "s/^.* UUID=\"//p" | grep -Eo '[^"]+' - fi -} +write_image_specific_cmdline() { + # security + cmdline_add security=apparmor + cmdline_add apparmor=1 -write_boot_configs() { - if $in_aboot; then - # generate the default kernel parameters for the platform - echo "$append" > $cmdline_base - cat /etc/cmdline | sed "/^\(${bootconfigvars// /\|}\|crashkernel\|loglevel\|ignore_loglevel\)\(\$\|=\)/d;/^\$/d" >> $cmdline_base - parse_environment_config >> $cmdline_base - elif [ ! -f "$cmdline_base" ]; then - # some systems were started with other versions of this script and therefore - # do not have the $cmdline_base file. we assume that we are on Sonic or EOS. - cat /proc/cmdline | sed -E 's/^(.*) rw .*$/\1/' | tr ' ' '\n' > $cmdline_base - fi + # fs configuration + cmdline_add rw - cp $cmdline_base /tmp/append + # disable deterministic interface naming + cmdline_add net.ifnames=0 - platform_specific - echo "rw loop=$image_name/fs.squashfs loopfstype=squashfs apparmor=1 security=apparmor quiet" >> /tmp/append + # verbosity + cmdline_add quiet + # Start showing systemd information from the first failing unit if any. + # systemd.show_status=false or quiet can be used to silence systemd entierly + cmdline_add systemd.show_status=auto # Pass the MAC address to the new kernel as a command line parameter. This makes it # possible to restore the MAC address in the new kernel without requiring driver modifications. if [ -f /sys/class/net/ma1/address ]; then - echo "hwaddr_ma1=$(cat /sys/class/net/ma1/address)" >> /tmp/append + cmdline_add "hwaddr_ma1=$(cat /sys/class/net/ma1/address)" elif [ -f /sys/class/net/eth0/address ]; then - echo "hwaddr_ma1=$(cat /sys/class/net/eth0/address)" >> /tmp/append + cmdline_add "hwaddr_ma1=$(cat /sys/class/net/eth0/address)" else err "Management port not found." fi + # Obtain root partition uuid + local rootdev="$(mount | grep -E "$flash_re" | cut -f1 -d' ')" + local rootfstype="$(mount | grep -E "$flash_re" | cut -f5 -d' ')" + local rootuuid="$(get_uuid_for $rootdev)" + if [ -z "$rootuuid" ] || [ "$rootfstype" = "vfat" ] ; then + cmdline_add "root=$rootdev" + else + cmdline_add "root=UUID=$rootuuid" + fi +} + +write_default_cmdline() { + local delimiter="cmdline-aboot-end" + + cmdline_clear + + if $in_aboot; then + # generate the default kernel parameters for the platform + cat /etc/cmdline | sed "/^\(${bootconfigvars// /\|}\|crashkernel\|loglevel\|ignore_loglevel\)\(\$\|=\)/d;/^\$/d" | cmdline_append + elif grep -q "$delimiter" /proc/cmdline; then + # we are on a recent sonic image using delimiter. extracting the part of the + # cmdline coming from aboot is trivial. + cat /proc/cmdline | sed -E "s/^(.*) $delimiter .*$/\1/" | tr ' ' '\n' | cmdline_append + else + # we are either on SONiC or EOS and the commandline doesn't have a delimiter + # for the Aboot part. Take an educated guess at a right delimiter. + # Subject to breakage if EOS or SONiC cmdline change. + cat /proc/cmdline | sed -E 's/^(.*) rw .*$/\1/' | tr ' ' '\n' | cmdline_append + fi + + cmdline_add "$delimiter" +} + +write_common_configs() { + write_default_cmdline + write_platform_specific_cmdline + write_image_specific_cmdline + write_machine_config +} + +write_secureboot_configs() { + write_common_configs + cmdline_add "loop=$(echo "$installer_image_path" | sed 's/mnt\/flash\///')" + cmdline_add loopfstype=squashfs + cmdline_add "loopoffset=$(unzip -qqf "$installer_image_path" fs.squashfs)" + cmdline_add docker_inram=on + cmdline_add secure_boot_enable=y + cmdline_add aboot.secureboot=enabled + # setting panic= has the side effect of disabling the initrd shell on error + cmdline_add panic=0 +} + +write_regular_configs() { + write_common_configs + cmdline_add "loop=$image_name/fs.squashfs" + cmdline_add loopfstype=squashfs + # use extra parameters from kernel-params hook if the file exists if [ -f "$target_path/$kernel_params" ]; then - cat "$target_path/$kernel_params" >> /tmp/append + cat "$target_path/$kernel_params" | cmdline_append fi - # setting root partition if not overridden by kernel-params - if ! grep -q "root=" /tmp/append; then - rootdev="$(mount | grep -E "$flash_re" | cut -f1 -d' ')" - rootfstype="$(mount | grep -E "$flash_re" | cut -f5 -d' ')" - rootuuid="$(get_uuid_for $rootdev)" - if [ -z "$rootuuid" ] || [ "$rootfstype" = "vfat" ] ; then - echo "root=$rootdev" >> /tmp/append - else - echo "root=UUID=$rootuuid" >> /tmp/append - fi + # FIXME: sonic sometimes adds extra kernel parameters from user space + # this is unsafe but some will be kept as part of the regular boot + if [ -f "$image_path/kernel-cmdline" ]; then + cat "$image_path/kernel-cmdline" | tr ' ' '\n' | grep -E "$cmdline_allowlist" | cmdline_append fi - # setting secure_boot_enable=y when secure boot enabled - [ -f /bin/securebootctl ] && securebootctl secureboot -display | grep -i "Secure Boot enable" -q && echo "secure_boot_enable=y" >> /tmp/append - - mkdir -p "$image_path" - cat /tmp/append > $cmdline_image - [ -s ${target_path}/machine.conf ] || write_machine_config - sync + # FIXME: legacy configuration files used by fast-reboot and eos2sonic + # these should be deprecated over time. + cmdline_echo > "$image_path/kernel-cmdline" + cmdline_echo | sed 's/ cmdline-aboot-end.*$//' > "$target_path/kernel-params-base" } run_kexec() { - local cmdline="$(cat $cmdline_image | tr '\n' ' ') $ENV_EXTRA_CMDLINE" - local kernel="${KERNEL:-$(find $image_path/boot -name 'vmlinuz-*' -type f | head -n 1)}" - local initrd="${INITRD:-$(find $image_path/boot -name 'initrd.img-*' -type f | head -n 1)}" + local cmdline="${CMDLINE:-$(cmdline_echo) $ENV_EXTRA_CMDLINE}" + local kernel="${KERNEL:-$(find_first_kernel_under "$image_path/boot")}" + local initrd="${INITRD:-$(find_first_initrd_under "$image_path/boot")}" if $verbose; then - # show systemd showdown sequence when verbose is set - cmdline="$cmdline systemd.show_status=true" - else - # Start showing systemd information from the first failing unit if any. - # systemd.show_status=false or quiet can be used to silence systemd entierly - cmdline="$cmdline systemd.show_status=auto" + # show systemd showdown sequence when verbose is set + cmdline="$(echo "$cmdline" | sed 's/systemd.show_status=auto/systemd.show_status=true/')" + fi + + if $debug; then + # enable initrd debug as well as kernel verbose output + cmdline="$(echo "$cmdline" | sed 's/ quiet//')" + cmdline="$cmdline debug loglevel=7 log_buf_len=8M printk.devmsg=on" fi + sync kexec --load --initrd="$initrd" --append="$cmdline" "$kernel" [ -z "$testonly" ] || exit 0 @@ -429,21 +606,46 @@ run_kexec() { kexec --exec } -get_sorted_hooks() { - echo $(find "$1" -name '[0-9][0-9]-*' -type f) +secureboot_install() { + if [ -e "$image_path" ]; then + warn "Image folder $image_path already exist, wiping..." + rm -rf "$image_path" + fi + + info "Installing image as $installer_image_path" + extract_image_secureboot } -run_hooks() { - if [ -d "$hook_path/$1" ]; then - for hook in $(get_sorted_hooks "$hook_path/$1"); do - if [ ! -z "$hook" ]; then - info "Running hook $(basename $hook)" - . "$hook" - fi - done - fi +regular_install() { + mkdir -p $image_path + + info "Generating boot-config, machine.conf and cmdline" + write_regular_configs "$image_path" + + info "Installing image under $image_path" + extract_image + + run_hooks post-install +} + +secureboot_boot() { + # boot material is extracted and generated in RAM. + # SONiC starts as a live OS. + info "Preparing image for secureboot" + prepare_image_secureboot + update_next_boot + run_kexec } +regular_boot() { + # boot uses the image installed on the flash + run_hooks pre-kexec + write_regular_configs "$image_path" + update_next_boot + run_kexec +} + + # In Aboot no option will be provided therefore these are the default values to use in_aboot=true do_clean=true @@ -466,35 +668,48 @@ elif [ ! -z "$kexec" ]; then in_aboot=false do_install=false do_clean=false -elif [ $# -ne 0 ]; then - echo "usage: $0 (see code)" - exit 1 fi # Verbosity can be defined by the caller, default to false otherwise verbose=${verbose:-false} +debug=${debug:-false} if [ -f "$target_path/verbose-boot" ] || [ "$(get_boot_config VERBOSE)" = "1" ] || ! $in_aboot; then - verbose=true + verbose=true +fi +if [ -f "$target_path/debug-boot" ] || [ "$(get_boot_config DEBUG)" = "1" ]; then + verbose=true + debug=true fi +# behavioral configuration for secureboot +# can be overidden by passing secureboot=true via env +if [ -z "$secureboot" ]; then + if is_secureboot_enabled; then + secureboot=true + else + secureboot=false + fi +fi + +preserve_installer=false + # enable shell debug mode to get the most verbosity if $verbose; then - set -x + set -x fi # install the image if newer if $do_install; then - # we expect the swi to install to be a non empty file - if [ ! -s "$swipath" ]; then + if ! unzip -l "$swipath" 2>&1 > /dev/null; then err "The swipath= environment variable does not point to a valid SWI" exit 1 fi # check the hash file in the image, and determine to install or just skip - GIT_REVISION=$(unzip -p "$swipath" .imagehash) - LOCAL_IMAGEHASH=$(cat $image_path/.imagehash 2>/dev/null || true) + GIT_REVISION="$(unzip -p "$swipath" .imagehash)" + LOCAL_IMAGEHASH="$(cat $image_path/.imagehash 2>/dev/null || true)" if [ "$GIT_REVISION" != "$LOCAL_IMAGEHASH" ] || [ ! -z "$force" ]; then if $do_clean; then @@ -502,13 +717,11 @@ if $do_install; then clean_flash fi - info "Generating boot-config, machine.conf and cmdline" - write_boot_configs - - info "Installing image under $image_path" - extract_image - - run_hooks post-install + if $secureboot; then + secureboot_install + else + regular_install + fi else info "Using previously installed image" fi @@ -516,7 +729,9 @@ fi # chainloading using kexec if $do_kexec; then - run_hooks pre-kexec - update_next_boot - run_kexec + if $secureboot; then + secureboot_boot + else + regular_boot + fi fi diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index 81d35dd8345d..a335e81e194c 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -11,18 +11,37 @@ case $1 in ;; esac +docker_inram=false +logs_inram=false +secureboot=false +bootloader=generic + +# Extract kernel parameters +for x in $(cat /proc/cmdline); do + case "$x" in + Aboot=*) + bootloader=aboot + ;; + docker_inram=on) + docker_inram=true + ;; + logs_inram=on) + logs_inram=true + ;; + secure_boot_enable=[y1]) + secureboot=true + docker_inram=true + ;; + platform=*) + platform_flag="${x#platform=}" + ;; + esac +done + set_tmpfs_log_partition_size() { varlogsize=128 - # NOTE: certain platforms, when reaching initramfs stage, have a small - # limit of mounting tmpfs partition, potentially due to amount - # of RAM available in this stage. e.g. Arista 7050-qx32[s] and 7060-cx32s - [ X"$aboot_platform" = X"x86_64-arista_7050_qx32" ] && return - [ X"$aboot_platform" = X"x86_64-arista_7050_qx32s" ] && return - [ X"$aboot_platform" = X"x86_64-arista_7060_cx32s" ] && return - [ X"$aboot_platform" = X"x86_64-arista_7060cx2_32s" ] && return - # set varlogsize to existing var-log.ext4 size if [ -f ${rootmnt}/host/disk-img/var-log.ext4 ]; then varlogsize=$(ls -l ${rootmnt}/host/disk-img/var-log.ext4 | awk '{print $5}') @@ -41,13 +60,9 @@ set_tmpfs_log_partition_size() remove_not_in_allowlist_files() { - image_dir=$1 - allowlist_file=${rootmnt}/host/$image_dir/allowlist_paths.conf - - # Return if the secure_boot_enable option is not set - if ! (cat /proc/cmdline | grep -i -q "secure_boot_enable=[y1]"); then - return - fi + local allowlist_file="$1" + local targeted_dir="$2" + local allowlist_pattern_file=/tmp/allowlist_paths.pattern # Return if the allowlist file does not exist if ! test -f "${allowlist_file}"; then @@ -55,28 +70,38 @@ remove_not_in_allowlist_files() exit 1 fi - rw_dir=${rootmnt}/host/$image_dir/rw - # Set the grep pattern file, remove the blank line in config file - allowlist_pattern_file=${rootmnt}/host/$image_dir/allowlist_paths.pattern - awk -v rw_dir="$rw_dir" 'NF {print rw_dir"/"$0"$"}' ${allowlist_file} > $allowlist_pattern_file + awk -v rw_dir="$targeted_dir" 'NF {print rw_dir"/"$0"$"}' ${allowlist_file} > $allowlist_pattern_file # Find the files in the rw folder, and remove the files not in the allowlist - find ${rw_dir} -type f | grep -v -f $allowlist_pattern_file | xargs /bin/rm -f + find ${targeted_dir} -type f | grep -v -f $allowlist_pattern_file | xargs /bin/rm -f rm -f $allowlist_pattern_file } ## Mount the overlay file system: rw layer over squashfs image_dir=$(cat /proc/cmdline | sed -e 's/.*loop=\(\S*\)\/.*/\1/') -mkdir -p ${rootmnt}/host/$image_dir/rw -mkdir -p ${rootmnt}/host/$image_dir/work +rw_dir=${rootmnt}/host/$image_dir/rw +work_dir=${rootmnt}/host/$image_dir/work +mkdir -p "$rw_dir" +mkdir -p "$work_dir" + ## Remove the files not in allowlist in the rw folder -remove_not_in_allowlist_files "$image_dir" +if $secureboot; then + if [ "$bootloader" = "aboot" ]; then + swi_path="${rootmnt}/host/$(sed -E 's/.*loop=([^ ]+).*/\1/' /proc/cmdline)" + unzip -q "$swi_path" allowlist_paths.conf -d /tmp + allowlist_file=/tmp/allowlist_paths.conf + else + allowlist_file=${rootmnt}/host/$image_dir/allowlist_paths.conf + fi + remove_not_in_allowlist_files "$allowlist_file" "$rw_dir" +fi + ## Remove the executable permission for all the files in rw folder except home folder -rw_dir=${rootmnt}/host/$image_dir/rw find ${rw_dir} -type f -not -path ${rw_dir}/home -exec chmod a-x {} + -mount -n -o lowerdir=${rootmnt},upperdir=${rootmnt}/host/$image_dir/rw,workdir=${rootmnt}/host/$image_dir/work -t overlay root-overlay ${rootmnt} +mount -n -o lowerdir=${rootmnt},upperdir=${rw_dir},workdir=${work_dir} -t overlay root-overlay ${rootmnt} + ## Check if the root block device is still there [ -b ${ROOT} ] || mdev -s case "${ROOT}" in @@ -94,7 +119,17 @@ case "${ROOT}" in esac mkdir -p ${rootmnt}/var/lib/docker -if [ -f ${rootmnt}/host/$image_dir/{{ FILESYSTEM_DOCKERFS }} ]; then +if $secureboot; then + mount -t tmpfs -o rw,nodev,size={{ DOCKER_RAMFS_SIZE }} tmpfs ${rootmnt}/var/lib/docker + if [ "$bootloader" = "aboot" ]; then + unzip -qp "$swi_path" dockerfs.tar.gz | tar xz --numeric-owner -C ${rootmnt}/var/lib/docker + ## Boot folder is not extracted during secureboot since content would inherently become unsafe + mkdir -p ${rootmnt}/host/$image_dir/boot + else + echo "secureboot unsupported for bootloader $bootloader" 1>&2 + exit 1 + fi +elif [ -f ${rootmnt}/host/$image_dir/{{ FILESYSTEM_DOCKERFS }} ]; then ## mount tmpfs and extract docker into it mount -t tmpfs -o rw,nodev,size={{ DOCKER_RAMFS_SIZE }} tmpfs ${rootmnt}/var/lib/docker tar xz --numeric-owner -f ${rootmnt}/host/$image_dir/{{ FILESYSTEM_DOCKERFS }} -C ${rootmnt}/var/lib/docker @@ -106,17 +141,12 @@ fi ## Mount the boot directory in the raw partition, bypass the overlay mkdir -p ${rootmnt}/boot mount --bind ${rootmnt}/host/$image_dir/boot ${rootmnt}/boot -## Mount loop device or tmpfs for /var/log -onie_platform="" -aboot_platform="" -if [ -f ${rootmnt}/host/machine.conf ]; then - . ${rootmnt}/host/machine.conf -fi -if [ X"$aboot_platform" = X"x86_64-arista_7050_qx32" ] || - [ X"$aboot_platform" = X"x86_64-arista_7050_qx32s" ] || - [ X"$aboot_platform" = X"x86_64-arista_7060_cx32s" ] -then +## Mount loop device or tmpfs for /var/log +if $logs_inram; then + # NOTE: some platforms, when reaching initramfs stage, have a small + # limit of mounting tmpfs partition, potentially due to amount + # of RAM available in this stage. e.g. Arista 7050-qx32[s] and 7060-cx32s set_tmpfs_log_partition_size mount -t tmpfs -o rw,nosuid,nodev,size=${varlogsize}M tmpfs ${rootmnt}/var/log [ -f ${rootmnt}/host/disk-img/var-log.ext4 ] && rm -rf ${rootmnt}/host/disk-img/var-log.ext4 diff --git a/src/initramfs-tools/Makefile b/src/initramfs-tools/Makefile index faf80b287f0f..9ef8e78f5479 100644 --- a/src/initramfs-tools/Makefile +++ b/src/initramfs-tools/Makefile @@ -15,7 +15,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Patch pushd ./initramfs-tools git checkout $(INITRAMFS_TOOLS_REVISION) - patch -p1 < ../loopback-file-system-support.patch + QUILT_PATCHES=.. quilt push -a # Build the package rm -f debian/*.debhelper.log diff --git a/src/initramfs-tools/loopback-file-offset-support.patch b/src/initramfs-tools/loopback-file-offset-support.patch new file mode 100644 index 000000000000..396e1c92007a --- /dev/null +++ b/src/initramfs-tools/loopback-file-offset-support.patch @@ -0,0 +1,73 @@ +From: Samuel Angebault +Date: Tue, 9 Jun 2020 14:43:31 -0700 +Subject: Add loopback from file support + +By providing the extra loopoffset= parameter, it becomes possible to +mount a rootfs from within the file pointed by loop= at a given offset. +This mechanism uses losetup to create a loopdevice +--- + init | 4 ++++ + initramfs-tools.7 | 5 +++++ + scripts/functions | 8 ++++++++ + 3 files changed, 17 insertions(+) + +diff --git a/init b/init +index fe1005a..5fb054f 100755 +--- a/init ++++ b/init +@@ -52,6 +52,7 @@ export ROOTFSTYPE= + export LOOP= + export LOOPFLAGS= + export LOOPFSTYPE= ++export LOOPOFFSET= + export IP= + export DEVICE= + export BOOT= +@@ -116,6 +117,9 @@ for x in $(cat /proc/cmdline); do + loopfstype=*) + LOOPFSTYPE="${x#loopfstype=}" + ;; ++ loopoffset=*) ++ LOOPOFFSET="${x#loopoffset=}" ++ ;; + nfsroot=*) + # shellcheck disable=SC2034 + NFSROOT="${x#nfsroot=}" +diff --git a/initramfs-tools.7 b/initramfs-tools.7 +index 745e7a0..a5d92b0 100644 +--- a/initramfs-tools.7 ++++ b/initramfs-tools.7 +@@ -66,6 +66,11 @@ set the loop file system mount option string, if applicable. + \fB\fI loopfstype + set the loop file system type, if applicable. + ++.TP ++\fB\fI loopoffset ++set the loop file offset from which to mount the loop, if applicable. ++The default is 0 and requires loop to be defined. ++ + .TP + \fB\fI nfsroot + can be either "auto" to try to get the relevant information from DHCP or a +diff --git a/scripts/functions b/scripts/functions +index a17e740..2bef5cb 100644 +--- a/scripts/functions ++++ b/scripts/functions +@@ -473,6 +473,14 @@ mount_loop_root() + modprobe loop + modprobe "${FSTYPE}" + ++ if [ ! -z "${LOOPOFFSET}" ]; then ++ # create a loop device for the fs within the file ++ loopdev="$(losetup -f)" ++ losetup -o "${LOOPOFFSET:-0}" "${loopdev}" "${loopfile}" || \ ++ panic "ALERT! $loopdev could not be setup using $loopfile" ++ loopfile="$loopdev" ++ fi ++ + # FIXME This has no error checking + if [ -z "${LOOPFLAGS}" ]; then + mount ${roflag} -o loop -t "${FSTYPE}" "$loopfile" "${rootmnt}" +-- +2.26.2 + diff --git a/src/initramfs-tools/series b/src/initramfs-tools/series new file mode 100644 index 000000000000..ba6e8edfacd4 --- /dev/null +++ b/src/initramfs-tools/series @@ -0,0 +1,2 @@ +loopback-file-system-support.patch +loopback-file-offset-support.patch From b48d274f692ce0199c3c34cd3ae8cc67d052454d Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Mon, 22 Jun 2020 15:34:21 -0700 Subject: [PATCH 0826/1427] [docker-dhcp-relay]: convert dhcp-relay docker to buster (#4671) Upgrade isc-dhcp to 4.4.1-2 (buster version) Update libevent dependency for dhcpmon to 2.1-6 Signed-off-by: Joyas Joseph --- dockers/docker-dhcp-relay/Dockerfile.j2 | 2 +- rules/docker-dhcp-relay.mk | 8 +- rules/isc-dhcp.mk | 11 +- src/dhcpmon/debian/control | 2 +- src/isc-dhcp/Makefile | 6 +- ...ion-82-circuit-ID-and-remote-ID-fiel.patch | 71 ++++++--- ...ining-name-of-physical-interface-tha.patch | 8 +- ...ing-port-alias-map-file-to-replace-p.patch | 40 ++--- ...ockets-to-configure-flags-in-debian-.patch | 8 +- ...f-BOOTREQUEST-is-directed-broadcast-.patch | 78 ++++------ src/isc-dhcp/patch/0008-CVE-2017-3144.patch | 47 ------ ...nterfaces-when-discovering-interfac.patch} | 0 .../0008-interface-name-maxlen-crash.patch | 13 -- src/isc-dhcp/patch/0009-CVE-2018-5733.patch | 131 ---------------- src/isc-dhcp/patch/0010-CVE-2018-5732.patch | 144 ------------------ src/isc-dhcp/patch/series | 6 +- 16 files changed, 126 insertions(+), 449 deletions(-) delete mode 100644 src/isc-dhcp/patch/0008-CVE-2017-3144.patch rename src/isc-dhcp/patch/{0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch => 0008-Don-t-skip-down-interfaces-when-discovering-interfac.patch} (100%) delete mode 100644 src/isc-dhcp/patch/0008-interface-name-maxlen-crash.patch delete mode 100644 src/isc-dhcp/patch/0009-CVE-2018-5733.patch delete mode 100644 src/isc-dhcp/patch/0010-CVE-2018-5732.patch diff --git a/dockers/docker-dhcp-relay/Dockerfile.j2 b/dockers/docker-dhcp-relay/Dockerfile.j2 index d3c09f9ba260..49361e97ba18 100644 --- a/dockers/docker-dhcp-relay/Dockerfile.j2 +++ b/dockers/docker-dhcp-relay/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 4c044d5e05a0..50d3d23acf87 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -7,20 +7,18 @@ DOCKER_DHCP_RELAY_DBG = $(DOCKER_DHCP_RELAY_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/$(DOCKER_DHCP_RELAY_STEM) $(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(REDIS_TOOLS) $(SONIC_DHCPMON) -$(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS += $(ISC_DHCP_RELAY_DBG) -$(DOCKER_DHCP_RELAY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_DHCP_RELAY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) -SONIC_STRETCH_DOCKERS += $(DOCKER_DHCP_RELAY) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DHCP_RELAY_DBG) $(DOCKER_DHCP_RELAY)_CONTAINER_NAME = dhcp_relay $(DOCKER_DHCP_RELAY)_RUN_OPT += --privileged -t diff --git a/rules/isc-dhcp.mk b/rules/isc-dhcp.mk index e4bf23355076..3edebfd0dde0 100644 --- a/rules/isc-dhcp.mk +++ b/rules/isc-dhcp.mk @@ -1,12 +1,15 @@ # isc-dhcp packages -ISC_DHCP_VERSION = 4.3.5-2 +ISC_DHCP_VERSION = 4.4.1 +ISC_DHCP_VERSION_FULL = ${ISC_DHCP_VERSION}-2 -export ISC_DHCP_VERSION +export ISC_DHCP_VERSION ISC_DHCP_VERSION_FULL -ISC_DHCP_RELAY = isc-dhcp-relay_$(ISC_DHCP_VERSION)_$(CONFIGURED_ARCH).deb +ISC_DHCP_RELAY = isc-dhcp-relay_$(ISC_DHCP_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(ISC_DHCP_RELAY)_SRC_PATH = $(SRC_PATH)/isc-dhcp SONIC_MAKE_DEBS += $(ISC_DHCP_RELAY) -ISC_DHCP_RELAY_DBG = isc-dhcp-relay-dbgsym_$(ISC_DHCP_VERSION)_$(CONFIGURED_ARCH).deb +ISC_DHCP_RELAY_DBG = isc-dhcp-relay-dbgsym_$(ISC_DHCP_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(ISC_DHCP_RELAY),$(ISC_DHCP_RELAY_DBG))) + +export ISC_DHCP_RELAY ISC_DHCP_RELAY_DBG diff --git a/src/dhcpmon/debian/control b/src/dhcpmon/debian/control index 2f05fda79963..8623428462e3 100644 --- a/src/dhcpmon/debian/control +++ b/src/dhcpmon/debian/control @@ -12,5 +12,5 @@ Package: sonic-dhcpmon Architecture: any Built-Using: ${misc:Built-Using} Depends: libexplain51, - libevent-2.0-5 + libevent-2.1-6 Description: SONiC DHCP Monitor diff --git a/src/isc-dhcp/Makefile b/src/isc-dhcp/Makefile index 45535574ed61..bd957a08a6f5 100644 --- a/src/isc-dhcp/Makefile +++ b/src/isc-dhcp/Makefile @@ -2,8 +2,8 @@ SHELL = /bin/bash .SHELLFLAGS += -e -MAIN_TARGET = isc-dhcp-relay_$(ISC_DHCP_VERSION)_$(CONFIGURED_ARCH).deb -DERIVED_TARGETS = isc-dhcp-relay-dbgsym_$(ISC_DHCP_VERSION)_$(CONFIGURED_ARCH).deb +MAIN_TARGET = $(ISC_DHCP_RELAY) +DERIVED_TARGETS = $(ISC_DHCP_RELAY_DBG) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Remove any stale files @@ -16,7 +16,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Reset HEAD to the commit of the proper tag # NOTE: Using "git checkout " here detaches our HEAD, # which stg doesn't like, so we use this method instead - git reset --hard debian/$(ISC_DHCP_VERSION) + git reset --hard debian/$(ISC_DHCP_VERSION_FULL) # Apply patches stg init diff --git a/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch b/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch index a796845e516b..e6d09dedc711 100644 --- a/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch +++ b/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch @@ -8,7 +8,7 @@ Subject: [PATCH] Customizable Option 82 circuit ID and remote ID fields 1 file changed, 147 insertions(+), 24 deletions(-) diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 344cee7..7b4c1ef 100644 +index 0cb2ef6..418b943 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -75,6 +75,8 @@ int bad_circuit_id = 0; /* Circuit ID option in matching RAI option @@ -19,8 +19,8 @@ index 344cee7..7b4c1ef 100644 +const char *agent_remote_id_fmt = NULL; /* Remote ID custom format string. */ int max_hop_count = 10; /* Maximum hop count */ - #ifdef DHCPv6 -@@ -148,9 +150,19 @@ static const char url[] = + int no_daemon = 0; +@@ -151,10 +153,20 @@ static const char url[] = char *progname; @@ -35,35 +35,66 @@ index 344cee7..7b4c1ef 100644 +" %%I DHCP relay agent IP Address\n" \ + #ifdef DHCPv6 + #ifdef RELAY_PORT + #define DHCRELAY_USAGE \ +-"Usage: %s [-4] [-d] [-q] [-a] [-D]\n" \ ++"Usage: %s [-4] [-d] [-q] [-a ] [-D]\n"\ + " [-A ] [-c ]\n" \ + " [-p | -rp ]\n" \ + " [-pf ] [--no-pid]\n"\ +@@ -171,11 +183,11 @@ char *progname; + " -l lower0 [ ... -l lowerN]\n" \ + " -u upper0 [ ... -u upperN]\n" \ + " lower (client link): [address%%]interface[#index]\n" \ +-" upper (server link): [address%%]interface\n\n" \ ++" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE \ + " %s {--version|--help|-h}" + #else #define DHCRELAY_USAGE \ --"Usage: %s [-4] [-d] [-q] [-a] [-D]\n"\ +-"Usage: %s [-4] [-d] [-q] [-a] [-D]\n" \ +"Usage: %s [-4] [-d] [-q] [-a ] [-D]\n"\ " [-A ] [-c ] [-p ]\n" \ " [-pf ] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ -@@ -165,17 +177,18 @@ char *progname; +@@ -190,13 +202,13 @@ char *progname; " -l lower0 [ ... -l lowerN]\n" \ " -u upper0 [ ... -u upperN]\n" \ - " lower (client link): [address%%]interface[#index]\n" \ --" upper (server link): [address%%]interface" -+" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE + " lower (client link): [address%%]interface[#index]\n" \ +-" upper (server link): [address%%]interface\n\n" \ ++" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE \ + " %s {--version|--help|-h}" + #endif + #else /* !DHCPv6 */ + #ifdef RELAY_PORT + #define DHCRELAY_USAGE \ +-"Usage: %s [-d] [-q] [-a] [-D] [-A ] [-c ]\n" \ ++"Usage: %s [-d] [-q] [-a ] [-D] [-A ] [-c ]\n" \ + " [-p | -rp ]\n" \ + " [-pf ] [--no-pid]\n" \ + " [-m append|replace|forward|discard]\n" \ +@@ -204,18 +216,18 @@ char *progname; + " [-iu interface0 [ ... -iu interfaceN]\n" \ + " [-id interface0 [ ... -id interfaceN]\n" \ + " [-U interface]\n" \ +-" server0 [ ... serverN]\n\n" \ ++" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \ + " %s {--version|--help|-h}" #else #define DHCRELAY_USAGE \ -"Usage: %s [-d] [-q] [-a] [-D] [-A ] [-c ] [-p ]\n" \ -+"Usage: %s [-d] [-q] [-a ] [-D]\n" \ -+" [-A ] [-c ] [-p ]\n" \ ++"Usage: %s [-d] [-q] [-a ] [-D] [-A ] [-c ] [-p ]\n" \ " [-pf ] [--no-pid]\n" \ " [-m append|replace|forward|discard]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ " [-iu interface0 [ ... -iu interfaceN]\n" \ " [-id interface0 [ ... -id interfaceN]\n" \ " [-U interface]\n" \ --" server0 [ ... serverN]\n\n" -+" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE +-" server0 [ ... serverN]\n\n" \ ++" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \ + " %s {--version|--help|-h}" #endif - - /*! -@@ -354,6 +367,15 @@ main(int argc, char **argv) { + #endif +@@ -471,6 +483,15 @@ main(int argc, char **argv) { local_family_set = 1; local_family = AF_INET; #endif @@ -79,7 +110,7 @@ index 344cee7..7b4c1ef 100644 add_agent_options = 1; } else if (!strcmp(argv[i], "-A")) { #ifdef DHCPv6 -@@ -1050,6 +1072,81 @@ find_interface_by_agent_option(struct dhcp_packet *packet, +@@ -1171,6 +1192,81 @@ find_interface_by_agent_option(struct dhcp_packet *packet, return (-1); } @@ -161,7 +192,7 @@ index 344cee7..7b4c1ef 100644 /* * Examine a packet to see if it's a candidate to have a Relay * Agent Information option tacked onto its tail. If it is, tack -@@ -1059,9 +1156,12 @@ static int +@@ -1180,9 +1276,12 @@ static int add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, unsigned length, struct in_addr giaddr) { int is_dhcp = 0, mms; @@ -175,7 +206,7 @@ index 344cee7..7b4c1ef 100644 /* If we're not adding agent options to packets, we can skip this. */ -@@ -1195,17 +1295,40 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, +@@ -1316,17 +1415,40 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, op = sp; #endif @@ -227,7 +258,7 @@ index 344cee7..7b4c1ef 100644 } if (adding_link_select) { -@@ -1224,7 +1347,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, +@@ -1351,7 +1473,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, * If not, forward without adding the option. */ if (max - sp >= optlen + 3) { @@ -236,7 +267,7 @@ index 344cee7..7b4c1ef 100644 /* Okay, cons up *our* Relay Agent Information option. */ *sp++ = DHO_DHCP_AGENT_OPTIONS; -@@ -1232,16 +1355,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, +@@ -1359,16 +1481,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, /* Copy in the circuit id... */ *sp++ = RAI_CIRCUIT_ID; diff --git a/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch b/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch index fd9ff420d970..af3052e4b088 100644 --- a/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch +++ b/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch @@ -9,10 +9,10 @@ Subject: [PATCH] Support for obtaining name of physical interface that is a 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 4659660..0f7d658 100644 +index db1af9c..f2418e8 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c -@@ -1072,6 +1072,47 @@ find_interface_by_agent_option(struct dhcp_packet *packet, +@@ -1192,6 +1192,47 @@ find_interface_by_agent_option(struct dhcp_packet *packet, return (-1); } @@ -60,7 +60,7 @@ index 4659660..0f7d658 100644 /* * Format the message that will be used by circuit_id and remote_id */ -@@ -1104,8 +1145,30 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack +@@ -1224,8 +1265,30 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack break; case 'p': /* Name of interface that we received the request from */ @@ -89,7 +89,7 @@ index 4659660..0f7d658 100644 + } + + str = ifname; -+ } ++ } break; case 'P': /* Physical address of interface that we received the request from */ diff --git a/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch b/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch index b564a0822a0c..f26871019b63 100644 --- a/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch +++ b/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch @@ -9,10 +9,10 @@ Subject: [PATCH] Support for loading port alias map file to replace port name 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 0f7d658..797dac6 100644 +index 00c81d3..54f132a 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c -@@ -126,6 +126,14 @@ static void setup_streams(void); +@@ -129,6 +129,14 @@ static void setup_streams(void); char *dhcrelay_sub_id = NULL; #endif @@ -27,7 +27,7 @@ index 0f7d658..797dac6 100644 static void do_relay4(struct interface_info *, struct dhcp_packet *, unsigned int, unsigned int, struct iaddr, struct hardware *); -@@ -140,6 +148,10 @@ static int strip_relay_agent_options(struct interface_info *, +@@ -143,6 +151,10 @@ static int strip_relay_agent_options(struct interface_info *, static void request_v4_interface(const char* name, int flags); @@ -36,9 +36,9 @@ index 0f7d658..797dac6 100644 +static void free_interface_alias_map(void); + static const char copyright[] = - "Copyright 2004-2016 Internet Systems Consortium."; + "Copyright 2004-2018 Internet Systems Consortium."; static const char arr[] = "All rights reserved."; -@@ -155,7 +167,7 @@ char *progname; +@@ -158,7 +170,7 @@ char *progname; "\n" \ " %%%% A single %%\n" \ " %%h Hostname of device\n" \ @@ -47,23 +47,23 @@ index 0f7d658..797dac6 100644 " %%P Hardware address of interface that generated the request\n" \ " %%C Client hardware address\n" \ " %%I DHCP relay agent IP Address\n" \ -@@ -166,6 +178,7 @@ char *progname; - " [-A ] [-c ] [-p ]\n" \ +@@ -171,6 +183,7 @@ char *progname; + " [-p | -rp ]\n" \ " [-pf ] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ +" [--name-alias-map-file ]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ " [-iu interface0 [ ... -iu interfaceN]\n" \ " [-id interface0 [ ... -id interfaceN]\n" \ -@@ -173,6 +186,7 @@ char *progname; - " server0 [ ... serverN]\n\n" \ - " %s -6 [-d] [-q] [-I] [-c ] [-p ]\n" \ +@@ -179,6 +192,7 @@ char *progname; + " %s -6 [-d] [-q] [-I] [-c ]\n" \ + " [-p | -rp ]\n" \ " [-pf ] [--no-pid]\n" \ +" [--name-alias-map-file ]\n" \ " [-s ]\n" \ " -l lower0 [ ... -l lowerN]\n" \ " -u upper0 [ ... -u upperN]\n" \ -@@ -503,6 +517,11 @@ main(int argc, char **argv) { +@@ -619,6 +633,11 @@ main(int argc, char **argv) { no_dhcrelay_pid = ISC_TRUE; } else if (!strcmp(argv[i], "--no-pid")) { no_pid_file = ISC_TRUE; @@ -72,10 +72,10 @@ index 0f7d658..797dac6 100644 + usage(use_noarg, argv[i-1]); + if (load_interface_alias_map(argv[i]) != 0) + log_fatal("Failed to load interface name-alias map."); - } else if (!strcmp(argv[i], "--version")) { - log_info("isc-dhcrelay-%s", PACKAGE_VERSION); - exit(0); -@@ -726,6 +745,7 @@ main(int argc, char **argv) { + } else if (argv[i][0] == '-') { + usage("Unknown command: %s", argv[i]); + } else { +@@ -841,6 +860,7 @@ main(int argc, char **argv) { dispatch(); /* In fact dispatch() never returns. */ @@ -83,7 +83,7 @@ index 0f7d658..797dac6 100644 return (0); } -@@ -1151,6 +1171,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack +@@ -1271,6 +1291,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack */ if (packet->htype && !packet->giaddr.s_addr) { int ret = 0, vlanid = 0; @@ -91,7 +91,7 @@ index 0f7d658..797dac6 100644 ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr), ifname, -@@ -1167,6 +1188,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack +@@ -1287,6 +1308,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack strncpy(ifname, ip->name, IFNAMSIZ); } @@ -105,12 +105,12 @@ index 0f7d658..797dac6 100644 + // ifname, ifalias, print_hw_addr (packet->htype, packet->hlen, packet->chaddr)); + + strncpy(ifname, ifalias, IFNAMSIZ); -+ } ++ } + str = ifname; - } + } break; -@@ -2096,3 +2129,73 @@ void request_v4_interface(const char* name, int flags) { +@@ -2313,3 +2346,73 @@ void request_v4_interface(const char* name, int flags) { interface_snorf(tmp, (INTERFACE_REQUESTED | flags)); interface_dereference(&tmp, MDL); } diff --git a/src/isc-dhcp/patch/0005-Add-enable-use-sockets-to-configure-flags-in-debian-.patch b/src/isc-dhcp/patch/0005-Add-enable-use-sockets-to-configure-flags-in-debian-.patch index 7c39f977bb3b..7e9bcc30fb89 100644 --- a/src/isc-dhcp/patch/0005-Add-enable-use-sockets-to-configure-flags-in-debian-.patch +++ b/src/isc-dhcp/patch/0005-Add-enable-use-sockets-to-configure-flags-in-debian-.patch @@ -9,15 +9,15 @@ Subject: [PATCH 1/3] Add --enable-use-sockets to configure flags in 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules -index 114606b..9919237 100755 +index d3fcc1d..2a7219d 100755 --- a/debian/rules +++ b/debian/rules -@@ -23,7 +23,7 @@ CFLAGS+=-D_PATH_DHCLIENT_CONF='\"/etc/dhcp/dhclient.conf\"' +@@ -24,7 +24,7 @@ CFLAGS+=-D_PATH_DHCLIENT_CONF='\"/etc/dhcp/dhclient.conf\"' CFLAGS+=-D_PATH_DHCLIENT_DB='\"$(LEASE_PATH)/dhclient.leases\"' CFLAGS+=-D_PATH_DHCLIENT6_DB='\"$(LEASE_PATH)/dhclient6.leases\"' --CONFFLAGS=--prefix=/usr --enable-log-pid --enable-paranoia -+CONFFLAGS=--prefix=/usr --enable-log-pid --enable-paranoia --enable-use-sockets +-CONFFLAGS=--prefix=/usr --with-libbind=/usr --enable-log-pid --enable-paranoia ++CONFFLAGS=--prefix=/usr --with-libbind=/usr --enable-log-pid --enable-paranoia --enable-use-sockets # cross-architecture building ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE)) diff --git a/src/isc-dhcp/patch/0007-If-destination-of-BOOTREQUEST-is-directed-broadcast-.patch b/src/isc-dhcp/patch/0007-If-destination-of-BOOTREQUEST-is-directed-broadcast-.patch index e64f8439e2a2..bf24e448ea1a 100644 --- a/src/isc-dhcp/patch/0007-If-destination-of-BOOTREQUEST-is-directed-broadcast-.patch +++ b/src/isc-dhcp/patch/0007-If-destination-of-BOOTREQUEST-is-directed-broadcast-.patch @@ -12,52 +12,44 @@ Subject: [PATCH 3/3] If destination of BOOTREQUEST is directed broadcast, 3 files changed, 131 insertions(+), 16 deletions(-) diff --git a/common/discover.c b/common/discover.c -index 8e7f632..73eb8a9 100644 +index 98ac46a..53afecc 100644 --- a/common/discover.c +++ b/common/discover.c -@@ -227,6 +227,7 @@ struct iface_conf_list { +@@ -236,6 +236,7 @@ struct iface_conf_list { struct iface_info { char name[IF_NAMESIZE+1]; /* name of the interface, e.g. "bge0" */ struct sockaddr_storage addr; /* address information */ -+ struct sockaddr_storage netmask; /* netmask information */ ++ struct sockaddr_storage netmask; /* netmask information */ isc_uint64_t flags; /* interface flags, e.g. IFF_LOOPBACK */ }; -@@ -401,6 +402,7 @@ struct iface_conf_list { - struct iface_info { - char name[IFNAMSIZ]; /* name of the interface, e.g. "eth0" */ - struct sockaddr_storage addr; /* address information */ -+ struct sockaddr_storage netmask; /* netmask information */ - isc_uint64_t flags; /* interface flags, e.g. IFF_LOOPBACK */ - }; - -@@ -576,6 +578,17 @@ next_iface4(struct iface_info *info, int *err, struct iface_conf_list *ifaces) { - } - memcpy(&info->addr, &tmp.ifr_addr, sizeof(tmp.ifr_addr)); +@@ -367,6 +368,17 @@ next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) { + } + info->flags = tmp.lifr_flags; -+ if (ioctl(ifaces->sock, SIOCGIFNETMASK, &tmp) < 0) { -+ if (errno == EADDRNOTAVAIL) { -+ continue; -+ } -+ log_error("Error getting netmask " -+ "for '%s'; %m", name); -+ *err = 1; -+ return 0; ++ if (ioctl(ifaces->sock, SIOCGIFNETMASK, &tmp) < 0) { ++ if (errno == EADDRNOTAVAIL) { ++ continue; + } -+ memcpy(&info->netmask, &tmp.ifr_netmask, sizeof(tmp.ifr_netmask)); -+ - memset(&tmp, 0, sizeof(tmp)); - strncpy(tmp.ifr_name, name, sizeof(tmp.ifr_name) - 1); - if (ioctl(ifaces->sock, SIOCGIFFLAGS, &tmp) < 0) { -@@ -780,6 +793,7 @@ struct iface_conf_list { ++ log_error("Error getting netmask " ++ "for '%s'; %m", name); ++ *err = 1; ++ return 0; ++ } ++ memcpy(&info->netmask, &tmp.ifr_netmask, sizeof(tmp.ifr_netmask)); ++ + ifaces->next++; + *err = 0; + return 1; +@@ -410,6 +422,7 @@ struct iface_conf_list { struct iface_info { char name[IFNAMSIZ]; /* name of the interface, e.g. "bge0" */ struct sockaddr_storage addr; /* address information */ -+ struct sockaddr_storage netmask; /* netmask information */ ++ struct sockaddr_storage netmask; /* netmask information */ isc_uint64_t flags; /* interface flags, e.g. IFF_LOOPBACK */ }; -@@ -840,7 +854,8 @@ end_iface_scan(struct iface_conf_list *ifaces) { +@@ -487,7 +500,8 @@ end_iface_scan(struct iface_conf_list *ifaces) { /* XXX: perhaps create drealloc() rather than do it manually */ void add_ipv4_addr_to_interface(struct interface_info *iface, @@ -67,11 +59,10 @@ index 8e7f632..73eb8a9 100644 /* * We don't expect a lot of addresses per IPv4 interface, so * we use 4, as our "chunk size" for collecting addresses. -@@ -851,6 +866,12 @@ add_ipv4_addr_to_interface(struct interface_info *iface, +@@ -498,6 +512,11 @@ add_ipv4_addr_to_interface(struct interface_info *iface, log_fatal("Out of memory saving IPv4 address " "on interface."); } -+ + iface->netmasks = dmalloc(4 * sizeof(struct in_addr), MDL); + if (iface->netmasks == NULL) { + log_fatal("Out of memory saving IPv4 netmask " @@ -80,14 +71,7 @@ index 8e7f632..73eb8a9 100644 iface->address_count = 0; iface->address_max = 4; } else if (iface->address_count >= iface->address_max) { -@@ -863,14 +884,28 @@ add_ipv4_addr_to_interface(struct interface_info *iface, - log_fatal("Out of memory saving IPv4 address " - "on interface."); - } -- memcpy(tmp, -- iface->addresses, -+ memcpy(tmp, -+ iface->addresses, +@@ -515,9 +534,23 @@ add_ipv4_addr_to_interface(struct interface_info *iface, iface->address_max * sizeof(struct in_addr)); dfree(iface->addresses, MDL); iface->addresses = tmp; @@ -95,7 +79,7 @@ index 8e7f632..73eb8a9 100644 + tmp = dmalloc(new_max * sizeof(struct in_addr), MDL); + if (tmp == NULL) { + log_fatal("Out of memory saving IPv4 netmask " -+ "on interface."); ++ "on interface."); + } + memcpy(tmp, + iface->netmasks, @@ -112,7 +96,7 @@ index 8e7f632..73eb8a9 100644 } #ifdef DHCPv6 -@@ -1005,6 +1040,7 @@ discover_interfaces(int state) { +@@ -656,6 +689,7 @@ discover_interfaces(int state) { if ((info.addr.ss_family == AF_INET) && (local_family == AF_INET)) { struct sockaddr_in *a = (struct sockaddr_in*)&info.addr; @@ -120,7 +104,7 @@ index 8e7f632..73eb8a9 100644 struct iaddr addr; /* We don't want the loopback interface. */ -@@ -1019,7 +1055,7 @@ discover_interfaces(int state) { +@@ -670,7 +704,7 @@ discover_interfaces(int state) { if (a->sin_addr.s_addr != htonl(INADDR_ANY)) tmp->configured = 1; @@ -130,10 +114,10 @@ index 8e7f632..73eb8a9 100644 /* invoke the setup hook */ addr.len = 4; diff --git a/includes/dhcpd.h b/includes/dhcpd.h -index 261714d..89bfe82 100644 +index df3da59..2c7f059 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h -@@ -1347,6 +1347,9 @@ struct interface_info { +@@ -1369,6 +1369,9 @@ struct interface_info { struct in_addr *addresses; /* Addresses associated with this * interface. */ @@ -144,7 +128,7 @@ index 261714d..89bfe82 100644 int address_max; /* Size of addresses buffer. */ struct in6_addr *v6addresses; /* IPv6 addresses associated with diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index c9b6d8e..8aac4b3 100644 +index 54f132a..beae977 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -30,6 +30,7 @@ @@ -155,7 +139,7 @@ index c9b6d8e..8aac4b3 100644 #include TIME default_lease_time = 43200; /* 12 hours... */ -@@ -881,20 +882,95 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, +@@ -1001,20 +1002,95 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, /* Otherwise, it's a BOOTREQUEST, so forward it to all the servers. */ for (sp = servers; sp; sp = sp->next) { diff --git a/src/isc-dhcp/patch/0008-CVE-2017-3144.patch b/src/isc-dhcp/patch/0008-CVE-2017-3144.patch deleted file mode 100644 index fe066e177a8c..000000000000 --- a/src/isc-dhcp/patch/0008-CVE-2017-3144.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Thomas Markwalder -Date: Thu, 7 Dec 2017 11:23:36 -0500 -Subject: [master] Plugs a socket descriptor leak in OMAPI -Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=1a6b62fe17a42b00fa234d06b6dfde3d03451894 -Bug: https://bugs.isc.org/Public/Bug/Display.html?id=46767 -Bug-Debian: https://bugs.debian.org/887413 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-3144 - - Merges in rt46767. ---- - -diff --git a/omapip/buffer.c b/omapip/buffer.c -index 6e0621b5..a21f0a80 100644 ---- a/omapip/buffer.c -+++ b/omapip/buffer.c -@@ -565,6 +565,15 @@ isc_result_t omapi_connection_writer (omapi_object_t *h) - omapi_buffer_dereference (&buffer, MDL); - } - } -+ -+ /* If we had data left to write when we're told to disconnect, -+ * we need recall disconnect, now that we're done writing. -+ * See rt46767. */ -+ if (c->out_bytes == 0 && c->state == omapi_connection_disconnecting) { -+ omapi_disconnect (h, 1); -+ return ISC_R_SHUTTINGDOWN; -+ } -+ - return ISC_R_SUCCESS; - } - -diff --git a/omapip/message.c b/omapip/message.c -index ee15d821..37abbd25 100644 ---- a/omapip/message.c -+++ b/omapip/message.c -@@ -339,7 +339,7 @@ isc_result_t omapi_message_unregister (omapi_object_t *mo) - } - - #ifdef DEBUG_PROTOCOL --static const char *omapi_message_op_name(int op) { -+const char *omapi_message_op_name(int op) { - switch (op) { - case OMAPI_OP_OPEN: return "OMAPI_OP_OPEN"; - case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH"; --- -2.16.2 - diff --git a/src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch b/src/isc-dhcp/patch/0008-Don-t-skip-down-interfaces-when-discovering-interfac.patch similarity index 100% rename from src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch rename to src/isc-dhcp/patch/0008-Don-t-skip-down-interfaces-when-discovering-interfac.patch diff --git a/src/isc-dhcp/patch/0008-interface-name-maxlen-crash.patch b/src/isc-dhcp/patch/0008-interface-name-maxlen-crash.patch deleted file mode 100644 index 38d000c1b319..000000000000 --- a/src/isc-dhcp/patch/0008-interface-name-maxlen-crash.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/common/discover.c b/common/discover.c -index 3cd64a7..c85d18c 100644 ---- a/common/discover.c -+++ b/common/discover.c -@@ -547,7 +547,7 @@ next_iface4(struct iface_info *info, int *err, struct iface_conf_list *ifaces) { - log_error("Interface name '%s' too long", name); - return 0; - } -- strncpy(info->name, name, sizeof(info->name) - 1); -+ strncpy(info->name, name, sizeof(info->name)); - - #ifdef ALIAS_NAMED_PERMUTED - /* interface aliases look like "eth0:1" or "wlan1:3" */ diff --git a/src/isc-dhcp/patch/0009-CVE-2018-5733.patch b/src/isc-dhcp/patch/0009-CVE-2018-5733.patch deleted file mode 100644 index 99017fc9839d..000000000000 --- a/src/isc-dhcp/patch/0009-CVE-2018-5733.patch +++ /dev/null @@ -1,131 +0,0 @@ -From: Thomas Markwalder -Date: Fri, 9 Feb 2018 14:46:08 -0500 -Subject: [master] Corrected refcnt loss in option parsing -Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=197b26f25309f947b97a83b8fdfc414b767798f8 -Bug: https://bugs.isc.org/Public/Bug/Display.html?id=47140 -Bug-Debian: https://bugs.debian.org/891785 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-5733 - - Merges in 47140. ---- - ---- a/common/options.c -+++ b/common/options.c -@@ -177,6 +177,8 @@ int parse_option_buffer (options, buffer - - /* If the length is outrageous, the options are bad. */ - if (offset + len > length) { -+ /* Avoid reference count overflow */ -+ option_dereference(&option, MDL); - reason = "option length exceeds option buffer length"; - bogus: - log_error("parse_option_buffer: malformed option " ---- a/common/tests/Makefile.am -+++ b/common/tests/Makefile.am -@@ -10,7 +10,8 @@ ATF_TESTS = - - if HAVE_ATF - --ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest -+ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest \ -+ option_unittest - - alloc_unittest_SOURCES = test_alloc.c $(top_srcdir)/tests/t_api_dhcp.c - alloc_unittest_LDADD = $(ATF_LDFLAGS) -@@ -36,6 +37,14 @@ ns_name_unittest_LDADD += ../libdhcp.a - ../../omapip/libomapi.a $(BINDLIBDIR)/libirs.a \ - $(BINDLIBDIR)/libdns.a $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a - -+option_unittest_SOURCES = option_unittest.c $(top_srcdir)/tests/t_api_dhcp.c -+option_unittest_LDADD = $(ATF_LDFLAGS) -+option_unittest_LDADD += ../libdhcp.@A@ ../../omapip/libomapi.@A@ \ -+ @BINDLIBIRSDIR@/libirs.@A@ \ -+ @BINDLIBDNSDIR@/libdns.@A@ \ -+ @BINDLIBISCCFGDIR@/libisccfg.@A@ \ -+ @BINDLIBISCDIR@/libisc.@A@ -+ - check: $(ATF_TESTS) - @if test $(top_srcdir) != ${top_builddir}; then \ - cp $(top_srcdir)/common/tests/Atffile Atffile; \ ---- /dev/null -+++ b/common/tests/option_unittest.c -@@ -0,0 +1,79 @@ -+/* -+ * Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC") -+ * -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -+ * PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include "dhcpd.h" -+ -+ATF_TC(option_refcnt); -+ -+ATF_TC_HEAD(option_refcnt, tc) -+{ -+ atf_tc_set_md_var(tc, "descr", -+ "Verify option reference count does not overflow."); -+} -+ -+/* This test does a simple check to see if option reference count is -+ * decremented even an error path exiting parse_option_buffer() -+ */ -+ATF_TC_BODY(option_refcnt, tc) -+{ -+ struct option_state *options; -+ struct option *option; -+ unsigned code; -+ int refcnt; -+ unsigned char buffer[3] = { 15, 255, 0 }; -+ -+ initialize_common_option_spaces(); -+ -+ options = NULL; -+ if (!option_state_allocate(&options, MDL)) { -+ atf_tc_fail("can't allocate option state"); -+ } -+ -+ option = NULL; -+ code = 15; /* domain-name */ -+ if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -+ &code, 0, MDL)) { -+ atf_tc_fail("can't find option 15"); -+ } -+ if (option == NULL) { -+ atf_tc_fail("option is NULL"); -+ } -+ refcnt = option->refcnt; -+ -+ buffer[0] = 15; -+ buffer[1] = 255; /* invalid */ -+ buffer[2] = 0; -+ -+ if (parse_option_buffer(options, buffer, 3, &dhcp_universe)) { -+ atf_tc_fail("parse_option_buffer is expected to fail"); -+ } -+ -+ if (refcnt != option->refcnt) { -+ atf_tc_fail("refcnt changed from %d to %d", refcnt, option->refcnt); -+ } -+} -+ -+/* This macro defines main() method that will call specified -+ test cases. tp and simple_test_case names can be whatever you want -+ as long as it is a valid variable identifier. */ -+ATF_TP_ADD_TCS(tp) -+{ -+ ATF_TP_ADD_TC(tp, option_refcnt); -+ -+ return (atf_no_error()); -+} diff --git a/src/isc-dhcp/patch/0010-CVE-2018-5732.patch b/src/isc-dhcp/patch/0010-CVE-2018-5732.patch deleted file mode 100644 index d6c10e2e6532..000000000000 --- a/src/isc-dhcp/patch/0010-CVE-2018-5732.patch +++ /dev/null @@ -1,144 +0,0 @@ -From: Thomas Markwalder -Date: Sat, 10 Feb 2018 12:15:27 -0500 -Subject: [master] Correct buffer overrun in pretty_print_option -Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=c5931725b48b121d232df4ba9e45bc41e0ba114d -Bug: https://bugs.isc.org/Public/Bug/Display.html?id=47139 -Bug-Debian: https://bugs.debian.org/891786 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-5732 - - Merges in rt47139. ---- - -diff --git a/common/options.c b/common/options.c -index 6f23bc15..fc0e0889 100644 ---- a/common/options.c -+++ b/common/options.c -@@ -1776,7 +1776,8 @@ format_min_length(format, oc) - - - /* Format the specified option so that a human can easily read it. */ -- -+/* Maximum pretty printed size */ -+#define MAX_OUTPUT_SIZE 32*1024 - const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - struct option *option; - const unsigned char *data; -@@ -1784,8 +1785,9 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - int emit_commas; - int emit_quotes; - { -- static char optbuf [32768]; /* XXX */ -- static char *endbuf = &optbuf[sizeof(optbuf)]; -+ /* We add 128 byte pad so we don't have to add checks everywhere. */ -+ static char optbuf [MAX_OUTPUT_SIZE + 128]; /* XXX */ -+ static char *endbuf = optbuf + MAX_OUTPUT_SIZE; - int hunksize = 0; - int opthunk = 0; - int hunkinc = 0; -@@ -2211,7 +2213,14 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - log_error ("Unexpected format code %c", - fmtbuf [j]); - } -+ - op += strlen (op); -+ if (op >= endbuf) { -+ log_error ("Option data exceeds" -+ " maximum size %d", MAX_OUTPUT_SIZE); -+ return (""); -+ } -+ - if (dp == data + len) - break; - if (j + 1 < numelem && comma != ':') -diff --git a/common/tests/option_unittest.c b/common/tests/option_unittest.c -index 36236b84..cd52cfb4 100644 ---- a/common/tests/option_unittest.c -+++ b/common/tests/option_unittest.c -@@ -43,7 +43,7 @@ ATF_TC_BODY(option_refcnt, tc) - if (!option_state_allocate(&options, MDL)) { - atf_tc_fail("can't allocate option state"); - } -- -+ - option = NULL; - code = 15; /* domain-name */ - if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -@@ -68,12 +68,75 @@ ATF_TC_BODY(option_refcnt, tc) - } - } - -+ATF_TC(pretty_print_option); -+ -+ATF_TC_HEAD(pretty_print_option, tc) -+{ -+ atf_tc_set_md_var(tc, "descr", -+ "Verify pretty_print_option does not overrun its buffer."); -+} -+ -+ -+/* -+ * This test verifies that pretty_print_option() will not overrun its -+ * internal, static buffer when given large 'x/X' format options. -+ * -+ */ -+ATF_TC_BODY(pretty_print_option, tc) -+{ -+ struct option *option; -+ unsigned code; -+ unsigned char bad_data[32*1024]; -+ unsigned char good_data[] = { 1,2,3,4,5,6 }; -+ int emit_commas = 1; -+ int emit_quotes = 1; -+ const char *output_buf; -+ -+ /* Initialize whole thing to non-printable chars */ -+ memset(bad_data, 0x1f, sizeof(bad_data)); -+ -+ initialize_common_option_spaces(); -+ -+ /* We'll use dhcp_client_identitifer because it happens to be format X */ -+ code = 61; -+ option = NULL; -+ if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -+ &code, 0, MDL)) { -+ atf_tc_fail("can't find option %d", code); -+ } -+ -+ if (option == NULL) { -+ atf_tc_fail("option is NULL"); -+ } -+ -+ /* First we will try a good value we know should fit. */ -+ output_buf = pretty_print_option (option, good_data, sizeof(good_data), -+ emit_commas, emit_quotes); -+ -+ /* Make sure we get what we expect */ -+ if (!output_buf || strcmp(output_buf, "1:2:3:4:5:6")) { -+ atf_tc_fail("pretty_print_option did not return \"\""); -+ } -+ -+ -+ /* Now we'll try a data value that's too large */ -+ output_buf = pretty_print_option (option, bad_data, sizeof(bad_data), -+ emit_commas, emit_quotes); -+ -+ /* Make sure we safely get an error */ -+ if (!output_buf || strcmp(output_buf, "")) { -+ atf_tc_fail("pretty_print_option did not return \"\""); -+ } -+} -+ -+ - /* This macro defines main() method that will call specified - test cases. tp and simple_test_case names can be whatever you want - as long as it is a valid variable identifier. */ - ATF_TP_ADD_TCS(tp) - { - ATF_TP_ADD_TC(tp, option_refcnt); -+ ATF_TP_ADD_TC(tp, pretty_print_option); - - return (atf_no_error()); - } --- -2.16.2 - diff --git a/src/isc-dhcp/patch/series b/src/isc-dhcp/patch/series index ec68967e28b9..169012b0bc0e 100644 --- a/src/isc-dhcp/patch/series +++ b/src/isc-dhcp/patch/series @@ -6,8 +6,4 @@ 0005-Add-enable-use-sockets-to-configure-flags-in-debian-.patch 0006-Bugfix-Ensure-HAVE_SO_BINDTODEVICE-has-a-chance-to-b.patch 0007-If-destination-of-BOOTREQUEST-is-directed-broadcast-.patch -0008-CVE-2017-3144.patch -0009-CVE-2018-5733.patch -0010-CVE-2018-5732.patch -0008-interface-name-maxlen-crash.patch -0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch +0008-Don-t-skip-down-interfaces-when-discovering-interfac.patch From c6dcd7d9a1b6d0c6fe585751048b85123d18dacc Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Mon, 22 Jun 2020 15:38:36 -0700 Subject: [PATCH 0827/1427] [docker-sonic-vs/Dockerfile.j2]: Install new YANG PKGs in VS docker. (#4684) Changes: . Install new YANG PKGs in VS docker. . Install fixed version on other PY PKGs. Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com --- platform/vs/docker-sonic-vs.mk | 3 +++ platform/vs/docker-sonic-vs/Dockerfile.j2 | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index 718534231689..43310073b65d 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -13,6 +13,9 @@ $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS) \ $(DOCKER_SONIC_VS)_PYTHON_DEBS += $(SONIC_UTILS) +$(DOCKER_SONIC_VS)_PYTHON_WHEELS += $(SONIC_YANG_MODELS_PY3) +$(DOCKER_SONIC_VS)_PYTHON_WHEELS += $(SONIC_YANG_MGMT_PY) + ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 0e129884aab9..b670ee26b6b8 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -44,7 +44,8 @@ RUN apt-get install -y net-tools \ tcpdump \ python-scapy \ conntrack \ - iptables + iptables \ + python3-pip RUN pip install setuptools RUN pip install py2_ipaddress @@ -76,6 +77,23 @@ RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return {%- endfor %} {%- endif %} +{% if docker_sonic_vs_whls.strip() %} +# copy all whl PKGs first, +{% for whl in docker_sonic_vs_whls.split(' ') -%} +COPY python-wheels/{{ whl }} python-wheels/ +{% endfor %} + +# install PKGs after copying all PKGs to avoid dependency failure +# use py3 to find python3 package, which is forced by wheel as of now +{%- for whl in docker_sonic_vs_whls.split(' ') %} +{%- if 'py3' in whl %} +RUN pip3 install python-wheels/{{ whl }} +{% else -%} +RUN pip install python-wheels/{{ whl }} +{%- endif %} +{%- endfor %} +{% endif %} + # Clean up RUN apt-get clean -y RUN apt-get autoclean -y From 0d809d0d5987d1c10ba46b595e250e628d690876 Mon Sep 17 00:00:00 2001 From: Sachin Holla <51310506+sachinholla@users.noreply.github.com> Date: Tue, 23 Jun 2020 04:31:55 +0530 Subject: [PATCH 0828/1427] Mgmt reorg -- submodule and build rules for sonic-mgmt-common (#4765) - Why I did it New repo sonic-mgmt-common is introduced for the common translib related code. This commit adds build rules for this new repo. - How I did it Added sonic-mgmt-common submodule Added build rules for the new sonic-mgmt-common repo. It creates two deb packages -- sonic-mgmt-common_1.0.0_{arch}.deb and sonic-mgmt-common-codegen_1.0.0_{arch}.deb. Package cache is enabled. Added dependency on sonic-mgmt-common for mgmt-framework and telemetry debs and dockers. - How to verify it Full build and incremental builds Basic ACL and interface opreations through REST, KLISH CLI and gNMI - Description for the changelog Git submodule and build rules for the new sonic-mgmt-common repo. --- .gitmodules | 3 +++ rules/docker-sonic-mgmt-framework.mk | 1 + rules/docker-telemetry.mk | 1 + rules/sonic-mgmt-common.dep | 12 ++++++++++++ rules/sonic-mgmt-common.mk | 12 ++++++++++++ rules/sonic-mgmt-framework.mk | 4 ++-- rules/telemetry.mk | 4 ++-- src/sonic-mgmt-common | 1 + src/sonic-mgmt-framework | 2 +- src/sonic-telemetry | 2 +- 10 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 rules/sonic-mgmt-common.dep create mode 100644 rules/sonic-mgmt-common.mk create mode 160000 src/sonic-mgmt-common diff --git a/.gitmodules b/.gitmodules index 4fd4bd52be6c..96bb4ed2cda1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -82,3 +82,6 @@ path = src/sonic-restapi url = https://github.com/Azure/sonic-restapi.git branch = master +[submodule "src/sonic-mgmt-common"] + path = src/sonic-mgmt-common + url = https://github.com/Azure/sonic-mgmt-common.git diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk index b0e11c89f510..7f113f760253 100644 --- a/rules/docker-sonic-mgmt-framework.mk +++ b/rules/docker-sonic-mgmt-framework.mk @@ -6,6 +6,7 @@ DOCKER_MGMT_FRAMEWORK_DBG = $(DOCKER_MGMT_FRAMEWORK_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_MGMT_FRAMEWORK)_PATH = $(DOCKERS_PATH)/$(DOCKER_MGMT_FRAMEWORK_STEM) +$(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(SONIC_MGMT_COMMON) $(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK) $(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK_DBG) diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index e4c689bde5d1..761d80a07d5e 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -6,6 +6,7 @@ DOCKER_TELEMETRY_DBG = $(DOCKER_TELEMETRY_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_TELEMETRY)_PATH = $(DOCKERS_PATH)/$(DOCKER_TELEMETRY_STEM) +$(DOCKER_TELEMETRY)_DEPENDS += $(SONIC_MGMT_COMMON) $(DOCKER_TELEMETRY)_DEPENDS += $(REDIS_TOOLS) $(SONIC_TELEMETRY) $(DOCKER_TELEMETRY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) diff --git a/rules/sonic-mgmt-common.dep b/rules/sonic-mgmt-common.dep new file mode 100644 index 000000000000..69db9ac08859 --- /dev/null +++ b/rules/sonic-mgmt-common.dep @@ -0,0 +1,12 @@ + +SPATH := $($(SONIC_MGMT_COMMON)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-mgmt-common.mk rules/sonic-mgmt-common.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_MGMT_COMMON)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_MGMT_COMMON)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_MGMT_COMMON)_DEP_FILES := $(DEP_FILES) +$(SONIC_MGMT_COMMON)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_MGMT_COMMON)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/sonic-mgmt-common.mk b/rules/sonic-mgmt-common.mk new file mode 100644 index 000000000000..cde659484df6 --- /dev/null +++ b/rules/sonic-mgmt-common.mk @@ -0,0 +1,12 @@ +# SONiC mgmt-common package + +MGMT_COMMON_VERSION = 1.0.0 +SONIC_MGMT_COMMON = sonic-mgmt-common_$(MGMT_COMMON_VERSION)_$(CONFIGURED_ARCH).deb +$(SONIC_MGMT_COMMON)_SRC_PATH = $(SRC_PATH)/sonic-mgmt-common +$(SONIC_MGMT_COMMON)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) +$(SONIC_MGMT_COMMON)_RDEPENDS = $(LIBYANG) +SONIC_DPKG_DEBS += $(SONIC_MGMT_COMMON) + +SONIC_MGMT_COMMON_CODEGEN = sonic-mgmt-common-codegen_$(MGMT_COMMON_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(SONIC_MGMT_COMMON),$(SONIC_MGMT_COMMON_CODEGEN))) + diff --git a/rules/sonic-mgmt-framework.mk b/rules/sonic-mgmt-framework.mk index d3536edcfb65..e9a514634850 100644 --- a/rules/sonic-mgmt-framework.mk +++ b/rules/sonic-mgmt-framework.mk @@ -4,8 +4,8 @@ ifeq ($(ENABLE_MGMT_FRAMEWORK), y) SONIC_MGMT_FRAMEWORK = sonic-mgmt-framework_1.0-01_$(CONFIGURED_ARCH).deb $(SONIC_MGMT_FRAMEWORK)_SRC_PATH = $(SRC_PATH)/sonic-mgmt-framework -$(SONIC_MGMT_FRAMEWORK)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) -$(SONIC_MGMT_FRAMEWORK)_RDEPENDS = $(LIBYANG) +$(SONIC_MGMT_FRAMEWORK)_DEPENDS = $(SONIC_MGMT_COMMON) $(SONIC_MGMT_COMMON_CODEGEN) +$(SONIC_MGMT_FRAMEWORK)_RDEPENDS = SONIC_DPKG_DEBS += $(SONIC_MGMT_FRAMEWORK) SONIC_MGMT_FRAMEWORK_DBG = sonic-mgmt-framework-dbg_1.0-01_$(CONFIGURED_ARCH).deb diff --git a/rules/telemetry.mk b/rules/telemetry.mk index 0b4421b11942..392ed4f28680 100644 --- a/rules/telemetry.mk +++ b/rules/telemetry.mk @@ -2,6 +2,6 @@ SONIC_TELEMETRY = sonic-telemetry_0.1_$(CONFIGURED_ARCH).deb $(SONIC_TELEMETRY)_SRC_PATH = $(SRC_PATH)/sonic-telemetry -$(SONIC_TELEMETRY)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) -$(SONIC_TELEMETRY)_RDEPENDS = $(LIBYANG) +$(SONIC_TELEMETRY)_DEPENDS = $(SONIC_MGMT_COMMON) $(SONIC_MGMT_COMMON_CODEGEN) +$(SONIC_TELEMETRY)_RDEPENDS = SONIC_DPKG_DEBS += $(SONIC_TELEMETRY) diff --git a/src/sonic-mgmt-common b/src/sonic-mgmt-common new file mode 160000 index 000000000000..444aa9ac1f57 --- /dev/null +++ b/src/sonic-mgmt-common @@ -0,0 +1 @@ +Subproject commit 444aa9ac1f57b9d92581092a9ea807dc57cb712d diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework index f789b295f4c7..3c3384cec8d1 160000 --- a/src/sonic-mgmt-framework +++ b/src/sonic-mgmt-framework @@ -1 +1 @@ -Subproject commit f789b295f4c775ac303b4370d9380ebba8ac6272 +Subproject commit 3c3384cec8d15e493e6889bff6361a5a280a8811 diff --git a/src/sonic-telemetry b/src/sonic-telemetry index aaa9188fda4b..fa8d49878c7c 160000 --- a/src/sonic-telemetry +++ b/src/sonic-telemetry @@ -1 +1 @@ -Subproject commit aaa9188fda4b6f36dd5da00cdb240933fedae5ce +Subproject commit fa8d49878c7c37e93f7aa7c982b67f0aea8ff440 From 1e81e1da8e0be49f42b257534ec065900f075c59 Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 22 Jun 2020 19:46:52 -0700 Subject: [PATCH 0829/1427] [submodule]: update sonic-swss-common (#4826) * 77d3417 2020-06-22 | [sonic-swss-common] ARMHF warning fixes (#352) (HEAD -> master, origin/master, origin/HEAD) [arheneus@marvell.com] * da8e264 2020-06-21 | [python3]: build python3-swsscommon for python3 support (#355) [lguohan] * 292b08a 2020-06-16 | Changes to support SONiC Gearbox Manager (#347) [Syd Logan] * 58ca4d9 2020-06-10 | Add missed BGP tables into the schema (#351) [pavel-shirshov] * cddfc4e 2020-06-09 | [loglevel] Avoid accessing null ptr in swssloglevel (#349) [Stephen Sun] * 8fce898 2020-06-08 | [schema] update schema with rates and utilization table names (#330) [Mykola F] Signed-off-by: Guohan Lu --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 35bc01a70946..77d34173a515 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 35bc01a709464ad19eda2ae35a605987fe689fa1 +Subproject commit 77d34173a5151a3367d3ce1b8adac3733a24e82c From f7d43173a2cddd714ecd5f71fd1b26119185476d Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Tue, 23 Jun 2020 11:33:44 -0700 Subject: [PATCH 0830/1427] [secureboot] only remove exec bit in secureboot Address issue #4832 --- files/initramfs-tools/union-mount.j2 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index a335e81e194c..ea43eddb9dc3 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -94,11 +94,12 @@ if $secureboot; then else allowlist_file=${rootmnt}/host/$image_dir/allowlist_paths.conf fi + remove_not_in_allowlist_files "$allowlist_file" "$rw_dir" -fi -## Remove the executable permission for all the files in rw folder except home folder -find ${rw_dir} -type f -not -path ${rw_dir}/home -exec chmod a-x {} + + ## Remove the executable permission for all the files in rw folder except home folder + find ${rw_dir} -type f -not -path ${rw_dir}/home -exec chmod a-x {} + +fi mount -n -o lowerdir=${rootmnt},upperdir=${rw_dir},workdir=${work_dir} -t overlay root-overlay ${rootmnt} From 8339d5f4b1b1375a68ac7f746622120b0c239aaf Mon Sep 17 00:00:00 2001 From: kktheballer Date: Tue, 23 Jun 2020 16:36:47 -0700 Subject: [PATCH 0831/1427] [minigraph.py]: Add Tagged Vlan support in Minigraph (#4731) To enable tagged vlan support by minigraph parser. This enables us to generate a config_db file that will enable SONiC device to operate using tagged and untagged vlan. --- src/sonic-config-engine/minigraph.py | 9 ++++++++- .../tests/simple-sample-graph.xml | 9 +++++++++ src/sonic-config-engine/tests/test_cfggen.py | 15 ++++++++++----- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 64ce96182529..79e553e0191d 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -336,15 +336,22 @@ def parse_dpg(dpg, hname): vlan_intfs = [] vlans = {} vlan_members = {} + vlantype_name = "" for vintf in vlanintfs.findall(str(QName(ns, "VlanInterface"))): vintfname = vintf.find(str(QName(ns, "Name"))).text vlanid = vintf.find(str(QName(ns, "VlanID"))).text vintfmbr = vintf.find(str(QName(ns, "AttachTo"))).text + vlantype = vintf.find(str(QName(ns, "Type"))) + if vlantype != None: + vlantype_name = vintf.find(str(QName(ns, "Type"))).text vmbr_list = vintfmbr.split(';') for i, member in enumerate(vmbr_list): vmbr_list[i] = port_alias_map.get(member, member) sonic_vlan_member_name = "Vlan%s" % (vlanid) - vlan_members[(sonic_vlan_member_name, vmbr_list[i])] = {'tagging_mode': 'untagged'} + if vlantype_name == "Tagged": + vlan_members[(sonic_vlan_member_name, vmbr_list[i])] = {'tagging_mode': 'tagged'} + else: + vlan_members[(sonic_vlan_member_name, vmbr_list[i])] = {'tagging_mode': 'untagged'} vlan_attributes = {'vlanid': vlanid} diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index 5ebbaafd9671..b99da804ea32 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -164,6 +164,15 @@ 1000 192.168.0.0/27 + + kk1 + fortyGigE0/12 + 192.0.0.1;192.0.0.2 + 2020 + 2020 + Tagged + 192.168.0.0/28 + diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 66ca26f3250e..cd6372dccdae 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -93,7 +93,8 @@ def test_additional_json_data_level2_key(self): def test_var_json_data(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" --var-json VLAN_MEMBER' output = self.run_script(argument) - self.assertEqual(output.strip(), '{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "untagged"\n }\n}') + self.assertEqual(output.strip(), '{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "untagged"\n },' + ' \n "Vlan2020|Ethernet12": {\n "tagging_mode": "tagged"\n }\n}') def test_read_yaml(self): argument = '-v yml_item -y ' + os.path.join(self.test_dir, 'test.yml') @@ -141,12 +142,16 @@ def test_minigraph_interfaces(self): def test_minigraph_vlans(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}}") + self.assertEqual(output.strip(), + "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}, " + "'Vlan2020': {'alias': 'kk1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '2020'}}") + def test_minigraph_vlan_members(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN_MEMBER' output = self.run_script(argument) - self.assertEqual(output.strip(), "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}}") + self.assertEqual(output.strip(), "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}, " + "('Vlan2020', 'Ethernet12'): {'tagging_mode': 'tagged'}}") def test_minigraph_vlan_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' @@ -228,7 +233,7 @@ def test_minigraph_ethernet_interfaces(self): self.assertEqual(output.strip(), "{'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}") argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet12\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '33,34,35,36', 'fec': 'rs', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'pfc_asym': 'off', 'speed': '100000', 'description': 'Interface description'}") + self.assertEqual(output.strip(), "{'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}") def test_minigraph_extra_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT"' @@ -254,7 +259,7 @@ def test_minigraph_extra_ethernet_interfaces(self): "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " - "'Ethernet12': {'lanes': '33,34,35,36', 'fec': 'rs', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'pfc_asym': 'off', 'speed': '100000', 'description': 'Interface description'}, " + "'Ethernet12': {'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}, " "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " From 563a0fd21e0099229926f10481fa91adca083fc6 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Wed, 24 Jun 2020 08:21:36 +0800 Subject: [PATCH 0832/1427] [Mellanox] Change port index in port_config.ini to 1-based (#4781) * Change port index in port_config.ini to 1-based * Add default port index to port_config.ini, change platform plugins to accept 1-based port index * fix port index in sfp_event.py --- .../ACS-MSN2010/port_config.ini | 44 ++-- .../ACS-MSN2100/port_config.ini | 34 +-- .../ACS-MSN2410/port_config.ini | 114 ++++----- .../ACS-MSN2700/port_config.ini | 66 ++--- .../Mellanox-SN2700-C28D8/port_config.ini | 72 +++--- .../Mellanox-SN2700-D48C8/port_config.ini | 112 ++++---- .../plugins/sfplpmget.py | 2 +- .../plugins/sfplpmset.py | 2 +- .../plugins/sfpreset.py | 2 +- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 8 +- .../ACS-MSN2740/port_config.ini | 66 ++--- .../ACS-MSN3420/port_config.ini | 120 ++++----- .../ACS-MSN3800/port_config.ini | 130 +++++----- .../Mellanox-SN3800-D112C8/port_config.ini | 240 +++++++++--------- .../Mellanox-SN3800-D24C52/port_config.ini | 152 +++++------ .../Mellanox-SN3800-D28C50/port_config.ini | 154 +++++------ .../ACS-MSN4600C/port_config.ini | 128 +++++----- .../ACS-MSN4700/port_config.ini | 64 ++--- .../sonic_platform/chassis.py | 10 +- .../sonic_platform/sfp_event.py | 2 +- 20 files changed, 761 insertions(+), 761 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/port_config.ini b/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/port_config.ini index 2bd7aef02e1f..f9fa81669a13 100644 --- a/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/port_config.ini @@ -1,23 +1,23 @@ # name lanes index -Ethernet0 0 0 -Ethernet4 4 1 -Ethernet8 8 2 -Ethernet12 12 3 -Ethernet16 16 4 -Ethernet20 20 5 -Ethernet24 24 6 -Ethernet28 28 7 -Ethernet32 32 8 -Ethernet36 36 9 -Ethernet40 40 10 -Ethernet44 44 11 -Ethernet48 48 12 -Ethernet52 52 13 -Ethernet56 56 14 -Ethernet60 60 15 -Ethernet64 64 16 -Ethernet68 68 17 -Ethernet72 72,73,74,75 18 -Ethernet76 76,77,78,79 19 -Ethernet80 80,81,82,83 20 -Ethernet84 84,85,86,87 21 +Ethernet0 0 1 +Ethernet4 4 2 +Ethernet8 8 3 +Ethernet12 12 4 +Ethernet16 16 5 +Ethernet20 20 6 +Ethernet24 24 7 +Ethernet28 28 8 +Ethernet32 32 9 +Ethernet36 36 10 +Ethernet40 40 11 +Ethernet44 44 12 +Ethernet48 48 13 +Ethernet52 52 14 +Ethernet56 56 15 +Ethernet60 60 16 +Ethernet64 64 17 +Ethernet68 68 18 +Ethernet72 72,73,74,75 19 +Ethernet76 76,77,78,79 20 +Ethernet80 80,81,82,83 21 +Ethernet84 84,85,86,87 22 diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/port_config.ini b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/port_config.ini index c792a4114b9c..c7ea79bbdbee 100644 --- a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/port_config.ini @@ -1,17 +1,17 @@ -# name lanes -Ethernet0 0,1,2,3 -Ethernet4 4,5,6,7 -Ethernet8 8,9,10,11 -Ethernet12 12,13,14,15 -Ethernet16 16,17,18,19 -Ethernet20 20,21,22,23 -Ethernet24 24,25,26,27 -Ethernet28 28,29,30,31 -Ethernet32 32,33,34,35 -Ethernet36 36,37,38,39 -Ethernet40 40,41,42,43 -Ethernet44 44,45,46,47 -Ethernet48 48,49,50,51 -Ethernet52 52,53,54,55 -Ethernet56 56,57,58,59 -Ethernet60 60,61,62,63 +# name lanes index +Ethernet0 0,1,2,3 1 +Ethernet4 4,5,6,7 2 +Ethernet8 8,9,10,11 3 +Ethernet12 12,13,14,15 4 +Ethernet16 16,17,18,19 5 +Ethernet20 20,21,22,23 6 +Ethernet24 24,25,26,27 7 +Ethernet28 28,29,30,31 8 +Ethernet32 32,33,34,35 9 +Ethernet36 36,37,38,39 10 +Ethernet40 40,41,42,43 11 +Ethernet44 44,45,46,47 12 +Ethernet48 48,49,50,51 13 +Ethernet52 52,53,54,55 14 +Ethernet56 56,57,58,59 15 +Ethernet60 60,61,62,63 16 diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/port_config.ini b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/port_config.ini index c7db66b02274..782949e5706a 100644 --- a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/port_config.ini @@ -1,57 +1,57 @@ -# name lanes -Ethernet0 0 -Ethernet4 4 -Ethernet8 8 -Ethernet12 12 -Ethernet16 16 -Ethernet20 20 -Ethernet24 24 -Ethernet28 28 -Ethernet32 32 -Ethernet36 36 -Ethernet40 40 -Ethernet44 44 -Ethernet48 48 -Ethernet52 52 -Ethernet56 56 -Ethernet60 60 -Ethernet64 64 -Ethernet68 68 -Ethernet72 72 -Ethernet76 76 -Ethernet80 80 -Ethernet84 84 -Ethernet88 88 -Ethernet92 92 -Ethernet96 96 -Ethernet100 100 -Ethernet104 104 -Ethernet108 108 -Ethernet112 112 -Ethernet116 116 -Ethernet120 120 -Ethernet124 124 -Ethernet128 128 -Ethernet132 132 -Ethernet136 136 -Ethernet140 140 -Ethernet144 144 -Ethernet148 148 -Ethernet152 152 -Ethernet156 156 -Ethernet160 160 -Ethernet164 164 -Ethernet168 168 -Ethernet172 172 -Ethernet176 176 -Ethernet180 180 -Ethernet184 184 -Ethernet188 188 -Ethernet192 192,193,194,195 -Ethernet196 196,197,198,199 -Ethernet200 200,201,202,203 -Ethernet204 204,205,206,207 -Ethernet208 208,209,210,211 -Ethernet212 212,213,214,215 -Ethernet216 216,217,218,219 -Ethernet220 220,221,222,223 +# name lanes index +Ethernet0 0 1 +Ethernet4 4 2 +Ethernet8 8 3 +Ethernet12 12 4 +Ethernet16 16 5 +Ethernet20 20 6 +Ethernet24 24 7 +Ethernet28 28 8 +Ethernet32 32 9 +Ethernet36 36 10 +Ethernet40 40 11 +Ethernet44 44 12 +Ethernet48 48 13 +Ethernet52 52 14 +Ethernet56 56 15 +Ethernet60 60 16 +Ethernet64 64 17 +Ethernet68 68 18 +Ethernet72 72 19 +Ethernet76 76 20 +Ethernet80 80 21 +Ethernet84 84 22 +Ethernet88 88 23 +Ethernet92 92 24 +Ethernet96 96 25 +Ethernet100 100 26 +Ethernet104 104 27 +Ethernet108 108 28 +Ethernet112 112 29 +Ethernet116 116 30 +Ethernet120 120 31 +Ethernet124 124 32 +Ethernet128 128 33 +Ethernet132 132 34 +Ethernet136 136 35 +Ethernet140 140 36 +Ethernet144 144 37 +Ethernet148 148 38 +Ethernet152 152 39 +Ethernet156 156 40 +Ethernet160 160 41 +Ethernet164 164 42 +Ethernet168 168 43 +Ethernet172 172 44 +Ethernet176 176 45 +Ethernet180 180 46 +Ethernet184 184 47 +Ethernet188 188 48 +Ethernet192 192,193,194,195 49 +Ethernet196 196,197,198,199 50 +Ethernet200 200,201,202,203 51 +Ethernet204 204,205,206,207 52 +Ethernet208 208,209,210,211 53 +Ethernet212 212,213,214,215 54 +Ethernet216 216,217,218,219 55 +Ethernet220 220,221,222,223 56 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini index 1e1906ff0ef5..c1e59909c0fb 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini @@ -1,33 +1,33 @@ -# name lanes alias -Ethernet0 0,1,2,3 etp1 -Ethernet4 4,5,6,7 etp2 -Ethernet8 8,9,10,11 etp3 -Ethernet12 12,13,14,15 etp4 -Ethernet16 16,17,18,19 etp5 -Ethernet20 20,21,22,23 etp6 -Ethernet24 24,25,26,27 etp7 -Ethernet28 28,29,30,31 etp8 -Ethernet32 32,33,34,35 etp9 -Ethernet36 36,37,38,39 etp10 -Ethernet40 40,41,42,43 etp11 -Ethernet44 44,45,46,47 etp12 -Ethernet48 48,49,50,51 etp13 -Ethernet52 52,53,54,55 etp14 -Ethernet56 56,57,58,59 etp15 -Ethernet60 60,61,62,63 etp16 -Ethernet64 64,65,66,67 etp17 -Ethernet68 68,69,70,71 etp18 -Ethernet72 72,73,74,75 etp19 -Ethernet76 76,77,78,79 etp20 -Ethernet80 80,81,82,83 etp21 -Ethernet84 84,85,86,87 etp22 -Ethernet88 88,89,90,91 etp23 -Ethernet92 92,93,94,95 etp24 -Ethernet96 96,97,98,99 etp25 -Ethernet100 100,101,102,103 etp26 -Ethernet104 104,105,106,107 etp27 -Ethernet108 108,109,110,111 etp28 -Ethernet112 112,113,114,115 etp29 -Ethernet116 116,117,118,119 etp30 -Ethernet120 120,121,122,123 etp31 -Ethernet124 124,125,126,127 etp32 +# name lanes alias index +Ethernet0 0,1,2,3 etp1 1 +Ethernet4 4,5,6,7 etp2 2 +Ethernet8 8,9,10,11 etp3 3 +Ethernet12 12,13,14,15 etp4 4 +Ethernet16 16,17,18,19 etp5 5 +Ethernet20 20,21,22,23 etp6 6 +Ethernet24 24,25,26,27 etp7 7 +Ethernet28 28,29,30,31 etp8 8 +Ethernet32 32,33,34,35 etp9 9 +Ethernet36 36,37,38,39 etp10 10 +Ethernet40 40,41,42,43 etp11 11 +Ethernet44 44,45,46,47 etp12 12 +Ethernet48 48,49,50,51 etp13 13 +Ethernet52 52,53,54,55 etp14 14 +Ethernet56 56,57,58,59 etp15 15 +Ethernet60 60,61,62,63 etp16 16 +Ethernet64 64,65,66,67 etp17 17 +Ethernet68 68,69,70,71 etp18 18 +Ethernet72 72,73,74,75 etp19 19 +Ethernet76 76,77,78,79 etp20 20 +Ethernet80 80,81,82,83 etp21 21 +Ethernet84 84,85,86,87 etp22 22 +Ethernet88 88,89,90,91 etp23 23 +Ethernet92 92,93,94,95 etp24 24 +Ethernet96 96,97,98,99 etp25 25 +Ethernet100 100,101,102,103 etp26 26 +Ethernet104 104,105,106,107 etp27 27 +Ethernet108 108,109,110,111 etp28 28 +Ethernet112 112,113,114,115 etp29 29 +Ethernet116 116,117,118,119 etp30 30 +Ethernet120 120,121,122,123 etp31 31 +Ethernet124 124,125,126,127 etp32 32 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini index 8bc48269d163..653a61ecc23c 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini @@ -1,37 +1,37 @@ # name lanes alias index speed -Ethernet0 0,1,2,3 etp1 0 100000 -Ethernet4 4,5,6,7 etp2 1 100000 -Ethernet8 8,9,10,11 etp3 2 100000 -Ethernet12 12,13,14,15 etp4 3 100000 -Ethernet16 16,17,18,19 etp5 4 100000 -Ethernet20 20,21,22,23 etp6 5 100000 -Ethernet24 24,25,26,27 etp7 6 100000 -Ethernet28 28,29,30,31 etp8 7 100000 -Ethernet32 32,33,34,35 etp9 8 100000 -Ethernet36 36,37,38,39 etp10 9 100000 -Ethernet40 40,41,42,43 etp11 10 100000 -Ethernet44 44,45,46,47 etp12 11 100000 -Ethernet48 48,49,50,51 etp13 12 100000 -Ethernet52 52,53,54,55 etp14 13 100000 -Ethernet56 56,57,58,59 etp15 14 100000 -Ethernet60 60,61,62,63 etp16 15 100000 -Ethernet64 64,65,66,67 etp17 16 100000 -Ethernet68 68,69,70,71 etp18 17 100000 -Ethernet72 72,73,74,75 etp19 18 100000 -Ethernet76 76,77,78,79 etp20 19 100000 -Ethernet80 80,81,82,83 etp21 20 100000 -Ethernet84 84,85,86,87 etp22 21 100000 -Ethernet88 88,89,90,91 etp23 22 100000 -Ethernet92 92,93,94,95 etp24 23 100000 -Ethernet96 96,97,98,99 etp25 24 100000 -Ethernet100 100,101,102,103 etp26 25 100000 -Ethernet104 104,105,106,107 etp27 26 100000 -Ethernet108 108,109,110,111 etp28 27 100000 -Ethernet112 112,113 etp29a 28 50000 -Ethernet114 114,115 etp29b 28 50000 -Ethernet116 116,117 etp30a 29 50000 -Ethernet118 118,119 etp30b 29 50000 -Ethernet120 120,121 etp31a 30 50000 -Ethernet122 122,123 etp31b 30 50000 -Ethernet124 124,125 etp32a 31 50000 -Ethernet126 126,127 etp32b 31 50000 +Ethernet0 0,1,2,3 etp1 1 100000 +Ethernet4 4,5,6,7 etp2 2 100000 +Ethernet8 8,9,10,11 etp3 3 100000 +Ethernet12 12,13,14,15 etp4 4 100000 +Ethernet16 16,17,18,19 etp5 5 100000 +Ethernet20 20,21,22,23 etp6 6 100000 +Ethernet24 24,25,26,27 etp7 7 100000 +Ethernet28 28,29,30,31 etp8 8 100000 +Ethernet32 32,33,34,35 etp9 9 100000 +Ethernet36 36,37,38,39 etp10 10 100000 +Ethernet40 40,41,42,43 etp11 11 100000 +Ethernet44 44,45,46,47 etp12 12 100000 +Ethernet48 48,49,50,51 etp13 13 100000 +Ethernet52 52,53,54,55 etp14 14 100000 +Ethernet56 56,57,58,59 etp15 15 100000 +Ethernet60 60,61,62,63 etp16 16 100000 +Ethernet64 64,65,66,67 etp17 17 100000 +Ethernet68 68,69,70,71 etp18 18 100000 +Ethernet72 72,73,74,75 etp19 19 100000 +Ethernet76 76,77,78,79 etp20 20 100000 +Ethernet80 80,81,82,83 etp21 21 100000 +Ethernet84 84,85,86,87 etp22 22 100000 +Ethernet88 88,89,90,91 etp23 23 100000 +Ethernet92 92,93,94,95 etp24 24 100000 +Ethernet96 96,97,98,99 etp25 25 100000 +Ethernet100 100,101,102,103 etp26 26 100000 +Ethernet104 104,105,106,107 etp27 27 100000 +Ethernet108 108,109,110,111 etp28 28 100000 +Ethernet112 112,113 etp29a 29 50000 +Ethernet114 114,115 etp29b 29 50000 +Ethernet116 116,117 etp30a 30 50000 +Ethernet118 118,119 etp30b 30 50000 +Ethernet120 120,121 etp31a 31 50000 +Ethernet122 122,123 etp31b 31 50000 +Ethernet124 124,125 etp32a 32 50000 +Ethernet126 126,127 etp32b 32 50000 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini index f9f465f1a3ea..830f558fb383 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini @@ -1,57 +1,57 @@ # name lanes alias index speed -Ethernet0 0,1 etp1a 0 50000 -Ethernet2 2,3 etp1b 0 50000 -Ethernet4 4,5 etp2a 1 50000 -Ethernet6 6,7 etp2b 1 50000 -Ethernet8 8,9 etp3a 2 50000 -Ethernet10 10,11 etp3b 2 50000 -Ethernet12 12,13 etp4a 3 50000 -Ethernet14 14,15 etp4b 3 50000 -Ethernet16 16,17 etp5a 4 50000 -Ethernet18 18,19 etp5b 4 50000 -Ethernet20 20,21 etp6a 5 50000 -Ethernet22 22,23 etp6b 5 50000 -Ethernet24 24,25,26,27 etp7 6 100000 -Ethernet28 28,29,30,31 etp8 7 100000 -Ethernet32 32,33,34,35 etp9 8 100000 -Ethernet36 36,37,38,39 etp10 9 100000 -Ethernet40 40,41 etp11a 10 50000 -Ethernet42 42,43 etp11b 10 50000 -Ethernet44 44,45 etp12a 11 50000 -Ethernet46 46,47 etp12b 11 50000 -Ethernet48 48,49 etp13a 12 50000 -Ethernet50 50,51 etp13b 12 50000 -Ethernet52 52,53 etp14a 13 50000 -Ethernet54 54,55 etp14b 13 50000 -Ethernet56 56,57 etp15a 14 50000 -Ethernet58 58,59 etp15b 14 50000 -Ethernet60 60,61 etp16a 15 50000 -Ethernet62 62,63 etp16b 15 50000 -Ethernet64 64,65 etp17a 16 50000 -Ethernet66 66,67 etp17b 16 50000 -Ethernet68 68,69 etp18a 17 50000 -Ethernet70 70,71 etp18b 17 50000 -Ethernet72 72,73 etp19a 18 50000 -Ethernet74 74,75 etp19b 18 50000 -Ethernet76 76,77 etp20a 19 50000 -Ethernet78 78,79 etp20b 19 50000 -Ethernet80 80,81 etp21a 20 50000 -Ethernet82 82,83 etp21b 20 50000 -Ethernet84 84,85 etp22a 21 50000 -Ethernet86 86,87 etp22b 21 50000 -Ethernet88 88,89,90,91 etp23 22 100000 -Ethernet92 92,93,94,95 etp24 23 100000 -Ethernet96 96,97,98,99 etp25 24 100000 -Ethernet100 100,101,102,103 etp26 25 100000 -Ethernet104 104,105 etp27a 26 50000 -Ethernet106 106,107 etp27b 26 50000 -Ethernet108 108,109 etp28a 27 50000 -Ethernet110 110,111 etp28b 27 50000 -Ethernet112 112,113 etp29a 28 50000 -Ethernet114 114,115 etp29b 28 50000 -Ethernet116 116,117 etp30a 29 50000 -Ethernet118 118,119 etp30b 29 50000 -Ethernet120 120,121 etp31a 30 50000 -Ethernet122 122,123 etp31b 30 50000 -Ethernet124 124,125 etp32a 31 50000 -Ethernet126 126,127 etp32b 31 50000 +Ethernet0 0,1 etp1a 1 50000 +Ethernet2 2,3 etp1b 1 50000 +Ethernet4 4,5 etp2a 2 50000 +Ethernet6 6,7 etp2b 2 50000 +Ethernet8 8,9 etp3a 3 50000 +Ethernet10 10,11 etp3b 3 50000 +Ethernet12 12,13 etp4a 4 50000 +Ethernet14 14,15 etp4b 4 50000 +Ethernet16 16,17 etp5a 5 50000 +Ethernet18 18,19 etp5b 5 50000 +Ethernet20 20,21 etp6a 6 50000 +Ethernet22 22,23 etp6b 6 50000 +Ethernet24 24,25,26,27 etp7 7 100000 +Ethernet28 28,29,30,31 etp8 8 100000 +Ethernet32 32,33,34,35 etp9 9 100000 +Ethernet36 36,37,38,39 etp10 10 100000 +Ethernet40 40,41 etp11a 11 50000 +Ethernet42 42,43 etp11b 11 50000 +Ethernet44 44,45 etp12a 12 50000 +Ethernet46 46,47 etp12b 12 50000 +Ethernet48 48,49 etp13a 13 50000 +Ethernet50 50,51 etp13b 13 50000 +Ethernet52 52,53 etp14a 14 50000 +Ethernet54 54,55 etp14b 14 50000 +Ethernet56 56,57 etp15a 15 50000 +Ethernet58 58,59 etp15b 15 50000 +Ethernet60 60,61 etp16a 16 50000 +Ethernet62 62,63 etp16b 16 50000 +Ethernet64 64,65 etp17a 17 50000 +Ethernet66 66,67 etp17b 17 50000 +Ethernet68 68,69 etp18a 18 50000 +Ethernet70 70,71 etp18b 18 50000 +Ethernet72 72,73 etp19a 19 50000 +Ethernet74 74,75 etp19b 19 50000 +Ethernet76 76,77 etp20a 20 50000 +Ethernet78 78,79 etp20b 20 50000 +Ethernet80 80,81 etp21a 21 50000 +Ethernet82 82,83 etp21b 21 50000 +Ethernet84 84,85 etp22a 22 50000 +Ethernet86 86,87 etp22b 22 50000 +Ethernet88 88,89,90,91 etp23 23 100000 +Ethernet92 92,93,94,95 etp24 24 100000 +Ethernet96 96,97,98,99 etp25 25 100000 +Ethernet100 100,101,102,103 etp26 26 100000 +Ethernet104 104,105 etp27a 27 50000 +Ethernet106 106,107 etp27b 27 50000 +Ethernet108 108,109 etp28a 28 50000 +Ethernet110 110,111 etp28b 28 50000 +Ethernet112 112,113 etp29a 29 50000 +Ethernet114 114,115 etp29b 29 50000 +Ethernet116 116,117 etp30a 30 50000 +Ethernet118 118,119 etp30b 30 50000 +Ethernet120 120,121 etp31a 31 50000 +Ethernet122 122,123 etp31b 31 50000 +Ethernet124 124,125 etp32a 32 50000 +Ethernet126 126,127 etp32b 32 50000 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py index 170766e9bce4..a4a53fb099f1 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py @@ -24,7 +24,7 @@ sys.exit(errno.EACCES) # Get SFP module number -sfp_module = int(sys.argv[1]) +sfp_module = int(sys.argv[1]) - 1 # Get MCION mcion = ku_mcion_reg() diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py index f9b35b8e74e7..9fafaa951404 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py @@ -146,7 +146,7 @@ def set_sfp_lpmode(sfp_module, lpm_enable): sys.exit(errno.EACCES); # Get SFP module -sfp_module = int(sys.argv[1]) +sfp_module = int(sys.argv[1]) - 1 # Get all ports at admin up status that related to the SFP module log_port_list = get_log_ports(handle, sfp_module) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py index 69fa2be614c2..2ba6c6d7bc78 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py @@ -24,7 +24,7 @@ sys.exit(errno.EACCES) # Get SFP module number -sfp_module = int(sys.argv[1]) +sfp_module = int(sys.argv[1]) - 1 # Get PMAOS pmaos = ku_pmaos_reg() diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 9b937225b6ff..d0e0b0b619f1 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -36,7 +36,7 @@ GET_PLATFORM_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.platform" # Ethernet <=> sfp -SFP_PORT_NAME_OFFSET = 1 +SFP_PORT_NAME_OFFSET = 0 SFP_PORT_NAME_CONVENTION = "sfp{}" # magic code defnition for port number, qsfp port position of each platform @@ -94,9 +94,9 @@ def get_port_position_tuple_by_platform_name(self): def __init__(self): port_position_tuple = self.get_port_position_tuple_by_platform_name() - self.PORT_START = port_position_tuple[0] - self.QSFP_PORT_START = port_position_tuple[1] - self.PORT_END = port_position_tuple[2] + self.PORT_START = port_position_tuple[0] + 1 + self.QSFP_PORT_START = port_position_tuple[1] + 1 + self.PORT_END = port_position_tuple[2] + 1 self.PORTS_IN_BLOCK = port_position_tuple[3] self.EEPROM_OFFSET = port_position_tuple[4] self.mlnx_sfpd_started = False diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/port_config.ini b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/port_config.ini index 816bb0e94a70..2ef052c68d52 100644 --- a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/port_config.ini @@ -1,33 +1,33 @@ -# name lanes -Ethernet0 0,1,2,3 -Ethernet4 4,5,6,7 -Ethernet8 8,9,10,11 -Ethernet12 12,13,14,15 -Ethernet16 16,17,18,19 -Ethernet20 20,21,22,23 -Ethernet24 24,25,26,27 -Ethernet28 28,29,30,31 -Ethernet32 32,33,34,35 -Ethernet36 36,37,38,39 -Ethernet40 40,41,42,43 -Ethernet44 44,45,46,47 -Ethernet48 48,49,50,51 -Ethernet52 52,53,54,55 -Ethernet56 56,57,58,59 -Ethernet60 60,61,62,63 -Ethernet64 64,65,66,67 -Ethernet68 68,69,70,71 -Ethernet72 72,73,74,75 -Ethernet76 76,77,78,79 -Ethernet80 80,81,82,83 -Ethernet84 84,85,86,87 -Ethernet88 88,89,90,91 -Ethernet92 92,93,94,95 -Ethernet96 96,97,98,99 -Ethernet100 100,101,102,103 -Ethernet104 104,105,106,107 -Ethernet108 108,109,110,111 -Ethernet112 112,113,114,115 -Ethernet116 116,117,118,119 -Ethernet120 120,121,122,123 -Ethernet124 124,125,126,127 +# name lanes index +Ethernet0 0,1,2,3 1 +Ethernet4 4,5,6,7 2 +Ethernet8 8,9,10,11 3 +Ethernet12 12,13,14,15 4 +Ethernet16 16,17,18,19 5 +Ethernet20 20,21,22,23 6 +Ethernet24 24,25,26,27 7 +Ethernet28 28,29,30,31 8 +Ethernet32 32,33,34,35 9 +Ethernet36 36,37,38,39 10 +Ethernet40 40,41,42,43 11 +Ethernet44 44,45,46,47 12 +Ethernet48 48,49,50,51 13 +Ethernet52 52,53,54,55 14 +Ethernet56 56,57,58,59 15 +Ethernet60 60,61,62,63 16 +Ethernet64 64,65,66,67 17 +Ethernet68 68,69,70,71 18 +Ethernet72 72,73,74,75 19 +Ethernet76 76,77,78,79 20 +Ethernet80 80,81,82,83 21 +Ethernet84 84,85,86,87 22 +Ethernet88 88,89,90,91 23 +Ethernet92 92,93,94,95 24 +Ethernet96 96,97,98,99 25 +Ethernet100 100,101,102,103 26 +Ethernet104 104,105,106,107 27 +Ethernet108 108,109,110,111 28 +Ethernet112 112,113,114,115 29 +Ethernet116 116,117,118,119 30 +Ethernet120 120,121,122,123 31 +Ethernet124 124,125,126,127 32 diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini index df63cbe39ac3..38441f21f003 100644 --- a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini @@ -1,61 +1,61 @@ # name lanes alias index -Ethernet0 0 etp1 0 -Ethernet4 4 etp2 1 -Ethernet8 8 etp3 2 -Ethernet12 12 etp4 3 -Ethernet16 16 etp5 4 -Ethernet20 20 etp6 5 -Ethernet24 24 etp7 6 -Ethernet28 28 etp8 7 -Ethernet32 32 etp9 8 -Ethernet36 36 etp10 9 -Ethernet40 40 etp11 10 -Ethernet44 44 etp12 11 -Ethernet48 48 etp13 12 -Ethernet52 52 etp14 13 -Ethernet56 56 etp15 14 -Ethernet60 60 etp16 15 -Ethernet64 64 etp17 16 -Ethernet68 68 etp18 17 -Ethernet72 72 etp19 18 -Ethernet76 76 etp20 19 -Ethernet80 80 etp21 20 -Ethernet84 84 etp22 21 -Ethernet88 88 etp23 22 -Ethernet92 92 etp24 23 -Ethernet96 96 etp25 24 -Ethernet100 100 etp26 25 -Ethernet104 104 etp27 26 -Ethernet108 108 etp28 27 -Ethernet112 112 etp29 28 -Ethernet116 116 etp30 29 -Ethernet120 120 etp31 30 -Ethernet124 124 etp32 31 -Ethernet128 128 etp33 32 -Ethernet132 132 etp34 33 -Ethernet136 136 etp35 34 -Ethernet140 140 etp36 35 -Ethernet144 144 etp37 36 -Ethernet148 148 etp38 37 -Ethernet152 152 etp39 38 -Ethernet156 156 etp40 39 -Ethernet160 160 etp41 40 -Ethernet164 164 etp42 41 -Ethernet168 168 etp43 42 -Ethernet172 172 etp44 43 -Ethernet176 176 etp45 44 -Ethernet180 180 etp46 45 -Ethernet184 184 etp47 46 -Ethernet188 188 etp48 47 -Ethernet192 192,193,194,195 etp49 48 -Ethernet196 196,197,198,199 etp50 49 -Ethernet200 200,201,202,203 etp51 50 -Ethernet204 204,205,206,207 etp52 51 -Ethernet208 208,209,210,211 etp53 52 -Ethernet212 212,213,214,215 etp54 53 -Ethernet216 216,217,218,219 etp55 54 -Ethernet220 220,221,222,223 etp56 55 -Ethernet224 224,225,226,227 etp57 56 -Ethernet228 228,229,230,231 etp58 57 -Ethernet232 232,233,234,235 etp59 58 -Ethernet236 236,237,238,239 etp60 59 +Ethernet0 0 etp1 1 +Ethernet4 4 etp2 2 +Ethernet8 8 etp3 3 +Ethernet12 12 etp4 4 +Ethernet16 16 etp5 5 +Ethernet20 20 etp6 6 +Ethernet24 24 etp7 7 +Ethernet28 28 etp8 8 +Ethernet32 32 etp9 9 +Ethernet36 36 etp10 10 +Ethernet40 40 etp11 11 +Ethernet44 44 etp12 12 +Ethernet48 48 etp13 13 +Ethernet52 52 etp14 14 +Ethernet56 56 etp15 15 +Ethernet60 60 etp16 16 +Ethernet64 64 etp17 17 +Ethernet68 68 etp18 18 +Ethernet72 72 etp19 19 +Ethernet76 76 etp20 20 +Ethernet80 80 etp21 21 +Ethernet84 84 etp22 22 +Ethernet88 88 etp23 23 +Ethernet92 92 etp24 24 +Ethernet96 96 etp25 25 +Ethernet100 100 etp26 26 +Ethernet104 104 etp27 27 +Ethernet108 108 etp28 28 +Ethernet112 112 etp29 29 +Ethernet116 116 etp30 30 +Ethernet120 120 etp31 31 +Ethernet124 124 etp32 32 +Ethernet128 128 etp33 33 +Ethernet132 132 etp34 34 +Ethernet136 136 etp35 35 +Ethernet140 140 etp36 36 +Ethernet144 144 etp37 37 +Ethernet148 148 etp38 38 +Ethernet152 152 etp39 39 +Ethernet156 156 etp40 40 +Ethernet160 160 etp41 41 +Ethernet164 164 etp42 42 +Ethernet168 168 etp43 43 +Ethernet172 172 etp44 44 +Ethernet176 176 etp45 45 +Ethernet180 180 etp46 46 +Ethernet184 184 etp47 47 +Ethernet188 188 etp48 48 +Ethernet192 192,193,194,195 etp49 49 +Ethernet196 196,197,198,199 etp50 50 +Ethernet200 200,201,202,203 etp51 51 +Ethernet204 204,205,206,207 etp52 52 +Ethernet208 208,209,210,211 etp53 53 +Ethernet212 212,213,214,215 etp54 54 +Ethernet216 216,217,218,219 etp55 55 +Ethernet220 220,221,222,223 etp56 56 +Ethernet224 224,225,226,227 etp57 57 +Ethernet228 228,229,230,231 etp58 58 +Ethernet232 232,233,234,235 etp59 59 +Ethernet236 236,237,238,239 etp60 60 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/port_config.ini index db5216ccf24f..d43b11a22eb6 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/port_config.ini @@ -1,65 +1,65 @@ -# name lanes alias -Ethernet0 0,1,2,3 etp1 -Ethernet4 4,5,6,7 etp2 -Ethernet8 8,9,10,11 etp3 -Ethernet12 12,13,14,15 etp4 -Ethernet16 16,17,18,19 etp5 -Ethernet20 20,21,22,23 etp6 -Ethernet24 24,25,26,27 etp7 -Ethernet28 28,29,30,31 etp8 -Ethernet32 32,33,34,35 etp9 -Ethernet36 36,37,38,39 etp10 -Ethernet40 40,41,42,43 etp11 -Ethernet44 44,45,46,47 etp12 -Ethernet48 48,49,50,51 etp13 -Ethernet52 52,53,54,55 etp14 -Ethernet56 56,57,58,59 etp15 -Ethernet60 60,61,62,63 etp16 -Ethernet64 64,65,66,67 etp17 -Ethernet68 68,69,70,71 etp18 -Ethernet72 72,73,74,75 etp19 -Ethernet76 76,77,78,79 etp20 -Ethernet80 80,81,82,83 etp21 -Ethernet84 84,85,86,87 etp22 -Ethernet88 88,89,90,91 etp23 -Ethernet92 92,93,94,95 etp24 -Ethernet96 96,97,98,99 etp25 -Ethernet100 100,101,102,103 etp26 -Ethernet104 104,105,106,107 etp27 -Ethernet108 108,109,110,111 etp28 -Ethernet112 112,113,114,115 etp29 -Ethernet116 116,117,118,119 etp30 -Ethernet120 120,121,122,123 etp31 -Ethernet124 124,125,126,127 etp32 -Ethernet128 128,129,130,131 etp33 -Ethernet132 132,133,134,135 etp34 -Ethernet136 136,137,138,139 etp35 -Ethernet140 140,141,142,143 etp36 -Ethernet144 144,145,146,147 etp37 -Ethernet148 148,149,150,151 etp38 -Ethernet152 152,153,154,155 etp39 -Ethernet156 156,157,158,159 etp40 -Ethernet160 160,161,162,163 etp41 -Ethernet164 164,165,166,167 etp42 -Ethernet168 168,169,170,171 etp43 -Ethernet172 172,173,174,175 etp44 -Ethernet176 176,177,178,179 etp45 -Ethernet180 180,181,182,183 etp46 -Ethernet184 184,185,186,187 etp47 -Ethernet188 188,189,190,191 etp48 -Ethernet192 192,193,194,195 etp49 -Ethernet196 196,197,198,199 etp50 -Ethernet200 200,201,202,203 etp51 -Ethernet204 204,205,206,207 etp52 -Ethernet208 208,209,210,211 etp53 -Ethernet212 212,213,214,215 etp54 -Ethernet216 216,217,218,219 etp55 -Ethernet220 220,221,222,223 etp56 -Ethernet224 224,225,226,227 etp57 -Ethernet228 228,229,230,231 etp58 -Ethernet232 232,233,234,235 etp59 -Ethernet236 236,237,238,239 etp60 -Ethernet240 240,241,242,243 etp61 -Ethernet244 244,245,246,247 etp62 -Ethernet248 248,249,250,251 etp63 -Ethernet252 252,253,254,255 etp64 +# name lanes alias index +Ethernet0 0,1,2,3 etp1 1 +Ethernet4 4,5,6,7 etp2 2 +Ethernet8 8,9,10,11 etp3 3 +Ethernet12 12,13,14,15 etp4 4 +Ethernet16 16,17,18,19 etp5 5 +Ethernet20 20,21,22,23 etp6 6 +Ethernet24 24,25,26,27 etp7 7 +Ethernet28 28,29,30,31 etp8 8 +Ethernet32 32,33,34,35 etp9 9 +Ethernet36 36,37,38,39 etp10 10 +Ethernet40 40,41,42,43 etp11 11 +Ethernet44 44,45,46,47 etp12 12 +Ethernet48 48,49,50,51 etp13 13 +Ethernet52 52,53,54,55 etp14 14 +Ethernet56 56,57,58,59 etp15 15 +Ethernet60 60,61,62,63 etp16 16 +Ethernet64 64,65,66,67 etp17 17 +Ethernet68 68,69,70,71 etp18 18 +Ethernet72 72,73,74,75 etp19 19 +Ethernet76 76,77,78,79 etp20 20 +Ethernet80 80,81,82,83 etp21 21 +Ethernet84 84,85,86,87 etp22 22 +Ethernet88 88,89,90,91 etp23 23 +Ethernet92 92,93,94,95 etp24 24 +Ethernet96 96,97,98,99 etp25 25 +Ethernet100 100,101,102,103 etp26 26 +Ethernet104 104,105,106,107 etp27 27 +Ethernet108 108,109,110,111 etp28 28 +Ethernet112 112,113,114,115 etp29 29 +Ethernet116 116,117,118,119 etp30 30 +Ethernet120 120,121,122,123 etp31 31 +Ethernet124 124,125,126,127 etp32 32 +Ethernet128 128,129,130,131 etp33 33 +Ethernet132 132,133,134,135 etp34 34 +Ethernet136 136,137,138,139 etp35 35 +Ethernet140 140,141,142,143 etp36 36 +Ethernet144 144,145,146,147 etp37 37 +Ethernet148 148,149,150,151 etp38 38 +Ethernet152 152,153,154,155 etp39 39 +Ethernet156 156,157,158,159 etp40 40 +Ethernet160 160,161,162,163 etp41 41 +Ethernet164 164,165,166,167 etp42 42 +Ethernet168 168,169,170,171 etp43 43 +Ethernet172 172,173,174,175 etp44 44 +Ethernet176 176,177,178,179 etp45 45 +Ethernet180 180,181,182,183 etp46 46 +Ethernet184 184,185,186,187 etp47 47 +Ethernet188 188,189,190,191 etp48 48 +Ethernet192 192,193,194,195 etp49 49 +Ethernet196 196,197,198,199 etp50 50 +Ethernet200 200,201,202,203 etp51 51 +Ethernet204 204,205,206,207 etp52 52 +Ethernet208 208,209,210,211 etp53 53 +Ethernet212 212,213,214,215 etp54 54 +Ethernet216 216,217,218,219 etp55 55 +Ethernet220 220,221,222,223 etp56 56 +Ethernet224 224,225,226,227 etp57 57 +Ethernet228 228,229,230,231 etp58 58 +Ethernet232 232,233,234,235 etp59 59 +Ethernet236 236,237,238,239 etp60 60 +Ethernet240 240,241,242,243 etp61 61 +Ethernet244 244,245,246,247 etp62 62 +Ethernet248 248,249,250,251 etp63 63 +Ethernet252 252,253,254,255 etp64 64 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini index 7cb69a141f28..8e40d6bd41ec 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini @@ -1,121 +1,121 @@ # name lanes alias index speed -Ethernet0 0,1 etp1a 0 50000 -Ethernet2 2,3 etp1b 0 50000 -Ethernet4 4,5 etp2a 1 50000 -Ethernet6 6,7 etp2b 1 50000 -Ethernet8 8,9 etp3a 2 50000 -Ethernet10 10,11 etp3b 2 50000 -Ethernet12 12,13 etp4a 3 50000 -Ethernet14 14,15 etp4b 3 50000 -Ethernet16 16,17 etp5a 4 50000 -Ethernet18 18,19 etp5b 4 50000 -Ethernet20 20,21 etp6a 5 50000 -Ethernet22 22,23 etp6b 5 50000 -Ethernet24 24,25 etp7a 6 50000 -Ethernet26 26,27 etp7b 6 50000 -Ethernet28 28,29 etp8a 7 50000 -Ethernet30 30,31 etp8b 7 50000 -Ethernet32 32,33 etp9a 8 50000 -Ethernet34 34,35 etp9b 8 50000 -Ethernet36 36,37 etp10a 9 50000 -Ethernet38 38,39 etp10b 9 50000 -Ethernet40 40,41 etp11a 10 50000 -Ethernet42 42,43 etp11b 10 50000 -Ethernet44 44,45 etp12a 11 50000 -Ethernet46 46,47 etp12b 11 50000 -Ethernet48 48,49 etp13a 12 50000 -Ethernet50 50,51 etp13b 12 50000 -Ethernet52 52,53 etp14a 13 50000 -Ethernet54 54,55 etp14b 13 50000 -Ethernet56 56,57 etp15a 14 50000 -Ethernet58 58,59 etp15b 14 50000 -Ethernet60 60,61 etp16a 15 50000 -Ethernet62 62,63 etp16b 15 50000 -Ethernet64 64,65 etp17a 16 50000 -Ethernet66 66,67 etp17b 16 50000 -Ethernet68 68,69 etp18a 17 50000 -Ethernet70 70,71 etp18b 17 50000 -Ethernet72 72,73 etp19a 18 50000 -Ethernet74 74,75 etp19b 18 50000 -Ethernet76 76,77 etp20a 19 50000 -Ethernet78 78,79 etp20b 19 50000 -Ethernet80 80,81 etp21a 20 50000 -Ethernet82 82,83 etp21b 20 50000 -Ethernet84 84,85 etp22a 21 50000 -Ethernet86 86,87 etp22b 21 50000 -Ethernet88 88,89 etp23a 22 50000 -Ethernet90 90,91 etp23b 22 50000 -Ethernet92 92,93 etp24a 23 50000 -Ethernet94 94,95 etp24b 23 50000 -Ethernet96 96,97,98,99 etp25 24 100000 -Ethernet100 100,101,102,103 etp26 25 100000 -Ethernet104 104,105 etp27a 26 50000 -Ethernet106 106,107 etp27b 26 50000 -Ethernet108 108,109 etp28a 27 50000 -Ethernet110 110,111 etp28b 27 50000 -Ethernet112 112,113,114,115 etp29 28 100000 -Ethernet116 116,117,118,119 etp30 29 100000 -Ethernet120 120,121 etp31a 30 50000 -Ethernet122 122,123 etp31b 30 50000 -Ethernet124 124,125 etp32a 31 50000 -Ethernet126 126,127 etp32b 31 50000 -Ethernet128 128,129,130,131 etp33 32 100000 -Ethernet132 132,133,134,135 etp34 33 100000 -Ethernet136 136,137 etp35a 34 50000 -Ethernet138 138,139 etp35b 34 50000 -Ethernet140 140,141 etp36a 35 50000 -Ethernet142 142,143 etp36b 35 50000 -Ethernet144 144,145,146,147 etp37 36 100000 -Ethernet148 148,149,150,151 etp38 37 100000 -Ethernet152 152,153 etp39a 38 50000 -Ethernet154 154,155 etp39b 38 50000 -Ethernet156 156,157 etp40a 39 50000 -Ethernet158 158,159 etp40b 39 50000 -Ethernet160 160,161 etp41a 40 50000 -Ethernet162 162,163 etp41b 40 50000 -Ethernet164 164,165 etp42a 41 50000 -Ethernet166 166,167 etp42b 41 50000 -Ethernet168 168,169 etp43a 42 50000 -Ethernet170 170,171 etp43b 42 50000 -Ethernet172 172,173 etp44a 43 50000 -Ethernet174 174,175 etp44b 43 50000 -Ethernet176 176,177 etp45a 44 50000 -Ethernet178 178,179 etp45b 44 50000 -Ethernet180 180,181 etp46a 45 50000 -Ethernet182 182,183 etp46b 45 50000 -Ethernet184 184,185 etp47a 46 50000 -Ethernet186 186,187 etp47b 46 50000 -Ethernet188 188,189 etp48a 47 50000 -Ethernet190 190,191 etp48b 47 50000 -Ethernet192 192,193 etp49a 48 50000 -Ethernet194 194,195 etp49b 48 50000 -Ethernet196 196,197 etp50a 49 50000 -Ethernet198 198,199 etp50b 49 50000 -Ethernet200 200,201 etp51a 50 50000 -Ethernet202 202,203 etp51b 50 50000 -Ethernet204 204,205 etp52a 51 50000 -Ethernet206 206,207 etp52b 51 50000 -Ethernet208 208,209 etp53a 52 50000 -Ethernet210 210,211 etp53b 52 50000 -Ethernet212 212,213 etp54a 53 50000 -Ethernet214 214,215 etp54b 53 50000 -Ethernet216 216,217 etp55a 54 50000 -Ethernet218 218,219 etp55b 54 50000 -Ethernet220 220,221 etp56a 55 50000 -Ethernet222 222,223 etp56b 55 50000 -Ethernet224 224,225 etp57a 56 50000 -Ethernet226 226,227 etp57b 56 50000 -Ethernet228 228,229 etp58a 57 50000 -Ethernet230 230,231 etp58b 57 50000 -Ethernet232 232,233 etp59a 58 50000 -Ethernet234 234,235 etp59b 58 50000 -Ethernet236 236,237 etp60a 59 50000 -Ethernet238 238,239 etp60b 59 50000 -Ethernet240 240,241 etp61a 60 50000 -Ethernet242 242,243 etp61b 60 50000 -Ethernet244 244,245 etp62a 61 50000 -Ethernet246 246,247 etp62b 61 50000 -Ethernet248 248,249 etp63a 62 50000 -Ethernet250 250,251 etp63b 62 50000 -Ethernet252 252,253 etp64a 63 50000 -Ethernet254 254,255 etp64b 63 50000 \ No newline at end of file +Ethernet0 0,1 etp1a 1 50000 +Ethernet2 2,3 etp1b 1 50000 +Ethernet4 4,5 etp2a 2 50000 +Ethernet6 6,7 etp2b 2 50000 +Ethernet8 8,9 etp3a 3 50000 +Ethernet10 10,11 etp3b 3 50000 +Ethernet12 12,13 etp4a 4 50000 +Ethernet14 14,15 etp4b 4 50000 +Ethernet16 16,17 etp5a 5 50000 +Ethernet18 18,19 etp5b 5 50000 +Ethernet20 20,21 etp6a 6 50000 +Ethernet22 22,23 etp6b 6 50000 +Ethernet24 24,25 etp7a 7 50000 +Ethernet26 26,27 etp7b 7 50000 +Ethernet28 28,29 etp8a 8 50000 +Ethernet30 30,31 etp8b 8 50000 +Ethernet32 32,33 etp9a 9 50000 +Ethernet34 34,35 etp9b 9 50000 +Ethernet36 36,37 etp10a 10 50000 +Ethernet38 38,39 etp10b 10 50000 +Ethernet40 40,41 etp11a 11 50000 +Ethernet42 42,43 etp11b 11 50000 +Ethernet44 44,45 etp12a 12 50000 +Ethernet46 46,47 etp12b 12 50000 +Ethernet48 48,49 etp13a 13 50000 +Ethernet50 50,51 etp13b 13 50000 +Ethernet52 52,53 etp14a 14 50000 +Ethernet54 54,55 etp14b 14 50000 +Ethernet56 56,57 etp15a 15 50000 +Ethernet58 58,59 etp15b 15 50000 +Ethernet60 60,61 etp16a 16 50000 +Ethernet62 62,63 etp16b 16 50000 +Ethernet64 64,65 etp17a 17 50000 +Ethernet66 66,67 etp17b 17 50000 +Ethernet68 68,69 etp18a 18 50000 +Ethernet70 70,71 etp18b 18 50000 +Ethernet72 72,73 etp19a 19 50000 +Ethernet74 74,75 etp19b 19 50000 +Ethernet76 76,77 etp20a 20 50000 +Ethernet78 78,79 etp20b 20 50000 +Ethernet80 80,81 etp21a 21 50000 +Ethernet82 82,83 etp21b 21 50000 +Ethernet84 84,85 etp22a 22 50000 +Ethernet86 86,87 etp22b 22 50000 +Ethernet88 88,89 etp23a 23 50000 +Ethernet90 90,91 etp23b 23 50000 +Ethernet92 92,93 etp24a 24 50000 +Ethernet94 94,95 etp24b 24 50000 +Ethernet96 96,97,98,99 etp25 25 100000 +Ethernet100 100,101,102,103 etp26 26 100000 +Ethernet104 104,105 etp27a 27 50000 +Ethernet106 106,107 etp27b 27 50000 +Ethernet108 108,109 etp28a 28 50000 +Ethernet110 110,111 etp28b 28 50000 +Ethernet112 112,113,114,115 etp29 29 100000 +Ethernet116 116,117,118,119 etp30 30 100000 +Ethernet120 120,121 etp31a 31 50000 +Ethernet122 122,123 etp31b 31 50000 +Ethernet124 124,125 etp32a 32 50000 +Ethernet126 126,127 etp32b 32 50000 +Ethernet128 128,129,130,131 etp33 33 100000 +Ethernet132 132,133,134,135 etp34 34 100000 +Ethernet136 136,137 etp35a 35 50000 +Ethernet138 138,139 etp35b 35 50000 +Ethernet140 140,141 etp36a 36 50000 +Ethernet142 142,143 etp36b 36 50000 +Ethernet144 144,145,146,147 etp37 37 100000 +Ethernet148 148,149,150,151 etp38 38 100000 +Ethernet152 152,153 etp39a 39 50000 +Ethernet154 154,155 etp39b 39 50000 +Ethernet156 156,157 etp40a 40 50000 +Ethernet158 158,159 etp40b 40 50000 +Ethernet160 160,161 etp41a 41 50000 +Ethernet162 162,163 etp41b 41 50000 +Ethernet164 164,165 etp42a 42 50000 +Ethernet166 166,167 etp42b 42 50000 +Ethernet168 168,169 etp43a 43 50000 +Ethernet170 170,171 etp43b 43 50000 +Ethernet172 172,173 etp44a 44 50000 +Ethernet174 174,175 etp44b 44 50000 +Ethernet176 176,177 etp45a 45 50000 +Ethernet178 178,179 etp45b 45 50000 +Ethernet180 180,181 etp46a 46 50000 +Ethernet182 182,183 etp46b 46 50000 +Ethernet184 184,185 etp47a 47 50000 +Ethernet186 186,187 etp47b 47 50000 +Ethernet188 188,189 etp48a 48 50000 +Ethernet190 190,191 etp48b 48 50000 +Ethernet192 192,193 etp49a 49 50000 +Ethernet194 194,195 etp49b 49 50000 +Ethernet196 196,197 etp50a 50 50000 +Ethernet198 198,199 etp50b 50 50000 +Ethernet200 200,201 etp51a 51 50000 +Ethernet202 202,203 etp51b 51 50000 +Ethernet204 204,205 etp52a 52 50000 +Ethernet206 206,207 etp52b 52 50000 +Ethernet208 208,209 etp53a 53 50000 +Ethernet210 210,211 etp53b 53 50000 +Ethernet212 212,213 etp54a 54 50000 +Ethernet214 214,215 etp54b 54 50000 +Ethernet216 216,217 etp55a 55 50000 +Ethernet218 218,219 etp55b 55 50000 +Ethernet220 220,221 etp56a 56 50000 +Ethernet222 222,223 etp56b 56 50000 +Ethernet224 224,225 etp57a 57 50000 +Ethernet226 226,227 etp57b 57 50000 +Ethernet228 228,229 etp58a 58 50000 +Ethernet230 230,231 etp58b 58 50000 +Ethernet232 232,233 etp59a 59 50000 +Ethernet234 234,235 etp59b 59 50000 +Ethernet236 236,237 etp60a 60 50000 +Ethernet238 238,239 etp60b 60 50000 +Ethernet240 240,241 etp61a 61 50000 +Ethernet242 242,243 etp61b 61 50000 +Ethernet244 244,245 etp62a 62 50000 +Ethernet246 246,247 etp62b 62 50000 +Ethernet248 248,249 etp63a 63 50000 +Ethernet250 250,251 etp63b 63 50000 +Ethernet252 252,253 etp64a 64 50000 +Ethernet254 254,255 etp64b 64 50000 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/port_config.ini index 34cd64b90cec..87d4485963f7 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/port_config.ini @@ -1,77 +1,77 @@ # name lanes alias index speed -Ethernet0 0,1,2,3 etp1 0 100000 -Ethernet4 4,5,6,7 etp2 1 100000 -Ethernet8 8,9,10,11 etp3 2 100000 -Ethernet12 12,13,14,15 etp4 3 100000 -Ethernet16 16,17,18,19 etp5 4 100000 -Ethernet20 20,21,22,23 etp6 5 100000 -Ethernet24 24,25,26,27 etp7 6 100000 -Ethernet28 28,29,30,31 etp8 7 100000 -Ethernet32 32,33 etp9a 8 50000 -Ethernet34 34,35 etp9b 8 50000 -Ethernet36 36,37 etp10a 9 50000 -Ethernet38 38,39 etp10b 9 50000 -Ethernet40 40,41 etp11a 10 50000 -Ethernet42 42,43 etp11b 10 50000 -Ethernet44 44,45 etp12a 11 50000 -Ethernet46 46,47 etp12b 11 50000 -Ethernet48 48,49,50,51 etp13 12 100000 -Ethernet52 52,53,54,55 etp14 13 100000 -Ethernet56 56,57,58,59 etp15 14 100000 -Ethernet60 60,61,62,63 etp16 15 100000 -Ethernet64 64,65,66,67 etp17 16 100000 -Ethernet68 68,69,70,71 etp18 17 100000 -Ethernet72 72,73,74,75 etp19 18 100000 -Ethernet76 76,77,78,79 etp20 19 100000 -Ethernet80 80,81,82,83 etp21 20 100000 -Ethernet84 84,85,86,87 etp22 21 100000 -Ethernet88 88,89,90,91 etp23 22 100000 -Ethernet92 92,93,94,95 etp24 23 100000 -Ethernet96 96,97,98,99 etp25 24 100000 -Ethernet100 100,101,102,103 etp26 25 100000 -Ethernet104 104,105 etp27a 26 50000 -Ethernet106 106,107 etp27b 26 50000 -Ethernet108 108,109 etp28a 27 50000 -Ethernet110 110,111 etp28b 27 50000 -Ethernet112 112,113,114,115 etp29 28 100000 -Ethernet116 116,117,118,119 etp30 29 100000 -Ethernet120 120,121,122,123 etp31 30 100000 -Ethernet124 124,125,126,127 etp32 31 100000 -Ethernet128 128,129,130,131 etp33 32 100000 -Ethernet132 132,133,134,135 etp34 33 100000 -Ethernet136 136,137,138,139 etp35 34 100000 -Ethernet140 140,141,142,143 etp36 35 100000 -Ethernet144 144,145,146,147 etp37 36 100000 -Ethernet148 148,149,150,151 etp38 37 100000 -Ethernet152 152,153,154,155 etp39 38 100000 -Ethernet156 156,157,158,159 etp40 39 100000 -Ethernet160 160,161,162,163 etp41 40 100000 -Ethernet164 164,165,166,167 etp42 41 100000 -Ethernet168 168,169,170,171 etp43 42 100000 -Ethernet172 172,173,174,175 etp44 43 100000 -Ethernet176 176,177 etp45a 44 50000 -Ethernet178 178,179 etp45b 44 50000 -Ethernet180 180,181 etp46a 45 50000 -Ethernet182 182,183 etp46b 45 50000 -Ethernet184 184,185 etp47a 46 50000 -Ethernet186 186,187 etp47b 46 50000 -Ethernet188 188,189 etp48a 47 50000 -Ethernet190 190,191 etp48b 47 50000 -Ethernet192 192,193,194,195 etp49 48 100000 -Ethernet196 196,197,198,199 etp50 49 100000 -Ethernet200 200,201,202,203 etp51 50 100000 -Ethernet204 204,205,206,207 etp52 51 100000 -Ethernet208 208,209,210,211 etp53 52 100000 -Ethernet212 212,213,214,215 etp54 53 100000 -Ethernet216 216,217,218,219 etp55 54 100000 -Ethernet220 220,221,222,223 etp56 55 100000 -Ethernet224 224,225,226,227 etp57 56 100000 -Ethernet228 228,229,230,231 etp58 57 100000 -Ethernet232 232,233,234,235 etp59 58 100000 -Ethernet236 236,237,238,239 etp60 59 100000 -Ethernet240 240,241 etp61a 60 50000 -Ethernet242 242,243 etp61b 60 50000 -Ethernet244 244,245 etp62a 61 50000 -Ethernet246 246,247 etp62b 61 50000 -Ethernet248 248,249,250,251 etp63 62 100000 -Ethernet252 252,253,254,255 etp64 63 100000 \ No newline at end of file +Ethernet0 0,1,2,3 etp1 1 100000 +Ethernet4 4,5,6,7 etp2 2 100000 +Ethernet8 8,9,10,11 etp3 3 100000 +Ethernet12 12,13,14,15 etp4 4 100000 +Ethernet16 16,17,18,19 etp5 5 100000 +Ethernet20 20,21,22,23 etp6 6 100000 +Ethernet24 24,25,26,27 etp7 7 100000 +Ethernet28 28,29,30,31 etp8 8 100000 +Ethernet32 32,33 etp9a 9 50000 +Ethernet34 34,35 etp9b 9 50000 +Ethernet36 36,37 etp10a 10 50000 +Ethernet38 38,39 etp10b 10 50000 +Ethernet40 40,41 etp11a 11 50000 +Ethernet42 42,43 etp11b 11 50000 +Ethernet44 44,45 etp12a 12 50000 +Ethernet46 46,47 etp12b 12 50000 +Ethernet48 48,49,50,51 etp13 13 100000 +Ethernet52 52,53,54,55 etp14 14 100000 +Ethernet56 56,57,58,59 etp15 15 100000 +Ethernet60 60,61,62,63 etp16 16 100000 +Ethernet64 64,65,66,67 etp17 17 100000 +Ethernet68 68,69,70,71 etp18 18 100000 +Ethernet72 72,73,74,75 etp19 19 100000 +Ethernet76 76,77,78,79 etp20 20 100000 +Ethernet80 80,81,82,83 etp21 21 100000 +Ethernet84 84,85,86,87 etp22 22 100000 +Ethernet88 88,89,90,91 etp23 23 100000 +Ethernet92 92,93,94,95 etp24 24 100000 +Ethernet96 96,97,98,99 etp25 25 100000 +Ethernet100 100,101,102,103 etp26 26 100000 +Ethernet104 104,105 etp27a 27 50000 +Ethernet106 106,107 etp27b 27 50000 +Ethernet108 108,109 etp28a 28 50000 +Ethernet110 110,111 etp28b 28 50000 +Ethernet112 112,113,114,115 etp29 29 100000 +Ethernet116 116,117,118,119 etp30 30 100000 +Ethernet120 120,121,122,123 etp31 31 100000 +Ethernet124 124,125,126,127 etp32 32 100000 +Ethernet128 128,129,130,131 etp33 33 100000 +Ethernet132 132,133,134,135 etp34 34 100000 +Ethernet136 136,137,138,139 etp35 35 100000 +Ethernet140 140,141,142,143 etp36 36 100000 +Ethernet144 144,145,146,147 etp37 37 100000 +Ethernet148 148,149,150,151 etp38 38 100000 +Ethernet152 152,153,154,155 etp39 39 100000 +Ethernet156 156,157,158,159 etp40 40 100000 +Ethernet160 160,161,162,163 etp41 41 100000 +Ethernet164 164,165,166,167 etp42 42 100000 +Ethernet168 168,169,170,171 etp43 43 100000 +Ethernet172 172,173,174,175 etp44 44 100000 +Ethernet176 176,177 etp45a 45 50000 +Ethernet178 178,179 etp45b 45 50000 +Ethernet180 180,181 etp46a 46 50000 +Ethernet182 182,183 etp46b 46 50000 +Ethernet184 184,185 etp47a 47 50000 +Ethernet186 186,187 etp47b 47 50000 +Ethernet188 188,189 etp48a 48 50000 +Ethernet190 190,191 etp48b 48 50000 +Ethernet192 192,193,194,195 etp49 49 100000 +Ethernet196 196,197,198,199 etp50 50 100000 +Ethernet200 200,201,202,203 etp51 51 100000 +Ethernet204 204,205,206,207 etp52 52 100000 +Ethernet208 208,209,210,211 etp53 53 100000 +Ethernet212 212,213,214,215 etp54 54 100000 +Ethernet216 216,217,218,219 etp55 55 100000 +Ethernet220 220,221,222,223 etp56 56 100000 +Ethernet224 224,225,226,227 etp57 57 100000 +Ethernet228 228,229,230,231 etp58 58 100000 +Ethernet232 232,233,234,235 etp59 59 100000 +Ethernet236 236,237,238,239 etp60 60 100000 +Ethernet240 240,241 etp61a 61 50000 +Ethernet242 242,243 etp61b 61 50000 +Ethernet244 244,245 etp62a 62 50000 +Ethernet246 246,247 etp62b 62 50000 +Ethernet248 248,249,250,251 etp63 63 100000 +Ethernet252 252,253,254,255 etp64 64 100000 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/port_config.ini index 2c0c25ec0564..4c169a5fb48f 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/port_config.ini @@ -1,79 +1,79 @@ # name lanes alias index speed -Ethernet0 0,1,2,3 etp1 0 100000 -Ethernet4 4,5,6,7 etp2 1 100000 -Ethernet8 8,9,10,11 etp3 2 100000 -Ethernet12 12,13,14,15 etp4 3 100000 -Ethernet16 16,17,18,19 etp5 4 100000 -Ethernet20 20,21,22,23 etp6 5 100000 -Ethernet24 24,25,26,27 etp7 6 100000 -Ethernet28 28,29,30,31 etp8 7 100000 -Ethernet32 32,33 etp9a 8 50000 -Ethernet34 34,35 etp9b 8 50000 -Ethernet36 36,37 etp10a 9 50000 -Ethernet38 38,39 etp10b 9 50000 -Ethernet40 40,41 etp11a 10 50000 -Ethernet42 42,43 etp11b 10 50000 -Ethernet44 44,45 etp12a 11 50000 -Ethernet46 46,47 etp12b 11 50000 -Ethernet48 48,49,50,51 etp13 12 100000 -Ethernet52 52,53,54,55 etp14 13 100000 -Ethernet56 56,57,58,59 etp15 14 100000 -Ethernet60 60,61,62,63 etp16 15 100000 -Ethernet64 64,65,66,67 etp17 16 100000 -Ethernet68 68,69,70,71 etp18 17 100000 -Ethernet72 72,73,74,75 etp19 18 100000 -Ethernet76 76,77,78,79 etp20 19 100000 -Ethernet80 80,81,82,83 etp21 20 100000 -Ethernet84 84,85,86,87 etp22 21 100000 -Ethernet88 88,89,90,91 etp23 22 100000 -Ethernet92 92,93,94,95 etp24 23 100000 -Ethernet96 96,97,98,99 etp25 24 100000 -Ethernet100 100,101,102,103 etp26 25 100000 -Ethernet104 104,105 etp27a 26 50000 -Ethernet106 106,107 etp27b 26 50000 -Ethernet108 108,109 etp28a 27 50000 -Ethernet110 110,111 etp28b 27 50000 -Ethernet112 112,113,114,115 etp29 28 100000 -Ethernet116 116,117,118,119 etp30 29 100000 -Ethernet120 120,121,122,123 etp31 30 100000 -Ethernet124 124,125,126,127 etp32 31 100000 -Ethernet128 128,129,130,131 etp33 32 100000 -Ethernet132 132,133,134,135 etp34 33 100000 -Ethernet136 136,137,138,139 etp35 34 100000 -Ethernet140 140,141,142,143 etp36 35 100000 -Ethernet144 144,145,146,147 etp37 36 100000 -Ethernet148 148,149,150,151 etp38 37 100000 +Ethernet0 0,1,2,3 etp1 1 100000 +Ethernet4 4,5,6,7 etp2 2 100000 +Ethernet8 8,9,10,11 etp3 3 100000 +Ethernet12 12,13,14,15 etp4 4 100000 +Ethernet16 16,17,18,19 etp5 5 100000 +Ethernet20 20,21,22,23 etp6 6 100000 +Ethernet24 24,25,26,27 etp7 7 100000 +Ethernet28 28,29,30,31 etp8 8 100000 +Ethernet32 32,33 etp9a 9 50000 +Ethernet34 34,35 etp9b 9 50000 +Ethernet36 36,37 etp10a 10 50000 +Ethernet38 38,39 etp10b 10 50000 +Ethernet40 40,41 etp11a 11 50000 +Ethernet42 42,43 etp11b 11 50000 +Ethernet44 44,45 etp12a 12 50000 +Ethernet46 46,47 etp12b 12 50000 +Ethernet48 48,49,50,51 etp13 13 100000 +Ethernet52 52,53,54,55 etp14 14 100000 +Ethernet56 56,57,58,59 etp15 15 100000 +Ethernet60 60,61,62,63 etp16 16 100000 +Ethernet64 64,65,66,67 etp17 17 100000 +Ethernet68 68,69,70,71 etp18 18 100000 +Ethernet72 72,73,74,75 etp19 19 100000 +Ethernet76 76,77,78,79 etp20 20 100000 +Ethernet80 80,81,82,83 etp21 21 100000 +Ethernet84 84,85,86,87 etp22 22 100000 +Ethernet88 88,89,90,91 etp23 23 100000 +Ethernet92 92,93,94,95 etp24 24 100000 +Ethernet96 96,97,98,99 etp25 25 100000 +Ethernet100 100,101,102,103 etp26 26 100000 +Ethernet104 104,105 etp27a 27 50000 +Ethernet106 106,107 etp27b 27 50000 +Ethernet108 108,109 etp28a 28 50000 +Ethernet110 110,111 etp28b 28 50000 +Ethernet112 112,113,114,115 etp29 29 100000 +Ethernet116 116,117,118,119 etp30 30 100000 +Ethernet120 120,121,122,123 etp31 31 100000 +Ethernet124 124,125,126,127 etp32 32 100000 +Ethernet128 128,129,130,131 etp33 33 100000 +Ethernet132 132,133,134,135 etp34 34 100000 +Ethernet136 136,137,138,139 etp35 35 100000 +Ethernet140 140,141,142,143 etp36 36 100000 +Ethernet144 144,145,146,147 etp37 37 100000 +Ethernet148 148,149,150,151 etp38 38 100000 Ethernet152 152,153,154,155 etp39 38 100000 -Ethernet156 156,157,158,159 etp40 39 100000 -Ethernet160 160,161,162,163 etp41 40 100000 -Ethernet164 164,165,166,167 etp42 41 100000 -Ethernet168 168,169,170,171 etp43 42 100000 -Ethernet172 172,173,174,175 etp44 43 100000 -Ethernet176 176,177 etp45a 44 50000 -Ethernet178 178,179 etp45b 44 50000 -Ethernet180 180,181 etp46a 45 50000 -Ethernet182 182,183 etp46b 45 50000 -Ethernet184 184,185 etp47a 46 50000 -Ethernet186 186,187 etp47b 46 50000 -Ethernet188 188,189 etp48a 47 50000 -Ethernet190 190,191 etp48b 47 50000 -Ethernet192 192,193,194,195 etp49 48 100000 -Ethernet196 196,197,198,199 etp50 49 100000 -Ethernet200 200,201,202,203 etp51 50 100000 -Ethernet204 204,205,206,207 etp52 51 100000 -Ethernet208 208,209,210,211 etp53 52 100000 -Ethernet212 212,213,214,215 etp54 53 100000 -Ethernet216 216,217,218,219 etp55 54 100000 -Ethernet220 220,221,222,223 etp56 55 100000 -Ethernet224 224,225,226,227 etp57 56 100000 -Ethernet228 228,229,230,231 etp58 57 100000 -Ethernet232 232,233,234,235 etp59 58 100000 -Ethernet236 236,237,238,239 etp60 59 100000 -Ethernet240 240,241 etp61a 60 50000 -Ethernet242 242,243 etp61b 60 50000 -Ethernet244 244,245 etp62a 61 50000 -Ethernet246 246,247 etp62b 61 50000 -Ethernet248 248,249 etp63a 62 50000 -Ethernet250 250,251 etp63b 62 50000 -Ethernet252 252,253 etp64a 63 50000 -Ethernet254 254,255 etp64b 63 50000 \ No newline at end of file +Ethernet156 156,157,158,159 etp40 40 100000 +Ethernet160 160,161,162,163 etp41 41 100000 +Ethernet164 164,165,166,167 etp42 42 100000 +Ethernet168 168,169,170,171 etp43 43 100000 +Ethernet172 172,173,174,175 etp44 44 100000 +Ethernet176 176,177 etp45a 45 50000 +Ethernet178 178,179 etp45b 45 50000 +Ethernet180 180,181 etp46a 46 50000 +Ethernet182 182,183 etp46b 46 50000 +Ethernet184 184,185 etp47a 47 50000 +Ethernet186 186,187 etp47b 47 50000 +Ethernet188 188,189 etp48a 48 50000 +Ethernet190 190,191 etp48b 48 50000 +Ethernet192 192,193,194,195 etp49 49 100000 +Ethernet196 196,197,198,199 etp50 50 100000 +Ethernet200 200,201,202,203 etp51 51 100000 +Ethernet204 204,205,206,207 etp52 52 100000 +Ethernet208 208,209,210,211 etp53 53 100000 +Ethernet212 212,213,214,215 etp54 54 100000 +Ethernet216 216,217,218,219 etp55 55 100000 +Ethernet220 220,221,222,223 etp56 56 100000 +Ethernet224 224,225,226,227 etp57 57 100000 +Ethernet228 228,229,230,231 etp58 58 100000 +Ethernet232 232,233,234,235 etp59 59 100000 +Ethernet236 236,237,238,239 etp60 60 100000 +Ethernet240 240,241 etp61a 61 50000 +Ethernet242 242,243 etp61b 61 50000 +Ethernet244 244,245 etp62a 62 50000 +Ethernet246 246,247 etp62b 62 50000 +Ethernet248 248,249 etp63a 63 50000 +Ethernet250 250,251 etp63b 63 50000 +Ethernet252 252,253 etp64a 64 50000 +Ethernet254 254,255 etp64b 64 50000 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini index 7ccff5a8da4b..a1ecf9aa3266 100644 --- a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini @@ -1,65 +1,65 @@ # name lanes alias index -Ethernet0 0,1,2,3 etp1 0 -Ethernet8 8,9,10,11 etp2 1 -Ethernet16 16,17,18,19 etp3 2 -Ethernet24 24,25,26,27 etp4 3 -Ethernet32 32,33,34,35 etp5 4 -Ethernet40 40,41,42,43 etp6 5 -Ethernet48 48,49,50,51 etp7 6 -Ethernet56 56,57,58,59 etp8 7 -Ethernet64 64,65,66,67 etp9 8 -Ethernet72 72,73,74,75 etp10 9 -Ethernet80 80,81,82,83 etp11 10 -Ethernet88 88,89,90,91 etp12 11 -Ethernet96 96,97,98,99 etp13 12 -Ethernet104 104,105,106,107 etp14 13 -Ethernet112 112,113,114,115 etp15 14 -Ethernet120 120,121,122,123 etp16 15 -Ethernet128 128,129,130,131 etp17 16 -Ethernet136 136,137,138,139 etp18 17 -Ethernet144 144,145,146,147 etp19 18 -Ethernet152 152,153,154,155 etp20 19 -Ethernet160 160,161,162,163 etp21 20 -Ethernet168 168,169,170,171 etp22 21 -Ethernet176 176,177,178,179 etp23 22 -Ethernet184 184,185,186,187 etp24 23 -Ethernet192 192,193,194,195 etp25 24 -Ethernet200 200,201,202,203 etp26 25 -Ethernet208 208,209,210,211 etp27 26 -Ethernet216 216,217,218,219 etp28 27 -Ethernet224 224,225,226,227 etp29 28 -Ethernet232 232,233,234,235 etp30 29 -Ethernet240 240,241,242,243 etp31 30 -Ethernet248 248,249,250,251 etp32 31 -Ethernet256 256,257,258,259 etp33 32 -Ethernet264 264,265,266,267 etp34 33 -Ethernet272 272,273,274,275 etp35 34 -Ethernet280 280,281,282,283 etp36 35 -Ethernet288 288,289,290,291 etp37 36 -Ethernet296 296,297,298,299 etp38 37 -Ethernet304 304,305,306,307 etp39 38 -Ethernet312 312,313,314,315 etp40 39 -Ethernet320 320,321,322,323 etp41 40 -Ethernet328 328,329,330,331 etp42 41 -Ethernet336 336,337,338,339 etp43 42 -Ethernet344 344,345,346,347 etp44 43 -Ethernet352 352,353,354,355 etp45 44 -Ethernet360 360,361,362,363 etp46 45 -Ethernet368 368,369,370,371 etp47 46 -Ethernet376 376,377,378,379 etp48 47 -Ethernet384 384,385,386,387 etp49 48 -Ethernet392 392,393,394,395 etp50 49 -Ethernet400 400,401,402,403 etp51 50 -Ethernet408 408,409,410,411 etp52 51 -Ethernet416 416,417,418,419 etp53 52 -Ethernet424 424,425,426,427 etp54 53 -Ethernet432 432,433,434,435 etp55 54 -Ethernet440 440,441,442,443 etp56 55 -Ethernet448 448,449,450,451 etp57 56 -Ethernet456 456,457,458,459 etp58 57 -Ethernet464 464,465,466,467 etp59 58 -Ethernet472 472,473,474,475 etp60 59 -Ethernet480 480,481,482,483 etp61 60 -Ethernet488 488,489,490,491 etp62 61 -Ethernet496 496,497,498,499 etp63 62 -Ethernet504 504,505,506,507 etp64 63 +Ethernet0 0,1,2,3 etp1 1 +Ethernet8 8,9,10,11 etp2 2 +Ethernet16 16,17,18,19 etp3 3 +Ethernet24 24,25,26,27 etp4 4 +Ethernet32 32,33,34,35 etp5 5 +Ethernet40 40,41,42,43 etp6 6 +Ethernet48 48,49,50,51 etp7 7 +Ethernet56 56,57,58,59 etp8 8 +Ethernet64 64,65,66,67 etp9 9 +Ethernet72 72,73,74,75 etp10 10 +Ethernet80 80,81,82,83 etp11 11 +Ethernet88 88,89,90,91 etp12 12 +Ethernet96 96,97,98,99 etp13 13 +Ethernet104 104,105,106,107 etp14 14 +Ethernet112 112,113,114,115 etp15 15 +Ethernet120 120,121,122,123 etp16 16 +Ethernet128 128,129,130,131 etp17 17 +Ethernet136 136,137,138,139 etp18 18 +Ethernet144 144,145,146,147 etp19 19 +Ethernet152 152,153,154,155 etp20 20 +Ethernet160 160,161,162,163 etp21 21 +Ethernet168 168,169,170,171 etp22 22 +Ethernet176 176,177,178,179 etp23 23 +Ethernet184 184,185,186,187 etp24 24 +Ethernet192 192,193,194,195 etp25 25 +Ethernet200 200,201,202,203 etp26 26 +Ethernet208 208,209,210,211 etp27 27 +Ethernet216 216,217,218,219 etp28 28 +Ethernet224 224,225,226,227 etp29 29 +Ethernet232 232,233,234,235 etp30 30 +Ethernet240 240,241,242,243 etp31 31 +Ethernet248 248,249,250,251 etp32 32 +Ethernet256 256,257,258,259 etp33 33 +Ethernet264 264,265,266,267 etp34 34 +Ethernet272 272,273,274,275 etp35 35 +Ethernet280 280,281,282,283 etp36 36 +Ethernet288 288,289,290,291 etp37 37 +Ethernet296 296,297,298,299 etp38 38 +Ethernet304 304,305,306,307 etp39 39 +Ethernet312 312,313,314,315 etp40 40 +Ethernet320 320,321,322,323 etp41 41 +Ethernet328 328,329,330,331 etp42 42 +Ethernet336 336,337,338,339 etp43 43 +Ethernet344 344,345,346,347 etp44 44 +Ethernet352 352,353,354,355 etp45 45 +Ethernet360 360,361,362,363 etp46 46 +Ethernet368 368,369,370,371 etp47 47 +Ethernet376 376,377,378,379 etp48 48 +Ethernet384 384,385,386,387 etp49 49 +Ethernet392 392,393,394,395 etp50 50 +Ethernet400 400,401,402,403 etp51 51 +Ethernet408 408,409,410,411 etp52 52 +Ethernet416 416,417,418,419 etp53 53 +Ethernet424 424,425,426,427 etp54 54 +Ethernet432 432,433,434,435 etp55 55 +Ethernet440 440,441,442,443 etp56 56 +Ethernet448 448,449,450,451 etp57 57 +Ethernet456 456,457,458,459 etp58 58 +Ethernet464 464,465,466,467 etp59 59 +Ethernet472 472,473,474,475 etp60 60 +Ethernet480 480,481,482,483 etp61 61 +Ethernet488 488,489,490,491 etp62 62 +Ethernet496 496,497,498,499 etp63 63 +Ethernet504 504,505,506,507 etp64 64 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini index 2a14b4a79eb6..ea7219932624 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini @@ -1,33 +1,33 @@ # name lanes alias index -Ethernet0 0,1,2,3,4,5,6,7 etp1 0 -Ethernet8 8,9,10,11,12,13,14,15 etp2 1 -Ethernet16 16,17,18,19,20,21,22,23 etp3 2 -Ethernet24 24,25,26,27,28,29,30,31 etp4 3 -Ethernet32 32,33,34,35,36,37,38,39 etp5 4 -Ethernet40 40,41,42,43,44,45,46,47 etp6 5 -Ethernet48 48,49,50,51,52,53,54,55 etp7 6 -Ethernet56 56,57,58,59,60,61,62,63 etp8 7 -Ethernet64 64,65,66,67,68,69,70,71 etp9 8 -Ethernet72 72,73,74,75,76,77,78,79 etp10 9 -Ethernet80 80,81,82,83,84,85,86,87 etp11 10 -Ethernet88 88,89,90,91,92,93,94,95 etp12 11 -Ethernet96 96,97,98,99,100,101,102,103 etp13 12 -Ethernet104 104,105,106,107,108,109,110,111 etp14 13 -Ethernet112 112,113,114,115,116,117,118,119 etp15 14 -Ethernet120 120,121,122,123,124,125,126,127 etp16 15 -Ethernet128 128,129,130,131,132,133,134,135 etp17 16 -Ethernet136 136,137,138,139,140,141,142,143 etp18 17 -Ethernet144 144,145,146,147,148,149,150,151 etp19 18 -Ethernet152 152,153,154,155,156,157,158,159 etp20 19 -Ethernet160 160,161,162,163,164,165,166,167 etp21 20 -Ethernet168 168,169,170,171,172,173,174,175 etp22 21 -Ethernet176 176,177,178,179,180,181,182,183 etp23 22 -Ethernet184 184,185,186,187,188,189,190,191 etp24 23 -Ethernet192 192,193,194,195,196,197,198,199 etp25 24 -Ethernet200 200,201,202,203,204,205,206,207 etp26 25 -Ethernet208 208,209,210,211,212,213,214,215 etp27 26 -Ethernet216 216,217,218,219,220,221,222,223 etp28 27 -Ethernet224 224,225,226,227,228,229,230,231 etp29 28 -Ethernet232 232,233,234,235,236,237,238,239 etp30 29 -Ethernet240 240,241,242,243,244,245,246,247 etp31 30 -Ethernet248 248,249,250,251,252,253,254,255 etp32 31 +Ethernet0 0,1,2,3,4,5,6,7 etp1 1 +Ethernet8 8,9,10,11,12,13,14,15 etp2 2 +Ethernet16 16,17,18,19,20,21,22,23 etp3 3 +Ethernet24 24,25,26,27,28,29,30,31 etp4 4 +Ethernet32 32,33,34,35,36,37,38,39 etp5 5 +Ethernet40 40,41,42,43,44,45,46,47 etp6 6 +Ethernet48 48,49,50,51,52,53,54,55 etp7 7 +Ethernet56 56,57,58,59,60,61,62,63 etp8 8 +Ethernet64 64,65,66,67,68,69,70,71 etp9 9 +Ethernet72 72,73,74,75,76,77,78,79 etp10 10 +Ethernet80 80,81,82,83,84,85,86,87 etp11 11 +Ethernet88 88,89,90,91,92,93,94,95 etp12 12 +Ethernet96 96,97,98,99,100,101,102,103 etp13 13 +Ethernet104 104,105,106,107,108,109,110,111 etp14 14 +Ethernet112 112,113,114,115,116,117,118,119 etp15 15 +Ethernet120 120,121,122,123,124,125,126,127 etp16 16 +Ethernet128 128,129,130,131,132,133,134,135 etp17 17 +Ethernet136 136,137,138,139,140,141,142,143 etp18 18 +Ethernet144 144,145,146,147,148,149,150,151 etp19 19 +Ethernet152 152,153,154,155,156,157,158,159 etp20 20 +Ethernet160 160,161,162,163,164,165,166,167 etp21 21 +Ethernet168 168,169,170,171,172,173,174,175 etp22 22 +Ethernet176 176,177,178,179,180,181,182,183 etp23 23 +Ethernet184 184,185,186,187,188,189,190,191 etp24 24 +Ethernet192 192,193,194,195,196,197,198,199 etp25 25 +Ethernet200 200,201,202,203,204,205,206,207 etp26 26 +Ethernet208 208,209,210,211,212,213,214,215 etp27 27 +Ethernet216 216,217,218,219,220,221,222,223 etp28 28 +Ethernet224 224,225,226,227,228,229,230,231 etp29 29 +Ethernet232 232,233,234,235,236,237,238,239 etp30 30 +Ethernet240 240,241,242,243,244,245,246,247 etp31 31 +Ethernet248 248,249,250,251,252,253,254,255 etp32 32 diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 567f5f0c541d..ff4e28900550 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -197,13 +197,13 @@ def get_all_sfps(self): def get_sfp(self, index): """ - Retrieves sfp represented by (0-based) index + Retrieves sfp represented by (1-based) index Args: - index: An integer, the index (0-based) of the sfp to retrieve. + index: An integer, the index (1-based) of the sfp to retrieve. The index should be the sequence of a physical port in a chassis, - starting from 0. - For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + starting from 1. + For example, 1 for Ethernet0, 2 for Ethernet4 and so on. Returns: An object dervied from SfpBase representing the specified sfp @@ -212,7 +212,7 @@ def get_sfp(self, index): self.initialize_sfp() sfp = None - + index -= 1 try: sfp = self._sfp_list[index] except IndexError: diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py index 0ed75c26c63a..859e411fb00a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py @@ -259,7 +259,7 @@ def check_sfp_status(self, port_change, timeout): for port in port_list: logger.log_info("SFP on port {} state {}".format(port, sfp_state)) - port_change[port] = sfp_state + port_change[port+1] = sfp_state found += 1 return found != 0 From 5cacc2004c59b7ac584e2a3e05f452c3c57f35bb Mon Sep 17 00:00:00 2001 From: padmanarayana Date: Tue, 23 Jun 2020 22:23:08 -0700 Subject: [PATCH 0833/1427] Add a port index mapper service for sFlow (#4794) * Add a port index mapper service for sFlow --- dockers/docker-sflow/Dockerfile.j2 | 4 + dockers/docker-sflow/port_index_mapper.py | 114 ++++++++++++++++++++++ dockers/docker-sflow/supervisord.conf | 10 ++ 3 files changed, 128 insertions(+) create mode 100755 dockers/docker-sflow/port_index_mapper.py diff --git a/dockers/docker-sflow/Dockerfile.j2 b/dockers/docker-sflow/Dockerfile.j2 index f532a4040e07..03e209621dd9 100644 --- a/dockers/docker-sflow/Dockerfile.j2 +++ b/dockers/docker-sflow/Dockerfile.j2 @@ -12,6 +12,9 @@ RUN apt-get update && \ dmidecode \ libmnl0=1.0.4-2 +RUN pip install \ + pyroute2==0.5.3 + {% if docker_sflow_debs.strip() -%} # Copy locally-built Debian package dependencies {{ copy_files("debs/", docker_sflow_debs.split(' '), "/debs/") }} @@ -30,5 +33,6 @@ RUN sed -ri '/^DAEMON_ARGS=""/c DAEMON_ARGS="-c /var/log/hsflowd.crash"' /etc/in COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] +COPY ["port_index_mapper.py", "/usr/bin"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sflow/port_index_mapper.py b/dockers/docker-sflow/port_index_mapper.py new file mode 100755 index 000000000000..24f078b20f90 --- /dev/null +++ b/dockers/docker-sflow/port_index_mapper.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python + +""" port_index_mapper + A mapper service that watches for NetLink NEWLINK and DELLINKs + to construct a PORT_INDEX_TABLE in state DB which includes the + interface name, the interface index and the ifindex. + + Note : Currently supports only interfaces supported by port_util. +""" + +import os +import sys +import syslog +import signal +import traceback +from pyroute2 import IPDB +from pyroute2.iproute import RTM_NEWLINK, RTM_DELLINK +from swsssdk import SonicV2Connector, port_util + +PORT_INDEX_TABLE_NAME = 'PORT_INDEX_TABLE' +SYSLOG_IDENTIFIER = 'port_index_mapper' + +ipdb = None +state_db = None + +def set_port_index_table_entry(key, index, ifindex): + state_db.set(state_db.STATE_DB, key, 'index', index) + state_db.set(state_db.STATE_DB, key, 'ifindex', ifindex) + +def interface_callback(ipdb, nlmsg, action): + global state_db + + try: + msgtype = nlmsg['header']['type'] + if (msgtype != RTM_NEWLINK and msgtype != RTM_DELLINK): + return + + # filter out unwanted messages + change = nlmsg['change'] + if (change != 0xFFFFFFFF): + return + + attrs = nlmsg['attrs'] + for list in attrs: + if list[0] == 'IFLA_IFNAME': + ifname = list[1] + break + else: + return + + # Extract the port index from the interface name + index = port_util.get_index_from_str(ifname) + if index is None: + return + + _hash = '{}|{}'.format(PORT_INDEX_TABLE_NAME, ifname) + + if msgtype == RTM_NEWLINK: + set_port_index_table_entry(_hash, str(index), nlmsg['index']) + elif msgtype == RTM_DELLINK: + state_db.delete(state_db.STATE_DB, _hash) + + except Exception, e: + t = sys.exc_info()[2] + traceback.print_tb(t) + syslog.syslog(syslog.LOG_CRIT, "%s" % str(e)) + os.kill(os.getpid(), signal.SIGTERM) + +def main(): + global state_db, ipdb + state_db = SonicV2Connector(host='127.0.0.1') + state_db.connect(state_db.STATE_DB, False) + + ipdb = IPDB() + + # Initialize the table at startup. + ifnames = ipdb.by_name.keys() + for ifname in ifnames: + index = port_util.get_index_from_str(ifname) + if index is None: + continue + ifindex = ipdb.interfaces[ifname]['index'] + _hash = '{}|{}'.format(PORT_INDEX_TABLE_NAME, ifname) + set_port_index_table_entry(_hash, str(index), str(ifindex)) + + ipdb.register_callback(interface_callback) + + signal.pause() + +def signal_handler(signum, frame): + syslog.syslog(syslog.LOG_NOTICE, "got signal %d" % signum) + sys.exit(0) + +if __name__ == '__main__': + rc = 0 + try: + syslog.openlog(SYSLOG_IDENTIFIER) + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) + main() + except Exception, e: + t = sys.exc_info()[2] + traceback.print_tb(t) + syslog.syslog(syslog.LOG_CRIT, "%s" % str(e)) + rc = -1 + finally: + if ipdb is not None: + ipdb.release() + else: + syslog.syslog(syslog.LOG_ERR, "ipdb undefined in signal_handler") + + syslog.closelog() + sys.exit(rc) + diff --git a/dockers/docker-sflow/supervisord.conf b/dockers/docker-sflow/supervisord.conf index 3605e50318dc..a3150f23afb3 100644 --- a/dockers/docker-sflow/supervisord.conf +++ b/dockers/docker-sflow/supervisord.conf @@ -35,3 +35,13 @@ stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=rsyslogd:running + +[program:port_index_mapper] +command=/usr/bin/port_index_mapper.py +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running From c50b43174746fa14b5ec5a2bac62e09417e8e74c Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Wed, 24 Jun 2020 14:07:22 -0700 Subject: [PATCH 0834/1427] [dvs] Install libteamdctl runtime dependency in VS docker (#4837) * Add libteamdctl dependency to VS docker * Reorder dependencies and rename libteamctl Signed-off-by: Danny Allen --- platform/p4/docker-sonic-p4.mk | 2 +- platform/vs/docker-sonic-vs.mk | 2 +- rules/docker-teamd.mk | 4 ++-- rules/libteam.mk | 12 ++++++------ rules/swss.mk | 5 +++-- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/platform/p4/docker-sonic-p4.mk b/platform/p4/docker-sonic-p4.mk index 534d161631f5..7cdeee254c41 100644 --- a/platform/p4/docker-sonic-p4.mk +++ b/platform/p4/docker-sonic-p4.mk @@ -8,7 +8,7 @@ $(DOCKER_SONIC_P4)_DEPENDS += $(SWSS) \ $(REDIS_TOOLS) \ $(REDIS_SERVER) \ $(PYTHON_SWSSCOMMON) \ - $(LIBTEAMDCT) \ + $(LIBTEAMDCTL) \ $(LIBTEAM_UTILS) \ $(SONIC_DEVICE_DATA) \ $(SONIC_UTILS) \ diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index 43310073b65d..b539543dfd2f 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -7,7 +7,7 @@ $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS) \ $(REDIS_TOOLS) \ $(REDIS_SERVER) \ $(PYTHON_SWSSCOMMON) \ - $(LIBTEAMDCT) \ + $(LIBTEAMDCTL) \ $(LIBTEAM_UTILS) \ $(SONIC_DEVICE_DATA) diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk index ce7b5bbab1f5..a4ac31599fd1 100644 --- a/rules/docker-teamd.mk +++ b/rules/docker-teamd.mk @@ -6,10 +6,10 @@ DOCKER_TEAMD_DBG = $(DOCKER_TEAMD_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_TEAMD)_PATH = $(DOCKERS_PATH)/$(DOCKER_TEAMD_STEM) -$(DOCKER_TEAMD)_DEPENDS += $(SWSS) $(LIBTEAMDCT) $(LIBTEAM_UTILS) $(REDIS_TOOLS) +$(DOCKER_TEAMD)_DEPENDS += $(SWSS) $(LIBTEAMDCTL) $(LIBTEAM_UTILS) $(REDIS_TOOLS) $(DOCKER_TEAMD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_TEAMD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) -$(DOCKER_TEAMD)_DBG_DEPENDS += $(LIBTEAMDCT_DBG) $(LIBTEAM_UTILS_DBG) +$(DOCKER_TEAMD)_DBG_DEPENDS += $(LIBTEAMDCTL_DBG) $(LIBTEAM_UTILS_DBG) $(DOCKER_TEAMD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) diff --git a/rules/libteam.mk b/rules/libteam.mk index d10d5af4fa15..0dd1b88b099a 100644 --- a/rules/libteam.mk +++ b/rules/libteam.mk @@ -13,17 +13,17 @@ LIBTEAM_DBG = libteam5-dbgsym_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAM_DBG))) LIBTEAM_DEV = libteam-dev_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb -$(LIBTEAM_DEV)_DEPENDS += $(LIBTEAMDCT) +$(LIBTEAM_DEV)_DEPENDS += $(LIBTEAMDCTL) $(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAM_DEV))) -LIBTEAMDCT = libteamdctl0_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAMDCT))) +LIBTEAMDCTL = libteamdctl0_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAMDCTL))) -LIBTEAMDCT_DBG = libteamdctl0-dbgsym_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAMDCT_DBG))) +LIBTEAMDCTL_DBG = libteamdctl0-dbgsym_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAMDCTL_DBG))) LIBTEAM_UTILS = libteam-utils_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb -$(LIBTEAM_UTILS)_DEPENDS += $(LIBTEAMDCT) +$(LIBTEAM_UTILS)_DEPENDS += $(LIBTEAMDCTL) $(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAM_UTILS))) LIBTEAM_UTILS_DBG = libteam-utils-dbgsym_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb diff --git a/rules/swss.mk b/rules/swss.mk index f8044d77fb6a..b8106757ac66 100644 --- a/rules/swss.mk +++ b/rules/swss.mk @@ -3,8 +3,9 @@ SWSS = swss_1.0.0_$(CONFIGURED_ARCH).deb $(SWSS)_SRC_PATH = $(SRC_PATH)/sonic-swss $(SWSS)_DEPENDS += $(LIBSAIREDIS_DEV) $(LIBSAIMETADATA_DEV) $(LIBTEAM_DEV) \ - $(LIBTEAMDCT) $(LIBTEAM_UTILS) $(LIBSWSSCOMMON_DEV) -$(SWSS)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) $(LIBTEAM) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) + $(LIBTEAMDCTL) $(LIBTEAM_UTILS) $(LIBSWSSCOMMON_DEV) +$(SWSS)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) $(LIBTEAM) \ + $(LIBTEAMDCTL) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) SONIC_DPKG_DEBS += $(SWSS) SWSS_DBG = swss-dbg_1.0.0_$(CONFIGURED_ARCH).deb From 63d2efbe03198868dad00c6139a629c317b28323 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 24 Jun 2020 15:25:16 -0700 Subject: [PATCH 0835/1427] [build][systemd] Mask disabled services by default (#4721) When building the SONiC image, used systemd to mask all services which are set to "disabled" in init_cfg.json. This PR depends on https://github.com/Azure/sonic-utilities/pull/944, otherwise `config load_minigraph will fail when trying to restart disabled services. --- files/build_scripts/mask_disabled_services.py | 13 +++++++++++++ files/build_templates/sonic_debian_extension.j2 | 7 +++++++ 2 files changed, 20 insertions(+) create mode 100755 files/build_scripts/mask_disabled_services.py diff --git a/files/build_scripts/mask_disabled_services.py b/files/build_scripts/mask_disabled_services.py new file mode 100755 index 000000000000..e2597ac686f1 --- /dev/null +++ b/files/build_scripts/mask_disabled_services.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +import json +import subprocess + +INIT_CFG_FILE_PATH = '/etc/sonic/init_cfg.json' + +with open(INIT_CFG_FILE_PATH) as init_cfg_file: + init_cfg = json.load(init_cfg_file) + if 'FEATURE' in init_cfg: + for feature_name, feature_props in init_cfg['FEATURE'].items(): + if 'status' in feature_props and feature_props['status'] == 'disabled': + subprocess.run(['systemctl', 'mask', '{}.service'.format(feature_name)]) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 2488da1c2061..635084fd5414 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -27,6 +27,7 @@ set -x -e CONFIGURED_ARCH=$([ -f .arch ] && cat .arch || echo amd64) . functions.sh +BUILD_SCRIPTS_DIR=files/build_scripts BUILD_TEMPLATES=files/build_templates IMAGE_CONFIGS=files/image_config SCRIPTS_DIR=files/scripts @@ -559,3 +560,9 @@ sudo chown -R $FRR_USER_UID:$FRR_USER_GID $FILESYSTEM_ROOT/etc/sonic/frr sudo chmod -R 640 $FILESYSTEM_ROOT/etc/sonic/frr/ sudo chmod 750 $FILESYSTEM_ROOT/etc/sonic/frr {%- endif %} + +# Mask services which are disabled by default +sudo cp $BUILD_SCRIPTS_DIR/mask_disabled_services.py $FILESYSTEM_ROOT/tmp/ +sudo chmod a+x $FILESYSTEM_ROOT/tmp/mask_disabled_services.py +sudo LANG=C chroot $FILESYSTEM_ROOT /tmp/mask_disabled_services.py +sudo rm -rf $FILESYSTEM_ROOT/tmp/mask_disabled_services.py From cebb85b16121e73abbee05a1c97474c5682061e5 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 24 Jun 2020 22:48:37 -0700 Subject: [PATCH 0836/1427] [docker-orchagent]: start portsyncd before orchagent (#4845) when portsyncd starts, it first enumerates all front panel ports and marks them as old interfaces. Then, for new front panel ports it checks if their indexes exist in previous sets. If yes, it will treats them as old interfaces and ignore them. The reason we have this check is because broadcom SAI only removes front panel ports after sai switch init. So, if portsyncd starts after orchagent, new interfaces could be created before portsyncd and treated as old interface. Signed-off-by: Guohan Lu --- dockers/docker-orchagent/supervisord.conf | 28 +++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index cefbce98c64a..3cd192f24ce8 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -26,8 +26,8 @@ stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true -[program:orchagent] -command=/usr/bin/orchagent.sh +[program:portsyncd] +command=/usr/bin/portsyncd priority=3 autostart=false autorestart=false @@ -36,9 +36,19 @@ stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=rsyslogd:running +[program:orchagent] +command=/usr/bin/orchagent.sh +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=portsyncd:running + [program:restore_neighbors] command=/usr/bin/restore_neighbors.py -priority=4 +priority=5 autostart=false autorestart=false startsecs=0 @@ -60,19 +70,9 @@ stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=orchagent:running -[program:portsyncd] -command=/usr/bin/portsyncd -priority=4 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog -dependent_startup=true -dependent_startup_wait_for=swssconfig:exited - [program:neighsyncd] command=/usr/bin/neighsyncd -priority=5 +priority=7 autostart=false autorestart=false stdout_logfile=syslog From de0702935254280a72a6480da753f9a8f607ebae Mon Sep 17 00:00:00 2001 From: Eric Seifert Date: Thu, 25 Jun 2020 08:04:43 -0700 Subject: [PATCH 0837/1427] Add TELEMETRY_WRITABLE build option to enable telemetry write mode (default read-only) (#4209) Add build flag TELEMETRY_WRITABLE. When set to "y" it will add a go build flag in the telemetry build that will enable telemetry write mode to allow configuration via gNMI Set RPC as well as operations via the gNOI RPC's. The default for TELEMETRY_WRITABLE is unset in which case telemetry is read-only. In read-only mode the Set RPC and all gNOI RPC's are disabled and will return an "Unsupported" error when called. authored-by: Eric Seifert --- Makefile.work | 4 ++++ rules/config | 3 +++ slave.mk | 2 ++ 3 files changed, 9 insertions(+) diff --git a/Makefile.work b/Makefile.work index ac87eef87937..4694750db68a 100644 --- a/Makefile.work +++ b/Makefile.work @@ -32,6 +32,9 @@ # * Default: yes # * Values: yes, no # * KERNEL_PROCURE_METHOD: Specifying method of obtaining kernel Debian package: download or build +# * TELEMETRY_WRITABLE: Enable write/config operations via the gNMI interface. +# * Default: unset +# * Values: y # * SONIC_DPKG_CACHE_METHOD: Specifying method of obtaining the Debian packages from cache: none or cache # * SONIC_DPKG_CACHE_SOURCE: Debian package cache location when cache enabled for debian packages # * BUILD_LOG_TIMESTAMP: Set timestamp in the build log (simple/none) @@ -200,6 +203,7 @@ SONIC_BUILD_INSTRUCTION := make \ HTTPS_PROXY=$(https_proxy) \ SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY) \ SONIC_ENABLE_RESTAPI=$(ENABLE_RESTAPI) \ + TELEMETRY_WRITABLE=$(TELEMETRY_WRITABLE) \ EXTRA_DOCKER_TARGETS=$(EXTRA_DOCKER_TARGETS) \ BUILD_LOG_TIMESTAMP=$(BUILD_LOG_TIMESTAMP) \ SONIC_ENABLE_IMAGE_SIGNATURE=$(ENABLE_IMAGE_SIGNATURE) \ diff --git a/rules/config b/rules/config index f20708bbd2b9..b7f55122ee4a 100644 --- a/rules/config +++ b/rules/config @@ -131,6 +131,9 @@ ENABLE_RESTAPI = n # ENABLE_NAT - build docker-sonic-nat for nat support ENABLE_NAT = y +# TELEMETRY_WRITABLE - Enable write/config operations via the gNMI interface. +# Uncomment to enable: +# TELEMETRY_WRITABLE = y # INSTALL_KUBERNETES - if set to y kubernetes packages are installed to be able to # run as worker node in kubernetes cluster. INSTALL_KUBERNETES = n diff --git a/slave.mk b/slave.mk index 4b14f4fea227..891f5686b80e 100644 --- a/slave.mk +++ b/slave.mk @@ -230,6 +230,8 @@ $(info "BLDENV" : "$(BLDENV)") $(info "VS_PREPARE_MEM" : "$(VS_PREPARE_MEM)") $(info "ENABLE_SFLOW" : "$(ENABLE_SFLOW)") $(info "ENABLE_NAT" : "$(ENABLE_NAT)") +$(info "TELEMETRY_WRITABLE" : "$(TELEMETRY_WRITABLE)") +$(info ) include Makefile.cache From d592e9b0f896c3a4d7a420b3ee2b58149b100d31 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 25 Jun 2020 14:54:02 -0700 Subject: [PATCH 0838/1427] Tests for bgpcfgd templates (#4841) * Tests for bgpcfgd templates --- .../bgpd/templates/dynamic/instance.conf.j2 | 2 +- .../bgpd/templates/general/instance.conf.j2 | 31 ++- src/sonic-bgpcfgd/.gitignore | 2 + src/sonic-bgpcfgd/app/__init__.py | 0 src/sonic-bgpcfgd/app/config.py | 103 ++++++++ src/sonic-bgpcfgd/app/log.py | 33 +++ src/sonic-bgpcfgd/app/template.py | 98 +++++++ src/sonic-bgpcfgd/app/util.py | 22 ++ src/sonic-bgpcfgd/app/vars.py | 1 + src/sonic-bgpcfgd/bgpcfgd | 245 +----------------- src/sonic-bgpcfgd/setup.py | 5 +- .../data/dynamic/instance.conf/param_all.json | 21 ++ .../dynamic/instance.conf/param_base.json | 19 ++ .../dynamic/instance.conf/result_all.conf | 22 ++ .../dynamic/instance.conf/result_base.conf | 22 ++ .../dynamic/peer-group.conf/param_all.json | 1 + .../dynamic/peer-group.conf/result_all.conf | 7 + .../data/dynamic/policies.conf/param_all.json | 1 + .../dynamic/policies.conf/result_all.conf | 9 + .../general/instance.conf/param_ASIC_v4.json | 15 ++ .../general/instance.conf/param_ASIC_v6.json | 15 ++ .../general/instance.conf/param_all_v4.json | 23 ++ .../general/instance.conf/param_all_v6.json | 23 ++ .../general/instance.conf/param_base_v4.json | 15 ++ .../general/instance.conf/param_base_v6.json | 15 ++ .../general/instance.conf/param_l2vpn.json | 18 ++ .../instance.conf/param_shutdown_1.json | 17 ++ .../instance.conf/param_shutdown_2.json | 17 ++ .../general/instance.conf/param_timers_1.json | 16 ++ .../general/instance.conf/param_timers_2.json | 16 ++ .../general/instance.conf/result_ASIC_v4.conf | 13 + .../general/instance.conf/result_ASIC_v6.conf | 13 + .../general/instance.conf/result_all_v4.conf | 17 ++ .../general/instance.conf/result_all_v6.conf | 17 ++ .../general/instance.conf/result_base_v4.conf | 12 + .../general/instance.conf/result_base_v6.conf | 12 + .../general/instance.conf/result_l2vpn.conf | 16 ++ .../instance.conf/result_shutdown_1.conf | 13 + .../instance.conf/result_shutdown_2.conf | 12 + .../instance.conf/result_timers_1.conf | 13 + .../instance.conf/result_timers_2.conf | 13 + .../general/peer-group.conf/param_all.json | 7 + .../general/peer-group.conf/param_base.json | 8 + .../general/peer-group.conf/result_all.conf | 30 +++ .../general/peer-group.conf/result_base.conf | 28 ++ .../data/general/policies.conf/param_all.json | 8 + .../general/policies.conf/param_base.json | 8 + .../general/policies.conf/result_all.conf | 25 ++ .../general/policies.conf/result_base.conf | 16 ++ .../monitors/instance.conf/param_all.json | 12 + .../monitors/instance.conf/result_all.conf | 13 + .../monitors/peer-group.conf/param_all.json | 3 + .../monitors/peer-group.conf/result_all.conf | 12 + .../monitors/policies.conf/param_all.json | 1 + .../monitors/policies.conf/result_all.conf | 9 + .../tests/test_ipv6_nexthop_global.py | 114 ++++++++ src/sonic-bgpcfgd/tests/test_sample.py | 4 - src/sonic-bgpcfgd/tests/test_templates.py | 129 +++++++++ src/sonic-bgpcfgd/tests/util.py | 16 ++ 59 files changed, 1169 insertions(+), 259 deletions(-) create mode 100644 src/sonic-bgpcfgd/app/__init__.py create mode 100644 src/sonic-bgpcfgd/app/config.py create mode 100644 src/sonic-bgpcfgd/app/log.py create mode 100644 src/sonic-bgpcfgd/app/template.py create mode 100644 src/sonic-bgpcfgd/app/util.py create mode 100644 src/sonic-bgpcfgd/app/vars.py create mode 100644 src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_all.json create mode 100644 src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_base.json create mode 100644 src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_base.conf create mode 100644 src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/param_all.json create mode 100644 src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/result_all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/param_all.json create mode 100644 src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/result_all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v4.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v6.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v4.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v6.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v4.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v6.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_l2vpn.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_1.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_2.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_1.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_2.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v4.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v6.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v4.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v6.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v4.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v6.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_l2vpn.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_1.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_2.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_1.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_2.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_all.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_base.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/result_base.conf create mode 100644 src/sonic-bgpcfgd/tests/data/monitors/instance.conf/param_all.json create mode 100644 src/sonic-bgpcfgd/tests/data/monitors/instance.conf/result_all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/param_all.json create mode 100644 src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/result_all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/monitors/policies.conf/param_all.json create mode 100644 src/sonic-bgpcfgd/tests/data/monitors/policies.conf/result_all.conf create mode 100644 src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py delete mode 100644 src/sonic-bgpcfgd/tests/test_sample.py create mode 100644 src/sonic-bgpcfgd/tests/test_templates.py create mode 100644 src/sonic-bgpcfgd/tests/util.py diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 index efb1546dac4b..5082b75005c2 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 @@ -34,5 +34,5 @@ neighbor {{ bgp_session['name'] }} activate exit-address-family ! -! end of template: bgpd/templates/BGP_SPEAKER/instance.conf.j2 +! end of template: bgpd/templates/dynamic/instance.conf.j2 ! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 index aed32d291c76..e4422a771664 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 @@ -6,7 +6,7 @@ {# set the bgp neighbor timers if they have not default values #} {% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} - neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} + neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] | default("60") }} {{ bgp_session['holdtime'] | default("180") }} {% endif %} ! {% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and CONFIG_DB__DEVICE_METADATA['localhost'].has_key('default_bgp_status') and CONFIG_DB__DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} @@ -15,36 +15,43 @@ ! {% if neighbor_addr | ipv4 %} address-family ipv4 -{% if 'ASIC' in bgp_session['name'] %} +{% if 'ASIC' in bgp_session['name'] %} neighbor {{ neighbor_addr }} peer-group PEER_V4_INT -{% else %} +{% else %} neighbor {{ neighbor_addr }} peer-group PEER_V4 {% endif %} +! {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V4_INT in {% endif %} +! {% elif neighbor_addr | ipv6 %} address-family ipv6 -{% if 'ASIC' in bgp_session['name'] %} +{% if 'ASIC' in bgp_session['name'] %} neighbor {{ neighbor_addr }} peer-group PEER_V6_INT -{% else %} +{% else %} neighbor {{ neighbor_addr }} peer-group PEER_V6 {% endif %} +! {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V6_INT in {% endif %} {% endif %} ! -{% if bgp_session['rrclient'] | int != 0 %} +{% if bgp_session.has_key('rrclient') and bgp_session['rrclient'] | int != 0 %} neighbor {{ neighbor_addr }} route-reflector-client -{% endif %} +{% endif %} ! -{% if bgp_session['nhopself'] | int != 0 %} +{% if bgp_session.has_key('nhopself') and bgp_session['nhopself'] | int != 0 %} neighbor {{ neighbor_addr }} next-hop-self -{% endif %} -{% if 'ASIC' in bgp_session['name'] %} +{% endif %} +! +{% if 'ASIC' in bgp_session['name'] %} neighbor {{ neighbor_addr }} next-hop-self force -{% endif %} +{% endif %} +! + neighbor {{ neighbor_addr }} activate + exit-address-family ! {% if bgp_session["asn"] == bgp_asn and CONFIG_DB__DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} address-family l2vpn evpn @@ -52,8 +59,6 @@ advertise-all-vni exit-address-family {% endif %} - neighbor {{ neighbor_addr }} activate - exit-address-family ! ! end of template: bgpd/templates/general/instance.conf.j2 ! diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore index 013f58816544..bb1ba531d1d6 100644 --- a/src/sonic-bgpcfgd/.gitignore +++ b/src/sonic-bgpcfgd/.gitignore @@ -2,5 +2,7 @@ build/ dist/ *.egg-info/ +app/*.pyc tests/*.pyc tests/__pycache__/ +.idea diff --git a/src/sonic-bgpcfgd/app/__init__.py b/src/sonic-bgpcfgd/app/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-bgpcfgd/app/config.py b/src/sonic-bgpcfgd/app/config.py new file mode 100644 index 000000000000..26639fe75e89 --- /dev/null +++ b/src/sonic-bgpcfgd/app/config.py @@ -0,0 +1,103 @@ +import os +import tempfile + +from .vars import g_debug +from .log import log_crit, log_err +from .util import run_command + + +class ConfigMgr(object): + """ The class represents frr configuration """ + def __init__(self): + self.current_config = None + + def reset(self): + """ Reset stored config """ + self.current_config = None + + def update(self): + """ Read current config from FRR """ + self.current_config = None + ret_code, out, err = run_command(["vtysh", "-c", "show running-config"]) + if ret_code != 0: + log_crit("can't update running config: rc=%d out='%s' err='%s'" % (ret_code, out, err)) + return + self.current_config = self.to_canonical(out) + + def push(self, cmd): + """ + Push new changes to FRR + :param cmd: configuration change for FRR. Type: String + :return: True if change was applied successfully, False otherwise + """ + return self.write(cmd) + + def write(self, cmd): + """ + Write configuration change to FRR. + :param cmd: new configuration to write into FRR. Type: String + :return: True if change was applied successfully, False otherwise + """ + fd, tmp_filename = tempfile.mkstemp(dir='/tmp') + os.close(fd) + with open(tmp_filename, 'w') as fp: + fp.write("%s\n" % cmd) + command = ["vtysh", "-f", tmp_filename] + ret_code, out, err = run_command(command) + if not g_debug: + os.remove(tmp_filename) + if ret_code != 0: + err_tuple = str(cmd), ret_code, out, err + log_err("ConfigMgr::push(): can't push configuration '%s', rc='%d', stdout='%s', stderr='%s'" % err_tuple) + if ret_code == 0: + self.current_config = None # invalidate config + return ret_code == 0 + + @staticmethod + def to_canonical(raw_config): + """ + Convert FRR config into canonical format + :param raw_config: config in frr format + :return: frr config in canonical format + """ + parsed_config = [] + lines_with_comments = raw_config.split("\n") + lines = [line for line in lines_with_comments + if not line.strip().startswith('!') and line.strip() != ''] + if len(lines) == 0: + return [] + cur_path = [lines[0]] + cur_offset = ConfigMgr.count_spaces(lines[0]) + for line in lines: + n_spaces = ConfigMgr.count_spaces(line) + s_line = line.strip() +# assert(n_spaces == cur_offset or (n_spaces + 1) == cur_offset or (n_spaces - 1) == cur_offset) + if n_spaces == cur_offset: + cur_path[-1] = s_line + elif n_spaces > cur_offset: + cur_path.append(s_line) + elif n_spaces < cur_offset: + cur_path = cur_path[:-2] + cur_path.append(s_line) + parsed_config.append(cur_path[:]) + cur_offset = n_spaces + return parsed_config + + @staticmethod + def count_spaces(line): + """ Count leading spaces in the line """ + return len(line) - len(line.lstrip()) + + @staticmethod + def from_canonical(canonical_config): + """ + Convert config from canonical format into FRR raw format + :param canonical_config: config in a canonical format + :return: config in the FRR raw format + """ + out = "" + for lines in canonical_config: + spaces = len(lines) - 1 + out += " " * spaces + lines[-1] + "\n" + + return out \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/log.py b/src/sonic-bgpcfgd/app/log.py new file mode 100644 index 000000000000..4083b13aa6ad --- /dev/null +++ b/src/sonic-bgpcfgd/app/log.py @@ -0,0 +1,33 @@ +import syslog + +from .vars import g_debug + +def log_debug(msg): + """ Send a message msg to the syslog as DEBUG """ + if g_debug: + syslog.syslog(syslog.LOG_DEBUG, msg) + + +def log_notice(msg): + """ Send a message msg to the syslog as NOTICE """ + syslog.syslog(syslog.LOG_NOTICE, msg) + + +def log_info(msg): + """ Send a message msg to the syslog as INFO """ + syslog.syslog(syslog.LOG_INFO, msg) + + +def log_warn(msg): + """ Send a message msg to the syslog as WARNING """ + syslog.syslog(syslog.LOG_WARNING, msg) + + +def log_err(msg): + """ Send a message msg to the syslog as ERR """ + syslog.syslog(syslog.LOG_ERR, msg) + + +def log_crit(msg): + """ Send a message msg to the syslog as CRIT """ + syslog.syslog(syslog.LOG_CRIT, msg) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/template.py b/src/sonic-bgpcfgd/app/template.py new file mode 100644 index 000000000000..5c8a4ed810bd --- /dev/null +++ b/src/sonic-bgpcfgd/app/template.py @@ -0,0 +1,98 @@ +from collections import OrderedDict +from functools import partial + +import jinja2 +import netaddr + + +class TemplateFabric(object): + """ Fabric for rendering jinja2 templates """ + def __init__(self, template_path = '/usr/share/sonic/templates'): + j2_template_paths = [template_path] + j2_loader = jinja2.FileSystemLoader(j2_template_paths) + j2_env = jinja2.Environment(loader=j2_loader, trim_blocks=False) + j2_env.filters['ipv4'] = self.is_ipv4 + j2_env.filters['ipv6'] = self.is_ipv6 + j2_env.filters['pfx_filter'] = self.pfx_filter + for attr in ['ip', 'network', 'prefixlen', 'netmask']: + j2_env.filters[attr] = partial(self.prefix_attr, attr) + self.env = j2_env + + def from_file(self, filename): + """ + Read a template from a file + :param filename: filename of the file. Type String + :return: Jinja2 template object + """ + return self.env.get_template(filename) + + def from_string(self, tmpl): + """ + Read a template from a string + :param tmpl: Text representation of Jinja2 template + :return: Jinja2 template object + """ + return self.env.from_string(tmpl) + + @staticmethod + def is_ipv4(value): + """ Return True if the value is an ipv4 address """ + if not value: + return False + if isinstance(value, netaddr.IPNetwork): + addr = value + else: + try: + addr = netaddr.IPNetwork(str(value)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + return False + return addr.version == 4 + + @staticmethod + def is_ipv6(value): + """ Return True if the value is an ipv6 address """ + if not value: + return False + if isinstance(value, netaddr.IPNetwork): + addr = value + else: + try: + addr = netaddr.IPNetwork(str(value)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + return False + return addr.version == 6 + + @staticmethod + def prefix_attr(attr, value): + """ + Extract attribute from IPNetwork object + :param attr: attribute to extract + :param value: the string representation of ip prefix which will be converted to IPNetwork. + :return: the value of the extracted attribute + """ + if not value: + return None + else: + try: + prefix = netaddr.IPNetwork(str(value)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + return None + return str(getattr(prefix, attr)) + + @staticmethod + def pfx_filter(value): + """INTERFACE Table can have keys in one of the two formats: + string or tuple - This filter skips the string keys and only + take into account the tuple. + For eg - VLAN_INTERFACE|Vlan1000 vs VLAN_INTERFACE|Vlan1000|192.168.0.1/21 + """ + table = OrderedDict() + + if not value: + return table + + for key, val in value.items(): + if not isinstance(key, tuple): + continue + table[key] = val + return table \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/util.py b/src/sonic-bgpcfgd/app/util.py new file mode 100644 index 000000000000..b25e651f1ec6 --- /dev/null +++ b/src/sonic-bgpcfgd/app/util.py @@ -0,0 +1,22 @@ +import subprocess + +from .log import log_debug, log_err + + +def run_command(command, shell=False, hide_errors=False): + """ + Run a linux command. The command is defined as a list. See subprocess.Popen documentation on format + :param command: command to execute. Type: List of strings + :param shell: execute the command through shell when True. Type: Boolean + :param hide_errors: don't report errors to syslog when True. Type: Boolean + :return: Tuple: integer exit code from the command, stdout as a string, stderr as a string + """ + log_debug("execute command '%s'." % str(command)) + p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + if p.returncode != 0: + if not hide_errors: + print_tuple = p.returncode, str(command), stdout, stderr + log_err("command execution returned %d. Command: '%s', stdout: '%s', stderr: '%s'" % print_tuple) + + return p.returncode, stdout, stderr \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/vars.py b/src/sonic-bgpcfgd/app/vars.py new file mode 100644 index 000000000000..11377fc87f93 --- /dev/null +++ b/src/sonic-bgpcfgd/app/vars.py @@ -0,0 +1 @@ +g_debug = False diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd index adc142c109d2..0fbe44602a22 100755 --- a/src/sonic-bgpcfgd/bgpcfgd +++ b/src/sonic-bgpcfgd/bgpcfgd @@ -1,260 +1,27 @@ #!/usr/bin/env python import sys -import subprocess import datetime import time import syslog import signal import traceback import os -import tempfile import json -from collections import defaultdict, OrderedDict -from pprint import pprint -from functools import partial +from collections import defaultdict import yaml import jinja2 import netaddr from swsscommon import swsscommon +from app.vars import g_debug +from app.log import log_debug, log_notice, log_info, log_warn, log_err, log_crit +from app.template import TemplateFabric +from app.config import ConfigMgr +from app.util import run_command g_run = True -g_debug = False - - -def log_debug(msg): - """ Send a message msg to the syslog as DEBUG """ - if g_debug: - syslog.syslog(syslog.LOG_DEBUG, msg) - -def log_notice(msg): - """ Send a message msg to the syslog as NOTICE """ - syslog.syslog(syslog.LOG_NOTICE, msg) - -def log_info(msg): - """ Send a message msg to the syslog as INFO """ - syslog.syslog(syslog.LOG_INFO, msg) - -def log_warn(msg): - """ Send a message msg to the syslog as WARNING """ - syslog.syslog(syslog.LOG_WARNING, msg) - -def log_err(msg): - """ Send a message msg to the syslog as ERR """ - syslog.syslog(syslog.LOG_ERR, msg) - -def log_crit(msg): - """ Send a message msg to the syslog as CRIT """ - syslog.syslog(syslog.LOG_CRIT, msg) - - -def run_command(command, shell=False, hide_errors=False): - """ - Run a linux command. The command is defined as a list. See subprocess.Popen documentation on format - :param command: command to execute. Type: List of strings - :param shell: execute the command through shell when True. Type: Boolean - :param hide_errors: don't report errors to syslog when True. Type: Boolean - :return: Tuple: integer exit code from the command, stdout as a string, stderr as a string - """ - log_debug("execute command '%s'." % str(command)) - p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - if p.returncode != 0: - if not hide_errors: - print_tuple = p.returncode, str(command), stdout, stderr - log_err("command execution returned %d. Command: '%s', stdout: '%s', stderr: '%s'" % print_tuple) - - return p.returncode, stdout, stderr - - -class ConfigMgr(object): - """ The class represents frr configuration """ - def __init__(self): - self.current_config = None - - def reset(self): - """ Reset stored config """ - self.current_config = None - - def update(self): - """ Read current config from FRR """ - self.current_config = None - ret_code, out, err = run_command(["vtysh", "-c", "show running-config"]) - if ret_code != 0: - log_crit("can't update running config: rc=%d out='%s' err='%s'" % (ret_code, out, err)) - return - self.current_config = self.to_canonical(out) - - def push(self, cmd): - """ - Push new changes to FRR - :param cmd: configuration change for FRR. Type: String - :return: True if change was applied successfully, False otherwise - """ - return self.write(cmd) - - def write(self, cmd): - """ - Write configuration change to FRR. - :param cmd: new configuration to write into FRR. Type: String - :return: True if change was applied successfully, False otherwise - """ - fd, tmp_filename = tempfile.mkstemp(dir='/tmp') - os.close(fd) - with open(tmp_filename, 'w') as fp: - fp.write("%s\n" % cmd) - command = ["vtysh", "-f", tmp_filename] - ret_code, out, err = run_command(command) - if not g_debug: - os.remove(tmp_filename) - if ret_code != 0: - err_tuple = str(cmd), ret_code, out, err - log_err("ConfigMgr::push(): can't push configuration '%s', rc='%d', stdout='%s', stderr='%s'" % err_tuple) - if ret_code == 0: - self.current_config = None # invalidate config - return ret_code == 0 - - @staticmethod - def to_canonical(raw_config): - """ - Convert FRR config into canonical format - :param raw_config: config in frr format - :return: frr config in canonical format - """ - parsed_config = [] - cur_offset = 0 - lines = raw_config.split("\n") - cur_path = [lines[0]] - for line in lines: - if line.strip().startswith('!') or line.strip() == '': - continue - n_spaces = ConfigMgr.count_spaces(line) - s_line = line.strip() - assert(n_spaces == cur_offset or (n_spaces + 1) == cur_offset or (n_spaces - 1) == cur_offset) - if n_spaces == cur_offset: - cur_path[-1] = s_line - elif n_spaces > cur_offset: - cur_path.append(s_line) - elif n_spaces < cur_offset: - cur_path = cur_path[:-2] - cur_path.append(s_line) - parsed_config.append(cur_path[:]) - cur_offset = n_spaces - return parsed_config - - @staticmethod - def count_spaces(line): - """ Count leading spaces in the line """ - return len(line) - len(line.lstrip()) - - @staticmethod - def from_canonical(canonical_config): - """ - Convert config from canonical format into FRR raw format - :param canonical_config: config in a canonical format - :return: config in the FRR raw format - """ - out = "" - for lines in canonical_config: - spaces = len(lines) - 1 - out += " " * spaces + lines[-1] + "\n" - - return out - - -class TemplateFabric(object): - """ Fabric for rendering jinja2 templates """ - def __init__(self): - j2_template_paths = ['/usr/share/sonic/templates'] - j2_loader = jinja2.FileSystemLoader(j2_template_paths) - j2_env = jinja2.Environment(loader=j2_loader, trim_blocks=False) - j2_env.filters['ipv4'] = self.is_ipv4 - j2_env.filters['ipv6'] = self.is_ipv6 - j2_env.filters['pfx_filter'] = self.pfx_filter - for attr in ['ip', 'network', 'prefixlen', 'netmask']: - j2_env.filters[attr] = partial(self.prefix_attr, attr) - self.env = j2_env - - def from_file(self, filename): - """ - Read a template from a file - :param filename: filename of the file. Type String - :return: Jinja2 template object - """ - return self.env.get_template(filename) - - def from_string(self, tmpl): - """ - Read a template from a string - :param tmpl: Text representation of Jinja2 template - :return: Jinja2 template object - """ - return self.env.from_string(tmpl) - - @staticmethod - def is_ipv4(value): - """ Return True if the value is an ipv4 address """ - if not value: - return False - if isinstance(value, netaddr.IPNetwork): - addr = value - else: - try: - addr = netaddr.IPNetwork(str(value)) - except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): - return False - return addr.version == 4 - - @staticmethod - def is_ipv6(value): - """ Return True if the value is an ipv6 address """ - if not value: - return False - if isinstance(value, netaddr.IPNetwork): - addr = value - else: - try: - addr = netaddr.IPNetwork(str(value)) - except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): - return False - return addr.version == 6 - - @staticmethod - def prefix_attr(attr, value): - """ - Extract attribute from IPNetwork object - :param attr: attribute to extract - :param value: the string representation of ip prefix which will be converted to IPNetwork. - :return: the value of the extracted attribute - """ - if not value: - return None - else: - try: - prefix = netaddr.IPNetwork(str(value)) - except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): - return None - return str(getattr(prefix, attr)) - - @staticmethod - def pfx_filter(value): - """INTERFACE Table can have keys in one of the two formats: - string or tuple - This filter skips the string keys and only - take into account the tuple. - For eg - VLAN_INTERFACE|Vlan1000 vs VLAN_INTERFACE|Vlan1000|192.168.0.1/21 - """ - table = OrderedDict() - - if not value: - return table - - for key, val in value.items(): - if not isinstance(key, tuple): - continue - table[key] = val - return table class Directory(object): diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index 2aea5cdb0c5a..fae1c313850e 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -1,13 +1,14 @@ #!/usr/bin/env python -from setuptools import setup +import setuptools -setup(name='sonic-bgpcfgd', +setuptools.setup(name='sonic-bgpcfgd', version='1.0', description='Utility to dynamically generate BGP configuration for FRR', author='Pavel Shirshov', author_email='pavelsh@microsoft.com', url='https://github.com/Azure/sonic-buildimage', + packages=setuptools.find_packages(), scripts=['bgpcfgd'], install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], setup_requires=['pytest-runner', 'pytest'], diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_all.json new file mode 100644 index 000000000000..c4134ff29806 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_all.json @@ -0,0 +1,21 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "deployment_id": "5" + } + }, + "CONFIG_DB__LOOPBACK_INTERFACE": { + "Loopback1|55.55.55.55/32": {} + }, + "bgp_session": { + "ip_range": "10.10.20.0/24,20.20.20.0/24", + "name": "dyn_name", + "peer_asn": "11111", + "src_address": "1.1.1.1" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_base.json new file mode 100644 index 000000000000..04fd24fa0819 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_base.json @@ -0,0 +1,19 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "deployment_id": "5" + } + }, + "CONFIG_DB__LOOPBACK_INTERFACE": { + "Loopback1|55.55.55.55/32": {} + }, + "bgp_session": { + "ip_range": "10.10.20.0/24,20.20.20.0/24", + "name": "dyn_name" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_all.conf new file mode 100644 index 000000000000..1ffc3d34343e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_all.conf @@ -0,0 +1,22 @@ +! +! template: bgpd/templates/dynamic/instance.conf.j2 +! + neighbor dyn_name peer-group + neighbor dyn_name passive + neighbor dyn_name ebgp-multihop 255 + neighbor dyn_name soft-reconfiguration inbound + neighbor dyn_name route-map FROM_BGP_SPEAKER in + neighbor dyn_name route-map TO_BGP_SPEAKER out + neighbor dyn_name remote-as 11111 + bgp listen range 10.10.20.0/24 peer-group dyn_name + bgp listen range 20.20.20.0/24 peer-group dyn_name + neighbor dyn_name update-source 1.1.1.1 + address-family ipv4 + neighbor dyn_name activate + exit-address-family + address-family ipv6 + neighbor dyn_name activate + exit-address-family +! +! end of template: bgpd/templates/dynamic/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_base.conf b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_base.conf new file mode 100644 index 000000000000..ac2a4f3e18d7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_base.conf @@ -0,0 +1,22 @@ +! +! template: bgpd/templates/dynamic/instance.conf.j2 +! + neighbor dyn_name peer-group + neighbor dyn_name passive + neighbor dyn_name ebgp-multihop 255 + neighbor dyn_name soft-reconfiguration inbound + neighbor dyn_name route-map FROM_BGP_SPEAKER in + neighbor dyn_name route-map TO_BGP_SPEAKER out + neighbor dyn_name remote-as 51111 + bgp listen range 10.10.20.0/24 peer-group dyn_name + bgp listen range 20.20.20.0/24 peer-group dyn_name + neighbor dyn_name update-source 55.55.55.55 + address-family ipv4 + neighbor dyn_name activate + exit-address-family + address-family ipv6 + neighbor dyn_name activate + exit-address-family +! +! end of template: bgpd/templates/dynamic/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/param_all.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/param_all.json @@ -0,0 +1 @@ +{} diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/result_all.conf new file mode 100644 index 000000000000..86d5c0297227 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/result_all.conf @@ -0,0 +1,7 @@ +! +! template: bgpd/templates/BGP_SPEAKER/peer-group.conf.j2 +! +! nothing is here +! +! end of template: bgpd/templates/BGP_SPEAKER/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/param_all.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/param_all.json @@ -0,0 +1 @@ +{} diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/result_all.conf new file mode 100644 index 000000000000..17ca09ec2a36 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/result_all.conf @@ -0,0 +1,9 @@ +! +! template: bgpd/templates/BGP_SPEAKER/policies.conf.j2 +! +route-map FROM_BGP_SPEAKER permit 10 +! +route-map TO_BGP_SPEAKER deny 1 +! +! end of template: bgpd/templates/BGP_SPEAKER/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v4.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v4.json new file mode 100644 index 000000000000..1691732b39b4 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v4.json @@ -0,0 +1,15 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "_ASIC_" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v6.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v6.json new file mode 100644 index 000000000000..89a4117fdac2 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v6.json @@ -0,0 +1,15 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + }, + "neighbor_addr": "FC00::", + "bgp_session": { + "asn": "555", + "name": "_ASIC_" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v4.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v4.json new file mode 100644 index 000000000000..c2391674a56e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v4.json @@ -0,0 +1,23 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something", + "rrclient": "1", + "nhopself": "1" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v6.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v6.json new file mode 100644 index 000000000000..d19139a75a88 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v6.json @@ -0,0 +1,23 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "neighbor_addr": "fc::10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something", + "rrclient": "1", + "nhopself": "1" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v4.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v4.json new file mode 100644 index 000000000000..e2e59575cbb3 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v4.json @@ -0,0 +1,15 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v6.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v6.json new file mode 100644 index 000000000000..5e79378e3e00 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v6.json @@ -0,0 +1,15 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + }, + "neighbor_addr": "fc00::2", + "bgp_session": { + "asn": "555", + "name": "remote_peer" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_l2vpn.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_l2vpn.json new file mode 100644 index 000000000000..e679bff08435 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_l2vpn.json @@ -0,0 +1,18 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "type": "SpineChassisFrontendRouter" + } + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + }, + "bgp_asn": "555" +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_1.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_1.json new file mode 100644 index 000000000000..b7c1e2075f02 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_1.json @@ -0,0 +1,17 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "default_bgp_status": "down" + } + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_2.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_2.json new file mode 100644 index 000000000000..610254a2b2ba --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_2.json @@ -0,0 +1,17 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "default_bgp_status": "up" + } + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_1.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_1.json new file mode 100644 index 000000000000..88d2b6defb2a --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_1.json @@ -0,0 +1,16 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_2.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_2.json new file mode 100644 index 000000000000..4b5c2bec220b --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_2.json @@ -0,0 +1,16 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "holdtime": "240" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v4.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v4.conf new file mode 100644 index 000000000000..1e89f822457a --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v4.conf @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description _ASIC_ + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4_INT + neighbor 10.10.10.10 next-hop-self force + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v6.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v6.conf new file mode 100644 index 000000000000..64d14dcd4fa5 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v6.conf @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor FC00:: remote-as 555 + neighbor FC00:: description _ASIC_ + address-family ipv6 + neighbor FC00:: peer-group PEER_V6_INT + neighbor FC00:: next-hop-self force + neighbor FC00:: activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v4.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v4.conf new file mode 100644 index 000000000000..2241bbf34146 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v4.conf @@ -0,0 +1,17 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 timers 5 30 + neighbor 10.10.10.10 shutdown + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 route-map FROM_BGP_PEER_V4_INT in + neighbor 10.10.10.10 route-reflector-client + neighbor 10.10.10.10 next-hop-self + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v6.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v6.conf new file mode 100644 index 000000000000..7194b0916620 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v6.conf @@ -0,0 +1,17 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor fc::10 remote-as 555 + neighbor fc::10 description remote_peer + neighbor fc::10 timers 5 30 + neighbor fc::10 shutdown + address-family ipv6 + neighbor fc::10 peer-group PEER_V6 + neighbor fc::10 route-map FROM_BGP_PEER_V6_INT in + neighbor fc::10 route-reflector-client + neighbor fc::10 next-hop-self + neighbor fc::10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v4.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v4.conf new file mode 100644 index 000000000000..2990d5aef7c7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v4.conf @@ -0,0 +1,12 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v6.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v6.conf new file mode 100644 index 000000000000..38ec714894ae --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v6.conf @@ -0,0 +1,12 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor fc00::2 remote-as 555 + neighbor fc00::2 description remote_peer + address-family ipv6 + neighbor fc00::2 peer-group PEER_V6 + neighbor fc00::2 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_l2vpn.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_l2vpn.conf new file mode 100644 index 000000000000..b30eaaa62a35 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_l2vpn.conf @@ -0,0 +1,16 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family + address-family l2vpn evpn + neighbor 10.10.10.10 activate + advertise-all-vni + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_1.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_1.conf new file mode 100644 index 000000000000..9303e3b9ab7f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_1.conf @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 shutdown + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_2.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_2.conf new file mode 100644 index 000000000000..2990d5aef7c7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_2.conf @@ -0,0 +1,12 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_1.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_1.conf new file mode 100644 index 000000000000..ffca0e6b69e6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_1.conf @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 timers 5 180 + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_2.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_2.conf new file mode 100644 index 000000000000..3a8ac3d90e3f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_2.conf @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 timers 60 240 + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_all.json new file mode 100644 index 000000000000..293ccc7990dc --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_all.json @@ -0,0 +1,7 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "type": "ToRRouter" + } + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json new file mode 100644 index 000000000000..046ffb1a6417 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json @@ -0,0 +1,8 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "type": "LeafRouter", + "sub_role": "BackEnd" + } + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_all.conf new file mode 100644 index 000000000000..63211ded8796 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_all.conf @@ -0,0 +1,30 @@ +! +! template: bgpd/templates/general/peer-group.conf.j2 +! + neighbor PEER_V4 peer-group + neighbor PEER_V4_INT peer-group + neighbor PEER_V6 peer-group + neighbor PEER_V6_INT peer-group + address-family ipv4 + neighbor PEER_V4 allowas-in 1 + neighbor PEER_V4_INT allowas-in 1 + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out + neighbor PEER_V4_INT soft-reconfiguration inbound + neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in + neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out + exit-address-family + address-family ipv6 + neighbor PEER_V6 allowas-in 1 + neighbor PEER_V6_INT allowas-in 1 + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out + neighbor PEER_V6_INT soft-reconfiguration inbound + neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in + neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/general/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_base.conf b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_base.conf new file mode 100644 index 000000000000..a681e7f08083 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_base.conf @@ -0,0 +1,28 @@ +! +! template: bgpd/templates/general/peer-group.conf.j2 +! + neighbor PEER_V4 peer-group + neighbor PEER_V4_INT peer-group + neighbor PEER_V6 peer-group + neighbor PEER_V6_INT peer-group + address-family ipv4 + neighbor PEER_V4_INT route-reflector-client + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out + neighbor PEER_V4_INT soft-reconfiguration inbound + neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in + neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out + exit-address-family + address-family ipv6 + neighbor PEER_V6_INT route-reflector-client + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out + neighbor PEER_V6_INT soft-reconfiguration inbound + neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in + neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/general/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json new file mode 100644 index 000000000000..148456fe960f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json @@ -0,0 +1,8 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "loopback0_ipv4": "10.10.10.10/32" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json new file mode 100644 index 000000000000..53bf5572eff3 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json @@ -0,0 +1,8 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "NotBackEnd" + } + }, + "loopback0_ipv4": "10.10.10.10/32" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf new file mode 100644 index 000000000000..1e3288b9a7da --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf @@ -0,0 +1,25 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +route-map FROM_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V4 permit 100 +! +route-map FROM_BGP_PEER_V6 permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +route-map FROM_BGP_PEER_V4_INT permit 2 + set originator-id 10.10.10.10 +! +route-map FROM_BGP_PEER_V6_INT permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6_INT permit 2 + set originator-id 10.10.10.10 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_base.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_base.conf new file mode 100644 index 000000000000..957264352209 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_base.conf @@ -0,0 +1,16 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +route-map FROM_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V4 permit 100 +! +route-map FROM_BGP_PEER_V6 permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/param_all.json new file mode 100644 index 000000000000..9ac3ceda978a --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/param_all.json @@ -0,0 +1,12 @@ +{ + "bgp_asn": "555", + "neighbor_addr": "10.20.30.40", + "bgp_session": { + "name": "monitor" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/result_all.conf new file mode 100644 index 000000000000..c8faaa895bd7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/result_all.conf @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/monitors/instance.conf.j2 +! + neighbor 10.20.30.40 remote-as 555 + neighbor 10.20.30.40 peer-group BGPMON + neighbor 10.20.30.40 description monitor + neighbor 10.20.30.40 activate + address-family ipv6 + neighbor 10.20.30.40 activate + exit-address-family +! +! end of template: bgpd/templates/BGPMON/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/param_all.json new file mode 100644 index 000000000000..4f45f8a0f3f4 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/param_all.json @@ -0,0 +1,3 @@ +{ + "loopback0_ipv4": "1.1.1.1/32" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/result_all.conf new file mode 100644 index 000000000000..d5e9624ff1a5 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/result_all.conf @@ -0,0 +1,12 @@ +! +! template: bgpd/templates/BGPMON/peer-group.conf.j2 +! + neighbor BGPMON peer-group + neighbor BGPMON update-source 1.1.1.1 + neighbor BGPMON route-map FROM_BGPMON in + neighbor BGPMON route-map TO_BGPMON out + neighbor BGPMON send-community + neighbor BGPMON maximum-prefix 1 +! +! end of template: bgpd/templates/BGPMON/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/param_all.json new file mode 100644 index 000000000000..9e26dfeeb6e6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/param_all.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/result_all.conf new file mode 100644 index 000000000000..8d53991064de --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/result_all.conf @@ -0,0 +1,9 @@ +! +! template: bgpd/templates/BGPMON/policies.conf.j2 +! +route-map FROM_BGPMON deny 10 +! +route-map TO_BGPMON permit 10 +! +! end of template: bgpd/templates/BGPMON/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py new file mode 100644 index 000000000000..bc6d01cdb536 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -0,0 +1,114 @@ +import os +import re + +from app.template import TemplateFabric +from .util import load_constants + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') + + +def parse_instance_conf(filename): + activate_re = re.compile(r'^neighbor\s+(\S+)\s+activate$') + with open(filename) as fp: + lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] + # Search all v6 neighbors + neighbors = {} + for line in lines: + if activate_re.match(line): + neighbor = activate_re.match(line).group(1) + if TemplateFabric.is_ipv6(neighbor): + neighbors[neighbor] = {} + # Extract peer-groups and route-maps + for neighbor, neighbor_data in neighbors.iteritems(): + route_map_in_re = re.compile(r'^neighbor\s+%s\s+route-map\s+(\S+) in$' % neighbor) + peer_group_re = re.compile(r'^neighbor\s+%s\s+peer-group\s+(\S+)$' % neighbor) + for line in lines: + if route_map_in_re.match(line): + assert "route-map" not in neighbor_data + neighbor_data["route-map"] = route_map_in_re.match(line).group(1) + if peer_group_re.match(line): + assert "peer-group" not in neighbor_data + neighbor_data["peer-group"] = peer_group_re.match(line).group(1) + # Ensure that every ivp6 neighbor has either route-map or peer-group + for neighbor, neighbor_data in neighbors.iteritems(): + assert "route-map" in neighbor_data or "peer-group" in neighbor_data,\ + "IPv6 neighbor '%s' must have either route-map in or peer-group %s" % (neighbor, neighbor_data) + return neighbors + +def load_results(path, dir_name): + result_files = [] + for fname in os.listdir(os.path.join(path, dir_name)): + if not fname.startswith("result_"): + continue + full_fname = os.path.join(path, dir_name, fname) + if not os.path.isfile(full_fname): + continue + result_files.append(full_fname) + return result_files + +def process_instances(path): + result_files = load_results(path, "instance.conf") + # search for ipv6 neighbors + neighbors_list = [] + for fname in result_files: + neighbors = parse_instance_conf(fname) + if neighbors: + neighbors_list.append(neighbors) + return neighbors_list + +def parse_peer_group_conf(filename, pg_name): + route_map_re = re.compile(r'^neighbor\s+%s\s+route-map\s+(\S+)\s+in$' % pg_name) + with open(filename) as fp: + lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] + route_maps = set() + for line in lines: + if route_map_re.match(line): + route_map = route_map_re.match(line).group(1) + route_maps.add(route_map) + return route_maps + +def extract_rm_from_peer_group(path, peer_group_name): + result_files = load_results(path, "peer-group.conf") + rm_set = set() + for fname in result_files: + route_maps = parse_peer_group_conf(fname, peer_group_name) + if route_maps: + rm_set |= route_maps + return list(rm_set) + +def check_routemap_in_file(filename, route_map_name): + route_map_re = re.compile(r'^route-map\s+%s\s+(\S+)' % route_map_name) + set_re = re.compile(r'set ipv6 next-hop prefer-global') + with open(filename) as fp: + lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] + found_first_entry = False + for line in lines: + err_msg = "route-map %s doesn't have mandatory 'set ipv6 next-hop prefer-global' entry as the first rule" % route_map_name + assert not (found_first_entry and line.startswith("route-map")), err_msg + if found_first_entry and set_re.match(line): + break # We're good + if route_map_re.match(line): + err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name + assert route_map_re.match(line).group(1) == 'permit', err_msg + found_first_entry = True + return found_first_entry + +def check_routemap(path, route_map_name): + result_files = load_results(path, "policies.conf") + checked = False + for fname in result_files: + checked = checked or check_routemap_in_file(fname, route_map_name) + assert checked, "route-map %s wasn't found" % route_map_name + +def test_v6_next_hop_global(): + paths = ["tests/data/%s" % value for value in load_constants().values()] + for path in paths: + test_cases = process_instances(path) + for test_case in test_cases: + for neighbor_value in test_case.values(): + if 'route-map' in neighbor_value: + check_routemap(path, neighbor_value['route-map']) + elif 'peer-group' in neighbor_value: + route_map_in_list = extract_rm_from_peer_group(path, neighbor_value['peer-group']) + for route_map_in in route_map_in_list: + check_routemap(path, route_map_in) diff --git a/src/sonic-bgpcfgd/tests/test_sample.py b/src/sonic-bgpcfgd/tests/test_sample.py deleted file mode 100644 index 3adfe439d29c..000000000000 --- a/src/sonic-bgpcfgd/tests/test_sample.py +++ /dev/null @@ -1,4 +0,0 @@ -import pytest - -def test_sample(): - assert True diff --git a/src/sonic-bgpcfgd/tests/test_templates.py b/src/sonic-bgpcfgd/tests/test_templates.py new file mode 100644 index 000000000000..bd0bf9dbb484 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_templates.py @@ -0,0 +1,129 @@ +import os +import json + + +from app.template import TemplateFabric +from app.config import ConfigMgr +from .util import load_constants + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') + + +def load_tests(peer_type, template_name): + constants = load_constants() + path = "tests/data/%s/%s" % (constants[peer_type], template_name) + param_files = [name for name in os.listdir(path) + if os.path.isfile(os.path.join(path, name)) and name.startswith("param_")] + tests = [] + for param_fname in param_files: + casename = param_fname.replace("param_", "").replace(".json", "") + result_fname = "result_%s.conf" % casename + full_param_fname = os.path.join(path, param_fname) + full_result_fname = os.path.join(path, result_fname) + tests.append((casename, full_param_fname, full_result_fname)) + tmpl_path = os.path.join("bgpd", "templates", constants[peer_type], "%s.j2" % template_name) + return tmpl_path, tests + +def load_json(fname): + with open(fname) as param_fp: + raw_params = json.load(param_fp) + params = {} + for table_key, table_entries in raw_params.items(): + if table_key.startswith("CONFIG_DB__"): + # convert CONFIG_DB__* entries keys into tuple if needed + new_table_entries = {} + for entry_key, entry_value in table_entries.items(): + if '|' in entry_key: + new_key = tuple(entry_key.split('|')) + else: + new_key = entry_key + new_table_entries[new_key] = entry_value + params[table_key] = new_table_entries + else: + params[table_key] = table_entries + return params + +def compress_comments(raw_config): + comment_counter = 0 + output = [] + for line in raw_config.split('\n'): + stripped_line = line.strip() + # Skip empty lines + if stripped_line == '': + pass + # Write lines without comments + elif not stripped_line.startswith('!'): + if comment_counter > 0: + output.append("!") + comment_counter = 0 + output.append(line) + # Write non-empty comments + elif stripped_line.startswith('!') and len(stripped_line) > 1: + if comment_counter > 0: + output.append("!") + comment_counter = 0 + output.append(line) + # Count empty comments + else: # stripped_line == '!' + comment_counter += 1 + # Flush last comment if we have one + if comment_counter > 0: + output.append("!") + return "\n".join(output) + "\n" + +def write_result(fname, raw_result): + with open(fname, 'w') as fp: + raw_result_w_commpressed_comments = compress_comments(raw_result) + fp.write(raw_result_w_commpressed_comments) + +def run_tests(test_name, template_fname, tests): + tf = TemplateFabric(TEMPLATE_PATH) + template = tf.from_file(template_fname) + for case_name, param_fname, result_fname in tests: + params = load_json(param_fname) + raw_generated_result = str(template.render(params)) + assert "None" not in raw_generated_result, "Test %s.%s" % (test_name, case_name) + # this is used only for initial generation write_result(result_fname, raw_generated_result) + canonical_generated_result = ConfigMgr.to_canonical(raw_generated_result) + with open(result_fname) as result_fp: + raw_saved_result = result_fp.read() + canonical_saved_result = ConfigMgr.to_canonical(raw_saved_result) + assert canonical_saved_result == canonical_generated_result, "Test %s.%s" % (test_name, case_name) + +# Tests + +def test_general_policies(): + test_data = load_tests("general", "policies.conf") + run_tests("general_policies", *test_data) + +def test_general_pg(): + test_data = load_tests("general", "peer-group.conf") + run_tests("general_pg", *test_data) + +def test_general_instance(): + test_data = load_tests("general", "instance.conf") + run_tests("general_instance", *test_data) + +def test_dynamic_policies(): + test_data = load_tests("dynamic", "policies.conf") + run_tests("dynamic_policies", *test_data) + +def test_dynamic_pg(): + test_data = load_tests("dynamic", "peer-group.conf") + run_tests("dynamic_pg", *test_data) + +def test_dynamic_instance(): + test_data = load_tests("dynamic", "instance.conf") + run_tests("dynamic_instance", *test_data) + +def test_monitors_policies(): + test_data = load_tests("monitors", "policies.conf") + run_tests("monitors_policies", *test_data) + +def test_monitors_pg(): + test_data = load_tests("monitors", "peer-group.conf") + run_tests("monitors_pg", *test_data) + +def test_monitors_instance(): + test_data = load_tests("monitors", "instance.conf") + run_tests("monitors_instance", *test_data) diff --git a/src/sonic-bgpcfgd/tests/util.py b/src/sonic-bgpcfgd/tests/util.py new file mode 100644 index 000000000000..0bc12b060aec --- /dev/null +++ b/src/sonic-bgpcfgd/tests/util.py @@ -0,0 +1,16 @@ +import os +import yaml + +CONSTANTS_PATH = os.path.abspath('../../files/image_config/constants/constants.yml') + +def load_constants(): + with open(CONSTANTS_PATH) as f: + data = yaml.load(f) + result = {} + assert "constants" in data, "'constants' key not found in constants.yml" + assert "bgp" in data["constants"], "'bgp' key not found in constants.yml" + assert "peers" in data["constants"]["bgp"], "'peers' key not found in constants.yml" + for name, value in data["constants"]["bgp"]["peers"].items(): + assert "template_dir" in value, "'template_dir' key not found for peer '%s'" % name + result[name] = value["template_dir"] + return result \ No newline at end of file From b88770a67bd4f725aea4f0da1c32d6908e01b60b Mon Sep 17 00:00:00 2001 From: carycelestica <39321413+carycelestica@users.noreply.github.com> Date: Fri, 26 Jun 2020 06:02:21 +0800 Subject: [PATCH 0839/1427] add PCIe config file (#4724) --- .../x86_64-cel_e1031-r0/plugins/pcie.yaml | 76 +++++++++++++++++++ .../x86_64-cel_seastone-r0/plugins/pcie.yaml | 75 ++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 device/celestica/x86_64-cel_e1031-r0/plugins/pcie.yaml create mode 100644 device/celestica/x86_64-cel_seastone-r0/plugins/pcie.yaml diff --git a/device/celestica/x86_64-cel_e1031-r0/plugins/pcie.yaml b/device/celestica/x86_64-cel_e1031-r0/plugins/pcie.yaml new file mode 100644 index 000000000000..485ac3512fe5 --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/plugins/pcie.yaml @@ -0,0 +1,76 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 1f0f + name: 'Host bridge: Intel Corporation Atom processor C2000 SoC Transaction Router' +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3' +- bus: '00' + dev: '04' + fn: '0' + id: 1f13 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 4' +- bus: '00' + dev: 0e + fn: '0' + id: 1f14 + name: 'Host bridge: Intel Corporation Atom processor C2000 RAS' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '00' + dev: '16' + fn: '0' + id: 1f2c + name: 'USB controller: Intel Corporation Atom processor C2000 USB Enhanced Host Controller' +- bus: '00' + dev: '17' + fn: '0' + id: 1f22 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA2 Controller' +- bus: '00' + dev: 1f + fn: '0' + id: 1f38 + name: 'ISA bridge: Intel Corporation Atom processor C2000 PCU' +- bus: '00' + dev: 1f + fn: '3' + id: 1f3c + name: 'SMBus: Intel Corporation Atom processor C2000 PCU SMBus' +- bus: '01' + dev: '00' + fn: '0' + id: b340 + name: 'Ethernet controller: Broadcom Limited Device b340' +- bus: '01' + dev: '00' + fn: '1' + id: b340 + name: 'Ethernet controller: Broadcom Limited Device b340' + diff --git a/device/celestica/x86_64-cel_seastone-r0/plugins/pcie.yaml b/device/celestica/x86_64-cel_seastone-r0/plugins/pcie.yaml new file mode 100644 index 000000000000..18e52be96474 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/plugins/pcie.yaml @@ -0,0 +1,75 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 1f0c + name: 'Host bridge: Intel Corporation Atom processor C2000 SoC Transaction Router' +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3' +- bus: '00' + dev: 0e + fn: '0' + id: 1f14 + name: 'Host bridge: Intel Corporation Atom processor C2000 RAS' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '00' + dev: '16' + fn: '0' + id: 1f2c + name: 'USB controller: Intel Corporation Atom processor C2000 USB Enhanced Host Controller' +- bus: '00' + dev: '17' + fn: '0' + id: 1f22 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA2 Controller' +- bus: '00' + dev: '18' + fn: '0' + id: 1f32 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA3 Controller' +- bus: '00' + dev: 1f + fn: '0' + id: 1f38 + name: 'ISA bridge: Intel Corporation Atom processor C2000 PCU' +- bus: '00' + dev: 1f + fn: '3' + id: 1f3c + name: 'SMBus: Intel Corporation Atom processor C2000 PCU SMBus' +- bus: '01' + dev: '00' + fn: '0' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC' +- bus: '01' + dev: '00' + fn: '1' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC' From ddf8c8bb3c291a33012c794104e8ec01a6819cee Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Thu, 25 Jun 2020 16:46:27 -0700 Subject: [PATCH 0840/1427] [rules/sonic-utilities.mk]: Add libyang as build time dependencies for sonic-utilities. (#4850) sonic-utils has sonic-yang-mgmt as build time deps, which inturn installs libyang. libyang is needed to run newly added test. If sonic-yang-mgmt is already built then libyang will not be installed in slave docker without this PR and test will not run. Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com --- rules/sonic-utilities.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index c9185596d794..6938a3790d20 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -12,5 +12,7 @@ SONIC_UTILS = python-sonic-utilities_1.2-1_all.deb $(SONIC_UTILS)_SRC_PATH = $(SRC_PATH)/sonic-utilities -$(SONIC_UTILS)_WHEEL_DEPENDS += $(SONIC_CONFIG_ENGINE) $(SONIC_YANG_MGMT_PY) +$(SONIC_UTILS)_DEBS_DEPENDS = $(LIBYANG) $(LIBYANG_CPP) $(LIBYANG_PY2) \ + $(LIBYANG_PY3) +$(SONIC_UTILS)_WHEEL_DEPENDS = $(SONIC_CONFIG_ENGINE) $(SONIC_YANG_MGMT_PY) SONIC_PYTHON_STDEB_DEBS += $(SONIC_UTILS) From b8ad0ed4e47eef7d5721c482917d936ad9edaada Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Thu, 25 Jun 2020 17:03:14 -0700 Subject: [PATCH 0841/1427] [Monit] Use the string "/usr/bin/syncd\s" to monitor the syncd process (#4706) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **- Why I did it** After discussed with Joe, we use the string "/usr/bin/syncd\s" in Monit configuration file to monitor syncd process on Broadcom and Mellanox. Due to my careless, I did not find this bug during the previous testing. If we use the string "/usr/bin/syncd" in Monit configuration file to monitor the syncd process, Monit will not detect whether syncd process is running or not. If we ran the command `sudo monit procmactch “/usr/bin/syncdâ€` on Broadcom, there will be three processes in syncd container which matched this "/usr/bin/syncd": `/bin/bash /usr/bin/syncd.sh wait`, `/usr/bin/dsserve /usr/bin/syncd –diag -u -p /etc/sai.d/sai.profile` and `/usr/bin/syncd –diag - u -p /etc/sai.d/said.profile`. Monit will select the processes with the highest uptime (at there `/bin/bash /usr/bin/syncd.sh wait`) to match and did not select `/usr/bin/syncd –diag -u -p /etc/sai.d/said.profile` to match. Similarly, On Mellanox Monit will also select the process with the highest uptime (at there `/bin/bash /usr/bin/syncd.sh wait`) to match and did not select `/usr/bin/syncd –diag -u -p /etc/sai.d/said.profile` to match. That is why Monit is unable to detect whether syncd process is running or not if we use the string “/usr/bin/syncd†in Monit configuration file. If we use the string "/usr/bin/syncd\s" in Monit configuration file, Monit can filter out the process `/bin/bash /usr/bin/syncd.sh wait` and thus can correctly monitor the syncd process. **- How I did it** **- How to verify it** Signed-off-by: Yong Zhao --- platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd | 2 +- .../broadcom/docker-syncd-brcm/base_image_files/monit_syncd | 2 +- platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd | 2 +- .../centec/docker-syncd-centec/base_image_files/monit_syncd | 2 +- .../docker-syncd-mrvl/base_image_files/monit_syncd | 2 +- .../docker-syncd-mrvl/base_image_files/monit_syncd | 2 +- platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd | 2 +- .../mellanox/docker-syncd-mlnx/base_image_files/monit_syncd | 2 +- .../nephos/docker-syncd-nephos/base_image_files/monit_syncd | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd index 3079618990ed..75391f90ac32 100644 --- a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd +++ b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd" +check process syncd matching "/usr/bin/syncd\s" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd index 0b9ec741cd57..81c0b6ef6bc6 100644 --- a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd @@ -4,7 +4,7 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd" +check process syncd matching "/usr/bin/syncd\s" if does not exist for 5 times within 5 cycles then alert check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" diff --git a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd index 3079618990ed..75391f90ac32 100644 --- a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd +++ b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd" +check process syncd matching "/usr/bin/syncd\s" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd index 3079618990ed..75391f90ac32 100644 --- a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd +++ b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd" +check process syncd matching "/usr/bin/syncd\s" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd index 3079618990ed..75391f90ac32 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd" +check process syncd matching "/usr/bin/syncd\s" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd index 3079618990ed..75391f90ac32 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd" +check process syncd matching "/usr/bin/syncd\s" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd index 3079618990ed..75391f90ac32 100644 --- a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd" +check process syncd matching "/usr/bin/syncd\s" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd index 3079618990ed..75391f90ac32 100644 --- a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd +++ b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd" +check process syncd matching "/usr/bin/syncd\s" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd index 0b9ec741cd57..81c0b6ef6bc6 100644 --- a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd +++ b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd @@ -4,7 +4,7 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd" +check process syncd matching "/usr/bin/syncd\s" if does not exist for 5 times within 5 cycles then alert check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" From 921d132a322bae512739defd7eea7fe4b76a277b Mon Sep 17 00:00:00 2001 From: Shuba Viswanathan <42399057+shubav@users.noreply.github.com> Date: Thu, 25 Jun 2020 17:45:16 -0700 Subject: [PATCH 0842/1427] [sonic-mgmt]: Support for pytest-html to control logs better (#4791) The current stdout file which also includes the dut logs are very verbose and noisy. We have manually installed it in the sonic-mgmt docker in our organization and tuned the pytest settings to produce very helpful and concise logs. pytest-html plugins can be used to post-process the output in various ways based on our different and unique organizational needs. Hence proposing to add this pkt to the docker file --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index acb4417636ec..3c2bbff2504e 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -55,6 +55,7 @@ RUN pip install cffi==1.10.0 \ pyro4 \ pysnmp==4.2.5 \ pytest-repeat \ + pytest-html \ pytest-xdist==1.28.0 \ pytest==4.6.5 \ redis \ From 4fa81b4f8d97281f19bd4cce379cd72eb56fa259 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Thu, 25 Jun 2020 21:18:21 -0700 Subject: [PATCH 0843/1427] [dockers] Update critical_processes file syntax (#4831) **- Why I did it** Initially, the critical_processes file contains either the name of critical process or the name of group. For example, the critical_processes file in the dhcp_relay container contains a single group name `isc-dhcp-relay`. When testing the autorestart feature of each container, we need get all the critical processes and test whether a container can be restarted correctly if one of its critical processes is killed. However, it will be difficult to differentiate whether the names in the critical_processes file are the critical processes or group names. At the same time, changing the syntax in this file will separate the individual process from the groups and also makes it clear to the user. Right now the critical_processes file contains two different kind of entries. One is "program:xxx" which indicates a critical process. Another is "group:xxx" which indicates a group of critical processes managed by supervisord using the name "xxx". At the same time, I also updated the logic to parse the file critical_processes in supervisor-proc-event-listener script. **- How to verify it** We can first enable the autorestart feature of a specified container for example `dhcp_relay` by running the comman `sudo config container feature autorestart dhcp_relay enabled` on DUT. Then we can select a critical process from the command `docker top dhcp_relay` and use the command `sudo kill -SIGKILL ` to kill that critical process. Final step is to check whether the container is restarted correctly or not. --- dockers/docker-database/critical_processes | 2 +- dockers/docker-dhcp-relay/critical_processes | 2 +- dockers/docker-fpm-frr/critical_processes | 10 ++--- dockers/docker-fpm-gobgp/critical_processes | 4 +- dockers/docker-fpm-quagga/critical_processes | 8 ++-- dockers/docker-lldp/critical_processes | 6 +-- dockers/docker-nat/critical_processes | 4 +- dockers/docker-orchagent/critical_processes | 20 +++++----- .../critical_processes | 6 +-- .../critical_processes | 2 +- dockers/docker-sflow/critical_processes | 2 +- dockers/docker-snmp/critical_processes | 4 +- .../docker-sonic-restapi/critical_processes | 2 +- .../docker-sonic-telemetry/critical_processes | 4 +- dockers/docker-teamd/critical_processes | 4 +- files/scripts/supervisor-proc-exit-listener | 38 ++++++++++++++++--- .../docker-syncd-bfn/critical_processes | 2 +- .../docker-syncd-brcm/critical_processes | 4 +- .../docker-syncd-cavm/critical_processes | 2 +- .../docker-syncd-centec/critical_processes | 2 +- .../docker-syncd-mrvl/critical_processes | 2 +- .../docker-syncd-mrvl/critical_processes | 2 +- .../docker-syncd-mrvl/critical_processes | 2 +- .../docker-syncd-mlnx/critical_processes | 2 +- .../docker-syncd-nephos/critical_processes | 4 +- .../vs/docker-syncd-vs/critical_processes | 2 +- 26 files changed, 84 insertions(+), 58 deletions(-) diff --git a/dockers/docker-database/critical_processes b/dockers/docker-database/critical_processes index 7800f0fad3ff..53a45931dfc9 100644 --- a/dockers/docker-database/critical_processes +++ b/dockers/docker-database/critical_processes @@ -1 +1 @@ -redis +program:redis diff --git a/dockers/docker-dhcp-relay/critical_processes b/dockers/docker-dhcp-relay/critical_processes index ddb183963a67..855851bf2d68 100644 --- a/dockers/docker-dhcp-relay/critical_processes +++ b/dockers/docker-dhcp-relay/critical_processes @@ -1 +1 @@ -isc-dhcp-relay +group:isc-dhcp-relay diff --git a/dockers/docker-fpm-frr/critical_processes b/dockers/docker-fpm-frr/critical_processes index 8ea09e1bb538..2631fee15e66 100644 --- a/dockers/docker-fpm-frr/critical_processes +++ b/dockers/docker-fpm-frr/critical_processes @@ -1,5 +1,5 @@ -zebra -staticd -bgpd -fpmsyncd -bgpcfgd +program:zebra +program:staticd +program:bgpd +program:fpmsyncd +program:bgpcfgd diff --git a/dockers/docker-fpm-gobgp/critical_processes b/dockers/docker-fpm-gobgp/critical_processes index 2a9e47831e0d..789f4685244a 100644 --- a/dockers/docker-fpm-gobgp/critical_processes +++ b/dockers/docker-fpm-gobgp/critical_processes @@ -1,2 +1,2 @@ -gobgpd -fpmsyncd +program:gobgpd +program:fpmsyncd diff --git a/dockers/docker-fpm-quagga/critical_processes b/dockers/docker-fpm-quagga/critical_processes index f151af9c4bdd..2dceb501e3e5 100644 --- a/dockers/docker-fpm-quagga/critical_processes +++ b/dockers/docker-fpm-quagga/critical_processes @@ -1,4 +1,4 @@ -zebra -bgpd -fpmsyncd -bgpcfgd +program:zebra +program:bgpd +program:fpmsyncd +program:bgpcfgd diff --git a/dockers/docker-lldp/critical_processes b/dockers/docker-lldp/critical_processes index b845b70bb3f7..7a6b137a76f6 100644 --- a/dockers/docker-lldp/critical_processes +++ b/dockers/docker-lldp/critical_processes @@ -1,3 +1,3 @@ -lldpd -lldp-syncd -lldpmgrd +program:lldpd +program:lldp_syncd +program:lldpmgrd diff --git a/dockers/docker-nat/critical_processes b/dockers/docker-nat/critical_processes index d442976143f1..5edc5eedc3d5 100644 --- a/dockers/docker-nat/critical_processes +++ b/dockers/docker-nat/critical_processes @@ -1,2 +1,2 @@ -natmgrd -natsyncd +program:natmgrd +program:natsyncd diff --git a/dockers/docker-orchagent/critical_processes b/dockers/docker-orchagent/critical_processes index 7fd8a516520c..99f501e2cc03 100644 --- a/dockers/docker-orchagent/critical_processes +++ b/dockers/docker-orchagent/critical_processes @@ -1,10 +1,10 @@ -orchagent -portsyncd -neighsyncd -vlanmgrd -intfmgrd -portmgrd -buffermgrd -vrfmgrd -nbrmgrd -vxlanmgrd +program:orchagent +program:portsyncd +program:neighsyncd +program:vlanmgrd +program:intfmgrd +program:portmgrd +program:buffermgrd +program:vrfmgrd +program:nbrmgrd +program:vxlanmgrd diff --git a/dockers/docker-platform-monitor/critical_processes b/dockers/docker-platform-monitor/critical_processes index 9798dffc4c27..3165d13ecdbc 100644 --- a/dockers/docker-platform-monitor/critical_processes +++ b/dockers/docker-platform-monitor/critical_processes @@ -1,3 +1,3 @@ -ledd -xcvrd -psud +program:ledd +program:xcvrd +program:psud diff --git a/dockers/docker-router-advertiser/critical_processes b/dockers/docker-router-advertiser/critical_processes index 238a0346ac9f..a343765f78e0 100644 --- a/dockers/docker-router-advertiser/critical_processes +++ b/dockers/docker-router-advertiser/critical_processes @@ -1 +1 @@ -radvd +program:radvd diff --git a/dockers/docker-sflow/critical_processes b/dockers/docker-sflow/critical_processes index 5b24e2d8e1da..8180f8ad1c37 100644 --- a/dockers/docker-sflow/critical_processes +++ b/dockers/docker-sflow/critical_processes @@ -1 +1 @@ -sflowmgrd +program:sflowmgrd diff --git a/dockers/docker-snmp/critical_processes b/dockers/docker-snmp/critical_processes index e6039c5b9840..cff479d7fa11 100644 --- a/dockers/docker-snmp/critical_processes +++ b/dockers/docker-snmp/critical_processes @@ -1,2 +1,2 @@ -snmpd -snmp-subagent +program:snmpd +program:snmp-subagent diff --git a/dockers/docker-sonic-restapi/critical_processes b/dockers/docker-sonic-restapi/critical_processes index 3106eaa9410a..455b7fb2fa46 100644 --- a/dockers/docker-sonic-restapi/critical_processes +++ b/dockers/docker-sonic-restapi/critical_processes @@ -1 +1 @@ -restapi +program:restapi diff --git a/dockers/docker-sonic-telemetry/critical_processes b/dockers/docker-sonic-telemetry/critical_processes index d6953dd0c883..612a94d9edac 100644 --- a/dockers/docker-sonic-telemetry/critical_processes +++ b/dockers/docker-sonic-telemetry/critical_processes @@ -1,2 +1,2 @@ -telemetry -dialout +program:telemetry +program:dialout diff --git a/dockers/docker-teamd/critical_processes b/dockers/docker-teamd/critical_processes index b5c543df050d..286d6aef4c7a 100644 --- a/dockers/docker-teamd/critical_processes +++ b/dockers/docker-teamd/critical_processes @@ -1,2 +1,2 @@ -teammgrd -teamsyncd +program:teammgrd +program:teamsyncd diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index cf154b3a5c10..04a2a5001371 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -10,14 +10,42 @@ import swsssdk from supervisor import childutils -# Contents of file should be the names of critical processes (as defined in -# supervisor.conf file), one per line +# Each line of this file should specify either one critical process or one +# critical process group, (as defined in supervisord.conf file), in the +# following format: +# +# program: +# group: CRITICAL_PROCESSES_FILE = '/etc/supervisor/critical_processes' # This table in databse contains the features for container and each # feature for a row will be configured a state or number. CONTAINER_FEATURE_TABLE_NAME = 'CONTAINER_FEATURE' +# Read the critical processes/group names from CRITICAL_PROCESSES_FILE +def get_critical_group_and_process_list(): + critical_group_list = [] + critical_process_list = [] + + with open(CRITICAL_PROCESSES_FILE, 'r') as file: + for line in file: + line_info = line.strip(' \n').split(':') + if len(line_info) != 2: + syslog.syslog(syslog.LOG_ERR, "Syntax of the line {} in critical_processes file is incorrect. Exiting...".format(line)) + sys.exit(5) + + identifier_key = line_info[0].strip() + identifier_value = line_info[1].strip() + if identifier_key == "group" and identifier_value: + critical_group_list.append(identifier_value) + elif identifier_key == "program" and identifier_value: + critical_process_list.append(identifier_value) + else: + syslog.syslog(syslog.LOG_ERR, "Syntax of the line {} in critical_processes file is incorrect. Exiting...".format(line)) + sys.exit(6) + + return critical_group_list, critical_process_list + def main(argv): container_name = None opts, args = getopt.getopt(argv, "c:", ["container-name="]) @@ -29,9 +57,7 @@ def main(argv): syslog.syslog(syslog.LOG_ERR, "Container name not specified. Exiting...") sys.exit(1) - # Read the list of critical processes from a file - with open(CRITICAL_PROCESSES_FILE, 'r') as f: - critical_processes = [line.rstrip('\n') for line in f] + critical_group_list, critical_process_list = get_critical_group_and_process_list() while True: # Transition from ACKNOWLEDGED to READY @@ -73,7 +99,7 @@ def main(argv): # If container is database or auto-restart feature is enabled and at the same time # a critical process exited unexpectedly, terminate supervisor if ((container_name == 'database' or restart_feature == 'enabled') and expected == 0 and - (processname in critical_processes or groupname in critical_processes)): + (processname in critical_process_list or groupname in critical_group_list)): MSG_FORMAT_STR = "Process {} exited unxepectedly. Terminating supervisor..." msg = MSG_FORMAT_STR.format(payload_headers['processname']) syslog.syslog(syslog.LOG_INFO, msg) diff --git a/platform/barefoot/docker-syncd-bfn/critical_processes b/platform/barefoot/docker-syncd-bfn/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/barefoot/docker-syncd-bfn/critical_processes +++ b/platform/barefoot/docker-syncd-bfn/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/broadcom/docker-syncd-brcm/critical_processes b/platform/broadcom/docker-syncd-brcm/critical_processes index 489668a89e08..d1163a9c3046 100644 --- a/platform/broadcom/docker-syncd-brcm/critical_processes +++ b/platform/broadcom/docker-syncd-brcm/critical_processes @@ -1,2 +1,2 @@ -dsserve -syncd +program:dsserve +program:syncd diff --git a/platform/cavium/docker-syncd-cavm/critical_processes b/platform/cavium/docker-syncd-cavm/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/cavium/docker-syncd-cavm/critical_processes +++ b/platform/cavium/docker-syncd-cavm/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/centec/docker-syncd-centec/critical_processes b/platform/centec/docker-syncd-centec/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/centec/docker-syncd-centec/critical_processes +++ b/platform/centec/docker-syncd-centec/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/marvell-arm64/docker-syncd-mrvl/critical_processes b/platform/marvell-arm64/docker-syncd-mrvl/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/critical_processes +++ b/platform/marvell-arm64/docker-syncd-mrvl/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/marvell-armhf/docker-syncd-mrvl/critical_processes b/platform/marvell-armhf/docker-syncd-mrvl/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/critical_processes +++ b/platform/marvell-armhf/docker-syncd-mrvl/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/marvell/docker-syncd-mrvl/critical_processes b/platform/marvell/docker-syncd-mrvl/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/marvell/docker-syncd-mrvl/critical_processes +++ b/platform/marvell/docker-syncd-mrvl/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/mellanox/docker-syncd-mlnx/critical_processes b/platform/mellanox/docker-syncd-mlnx/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/mellanox/docker-syncd-mlnx/critical_processes +++ b/platform/mellanox/docker-syncd-mlnx/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/nephos/docker-syncd-nephos/critical_processes b/platform/nephos/docker-syncd-nephos/critical_processes index 489668a89e08..d1163a9c3046 100644 --- a/platform/nephos/docker-syncd-nephos/critical_processes +++ b/platform/nephos/docker-syncd-nephos/critical_processes @@ -1,2 +1,2 @@ -dsserve -syncd +program:dsserve +program:syncd diff --git a/platform/vs/docker-syncd-vs/critical_processes b/platform/vs/docker-syncd-vs/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/vs/docker-syncd-vs/critical_processes +++ b/platform/vs/docker-syncd-vs/critical_processes @@ -1 +1 @@ -syncd +program:syncd From 88bbcbf2463c2f50d927eb871aec69b2cb6239e6 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Fri, 26 Jun 2020 13:44:21 +0300 Subject: [PATCH 0844/1427] [Mellanox] Update SDK to 4.4.0952, FW to *.2007.1280 (#4842) --- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 115d3e5f4726..35265337fe21 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2007.1244 +MLNX_SPC_FW_VERSION = 13.2007.1280 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2007.1244 +MLNX_SPC2_FW_VERSION = 29.2007.1280 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2007.1244 +MLNX_SPC3_FW_VERSION = 30.2007.1280 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index bf5651d92c21..bb4c9c1c9856 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit bf5651d92c21e62837aea2970488a01b0ff94768 +Subproject commit bb4c9c1c98563c3177dc8e086b8ddfe41b9695a2 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 28700ff40b71..e74e9e673ce0 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.4.0940 +MLNX_SDK_VERSION = 4.4.0952 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 94d448e9bd884932582a83f7cc08fc1dfe3bf579 Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Fri, 26 Jun 2020 11:32:35 -0700 Subject: [PATCH 0845/1427] [slave.mk]: Adding support to specify debs dependencies for python-debs package. (#4849) **- How I did it** added below line: $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEBS_DEPENDS))) \ **- How to verify it** Added below dependencies in sonic-utils ``` SONIC_UTILS = python-sonic-utilities_1.2-1_all.deb $(SONIC_UTILS)_SRC_PATH = $(SRC_PATH)/sonic-utilities $(SONIC_UTILS)_DEBS_DEPENDS = $(LIBYANG) $(LIBYANG_CPP) $(LIBYANG_PY2) \ <<<<<<<<<<< $(LIBYANG_PY3) $(SONIC_UTILS)_WHEEL_DEPENDS = $(SONIC_CONFIG_ENGINE) $(SONIC_YANG_MGMT_PY) SONIC_PYTHON_STDEB_DEBS += $(SONIC_UTILS) ``` Build the PKGs successfully. Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com --- slave.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/slave.mk b/slave.mk index 891f5686b80e..a03c28f44867 100644 --- a/slave.mk +++ b/slave.mk @@ -501,6 +501,7 @@ $(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -inst # $(SOME_NEW_DEB)_DEPENDS = $(SOME_OTHER_DEB1) $(SOME_OTHER_DEB2) ... # SONIC_PYTHON_STDEB_DEBS += $(SOME_NEW_DEB) $(addprefix $(PYTHON_DEBS_PATH)/, $(SONIC_PYTHON_STDEB_DEBS)) : $(PYTHON_DEBS_PATH)/% : .platform \ + $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEBS_DEPENDS))) \ $$(addsuffix -install,$$(addprefix $(PYTHON_DEBS_PATH)/,$$($$*_DEPENDS))) \ $$(addsuffix -install,$$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*_WHEEL_DEPENDS))) \ $(call dpkg_depend,$(PYTHON_DEBS_PATH)/%.dep) From c79783003d1ec615eed50135bd56dbb793794128 Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 26 Jun 2020 23:59:22 -0700 Subject: [PATCH 0846/1427] [submodule]: update sonic-linux-kernel (#4856) * c60b1f4 2020-06-26 | e1000: Do not perform reset in reset_task if we are already down (#148) (HEAD -> master, origin/master, origin/HEAD) [lguohan] * c6aeedd 2020-06-25 | Updated NAT kernel patch for 4.19 buster (#147) [Akhilesh Samineni] Signed-off-by: Guohan Lu --- src/sonic-linux-kernel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 0776e9f66dc3..c60b1f49c26d 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 0776e9f66dc31ee61e808d076f97818c19735214 +Subproject commit c60b1f49c26db1f0c511cd86ecdd52611164fc0a From 6849a0351c51915232a817ea0ded723006feda9e Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Sat, 27 Jun 2020 01:17:20 -0700 Subject: [PATCH 0847/1427] [redis] Install vanilla redis packages for Buster and Stretch; upgrade Buster to 6.0.5 (#4732) upgrade redis server to 5:6.0.5-1~bpo10+1 --- dockers/docker-base-buster/Dockerfile.j2 | 8 ++------ dockers/docker-base-stretch/Dockerfile.j2 | 8 ++------ dockers/docker-database/Dockerfile.j2 | 3 +++ files/build_templates/sonic_debian_extension.j2 | 2 +- platform/cavium/docker-syncd-cavm-rpc.mk | 2 +- platform/cavium/docker-syncd-cavm.mk | 2 +- platform/vs/docker-sonic-vs.mk | 2 -- platform/vs/docker-sonic-vs/Dockerfile.j2 | 1 + rules/docker-base-buster.mk | 2 +- rules/docker-base-stretch.mk | 2 +- rules/docker-database.mk | 2 -- rules/docker-dhcp-relay.mk | 2 +- rules/docker-iccpd.mk | 2 +- rules/docker-nat.mk | 2 +- rules/docker-orchagent.mk | 2 +- rules/docker-router-advertiser.mk | 2 +- rules/docker-sflow.mk | 2 +- rules/docker-sonic-mgmt-framework.mk | 4 ++-- rules/docker-teamd.mk | 2 +- rules/docker-telemetry.mk | 2 +- rules/redis.mk | 4 ++++ src/sonic-py-swsssdk | 2 +- 22 files changed, 28 insertions(+), 32 deletions(-) diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index fcf983229504..1959bb56cb7b 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -52,12 +52,8 @@ RUN apt-get update && \ # Install dependencies of supervisor python-pkg-resources \ python-meld3 \ -# dependencies of redis-tools - libatomic1 \ - libjemalloc2 \ - liblua5.1-0 \ - lua-bitop \ - lua-cjson \ +# Install redis-tools + redis-tools=5:6.0.5-1~bpo10+1 \ # common dependencies libpython2.7 \ libdaemon0 \ diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 30e59eccf705..f573e94b78d7 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -50,12 +50,8 @@ RUN apt-get update && \ # Install dependencies of supervisor python-pkg-resources \ python-meld3 \ -# dependencies of redis-tools - libatomic1 \ - libjemalloc1 \ - liblua5.1-0 \ - lua-bitop \ - lua-cjson \ +# Install redis-tools + redis-tools=5:5.0.3-3~bpo9+2 \ # common dependencies libpython2.7 \ libdaemon0 \ diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index 24416c838db5..e14be96e8592 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -10,6 +10,9 @@ ENV DEBIAN_FRONTEND=noninteractive # Update apt's cache of available packages RUN apt-get update +# install redis-server +RUN apt-get install -y redis-server=5:6.0.5-1~bpo10+1 + {% if docker_database_debs.strip() -%} # Copy locally-built Debian package dependencies {{ copy_files("debs/", docker_database_debs.split(' '), "/debs/") }} diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 635084fd5414..14d49c64e5e0 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -104,7 +104,7 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $CONFIG sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_WHEEL_NAME # Install Python client for Redis -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install "redis==2.10.6" +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install "redis==3.5.3" # Install redis-dump-load Python 3 package # Note: the scripts will be overwritten by corresponding Python 2 package diff --git a/platform/cavium/docker-syncd-cavm-rpc.mk b/platform/cavium/docker-syncd-cavm-rpc.mk index ebe614b3c183..a19124609bb0 100644 --- a/platform/cavium/docker-syncd-cavm-rpc.mk +++ b/platform/cavium/docker-syncd-cavm-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_CAVM_RPC = docker-syncd-cavm-rpc.gz $(DOCKER_SYNCD_CAVM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm-rpc -$(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) $(PTF) +$(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(CAVM_LIBSAI) $(XP_TOOLS) $(PTF) $(DOCKER_SYNCD_CAVM_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/cavium/docker-syncd-cavm.mk b/platform/cavium/docker-syncd-cavm.mk index ad43d6f1196f..059d2c71ebb4 100644 --- a/platform/cavium/docker-syncd-cavm.mk +++ b/platform/cavium/docker-syncd-cavm.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_CAVM = docker-syncd-cavm.gz $(DOCKER_SYNCD_CAVM)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm -$(DOCKER_SYNCD_CAVM)_DEPENDS += $(SYNCD) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) +$(DOCKER_SYNCD_CAVM)_DEPENDS += $(SYNCD) $(CAVM_LIBSAI) $(XP_TOOLS) $(DOCKER_SYNCD_CAVM)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CAVM)_DEPENDS += $(SYNCD_DBG) \ diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index b539543dfd2f..ab86e4716a19 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -4,8 +4,6 @@ DOCKER_SONIC_VS = docker-sonic-vs.gz $(DOCKER_SONIC_VS)_PATH = $(PLATFORM_PATH)/docker-sonic-vs $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS) \ $(SYNCD_VS) \ - $(REDIS_TOOLS) \ - $(REDIS_SERVER) \ $(PYTHON_SWSSCOMMON) \ $(LIBTEAMDCTL) \ $(LIBTEAM_UTILS) \ diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index b670ee26b6b8..89abf3cd6351 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -13,6 +13,7 @@ RUN echo "deb http://packages.microsoft.com/repos/sonic-dev/ jessie main" >> /et RUN apt-get update RUN apt-get install -y net-tools \ + redis-server=5:5.0.3-3~bpo9+2 \ arping \ ndisc6 \ ethtool \ diff --git a/rules/docker-base-buster.mk b/rules/docker-base-buster.mk index e1f02d19f30e..61ba96eda5fc 100644 --- a/rules/docker-base-buster.mk +++ b/rules/docker-base-buster.mk @@ -3,7 +3,7 @@ DOCKER_BASE_BUSTER = docker-base-buster.gz $(DOCKER_BASE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-base-buster -$(DOCKER_BASE_BUSTER)_DEPENDS += $(SUPERVISOR) $(REDIS_TOOLS) +$(DOCKER_BASE_BUSTER)_DEPENDS += $(SUPERVISOR) $(DOCKER_BASE_BUSTER)_DEPENDS += $(SOCAT) GDB = gdb diff --git a/rules/docker-base-stretch.mk b/rules/docker-base-stretch.mk index a54f4ec092aa..55b7fd9f8661 100644 --- a/rules/docker-base-stretch.mk +++ b/rules/docker-base-stretch.mk @@ -2,7 +2,7 @@ DOCKER_BASE_STRETCH = docker-base-stretch.gz $(DOCKER_BASE_STRETCH)_PATH = $(DOCKERS_PATH)/docker-base-stretch -$(DOCKER_BASE_STRETCH)_DEPENDS += $(SUPERVISOR) $(REDIS_TOOLS) +$(DOCKER_BASE_STRETCH)_DEPENDS += $(SUPERVISOR) $(DOCKER_BASE_STRETCH)_DEPENDS += $(SOCAT) GDB = gdb diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 9fb15855c247..8062c3b147a5 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -6,9 +6,7 @@ DOCKER_DATABASE_DBG = $(DOCKER_DATABASE_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_DATABASE)_PATH = $(DOCKERS_PATH)/$(DOCKER_DATABASE_STEM) -$(DOCKER_DATABASE)_DEPENDS += $(REDIS_TOOLS) $(REDIS_SERVER) $(DOCKER_DATABASE)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) -$(DOCKER_DATABASE)_DBG_DEPENDS += $(REDIS_TOOLS_DBG) $(DOCKER_DATABASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 50d3d23acf87..860928bf8176 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -6,7 +6,7 @@ DOCKER_DHCP_RELAY_DBG = $(DOCKER_DHCP_RELAY_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/$(DOCKER_DHCP_RELAY_STEM) -$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(REDIS_TOOLS) $(SONIC_DHCPMON) +$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(SONIC_DHCPMON) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS += $(ISC_DHCP_RELAY_DBG) diff --git a/rules/docker-iccpd.mk b/rules/docker-iccpd.mk index 106da8e589d8..fefa5504df13 100644 --- a/rules/docker-iccpd.mk +++ b/rules/docker-iccpd.mk @@ -4,7 +4,7 @@ DOCKER_ICCPD_STEM = docker-iccpd DOCKER_ICCPD = $(DOCKER_ICCPD_STEM).gz DOCKER_ICCPD_DBG = $(DOCKER_ICCPD_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_ICCPD)_PATH = $(DOCKERS_PATH)/$(DOCKER_ICCPD_STEM) -$(DOCKER_ICCPD)_DEPENDS += $(SWSS) $(REDIS_TOOLS) $(ICCPD) +$(DOCKER_ICCPD)_DEPENDS += $(SWSS) $(ICCPD) $(DOCKER_ICCPD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_ICCPD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) $(ICCPD_DBG) $(DOCKER_ICCPD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk index eb6bd16ccd46..b421bfd886cf 100644 --- a/rules/docker-nat.mk +++ b/rules/docker-nat.mk @@ -6,7 +6,7 @@ DOCKER_NAT_DBG = $(DOCKER_NAT_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_NAT)_PATH = $(DOCKERS_PATH)/$(DOCKER_NAT_STEM) -$(DOCKER_NAT)_DEPENDS += $(SWSS) $(REDIS_TOOLS) $(IPTABLESIP4TC) $(IPTABLESIP6TC) $(IPTABLESIPTC) $(IPXTABLES12) $(IPTABLES) +$(DOCKER_NAT)_DEPENDS += $(SWSS) $(IPTABLESIP4TC) $(IPTABLESIP6TC) $(IPTABLESIPTC) $(IPXTABLES12) $(IPTABLES) $(DOCKER_NAT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_NAT)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) $(DOCKER_NAT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index bab1a3a29920..4d63502ebb44 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -4,7 +4,7 @@ DOCKER_ORCHAGENT_STEM = docker-orchagent DOCKER_ORCHAGENT = $(DOCKER_ORCHAGENT_STEM).gz DOCKER_ORCHAGENT_DBG = $(DOCKER_ORCHAGENT_STEM)-$(DBG_IMAGE_MARK).gz -$(DOCKER_ORCHAGENT)_DEPENDS += $(SWSS) $(REDIS_TOOLS) +$(DOCKER_ORCHAGENT)_DEPENDS += $(SWSS) $(DOCKER_ORCHAGENT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_ORCHAGENT)_DBG_DEPENDS += $(SWSS_DBG) \ diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk index c7efe7c1f560..11549815e266 100644 --- a/rules/docker-router-advertiser.mk +++ b/rules/docker-router-advertiser.mk @@ -6,7 +6,7 @@ DOCKER_ROUTER_ADVERTISER_DBG = $(DOCKER_ROUTER_ADVERTISER_STEM)-$(DBG_IMAGE_MARK $(DOCKER_ROUTER_ADVERTISER)_PATH = $(DOCKERS_PATH)/$(DOCKER_ROUTER_ADVERTISER_STEM) -$(DOCKER_ROUTER_ADVERTISER)_DEPENDS += $(RADVD) $(REDIS_TOOLS) +$(DOCKER_ROUTER_ADVERTISER)_DEPENDS += $(RADVD) $(DOCKER_ROUTER_ADVERTISER)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_ROUTER_ADVERTISER)_DBG_DEPENDS += $(RADVD_DBG) diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk index 67724ad7c548..04700349fbae 100644 --- a/rules/docker-sflow.mk +++ b/rules/docker-sflow.mk @@ -6,7 +6,7 @@ DOCKER_SFLOW_DBG = $(DOCKER_SFLOW_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_SFLOW)_PATH = $(DOCKERS_PATH)/$(DOCKER_SFLOW_STEM) -$(DOCKER_SFLOW)_DEPENDS += $(SWSS) $(REDIS_TOOLS) $(HSFLOWD) $(SFLOWTOOL) $(PSAMPLE) +$(DOCKER_SFLOW)_DEPENDS += $(SWSS) $(HSFLOWD) $(SFLOWTOOL) $(PSAMPLE) $(DOCKER_SFLOW)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_TEAMD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) $(DOCKER_SFLOW)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk index 7f113f760253..b1e23c026c9f 100644 --- a/rules/docker-sonic-mgmt-framework.mk +++ b/rules/docker-sonic-mgmt-framework.mk @@ -7,9 +7,9 @@ DOCKER_MGMT_FRAMEWORK_DBG = $(DOCKER_MGMT_FRAMEWORK_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_MGMT_FRAMEWORK)_PATH = $(DOCKERS_PATH)/$(DOCKER_MGMT_FRAMEWORK_STEM) $(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(SONIC_MGMT_COMMON) -$(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK) +$(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(SONIC_MGMT_FRAMEWORK) $(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) -$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK_DBG) +$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS += $(SONIC_MGMT_FRAMEWORK_DBG) SONIC_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) $(DOCKER_MGMT_FRAMEWORK)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk index a4ac31599fd1..49c9dde9ba17 100644 --- a/rules/docker-teamd.mk +++ b/rules/docker-teamd.mk @@ -6,7 +6,7 @@ DOCKER_TEAMD_DBG = $(DOCKER_TEAMD_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_TEAMD)_PATH = $(DOCKERS_PATH)/$(DOCKER_TEAMD_STEM) -$(DOCKER_TEAMD)_DEPENDS += $(SWSS) $(LIBTEAMDCTL) $(LIBTEAM_UTILS) $(REDIS_TOOLS) +$(DOCKER_TEAMD)_DEPENDS += $(SWSS) $(LIBTEAMDCTL) $(LIBTEAM_UTILS) $(DOCKER_TEAMD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_TEAMD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) $(DOCKER_TEAMD)_DBG_DEPENDS += $(LIBTEAMDCTL_DBG) $(LIBTEAM_UTILS_DBG) diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 761d80a07d5e..9544e7bf4687 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -7,7 +7,7 @@ DOCKER_TELEMETRY_DBG = $(DOCKER_TELEMETRY_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_TELEMETRY)_PATH = $(DOCKERS_PATH)/$(DOCKER_TELEMETRY_STEM) $(DOCKER_TELEMETRY)_DEPENDS += $(SONIC_MGMT_COMMON) -$(DOCKER_TELEMETRY)_DEPENDS += $(REDIS_TOOLS) $(SONIC_TELEMETRY) +$(DOCKER_TELEMETRY)_DEPENDS += $(SONIC_TELEMETRY) $(DOCKER_TELEMETRY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_TELEMETRY)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) diff --git a/rules/redis.mk b/rules/redis.mk index 83b3d81ba6c5..f4732d1ecbb5 100644 --- a/rules/redis.mk +++ b/rules/redis.mk @@ -6,7 +6,11 @@ REDIS_TOOLS = redis-tools_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb $(REDIS_TOOLS)_SRC_PATH = $(SRC_PATH)/redis $(REDIS_TOOLS)_DEPENDS += $(LIBHIREDIS_DEV) $(REDIS_TOOLS)_RDEPENDS += $(LIBHIREDIS) +# TODO: docker-sonic-p4 depends on redis-tools in Jessie. +# Remove this file and src/redis after that resolved. +ifneq ($(BLDENV),buster) SONIC_MAKE_DEBS += $(REDIS_TOOLS) +endif REDIS_TOOLS_DBG = redis-tools-dbgsym_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_TOOLS_DBG))) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 132f8d5f1b00..a83366e827cc 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 132f8d5f1b00fb8a1b3cdbd7a5c69bb89cfff0e3 +Subproject commit a83366e827cc08dbd3d22de92773c7ef79215199 From 1eb3dfe5414587d763cf746f6483961095531b9b Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Sat, 27 Jun 2020 01:22:23 -0700 Subject: [PATCH 0848/1427] [docker-teamd]: Introducing tlm_teamd: telemetry for teamd (#4824) **- What I did** 1. Updated submodule sonic-swss to bring tlm_teamd to the buildimage. 2. Updated supervisord for the teamd 3. Updated critical process list (not sure that tlm_teamd is critical for now) **- How to verify it** Build an image and run. Check that tlm_teamd is running and STATE_DB has information in the LAG_INTERFACE, and :LAG_MEMBER_INTERFACE ``` admin@sonic:~$ redis-cli -n 6 hgetall 'LAG_TABLE|PortChannel16' 1) "state" 2) "ok" 3) "team_device.ifinfo.dev_addr" 4) "4c:76:25:f5:48:80" 5) "setup.kernel_team_mode_name" 6) "loadbalance" 7) "team_device.ifinfo.ifindex" 8) "6" 9) "runner.fast_rate" 10) "false" 11) "runner.active" 12) "true" 13) "setup.pid" 14) "35" 15) "runner.fallback" 16) "false" ``` ``` admin@sonic:~$ redis-cli -n 6 hgetall 'LAG_MEMBER_TABLE|PortChannel16|Ethernet16' 1) "runner.selected" 2) "true" 3) "runner.aggregator.selected" 4) "true" 5) "runner.aggregator.id" 6) "26" 7) "runner.actor_lacpdu_info.state" 8) "61" 9) "runner.state" 10) "current" 11) "runner.actor_lacpdu_info.system" 12) "4c:76:25:f5:48:80" 13) "runner.partner_lacpdu_info.state" 14) "61" 15) "link.up" 16) "true" 17) "ifinfo.dev_addr" 18) "4c:76:25:f5:48:80" 19) "ifinfo.ifindex" 20) "26" 21) "link_watches.list.link_watch_0.up" 22) "true" 23) "runner.actor_lacpdu_info.port" 24) "17" 25) "runner.partner_lacpdu_info.port" 26) "1" 27) "runner.partner_lacpdu_info.system" 28) "52:54:00:ff:34:1b" ``` --- dockers/docker-teamd/critical_processes | 1 + dockers/docker-teamd/supervisord.conf | 11 +++++++++++ src/sonic-swss | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/dockers/docker-teamd/critical_processes b/dockers/docker-teamd/critical_processes index 286d6aef4c7a..bb7d3c4b0810 100644 --- a/dockers/docker-teamd/critical_processes +++ b/dockers/docker-teamd/critical_processes @@ -1,2 +1,3 @@ program:teammgrd program:teamsyncd +program:tlm_teamd \ No newline at end of file diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index 166b0be0f7dc..50d4249b1966 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -57,3 +57,14 @@ stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=teammgrd:running + +[program:tlm_teamd] +command=/usr/bin/tlm_teamd +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + diff --git a/src/sonic-swss b/src/sonic-swss index a3a010af7283..17a2f93a545b 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit a3a010af728345b085d8a6e344b60b16c32815fd +Subproject commit 17a2f93a545b8669e44a62231c340ba518272ed7 From 0c3ec0e6443d6a11149cf463fd6a922e82cb9e77 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Sun, 28 Jun 2020 00:32:53 +0530 Subject: [PATCH 0849/1427] [DellEMC] S52xx fix SFP reset in 1.0 API (#4858) Issue: Port with AOC cable does not come up when "sfputil reset " is executed. Modified the incorrect mask used in reset API to resolve the issue. --- device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py | 4 ++-- device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py index 03bf1585d935..b5b1408ef9b1 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py @@ -193,7 +193,7 @@ def set_low_power_mode(self, port_num, lpmode): if (reg_value == "" ): return False - # Mask off 4th bit for presence + # Mask off 6th bit for lpmode mask = (1 << 6) # LPMode is active high; set or clear the bit accordingly @@ -224,7 +224,7 @@ def reset(self, port_num): return False # Mask off 4th bit for presence - mask = (1 << 6) + mask = (1 << 4) # ResetL is active low reg_value = reg_value & ~mask diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py index 4bc0745df2de..d9417fef8fbd 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py @@ -252,7 +252,7 @@ def set_low_power_mode(self, port_num, lpmode): if (reg_value == "" ): return False - # Mask off 4th bit for presence + # Mask off 6th bit for lpmode mask = (1 << 6) # LPMode is active high; set or clear the bit accordingly @@ -283,7 +283,7 @@ def reset(self, port_num): return False # Mask off 4th bit for presence - mask = (1 << 6) + mask = (1 << 4) # ResetL is active low reg_value = reg_value & ~mask From ced0f7ba3d07c730e6c7532c1b725da6461c877b Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 27 Jun 2020 22:57:26 -0700 Subject: [PATCH 0850/1427] [sonic-platform-common][sonic-platform-daemons][sonic-utilities] Update submodules (#4852) * src/sonic-platform-common 75698a8...82bbeab (9): > [sfputil] Make SfpUtilHelper.get_physical_to_logical noexcept as in SfpUtilBase (#96) > [sfp_base] Update return value documentation of channel-specific methods (#98) > [sfp] Tweak key names of some transceiver info fields (#97) > fix typo: portconfig.ini to port_config.ini (#94) > [chassis_base] Add platform API support for system LED (#91) > Add PCIe check commad (#64) > [sfputilbase.py] Don't try to print EEPROM sysfs file name if we failed to read from it (#81) > [sfputilbase | sfputilhelper] Add support of platform.json (#72) > [eeprom] Add try-except to catch the IOError (#85) * src/sonic-platform-daemons 0f4fd83...abe115e (2): > [xcvrd] Tweak some transceiver info key names (#62) > [psud][thermalctld] Always get fan/PSU LED status from platform API to avoid status inconsistencies (#59) * src/sonic-utilities fd7781b...16a33f2 (9): > [config] Fix syntax error (#966) > [config] Fix indentation level in _get_disabled_services_list() (#965) > a4e64d1 [sonic_installer] Refactor sonic_installer code (#953) > 90efd62 [Show | Command Reference] Add Port breakout Show Command (#859) > [sfpshow][mock_state_db] Tweak key names of some transceiver info fields (#958) > [show] Add missing verbose option to "show line" (#961) > [filter-fdb] Check VLAN Presence When Filter FDB (#957) > [master]fix #4716 show ipv6 interfaces neighbor_ip is N/A issue (#948) > Fix for command. show interface transceiver eeprom -d Ethernet (#955) Note: sonic-utilities update fixes #4716 --- src/sonic-platform-common | 2 +- src/sonic-platform-daemons | 2 +- src/sonic-utilities | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 75698a8dd8f5..82bbeabc59b7 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 75698a8dd8f5a9ea2a0e72c5f7e2b3196d22571a +Subproject commit 82bbeabc59b78886b5cadffe0998c8fe67031343 diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 0f4fd835f324..abe115e6a680 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 0f4fd835f324cb754a8b955f9a5fad6b54d7d6dc +Subproject commit abe115e6a680c76d09dea04e6aab1d16876aed7a diff --git a/src/sonic-utilities b/src/sonic-utilities index fd7781b52d6b..16a33f2fb67e 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit fd7781b52d6b70d90505ca128277ce864cee7ab2 +Subproject commit 16a33f2fb67e9da15ecc7780daa6b15408665539 From 07930c39ba274463f2a2ffe31bb377b3eeaa2f76 Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Sun, 28 Jun 2020 11:03:48 -0700 Subject: [PATCH 0851/1427] [build] Add essential PY PKGs on host for sonic-utilities/config/config_mgmt.py (#4740) Add essential PY PKGs on host by installing them in sonic_debian_extension.j2 Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com --- files/build_templates/sonic_debian_extension.j2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 14d49c64e5e0..35340e0195fb 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -176,6 +176,10 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install pexpect # Install tabulate >= 0.8.1 via pip in order to support multi-line row output for sonic-utilities sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install tabulate==0.8.2 +# Install packages to support Dynamic Port Breakout config command for sonic-utilities +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install xmltodict==0.12.0 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install jsondiff==1.2.0 + # Install SONiC Utilities (and its dependencies via 'apt-get -y install -f') sudo dpkg --root=$FILESYSTEM_ROOT -i $python_debs_path/python-sonic-utilities_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f From 1c32933c7d7333e3530422c3651aea2841ec3cda Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Sun, 28 Jun 2020 11:08:30 -0700 Subject: [PATCH 0852/1427] [docker] Correct the lldp-syncd program name in critical_process file. (#4862) The program name in critical_processes file must match the program name defined in supervisord.conf file. Signed-off-by: Yong Zhao --- dockers/docker-lldp/critical_processes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-lldp/critical_processes b/dockers/docker-lldp/critical_processes index 7a6b137a76f6..90586536a4f5 100644 --- a/dockers/docker-lldp/critical_processes +++ b/dockers/docker-lldp/critical_processes @@ -1,3 +1,3 @@ program:lldpd -program:lldp_syncd +program:lldp-syncd program:lldpmgrd From dd4cf912a6141cff47d299cdf2009104514edceb Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Sun, 28 Jun 2020 23:41:34 +0530 Subject: [PATCH 0853/1427] [Juniper][QFX5210] Fixing a few platform issues (#4857) This patch addresses the following issues: 1) Platform drivers were not loading in the latest images. Fixed the intialization script to make sure that all the drivers are loaded. 2) Getting rid of "pstore: crypto_comp_decompress failed, ret = -22!" messages during the kernel boot, after moving to 4.19 kernel. The solution is to remove the files under '/sys/fs/pstore' directory. Signed-off-by: Ciju Rajan K --- .../sonic-platform-juniper-qfx5210.postinst | 1 + .../qfx5210/utils/juniper_qfx5210_util.py | 17 ++++++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst index 97b66fb44e4c..e5b65e81206b 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst @@ -28,4 +28,5 @@ if [ -f $FIRST_BOOT_FILE ]; then # Creating the UEFI entry for the first time. efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /var/tmp/efi_log 2>&1 fi + rm -rf /sys/fs/pstore/* fi diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py index 26eed74c944a..c6aaf435e504 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py @@ -338,14 +338,12 @@ def system_ready(): def do_install(): logging.info('Checking system....') - if driver_check() == False: - logging.info('No driver, installing....') - status = driver_install() - if status: - if FORCE == 0: - return status - else: - print PROJECT_NAME.upper()+" drivers detected...." + + status = driver_install() + if status: + if FORCE == 0: + return status + if not device_exist(): logging.info('No device, installing....') status = device_install() @@ -353,7 +351,8 @@ def do_install(): if FORCE == 0: return status else: - print PROJECT_NAME.upper()+" devices detected...." + print PROJECT_NAME.upper()+" devices detected...." + return def do_uninstall(): From ce391645f21fc1b196893df865acf8a21e23e957 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Mon, 29 Jun 2020 08:54:28 +0800 Subject: [PATCH 0854/1427] [Mellanox] add ASIC temperature support to platform API (#4828) **- Why I did it** System health feature requires to read ASIC temperature and threshold from platform API **- How I did it** Implement Chassis.get_asic_temperature and Chassis.get_asic_temperature_threshold by getting value from system fs. --- .../sonic_platform/thermal.py | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 3525220a4035..0571707eb707 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -52,6 +52,12 @@ MODULE_TEMPERATURE_FAULT_PATH = "/var/run/hw-management/thermal/module{}_temp_fault" +thermal_api_handler_asic = { + THERMAL_API_GET_TEMPERATURE: 'asic', + THERMAL_API_GET_HIGH_THRESHOLD: 'mlxsw/temp_trip_hot', + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD: 'mlxsw/temp_trip_crit' +} + thermal_api_handler_cpu_core = { THERMAL_API_GET_TEMPERATURE:"cpu_core{}", THERMAL_API_GET_HIGH_THRESHOLD:"cpu_core{}_max", @@ -78,14 +84,14 @@ THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:None } thermal_ambient_apis = { - THERMAL_DEV_ASIC_AMBIENT : "asic", + THERMAL_DEV_ASIC_AMBIENT : thermal_api_handler_asic, THERMAL_DEV_PORT_AMBIENT : "port_amb", THERMAL_DEV_FAN_AMBIENT : "fan_amb", THERMAL_DEV_COMEX_AMBIENT : "comex_amb", THERMAL_DEV_BOARD_AMBIENT : "board_amb" } thermal_ambient_name = { - THERMAL_DEV_ASIC_AMBIENT : "Ambient ASIC Temp", + THERMAL_DEV_ASIC_AMBIENT : 'ASIC', THERMAL_DEV_PORT_AMBIENT : "Ambient Port Side Temp", THERMAL_DEV_FAN_AMBIENT : "Ambient Fan Side Temp", THERMAL_DEV_COMEX_AMBIENT : "Ambient COMEX Temp", @@ -383,8 +389,14 @@ def _read_generic_file(cls, filename, len): def _get_file_from_api(self, api_name): if self.category == THERMAL_DEV_CATEGORY_AMBIENT: - if api_name == THERMAL_API_GET_TEMPERATURE: - filename = thermal_ambient_apis[self.index] + handler = thermal_ambient_apis[self.index] + if isinstance(handler, str): + if api_name == THERMAL_API_GET_TEMPERATURE: + filename = thermal_ambient_apis[self.index] + else: + return None + elif isinstance(handler, dict): + filename = handler[api_name] else: return None else: From ab2177b4a93307503d60a16543296b1917c5e268 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Mon, 29 Jun 2020 09:39:23 -0700 Subject: [PATCH 0855/1427] [systemd-generator]: Fix dependency update for multi-asic platform (#4820) * [systemd-generator]: Fix the code to make sure that dependencies of host services are generated correctly for multi-asic platforms. Add code to make sure that systemd timer files are also modified to add the correct service dependency for multi-asic platforms. Signed-off-by: SuvarnaMeenakshi * [systemd-generator]: Minor fix, remove debug code and remove unused variable. --- .../build_templates/sonic_debian_extension.j2 | 4 +-- .../systemd-sonic-generator.c | 27 +++++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 35340e0195fb..925998f0aef9 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -519,10 +519,10 @@ sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netn # Copy systemd timer configuration # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM -sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer +echo "snmp.timer" | sudo tee -a $GENERATED_SERVICE_FILE {% if enable_system_telemetry == 'y' %} sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM -sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable telemetry.timer +echo "telemetry.timer" | sudo tee -a $GENERATED_SERVICE_FILE {% endif %} sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-dev diff --git a/src/systemd-sonic-generator/systemd-sonic-generator.c b/src/systemd-sonic-generator/systemd-sonic-generator.c index 9a5fabd33484..e801fcb229d2 100644 --- a/src/systemd-sonic-generator/systemd-sonic-generator.c +++ b/src/systemd-sonic-generator/systemd-sonic-generator.c @@ -147,12 +147,16 @@ static void replace_multi_inst_dep(char *src) { char *line_copy; char *service_name; char *type; + char *save_ptr1 = NULL; + char *save_ptr2 = NULL; ssize_t nread; bool section_done = false; char tmp_file_path[PATH_MAX]; - /* assumes that the service files has 3 sections, + /* Assumes that the service files has 3 sections, * in the order: Unit, Service and Install. + * Assumes that the timer file has 3 sectiosn, + * in the order: Unit, Timer and Install. * Read service dependency from Unit and Install * sections, replace if dependent on multi instance * service. @@ -162,30 +166,31 @@ static void replace_multi_inst_dep(char *src) { fp_tmp = fopen(tmp_file_path, "w"); while ((nread = getline(&line, &len, fp_src)) != -1 ) { - if (strstr(line, "[Service]") != NULL) { + if ((strstr(line, "[Service]") != NULL) || + (strstr(line, "[Timer]") != NULL)) { section_done = true; fputs(line,fp_tmp); - } else if (strstr(line, "[Install]") != NULL) { + } else if (strstr(line, "[Install]") != NULL) { section_done = false; fputs(line,fp_tmp); } else if ((strstr(line, "[Unit]") != NULL) || (strstr(line, "Description") != NULL) || - (section_done == true)){ + (section_done == true)) { fputs(line,fp_tmp); } else { line_copy = strdup(line); - token = strtok(line_copy, "="); - while ((word = strtok(NULL, " "))){ + token = strtok_r(line_copy, "=", &save_ptr1); + while ((word = strtok_r(NULL, " ", &save_ptr1))) { if((strchr(word, '.') == NULL) || (strchr(word, '@') != NULL)) { snprintf(buf, MAX_BUF_SIZE,"%s=%s\n",token, word); fputs(buf,fp_tmp); } else { service_name = strdup(word); - service_name = strtok(service_name, "."); - type = strtok(NULL, " "); + service_name = strtok_r(service_name, ".", &save_ptr2); + type = strtok_r(NULL, " ", &save_ptr2); if (is_multi_instance_service(word)) { - for(i = 0; i < num_asics; i++){ + for(i = 0; i < num_asics; i++) { snprintf(buf, MAX_BUF_SIZE, "%s=%s@%d.%s\n", token, service_name, i, type); fputs(buf,fp_tmp); @@ -513,7 +518,7 @@ static int get_num_of_asic() { while ((nread = getline(&line, &len, fp)) != -1) { if ((strstr(line, "onie_platform") != NULL) || - (strstr(line, "aboot_platform") != NULL)) { + (strstr(line, "aboot_platform") != NULL)) { token = strtok(line, "="); platform = strtok(NULL, "="); strip_trailing_newline(platform); @@ -580,7 +585,7 @@ int main(int argc, char **argv) { // For each unit file, get the installation targets and install the unit for (int i = 0; i < num_unit_files; i++) { - unit_instance = strdup(unit_files[i]); + unit_instance = strdup(unit_files[i]); if ((num_asics == 1) && strstr(unit_instance, "@") != NULL) { prefix = strtok(unit_instance, "@"); suffix = strtok(NULL, "@"); From 15440b6e439e2a257a625505741f834770ea21fc Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 29 Jun 2020 11:38:46 -0700 Subject: [PATCH 0856/1427] Changes to make default route programming correct in multi-npu platforms (#4774) * Changes to make default route programming correct in multi-asic platform where frr is not running in host namespace. Change is to set correct administrative distance. Also make NAMESPACE* enviroment variable available for all dockers so that it can be used when needed. Signed-off-by: Abhishek Dosi * Fix review comments * Review comment to check to add default route only if default route exist and delete is successful. --- dockers/docker-fpm-frr/docker_init.sh | 24 +++++++++++++++++++++++ files/build_templates/docker_image_ctl.j2 | 2 -- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/dockers/docker-fpm-frr/docker_init.sh b/dockers/docker-fpm-frr/docker_init.sh index a4db7d3cf3c6..c0cc341ce795 100755 --- a/dockers/docker-fpm-frr/docker_init.sh +++ b/dockers/docker-fpm-frr/docker_init.sh @@ -6,6 +6,30 @@ mkdir -p /etc/supervisor/conf.d sonic-cfggen -d -t /usr/share/sonic/templates/supervisord/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf CONFIG_TYPE=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["docker_routing_config_mode"]'` + +if [[ ! -z "$NAMESPACE_ID" ]]; then + # FRR is not running in host namespace so we need to delete + # default gw kernel route added by docker network via eth0 and add it back + # with higher administrative distance so that default route learnt + # by FRR becomes best route if/when available + GATEWAY_IP=$(ip route show 0.0.0.0/0 dev eth0 | awk '{print $3}') + #Check if docker default route is there + if [[ ! -z "$GATEWAY_IP" ]]; then + ip route del 0.0.0.0/0 dev eth0 + #Make sure route is deleted + CHECK_GATEWAY_IP=$(ip route show 0.0.0.0/0 dev eth0 | awk '{print $3}') + if [[ -z "$CHECK_GATEWAY_IP" ]]; then + # Ref: http://docs.frrouting.org/en/latest/zebra.html#zebra-vrf + # Zebra does treat Kernel routes as special case for the purposes of Admin Distance. \ + # Upon learning about a route that is not originated by FRR we read the metric value as a uint32_t. + # The top byte of the value is interpreted as the Administrative Distance and + # the low three bytes are read in as the metric. + # so here we are programming administrative distance of 210 (210 << 24) > 200 (for routes learnt via IBGP) + ip route add 0.0.0.0/0 via $GATEWAY_IP dev eth0 metric 3523215360 + fi + fi +fi + if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then sonic-cfggen -d -t /usr/share/sonic/templates/bgpd/bgpd.conf.j2 -y /etc/sonic/constants.yml > /etc/frr/bgpd.conf sonic-cfggen -d -t /usr/share/sonic/templates/zebra/zebra.conf.j2 > /etc/frr/zebra.conf diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 90a234c009eb..381480123f67 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -295,11 +295,9 @@ start() { --tmpfs /tmp \ {%- endif %} --tmpfs /var/tmp \ -{%- if docker_container_name == "database" %} --env "NAMESPACE_ID"="$DEV" \ --env "NAMESPACE_PREFIX"="$NAMESPACE_PREFIX" \ --env "NAMESPACE_COUNT"=$NUM_ASIC \ -{%- endif %} --name={{docker_container_name}}$DEV {{docker_image_name}}:latest || { echo "Failed to docker run" >&1 exit 4 From 0f4460e7ad3f21358979974080f3c37f2de4717e Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Mon, 29 Jun 2020 14:44:52 -0700 Subject: [PATCH 0857/1427] [rules/sonic-utilities.mk]: Add sonic_yang_models as dep to sonic utils (#4869) Since we can not refer a dir in sonic-buildimage while jenkins testing of sonic-utilities. We need to create build dependency on sonic_yang_models PKG too. Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com --- rules/sonic-utilities.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index 6938a3790d20..96091ddbc269 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -14,5 +14,6 @@ SONIC_UTILS = python-sonic-utilities_1.2-1_all.deb $(SONIC_UTILS)_SRC_PATH = $(SRC_PATH)/sonic-utilities $(SONIC_UTILS)_DEBS_DEPENDS = $(LIBYANG) $(LIBYANG_CPP) $(LIBYANG_PY2) \ $(LIBYANG_PY3) -$(SONIC_UTILS)_WHEEL_DEPENDS = $(SONIC_CONFIG_ENGINE) $(SONIC_YANG_MGMT_PY) +$(SONIC_UTILS)_WHEEL_DEPENDS = $(SONIC_CONFIG_ENGINE) $(SONIC_YANG_MGMT_PY) \ + $(SONIC_YANG_MODELS_PY3) SONIC_PYTHON_STDEB_DEBS += $(SONIC_UTILS) From a8b99f77f35d1f55ef7d332570d2fda388850955 Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Tue, 30 Jun 2020 06:29:20 -0700 Subject: [PATCH 0858/1427] syslog changes Multi ASIC platforms (#4738) Add changes for syslog support for containers running in namespaces on multi ASIC platforms. On Multi ASIC platforms Rsyslog service is only running on the host. There is no rsyslog service running in each namespace. On multi ASIC platforms the rsyslog service on the host will be listening on the docker0 ip address instead of loopback address. The rsyslog.conf on the containers is modified to have omfwd target ip to be docker0 ipaddress instead of loopback ip Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- files/build_templates/docker_image_ctl.j2 | 17 +++++ .../build_templates/sonic_debian_extension.j2 | 1 + files/image_config/rsyslog/rsyslog-config.sh | 21 ++++- .../rsyslog/rsyslog-container.conf.j2 | 76 +++++++++++++++++++ files/image_config/rsyslog/rsyslog.conf.j2 | 2 +- 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 files/image_config/rsyslog/rsyslog-container.conf.j2 diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 381480123f67..0a0461795944 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -27,6 +27,22 @@ link_namespace() { } {%- endif %} +function updateSyslogConf() +{ + # On multiNPU platforms, change the syslog target ip to docker0 ip to allow logs from containers + # running on the namespace to reach the rsyslog service running on the host + # Also update the container name + if [[ ($NUM_ASIC -gt 1) ]]; then + TARGET_IP=$(docker network inspect bridge --format={{ "'{{(index .IPAM.Config 0).Gateway}}'" }}) + CONTAINER_NAME="{{docker_container_name}}$DEV" + TMP_FILE="/tmp/rsyslog.$CONTAINER_NAME.conf" + + sonic-cfggen -t /usr/share/sonic/templates/rsyslog-container.conf.j2 -a "{\"target_ip\": \"$TARGET_IP\", \"container_name\": \"$CONTAINER_NAME\" }" > $TMP_FILE + docker cp $TMP_FILE {{docker_container_name}}$DEV:/etc/rsyslog.conf + rm -rf $TMP_FILE + fi +} + function getMountPoint() { echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.basename(mnts[0]['Source'])" 2>/dev/null @@ -68,6 +84,7 @@ function preStartAction() {%- else %} : # nothing {%- endif %} + updateSyslogConf } function postStartAction() diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 925998f0aef9..737ce1271fa6 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -241,6 +241,7 @@ echo "warmboot-finalizer.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-container.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.d/* $FILESYSTEM_ROOT/etc/rsyslog.d/ echo "rsyslog-config.service" | sudo tee -a $GENERATED_SERVICE_FILE diff --git a/files/image_config/rsyslog/rsyslog-config.sh b/files/image_config/rsyslog/rsyslog-config.sh index c8ba7b99453c..26767d84fbe0 100755 --- a/files/image_config/rsyslog/rsyslog-config.sh +++ b/files/image_config/rsyslog/rsyslog-config.sh @@ -1,4 +1,23 @@ #!/bin/bash -sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog.conf.j2 >/etc/rsyslog.conf +PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +if [ -f "$ASIC_CONF" ]; then + source $ASIC_CONF +fi + +# On Multi NPU platforms we need to start the rsyslog server on the docker0 ip address +# for the syslogs from the containers in the namespaces to work. +# on Single NPU platforms we continue to use loopback adddres + +if [[ ($NUM_ASIC -gt 1) ]]; then + udp_server_ip=$(ip -o -4 addr list docker0 | awk '{print $4}' | cut -d/ -f1) +else + udp_server_ip=$(ip -o -4 addr list lo scope host | awk '{print $4}' | cut -d/ -f1) +fi + +sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog.conf.j2 -a "{\"udp_server_ip\": \"$udp_server_ip\"}" >/etc/rsyslog.conf + systemctl restart rsyslog diff --git a/files/image_config/rsyslog/rsyslog-container.conf.j2 b/files/image_config/rsyslog/rsyslog-container.conf.j2 new file mode 100644 index 000000000000..d17fbb6767ba --- /dev/null +++ b/files/image_config/rsyslog/rsyslog-container.conf.j2 @@ -0,0 +1,76 @@ +# +# /etc/rsyslog.conf Configuration file for rsyslog. +# +# For more information see +# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html + + +################# +#### MODULES #### +################# + +$ModLoad imuxsock # provides support for local system logging + +# +# Set a rate limit on messages from the container +# +$SystemLogRateLimitInterval 300 +$SystemLogRateLimitBurst 20000 + +#$ModLoad imklog # provides kernel logging support +#$ModLoad immark # provides --MARK-- message capability + +# provides UDP syslog reception +#$ModLoad imudp +#$UDPServerRun 514 + +# provides TCP syslog reception +#$ModLoad imtcp +#$InputTCPServerRun 514 + + +########################### +#### GLOBAL DIRECTIVES #### +########################### + +# Set remote syslog server +template (name="ForwardFormatInContainer" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% {{container_name}}#%syslogtag%%msg:::sp-if-no-1st-sp%%msg%") +*.* action(type="omfwd" target="{{target_ip}}" port="514" protocol="udp" Template="ForwardFormatInContainer") + +# +# Use traditional timestamp format. +# To enable high precision timestamps, comment out the following line. +# +#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat + +# Define a custom template +$template SONiCFileFormat,"%TIMESTAMP%.%timestamp:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% {{container_name}}#%syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" +$ActionFileDefaultTemplate SONiCFileFormat + +# +# Set the default permissions for all log files. +# +$FileOwner root +$FileGroup adm +$FileCreateMode 0640 +$DirCreateMode 0755 +$Umask 0022 + +# +# Where to place spool and state files +# +$WorkDirectory /var/spool/rsyslog + +# +# Include all config files in /etc/rsyslog.d/ +# +$IncludeConfig /etc/rsyslog.d/*.conf + +# +# Suppress duplicate messages and report "message repeated n times" +# +$RepeatedMsgReduction on + +############### +#### RULES #### +############### diff --git a/files/image_config/rsyslog/rsyslog.conf.j2 b/files/image_config/rsyslog/rsyslog.conf.j2 index fbf8bf20160a..37410293a45f 100644 --- a/files/image_config/rsyslog/rsyslog.conf.j2 +++ b/files/image_config/rsyslog/rsyslog.conf.j2 @@ -19,7 +19,7 @@ $ModLoad imklog # provides kernel logging support # provides UDP syslog reception $ModLoad imudp -$UDPServerAddress 127.0.0.1 # bind to localhost before udp server run +$UDPServerAddress {{udp_server_ip}} #bind to localhost before udp server run $UDPServerRun 514 # provides TCP syslog reception From 77a1bc25de7000c6082286f3f54a828fb0a8e176 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Tue, 30 Jun 2020 19:07:37 +0300 Subject: [PATCH 0859/1427] [sonic-platform-common] Update submodule (#4871) * src/sonic-platform-common 82bbeab...42781ff (1): > [SfpBase] Fix key name typo in docstring (#99) Signed-off-by: Volodymyr Boyko --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 82bbeabc59b7..42781ff90413 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 82bbeabc59b78886b5cadffe0998c8fe67031343 +Subproject commit 42781ff90413efe2ff709908a5318c85ca67f058 From 0921e3d6ff9f2e1985d73161d4ff5a3a42f0ccdf Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 30 Jun 2020 21:32:56 +0300 Subject: [PATCH 0860/1427] [mellanox]: Update SAI to 1.16.5 (#4873) 1. Upgrade SAI headers to v1.6.3 2. Fix traffic lost during FFB related to buffer config + optimize buffer config timing for FB 3. Add ACL fields BTH, IP flags 4. Add ACL infrastructure of different fields per ASIC type --- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index ba954beb7ae0..a978926f33e1 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.4.1-sai16 +MLNX_SAI_VERSION = SAIRel1.16.5-sai16 export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index b318bb380ac1..0ddcb4e6d12e 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit b318bb380ac13dba98c94b163fbe644ab7eb236e +Subproject commit 0ddcb4e6d12efdd5255529ed53cc785351e8b3b3 From 1af68b3aa680eb238db43494a0c1f2ac6886372a Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Tue, 30 Jun 2020 14:32:04 -0700 Subject: [PATCH 0861/1427] Support for connecting to DB in namespace via TCP port in multi-asic platform. (#4779) * Support for connecting to DB in namespace via IP:port ( using docker bridge network ) for applications in multi-asic platform. * Added the default IP as 127.0.0.1 if the IPaddress derivation from interface fails. Moved the localhost loopback IP binding logic into the supervisor.j2 file. --- .../docker-database/database_config.json.j2 | 2 +- .../docker-database/docker-database-init.sh | 19 ++++++++++++++++++- dockers/docker-database/supervisord.conf.j2 | 7 ++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/dockers/docker-database/database_config.json.j2 b/dockers/docker-database/database_config.json.j2 index 3383ec161144..6d116b5e1ae0 100644 --- a/dockers/docker-database/database_config.json.j2 +++ b/dockers/docker-database/database_config.json.j2 @@ -1,7 +1,7 @@ { "INSTANCES": { "redis":{ - "hostname" : "127.0.0.1", + "hostname" : "{{HOST_IP}}", "port" : 6379, "unix_socket_path" : "/var/run/redis{{NAMESPACE_ID}}/redis.sock", "persistence_for_warm_boot" : "yes" diff --git a/dockers/docker-database/docker-database-init.sh b/dockers/docker-database/docker-database-init.sh index 5dae34d8f616..645a7d99272a 100755 --- a/dockers/docker-database/docker-database-init.sh +++ b/dockers/docker-database/docker-database-init.sh @@ -1,12 +1,29 @@ #!/usr/bin/env bash +# For linux host namespace, in both single and multi ASIC platform use the loopback interface +# For other namespaces, use eth0 interface which is connected to the docker0 bridge in the host. +if [[ $NAMESPACE_ID == "" ]] +then + INTFC=lo +else + INTFC=eth0 +fi + +# Get the ip address of the interface +# if the ip address was not retrieved correctly, put localhost(127.0.0.1) as the default. +host_ip=$(ip -4 -o addr show $INTFC | awk '{print $4}' | cut -d'/' -f1 | head -1) +if [[ $host_ip == "" ]] +then + host_ip=127.0.0.1 +fi + REDIS_DIR=/var/run/redis$NAMESPACE_ID mkdir -p $REDIS_DIR/sonic-db if [ -f /etc/sonic/database_config$NAMESPACE_ID.json ]; then cp /etc/sonic/database_config$NAMESPACE_ID.json $REDIS_DIR/sonic-db/database_config.json else - j2 /usr/share/sonic/templates/database_config.json.j2 > $REDIS_DIR/sonic-db/database_config.json + HOST_IP=$host_ip j2 /usr/share/sonic/templates/database_config.json.j2 > $REDIS_DIR/sonic-db/database_config.json fi mkdir -p /etc/supervisor/conf.d/ diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index 44268274cdad..6d4557dab705 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -20,7 +20,12 @@ stderr_logfile=syslog {% if INSTANCES %} {% for redis_inst, redis_items in INSTANCES.iteritems() %} [program: {{ redis_inst }}] -command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --port {{ redis_items['port'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}" +{% if redis_items['hostname'] != '127.0.0.1' %} +{%- set LOOPBACK_IP = '127.0.0.1' -%} +{%- else -%} +{%- set LOOPBACK_IP = '' -%} +{%- endif -%} +command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --bind {{ LOOPBACK_IP }} {{ redis_items['hostname'] }} --port {{ redis_items['port'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}" priority=2 autostart=true autorestart=false From 74389cb40280c2db4e23d637cac76c03704d2d74 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Tue, 30 Jun 2020 16:29:47 -0700 Subject: [PATCH 0862/1427] [sonic-sairedis] sonic-sairedis submodule update (#4847) * sonic-sairedis submodule update * Update BRCM SAI to 3.7.5.1 --- platform/broadcom/sai.mk | 8 ++++---- src/sonic-sairedis | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 572ae0a70f68..8599e712a3ff 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,8 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.4.2-2_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.4.2-2_amd64.deb?sv=2015-04-05&sr=b&sig=sl819d71a%2BcgrDtOt%2BmywfSL9N2EQS58qMJFq0aKqo8%3D&se=2034-02-11T20%3A28%3A46Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.4.2-2_amd64.deb +BRCM_SAI = libsaibcm_3.7.5.1_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.5.1_amd64.deb?sv=2015-04-05&sr=b&sig=hZLFA8GbuY83MW9g2ggfe53ATx9riuyL1JYXIe1Bib4%3D&se=2034-03-04T00%3A08%3A23Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_3.7.5.1_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.4.2-2_amd64.deb?sv=2015-04-05&sr=b&sig=cvOpP0PWFVmBNeYLMkxyI4BFBQf1DopD32t%2B3AkJHRg%3D&se=2034-02-11T20%3A27%3A46Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.5.1_amd64.deb?sv=2015-04-05&sr=b&sig=i5GcJ8ATr4NL5iLth6DrX8YXxe7ir5OsXN7fxJISvCE%3D&se=2034-03-04T00%3A09%3A48Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 322dd01db434..ef721595520d 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 322dd01db434d00394898d4d1ac34433e95447cd +Subproject commit ef721595520d827277610d11e24082934afc4df8 From eed16e96182adf9e8ff86f0520d4d6ea9685f985 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni <47657796+AkhileshSamineni@users.noreply.github.com> Date: Wed, 1 Jul 2020 15:22:52 +0530 Subject: [PATCH 0863/1427] [docker-nat]: Updated the NAT iptables patch for 4.19 buster (#4843) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated the NAT iptables patch for 4.19 buster Depends on PR : Azure/sonic-linux-kernel#147 1 Known issue: With both NAT patch files for 4.19 buster kernel, seeing 1 display issue in iptables like explained below On Docker NAT, iptables supported version is 1.6.0 and on base OS it’s 1.8.2. So seeing an display issue of which fullcone option is not showing in version 1.8.2 iptables output and no issues in functionality. Display issue – For example of comparsion: NAT Docker: root@sonic:/home/admin# docker exec -it nat bash root@sonic:/# iptables -t nat -nvL Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT all -- * * 0.0.0.0/0 0.0.0.0/0 to:1.1.1.1 fullcone Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 30 packets, 2749 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 30 packets, 2749 bytes) pkts bytes target prot opt in out source destination root@sonic:/# Base OS: root@sonic:/home/admin# iptables-legacy -t nat -nvL Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1 36 DNAT all -- * * 0.0.0.0/0 0.0.0.0/0 to:1.1.1.1 Chain INPUT (policy ACCEPT 1 packets, 36 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 41 packets, 3572 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 41 packets, 3572 bytes) pkts bytes target prot opt in out source destination root@sonic:/home/admin# To fix this issue, iptables need to update from 1.6.0 to 1.8.2 version and have to update the NAT docker from stretch to buster. Will raise a new PR with this. Signed-off-by: Akhilesh Samineni akhilesh.samineni@broadcom.com Signed-off-by: Akhilesh Samineni --- .../0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch index f7fba85a270b..528ce8edea2d 100644 --- a/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch +++ b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch @@ -19,7 +19,7 @@ index a14d16f..4bfab98 100644 +/* Temporarily defining here, need to be picked up from the + * new kernel header linux/netfilter/nf_nat.h */ -+#define NF_NAT_RANGE_FULLCONE (1 << 5) ++#define NF_NAT_RANGE_FULLCONE (1 << 6) + enum { O_TO_DEST = 0, @@ -106,7 +106,7 @@ index b7b5fc7..88ff650 100644 +/* Temporarily defining here, need to be picked up from the + * new kernel header linux/netfilter/nf_nat.h */ -+#define NF_NAT_RANGE_FULLCONE (1 << 5) ++#define NF_NAT_RANGE_FULLCONE (1 << 6) + enum { O_TO_PORTS = 0, @@ -181,7 +181,7 @@ index e92d811..9634ba9 100644 +/* Temporarily defining here, need to be picked up from the + * new kernel header linux/netfilter/nf_nat.h */ -+#define NF_NAT_RANGE_FULLCONE (1 << 5) ++#define NF_NAT_RANGE_FULLCONE (1 << 6) + enum { O_TO_SRC = 0, From 5eabae1edec825e9b72afb7326135bb531cf4fd1 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Wed, 1 Jul 2020 09:08:21 -0700 Subject: [PATCH 0864/1427] Fix in libsaibcm for high CPU utilization of syncd (#4874) --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 8599e712a3ff..bda1231bf2a9 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,8 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.5.1_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.5.1_amd64.deb?sv=2015-04-05&sr=b&sig=hZLFA8GbuY83MW9g2ggfe53ATx9riuyL1JYXIe1Bib4%3D&se=2034-03-04T00%3A08%3A23Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.5.1_amd64.deb +BRCM_SAI = libsaibcm_3.7.5.1-1_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm_3.7.5.1-1_amd64.deb?sv=2015-04-05&sr=b&sig=vSaGIDz2fHBtQXmwJ8OrulAF1N%2Bwk%2B51CkqwNiZFx6I%3D&se=2034-03-10T00%3A45%3A39Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_3.7.5.1-1_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.5.1_amd64.deb?sv=2015-04-05&sr=b&sig=i5GcJ8ATr4NL5iLth6DrX8YXxe7ir5OsXN7fxJISvCE%3D&se=2034-03-04T00%3A09%3A48Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm-dev_3.7.5.1-1_amd64.deb?sv=2015-04-05&sr=b&sig=XpczZg8q3b2z3754wXdc4faOXOFofdlydJKEQaed01o%3D&se=2034-03-10T00%3A46%3A38Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From fc6bcff52bc24bf9f7ff5ccc828b1a2d56f92de9 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 1 Jul 2020 15:58:53 -0700 Subject: [PATCH 0865/1427] [sonic-buildimage] Changes to make network specific sysctl common for both host and docker namespace (#4838) * [sonic-buildimage] Changes to make network specific sysctl common for both host and docker namespace (in multi-npu). This change is triggered with issue found in multi-npu platforms where in docker namespace net.ipv6.conf.all.forwarding was 0 (should be 1) because of which RS/RA message were triggered and link-local router were learnt. Beside this there were some other sysctl.net.ipv6* params whose value in docker namespace is not same as host namespace. So to make we are always in sync in host and docker namespace created common file that list all sysctl.net.* params and used both by host and docker namespace. Any change will get applied to both namespace. Signed-off-by: Abhishek Dosi * Address Review Comments and made sure to invoke augtool only one and do string concatenation of all set commands * Address Review Comments. --- build_debian.sh | 57 +++++------------------ dockers/docker-database/Dockerfile.j2 | 1 + files/build_templates/docker_image_ctl.j2 | 2 +- files/image_config/sysctl/sysctl-net.conf | 39 ++++++++++++++++ rules/docker-database.mk | 2 +- rules/scripts.mk | 8 ++-- 6 files changed, 58 insertions(+), 51 deletions(-) create mode 100644 files/image_config/sysctl/sysctl-net.conf diff --git a/build_debian.sh b/build_debian.sh index 550585c176ec..be973ea4a83c 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -389,61 +389,26 @@ rm /files/lib/systemd/system/rsyslog.service/Service/ExecStart/arguments set /files/lib/systemd/system/rsyslog.service/Service/ExecStart/arguments/1 -n " -## Config sysctl sudo mkdir -p $FILESYSTEM_ROOT/var/core + +# Config sysctl sudo augtool --autosave " set /files/etc/sysctl.conf/kernel.core_pattern '|/usr/bin/coredump-compress %e %t %p' - set /files/etc/sysctl.conf/kernel.softlockup_panic 1 set /files/etc/sysctl.conf/kernel.panic 10 set /files/etc/sysctl.conf/vm.panic_on_oom 2 set /files/etc/sysctl.conf/fs.suid_dumpable 2 +" -r $FILESYSTEM_ROOT -set /files/etc/sysctl.conf/net.ipv4.conf.default.forwarding 1 -set /files/etc/sysctl.conf/net.ipv4.conf.all.forwarding 1 -set /files/etc/sysctl.conf/net.ipv4.conf.eth0.forwarding 0 - -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_accept 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_announce 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_filter 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_notify 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_ignore 0 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_accept 0 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_announce 1 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_filter 0 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_notify 1 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_ignore 2 - -set /files/etc/sysctl.conf/net.ipv4.neigh.default.base_reachable_time_ms 1800000 -set /files/etc/sysctl.conf/net.ipv6.neigh.default.base_reachable_time_ms 1800000 -set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh1 1024 -set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh1 1024 -set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh2 2048 -set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh2 2048 -set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh3 4096 -set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh3 4096 - -set /files/etc/sysctl.conf/net.ipv6.conf.default.forwarding 1 -set /files/etc/sysctl.conf/net.ipv6.conf.all.forwarding 1 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.forwarding 0 - -set /files/etc/sysctl.conf/net.ipv6.conf.default.accept_dad 0 -set /files/etc/sysctl.conf/net.ipv6.conf.all.accept_dad 0 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_dad 0 - -set /files/etc/sysctl.conf/net.ipv6.conf.default.keep_addr_on_down 1 -set /files/etc/sysctl.conf/net.ipv6.conf.all.keep_addr_on_down 1 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.keep_addr_on_down 1 - -set /files/etc/sysctl.conf/net.ipv4.tcp_l3mdev_accept 1 -set /files/etc/sysctl.conf/net.ipv4.udp_l3mdev_accept 1 - -set /files/etc/sysctl.conf/net.core.rmem_max 2097152 -set /files/etc/sysctl.conf/net.core.wmem_max 2097152 - -set /files/etc/sysctl.conf/net.core.somaxconn 512 +sysctl_net_cmd_string="" +while read line; do + [[ "$line" =~ ^#.*$ ]] && continue + sysctl_net_conf_key=`echo $line | awk -F '=' '{print $1}'` + sysctl_net_conf_value=`echo $line | awk -F '=' '{print $2}'` + sysctl_net_cmd_string=$sysctl_net_cmd_string"set /files/etc/sysctl.conf/$sysctl_net_conf_key $sysctl_net_conf_value"$'\n' +done < files/image_config/sysctl/sysctl-net.conf -" -r $FILESYSTEM_ROOT +sudo augtool --autosave "$sysctl_net_cmd_string" -r $FILESYSTEM_ROOT ## docker Python API package is needed by Ansible docker module sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install 'docker==4.1.0' diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index e14be96e8592..cf62d6868dd8 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -40,6 +40,7 @@ COPY ["docker-database-init.sh", "/usr/local/bin/"] COPY ["database_config.json.j2", "/usr/share/sonic/templates/"] COPY ["database_global.json.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["files/sysctl-net.conf", "/etc/sysctl.d/"] COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"] diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 0a0461795944..2ddc18a8ce9b 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -91,7 +91,7 @@ function postStartAction() { {%- if docker_container_name == "database" %} if [ "$DEV" ]; then - docker exec -i database$DEV sysctl -w net.ipv6.conf.all.disable_ipv6=0 + docker exec -i database$DEV sysctl --system -e link_namespace $DEV fi diff --git a/files/image_config/sysctl/sysctl-net.conf b/files/image_config/sysctl/sysctl-net.conf new file mode 100644 index 000000000000..62fda3a8ca91 --- /dev/null +++ b/files/image_config/sysctl/sysctl-net.conf @@ -0,0 +1,39 @@ +# All the sysctl for ipv4/ipv6 network. +# Same will be used in host or docker namespace +# It should be provided as key=value format for parsing +net.ipv6.conf.all.disable_ipv6=0 +net.ipv4.conf.default.forwarding=1 +net.ipv4.conf.all.forwarding=1 +net.ipv4.conf.eth0.forwarding=0 +net.ipv4.conf.default.arp_accept=0 +net.ipv4.conf.default.arp_announce=0 +net.ipv4.conf.default.arp_filter=0 +net.ipv4.conf.default.arp_notify=0 +net.ipv4.conf.default.arp_ignore=0 +net.ipv4.conf.all.arp_accept=0 +net.ipv4.conf.all.arp_announce=1 +net.ipv4.conf.all.arp_filter=0 +net.ipv4.conf.all.arp_notify=1 +net.ipv4.conf.all.arp_ignore=2 +net.ipv4.neigh.default.base_reachable_time_ms=1800000 +net.ipv6.neigh.default.base_reachable_time_ms=1800000 +net.ipv4.neigh.default.gc_thresh1=1024 +net.ipv6.neigh.default.gc_thresh1=1024 +net.ipv4.neigh.default.gc_thresh2=2048 +net.ipv6.neigh.default.gc_thresh2=2048 +net.ipv4.neigh.default.gc_thresh3=4096 +net.ipv6.neigh.default.gc_thresh3=4096 +net.ipv6.conf.default.forwarding=1 +net.ipv6.conf.all.forwarding=1 +net.ipv6.conf.eth0.forwarding=0 +net.ipv6.conf.default.accept_dad=0 +net.ipv6.conf.all.accept_dad=0 +net.ipv6.conf.eth0.accept_dad=0 +net.ipv6.conf.default.keep_addr_on_down=1 +net.ipv6.conf.all.keep_addr_on_down=1 +net.ipv6.conf.eth0.keep_addr_on_down=1 +net.ipv4.tcp_l3mdev_accept=1 +net.ipv4.udp_l3mdev_accept=1 +net.core.rmem_max=2097152 +net.core.wmem_max=2097152 +net.core.somaxconn=512 diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 8062c3b147a5..7cfd8f0bf21e 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -24,4 +24,4 @@ $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli $(DOCKER_DATABASE)_BASE_IMAGE_FILES += monit_database:/etc/monit/conf.d -$(DOCKER_DATABASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_DATABASE)_FILES += $(SYSCTL_NET_CONFIG) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/scripts.mk b/rules/scripts.mk index 8c6d0324fc0e..b3ed0cab95f8 100644 --- a/rules/scripts.mk +++ b/rules/scripts.mk @@ -14,10 +14,12 @@ $(QOS_CONFIG_TEMPLATE)_PATH = files/build_templates SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT = supervisor-proc-exit-listener $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)_PATH = files/scripts +SYSCTL_NET_CONFIG = sysctl-net.conf +$(SYSCTL_NET_CONFIG)_PATH = files/image_config/sysctl + SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(ARP_UPDATE_SCRIPT) \ $(BUFFERS_CONFIG_TEMPLATE) \ $(QOS_CONFIG_TEMPLATE) \ - $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) - - + $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) \ + $(SYSCTL_NET_CONFIG) From 7d0ea7383d34834eb19e5453c0473d80fd98a212 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 2 Jul 2020 00:22:58 -0700 Subject: [PATCH 0866/1427] [pfx_filter]: Add a prefix mask by default in pfx_filter, when there is no one (#4860) If some table with a list of tuples (interface name, ip prefix) has ip prefixes without a mask length, it will cause issues in SONiC. For example quagga and frr will treat ipv4 address without a mask, so "10.20.30.40" address will be treated as "10.0.0.0/8", which is dangerous. The fix here is that when pfx_filter get a tuple (interface name, ip prefix), where the ip prefix doesn't have prefix mask length, add a mask by default: "/32 for ipv4 addresses, /128 for ipv6 addresses". Co-authored-by: Pavel Shirshov --- src/sonic-bgpcfgd/app/template.py | 12 +- src/sonic-bgpcfgd/tests/test_pfx_filter.py | 139 ++++++++++++++++++ src/sonic-config-engine/sonic-cfggen | 12 +- .../tests/data/pfx_filter/param_1.json | 12 ++ .../tests/data/pfx_filter/result_1.txt | 5 + .../tests/data/pfx_filter/tmpl_1.txt.j2 | 3 + .../tests/test_cfggen_pfx_filter.py | 15 ++ 7 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 src/sonic-bgpcfgd/tests/test_pfx_filter.py create mode 100644 src/sonic-config-engine/tests/data/pfx_filter/param_1.json create mode 100644 src/sonic-config-engine/tests/data/pfx_filter/result_1.txt create mode 100644 src/sonic-config-engine/tests/data/pfx_filter/tmpl_1.txt.j2 create mode 100644 src/sonic-config-engine/tests/test_cfggen_pfx_filter.py diff --git a/src/sonic-bgpcfgd/app/template.py b/src/sonic-bgpcfgd/app/template.py index 5c8a4ed810bd..e88073881171 100644 --- a/src/sonic-bgpcfgd/app/template.py +++ b/src/sonic-bgpcfgd/app/template.py @@ -4,6 +4,7 @@ import jinja2 import netaddr +from .log import log_err class TemplateFabric(object): """ Fabric for rendering jinja2 templates """ @@ -94,5 +95,14 @@ def pfx_filter(value): for key, val in value.items(): if not isinstance(key, tuple): continue - table[key] = val + intf, ip_address = key + if '/' not in ip_address: + if TemplateFabric.is_ipv4(ip_address): + table[(intf, "%s/32" % ip_address)] = val + elif TemplateFabric.is_ipv6(ip_address): + table[(intf, "%s/128" % ip_address)] = val + else: + log_err("'%s' is invalid ip address" % ip_address) + else: + table[key] = val return table \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/test_pfx_filter.py b/src/sonic-bgpcfgd/tests/test_pfx_filter.py new file mode 100644 index 000000000000..3eebd3951f7b --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_pfx_filter.py @@ -0,0 +1,139 @@ +from app.template import TemplateFabric +from collections import OrderedDict +import pytest + + +def test_pfx_filter_none(): + res = TemplateFabric.pfx_filter(None) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_empty_tuple(): + res = TemplateFabric.pfx_filter(()) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_empty_list(): + res = TemplateFabric.pfx_filter([]) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_empty_dict(): + res = TemplateFabric.pfx_filter({}) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_strings(): + src = { + 'Loopback0': {}, + 'Loopback1': {}, + } + expected = OrderedDict([]) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +def test_pfx_filter_mixed_keys(): + src = { + 'Loopback0': {}, + ('Loopback0', '11.11.11.11/32'): {}, + 'Loopback1': {}, + ('Loopback1', '55.55.55.55/32'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', '55.55.55.55/32'), {}), + (('Loopback0', '11.11.11.11/32'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + + +def test_pfx_filter_pfx_v4_w_mask(): + src = { + ('Loopback0', '11.11.11.11/32'): {}, + ('Loopback1', '55.55.55.55/32'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', '55.55.55.55/32'), {}), + (('Loopback0', '11.11.11.11/32'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +def test_pfx_filter_pfx_v6_w_mask(): + src = { + ('Loopback0', 'fc00::/128'): {}, + ('Loopback1', 'fc00::1/128'): {}, + } + expected = OrderedDict( + [ + (('Loopback0', 'fc00::/128'), {}), + (('Loopback1', 'fc00::1/128'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +def test_pfx_filter_pfx_v4_no_mask(): + src = { + ('Loopback0', '11.11.11.11'): {}, + ('Loopback1', '55.55.55.55'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', '55.55.55.55/32'), {}), + (('Loopback0', '11.11.11.11/32'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +def test_pfx_filter_pfx_v6_no_mask(): + src = { + ('Loopback0', 'fc00::'): {}, + ('Loopback1', 'fc00::1'): {}, + } + expected = OrderedDict( + [ + (('Loopback0', 'fc00::/128'), {}), + (('Loopback1', 'fc00::1/128'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + + +def test_pfx_filter_pfx_comprehensive(): + src = { + 'Loopback0': {}, + ('Loopback0', 'fc00::'): {}, + 'Loopback1': {}, + ('Loopback1', 'fc00::1/128'): {}, + ('Loopback2', '11.11.11.11/32'): {}, + ('Loopback3', '55.55.55.55'): {}, + 'Loopback2': {}, + 'Loopback3': {}, + ('Loopback5', '22.22.22.1/24'): {}, + ('Loopback6', 'fc00::55/64'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', 'fc00::1/128'), {}), + (('Loopback3', '55.55.55.55/32'), {}), + (('Loopback6', 'fc00::55/64'), {}), + (('Loopback2', '11.11.11.11/32'), {}), + (('Loopback0', 'fc00::/128'), {}), + (('Loopback5', '22.22.22.1/24'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +@pytest.fixture +def test_pfx_filter_wrong_ip(caplog): + src = { + ('Loopback0', 'wrong_ip'): {}, + } + res = TemplateFabric.pfx_filter(src) + assert "'wrong_ip' is invalid ip address" in caplog.text + assert isinstance(res, OrderedDict) and len(res) == 0 + diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index c0f61d8a95f9..8528f828c8a7 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -113,7 +113,17 @@ def pfx_filter(value): for key,val in value.items(): if not isinstance(key, tuple): continue - table[key] = val + intf, ip_address = key + if '/' not in ip_address: + if is_ipv4(ip_address): + new_ip_address = "%s/32" % ip_address + elif is_ipv6(ip_address): + new_ip_address = "%s/128" % ip_address + else: + raise ValueError("'%s' is invalid ip address" % ip_address) + table[(intf, new_ip_address)] = val + else: + table[key] = val return table def ip_network(value): diff --git a/src/sonic-config-engine/tests/data/pfx_filter/param_1.json b/src/sonic-config-engine/tests/data/pfx_filter/param_1.json new file mode 100644 index 000000000000..ce6cd21886a2 --- /dev/null +++ b/src/sonic-config-engine/tests/data/pfx_filter/param_1.json @@ -0,0 +1,12 @@ +{ + "VLAN_INTERFACE": { + "Vlan1": {}, + "Vlan1|1.1.1.1/32": {}, + "Vlan2": {}, + "Vlan2|2.2.2.2": {}, + "Vlan3": {}, + "Vlan3|fc00::1": {}, + "Vlan4": {}, + "Vlan4|fc00::2/64": {} + } +} diff --git a/src/sonic-config-engine/tests/data/pfx_filter/result_1.txt b/src/sonic-config-engine/tests/data/pfx_filter/result_1.txt new file mode 100644 index 000000000000..d8ea7d304222 --- /dev/null +++ b/src/sonic-config-engine/tests/data/pfx_filter/result_1.txt @@ -0,0 +1,5 @@ +"Vlan1"="1.1.1.1/32" +"Vlan2"="2.2.2.2/32" +"Vlan3"="fc00::1/128" +"Vlan4"="fc00::2/64" + diff --git a/src/sonic-config-engine/tests/data/pfx_filter/tmpl_1.txt.j2 b/src/sonic-config-engine/tests/data/pfx_filter/tmpl_1.txt.j2 new file mode 100644 index 000000000000..2612fe4a2936 --- /dev/null +++ b/src/sonic-config-engine/tests/data/pfx_filter/tmpl_1.txt.j2 @@ -0,0 +1,3 @@ +{% for intf, addr in VLAN_INTERFACE|pfx_filter %} +"{{ intf }}"="{{ addr }}" +{% endfor %} diff --git a/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py b/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py new file mode 100644 index 000000000000..8ffd72907b21 --- /dev/null +++ b/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py @@ -0,0 +1,15 @@ +from unittest import TestCase +import subprocess + +class TestPfxFilter(TestCase): + def test_comprehensive(self): + # Generate output + data_dir = "tests/data/pfx_filter" + cmd = "./sonic-cfggen -j %s/param_1.json -t %s/tmpl_1.txt.j2 > /tmp/result_1.txt" % (data_dir, data_dir) + subprocess.check_output(cmd, shell=True) + # Compare outputs + cmd = "diff -u tests/data/pfx_filter/result_1.txt /tmp/result_1.txt" + try: + res = subprocess.check_output(cmd, shell=True) + except subprocess.CalledProcessError as e: + assert False, "Wrong output. return code: %d, Diff: %s" % (e.returncode, e.output) From 2b137fb540691c2a5ca398febd5e9419baf8b99f Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 2 Jul 2020 07:35:45 -0700 Subject: [PATCH 0867/1427] Tests of FRR templates which rendered by sonic-cfggen (#4875) * Tests of FRR templates which rendered by sonic-cfggen --- .../docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 1 + .../data/sonic-cfggen/bgpd.conf.j2/all.conf | 76 ++++++++++ .../data/sonic-cfggen/bgpd.conf.j2/all.json | 33 +++++ .../sonic-cfggen/bgpd.main.conf.j2/all.conf | 56 ++++++++ .../sonic-cfggen/bgpd.main.conf.j2/all.json | 32 +++++ .../sonic-cfggen/bgpd.main.conf.j2/base.conf | 22 +++ .../sonic-cfggen/bgpd.main.conf.j2/base.json | 19 +++ .../bgpd.main.conf.j2/defaults.conf | 56 ++++++++ .../bgpd.main.conf.j2/defaults.json | 29 ++++ .../base.conf | 39 +++++ .../base.json | 42 ++++++ .../sonic-cfggen/common/daemons.common.conf | 10 ++ .../common/daemons.common.conf.json | 7 + .../data/sonic-cfggen/common/functions.conf | 1 + .../sonic-cfggen/common/functions.conf.json | 1 + .../data/sonic-cfggen/frr.conf.j2/all.conf | 91 ++++++++++++ .../data/sonic-cfggen/frr.conf.j2/all.json | 46 ++++++ .../tests/data/sonic-cfggen/isolate/isolate | 17 +++ .../data/sonic-cfggen/isolate/isolate.json | 11 ++ .../tests/data/sonic-cfggen/isolate/unisolate | 17 +++ .../data/sonic-cfggen/isolate/unisolate.json | 11 ++ .../data/sonic-cfggen/staticd/staticd.conf | 19 +++ .../sonic-cfggen/staticd/staticd.conf.json | 12 ++ .../staticd/staticd.default_route.conf | 4 + .../staticd/staticd.default_route.conf.json | 7 + .../tests/data/sonic-cfggen/tsa/isolate.conf | 5 + .../tests/data/sonic-cfggen/tsa/isolate.json | 9 ++ .../data/sonic-cfggen/tsa/unisolate.conf | 3 + .../data/sonic-cfggen/tsa/unisolate.json | 3 + .../data/sonic-cfggen/zebra/interfaces.conf | 14 ++ .../data/sonic-cfggen/zebra/interfaces.json | 10 ++ .../data/sonic-cfggen/zebra/set_src.conf | 8 ++ .../data/sonic-cfggen/zebra/set_src.json | 5 + .../tests/data/sonic-cfggen/zebra/zebra.conf | 36 +++++ .../data/sonic-cfggen/zebra/zebra.conf.json | 23 +++ src/sonic-bgpcfgd/tests/test_sonic-cfggen.py | 133 ++++++++++++++++++ src/sonic-config-engine/sonic-cfggen | 2 + 37 files changed, 910 insertions(+) create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf.json create mode 100644 src/sonic-bgpcfgd/tests/test_sonic-cfggen.py diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index 051cfa4e9dd9..ef98dcf9f16a 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -1,3 +1,4 @@ +{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address %} ! ! template: bgpd/bgpd.main.conf.j2 ! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf new file mode 100644 index 000000000000..166a5c64752c --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf @@ -0,0 +1,76 @@ +! +! template: bgpd/bgpd.conf.j2 +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! template: common/daemons.common.conf.j2 +! +hostname new_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 480 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 32 + exit-address-family + address-family ipv6 + maximum-paths 32 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.json new file mode 100644 index 000000000000..17e32589d84c --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.json @@ -0,0 +1,33 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "new_hostname", + "bgp_asn": "55555", + "sub_role": "FrontEnd" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true, + "restart_time": 480 + }, + "maximum_paths": { + "enabled": true, + "ipv4": 32, + "ipv6": 32 + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf new file mode 100644 index 000000000000..8edbdb60a613 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf @@ -0,0 +1,56 @@ +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 480 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 32 + exit-address-family + address-family ipv6 + maximum-paths 32 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json new file mode 100644 index 000000000000..36099674ac4e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json @@ -0,0 +1,32 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "sub_role": "FrontEnd" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true, + "restart_time": 480 + }, + "maximum_paths": { + "enabled": true, + "ipv4": 32, + "ipv6": 32 + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.conf new file mode 100644 index 000000000000..97159456b6f9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.conf @@ -0,0 +1,22 @@ +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.json new file mode 100644 index 000000000000..692d4c78f0b9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.json @@ -0,0 +1,19 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "sub_role": "" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback1|fc00::1/128": {} + }, + "constants": { + "bgp": { + "multipath_relax": {}, + "graceful_restart": {}, + "maximum_paths": {} + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf new file mode 100644 index 000000000000..b444fcd7e559 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf @@ -0,0 +1,56 @@ +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json new file mode 100644 index 000000000000..2db9bd771c84 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json @@ -0,0 +1,29 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "sub_role": "FrontEnd" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true + }, + "maximum_paths": { + "enabled": true + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf new file mode 100644 index 000000000000..581eb107ec23 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf @@ -0,0 +1,39 @@ +! +! Vnet BGP instance +router bgp 555 vrf First + no bgp default ipv4-unicast + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 10.20.30.40 + neighbor 10.10.10.1 remote-as 10 + neighbor 10.10.10.1 description session1 + address-family ipv4 unicast + neighbor 10.10.10.1 activate + neighbor 10.10.10.1 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +router bgp 555 vrf Second + no bgp default ipv4-unicast + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 10.20.30.40 + neighbor 20.20.20.1 remote-as 20 + neighbor 20.20.20.1 description session2 + address-family ipv4 unicast + neighbor 20.20.20.1 activate + neighbor 20.20.20.1 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.json new file mode 100644 index 000000000000..d6f09fb1139e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.json @@ -0,0 +1,42 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "555" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|10.20.30.40/32": {} + }, + "VNET": { + "First": { + "vni": 10 + }, + "Second": { + "vni": 20 + } + }, + "INTERFACE": { + "Ethernet0": { + "vnet_name": "First" + }, + "Ethernet0|10.10.10.10/24": {}, + "Ethernet8": { + "vnet_name": "Second" + }, + "Ethernet8|20.20.20.20/24": {}, + "Ethernet10": {}, + "Ethernet10|20.20.20.20/24": {} + }, + "BGP_NEIGHBOR": { + "10.10.10.1": { + "asn": "10", + "name": "session1", + "local_addr": "10.10.10.10" + }, + "20.20.20.1": { + "asn": "20", + "name": "session2", + "local_addr": "20.20.20.20" + } + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf new file mode 100644 index 000000000000..14d7b99d07ed --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf @@ -0,0 +1,10 @@ +! template: common/daemons.common.conf.j2 +! +hostname test_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2 diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf.json new file mode 100644 index 000000000000..8ef3e43694a7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf.json @@ -0,0 +1,7 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "test_hostname" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf @@ -0,0 +1 @@ + diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf.json new file mode 100644 index 000000000000..9e26dfeeb6e6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf new file mode 100644 index 000000000000..4c5e81f4f90d --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf @@ -0,0 +1,91 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr.conf.j2 with config DB data +! file: frr.conf +! +! template: common/daemons.common.conf.j2 +! +hostname test_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface PortChannel10 +link-detect +! +interface PortChannel20 +link-detect +! +!! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.10.10.1 200 +!! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 480 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 32 + exit-address-family + address-family ipv6 + maximum-paths 32 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.json new file mode 100644 index 000000000000..d81eba2b0fe6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.json @@ -0,0 +1,46 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "hostname": "test_hostname", + "sub_role": "FrontEnd" + } + }, + "INTERFACE": { + "Ethernet0|10.20.30.40/24": {}, + "Ethernet4|20.20.30.40/24": {} + }, + "PORTCHANNEL": { + "PortChannel10": {}, + "PortChannel20": {} + }, + "MGMT_INTERFACE": { + "eth0|10.10.10.10/24": { + "gwaddr": "10.10.10.1" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true, + "restart_time": 480 + }, + "maximum_paths": { + "enabled": true, + "ipv4": 32, + "ipv6": 32 + } + } + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate new file mode 100644 index 000000000000..74f107495298 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate @@ -0,0 +1,17 @@ +#!/bin/bash +## vtysh only accepts script in stdin, so cannot be directly used in shebang +## Cut the tail of this script and feed vtysh stdin +sed -n -e '9,$p' < "$0" | vtysh "$@" +## Exit with vtysh return code +exit $? +## vtysh script start from next line, which line number MUST equal in 'sed' command above +configure terminal + router bgp 12345 + neighbor 10.20.30.40 route-map ISOLATE out + address-family ipv6 + neighbor fc00::1 route-map ISOLATE out + exit-address-family + exit +exit +clear ip bgp 10.20.30.40 soft out +clear ip bgp fc00::1 soft out diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate.json new file mode 100644 index 000000000000..012b69ef3036 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate.json @@ -0,0 +1,11 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "12345" + } + }, + "BGP_NEIGHBOR": { + "10.20.30.40": {}, + "fc00::1": {} + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate new file mode 100644 index 000000000000..b9476d0b7107 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate @@ -0,0 +1,17 @@ +#!/bin/bash +## vtysh only accepts script in stdin, so cannot be directly used in shebang +## Cut the tail of this script and feed vtysh stdin +sed -n -e '9,$p' < "$0" | vtysh "$@" +## Exit with vtysh return code +exit $? +## vtysh script start from next line, which line number MUST equal in 'sed' command above +configure terminal + router bgp 12345 + no neighbor 10.20.30.40 route-map ISOLATE out + address-family ipv6 + no neighbor fc00::1 route-map ISOLATE out + exit-address-family + exit +exit +clear ip bgp 10.20.30.40 soft out +clear ip bgp fc00::1 soft out diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate.json new file mode 100644 index 000000000000..012b69ef3036 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate.json @@ -0,0 +1,11 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "12345" + } + }, + "BGP_NEIGHBOR": { + "10.20.30.40": {}, + "fc00::1": {} + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf new file mode 100644 index 000000000000..522c0d36f296 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf @@ -0,0 +1,19 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr/staticd.conf.j2 using config DB data +! file: staticd.conf +! +! template: common/daemons.common.conf.j2 +! +hostname new_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.10.10.1 200 +!! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf.json new file mode 100644 index 000000000000..37f660d101d6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf.json @@ -0,0 +1,12 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "new_hostname" + } + }, + "MGMT_INTERFACE": { + "eth0|10.10.10.10/24": { + "gwaddr": "10.10.10.1" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf new file mode 100644 index 000000000000..11adb98ebc3c --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf @@ -0,0 +1,4 @@ +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.10.10.1 200 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf.json new file mode 100644 index 000000000000..80cd218a790e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf.json @@ -0,0 +1,7 @@ +{ + "MGMT_INTERFACE": { + "eth0|10.10.10.10/24": { + "gwaddr": "10.10.10.1" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.conf new file mode 100644 index 000000000000..7bd155fcdb64 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.conf @@ -0,0 +1,5 @@ +route-map test_rm_name permit 2 + match ip address prefix-list PL_LoopbackV4 + set community 12345:555 +route-map test_rm_name deny 3 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json new file mode 100644 index 000000000000..708e4013f131 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json @@ -0,0 +1,9 @@ +{ + "constants": { + "bgp": { + "traffic_shift_community": "12345:555" + } + }, + "route_map_name": "test_rm_name", + "ip_version": "V4" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.conf new file mode 100644 index 000000000000..db53a69e7ec4 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.conf @@ -0,0 +1,3 @@ +no route-map test_rm permit 2 +no route-map test_rm deny 3 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.json new file mode 100644 index 000000000000..da070431493d --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.json @@ -0,0 +1,3 @@ +{ + "route_map_name": "test_rm" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf new file mode 100644 index 000000000000..919c35085b5c --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf @@ -0,0 +1,14 @@ +! +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface PortChannel10 +link-detect +! +interface PortChannel20 +link-detect +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.json new file mode 100644 index 000000000000..e9c1bcba418d --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.json @@ -0,0 +1,10 @@ +{ + "INTERFACE": { + "Ethernet0|10.20.30.40/24": {}, + "Ethernet4|20.20.30.40/24": {} + }, + "PORTCHANNEL": { + "PortChannel10": {}, + "PortChannel20": {} + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.conf new file mode 100644 index 000000000000..b543d24e0023 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.conf @@ -0,0 +1,8 @@ +! +! Set ip source to loopback for bgp learned routes +! +route-map new_rm_name permit 10 + set src 10.20.30.40 +! +ipv4 protocol bgp route-map new_rm_name +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.json new file mode 100644 index 000000000000..2e76d46fd106 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.json @@ -0,0 +1,5 @@ +{ + "rm_name": "new_rm_name", + "lo_ip": "10.20.30.40", + "ip_proto": "v4" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf new file mode 100644 index 000000000000..f7b30f214d4d --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf @@ -0,0 +1,36 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! template: common/daemons.common.conf.j2 +! +hostname new_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +vrf First +vni 10 +! +vrf Second +vni 20 +! +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface PortChannel10 +link-detect +! +interface PortChannel20 +link-detect +! +!! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf.json new file mode 100644 index 000000000000..9b63ff526fb9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf.json @@ -0,0 +1,23 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "new_hostname" + } + }, + "VNET": { + "First": { + "vni": 10 + }, + "Second": { + "vni": 20 + } + }, + "INTERFACE": { + "Ethernet0|10.20.30.40/24": {}, + "Ethernet4|20.20.30.40/24": {} + }, + "PORTCHANNEL": { + "PortChannel10": {}, + "PortChannel20": {} + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py new file mode 100644 index 000000000000..065ecb815ccb --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py @@ -0,0 +1,133 @@ +import os +import subprocess + + +from app.config import ConfigMgr +from .test_templates import compress_comments, write_result + + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') +DATA_PATH = "tests/data/sonic-cfggen/" +CONSTANTS_PATH = os.path.abspath('../../files/image_config/constants/constants.yml') + + +def run_test(name, template_path, json_path, match_path): + template_path = os.path.join(TEMPLATE_PATH, template_path) + json_path = os.path.join(DATA_PATH, json_path) + cfggen = os.path.abspath("../sonic-config-engine/sonic-cfggen") + command = [cfggen, "-T", TEMPLATE_PATH, "-t", template_path, "-y", json_path] + p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + assert p.returncode == 0, "sonic-cfggen for %s test returned %d code. stderr='%s'" % (name, p.returncode, stderr) + raw_generated_result = stdout + assert "None" not in raw_generated_result, "Test %s" % name + canonical_generated_result = ConfigMgr.to_canonical(raw_generated_result) + match_path = os.path.join(DATA_PATH, match_path) + # only for development write_result(match_path, raw_generated_result) + with open(match_path) as result_fp: + raw_saved_result = result_fp.read() + canonical_saved_result = ConfigMgr.to_canonical(raw_saved_result) + assert canonical_saved_result == canonical_generated_result, "Test %s" % name + + +def test_bgpd_main_conf_base(): + run_test("Base bgpd.main.conf.j2", + "bgpd/bgpd.main.conf.j2", + "bgpd.main.conf.j2/base.json", + "bgpd.main.conf.j2/base.conf") + +def test_bgpd_main_conf_comprehensive(): + run_test("Comprehensive bgpd.main.conf.j2", + "bgpd/bgpd.main.conf.j2", + "bgpd.main.conf.j2/all.json", + "bgpd.main.conf.j2/all.conf") + +def test_bgpd_main_conf_defaults(): + run_test("Defaults bgpd.main.conf.j2", + "bgpd/bgpd.main.conf.j2", + "bgpd.main.conf.j2/defaults.json", + "bgpd.main.conf.j2/defaults.conf") + +def test_tsa_isolate(): + run_test("tsa/bgpd.tsa.isolate.conf.j2", + "bgpd/tsa/bgpd.tsa.isolate.conf.j2", + "tsa/isolate.json", + "tsa/isolate.conf") + +def test_tsa_unisolate(): + run_test("tsa/bgpd.tsa.unisolate.conf.j2", + "bgpd/tsa/bgpd.tsa.unisolate.conf.j2", + "tsa/unisolate.json", + "tsa/unisolate.conf") + +def test_common_daemons(): + run_test("daemons.common.conf.j2", + "common/daemons.common.conf.j2", + "common/daemons.common.conf.json", + "common/daemons.common.conf") + +def test_common_functions(): + run_test("functions.conf.j2", + "common/functions.conf.j2", + "common/functions.conf.json", + "common/functions.conf") + +def test_staticd_default_route(): + run_test("staticd.default_route.conf.j2", + "staticd/staticd.default_route.conf.j2", + "staticd/staticd.default_route.conf.json", + "staticd/staticd.default_route.conf") + +def test_staticd(): + run_test("staticd.conf.j2", + "staticd/staticd.conf.j2", + "staticd/staticd.conf.json", + "staticd/staticd.conf") + +def test_zebra_interfaces(): + run_test("zebra.interfaces.conf.j2", + "zebra/zebra.interfaces.conf.j2", + "zebra/interfaces.json", + "zebra/interfaces.conf") + +def test_zebra_set_src(): + run_test("zebra.set_src.conf.j2", + "zebra/zebra.set_src.conf.j2", + "zebra/set_src.json", + "zebra/set_src.conf") + +def test_zebra(): + run_test("zebra.conf.j2", + "zebra/zebra.conf.j2", + "zebra/zebra.conf.json", + "zebra/zebra.conf") + +def test_isolate(): + run_test("isolate.j2", + "isolate.j2", + "isolate/isolate.json", + "isolate/isolate") + +def test_unisolate(): + run_test("unisolate.j2", + "unisolate.j2", + "isolate/unisolate.json", + "isolate/unisolate") + +def test_frr_conf(): + run_test("frr.conf.j2", + "frr.conf.j2", + "frr.conf.j2/all.json", + "frr.conf.j2/all.conf") + +def test_l3vpn_base(): + run_test("bgpd spine_chassis_frontend_router.conf.j2", + "bgpd/bgpd.spine_chassis_frontend_router.conf.j2", + "bgpd.spine_chassis_frontend_router.conf.j2/base.json", + "bgpd.spine_chassis_frontend_router.conf.j2/base.conf") + +def test_bgp_conf_all(): + run_test("bgpd/bgpd.conf", + "bgpd/bgpd.conf.j2", + "bgpd.conf.j2/all.json", + "bgpd.conf.j2/all.conf") diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 8528f828c8a7..1118703458db 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -16,6 +16,8 @@ See usage string for detail description for arguments. """ from __future__ import print_function +import sys +sys.path.insert(0, "/usr/local/lib/python2.7/dist-packages") # monkey patch re.compile to do lazy regular expression compilation. # This is done to improve import time of jinja2, yaml, natsort modules, because they From 002335a3d5f0adceeeccebcd513f5e345e833789 Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Thu, 2 Jul 2020 11:37:40 -0700 Subject: [PATCH 0868/1427] [config]: Loopback Interface changes for multi ASIC devices (#4825) * Loopback IP changes for multi ASIC devices multi ASIC will have 2 Loopback Interfaces - Loopback0 has globally unique IP address, which is advertised by the multi ASIC device to its peers. This way all the external devices will see this device as a single device. - Loopback4096 is assigned an IP address which has a scope is within the device. Each ASIC has a different ip address for Loopback4096. This ip address will be used as Router-Id by the bgp instance on multi ASIC devices. This PR implements this change for multi ASIC devices Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- .../docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 16 +++++++- src/sonic-config-engine/minigraph.py | 32 +++++++++++---- src/sonic-config-engine/sonic-cfggen | 3 ++ src/sonic-config-engine/sonic_device_util.py | 16 ++++++-- .../tests/multi_npu_data/sample-minigraph.xml | 40 +++++++++++++++++-- .../tests/test_multinpu_cfggen.py | 29 ++++++++++++++ 6 files changed, 120 insertions(+), 16 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index ef98dcf9f16a..0199b254d149 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -15,7 +15,7 @@ ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTE {% endif %} ! ! -{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %} +{% if multi_asic() %} route-map HIDE_INTERNAL permit 10 set community local-AS ! @@ -38,16 +38,30 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} ! {# set router-id #} +{% if multi_asic() %} + bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }} +{% else %} bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }} +{% endif %} ! {# advertise loopback #} network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 +{% if multi_asic() %} + network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/32 route-map HIDE_INTERNAL +{% endif %} ! {% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} address-family ipv6 network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/64 exit-address-family {% endif %} +{% if multi_asic() %} +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") != 'None' %} + address-family ipv6 + network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/64 route-map HIDE_INTERNAL + exit-address-family +{% endif %} +{% endif %} {% endblock bgp_init %} ! {% block vlan_advertisement %} diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 79e553e0191d..2fe699987279 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -251,6 +251,15 @@ def parse_asic_png(png, asic_name, hostname): devices[name] = device_data return (neighbors, devices, port_speeds) +def parse_loopback_intf(child): + lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) + lo_intfs = {} + for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): + intfname = lointf.find(str(QName(ns, "AttachTo"))).text + ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text + lo_intfs[(intfname, ipprefix)] = {} + return lo_intfs + def parse_dpg(dpg, hname): aclintfs = None mgmtintfs = None @@ -269,7 +278,6 @@ def parse_dpg(dpg, hname): """ if mgmtintfs is None and child.find(str(QName(ns, "ManagementIPInterfaces"))) is not None: mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) - hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue @@ -290,12 +298,7 @@ def parse_dpg(dpg, hname): ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text intfs[(intfname, ipprefix)] = {} - lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) - lo_intfs = {} - for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): - intfname = lointf.find(str(QName(ns, "AttachTo"))).text - ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text - lo_intfs[(intfname, ipprefix)] = {} + lo_intfs = parse_loopback_intf(child) mvrfConfigs = child.find(str(QName(ns, "MgmtVrfConfigs"))) mvrf = {} @@ -452,6 +455,13 @@ def parse_dpg(dpg, hname): return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni return None, None, None, None, None, None, None, None, None, None +def parse_host_loopback(dpg, hname): + for child in dpg: + hostname = child.find(str(QName(ns, "Hostname"))) + if hostname.text.lower() != hname.lower(): + continue + lo_intfs = parse_loopback_intf(child) + return lo_intfs def parse_cpg(cpg, hname): bgp_sessions = {} @@ -826,6 +836,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw cloudtype = None hostname = None linkmetas = {} + host_lo_intfs = None # hostname is the asic_name, get the asic_id from the asic_name if asic_name is not None: @@ -867,6 +878,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw else: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) + host_lo_intfs = parse_host_loopback(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) enable_internal_bgp_session(bgp_sessions, filename, asic_name) @@ -930,6 +942,12 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw for lo_intf in lo_intfs: results['LOOPBACK_INTERFACE'][lo_intf] = lo_intfs[lo_intf] results['LOOPBACK_INTERFACE'][lo_intf[0]] = {} + + if host_lo_intfs is not None: + for host_lo_intf in host_lo_intfs: + results['LOOPBACK_INTERFACE'][host_lo_intf] = host_lo_intfs[host_lo_intf] + results['LOOPBACK_INTERFACE'][host_lo_intf[0]] = {} + results['MGMT_VRF_CONFIG'] = mvrf phyport_intfs = {} diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 1118703458db..9bda72071937 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -45,6 +45,7 @@ from sonic_device_util import get_machine_info from sonic_device_util import get_platform_info from sonic_device_util import get_system_mac from sonic_device_util import get_npu_id_from_name +from sonic_device_util import is_multi_npu from config_samples import generate_sample_config from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig @@ -344,6 +345,8 @@ def main(): env.filters['ip_network'] = ip_network for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']: env.filters[attr] = partial(prefix_attr, attr) + # Pass the is_multi_npu function as global + env.globals['multi_asic'] = is_multi_npu template = env.get_template(template_file) print(template.render(sort_data(data))) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index 5984a7047fe7..ddfa751250c5 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -44,12 +44,20 @@ def get_npu_id_from_name(npu_name): else: return None +def get_asic_conf_file_path(platform): + asic_conf_path_candidates = [] + asic_conf_path_candidates.append(os.path.join('/usr/share/sonic/platform', ASIC_CONF_FILENAME)) + if platform is not None: + asic_conf_path_candidates.append(os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME)) + for asic_conf_file_path in asic_conf_path_candidates: + if os.path.isfile(asic_conf_file_path): + return asic_conf_file_path + return None + def get_num_npus(): platform = get_platform_info(get_machine_info()) - if not platform: - return 1 - asic_conf_file_path = os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME) - if not os.path.isfile(asic_conf_file_path): + asic_conf_file_path = get_asic_conf_file_path(platform) + if asic_conf_file_path is None: return 1 with open(asic_conf_file_path) as asic_conf_file: for line in asic_conf_file: diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml index 8ca17925c6ec..412262315b4e 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml +++ b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml @@ -387,12 +387,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.0/32 8.0.0.0/32 + + HostIP1 + Loopback4096 + + FD00:1::32/128 + + FD00:1::32/128 + @@ -457,12 +465,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.1/32 8.0.0.1/32 + + HostIP1 + Loopback4096 + + FD00:2::32/128 + + FD00:2::32/128 + @@ -526,12 +542,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.4/32 8.0.0.4/32 + + HostIP1 + Loopback4096 + + FD00:3::32/128 + + FD00:3::32/128 + @@ -580,12 +604,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.5/32 8.0.0.5/32 + + HostIP1 + Loopback4096 + + FD00:4::32/128 + + FD00:4::32/128 + diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index c3307b482b79..7511ce9bcdd1 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -245,3 +245,32 @@ def test_back_end_asic_acl(self): argument = "-m {} -p {} -n asic3 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[3]) output = json.loads(self.run_script(argument)) self.assertDictEqual(output, {}) + + def test_loopback_intfs(self): + argument = "-m {} --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + "Loopback0": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}}) + + # The asic configuration should have 2 loopback interfaces + argument = "-m {} -n asic0 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, { \ + "Loopback0": {}, + "Loopback4096": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}, + "Loopback4096|8.0.0.0/32": {}, + "Loopback4096|FD00:1::32/128": {}}) + + argument = "-m {} -n asic3 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + "Loopback0": {}, + "Loopback4096": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}, + "Loopback4096|8.0.0.5/32": {}, + "Loopback4096|FD00:4::32/128": {}}) From 7c30949758194cc407ccf90a7bda91368e3b778b Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Thu, 2 Jul 2020 11:43:35 -0700 Subject: [PATCH 0869/1427] Added new pip packages, required by kube.py (kubernetes CLI). (#4884) --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 89abf3cd6351..b58f7828187c 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -53,6 +53,9 @@ RUN pip install py2_ipaddress RUN pip install six RUN pip install pyroute2==0.5.3 netifaces==0.10.7 RUN pip install monotonic==1.5 +RUN pip install urllib3 +RUN pip install requests +RUN pip install crontab {% if docker_sonic_vs_debs.strip() -%} # Copy locally-built Debian package dependencies From f8da3e4c696c852cae695e9b06ae56254735180a Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 3 Jul 2020 00:06:17 +0000 Subject: [PATCH 0870/1427] Revert "[config]: Loopback Interface changes for multi ASIC devices (#4825)" This reverts commit cae65a451c6408cf932f8c8316c6747937c7f562. --- .../docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 16 +------- src/sonic-config-engine/minigraph.py | 32 ++++----------- src/sonic-config-engine/sonic-cfggen | 3 -- src/sonic-config-engine/sonic_device_util.py | 16 ++------ .../tests/multi_npu_data/sample-minigraph.xml | 40 ++----------------- .../tests/test_multinpu_cfggen.py | 29 -------------- 6 files changed, 16 insertions(+), 120 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index 0199b254d149..ef98dcf9f16a 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -15,7 +15,7 @@ ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTE {% endif %} ! ! -{% if multi_asic() %} +{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %} route-map HIDE_INTERNAL permit 10 set community local-AS ! @@ -38,30 +38,16 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} ! {# set router-id #} -{% if multi_asic() %} - bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }} -{% else %} bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }} -{% endif %} ! {# advertise loopback #} network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 -{% if multi_asic() %} - network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/32 route-map HIDE_INTERNAL -{% endif %} ! {% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} address-family ipv6 network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/64 exit-address-family {% endif %} -{% if multi_asic() %} -{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") != 'None' %} - address-family ipv6 - network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/64 route-map HIDE_INTERNAL - exit-address-family -{% endif %} -{% endif %} {% endblock bgp_init %} ! {% block vlan_advertisement %} diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 2fe699987279..79e553e0191d 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -251,15 +251,6 @@ def parse_asic_png(png, asic_name, hostname): devices[name] = device_data return (neighbors, devices, port_speeds) -def parse_loopback_intf(child): - lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) - lo_intfs = {} - for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): - intfname = lointf.find(str(QName(ns, "AttachTo"))).text - ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text - lo_intfs[(intfname, ipprefix)] = {} - return lo_intfs - def parse_dpg(dpg, hname): aclintfs = None mgmtintfs = None @@ -278,6 +269,7 @@ def parse_dpg(dpg, hname): """ if mgmtintfs is None and child.find(str(QName(ns, "ManagementIPInterfaces"))) is not None: mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) + hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue @@ -298,7 +290,12 @@ def parse_dpg(dpg, hname): ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text intfs[(intfname, ipprefix)] = {} - lo_intfs = parse_loopback_intf(child) + lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) + lo_intfs = {} + for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): + intfname = lointf.find(str(QName(ns, "AttachTo"))).text + ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text + lo_intfs[(intfname, ipprefix)] = {} mvrfConfigs = child.find(str(QName(ns, "MgmtVrfConfigs"))) mvrf = {} @@ -455,13 +452,6 @@ def parse_dpg(dpg, hname): return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni return None, None, None, None, None, None, None, None, None, None -def parse_host_loopback(dpg, hname): - for child in dpg: - hostname = child.find(str(QName(ns, "Hostname"))) - if hostname.text.lower() != hname.lower(): - continue - lo_intfs = parse_loopback_intf(child) - return lo_intfs def parse_cpg(cpg, hname): bgp_sessions = {} @@ -836,7 +826,6 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw cloudtype = None hostname = None linkmetas = {} - host_lo_intfs = None # hostname is the asic_name, get the asic_id from the asic_name if asic_name is not None: @@ -878,7 +867,6 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw else: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) - host_lo_intfs = parse_host_loopback(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) enable_internal_bgp_session(bgp_sessions, filename, asic_name) @@ -942,12 +930,6 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw for lo_intf in lo_intfs: results['LOOPBACK_INTERFACE'][lo_intf] = lo_intfs[lo_intf] results['LOOPBACK_INTERFACE'][lo_intf[0]] = {} - - if host_lo_intfs is not None: - for host_lo_intf in host_lo_intfs: - results['LOOPBACK_INTERFACE'][host_lo_intf] = host_lo_intfs[host_lo_intf] - results['LOOPBACK_INTERFACE'][host_lo_intf[0]] = {} - results['MGMT_VRF_CONFIG'] = mvrf phyport_intfs = {} diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 9bda72071937..1118703458db 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -45,7 +45,6 @@ from sonic_device_util import get_machine_info from sonic_device_util import get_platform_info from sonic_device_util import get_system_mac from sonic_device_util import get_npu_id_from_name -from sonic_device_util import is_multi_npu from config_samples import generate_sample_config from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig @@ -345,8 +344,6 @@ def main(): env.filters['ip_network'] = ip_network for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']: env.filters[attr] = partial(prefix_attr, attr) - # Pass the is_multi_npu function as global - env.globals['multi_asic'] = is_multi_npu template = env.get_template(template_file) print(template.render(sort_data(data))) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index ddfa751250c5..5984a7047fe7 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -44,20 +44,12 @@ def get_npu_id_from_name(npu_name): else: return None -def get_asic_conf_file_path(platform): - asic_conf_path_candidates = [] - asic_conf_path_candidates.append(os.path.join('/usr/share/sonic/platform', ASIC_CONF_FILENAME)) - if platform is not None: - asic_conf_path_candidates.append(os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME)) - for asic_conf_file_path in asic_conf_path_candidates: - if os.path.isfile(asic_conf_file_path): - return asic_conf_file_path - return None - def get_num_npus(): platform = get_platform_info(get_machine_info()) - asic_conf_file_path = get_asic_conf_file_path(platform) - if asic_conf_file_path is None: + if not platform: + return 1 + asic_conf_file_path = os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME) + if not os.path.isfile(asic_conf_file_path): return 1 with open(asic_conf_file_path) as asic_conf_file: for line in asic_conf_file: diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml index 412262315b4e..8ca17925c6ec 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml +++ b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml @@ -387,20 +387,12 @@ LoopbackInterface HostIP - Loopback4096 + Loopback0 8.0.0.0/32 8.0.0.0/32 - - HostIP1 - Loopback4096 - - FD00:1::32/128 - - FD00:1::32/128 - @@ -465,20 +457,12 @@ LoopbackInterface HostIP - Loopback4096 + Loopback0 8.0.0.1/32 8.0.0.1/32 - - HostIP1 - Loopback4096 - - FD00:2::32/128 - - FD00:2::32/128 - @@ -542,20 +526,12 @@ LoopbackInterface HostIP - Loopback4096 + Loopback0 8.0.0.4/32 8.0.0.4/32 - - HostIP1 - Loopback4096 - - FD00:3::32/128 - - FD00:3::32/128 - @@ -604,20 +580,12 @@ LoopbackInterface HostIP - Loopback4096 + Loopback0 8.0.0.5/32 8.0.0.5/32 - - HostIP1 - Loopback4096 - - FD00:4::32/128 - - FD00:4::32/128 - diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 7511ce9bcdd1..c3307b482b79 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -245,32 +245,3 @@ def test_back_end_asic_acl(self): argument = "-m {} -p {} -n asic3 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[3]) output = json.loads(self.run_script(argument)) self.assertDictEqual(output, {}) - - def test_loopback_intfs(self): - argument = "-m {} --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) - output = json.loads(self.run_script(argument)) - self.assertDictEqual(output, {\ - "Loopback0": {}, - "Loopback0|10.1.0.32/32": {}, - "Loopback0|FC00:1::32/128": {}}) - - # The asic configuration should have 2 loopback interfaces - argument = "-m {} -n asic0 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) - output = json.loads(self.run_script(argument)) - self.assertDictEqual(output, { \ - "Loopback0": {}, - "Loopback4096": {}, - "Loopback0|10.1.0.32/32": {}, - "Loopback0|FC00:1::32/128": {}, - "Loopback4096|8.0.0.0/32": {}, - "Loopback4096|FD00:1::32/128": {}}) - - argument = "-m {} -n asic3 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) - output = json.loads(self.run_script(argument)) - self.assertDictEqual(output, {\ - "Loopback0": {}, - "Loopback4096": {}, - "Loopback0|10.1.0.32/32": {}, - "Loopback0|FC00:1::32/128": {}, - "Loopback4096|8.0.0.5/32": {}, - "Loopback4096|FD00:4::32/128": {}}) From 58632e6e831e6aecb57a4dcca1236c3352e91b1c Mon Sep 17 00:00:00 2001 From: lguohan Date: Thu, 2 Jul 2020 22:03:50 -0700 Subject: [PATCH 0871/1427] [docker-orchagent]: make build depends only on sairedis package (#4880) make swss build depends only on libsairedis instead of syncd. This allows to build swss without depending on vendor sai library. Currently, libsairedis build also buils syncd which requires vendor SAI lib. This makes difficult to build swss docker in buster while still keeping syncd docker in stretch, as swss requires libsairedis which also build syncd and requires vendor to provide SAI for buster. As swss docker does not really contain syncd binary, so it is not necessary to build syncd for swss docker. * [submodule]: update sonic-sairedis * ccbb3bc 2020-06-28 | add option to build without syncd (HEAD, origin/master, origin/HEAD) [Guohan Lu] * 4247481 2020-06-28 | install saidiscovery into syncd package [Guohan Lu] * 61b8e8e 2020-06-26 | Revert "sonic-sairedis: Add support to sonic-sairedis for gearbox phys (#624)" (#630) [Danny Allen] * 85e543c 2020-06-26 | add a README to tests directory to describe how to run 'make check' (#629) [Syd Logan] * 2772f15 2020-06-26 | sonic-sairedis: Add support to sonic-sairedis for gearbox phys (#624) [Syd Logan] Signed-off-by: Guohan Lu --- platform/barefoot/bfn-sai.mk | 1 + platform/barefoot/rules.mk | 8 ++++---- platform/broadcom/rules.mk | 6 +++--- platform/broadcom/sai.mk | 1 + platform/cavium/rules.mk | 6 +++--- platform/centec/rules.mk | 6 +++--- platform/centec/sdk.mk | 1 + platform/innovium/invm-sai.mk | 2 ++ platform/innovium/rules.mk | 4 ++-- platform/marvell-arm64/rules.mk | 6 +++--- platform/marvell-arm64/sai.mk | 1 + platform/marvell-armhf/rules.mk | 6 +++--- platform/marvell-armhf/sai.mk | 1 + platform/marvell/rules.mk | 6 +++--- platform/marvell/sai.mk | 2 ++ platform/mellanox/mlnx-sai.mk | 1 + platform/mellanox/rules.mk | 6 +++--- platform/nephos/rules.mk | 6 +++--- platform/nephos/sai.mk | 3 ++- platform/p4/rules.mk | 6 +++--- platform/vs/syncd-vs.mk | 3 --- rules/sairedis.mk | 35 +------------------------------- rules/swss.mk | 4 +++- rules/syncd.dep | 20 ++++++++++++++++++ rules/syncd.mk | 36 +++++++++++++++++++++++++++++++++ slave.mk | 23 ++++++++++++++++++++- src/sonic-sairedis | 2 +- 27 files changed, 128 insertions(+), 74 deletions(-) create mode 100644 rules/syncd.dep create mode 100644 rules/syncd.mk diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 39b8f3691811..3ba95162032e 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -6,3 +6,4 @@ $(BFN_SAI)_RDEPENDS += $(LIBNL_GENL3) SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) +$(BFN_SAI_DEV)_CONFLICTS += $(LIBSAIVS_DEV) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index 2e45dce8e78b..e223d02c0552 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -19,12 +19,12 @@ include $(PLATFORM_PATH)/bfn-modules.mk SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_ONE_ABOOT) \ $(DOCKER_FPM) -# Inject sai into sairedis -#$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +# Inject sai into syncd +#$(SYNCD)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +$(SYNCD)_DEPENDS += $(BFN_SAI) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on sai is set only for syncd diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk index 8dd7b2c8cbb2..afcec34a73de 100644 --- a/platform/broadcom/rules.mk +++ b/platform/broadcom/rules.mk @@ -32,10 +32,10 @@ SONIC_ONLINE_FILES += $(BCMCMD) $(DSSERVE) SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_ONE_ABOOT_IMAGE) \ $(DOCKER_FPM) -# Inject brcm sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BRCM_SAI) $(BRCM_SAI_DEV) +# Inject brcm sai into syncd +$(SYNCD)_DEPENDS += $(BRCM_SAI) $(BRCM_SAI_DEV) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on brcm sai is set only for syncd diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index bda1231bf2a9..95a97d7b1b91 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -6,3 +6,4 @@ $(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsa SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) +$(BRCM_SAI_DEV)_CONFLICTS += $(LIBSAIVS_DEV) diff --git a/platform/cavium/rules.mk b/platform/cavium/rules.mk index 2da9f5cca9f6..acdd7477fd29 100644 --- a/platform/cavium/rules.mk +++ b/platform/cavium/rules.mk @@ -12,10 +12,10 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_PTF_CAVM) \ $(DOCKER_SYNCD_CAVM_RPC) -# Inject cavium sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(CAVM_SAI) $(CAVM_LIBSAI) +# Inject cavium sai into syncd +$(SYNCD)_DEPENDS += $(CAVM_SAI) $(CAVM_LIBSAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV_CAVM) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV_CAVM) endif # Runtime dependency on cavium sai is set only for syncd diff --git a/platform/centec/rules.mk b/platform/centec/rules.mk index 6f3ac98ecab4..0c9f5a0309ee 100644 --- a/platform/centec/rules.mk +++ b/platform/centec/rules.mk @@ -9,10 +9,10 @@ include $(PLATFORM_PATH)/docker-ptf-centec.mk SONIC_ALL += $(SONIC_ONE_IMAGE) -# Inject centec sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(CENTEC_SAI) +# Inject centec sai into syncd +$(SYNCD)_DEPENDS += $(CENTEC_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on centec sai is set only for syncd diff --git a/platform/centec/sdk.mk b/platform/centec/sdk.mk index 5a5c888e0b09..724c15735675 100644 --- a/platform/centec/sdk.mk +++ b/platform/centec/sdk.mk @@ -1,5 +1,6 @@ # Centec SAI CENTEC_SAI = libsai_1.6.1_amd64.deb $(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/libsai_1.6.1-1.0_amd64.deb +$(CENTEC_SAI)_CONFLICTS += $(LIBSAIVS_DEV) SONIC_ONLINE_DEBS += $(CENTEC_SAI) diff --git a/platform/innovium/invm-sai.mk b/platform/innovium/invm-sai.mk index 9f013208201b..c375572b1d41 100755 --- a/platform/innovium/invm-sai.mk +++ b/platform/innovium/invm-sai.mk @@ -10,4 +10,6 @@ $(INVM_LIBSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_LIBSAI) $(INVM_HSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_HSAI) $(INVM_DRV)_URL = $(INVM_SAI_ONLINE)/$(INVM_DRV) +$(INVM_HSAI)_CONFLICTS += $(LIBSAIVS_DEV) + SONIC_ONLINE_DEBS += $(INVM_LIBSAI) $(INVM_HSAI) $(INVM_DRV) diff --git a/platform/innovium/rules.mk b/platform/innovium/rules.mk index 68a9dbb41040..69b29afb98ca 100755 --- a/platform/innovium/rules.mk +++ b/platform/innovium/rules.mk @@ -13,8 +13,8 @@ SONIC_ALL += $(SONIC_INVM_ONE_IMAGE) \ $(DOCKER_PTF_INVM) \ $(DOCKER_SYNCD_INVM_RPC) -# Inject invm sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(INVM_HSAI) $(INVM_LIBSAI) $(LIBSAITHRIFT_DEV_INVM) +# Inject invm sai into syncd +$(SYNCD)_DEPENDS += $(INVM_HSAI) $(INVM_LIBSAI) $(LIBSAITHRIFT_DEV_INVM) # Runtime dependency on invm sai is set only for syncd $(SYNCD)_RDEPENDS += $(INVM_HSAI) diff --git a/platform/marvell-arm64/rules.mk b/platform/marvell-arm64/rules.mk index bf4667a46d41..5c63392de974 100644 --- a/platform/marvell-arm64/rules.mk +++ b/platform/marvell-arm64/rules.mk @@ -15,10 +15,10 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_PTF_MRVL) \ $(DOCKER_SYNCD_MRVL_RPC) -# Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_SAI) +# Inject mrvl sai into syncd +$(SYNCD)_DEPENDS += $(MRVL_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mrvl sai is set only for syncd diff --git a/platform/marvell-arm64/sai.mk b/platform/marvell-arm64/sai.mk index ebdd7030a3d4..1de18debe615 100644 --- a/platform/marvell-arm64/sai.mk +++ b/platform/marvell-arm64/sai.mk @@ -4,4 +4,5 @@ export MRVL_SAI_VERSION = 1.5.1 export MRVL_SAI = mrvllibsai_$(PLATFORM_ARCH)_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai +$(MRVL_SAI)_CONFLICTS = $(LIBSAIVS_DEV) SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/marvell-armhf/rules.mk b/platform/marvell-armhf/rules.mk index 05ca4788069e..bb4c3f0d4f4f 100644 --- a/platform/marvell-armhf/rules.mk +++ b/platform/marvell-armhf/rules.mk @@ -16,10 +16,10 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) #$(DOCKER_SYNCD_MRVL_RPC) -# Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_SAI) +# Inject mrvl sai into syncd +$(SYNCD)_DEPENDS += $(MRVL_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mrvl sai is set only for syncd diff --git a/platform/marvell-armhf/sai.mk b/platform/marvell-armhf/sai.mk index ebdd7030a3d4..1de18debe615 100644 --- a/platform/marvell-armhf/sai.mk +++ b/platform/marvell-armhf/sai.mk @@ -4,4 +4,5 @@ export MRVL_SAI_VERSION = 1.5.1 export MRVL_SAI = mrvllibsai_$(PLATFORM_ARCH)_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai +$(MRVL_SAI)_CONFLICTS = $(LIBSAIVS_DEV) SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/marvell/rules.mk b/platform/marvell/rules.mk index c01e1e491803..442af4cbe99f 100644 --- a/platform/marvell/rules.mk +++ b/platform/marvell/rules.mk @@ -8,10 +8,10 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) \ $(DOCKER_SYNCD_MRVL_RPC) -# Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_FPA) $(MRVL_SAI) +# Inject mrvl sai into syncd +$(SYNCD)_DEPENDS += $(MRVL_FPA) $(MRVL_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mrvl sai is set only for syncd diff --git a/platform/marvell/sai.mk b/platform/marvell/sai.mk index 553188100045..9e09627c98f5 100644 --- a/platform/marvell/sai.mk +++ b/platform/marvell/sai.mk @@ -4,4 +4,6 @@ export MRVL_SAI_VERSION = 1.5.1 export MRVL_SAI = mrvllibsai_amd64_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai +$(MRVL_SAI)_CONFLICTS = $(LIBSAIVS_DEV) + SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index a978926f33e1..9e9075a6eb3d 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -8,6 +8,7 @@ MLNX_SAI = mlnx-sai_1.mlnx.$(MLNX_SAI_VERSION)_amd64.deb $(MLNX_SAI)_SRC_PATH = $(PLATFORM_PATH)/mlnx-sai $(MLNX_SAI)_DEPENDS += $(MLNX_SDK_DEBS) $(MLNX_SAI)_RDEPENDS += $(MLNX_SDK_RDEBS) $(MLNX_SDK_DEBS) +$(MLNX_SAI)_CONFLICTS += $(LIBSAIVS_DEV) MLNX_SAI_DBGSYM = mlnx-sai-dbgsym_1.mlnx.$(MLNX_SAI_VERSION)_amd64.deb $(eval $(call add_derived_package,$(MLNX_SAI),$(MLNX_SAI_DBGSYM))) SONIC_MAKE_DEBS += $(MLNX_SAI) diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index 1270579e2942..74a87bdb29e1 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -18,10 +18,10 @@ include $(PLATFORM_PATH)/mlnx-ssd-fw-update.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) -# Inject mlnx sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MLNX_SAI) +# Inject mlnx sai into syncd +$(SYNCD)_DEPENDS += $(MLNX_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mlnx sai is set only for syncd diff --git a/platform/nephos/rules.mk b/platform/nephos/rules.mk index 5c115eeaf8d0..727f6ab4610e 100644 --- a/platform/nephos/rules.mk +++ b/platform/nephos/rules.mk @@ -22,10 +22,10 @@ SONIC_ONLINE_FILES += $(NPX_DIAG) $(WARM_VERIFIER) $(DSSERVE) SONIC_ALL += $(SONIC_ONE_IMAGE) $(DOCKER_FPM) -# Inject nephos sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) +# Inject nephos sai into syncd +$(SYNCD)_DEPENDS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on nephos sai is set only for syncd diff --git a/platform/nephos/sai.mk b/platform/nephos/sai.mk index 5f7c4a23ae95..2f457e6ecb4b 100644 --- a/platform/nephos/sai.mk +++ b/platform/nephos/sai.mk @@ -3,7 +3,7 @@ SAI_VERSION = 1.5.0 SAI_COMMIT_ID = 06a67d # Place here URL where SAI deb exist -NEPHOS_SAI_DEB_LOCAL_URL = +NEPHOS_SAI_DEB_LOCAL_URL = export NEPHOS_SAI_DEB_LOCAL_URL # ifneq ($(NEPHOS_SAI_DEB_LOCAL_URL), ) @@ -33,3 +33,4 @@ else SONIC_ONLINE_DEBS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) endif $(NEPHOS_SAI_DEV)_DEPENDS += $(NEPHOS_SAI) +$(NEPHOS_SAI_DEV)_CONFLICTS += $(LIBSAIVS_DEV) diff --git a/platform/p4/rules.mk b/platform/p4/rules.mk index 975dbb82ec8c..b33b04f43d41 100644 --- a/platform/p4/rules.mk +++ b/platform/p4/rules.mk @@ -10,8 +10,8 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk SONIC_ALL += $(DOCKER_SONIC_P4) -$(LIBSAIREDIS)_DEPENDS += $(P4_SWITCH) +$(SYNCD)_DEPENDS += $(P4_SWITCH) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV_P4) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV_P4) endif -$(LIBSAIREDIS)_RDEPENDS += $(P4_SWITCH) +$(SYNCD)_RDEPENDS += $(P4_SWITCH) diff --git a/platform/vs/syncd-vs.mk b/platform/vs/syncd-vs.mk index 49035aaf958b..22b34fbcaae3 100644 --- a/platform/vs/syncd-vs.mk +++ b/platform/vs/syncd-vs.mk @@ -1,8 +1,5 @@ $(LIBSAIREDIS)_DPKG_TARGET = binary-syncd-vs -# inject libsaivs and libsaivs_dev to swss build dependency -$(SWSS)_DEPENDS += $(LIBSAIVS) $(LIBSAIVS_DEV) - SYNCD_VS = syncd-vs_1.0.0_amd64.deb $(SYNCD_VS)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) $(LIBSAIVS) $(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_VS))) diff --git a/rules/sairedis.mk b/rules/sairedis.mk index fd026541a4fb..8e6aff2f7ddb 100644 --- a/rules/sairedis.mk +++ b/rules/sairedis.mk @@ -1,16 +1,10 @@ # sairedis package LIBSAIREDIS = libsairedis_1.0.0_$(CONFIGURED_ARCH).deb +$(LIBSAIREDIS)_DPKG_TARGET = binary-sairedis $(LIBSAIREDIS)_SRC_PATH = $(SRC_PATH)/sonic-sairedis $(LIBSAIREDIS)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBSAIREDIS)_RDEPENDS += $(LIBSWSSCOMMON) -ifneq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DPKG_TARGET = binary-syncd -else -# Inject libthrift build dependency for RPC build -$(LIBSAIREDIS)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBTHRIFT_DEV) -$(LIBSAIREDIS)_DPKG_TARGET = binary-syncd-rpc -endif $(LIBSAIREDIS)_DEB_BUILD_OPTIONS = nocheck SONIC_DPKG_DEBS += $(LIBSAIREDIS) @@ -23,18 +17,6 @@ $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIVS))) LIBSAIVS_DEV = libsaivs-dev_1.0.0_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIVS_DEV))) -ifneq ($(CONFIGURED_PLATFORM),vs) -SYNCD = syncd_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD))) - -ifeq ($(ENABLE_SYNCD_RPC),y) -SYNCD_RPC = syncd-rpc_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD_RPC)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_RPC))) -endif -endif - LIBSAIMETADATA = libsaimetadata_1.0.0_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIMETADATA))) @@ -52,20 +34,6 @@ $(LIBSAIVS_DBG)_DEPENDS += $(LIBSAIVS) $(LIBSAIVS_DBG)_RDEPENDS += $(LIBSAIVS) $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIVS_DBG))) -ifneq ($(CONFIGURED_PLATFORM),vs) -SYNCD_DBG = syncd-dbg_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD_DBG)_DEPENDS += $(SYNCD) -$(SYNCD_DBG)_RDEPENDS += $(SYNCD) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_DBG))) - -ifeq ($(ENABLE_SYNCD_RPC),y) -SYNCD_RPC_DBG = syncd-rpc-dbg_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD_RPC_DBG)_DEPENDS += $(SYNCD_RPC) -$(SYNCD_RPC_DBG)_RDEPENDS += $(SYNCD_RPC) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_RPC_DBG))) -endif -endif - LIBSAIMETADATA_DBG = libsaimetadata-dbg_1.0.0_$(CONFIGURED_ARCH).deb $(LIBSAIMETADATA_DBG)_DEPENDS += $(LIBSAIMETADATA) $(LIBSAIMETADATA_DBG)_RDEPENDS += $(LIBSAIMETADATA) @@ -75,4 +43,3 @@ $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIMETADATA_DBG))) # are archived into debug one image to facilitate debugging. # DBG_SRC_ARCHIVE += sonic-sairedis - diff --git a/rules/swss.mk b/rules/swss.mk index b8106757ac66..bb4293c2d9bb 100644 --- a/rules/swss.mk +++ b/rules/swss.mk @@ -3,7 +3,9 @@ SWSS = swss_1.0.0_$(CONFIGURED_ARCH).deb $(SWSS)_SRC_PATH = $(SRC_PATH)/sonic-swss $(SWSS)_DEPENDS += $(LIBSAIREDIS_DEV) $(LIBSAIMETADATA_DEV) $(LIBTEAM_DEV) \ - $(LIBTEAMDCTL) $(LIBTEAM_UTILS) $(LIBSWSSCOMMON_DEV) + $(LIBTEAMDCTL) $(LIBTEAM_UTILS) $(LIBSWSSCOMMON_DEV) \ + $(LIBSAIVS) $(LIBSAIVS_DEV) + $(SWSS)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) $(LIBTEAM) \ $(LIBTEAMDCTL) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) SONIC_DPKG_DEBS += $(SWSS) diff --git a/rules/syncd.dep b/rules/syncd.dep new file mode 100644 index 000000000000..d9f40a8a0210 --- /dev/null +++ b/rules/syncd.dep @@ -0,0 +1,20 @@ + +ifneq ($(CONFIGURED_PLATFORM),vs) + +#DPKG FRK +SPATH := $($(SYNCD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/syncd.mk rules/syncd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) + +SMDEP_PATHS := $(SPATH) $(SPATH)/SAI $(SPATH)/SAI/bm/behavioral-model $(SPATH)/SAI/test/ptf $(SPATH)/SAI/test/saithrift/ctypesgen +$(foreach path, $(SMDEP_PATHS), $(eval $(path) :=$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/, \ + $(shell cd $(path) && git ls-files | grep -v " "))))) + + +$(SYNCD)_CACHE_MODE := GIT_CONTENT_SHA +$(SYNCD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SYNCD)_DEP_FILES := $(DEP_FILES) +$(SYNCD)_SMDEP_FILES := $(foreach path, $(SMDEP_PATHS), $($(path))) +$(SYNCD)_SMDEP_PATHS := $(SMDEP_PATHS) + +endif diff --git a/rules/syncd.mk b/rules/syncd.mk new file mode 100644 index 000000000000..2b7007d84d5b --- /dev/null +++ b/rules/syncd.mk @@ -0,0 +1,36 @@ +# only used for non-vs platforms + +ifneq ($(CONFIGURED_PLATFORM),vs) + +SYNCD = syncd_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) +$(SYNCD)_DPKG_TARGET = binary-syncd +$(SYNCD)_SRC_PATH = $(SRC_PATH)/sonic-sairedis +$(SYNCD)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBSAIREDIS) +$(SYNCD)_RDEPENDS += $(LIBSWSSCOMMON) +$(SYNCD)_DEB_BUILD_OPTIONS = nocheck +SONIC_DPKG_DEBS += $(SYNCD) + +ifeq ($(ENABLE_SYNCD_RPC),y) +SYNCD_RPC = syncd-rpc_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD_RPC)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) +$(eval $(call add_derived_package,$(SYNCD),$(SYNCD_RPC))) + +# Inject libthrift build dependency for RPC build +$(SYNCD)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBTHRIFT_DEV) +$(SYNCD)_DPKG_TARGET = binary-syncd-rpc +endif + +SYNCD_DBG = syncd-dbg_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD_DBG)_DEPENDS += $(SYNCD) +$(SYNCD_DBG)_RDEPENDS += $(SYNCD) +$(eval $(call add_derived_package,$(SYNCD),$(SYNCD_DBG))) + +ifeq ($(ENABLE_SYNCD_RPC),y) +SYNCD_RPC_DBG = syncd-rpc-dbg_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD_RPC_DBG)_DEPENDS += $(SYNCD_RPC) +$(SYNCD_RPC_DBG)_RDEPENDS += $(SYNCD_RPC) +$(eval $(call add_derived_package,$(SYNCD),$(SYNCD_RPC_DBG))) +endif + +endif diff --git a/slave.mk b/slave.mk index a03c28f44867..cd22d665cfb8 100644 --- a/slave.mk +++ b/slave.mk @@ -479,7 +479,7 @@ SONIC_INSTALL_TARGETS = $(addsuffix -install,$(addprefix $(DEBS_PATH)/, \ $(SONIC_PYTHON_STDEB_DEBS) \ $(SONIC_DERIVED_DEBS) \ $(SONIC_EXTRA_DEBS))) -$(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) $(DEBS_PATH)/$$* +$(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) $(DEBS_PATH)/$$* $$(addsuffix -uninstall,$$(addprefix $(DEBS_PATH)/,$$($$*_CONFLICTS))) $(HEADER) [ -f $(DEBS_PATH)/$* ] || { echo $(DEBS_PATH)/$* does not exist $(LOG) && false $(LOG) } # put a lock here because dpkg does not allow installing packages in parallel @@ -490,6 +490,27 @@ $(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -inst done $(FOOTER) +# Targets for installing debian packages prior to build one that depends on them +SONIC_UNINSTALL_TARGETS = $(addsuffix -uninstall,$(addprefix $(DEBS_PATH)/, \ + $(SONIC_ONLINE_DEBS) \ + $(SONIC_COPY_DEBS) \ + $(SONIC_MAKE_DEBS) \ + $(SONIC_DPKG_DEBS) \ + $(SONIC_PYTHON_STDEB_DEBS) \ + $(SONIC_DERIVED_DEBS) \ + $(SONIC_EXTRA_DEBS))) + +$(SONIC_UNINSTALL_TARGETS) : $(DEBS_PATH)/%-uninstall : .platform + $(HEADER) + [ -f $(DEBS_PATH)/$* ] || { echo $(DEBS_PATH)/$* does not exist $(LOG) && false $(LOG) } + # put a lock here because dpkg does not allow installing packages in parallel + while true; do + if mkdir $(DEBS_PATH)/dpkg_lock &> /dev/null; then + { sudo DEBIAN_FRONTEND=noninteractive dpkg -P $(firstword $(subst _, ,$(basename $*))) $(LOG) && rm -d $(DEBS_PATH)/dpkg_lock && break; } || { rm -d $(DEBS_PATH)/dpkg_lock && exit 1 ; } + fi + done + $(FOOTER) + ############################################################################### ## Python packages ############################################################################### diff --git a/src/sonic-sairedis b/src/sonic-sairedis index ef721595520d..ccbb3bcc877c 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit ef721595520d827277610d11e24082934afc4df8 +Subproject commit ccbb3bcc877cff271104ed428d9aadc4438dd73a From cba801ae892ea1f580638facebf098f939138d29 Mon Sep 17 00:00:00 2001 From: paavaanan Date: Fri, 3 Jul 2020 10:38:04 +0530 Subject: [PATCH 0872/1427] [Dell]: DellEMC S6100 disable pericom/xlinx chipset (#4868) - Xilinx/pericom peripherals are not actively used in DellEMC S6100 switch. - These peripherals are throwing PCIE corrected messages in some of the units and filling syslog. - Since it is not usable disabling it at startup. --- .../s6100/scripts/s6100_platform.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh index 34dc0daa4ff0..1f65045bd315 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -18,6 +18,8 @@ remove_python_api_package() { if [[ "$1" == "init" ]]; then + + pericom="/sys/bus/pci/devices/0000:08:00.0" modprobe i2c-dev modprobe i2c-mux-pca954x force_deselect_on_exit=1 modprobe dell_ich @@ -26,6 +28,10 @@ if [[ "$1" == "init" ]]; then modprobe nvram systemctl start s6100-reboot-cause.service + # Disable pericom/xilinx + echo 1 > /sys/bus/pci/devices/0000:02:00.0/remove + [ -d $pericom ] && echo 1 > $pericom/remove + # Disable Watchdog Timer if [[ -e /usr/local/bin/platform_watchdog_disable.sh ]]; then /usr/local/bin/platform_watchdog_disable.sh From 856f117fd30f834b16f08784cca7f08ff6e43f40 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 2 Jul 2020 22:38:31 -0700 Subject: [PATCH 0873/1427] [sonic-platform-daemons] Update submodule (#4887) * src/sonic-platform-daemons abe115e...9b8bfa1 (1): > [xcvrd] Update key names in 'get_media_settings_value()' (#63) --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index abe115e6a680..9b8bfa10b2ba 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit abe115e6a680c76d09dea04e6aab1d16876aed7a +Subproject commit 9b8bfa10b2ba57129edfe5447880afea02b5692d From e2e57d32d69f0f12292f02c3f4badce220fe1b61 Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 3 Jul 2020 14:31:31 -0700 Subject: [PATCH 0874/1427] [docker-orchagent]: upgrade docker-orchagent to buster (#4889) also update submodule * 01f810f 2020-07-02 | fix compiling issue for gcc8.3 (#1339) [lguohan] * 9b13120 2020-07-03 | Fix in script to avoid orchagent crash when port down followed by fdb delete (#1340) [rupesh-k] * 9b01844 2020-07-01 | [qosorch] Update QoS scheduler params for shaping features (#1296) [Michael Li] * 86b5e99 2020-07-02 | [mirrororch] Port Mirroring implementation (#1314) [rupesh-k] * c05601c 2020-06-24 | [portsyncd]: add debug message if a port cannot be found in port able (#1328) [lguohan] * a0b6412 2020-06-23 | COPP_DEL_fix: DEL for one trap group from SONIC is resetting all the trap IDs (#1273) [SinghMinu] Signed-off-by: Guohan Lu --- dockers/docker-orchagent/Dockerfile.j2 | 2 +- rules/docker-orchagent.mk | 8 +++----- src/sonic-swss | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index d08ecdb49d48..2584a34e1e31 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index 4d63502ebb44..e60bc8191461 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -6,23 +6,21 @@ DOCKER_ORCHAGENT_DBG = $(DOCKER_ORCHAGENT_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_ORCHAGENT)_DEPENDS += $(SWSS) -$(DOCKER_ORCHAGENT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_ORCHAGENT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_ORCHAGENT)_DBG_DEPENDS += $(SWSS_DBG) \ $(LIBSWSSCOMMON_DBG) \ $(LIBSAIREDIS_DBG) -$(DOCKER_ORCHAGENT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_ORCHAGENT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) $(DOCKER_ORCHAGENT)_PATH = $(DOCKERS_PATH)/$(DOCKER_ORCHAGENT_STEM) -$(DOCKER_ORCHAGENT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_ORCHAGENT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_ORCHAGENT) -SONIC_STRETCH_DOCKERS += $(DOCKER_ORCHAGENT) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ORCHAGENT) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_ORCHAGENT_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ORCHAGENT_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ORCHAGENT_DBG) $(DOCKER_ORCHAGENT)_CONTAINER_NAME = swss diff --git a/src/sonic-swss b/src/sonic-swss index 17a2f93a545b..01f810f43e71 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 17a2f93a545b8669e44a62231c340ba518272ed7 +Subproject commit 01f810f43e71a570f7821c63f8ac030c03f88150 From 15748a50ae04dd20bdd4d94e20f4bb478d00ca67 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Sat, 4 Jul 2020 00:33:12 +0300 Subject: [PATCH 0875/1427] [barefoot][SAI v1.6.3] Update SAI and platform packages to 20200701 (#4890) Signed-off-by: Volodymyr Boyko --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 99ee7592f372..d563db67454e 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20200618_deb9.deb +BFN_PLATFORM = bfnplatform_20200701_deb9.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 3ba95162032e..05e70282ddb9 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20200618_deb9.deb +BFN_SAI = bfnsdk_20200701_deb9.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) From 68e7cdb5eda92a040c894663213358b025a22a47 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Sat, 4 Jul 2020 21:40:02 +0800 Subject: [PATCH 0876/1427] Fix dpkg cache hash value relative to file path issue (#4894) --- Makefile.cache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.cache b/Makefile.cache index fb79e51e7f1d..5422b595929a 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -68,7 +68,7 @@ # Run the 'touch cache.skip.common' command in the base directory to exclude the common files from caching SONIC_COMMON_FILES_LIST := $(if $(wildcard cache.skip.common),, .platform slave.mk rules/functions Makefile.cache) SONIC_COMMON_FLAGS_LIST := $(CONFIGURED_PLATFORM) \ - $(SONIC_DPKG_CACHE_SOURCE) $(SONIC_DEBUGGING_ON) \ + $(SONIC_DEBUGGING_ON) \ $(SONIC_PROFILING_ON) $(SONIC_ENABLE_SYNCD_RPC) SONIC_COMMON_DPKG_LIST := debian/control debian/changelog debian/rules \ debian/compat debian/install debian/copyright From 2c426a8290bc5f6a97d7a7181b15b0a7d395d916 Mon Sep 17 00:00:00 2001 From: zzhiyuan Date: Sun, 5 Jul 2020 00:11:42 -0700 Subject: [PATCH 0877/1427] Skip thermalctld for arista platforms (#4893) thermalctld throwing error messages because it is not yet fully configured, disabling it for now on arista platforms. Co-authored-by: Zhi Yuan Carl Zhao --- .../arista/x86_64-arista_7050_qx32/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7060px4_32/pmon_daemon_control.json | 1 + device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7170_32cd/pmon_daemon_control.json | 1 + device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json | 1 + .../x86_64-arista_7280cr3_32p4/pmon_daemon_control.json | 1 + .../pmon_daemon_control_skip_thermalctld.json | 4 ++++ 12 files changed, 15 insertions(+) create mode 120000 device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json create mode 100644 device/arista/x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json diff --git a/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json b/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json new file mode 120000 index 000000000000..2322ef7a22d8 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json new file mode 120000 index 000000000000..2322ef7a22d8 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json new file mode 120000 index 000000000000..2322ef7a22d8 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json new file mode 120000 index 000000000000..2322ef7a22d8 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json new file mode 120000 index 000000000000..2322ef7a22d8 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json b/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json new file mode 120000 index 000000000000..2322ef7a22d8 --- /dev/null +++ b/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json new file mode 120000 index 000000000000..2322ef7a22d8 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json new file mode 120000 index 000000000000..2322ef7a22d8 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json new file mode 120000 index 000000000000..2322ef7a22d8 --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json b/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json new file mode 120000 index 000000000000..2322ef7a22d8 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json b/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json new file mode 120000 index 000000000000..2322ef7a22d8 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json b/device/arista/x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json new file mode 100644 index 000000000000..75db6d97558a --- /dev/null +++ b/device/arista/x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json @@ -0,0 +1,4 @@ +{ + "skip_thermalctld": true +} + From 97fa2c087b6b5e49a6d285e1e8131796d05470f4 Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Sun, 5 Jul 2020 22:22:31 -0700 Subject: [PATCH 0878/1427] "[config]: Multi ASIC loopback changes (#4895) Resubmitting the changes for (#4825) with fixes for sonic-bgpcdgd test failures Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- .../docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 16 +++++++- src/sonic-config-engine/minigraph.py | 32 +++++++++++---- src/sonic-config-engine/sonic-cfggen | 3 ++ src/sonic-config-engine/sonic_device_util.py | 16 ++++++-- .../tests/multi_npu_data/sample-minigraph.xml | 40 +++++++++++++++++-- .../tests/test_multinpu_cfggen.py | 29 ++++++++++++++ 6 files changed, 120 insertions(+), 16 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index ef98dcf9f16a..5fe7a2b01051 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -15,7 +15,7 @@ ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTE {% endif %} ! ! -{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %} +{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' or DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} route-map HIDE_INTERNAL permit 10 set community local-AS ! @@ -38,16 +38,30 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} ! {# set router-id #} +{% if multi_asic() %} + bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }} +{% else %} bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }} +{% endif %} ! {# advertise loopback #} network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 +{% if multi_asic() %} + network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/32 route-map HIDE_INTERNAL +{% endif %} ! {% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} address-family ipv6 network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/64 exit-address-family {% endif %} +{% if multi_asic() %} +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") != 'None' %} + address-family ipv6 + network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/64 route-map HIDE_INTERNAL + exit-address-family +{% endif %} +{% endif %} {% endblock bgp_init %} ! {% block vlan_advertisement %} diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 79e553e0191d..2fe699987279 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -251,6 +251,15 @@ def parse_asic_png(png, asic_name, hostname): devices[name] = device_data return (neighbors, devices, port_speeds) +def parse_loopback_intf(child): + lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) + lo_intfs = {} + for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): + intfname = lointf.find(str(QName(ns, "AttachTo"))).text + ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text + lo_intfs[(intfname, ipprefix)] = {} + return lo_intfs + def parse_dpg(dpg, hname): aclintfs = None mgmtintfs = None @@ -269,7 +278,6 @@ def parse_dpg(dpg, hname): """ if mgmtintfs is None and child.find(str(QName(ns, "ManagementIPInterfaces"))) is not None: mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) - hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue @@ -290,12 +298,7 @@ def parse_dpg(dpg, hname): ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text intfs[(intfname, ipprefix)] = {} - lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) - lo_intfs = {} - for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): - intfname = lointf.find(str(QName(ns, "AttachTo"))).text - ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text - lo_intfs[(intfname, ipprefix)] = {} + lo_intfs = parse_loopback_intf(child) mvrfConfigs = child.find(str(QName(ns, "MgmtVrfConfigs"))) mvrf = {} @@ -452,6 +455,13 @@ def parse_dpg(dpg, hname): return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni return None, None, None, None, None, None, None, None, None, None +def parse_host_loopback(dpg, hname): + for child in dpg: + hostname = child.find(str(QName(ns, "Hostname"))) + if hostname.text.lower() != hname.lower(): + continue + lo_intfs = parse_loopback_intf(child) + return lo_intfs def parse_cpg(cpg, hname): bgp_sessions = {} @@ -826,6 +836,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw cloudtype = None hostname = None linkmetas = {} + host_lo_intfs = None # hostname is the asic_name, get the asic_id from the asic_name if asic_name is not None: @@ -867,6 +878,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw else: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) + host_lo_intfs = parse_host_loopback(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) enable_internal_bgp_session(bgp_sessions, filename, asic_name) @@ -930,6 +942,12 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw for lo_intf in lo_intfs: results['LOOPBACK_INTERFACE'][lo_intf] = lo_intfs[lo_intf] results['LOOPBACK_INTERFACE'][lo_intf[0]] = {} + + if host_lo_intfs is not None: + for host_lo_intf in host_lo_intfs: + results['LOOPBACK_INTERFACE'][host_lo_intf] = host_lo_intfs[host_lo_intf] + results['LOOPBACK_INTERFACE'][host_lo_intf[0]] = {} + results['MGMT_VRF_CONFIG'] = mvrf phyport_intfs = {} diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 1118703458db..9bda72071937 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -45,6 +45,7 @@ from sonic_device_util import get_machine_info from sonic_device_util import get_platform_info from sonic_device_util import get_system_mac from sonic_device_util import get_npu_id_from_name +from sonic_device_util import is_multi_npu from config_samples import generate_sample_config from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig @@ -344,6 +345,8 @@ def main(): env.filters['ip_network'] = ip_network for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']: env.filters[attr] = partial(prefix_attr, attr) + # Pass the is_multi_npu function as global + env.globals['multi_asic'] = is_multi_npu template = env.get_template(template_file) print(template.render(sort_data(data))) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index 5984a7047fe7..ddfa751250c5 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -44,12 +44,20 @@ def get_npu_id_from_name(npu_name): else: return None +def get_asic_conf_file_path(platform): + asic_conf_path_candidates = [] + asic_conf_path_candidates.append(os.path.join('/usr/share/sonic/platform', ASIC_CONF_FILENAME)) + if platform is not None: + asic_conf_path_candidates.append(os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME)) + for asic_conf_file_path in asic_conf_path_candidates: + if os.path.isfile(asic_conf_file_path): + return asic_conf_file_path + return None + def get_num_npus(): platform = get_platform_info(get_machine_info()) - if not platform: - return 1 - asic_conf_file_path = os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME) - if not os.path.isfile(asic_conf_file_path): + asic_conf_file_path = get_asic_conf_file_path(platform) + if asic_conf_file_path is None: return 1 with open(asic_conf_file_path) as asic_conf_file: for line in asic_conf_file: diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml index 8ca17925c6ec..412262315b4e 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml +++ b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml @@ -387,12 +387,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.0/32 8.0.0.0/32 + + HostIP1 + Loopback4096 + + FD00:1::32/128 + + FD00:1::32/128 + @@ -457,12 +465,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.1/32 8.0.0.1/32 + + HostIP1 + Loopback4096 + + FD00:2::32/128 + + FD00:2::32/128 + @@ -526,12 +542,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.4/32 8.0.0.4/32 + + HostIP1 + Loopback4096 + + FD00:3::32/128 + + FD00:3::32/128 + @@ -580,12 +604,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.5/32 8.0.0.5/32 + + HostIP1 + Loopback4096 + + FD00:4::32/128 + + FD00:4::32/128 + diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index c3307b482b79..7511ce9bcdd1 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -245,3 +245,32 @@ def test_back_end_asic_acl(self): argument = "-m {} -p {} -n asic3 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[3]) output = json.loads(self.run_script(argument)) self.assertDictEqual(output, {}) + + def test_loopback_intfs(self): + argument = "-m {} --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + "Loopback0": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}}) + + # The asic configuration should have 2 loopback interfaces + argument = "-m {} -n asic0 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, { \ + "Loopback0": {}, + "Loopback4096": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}, + "Loopback4096|8.0.0.0/32": {}, + "Loopback4096|FD00:1::32/128": {}}) + + argument = "-m {} -n asic3 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + "Loopback0": {}, + "Loopback4096": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}, + "Loopback4096|8.0.0.5/32": {}, + "Loopback4096|FD00:4::32/128": {}}) From 1dcf8ec04f6f637c32d0ae2dbf4d5c904a17d56d Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 6 Jul 2020 22:10:27 -0700 Subject: [PATCH 0879/1427] [kernel]: upgrade linux kernel to 4.9.118 (#4897) upgrade kernel to latest maintenance version 4.9.118 Signed-off-by: Guohan Lu --- build_debian.sh | 2 +- installer/x86_64/install.sh | 4 ++-- platform/barefoot/bfn-modules/debian/control | 2 +- .../debian/control | 2 +- .../debian/control | 2 +- .../sonic-platform-modules-bfn/debian/control | 2 +- .../debian/control | 2 +- platform/broadcom/saibcm-modules/debian/control | 2 +- .../saibcm-modules/debian/opennsl-modules.dirs | 2 +- .../saibcm-modules/debian/opennsl-modules.install | 10 +++++----- platform/broadcom/saibcm-modules/debian/rules | 2 +- .../debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 8 ++++---- .../sonic-platform-modules-dell/debian/control | 14 +++++++------- .../sonic-platform-modules-delta/debian/control | 12 ++++++------ .../sonic-platform-modules-inventec/debian/control | 12 ++++++------ .../sonic-platform-modules-mitac/debian/control | 2 +- .../cavium/cavm_platform_modules/DEBIAN/control | 2 +- .../sonic-platform-modules-e582/debian/control | 4 ++-- .../sonic-platform-modules-embedway/debian/control | 2 +- .../sonic-platform-modules-cel/debian/control | 2 +- .../sonic-platform-modules-delta/debian/control | 2 +- platform/nephos/nephos-modules/debian/control | 2 +- .../sonic-platform-modules-accton/debian/control | 2 +- .../sonic-platform-modules-cig/debian/control | 6 +++--- .../sonic-platform-modules-pegatron/debian/control | 2 +- rules/linux-kernel.mk | 6 +++--- src/sonic-linux-kernel | 2 +- 28 files changed, 58 insertions(+), 58 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index be973ea4a83c..4a6751fa40ca 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -37,7 +37,7 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then else DOCKER_VERSION=5:18.09.8~3-0~debian-$IMAGE_DISTRO fi -LINUX_KERNEL_VERSION=4.19.0-6-2 +LINUX_KERNEL_VERSION=4.19.0-9-2 ## Working directory to prepare the file system FILESYSTEM_ROOT=./fsroot diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index 993992e295fd..c64386d7622d 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -609,12 +609,12 @@ menuentry '$demo_grub_entry' { if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 - linux /$image_dir/boot/vmlinuz-4.19.0-6-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ + linux /$image_dir/boot/vmlinuz-4.19.0-9-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ net.ifnames=0 biosdevname=0 \ loop=$image_dir/$FILESYSTEM_SQUASHFS loopfstype=squashfs \ apparmor=1 security=apparmor varlog_size=$VAR_LOG_SIZE usbcore.autosuspend=-1 $ONIE_PLATFORM_EXTRA_CMDLINE_LINUX echo 'Loading $demo_volume_label $demo_type initial ramdisk ...' - initrd /$image_dir/boot/initrd.img-4.19.0-6-2-amd64 + initrd /$image_dir/boot/initrd.img-4.19.0-9-2-amd64 } EOF diff --git a/platform/barefoot/bfn-modules/debian/control b/platform/barefoot/bfn-modules/debian/control index da1f2c64a030..2c3d8368bc4b 100644 --- a/platform/barefoot/bfn-modules/debian/control +++ b/platform/barefoot/bfn-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: bfn-modules Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for bfn asic for mmap diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index f3daec7458ed..60b46a43ac6f 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-montara Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control index 9d8b6b5b2438..c6ad1386e72d 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-newport Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index 98395d3e84a0..f0ca639077ed 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control index d9059da93500..6f7bd62ffcc2 100644 --- a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: platform-modules-wnc-osw1800 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/saibcm-modules/debian/control b/platform/broadcom/saibcm-modules/debian/control index 2a6423cf15f0..d022eadb0501 100644 --- a/platform/broadcom/saibcm-modules/debian/control +++ b/platform/broadcom/saibcm-modules/debian/control @@ -10,5 +10,5 @@ Standards-Version: 3.9.3 Package: opennsl-modules Architecture: amd64 Section: main -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for broadcom SAI diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs index 64136958bbdf..27fae96d8a1a 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs @@ -1 +1 @@ -lib/modules/4.19.0-6-2-amd64/extra +lib/modules/4.19.0-9-2-amd64/extra diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index 5016ea0367ab..e536bae27494 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -1,6 +1,6 @@ -systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.19.0-6-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.19.0-6-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.19.0-6-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.19.0-6-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.19.0-6-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.19.0-9-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.19.0-9-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.19.0-9-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.19.0-9-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.19.0-9-2-amd64/extra systemd/opennsl-modules.service lib/systemd/system diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index b7e35f2aef08..5fee0cbf8f65 100755 --- a/platform/broadcom/saibcm-modules/debian/rules +++ b/platform/broadcom/saibcm-modules/debian/rules @@ -34,7 +34,7 @@ sname:=opennsl PACKAGE=opennsl-modules # modifieable for experiments or debugging m-a MA_DIR ?= /usr/share/modass -KVERSION ?= 4.19.0-6-2-amd64 +KVERSION ?= 4.19.0-9-2-amd64 # load generic variable handling -include $(MA_DIR)/include/generic.make # load default rules, including kdist, kdist_image, ... diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control index d26493bfaaae..6c7b1c41446f 100644 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: sonic-platform-alphanetworks-snh60a0-320fv2 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-alphanetworks-snh60b0-640f Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 0c3f18621c1f..1eedf83d07b0 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -7,21 +7,21 @@ Standards-Version: 3.9.3 Package: platform-modules-dx010 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-haliburton Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-seastone2 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as led, sfp Package: platform-modules-silverstone Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as led, sfp. diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index d59fd646e7d7..eca4085787e0 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -7,35 +7,35 @@ Standards-Version: 3.9.3 Package: platform-modules-s6000 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9100 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s6100 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9264f Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5232f Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5248f Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9332f Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index a7475cabd1b8..6105f280ad33 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-ag9032v1 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9064 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag5648 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-et-6248brb Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9032v2a Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as syseeprom, sfp Package: platform-modules-agc032 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index cf7c2ff9f2e1..9360f9226652 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-d7032q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7054q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6254qs Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6556 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6356 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7264q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/control b/platform/broadcom/sonic-platform-modules-mitac/debian/control index 4f3a3281f6ed..f1a62577f6e2 100644 --- a/platform/broadcom/sonic-platform-modules-mitac/debian/control +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-mitac-ly1200-32x Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/cavium/cavm_platform_modules/DEBIAN/control b/platform/cavium/cavm_platform_modules/DEBIAN/control index 483ad94a5553..938215c8f8ee 100755 --- a/platform/cavium/cavm_platform_modules/DEBIAN/control +++ b/platform/cavium/cavm_platform_modules/DEBIAN/control @@ -1,6 +1,6 @@ Package: cavm-platform-modules Version: 1.0 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Maintainer: Nadiya.Stetskovych@cavium.com Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-e582/debian/control b/platform/centec/sonic-platform-modules-e582/debian/control index aefb642a673f..5d6bcc7002e8 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/control +++ b/platform/centec/sonic-platform-modules-e582/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: platform-modules-e582-48x2q4z Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-e582-48x6q Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-embedway/debian/control b/platform/centec/sonic-platform-modules-embedway/debian/control index 78053927ea9a..781f4df43422 100644 --- a/platform/centec/sonic-platform-modules-embedway/debian/control +++ b/platform/centec/sonic-platform-modules-embedway/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: platform-modules-embedway-es6220 Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/innovium/sonic-platform-modules-cel/debian/control b/platform/innovium/sonic-platform-modules-cel/debian/control index 13681358e307..3b9152232d38 100755 --- a/platform/innovium/sonic-platform-modules-cel/debian/control +++ b/platform/innovium/sonic-platform-modules-cel/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: platform-modules-midstone-200i Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices diff --git a/platform/innovium/sonic-platform-modules-delta/debian/control b/platform/innovium/sonic-platform-modules-delta/debian/control index 44cb905419c4..ac94e19b4cf8 100644 --- a/platform/innovium/sonic-platform-modules-delta/debian/control +++ b/platform/innovium/sonic-platform-modules-delta/debian/control @@ -7,7 +7,7 @@ Standards-Version: 3.9.3 Package: platform-modules-et-c032if Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/nephos-modules/debian/control b/platform/nephos/nephos-modules/debian/control index f13c9ce5ceaa..78eb7af671fe 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: nephos-modules Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for nephos asic diff --git a/platform/nephos/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control index 27d678a4f82d..e2b67b03b9e4 100755 --- a/platform/nephos/sonic-platform-modules-accton/debian/control +++ b/platform/nephos/sonic-platform-modules-accton/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: sonic-platform-accton-as7116-54x Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-cig/debian/control b/platform/nephos/sonic-platform-modules-cig/debian/control index a8cbc4903166..870edcf1a234 100644 --- a/platform/nephos/sonic-platform-modules-cig/debian/control +++ b/platform/nephos/sonic-platform-modules-cig/debian/control @@ -7,15 +7,15 @@ Standards-Version: 3.9.3 Package: sonic-platform-cig-cs6436-56p Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-cig-cs6436-54p Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-cig-cs5435-54p Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/control b/platform/nephos/sonic-platform-modules-pegatron/debian/control index 694e2a16a537..fc3054a4c876 100755 --- a/platform/nephos/sonic-platform-modules-pegatron/debian/control +++ b/platform/nephos/sonic-platform-modules-pegatron/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-pegatron-porsche Architecture: amd64 -Depends: linux-image-4.19.0-6-2-amd64-unsigned +Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/rules/linux-kernel.mk b/rules/linux-kernel.mk index 359b24e31f88..600600cc96f6 100644 --- a/rules/linux-kernel.mk +++ b/rules/linux-kernel.mk @@ -1,9 +1,9 @@ # linux kernel package -KVERSION_SHORT = 4.19.0-6-2 +KVERSION_SHORT = 4.19.0-9-2 KVERSION = $(KVERSION_SHORT)-$(CONFIGURED_ARCH) -KERNEL_VERSION = 4.19.67 -KERNEL_SUBVERSION = 2+deb10u2 +KERNEL_VERSION = 4.19.118 +KERNEL_SUBVERSION = 2+deb10u1 ifeq ($(CONFIGURED_ARCH), armhf) # Override kernel version for ARMHF as it uses arm MP (multi-platform) for short version KVERSION = $(KVERSION_SHORT)-armmp diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index c60b1f49c26d..fdbb8851fee8 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit c60b1f49c26db1f0c511cd86ecdd52611164fc0a +Subproject commit fdbb8851fee82d04c4fed06e53d233a2d5b37933 From 7d003c3518be0791de5335d31ff721185d32b804 Mon Sep 17 00:00:00 2001 From: Venkatesan Mahalingam <34145258+venkatmahalingam@users.noreply.github.com> Date: Tue, 7 Jul 2020 12:56:57 -0700 Subject: [PATCH 0880/1427] [TACACS+]: Add support to specify source address for TACACS+ (#4610) This pull request was cherry picked from "#1238" to resolve the conflicts. - Why I did it Add support to specify source address for TACACS+ - How I did it Add patches for libpam-tacplus and libnss-tacplus. The patches parse the new option 'src_ip' and store the converted addrinfo. Then the addrinfo is used for TACACS+ connection. Add a attribute 'src_ip' for table "TACPLUS|global" in configDB Add some code to adapt to the attribute 'src_ip'. - How to verify it Config command for source address PR in sonic-utilities config tacacs src_ip - Description for the changelog Add patches to specify source address for the TACACS+ outgoing packets. - A picture of a cute animal (not mandatory but encouraged) **UT logs: ** UT_tacacs_source_intf.txt --- .../hostcfgd/common-auth-sonic.j2 | 6 +- files/image_config/hostcfgd/hostcfgd | 8 +- .../image_config/hostcfgd/tacplus_nss.conf.j2 | 7 + ...dd-support-for-TACACS-source-address.patch | 77 ++++++++++ src/tacacs/nss/Makefile | 1 + ...06-Add-support-for-source-ip-address.patch | 131 ++++++++++++++++++ src/tacacs/pam/Makefile | 1 + 7 files changed, 226 insertions(+), 5 deletions(-) create mode 100644 src/tacacs/nss/0007-Add-support-for-TACACS-source-address.patch create mode 100644 src/tacacs/pam/0006-Add-support-for-source-ip-address.patch diff --git a/files/image_config/hostcfgd/common-auth-sonic.j2 b/files/image_config/hostcfgd/common-auth-sonic.j2 index e609296d4e05..a9e95fda19fd 100644 --- a/files/image_config/hostcfgd/common-auth-sonic.j2 +++ b/files/image_config/hostcfgd/common-auth-sonic.j2 @@ -15,16 +15,16 @@ auth [success=1 default=ignore] pam_unix.so nullok try_first_pass {% elif auth['login'] == 'local,tacacs+' %} auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_unix.so nullok try_first_pass {% for server in servers | sub(0, -1) %} -auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_tacplus.so server={{ server.ip }}:{{ server.tcp_port }} secret={{ server.passkey }} login={{ server.auth_type }} timeout={{ server.timeout }} {% if server.vrf %} vrf={{ server.vrf }} {% endif %} try_first_pass +auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_tacplus.so server={{ server.ip }}:{{ server.tcp_port }} secret={{ server.passkey }} login={{ server.auth_type }} timeout={{ server.timeout }} {% if server.vrf %} vrf={{ server.vrf }} {% endif %} {{ 'source_ip=%s' % src_ip if src_ip }} try_first_pass {% endfor %} {% if servers | count %} {% set last_server = servers | last %} -auth [success=1 default=ignore] pam_tacplus.so server={{ last_server.ip }}:{{ last_server.tcp_port }} secret={{ last_server.passkey }} login={{ last_server.auth_type }} timeout={{ last_server.timeout }} {% if last_server.vrf %} vrf={{ last_server.vrf }} {% endif %} try_first_pass +auth [success=1 default=ignore] pam_tacplus.so server={{ last_server.ip }}:{{ last_server.tcp_port }} secret={{ last_server.passkey }} login={{ last_server.auth_type }} timeout={{ last_server.timeout }} {% if last_server.vrf %} vrf={{ last_server.vrf }} {% endif %} {{ 'source_ip=%s' % src_ip if src_ip }} try_first_pass {% endif %} {% elif auth['login'] == 'tacacs+' or auth['login'] == 'tacacs+,local' %} {% for server in servers %} -auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_tacplus.so server={{ server.ip }}:{{ server.tcp_port }} secret={{ server.passkey }} login={{ server.auth_type }} timeout={{ server.timeout }} {%if server.vrf %} vrf={{ server.vrf }} {% endif %} try_first_pass +auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_tacplus.so server={{ server.ip }}:{{ server.tcp_port }} secret={{ server.passkey }} login={{ server.auth_type }} timeout={{ server.timeout }} {%if server.vrf %} vrf={{ server.vrf }} {% endif %} {{ 'source_ip=%s' % src_ip if src_ip }} try_first_pass {% endfor %} auth [success=1 default=ignore] pam_unix.so nullok try_first_pass diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index b950345d3d9b..67d5126773f8 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -212,6 +212,10 @@ class AaaCfg(object): auth.update(self.auth) tacplus_global = self.tacplus_global_default.copy() tacplus_global.update(self.tacplus_global) + if 'src_ip' in tacplus_global: + src_ip = tacplus_global['src_ip'] + else: + src_ip = None servers_conf = [] if self.tacplus_servers: @@ -226,7 +230,7 @@ class AaaCfg(object): env = jinja2.Environment(loader=jinja2.FileSystemLoader('/'), trim_blocks=True) env.filters['sub'] = sub template = env.get_template(template_file) - pam_conf = template.render(auth=auth, servers=servers_conf) + pam_conf = template.render(auth=auth, src_ip=src_ip, servers=servers_conf) with open(PAM_AUTH_CONF, 'w') as f: f.write(pam_conf) @@ -249,7 +253,7 @@ class AaaCfg(object): # Set tacacs+ server in nss-tacplus conf template_file = os.path.abspath(NSS_TACPLUS_CONF_TEMPLATE) template = env.get_template(template_file) - nss_tacplus_conf = template.render(debug=self.debug, servers=servers_conf) + nss_tacplus_conf = template.render(debug=self.debug, src_ip=src_ip, servers=servers_conf) with open(NSS_TACPLUS_CONF, 'w') as f: f.write(nss_tacplus_conf) diff --git a/files/image_config/hostcfgd/tacplus_nss.conf.j2 b/files/image_config/hostcfgd/tacplus_nss.conf.j2 index 7f737888f59d..8fad3035d601 100644 --- a/files/image_config/hostcfgd/tacplus_nss.conf.j2 +++ b/files/image_config/hostcfgd/tacplus_nss.conf.j2 @@ -7,6 +7,13 @@ debug=on {% endif %} +# src_ip - set source address of TACACS+ protocol packets +# Default: None (auto source ip address) +# src_ip=2.2.2.2 +{% if src_ip %} +src_ip={{ src_ip }} +{% endif %} + # server - set ip address, tcp port, secret string and timeout for TACACS+ servers # Default: None (no TACACS+ server) # server=1.1.1.1:49,secret=test,timeout=3 diff --git a/src/tacacs/nss/0007-Add-support-for-TACACS-source-address.patch b/src/tacacs/nss/0007-Add-support-for-TACACS-source-address.patch new file mode 100644 index 000000000000..251ef172b23e --- /dev/null +++ b/src/tacacs/nss/0007-Add-support-for-TACACS-source-address.patch @@ -0,0 +1,77 @@ +From 61e951efe54085fe427a32d0e7db8ef08c02fa95 Mon Sep 17 00:00:00 2001 +From: Venkatesan Mahalingam +Date: Mon, 6 Jul 2020 12:14:26 -0700 +Subject: [PATCH] Add support for TACACS+ source address. + +Signed-off-by: Venkatesan Mahalingam +--- + nss_tacplus.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +diff --git a/nss_tacplus.c b/nss_tacplus.c +index 64a9328..bf6b934 100644 +--- a/nss_tacplus.c ++++ b/nss_tacplus.c +@@ -73,6 +73,7 @@ typedef struct { + static tacplus_server_t tac_srv[TAC_PLUS_MAXSERVERS]; + static int tac_srv_no; + static useradd_info_t useradd_grp_list[MAX_TACACS_USER_PRIV + 1]; ++static struct addrinfo *source_addr; + + static char *tac_service = "shell"; + static char *tac_protocol = "ssh"; +@@ -247,6 +248,10 @@ static int parse_config(const char *file) + return NSS_STATUS_UNAVAIL; + } + ++ if(source_addr) { ++ freeaddrinfo(source_addr); ++ source_addr = NULL; ++ } + debug = false; + tac_srv_no = 0; + while(fgets(buf, sizeof buf, fp)) { +@@ -262,6 +267,22 @@ static int parse_config(const char *file) + else if(!strncmp(buf, "user_priv=", 10)) { + parse_user_priv(buf); + } ++ else if(!strncmp(buf, "src_ip=", 7)) { ++ struct addrinfo hints; ++ char *ip = buf + 7, *new_line; ++ ++ // Remove the new line character as getaddrinfo is not working for IPv6 address with '\n'. ++ if ((new_line = strchr(buf, '\n')) != NULL) { ++ *new_line = '\0'; ++ } ++ memset(&hints, 0, sizeof hints); ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_STREAM; ++ ++ if(0 != getaddrinfo(ip, NULL, &hints, &source_addr)) ++ syslog(LOG_ERR, "%s: error setting the source ip information", ++ nssname); ++ } + else if(!strncmp(buf, "server=", 7)) { + if(TAC_PLUS_MAXSERVERS <= tac_srv_no) { + syslog(LOG_ERR, "%s: tac server num is more than %d", +@@ -282,6 +303,8 @@ static int parse_config(const char *file) + nssname, n, tac_ntop(tac_srv[n].addr->ai_addr), + tac_srv[n].key[0], tac_srv[n].timeout); + } ++ syslog(LOG_DEBUG, "%s: src_ip=%s", nssname, NULL == source_addr ++ ? "NULL" : tac_ntop(source_addr->ai_addr)); + syslog(LOG_DEBUG, "%s: many_to_one %s", nssname, 1 == many_to_one + ? "enable" : "disable"); + for(n = MIN_TACACS_USER_PRIV; n <= MAX_TACACS_USER_PRIV; n++) { +@@ -690,7 +713,7 @@ connect_tacacs(struct tac_attrib **attr, int srvr) + if(!*tac_service) /* reported at config file processing */ + return -1; + +- fd = tac_connect_single(tac_srv[srvr].addr, tac_srv[srvr].key, NULL, ++ fd = tac_connect_single(tac_srv[srvr].addr, tac_srv[srvr].key, source_addr, + tac_srv[srvr].timeout, vrfname[0] ? vrfname : NULL); + if(fd >= 0) { + *attr = NULL; /* so tac_add_attr() allocates memory */ +-- +2.7.4 + diff --git a/src/tacacs/nss/Makefile b/src/tacacs/nss/Makefile index cb9382d07a89..c133cafe9212 100644 --- a/src/tacacs/nss/Makefile +++ b/src/tacacs/nss/Makefile @@ -24,6 +24,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git $(GIT_APPLY) ../0004-Skip-accessing-tacacs-servers-for-local-non-tacacs-u.patch git $(GIT_APPLY) ../0005-libnss-Modify-parsing-of-IP-addr-and-port-number-str.patch git $(GIT_APPLY) ../0006-fix-compiling-warning-about-token-dereference.patch + git $(GIT_APPLY) ../0007-Add-support-for-TACACS-source-address.patch dpkg-buildpackage -rfakeroot -b -us -uc popd diff --git a/src/tacacs/pam/0006-Add-support-for-source-ip-address.patch b/src/tacacs/pam/0006-Add-support-for-source-ip-address.patch new file mode 100644 index 000000000000..280cfeee28fb --- /dev/null +++ b/src/tacacs/pam/0006-Add-support-for-source-ip-address.patch @@ -0,0 +1,131 @@ +From 9c26e734cf9e5cec950dc8b8f474f89d87833bcd Mon Sep 17 00:00:00 2001 +From: Venkatesan Mahalingam +Date: Wed, 1 Jul 2020 18:57:28 -0700 +Subject: [PATCH] Add support to specify source address for TACACS+ + +--- + pam_tacplus.c | 8 ++++---- + support.c | 31 +++++++++++++++++++++++++++++++ + support.h | 1 + + 3 files changed, 36 insertions(+), 4 deletions(-) + +diff --git a/pam_tacplus.c b/pam_tacplus.c +index 38e2a70..ec8ea27 100644 +--- a/pam_tacplus.c ++++ b/pam_tacplus.c +@@ -177,7 +177,7 @@ int _pam_account(pam_handle_t *pamh, int argc, const char **argv, + + status = PAM_SESSION_ERR; + for(srv_i = 0; srv_i < tac_srv_no; srv_i++) { +- tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout, __vrfname); ++ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, tac_source_addr, tac_timeout, __vrfname); + if (tac_fd < 0) { + _pam_log(LOG_WARNING, "%s: error sending %s (fd)", + __FUNCTION__, typemsg); +@@ -276,7 +276,7 @@ int pam_sm_authenticate (pam_handle_t * pamh, int flags, + if (ctrl & PAM_TAC_DEBUG) + syslog(LOG_DEBUG, "%s: trying srv %d", __FUNCTION__, srv_i ); + +- tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout, __vrfname); ++ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, tac_source_addr, tac_timeout, __vrfname); + if (tac_fd < 0) { + _pam_log(LOG_ERR, "%s: connection to srv %d failed", __FUNCTION__, srv_i); + continue; +@@ -579,7 +579,7 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags, + if(tac_protocol[0] != '\0') + tac_add_attrib(&attr, "protocol", tac_protocol); + +- tac_fd = tac_connect_single(active_server.addr, active_server.key, NULL, tac_timeout, __vrfname); ++ tac_fd = tac_connect_single(active_server.addr, active_server.key, tac_source_addr, tac_timeout, __vrfname); + if(tac_fd < 0) { + _pam_log (LOG_ERR, "TACACS+ server unavailable"); + if(arep.msg != NULL) +@@ -762,7 +762,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, + if (ctrl & PAM_TAC_DEBUG) + syslog(LOG_DEBUG, "%s: trying srv %d", __FUNCTION__, srv_i ); + +- tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout, __vrfname); ++ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, tac_source_addr, tac_timeout, __vrfname); + if (tac_fd < 0) { + _pam_log(LOG_ERR, "connection failed srv %d: %m", srv_i); + continue; +diff --git a/support.c b/support.c +index 7c00618..3e55e2f 100644 +--- a/support.c ++++ b/support.c +@@ -37,6 +37,8 @@ char tac_service[64]; + char tac_protocol[64]; + char tac_prompt[64]; + char *__vrfname=NULL; ++char tac_source_ip[64]; ++struct addrinfo *tac_source_addr = NULL; + + void _pam_log(int err, const char *format,...) { + char msg[256]; +@@ -183,6 +185,12 @@ int _pam_parse (int argc, const char **argv) { + tac_protocol[0] = 0; + tac_prompt[0] = 0; + tac_login[0] = 0; ++ tac_source_ip[0] = 0; ++ ++ if (tac_source_addr != NULL) { ++ freeaddrinfo(tac_source_addr); ++ tac_source_addr = NULL; ++ } + + for (ctrl = 0; argc-- > 0; ++argv) { + if (!strcmp (*argv, "debug")) { /* all */ +@@ -274,6 +282,10 @@ int _pam_parse (int argc, const char **argv) { + } + } else if(!strncmp(*argv, "vrf=", 4)) { + __vrfname = strdup(*argv + 4); ++ } else if (!strncmp (*argv, "source_ip=", strlen("source_ip="))) { ++ /* source ip for the packets */ ++ strncpy (tac_source_ip, *argv + strlen("source_ip="), sizeof(tac_source_ip)); ++ set_source_ip (tac_source_ip, &tac_source_addr); + } else { + _pam_log (LOG_WARNING, "unrecognized option: %s", *argv); + } +@@ -292,8 +304,27 @@ int _pam_parse (int argc, const char **argv) { + _pam_log(LOG_DEBUG, "tac_protocol='%s'", tac_protocol); + _pam_log(LOG_DEBUG, "tac_prompt='%s'", tac_prompt); + _pam_log(LOG_DEBUG, "tac_login='%s'", tac_login); ++ _pam_log(LOG_DEBUG, "tac_source_ip='%s'", tac_source_ip); + } + + return ctrl; + } /* _pam_parse */ + ++/* set source ip address for the outgoing tacacs packets */ ++void set_source_ip(const char *tac_source_ip, ++ struct addrinfo **source_address) { ++ ++ struct addrinfo hints; ++ int rv; ++ ++ /* set the source ip address for the tacacs packets */ ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_STREAM; ++ if ((rv = getaddrinfo(tac_source_ip, NULL, &hints, ++ source_address)) != 0) { ++ _pam_log(LOG_ERR, "error setting the source ip information"); ++ } else { ++ _pam_log(LOG_DEBUG, "source ip is set"); ++ } ++} +diff --git a/support.h b/support.h +index 9cbd040..09b8a85 100644 +--- a/support.h ++++ b/support.h +@@ -37,6 +37,7 @@ extern int tac_srv_no; + extern char tac_service[64]; + extern char tac_protocol[64]; + extern char tac_prompt[64]; ++extern struct addrinfo *tac_source_addr; + + int _pam_parse (int, const char **); + unsigned long _resolve_name (char *); +-- +2.7.4 + diff --git a/src/tacacs/pam/Makefile b/src/tacacs/pam/Makefile index 487cf975fd77..1f5213915641 100644 --- a/src/tacacs/pam/Makefile +++ b/src/tacacs/pam/Makefile @@ -19,6 +19,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git apply ../0003-Obfuscate-key-before-printing-to-syslog.patch git apply ../0004-management-vrf-support.patch git apply ../0005-pam-Modify-parsing-of-IP-address-and-port-number-to-.patch + git apply ../0006-Add-support-for-source-ip-address.patch dpkg-buildpackage -rfakeroot -b -us -uc popd From caa3323e9d354307b591daabaaf6142a2aeef028 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Tue, 7 Jul 2020 17:55:17 -0700 Subject: [PATCH 0881/1427] [sonic mgmt docker] lock pycryptodome version to 3.9.7 (#4913) Signed-off-by: Ying Xie --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 3c2bbff2504e..4749a2822292 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -49,7 +49,7 @@ RUN pip install cffi==1.10.0 \ prettytable \ psutil \ pyasn1==0.1.9 \ - pycryptodome \ + pycryptodome==3.9.7 \ pyfiglet \ pylint==1.8.1 \ pyro4 \ From 6f11833ffae645b5f6405805f9f1dabc883e9808 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Tue, 7 Jul 2020 23:22:03 -0700 Subject: [PATCH 0882/1427] Revert "[sonic mgmt docker] lock pycryptodome version to 3.9.7 (#4913)" (#4915) This reverts commit f427d2eecfd68b4b03815880cb189495b528c1ca. --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 4749a2822292..3c2bbff2504e 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -49,7 +49,7 @@ RUN pip install cffi==1.10.0 \ prettytable \ psutil \ pyasn1==0.1.9 \ - pycryptodome==3.9.7 \ + pycryptodome \ pyfiglet \ pylint==1.8.1 \ pyro4 \ From 7707185aafd6c920051377e4fc91213a084d646b Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 8 Jul 2020 06:48:08 -0700 Subject: [PATCH 0883/1427] [build]: Fix `make clean` for redis-tools (#4903) Fixed #4898 --- rules/redis.mk | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/rules/redis.mk b/rules/redis.mk index f4732d1ecbb5..53566b5cdf8b 100644 --- a/rules/redis.mk +++ b/rules/redis.mk @@ -1,30 +1,30 @@ # redis package - -REDIS_VERSION = 5.0.3-3~bpo9+2 - -REDIS_TOOLS = redis-tools_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb -$(REDIS_TOOLS)_SRC_PATH = $(SRC_PATH)/redis -$(REDIS_TOOLS)_DEPENDS += $(LIBHIREDIS_DEV) -$(REDIS_TOOLS)_RDEPENDS += $(LIBHIREDIS) # TODO: docker-sonic-p4 depends on redis-tools in Jessie. # Remove this file and src/redis after that resolved. ifneq ($(BLDENV),buster) -SONIC_MAKE_DEBS += $(REDIS_TOOLS) -endif -REDIS_TOOLS_DBG = redis-tools-dbgsym_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_TOOLS_DBG))) + REDIS_VERSION = 5.0.3-3~bpo9+2 -REDIS_SERVER = redis-server_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_SERVER))) + REDIS_TOOLS = redis-tools_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb + $(REDIS_TOOLS)_SRC_PATH = $(SRC_PATH)/redis + $(REDIS_TOOLS)_DEPENDS += $(LIBHIREDIS_DEV) + $(REDIS_TOOLS)_RDEPENDS += $(LIBHIREDIS) + SONIC_MAKE_DEBS += $(REDIS_TOOLS) -REDIS_SENTINEL = redis-sentinel_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb -$(REDIS_SENTINEL)_DEPENDS += $(REDIS_SERVER) -$(REDIS_SENTINEL)_RDEPENDS += $(REDIS_SERVER) -$(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_SENTINEL))) + REDIS_TOOLS_DBG = redis-tools-dbgsym_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb + $(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_TOOLS_DBG))) -# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} -# are archived into debug one image to facilitate debugging. -# -DBG_SRC_ARCHIVE += redis + REDIS_SERVER = redis-server_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb + $(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_SERVER))) + REDIS_SENTINEL = redis-sentinel_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb + $(REDIS_SENTINEL)_DEPENDS += $(REDIS_SERVER) + $(REDIS_SENTINEL)_RDEPENDS += $(REDIS_SERVER) + $(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_SENTINEL))) + + # The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} + # are archived into debug one image to facilitate debugging. + # + DBG_SRC_ARCHIVE += redis + +endif From e666bf84904896d2817f0b8d7a81362d4d7690eb Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Wed, 8 Jul 2020 16:52:14 +0300 Subject: [PATCH 0884/1427] [Mellanox] Add a new SKU Mellanox-SN4600C-D112C8 (#4833) Add related files to the device folder: buffer config templates pg lookup profile port_config.ini sai profile sensor conf plugins Co-authored-by: Stephen Sun --- .../Mellanox-SN4600C-D112C8/buffers.json.j2 | 1 + .../buffers_defaults_t0.j2 | 98 ++++ .../buffers_defaults_t1.j2 | 98 ++++ .../pg_profile_lookup.ini | 1 + .../Mellanox-SN4600C-D112C8/port_config.ini | 105 ++++ .../Mellanox-SN4600C-D112C8/qos.json.j2 | 1 + .../Mellanox-SN4600C-D112C8/sai.profile | 1 + .../sai_4600c_112x50g_8x100g.xml | 510 ++++++++++++++++++ 8 files changed, 815 insertions(+) create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t0.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t1.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/port_config.ini create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/qos.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai.profile create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai_4600c_112x50g_8x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers.json.j2 new file mode 120000 index 000000000000..117d740b0f5b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers.json.j2 @@ -0,0 +1 @@ +../ACS-MSN4600C/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..ab9cdd8c00c3 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t0.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '57499648' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '57499648' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..d47117501be1 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t1.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '52363264' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '52363264' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/pg_profile_lookup.ini new file mode 120000 index 000000000000..dc307e1020f5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/pg_profile_lookup.ini @@ -0,0 +1 @@ +../ACS-MSN4600C/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/port_config.ini new file mode 100644 index 000000000000..eb4cdc35637b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/port_config.ini @@ -0,0 +1,105 @@ +# name lanes alias index speed fec +Ethernet0 0,1 etp1a 1 50000 none +Ethernet2 2,3 etp1b 1 50000 none +Ethernet8 8,9 etp2a 2 50000 none +Ethernet10 10,11 etp2b 2 50000 none +Ethernet16 16,17 etp3a 3 50000 none +Ethernet18 18,19 etp3b 3 50000 none +Ethernet24 24,25,26,27 etp4 4 100000 rs +Ethernet32 32,33 etp5a 5 50000 none +Ethernet34 34,35 etp5b 5 50000 none +Ethernet40 40,41 etp6a 6 50000 none +Ethernet42 42,43 etp6b 6 50000 none +Ethernet48 48,49 etp7a 7 50000 none +Ethernet50 50,51 etp7b 7 50000 none +Ethernet56 56,57,58,59 etp8 8 100000 rs +Ethernet64 64,65 etp9a 9 50000 none +Ethernet66 66,67 etp9b 9 50000 none +Ethernet72 72,73 etp10a 10 50000 none +Ethernet74 74,75 etp10b 10 50000 none +Ethernet80 80,81 etp11a 11 50000 none +Ethernet82 82,83 etp11b 11 50000 none +Ethernet88 88,89,90,91 etp12 12 100000 rs +Ethernet96 96,97 etp13a 13 50000 none +Ethernet98 98,99 etp13b 13 50000 none +Ethernet104 104,105 etp14a 14 50000 none +Ethernet106 106,107 etp14b 14 50000 none +Ethernet112 112,113 etp15a 15 50000 none +Ethernet114 114,115 etp15b 15 50000 none +Ethernet120 120,121,122,123 etp16 16 100000 rs +Ethernet128 128,129 etp17a 17 50000 none +Ethernet130 130,131 etp17b 17 50000 none +Ethernet136 136,137 etp18a 18 50000 none +Ethernet138 138,139 etp18b 18 50000 none +Ethernet144 144,145 etp19a 19 50000 none +Ethernet146 146,147 etp19b 19 50000 none +Ethernet152 152,153,154,155 etp20 20 100000 rs +Ethernet160 160,161 etp21a 21 50000 none +Ethernet162 162,163 etp21b 21 50000 none +Ethernet168 168,169 etp22a 22 50000 none +Ethernet170 170,171 etp22b 22 50000 none +Ethernet176 176,177 etp23a 23 50000 none +Ethernet178 178,179 etp23b 23 50000 none +Ethernet184 184,185,186,187 etp24 24 100000 rs +Ethernet192 192,193,194,195 etp25 25 100000 rs +Ethernet200 200,201,202,203 etp26 26 100000 rs +Ethernet208 208,209 etp27a 27 50000 none +Ethernet210 210,211 etp27b 27 50000 none +Ethernet216 216,217,218,219 etp28 28 100000 rs +Ethernet224 224,225,226,227 etp29 29 100000 rs +Ethernet232 232,233,234,235 etp30 30 100000 rs +Ethernet240 240,241 etp31a 31 50000 none +Ethernet242 242,243 etp31b 31 50000 none +Ethernet248 248,249,250,251 etp32 32 100000 rs +Ethernet256 256,257,258,259 etp33 33 100000 rs +Ethernet264 264,265,266,267 etp34 34 100000 rs +Ethernet272 272,273 etp35a 35 50000 none +Ethernet274 274,275 etp35b 35 50000 none +Ethernet280 280,281,282,283 etp36 36 100000 rs +Ethernet288 288,289,290,291 etp37 37 100000 rs +Ethernet296 296,297,298,299 etp38 38 100000 rs +Ethernet304 304,305 etp39a 39 50000 none +Ethernet306 306,307 etp39b 39 50000 none +Ethernet312 312,313,314,315 etp40 40 100000 rs +Ethernet320 320,321 etp41a 41 50000 none +Ethernet322 322,323 etp41b 41 50000 none +Ethernet328 328,329 etp42a 42 50000 none +Ethernet330 330,331 etp42b 42 50000 none +Ethernet336 336,337 etp43a 43 50000 none +Ethernet338 338,339 etp43b 43 50000 none +Ethernet344 344,345,346,347 etp44 44 100000 rs +Ethernet352 352,353 etp45a 45 50000 none +Ethernet354 354,355 etp45b 45 50000 none +Ethernet360 360,361 etp46a 46 50000 none +Ethernet362 362,363 etp46b 46 50000 none +Ethernet368 368,369 etp47a 47 50000 none +Ethernet370 370,371 etp47b 47 50000 none +Ethernet376 376,377,378,379 etp48 48 100000 rs +Ethernet384 384,385 etp49a 49 50000 none +Ethernet386 386,387 etp49b 49 50000 none +Ethernet392 392,393 etp50a 50 50000 none +Ethernet394 394,395 etp50b 50 50000 none +Ethernet400 400,401 etp51a 51 50000 none +Ethernet402 402,403 etp51b 51 50000 none +Ethernet408 408,409,410,411 etp52 52 100000 rs +Ethernet416 416,417 etp53a 53 50000 none +Ethernet418 418,419 etp53b 53 50000 none +Ethernet424 424,425 etp54a 54 50000 none +Ethernet426 426,427 etp54b 54 50000 none +Ethernet432 432,433 etp55a 55 50000 none +Ethernet434 434,435 etp55b 55 50000 none +Ethernet440 440,441,442,443 etp56 56 100000 rs +Ethernet448 448,449 etp57a 57 50000 none +Ethernet450 450,451 etp57b 57 50000 none +Ethernet456 456,457 etp58a 58 50000 none +Ethernet458 458,459 etp58b 58 50000 none +Ethernet464 464,465 etp59a 59 50000 none +Ethernet466 466,467 etp59b 59 50000 none +Ethernet472 472,473,474,475 etp60 60 100000 rs +Ethernet480 480,481 etp61a 61 50000 none +Ethernet482 482,483 etp61b 61 50000 none +Ethernet488 488,489 etp62a 62 50000 none +Ethernet490 490,491 etp62b 62 50000 none +Ethernet496 496,497 etp63a 63 50000 none +Ethernet498 498,499 etp63b 63 50000 none +Ethernet504 504,505,506,507 etp64 64 100000 rs diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/qos.json.j2 new file mode 120000 index 000000000000..05394016a129 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/qos.json.j2 @@ -0,0 +1 @@ +../ACS-MSN4600C/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai.profile b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai.profile new file mode 100644 index 000000000000..15fccb416efd --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4600c_112x50g_8x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai_4600c_112x50g_8x100g.xml b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai_4600c_112x50g_8x100g.xml new file mode 100644 index 000000000000..199c251fbee2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai_4600c_112x50g_8x100g.xml @@ -0,0 +1,510 @@ + + + + + + 00:02:03:04:05:80 + + + 1 + + + 64 + + + + + 105 + 2 + 4 + 0 + + + 3 + + + 384 + + + 107 + 2 + 4 + 1 + 3 + 384 + + + 109 + 2 + 4 + 2 + 3 + 384 + + + 111 + 4 + 3 + 3 + 1536 + + + 97 + 2 + 4 + 4 + 3 + 384 + + + 99 + 2 + 4 + 5 + 3 + 384 + + + 101 + 2 + 4 + 6 + 3 + 384 + + + 103 + 4 + 7 + 3 + 1536 + + + 121 + 2 + 4 + 8 + 3 + 384 + + + 123 + 2 + 4 + 9 + 3 + 384 + + + 125 + 2 + 4 + 10 + 3 + 384 + + + 127 + 4 + 11 + 3 + 1536 + + + 113 + 2 + 4 + 12 + 3 + 384 + + + 115 + 2 + 4 + 13 + 3 + 384 + + + 117 + 2 + 4 + 14 + 3 + 384 + + + 119 + 4 + 15 + 3 + 1536 + + + 89 + 2 + 4 + 16 + 3 + 384 + + + 91 + 2 + 4 + 17 + 3 + 384 + + + 93 + 2 + 4 + 18 + 3 + 384 + + + 95 + 4 + 19 + 3 + 1536 + + + 81 + 2 + 4 + 20 + 3 + 384 + + + 83 + 2 + 4 + 21 + 3 + 384 + + + 85 + 2 + 4 + 22 + 3 + 384 + + + 87 + 4 + 23 + 3 + 1536 + + + 73 + 4 + 24 + 3 + 1536 + + + 75 + 4 + 25 + 3 + 1536 + + + 77 + 2 + 4 + 26 + 3 + 384 + + + 79 + 4 + 27 + 3 + 1536 + + + 65 + 4 + 28 + 3 + 1536 + + + 67 + 4 + 29 + 3 + 1536 + + + 69 + 2 + 4 + 30 + 3 + 384 + + + 71 + 4 + 31 + 3 + 1536 + + + 5 + 4 + 32 + 3 + 1536 + + + 7 + 4 + 33 + 3 + 1536 + + + 1 + 2 + 4 + 34 + 3 + 384 + + + 3 + 4 + 35 + 3 + 1536 + + + 13 + 4 + 36 + 3 + 1536 + + + 15 + 4 + 37 + 3 + 1536 + + + 9 + 2 + 4 + 38 + 3 + 384 + + + 11 + 4 + 39 + 3 + 1536 + + + 21 + 2 + 4 + 40 + 3 + 384 + + + 23 + 2 + 4 + 41 + 3 + 384 + + + 17 + 2 + 4 + 42 + 3 + 384 + + + 19 + 4 + 43 + 3 + 1536 + + + 29 + 2 + 4 + 44 + 3 + 384 + + + 31 + 2 + 4 + 45 + 3 + 384 + + + 25 + 2 + 4 + 46 + 3 + 384 + + + 27 + 4 + 47 + 3 + 1536 + + + 53 + 2 + 4 + 48 + 3 + 384 + + + 55 + 2 + 4 + 49 + 3 + 384 + + + 49 + 2 + 4 + 50 + 3 + 384 + + + 51 + 4 + 51 + 3 + 1536 + + + 61 + 2 + 4 + 52 + 3 + 384 + + + 63 + 2 + 4 + 53 + 3 + 384 + + + 57 + 2 + 4 + 54 + 3 + 384 + + + 59 + 4 + 55 + 3 + 1536 + + + 37 + 2 + 4 + 56 + 3 + 384 + + + 39 + 2 + 4 + 57 + 3 + 384 + + + 33 + 2 + 4 + 58 + 3 + 384 + + + 35 + 4 + 59 + 3 + 1536 + + + 45 + 2 + 4 + 60 + 3 + 384 + + + 47 + 2 + 4 + 61 + 3 + 384 + + + 41 + 2 + 4 + 62 + 3 + 384 + + + 43 + 4 + 63 + 3 + 1536 + + + + From 153f880e6bf04113bfdcb1ae1395d1ae337d2a65 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 8 Jul 2020 21:53:54 +0800 Subject: [PATCH 0885/1427] [mellanox]: Support warm reboot on MSN4700 (#4910) --- .../mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml index 177a79d13d6f..e3d0e4ea723d 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 32 From f4eae5dabd258f58019bf36e74bd998ef77e46e1 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Wed, 8 Jul 2020 10:27:05 -0700 Subject: [PATCH 0886/1427] [telemetry] Call sonic-cfggen Once (#4901) sonic-cfggen call is slow and this is taking place in the SONiC boot up process. The change uses templates to assemble all required vars into single template file. With this change, telemetry now calls once into sonic-cfggen. signed-off-by: Tamer Ahmed --- dockers/docker-base-buster/Dockerfile.j2 | 4 ++- dockers/docker-base-stretch/Dockerfile.j2 | 4 ++- dockers/docker-sonic-telemetry/Dockerfile.j2 | 2 +- dockers/docker-sonic-telemetry/telemetry.sh | 35 ++++++++++--------- .../docker-sonic-telemetry/telemetry_vars.j2 | 5 +++ 5 files changed, 31 insertions(+), 19 deletions(-) create mode 100644 dockers/docker-sonic-telemetry/telemetry_vars.j2 diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index 1959bb56cb7b..2d7bd887d2e8 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -64,7 +64,9 @@ RUN apt-get update && \ net-tools \ # for arm arch: Installing j2cli dependency package MarkupSafe from source relies on weeksetuptools and wheel python-setuptools \ - python-wheel + python-wheel \ +# for processing/handling json files in bash environment + jq # For templating RUN pip install j2cli diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index f573e94b78d7..f563aee8d9ea 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -62,7 +62,9 @@ RUN apt-get update && \ net-tools \ # for arm arch: Installing j2cli dependency package MarkupSafe from source relies on weeksetuptools and wheel python-setuptools \ - python-wheel + python-wheel \ +# for processing json files in bash environment + jq # For templating RUN pip install j2cli diff --git a/dockers/docker-sonic-telemetry/Dockerfile.j2 b/dockers/docker-sonic-telemetry/Dockerfile.j2 index d3b95c3b4002..b878266f1c6c 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/Dockerfile.j2 @@ -22,7 +22,7 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs -COPY ["start.sh", "telemetry.sh", "dialout.sh", "/usr/bin/"] +COPY ["start.sh", "telemetry.sh", "dialout.sh", "telemetry_vars.j2", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index b8f7fffb3ebb..18356e0945e2 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -2,36 +2,38 @@ # Try to read telemetry and certs config from ConfigDB. # Use default value if no valid config exists -X509=`sonic-cfggen -d -v "DEVICE_METADATA['x509']"` -gnmi=`sonic-cfggen -d -v "TELEMETRY['gnmi']"` -certs=`sonic-cfggen -d -v "TELEMETRY['certs']"` +TELEMETRY_VARS=$(sonic-cfggen -d -t telemetry_vars.j2) +TELEMETRY_VARS=${TELEMETRY_VARS//[\']/\"} +X509=$(echo $TELEMETRY_VARS | jq -r '.x509') +GNMI=$(echo $TELEMETRY_VARS | jq -r '.gnmi') +CERTS=$(echo $TELEMETRY_VARS | jq -r '.certs') TELEMETRY_ARGS=" -logtostderr" export CVL_SCHEMA_PATH=/usr/sbin/schema -if [ -n "$certs" ]; then - SERVER_CRT=`sonic-cfggen -d -v "TELEMETRY['certs']['server_crt']"` - SERVER_KEY=`sonic-cfggen -d -v "TELEMETRY['certs']['server_key']"` +if [ -n "$CERTS" ]; then + SERVER_CRT=$(echo $CERTS | jq -r '.server_crt') + SERVER_KEY=$(echo $CERTS | jq -r '.server_key') if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then TELEMETRY_ARGS+=" --insecure" else TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " fi - CA_CRT=`sonic-cfggen -d -v "TELEMETRY['certs']['ca_crt']"` + CA_CRT=$(echo $CERTS | jq -r '.ca_crt') if [ ! -z $CA_CRT ]; then TELEMETRY_ARGS+=" --ca_crt $CA_CRT" fi elif [ -n "$X509" ]; then - SERVER_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']"` - SERVER_KEY=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']"` + SERVER_CRT=$(echo $X509 | jq -r '.server_crt') + SERVER_KEY=$(echo $X509 | jq -r '.server_key') if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then TELEMETRY_ARGS+=" --insecure" else TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " fi - CA_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']"` + CA_CRT=$(echo $X509 | jq -r '.ca_crt') if [ ! -z $CA_CRT ]; then TELEMETRY_ARGS+=" --ca_crt $CA_CRT" fi @@ -40,19 +42,20 @@ else fi # If no configuration entry exists for TELEMETRY, create one default port -if [ -z "$gnmi" ]; then - sonic-db-cli CONFIG_DB hset "TELEMETRY|gnmi" port 8080 +if [ -z "$GNMI" ]; then + PORT=8080 + sonic-db-cli CONFIG_DB hset "TELEMETRY|gnmi" port $PORT +else + PORT=$(echo $GNMI | jq -r '.port') fi - -PORT=`sonic-cfggen -d -v "TELEMETRY['gnmi']['port']"` TELEMETRY_ARGS+=" --port $PORT" -CLIENT_AUTH=`sonic-cfggen -d -v "TELEMETRY['gnmi']['client_auth']"` +CLIENT_AUTH=$(echo $GNMI | jq -r '.client_auth') if [ -z $CLIENT_AUTH ] || [ $CLIENT_AUTH == "false" ]; then TELEMETRY_ARGS+=" --allow_no_client_auth" fi -LOG_LEVEL=`sonic-cfggen -d -v "TELEMETRY['gnmi']['log_level']"` +LOG_LEVEL=$(echo $GNMI | jq -r '.log_level') if [ ! -z $LOG_LEVEL ]; then TELEMETRY_ARGS+=" -v=$LOG_LEVEL" else diff --git a/dockers/docker-sonic-telemetry/telemetry_vars.j2 b/dockers/docker-sonic-telemetry/telemetry_vars.j2 new file mode 100644 index 000000000000..687781e1b9b2 --- /dev/null +++ b/dockers/docker-sonic-telemetry/telemetry_vars.j2 @@ -0,0 +1,5 @@ +{ + "certs": "{% if "certs" in TELEMETRY.keys() %}{{ TELEMETRY["certs"] }}{% endif %}", + "gnmi" : "{% if "gnmi" in TELEMETRY.keys() %}{{ TELEMETRY["gnmi"] }}{% endif %}", + "x509" : "{% if "x509" in DEVICE_METADATA.keys() %}{{ DEVICE_METADATA["x509"] }}{% endif %}" +} From 7a6fca2f981610e09919ee71f775863b99055909 Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Wed, 8 Jul 2020 11:30:01 -0700 Subject: [PATCH 0887/1427] [docker-sflow]: upgrade docker-sflow on buster (#4904) --- dockers/docker-sflow/Dockerfile.j2 | 2 +- rules/docker-sflow.mk | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dockers/docker-sflow/Dockerfile.j2 b/dockers/docker-sflow/Dockerfile.j2 index 03e209621dd9..94f4d73c968c 100644 --- a/dockers/docker-sflow/Dockerfile.j2 +++ b/dockers/docker-sflow/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk index 04700349fbae..db16aad8b20a 100644 --- a/rules/docker-sflow.mk +++ b/rules/docker-sflow.mk @@ -7,22 +7,20 @@ DOCKER_SFLOW_DBG = $(DOCKER_SFLOW_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_SFLOW)_PATH = $(DOCKERS_PATH)/$(DOCKER_SFLOW_STEM) $(DOCKER_SFLOW)_DEPENDS += $(SWSS) $(HSFLOWD) $(SFLOWTOOL) $(PSAMPLE) -$(DOCKER_SFLOW)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_SFLOW)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_TEAMD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) -$(DOCKER_SFLOW)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_SFLOW)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_SFLOW)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_SFLOW)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_SFLOW) ifeq ($(ENABLE_SFLOW), y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SFLOW) -SONIC_STRETCH_DOCKERS += $(DOCKER_SFLOW) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_SFLOW_DBG) ifeq ($(ENABLE_SFLOW), y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SFLOW_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SFLOW_DBG) endif $(DOCKER_SFLOW)_CONTAINER_NAME = sflow From 525029e3d85fb3e69fb5ea2bf1acd0e37ae5f590 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni <47657796+AkhileshSamineni@users.noreply.github.com> Date: Thu, 9 Jul 2020 02:58:43 +0530 Subject: [PATCH 0888/1427] [NAT]: Update the conntrack entries timeout to Max value after warmboot (#4596) Signed-off-by: Akhilesh Samineni All new NAT conntrack entries are added to kernel with max entry timeout of 432000 and setting the same timeout during system warm reboot also --- dockers/docker-nat/restore_nat_entries.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-nat/restore_nat_entries.py b/dockers/docker-nat/restore_nat_entries.py index d07facab290b..fc446f3655a6 100755 --- a/dockers/docker-nat/restore_nat_entries.py +++ b/dockers/docker-nat/restore_nat_entries.py @@ -36,7 +36,7 @@ def add_nat_conntrack_entry_in_kernel(ipproto, srcip, dstip, srcport, dstport, n if (ipproto == IP_PROTO_TCP): state = ' --state ESTABLISHED ' ctcmd = 'conntrack -I -n ' + natdstip + ':' + natdstport + ' -g ' + natsrcip + ':' + natsrcport + \ - ' --protonum ' + ipproto + state + ' --timeout 600 --src ' + srcip + ' --sport ' + srcport + \ + ' --protonum ' + ipproto + state + ' --timeout 432000 --src ' + srcip + ' --sport ' + srcport + \ ' --dst ' + dstip + ' --dport ' + dstport + ' -u ASSURED' subprocess.call(ctcmd, shell=True) logger.info("Restored NAT entry: {}".format(ctcmd)) From d499a266c02688239e312fbbdcd7ca69ed371452 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Wed, 8 Jul 2020 16:39:42 -0700 Subject: [PATCH 0889/1427] [mgmt docker] move pycryptodome installation to the end of the docker building (#4917) * [mgmt docker] move pycryptodome installation to the end of the docker building Signed-off-by: Ying Xie * pin down the version to current: 3.9.8 * comment --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 3c2bbff2504e..67142242293c 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -49,7 +49,6 @@ RUN pip install cffi==1.10.0 \ prettytable \ psutil \ pyasn1==0.1.9 \ - pycryptodome \ pyfiglet \ pylint==1.8.1 \ pyro4 \ @@ -169,3 +168,7 @@ RUN ~/lib/azure-cli/bin/python -m pip install azure-keyvault==0.3.7 -U # Install Virtual Environment RUN python -m virtualenv --system-site-packages env-201811 RUN env-201811/bin/pip install ansible==2.0.0.2 + +# NOTE: There is an ordering dependency for pycryptodome. Leaving this at +# the end until we figure that out. +RUN pip install pycryptodome==3.9.8 From c213bcf23a2f6ce9d3d39918e9b731089b15d255 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Thu, 9 Jul 2020 01:22:26 -0700 Subject: [PATCH 0890/1427] [arista]: Update arista driver submodules (#4922) - Add more reboot cause reporting - Fix backward compatibility issue with older reboot cause format - Miscellaneous improvements --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 9ea7795ac085..5c0bf0fad3f2 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 9ea7795ac085452bd14e4146a446ef842152e7de +Subproject commit 5c0bf0fad3f2e2ac9fa9034c99f216cd7604ccf8 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 9ea7795ac085..5c0bf0fad3f2 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 9ea7795ac085452bd14e4146a446ef842152e7de +Subproject commit 5c0bf0fad3f2e2ac9fa9034c99f216cd7604ccf8 From a46f4c96e7b4fc9a99c26d098de83bc0c1dca7df Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Thu, 9 Jul 2020 11:02:53 -0700 Subject: [PATCH 0891/1427] Add support for bcmsh and bcmcmd utlitites in multi ASIC devices (#4926) Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan This PR has changes to support accessing the bcmsh and bcmcmd utilities on multi ASIC devices Changes done - move the link of /var/run/sswsyncd from docker-syncd-brcm.mk to docker_image_ctl.j2 - update the bcmsh and bcmcmd scripts to take -n [ASIC_ID] as an argument on multi ASIC platforms --- files/build_templates/docker_image_ctl.j2 | 5 +++ platform/broadcom/docker-syncd-brcm.mk | 2 +- .../base_image_files/bcm_common | 40 +++++++++++++++++++ .../docker-syncd-brcm/base_image_files/bcmcmd | 7 +++- .../docker-syncd-brcm/base_image_files/bcmsh | 7 +++- 5 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 platform/broadcom/docker-syncd-brcm/base_image_files/bcm_common diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 2ddc18a8ce9b..4f265a5ceb92 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -299,6 +299,11 @@ start() { --tmpfs /tmp \ {%- endif %} {%- endif %} +{%- if sonic_asic_platform == "broadcom" %} +{%- if docker_container_name == "syncd" %} + -v /var/run/docker-syncd$DEV:/var/run/sswsyncd \ +{%- endif %} +{%- endif %} {%- if docker_container_name == "bgp" %} -v /etc/sonic/frr/$DEV:/etc/frr:rw \ {%- endif %} diff --git a/platform/broadcom/docker-syncd-brcm.mk b/platform/broadcom/docker-syncd-brcm.mk index 71a834ab67df..b1b412fc9edd 100644 --- a/platform/broadcom/docker-syncd-brcm.mk +++ b/platform/broadcom/docker-syncd-brcm.mk @@ -15,8 +15,8 @@ SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot -$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmcmd:/usr/bin/bcmcmd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcm_common:/usr/bin/bcm_common $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/bcm_common b/platform/broadcom/docker-syncd-brcm/base_image_files/bcm_common new file mode 100644 index 000000000000..1b560a1a1522 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/bcm_common @@ -0,0 +1,40 @@ +#!/bin/bash + +function help() +{ + echo "Usage: $0 -n [0 to $(($NUM_ASIC-1))]" 1>&2; exit 1; + +} + + +DEV="" + +PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + +# Parse the device specific asic conf file, if it exists + +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +if [ -f "$ASIC_CONF" ]; then + source $ASIC_CONF +fi + + +if [[ ($NUM_ASIC -gt 1) ]]; then + OPTIND=1 + + while getopts ":n:h:" opt; do + case "${opt}" in + h) help + exit 0 + ;; + n) DEV=${OPTARG} + [ $DEV -lt $NUM_ASIC -a $DEV -ge 0 ] || help + ;; + esac + done + shift "$((OPTIND-1))" + + if [ -z "${DEV}" ]; then + help + fi +fi diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/bcmcmd b/platform/broadcom/docker-syncd-brcm/base_image_files/bcmcmd index 7903db6ed6a3..76362fc64804 100755 --- a/platform/broadcom/docker-syncd-brcm/base_image_files/bcmcmd +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/bcmcmd @@ -1,3 +1,8 @@ #!/bin/bash -docker exec -i syncd bcmcmd "$@" +BCM_COMMON=/usr/bin/bcm_common +if [ -f "$BCM_COMMON" ]; then + source $BCM_COMMON +fi +docker exec -i syncd$DEV bcmcmd "$@" + diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/bcmsh b/platform/broadcom/docker-syncd-brcm/base_image_files/bcmsh index 3bb78b0da796..3cb2aad7afb6 100755 --- a/platform/broadcom/docker-syncd-brcm/base_image_files/bcmsh +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/bcmsh @@ -1,3 +1,8 @@ #!/bin/bash -docker exec -it syncd bcmsh "$@" +BCM_COMMON=/usr/bin/bcm_common +if [ -f "$BCM_COMMON" ]; then + source $BCM_COMMON +fi + +docker exec -it syncd$DEV bcmsh "$@" From 2731571dc9b60b3360d3bafa471132f97269f0b4 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 9 Jul 2020 11:44:13 -0700 Subject: [PATCH 0892/1427] [caclmgrd] Improve code reuse (#4931) Improve code reuse in `generate_block_ip2me_traffic_iptables_commands()` function. --- files/image_config/caclmgrd/caclmgrd | 108 +++++++-------------------- 1 file changed, 28 insertions(+), 80 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 37a86418967e..b6d5cbe71398 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -134,89 +134,37 @@ class ControlPlaneAclManager(object): return tcp_flags_str def generate_block_ip2me_traffic_iptables_commands(self): - LOOPBACK_INTERFACE_TABLE_NAME = "LOOPBACK_INTERFACE" - MGMT_INTERFACE_TABLE_NAME = "MGMT_INTERFACE" - VLAN_INTERFACE_TABLE_NAME = "VLAN_INTERFACE" - PORTCHANNEL_INTERFACE_TABLE_NAME = "PORTCHANNEL_INTERFACE" - INTERFACE_TABLE_NAME = "INTERFACE" + INTERFACE_TABLE_NAME_LIST = [ + "LOOPBACK_INTERFACE", + "MGMT_INTERFACE", + "VLAN_INTERFACE", + "PORTCHANNEL_INTERFACE", + "INTERFACE" + ] block_ip2me_cmds = [] - # Add iptables rules to drop all packets destined for loopback interface IP addresses - loopback_iface_table = self.config_db.get_table(LOOPBACK_INTERFACE_TABLE_NAME) - if loopback_iface_table: - for key, _ in loopback_iface_table.iteritems(): - if not _ip_prefix_in_key(key): - continue - iface_name, iface_cidr = key - ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) - if isinstance(ip_ntwrk, ipaddress.IPv4Network): - block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) - elif isinstance(ip_ntwrk, ipaddress.IPv6Network): - block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) - else: - log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) - - # Add iptables rules to drop all packets destined for management interface IP addresses - mgmt_iface_table = self.config_db.get_table(MGMT_INTERFACE_TABLE_NAME) - if mgmt_iface_table: - for key, _ in mgmt_iface_table.iteritems(): - if not _ip_prefix_in_key(key): - continue - iface_name, iface_cidr = key - ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) - if isinstance(ip_ntwrk, ipaddress.IPv4Network): - block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) - elif isinstance(ip_ntwrk, ipaddress.IPv6Network): - block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) - else: - log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) - - # Add iptables rules to drop all packets destined for our VLAN interface gateway IP addresses - vlan_iface_table = self.config_db.get_table(VLAN_INTERFACE_TABLE_NAME) - if vlan_iface_table: - for key, _ in vlan_iface_table.iteritems(): - if not _ip_prefix_in_key(key): - continue - iface_name, iface_cidr = key - ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) - first_host = next(ip_ntwrk.hosts()) - if isinstance(ip_ntwrk, ipaddress.IPv4Network): - block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(first_host, ip_ntwrk.max_prefixlen)) - elif isinstance(ip_ntwrk, ipaddress.IPv6Network): - block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(first_host, ip_ntwrk.max_prefixlen)) - else: - log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) - - # Add iptables rules to drop all packets destined for point-to-point interface IP addresses - # (All portchannel interfaces and configured front-panel interfaces) - portchannel_iface_table = self.config_db.get_table(PORTCHANNEL_INTERFACE_TABLE_NAME) - if portchannel_iface_table: - for key, _ in portchannel_iface_table.iteritems(): - if not _ip_prefix_in_key(key): - continue - iface_name, iface_cidr = key - ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) - if isinstance(ip_ntwrk, ipaddress.IPv4Network): - block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) - elif isinstance(ip_ntwrk, ipaddress.IPv6Network): - block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) - else: - log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) - - iface_table = self.config_db.get_table(INTERFACE_TABLE_NAME) - if iface_table: - for key, _ in iface_table.iteritems(): - if not _ip_prefix_in_key(key): - continue - iface_name, iface_cidr = key - ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) - if isinstance(ip_ntwrk, ipaddress.IPv4Network): - block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) - elif isinstance(ip_ntwrk, ipaddress.IPv6Network): - block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) - else: - log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + # Add iptables rules to drop all packets destined for peer-to-peer interface IP addresses + for iface_table_name in INTERFACE_TABLE_NAME_LIST: + iface_table = self.config_db.get_table(iface_table_name) + if iface_table: + for key, _ in iface_table.iteritems(): + if not _ip_prefix_in_key(key): + continue + + iface_name, iface_cidr = key + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + + # For VLAN interfaces, the IP address we want to block is the default gateway (i.e., + # the first available host IP address of the VLAN subnet) + ip_addr = next(ip_ntwrk.hosts()) if iface_table_name == "VLAN_INTERFACE" else ip_ntwrk.network_address + + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_addr, ip_ntwrk.max_prefixlen)) + elif isinstance(ip_ntwrk, ipaddress.IPv6Network): + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_addr, ip_ntwrk.max_prefixlen)) + else: + log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) return block_ip2me_cmds From b4452edb8a26237a1100f85d9d6b5bcc64ea3f67 Mon Sep 17 00:00:00 2001 From: Sujin Kang Date: Thu, 9 Jul 2020 16:14:06 -0700 Subject: [PATCH 0893/1427] Add disabling HW watchdog during boot for fast-reboot and warm-reboot (#4927) * Add disabling HW watchdog during boot for fast-reboot and warm-reboot case * typo --- .../build_templates/sonic_debian_extension.j2 | 5 +++ .../watchdog-control/watchdog-control.service | 10 +++++ .../watchdog-control/watchdog-control.sh | 44 +++++++++++++++++++ src/sonic-utilities | 2 +- 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 files/image_config/watchdog-control/watchdog-control.service create mode 100755 files/image_config/watchdog-control/watchdog-control.sh diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 737ce1271fa6..7c269ad29a7d 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -237,6 +237,11 @@ sudo LANG=C cp $IMAGE_CONFIGS/warmboot-finalizer/finalize-warmboot.sh $FILESYSTE sudo LANG=C cp $IMAGE_CONFIGS/warmboot-finalizer/warmboot-finalizer.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "warmboot-finalizer.service" | sudo tee -a $GENERATED_SERVICE_FILE +# Copy watchdog-control files +sudo LANG=C cp $IMAGE_CONFIGS/watchdog-control/watchdog-control.sh $FILESYSTEM_ROOT/usr/local/bin/watchdog-control.sh +sudo LANG=C cp $IMAGE_CONFIGS/watchdog-control/watchdog-control.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +echo "watchdog-control.service" | sudo tee -a $GENERATED_SERVICE_FILE + # Copy rsyslog configuration files and templates sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.sh $FILESYSTEM_ROOT/usr/bin/ diff --git a/files/image_config/watchdog-control/watchdog-control.service b/files/image_config/watchdog-control/watchdog-control.service new file mode 100644 index 000000000000..579e645e248d --- /dev/null +++ b/files/image_config/watchdog-control/watchdog-control.service @@ -0,0 +1,10 @@ +[Unit] +Description=watchdog control service +After=swss.service + +[Service] +Type=simple +ExecStart=/usr/local/bin/watchdog-control.sh + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/watchdog-control/watchdog-control.sh b/files/image_config/watchdog-control/watchdog-control.sh new file mode 100755 index 000000000000..b26fea03f192 --- /dev/null +++ b/files/image_config/watchdog-control/watchdog-control.sh @@ -0,0 +1,44 @@ +#! /bin/bash + +VERBOSE=no +WATCHDOG_UTIL="/usr/bin/watchdogutil" + +function debug() +{ + /usr/bin/logger "$0 : $1" + if [[ x"${VERBOSE}" == x"yes" ]]; then + echo "$(date) $0: $1" + fi +} + + +function getBootType() +{ + # same code snippet in files/scripts/syncd.sh + case "$(cat /proc/cmdline)" in + *SONIC_BOOT_TYPE=warm*) + TYPE='warm' + ;; + *SONIC_BOOT_TYPE=fastfast*) + TYPE='fastfast' + ;; + *SONIC_BOOT_TYPE=fast*|*fast-reboot*) + TYPE='fast' + ;; + *) + TYPE='cold' + esac + echo "${TYPE}" +} + +function disable_watchdog() +{ + # Obtain boot type from kernel arguments + BOOT_TYPE=`getBootType` + if [[ -x ${WATCHDOG_UTIL} ]]; then + debug "Disabling Watchdog during bootup after $BOOT_TYPE" + ${WATCHDOG_UTIL} disarm + fi +} + +disable_watchdog diff --git a/src/sonic-utilities b/src/sonic-utilities index 16a33f2fb67e..9715244d715c 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 16a33f2fb67e9da15ecc7780daa6b15408665539 +Subproject commit 9715244d715ca08b54595364c0386111bce7ef02 From ceace4b605ca51130b54a23aed095440147f2955 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Thu, 9 Jul 2020 19:45:21 -0700 Subject: [PATCH 0894/1427] [telemetry] Fix telemetry vars template path (#4938) The template is referenced relative to the script path and this could results in errors in case script is run from root. Add explicit path to the template file name. Also, moving telemetry_var template to template dir. And remove double quotes from around json dict. signed-off-by: Tamer Ahmed --- dockers/docker-sonic-telemetry/Dockerfile.j2 | 3 ++- dockers/docker-sonic-telemetry/telemetry.sh | 10 +++++++++- dockers/docker-sonic-telemetry/telemetry_vars.j2 | 6 +++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/dockers/docker-sonic-telemetry/Dockerfile.j2 b/dockers/docker-sonic-telemetry/Dockerfile.j2 index b878266f1c6c..90bb1d574119 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/Dockerfile.j2 @@ -22,7 +22,8 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs -COPY ["start.sh", "telemetry.sh", "dialout.sh", "telemetry_vars.j2", "/usr/bin/"] +COPY ["start.sh", "telemetry.sh", "dialout.sh", "/usr/bin/"] +COPY ["telemetry_vars.j2", "/usr/share/sonic/templates/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 18356e0945e2..0fd80fcbfcc8 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -1,8 +1,16 @@ #!/usr/bin/env bash +EXIT_TELEMETRY_VARS_FILE_NOT_FOUND=1 +TELEMETRY_VARS_FILE=/usr/share/sonic/templates/telemetry_vars.j2 + +if [ ! -f "$TELEMETRY_VARS_FILE" ]; then + echo "Telemetry vars template file not found" + exit $EXIT_TELEMETRY_VARS_FILE_NOT_FOUND +fi + # Try to read telemetry and certs config from ConfigDB. # Use default value if no valid config exists -TELEMETRY_VARS=$(sonic-cfggen -d -t telemetry_vars.j2) +TELEMETRY_VARS=$(sonic-cfggen -d -t $TELEMETRY_VARS_FILE) TELEMETRY_VARS=${TELEMETRY_VARS//[\']/\"} X509=$(echo $TELEMETRY_VARS | jq -r '.x509') GNMI=$(echo $TELEMETRY_VARS | jq -r '.gnmi') diff --git a/dockers/docker-sonic-telemetry/telemetry_vars.j2 b/dockers/docker-sonic-telemetry/telemetry_vars.j2 index 687781e1b9b2..d1d2d8977f1f 100644 --- a/dockers/docker-sonic-telemetry/telemetry_vars.j2 +++ b/dockers/docker-sonic-telemetry/telemetry_vars.j2 @@ -1,5 +1,5 @@ { - "certs": "{% if "certs" in TELEMETRY.keys() %}{{ TELEMETRY["certs"] }}{% endif %}", - "gnmi" : "{% if "gnmi" in TELEMETRY.keys() %}{{ TELEMETRY["gnmi"] }}{% endif %}", - "x509" : "{% if "x509" in DEVICE_METADATA.keys() %}{{ DEVICE_METADATA["x509"] }}{% endif %}" + "certs": {% if "certs" in TELEMETRY.keys() %}{{ TELEMETRY["certs"] }}{% else %}""{% endif %}, + "gnmi" : {% if "gnmi" in TELEMETRY.keys() %}{{ TELEMETRY["gnmi"] }}{% else %}""{% endif %}, + "x509" : {% if "x509" in DEVICE_METADATA.keys() %}{{ DEVICE_METADATA["x509"] }}{% else %}""{% endif %} } From d24d7b15f68bc920e3b0e4c4886bbbd3364d0799 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 10 Jul 2020 06:47:26 -0700 Subject: [PATCH 0895/1427] [build] only touch cache if wcache mode (#4896) --- Makefile.cache | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile.cache b/Makefile.cache index 5422b595929a..8ccc97cae770 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -249,9 +249,8 @@ define LOAD_FROM_CACHE $(if $(LOAD_DRV_DEB), $($(1)_CACHE_USER) tar -C $($(1)_BASE_PATH) -mxzvf $(CACHE_FILE_SELECT) 1>> $($(1)_DST_PATH)/$(1).log ,echo ); echo "File $(CACHE_FILE_SELECT) is loaded from cache into $($(1)_BASE_PATH)" >> $($(1)_DST_PATH)/$(1).log $(eval $(1)_CACHE_LOADED := Yes) - $(shell touch $(CACHE_FILE_SELECT)) + $(if $(call CHECK_WCACHE_ENABLED,$(1)), $(shell touch $(CACHE_FILE_SELECT))) echo "[ CACHE::LOADED ] $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE)" >> $($(1)_DST_PATH)/$(1).log - , echo "File $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE) is not present in cache or cache mode set as $(SONIC_DPKG_CACHE_METHOD) !" >> $($(1)_DST_PATH)/$(1).log echo "[ CACHE::SKIPPED ] $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE)" >> $($(1)_DST_PATH)/$(1).log echo "[ CACHE::SKIPPED ] DEP_FILES - Modified Files: [$($(1)_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log From 5a0a4667683ba664d4a624760a3b1a5b7d632584 Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 10 Jul 2020 11:48:38 -0700 Subject: [PATCH 0896/1427] [submodule]: update sonic-linux-kernel (#4940) d155c1e 2020-07-10 | use kstrtol_from_user in dni_dps460 driver (#151) Signed-off-by: Guohan Lu --- src/sonic-linux-kernel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index fdbb8851fee8..d155c1ea89ee 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit fdbb8851fee82d04c4fed06e53d233a2d5b37933 +Subproject commit d155c1ea89eecbb15409aea82e67e8dfc8e2196e From c9a14f71d01110bc22db5eecd6002d62d678ed16 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar T <53558409+santhosh-kt@users.noreply.github.com> Date: Sat, 11 Jul 2020 08:27:37 +0530 Subject: [PATCH 0897/1427] [DellEMC] Z9264f Disable low power modes in 10G ports (#4908) In Z9264 by default, all the ports have disabled low power mode except the last two 10G ports. Disabled low power mode in the last two 10G ports. --- .../z9264f/scripts/z9264f_platform.sh | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh index 33812c54b6eb..99a5e8a52334 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh @@ -100,13 +100,25 @@ switch_board_sfp() { #Modsel 64 ports to applicable QSFP type modules #This enables the adapter to respond for i2c commands switch_board_modsel() { - resource="/sys/bus/pci/devices/0000:04:00.0/resource0" - for ((i=1;i<=64;i++)); - do - port_addr=$(( 16384 + ((i - 1) * 16))) - hex=$( printf "0x%x" $port_addr ) - python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 - done + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + for ((i=1;i<=64;i++)); + do + port_addr=$(( 16384 + ((i - 1) * 16))) + hex=$( printf "0x%x" $port_addr ) + python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + done + + # Disabling low power mode for last two 10G ports + # From last 6th bit: Disable - 0; Enable - 1 + reg_offset=$(python /usr/bin/pcisysfs.py --get --offset 0x4400 --res $resource | cut -d':' -f 2) + reg_offset=$( printf '0x%s' $reg_offset) + reg_offset=$( printf '0x%x' $(( $reg_offset & 0xbf )) ) + python /usr/bin/pcisysfs.py --set --offset 0x4400 --val $reg_offset --res $resource > /dev/null 2>&1 + + reg_offset=$(python /usr/bin/pcisysfs.py --get --offset 0x4410 --res $resource | cut -d':' -f 2) + reg_offset=$( printf '0x%s' $reg_offset) + reg_offset=$( printf '0x%x' $(( $reg_offset & 0xbf )) ) + python /usr/bin/pcisysfs.py --set --offset 0x4410 --val $reg_offset --res $resource > /dev/null 2>&1 } # Copy led_proc_init.soc file according to the HWSKU From 24f684da68116ecb5f21b31258b8173a9cd59069 Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Fri, 10 Jul 2020 19:58:47 -0700 Subject: [PATCH 0898/1427] [docker-ptf] add gnmi python client (#4928) For telemetry regression test we need gnmi client to be present on ptfdocker. Gnmi-server will be present on SONiC DuT. Further, we can access gnmi_get from ptfdocker inside pytest to verify gnmi server streaming data successfully or not. --- dockers/docker-ptf/Dockerfile.j2 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index c9f7be803a20..b4a7834f60e8 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -139,6 +139,13 @@ RUN ln -s /usr/bin/tcpdump /usr/sbin/tcpdump RUN mkdir -p /var/log/supervisor +# Install Python-based GNMI client +RUN git clone https://github.com/lguohan/gnxi.git \ + && cd gnxi \ + && git checkout d01b36e \ + && cd gnmi_cli_py \ + && pip install -r requirements.txt + EXPOSE 22 8009 ENTRYPOINT ["/usr/local/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] From 3197c2dfaccea82e6a2dd70b2710f464e68aaf1b Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Fri, 10 Jul 2020 20:01:47 -0700 Subject: [PATCH 0899/1427] [mgmt-framework] Call sonic-cfggen Once (#4937) Optimizing number of calls made to sonic-cfggen during service start up as it adds to total system boot up time. ***-Test 1*** there is an average saving of 1 to 1.5 sec between old script and new script ``` root@str-s6000-acs-14:/# time /usr/bin/rest-server-old.sh Generating temporary TLS server certificate ... 2020/07/09 19:03:33 wrote cert.pem 2020/07/09 19:03:33 wrote key.pem REST_SERVER_ARGS = -ui /rest_ui -logtostderr -cert /tmp/cert.pem -key /tmp/key.pem /usr/sbin/rest_server -ui /rest_ui -logtostderr -cert /tmp/cert.pem -key /tmp/key.pem real 0m8.790s user 0m7.993s sys 0m0.584s root@str-s6000-acs-14:/# time /usr/bin/rest-server-new.sh Generating temporary TLS server certificate ... 2020/07/09 19:03:45 wrote cert.pem 2020/07/09 19:03:45 wrote key.pem REST_SERVER_ARGS = -ui /rest_ui -logtostderr -cert /tmp/cert.pem -key /tmp/key.pem /usr/sbin/rest_server -ui /rest_ui -logtostderr -cert /tmp/cert.pem -key /tmp/key.pem real 0m6.940s user 0m5.670s sys 0m0.386s ``` ***-Test 2*** Built an image with this change and rest server is running with params as described in test 1 above ``` admin@str-s6000-acs-14:~$ ps -ef | grep rest_server root 3301 2866 2 02:09 pts/0 00:00:10 /usr/sbin/rest_server -ui /rest_ui -logtostderr -cert /tmp/cert.pem -key /tmp/key.pem ``` signed-off-by: Tamer Ahmed --- .../docker-sonic-mgmt-framework/Dockerfile.j2 | 1 + .../docker-sonic-mgmt-framework/mgmt_vars.j2 | 4 ++ .../rest-server.sh | 39 ++++++++++++------- 3 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 dockers/docker-sonic-mgmt-framework/mgmt_vars.j2 diff --git a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 index 37675dbc33ff..dd396994d9f4 100644 --- a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 @@ -29,6 +29,7 @@ debs/{{ deb }}{{' '}} {%- endfor %} COPY ["start.sh", "rest-server.sh", "/usr/bin/"] +COPY ["mgmt_vars.j2", "/usr/share/sonic/templates/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] RUN apt-get remove -y g++ python-dev diff --git a/dockers/docker-sonic-mgmt-framework/mgmt_vars.j2 b/dockers/docker-sonic-mgmt-framework/mgmt_vars.j2 new file mode 100644 index 000000000000..f43b11ba4199 --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/mgmt_vars.j2 @@ -0,0 +1,4 @@ +{ + "rest_server": {% if REST_SERVER is defined and "default" in RESET_SERVER.keys() %}{{ REST_SERVER['default'] }}{% else %}""{% endif %}, + "x509" : {% if "x509" in DEVICE_METADATA.keys() %}{{ DEVICE_METADATA["x509"] }}{% else %}""{% endif %} +} diff --git a/dockers/docker-sonic-mgmt-framework/rest-server.sh b/dockers/docker-sonic-mgmt-framework/rest-server.sh index 6e551d7c6143..56a7e2999402 100755 --- a/dockers/docker-sonic-mgmt-framework/rest-server.sh +++ b/dockers/docker-sonic-mgmt-framework/rest-server.sh @@ -1,28 +1,39 @@ #!/usr/bin/env bash # Startup script for SONiC Management REST Server +EXIT_MGMT_VARS_FILE_NOT_FOUND=1 +MGMT_VARS_FILE=/usr/share/sonic/templates/mgmt_vars.j2 -# Read basic server settings from REST_SERVER|default entry -HAS_REST_CONFIG=$(sonic-cfggen -d -v "1 if REST_SERVER and REST_SERVER['default']") -if [ "$HAS_REST_CONFIG" == "1" ]; then - SERVER_PORT=$(sonic-cfggen -d -v "REST_SERVER['default']['port']") - CLIENT_AUTH=$(sonic-cfggen -d -v "REST_SERVER['default']['client_auth']") - LOG_LEVEL=$(sonic-cfggen -d -v "REST_SERVER['default']['log_level']") +if [ ! -f "$MGMT_VARS_FILE" ]; then + echo "Mgmt vars template file not found" + exit $EXIT_MGMT_VARS_FILE_NOT_FOUND +fi + +# Read basic server settings from mgmt vars entries +MGMT_VARS=$(sonic-cfggen -d -t $MGMT_VARS_FILE) +MGMT_VARS=${MGMT_VARS//[\']/\"} + +REST_SERVER=$(echo $MGMT_VARS | jq -r '.rest_server') + +if [ -n "$REST_SERVER" ]; then + SERVER_PORT=$(echo $REST_SERVER | jq -r '.port') + CLIENT_AUTH=$(echo $REST_SERVER | jq -r '.client_auth') + LOG_LEVEL=$(echo $REST_SERVER | jq -r '.log_level') - SERVER_CRT=$(sonic-cfggen -d -v "REST_SERVER['default']['server_crt']") - SERVER_KEY=$(sonic-cfggen -d -v "REST_SERVER['default']['server_key']") - CA_CRT=$(sonic-cfggen -d -v "REST_SERVER['default']['ca_crt']") + SERVER_CRT=$(echo $REST_SERVER | jq -r '.server_crt') + SERVER_KEY=$(echo $REST_SERVER | jq -r '.server_key') + CA_CRT=$(echo $REST_SERVER | jq -r '.ca_crt') fi if [[ -z $SERVER_CRT ]] && [[ -z $SERVER_KEY ]] && [[ -z $CA_CRT ]]; then - HAS_X509_CONFIG=$(sonic-cfggen -d -v "1 if DEVICE_METADATA and DEVICE_METADATA['x509']") + X509=$(echo $MGMT_VARS | jq -r '.x509') fi # Read certificate file paths from DEVICE_METADATA|x509 entry. -if [ "$HAS_X509_CONFIG" == "1" ]; then - SERVER_CRT=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']") - SERVER_KEY=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']") - CA_CRT=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']") +if [ -n "$X509" ]; then + SERVER_CRT=$(echo $X509 | jq -r '.server_crt') + SERVER_KEY=$(echo $X509 | jq -r '.server_key') + CA_CRT=$(echo $X509 | jq -r '.ca_crt') fi # Create temporary server certificate if they not configured in ConfigDB From 0db05e35b02d62677e2e689953a6875b9f3262fc Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Sat, 11 Jul 2020 14:29:37 +0800 Subject: [PATCH 0900/1427] [watermark] Fix error: BUFFER_POOL_WATERMARK isn't enabled by default (#4882) * Fix error: watermarkstat -t buffer_pool doesn't work Signed-off-by: Stephen Sun --- dockers/docker-orchagent/enable_counters.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-orchagent/enable_counters.py b/dockers/docker-orchagent/enable_counters.py index b2ec4b85a202..9ce7a0f8d8b4 100755 --- a/dockers/docker-orchagent/enable_counters.py +++ b/dockers/docker-orchagent/enable_counters.py @@ -17,6 +17,7 @@ def enable_counters(): enable_counter_group(db, 'PFCWD') enable_counter_group(db, 'PG_WATERMARK') enable_counter_group(db, 'QUEUE_WATERMARK') + enable_counter_group(db, 'BUFFER_POOL_WATERMARK') def get_uptime(): with open('/proc/uptime') as fp: From 71e93d921c0fbc82f8c85e944cb4e65e9cb6b300 Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Sat, 11 Jul 2020 12:12:22 -0700 Subject: [PATCH 0901/1427] [docker-team]: upgrade docker-teamd to buster (#4914) Signed-off-by: Joyas Joseph --- dockers/docker-teamd/Dockerfile.j2 | 2 +- rules/docker-teamd.mk | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dockers/docker-teamd/Dockerfile.j2 b/dockers/docker-teamd/Dockerfile.j2 index 704f3c2ebbda..d9795f20f59d 100644 --- a/dockers/docker-teamd/Dockerfile.j2 +++ b/dockers/docker-teamd/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk index 49c9dde9ba17..c0fe6bfb6bb1 100644 --- a/rules/docker-teamd.mk +++ b/rules/docker-teamd.mk @@ -7,21 +7,19 @@ DOCKER_TEAMD_DBG = $(DOCKER_TEAMD_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_TEAMD)_PATH = $(DOCKERS_PATH)/$(DOCKER_TEAMD_STEM) $(DOCKER_TEAMD)_DEPENDS += $(SWSS) $(LIBTEAMDCTL) $(LIBTEAM_UTILS) -$(DOCKER_TEAMD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_TEAMD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_TEAMD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) $(DOCKER_TEAMD)_DBG_DEPENDS += $(LIBTEAMDCTL_DBG) $(LIBTEAM_UTILS_DBG) -$(DOCKER_TEAMD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_TEAMD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_TEAMD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_TEAMD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_TEAMD) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_TEAMD) -SONIC_STRETCH_DOCKERS += $(DOCKER_TEAMD) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_TEAMD_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_TEAMD_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_TEAMD_DBG) $(DOCKER_TEAMD)_CONTAINER_NAME = teamd $(DOCKER_TEAMD)_RUN_OPT += --privileged -t From a0236f7cbb9a1f42dc0aa6125c321b6d9c0fcd96 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Sat, 11 Jul 2020 14:35:19 -0700 Subject: [PATCH 0902/1427] [bgpcfgd] - Fix a key error during delete (#4946) --- src/sonic-bgpcfgd/bgpcfgd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd index 0fbe44602a22..38d7f0671f89 100755 --- a/src/sonic-bgpcfgd/bgpcfgd +++ b/src/sonic-bgpcfgd/bgpcfgd @@ -647,7 +647,7 @@ class BGPPeerMgrBase(Manager): ret_code = self.apply_op(cmd, vrf) if ret_code: log_info("Peer '(%s|%s)' has been removed" % (vrf, nbr)) - self.peers.remove(key) + self.peers.remove(peer_key) else: log_err("Peer '(%s|%s)' hasn't been removed" % (vrf, nbr)) From 39941f0ae242da3449593493532f33d4269731fa Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Sun, 12 Jul 2020 09:25:09 +0300 Subject: [PATCH 0903/1427] [BFN] Update SAI and platform packages to 20200710 (#4942) Barefoot, updated SAI and platform packages to 20200710 Signed-off-by: Volodymyr Boyko --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index d563db67454e..a59f9f39d5b6 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20200701_deb9.deb +BFN_PLATFORM = bfnplatform_20200710_deb9.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 05e70282ddb9..36b5dfed7d10 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20200701_deb9.deb +BFN_SAI = bfnsdk_20200710_deb9.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) From e1f7fb135bb68b55195e6e772b6c347936bae3ff Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Tue, 14 Jul 2020 01:20:22 +0800 Subject: [PATCH 0904/1427] [Mellanox] Add system health configuration file for Mellanox platforms (#4834) The new feature system health support a platform based configuration file. Add configuration files for all Mellanox platform. Add a configuration file for SN2700, other platform will use a soft link to it. --- .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 11 +++++++++++ .../system_health_monitoring_config.json | 11 +++++++++++ .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 1 + .../system_health_monitoring_config.json | 1 + 15 files changed, 35 insertions(+) create mode 120000 device/mellanox/x86_64-mlnx_lssn2700-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn2100-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn2410-r0/system_health_monitoring_config.json create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json create mode 100644 device/mellanox/x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn2740-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn3700-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn3700_simx-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn3700c-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/system_health_monitoring_config.json create mode 120000 device/mellanox/x86_64-mlnx_msn4700_simx-r0/system_health_monitoring_config.json diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_lssn2700-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2100-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2410-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json new file mode 100644 index 000000000000..4c7d53f19cf5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json @@ -0,0 +1,11 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": ["psu.voltage"], + "external_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "orange", + "normal": "green", + "booting": "orange_blink" + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json new file mode 100644 index 000000000000..e4ba06d7f46c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json @@ -0,0 +1,11 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": ["psu","asic","fan"], + "external_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "orange", + "normal": "green", + "booting": "orange_blink" + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2740-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn3420-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn3700-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700_simx-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..42fe945344c9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn3800-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn4700-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..42fe945344c9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json \ No newline at end of file From 76d68ad1f5364c3b76b12b2b0ccb7e96c081a416 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Tue, 14 Jul 2020 01:22:39 +0800 Subject: [PATCH 0905/1427] [Mellanox] Add support for set/get system led status (#4829) System health feature needs to set/get system led status - Add a led object in chassis class and initialize it when the API is called on host side - Read/write system led system fs to get/set the status --- .../sonic_platform/chassis.py | 29 +++++ .../mlnx-platform-api/sonic_platform/led.py | 113 +++++++++++++++++- .../sonic_platform/platform.py | 1 + 3 files changed, 142 insertions(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index ff4e28900550..5a297ed29d7d 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -56,6 +56,9 @@ class Chassis(ChassisBase): """Platform-specific Chassis class""" + # System status LED + _led = None + def __init__(self): super(Chassis, self).__init__() @@ -156,6 +159,10 @@ def initialize_components(self): self._component_list.append(ComponentBIOS()) self._component_list.extend(ComponentCPLD.get_component_list()) + def initizalize_system_led(self): + from .led import SystemLed + Chassis._led = SystemLed() + def get_name(self): """ @@ -467,3 +474,25 @@ def get_thermal_manager(self): from .thermal_manager import ThermalManager return ThermalManager + def set_status_led(self, color): + """ + Sets the state of the system LED + + Args: + color: A string representing the color with which to set the + system LED + + Returns: + bool: True if system LED state is set successfully, False if not + """ + return False if not Chassis._led else Chassis._led.set_status(color) + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + return None if not Chassis._led else Chassis._led.get_status() diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/led.py b/platform/mellanox/mlnx-platform-api/sonic_platform/led.py index ebc2de25a5c1..1e401ebbaf15 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/led.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/led.py @@ -3,12 +3,16 @@ class Led(object): STATUS_LED_COLOR_GREEN = 'green' + STATUS_LED_COLOR_GREEN_BLINK = 'green_blink' STATUS_LED_COLOR_RED = 'red' + STATUS_LED_COLOR_RED_BLINK = 'red_blink' STATUS_LED_COLOR_ORANGE = 'orange' + STATUS_LED_COLOR_ORANGE_BLINK = 'orange_blink' STATUS_LED_COLOR_OFF = 'off' LED_ON = '1' LED_OFF = '0' + LED_BLINK = '50' LED_PATH = "/var/run/hw-management/led/" @@ -19,6 +23,11 @@ def set_status(self, color): status = False try: + self._stop_blink(led_cap_list) + blink_pos = color.find('blink') + if blink_pos != -1: + return self._set_status_blink(color, blink_pos, led_cap_list) + if color == Led.STATUS_LED_COLOR_GREEN: with open(self.get_green_led_path(), 'w') as led: led.write(Led.LED_ON) @@ -54,12 +63,53 @@ def set_status(self, color): return status + def _set_status_blink(self, color, blink_pos, led_cap_list): + if color not in led_cap_list: + if color == Led.STATUS_LED_COLOR_RED_BLINK and Led.STATUS_LED_COLOR_ORANGE_BLINK in led_cap_list: + color = Led.STATUS_LED_COLOR_ORANGE_BLINK + elif color == Led.STATUS_LED_COLOR_ORANGE_BLINK and Led.STATUS_LED_COLOR_RED_BLINK in led_cap_list: + color = Led.STATUS_LED_COLOR_RED_BLINK + else: + return False + + if Led.STATUS_LED_COLOR_GREEN_BLINK == color: + self._set_led_blink_status(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path(), Led.LED_BLINK) + elif Led.STATUS_LED_COLOR_RED_BLINK == color: + self._set_led_blink_status(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path(), Led.LED_BLINK) + elif Led.STATUS_LED_COLOR_ORANGE_BLINK == color: + self._set_led_blink_status(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path(), Led.LED_BLINK) + else: + return False + + return True + + def _stop_blink(self, led_cap_list): + try: + if Led.STATUS_LED_COLOR_GREEN_BLINK in led_cap_list: + self._set_led_blink_status(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path(), Led.LED_OFF) + if Led.STATUS_LED_COLOR_RED_BLINK in led_cap_list: + self._set_led_blink_status(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path(), Led.LED_OFF) + if Led.STATUS_LED_COLOR_ORANGE_BLINK in led_cap_list: + self._set_led_blink_status(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path(), Led.LED_OFF) + except Exception as e: + return + + def _set_led_blink_status(self, delay_on_file, delay_off_file, value): + with open(delay_on_file, 'w') as led: + led.write(value) + with open(delay_off_file, 'w') as led: + led.write(value) + def get_status(self): led_cap_list = self.get_capability() if led_cap_list is None: return Led.STATUS_LED_COLOR_OFF try: + blink_status = self._get_blink_status(led_cap_list) + if blink_status is not None: + return blink_status + with open(self.get_green_led_path(), 'r') as led: if Led.LED_OFF != led.read().rstrip('\n'): return Led.STATUS_LED_COLOR_GREEN @@ -77,12 +127,35 @@ def get_status(self): return Led.STATUS_LED_COLOR_OFF + def _get_blink_status(self, led_cap_list): + try: + if Led.STATUS_LED_COLOR_GREEN_BLINK in led_cap_list: + if self._is_led_blinking(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path()): + return Led.STATUS_LED_COLOR_GREEN_BLINK + if Led.STATUS_LED_COLOR_RED_BLINK in led_cap_list: + if self._is_led_blinking(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path()): + return Led.STATUS_LED_COLOR_RED_BLINK + if Led.STATUS_LED_COLOR_ORANGE_BLINK in led_cap_list: + if self._is_led_blinking(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path()): + return Led.STATUS_LED_COLOR_ORANGE_BLINK + except Exception as e: + return None + + return None + + def _is_led_blinking(self, delay_on_file, delay_off_file): + with open(delay_on_file, 'r') as led: + delay_on = led.read().rstrip('\n') + with open(delay_off_file, 'r') as led: + delay_off = led.read().rstrip('\n') + return delay_on != Led.LED_OFF and delay_off != Led.LED_OFF + def get_capability(self): cap_list = None try: with open(self.get_led_cap_path(), 'r') as led_cap: caps = led_cap.read() - cap_list = caps.split() + cap_list = set(caps.split()) except (ValueError, IOError): pass @@ -91,12 +164,30 @@ def get_capability(self): def get_green_led_path(self): pass + def get_green_led_delay_off_path(self): + return '{}_delay_off'.format(self.get_green_led_path()) + + def get_green_led_delay_on_path(self): + return '{}_delay_on'.format(self.get_green_led_path()) + def get_red_led_path(self): pass + def get_red_led_delay_off_path(self): + return '{}_delay_off'.format(self.get_red_led_path()) + + def get_red_led_delay_on_path(self): + return '{}_delay_on'.format(self.get_red_led_path()) + def get_orange_led_path(self): pass + def get_orange_led_delay_off_path(self): + return '{}_delay_off'.format(self.get_orange_led_path()) + + def get_orange_led_delay_on_path(self): + return '{}_delay_on'.format(self.get_orange_led_path()) + def get_led_cap_path(self): pass @@ -159,6 +250,26 @@ def get_led_cap_path(self): return self._led_cap_path +class SystemLed(Led): + def __init__(self): + self._green_led_path = os.path.join(Led.LED_PATH, "led_status_green") + self._red_led_path = os.path.join(Led.LED_PATH, "led_status_red") + self._orange_led_path = os.path.join(Led.LED_PATH, "led_status_orange") + self._led_cap_path = os.path.join(Led.LED_PATH, "led_status_capability") + + def get_green_led_path(self): + return self._green_led_path + + def get_red_led_path(self): + return self._red_led_path + + def get_orange_led_path(self): + return self._orange_led_path + + def get_led_cap_path(self): + return self._led_cap_path + + class SharedLed(object): LED_PRIORITY = { Led.STATUS_LED_COLOR_RED: 0, diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py index 6d81ca3e7b51..6073ce5faed9 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -19,6 +19,7 @@ def __init__(self): if self._is_host(): self._chassis = Chassis() self._chassis.initialize_components() + self._chassis.initizalize_system_led() else: self._chassis = Chassis() self._chassis.initialize_psu() From bf45e11d2760c852f0a056d71add260e55179b04 Mon Sep 17 00:00:00 2001 From: Sujin Kang Date: Mon, 13 Jul 2020 14:15:09 -0700 Subject: [PATCH 0906/1427] Add pcie-check service to check PCIe devices at boot (#4771) * PCIe Monitor service * Add rescan to pcie-mon.service when it fails to get all pcie devices * space * Clean up * review comments * update the pcie status in state db * update the failed pcie status once at the end * Update the pcie_status in STATE_DB and rename the service * Add log to exit the service if the configuration file doesn't exist. * fix the build failure * Redo the pcie rescan for pcie-check failed case. * review comments * review comments * review comments --- files/build_templates/pcie-check.timer | 9 +++ .../build_templates/sonic_debian_extension.j2 | 9 +++ .../pcie-check/pcie-check.service | 7 +++ files/image_config/pcie-check/pcie-check.sh | 59 +++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 files/build_templates/pcie-check.timer create mode 100644 files/image_config/pcie-check/pcie-check.service create mode 100644 files/image_config/pcie-check/pcie-check.sh diff --git a/files/build_templates/pcie-check.timer b/files/build_templates/pcie-check.timer new file mode 100644 index 000000000000..4ad5c6481861 --- /dev/null +++ b/files/build_templates/pcie-check.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Start the pcie-check.service 10 seconds after boot + +[Timer] +OnBootSec=10sec +Unit=pcie-check.service + +[Install] +WantedBy=timers.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 7c269ad29a7d..fd8ccb02f47f 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -364,6 +364,15 @@ sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd.service $FILESYSTEM_ROO echo "procdockerstatsd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd $FILESYSTEM_ROOT/usr/bin/ +# Copy systemd timer configuration +sudo cp $BUILD_TEMPLATES/pcie-check.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable pcie-check.timer + +# Copy pcie-check service files +sudo cp $IMAGE_CONFIGS/pcie-check/pcie-check.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +echo "pcie-check.service" | sudo tee -a $GENERATED_SERVICE_FILE +sudo cp $IMAGE_CONFIGS/pcie-check/pcie-check.sh $FILESYSTEM_ROOT/usr/bin/ + # Copy systemd timer configuration # It implements delayed start of services sudo cp $BUILD_TEMPLATES/process-reboot-cause.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM diff --git a/files/image_config/pcie-check/pcie-check.service b/files/image_config/pcie-check/pcie-check.service new file mode 100644 index 000000000000..9bea910a7fbd --- /dev/null +++ b/files/image_config/pcie-check/pcie-check.service @@ -0,0 +1,7 @@ +[Unit] +Description=Check the PCIe device presence and status +After=rc.local.service + +[Service] +Type=simple +ExecStart=/usr/bin/pcie-check.sh diff --git a/files/image_config/pcie-check/pcie-check.sh b/files/image_config/pcie-check/pcie-check.sh new file mode 100644 index 000000000000..90fc0bb5cae9 --- /dev/null +++ b/files/image_config/pcie-check/pcie-check.sh @@ -0,0 +1,59 @@ +#! /bin/bash +## Check the platform PCIe device presence and status + +VERBOSE="no" +RESULTS="PCIe Device Checking All Test" +EXPECTED="PCIe Device Checking All Test ----------->>> PASSED" +MAX_WAIT_SECONDS=15 + +function debug() +{ + /usr/bin/logger "$0 : $1" + if [[ x"${VERBOSE}" == x"yes" ]]; then + echo "$(date) $0: $1" + fi +} + +function check_and_rescan_pcie_devices() +{ + PCIE_CHK_CMD=$(sudo pcieutil pcie-check |grep "$RESULTS") + PLATFORM=$(sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + + if [ ! -f /usr/share/sonic/device/$PLATFORM/plugins/pcie.yaml ]; then + debug "pcie.yaml does not exist! can't check pcie status!" + exit + fi + + begin=$SECONDS + end=$((begin + MAX_WAIT_SECONDS)) + rescan_time=$((MAX_WAIT_SECONDS/2)) + rescan_time=$((begin + rescan_time)) + + while true + do + now=$SECONDS + if [[ $now -gt $end ]]; then + break + fi + + if [ "$PCIE_CHK_CMD" = "$EXPECTED" ]; then + redis-cli -n 6 SET "PCIE_STATUS|PCIE_DEVICES" "PASSED" + debug "PCIe check passed" + exit + else + debug "sleep 0.1 seconds" + sleep 0.1 + fi + + if [ $now -gt $rescan_time ]; then + debug "PCIe check failed, try pci bus rescan" + echo 1 > /sys/bus/pci/rescan + rescan_time=$end + fi + + done + debug "PCIe check failed" + redis-cli -n 6 SET "PCIE_STATUS|PCIE_DEVICES" "FAILED" +} + +check_and_rescan_pcie_devices From de16e6f14d4138ec2914b54415827d8707f75f09 Mon Sep 17 00:00:00 2001 From: taochengyi <54564117+taocy001@users.noreply.github.com> Date: Tue, 14 Jul 2020 13:56:42 +0800 Subject: [PATCH 0907/1427] [build][centec] update sai to v1.6.3 (#4951) update sai to v1.6.3 for centec E582 platform(x86 CPU) --- platform/centec/sdk.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/centec/sdk.mk b/platform/centec/sdk.mk index 724c15735675..935d6c14a892 100644 --- a/platform/centec/sdk.mk +++ b/platform/centec/sdk.mk @@ -1,6 +1,6 @@ # Centec SAI -CENTEC_SAI = libsai_1.6.1_amd64.deb -$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/libsai_1.6.1-1.0_amd64.deb +CENTEC_SAI = libsai_1.6.3-1_amd64.deb +$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/$(CENTEC_SAI) $(CENTEC_SAI)_CONFLICTS += $(LIBSAIVS_DEV) SONIC_ONLINE_DEBS += $(CENTEC_SAI) From f929b00eaae89b7654259bde19dc166bd23b2ad8 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 14 Jul 2020 11:56:54 -0700 Subject: [PATCH 0908/1427] [sonic-utilities] Update submodule (#4963) * src/sonic-utilities 9715244...a23479e (7): > [sonic-installer] Hyphens instead of underscores in command and subcommands (#983) > Fix the None Type Exception when Interface Table does not exist (cold boot) as part of db migration (#986) > Support to verify reboot for secure boot (#979) > [filter-fdb] Fix For Vlan Defined With No CIDR (#976) > Intf table migration for APP_DB entries during warmboot (#980) > Enable HW watchdog before fast-reboot (#977) > [Multi NPU] Time Improvements to the config reload/load_minigraph commands (#917) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 9715244d715c..a23479e8cf79 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 9715244d715ca08b54595364c0386111bce7ef02 +Subproject commit a23479e8cf792c9c821329dc374c3ce0f9bd8348 From 46cc6968d7a0aaaad254fa17c6449834ce056162 Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Wed, 15 Jul 2020 02:50:41 +0530 Subject: [PATCH 0909/1427] [Juniper][QFX52xx] Platform fixes/enhancements (#4953) 1) Fixing the issues while applying platform TxCTLE settings in sfputil.py for QFX5200 2) Adding the support for transceiver dom threshold info in sfputil.py for both QFX5210 & QFX5200 platforms 3) Updating the sfputil.py for QFX5210 & QFX5200 platforms 4) Adding a new platform specific command 'show_thresholds' to display the FAN dutycycle percentage for various temperature ranges (for both AFI & AFO QFX5200 systems). Signed-off-by: Ciju Rajan K --- .../plugins/qfx5200_sfp_init.py | 23 +- .../plugins/sfputil.py | 405 ++++++++++++++---- .../plugins/sfputil.py | 157 ++++++- .../sonic-platform-juniper-qfx5200.install | 3 + .../qfx5200/utils/show_thresholds | 24 ++ .../utils/temperature_thresholds_AFI.txt | 27 ++ .../utils/temperature_thresholds_AFO.txt | 27 ++ 7 files changed, 551 insertions(+), 115 deletions(-) create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFI.txt create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFO.txt diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py index c6846ec12a8a..4ba33dc8b22d 100644 --- a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py @@ -35,8 +35,14 @@ import time import os.path import sfputil as jnpr_sfp +from sonic_daemon_base.daemon_base import Logger from pprint import pprint +SYSLOG_IDENTIFIER = "sfputil" + +# Global logger class instance +logger = Logger(SYSLOG_IDENTIFIER) + DEBUG = False def i2c_eeprom_dev_update(port, create_eeprom): @@ -69,23 +75,16 @@ def gpio_sfp_init(): #Reset all ports for port in range(jnpr_sfp.GPIO_PORT_START, jnpr_sfp.GPIO_PORT_END + 1): - port_inited = False - if jnpr_sfp.gpio_sfp_presence_get(port): - port_inited = jnpr_sfp.gpio_sfp_reset_set(port, 0) + logger.log_debug("GPIO SFP port {}".format(port)) - if port_inited: - i2c_eeprom_dev_update(port, True) - else: - i2c_eeprom_dev_update(port, False) + jnpr_sfp.gpio_sfp_reset_set(port, 0) + i2c_eeprom_dev_update(port, True) - time.sleep(2) + time.sleep(1) #Enable optics for all ports which have XCVRs present for port in range(jnpr_sfp.GPIO_PORT_START, jnpr_sfp.GPIO_PORT_END + 1): - if jnpr_sfp.gpio_sfp_presence_get(port): - jnpr_sfp.gpio_sfp_lpmode_set(port, 1) - - time.sleep(2) + jnpr_sfp.gpio_sfp_lpmode_set(port, 1) if __name__ == '__main__': diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py index 2e3e453403a2..e1543bedb8b8 100644 --- a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py @@ -36,16 +36,23 @@ import time import os.path import glob + import io from sonic_sfp.sfputilbase import SfpUtilBase from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_daemon_base.daemon_base import Logger from ctypes import create_string_buffer except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +SYSLOG_IDENTIFIER = "sfputil" + +# Global logger class instance +logger = Logger(SYSLOG_IDENTIFIER) + qfx5200_qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') @@ -125,6 +132,10 @@ QSFP_CHANNL_MON_OFFSET = 34 QSFP_CHANNL_MON_WIDTH = 16 QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 16 SFP_TEMPE_OFFSET = 96 @@ -282,92 +293,115 @@ class SfpUtil(SfpUtilBase): } port_ctle_settings = { - 0: 7, - 1: 6, - 2: 6, - 3: 6, - 4: 6, - 5: 5, - 6: 6, - 7: 5, - 8: 5, - 9: 5, - 10: 7, - 11: 7, - 12: 6, - 13: 5, - 14: 4, - 15: 3, - 16: 4, - 17: 5, - 18: 6, - 19: 6, - 20: 7, - 21: 6, - 22: 5, - 23: 5, - 24: 5, - 25: 5, - 26: 6, - 27: 5, - 28: 6, - 29: 6, - 30: 7, - 31: 7 + 0: 119, # 0x77 + 1: 102, # 0x66 + 2: 102, # 0x66 + 3: 102, # 0x66 + 4: 102, # 0x66 + 5: 85, # 0x55 + 6: 102, # 0x66 + 7: 85, # 0x55 + 8: 85, # 0x55 + 9: 85, # 0x55 + 10: 119, # 0x77 + 11: 119, # 0x77 + 12: 102, # 0x66 + 13: 85, # 0x55 + 14: 68, # 0x44 + 15: 51, # 0x33 + 16: 68, # 0x44 + 17: 85, # 0x55 + 18: 102, # 0x66 + 19: 102, # 0x66 + 20: 119, # 0X77 + 21: 102, # 0x66 + 22: 85, # 0X55 + 23: 85, # 0X55 + 24: 85, # 0x55 + 25: 85, # 0x55 + 26: 102, # 0x66 + 27: 85, # 0x55 + 28: 102, # 0x66 + 29: 102, # 0x66 + 30: 119, # 0x77 + 31: 119 # 0x77 } optics_list_100g = { "AFBR-89CDDZ-JU1", + "AFBR-89CDDZ-JU2", "FTLC9551REPM-J1", + "FTLC9551REPM-J3", "LUX42604CO", "EOLQ-161HG-10-LJ1", "FTLC1151RDPL-J1", - "TR-FC13R-NJ3", - "SPQ-CE-LR-CDFB-J2" + "TR-FC13R-NJC", + "TR-FC13L-NJC", + "SPQ-CE-LR-CDFB-J2", + "1K1QAC", + "SPQCELRCDFAJ2" } - def is_100g_optics(self,part_num): + optics_list_40g = { + "FTL4C1QE1C-J1" + } + + def clear_bit(self, data, pos): + return (data & (~(1 << pos))) + + def check_bit(self, data, pos): + return (data & (1 << pos)) + + def set_bit(self, data, pos): + return (data | (1 << pos)) + + def is_100g_optics(self, part_num): ret = part_num in self.optics_list_100g return ret + + def is_40g_optics(self, part_num): + ret = part_num in self.optics_list_40g + return ret - def process_TxCTLE(self, port_num, part_num): - - eeprom = None - - try: - if self.is_100g_optics(part_num): - # Accessing page 3 of optics - regval = 0x3 - buffer = create_string_buffer(1) - buffer[0] = chr(regval) - eeprom = open(self._port_to_eeprom_mapping[port_num], "r+b") - eeprom.seek(127) - eeprom.write(buffer[0]) - - regval = self.port_ctle_settings[port_num] - - eeprom.seek(234) - buffer[0] = eeprom.read(1) - if (buffer[0] != chr(regval)): - buffer[0] = chr(regval) - eeprom.write(buffer[0]) - eeprom.seek(235) - eeprom.write(buffer[0]) - else: - pass - # Moving back the optics page to 0 - regval = 0x0 - buffer[0] = chr(regval) - eeprom.seek(127) - eeprom.write(buffer[0]) - else: - pass - except IOError as e: - print "Error: unable to open file: %s" % str(e) + def is_optics(self, part_num): + if self.is_100g_optics(part_num): + return True + elif self.is_40g_optics(part_num): + return True + else: + return False - finally: - if eeprom is not None: - eeprom.close + def process_TxCTLE(self, eeprom, port_num, part_num): + if self.is_100g_optics(part_num): + logger.log_debug(" QFX5200: TxCTLE port {} and SFP PN NUM {} ".format(port_num,part_num)) + # Accessing page 3 of optics + regval = 3 + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + eeprom.seek(127) + eeprom.write(buffer[0]) + + regval = self.port_ctle_settings[port_num] + logger.log_debug("QFX5200: TxCTLE port {}, SFP PN NUM {}, regval {} ".format(port_num,part_num,regval)) + + eeprom.seek(234) + buffer[0] = chr(regval) + eeprom.write(buffer[0]) + eeprom.seek(235) + eeprom.write(buffer[0]) + # Moving back the optics page to 0 + regval = 0x0 + buffer[0] = chr(regval) + eeprom.seek(127) + eeprom.write(buffer[0]) + else: + pass + + def is_highpower_optics(self, data): + return (self.check_bit(data, 0) | self.check_bit(data, 1)) + + def is_cdr_present(self, data): + return (self.check_bit(data, 2) | self.check_bit(data, 3)) @property def port_start(self): @@ -399,6 +433,11 @@ def __init__(self): for x in range(0, self.port_end + 1): self.port_to_eeprom_mapping[x] = eeprom_path.format(self.port_to_i2cbus_mapping[x]) + logger.log_debug("QFX5200: SfpUtil __init__") + if os.path.isfile(self.cmd): + logger.log_debug("QFX5200: SfpUtil removing sfppresence file") + os.remove(self.cmd) + SfpUtilBase.__init__(self) def get_presence(self, port_num): @@ -410,7 +449,7 @@ def get_presence(self, port_num): def get_low_power_mode(self, port_num): reg_value = gpio_sfp_lpmode_get(port_num) - if reg_value == 1: + if reg_value == 0: return True return False @@ -418,9 +457,9 @@ def get_low_power_mode(self, port_num): def set_low_power_mode(self, port_num, lpmode): if lpmode == False: - lpmode = 0 - else: lpmode = 1 + else: + lpmode = 0 status = gpio_sfp_lpmode_set(port_num, lpmode) return status @@ -466,31 +505,83 @@ def sfp_detect(self): current_sfp_values = [0] * 32 previous_sfp_values = [0] * 32 + logger.log_debug("QFX5200: sfp_detect Start") if not os.path.isfile(self.cmd): - pass + logger.log_debug("QFX5200: sfppresence file not created") else: if (self.read_from_file(self.cmd) == False): + logger.log_debug("QFX5200: sfp_detect not able to open sfppresence file") return False, defl_dict else: previous_sfp_values = self.read_from_file(self.cmd) + logger.log_debug("QFX5200: sfp_detect sfppresence file present, previous_sfp_values populated") # Read the current values from sysfs for port in range(GPIO_PORT_START, GPIO_PORT_END + 1): sfp_present = gpio_sfp_presence_get(port) current_sfp_values[port] = str(sfp_present) ret_dict.update({port:current_sfp_values[port]}) - if (current_sfp_values[port] != previous_sfp_values[port]): + + prev_value = str(previous_sfp_values[port]) + + current_value = current_sfp_values[port] + if (prev_value != current_value): ret_dict.update({port:current_sfp_values[port]}) + value = str(current_sfp_values[port]) + if (value): + offset = 128 + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return None + + file_path = self._get_port_eeprom_path(port, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + print("Error, file not exist %s" % file_path) + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + sfp_pn_num = str(sfp_vendor_pn_data['data']['Vendor PN']['value']) + if self.is_optics(sfp_pn_num): + logger.log_debug("QFX5200: Port {} is connected with Optics with Part Number {}".format(port,sfp_pn_num)) + eeprom1 = open(self._port_to_eeprom_mapping[port], "r+b") + self.process_TxCTLE(eeprom1, port, sfp_pn_num) + eeprom1.close + # End of if(value) + # End of current_sfp_values != previous_sfp_vlalues + # End of for loop + + if(self.write_to_file(self.cmd, current_sfp_values) == True): + logger.log_debug("QFX5200: sfp_detect, current sfp values written successfully to sfppresence file") + logger.log_debug("QFX5200: sfp_detect ret_dict is {}".format(ret_dict)) return True, ret_dict else: + logger.log_debug("QFX5200: sfp_detect, current sfp values not written to sfppresence file") + logger.log_debug("QFX5200: sfp_detect ret_dict is {}".format(def1_dict)) return False, defl_dict # Read out SFP type, vendor name, PN, REV, SN from eeprom. def get_transceiver_info_dict(self, port_num): transceiver_info_dict = {} compliance_code_dict = {} - + logger.log_debug("QFX5200: get_transceiver_info_dict Start") # ToDo: OSFP tranceiver info parsing not fully supported. # in inf8628.py lack of some memory map definition # will be implemented when the inf8628 memory map ready @@ -552,14 +643,14 @@ def get_transceiver_info_dict(self, port_num): transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_type_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] # Below part is added to avoid fail the xcvrd, shall be implemented later transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -652,13 +743,13 @@ def get_transceiver_info_dict(self, port_num): transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] @@ -700,14 +791,13 @@ def get_transceiver_info_dict(self, port_num): else: transceiver_info_dict['nominal_bit_rate'] = 'N/A' - sfp_pn_num = str(sfp_vendor_pn_data['data']['Vendor PN']['value']) - self.process_TxCTLE(port_num,sfp_pn_num) - + logger.log_debug("QFX5200: get_transceiver_info_dict End") return transceiver_info_dict def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict = {} + logger.log_debug("QFX5200: get_transceiver_dom_info_dict Start") if port_num in self.osfp_ports: # Below part is added to avoid fail xcvrd, shall be implemented later transceiver_dom_info_dict['temperature'] = 'N/A' @@ -877,8 +967,141 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx3power'] = 'N/A' transceiver_dom_info_dict['tx4power'] = 'N/A' + logger.log_debug("QFX5200: get_transceiver_dom_info_dict End") return transceiver_dom_info_dict + def get_transceiver_dom_threshold_info_dict(self, port_num): + transceiver_dom_threshold_info_dict = {} + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + logger.log_debug("QFX5200: get_transceiver_dom_threshold_info_dict Start") + if port_num in self.qsfp_ports: + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + #Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + logger.log_debug("QFX5200: get_transceiver_dom_threshold_info_dict End") + return transceiver_dom_threshold_info_dict + def get_transceiver_change_event(self, timeout=2000): time.sleep(3) return self.sfp_detect() + diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py index 59b1dfdb5875..545917a5eaae 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py +++ b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py @@ -5,13 +5,15 @@ from sonic_sfp.sfputilbase import * import sys import os + import io import string from ctypes import create_string_buffer - # sys.path.append('/usr/local/bin') - # import sfp_detect + from sonic_daemon_base.daemon_base import Logger except ImportError, e: raise ImportError (str(e) + "- required module not found") +SYSLOG_IDENTIFIER = "sfputil" +logger = Logger(SYSLOG_IDENTIFIER) qfx5210_qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', @@ -368,14 +370,14 @@ def get_transceiver_info_dict(self, port_num): transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_type_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] # Below part is added to avoid fail the xcvrd, shall be implemented later transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -470,13 +472,13 @@ def get_transceiver_info_dict(self, port_num): transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] @@ -694,3 +696,134 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx4power'] = 'N/A' return transceiver_dom_info_dict + + def get_transceiver_dom_threshold_info_dict(self, port_num): + transceiver_dom_threshold_info_dict = {} + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + logger.log_debug("QFX5210: get_transceiver_dom_threshold_info_dict Start") + if port_num in self.qsfp_ports: + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + #Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + logger.log_debug("QFX5210: get_transceiver_dom_threshold_info_dict End") + return transceiver_dom_threshold_info_dict diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install index 741b6da7b36a..285c07edd1a3 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install @@ -1,3 +1,6 @@ qfx5200/utils/juniper_qfx5200_util.py usr/local/bin qfx5200/utils/juniper_qfx5200_monitor.py usr/local/bin +qfx5200/utils/show_thresholds usr/local/bin +qfx5200/utils/temperature_thresholds_AFI.txt usr/local/bin +qfx5200/utils/temperature_thresholds_AFO.txt usr/local/bin qfx5200/service/qfx5200-platform-init.service etc/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds new file mode 100755 index 000000000000..2edb69de40a4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds @@ -0,0 +1,24 @@ +#!/usr/bin/env python +import commands +def main(): + FAN0_TYPE="cat /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan0_type" + + try: + status,fan0_type=commands.getstatusoutput(FAN0_TYPE) + except Exception as e: + print "Error on refpga-tmc.15 fan0_type e:" + str(e) + return False + + AFO = "1" + + if fan0_type == AFO: + temp_thres_file = open("/usr/local/bin/temperature_thresholds_AFO.txt", "r+") + print temp_thres_file.read() + else: + temp_thres_file = open("/usr/local/bin/temperature_thresholds_AFI.txt", "r+") + print temp_thres_file.read() + + temp_thres_file.close() + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFI.txt b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFI.txt new file mode 100755 index 000000000000..055bd850906a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFI.txt @@ -0,0 +1,27 @@ +Sensor # 35% 55% 75% 90% 100% Yellow Red Fire + Duty cycle Duty cycle Duty cycle Duty cycle Duty cycle Alarm Alarm Shutdown +================== ================================================================================================== +1 CPU <50 >=50 & <58 >=58 & 66 >=66 & <75 >=75 >86 >92 >95 + +2 (tmp435-i2c-7-48) <39 >=39 & <48 >=48 & <56 >=56 & <66 >=66 >64 >70 >73 + +3 (tmp435-i2c-7-49) <39 >=39 & <48 >=48 & <56 >=56 & <66 >=66 >64 >70 >73 + +4 BRCM TH1 ASIC <74 >=74 & <80 >=80 & <85 >=85 & <92 >=92 >99 >102 >105 + +5 (tmp435-i2c-5-48) <47 >=47 & <55 >=55 & <62 >=62 & <70 >=70 >68 >74 >77 + +6 (tmp435-i2c-5-49) <44 >=44 & <52 >=52 & <60 >=60 & <69 >=69 >67 >73 >76 + +7 (tmp435-i2c-5-4a) <57 >=57 & <63 >=63 & <68 >=68 & <74 >=74 >72 >78 >81 + +8 (tmp435-i2c-5-4b) <45 >=45 & <53 >=53 & <61 >=61 & <70 >=70 >68 >74 >77 + +9 (tmp435-i2c-6-48) <45 >=45 & <53 >=53 & <60 >=60 & <69 >=69 >67 >73 >76 + +10 (tmp435-i2c-6-49) <57 >=57 & <63 >=63 & <68 >=68 & <74 >=74 >72 >78 >81 + +11 (tmp435-i2c-6-4A) <48 >=48 & <55 >=55 & <62 >=62 & <70 >=70 >68 >74 >77 + +12 (tmp435-i2c-6-4B) <49 >=49 & <57 >=57 & <64 >=64 & <72 >=72 >70 >76 >79 + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFO.txt b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFO.txt new file mode 100755 index 000000000000..b7f489b5565a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFO.txt @@ -0,0 +1,27 @@ +Sensor # 35% 55% 75% 90% 100% Yellow Red Fire + Duty cycle Duty cycle Duty cycle Duty cycle Duty cycle Alarm Alarm Shutdown +================== ================================================================================================== +1 CPU <58 >=58 & <64 >=64 & <70 >=70 & <78 >=78 >86 >92 >95 + +2 (tmp435-i2c-7-48) <49 >=49 & <55 >=55 & <62 >=62 & <69 >=69 >67 >73 >76 + +3 (tmp435-i2c-7-49) <48 >=48 & <55 >=55 & <61 >=61 & <69 >=69 >67 >73 >76 + +4 BRCM TH1 ASIC <79 >=79 & <83 >=83 & <86 >=86 & <90 >=90 >99 >102 >105 + +5 (tmp435-i2c-5-48) <50 >=50 & <56 >=56 & <63 >=63 & <70 >=70 >68 >74 >77 + +6 (tmp435-i2c-5-49) <43 >=43 & <50 >=50 & <57 >=57 & <65 >=65 >63 >69 >72 + +7 (tmp435-i2c-5-4a) <54 >=54 & <60 >=60 & <65 >=65 & <71 >=71 >68 >74 >77 + +8 (tmp435-i2c-5-4b) <52 >=52 & <58 >=58 & <63 >=63 & <70 >=70 >68 >74 >77 + +9 (tmp435-i2c-6-48) <55 >=55 & <60 >=60 & <65 >=65 & <71 >=71 >65 >71 >78 + +10 (tmp435-i2c-6-49) <55 >=55 & <60 >=60 & <66 >=66 & <72 >=72 >70 >76 >79 + +11 (tmp435-i2c-6-4A) <47 >=47 & <54 >=54 & <60 >=60 & <67 >=67 >65 >71 >74 + +12 (tmp435-i2c-6-4B) <61 >=61 & <66 >=66 & <70 >=70 & <75 >=75 >73 >79 >82 + From df740b36535dc7826c8364e51da34cfc01df0da1 Mon Sep 17 00:00:00 2001 From: rkdevi27 <54701695+rkdevi27@users.noreply.github.com> Date: Wed, 15 Jul 2020 04:04:19 +0530 Subject: [PATCH 0910/1427] [baseimage]: /host unmount failed in VM during reboot (#4865) Added a check further to make the services to stop appropriately before unmount. Fix #4651 --- files/image_config/syslog/override.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/syslog/override.conf b/files/image_config/syslog/override.conf index 74f7aea9f076..5806cce0ecdc 100644 --- a/files/image_config/syslog/override.conf +++ b/files/image_config/syslog/override.conf @@ -1,5 +1,5 @@ [Unit] -After=var-log.mount host.mount +After=var-log.mount host.mount local-fs.target [Socket] ExecStopPre=/usr/bin/host_umount.sh journal_stop From 5f3c4fac4bd84784020b716f3ee7a527f52579cf Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Tue, 14 Jul 2020 15:36:47 -0700 Subject: [PATCH 0911/1427] [docker-orchagent] Call sonic-cfggen Once (#4936) Optimizing number of calls made to sonic-cfggen during service start up as it adds to total system boot up time. signed-off-by: Tamer Ahmed **- Why I did it** sonic-cfggen call is slow and it adds to system start up time **- How I did it** places all required variable into single template and called into sonic-cfggen using this template **- How to verify it** ***-Test 1*** there is an average saving of .5 to 1 sec between old script and new script ``` root@str-s6000-acs-14:/# time ./orchagent_old.sh /usr/bin/orchagent -d /var/log/swss -b 8192 -m f4:8e:38:16:bc:8d real 0m3.546s user 0m2.365s sys 0m0.585s root@str-s6000-acs-14:/# time ./orchagent_new.sh /usr/bin/orchagent -d /var/log/swss -b 8192 -m f4:8e:38:16:bc:8d real 0m2.058s user 0m1.650s sys 0m0.363s ``` ***-Test 2*** Built an image with this change and orchagent is running with intended params: ``` admin@str-s6000-acs-14:~$ ps -ef | grep orchagent root 2988 1901 1 02:09 pts/0 00:00:02 /usr/bin/orchagent -d /var/log/swss -b 8192 -m f4:8e:38:16:bc:8d ``` signed-off-by: Tamer Ahmed --- dockers/docker-orchagent/orchagent.sh | 20 ++++++++++++++------ dockers/docker-orchagent/swss_vars.j2 | 6 ++++++ 2 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 dockers/docker-orchagent/swss_vars.j2 diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 917205f3ebf2..a68f2d70fb13 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -1,10 +1,18 @@ #!/usr/bin/env bash -# Export platform information. Required to be able to write -# vendor specific code. -export platform=`sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type` +EXIT_SWSS_VARS_FILE_NOT_FOUND=1 +SWSS_VARS_FILE=/usr/share/sonic/templates/swss_vars.j2 -MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +if [ ! -f "$SWSS_VARS_FILE" ]; then + echo "SWSS vars template file not found" + exit $EXIT_SWSS_VARS_FILE_NOT_FOUND +fi + +# Retrieve SWSS vars from sonic-cfggen +SWSS_VARS=$(sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t $SWSS_VARS_FILE) +platform=$(echo $SWSS_VARS | jq -r '.asic_type') + +MAC_ADDRESS=$(echo $SWSS_VARS | jq -r '.mac') if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') logger "Mac address not found in Device Metadata, Falling back to eth0" @@ -27,7 +35,7 @@ ORCHAGENT_ARGS+="-b 8192 " # ID field could be integers just to denote the asic instance like 0,1,2... # OR could be PCI device ID's which will be strings like "03:00.0" # depending on what the SAI/SDK expects. -asic_id=`sonic-cfggen -d -v DEVICE_METADATA.localhost.asic_id` +asic_id=$(echo $SWSS_VARS | jq -r '.asic_id') if [ -n "$asic_id" ] then ORCHAGENT_ARGS+="-i $asic_id " @@ -51,7 +59,7 @@ elif [ "$platform" == "mellanox" ]; then elif [ "$platform" == "innovium" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" else - MAC_ADDRESS=`sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac'` + # Should we use the fallback MAC in case it is not found in Device.Metadata ORCHAGENT_ARGS+="-m $MAC_ADDRESS" fi diff --git a/dockers/docker-orchagent/swss_vars.j2 b/dockers/docker-orchagent/swss_vars.j2 new file mode 100644 index 000000000000..0a0b2712f46a --- /dev/null +++ b/dockers/docker-orchagent/swss_vars.j2 @@ -0,0 +1,6 @@ +{ + "asic_type": "{{ asic_type }}", + "asic_id": "{{ DEVICE_METADATA.localhost.asic_id }}", + "mac": "{{ DEVICE_METADATA.localhost.mac }}" +} + From 6ebcfb226b1828f2056815ee4548265e86b11ddb Mon Sep 17 00:00:00 2001 From: Sangita Maity Date: Tue, 14 Jul 2020 15:52:03 -0700 Subject: [PATCH 0912/1427] [docker-vs] Install dependencies for testing DPB (#4960) Added xmltodict and jsondiff packages needed to run vs test cases successfully for DPB. sonic-utilities PR #766 has a dependency on these packages. Signed-off-by: Sangita Maity --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index b58f7828187c..65253fc6a572 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -57,6 +57,10 @@ RUN pip install urllib3 RUN pip install requests RUN pip install crontab +# Install dependencies for Dynamic Port Breakout +RUN pip install xmltodict==0.12.0 +RUN pip install jsondiff==1.2.0 + {% if docker_sonic_vs_debs.strip() -%} # Copy locally-built Debian package dependencies {%- for deb in docker_sonic_vs_debs.split(' ') %} From ade634090de244f8c3cbd08059928db36a761dd9 Mon Sep 17 00:00:00 2001 From: madhanmellanox <62459540+madhanmellanox@users.noreply.github.com> Date: Wed, 15 Jul 2020 10:24:44 -0700 Subject: [PATCH 0913/1427] [caclmgrd] Log error message if IPv4 ACL table contains IPv6 rule and vice-versa (#4498) * Defect 2082949: Handling Control Plane ACLs so that IPv4 rules and IPv6 rules are not added to the same ACL table * Previous code review comments of coming up with functions for is_ipv4_rule and is_ipv6_rule is addressed and also raising Exceptions instead of simply aborting when the conflict occurs is handled * Addressed code review comment to replace duplicate code with already existing functions * removed raising Exception when rule conflict in Control plane ACLs are found * added code to remove the rule_props if it is conflicting ACL table versioning rule * addressed review comment to add ignoring rule in the error statement Co-authored-by: Madhan Babu --- files/image_config/caclmgrd/caclmgrd | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index b6d5cbe71398..3f0c7f93ffb0 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -168,6 +168,19 @@ class ControlPlaneAclManager(object): return block_ip2me_cmds + def is_rule_ipv4(self, rule_props): + if (("SRC_IP" in rule_props and rule_props["SRC_IP"]) or + ("DST_IP" in rule_props and rule_props["DST_IP"])): + return True + else: + return False + + def is_rule_ipv6(self, rule_props): + if (("SRC_IPV6" in rule_props and rule_props["SRC_IPV6"]) or + ("DST_IPV6" in rule_props and rule_props["DST_IPV6"])): + return True + else: + return False def get_acl_rules_and_translate_to_iptables_commands(self): """ @@ -295,13 +308,20 @@ class ControlPlaneAclManager(object): # try to do it now. We attempt to determine heuristically based on # whether the src or dst IP of this rule is an IPv4 or IPv6 address. if not table_ip_version: - if (("SRC_IPV6" in rule_props and rule_props["SRC_IPV6"]) or - ("DST_IPV6" in rule_props and rule_props["DST_IPV6"])): + if self.is_rule_ipv6(rule_props): table_ip_version = 6 - elif (("SRC_IP" in rule_props and rule_props["SRC_IP"]) or - ("DST_IP" in rule_props and rule_props["DST_IP"])): + elif self.is_rule_ipv4(rule_props): table_ip_version = 4 + if (self.is_rule_ipv6(rule_props) and (table_ip_version == 4)): + log_error("CtrlPlane ACL table {} is a IPv4 based table and rule {} is a IPV6 rule! Ignoring rule." + .format(table_name, rule_id)) + acl_rules.pop(rule_props["PRIORITY"]) + elif (self.is_rule_ipv4(rule_props) and (table_ip_version == 6)): + log_error("CtrlPlane ACL table {} is a IPv6 based table and rule {} is a IPV4 rule! Ignroing rule." + .format(table_name, rule_id)) + acl_rules.pop(rule_props["PRIORITY"]) + # If we were unable to determine whether this ACL table contains # IPv4 or IPv6 rules, log a message and skip processing this table. if not table_ip_version: From 545fe3ecd015abb4d2334ca7dd77cbca1da775f8 Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Wed, 15 Jul 2020 21:09:46 +0300 Subject: [PATCH 0914/1427] Add support for QSFP-DD cables on MLNX platform API (#4965) Signed-off-by: Shlomi Bitton --- .../mlnx-platform-api/sonic_platform/sfp.py | 561 ++++++++++++++++-- 1 file changed, 527 insertions(+), 34 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 254d9c2e3e58..2cfa98a7ebd2 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -19,6 +19,8 @@ from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId + from sonic_platform_base.sonic_sfp.qsfp_dd import qsfp_dd_InterfaceId + from sonic_platform_base.sonic_sfp.qsfp_dd import qsfp_dd_Dom from sonic_daemon_base.daemon_base import Logger from python_sdk_api.sxd_api import * from python_sdk_api.sx_api import * @@ -63,6 +65,27 @@ XCVR_VENDOR_DATE_WIDTH = 8 XCVR_DOM_CAPABILITY_OFFSET = 92 XCVR_DOM_CAPABILITY_WIDTH = 2 + +# definitions of the offset and width for values in XCVR_QSFP_DD info eeprom +XCVR_EXT_TYPE_OFFSET_QSFP_DD = 72 +XCVR_EXT_TYPE_WIDTH_QSFP_DD = 2 +XCVR_CONNECTOR_OFFSET_QSFP_DD = 75 +XCVR_CONNECTOR_WIDTH_QSFP_DD = 1 +XCVR_CABLE_LENGTH_OFFSET_QSFP_DD = 74 +XCVR_CABLE_LENGTH_WIDTH_QSFP_DD = 1 +XCVR_HW_REV_OFFSET_QSFP_DD = 36 +XCVR_HW_REV_WIDTH_QSFP_DD = 2 +XCVR_VENDOR_DATE_OFFSET_QSFP_DD = 54 +XCVR_VENDOR_DATE_WIDTH_QSFP_DD = 8 +XCVR_DOM_CAPABILITY_OFFSET_QSFP_DD = 2 +XCVR_DOM_CAPABILITY_WIDTH_QSFP_DD = 1 +XCVR_MEDIA_TYPE_OFFSET_QSFP_DD = 85 +XCVR_MEDIA_TYPE_WIDTH_QSFP_DD = 1 +XCVR_FIRST_APPLICATION_LIST_OFFSET_QSFP_DD = 86 +XCVR_FIRST_APPLICATION_LIST_WIDTH_QSFP_DD = 32 +XCVR_SECOND_APPLICATION_LIST_OFFSET_QSFP_DD = 351 +XCVR_SECOND_APPLICATION_LIST_WIDTH_QSFP_DD = 28 + # to improve performance we retrieve all eeprom data via a single ethtool command # in function get_transceiver_info and get_transceiver_bulk_status # XCVR_INTERFACE_DATA_SIZE stands for the max size to be read @@ -85,6 +108,9 @@ SFP_DOM_BULK_DATA_START = 96 SFP_DOM_BULK_DATA_SIZE = 10 +QSFP_DD_DOM_BULK_DATA_START = 14 +QSFP_DD_DOM_BULK_DATA_SIZE = 4 + # definitions of the offset for values in OSFP info eeprom OSFP_TYPE_OFFSET = 0 OSFP_VENDOR_NAME_OFFSET = 129 @@ -92,6 +118,13 @@ OSFP_HW_REV_OFFSET = 164 OSFP_VENDOR_SN_OFFSET = 166 +# definitions of the offset for values in QSFP_DD info eeprom +QSFP_DD_TYPE_OFFSET = 0 +QSFP_DD_VENDOR_NAME_OFFSET = 1 +QSFP_DD_VENDOR_PN_OFFSET = 20 +QSFP_DD_VENDOR_SN_OFFSET = 38 +QSFP_DD_VENDOR_OUI_OFFSET = 17 + #definitions of the offset and width for values in DOM info eeprom QSFP_DOM_REV_OFFSET = 1 QSFP_DOM_REV_WIDTH = 1 @@ -136,6 +169,29 @@ SFP_CHANNL_STATUS_OFFSET = 110 SFP_CHANNL_STATUS_WIDTH = 1 +QSFP_DD_TEMPE_OFFSET = 14 +QSFP_DD_TEMPE_WIDTH = 2 +QSFP_DD_VOLT_OFFSET = 16 +QSFP_DD_VOLT_WIDTH = 2 +QSFP_DD_TX_BIAS_OFFSET = 42 +QSFP_DD_TX_BIAS_WIDTH = 16 +QSFP_DD_RX_POWER_OFFSET = 58 +QSFP_DD_RX_POWER_WIDTH = 16 +QSFP_DD_TX_POWER_OFFSET = 26 +QSFP_DD_TX_POWER_WIDTH = 16 +QSFP_DD_CHANNL_MON_OFFSET = 154 +QSFP_DD_CHANNL_MON_WIDTH = 48 +QSFP_DD_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_DD_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_DD_CHANNL_RX_LOS_STATUS_OFFSET = 19 +QSFP_DD_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_DD_CHANNL_TX_FAULT_STATUS_OFFSET = 7 +QSFP_DD_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_DD_MODULE_THRESHOLD_OFFSET = 0 +QSFP_DD_MODULE_THRESHOLD_WIDTH = 72 +QSFP_DD_CHANNL_STATUS_OFFSET = 26 +QSFP_DD_CHANNL_STATUS_WIDTH = 1 + # identifier value of xSFP module which is in the first byte of the EEPROM # if the identifier value falls into SFP_TYPE_CODE_LIST the module is treated as a SFP module and parsed according to 8472 # for QSFP_TYPE_CODE_LIST the module is treated as a QSFP module and parsed according to 8436/8636 @@ -155,6 +211,9 @@ '0d', # QSFP+ or later '11' # QSFP28 or later ] +QSFP_DD_TYPE_CODE_LIST = [ + '18' # QSFP-DD Double Density 8X Pluggable Transceiver +] qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', @@ -179,6 +238,7 @@ SFP_TYPE = "SFP" QSFP_TYPE = "QSFP" OSFP_TYPE = "OSFP" +QSFP_DD_TYPE = "QSFP_DD" #variables for sdk REGISTER_NUM = 1 @@ -321,6 +381,8 @@ def _detect_sfp_type(self, sfp_type): self.sfp_type = SFP_TYPE elif eeprom_raw[0] in QSFP_TYPE_CODE_LIST: self.sfp_type = QSFP_TYPE + elif eeprom_raw[0] in QSFP_DD_TYPE_CODE_LIST: + self.sfp_type = QSFP_DD_TYPE else: # we don't regonize this identifier value, treat the xSFP module as the default type self.sfp_type = sfp_type @@ -339,6 +401,7 @@ def _dom_capability_detect(self): self.dom_temp_supported = False self.dom_volt_supported = False self.dom_rx_power_supported = False + self.dom_tx_bias_power_supported = False self.dom_tx_power_supported = False self.calibration = 0 return @@ -388,6 +451,46 @@ def _dom_capability_detect(self): self.dom_tx_power_supported = False self.calibration = 0 self.qsfp_page3_available = False + + elif self.sfp_type == QSFP_DD_TYPE: + sfpi_obj = qsfp_dd_InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + + offset = 0 + # two types of QSFP-DD cable types supported: Copper and Optical. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes((offset + XCVR_DOM_CAPABILITY_OFFSET_QSFP_DD), XCVR_DOM_CAPABILITY_WIDTH_QSFP_DD) + if qsfp_dom_capability_raw is not None: + self.dom_temp_supported = True + self.dom_volt_supported = True + dom_capability = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + if dom_capability['data']['Flat_MEM']['value'] == 'Off': + self.dom_supported = True + self.second_application_list = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + self.dom_tx_bias_power_supported = True + self.dom_thresholds_supported = True + #currently set to False becasue Page 11h is not supported by FW + self.dom_rx_tx_power_bias_supported = False + else: + self.dom_supported = False + self.second_application_list = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.dom_tx_bias_power_supported = False + self.dom_thresholds_supported = False + self.dom_rx_tx_power_bias_supported = False + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.dom_tx_bias_power_supported = False + self.dom_thresholds_supported = False + self.dom_rx_tx_power_bias_supported = False + elif self.sfp_type == SFP_TYPE: sfpi_obj = sff8472InterfaceId() if sfpi_obj is None: @@ -449,7 +552,7 @@ def get_transceiver_info(self): Returns: A dict which contains following keys/values : - ======================================================================== + ================================================================================ keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP @@ -466,7 +569,8 @@ def get_transceiver_info(self): specification_compliance |1*255VCHAR |specification compliance vendor_date |1*255VCHAR |vendor date vendor_oui |1*255VCHAR |vendor OUI - ======================================================================== + application_advertisement |1*255VCHAR |supported applications advertisement + ================================================================================ """ transceiver_info_dict = {} compliance_code_dict = {} @@ -513,13 +617,13 @@ def get_transceiver_info(self): return None transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -527,32 +631,148 @@ def get_transceiver_info(self): transceiver_info_dict['cable_length'] = 'N/A' transceiver_info_dict['specification_compliance'] = 'N/A' transceiver_info_dict['nominal_bit_rate'] = 'N/A' + transceiver_info_dict['application_advertisement'] = 'N/A' - else: - if self.sfp_type == QSFP_TYPE: - offset = 128 - vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP - cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP - interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP - sfp_type = 'QSFP' - - sfpi_obj = sff8436InterfaceId() - if sfpi_obj is None: - print("Error: sfp_object open failed") - return None + elif self.sfp_type == QSFP_TYPE: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + elif self.sfp_type == QSFP_DD_TYPE: + offset = 128 + + sfpi_obj = qsfp_dd_InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + sfp_type_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET_QSFP_DD), XCVR_HW_REV_WIDTH_QSFP_DD) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + else: + return None + + sfp_vendor_oui_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + else: + return None + + sfp_vendor_date_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET_QSFP_DD), XCVR_VENDOR_DATE_WIDTH_QSFP_DD) + if sfp_vendor_date_raw is not None: + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + else: + return None + + sfp_connector_raw = self._read_eeprom_specific_bytes((offset + XCVR_CONNECTOR_OFFSET_QSFP_DD), XCVR_CONNECTOR_WIDTH_QSFP_DD) + if sfp_connector_raw is not None: + sfp_connector_data = sfpi_obj.parse_connector(sfp_connector_raw, 0) + else: + return None + + sfp_ext_identifier_raw = self._read_eeprom_specific_bytes((offset + XCVR_EXT_TYPE_OFFSET_QSFP_DD), XCVR_EXT_TYPE_WIDTH_QSFP_DD) + if sfp_ext_identifier_raw is not None: + sfp_ext_identifier_data = sfpi_obj.parse_ext_iden(sfp_ext_identifier_raw, 0) + else: + return None + sfp_cable_len_raw = self._read_eeprom_specific_bytes((offset + XCVR_CABLE_LENGTH_OFFSET_QSFP_DD), XCVR_CABLE_LENGTH_WIDTH_QSFP_DD) + if sfp_cable_len_raw is not None: + sfp_cable_len_data = sfpi_obj.parse_cable_len(sfp_cable_len_raw, 0) else: - offset = 0 - vendor_rev_width = XCVR_HW_REV_WIDTH_SFP - cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP - interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP - sfp_type = 'SFP' - - sfpi_obj = sff8472InterfaceId() - if sfpi_obj is None: - print("Error: sfp_object open failed") + return None + + sfp_media_type_raw = self._read_eeprom_specific_bytes(XCVR_MEDIA_TYPE_OFFSET_QSFP_DD, XCVR_MEDIA_TYPE_WIDTH_QSFP_DD) + if sfp_media_type_raw is not None: + sfp_media_type_dict = sfpi_obj.parse_media_type(sfp_media_type_raw, 0) + if sfp_media_type_dict is None: return None + host_media_list = "" + sfp_application_type_first_list = self._read_eeprom_specific_bytes((XCVR_FIRST_APPLICATION_LIST_OFFSET_QSFP_DD), XCVR_FIRST_APPLICATION_LIST_WIDTH_QSFP_DD) + if self.second_application_list: + possible_application_count = 15 + sfp_application_type_second_list = self._read_eeprom_specific_bytes((XCVR_SECOND_APPLICATION_LIST_OFFSET_QSFP_DD), XCVR_SECOND_APPLICATION_LIST_WIDTH_QSFP_DD) + if sfp_application_type_first_list is not None and sfp_application_type_second_list is not None: + sfp_application_type_list = sfp_application_type_first_list + sfp_application_type_second_list + else: + return None + else: + possible_application_count = 8 + if sfp_application_type_first_list is not None: + sfp_application_type_list = sfp_application_type_first_list + else: + return None + + for i in range(0, possible_application_count): + if sfp_application_type_list[i * 4] == 'ff': + break + host_electrical, media_interface = sfpi_obj.parse_application(sfp_media_type_dict, sfp_application_type_list[i * 4], sfp_application_type_list[i * 4 + 1]) + host_media_list = host_media_list + host_electrical + ' - ' + media_interface + '\n\t\t\t\t ' + else: + return None + + transceiver_info_dict['type'] = str(sfp_type_data['data']['type']['value']) + transceiver_info_dict['manufacturer'] = str(sfp_vendor_name_data['data']['Vendor Name']['value']) + transceiver_info_dict['model'] = str(sfp_vendor_pn_data['data']['Vendor PN']['value']) + transceiver_info_dict['hardware_rev'] = str(sfp_vendor_rev_data['data']['Vendor Rev']['value']) + transceiver_info_dict['serial'] = str(sfp_vendor_sn_data['data']['Vendor SN']['value']) + transceiver_info_dict['vendor_oui'] = str(sfp_vendor_oui_data['data']['Vendor OUI']['value']) + transceiver_info_dict['vendor_date'] = str(sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value']) + transceiver_info_dict['connector'] = str(sfp_connector_data['data']['Connector']['value']) + transceiver_info_dict['encoding'] = "Not supported for CMIS cables" + transceiver_info_dict['ext_identifier'] = str(sfp_ext_identifier_data['data']['Extended Identifier']['value']) + transceiver_info_dict['ext_rateselect_compliance'] = "Not supported for CMIS cables" + transceiver_info_dict['specification_compliance'] = "Not supported for CMIS cables" + transceiver_info_dict['cable_type'] = "Length Cable Assembly(m)" + transceiver_info_dict['cable_length'] = str(sfp_cable_len_data['data']['Length Cable Assembly(m)']['value']) + transceiver_info_dict['nominal_bit_rate'] = "Not supported for CMIS cables" + transceiver_info_dict['application_advertisement'] = host_media_list + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + if self.sfp_type != QSFP_DD_TYPE: sfp_interface_bulk_raw = self._read_eeprom_specific_bytes(offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) if sfp_interface_bulk_raw is None: return None @@ -586,16 +806,17 @@ def get_transceiver_info(self): sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_interface_bulk_raw[start : end], 0) transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['application_advertisement'] = 'N/A' if self.sfp_type == QSFP_TYPE: for key in qsfp_cable_length_tup: @@ -659,10 +880,16 @@ def get_transceiver_bulk_status(self): dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', 'rx2power', 'rx3power', 'rx4power', + 'rx5power', 'rx6power', + 'rx7power', 'rx8power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', + 'tx5bias', 'tx6bias', + 'tx7bias', 'tx8bias', 'tx1power', 'tx2power', - 'tx3power', 'tx4power' + 'tx3power', 'tx4power', + 'tx5power', 'tx6power', + 'tx7power', 'tx8power' ] transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') @@ -719,6 +946,72 @@ def get_transceiver_bulk_status(self): transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + elif self.sfp_type == QSFP_DD_TYPE: + + offset = 0 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_data_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_DOM_BULK_DATA_START), QSFP_DD_DOM_BULK_DATA_SIZE) + if dom_data_raw is None: + return transceiver_dom_info_dict + + if self.dom_temp_supported: + start = QSFP_DD_TEMPE_OFFSET - QSFP_DD_DOM_BULK_DATA_START + end = start + QSFP_DD_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature(dom_data_raw[start : end], 0) + temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + if temp is not None: + transceiver_dom_info_dict['temperature'] = temp + + if self.dom_volt_supported: + start = QSFP_DD_VOLT_OFFSET - QSFP_DD_DOM_BULK_DATA_START + end = start + QSFP_DD_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage(dom_data_raw[start : end], 0) + volt = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + if volt is not None: + transceiver_dom_info_dict['voltage'] = volt + + if self.dom_rx_tx_power_bias_supported: + # page 11h + dom_data_raw = self._read_eeprom_specific_bytes((QSFP_DD_CHANNL_MON_OFFSET), QSFP_DD_CHANNL_MON_WIDTH) + if dom_data_raw is None: + return transceiver_dom_info_dict + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_data_raw, 0) + + if self.dom_tx_power_supported: + transceiver_dom_info_dict['tx1power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Power']['value'])) + transceiver_dom_info_dict['tx2power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Power']['value'])) + transceiver_dom_info_dict['tx3power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Power']['value'])) + transceiver_dom_info_dict['tx4power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Power']['value'])) + transceiver_dom_info_dict['tx5power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX5Power']['value'])) + transceiver_dom_info_dict['tx6power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX6Power']['value'])) + transceiver_dom_info_dict['tx7power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX7Power']['value'])) + transceiver_dom_info_dict['tx8power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX8Power']['value'])) + + if self.dom_rx_power_supported: + transceiver_dom_info_dict['rx1power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX1Power']['value'])) + transceiver_dom_info_dict['rx2power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX2Power']['value'])) + transceiver_dom_info_dict['rx3power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX3Power']['value'])) + transceiver_dom_info_dict['rx4power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX4Power']['value'])) + transceiver_dom_info_dict['rx5power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX5Power']['value'])) + transceiver_dom_info_dict['rx6power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX6Power']['value'])) + transceiver_dom_info_dict['rx7power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX7Power']['value'])) + transceiver_dom_info_dict['rx8power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX8Power']['value'])) + + if self.dom_tx_bias_power_supported: + transceiver_dom_info_dict['tx1bias'] = str(dom_channel_monitor_data['data']['TX1Bias']['value']) + transceiver_dom_info_dict['tx2bias'] = str(dom_channel_monitor_data['data']['TX2Bias']['value']) + transceiver_dom_info_dict['tx3bias'] = str(dom_channel_monitor_data['data']['TX3Bias']['value']) + transceiver_dom_info_dict['tx4bias'] = str(dom_channel_monitor_data['data']['TX4Bias']['value']) + transceiver_dom_info_dict['tx5bias'] = str(dom_channel_monitor_data['data']['TX5Bias']['value']) + transceiver_dom_info_dict['tx6bias'] = str(dom_channel_monitor_data['data']['TX6Bias']['value']) + transceiver_dom_info_dict['tx7bias'] = str(dom_channel_monitor_data['data']['TX7Bias']['value']) + transceiver_dom_info_dict['tx8bias'] = str(dom_channel_monitor_data['data']['TX8Bias']['value']) + + return transceiver_dom_info_dict + else: if not self.dom_supported: return transceiver_dom_info_dict @@ -846,6 +1139,47 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + elif self.sfp_type == QSFP_DD_TYPE: + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + if not self.dom_thresholds_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # page 02 + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_MODULE_THRESHOLD_OFFSET), QSFP_DD_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['TxBiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TxPowerLowWarning']['value'] + else: offset = SFP_MODULE_ADDRA2_OFFSET @@ -929,7 +1263,16 @@ def get_reset_status(self): return True else: return False + elif self.sfp_type == QSFP_DD_TYPE: + offset = 0 + sfpd_obj = qsfp_dd_InterfaceId() + dom_channel_status_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_CHANNL_STATUS_OFFSET), QSFP_DD_CHANNL_STATUS_WIDTH) + + if dom_channel_status_raw is None: + return False + dom_channel_status_data = sfpd_obj.parse_dom_channel_status(dom_channel_status_raw, 0) + return dom_channel_status_data['data']['Status']['value'] == 'On' def get_rx_los(self): """ @@ -954,6 +1297,23 @@ def get_rx_los(self): rx_los_list.append(rx_los_data & 0x02 != 0) rx_los_list.append(rx_los_data & 0x04 != 0) rx_los_list.append(rx_los_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 128 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_DD_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 8) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + rx_los_list.append(rx_los_data & 0x10 != 0) + rx_los_list.append(rx_los_data & 0x20 != 0) + rx_los_list.append(rx_los_data & 0x40 != 0) + rx_los_list.append(rx_los_data & 0x80 != 0) + else: offset = 256 dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) @@ -988,6 +1348,24 @@ def get_tx_fault(self): tx_fault_list.append(tx_fault_data & 0x02 != 0) tx_fault_list.append(tx_fault_data & 0x04 != 0) tx_fault_list.append(tx_fault_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + return None + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 128 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_DD_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 8) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + tx_fault_list.append(tx_fault_data & 0x10 != 0) + tx_fault_list.append(tx_fault_data & 0x20 != 0) + tx_fault_list.append(tx_fault_data & 0x40 != 0) + tx_fault_list.append(tx_fault_data & 0x80 != 0) + else: offset = 256 dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) @@ -1025,6 +1403,22 @@ def get_tx_disable(self): tx_disable_list.append(tx_disable_data & 0x02 != 0) tx_disable_list.append(tx_disable_data & 0x04 != 0) tx_disable_list.append(tx_disable_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + if self.dom_rx_tx_power_bias_supported: + offset = 128 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_CHANNL_DISABLE_STATUS_OFFSET), QSFP_DD_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + tx_disable_list.append(tx_disable_data & 0x10 != 0) + tx_disable_list.append(tx_disable_data & 0x20 != 0) + tx_disable_list.append(tx_disable_data & 0x40 != 0) + tx_disable_list.append(tx_disable_data & 0x80 != 0) + else: offset = 256 dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) @@ -1135,6 +1529,22 @@ def get_temperature(self): return None else: return None + + elif self.sfp_type == QSFP_DD_TYPE: + offset = 0 + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_TEMPE_OFFSET), QSFP_DD_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + return temp + return None + else: offset = 256 sfpd_obj = sff8472Dom() @@ -1177,6 +1587,22 @@ def get_voltage(self): else: return None return None + + if self.sfp_type == QSFP_DD_TYPE: + offset = 128 + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_volt_supported: + dom_voltage_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_VOLT_OFFSET), QSFP_DD_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + return voltage + return None + else: offset = 256 @@ -1220,6 +1646,28 @@ def get_tx_bias(self): tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Bias']['value'])) tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Bias']['value'])) tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Bias']['value'])) + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 128 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if dom_tx_bias_power_supported: + dom_tx_bias_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_TX_BIAS_OFFSET), QSFP_DD_TX_BIAS_WIDTH) + if dom_tx_bias_raw is not None: + dom_tx_bias_data = sfpd_obj.parse_dom_tx_bias(dom_tx_bias_raw, 0) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX4Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX5Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX6Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX7Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX8Bias']['value'])) + else: offset = 256 @@ -1275,6 +1723,28 @@ def get_rx_power(self): return None else: return None + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11 + if self.dom_rx_tx_power_bias_supported: + offset = 128 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_rx_power_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_RX_POWER_OFFSET), QSFP_DD_RX_POWER_WIDTH) + if dom_rx_power_raw is not None: + dom_rx_power_data = sfpd_obj.parse_dom_rx_power(dom_rx_power_raw, 0) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX1Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX2Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX3Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX4Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX5Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX6Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX7Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX8Power']['value'])) + else: offset = 256 @@ -1330,6 +1800,29 @@ def get_tx_power(self): return None else: return None + + elif self.sfp_type == QSFP_DD_TYPE: + return None + # page 11 + if self.dom_rx_tx_power_bias_supported: + offset = 128 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_tx_power_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_TX_POWER_OFFSET), QSFP_DD_TX_POWER_WIDTH) + if dom_tx_power_raw is not None: + dom_tx_power_data = sfpd_obj.parse_dom_tx_power(dom_tx_power_raw, 0) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX4Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX5Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX6Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX7Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX8Power']['value'])) + else: offset = 256 sfpd_obj = sff8472Dom() From de51b9e42424f0c2c7bb03fb13409620c8ea17a4 Mon Sep 17 00:00:00 2001 From: heidinet2007 <43017482+heidinet2007@users.noreply.github.com> Date: Wed, 15 Jul 2020 11:46:23 -0700 Subject: [PATCH 0915/1427] BGP warm reboot script to service (#3992) * [sonic-buildimage] Move BGP warm reboot scripts into BGP service /usr/local/bin * Revert "[sonic-buildimage] Move BGP warm reboot scripts into BGP service /usr/local/bin" This reverts commit d16d163fc41c34e129cdfa61d3f27ad51984b197. * [sonic-buildimage] Move BGP warm reboot script to BGP service * [sonic-buildimage] Move BGP warm reboot script to BGP service * [sonic-buildimage] Move BGP warm reboot script to BGP service - access DB correctly * Address code review comments, also change file mode of bgp.sh (+x) * Address code review comments, also change the file mode of bgp.sh (+x) * BGP warm reboot script to service, also handle fast boot as indicated by flag saved in StateDB * BGP warm reboot script to service, code review comments on space alignment * BGP warm reboot script to service: remove uncesseary space * BGP warm reboot script to service: replace tab with space * Code review comments: -) use new multi-db api -) add ignore error from zebra in case it's not configured * Integrate with multi-ASIC changes committed recently Co-authored-by: heidi.ou@alibaba-inc.com --- .../build_templates/sonic_debian_extension.j2 | 1 + files/scripts/bgp.sh | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100755 files/scripts/bgp.sh diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index fd8ccb02f47f..1732580b5ac8 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -527,6 +527,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys # Copy swss and syncd service script sudo LANG=C cp $SCRIPTS_DIR/swss.sh $FILESYSTEM_ROOT/usr/local/bin/swss.sh sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh +sudo LANG=C cp $SCRIPTS_DIR/bgp.sh $FILESYSTEM_ROOT/usr/local/bin/bgp.sh # Copy sonic-netns-exec script sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netns-exec diff --git a/files/scripts/bgp.sh b/files/scripts/bgp.sh new file mode 100755 index 000000000000..5da8c35cf064 --- /dev/null +++ b/files/scripts/bgp.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +function debug() +{ + /usr/bin/logger $1 + /bin/echo `date` "- $1" >> ${DEBUGLOG} +} + +function check_warm_boot() +{ + SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then + WARM_BOOT="true" + else + WARM_BOOT="false" + fi +} + +function validate_restore_count() +{ + if [[ x"$WARM_BOOT" == x"true" ]]; then + RESTORE_COUNT=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_TABLE|bgp" restore_count` + # We have to make sure db data has not been flushed. + if [[ -z "$RESTORE_COUNT" ]]; then + WARM_BOOT="false" + fi + fi +} + +function check_fast_boot () +{ + if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + FAST_BOOT = "true" + else + FAST_BOOT = "false" + fi +} + +start() { + debug "Starting ${SERVICE}$DEV service..." + + check_warm_boot + validate_restore_count + + check_fast_boot + + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Fast boot flag: ${SERVICE}$DEV ${Fast_BOOT}." + + # start service docker + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE}$DEV service..." + +} + +wait() { + /usr/bin/${SERVICE}.sh wait $DEV +} + +stop() { + debug "Stopping ${SERVICE}$DEV service..." + + check_warm_boot + check_fast_boot + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Fast boot flag: ${SERVICE}$DEV ${FAST_BOOT}." + + # Kill bgpd to start the bgp graceful restart procedure + if [[ x"$WARM_BOOT" == x"true" ]] || [[ x"$FAST_BOOT" == x"true" ]]; then + debug "Kill zebra first" + /usr/bin/docker exec -i bgp pkill -9 zebra || [ $? == 1 ] + /usr/bin/docker exec -i bgp pkill -9 bgpd || [ $? == 1 ] + fi + + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." + +} + +DEV=$2 + +SERVICE="bgp" +DEBUGLOG="/tmp/bgp-debug$DEV.log" +NAMESPACE_PREFIX="asic" +if [ "$DEV" ]; then + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" +else + NET_NS="" + SONIC_DB_CLI="sonic-db-cli" +fi + +case "$1" in + start|wait|stop) + $1 + ;; + *) + echo "Usage: $0 {start|wait|stop}" + exit 1 + ;; +esac From 83738fca2f174289d793459fac457391f982748f Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Wed, 15 Jul 2020 11:49:14 -0700 Subject: [PATCH 0916/1427] [dockers] Default container autorestart feature to "enabled" for all except database (#4853) Set the default auto_restart state to "enabled" in init_cfg.json for all containers except database Signed-off-by: Yong Zhao --- files/build_templates/init_cfg.json.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 7a0a8d15880d..90980fe069a6 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -28,7 +28,7 @@ {%- for container in ["bgp", "database", "dhcp_relay", "lldp", "nat", "pmon", "radv", "restapi", "sflow", "snmp", "swss", "syncd", "teamd", "telemetry"] %} "{{container}}": { - "auto_restart": "disabled", + "auto_restart": "{% if container == "database" %}disabled{% else %}enabled{% endif %}", "high_mem_alert": "disabled" }{% if not loop.last %},{% endif -%} {% endfor %} From 1ca47da40d16cfe5acb05204eaf1817b662516e1 Mon Sep 17 00:00:00 2001 From: taochengyi <54564117+taocy001@users.noreply.github.com> Date: Thu, 16 Jul 2020 03:23:20 +0800 Subject: [PATCH 0917/1427] [build][arm] Adding a backport source to arm to resolve docker-base-stretch install redis-tools=5:5.0.3-3~bpo9+2 failure issue (#4950) --- dockers/docker-base-buster/sources.list.arm64 | 1 + dockers/docker-base-buster/sources.list.armhf | 1 + dockers/docker-base-stretch/sources.list.arm64 | 1 + dockers/docker-base-stretch/sources.list.armhf | 1 + 4 files changed, 4 insertions(+) diff --git a/dockers/docker-base-buster/sources.list.arm64 b/dockers/docker-base-buster/sources.list.arm64 index b92971dccead..d4450c25952e 100644 --- a/dockers/docker-base-buster/sources.list.arm64 +++ b/dockers/docker-base-buster/sources.list.arm64 @@ -5,3 +5,4 @@ deb [arch=arm64] http://deb.debian.org/debian buster main contrib non-free deb-src [arch=arm64] http://deb.debian.org/debian buster main contrib non-free deb [arch=arm64] http://security.debian.org buster/updates main contrib non-free deb-src [arch=arm64] http://security.debian.org buster/updates main contrib non-free +deb [arch=arm64] http://deb.debian.org/debian/ buster-backports main contrib non-free diff --git a/dockers/docker-base-buster/sources.list.armhf b/dockers/docker-base-buster/sources.list.armhf index e28fd605678f..a053a509e148 100644 --- a/dockers/docker-base-buster/sources.list.armhf +++ b/dockers/docker-base-buster/sources.list.armhf @@ -5,3 +5,4 @@ deb [arch=armhf] http://deb.debian.org/debian buster main contrib non-free deb-src [arch=armhf] http://deb.debian.org/debian buster main contrib non-free deb [arch=armhf] http://security.debian.org buster/updates main contrib non-free deb-src [arch=armhf] http://security.debian.org buster/updates main contrib non-free +deb [arch=armhf] http://deb.debian.org/debian/ buster-backports main contrib non-free diff --git a/dockers/docker-base-stretch/sources.list.arm64 b/dockers/docker-base-stretch/sources.list.arm64 index b2e0a329d0b1..f5fe1d391427 100644 --- a/dockers/docker-base-stretch/sources.list.arm64 +++ b/dockers/docker-base-stretch/sources.list.arm64 @@ -5,3 +5,4 @@ deb [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free deb-src [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free deb [arch=arm64] http://security.debian.org stretch/updates main contrib non-free deb-src [arch=arm64] http://security.debian.org stretch/updates main contrib non-free +deb [arch=arm64] http://deb.debian.org/debian/ stretch-backports main contrib non-free diff --git a/dockers/docker-base-stretch/sources.list.armhf b/dockers/docker-base-stretch/sources.list.armhf index 884a091175ab..90c4d351f09c 100644 --- a/dockers/docker-base-stretch/sources.list.armhf +++ b/dockers/docker-base-stretch/sources.list.armhf @@ -5,3 +5,4 @@ deb [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free deb-src [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free deb [arch=armhf] http://security.debian.org stretch/updates main contrib non-free deb-src [arch=armhf] http://security.debian.org stretch/updates main contrib non-free +deb [arch=armhf] http://deb.debian.org/debian/ stretch-backports main contrib non-free From 18bfa6df0823ee25742e6efe1a57ba78a4046cb8 Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Wed, 15 Jul 2020 22:48:09 -0700 Subject: [PATCH 0918/1427] [docker-nat]: upgrade docker-nat to buster (#4943) move iptables to 1.8.2-4 (version in buster) Signed-off-by: Joyas Joseph --- dockers/docker-nat/Dockerfile.j2 | 2 +- rules/docker-nat.mk | 8 +- rules/iptables.mk | 4 +- ...ng-fullcone-option-for-SNAT-and-DNAT.patch | 110 +++++++++++++----- 4 files changed, 88 insertions(+), 36 deletions(-) diff --git a/dockers/docker-nat/Dockerfile.j2 b/dockers/docker-nat/Dockerfile.j2 index 30f4cd1c0cb8..38930f7860e1 100644 --- a/dockers/docker-nat/Dockerfile.j2 +++ b/dockers/docker-nat/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk index b421bfd886cf..9738903a0fc8 100644 --- a/rules/docker-nat.mk +++ b/rules/docker-nat.mk @@ -7,22 +7,20 @@ DOCKER_NAT_DBG = $(DOCKER_NAT_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_NAT)_PATH = $(DOCKERS_PATH)/$(DOCKER_NAT_STEM) $(DOCKER_NAT)_DEPENDS += $(SWSS) $(IPTABLESIP4TC) $(IPTABLESIP6TC) $(IPTABLESIPTC) $(IPXTABLES12) $(IPTABLES) -$(DOCKER_NAT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_NAT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_NAT)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) -$(DOCKER_NAT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_NAT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_NAT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_NAT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) ifeq ($(ENABLE_NAT), y) SONIC_DOCKER_IMAGES += $(DOCKER_NAT) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_NAT) -SONIC_STRETCH_DOCKERS += $(DOCKER_NAT) endif ifeq ($(ENABLE_NAT), y) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_NAT_DBG) endif $(DOCKER_NAT)_CONTAINER_NAME = nat diff --git a/rules/iptables.mk b/rules/iptables.mk index a166f5817a8b..fcdcc3434e08 100644 --- a/rules/iptables.mk +++ b/rules/iptables.mk @@ -1,7 +1,7 @@ # iptables package -IPTABLES_VERSION = 1.6.0+snapshot20161117 -IPTABLES_VERSION_SUFFIX = 6 +IPTABLES_VERSION = 1.8.2 +IPTABLES_VERSION_SUFFIX = 4 IPTABLES_VERSION_FULL = $(IPTABLES_VERSION)-$(IPTABLES_VERSION_SUFFIX) IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb diff --git a/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch index 528ce8edea2d..9ed886bb5dbd 100644 --- a/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch +++ b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch @@ -10,7 +10,7 @@ Subject: [PATCH] Passing fullcone option for SNAT and DNAT 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c -index a14d16f..4bfab98 100644 +index 4907a2e..543421c 100644 --- a/extensions/libipt_DNAT.c +++ b/extensions/libipt_DNAT.c @@ -8,14 +8,20 @@ @@ -42,8 +42,17 @@ index a14d16f..4bfab98 100644 +"[--random] [--persistent] [--fullcone]\n"); } + static void DNAT_help_v2(void) +@@ -41,7 +47,7 @@ static void DNAT_help_v2(void) + "DNAT target options:\n" + " --to-destination [[-]][:port[-port[/port]]]\n" + " Address to map destination to.\n" +-"[--random] [--persistent]\n"); ++"[--random] [--persistent] [--fullcone]\n"); + } + static const struct xt_option_entry DNAT_opts[] = { -@@ -40,6 +46,7 @@ static const struct xt_option_entry DNAT_opts[] = { +@@ -49,6 +55,7 @@ static const struct xt_option_entry DNAT_opts[] = { .flags = XTOPT_MAND | XTOPT_MULTI}, {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, {.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE}, @@ -51,7 +60,7 @@ index a14d16f..4bfab98 100644 XTOPT_TABLEEND, }; -@@ -185,10 +192,14 @@ static void DNAT_parse(struct xt_option_call *cb) +@@ -194,10 +201,14 @@ static void DNAT_parse(struct xt_option_call *cb) static void DNAT_fcheck(struct xt_fcheck_call *cb) { static const unsigned int f = F_TO_DEST | F_RANDOM; @@ -66,7 +75,7 @@ index a14d16f..4bfab98 100644 } static void print_range(const struct nf_nat_ipv4_range *r) -@@ -224,6 +235,8 @@ static void DNAT_print(const void *ip, const struct xt_entry_target *target, +@@ -233,6 +244,8 @@ static void DNAT_print(const void *ip, const struct xt_entry_target *target, printf(" random"); if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) printf(" persistent"); @@ -75,7 +84,7 @@ index a14d16f..4bfab98 100644 } } -@@ -239,6 +252,8 @@ static void DNAT_save(const void *ip, const struct xt_entry_target *target) +@@ -248,6 +261,8 @@ static void DNAT_save(const void *ip, const struct xt_entry_target *target) printf(" --random"); if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) printf(" --persistent"); @@ -84,7 +93,7 @@ index a14d16f..4bfab98 100644 } } -@@ -282,6 +297,11 @@ static int DNAT_xlate(struct xt_xlate *xl, +@@ -291,6 +306,11 @@ static int DNAT_xlate(struct xt_xlate *xl, sep = ","; xt_xlate_add(xl, "%spersistent", sep); } @@ -96,11 +105,56 @@ index a14d16f..4bfab98 100644 } return 1; +@@ -426,10 +446,14 @@ static void DNAT_parse_v2(struct xt_option_call *cb) + static void DNAT_fcheck_v2(struct xt_fcheck_call *cb) + { + static const unsigned int f = F_TO_DEST | F_RANDOM; ++ static const unsigned int c = F_FULLCONE; + struct nf_nat_range2 *range = cb->data; + + if ((cb->xflags & f) == f) + range->flags |= NF_NAT_RANGE_PROTO_RANDOM; ++ ++ if ((cb->xflags & c) == c) ++ range->flags |= NF_NAT_RANGE_FULLCONE; + } + + static void print_range_v2(const struct nf_nat_range2 *range) +@@ -461,6 +485,8 @@ static void DNAT_print_v2(const void *ip, const struct xt_entry_target *target, + printf(" random"); + if (range->flags & NF_NAT_RANGE_PERSISTENT) + printf(" persistent"); ++ if (range->flags & NF_NAT_RANGE_FULLCONE) ++ printf(" fullcone"); + } + + static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target) +@@ -473,6 +499,8 @@ static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target) + printf(" --random"); + if (range->flags & NF_NAT_RANGE_PERSISTENT) + printf(" --persistent"); ++ if (range->flags & NF_NAT_RANGE_FULLCONE) ++ printf(" --fullcone"); + } + + static void print_range_xlate_v2(const struct nf_nat_range2 *range, +@@ -512,6 +540,11 @@ static int DNAT_xlate_v2(struct xt_xlate *xl, + sep = ","; + xt_xlate_add(xl, "%spersistent", sep); + } ++ if (range->flags & NF_NAT_RANGE_FULLCONE) { ++ if (sep_need) ++ sep = ","; ++ xt_xlate_add(xl, "%sfullcone", sep); ++ } + + return 1; + } diff --git a/extensions/libipt_MASQUERADE.c b/extensions/libipt_MASQUERADE.c -index b7b5fc7..88ff650 100644 +index 90bf606..169457d 100644 --- a/extensions/libipt_MASQUERADE.c +++ b/extensions/libipt_MASQUERADE.c -@@ -8,9 +8,15 @@ +@@ -8,10 +8,15 @@ #include #include @@ -111,17 +165,17 @@ index b7b5fc7..88ff650 100644 enum { O_TO_PORTS = 0, O_RANDOM, -+ O_RANDOM_FULLY, + O_RANDOM_FULLY, + O_FULLCONE }; static void MASQUERADE_help(void) -@@ -20,12 +26,15 @@ static void MASQUERADE_help(void) - " --to-ports [-]\n" - " Port (range) to map to.\n" +@@ -23,13 +28,16 @@ static void MASQUERADE_help(void) " --random\n" --" Randomize source port.\n"); -+" Randomize source port.\n" + " Randomize source port.\n" + " --random-fully\n" +-" Fully randomize source port.\n"); ++" Fully randomize source port.\n" +" --fullcone\n" +" Do fullcone NAT mapping.\n"); } @@ -129,13 +183,14 @@ index b7b5fc7..88ff650 100644 static const struct xt_option_entry MASQUERADE_opts[] = { {.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING}, {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, + {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE}, + {.name = "fullcone", .id = O_FULLCONE, .type = XTTYPE_NONE}, XTOPT_TABLEEND, }; -@@ -97,6 +106,9 @@ static void MASQUERADE_parse(struct xt_option_call *cb) - case O_RANDOM: - mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM; +@@ -104,6 +112,9 @@ static void MASQUERADE_parse(struct xt_option_call *cb) + case O_RANDOM_FULLY: + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; break; + case O_FULLCONE: + mr->range[0].flags |= NF_NAT_RANGE_FULLCONE; @@ -143,25 +198,27 @@ index b7b5fc7..88ff650 100644 } } -@@ -116,6 +128,8 @@ MASQUERADE_print(const void *ip, const struct xt_entry_target *target, +@@ -126,6 +137,9 @@ MASQUERADE_print(const void *ip, const struct xt_entry_target *target, - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) - printf(" random"); + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) + printf(" random-fully"); ++ + if (r->flags & NF_NAT_RANGE_FULLCONE) + printf(" fullcone"); } static void -@@ -132,6 +146,8 @@ MASQUERADE_save(const void *ip, const struct xt_entry_target *target) +@@ -145,6 +159,9 @@ MASQUERADE_save(const void *ip, const struct xt_entry_target *target) - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) - printf(" --random"); + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) + printf(" --random-fully"); ++ + if (r->flags & NF_NAT_RANGE_FULLCONE) + printf(" --fullcone"); } static int MASQUERADE_xlate(struct xt_xlate *xl, -@@ -153,6 +169,9 @@ static int MASQUERADE_xlate(struct xt_xlate *xl, +@@ -166,6 +183,9 @@ static int MASQUERADE_xlate(struct xt_xlate *xl, if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) xt_xlate_add(xl, "random "); @@ -172,7 +229,7 @@ index b7b5fc7..88ff650 100644 } diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c -index e92d811..9634ba9 100644 +index e92d811..ad42b8c 100644 --- a/extensions/libipt_SNAT.c +++ b/extensions/libipt_SNAT.c @@ -8,16 +8,22 @@ @@ -262,6 +319,3 @@ index e92d811..9634ba9 100644 } return 1; --- -2.18.0 - From 9905d9382d689ada9cc6c49bbdf8beea13417fba Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 16 Jul 2020 13:03:50 -0700 Subject: [PATCH 0919/1427] [devices] Update SFP keys to align with new standard (#4975) Align SFP key names with new standard defined in https://github.com/Azure/sonic-platform-common/pull/97 - hardwarerev -> hardware_rev - serialnum -> serial - manufacturename -> manufacturer - modelname -> model - Connector -> connector --- .../sonic_platform/sfp.py | 46 +++++++++---------- .../x86_64-cel_e1031-r0/sonic_platform/sfp.py | 26 +++++------ .../sonic_platform/sfp.py | 36 +++++++-------- .../sonic_platform/sfp.py | 36 +++++++-------- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 20 ++++---- .../s5232f/sonic_platform/sfp.py | 46 +++++++++---------- .../s6000/sonic_platform/sfp.py | 38 +++++++-------- .../s6100/sonic_platform/sfp.py | 36 +++++++-------- .../z9100/sonic_platform/sfp.py | 36 +++++++-------- .../z9264f/sonic_platform/sfp.py | 46 +++++++++---------- .../d6356/sonic_platform/qsfp.py | 38 +++++++-------- .../d6356/sonic_platform/sfp.py | 38 +++++++-------- .../d7054q28b/sonic_platform/sfp.py | 32 ++++++------- .../mlnx-platform-api/sonic_platform/sfp.py | 10 ++-- 14 files changed, 242 insertions(+), 242 deletions(-) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py index be1dbb52a79b..2871172755a9 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py @@ -195,7 +195,7 @@ def __init__(self, sfp_index, sfp_type): self.port_to_eeprom_mapping[p_num] = eeprom_path.format( self.port_to_i2c_mapping[p_num]) - self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', @@ -308,11 +308,11 @@ def get_sfp_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -371,17 +371,17 @@ def get_sfp_transceiver_info(self): if sfp_interface_bulk_data: transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[ + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data[ 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' @@ -562,11 +562,11 @@ def get_qsfp_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -625,17 +625,17 @@ def get_qsfp_transceiver_info(self): if sfp_interface_bulk_data: transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[ + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data[ 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' @@ -1121,7 +1121,7 @@ def get_model(self): string: Model/part number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("modelname", "N/A") + return transceiver_dom_info_dict.get("model", "N/A") def get_serial(self): """ @@ -1130,4 +1130,4 @@ def get_serial(self): string: Serial number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("serialnum", "N/A") + return transceiver_dom_info_dict.get("serial", "N/A") diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py index 6ef8838ba8af..83ac8b2bfe68 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py @@ -105,7 +105,7 @@ def __init__(self, sfp_index): self.port_to_eeprom_mapping[x] = eeprom_path.format( self.port_to_i2c_mapping[x]) - self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', @@ -185,11 +185,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -248,17 +248,17 @@ def get_transceiver_info(self): if sfp_interface_bulk_data: transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[ + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data[ 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' @@ -705,7 +705,7 @@ def get_model(self): string: Model/part number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("modelname", "N/A") + return transceiver_dom_info_dict.get("model", "N/A") def get_serial(self): """ @@ -714,4 +714,4 @@ def get_serial(self): string: Serial number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("serialnum", "N/A") + return transceiver_dom_info_dict.get("serial", "N/A") diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py index c4bfbdfafb2e..faf3b867fa60 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py @@ -193,7 +193,7 @@ def __init__(self, sfp_index): port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) self.port_to_eeprom_mapping[x] = port_eeprom_path - self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', @@ -373,11 +373,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -444,13 +444,13 @@ def get_transceiver_info(self): return None transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -521,14 +521,14 @@ def get_transceiver_info(self): sfp_vendor_date_data = sfpi_obj.parse_vendor_date( sfp_interface_bulk_raw[start: end], 0) transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] @@ -1359,7 +1359,7 @@ def get_model(self): string: Model/part number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("modelname", "N/A") + return transceiver_dom_info_dict.get("model", "N/A") def get_serial(self): """ @@ -1368,7 +1368,7 @@ def get_serial(self): string: Serial number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("serialnum", "N/A") + return transceiver_dom_info_dict.get("serial", "N/A") def get_status(self): """ diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py index d0d0f59cd10d..4c5ebf9ea8fe 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py @@ -228,7 +228,7 @@ def __init__(self, sfp_index): port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) self.port_to_eeprom_mapping[x] = port_eeprom_path - self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', @@ -412,11 +412,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -483,13 +483,13 @@ def get_transceiver_info(self): return None transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -562,14 +562,14 @@ def get_transceiver_info(self): sfp_vendor_date_data = sfpi_obj.parse_vendor_date( sfp_interface_bulk_raw[start: end], 0) transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] @@ -1447,7 +1447,7 @@ def get_model(self): string: Model/part number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("modelname", "N/A") + return transceiver_dom_info_dict.get("model", "N/A") def get_serial(self): """ @@ -1456,7 +1456,7 @@ def get_serial(self): string: Serial number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("serialnum", "N/A") + return transceiver_dom_info_dict.get("serial", "N/A") def get_status(self): """ diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index d0e0b0b619f1..09d7fe272edb 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -320,14 +320,14 @@ def get_transceiver_info_dict(self, port_num): return None transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] # Below part is added to avoid fail the xcvrd, shall be implemented later transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -404,13 +404,13 @@ def get_transceiver_info_dict(self, port_num): return None transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/sfp.py index adb61113d41e..56f37afea6e8 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/sfp.py @@ -62,8 +62,8 @@ 'FibreChannelTechnology', 'SFP+CableTechnology', 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') -info_dict_keys = ['type', 'hardwarerev', 'serialnum', - 'manufacturename', 'modelname', 'Connector', +info_dict_keys = ['type', 'hardware_rev', 'serial', + 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'type_abbrv_name','vendor_date', 'vendor_oui'] @@ -102,7 +102,7 @@ 'cable_type': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'connector': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'encoding': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'ext_identifier': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], @@ -112,11 +112,11 @@ 'specification_compliance': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type_abbrv_name': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], - 'manufacturename': [QSFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'manufacturer': [QSFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [QSFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [QSFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [QSFP_INFO_OFFSET, 56, 2, 'parse_vendor_rev'], - 'serialnum': [QSFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [QSFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [QSFP_INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serial': [QSFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [QSFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], 'dom_capability': [QSFP_INFO_OFFSET, 92, 1, 'parse_qsfp_dom_capability'], 'dom_rev': [QSFP_DOM_OFFSET, 1, 1, 'parse_sfp_dom_rev'], @@ -131,7 +131,7 @@ 'cable_type': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'connector': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'type': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'encoding': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'ext_identifier': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], @@ -141,11 +141,11 @@ 'specification_compliance': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'type_abbrv_name': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], - 'manufacturename': [SFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'manufacturer': [SFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [SFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [SFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [SFP_INFO_OFFSET, 56, 4, 'parse_vendor_rev'], - 'serialnum': [SFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [SFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [SFP_INFO_OFFSET, 56, 4, 'parse_vendor_rev'], + 'serial': [SFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [SFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], 'ModuleThreshold': [SFP_DOM_OFFSET, 0, 56, 'parse_alarm_warning_threshold'], } @@ -321,7 +321,7 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor Name - vendor_name_data = self._get_eeprom_data('manufacturename') + vendor_name_data = self._get_eeprom_data('manufacturer') if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: @@ -335,21 +335,21 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor PN - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: return transceiver_info_dict # Vendor Revision - vendor_rev_data = self._get_eeprom_data('hardwarerev') + vendor_rev_data = self._get_eeprom_data('hardware_rev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: return transceiver_info_dict # Vendor Serial Number - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: @@ -357,11 +357,11 @@ def get_transceiver_info(self): # Fill The Dictionary and return transceiver_info_dict['type'] = identifier - transceiver_info_dict['hardwarerev'] = vendor_rev - transceiver_info_dict['serialnum'] = vendor_sn - transceiver_info_dict['manufacturename'] = vendor_name - transceiver_info_dict['modelname'] = vendor_pn - transceiver_info_dict['Connector'] = connector + transceiver_info_dict['hardware_rev'] = vendor_rev + transceiver_info_dict['serial'] = vendor_sn + transceiver_info_dict['manufacturer'] = vendor_name + transceiver_info_dict['model'] = vendor_pn + transceiver_info_dict['connector'] = connector transceiver_info_dict['encoding'] = encoding transceiver_info_dict['ext_identifier'] = ext_id transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier @@ -557,7 +557,7 @@ def get_model(self): """ Retrieves the model number (or part number) of the sfp """ - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: @@ -569,7 +569,7 @@ def get_serial(self): """ Retrieves the serial number of the sfp """ - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py index 9ab89db5d61a..2b6cb0d18edf 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py @@ -40,8 +40,8 @@ 'Fibre Channel transmission media', 'Fibre Channel Speed') -info_dict_keys = ['type', 'hardwarerev', 'serialnum', - 'manufacturename', 'modelname', 'Connector', +info_dict_keys = ['type', 'hardware_rev', 'serial', + 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'type_abbrv_name','vendor_date', 'vendor_oui'] @@ -78,7 +78,7 @@ 'cable_type': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'encoding': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'ext_identifier': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], @@ -87,12 +87,12 @@ 'nominal_bit_rate': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'specification_compliance': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], - 'type_abbrv_name' : [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], - 'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'type_abbrv_name': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'manufacturer': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], - 'serialnum': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serial': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [INFO_OFFSET, 84, 8, 'parse_vendor_date'], 'ModuleThreshold': [DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], 'ChannelThreshold': [DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], @@ -208,7 +208,7 @@ def get_transceiver_info(self): return None # Vendor Name - vendor_name_data = self._get_eeprom_data('manufacturename') + vendor_name_data = self._get_eeprom_data('manufacturer') if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: @@ -222,21 +222,21 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor PN - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: return transceiver_info_dict # Vendor Revision - vendor_rev_data = self._get_eeprom_data('hardwarerev') + vendor_rev_data = self._get_eeprom_data('hardware_rev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: return transceiver_info_dict # Vendor Serial Number - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: @@ -244,11 +244,11 @@ def get_transceiver_info(self): # Fill The Dictionary and return transceiver_info_dict['type'] = identifier - transceiver_info_dict['hardwarerev'] = vendor_rev - transceiver_info_dict['serialnum'] = vendor_sn - transceiver_info_dict['manufacturename'] = vendor_name - transceiver_info_dict['modelname'] = vendor_pn - transceiver_info_dict['Connector'] = connector + transceiver_info_dict['hardware_rev'] = vendor_rev + transceiver_info_dict['serial'] = vendor_sn + transceiver_info_dict['manufacturer'] = vendor_name + transceiver_info_dict['model'] = vendor_pn + transceiver_info_dict['connector'] = connector transceiver_info_dict['encoding'] = encoding transceiver_info_dict['ext_identifier'] = ext_id transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier @@ -434,7 +434,7 @@ def get_model(self): """ Retrieves the model number (or part number) of the sfp """ - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: @@ -446,7 +446,7 @@ def get_serial(self): """ Retrieves the serial number of the sfp """ - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py index e94c53b11a95..6ccef9eceab4 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py @@ -40,8 +40,8 @@ 'Fibre Channel transmission media', 'Fibre Channel Speed') -info_dict_keys = ['type', 'hardwarerev', 'serialnum', - 'manufacturename', 'modelname', 'Connector', +info_dict_keys = ['type', 'hardware_rev', 'serial', + 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] @@ -78,7 +78,7 @@ 'cable_type': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'encoding': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'ext_identifier': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], @@ -87,11 +87,11 @@ 'nominal_bit_rate': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'specification_compliance': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], - 'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'manufacturer': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], - 'serialnum': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serial': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [INFO_OFFSET, 84, 8, 'parse_vendor_date'], 'ModuleThreshold': [DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], 'ChannelThreshold': [DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], @@ -205,7 +205,7 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor Name - vendor_name_data = self._get_eeprom_data('manufacturename') + vendor_name_data = self._get_eeprom_data('manufacturer') if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: @@ -219,21 +219,21 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor PN - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: return transceiver_info_dict # Vendor Revision - vendor_rev_data = self._get_eeprom_data('hardwarerev') + vendor_rev_data = self._get_eeprom_data('hardware_rev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: return transceiver_info_dict # Vendor Serial Number - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: @@ -241,11 +241,11 @@ def get_transceiver_info(self): # Fill The Dictionary and return transceiver_info_dict['type'] = identifier - transceiver_info_dict['hardwarerev'] = vendor_rev - transceiver_info_dict['serialnum'] = vendor_sn - transceiver_info_dict['manufacturename'] = vendor_name - transceiver_info_dict['modelname'] = vendor_pn - transceiver_info_dict['Connector'] = connector + transceiver_info_dict['hardware_rev'] = vendor_rev + transceiver_info_dict['serial'] = vendor_sn + transceiver_info_dict['manufacturer'] = vendor_name + transceiver_info_dict['model'] = vendor_pn + transceiver_info_dict['connector'] = connector transceiver_info_dict['encoding'] = encoding transceiver_info_dict['ext_identifier'] = ext_id transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier @@ -436,7 +436,7 @@ def get_model(self): """ Retrieves the model number (or part number) of the sfp """ - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: @@ -448,7 +448,7 @@ def get_serial(self): """ Retrieves the serial number of the sfp """ - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py index 9f5844d2058c..669abe138bff 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py @@ -40,8 +40,8 @@ 'Fibre Channel transmission media', 'Fibre Channel Speed') -info_dict_keys = ['type', 'hardwarerev', 'serialnum', - 'manufacturename', 'modelname', 'Connector', +info_dict_keys = ['type', 'hardware_rev', 'serial', + 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance','type_abbrv_name','vendor_date', 'vendor_oui'] @@ -78,7 +78,7 @@ 'cable_type': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'encoding': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'ext_identifier': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], @@ -88,11 +88,11 @@ 'specification_compliance': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type_abbrv_name': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], - 'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'manufacturer': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], - 'serialnum': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serial': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [INFO_OFFSET, 84, 8, 'parse_vendor_date'], 'ModuleThreshold': [DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], 'ChannelThreshold': [DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], @@ -207,7 +207,7 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor Name - vendor_name_data = self._get_eeprom_data('manufacturename') + vendor_name_data = self._get_eeprom_data('manufacturer') if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: @@ -221,21 +221,21 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor PN - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: return transceiver_info_dict # Vendor Revision - vendor_rev_data = self._get_eeprom_data('hardwarerev') + vendor_rev_data = self._get_eeprom_data('hardware_rev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: return transceiver_info_dict # Vendor Serial Number - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: @@ -243,11 +243,11 @@ def get_transceiver_info(self): # Fill The Dictionary and return transceiver_info_dict['type'] = identifier - transceiver_info_dict['hardwarerev'] = vendor_rev - transceiver_info_dict['serialnum'] = vendor_sn - transceiver_info_dict['manufacturename'] = vendor_name - transceiver_info_dict['modelname'] = vendor_pn - transceiver_info_dict['Connector'] = connector + transceiver_info_dict['hardware_rev'] = vendor_rev + transceiver_info_dict['serial'] = vendor_sn + transceiver_info_dict['manufacturer'] = vendor_name + transceiver_info_dict['model'] = vendor_pn + transceiver_info_dict['connector'] = connector transceiver_info_dict['encoding'] = encoding transceiver_info_dict['ext_identifier'] = ext_id transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier @@ -436,7 +436,7 @@ def get_model(self): """ Retrieves the model number (or part number) of the sfp """ - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: @@ -448,7 +448,7 @@ def get_serial(self): """ Retrieves the serial number of the sfp """ - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py index 19c678f0e9df..8d9bd36c6abb 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py @@ -66,8 +66,8 @@ 'FibreChannelTechnology', 'SFP+CableTechnology', 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') -info_dict_keys = ['type', 'hardwarerev', 'serialnum', - 'manufacturename', 'modelname', 'Connector', +info_dict_keys = ['type', 'hardware_rev', 'serial', + 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'type_abbrv_name','vendor_date', 'vendor_oui'] @@ -106,7 +106,7 @@ 'cable_type': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'connector': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'encoding': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'ext_identifier': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], @@ -116,11 +116,11 @@ 'specification_compliance': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type_abbrv_name': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], - 'manufacturename': [QSFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'manufacturer': [QSFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [QSFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [QSFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [QSFP_INFO_OFFSET, 56, 2, 'parse_vendor_rev'], - 'serialnum': [QSFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [QSFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [QSFP_INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serial': [QSFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [QSFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], 'dom_capability': [QSFP_INFO_OFFSET, 92, 1, 'parse_qsfp_dom_capability'], 'dom_rev': [QSFP_DOM_OFFSET, 1, 1, 'parse_sfp_dom_rev'], @@ -135,7 +135,7 @@ 'cable_type': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'connector': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'type': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'encoding': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'ext_identifier': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], @@ -145,11 +145,11 @@ 'specification_compliance': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'type_abbrv_name': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], - 'manufacturename': [SFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'manufacturer': [SFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [SFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [SFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [SFP_INFO_OFFSET, 56, 4, 'parse_vendor_rev'], - 'serialnum': [SFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [SFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [SFP_INFO_OFFSET, 56, 4, 'parse_vendor_rev'], + 'serial': [SFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [SFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], 'ModuleThreshold': [SFP_DOM_OFFSET, 0, 56, 'parse_alarm_warning_threshold'], } @@ -326,7 +326,7 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor Name - vendor_name_data = self._get_eeprom_data('manufacturename') + vendor_name_data = self._get_eeprom_data('manufacturer') if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: @@ -340,21 +340,21 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor PN - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: return transceiver_info_dict # Vendor Revision - vendor_rev_data = self._get_eeprom_data('hardwarerev') + vendor_rev_data = self._get_eeprom_data('hardware_rev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: return transceiver_info_dict # Vendor Serial Number - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: @@ -362,11 +362,11 @@ def get_transceiver_info(self): # Fill The Dictionary and return transceiver_info_dict['type'] = identifier - transceiver_info_dict['hardwarerev'] = vendor_rev - transceiver_info_dict['serialnum'] = vendor_sn - transceiver_info_dict['manufacturename'] = vendor_name - transceiver_info_dict['modelname'] = vendor_pn - transceiver_info_dict['Connector'] = connector + transceiver_info_dict['hardware_rev'] = vendor_rev + transceiver_info_dict['serial'] = vendor_sn + transceiver_info_dict['manufacturer'] = vendor_name + transceiver_info_dict['model'] = vendor_pn + transceiver_info_dict['connector'] = connector transceiver_info_dict['encoding'] = encoding transceiver_info_dict['ext_identifier'] = ext_id transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier @@ -562,7 +562,7 @@ def get_model(self): """ Retrieves the model number (or part number) of the sfp """ - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: @@ -574,7 +574,7 @@ def get_serial(self): """ Retrieves the serial number of the sfp """ - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py index f3f873be08ce..c002697d96a3 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py @@ -205,7 +205,7 @@ def get_model(self): string: Model/part number of device """ transceiver_info_dict = self.get_transceiver_info() - return transceiver_info_dict.get("modelname", "N/A") + return transceiver_info_dict.get("model", "N/A") def get_serial(self): """ @@ -215,7 +215,7 @@ def get_serial(self): string: Serial number of device """ transceiver_info_dict = self.get_transceiver_info() - return transceiver_info_dict.get("serialnum", "N/A") + return transceiver_info_dict.get("serial", "N/A") def get_status(self): """ @@ -240,11 +240,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -256,9 +256,9 @@ def get_transceiver_info(self): ======================================================================== """ - transceiver_info_dict_keys = ['type', 'hardwarerev', - 'serialnum', 'manufacturename', - 'modelname', 'Connector', + transceiver_info_dict_keys = ['type', 'hardware_rev', + 'serial', 'manufacturer', + 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', @@ -305,22 +305,22 @@ def get_transceiver_info(self): if sfp_interface_bulk_data: transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' - transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' - transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' - transceiver_info_dict['cable_type'] = "Unknown" - transceiver_info_dict['cable_length'] = "Unknown" + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" for key in qsfp_cable_length_tup: if key in sfp_interface_bulk_data['data']: transceiver_info_dict['cable_type'] = key diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py index d8d88a2df2b0..8c432dc19764 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py @@ -192,7 +192,7 @@ def get_model(self): string: Model/part number of device """ transceiver_info_dict = self.get_transceiver_info() - return transceiver_info_dict.get("modelname", "N/A") + return transceiver_info_dict.get("model", "N/A") def get_serial(self): """ @@ -202,7 +202,7 @@ def get_serial(self): string: Serial number of device """ transceiver_info_dict = self.get_transceiver_info() - return transceiver_info_dict.get("serialnum", "N/A") + return transceiver_info_dict.get("serial", "N/A") def get_status(self): """ @@ -227,11 +227,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -243,9 +243,9 @@ def get_transceiver_info(self): ======================================================================== """ - transceiver_info_dict_keys = ['type', 'hardwarerev', - 'serialnum', 'manufacturename', - 'modelname', 'Connector', + transceiver_info_dict_keys = ['type', 'hardware_rev', + 'serial', 'manufacturer', + 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', @@ -294,22 +294,22 @@ def get_transceiver_info(self): if sfp_interface_bulk_data: transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' - transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' - transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' - transceiver_info_dict['cable_type'] = "Unknown" - transceiver_info_dict['cable_length'] = "Unknown" + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" for key in sfp_cable_length_tup: if key in sfp_interface_bulk_data['data']: transceiver_info_dict['cable_type'] = key diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py index 47d88afa13a4..4d71424ccf6f 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py @@ -232,7 +232,7 @@ def __init__(self, sfp_index, sfp_type): port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) self.port_to_eeprom_mapping[x] = port_eeprom_path - self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', @@ -426,11 +426,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -486,13 +486,13 @@ def get_transceiver_info(self): return None transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -557,13 +557,13 @@ def get_transceiver_info(self): end = start + XCVR_VENDOR_DATE_WIDTH sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_interface_bulk_raw[start : end], 0) transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 2cfa98a7ebd2..aa9d18d04f84 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -556,11 +556,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance From 458b4aef484f8ac4722b8041b538145232416c6e Mon Sep 17 00:00:00 2001 From: lguohan Date: Thu, 16 Jul 2020 17:19:21 -0700 Subject: [PATCH 0920/1427] [vstest]: remove kill exabgp command from the test (#4978) the command kills all exabgp processes on the host. since the namespaces are newly added, there should be no prior exabgp processes. if it is existing namespace, it is also the dvs framework job to clean up all prior processes. --- platform/vs/tests/bgp/test_gr_livelock.py | 1 - platform/vs/tests/bgp/test_no_export.py | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/vs/tests/bgp/test_gr_livelock.py b/platform/vs/tests/bgp/test_gr_livelock.py index aff0afdb02b4..5f85bfc239b5 100644 --- a/platform/vs/tests/bgp/test_gr_livelock.py +++ b/platform/vs/tests/bgp/test_gr_livelock.py @@ -81,7 +81,6 @@ def test_gr_livelock(dvs, testlog): dvs.servers[0].runcmd("pip install 'exabgp==4.0.10' --force-reinstall ") # dvs.copy_file("/etc/frr/", "bgp/files/gr_livelock/bgpd.conf") - dvs.servers[0].runcmd("pkill exabgp") # In case previous test didn't stop exa dvs.runcmd("supervisorctl stop bgpd") time.sleep(5) dvs.runcmd("supervisorctl start bgpd") diff --git a/platform/vs/tests/bgp/test_no_export.py b/platform/vs/tests/bgp/test_no_export.py index 92bece320c1c..61858bc78200 100644 --- a/platform/vs/tests/bgp/test_no_export.py +++ b/platform/vs/tests/bgp/test_no_export.py @@ -5,10 +5,9 @@ import json def test_bounce(dvs, testlog): - dvs.servers[0].runcmd("pkill -f exabgp") dvs.copy_file("/etc/frr/", "bgp/files/no_export/bgpd.conf") dvs.runcmd("supervisorctl start bgpd") - dvs.runcmd("ip addr add 10.0.0.0/31 dev Ethernet0") + dvs.runcmd("ip addr add 10.0.0.0/31 dev Ethernet0") dvs.runcmd("config interface startup Ethernet0") dvs.runcmd("ip addr add 10.0.0.2/31 dev Ethernet4") @@ -30,7 +29,7 @@ def test_bounce(dvs, testlog): (exit_code, sum_res) = dvs.runcmd(["vtysh", "-c", "show ip bgp sum"]) (exit_code, all_route) = dvs.runcmd(["vtysh", "-c", "show ip bgp"]) (exit_code, announce_route) = dvs.runcmd(["vtysh", "-c", "show ip bgp neighbors 10.0.0.3 advertised-routes"]) - + p1.terminate() p1 = p1.wait() From d6925499f129ed4a893fe6e9bb314106f0a33653 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 17 Jul 2020 11:16:19 -0700 Subject: [PATCH 0921/1427] [caclmgrd] Filter DHCP packets based on dest port only (#4995) --- files/image_config/caclmgrd/caclmgrd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 3f0c7f93ffb0..927675524ea3 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -245,12 +245,12 @@ class ControlPlaneAclManager(object): iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT") # Add iptables/ip6tables commands to allow all incoming IPv4 DHCP packets - iptables_cmds.append("iptables -A INPUT -p udp --dport 67:68 --sport 67:68 -j ACCEPT") - iptables_cmds.append("ip6tables -A INPUT -p udp --dport 67:68 --sport 67:68 -j ACCEPT") + iptables_cmds.append("iptables -A INPUT -p udp --dport 67:68 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p udp --dport 67:68 -j ACCEPT") # Add iptables/ip6tables commands to allow all incoming IPv6 DHCP packets - iptables_cmds.append("iptables -A INPUT -p udp --dport 546:547 --sport 546:547 -j ACCEPT") - iptables_cmds.append("ip6tables -A INPUT -p udp --dport 546:547 --sport 546:547 -j ACCEPT") + iptables_cmds.append("iptables -A INPUT -p udp --dport 546:547 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p udp --dport 546:547 -j ACCEPT") # Add iptables/ip6tables commands to allow all incoming BGP traffic # TODO: Determine BGP ACLs based on configured device sessions, and remove this blanket acceptance From 04615ca98c30ba5a63988fac4b71c576d78c66e1 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 17 Jul 2020 11:20:39 -0700 Subject: [PATCH 0922/1427] [sonic-snmpagent][sonic-py-swsssdk] Update submodules (#4968) * src/sonic-snmpagent 89b7b2c...c702a57 (7): > Revert "[rfc1213] Interface MIB add l3 vlan interfaces & aggregate rif counters (#133)" (#151) > Update transceiver info DB key names (#146) > Fix LGTM reported alert of PR#141 (#142) > [Namespace] Fix interfaces counters in InterfacesMIB RFC 2863 (#141) > [Namespace]: Fix SNMP AgentX socket connection timeout when using Namespace.get_all() (#140) > [rfc1213] Interface MIB add l3 vlan interfaces & aggregate rif counters (#133) > Fix undefined variable and warning message (#134) * src/sonic-py-swsssdk a83366e...2df4f40 (3): > Allowing TCP connections with namespace as well. (#81) > [port_util] add get_rif_port_map, get_vlan_interface_oid_map (#78) > Updates to the namespace API's for test_moduleLoad.py (#77) Note that sonic-snmpagent submodule update is dependent upon sonic-py-swsssdk update, so updating both submodules in this PR. --- src/sonic-py-swsssdk | 2 +- src/sonic-snmpagent | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index a83366e827cc..2df4f40fcec2 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit a83366e827cc08dbd3d22de92773c7ef79215199 +Subproject commit 2df4f40fcec2c5ddafe543aec964a6390d2a9a90 diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 89b7b2c90099..c702a57608e4 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 89b7b2c90099bc3404edeb1210b0aa90070a6a80 +Subproject commit c702a57608e42fa40f0ea86f82870514eab4c1b7 From d8a79bc71e42b97888f8c6d9ddb6c517a2f338e9 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 17 Jul 2020 15:07:12 -0700 Subject: [PATCH 0923/1427] [secureboot] Fix some installation behavior for secureboot (#4980) --- files/Aboot/boot0.j2 | 78 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 7672919056c3..8db7fc2dc074 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -76,6 +76,7 @@ fi image_path="$target_path/$image_name" hook_path="$image_path/platform/hooks" data_path="$image_path/platform/data" +boot_image_path="$image_path/$boot_image" installer_image_path="$image_path/$installer_image" boot_config="$target_path/boot-config" @@ -106,6 +107,7 @@ clean_flash() { for f in $(ls -A $target_path); do if [ $f != "${swipath##*/}" ] && [ $f != "boot-config" ] && + [ $f != "preserve-installer" ] && [ $f != "$kernel_params" ] && [ $f != "aquota.user" ] && [ $f != "old_config" ] && @@ -254,9 +256,47 @@ cleanup_swi_tmpfs() { clean_tmpfs "$(dirname "$swipath")" } -extract_image() { - mkdir -p "$image_path" +SWI_ALREADY_INSTALLED=0 +SWI_NOT_INSTALLED=1 +SWI_VERSION_MISMATCH=2 +SWI_OTHER_VARIANT_INSTALLED=3 + +is_swi_installed() { + local swi_path="$1" + local swi_version="$(unzip -qp "$swi_path" .imagehash)" + local local_version="$(cat $image_path/.imagehash 2>/dev/null || :)" + + if [ -z "$local_version" ]; then + # no image installed for this version + return $SWI_NOT_INSTALLED + fi + + if [ "$swi_version" != "$local_version" ]; then + warn "Installed image has a different version than $swipath" + return $SWI_VERSION_MISMATCH + fi + + if $secureboot; then + if [ -s "$installer_image_path" ]; then + # secureboot image already installed + return $SWI_ALREADY_INSTALLED + else + # regular image of the same version already installed + return $SWI_OTHER_VARIANT_INSTALLED + fi + else + if [ -s "$boot_image_path" ]; then + # regular image already installed + return $SWI_ALREADY_INSTALLED + else + # secureboot image of the same version already installed + return $SWI_OTHER_VARIANT_INSTALLED + fi + fi +} + +extract_image() { info "Moving swi to a tmpfs" ## Avoid problematic flash usage spike on older systems, also improves I/O swipath="$(move_swi_to_tmpfs "$swipath")" @@ -308,7 +348,6 @@ extract_image() { extract_image_secureboot() { info "Extracting necessary swi content" - mkdir "$image_path" unzip -oq "$swipath" platform/firsttime .imagehash -d "$image_path" info "Installing image as $installer_image_path" @@ -608,15 +647,20 @@ run_kexec() { secureboot_install() { if [ -e "$image_path" ]; then - warn "Image folder $image_path already exist, wiping..." - rm -rf "$image_path" + warn "Image folder $image_path already exist (likely regular install)" fi + mkdir -p "$image_path" + info "Installing image as $installer_image_path" extract_image_secureboot } regular_install() { + if [ -e "$image_path" ]; then + warn "Image folder $image_path already exist (likely secureboot install)" + fi + mkdir -p $image_path info "Generating boot-config, machine.conf and cmdline" @@ -670,6 +714,9 @@ elif [ ! -z "$kexec" ]; then do_clean=false fi +# Make sure boot-config exists to avoid noise +touch "$boot_config" + # Verbosity can be defined by the caller, default to false otherwise verbose=${verbose:-false} debug=${debug:-false} @@ -693,7 +740,12 @@ if [ -z "$secureboot" ]; then fi fi +# preserve original installer during regular install when set preserve_installer=false +if [ -f "$target_path/preserve-installer" ] || + [ "$(get_boot_config PRESERVE_INSTALLER)" = "1" ]; then + preserve_installer=true +fi # enable shell debug mode to get the most verbosity if $verbose; then @@ -702,21 +754,23 @@ fi # install the image if newer if $do_install; then - if ! unzip -l "$swipath" 2>&1 > /dev/null; then + if ! unzip -ql "$swipath" 2>&1 > /dev/null; then err "The swipath= environment variable does not point to a valid SWI" exit 1 fi - # check the hash file in the image, and determine to install or just skip - GIT_REVISION="$(unzip -p "$swipath" .imagehash)" - LOCAL_IMAGEHASH="$(cat $image_path/.imagehash 2>/dev/null || true)" + swi_installed=0 + is_swi_installed "$swipath" || swi_installed=$? - if [ "$GIT_REVISION" != "$LOCAL_IMAGEHASH" ] || [ ! -z "$force" ]; then - if $do_clean; then + if [ "$swi_installed" -ne $SWI_ALREADY_INSTALLED ] || [ -n "$force" ]; then + if [ "$swi_installed" -eq $SWI_VERSION_MISMATCH ] || [ -n "$force" ]; then + warn "Removing existing installation folder $image_path" + rm -rf $image_path + fi + if [ "$swi_installed" -ne $SWI_OTHER_VARIANT_INSTALLED ] && $do_clean; then info "Cleaning flash content $target_path" clean_flash fi - if $secureboot; then secureboot_install else From a3f4c31193efee412c675be87631756767a62aa7 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Sat, 18 Jul 2020 10:05:10 +0300 Subject: [PATCH 0924/1427] [orchagent]: Fix platform string export. (#4993) Signed-off-by: Nazarii Hnydyn --- dockers/docker-orchagent/orchagent.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index a68f2d70fb13..8743caea1fb5 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -10,7 +10,7 @@ fi # Retrieve SWSS vars from sonic-cfggen SWSS_VARS=$(sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t $SWSS_VARS_FILE) -platform=$(echo $SWSS_VARS | jq -r '.asic_type') +export platform=$(echo $SWSS_VARS | jq -r '.asic_type') MAC_ADDRESS=$(echo $SWSS_VARS | jq -r '.mac') if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then From 25c39000859e9fd103abb4efa1c9e243b194286f Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 18 Jul 2020 00:11:09 -0700 Subject: [PATCH 0925/1427] [docker-sonic-vs]: upgrade docker-sonic-vs to buster (#4979) Signed-off-by: Guohan Lu --- platform/vs/docker-sonic-vs.mk | 3 +-- platform/vs/docker-sonic-vs/Dockerfile.j2 | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index ab86e4716a19..e96355f8e05c 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -36,6 +36,5 @@ $(DOCKER_SONIC_VS)_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(QOS_CONFIG_TEMPLATE) \ $(SONIC_VERSION) -$(DOCKER_SONIC_VS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_SONIC_VS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_SONIC_VS) -SONIC_STRETCH_DOCKERS += $(DOCKER_SONIC_VS) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 65253fc6a572..6fabf0a60a2a 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -13,7 +13,7 @@ RUN echo "deb http://packages.microsoft.com/repos/sonic-dev/ jessie main" >> /et RUN apt-get update RUN apt-get install -y net-tools \ - redis-server=5:5.0.3-3~bpo9+2 \ + redis-server=5:6.0.5-1~bpo10+1 \ arping \ ndisc6 \ ethtool \ @@ -23,15 +23,15 @@ RUN apt-get install -y net-tools \ python-ply \ libqt5core5a \ libqt5network5 \ - libboost-program-options1.62.0 \ - libboost-system1.62.0 \ - libboost-thread1.62.0 \ + libboost-program-options1.71.0 \ + libboost-system1.71.0 \ + libboost-thread1.71.0 \ libgmp10 \ libjudydebian1 \ openssh-client \ openssh-server \ libc-ares2 \ - iproute \ + iproute2 \ grub2-common \ python-click \ python-natsort \ From 78945766fc7d57494f3dfcd865b8362b77a8bdb8 Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Sat, 18 Jul 2020 00:12:59 -0700 Subject: [PATCH 0926/1427] [docker-iccpd]: Upgrade docker-iccpd to buster (#4984) Signed-off-by: Joyas Joseph --- dockers/docker-iccpd/Dockerfile.j2 | 2 +- rules/docker-iccpd.mk | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dockers/docker-iccpd/Dockerfile.j2 b/dockers/docker-iccpd/Dockerfile.j2 index 3424c0e97fc9..7c5c98ac720d 100644 --- a/dockers/docker-iccpd/Dockerfile.j2 +++ b/dockers/docker-iccpd/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-iccpd.mk b/rules/docker-iccpd.mk index fefa5504df13..97e9a842319a 100644 --- a/rules/docker-iccpd.mk +++ b/rules/docker-iccpd.mk @@ -5,18 +5,16 @@ DOCKER_ICCPD = $(DOCKER_ICCPD_STEM).gz DOCKER_ICCPD_DBG = $(DOCKER_ICCPD_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_ICCPD)_PATH = $(DOCKERS_PATH)/$(DOCKER_ICCPD_STEM) $(DOCKER_ICCPD)_DEPENDS += $(SWSS) $(ICCPD) -$(DOCKER_ICCPD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_ICCPD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_ICCPD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) $(ICCPD_DBG) -$(DOCKER_ICCPD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) -$(DOCKER_ICCPD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_ICCPD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) +$(DOCKER_ICCPD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) ifeq ($(ENABLE_ICCPD), y) SONIC_DOCKER_IMAGES += $(DOCKER_ICCPD) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ICCPD) -SONIC_STRETCH_DOCKERS += $(DOCKER_ICCPD) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_ICCPD_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ICCPD_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ICCPD_DBG) endif $(DOCKER_ICCPD)_CONTAINER_NAME = iccpd From 16a37d8c17c53764ef2af255c31e9c1454ea0a94 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Sat, 18 Jul 2020 13:46:15 +0300 Subject: [PATCH 0927/1427] [dockers] update mellanox syncd and pmon to buster (#4818) Upgrade to libsensors5 Updated sonic-sairedis pointer: d54bfb4 [SAI] update pointer (#636) 1885a8c [syncd] Fix notification on shutdown request (#635) 9e57ba2 Fixing hostif For Genetlink host interfaces (#633) 449a092 sonic-sairedis: Add support to sonic-sairedis for gearbox phys (#632) Signed-off-by: Stepan Blyschak --- dockers/docker-platform-monitor/Dockerfile.j2 | 2 +- platform/mellanox/docker-syncd-mlnx-rpc.mk | 2 +- platform/mellanox/docker-syncd-mlnx.mk | 3 - .../mellanox/docker-syncd-mlnx/Dockerfile.j2 | 2 +- .../sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 3 +- rules/docker-platform-monitor.mk | 8 +- rules/lm-sensors.mk | 12 ++- sonic-slave-buster/Dockerfile.j2 | 2 +- src/lm-sensors/.gitignore | 1 + src/lm-sensors/Makefile | 13 ++- ...e-debian-package-info-to-get-sensord.patch | 102 +++++++++--------- ...dh_installinit-to-include-sensord.in.patch | 10 +- src/lm-sensors/patch/series | 2 + src/sonic-sairedis | 2 +- 15 files changed, 89 insertions(+), 77 deletions(-) rename src/lm-sensors/{ => patch}/0001-patch-the-debian-package-info-to-get-sensord.patch (66%) rename src/lm-sensors/{ => patch}/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch (72%) create mode 100644 src/lm-sensors/patch/series diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index b167dea0085e..884fd565c3a4 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.mk b/platform/mellanox/docker-syncd-mlnx-rpc.mk index ef2aec3333ac..806b40035f23 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc.mk +++ b/platform/mellanox/docker-syncd-mlnx-rpc.mk @@ -14,7 +14,7 @@ endif $(DOCKER_SYNCD_MLNX_RPC)_PYTHON_DEBS += $(MLNX_SFPD) $(DOCKER_SYNCD_MLNX_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MLNX_RPC) -SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_MLNX_RPC) +SONIC_BUSTER_DOCKERS += $(DOCKER_SYNCD_MLNX_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_MLNX_RPC) endif diff --git a/platform/mellanox/docker-syncd-mlnx.mk b/platform/mellanox/docker-syncd-mlnx.mk index c89d8dbc4ddc..9bdc5a8ad8ec 100644 --- a/platform/mellanox/docker-syncd-mlnx.mk +++ b/platform/mellanox/docker-syncd-mlnx.mk @@ -14,8 +14,5 @@ ifeq ($(SDK_FROM_SRC), y) $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(MLNX_SDK_DBG_DEBS) $(MLNX_SAI_DBGSYM) endif -SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) - $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index c2cfc9edbbdd..21aaef2f3009 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index bb4c9c1c9856..9dff92deb1f4 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit bb4c9c1c98563c3177dc8e086b8ddfe41b9695a2 +Subproject commit 9dff92deb1f4cafa2e5c5077c8a6e98f0fbf586e diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index e74e9e673ce0..973ea8294cf5 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,4 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ +MLNX_SDK_PKG_BASE_PATH = $(MLNX_SDK_BASE_PATH)/$(BLDENV)/ MLNX_SDK_VERSION = 4.4.0952 MLNX_SDK_ISSU_VERSION = 101 @@ -136,7 +137,7 @@ SX_KERNEL_DEV = sx-kernel-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(eval $(call add_derived_package,$(SX_KERNEL),$(SX_KERNEL_DEV))) define make_path - $(1)_PATH = $(MLNX_SDK_BASE_PATH) + $(1)_PATH = $(MLNX_SDK_PKG_BASE_PATH) endef diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index db1c8c5a0289..11a6f1c94c86 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -16,19 +16,17 @@ $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_DAEMON_BASE_PY2) -$(DOCKER_PLATFORM_MONITOR)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_PLATFORM_MONITOR)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_PLATFORM_MONITOR)_DBG_DEPENDS += $(LIBSWSSCOMMON_DBG) $(LIBSENSORS_DBG) $(DOCKER_PLATFORM_MONITOR)_DBG_DEPENDS += $(LM_SENSORS_DBG) $(SENSORD_DBG) -$(DOCKER_PLATFORM_MONITOR)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_PLATFORM_MONITOR)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_PLATFORM_MONITOR)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_PLATFORM_MONITOR)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BUSTER) -SONIC_STRETCH_DOCKERS += $(DOCKER_PLATFORM_MONITOR) SONIC_DOCKER_IMAGES += $(DOCKER_PLATFORM_MONITOR) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_PLATFORM_MONITOR) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_PLATFORM_MONITOR_DBG) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_PLATFORM_MONITOR_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_PLATFORM_MONITOR_DBG) diff --git a/rules/lm-sensors.mk b/rules/lm-sensors.mk index 7df208abfdbf..414aeb72b229 100644 --- a/rules/lm-sensors.mk +++ b/rules/lm-sensors.mk @@ -1,7 +1,11 @@ # lm-senensors package -LM_SENSORS_VERSION=3.4.0 -LM_SENSORS_VERSION_FULL=$(LM_SENSORS_VERSION)-4 +LM_SENSORS_MAJOR_VERSION = 3 +LM_SENSORS_MINOR_VERSION = 5 +LM_SENSORS_PATCH_VERSION = 0 + +LM_SENSORS_VERSION=$(LM_SENSORS_MAJOR_VERSION).$(LM_SENSORS_MINOR_VERSION).$(LM_SENSORS_PATCH_VERSION) +LM_SENSORS_VERSION_FULL=$(LM_SENSORS_VERSION)-3 LM_SENSORS = lm-sensors_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(LM_SENSORS)_SRC_PATH = $(SRC_PATH)/lm-sensors @@ -12,10 +16,10 @@ $(eval $(call add_derived_package,$(LM_SENSORS),$(LM_SENSORS_DBG))) FANCONTROL = fancontrol_$(LM_SENSORS_VERSION_FULL)_all.deb $(eval $(call add_derived_package,$(LM_SENSORS),$(FANCONTROL))) -LIBSENSORS = libsensors4_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb +LIBSENSORS = libsensors$(LM_SENSORS_MINOR_VERSION)_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LM_SENSORS),$(LIBSENSORS))) -LIBSENSORS_DBG = libsensors4-dbgsym_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb +LIBSENSORS_DBG = libsensors$(LM_SENSORS_MINOR_VERSION)-dbgsym_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LM_SENSORS),$(LIBSENSORS_DBG))) SENSORD = sensord_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 87f39c10b9b3..08c7aaac4b57 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -337,7 +337,7 @@ RUN export VERSION=1.14.2 \ # For p4 build RUN pip install \ - ctypesgen==0.r125 \ + ctypesgen==1.0.2 \ crc16 # For sonic config engine testing diff --git a/src/lm-sensors/.gitignore b/src/lm-sensors/.gitignore index a0991ff4402b..dfa47d4833b3 100644 --- a/src/lm-sensors/.gitignore +++ b/src/lm-sensors/.gitignore @@ -1,3 +1,4 @@ * !.gitignore !Makefile +!patch/* diff --git a/src/lm-sensors/Makefile b/src/lm-sensors/Makefile index 50cc3e51bb3c..af080a8dba55 100644 --- a/src/lm-sensors/Makefile +++ b/src/lm-sensors/Makefile @@ -5,7 +5,7 @@ SHELL = /bin/bash MAIN_TARGET = $(LM_SENSORS) DERIVED_TARGETS = fancontrol_$(LM_SENSORS_VERSION_FULL)_all.deb \ - libsensors4_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ + $(LIBSENSORS) \ sensord_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ $(LM_SENSORS_DBG) \ $(LIBSENSORS_DBG) \ @@ -14,8 +14,17 @@ DERIVED_TARGETS = fancontrol_$(LM_SENSORS_VERSION_FULL)_all.deb \ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf lm-sensors-$(LM_SENSORS_VERSION) dget -u http://deb.debian.org/debian/pool/main/l/lm-sensors/lm-sensors_$(LM_SENSORS_VERSION_FULL).dsc - git apply *.patch pushd lm-sensors-$(LM_SENSORS_VERSION) + + # Initialize as git repository + git init + git add -f * + git commit -m "unmodified lm-sensors sources" + + # Apply patches + stg init + stg import -s ../patch/series + DEB_BUILD_OPTIONS=nocheck PROG_EXTRA=sensord dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) popd diff --git a/src/lm-sensors/0001-patch-the-debian-package-info-to-get-sensord.patch b/src/lm-sensors/patch/0001-patch-the-debian-package-info-to-get-sensord.patch similarity index 66% rename from src/lm-sensors/0001-patch-the-debian-package-info-to-get-sensord.patch rename to src/lm-sensors/patch/0001-patch-the-debian-package-info-to-get-sensord.patch index 4ff40124018e..262c7bca3f46 100644 --- a/src/lm-sensors/0001-patch-the-debian-package-info-to-get-sensord.patch +++ b/src/lm-sensors/patch/0001-patch-the-debian-package-info-to-get-sensord.patch @@ -5,37 +5,37 @@ Subject: [PATCH] patch the debian package info to get sensord Signed-off-by: Mykola Faryma --- - .../lm-sensors-3.4.0/debian/sensord.NEWS | 12 ++++ - .../lm-sensors-3.4.0/debian/sensord.README.Debian | 23 ++++++++ - .../lm-sensors-3.4.0/debian/sensord.default | 20 +++++++ - .../lm-sensors-3.4.0/debian/sensord.dirs | 3 + - .../lm-sensors-3.4.0/debian/sensord.init | 64 ++++++++++++++++++++++ - .../lm-sensors-3.4.0/debian/sensord.install | 2 + - .../lm-sensors-3.4.0/debian/sensord.maintscript | 2 + - .../lm-sensors-3.4.0/debian/sensord.postinst | 23 ++++++++ - .../lm-sensors-3.4.0/debian/sensord.substvars | 2 + - .../lm-sensors-3.4.0/debian/control | 14 ++++++++++++++ + debian/sensord.NEWS | 12 ++++ + debian/sensord.README.Debian | 23 ++++++++ + debian/sensord.default | 20 +++++++ + debian/sensord.dirs | 3 + + debian/sensord.init | 64 ++++++++++++++++++++++ + debian/sensord.install | 2 + + debian/sensord.maintscript | 2 + + debian/sensord.postinst | 23 ++++++++ + debian/sensord.substvars | 2 + + debian/control | 14 ++++++++++++++ 11 files changed, 167 insertions(+), 1 deletion(-) - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.NEWS - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.README.Debian - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.default - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.dirs - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.init - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.install - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.maintscript - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.postinst - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.substvars + create mode 100644 /debian/sensord.NEWS + create mode 100644 /debian/sensord.README.Debian + create mode 100644 /debian/sensord.default + create mode 100644 /debian/sensord.dirs + create mode 100644 /debian/sensord.init + create mode 100644 /debian/sensord.install + create mode 100644 /debian/sensord.maintscript + create mode 100644 /debian/sensord.postinst + create mode 100644 /debian/sensord.substvars -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.NEWS b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.NEWS +diff --git a/debian/sensord.NEWS b/debian/sensord.NEWS new file mode 100644 index 0000000..4bcfdb9 --- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.NEWS ++++ b/debian/sensord.NEWS @@ -0,0 +1,12 @@ +lm-sensors (1:2.9.0-7) unstable; urgency=low + -+ Since version 2.9.0 sensord doesn't scale the loadavg itself (* 10) as -+ RRDs work with floating-point values and thus do very well with ++ Since version 2.9.0 sensord doesn't scale the loadavg itself (* 10) as ++ RRDs work with floating-point values and thus do very well with + non-integer values even < 1. + + They can even be scaled later at display time by rrdtool itself using: @@ -44,40 +44,40 @@ index 0000000..4bcfdb9 + + -- Aurelien Jarno Tue, 11 Jan 2005 22:41:34 +0100 + -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.README.Debian b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.README.Debian +diff --git a/debian/sensord.README.Debian b/debian/sensord.README.Debian new file mode 100644 index 0000000..9159fbc --- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.README.Debian ++++ b/debian/sensord.README.Debian @@ -0,0 +1,23 @@ +This is the Debian packaging of sensord, the sensord logging daemon. + -+The file /etc/default/sensord specifies the configuration parameters -+used to start the daemon. In particular, the syslog facility is set ++The file /etc/default/sensord specifies the configuration parameters ++used to start the daemon. In particular, the syslog facility is set +to `daemon' and not `local4'. + +You must load the appropriate lm-sensors modules during system boot in +order for the daemon to function correctly. + -+The file /etc/modules is a useful place to list these modules; for -+example, you might list i2c-amd756 (an I2C/SMBUS module) and w83781d ++The file /etc/modules is a useful place to list these modules; for ++example, you might list i2c-amd756 (an I2C/SMBUS module) and w83781d +(a sensor chip module). + -+The daemon does not setup the sensors limits from /etc/sensors3.conf, ++The daemon does not setup the sensors limits from /etc/sensors3.conf, +this is the job of sensors, when called with -s. Note that 'sensors -s' -+is called at boot time from /etc/init.d/lm-sensors, so that the sensors -+limits should be the right ones in normal use. Don't forget to run ++is called at boot time from /etc/init.d/lm-sensors, so that the sensors ++limits should be the right ones in normal use. Don't forget to run +sensors -s again if you changed the limits in /etc/sensors3.conf. + +For full documentation on setting up lm-sensors on your system, +see /usr/share/doc/lm-sensors. + +-- David Z. Maze -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.default b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.default +diff --git a/debian/sensord.default b/debian/sensord.default new file mode 100644 index 0000000..589b94c --- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.default ++++ b/debian/sensord.default @@ -0,0 +1,20 @@ +# Interval between scanning for alarms; e.g., 30s, 1m, 1h +# ALARM_INTERVAL=1m @@ -99,20 +99,20 @@ index 0000000..589b94c +# Include the load average in the RRD file. If you enable this you +# must remove your old RRD file and rebuild your CGI script. +# RRD_LOADAVG=yes -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.dirs b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.dirs +diff --git a/debian/sensord.dirs b/debian/sensord.dirs new file mode 100644 index 0000000..b9cd814 --- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.dirs ++++ b/debian/sensord.dirs @@ -0,0 +1,3 @@ +usr/sbin +usr/share/man/man8 +etc/default -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.init b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.init +diff --git a/debian/sensord.init b/debian/sensord.init new file mode 100644 index 0000000..4d70d43 --- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.init ++++ b/debian/sensord.init @@ -0,0 +1,64 @@ +#!/bin/sh + @@ -178,27 +178,27 @@ index 0000000..4d70d43 +esac + +exit 0 -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.install b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.install +diff --git a/debian/sensord.install b/debian/sensord.install new file mode 100644 index 0000000..9713fee --- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.install ++++ b/debian/sensord.install @@ -0,0 +1,2 @@ +usr/sbin/sensord +usr/share/man/man8/sensord.8 -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.maintscript b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.maintscript +diff --git a/debian/sensord.maintscript b/debian/sensord.maintscript new file mode 100644 index 0000000..0e0ff03 --- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.maintscript ++++ b/debian/sensord.maintscript @@ -0,0 +1,2 @@ +# Remove old logcheck ignore file -+rm_conffile /etc/logcheck/ignore.d.server/sensord 1:3.3.5-1~ -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.postinst b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.postinst ++rm_conffile /etc/logcheck/ignore.d.server/sensord 1:3.3.5-1~ +diff --git a/debian/sensord.postinst b/debian/sensord.postinst new file mode 100644 index 0000000..3418fa6 --- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.postinst ++++ b/debian/sensord.postinst @@ -0,0 +1,23 @@ +#!/bin/sh +# postinst script for sensord @@ -223,17 +223,17 @@ index 0000000..3418fa6 +esac + +#DEBHELPER# -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.substvars b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.substvars +diff --git a/debian/sensord.substvars b/debian/sensord.substvars new file mode 100644 index 0000000..978fc8b --- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.substvars ++++ b/debian/sensord.substvars @@ -0,0 +1,2 @@ +misc:Depends= +misc:Pre-Depends= -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/control b/src/lm-sensors/lm-sensors-3.4.0/debian/control ---- a/src/lm-sensors/lm-sensors-3.4.0/debian/control -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/control +diff --git a/debian/control b/debian/control +--- a/debian/control ++++ b/debian/control @@ -68,3 +68,17 @@ Description: utility to control the fan speed and sets the corresponding PWM outputs to the computed values. This is useful when this feature is not provided by the BIOS or ACPI, which should @@ -252,5 +252,5 @@ diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/control b/src/lm-sensors/lm- + This package contains a daemon that logs hardware health status to the + system log with optional warnings on potential system problems. + --- +-- 1.9.1 diff --git a/src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch b/src/lm-sensors/patch/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch similarity index 72% rename from src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch rename to src/lm-sensors/patch/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch index 6d3e279ea5e7..7bfdee11e3be 100644 --- a/src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch +++ b/src/lm-sensors/patch/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch @@ -9,15 +9,15 @@ Signed-off-by: Charlie Chen debian/rules | 1 + 1 file changed, 1 insertion(+) -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/rules b/src/lm-sensors/lm-sensors-3.4.0/debian/rules +diff --git a/debian/rules b/debian/rules index 5ebda06..1d77e28 100755 ---- a/src/lm-sensors/lm-sensors-3.4.0/debian/rules -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/rules +--- a/debian/rules ++++ b/debian/rules @@ -56,3 +56,4 @@ override_dh_auto_install-arch: - + override_dh_installinit-arch: dh_installinit -plm-sensors --no-start + dh_installinit -psensord --no-start --- +-- 2.17.1 diff --git a/src/lm-sensors/patch/series b/src/lm-sensors/patch/series new file mode 100644 index 000000000000..43980ccab4db --- /dev/null +++ b/src/lm-sensors/patch/series @@ -0,0 +1,2 @@ +0001-patch-the-debian-package-info-to-get-sensord.patch +0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch diff --git a/src/sonic-sairedis b/src/sonic-sairedis index ccbb3bcc877c..d54bfb454356 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit ccbb3bcc877cff271104ed428d9aadc4438dd73a +Subproject commit d54bfb45435685059578ea53453e797b87241617 From b3ae7858ca255706e2d5a8f94a00f393667225bb Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Sat, 18 Jul 2020 17:22:05 +0530 Subject: [PATCH 0928/1427] [Juniper][QFX5200] Adding qos.json (#4982) Adding buffers.json.j2, buffers_defaults_t1.j2 and qos.json.j2 for qfx5200 platform. Signed-off-by: Ciju Rajan K --- .../Juniper-QFX5200-32C-S/buffers.json.j2 | 1 + .../buffers_defaults_t1.j2 | 46 +++++++++++++++++++ .../Juniper-QFX5200-32C-S/qos.json.j2 | 1 + 3 files changed, 48 insertions(+) create mode 100644 device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers.json.j2 create mode 100644 device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers_defaults_t1.j2 create mode 100644 device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/qos.json.j2 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers.json.j2 b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers_defaults_t1.j2 b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..3442612f70b2 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ +{%- set default_cable = '5m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "33329088", + "type": "ingress", + "mode": "dynamic", + "xoff": "7827456" + }, + "egress_lossy_pool": { + "size": "26663272", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "42349632", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"44302336" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"42349632" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1664", + "dynamic_th":"-1" + } + }, +{%- endmacro %} diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/qos.json.j2 b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} From aa9e1e2f437f201d1ca3513c690666494690fbf2 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sun, 19 Jul 2020 03:39:49 +0000 Subject: [PATCH 0929/1427] [vstest]: convert the tests to python3 Signed-off-by: Guohan Lu --- platform/vs/tests/bgp/test_gr_livelock.py | 42 +++++++++---------- platform/vs/tests/bgp/test_invalid_nexthop.py | 4 +- platform/vs/tests/bgp/test_no_export.py | 4 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/platform/vs/tests/bgp/test_gr_livelock.py b/platform/vs/tests/bgp/test_gr_livelock.py index 5f85bfc239b5..cd72ffef3e4f 100644 --- a/platform/vs/tests/bgp/test_gr_livelock.py +++ b/platform/vs/tests/bgp/test_gr_livelock.py @@ -6,7 +6,7 @@ import random def output(dvs, title): - print "=========================== %s ===========================" % title + print("=========================== %s ===========================" % title) exit_cod, sum_res = dvs.runcmd(["vtysh", "-c", "show ip bgp sum"]) exit_code, all_route = dvs.runcmd(["vtysh", "-c", "show ip bgp"]) exit_code, neig_1 = dvs.runcmd(["vtysh", "-c", "show ip bgp neighbors 10.0.0.1"]) @@ -14,22 +14,22 @@ def output(dvs, title): exit_code, received_route_1 = dvs.runcmd(["vtysh", "-c", "show ip bgp neighbors 10.0.0.1 routes"]) exit_code, announce_route_3 = dvs.runcmd(["vtysh", "-c", "show ip bgp neighbors 10.0.0.3 advertised-routes"]) exit_code, received_route_3 = dvs.runcmd(["vtysh", "-c", "show ip bgp neighbors 10.0.0.3 routes"]) - print "Summary:" - print sum_res - print "Received routes:" - print "10.0.0.1" - print received_route_1 - print "10.0.0.3" - print received_route_3 - print "Announces routes:" - print "10.0.0.1" - print announce_route_1 - print "10.0.0.3" - print announce_route_3 - print "Neighbors" - print "10.0.0.1" - print neig_1 - print "======================================================" + print("Summary:") + print(sum_res) + print("Received routes:") + print("10.0.0.1") + print(received_route_1) + print("10.0.0.3") + print(received_route_3) + print("Announces routes:") + print("10.0.0.1") + print(announce_route_1) + print("10.0.0.3") + print(announce_route_3) + print("Neighbors") + print("10.0.0.1") + print(neig_1) + print("======================================================") def mkdir(path): if not os.path.exists(path): @@ -66,11 +66,11 @@ def run_exa(dvs, idx, cfg): remove(fifo_out_path) os.mkfifo(fifo_in_path) os.mkfifo(fifo_out_path) - os.chmod(fifo_in_path, 0666) - os.chmod(fifo_out_path, 0666) - print "!!! Start exabgp instance %d" % idx + os.chmod(fifo_in_path, 0o666) + os.chmod(fifo_out_path, 0o666) + print("!!! Start exabgp instance %d" % idx) cmd = "exabgp -d --env %s %s" % (get_target_env(idx), cfg) - print "Cmd is ___ %s ___" % cmd + print("Cmd is ___ %s ___" % cmd) return dvs.servers[idx].runcmd_async(cmd) def run_exacli(dvs, idx, cmd): diff --git a/platform/vs/tests/bgp/test_invalid_nexthop.py b/platform/vs/tests/bgp/test_invalid_nexthop.py index 24f3d8790b9c..3e8acd94e20d 100644 --- a/platform/vs/tests/bgp/test_invalid_nexthop.py +++ b/platform/vs/tests/bgp/test_invalid_nexthop.py @@ -17,7 +17,7 @@ def test_InvalidNexthop(dvs, testlog): time.sleep(5) - print dvs.runcmd("supervisorctl status") + print(dvs.runcmd("supervisorctl status")) p = dvs.servers[0].runcmd_async("exabgp -d bgp/files/invalid_nexthop/invalid_nexthop.conf") @@ -28,6 +28,6 @@ def test_InvalidNexthop(dvs, testlog): p.terminate() p = p.wait() - print exit_code, output + print(exit_code, output) assert "3333::/64" in output diff --git a/platform/vs/tests/bgp/test_no_export.py b/platform/vs/tests/bgp/test_no_export.py index 61858bc78200..b2c7c5e7cbde 100644 --- a/platform/vs/tests/bgp/test_no_export.py +++ b/platform/vs/tests/bgp/test_no_export.py @@ -36,8 +36,8 @@ def test_bounce(dvs, testlog): p2.terminate() p2 = p2.wait() - print sum_res - print announce_route + print(sum_res) + print(announce_route) assert "1.1.1.1/32" in all_route assert "1.1.1.1/32" not in announce_route assert "2.2.2.2/32" in all_route From c9983df062d21d23bd7fa94297fa32c69fbda9a9 Mon Sep 17 00:00:00 2001 From: vdahiya12 <67608553+vdahiya12@users.noreply.github.com> Date: Sun, 19 Jul 2020 20:58:52 -0700 Subject: [PATCH 0930/1427] [daemon_base] fix to not reregister signal handler (#4998) * [daemon_base] fix to not reregister signal handler -src/sonic-daemon-base/sonic_daemon_base/daemon_base.py Problem: Currently all daemons inherit from daemon_base class, and for signal handling functionality they register the signal_handler() by overriding the siganl_handler() in daemon_base by their own implmentation. But some sonic_platform instances also can invoke the daemon_base constructor while trying to instantiate the common utilities for example platform_chassis = sonic_platform.platform.Platform().get_chassis() This will cause the re registration of signal_handler which will cause base class signal_handler() to be invoked when the daemon gets a signal, whereas their own signal_handler should have been invoked. Fix: We only register the siganl_handler once, and if signal_handler has been registered, not re register it. Signed-off-by: vaibhav-dahiya * [daemon_base] fix to not reregister signal handler Signed-off-by: vaibhav-dahiya --- .../sonic_daemon_base/daemon_base.py | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index 0e579515365c..ae4b3b916ccf 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -90,9 +90,25 @@ def log_debug(self, msg, also_print_to_console=False): class DaemonBase(object): def __init__(self): # Register our signal handlers - signal.signal(signal.SIGHUP, self.signal_handler) - signal.signal(signal.SIGINT, self.signal_handler) - signal.signal(signal.SIGTERM, self.signal_handler) + '''all daemons inherit from daemon_base class, and for + signal handling functionality they register the signal_handler() by + overriding the siganl_handler() in daemon_base by their own + implmentation. + But some sonic_platform instances also can invoke the daemon_base + constructor while trying to instantiate the common utilities + for example + platform_chassis = sonic_platform.platform.Platform().get_chassis() + This will cause the re registration of signal_handler which will + cause base class signal_handler() to be invoked when the daemon + gets a signal, whereas the derived class signal_handler should have + been invoked. The if checks will not allow the re registration + of signal handler ''' + if not signal.getsignal(signal.SIGHUP): + signal.signal(signal.SIGHUP, self.signal_handler) + if not signal.getsignal(signal.SIGINT): + signal.signal(signal.SIGINT, self.signal_handler) + if not signal.getsignal(signal.SIGTERM): + signal.signal(signal.SIGTERM, self.signal_handler) # Signal handler def signal_handler(self, sig, frame): From 5d753b8d4332d19b274dc64dad2c44488f8c7b4b Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Mon, 20 Jul 2020 07:50:26 +0300 Subject: [PATCH 0931/1427] [services] remove swss from WantedBy for nat service (#4991) Otherwise, it may cause issues for warm restarts, warm reboot. Warm restart of swss will start nat which is not expected for warm restart. Also it is observed that during warm-reboot script execution nat container gets started after it was killed. This causes removal of nat dump generated by nat previously: A check [ -f /host/warmboot/nat/nat_entries.dump ] || echo "NAT dump does not exists" was added right before kexec: ``` Fri Jul 17 10:47:16 UTC 2020 Prepare MLNX ASIC to fastfast-reboot: install new FW if required Fri Jul 17 10:47:18 UTC 2020 Pausing orchagent ... Fri Jul 17 10:47:18 UTC 2020 Stopping nat ... Fri Jul 17 10:47:18 UTC 2020 Stopped nat ... Fri Jul 17 10:47:18 UTC 2020 Stopping radv ... Fri Jul 17 10:47:19 UTC 2020 Stopping bgp ... Fri Jul 17 10:47:19 UTC 2020 Stopped bgp ... Fri Jul 17 10:47:21 UTC 2020 Initialize pre-shutdown ... Fri Jul 17 10:47:21 UTC 2020 Requesting pre-shutdown ... Fri Jul 17 10:47:22 UTC 2020 Waiting for pre-shutdown ... Fri Jul 17 10:47:24 UTC 2020 Pre-shutdown succeeded ... Fri Jul 17 10:47:24 UTC 2020 Backing up database ... Fri Jul 17 10:47:25 UTC 2020 Stopping teamd ... Fri Jul 17 10:47:25 UTC 2020 Stopped teamd ... Fri Jul 17 10:47:25 UTC 2020 Stopping syncd ... Fri Jul 17 10:47:35 UTC 2020 Stopped syncd ... Fri Jul 17 10:47:35 UTC 2020 Stopping all remaining containers ... Warning: Stopping telemetry.service, but it can still be activated by: telemetry.timer Fri Jul 17 10:47:37 UTC 2020 Stopped all remaining containers ... NAT dump does not exists Fri Jul 17 10:47:39 UTC 2020 Rebooting with /sbin/kexec -e to SONiC-OS-201911.140-08245093 ... ``` With this change, executed warm-reboot 10 times without hitting this issue, while without this change the issue is easily reproducible almost every warm-reboot run. Signed-off-by: Stepan Blyschak --- files/build_templates/nat.service.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/nat.service.j2 b/files/build_templates/nat.service.j2 index 4a0e20efaee8..1d267cfe9302 100644 --- a/files/build_templates/nat.service.j2 +++ b/files/build_templates/nat.service.j2 @@ -15,5 +15,5 @@ Restart=always RestartSec=30 [Install] -WantedBy=multi-user.target swss.service +WantedBy=multi-user.target From c6027ab46ff764d3a2dd4f933b3ec0e7e8de275d Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 20 Jul 2020 02:59:55 -0700 Subject: [PATCH 0932/1427] [submodule]: update sonic-swss (#5002) * d2bab10 2020-07-19 | [vstest]: use BytesIO for file operations [lguohan] * 982c9a3 2020-07-18 | [vstest]: fix vstest for python3 (#1354) [lguohan] * ffa0dc3 2020-07-16 | [vstest]: clean up processes in server namespace at start (#1353) [lguohan] * b16368c 2020-07-15 | [aclorch.cpp] Handle all the ACL redirect requests in AclRuleL3::validateAddAction() (#1278) [madhanmellanox] * 310e0aa 2020-07-15 | [portsorch,intfsorch] add port, rif rates FC groups (#1201) [Mykola F] * 5ddea37 2020-07-09 | [NAT]: Update NAT conntrack entries from natmgr instead of natorch (#1274) [Akhilesh Samineni] * 94c622f 2020-07-07 | [aclorch] Use IPv6 Next Header internally for protocol number on MLNX platform (#1343) [Danny Allen] * 82d36c4 2020-07-07 | support swss vstest in python3 [lguohan] |\ | * ff04e6d 2020-06-27 | [doc]: update instruction to run vstest under python3 [Guohan Lu] | * c90b281 2020-07-05 | [vstest]: reuse dvs setReadOnlyAttr in test_crm.py [Guohan Lu] | * 8807b40 2020-07-05 | [vstest]: fix string format compatibility issue for python2 and swig [Guohan Lu] | * 26efbcf 2020-07-04 | [vstest]: change float division to integer division [Guohan Lu] | * 6adaf2e 2020-07-04 | [vstest]: change time.clock() to time.time() [Guohan Lu] | * 9c71203 2020-07-04 | [vstest]: let redis decodes the response to be string instead of bytes [Guohan Lu] | * c7c63ee 2020-06-27 | [vstest]: change from platform to distro [Guohan Lu] | * d7ff1ad 2020-06-27 | [vstest]: upgrade swss vs tests to python3 [Guohan Lu] * | 2ebd44e 2020-07-03 | [sonic-swss] ARMHF warning fixes (#1325) [arheneus@marvell.com] * | 10ad70c 2020-07-02 | [swss] Add support for gearbox phys (#1321) [Syd Logan] Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 01f810f43e71..d2bab10efe05 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 01f810f43e71a570f7821c63f8ac030c03f88150 +Subproject commit d2bab10efe05e8ec209fd5a360778a2d7c8d7f54 From 52c3a238bb54bdf38462c867f1e65cdeee2b801f Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Mon, 20 Jul 2020 21:11:51 +0300 Subject: [PATCH 0933/1427] [barefoot][platform] increase init timeout in eeprom.py (#5006) Because of platform-specific reasons I have to increase init timeout in (platform-plugin)/eeprom.py --- .../x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py index 9c14441475d4..d50380b97cfd 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py @@ -77,7 +77,7 @@ EEPROM_STATUS = "/var/run/platform/eeprom/status" class board(eeprom_tlvinfo.TlvInfoDecoder): - RETRIES = 3 + RETRIES = 35 def __init__(self, name, path, cpld_root, ro): @@ -101,8 +101,10 @@ def __init__(self, name, path, cpld_root, ro): super(board, self).__init__(self.eeprom_path, 0, EEPROM_STATUS, True) for attempt in range(self.RETRIES): - if self.eeprom_init() or (attempt + 1 >= self.RETRIES): + if self.eeprom_init(): break + if attempt + 1 == self.RETRIES: + raise RuntimeError("eeprom.py: Initialization failed") time.sleep(1) def thrift_setup(self): From 6ef199ffdd4f7da58d37e1068e8dc29ab5841c7e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 20 Jul 2020 11:21:24 -0700 Subject: [PATCH 0934/1427] [sonic-utilities] Update submodule (#5004) * src/sonic-utilities a23479e...82dfe50 (3): > [sonic-installer] Update group name for 'verify-next-image' subcommand (#/995) > [acl_loader] Fix bugs in acl_loader (#991) > [show] Add support for QSFP-DD cables on 'show' command (#989) This submodule update resolves https://github.com/Azure/sonic-utilities/issues/997 by including PR https://github.com/Azure/sonic-utilities/pull/995 --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index a23479e8cf79..82dfe50578da 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit a23479e8cf792c9c821329dc374c3ce0f9bd8348 +Subproject commit 82dfe50578dac1d86951ff32edb0b8b3912a8df7 From 43b5832e0c165efaa504b2e3504b0bc042297f17 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 20 Jul 2020 11:23:05 -0700 Subject: [PATCH 0935/1427] [sudoers] Add `sonic-installer list` to read-only commands (#4996) `sonic-installer list` is a read-only command. Specify it as such in the sudoers file. This will also ensure the new `show boot` command, which calls `sudo sonic-installer list` under the hood doesn't fail due to permissions. --- files/image_config/sudoers/sudoers | 1 + 1 file changed, 1 insertion(+) diff --git a/files/image_config/sudoers/sudoers b/files/image_config/sudoers/sudoers index 45b943846cb1..98493b25856c 100644 --- a/files/image_config/sudoers/sudoers +++ b/files/image_config/sudoers/sudoers @@ -31,6 +31,7 @@ Cmnd_Alias READ_ONLY_CMDS = /sbin/brctl show, \ /usr/bin/lldpshow, \ /usr/bin/psuutil *, \ /usr/bin/sensors, \ + /usr/bin/sonic-installer list, \ /usr/bin/sfputil show *, \ /usr/bin/teamshow, \ /usr/bin/vtysh -c show *, \ From 07d559103f6ca48329468a85e798260cbd55b9f1 Mon Sep 17 00:00:00 2001 From: anish-n <44376847+anish-n@users.noreply.github.com> Date: Tue, 21 Jul 2020 02:55:42 -0700 Subject: [PATCH 0936/1427] [bgpcfgd]: Add fix to bgpcfgd to ignore NEIGHBOR_METADATA entries for dynamic peers (#5008) This fix removes the requirement to have a NEIGHBOR_METADATA for dynamic peers. The change is made since it is not necessary for NEIGHBOR_METADATA entries be present for the dynamic neighbors --- src/sonic-bgpcfgd/bgpcfgd | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd index 38d7f0671f89..5df174ef357c 100755 --- a/src/sonic-bgpcfgd/bgpcfgd +++ b/src/sonic-bgpcfgd/bgpcfgd @@ -453,7 +453,7 @@ class BGPPeerGroupMgr(object): class BGPPeerMgrBase(Manager): """ Manager of BGP peers """ - def __init__(self, common_objs, db_name, table_name, peer_type): + def __init__(self, common_objs, db_name, table_name, peer_type, check_neig_meta): """ Initialize the object :param common_objs: common objects @@ -480,9 +480,13 @@ class BGPPeerMgrBase(Manager): ("LOCAL", "interfaces", ""), ] - self.check_neig_meta = 'bgp' in self.constants \ + if check_neig_meta: + self.check_neig_meta = 'bgp' in self.constants \ and 'use_neighbors_meta' in self.constants['bgp'] \ and self.constants['bgp']['use_neighbors_meta'] + else: + self.check_neig_meta = False + self.check_deployment_id = 'bgp' in self.constants \ and 'use_deployment_id' in self.constants['bgp'] \ and self.constants['bgp']['use_deployment_id'] @@ -862,9 +866,9 @@ def main(): # State DB managers ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME), # Peer Managers - BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general"), - BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors"), - BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic"), + BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", True), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), ] runner = Runner() for mgr in managers: From 1870c181c572311feefc31a5f6628b312bd36cc1 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 21 Jul 2020 03:05:00 -0700 Subject: [PATCH 0937/1427] Update PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b86fef4c0aef..38fbae5f8de4 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -16,6 +16,19 @@ Please provide the following information: **- How to verify it** +**- Which release branch to backport (provide reason below if seleted)** + + + +- [ ] 201811 +- [ ] 201911 +- [ ] 202006 + **- Description for the changelog** 2x50G passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '4x25G[10G]') + expected_dict = expected["Ethernet4_4x25G"] + assert output_dict == expected_dict + print("**** 1X100G --> 4x25G[10G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '2x25G(2)+1x50G(2)') + expected_dict = expected["Ethernet8_2x25G_1x50G"] + assert output_dict == expected_dict + print("**** 1X100G --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet12', '1x50G(2)+2x25G(2)') + expected_dict = expected["Ethernet12_1x50G_2x25G"] + assert output_dict == expected_dict + print("**** 1X100G --> 1x50G(2)+2x25G(2) passed ****") + + #TODOFIX: remove comments once #4442 PR got merged. + """ + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 2x50G --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '4x25G[10G]') + expected_dict = expected["Ethernet0_4x25G"] + assert output_dict == expected_dict + print("**** 1X100G --> 4x25G[10G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 4x25G[10G] --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '2x50G') + print("**** 1X100G --> 2x50G mode change ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '4x25G[10G]') + expected_dict = expected["Ethernet4_4x25G"] + assert output_dict == expected_dict + print("**** 2X50G --> 4x25G[10G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '2x50G') + expected_dict = expected["Ethernet4_2x50G"] + assert output_dict == expected_dict + print("**** 4x25G[10G] --> 2X50G passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '1x100G[40G]') + print("**** 2x50G -- > 1X100G mode change ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '2x25G(2)+1x50G(2)') + expected_dict = expected["Ethernet0_2x25G_1x50G"] + assert output_dict == expected_dict + print("**** 1x100G[40G] --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 2x25G(2)+1x50G(2) --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x50G(2)+2x25G(2)') + expected_dict = expected["Ethernet0_1x50G_2x25G"] + assert output_dict == expected_dict + print("**** 1x100G[40G] --> 1x50G(2)+2x25G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 1x50G(2)+2x25G(2) --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '2x50G') + print("**** 1x100G[40G] --> 2x50G mode change ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '1x50G(2)+2x25G(2)') + expected_dict = expected["Ethernet8_1x50G_2x25G"] + assert output_dict == expected_dict + print("**** 2x50G --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '2x25G(2)+1x50G(2)') + expected_dict = expected["Ethernet8_2x25G_1x50G"] + assert output_dict == expected_dict + print("**** 1x50G(2)+2x25G(2) --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '1x100G[40G]') + expected_dict = expected["Ethernet8_1x100G"] + assert output_dict == expected_dict + print("**** 2x25G(2)+1x50G(2) --> 1x100G[40G] passed ****") + """ diff --git a/src/sonic-utilities b/src/sonic-utilities index 995cf3988c07..c0c3cce6bee0 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 995cf3988c0754a1627b98e90c7e6f3ac4fd106e +Subproject commit c0c3cce6bee0e335cf1b5528f1172b511d48ee12 From 172354d36aed57a775bcbe4bd83589f97c3465f3 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 4 Aug 2020 23:51:35 -0700 Subject: [PATCH 0985/1427] [sonic-py-common] get_platform(): Refactor method of retrieving platform identifier (#5094) Applications running in the host OS can read the platform identifier from /host/machine.conf. When loading configuration, sonic-config-engine *needs* to read the platform identifier from machine.conf, as it it responsible for populating the value in Config DB. When an application is running inside a Docker container, the machine.conf file is not accessible, as the /host directory is not mounted. So we need to retrieve the platform identifier from Config DB if get_platform() is called from inside a Docker container. However, we can't simply check that we're running in a Docker container because the host OS of the SONiC virtual switch is running inside a Docker container. So I refactored `get_platform()` to: 1. Read from the `PLATFORM` environment variable if it exists (which is defined in a virtual switch Docker container) 2. Read from machine.conf if possible (works in the host OS of a standard SONiC image, critical for sonic-config-engine at boot) 3. Read the value from Config DB (needed for Docker containers running in SONiC, as machine.conf is not accessible to them) - Also fix typo in daemon_base.py - Also changes to align `get_hwsku()` with `get_platform()` --- platform/vs/docker-sonic-vs/start.sh | 4 +- .../sonic_py_common/daemon_base.py | 2 +- .../sonic_py_common/device_info.py | 41 ++++++++++++++++--- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 498c2448ce0c..5509ec4292f9 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -2,8 +2,8 @@ # generate configuration -PLATFORM=x86_64-kvm_x86_64-r0 -HWSKU=Force10-S6000 +export PLATFORM=x86_64-kvm_x86_64-r0 +export HWSKU=Force10-S6000 ln -sf /usr/share/sonic/device/$PLATFORM/$HWSKU /usr/share/sonic/hwsku diff --git a/src/sonic-py-common/sonic_py_common/daemon_base.py b/src/sonic-py-common/sonic_py_common/daemon_base.py index 77188a004f78..6a2c6a22d2aa 100644 --- a/src/sonic-py-common/sonic_py_common/daemon_base.py +++ b/src/sonic-py-common/sonic_py_common/daemon_base.py @@ -56,7 +56,7 @@ def load_platform_util(self, module_name, class_name): platform_util = None # Get path to platform and hwsku - (platform_path, hwsku_path) = device_info.get_paths_to_platform_and_hwsku() + (platform_path, hwsku_path) = device_info.get_paths_to_platform_and_hwsku_dirs() try: module_file = "/".join([platform_path, "plugins", module_name + ".py"]) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index a1645182a84c..99f818b0f27e 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -58,6 +58,17 @@ def get_platform(): Returns: A string containing the device's platform identifier """ + + # If we are running in a virtual switch Docker container, the environment + # variable 'PLATFORM' will be defined and will contain the platform + # identifier. + platform_env = os.getenv("PLATFORM") + if platform_env: + return platform_env + + # If 'PLATFORM' env variable is not defined, we try to read the platform + # identifier from machine.conf. This is critical for sonic-config-engine, + # because it is responsible for populating this value in Config DB. machine_info = get_machine_info() if machine_info: if 'onie_platform' in machine_info: @@ -65,6 +76,21 @@ def get_platform(): elif 'aboot_platform' in machine_info: return machine_info['aboot_platform'] + # If we fail to read from machine.conf, we may be running inside a Docker + # container in SONiC, where the /host directory is not mounted. In this + # case the value should already be populated in Config DB so we finally + # try reading it from there. + try: + config_db = ConfigDBConnector() + config_db.connect() + + metadata = config_db.get_table('DEVICE_METADATA') + + if 'localhost' in metadata and 'platform' in metadata['localhost']: + return metadata['localhost']['platform'] + except Exception: + pass + return None @@ -75,15 +101,18 @@ def get_hwsku(): Returns: A string containing the device's hardware SKU identifier """ - config_db = ConfigDBConnector() - config_db.connect() + try: + config_db = ConfigDBConnector() + config_db.connect() - metadata = config_db.get_table('DEVICE_METADATA') + metadata = config_db.get_table('DEVICE_METADATA') - if 'localhost' in metadata and 'hwsku' in metadata['localhost']: - return metadata['localhost']['hwsku'] + if 'localhost' in metadata and 'hwsku' in metadata['localhost']: + return metadata['localhost']['hwsku'] + except Exception: + pass - return "" + return None def get_platform_and_hwsku(): From 569289ac86f8a3f5a195ccd4aec613311cb69a0f Mon Sep 17 00:00:00 2001 From: gechiang <62408185+gechiang@users.noreply.github.com> Date: Wed, 5 Aug 2020 09:12:04 -0700 Subject: [PATCH 0986/1427] =?UTF-8?q?Moving=20BRCM=20SAI=20from=203.7.5.1-?= =?UTF-8?q?1=20to=203.7.5.1-2=20to=20pick=20up=20the=20stubbed=20SA?= =?UTF-8?q?=E2=80=A6=20(#5101)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Moving BRCM SAI from 3.7.5.1-1 to 3.7.5.1-2 to pick up the stubbed SAI API that were present in the header but missing in SAI implementation that cause link error during build. In SAI header 1.5.2 there are defined SAI APIs such as "sai_query_attribute_capability()" and few other APIs that were missing the stub code in BRCM 3.7.5.1 SAI code delivery. This causes linking issue during build when we implemented the common handler to support "sai_query_attribute_capability()" that other platform supports. The expectation is that all SAI vendors must implement all the SAI header defined SAI APIs by stubbing those that they don't have the actual code support to return "SAI_STATUS_NOT_IMPLEMENTED". This allows common code for all platforms to be developed without having linking issue during build for all platforms. BRCM has provided the patch code and this PR moves the BRCM SAI from 3.7.5.1-1 to 3.7.5.1-2 to pick up those missing stubbed SAI APIs. See BRCM case CS00010790550 for more details --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 724b4fba6e77..a2232367fd27 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,8 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.5.1-1_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm_3.7.5.1-1_amd64.deb?sv=2015-04-05&sr=b&sig=vSaGIDz2fHBtQXmwJ8OrulAF1N%2Bwk%2B51CkqwNiZFx6I%3D&se=2034-03-10T00%3A45%3A39Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.5.1-1_amd64.deb +BRCM_SAI = libsaibcm_3.7.5.1-2_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm_3.7.5.1-2_amd64.deb?sv=2015-04-05&sr=b&sig=Ir7VDgFPOs4mU0k%2Fu76shUBpysh46Q1Btt0i%2FdhM0Ig%3D&se=2034-04-14T01%3A19%3A11Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_3.7.5.1-2_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm-dev_3.7.5.1-1_amd64.deb?sv=2015-04-05&sr=b&sig=XpczZg8q3b2z3754wXdc4faOXOFofdlydJKEQaed01o%3D&se=2034-03-10T00%3A46%3A38Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm-dev_3.7.5.1-2_amd64.deb?sv=2015-04-05&sr=b&sig=sBiXxx2vncp0GLHIPx4IyiJQBqFV%2BGWUmdr7ccrnsT4%3D&se=2034-04-14T01%3A18%3A39Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 6c2c9fe93cc5f2f520e48f6045c1d0ea1f04da8f Mon Sep 17 00:00:00 2001 From: Petro Bratash <68950226+bratashX@users.noreply.github.com> Date: Wed, 5 Aug 2020 20:47:07 +0300 Subject: [PATCH 0987/1427] [BFN] Added skip_pcied for Barefoot platforms (#5105) It`s a temporary solution to avoid pmon container failure, implementation will be added later. Signed-off-by: Petro Bratash --- .../x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json | 1 + .../x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json | 1 + .../x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json | 1 + 3 files changed, 3 insertions(+) diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json index 0508c5cac0da..bee6a60418cf 100644 --- a/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { + "skip_pcied": true, "skip_fancontrol": true, "skip_thermalctld": true, "skip_ledd": true, diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json index ae8601e866b4..f94fa8370273 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { + "skip_pcied": true, "skip_fancontrol": true, "skip_thermalctld": true, "skip_ledd": true, diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json index ae8601e866b4..f94fa8370273 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { + "skip_pcied": true, "skip_fancontrol": true, "skip_thermalctld": true, "skip_ledd": true, From 082c26a27d6e0037f509b4f5b249506d45343b20 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 5 Aug 2020 13:23:12 -0700 Subject: [PATCH 0988/1427] [build]: combine feature and container feature table (#5081) 1. remove container feature table 2. do not generate feature entry if the feature is not included in the image 3. rename ENABLE_* to INCLUDE_* for better clarity 4. rename feature status to feature state 5. [submodule]: update sonic-utilities * 9700e45 2020-08-03 | [show/config]: combine feature and container feature cli (#1015) (HEAD, origin/master, origin/HEAD) [lguohan] * c9d3550 2020-08-03 | [tests]: fix drops_group_test failure on second run (#1023) [lguohan] * dfaae69 2020-08-03 | [lldpshow]: Fix input device is not a TTY error (#1016) [Arun Saravanan Balachandran] * 216688e 2020-08-02 | [tests]: rename sonic-utilitie-tests to tests (#1022) [lguohan] Signed-off-by: Guohan Lu --- Makefile.work | 8 ++-- build_debian.sh | 2 +- files/build_scripts/mask_disabled_services.py | 2 +- files/build_templates/init_cfg.json.j2 | 29 ++++++++----- .../build_templates/sonic_debian_extension.j2 | 6 +-- files/image_config/hostcfgd/hostcfgd | 34 +++++++-------- files/scripts/supervisor-proc-exit-listener | 29 +++++++------ platform/marvell-arm64/rules.mk | 2 +- platform/marvell-armhf/rules.mk | 2 +- rules/config | 32 +++++++-------- rules/docker-iccpd.mk | 2 +- rules/docker-nat.mk | 4 +- rules/docker-restapi.mk | 2 +- rules/docker-sflow.mk | 4 +- rules/docker-sonic-mgmt-framework.mk | 4 +- rules/docker-telemetry.mk | 4 +- rules/sonic-mgmt-framework.mk | 2 +- slave.mk | 41 +++++++++++-------- src/sonic-utilities | 2 +- 19 files changed, 112 insertions(+), 99 deletions(-) diff --git a/Makefile.work b/Makefile.work index eca21445f138..253d2039a9a4 100644 --- a/Makefile.work +++ b/Makefile.work @@ -9,7 +9,7 @@ # through http. # * ENABLE_ZTP: Enables zero touch provisioning. # * SHUTDOWN_BGP_ON_START: Sets admin-down state for all bgp peerings after restart. -# * INSTALL_KUBERNETES: Allows including Kubernetes +# * INCLUDE_KUBERNETES: Allows including Kubernetes # * ENABLE_PFCWD_ON_START: Enable PFC Watchdog (PFCWD) on server-facing ports # * by default for TOR switch. # * ENABLE_SYNCD_RPC: Enables rpc-based syncd builds. @@ -188,7 +188,7 @@ SONIC_BUILD_INSTRUCTION := make \ ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \ ENABLE_ZTP=$(ENABLE_ZTP) \ SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \ - INSTALL_KUBERNETES=$(INSTALL_KUBERNETES) \ + INCLUDE_KUBERNETES=$(INCLUDE_KUBERNETES) \ KUBERNETES_VERSION=$(KUBERNETES_VERSION) \ KUBERNETES_CNI_VERSION=$(KUBERNETES_CNI_VERSION) \ K8s_GCR_IO_PAUSE_VERSION=$(K8s_GCR_IO_PAUSE_VERSION) \ @@ -207,8 +207,8 @@ SONIC_BUILD_INSTRUCTION := make \ SONIC_DPKG_CACHE_SOURCE=$(SONIC_DPKG_CACHE_SOURCE) \ HTTP_PROXY=$(http_proxy) \ HTTPS_PROXY=$(https_proxy) \ - SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY) \ - SONIC_ENABLE_RESTAPI=$(ENABLE_RESTAPI) \ + SONIC_INCLUDE_SYSTEM_TELEMETRY=$(INCLUDE_SYSTEM_TELEMETRY) \ + SONIC_INCLUDE_RESTAPI=$(INCLUDE_RESTAPI) \ TELEMETRY_WRITABLE=$(TELEMETRY_WRITABLE) \ EXTRA_DOCKER_TARGETS=$(EXTRA_DOCKER_TARGETS) \ BUILD_LOG_TIMESTAMP=$(BUILD_LOG_TIMESTAMP) \ diff --git a/build_debian.sh b/build_debian.sh index 952ee9e91a9f..529d74faab6e 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -212,7 +212,7 @@ fi sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 -if [ "$INSTALL_KUBERNETES" == "y" ] +if [ "$INCLUDE_KUBERNETES" == "y" ] then ## Install Kubernetes echo '[INFO] Install kubernetes' diff --git a/files/build_scripts/mask_disabled_services.py b/files/build_scripts/mask_disabled_services.py index e2597ac686f1..f3a1d76bf102 100755 --- a/files/build_scripts/mask_disabled_services.py +++ b/files/build_scripts/mask_disabled_services.py @@ -9,5 +9,5 @@ init_cfg = json.load(init_cfg_file) if 'FEATURE' in init_cfg: for feature_name, feature_props in init_cfg['FEATURE'].items(): - if 'status' in feature_props and feature_props['status'] == 'disabled': + if 'state' in feature_props and feature_props['state'] == 'disabled': subprocess.run(['systemctl', 'mask', '{}.service'.format(feature_name)]) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 90980fe069a6..63d54989f5d0 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -17,18 +17,27 @@ {% endfor %} } }, +{%- set features = [("bgp", "enabled", "enabled"), + ("database", "enabled", "disabled"), + ("dhcp_relay", "enabled", "enabled"), + ("lldp", "enabled", "enabled"), + ("pmon", "enabled", "enabled"), + ("radv", "enabled", "enabled"), + ("snmp", "enabled", "enabled"), + ("swss", "enabled", "enabled"), + ("syncd", "enabled", "enabled"), + ("teamd", "enabled", "enabled")] %} +{%- if include_iccpd == "y" %}{% do features.append(("iccpd", "disabled", "enabled")) %}{% endif %} +{%- if include_mgmt_framework == "y" %}{% do features.append(("mgmt-framework", "enabled", "enabled")) %}{% endif %} +{%- if include_nat == "y" %}{% do features.append(("nat", "disabled", "enabled")) %}{% endif %} +{%- if include_restapi == "y" %}{% do features.append(("restapi", "disabled", "enabled")) %}{% endif %} +{%- if include_sflow == "y" %}{% do features.append(("sflow", "disabled", "enabled")) %}{% endif %} +{%- if include_system_telemetry == "y" %}{% do features.append(("telemetry", "enabled", "enabled")) %}{% endif %} "FEATURE": { -{%- for feature, status in [("sflow", "disabled"), ("telemetry", "enabled")] %} +{%- for feature, state, autorestart in features %} "{{feature}}": { - "status": "{{status}}" - }{% if not loop.last %},{% endif -%} -{% endfor %} - }, - "CONTAINER_FEATURE": { -{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "nat", "pmon", "radv", "restapi", "sflow", - "snmp", "swss", "syncd", "teamd", "telemetry"] %} - "{{container}}": { - "auto_restart": "{% if container == "database" %}disabled{% else %}enabled{% endif %}", + "state": "{{state}}", + "auto_restart": "{{autorestart}}", "high_mem_alert": "disabled" }{% if not loop.last %},{% endif -%} {% endfor %} diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 72454c60902c..34dcd48f9341 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -307,7 +307,7 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-s sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog==0.10.2 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures==3.3.0 -{% if install_kubernetes == "y" %} +{% if include_kubernetes == "y" %} # Copy kubelet service files # Keep it disabled until join, else it continuously restart and as well spew too many # non-required log lines wasting syslog resources. @@ -481,7 +481,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta {% endif %} {% endfor %} -{% if install_kubernetes == "y" %} +{% if include_kubernetes == "y" %} ## Pull in kubernetes docker images echo "pulling universal k8s images ..." FLANNEL_ARCH=$([ "${CONFIGURED_ARCH}" == "armhf" ] && echo "arm64" || echo "${CONFIGURED_ARCH}") @@ -537,7 +537,7 @@ sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netn # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "snmp.timer" | sudo tee -a $GENERATED_SERVICE_FILE -{% if enable_system_telemetry == 'y' %} +{% if include_system_telemetry == 'y' %} sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "telemetry.timer" | sudo tee -a $GENERATED_SERVICE_FILE {% endif %} diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 67d5126773f8..3a895a729b19 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -41,8 +41,8 @@ def obfuscate(data): return data -def update_feature_status(feature_name, status): - if status == "enabled": +def update_feature_state(feature_name, state): + if state == "enabled": start_cmds = [] start_cmds.append("sudo systemctl unmask {}.service".format(feature_name)) start_cmds.append("sudo systemctl enable {}.service".format(feature_name)) @@ -56,7 +56,7 @@ def update_feature_status(feature_name, status): .format(err.cmd, err.returncode, err.output)) continue syslog.syslog(syslog.LOG_INFO, "Feature '{}' is enabled and started".format(feature_name)) - elif status == "disabled": + elif state == "disabled": stop_cmds = [] stop_cmds.append("sudo systemctl stop {}.service".format(feature_name)) stop_cmds.append("sudo systemctl disable {}.service".format(feature_name)) @@ -71,7 +71,7 @@ def update_feature_status(feature_name, status): continue syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(feature_name)) else: - syslog.syslog(syslog.LOG_ERR, "Unexpected status value '{}' for feature '{}'".format(status, feature_name)) + syslog.syslog(syslog.LOG_ERR, "Unexpected state value '{}' for feature '{}'".format(state, feature_name)) class Iptables(object): @@ -272,19 +272,19 @@ class HostConfigDaemon: self.iptables = Iptables() self.iptables.load(lpbk_table) - def update_all_feature_statuses(self): + def update_all_feature_states(self): feature_table = self.config_db.get_table('FEATURE') for feature_name in feature_table.keys(): if not feature_name: syslog.syslog(syslog.LOG_WARNING, "Feature is None") continue - status = feature_table[feature_name]['status'] - if not status: - syslog.syslog(syslog.LOG_WARNING, "Status of feature '{}' is None".format(feature_name)) + state = feature_table[feature_name]['state'] + if not state: + syslog.syslog(syslog.LOG_WARNING, "Eanble state of feature '{}' is None".format(feature_name)) continue - update_feature_status(feature_name, status) + update_feature_state(feature_name, state) def aaa_handler(self, key, data): self.aaacfg.aaa_update(key, data) @@ -314,29 +314,29 @@ class HostConfigDaemon: self.iptables.iptables_handler(key, data, add) - def feature_status_handler(self, key, data): + def feature_state_handler(self, key, data): feature_name = key feature_table = self.config_db.get_table('FEATURE') if feature_name not in feature_table.keys(): syslog.syslog(syslog.LOG_WARNING, "Feature '{}' not in FEATURE table".format(feature_name)) return - status = feature_table[feature_name]['status'] - if not status: - syslog.syslog(syslog.LOG_WARNING, "Status of feature '{}' is None".format(feature_name)) + state = feature_table[feature_name]['state'] + if not state: + syslog.syslog(syslog.LOG_WARNING, "Enable state of feature '{}' is None".format(feature_name)) return - update_feature_status(feature_name, status) + update_feature_state(feature_name, state) def start(self): - # Update all feature statuses once upon starting - self.update_all_feature_statuses() + # Update all feature states once upon starting + self.update_all_feature_states() self.config_db.subscribe('AAA', lambda table, key, data: self.aaa_handler(key, data)) self.config_db.subscribe('TACPLUS_SERVER', lambda table, key, data: self.tacacs_server_handler(key, data)) self.config_db.subscribe('TACPLUS', lambda table, key, data: self.tacacs_global_handler(key, data)) self.config_db.subscribe('LOOPBACK_INTERFACE', lambda table, key, data: self.lpbk_handler(key, data)) - self.config_db.subscribe('FEATURE', lambda table, key, data: self.feature_status_handler(key, data)) + self.config_db.subscribe('FEATURE', lambda table, key, data: self.feature_state_handler(key, data)) self.config_db.listen() diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index 04a2a5001371..e81e6b31a82c 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -11,21 +11,20 @@ import swsssdk from supervisor import childutils # Each line of this file should specify either one critical process or one -# critical process group, (as defined in supervisord.conf file), in the +# critical process group, (as defined in supervisord.conf file), in the # following format: # # program: # group: CRITICAL_PROCESSES_FILE = '/etc/supervisor/critical_processes' -# This table in databse contains the features for container and each -# feature for a row will be configured a state or number. -CONTAINER_FEATURE_TABLE_NAME = 'CONTAINER_FEATURE' +# The FEATURE table in config db contains auto-restart field +FEATURE_TABLE_NAME = 'FEATURE' # Read the critical processes/group names from CRITICAL_PROCESSES_FILE def get_critical_group_and_process_list(): critical_group_list = [] - critical_process_list = [] + critical_process_list = [] with open(CRITICAL_PROCESSES_FILE, 'r') as file: for line in file: @@ -43,7 +42,7 @@ def get_critical_group_and_process_list(): else: syslog.syslog(syslog.LOG_ERR, "Syntax of the line {} in critical_processes file is incorrect. Exiting...".format(line)) sys.exit(6) - + return critical_group_list, critical_process_list def main(argv): @@ -82,23 +81,23 @@ def main(argv): if container_name != 'database': config_db = swsssdk.ConfigDBConnector() config_db.connect() - container_features_table = config_db.get_table(CONTAINER_FEATURE_TABLE_NAME) - if not container_features_table: - syslog.syslog(syslog.LOG_ERR, "Unable to retrieve container features table from Config DB. Exiting...") + features_table = config_db.get_table(FEATURE_TABLE_NAME) + if not features_table: + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve features table from Config DB. Exiting...") sys.exit(2) - if not container_features_table.has_key(container_name): - syslog.syslog(syslog.LOG_ERR, "Unable to retrieve features for container '{}'. Exiting...".format(container_name)) + if not features_table.has_key(container_name): + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve feature '{}'. Exiting...".format(container_name)) sys.exit(3) - restart_feature = container_features_table[container_name].get('auto_restart') + restart_feature = features_table[container_name].get('auto_restart') if not restart_feature: - syslog.syslog(syslog.LOG_ERR, "Unable to determine auto-restart feature status for container '{}'. Exiting...".format(container_name)) + syslog.syslog(syslog.LOG_ERR, "Unable to determine auto-restart feature status for '{}'. Exiting...".format(container_name)) sys.exit(4) - # If container is database or auto-restart feature is enabled and at the same time + # If container is database or auto-restart feature is enabled and at the same time # a critical process exited unexpectedly, terminate supervisor - if ((container_name == 'database' or restart_feature == 'enabled') and expected == 0 and + if ((container_name == 'database' or restart_feature == 'enabled') and expected == 0 and (processname in critical_process_list or groupname in critical_group_list)): MSG_FORMAT_STR = "Process {} exited unxepectedly. Terminating supervisor..." msg = MSG_FORMAT_STR.format(payload_headers['processname']) diff --git a/platform/marvell-arm64/rules.mk b/platform/marvell-arm64/rules.mk index 2415686bd408..c3d7092ebb82 100644 --- a/platform/marvell-arm64/rules.mk +++ b/platform/marvell-arm64/rules.mk @@ -7,7 +7,7 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-mrvl.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/linux-kernel-arm64.mk -ENABLE_SYSTEM_TELEMETRY = "" +INCLUDE_SYSTEM_TELEMETRY = "" SONIC_ALL += $(SONIC_ONE_IMAGE) \ diff --git a/platform/marvell-armhf/rules.mk b/platform/marvell-armhf/rules.mk index 17d702238a81..9204955d9ccc 100644 --- a/platform/marvell-armhf/rules.mk +++ b/platform/marvell-armhf/rules.mk @@ -9,7 +9,7 @@ include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/linux-kernel-armhf.mk include $(PLATFORM_PATH)/platform-et6448m.mk -ENABLE_SYSTEM_TELEMETRY = "" +INCLUDE_SYSTEM_TELEMETRY = "" ENABLE_SYNCD_RPC = "" SONIC_ALL += $(SONIC_ONE_IMAGE) \ diff --git a/rules/config b/rules/config index 5c1a2bcf0ee1..e41a8de1d72b 100644 --- a/rules/config +++ b/rules/config @@ -83,9 +83,6 @@ ENABLE_ORGANIZATION_EXTENSIONS = y #SONIC_DEBUGGING_ON = y #SONIC_PROFILING_ON = y -# ENABLE_SYSTEM_TELEMETRY - build docker-sonic-telemetry for system telemetry support -ENABLE_SYSTEM_TELEMETRY = y - # DEFAULT_KERNEL_PROCURE_METHOD - default method for obtaining kernel # build: build kernel from source # download: download pre-built kernel from Azure storage. @@ -116,32 +113,35 @@ SONIC_DPKG_CACHE_SOURCE ?= /var/cache/sonic/artifacts DEFAULT_VS_PREPARE_MEM = yes -# ENABLE_ICCPD - build docker-iccpd for mclag support -ENABLE_ICCPD = n +# INCLUDE_SYSTEM_TELEMETRY - build docker-sonic-telemetry for system telemetry support +INCLUDE_SYSTEM_TELEMETRY = y + +# INCLUDE_ICCPD - build docker-iccpd for mclag support +INCLUDE_ICCPD = n -# ENABLE_SYSTEM_SFLOW - build docker-sonic-sflow for sFlow support -ENABLE_SFLOW = y +# INCLUDE_SFLOW - build docker-sflow for sFlow support +INCLUDE_SFLOW = y -# ENABLE_MGMT_FRAMEWORK - build docker-sonic-mgt-framework for CLI and REST server support -ENABLE_MGMT_FRAMEWORK = y +# INCLUDE_MGMT_FRAMEWORK - build docker-sonic-mgmt-framework for CLI and REST server support +INCLUDE_MGMT_FRAMEWORK = y -# ENABLE_RESTAPI - build docker-sonic-restapi for configuring the switch using REST APIs -ENABLE_RESTAPI = n +# INCLUDE_RESTAPI - build docker-sonic-restapi for configuring the switch using REST APIs +INCLUDE_RESTAPI = n -# ENABLE_NAT - build docker-sonic-nat for nat support -ENABLE_NAT = y +# INCLUDE_NAT - build docker-nat for nat support +INCLUDE_NAT = y # TELEMETRY_WRITABLE - Enable write/config operations via the gNMI interface. # Uncomment to enable: # TELEMETRY_WRITABLE = y -# INSTALL_KUBERNETES - if set to y kubernetes packages are installed to be able to +# INCLUDE_KUBERNETES - if set to y kubernetes packages are installed to be able to # run as worker node in kubernetes cluster. -INSTALL_KUBERNETES = n +INCLUDE_KUBERNETES = n # KUBERNETES_VERSION - Set to the required version. # K8s_GCR_IO_PAUSE_VERSION - Version of k8s universal pause container image # K8s_CNI_FLANNEL_VERSION - Flannel used as CNI; Appropriate version for this Kubernetes version -# These are Used *only* when INSTALL_KUBERNETES=y +# These are Used *only* when INCLUDE_KUBERNETES=y # NOTE: As a worker node it has to run version compatible to kubernetes master. # KUBERNETES_VERSION = 1.18.6 diff --git a/rules/docker-iccpd.mk b/rules/docker-iccpd.mk index 97e9a842319a..da77d9c9c1fd 100644 --- a/rules/docker-iccpd.mk +++ b/rules/docker-iccpd.mk @@ -10,7 +10,7 @@ $(DOCKER_ICCPD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) $(ICCPD_DBG) $(DOCKER_ICCPD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) $(DOCKER_ICCPD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) -ifeq ($(ENABLE_ICCPD), y) +ifeq ($(INCLUDE_ICCPD), y) SONIC_DOCKER_IMAGES += $(DOCKER_ICCPD) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ICCPD) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_ICCPD_DBG) diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk index 9738903a0fc8..981019dbcdb6 100644 --- a/rules/docker-nat.mk +++ b/rules/docker-nat.mk @@ -13,12 +13,12 @@ $(DOCKER_NAT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PA $(DOCKER_NAT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) -ifeq ($(ENABLE_NAT), y) +ifeq ($(INCLUDE_NAT), y) SONIC_DOCKER_IMAGES += $(DOCKER_NAT) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_NAT) endif -ifeq ($(ENABLE_NAT), y) +ifeq ($(INCLUDE_NAT), y) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) endif diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index bd91aabd86c5..ef56789dd759 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -10,7 +10,7 @@ $(DOCKER_RESTAPI)_PATH = $(DOCKERS_PATH)/$(DOCKER_RESTAPI_STEM) $(DOCKER_RESTAPI)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) -ifeq ($(ENABLE_RESTAPI), y) +ifeq ($(INCLUDE_RESTAPI), y) SONIC_DOCKER_IMAGES += $(DOCKER_RESTAPI) SONIC_STRETCH_DOCKERS += $(DOCKER_RESTAPI) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_RESTAPI) diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk index db16aad8b20a..6888304b8bce 100644 --- a/rules/docker-sflow.mk +++ b/rules/docker-sflow.mk @@ -14,12 +14,12 @@ $(DOCKER_SFLOW)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_ $(DOCKER_SFLOW)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_SFLOW) -ifeq ($(ENABLE_SFLOW), y) +ifeq ($(INCLUDE_SFLOW), y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SFLOW) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_SFLOW_DBG) -ifeq ($(ENABLE_SFLOW), y) +ifeq ($(INCLUDE_SFLOW), y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SFLOW_DBG) endif diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk index b1e23c026c9f..997881ca46f9 100644 --- a/rules/docker-sonic-mgmt-framework.mk +++ b/rules/docker-sonic-mgmt-framework.mk @@ -15,12 +15,12 @@ SONIC_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) $(DOCKER_MGMT_FRAMEWORK)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) $(DOCKER_MGMT_FRAMEWORK)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -ifeq ($(ENABLE_MGMT_FRAMEWORK), y) +ifeq ($(INCLUDE_MGMT_FRAMEWORK), y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) -ifeq ($(ENABLE_MGMT_FRAMEWORK), y) +ifeq ($(INCLUDE_MGMT_FRAMEWORK), y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) endif diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 9544e7bf4687..b44f7dc60227 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -14,12 +14,12 @@ $(DOCKER_TELEMETRY)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) $(DOCKER_TELEMETRY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) SONIC_DOCKER_IMAGES += $(DOCKER_TELEMETRY) -ifeq ($(ENABLE_SYSTEM_TELEMETRY), y) +ifeq ($(INCLUDE_SYSTEM_TELEMETRY), y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_TELEMETRY) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_TELEMETRY_DBG) -ifeq ($(ENABLE_SYSTEM_TELEMETRY), y) +ifeq ($(INCLUDE_SYSTEM_TELEMETRY), y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_TELEMETRY_DBG) endif diff --git a/rules/sonic-mgmt-framework.mk b/rules/sonic-mgmt-framework.mk index e9a514634850..a423f7cd506b 100644 --- a/rules/sonic-mgmt-framework.mk +++ b/rules/sonic-mgmt-framework.mk @@ -1,6 +1,6 @@ # SONiC mgmt-framework package -ifeq ($(ENABLE_MGMT_FRAMEWORK), y) +ifeq ($(INCLUDE_MGMT_FRAMEWORK), y) SONIC_MGMT_FRAMEWORK = sonic-mgmt-framework_1.0-01_$(CONFIGURED_ARCH).deb $(SONIC_MGMT_FRAMEWORK)_SRC_PATH = $(SRC_PATH)/sonic-mgmt-framework diff --git a/slave.mk b/slave.mk index b1e10c82a091..64fb77b5721d 100644 --- a/slave.mk +++ b/slave.mk @@ -99,8 +99,8 @@ ifeq ($(SONIC_ENABLE_PFCWD_ON_START),y) ENABLE_PFCWD_ON_START = y endif -ifeq ($(SONIC_ENABLE_SYSTEM_TELEMETRY),y) -ENABLE_SYSTEM_TELEMETRY = y +ifeq ($(SONIC_INCLUDE_SYSTEM_TELEMETRY),y) +INCLUDE_SYSTEM_TELEMETRY = y endif ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) @@ -108,11 +108,11 @@ ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) # Issue: qemu crashes when it uses "go get url" # Qemu Support: https://bugs.launchpad.net/qemu/+bug/1838946 # Golang Support: https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!topic/golang-nuts/1txPOGa4aGc -ENABLE_SYSTEM_TELEMETRY = N +INCLUDE_SYSTEM_TELEMETRY = n endif -ifeq ($(SONIC_ENABLE_RESTAPI),y) -ENABLE_RESTAPI = y +ifeq ($(SONIC_INCLUDE_RESTAPI),y) +INCLUDE_RESTAPI = y endif ifeq ($(SONIC_ENABLE_SYNCD_RPC),y) @@ -123,12 +123,12 @@ ifeq ($(SONIC_INSTALL_DEBUG_TOOLS),y) INSTALL_DEBUG_TOOLS = y endif -ifeq ($(SONIC_ENABLE_SFLOW),y) -ENABLE_SFLOW = y +ifeq ($(SONIC_INCLUDE_SFLOW),y) +INCLUDE_SFLOW = y endif -ifeq ($(SONIC_ENABLE_NAT),y) -ENABLE_NAT = y +ifeq ($(SONIC_INCLUDE_NAT),y) +INCLUDE_NAT = y endif @@ -202,7 +202,6 @@ $(info "USERNAME" : "$(USERNAME)") $(info "PASSWORD" : "$(PASSWORD)") $(info "ENABLE_DHCP_GRAPH_SERVICE" : "$(ENABLE_DHCP_GRAPH_SERVICE)") $(info "SHUTDOWN_BGP_ON_START" : "$(SHUTDOWN_BGP_ON_START)") -$(info "INSTALL_KUBERNETES" : "$(INSTALL_KUBERNETES)") $(info "ENABLE_PFCWD_ON_START" : "$(ENABLE_PFCWD_ON_START)") $(info "INSTALL_DEBUG_TOOLS" : "$(INSTALL_DEBUG_TOOLS)") $(info "ROUTING_STACK" : "$(SONIC_ROUTING_STACK)") @@ -214,8 +213,6 @@ $(info "ENABLE_SYNCD_RPC" : "$(ENABLE_SYNCD_RPC)") $(info "ENABLE_ORGANIZATION_EXTENSIONS" : "$(ENABLE_ORGANIZATION_EXTENSIONS)") $(info "HTTP_PROXY" : "$(HTTP_PROXY)") $(info "HTTPS_PROXY" : "$(HTTPS_PROXY)") -$(info "ENABLE_SYSTEM_TELEMETRY" : "$(ENABLE_SYSTEM_TELEMETRY)") -$(info "ENABLE_RESTAPI" : "$(ENABLE_RESTAPI)") $(info "ENABLE_ZTP" : "$(ENABLE_ZTP)") $(info "SONIC_DEBUGGING_ON" : "$(SONIC_DEBUGGING_ON)") $(info "SONIC_PROFILING_ON" : "$(SONIC_PROFILING_ON)") @@ -224,8 +221,13 @@ $(info "BUILD_TIMESTAMP" : "$(BUILD_TIMESTAMP)") $(info "BUILD_LOG_TIMESTAMP" : "$(BUILD_LOG_TIMESTAMP)") $(info "BLDENV" : "$(BLDENV)") $(info "VS_PREPARE_MEM" : "$(VS_PREPARE_MEM)") -$(info "ENABLE_SFLOW" : "$(ENABLE_SFLOW)") -$(info "ENABLE_NAT" : "$(ENABLE_NAT)") +$(info "INCLUDE_MGMT_FRAMEWORK" : "$(INCLUDE_MGMT_FRAMEWORK)") +$(info "INCLUDE_ICCPD" : "$(INCLUDE_ICCPD)") +$(info "INCLUDE_SYSTEM_TELEMETRY" : "$(INCLUDE_SYSTEM_TELEMETRY)") +$(info "INCLUDE_RESTAPI" : "$(INCLUDE_RESTAPI)") +$(info "INCLUDE_SFLOW" : "$(INCLUDE_SFLOW)") +$(info "INCLUDE_NAT" : "$(INCLUDE_NAT)") +$(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)") $(info "TELEMETRY_WRITABLE" : "$(TELEMETRY_WRITABLE)") $(info ) @@ -815,12 +817,15 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export sonic_asic_platform="$(patsubst %-$(CONFIGURED_ARCH),%,$(CONFIGURED_PLATFORM))" export enable_organization_extensions="$(ENABLE_ORGANIZATION_EXTENSIONS)" export enable_dhcp_graph_service="$(ENABLE_DHCP_GRAPH_SERVICE)" - export enable_system_telemetry="$(ENABLE_SYSTEM_TELEMETRY)" - export enable_restapi="$(ENABLE_RESTAPI)" export enable_ztp="$(ENABLE_ZTP)" - export enable_nat="$(ENABLE_NAT)" + export include_system_telemetry="$(INCLUDE_SYSTEM_TELEMETRY)" + export include_restapi="$(INCLUDE_RESTAPI)" + export include_nat="$(INCLUDE_NAT)" + export include_sflow="$(INCLUDE_SFLOW)" + export include_mgmt_framework="$(INCLUDE_MGMT_FRAMEWORK)" + export include_iccpd="$(INCLUDE_ICCPD)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" - export install_kubernetes="$(INSTALL_KUBERNETES)" + export include_kubernetes="$(INCLUDE_KUBERNETES)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" export installer_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($*_INSTALLS))" export lazy_installer_debs="$(foreach deb, $($*_LAZY_INSTALLS),$(foreach device, $($(deb)_PLATFORM),$(addprefix $(device)@, $(IMAGE_DISTRO_DEBS_PATH)/$(deb))))" diff --git a/src/sonic-utilities b/src/sonic-utilities index c0c3cce6bee0..9700e45322a4 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit c0c3cce6bee0e335cf1b5528f1172b511d48ee12 +Subproject commit 9700e45322a4a58076e5cef604ed15803ffb9314 From 457674ce00adf2b03d33db24399e5d05b2b7478e Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 5 Aug 2020 23:44:00 +0000 Subject: [PATCH 0989/1427] Revert "DPB Breakout Cli Test with proper setup (#3910)" This reverts commit 0a409ff65e4b0caff039ff14425d1197ab1929f2. --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 7 +- platform/vs/docker-sonic-vs/hwsku.json | 100 ------- platform/vs/docker-sonic-vs/platform.json | 196 -------------- platform/vs/docker-sonic-vs/start.sh | 2 +- .../sample_output/sample_new_port_config.json | 252 ------------------ .../vs/tests/breakout/test_breakout_cli.py | 166 ------------ 6 files changed, 2 insertions(+), 721 deletions(-) delete mode 100644 platform/vs/docker-sonic-vs/hwsku.json delete mode 100644 platform/vs/docker-sonic-vs/platform.json delete mode 100644 platform/vs/tests/breakout/sample_output/sample_new_port_config.json delete mode 100755 platform/vs/tests/breakout/test_breakout_cli.py diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 2e133165f5bc..e96db2d79ddc 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -46,8 +46,7 @@ RUN apt-get install -y net-tools \ python-scapy \ conntrack \ iptables \ - python3-pip \ - jq + python3-pip RUN pip install setuptools RUN pip3 install setuptools @@ -133,10 +132,6 @@ COPY ["hostname.j2", "/usr/share/sonic/templates/"] COPY ["default_chassis_cfg.json", "/etc/default/sonic-db/"] COPY ["chassis_db.py", "/usr/bin/"] -COPY ["platform.json", "/usr/share/sonic/device/x86_64-kvm_x86_64-r0/"] -COPY ["hwsku.json", "/usr/share/sonic/device/x86_64-kvm_x86_64-r0/Force10-S6000/"] -COPY ["platform.json", "/usr/share/sonic/platform/"] - # Workaround the tcpdump issue RUN mv /usr/sbin/tcpdump /usr/bin/tcpdump diff --git a/platform/vs/docker-sonic-vs/hwsku.json b/platform/vs/docker-sonic-vs/hwsku.json deleted file mode 100644 index daaa5625f3f0..000000000000 --- a/platform/vs/docker-sonic-vs/hwsku.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "interfaces": { - "Ethernet0": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet4": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet8": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet12": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet16": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet20": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet24": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet28": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet32": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet36": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet40": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet44": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet48": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet52": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet56": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet60": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet64": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet68": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet72": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet76": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet80": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet84": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet88": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet92": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet96": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet100": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet104": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet108": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet112": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet116": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet120": { - "default_brkout_mode": "1x100G[40G]" - }, - "Ethernet124": { - "default_brkout_mode": "1x100G[40G]" - } - } -} diff --git a/platform/vs/docker-sonic-vs/platform.json b/platform/vs/docker-sonic-vs/platform.json deleted file mode 100644 index 053fed5516ed..000000000000 --- a/platform/vs/docker-sonic-vs/platform.json +++ /dev/null @@ -1,196 +0,0 @@ -{ - "interfaces": { - "Ethernet0": { - "index": "0,0,0,0", - "lanes": "25,26,27,28", - "alias_at_lanes": "fortyGigE0/0,fortyGigE0/1,fortyGigE0/2,fortyGigE0/3", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet4": { - "index": "1,1,1,1", - "lanes": "29,30,31,32", - "alias_at_lanes": "fortyGigE0/4,fortyGigE0/5,fortyGigE0/6,fortyGigE0/7", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" - }, - "Ethernet8": { - "index": "2,2,2,2", - "lanes": "33,34,35,36", - "alias_at_lanes": "fortyGigE0/8,fortyGigE0/9,fortyGigE0/10,fortyGigE0/11", - "breakout_modes": "1x100G[40G],2x50G,2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet12": { - "index": "3,3,3,3", - "lanes": "37,38,39,40", - "alias_at_lanes": "fortyGigE0/12,fortyGigE0/13,fortyGigE0/14,fortyGigE0/15", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet16": { - "index": "4,4,4,4", - "lanes": "45,46,47,48", - "alias_at_lanes": "fortyGigE0/16,fortyGigE0/17,fortyGigE0/18,fortyGigE0/19", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet20": { - "index": "5,5,5,5", - "lanes": "41,42,43,44", - "alias_at_lanes": "fortyGigE0/20,fortyGigE0/21,fortyGigE0/22,fortyGigE0/23", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet24": { - "index": "6,6,6,6", - "lanes": "1,2,3,4", - "alias_at_lanes": "fortyGigE0/24,fortyGigE0/25,fortyGigE0/26,fortyGigE0/27", - "breakout_modes": "1x100G[40G],4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet28": { - "index": "7,7,7,7", - "lanes": "5,6,7,8", - "alias_at_lanes": "fortyGigE0/28,fortyGigE0/29,fortyGigE0/30,fortyGigE0/31", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet32": { - "index": "8,8,8,8", - "lanes": "13,14,15,16", - "alias_at_lanes": "fortyGigE0/32,fortyGigE0/33,fortyGigE0/34,fortyGigE0/35", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet36": { - "index": "9,9,9,9", - "lanes": "9,10,11,12", - "alias_at_lanes": "fortyGigE0/36,fortyGigE0/37,fortyGigE0/38,fortyGigE0/39", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet40": { - "index": "10,10,10,10", - "lanes": "17,18,19,20", - "alias_at_lanes": "fortyGigE0/40,fortyGigE0/41,fortyGigE0/42,fortyGigE0/43", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet44": { - "index": "11,11,11,11", - "lanes": "21,22,23,24", - "alias_at_lanes": "fortyGigE0/44,fortyGigE0/45,fortyGigE0/46,fortyGigE0/47", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet48": { - "index": "12,12,12,12", - "lanes": "53,54,55,56", - "alias_at_lanes": "fortyGigE0/48,fortyGigE0/49,fortyGigE0/50,fortyGigE0/51", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet52": { - "index": "13,13,13,13", - "lanes": "49,50,51,52", - "alias_at_lanes": "fortyGigE0/52,fortyGigE0/53,fortyGigE0/54,fortyGigE0/55", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet56": { - "index": "14,14,14,14", - "lanes": "57,58,59,60", - "alias_at_lanes": "fortyGigE0/56,fortyGigE0/57,fortyGigE0/58,fortyGigE0/59", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet60": { - "index": "15,15,15,15", - "lanes": "61,62,63,64", - "alias_at_lanes": "fortyGigE0/60,fortyGigE0/61,fortyGigE0/62,fortyGigE0/63", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet64": { - "index": "16,16,16,16", - "lanes": "69,70,71,72", - "alias_at_lanes": "fortyGigE0/64,fortyGigE0/65,fortyGigE0/66,fortyGigE0/67", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet68": { - "index": "17,17,17,17", - "lanes": "65,66,67,68", - "alias_at_lanes": "fortyGigE0/68,fortyGigE0/69,fortyGigE0/70,fortyGigE0/71", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet72": { - "index": "18,18,18,18", - "lanes": "73,74,75,76", - "alias_at_lanes": "fortyGigE0/72,fortyGigE0/73,fortyGigE0/74,fortyGigE0/75", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet76": { - "index": "19,19,19,19", - "lanes": "77,78,79,80", - "alias_at_lanes": "fortyGigE0/76,fortyGigE0/77,fortyGigE0/78,fortyGigE0/79", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet80": { - "index": "20,20,20,20", - "lanes": "109,110,111,112", - "alias_at_lanes": "fortyGigE0/80,fortyGigE0/81,fortyGigE0/82,fortyGigE0/83", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet84": { - "index": "21,21,21,21", - "lanes": "105,106,107,108", - "alias_at_lanes": "fortyGigE0/84,fortyGigE0/85,fortyGigE0/86,fortyGigE0/87", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet88": { - "index": "22,22,22,22", - "lanes": "113,114,115,116", - "alias_at_lanes": "fortyGigE0/88,fortyGigE0/89,fortyGigE0/90,fortyGigE0/91", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet92": { - "index": "23,23,23,23", - "lanes": "117,118,119,120", - "alias_at_lanes": "fortyGigE0/92,fortyGigE0/93,fortyGigE0/94,fortyGigE0/95", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet96": { - "index": "24,24,24,24", - "lanes": "125,126,127,128", - "alias_at_lanes": "fortyGigE0/96,fortyGigE0/97,fortyGigE0/98,fortyGigE0/99", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet100": { - "index": "25,25,25,25", - "lanes": "121,122,123,124", - "alias_at_lanes": "fortyGigE0/100,fortyGigE0/101,fortyGigE0/102,fortyGigE0/103", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet104": { - "index": "26,26,26,26", - "lanes": "81,82,83,84", - "alias_at_lanes": "fortyGigE0/104,fortyGigE0/105,fortyGigE0/106,fortyGigE0/107", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet108": { - "index": "27,27,27,27", - "lanes": "85,86,87,88", - "alias_at_lanes": "fortyGigE0/108,fortyGigE0/109,fortyGigE0/110,fortyGigE0/111", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet112": { - "index": "28,28,28,28", - "lanes": "93,94,95,96", - "alias_at_lanes": "fortyGigE0/112,fortyGigE0/113,fortyGigE0/114,fortyGigE0/115", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet116": { - "index": "29,29,29,29", - "lanes": "89,90,91,92", - "alias_at_lanes": "fortyGigE0/116,fortyGigE0/117,fortyGigE0/118,fortyGigE0/119", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet120": { - "index": "30,30,30,30", - "lanes": "101,102,103,104", - "alias_at_lanes": "fortyGigE0/120,fortyGigE0/121,fortyGigE0/122,fortyGigE0/123", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - }, - "Ethernet124": { - "index": "31,31,31,31", - "lanes": "97,98,99,100", - "alias_at_lanes": "fortyGigE0/124,fortyGigE0/125,fortyGigE0/126,fortyGigE0/127", - "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" - } - } -} diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 5509ec4292f9..94825825851c 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -40,7 +40,7 @@ else # generate and merge buffers configuration into config file sonic-cfggen -k $HWSKU -p /usr/share/sonic/hwsku/port_config.ini -t /usr/share/sonic/hwsku/buffers.json.j2 > /tmp/buffers.json sonic-cfggen -j /etc/sonic/init_cfg.json -t /usr/share/sonic/hwsku/qos.json.j2 > /tmp/qos.json - sonic-cfggen -p /usr/share/sonic/device/$PLATFORM/platform.json -k $HWSKU --print-data > /tmp/ports.json + sonic-cfggen -p /usr/share/sonic/hwsku/port_config.ini -k $HWSKU --print-data > /tmp/ports.json sonic-cfggen -j /etc/sonic/init_cfg.json -j /tmp/buffers.json -j /tmp/qos.json -j /tmp/ports.json --print-data > /etc/sonic/config_db.json fi diff --git a/platform/vs/tests/breakout/sample_output/sample_new_port_config.json b/platform/vs/tests/breakout/sample_output/sample_new_port_config.json deleted file mode 100644 index 7c5c190a3330..000000000000 --- a/platform/vs/tests/breakout/sample_output/sample_new_port_config.json +++ /dev/null @@ -1,252 +0,0 @@ -{ - "Ethernet0_2x50G": { - "Ethernet2": { - "alias": "fortyGigE0/2", - "admin_status": "up", - "lanes": "27,28", - "speed": "50000", - "index": "0" - }, - "Ethernet0": { - "alias": "fortyGigE0/0", - "admin_status": "up", - "lanes": "25,26", - "speed": "50000", - "index": "0" - } - }, - "Ethernet12_1x50G_2x25G": { - "Ethernet12": { - "alias": "fortyGigE0/12", - "admin_status": "up", - "lanes": "37,38", - "speed": "50000", - "index": "3" - }, - "Ethernet14": { - "alias": "fortyGigE0/14", - "admin_status": "up", - "lanes": "39", - "speed": "25000", - "index": "3" - }, - "Ethernet15": { - "alias": "fortyGigE0/15", - "admin_status": "up", - "lanes": "40", - "speed": "25000", - "index": "3" - } - }, - "Ethernet0_2x50G": { - "Ethernet2": { - "alias": "fortyGigE0/2", - "admin_status": "up", - "lanes": "27,28", - "speed": "50000", - "index": "0" - }, - "Ethernet0": { - "alias": "fortyGigE0/0", - "admin_status": "up", - "lanes": "25,26", - "speed": "50000", - "index": "0" - } - }, - "Ethernet0_1x100G": { - "Ethernet0": { - "alias": "fortyGigE0/0", - "admin_status": "up", - "lanes": "25,26,27,28", - "speed": "100000", - "index": "0" - } - }, - "Ethernet0_4x25G": { - "Ethernet2": { - "alias": "fortyGigE0/2", - "admin_status": "up", - "lanes": "27", - "speed": "25000", - "index": "0" - }, - "Ethernet3": { - "alias": "fortyGigE0/3", - "admin_status": "up", - "lanes": "28", - "speed": "25000", - "index": "0" - }, - "Ethernet0": { - "alias": "fortyGigE0/0", - "admin_status": "up", - "lanes": "25", - "speed": "25000", - "index": "0" - }, - "Ethernet1": { - "alias": "fortyGigE0/1", - "admin_status": "up", - "lanes": "26", - "speed": "25000", - "index": "0" - } - }, - "Ethernet0_2x25G_1x50G": { - "Ethernet2": { - "alias": "fortyGigE0/2", - "admin_status": "up", - "lanes": "27,28", - "speed": "50000", - "index": "0" - }, - "Ethernet0": { - "alias": "fortyGigE0/0", - "admin_status": "up", - "lanes": "25", - "speed": "25000", - "index": "0" - }, - "Ethernet1": { - "alias": "fortyGigE0/1", - "admin_status": "up", - "lanes": "26", - "speed": "25000", - "index": "0" - } - }, - "Ethernet0_1x50G_2x25G": { - "Ethernet2": { - "alias": "fortyGigE0/2", - "admin_status": "up", - "lanes": "27", - "speed": "25000", - "index": "0" - }, - "Ethernet3": { - "alias": "fortyGigE0/3", - "admin_status": "up", - "lanes": "28", - "speed": "25000", - "index": "0" - }, - "Ethernet0": { - "alias": "fortyGigE0/0", - "admin_status": "up", - "lanes": "25,26", - "speed": "50000", - "index": "0" - } - }, - "Ethernet4_4x25G": { - "Ethernet6": { - "alias": "fortyGigE0/6", - "admin_status": "up", - "lanes": "31", - "speed": "25000", - "index": "1" - }, - "Ethernet7": { - "alias": "fortyGigE0/7", - "admin_status": "up", - "lanes": "32", - "speed": "25000", - "index": "1" - }, - "Ethernet4": { - "alias": "fortyGigE0/4", - "admin_status": "up", - "lanes": "29", - "speed": "25000", - "index": "1" - }, - "Ethernet5": { - "alias": "fortyGigE0/5", - "admin_status": "up", - "lanes": "30", - "speed": "25000", - "index": "1" - } - }, - "Ethernet4_2x50G": { - "Ethernet6": { - "alias": "fortyGigE0/6", - "admin_status": "up", - "lanes": "31,32", - "speed": "50000", - "index": "1" - }, - "Ethernet4": { - "alias": "fortyGigE0/4", - "admin_status": "up", - "lanes": "29,30", - "speed": "50000", - "index": "1" - } - }, - "Ethernet8_2x50G": { - "Ethernet8": { - "alias": "fortyGigE0/8", - "admin_status": "up", - "lanes": "33,34", - "speed": "50000", - "index": "2" - }, - "Ethernet10": { - "alias": "fortyGigE0/10", - "admin_status": "up", - "lanes": "35,36", - "speed": "50000", - "index": "2" - } - }, - "Ethernet8_1x50G_2x25G": { - "Ethernet10": { - "alias": "fortyGigE0/10", - "admin_status": "up", - "lanes": "35", - "speed": "25000", - "index": "2" - }, - "Ethernet11": { - "alias": "fortyGigE0/11", - "admin_status": "up", - "lanes": "36", - "speed": "25000", - "index": "2" - } - }, - "Ethernet8_2x25G_1x50G": { - "Ethernet8": { - "alias": "fortyGigE0/8", - "admin_status": "up", - "lanes": "33", - "speed": "25000", - "index": "2" - }, - "Ethernet9": { - "alias": "fortyGigE0/9", - "admin_status": "up", - "lanes": "34", - "speed": "25000", - "index": "2" - }, - "Ethernet10": { - "alias": "fortyGigE0/10", - "admin_status": "up", - "lanes": "35,36", - "speed": "50000", - "index": "2" - } - }, - "Ethernet8_1x100G": { - "Ethernet8": { - "alias": "fortyGigE0/8", - "admin_status": "up", - "lanes": "33,34,35,36", - "speed": "100000", - "index": "2" - } - } -} diff --git a/platform/vs/tests/breakout/test_breakout_cli.py b/platform/vs/tests/breakout/test_breakout_cli.py deleted file mode 100755 index 9208e159b1d5..000000000000 --- a/platform/vs/tests/breakout/test_breakout_cli.py +++ /dev/null @@ -1,166 +0,0 @@ -from swsscommon import swsscommon -import time -import os -import json -import ast -import pytest -import collections - -@pytest.mark.usefixtures('dpb_setup_fixture') -class TestBreakoutCli(object): - def setup_db(self, dvs): - self.cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0) - - def read_Json(self, dvs): - test_dir = os.path.dirname(os.path.realpath(__file__)) - sample_output_file = os.path.join(test_dir, 'sample_output', 'sample_new_port_config.json') - fh = open(sample_output_file, 'rb') - fh_data = json.load(fh) - fh.close() - - if not fh_data: - return False - expected = ast.literal_eval(json.dumps(fh_data)) - return expected - - def breakout(self, dvs, interface, brkout_mode): - (exitcode, result) = dvs.runcmd("config interface breakout {} {} -y".format(interface, brkout_mode)) - - if result.strip("\n")[0] == "[ERROR] Breakout feature is not available without platform.json file" : - pytest.skip("**** This test is not needed ****") - root_dir = os.path.dirname('/') - (exitcode, output_dict) = dvs.runcmd("jq '.' new_port_config.json") - if output_dict is None: - raise Exception("Breakout output cant be None") - - output_dict = ast.literal_eval(output_dict.strip()) - return output_dict - - # Check Initial Brakout Mode - def test_InitialBreakoutMode(self, dvs, testlog): - self.setup_db(dvs) - - output_dict = {} - brkoutTbl = swsscommon.Table(self.cdb, "BREAKOUT_CFG") - brkout_entries = brkoutTbl.getKeys() - assert len(brkout_entries) == 32 - - for key in brkout_entries: - (status, fvs) = brkoutTbl.get(key) - assert(status == True) - - brkout_mode = fvs[0][1] - output_dict[key] = brkout_mode - output = collections.OrderedDict(sorted(output_dict.items(), key=lambda t: t[0])) - expected_dict = \ - {'Ethernet8': '1x100G[40G]', 'Ethernet0': '1x100G[40G]', 'Ethernet4': '1x100G[40G]', \ - 'Ethernet108': '1x100G[40G]', 'Ethernet100': '1x100G[40G]', 'Ethernet104': '1x100G[40G]', \ - 'Ethernet68': '1x100G[40G]', 'Ethernet96': '1x100G[40G]', 'Ethernet124': '1x100G[40G]', \ - 'Ethernet92': '1x100G[40G]', 'Ethernet120': '1x100G[40G]', 'Ethernet52': '1x100G[40G]', \ - 'Ethernet56': '1x100G[40G]', 'Ethernet76': '1x100G[40G]', 'Ethernet72': '1x100G[40G]', \ - 'Ethernet32': '1x100G[40G]', 'Ethernet16': '1x100G[40G]', 'Ethernet36': '1x100G[40G]', \ - 'Ethernet12': '1x100G[40G]', 'Ethernet28': '1x100G[40G]', 'Ethernet88': '1x100G[40G]', \ - 'Ethernet116': '1x100G[40G]', 'Ethernet80': '1x100G[40G]', 'Ethernet112': '1x100G[40G]', \ - 'Ethernet84': '1x100G[40G]', 'Ethernet48': '1x100G[40G]', 'Ethernet44': '1x100G[40G]', \ - 'Ethernet40': '1x100G[40G]', 'Ethernet64': '1x100G[40G]', 'Ethernet60': '1x100G[40G]', \ - 'Ethernet20': '1x100G[40G]', 'Ethernet24': '1x100G[40G]'} - expected = collections.OrderedDict(sorted(expected_dict.items(), key=lambda t: t[0])) - assert output == expected - - # Breakout Cli Test Mode - def test_breakout_modes(self, dvs): - expected = self.read_Json(dvs) - assert expected - - print("**** Breakout Cli test Starts ****") - output_dict = self.breakout(dvs, 'Ethernet0', '2x50G') - expected_dict = expected["Ethernet0_2x50G"] - assert output_dict == expected_dict - print("**** 1X100G --> 2x50G passed ****") - - output_dict = self.breakout(dvs, 'Ethernet4', '4x25G[10G]') - expected_dict = expected["Ethernet4_4x25G"] - assert output_dict == expected_dict - print("**** 1X100G --> 4x25G[10G] passed ****") - - output_dict = self.breakout(dvs, 'Ethernet8', '2x25G(2)+1x50G(2)') - expected_dict = expected["Ethernet8_2x25G_1x50G"] - assert output_dict == expected_dict - print("**** 1X100G --> 2x25G(2)+1x50G(2) passed ****") - - output_dict = self.breakout(dvs, 'Ethernet12', '1x50G(2)+2x25G(2)') - expected_dict = expected["Ethernet12_1x50G_2x25G"] - assert output_dict == expected_dict - print("**** 1X100G --> 1x50G(2)+2x25G(2) passed ****") - - #TODOFIX: remove comments once #4442 PR got merged. - """ - output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') - expected_dict = expected["Ethernet0_1x100G"] - assert output_dict == expected_dict - print("**** 2x50G --> 1x100G[40G] passed ****") - - output_dict = self.breakout(dvs, 'Ethernet0', '4x25G[10G]') - expected_dict = expected["Ethernet0_4x25G"] - assert output_dict == expected_dict - print("**** 1X100G --> 4x25G[10G] passed ****") - - output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') - expected_dict = expected["Ethernet0_1x100G"] - assert output_dict == expected_dict - print("**** 4x25G[10G] --> 1x100G[40G] passed ****") - - output_dict = self.breakout(dvs, 'Ethernet4', '2x50G') - print("**** 1X100G --> 2x50G mode change ****") - - output_dict = self.breakout(dvs, 'Ethernet4', '4x25G[10G]') - expected_dict = expected["Ethernet4_4x25G"] - assert output_dict == expected_dict - print("**** 2X50G --> 4x25G[10G] passed ****") - - output_dict = self.breakout(dvs, 'Ethernet4', '2x50G') - expected_dict = expected["Ethernet4_2x50G"] - assert output_dict == expected_dict - print("**** 4x25G[10G] --> 2X50G passed ****") - - output_dict = self.breakout(dvs, 'Ethernet4', '1x100G[40G]') - print("**** 2x50G -- > 1X100G mode change ****") - - output_dict = self.breakout(dvs, 'Ethernet0', '2x25G(2)+1x50G(2)') - expected_dict = expected["Ethernet0_2x25G_1x50G"] - assert output_dict == expected_dict - print("**** 1x100G[40G] --> 2x25G(2)+1x50G(2) passed ****") - - output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') - expected_dict = expected["Ethernet0_1x100G"] - assert output_dict == expected_dict - print("**** 2x25G(2)+1x50G(2) --> 1x100G[40G] passed ****") - - output_dict = self.breakout(dvs, 'Ethernet0', '1x50G(2)+2x25G(2)') - expected_dict = expected["Ethernet0_1x50G_2x25G"] - assert output_dict == expected_dict - print("**** 1x100G[40G] --> 1x50G(2)+2x25G(2) passed ****") - - output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') - expected_dict = expected["Ethernet0_1x100G"] - assert output_dict == expected_dict - print("**** 1x50G(2)+2x25G(2) --> 1x100G[40G] passed ****") - - output_dict = self.breakout(dvs, 'Ethernet8', '2x50G') - print("**** 1x100G[40G] --> 2x50G mode change ****") - - output_dict = self.breakout(dvs, 'Ethernet8', '1x50G(2)+2x25G(2)') - expected_dict = expected["Ethernet8_1x50G_2x25G"] - assert output_dict == expected_dict - print("**** 2x50G --> 2x25G(2)+1x50G(2) passed ****") - - output_dict = self.breakout(dvs, 'Ethernet8', '2x25G(2)+1x50G(2)') - expected_dict = expected["Ethernet8_2x25G_1x50G"] - assert output_dict == expected_dict - print("**** 1x50G(2)+2x25G(2) --> 2x25G(2)+1x50G(2) passed ****") - - output_dict = self.breakout(dvs, 'Ethernet8', '1x100G[40G]') - expected_dict = expected["Ethernet8_1x100G"] - assert output_dict == expected_dict - print("**** 2x25G(2)+1x50G(2) --> 1x100G[40G] passed ****") - """ From 9e100257d080dd5846055e2e20971553757b22d9 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 6 Aug 2020 02:18:29 -0700 Subject: [PATCH 0990/1427] [.github] Update pull request template #5115 (#5115) Fix a spelling error in the template. Also make a few other minor tweaks. --- .github/PULL_REQUEST_TEMPLATE.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 38fbae5f8de4..8d1db94323fd 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,11 +1,11 @@ @@ -16,10 +16,10 @@ Please provide the following information: **- How to verify it** -**- Which release branch to backport (provide reason below if seleted)** +**- Which release branch to backport (provide reason below if selected)** susbcriber table's object + config_db_subscriber_table_map = {} + + # Loop through all asic namespaces (if present) and host (namespace='') + for namespace in self.config_db_map.keys(): + # Unconditionally update control plane ACLs once at start on given namespace + self.update_control_plane_acls(namespace) + # Connect to Config DB of given namespace + acl_db_connector = swsscommon.DBConnector("CONFIG_DB", 0, False, namespace) + # Subscribe to notifications when ACL tables changes + subscribe_acl_table = swsscommon.SubscriberStateTable(acl_db_connector, swsscommon.CFG_ACL_TABLE_TABLE_NAME) + # Subscribe to notifications when ACL rule tables changes + subscribe_acl_rule_table = swsscommon.SubscriberStateTable(acl_db_connector, swsscommon.CFG_ACL_RULE_TABLE_NAME) + # Add both tables to the selectable object + sel.addSelectable(subscribe_acl_table) + sel.addSelectable(subscribe_acl_rule_table) + # Update the map + config_db_subscriber_table_map[namespace] = [] + config_db_subscriber_table_map[namespace].append(subscribe_acl_table) + config_db_subscriber_table_map[namespace].append(subscribe_acl_rule_table) + + # Loop on select to see if any event happen on config db of any namespace + while True: + (state, c) = sel.select(SELECT_TIMEOUT_MS) + # Continue if select is timeout or selectable object is not return + if state != swsscommon.Select.OBJECT: + continue + # Get the corresponding namespace from selectable object + namespace = c.getDbNamespace() + # Pop data of both Subscriber Table object of namespace that got config db acl table event + for table in config_db_subscriber_table_map[namespace]: + table.pop() + # Update the Control Plane ACL of the namespace that got config db acl table event + self.update_control_plane_acls(namespace) # ============================= Functions ============================= + def main(): log_info("Starting up...") diff --git a/slave.mk b/slave.mk index 83c45aec0bfd..63779c22d636 100644 --- a/slave.mk +++ b/slave.mk @@ -790,7 +790,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(KDUMP_TOOLS) \ $(LIBPAM_TACPLUS) \ $(LIBNSS_TACPLUS) \ - $(MONIT)) \ + $(MONIT) \ + $(PYTHON_SWSSCOMMON)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \ @@ -842,6 +843,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export sonic_yang_models_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3))" export sonic_yang_mgmt_py_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY))" export multi_instance="false" + export python_swss_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($(LIBSWSSCOMMON)_RDEPENDS))" + export python_swss_debs+=" $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(LIBSWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON_SWSSCOMMON))" $(foreach docker, $($*_DOCKERS),\ export docker_image="$(docker)" From a273e56bc672609933567676b2788e9af289b2c7 Mon Sep 17 00:00:00 2001 From: Sangita Maity Date: Thu, 20 Aug 2020 17:10:58 -0700 Subject: [PATCH 1057/1427] Add support to VS platform for platform.json and DPB CLI Tests (#5192) - Reverts commit 457674c - Creates "platform.json" for vs docker - Adds test case for port breakout CLI - Explicitly sets admin status of all the VS interfaces to down to be compatible with SWSS test cases, specifically vnet tests and sflow tests Signed-off-by: Sangita Maity --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 7 +- platform/vs/docker-sonic-vs/hwsku.json | 100 +++++++ platform/vs/docker-sonic-vs/platform.json | 196 ++++++++++++++ platform/vs/docker-sonic-vs/start.sh | 6 +- .../sample_output/sample_new_port_config.json | 252 ++++++++++++++++++ .../vs/tests/breakout/test_breakout_cli.py | 168 ++++++++++++ 6 files changed, 726 insertions(+), 3 deletions(-) create mode 100644 platform/vs/docker-sonic-vs/hwsku.json create mode 100644 platform/vs/docker-sonic-vs/platform.json create mode 100644 platform/vs/tests/breakout/sample_output/sample_new_port_config.json create mode 100755 platform/vs/tests/breakout/test_breakout_cli.py diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index e96db2d79ddc..2e133165f5bc 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -46,7 +46,8 @@ RUN apt-get install -y net-tools \ python-scapy \ conntrack \ iptables \ - python3-pip + python3-pip \ + jq RUN pip install setuptools RUN pip3 install setuptools @@ -132,6 +133,10 @@ COPY ["hostname.j2", "/usr/share/sonic/templates/"] COPY ["default_chassis_cfg.json", "/etc/default/sonic-db/"] COPY ["chassis_db.py", "/usr/bin/"] +COPY ["platform.json", "/usr/share/sonic/device/x86_64-kvm_x86_64-r0/"] +COPY ["hwsku.json", "/usr/share/sonic/device/x86_64-kvm_x86_64-r0/Force10-S6000/"] +COPY ["platform.json", "/usr/share/sonic/platform/"] + # Workaround the tcpdump issue RUN mv /usr/sbin/tcpdump /usr/bin/tcpdump diff --git a/platform/vs/docker-sonic-vs/hwsku.json b/platform/vs/docker-sonic-vs/hwsku.json new file mode 100644 index 000000000000..ed121868c9f5 --- /dev/null +++ b/platform/vs/docker-sonic-vs/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[40G]" + } + } +} diff --git a/platform/vs/docker-sonic-vs/platform.json b/platform/vs/docker-sonic-vs/platform.json new file mode 100644 index 000000000000..053fed5516ed --- /dev/null +++ b/platform/vs/docker-sonic-vs/platform.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "0,0,0,0", + "lanes": "25,26,27,28", + "alias_at_lanes": "fortyGigE0/0,fortyGigE0/1,fortyGigE0/2,fortyGigE0/3", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet4": { + "index": "1,1,1,1", + "lanes": "29,30,31,32", + "alias_at_lanes": "fortyGigE0/4,fortyGigE0/5,fortyGigE0/6,fortyGigE0/7", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet8": { + "index": "2,2,2,2", + "lanes": "33,34,35,36", + "alias_at_lanes": "fortyGigE0/8,fortyGigE0/9,fortyGigE0/10,fortyGigE0/11", + "breakout_modes": "1x100G[40G],2x50G,2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet12": { + "index": "3,3,3,3", + "lanes": "37,38,39,40", + "alias_at_lanes": "fortyGigE0/12,fortyGigE0/13,fortyGigE0/14,fortyGigE0/15", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet16": { + "index": "4,4,4,4", + "lanes": "45,46,47,48", + "alias_at_lanes": "fortyGigE0/16,fortyGigE0/17,fortyGigE0/18,fortyGigE0/19", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet20": { + "index": "5,5,5,5", + "lanes": "41,42,43,44", + "alias_at_lanes": "fortyGigE0/20,fortyGigE0/21,fortyGigE0/22,fortyGigE0/23", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet24": { + "index": "6,6,6,6", + "lanes": "1,2,3,4", + "alias_at_lanes": "fortyGigE0/24,fortyGigE0/25,fortyGigE0/26,fortyGigE0/27", + "breakout_modes": "1x100G[40G],4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet28": { + "index": "7,7,7,7", + "lanes": "5,6,7,8", + "alias_at_lanes": "fortyGigE0/28,fortyGigE0/29,fortyGigE0/30,fortyGigE0/31", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet32": { + "index": "8,8,8,8", + "lanes": "13,14,15,16", + "alias_at_lanes": "fortyGigE0/32,fortyGigE0/33,fortyGigE0/34,fortyGigE0/35", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet36": { + "index": "9,9,9,9", + "lanes": "9,10,11,12", + "alias_at_lanes": "fortyGigE0/36,fortyGigE0/37,fortyGigE0/38,fortyGigE0/39", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet40": { + "index": "10,10,10,10", + "lanes": "17,18,19,20", + "alias_at_lanes": "fortyGigE0/40,fortyGigE0/41,fortyGigE0/42,fortyGigE0/43", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet44": { + "index": "11,11,11,11", + "lanes": "21,22,23,24", + "alias_at_lanes": "fortyGigE0/44,fortyGigE0/45,fortyGigE0/46,fortyGigE0/47", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet48": { + "index": "12,12,12,12", + "lanes": "53,54,55,56", + "alias_at_lanes": "fortyGigE0/48,fortyGigE0/49,fortyGigE0/50,fortyGigE0/51", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet52": { + "index": "13,13,13,13", + "lanes": "49,50,51,52", + "alias_at_lanes": "fortyGigE0/52,fortyGigE0/53,fortyGigE0/54,fortyGigE0/55", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet56": { + "index": "14,14,14,14", + "lanes": "57,58,59,60", + "alias_at_lanes": "fortyGigE0/56,fortyGigE0/57,fortyGigE0/58,fortyGigE0/59", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet60": { + "index": "15,15,15,15", + "lanes": "61,62,63,64", + "alias_at_lanes": "fortyGigE0/60,fortyGigE0/61,fortyGigE0/62,fortyGigE0/63", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet64": { + "index": "16,16,16,16", + "lanes": "69,70,71,72", + "alias_at_lanes": "fortyGigE0/64,fortyGigE0/65,fortyGigE0/66,fortyGigE0/67", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet68": { + "index": "17,17,17,17", + "lanes": "65,66,67,68", + "alias_at_lanes": "fortyGigE0/68,fortyGigE0/69,fortyGigE0/70,fortyGigE0/71", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet72": { + "index": "18,18,18,18", + "lanes": "73,74,75,76", + "alias_at_lanes": "fortyGigE0/72,fortyGigE0/73,fortyGigE0/74,fortyGigE0/75", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet76": { + "index": "19,19,19,19", + "lanes": "77,78,79,80", + "alias_at_lanes": "fortyGigE0/76,fortyGigE0/77,fortyGigE0/78,fortyGigE0/79", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet80": { + "index": "20,20,20,20", + "lanes": "109,110,111,112", + "alias_at_lanes": "fortyGigE0/80,fortyGigE0/81,fortyGigE0/82,fortyGigE0/83", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet84": { + "index": "21,21,21,21", + "lanes": "105,106,107,108", + "alias_at_lanes": "fortyGigE0/84,fortyGigE0/85,fortyGigE0/86,fortyGigE0/87", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet88": { + "index": "22,22,22,22", + "lanes": "113,114,115,116", + "alias_at_lanes": "fortyGigE0/88,fortyGigE0/89,fortyGigE0/90,fortyGigE0/91", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet92": { + "index": "23,23,23,23", + "lanes": "117,118,119,120", + "alias_at_lanes": "fortyGigE0/92,fortyGigE0/93,fortyGigE0/94,fortyGigE0/95", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet96": { + "index": "24,24,24,24", + "lanes": "125,126,127,128", + "alias_at_lanes": "fortyGigE0/96,fortyGigE0/97,fortyGigE0/98,fortyGigE0/99", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet100": { + "index": "25,25,25,25", + "lanes": "121,122,123,124", + "alias_at_lanes": "fortyGigE0/100,fortyGigE0/101,fortyGigE0/102,fortyGigE0/103", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet104": { + "index": "26,26,26,26", + "lanes": "81,82,83,84", + "alias_at_lanes": "fortyGigE0/104,fortyGigE0/105,fortyGigE0/106,fortyGigE0/107", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet108": { + "index": "27,27,27,27", + "lanes": "85,86,87,88", + "alias_at_lanes": "fortyGigE0/108,fortyGigE0/109,fortyGigE0/110,fortyGigE0/111", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet112": { + "index": "28,28,28,28", + "lanes": "93,94,95,96", + "alias_at_lanes": "fortyGigE0/112,fortyGigE0/113,fortyGigE0/114,fortyGigE0/115", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet116": { + "index": "29,29,29,29", + "lanes": "89,90,91,92", + "alias_at_lanes": "fortyGigE0/116,fortyGigE0/117,fortyGigE0/118,fortyGigE0/119", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet120": { + "index": "30,30,30,30", + "lanes": "101,102,103,104", + "alias_at_lanes": "fortyGigE0/120,fortyGigE0/121,fortyGigE0/122,fortyGigE0/123", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet124": { + "index": "31,31,31,31", + "lanes": "97,98,99,100", + "alias_at_lanes": "fortyGigE0/124,fortyGigE0/125,fortyGigE0/126,fortyGigE0/127", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + } + } +} diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 5b1d462685a3..bf2e8acacb36 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -38,9 +38,11 @@ if [ -f /etc/sonic/config_db.json ]; then mv /tmp/config_db.json /etc/sonic/config_db.json else # generate and merge buffers configuration into config file - sonic-cfggen -k $HWSKU -p /usr/share/sonic/hwsku/port_config.ini -t /usr/share/sonic/hwsku/buffers.json.j2 > /tmp/buffers.json + sonic-cfggen -k $HWSKU -p /usr/share/sonic/device/$PLATFORM/platform.json -t /usr/share/sonic/hwsku/buffers.json.j2 > /tmp/buffers.json sonic-cfggen -j /etc/sonic/init_cfg.json -t /usr/share/sonic/hwsku/qos.json.j2 > /tmp/qos.json - sonic-cfggen -p /usr/share/sonic/hwsku/port_config.ini -k $HWSKU --print-data > /tmp/ports.json + sonic-cfggen -p /usr/share/sonic/device/$PLATFORM/platform.json -k $HWSKU --print-data > /tmp/ports.json + # change admin_status from up to down; Test cases dependent + sed -i "s/up/down/g" /tmp/ports.json sonic-cfggen -j /etc/sonic/init_cfg.json -j /tmp/buffers.json -j /tmp/qos.json -j /tmp/ports.json --print-data > /etc/sonic/config_db.json fi diff --git a/platform/vs/tests/breakout/sample_output/sample_new_port_config.json b/platform/vs/tests/breakout/sample_output/sample_new_port_config.json new file mode 100644 index 000000000000..7c5c190a3330 --- /dev/null +++ b/platform/vs/tests/breakout/sample_output/sample_new_port_config.json @@ -0,0 +1,252 @@ +{ + "Ethernet0_2x50G": { + "Ethernet2": { + "alias": "fortyGigE0/2", + "admin_status": "up", + "lanes": "27,28", + "speed": "50000", + "index": "0" + }, + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25,26", + "speed": "50000", + "index": "0" + } + }, + "Ethernet12_1x50G_2x25G": { + "Ethernet12": { + "alias": "fortyGigE0/12", + "admin_status": "up", + "lanes": "37,38", + "speed": "50000", + "index": "3" + }, + "Ethernet14": { + "alias": "fortyGigE0/14", + "admin_status": "up", + "lanes": "39", + "speed": "25000", + "index": "3" + }, + "Ethernet15": { + "alias": "fortyGigE0/15", + "admin_status": "up", + "lanes": "40", + "speed": "25000", + "index": "3" + } + }, + "Ethernet0_2x50G": { + "Ethernet2": { + "alias": "fortyGigE0/2", + "admin_status": "up", + "lanes": "27,28", + "speed": "50000", + "index": "0" + }, + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25,26", + "speed": "50000", + "index": "0" + } + }, + "Ethernet0_1x100G": { + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25,26,27,28", + "speed": "100000", + "index": "0" + } + }, + "Ethernet0_4x25G": { + "Ethernet2": { + "alias": "fortyGigE0/2", + "admin_status": "up", + "lanes": "27", + "speed": "25000", + "index": "0" + }, + "Ethernet3": { + "alias": "fortyGigE0/3", + "admin_status": "up", + "lanes": "28", + "speed": "25000", + "index": "0" + }, + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25", + "speed": "25000", + "index": "0" + }, + "Ethernet1": { + "alias": "fortyGigE0/1", + "admin_status": "up", + "lanes": "26", + "speed": "25000", + "index": "0" + } + }, + "Ethernet0_2x25G_1x50G": { + "Ethernet2": { + "alias": "fortyGigE0/2", + "admin_status": "up", + "lanes": "27,28", + "speed": "50000", + "index": "0" + }, + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25", + "speed": "25000", + "index": "0" + }, + "Ethernet1": { + "alias": "fortyGigE0/1", + "admin_status": "up", + "lanes": "26", + "speed": "25000", + "index": "0" + } + }, + "Ethernet0_1x50G_2x25G": { + "Ethernet2": { + "alias": "fortyGigE0/2", + "admin_status": "up", + "lanes": "27", + "speed": "25000", + "index": "0" + }, + "Ethernet3": { + "alias": "fortyGigE0/3", + "admin_status": "up", + "lanes": "28", + "speed": "25000", + "index": "0" + }, + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25,26", + "speed": "50000", + "index": "0" + } + }, + "Ethernet4_4x25G": { + "Ethernet6": { + "alias": "fortyGigE0/6", + "admin_status": "up", + "lanes": "31", + "speed": "25000", + "index": "1" + }, + "Ethernet7": { + "alias": "fortyGigE0/7", + "admin_status": "up", + "lanes": "32", + "speed": "25000", + "index": "1" + }, + "Ethernet4": { + "alias": "fortyGigE0/4", + "admin_status": "up", + "lanes": "29", + "speed": "25000", + "index": "1" + }, + "Ethernet5": { + "alias": "fortyGigE0/5", + "admin_status": "up", + "lanes": "30", + "speed": "25000", + "index": "1" + } + }, + "Ethernet4_2x50G": { + "Ethernet6": { + "alias": "fortyGigE0/6", + "admin_status": "up", + "lanes": "31,32", + "speed": "50000", + "index": "1" + }, + "Ethernet4": { + "alias": "fortyGigE0/4", + "admin_status": "up", + "lanes": "29,30", + "speed": "50000", + "index": "1" + } + }, + "Ethernet8_2x50G": { + "Ethernet8": { + "alias": "fortyGigE0/8", + "admin_status": "up", + "lanes": "33,34", + "speed": "50000", + "index": "2" + }, + "Ethernet10": { + "alias": "fortyGigE0/10", + "admin_status": "up", + "lanes": "35,36", + "speed": "50000", + "index": "2" + } + }, + "Ethernet8_1x50G_2x25G": { + "Ethernet10": { + "alias": "fortyGigE0/10", + "admin_status": "up", + "lanes": "35", + "speed": "25000", + "index": "2" + }, + "Ethernet11": { + "alias": "fortyGigE0/11", + "admin_status": "up", + "lanes": "36", + "speed": "25000", + "index": "2" + } + }, + "Ethernet8_2x25G_1x50G": { + "Ethernet8": { + "alias": "fortyGigE0/8", + "admin_status": "up", + "lanes": "33", + "speed": "25000", + "index": "2" + }, + "Ethernet9": { + "alias": "fortyGigE0/9", + "admin_status": "up", + "lanes": "34", + "speed": "25000", + "index": "2" + }, + "Ethernet10": { + "alias": "fortyGigE0/10", + "admin_status": "up", + "lanes": "35,36", + "speed": "50000", + "index": "2" + } + }, + "Ethernet8_1x100G": { + "Ethernet8": { + "alias": "fortyGigE0/8", + "admin_status": "up", + "lanes": "33,34,35,36", + "speed": "100000", + "index": "2" + } + } +} diff --git a/platform/vs/tests/breakout/test_breakout_cli.py b/platform/vs/tests/breakout/test_breakout_cli.py new file mode 100755 index 000000000000..d93dc0e044a6 --- /dev/null +++ b/platform/vs/tests/breakout/test_breakout_cli.py @@ -0,0 +1,168 @@ +from swsscommon import swsscommon +import time +import os +import json +import ast +import pytest +import collections + +@pytest.mark.usefixtures('dpb_setup_fixture') +class TestBreakoutCli(object): + def setup_db(self, dvs): + self.cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0) + + def read_Json(self, dvs): + test_dir = os.path.dirname(os.path.realpath(__file__)) + sample_output_file = os.path.join(test_dir, 'sample_output', 'sample_new_port_config.json') + with open(sample_output_file, 'rb') as fh: + fh_data = json.load(fh) + + if not fh_data: + return False + expected = ast.literal_eval(json.dumps(fh_data)) + return expected + + def breakout(self, dvs, interface, brkout_mode): + (exitcode, result) = dvs.runcmd("config interface breakout {} {} -y".format(interface, brkout_mode)) + + if result.strip("\n")[0] == "[ERROR] Breakout feature is not available without platform.json file" : + pytest.skip("**** This test is not needed ****") + root_dir = os.path.dirname('/') + (exitcode, output_dict) = dvs.runcmd("jq '.' new_port_config.json") + if output_dict is None: + raise Exception("Breakout output cant be None") + + output_dict = ast.literal_eval(output_dict.strip()) + return output_dict + + # Check Initial Brakout Mode + def test_InitialBreakoutMode(self, dvs, testlog): + self.setup_db(dvs) + + output_dict = {} + brkoutTbl = swsscommon.Table(self.cdb, "BREAKOUT_CFG") + brkout_entries = brkoutTbl.getKeys() + assert len(brkout_entries) == 32 + + for key in brkout_entries: + (status, fvs) = brkoutTbl.get(key) + assert status + + brkout_mode = fvs[0][1] + output_dict[key] = brkout_mode + output = collections.OrderedDict(sorted(output_dict.items(), key=lambda t: t[0])) + expected_dict = \ + {'Ethernet8': '1x100G[40G]', 'Ethernet0': '1x100G[40G]', 'Ethernet4': '1x100G[40G]', \ + 'Ethernet108': '1x100G[40G]', 'Ethernet100': '1x100G[40G]', 'Ethernet104': '1x100G[40G]', \ + 'Ethernet68': '1x100G[40G]', 'Ethernet96': '1x100G[40G]', 'Ethernet124': '1x100G[40G]', \ + 'Ethernet92': '1x100G[40G]', 'Ethernet120': '1x100G[40G]', 'Ethernet52': '1x100G[40G]', \ + 'Ethernet56': '1x100G[40G]', 'Ethernet76': '1x100G[40G]', 'Ethernet72': '1x100G[40G]', \ + 'Ethernet32': '1x100G[40G]', 'Ethernet16': '1x100G[40G]', 'Ethernet36': '1x100G[40G]', \ + 'Ethernet12': '1x100G[40G]', 'Ethernet28': '1x100G[40G]', 'Ethernet88': '1x100G[40G]', \ + 'Ethernet116': '1x100G[40G]', 'Ethernet80': '1x100G[40G]', 'Ethernet112': '1x100G[40G]', \ + 'Ethernet84': '1x100G[40G]', 'Ethernet48': '1x100G[40G]', 'Ethernet44': '1x100G[40G]', \ + 'Ethernet40': '1x100G[40G]', 'Ethernet64': '1x100G[40G]', 'Ethernet60': '1x100G[40G]', \ + 'Ethernet20': '1x100G[40G]', 'Ethernet24': '1x100G[40G]'} + expected = collections.OrderedDict(sorted(expected_dict.items(), key=lambda t: t[0])) + assert output == expected + + # Breakout Cli Test Mode + def test_breakout_modes(self, dvs): + expected = self.read_Json(dvs) + assert expected + + print("**** Breakout Cli test Starts ****") + output_dict = self.breakout(dvs, 'Ethernet0', '2x50G') + expected_dict = expected["Ethernet0_2x50G"] + assert output_dict == expected_dict + print("**** 1X100G --> 2x50G passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '4x25G[10G]') + expected_dict = expected["Ethernet4_4x25G"] + assert output_dict == expected_dict + print("**** 1X100G --> 4x25G[10G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '2x25G(2)+1x50G(2)') + expected_dict = expected["Ethernet8_2x25G_1x50G"] + assert output_dict == expected_dict + print("**** 1X100G --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet12', '1x50G(2)+2x25G(2)') + expected_dict = expected["Ethernet12_1x50G_2x25G"] + assert output_dict == expected_dict + print("**** 1X100G --> 1x50G(2)+2x25G(2) passed ****") + + # TODOFIX: remove comments once #4442 PR got merged and + # yang model for DEVICE_METADATA becomes available. + # As below test cases are dependent on DEVICE_METADATA to go + # from a non-default breakout mode to a different breakout mode. + """ + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 2x50G --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '4x25G[10G]') + expected_dict = expected["Ethernet0_4x25G"] + assert output_dict == expected_dict + print("**** 1X100G --> 4x25G[10G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 4x25G[10G] --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '2x50G') + print("**** 1X100G --> 2x50G mode change ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '4x25G[10G]') + expected_dict = expected["Ethernet4_4x25G"] + assert output_dict == expected_dict + print("**** 2X50G --> 4x25G[10G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '2x50G') + expected_dict = expected["Ethernet4_2x50G"] + assert output_dict == expected_dict + print("**** 4x25G[10G] --> 2X50G passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '1x100G[40G]') + print("**** 2x50G -- > 1X100G mode change ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '2x25G(2)+1x50G(2)') + expected_dict = expected["Ethernet0_2x25G_1x50G"] + assert output_dict == expected_dict + print("**** 1x100G[40G] --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 2x25G(2)+1x50G(2) --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x50G(2)+2x25G(2)') + expected_dict = expected["Ethernet0_1x50G_2x25G"] + assert output_dict == expected_dict + print("**** 1x100G[40G] --> 1x50G(2)+2x25G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 1x50G(2)+2x25G(2) --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '2x50G') + print("**** 1x100G[40G] --> 2x50G mode change ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '1x50G(2)+2x25G(2)') + expected_dict = expected["Ethernet8_1x50G_2x25G"] + assert output_dict == expected_dict + print("**** 2x50G --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '2x25G(2)+1x50G(2)') + expected_dict = expected["Ethernet8_2x25G_1x50G"] + assert output_dict == expected_dict + print("**** 1x50G(2)+2x25G(2) --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '1x100G[40G]') + expected_dict = expected["Ethernet8_1x100G"] + assert output_dict == expected_dict + print("**** 2x25G(2)+1x50G(2) --> 1x100G[40G] passed ****") + """ From 570dbf52f66200ce57ef086daaeb0bd9e0242d70 Mon Sep 17 00:00:00 2001 From: Kelly Chen Date: Fri, 21 Aug 2020 15:27:04 +0800 Subject: [PATCH 1058/1427] [iccpd] Fix uninitialized variable. (#5112) To declare *tb[] but do not initialize it, it might be very risky. We get iccpd exception during processing arp/nd event. Initialize it to {0}; --- src/iccpd/src/iccp_ifm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/iccpd/src/iccp_ifm.c b/src/iccpd/src/iccp_ifm.c index ea8ce20f05c3..258c661e03a4 100644 --- a/src/iccpd/src/iccp_ifm.c +++ b/src/iccpd/src/iccp_ifm.c @@ -502,7 +502,7 @@ int do_one_neigh_request(struct nlmsghdr *n) { struct ndmsg *ndm = NLMSG_DATA(n); int len = n->nlmsg_len; - struct rtattr * tb[NDA_MAX + 1]; + struct rtattr *tb[NDA_MAX + 1] = {0}; if (n->nlmsg_type == NLMSG_DONE) { @@ -966,7 +966,7 @@ void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n) { struct ifinfomsg *ifm = NLMSG_DATA(n); int len = n->nlmsg_len; - struct rtattr * tb[IFLA_MAX + 1]; + struct rtattr *tb[IFLA_MAX + 1] = {0}; if (n->nlmsg_type != RTM_NEWLINK) { From 1a805e740967e89c0238449749f4e6a68b7ce7f0 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 21 Aug 2020 07:33:19 -0700 Subject: [PATCH 1059/1427] Fix unwanted python exception in syslog during database container (#5227) startup when doing redis PING since database_config.json getting generated from jinja2 template is still not ready. Signed-off-by: Abhishek Dosi --- files/build_templates/docker_image_ctl.j2 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 7d266e7d650e..e252af17718b 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -95,8 +95,13 @@ function postStartAction() link_namespace $DEV fi - # Wait until redis starts - until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do + # Wait until supervisord and redis starts. This change is needed + # because now database_config.json is jinja2 templated based + # and by the time file gets generated if we do redis ping + # then we catch python exception of file not valid + # that comes to syslog which is unwanted so wait till database + # config is ready and then ping + until [[ ($(docker exec -i database$DEV pgrep -x -c supervisord) -gt 0) && ($($SONIC_DB_CLI PING | grep -c PONG) -gt 0) ]]; do sleep 1; done From 90cbb4d78c7d46bb28b4141c1732ab635e4d7a5e Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Fri, 21 Aug 2020 09:51:41 -0700 Subject: [PATCH 1060/1427] [hostcfgd] Handle Both Service And Timer Units (#5228) Commit e484ae9dd introduced systemd .timer unit to hostcfgd. However, when stopping service that has timer, there is possibility that timer is not running and the service would not be stopped. This PR address this situation by handling both .timer and .service units. signed-off-by: Tamer Ahmed --- files/image_config/hostcfgd/hostcfgd | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 2817e37a8f4c..29c88eb6456a 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -42,12 +42,15 @@ def obfuscate(data): def update_feature_state(feature_name, state, has_timer=False): - feature_suffix = "timer" if has_timer else "service" + feature_suffixes = ["service"] + (["timer"] if has_timer else []) if state == "enabled": start_cmds = [] - start_cmds.append("sudo systemctl unmask {}.{}".format(feature_name, feature_suffix)) - start_cmds.append("sudo systemctl enable {}.{}".format(feature_name, feature_suffix)) - start_cmds.append("sudo systemctl start {}.{}".format(feature_name, feature_suffix)) + for suffix in feature_suffixes: + start_cmds.append("sudo systemctl unmask {}.{}".format(feature_name, suffix)) + start_cmds.append("sudo systemctl enable {}.{}".format(feature_name, suffix)) + # If feature has timer associated with it, start corresponding systemd .timer unit + # otherwise, start corresponding systemd .service unit + start_cmds.append("sudo systemctl start {}.{}".format(feature_name, feature_suffixes[-1])) for cmd in start_cmds: syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) try: @@ -56,12 +59,14 @@ def update_feature_state(feature_name, state, has_timer=False): syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" .format(err.cmd, err.returncode, err.output)) continue - syslog.syslog(syslog.LOG_INFO, "Feature '{}.{}' is enabled and started".format(feature_name, feature_suffix)) + syslog.syslog(syslog.LOG_INFO, "Feature '{}.{}' is enabled and started" + .format(feature_name, feature_suffixes[-1])) elif state == "disabled": stop_cmds = [] - stop_cmds.append("sudo systemctl stop {}.{}".format(feature_name, feature_suffix)) - stop_cmds.append("sudo systemctl disable {}.{}".format(feature_name, feature_suffix)) - stop_cmds.append("sudo systemctl mask {}.{}".format(feature_name, feature_suffix)) + for suffix in reversed(feature_suffixes): + stop_cmds.append("sudo systemctl stop {}.{}".format(feature_name, suffix)) + stop_cmds.append("sudo systemctl disable {}.{}".format(feature_name, suffix)) + stop_cmds.append("sudo systemctl mask {}.{}".format(feature_name, suffix)) for cmd in stop_cmds: syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) try: @@ -72,8 +77,8 @@ def update_feature_state(feature_name, state, has_timer=False): continue syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(feature_name)) else: - syslog.syslog(syslog.LOG_ERR, "Unexpected state value '{}' for feature '{}.{}'" - .format(state, feature_name, feature_suffix)) + syslog.syslog(syslog.LOG_ERR, "Unexpected state value '{}' for feature '{}'" + .format(state, feature_name)) class Iptables(object): From 6f4ef03b2925389acd18467823d6387ed5e5f810 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 21 Aug 2020 10:38:35 -0700 Subject: [PATCH 1061/1427] [arista] Update driver submodules (#5147) - fix watchdog timeout units - fix import path for thermal_manager - remove arista bind mounts for docker-snmp - improve arista bind mounts for pmon --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- rules/docker-platform-monitor.mk | 4 +++- rules/docker-snmp.mk | 2 -- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 99e5e07d91be..77d887095c33 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 99e5e07d91be1094e082cfb363a56c8d0db670bc +Subproject commit 77d887095c331ddff0bc681edfc6a6dd66d96228 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 99e5e07d91be..77d887095c33 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 99e5e07d91be1094e082cfb363a56c8d0db670bc +Subproject commit 77d887095c331ddff0bc681edfc6a6dd66d96228 diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index 9e49ee8a81a1..72f9e145d6d4 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -41,7 +41,9 @@ $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # Mount Arista python library on Aboot images to be used by plugins $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista:/usr/lib/python2.7/dist-packages/arista:ro -$(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista/utils/sonic_platform:/usr/lib/python2.7/dist-packages/sonic_platform:ro +$(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro +$(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/sonic_platform:/usr/lib/python2.7/dist-packages/sonic_platform:ro +$(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python3/dist-packages/sonic_platform:/usr/lib/python3/dist-packages/sonic_platform:ro $(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/bin/sensors $(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/sbin/smartctl diff --git a/rules/docker-snmp.mk b/rules/docker-snmp.mk index 0b2f2e5da3cd..3493a2dfa337 100644 --- a/rules/docker-snmp.mk +++ b/rules/docker-snmp.mk @@ -26,7 +26,5 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_DBG) $(DOCKER_SNMP)_CONTAINER_NAME = snmp $(DOCKER_SNMP)_RUN_OPT += --privileged -t $(DOCKER_SNMP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro -# mount Arista platform python libraries to support corresponding platforms SNMP power status query -$(DOCKER_SNMP)_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro $(DOCKER_SNMP)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SNMP)_BASE_IMAGE_FILES += monit_snmp:/etc/monit/conf.d From 97d44214cff98f9c18e36ff67f606f4d08d5ac51 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 21 Aug 2020 13:12:01 -0700 Subject: [PATCH 1062/1427] [docker-radv] Fix startup issues (#5230) **- Why I did it** PR https://github.com/Azure/sonic-buildimage/pull/4599 introduced two bugs in the startup of the router advertiser container: 1. References to the `wait_for_intf.sh` script were changed to `wait_for_link.sh`, but the actual script was not renamed 2. The `ipv6_found` Jinja2 variable added to the supervisor config file goes out of scope before it is read. **- How I did it** 1. Rename the `wait_for_intf.sh` script to `wait_for_link.sh` 2. Use the Jinja2 "namespace" construct to fix the scope issue **- How to verify it** Ensure all processes in the radv container start properly under the correct conditions (i.e., whether or not there is at least one VLAN with an IPv6 address assigned). --- .../docker-router-advertiser/Dockerfile.j2 | 2 +- .../docker-router-advertiser/docker-init.sh | 4 +-- ...cker-router-advertiser.supervisord.conf.j2 | 29 +++++++++---------- ...ait_for_intf.sh.j2 => wait_for_link.sh.j2} | 0 4 files changed, 17 insertions(+), 18 deletions(-) rename dockers/docker-router-advertiser/{wait_for_intf.sh.j2 => wait_for_link.sh.j2} (100%) diff --git a/dockers/docker-router-advertiser/Dockerfile.j2 b/dockers/docker-router-advertiser/Dockerfile.j2 index 7f57ade4fade..1d5a9acc43ea 100644 --- a/dockers/docker-router-advertiser/Dockerfile.j2 +++ b/dockers/docker-router-advertiser/Dockerfile.j2 @@ -25,7 +25,7 @@ RUN apt-get clean -y && \ rm -rf /debs COPY ["docker-init.sh", "/usr/bin/"] -COPY ["radvd.conf.j2", "wait_for_intf.sh.j2", "docker-router-advertiser.supervisord.conf.j2", "/usr/share/sonic/templates/"] +COPY ["radvd.conf.j2", "wait_for_link.sh.j2", "docker-router-advertiser.supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] diff --git a/dockers/docker-router-advertiser/docker-init.sh b/dockers/docker-router-advertiser/docker-init.sh index a38988186a94..a3f373f438aa 100755 --- a/dockers/docker-router-advertiser/docker-init.sh +++ b/dockers/docker-router-advertiser/docker-init.sh @@ -8,10 +8,10 @@ CFGGEN_PARAMS=" \ -d \ -t /usr/share/sonic/templates/docker-router-advertiser.supervisord.conf.j2,/etc/supervisor/conf.d/supervisord.conf \ -t /usr/share/sonic/templates/radvd.conf.j2,/etc/radvd.conf \ - -t /usr/share/sonic/templates/wait_for_intf.sh.j2,/usr/bin/wait_for_intf.sh \ + -t /usr/share/sonic/templates/wait_for_link.sh.j2,/usr/bin/wait_for_link.sh \ " sonic-cfggen $CFGGEN_PARAMS -chmod +x /usr/bin/wait_for_intf.sh +chmod +x /usr/bin/wait_for_link.sh exec /usr/bin/supervisord diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 index 146e7c1b67db..9bfc8d9220ad 100644 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 @@ -26,20 +26,21 @@ stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true -{# Router advertiser should only run on ToR (T0) devices #} -{% if DEVICE_METADATA.localhost.type == "ToRRouter" %} - - {% if VLAN_INTERFACE %} - {% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} +{# Router advertiser should only run on ToR (T0) devices which have #} +{# at least one VLAN interface which has an IPv6 address asigned #} +{%- set vlan_v6 = namespace(count=0) -%} +{%- if DEVICE_METADATA.localhost.type == "ToRRouter" -%} + {%- if VLAN_INTERFACE -%} + {%- for (name, prefix) in VLAN_INTERFACE|pfx_filter -%} {# If this VLAN has an IPv6 address... #} - {% if prefix | ipv6 %} - {% set ipv6_found = true %} - {% endif %} - {% endfor %} - {% endif %} + {%- if prefix | ipv6 -%} + {%- set vlan_v6.count = vlan_v6.count + 1 -%} + {%- endif -%} + {%- endfor -%} + {%- endif -%} +{%- endif -%} - {# Enusre at least one ipv6 vlan interface #} - {% if ipv6_found == true %} +{%- if vlan_v6.count > 0 %} [program:wait_for_link] command=/usr/bin/wait_for_link.sh priority=3 @@ -60,6 +61,4 @@ stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=wait_for_link:exited - {% endif %} - -{% endif %} +{% endif -%} diff --git a/dockers/docker-router-advertiser/wait_for_intf.sh.j2 b/dockers/docker-router-advertiser/wait_for_link.sh.j2 similarity index 100% rename from dockers/docker-router-advertiser/wait_for_intf.sh.j2 rename to dockers/docker-router-advertiser/wait_for_link.sh.j2 From a1335aa1f4bfe4a63c6daedd894578b1a4f33c9b Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 21 Aug 2020 13:58:46 -0700 Subject: [PATCH 1063/1427] [sonic-utilities] Update submodule (#5233) * src/sonic-utilities d5fdd74...17fb378 (7): > [sonic-installer] Import re module (#1061) > [fast-reboot]: Fix fail to execute fast-reboot problem (#1047) > [config] Reduce Calls to SONiC Cfggen (#1052) > [filter-fdb] Call Filter FDB Main From Within Test Code (#1051) > [sflow_test.py]: Fix show sflow display. (#1054) > Change fast-reboot script to use swss and radv service script (#1036) > Common functions for show CLI support on multi ASIC (#999) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index d5fdd74d3d54..17fb3781b2cb 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit d5fdd74d3d548b608aae849aecf4094ef27adaf0 +Subproject commit 17fb3781b2cb7dfb845faa9f16bc17ccd0069649 From bb57ccecd424a3ab3a6f15504bd60e0b1b2130b1 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Fri, 21 Aug 2020 15:34:14 -0700 Subject: [PATCH 1064/1427] [sonic-host-service]: Add SONiC Host Services infrastructure (#4840) - Why I did it When SONiC is configured with the management framework and/or telemetry services, the applications running inside those containers need to access some functionality on the host system. The following is a non-exhaustive list of such functionality: Image management Configuration save and load ZTP enable/disable and status Show tech support - How I did it The host service is a Python process that listens for requests via D-Bus. It will then service those requests and send a response back to the requestor. This PR only introduces the host service infrastructure. Applications that need access to the host services must add applets that will register on D-Bus endpoints to service the appropriate functionality. - How to verify it - Description for the changelog Add SONiC Host Service for container to execute select commands in host Signed-off-by: Nirenjan Krishnan --- .../build_templates/sonic_debian_extension.j2 | 6 ++ rules/config | 4 + rules/docker-sonic-mgmt-framework.mk | 1 + rules/docker-telemetry.mk | 1 + rules/sonic-host-service.dep | 11 +++ rules/sonic-host-service.mk | 9 +++ slave.mk | 5 +- src/sonic-host-service/Makefile | 41 ++++++++++ src/sonic-host-service/debian/.gitignore | 4 + src/sonic-host-service/debian/changelog | 5 ++ src/sonic-host-service/debian/compat | 1 + src/sonic-host-service/debian/control | 15 ++++ src/sonic-host-service/debian/rules | 9 +++ .../host_modules/host_service.py | 34 ++++++++ .../org.sonic.hostservice.conf | 18 +++++ .../sonic-hostservice.service | 15 ++++ src/sonic-host-service/sonic_host_server.py | 79 +++++++++++++++++++ 17 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 rules/sonic-host-service.dep create mode 100644 rules/sonic-host-service.mk create mode 100644 src/sonic-host-service/Makefile create mode 100644 src/sonic-host-service/debian/.gitignore create mode 100644 src/sonic-host-service/debian/changelog create mode 100644 src/sonic-host-service/debian/compat create mode 100644 src/sonic-host-service/debian/control create mode 100755 src/sonic-host-service/debian/rules create mode 100644 src/sonic-host-service/host_modules/host_service.py create mode 100644 src/sonic-host-service/org.sonic.hostservice.conf create mode 100644 src/sonic-host-service/sonic-hostservice.service create mode 100755 src/sonic-host-service/sonic_host_server.py diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index b22f7ac03a10..9fb517cb09a9 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -196,6 +196,12 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-ztp_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f {% endif %} +{% if include_host_service == "y" %} +# Install SONiC Host Service (and its dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-host-service_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +{% endif %} + # SONiC utilities installs bash-completion as a dependency. However, it is disabled by default # in bash.bashrc, so we copy a version of the file with it enabled here. sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/ diff --git a/rules/config b/rules/config index 1691fd129886..8cffedc4e965 100644 --- a/rules/config +++ b/rules/config @@ -125,6 +125,10 @@ INCLUDE_SFLOW = y # INCLUDE_MGMT_FRAMEWORK - build docker-sonic-mgmt-framework for CLI and REST server support INCLUDE_MGMT_FRAMEWORK = y +# INCLUDE_HOST_SERVICE - build sonic-host-services for mgmt-framework and/or +# telemetry containers to access host functionality +INCLUDE_HOST_SERVICE = n + # INCLUDE_RESTAPI - build docker-sonic-restapi for configuring the switch using REST APIs INCLUDE_RESTAPI = n diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk index 997881ca46f9..65bac8bd9ddc 100644 --- a/rules/docker-sonic-mgmt-framework.mk +++ b/rules/docker-sonic-mgmt-framework.mk @@ -28,6 +28,7 @@ $(DOCKER_MGMT_FRAMEWORK)_CONTAINER_NAME = mgmt-framework $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --privileged -t $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += -v /etc:/host_etc:ro +$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += -v /var/run/dbus:/var/run/dbus:rw $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" $(DOCKER_MGMT_FRAMEWORK)_BASE_IMAGE_FILES += sonic-cli:/usr/bin/sonic-cli diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index b44f7dc60227..c42e15e24430 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -26,6 +26,7 @@ endif $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry $(DOCKER_TELEMETRY)_RUN_OPT += --privileged -t $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_TELEMETRY)_RUN_OPT += -v /var/run/dbus:/var/run/dbus:rw $(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" $(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/sonic-host-service.dep b/rules/sonic-host-service.dep new file mode 100644 index 000000000000..9e5d823caeaf --- /dev/null +++ b/rules/sonic-host-service.dep @@ -0,0 +1,11 @@ + +SPATH := $($(SONIC_HOST_SERVICE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-host-service.mk rules/sonic-host-service.dep +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_HOST_SERVICE)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_HOST_SERVICE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_HOST_SERVICE)_DEP_FILES := $(DEP_FILES) +$(SONIC_HOST_SERVICE)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_HOST_SERVICE)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/sonic-host-service.mk b/rules/sonic-host-service.mk new file mode 100644 index 000000000000..ad786f1a9d1a --- /dev/null +++ b/rules/sonic-host-service.mk @@ -0,0 +1,9 @@ +# SONiC host service package + +ifeq ($(INCLUDE_HOST_SERVICE), y) + +SONIC_HOST_SERVICE = sonic-host-service_1.0.0_all.deb +$(SONIC_HOST_SERVICE)_SRC_PATH = $(SRC_PATH)/sonic-host-service +SONIC_MAKE_DEBS += $(SONIC_HOST_SERVICE) + +endif diff --git a/slave.mk b/slave.mk index 63779c22d636..36849686647d 100644 --- a/slave.mk +++ b/slave.mk @@ -224,6 +224,7 @@ $(info "VS_PREPARE_MEM" : "$(VS_PREPARE_MEM)") $(info "INCLUDE_MGMT_FRAMEWORK" : "$(INCLUDE_MGMT_FRAMEWORK)") $(info "INCLUDE_ICCPD" : "$(INCLUDE_ICCPD)") $(info "INCLUDE_SYSTEM_TELEMETRY" : "$(INCLUDE_SYSTEM_TELEMETRY)") +$(info "INCLUDE_HOST_SERVICE" : "$(INCLUDE_HOST_SERVICE)") $(info "INCLUDE_RESTAPI" : "$(INCLUDE_RESTAPI)") $(info "INCLUDE_SFLOW" : "$(INCLUDE_SFLOW)") $(info "INCLUDE_NAT" : "$(INCLUDE_NAT)") @@ -794,7 +795,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(PYTHON_SWSSCOMMON)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ - $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \ + $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \ + $(if $(findstring y,$(INCLUDE_HOST_SERVICE)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_HOST_SERVICE))) \ $(addprefix $(PYTHON_DEBS_PATH)/,$(SONIC_UTILS)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3)) \ @@ -821,6 +823,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_ztp="$(ENABLE_ZTP)" export include_system_telemetry="$(INCLUDE_SYSTEM_TELEMETRY)" export include_restapi="$(INCLUDE_RESTAPI)" + export include_host_service="$(INCLUDE_HOST_SERVICE)" export include_nat="$(INCLUDE_NAT)" export include_sflow="$(INCLUDE_SFLOW)" export include_mgmt_framework="$(INCLUDE_MGMT_FRAMEWORK)" diff --git a/src/sonic-host-service/Makefile b/src/sonic-host-service/Makefile new file mode 100644 index 000000000000..53eaa4cd510a --- /dev/null +++ b/src/sonic-host-service/Makefile @@ -0,0 +1,41 @@ +################################################################################ +# # +# Copyright 2020 Dell Inc. # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +# # +################################################################################ + +TOPDIR := $(abspath .) +MAIN_TARGET = sonic-host-service_1.0.0_all.deb +INSTALL := /usr/bin/install + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + dpkg-buildpackage -us -uc -b + mv ../$(MAIN_TARGET) $(DEST)/ + +SOURCES := $(wildcard '*.*') $(wildcard 'host_modules/*.py') +install: $(SOURCES) + # Scripts for host service + $(INSTALL) -d $(DESTDIR)/usr/lib/sonic_host_service/host_modules + $(INSTALL) -D $(TOPDIR)/sonic_host_server.py $(DESTDIR)/usr/lib/sonic_host_service + $(INSTALL) -D $(TOPDIR)/host_modules/*.py $(DESTDIR)/usr/lib/sonic_host_service/host_modules + + # D-Bus permissions configuration + $(INSTALL) -d $(DESTDIR)/etc/dbus-1/system.d + $(INSTALL) -D $(TOPDIR)/org.sonic.hostservice.conf $(DESTDIR)/etc/dbus-1/system.d + + # systemd unit + $(INSTALL) -d $(DESTDIR)/lib/systemd/system + $(INSTALL) -D $(TOPDIR)/sonic-hostservice.service $(DESTDIR)/lib/systemd/system + diff --git a/src/sonic-host-service/debian/.gitignore b/src/sonic-host-service/debian/.gitignore new file mode 100644 index 000000000000..9a07690ac277 --- /dev/null +++ b/src/sonic-host-service/debian/.gitignore @@ -0,0 +1,4 @@ +.debhelper +sonic-host-service.* +sonic-host-service/ +files diff --git a/src/sonic-host-service/debian/changelog b/src/sonic-host-service/debian/changelog new file mode 100644 index 000000000000..5c512fe009e8 --- /dev/null +++ b/src/sonic-host-service/debian/changelog @@ -0,0 +1,5 @@ +sonic-host-service (1.0.0) UNRELEASED; urgency=low + + * Initial release. + + -- Nirenjan Krishnan Mon, 22 Jun 2020 00:00:00 +0000 diff --git a/src/sonic-host-service/debian/compat b/src/sonic-host-service/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/sonic-host-service/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/sonic-host-service/debian/control b/src/sonic-host-service/debian/control new file mode 100644 index 000000000000..57d126af60dd --- /dev/null +++ b/src/sonic-host-service/debian/control @@ -0,0 +1,15 @@ +Source: sonic-host-service +Maintainer: Nirenjan Krishnan +Build-Depends: debhelper (>= 8.0.0), + dh-systemd +Vcs-Git: https://github.com/Azure/sonic-buildimage +Homepage: https://github.com/Azure/SONiC/ +Standards-Version: 3.9.3 +Section: net + +Package: sonic-host-service +Priority: extra +Architecture: all +Depends: python3-systemd, python3-dbus, python3-gi, ${misc:Depends} +Description: SONiC Host Service + diff --git a/src/sonic-host-service/debian/rules b/src/sonic-host-service/debian/rules new file mode 100755 index 000000000000..eaed7a19038d --- /dev/null +++ b/src/sonic-host-service/debian/rules @@ -0,0 +1,9 @@ +#!/usr/bin/make -f +%: + dh $@ --with systemd --parallel + +override_dh_auto_clean: +override_dh_auto_test: +override_dh_auto_build: +override_dh_auto_install: + make install DESTDIR=debian/sonic-host-service diff --git a/src/sonic-host-service/host_modules/host_service.py b/src/sonic-host-service/host_modules/host_service.py new file mode 100644 index 000000000000..48f55ae0623c --- /dev/null +++ b/src/sonic-host-service/host_modules/host_service.py @@ -0,0 +1,34 @@ +"""Base class for host modules""" + +import dbus.service +import dbus + +BUS_NAME_BASE = 'org.SONiC.HostService' +BUS_PATH = '/org/SONiC/HostService' + +def bus_name(mod_name): + """Return the bus name for the service""" + return BUS_NAME_BASE + '.' + mod_name + +def bus_path(mod_name): + """Return the bus path for the service""" + return BUS_PATH + '/' + mod_name + +method = dbus.service.method + +class HostService(dbus.service.Object): + """Service class for top level DBus endpoint""" + def __init__(self, mod_name): + self.bus = dbus.SystemBus() + self.bus_name = dbus.service.BusName(BUS_NAME_BASE, self.bus) + super(HostService, self).__init__(self.bus_name, BUS_PATH) + +class HostModule(dbus.service.Object): + """Base class for all host modules""" + def __init__(self, mod_name): + self.bus = dbus.SystemBus() + self.bus_name = dbus.service.BusName(bus_name(mod_name), self.bus) + super(HostModule, self).__init__(self.bus_name, bus_path(mod_name)) + +def register(): + return HostService, "host_service" diff --git a/src/sonic-host-service/org.sonic.hostservice.conf b/src/sonic-host-service/org.sonic.hostservice.conf new file mode 100644 index 000000000000..08599007d9ba --- /dev/null +++ b/src/sonic-host-service/org.sonic.hostservice.conf @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/src/sonic-host-service/sonic-hostservice.service b/src/sonic-host-service/sonic-hostservice.service new file mode 100644 index 000000000000..7717022285b5 --- /dev/null +++ b/src/sonic-host-service/sonic-hostservice.service @@ -0,0 +1,15 @@ +[Unit] +Description=SONiC Host Service + +[Service] +Type=dbus +BusName=org.SONiC.HostService + +ExecStart=/usr/bin/python3 -u /usr/lib/sonic_host_service/sonic_host_server.py + +Restart=on-failure +RestartSec=10 +TimeoutStopSec=3 + +[Install] +WantedBy=multi-user.target diff --git a/src/sonic-host-service/sonic_host_server.py b/src/sonic-host-service/sonic_host_server.py new file mode 100755 index 000000000000..9232209f7dc1 --- /dev/null +++ b/src/sonic-host-service/sonic_host_server.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +"""Host Service to handle docker-to-host communication""" + +import os +import os.path +import glob +import importlib +import sys + +import dbus +import dbus.service +import dbus.mainloop.glib + +from gi.repository import GObject + +def register_modules(): + """Register all host modules""" + mod_path = os.path.join(os.path.dirname(__file__), 'host_modules') + sys.path.append(mod_path) + for mod_file in glob.glob(os.path.join(mod_path, '*.py')): + if os.path.isfile(mod_file) and not mod_file.endswith('__init__.py'): + mod_name = os.path.basename(mod_file)[:-3] + module = importlib.import_module(mod_name) + + register_cb = getattr(module, 'register', None) + if not register_cb: + raise Exception('Missing register function for ' + mod_name) + + register_dbus(register_cb) + +def register_dbus(register_cb): + """Register DBus handlers for individual modules""" + handler_class, mod_name = register_cb() + handlers[mod_name] = handler_class(mod_name) + +# Create a main loop reactor +GObject.threads_init() +dbus.mainloop.glib.threads_init() +dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) +loop = GObject.MainLoop() +handlers = {} + +class SignalManager(object): + ''' This is used to manage signals received (e.g. SIGINT). + When stopping a process (systemctl stop [service]), systemd sends + a SIGTERM signal. + ''' + shutdown = False + def __init__(self): + ''' Install signal handlers. + + SIGTERM is invoked when systemd wants to stop the daemon. + For example, "systemctl stop mydaemon.service" + or, "systemctl restart mydaemon.service" + + ''' + import signal + signal.signal(signal.SIGTERM, self.sigterm_hdlr) + + def sigterm_hdlr(self, _signum, _frame): + self.shutdown = True + loop.quit() + +sigmgr = SignalManager() +register_modules() + +# Only run if we actually have some handlers +if handlers: + import systemd.daemon + systemd.daemon.notify("READY=1") + + while not sigmgr.shutdown: + loop.run() + if sigmgr.shutdown: + break + + systemd.daemon.notify("STOPPING=1") +else: + print("No handlers to register, quitting...") From cbb46e426b5e88d34a6a38b2132b222bd3b896a4 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Sat, 22 Aug 2020 16:24:44 -0700 Subject: [PATCH 1065/1427] Add common functions applicable to single/multi asic platforms (#5224) * Add common functions applicable to single/multi asic platforms * Raise exception if invalid namespace is given as input. --- .../sonic_py_common/multi_asic.py | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index 2083e3935bb6..78bc6d72ba90 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -123,11 +123,17 @@ def is_multi_asic(): def get_asic_id_from_name(asic_name): + """ + Get the asic id from the asic name for multi-asic platforms + In single ASIC platforms, it would fail and throw an exception. + Returns: + asic id. + """ if asic_name.startswith(ASIC_NAME_PREFIX): return asic_name[len(ASIC_NAME_PREFIX):] else: - return None + raise ValueError('Unknown asic namespace name {}'.format(asic_name)) def get_namespaces_from_linux(): @@ -308,3 +314,33 @@ def is_bgp_session_internal(bgp_neigh_ip, namespace=None): else: return False return False + +def get_front_end_namespaces(): + """ + Get the namespaces in the platform. For multi-asic devices we get the namespaces + mapped to asic which have front-panel interfaces. For single ASIC device it is the + DEFAULT_NAMESPACE which maps to the linux host. + + Returns: + a list of namespaces + """ + namespaces = [DEFAULT_NAMESPACE] + if is_multi_asic(): + ns_list = get_all_namespaces() + namespaces = ns_list['front_ns'] + + return namespaces + + +def get_asic_index_from_namespace(namespace): + """ + Get asic index from the namespace name. + With single ASIC platform, return asic_index 0, which is mapped to the only asic present. + + Returns: + asic_index as an integer. + """ + if is_multi_asic(): + return int(get_asic_id_from_name(namespace)) + + return 0 From 87713aaa1bc4bbb4a235a09c253eb5e3260ba6c8 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 22 Aug 2020 18:41:32 -0700 Subject: [PATCH 1066/1427] [sonic-swss] Update submodule (#5231) * src/sonic-swss d2bab10...c4949a2 (34): > [dvs] Add new common issues and TOC to DVS README (#1405) > Avoid adding loopback interface (ip link add) when setting nat zone on loopback interface (#1411) > [portsorch] add buffer drop FC group (#1368) > [dvs/chassis] Bring up SONiC interfaces in virtual chassis (#1410) > [chassis/dvs] Add support for virtual chassis to DVS testbed (#1345) > [sonic-swsss] Fix the issue of field "next_hop_ip" not getting updated in state DB in ERSPAN Mirror (#1375) > [intfmgr] Fix OA crash issue due to link local configurations (#1195) > Fix the issue when persistent DVS is used to run pytest which has number of front-panel ports < 32 (#1373) > [dvs] Refactor AsicDbValidator (#1402) > [fec] Get FEC mode when port is already admin down (#1403) > [fec] added logic that put port down before applying fec onfiguration (#1399) > [dvs] Add performance test for adding and deleting routes (#1392) > Ignore IPv6 link-local and multicast entries as Vnet routes (#1401) > [vlanmgr] Support Jumbo Frame By Default (#1393) > Fix log/syslog not being correct when last test fails for given module (#1395) > Get initial speed from ASIC DB (#1390) > [dvs] Add options to limit CPU usage (#1394) > [intfsorch] Retrieve Port object before setting NAT zone on router interfaces. (#1372) > [.gitignore] Ignore gearsyncd binary (#1381) > Added Max Nexthopgroup/ECMP Count supported by device into State DB. (#1383) > [dvs] Upload logs even if failure occurs during startup (#1389) > [rates] fix issue with rates init (#1387) > [dvs] Validate that SWSS is ready to receive input before starting tests (#1385) > [dvs] Convert sflow and speed tests to use dvslib (#1382) > [dvs_acl] Refactor and document dvs_acl library (#1378) > [dvs] Fix install instructions in README (#1379) > [dvs] Update README with new flags, options, and known issues (#1380) > swss: gearsyncd should return 0 on exit (#1376) > Remove 00-copp.config.json from swss debian package. (#1366) > fix undefined var in rates lua scripts (#1365) > [fdborch] Fixed Orchagent crash in FDB flush on port disable. (#1369) > [tlm_teamd]: Try to add LAG again, when teamd is not ready first time (#1347) > [vs] Incorporate python3 best practices into DVSLib (#1357) > [dvs] Mark unstable tests as xfail (#1356) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index d2bab10efe05..c4949a20a27f 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit d2bab10efe05e8ec209fd5a360778a2d7c8d7f54 +Subproject commit c4949a20a27fcbbe7bbf17cc6fd0a95304584fcb From cd486a82a4d982a7d642905eea33b70d9b013cd3 Mon Sep 17 00:00:00 2001 From: Baptiste Covolato Date: Sat, 22 Aug 2020 18:46:30 -0700 Subject: [PATCH 1067/1427] [arista/aboot]: Zero out 1st MB before repartitioning (#5220) The first partition starting point was changed to be 1M as part of this commit: 6ba2f97f1ec1. On systems that are misaligned before conversion (partition start is the first sector), the relica partition that is left in the first MB can cause problems in Aboot and result in corruption of the filesystem on the new aligned partition. Zeroing this old relica makes sure that there is nothing left of the old partition lying around. There won't be any risk of having Aboot corrupt the new filesystem because of the old relica. Signed-off-by: Baptiste Covolato --- files/initramfs-tools/arista-convertfs.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/files/initramfs-tools/arista-convertfs.j2 b/files/initramfs-tools/arista-convertfs.j2 index 0dad56e5776b..348272c59554 100644 --- a/files/initramfs-tools/arista-convertfs.j2 +++ b/files/initramfs-tools/arista-convertfs.j2 @@ -213,6 +213,9 @@ umount "$root_mnt" if [ $(echo -n "$root_dev" | tail -c 1) == "1" ]; then # Create a new partition table (content in flash_dev will be deleted) + err_msg="Error: Failed to zero out first MB" + cmd="dd if=/dev/zero of=$flash_dev bs=512 count=2048" + run_cmd "$cmd" "$err_msg" err_msg="Error: repartitioning $flash_dev failed" cmd="echo '2048' | sfdisk $flash_dev || (sleep 3; blockdev --rereadpt $flash_dev && fdisk -l $flash_dev | grep -q ${root_dev}.*Linux)" run_cmd "$cmd" "$err_msg" From 58db2d53e34207c6471135a829dcf40d28711570 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 24 Aug 2020 10:35:22 -0700 Subject: [PATCH 1068/1427] [sonic-py-common] Add unit test framework (#5238) **- Why I did it** To install the framework for adding unit tests to the sonic-py-common package and report coverage. ** How I did it ** - Incorporate pytest and pytest-cov into sonic-py-common package build - Updgrade version of 'mock' installed to version 3.0.5, the last version which supports Python 2. This fixes a bug where the file object returned from `mock_open()` was not iterable (see https://bugs.python.org/issue32933) - Add support for Python 3 setuptools and pytest in sonic-slave-buster environment - Add tests for `device_info.get_machine_info()` and `device_info.get_platform()` functions - Also add a .gitignore in the root of the sonic-py-common directory, move all related ignores from main .gitignore file, and add ignores for files and dirs generated by pytest-cov --- .gitignore | 6 -- sonic-slave-buster/Dockerfile.j2 | 27 ++++--- src/sonic-py-common/.gitignore | 13 ++++ src/sonic-py-common/pytest.ini | 2 + src/sonic-py-common/setup.cfg | 2 + src/sonic-py-common/setup.py | 8 ++ .../sonic_py_common/device_info.py | 2 +- src/sonic-py-common/tests/__init__.py | 0 src/sonic-py-common/tests/device_info_test.py | 75 +++++++++++++++++++ 9 files changed, 119 insertions(+), 16 deletions(-) create mode 100644 src/sonic-py-common/.gitignore create mode 100644 src/sonic-py-common/pytest.ini create mode 100644 src/sonic-py-common/setup.cfg create mode 100644 src/sonic-py-common/tests/__init__.py create mode 100644 src/sonic-py-common/tests/device_info_test.py diff --git a/.gitignore b/.gitignore index 307a6cf0ae46..5916ed62b395 100644 --- a/.gitignore +++ b/.gitignore @@ -28,12 +28,6 @@ platform/*/docker-*/Dockerfile # Installer-related files and directories installer/x86_64/platforms/ -src/sonic-py-common/**/*.pyc -src/sonic-py-common/.eggs/ -src/sonic-py-common/build -src/sonic-py-common/dist -src/sonic-py-common/sonic_py_common.egg-info - # Misc. files asic_config_checksum files/Aboot/boot0 diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index e7ad71c53a55..88f905cb0f8a 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -209,8 +209,10 @@ RUN apt-get update && apt-get install -y \ clang \ pylint \ python-pytest \ + python3-pytest \ gcovr \ python-pytest-cov \ + python3-pytest-cov \ python-parse \ # For snmpd default-libmysqlclient-dev \ @@ -339,6 +341,21 @@ RUN export VERSION=1.14.2 \ && echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/bash.bashrc \ && rm go$VERSION.linux-*.tar.gz +# For building Python packages +RUN pip install setuptools==40.8.0 +RUN pip3 install setuptools==49.6.00 + +# For running Python unit tests +RUN pip install pytest-runner==4.4 +RUN pip3 install pytest-runner==5.2 +RUN pip install mockredispy==2.9.3 +RUN pip3 install mockredispy==2.9.3 + +# For Python 2 unit tests, we need 'mock'. The last version of 'mock' +# which supports Python 2 is 3.0.5. In Python 3, 'mock' is part of 'unittest' +# in the standard library +RUN pip install mock==3.0.5 + # For p4 build RUN pip install \ ctypesgen==1.0.2 \ @@ -357,25 +374,17 @@ RUN apt-get purge -y python-click # For sonic utilities testing RUN pip install click natsort tabulate netifaces==0.10.7 fastentrypoints -# For sonic snmpagent mock testing -RUN pip3 install mockredispy==2.9.3 - RUN pip3 install "PyYAML>=5.1" # For sonic-platform-common testing RUN pip3 install redis # For supervisor build -RUN pip install meld3 mock +RUN pip install meld3 # For vs image build RUN pip install pexpect==4.6.0 -# For sonic-utilities build -RUN pip install mockredispy==2.9.3 -RUN pip install pytest-runner==4.4 -RUN pip install setuptools==40.8.0 - # For sonic-swss-common testing RUN pip install Pympler==0.8 diff --git a/src/sonic-py-common/.gitignore b/src/sonic-py-common/.gitignore new file mode 100644 index 000000000000..5f621ff9e2ab --- /dev/null +++ b/src/sonic-py-common/.gitignore @@ -0,0 +1,13 @@ +**/*.pyc + +# Distribution / packaging +*.egg-info/ +.eggs/ +build/ +dist/ + +# Unit test / coverage reports +.cache +.coverage +coverage.xml +htmlcov/ diff --git a/src/sonic-py-common/pytest.ini b/src/sonic-py-common/pytest.ini new file mode 100644 index 000000000000..777811f8f489 --- /dev/null +++ b/src/sonic-py-common/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = --cov=sonic_py_common --cov-report html --cov-report term --cov-report xml diff --git a/src/sonic-py-common/setup.cfg b/src/sonic-py-common/setup.cfg new file mode 100644 index 000000000000..b7e478982ccf --- /dev/null +++ b/src/sonic-py-common/setup.cfg @@ -0,0 +1,2 @@ +[aliases] +test=pytest diff --git a/src/sonic-py-common/setup.py b/src/sonic-py-common/setup.py index b1294472624e..f56ad96b04fd 100644 --- a/src/sonic-py-common/setup.py +++ b/src/sonic-py-common/setup.py @@ -27,6 +27,13 @@ packages=[ 'sonic_py_common', ], + setup_requires= [ + 'pytest-runner' + ], + tests_require=[ + 'pytest', + 'mock==3.0.5' # For python 2. Version >=4.0.0 drops support for py2 + ], classifiers=[ 'Intended Audience :: Developers', 'Operating System :: Linux', @@ -35,5 +42,6 @@ 'Programming Language :: Python', ], keywords='SONiC sonic PYTHON python COMMON common', + test_suite = 'setup.get_test_suite' ) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index 99f818b0f27e..b5aefc397fe8 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -6,7 +6,7 @@ import yaml from natsort import natsorted -# TODD: Replace with swsscommon +# TODO: Replace with swsscommon from swsssdk import ConfigDBConnector, SonicDBConfig USR_SHARE_SONIC_PATH = "/usr/share/sonic" diff --git a/src/sonic-py-common/tests/__init__.py b/src/sonic-py-common/tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-py-common/tests/device_info_test.py b/src/sonic-py-common/tests/device_info_test.py new file mode 100644 index 000000000000..f3b14b0a5f13 --- /dev/null +++ b/src/sonic-py-common/tests/device_info_test.py @@ -0,0 +1,75 @@ +import os +import sys + +# TODO: Remove this if/else block once we no longer support Python 2 +if sys.version_info.major == 3: + from unittest import mock +else: + # Expect the 'mock' package for python 2 + # https://pypi.python.org/pypi/mock + import mock + +from sonic_py_common import device_info + + +# TODO: Remove this if/else block once we no longer support Python 2 +if sys.version_info.major == 3: + BUILTINS = "builtins" +else: + BUILTINS = "__builtin__" + +MACHINE_CONF_CONTENTS = """\ +onie_version=2016.11-5.1.0008-9600 +onie_vendor_id=33049 +onie_machine_rev=0 +onie_arch=x86_64 +onie_config_version=1 +onie_build_date="2017-04-26T11:01+0300" +onie_partition_type=gpt +onie_kernel_version=4.10.11 +onie_firmware=auto +onie_switch_asic=mlnx +onie_skip_ethmgmt_macs=yes +onie_machine=mlnx_msn2700 +onie_platform=x86_64-mlnx_msn2700-r0""" + +EXPECTED_GET_MACHINE_INFO_RESULT = { + 'onie_arch': 'x86_64', + 'onie_skip_ethmgmt_macs': 'yes', + 'onie_platform': 'x86_64-mlnx_msn2700-r0', + 'onie_machine_rev': '0', + 'onie_version': '2016.11-5.1.0008-9600', + 'onie_machine': 'mlnx_msn2700', + 'onie_config_version': '1', + 'onie_partition_type': 'gpt', + 'onie_build_date': '"2017-04-26T11:01+0300"', + 'onie_switch_asic': 'mlnx', + 'onie_vendor_id': '33049', + 'onie_firmware': 'auto', + 'onie_kernel_version': '4.10.11' +} + + +class TestDeviceInfo(object): + @classmethod + def setup_class(cls): + print("SETUP") + + def test_get_machine_info(self): + with mock.patch("os.path.isfile") as mock_isfile: + mock_isfile.return_value = True + open_mocked = mock.mock_open(read_data=MACHINE_CONF_CONTENTS) + with mock.patch("{}.open".format(BUILTINS), open_mocked): + result = device_info.get_machine_info() + assert result == EXPECTED_GET_MACHINE_INFO_RESULT + open_mocked.assert_called_once_with("/host/machine.conf") + + def test_get_platform(self): + with mock.patch("sonic_py_common.device_info.get_machine_info") as get_machine_info_mocked: + get_machine_info_mocked.return_value = EXPECTED_GET_MACHINE_INFO_RESULT + result = device_info.get_platform() + assert result == "x86_64-mlnx_msn2700-r0" + + @classmethod + def teardown_class(cls): + print("TEARDOWN") From f3feb56c8a2a9df55e5450108ae283e45b39724f Mon Sep 17 00:00:00 2001 From: shi-su <67605788+shi-su@users.noreply.github.com> Date: Mon, 24 Aug 2020 14:04:10 -0700 Subject: [PATCH 1069/1427] Add switch for synchronous mode (#5237) Add a master switch so that the sync/async mode can be configured. Example usage of the switch: 1. Configure mode while building an image `make ENABLE_SYNCHRONOUS_MODE=y ` 2. Configure when the device is running Change CONFIG_DB with `sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"synchronous_mode": "enable"}}}' --write-to-db` Restart swss with `systemctl restart swss` --- .gitignore | 2 ++ Makefile.work | 2 ++ dockers/docker-orchagent/orchagent.sh | 6 ++++++ dockers/docker-orchagent/swss_vars.j2 | 3 ++- files/build_templates/init_cfg.json.j2 | 3 ++- platform/p4/docker-sonic-p4/Dockerfile.j2 | 1 + platform/p4/docker-sonic-p4/init_cfg.json.j2 | 7 +++++++ platform/p4/docker-sonic-p4/orchagent.sh | 6 ++++++ platform/p4/docker-sonic-p4/start.sh | 7 ++++++- platform/vs/docker-sonic-vs/Dockerfile.j2 | 1 + platform/vs/docker-sonic-vs/init_cfg.json.j2 | 7 +++++++ platform/vs/docker-sonic-vs/orchagent.sh | 9 ++++++++- platform/vs/docker-sonic-vs/start.sh | 7 ++++++- rules/config | 3 +++ slave.mk | 5 +++++ 15 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 platform/p4/docker-sonic-p4/init_cfg.json.j2 create mode 100644 platform/vs/docker-sonic-vs/init_cfg.json.j2 diff --git a/.gitignore b/.gitignore index 5916ed62b395..88a4174168ca 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,5 @@ platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_lpc.c platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_ich.c platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_mailbox.c platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/ipmihelper.py +platform/vs/docker-sonic-vs/init_cfg.json +platform/p4/docker-sonic-p4/init_cfg.json diff --git a/Makefile.work b/Makefile.work index 4ba02939f991..99e8d85d1b24 100644 --- a/Makefile.work +++ b/Makefile.work @@ -38,6 +38,7 @@ # * SONIC_DPKG_CACHE_METHOD: Specifying method of obtaining the Debian packages from cache: none or cache # * SONIC_DPKG_CACHE_SOURCE: Debian package cache location when cache enabled for debian packages # * BUILD_LOG_TIMESTAMP: Set timestamp in the build log (simple/none) +# * ENABLE_SYNCHRONOUS_MODE: Enable synchronous mode between orchagent and syncd # ############################################################################### @@ -212,6 +213,7 @@ SONIC_BUILD_INSTRUCTION := make \ EXTRA_DOCKER_TARGETS=$(EXTRA_DOCKER_TARGETS) \ BUILD_LOG_TIMESTAMP=$(BUILD_LOG_TIMESTAMP) \ SONIC_ENABLE_IMAGE_SIGNATURE=$(ENABLE_IMAGE_SIGNATURE) \ + ENABLE_SYNCHRONOUS_MODE=$(ENABLE_SYNCHRONOUS_MODE) \ $(SONIC_OVERRIDE_BUILD_VARS) .PHONY: sonic-slave-build sonic-slave-bash init reset diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 8743caea1fb5..fde5370dc181 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -25,6 +25,12 @@ ORCHAGENT_ARGS="-d /var/log/swss " # Set orchagent pop batch size to 8192 ORCHAGENT_ARGS+="-b 8192 " +# Set synchronous mode if it is enabled in CONFIG_DB +SYNC_MODE=$(echo $SWSS_VARS | jq -r '.synchronous_mode') +if [ "$SYNC_MODE" == "enable" ]; then + ORCHAGENT_ARGS+="-s " +fi + # Check if there is an "asic_id field" in the DEVICE_METADATA in configDB. #"DEVICE_METADATA": { # "localhost": { diff --git a/dockers/docker-orchagent/swss_vars.j2 b/dockers/docker-orchagent/swss_vars.j2 index 0a0b2712f46a..cb96aa826f6b 100644 --- a/dockers/docker-orchagent/swss_vars.j2 +++ b/dockers/docker-orchagent/swss_vars.j2 @@ -1,6 +1,7 @@ { "asic_type": "{{ asic_type }}", "asic_id": "{{ DEVICE_METADATA.localhost.asic_id }}", - "mac": "{{ DEVICE_METADATA.localhost.mac }}" + "mac": "{{ DEVICE_METADATA.localhost.mac }}", + "synchronous_mode": "{{ DEVICE_METADATA.localhost.synchronous_mode }}" } diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 6db4fa8893d1..23c0b8eb195f 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -2,7 +2,8 @@ "DEVICE_METADATA": { "localhost": { "default_bgp_status": {% if shutdown_bgp_on_start == "y" %}"down"{% else %}"up"{% endif %}, - "default_pfcwd_status": {% if enable_pfcwd_on_start == "y" %}"enable"{% else %}"disable"{% endif %} + "default_pfcwd_status": {% if enable_pfcwd_on_start == "y" %}"enable"{% else %}"disable"{% endif %}, + "synchronous_mode": {% if enable_synchronous_mode == "y" %}"enable"{% else %}"disable"{% endif %} } }, "CRM": { diff --git a/platform/p4/docker-sonic-p4/Dockerfile.j2 b/platform/p4/docker-sonic-p4/Dockerfile.j2 index 22621b985465..c0063af09bd1 100644 --- a/platform/p4/docker-sonic-p4/Dockerfile.j2 +++ b/platform/p4/docker-sonic-p4/Dockerfile.j2 @@ -78,6 +78,7 @@ COPY ["start.sh", "orchagent.sh", "config_bm.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin"] +COPY ["init_cfg.json", "/etc/sonic/"] RUN echo "docker-sonic-p4" > /etc/hostname RUN touch /etc/quagga/zebra.conf diff --git a/platform/p4/docker-sonic-p4/init_cfg.json.j2 b/platform/p4/docker-sonic-p4/init_cfg.json.j2 new file mode 100644 index 000000000000..a30ea5770dd3 --- /dev/null +++ b/platform/p4/docker-sonic-p4/init_cfg.json.j2 @@ -0,0 +1,7 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "synchronous_mode": {% if enable_synchronous_mode == "y" %}"enable"{% else %}"disable"{% endif %} + } + } +} diff --git a/platform/p4/docker-sonic-p4/orchagent.sh b/platform/p4/docker-sonic-p4/orchagent.sh index 9abfc22c967e..52cdd43265f0 100755 --- a/platform/p4/docker-sonic-p4/orchagent.sh +++ b/platform/p4/docker-sonic-p4/orchagent.sh @@ -13,6 +13,12 @@ ORCHAGENT_ARGS="-d /var/log/swss " # Set orchagent pop batch size to 8192 ORCHAGENT_ARGS+="-b 8192 " +# Set synchronous mode if it is enabled in CONFIG_DB +SYNC_MODE=$(sonic-cfggen -d -v DEVICE_METADATA.localhost.synchronous_mode) +if [ "$SYNC_MODE" == "enable" ]; then + ORCHAGENT_ARGS+="-s " +fi + # Set mac address ORCHAGENT_ARGS+="-m $MAC_ADDRESS" diff --git a/platform/p4/docker-sonic-p4/start.sh b/platform/p4/docker-sonic-p4/start.sh index e3251bb2f4e5..b3c451e7c3d4 100755 --- a/platform/p4/docker-sonic-p4/start.sh +++ b/platform/p4/docker-sonic-p4/start.sh @@ -8,7 +8,12 @@ if ! ip link show eth0 &> /dev/null; then fi SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') -sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /etc/sonic/init_cfg.json +if [ -f /etc/sonic/init_cfg.json ]; then + sonic-cfggen -j /etc/sonic/init_cfg.json -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /tmp/init_cfg.json + mv /tmp/init_cfg.json /etc/sonic/init_cfg.json +else + sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /etc/sonic/init_cfg.json +fi if [ -f /etc/sonic/config_db.json ]; then sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --print-data > /tmp/config_db.json diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 2e133165f5bc..b3a6f1cefa9e 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -128,6 +128,7 @@ COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin/"] COPY ["files/buffers_config.j2", "files/qos_config.j2", "/usr/share/sonic/templates/"] COPY ["files/sonic_version.yml", "/etc/sonic/"] +COPY ["init_cfg.json", "/etc/sonic/"] COPY ["database_config.json", "/etc/default/sonic-db/"] COPY ["hostname.j2", "/usr/share/sonic/templates/"] COPY ["default_chassis_cfg.json", "/etc/default/sonic-db/"] diff --git a/platform/vs/docker-sonic-vs/init_cfg.json.j2 b/platform/vs/docker-sonic-vs/init_cfg.json.j2 new file mode 100644 index 000000000000..a30ea5770dd3 --- /dev/null +++ b/platform/vs/docker-sonic-vs/init_cfg.json.j2 @@ -0,0 +1,7 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "synchronous_mode": {% if enable_synchronous_mode == "y" %}"enable"{% else %}"disable"{% endif %} + } + } +} diff --git a/platform/vs/docker-sonic-vs/orchagent.sh b/platform/vs/docker-sonic-vs/orchagent.sh index 2acd709a8e94..ec703fa10ee6 100755 --- a/platform/vs/docker-sonic-vs/orchagent.sh +++ b/platform/vs/docker-sonic-vs/orchagent.sh @@ -6,7 +6,8 @@ else export platform=$fake_platform fi -MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +CFG_VARS=$(sonic-cfggen -d --var-json 'DEVICE_METADATA') +MAC_ADDRESS=$(echo $CFG_VARS | jq -r '.localhost.mac') if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') logger "Mac address not found in Device Metadata, Falling back to eth0" @@ -19,6 +20,12 @@ ORCHAGENT_ARGS="-d /var/log/swss " # Set orchagent pop batch size to 8192 ORCHAGENT_ARGS+="-b 8192 " +# Set synchronous mode if it is enabled in CONFIG_DB +SYNC_MODE=$(echo $CFG_VARS | jq -r '.localhost.synchronous_mode') +if [ "$SYNC_MODE" == "enable" ]; then + ORCHAGENT_ARGS+="-s " +fi + # Set mac address ORCHAGENT_ARGS+="-m $MAC_ADDRESS" diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index bf2e8acacb36..7c53c864a79b 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -31,7 +31,12 @@ if [[ -f /usr/share/sonic/virtual_chassis/default_config.json ]]; then fi SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') -sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' $CHASS_CFG --print-data > /etc/sonic/init_cfg.json +if [ -f /etc/sonic/init_cfg.json ]; then + sonic-cfggen -j /etc/sonic/init_cfg.json -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' $CHASS_CFG --print-data > /tmp/init_cfg.json + mv /tmp/init_cfg.json /etc/sonic/init_cfg.json +else + sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' $CHASS_CFG --print-data > /etc/sonic/init_cfg.json +fi if [ -f /etc/sonic/config_db.json ]; then sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --print-data > /tmp/config_db.json diff --git a/rules/config b/rules/config index 8cffedc4e965..b0bbb0b60173 100644 --- a/rules/config +++ b/rules/config @@ -158,3 +158,6 @@ K8s_GCR_IO_PAUSE_VERSION = 3.2 # CA_CERT = # The relative path is build root folder. SONIC_ENABLE_IMAGE_SIGNATURE ?= n + +# ENABLE_SYNCHRONOUS_MODE - enable synchronous mode between orchagent and syncd +ENABLE_SYNCHRONOUS_MODE = n diff --git a/slave.mk b/slave.mk index 36849686647d..f77cec3f1eaa 100644 --- a/slave.mk +++ b/slave.mk @@ -230,6 +230,7 @@ $(info "INCLUDE_SFLOW" : "$(INCLUDE_SFLOW)") $(info "INCLUDE_NAT" : "$(INCLUDE_NAT)") $(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)") $(info "TELEMETRY_WRITABLE" : "$(TELEMETRY_WRITABLE)") +$(info "ENABLE_SYNCHRONOUS_MODE" : "$(ENABLE_SYNCHRONOUS_MODE)") $(info ) include Makefile.cache @@ -247,6 +248,7 @@ endif export kernel_procure_method=$(KERNEL_PROCURE_METHOD) export vs_build_prepare_mem=$(VS_PREPARE_MEM) +export enable_synchronous_mode=$(ENABLE_SYNCHRONOUS_MODE) ############################################################################### ## Local targets @@ -695,6 +697,9 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_whls=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_PYTHON_WHEELS)))\n" | awk '!a[$$0]++')) $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_PACKAGES)))\n" | awk '!a[$$0]++')) j2 $($*.gz_PATH)/Dockerfile.j2 > $($*.gz_PATH)/Dockerfile + if [ -f $($*.gz_PATH)/init_cfg.json.j2 ] ; then + j2 $($*.gz_PATH)/init_cfg.json.j2 > $($*.gz_PATH)/init_cfg.json + fi docker info $(LOG) docker build --squash --no-cache \ --build-arg http_proxy=$(HTTP_PROXY) \ From 834a29cb665b32b231a1819b10f3bac8f8304eb8 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Tue, 25 Aug 2020 18:48:56 +0300 Subject: [PATCH 1070/1427] [enable counters] Enable port buffer drops by default and update MLNX SAI submodule (#5059) * Enable port buffer drops by default * [Mellanox] Update SAI_Implementation Signed-off-by: Mykola Faryma --- dockers/docker-orchagent/enable_counters.py | 1 + platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dockers/docker-orchagent/enable_counters.py b/dockers/docker-orchagent/enable_counters.py index 9ce7a0f8d8b4..5178684c5e16 100755 --- a/dockers/docker-orchagent/enable_counters.py +++ b/dockers/docker-orchagent/enable_counters.py @@ -18,6 +18,7 @@ def enable_counters(): enable_counter_group(db, 'PG_WATERMARK') enable_counter_group(db, 'QUEUE_WATERMARK') enable_counter_group(db, 'BUFFER_POOL_WATERMARK') + enable_counter_group(db, 'PORT_BUFFER_DROP') def get_uptime(): with open('/proc/uptime') as fp: diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 61e28bc2949c..db9336c0bcd6 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 61e28bc2949ce03d9fbf0da818cd7f7348ab209a +Subproject commit db9336c0bcd62caf04156fda4496d6706fa25b32 From 394aa5f75f032862e379fe965e6ce9cf6e988d41 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Tue, 25 Aug 2020 09:33:43 -0700 Subject: [PATCH 1071/1427] Platform monitor changes in daemon_base for multi_asic (#4932) Adding namespace support for db connect API. --- src/sonic-py-common/sonic_py_common/daemon_base.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/daemon_base.py b/src/sonic-py-common/sonic_py_common/daemon_base.py index 6a2c6a22d2aa..97bf3011b6e4 100644 --- a/src/sonic-py-common/sonic_py_common/daemon_base.py +++ b/src/sonic-py-common/sonic_py_common/daemon_base.py @@ -13,13 +13,16 @@ EEPROM_MODULE_NAME = 'eeprom' EEPROM_CLASS_NAME = 'board' +# The empty namespace refers to linux host namespace. +EMPTY_NAMESPACE = '' + # # Helper functions ============================================================= # -def db_connect(db_name): +def db_connect(db_name, namespace=EMPTY_NAMESPACE): from swsscommon import swsscommon - return swsscommon.DBConnector(db_name, REDIS_TIMEOUT_MSECS, True) + return swsscommon.DBConnector(db_name, REDIS_TIMEOUT_MSECS, True, namespace) # # DaemonBase =================================================================== From a38105237caacfa5bcf61db383f875438a1941fe Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Wed, 26 Aug 2020 09:09:43 -0700 Subject: [PATCH 1072/1427] [py-swsssdk] Submodule Update (#5249) Change: c25d492 Merge pull request #83 from tahmed-dev/taahme/add-redis-pipeline-operation 198d143 review comments - part of [configdb] Add Ability to Query/Update Redis Using Pipelines 994851c review comments - part of [configdb] Add Ability to Query/Update Redis Using Pipelines 2d2b7e1 making lgtm happy - part of [configdb] Add Ability to Query/Update Redis Using Pipelines fa9093c [configdb] Add Ability to Query/Update Redis Using Pipelines signed-off-by: Tamer Ahmed --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 2df4f40fcec2..c25d492c4cbb 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 2df4f40fcec2c5ddafe543aec964a6390d2a9a90 +Subproject commit c25d492c4cbb356b1fdd4502f75eda7db9e48aea From a8016a6987e4225ef9f35bae0148f07f4e0f7865 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Wed, 26 Aug 2020 15:05:54 -0700 Subject: [PATCH 1073/1427] [cfggen] Use Redis Pipeline (#5250) This PR enables cfggen to readr/write from Redis DB using pipelines. Pipelines enables batch read/write from/to Redis DB. signed-off-by: Tamer Ahmed --- src/sonic-config-engine/sonic-cfggen | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index ae1b5977d892..6897e383d8c6 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -46,7 +46,7 @@ from sonic_py_common.device_info import get_platform, get_system_mac from sonic_py_common.multi_asic import get_asic_id_from_name, is_multi_asic from config_samples import generate_sample_config from config_samples import get_available_config -from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig +from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig, ConfigDBPipeConnector from redis_bcc import RedisBytecodeCache from collections import OrderedDict from natsort import natsorted @@ -340,9 +340,9 @@ def main(): if args.from_db: if args.namespace is None: - configdb = ConfigDBConnector(use_unix_socket_path=True, **db_kwargs) + configdb = ConfigDBPipeConnector(use_unix_socket_path=True, **db_kwargs) else: - configdb = ConfigDBConnector(use_unix_socket_path=True, namespace=args.namespace, **db_kwargs) + configdb = ConfigDBPipeConnector(use_unix_socket_path=True, namespace=args.namespace, **db_kwargs) configdb.connect() deep_update(data, FormatConverter.db_to_output(configdb.get_config())) @@ -401,9 +401,9 @@ def main(): if args.write_to_db: if args.namespace is None: - configdb = ConfigDBConnector(use_unix_socket_path=True, **db_kwargs) + configdb = ConfigDBPipeConnector(use_unix_socket_path=True, **db_kwargs) else: - configdb = ConfigDBConnector(use_unix_socket_path=True, namespace=args.namespace, **db_kwargs) + configdb = ConfigDBPipeConnector(use_unix_socket_path=True, namespace=args.namespace, **db_kwargs) configdb.connect(False) configdb.mod_config(FormatConverter.output_to_db(data)) From 7d3ec60b1f3b8a79801f6d9d891f78d2220fda5a Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Thu, 27 Aug 2020 06:50:03 -0700 Subject: [PATCH 1074/1427] [hostcfgd] Fix Boolean String Evaluation (#5248) New attribute 'has_timer' introduced to init_cfg.json does not evaluate as Bool, rather it evaluates as string. This PR fixes this issue. Also, this PR fixes an issue when there is system config unit (snmp, telemetry) that has no installation config (WantedBy=, RequiredBy=, Also=, Alias=) settings in the [Install] section. In the latter case, the .service should not be enabled. signed-off-by: Tamer Ahmed --- files/image_config/hostcfgd/hostcfgd | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 29c88eb6456a..acfc3d0c8055 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -1,6 +1,7 @@ #!/usr/bin/python -u # -*- coding: utf-8 -*- +import ast import os import sys import subprocess @@ -41,15 +42,15 @@ def obfuscate(data): return data -def update_feature_state(feature_name, state, has_timer=False): - feature_suffixes = ["service"] + (["timer"] if has_timer else []) +def update_feature_state(feature_name, state, has_timer): + feature_suffixes = ["service"] + (["timer"] if ast.literal_eval(has_timer) else []) if state == "enabled": start_cmds = [] for suffix in feature_suffixes: start_cmds.append("sudo systemctl unmask {}.{}".format(feature_name, suffix)) - start_cmds.append("sudo systemctl enable {}.{}".format(feature_name, suffix)) - # If feature has timer associated with it, start corresponding systemd .timer unit - # otherwise, start corresponding systemd .service unit + # If feature has timer associated with it, start/enable corresponding systemd .timer unit + # otherwise, start/enable corresponding systemd .service unit + start_cmds.append("sudo systemctl enable {}.{}".format(feature_name, feature_suffixes[-1])) start_cmds.append("sudo systemctl start {}.{}".format(feature_name, feature_suffixes[-1])) for cmd in start_cmds: syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) From b31050d60eb5d499468869b252422fc8108e239f Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Thu, 27 Aug 2020 21:53:58 +0300 Subject: [PATCH 1075/1427] [services][mgmt-framework] delay mgmt-framework service on boot (#5226) management framework provides management plane services like rest and CLI which is not needed right after boot, instead by delaying this service we give some more CPU for data plane and control plane services on fast/warm boot. Signed-off-by: Stepan Blyschak --- files/build_templates/init_cfg.json.j2 | 2 +- files/build_templates/mgmt-framework.service.j2 | 2 -- files/build_templates/mgmt-framework.timer | 9 +++++++++ files/build_templates/sonic_debian_extension.j2 | 8 +++++++- 4 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 files/build_templates/mgmt-framework.timer diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 23c0b8eb195f..cee663a2b6e3 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -29,7 +29,7 @@ ("syncd", "enabled", false, "enabled"), ("teamd", "enabled", false, "enabled")] %} {%- if include_iccpd == "y" %}{% do features.append(("iccpd", "disabled", false, "enabled")) %}{% endif %} -{%- if include_mgmt_framework == "y" %}{% do features.append(("mgmt-framework", "enabled", false, "enabled")) %}{% endif %} +{%- if include_mgmt_framework == "y" %}{% do features.append(("mgmt-framework", "enabled", true, "enabled")) %}{% endif %} {%- if include_nat == "y" %}{% do features.append(("nat", "disabled", false, "enabled")) %}{% endif %} {%- if include_restapi == "y" %}{% do features.append(("restapi", "enabled", false, "enabled")) %}{% endif %} {%- if include_sflow == "y" %}{% do features.append(("sflow", "disabled", false, "enabled")) %}{% endif %} diff --git a/files/build_templates/mgmt-framework.service.j2 b/files/build_templates/mgmt-framework.service.j2 index bd4d28a2ee55..883711aa82eb 100644 --- a/files/build_templates/mgmt-framework.service.j2 +++ b/files/build_templates/mgmt-framework.service.j2 @@ -10,5 +10,3 @@ ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/mgmt-framework.timer b/files/build_templates/mgmt-framework.timer new file mode 100644 index 000000000000..62ab8ef1bd58 --- /dev/null +++ b/files/build_templates/mgmt-framework.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays management framework container until SONiC has started + +[Timer] +OnBootSec=3min 30 sec +Unit=mgmt-framework.service + +[Install] +WantedBy=timers.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 9fb517cb09a9..0d1076c2f5f5 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -78,7 +78,7 @@ sudo mkdir -p $FILESYSTEM_ROOT/etc/sonic/ sudo mkdir -p $FILESYSTEM_ROOT/etc/modprobe.d/ sudo mkdir -p $FILESYSTEM_ROOT/var/cache/sonic/ sudo mkdir -p $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ -# This is needed for Stretch and might not be needed for Buster where Linux create this directory by default. +# This is needed for Stretch and might not be needed for Buster where Linux create this directory by default. # Keeping it generic. It should not harm anyways. sudo mkdir -p $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM @@ -542,11 +542,17 @@ sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netn # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "snmp.timer" | sudo tee -a $GENERATED_SERVICE_FILE + {% if include_system_telemetry == 'y' %} sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "telemetry.timer" | sudo tee -a $GENERATED_SERVICE_FILE {% endif %} +{% if include_mgmt_framework == 'y' %} +sudo cp $BUILD_TEMPLATES/mgmt-framework.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +echo "mgmt-framework.timer" | sudo tee -a $GENERATED_SERVICE_FILE +{% endif %} + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-dev sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get clean -y sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get autoremove -y From 4338d8293fe51c3d33daf4020cbb0e7a943ad38b Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 27 Aug 2020 14:14:04 -0700 Subject: [PATCH 1076/1427] Skip vnet-vxlan interfaces from generating networks (#5251) * Skip Vnet interface from generating networks --- dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 13 ++++++++----- dockers/docker-fpm-frr/frr/common/functions.conf.j2 | 12 ++++++++++++ .../data/sonic-cfggen/bgpd.main.conf.j2/all.json | 5 ++++- .../sonic-cfggen/bgpd.main.conf.j2/defaults.json | 5 ++++- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index c216e24a64d3..30a399d0af8b 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -1,4 +1,4 @@ -{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address %} +{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address, get_vnet_interfaces %} ! ! template: bgpd/bgpd.main.conf.j2 ! @@ -14,14 +14,17 @@ ip prefix-list PL_LoopbackV4 permit {{ get_ipv4_loopback_address(LOOPBACK_INTERF ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | replace('/128', '/64') | ip_network }}/64 {% endif %} ! +{% if VLAN_INTERFACE is defined %} +{% set vnet_intfs = get_vnet_interfaces(VLAN_INTERFACE) %} +{% endif %} {% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} -{% if prefix | ipv4 %} +{% if prefix | ipv4 and name not in vnet_intfs %} ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq {{ loop.index * 5 }} permit {{ prefix }} ! {% endif %} {% endfor %} {% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} -{% if prefix | ipv6 %} +{% if prefix | ipv6 and name not in vnet_intfs %} ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq {{ loop.index * 5 }} permit {{ prefix }} ! {% endif %} @@ -78,9 +81,9 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} ! {% block vlan_advertisement %} {% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} -{% if prefix | ipv4 %} +{% if prefix | ipv4 and name not in vnet_intfs %} network {{ prefix }} -{% elif prefix | ipv6 %} +{% elif prefix | ipv6 and name not in vnet_intfs %} address-family ipv6 network {{ prefix }} exit-address-family diff --git a/dockers/docker-fpm-frr/frr/common/functions.conf.j2 b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 index 9857f068fe93..2049e1141429 100644 --- a/dockers/docker-fpm-frr/frr/common/functions.conf.j2 +++ b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 @@ -21,3 +21,15 @@ {% endfor %} {{ L.ip }} {%- endmacro %} + +{% macro get_vnet_interfaces(interfaces) -%} +{% set L = namespace(intfs=[]) %} +{% set vnet_intfs = [] %} +{% for (key, metadata) in interfaces.iteritems() %} +{% if metadata.has_key("vnet_name") %} +{% set vnet_intfs = vnet_intfs.append(key) %} +{% endif %} +{% endfor %} +{% set L.intfs = vnet_intfs %} +{{ L.intfs }} +{%- endmacro %} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json index 36099674ac4e..3d5d07d95f09 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json @@ -11,7 +11,10 @@ }, "VLAN_INTERFACE": { "Vlan10|10.10.10.1/24": {}, - "Vlan10|fc01::1/64": {} + "Vlan10|fc01::1/64": {}, + "Vlan20": {"vnet_name": "Vnet1"}, + "Vlan20|20.20.20.1/24": {}, + "Vlan20|fd01::1/64": {} }, "constants": { "bgp": { diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json index 2db9bd771c84..e841437650ac 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json @@ -11,7 +11,10 @@ }, "VLAN_INTERFACE": { "Vlan10|10.10.10.1/24": {}, - "Vlan10|fc01::1/64": {} + "Vlan10|fc01::1/64": {}, + "Vlan20": {"vnet_name": "Vnet1"}, + "Vlan20|20.20.20.1/24": {}, + "Vlan20|fd01::1/64": {} }, "constants": { "bgp": { From 5a166cc60c7619c17392714dd68b0fe888f48e2c Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Fri, 28 Aug 2020 13:47:44 -0700 Subject: [PATCH 1077/1427] [sonic-py-common] Add function to get hostname (#5265) Added a function to get hostname. It get it from DEVICE_METADATA|localhost: hostname. --- .../sonic_py_common/device_info.py | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index b5aefc397fe8..6e30cb8b94a7 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -29,6 +29,25 @@ BACKEND_ASIC_SUB_ROLE = "BackEnd" +def get_localhost_info(field): + try: + config_db = ConfigDBConnector() + config_db.connect() + + metadata = config_db.get_table('DEVICE_METADATA') + + if 'localhost' in metadata and field in metadata['localhost']: + return metadata['localhost'][field] + except Exception: + pass + + return None + + +def get_hostname(): + return get_localhost_info('hostname') + + def get_machine_info(): """ Retreives data from the machine configuration file @@ -80,18 +99,8 @@ def get_platform(): # container in SONiC, where the /host directory is not mounted. In this # case the value should already be populated in Config DB so we finally # try reading it from there. - try: - config_db = ConfigDBConnector() - config_db.connect() - - metadata = config_db.get_table('DEVICE_METADATA') - - if 'localhost' in metadata and 'platform' in metadata['localhost']: - return metadata['localhost']['platform'] - except Exception: - pass - - return None + + return get_localhost_info('platform') def get_hwsku(): @@ -101,18 +110,8 @@ def get_hwsku(): Returns: A string containing the device's hardware SKU identifier """ - try: - config_db = ConfigDBConnector() - config_db.connect() - - metadata = config_db.get_table('DEVICE_METADATA') - if 'localhost' in metadata and 'hwsku' in metadata['localhost']: - return metadata['localhost']['hwsku'] - except Exception: - pass - - return None + return get_localhost_info('hwsku') def get_platform_and_hwsku(): From 123a5640bd9e538ad07f352159830c1afb9af087 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Sat, 29 Aug 2020 10:25:06 -0700 Subject: [PATCH 1078/1427] Update platform-common submodule (#5261) Updating platform-common submodule with these commits commit 14c6e53ecb861e124e2b45a7b65875ffac1b949e [sff8472.py] Make hex keys all lowercase (#115) Alpha chars in hex-based keys should be lowercase commit b60f46cd1fb0ced1ffbff382e0125517f8c74b9e Sfputil base and helper class changes for multi-ASIC (#100) * Sfputil base and helper class changes for multi-ASIC > adding the logical interface to asic id mapping * Updated based on new sonic-py-common API's. --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 433dd1ae9d3f..14c6e53ecb86 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 433dd1ae9d3f9f45b048fbbe402e8fd2944d85e0 +Subproject commit 14c6e53ecb861e124e2b45a7b65875ffac1b949e From c3dbffa84784caecdf3ccb76db886ac080e4fe99 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Sat, 29 Aug 2020 10:25:46 -0700 Subject: [PATCH 1079/1427] [sonic-platform-daemons] Update submodule (#5262) Update the patform daemons with new commits commit e9628b6b5a4683c7366fc99ee19ce727546fbabb Merge pull request #64 from judyjoseph/multi_asic_ledd_xcvr * platform daemon (Xcvrd, Ledd) changes for multi asic platform * Updates in ledd daemon to use namespaces and get the namespace from selector object. * Updates to xcvrd daemon to use the asic_id in talking to the right DB. * Updated based on new sonic-py-common API's * Invoke initializeGlobalConfig() in the SfpUpdate/DomInfoUpdate processes as well. commit 415b8c457625c514aff0f8ecbdbbb655414d8067 [thermalctld] Optimize the thermal policy loop to make it execute every 60 seconds (#77) commit 3d1f3196fd9c9942134e4926de7d248743e9589d Update FAN_INFO in psud to avoid inconsistant output of show platform psud and show platform fan (#81) --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 80661c7ecee3..e9628b6b5a46 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 80661c7ecee3acf67cbd52ea4341b6ed33544a6f +Subproject commit e9628b6b5a4683c7366fc99ee19ce727546fbabb From 07b9d7f44dcdc74ca9a42755310381d86fde0b74 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 29 Aug 2020 10:29:42 -0700 Subject: [PATCH 1080/1427] [pcie-check] Make pcie-check.sh executable (#5256) The pcie-check.sh script was added in https://github.com/Azure/sonic-buildimage/pull/4771, but was not given executable permission. Therefore, we would see messages like: ``` Aug 26 22:54:05.536248 sonic ERR systemd[664]: pcie-check.service: Failed to execute command: Permission denied Aug 26 22:54:05.536386 sonic ERR systemd[664]: pcie-check.service: Failed at step EXEC spawning /usr/bin/pcie-check.sh: Permission denied Aug 26 22:54:05.536600 sonic WARNING systemd[1]: pcie-check.service: Failed with result 'exit-code'. ``` --- files/image_config/pcie-check/pcie-check.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 files/image_config/pcie-check/pcie-check.sh diff --git a/files/image_config/pcie-check/pcie-check.sh b/files/image_config/pcie-check/pcie-check.sh old mode 100644 new mode 100755 From f973d90c764328860047fd78fb48c3209474b442 Mon Sep 17 00:00:00 2001 From: shi-su <67605788+shi-su@users.noreply.github.com> Date: Sat, 29 Aug 2020 18:03:52 -0700 Subject: [PATCH 1081/1427] [sonic-sairedis] Update submodule (#5243) Signed-off-by: shi-su --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index f0b1e5472f9e..c4a86b3e66e8 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit f0b1e5472f9ecfc1892f6919abaedf563245d9ef +Subproject commit c4a86b3e66e8ce14690a9ed796b879325ca676b2 From ca3e71da0a35da06be90e641636b246efd7a24d2 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Sun, 30 Aug 2020 08:24:29 -0700 Subject: [PATCH 1082/1427] [sonic-py-common] Relocate some functions from sonic-utilities (#5269) * Relocate interface related common functions to py-common * Add unit tests for interface API's. --- .../sonic_py_common/interface.py | 42 +++++++++++++++++++ .../sonic_py_common/multi_asic.py | 12 ++++++ src/sonic-py-common/tests/interface_test.py | 41 ++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 src/sonic-py-common/tests/interface_test.py diff --git a/src/sonic-py-common/sonic_py_common/interface.py b/src/sonic-py-common/sonic_py_common/interface.py index 9136b71f7804..10452c613124 100644 --- a/src/sonic-py-common/sonic_py_common/interface.py +++ b/src/sonic-py-common/sonic_py_common/interface.py @@ -1,3 +1,7 @@ +""" +SONiC interface types and access functions. +""" + """ Dictionary of SONIC interface name prefixes. Each entry in the format "Human readable interface string":"Sonic interface prefix" @@ -12,6 +16,8 @@ "Ethernet-Backplane": "Ethernet-BP" } +VLAN_SUB_INTERFACE_SEPARATOR = '.' + def front_panel_prefix(): """ Retrieves the SONIC front panel interface name prefix. @@ -41,3 +47,39 @@ def loopback_prefix(): Retrieves the SONIC Loopback interface name prefix. """ return SONIC_INTERFACE_PREFIXES["Loopback"] + +def get_interface_table_name(interface_name): + """Get table name by interface_name prefix + """ + if interface_name.startswith(front_panel_prefix()): + if VLAN_SUB_INTERFACE_SEPARATOR in interface_name: + return "VLAN_SUB_INTERFACE" + return "INTERFACE" + elif interface_name.startswith(portchannel_prefix()): + if VLAN_SUB_INTERFACE_SEPARATOR in interface_name: + return "VLAN_SUB_INTERFACE" + return "PORTCHANNEL_INTERFACE" + elif interface_name.startswith(vlan_prefix()): + return "VLAN_INTERFACE" + elif interface_name.startswith(loopback_prefix()): + return "LOOPBACK_INTERFACE" + else: + return "" + +def get_port_table_name(interface_name): + """Get table name by port_name prefix + """ + if interface_name.startswith(front_panel_prefix()): + if VLAN_SUB_INTERFACE_SEPARATOR in interface_name: + return "VLAN_SUB_INTERFACE" + return "PORT" + elif interface_name.startswith(portchannel_prefix()): + if VLAN_SUB_INTERFACE_SEPARATOR in interface_name: + return "VLAN_SUB_INTERFACE" + return "PORTCHANNEL" + elif interface_name.startswith(vlan_prefix()): + return "VLAN_INTERFACE" + elif interface_name.startswith(loopback_prefix()): + return "LOOPBACK_INTERFACE" + else: + return "" diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index 78bc6d72ba90..d5925ea37de2 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -344,3 +344,15 @@ def get_asic_index_from_namespace(namespace): return int(get_asic_id_from_name(namespace)) return 0 + +# Validate whether a given namespace name is valid in the device. +# This API is significant in multi-asic platforms. +def validate_namespace(namespace): + if not is_multi_asic(): + return True + + namespaces = get_all_namespaces() + if namespace in namespaces['front_ns'] + namespaces['back_ns']: + return True + else: + return False diff --git a/src/sonic-py-common/tests/interface_test.py b/src/sonic-py-common/tests/interface_test.py new file mode 100644 index 000000000000..bb9047973381 --- /dev/null +++ b/src/sonic-py-common/tests/interface_test.py @@ -0,0 +1,41 @@ +import os +import sys + +from sonic_py_common import interface + +class TestInterface(object): + @classmethod + def setup_class(cls): + print("SETUP") + + def test_get_interface_table_name(self): + result = interface.get_interface_table_name("Ethernet0") + assert result == "INTERFACE" + result = interface.get_interface_table_name("Ethernet0.100") + assert result == "VLAN_SUB_INTERFACE" + result = interface.get_interface_table_name("PortChannel0") + assert result == "PORTCHANNEL_INTERFACE" + result = interface.get_interface_table_name("PortChannel0.100") + assert result == "VLAN_SUB_INTERFACE" + result = interface.get_interface_table_name("Vlan100") + assert result == "VLAN_INTERFACE" + result = interface.get_interface_table_name("Loopback0") + assert result == "LOOPBACK_INTERFACE" + + def test_get_port_table_name(self): + result = interface.get_port_table_name("Ethernet0") + assert result == "PORT" + result = interface.get_port_table_name("Ethernet0.100") + assert result == "VLAN_SUB_INTERFACE" + result = interface.get_port_table_name("PortChannel0") + assert result == "PORTCHANNEL" + result = interface.get_port_table_name("PortChannel0.100") + assert result == "VLAN_SUB_INTERFACE" + result = interface.get_port_table_name("Vlan100") + assert result == "VLAN_INTERFACE" + result = interface.get_port_table_name("Loopback0") + assert result == "LOOPBACK_INTERFACE" + + @classmethod + def teardown_class(cls): + print("TEARDOWN") From 3d6ef3e79043cfff9259a543f0542518985c86a2 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Mon, 31 Aug 2020 10:43:32 -0700 Subject: [PATCH 1083/1427] Update restapi (#5267) * Add available routes data to heartbeat API * Accept subnet routes via tunnel, skip self loopback nexthop --- src/sonic-restapi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-restapi b/src/sonic-restapi index d821e5a9d85f..71b81892fc51 160000 --- a/src/sonic-restapi +++ b/src/sonic-restapi @@ -1 +1 @@ -Subproject commit d821e5a9d85f346942e694698b8b75b5bddea902 +Subproject commit 71b81892fc5128e9b0bce42f889987888860126a From 8793814d53b020011f74a01f867ceddf69b09f41 Mon Sep 17 00:00:00 2001 From: brandonchuang Date: Tue, 1 Sep 2020 08:09:19 +0800 Subject: [PATCH 1084/1427] [Device] Disabled thermalctld for Accton platforms (#5276) Disable thermalctld on Accton platforms until support is added as to avoid logs flooding Signed-off-by: brandon_chuang --- .../x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as5712_54x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as5812_54t-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as5812_54x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as5835_54t-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as5835_54x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as6712_32x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7116_54x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7212_54x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7312_54x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7326_56x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7512_32x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7712_32x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7716_32x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7726_32x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as7816_64x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_as9716_32d-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_minipack-r0/pmon_daemon_control.json | 5 +++++ 21 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 device/accton/x86_64-accton_minipack-r0/pmon_daemon_control.json diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as5712_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5712_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as5712_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as5712_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as5812_54t-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5812_54t-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as5812_54t-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as5812_54t-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as5812_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5812_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as5812_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as5812_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as5835_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5835_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as5835_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as6712_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as6712_32x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as6712_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as6712_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7116_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7116_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7116_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7212_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7212_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7212_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7212_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7312_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7312_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7312_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7312_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7326_56x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7326_56x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7326_56x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7512_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7512_32x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7512_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7512_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7716_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7716_32x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7716_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7716_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7816_64x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7816_64x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7816_64x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7816_64x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_minipack-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_minipack-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..584a14b9d942 --- /dev/null +++ b/device/accton/x86_64-accton_minipack-r0/pmon_daemon_control.json @@ -0,0 +1,5 @@ +{ + "skip_ledd": true, + "skip_thermalctld": true +} + From 17e78715ae1a0de2d6140bc9b175f4a7738ebf57 Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Mon, 31 Aug 2020 17:35:48 -0700 Subject: [PATCH 1085/1427] [Multi-ASIC]:Update the template to add ipinip entry for Loopback4096 (#5235) Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan The following changes are done. - Multi asic platform have 2 Loopback interfaces, Loopback0 and Loopback4096. IPinIP decap entries need to be added for both of them. Update the ipinip.json.j2 template to add decap entries for Loopback4096. - Add corressponding unit test --- dockers/docker-orchagent/ipinip.json.j2 | 9 ++++++-- .../tests/multi_npu_data/ipinip.json | 23 +++++++++++++++++++ src/sonic-config-engine/tests/test_j2files.py | 10 ++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 src/sonic-config-engine/tests/multi_npu_data/ipinip.json diff --git a/dockers/docker-orchagent/ipinip.json.j2 b/dockers/docker-orchagent/ipinip.json.j2 index 66bec75da7dc..d0eafb2206f1 100644 --- a/dockers/docker-orchagent/ipinip.json.j2 +++ b/dockers/docker-orchagent/ipinip.json.j2 @@ -2,12 +2,17 @@ {% set ipv6_addresses = [] %} {% set ipv4_loopback_addresses = [] %} {% set ipv6_loopback_addresses = [] %} +{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' or DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd'%} +{% set loopback_intf_names = ['Loopback0', 'Loopback4096'] %} +{% else %} +{% set loopback_intf_names = ['Loopback0'] %} +{% endif %} {% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} - {%- if prefix | ipv4 and name == 'Loopback0' %} + {%- if prefix | ipv4 and name in loopback_intf_names %} {%- set ipv4_addresses = ipv4_addresses.append(prefix) %} {%- set ipv4_loopback_addresses = ipv4_loopback_addresses.append(prefix) %} {%- endif %} - {%- if prefix | ipv6 and name == 'Loopback0' %} + {%- if prefix | ipv6 and name in loopback_intf_names %} {%- set ipv6_addresses = ipv6_addresses.append(prefix) %} {%- set ipv6_loopback_addresses = ipv6_loopback_addresses.append(prefix) %} {%- endif %} diff --git a/src/sonic-config-engine/tests/multi_npu_data/ipinip.json b/src/sonic-config-engine/tests/multi_npu_data/ipinip.json new file mode 100644 index 000000000000..0f8396e63b30 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/ipinip.json @@ -0,0 +1,23 @@ +[ + { + "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"10.1.0.32,8.0.0.0,10.0.0.0,10.1.0.1,10.1.0.3", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } + , + { + "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"fc00:1::32,fd00:1::32,fc00::1", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 583d7c55b701..db5c1cf3a91a 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -19,6 +19,8 @@ def setUp(self): self.mlnx_port_config = os.path.join(self.test_dir, 'sample-port-config-mlnx.ini') self.dell6100_t0_minigraph = os.path.join(self.test_dir, 'sample-dell-6100-t0-minigraph.xml') self.arista7050_t0_minigraph = os.path.join(self.test_dir, 'sample-arista-7050-t0-minigraph.xml') + self.multi_asic_minigraph = os.path.join(self.test_dir, 'multi_npu_data', 'sample-minigraph.xml') + self.multi_asic_port_config = os.path.join(self.test_dir, 'multi_npu_data', 'sample_port_config-0.ini') self.output_file = os.path.join(self.test_dir, 'output') def run_script(self, argument): @@ -151,6 +153,14 @@ def test_buffers_dell6100_render_template(self): sample_output_file = os.path.join(self.test_dir, 'sample_output', 'buffers-dell6100.json') assert filecmp.cmp(sample_output_file, self.output_file) + def test_ipinip_multi_asic(self): + ipinip_file = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ipinip.json.j2') + argument = '-m ' + self.multi_asic_minigraph + ' -p ' + self.multi_asic_port_config + ' -t ' + ipinip_file + ' -n asic0 ' + ' > ' + self.output_file + print(argument) + self.run_script(argument) + sample_output_file = os.path.join(self.test_dir, 'multi_npu_data', 'ipinip.json') + assert filecmp.cmp(sample_output_file, self.output_file) + def tearDown(self): try: os.remove(self.output_file) From 426b6aaf5ba0137a9d7fdd70fad542c1f8294b19 Mon Sep 17 00:00:00 2001 From: sdddean <50697155+sdddean@users.noreply.github.com> Date: Wed, 2 Sep 2020 04:07:13 +0800 Subject: [PATCH 1086/1427] [iccpd] Fix the bug of iccp cmd show. (#5214) The cmd "mclagdctl dump state" would goes wrong when there are two or more mclag_groups configured. The field "MCLAG Interface" can not be displayed in some group. Signed-off-by: Sun Dandan --- src/iccpd/src/iccp_cmd_show.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/iccpd/src/iccp_cmd_show.c b/src/iccpd/src/iccp_cmd_show.c index b0a60fb5f49c..18b2e5bded8e 100644 --- a/src/iccpd/src/iccp_cmd_show.c +++ b/src/iccpd/src/iccp_cmd_show.c @@ -99,6 +99,7 @@ int iccp_mclag_config_dump(char * *buf, int *num, int mclag_id) state_info.role = csm->role_type; str_size = MCLAGDCTL_PORT_MEMBER_BUF_LEN; + len = 0; LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) { From 5c73c0197f00a7418880dfbf6c0018f449f1a901 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 1 Sep 2020 13:39:10 -0700 Subject: [PATCH 1087/1427] [docker-sonic-vs] Set PLATFORM and HWSKU env vars in Dockerfile (#5266) sonic-py-common package relies on the `PLATFORM` environment variable to be set at runtime in the SONiC VS container. Exporting the variables in the start.sh script causes the variables to only be available to the shell running start.sh and any subshells it spawns. However, once the script exits, the variable is lost. This is resulting in the failure of tests which are run in the VS container, as they call applications which in turn call sonic-py-common functions which rely on PLATFORM to be set. Setting the environment variables in the Dockerfile allows them to persist through the entire runtime of the container. --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 4 ++++ platform/vs/docker-sonic-vs/start.sh | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index b3a6f1cefa9e..8a764960f19b 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -151,4 +151,8 @@ RUN rm /etc/frr/frr.conf # Create /var/warmboot/teamd folder for teammgrd RUN mkdir -p /var/warmboot/teamd +# Set PLATFORM and HWSKU environment variables +ENV PLATFORM=x86_64-kvm_x86_64-r0 +ENV HWSKU=Force10-S6000 + ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 7c53c864a79b..d7ff9920fb7f 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -1,9 +1,9 @@ #!/bin/bash -e -# generate configuration +# Generate configuration -export PLATFORM=x86_64-kvm_x86_64-r0 -export HWSKU=Force10-S6000 +# NOTE: 'PLATFORM' and 'HWSKU' environment variables are set +# in the Dockerfile so that they persist for the life of the container ln -sf /usr/share/sonic/device/$PLATFORM/$HWSKU /usr/share/sonic/hwsku From 456adc32a9c86ed9b727e71227b3b2bd5b0a85a3 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 1 Sep 2020 13:52:29 -0700 Subject: [PATCH 1088/1427] [docker-sonic-vs] Create /usr/share/sonic/platform symlink (#5268) Copying platform.json file into an empty /usr/share/sonic/platform directory does not mimic an actual device. A more correct approach is to create a /usr/share/sonic/platform symlink which links to the actual platform directory; this is more like what is done inside SONiC containers. Then, we only need to copy the platform.json file into the actual platform directory; the symlink takes care of the alternative path, and also exposes all the other files in the platform directory. --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 1 - platform/vs/docker-sonic-vs/start.sh | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 8a764960f19b..b6dde0b9f86c 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -136,7 +136,6 @@ COPY ["chassis_db.py", "/usr/bin/"] COPY ["platform.json", "/usr/share/sonic/device/x86_64-kvm_x86_64-r0/"] COPY ["hwsku.json", "/usr/share/sonic/device/x86_64-kvm_x86_64-r0/Force10-S6000/"] -COPY ["platform.json", "/usr/share/sonic/platform/"] # Workaround the tcpdump issue RUN mv /usr/sbin/tcpdump /usr/bin/tcpdump diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index d7ff9920fb7f..95c24ae37146 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -5,6 +5,7 @@ # NOTE: 'PLATFORM' and 'HWSKU' environment variables are set # in the Dockerfile so that they persist for the life of the container +ln -sf /usr/share/sonic/device/$PLATFORM /usr/share/sonic/platform ln -sf /usr/share/sonic/device/$PLATFORM/$HWSKU /usr/share/sonic/hwsku pushd /usr/share/sonic/hwsku From fb8f09a116d4d9f2dce23da5e081c5e71813f00e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 1 Sep 2020 13:53:36 -0700 Subject: [PATCH 1089/1427] [radvd] No longer build from source; Install vanilla Debian package once again (#5242) Remove radvd Makefile and patch, change docker-router-advertiser Dockerfile template to simply install the vanilla radvd package using apt-get. - In PR https://github.com/Azure/sonic-buildimage/pull/2795, we started building radvd from source and patching it to prevent it from erroring out when advertising an MTU of 9100 which was greater than the MTU size configured on the bridge interface (1500), which was due to a limitation in the 4.9 Linux kernel. - Master branch is now using Linux kernel 4.19. As of 4.18, the kernel supports setting a bridge MTU to a value > 1500. - PR https://github.com/Azure/sonic-swss/pull/1393 modified vlanmgrd to take advantage of this and now configures the MTU of bridge interfaces in SONiC to the proper size of 9100. Therefore, we no longer need to patch radvd. Since we no longer need to patch radvd, we no longer need to build it from source, so we can save build time by going back to simply installing the vanilla radvd Debian package in the router-advertiser container. --- .../docker-router-advertiser/Dockerfile.j2 | 3 ++ rules/docker-router-advertiser.mk | 1 - rules/radvd.dep | 10 ------ rules/radvd.mk | 17 ---------- src/radvd/.gitignore | 4 --- src/radvd/Makefile | 32 ------------------ ...t-treat-out-of-range-MTU-as-an-error.patch | 33 ------------------- src/radvd/patch/series | 2 -- 8 files changed, 3 insertions(+), 99 deletions(-) delete mode 100644 rules/radvd.dep delete mode 100644 rules/radvd.mk delete mode 100644 src/radvd/.gitignore delete mode 100644 src/radvd/Makefile delete mode 100644 src/radvd/patch/0001-Don-t-treat-out-of-range-MTU-as-an-error.patch delete mode 100644 src/radvd/patch/series diff --git a/dockers/docker-router-advertiser/Dockerfile.j2 b/dockers/docker-router-advertiser/Dockerfile.j2 index 1d5a9acc43ea..38962865567d 100644 --- a/dockers/docker-router-advertiser/Dockerfile.j2 +++ b/dockers/docker-router-advertiser/Dockerfile.j2 @@ -10,6 +10,9 @@ ENV DEBIAN_FRONTEND=noninteractive # Update apt's cache of available packages RUN apt-get update +# Install radvd Debian package +RUN apt-get -y install radvd=1:2.17-2 + {% if docker_router_advertiser_debs.strip() -%} # Copy built Debian packages {{ copy_files("debs/", docker_router_advertiser_debs.split(' '), "/debs/") }} diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk index 11549815e266..3b9f7ae8ba01 100644 --- a/rules/docker-router-advertiser.mk +++ b/rules/docker-router-advertiser.mk @@ -6,7 +6,6 @@ DOCKER_ROUTER_ADVERTISER_DBG = $(DOCKER_ROUTER_ADVERTISER_STEM)-$(DBG_IMAGE_MARK $(DOCKER_ROUTER_ADVERTISER)_PATH = $(DOCKERS_PATH)/$(DOCKER_ROUTER_ADVERTISER_STEM) -$(DOCKER_ROUTER_ADVERTISER)_DEPENDS += $(RADVD) $(DOCKER_ROUTER_ADVERTISER)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_ROUTER_ADVERTISER)_DBG_DEPENDS += $(RADVD_DBG) diff --git a/rules/radvd.dep b/rules/radvd.dep deleted file mode 100644 index 457a74becc77..000000000000 --- a/rules/radvd.dep +++ /dev/null @@ -1,10 +0,0 @@ - -SPATH := $($(RADVD)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/radvd.mk rules/radvd.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(SPATH)) - -$(RADVD)_CACHE_MODE := GIT_CONTENT_SHA -$(RADVD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(RADVD)_DEP_FILES := $(DEP_FILES) - diff --git a/rules/radvd.mk b/rules/radvd.mk deleted file mode 100644 index f0a048280443..000000000000 --- a/rules/radvd.mk +++ /dev/null @@ -1,17 +0,0 @@ -# radvd package - -RADVD_VERSION = 2.17-2 - -export RADVD_VERSION - -RADVD = radvd_$(RADVD_VERSION)_$(CONFIGURED_ARCH).deb -$(RADVD)_SRC_PATH = $(SRC_PATH)/radvd -SONIC_MAKE_DEBS += $(RADVD) - -RADVD_DBG = radvd-dbgsym_$(RADVD_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(RADVD),$(RADVD_DBG))) - -# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} -# are archived into debug one image to facilitate debugging. -# -DBG_SRC_ARCHIVE += radvd diff --git a/src/radvd/.gitignore b/src/radvd/.gitignore deleted file mode 100644 index d19db76ab9a9..000000000000 --- a/src/radvd/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!.gitignore -!Makefile -!patch/ diff --git a/src/radvd/Makefile b/src/radvd/Makefile deleted file mode 100644 index 98e62bc216d4..000000000000 --- a/src/radvd/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -.ONESHELL: -SHELL = /bin/bash -.SHELLFLAGS += -e - -MAIN_TARGET = radvd_$(RADVD_VERSION)_$(CONFIGURED_ARCH).deb -DERIVED_TARGETS = radvd-dbgsym_$(RADVD_VERSION)_$(CONFIGURED_ARCH).deb - -$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : - # Remove any stale files - rm -rf ./radvd - - # Clone radvd repo - git clone https://salsa.debian.org/debian/radvd.git - pushd ./radvd - - # Reset HEAD to the commit of the proper tag - # NOTE: Using "git checkout " here detaches our HEAD, - # which stg doesn't like, so we use this method instead - # NOTE 1: For some reason, tags in the Debian radvd repo are prefixed with "1%" - # NOTE 2: "~" in version string is replaced by "_" in branch name - git reset --hard debian/1\%$(subst ~,_,$(RADVD_VERSION)) - - # Apply patches - stg init - stg import -s ../patch/series - - # Build source and Debian packages - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) - popd - - # Move the newly-built .deb package to the destination directory - mv $(DERIVED_TARGETS) $* $(DEST)/ diff --git a/src/radvd/patch/0001-Don-t-treat-out-of-range-MTU-as-an-error.patch b/src/radvd/patch/0001-Don-t-treat-out-of-range-MTU-as-an-error.patch deleted file mode 100644 index a9f988fee5d7..000000000000 --- a/src/radvd/patch/0001-Don-t-treat-out-of-range-MTU-as-an-error.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 45c15407f11de8b1064b77212727e5234f3ef1e8 Mon Sep 17 00:00:00 2001 -From: Joe LeVeque -Date: Sat, 16 Feb 2019 02:59:10 +0000 -Subject: [PATCH] Don't treat out-of-range MTU as an error - ---- - interface.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/interface.c b/interface.c -index 512f2bd..0dc19f4 100644 ---- a/interface.c -+++ b/interface.c -@@ -200,9 +200,14 @@ int check_iface(struct Interface *iface) - - if ((iface->AdvLinkMTU != 0) && ((iface->AdvLinkMTU < MIN_AdvLinkMTU) || - (iface->sllao.if_maxmtu != -1 && (iface->AdvLinkMTU > iface->sllao.if_maxmtu)))) { -- flog(LOG_ERR, "AdvLinkMTU for %s (%u) must be zero or between %u and %u", iface->props.name, iface->AdvLinkMTU, -+ // FIXME: Temporary workaround for SONiC. Currently, when interfaces are added -+ // or removed from VLANs, the kernel sets the MTU size for the VLAN to the -+ // default value of 1500. Here, we prevent radvd from treating a larger value -+ // in its configuration as an error. Instead of logging an error and setting -+ // res to -1, we simply log a warning and continue on. Once the aforementioned -+ // behavior is addressed, this patch should be removed. -+ flog(LOG_WARNING, "AdvLinkMTU for %s (%u) must be zero or between %u and %u", iface->props.name, iface->AdvLinkMTU, - MIN_AdvLinkMTU, iface->sllao.if_maxmtu); -- res = -1; - } - - if (iface->ra_header_info.AdvReachableTime > MAX_AdvReachableTime) { --- -2.17.1 - diff --git a/src/radvd/patch/series b/src/radvd/patch/series deleted file mode 100644 index 7a12163dc040..000000000000 --- a/src/radvd/patch/series +++ /dev/null @@ -1,2 +0,0 @@ -# This series applies on GIT commit 413616c1b6a05f07f07f3ee6af0cf25a3215fe1a -0001-Don-t-treat-out-of-range-MTU-as-an-error.patch From dd908c2ee2311204b7b313f12d5f7c11fd6a4e30 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 2 Sep 2020 18:09:03 -0700 Subject: [PATCH 1090/1427] [sonic-swsscommon] submodule update with commit's (#5300) [schema] Make schema header support C project (#373) Removed DB specific get api's from Selectable class (#378) With the change as part of #378 caclmgrd need to be updated to use new client side Get API to access namespace. Signed-off-by: Abhishek Dosi --- files/image_config/caclmgrd/caclmgrd | 8 +++++--- src/sonic-swss-common | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 6b1cd6cc49ad..ffeb23ca9d16 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -476,12 +476,14 @@ class ControlPlaneAclManager(object): # Loop on select to see if any event happen on config db of any namespace while True: - (state, c) = sel.select(SELECT_TIMEOUT_MS) + (state, selectableObj) = sel.select(SELECT_TIMEOUT_MS) # Continue if select is timeout or selectable object is not return if state != swsscommon.Select.OBJECT: continue - # Get the corresponding namespace from selectable object - namespace = c.getDbNamespace() + # Get the redisselect object from selectable object + redisSelectObj = swsscommon.CastSelectableToRedisSelectObj(selectableObj) + # Get the corresponding namespace from redisselect db connector object + namespace = redisSelectObj.getDbConnector().getNamespace() # Pop data of both Subscriber Table object of namespace that got config db acl table event for table in config_db_subscriber_table_map[namespace]: table.pop() diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 49a7c9d87e36..200f2b0a2377 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 49a7c9d87e364e2ebad1072ad1eb185ce85ac4de +Subproject commit 200f2b0a23774e64e0a624fc19d220b3db064d28 From fdb9d028e9bb10cce1d1854f7ad19e2e4459bb5e Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Wed, 2 Sep 2020 23:40:22 -0700 Subject: [PATCH 1091/1427] [redis] Add redis Group And Grant Read/Write Access to Members (#5289) sonic-cfggen is now using Unix Domain Socket for Redis DB. The socket is created using root account. Subsequently, services that are started as admin fails to start. This PR creates redis group and add admin user to redis group. It also grants read/write access on redis.sock for redis group members. signed-off-by: Tamer Ahmed --- build_debian.sh | 7 +++++-- files/build_templates/docker_image_ctl.j2 | 12 +++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 346bf969af9b..c0d7a321e4bf 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -242,9 +242,12 @@ sudo cp files/docker/docker.service.conf $_ ## Fix systemd race between docker and containerd sudo sed -i '/After=/s/$/ containerd.service/' $FILESYSTEM_ROOT/lib/systemd/system/docker.service +## Create redis group +sudo LANG=C chroot $FILESYSTEM_ROOT groupadd -f redis + ## Create default user -## Note: user should be in the group with the same name, and also in sudo/docker group -sudo LANG=C chroot $FILESYSTEM_ROOT useradd -G sudo,docker $USERNAME -c "$DEFAULT_USERINFO" -m -s /bin/bash +## Note: user should be in the group with the same name, and also in sudo/docker/redis groups +sudo LANG=C chroot $FILESYSTEM_ROOT useradd -G sudo,docker,redis $USERNAME -c "$DEFAULT_USERINFO" -m -s /bin/bash ## Create password for the default user echo "$USERNAME:$PASSWORD" | sudo LANG=C chroot $FILESYSTEM_ROOT chpasswd diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index e252af17718b..965d927bc5c5 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -131,6 +131,9 @@ function postStartAction() /usr/bin/db_migrator.py -o migrate fi fi + # Add redis UDS to the redis group and give read/write access to the group + REDIS_SOCK="/var/run/redis${DEV}/redis.sock" + chgrp -f redis $REDIS_SOCK && chmod -f 0760 $REDIS_SOCK {%- elif docker_container_name == "swss" %} docker exec swss$DEV rm -f /ready # remove cruft if [[ "$BOOT_TYPE" == "fast" ]] && [[ -d /host/fast-reboot ]]; then @@ -354,13 +357,8 @@ NAMESPACE_PREFIX="asic" if [ "$DEV" ]; then NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace - # While using -n (namespace) argument, sonic-cfggen/sonic-db-cli uses redis UNIX socket - # for accessing redis DB in a namespace. This unix socket has permission restrictions since - # it is created by systemd database.servce started with [User] as [root]. - # sudo is needed here for services which are started by systemd with [User] as [admin] - # and needs to override this unix socket permission restrictions. - SONIC_CFGGEN="sudo sonic-cfggen -n $NET_NS" - SONIC_DB_CLI="sudo sonic-db-cli -n $NET_NS" + SONIC_CFGGEN="sonic-cfggen -n $NET_NS" + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" else NET_NS="" SONIC_CFGGEN="sonic-cfggen" From fe01f0c28541fd52f747d09e4c2d139edab664e4 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Thu, 3 Sep 2020 00:21:25 -0700 Subject: [PATCH 1092/1427] [submodule] Update swsssdk submodule (#5295) Signed-off-by: Danny Allen --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index c25d492c4cbb..91cc6c651e90 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit c25d492c4cbb356b1fdd4502f75eda7db9e48aea +Subproject commit 91cc6c651e903b65b95838dc3b2cd1d2751c63b6 From 47a925cac6e5ce882a039238c0f670f5cb332aab Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Thu, 3 Sep 2020 13:09:57 -0700 Subject: [PATCH 1093/1427] Pass additional parameter "%P" - pid of the process in the initial namespace, which is host. (#5301) This would enable the coredump_compress script to retrieve additional info regarding the crashing process. --- build_debian.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_debian.sh b/build_debian.sh index c0d7a321e4bf..c39a4b28b4b0 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -396,7 +396,7 @@ sudo mkdir -p $FILESYSTEM_ROOT/var/core # Config sysctl sudo augtool --autosave " -set /files/etc/sysctl.conf/kernel.core_pattern '|/usr/bin/coredump-compress %e %t %p' +set /files/etc/sysctl.conf/kernel.core_pattern '|/usr/bin/coredump-compress %e %t %p %P' set /files/etc/sysctl.conf/kernel.softlockup_panic 1 set /files/etc/sysctl.conf/kernel.panic 10 set /files/etc/sysctl.conf/vm.panic_on_oom 2 From f136fd06237d983140d189e92cd06b439df8ea5b Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Fri, 4 Sep 2020 05:57:07 +0530 Subject: [PATCH 1094/1427] [ebtbles] Replace binary config file to text config file for ebtables (#5252) Issue: Binary ebtables config file is CPU arch dependent Fix: Load the text config during firsttime boot and Generate the binary persistent atomic file Signed-off-by: Antony Rheneus --- build_debian.sh | 2 +- files/image_config/ebtables/ebtables.filter | Bin 840 -> 0 bytes files/image_config/ebtables/ebtables.filter.cfg | 11 +++++++++++ files/image_config/platform/rc.local | 10 ++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) delete mode 100644 files/image_config/ebtables/ebtables.filter create mode 100644 files/image_config/ebtables/ebtables.filter.cfg diff --git a/build_debian.sh b/build_debian.sh index c39a4b28b4b0..fa5984187b83 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -486,7 +486,7 @@ fi sudo cp -f files/image_config/ebtables/ebtables.default $FILESYSTEM_ROOT/etc/default/ebtables sudo cp -f files/image_config/ebtables/ebtables.init $FILESYSTEM_ROOT/etc/init.d/ebtables sudo cp -f files/image_config/ebtables/ebtables.service $FILESYSTEM_ROOT/lib/systemd/system/ebtables.service -sudo cp files/image_config/ebtables/ebtables.filter ${FILESYSTEM_ROOT}/etc +sudo cp files/image_config/ebtables/ebtables.filter.cfg ${FILESYSTEM_ROOT}/etc sudo LANG=C chroot $FILESYSTEM_ROOT update-alternatives --set ebtables /usr/sbin/ebtables-legacy sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable ebtables.service diff --git a/files/image_config/ebtables/ebtables.filter b/files/image_config/ebtables/ebtables.filter deleted file mode 100644 index dfe55672769d11ab45ac86336eb0db9bf5050126..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 840 zcmYex%qdANVqo}@t1thio&f{!0Y#XBcmWea%FRD0JYZA9p5>to3=L5Fz!nG}rs_Ws zfb@Yd2so^Q$iwu3#60~1LPJ0dAW%!(0JfhI!iAF{b6^~hy^cXHFfN!j;(>7Of%-u# zn7zUfVL0i7!+aB{{urn{TmzJ03YCX&85<4(86Z1At||bsL3jZW7ndaFr6d-m0GU_; z2UPSQSSJGm%%2==5D9&OOA6S+--H(;?~6m;6e diff --git a/files/image_config/ebtables/ebtables.filter.cfg b/files/image_config/ebtables/ebtables.filter.cfg new file mode 100644 index 000000000000..7a2dc5c8b6ec --- /dev/null +++ b/files/image_config/ebtables/ebtables.filter.cfg @@ -0,0 +1,11 @@ +# SONiC ebtables filter table configuration +# Generated using ebtables-save + +*filter +:INPUT ACCEPT +:FORWARD ACCEPT +:OUTPUT ACCEPT +-A FORWARD -d BGA -j DROP +-A FORWARD -p ARP -j DROP +-A FORWARD -p 802_1Q --vlan-encap ARP -j DROP + diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index bf4e0b631cd9..a58d6197558f 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -123,6 +123,13 @@ program_console_speed() systemctl daemon-reload } +ebtables_config() +{ + # Generate atomic config file and save it persistent + /usr/sbin/ebtables-restore < /etc/ebtables.filter.cfg + /usr/sbin/ebtables -t filter --atomic-file /etc/ebtables.filter --atomic-save +} + #### Begin Main Body #### logger "SONiC version ${SONIC_VERSION} starting up..." @@ -341,6 +348,9 @@ if [ -f $FIRST_BOOT_FILE ]; then # Create dir where following scripts put their output files mkdir -p /var/platform + # Firsttime ebtables configuration + ebtables_config + firsttime_exit fi From b6efb498175be9bfa72786277c8bdc8fe1e5e042 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 4 Sep 2020 07:40:17 -0700 Subject: [PATCH 1095/1427] Update bcm soc property bcm_num_cos from 8 to 10 (#5314) as needed by SAI 3.7 and above. Without this change Warmboot fails from 3.5 to 3.7 as Braodcoam Datastructure gets corrupted after warm-boot. Signed-off-by: Abhishek Dosi --- .../Accton-AS5712-54X/td2-as5712-72x10G.config.bcm | 2 +- .../Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm | 2 +- .../Accton-AS5812-54X/td2-as5812-72x10G.config.bcm | 2 +- .../Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm | 2 +- .../Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm | 2 +- .../Accton-AS7712-32X/th-as7712-32x100G.config.bcm | 2 +- .../Accton-AS7716-32X/th-as7716-32x100G.config.bcm | 2 +- .../Accton-AS7716-32XB/th-as7716-32x100G.config.bcm | 2 +- .../Accton-AS7726-32X/td3-as7726-32x100G.config.bcm | 2 +- .../Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm | 2 +- .../td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm | 2 +- .../Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm | 2 +- .../Arista-7050-QX-32S/td2-a7050-qx32s-32x40G.config.bcm | 2 +- .../Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm | 2 +- .../Arista-7060CX-32S-C32/th-a7060-cx32s-32x100G-t1.config.bcm | 2 +- .../th-a7060-cx32s-8x100G+48x50G.config.bcm | 2 +- .../th-a7060-cx32s-8x100G+24x40G.config.bcm | 2 +- .../Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm | 2 +- .../Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm | 2 +- .../th-a7060-cx32s-8x100G+96x25G.config.bcm | 2 +- .../Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm | 2 +- .../th2-a7260cx3-64-112x50G+8x100G.config.bcm | 2 +- .../Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm | 2 +- .../Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm | 2 +- .../Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm | 2 +- .../Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm | 2 +- .../Force10-S6000/td2-s6000-32x40G.config.bcm | 2 +- .../Force10-S6100/th-s6100-64x40G-t0.config.bcm | 2 +- .../Force10-S6100/th-s6100-64x40G-t1.config.bcm | 2 +- .../Force10-Z9100-C32/th-z9100-32x100G.config.bcm | 2 +- .../Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm | 2 +- .../DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm | 2 +- .../DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm | 2 +- .../DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm | 2 +- .../DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm | 2 +- .../DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm | 2 +- .../DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm | 2 +- .../Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm | 2 +- .../Delta-ag9064/th2-ag9064-64x100G.config.bcm | 2 +- .../Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm | 2 +- .../MiTAC-LY1200-B32H0-C3/th-ly1200-32x100G.config.bcm | 2 +- .../Quanta-IX7-32X/td3-ix7-32x100G.config.bcm | 2 +- .../Quanta-IX8-56X/td3-ix8-48x25G+8x100G.config.bcm | 2 +- .../Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm | 2 +- .../msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm | 2 +- .../msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm | 2 +- .../msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm | 2 +- .../msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm | 2 +- .../msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm | 2 +- .../msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm | 2 +- 50 files changed, 50 insertions(+), 50 deletions(-) diff --git a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/td2-as5712-72x10G.config.bcm b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/td2-as5712-72x10G.config.bcm index 4844616d0382..1d6286ba3bd7 100644 --- a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/td2-as5712-72x10G.config.bcm +++ b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/td2-as5712-72x10G.config.bcm @@ -3,7 +3,7 @@ bcm_stat_flags=0 parity_enable=0 parity_correction=0 -bcm_num_cos=8 +bcm_num_cos=10 l2_mem_entries=32768 l3_mem_entries=16384 l3_alpm_enable=2 diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm index b55558521094..23ccc495bbd6 100644 --- a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm +++ b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm @@ -1,4 +1,4 @@ -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=0 bcm_stat_interval=2000000 bcm_tunnel_term_compatible_mode=1 diff --git a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm index 4844616d0382..1d6286ba3bd7 100644 --- a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm +++ b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm @@ -3,7 +3,7 @@ bcm_stat_flags=0 parity_enable=0 parity_correction=0 -bcm_num_cos=8 +bcm_num_cos=10 l2_mem_entries=32768 l3_mem_entries=16384 l3_alpm_enable=2 diff --git a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm index 1a575bd18a69..63738e788d54 100755 --- a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm +++ b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm @@ -19,7 +19,7 @@ fpem_mem_entries=16384 l2xmsg_mode=1 # Platform specfic -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 ifp_inports_support_enable=1 diff --git a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm index 1a4b7da32df3..83f614bf093d 100755 --- a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm +++ b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm @@ -14,7 +14,7 @@ fpem_mem_entries=16384 l2xmsg_mode=1 # Platform specfic -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 ifp_inports_support_enable=1 diff --git a/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/th-as7712-32x100G.config.bcm b/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/th-as7712-32x100G.config.bcm index 09d97c5e4c63..6ecca8e02a08 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/th-as7712-32x100G.config.bcm +++ b/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/th-as7712-32x100G.config.bcm @@ -14,7 +14,7 @@ pbmp_xport_xe=0x444444451111111144444444422222222 # arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/th-as7716-32x100G.config.bcm b/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/th-as7716-32x100G.config.bcm index 1231bf302be7..1aa9f5d2c16b 100644 --- a/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/th-as7716-32x100G.config.bcm +++ b/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/th-as7716-32x100G.config.bcm @@ -14,7 +14,7 @@ pbmp_xport_xe=0x444444451111111144444444422222222 # arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/th-as7716-32x100G.config.bcm b/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/th-as7716-32x100G.config.bcm index 1231bf302be7..1aa9f5d2c16b 100644 --- a/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/th-as7716-32x100G.config.bcm +++ b/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/th-as7716-32x100G.config.bcm @@ -14,7 +14,7 @@ pbmp_xport_xe=0x444444451111111144444444422222222 # arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm index 49838f4b0bec..8042955fcae7 100755 --- a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm +++ b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm @@ -15,7 +15,7 @@ fpem_mem_entries=16384 l2xmsg_mode=1 # Platform specfic -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 ifp_inports_support_enable=1 diff --git a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm index 0b19742ffe3f..bceebfddaf18 100644 --- a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm +++ b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm @@ -14,7 +14,7 @@ pbmp_oversubscribe=0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff # platform specific setting arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm index 4ce6b2d4a9d6..d3ee2d5e3b0a 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm @@ -37,7 +37,7 @@ stat_if_parity_enable=0 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 lls_num_l2uc=12 max_vp_lags=0 diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm index 76b1af3aba16..7537b36411f7 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm @@ -37,7 +37,7 @@ stat_if_parity_enable=0 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 lls_num_l2uc=12 max_vp_lags=0 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/td2-a7050-qx32s-32x40G.config.bcm b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/td2-a7050-qx32s-32x40G.config.bcm index 3b1a4514409c..31521e4c43ae 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/td2-a7050-qx32s-32x40G.config.bcm +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/td2-a7050-qx32s-32x40G.config.bcm @@ -31,7 +31,7 @@ stat_if_parity_enable=0 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 lls_num_l2uc=12 max_vp_lags=0 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm index e66e2e98416e..09354d6fd8e7 100644 --- a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm @@ -1,6 +1,6 @@ arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 bcm_tunnel_term_compatible_mode=1 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/th-a7060-cx32s-32x100G-t1.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/th-a7060-cx32s-32x100G-t1.config.bcm index 039fd955836c..95a947003fbc 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/th-a7060-cx32s-32x100G-t1.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/th-a7060-cx32s-32x100G-t1.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/th-a7060-cx32s-8x100G+48x50G.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/th-a7060-cx32s-8x100G+48x50G.config.bcm index 326a51ada84f..5c70d324dbb3 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/th-a7060-cx32s-8x100G+48x50G.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/th-a7060-cx32s-8x100G+48x50G.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/th-a7060-cx32s-8x100G+24x40G.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/th-a7060-cx32s-8x100G+24x40G.config.bcm index 7149b5e7ef54..05908a259c48 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/th-a7060-cx32s-8x100G+24x40G.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/th-a7060-cx32s-8x100G+24x40G.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm index 0cb4ae4a474a..c011ad93f4d7 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm index c3218645ac2d..65a7d57b5513 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/th-a7060-cx32s-8x100G+96x25G.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/th-a7060-cx32s-8x100G+96x25G.config.bcm index d3b9a758ba1f..467d428830c9 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/th-a7060-cx32s-8x100G+96x25G.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/th-a7060-cx32s-8x100G+96x25G.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm index 44fb6f7536b4..13fdd280e857 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm @@ -1,7 +1,7 @@ PHY_AN_ALLOW_PLL_CHANGE=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm index 3c2a343bf04d..6e4c266b1db4 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm @@ -1,7 +1,7 @@ PHY_AN_ALLOW_PLL_CHANGE=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm index f5ac5e37ef7e..e26a8131efdb 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm @@ -1,7 +1,7 @@ PHY_AN_ALLOW_PLL_CHANGE=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm index 273dfdbe98bb..d63f589d4fc9 100755 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm index be36c1eb832f..5734e9ee5b1d 100755 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm index 8d8be86636b8..e0ebfd96f00b 100755 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/td2-s6000-32x40G.config.bcm b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/td2-s6000-32x40G.config.bcm +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/td2-s6000-32x40G.config.bcm @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm index adbef9387eda..7fa577052635 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm @@ -2,7 +2,7 @@ l3_alpm_enable=2 pfc_deadlock_seq_control=1 bcm_stat_interval=2000000 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm index f9dc619849d0..f55fb9d3ab51 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm @@ -2,7 +2,7 @@ l3_alpm_enable=2 pfc_deadlock_seq_control=1 bcm_stat_interval=2000000 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm index 39a3695b4cdc..48fa30d78111 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm @@ -3,7 +3,7 @@ l3_alpm_enable=2 pfc_deadlock_seq_control=1 bcm_stat_interval=2000000 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm index 3dd7cc89456d..3130c801a38f 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm @@ -3,7 +3,7 @@ l3_alpm_enable=2 pfc_deadlock_seq_control=1 bcm_stat_interval=2000000 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm index fdd3b3fc076d..1a9917c1f60c 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm @@ -8,7 +8,7 @@ fpem_mem_entries=65536 l2xmsg_mode=1 l3_alpm_enable=2 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm index f4b3addfb516..a80b341e4bd7 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm @@ -8,7 +8,7 @@ fpem_mem_entries=65536 l2xmsg_mode=1 l3_alpm_enable=2 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm index 79ec519f7853..f1abb5fdf286 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm @@ -8,7 +8,7 @@ fpem_mem_entries=65536 l2xmsg_mode=1 l3_alpm_enable=2 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm index 8551d7b5b14d..8117fd108f0c 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm @@ -8,7 +8,7 @@ fpem_mem_entries=65536 l2xmsg_mode=1 l3_alpm_enable=2 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm index c3f472b41294..00e6887b4b49 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm @@ -32,7 +32,7 @@ tdma_intr_enable=1 tdma_timeout_usec.0=5000000 parity_correction.0=1 mmu_lossless.0=0 -bcm_num_cos=8 +bcm_num_cos=10 default_cpu_tx_queue=7 pktdma_poll_mode_channel_bitmap=1 l3_max_ecmp_mode.0=1 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm index 3d204640d5aa..38296d61c1b7 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm @@ -32,7 +32,7 @@ tdma_intr_enable=1 tdma_timeout_usec.0=5000000 parity_correction.0=1 mmu_lossless.0=0 -bcm_num_cos=8 +bcm_num_cos=10 default_cpu_tx_queue=7 pktdma_poll_mode_channel_bitmap=1 l3_max_ecmp_mode.0=1 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm index 4c6ceb075bf4..2cef2f4261a3 100755 --- a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm +++ b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm @@ -9,7 +9,7 @@ l2_mem_entries=32768 l3_mem_entries=16384 fpem_mem_entries=131072 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 ipv6_lpm_128b_enable=0x1 diff --git a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm index eae7278a3ab2..4aba9cc855a2 100644 --- a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm +++ b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm @@ -781,7 +781,7 @@ portmap_8=29:100 portmap_9=33:100 lpm_scaling_enable=0 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_jumbo=9236 ipv6_lpm_128b_enable=1 max_vp_lags=0 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm index bc421a4e5152..4d6e2f988c65 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm @@ -14,7 +14,7 @@ pbmp_oversubscribe=0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff # platform specific setting arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/th-ly1200-32x100G.config.bcm b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/th-ly1200-32x100G.config.bcm index 84b2c572664f..9bf869f16bcf 100644 --- a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/th-ly1200-32x100G.config.bcm +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/th-ly1200-32x100G.config.bcm @@ -1,6 +1,6 @@ ### BMS (start) ## Global settings -bcm_num_cos=8 +bcm_num_cos=10 dport_map_indexed=0 ## Switch settings diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/td3-ix7-32x100G.config.bcm b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/td3-ix7-32x100G.config.bcm index 54abc9ddae7b..aaea0380e50b 100644 --- a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/td3-ix7-32x100G.config.bcm +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/td3-ix7-32x100G.config.bcm @@ -8,7 +8,7 @@ l3_mem_entries=40960 fpem_mem_entries=16384 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/td3-ix8-48x25G+8x100G.config.bcm b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/td3-ix8-48x25G+8x100G.config.bcm index e4c8f8b656e1..407105d0ca0a 100644 --- a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/td3-ix8-48x25G+8x100G.config.bcm +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/td3-ix8-48x25G+8x100G.config.bcm @@ -8,7 +8,7 @@ l3_mem_entries=40960 fpem_mem_entries=16384 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm index e4c8f8b656e1..407105d0ca0a 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm @@ -8,7 +8,7 @@ l3_mem_entries=40960 fpem_mem_entries=16384 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 From 200d49eabb657a8a4cabace0b615816e3cc4daea Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Fri, 4 Sep 2020 08:58:20 -0700 Subject: [PATCH 1096/1427] sonic-platform-daemons submodule update (#5311) [ledd][multi-ASIC] Update to ledd based on sonic-swss-common updates (#87) remove sonic-utilities dependency from pcied (#88) --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index e9628b6b5a46..e4ee8528025f 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit e9628b6b5a4683c7366fc99ee19ce727546fbabb +Subproject commit e4ee8528025fb08e7e330ae66dd77d9f723dbcc5 From eff745fbb12b86085a916bfde08e4b49c16e9e7b Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 4 Sep 2020 09:34:26 -0700 Subject: [PATCH 1097/1427] Fix the issue as reported in (#5315) https://github.com/Azure/sonic-buildimage/issues/5255 Root Cause: Waiting on Restore count != 0 can lead to race condition between orchagent process and swssconfig.sh. Ideally check of Restore count != 0 is not needed as the State DB cannot be flushed as if it was flushed then Warm Restart or swss-restart should not be true also. --- dockers/docker-orchagent/swssconfig.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index 2185b00805a1..276132a7ef29 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -49,11 +49,7 @@ HWSKU=${HWSKU:-`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['hwsku']"`} SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` SWSS_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|swss" enable` if [[ "$SYSTEM_WARM_START" == "true" ]] || [[ "$SWSS_WARM_START" == "true" ]]; then - # We have to make sure db data has not been flushed. - RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` - if [[ -n "$RESTORE_COUNT" ]] && [[ "$RESTORE_COUNT" != "0" ]]; then - exit 0 - fi + exit 0 fi SWSSCONFIG_ARGS="00-copp.config.json ipinip.json ports.json switch.json " From 679d8df36f93af397dbe03fb6ddb2b9f24eef898 Mon Sep 17 00:00:00 2001 From: vdahiya12 <67608553+vdahiya12@users.noreply.github.com> Date: Fri, 4 Sep 2020 10:19:12 -0700 Subject: [PATCH 1098/1427] [sonic-utilities][sonic-py-common] Move logic to get port config file path to sonic-py-common and update sonic-utilities to comply (#5264) * [sonic-utilities]update submodule with fix This PR addresses fixes in sonic-py-common to imitate the behavior inside sonic-cfggen. Essentially this is a fix for accessing the port-config file. First check if there is a platform.json file for config generation and then for legacy port_config.ini. Also updating the sub-module sonic-utilities. Fix pfcwd stats crash with invalid queue name (#1077) [show][bgp]Display the Total number of neighbors in the show ip bgp(v6) summary. (#1079) [config] Update SONiC Environment Vars When Loading Minigraph (#1073) Multi asic platform changes for interface, portchannel commands (#878) Update Command-Reference.md (#1075) [filter-fdb] Fix Filter FDB With IPv6 Present in Config DB (#1059) [config] Remove _get_breakout_cfg_file_name helper function (#1069) [SHOW][BGP] support show ip(v6) bgp summary for multi asic platform (#1064) [fanshow] Display other fan status, such as Updating (#1014) Add ip_prefix len based on proxy_arp status (#1046) Enable the platform specific ssd firmware upgrade during reboot (#954) [show][cli[show interface portchannel support for Multi ASIC (#1005) support show interface commands for multi ASIC platforms (#1006) Signed-off-by: vaibhav-dahiya --- src/sonic-config-engine/portconfig.py | 32 +----- src/sonic-config-engine/sonic-cfggen | 14 +-- .../sonic_py_common/device_info.py | 100 ++++++++++++++---- src/sonic-utilities | 2 +- 4 files changed, 91 insertions(+), 57 deletions(-) diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py index 714ddd37f5f9..df1decece763 100644 --- a/src/sonic-config-engine/portconfig.py +++ b/src/sonic-config-engine/portconfig.py @@ -7,6 +7,7 @@ import re from collections import OrderedDict from swsssdk import ConfigDBConnector + from sonic_py_common import device_info except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -64,33 +65,6 @@ def db_connect_configdb(): config_db = None return config_db -def get_port_config_file_name(hwsku=None, platform=None, asic=None): - - # check 'platform.json' file presence - port_config_candidates_Json = [] - port_config_candidates_Json.append(os.path.join(PLATFORM_ROOT_PATH_DOCKER, PLATFORM_JSON)) - if platform: - port_config_candidates_Json.append(os.path.join(PLATFORM_ROOT_PATH, platform, PLATFORM_JSON)) - - # check 'portconfig.ini' file presence - port_config_candidates = [] - port_config_candidates.append(os.path.join(HWSKU_ROOT_PATH, PORT_CONFIG_INI)) - if hwsku: - if platform: - if asic: - port_config_candidates.append(os.path.join(PLATFORM_ROOT_PATH, platform, hwsku, asic, PORT_CONFIG_INI)) - port_config_candidates.append(os.path.join(PLATFORM_ROOT_PATH, platform, hwsku, PORT_CONFIG_INI)) - port_config_candidates.append(os.path.join(PLATFORM_ROOT_PATH_DOCKER, hwsku, PORT_CONFIG_INI)) - port_config_candidates.append(os.path.join(SONIC_ROOT_PATH, hwsku, PORT_CONFIG_INI)) - - elif platform and not hwsku: - port_config_candidates.append(os.path.join(PLATFORM_ROOT_PATH, platform, PORT_CONFIG_INI)) - - for candidate in port_config_candidates_Json + port_config_candidates: - if os.path.isfile(candidate): - return candidate - return None - def get_hwsku_file_name(hwsku=None, platform=None): hwsku_candidates_Json = [] hwsku_candidates_Json.append(os.path.join(HWSKU_ROOT_PATH, HWSKU_JSON)) @@ -119,7 +93,7 @@ def get_port_config(hwsku=None, platform=None, port_config_file=None, hwsku_conf return (ports, port_alias_map, port_alias_asic_map) if not port_config_file: - port_config_file = get_port_config_file_name(hwsku, platform, asic) + port_config_file = device_info.get_path_to_port_config_file(hwsku, asic) if not port_config_file: return ({}, {}, {}) @@ -289,7 +263,7 @@ def parse_platform_json_file(hwsku_json_file, platform_json_file): def get_breakout_mode(hwsku=None, platform=None, port_config_file=None): if not port_config_file: - port_config_file = get_port_config_file_name(hwsku, platform) + port_config_file = device_info.get_path_to_port_config_file(hwsku) if not port_config_file: return None if port_config_file.endswith('.json'): diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 6897e383d8c6..3e4e661f6adc 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -41,9 +41,9 @@ from minigraph import minigraph_encoder from minigraph import parse_xml from minigraph import parse_device_desc_xml from minigraph import parse_asic_sub_role -from portconfig import get_port_config, get_port_config_file_name, get_breakout_mode -from sonic_py_common.device_info import get_platform, get_system_mac +from portconfig import get_port_config, get_breakout_mode from sonic_py_common.multi_asic import get_asic_id_from_name, is_multi_asic +from sonic_py_common import device_info from config_samples import generate_sample_config from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig, ConfigDBPipeConnector @@ -277,7 +277,7 @@ def main(): group.add_argument("-K", "--key", help="Lookup for a specific key") args = parser.parse_args() - platform = get_platform() + platform = device_info.get_platform() db_kwargs = {} if args.redis_unix_sock_file != None: @@ -301,7 +301,7 @@ def main(): }}} deep_update(data, hardware_data) if args.port_config is None: - args.port_config = get_port_config_file_name(hwsku, platform) + args.port_config = device_info.get_path_to_port_config_file(hwsku) (ports, _, _) = get_port_config(hwsku, platform, args.port_config, asic_id) if not ports: print('Failed to get port config', file=sys.stderr) @@ -356,11 +356,11 @@ def main(): asic_role = parse_asic_sub_role(args.minigraph, asic_name) if asic_role is not None and asic_role.lower() == "backend": - mac = get_system_mac(namespace=asic_name) + mac = device_info.get_system_mac(namespace=asic_name) else: - mac = get_system_mac() + mac = device_info.get_system_mac() else: - mac = get_system_mac() + mac = device_info.get_system_mac() hardware_data = {'DEVICE_METADATA': {'localhost': { 'platform': platform, diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index 6e30cb8b94a7..f6b25de55ab5 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -153,18 +153,15 @@ def get_asic_conf_file_path(): return None -def get_paths_to_platform_and_hwsku_dirs(): +def get_path_to_platform_dir(): """ - Retreives the paths to the device's platform and hardware SKU data - directories + Retreives the paths to the device's platform directory Returns: - A tuple of two strings, the first containing the path to the platform - directory of the device, the second containing the path to the hardware - SKU directory of the device + A string containing the path to the platform directory of the device """ - # Get platform and hwsku - (platform, hwsku) = get_platform_and_hwsku() + # Get platform + platform = get_platform() # Determine whether we're running in a container or on the host platform_path_host = os.path.join(HOST_DEVICE_PATH, platform) @@ -176,31 +173,94 @@ def get_paths_to_platform_and_hwsku_dirs(): else: raise OSError("Failed to locate platform directory") + return platform_path + +def get_path_to_hwsku_dir(): + """ + Retreives the path to the device's hardware SKU data directory + + Returns: + A string, containing the path to the hardware SKU directory of the device + """ + + # Get Platform path first + platform_path = get_path_to_platform_dir() + + # Get hwsku + hwsku = get_hwsku() + hwsku_path = os.path.join(platform_path, hwsku) - return (platform_path, hwsku_path) + return hwsku_path +def get_paths_to_platform_and_hwsku_dirs(): + """ + Retreives the paths to the device's platform and hardware SKU data + directories -def get_path_to_port_config_file(): + Returns: + A tuple of two strings, the first containing the path to the platform + directory of the device, the second containing the path to the hardware + SKU directory of the device + """ + + # Get Platform path first + platform_path = get_path_to_platform_dir() + + # Get hwsku + hwsku = get_hwsku() + + hwsku_path = os.path.join(platform_path, hwsku) + + return (platform_path, hwsku_path) + +def get_path_to_port_config_file(hwsku=None, asic=None): """ Retrieves the path to the device's port configuration file + Args: + hwsku: a string, it is allowed to be passed in args because when loading the + initial configuration on the device, the HwSKU is not yet present in ConfigDB. + asic: a string , asic argument should be passed on multi-ASIC devices only, + it should be omitted on single-ASIC platforms. + Returns: A string containing the path the the device's port configuration file """ - # Get platform and hwsku path - (platform_path, hwsku_path) = get_paths_to_platform_and_hwsku_dirs() - # First check for the presence of the new 'platform.json' file - port_config_file_path = os.path.join(platform_path, PLATFORM_JSON_FILE) - if not os.path.isfile(port_config_file_path): - # platform.json doesn't exist. Try loading the legacy 'port_config.ini' file - port_config_file_path = os.path.join(hwsku_path, PORT_CONFIG_FILE) - if not os.path.isfile(port_config_file_path): - raise OSError("Failed to detect port config file: {}".format(port_config_file_path)) + """ + This platform check is performed to make sure we return a None + in case of unit-tests within sonic-cfggen where platform is not expected to be + present because tests are not run on actual Hardware/Container. + TODO: refactor sonic-cfggen such that we can remove this check + """ + + platform = get_platform() + if not platform: + return None + + if hwsku: + platform_path = get_path_to_platform_dir() + hwsku_path = os.path.join(platform_path, hwsku) + else: + (platform_path, hwsku_path) = get_paths_to_platform_and_hwsku_dirs() - return port_config_file_path + port_config_candidates = [] + # Check for 'platform.json' file presence first + port_config_candidates.append(os.path.join(platform_path, PLATFORM_JSON_FILE)) + + # Check for 'port_config.ini' file presence in a few locations + if asic: + port_config_candidates.append(os.path.join(hwsku_path, asic, PORT_CONFIG_FILE)) + else: + port_config_candidates.append(os.path.join(hwsku_path, PORT_CONFIG_FILE)) + + for candidate in port_config_candidates: + if os.path.isfile(candidate): + return candidate + + return None def get_sonic_version_info(): if not os.path.isfile(SONIC_VERSION_YAML_PATH): diff --git a/src/sonic-utilities b/src/sonic-utilities index 17fb3781b2cb..58c29616f510 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 17fb3781b2cb7dfb845faa9f16bc17ccd0069649 +Subproject commit 58c29616f510ebd94122db4490523174e1256943 From 1558c04fa83992e127b364a81e9820ea9aa1dbc1 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Sun, 6 Sep 2020 08:16:20 -0700 Subject: [PATCH 1099/1427] Update sonic-swss submodule (#5322) 65f63c1 Sflow fixes during DEL processing (#1427) e54948a [teamsyncd][teammgrd] Graceful exit after receiving SIGTERM (#1407) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index c4949a20a27f..65f63c1647f5 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit c4949a20a27fcbbe7bbf17cc6fd0a95304584fcb +Subproject commit 65f63c1647f59b75b3d06b1cb293efbbc5472012 From 8d285b46762671bae49fa04bb6c5e63fb3673605 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Mon, 7 Sep 2020 00:20:53 +0800 Subject: [PATCH 1100/1427] [Mellanox] Update SDK 4.4.1622, FW xx.2008.1622 (#5302) --- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 83ae59308ed8..b5da6b872b9d 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2008.1310 +MLNX_SPC_FW_VERSION = 13.2008.1622 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2008.1310 +MLNX_SPC2_FW_VERSION = 29.2008.1622 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2008.1310 +MLNX_SPC3_FW_VERSION = 30.2008.1622 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index efac7c95806f..d5f6db1ceaef 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit efac7c95806fa6092c7995ca2605b3778f8e1dce +Subproject commit d5f6db1ceaef84bce4dd7b2c3d4876037ef1209f diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 0abce26527b3..f40147b048d0 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,6 +1,6 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ MLNX_SDK_PKG_BASE_PATH = $(MLNX_SDK_BASE_PATH)/$(BLDENV)/ -MLNX_SDK_VERSION = 4.4.1306 +MLNX_SDK_VERSION = 4.4.1622 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 0b6fd707679c5ab1947553b62cacf3d8cd2c8aa5 Mon Sep 17 00:00:00 2001 From: Wei Bai Date: Tue, 8 Sep 2020 11:57:21 -0700 Subject: [PATCH 1101/1427] Update PG profiles for Arista 7050 (#5324) * Update pg_profile_lookup.ini --- .../Arista-7050-QX32/pg_profile_lookup.ini | 18 +++++++++--------- .../Arista-7050-QX-32S/pg_profile_lookup.ini | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/pg_profile_lookup.ini b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/pg_profile_lookup.ini index 0588079e6840..d8190e4893de 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/pg_profile_lookup.ini @@ -1,11 +1,11 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 40000 5m 56368 18432 55120 -3 2496 - 50000 5m 56368 18432 55120 -3 2496 - 100000 5m 56368 18432 55120 -3 2496 - 40000 40m 56368 18432 55120 -3 2496 - 50000 40m 56368 18432 55120 -3 2496 - 100000 40m 56368 18432 55120 -3 2496 - 40000 300m 56368 18432 55120 -3 2496 - 50000 300m 56368 18432 55120 -3 2496 - 100000 300m 56368 18432 55120 -3 2496 + 40000 5m 46384 18432 45136 -3 2496 + 50000 5m 46592 18432 45344 -3 2496 + 100000 5m 48464 18432 47216 -3 2496 + 40000 40m 48464 18432 47216 -3 2496 + 50000 40m 49296 18432 48048 -3 2496 + 100000 40m 53872 18432 52624 -3 2496 + 40000 300m 64064 18432 62816 -3 2496 + 50000 300m 68848 18432 67600 -3 2496 + 100000 300m 92976 18432 91728 -3 2496 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/pg_profile_lookup.ini b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/pg_profile_lookup.ini index 0588079e6840..d8190e4893de 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/pg_profile_lookup.ini @@ -1,11 +1,11 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 40000 5m 56368 18432 55120 -3 2496 - 50000 5m 56368 18432 55120 -3 2496 - 100000 5m 56368 18432 55120 -3 2496 - 40000 40m 56368 18432 55120 -3 2496 - 50000 40m 56368 18432 55120 -3 2496 - 100000 40m 56368 18432 55120 -3 2496 - 40000 300m 56368 18432 55120 -3 2496 - 50000 300m 56368 18432 55120 -3 2496 - 100000 300m 56368 18432 55120 -3 2496 + 40000 5m 46384 18432 45136 -3 2496 + 50000 5m 46592 18432 45344 -3 2496 + 100000 5m 48464 18432 47216 -3 2496 + 40000 40m 48464 18432 47216 -3 2496 + 50000 40m 49296 18432 48048 -3 2496 + 100000 40m 53872 18432 52624 -3 2496 + 40000 300m 64064 18432 62816 -3 2496 + 50000 300m 68848 18432 67600 -3 2496 + 100000 300m 92976 18432 91728 -3 2496 From 01fb32fa087ba7fead04a98b853ccba574beb287 Mon Sep 17 00:00:00 2001 From: Blueve <672454911@qq.com> Date: Wed, 9 Sep 2020 03:29:02 +0800 Subject: [PATCH 1102/1427] [conf] append nos-config-part for s6100 (#5234) * [conf] append nos-config-part for s6100 * modify rc.local Signed-off-by: Guohan Lu * Update rc.local Co-authored-by: Blueve Co-authored-by: Guohan Lu Co-authored-by: Ying Xie --- .../x86_64-dell_s6100_c2538-r0/installer.conf | 2 +- files/image_config/platform/rc.local | 124 ++++++++++-------- 2 files changed, 69 insertions(+), 57 deletions(-) diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/installer.conf b/device/dell/x86_64-dell_s6100_c2538-r0/installer.conf index 0a9a3a639eb2..0932d0637760 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/installer.conf +++ b/device/dell/x86_64-dell_s6100_c2538-r0/installer.conf @@ -1,3 +1,3 @@ CONSOLE_PORT=0x2f8 CONSOLE_DEV=1 -ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="module_blacklist=gpio_ich" +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="module_blacklist=gpio_ich nos-config-part=/dev/sda12" diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index a58d6197558f..2e242559094c 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -61,8 +61,8 @@ update_mgmt_interface_macaddr() { fi # Get the ethtool magic and offset for changing the mac address in the EEPROM - ethtool_magic=$(grep "ethtool_magic" $mgmt_config | awk -F'=' '{print $2}') - ethtool_offset=$(grep "ethtool_offset" $mgmt_config | awk -F'=' '{print $2}') + ethtool_magic=$(grep "ethtool_magic" $mgmt_config | awk -F'=' '{print $2}') + ethtool_offset=$(grep "ethtool_offset" $mgmt_config | awk -F'=' '{print $2}') if [ -z "$ethtool_magic" ] || [ -z "$ethtool_offset" ]; then log_migration "Unable to retrieve ethtool params ($ethtool_magic,$ethtool_offset)" return @@ -92,6 +92,69 @@ update_mgmt_interface_macaddr() { ethtool -e eth0 offset $ethtool_offset length 6 >> /host/migration/migration.log } +migrate_nos_configuration() +{ + rm -rf /host/migration + mkdir -p /host/migration + + # Extract the previous NOS's partition that contains the migration artifacts + set -- $(cat /proc/cmdline) + for x in "$@"; do + case "$x" in + nos-config-part=*) + nos_dev="${x#nos-config-part=}" + ;; + SONIC_BOOT_TYPE=fast*) + sonic_fast_reboot=true + ;; + esac + done + + if [ -n "$nos_dev" ]; then + # remove nos-config-part from cmdline + sed -r -i.bak "s/nos-config-part=[^[:space:]]+//" /host/grub/grub.cfg + + # Mount the previous NOS's partition + NOS_DIR=/mnt/nos_migration + MG_GZFILE=$NOS_DIR/minigraph.xml.gz.base64.txt + MG_FILE=$NOS_DIR/minigraph.xml + ACL_GZFILE=$NOS_DIR/acl.json.gz.base64.txt + ACL_FILE=$NOS_DIR/acl.json + SNMP_FILE=$NOS_DIR/snmp.yml + mkdir -p $NOS_DIR + + mount $nos_dev $NOS_DIR + if [ $? != 0 ]; then + log_migration "ERROR: cannot mount $nos_dev" + else + + # decode & unzip minigraph.xml.gz.base64.txt + [ -f $MG_GZFILE ] && /usr/bin/base64 -d $MG_GZFILE | /bin/gunzip > $MG_FILE + [ -f $ACL_GZFILE ] && /usr/bin/base64 -d $ACL_GZFILE | /bin/gunzip > $ACL_FILE + + # Copy relevant files + nos_migration_import $NOS_DIR/mgmt_interface.cfg /host/migration + nos_migration_import $MG_FILE /host/migration + nos_migration_import $ACL_FILE /host/migration + nos_migration_import $SNMP_FILE /host/migration + + if [ "$sonic_fast_reboot" == true ]; then + mkdir -p /host/fast-reboot + nos_migration_import $NOS_DIR/arp.json /host/fast-reboot + nos_migration_import $NOS_DIR/fdb.json /host/fast-reboot + nos_migration_import $NOS_DIR/default_routes.json /host/fast-reboot + fi + + umount $NOS_DIR + rmdir $NOS_DIR + fi + + [ -f /host/migration/mgmt_interface.cfg ] && update_mgmt_interface_macaddr /host/migration/mgmt_interface.cfg + + migration="TRUE" + fi +} + firsttime_exit() { rm -rf $FIRST_BOOT_FILE exit 0 @@ -137,13 +200,11 @@ logger "SONiC version ${SONIC_VERSION} starting up..." # If the machine.conf is absent, it indicates that the unit booted # into SONiC from another NOS. Extract the machine.conf from ONIE. if [ ! -e /host/machine.conf ]; then - mkdir -p /host/migration - onie_dev=$(blkid | grep ONIE-BOOT | head -n 1 | awk '{print $1}' | sed -e 's/:.*$//') mkdir -p /mnt/onie-boot mount $onie_dev /mnt/onie-boot onie_grub_cfg=/mnt/onie-boot/onie/grub/grub-machine.cfg - + if [ ! -e $onie_grub_cfg ]; then log_migration "$onie_grub_cfg not found" else @@ -154,60 +215,11 @@ if [ ! -e /host/machine.conf ]; then done fi - # Extract the previous NOS's partition that contains the migration artifacts - set -- $(cat /proc/cmdline) - for x in "$@"; do - case "$x" in - nos-config-part=*) - nos_val="${x#nos-config-part=}" - ;; - esac - done - - if [ -n "$nos_val" ]; then - nos_dev=$(findfs $nos_val) - if [ $? != 0 ]; then - log_migration "ERROR: nos_dev not found. Check grub parameters" - fi - else - log_migration "ERROR: nos_val not found. Check grub parameters" - fi - - if [ -n "$nos_dev" ]; then - # Mount the previous NOS's partition - NOS_DIR=/mnt/nos_migration - MG_GZFILE=$NOS_DIR/minigraph.xml.gz.base64.txt - MG_FILE=$NOS_DIR/minigraph.xml - ACL_GZFILE=$NOS_DIR/acl.json.gz.base64.txt - ACL_FILE=$NOS_DIR/acl.json - SNMP_FILE=$NOS_DIR/snmp.yml - mkdir -p $NOS_DIR - mount $nos_dev $NOS_DIR - mkdir -p /host/fast-reboot - - # decode & unzip minigraph.xml.gz.base64.txt - [ -f $MG_GZFILE ] && /usr/bin/base64 -d $MG_GZFILE | /bin/gunzip > $MG_FILE - [ -f $ACL_GZFILE ] && /usr/bin/base64 -d $ACL_GZFILE | /bin/gunzip > $ACL_FILE - - # Copy relevant files - nos_migration_import $NOS_DIR/mgmt_interface.cfg /host/migration - nos_migration_import $MG_FILE /host/migration - nos_migration_import $ACL_FILE /host/migration - nos_migration_import $SNMP_FILE /host/migration - nos_migration_import $NOS_DIR/arp.json /host/fast-reboot - nos_migration_import $NOS_DIR/fdb.json /host/fast-reboot - nos_migration_import $NOS_DIR/default_routes.json /host/fast-reboot - - umount $NOS_DIR - rmdir $NOS_DIR - fi - - update_mgmt_interface_macaddr /host/migration/mgmt_interface.cfg - - migration="TRUE" umount /mnt/onie-boot fi +migrate_nos_configuration + . /host/machine.conf program_console_speed From d4fc8e5b22bc465260190a604b74726e31dcc10f Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Tue, 8 Sep 2020 19:30:14 -0700 Subject: [PATCH 1103/1427] [redis] Use redis-server and redis-tools in blob storage to prevent upstream link broken (#5340) * [redis] Use redis-server and redis-tools in blob storage to prevent upstream link broken * Use curl instead of wget * Explicitly install dependencies --- dockers/docker-base-buster/Dockerfile.j2 | 14 ++++++++++++-- dockers/docker-database/Dockerfile.j2 | 5 ++++- platform/vs/docker-sonic-vs/Dockerfile.j2 | 7 ++++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index 98d5fca5e8da..6f848b1f7177 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -40,6 +40,7 @@ COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] # pre-install fundamental packages RUN apt-get update && \ apt-get -y install \ + curl \ less \ perl \ procps \ @@ -52,8 +53,12 @@ RUN apt-get update && \ # Install dependencies of supervisor python-pkg-resources \ python-meld3 \ -# Install redis-tools - redis-tools=5:6.0.6-1~bpo10+1 \ +# Install dependencies of redis-tools + libatomic1 \ + libjemalloc2 \ + liblua5.1-0 \ + lua-bitop \ + lua-cjson \ # common dependencies libpython2.7 \ libdaemon0 \ @@ -68,6 +73,11 @@ RUN apt-get update && \ # for processing/handling json files in bash environment jq +# Install redis-tools +RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f -y +RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb + # For templating RUN pip install j2cli diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index f3a2669e7af1..fcfb3b620c25 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -11,7 +11,10 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update # install redis-server -RUN apt-get install -y redis-server=5:6.0.6-1~bpo10+1 +RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" +RUN curl -o redis-server_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=2Ketg7BmkZEaTxR%2FgvAFVmhjn7ywdmkc7l2T2rsL57o%3D&se=2030-09-06T19%3A45%3A20Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb {% if docker_database_debs.strip() -%} # Copy locally-built Debian package dependencies diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index b6dde0b9f86c..3b1b15bf7c52 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -13,7 +13,6 @@ RUN echo "deb http://packages.microsoft.com/repos/sonic-dev/ jessie main" >> /et RUN apt-get update RUN apt-get install -y net-tools \ - redis-server=5:6.0.6-1~bpo10+1 \ arping \ ndisc6 \ ethtool \ @@ -49,6 +48,12 @@ RUN apt-get install -y net-tools \ python3-pip \ jq +# install redis-server +RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" +RUN curl -o redis-server_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=2Ketg7BmkZEaTxR%2FgvAFVmhjn7ywdmkc7l2T2rsL57o%3D&se=2030-09-06T19%3A45%3A20Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb + RUN pip install setuptools RUN pip3 install setuptools RUN pip install py2_ipaddress From 5b3b4804adcffaa43012596acf6effe5a31f0256 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 8 Sep 2020 23:36:38 -0700 Subject: [PATCH 1104/1427] [dockers][supervisor] Increase event buffer size for dependent-startup (#5247) When stopping the swss, pmon or bgp containers, log messages like the following can be seen: ``` Aug 23 22:50:43.789760 sonic-dut INFO swss#supervisord 2020-08-23 22:50:10,061 ERRO pool dependent-startup event buffer overflowed, discarding event 34 Aug 23 22:50:43.789760 sonic-dut INFO swss#supervisord 2020-08-23 22:50:10,063 ERRO pool dependent-startup event buffer overflowed, discarding event 35 Aug 23 22:50:43.789760 sonic-dut INFO swss#supervisord 2020-08-23 22:50:10,064 ERRO pool dependent-startup event buffer overflowed, discarding event 36 Aug 23 22:50:43.789760 sonic-dut INFO swss#supervisord 2020-08-23 22:50:10,066 ERRO pool dependent-startup event buffer overflowed, discarding event 37 ``` This is due to the number of programs in the container managed by supervisor, all generating events at the same time. The default event queue buffer size in supervisor is 10. This patch increases that value in all containers in order to eliminate these errors. As more programs are added to the containers, we may need to further adjust these values. I increased all buffer sizes to 25 except for containers with more programs or templated supervisor.conf files which allow for a variable number of programs. In these cases I increased the buffer size to 50. One final exception is the swss container, where the buffer fills up to ~50, so I increased this buffer to 100. Resolves https://github.com/Azure/sonic-buildimage/issues/5241 --- dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 | 1 + dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 | 1 + dockers/docker-lldp/supervisord.conf.j2 | 1 + dockers/docker-nat/supervisord.conf | 1 + dockers/docker-orchagent/supervisord.conf | 1 + dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 | 1 + .../docker-router-advertiser.supervisord.conf.j2 | 1 + dockers/docker-sflow/supervisord.conf | 1 + dockers/docker-snmp/supervisord.conf | 1 + dockers/docker-sonic-mgmt-framework/supervisord.conf | 1 + dockers/docker-sonic-restapi/supervisord.conf | 1 + dockers/docker-sonic-telemetry/supervisord.conf | 1 + dockers/docker-teamd/supervisord.conf | 1 + platform/barefoot/docker-syncd-bfn/supervisord.conf | 1 + platform/broadcom/docker-syncd-brcm/supervisord.conf | 1 + platform/centec-arm64/docker-syncd-centec/supervisord.conf | 1 + platform/innovium/docker-syncd-invm/supervisord.conf | 1 + platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf | 1 + platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf | 1 + platform/marvell/docker-syncd-mrvl/supervisord.conf | 1 + platform/mellanox/docker-syncd-mlnx/supervisord.conf | 1 + platform/nephos/docker-syncd-nephos/supervisord.conf | 1 + platform/vs/docker-syncd-vs/supervisord.conf | 1 + .../tests/sample_output/docker-dhcp-relay.supervisord.conf | 1 + 24 files changed, 24 insertions(+) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index 97de4f360428..2efac176fabe 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=50 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay diff --git a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 index e752b1ca05fb..862886b8afae 100644 --- a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 +++ b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=50 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name bgp diff --git a/dockers/docker-lldp/supervisord.conf.j2 b/dockers/docker-lldp/supervisord.conf.j2 index 776dcd029621..5499e2af4678 100644 --- a/dockers/docker-lldp/supervisord.conf.j2 +++ b/dockers/docker-lldp/supervisord.conf.j2 @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name lldp diff --git a/dockers/docker-nat/supervisord.conf b/dockers/docker-nat/supervisord.conf index a6fb78aa1bc1..9840300ec163 100644 --- a/dockers/docker-nat/supervisord.conf +++ b/dockers/docker-nat/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name nat diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 3cd192f24ce8..f8c68337f0c0 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=100 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name swss diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index ffb6a61cb183..f1eacf5b408c 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=100 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name pmon diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 index 9bfc8d9220ad..9e7594117092 100644 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-script] command=/usr/bin/supervisor-proc-exit-listener --container-name radv diff --git a/dockers/docker-sflow/supervisord.conf b/dockers/docker-sflow/supervisord.conf index a3150f23afb3..2731d89d0681 100644 --- a/dockers/docker-sflow/supervisord.conf +++ b/dockers/docker-sflow/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name sflow diff --git a/dockers/docker-snmp/supervisord.conf b/dockers/docker-snmp/supervisord.conf index 2ca3686dcd11..05f54122b59a 100644 --- a/dockers/docker-snmp/supervisord.conf +++ b/dockers/docker-snmp/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=50 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name snmp diff --git a/dockers/docker-sonic-mgmt-framework/supervisord.conf b/dockers/docker-sonic-mgmt-framework/supervisord.conf index f78d0ec84121..5ff38f0f6213 100644 --- a/dockers/docker-sonic-mgmt-framework/supervisord.conf +++ b/dockers/docker-sonic-mgmt-framework/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [program:rsyslogd] command=/usr/sbin/rsyslogd -n -iNONE diff --git a/dockers/docker-sonic-restapi/supervisord.conf b/dockers/docker-sonic-restapi/supervisord.conf index 6f907a0ab082..ac9a9fe18ac9 100644 --- a/dockers/docker-sonic-restapi/supervisord.conf +++ b/dockers/docker-sonic-restapi/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name restapi diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index d968983cddca..f0578803a205 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=50 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name telemetry diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index 50d4249b1966..c152932608c1 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=50 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name teamd diff --git a/platform/barefoot/docker-syncd-bfn/supervisord.conf b/platform/barefoot/docker-syncd-bfn/supervisord.conf index 7083a174c59b..7137279103e4 100644 --- a/platform/barefoot/docker-syncd-bfn/supervisord.conf +++ b/platform/barefoot/docker-syncd-bfn/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index e0ac48c0a243..77f6519c2e9f 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd diff --git a/platform/centec-arm64/docker-syncd-centec/supervisord.conf b/platform/centec-arm64/docker-syncd-centec/supervisord.conf index e1fd242b4e6d..1a15c140a7be 100755 --- a/platform/centec-arm64/docker-syncd-centec/supervisord.conf +++ b/platform/centec-arm64/docker-syncd-centec/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd diff --git a/platform/innovium/docker-syncd-invm/supervisord.conf b/platform/innovium/docker-syncd-invm/supervisord.conf index a614d68f2890..2a2413b30098 100755 --- a/platform/innovium/docker-syncd-invm/supervisord.conf +++ b/platform/innovium/docker-syncd-invm/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [program:rsyslogd] command=/usr/sbin/rsyslogd -n -iNONE diff --git a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf index e1fd242b4e6d..1a15c140a7be 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd diff --git a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf index 0adb188ce329..408899f8886b 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd diff --git a/platform/marvell/docker-syncd-mrvl/supervisord.conf b/platform/marvell/docker-syncd-mrvl/supervisord.conf index 12752786ebba..73523ac02a12 100644 --- a/platform/marvell/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell/docker-syncd-mrvl/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd diff --git a/platform/mellanox/docker-syncd-mlnx/supervisord.conf b/platform/mellanox/docker-syncd-mlnx/supervisord.conf index dc6977ed4710..55578ff2dced 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd diff --git a/platform/nephos/docker-syncd-nephos/supervisord.conf b/platform/nephos/docker-syncd-nephos/supervisord.conf index dc6977ed4710..55578ff2dced 100644 --- a/platform/nephos/docker-syncd-nephos/supervisord.conf +++ b/platform/nephos/docker-syncd-nephos/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd diff --git a/platform/vs/docker-syncd-vs/supervisord.conf b/platform/vs/docker-syncd-vs/supervisord.conf index b097d1aa8c10..36e33850cbff 100644 --- a/platform/vs/docker-syncd-vs/supervisord.conf +++ b/platform/vs/docker-syncd-vs/supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=25 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index 6eeba48fe9af..5037476139ce 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -10,6 +10,7 @@ autorestart=unexpected startretries=0 exitcodes=0,3 events=PROCESS_STATE +buffer_size=50 [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay From e9918bac07a87dfd9bb7199e8b739f42e5a58857 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Wed, 9 Sep 2020 09:04:21 -0700 Subject: [PATCH 1105/1427] [sonic-utilities] Update submodule (#5337) Update to current head in master. Latest: commit 96cb3594a6afc64edcef7351623258287099118d --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 58c29616f510..96cb3594a6af 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 58c29616f510ebd94122db4490523174e1256943 +Subproject commit 96cb3594a6afc64edcef7351623258287099118d From aa601f4b0ada459181a36e834720f64363f4cfc3 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 10 Sep 2020 00:32:56 +0700 Subject: [PATCH 1106/1427] [device/celestica]: Implement Seastone2 platform API (#5080) Implement Seastone2 platform API: 1. Implement Fan APIs. 2. Implement Psu APIs. 3. Implement Thermal APIs. 4. Implement Component APIs. 5. Implement Chassis APIs. 6. Implement Sfp APIs. 7. Implement Watchdog APIs. (Required new CPLD version) 8. Upgrade switchboard driver to support port insert/remove interrupt 9. Init all above APIs class on chassis API. Co-authored-by: pjaipakdee Co-authored-by: Pradchaya P --- .../pmon_daemon_control.json | 3 +- .../sonic_platform_config/chassis.json | 45 + .../sonic_platform_config/component.json | 62 + .../sonic_platform_config/event.py | 114 + .../sonic_platform_config/fan.json | 200 ++ .../sonic_platform_config/psu.json | 135 ++ .../sonic_platform_config/sfp.json | 106 + .../sonic_platform_config/thermal.json | 105 + .../sonic_platform_config/watchdog.py | 191 ++ .../debian/platform-modules-seastone2.install | 2 + .../platform-modules-seastone2.postinst | 4 +- .../sonic-platform-modules-cel/debian/rules | 4 + .../seastone2/modules/switchboard_fpga.c | 1750 ++++++++------ .../services/platform_api/setup.py | 30 + .../platform_api/sonic_platform/__init__.py | 2 + .../platform_api/sonic_platform/chassis.py | 325 +++ .../platform_api/sonic_platform/common.py | 283 +++ .../platform_api/sonic_platform/component.py | 57 + .../platform_api/sonic_platform/eeprom.py | 110 + .../platform_api/sonic_platform/fan.py | 193 ++ .../platform_api/sonic_platform/fan_drawer.py | 82 + .../platform_api/sonic_platform/platform.py | 23 + .../platform_api/sonic_platform/psu.py | 182 ++ .../platform_api/sonic_platform/sfp.py | 2037 +++++++++++++++++ .../platform_api/sonic_platform/thermal.py | 176 ++ 25 files changed, 5482 insertions(+), 739 deletions(-) create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/chassis.json create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/component.json create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/fan.json create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/psu.json create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/sfp.json create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/thermal.json create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py create mode 100755 platform/broadcom/sonic-platform-modules-cel/services/platform_api/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/common.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan_drawer.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/platform.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/sfp.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/thermal.py diff --git a/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json index 294259681a11..5e59513ef696 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json +++ b/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json @@ -2,5 +2,6 @@ "skip_ledd": true, "skip_xcvrd": false, "skip_psud": false, - "skip_syseepromd": false + "skip_syseepromd": false, + "skip_fancontrol": true } \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/chassis.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/chassis.json new file mode 100644 index 000000000000..dfa1a1bddff8 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/chassis.json @@ -0,0 +1,45 @@ +{ + "eeprom": "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom", + "get_reboot_cause": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0c 0x0 0x2 0x06", + "output_translator": { + "00": "Hardware - Other", + "11": "Hardware - Other", + "22": "Non-Hardware", + "33": "Hardware - Other", + "44": "Non-Hardware", + "55": "Non-Hardware", + "77": "Watchdog", + "88": "Thermal Overload: CPU", + "99": "Thermal Overload: ASIC" + } + }, + "get_reboot_description": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0c 0x0 0x2 0x06", + "output_translator": { + "00": "The last reset is power cycle reset (set register 0xA164)", + "11": "The last reset is Power on reset", + "22": "The last reset is soft-set CPU warm reset", + "33": "The last reset is soft-set CPU cold reset", + "44": "The last reset is CPU warm reset", + "55": "The last reset is CPU cold reset", + "77": "The last reset is watchdog reset", + "88": "The last reset is CPU thermal overload", + "99": "The last reset is ASIC thermal overload" + } + }, + "get_watchdog": { + "output_source": "class", + "host_path": "/usr/share/sonic/device/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py", + "pmon_path": "/usr/share/sonic/platform/sonic_platform_config/watchdog.py", + "class": "Watchdog" + }, + "get_change_event": { + "output_source": "class", + "host_path": "/usr/share/sonic/device/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py", + "pmon_path": "/usr/share/sonic/platform/sonic_platform_config/event.py", + "class": "SfpEvent" + } +} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/component.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/component.json new file mode 100644 index 000000000000..96f646206f97 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/component.json @@ -0,0 +1,62 @@ +{ + "component_num": 5, + "get_name": { + "output_source": "value_list", + "value_list": [ + "BIOS", + "CPLD_BASEBOARD", + "CPLD_SWITCHBOARD", + "FPGA", + "BMC" + ] + }, + "get_description": { + "output_source": "value_list", + "value_list": [ + "Used to perform hardware initialization during the booting process", + "Used to control the system power & reset, Control FAN, UART Mux etc", + "Used for managing QSFP ports", + "Used for managing I2C, SPI, PCIe etc", + "Used for monitoring and managing whole system" + ] + }, + "get_firmware_version": { + "output_source": "function", + "function": [ + "_get_bios_ver", + "_get_base_cpld_ver", + "_get_sw_cpld_ver", + "_get_fpga_ver", + "_get_bmc_ver" + ] + }, + "_get_bmc_ver": { + "output_source": "ipmitool", + "command": "ipmitool mc info | grep 'Firmware Revision'", + "output_translator": "'{}'.split(':')[-1].strip()" + }, + "_get_bios_ver": { + "output_source": "txt_file", + "path": "/sys/class/dmi/id/bios_version" + }, + "_get_base_cpld_ver": { + "output_source": "hex_version_file", + "num_of_points": 1, + "num_of_bits": 8, + "path": "/sys/devices/platform/baseboard/version" + }, + "_get_sw_cpld_ver": { + "output_source": "hex_version_getreg", + "num_of_points": 1, + "num_of_bits": 8, + "reg_addr": "0x00", + "path": "/sys/devices/platform/switchboard/CPLD1/getreg" + }, + "_get_fpga_ver": { + "output_source": "hex_version_getreg", + "num_of_points": 1, + "num_of_bits": 32, + "reg_addr": "0x00", + "path": "/sys/devices/platform/switchboard/FPGA/getreg" + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py new file mode 100644 index 000000000000..0153d29418f2 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica Seastone2 +# +# SfpEvent contains an implementation of SONiC Platform Base API +# +############################################################################# +try: + import time + import os + from sonic_platform.common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +PLATFORM_PATH = "/sys/devices/platform/" +SWITCH_BRD_PLATFORM = "switchboard" +POLL_INTERVAL = 1 + + +class SfpEvent: + ''' Listen to insert/remove sfp events ''' + + PORT_INFO_DIR = 'SFF' + PATH_INT_SYSFS = "{0}/{port_name}/{type_prefix}_isr_flags" + PATH_INTMASK_SYSFS = "{0}/{port_name}/{type_prefix}_isr_mask" + PATH_PRS_SYSFS = "{0}/{port_name}/{prs_file_name}" + PRESENT_EN = 0x01 + + def __init__(self, sfp_list): + self.num_sfp = len(sfp_list) + self._api_common = Common() + self._initialize_interrupts() + + def _initialize_interrupts(self): + sfp_info_obj = {} + port_info_path = os.path.join( + PLATFORM_PATH, SWITCH_BRD_PLATFORM, self.PORT_INFO_DIR) + + for index in range(self.num_sfp): + port_num = index + 1 + port_name = "QSFP{}".format(port_num) + port_type = "qsfp" + sysfs_prs_file = "{}_modprs".format(port_type) + + sfp_info_obj[index] = {} + sfp_info_obj[index]['intmask_sysfs'] = self.PATH_INTMASK_SYSFS.format( + port_info_path, + port_name=port_name, + type_prefix=port_type) + + sfp_info_obj[index]['int_sysfs'] = self.PATH_INT_SYSFS.format( + port_info_path, + port_name=port_name, + type_prefix=port_type) + + sfp_info_obj[index]['prs_sysfs'] = self.PATH_PRS_SYSFS.format( + port_info_path, + port_name=port_name, + prs_file_name=sysfs_prs_file) + + self._api_common.write_txt_file( + sfp_info_obj[index]["intmask_sysfs"], hex(self.PRESENT_EN)) + + self.sfp_info_obj = sfp_info_obj + + def _is_port_device_present(self, port_idx): + prs_path = self.sfp_info_obj[port_idx]["prs_sysfs"] + is_present = 1 - int(self._api_common.read_txt_file(prs_path)) + return is_present + + def _update_port_event_object(self, interrup_devices, port_dict): + for port_idx in interrup_devices: + device_id = str(port_idx + 1) + port_dict[device_id] = str(self._is_port_device_present(port_idx)) + return port_dict + + def _clear_event_flag(self, path): + self._api_common.write_txt_file(path, hex(0xff)) + time.sleep(0.1) + self._api_common.write_txt_file(path, hex(0x0)) + + def _check_all_port_interrupt_event(self): + interrupt_devices = {} + for i in range(self.num_sfp): + int_sysfs = self.sfp_info_obj[i]["int_sysfs"] + interrupt_flags = self._api_common.read_txt_file(int_sysfs) + if interrupt_flags != '0x00': + interrupt_devices[i] = 1 + self._clear_event_flag(int_sysfs) + return interrupt_devices + + def get_event(self, timeout): + sleep_time = min( + timeout, POLL_INTERVAL) if timeout != 0 else POLL_INTERVAL + start_milli_time = int(round(time.time() * 1000)) + int_sfp = {} + + while True: + chk_sfp = self._check_all_port_interrupt_event() + int_sfp = self._update_port_event_object( + chk_sfp, int_sfp) if chk_sfp else int_sfp + current_milli_time = int(round(time.time() * 1000)) + if (int_sfp) or \ + (timeout != 0 and current_milli_time - start_milli_time > timeout): + break + + time.sleep(sleep_time) + + change_dict = dict() + change_dict['sfp'] = int_sfp + + return True, change_dict diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/fan.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/fan.json new file mode 100644 index 000000000000..724f6edf53c1 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/fan.json @@ -0,0 +1,200 @@ +{ + "fan_num_per_drawer": 2, + "drawer_num": 4, + "get_name": { + "output_source": "value_list", + "value_list": [ + "Fan1-F", + "Fan1-R", + "Fan2-F", + "Fan2-R", + "Fan3-F", + "Fan3-R", + "Fan4-F", + "Fan4-R" + ] + }, + "get_presence": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x03 0x03 {}", + "argument": [ + "0x00", + "0x00", + "0x01", + "0x01", + "0x02", + "0x02", + "0x03", + "0x03" + ], + "output_translator": "True if '00' in '{}' else False" + }, + "get_model": { + "output_source": "ipmitool", + "command": "ipmitool fru list {} | grep 'Board Part Number'", + "argument": [ + "5", + "5", + "6", + "6", + "7", + "7", + "8", + "8" + ], + "output_translator": "'{}'.split()[-1]" + }, + "get_serial": { + "output_source": "ipmitool", + "command": "ipmitool fru list {} | grep 'Board Serial'", + "argument": [ + "5", + "5", + "6", + "6", + "7", + "7", + "8", + "8" + ], + "output_translator": "'{}'.split()[-1]" + }, + "get_direction": { + "output_source": "ipmitool", + "command": "ipmitool fru list {} | grep 'F2B\\|B2F'", + "argument": [ + "5", + "5", + "6", + "6", + "7", + "7", + "8", + "8" + ], + "output_translator": "'intake' if 'B2F' in '{}' else 'exhaust'" + }, + "get_speed": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x2d {}", + "argument": [ + "0x81", + "0x80", + "0x83", + "0x82", + "0x85", + "0x84", + "0x87", + "0x86" + ], + "output_translator": "int('{}'.split()[0],16)*150", + "max_front": 23000, + "max_rear": 20500 + }, + "get_target_speed": { + "output_source": "value", + "value": "N/A" + }, + "get_speed_tolerance": { + "output_source": "value", + "value": 10 + }, + "set_speed": { + "set_method": "ipmitool", + "input_translator": "hex(int({} * 255 / 100.0))", + "command": "ipmitool raw 0x3a 0x0c 0x00 0x03 {}", + "argument": [ + "0x40 {}", + "0x40 {}", + "0x44 {}", + "0x44 {}", + "0x4c {}", + "0x4c {}", + "0x50 {}", + "0x50 {}" + ] + }, + "set_status_led": { + "set_method": "ipmitool", + "avaliable_input": [ + "off", + "amber", + "green" + ], + "input_translator": { + "off": "0x0", + "amber": "0x1", + "green": "0x2" + }, + "command": "ipmitool raw 0x3a 0x0a {}", + "argument": [ + "0x4 {}", + "0x4 {}", + "0x5 {}", + "0x5 {}", + "0x6 {}", + "0x6 {}", + "0x7 {}", + "0x7 {}" + ] + }, + "get_status_led": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0b {}", + "argument": [ + "0x4", + "0x4", + "0x5", + "0x5", + "0x6", + "0x6", + "0x7", + "0x7" + ], + "output_translator": { + "00": "off", + "01": "amber", + "02": "green" + } + }, + "psu_fan": [ + { + "num_of_fan": 1, + "get_name": { + "output_source": "value_list", + "value_list": [ + "PSU-R-Fan" + ] + }, + "get_speed": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x2d {}", + "argument": [ + "0x8b" + ], + "output_translator": "int('{}'.split()[0],16)*100", + "max_front": 22600, + "max_rear": 22600 + } + }, + { + "num_of_fan": 1, + "get_name": { + "output_source": "value_list", + "value_list": [ + "PSU-L-Fan" + ] + }, + "get_speed": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x2d {}", + "argument": [ + "0x8a" + ], + "output_translator": "int('{}'.split()[0],16)*100", + "max_front": 22600, + "max_rear": 22600 + } + } + ] +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/psu.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/psu.json new file mode 100644 index 000000000000..c3e953c082a7 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/psu.json @@ -0,0 +1,135 @@ +{ + "psu_num": 2, + "fan_per_psu_num": 1, + "get_name": { + "output_source": "value_list", + "value_list": [ + "PSU-R", + "PSU-L" + ] + }, + "get_power": { + "output_source": "ipmitool", + "command": "ipmitool sdr | grep {}", + "argument": [ + "PSUR_POut", + "PSUL_POut" + ], + "output_translator": "float('{}'.split()[2])" + }, + "get_current": { + "output_source": "ipmitool", + "command": "ipmitool sdr | grep {}", + "argument": [ + "PSUR_COut", + "PSUL_COut" + ], + "output_translator": "float('{}'.split()[2])" + }, + "get_voltage": { + "output_source": "ipmitool", + "command": "ipmitool sdr | grep {}", + "argument": [ + "PSUR_VOut", + "PSUL_VOut" + ], + "output_translator": "float('{}'.split()[2])" + }, + "get_voltage_high_threshold": { + "output_source": "ipmitool", + "command": "ipmitool sensor list | grep {}", + "argument": [ + "PSUR_Temp2", + "PSUL_Temp2" + ], + "output_translator": "float(0 if '{0}'.split()[-3]=='na' else '{0}'.split()[-3])" + }, + "get_voltage_low_threshold": { + "output_source": "ipmitool", + "command": "ipmitool sensor list | grep {}", + "argument": [ + "PSUR_Temp2", + "PSUL_Temp2" + ], + "output_translator": "float(0 if '{0}'.split()[-9]=='na' else '{0}'.split()[-9])" + }, + "get_presence": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0c 0x00 0x2 0x60", + "output_translator": [ + "True if (int('{}', 16) >> 4 & 1) == 0 else False", + "True if (int('{}', 16) >> 5 & 1) == 0 else False" + ] + }, + "get_model": { + "output_source": "ipmitool", + "command": "ipmitool fru list {} | grep 'Product Part Number'", + "argument": [ + "4", + "3" + ], + "output_translator": "'{}'.split()[-1]" + }, + "get_serial": { + "output_source": "ipmitool", + "command": "ipmitool fru list {} | grep 'Product Serial'", + "argument": [ + "4", + "3" + ], + "output_translator": "'{}'.split()[-1]" + }, + "get_powergood_status": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0c 0x0 0x2 0x60", + "output_translator": [ + "True if (int('{}', 16) >> 2 & 1) == 1 else False", + "True if (int('{}', 16) >> 3 & 1) == 1 else False" + ] + }, + "set_status_led": { + "set_method": "ipmitool", + "avaliable_input": [ + "amber" + ], + "input_translator": { + "amber": "0x1" + }, + "command": "ipmitool raw 0x3a 0x0a {}", + "argument": [ + "0x3 {}", + "0x2 {}" + ] + }, + "get_status_led": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0b {}", + "argument": [ + "0x3", + "0x2" + ], + "output_translator": { + "00": "green", + "01": "amber" + }, + "default_output": "off" + }, + "get_temperature": { + "output_source": "ipmitool", + "command": "ipmitool sdr | grep {}", + "argument": [ + "PSUR_Temp2", + "PSUL_Temp2" + ], + "output_translator": "float('{}'.split()[2])" + }, + "get_temperature_high_threshold": { + "output_source": "ipmitool", + "command": "ipmitool sensor list | grep {}", + "argument": [ + "PSUR_Temp2", + "PSUL_Temp2" + ], + "output_translator": "float(0 if '{0}'.split()[-3]=='na' else '{0}'.split()[-3])" + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/sfp.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/sfp.json new file mode 100644 index 000000000000..d77e75e50e2f --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/sfp.json @@ -0,0 +1,106 @@ +{ + "port_num": 32, + "eeprom_path": "/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom", + "port_i2c_mapping": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33 + ], + "get_presence": { + "output_source": "sysfs_value", + "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_modprs", + "argument": "$ref:_port_name", + "output_translator": "False if '{}' == '1' else True" + }, + "get_lpmode": { + "output_source": "sysfs_value", + "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_lpmode", + "argument": "$ref:_port_name", + "output_translator": "True if '{}' == '1' else False" + }, + "get_reset_status": { + "output_source": "sysfs_value", + "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_reset", + "argument": "$ref:_port_name", + "output_translator": "False if '{}' == '1' else True" + }, + "reset": { + "set_method": "sysfs_value", + "write_offset": 0, + "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_reset", + "argument": "$ref:_port_name" + }, + "set_lpmode": { + "set_method": "sysfs_value", + "input_translator": { + "True": "0x1", + "False": "0x0" + }, + "write_offset": 0, + "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_lpmode", + "argument": "$ref:_port_name" + }, + "_port_name": [ + "QSFP1", + "QSFP2", + "QSFP3", + "QSFP4", + "QSFP5", + "QSFP6", + "QSFP7", + "QSFP8", + "QSFP9", + "QSFP10", + "QSFP11", + "QSFP12", + "QSFP13", + "QSFP14", + "QSFP15", + "QSFP16", + "QSFP17", + "QSFP18", + "QSFP19", + "QSFP20", + "QSFP21", + "QSFP22", + "QSFP23", + "QSFP24", + "QSFP25", + "QSFP26", + "QSFP27", + "QSFP28", + "QSFP29", + "QSFP30", + "QSFP31", + "QSFP32" + ] +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/thermal.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/thermal.json new file mode 100644 index 000000000000..e3dcb7fb9271 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/thermal.json @@ -0,0 +1,105 @@ +{ + "thermal_num": 9, + "get_name": { + "output_source": "value_list", + "value_list": [ + "Base_Temp_U5", + "Base_Temp_U7", + "CPU_Temp", + "Switch_Temp_U1", + "Switch_Temp_U18", + "Switch_Temp_U28", + "Switch_Temp_U29", + "Switch_U21_Temp", + "Switch_U33_Temp" + ] + }, + "get_temperature": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x2D {}", + "argument": [ + "0x1", + "0x2", + "0x7", + "0x3", + "0x4", + "0x5", + "0x6", + "0x56", + "0x4C" + ], + "output_translator": "int('{}'.split()[0],16)" + }, + "get_high_threshold": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x27 {}", + "argument": [ + "0x1", + "0x2", + "0x7", + "0x3", + "0x4", + "0x5", + "0x6", + "0x56", + "0x4c" + ], + "output_translator": "int('{}'.split()[4], 16)" + }, + "get_low_threshold": { + "output_source": "value", + "value": "N/A" + }, + "set_high_threshold": { + "set_method": "ipmitool", + "command": "ipmitool sensor thresh {}", + "input_translator": "{}", + "argument": [ + "Base_Temp_U5 unc {}", + "Base_Temp_U7 unc {}", + "CPU_Temp unc {}", + "Switch_Temp_U1 unc {}", + "Switch_Temp_U18 unc {}", + "Switch_Temp_U28 unc {}", + "Switch_Temp_U29 unc {}", + "Switch_U21_Temp unc {}", + "Switch_U33_Temp unc {}" + ] + }, + "set_low_threshold": { + "output_source": "ipmitool", + "command": "ipmitool sensor thresh {}", + "input_translator": "{}", + "argument": [ + "Base_Temp_U5 lnc {}", + "Base_Temp_U7 lnc {}", + "CPU_Temp lnc {}", + "Switch_Temp_U1 lnc {}", + "Switch_Temp_U18 lnc {}", + "Switch_Temp_U28 lnc {}", + "Switch_Temp_U29 lnc {}", + "Switch_U21_Temp lnc {}", + "Switch_U33_Temp lnc {}" + ] + }, + "get_high_critical_threshold": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x27 {}", + "argument": [ + "0x1", + "0x2", + "0x7", + "0x3", + "0x4", + "0x5", + "0x6", + "0x56", + "0x4c" + ], + "output_translator": "int('{}'.split()[5], 16)" + }, + "get_low_critical_threshold": { + "output_source": "value", + "value": "N/A" + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py new file mode 100644 index 000000000000..70eae5b95b3b --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica Seastone2 +# +# Watchdog contains an implementation of SONiC Platform Base API +# +############################################################################# +import os +import time + +try: + from sonic_platform_base.watchdog_base import WatchdogBase + from sonic_platform.common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PLATFORM_CPLD_PATH = '/sys/devices/platform/baseboard/' +GETREG_FILE = 'getreg' +SETREG_FILE = 'setreg' +WDT_ENABLE_REG = '0xA181' +WDT_TIMER_L_BIT_REG = '0xA182' +WDT_TIMER_M_BIT_REG = '0xA183' +WDT_TIMER_H_BIT_REG = '0xA184' +WDT_KEEP_ALVIVE_REG = '0xA185' +ENABLE_CMD = '0x1' +DISABLE_CMD = '0x0' +WDT_COMMON_ERROR = -1 + + +class Watchdog(WatchdogBase): + + def __init__(self): + self._api_common = Common() + + # Init cpld reg path + self.setreg_path = os.path.join(PLATFORM_CPLD_PATH, SETREG_FILE) + self.getreg_path = os.path.join(PLATFORM_CPLD_PATH, GETREG_FILE) + + # Set default value + self._disable() + self.armed = False + self.timeout = self._gettimeout() + + def _enable(self): + """ + Turn on the watchdog timer + """ + # echo 0xA181 0x1 > /sys/devices/platform/baseboard/setreg + enable_val = '{} {}'.format(WDT_ENABLE_REG, ENABLE_CMD) + return self._api_common.write_txt_file(self.setreg_path, enable_val) + + def _disable(self): + """ + Turn off the watchdog timer + """ + # echo 0xA181 0x0 > /sys/devices/platform/baseboard/setreg + disable_val = '{} {}'.format(WDT_ENABLE_REG, DISABLE_CMD) + return self._api_common.write_txt_file(self.setreg_path, disable_val) + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + # echo 0xA185 0x1 > /sys/devices/platform/baseboard/setreg + enable_val = '{} {}'.format(WDT_KEEP_ALVIVE_REG, ENABLE_CMD) + return self._api_common.write_txt_file(self.setreg_path, enable_val) + + def _get_level_hex(self, sub_hex): + sub_hex_str = sub_hex.replace("x", "0") + return hex(int(sub_hex_str, 16)) + + def _seconds_to_lmh_hex(self, seconds): + ms = seconds*1000 # calculate timeout in ms format + hex_str = hex(ms) + l = self._get_level_hex(hex_str[-2:]) + m = self._get_level_hex(hex_str[-4:-2]) + h = self._get_level_hex(hex_str[-6:-4]) + return (l, m, h) + + def _settimeout(self, seconds): + """ + Set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + # max = 0xffffff = 16777.215 seconds + + (l, m, h) = self._seconds_to_lmh_hex(seconds) + set_h_val = '{} {}'.format(WDT_TIMER_H_BIT_REG, h) + set_m_val = '{} {}'.format(WDT_TIMER_M_BIT_REG, m) + set_l_val = '{} {}'.format(WDT_TIMER_L_BIT_REG, l) + + self._api_common.write_txt_file( + self.setreg_path, set_h_val) # set high bit + self._api_common.write_txt_file( + self.setreg_path, set_m_val) # set med bit + self._api_common.write_txt_file( + self.setreg_path, set_l_val) # set low bit + + return seconds + + def _gettimeout(self): + """ + Get watchdog timeout + @return watchdog timeout + """ + + h_bit = self._api_common.get_reg( + self.getreg_path, WDT_TIMER_H_BIT_REG) + m_bit = self._api_common.get_reg( + self.getreg_path, WDT_TIMER_M_BIT_REG) + l_bit = self._api_common.get_reg( + self.getreg_path, WDT_TIMER_L_BIT_REG) + + hex_time = '0x{}{}{}'.format(h_bit[2:], m_bit[2:], l_bit[2:]) + ms = int(hex_time, 16) + return int(float(ms)/1000) + + ################################################################# + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* available + value. + Returns: + An integer specifying the *actual* number of seconds the watchdog + was armed with. On failure returns -1. + """ + + ret = WDT_COMMON_ERROR + if seconds < 0: + return ret + + try: + if self.timeout != seconds: + self.timeout = self._settimeout(seconds) + + if self.armed: + self._keepalive() + else: + self._enable() + self.armed = True + + ret = self.timeout + self.arm_timestamp = time.time() + except IOError as e: + pass + + return ret + + def disarm(self): + """ + Disarm the hardware watchdog + Returns: + A boolean, True if watchdog is disarmed successfully, False if not + """ + disarmed = False + if self.is_armed(): + try: + self._disable() + self.armed = False + disarmed = True + except IOError: + pass + + return disarmed + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + Returns: + A boolean, True if watchdog is armed, False if not + """ + + return self.armed + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds remaining on + the watchdog timer + Returns: + An integer specifying the number of seconds remaining on thei + watchdog timer. If the watchdog is not armed, returns -1. + """ + + return int(self.timeout - (time.time() - self.arm_timestamp)) if self.armed else WDT_COMMON_ERROR diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install index e17b5e9cae83..41a381eeb0ce 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install @@ -1,2 +1,4 @@ seastone2/cfg/seastone2-modules.conf etc/modules-load.d seastone2/systemd/platform-modules-seastone2.service lib/systemd/system +seastone2/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone_2-r0 +services/platform_api/platform_api_mgnt.sh usr/local/bin \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst index 9a8e57cb8e9c..f232a2cac59d 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst @@ -1,3 +1,5 @@ depmod -a systemctl enable platform-modules-seastone2.service -systemctl start platform-modules-seastone2.service \ No newline at end of file +systemctl start platform-modules-seastone2.service + +/usr/local/bin/platform_api_mgnt.sh install diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/rules b/platform/broadcom/sonic-platform-modules-cel/debian/rules index 0ed48f9feaea..a7293e0b6700 100755 --- a/platform/broadcom/sonic-platform-modules-cel/debian/rules +++ b/platform/broadcom/sonic-platform-modules-cel/debian/rules @@ -16,6 +16,10 @@ override_dh_auto_build: cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ + if [ $$mod = "seastone2" ]; then \ + cd services/platform_api; \ + python2 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + fi \ done) override_dh_auto_install: diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c index c7a86e13d3ad..5918d27f3911 100644 --- a/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c @@ -25,7 +25,7 @@ */ #ifndef TEST_MODE -#define MOD_VERSION "2.1.3" +#define MOD_VERSION "2.2.0" #else #define MOD_VERSION "TEST" #endif @@ -51,8 +51,6 @@ #include #include - - static int majorNumber; #define CLASS_NAME "seastone2_fpga" @@ -62,17 +60,16 @@ static int majorNumber; static int smbus_access(struct i2c_adapter *adapter, u16 addr, - unsigned short flags, char rw, u8 cmd, - int size, union i2c_smbus_data *data); + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, - unsigned short flags, char rw, u8 cmd, - int size, union i2c_smbus_data *data); + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); static int fpgafw_init(void); static void fpgafw_exit(void); - /* ======================================== FPGA PCIe BAR 0 Registers @@ -186,7 +183,6 @@ PORT XCVR 0x00004000 - 0x00004FFF. */ #define INTR_INT_N 5 #define INTR_PRESENT 4 -#define INTR_TXFAULT 2 #define INTR_RXLOS 1 #define INTR_MODABS 0 @@ -201,7 +197,6 @@ PORT XCVR 0x00004000 - 0x00004FFF. */ #define MASK_INT_N 5 #define MASK_PRESENT 4 -#define MASK_TXFAULT 2 #define MASK_RXLOS 1 #define MASK_MODABS 0 @@ -254,6 +249,7 @@ enum { static struct class* fpgafwclass = NULL; ///< The device-driver class struct pointer static struct device* fpgafwdev = NULL; ///< The device-driver device struct pointer +static struct platform_device *seastone2_dev; #define PCI_VENDOR_ID_TEST 0x1af4 @@ -287,7 +283,7 @@ enum PORT_TYPE { SFP }; -struct i2c_switch{ +struct i2c_switch { unsigned char master_bus; // I2C bus number unsigned char switch_addr; // PCA9548 device address, 0xFF if directly connect to a bus. unsigned char channel; // PCA9548 channel number. If the switch_addr is 0xFF, this value is ignored. @@ -303,32 +299,32 @@ struct i2c_dev_data { /* PREDEFINED I2C SWITCH DEVICE TOPOLOGY */ static struct i2c_switch fpga_i2c_bus_dev[] = { /* BUS2 QSFP Exported as virtual bus */ - {I2C_MASTER_CH_2,0x72,0,QSFP,"QSFP1"}, {I2C_MASTER_CH_2,0x72,1,QSFP,"QSFP2"}, - {I2C_MASTER_CH_2,0x72,2,QSFP,"QSFP3"}, {I2C_MASTER_CH_2,0x72,3,QSFP,"QSFP4"}, - {I2C_MASTER_CH_2,0x72,4,QSFP,"QSFP5"}, {I2C_MASTER_CH_2,0x72,5,QSFP,"QSFP6"}, - {I2C_MASTER_CH_2,0x72,6,QSFP,"QSFP7"}, {I2C_MASTER_CH_2,0x72,7,QSFP,"QSFP8"}, - {I2C_MASTER_CH_2,0x73,0,QSFP,"QSFP9"}, {I2C_MASTER_CH_2,0x73,1,QSFP,"QSFP10"}, - {I2C_MASTER_CH_2,0x73,2,QSFP,"QSFP11"},{I2C_MASTER_CH_2,0x73,3,QSFP,"QSFP12"}, - {I2C_MASTER_CH_2,0x73,4,QSFP,"QSFP13"},{I2C_MASTER_CH_2,0x73,5,QSFP,"QSFP14"}, - {I2C_MASTER_CH_2,0x73,6,QSFP,"QSFP15"},{I2C_MASTER_CH_2,0x73,7,QSFP,"QSFP16"}, - {I2C_MASTER_CH_2,0x74,0,QSFP,"QSFP17"},{I2C_MASTER_CH_2,0x74,1,QSFP,"QSFP18"}, - {I2C_MASTER_CH_2,0x74,2,QSFP,"QSFP19"},{I2C_MASTER_CH_2,0x74,3,QSFP,"QSFP20"}, - {I2C_MASTER_CH_2,0x74,4,QSFP,"QSFP21"},{I2C_MASTER_CH_2,0x74,5,QSFP,"QSFP22"}, - {I2C_MASTER_CH_2,0x74,6,QSFP,"QSFP23"},{I2C_MASTER_CH_2,0x74,7,QSFP,"QSFP24"}, - {I2C_MASTER_CH_2,0x75,0,QSFP,"QSFP25"},{I2C_MASTER_CH_2,0x75,1,QSFP,"QSFP26"}, - {I2C_MASTER_CH_2,0x75,2,QSFP,"QSFP27"},{I2C_MASTER_CH_2,0x75,3,QSFP,"QSFP28"}, - {I2C_MASTER_CH_2,0x75,4,QSFP,"QSFP29"},{I2C_MASTER_CH_2,0x75,5,QSFP,"QSFP30"}, - {I2C_MASTER_CH_2,0x75,6,QSFP,"QSFP31"},{I2C_MASTER_CH_2,0x75,7,QSFP,"QSFP32"}, + {I2C_MASTER_CH_2, 0x72, 0, QSFP, "QSFP1"}, {I2C_MASTER_CH_2, 0x72, 1, QSFP, "QSFP2"}, + {I2C_MASTER_CH_2, 0x72, 2, QSFP, "QSFP3"}, {I2C_MASTER_CH_2, 0x72, 3, QSFP, "QSFP4"}, + {I2C_MASTER_CH_2, 0x72, 4, QSFP, "QSFP5"}, {I2C_MASTER_CH_2, 0x72, 5, QSFP, "QSFP6"}, + {I2C_MASTER_CH_2, 0x72, 6, QSFP, "QSFP7"}, {I2C_MASTER_CH_2, 0x72, 7, QSFP, "QSFP8"}, + {I2C_MASTER_CH_2, 0x73, 0, QSFP, "QSFP9"}, {I2C_MASTER_CH_2, 0x73, 1, QSFP, "QSFP10"}, + {I2C_MASTER_CH_2, 0x73, 2, QSFP, "QSFP11"}, {I2C_MASTER_CH_2, 0x73, 3, QSFP, "QSFP12"}, + {I2C_MASTER_CH_2, 0x73, 4, QSFP, "QSFP13"}, {I2C_MASTER_CH_2, 0x73, 5, QSFP, "QSFP14"}, + {I2C_MASTER_CH_2, 0x73, 6, QSFP, "QSFP15"}, {I2C_MASTER_CH_2, 0x73, 7, QSFP, "QSFP16"}, + {I2C_MASTER_CH_2, 0x74, 0, QSFP, "QSFP17"}, {I2C_MASTER_CH_2, 0x74, 1, QSFP, "QSFP18"}, + {I2C_MASTER_CH_2, 0x74, 2, QSFP, "QSFP19"}, {I2C_MASTER_CH_2, 0x74, 3, QSFP, "QSFP20"}, + {I2C_MASTER_CH_2, 0x74, 4, QSFP, "QSFP21"}, {I2C_MASTER_CH_2, 0x74, 5, QSFP, "QSFP22"}, + {I2C_MASTER_CH_2, 0x74, 6, QSFP, "QSFP23"}, {I2C_MASTER_CH_2, 0x74, 7, QSFP, "QSFP24"}, + {I2C_MASTER_CH_2, 0x75, 0, QSFP, "QSFP25"}, {I2C_MASTER_CH_2, 0x75, 1, QSFP, "QSFP26"}, + {I2C_MASTER_CH_2, 0x75, 2, QSFP, "QSFP27"}, {I2C_MASTER_CH_2, 0x75, 3, QSFP, "QSFP28"}, + {I2C_MASTER_CH_2, 0x75, 4, QSFP, "QSFP29"}, {I2C_MASTER_CH_2, 0x75, 5, QSFP, "QSFP30"}, + {I2C_MASTER_CH_2, 0x75, 6, QSFP, "QSFP31"}, {I2C_MASTER_CH_2, 0x75, 7, QSFP, "QSFP32"}, /* BUS1 SFP+ Exported as virtual bus */ - {I2C_MASTER_CH_1,0x72,0,SFP,"SFP1"}, + {I2C_MASTER_CH_1, 0x72, 0, SFP, "SFP1"}, /* BUS3 Switchboard CPLD */ - {I2C_MASTER_CH_3,0xFF,0,NONE,"I2C_3"}, + {I2C_MASTER_CH_3, 0xFF, 0, NONE, "I2C_3"}, }; #define VIRTUAL_I2C_PORT_LENGTH ARRAY_SIZE(fpga_i2c_bus_dev) #define VIRTUAL_I2C_CPLD_INDEX SFF_PORT_TOTAL -struct fpga_device{ +struct fpga_device { /* data mmio region */ void __iomem *data_base_addr; resource_size_t data_mmio_start; @@ -373,82 +369,83 @@ static struct kobject *cpld2 = NULL; static struct device *sff_dev = NULL; /** - * [get_fpga_reg_value description] - * @param dev [description] - * @param devattr [description] - * @param buf [description] - * @return [description] + * Show the value of the register set by 'set_fpga_reg_address' + * If the address is not set by 'set_fpga_reg_address' first, + * The version register is selected by default. + * @param buf register value in hextring + * @return number of bytes read, or an error code */ -static ssize_t get_fpga_reg_value(struct device *dev, struct device_attribute *devattr, - char *buf) +static ssize_t get_fpga_reg_value(struct device *dev, + struct device_attribute *attr, char *buf) { // read data from the address uint32_t data; data = ioread32(fpga_data->fpga_read_addr); - return sprintf(buf,"0x%8.8x\n",data); + return sprintf(buf, "0x%8.8x\n", data); } + /** - * [set_fpga_reg_address description] - * @param dev [description] - * @param devattr [description] - * @param buf [description] - * @param count [description] - * @return [description] + * Store the register address + * @param buf address wanted to be read value of + * @return number of bytes stored, or an error code */ -static ssize_t set_fpga_reg_address(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) +static ssize_t set_fpga_reg_address(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { + ssize_t status; uint32_t addr; - char *last; - addr = (uint32_t)strtoul(buf,&last,16); - if(addr == 0 && buf == last){ - return -EINVAL; + status = kstrtou32(buf, 0, &addr); + if (status == 0) { + fpga_data->fpga_read_addr = fpga_dev.data_base_addr + addr; + status = count; } - fpga_data->fpga_read_addr = fpga_dev.data_base_addr+addr; - return count; + return status; } + /** - * [get_fpga_scratch description] - * @param dev [description] - * @param devattr [description] - * @param buf [description] - * @return [description] + * Show value of fpga scratch register + * @param buf register value in hexstring + * @return number of bytes read, or an error code */ -static ssize_t get_fpga_scratch(struct device *dev, struct device_attribute *devattr, - char *buf) +static ssize_t get_fpga_scratch(struct device *dev, + struct device_attribute *attr, char *buf) { - return sprintf(buf,"0x%8.8x\n", ioread32(fpga_dev.data_base_addr+FPGA_SCRATCH) & 0xffffffff); + uint32_t data; + data = ioread32(fpga_dev.data_base_addr + FPGA_SCRATCH); + data &= 0xffffffff; + return sprintf(buf, "0x%8.8x\n", data); } + /** - * [set_fpga_scratch description] - * @param dev [description] - * @param devattr [description] - * @param buf [description] - * @param count [description] - * @return [description] + * Store value of fpga scratch register + * @param buf scratch register value passing from user space + * @return number of bytes stored, or an error code */ -static ssize_t set_fpga_scratch(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) +static ssize_t set_fpga_scratch(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { + ssize_t status; uint32_t data; - char *last; - data = (uint32_t)strtoul(buf,&last,16); - if(data == 0 && buf == last){ - return -EINVAL; + + status = kstrtou32(buf, 0, &data); + if (status == 0) { + iowrite32(data, fpga_dev.data_base_addr + FPGA_SCRATCH); + status = count; } - iowrite32(data, fpga_dev.data_base_addr+FPGA_SCRATCH); - return count; + return status; } + /** - * [set_fpga_reg_value description] - * @param dev [description] - * @param devattr [description] - * @param buf [description] - * @return [description] + * Store a value in a specific register address + * @param buf the value and address in format '0xhhhh 0xhhhhhhhh' + * @return number of bytes sent by user space, or an error code */ -static ssize_t set_fpga_reg_value(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) +static ssize_t set_fpga_reg_value(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { //register is 4 bytes uint32_t addr; @@ -457,46 +454,46 @@ static ssize_t set_fpga_reg_value(struct device *dev, struct device_attribute *d char *tok; char clone[count]; char *pclone = clone; - char *last; + ssize_t status; strcpy(clone, buf); mutex_lock(&fpga_data->fpga_lock); tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } - addr = (uint32_t)strtoul(tok,&last,16); - if(addr == 0 && tok == last){ + status = kstrtou32(tok, 0, &addr); + if (status != 0) { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } - value = (uint32_t)strtoul(tok,&last,16); - if(value == 0 && tok == last){ + status = kstrtou32(tok, 0, &value); + if (status != 0) { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { mode = 32; - }else{ - mode = (uint32_t)strtoul(tok,&last,10); - if(mode == 0 && tok == last){ + } else { + status = kstrtou32(tok, 0, &mode); + if (status != 0) { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } } - if(mode == 32){ - iowrite32(value, fpga_dev.data_base_addr+addr); - }else if(mode == 8){ - iowrite8(value, fpga_dev.data_base_addr+addr); - }else{ + if (mode == 32) { + iowrite32(value, fpga_dev.data_base_addr + addr); + } else if (mode == 8) { + iowrite8(value, fpga_dev.data_base_addr + addr); + } else { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } @@ -513,7 +510,7 @@ static ssize_t ready_show(struct device *dev, struct device_attribute *attr, cha unsigned int REGISTER = FPGA_PORT_XCVR_READY; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> 0) & 1U); } @@ -525,409 +522,673 @@ static DEVICE_ATTR( setreg, 0200, NULL , set_fpga_reg_value); static DEVICE_ATTR_RO(ready); static struct attribute *fpga_attrs[] = { - &dev_attr_getreg.attr, - &dev_attr_scratch.attr, - &dev_attr_setreg.attr, - &dev_attr_ready.attr, - NULL, + &dev_attr_getreg.attr, + &dev_attr_scratch.attr, + &dev_attr_setreg.attr, + &dev_attr_ready.attr, + NULL, }; static struct attribute_group fpga_attr_grp = { - .attrs = fpga_attrs, + .attrs = fpga_attrs, }; /* SW CPLDs attributes */ -static ssize_t cpld1_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t cpld1_getreg_show(struct device *dev, + struct device_attribute *attr, char *buf) { // CPLD register is one byte uint8_t data; - fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,fpga_data->cpld1_read_addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - return sprintf(buf,"0x%2.2x\n",data); + int err; + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, fpga_data->cpld1_read_addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + + if (err < 0) + return err; + + return sprintf(buf, "0x%2.2x\n", data); } -static ssize_t cpld1_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) + +static ssize_t cpld1_getreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { + ssize_t status; uint8_t addr; - char *last; - addr = (uint8_t)strtoul(buf,&last,16); - if(addr == 0 && buf == last){ - return -EINVAL; + + status = kstrtou8(buf, 0, &addr); + if (status == 0) { + fpga_data->cpld1_read_addr = addr; + status = count; } - fpga_data->cpld1_read_addr = addr; - return size; + return status; } -struct device_attribute dev_attr_cpld1_getreg = __ATTR(getreg,0600,cpld1_getreg_show,cpld1_getreg_store); -static ssize_t cpld1_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t cpld1_scratch_show(struct device *dev, + struct device_attribute *attr, char *buf) { // CPLD register is one byte - __u8 data; + uint8_t data; int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - if(err < 0) + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) return err; - return sprintf(buf, "0x%2.2x\n",data); + + return sprintf(buf, "0x%2.2x\n", data); } -static ssize_t cpld1_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) + +static ssize_t cpld1_scratch_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { // CPLD register is one byte - __u8 data; - char *last; + uint8_t data; + ssize_t status; int err; - data = (uint8_t)strtoul(buf,&last,16); - if(data == 0 && buf == last){ - return -EINVAL; + + status = kstrtou8(buf, 0, &data); + if (status != 0) { + return status; } - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - if(err < 0) + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) return err; - return size; + + return count; } -struct device_attribute dev_attr_cpld1_scratch = __ATTR(scratch,0600,cpld1_scratch_show,cpld1_scratch_store); -static ssize_t cpld1_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t cpld1_setreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { - uint8_t addr,value; + uint8_t addr, value; char *tok; - char clone[size]; + char clone[count]; char *pclone = clone; + ssize_t status; int err; - char *last; strcpy(clone, buf); tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { return -EINVAL; } - addr = (uint8_t)strtoul(tok,&last,16); - if(addr == 0 && tok == last){ + status = kstrtou8(tok, 0, &addr); + if (status != 0) { return -EINVAL; } tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { return -EINVAL; } - value = (uint8_t)strtoul(tok,&last,16); - if(value == 0 && tok == last){ + status = kstrtou8(tok, 0, &value); + if (status != 0) { return -EINVAL; } - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&value); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); + if (err < 0) return err; - return size; + return count; } -struct device_attribute dev_attr_cpld1_setreg = __ATTR(setreg,0200,NULL,cpld1_setreg_store); + +struct device_attribute dev_attr_cpld1_getreg = __ATTR(getreg, 0600, cpld1_getreg_show, cpld1_getreg_store); +struct device_attribute dev_attr_cpld1_scratch = __ATTR(scratch, 0600, cpld1_scratch_show, cpld1_scratch_store); +struct device_attribute dev_attr_cpld1_setreg = __ATTR(setreg, 0200, NULL, cpld1_setreg_store); static struct attribute *cpld1_attrs[] = { - &dev_attr_cpld1_getreg.attr, - &dev_attr_cpld1_scratch.attr, - &dev_attr_cpld1_setreg.attr, - NULL, + &dev_attr_cpld1_getreg.attr, + &dev_attr_cpld1_scratch.attr, + &dev_attr_cpld1_setreg.attr, + NULL, }; static struct attribute_group cpld1_attr_grp = { - .attrs = cpld1_attrs, + .attrs = cpld1_attrs, }; -static ssize_t cpld2_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t cpld2_getreg_show(struct device *dev, + struct device_attribute *attr, char *buf) { // CPLD register is one byte uint8_t data; - fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,fpga_data->cpld2_read_addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - return sprintf(buf,"0x%2.2x\n",data); + int err; + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld2_read_addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + + return sprintf(buf, "0x%2.2x\n", data); } -static ssize_t cpld2_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) + +static ssize_t cpld2_getreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { // CPLD register is one byte - uint32_t addr; - char *last; - addr = (uint8_t)strtoul(buf,&last,16); - if(addr == 0 && buf == last){ - return -EINVAL; + uint8_t addr; + ssize_t status; + + status = kstrtou8(buf, 0, &addr); + if (status == 0) { + fpga_data->cpld2_read_addr = addr; + status = count; } - fpga_data->cpld2_read_addr = addr; - return size; + return status; } -struct device_attribute dev_attr_cpld2_getreg = __ATTR(getreg,0600,cpld2_getreg_show,cpld2_getreg_store); -static ssize_t cpld2_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t cpld2_scratch_show(struct device *dev, + struct device_attribute *attr, char *buf) { // CPLD register is one byte - __u8 data; + uint8_t data; int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - if(err < 0) + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) return err; - return sprintf(buf, "0x%2.2x\n",data); + + return sprintf(buf, "0x%2.2x\n", data); } -static ssize_t cpld2_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) + +static ssize_t cpld2_scratch_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { // CPLD register is one byte - __u8 data; - char *last; + uint8_t data; int err; + ssize_t status; - data = (uint8_t)strtoul(buf,&last,16); - if(data == 0 && buf == last){ + status = kstrtou8(buf, 0, &data); + if (status != 0) { return -EINVAL; } - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) return err; - return size; + + return count; } -struct device_attribute dev_attr_cpld2_scratch = __ATTR(scratch,0600,cpld2_scratch_show,cpld2_scratch_store); -static ssize_t cpld2_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t cpld2_setreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { - uint8_t addr,value; + uint8_t addr, value; char *tok; - char clone[size]; + char clone[count]; char *pclone = clone; + ssize_t status; int err; - char *last; strcpy(clone, buf); tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { return -EINVAL; } - addr = (uint8_t)strtoul(tok,&last,16); - if(addr == 0 && tok == last){ + status = kstrtou8(tok, 0, &addr); + if (status != 0) { return -EINVAL; } tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { return -EINVAL; } - value = (uint8_t)strtoul(tok,&last,16); - if(value == 0 && tok == last){ + status = kstrtou8(tok, 0, &value); + if (status != 0) { return -EINVAL; } - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&value); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); + if (err < 0) return err; - return size; + return count; } -struct device_attribute dev_attr_cpld2_setreg = __ATTR(setreg,0200,NULL,cpld2_setreg_store); + +struct device_attribute dev_attr_cpld2_getreg = __ATTR(getreg, 0600, cpld2_getreg_show, cpld2_getreg_store); +struct device_attribute dev_attr_cpld2_scratch = __ATTR(scratch, 0600, cpld2_scratch_show, cpld2_scratch_store); +struct device_attribute dev_attr_cpld2_setreg = __ATTR(setreg, 0200, NULL, cpld2_setreg_store); static struct attribute *cpld2_attrs[] = { - &dev_attr_cpld2_getreg.attr, - &dev_attr_cpld2_scratch.attr, - &dev_attr_cpld2_setreg.attr, - NULL, + &dev_attr_cpld2_getreg.attr, + &dev_attr_cpld2_scratch.attr, + &dev_attr_cpld2_setreg.attr, + NULL, }; static struct attribute_group cpld2_attr_grp = { - .attrs = cpld2_attrs, + .attrs = cpld2_attrs, }; /* QSFP/SFP+ attributes */ -static ssize_t qsfp_modirq_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t qsfp_modirq_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> STAT_IRQ) & 1U); } DEVICE_ATTR_RO(qsfp_modirq); -static ssize_t qsfp_modprs_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t qsfp_modprs_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> STAT_PRESENT) & 1U); } DEVICE_ATTR_RO(qsfp_modprs); -static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t sfp_txfault_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> STAT_TXFAULT) & 1U); } DEVICE_ATTR_RO(sfp_txfault); -static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t sfp_rxlos_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> STAT_RXLOS) & 1U); } DEVICE_ATTR_RO(sfp_rxlos); -static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t sfp_modabs_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> STAT_MODABS) & 1U); } DEVICE_ATTR_RO(sfp_modabs); -static ssize_t qsfp_lpmode_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t qsfp_lpmode_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> CTRL_LPMOD) & 1U); } -static ssize_t qsfp_lpmode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t qsfp_lpmode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { ssize_t status; - long value; + uint32_t value; u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - status = kstrtol(buf, 0, &value); + status = kstrtou32(buf, 0, &value); if (status == 0) { // check if value is 0 clear - data = ioread32(fpga_dev.data_base_addr+REGISTER); - if(!value) + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) data = data & ~( (u32)0x1 << CTRL_LPMOD); else data = data | ((u32)0x1 << CTRL_LPMOD); - iowrite32(data,fpga_dev.data_base_addr+REGISTER); - status = size; + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = count; } mutex_unlock(&fpga_data->fpga_lock); return status; } DEVICE_ATTR_RW(qsfp_lpmode); -static ssize_t qsfp_reset_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t qsfp_reset_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> CTRL_RST) & 1U); } -static ssize_t qsfp_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t qsfp_reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { ssize_t status; - long value; + uint32_t value; u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - status = kstrtol(buf, 0, &value); + status = kstrtou32(buf, 0, &value); if (status == 0) { // check if value is 0 clear - data = ioread32(fpga_dev.data_base_addr+REGISTER); - if(!value) + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) data = data & ~( (u32)0x1 << CTRL_RST); else data = data | ((u32)0x1 << CTRL_RST); - iowrite32(data,fpga_dev.data_base_addr+REGISTER); - status = size; + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = count; } mutex_unlock(&fpga_data->fpga_lock); return status; } DEVICE_ATTR_RW(qsfp_reset); -static ssize_t sfp_txdisable_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t qsfp_isr_flags_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + data = (u8) ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + /* + * Unify the return pattern to 2-bit + * [1] : module interrupt + * [0] : presence + */ + data = data & valid_bits; + data = data >> 4; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t qsfp_isr_flags_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value << 4; + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_isr_flags); + +static ssize_t qsfp_isr_mask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + /* + * Unify the return pattern to 2-bit + * [1] : module interrupt + * [0] : presence + */ + data = data & valid_bits; + data = data >> 4; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t qsfp_isr_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value << 4; + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_isr_mask); + +static ssize_t sfp_txdisable_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> CTRL_TXDIS) & 1U); } -static ssize_t sfp_txdisable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t sfp_txdisable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { ssize_t status; long value; u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); status = kstrtol(buf, 0, &value); if (status == 0) { // check if value is 0 clear - data = ioread32(fpga_dev.data_base_addr+REGISTER); - if(!value) + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) data = data & ~( (u32)0x1 << CTRL_TXDIS); else data = data | ((u32)0x1 << CTRL_TXDIS); - iowrite32(data,fpga_dev.data_base_addr+REGISTER); - status = size; + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = count; } mutex_unlock(&fpga_data->fpga_lock); return status; } DEVICE_ATTR_RW(sfp_txdisable); +static ssize_t sfp_isr_flags_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_RXLOS) | BIT(INTR_MODABS); + + mutex_lock(&fpga_data->fpga_lock); + data = (u8) ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + data = data & valid_bits; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t sfp_isr_flags_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(sfp_isr_flags); + +static ssize_t sfp_isr_mask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_RXLOS) | BIT(INTR_MODABS); + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + data = data & valid_bits; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t sfp_isr_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_RXLOS) | BIT(INTR_MODABS); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(sfp_isr_mask); + static struct attribute *sff_attrs[] = { &dev_attr_qsfp_modirq.attr, &dev_attr_qsfp_modprs.attr, &dev_attr_qsfp_lpmode.attr, &dev_attr_qsfp_reset.attr, + &dev_attr_qsfp_isr_flags.attr, + &dev_attr_qsfp_isr_mask.attr, &dev_attr_sfp_txfault.attr, &dev_attr_sfp_rxlos.attr, &dev_attr_sfp_modabs.attr, &dev_attr_sfp_txdisable.attr, + &dev_attr_sfp_isr_flags.attr, + &dev_attr_sfp_isr_mask.attr, NULL, }; static struct attribute_group sff_attr_grp = { - .attrs = sff_attrs, + .attrs = sff_attrs, }; static const struct attribute_group *sff_attr_grps[] = { @@ -936,78 +1197,99 @@ static const struct attribute_group *sff_attr_grps[] = { }; -static ssize_t port_led_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t port_led_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) { // value can be "nomal", "test" - __u8 led_mode_1,led_mode_2; + __u8 led_mode_1, led_mode_2; int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + if (err < 0) return err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_2); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_2); + if (err < 0) return err; + return sprintf(buf, "%s %s\n", - led_mode_1 ? "test" : "normal", - led_mode_2 ? "test" : "normal"); + led_mode_1 ? "test" : "normal", + led_mode_2 ? "test" : "normal"); } -static ssize_t port_led_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t port_led_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { int status; __u8 led_mode_1; - if(sysfs_streq(buf, "test")){ + if (sysfs_streq(buf, "test")) { led_mode_1 = 0x01; - }else if(sysfs_streq(buf, "normal")){ + } else if (sysfs_streq(buf, "normal")) { led_mode_1 = 0x00; - }else{ + } else { return -EINVAL; } - status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, - I2C_SMBUS_WRITE,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); - status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, - I2C_SMBUS_WRITE,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); - return size; + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + return count; } DEVICE_ATTR_RW(port_led_mode); // Only work when port_led_mode set to 1 -static ssize_t port_led_color_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t port_led_color_show(struct device *dev, + struct device_attribute *attr, char *buf) { // value can be "off", "green", "amber", "both" - __u8 led_color1,led_color2; + __u8 led_color1, led_color2; int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color1); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x0A, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color1); + if (err < 0) return err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color2); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x0A, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color2); + if (err < 0) return err; return sprintf(buf, "%s %s\n", - led_color1 == 0x03 ? "off" : led_color1 == 0x02 ? "green" : led_color1 ==0x01 ? "amber": "both", - led_color2 == 0x03 ? "off" : led_color2 == 0x02 ? "green" : led_color2 ==0x01 ? "amber": "both"); + led_color1 == 0x03 ? "off" : led_color1 == 0x02 ? "green" : led_color1 == 0x01 ? "amber" : "both", + led_color2 == 0x03 ? "off" : led_color2 == 0x02 ? "green" : led_color2 == 0x01 ? "amber" : "both"); } -static ssize_t port_led_color_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t port_led_color_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { int status; __u8 led_color; - if(sysfs_streq(buf, "off")){ + if (sysfs_streq(buf, "off")) { led_color = 0x03; - }else if(sysfs_streq(buf, "green")){ + } else if (sysfs_streq(buf, "green")) { led_color = 0x02; - }else if(sysfs_streq(buf, "amber")){ + } else if (sysfs_streq(buf, "amber")) { led_color = 0x01; - }else if(sysfs_streq(buf, "both")){ + } else if (sysfs_streq(buf, "both")) { led_color = 0x00; - }else{ + } else { status = -EINVAL; return status; } - status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, - I2C_SMBUS_WRITE,0x0A,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color); - status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, - I2C_SMBUS_WRITE,0x0A,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color); - return size; + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, + (union i2c_smbus_data*)&led_color); + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, + (union i2c_smbus_data*)&led_color); + return count; } DEVICE_ATTR_RW(port_led_color); @@ -1018,10 +1300,10 @@ static struct attribute *sff_led_test[] = { }; static struct attribute_group sff_led_test_grp = { - .attrs = sff_led_test, + .attrs = sff_led_test, }; -static struct device * seastone2_sff_init(int portid){ +static struct device * seastone2_sff_init(int portid) { struct sff_device_data *new_data; struct device *new_device; @@ -1031,9 +1313,11 @@ static struct device * seastone2_sff_init(int portid){ return NULL; } /* The QSFP port ID start from 1 */ - new_data->portid = portid+1; + new_data->portid = portid + 1; new_data->port_type = fpga_i2c_bus_dev[portid].port_type; - new_device = device_create_with_groups(fpgafwclass, sff_dev, MKDEV(0,0), new_data, sff_attr_grps, "%s",fpga_i2c_bus_dev[portid].calling_name); + new_device = device_create_with_groups(fpgafwclass, sff_dev, + MKDEV(0, 0), new_data, sff_attr_grps, "%s", + fpga_i2c_bus_dev[portid].calling_name); if (IS_ERR(new_device)) { printk(KERN_ALERT "Cannot create sff device @port%d", portid); kfree(new_data); @@ -1042,7 +1326,7 @@ static struct device * seastone2_sff_init(int portid){ return new_device; } -static int i2c_wait_ack(struct i2c_adapter *a,unsigned long timeout,int writing){ +static int i2c_wait_ack(struct i2c_adapter *a, unsigned long timeout, int writing) { int error = 0; int Status; @@ -1057,65 +1341,65 @@ static int i2c_wait_ack(struct i2c_adapter *a,unsigned long timeout,int writing) unsigned int master_bus = new_data->pca9548.master_bus; - if(master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL){ + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { error = -EINVAL; return error; } - REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus-1)*0x0100; - REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus-1)*0x0100; - REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus-1)*0x0100; - REG_DR0 = I2C_MASTER_DATA_1 + (master_bus-1)*0x0100; - REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus-1)*0x0100; + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; - check(pci_bar+REG_SR0); - check(pci_bar+REG_CR0); + check(pci_bar + REG_SR0); + check(pci_bar + REG_CR0); timeout = jiffies + msecs_to_jiffies(timeout); - while(1){ - Status = ioread8(pci_bar+REG_SR0); - if(jiffies > timeout){ - info("Status %2.2X",Status); + while (1) { + Status = ioread8(pci_bar + REG_SR0); + if (jiffies > timeout) { + info("Status %2.2X", Status); info("Error Timeout"); error = -ETIMEDOUT; break; } - if(Status & (1 << I2C_SR_BIT_MIF)){ + if (Status & (1 << I2C_SR_BIT_MIF)) { break; } - if(writing == 0 && (Status & (1<portid; - pci_bar = fpga_dev.data_base_addr; + int error = 0; + int cnt = 0; + int bid = 0; + struct i2c_dev_data *dev_data; + void __iomem *pci_bar; + unsigned int portid, master_bus; + + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + REG_FDR0 = 0; + REG_CR0 = 0; + REG_SR0 = 0; + REG_DR0 = 0; + REG_ID0 = 0; + + /* Write the command register */ + dev_data = i2c_get_adapdata(adapter); + portid = dev_data->portid; + pci_bar = fpga_dev.data_base_addr; #ifdef DEBUG_KERN - printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-15s|CMD %2.2X " - ,portid,addr,flags,rw,rw == 1 ? "READ ":"WRITE" - ,size, size == 0 ? "QUICK" : - size == 1 ? "BYTE" : - size == 2 ? "BYTE_DATA" : - size == 3 ? "WORD_DATA" : - size == 4 ? "PROC_CALL" : - size == 5 ? "BLOCK_DATA" : - size == 8 ? "I2C_BLOCK_DATA" : "ERROR" - ,cmd); + printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-15s|CMD %2.2X " + , portid, addr, flags, rw, rw == 1 ? "READ " : "WRITE" + , size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + , cmd); #endif - /* Map the size to what the chip understands */ - switch (size) { - case I2C_SMBUS_QUICK: - case I2C_SMBUS_BYTE: - case I2C_SMBUS_BYTE_DATA: - case I2C_SMBUS_WORD_DATA: - case I2C_SMBUS_BLOCK_DATA: - case I2C_SMBUS_I2C_BLOCK_DATA: - break; - default: - printk(KERN_INFO "Unsupported transaction %d\n", size); - error = -EOPNOTSUPP; - goto Done; - } + /* Map the size to what the chip understands */ + switch (size) { + case I2C_SMBUS_QUICK: + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + break; + default: + printk(KERN_INFO "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; + } - master_bus = dev_data->pca9548.master_bus; + master_bus = dev_data->pca9548.master_bus; - if(master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL){ - error = -ENXIO; - goto Done; - } + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { + error = -ENXIO; + goto Done; + } - REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus-1)*0x0100; - REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus-1)*0x0100; - REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus-1)*0x0100; - REG_DR0 = I2C_MASTER_DATA_1 + (master_bus-1)*0x0100; - REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus-1)*0x0100; - - iowrite8(portid,pci_bar+REG_ID0); - - ////[S][ADDR/R] - // Clear status register - iowrite8(0,pci_bar+REG_SR0); - iowrite8(1 << I2C_CR_BIT_MIEN | 1 << I2C_CR_BIT_MTX | 1 << I2C_CR_BIT_MSTA ,pci_bar+REG_CR0); - SET_REG_BIT_H(pci_bar+REG_CR0,I2C_CR_BIT_MEN); - - if(rw == I2C_SMBUS_READ && - (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)){ - // sent device address with Read mode - iowrite8(addr << 1 | 0x01,pci_bar+REG_DR0); - }else{ - // sent device address with Write mode - iowrite8(addr << 1 | 0x00,pci_bar+REG_DR0); - } + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; + + iowrite8(portid, pci_bar + REG_ID0); + + ////[S][ADDR/R] + // Clear status register + iowrite8(0, pci_bar + REG_SR0); + iowrite8(1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MTX | + 1 << I2C_CR_BIT_MSTA , pci_bar + REG_CR0); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + + if (rw == I2C_SMBUS_READ && + (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)) { + // sent device address with Read mode + iowrite8(addr << 1 | 0x01, pci_bar + REG_DR0); + } else { + // sent device address with Write mode + iowrite8(addr << 1 | 0x00, pci_bar + REG_DR0); + } - info( "MS Start"); + info( "MS Start"); - //// Wait {A} - error = i2c_wait_ack(adapter,12,1); - if(error<0){ - info( "get error %d",error); - goto Done; - } + //// Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; + } - //// [CMD]{A} - if(size == I2C_SMBUS_BYTE_DATA || + //// [CMD]{A} + if (size == I2C_SMBUS_BYTE_DATA || size == I2C_SMBUS_WORD_DATA || size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA || - (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)){ - - // sent command code to data register - iowrite8(cmd,pci_bar+REG_DR0); - info( "MS Send CMD 0x%2.2X",cmd); + (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)) { - // Wait {A} - error = i2c_wait_ack(adapter,12,1); - if(error<0){ - info( "get error %d",error); - goto Done; - } - } + // sent command code to data register + iowrite8(cmd, pci_bar + REG_DR0); + info( "MS Send CMD 0x%2.2X", cmd); - switch(size){ - case I2C_SMBUS_BYTE_DATA: - cnt = 1; break; - case I2C_SMBUS_WORD_DATA: - cnt = 2; break; - case I2C_SMBUS_BLOCK_DATA: - case I2C_SMBUS_I2C_BLOCK_DATA: - /* In block data modes keep number of byte in block[0] */ - cnt = data->block[0]; - break; - default: - cnt = 0; break; + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; } + } - // [CNT] used only block data write - if(size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE){ - - iowrite8(cnt,pci_bar+REG_DR0); - info( "MS Send CNT 0x%2.2X",cnt); + switch (size) { + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + /* In block data modes keep number of byte in block[0] */ + cnt = data->block[0]; + break; + default: + cnt = 0; break; + } - // Wait {A} - error = i2c_wait_ack(adapter,12,1); - if(error<0){ - info( "get error %d",error); - goto Done; - } - } + // [CNT] used only block data write + if (size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE) { - // [DATA]{A} - if( rw == I2C_SMBUS_WRITE && ( - size == I2C_SMBUS_BYTE || - size == I2C_SMBUS_BYTE_DATA || - size == I2C_SMBUS_WORD_DATA || - size == I2C_SMBUS_BLOCK_DATA || - size == I2C_SMBUS_I2C_BLOCK_DATA - )){ - bid = 0; - info( "MS prepare to sent [%d bytes]",cnt); - if(size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA){ - bid=1; // block[0] is cnt; - cnt+=1; // offset from block[0] - } - for(;bidblock[bid],pci_bar+REG_DR0); - info( " Data > %2.2X",data->block[bid]); - // Wait {A} - error = i2c_wait_ack(adapter,12,1); - if(error<0){ - goto Done; - } - } + iowrite8(cnt, pci_bar + REG_DR0); + info( "MS Send CNT 0x%2.2X", cnt); + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; } + } - // REPEATE START - if( rw == I2C_SMBUS_READ && ( + // [DATA]{A} + if ( rw == I2C_SMBUS_WRITE && ( + size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA || size == I2C_SMBUS_WORD_DATA || size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA - )){ - info( "MS Repeated Start"); - - SET_REG_BIT_L(pci_bar+REG_CR0,I2C_CR_BIT_MEN); - iowrite8(1 << I2C_CR_BIT_MIEN | - 1 << I2C_CR_BIT_MTX | - 1 << I2C_CR_BIT_MSTA | - 1 << I2C_CR_BIT_RSTA ,pci_bar+REG_CR0); - SET_REG_BIT_H(pci_bar+REG_CR0,I2C_CR_BIT_MEN); - - // sent Address with Read mode - iowrite8( addr<<1 | 0x1 ,pci_bar+REG_DR0); + )) { + bid = 0; + info( "MS prepare to sent [%d bytes]", cnt); + if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) { + bid = 1; // block[0] is cnt; + cnt += 1; // offset from block[0] + } + for (; bid < cnt; bid++) { + iowrite8(data->block[bid], pci_bar + REG_DR0); + info( " Data > %2.2X", data->block[bid]); // Wait {A} - error = i2c_wait_ack(adapter,12,1); - if(error<0){ + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { goto Done; } + } + } + + // REPEATE START + if ( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )) { + info( "MS Repeated Start"); + + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + iowrite8(1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MTX | + 1 << I2C_CR_BIT_MSTA | + 1 << I2C_CR_BIT_RSTA , pci_bar + REG_CR0); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + + // sent Address with Read mode + iowrite8( addr << 1 | 0x1 , pci_bar + REG_DR0); + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + goto Done; } - if( rw == I2C_SMBUS_READ && ( + } + + if ( rw == I2C_SMBUS_READ && ( size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA || size == I2C_SMBUS_WORD_DATA || size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA - )){ - - switch(size){ - case I2C_SMBUS_BYTE: - case I2C_SMBUS_BYTE_DATA: - cnt = 1; break; - case I2C_SMBUS_WORD_DATA: - cnt = 2; break; - case I2C_SMBUS_BLOCK_DATA: - // will be changed after recived first data - cnt = 3; break; - case I2C_SMBUS_I2C_BLOCK_DATA: - cnt = data->block[0]; break; - default: - cnt = 0; break; - } + )) { - bid = 0; - info( "MS Receive"); + switch (size) { + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + // will be changed after recived first data + cnt = 3; break; + case I2C_SMBUS_I2C_BLOCK_DATA: + cnt = data->block[0]; break; + default: + cnt = 0; break; + } - //set to Receive mode - iowrite8(1 << I2C_CR_BIT_MEN | - 1 << I2C_CR_BIT_MIEN | - 1 << I2C_CR_BIT_MSTA , pci_bar+REG_CR0); + bid = 0; + info( "MS Receive"); - for(bid=-1;bidblock[bid+1] = ioread8(pci_bar+REG_DR0); - }else { - data->block[bid] = ioread8(pci_bar+REG_DR0); - } - info( "DATA IN [%d] %2.2X",bid,data->block[bid]); + if (bid < 0) { + ioread8(pci_bar + REG_DR0); + info( "READ Dummy Byte" ); + } else { - if(size == I2C_SMBUS_BLOCK_DATA && bid == 0){ - cnt = data->block[0] + 1; - } + if (bid == cnt - 1) { + info ( "SET STOP in read loop"); + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); + } + if (size == I2C_SMBUS_I2C_BLOCK_DATA) { + // block[0] is read length + data->block[bid + 1] = ioread8(pci_bar + REG_DR0); + } else { + data->block[bid] = ioread8(pci_bar + REG_DR0); + } + info( "DATA IN [%d] %2.2X", bid, data->block[bid]); + + if (size == I2C_SMBUS_BLOCK_DATA && bid == 0) { + cnt = data->block[0] + 1; } } } + } - // [P] - SET_REG_BIT_L(pci_bar+REG_CR0,I2C_CR_BIT_MSTA); - info( "MS STOP"); + // [P] + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); + info( "MS STOP"); Done: - iowrite8(1<= 0){ + while (retry--) { + error = smbus_access(adapter, (u16)(prev_switch), flags, + I2C_SMBUS_WRITE, 0x00, + I2C_SMBUS_BYTE, NULL); + if (error >= 0) { break; - }else{ - dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); + } else { + dev_dbg(&adapter->dev, + "Failed to deselect ch %d of 0x%x, CODE %d\n", + prev_ch, prev_switch, error); } } - if(retry < 0){ + if (retry < 0) { goto release_unlock; } // set PCA9548 to current channel retry = 3; - while(retry--){ - error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); - if(error >= 0){ + while (retry--) { + error = smbus_access(adapter, switch_addr, flags, + I2C_SMBUS_WRITE, 1 << channel, + I2C_SMBUS_BYTE, NULL); + if (error >= 0) { break; - }else{ - dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); + } else { + dev_dbg(&adapter->dev, + "Failed to deselect ch %d of 0x%x, CODE %d\n", + prev_ch, prev_switch, error); } } - if(retry < 0){ + if (retry < 0) { goto release_unlock; } // update lasted port @@ -1473,41 +1767,47 @@ static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, if ( prev_ch != channel || prev_switch == 0 ) { // set new PCA9548 at switch_addr to current retry = 3; - while(retry--){ - error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); - if(error >= 0){ + while (retry--) { + error = smbus_access(adapter, switch_addr, flags, + I2C_SMBUS_WRITE, 1 << channel, + I2C_SMBUS_BYTE, NULL); + if (error >= 0) { break; - }else{ - dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); + } else { + dev_dbg(&adapter->dev, + "Failed to deselect ch %d of 0x%x, CODE %d\n", + prev_ch, prev_switch, error); + } } - } - if(retry < 0){ - goto release_unlock; - } - // update lasted port - fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + if (retry < 0) { + goto release_unlock; + } + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; } } } // Do SMBus communication error = smbus_access(adapter, addr, flags, rw, cmd, size, data); - if(error < 0){ - dev_dbg( &adapter->dev,"smbus_xfer failed (%d) @ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " - , error, addr, flags, rw, rw == 1 ? "READ " : "WRITE" - , size, size == 0 ? "QUICK" : - size == 1 ? "BYTE" : - size == 2 ? "BYTE_DATA" : - size == 3 ? "WORD_DATA" : - size == 4 ? "PROC_CALL" : - size == 5 ? "BLOCK_DATA" : - size == 8 ? "I2C_BLOCK_DATA" : "ERROR" - , cmd); + if (error < 0) { + dev_dbg( &adapter->dev, + "smbus_xfer failed (%d) @ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " + , error, addr, flags, rw, rw == 1 ? "READ " : "WRITE" + , size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + , cmd); } -release_unlock: +release_unlock: mutex_unlock(&fpga_i2c_master_locks[master_bus - 1]); - dev_dbg(&adapter->dev,"switch ch %d of 0x%x -> ch %d of 0x%x\n", prev_ch, prev_switch, channel, switch_addr); + dev_dbg(&adapter->dev, "switch ch %d of 0x%x -> ch %d of 0x%x\n", + prev_ch, prev_switch, channel, switch_addr); return error; } @@ -1519,11 +1819,11 @@ static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, static u32 fpga_i2c_func(struct i2c_adapter *a) { return I2C_FUNC_SMBUS_QUICK | - I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_BLOCK_DATA| - I2C_FUNC_SMBUS_I2C_BLOCK; + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK; } static const struct i2c_algorithm seastone2_i2c_algorithm = { @@ -1541,7 +1841,8 @@ static const struct i2c_algorithm seastone2_i2c_algorithm = { * When bus_number_offset is -1, created adapter with dynamic bus number. * Otherwise create adapter at i2c bus = bus_number_offset + portid. */ -static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int portid, int bus_number_offset) +static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, + int portid, int bus_number_offset) { int error; struct i2c_adapter *new_adapter; @@ -1549,8 +1850,9 @@ static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int void __iomem *i2c_freq_base_reg; new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL); - if (!new_adapter){ - printk(KERN_ALERT "Cannot alloc i2c adapter for %s", fpga_i2c_bus_dev[portid].calling_name); + if (!new_adapter) { + printk(KERN_ALERT "Cannot alloc i2c adapter for %s", + fpga_i2c_bus_dev[portid].calling_name); return NULL; } @@ -1558,15 +1860,16 @@ static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; new_adapter->algo = &seastone2_i2c_algorithm; /* If the bus offset is -1, use dynamic bus number */ - if (bus_number_offset == -1){ + if (bus_number_offset == -1) { new_adapter->nr = -1; - }else{ + } else { new_adapter->nr = bus_number_offset + portid; } new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); - if (!new_data){ - printk(KERN_ALERT "Cannot alloc i2c data for %s", fpga_i2c_bus_dev[portid].calling_name); + if (!new_data) { + printk(KERN_ALERT "Cannot alloc i2c data for %s", + fpga_i2c_bus_dev[portid].calling_name); kzfree(new_adapter); return NULL; } @@ -1575,16 +1878,16 @@ static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int new_data->pca9548.master_bus = fpga_i2c_bus_dev[portid].master_bus; new_data->pca9548.switch_addr = fpga_i2c_bus_dev[portid].switch_addr; new_data->pca9548.channel = fpga_i2c_bus_dev[portid].channel; - strcpy(new_data->pca9548.calling_name,fpga_i2c_bus_dev[portid].calling_name); + strcpy(new_data->pca9548.calling_name, fpga_i2c_bus_dev[portid].calling_name); snprintf(new_adapter->name, sizeof(new_adapter->name), - "SMBus I2C Adapter PortID: %s", new_data->pca9548.calling_name); + "SMBus I2C Adapter PortID: %s", new_data->pca9548.calling_name); - i2c_freq_base_reg = fpga_dev.data_base_addr+I2C_MASTER_FREQ_1; - iowrite8(0x07,i2c_freq_base_reg+(new_data->pca9548.master_bus-1)*0x100); // 0x07 400kHz - i2c_set_adapdata(new_adapter,new_data); + i2c_freq_base_reg = fpga_dev.data_base_addr + I2C_MASTER_FREQ_1; + iowrite8(0x07, i2c_freq_base_reg + (new_data->pca9548.master_bus - 1) * 0x100); // 0x07 400kHz + i2c_set_adapdata(new_adapter, new_data); error = i2c_add_numbered_adapter(new_adapter); - if(error < 0){ + if (error < 0) { printk(KERN_ALERT "Cannot add i2c adapter %s", new_data->pca9548.calling_name); kzfree(new_adapter); kzfree(new_data); @@ -1594,30 +1897,6 @@ static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int return new_adapter; }; -// I/O resource need. -static struct resource seastone2_resources[] = { - { - .start = 0x10000000, - .end = 0x10001000, - .flags = IORESOURCE_MEM, - }, -}; - -static void seastone2_dev_release( struct device * dev) -{ - return; -} - -static struct platform_device seastone2_dev = { - .name = DRIVER_NAME, - .id = -1, - .num_resources = ARRAY_SIZE(seastone2_resources), - .resource = seastone2_resources, - .dev = { - .release = seastone2_dev_release, - } -}; - /** * Board info for QSFP/SFP+ eeprom. * Note: Using sff8436 as I2C eeprom driver. @@ -1629,7 +1908,6 @@ static struct i2c_board_info sff8436_eeprom_info[] = { static int seastone2_drv_probe(struct platform_device *pdev) { - struct resource *res; int ret = 0; int portid_count; uint8_t cpld1_version, cpld2_version; @@ -1640,30 +1918,24 @@ static int seastone2_drv_probe(struct platform_device *pdev) BUG_ON(fpgafwclass == NULL); fpga_data = devm_kzalloc(&pdev->dev, sizeof(struct seastone2_fpga_data), - GFP_KERNEL); + GFP_KERNEL); if (!fpga_data) return -ENOMEM; // Set default read address to VERSION - fpga_data->fpga_read_addr = fpga_dev.data_base_addr+FPGA_VERSION; + fpga_data->fpga_read_addr = fpga_dev.data_base_addr + FPGA_VERSION; fpga_data->cpld1_read_addr = 0x00; fpga_data->cpld2_read_addr = 0x00; mutex_init(&fpga_data->fpga_lock); - for(ret=I2C_MASTER_CH_1 ;ret <= I2C_MASTER_CH_TOTAL; ret++){ - mutex_init(&fpga_i2c_master_locks[ret-1]); - } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (unlikely(!res)) { - printk(KERN_ERR "Specified Resource Not Available...\n"); - kzfree(fpga_data); - return -1; + for (ret = I2C_MASTER_CH_1 ; ret <= I2C_MASTER_CH_TOTAL; ret++) { + mutex_init(&fpga_i2c_master_locks[ret - 1]); } fpga = kobject_create_and_add("FPGA", &pdev->dev.kobj); - if (!fpga){ + if (!fpga) { kzfree(fpga_data); return -ENOMEM; } @@ -1677,7 +1949,7 @@ static int seastone2_drv_probe(struct platform_device *pdev) } cpld1 = kobject_create_and_add("CPLD1", &pdev->dev.kobj); - if (!cpld1){ + if (!cpld1) { sysfs_remove_group(fpga, &fpga_attr_grp); kobject_put(fpga); kzfree(fpga_data); @@ -1694,7 +1966,7 @@ static int seastone2_drv_probe(struct platform_device *pdev) } cpld2 = kobject_create_and_add("CPLD2", &pdev->dev.kobj); - if (!cpld2){ + if (!cpld2) { sysfs_remove_group(cpld1, &cpld1_attr_grp); kobject_put(cpld1); sysfs_remove_group(fpga, &fpga_attr_grp); @@ -1714,8 +1986,8 @@ static int seastone2_drv_probe(struct platform_device *pdev) return ret; } - sff_dev = device_create(fpgafwclass, NULL, MKDEV(0,0), NULL, "sff_device"); - if (IS_ERR(sff_dev)){ + sff_dev = device_create(fpgafwclass, NULL, MKDEV(0, 0), NULL, "sff_device"); + if (IS_ERR(sff_dev)) { printk(KERN_ERR "Failed to create sff device\n"); sysfs_remove_group(cpld2, &cpld2_attr_grp); kobject_put(cpld2); @@ -1730,7 +2002,7 @@ static int seastone2_drv_probe(struct platform_device *pdev) ret = sysfs_create_group(&sff_dev->kobj, &sff_led_test_grp); if (ret != 0) { printk(KERN_ERR "Cannot create SFF attributes\n"); - device_destroy(fpgafwclass, MKDEV(0,0)); + device_destroy(fpgafwclass, MKDEV(0, 0)); sysfs_remove_group(cpld2, &cpld2_attr_grp); kobject_put(cpld2); sysfs_remove_group(cpld1, &cpld1_attr_grp); @@ -1741,10 +2013,10 @@ static int seastone2_drv_probe(struct platform_device *pdev) return ret; } - ret = sysfs_create_link(&pdev->dev.kobj,&sff_dev->kobj,"SFF"); - if (ret != 0){ + ret = sysfs_create_link(&pdev->dev.kobj, &sff_dev->kobj, "SFF"); + if (ret != 0) { sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); - device_destroy(fpgafwclass, MKDEV(0,0)); + device_destroy(fpgafwclass, MKDEV(0, 0)); sysfs_remove_group(cpld2, &cpld2_attr_grp); kobject_put(cpld2); sysfs_remove_group(cpld1, &cpld1_attr_grp); @@ -1755,27 +2027,27 @@ static int seastone2_drv_probe(struct platform_device *pdev) return ret; } - for(portid_count=0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++){ + for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { fpga_data->i2c_adapter[portid_count] = seastone2_i2c_init(pdev, portid_count, VIRTUAL_I2C_BUS_OFFSET); } /* Init SFF devices */ - for(portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { struct i2c_adapter *i2c_adap = fpga_data->i2c_adapter[portid_count]; - if(i2c_adap){ + if (i2c_adap) { fpga_data->sff_devices[portid_count] = seastone2_sff_init(portid_count); sff_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); BUG_ON(sff_data == NULL); - if( sff_data->port_type == QSFP ){ + if ( sff_data->port_type == QSFP ) { fpga_data->sff_i2c_clients[portid_count] = i2c_new_device(i2c_adap, &sff8436_eeprom_info[0]); - }else{ + } else { fpga_data->sff_i2c_clients[portid_count] = i2c_new_device(i2c_adap, &sff8436_eeprom_info[1]); } sff_data = NULL; sysfs_create_link(&fpga_data->sff_devices[portid_count]->kobj, - &fpga_data->sff_i2c_clients[portid_count]->dev.kobj, - "i2c"); + &fpga_data->sff_i2c_clients[portid_count]->dev.kobj, + "i2c"); } } @@ -1785,10 +2057,10 @@ static int seastone2_drv_probe(struct platform_device *pdev) #ifdef TEST_MODE return 0; #endif - fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, - I2C_SMBUS_READ,0x00,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&cpld1_version); - fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, - I2C_SMBUS_READ,0x00,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&cpld2_version); + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld1_version); + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld2_version); printk(KERN_INFO "CPLD1 VERSON: %2.2x\n", cpld1_version); printk(KERN_INFO "CPLD2 VERSON: %2.2x\n", cpld2_version); @@ -1809,7 +2081,7 @@ static int seastone2_drv_probe(struct platform_device *pdev) if (prev_i2c_switch != ( (master_bus << 8) | switch_addr) ) { // Found the bus with PCA9548, trying to clear all switch in it. smbus_access(fpga_data->i2c_adapter[portid_count], switch_addr, 0x00, - I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); + I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); prev_i2c_switch = ( master_bus << 8 ) | switch_addr; } } @@ -1822,20 +2094,20 @@ static int seastone2_drv_remove(struct platform_device *pdev) int portid_count; struct sff_device_data *rem_data; - for(portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ - sysfs_remove_link(&fpga_data->sff_devices[portid_count]->kobj,"i2c"); + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + sysfs_remove_link(&fpga_data->sff_devices[portid_count]->kobj, "i2c"); i2c_unregister_device(fpga_data->sff_i2c_clients[portid_count]); } - for(portid_count=0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++){ - if(fpga_data->i2c_adapter[portid_count] != NULL){ - info(KERN_INFO "<%x>",fpga_data->i2c_adapter[portid_count]); + for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { + if (fpga_data->i2c_adapter[portid_count] != NULL) { + info(KERN_INFO "<%x>", fpga_data->i2c_adapter[portid_count]); i2c_del_adapter(fpga_data->i2c_adapter[portid_count]); } } - for (portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ - if(fpga_data->sff_devices[portid_count] != NULL){ + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + if (fpga_data->sff_devices[portid_count] != NULL) { rem_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); device_unregister(fpga_data->sff_devices[portid_count]); put_device(fpga_data->sff_devices[portid_count]); @@ -1850,7 +2122,7 @@ static int seastone2_drv_remove(struct platform_device *pdev) kobject_put(fpga); kobject_put(cpld1); kobject_put(cpld2); - device_destroy(fpgafwclass, MKDEV(0,0)); + device_destroy(fpgafwclass, MKDEV(0, 0)); devm_kfree(&pdev->dev, fpga_data); return 0; } @@ -1864,9 +2136,9 @@ static struct platform_driver seastone2_drv = { }; #ifdef TEST_MODE - #define FPGA_PCI_BAR_NUM 2 +#define FPGA_PCI_BAR_NUM 2 #else - #define FPGA_PCI_BAR_NUM 0 +#define FPGA_PCI_BAR_NUM 0 #endif static const struct pci_device_id fpga_id_table[] = { @@ -1885,7 +2157,7 @@ static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if ((err = pci_enable_device(pdev))) { dev_err(dev, "pci_enable_device probe error %d for device %s\n", - err, pci_name(pdev)); + err, pci_name(pdev)); return err; } @@ -1900,28 +2172,32 @@ static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) fpga_dev.data_base_addr = pci_iomap(pdev, FPGA_PCI_BAR_NUM, 0); if (!fpga_dev.data_base_addr) { dev_err(dev, "cannot iomap region of size %lu\n", - (unsigned long)fpga_dev.data_mmio_len); + (unsigned long)fpga_dev.data_mmio_len); goto pci_release; } dev_info(dev, "data_mmio iomap base = 0x%lx \n", - (unsigned long)fpga_dev.data_base_addr); + (unsigned long)fpga_dev.data_base_addr); dev_info(dev, "data_mmio_start = 0x%lx data_mmio_len = %lu\n", - (unsigned long)fpga_dev.data_mmio_start, - (unsigned long)fpga_dev.data_mmio_len); + (unsigned long)fpga_dev.data_mmio_start, + (unsigned long)fpga_dev.data_mmio_len); printk(KERN_INFO "FPGA PCIe driver probe OK.\n"); - printk(KERN_INFO "FPGA ioremap registers of size %lu\n",(unsigned long)fpga_dev.data_mmio_len); + printk(KERN_INFO "FPGA ioremap registers of size %lu\n", (unsigned long)fpga_dev.data_mmio_len); printk(KERN_INFO "FPGA Virtual BAR %d at %8.8lx - %8.8lx\n", FPGA_PCI_BAR_NUM, - (unsigned long)fpga_dev.data_base_addr, - (unsigned long)(fpga_dev.data_base_addr + fpga_dev.data_mmio_len)); + (unsigned long)fpga_dev.data_base_addr, + (unsigned long)(fpga_dev.data_base_addr + fpga_dev.data_mmio_len)); printk(KERN_INFO ""); fpga_version = ioread32(fpga_dev.data_base_addr); printk(KERN_INFO "FPGA VERSION : %8.8x\n", fpga_version); - fpgafw_init(); - platform_device_register(&seastone2_dev); + if ((err = fpgafw_init()) < 0) { + goto pci_unmap; + } + seastone2_dev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); platform_driver_register(&seastone2_drv); return 0; +pci_unmap: + pci_iounmap(pdev, fpga_dev.data_base_addr); pci_release: pci_release_regions(pdev); pci_disable: @@ -1932,7 +2208,7 @@ static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) static void fpga_pci_remove(struct pci_dev *pdev) { platform_driver_unregister(&seastone2_drv); - platform_device_unregister(&seastone2_dev); + platform_device_unregister(seastone2_dev); fpgafw_exit(); pci_iounmap(pdev, fpga_dev.data_base_addr); pci_release_regions(pdev); @@ -1947,7 +2223,7 @@ static struct pci_driver pci_dev_ops = { .id_table = fpga_id_table, }; -enum{ +enum { READREG, WRITEREG }; @@ -1957,7 +2233,8 @@ struct fpga_reg_data { uint32_t value; }; -static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg){ +static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { int ret = 0; struct fpga_reg_data data; mutex_lock(&fpga_data->fpga_lock); @@ -1966,55 +2243,55 @@ static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned static uint32_t status_reg; #endif // Switch function to read and write. - switch (cmd){ - case READREG: - if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0){ - mutex_unlock(&fpga_data->fpga_lock); - return -EFAULT; - } - data.value = ioread32(fpga_dev.data_base_addr+data.addr); - if (copy_to_user((void __user*)arg ,&data, sizeof(data)) != 0){ - mutex_unlock(&fpga_data->fpga_lock); - return -EFAULT; - } + switch (cmd) { + case READREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + data.value = ioread32(fpga_dev.data_base_addr + data.addr); + if (copy_to_user((void __user*)arg , &data, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } #ifdef TEST_MODE - if(data.addr == 0x1210){ - switch (status_reg){ - case 0x0000 : status_reg=0x8000; - break; + if (data.addr == 0x1210) { + switch (status_reg) { + case 0x0000 : status_reg = 0x8000; + break; - case 0x8080 : status_reg=0x80C0; - break; - case 0x80C0 : status_reg=0x80F0; - break; - case 0x80F0 : status_reg=0x80F8; - break; + case 0x8080 : status_reg = 0x80C0; + break; + case 0x80C0 : status_reg = 0x80F0; + break; + case 0x80F0 : status_reg = 0x80F8; + break; - } - iowrite32(status_reg,fpga_dev.data_base_addr+0x1210); } + iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); + } #endif - break; - case WRITEREG: - if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0){ - mutex_unlock(&fpga_data->fpga_lock); - return -EFAULT; - } - iowrite32(data.value,fpga_dev.data_base_addr+data.addr); + break; + case WRITEREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + iowrite32(data.value, fpga_dev.data_base_addr + data.addr); #ifdef TEST_MODE - if(data.addr == 0x1204){ - status_reg=0x8080; - iowrite32(status_reg,fpga_dev.data_base_addr+0x1210); - } + if (data.addr == 0x1204) { + status_reg = 0x8080; + iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); + } #endif - break; - default: - mutex_unlock(&fpga_data->fpga_lock); - return -EINVAL; + break; + default: + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; } mutex_unlock(&fpga_data->fpga_lock); return ret; @@ -2027,50 +2304,49 @@ const struct file_operations fpgafw_fops = { }; -static int fpgafw_init(void){ - printk(KERN_INFO "Initializing the switchboard driver\n"); - // Try to dynamically allocate a major number for the device -- more difficult but worth it - majorNumber = register_chrdev(0, DEVICE_NAME, &fpgafw_fops); - if (majorNumber<0){ - printk(KERN_ALERT "Failed to register a major number\n"); - return majorNumber; - } - printk(KERN_INFO "Device registered correctly with major number %d\n", majorNumber); - - // Register the device class - fpgafwclass = class_create(THIS_MODULE, CLASS_NAME); - if (IS_ERR(fpgafwclass)){ // Check for error and clean up if there is - unregister_chrdev(majorNumber, DEVICE_NAME); - printk(KERN_ALERT "Failed to register device class\n"); - return PTR_ERR(fpgafwclass); // Correct way to return an error on a pointer - } - printk(KERN_INFO "Device class registered correctly\n"); - - // Register the device driver - fpgafwdev = device_create(fpgafwclass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME); - if (IS_ERR(fpgafwdev)){ // Clean up if there is an error - class_destroy(fpgafwclass); // Repeated code but the alternative is goto statements - unregister_chrdev(majorNumber, DEVICE_NAME); - printk(KERN_ALERT "Failed to create the FW upgrade device node\n"); - return PTR_ERR(fpgafwdev); - } - printk(KERN_INFO "FPGA fw upgrade device node created correctly\n"); // Made it! device was initialized - return 0; +static int fpgafw_init(void) { + printk(KERN_INFO "Initializing the switchboard driver\n"); + // Try to dynamically allocate a major number for the device -- more difficult but worth it + majorNumber = register_chrdev(0, DEVICE_NAME, &fpgafw_fops); + if (majorNumber < 0) { + printk(KERN_ALERT "Failed to register a major number\n"); + return majorNumber; + } + printk(KERN_INFO "Device registered correctly with major number %d\n", majorNumber); + + // Register the device class + fpgafwclass = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(fpgafwclass)) { // Check for error and clean up if there is + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to register device class\n"); + return PTR_ERR(fpgafwclass); + } + printk(KERN_INFO "Device class registered correctly\n"); + + // Register the device driver + fpgafwdev = device_create(fpgafwclass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME); + if (IS_ERR(fpgafwdev)) { // Clean up if there is an error + class_destroy(fpgafwclass); // Repeated code but the alternative is goto statements + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to create the FW upgrade device node\n"); + return PTR_ERR(fpgafwdev); + } + printk(KERN_INFO "FPGA fw upgrade device node created correctly\n"); // Made it! device was initialized + return 0; } -static void fpgafw_exit(void){ - device_destroy(fpgafwclass, MKDEV(majorNumber, 0)); // remove the device - class_unregister(fpgafwclass); // unregister the device class - class_destroy(fpgafwclass); // remove the device class - unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number - printk(KERN_INFO "Goodbye!\n"); +static void fpgafw_exit(void) { + device_destroy(fpgafwclass, MKDEV(majorNumber, 0)); // remove the device + class_destroy(fpgafwclass); // remove the device class + unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number + printk(KERN_INFO "Goodbye!\n"); } int seastone2_init(void) { int rc; rc = pci_register_driver(&pci_dev_ops); - if(rc) + if (rc) return rc; return 0; } @@ -2083,7 +2359,7 @@ void seastone2_exit(void) module_init(seastone2_init); module_exit(seastone2_exit); -MODULE_AUTHOR("Pradchaya P. pphuhcar@celestica.com"); -MODULE_DESCRIPTION("Celestica seastone2 platform driver"); +MODULE_AUTHOR("Pradchaya P. "); +MODULE_DESCRIPTION("Celestica Seastone2 switchboard driver"); MODULE_VERSION(MOD_VERSION); MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/setup.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/setup.py new file mode 100755 index 000000000000..b0c8d1d8c9b8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/setup.py @@ -0,0 +1,30 @@ +from setuptools import setup + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Celestica Platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Wirut Getbamrung', + maintainer_email='wgetbumr@celestica.com', + packages=[ + 'sonic_platform', + ], + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) + diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/__init__.py new file mode 100644 index 000000000000..7b86fa12b515 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +import chassis +import platform diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/chassis.py new file mode 100644 index 000000000000..41eff734407b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/chassis.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +try: + import sys + from sonic_platform_base.chassis_base import ChassisBase + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + CHASSIS_CONFIG = 'chassis.json' + THERMAL_CONFIG = 'thermal.json' + SFP_CONFIG = 'sfp.json' + PSU_CONFIG = 'psu.json' + FAN_CONFIG = 'fan.json' + COMPONENT_CONFIG = 'component.json' + + def __init__(self): + ChassisBase.__init__(self) + self._api_common = Common() + config_path = self._api_common.get_config_path(self.CHASSIS_CONFIG) + self._config = self._api_common.load_json_file(config_path) + + self.sfp_module_initialized = False + self.__initialize_eeprom() + + if not self._api_common.is_host(): + self.__initialize_fan() + self.__initialize_psu() + self.__initialize_thermals() + else: + self.__initialize_components() + + def __initialize_fan(self): + from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer + + fan_config_path = self._api_common.get_config_path(self.FAN_CONFIG) + self._fan_config = self._api_common.load_json_file(fan_config_path) + + if self._fan_config: + fan_index = 0 + for drawer_index in range(0, self._fan_config['drawer_num']): + drawer_fan_list = [] + for index in range(0, self._fan_config['fan_num_per_drawer']): + fan = Fan(fan_index, conf=self._fan_config) + fan_index += 1 + self._fan_list.append(fan) + drawer_fan_list.append(fan) + fan_drawer = FanDrawer(drawer_index, drawer_fan_list) + self._fan_drawer_list.append(fan_drawer) + + def __initialize_sfp(self): + from sonic_platform.sfp import Sfp + + sfp_config_path = self._api_common.get_config_path(self.SFP_CONFIG) + sfp_config = self._api_common.load_json_file(sfp_config_path) + + sfp_index = 0 + for index in range(0, sfp_config['port_num']): + sfp = Sfp(sfp_index, conf=sfp_config) + self._sfp_list.append(sfp) + sfp_index += 1 + self.sfp_module_initialized = True + + def __initialize_psu(self): + from sonic_platform.psu import Psu + + psu_config_path = self._api_common.get_config_path(self.PSU_CONFIG) + psu_config = self._api_common.load_json_file(psu_config_path) + + if psu_config: + psu_index = 0 + for index in range(0, psu_config['psu_num']): + psu = Psu(psu_index, conf=psu_config, + fan_conf=self._fan_config) + psu_index += 1 + self._psu_list.append(psu) + + def __initialize_thermals(self): + from sonic_platform.thermal import Thermal + + thermal_config_path = self._api_common.get_config_path( + self.THERMAL_CONFIG) + thermal_config = self._api_common.load_json_file(thermal_config_path) + + thermal_index = 0 + for index in range(0, thermal_config['thermal_num']): + thermal = Thermal(thermal_index, conf=thermal_config) + thermal_index += 1 + self._thermal_list.append(thermal) + + def __initialize_eeprom(self): + from sonic_platform.eeprom import Tlv + self._eeprom = Tlv(self._config) + + def __initialize_components(self): + from component import Component + + component_config_path = self._api_common.get_config_path( + self.COMPONENT_CONFIG) + component_config = self._api_common.load_json_file( + component_config_path) + + for index in range(0, component_config['component_num']): + component = Component(index, conf=component_config) + self._component_list.append(component) + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.get_mac() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.get_serial() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.get_eeprom() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + + Avaliable reboot cause: + REBOOT_CAUSE_POWER_LOSS = "Power Loss" + REBOOT_CAUSE_THERMAL_OVERLOAD_CPU = "Thermal Overload: CPU" + REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC = "Thermal Overload: ASIC" + REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER = "Thermal Overload: Other" + REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED = "Insufficient Fan Speed" + REBOOT_CAUSE_WATCHDOG = "Watchdog" + REBOOT_CAUSE_HARDWARE_OTHER = "Hardware - Other" + REBOOT_CAUSE_NON_HARDWARE = "Non-Hardware" + + """ + reboot_cause = self._api_common.get_output( + 0, self._config['get_reboot_cause'], self.REBOOT_CAUSE_HARDWARE_OTHER) + description = self._api_common.get_output( + 0, self._config['get_reboot_description'], 'Unknown') + + return (reboot_cause, description) + + # ############################################################## + # ######################## SFP methods ######################### + # ############################################################## + + def get_num_sfps(self): + """ + Retrieves the number of sfps available on this chassis + Returns: + An integer, the number of sfps available on this chassis + """ + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return len(self._sfp_list) + + def get_all_sfps(self): + """ + Retrieves all sfps available on this chassis + Returns: + A list of objects derived from SfpBase representing all sfps + available on this chassis + """ + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return self._sfp_list + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 1. + For example, 1 for Ethernet0, 2 for Ethernet4 and so on. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + if not self.sfp_module_initialized: + self.__initialize_sfp() + + try: + # The index will start from 1 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp + + ############################################################## + ###################### Event methods ######################### + ############################################################## + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + Specifically for SFP event, besides SFP plug in and plug out, + there are some other error event could be raised from SFP, when + these error happened, SFP eeprom will not be avalaible, XCVRD shall + stop to read eeprom before SFP recovered from error status. + status='2' I2C bus stuck, + status='3' Bad eeprom, + status='4' Unsupported cable, + status='5' High Temperature, + status='6' Bad cable. + """ + + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return self._api_common.get_event(timeout, self._config['get_change_event'], self._sfp_list) + + # ############################################################## + # ###################### Other methods ######################## + # ############################################################## + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + wdt = self._api_common.get_output( + 0, self._config['get_watchdog'], None) + self._watchdog = wdt() + + return self._watchdog + + # ############################################################## + # ###################### Device methods ######################## + # ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return self._api_common.hwsku + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._eeprom.get_pn() + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self._eeprom.get_serial() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/common.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/common.py new file mode 100644 index 000000000000..697308b8c3cf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/common.py @@ -0,0 +1,283 @@ +import os +import imp +import yaml +import subprocess + +from sonic_py_common import device_info + + +class Common: + + DEVICE_PATH = '/usr/share/sonic/device/' + PMON_PLATFORM_PATH = '/usr/share/sonic/platform/' + CONFIG_DIR = 'sonic_platform_config' + + OUTPUT_SOURCE_IPMI = 'ipmitool' + OUTPUT_SOURCE_GIVEN_LIST = 'value_list' + OUTPUT_SOURCE_GIVEN_VALUE = 'value' + OUTPUT_SOURCE_GIVEN_CLASS = 'class' + OUTPUT_SOURCE_SYSFS = 'sysfs_value' + OUTPUT_SOURCE_FUNC = 'function' + OUTPUT_SOURCE_GIVEN_TXT_FILE = 'txt_file' + OUTPUT_SOURCE_GIVEN_VER_HEX_FILE = 'hex_version_file' + OUTPUT_SOURCE_GIVEN_VER_HEX_ADDR = 'hex_version_getreg' + + SET_METHOD_IPMI = 'ipmitool' + NULL_VAL = 'N/A' + HOST_CHK_CMD = "docker > /dev/null 2>&1" + REF_KEY = '$ref:' + + def __init__(self, conf=None): + self._main_conf = conf + (self.platform, self.hwsku) = device_info.get_platform_and_hwsku() + + def _run_command(self, command): + status = False + output = "" + try: + p = subprocess.Popen( + command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + status, output = True, raw_data.strip() + except Exception: + pass + return status, output + + def _clean_input(self, input, config): + cleaned_input = input + + ai = config.get('avaliable_input') + if ai and input not in ai: + return None + + input_translator = config.get('input_translator') + if type(input_translator) is dict: + cleaned_input = input_translator.get(input) + + elif type(input_translator) is str: + cleaned_input = eval(input_translator.format(input)) + + return cleaned_input + + def _clean_output(self, index, output, config): + output_translator = config.get('output_translator') + + if type(output_translator) is dict: + output = output_translator.get(output) + elif type(output_translator) is str: + output = eval(output_translator.format(output)) + elif type(output_translator) is list: + output = eval(output_translator[index].format(output)) + + return output + + def _ipmi_get(self, index, config): + argument = config.get('argument') + cmd = config['command'].format( + config['argument'][index]) if argument else config['command'] + status, output = self._run_command(cmd) + return output if status else None + + def _sysfs_read(self, index, config): + sysfs_path = config.get('sysfs_path') + argument = config.get('argument', '') + + if self.REF_KEY in argument: + argument = self._main_conf[argument.split(":")[1]] + + if type(argument) is list: + sysfs_path = sysfs_path.format(argument[index]) + + content = "" + try: + content = open(sysfs_path) + content = content.readline().rstrip() + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + return content + + def _sysfs_write(self, index, config, input): + sysfs_path = config.get('sysfs_path') + argument = config.get('argument', '') + + if self.REF_KEY in argument: + argument = self._main_conf[argument.split(":")[1]] + + if type(argument) is list: + sysfs_path = sysfs_path.format(argument[index]) + + write_offset = int(config.get('write_offset', 0)) + output = "" + try: + open_file = open(sysfs_path, "r+") + open_file.seek(write_offset) + open_file.write(input) + open_file.close() + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False, output + return True, output + + def _ipmi_set(self, index, config, input): + arg = config['argument'][index].format(input) + return self._run_command(config['command'].format(arg)) + + def _hex_ver_decode(self, hver, num_of_bits, num_of_points): + ver_list = [] + c_bit = 0 + bin_val = bin(int(hver, 16))[2:].zfill(num_of_bits) + bit_split = num_of_bits / (num_of_points + 1) + for x in range(0, num_of_points+1): + split_bin = bin_val[c_bit:c_bit+bit_split] + ver_list.append(str(int(split_bin, 2))) + c_bit += bit_split + return '.'.join(ver_list) + + def _get_class(self, config): + """ + Retreives value of expected attribute + Returns: + A value of the attribute of object + """ + path = config['host_path'] if self.is_host() else config['pmon_path'] + module = imp.load_source(config['class'], path) + class_ = getattr(module, config['class']) + return class_ + + def get_reg(self, path, reg_addr): + cmd = "echo {1} > {0}; cat {0}".format(path, reg_addr) + status, output = self._run_command(cmd) + return output if status else None + + def read_txt_file(self, path): + with open(path, 'r') as f: + output = f.readline() + return output.strip('\n') + + def write_txt_file(self, file_path, value): + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except Exception: + return False + return True + + def is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def load_json_file(self, path): + """ + Retrieves the json object from json file path + + Returns: + A json object + """ + with open(path, 'r') as f: + json_data = yaml.safe_load(f) + + return json_data + + def get_config_path(self, config_name): + """ + Retrieves the path to platform api config directory + + Args: + config_name: A string containing the name of config file. + + Returns: + A string containing the path to json file + """ + return os.path.join(self.DEVICE_PATH, self.platform, self.CONFIG_DIR, config_name) if self.is_host() else os.path.join(self.PMON_PLATFORM_PATH, self.CONFIG_DIR, config_name) + + def get_output(self, index, config, default): + """ + Retrieves the output for each function base on config + + Args: + index: An integer containing the index of device. + config: A dict object containing the configuration of specified function. + default: A string containing the default output of specified function. + + Returns: + A string containing the output of specified function in config + """ + output_source = config.get('output_source') + + if output_source == self.OUTPUT_SOURCE_IPMI: + output = self._ipmi_get(index, config) + + elif output_source == self.OUTPUT_SOURCE_GIVEN_VALUE: + output = config["value"] + + elif output_source == self.OUTPUT_SOURCE_GIVEN_CLASS: + output = self._get_class(config) + + elif output_source == self.OUTPUT_SOURCE_GIVEN_LIST: + output = config["value_list"][index] + + elif output_source == self.OUTPUT_SOURCE_SYSFS: + output = self._sysfs_read(index, config) + + elif output_source == self.OUTPUT_SOURCE_FUNC: + func_conf = self._main_conf[config['function'][index]] + output = self.get_output(index, func_conf, default) + + elif output_source == self.OUTPUT_SOURCE_GIVEN_TXT_FILE: + path = config.get('path') + output = self.read_txt_file(path) + + elif output_source == self.OUTPUT_SOURCE_GIVEN_VER_HEX_FILE: + path = config.get('path') + hex_ver = self.read_txt_file(path) + output = self._hex_ver_decode( + hex_ver, config['num_of_bits'], config['num_of_points']) + + elif output_source == self.OUTPUT_SOURCE_GIVEN_VER_HEX_ADDR: + path = config.get('path') + addr = config.get('reg_addr') + hex_ver = self.get_reg(path, addr) + output = self._hex_ver_decode( + hex_ver, config['num_of_bits'], config['num_of_points']) + + else: + output = default + + return self._clean_output(index, output, config) or default + + def set_output(self, index, input, config): + """ + Sets the output of specified function on config + + Args: + config: A dict object containing the configuration of specified function. + index: An integer containing the index of device. + input: A string containing the input of specified function. + + Returns: + bool: True if set function is successfully, False if not + """ + cleaned_input = self._clean_input(input, config) + if not cleaned_input: + return False + + set_method = config.get('set_method') + if set_method == self.SET_METHOD_IPMI: + output = self._ipmi_set(index, config, cleaned_input)[0] + elif set_method == self.OUTPUT_SOURCE_SYSFS: + output = self._sysfs_write(index, config, cleaned_input)[0] + else: + output = False + + return output + + def get_event(self, timeout, config, sfp_list): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + """ + event_class = self._get_class(config) + return event_class(sfp_list).get_event(timeout) diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/component.py new file mode 100644 index 000000000000..958b34623222 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/component.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Component contains an implementation of SONiC Platform Base API and +# provides the components firmware management function +# +############################################################################# + +try: + from sonic_platform_base.component_base import ComponentBase + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Component(ComponentBase): + """Platform-specific Component class""" + + def __init__(self, component_index, conf): + ComponentBase.__init__(self) + + self._index = component_index + self._config = conf + self._api_common = Common(self._config) + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + default = 'N/A' + config = self._config["get_name"] + return self._api_common.get_output(self._index, config, default) + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + default = 'N/A' + config = self._config["get_description"] + return self._api_common.get_output(self._index, config, default) + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + Note: the firmware version will be read from HW + Returns: + A string containing the firmware version of the component + """ + default = 'N/A' + config = self._config["get_firmware_version"] + return self._api_common.get_output(self._index, config, default) diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/eeprom.py new file mode 100644 index 000000000000..53306c003474 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/eeprom.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import os + import sys + import re + from cStringIO import StringIO + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + +CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' +CACHE_FILE = 'syseeprom_cache' + + +class Tlv(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + DEFAULT_EEPROM_PATH = "/sys/class/i2c-adapter/i2c-12/12-0050/eeprom" + + def __init__(self, conf=None): + eeprom_path = conf.get('eeprom', self.DEFAULT_EEPROM_PATH) + super(Tlv, self).__init__(eeprom_path, 0, '', True) + + self._eeprom = self._load_eeprom() + + def _parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search( + '(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + if match is not None: + idx = match.group(1) + value = match.group(3).rstrip('\0') + + _eeprom_info_dict[idx] = value + except Exception: + pass + return _eeprom_info_dict + + def _load_eeprom(self): + original_stdout = sys.stdout + sys.stdout = StringIO() + try: + self.read_eeprom_db() + except Exception: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + return self._parse_output(decode_output) + + status = self.check_status() + if 'ok' not in status: + return False + + if not os.path.exists(CACHE_ROOT): + try: + os.makedirs(CACHE_ROOT) + except Exception: + pass + + # + # only the eeprom classes that inherit from eeprom_base + # support caching. Others will work normally + # + try: + self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) + except Exception: + pass + + e = self.read_eeprom() + if e is None: + return 0 + + try: + self.update_cache(e) + except Exception: + pass + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + # (is_valid, valid_crc) = self.is_checksum_valid(e) + # if not is_valid: + # return False + + return self._parse_output(decode_output) + + def get_eeprom(self): + return self._eeprom + + def get_serial(self): + return self._eeprom.get('0x23', "Undefined.") + + def get_mac(self): + return self._eeprom.get('0x24', "Undefined.") diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan.py new file mode 100644 index 000000000000..b0ebebccd3d7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.fan_base import FanBase + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, index, is_psu_fan=False, psu_index=0, conf=None): + FanBase.__init__(self) + + self._fan_index = index + self._config = conf + self._api_common = Common() + + self._is_psu_fan = is_psu_fan + if self._is_psu_fan: + self._initialize_psu_fan(psu_index) + + self._name = self.get_name() + + def _initialize_psu_fan(self, psu_index): + self._psu_index = psu_index + self._psu_fan_config = self._config['psu_fan'][self._psu_index] + + def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + return self._api_common.get_output(self._fan_index, self._config['get_direction'], self.FAN_DIRECTION_NOT_APPLICABLE) + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + speed = pwm_in/255*100 + """ + config = self._config['get_speed'] if not self._is_psu_fan else self._psu_fan_config['get_speed'] + max_rpm = config['max_rear'] if 'R' in self._name else config['max_front'] + raw_speed = self._api_common.get_output( + self._fan_index, config, 0) + + return int(float(raw_speed) / max_rpm * 100.0) + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + 0 : when PWM mode is not in use + pwm : when pwm mode is not use + """ + return self._api_common.get_output(self._fan_index, self._config['get_target_speed'], Common.NULL_VAL) + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return self._api_common.get_output(self._fan_index, self._config['get_speed_tolerance'], Common.NULL_VAL) + + def set_speed(self, speed): + """ + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + + Note: + Depends on pwm or target mode is selected: + 1) pwm = speed_pc * 255 <-- Currently use this mode. + 2) target_pwm = speed_pc * 100 / 255 + 2.1) set pwm{}_enable to 3 + + ipmitool raw 0x3a 0x0e 0x00 > enable auto fcs + ipmitool raw 0x3a 0x0e 0x01 > disable auto fcs + """ + if speed not in range(1, 101) or self._is_psu_fan: + return False + + return self._api_common.set_output(self._fan_index, speed, self._config['set_speed']) + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + + + Note: Required Manual Control LED mode ('ipmitool raw 0x3a 0x0f 0x2 0x0') + """ + config = self._config['set_status_led'] + avaliable_input = config.get('avaliable_input') + if (avaliable_input and color not in avaliable_input) or self._is_psu_fan: + return False + + return self._api_common.set_output(self._fan_index, color, config) + + def get_status_led(self): + """ + Gets the state of the fan status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + + Note: + STATUS_LED_COLOR_GREEN = "green" + STATUS_LED_COLOR_AMBER = "amber" + STATUS_LED_COLOR_RED = "red" + STATUS_LED_COLOR_OFF = "off" + """ + + default = self.STATUS_LED_COLOR_OFF + + if self._is_psu_fan: + return default + + return self._api_common.get_output(self._fan_index, self._config['get_status_led'], default) + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + config = self._config['get_name'] if not self._is_psu_fan else self._psu_fan_config['get_name'] + return self._api_common.get_output(self._fan_index, config, Common.NULL_VAL) + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + return self._api_common.get_output(self._fan_index, self._config['get_presence'], False) + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + default = Common.NULL_VAL + if self._is_psu_fan: + return default + return self._api_common.get_output(self._fan_index, self._config['get_model'], default) + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + default = Common.NULL_VAL + if self._is_psu_fan: + return default + return self._api_common.get_output(self._fan_index, self._config['get_serial'], default) + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and self.get_speed() > 10 diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..5ef283a105d4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan_drawer.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(FanDrawerBase): + + def __init__(self, index, fan_list): + FanDrawerBase.__init__(self) + + self._fan_list = fan_list + self._index = index + 1 + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + Args: + color: A string representing the color with which to set the + fan drawer status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + return self._fan_list[0].set_status_led(color) + + def get_status_led(self, color): + """ + Gets the state of the fan drawer LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + return self._fan_list[0].get_status_led() + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return 'Fan {}'.format(self._index) + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + return self._fan_list[0].get_presence() + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._fan_list[0].get_model() + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self._fan_list[0].get_serial() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self._fan_list[0].get_status() diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/platform.py new file mode 100644 index 000000000000..a632de87e742 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/platform.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/psu.py new file mode 100644 index 000000000000..68dfe201d33f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/psu.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the psu status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.psu_base import PsuBase + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Psu(PsuBase): + """Platform-specific Fan class""" + + def __init__(self, index, conf=None, fan_conf=None): + PsuBase.__init__(self) + + self._psu_index = index + self._config = conf + self._api_common = Common(self._config) + self._fan_conf = fan_conf + self._initialize_psu_fan() + + def _initialize_psu_fan(self): + from sonic_platform.fan import Fan + + num_fan = self._fan_conf['psu_fan'][self._psu_index]["num_of_fan"] + for fan_index in range(0, num_fan): + fan = Fan(fan_index, is_psu_fan=True, + psu_index=self._psu_index, conf=self._fan_conf) + self._fan_list.append(fan) + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + return self._api_common.get_output(self._psu_index, self._config['get_voltage'], 0.0) + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + return self._api_common.get_output(self._psu_index, self._config['get_current'], 0.0) + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, e.g. 302.6 + """ + return self._api_common.get_output(self._psu_index, self._config['get_current'], 0.0) + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self._api_common.get_output(self._psu_index, self._config['get_powergood_status'], False) + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Note: + Seastone2 CPLD able to set only AMBER color. + This function should be disable auto mode before execute + command: ipmitool raw 0x3a 0x0f 0x02 0x00 + Args: + color: A string representing the color with which to set the + PSU status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + return self._api_common.set_output(self._psu_index, color, self._config['set_status_led']) + + def get_status_led(self): + """ + Gets the state of the PSU status LED + Note: + Seastone2 PSU LED got only 2 mode, AMBER and Hardware control mode. + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + return self._api_common.get_output(self._psu_index, self._config['get_status_led'], Common.NULL_VAL) + + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + return self._api_common.get_output(self._psu_index, self._config['get_temperature'], 0.0) + + def get_temperature_high_threshold(self): + """ + Retrieves the high threshold temperature of PSU + Returns: + A float number, the high threshold temperature of PSU in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self._api_common.get_output(self._psu_index, self._config['get_temperature_high_threshold'], 0.0) + + def get_voltage_high_threshold(self): + """ + Retrieves the high threshold PSU voltage output + + Returns: + ucr as float number and return 0 if the BMC output is na. + A float number, the high threshold output voltage in volts, + e.g. 12.1 + """ + return self._api_common.get_output(self._psu_index, self._config['get_voltage_high_threshold'], 0.0) + + def get_voltage_low_threshold(self): + """ + Retrieves the low threshold PSU voltage output + + Returns: + lcr as float number and return 0 if the BMC output is na. + A float number, the low threshold output voltage in volts, + e.g. 12.1 + """ + return self._api_common.get_output(self._psu_index, self._config['get_voltage_low_threshold'], 0.0) + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return self._api_common.get_output(self._psu_index, self._config['get_name'], Common.NULL_VAL) + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + return self._api_common.get_output(self._psu_index, self._config['get_name'], False) + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._api_common.get_output(self._psu_index, self._config['get_model'], Common.NULL_VAL) + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self._api_common.get_output(self._psu_index, self._config['get_serial'], Common.NULL_VAL) + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_powergood_status() diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/sfp.py new file mode 100644 index 000000000000..17f2756dee1a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/sfp.py @@ -0,0 +1,2037 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the sfp status which are available in the platform +# +############################################################################# + +import time +from ctypes import create_string_buffer + +try: + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId + from sonic_platform_base.sonic_sfp.qsfp_dd import qsfp_dd_InterfaceId + from sonic_platform_base.sonic_sfp.qsfp_dd import qsfp_dd_Dom + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_EXT_SPECIFICATION_COMPLIANCE_OFFSET = 64 +XCVR_EXT_SPECIFICATION_COMPLIANCE_WIDTH = 1 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 2 + +XCVR_INTERFACE_DATA_START = 0 +XCVR_INTERFACE_DATA_SIZE = 92 + +QSFP_DOM_BULK_DATA_START = 22 +QSFP_DOM_BULK_DATA_SIZE = 36 +SFP_DOM_BULK_DATA_START = 96 +SFP_DOM_BULK_DATA_SIZE = 10 +QSFP_DD_DOM_BULK_DATA_START = 14 +QSFP_DD_DOM_BULK_DATA_SIZE = 4 + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 + +# definitions of the offset for values in QSFP_DD info eeprom +QSFP_DD_TYPE_OFFSET = 0 +QSFP_DD_VENDOR_NAME_OFFSET = 1 +QSFP_DD_VENDOR_PN_OFFSET = 20 +QSFP_DD_VENDOR_SN_OFFSET = 38 +QSFP_DD_VENDOR_OUI_OFFSET = 17 + +# definitions of the offset and width for values in XCVR_QSFP_DD info eeprom +XCVR_EXT_TYPE_OFFSET_QSFP_DD = 72 +XCVR_EXT_TYPE_WIDTH_QSFP_DD = 2 +XCVR_CONNECTOR_OFFSET_QSFP_DD = 75 +XCVR_CONNECTOR_WIDTH_QSFP_DD = 1 +XCVR_CABLE_LENGTH_OFFSET_QSFP_DD = 74 +XCVR_CABLE_LENGTH_WIDTH_QSFP_DD = 1 +XCVR_HW_REV_OFFSET_QSFP_DD = 36 +XCVR_HW_REV_WIDTH_QSFP_DD = 2 +XCVR_VENDOR_DATE_OFFSET_QSFP_DD = 54 +XCVR_VENDOR_DATE_WIDTH_QSFP_DD = 8 +XCVR_DOM_CAPABILITY_OFFSET_QSFP_DD = 2 +XCVR_DOM_CAPABILITY_WIDTH_QSFP_DD = 1 +XCVR_MEDIA_TYPE_OFFSET_QSFP_DD = 85 +XCVR_MEDIA_TYPE_WIDTH_QSFP_DD = 1 +XCVR_FIRST_APPLICATION_LIST_OFFSET_QSFP_DD = 86 +XCVR_FIRST_APPLICATION_LIST_WIDTH_QSFP_DD = 32 +XCVR_SECOND_APPLICATION_LIST_OFFSET_QSFP_DD = 351 +XCVR_SECOND_APPLICATION_LIST_WIDTH_QSFP_DD = 28 + +# Offset for values in QSFP eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_VERSION_COMPLIANCE_OFFSET = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_MODULE_MONITOR_OFFSET = 0 +QSFP_MODULE_MONITOR_WIDTH = 9 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_POWEROVERRIDE_BIT = 0 +QSFP_POWERSET_BIT = 1 +QSFP_OPTION_VALUE_OFFSET = 192 +QSFP_OPTION_VALUE_WIDTH = 4 +QSFP_MODULE_UPPER_PAGE3_START = 384 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 24 + +SFP_MODULE_ADDRA2_OFFSET = 256 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_CHANNL_STATUS_OFFSET = 110 +SFP_CHANNL_STATUS_WIDTH = 1 + +QSFP_DD_TEMPE_OFFSET = 14 +QSFP_DD_TEMPE_WIDTH = 2 +QSFP_DD_VOLT_OFFSET = 16 +QSFP_DD_VOLT_WIDTH = 2 +QSFP_DD_TX_BIAS_OFFSET = 42 +QSFP_DD_TX_BIAS_WIDTH = 16 +QSFP_DD_RX_POWER_OFFSET = 58 +QSFP_DD_RX_POWER_WIDTH = 16 +QSFP_DD_TX_POWER_OFFSET = 26 +QSFP_DD_TX_POWER_WIDTH = 16 +QSFP_DD_CHANNL_MON_OFFSET = 154 +QSFP_DD_CHANNL_MON_WIDTH = 48 +QSFP_DD_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_DD_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_DD_CHANNL_RX_LOS_STATUS_OFFSET = 19 +QSFP_DD_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_DD_CHANNL_TX_FAULT_STATUS_OFFSET = 7 +QSFP_DD_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_DD_MODULE_THRESHOLD_OFFSET = 0 +QSFP_DD_MODULE_THRESHOLD_WIDTH = 72 +QSFP_DD_CHANNL_STATUS_OFFSET = 26 +QSFP_DD_CHANNL_STATUS_WIDTH = 1 + + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +info_dict_keys = ['type', 'hardwarerev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', + 'vendor_date', 'vendor_oui', 'application_advertisement'] + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +dom_info_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'lp_mode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'rx5power', 'rx6power', 'rx7power', 'rx8power', + 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx5bias', 'tx6bias', 'tx7bias', 'tx8bias', + 'tx1power', 'tx2power', 'tx3power', 'tx4power', 'tx5power', 'tx6power', 'tx7power', 'tx8power'] + +threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', + 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + +SFP_TYPE_CODE_LIST = [ + '03' # SFP/SFP+/SFP28 +] +QSFP_TYPE_CODE_LIST = [ + '0d', # QSFP+ or later + '11' # QSFP28 or later +] +QSFP_DD_TYPE_CODE_LIST = [ + '18' # QSFP-DD Double Density 8X Pluggable Transceiver +] + +SFP_TYPE = "SFP" +QSFP_TYPE = "QSFP" +OSFP_TYPE = "OSFP" +QSFP_DD_TYPE = "QSFP_DD" + + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + def __init__(self, sfp_index=0, conf=None): + SfpBase.__init__(self) + + self._sfp_index = sfp_index + self._config = conf + self._api_common = Common(self._config) + + self._read_porttab_mappings() + self._dom_capability_detect() + + def _read_porttab_mappings(self): + self._sfputil_helper = SfpUtilHelper() + self._sfputil_helper.read_porttab_mappings( + self._get_path_to_port_config_file()) + + def _get_path_to_port_config_file(self): + host_platform_root_path = '/usr/share/sonic/device' + docker_hwsku_path = '/usr/share/sonic/hwsku' + + host_platform_path = "/".join([host_platform_root_path, + self._api_common.platform]) + hwsku_path = "/".join([host_platform_path, self._api_common.hwsku] + ) if self._api_common.is_host() else docker_hwsku_path + + return "/".join([hwsku_path, "port_config.ini"]) + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return Common.NULL_VAL + elif "Unknown" in value_str: + return Common.NULL_VAL + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return Common.NULL_VAL + + def _read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self._get_eeprom_path() + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except Exception: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def _detect_sfp_type(self): + sfp_type = QSFP_TYPE + eeprom_raw = [] + eeprom_raw = self._read_eeprom_specific_bytes( + XCVR_TYPE_OFFSET, XCVR_TYPE_WIDTH) + if eeprom_raw: + if eeprom_raw[0] in SFP_TYPE_CODE_LIST: + self.sfp_type = SFP_TYPE + elif eeprom_raw[0] in QSFP_TYPE_CODE_LIST: + self.sfp_type = QSFP_TYPE + elif eeprom_raw[0] in QSFP_DD_TYPE_CODE_LIST: + self.sfp_type = QSFP_DD_TYPE + else: + self.sfp_type = sfp_type + else: + self.sfp_type = sfp_type + + def _get_eeprom_path(self): + eeprom_path = self._config['eeprom_path'] + port_to_i2c_mapping = self._config['port_i2c_mapping'] + port_eeprom_path = eeprom_path.format( + port_to_i2c_mapping[self._sfp_index]) + + return port_eeprom_path + + def _dom_capability_detect(self): + if not self.get_presence(): + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + return + + self._detect_sfp_type() + + if self.sfp_type == QSFP_TYPE: + self.calibration = 1 + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + offset = 128 + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qsfp_version_compliance_raw = self._read_eeprom_specific_bytes( + QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH) + qsfp_version_compliance = int( + qsfp_version_compliance_raw[0], 16) + dom_capability = sfpi_obj.parse_qsfp_dom_capability( + qsfp_dom_capability_raw, 0) + if qsfp_version_compliance >= 0x08: + self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On' + self.dom_volt_supported = dom_capability['data']['Voltage_support']['value'] == 'On' + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' + self.dom_tx_power_supported = dom_capability['data']['Tx_power_support']['value'] == 'On' + else: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' + self.dom_tx_power_supported = True + + self.dom_supported = True + self.calibration = 1 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + qsfp_option_value_raw = self._read_eeprom_specific_bytes( + QSFP_OPTION_VALUE_OFFSET, QSFP_OPTION_VALUE_WIDTH) + if qsfp_option_value_raw is not None: + optional_capability = sfpd_obj.parse_option_params( + qsfp_option_value_raw, 0) + self.dom_tx_disable_supported = optional_capability[ + 'data']['TxDisable']['value'] == 'On' + dom_status_indicator = sfpd_obj.parse_dom_status_indicator( + qsfp_version_compliance_raw, 1) + self.qsfp_page3_available = dom_status_indicator['data']['FlatMem']['value'] == 'Off' + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.qsfp_page3_available = False + + elif self.sfp_type == QSFP_DD_TYPE: + sfpi_obj = qsfp_dd_InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + + offset = 0 + # two types of QSFP-DD cable types supported: Copper and Optical. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_DOM_CAPABILITY_OFFSET_QSFP_DD), XCVR_DOM_CAPABILITY_WIDTH_QSFP_DD) + if qsfp_dom_capability_raw is not None: + self.dom_temp_supported = True + self.dom_volt_supported = True + dom_capability = sfpi_obj.parse_qsfp_dom_capability( + qsfp_dom_capability_raw, 0) + if dom_capability['data']['Flat_MEM']['value'] == 'Off': + self.dom_supported = True + self.second_application_list = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + self.dom_tx_bias_power_supported = True + self.dom_thresholds_supported = True + # currently set to False becasue Page 11h is not supported by FW + self.dom_rx_tx_power_bias_supported = False + else: + self.dom_supported = False + self.second_application_list = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.dom_tx_bias_power_supported = False + self.dom_thresholds_supported = False + self.dom_rx_tx_power_bias_supported = False + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.dom_tx_bias_power_supported = False + self.dom_thresholds_supported = False + self.dom_rx_tx_power_bias_supported = False + + elif self.sfp_type == SFP_TYPE: + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + return None + sfp_dom_capability_raw = self._read_eeprom_specific_bytes( + XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) + self.dom_supported = (sfp_dom_capability & 0x40 != 0) + if self.dom_supported: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + if sfp_dom_capability & 0x20 != 0: + self.calibration = 1 + elif sfp_dom_capability & 0x10 != 0: + self.calibration = 2 + else: + self.calibration = 0 + else: + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.dom_tx_disable_supported = ( + int(sfp_dom_capability_raw[1], 16) & 0x40 != 0) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + + def get_name(self): + """ + Retrieves the human-readable name of a sfp by 1-based index + + Returns: + :param index: An integer, 1-based index of the sfp of which to query status + :return: String, + A string representing the name of the sfp. + """ + return self._sfputil_helper.logical[self._sfp_index] or "Unknown" + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + return self._api_common.get_output(self._sfp_index, self._config['get_presence'], False) + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("model", Common.NULL_VAL) + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("serial", Common.NULL_VAL) + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ================================================================================ + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + application_advertisement |1*255VCHAR |supported applications advertisement + ================================================================================ + """ + + transceiver_info_dict = {} + compliance_code_dict = {} + transceiver_info_dict = dict.fromkeys( + info_dict_keys, Common.NULL_VAL) + + # ToDo: OSFP tranceiver info parsing not fully supported. + # in inf8628.py lack of some memory map definition + # will be implemented when the inf8628 memory map ready + if self.sfp_type == OSFP_TYPE: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + + sfpi_obj = inf8628InterfaceId() + if sfpi_obj is None: + return None + + sfp_type_raw = self._read_eeprom_specific_bytes( + (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes( + (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + else: + return None + + transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + + elif self.sfp_type == QSFP_TYPE: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + elif self.sfp_type == QSFP_DD_TYPE: + offset = 128 + + sfpi_obj = qsfp_dd_InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + sfp_type_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_HW_REV_OFFSET_QSFP_DD), XCVR_HW_REV_WIDTH_QSFP_DD) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + else: + return None + + sfp_vendor_oui_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_vendor_oui_raw, 0) + else: + return None + + sfp_vendor_date_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_DATE_OFFSET_QSFP_DD), XCVR_VENDOR_DATE_WIDTH_QSFP_DD) + if sfp_vendor_date_raw is not None: + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_vendor_date_raw, 0) + else: + return None + + sfp_connector_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_CONNECTOR_OFFSET_QSFP_DD), XCVR_CONNECTOR_WIDTH_QSFP_DD) + if sfp_connector_raw is not None: + sfp_connector_data = sfpi_obj.parse_connector( + sfp_connector_raw, 0) + else: + return None + + sfp_ext_identifier_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_EXT_TYPE_OFFSET_QSFP_DD), XCVR_EXT_TYPE_WIDTH_QSFP_DD) + if sfp_ext_identifier_raw is not None: + sfp_ext_identifier_data = sfpi_obj.parse_ext_iden( + sfp_ext_identifier_raw, 0) + else: + return None + + sfp_cable_len_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_CABLE_LENGTH_OFFSET_QSFP_DD), XCVR_CABLE_LENGTH_WIDTH_QSFP_DD) + if sfp_cable_len_raw is not None: + sfp_cable_len_data = sfpi_obj.parse_cable_len( + sfp_cable_len_raw, 0) + else: + return None + + sfp_media_type_raw = self._read_eeprom_specific_bytes( + XCVR_MEDIA_TYPE_OFFSET_QSFP_DD, XCVR_MEDIA_TYPE_WIDTH_QSFP_DD) + if sfp_media_type_raw is not None: + sfp_media_type_dict = sfpi_obj.parse_media_type( + sfp_media_type_raw, 0) + if sfp_media_type_dict is None: + return None + + host_media_list = "" + sfp_application_type_first_list = self._read_eeprom_specific_bytes( + (XCVR_FIRST_APPLICATION_LIST_OFFSET_QSFP_DD), XCVR_FIRST_APPLICATION_LIST_WIDTH_QSFP_DD) + if self.second_application_list: + possible_application_count = 15 + sfp_application_type_second_list = self._read_eeprom_specific_bytes( + (XCVR_SECOND_APPLICATION_LIST_OFFSET_QSFP_DD), XCVR_SECOND_APPLICATION_LIST_WIDTH_QSFP_DD) + if sfp_application_type_first_list is not None and sfp_application_type_second_list is not None: + sfp_application_type_list = sfp_application_type_first_list + \ + sfp_application_type_second_list + else: + return None + else: + possible_application_count = 8 + if sfp_application_type_first_list is not None: + sfp_application_type_list = sfp_application_type_first_list + else: + return None + + for i in range(0, possible_application_count): + if sfp_application_type_list[i * 4] == 'ff': + break + host_electrical, media_interface = sfpi_obj.parse_application( + sfp_media_type_dict, sfp_application_type_list[i * 4], sfp_application_type_list[i * 4 + 1]) + host_media_list = host_media_list + host_electrical + \ + ' - ' + media_interface + '\n\t\t\t\t ' + else: + return None + + transceiver_info_dict['type'] = str( + sfp_type_data['data']['type']['value']) + transceiver_info_dict['manufacturer'] = str( + sfp_vendor_name_data['data']['Vendor Name']['value']) + transceiver_info_dict['model'] = str( + sfp_vendor_pn_data['data']['Vendor PN']['value']) + transceiver_info_dict['hardware_rev'] = str( + sfp_vendor_rev_data['data']['Vendor Rev']['value']) + transceiver_info_dict['serial'] = str( + sfp_vendor_sn_data['data']['Vendor SN']['value']) + transceiver_info_dict['vendor_oui'] = str( + sfp_vendor_oui_data['data']['Vendor OUI']['value']) + transceiver_info_dict['vendor_date'] = str( + sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value']) + transceiver_info_dict['connector'] = str( + sfp_connector_data['data']['Connector']['value']) + transceiver_info_dict['encoding'] = "Not supported for CMIS cables" + transceiver_info_dict['ext_identifier'] = str( + sfp_ext_identifier_data['data']['Extended Identifier']['value']) + transceiver_info_dict['ext_rateselect_compliance'] = "Not supported for CMIS cables" + transceiver_info_dict['specification_compliance'] = "Not supported for CMIS cables" + transceiver_info_dict['cable_type'] = "Length Cable Assembly(m)" + transceiver_info_dict['cable_length'] = str( + sfp_cable_len_data['data']['Length Cable Assembly(m)']['value']) + transceiver_info_dict['nominal_bit_rate'] = "Not supported for CMIS cables" + transceiver_info_dict['application_advertisement'] = host_media_list + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + if self.sfp_type != QSFP_DD_TYPE: + sfp_interface_bulk_raw = self._read_eeprom_specific_bytes( + offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) + if sfp_interface_bulk_raw is None: + return None + + start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START + end = start + interface_info_bulk_width + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_NAME_WIDTH + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_PN_WIDTH + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START + end = start + vendor_rev_width + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_SN_WIDTH + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_OUI_WIDTH + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_DATE_WIDTH + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_interface_bulk_raw[start: end], 0) + + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + + if self.sfp_type == QSFP_TYPE: + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + sfp_ext_specification_compliance_raw = self._read_eeprom_specific_bytes( + offset + XCVR_EXT_SPECIFICATION_COMPLIANCE_OFFSET, XCVR_EXT_SPECIFICATION_COMPLIANCE_WIDTH) + if sfp_ext_specification_compliance_raw is not None: + sfp_ext_specification_compliance_data = sfpi_obj.parse_ext_specification_compliance( + sfp_ext_specification_compliance_raw[0: 1], 0) + if sfp_ext_specification_compliance_data['data']['Extended Specification compliance']['value'] != "Unspecified": + compliance_code_dict['Extended Specification compliance'] = sfp_ext_specification_compliance_data[ + 'data']['Extended Specification compliance']['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + transceiver_dom_info_dict = dict.fromkeys( + dom_info_dict_keys, Common.NULL_VAL) + + if self.sfp_type == OSFP_TYPE: + pass + + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported: + return transceiver_dom_info_dict + + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_data_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DOM_BULK_DATA_START), QSFP_DOM_BULK_DATA_SIZE) + if dom_data_raw is None: + return transceiver_dom_info_dict + + if self.dom_temp_supported: + start = QSFP_TEMPE_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + temp = dom_temperature_data['data']['Temperature']['value'] + if temp is not None: + transceiver_dom_info_dict['temperature'] = temp + + if self.dom_volt_supported: + start = QSFP_VOLT_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + volt = dom_voltage_data['data']['Vcc']['value'] + if volt is not None: + transceiver_dom_info_dict['voltage'] = volt + + start = QSFP_CHANNL_MON_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_data_raw[start: end], 0) + + if self.dom_tx_power_supported: + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if self.dom_rx_power_supported: + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + elif self.sfp_type == QSFP_DD_TYPE: + + offset = 0 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_data_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_DOM_BULK_DATA_START), QSFP_DD_DOM_BULK_DATA_SIZE) + if dom_data_raw is None: + return transceiver_dom_info_dict + + if self.dom_temp_supported: + start = QSFP_DD_TEMPE_OFFSET - QSFP_DD_DOM_BULK_DATA_START + end = start + QSFP_DD_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + temp = dom_temperature_data['data']['Temperature']['value'] + if temp is not None: + transceiver_dom_info_dict['temperature'] = temp + + if self.dom_volt_supported: + start = QSFP_DD_VOLT_OFFSET - QSFP_DD_DOM_BULK_DATA_START + end = start + QSFP_DD_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + volt = dom_voltage_data['data']['Vcc']['value'] + if volt is not None: + transceiver_dom_info_dict['voltage'] = volt + + if self.dom_rx_tx_power_bias_supported: + # page 11h + dom_data_raw = self._read_eeprom_specific_bytes( + (QSFP_DD_CHANNL_MON_OFFSET), QSFP_DD_CHANNL_MON_WIDTH) + if dom_data_raw is None: + return transceiver_dom_info_dict + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_data_raw, 0) + + if self.dom_tx_power_supported: + transceiver_dom_info_dict['tx1power'] = str( + dom_channel_monitor_data['data']['TX1Power']['value']) + transceiver_dom_info_dict['tx2power'] = str( + dom_channel_monitor_data['data']['TX2Power']['value']) + transceiver_dom_info_dict['tx3power'] = str( + dom_channel_monitor_data['data']['TX3Power']['value']) + transceiver_dom_info_dict['tx4power'] = str( + dom_channel_monitor_data['data']['TX4Power']['value']) + transceiver_dom_info_dict['tx5power'] = str( + dom_channel_monitor_data['data']['TX5Power']['value']) + transceiver_dom_info_dict['tx6power'] = str( + dom_channel_monitor_data['data']['TX6Power']['value']) + transceiver_dom_info_dict['tx7power'] = str( + dom_channel_monitor_data['data']['TX7Power']['value']) + transceiver_dom_info_dict['tx8power'] = str( + dom_channel_monitor_data['data']['TX8Power']['value']) + + if self.dom_rx_power_supported: + transceiver_dom_info_dict['rx1power'] = str( + dom_channel_monitor_data['data']['RX1Power']['value']) + transceiver_dom_info_dict['rx2power'] = str( + dom_channel_monitor_data['data']['RX2Power']['value']) + transceiver_dom_info_dict['rx3power'] = str( + dom_channel_monitor_data['data']['RX3Power']['value']) + transceiver_dom_info_dict['rx4power'] = str( + dom_channel_monitor_data['data']['RX4Power']['value']) + transceiver_dom_info_dict['rx5power'] = str( + dom_channel_monitor_data['data']['RX5Power']['value']) + transceiver_dom_info_dict['rx6power'] = str( + dom_channel_monitor_data['data']['RX6Power']['value']) + transceiver_dom_info_dict['rx7power'] = str( + dom_channel_monitor_data['data']['RX7Power']['value']) + transceiver_dom_info_dict['rx8power'] = str( + dom_channel_monitor_data['data']['RX8Power']['value']) + + if self.dom_tx_bias_power_supported: + transceiver_dom_info_dict['tx1bias'] = str( + dom_channel_monitor_data['data']['TX1Bias']['value']) + transceiver_dom_info_dict['tx2bias'] = str( + dom_channel_monitor_data['data']['TX2Bias']['value']) + transceiver_dom_info_dict['tx3bias'] = str( + dom_channel_monitor_data['data']['TX3Bias']['value']) + transceiver_dom_info_dict['tx4bias'] = str( + dom_channel_monitor_data['data']['TX4Bias']['value']) + transceiver_dom_info_dict['tx5bias'] = str( + dom_channel_monitor_data['data']['TX5Bias']['value']) + transceiver_dom_info_dict['tx6bias'] = str( + dom_channel_monitor_data['data']['TX6Bias']['value']) + transceiver_dom_info_dict['tx7bias'] = str( + dom_channel_monitor_data['data']['TX7Bias']['value']) + transceiver_dom_info_dict['tx8bias'] = str( + dom_channel_monitor_data['data']['TX8Bias']['value']) + + return transceiver_dom_info_dict + + else: + if not self.dom_supported: + return transceiver_dom_info_dict + + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + sfpd_obj._calibration_type = self.calibration + + dom_data_raw = self._read_eeprom_specific_bytes( + (offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE) + + start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + + start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + + start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_CHANNL_MON_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_data_raw[start: end], 0) + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable() + transceiver_dom_info_dict['tx_disabled_channel'] = self.get_tx_disable_channel( + ) + + for key in transceiver_dom_info_dict: + val = transceiver_dom_info_dict[key] + transceiver_dom_info_dict[key] = self._convert_string_to_num( + val) if type(val) is str else val + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict = dict.fromkeys( + threshold_dict_keys, Common.NULL_VAL) + + if self.sfp_type == OSFP_TYPE: + pass + + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported or not self.qsfp_page3_available: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = QSFP_MODULE_UPPER_PAGE3_START + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values( + dom_module_threshold_raw, 0) + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is None: + return transceiver_dom_threshold_info_dict + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values( + dom_channel_threshold_raw, 0) + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + + elif self.sfp_type == QSFP_DD_TYPE: + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + if not self.dom_thresholds_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # page 02 + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_MODULE_THRESHOLD_OFFSET), QSFP_DD_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values( + dom_module_threshold_raw, 0) + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['TxBiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TxPowerLowWarning']['value'] + + else: + offset = SFP_MODULE_ADDRA2_OFFSET + + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = sff8472Dom(None, self.calibration) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[ + 'data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num( + transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + return self._api_common.get_output(self._sfp_index, self._config['get_reset_status'], False) + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + if not self.dom_supported: + return None + + rx_los_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 128 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_DD_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 8) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + rx_los_list.append(rx_los_data & 0x10 != 0) + rx_los_list.append(rx_los_data & 0x20 != 0) + rx_los_list.append(rx_los_data & 0x40 != 0) + rx_los_list.append(rx_los_data & 0x80 != 0) + + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x02 != 0) + else: + return None + return rx_los_list + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + if not self.dom_supported: + return None + + tx_fault_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 128 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_DD_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 8) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + tx_fault_list.append(tx_fault_data & 0x10 != 0) + tx_fault_list.append(tx_fault_data & 0x20 != 0) + tx_fault_list.append(tx_fault_data & 0x40 != 0) + tx_fault_list.append(tx_fault_data & 0x80 != 0) + + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + else: + return None + return tx_fault_list + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A list of boolean values, representing the TX disable status + of each available channel, value is True if SFP channel + is TX disabled, False if not. + E.g., for a tranceiver with four channels: [False, False, True, False] + """ + if not self.dom_supported: + return None + + tx_disable_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + if self.dom_rx_tx_power_bias_supported: + offset = 128 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_CHANNL_DISABLE_STATUS_OFFSET), QSFP_DD_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + tx_disable_list.append(tx_disable_data & 0x10 != 0) + tx_disable_list.append(tx_disable_data & 0x20 != 0) + tx_disable_list.append(tx_disable_data & 0x40 != 0) + tx_disable_list.append(tx_disable_data & 0x80 != 0) + + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0xC0 != 0) + else: + return None + return tx_disable_list + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + return tx_disabled + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + return self._api_common.get_output(self._sfp_index, self._config['get_lpmode'], False) + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + if self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_CONTROL_OFFSET), QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes( + dom_control_raw, 0) + return ('On' == dom_control_data['data']['PowerOverride']) + else: + return NotImplementedError + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + temp = self._convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + else: + return None + + elif self.sfp_type == QSFP_DD_TYPE: + offset = 0 + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_TEMPE_OFFSET), QSFP_DD_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + temp = self._convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + return temp + return None + + else: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = 1 + + dom_temperature_raw = self._read_eeprom_specific_bytes( + (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + temp = self._convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_volt_supported: + dom_voltage_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage( + dom_voltage_raw, 0) + voltage = self._convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + return None + + if self.sfp_type == QSFP_DD_TYPE: + offset = 128 + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_volt_supported: + dom_voltage_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_VOLT_OFFSET), QSFP_DD_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage( + dom_voltage_raw, 0) + voltage = self._convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + return voltage + return None + + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + sfpd_obj._calibration_type = self.calibration + + dom_voltage_raw = self._read_eeprom_specific_bytes( + (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + tx_bias_list = [] + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX4Bias']['value'])) + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 128 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if dom_tx_bias_power_supported: + dom_tx_bias_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_TX_BIAS_OFFSET), QSFP_DD_TX_BIAS_WIDTH) + if dom_tx_bias_raw is not None: + dom_tx_bias_data = sfpd_obj.parse_dom_tx_bias( + dom_tx_bias_raw, 0) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX4Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX5Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX6Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX7Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX8Bias']['value'])) + + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = self.calibration + + if self.dom_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TXBias']['value'])) + else: + return None + else: + return None + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX1Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX2Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX3Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX4Power']['value'])) + else: + return None + else: + return None + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11 + if self.dom_rx_tx_power_bias_supported: + offset = 128 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_rx_power_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_RX_POWER_OFFSET), QSFP_DD_RX_POWER_WIDTH) + if dom_rx_power_raw is not None: + dom_rx_power_data = sfpd_obj.parse_dom_rx_power( + dom_rx_power_raw, 0) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX1Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX2Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX3Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX4Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX5Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX6Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX7Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX8Power']['value'])) + + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value'])) + else: + return None + else: + return None + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX4Power']['value'])) + else: + return None + else: + return None + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11 + if self.dom_rx_tx_power_bias_supported: + offset = 128 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_tx_power_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_TX_POWER_OFFSET), QSFP_DD_TX_POWER_WIDTH) + if dom_tx_power_raw is not None: + dom_tx_power_data = sfpd_obj.parse_dom_tx_power( + dom_tx_power_raw, 0) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX4Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX5Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX6Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX7Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX8Power']['value'])) + + else: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value'])) + else: + return None + else: + return None + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + + Returns: + A boolean, True if successful, False if not + """ + config = self._config['reset'] + # Convert our register value back to a hex string and write back + output1 = self._api_common.set_output(self._sfp_index, "0x0", config) + + # Sleep 1 second to allow it to settle + time.sleep(1) + # Flip the bit back high and write back to the register to take port out of reset + output2 = self._api_common.set_output(self._sfp_index, "0x1", config) + + return True if (output1 and output2) else False + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + tx_disable_ctl = 0xf if tx_disable else 0x0 + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfs_sfp_i2c_client_eeprom_path = self._get_eeprom_path() + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + + Returns: + A boolean, True if successful, False if not + """ + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + channel_state = self.get_tx_disable_channel() + tx_enable_mask = [0xe, 0xd, 0xb, 0x7] + tx_disable_mask = [0x1, 0x3, 0x7, 0xf] + tx_disable_ctl = channel_state | tx_disable_mask[ + channel] if disable else channel_state & tx_enable_mask[channel] + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfs_sfp_i2c_client_eeprom_path = self._get_eeprom_path() + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + return self._api_common.set_output(self._sfp_index, str(lpmode), self._config['set_lpmode']) + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + sysfs_sfp_i2c_client_eeprom_path = self._get_eeprom_path() + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + + return False diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/thermal.py new file mode 100644 index 000000000000..714e073db37d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/thermal.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the thermal status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.thermal_base import ThermalBase + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """Platform-specific Thermal class""" + + def __init__(self, index, _thermal_index=0, conf=None): + ThermalBase.__init__(self) + + self._thermal_index = index + self._config = conf + self._api_common = Common(self._config) + + def get_name(self): + """ + Retrieves the human-readable name of a thermal sensor by 1-based index + + Returns: + :param index: An integer, 1-based index of the thermal sensor of which to query status + :return: String, + A string representing the name of the thermal sensor. + """ + return self._api_common.get_output(self._thermal_index, self._config['get_name'], Common.NULL_VAL) + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + by using command ipmitool raw 0x04 0x2D [address] + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + output = self._api_common.get_output( + self._thermal_index, self._config['get_temperature'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self._api_common.get_output( + self._thermal_index, self._config['get_high_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + lnc as float number and return 0 if the BMC output is na. + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self._api_common.get_output( + self._thermal_index, self._config['get_low_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + For AMI BMC device : + use ipmitool command + ipmitool sensor thresh [sensor name] unc [0>= temp_value <=62] + if the current value of unc is 'na' ipmitool can't be set the value + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + output = self._api_common.get_output( + self._thermal_index, self._config['set_high_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + For AMI BMC device : + use ipmitool command + ipmitool sensor thresh [sensor name] lnc [temp_value] + if the current value of lnc is 'na' ipmitool can't be set the value + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + output = self._api_common.get_output( + self._thermal_index, self._config['set_low_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + ucr as float number and return 0 if the BMC output is na. + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self._api_common.get_output( + self._thermal_index, self._config['get_high_critical_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of thermal + + Returns: + lnr as float number and return 0 if the BMC output is na. + A float number, the low critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self._api_common.get_output( + self._thermal_index, self._config['get_low_critical_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return Common.NULL_VAL + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + return Common.NULL_VAL + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True From 41dcdc6f49ae6a043a426364f103182cabf54d7f Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Wed, 9 Sep 2020 11:41:35 -0700 Subject: [PATCH 1107/1427] [Arista] Update driver submodules (#5296) - Finish the refactor of the smbus backend (huge performance enhencement) - Split scd-hwmon kernel module in multiple source files - Add new scd-uart driver to manage linecard consoles within a chassis - Bootstrap of thermal platform API implementation - Fix psud led error message - Fix fan led color on Smartsville --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 77d887095c33..6de446114d0e 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 77d887095c331ddff0bc681edfc6a6dd66d96228 +Subproject commit 6de446114d0e2bfaa100bab42897f6f1192e2723 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 77d887095c33..6de446114d0e 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 77d887095c331ddff0bc681edfc6a6dd66d96228 +Subproject commit 6de446114d0e2bfaa100bab42897f6f1192e2723 From 12f864a92e68d6a710dfa539b0aab2108d477ae8 Mon Sep 17 00:00:00 2001 From: Petro Bratash <68950226+bratashX@users.noreply.github.com> Date: Wed, 9 Sep 2020 22:33:13 +0300 Subject: [PATCH 1108/1427] [BFN] Fix vulnerability in eeprom.py (#5333) Due to https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation, yaml.load(input) is deprecated. Added a specifying parameter to fix this issue. Signed-off-by: Petro Bratash --- .../barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py index d50380b97cfd..937cc003f60e 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py @@ -82,7 +82,7 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): with open(os.path.dirname(__file__) + "/logging.conf", 'r') as f: - config_dict = yaml.load(f) + config_dict = yaml.load(f, yaml.SafeLoader) logging.config.dictConfig(config_dict) if not os.path.exists(os.path.dirname(EEPROM_SYMLINK)): From 1bf6fdc6d27027b24f64f7d5d0eedc5cc1bb69a5 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Wed, 9 Sep 2020 18:37:01 -0700 Subject: [PATCH 1109/1427] [dhcpmon] Monitor Mgmt Interface For DHCP Packets (#5317) When BGP routes are missing, DHCP packets get relayed over mgmt interface. This results in dhcpmon alerting that DHCP packets are not being relayed. This is PR include mgmt interface as uplink device, and so, if DHCP packet gets relayed over mgmt interface, regular dhcpmon alert will not be issues. Instead, dhcpmon will check the mgmt interface counts and issue a separate alert regarding packets travelling through mgmt network. In addition, this PR includes the following enhancements: 1. Add SIGUSR1 handler that prints out current packet counts 2. Increase alert grace window to 3 minutes from currently 2 minutes 3. Time is now computed more accurately 4. Print vlan name before counters signed-off-by: Tamer Ahmed --- .../docker-dhcp-relay.supervisord.conf.j2 | 5 + src/dhcpmon/src/dhcp_device.c | 285 ++++++++++++------ src/dhcpmon/src/dhcp_device.h | 73 ++++- src/dhcpmon/src/dhcp_devman.c | 86 ++++-- src/dhcpmon/src/dhcp_devman.h | 41 ++- src/dhcpmon/src/dhcp_mon.c | 101 +++++-- src/dhcpmon/src/main.c | 8 +- .../docker-dhcp-relay.supervisord.conf | 2 +- 8 files changed, 445 insertions(+), 156 deletions(-) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index 2efac176fabe..ae5af58ba80d 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -137,6 +137,11 @@ command=/usr/sbin/dhcpmon -id {{ vlan_name }} {% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %} {% if prefix | ipv4 %} -iu {{ name }}{% endif -%} {% endfor %} +{% if MGMT_INTERFACE %} +{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} -im {{ name }}{% endif %} +{% endfor %} +{% endif %} priority=4 autostart=false diff --git a/src/dhcpmon/src/dhcp_device.c b/src/dhcpmon/src/dhcp_device.c index 554a1dcf0a97..84ec9be9b65e 100644 --- a/src/dhcpmon/src/dhcp_device.c +++ b/src/dhcpmon/src/dhcp_device.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,9 @@ #include "dhcp_device.h" +/** Counter print width */ +#define DHCP_COUNTER_WIDTH 10 + /** Start of Ether header of a captured frame */ #define ETHER_START_OFFSET 0 /** Start of IP header of a captured frame */ @@ -36,21 +40,6 @@ /** Offset of DHCP GIADDR */ #define DHCP_GIADDR_OFFSET 24 -/** - * DHCP message types - **/ -typedef enum -{ - DHCP_MESSAGE_TYPE_DISCOVER = 1, - DHCP_MESSAGE_TYPE_OFFER = 2, - DHCP_MESSAGE_TYPE_REQUEST = 3, - DHCP_MESSAGE_TYPE_DECLINE = 4, - DHCP_MESSAGE_TYPE_ACK = 5, - DHCP_MESSAGE_TYPE_NAK = 6, - DHCP_MESSAGE_TYPE_RELEASE = 7, - DHCP_MESSAGE_TYPE_INFORM = 8 -} dhcp_message_type; - #define OP_LDHA (BPF_LD | BPF_H | BPF_ABS) /** bpf ldh Abs */ #define OP_LDHI (BPF_LD | BPF_H | BPF_IND) /** bpf ldh Ind */ #define OP_LDB (BPF_LD | BPF_B | BPF_ABS) /** bpf ldb Abs*/ @@ -95,17 +84,21 @@ static struct sock_fprog dhcp_sock_bfp = { .len = sizeof(dhcp_bpf_code) / sizeof(*dhcp_bpf_code), .filter = dhcp_bpf_code }; -/** global aggregate counter for DHCP interfaces */ -static dhcp_device_counters_t glob_counters[DHCP_DIR_COUNT] = { - [DHCP_RX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, - [DHCP_TX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, +/** Aggregate device of DHCP interfaces. It contains aggregate counters from + all interfaces + */ +static dhcp_device_context_t aggregate_dev = {0}; + +/** Monitored DHCP message type */ +static dhcp_message_type_t monitored_msgs[] = { + DHCP_MESSAGE_TYPE_DISCOVER, + DHCP_MESSAGE_TYPE_OFFER, + DHCP_MESSAGE_TYPE_REQUEST, + DHCP_MESSAGE_TYPE_ACK }; -/** global aggregate counter snapshot for DHCP interfaces */ -static dhcp_device_counters_t glob_counters_snapshot[DHCP_DIR_COUNT] = { - [DHCP_RX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, - [DHCP_TX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, -}; +/** Number of monitored DHCP message type */ +static uint8_t monitored_msg_sz = sizeof(monitored_msgs) / sizeof(*monitored_msgs); /** * @code handle_dhcp_option_53(context, dhcp_option, dir, iphdr, dhcphdr); @@ -129,43 +122,30 @@ static void handle_dhcp_option_53(dhcp_device_context_t *context, in_addr_t giaddr; switch (dhcp_option[2]) { + // DHCP messages send by client case DHCP_MESSAGE_TYPE_DISCOVER: - giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 | - dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]); - context->counters[dir].discover++; - if ((context->vlan_ip == giaddr && context->is_uplink && dir == DHCP_TX) || - (!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) { - glob_counters[dir].discover++; - } - break; - case DHCP_MESSAGE_TYPE_OFFER: - context->counters[dir].offer++; - if ((context->vlan_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) || - (!context->is_uplink && dir == DHCP_TX)) { - glob_counters[dir].offer++; - } - break; case DHCP_MESSAGE_TYPE_REQUEST: + case DHCP_MESSAGE_TYPE_DECLINE: + case DHCP_MESSAGE_TYPE_RELEASE: + case DHCP_MESSAGE_TYPE_INFORM: giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 | dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]); - context->counters[dir].request++; if ((context->vlan_ip == giaddr && context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) { - glob_counters[dir].request++; + context->counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++; + aggregate_dev.counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++; } break; + // DHCP messages send by server + case DHCP_MESSAGE_TYPE_OFFER: case DHCP_MESSAGE_TYPE_ACK: - context->counters[dir].ack++; + case DHCP_MESSAGE_TYPE_NAK: if ((context->vlan_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) || (!context->is_uplink && dir == DHCP_TX)) { - glob_counters[dir].ack++; + context->counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++; + aggregate_dev.counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++; } break; - case DHCP_MESSAGE_TYPE_DECLINE: - case DHCP_MESSAGE_TYPE_NAK: - case DHCP_MESSAGE_TYPE_RELEASE: - case DHCP_MESSAGE_TYPE_INFORM: - break; default: syslog(LOG_WARNING, "handle_dhcp_option_53(%s): Unknown DHCP option 53 type %d", context->intf, dhcp_option[2]); break; @@ -242,62 +222,166 @@ static void read_callback(int fd, short event, void *arg) } /** - * @code dhcp_device_validate(counters, counters_snapshot); + * @code dhcp_device_is_dhcp_inactive(counters); + * + * @brief Check if there were no DHCP activity + * + * @param counters current/snapshot counter + * + * @return true if there were no DHCP activity, false otherwise + */ +static bool dhcp_device_is_dhcp_inactive(uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) +{ + uint64_t *rx_counters = counters[DHCP_COUNTERS_CURRENT][DHCP_RX]; + uint64_t *rx_counter_snapshot = counters[DHCP_COUNTERS_SNAPSHOT][DHCP_RX]; + + bool rv = true; + for (uint8_t i = 0; (i < monitored_msg_sz) && rv; i++) { + rv = rx_counters[monitored_msgs[i]] == rx_counter_snapshot[monitored_msgs[i]]; + } + + return rv; +} + +/** + * @code dhcp_device_is_dhcp_msg_unhealthy(type, counters); + * + * @brief Check if DHCP relay is functioning properly for message of type 'type'. + * For every rx of message 'type', there should be increment of the same message type. + * + * @param type DHCP message type + * @param counters current/snapshot counter + * + * @return true if DHCP message 'type' is transmitted,false otherwise + */ +static bool dhcp_device_is_dhcp_msg_unhealthy(dhcp_message_type_t type, + uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) +{ + // check if DHCP message 'type' is being relayed + return ((counters[DHCP_COUNTERS_CURRENT][DHCP_RX][type] > counters[DHCP_COUNTERS_SNAPSHOT][DHCP_RX][type]) && + (counters[DHCP_COUNTERS_CURRENT][DHCP_TX][type] <= counters[DHCP_COUNTERS_SNAPSHOT][DHCP_TX][type]) ); +} + +/** + * @code dhcp_device_check_positive_health(counters, counters_snapshot); + * + * @brief Check if DHCP relay is functioning properly for monitored messages (Discover, Offer, Request, ACK.) + * For every rx of monitored messages, there should be increment of the same message type. + * + * @param counters current/snapshot counter + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +static dhcp_mon_status_t dhcp_device_check_positive_health(uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) +{ + dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY; + + bool is_dhcp_unhealthy = false; + for (uint8_t i = 0; (i < monitored_msg_sz) && !is_dhcp_unhealthy; i++) { + is_dhcp_unhealthy = dhcp_device_is_dhcp_msg_unhealthy(monitored_msgs[i], counters); + } + + // if we have rx DORA then we should have corresponding tx DORA (DORA being relayed) + if (is_dhcp_unhealthy) { + rv = DHCP_MON_STATUS_UNHEALTHY; + } + + return rv; +} + +/** + * @code dhcp_device_check_negative_health(counters); * - * @brief validate current interface counters by comparing aggregate counter with snapshot counters. + * @brief Check that DHCP relayed messages are not being transmitted out of this interface/dev + * using its counters. The interface is negatively healthy if there are not DHCP message + * travelling through it. * * @param counters recent interface counter * @param counters_snapshot snapshot counters * * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE */ -static dhcp_mon_status_t dhcp_device_validate(dhcp_device_counters_t *counters, - dhcp_device_counters_t *counters_snapshot) +static dhcp_mon_status_t dhcp_device_check_negative_health(uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) { dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY; - if ((counters[DHCP_RX].discover == counters_snapshot[DHCP_RX].discover) && - (counters[DHCP_RX].offer == counters_snapshot[DHCP_RX].offer ) && - (counters[DHCP_RX].request == counters_snapshot[DHCP_RX].request ) && - (counters[DHCP_RX].ack == counters_snapshot[DHCP_RX].ack ) ) { + uint64_t *tx_counters = counters[DHCP_COUNTERS_CURRENT][DHCP_TX]; + uint64_t *tx_counter_snapshot = counters[DHCP_COUNTERS_SNAPSHOT][DHCP_TX]; + + bool is_dhcp_unhealthy = false; + for (uint8_t i = 0; (i < monitored_msg_sz) && !is_dhcp_unhealthy; i++) { + is_dhcp_unhealthy = tx_counters[monitored_msgs[i]] > tx_counter_snapshot[monitored_msgs[i]]; + } + + // for negative validation, return unhealthy if DHCP packet are being + // transmitted out of the device/interface + if (is_dhcp_unhealthy) { + rv = DHCP_MON_STATUS_UNHEALTHY; + } + + return rv; +} + +/** + * @code dhcp_device_check_health(check_type, counters, counters_snapshot); + * + * @brief Check that DHCP relay is functioning properly given a check type. Positive check + * indicates for every rx of DHCP message of type 'type', there would increment of + * the corresponding TX of the same message type. While negative check indicates the + * device should not be actively transmitting any DHCP messages. If it does, it is + * considered unhealthy. + * + * @param check_type type of health check + * @param counters current/snapshot counter + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +static dhcp_mon_status_t dhcp_device_check_health(dhcp_mon_check_t check_type, + uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) +{ + dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY; + + if (dhcp_device_is_dhcp_inactive(aggregate_dev.counters)) { rv = DHCP_MON_STATUS_INDETERMINATE; - } else { - // if we have rx DORA then we should have corresponding tx DORA (DORA being relayed) - if (((counters[DHCP_RX].discover > counters_snapshot[DHCP_RX].discover) && - (counters[DHCP_TX].discover <= counters_snapshot[DHCP_TX].discover) ) || - ((counters[DHCP_RX].offer > counters_snapshot[DHCP_RX].offer ) && - (counters[DHCP_TX].offer <= counters_snapshot[DHCP_TX].offer ) ) || - ((counters[DHCP_RX].request > counters_snapshot[DHCP_RX].request ) && - (counters[DHCP_TX].request <= counters_snapshot[DHCP_TX].request ) ) || - ((counters[DHCP_RX].ack > counters_snapshot[DHCP_RX].ack ) && - (counters[DHCP_TX].ack <= counters_snapshot[DHCP_TX].ack ) ) ) { - rv = DHCP_MON_STATUS_UNHEALTHY; - } + } else if (check_type == DHCP_MON_CHECK_POSITIVE) { + rv = dhcp_device_check_positive_health(counters); + } else if (check_type == DHCP_MON_CHECK_NEGATIVE) { + rv = dhcp_device_check_negative_health(counters); } return rv; } /** - * @code dhcp_print_counters(counters); + * @code dhcp_print_counters(vlan_intf, counters); * * @brief prints DHCP counters to sylsog. * * @param counters interface counter */ -static void dhcp_print_counters(dhcp_device_counters_t *counters) +static void dhcp_print_counters(const char *vlan_intf, uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) { - syslog(LOG_NOTICE, "DHCP Discover rx: %lu, tx:%lu, Offer rx: %lu, tx:%lu, Request rx: %lu, tx:%lu, ACK rx: %lu, tx:%lu\n", - counters[DHCP_RX].discover, counters[DHCP_TX].discover, - counters[DHCP_RX].offer, counters[DHCP_TX].offer, - counters[DHCP_RX].request, counters[DHCP_TX].request, - counters[DHCP_RX].ack, counters[DHCP_TX].ack); + uint64_t *rx_counters = counters[DHCP_COUNTERS_CURRENT][DHCP_RX]; + uint64_t *tx_counters = counters[DHCP_COUNTERS_CURRENT][DHCP_TX]; + + syslog(LOG_NOTICE, + "[%*s] DHCP Discover rx/tx: %*lu/%*lu, Offer rx/tx: %*lu/%*lu, " + "Request rx/tx: %*lu/%*lu, ACK rx/tx: %*lu/%*lu\n", + IF_NAMESIZE, vlan_intf, + DHCP_COUNTER_WIDTH, rx_counters[DHCP_MESSAGE_TYPE_DISCOVER], + DHCP_COUNTER_WIDTH, tx_counters[DHCP_MESSAGE_TYPE_DISCOVER], + DHCP_COUNTER_WIDTH, rx_counters[DHCP_MESSAGE_TYPE_OFFER], + DHCP_COUNTER_WIDTH, tx_counters[DHCP_MESSAGE_TYPE_OFFER], + DHCP_COUNTER_WIDTH, rx_counters[DHCP_MESSAGE_TYPE_REQUEST], + DHCP_COUNTER_WIDTH, tx_counters[DHCP_MESSAGE_TYPE_REQUEST], + DHCP_COUNTER_WIDTH, rx_counters[DHCP_MESSAGE_TYPE_ACK], + DHCP_COUNTER_WIDTH, tx_counters[DHCP_MESSAGE_TYPE_ACK]); } /** * @code init_socket(context, intf); * - * @brief initializes socket, bind it to interface and bpf prgram, and + * @brief initializes socket, bind it to interface and bpf program, and * associate with libevent base * * @param context pointer to device (interface) context @@ -403,6 +487,18 @@ int dhcp_device_get_ip(dhcp_device_context_t *context, in_addr_t *ip) return rv; } +/** + * @code dhcp_device_get_aggregate_context(); + * + * @brief Accessor method + * + * @return pointer to aggregate device (interface) context + */ +dhcp_device_context_t* dhcp_device_get_aggregate_context() +{ + return &aggregate_dev; +} + /** * @code dhcp_device_init(context, intf, is_uplink); * @@ -422,8 +518,7 @@ int dhcp_device_init(dhcp_device_context_t **context, const char *intf, uint8_t dev_context->is_uplink = is_uplink; - memset(&dev_context->counters, 0, sizeof(dev_context->counters)); - memset(&dev_context->counters_snapshot, 0, sizeof(dev_context->counters_snapshot)); + memset(dev_context->counters, 0, sizeof(dev_context->counters)); *context = dev_context; rv = 0; @@ -498,36 +593,44 @@ void dhcp_device_shutdown(dhcp_device_context_t *context) } /** - * @code dhcp_device_get_status(context); + * @code dhcp_device_get_status(check_type, context); * * @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate * status */ -dhcp_mon_status_t dhcp_device_get_status(dhcp_device_context_t *context) +dhcp_mon_status_t dhcp_device_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context) { - dhcp_mon_status_t rv = 0; + dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY; if (context != NULL) { - rv = dhcp_device_validate(context->counters, context->counters_snapshot); - memcpy(context->counters_snapshot, context->counters, sizeof(context->counters_snapshot)); - } else { - rv = dhcp_device_validate(glob_counters, glob_counters_snapshot); - memcpy(glob_counters_snapshot, glob_counters, sizeof(glob_counters_snapshot)); + rv = dhcp_device_check_health(check_type, context->counters); } return rv; } /** - * @code dhcp_device_print_status(); + * @code dhcp_device_update_snapshot(context); + * + * @brief Update device/interface counters snapshot + */ +void dhcp_device_update_snapshot(dhcp_device_context_t *context) +{ + if (context != NULL) { + memcpy(context->counters[DHCP_COUNTERS_SNAPSHOT], + context->counters[DHCP_COUNTERS_CURRENT], + sizeof(context->counters[DHCP_COUNTERS_SNAPSHOT])); + } +} + +/** + * @code dhcp_device_print_status(context); * - * @brief prints status counters to syslog. If context is null, it will print aggregate status + * @brief prints status counters to syslog. */ void dhcp_device_print_status(dhcp_device_context_t *context) { if (context != NULL) { - dhcp_print_counters(context->counters); - } else { - dhcp_print_counters(glob_counters); + dhcp_print_counters(context->intf, context->counters); } } diff --git a/src/dhcpmon/src/dhcp_device.h b/src/dhcpmon/src/dhcp_device.h index bc1582d46a82..9eee6691017f 100644 --- a/src/dhcpmon/src/dhcp_device.h +++ b/src/dhcpmon/src/dhcp_device.h @@ -17,6 +17,23 @@ #include +/** + * DHCP message types + **/ +typedef enum +{ + DHCP_MESSAGE_TYPE_DISCOVER = 1, + DHCP_MESSAGE_TYPE_OFFER = 2, + DHCP_MESSAGE_TYPE_REQUEST = 3, + DHCP_MESSAGE_TYPE_DECLINE = 4, + DHCP_MESSAGE_TYPE_ACK = 5, + DHCP_MESSAGE_TYPE_NAK = 6, + DHCP_MESSAGE_TYPE_RELEASE = 7, + DHCP_MESSAGE_TYPE_INFORM = 8, + + DHCP_MESSAGE_TYPE_COUNT +} dhcp_message_type_t; + /** packet direction */ typedef enum { @@ -26,6 +43,15 @@ typedef enum DHCP_DIR_COUNT } dhcp_packet_direction_t; +/** counters type */ +typedef enum +{ + DHCP_COUNTERS_CURRENT, /** DHCP current counters */ + DHCP_COUNTERS_SNAPSHOT, /** DHCP snapshot counters */ + + DHCP_COUNTERS_COUNT +} dhcp_counters_type_t; + /** dhcp health status */ typedef enum { @@ -34,14 +60,12 @@ typedef enum DHCP_MON_STATUS_INDETERMINATE, /** DHCP relay health could not be determined */ } dhcp_mon_status_t; -/** DHCP device (interface) health counters */ -typedef struct +/** dhcp check type */ +typedef enum { - uint64_t discover; /** DHCP discover packets */ - uint64_t offer; /** DHCP offer packets */ - uint64_t request; /** DHCP request packets */ - uint64_t ack; /** DHCP ack packets */ -} dhcp_device_counters_t; + DHCP_MON_CHECK_NEGATIVE, /** Presence of relayed DHCP packets activity is flagged as unhealthy state */ + DHCP_MON_CHECK_POSITIVE, /** Validate that received DORA packets are relayed */ +} dhcp_mon_check_t; /** DHCP device (interface) context */ typedef struct @@ -54,10 +78,8 @@ typedef struct char intf[IF_NAMESIZE]; /** device (interface) name */ uint8_t *buffer; /** buffer used to read socket data */ size_t snaplen; /** snap length or buffer size */ - dhcp_device_counters_t counters[DHCP_DIR_COUNT]; - /** current coutners of DORA packets */ - dhcp_device_counters_t counters_snapshot[DHCP_DIR_COUNT]; - /** counter snapshot */ + uint64_t counters[DHCP_COUNTERS_COUNT][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]; + /** current/snapshot counters of DHCP packets */ } dhcp_device_context_t; /** @@ -72,6 +94,15 @@ typedef struct */ int dhcp_device_get_ip(dhcp_device_context_t *context, in_addr_t *ip); +/** + * @code dhcp_device_get_aggregate_context(); + * + * @brief Accessor method + * + * @return pointer to aggregate device (interface) context + */ +dhcp_device_context_t* dhcp_device_get_aggregate_context(); + /** * @code dhcp_device_init(context, intf, is_uplink); * @@ -116,22 +147,34 @@ int dhcp_device_start_capture(dhcp_device_context_t *context, void dhcp_device_shutdown(dhcp_device_context_t *context); /** - * @code dhcp_device_get_status(context); + * @code dhcp_device_get_status(check_type, context); * * @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate * status * - * @param context Device (interface) context + * @param check_type Type of validation + * @param context Device (interface) context * * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE */ -dhcp_mon_status_t dhcp_device_get_status(dhcp_device_context_t *context); +dhcp_mon_status_t dhcp_device_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context); + +/** + * @code dhcp_device_update_snapshot(context); + * + * @param context Device (interface) context + * + * @brief Update device/interface counters snapshot + */ +void dhcp_device_update_snapshot(dhcp_device_context_t *context); /** - * @code dhcp_device_print_status(); + * @code dhcp_device_print_status(context); * * @brief prints status counters to syslog. If context is null, it will print aggregate status * + * @param context Device (interface) context + * * @return none */ void dhcp_device_print_status(dhcp_device_context_t *context); diff --git a/src/dhcpmon/src/dhcp_devman.c b/src/dhcpmon/src/dhcp_devman.c index 077ed210a299..e9a47ae5817a 100644 --- a/src/dhcpmon/src/dhcp_devman.c +++ b/src/dhcpmon/src/dhcp_devman.c @@ -12,6 +12,9 @@ #include "dhcp_devman.h" +/** Prefix appended to Aggregation device */ +#define AGG_DEV_PREFIX "Agg-" + /** struct for interface information */ struct intf { @@ -27,22 +30,34 @@ static LIST_HEAD(intf_list, intf) intfs; static uint32_t dhcp_num_south_intf = 0; /** dhcp_num_north_intf number of north interfaces */ static uint32_t dhcp_num_north_intf = 0; +/** dhcp_num_mgmt_intf number of mgmt interfaces */ +static uint32_t dhcp_num_mgmt_intf = 0; /** On Device vlan interface IP address corresponding vlan downlink IP * This IP is used to filter Offer/Ack packet coming from DHCP server */ static in_addr_t vlan_ip = 0; -/** vlan interface name */ -static char vlan_intf[IF_NAMESIZE] = "Undefined"; +/** mgmt interface */ +static struct intf *mgmt_intf = NULL; /** * @code dhcp_devman_get_vlan_intf(); * * Accessor method */ -const char* dhcp_devman_get_vlan_intf() +dhcp_device_context_t* dhcp_devman_get_agg_dev() { - return vlan_intf; + return dhcp_device_get_aggregate_context(); +} + +/** + * @code dhcp_devman_get_mgmt_dev(); + * + * Accessor method + */ +dhcp_device_context_t* dhcp_devman_get_mgmt_dev() +{ + return mgmt_intf ? mgmt_intf->dev_context : NULL; } /** @@ -86,27 +101,42 @@ void dhcp_devman_shutdown() * * @brief adds interface to the device manager. */ -int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) +int dhcp_devman_add_intf(const char *name, char intf_type) { int rv = -1; struct intf *dev = malloc(sizeof(struct intf)); if (dev != NULL) { dev->name = name; - dev->is_uplink = is_uplink; - if (is_uplink) { + dev->is_uplink = intf_type != 'd'; + + switch (intf_type) + { + case 'u': dhcp_num_north_intf++; - } else { + break; + case 'd': dhcp_num_south_intf++; assert(dhcp_num_south_intf <= 1); + break; + case 'm': + dhcp_num_mgmt_intf++; + assert(dhcp_num_mgmt_intf <= 1); + mgmt_intf = dev; + break; + default: + break; } rv = dhcp_device_init(&dev->dev_context, dev->name, dev->is_uplink); - if (rv == 0 && !is_uplink) { + if (rv == 0 && intf_type == 'd') { rv = dhcp_device_get_ip(dev->dev_context, &vlan_ip); - strncpy(vlan_intf, name, sizeof(vlan_intf) - 1); - vlan_intf[sizeof(vlan_intf) - 1] = '\0'; + dhcp_device_context_t *agg_dev = dhcp_device_get_aggregate_context(); + + strncpy(agg_dev->intf, AGG_DEV_PREFIX, sizeof(AGG_DEV_PREFIX)); + strncpy(agg_dev->intf + sizeof(AGG_DEV_PREFIX) - 1, name, sizeof(agg_dev->intf) - sizeof(AGG_DEV_PREFIX)); + agg_dev->intf[sizeof(agg_dev->intf) - 1] = '\0'; } LIST_INSERT_HEAD(&intfs, dev, entry); @@ -152,21 +182,41 @@ int dhcp_devman_start_capture(size_t snaplen, struct event_base *base) } /** - * @code dhcp_devman_get_status(); + * @code dhcp_devman_get_status(check_type, context); * * @brief collects DHCP relay status info. */ -dhcp_mon_status_t dhcp_devman_get_status() +dhcp_mon_status_t dhcp_devman_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context) { - return dhcp_device_get_status(NULL); + return dhcp_device_get_status(check_type, context); } /** - * @code dhcp_devman_print_status(); + * @code dhcp_devman_update_snapshot(context); * - * @brief prints status counters to syslog + * @brief Update device/interface counters snapshot */ -void dhcp_devman_print_status() +void dhcp_devman_update_snapshot(dhcp_device_context_t *context) { - dhcp_device_print_status(NULL); + dhcp_device_update_snapshot(context); +} + +/** + * @code dhcp_devman_print_status(context); + * + * @brief prints status counters to syslog, if context is null, it prints status counters for all interfaces + */ +void dhcp_devman_print_status(dhcp_device_context_t *context) +{ + if (context == NULL) { + struct intf *int_ptr; + + LIST_FOREACH(int_ptr, &intfs, entry) { + dhcp_device_print_status(int_ptr->dev_context); + } + + dhcp_device_print_status(dhcp_devman_get_agg_dev()); + } else { + dhcp_device_print_status(context); + } } diff --git a/src/dhcpmon/src/dhcp_devman.h b/src/dhcpmon/src/dhcp_devman.h index 2f66fa407ca2..4d8a53265715 100644 --- a/src/dhcpmon/src/dhcp_devman.h +++ b/src/dhcpmon/src/dhcp_devman.h @@ -36,9 +36,18 @@ void dhcp_devman_shutdown(); * * @brief Accessor method * - * @return pointer to vlan ip interface name + * @return pointer to aggregate device (interface) context */ -const char* dhcp_devman_get_vlan_intf(); +dhcp_device_context_t* dhcp_devman_get_agg_dev(); + +/** + * @code dhcp_devman_get_mgmt_intf_context(); + * + * @brief Accessor method + * + * @return pointer to mgmt interface context + */ +dhcp_device_context_t* dhcp_devman_get_mgmt_dev(); /** * @code dhcp_devman_add_intf(name, uplink); @@ -46,11 +55,13 @@ const char* dhcp_devman_get_vlan_intf(); * @brief adds interface to the device manager. * * @param name interface name - * @param is_uplink true for uplink (north) interface + * @param intf_type 'u' for uplink (north) interface + * 'd' for downlink (south) interface + * 'm' for mgmt interface * * @return 0 on success, nonzero otherwise */ -int dhcp_devman_add_intf(const char *name, uint8_t is_uplink); +int dhcp_devman_add_intf(const char *name, char intf_type); /** * @code dhcp_devman_start_capture(snaplen, base); @@ -65,21 +76,35 @@ int dhcp_devman_add_intf(const char *name, uint8_t is_uplink); int dhcp_devman_start_capture(size_t snaplen, struct event_base *base); /** - * @code dhcp_devman_get_status(); + * @code dhcp_devman_get_status(check_type, context); * * @brief collects DHCP relay status info. * + * @param check_type Type of validation + * @param context pointer to device (interface) context + * * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE */ -dhcp_mon_status_t dhcp_devman_get_status(); +dhcp_mon_status_t dhcp_devman_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context); /** - * @code dhcp_devman_print_status(); + * @code dhcp_devman_update_snapshot(context); + * + * @param context Device (interface) context + * + * @brief Update device/interface counters snapshot + */ +void dhcp_devman_update_snapshot(dhcp_device_context_t *context); + +/** + * @code dhcp_devman_print_status(context); * * @brief prints status counters to syslog * + * @param context pointer to device (interface) context + * * @return none */ -void dhcp_devman_print_status(); +void dhcp_devman_print_status(dhcp_device_context_t *context); #endif /* DHCP_DEVMAN_H_ */ diff --git a/src/dhcpmon/src/dhcp_mon.c b/src/dhcpmon/src/dhcp_mon.c index 623bc46f5276..8147b5057c8f 100644 --- a/src/dhcpmon/src/dhcp_mon.c +++ b/src/dhcpmon/src/dhcp_mon.c @@ -16,8 +16,17 @@ #include "dhcp_mon.h" #include "dhcp_devman.h" +/** DHCP device/interface state */ +typedef struct +{ + dhcp_mon_check_t check_type; /** check type */ + dhcp_device_context_t* (*get_context)(); /** functor to a device context accessor function */ + int count; /** count in the number of unhealthy checks */ + const char *msg; /** message to be printed if unhealthy state is determined */ +} dhcp_mon_state_t; + /** window_interval_sec monitoring window for dhcp relay health checks */ -static int window_interval_sec = 12; +static int window_interval_sec = 18; /** dhcp_unhealthy_max_count max count of consecutive unhealthy statuses before reporting to syslog */ static int dhcp_unhealthy_max_count = 10; /** libevent base struct */ @@ -28,6 +37,25 @@ static struct event *ev_timeout = NULL; static struct event *ev_sigint; /** libevent SIGTERM signal event struct */ static struct event *ev_sigterm; +/** libevent SIGUSR1 signal event struct */ +static struct event *ev_sigusr1; + +/** DHCP monitor state data for aggregate device for mgmt device */ +static dhcp_mon_state_t state_data[] = { + [0] = { + .check_type = DHCP_MON_CHECK_POSITIVE, + .get_context = dhcp_devman_get_agg_dev, + .count = 0, + .msg = "dhcpmon detected disparity in DHCP Relay behavior. Duration: %d (sec) for vlan: '%s'\n" + }, + [1] = { + .check_type = DHCP_MON_CHECK_NEGATIVE, + .get_context = dhcp_devman_get_mgmt_dev, + .count = 0, + .msg = "dhcpmon detected DHCP packets traveling through mgmt interface (please check BGP routes.)" + " Duration: %d (sec) for intf: '%s'\n" + } +}; /** * @code signal_callback(fd, event, arg); @@ -42,42 +70,42 @@ static struct event *ev_sigterm; */ static void signal_callback(evutil_socket_t fd, short event, void *arg) { - syslog(LOG_ALERT, "Received signal %s\n", strsignal(fd)); - dhcp_devman_print_status(); - dhcp_mon_stop(); + syslog(LOG_ALERT, "Received signal: '%s'\n", strsignal(fd)); + dhcp_devman_print_status(NULL); + if ((fd == SIGTERM) || (fd == SIGINT)) { + dhcp_mon_stop(); + } } /** - * @code timeout_callback(fd, event, arg); + * @code check_dhcp_relay_health(state_data); * - * @brief periodic timer call back + * @brief check DHCP relay overall health * - * @param fd libevent socket - * @param event event triggered - * @param arg pointer user provided context (libevent base) + * @param state_data pointer to dhcpmon state data * * @return none */ -static void timeout_callback(evutil_socket_t fd, short event, void *arg) +static void check_dhcp_relay_health(dhcp_mon_state_t *state_data) { - static int count = 0; - dhcp_mon_status_t dhcp_mon_status = dhcp_devman_get_status(); + dhcp_device_context_t *context = state_data->get_context(); + dhcp_mon_status_t dhcp_mon_status = dhcp_devman_get_status(state_data->check_type, context); switch (dhcp_mon_status) { case DHCP_MON_STATUS_UNHEALTHY: - if (++count > dhcp_unhealthy_max_count) { - syslog(LOG_ALERT, "dhcpmon detected disparity in DHCP Relay behavior. Failure count: %d for vlan: '%s'\n", - count, dhcp_devman_get_vlan_intf()); - dhcp_devman_print_status(); + if (++state_data->count > dhcp_unhealthy_max_count) { + syslog(LOG_ALERT, state_data->msg, state_data->count * window_interval_sec, context->intf); + dhcp_devman_print_status(context); } break; case DHCP_MON_STATUS_HEALTHY: - if (count > 0) { - count = 0; - } + state_data->count = 0; break; case DHCP_MON_STATUS_INDETERMINATE: + if (state_data->count) { + state_data->count++; + } break; default: syslog(LOG_ERR, "DHCP Relay returned unknown status %d\n", dhcp_mon_status); @@ -85,6 +113,28 @@ static void timeout_callback(evutil_socket_t fd, short event, void *arg) } } +/** + * @code timeout_callback(fd, event, arg); + * + * @brief periodic timer call back + * + * @param fd libevent socket + * @param event event triggered + * @param arg pointer user provided context (libevent base) + * + * @return none + */ +static void timeout_callback(evutil_socket_t fd, short event, void *arg) +{ + for (uint8_t i = 0; i < sizeof(state_data) / sizeof(*state_data); i++) { + check_dhcp_relay_health(&state_data[i]); + } + + for (uint8_t i = 0; i < sizeof(state_data) / sizeof(*state_data); i++) { + dhcp_devman_update_snapshot(state_data[i].get_context()); + } +} + /** * @code dhcp_mon_init(window_sec, max_count); * @@ -118,6 +168,12 @@ int dhcp_mon_init(int window_sec, int max_count) break; } + ev_sigusr1 = evsignal_new(base, SIGUSR1, signal_callback, base); + if (ev_sigusr1 == NULL) { + syslog(LOG_ERR, "Could not create SIGUSER1 libevent signal!\n"); + break; + } + ev_timeout = event_new(base, -1, EV_PERSIST, timeout_callback, base); if (ev_timeout == NULL) { syslog(LOG_ERR, "Could not create libevent timer!\n"); @@ -140,10 +196,12 @@ void dhcp_mon_shutdown() event_del(ev_timeout); event_del(ev_sigint); event_del(ev_sigterm); + event_del(ev_sigusr1); event_free(ev_timeout); event_free(ev_sigint); event_free(ev_sigterm); + event_free(ev_sigusr1); event_base_free(base); } @@ -173,6 +231,11 @@ int dhcp_mon_start(size_t snaplen) break; } + if (evsignal_add(ev_sigusr1, NULL) != 0) { + syslog(LOG_ERR, "Could not add SIGUSR1 libevent signal!\n"); + break; + } + struct timeval event_time = {.tv_sec = window_interval_sec, .tv_usec = 0}; if (evtimer_add(ev_timeout, &event_time) != 0) { syslog(LOG_ERR, "Could not add event timer to libevent!\n"); diff --git a/src/dhcpmon/src/main.c b/src/dhcpmon/src/main.c index 9d155393a6e6..bb8c45867f66 100644 --- a/src/dhcpmon/src/main.c +++ b/src/dhcpmon/src/main.c @@ -24,7 +24,7 @@ static const size_t dhcpmon_default_snaplen = 65535; /** dhcpmon_default_health_check_window: default value for a time window, during which DHCP DORA packet counts are being * collected */ -static const uint32_t dhcpmon_default_health_check_window = 12; +static const uint32_t dhcpmon_default_health_check_window = 18; /** dhcpmon_default_unhealthy_max_count: default max consecutive unhealthy status reported before reporting an issue * with DHCP relay */ static const uint32_t dhcpmon_default_unhealthy_max_count = 10; @@ -40,7 +40,7 @@ static const uint32_t dhcpmon_default_unhealthy_max_count = 10; */ static void usage(const char *prog) { - printf("Usage: %s -id {-iu }+ [-w ]" + printf("Usage: %s -id {-iu }+ -im [-w ]" "[-c ] [-s ] [-d]\n", prog); printf("where\n"); printf("\tsouth interface: is a vlan interface,\n"); @@ -50,7 +50,7 @@ static void usage(const char *prog) printf("\tunhealthy status count: count of consecutive unhealthy status before writing an alert to syslog " "(default %d),\n", dhcpmon_default_unhealthy_max_count); - printf("\tsnap length: snap length of packet capture (default %d),\n", dhcpmon_default_snaplen); + printf("\tsnap length: snap length of packet capture (default %ld),\n", dhcpmon_default_snaplen); printf("\t-d: daemonize %s.\n", prog); exit(EXIT_SUCCESS); @@ -127,7 +127,7 @@ int main(int argc, char **argv) usage(basename(argv[0])); break; case 'i': - if (dhcp_devman_add_intf(argv[i + 1], argv[i][2] == 'u') != 0) { + if (dhcp_devman_add_intf(argv[i + 1], argv[i][2]) != 0) { usage(basename(argv[0])); } i += 2; diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index 5037476139ce..3e485f4ddc35 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -56,7 +56,7 @@ dependent_startup_wait_for=start:exited programs=dhcpmon-Vlan1000 [program:dhcpmon-Vlan1000] -command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 +command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -im eth0 priority=4 autostart=false autorestart=false From 8bac4904b8c3017bc5f793032f2260c4900d3272 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Thu, 10 Sep 2020 01:21:47 -0700 Subject: [PATCH 1110/1427] [build]: Allow user to silence variable dump during make (#5327) Most of the devs know how they configured their build. Instead of generating a huge header for every make operation, allow the user to silence it via an environment variable. SONIC_BUILD_QUIETER=y make ... Also add SONIC_BUILDER_EXTRA_ENV variable which allows the user to inject arbitrary options to the docker run cmdline for the builder. SONIC_BUILDER_EXTRA_CMDLINE="-e test=var -e var='with spaces'" make ... --- Makefile.cache | 2 ++ Makefile.work | 7 ++++++- slave.mk | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Makefile.cache b/Makefile.cache index 8ccc97cae770..3c45cec3a97f 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -89,11 +89,13 @@ endif -include $(PLATFORM_PATH)/rules.dep endif +ifndef SONIC_BUILD_QUIETER $(info "SONIC_DPKG_CACHE_METHOD" : "$(SONIC_DPKG_CACHE_METHOD)") ifneq ($(SONIC_DPKG_CACHE_METHOD),none) $(info "DPKG_CACHE_PATH" : "$(SONIC_DPKG_CACHE_SOURCE)") endif $(info ) +endif ############################################################################### diff --git a/Makefile.work b/Makefile.work index 99e8d85d1b24..4f713ca314c1 100644 --- a/Makefile.work +++ b/Makefile.work @@ -116,7 +116,8 @@ DOCKER_RUN := docker run --rm=true --privileged --init \ -w $(DOCKER_BUILDER_WORKDIR) \ -e "http_proxy=$(http_proxy)" \ -e "https_proxy=$(https_proxy)" \ - -i$(if $(TERM),t,) + -i$(if $(TERM),t,) \ + $(SONIC_BUILDER_EXTRA_CMDLINE) include rules/config @@ -124,6 +125,10 @@ ifneq ($(DOCKER_BUILDER_USER_MOUNT),) DOCKER_RUN += $(foreach mount,$(subst $(comma), ,$(DOCKER_BUILDER_USER_MOUNT)), $(addprefix -v , $(mount))) endif +ifdef SONIC_BUILD_QUIETER + DOCKER_RUN += -e "SONIC_BUILD_QUIETER=$(SONIC_BUILD_QUIETER)" +endif + ifneq ($(SONIC_DPKG_CACHE_SOURCE),) DOCKER_RUN += -v "$(SONIC_DPKG_CACHE_SOURCE):/dpkg_cache:rw" endif diff --git a/slave.mk b/slave.mk index f77cec3f1eaa..fa2926d408cb 100644 --- a/slave.mk +++ b/slave.mk @@ -189,6 +189,7 @@ export FRR_USER_GID ## Dumping key config attributes associated to current building exercise ############################################################################### +ifndef SONIC_BUILD_QUIETER $(info SONiC Build System) $(info ) $(info Build Configuration) @@ -232,6 +233,9 @@ $(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)") $(info "TELEMETRY_WRITABLE" : "$(TELEMETRY_WRITABLE)") $(info "ENABLE_SYNCHRONOUS_MODE" : "$(ENABLE_SYNCHRONOUS_MODE)") $(info ) +else +$(info SONiC Build System for $(CONFIGURED_PLATFORM):$(CONFIGURED_ARCH)) +endif include Makefile.cache From 7e2fa7d9973105752e2e9d4abb3c9031657d0eaa Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Thu, 10 Sep 2020 01:24:12 -0700 Subject: [PATCH 1111/1427] [build]: Add a user defined rules/config file not tracked by git (#5325) This change introduce the rules/config.user file. It gets loaded after rules/config as a mean to override default values. If the configuration file does not exists this step is ignored. Since this path is tracked by .gitignore, it provides a mean to change the configuration of sonic build without dirtying the git tree. Signed-off-by: Samuel Angebault --- .gitignore | 1 + slave.mk | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 88a4174168ca..253196bd111e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .arch .platform .screen +rules/config.user # Build artifacts fsroot/ diff --git a/slave.mk b/slave.mk index fa2926d408cb..90805f286e57 100644 --- a/slave.mk +++ b/slave.mk @@ -94,6 +94,7 @@ list : ############################################################################### include $(RULES_PATH)/config +-include $(RULES_PATH)/config.user ifeq ($(SONIC_ENABLE_PFCWD_ON_START),y) ENABLE_PFCWD_ON_START = y From 339cfbf9aff10838698e8a6f0369a6a7b998c704 Mon Sep 17 00:00:00 2001 From: shi-su <67605788+shi-su@users.noreply.github.com> Date: Thu, 10 Sep 2020 01:26:10 -0700 Subject: [PATCH 1112/1427] Remove the configuration of synchronous mode from init_cfg.json (#5308) Remove the configuration of synchronous mode from init_cfg.json --- .gitignore | 2 -- Makefile.work | 2 -- files/build_templates/init_cfg.json.j2 | 3 +-- platform/p4/docker-sonic-p4/Dockerfile.j2 | 1 - platform/p4/docker-sonic-p4/init_cfg.json.j2 | 7 ------- platform/p4/docker-sonic-p4/start.sh | 7 +------ platform/vs/docker-sonic-vs/Dockerfile.j2 | 1 - platform/vs/docker-sonic-vs/init_cfg.json.j2 | 7 ------- platform/vs/docker-sonic-vs/start.sh | 7 +------ rules/config | 3 --- slave.mk | 5 ----- 11 files changed, 3 insertions(+), 42 deletions(-) delete mode 100644 platform/p4/docker-sonic-p4/init_cfg.json.j2 delete mode 100644 platform/vs/docker-sonic-vs/init_cfg.json.j2 diff --git a/.gitignore b/.gitignore index 253196bd111e..eda891212d53 100644 --- a/.gitignore +++ b/.gitignore @@ -61,5 +61,3 @@ platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_lpc.c platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_ich.c platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_mailbox.c platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/ipmihelper.py -platform/vs/docker-sonic-vs/init_cfg.json -platform/p4/docker-sonic-p4/init_cfg.json diff --git a/Makefile.work b/Makefile.work index 4f713ca314c1..d157b03bf48f 100644 --- a/Makefile.work +++ b/Makefile.work @@ -38,7 +38,6 @@ # * SONIC_DPKG_CACHE_METHOD: Specifying method of obtaining the Debian packages from cache: none or cache # * SONIC_DPKG_CACHE_SOURCE: Debian package cache location when cache enabled for debian packages # * BUILD_LOG_TIMESTAMP: Set timestamp in the build log (simple/none) -# * ENABLE_SYNCHRONOUS_MODE: Enable synchronous mode between orchagent and syncd # ############################################################################### @@ -218,7 +217,6 @@ SONIC_BUILD_INSTRUCTION := make \ EXTRA_DOCKER_TARGETS=$(EXTRA_DOCKER_TARGETS) \ BUILD_LOG_TIMESTAMP=$(BUILD_LOG_TIMESTAMP) \ SONIC_ENABLE_IMAGE_SIGNATURE=$(ENABLE_IMAGE_SIGNATURE) \ - ENABLE_SYNCHRONOUS_MODE=$(ENABLE_SYNCHRONOUS_MODE) \ $(SONIC_OVERRIDE_BUILD_VARS) .PHONY: sonic-slave-build sonic-slave-bash init reset diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index cee663a2b6e3..7126f2648d74 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -2,8 +2,7 @@ "DEVICE_METADATA": { "localhost": { "default_bgp_status": {% if shutdown_bgp_on_start == "y" %}"down"{% else %}"up"{% endif %}, - "default_pfcwd_status": {% if enable_pfcwd_on_start == "y" %}"enable"{% else %}"disable"{% endif %}, - "synchronous_mode": {% if enable_synchronous_mode == "y" %}"enable"{% else %}"disable"{% endif %} + "default_pfcwd_status": {% if enable_pfcwd_on_start == "y" %}"enable"{% else %}"disable"{% endif %} } }, "CRM": { diff --git a/platform/p4/docker-sonic-p4/Dockerfile.j2 b/platform/p4/docker-sonic-p4/Dockerfile.j2 index c0063af09bd1..22621b985465 100644 --- a/platform/p4/docker-sonic-p4/Dockerfile.j2 +++ b/platform/p4/docker-sonic-p4/Dockerfile.j2 @@ -78,7 +78,6 @@ COPY ["start.sh", "orchagent.sh", "config_bm.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin"] -COPY ["init_cfg.json", "/etc/sonic/"] RUN echo "docker-sonic-p4" > /etc/hostname RUN touch /etc/quagga/zebra.conf diff --git a/platform/p4/docker-sonic-p4/init_cfg.json.j2 b/platform/p4/docker-sonic-p4/init_cfg.json.j2 deleted file mode 100644 index a30ea5770dd3..000000000000 --- a/platform/p4/docker-sonic-p4/init_cfg.json.j2 +++ /dev/null @@ -1,7 +0,0 @@ -{ - "DEVICE_METADATA": { - "localhost": { - "synchronous_mode": {% if enable_synchronous_mode == "y" %}"enable"{% else %}"disable"{% endif %} - } - } -} diff --git a/platform/p4/docker-sonic-p4/start.sh b/platform/p4/docker-sonic-p4/start.sh index b3c451e7c3d4..e3251bb2f4e5 100755 --- a/platform/p4/docker-sonic-p4/start.sh +++ b/platform/p4/docker-sonic-p4/start.sh @@ -8,12 +8,7 @@ if ! ip link show eth0 &> /dev/null; then fi SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') -if [ -f /etc/sonic/init_cfg.json ]; then - sonic-cfggen -j /etc/sonic/init_cfg.json -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /tmp/init_cfg.json - mv /tmp/init_cfg.json /etc/sonic/init_cfg.json -else - sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /etc/sonic/init_cfg.json -fi +sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /etc/sonic/init_cfg.json if [ -f /etc/sonic/config_db.json ]; then sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --print-data > /tmp/config_db.json diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 3b1b15bf7c52..268bd47f4d5e 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -133,7 +133,6 @@ COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin/"] COPY ["files/buffers_config.j2", "files/qos_config.j2", "/usr/share/sonic/templates/"] COPY ["files/sonic_version.yml", "/etc/sonic/"] -COPY ["init_cfg.json", "/etc/sonic/"] COPY ["database_config.json", "/etc/default/sonic-db/"] COPY ["hostname.j2", "/usr/share/sonic/templates/"] COPY ["default_chassis_cfg.json", "/etc/default/sonic-db/"] diff --git a/platform/vs/docker-sonic-vs/init_cfg.json.j2 b/platform/vs/docker-sonic-vs/init_cfg.json.j2 deleted file mode 100644 index a30ea5770dd3..000000000000 --- a/platform/vs/docker-sonic-vs/init_cfg.json.j2 +++ /dev/null @@ -1,7 +0,0 @@ -{ - "DEVICE_METADATA": { - "localhost": { - "synchronous_mode": {% if enable_synchronous_mode == "y" %}"enable"{% else %}"disable"{% endif %} - } - } -} diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 95c24ae37146..1f30dda376e8 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -32,12 +32,7 @@ if [[ -f /usr/share/sonic/virtual_chassis/default_config.json ]]; then fi SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') -if [ -f /etc/sonic/init_cfg.json ]; then - sonic-cfggen -j /etc/sonic/init_cfg.json -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' $CHASS_CFG --print-data > /tmp/init_cfg.json - mv /tmp/init_cfg.json /etc/sonic/init_cfg.json -else - sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' $CHASS_CFG --print-data > /etc/sonic/init_cfg.json -fi +sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' $CHASS_CFG --print-data > /etc/sonic/init_cfg.json if [ -f /etc/sonic/config_db.json ]; then sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --print-data > /tmp/config_db.json diff --git a/rules/config b/rules/config index b0bbb0b60173..8cffedc4e965 100644 --- a/rules/config +++ b/rules/config @@ -158,6 +158,3 @@ K8s_GCR_IO_PAUSE_VERSION = 3.2 # CA_CERT = # The relative path is build root folder. SONIC_ENABLE_IMAGE_SIGNATURE ?= n - -# ENABLE_SYNCHRONOUS_MODE - enable synchronous mode between orchagent and syncd -ENABLE_SYNCHRONOUS_MODE = n diff --git a/slave.mk b/slave.mk index 90805f286e57..832f7b9049b3 100644 --- a/slave.mk +++ b/slave.mk @@ -232,7 +232,6 @@ $(info "INCLUDE_SFLOW" : "$(INCLUDE_SFLOW)") $(info "INCLUDE_NAT" : "$(INCLUDE_NAT)") $(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)") $(info "TELEMETRY_WRITABLE" : "$(TELEMETRY_WRITABLE)") -$(info "ENABLE_SYNCHRONOUS_MODE" : "$(ENABLE_SYNCHRONOUS_MODE)") $(info ) else $(info SONiC Build System for $(CONFIGURED_PLATFORM):$(CONFIGURED_ARCH)) @@ -253,7 +252,6 @@ endif export kernel_procure_method=$(KERNEL_PROCURE_METHOD) export vs_build_prepare_mem=$(VS_PREPARE_MEM) -export enable_synchronous_mode=$(ENABLE_SYNCHRONOUS_MODE) ############################################################################### ## Local targets @@ -702,9 +700,6 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_whls=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_PYTHON_WHEELS)))\n" | awk '!a[$$0]++')) $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_PACKAGES)))\n" | awk '!a[$$0]++')) j2 $($*.gz_PATH)/Dockerfile.j2 > $($*.gz_PATH)/Dockerfile - if [ -f $($*.gz_PATH)/init_cfg.json.j2 ] ; then - j2 $($*.gz_PATH)/init_cfg.json.j2 > $($*.gz_PATH)/init_cfg.json - fi docker info $(LOG) docker build --squash --no-cache \ --build-arg http_proxy=$(HTTP_PROXY) \ From 0b4191fe2ab88223e689ef341592d5b79e72fb0b Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Thu, 10 Sep 2020 01:34:38 -0700 Subject: [PATCH 1113/1427] [Arista] Updating driver submodules (#5352) - Merge chassis codebase upstream - Add support for Otterlake supervisor - Add support for NorthFace and Camp chassis - Add support for Eldridge, Dragonfly and Brooks fabrics - Add support for Clearwater2 and Clearwater2Ms linecards - Add new arista Cli to power on/off cards - Add new arista show Cli to inspect supervisor, chassis, fabrics and linecards --- .../x86_64-arista_7800_sup/platform_reboot | 1 + device/arista/x86_64-arista_7800_sup/plugins | 1 + .../pmon_daemon_control.json | 4 +++ .../platform_reboot | 1 + .../x86_64-arista_7800r3_48cq2_lc/plugins | 1 + .../sensors.conf | 0 .../platform_reboot | 1 + .../x86_64-arista_7800r3_48cqm2_lc/plugins | 1 + .../sensors.conf | 0 files/Aboot/boot0.j2 | 27 +++++++++++++++++-- .../barefoot/sonic-platform-modules-arista | 2 +- .../broadcom/sonic-platform-modules-arista | 2 +- 12 files changed, 37 insertions(+), 4 deletions(-) create mode 120000 device/arista/x86_64-arista_7800_sup/platform_reboot create mode 120000 device/arista/x86_64-arista_7800_sup/plugins create mode 100644 device/arista/x86_64-arista_7800_sup/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7800r3_48cq2_lc/platform_reboot create mode 120000 device/arista/x86_64-arista_7800r3_48cq2_lc/plugins create mode 100644 device/arista/x86_64-arista_7800r3_48cq2_lc/sensors.conf create mode 120000 device/arista/x86_64-arista_7800r3_48cqm2_lc/platform_reboot create mode 120000 device/arista/x86_64-arista_7800r3_48cqm2_lc/plugins create mode 100644 device/arista/x86_64-arista_7800r3_48cqm2_lc/sensors.conf diff --git a/device/arista/x86_64-arista_7800_sup/platform_reboot b/device/arista/x86_64-arista_7800_sup/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7800_sup/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800_sup/plugins b/device/arista/x86_64-arista_7800_sup/plugins new file mode 120000 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7800_sup/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800_sup/pmon_daemon_control.json b/device/arista/x86_64-arista_7800_sup/pmon_daemon_control.json new file mode 100644 index 000000000000..fbec8f525160 --- /dev/null +++ b/device/arista/x86_64-arista_7800_sup/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true, + "skip_xcvrd": true +} diff --git a/device/arista/x86_64-arista_7800r3_48cq2_lc/platform_reboot b/device/arista/x86_64-arista_7800r3_48cq2_lc/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7800r3_48cq2_lc/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800r3_48cq2_lc/plugins b/device/arista/x86_64-arista_7800r3_48cq2_lc/plugins new file mode 120000 index 000000000000..5fbbf98a6284 --- /dev/null +++ b/device/arista/x86_64-arista_7800r3_48cq2_lc/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800r3_48cq2_lc/sensors.conf b/device/arista/x86_64-arista_7800r3_48cq2_lc/sensors.conf new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/device/arista/x86_64-arista_7800r3_48cqm2_lc/platform_reboot b/device/arista/x86_64-arista_7800r3_48cqm2_lc/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7800r3_48cqm2_lc/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800r3_48cqm2_lc/plugins b/device/arista/x86_64-arista_7800r3_48cqm2_lc/plugins new file mode 120000 index 000000000000..5fbbf98a6284 --- /dev/null +++ b/device/arista/x86_64-arista_7800r3_48cqm2_lc/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800r3_48cqm2_lc/sensors.conf b/device/arista/x86_64-arista_7800r3_48cqm2_lc/sensors.conf new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 34291c2b1e8f..eccdfd251bf5 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -431,6 +431,11 @@ write_platform_specific_cmdline() { # set varlog size to 100MB local varlog_size=100 + # sonic_mode is set to fixed by default. + sonic_mode="fixed" + supervisor_mode="supervisor" + linecard_mode="linecard" + # detect the size of the flash partition from name in Aboot/EOS/SONiC local flash_size=$(($(df "$target_path" | tail -1 | tr -s ' ' | cut -f2 -d' ') / 1000)) @@ -502,14 +507,27 @@ write_platform_specific_cmdline() { aboot_machine=arista_7280cr3k_32d4 flash_size=7382 fi - if in_array "$platform" "rook" "magpie" "woodpecker"; then + if [ "$sid" = "Clearwater2" ]; then + aboot_machine=arista_7800r3_48cq2_lc + sonic_mode="$linecard_mode" + fi + if [ "$sid" = "Clearwater2Ms" ]; then + aboot_machine=arista_7800r3_48cqm2_lc + sonic_mode="$linecard_mode" + fi + if [ "$sid" = "OtterLake" ]; then + aboot_machine=arista_7800_sup + flash_size=30000 + sonic_mode=$supervisor_mode + fi + if in_array "$platform" "rook" "magpie" "woodpecker" "sprucefish"; then cmdline_add tsc=reliable cmdline_add pcie_ports=native cmdline_add rhash_entries=1 cmdline_add usb-storage.delay_use=0 cmdline_add reassign_prefmem fi - if in_array "$platform" "rook"; then + if in_array "$platform" "rook" "sprucefish"; then cmdline_add iommu=on cmdline_add intel_iommu=on read_system_eeprom @@ -523,6 +541,9 @@ write_platform_specific_cmdline() { cmdline_add modprobe.blacklist=snd_hda_intel,hdaudio read_system_eeprom fi + if in_array "$platform" "lorikeet" "hedgehog"; then + read_system_eeprom + fi if [ $flash_size -ge 28000 ]; then varlog_size=4096 @@ -535,6 +556,8 @@ write_platform_specific_cmdline() { fi cmdline_add "varlog_size=$varlog_size" + + cmdline_add "sonic.mode=$sonic_mode" } write_image_specific_cmdline() { diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 6de446114d0e..10f08eea2732 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 6de446114d0e2bfaa100bab42897f6f1192e2723 +Subproject commit 10f08eea27329e7090fcedf1857f3ab385a27a27 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 6de446114d0e..10f08eea2732 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 6de446114d0e2bfaa100bab42897f6f1192e2723 +Subproject commit 10f08eea27329e7090fcedf1857f3ab385a27a27 From c44279a36526426780475dd73968d9624410c10e Mon Sep 17 00:00:00 2001 From: Petro Bratash <68950226+bratashX@users.noreply.github.com> Date: Fri, 11 Sep 2020 23:03:53 +0300 Subject: [PATCH 1114/1427] [sonic-platform-daemons] Update submodule (#5355) - https://github.com/Azure/sonic-platform-daemons/commit/1893c4049531194c8937af31a7cd25cb19852834 - Fix the xcvrd theowing error on sfprecover function on getKeys() not valid. - https://github.com/Azure/sonic-platform-daemons/commit/65fa4430feb5f10a8f7c86a348402eb947795c29 - Merge pull request #90 from abdosi/multiasic-fix - https://github.com/Azure/sonic-platform-daemons/commit/7f812c93b19fc456ac1ecd66510d403b8ff775c3 - [xcvrd] Don't log unnecessary messages upon empty transceiver change event (#53) - https://github.com/Azure/sonic-platform-daemons/commit/096920273b685e451bc20035a0e3ab8dbba7df31 - Fix pcied daemon failure (#91) Signed-off-by: Petro Bratash --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index e4ee8528025f..096920273b68 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit e4ee8528025fb08e7e330ae66dd77d9f723dbcc5 +Subproject commit 096920273b685e451bc20035a0e3ab8dbba7df31 From 72ec212fa75378b2b60e5210fa04f0b1eebc0462 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sat, 12 Sep 2020 04:23:23 +0800 Subject: [PATCH 1115/1427] [Mellanox] Refactor SFP related platform API and plugins with new SDK API (#5326) Refactor SFP reset, low power get/set API, and plugins with new SDK SX APIs. Previously they were calling SDK SXD APIs which have glibc dependency because of shared memory usage. Remove implementation "set_power_override", "tx_disable_channel", "tx_disable" which using SXD APIs, once related SDK SX API available, will add them back based on new SDK SX APIs. --- .../plugins/sfplpmget.py | 56 +-- .../plugins/sfplpmset.py | 177 +++++----- .../plugins/sfpreset.py | 73 ++-- .../mlnx-platform-api/sonic_platform/sfp.py | 326 ++++++------------ 4 files changed, 257 insertions(+), 375 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py index a4a53fb099f1..2f19edfa1a52 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py @@ -1,43 +1,51 @@ #!/usr/bin/env python +""" +This utility get the power mode of a given module. +""" -import sys, errno -import os -from python_sdk_api.sxd_api import * +import sys +import errno from python_sdk_api.sx_api import * +def mgmt_phy_mod_pwr_attr_get(handle, module_id, power_attr_type): + sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p() + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t() + sx_mgmt_phy_mod_pwr_attr.power_attr_type = power_attr_type + sx_mgmt_phy_mod_pwr_attr_t_p_assign(sx_mgmt_phy_mod_pwr_attr_p, sx_mgmt_phy_mod_pwr_attr) + try: + rc = sx_mgmt_phy_mod_pwr_attr_get(handle, module_id, sx_mgmt_phy_mod_pwr_attr_p) + assert SX_STATUS_SUCCESS == rc, "sx_mgmt_phy_mod_pwr_attr_get failed" + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t_p_value(sx_mgmt_phy_mod_pwr_attr_p) + pwr_mode_attr = sx_mgmt_phy_mod_pwr_attr.pwr_mode_attr + return pwr_mode_attr.admin_pwr_mode_e, pwr_mode_attr.oper_pwr_mode_e + finally: + delete_sx_mgmt_phy_mod_pwr_attr_t_p(sx_mgmt_phy_mod_pwr_attr_p) + # Check if SFP port number is provided if len(sys.argv) < 2: - print "SFP module number is missed." - print "Usage: sfplpmget.py " + print("SFP module number is missed.") + print("Usage: sfplpmget.py ") sys.exit(errno.EINVAL) # Init SDK API rc, handle = sx_api_open(None) if (rc != SX_STATUS_SUCCESS): - print "Failed to open api handle.\nPlease check that SDK is running." - sys.exit(errno.EACCES) - -pid = os.getpid() -rc = sxd_access_reg_init(pid, None, 0) -if (rc != 0): - print "Failed to initializing register access.\nPlease check that SDK is running." + print("Failed to open api handle.\nPlease check that SDK is running.") sys.exit(errno.EACCES) # Get SFP module number sfp_module = int(sys.argv[1]) - 1 -# Get MCION -mcion = ku_mcion_reg() -mcion.module = sfp_module -meta = sxd_reg_meta_t() -meta.dev_id = 1 -meta.swid = 0 -meta.access_cmd = SXD_ACCESS_CMD_GET +admin_pwr_mode, oper_pwr_mode = mgmt_phy_mod_pwr_attr_get(handle, sfp_module, SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E) -rc = sxd_access_reg_mcion(mcion, meta, 1, None, None) -assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_mcion failed, rc = %d" % rc +lpm_status = None +if oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_HIGH_E: + lpm_status = False +elif oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E: + lpm_status = True +else: + print("LPM UNKNOWN") -# Get low power mode status -lpm_mask = 1 << 8 -lpm_status = (lpm_mask & mcion.module_status_bits) != 0 print "LPM ON" if lpm_status else "LPM OFF" + +sx_api_close(handle) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py index 9fafaa951404..132d34257558 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py @@ -1,23 +1,17 @@ #!/usr/bin/env python +""" +This utility set the power mode of a given module. +""" -import sys, errno -import os -from python_sdk_api.sxd_api import * +import sys +import errno from python_sdk_api.sx_api import * -REGISTER_NUM = 1 -SXD_LOG_VERBOSITY_LEVEL = 0 + DEVICE_ID = 1 SWITCH_ID = 0 SX_PORT_ATTR_ARR_SIZE = 64 -PMAOS_ASE = 1 -PMAOS_EE = 1 -PMAOS_E = 2 -PMAOS_RST = 0 -PMAOS_ENABLE = 1 -PMAOS_DISABLE = 2 - PORT_TYPE_CPU = 4 PORT_TYPE_NVE = 8 PORT_TYPE_OFFSET = 28 @@ -36,7 +30,7 @@ def is_port_admin_status_up(log_port): admin_state_p = new_sx_port_admin_state_t_p() module_state_p = new_sx_port_module_state_t_p() rc = sx_api_port_state_get(handle, log_port, oper_state_p, admin_state_p, module_state_p) - assert rc == SXD_STATUS_SUCCESS, "sx_api_port_state_get failed, rc = %d" % rc + assert rc == SX_STATUS_SUCCESS, "sx_api_port_state_get failed, rc = %d" % rc admin_state = sx_port_admin_state_t_p_value(admin_state_p) if admin_state == SX_PORT_ADMIN_STATUS_UP: @@ -54,116 +48,109 @@ def get_log_ports(handle, sfp_module): port_cnt_p = new_uint32_t_p() uint32_t_p_assign(port_cnt_p, SX_PORT_ATTR_ARR_SIZE) - rc = sx_api_port_device_get(handle, DEVICE_ID , SWITCH_ID, port_attributes_list, port_cnt_p) + rc = sx_api_port_device_get(handle, DEVICE_ID, SWITCH_ID, port_attributes_list, port_cnt_p) assert rc == SX_STATUS_SUCCESS, "sx_api_port_device_get failed, rc = %d" % rc port_cnt = uint32_t_p_value(port_cnt_p) log_port_list = [] for i in range(0, port_cnt): port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i) - if is_nve(int(port_attributes.log_port)) == False \ - and is_cpu(int(port_attributes.log_port)) == False \ + if not is_nve(int(port_attributes.log_port)) \ + and not is_cpu(int(port_attributes.log_port)) \ and port_attributes.port_mapping.module_port == sfp_module \ and is_port_admin_status_up(port_attributes.log_port): log_port_list.append(port_attributes.log_port) return log_port_list -def init_sx_meta_data(): - meta = sxd_reg_meta_t() - meta.dev_id = DEVICE_ID - meta.swid = SWITCH_ID - return meta - -def set_sfp_admin_status(sfp_module, admin_status): - # Get PMAOS - pmaos = ku_pmaos_reg() - pmaos.module = sfp_module - meta = init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc - - # Set admin status to PMAOS - pmaos.ase = PMAOS_ASE - pmaos.ee = PMAOS_EE - pmaos.e = PMAOS_E - pmaos.rst = PMAOS_RST - if admin_status == SX_PORT_ADMIN_STATUS_DOWN: - pmaos.admin_status = PMAOS_DISABLE +def mgmt_phy_mod_pwr_attr_set(handle, module_id, power_attr_type, admin_pwr_mode): + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t() + sx_mgmt_phy_mod_pwr_mode_attr = sx_mgmt_phy_mod_pwr_mode_attr_t() + sx_mgmt_phy_mod_pwr_attr.power_attr_type = power_attr_type + sx_mgmt_phy_mod_pwr_mode_attr.admin_pwr_mode_e = admin_pwr_mode + sx_mgmt_phy_mod_pwr_attr.pwr_mode_attr = sx_mgmt_phy_mod_pwr_mode_attr + sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p() + sx_mgmt_phy_mod_pwr_attr_t_p_assign(sx_mgmt_phy_mod_pwr_attr_p, sx_mgmt_phy_mod_pwr_attr) + try: + rc = sx_mgmt_phy_mod_pwr_attr_set(handle, SX_ACCESS_CMD_SET, module_id, sx_mgmt_phy_mod_pwr_attr_p) + assert SX_STATUS_SUCCESS == rc, "sx_mgmt_phy_mod_pwr_attr_set failed" + finally: + delete_sx_mgmt_phy_mod_pwr_attr_t_p(sx_mgmt_phy_mod_pwr_attr_p) + +def mgmt_phy_mod_pwr_attr_get(handle, module_id, power_attr_type): + sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p() + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t() + sx_mgmt_phy_mod_pwr_attr.power_attr_type = power_attr_type + sx_mgmt_phy_mod_pwr_attr_t_p_assign(sx_mgmt_phy_mod_pwr_attr_p, sx_mgmt_phy_mod_pwr_attr) + try: + rc = sx_mgmt_phy_mod_pwr_attr_get(handle, module_id, sx_mgmt_phy_mod_pwr_attr_p) + assert SX_STATUS_SUCCESS == rc, "sx_mgmt_phy_mod_pwr_attr_get failed" + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t_p_value(sx_mgmt_phy_mod_pwr_attr_p) + pwr_mode_attr = sx_mgmt_phy_mod_pwr_attr.pwr_mode_attr + return pwr_mode_attr.admin_pwr_mode_e, pwr_mode_attr.oper_pwr_mode_e + finally: + delete_sx_mgmt_phy_mod_pwr_attr_t_p(sx_mgmt_phy_mod_pwr_attr_p) + + +def pwr_attr_set(handle, module_id, ports, attr_type, power_mode): + # Check if the module already works in the same mode + admin_pwr_mode, oper_pwr_mode = mgmt_phy_mod_pwr_attr_get(handle, module_id, attr_type) + if (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E and oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E) \ + or (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E and admin_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E): + return + try: + # Bring the port down + for port in ports: + set_port_admin_status_by_log_port(handle, port, SX_PORT_ADMIN_STATUS_DOWN) + # Set the desired power mode + mgmt_phy_mod_pwr_attr_set(handle, module_id, attr_type, power_mode) + # Bring the port up + finally: + for port in ports: + set_port_admin_status_by_log_port(handle, port, SX_PORT_ADMIN_STATUS_UP) + +def set_lpmode(handle, cmd, module_id): + # Construct the port module map. + log_port_list = get_log_ports(handle, module_id) + + if cmd == "enable": + pwr_attr_set(handle, module_id, log_port_list, SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E, SX_MGMT_PHY_MOD_PWR_MODE_LOW_E) + print("Enabled low power mode for module [%d]" % module_id) + elif cmd == "disable": + pwr_attr_set(handle, module_id, log_port_list, SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E, SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E) + print("Disabled low power mode for module [%d]" % module_id) else: - pmaos.admin_status = PMAOS_ENABLE - - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc - -def set_sfp_lpmode(sfp_module, lpm_enable): - # Get PMMP - pmmp = ku_pmmp_reg() - pmmp.module = sfp_module - meta = init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc - - # Set low power mode status - lpm_mask = 1 << 8 - if lpm_enable: - pmmp.eeprom_override = pmmp.eeprom_override | lpm_mask - else: - pmmp.eeprom_override = pmmp.eeprom_override & (~lpm_mask) - - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc + print("Error: Invalid command") + sys.exit(0) -# Check if SFP port number is provided if len(sys.argv) < 3: - print "SFP module number or LPM is missed." - print "Usage: sfplpmset.py " + print("SFP module number or LPM is missed.") + print("Usage: sfplpmset.py ") sys.exit(errno.EINVAL) +cmd = None lpm_enable = None if sys.argv[2] == 'on': lpm_enable = True + cmd = 'enable' elif sys.argv[2] == 'off': lpm_enable = False + cmd = 'disable' else: - print "Unrecognized LPM parameter. Please use or values" + print("Unrecognized LPM parameter. Please use or values") sys.exit(errno.EINVAL) -# Init SDK API -rc, handle = sx_api_open(None) -if (rc != SX_STATUS_SUCCESS): - print "Failed to open api handle.\nPlease check that SDK is running." - sys.exit(errno.EACCES) - -pid = os.getpid() -rc = sxd_access_reg_init(pid, None, SXD_LOG_VERBOSITY_LEVEL) -if (rc != SXD_STATUS_SUCCESS): - print "Failed to initializing register access.\nPlease check that SDK is running." - sys.exit(errno.EACCES); - # Get SFP module sfp_module = int(sys.argv[1]) - 1 -# Get all ports at admin up status that related to the SFP module -log_port_list = get_log_ports(handle, sfp_module) - -# SET SFP related ports to admin down status -for log_port in log_port_list: - set_port_admin_status_by_log_port(handle, log_port, SX_PORT_ADMIN_STATUS_DOWN) - -# Disable admin status before LPM settings -set_sfp_admin_status(sfp_module, SX_PORT_ADMIN_STATUS_DOWN) +print "[+] opening sdk" +rc, handle = sx_api_open(None) -# Set low power mode status -set_sfp_lpmode(sfp_module, lpm_enable) +if (rc != SX_STATUS_SUCCESS): + print("Failed to open api handle.\nPlease check that SDK is running.") + sys.exit(errno.EACCES) -# Enable admin status after LPM settings -set_sfp_admin_status(sfp_module, SX_PORT_ADMIN_STATUS_UP) +# Set low power mode +set_lpmode(handle, cmd, sfp_module) -# SET SFP related ports to admin up status -for log_port in log_port_list: - set_port_admin_status_by_log_port(handle, log_port, SX_PORT_ADMIN_STATUS_UP) +sx_api_close(handle) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py index 2ba6c6d7bc78..2e6de2e8bc8c 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py @@ -1,45 +1,28 @@ -#!/usr/bin/env python - -import sys, errno -import os -from python_sdk_api.sxd_api import * -from python_sdk_api.sx_api import * - -# Check if SFP port number is provided -if len(sys.argv) < 2: - print "SFP module number or LPM is missed." - print "Usage: sfpreset.py " - sys.exit(errno.EINVAL) - -# Init SDK API -rc, handle = sx_api_open(None) -if (rc != SX_STATUS_SUCCESS): - print "Failed to open api handle.\nPlease check that SDK is running." - sys.exit(errno.EACCES) - -pid = os.getpid() -rc = sxd_access_reg_init(pid, None, 0) -if (rc != 0): - print "Failed to initializing register access.\nPlease check that SDK is running." - sys.exit(errno.EACCES) - -# Get SFP module number -sfp_module = int(sys.argv[1]) - 1 - -# Get PMAOS -pmaos = ku_pmaos_reg() -pmaos.module = sfp_module -meta = sxd_reg_meta_t() -meta.dev_id = 1 -meta.swid = 0 -meta.access_cmd = SXD_ACCESS_CMD_GET - -rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None) -assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc - -# Reset SFP -pmaos.rst = 1 -meta.access_cmd = SXD_ACCESS_CMD_SET -rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None) -assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc -print "Reset flag is set" +#!/usr/bin/env python +""" +This utility reset the given SFP module. +""" + +import sys +import errno +from python_sdk_api.sx_api import * + +# Check if SFP port number is provided +if len(sys.argv) < 2: + print("SFP module number or LPM is missed.") + print("Usage: sfpreset.py ") + sys.exit(errno.EINVAL) + +# Init SDK API +rc, handle = sx_api_open(None) +if rc != SX_STATUS_SUCCESS: + print("Failed to open api handle.\nPlease check that SDK is running.") + sys.exit(errno.EACCES) + +# Get SFP module number +sfp_module = int(sys.argv[1]) - 1 + +rc = sx_mgmt_phy_mod_reset(handle, sfp_module) +assert rc == SX_STATUS_SUCCESS, "sx_mgmt_phy_mod_reset failed, rc = %d" % rc + +sx_api_close(handle) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index afe0dd0cc19b..1d6a618a370b 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -92,8 +92,8 @@ # in function get_transceiver_info and get_transceiver_bulk_status # XCVR_INTERFACE_DATA_SIZE stands for the max size to be read # this variable is only used by get_transceiver_info. -# please be noted that each time some new value added to the function -# we should make sure that it falls into the area +# please be noted that each time some new value added to the function +# we should make sure that it falls into the area # [XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE] or # adjust XCVR_INTERFACE_MAX_SIZE to contain the new data # It's same for [QSFP_DOM_BULK_DATA_START, QSFP_DOM_BULK_DATA_SIZE] and @@ -197,12 +197,12 @@ # identifier value of xSFP module which is in the first byte of the EEPROM # if the identifier value falls into SFP_TYPE_CODE_LIST the module is treated as a SFP module and parsed according to 8472 # for QSFP_TYPE_CODE_LIST the module is treated as a QSFP module and parsed according to 8436/8636 -# Originally the type (SFP/QSFP) of each module is determined according to the SKU dictionary +# Originally the type (SFP/QSFP) of each module is determined according to the SKU dictionary # where the type of each FP port is defined. The content of EEPROM is parsed according to its type. # However, sometimes the SFP module can be fit in an adapter and then pluged into a QSFP port. # In this case the EEPROM content is in format of SFP but parsed as QSFP, causing failure. -# To resolve that issue the type field of the xSFP module is also fetched so that we can know exectly what type the -# module is. Currently only the following types are recognized as SFP/QSFP module. +# To resolve that issue the type field of the xSFP module is also fetched so that we can know exectly what type the +# module is. Currently only the following types are recognized as SFP/QSFP module. # Meanwhile, if the a module's identifier value can't be recognized, it will be parsed according to the SKU dictionary. # This is because in the future it's possible that some new identifier value which is not regonized but backward compatible # with the current format and by doing so it can be parsed as much as possible. @@ -217,7 +217,7 @@ '18' # QSFP-DD Double Density 8X Pluggable Transceiver ] -qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') @@ -225,7 +225,7 @@ 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') -sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', 'ESCONComplianceCodes', 'SONETComplianceCodes', 'EthernetComplianceCodes','FibreChannelLinkLength', 'FibreChannelTechnology', 'SFP+CableTechnology', @@ -274,9 +274,11 @@ MCIA_ADDR_TX_DISABLE_BIT = 6 PORT_TYPE_NVE = 8 +PORT_TYPE_CPU = 4 PORT_TYPE_OFFSET = 28 PORT_TYPE_MASK = 0xF0000000 NVE_MASK = PORT_TYPE_MASK & (PORT_TYPE_NVE << PORT_TYPE_OFFSET) +CPU_MASK = PORT_TYPE_MASK & (PORT_TYPE_CPU << PORT_TYPE_OFFSET) # Global logger class instance logger = Logger() @@ -555,7 +557,7 @@ def get_transceiver_info(self): Returns: A dict which contains following keys/values : ================================================================================ - keys |Value Format |Information + keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP hardware_rev |1*255VCHAR |hardware version of SFP @@ -714,7 +716,7 @@ def get_transceiver_info(self): sfp_cable_len_data = sfpi_obj.parse_cable_len(sfp_cable_len_raw, 0) else: return None - + sfp_media_type_raw = self._read_eeprom_specific_bytes(XCVR_MEDIA_TYPE_OFFSET_QSFP_DD, XCVR_MEDIA_TYPE_WIDTH_QSFP_DD) if sfp_media_type_raw is not None: sfp_media_type_dict = sfpi_obj.parse_media_type(sfp_media_type_raw, 0) @@ -828,14 +830,14 @@ def get_transceiver_info(self): for key in qsfp_compliance_code_tup: if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: - compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] sfp_ext_specification_compliance_raw = self._read_eeprom_specific_bytes(offset + XCVR_EXT_SPECIFICATION_COMPLIANCE_OFFSET, XCVR_EXT_SPECIFICATION_COMPLIANCE_WIDTH) if sfp_ext_specification_compliance_raw is not None: sfp_ext_specification_compliance_data = sfpi_obj.parse_ext_specification_compliance(sfp_ext_specification_compliance_raw[0 : 1], 0) if sfp_ext_specification_compliance_data['data']['Extended Specification compliance']['value'] != "Unspecified": compliance_code_dict['Extended Specification compliance'] = sfp_ext_specification_compliance_data['data']['Extended Specification compliance']['value'] transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) - + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) else: for key in sfp_cable_length_tup: @@ -849,7 +851,7 @@ def get_transceiver_info(self): transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) - + return transceiver_info_dict @@ -860,7 +862,7 @@ def get_transceiver_bulk_status(self): Returns: A dict which contains following keys/values : ======================================================================== - keys |Value Format |Information + keys |Value Format |Information ---------------------------|---------------|---------------------------- RX LOS |BOOLEAN |RX lost-of-signal status, | |True if has RX los, False if not. @@ -1237,12 +1239,12 @@ def get_reset_status(self): A Boolean, True if reset enabled, False if disabled for QSFP, originally I would like to make use of Initialization complete flag bit - which is at Page a0 offset 6 bit 0 to test whether reset is complete. + which is at Page a0 offset 6 bit 0 to test whether reset is complete. However as unit testing was carried out I find this approach may fail because: 1. we make use of ethtool to read data on I2C bus rather than to read directly 2. ethtool is unable to access I2C during QSFP module being reset In other words, whenever the flag is able to be retrived, the value is always be 1 - As a result, it doesn't make sense to retrieve that flag. Just treat successfully + As a result, it doesn't make sense to retrieve that flag. Just treat successfully retrieving data as "data ready". for SFP it seems that there is not flag indicating whether reset succeed. However, we can also do it in the way for QSFP. @@ -1444,7 +1446,7 @@ def get_tx_disable_channel(self): Returns: A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent TX channels which have been disabled in this SFP. - As an example, a returned value of 0x5 indicates that channel 0 + As an example, a returned value of 0x5 indicates that channel 0 and channel 2 have been disabled. """ tx_disable_list = self.get_tx_disable() @@ -1457,6 +1459,21 @@ def get_tx_disable_channel(self): return tx_disabled + def mgmt_phy_mod_pwr_attr_get(self, power_attr_type): + sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p() + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t() + sx_mgmt_phy_mod_pwr_attr.power_attr_type = power_attr_type + sx_mgmt_phy_mod_pwr_attr_t_p_assign(sx_mgmt_phy_mod_pwr_attr_p, sx_mgmt_phy_mod_pwr_attr) + try: + rc = sx_mgmt_phy_mod_pwr_attr_get(self.sdk_handle, self.sdk_index, sx_mgmt_phy_mod_pwr_attr_p) + assert SX_STATUS_SUCCESS == rc, "sx_mgmt_phy_mod_pwr_attr_get failed" + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t_p_value(sx_mgmt_phy_mod_pwr_attr_p) + pwr_mode_attr = sx_mgmt_phy_mod_pwr_attr.pwr_mode_attr + return pwr_mode_attr.admin_pwr_mode_e, pwr_mode_attr.oper_pwr_mode_e + finally: + delete_sx_mgmt_phy_mod_pwr_attr_t_p(sx_mgmt_phy_mod_pwr_attr_p) + + def get_lpmode(self): """ Retrieves the lpmode (low power mode) status of this SFP @@ -1464,28 +1481,15 @@ def get_lpmode(self): Returns: A Boolean, True if lpmode is enabled, False if disabled """ - if self.sfp_type == QSFP_TYPE: - if self._open_sdk(): - # Get MCION - mcion = ku_mcion_reg() - mcion.module = self.sdk_index - meta = self._init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - - rc = sxd_access_reg_mcion(mcion, meta, REGISTER_NUM, None, None) - self._close_sdk() - - if rc != SXD_STATUS_SUCCESS: - logger.log_warning("sxd_access_reg_mcion getting failed, rc = %d" % rc) - return None + handle = self._open_sdk() + if handle is None: + logger.log_error("SDK handler is missing for sfp %d object" % self.index) + return False - # Get low power mode status - lpm_mask = 1 << 8 - lpm_status = (lpm_mask & mcion.module_status_bits) != 0 + admin_pwr_mode, oper_pwr_mode = self.mgmt_phy_mod_pwr_attr_get(SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E) - return lpm_status - else: - return NotImplementedError + self._close_sdk() + return oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E def get_power_override(self): @@ -1580,7 +1584,7 @@ def get_voltage(self): if self.sfp_type == QSFP_TYPE: offset = 0 offset_xcvr = 128 - + sfpd_obj = sff8436Dom() if sfpd_obj is None: return None @@ -1596,7 +1600,7 @@ def get_voltage(self): return None if self.sfp_type == QSFP_DD_TYPE: - offset = 128 + offset = 128 sfpd_obj = qsfp_dd_Dom() if sfpd_obj is None: @@ -1641,7 +1645,7 @@ def get_tx_bias(self): if self.sfp_type == QSFP_TYPE: offset = 0 offset_xcvr = 128 - + sfpd_obj = sff8436Dom() if sfpd_obj is None: return None @@ -1653,7 +1657,7 @@ def get_tx_bias(self): tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Bias']['value'])) tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Bias']['value'])) tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Bias']['value'])) - + elif self.sfp_type == QSFP_DD_TYPE: # page 11h if self.dom_rx_tx_power_bias_supported: @@ -1713,7 +1717,7 @@ def get_rx_power(self): elif self.sfp_type == QSFP_TYPE: offset = 0 offset_xcvr = 128 - + sfpd_obj = sff8436Dom() if sfpd_obj is None: return None @@ -1861,64 +1865,15 @@ def reset(self): """ handle = self._open_sdk() if handle is None: + logger.log_error("SDK handler is missing for sfp %d object" % self.index) return False - # Get PMAOS - pmaos = ku_pmaos_reg() - pmaos.module = self.sdk_index - meta = self._init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - if rc != SXD_STATUS_SUCCESS: - logger.log_warning("sxd_access_reg_pmaos getting failed, rc = %d" % rc) - self._close_sdk() - return None - - # Reset SFP - pmaos.rst = 1 - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - if rc != SXD_STATUS_SUCCESS: - logger.log_warning("sxd_access_reg_pmaos setting failed, rc = %d" % rc) - - self._close_sdk() - return rc == SXD_STATUS_SUCCESS - - - def _write_i2c_via_mcia(self, page, i2caddr, address, data, mask): - handle = self._open_sdk() - if handle is None: - return False - - mcia = ku_mcia_reg() - - meta = self._init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - - mcia.module = self.sdk_index - mcia.page_number = page - mcia.i2c_device_address = i2caddr - mcia.device_address = address - mcia.size = 1 - rc = sxd_access_reg_mcia(mcia, meta, REGISTER_NUM, None, None) - if rc != SXD_STATUS_SUCCESS: - logger.log_warning("sxd_access_reg_mcia getting failed, rc = %d" % rc) - self._close_sdk() - return False - - original_data = (mcia.dword_0 >> 24) & 0x000000FF - updated_data = original_data & (~mask) - updated_data |= (data & mask) - - mcia.dword_0 = (updated_data << 24) & 0xFF000000 - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_mcia(mcia, meta, REGISTER_NUM, None, None) - if rc != SXD_STATUS_SUCCESS: - logger.log_warning("sxd_access_reg_mcia setting failed, rc = %d" % rc) + rc = sx_mgmt_phy_mod_reset(self.sdk_handle, self.sdk_index) + if rc != SX_STATUS_SUCCESS: + logger.log_warning("sx_mgmt_phy_mod_reset failed, rc = %d" % rc) self._close_sdk() - return rc == SXD_STATUS_SUCCESS + return rc == SX_STATUS_SUCCESS def tx_disable(self, tx_disable): @@ -1935,34 +1890,7 @@ def tx_disable(self, tx_disable): for SFP, make use of bit 6 of byte at (offset 110, a2h (i2c addr 0x51)) to disable/enable tx for QSFP, set all channels to disable/enable tx """ - if self.sfp_type == SFP_TYPE: - if self.dom_tx_disable_supported: - handle = self._open_sdk() - if handle is None: - return False - - tx_disable_mask = 1 << MCIA_ADDR_TX_DISABLE_BIT - if tx_disable: - tx_disable_bit = tx_disable_mask - else: - tx_disable_bit = 0 - - return self._write_i2c_via_mcia(2, 0x51, MCIA_ADDR_TX_DISABLE, tx_disable_bit, tx_disable_mask) - else: - return False - elif self.sfp_type == QSFP_TYPE: - if self.dom_tx_disable_supported: - channel_mask = 0x0f - if tx_disable: - disable_flag = channel_mask - else: - disable_flag = 0 - - return self._write_i2c_via_mcia(0, 0x50, MCIA_ADDR_TX_CHANNEL_DISABLE, disable_flag, channel_mask) - else: - return False - else: - return NotImplementedError + return NotImplementedError def tx_disable_channel(self, channel, disable): @@ -1980,25 +1908,17 @@ def tx_disable_channel(self, channel, disable): QSFP: page a0, address 86, lower 4 bits """ - if self.sfp_type == QSFP_TYPE: - if self.dom_tx_disable_supported: - channel_mask = 1 << channel - if disable: - disable_flag = channel_mask - else: - disable_flag = 0 - - return self._write_i2c_via_mcia(0, 0x50, MCIA_ADDR_TX_CHANNEL_DISABLE, disable_flag, channel_mask) - else: - return False - else: - return NotImplementedError + return NotImplementedError def is_nve(self, port): return (port & NVE_MASK) != 0 + def is_cpu(self, port): + return (port & CPU_MASK) != 0 + + def is_port_admin_status_up(self, log_port): oper_state_p = new_sx_port_oper_state_t_p() admin_state_p = new_sx_port_admin_state_t_p() @@ -2015,11 +1935,14 @@ def is_port_admin_status_up(self, log_port): def set_port_admin_status_by_log_port(self, log_port, admin_status): rc = sx_api_port_state_set(self.sdk_handle, log_port, admin_status) - assert rc == SX_STATUS_SUCCESS, "sx_api_port_state_set failed, rc = %d" % rc + if SX_STATUS_SUCCESS != rc: + logger.log_error("sx_api_port_state_set failed, rc = %d" % rc) + return SX_STATUS_SUCCESS == rc - # Get all the ports related to the sfp, if port admin status is up, put it to list - def get_log_ports(self): + + def get_logical_ports(self): + # Get all the ports related to the sfp, if port admin status is up, put it to list port_attributes_list = new_sx_port_attributes_t_arr(SX_PORT_ATTR_ARR_SIZE) port_cnt_p = new_uint32_t_p() uint32_t_p_assign(port_cnt_p, SX_PORT_ATTR_ARR_SIZE) @@ -2031,58 +1954,56 @@ def get_log_ports(self): log_port_list = [] for i in range(0, port_cnt): port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i) - if self.is_nve(int(port_attributes.log_port)) == False \ - and port_attributes.port_mapping.module_port == self.sdk_index \ - and self.is_port_admin_status_up(port_attributes.log_port): + if not self.is_nve(int(port_attributes.log_port)) \ + and not self.is_cpu(int(port_attributes.log_port)) \ + and port_attributes.port_mapping.module_port == self.sdk_index \ + and self.is_port_admin_status_up(port_attributes.log_port): log_port_list.append(port_attributes.log_port) return log_port_list - def _set_sfp_admin_status_raw(self, admin_status): - # Get PMAOS - pmaos = ku_pmaos_reg() - pmaos.module = self.sdk_index - meta = self._init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc - - # Set admin status to PMAOS - pmaos.ase = PMAOS_ASE - pmaos.ee = PMAOS_EE - pmaos.e = PMAOS_E - pmaos.rst = PMAOS_RST - if admin_status == SX_PORT_ADMIN_STATUS_DOWN: - pmaos.admin_status = PMAOS_DISABLE - else: - pmaos.admin_status = PMAOS_ENABLE - - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc - + def mgmt_phy_mod_pwr_attr_set(self, power_attr_type, admin_pwr_mode): + result = False + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t() + sx_mgmt_phy_mod_pwr_mode_attr = sx_mgmt_phy_mod_pwr_mode_attr_t() + sx_mgmt_phy_mod_pwr_attr.power_attr_type = power_attr_type + sx_mgmt_phy_mod_pwr_mode_attr.admin_pwr_mode_e = admin_pwr_mode + sx_mgmt_phy_mod_pwr_attr.pwr_mode_attr = sx_mgmt_phy_mod_pwr_mode_attr + sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p() + sx_mgmt_phy_mod_pwr_attr_t_p_assign(sx_mgmt_phy_mod_pwr_attr_p, sx_mgmt_phy_mod_pwr_attr) + try: + rc = sx_mgmt_phy_mod_pwr_attr_set(self.sdk_handle, SX_ACCESS_CMD_SET, self.sdk_index, sx_mgmt_phy_mod_pwr_attr_p) + if SX_STATUS_SUCCESS != rc: + logger.log_error("sx_mgmt_phy_mod_pwr_attr_set failed, rc = %d" % rc) + result = False + else: + result = True + finally: + delete_sx_mgmt_phy_mod_pwr_attr_t_p(sx_mgmt_phy_mod_pwr_attr_p) - def _set_lpmode_raw(self, lpmode): - # Get PMMP - pmmp = ku_pmmp_reg() - pmmp.module = self.sdk_index - meta = self._init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc + return result - # Set low power mode status - lpm_mask = 1 << PMMP_LPMODE_BIT - if lpmode: - pmmp.eeprom_override = pmmp.eeprom_override | lpm_mask - else: - pmmp.eeprom_override = pmmp.eeprom_override & (~lpm_mask) - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None) + def _set_lpmode_raw(self, ports, attr_type, power_mode): + result = False + # Check if the module already works in the same mode + admin_pwr_mode, oper_pwr_mode = self.mgmt_phy_mod_pwr_attr_get(attr_type) + if (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E and oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E) \ + or (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E and admin_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E): + return True + try: + # Bring the port down + for port in ports: + self.set_port_admin_status_by_log_port(port, SX_PORT_ADMIN_STATUS_DOWN) + # Set the desired power mode + result = self.mgmt_phy_mod_pwr_attr_set(attr_type, power_mode) + finally: + # Bring the port up + for port in ports: + self.set_port_admin_status_by_log_port(port, SX_PORT_ADMIN_STATUS_UP) - return rc + return result def set_lpmode(self, lpmode): @@ -2098,24 +2019,18 @@ def set_lpmode(self, lpmode): """ handle = self._open_sdk() if handle is None: + logger.log_error("SDK handler is missing for sfp %d object" % self.index) return False - try: - log_port_list = self.get_log_ports() - for log_port in log_port_list: - self.set_port_admin_status_by_log_port(log_port, SX_PORT_ADMIN_STATUS_DOWN) - self._set_sfp_admin_status_raw(SX_PORT_ADMIN_STATUS_DOWN) - - result = self._set_lpmode_raw(lpmode) - self._set_sfp_admin_status_raw(SX_PORT_ADMIN_STATUS_UP) - for log_port in log_port_list: - self.set_port_admin_status_by_log_port(log_port, SX_PORT_ADMIN_STATUS_DOWN) - - return result == SXD_STATUS_SUCCESS - except: - logger.log_warning("set_lpmode failed due to some SDK failure") - self._close_sdk() - return False + log_port_list = self.get_logical_ports() + if lpmode: + self._set_lpmode_raw(log_port_list, SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E, SX_MGMT_PHY_MOD_PWR_MODE_LOW_E) + logger.log_info("Enabled low power mode for module [%d]" % (self.sdk_index)) + else: + self._set_lpmode_raw(log_port_list, SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E, SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E) + logger.log_info( "Disabled low power mode for module [%d]" % (self.sdk_index)) + self._close_sdk() + return True def set_power_override(self, power_override, power_set): @@ -2123,7 +2038,7 @@ def set_power_override(self, power_override, power_set): Sets SFP power level using power_override and power_set Args: - power_override : + power_override : A Boolean, True to override set_lpmode and use power_set to control SFP power, False to disable SFP power control through power_override/power_set and use set_lpmode @@ -2137,15 +2052,4 @@ def set_power_override(self, power_override, power_set): A boolean, True if power-override and power_set are set successfully, False if not """ - if self.sfp_type == QSFP_TYPE: - power_override_bit = 0 - if power_override: - power_override_bit |= 1 << MCIA_ADDR_POWER_OVERRIDE_POR_BIT - power_set_bit = 0 - if power_set: - power_set_bit |= 1 << MCIA_ADDR_POWER_OVERRIDE_PS_BIT - power_override_mask = 1 << MCIA_ADDR_POWER_OVERRIDE_PS_BIT | 1 << MCIA_ADDR_POWER_OVERRIDE_POR_BIT - - return self._write_i2c_via_mcia(0, 0x50, MCIA_ADDR_POWER_OVERRIDE, power_set_bit|power_override_bit, power_override_mask) - else: - return NotImplementedError + return NotImplementedError From 17c923c15b7e4b4dc3c808a63c0b09a3dc73a122 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Sat, 12 Sep 2020 00:17:23 -0700 Subject: [PATCH 1116/1427] [submodule]: update sonic-swss-common (#5362) cc2f80b 2020-09-11 | Fix SubscriberStateTable::hasCachedData formula for a timing risk --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 200f2b0a2377..cc2f80bd4756 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 200f2b0a23774e64e0a624fc19d220b3db064d28 +Subproject commit cc2f80bd4756a2c4a6b6a426fa60dab475b52681 From e2b4afc4381201fbd8718c460a249acae1eb7d64 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Sun, 13 Sep 2020 10:23:22 +0300 Subject: [PATCH 1117/1427] [Mellanox] Update platform components config files. (#5360) Signed-off-by: Nazarii Hnydyn --- .../x86_64-mlnx_msn2010-r0/platform_components.json | 5 ++++- .../x86_64-mlnx_msn2100-r0/platform_components.json | 5 ++++- .../x86_64-mlnx_msn2410-r0/platform_components.json | 6 +++++- .../x86_64-mlnx_msn2700-r0/platform_components.json | 6 +++++- .../x86_64-mlnx_msn2740-r0/platform_components.json | 5 ++++- .../x86_64-mlnx_msn3420-r0/platform_components.json | 2 ++ .../x86_64-mlnx_msn3700-r0/platform_components.json | 6 +++++- .../x86_64-mlnx_msn3700c-r0/platform_components.json | 6 +++++- .../x86_64-mlnx_msn3800-r0/platform_components.json | 7 ++++++- .../x86_64-mlnx_msn4600c-r0/platform_components.json | 2 ++ .../x86_64-mlnx_msn4700-r0/platform_components.json | 6 +++++- 11 files changed, 47 insertions(+), 9 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json index 775c6e22cf5c..2ffab4b01794 100644 --- a/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json @@ -2,8 +2,11 @@ "chassis": { "x86_64-mlnx_msn2010-r0": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json index 6a6a74301cbc..7778adf6fc1e 100644 --- a/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json @@ -2,8 +2,11 @@ "chassis": { "x86_64-mlnx_msn2100-r0": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json index 77da35ce5818..b6a1555c712f 100644 --- a/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json @@ -2,8 +2,12 @@ "chassis": { "x86_64-mlnx_msn2410-r0": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json index 2a6069414786..00ef07c819b1 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json @@ -2,8 +2,12 @@ "chassis": { "x86_64-mlnx_msn2700-r0": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json index 7964d9cb8713..1765103d2f38 100644 --- a/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json @@ -2,8 +2,11 @@ "chassis": { "x86_64-mlnx_msn2740-r0": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json index f3ea5918a09f..b243ca061aba 100644 --- a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json @@ -2,6 +2,8 @@ "chassis": { "x86_64-mlnx_msn3420-r0": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, "CPLD1": { }, "CPLD2": { }, diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json index 7c0b7598aff7..c374fb0aba76 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json @@ -2,8 +2,12 @@ "chassis": { "x86_64-mlnx_msn3700-r0": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json index c55b9feab7cb..437804c65205 100644 --- a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json @@ -2,8 +2,12 @@ "chassis": { "x86_64-mlnx_msn3700c-r0": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json index fa3b172b763e..88d3afec166b 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json @@ -2,8 +2,13 @@ "chassis": { "x86_64-mlnx_msn3800-r0": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { }, + "CPLD4": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json index 300a3827a0c4..09a7e924d1b3 100644 --- a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json @@ -2,6 +2,8 @@ "chassis": { "x86_64-mlnx_msn4600c-r0": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, "CPLD1": { }, "CPLD2": { }, diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json index 2804e29e11b1..4a64ae0cb2a0 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json @@ -2,8 +2,12 @@ "chassis": { "x86_64-mlnx_msn4700-r0": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } } } } From c6f714ba818058b07535652cf3a8cb7f320f2eb1 Mon Sep 17 00:00:00 2001 From: hanstseng Date: Tue, 15 Sep 2020 01:58:59 +0800 Subject: [PATCH 1118/1427] [delta] Support front-panel LEDs (#5348) Support controlling front-panel LEDs on x86_64-delta_ag9032v2a-r0 platform Signed-off-by: hans-tseng --- .../Delta-ag9032v2a/custom_led.bin | Bin 0 -> 460 bytes .../x86_64-delta_ag9032v2a-r0/led_proc_init.soc | 3 +++ 2 files changed, 3 insertions(+) create mode 100755 device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/custom_led.bin create mode 100644 device/delta/x86_64-delta_ag9032v2a-r0/led_proc_init.soc diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/custom_led.bin b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..fca72410f8d782e09d24e54fe98161234a95df1a GIT binary patch literal 460 zcmXZUK}eHf9LMqh^E|J69Sqi~!lb$Pl~*Es59MY`>H9v8zXY|x4noGXZKChVqn^g* z(7;m-L>a;RLf|Qc^|qRXxtPZ;?`l!U=jL^IFbJBxMu!jl;s52=eZPov_!tw|t#8#> z1+;fqQYuJQ=0ps#=fc?FQ_Nrut1eUm*4z0MhWSJ9xiy~Yo9?-i&VM#wF8S+86Bj`m zKSHp{NP~Yc*SL$F#4M^G&M>-L~s@pPrXUe9E)>)b;t!JRJY&dFWL(z?FD|=;F z%0-3~xs6;aH>A*fRN;B5l=CO~lckVgN=coyey7X+I Date: Tue, 15 Sep 2020 02:24:29 +0800 Subject: [PATCH 1119/1427] [Mellanox] update hw-mgmt package to V.7.0010.1300 (#5363) --- platform/mellanox/hw-management.mk | 2 +- ...agement-thermal-control-shell-script.patch | 28 ------------------- platform/mellanox/hw-management/hw-mgmt | 2 +- 3 files changed, 2 insertions(+), 30 deletions(-) delete mode 100644 platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index eb90cf16d4f2..521daa1c7c3b 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0010.1000 +MLNX_HW_MANAGEMENT_VERSION = 7.0010.1300 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch b/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch deleted file mode 100644 index eef970ed23c7..000000000000 --- a/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 3bce9e33132a86c0a53a7b0a49ee1932d65bfb7f Mon Sep 17 00:00:00 2001 -From: junchao -Date: Wed, 6 May 2020 11:37:56 +0800 -Subject: [PATCH] Disable hw-management thermal control shell script - ---- - usr/usr/bin/hw-management.sh | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh -index 65e5d39..cffff7a 100755 ---- a/usr/usr/bin/hw-management.sh -+++ b/usr/usr/bin/hw-management.sh -@@ -832,7 +832,10 @@ do_start() - if [ -f $config_path/max_tachos ]; then - max_tachos=$(<$config_path/max_tachos) - fi -- $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& -+ -+ # Disable thermal control shell script in hw-management -+ # because there has already been that in SONiC -+ # $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& - } - - do_stop() --- -1.9.1 - diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index cdacf1e932f9..dec7935777b5 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit cdacf1e932f929c8dedde6c7e14759a2083aac66 +Subproject commit dec7935777b52d31a2220bad8b0cec4b71ec0961 From 353003f6eecb08b3b19147f22775370d41d7813c Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Mon, 14 Sep 2020 21:28:24 +0300 Subject: [PATCH 1120/1427] Change update_feature_state call to pass False as default if feature has no 'has_timer' field (#5260) * Pass False as default if feature has no timer field * Update hostcfgd to fit the new changes merged New changes can be found in PR:5248 --- files/image_config/hostcfgd/hostcfgd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index acfc3d0c8055..2c66598e3581 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -292,7 +292,7 @@ class HostConfigDaemon: syslog.syslog(syslog.LOG_WARNING, "Eanble state of feature '{}' is None".format(feature_name)) continue - update_feature_state(feature_name, state, feature_table[feature_name]['has_timer']) + update_feature_state(feature_name, state, feature_table[feature_name].get('has_timer', 'False')) def aaa_handler(self, key, data): self.aaacfg.aaa_update(key, data) @@ -334,7 +334,7 @@ class HostConfigDaemon: syslog.syslog(syslog.LOG_WARNING, "Enable state of feature '{}' is None".format(feature_name)) return - update_feature_state(feature_name, state, feature_table[feature_name]['has_timer']) + update_feature_state(feature_name, state, feature_table[feature_name].get('has_timer', 'False')) def start(self): # Update all feature states once upon starting From 3a901eeae0f65e924ecf35d92a8bd9bd2b8bdcc6 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 14 Sep 2020 16:36:37 -0700 Subject: [PATCH 1121/1427] [procdockerstatsd] Inherit DaemonBase class from sonic-py-common package (#5372) Eliminate duplicate logging code by inheriting from DaemonBase class in sonic-py-common package. --- .../procdockerstatsd/procdockerstatsd | 77 +++++++++---------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd index 65d4b029b0ff..00501f810072 100755 --- a/files/image_config/procdockerstatsd/procdockerstatsd +++ b/files/image_config/procdockerstatsd/procdockerstatsd @@ -8,10 +8,10 @@ import os import re import subprocess import sys -import syslog import time from datetime import datetime +from sonic_py_common import daemon_base import swsssdk VERSION = '1.0' @@ -20,26 +20,11 @@ SYSLOG_IDENTIFIER = "procdockerstatsd" REDIS_HOSTIP = "127.0.0.1" -# ========================== Syslog wrappers ========================== -def log_info(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() -def log_warning(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_WARNING, msg) - syslog.closelog() +class ProcDockerStats(daemon_base.DaemonBase): -def log_error(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() - -# ========================== ProcessDocker class ========================== -class ProcDockerStats: - - def __init__(self): + def __init__(self, log_identifier): + super(ProcDockerStats, self).__init__(log_identifier) self.state_db = swsssdk.SonicV2Connector(host=REDIS_HOSTIP) self.state_db.connect("STATE_DB") @@ -47,7 +32,7 @@ class ProcDockerStats: proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) (stdout, stderr) = proc.communicate() if proc.returncode != 0: - log_error("Error running command '{}'".format(cmd)) + self.log_error("Error running command '{}'".format(cmd)) return None else: return stdout @@ -144,11 +129,11 @@ class ProcDockerStats: cmd = "docker stats --no-stream -a" data = self.run_command(cmd) if not data: - log_error("'{}' returned null output".format(cmd)) + self.log_error("'{}' returned null output".format(cmd)) return False dockerdata = self.format_docker_cmd_output(data) if not dockerdata: - log_error("formatting for docker output failed") + self.log_error("formatting for docker output failed") return False # wipe out all data from state_db before updating self.state_db.delete_all_by_pattern('STATE_DB', 'DOCKER_STATS|*') @@ -188,26 +173,36 @@ class ProcDockerStats: self.state_db.set('STATE_DB', key1, key2, value2) def run(self): - self.update_dockerstats_command() - datetimeobj = datetime.now() - # Adding key to store latest update time. - self.update_state_db('DOCKER_STATS|LastUpdateTime', 'lastupdate', datetimeobj) - self.update_processstats_command() - self.update_state_db('PROCESS_STATS|LastUpdateTime', 'lastupdate', datetimeobj) - -# main start + self.log_info("Starting up ...") + + if not os.getuid() == 0: + self.log_error("Must be root to run this daemon") + print("Must be root to run this daemon") + sys.exit(1) + + while True: + self.update_dockerstats_command() + datetimeobj = datetime.now() + # Adding key to store latest update time. + self.update_state_db('DOCKER_STATS|LastUpdateTime', 'lastupdate', datetimeobj) + self.update_processstats_command() + self.update_state_db('PROCESS_STATS|LastUpdateTime', 'lastupdate', datetimeobj) + + # Data need to be updated every 2 mins. hence adding delay of 120 seconds + time.sleep(120) + + self.log_info("Exiting ...") + + def main(): - log_info("process-docker stats daemon starting up..") - if not os.getuid() == 0: - log_error("Must be root to run process-docker daemon") - print "Error: Must be root to run process-docker daemon" - sys.exit(1) - pd = ProcDockerStats() - # Data need to be updated every 2 mins. hence adding delay of 120 seconds - while True: - pd.run() - time.sleep(120) - log_info("process-docker stats daemon exited") + # Instantiate a ProcDockerStats object + pd = ProcDockerStats(SYSLOG_IDENTIFIER) + + # Log all messages from INFO level and higher + pd.set_min_log_priority_info() + + pd.run() + if __name__ == '__main__': main() From 12c94a74318cd9afe0516ddab6fed41f474df6c2 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 15 Sep 2020 10:55:55 -0700 Subject: [PATCH 1122/1427] [lldpmgrd] Inherit DaemonBase class from sonic-py-common package (#5370) Eliminate duplicate logging and signal handling code by inheriting from DaemonBase class in sonic-py-common package. --- dockers/docker-lldp/lldpmgrd | 92 ++++++++++-------------------------- 1 file changed, 25 insertions(+), 67 deletions(-) diff --git a/dockers/docker-lldp/lldpmgrd b/dockers/docker-lldp/lldpmgrd index a0dff5d402f8..dcfaab2244c5 100755 --- a/dockers/docker-lldp/lldpmgrd +++ b/dockers/docker-lldp/lldpmgrd @@ -16,11 +16,10 @@ try: import os - import signal import subprocess import sys - import syslog - import os.path + + from sonic_py_common import daemon_base from swsscommon import swsscommon except ImportError as err: raise ImportError("%s - required module not found" % str(err)) @@ -30,50 +29,7 @@ VERSION = "1.0" SYSLOG_IDENTIFIER = "lldpmgrd" -# ========================== Syslog wrappers ========================== - -def log_debug(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_DEBUG, msg) - syslog.closelog() - - -def log_info(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - - -def log_warning(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_WARNING, msg) - syslog.closelog() - - -def log_error(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() - - -# ========================== Signal Handling ========================== - -def signal_handler(sig, frame): - if sig == signal.SIGHUP: - log_info("Caught SIGHUP - ignoring...") - return - elif sig == signal.SIGINT: - log_info("Caught SIGINT - exiting...") - sys.exit(128 + sig) - elif sig == signal.SIGTERM: - log_info("Caught SIGTERM - exiting...") - sys.exit(128 + sig) - else: - log_warning("Caught unhandled signal '" + sig + "'") - -# ============================== Classes ============================== - -class LldpManager(object): +class LldpManager(daemon_base.DaemonBase): """ Class which subscribes to notifications of changes in the PORT table of the Redis State database and updates LLDP configuration accordingly for @@ -86,7 +42,9 @@ class LldpManager(object): """ REDIS_TIMEOUT_MS = 0 - def __init__(self): + def __init__(self, log_identifier): + super(LldpManager, self).__init__(log_identifier) + # Open a handle to the Config database self.config_db = swsscommon.DBConnector("CONFIG_DB", self.REDIS_TIMEOUT_MS, @@ -114,7 +72,7 @@ class LldpManager(object): # Get the oper-status for the port if port_table_dict.has_key("oper_status"): port_oper_status = port_table_dict.get("oper_status") - log_info("Port name {} oper status: {}".format(port_name, port_oper_status)) + self.log_info("Port name {} oper status: {}".format(port_name, port_oper_status)) return port_oper_status == "up" else: return False @@ -123,7 +81,7 @@ class LldpManager(object): (init_status, init_fvp) = port_table.get("PortInitDone") #The initialization procedure is done, but don't have this port entry if init_status: - log_error("Port '{}' not found in {} table in App DB".format(port_name, swsscommon.APP_PORT_TABLE_NAME)) + self.log_error("Port '{}' not found in {} table in App DB".format(port_name, swsscommon.APP_PORT_TABLE_NAME)) return False def generate_pending_lldp_config_cmd_for_port(self, port_name): @@ -143,14 +101,14 @@ class LldpManager(object): # Get the port alias. If None or empty string, use port name instead port_alias = port_table_dict.get("alias") if not port_alias: - log_info("Unable to retrieve port alias for port '{}'. Using port name instead.".format(port_name)) + self.log_info("Unable to retrieve port alias for port '{}'. Using port name instead.".format(port_name)) port_alias = port_name # Get the port description. If None or empty string, we'll skip this configuration port_desc = port_table_dict.get("description") else: - log_error("Port '{}' not found in {} table in Config DB. Using port name instead of port alias.".format(port_name, swsscommon.CFG_PORT_TABLE_NAME)) + self.log_error("Port '{}' not found in {} table in Config DB. Using port name instead of port alias.".format(port_name, swsscommon.CFG_PORT_TABLE_NAME)) port_alias = port_name lldpcli_cmd = "lldpcli configure ports {0} lldp portidsubtype local {1}".format(port_name, port_alias) @@ -159,7 +117,7 @@ class LldpManager(object): if port_desc: lldpcli_cmd += " description '{}'".format(port_desc) else: - log_info("Unable to retrieve description for port '{}'. Not adding port description".format(port_name)) + self.log_info("Unable to retrieve description for port '{}'. Not adding port description".format(port_name)) # Add the command to our dictionary of pending commands, overwriting any # previous pending command for this port @@ -170,7 +128,7 @@ class LldpManager(object): to_delete = [] for (port_name, cmd) in self.pending_cmds.iteritems(): - log_debug("Running command: '{}'".format(cmd)) + self.log_debug("Running command: '{}'".format(cmd)) proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -184,7 +142,7 @@ class LldpManager(object): if proc.returncode == 0: to_delete.append(port_name) else: - log_warning("Command failed '{}': {}".format(cmd, stderr)) + self.log_warning("Command failed '{}': {}".format(cmd, stderr)) # Delete all successful commands from self.pending_cmds for port_name in to_delete: @@ -198,6 +156,13 @@ class LldpManager(object): Subscribe to CONFIG_DB - get notified of port config changes Update LLDP configuration accordingly. """ + self.log_info("Starting up...") + + if not os.geteuid() == 0: + self.log_error("Must be root to run this daemon") + print("Error: Must be root to run this daemon") + sys.exit(1) + # Set select timeout to 10 seconds SELECT_TIMEOUT_MS = 1000 * 10 @@ -246,21 +211,14 @@ class LldpManager(object): # ============================= Functions ============================= def main(): - log_info("Starting up...") - - if not os.geteuid() == 0: - log_error("Must be root to run this daemon") - print "Error: Must be root to run this daemon" - sys.exit(1) + # Instantiate a LldpManager object + lldpmgr = LldpManager(SYSLOG_IDENTIFIER) - # Register our signal handlers - signal.signal(signal.SIGHUP, signal_handler) - signal.signal(signal.SIGINT, signal_handler) - signal.signal(signal.SIGTERM, signal_handler) + # Log all messages from INFO level and higher + lldpmgr.set_min_log_priority_info() - # Instantiate a LldpManager object - lldpmgr = LldpManager() lldpmgr.run() + if __name__ == "__main__": main() From 1ac146dd97af89057571e9378af492c852a2cf88 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 15 Sep 2020 13:34:41 -0700 Subject: [PATCH 1123/1427] [caclmgrd] Inherit DaemonBase class from sonic-py-common package (#5373) Eliminate duplicate logging code by inheriting from DaemonBase class in sonic-py-common package. --- files/image_config/caclmgrd/caclmgrd | 80 ++++++++++++---------------- 1 file changed, 33 insertions(+), 47 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index ffeb23ca9d16..0189743820f3 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -15,9 +15,8 @@ try: import os import subprocess import sys - import syslog - from sonic_py_common import device_info + from sonic_py_common import daemon_base, device_info from swsscommon import swsscommon from swsssdk import SonicDBConfig, ConfigDBConnector except ImportError as err: @@ -28,25 +27,6 @@ VERSION = "1.0" SYSLOG_IDENTIFIER = "caclmgrd" -# ========================== Syslog wrappers ========================== - -def log_info(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - - -def log_warning(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_WARNING, msg) - syslog.closelog() - - -def log_error(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() - # ========================== Helper Functions ========================= @@ -61,7 +41,7 @@ def _ip_prefix_in_key(key): # ============================== Classes ============================== -class ControlPlaneAclManager(object): +class ControlPlaneAclManager(daemon_base.DaemonBase): """ Class which reads control plane ACL tables and rules from Config DB, translates them into equivalent iptables commands and runs those @@ -91,7 +71,9 @@ class ControlPlaneAclManager(object): } } - def __init__(self): + def __init__(self, log_identifier): + super(ControlPlaneAclManager, self).__init__(log_identifier) + SonicDBConfig.load_sonic_global_db_config() self.config_db_map = {} self.iptables_cmd_ns_prefix = {} @@ -131,7 +113,7 @@ class ControlPlaneAclManager(object): (stdout, stderr) = proc.communicate() if proc.returncode != 0: - log_error("Error running command '{}'".format(cmd)) + self.log_error("Error running command '{}'".format(cmd)) elif stdout: return stdout.rstrip('\n') @@ -192,7 +174,7 @@ class ControlPlaneAclManager(object): elif isinstance(ip_ntwrk, ipaddress.IPv6Network): block_ip2me_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "ip6tables -A INPUT -d {}/{} -j DROP".format(ip_addr, ip_ntwrk.max_prefixlen)) else: - log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + self.log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) return block_ip2me_cmds @@ -327,12 +309,12 @@ class ControlPlaneAclManager(object): for acl_service in acl_services: if acl_service not in self.ACL_SERVICES: - log_warning("Ignoring control plane ACL '{}' with unrecognized service '{}'" - .format(table_name, acl_service)) + self.log_warning("Ignoring control plane ACL '{}' with unrecognized service '{}'" + .format(table_name, acl_service)) continue - log_info("Translating ACL rules for control plane ACL '{}' (service: '{}')" - .format(table_name, acl_service)) + self.log_info("Translating ACL rules for control plane ACL '{}' (service: '{}')" + .format(table_name, acl_service)) # Obtain default IP protocol(s) and destination port(s) for this service ip_protocols = self.ACL_SERVICES[acl_service]["ip_protocols"] @@ -343,13 +325,13 @@ class ControlPlaneAclManager(object): for ((rule_table_name, rule_id), rule_props) in self._rules_db_info.iteritems(): if rule_table_name == table_name: if not rule_props: - log_warning("rule_props for rule_id {} empty or null!".format(rule_id)) + self.log_warning("rule_props for rule_id {} empty or null!".format(rule_id)) continue try: acl_rules[rule_props["PRIORITY"]] = rule_props except KeyError: - log_error("rule_props for rule_id {} does not have key 'PRIORITY'!".format(rule_id)) + self.log_error("rule_props for rule_id {} does not have key 'PRIORITY'!".format(rule_id)) continue # If we haven't determined the IP version for this ACL table yet, @@ -362,19 +344,19 @@ class ControlPlaneAclManager(object): table_ip_version = 4 if (self.is_rule_ipv6(rule_props) and (table_ip_version == 4)): - log_error("CtrlPlane ACL table {} is a IPv4 based table and rule {} is a IPV6 rule! Ignoring rule." - .format(table_name, rule_id)) + self.log_error("CtrlPlane ACL table {} is a IPv4 based table and rule {} is a IPV6 rule! Ignoring rule." + .format(table_name, rule_id)) acl_rules.pop(rule_props["PRIORITY"]) elif (self.is_rule_ipv4(rule_props) and (table_ip_version == 6)): - log_error("CtrlPlane ACL table {} is a IPv6 based table and rule {} is a IPV4 rule! Ignroing rule." - .format(table_name, rule_id)) + self.log_error("CtrlPlane ACL table {} is a IPv6 based table and rule {} is a IPV4 rule! Ignroing rule." + .format(table_name, rule_id)) acl_rules.pop(rule_props["PRIORITY"]) # If we were unable to determine whether this ACL table contains # IPv4 or IPv6 rules, log a message and skip processing this table. if not table_ip_version: - log_warning("Unable to determine if ACL table '{}' contains IPv4 or IPv6 rules. Skipping table..." - .format(table_name)) + self.log_warning("Unable to determine if ACL table '{}' contains IPv4 or IPv6 rules. Skipping table..." + .format(table_name)) continue # For each ACL rule in this table (in descending order of priority) @@ -382,7 +364,7 @@ class ControlPlaneAclManager(object): rule_props = acl_rules[priority] if "PACKET_ACTION" not in rule_props: - log_error("ACL rule does not contain PACKET_ACTION property") + self.log_error("ACL rule does not contain PACKET_ACTION property") continue # Apply the rule to the default protocol(s) for this ACL service @@ -437,9 +419,9 @@ class ControlPlaneAclManager(object): commands and runs them. """ iptables_cmds = self.get_acl_rules_and_translate_to_iptables_commands(namespace) - log_info("Issuing the following iptables commands:") + self.log_info("Issuing the following iptables commands:") for cmd in iptables_cmds: - log_info(" " + cmd) + self.log_info(" " + cmd) self.run_commands(iptables_cmds) @@ -447,6 +429,13 @@ class ControlPlaneAclManager(object): # Select Time-out for 10 Seconds SELECT_TIMEOUT_MS = 1000 * 10 + self.log_info("Starting up ...") + + if not os.geteuid() == 0: + self.log_error("Must be root to run this daemon") + print("Error: Must be root to run this daemon") + sys.exit(1) + # Initlaize Global config that loads all database*.json if device_info.is_multi_npu(): swsscommon.SonicDBConfig.initializeGlobalConfig() @@ -494,15 +483,12 @@ class ControlPlaneAclManager(object): def main(): - log_info("Starting up...") + # Instantiate a ControlPlaneAclManager object + caclmgr = ControlPlaneAclManager(SYSLOG_IDENTIFIER) - if not os.geteuid() == 0: - log_error("Must be root to run this daemon") - print "Error: Must be root to run this daemon" - sys.exit(1) + # Log all messages from INFO level and higher + caclmgr.set_min_log_priority_info() - # Instantiate a ControlPlaneAclManager object - caclmgr = ControlPlaneAclManager() caclmgr.run() From da3579cf3660a41b5a09879fdd848c3c03f6a349 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Tue, 15 Sep 2020 22:20:12 +0000 Subject: [PATCH 1124/1427] DellEMC S6100: Log HW reboot reason registers (#5361) --- .../s6100/scripts/track_reboot_reason.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh index 0686d577c9e4..27ea3553475b 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh @@ -77,7 +77,7 @@ _get_smf_reset_register(){ echo "Third reset - $third_reset" >> $RESET_REASON_FILE echo "Fourth reset - $fourth_reset" >> $RESET_REASON_FILE fi - + logger -p user.info -t DELL_S6100_REBOOT_CAUSE "RST value in NVRAM: $first_reset, $second_reset, $third_reset, $fourth_reset" # Clearing NVRAM values to holding next reset values nvram_rd_wr.py --set --val 0xee --offset 0x58 nvram_rd_wr.py --set --val 0xee --offset 0x5c @@ -147,8 +147,11 @@ update_mailbox_register(){ is_wd_reboot=$(_is_watchdog_reset) + por=$(cat $SMF_POWERON_REASON) + rst=$(cat $SMF_RESET_REASON) mbr=$(cat $MAILBOX_POWERON_REASON) reason=$(echo $mbr | cut -d 'x' -f2) + logger -p user.info -t DELL_S6100_REBOOT_CAUSE "POR: $por, RST: $rst, MBR: $mbr" if [[ $reason = "ff" ]]; then echo "None" > $REBOOT_REASON_FILE echo 0xbb > $MAILBOX_POWERON_REASON From 558ec53aa66aaf42f90ecce771f98ebc6d2c5ea6 Mon Sep 17 00:00:00 2001 From: Petro Bratash <68950226+bratashX@users.noreply.github.com> Date: Wed, 16 Sep 2020 01:21:31 +0300 Subject: [PATCH 1125/1427] Fix bug with pcie-check.service (#5368) * Change STATE_DB key (PCIE_STATUS|PCIE_DEVICES -> PCIE_DEVICES) Signed-off-by: Petro Bratash * [pcie-check.service] Add dependency on database.service Signed-off-by: Petro Bratash --- files/image_config/pcie-check/pcie-check.service | 2 +- files/image_config/pcie-check/pcie-check.sh | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/files/image_config/pcie-check/pcie-check.service b/files/image_config/pcie-check/pcie-check.service index 9bea910a7fbd..fbf3cfd3f19d 100644 --- a/files/image_config/pcie-check/pcie-check.service +++ b/files/image_config/pcie-check/pcie-check.service @@ -1,6 +1,6 @@ [Unit] Description=Check the PCIe device presence and status -After=rc.local.service +After=rc.local.service database.service [Service] Type=simple diff --git a/files/image_config/pcie-check/pcie-check.sh b/files/image_config/pcie-check/pcie-check.sh index 90fc0bb5cae9..4ef2ce3047f0 100755 --- a/files/image_config/pcie-check/pcie-check.sh +++ b/files/image_config/pcie-check/pcie-check.sh @@ -16,7 +16,7 @@ function debug() function check_and_rescan_pcie_devices() { - PCIE_CHK_CMD=$(sudo pcieutil pcie-check |grep "$RESULTS") + PCIE_CHK_CMD='sudo pcieutil pcie-check |grep "$RESULTS"' PLATFORM=$(sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) if [ ! -f /usr/share/sonic/device/$PLATFORM/plugins/pcie.yaml ]; then @@ -36,8 +36,8 @@ function check_and_rescan_pcie_devices() break fi - if [ "$PCIE_CHK_CMD" = "$EXPECTED" ]; then - redis-cli -n 6 SET "PCIE_STATUS|PCIE_DEVICES" "PASSED" + if [ "$(eval $PCIE_CHK_CMD)" = "$EXPECTED" ]; then + redis-cli -n 6 HSET "PCIE_DEVICES" "status" "PASSED" debug "PCIe check passed" exit else @@ -53,7 +53,7 @@ function check_and_rescan_pcie_devices() done debug "PCIe check failed" - redis-cli -n 6 SET "PCIE_STATUS|PCIE_DEVICES" "FAILED" + redis-cli -n 6 HSET "PCIE_DEVICES" "status" "FAILED" } check_and_rescan_pcie_devices From 15f5d473383430ba811397964752676ac55f3c26 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Tue, 15 Sep 2020 15:27:36 -0700 Subject: [PATCH 1126/1427] [dhcpmon] Print Both Snapshot And Current Counters (#5374) Printing both snapshot and current counter sets will make it easier to pinpoint which message type(s) is/are not being relayed. This PR prints both counter sets. Also, this PR defines gnu11 as a C standard to compile with in order to avoid making changes when porting to 201811 branch. singed-off-by: Tamer Ahmed --- .../docker-dhcp-relay.supervisord.conf.j2 | 2 +- src/dhcpmon/debian/rules | 6 ++- src/dhcpmon/src/dhcp_device.c | 52 +++++++++++-------- src/dhcpmon/src/dhcp_device.h | 7 +-- src/dhcpmon/src/dhcp_devman.c | 22 +++++--- src/dhcpmon/src/dhcp_devman.h | 5 +- src/dhcpmon/src/dhcp_mon.c | 9 ++-- 7 files changed, 64 insertions(+), 39 deletions(-) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index ae5af58ba80d..9e8c553b65c6 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -139,7 +139,7 @@ command=/usr/sbin/dhcpmon -id {{ vlan_name }} {% endfor %} {% if MGMT_INTERFACE %} {% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} -{% if prefix | ipv4 %} -im {{ name }}{% endif %} +{% if prefix | ipv4 %} -im {{ name }}{% endif -%} {% endfor %} {% endif %} diff --git a/src/dhcpmon/debian/rules b/src/dhcpmon/debian/rules index 3995a26d7fcd..00c628b6625f 100755 --- a/src/dhcpmon/debian/rules +++ b/src/dhcpmon/debian/rules @@ -1,3 +1,7 @@ #!/usr/bin/make -f + +DEB_CFLAGS_APPEND=-std=gnu11 +export DEB_CFLAGS_APPEND + %: - dh $@ --with systemd + dh $@ --parallel diff --git a/src/dhcpmon/src/dhcp_device.c b/src/dhcpmon/src/dhcp_device.c index 84ec9be9b65e..f5cb705ee285 100644 --- a/src/dhcpmon/src/dhcp_device.c +++ b/src/dhcpmon/src/dhcp_device.c @@ -25,7 +25,7 @@ #include "dhcp_device.h" /** Counter print width */ -#define DHCP_COUNTER_WIDTH 10 +#define DHCP_COUNTER_WIDTH 9 /** Start of Ether header of a captured frame */ #define ETHER_START_OFFSET 0 @@ -353,29 +353,39 @@ static dhcp_mon_status_t dhcp_device_check_health(dhcp_mon_check_t check_type, } /** - * @code dhcp_print_counters(vlan_intf, counters); + * @code dhcp_print_counters(vlan_intf, type, counters); * * @brief prints DHCP counters to sylsog. * + * @param vlan_intf vlan interface name + * @param type counter type * @param counters interface counter + * + * @return none */ -static void dhcp_print_counters(const char *vlan_intf, uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) +static void dhcp_print_counters(const char *vlan_intf, + dhcp_counters_type_t type, + uint64_t counters[][DHCP_MESSAGE_TYPE_COUNT]) { - uint64_t *rx_counters = counters[DHCP_COUNTERS_CURRENT][DHCP_RX]; - uint64_t *tx_counters = counters[DHCP_COUNTERS_CURRENT][DHCP_TX]; - - syslog(LOG_NOTICE, - "[%*s] DHCP Discover rx/tx: %*lu/%*lu, Offer rx/tx: %*lu/%*lu, " - "Request rx/tx: %*lu/%*lu, ACK rx/tx: %*lu/%*lu\n", - IF_NAMESIZE, vlan_intf, - DHCP_COUNTER_WIDTH, rx_counters[DHCP_MESSAGE_TYPE_DISCOVER], - DHCP_COUNTER_WIDTH, tx_counters[DHCP_MESSAGE_TYPE_DISCOVER], - DHCP_COUNTER_WIDTH, rx_counters[DHCP_MESSAGE_TYPE_OFFER], - DHCP_COUNTER_WIDTH, tx_counters[DHCP_MESSAGE_TYPE_OFFER], - DHCP_COUNTER_WIDTH, rx_counters[DHCP_MESSAGE_TYPE_REQUEST], - DHCP_COUNTER_WIDTH, tx_counters[DHCP_MESSAGE_TYPE_REQUEST], - DHCP_COUNTER_WIDTH, rx_counters[DHCP_MESSAGE_TYPE_ACK], - DHCP_COUNTER_WIDTH, tx_counters[DHCP_MESSAGE_TYPE_ACK]); + static const char *counter_desc[DHCP_COUNTERS_COUNT] = { + [DHCP_COUNTERS_CURRENT] = " Current", + [DHCP_COUNTERS_SNAPSHOT] = "Snapshot" + }; + + syslog( + LOG_NOTICE, + "[%*s-%*s rx/tx] Discover: %*lu/%*lu, Offer: %*lu/%*lu, Request: %*lu/%*lu, ACK: %*lu/%*lu\n", + IF_NAMESIZE, vlan_intf, + (int) strlen(counter_desc[type]), counter_desc[type], + DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_DISCOVER], + DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_DISCOVER], + DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_OFFER], + DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_OFFER], + DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_REQUEST], + DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_REQUEST], + DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_ACK], + DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_ACK] + ); } /** @@ -624,13 +634,13 @@ void dhcp_device_update_snapshot(dhcp_device_context_t *context) } /** - * @code dhcp_device_print_status(context); + * @code dhcp_device_print_status(context, type); * * @brief prints status counters to syslog. */ -void dhcp_device_print_status(dhcp_device_context_t *context) +void dhcp_device_print_status(dhcp_device_context_t *context, dhcp_counters_type_t type) { if (context != NULL) { - dhcp_print_counters(context->intf, context->counters); + dhcp_print_counters(context->intf, type, context->counters[type]); } } diff --git a/src/dhcpmon/src/dhcp_device.h b/src/dhcpmon/src/dhcp_device.h index 9eee6691017f..133b9265a434 100644 --- a/src/dhcpmon/src/dhcp_device.h +++ b/src/dhcpmon/src/dhcp_device.h @@ -169,14 +169,15 @@ dhcp_mon_status_t dhcp_device_get_status(dhcp_mon_check_t check_type, dhcp_devic void dhcp_device_update_snapshot(dhcp_device_context_t *context); /** - * @code dhcp_device_print_status(context); + * @code dhcp_device_print_status(context, type); * * @brief prints status counters to syslog. If context is null, it will print aggregate status * - * @param context Device (interface) context + * @param context Device (interface) context + * @param counters_type Counter type to be printed * * @return none */ -void dhcp_device_print_status(dhcp_device_context_t *context); +void dhcp_device_print_status(dhcp_device_context_t *context, dhcp_counters_type_t type); #endif /* DHCP_DEVICE_H_ */ diff --git a/src/dhcpmon/src/dhcp_devman.c b/src/dhcpmon/src/dhcp_devman.c index e9a47ae5817a..35378a631ca7 100644 --- a/src/dhcpmon/src/dhcp_devman.c +++ b/src/dhcpmon/src/dhcp_devman.c @@ -198,25 +198,35 @@ dhcp_mon_status_t dhcp_devman_get_status(dhcp_mon_check_t check_type, dhcp_devic */ void dhcp_devman_update_snapshot(dhcp_device_context_t *context) { - dhcp_device_update_snapshot(context); + if (context == NULL) { + struct intf *int_ptr; + + LIST_FOREACH(int_ptr, &intfs, entry) { + dhcp_device_update_snapshot(int_ptr->dev_context); + } + + dhcp_device_update_snapshot(dhcp_devman_get_agg_dev()); + } else { + dhcp_device_update_snapshot(context); + } } /** - * @code dhcp_devman_print_status(context); + * @code dhcp_devman_print_status(context, type); * * @brief prints status counters to syslog, if context is null, it prints status counters for all interfaces */ -void dhcp_devman_print_status(dhcp_device_context_t *context) +void dhcp_devman_print_status(dhcp_device_context_t *context, dhcp_counters_type_t type) { if (context == NULL) { struct intf *int_ptr; LIST_FOREACH(int_ptr, &intfs, entry) { - dhcp_device_print_status(int_ptr->dev_context); + dhcp_device_print_status(int_ptr->dev_context, type); } - dhcp_device_print_status(dhcp_devman_get_agg_dev()); + dhcp_device_print_status(dhcp_devman_get_agg_dev(), type); } else { - dhcp_device_print_status(context); + dhcp_device_print_status(context, type); } } diff --git a/src/dhcpmon/src/dhcp_devman.h b/src/dhcpmon/src/dhcp_devman.h index 4d8a53265715..bba7076902cb 100644 --- a/src/dhcpmon/src/dhcp_devman.h +++ b/src/dhcpmon/src/dhcp_devman.h @@ -97,14 +97,15 @@ dhcp_mon_status_t dhcp_devman_get_status(dhcp_mon_check_t check_type, dhcp_devic void dhcp_devman_update_snapshot(dhcp_device_context_t *context); /** - * @code dhcp_devman_print_status(context); + * @code dhcp_devman_print_status(context, type); * * @brief prints status counters to syslog * * @param context pointer to device (interface) context + * @param type Counter type to be printed * * @return none */ -void dhcp_devman_print_status(dhcp_device_context_t *context); +void dhcp_devman_print_status(dhcp_device_context_t *context, dhcp_counters_type_t type); #endif /* DHCP_DEVMAN_H_ */ diff --git a/src/dhcpmon/src/dhcp_mon.c b/src/dhcpmon/src/dhcp_mon.c index 8147b5057c8f..74d9869741d1 100644 --- a/src/dhcpmon/src/dhcp_mon.c +++ b/src/dhcpmon/src/dhcp_mon.c @@ -71,7 +71,7 @@ static dhcp_mon_state_t state_data[] = { static void signal_callback(evutil_socket_t fd, short event, void *arg) { syslog(LOG_ALERT, "Received signal: '%s'\n", strsignal(fd)); - dhcp_devman_print_status(NULL); + dhcp_devman_print_status(NULL, DHCP_COUNTERS_CURRENT); if ((fd == SIGTERM) || (fd == SIGINT)) { dhcp_mon_stop(); } @@ -96,7 +96,8 @@ static void check_dhcp_relay_health(dhcp_mon_state_t *state_data) case DHCP_MON_STATUS_UNHEALTHY: if (++state_data->count > dhcp_unhealthy_max_count) { syslog(LOG_ALERT, state_data->msg, state_data->count * window_interval_sec, context->intf); - dhcp_devman_print_status(context); + dhcp_devman_print_status(context, DHCP_COUNTERS_SNAPSHOT); + dhcp_devman_print_status(context, DHCP_COUNTERS_CURRENT); } break; case DHCP_MON_STATUS_HEALTHY: @@ -130,9 +131,7 @@ static void timeout_callback(evutil_socket_t fd, short event, void *arg) check_dhcp_relay_health(&state_data[i]); } - for (uint8_t i = 0; i < sizeof(state_data) / sizeof(*state_data); i++) { - dhcp_devman_update_snapshot(state_data[i].get_context()); - } + dhcp_devman_update_snapshot(NULL); } /** From 9bf4b0a93eba1ed1d2b1a7554a3b56e6612d7e0e Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Tue, 15 Sep 2020 15:29:48 -0700 Subject: [PATCH 1127/1427] [baseimage]: Change the loopback mask from /8 to /16 (#5353) As per the VOQ HLDs, internal networking between the linecards and supervisor is required within a chassis. Allocating 127.X/16 subnets for private communication within a chassis is a good candidate. It doesn't require any external IP allocation as well as ensure that the traffic will not leave the chassis. References: https://github.com/Azure/SONiC/pull/622 https://github.com/Azure/SONiC/pull/639 **- How I did it** Changed the `interfaces.j2` file to add `127.0.0.1/16` as the `lo` ip address. Then once the interface is up, the post-up command removes the `127.0.0.1/8` ip address. The order in which the netmask change is made matters for `127.0.0.1` to be reachable at all times. **- How to verify it** ``` root@sonic:~# ip address show dev lo 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/16 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever ``` Co-authored-by: Baptiste Covolato --- files/image_config/interfaces/interfaces.j2 | 5 ++++- src/sonic-config-engine/tests/sample_output/interfaces | 3 +++ src/sonic-config-engine/tests/sample_output/mvrf_interfaces | 5 ++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index dbedd5e9418a..1136c0970db0 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -13,7 +13,7 @@ iface mgmt # The loopback network interface for mgmt VRF that is required for applications like NTP up ip link add lo-m type dummy up ip link set dev lo-m master mgmt - up ip addr add 127.0.0.1/8 dev lo-m + up ip addr add 127.0.0.1/16 dev lo-m up ip link set lo-m up down ip link delete dev lo-m {% endif %} @@ -22,6 +22,9 @@ iface mgmt # The loopback network interface auto lo iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo {% endblock loopback %} {% block mgmt_interface %} diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index 07fd7a522c3b..f5929119703c 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -6,6 +6,9 @@ # The loopback network interface auto lo iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo # The management network interface auto eth0 diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces index 085f5111c3f5..49d307aa2df7 100644 --- a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces @@ -9,12 +9,15 @@ iface mgmt # The loopback network interface for mgmt VRF that is required for applications like NTP up ip link add lo-m type dummy up ip link set dev lo-m master mgmt - up ip addr add 127.0.0.1/8 dev lo-m + up ip addr add 127.0.0.1/16 dev lo-m up ip link set lo-m up down ip link delete dev lo-m # The loopback network interface auto lo iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo # The management network interface auto eth0 From 1b25b98f431eed2ece1544a54b373dfaa03c5027 Mon Sep 17 00:00:00 2001 From: madhanmellanox <62459540+madhanmellanox@users.noreply.github.com> Date: Wed, 16 Sep 2020 09:12:13 -0700 Subject: [PATCH 1128/1427] [submodule]: updating sonic-utilities changes (#5383) Updating submodule for sonic-utilities to get the changes to Azure master. The following were the commits that were part of this submodule. Handling deletion of Portchannel before deletion of its members 219d78bda596cf78b71e5f6930545fb43f9c6c8b removed a extra space in the condifitional statement 828719ed89112f317f9e78fff8264416176736f0 added Note about portchannel deletion in Command-Reference guide b36079f1d3f4086e42cfdca2090ebc76d811ad10 removed ctx.fail() and replaced it with click.echo() to display the error. Also, references of portchannel is replaced with port channel in the command reference guide b716b97e1aaf890ba9ef4ed0bb2931f4c2c030d2 Co-authored-by: Madhan Babu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 96cb3594a6af..aa27dd9781b9 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 96cb3594a6afc64edcef7351623258287099118d +Subproject commit aa27dd9781b991a944e35612c9faa1ca70b1ed2f From 3397e41aa81aa39dde32d007126b4dfc01014b8b Mon Sep 17 00:00:00 2001 From: Vitaliy Senchyshyn <43479243+vsenchyshyn@users.noreply.github.com> Date: Wed, 16 Sep 2020 10:34:49 -0700 Subject: [PATCH 1129/1427] [barefoot][platform] Update BFN platforms (#5356) 1. Added support of BFN newport new platform name. 2. Updated debian version for montara and mavericks platforms. --- .../default_sku | 0 .../installer.conf | 0 .../newport/buffers.json.j2 | 0 .../newport/buffers_defaults_t0.j2 | 0 .../newport/buffers_defaults_t1.j2 | 0 .../newport/pg_profile_lookup.ini | 0 .../newport/port_config.ini | 0 .../newport/qos.json.j2 | 0 .../newport/sai.profile | 0 .../newport/switch-tna-sai.conf | 0 .../plugins | 0 .../pmon_daemon_control.json | 0 device/barefoot/x86_64-accton_as9516bf_32d-r0 | 1 + platform/barefoot/one-image.mk | 1 + .../barefoot/platform-modules-bfn-newport.mk | 8 +++++-- .../debian/compat | 2 +- .../debian/control | 2 +- .../debian/compat | 2 +- .../debian/control | 9 ++++++-- .../debian/rules | 21 +++++++++++-------- .../sonic-platform-modules-bfn/debian/compat | 2 +- .../sonic-platform-modules-bfn/debian/control | 2 +- 22 files changed, 32 insertions(+), 18 deletions(-) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/default_sku (100%) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/installer.conf (100%) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/newport/buffers.json.j2 (100%) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/newport/buffers_defaults_t0.j2 (100%) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/newport/buffers_defaults_t1.j2 (100%) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/newport/pg_profile_lookup.ini (100%) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/newport/port_config.ini (100%) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/newport/qos.json.j2 (100%) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/newport/sai.profile (100%) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/newport/switch-tna-sai.conf (100%) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/plugins (100%) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/pmon_daemon_control.json (100%) create mode 120000 device/barefoot/x86_64-accton_as9516bf_32d-r0 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/default_sku b/device/barefoot/x86_64-accton_as9516_32d-r0/default_sku similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/default_sku rename to device/barefoot/x86_64-accton_as9516_32d-r0/default_sku diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/installer.conf b/device/barefoot/x86_64-accton_as9516_32d-r0/installer.conf similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/installer.conf rename to device/barefoot/x86_64-accton_as9516_32d-r0/installer.conf diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers.json.j2 b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers.json.j2 similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers.json.j2 rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers.json.j2 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers_defaults_t0.j2 similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers_defaults_t0.j2 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers_defaults_t1.j2 similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers_defaults_t1.j2 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/pg_profile_lookup.ini b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/pg_profile_lookup.ini similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/pg_profile_lookup.ini rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/pg_profile_lookup.ini diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/port_config.ini b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/port_config.ini similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/port_config.ini rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/port_config.ini diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/qos.json.j2 b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/qos.json.j2 similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/qos.json.j2 rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/qos.json.j2 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/sai.profile b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/sai.profile similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/sai.profile rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/sai.profile diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/switch-tna-sai.conf similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/switch-tna-sai.conf diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/plugins b/device/barefoot/x86_64-accton_as9516_32d-r0/plugins similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/plugins rename to device/barefoot/x86_64-accton_as9516_32d-r0/plugins diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_as9516_32d-r0/pmon_daemon_control.json similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json rename to device/barefoot/x86_64-accton_as9516_32d-r0/pmon_daemon_control.json diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0 b/device/barefoot/x86_64-accton_as9516bf_32d-r0 new file mode 120000 index 000000000000..93f47d51b742 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0 @@ -0,0 +1 @@ +x86_64-accton_as9516_32d-r0 \ No newline at end of file diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index 0147b62d00a1..df54898300ea 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -8,6 +8,7 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_NEWPORT_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_NEWPORT_BF_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9280_64X_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-bfn-newport.mk b/platform/barefoot/platform-modules-bfn-newport.mk index 7d0e0a6cc261..151d8d0e58c2 100644 --- a/platform/barefoot/platform-modules-bfn-newport.mk +++ b/platform/barefoot/platform-modules-bfn-newport.mk @@ -4,8 +4,12 @@ BFN_NEWPORT_PLATFORM_MODULE_VERSION = 1.0 export BFN_NEWPORT_PLATFORM_MODULE_VERSION -BFN_NEWPORT_PLATFORM_MODULE = sonic-platform-modules-bfn-newport_$(BFN_NEWPORT_PLATFORM_MODULE_VERSION)_amd64.deb +BFN_NEWPORT_PLATFORM_MODULE = sonic-platform-modules-bfn-newport-as9516_$(BFN_NEWPORT_PLATFORM_MODULE_VERSION)_amd64.deb $(BFN_NEWPORT_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-bfn-newport $(BFN_NEWPORT_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) -$(BFN_NEWPORT_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9516bf_32d-r0 +$(BFN_NEWPORT_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9516_32d-r0 SONIC_DPKG_DEBS += $(BFN_NEWPORT_PLATFORM_MODULE) + +BFN_NEWPORT_BF_PLATFORM_MODULE = sonic-platform-modules-bfn-newport-as9516bf_$(BFN_NEWPORT_PLATFORM_MODULE_VERSION)_amd64.deb +$(BFN_NEWPORT_BF_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9516bf_32d-r0 +$(eval $(call add_extra_package,$(BFN_NEWPORT_PLATFORM_MODULE),$(BFN_NEWPORT_BF_PLATFORM_MODULE))) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat index 45a4fb75db86..ec635144f600 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat @@ -1 +1 @@ -8 +9 diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index 60b46a43ac6f..7c46f1f96fa7 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -2,7 +2,7 @@ Source: sonic-platform-modules-bfn-montara Section: main Priority: extra Maintainer: Support -Build-Depends: debhelper (>= 8.0.0), bzip2 +Build-Depends: debhelper (>= 9.0.0), bzip2 Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-montara diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat index 45a4fb75db86..ec635144f600 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat @@ -1 +1 @@ -8 +9 diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control index c6ad1386e72d..89135fda2478 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -2,10 +2,15 @@ Source: sonic-platform-modules-bfn-newport Section: main Priority: extra Maintainer: Support -Build-Depends: debhelper (>= 8.0.0), bzip2 +Build-Depends: debhelper (>= 9.0.0), bzip2 Standards-Version: 3.9.3 -Package: sonic-platform-modules-bfn-newport +Package: sonic-platform-modules-bfn-newport-as9516 +Architecture: amd64 +Depends: linux-image-4.19.0-9-2-amd64-unsigned +Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp + +Package: sonic-platform-modules-bfn-newport-as9516bf Architecture: amd64 Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules index cb033bae0514..5bb10ed19350 100755 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules @@ -2,13 +2,14 @@ export INSTALL_MOD_DIR:=extra -PACKAGE_NAME := sonic-platform-modules-bfn-newport +PACKAGE_PRE_NAME := sonic-platform-modules-bfn-newport KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MODULE_SRC := $(shell pwd)/modules SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs PLUGINS_DIR := $(shell pwd)/plugins +MODULE_NAMES := as9516 as9516bf %: dh $@ @@ -17,14 +18,16 @@ override_dh_auto_build: make -C $(KERNEL_SRC)/build M=$(MODULE_SRC) override_dh_auto_install: - dh_installdirs -p$(PACKAGE_NAME) $(KERNEL_SRC)/$(INSTALL_MOD_DIR) - cp $(MODULE_SRC)/*.ko debian/$(PACKAGE_NAME)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) - dh_installdirs -p$(PACKAGE_NAME) usr/local/bin - cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin - dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ - cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ - dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/x86_64-accton_as9516bf_32d-r0/plugins - cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/x86_64-accton_as9516bf_32d-r0/plugins/ + (for mod in $(MODULE_NAMES); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MODULE_SRC)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/local/bin; \ + cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} etc/network/interfaces.d/; \ + cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_PRE_NAME)-$${mod}/etc/network/interfaces.d/; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/plugins; \ + cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/plugins/; \ + done) override_dh_usrlocal: diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/compat b/platform/barefoot/sonic-platform-modules-bfn/debian/compat index 45a4fb75db86..ec635144f600 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/compat +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/compat @@ -1 +1 @@ -8 +9 diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index f0ca639077ed..e5ce77ba7120 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -2,7 +2,7 @@ Source: sonic-platform-modules-bfn Section: main Priority: extra Maintainer: support -Build-Depends: debhelper (>= 8.0.0), bzip2 +Build-Depends: debhelper (>= 9.0.0), bzip2 Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn From c7186a2d399cc8c1e891eeac4f01d448d5d728b4 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 16 Sep 2020 10:35:19 -0700 Subject: [PATCH 1130/1427] [process-reboot-cause] Use Logger class from sonic-py-common package (#5384) Eliminate duplicate logging code by importing Logger class from sonic-py-common package. --- .../process-reboot-cause/process-reboot-cause | 48 +++++++------------ 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause index 7762250ae648..4b1724b5840c 100755 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -9,11 +9,10 @@ try: import os import pwd - import sys - import syslog import re + import sys - from sonic_py_common import device_info + from sonic_py_common import device_info, logger except ImportError as err: raise ImportError("%s - required module not found" % str(err)) @@ -39,24 +38,8 @@ REBOOT_TYPE_KEXEC_PATTERN_FAST = ".*SONIC_BOOT_TYPE=(fast|fast-reboot).*" REBOOT_CAUSE_UNKNOWN = "Unknown" -# ========================== Syslog wrappers ========================== - -def log_info(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - - -def log_warning(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_WARNING, msg) - syslog.closelog() - - -def log_error(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() +# Global logger class instance +sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) # ============================= Functions ============================= @@ -79,9 +62,9 @@ def find_software_reboot_cause(): if os.path.isfile(REBOOT_CAUSE_FILE): with open(REBOOT_CAUSE_FILE, "r") as cause_file: software_reboot_cause = cause_file.readline().rstrip('\n') - log_info("{} indicates the reboot cause: {}".format(REBOOT_CAUSE_FILE, software_reboot_cause)) + sonic_logger.log_info("{} indicates the reboot cause: {}".format(REBOOT_CAUSE_FILE, software_reboot_cause)) else: - log_info("Reboot cause file {} not found".format(REBOOT_CAUSE_FILE)) + sonic_logger.log_info("Reboot cause file {} not found".format(REBOOT_CAUSE_FILE)) if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): if software_reboot_cause == REBOOT_CAUSE_UNKNOWN: @@ -97,9 +80,9 @@ def find_proc_cmdline_reboot_cause(): proc_cmdline_reboot_cause = parse_warmfast_reboot_from_proc_cmdline() if proc_cmdline_reboot_cause: - log_info("/proc/cmdline indicates reboot type: {}".format(proc_cmdline_reboot_cause)) + sonic_logger.log_info("/proc/cmdline indicates reboot type: {}".format(proc_cmdline_reboot_cause)) else: - log_info("No reboot cause found from /proc/cmdline") + sonic_logger.log_info("No reboot cause found from /proc/cmdline") return proc_cmdline_reboot_cause @@ -128,21 +111,24 @@ def find_hardware_reboot_cause(): else: hardware_reboot_cause = hardware_reboot_cause_major except ImportError as err: - log_warning("sonic_platform package not installed. Unable to detect hardware reboot causes.") + sonic_logger.log_warning("sonic_platform package not installed. Unable to detect hardware reboot causes.") if hardware_reboot_cause: - log_info("Platform api indicates reboot cause {}".format(hardware_reboot_cause)) + sonic_logger.log_info("Platform api indicates reboot cause {}".format(hardware_reboot_cause)) else: - log_info("No reboot cause found from platform api") + sonic_logger.log_info("No reboot cause found from platform api") return hardware_reboot_cause def main(): - log_info("Starting up...") + # Configure logger to log all messages INFO level and higher + sonic_logger.set_min_log_priority_info() + + sonic_logger.log_info("Starting up...") if not os.geteuid() == 0: - log_error("User {} does not have permission to execute".format(pwd.getpwuid(os.getuid()).pw_name)) + sonic_logger.log_error("User {} does not have permission to execute".format(pwd.getpwuid(os.getuid()).pw_name)) sys.exit("This utility must be run as root") # Create REBOOT_CAUSE_DIR if it doesn't exist @@ -186,7 +172,7 @@ def main(): prev_cause_file.write(previous_reboot_cause) # Also log the previous reboot cause to the syslog - log_info("Previous reboot cause: {}".format(previous_reboot_cause)) + sonic_logger.log_info("Previous reboot cause: {}".format(previous_reboot_cause)) # Remove the old REBOOT_CAUSE_FILE if os.path.exists(REBOOT_CAUSE_FILE): From 35de31b741e094c729161a95804d190ab0b19020 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Thu, 17 Sep 2020 01:36:40 +0800 Subject: [PATCH 1131/1427] [sonic-platform-daemons] Update submodule (#5386) e1842b2 Change STATE_DB key (PCIE_STATUS|PCIE_DEVICES -> PCIE_DEVICES) (#93) a6c0071 [thermalctld] Fix issue: fan status should not be True when fan is absent (#92) --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 096920273b68..e1842b2dff48 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 096920273b685e451bc20035a0e3ab8dbba7df31 +Subproject commit e1842b2dff481735ab42a7b0fd5594c24b7018e9 From f494ff1890caeedb3f0f3f9a8f8b93187c6d047b Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 16 Sep 2020 10:38:21 -0700 Subject: [PATCH 1132/1427] Revert "[Mellanox] update hw-mgmt package to V.7.0010.1300 (#5363)" (#5371) This reverts commit 940de61ffc94875c1913f2f77998e8f3ad749866. --- platform/mellanox/hw-management.mk | 2 +- ...agement-thermal-control-shell-script.patch | 28 +++++++++++++++++++ platform/mellanox/hw-management/hw-mgmt | 2 +- 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index 521daa1c7c3b..eb90cf16d4f2 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0010.1300 +MLNX_HW_MANAGEMENT_VERSION = 7.0010.1000 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch b/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch new file mode 100644 index 000000000000..eef970ed23c7 --- /dev/null +++ b/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch @@ -0,0 +1,28 @@ +From 3bce9e33132a86c0a53a7b0a49ee1932d65bfb7f Mon Sep 17 00:00:00 2001 +From: junchao +Date: Wed, 6 May 2020 11:37:56 +0800 +Subject: [PATCH] Disable hw-management thermal control shell script + +--- + usr/usr/bin/hw-management.sh | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh +index 65e5d39..cffff7a 100755 +--- a/usr/usr/bin/hw-management.sh ++++ b/usr/usr/bin/hw-management.sh +@@ -832,7 +832,10 @@ do_start() + if [ -f $config_path/max_tachos ]; then + max_tachos=$(<$config_path/max_tachos) + fi +- $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& ++ ++ # Disable thermal control shell script in hw-management ++ # because there has already been that in SONiC ++ # $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& + } + + do_stop() +-- +1.9.1 + diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index dec7935777b5..cdacf1e932f9 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit dec7935777b52d31a2220bad8b0cec4b71ec0961 +Subproject commit cdacf1e932f929c8dedde6c7e14759a2083aac66 From 6de9390bb03c8beb852112387276f8b2c6ad8db0 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Wed, 16 Sep 2020 20:47:26 +0300 Subject: [PATCH 1133/1427] [build] Add a parameter to specify sonic version during build (#5278) Introduced a new build parameter 'SONIC_IMAGE_VERSION' that allows build system users to build SONiC image with a specific version string. If 'SONIC_IMAGE_VERSION' was not passed by the user, SONIC_IMAGE_VERSION will be set to the output of functions.sh:sonic_get_version function. Signed-off-by: Stepan Blyschak --- Makefile.work | 1 + build_debian.sh | 2 +- build_image.sh | 2 +- files/build_templates/sonic_debian_extension.j2 | 4 ++-- slave.mk | 15 ++++++++++----- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Makefile.work b/Makefile.work index d157b03bf48f..76d6c2cddd07 100644 --- a/Makefile.work +++ b/Makefile.work @@ -190,6 +190,7 @@ SONIC_BUILD_INSTRUCTION := make \ PLATFORM_ARCH=$(PLATFORM_ARCH) \ BUILD_NUMBER=$(BUILD_NUMBER) \ BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) \ + SONIC_IMAGE_VERSION=$(SONIC_IMAGE_VERSION) \ ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \ ENABLE_ZTP=$(ENABLE_ZTP) \ SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \ diff --git a/build_debian.sh b/build_debian.sh index fa5984187b83..b482ec8be67c 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -449,7 +449,7 @@ fi ## Version file sudo mkdir -p $FILESYSTEM_ROOT/etc/sonic sudo tee $FILESYSTEM_ROOT/etc/sonic/sonic_version.yml > /dev/null < $@ # Clean up @@ -710,7 +715,7 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform --build-arg docker_container_name=$($*.gz_CONTAINER_NAME) \ --build-arg frr_user_uid=$(FRR_USER_UID) \ --build-arg frr_user_gid=$(FRR_USER_GID) \ - --label Tag=$(SONIC_GET_VERSION) \ + --label Tag=$(SONIC_IMAGE_VERSION) \ -t $* $($*.gz_PATH) $(LOG) docker save $* | gzip -c > $@ # Clean up @@ -750,7 +755,7 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_DBG_IMAGES)) : $(TARGET_PATH)/%-$(DBG_IMAG --build-arg http_proxy=$(HTTP_PROXY) \ --build-arg https_proxy=$(HTTPS_PROXY) \ --build-arg docker_container_name=$($*.gz_CONTAINER_NAME) \ - --label Tag=$(SONIC_GET_VERSION) \ + --label Tag=$(SONIC_IMAGE_VERSION) \ --file $($*.gz_PATH)/Dockerfile-dbg \ -t $*-dbg $($*.gz_PATH) $(LOG) docker save $*-dbg | gzip -c > $@ @@ -851,7 +856,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export sonic_yang_models_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3))" export sonic_yang_mgmt_py_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY))" export multi_instance="false" - export python_swss_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($(LIBSWSSCOMMON)_RDEPENDS))" + export python_swss_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($(LIBSWSSCOMMON)_RDEPENDS))" export python_swss_debs+=" $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(LIBSWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON_SWSSCOMMON))" $(foreach docker, $($*_DOCKERS),\ From 642479f75d843910898cac84cda99907e554ffb4 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Wed, 16 Sep 2020 11:29:05 -0700 Subject: [PATCH 1134/1427] [multi-Asic] Add support for multi-asic to swssloglevel (#5316) * Support for multi-asic platform for swssloglevel command admin@str-acs-1:~$ swssloglevel Usage: /usr/bin/swssloglevel -n [0 to 3] [OPTION]... * Update to use the env file to get the PLATFORM string. --- .../base_image_files/swssloglevel | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/dockers/docker-orchagent/base_image_files/swssloglevel b/dockers/docker-orchagent/base_image_files/swssloglevel index d03685ed383c..533bcb893a02 100755 --- a/dockers/docker-orchagent/base_image_files/swssloglevel +++ b/dockers/docker-orchagent/base_image_files/swssloglevel @@ -1,5 +1,13 @@ #!/bin/bash +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + +function help() +{ + echo -e "Usage: $0 -n [0 to $(($NUM_ASIC-1))] [OPTION]... " 1>&2; exit 1; +} + DOCKER_EXEC_FLAGS="i" # Determine whether stdout is on a terminal @@ -7,4 +15,30 @@ if [ -t 1 ] ; then DOCKER_EXEC_FLAGS+="t" fi -docker exec -$DOCKER_EXEC_FLAGS swss swssloglevel "$@" +DEV="" +PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +[ -f $ASIC_CONF ] && . $ASIC_CONF + +if [[ ($NUM_ASIC -gt 1) ]]; then + while getopts ":n:h:" opt; do + case "${opt}" in + h) help + ;; + n) DEV=${OPTARG} + [ $DEV -lt $NUM_ASIC -a $DEV -ge 0 ] || help + ;; + esac + done + + if [ -z "${DEV}" ]; then + help + fi + + # Skip the arguments -n while passing to docker command + shift 2 +fi + +docker exec -$DOCKER_EXEC_FLAGS swss$DEV swssloglevel "$@" From d12e9cbbc68a0ce753f74d61e7c2f52f04892f82 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 16 Sep 2020 11:32:35 -0700 Subject: [PATCH 1135/1427] [Multi-Asic] Fix for multi-asic where we should allow docker local (#5364) communication on docker eth0 ip . Without this TCP Connection to Redis does not happen in namespace. Signed-off-by: Abhishek Dosi Co-authored-by: Abhishek Dosi --- files/image_config/caclmgrd/caclmgrd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 0189743820f3..ed6064b9696f 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -182,6 +182,10 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): allow_internal_docker_ip_cmds = [] if namespace: + # For namespace docker allow local communication on docker management ip for all proto + allow_internal_docker_ip_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "iptables -A INPUT -s {} -d {} -j ACCEPT".format + (self.namespace_docker_mgmt_ip[namespace], self.namespace_docker_mgmt_ip[namespace])) + # For namespace docker allow all tcp/udp traffic from host docker bridge to its eth0 management ip allow_internal_docker_ip_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "iptables -A INPUT -p tcp -s {} -d {} -j ACCEPT".format (self.namespace_mgmt_ip, self.namespace_docker_mgmt_ip[namespace])) From ae9a86fac44caf05bcef5d888cd7b02521acc31d Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Wed, 16 Sep 2020 19:02:47 -0700 Subject: [PATCH 1136/1427] Add new DB for Restapi to database config (#5350) --- dockers/docker-database/database_config.json.j2 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dockers/docker-database/database_config.json.j2 b/dockers/docker-database/database_config.json.j2 index 6d116b5e1ae0..242b065eb398 100644 --- a/dockers/docker-database/database_config.json.j2 +++ b/dockers/docker-database/database_config.json.j2 @@ -52,6 +52,11 @@ "id" : 7, "separator": "|", "instance" : "redis" + }, + "RESTAPI_DB" : { + "id" : 8, + "separator": "|", + "instance" : "redis" } }, "VERSION" : "1.0" From 47316de5c432a78c8bd08b316b0e1923c660ab9b Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 17 Sep 2020 22:56:52 +0700 Subject: [PATCH 1137/1427] [device/celestica]: Update DX010 reboot cause API (#4678) - Add more cases support in DX010 reboot cause API - Add Thermal Overload reboot cause support - Add new Watchdog reboot cause support --- .../x86_64-cel_seastone-r0/fancontrol-B2F | 4 +- .../x86_64-cel_seastone-r0/fancontrol-F2B | 3 +- .../sonic_platform/__init__.py | 4 +- .../sonic_platform/chassis.py | 57 +- .../sonic_platform/helper.py | 13 + .../sonic_platform/watchdog.py | 172 ++-- .../debian/platform-modules-dx010.install | 1 + .../dx010/modules/dx010_cpld.c | 379 ++++--- .../dx010/scripts/thermal_overload_control.sh | 75 ++ .../services/fancontrol/fancontrol | 937 +++++++++--------- 10 files changed, 896 insertions(+), 749 deletions(-) create mode 100755 platform/broadcom/sonic-platform-modules-cel/dx010/scripts/thermal_overload_control.sh diff --git a/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F b/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F index c2132d7f2806..61b1c386f3d8 100644 --- a/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F +++ b/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F @@ -8,4 +8,6 @@ MINSTART=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e MINSTOP=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 MINPWM=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 MAXPWM=13-002e/pwm1=255 13-002e/pwm2=255 13-002e/pwm3=255 13-002e/pwm4=255 13-002e/pwm5=255 13-004d/pwm1=255 13-004d/pwm2=255 13-004d/pwm3=255 13-004d/pwm4=255 13-004d/pwm5=255 -THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3 \ No newline at end of file +THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3 +MAXTEMPCRIT=/sys/bus/i2c/devices/7-004a/hwmon/hwmon*/temp1_input=65 /sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input=75 +MAXTEMPTYPE=/sys/bus/i2c/devices/7-004a/hwmon/hwmon*/temp1_input=ASIC /sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input=CPU diff --git a/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B b/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B index dc67e2623cc2..b851d0a6d6ca 100644 --- a/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B +++ b/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B @@ -9,4 +9,5 @@ MINSTOP=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/ MINPWM=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 MAXPWM=13-002e/pwm1=255 13-002e/pwm2=255 13-002e/pwm3=255 13-002e/pwm4=255 13-002e/pwm5=255 13-004d/pwm1=255 13-004d/pwm2=255 13-004d/pwm3=255 13-004d/pwm4=255 13-004d/pwm5=255 THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3 - +MAXTEMPCRIT=/sys/bus/i2c/devices/7-004a/hwmon/hwmon*/temp1_input=75 /sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input=75 +MAXTEMPTYPE=/sys/bus/i2c/devices/7-004a/hwmon/hwmon*/temp1_input=ASIC /sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input=CPU diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py index d82f3749319c..7b86fa12b515 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py @@ -1,2 +1,2 @@ -__all__ = ["platform", "chassis"] -from sonic_platform import * +import chassis +import platform diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index 421d03c82bb4..18d57096b6d3 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -23,9 +23,9 @@ NUM_COMPONENT = 5 RESET_REGISTER = "0x103" HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/" -PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" REBOOT_CAUSE_FILE = "reboot-cause.txt" PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" +GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg" HOST_CHK_CMD = "docker > /dev/null 2>&1" @@ -118,35 +118,38 @@ def get_reboot_cause(self): one of the predefined strings in this class. If the first string is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. - """ - description = 'None' - reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER - - reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) if self.is_host else PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE - prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) if self.is_host else PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE - hw_reboot_cause = self._component_list[0].get_register_value(RESET_REGISTER) + REBOOT_CAUSE_POWER_LOSS = "Power Loss" + REBOOT_CAUSE_THERMAL_OVERLOAD_CPU = "Thermal Overload: CPU" + REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC = "Thermal Overload: ASIC" + REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER = "Thermal Overload: Other" + REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED = "Insufficient Fan Speed" + REBOOT_CAUSE_WATCHDOG = "Watchdog" + REBOOT_CAUSE_HARDWARE_OTHER = "Hardware - Other" + REBOOT_CAUSE_NON_HARDWARE = "Non-Hardware" + """ + reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) sw_reboot_cause = self._api_helper.read_txt_file( reboot_cause_path) or "Unknown" - prev_sw_reboot_cause = self._api_helper.read_txt_file( - prev_reboot_cause_path) or "Unknown" - - if sw_reboot_cause == "Unknown" and (prev_sw_reboot_cause == "Unknown" or prev_sw_reboot_cause == self.REBOOT_CAUSE_POWER_LOSS) and hw_reboot_cause == "0x11": - reboot_cause = self.REBOOT_CAUSE_POWER_LOSS - elif sw_reboot_cause != "Unknown" and hw_reboot_cause == "0x11": - reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE - description = sw_reboot_cause - elif prev_reboot_cause_path != "Unknown" and hw_reboot_cause == "0x11": - reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE - description = prev_sw_reboot_cause - elif hw_reboot_cause == "0x22": - reboot_cause = self.REBOOT_CAUSE_WATCHDOG, - else: - reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER - description = 'Unknown reason' + hw_reboot_cause = self._api_helper.get_cpld_reg_value( + GETREG_PATH, RESET_REGISTER) + + prev_reboot_cause = { + '0x11': (self.REBOOT_CAUSE_POWER_LOSS, 'Power on reset'), + '0x22': (self.REBOOT_CAUSE_HARDWARE_OTHER, 'CPLD_WD_RESET'), + '0x33': (self.REBOOT_CAUSE_HARDWARE_OTHER, 'Power cycle reset triggered by CPU'), + '0x44': (self.REBOOT_CAUSE_HARDWARE_OTHER, 'Power cycle reset triggered by reset button'), + '0x55': (self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, ''), + '0x66': (self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC, ''), + '0x77': (self.REBOOT_CAUSE_WATCHDOG, '') + }.get(hw_reboot_cause, (self.REBOOT_CAUSE_HARDWARE_OTHER, 'Unknown reason')) + + if sw_reboot_cause != 'Unknown' and hw_reboot_cause == '0x11': + prev_reboot_cause = ( + self.REBOOT_CAUSE_NON_HARDWARE, sw_reboot_cause) - return (reboot_cause, description) + return prev_reboot_cause ############################################################## ######################## SFP methods ######################### @@ -229,9 +232,9 @@ def get_name(self): def get_presence(self): """ - Retrieves the presence of the PSU + Retrieves the presence of the Chassis Returns: - bool: True if PSU is present, False if not + bool: True if Chassis is present, False if not """ return True diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py index eaf6743bc537..04149ae514f6 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py @@ -70,6 +70,19 @@ def read_one_line_file(self, file_path): pass return None + def write_txt_file(self, file_path, value): + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except Exception: + return False + return True + + def get_cpld_reg_value(self, getreg_path, register): + cmd = "echo {1} > {0}; cat {0}".format(getreg_path, register) + status, result = self.run_command(cmd) + return result if status else None + def ipmi_raw(self, netfn, cmd): status = True result = "" diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py index b539bc06f618..e410a940ee7e 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py @@ -7,115 +7,79 @@ # ############################################################################# import ctypes -import fcntl import os import subprocess import time -import array try: from sonic_platform_base.watchdog_base import WatchdogBase + from helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") -""" ioctl constants """ -IO_WRITE = 0x40000000 -IO_READ = 0x80000000 -IO_READ_WRITE = 0xC0000000 -IO_SIZE_INT = 0x00040000 -IO_SIZE_40 = 0x00280000 -IO_TYPE_WATCHDOG = ord('W') << 8 - -WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG -WDR_40 = IO_READ | IO_SIZE_40 | IO_TYPE_WATCHDOG -WDWR_INT = IO_READ_WRITE | IO_SIZE_INT | IO_TYPE_WATCHDOG - -""" Watchdog ioctl commands """ -WDIOC_GETSUPPORT = 0 | WDR_40 -WDIOC_GETSTATUS = 1 | WDR_INT -WDIOC_GETBOOTSTATUS = 2 | WDR_INT -WDIOC_GETTEMP = 3 | WDR_INT -WDIOC_SETOPTIONS = 4 | WDR_INT -WDIOC_KEEPALIVE = 5 | WDR_INT -WDIOC_SETTIMEOUT = 6 | WDWR_INT -WDIOC_GETTIMEOUT = 7 | WDR_INT -WDIOC_SETPRETIMEOUT = 8 | WDWR_INT -WDIOC_GETPRETIMEOUT = 9 | WDR_INT -WDIOC_GETTIMELEFT = 10 | WDR_INT - -""" Watchdog status constants """ -WDIOS_DISABLECARD = 0x0001 -WDIOS_ENABLECARD = 0x0002 - +PLATFORM_CPLD_PATH = '/sys/devices/platform/dx010_cpld' +GETREG_FILE = 'getreg' +SETREG_FILE = 'setreg' +WDT_ENABLE_REG = '0x141' +WDT_TIMER_L_BIT_REG = '0x142' +WDT_TIMER_M_BIT_REG = '0x143' +WDT_TIMER_H_BIT_REG = '0x144' +WDT_KEEP_ALVIVE_REG = '0x145' +ENABLE_CMD = '0x1' +DISABLE_CMD = '0x0' WDT_COMMON_ERROR = -1 -WD_MAIN_IDENTITY = "iTCO_wdt" -WDT_SYSFS_PATH = "/sys/class/watchdog/" class Watchdog(WatchdogBase): def __init__(self): + # Init helper + self._api_helper = APIHelper() + + # Init cpld reg path + self.setreg_path = os.path.join(PLATFORM_CPLD_PATH, SETREG_FILE) + self.getreg_path = os.path.join(PLATFORM_CPLD_PATH, GETREG_FILE) - self.watchdog, self.wdt_main_dev_name = self._get_wdt() - self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name - self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name - self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name # Set default value self._disable() self.armed = False - self.timeout = self._gettimeout(self.timeout_path) - - def _is_wd_main(self, dev): - """ - Checks watchdog identity - """ - identity = self._read_file( - "{}/{}/identity".format(WDT_SYSFS_PATH, dev)) - return identity == WD_MAIN_IDENTITY - - def _get_wdt(self): - """ - Retrieves watchdog device - """ - wdt_main_dev_list = [dev for dev in os.listdir( - "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)] - if not wdt_main_dev_list: - return None - wdt_main_dev_name = wdt_main_dev_list[0] - watchdog_device_path = "/dev/{}".format(wdt_main_dev_name) - watchdog = os.open(watchdog_device_path, os.O_RDWR) - return watchdog, wdt_main_dev_name - - def _read_file(self, file_path): - """ - Read text file - """ - try: - with open(file_path, "r") as fd: - txt = fd.read() - except IOError: - return WDT_COMMON_ERROR - return txt.strip() + self.timeout = self._gettimeout() def _enable(self): """ Turn on the watchdog timer """ - req = array.array('h', [WDIOS_ENABLECARD]) - fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + # echo 0x141 0x1 > /sys/devices/platform/dx010_cpld/setreg + enable_val = '{} {}'.format(WDT_ENABLE_REG, ENABLE_CMD) + return self._api_helper.write_txt_file(self.setreg_path, enable_val) def _disable(self): """ Turn off the watchdog timer """ - req = array.array('h', [WDIOS_DISABLECARD]) - fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + # echo 0x141 0x0 > /sys/devices/platform/dx010_cpld/setreg + disable_val = '{} {}'.format(WDT_ENABLE_REG, DISABLE_CMD) + return self._api_helper.write_txt_file(self.setreg_path, disable_val) def _keepalive(self): """ Keep alive watchdog timer """ - fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE) + # echo 0x145 0x1 > /sys/devices/platform/dx010_cpld/setreg + enable_val = '{} {}'.format(WDT_KEEP_ALVIVE_REG, ENABLE_CMD) + return self._api_helper.write_txt_file(self.setreg_path, enable_val) + + def _get_level_hex(self, sub_hex): + sub_hex_str = sub_hex.replace("x", "0") + return hex(int(sub_hex_str, 16)) + + def _seconds_to_lmh_hex(self, seconds): + ms = seconds*1000 # calculate timeout in ms format + hex_str = hex(ms) + l = self._get_level_hex(hex_str[-2:]) + m = self._get_level_hex(hex_str[-4:-2]) + h = self._get_level_hex(hex_str[-6:-4]) + return (l, m, h) def _settimeout(self, seconds): """ @@ -123,29 +87,35 @@ def _settimeout(self, seconds): @param seconds - timeout in seconds @return is the actual set timeout """ - req = array.array('I', [seconds]) - fcntl.ioctl(self.watchdog, WDIOC_SETTIMEOUT, req, True) - return int(req[0]) + # max = 0xffffff = 16777.215 seconds + + (l, m, h) = self._seconds_to_lmh_hex(seconds) + set_h_val = '{} {}'.format(WDT_TIMER_H_BIT_REG, h) + set_m_val = '{} {}'.format(WDT_TIMER_M_BIT_REG, m) + set_l_val = '{} {}'.format(WDT_TIMER_L_BIT_REG, l) + + self._api_helper.write_txt_file(self.setreg_path, set_h_val) + self._api_helper.write_txt_file(self.setreg_path, set_m_val) + self._api_helper.write_txt_file(self.setreg_path, set_l_val) - def _gettimeout(self, timeout_path): + return seconds + + def _gettimeout(self): """ Get watchdog timeout @return watchdog timeout """ - req = array.array('I', [0]) - fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True) - - return int(req[0]) - def _gettimeleft(self): - """ - Get time left before watchdog timer expires - @return time left in seconds - """ - req = array.array('I', [0]) - fcntl.ioctl(self.watchdog, WDIOC_GETTIMELEFT, req, True) + h_bit = self._api_helper.get_cpld_reg_value( + self.getreg_path, WDT_TIMER_H_BIT_REG) + m_bit = self._api_helper.get_cpld_reg_value( + self.getreg_path, WDT_TIMER_M_BIT_REG) + l_bit = self._api_helper.get_cpld_reg_value( + self.getreg_path, WDT_TIMER_L_BIT_REG) - return int(req[0]) + hex_time = '0x{}{}{}'.format(h_bit[2:], m_bit[2:], l_bit[2:]) + ms = int(hex_time, 16) + return int(float(ms)/1000) ################################################################# @@ -169,12 +139,15 @@ def arm(self, seconds): try: if self.timeout != seconds: self.timeout = self._settimeout(seconds) + if self.armed: self._keepalive() else: self._enable() self.armed = True + ret = self.timeout + self.arm_timestamp = time.time() except IOError as e: pass @@ -215,19 +188,4 @@ def get_remaining_time(self): watchdog timer. If the watchdog is not armed, returns -1. """ - timeleft = WDT_COMMON_ERROR - - if self.armed: - try: - timeleft = self._gettimeleft() - except IOError: - pass - - return timeleft - - def __del__(self): - """ - Close watchdog - """ - - os.close(self.watchdog) + return int(self.timeout - (time.time() - self.arm_timestamp)) if self.armed else WDT_COMMON_ERROR diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install index a36e2cd1377c..d7720cea90f4 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install @@ -3,6 +3,7 @@ dx010/cfg/dx010-modules.conf etc/modules-load.d dx010/systemd/platform-modules-dx010.service lib/systemd/system dx010/scripts/fancontrol.sh etc/init.d dx010/scripts/fancontrol.service lib/systemd/system +dx010/scripts/thermal_overload_control.sh usr/local/bin services/fancontrol/fancontrol usr/local/bin dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c index 7893220ff6d5..ead28807832d 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c @@ -76,42 +76,52 @@ #define PORT_SFPP1 33 #define PORT_SFPP2 34 -#define PORT_ID_BANK1 0x210 -#define PORT_ID_BANK2 0x290 -#define PORT_ID_BANK3 0x390 -#define OPCODE_ID_BANK1 0x211 -#define OPCODE_ID_BANK2 0x291 -#define OPCODE_ID_BANK3 0x391 +#define CPLD_I2C_CLK_100Khz_BIT BIT(6) +#define CPLD_I2C_DATA_SZ_MASK GENMASK(7,4) +#define CPLD_I2C_CMD_SZ_MASK GENMASK(1,0) +#define CPLD_I2C_ERR BIT(7) +#define CPLD_I2C_BUSY BIT(6) +#define CPLD_I2C_RST_BIT BIT(0) +#define CPLD_I2C_RESET 0 +#define CPLD_I2C_UNRESET 1 +#define CPLD_I2C_DATA_SZ_MAX 8 +#define CPLD_I2C_CMD_SZ_MAX 3 + + +#define CPLD_I2C_BANK1_BASE 0x210 +#define CPLD_I2C_BANK2_BASE 0x290 +#define CPLD_I2C_BANK3_BASE 0x390 + +#define I2C_PORT_ID 0x0 +#define I2C_OPCODE 0x1 +#define I2C_DEV_ADDR 0x2 +#define I2C_CMD_BYT0 0x3 +#define I2C_SSR 0x6 +#define I2C_WRITE_DATA 0x10 +#define I2C_READ_DATA 0x20 -#define DEVADDR_ID_BANK1 0x212 -#define DEVADDR_ID_BANK2 0x292 -#define DEVADDR_ID_BANK3 0x392 - -#define CMDBYT_ID_BANK1 0x213 -#define CMDBYT_ID_BANK2 0x293 -#define CMDBYT_ID_BANK3 0x393 - -#define WRITE_ID_BANK1 0x220 -#define WRITE_ID_BANK2 0x2A0 -#define WRITE_ID_BANK3 0x3A0 - -#define READ_ID_BANK1 0x230 -#define READ_ID_BANK2 0x2B0 -#define READ_ID_BANK3 0x3B0 - -#define SSRR_ID_BANK1 0x216 -#define SSRR_ID_BANK2 0x296 -#define SSRR_ID_BANK3 0x396 - -#define HST_CNTL2_QUICK 0x00 -#define HST_CNTL2_BYTE 0x01 -#define HST_CNTL2_BYTE_DATA 0x02 -#define HST_CNTL2_WORD_DATA 0x03 -#define HST_CNTL2_BLOCK 0x05 +/* + * private data to send to I2C core + */ +struct current_xfer { + u8 addr; + u8 cmd[CPLD_I2C_CMD_SZ_MAX]; + u8 cmd_len; + u8 data_len; + union i2c_smbus_data *data; +}; +/* + * private data of I2C adapter + * base_addr: Base address of this I2C adapter core. + * port_id: The port ID, use to mux an i2c core to a font panel port. + * current_xfer: The struct carry current data setup of current smbus transfer. + */ struct dx010_i2c_data { + int base_addr; int portid; + struct current_xfer curr_xfer; }; struct dx010_cpld_data { @@ -364,179 +374,210 @@ static struct platform_device cel_dx010_lpc_dev = { } }; +// TODO: Refactoring this function with helper functions. +static s32 cpld_smbus_transfer(struct dx010_i2c_data *priv) { -/** - * Read eeprom of QSFP device. - * @param a i2c adapter. - * @param addr address to read. - * @param new_data QSFP port number struct. - * @param cmd i2c command. - * @return 0 if not error, else the error code. - */ -static int i2c_read_eeprom(struct i2c_adapter *a, u16 addr, - struct dx010_i2c_data *new_data, u8 cmd, union i2c_smbus_data *data){ + u8 val; + s32 error; + unsigned long ioBase; + short portid, opcode, devaddr, cmdbyte0, ssr, writedata, readdata; + union i2c_smbus_data *data; - u32 reg; - int ioBase=0; - char byte; - short temp; - short portid, opcode, devaddr, cmdbyte0, ssrr, writedata, readdata; - __u16 word_data; - int error = -EIO; + error = -EIO; mutex_lock(&cpld_data->cpld_lock); - if (((new_data->portid >= PORT_BANK1_START) - && (new_data->portid <= PORT_BANK1_END)) - || (new_data->portid == PORT_SFPP1) - || (new_data->portid == PORT_SFPP2)) - { - portid = PORT_ID_BANK1; - opcode = OPCODE_ID_BANK1; - devaddr = DEVADDR_ID_BANK1; - cmdbyte0 = CMDBYT_ID_BANK1; - ssrr = SSRR_ID_BANK1; - writedata = WRITE_ID_BANK1; - readdata = READ_ID_BANK1; - }else if ((new_data->portid >= PORT_BANK2_START) && (new_data->portid <= PORT_BANK2_END)){ - portid = PORT_ID_BANK2; - opcode = OPCODE_ID_BANK2; - devaddr = DEVADDR_ID_BANK2; - cmdbyte0 = CMDBYT_ID_BANK2; - ssrr = SSRR_ID_BANK2; - writedata = WRITE_ID_BANK2; - readdata = READ_ID_BANK2; - }else if ((new_data->portid >= PORT_BANK3_START) && (new_data->portid <= PORT_BANK3_END)){ - portid = PORT_ID_BANK3; - opcode = OPCODE_ID_BANK3; - devaddr = DEVADDR_ID_BANK3; - cmdbyte0 = CMDBYT_ID_BANK3; - ssrr = SSRR_ID_BANK3; - writedata = WRITE_ID_BANK3; - readdata = READ_ID_BANK3; - }else{ - /* Invalid parameter! */ - error = -EINVAL; - goto exit; + ioBase = priv->base_addr; + data = priv->curr_xfer.data; + + portid = ioBase + I2C_PORT_ID; + opcode = ioBase + I2C_OPCODE; + devaddr = ioBase + I2C_DEV_ADDR; + cmdbyte0 = ioBase + I2C_CMD_BYT0; + ssr = ioBase + I2C_SSR; + writedata = ioBase + I2C_WRITE_DATA; + readdata = ioBase + I2C_READ_DATA; + + /* Wait for the core to be free */ + pr_debug("CPLD_I2C Wait busy bit(6) to be cleared\n"); + do { + val = inb(ssr); + if ((val & CPLD_I2C_BUSY) == 0) + break; + udelay(100); + } while (true); // Risky - add timeout + + /* + * If any error happen here, we do soft-reset + * and check the BUSY/ERROR again. + */ + pr_debug("CPLD_I2C Check error bit(7)\n"); + if (val & CPLD_I2C_ERR) { + pr_debug("CPLD_I2C Error, try soft-reset\n"); + outb(CPLD_I2C_RESET, ssr); + udelay(3000); + outb(CPLD_I2C_UNRESET, ssr); + + val = inb(ssr); + if (val & (CPLD_I2C_BUSY | CPLD_I2C_ERR)) { + pr_debug("CPLD_I2C Error, core busy after reset\n"); + error = -EIO; + goto exit_unlock; + } } - while ((inb(ioBase + ssrr) & 0x40)); - if ((inb(ioBase + ssrr) & 0x80) == 0x80) { - error = -EIO; - /* Read error reset the port */ - outb(0x00, ioBase + ssrr); - udelay(3000); - outb(0x01, ioBase + ssrr); - goto exit; + /* Configure PortID */ + val = priv->portid | CPLD_I2C_CLK_100Khz_BIT; + outb(val, portid); + pr_debug("CPLD_I2C Write PortID 0x%x\n", val); + + /* Configure OP_Code */ + val = (priv->curr_xfer.data_len << 4) & CPLD_I2C_DATA_SZ_MASK; + val |= (priv->curr_xfer.cmd_len & CPLD_I2C_CMD_SZ_MASK); + outb(val, opcode); + pr_debug("CPLD_I2C Write OP_Code 0x%x\n", val); + + /* Configure CMD_Byte */ + outb(priv->curr_xfer.cmd[0], cmdbyte0); + pr_debug("CPLD_I2C Write CMD_Byte 0x%x\n", priv->curr_xfer.cmd[0]); + + /* Configure write data buffer */ + if ((priv->curr_xfer.addr & BIT(0)) == I2C_SMBUS_WRITE){ + pr_debug("CPLD_I2C Write WR_DATA buffer\n"); + switch(priv->curr_xfer.data_len){ + case 1: + outb(data->byte, writedata); + break; + case 2: + outb(data->block[0], writedata); + outb(data->block[1], ++writedata); + break; + } } - byte = 0x40 +new_data->portid; - reg = cmd; - outb(byte, ioBase + portid); - outb(reg,ioBase + cmdbyte0); - byte = 33; - outb(byte, ioBase + opcode); - addr = addr << 1; - addr |= 0x01; - outb(addr, ioBase + devaddr); - while ((inb(ioBase + ssrr) & 0x40)) - { + /* Start transfer, write the device address register */ + pr_debug("CPLD_I2C Write DEV_ADDR 0x%x\n", priv->curr_xfer.addr); + outb(priv->curr_xfer.addr, devaddr); + + /* Wait for transfer finish */ + pr_debug("CPLD_I2C Wait busy bit(6) to be cleared\n"); + do { + val = inb(ssr); + if ((val & CPLD_I2C_BUSY) == 0) + break; udelay(100); - } + } while (true); // Risky - add timeout - if ((inb(ioBase + ssrr) & 0x80) == 0x80) { - /* Read error reset the port */ + pr_debug("CPLD_I2C Check error bit(7)\n"); + if (val & CPLD_I2C_ERR) { error = -EIO; - outb(0x00, ioBase + ssrr); - udelay(3000); - outb(0x01, ioBase + ssrr); - goto exit; + goto exit_unlock; } - temp = ioBase + readdata; - word_data = inb(temp); - word_data |= (inb(++temp) << 8); + /* Get the data from buffer */ + if ((priv->curr_xfer.addr & BIT(0)) == I2C_SMBUS_READ){ + pr_debug("CPLD_I2C Read RD_DATA buffer\n"); + switch (priv->curr_xfer.data_len) { + case 1: + data->byte = inb(readdata); + break; + case 2: + data->block[0] = inb(readdata); + data->block[1] = inb(++readdata); + break; + } + } - mutex_unlock(&cpld_data->cpld_lock); - data->word = word_data; - return 0; + error = 0; -exit: +exit_unlock: + pr_debug("CPLD_I2C Exit with %d\n", error); mutex_unlock(&cpld_data->cpld_lock); return error; + } -static int dx010_i2c_access(struct i2c_adapter *a, u16 addr, - unsigned short flags, char rw, u8 cmd, - int size, union i2c_smbus_data *data) -{ +/* + * dx010_smbus_xfer - execute LPC-SMBus transfer + * Returns a negative errno code else zero on success. + */ +static s32 dx010_smbus_xfer(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data *data) { int error = 0; + struct dx010_i2c_data *priv; + + priv = i2c_get_adapdata(adap); - struct dx010_i2c_data *new_data; + pr_debug("smbus_xfer called RW:%x CMD:%x SIZE:0x%x", + read_write, command, size); - /* Write the command register */ - new_data = i2c_get_adapdata(a); + priv->curr_xfer.addr = (addr << 1) | read_write; + priv->curr_xfer.data = data; /* Map the size to what the chip understands */ switch (size) { - case I2C_SMBUS_QUICK: - size = HST_CNTL2_QUICK; - break; case I2C_SMBUS_BYTE: - size = HST_CNTL2_BYTE; - break; + priv->curr_xfer.cmd_len = 0; + priv->curr_xfer.data_len = 1; + break; case I2C_SMBUS_BYTE_DATA: - size = HST_CNTL2_BYTE_DATA; - break; + priv->curr_xfer.cmd_len = 1; + priv->curr_xfer.data_len = 1; + priv->curr_xfer.cmd[0] = command; + break; case I2C_SMBUS_WORD_DATA: - size = HST_CNTL2_WORD_DATA; - break; - case I2C_SMBUS_BLOCK_DATA: - size = HST_CNTL2_BLOCK; - break; + priv->curr_xfer.cmd_len = 1; + priv->curr_xfer.data_len = 2; + priv->curr_xfer.cmd[0] = command; + break; default: - dev_warn(&a->dev, "Unsupported transaction %d\n", size); + dev_warn(&adap->dev, "Unsupported transaction %d\n", size); error = -EOPNOTSUPP; goto Done; } - switch (size) { - case HST_CNTL2_BYTE: /* Result put in SMBHSTDAT0 */ - break; - case HST_CNTL2_BYTE_DATA: - break; - case HST_CNTL2_WORD_DATA: - if( 0 == i2c_read_eeprom(a,addr,new_data,cmd,data)){ - error = 0; - }else{ - error = -EIO; - } - break; - } + error = cpld_smbus_transfer(priv); Done: return error; } -static u32 dx010_i2c_func(struct i2c_adapter *a) -{ - return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_BLOCK_DATA; +// TODO: Add support for I2C_FUNC_SMBUS_PROC_CALL and I2C_FUNC_SMBUS_I2C_BLOCK +static u32 dx010_i2c_func(struct i2c_adapter *a) { + return I2C_FUNC_SMBUS_READ_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA; } static const struct i2c_algorithm dx010_i2c_algorithm = { - .smbus_xfer = dx010_i2c_access, + .smbus_xfer = dx010_smbus_xfer, .functionality = dx010_i2c_func, }; -static struct i2c_adapter * cel_dx010_i2c_init(struct platform_device *pdev, int portid) +static struct i2c_adapter *cel_dx010_i2c_init(struct platform_device *pdev, int portid) { int error; - + int base_addr; struct i2c_adapter *new_adapter; - struct dx010_i2c_data *new_data; + struct dx010_i2c_data *priv; + + switch (portid) { + case PORT_SFPP1 ... PORT_SFPP2: + case PORT_BANK1_START ... PORT_BANK1_END: + base_addr = CPLD_I2C_BANK1_BASE; + break; + case PORT_BANK2_START ... PORT_BANK2_END: + base_addr = CPLD_I2C_BANK2_BASE; + break; + case PORT_BANK3_START ... PORT_BANK3_END: + base_addr = CPLD_I2C_BANK3_BASE; + break; + default: + dev_err(&pdev->dev, "Invalid port adapter ID: %d\n", portid); + goto error_exit; + } new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL); if (!new_adapter) @@ -544,31 +585,39 @@ static struct i2c_adapter * cel_dx010_i2c_init(struct platform_device *pdev, int new_adapter->dev.parent = &pdev->dev; new_adapter->owner = THIS_MODULE; - new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + new_adapter->class = I2C_CLASS_DEPRECATED; new_adapter->algo = &dx010_i2c_algorithm; snprintf(new_adapter->name, sizeof(new_adapter->name), - "SMBus dx010 i2c Adapter portid@%04x", portid); - - new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); - if (!new_data) - return NULL; + "SMBus dx010 i2c Adapter port %d", portid); - new_data->portid = portid; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + goto free_adap; + } - i2c_set_adapdata(new_adapter,new_data); + priv->portid = portid; + priv->base_addr = base_addr; + i2c_set_adapdata(new_adapter, priv); error = i2c_add_adapter(new_adapter); if(error) - return NULL; + goto free_data; return new_adapter; + +free_adap: + kzfree(new_adapter); +free_data: + kzfree(priv); +error_exit: + return NULL; }; static int cel_dx010_lpc_drv_probe(struct platform_device *pdev) { struct resource *res; - int ret =0; + int ret = 0; int portid_count; cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct dx010_cpld_data), diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/thermal_overload_control.sh b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/thermal_overload_control.sh new file mode 100755 index 000000000000..57fd851f9cfb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/thermal_overload_control.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# +# Copyright 2020-present Celestica. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# + +PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin +SETREG_FILE=/sys/devices/platform/dx010_cpld/setreg +TOVERREG=0x140 +CPUOVER=0xa1 +ASICOVER=0xa2 + +prog="$0" +command="$1" + +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +usage() { + echo "Usage: thermal_overload_control.sh [option] " + echo + echo "Options:" + echo " -h, --help : to print this message." + echo + echo "Commands:" + echo + echo " cpu: To enabling CPU thermal overload handler" + echo + echo " asic : To enabling ASIC thermal overload handler" + echo +} + +cpu_overload() { + logger "Enable CPU thermal overload control" + set_reg=`echo ${TOVERREG} ${CPUOVER} > ${SETREG_FILE}` +} + +asic_overload() { + logger "Enable ASIC thermal overload control" + set_reg=`echo ${TOVERREG} ${ASICOVER} > ${SETREG_FILE}` +} + +if [ $# -lt 1 ]; then + usage + exit -1 +fi + +case "$command" in +-h | --help) + usage + ;; +cpu) + cpu_overload + ;; +asic) + asic_overload + ;; +*) + usage + exit -1 + ;; +esac + +exit $? diff --git a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol b/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol index eb15598b0efa..cdd5005e3688 100755 --- a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol +++ b/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol @@ -39,285 +39,327 @@ # PIDFILE="/var/run/fancontrol.pid" +THERMAL_OVERLOAD_CONTROL_FILE="/usr/local/bin/thermal_overload_control.sh" #DEBUG=1 MAX=255 function LoadConfig { - local fcvcount fcv - - echo "Loading configuration from $1 ..." - if [ ! -r "$1" ] - then - echo "Error: Can't read configuration file" >&2 - exit 1 - fi - - # grep configuration from file - INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'` - DEVPATH=`egrep '^DEVPATH=.*$' $1 | sed -e 's/DEVPATH= *//g'` - DEVNAME=`egrep '^DEVNAME=.*$' $1 | sed -e 's/DEVNAME= *//g'` - FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'` - MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'` - MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'` - MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'` - MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'` - # optional settings: - FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS=//g'` - MINPWM=`egrep '^MINPWM=.*$' $1 | sed -e 's/MINPWM=//g'` - MAXPWM=`egrep '^MAXPWM=.*$' $1 | sed -e 's/MAXPWM=//g'` - THYST=`egrep '^THYST=.*$' $1 | sed -e 's/THYST=//g'` - echo - # Check whether all mandatory settings are set - if [[ -z ${INTERVAL} || -z ${FCTEMPS} || -z ${MINTEMP} || -z ${MAXTEMP} || -z ${MINSTART} || -z ${MINSTOP} ]] - then - echo "Some mandatory settings missing, please check your config file!" >&2 - exit 1 - fi - if [ "$INTERVAL" -le 0 ] - then - echo "Error in configuration file:" >&2 - echo "INTERVAL must be at least 1" >&2 - exit 1 - fi - - # write settings to arrays for easier use and print them - echo - echo "Common settings:" - echo " INTERVAL=$INTERVAL" - - let fcvcount=0 - for fcv in $FCTEMPS - do - if ! echo $fcv | egrep -q '=' - then - echo "Error in configuration file:" >&2 - echo "FCTEMPS value is improperly formatted" >&2 - exit 1 - fi - - AFCPWM[$fcvcount]=`echo $fcv |cut -d'=' -f1` - AFCTEMP[$fcvcount]=`echo $fcv |cut -d'=' -f2` - AFCFAN[$fcvcount]=`echo $FCFANS |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - AFCFANFAULT[$fcvcount]=`echo "${AFCFAN[$fcvcount]}" |sed -e 's/input/fault/g'` - AFCMINTEMP[$fcvcount]=`echo $MINTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - AFCMAXTEMP[$fcvcount]=`echo $MAXTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - AFCMINSTART[$fcvcount]=`echo $MINSTART |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - AFCMINSTOP[$fcvcount]=`echo $MINSTOP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - AFCMINPWM[$fcvcount]=`echo $MINPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - [ -z "${AFCMINPWM[$fcvcount]}" ] && AFCMINPWM[$fcvcount]=0 - AFCMAXPWM[$fcvcount]=`echo $MAXPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - [ -z "${AFCMAXPWM[$fcvcount]}" ] && AFCMAXPWM[$fcvcount]=255 - AFCTHYST[$fcvcount]=`echo $THYST |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - [ -z "${AFCTHYST[$fcvcount]}" ] && AFCTHYST[$fcvcount]=0 - - # verify the validity of the settings - if [ "${AFCMINTEMP[$fcvcount]}" -ge "${AFCMAXTEMP[$fcvcount]}" ] - then - echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 - echo "MINTEMP must be less than MAXTEMP" >&2 - exit 1 - fi - if [ "${AFCMAXPWM[$fcvcount]}" -gt 255 ] - then - echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 - echo "MAXPWM must be at most 255" >&2 - exit 1 - fi - if [ "${AFCMINSTOP[$fcvcount]}" -ge "${AFCMAXPWM[$fcvcount]}" ] - then - echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 - echo "MINSTOP must be less than MAXPWM" >&2 - exit 1 - fi - if [ "${AFCMINSTOP[$fcvcount]}" -lt "${AFCMINPWM[$fcvcount]}" ] - then - echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 - echo "MINSTOP must be greater than or equal to MINPWM" >&2 - exit 1 - fi - if [ "${AFCMINPWM[$fcvcount]}" -lt 0 ] - then - echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 - echo "MINPWM must be at least 0" >&2 - exit 1 - fi - - echo - echo "Settings for ${AFCPWM[$fcvcount]}:" - echo " Depends on ${AFCTEMP[$fcvcount]}" - echo " Controls ${AFCFAN[$fcvcount]}" - echo " MINTEMP=${AFCMINTEMP[$fcvcount]}" - echo " MAXTEMP=${AFCMAXTEMP[$fcvcount]}" - echo " MINSTART=${AFCMINSTART[$fcvcount]}" - echo " MINSTOP=${AFCMINSTOP[$fcvcount]}" - echo " MINPWM=${AFCMINPWM[$fcvcount]}" - echo " MAXPWM=${AFCMAXPWM[$fcvcount]}" - echo " THYST=${AFCTHYST[$fcvcount]}" - let fcvcount=fcvcount+1 - done - echo + local fcvcount fcv + + echo "Loading configuration from $1 ..." + if [ ! -r "$1" ] + then + echo "Error: Can't read configuration file" >&2 + exit 1 + fi + + # grep configuration from file + INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'` + DEVPATH=`egrep '^DEVPATH=.*$' $1 | sed -e 's/DEVPATH= *//g'` + DEVNAME=`egrep '^DEVNAME=.*$' $1 | sed -e 's/DEVNAME= *//g'` + FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'` + MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'` + MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'` + MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'` + MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'` + # optional settings: + FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS=//g'` + MINPWM=`egrep '^MINPWM=.*$' $1 | sed -e 's/MINPWM=//g'` + MAXPWM=`egrep '^MAXPWM=.*$' $1 | sed -e 's/MAXPWM=//g'` + THYST=`egrep '^THYST=.*$' $1 | sed -e 's/THYST=//g'` + MAXTEMPCRIT=`egrep '^MAXTEMPCRIT=.*$' $1 | sed -e 's/MAXTEMPCRIT=//g'` + MAXTEMPTYPE=`egrep '^MAXTEMPTYPE=.*$' $1 | sed -e 's/MAXTEMPTYPE=//g'` + echo + # Check whether all mandatory settings are set + if [[ -z ${INTERVAL} || -z ${FCTEMPS} || -z ${MINTEMP} || -z ${MAXTEMP} || -z ${MINSTART} || -z ${MINSTOP} ]] + then + echo "Some mandatory settings missing, please check your config file!" >&2 + exit 1 + fi + if [ "$INTERVAL" -le 0 ] + then + echo "Error in configuration file:" >&2 + echo "INTERVAL must be at least 1" >&2 + exit 1 + fi + + # write settings to arrays for easier use and print them + echo + echo "Common settings:" + echo " INTERVAL=$INTERVAL" + + let fcvcount=0 + for fcv in $FCTEMPS + do + if ! echo $fcv | egrep -q '=' + then + echo "Error in configuration file:" >&2 + echo "FCTEMPS value is improperly formatted" >&2 + exit 1 + fi + + AFCPWM[$fcvcount]=`echo $fcv |cut -d'=' -f1` + AFCTEMP[$fcvcount]=`echo $fcv |cut -d'=' -f2` + AFCFAN[$fcvcount]=`echo $FCFANS |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + AFCFANFAULT[$fcvcount]=`echo "${AFCFAN[$fcvcount]}" |sed -e 's/input/fault/g'` + AFCMINTEMP[$fcvcount]=`echo $MINTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + AFCMAXTEMP[$fcvcount]=`echo $MAXTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + AFCMINSTART[$fcvcount]=`echo $MINSTART |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + AFCMINSTOP[$fcvcount]=`echo $MINSTOP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + AFCMINPWM[$fcvcount]=`echo $MINPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + [ -z "${AFCMINPWM[$fcvcount]}" ] && AFCMINPWM[$fcvcount]=0 + AFCMAXPWM[$fcvcount]=`echo $MAXPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + [ -z "${AFCMAXPWM[$fcvcount]}" ] && AFCMAXPWM[$fcvcount]=255 + AFCTHYST[$fcvcount]=`echo $THYST |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + [ -z "${AFCTHYST[$fcvcount]}" ] && AFCTHYST[$fcvcount]=0 + + # verify the validity of the settings + if [ "${AFCMINTEMP[$fcvcount]}" -ge "${AFCMAXTEMP[$fcvcount]}" ] + then + echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 + echo "MINTEMP must be less than MAXTEMP" >&2 + exit 1 + fi + if [ "${AFCMAXPWM[$fcvcount]}" -gt 255 ] + then + echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 + echo "MAXPWM must be at most 255" >&2 + exit 1 + fi + if [ "${AFCMINSTOP[$fcvcount]}" -ge "${AFCMAXPWM[$fcvcount]}" ] + then + echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 + echo "MINSTOP must be less than MAXPWM" >&2 + exit 1 + fi + if [ "${AFCMINSTOP[$fcvcount]}" -lt "${AFCMINPWM[$fcvcount]}" ] + then + echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 + echo "MINSTOP must be greater than or equal to MINPWM" >&2 + exit 1 + fi + if [ "${AFCMINPWM[$fcvcount]}" -lt 0 ] + then + echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 + echo "MINPWM must be at least 0" >&2 + exit 1 + fi + + echo + echo "Settings for ${AFCPWM[$fcvcount]}:" + echo " Depends on ${AFCTEMP[$fcvcount]}" + echo " Controls ${AFCFAN[$fcvcount]}" + echo " MINTEMP=${AFCMINTEMP[$fcvcount]}" + echo " MAXTEMP=${AFCMAXTEMP[$fcvcount]}" + echo " MINSTART=${AFCMINSTART[$fcvcount]}" + echo " MINSTOP=${AFCMINSTOP[$fcvcount]}" + echo " MINPWM=${AFCMINPWM[$fcvcount]}" + echo " MAXPWM=${AFCMAXPWM[$fcvcount]}" + echo " THYST=${AFCTHYST[$fcvcount]}" + let fcvcount=fcvcount+1 + done + echo + + + let tscount=0 + for ts in $MAXTEMPCRIT + do + CSTEMP[$tscount]=`echo $ts | cut -d '=' -f1` + CSMAXTEMPCRIT[$tscount]=`echo $ts | cut -d '=' -f2` + CSMAXTEMPTYPE=($(echo $MAXTEMPTYPE |sed -e 's/ /\n/g'| cut -d'=' -f2)) + + echo + echo "Settings for ${CSMAXTEMPTYPE[$tscount]} temperature sensor:" + echo " Depends on ${CSTEMP[$tscount]}" + echo " MAXTEMPCRIT=${CSMAXTEMPCRIT[$tscount]}" + let tscount=tscount+1 + done + echo + } function CheckFanFault() { - let fancount=0 - while (( $fancount < ${#AFCFANFAULT[@]} )) # go through all fan fault. - do - fault=`cat ${AFCFANFAULT[$fancount]}` - if [[ "$fault" == "1" ]] - then - return 1 # fan fault detected - fi - let fancount=$fancount+1 - done - return 0 + let fancount=0 + while (( $fancount < ${#AFCFANFAULT[@]} )) # go through all fan fault. + do + fault=`cat ${AFCFANFAULT[$fancount]}` + if [[ "$fault" == "1" ]] + then + return 1 # fan fault detected + fi + let fancount=$fancount+1 + done + return 0 +} + +function CheckTempOver() +{ + let tempcount=0 + while (( $tempcount < ${#CSTEMP[@]} )) # go through all temp. + do + ctemp=`cat ${CSTEMP[$tempcount]}` + let maxcrit="${CSMAXTEMPCRIT[$tempcount]}*1000" + if [ $ctemp -ge $maxcrit ] + then + logger "Thermal overload : ${CSMAXTEMPTYPE[$tempcount]} temperature ${ctemp} > ${maxcrit}" + if [ -f "$THERMAL_OVERLOAD_CONTROL_FILE" ] + then + toc_cmd="${THERMAL_OVERLOAD_CONTROL_FILE} ${CSMAXTEMPTYPE[$tempcount],,}" + bash $toc_cmd + exit 1 + fi + fi + let tempcount=$tempcount+1 + done + return 0 } function DevicePath() { - if [ -h "$1/device" ] - then - readlink -f "$1/device" | sed -e 's/^\/sys\///' - fi + if [ -h "$1/device" ] + then + readlink -f "$1/device" | sed -e 's/^\/sys\///' + fi } function DeviceName() { - if [ -r "$1/name" ] - then - cat "$1/name" | sed -e 's/[[:space:]=]/_/g' - elif [ -r "$1/device/name" ] - then - cat "$1/device/name" | sed -e 's/[[:space:]=]/_/g' - fi + if [ -r "$1/name" ] + then + cat "$1/name" | sed -e 's/[[:space:]=]/_/g' + elif [ -r "$1/device/name" ] + then + cat "$1/device/name" | sed -e 's/[[:space:]=]/_/g' + fi } function ValidateDevices() { - local OLD_DEVPATH="$1" OLD_DEVNAME="$2" outdated=0 - local entry device name path - - for entry in $OLD_DEVPATH - do - device=`echo "$entry" | sed -e 's/=[^=]*$//'` - path=`echo "$entry" | sed -e 's/^[^=]*=//'` - - if [ "`DevicePath "$device"`" != "$path" ] - then - echo "Device path of $device has changed" >&2 - outdated=1 - fi - done - - for entry in $OLD_DEVNAME - do - device=`echo "$entry" | sed -e 's/=[^=]*$//'` - name=`echo "$entry" | sed -e 's/^[^=]*=//'` - - if [ "`DeviceName "$device"`" != "$name" ] - then - echo "Device name of $device has changed" >&2 - outdated=1 - fi - done - - return $outdated + local OLD_DEVPATH="$1" OLD_DEVNAME="$2" outdated=0 + local entry device name path + + for entry in $OLD_DEVPATH + do + device=`echo "$entry" | sed -e 's/=[^=]*$//'` + path=`echo "$entry" | sed -e 's/^[^=]*=//'` + + if [ "`DevicePath "$device"`" != "$path" ] + then + echo "Device path of $device has changed" >&2 + outdated=1 + fi + done + + for entry in $OLD_DEVNAME + do + device=`echo "$entry" | sed -e 's/=[^=]*$//'` + name=`echo "$entry" | sed -e 's/^[^=]*=//'` + + if [ "`DeviceName "$device"`" != "$name" ] + then + echo "Device name of $device has changed" >&2 + outdated=1 + fi + done + + return $outdated } # Check that all referenced sysfs files exist function CheckFiles { - local outdated=0 fcvcount pwmo tsen fan - - let fcvcount=0 - while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs - do - pwmo=${AFCPWM[$fcvcount]} - if [ ! -w $pwmo ] - then - echo "Error: file $pwmo doesn't exist" >&2 - outdated=1 - fi - let fcvcount=$fcvcount+1 - done - - let fcvcount=0 - while (( $fcvcount < ${#AFCTEMP[@]} )) # go through all temp inputs - do - tsen=${AFCTEMP[$fcvcount]} - if [ ! -r $tsen ] - then - echo "Error: file $tsen doesn't exist" >&2 - outdated=1 - fi - let fcvcount=$fcvcount+1 - done - - let fcvcount=0 - while (( $fcvcount < ${#AFCFAN[@]} )) # go through all fan inputs - do - # A given PWM output can control several fans - for fan in $(echo ${AFCFAN[$fcvcount]} | sed -e 's/+/ /') - do - if [ ! -r $fan ] - then - echo "Error: file $fan doesn't exist" >&2 - outdated=1 - fi - done - let fcvcount=$fcvcount+1 - done - - if [ $outdated -eq 1 ] - then - echo >&2 - echo "At least one referenced file is missing. Either some required kernel" >&2 - echo "modules haven't been loaded, or your configuration file is outdated." >&2 - echo "In the latter case, you should run pwmconfig again." >&2 - fi - - return $outdated + local outdated=0 fcvcount pwmo tsen fan + + let fcvcount=0 + while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs + do + pwmo=${AFCPWM[$fcvcount]} + if [ ! -w $pwmo ] + then + echo "Error: file $pwmo doesn't exist" >&2 + outdated=1 + fi + let fcvcount=$fcvcount+1 + done + + let fcvcount=0 + while (( $fcvcount < ${#AFCTEMP[@]} )) # go through all temp inputs + do + tsen=${AFCTEMP[$fcvcount]} + if [ ! -r $tsen ] + then + echo "Error: file $tsen doesn't exist" >&2 + outdated=1 + fi + let fcvcount=$fcvcount+1 + done + + let fcvcount=0 + while (( $fcvcount < ${#AFCFAN[@]} )) # go through all fan inputs + do + # A given PWM output can control several fans + for fan in $(echo ${AFCFAN[$fcvcount]} | sed -e 's/+/ /') + do + if [ ! -r $fan ] + then + echo "Error: file $fan doesn't exist" >&2 + outdated=1 + fi + done + let fcvcount=$fcvcount+1 + done + + if [ $outdated -eq 1 ] + then + echo >&2 + echo "At least one referenced file is missing. Either some required kernel" >&2 + echo "modules haven't been loaded, or your configuration file is outdated." >&2 + echo "In the latter case, you should run pwmconfig again." >&2 + fi + + return $outdated } if [ "$1" == "--check" ] then - if [ -f "$2" ] - then - LoadConfig $2 - else - LoadConfig /etc/fancontrol - fi - exit 0 + if [ -f "$2" ] + then + LoadConfig $2 + else + LoadConfig /etc/fancontrol + fi + exit 0 fi if [ -f "$1" ] then - LoadConfig $1 + LoadConfig $1 else - LoadConfig /etc/fancontrol + LoadConfig /etc/fancontrol fi # Detect path to sensors if echo "${AFCPWM[0]}" | egrep -q '^/' then - DIR=/ + DIR=/ elif echo "${AFCPWM[0]}" | egrep -q '^hwmon[0-9]' then - DIR=/sys/class/hwmon + DIR=/sys/class/hwmon elif echo "${AFCPWM[0]}" | egrep -q '^[1-9]*[0-9]-[0-9abcdef]{4}' then - DIR=/sys/bus/i2c/devices + DIR=/sys/bus/i2c/devices else - echo "$0: Invalid path to sensors" >&2 - exit 1 + echo "$0: Invalid path to sensors" >&2 + exit 1 fi if [ ! -d $DIR ] then - echo $0: 'No sensors found! (did you load the necessary modules?)' >&2 - exit 1 + echo $0: 'No sensors found! (did you load the necessary modules?)' >&2 + exit 1 fi cd $DIR @@ -325,94 +367,94 @@ cd $DIR # if [ "$DIR" != "/" ] && [ -z "$DEVPATH" -o -z "$DEVNAME" ] # then # echo "Configuration is too old, please run pwmconfig again" >&2 -# exit 1 +# exit 1 # fi if [ "$DIR" = "/" -a -n "$DEVPATH" ] then - echo "Unneeded DEVPATH with absolute device paths" >&2 - exit 1 + echo "Unneeded DEVPATH with absolute device paths" >&2 + exit 1 fi if ! ValidateDevices "$DEVPATH" "$DEVNAME" then - echo "Configuration appears to be outdated, please run pwmconfig again" >&2 - exit 1 + echo "Configuration appears to be outdated, please run pwmconfig again" >&2 + exit 1 fi CheckFiles || exit 1 if [ -f "$PIDFILE" ] then - echo "File $PIDFILE exists, is fancontrol already running?" >&2 - exit 1 + echo "File $PIDFILE exists, is fancontrol already running?" >&2 + exit 1 fi echo $$ > "$PIDFILE" # $1 = pwm file name function pwmdisable() { - local ENABLE=${1}_enable - - # No enable file? Just set to max - if [ ! -f $ENABLE ] - then - echo $MAX > $1 - return 0 - fi - - # Try pwmN_enable=0 - echo 0 > $ENABLE 2> /dev/null - if [ `cat $ENABLE` -eq 0 ] - then - # Success - echo $MAX > $1 - return 0 - fi - - # It didn't work, try pwmN_enable=1 pwmN=255 - echo 1 > $ENABLE 2> /dev/null - echo $MAX > $1 - if [ `cat $ENABLE` -eq 1 -a `cat $1` -ge 190 ] - then - # Success - return 0 - fi - - # Nothing worked - echo "$ENABLE stuck to" `cat $ENABLE` >&2 - return 1 + local ENABLE=${1}_enable + + # No enable file? Just set to max + if [ ! -f $ENABLE ] + then + echo $MAX > $1 + return 0 + fi + + # Try pwmN_enable=0 + echo 0 > $ENABLE 2> /dev/null + if [ `cat $ENABLE` -eq 0 ] + then + # Success + echo $MAX > $1 + return 0 + fi + + # It didn't work, try pwmN_enable=1 pwmN=255 + echo 1 > $ENABLE 2> /dev/null + echo $MAX > $1 + if [ `cat $ENABLE` -eq 1 -a `cat $1` -ge 190 ] + then + # Success + return 0 + fi + + # Nothing worked + echo "$ENABLE stuck to" `cat $ENABLE` >&2 + return 1 } # $1 = pwm file name function pwmenable() { - local ENABLE=${1}_enable - - if [ -f $ENABLE ] - then - echo 1 > $ENABLE 2> /dev/null - if [ $? -ne 0 ] - then - return 1 - fi - fi - echo $MAX > $1 + local ENABLE=${1}_enable + + if [ -f $ENABLE ] + then + echo 1 > $ENABLE 2> /dev/null + if [ $? -ne 0 ] + then + return 1 + fi + fi + echo $MAX > $1 } function restorefans() { - local status=$1 fcvcount pwmo - - echo 'Aborting, restoring fans...' - let fcvcount=0 - while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs - do - pwmo=${AFCPWM[$fcvcount]} - pwmdisable $pwmo - let fcvcount=$fcvcount+1 - done - echo 'Verify fans have returned to full speed' - rm -f "$PIDFILE" - exit $status + local status=$1 fcvcount pwmo + + echo 'Aborting, restoring fans...' + let fcvcount=0 + while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs + do + pwmo=${AFCPWM[$fcvcount]} + pwmdisable $pwmo + let fcvcount=$fcvcount+1 + done + echo 'Verify fans have returned to full speed' + rm -f "$PIDFILE" + exit $status } trap 'restorefans 0' SIGQUIT SIGTERM @@ -446,163 +488,166 @@ function lowerBound # main function function UpdateFanSpeeds { - local fcvcount - local pwmo tsens fan mint maxt minsa minso minpwm maxpwm tHyst - local tval pwmpval fanval min_fanval one_fan one_fanval - local -i pwmval - - let fcvcount=0 - while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs - do - #hopefully shorter vars will improve readability: - pwmo=${AFCPWM[$fcvcount]} - tsens=${AFCTEMP[$fcvcount]} - fan=${AFCFAN[$fcvcount]} - let mint="${AFCMINTEMP[$fcvcount]}*1000" - let maxt="${AFCMAXTEMP[$fcvcount]}*1000" - minsa=${AFCMINSTART[$fcvcount]} - minso=${AFCMINSTOP[$fcvcount]} - minpwm=${AFCMINPWM[$fcvcount]} - maxpwm=${AFCMAXPWM[$fcvcount]} - let tHyst="${AFCTHYST[$fcvcount]}*1000" - - #if some fan fault detected all pwm=100% - CheckFanFault - if [ $? -ne 0 ] - then - echo $MAX > $pwmo - let fcvcount=$fcvcount+1 - continue - fi - - read tval < ${tsens} - if [ $? -ne 0 ] - then - echo "Error reading temperature from $DIR/$tsens" - restorefans 1 - fi - - read pwmpval < ${pwmo} - if [ $? -ne 0 ] - then - echo "Error reading PWM value from $DIR/$pwmo" - restorefans 1 - fi - - # If fanspeed-sensor output shall be used, do it - if [[ -n ${fan} ]] - then - min_fanval=100000 - fanval= - # A given PWM output can control several fans - for one_fan in $(echo $fan | sed -e 's/+/ /') - do - read one_fanval < ${one_fan} - if [ $? -ne 0 ] - then - echo "Error reading Fan value from $DIR/$one_fan" >&2 - restorefans 1 - fi - - # Remember the minimum, it only matters if it is 0 - if [ $one_fanval -lt $min_fanval ] - then - min_fanval=$one_fanval - fi - - if [ -z "$fanval" ] - then - fanval=$one_fanval - else - fanval="$fanval/$one_fanval" - fi - done - else - fanval=1 # set it to a non zero value, so the rest of the script still works - fi - - # debug info - if [ "$DEBUG" != "" ] - then - echo "pwmo=$pwmo" - echo "tsens=$tsens" - echo "fan=$fan" - echo "mint=$mint" - echo "maxt=$maxt" - echo "minsa=$minsa" - echo "minso=$minso" - echo "minpwm=$minpwm" - echo "maxpwm=$maxpwm" - echo "tval=$tval" - echo "pwmpval=$pwmpval" - echo "fanval=$fanval" - echo "min_fanval=$min_fanval" - echo "tHyst=$tHyst" - fi - pwmval=$pwmpval - if (( $tval+$tHyst <= $mint )) - then pwmval=$minpwm # below min temp, use defined min pwm - elif (( $tval >= $maxt )) - then pwmval=$maxpwm # over max temp, use defined max pwm - elif (( $tval+$tHyst >= $maxt )) && (( $pwmpval == $maxpwm )) - then pwmval=$maxpwm - else - # calculate the new value from temperature and settings - # pwmval="(${tval}-${mint})*(${maxpwm}-${minso})/(${maxt}-${mint})+${minso} - lowerBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst} - lb=$lw_b - upperBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst} - ub=$up_b - - if [ "$DEBUG" != "" ] - then - echo "old pwm=$pwmval lw_b=$lw_b up_b=$up_b" - fi - - if [[ "$pwmval" -gt "$ub" ]] - then - pwmval=$ub - else - if [[ "$pwmval" -lt "$lb" ]] - then - pwmval=$lb - fi - fi - - if [ $pwmpval -eq 0 -o $min_fanval -eq 0 ] - then # if fan was stopped start it using a safe value - echo $minsa > $pwmo - # Sleep while still handling signals - sleep 1 & - wait $! - fi - fi - echo $pwmval > $pwmo # write new value to pwm output - if [ $? -ne 0 ] - then - echo "Error writing PWM value to $DIR/$pwmo" >&2 - restorefans 1 - fi - if [ "$DEBUG" != "" ] - then - echo "new pwmval=$pwmval" - fi - let fcvcount=$fcvcount+1 - done + local fcvcount + local pwmo tsens fan mint maxt minsa minso minpwm maxpwm tHyst + local tval pwmpval fanval min_fanval one_fan one_fanval + local -i pwmval + + let fcvcount=0 + while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs + do + #hopefully shorter vars will improve readability: + pwmo=${AFCPWM[$fcvcount]} + tsens=${AFCTEMP[$fcvcount]} + fan=${AFCFAN[$fcvcount]} + let mint="${AFCMINTEMP[$fcvcount]}*1000" + let maxt="${AFCMAXTEMP[$fcvcount]}*1000" + minsa=${AFCMINSTART[$fcvcount]} + minso=${AFCMINSTOP[$fcvcount]} + minpwm=${AFCMINPWM[$fcvcount]} + maxpwm=${AFCMAXPWM[$fcvcount]} + let tHyst="${AFCTHYST[$fcvcount]}*1000" + + #if some fan fault detected all pwm=100% + CheckFanFault + if [ $? -ne 0 ] + then + echo $MAX > $pwmo + let fcvcount=$fcvcount+1 + continue + fi + + #check thermal overload + CheckTempOver + + read tval < ${tsens} + if [ $? -ne 0 ] + then + echo "Error reading temperature from $DIR/$tsens" + restorefans 1 + fi + + read pwmpval < ${pwmo} + if [ $? -ne 0 ] + then + echo "Error reading PWM value from $DIR/$pwmo" + restorefans 1 + fi + + # If fanspeed-sensor output shall be used, do it + if [[ -n ${fan} ]] + then + min_fanval=100000 + fanval= + # A given PWM output can control several fans + for one_fan in $(echo $fan | sed -e 's/+/ /') + do + read one_fanval < ${one_fan} + if [ $? -ne 0 ] + then + echo "Error reading Fan value from $DIR/$one_fan" >&2 + restorefans 1 + fi + + # Remember the minimum, it only matters if it is 0 + if [ $one_fanval -lt $min_fanval ] + then + min_fanval=$one_fanval + fi + + if [ -z "$fanval" ] + then + fanval=$one_fanval + else + fanval="$fanval/$one_fanval" + fi + done + else + fanval=1 # set it to a non zero value, so the rest of the script still works + fi + + # debug info + if [ "$DEBUG" != "" ] + then + echo "pwmo=$pwmo" + echo "tsens=$tsens" + echo "fan=$fan" + echo "mint=$mint" + echo "maxt=$maxt" + echo "minsa=$minsa" + echo "minso=$minso" + echo "minpwm=$minpwm" + echo "maxpwm=$maxpwm" + echo "tval=$tval" + echo "pwmpval=$pwmpval" + echo "fanval=$fanval" + echo "min_fanval=$min_fanval" + echo "tHyst=$tHyst" + fi + pwmval=$pwmpval + if (( $tval+$tHyst <= $mint )) + then pwmval=$minpwm # below min temp, use defined min pwm + elif (( $tval >= $maxt )) + then pwmval=$maxpwm # over max temp, use defined max pwm + elif (( $tval+$tHyst >= $maxt )) && (( $pwmpval == $maxpwm )) + then pwmval=$maxpwm + else + # calculate the new value from temperature and settings + # pwmval="(${tval}-${mint})*(${maxpwm}-${minso})/(${maxt}-${mint})+${minso} + lowerBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst} + lb=$lw_b + upperBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst} + ub=$up_b + + if [ "$DEBUG" != "" ] + then + echo "old pwm=$pwmval lw_b=$lw_b up_b=$up_b" + fi + + if [[ "$pwmval" -gt "$ub" ]] + then + pwmval=$ub + else + if [[ "$pwmval" -lt "$lb" ]] + then + pwmval=$lb + fi + fi + + if [ $pwmpval -eq 0 -o $min_fanval -eq 0 ] + then # if fan was stopped start it using a safe value + echo $minsa > $pwmo + # Sleep while still handling signals + sleep 1 & + wait $! + fi + fi + echo $pwmval > $pwmo # write new value to pwm output + if [ $? -ne 0 ] + then + echo "Error writing PWM value to $DIR/$pwmo" >&2 + restorefans 1 + fi + if [ "$DEBUG" != "" ] + then + echo "new pwmval=$pwmval" + fi + let fcvcount=$fcvcount+1 + done } echo 'Enabling PWM on fans...' let fcvcount=0 while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs do - pwmo=${AFCPWM[$fcvcount]} - pwmenable $pwmo - if [ $? -ne 0 ] - then - echo "Error enabling PWM on $DIR/$pwmo" >&2 - restorefans 1 - fi - let fcvcount=$fcvcount+1 + pwmo=${AFCPWM[$fcvcount]} + pwmenable $pwmo + if [ $? -ne 0 ] + then + echo "Error enabling PWM on $DIR/$pwmo" >&2 + restorefans 1 + fi + let fcvcount=$fcvcount+1 done echo 'Starting automatic fan control...' @@ -610,8 +655,8 @@ echo 'Starting automatic fan control...' # main loop calling the main function at specified intervals while true do - UpdateFanSpeeds - # Sleep while still handling signals - sleep $INTERVAL & - wait $! -done \ No newline at end of file + UpdateFanSpeeds + # Sleep while still handling signals + sleep $INTERVAL & + wait $! +done From 7515aea9dbb6edd09d703faa306e1af8a4f06a42 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Thu, 17 Sep 2020 18:33:10 -0700 Subject: [PATCH 1138/1427] [swss] Start Arp Update Process (#5391) Arp update process was not being started due to an issue with the directory name having an extra 'd' in supervisor as in '/etc/supervisord/conf.d/arp_update.conf'. signed-off-by: Tamer Ahmed --- dockers/docker-orchagent/docker-init.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-orchagent/docker-init.sh b/dockers/docker-orchagent/docker-init.sh index 189cf28c9a08..70b9f2d871b5 100755 --- a/dockers/docker-orchagent/docker-init.sh +++ b/dockers/docker-orchagent/docker-init.sh @@ -20,7 +20,7 @@ fi # Start arp_update when VLAN exists if [ "$VLAN" != "" ]; then - cp /usr/share/sonic/templates/arp_update.conf /etc/supervisord/conf.d/ + cp /usr/share/sonic/templates/arp_update.conf /etc/supervisor/conf.d/ fi exec /usr/bin/supervisord From 2868a2793558353a912cd2d738c3a70bb4ef7dbf Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Thu, 17 Sep 2020 22:00:32 -0700 Subject: [PATCH 1139/1427] [mgmt] Upgrade sonic-mgmt container to stretch (#5397) - Bump sonic-mgmt version to 18.04 - Update installation methods - Add virtualenv for python3 Signed-off-by: Danny Allen --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 67142242293c..f5c650c8daf7 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM ubuntu:16.04 +FROM ubuntu:18.04 ENV DEBIAN_FRONTEND=noninteractive @@ -20,6 +20,9 @@ RUN apt-get update && apt-get install -y build-essential \ python-dev \ python-scapy \ python-setuptools \ + python-pip \ + python3-pip \ + python3-venv \ rsyslog \ snmp \ sshpass \ @@ -28,8 +31,6 @@ RUN apt-get update && apt-get install -y build-essential \ telnet \ vim -RUN easy_install pip==20.1.1 - RUN pip install cffi==1.10.0 \ "cryptography>=2.5" \ "future>=0.16.0" \ @@ -156,19 +157,15 @@ USER $user # Install Azure CLI WORKDIR /var/$user -RUN curl -L https://aka.ms/InstallAzureCliBundled -o azure-cli_bundle.tar.gz -RUN tar -xvzf azure-cli_bundle.tar.gz -RUN azure-cli_bundle_*/installer - -# Known bug: azure keyvault cannot work behind a proxy -# Temporary fix: upgrade the azure-keyvault package within az cli -# TODO: if azure-cli contains newer version azure-keyvault, remove this -RUN ~/lib/azure-cli/bin/python -m pip install azure-keyvault==0.3.7 -U +RUN curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash -# Install Virtual Environment +# Install Virtual Environments RUN python -m virtualenv --system-site-packages env-201811 RUN env-201811/bin/pip install ansible==2.0.0.2 +RUN python3 -m venv env-python3 +RUN env-python3/bin/pip3 install azure-kusto-data azure-kusto-ingest defusedxml pytest + # NOTE: There is an ordering dependency for pycryptodome. Leaving this at # the end until we figure that out. RUN pip install pycryptodome==3.9.8 From f18b612ff95c00fa34dc05ac6bcc3c0ba55e3864 Mon Sep 17 00:00:00 2001 From: zhenggen-xu Date: Fri, 18 Sep 2020 15:29:29 -0700 Subject: [PATCH 1140/1427] [DPB Seastone] On boarding DPB feature to Seastone HWSKUs (#4235) This include the platform.json for Seastone platform and individual hwsku.json for each HWSKU port_config.ini will be removed once the CLI/parser library etc changes are merged **- What I did** On boarding DPB feature to Seastone HWSKUs **- How I did it** Add platform.json for Seastone and hwsku.json files to relevant HWSKUs. **- How to verify it** ``` sudo sonic-cfggen -H -k Seastone-DX010 --preset=t1 > config_db.json sudo config reload config_db.json -y show interface status: admin@lnos-x1-a-csw03:~$ show interfaces status Interface Lanes Speed MTU FEC Alias Vlan Oper Admin Type Asym PFC ----------- --------------- ------- ----- ----- ------- ------ ------ ------- ------ ---------- Ethernet0 65,66,67,68 100G 9100 N/A Eth1/1 routed down up N/A N/A Ethernet4 69,70,71,72 100G 9100 N/A Eth2/1 routed down up N/A N/A Ethernet8 73,74,75,76 100G 9100 N/A Eth3/1 routed down up N/A N/A Ethernet12 77,78,79,80 100G 9100 N/A Eth4/1 routed down up N/A N/A Ethernet16 33,34,35,36 100G 9100 N/A Eth5/1 routed down up N/A N/A Ethernet20 37,38,39,40 100G 9100 N/A Eth6/1 routed down up N/A N/A Ethernet24 41,42,43,44 100G 9100 N/A Eth7/1 routed down up N/A N/A Ethernet28 45,46,47,48 100G 9100 N/A Eth8/1 routed down up N/A N/A Ethernet32 49,50,51,52 100G 9100 N/A Eth9/1 routed down up N/A N/A Ethernet36 53,54,55,56 100G 9100 N/A Eth10/1 routed down up N/A N/A Ethernet40 57,58,59,60 100G 9100 N/A Eth11/1 routed down up N/A N/A Ethernet44 61,62,63,64 100G 9100 N/A Eth12/1 routed down up N/A N/A Ethernet48 81,82,83,84 100G 9100 N/A Eth13/1 routed down up N/A N/A Ethernet52 85,86,87,88 100G 9100 N/A Eth14/1 routed down up N/A N/A Ethernet56 89,90,91,92 100G 9100 N/A Eth15/1 routed down up N/A N/A Ethernet60 93,94,95,96 100G 9100 N/A Eth16/1 routed down up N/A N/A Ethernet64 97,98,99,100 100G 9100 N/A Eth17/1 routed down up N/A N/A Ethernet68 101,102,103,104 100G 9100 N/A Eth18/1 routed down up N/A N/A Ethernet72 105,106,107,108 100G 9100 N/A Eth19/1 routed up up N/A N/A Ethernet76 109,110,111,112 100G 9100 N/A Eth20/1 routed down up N/A N/A Ethernet80 1,2,3,4 100G 9100 N/A Eth21/1 routed down up N/A N/A Ethernet84 5,6,7,8 100G 9100 N/A Eth22/1 routed down up N/A N/A Ethernet88 9,10,11,12 100G 9100 N/A Eth23/1 routed down up N/A N/A Ethernet92 13,14,15,16 100G 9100 N/A Eth24/1 routed down up N/A N/A Ethernet96 17,18,19,20 100G 9100 N/A Eth25/1 routed down up N/A N/A Ethernet100 21,22,23,24 100G 9100 N/A Eth26/1 routed down up N/A N/A Ethernet104 25,26,27,28 100G 9100 N/A Eth27/1 routed down up N/A N/A Ethernet108 29,30,31,32 100G 9100 N/A Eth28/1 routed down up N/A N/A Ethernet112 113,114,115,116 100G 9100 N/A Eth29/1 routed down up N/A N/A Ethernet116 117,118,119,120 100G 9100 N/A Eth30/1 routed down up N/A N/A Ethernet120 121,122,123,124 100G 9100 N/A Eth31/1 routed down up N/A N/A Ethernet124 125,126,127,128 100G 9100 N/A Eth32/1 routed down up N/A N/A ``` **Breakout to 2x50G:** ``` admin@lnos-x1-a-csw03:~$ sudo config interface breakout Ethernet0 2x50G -y -f Running Breakout Mode : 1x100G[40G] Target Breakout Mode : 2x50G Ports to be deleted : { "Ethernet0": "100000" } Ports to be added : { "Ethernet2": "50000", "Ethernet0": "50000" } After running Logic to limit the impact Final list of ports to be deleted : { "Ethernet0": "100000" } Final list of ports to be added : { "Ethernet2": "50000", "Ethernet0": "50000" } Loaded below Yang Models ['sonic-acl', 'sonic-extension', 'sonic-interface', 'sonic-loopback-interface', 'sonic-port', 'sonic-portchannel', 'sonic-types', 'sonic-vlan'] Note: Below table(s) have no YANG models: CONTAINER_FEATURE, BGP_NEIGHBOR, VERSIONS, DEVICE_METADATA, FEATURE, LOCK, BREAKOUT_CFG, CRM, Below Config can not be verified, It may cause harm to the system { "BREAKOUT_CFG": { "Ethernet0": { "brkout_mode": "1x100G[40G]" } } } Do you wish to Continue? [y/N]: y Breakout process got successfully completed. Please note loaded setting will be lost after system reboot. To preserve setting, run `config save`. admin@lnos-x1-a-csw03:~$ admin@lnos-x1-a-csw03:~$ admin@lnos-x1-a-csw03:~$ show interfaces status Interface Lanes Speed MTU FEC Alias Vlan Oper Admin Type Asym PFC ----------- --------------- ------- ----- ----- ------- ------ ------ ------- ------ ---------- Ethernet0 65,66 50G N/A N/A Eth1/1 routed down up N/A N/A Ethernet2 67,68 50G 9100 N/A Eth1/3 routed down up N/A N/A admin@lnos-x1-a-csw03:~$ bcmcmd ps ps ena/ speed/ link auto STP lrn inter max cut loop port link Lns duplex scan neg? state pause discrd ops face frame thru? back xe0( 68) down 2 50G FD SW No Forward None FA KR2 9412 No xe1( 69) !ena 1 - SW No Forward None FA None 9122 No ``` **Breakout to 4x25G[10G]:** ``` admin@lnos-x1-a-csw03:~$ sudo config interface breakout Ethernet0 4x25G[10G] -y -f Running Breakout Mode : 2x50G Target Breakout Mode : 4x25G[10G] Ports to be deleted : { "Ethernet2": "50000", "Ethernet0": "50000" } Ports to be added : { "Ethernet2": "25000", "Ethernet3": "25000", "Ethernet0": "25000", "Ethernet1": "25000" } After running Logic to limit the impact Final list of ports to be deleted : { "Ethernet2": "50000", "Ethernet0": "50000" } Final list of ports to be added : { "Ethernet2": "25000", "Ethernet3": "25000", "Ethernet0": "25000", "Ethernet1": "25000" } Loaded below Yang Models ['sonic-acl', 'sonic-extension', 'sonic-interface', 'sonic-loopback-interface', 'sonic-port', 'sonic-portchannel', 'sonic-types', 'sonic-vlan'] Note: Below table(s) have no YANG models: CONTAINER_FEATURE, BGP_NEIGHBOR, VERSIONS, DEVICE_METADATA, FEATURE, LOCK, BREAKOUT_CFG, CRM, Below Config can not be verified, It may cause harm to the system { "BREAKOUT_CFG": { "Ethernet0": { "brkout_mode": "2x50G" } } } Do you wish to Continue? [y/N]: y Breakout process got successfully completed. Please note loaded setting will be lost after system reboot. To preserve setting, run `config save`. admin@lnos-x1-a-csw03:~$ show interfaces status Interface Lanes Speed MTU FEC Alias Vlan Oper Admin Type Asym PFC ----------- --------------- ------- ----- ----- ------- ------ ------ ------- ------ ---------- Ethernet0 65 25G N/A N/A Eth1/1 routed down up N/A N/A Ethernet1 66 25G 9100 N/A Eth1/2 routed down up N/A N/A Ethernet2 67 25G N/A N/A Eth1/3 routed down up N/A N/A Ethernet3 68 25G 9100 N/A Eth1/4 routed down up N/A N/A admin@lnos-x1-a-csw03:~$ bcmcmd ps ps ena/ speed/ link auto STP lrn inter max cut loop port link Lns duplex scan neg? state pause discrd ops face frame thru? back xe0( 68) down 1 25G FD SW No Forward None FA KR 9412 No xe1( 69) down 1 25G FD SW No Forward None FA KR 9122 No xe2( 70) down 1 25G FD SW No Forward None FA KR 9412 No xe3( 71) down 1 25G FD SW No Forward None FA KR 9122 No ``` **Breakin back to 1x100G[40G]:** ``` admin@lnos-x1-a-csw03:~$ sudo config interface breakout Ethernet0 1x10G[40G] -y -f [ERROR] Target mode 1x10G[40G] is not available for the port Ethernet0 Aborted! admin@lnos-x1-a-csw03:~$ sudo config interface breakout Ethernet0 1x100G[40G] -y -f Running Breakout Mode : 4x25G[10G] Target Breakout Mode : 1x100G[40G] Ports to be deleted : { "Ethernet2": "25000", "Ethernet3": "25000", "Ethernet0": "25000", "Ethernet1": "25000" } Ports to be added : { "Ethernet0": "100000" } After running Logic to limit the impact Final list of ports to be deleted : { "Ethernet2": "25000", "Ethernet3": "25000", "Ethernet0": "25000", "Ethernet1": "25000" } Final list of ports to be added : { "Ethernet0": "100000" } Loaded below Yang Models ['sonic-acl', 'sonic-extension', 'sonic-interface', 'sonic-loopback-interface', 'sonic-port', 'sonic-portchannel', 'sonic-types', 'sonic-vlan'] Note: Below table(s) have no YANG models: CONTAINER_FEATURE, BGP_NEIGHBOR, VERSIONS, DEVICE_METADATA, FEATURE, LOCK, FLEX_COUNTER_TABLE, BREAKOUT_CFG, CRM, Below Config can not be verified, It may cause harm to the system { "BREAKOUT_CFG": { "Ethernet0": { "brkout_mode": "4x25G[10G]" } } } Do you wish to Continue? [y/N]: y Breakout process got successfully completed. Please note loaded setting will be lost after system reboot. To preserve setting, run `config save`. admin@lnos-x1-a-csw03:~$ show interfaces status Interface Lanes Speed MTU FEC Alias Vlan Oper Admin Type Asym PFC ----------- --------------- ------- ----- ----- ------- ------ ------ ------- ------ ---------- Ethernet0 65,66,67,68 100G N/A N/A Eth1/1 routed down up N/A N/A admin@lnos-x1-a-csw03:~$ bcmcmd ps ps ena/ speed/ link auto STP lrn inter max cut loop port link Lns duplex scan neg? state pause discrd ops face frame thru? back ce0( 68) down 4 100G FD SW No Forward None FA KR4 9412 No xe0( 69) !ena 1 - SW No Forward None FA None 9122 No xe1( 70) !ena 2 - SW No Forward None FA None 9412 No xe2( 71) !ena 1 - SW No Forward None FA None 9122 No ``` Signed-off-by: Zhenggen Xu --- .../Seastone-DX010-10-50/hwsku.json | 100 +++++++++ .../Seastone-DX010-25-50/hwsku.json | 100 +++++++++ .../Seastone-DX010-50-40/hwsku.json | 100 +++++++++ .../Seastone-DX010-50/hwsku.json | 100 +++++++++ .../Seastone-DX010/hwsku.json | 100 +++++++++ .../x86_64-cel_seastone-r0/platform.json | 196 ++++++++++++++++++ 6 files changed, 696 insertions(+) create mode 100644 device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-10-50/hwsku.json create mode 100644 device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-25-50/hwsku.json create mode 100644 device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-40/hwsku.json create mode 100644 device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50/hwsku.json create mode 100644 device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/hwsku.json create mode 100644 device/celestica/x86_64-cel_seastone-r0/platform.json diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-10-50/hwsku.json b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-10-50/hwsku.json new file mode 100644 index 000000000000..b578376a3313 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-10-50/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet4": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet8": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet12": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet16": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet20": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet24": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet28": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet32": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet36": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet40": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet44": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet48": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet52": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet56": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet60": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet64": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet68": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet72": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet76": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet80": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet84": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet88": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet92": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet96": { + "default_brkout_mode": "2x50G" + }, + "Ethernet100": { + "default_brkout_mode": "2x50G" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G" + }, + "Ethernet108": { + "default_brkout_mode": "2x50G" + }, + "Ethernet112": { + "default_brkout_mode": "2x50G" + }, + "Ethernet116": { + "default_brkout_mode": "2x50G" + }, + "Ethernet120": { + "default_brkout_mode": "2x50G" + }, + "Ethernet124": { + "default_brkout_mode": "2x50G" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-25-50/hwsku.json b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-25-50/hwsku.json new file mode 100644 index 000000000000..b578376a3313 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-25-50/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet4": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet8": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet12": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet16": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet20": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet24": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet28": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet32": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet36": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet40": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet44": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet48": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet52": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet56": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet60": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet64": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet68": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet72": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet76": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet80": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet84": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet88": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet92": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet96": { + "default_brkout_mode": "2x50G" + }, + "Ethernet100": { + "default_brkout_mode": "2x50G" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G" + }, + "Ethernet108": { + "default_brkout_mode": "2x50G" + }, + "Ethernet112": { + "default_brkout_mode": "2x50G" + }, + "Ethernet116": { + "default_brkout_mode": "2x50G" + }, + "Ethernet120": { + "default_brkout_mode": "2x50G" + }, + "Ethernet124": { + "default_brkout_mode": "2x50G" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-40/hwsku.json b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-40/hwsku.json new file mode 100644 index 000000000000..3b1b8a97909a --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-40/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "2x50G" + }, + "Ethernet4": { + "default_brkout_mode": "2x50G" + }, + "Ethernet8": { + "default_brkout_mode": "2x50G" + }, + "Ethernet12": { + "default_brkout_mode": "2x50G" + }, + "Ethernet16": { + "default_brkout_mode": "2x50G" + }, + "Ethernet20": { + "default_brkout_mode": "2x50G" + }, + "Ethernet24": { + "default_brkout_mode": "2x50G" + }, + "Ethernet28": { + "default_brkout_mode": "2x50G" + }, + "Ethernet32": { + "default_brkout_mode": "2x50G" + }, + "Ethernet36": { + "default_brkout_mode": "2x50G" + }, + "Ethernet40": { + "default_brkout_mode": "2x50G" + }, + "Ethernet44": { + "default_brkout_mode": "2x50G" + }, + "Ethernet48": { + "default_brkout_mode": "2x50G" + }, + "Ethernet52": { + "default_brkout_mode": "2x50G" + }, + "Ethernet56": { + "default_brkout_mode": "2x50G" + }, + "Ethernet60": { + "default_brkout_mode": "2x50G" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[40G]" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50/hwsku.json b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50/hwsku.json new file mode 100644 index 000000000000..0b219eee39f7 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "2x50G" + }, + "Ethernet4": { + "default_brkout_mode": "2x50G" + }, + "Ethernet8": { + "default_brkout_mode": "2x50G" + }, + "Ethernet12": { + "default_brkout_mode": "2x50G" + }, + "Ethernet16": { + "default_brkout_mode": "2x50G" + }, + "Ethernet20": { + "default_brkout_mode": "2x50G" + }, + "Ethernet24": { + "default_brkout_mode": "2x50G" + }, + "Ethernet28": { + "default_brkout_mode": "2x50G" + }, + "Ethernet32": { + "default_brkout_mode": "2x50G" + }, + "Ethernet36": { + "default_brkout_mode": "2x50G" + }, + "Ethernet40": { + "default_brkout_mode": "2x50G" + }, + "Ethernet44": { + "default_brkout_mode": "2x50G" + }, + "Ethernet48": { + "default_brkout_mode": "2x50G" + }, + "Ethernet52": { + "default_brkout_mode": "2x50G" + }, + "Ethernet56": { + "default_brkout_mode": "2x50G" + }, + "Ethernet60": { + "default_brkout_mode": "2x50G" + }, + "Ethernet64": { + "default_brkout_mode": "2x50G" + }, + "Ethernet68": { + "default_brkout_mode": "2x50G" + }, + "Ethernet72": { + "default_brkout_mode": "2x50G" + }, + "Ethernet76": { + "default_brkout_mode": "2x50G" + }, + "Ethernet80": { + "default_brkout_mode": "2x50G" + }, + "Ethernet84": { + "default_brkout_mode": "2x50G" + }, + "Ethernet88": { + "default_brkout_mode": "2x50G" + }, + "Ethernet92": { + "default_brkout_mode": "2x50G" + }, + "Ethernet96": { + "default_brkout_mode": "2x50G" + }, + "Ethernet100": { + "default_brkout_mode": "2x50G" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G" + }, + "Ethernet108": { + "default_brkout_mode": "2x50G" + }, + "Ethernet112": { + "default_brkout_mode": "2x50G" + }, + "Ethernet116": { + "default_brkout_mode": "2x50G" + }, + "Ethernet120": { + "default_brkout_mode": "2x50G" + }, + "Ethernet124": { + "default_brkout_mode": "2x50G" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/hwsku.json b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/hwsku.json new file mode 100644 index 000000000000..984ba3e4f15e --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[40G]" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/platform.json b/device/celestica/x86_64-cel_seastone-r0/platform.json new file mode 100644 index 000000000000..66ed83ef2060 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/platform.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "65,66,67,68", + "alias_at_lanes": "Eth1/1, Eth1/2, Eth1/3, Eth1/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "69,70,71,72", + "alias_at_lanes": "Eth2/1, Eth2/2, Eth2/3, Eth2/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "73,74,75,76", + "alias_at_lanes": "Eth3/1, Eth3/2, Eth3/3, Eth3/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "77,78,79,80", + "alias_at_lanes": "Eth4/1, Eth4/2, Eth4/3, Eth4/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "33,34,35,36", + "alias_at_lanes": "Eth5/1, Eth5/2, Eth5/3, Eth5/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "37,38,39,40", + "alias_at_lanes": "Eth6/1, Eth6/2, Eth6/3, Eth6/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "41,42,43,44", + "alias_at_lanes": "Eth7/1, Eth7/2, Eth7/3, Eth7/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "45,46,47,48", + "alias_at_lanes": "Eth8/1, Eth8/2, Eth8/3, Eth8/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "49,50,51,52", + "alias_at_lanes": "Eth9/1, Eth9/2, Eth9/3, Eth9/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "53,54,55,56", + "alias_at_lanes": "Eth10/1, Eth10/2, Eth10/3, Eth10/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "57,58,59,60", + "alias_at_lanes": "Eth11/1, Eth11/2, Eth11/3, Eth11/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "61,62,63,64", + "alias_at_lanes": "Eth12/1, Eth12/2, Eth12/3, Eth12/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "81,82,83,84", + "alias_at_lanes": "Eth13/1, Eth13/2, Eth13/3, Eth13/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "85,86,87,88", + "alias_at_lanes": "Eth14/1, Eth14/2, Eth14/3, Eth14/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "89,90,91,92", + "alias_at_lanes": "Eth15/1, Eth15/2, Eth15/3, Eth15/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "93,94,95,96", + "alias_at_lanes": "Eth16/1, Eth16/2, Eth16/3, Eth16/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "97,98,99,100", + "alias_at_lanes": "Eth17/1, Eth17/2, Eth17/3, Eth17/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "101,102,103,104", + "alias_at_lanes": "Eth18/1, Eth18/2, Eth18/3, Eth18/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "105,106,107,108", + "alias_at_lanes": "Eth19/1, Eth19/2, Eth19/3, Eth19/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "109,110,111,112", + "alias_at_lanes": "Eth20/1, Eth20/2, Eth20/3, Eth20/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "1,2,3,4", + "alias_at_lanes": "Eth21/1, Eth21/2, Eth21/3, Eth21/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "5,6,7,8", + "alias_at_lanes": "Eth22/1, Eth22/2, Eth22/3, Eth22/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "9,10,11,12", + "alias_at_lanes": "Eth23/1, Eth23/2, Eth23/3, Eth23/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "13,14,15,16", + "alias_at_lanes": "Eth24/1, Eth24/2, Eth24/3, Eth24/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "17,18,19,20", + "alias_at_lanes": "Eth25/1, Eth25/2, Eth25/3, Eth25/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "21,22,23,24", + "alias_at_lanes": "Eth26/1, Eth26/2, Eth26/3, Eth26/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "25,26,27,28", + "alias_at_lanes": "Eth27/1, Eth27/2, Eth27/3, Eth27/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "29,30,31,32", + "alias_at_lanes": "Eth28/1, Eth28/2, Eth28/3, Eth28/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "113,114,115,116", + "alias_at_lanes": "Eth29/1, Eth29/2, Eth29/3, Eth29/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "117,118,119,120", + "alias_at_lanes": "Eth30/1, Eth30/2, Eth30/3, Eth30/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "121,122,123,124", + "alias_at_lanes": "Eth31/1, Eth31/2, Eth31/3, Eth31/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "125,126,127,128", + "alias_at_lanes": "Eth32/1, Eth32/2, Eth32/3, Eth32/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + } + } +} \ No newline at end of file From 2de3afaf35494f08a2156689dd73dee3bc3a9fa8 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Fri, 18 Sep 2020 18:44:23 -0700 Subject: [PATCH 1141/1427] [swss] Enhance ARP Update to Call Sonic Cfggen Once (#5398) This PR limited the number of calls to sonic-cfggen to one call per iteration instead of current 3 calls per iteration. The PR also installs jq on host for future scripts if needed. signed-off-by: Tamer Ahmed --- build_debian.sh | 3 ++- dockers/docker-orchagent/Dockerfile.j2 | 2 +- files/build_templates/arp_update_vars.j2 | 5 +++++ files/scripts/arp_update | 11 ++++++----- platform/p4/docker-sonic-p4.mk | 3 ++- platform/p4/docker-sonic-p4/Dockerfile.j2 | 2 ++ platform/vs/docker-sonic-vs.mk | 1 + platform/vs/docker-sonic-vs/Dockerfile.j2 | 2 +- rules/docker-orchagent.mk | 2 +- rules/scripts.dep | 1 + rules/scripts.mk | 4 ++++ 11 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 files/build_templates/arp_update_vars.j2 diff --git a/build_debian.sh b/build_debian.sh index b482ec8be67c..7479001042d8 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -315,7 +315,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in python-pip \ python3-pip \ cron \ - haveged + haveged \ + jq if [[ $CONFIGURED_ARCH == amd64 ]]; then diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 2584a34e1e31..9190a5d89b8f 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -59,7 +59,7 @@ RUN apt-get clean -y && \ rm -rf /debs COPY ["files/arp_update", "/usr/bin"] -COPY ["arp_update.conf", "/usr/share/sonic/templates/"] +COPY ["arp_update.conf", "files/arp_update_vars.j2", "/usr/share/sonic/templates/"] COPY ["enable_counters.py", "/usr/bin"] COPY ["docker-init.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] diff --git a/files/build_templates/arp_update_vars.j2 b/files/build_templates/arp_update_vars.j2 new file mode 100644 index 000000000000..b9315b5ebe50 --- /dev/null +++ b/files/build_templates/arp_update_vars.j2 @@ -0,0 +1,5 @@ +{ + "interface": "{% for (name, prefix) in INTERFACE|pfx_filter %}{% if prefix|ipv6 %}{{ name }} {% endif %}{% endfor %}", + "pc_interface" : "{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}{% if prefix|ipv6 %}{{ name }} {% endif %}{% endfor %}", + "vlan" : "{% if VLAN %}{{ VLAN.keys() | join(' ') }}{% endif %}" +} diff --git a/files/scripts/arp_update b/files/scripts/arp_update index 3cc9cd267985..2fec40c14beb 100755 --- a/files/scripts/arp_update +++ b/files/scripts/arp_update @@ -7,12 +7,13 @@ # Send gratuitous ARP/NDP requests to VLAN member neighbors to refresh # the ipv4/ipv6 neighbors state. +ARP_UPDATE_VARS_FILE="/usr/share/sonic/templates/arp_update_vars.j2" + while /bin/true; do # find L3 interfaces which are UP, send ipv6 multicast pings - echo "{% for (name, prefix) in INTERFACE|pfx_filter %} {{name}} {% endfor %}" > /tmp/intf_tmp.j2 - INTERFACE=`sonic-cfggen -d -t /tmp/intf_tmp.j2` - echo "{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %} {{name}} {% endfor %}" > /tmp/pc_intf_tmp.j2 - PC_INTERFACE=`sonic-cfggen -d -t /tmp/pc_intf_tmp.j2` + ARP_UPDATE_VARS=$(sonic-cfggen -d -t ${ARP_UPDATE_VARS_FILE}) + INTERFACE=$(echo $ARP_UPDATE_VARS | jq -r '.interface') + PC_INTERFACE=$(echo $ARP_UPDATE_VARS | jq -r '.pc_interface') ALL_INTERFACE="$INTERFACE $PC_INTERFACE" for intf in $ALL_INTERFACE; do @@ -23,7 +24,7 @@ while /bin/true; do fi done - VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` + VLAN=$(echo $ARP_UPDATE_VARS | jq -r '.vlan') for vlan in $VLAN; do # generate a list of arping commands: # arping -q -w 0 -c 1 -i ; diff --git a/platform/p4/docker-sonic-p4.mk b/platform/p4/docker-sonic-p4.mk index 7cdeee254c41..657a2a9c6d44 100644 --- a/platform/p4/docker-sonic-p4.mk +++ b/platform/p4/docker-sonic-p4.mk @@ -23,7 +23,8 @@ $(DOCKER_SONIC_P4)_DEPENDS += $(QUAGGA) # endif $(DOCKER_SONIC_P4)_FILES += $(CONFIGDB_LOAD_SCRIPT) \ - $(ARP_UPDATE_SCRIPT) + $(ARP_UPDATE_SCRIPT) \ + $(ARP_UPDATE_VARS_TEMPLATE) $(DOCKER_SONIC_P4)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_SONIC_P4) diff --git a/platform/p4/docker-sonic-p4/Dockerfile.j2 b/platform/p4/docker-sonic-p4/Dockerfile.j2 index 22621b985465..b4d6b23b9201 100644 --- a/platform/p4/docker-sonic-p4/Dockerfile.j2 +++ b/platform/p4/docker-sonic-p4/Dockerfile.j2 @@ -16,6 +16,7 @@ RUN apt-get install -y net-tools \ ethtool \ tcpdump \ ifupdown \ + jq \ bridge-utils \ python-ply \ libqt5core5a \ @@ -78,6 +79,7 @@ COPY ["start.sh", "orchagent.sh", "config_bm.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin"] +COPY ["files/arp_update_vars.j2", "/usr/share/sonic/templates/"] RUN echo "docker-sonic-p4" > /etc/hostname RUN touch /etc/quagga/zebra.conf diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index 55e3f1d3006f..e4dda41374fe 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -41,6 +41,7 @@ endif $(DOCKER_SONIC_VS)_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(ARP_UPDATE_SCRIPT) \ + $(ARP_UPDATE_VARS_TEMPLATE) \ $(BUFFERS_CONFIG_TEMPLATE) \ $(QOS_CONFIG_TEMPLATE) \ $(SONIC_VERSION) \ diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 268bd47f4d5e..af06553202f5 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -131,7 +131,7 @@ COPY ["start.sh", "orchagent.sh", "files/remove_chassisdb_config", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin/"] -COPY ["files/buffers_config.j2", "files/qos_config.j2", "/usr/share/sonic/templates/"] +COPY ["files/buffers_config.j2", "files/qos_config.j2", "files/arp_update_vars.j2", "/usr/share/sonic/templates/"] COPY ["files/sonic_version.yml", "/etc/sonic/"] COPY ["database_config.json", "/etc/default/sonic-db/"] COPY ["hostname.j2", "/usr/share/sonic/templates/"] diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index e60bc8191461..5e2e08ee2437 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -33,4 +33,4 @@ $(DOCKER_ORCHAGENT)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel $(DOCKER_ORCHAGENT)_BASE_IMAGE_FILES += monit_swss:/etc/monit/conf.d -$(DOCKER_ORCHAGENT)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_ORCHAGENT)_FILES += $(ARP_UPDATE_SCRIPT) $(ARP_UPDATE_VARS_TEMPLATE) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/scripts.dep b/rules/scripts.dep index 907ec1722b5b..677a60c2ae47 100644 --- a/rules/scripts.dep +++ b/rules/scripts.dep @@ -1,6 +1,7 @@ #DPKG FRK $(ARP_UPDATE_SCRIPT)_CACHE_MODE := none +$(ARP_UPDATE_VARS_TEMPLATE)_CACHE_MODE := none $(CONFIGDB_LOAD_SCRIPT)_CACHE_MODE := none $(BUFFERS_CONFIG_TEMPLATE)_CACHE_MODE := none $(UPDATE_PROC_VARIABLES_SCRIPT)_CACHE_MODE := none diff --git a/rules/scripts.mk b/rules/scripts.mk index bae3b92538de..971578db09c4 100644 --- a/rules/scripts.mk +++ b/rules/scripts.mk @@ -2,6 +2,9 @@ ARP_UPDATE_SCRIPT = arp_update $(ARP_UPDATE_SCRIPT)_PATH = files/scripts +ARP_UPDATE_VARS_TEMPLATE = arp_update_vars.j2 +$(ARP_UPDATE_VARS_TEMPLATE)_PATH = files/build_templates + CONFIGDB_LOAD_SCRIPT = configdb-load.sh $(CONFIGDB_LOAD_SCRIPT)_PATH = files/scripts @@ -22,6 +25,7 @@ $(RM_CHASSISDB_CONFIG_SCRIPT)_PATH = files/scripts SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(ARP_UPDATE_SCRIPT) \ + $(ARP_UPDATE_VARS_TEMPLATE) \ $(BUFFERS_CONFIG_TEMPLATE) \ $(QOS_CONFIG_TEMPLATE) \ $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) \ From 128def6969d787d65f84dbf530e36390e4559c99 Mon Sep 17 00:00:00 2001 From: gechiang <62408185+gechiang@users.noreply.github.com> Date: Sun, 20 Sep 2020 14:32:09 -0700 Subject: [PATCH 1142/1427] Add bgpmon to be started as a new daemon under BGP docker (#5329) * Add bgpmon under sonic-bgpcfgd to be started as a new daemon under BGP docker * Added bgpmon to be monitored by Monit so that if it crashed, it gets alerted * use console_scripts entry point to package bgpmon --- .../docker-fpm-frr/base_image_files/monit_bgp | 4 + .../frr/supervisord/supervisord.conf.j2 | 11 ++ src/sonic-bgpcfgd/bgpmon.py | 170 ++++++++++++++++++ src/sonic-bgpcfgd/setup.py | 5 + 4 files changed, 190 insertions(+) create mode 100755 src/sonic-bgpcfgd/bgpmon.py diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp index 5dbb794c346b..b9726c619582 100644 --- a/dockers/docker-fpm-frr/base_image_files/monit_bgp +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -6,6 +6,7 @@ ## bgpd ## staticd ## bgpcfgd +## bgpmon ############################################################################### check process zebra matching "/usr/lib/frr/zebra" if does not exist for 5 times within 5 cycles then alert @@ -21,3 +22,6 @@ check process staticd matching "/usr/lib/frr/staticd" check process bgpcfgd matching "python /usr/local/bin/bgpcfgd" if does not exist for 5 times within 5 cycles then alert + +check process bgpmon matching "python /usr/local/bin/bgpmon" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 index 862886b8afae..de6879c43725 100644 --- a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 +++ b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 @@ -84,6 +84,17 @@ stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=bgpd:running +[program:bgpmon] +command=/usr/local/bin/bgpmon +priority=6 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=bgpd:running + {% if DEVICE_METADATA.localhost.docker_routing_config_mode is defined and DEVICE_METADATA.localhost.docker_routing_config_mode == "unified" %} [program:vtysh_b] command=/usr/bin/vtysh -b diff --git a/src/sonic-bgpcfgd/bgpmon.py b/src/sonic-bgpcfgd/bgpmon.py new file mode 100755 index 000000000000..e4a9561142be --- /dev/null +++ b/src/sonic-bgpcfgd/bgpmon.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python2 + +"""" +Description: bgpmon.py -- populating bgp related information in stateDB. + script is started by supervisord in bgp docker when the docker is started. + + Initial creation of this daemon is to assist SNMP agent in obtaining the + BGP related information for its MIB support. The MIB that this daemon is + assiting is for the CiscoBgp4MIB (Neighbor state only). If there are other + BGP related items that needs to be updated in a periodic manner in the + future, then more can be added into this process. + + The script check if there are any bgp activities by monitoring the bgp + frr.log file timestamp. If activity is detected, then it will request bgp + neighbor state via vtysh cli interface. This bgp activity monitoring is + done periodically (every 15 second). When triggered, it looks specifically + for the neighbor state in the json output of show ip bgp neighbors json + and update the state DB for each neighbor accordingly. + In order to not disturb and hold on to the State DB access too long and + removal of the stale neighbors (neighbors that was there previously on + previous get request but no longer there in the current get request), a + "previous" neighbor dictionary will be kept and used to determine if there + is a need to perform update or the peer is stale to be removed from the + state DB +""" +import commands +import json +import os +import syslog +import swsssdk +import time + +PIPE_BATCH_MAX_COUNT = 50 + +class BgpStateGet(): + def __init__(self): + # list peer_l stores the Neighbor peer Ip address + # dic peer_state stores the Neighbor peer state entries + # list new_peer_l stores the new snapshot of Neighbor peer ip address + # dic new_peer_state stores the new snapshot of Neighbor peer states + self.peer_l = [] + self.peer_state = {} + self.new_peer_l = [] + self.new_peer_state = {} + self.cached_timestamp = 0 + self.db = swsssdk.SonicV2Connector() + self.db.connect(self.db.STATE_DB, False) + client = self.db.get_redis_client(self.db.STATE_DB) + self.pipe = client.pipeline() + self.db.delete_all_by_pattern(self.db.STATE_DB, "NEIGH_STATE_TABLE|*" ) + + # A quick way to check if there are anything happening within BGP is to + # check its log file has any activities. This is by checking its modified + # timestamp against the cached timestamp that we keep and if there is a + # difference, there is activity detected. In case the log file got wiped + # out, it will default back to constant pulling every 15 seconds + def bgp_activity_detected(self): + try: + timestamp = os.stat("/var/log/frr/frr.log").st_mtime + if timestamp != self.cached_timestamp: + self.cached_timestamp = timestamp + return True + else: + return False + except (IOError, OSError): + return True + + def update_new_peer_states(self, peer_dict): + peer_l = peer_dict["peers"].keys() + self.new_peer_l.extend(peer_l) + for i in range (0, len(peer_l)): + self.new_peer_state[peer_l[i]] = peer_dict["peers"][peer_l[i]]["state"] + + # Get a new snapshot of BGP neighbors and store them in the "new" location + def get_all_neigh_states(self): + cmd = "vtysh -c 'show bgp summary json'" + rc, output = commands.getstatusoutput(cmd) + if rc: + syslog.syslog(syslog.LOG_ERR, "*ERROR* Failed with rc:{} when execute: {}".format(rc, cmd)) + return + + peer_info = json.loads(output) + # cmd ran successfully, safe to Clean the "new" lists/dic for new sanpshot + del self.new_peer_l[:] + self.new_peer_state.clear() + for key, value in peer_info.items(): + if key == "ipv4Unicast" or key == "ipv6Unicast": + self.update_new_peer_states(value) + + # This method will take the caller's dictionary which contains the peer state operation + # That need to be updated in StateDB using Redis pipeline. + # The data{} will be cleared at the end of this method before returning to caller. + def flush_pipe(self, data): + """Dump each entry in data{} into State DB via redis pipeline. + Args: + data: Neighbor state in dictionary format + { + 'NEIGH_STATE_TABLE|ip_address_a': {'state':state}, + 'NEIGH_STATE_TABLE|ip_address_b': {'state':state}, + 'NEIGH_STATE_TABLE|ip_address_c': {'state':state}, + 'NEIGH_STATE_TABLE|ip_address_x': None, + 'NEIGH_STATE_TABLE|ip_address_z': None + ... + } + """ + for key, value in data.items(): + if value is None: + # delete case + self.pipe.delete(key) + else: + # Add or Modify case + self.pipe.hmset(key, value) + self.pipe.execute() + data.clear() + + def update_neigh_states(self): + data = {} + for i in range (0, len(self.new_peer_l)): + peer = self.new_peer_l[i] + key = "NEIGH_STATE_TABLE|%s" % peer + if peer in self.peer_l: + # only update the entry if state changed + if self.peer_state[peer] != self.new_peer_state[peer]: + # state changed. Update state DB for this entry + state = self.new_peer_state[peer] + data[key] = {'state':state} + self.peer_state[peer] = state + # remove this neighbor from old list since it is accounted for + self.peer_l.remove(peer) + else: + # New neighbor found case. Add to dictionary and state DB + state = self.new_peer_state[peer] + data[key] = {'state':state} + self.peer_state[peer] = state + if len(data) > PIPE_BATCH_MAX_COUNT: + self.flush_pipe(data) + # Check for stale state entries to be cleaned up + while len(self.peer_l) > 0: + # remove this from the stateDB and the current nighbor state entry + peer = self.peer_l.pop(0) + del_key = "NEIGH_STATE_TABLE|%s" % peer + data[del_key] = None + del self.peer_state[peer] + if len(data) > PIPE_BATCH_MAX_COUNT: + self.flush_pipe(data) + # If anything in the pipeline not yet flushed, flush them now + if len(data) > 0: + self.flush_pipe(data) + # Save the new List + self.peer_l = self.new_peer_l[:] + +def main(): + + print "bgpmon service started" + + try: + bgp_state_get = BgpStateGet() + except Exception as e: + syslog.syslog(syslog.LOG_ERR, "{}: error exit 1, reason {}".format(THIS_MODULE, str(e))) + exit(1) + + # periodically obtain the new neighbor infomraton and update if necessary + while True: + time.sleep(15) + if bgp_state_get.bgp_activity_detected(): + bgp_state_get.get_all_neigh_states() + bgp_state_get.update_neigh_states() + +if __name__ == '__main__': + main() diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index fae1c313850e..2f485592c712 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -10,6 +10,11 @@ url='https://github.com/Azure/sonic-buildimage', packages=setuptools.find_packages(), scripts=['bgpcfgd'], + entry_points={ + 'console_scripts': [ + 'bgpmon = bgpmon:main', + ] + }, install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], setup_requires=['pytest-runner', 'pytest'], ) From 3987cbd80a6533555bf506a746372f8ad69d3e89 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sun, 20 Sep 2020 20:16:42 -0700 Subject: [PATCH 1143/1427] [sonic-utilities] Build and install as a Python wheel package (#5409) We are moving toward building all Python packages for SONiC as wheel packages rather than Debian packages. This will also allow us to more easily transition to Python 3. Python files are now packaged in "sonic-utilities" Pyhton wheel. Data files are now packaged in "sonic-utilities-data" Debian package. **- How I did it** - Build and install sonic-utilities as a Python package - Remove explicit installation of wheel dependencies, as these will now get installed implicitly by pip when installing sonic-utilities as a wheel - Build and install new sonic-utilities-data package to install data files required by sonic-utilities applications - Update all references to sonic-utilities scripts/entrypoints to either reference the new /usr/local/bin/ location or remove absolute path entirely where applicable Submodule updates: * src/sonic-utilities aa27dd9...2244d7b (5): > Support building sonic-utilities as a Python wheel package instead of a Debian package (#1122) > [consutil] Display remote device name in show command (#1120) > [vrf] fix check state_db error when vrf moving (#1119) > [consutil] Fix issue where the ConfigDBConnector's reference is missing (#1117) > Update to make config load/reload backward compatible. (#1115) * src/sonic-ztp dd025bc...911d622 (1): > Update paths to reflect new sonic-utilities install location, /usr/local/bin/ (#19) --- build_debian.sh | 6 +++- dockers/docker-fpm-frr/base_image_files/TSC | 2 +- files/build_templates/docker_image_ctl.j2 | 4 +-- .../build_templates/sonic_debian_extension.j2 | 30 +++++++++---------- files/image_config/config-setup/config-setup | 4 +-- files/image_config/fstrim/fstrim.service | 2 +- files/image_config/monit/conf.d/sonic-host | 2 +- files/image_config/sudoers/sudoers | 25 ++++++++-------- .../warmboot-finalizer/finalize-warmboot.sh | 2 +- .../watchdog-control/watchdog-control.sh | 2 +- .../common/fw-updater | 2 +- platform/mellanox/mlnx-onie-fw-update.sh | 2 +- platform/p4/docker-sonic-p4.mk | 2 +- platform/vs/docker-sonic-vs.mk | 8 ++--- platform/vs/docker-sonic-vs/Dockerfile.j2 | 11 ++++--- rules/sonic-utilities-data.dep | 9 ++++++ rules/sonic-utilities-data.mk | 5 ++++ rules/sonic-utilities.dep | 14 ++++----- rules/sonic-utilities.mk | 29 +++++++++--------- slave.mk | 6 ++-- src/sonic-utilities | 2 +- src/sonic-ztp | 2 +- 22 files changed, 92 insertions(+), 79 deletions(-) create mode 100644 rules/sonic-utilities-data.dep create mode 100644 rules/sonic-utilities-data.mk diff --git a/build_debian.sh b/build_debian.sh index 7479001042d8..034a50784bb0 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -318,6 +318,10 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in haveged \ jq +# Install "wheel" package so that we can install .whl packages and not +# encounter a "error: invalid command 'bdist_wheel'" error +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install wheel +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install wheel if [[ $CONFIGURED_ARCH == amd64 ]]; then ## Pre-install the fundamental packages for amd64 (x86) @@ -397,7 +401,7 @@ sudo mkdir -p $FILESYSTEM_ROOT/var/core # Config sysctl sudo augtool --autosave " -set /files/etc/sysctl.conf/kernel.core_pattern '|/usr/bin/coredump-compress %e %t %p %P' +set /files/etc/sysctl.conf/kernel.core_pattern '|/usr/local/bin/coredump-compress %e %t %p %P' set /files/etc/sysctl.conf/kernel.softlockup_panic 1 set /files/etc/sysctl.conf/kernel.panic 10 set /files/etc/sysctl.conf/vm.panic_on_oom 2 diff --git a/dockers/docker-fpm-frr/base_image_files/TSC b/dockers/docker-fpm-frr/base_image_files/TSC index f0ccebb73d60..b8136ae4f4c3 100755 --- a/dockers/docker-fpm-frr/base_image_files/TSC +++ b/dockers/docker-fpm-frr/base_image_files/TSC @@ -2,4 +2,4 @@ docker exec -i bgp /usr/bin/TSC -/usr/bin/portstat -p 5 +portstat -p 5 diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 965d927bc5c5..182f7008cc87 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -125,10 +125,10 @@ function postStartAction() $SONIC_DB_CLI CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi - if [[ -x /usr/bin/db_migrator.py ]]; then + if [[ -x /usr/local/bin/db_migrator.py ]]; then # Migrate the DB to the latest schema version if needed if [ -z "$DEV" ]; then - /usr/bin/db_migrator.py -o migrate + /usr/local/bin/db_migrator.py -o migrate fi fi # Add redis UDS to the redis group and give read/write access to the group diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0c796c092a31..2fbd6687d800 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -169,27 +169,29 @@ sudo cp {{platform_common_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $PLATFORM_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME +# Install Debian packages and their dependencies which are needed by sonic-utilities +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f python-m2crypto + # Install built Python Click package (and its dependencies via 'apt-get -y install -f') # Do this before installing sonic-utilities so that it doesn't attempt to install # an older version as part of its dependencies sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python-click*_all.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -# Install python pexpect used by sonic-utilities consutil -# using pip install instead to get a more recent version than is available through debian -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install pexpect - -# Install tabulate >= 0.8.1 via pip in order to support multi-line row output for sonic-utilities -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install tabulate==0.8.2 - -# Install packages to support Dynamic Port Breakout config command for sonic-utilities -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install xmltodict==0.12.0 -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install jsondiff==1.2.0 +# Install SONiC Utilities Python 2 package +SONIC_UTILITIES_PY2_WHEEL_NAME=$(basename {{sonic_utilities_py2_wheel_path}}) +sudo cp {{sonic_utilities_py2_wheel_path}} $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY2_WHEEL_NAME +sudo LANG=C chroot $FILESYSTEM_ROOT pip install $SONIC_UTILITIES_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY2_WHEEL_NAME -# Install SONiC Utilities (and its dependencies via 'apt-get -y install -f') -sudo dpkg --root=$FILESYSTEM_ROOT -i $python_debs_path/python-sonic-utilities_*.deb || \ +# Install sonic-utilities data files (and any dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-utilities-data_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +# sonic-utilities-data installs bash-completion as a dependency. However, it is disabled by default +# in bash.bashrc, so we copy a version of the file with it enabled here. +sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/ + {% if enable_ztp == "y" %} # Install ZTP (and its dependencies via 'apt-get -y install -f') sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-ztp_*.deb || \ @@ -202,10 +204,6 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-host-service_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f {% endif %} -# SONiC utilities installs bash-completion as a dependency. However, it is disabled by default -# in bash.bashrc, so we copy a version of the file with it enabled here. -sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/ - # Install SONiC Device Data (and its dependencies via 'apt-get -y install -f') sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-device-data_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index d3860caf7c20..be89a983e231 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -188,9 +188,9 @@ load_config() return $? fi - if [[ -x /usr/bin/db_migrator.py ]]; then + if [[ -x /usr/local/bin/db_migrator.py ]]; then # Migrate the DB to the latest schema version if needed - /usr/bin/db_migrator.py -o migrate + /usr/local/bin/db_migrator.py -o migrate fi sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" diff --git a/files/image_config/fstrim/fstrim.service b/files/image_config/fstrim/fstrim.service index 0383b5fa010b..c61683400831 100644 --- a/files/image_config/fstrim/fstrim.service +++ b/files/image_config/fstrim/fstrim.service @@ -3,5 +3,5 @@ Description=Discard unused blocks [Service] Type=oneshot -ExecStartPre=/usr/bin/log_ssd_health +ExecStartPre=/usr/local/bin/log_ssd_health ExecStart=/sbin/fstrim -av diff --git a/files/image_config/monit/conf.d/sonic-host b/files/image_config/monit/conf.d/sonic-host index 0a881eb76f6f..3fd313e24bab 100644 --- a/files/image_config/monit/conf.d/sonic-host +++ b/files/image_config/monit/conf.d/sonic-host @@ -27,6 +27,6 @@ check process rsyslog with pidfile /var/run/rsyslogd.pid # Hence for any discrepancy, there will be log messages for "ERR" level # from both route_check.py & monit. # -check program routeCheck with path "/usr/bin/route_check.py" +check program routeCheck with path "/usr/local/bin/route_check.py" every 5 cycles if status != 0 then alert diff --git a/files/image_config/sudoers/sudoers b/files/image_config/sudoers/sudoers index 98493b25856c..94670e936fbc 100644 --- a/files/image_config/sudoers/sudoers +++ b/files/image_config/sudoers/sudoers @@ -19,26 +19,25 @@ Defaults lecture_file = /etc/sudoers.lecture # Cmnd alias specification # Note: bcmcmd is dangerous for users in read only netgroups because it may operate ASIC -Cmnd_Alias READ_ONLY_CMDS = /sbin/brctl show, \ - /usr/bin/decode-syseeprom, \ - /usr/bin/docker images *, \ +Cmnd_Alias READ_ONLY_CMDS = /bin/cat /var/log/syslog*, \ + /sbin/brctl show, \ /usr/bin/docker exec snmp cat /etc/snmp/snmpd.conf, \ /usr/bin/docker exec bgp cat /etc/quagga/bgpd.conf, \ /usr/bin/docker exec * ps aux, \ + /usr/bin/docker images *, \ /usr/bin/docker ps*, \ - /usr/bin/generate_dump, \ /usr/bin/lldpctl, \ - /usr/bin/lldpshow, \ - /usr/bin/psuutil *, \ /usr/bin/sensors, \ - /usr/bin/sonic-installer list, \ - /usr/bin/sfputil show *, \ - /usr/bin/teamshow, \ + /usr/bin/tail -F /var/log/syslog, \ /usr/bin/vtysh -c show *, \ - /bin/cat /var/log/syslog*, \ - /usr/bin/tail -F /var/log/syslog - -Cmnd_Alias PASSWD_CMDS = /usr/bin/config tacacs passkey *, \ + /usr/local/bin/decode-syseeprom, \ + /usr/local/bin/generate_dump, \ + /usr/local/bin/lldpshow, \ + /usr/local/bin/psuutil *, \ + /usr/local/bin/sonic-installer list, \ + /usr/local/bin/sfputil show * + +Cmnd_Alias PASSWD_CMDS = /usr/local/bin/config tacacs passkey *, \ /usr/sbin/chpasswd * # User privilege specification diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index 01ad921137b6..2cde4028396b 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -6,7 +6,7 @@ VERBOSE=no COMP_LIST="orchagent neighsyncd bgp natsyncd" EXP_STATE="reconciled" -ASSISTANT_SCRIPT="/usr/bin/neighbor_advertiser" +ASSISTANT_SCRIPT="/usr/local/bin/neighbor_advertiser" function debug() diff --git a/files/image_config/watchdog-control/watchdog-control.sh b/files/image_config/watchdog-control/watchdog-control.sh index b26fea03f192..892039964620 100755 --- a/files/image_config/watchdog-control/watchdog-control.sh +++ b/files/image_config/watchdog-control/watchdog-control.sh @@ -1,7 +1,7 @@ #! /bin/bash VERBOSE=no -WATCHDOG_UTIL="/usr/bin/watchdogutil" +WATCHDOG_UTIL="/usr/local/bin/watchdogutil" function debug() { diff --git a/platform/broadcom/sonic-platform-modules-dell/common/fw-updater b/platform/broadcom/sonic-platform-modules-dell/common/fw-updater index 6905664672ad..22cd1e14e3bb 100755 --- a/platform/broadcom/sonic-platform-modules-dell/common/fw-updater +++ b/platform/broadcom/sonic-platform-modules-dell/common/fw-updater @@ -16,7 +16,7 @@ HOST_GRUB_CFG = HOST_GRUB_DIR + '/grub/grub.cfg' HOST_GRUB_ENV = HOST_GRUB_DIR + '/grub/grubenv' HOST_GRUB_BOOT_DIR = '--boot-directory=' + HOST_GRUB_DIR HOST_PLATFORM_INFO = HOST_GRUB_DIR + '/platform' -dell_reload_tool = '/usr/bin/reboot' +dell_reload_tool = '/usr/local/bin/reboot' diff --git a/platform/mellanox/mlnx-onie-fw-update.sh b/platform/mellanox/mlnx-onie-fw-update.sh index 5a62e74b647b..0abc55ef76b4 100755 --- a/platform/mellanox/mlnx-onie-fw-update.sh +++ b/platform/mellanox/mlnx-onie-fw-update.sh @@ -94,7 +94,7 @@ system_reboot() { sleep 5s # Use SONiC reboot scenario - /usr/bin/reboot + /usr/local/bin/reboot } terminate_handler() { diff --git a/platform/p4/docker-sonic-p4.mk b/platform/p4/docker-sonic-p4.mk index 657a2a9c6d44..14747ec476e0 100644 --- a/platform/p4/docker-sonic-p4.mk +++ b/platform/p4/docker-sonic-p4.mk @@ -11,7 +11,7 @@ $(DOCKER_SONIC_P4)_DEPENDS += $(SWSS) \ $(LIBTEAMDCTL) \ $(LIBTEAM_UTILS) \ $(SONIC_DEVICE_DATA) \ - $(SONIC_UTILS) \ + $(SONIC_UTILITIES_PY2) \ $(IPROUTE2) # ifeq ($(ROUTING_STACK), quagga) diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index e4dda41374fe..d1d694756c59 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -10,9 +10,8 @@ $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS) \ $(SONIC_DEVICE_DATA) \ $(LIBYANG) \ $(LIBYANG_CPP) \ - $(LIBYANG_PY2) - -$(DOCKER_SONIC_VS)_PYTHON_DEBS += $(SONIC_UTILS) + $(LIBYANG_PY2) \ + $(SONIC_UTILITIES_DATA) # swsssdk is a dependency of sonic-py-common # TODO: sonic-py-common should depend on swsscommon instead @@ -21,7 +20,8 @@ $(DOCKER_SONIC_VS)_PYTHON_WHEELS += $(SWSSSDK_PY2) \ $(SONIC_PY_COMMON_PY2) \ $(SONIC_PY_COMMON_PY3) \ $(SONIC_YANG_MODELS_PY3) \ - $(SONIC_YANG_MGMT_PY) + $(SONIC_YANG_MGMT_PY) \ + $(SONIC_UTILITIES_PY2) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS_DBG) \ diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index af06553202f5..96d006883bd2 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -46,7 +46,8 @@ RUN apt-get install -y net-tools \ conntrack \ iptables \ python3-pip \ - jq + jq \ + python-m2crypto # install redis-server RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" @@ -56,6 +57,8 @@ RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64. RUN pip install setuptools RUN pip3 install setuptools +RUN pip install wheel +RUN pip3 install wheel RUN pip install py2_ipaddress RUN pip install six RUN pip install pyroute2==0.5.3 netifaces==0.10.7 @@ -102,11 +105,7 @@ COPY python-wheels/{{ whl }} python-wheels/ # install PKGs after copying all PKGs to avoid dependency failure # use py3 to find python3 package, which is forced by wheel as of now {%- for whl in docker_sonic_vs_whls.split(' ') %} -{%- if 'py3' in whl %} -RUN pip3 install python-wheels/{{ whl }} -{% else -%} -RUN pip install python-wheels/{{ whl }} -{%- endif %} +RUN pip{% if 'py3' in whl %}3{% endif %} install python-wheels/{{ whl }} {%- endfor %} {% endif %} diff --git a/rules/sonic-utilities-data.dep b/rules/sonic-utilities-data.dep new file mode 100644 index 000000000000..b11d0a554401 --- /dev/null +++ b/rules/sonic-utilities-data.dep @@ -0,0 +1,9 @@ +SPATH := $($(SONIC_UTILITIES_DATA)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-utilities-data.mk rules/sonic-utilities-data.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_UTILITIES_DATA)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_UTILITIES_DATA)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_UTILITIES_DATA)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic-utilities-data.mk b/rules/sonic-utilities-data.mk new file mode 100644 index 000000000000..8eca8b1c9732 --- /dev/null +++ b/rules/sonic-utilities-data.mk @@ -0,0 +1,5 @@ +# SONiC command line utilities data package + +SONIC_UTILITIES_DATA = sonic-utilities-data_1.0-1_all.deb +$(SONIC_UTILITIES_DATA)_SRC_PATH = $(SRC_PATH)/sonic-utilities/sonic-utilities-data +SONIC_DPKG_DEBS += $(SONIC_UTILITIES_DATA) diff --git a/rules/sonic-utilities.dep b/rules/sonic-utilities.dep index 9d5f64e0ac62..8686c79b61b7 100644 --- a/rules/sonic-utilities.dep +++ b/rules/sonic-utilities.dep @@ -1,12 +1,10 @@ - -SPATH := $($(SONIC_UTILS)_SRC_PATH) +SPATH := $($(SONIC_UTILITIES_PY2)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-utilities.mk rules/sonic-utilities.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) -$(SONIC_UTILS)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_UTILS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_UTILS)_DEP_FILES := $(DEP_FILES) -$(SONIC_UTILS)_SMDEP_FILES := $(SMDEP_FILES) -$(SONIC_UTILS)_SMDEP_PATHS := $(SPATH) - +$(SONIC_UTILITIES_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_UTILITIES_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_UTILITIES_PY2)_DEP_FILES := $(DEP_FILES) +$(SONIC_UTILITIES_PY2)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_UTILITIES_PY2)_SMDEP_PATHS := $(SPATH) diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index c5f3a3b29e82..614602b8507b 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -6,19 +6,18 @@ # added here also. However, the current build system assumes all runtime # dependencies are .deb packages. # -# TODO: Create a way to specify both .deb and .whl runtime dependencies -# then add the aforementioned runtime dependencies here. -# -SONIC_UTILS = python-sonic-utilities_1.2-1_all.deb -$(SONIC_UTILS)_SRC_PATH = $(SRC_PATH)/sonic-utilities -$(SONIC_UTILS)_DEBS_DEPENDS = $(LIBYANG) \ - $(LIBYANG_CPP) \ - $(LIBYANG_PY2) \ - $(LIBYANG_PY3) -$(SONIC_UTILS)_WHEEL_DEPENDS = $(SONIC_PY_COMMON_PY2) \ - $(SONIC_PY_COMMON_PY3) \ - $(SONIC_CONFIG_ENGINE) \ - $(SONIC_YANG_MGMT_PY) \ - $(SONIC_YANG_MODELS_PY3) -SONIC_PYTHON_STDEB_DEBS += $(SONIC_UTILS) +SONIC_UTILITIES_PY2 = sonic_utilities-1.2-py2-none-any.whl +$(SONIC_UTILITIES_PY2)_SRC_PATH = $(SRC_PATH)/sonic-utilities +$(SONIC_UTILITIES_PY2)_PYTHON_VERSION = 2 +$(SONIC_UTILITIES_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) \ + $(SONIC_PY_COMMON_PY3) \ + $(SWSSSDK_PY2) \ + $(SONIC_CONFIG_ENGINE) \ + $(SONIC_YANG_MGMT_PY) \ + $(SONIC_YANG_MODELS_PY3) +$(SONIC_UTILITIES_PY2)_DEBS_DEPENDS = $(LIBYANG) \ + $(LIBYANG_CPP) \ + $(LIBYANG_PY2) \ + $(LIBYANG_PY3) +SONIC_PYTHON_WHEELS += $(SONIC_UTILITIES_PY2) diff --git a/slave.mk b/slave.mk index 157027a4daad..2d45b2c1e13f 100644 --- a/slave.mk +++ b/slave.mk @@ -802,12 +802,13 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(LIBPAM_TACPLUS) \ $(LIBNSS_TACPLUS) \ $(MONIT) \ - $(PYTHON_SWSSCOMMON)) \ + $(PYTHON_SWSSCOMMON) \ + $(SONIC_UTILITIES_DATA)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \ $(if $(findstring y,$(INCLUDE_HOST_SERVICE)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_HOST_SERVICE))) \ - $(addprefix $(PYTHON_DEBS_PATH)/,$(SONIC_UTILS)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_UTILITIES_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ @@ -858,6 +859,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export multi_instance="false" export python_swss_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($(LIBSWSSCOMMON)_RDEPENDS))" export python_swss_debs+=" $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(LIBSWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON_SWSSCOMMON))" + export sonic_utilities_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_UTILITIES_PY2))" $(foreach docker, $($*_DOCKERS),\ export docker_image="$(docker)" diff --git a/src/sonic-utilities b/src/sonic-utilities index aa27dd9781b9..2244d7bec687 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit aa27dd9781b991a944e35612c9faa1ca70b1ed2f +Subproject commit 2244d7bec687fe7f72c3a8565dacdefd47deba0d diff --git a/src/sonic-ztp b/src/sonic-ztp index dd025bc25757..911d62238cb3 160000 --- a/src/sonic-ztp +++ b/src/sonic-ztp @@ -1 +1 @@ -Subproject commit dd025bc25757d8d83c92246bb7b45b9b35a0371b +Subproject commit 911d62238cb30d008f471c9659c3cb105c0604de From 0ed44db7b7c87accb42f4a61330b9a3232310039 Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 21 Sep 2020 02:09:50 -0700 Subject: [PATCH 1144/1427] [docker-base-stretch]: install rsyslog from stretch-backports (#5410) Install a newer version of rsyslog from stretch-backports to support -iNONE Previous backport from master use -iNONE option which is only available after v8.32.0 Signed-off-by: Guohan Lu --- dockers/docker-base-stretch/Dockerfile.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index f563aee8d9ea..a5eda50f0c1c 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -45,7 +45,6 @@ RUN apt-get update && \ procps \ python \ python-pip \ - rsyslog \ vim-tiny \ # Install dependencies of supervisor python-pkg-resources \ @@ -66,6 +65,9 @@ RUN apt-get update && \ # for processing json files in bash environment jq +# Install a newer version of rsyslog from stretch-backports to support -iNONE +RUN apt-get -y -t stretch-backports install rsyslog + # For templating RUN pip install j2cli From 03f82a0107417144a2d133b32b08d099365053d3 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Mon, 21 Sep 2020 14:49:56 -0700 Subject: [PATCH 1145/1427] [submodule]: update sonic-swss-common/sonic-sairedis/sonic-swss (#5406) --- src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- src/sonic-swss-common | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index c4a86b3e66e8..6117cf5549e0 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit c4a86b3e66e8ce14690a9ed796b879325ca676b2 +Subproject commit 6117cf5549e01cf188f3dfbd52fb447dfef9e5ad diff --git a/src/sonic-swss b/src/sonic-swss index 65f63c1647f5..b4938a5519d6 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 65f63c1647f59b75b3d06b1cb293efbbc5472012 +Subproject commit b4938a5519d633ac22eac5e1ea27820d1e665239 diff --git a/src/sonic-swss-common b/src/sonic-swss-common index cc2f80bd4756..2b9a00fffd90 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit cc2f80bd4756a2c4a6b6a426fa60dab475b52681 +Subproject commit 2b9a00fffd90d0efe258e9e10fdd4e859ac190d5 From 97aee026de217cdfd46e938b8f5c82bfef44bb21 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Tue, 22 Sep 2020 11:23:42 +0300 Subject: [PATCH 1146/1427] [logrotate] create separate logrotate.d config for update-alternatives (#5382) To fix the following error when running `logrotate /etc/logrotate.conf` : ``` error: dpkg:10 duplicate log entry for /var/log/alternatives.log error: found error in file dpkg, skipping ``` update-alternatives is provided with dedicated logrotate config in newer dpkg package versions (probably starting from buster) Signed-off-by: Volodymyr Boyko --- files/image_config/logrotate/logrotate.d/alternatives | 9 +++++++++ files/image_config/logrotate/logrotate.d/dpkg | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 files/image_config/logrotate/logrotate.d/alternatives diff --git a/files/image_config/logrotate/logrotate.d/alternatives b/files/image_config/logrotate/logrotate.d/alternatives new file mode 100644 index 000000000000..7c4c93c85834 --- /dev/null +++ b/files/image_config/logrotate/logrotate.d/alternatives @@ -0,0 +1,9 @@ +/var/log/alternatives.log { + size 100k + rotate 1 + compress + delaycompress + missingok + notifempty + create 644 root root +} diff --git a/files/image_config/logrotate/logrotate.d/dpkg b/files/image_config/logrotate/logrotate.d/dpkg index 5e24c7ed74e1..51b8f46fe105 100644 --- a/files/image_config/logrotate/logrotate.d/dpkg +++ b/files/image_config/logrotate/logrotate.d/dpkg @@ -7,12 +7,3 @@ notifempty create 644 root root } -/var/log/alternatives.log { - size 100k - rotate 1 - compress - delaycompress - missingok - notifempty - create 644 root root -} From dd008d012ce9baa77422d4f12f846785fef8eff2 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Tue, 22 Sep 2020 08:24:45 +0000 Subject: [PATCH 1147/1427] DellEMC: PCIe config files for S6000, S6100 (#5321) To support "pcieutil pcie-check" command in DellEMC S6000, S6100. --- .../plugins/pcie.yaml | 65 +++++++++++++++++++ .../plugins/pcie.yaml | 55 ++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 device/dell/x86_64-dell_s6000_s1220-r0/plugins/pcie.yaml create mode 100644 device/dell/x86_64-dell_s6100_c2538-r0/plugins/pcie.yaml diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/pcie.yaml b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/pcie.yaml new file mode 100644 index 000000000000..9c4bea46730a --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/pcie.yaml @@ -0,0 +1,65 @@ +- bus: '00' + dev: '01' + fn: '0' + id: 0c46 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 1' +- bus: '00' + dev: '02' + fn: '0' + id: 0c47 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 2' +- bus: '00' + dev: '03' + fn: '0' + id: 0c48 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 3' +- bus: '00' + dev: '04' + fn: '0' + id: 0c49 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 4' +- bus: '00' + dev: 0e + fn: '0' + id: 0c54 + name: 'IOMMU: Intel Corporation Atom Processor S1200 Internal' +- bus: '00' + dev: '13' + fn: '0' + id: 0c59 + name: 'System peripheral: Intel Corporation Atom Processor S1200 SMBus 2.0 Controller 0' +- bus: '00' + dev: '13' + fn: '1' + id: 0c5a + name: 'System peripheral: Intel Corporation Atom Processor S1200 SMBus 2.0 Controller 1' +- bus: '01' + dev: '00' + fn: '0' + id: b850 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56850 Switch ASIC' +- bus: '02' + dev: '00' + fn: '0' + id: '9170' + name: 'SATA controller: Marvell Technology Group Ltd. Device 9170' +- bus: '03' + dev: '00' + fn: '0' + id: 400a + name: 'PCI bridge: Pericom Semiconductor PI7C9X442SL PCI Express Bridge Port' +- bus: '04' + dev: '01' + fn: '0' + id: 400a + name: 'PCI bridge: Pericom Semiconductor PI7C9X442SL PCI Express Bridge Port' +- bus: '04' + dev: '02' + fn: '0' + id: 400a + name: 'PCI bridge: Pericom Semiconductor PI7C9X442SL PCI Express Bridge Port' +- bus: 08 + dev: '00' + fn: '0' + id: 10d3 + name: 'Ethernet controller: Intel Corporation 82574L Gigabit Network Connection' diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/pcie.yaml b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/pcie.yaml new file mode 100644 index 000000000000..650610c7b557 --- /dev/null +++ b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/pcie.yaml @@ -0,0 +1,55 @@ +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3' +- bus: '00' + dev: '04' + fn: '0' + id: 1f13 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 4' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '00' + dev: '14' + fn: '1' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '00' + dev: '14' + fn: '2' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '01' + dev: '00' + fn: '0' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC' +- bus: '01' + dev: '00' + fn: '1' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC' From a7f4bfa96d58e367415d8169c965613775e7c0d6 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Tue, 22 Sep 2020 08:32:17 -0700 Subject: [PATCH 1148/1427] Enabling ipv6 support on docker container network. This is needed (#5418) for ipv6 communication between container and host in multi-asic platforms. Address is assign is private address space of fd::/80 with prefix len selected as 80 so that last 48 bits can be container mac address and and you prevent NDP neighbor cache invalidation issues in the Docker layer. Ref: https://docs.docker.com/config/daemon/ipv6/ Ref:https://medium.com/@skleeschulte/how-to-enable-ipv6-for-docker-containers-on-ubuntu-18-04-c68394a219a2 Signed-off-by: Abhishek Dosi Co-authored-by: Abhishek Dosi --- files/docker/docker.service.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/docker/docker.service.conf b/files/docker/docker.service.conf index e9ba55c8afa8..7debd85a50ac 100644 --- a/files/docker/docker.service.conf +++ b/files/docker/docker.service.conf @@ -1,3 +1,3 @@ [Service] ExecStart= -ExecStart=/usr/bin/dockerd -H unix:// --storage-driver=overlay2 --bip=240.127.1.1/24 --iptables=false +ExecStart=/usr/bin/dockerd -H unix:// --storage-driver=overlay2 --bip=240.127.1.1/24 --iptables=false --ipv6=true --fixed-cidr-v6=fd00::/80 From 75e4258508e63d865ec509b19eae4fc29bb05f6a Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Tue, 22 Sep 2020 08:34:02 -0700 Subject: [PATCH 1149/1427] Enhanced Feature Table state enable/disable for multi-asic platforms. (#5358) * Enhanced Feature Table state enable/disbale for multi-asic platforms. In Multi-asic for some features we can service per asic so we need to get list of all services. Also updated logic to return if any one of systemctl command return failure and make sure syslog of feature getting enable/disable only come when all commads are sucessful. Moved the service list get api from sonic-util to sonic-py-common Signed-off-by: Abhishek Dosi * Make sure to retun None for both service list in case of error. Signed-off-by: Abhishek Dosi * Return empty list as fail condition Signed-off-by: Abhishek Dosi * Address Review Comments. Made init_cfg.json.j2 knowledegable of Feature service is global scope or per asic scope Signed-off-by: Abhishek Dosi * Fix merge conflict * Address Review Comment. Signed-off-by: Abhishek Dosi Co-authored-by: Abhishek Dosi --- files/build_templates/init_cfg.json.j2 | 2 + files/image_config/hostcfgd/hostcfgd | 104 +++++++++++++++---------- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 7126f2648d74..07ff9b1b3a72 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -39,6 +39,8 @@ "{{feature}}": { "state": "{{state}}", "has_timer" : {{has_timer | lower()}}, + "has_global_scope": {% if feature + '.service' in installer_services.split(' ') %}true{% else %}false{% endif %}, + "has_per_asic_scope": {% if feature + '@.service' in installer_services.split(' ') %}true{% else %}false{% endif %}, "auto_restart": "{{autorestart}}", "high_mem_alert": "disabled" }{% if not loop.last %},{% endif -%} diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 2c66598e3581..2b505ee5a0ee 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -10,6 +10,7 @@ import copy import jinja2 import ipaddr as ipaddress from swsssdk import ConfigDBConnector +from sonic_py_common import device_info # FILE PAM_AUTH_CONF = "/etc/pam.d/common-auth-sonic" @@ -42,45 +43,6 @@ def obfuscate(data): return data -def update_feature_state(feature_name, state, has_timer): - feature_suffixes = ["service"] + (["timer"] if ast.literal_eval(has_timer) else []) - if state == "enabled": - start_cmds = [] - for suffix in feature_suffixes: - start_cmds.append("sudo systemctl unmask {}.{}".format(feature_name, suffix)) - # If feature has timer associated with it, start/enable corresponding systemd .timer unit - # otherwise, start/enable corresponding systemd .service unit - start_cmds.append("sudo systemctl enable {}.{}".format(feature_name, feature_suffixes[-1])) - start_cmds.append("sudo systemctl start {}.{}".format(feature_name, feature_suffixes[-1])) - for cmd in start_cmds: - syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" - .format(err.cmd, err.returncode, err.output)) - continue - syslog.syslog(syslog.LOG_INFO, "Feature '{}.{}' is enabled and started" - .format(feature_name, feature_suffixes[-1])) - elif state == "disabled": - stop_cmds = [] - for suffix in reversed(feature_suffixes): - stop_cmds.append("sudo systemctl stop {}.{}".format(feature_name, suffix)) - stop_cmds.append("sudo systemctl disable {}.{}".format(feature_name, suffix)) - stop_cmds.append("sudo systemctl mask {}.{}".format(feature_name, suffix)) - for cmd in stop_cmds: - syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" - .format(err.cmd, err.returncode, err.output)) - continue - syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(feature_name)) - else: - syslog.syslog(syslog.LOG_ERR, "Unexpected state value '{}' for feature '{}'" - .format(state, feature_name)) - class Iptables(object): def __init__(self): @@ -279,6 +241,66 @@ class HostConfigDaemon: lpbk_table = self.config_db.get_table('LOOPBACK_INTERFACE') self.iptables = Iptables() self.iptables.load(lpbk_table) + self.is_multi_npu = device_info.is_multi_npu() + + def update_feature_state(self, feature_name, state, feature_table): + has_timer = ast.literal_eval(feature_table[feature_name].get('has_timer', 'False')) + has_global_scope = ast.literal_eval(feature_table[feature_name].get('has_global_scope', 'True')) + has_per_asic_scope = ast.literal_eval(feature_table[feature_name].get('has_per_asic_scope', 'False')) + + # Create feature name suffix depending feature is running in host or namespace or in both + feature_name_suffix_list = (([feature_name] if has_global_scope or not self.is_multi_npu else []) + + ([(feature_name + '@' + str(asic_inst)) for asic_inst in range(device_info.get_num_npus()) + if has_per_asic_scope and self.is_multi_npu])) + + if not feature_name_suffix_list: + syslog.syslog(syslog.LOG_ERR, "Feature '{}' service not available" + .format(feature_name)) + + feature_suffixes = ["service"] + (["timer"] if has_timer else []) + + if state == "enabled": + start_cmds = [] + for feature_name_suffix in feature_name_suffix_list: + for suffix in feature_suffixes: + start_cmds.append("sudo systemctl unmask {}.{}".format(feature_name_suffix, suffix)) + # If feature has timer associated with it, start/enable corresponding systemd .timer unit + # otherwise, start/enable corresponding systemd .service unit + start_cmds.append("sudo systemctl enable {}.{}".format(feature_name_suffix, feature_suffixes[-1])) + start_cmds.append("sudo systemctl start {}.{}".format(feature_name_suffix, feature_suffixes[-1])) + for cmd in start_cmds: + syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" + .format(err.cmd, err.returncode, err.output)) + syslog.syslog(syslog.LOG_ERR, "Feature '{}.{}' failed to be enabled and started" + .format(feature_name, feature_suffixes[-1])) + return + syslog.syslog(syslog.LOG_INFO, "Feature '{}.{}' is enabled and started" + .format(feature_name, feature_suffixes[-1])) + elif state == "disabled": + stop_cmds = [] + for feature_name_suffix in feature_name_suffix_list: + for suffix in reversed(feature_suffixes): + stop_cmds.append("sudo systemctl stop {}.{}".format(feature_name_suffix, suffix)) + stop_cmds.append("sudo systemctl disable {}.{}".format(feature_name_suffix, suffix)) + stop_cmds.append("sudo systemctl mask {}.{}".format(feature_name_suffix, suffix)) + for cmd in stop_cmds: + syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" + .format(err.cmd, err.returncode, err.output)) + syslog.syslog(syslog.LOG_ERR, "Feature '{}' failed to be stopped and disabled".format(feature_name)) + return + syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(feature_name)) + else: + syslog.syslog(syslog.LOG_ERR, "Unexpected state value '{}' for feature '{}'" + .format(state, feature_name)) + def update_all_feature_states(self): feature_table = self.config_db.get_table('FEATURE') @@ -292,7 +314,7 @@ class HostConfigDaemon: syslog.syslog(syslog.LOG_WARNING, "Eanble state of feature '{}' is None".format(feature_name)) continue - update_feature_state(feature_name, state, feature_table[feature_name].get('has_timer', 'False')) + self.update_feature_state(feature_name, state, feature_table) def aaa_handler(self, key, data): self.aaacfg.aaa_update(key, data) @@ -334,7 +356,7 @@ class HostConfigDaemon: syslog.syslog(syslog.LOG_WARNING, "Enable state of feature '{}' is None".format(feature_name)) return - update_feature_state(feature_name, state, feature_table[feature_name].get('has_timer', 'False')) + self.update_feature_state(feature_name, state, feature_table) def start(self): # Update all feature states once upon starting From c8277a4ebaacc35862fb3f390a2af9d1636cbd3b Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 23 Sep 2020 00:10:18 +0800 Subject: [PATCH 1150/1427] Update buffer configuration for SKUs based on SN3800 (#5320) C64: 32 100G down links and 32 100G up links. D112C8: 112 50G down links and 8 100G up links. D24C52: 24 50G down links, 20 100G down links, and 32 100G up links. D28C50: 28 50G down links, 18 100G down links, and 32 100G up links. Signed-off-by: Stephen Sun --- .../buffers_defaults_t0.j2 | 99 ++++++++++++++++++- .../buffers_defaults_t1.j2 | 99 ++++++++++++++++++- .../buffers_defaults_t0.j2 | 4 +- .../buffers_defaults_t1.j2 | 4 +- .../buffers_defaults_t0.j2 | 99 ++++++++++++++++++- .../buffers_defaults_t1.j2 | 99 ++++++++++++++++++- .../buffers_defaults_t0.j2 | 99 ++++++++++++++++++- .../buffers_defaults_t1.j2 | 99 ++++++++++++++++++- 8 files changed, 592 insertions(+), 10 deletions(-) mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 deleted file mode 120000 index 53fa14be9027..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..33c89f0e8e75 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '23343104' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '23343104' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 deleted file mode 120000 index ad442959ddca..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..3347e2abffa5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '19410944' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '19410944' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 index 5296eb8ede88..009f1d5ef5cc 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 @@ -1,7 +1,7 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '28856320' %} +{% set ingress_lossless_pool_size = '16576512' %} {% set egress_lossless_pool_size = '34287552' %} -{% set egress_lossy_pool_size = '28856320' %} +{% set egress_lossy_pool_size = '16576512' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 index 95b119a59f97..ae340eb2e6e2 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 @@ -1,7 +1,7 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '27586560' %} +{% set ingress_lossless_pool_size = '14790656' %} {% set egress_lossless_pool_size = '34287552' %} -{% set egress_lossy_pool_size = '27586560' %} +{% set egress_lossy_pool_size = '14790656' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 deleted file mode 120000 index 53fa14be9027..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..3edc53505912 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '21819392' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '21819392' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 deleted file mode 120000 index ad442959ddca..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c946d5ae9631 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '17862656' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '17862656' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 deleted file mode 120000 index 53fa14be9027..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19df7a7e066f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '21565440' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '21565440' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 deleted file mode 120000 index ad442959ddca..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..40768657a4e4 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '17604608' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '17604608' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} From 9feba88455d39f823b16c47390e98550f4c1d31d Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Tue, 22 Sep 2020 09:37:03 -0700 Subject: [PATCH 1151/1427] [mgmt] Fix Azure CLI install behind proxy (#5407) Signed-off-by: Danny Allen --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index f5c650c8daf7..59a237b2cb22 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -97,6 +97,9 @@ RUN apt-get update \ && apt-get update \ && apt-get install -y docker-ce-cli +# Install Azure CLI +RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash + # Install Microsoft Azure Kusto Library for Python RUN pip install azure-kusto-data==0.0.13 \ azure-kusto-ingest==0.0.13 @@ -154,10 +157,10 @@ RUN chmod go= /var/$user/.ssh -R RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers USER $user - -# Install Azure CLI WORKDIR /var/$user -RUN curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + +# Add az symlink for backwards compatibility +RUN mkdir bin && ln -s /usr/bin/az bin/az # Install Virtual Environments RUN python -m virtualenv --system-site-packages env-201811 From a6a10f05b7322f03eb3b19b3dcac8f3149343cf2 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Tue, 22 Sep 2020 11:21:12 -0700 Subject: [PATCH 1152/1427] In SAI 3.5 by default we are supporting 256 Group with 64 Memeber each. (#5400) However in SAI 3.7 default behaviout got changes to 128 Group and 128 Memeber each. This change is to make sure we are using same ECMP Group/Memeber Per Group for 3.7 also so that behaviour is consistent. Signed-off-by: Abhishek Dosi --- .../x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile | 1 + .../x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile | 1 + .../x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile | 1 + .../x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile | 1 + .../x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile | 1 + .../x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile | 1 + .../x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile | 1 + .../Accton-AS7312-54XS/sai.profile | 1 + .../Accton-AS7315-27XB/sai.profile | 1 + .../x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile | 1 + .../x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile | 1 + .../x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile | 1 + .../Accton-AS7716-32XB/sai.profile | 1 + .../x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile | 1 + .../x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile | 1 + .../x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile | 3 ++- .../Alphanetworks-SNH60A0-320FV2/sai.profile | 1 + .../Alphanetworks-SNH60B0-640F/sai.profile | 1 + .../x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile | 1 + .../Arista-7050QX-32S-S4Q31/sai.profile | 1 + .../Arista-7050CX3-32S-C32/sai.profile | 1 + .../x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile | 1 + .../Arista-7060CX-32S-D48C8/sai.profile | 1 + .../Arista-7060CX-32S-Q24C8/sai.profile | 1 + .../Arista-7060CX-32S-Q32/sai.profile.j2 | 1 + .../Arista-7060CX-32S-T96C8/sai.profile | 1 + .../x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile | 1 + .../x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile | 1 + .../x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile | 1 + .../x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile | 1 + .../x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile | 1 + .../x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile | 1 + .../Arista-7280CR3-C28S8/sai.profile | 1 + .../x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile | 1 + device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile | 1 + .../x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile | 1 + .../x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 | 1 + .../x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile | 1 + .../celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile | 1 + .../x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile | 1 + .../x86_64-cel_silverstone-r0/Silverstone/sai.profile | 1 + .../x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 | 1 + .../x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile | 1 + .../x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile | 1 + .../DellEMC-S5232f-C32/sai.profile | 1 + .../DellEMC-S5232f-C8D48/sai.profile | 1 + .../DellEMC-S5232f-P-100G/sai.profile | 1 + .../DellEMC-S5232f-P-10G/sai.profile | 1 + .../DellEMC-S5232f-P-25G/sai.profile | 1 + .../DellEMC-S5248f-P-10G/sai.profile | 1 + .../DellEMC-S5248f-P-25G/sai.profile | 1 + .../DellEMC-Z9264f-C64/sai.profile | 1 + .../DellEMC-Z9264f-C8D112/sai.profile | 1 + .../DellEMC-Z9264f-Q64/sai.profile.j2 | 1 + .../DellEMC-Z9332f-C32/sai.profile | 1 + .../DellEMC-Z9332f-O32/sai.profile | 1 + device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile | 1 + .../delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile | 1 + .../x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile | 1 + device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile | 1 + device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile | 1 + .../x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile | 1 + .../x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile | 1 + .../INGRASYS-S8810-32Q/sai.profile | 1 + .../INGRASYS-S8900-54XC/sai.profile | 1 + .../INGRASYS-S8900-64XC/sai.profile | 1 + .../x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile | 1 + .../INGRASYS-S9200-64X/sai.profile | 1 + .../Juniper-QFX5200-32C-S/sai.profile | 1 + .../x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile | 1 + .../MiTAC-LY1200-B32H0-C3/sai.profile | 1 + .../x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile | 1 + .../x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile | 1 + .../x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile | 1 + .../x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile | 1 + .../x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile | 1 + 76 files changed, 77 insertions(+), 1 deletion(-) diff --git a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile index aec436d22608..9020d35fda23 100755 --- a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile +++ b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5712-72x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile index dc4f243953bf..3c78aab15dcb 100644 --- a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile +++ b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5812t-72x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile index 063814c1fcb3..0ec3aa1896cf 100755 --- a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile +++ b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5812-72x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile index 44dc691640be..124811980e70 100755 --- a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile +++ b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile @@ -1,2 +1,3 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/mv2-as5835t-48x10G+6x100G.config.bcm SAI_BOARD_CONFIG_PATH=/etc/accton +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile index 8b795f81c4f2..744c6571f7c7 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile +++ b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/etc/bcm/mv2-as5835-48x10G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile b/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile index 22432e548b4a..6f2a70f146ca 100644 --- a/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile +++ b/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as6712-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile b/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile index 31aefe2c2905..54cdc34801dd 100644 --- a/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile +++ b/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7312-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile b/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile index 31aefe2c2905..54cdc34801dd 100644 --- a/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile +++ b/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7312-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile b/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile index 191b27dac2f8..551599b5eba9 100644 --- a/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile +++ b/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/qax-as7315-20x10G+4x25G+3x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile index 47e3107477a2..eb932199dfab 100755 --- a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile +++ b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7326-48x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile b/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile index 28953a08f205..6e4d11fb7292 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile +++ b/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7712-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile b/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile index 65944732653c..794c15a5c95a 100644 --- a/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile +++ b/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7716-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile b/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile index 65944732653c..794c15a5c95a 100755 --- a/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile +++ b/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7716-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile index 461cdd76c4d5..276f982e3e3d 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile +++ b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7726-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile index 30fc08adde62..7c7d74d3ce9e 100644 --- a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile +++ b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-as7816-64x25G-48x100G_row1.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile index b366aeaa93c9..60f0d4b11d63 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile +++ b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile @@ -1 +1,2 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-as9716-32x400G.config.bcm \ No newline at end of file +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-as9716-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile index b6e792ad0a18..66d99a8450c3 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile +++ b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-snh60a0-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile index 04555733c028..0abb91695d5d 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile +++ b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-snh60b0-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile index 6479c4c14d3f..cbaa8cdfd51a 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-a7050-qx32s-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile index 9a50433cabdc..0be2fc5e0f45 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-a7050-q31s4-31x40G-4x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile index d359ffc15cba..7d96f190de73 100644 --- a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-a7050cx3-32s-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile index 4f8c558b0885..66f88f894c30 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-32x100G-t1.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile index 87b4ffdadd6d..692f79decc1f 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-8x100G+48x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile index 42e0c57347a2..08abf1198948 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-8x100G+24x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 index 638fd28b0765..e2ad59262cdd 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile index d54a263e72b6..f9a1e2bdc4d6 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-8x100G+96x25G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile index 8f820cb0f066..9d051624c589 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-a7060px4-32-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile index 2163c4be9057..c9a6b4d330ce 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-a7060px4-o32-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile index 74aea949c3b7..2607bef50850 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-a7260cx3-64-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile index 235f2423df82..166f5c5b6e1a 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-a7260cx3-64-112x50G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile index db64a26b47da..a89cba46c3d1 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-a7260cx3-64-64x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile index bf99bb0ad4d2..17ef703d798d 100644 --- a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile +++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32d4-40x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile index 7e699b10430e..f0554cdb874f 100644 --- a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile index 130a3f8c4cbd..ac1394486c61 100644 --- a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32p4-40x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile b/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile index e80e0d4c89b0..9e6a31e3d1e9 100644 --- a/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile +++ b/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th_32x100.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile b/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile index f467f997fe62..a98bdc993e73 100644 --- a/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile +++ b/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/helix4-e1031-48x1G+4x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 index abc2daefd04e..21bf6cd6e737 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile index 46d96b2fd905..50220639519c 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-48x50G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile index ea150bf237c3..b57101d114f0 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-seastone_2-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile index bc7681f0272f..483e85c0c1fa 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-128x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile index 1915eb9b35a1..550bfe181df4 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 index df3cbb558294..d2c794277098 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile index a690c3ff8b94..1076ddfe28f4 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-z9100-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile index 182624c19bd4..b277ae5f0bde 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-z9100-8x100G-48x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai.profile index e5362a7aef00..3491c7700c24 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile index 0daed30c3bc2..b9703d137bb9 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-8x100G+48x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile index e5362a7aef00..3491c7700c24 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile index 947af7ebacc3..166a0fa8c8bc 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-96x10G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile index ae09492f0e76..0c5cf8ca671a 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-96x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile index 52afc687173c..72f420de5d40 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5248f-10g.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile index 4753ec3886c4..eb9a3cb196fe 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5248f-25g.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile index 0a4fed041752..c6e99b771db6 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile index 7bf21827cd19..a6a351387d56 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-8x100G-112x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 index 66859a473733..bfb71fa71e3c 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile index 1c58f69c7e03..bdc55873e429 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-z9332f-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile index 19cd5cb02839..26867a291b00 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-z9332f-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile b/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile index 094e2d2cda01..98876a9c2a39 100644 --- a/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile +++ b/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ag5648-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile b/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile index c77b2bf79a34..a1ec3ca258df 100644 --- a/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile +++ b/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ag9032v1-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile index f0eccb028258..0d3c85f8f38a 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile +++ b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ag9032v2a-32x100G+1x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile index 21f013773e61..2fc46808b555 100644 --- a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile +++ b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-ag9064-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile index 9d3f2cccc2da..2da82c5bffa5 100644 --- a/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile +++ b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-agc032-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile b/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile index 726e1b6dc667..20e067d8eda7 100644 --- a/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile +++ b/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/etc/bcm/helix4-et-6248brb-48x1G+2x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile b/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile index b5586b7ba24c..426284150a0d 100644 --- a/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile +++ b/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-wedge100-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile index 42315ee4ea6a..3205cd2d6ad9 100644 --- a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s8810-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile index 29db3ecd1624..607f20f329a6 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s8900-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile index 77a0e3efa431..1100f7199a3e 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s8900-48x25G+16x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile b/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile index 14a36af5f554..11c0ae1ab636 100644 --- a/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s9100-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile index 5404ca338ffd..d16307aa360d 100644 --- a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-s9200-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile index 4bcf21c09c41..9852552d899e 100644 --- a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-qfx5200-32x100g.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile index dca8c2f68c04..768a7fa47ad4 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-qfx5210-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile index a58c3ac6eabf..c32774b9677c 100644 --- a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ly1200-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile index fbd01105a4f3..219465108df8 100755 --- a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile +++ b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ix1b-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile index 8088d09edc12..367f18e369fa 100644 --- a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ix7-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile index faf28ace4c10..62ee26ea8c15 100644 --- a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ix8-48x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile index 04b43d5a4d33..936f0d0cddcf 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ix8c-48x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile index 54b62b1d097c..70397851c909 100644 --- a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-ix9-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 From a0afe2fc1608a0b352352bb4389b90921ba56c55 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Wed, 23 Sep 2020 03:57:32 +0530 Subject: [PATCH 1153/1427] Dell S6100 fix mux issue (#5414) - Why I did it For fixing PCA MUX attachment issue in Dell S6100 platform. - How I did it Wait till IOM MUX powered up properly and start I2C enumeration. --- .../common/dell_pmc.c | 34 +++++++++++++++ .../s6100/scripts/iom_power_off.sh | 18 ++++---- .../s6100/scripts/iom_power_on.sh | 2 + .../s6100/scripts/s6100_i2c_enumeration.sh | 43 ++++++++++++++++++- 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c index da4f451700eb..8206f20a1867 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -174,6 +174,12 @@ /* Mailbox PowerOn Reason */ #define TRACK_POWERON_REASON 0x05FF +/* CPU Set IO Modules */ +#define CPU_IOM1_CTRL_FLAG 0x04D9 +#define CPU_IOM2_CTRL_FLAG 0x04DA +#define CPU_IOM3_CTRL_FLAG 0x04DB +#define CPU_IOM4_CTRL_FLAG 0x04DC + unsigned long *mmio; static struct kobject *dell_kobj; @@ -752,6 +758,25 @@ static ssize_t show_psu_fan(struct device *dev, return sprintf(buf, "%d\n", ret); } +static ssize_t show_cpu_iom_control(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int cpu_iom_status; + + if(index == 0) + cpu_iom_status = smf_read_reg(data, CPU_IOM1_CTRL_FLAG); + else if (index == 1) + cpu_iom_status = smf_read_reg(data, CPU_IOM2_CTRL_FLAG); + else if (index == 2) + cpu_iom_status = smf_read_reg(data, CPU_IOM3_CTRL_FLAG); + else if (index == 3) + cpu_iom_status = smf_read_reg(data, CPU_IOM4_CTRL_FLAG); + + return sprintf(buf, "%x\n", cpu_iom_status); +} + static umode_t smf_fanin_is_visible(struct kobject *kobj, @@ -2033,6 +2058,11 @@ static SENSOR_DEVICE_ATTR(fan9_serialno, S_IRUGO, show_ppid, NULL, 4); static SENSOR_DEVICE_ATTR(iom_status, S_IRUGO, show_voltage, NULL, 44); static SENSOR_DEVICE_ATTR(iom_presence, S_IRUGO, show_voltage, NULL, 45); +static SENSOR_DEVICE_ATTR(cpu_iom1_control, S_IRUGO, show_cpu_iom_control, NULL, 0); +static SENSOR_DEVICE_ATTR(cpu_iom2_control, S_IRUGO, show_cpu_iom_control, NULL, 1); +static SENSOR_DEVICE_ATTR(cpu_iom3_control, S_IRUGO, show_cpu_iom_control, NULL, 2); +static SENSOR_DEVICE_ATTR(cpu_iom4_control, S_IRUGO, show_cpu_iom_control, NULL, 3); + static SENSOR_DEVICE_ATTR(psu1_presence, S_IRUGO, show_psu, NULL, 1); static SENSOR_DEVICE_ATTR(psu2_presence, S_IRUGO, show_psu, NULL, 6); static SENSOR_DEVICE_ATTR(psu1_serialno, S_IRUGO, show_ppid, NULL, 10); @@ -2082,6 +2112,10 @@ static struct attribute *smf_dell_attrs[] = { &sensor_dev_attr_fan7_serialno.dev_attr.attr, &sensor_dev_attr_fan9_serialno.dev_attr.attr, &sensor_dev_attr_current_total_power.dev_attr.attr, + &sensor_dev_attr_cpu_iom1_control.dev_attr.attr, + &sensor_dev_attr_cpu_iom2_control.dev_attr.attr, + &sensor_dev_attr_cpu_iom3_control.dev_attr.attr, + &sensor_dev_attr_cpu_iom4_control.dev_attr.attr, NULL }; diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh index a7671cfe589c..077d760fdfc0 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh @@ -2,15 +2,15 @@ #This script is used to power off IO modules # IOM can be controlled via SMF using mailbox registers # write 0x2 to 0x04D9 to power off IOM 1 -./io_rd_wr.py --set --val 0x04 --offset 0x210 -./io_rd_wr.py --set --val 0xd9 --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0x04 --offset 0x210 +io_rd_wr.py --set --val 0xd9 --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 # write 0x2 to 0x04DA to power off IOM 2 -./io_rd_wr.py --set --val 0xda --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0xda --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 # write 0x2 to 0x04DB to power off IOM 3 -./io_rd_wr.py --set --val 0xdb --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0xdb --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 # write 0x2 to 0x04DC to power off IOM 4 -./io_rd_wr.py --set --val 0xdc --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0xdc --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh index 3d31170803e1..80b876c216ec 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh @@ -15,3 +15,5 @@ # write 0x1 to 0x04DC to power up IOM 4 /usr/local/bin/io_rd_wr.py --set --val 0xdc --offset 0x211 /usr/local/bin/io_rd_wr.py --set --val 0x1 --offset 0x213 +#Delay for SMF to power on IOMs +sleep 3 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh index af91f378339e..d00fec233eaa 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh @@ -239,17 +239,58 @@ reset_muxes() { init_devnum +check_iom_status() +{ + SMF_DIR="/sys/devices/platform/SMF.512/hwmon/*" + count=0 + iom_sta=0 + MAX_IOM_STARTUP_DELAY=50 + + if [ -d $SMF_DIR ]; then + iom_status=$(cat $SMF_DIR/iom_status) + cpu_iom1_sta=$(cat $SMF_DIR/cpu_iom1_control) + cpu_iom2_sta=$(cat $SMF_DIR/cpu_iom2_control) + cpu_iom3_sta=$(cat $SMF_DIR/cpu_iom3_control) + cpu_iom4_sta=$(cat $SMF_DIR/cpu_iom4_control) + cpu_iom_sta=$(( cpu_iom1_sta|cpu_iom2_sta|cpu_iom3_sta|cpu_iom4_sta )) + echo "Started polling IOM status" + while [ "$iom_status" != "f0" -o "$cpu_iom_sta" != "0" ]; + do + if [ "$count" -gt "$MAX_IOM_STARTUP_DELAY" ];then + echo "IOM is taking longer than expected to power up.Aborting. + iom_status- $iom_status cpu_iom_sta1- $cpu_iom1_sta cpu_iom_sta2- $cpu_iom2_sta + cpu_iom_sta3- $cpu_iom3_sta cpu_iom_sta4- $cpu_iom4_sta " + iom_sta=1 + break + fi + cpu_iom1_sta=$(cat $SMF_DIR/cpu_iom1_control) + cpu_iom2_sta=$(cat $SMF_DIR/cpu_iom2_control) + cpu_iom3_sta=$(cat $SMF_DIR/cpu_iom3_control) + cpu_iom4_sta=$(cat $SMF_DIR/cpu_iom4_control) + cpu_iom_sta=$(( cpu_iom1_sta|cpu_iom2_sta|cpu_iom3_sta|cpu_iom4_sta )) + iom_status=$(cat $SMF_DIR/iom_status) + sleep .1 + count=`expr $count + 1` + done + + if [ "$iom_sta" != "1" ];then + echo "All IOM's are UP" + fi + fi +} + if [[ "$1" == "init" ]]; then cpu_board_mux "new_device" switch_board_mux "new_device" sys_eeprom "new_device" switch_board_eeprom "new_device" switch_board_cpld "new_device" - /usr/local/bin/s6100_bitbang_reset.sh + check_iom_status switch_board_qsfp_mux "new_device" switch_board_sfp "new_device" switch_board_qsfp "new_device" switch_board_qsfp_lpmode "disable" + /usr/local/bin/s6100_bitbang_reset.sh xcvr_presence_interrupts "enable" elif [[ "$1" == "deinit" ]]; then xcvr_presence_interrupts "disable" From f2194010f8765ebf863d2d7cc92bdabdf0476465 Mon Sep 17 00:00:00 2001 From: vdahiya12 <67608553+vdahiya12@users.noreply.github.com> Date: Tue, 22 Sep 2020 17:12:51 -0700 Subject: [PATCH 1154/1427] [MSN2700] Add platform.json file containing platform hardware facts (#5189) As part of Platform api testing for multiple platforms, this pull request adds a platform.json file which contains all the static data for Mellanox-2700 platform. This file would provide all the platform specific data required for testing of all the Platform tests . As part of testing the API's the values of static/default objects within this specific platform file will be compared against the values returned by calling the Platform specific API's in a typical platform test --- .../x86_64-mlnx_msn2700-r0/platform.json | 311 ++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/platform.json diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json b/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json new file mode 100644 index 000000000000..cdb3e52fd682 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json @@ -0,0 +1,311 @@ +{ + "chassis": { + "name": "MSN2700", + "components": [ + { + "name": "ONIE" + }, + { + "name": "SSD" + }, + { + "name": "BIOS" + }, + { + "name": "CPLD1" + }, + { + "name": "CPLD2" + }, + { + "name": "CPLD3" + } + ], + "fans": [], + "fan_drawers": [ + { + "name": "drawer1", + "fans": [ + { + "name": "fan1" + }, + { + "name": "fan2" + } + ] + }, + { + "name": "drawer2", + "fans": [ + { + "name": "fan3" + }, + { + "name": "fan4" + } + ] + }, + { + "name": "drawer3", + "fans": [ + { + "name": "fan5" + }, + { + "name": "fan6" + } + ] + }, + { + "name": "drawer4", + "fans": [ + { + "name": "fan7" + }, + { + "name": "fan8" + } + ] + } + ], + "psus": [ + { + "name": "PSU 1", + "fans": [ + { + "name": "psu_1_fan_1" + } + ] + }, + { + "name": "PSU 2", + "fans": [ + { + "name": "psu_2_fan_1" + } + ] + } + ], + "thermals": [ + { + "name": "ASIC" + }, + { + "name": "Ambient Fan Side Temp" + }, + { + "name": "Ambient Port Side Temp" + }, + { + "name": "CPU Core 0 Temp" + }, + { + "name": "CPU Core 1 Temp" + }, + { + "name": "CPU Pack Temp" + }, + { + "name": "PSU-1 Temp" + }, + { + "name": "PSU-2 Temp" + }, + { + "name": "xSFP module 1 Temp" + }, + { + "name": "xSFP module 2 Temp" + }, + { + "name": "xSFP module 3 Temp" + }, + { + "name": "xSFP module 4 Temp" + }, + { + "name": "xSFP module 5 Temp" + }, + { + "name": "xSFP module 6 Temp" + }, + { + "name": "xSFP module 7 Temp" + }, + { + "name": "xSFP module 8 Temp" + }, + { + "name": "xSFP module 9 Temp" + }, + { + "name": "xSFP module 10 Temp" + }, + { + "name": "xSFP module 11 Temp" + }, + { + "name": "xSFP module 12 Temp" + }, + { + "name": "xSFP module 13 Temp" + }, + { + "name": "xSFP module 14 Temp" + }, + { + "name": "xSFP module 15 Temp" + }, + { + "name": "xSFP module 16 Temp" + }, + { + "name": "xSFP module 17 Temp" + }, + { + "name": "xSFP module 18 Temp" + }, + { + "name": "xSFP module 19 Temp" + }, + { + "name": "xSFP module 20 Temp" + }, + { + "name": "xSFP module 21 Temp" + }, + { + "name": "xSFP module 22 Temp" + }, + { + "name": "xSFP module 23 Temp" + }, + { + "name": "xSFP module 24 Temp" + }, + { + "name": "xSFP module 25 Temp" + }, + { + "name": "xSFP module 26 Temp" + }, + { + "name": "xSFP module 27 Temp" + }, + { + "name": "xSFP module 28 Temp" + }, + { + "name": "xSFP module 29 Temp" + }, + { + "name": "xSFP module 30 Temp" + }, + { + "name": "xSFP module 31 Temp" + }, + { + "name": "xSFP module 32 Temp" + } + ], + "sfps": [ + { + "name": "sfp1" + }, + { + "name": "sfp2" + }, + { + "name": "sfp3" + }, + { + "name": "sfp4" + }, + { + "name": "sfp5" + }, + { + "name": "sfp6" + }, + { + "name": "sfp7" + }, + { + "name": "sfp8" + }, + { + "name": "sfp9" + }, + { + "name": "sfp10" + }, + { + "name": "sfp11" + }, + { + "name": "sfp12" + }, + { + "name": "sfp13" + }, + { + "name": "sfp14" + }, + { + "name": "sfp15" + }, + { + "name": "sfp16" + }, + { + "name": "sfp17" + }, + { + "name": "sfp18" + }, + { + "name": "sfp19" + }, + { + "name": "sfp20" + }, + { + "name": "sfp21" + }, + { + "name": "sfp22" + }, + { + "name": "sfp23" + }, + { + "name": "sfp24" + }, + { + "name": "sfp25" + }, + { + "name": "sfp26" + }, + { + "name": "sfp27" + }, + { + "name": "sfp28" + }, + { + "name": "sfp29" + }, + { + "name": "sfp30" + }, + { + "name": "sfp31" + }, + { + "name": "sfp32" + } + ] + }, + "interfaces": {} +} From 7eda531ffd512d1cb8e21f7a509a28601c3fd48e Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Tue, 22 Sep 2020 18:39:14 -0700 Subject: [PATCH 1155/1427] [mgmt] Install ip command in mgmt docker (#5430) Signed-off-by: Danny Allen --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 59a237b2cb22..c4d43c56c0b7 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -9,6 +9,7 @@ RUN apt-get update && apt-get install -y build-essential \ gcc \ git \ inetutils-ping \ + iproute2 \ libffi-dev \ libssl-dev \ libxml2 \ From 12d56adbfab24b49301224ea5d3b3803834fee40 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Wed, 23 Sep 2020 16:47:10 +0200 Subject: [PATCH 1156/1427] [docker-sonic-vs]: Add libzmq5 to docker-sonic-vs (#5431) libzmq5 is tcp/ipc communication library, needed by sairedis/syncd to communicate, as a new way (compared to current REDIS channel) to exchange messages which is faster than REDIS library and allows synchronous mode this library is required in sairedis repo, swss repo, sonic-buildimage and sonic-build-tools to make it work --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 96d006883bd2..55c68a049ae1 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -47,7 +47,8 @@ RUN apt-get install -y net-tools \ iptables \ python3-pip \ jq \ - python-m2crypto + python-m2crypto \ + libzmq5 # install redis-server RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" From 0483255e8231714055d41ca18103f24c42226cfc Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 23 Sep 2020 08:07:09 -0700 Subject: [PATCH 1157/1427] Fix the build issue when port2cable lenth define in (#5437) buffer_default_*.j2 because of which internal cable length never gets define and cause failure in test case test_multinpu_cfggen.py Signed-off-by: Abhishek Dosi Co-authored-by: Abhishek Dosi --- files/build_templates/buffers_config.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index f8733ed8e587..0eb976599a53 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -34,7 +34,6 @@ def {%- else %} {%- set ports2cable = { 'torrouter_server' : '5m', - 'internal' : '5m', 'leafrouter_torrouter' : '40m', 'spinerouter_leafrouter' : '300m' } @@ -50,6 +49,9 @@ def {%- set neighbor_role = neighbor.type %} {%- if 'asic' == neighbor_role | lower %} {%- set roles1 = 'internal' %} + {%- if 'internal' not in ports2cable %} + {%- set _ = ports2cable.update({'internal': '5m'}) %} + {%- endif -%} {%- else %} {%- set roles1 = switch_role + '_' + neighbor_role %} {%- set roles2 = neighbor_role + '_' + switch_role %} From 04c709d27fbc59880454519da357f1cf23409cf5 Mon Sep 17 00:00:00 2001 From: gechiang <62408185+gechiang@users.noreply.github.com> Date: Wed, 23 Sep 2020 09:40:49 -0700 Subject: [PATCH 1158/1427] Fix bgpmon.py packaging issue for console_scripts entry point (#5436) * Fix bgpmon.py packaging issue for console_scripts entry point * renamed directory from bgpmon_proj to bgpmon --- src/sonic-bgpcfgd/bgpmon/__init__.py | 0 src/sonic-bgpcfgd/{ => bgpmon}/bgpmon.py | 0 src/sonic-bgpcfgd/setup.py | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/sonic-bgpcfgd/bgpmon/__init__.py rename src/sonic-bgpcfgd/{ => bgpmon}/bgpmon.py (100%) diff --git a/src/sonic-bgpcfgd/bgpmon/__init__.py b/src/sonic-bgpcfgd/bgpmon/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-bgpcfgd/bgpmon.py b/src/sonic-bgpcfgd/bgpmon/bgpmon.py similarity index 100% rename from src/sonic-bgpcfgd/bgpmon.py rename to src/sonic-bgpcfgd/bgpmon/bgpmon.py diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index 2f485592c712..29d441e09a66 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -12,7 +12,7 @@ scripts=['bgpcfgd'], entry_points={ 'console_scripts': [ - 'bgpmon = bgpmon:main', + 'bgpmon = bgpmon.bgpmon:main', ] }, install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], From 418e437d793d841c6238d9ff0dff155b54b6ccdd Mon Sep 17 00:00:00 2001 From: Venkatesan Mahalingam <34145258+venkatmahalingam@users.noreply.github.com> Date: Wed, 23 Sep 2020 09:55:09 -0700 Subject: [PATCH 1159/1427] [caclmgrd] Add support to allow/deny any IP/IPv6 protocol packets coming to CPU based on source IP (#4591) Add support to allow/deny packets coming to CPU based on source IP, regardless of destination port --- files/image_config/caclmgrd/caclmgrd | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index ed6064b9696f..d7951677bee1 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -68,6 +68,10 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): "SSH": { "ip_protocols": ["tcp"], "dst_ports": ["22"] + }, + "ANY": { + "ip_protocols": ["any"], + "dst_ports": ["0"] } } @@ -375,14 +379,19 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): for ip_protocol in ip_protocols: for dst_port in dst_ports: rule_cmd = "ip6tables" if table_ip_version == 6 else "iptables" - rule_cmd += " -A INPUT -p {}".format(ip_protocol) + rule_cmd += " -A INPUT" + if ip_protocol != "any": + rule_cmd += " -p {}".format(ip_protocol) + if "SRC_IPV6" in rule_props and rule_props["SRC_IPV6"]: rule_cmd += " -s {}".format(rule_props["SRC_IPV6"]) elif "SRC_IP" in rule_props and rule_props["SRC_IP"]: rule_cmd += " -s {}".format(rule_props["SRC_IP"]) - rule_cmd += " --dport {}".format(dst_port) + # Destination port 0 is reserved/unused port, so, using it to apply the rule to all ports. + if dst_port != "0": + rule_cmd += " --dport {}".format(dst_port) # If there are TCP flags present and ip protocol is TCP, append them if ip_protocol == "tcp" and "TCP_FLAGS" in rule_props and rule_props["TCP_FLAGS"]: From ec9281be7656793bcc3cc2f1b5e077c592ea4704 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 23 Sep 2020 19:24:59 -0700 Subject: [PATCH 1160/1427] [sonic-platform-common][sonic-platform-daemons][sonic-snmpagent][sonic-utilities] Update submodules (#5435) Update Python-based submodules to include updated dependencies in setup.py files. * src/sonic-platform-common 14c6e53...7255d3a (2): > [setup.py] Update dependenices (#120) > [sfputilbase|sfputilhelper] fix value unpack error due to port_alias_asic_map in portconfig.py file (#116) * src/sonic-platform-daemons e1842b2...1aaffcc (2): > Add 'wheel' package to 'setup_requires' list (#95) > [thermalctld] Fix issue: thermalctld should be auto restarted when being killed (#94) * src/sonic-snmpagent 1a2b62a...5957460 (1): > [setup.py] Add 'wheel' to 'setup_requires' (#160) * src/sonic-utilities 2244d7b...2f79ac1 (4): > [show] Add missing import to fix `show ip interfaces` (#1126) > Fixed config load_minigrpah not working for Multi-asic platfroms. (#1123) > Add CLI for configuring synchronous mode (#1094) > [setup.py] Update dependencies (#1125) --- src/sonic-platform-common | 2 +- src/sonic-platform-daemons | 2 +- src/sonic-snmpagent | 2 +- src/sonic-utilities | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 14c6e53ecb86..7255d3a7a2dd 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 14c6e53ecb861e124e2b45a7b65875ffac1b949e +Subproject commit 7255d3a7a2ddea52cd88dcf0512ea1587ea63e6e diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index e1842b2dff48..1aaffcc98fc5 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit e1842b2dff481735ab42a7b0fd5594c24b7018e9 +Subproject commit 1aaffcc98fc56574a2d8b3ce3a7c50c4a6e8f8fc diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 1a2b62a93028..5957460b9f1b 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 1a2b62a93028642ad77ce8c0f356d093850d0343 +Subproject commit 5957460b9f1b5bc2657ded3a0bb4d84016c08da9 diff --git a/src/sonic-utilities b/src/sonic-utilities index 2244d7bec687..2f79ac135018 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 2244d7bec687fe7f72c3a8565dacdefd47deba0d +Subproject commit 2f79ac135018b62a2a04e031c5221799fcaa2dc4 From a56ad41b9ed83fc529135caa62929dff8e95decb Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Wed, 23 Sep 2020 20:01:58 -0700 Subject: [PATCH 1161/1427] [mgmt] Install dhclient in sonic-mgmt docker (#5447) Signed-off-by: Danny Allen --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index c4d43c56c0b7..736d83d2b4e2 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -10,6 +10,7 @@ RUN apt-get update && apt-get install -y build-essential \ git \ inetutils-ping \ iproute2 \ + isc-dhcp-client \ libffi-dev \ libssl-dev \ libxml2 \ From 4ec83b25bc4bf5f119d8c297a715836c95588f93 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Wed, 23 Sep 2020 22:41:07 -0700 Subject: [PATCH 1162/1427] [arista]: Add new 48x50G + 8x100G hwsku for Lodoga (#5452) --- .../Arista-7050CX3-32S-D48C8/port_config.ini | 57 ++ .../Arista-7050CX3-32S-D48C8/sai.profile | 2 + .../td3-a7050cx3-32s-48x50G+8x100G.config.bcm | 545 ++++++++++++++++++ 3 files changed, 604 insertions(+) create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/port_config.ini create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/sai.profile create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/td3-a7050cx3-32s-48x50G+8x100G.config.bcm diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/port_config.ini b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/port_config.ini new file mode 100644 index 000000000000..25670f87d9cc --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 1,2 Ethernet1/1 1 50000 +Ethernet2 3,4 Ethernet1/3 1 50000 +Ethernet4 5,6 Ethernet2/1 2 50000 +Ethernet6 7,8 Ethernet2/3 2 50000 +Ethernet8 9,10 Ethernet3/1 3 50000 +Ethernet10 11,12 Ethernet3/3 3 50000 +Ethernet12 13,14 Ethernet4/1 4 50000 +Ethernet14 15,16 Ethernet4/3 4 50000 +Ethernet16 21,22 Ethernet5/1 5 50000 +Ethernet18 23,24 Ethernet5/3 5 50000 +Ethernet20 17,18 Ethernet6/1 6 50000 +Ethernet22 19,20 Ethernet6/3 6 50000 +Ethernet24 25,26,27,28 Ethernet7/1 7 100000 +Ethernet28 29,30,31,32 Ethernet8/1 8 100000 +Ethernet32 37,38,39,40 Ethernet9/1 9 100000 +Ethernet36 33,34,35,36 Ethernet10/1 10 100000 +Ethernet40 41,42 Ethernet11/1 11 50000 +Ethernet42 43,44 Ethernet11/3 11 50000 +Ethernet44 45,46 Ethernet12/1 12 50000 +Ethernet46 47,48 Ethernet12/3 12 50000 +Ethernet48 53,54 Ethernet13/1 13 50000 +Ethernet50 55,56 Ethernet13/3 13 50000 +Ethernet52 49,50 Ethernet14/1 14 50000 +Ethernet54 51,52 Ethernet14/3 14 50000 +Ethernet56 57,58 Ethernet15/1 15 50000 +Ethernet58 59,60 Ethernet15/3 15 50000 +Ethernet60 61,62 Ethernet16/1 16 50000 +Ethernet62 63,64 Ethernet16/3 16 50000 +Ethernet64 69,70 Ethernet17/1 17 50000 +Ethernet66 71,72 Ethernet17/3 17 50000 +Ethernet68 65,66 Ethernet18/1 18 50000 +Ethernet70 67,68 Ethernet18/3 18 50000 +Ethernet72 73,74 Ethernet19/1 19 50000 +Ethernet74 75,76 Ethernet19/3 19 50000 +Ethernet76 77,78 Ethernet20/1 20 50000 +Ethernet78 79,80 Ethernet20/3 20 50000 +Ethernet80 85,86 Ethernet21/1 21 50000 +Ethernet82 87,88 Ethernet21/3 21 50000 +Ethernet84 81,82 Ethernet22/1 22 50000 +Ethernet86 83,84 Ethernet22/3 22 50000 +Ethernet88 89,90,91,92 Ethernet23/1 23 100000 +Ethernet92 93,94,95,96 Ethernet24/1 24 100000 +Ethernet96 101,102,103,104 Ethernet25/1 25 100000 +Ethernet100 97,98,99,100 Ethernet26/1 26 100000 +Ethernet104 105,106 Ethernet27/1 27 50000 +Ethernet106 107,108 Ethernet27/3 27 50000 +Ethernet108 109,110 Ethernet28/1 28 50000 +Ethernet110 111,112 Ethernet28/3 28 50000 +Ethernet112 117,118 Ethernet29/1 29 50000 +Ethernet114 119,120 Ethernet29/3 29 50000 +Ethernet116 113,114 Ethernet30/1 30 50000 +Ethernet118 115,116 Ethernet30/3 30 50000 +Ethernet120 121,122 Ethernet31/1 31 50000 +Ethernet122 123,124 Ethernet31/3 31 50000 +Ethernet124 125,126 Ethernet32/1 32 50000 +Ethernet126 127,128 Ethernet32/3 32 50000 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/sai.profile b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/sai.profile new file mode 100644 index 000000000000..1865041f8d9f --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-a7050cx3-32s-48x50G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/td3-a7050cx3-32s-48x50G+8x100G.config.bcm b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/td3-a7050cx3-32s-48x50G+8x100G.config.bcm new file mode 100644 index 000000000000..2b7da96358d5 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/td3-a7050cx3-32s-48x50G+8x100G.config.bcm @@ -0,0 +1,545 @@ +arl_clean_timeout_usec=15000000 +asf_mem_profile=2 +bcm_num_cos=8 +bcm_stat_flags=1 +bcm_stat_jumbo=9236 +bcm_tunnel_term_compatible_mode=1 +cdma_timeout_usec=15000000 +core_clock_frequency=1525 +dma_desc_timeout_usec=15000000 +dpp_clock_ratio=2:3 +fpem_mem_entries=0 +higig2_hdr_mode=1 +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l2xmsg_mode=1 +l3_alpm_enable=2 +l3_max_ecmp_mode=1 +l3_mem_entries=16384 +max_vp_lags=0 +miim_intr_enable=0 +module_64ports=1 +multicast_l2_range=16383 +multicast_l3_range=0 +os=unix +oversubscribe_mode=1 +pbmp_xport_xe=0x7ffffffffffffffffffffffffffffffffe +PHY_AN_ALLOW_PLL_CHANGE=1 +phy_an_c37_130=2 +phy_an_c37_66=2 +phy_an_c73=1 +port_flex_enable=1 +port_init_autoneg=0 +port_phy_addr=0xff +robust_hash_disable_egress_vlan=1 +robust_hash_disable_mpls=1 +robust_hash_disable_vlan=1 +stable_size=0x5500000 +tdma_timeout_usec=15000000 +tslam_timeout_usec=15000000 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_rx_lane_map_physical{5.0}=0x3120 +phy_chain_rx_lane_map_physical{9.0}=0x3120 +phy_chain_rx_lane_map_physical{13.0}=0x3120 +phy_chain_rx_lane_map_physical{17.0}=0x1203 +phy_chain_rx_lane_map_physical{21.0}=0x3120 +phy_chain_rx_lane_map_physical{25.0}=0x3120 +phy_chain_rx_lane_map_physical{29.0}=0x3120 +phy_chain_rx_lane_map_physical{33.0}=0x1203 +phy_chain_rx_lane_map_physical{37.0}=0x3120 +phy_chain_rx_lane_map_physical{41.0}=0x3120 +phy_chain_rx_lane_map_physical{45.0}=0x3120 +phy_chain_rx_lane_map_physical{49.0}=0x1203 +phy_chain_rx_lane_map_physical{53.0}=0x3120 +phy_chain_rx_lane_map_physical{57.0}=0x3120 +phy_chain_rx_lane_map_physical{61.0}=0x3120 +phy_chain_rx_lane_map_physical{65.0}=0x2130 +phy_chain_rx_lane_map_physical{69.0}=0x0213 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_rx_lane_map_physical{77.0}=0x0213 +phy_chain_rx_lane_map_physical{81.0}=0x2130 +phy_chain_rx_lane_map_physical{85.0}=0x0213 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_rx_lane_map_physical{93.0}=0x0213 +phy_chain_rx_lane_map_physical{97.0}=0x2130 +phy_chain_rx_lane_map_physical{101.0}=0x0213 +phy_chain_rx_lane_map_physical{105.0}=0x2031 +phy_chain_rx_lane_map_physical{109.0}=0x0213 +phy_chain_rx_lane_map_physical{113.0}=0x2130 +phy_chain_rx_lane_map_physical{117.0}=0x0213 +phy_chain_rx_lane_map_physical{121.0}=0x2031 +phy_chain_rx_lane_map_physical{125.0}=0x0213 +phy_chain_rx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{56.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{81.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{109.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_tx_lane_map_physical{1.0}=0x3021 +phy_chain_tx_lane_map_physical{5.0}=0x1203 +phy_chain_tx_lane_map_physical{9.0}=0x0213 +phy_chain_tx_lane_map_physical{13.0}=0x0213 +phy_chain_tx_lane_map_physical{17.0}=0x2031 +phy_chain_tx_lane_map_physical{21.0}=0x0213 +phy_chain_tx_lane_map_physical{25.0}=0x2031 +phy_chain_tx_lane_map_physical{29.0}=0x1203 +phy_chain_tx_lane_map_physical{33.0}=0x2031 +phy_chain_tx_lane_map_physical{37.0}=0x0213 +phy_chain_tx_lane_map_physical{41.0}=0x2031 +phy_chain_tx_lane_map_physical{45.0}=0x1203 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_tx_lane_map_physical{53.0}=0x0213 +phy_chain_tx_lane_map_physical{57.0}=0x2031 +phy_chain_tx_lane_map_physical{61.0}=0x1203 +phy_chain_tx_lane_map_physical{65.0}=0x1302 +phy_chain_tx_lane_map_physical{69.0}=0x1302 +phy_chain_tx_lane_map_physical{73.0}=0x1302 +phy_chain_tx_lane_map_physical{77.0}=0x2130 +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_tx_lane_map_physical{85.0}=0x3120 +phy_chain_tx_lane_map_physical{89.0}=0x1302 +phy_chain_tx_lane_map_physical{93.0}=0x2130 +phy_chain_tx_lane_map_physical{97.0}=0x1302 +phy_chain_tx_lane_map_physical{101.0}=0x3120 +phy_chain_tx_lane_map_physical{105.0}=0x1302 +phy_chain_tx_lane_map_physical{109.0}=0x2130 +phy_chain_tx_lane_map_physical{113.0}=0x1302 +phy_chain_tx_lane_map_physical{117.0}=0x3120 +phy_chain_tx_lane_map_physical{121.0}=0x1302 +phy_chain_tx_lane_map_physical{125.0}=0x3120 +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_tx_polarity_flip_physical{1.0}=0x1 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x1 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x0 +phy_chain_tx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x0 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_tx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x1 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{111.0}=0x0 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x0 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_tx_polarity_flip_physical{129.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x0 +portmap_1=1:50:2 +portmap_3=3:50:2 +portmap_5=5:50:2 +portmap_7=7:50:2 +portmap_9=9:50:2 +portmap_11=11:50:2 +portmap_13=13:50:2 +portmap_15=15:50:2 +portmap_17=17:50:2 +portmap_19=19:50:2 +portmap_21=21:50:2 +portmap_23=23:50:2 +portmap_25=25:100 +portmap_29=29:100 +portmap_33=33:100 +portmap_37=37:100 +portmap_41=41:50:2 +portmap_43=43:50:2 +portmap_45=45:50:2 +portmap_47=47:50:2 +portmap_49=49:50:2 +portmap_51=51:50:2 +portmap_53=53:50:2 +portmap_55=55:50:2 +portmap_57=57:50:2 +portmap_59=59:50:2 +portmap_61=61:50:2 +portmap_63=63:50:2 +# skip 2 +portmap_67=65:50:2 +portmap_69=67:50:2 +portmap_71=69:50:2 +portmap_73=71:50:2 +portmap_75=73:50:2 +portmap_77=75:50:2 +portmap_79=77:50:2 +portmap_81=79:50:2 +portmap_83=81:50:2 +portmap_85=83:50:2 +portmap_87=85:50:2 +portmap_89=87:50:2 +portmap_91=89:100 +portmap_95=93:100 +portmap_99=97:100 +portmap_103=101:100 +portmap_107=105:50:2 +portmap_109=107:50:2 +portmap_111=109:50:2 +portmap_113=111:50:2 +portmap_115=113:50:2 +portmap_117=115:50:2 +portmap_119=117:50:2 +portmap_121=119:50:2 +portmap_123=121:50:2 +portmap_125=123:50:2 +portmap_127=125:50:2 +portmap_129=127:50:2 +serdes_core_rx_polarity_flip_physical{1}=0x8 +serdes_core_rx_polarity_flip_physical{5}=0x2 +serdes_core_rx_polarity_flip_physical{9}=0xc +serdes_core_rx_polarity_flip_physical{13}=0x3 +serdes_core_rx_polarity_flip_physical{17}=0x4 +serdes_core_rx_polarity_flip_physical{21}=0x3 +serdes_core_rx_polarity_flip_physical{25}=0x6 +serdes_core_rx_polarity_flip_physical{29}=0x3 +serdes_core_rx_polarity_flip_physical{33}=0x4 +serdes_core_rx_polarity_flip_physical{37}=0x3 +serdes_core_rx_polarity_flip_physical{41}=0xc +serdes_core_rx_polarity_flip_physical{45}=0x3 +serdes_core_rx_polarity_flip_physical{49}=0x4 +serdes_core_rx_polarity_flip_physical{53}=0x3 +serdes_core_rx_polarity_flip_physical{57}=0xc +serdes_core_rx_polarity_flip_physical{61}=0x3 +serdes_core_rx_polarity_flip_physical{65}=0xb +serdes_core_rx_polarity_flip_physical{69}=0xc +serdes_core_rx_polarity_flip_physical{73}=0x7 +serdes_core_rx_polarity_flip_physical{77}=0xc +serdes_core_rx_polarity_flip_physical{81}=0xb +serdes_core_rx_polarity_flip_physical{85}=0xc +serdes_core_rx_polarity_flip_physical{89}=0x7 +serdes_core_rx_polarity_flip_physical{93}=0xc +serdes_core_rx_polarity_flip_physical{97}=0xb +serdes_core_rx_polarity_flip_physical{101}=0x9 +serdes_core_rx_polarity_flip_physical{105}=0x7 +serdes_core_rx_polarity_flip_physical{109}=0xc +serdes_core_rx_polarity_flip_physical{113}=0xb +serdes_core_rx_polarity_flip_physical{117}=0xc +serdes_core_rx_polarity_flip_physical{121}=0x7 +serdes_core_rx_polarity_flip_physical{125}=0xc +serdes_core_rx_polarity_flip_physical{129}=0x0 +serdes_core_tx_polarity_flip_physical{1}=0x3 +serdes_core_tx_polarity_flip_physical{5}=0xb +serdes_core_tx_polarity_flip_physical{9}=0x3 +serdes_core_tx_polarity_flip_physical{13}=0xb +serdes_core_tx_polarity_flip_physical{17}=0x0 +serdes_core_tx_polarity_flip_physical{21}=0x3 +serdes_core_tx_polarity_flip_physical{25}=0x4 +serdes_core_tx_polarity_flip_physical{29}=0xc +serdes_core_tx_polarity_flip_physical{33}=0xf +serdes_core_tx_polarity_flip_physical{37}=0xc +serdes_core_tx_polarity_flip_physical{41}=0xe +serdes_core_tx_polarity_flip_physical{45}=0xc +serdes_core_tx_polarity_flip_physical{49}=0xf +serdes_core_tx_polarity_flip_physical{53}=0xc +serdes_core_tx_polarity_flip_physical{57}=0xe +serdes_core_tx_polarity_flip_physical{61}=0xc +serdes_core_tx_polarity_flip_physical{65}=0xf +serdes_core_tx_polarity_flip_physical{69}=0xe +serdes_core_tx_polarity_flip_physical{73}=0xe +serdes_core_tx_polarity_flip_physical{77}=0xc +serdes_core_tx_polarity_flip_physical{81}=0xf +serdes_core_tx_polarity_flip_physical{85}=0xc +serdes_core_tx_polarity_flip_physical{89}=0xe +serdes_core_tx_polarity_flip_physical{93}=0xc +serdes_core_tx_polarity_flip_physical{97}=0xf +serdes_core_tx_polarity_flip_physical{101}=0x6 +serdes_core_tx_polarity_flip_physical{105}=0x1 +serdes_core_tx_polarity_flip_physical{109}=0x3 +serdes_core_tx_polarity_flip_physical{113}=0x0 +serdes_core_tx_polarity_flip_physical{117}=0x3 +serdes_core_tx_polarity_flip_physical{121}=0x1 +serdes_core_tx_polarity_flip_physical{125}=0x3 +serdes_core_tx_polarity_flip_physical{129}=0x0 +serdes_preemphasis_1=0x45808 +serdes_preemphasis_3=0x45808 +serdes_preemphasis_5=0x45808 +serdes_preemphasis_7=0x45808 +serdes_preemphasis_9=0x45808 +serdes_preemphasis_11=0x45808 +serdes_preemphasis_13=0x45808 +serdes_preemphasis_15=0x45808 +serdes_preemphasis_17=0x45808 +serdes_preemphasis_19=0x45808 +serdes_preemphasis_21=0x45808 +serdes_preemphasis_23=0x45808 +serdes_preemphasis_25=0xd3e05 +serdes_preemphasis_29=0xd3e05 +serdes_preemphasis_33=0xb3403 +serdes_preemphasis_37=0x93603 +serdes_preemphasis_41=0x580c +serdes_preemphasis_43=0x580c +serdes_preemphasis_45=0x580c +serdes_preemphasis_47=0x580c +serdes_preemphasis_49=0x580c +serdes_preemphasis_51=0x580c +serdes_preemphasis_53=0x580c +serdes_preemphasis_55=0x580c +serdes_preemphasis_57=0x580c +serdes_preemphasis_59=0x580c +serdes_preemphasis_61=0x580c +serdes_preemphasis_63=0x580c +serdes_preemphasis_67=0x580c +serdes_preemphasis_69=0x580c +serdes_preemphasis_71=0x580c +serdes_preemphasis_73=0x580c +serdes_preemphasis_75=0x580c +serdes_preemphasis_77=0x580c +serdes_preemphasis_79=0x580c +serdes_preemphasis_81=0x580c +serdes_preemphasis_83=0x580c +serdes_preemphasis_85=0x580c +serdes_preemphasis_87=0x580c +serdes_preemphasis_89=0x580c +serdes_preemphasis_91=0x93603 +serdes_preemphasis_95=0xd3e05 +serdes_preemphasis_99=0xb3403 +serdes_preemphasis_103=0xd3e05 +serdes_preemphasis_107=0x85804 +serdes_preemphasis_109=0x85804 +serdes_preemphasis_111=0x85804 +serdes_preemphasis_113=0x85804 +serdes_preemphasis_115=0x85804 +serdes_preemphasis_117=0x85804 +serdes_preemphasis_119=0x85804 +serdes_preemphasis_121=0x85804 +serdes_preemphasis_123=0x85804 +serdes_preemphasis_125=0x85804 +serdes_preemphasis_127=0x85804 +serdes_preemphasis_129=0x85804 From 623d5c08c183966509153b0af52c860c745df89f Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Thu, 24 Sep 2020 01:08:55 -0700 Subject: [PATCH 1163/1427] [submodule]: update sonic-swss-common/sonic-sairedis (#5449) Update to pick up changes needed for VS gearbox - sonic-sairedis - meta/saiserialize.cpp - Fix typo at SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32 (#662) - syncd/scripts/gbsyncd_start.sh - Rename physyncd_startup.sh/physyncd_startup.py to gbsyncd_startup.sh/gbsyncd_startup.py (#661) - syncd/scripts/gbsyncd_startup.py - Rename physyncd_startup.sh/physyncd_startup.py to gbsyncd_startup.sh/gbsyncd_startup.py (#661) - sonic-swss-common - common/database_config.json - Add restapi DB (#386) - common/redispipeline.h - Throw proper exceptions when talking with Redis (#384) - common/redisreply.cpp - Throw proper exceptions when talking with Redis (#384) - common/redisreply.h - Throw proper exceptions when talking with Redis (#384) - common/schema.h - Add restapi DB (#386) - common/table.cpp - Add restapi DB (#386) Signed-off-by Syd Logan syd.logan@broadcom.com --- src/sonic-sairedis | 2 +- src/sonic-swss-common | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 6117cf5549e0..b6e5a140ff3c 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 6117cf5549e01cf188f3dfbd52fb447dfef9e5ad +Subproject commit b6e5a140ff3c25e31622edac038c41dc145fbf35 diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 2b9a00fffd90..3751c81071c2 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 2b9a00fffd90d0efe258e9e10fdd4e859ac190d5 +Subproject commit 3751c81071c204fa737e6b3e6ea29f7413330370 From 8c8773bee6d58abd0f8c05893064efff2bb5da76 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Thu, 24 Sep 2020 11:12:23 -0700 Subject: [PATCH 1164/1427] [sonic-snmpagent]: Advance submodule (#5454) - Implementation changes for CiscoBgp4MIB (#158) Signed-off-by: SuvarnaMeenakshi --- src/sonic-snmpagent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 5957460b9f1b..51b09a8afe83 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 5957460b9f1b5bc2657ded3a0bb4d84016c08da9 +Subproject commit 51b09a8afe833443aca0fecd86962c2338b38c0d From 39edac5b956b4d841718b2106411b3fda2d53298 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 24 Sep 2020 11:13:05 -0700 Subject: [PATCH 1165/1427] [Centec] Update critical_processes file to use new syntax~ (#5450) This file was added recently, but was created using the old syntax. Update to the new syntax. --- platform/centec-arm64/docker-syncd-centec/critical_processes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/centec-arm64/docker-syncd-centec/critical_processes b/platform/centec-arm64/docker-syncd-centec/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/centec-arm64/docker-syncd-centec/critical_processes +++ b/platform/centec-arm64/docker-syncd-centec/critical_processes @@ -1 +1 @@ -syncd +program:syncd From 224cc3953f00cd8c0fe13837244c6eceac372b8a Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Thu, 24 Sep 2020 11:32:16 -0700 Subject: [PATCH 1166/1427] [CLI][Multi ASIC] update get_all_namespace to return current namespace (#5446) --- .../sonic_py_common/multi_asic.py | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index d5925ea37de2..0b2b1d9da9b8 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -136,10 +136,38 @@ def get_asic_id_from_name(asic_name): raise ValueError('Unknown asic namespace name {}'.format(asic_name)) +def get_current_namespace(): + """ + This API returns the network namespace in which it is + invoked. In case of global namepace the API returns None + """ + + net_namespace = None + command = ["/bin/ip netns identify", str(os.getpid())] + proc = subprocess.Popen(command, + stdout=subprocess.PIPE, + shell=True, + stderr=subprocess.STDOUT) + try: + stdout, stderr = proc.communicate() + if proc.returncode != 0: + raise RuntimeError( + "Command {} failed with stderr {}".format(command, stderr) + ) + if stdout.rstrip('\n') != "": + net_namespace = stdout.rstrip('\n') + except OSError as e: + raise OSError("Error running command {}".format(command)) + + return net_namespace + + def get_namespaces_from_linux(): """ In a multi asic platform, each ASIC is in a Linux Namespace. - This method returns list of all the Namespace present on the device + This method returns the asic namespace under which this is invoked, + if namespace is None (global namespace) it returns list of all + the Namespace present on the device Note: It is preferable to use this function only when config_db is not available. When configdb is available use get_all_namespaces() @@ -147,6 +175,10 @@ def get_namespaces_from_linux(): Returns: List of the namespaces present in the system """ + current_ns = get_current_namespace() + if current_ns: + return [current_ns] + ns_list = [] for path in glob.glob(NAMESPACE_PATH_GLOB): ns = os.path.basename(path) From b43f1129b4a41347cbf15b8ee072d8bc9e0eb853 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Thu, 24 Sep 2020 14:57:42 -0700 Subject: [PATCH 1167/1427] [swss] Start Restore Neighbor After SWSS Config (#5451) SWSS config script restore ARP/FDB/Routes. Restore neighbor script uses config DB ARP information to restore ARP entries and so needs to be started after swssconfig exits. signed-off-by: Tamer Ahmed --- dockers/docker-orchagent/supervisord.conf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index f8c68337f0c0..521b221c5fc1 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -47,29 +47,29 @@ stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=portsyncd:running -[program:restore_neighbors] -command=/usr/bin/restore_neighbors.py +[program:swssconfig] +command=/usr/bin/swssconfig.sh priority=5 autostart=false -autorestart=false -startsecs=0 +autorestart=unexpected startretries=0 +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=orchagent:running -[program:swssconfig] -command=/usr/bin/swssconfig.sh +[program:restore_neighbors] +command=/usr/bin/restore_neighbors.py priority=6 autostart=false -autorestart=unexpected -startretries=0 +autorestart=false startsecs=0 +startretries=0 stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true -dependent_startup_wait_for=orchagent:running +dependent_startup_wait_for=swssconfig:exited [program:neighsyncd] command=/usr/bin/neighsyncd From 13cec4c48609ca389155b77c9351814d9d2203ef Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 25 Sep 2020 00:28:28 -0700 Subject: [PATCH 1168/1427] [Monit] Unmonitor the processes in containers which are disabled. (#5153) We want to let Monit to unmonitor the processes in containers which are disabled in `FEATURE` table such that Monit will not generate false alerting messages into the syslog. Signed-off-by: Yong Zhao --- .../base_image_files/monit_database | 4 +- .../docker-fpm-frr/base_image_files/monit_bgp | 24 ++++---- .../docker-lldp/base_image_files/monit_lldp | 12 ++-- .../base_image_files/monit_swss | 42 +++++++------- .../docker-sflow/base_image_files/monit_sflow | 4 +- .../docker-snmp/base_image_files/monit_snmp | 8 +-- .../base_image_files/monit_restapi | 4 +- .../base_image_files/monit_telemetry | 8 +-- .../docker-teamd/base_image_files/monit_teamd | 11 ++++ .../build_templates/sonic_debian_extension.j2 | 5 ++ files/image_config/monit/process_checker | 57 +++++++++++++++++++ .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 8 +-- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 8 +-- rules/docker-teamd.mk | 1 + 21 files changed, 149 insertions(+), 75 deletions(-) create mode 100644 dockers/docker-teamd/base_image_files/monit_teamd create mode 100755 files/image_config/monit/process_checker diff --git a/dockers/docker-database/base_image_files/monit_database b/dockers/docker-database/base_image_files/monit_database index c5508922864e..c1addd8a6f05 100644 --- a/dockers/docker-database/base_image_files/monit_database +++ b/dockers/docker-database/base_image_files/monit_database @@ -3,5 +3,5 @@ ## process list: ## redis_server ############################################################################### -check process redis_server matching "/usr/bin/redis-server" - if does not exist for 5 times within 5 cycles then alert +check program database|redis_server with path "/usr/bin/process_checker database /usr/bin/redis-server" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp index b9726c619582..46ddc629013e 100644 --- a/dockers/docker-fpm-frr/base_image_files/monit_bgp +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -8,20 +8,20 @@ ## bgpcfgd ## bgpmon ############################################################################### -check process zebra matching "/usr/lib/frr/zebra" - if does not exist for 5 times within 5 cycles then alert +check program bgp|zebra with path "/usr/bin/process_checker bgp /usr/lib/frr/zebra" + if status != 0 for 5 times within 5 cycles then alert -check process fpmsyncd matching "fpmsyncd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|fpmsyncd with path "/usr/bin/process_checker bgp fpmsyncd" + if status != 0 for 5 times within 5 cycles then alert -check process bgpd matching "/usr/lib/frr/bgpd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|bgpd with path "/usr/bin/process_checker bgp /usr/lib/frr/bgpd" + if status != 0 for 5 times within 5 cycles then alert -check process staticd matching "/usr/lib/frr/staticd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|staticd with path "/usr/bin/process_checker bgp /usr/lib/frr/staticd" + if status != 0 for 5 times within 5 cycles then alert -check process bgpcfgd matching "python /usr/local/bin/bgpcfgd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|bgpcfgd with path "/usr/bin/process_checker bgp /usr/bin/python /usr/local/bin/bgpcfgd" + if status != 0 for 5 times within 5 cycles then alert -check process bgpmon matching "python /usr/local/bin/bgpmon" - if does not exist for 5 times within 5 cycles then alert +check program bgp|bgpmon with path "/usr/bin/process_checker bgp python /usr/local/bin/bgpmon" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-lldp/base_image_files/monit_lldp b/dockers/docker-lldp/base_image_files/monit_lldp index 200c52c7d332..194fa14a3088 100644 --- a/dockers/docker-lldp/base_image_files/monit_lldp +++ b/dockers/docker-lldp/base_image_files/monit_lldp @@ -5,11 +5,11 @@ ## lldp-syncd ## lldpmgrd ############################################################################### -check process lldpd_monitor matching "lldpd: " - if does not exist for 5 times within 5 cycles then alert +check program lldp|lldpd_monitor with path "/usr/bin/process_checker lldp lldpd:" + if status != 0 for 5 times within 5 cycles then alert -check process lldp_syncd matching "python2 -m lldp_syncd" - if does not exist for 5 times within 5 cycles then alert +check program lldp|lldp_syncd with path "/usr/bin/process_checker lldp python2 -m lldp_syncd" + if status != 0 for 5 times within 5 cycles then alert -check process lldpmgrd matching "python /usr/bin/lldpmgrd" - if does not exist for 5 times within 5 cycles then alert +check program lldp|lldpmgrd with path "/usr/bin/process_checker lldp python /usr/bin/lldpmgrd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-orchagent/base_image_files/monit_swss b/dockers/docker-orchagent/base_image_files/monit_swss index 5928dbd4ddb0..f5f4389f3fe4 100644 --- a/dockers/docker-orchagent/base_image_files/monit_swss +++ b/dockers/docker-orchagent/base_image_files/monit_swss @@ -11,33 +11,33 @@ ## buffermgrd ## nbrmgrd ## vxlanmgrd -############################################################################### -check process orchagent matching "/usr/bin/orchagent -d /var/log/swss" - if does not exist for 5 times within 5 cycles then alert +############################################################################## +check program swss|orchagent with path "/usr/bin/process_checker swss /usr/bin/orchagent -d /var/log/swss" + if status != 0 for 5 times within 5 cycles then alert -check process portsyncd matching "/usr/bin/portsyncd" - if does not exist for 5 times within 5 cycles then alert +check program swss|portsyncd with path "/usr/bin/process_checker swss /usr/bin/portsyncd" + if status != 0 for 5 times within 5 cycles then alert -check process neighsyncd matching "/usr/bin/neighsyncd" - if does not exist for 5 times within 5 cycles then alert +check program swss|neighsyncd with path "/usr/bin/process_checker swss /usr/bin/neighsyncd" + if status != 0 for 5 times within 5 cycles then alert -check process vrfmgrd matching "/usr/bin/vrfmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|vrfmgrd with path "/usr/bin/process_checker swss /usr/bin/vrfmgrd" + if status != 0 for 5 times within 5 cycles then alert -check process vlanmgrd matching "/usr/bin/vlanmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|vlanmgrd with path "/usr/bin/process_checker swss /usr/bin/vlanmgrd" + if status != 0 for 5 times within 5 cycles then alert -check process intfmgrd matching "/usr/bin/intfmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|intfmgrd with path "/usr/bin/process_checker swss /usr/bin/intfmgrd" + if status != 0 for 5 times within 5 cycles then alert -check process portmgrd matching "/usr/bin/portmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|portmgrd with path "/usr/bin/process_checker swss /usr/bin/portmgrd" + if status != 0 for 5 times within 5 cycles then alert -check process buffermgrd matching "/usr/bin/buffermgrd -l" - if does not exist for 5 times within 5 cycles then alert +check program swss|buffermgrd with path "/usr/bin/process_checker swss /usr/bin/buffermgrd -l" + if status != 0 for 5 times within 5 cycles then alert -check process nbrmgrd matching "/usr/bin/nbrmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|nbrmgrd with path "/usr/bin/process_checker swss /usr/bin/nbrmgrd" + if status != 0 for 5 times within 5 cycles then alert -check process vxlanmgrd matching "/usr/bin/vxlanmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|vxlanmgrd with path "/usr/bin/process_checker swss /usr/bin/vxlanmgrd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-sflow/base_image_files/monit_sflow b/dockers/docker-sflow/base_image_files/monit_sflow index d041f81001ea..217f2e625835 100644 --- a/dockers/docker-sflow/base_image_files/monit_sflow +++ b/dockers/docker-sflow/base_image_files/monit_sflow @@ -3,5 +3,5 @@ ## process list: ## sflowmgrd ############################################################################### -check process sflowmgrd matching "/usr/bin/sflowmgrd" - if does not exist for 5 times within 5 cycles then alert +check program sflow|sflowmgrd with path "/usr/bin/process_checker sflow /usr/bin/sflowmgrd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-snmp/base_image_files/monit_snmp b/dockers/docker-snmp/base_image_files/monit_snmp index cfb1a2b66831..a943985abcef 100644 --- a/dockers/docker-snmp/base_image_files/monit_snmp +++ b/dockers/docker-snmp/base_image_files/monit_snmp @@ -4,8 +4,8 @@ ## snmpd ## snmpd_subagent ############################################################################### -check process snmpd matching "/usr/sbin/snmpd\s" - if does not exist for 5 times within 5 cycles then alert +check program snmp|snmpd with path "/usr/bin/process_checker snmp /usr/sbin/snmpd" + if status != 0 for 5 times within 5 cycles then alert -check process snmp_subagent matching "python3 -m sonic_ax_impl" - if does not exist for 5 times within 5 cycles then alert +check program snmp|snmp_subagent with path "/usr/bin/process_checker snmp python3.6 -m sonic_ax_impl" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-restapi/base_image_files/monit_restapi b/dockers/docker-sonic-restapi/base_image_files/monit_restapi index 2e90baf30d57..84e4366f4ac5 100644 --- a/dockers/docker-sonic-restapi/base_image_files/monit_restapi +++ b/dockers/docker-sonic-restapi/base_image_files/monit_restapi @@ -3,5 +3,5 @@ ## process list: ## restapi ############################################################################### -check process restapi matching "/usr/sbin/go-server-server" - if does not exist for 5 times within 5 cycles then alert +check program restapi|restapi with path "/usr/bin/process_checker restapi /usr/sbin/go-server-server" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry index a82c652f8179..7365ce51d1fd 100644 --- a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry +++ b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry @@ -4,8 +4,8 @@ ## telemetry ## dialout_client ############################################################################### -check process telemetry matching "/usr/sbin/telemetry" - if does not exist for 5 times within 5 cycles then alert +check program telemetry|telemetry with path "/usr/bin/process_checker telemetry /usr/sbin/telemetry" + if status != 0 for 5 times within 5 cycles then alert -check process dialout_client matching "/usr/sbin/dialout_client_cli" - if does not exist for 5 times within 5 cycles then alert +check program telemetry|dialout_client with path "/usr/bin/process_checker telemetry /usr/sbin/dialout_client_cli" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-teamd/base_image_files/monit_teamd b/dockers/docker-teamd/base_image_files/monit_teamd new file mode 100644 index 000000000000..256482aef2bf --- /dev/null +++ b/dockers/docker-teamd/base_image_files/monit_teamd @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for teamd container +## process list: +## teamsyncd +## teammgrd +############################################################################### +check program teamd|teamsyncd with path "/usr/bin/process_checker teamd /usr/bin/teamsyncd" + if status != 0 for 5 times within 5 cycles then alert + +check program teamd|teammgrd with path "/usr/bin/process_checker teamd /usr/bin/teammgrd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 2fbd6687d800..36b521af8215 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -116,6 +116,9 @@ sudo rm -rf $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY2_WHEEL_NAME # Install Python module for ipaddress sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install ipaddress +# Install Python module for psutil +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install psutil + # Install SwSS SDK Python 3 package # Note: the scripts will be overwritten by corresponding Python 2 package if [ -e {{swsssdk_py3_wheel_path}} ]; then @@ -239,6 +242,8 @@ sudo cp $IMAGE_CONFIGS/monit/monitrc $FILESYSTEM_ROOT/etc/monit/ sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/monitrc sudo cp $IMAGE_CONFIGS/monit/conf.d/* $FILESYSTEM_ROOT/etc/monit/conf.d/ sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/conf.d/* +sudo cp $IMAGE_CONFIGS/monit/process_checker $FILESYSTEM_ROOT/usr/bin/ +sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/process_checker # Copy crontabs sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ diff --git a/files/image_config/monit/process_checker b/files/image_config/monit/process_checker new file mode 100755 index 000000000000..ba48e37729aa --- /dev/null +++ b/files/image_config/monit/process_checker @@ -0,0 +1,57 @@ +#!/usr/bin/python +import argparse +import sys +import syslog + +import psutil +import swsssdk + + +def check_process_existence(container_name, process_cmdline): + """ + @summary: Check whether the process in the specified container is running or not and + an alerting message will written into syslog if it failed to run. + """ + config_db = swsssdk.ConfigDBConnector() + config_db.connect() + feature_table = config_db.get_table("FEATURE") + + if container_name in feature_table.keys(): + # We look into the 'FEATURE' table to verify whether the container is disabled or not. + # If the container is diabled, we exit. + if ("state" in feature_table[container_name].keys() + and feature_table[container_name]["state"] == "disabled"): + sys.exit(0) + else: + # We leveraged the psutil library to help us check whether the process is running or not. + # If the process entity is found in process tree and it is also in the 'running' or 'sleeping' + # state, then it will be marked as 'running'. + is_running = False + for process in psutil.process_iter(["cmdline", "status"]): + if ((' '.join(process.cmdline())).startswith(process_cmdline) and process.status() in ["running", "sleeping"]): + is_running = True + break + + if not is_running: + # If this script is run by Monit, then the following output will be appended to + # Monit's syslog message. + print("'{}' is not running.".format(process_cmdline)) + sys.exit(1) + else: + syslog.syslog(syslog.LOG_ERR, "container '{}' is not included in SONiC image or the given container name is invalid!" + .format(container_name)) + + +def main(): + parser = argparse.ArgumentParser(description="Check whether the process in the specified \ + container is running and an alerting message will be written into syslog if it \ + failed to run.", usage="/usr/bin/process_checker ") + parser.add_argument("container_name", help="container name") + parser.add_argument("process_cmdline", nargs=argparse.REMAINDER, help="process command line") + args = parser.parse_args() + + check_process_existence(args.container_name, ' '.join(args.process_cmdline)) + + +if __name__ == '__main__': + main() diff --git a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd +++ b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd index 81c0b6ef6bc6..119548770096 100644 --- a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd @@ -4,8 +4,8 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert -check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" - if does not exist for 5 times within 5 cycles then alert +check program syncd|dsserve with path "/usr/bin/process_checker syncd /usr/bin/dsserve /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd +++ b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd +++ b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd +++ b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd index 81c0b6ef6bc6..119548770096 100644 --- a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd +++ b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd @@ -4,8 +4,8 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert -check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" - if does not exist for 5 times within 5 cycles then alert +check program syncd|dsserve with path "/usr/bin/process_checker syncd /usr/bin/dsserve /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk index c0fe6bfb6bb1..5442d5bf6b3f 100644 --- a/rules/docker-teamd.mk +++ b/rules/docker-teamd.mk @@ -27,4 +27,5 @@ $(DOCKER_TEAMD)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TEAMD)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_TEAMD)_BASE_IMAGE_FILES += teamdctl:/usr/bin/teamdctl +$(DOCKER_TEAMD)_BASE_IMAGE_FILES += monit_teamd:/etc/monit/conf.d $(DOCKER_TEAMD)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From 584e2223dc0b3b7986ad448d34ca9e6dc3f8e4ca Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Fri, 25 Sep 2020 20:19:18 +0800 Subject: [PATCH 1169/1427] Fix exception when attempting to write a datetime to db (#5467) redis-py 3.0 used in master branch only accepts user data as bytes, strings or numbers (ints, longs and floats). Attempting to specify a key or a value as any other type will raise a DataError exception. This PR address the issue bt converting datetime to str --- files/image_config/procdockerstatsd/procdockerstatsd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd index 00501f810072..b7dd1705db4c 100755 --- a/files/image_config/procdockerstatsd/procdockerstatsd +++ b/files/image_config/procdockerstatsd/procdockerstatsd @@ -184,9 +184,9 @@ class ProcDockerStats(daemon_base.DaemonBase): self.update_dockerstats_command() datetimeobj = datetime.now() # Adding key to store latest update time. - self.update_state_db('DOCKER_STATS|LastUpdateTime', 'lastupdate', datetimeobj) + self.update_state_db('DOCKER_STATS|LastUpdateTime', 'lastupdate', str(datetimeobj)) self.update_processstats_command() - self.update_state_db('PROCESS_STATS|LastUpdateTime', 'lastupdate', datetimeobj) + self.update_state_db('PROCESS_STATS|LastUpdateTime', 'lastupdate', str(datetimeobj)) # Data need to be updated every 2 mins. hence adding delay of 120 seconds time.sleep(120) From 0311a4a03799348963e71c08e0f3aca95aeeb17c Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Fri, 25 Sep 2020 08:32:44 -0700 Subject: [PATCH 1170/1427] Add gearbox phy device files and a new physyncd docker to support VS gearbox phy feature (#4851) * buildimage: Add gearbox phy device files and a new physyncd docker to support VS gearbox phy feature * scripts and configuration needed to support a second syncd docker (physyncd) * physyncd supports gearbox device and phy SAI APIs and runs multiple instances of syncd, one per phy in the device * support for VS target (sonic-sairedis vslib has been extended to support a virtual BCM81724 gearbox PHY). HLD is located at https://github.com/Azure/SONiC/blob/b817a12fd89520d3fd26bbc5897487928e7f6de7/doc/gearbox/gearbox_mgr_design.md **- Why I did it** This work is part of the gearbox phy joint effort between Microsoft and Broadcom, and is based on multi-switch support in sonic-sairedis. **- How I did it** Overall feature was implemented across several projects. The collective pull requests (some in late stages of review at this point): https://github.com/Azure/sonic-utilities/pull/931 - CLI (merged) https://github.com/Azure/sonic-swss-common/pull/347 - Minor changes (merged) https://github.com/Azure/sonic-swss/pull/1321 - gearsyncd, config parsers, changes to orchargent to create gearbox phy on supported systems https://github.com/Azure/sonic-sairedis/pull/624 - physyncd, virtual BCM81724 gearbox phy added to vslib **- How to verify it** In a vslib build: root@sonic:/home/admin# show gearbox interfaces status PHY Id Interface MAC Lanes MAC Lane Speed PHY Lanes PHY Lane Speed Line Lanes Line Lane Speed Oper Admin -------- ----------- --------------- ---------------- --------------- ---------------- ------------ ----------------- ------ ------- 1 Ethernet48 121,122,123,124 25G 200,201,202,203 25G 204,205 50G down down 1 Ethernet49 125,126,127,128 25G 206,207,208,209 25G 210,211 50G down down 1 Ethernet50 69,70,71,72 25G 212,213,214,215 25G 216 100G down down In addition, docker ps | grep phy should show a physyncd docker running. Signed-off-by: syd.logan@broadcom.com --- device/virtual/x86_64-kvm_x86_64-r0/README.md | 88 +++ .../brcm_gearbox_vs/buffers.json.j2 | 3 + .../brcm_gearbox_vs/buffers_defaults_def.j2 | 45 ++ .../brcm_gearbox_vs/buffers_defaults_t0.j2 | 45 ++ .../brcm_gearbox_vs/buffers_defaults_t1.j2 | 45 ++ .../brcm_gearbox_vs/context_config.json | 32 + .../brcm_gearbox_vs/gearbox_config.json | 38 ++ .../brcm_gearbox_vs/lanemap.ini | 32 + .../brcm_gearbox_vs/pg_profile_lookup.ini | 17 + .../brcm_gearbox_vs/phy1_config_1.json | 168 +++++ .../brcm_gearbox_vs/port_config.ini | 33 + .../brcm_gearbox_vs/qos.json.j2 | 1 + .../brcm_gearbox_vs/sai.profile | 5 + .../td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../docker-database/database_config.json.j2 | 15 + dockers/docker-orchagent/supervisord.conf | 12 + files/build_templates/gbsyncd.service.j2 | 18 + .../build_templates/sonic_debian_extension.j2 | 4 +- files/scripts/gbsyncd.sh | 45 ++ files/scripts/syncd.sh | 122 +--- files/scripts/syncd_common.sh | 141 ++++ platform/template/docker-gbsyncd-base.mk | 30 + platform/vs/docker-gbsyncd-vs.dep | 11 + platform/vs/docker-gbsyncd-vs.mk | 14 + platform/vs/docker-gbsyncd-vs/Dockerfile.j2 | 34 + .../vs/docker-gbsyncd-vs/critical_processes | 1 + platform/vs/docker-gbsyncd-vs/start.sh | 21 + .../vs/docker-gbsyncd-vs/supervisord.conf | 48 ++ .../vs/docker-sonic-vs/database_config.json | 17 +- platform/vs/gbsyncd-vs.mk | 14 + platform/vs/rules.mk | 1 + src/sonic-device-data/Makefile | 3 + src/sonic-device-data/src/pai.vs_profile | 7 + 33 files changed, 1639 insertions(+), 117 deletions(-) create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/README.md create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/context_config.json create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/gearbox_config.json create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/phy1_config_1.json create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/td2-s6000-32x40G.config.bcm create mode 100644 files/build_templates/gbsyncd.service.j2 create mode 100755 files/scripts/gbsyncd.sh create mode 100755 files/scripts/syncd_common.sh create mode 100644 platform/template/docker-gbsyncd-base.mk create mode 100644 platform/vs/docker-gbsyncd-vs.dep create mode 100644 platform/vs/docker-gbsyncd-vs.mk create mode 100644 platform/vs/docker-gbsyncd-vs/Dockerfile.j2 create mode 100644 platform/vs/docker-gbsyncd-vs/critical_processes create mode 100755 platform/vs/docker-gbsyncd-vs/start.sh create mode 100644 platform/vs/docker-gbsyncd-vs/supervisord.conf create mode 100644 platform/vs/gbsyncd-vs.mk create mode 100644 src/sonic-device-data/src/pai.vs_profile diff --git a/device/virtual/x86_64-kvm_x86_64-r0/README.md b/device/virtual/x86_64-kvm_x86_64-r0/README.md new file mode 100644 index 000000000000..0347432d67b4 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/README.md @@ -0,0 +1,88 @@ +# Changing the virtual device + +You can control the hw sku and default factory configuration for the VS image +by modifying the content of the file default_sku in this directory. + +The format of default_sku is a single line: + +``` + +``` + +## Allowable values for hw_key + +| hw_key | Device | +| ------ | ------ | +| Force10-S6000 | Dell Force10 S6000| +| brcm_gearbox_vs | Similar to Force10-S6000, but implements a virtual BRCM81724 Gearbox Phy | + +## Allowable values for default_preset + +These include "t1", "l2", and "empty". See the file +sonic-buildimage/src/sonic-config-engine/config_samples.py for details on how +each default_preset value is interpreted. + +# Changing the hwsku of an existing VS switch + +To change the default hwsku for a VS image that has already been built and installed, follow these steps: + +- Edit /usr/share/sonic/device/x86_64-kvm_x86_64-r0/default_sku. For details, see the section below (Device Specific Documentation) +- Edit /etc/sonic/config_db.json, and change the "hwsku" key in DEVICE_METADATA:localhost to match the hw_key used in default_sku. Example: + + "DEVICE_METADATA": { + "localhost": { + ... + "hwsku": "brcm_gearbox_vs", + ... + } + }, + ... +- Reboot the switch +- Use "show platform summary" to verify, and follow any steps specific to the platform, as needed, such as those described below for the brcm_gearbox_vs hwsku. + +# Device Specific Documentation + +For general info on building, see https://github.com/Azure/sonic-buildimage/blob/master/README.md + +## Force-10-S6000 + +This is the default VS for SONiC. To enable, set contents of default_sku to: + +``` +Force10-S6000 t1 +``` + +To build: + +``` +make init +make configure PLATFORM=vs +make target/sonic-vs.img.gz +``` + +## brcm_gearbox_vs + +This sku simulates a device with a Broadcom BRCM81724 gearbox PHY. To enable, +set default_sku to: + + +``` +brcm_gearbox_vs t1 +``` + +To build (same as Force-10-S6000): + +``` +make init +make configure PLATFORM=vs +make target/sonic-vs.img.gz +``` + +To verify, install and bring up SONiC. There will be a new gbsyncd docker +which is designed to respond to configuration directed towards the gearbox phy +"switch". swss will create that gearbox switch on startup after detecting the +gearbox is present (this is done by a short lived gearsyncd that runs in the +swss docker). + +The commands "show gearbox interfaces status" and "show gearbox phys status" can be +used to verify the virtual gearbox phy has been created. See https://github.com/Azure/sonic-utilities/blob/master/doc/Command-Reference.md#gearbox for details. diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/context_config.json new file mode 100644 index 000000000000..9f9f80ba0d36 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/context_config.json @@ -0,0 +1,32 @@ +{ + "CONTEXTS": [ + { + "guid" : 0, + "name" : "sw0", + "dbAsic" : "ASIC_DB", + "dbCounters" : "COUNTERS_DB", + "dbFlex": "FLEX_COUNTER_DB", + "dbState" : "STATE_DB", + "switches": [ + { + "index" : 0, + "hwinfo" : "" + } + ] + }, + { + "guid" : 1, + "name" : "phy1", + "dbAsic" : "GB_ASIC_DB", + "dbCounters" : "GB_COUNTERS_DB", + "dbFlex": "GB_FLEX_COUNTER_DB", + "dbState" : "STATE_DB", + "switches": [ + { + "index" : 1, + "hwinfo" : "" + } + ] + } + ] +} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/gearbox_config.json b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/gearbox_config.json new file mode 100644 index 000000000000..2de95c4d806d --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/gearbox_config.json @@ -0,0 +1,38 @@ +{ + "phys": [ + { + "phy_id": 1, + "name": "sesto-1", + "address": "0x1000", + "lib_name": "libsai_phy_sesto-1.so", + "firmware_path": "/tmp/phy-sesto-1.bin", + "config_file": "/usr/share/sonic/hwsku/phy1_config_1.json", + "sai_init_config_file": "/usr/share/sonic/hwsku/sesto-1.bcm", + "phy_access": "mdio", + "bus_id": 0 + } + ], + "interfaces": [ + { + "name": "Ethernet0", + "index": 0, + "phy_id" : 1, + "system_lanes": [200,201], + "line_lanes": [206] + }, + { + "name": "Ethernet4", + "index": 1, + "phy_id" : 1, + "system_lanes": [202,203], + "line_lanes": [207] + }, + { + "name": "Ethernet8", + "index": 2, + "phy_id" : 1, + "system_lanes": [204,205], + "line_lanes": [208] + } + ] +} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/phy1_config_1.json b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/phy1_config_1.json new file mode 100644 index 000000000000..1b81394e9936 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/phy1_config_1.json @@ -0,0 +1,168 @@ +{ + "lanes": [ + { + "index": 200, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0200" + }, + { + "index": 201, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0201" + }, + { + "index": 202, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0202" + }, + { + "index": 203, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0203" + }, + { + "index": 204, + "local_lane_id": 0, + "system_side": false, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 200, + "mdio_addr": "0x0204" + }, + { + "index": 205, + "local_lane_id": 0, + "system_side": false, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 202, + "mdio_addr": "0x0205" + }, + { + "index": 206, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0206" + }, + { + "index": 207, + "local_lane_id": 0, + "system_side": false, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0207" + }, + { + "index": 208, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0208" + } + ], + "ports": [ + { + "index": 0, + "mdio_addr": "0x2000", + "system_speed": 20000, + "system_fec": "none", + "system_auto_neg": true, + "system_loopback": "none", + "system_training": false, + "line_speed": 40000, + "line_fec": "none", + "line_auto_neg": true, + "line_media_type": "fiber", + "line_intf_type": "none", + "line_loopback": "none", + "line_training": false, + "line_adver_speed": [], + "line_adver_fec": [], + "line_adver_auto_neg": false, + "line_adver_asym_pause": false, + "line_adver_media_type": "fiber" + }, + { + "index": 1, + "mdio_addr": "0x3000", + "system_speed": 20000, + "system_fec": "none", + "system_auto_neg": true, + "system_loopback": "none", + "system_training": false, + "line_speed": 40000, + "line_fec": "none", + "line_auto_neg": true, + "line_media_type": "fiber", + "line_intf_type": "none", + "line_loopback": "none", + "line_training": false, + "line_adver_speed": [], + "line_adver_fec": [], + "line_adver_auto_neg": false, + "line_adver_asym_pause": false, + "line_adver_media_type": "fiber" + }, + { + "index": 2, + "mdio_addr": "0x4000", + "system_speed": 20000, + "system_fec": "none", + "system_auto_neg": true, + "system_loopback": "none", + "system_training": false, + "line_speed": 40000, + "line_fec": "none", + "line_auto_neg": true, + "line_media_type": "fiber", + "line_intf_type": "none", + "line_loopback": "none", + "line_training": false, + "line_adver_speed": [], + "line_adver_fec": [], + "line_adver_auto_neg": false, + "line_adver_asym_pause": false, + "line_adver_media_type": "fiber" + } + ] +} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/sai.profile new file mode 100644 index 000000000000..bfc466f27e54 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/sai.profile @@ -0,0 +1,5 @@ +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/dockers/docker-database/database_config.json.j2 b/dockers/docker-database/database_config.json.j2 index 242b065eb398..a24252ed810d 100644 --- a/dockers/docker-database/database_config.json.j2 +++ b/dockers/docker-database/database_config.json.j2 @@ -57,6 +57,21 @@ "id" : 8, "separator": "|", "instance" : "redis" + }, + "GB_ASIC_DB" : { + "id" : 9, + "separator": "|", + "instance" : "redis" + }, + "GB_COUNTERS_DB" : { + "id" : 10, + "separator": "|", + "instance" : "redis" + }, + "GB_FLEX_COUNTER_DB" : { + "id" : 11, + "separator": "|", + "instance" : "redis" } }, "VERSION" : "1.0" diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 521b221c5fc1..780a4d790464 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -27,6 +27,18 @@ stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true +[program:gearsyncd] +command=/usr/bin/gearsyncd -p /usr/share/sonic/hwsku/gearbox_config.json +priority=3 +autostart=false +autorestart=false +startsecs=0 +startretries=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + [program:portsyncd] command=/usr/bin/portsyncd priority=3 diff --git a/files/build_templates/gbsyncd.service.j2 b/files/build_templates/gbsyncd.service.j2 new file mode 100644 index 000000000000..e1080ae7d526 --- /dev/null +++ b/files/build_templates/gbsyncd.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=gbsyncd service +Requires=database.service updategraph.service +ConditionPathExists=!/usr/share/sonic/hwsku/gearbox_config.json +After=database.service updategraph.service +After=interfaces-config.service +After=swss.service +Before=ntp-config.service + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/gbsyncd.sh start +ExecStart=/usr/local/bin/gbsyncd.sh wait +ExecStop=/usr/local/bin/gbsyncd.sh stop + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 36b521af8215..eac1e2ba352a 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -1,6 +1,6 @@ #!/bin/bash ## This script is to automate loading of vendor specific docker images -## and instalation of configuration files and vendor specific packages +## and installation of configuration files and vendor specific packages ## to debian file system. ## ## USAGE: @@ -535,6 +535,8 @@ sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys # Copy service scripts (swss, syncd, bgp, radv) sudo LANG=C cp $SCRIPTS_DIR/swss.sh $FILESYSTEM_ROOT/usr/local/bin/swss.sh sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh +sudo LANG=C cp $SCRIPTS_DIR/syncd_common.sh $FILESYSTEM_ROOT/usr/local/bin/syncd_common.sh +sudo LANG=C cp $SCRIPTS_DIR/gbsyncd.sh $FILESYSTEM_ROOT/usr/local/bin/gbsyncd.sh sudo LANG=C cp $SCRIPTS_DIR/bgp.sh $FILESYSTEM_ROOT/usr/local/bin/bgp.sh sudo LANG=C cp $SCRIPTS_DIR/radv.sh $FILESYSTEM_ROOT/usr/local/bin/radv.sh diff --git a/files/scripts/gbsyncd.sh b/files/scripts/gbsyncd.sh new file mode 100755 index 000000000000..996fbf8cdf31 --- /dev/null +++ b/files/scripts/gbsyncd.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +. /usr/local/bin/syncd_common.sh + +function startplatform() { + : +} + +function waitplatform() { + : +} + +function stopplatform1() { + : +} + +function stopplatform2() { + : +} + +OP=$1 +DEV=$2 + +SERVICE="gbsyncd" +PEER="swss" +DEBUGLOG="/tmp/swss-gbsyncd-debug$DEV.log" +LOCKFILE="/tmp/swss-gbsyncd-lock$DEV" +NAMESPACE_PREFIX="asic" +if [ "$DEV" ]; then + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" +else + NET_NS="" + SONIC_DB_CLI="sonic-db-cli" +fi + +case "$1" in + start|wait|stop) + $1 + ;; + *) + echo "Usage: $0 {start|wait|stop}" + exit 1 + ;; +esac diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 87a39b71ae7b..22fa992b8e80 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -1,96 +1,8 @@ #!/bin/bash +. /usr/local/bin/syncd_common.sh -function debug() -{ - /usr/bin/logger $1 - /bin/echo `date` "- $1" >> ${DEBUGLOG} -} - -function lock_service_state_change() -{ - debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" - - exec {LOCKFD}>${LOCKFILE} - /usr/bin/flock -x ${LOCKFD} - trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" -} - -function unlock_service_state_change() -{ - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" - /usr/bin/flock -u ${LOCKFD} -} - -function check_warm_boot() -{ - SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` - # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. - if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then - WARM_BOOT="true" - else - WARM_BOOT="false" - fi -} - -function wait_for_database_service() -{ - # Wait for redis server start before database clean - until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do - sleep 1; - done - - # Wait for configDB initialization - until [[ $($SONIC_DB_CLI CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; - do sleep 1; - done -} - -function getBootType() -{ - # same code snippet in files/build_templates/docker_image_ctl.j2 - case "$(cat /proc/cmdline)" in - *SONIC_BOOT_TYPE=warm*) - TYPE='warm' - ;; - *SONIC_BOOT_TYPE=fastfast*) - TYPE='fastfast' - ;; - *SONIC_BOOT_TYPE=fast*|*fast-reboot*) - # check that the key exists - if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then - TYPE='fast' - else - TYPE='cold' - fi - ;; - *) - TYPE='cold' - esac - echo "${TYPE}" -} - -start() { - debug "Starting ${SERVICE}$DEV service..." - - lock_service_state_change - - mkdir -p /host/warmboot - - wait_for_database_service - check_warm_boot - - debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." - - if [[ x"$WARM_BOOT" == x"true" ]]; then - # Leave a mark for syncd scripts running inside docker. - touch /host/warmboot/warm-starting - else - rm -f /host/warmboot/warm-starting - fi +function startplatform() { # platform specific tasks @@ -119,35 +31,18 @@ start() { /etc/init.d/xpnet.sh start fi fi - - # start service docker - /usr/bin/${SERVICE}.sh start $DEV - debug "Started ${SERVICE} service..." - - unlock_service_state_change } -wait() { +function waitplatform() { + if [[ x"$sonic_asic_platform" == x"mellanox" ]]; then debug "Starting pmon service..." /bin/systemctl start pmon debug "Started pmon service" fi - /usr/bin/${SERVICE}.sh wait $DEV } -stop() { - debug "Stopping ${SERVICE}$DEV service..." - - lock_service_state_change - check_warm_boot - debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." - - if [[ x"$WARM_BOOT" == x"true" ]]; then - TYPE=warm - else - TYPE=cold - fi +function stopplatform1() { if [[ x$sonic_asic_platform == x"mellanox" ]] && [[ x$TYPE == x"cold" ]]; then debug "Stopping pmon service ahead of syncd..." @@ -177,10 +72,9 @@ stop() { /usr/bin/docker exec -i syncd$DEV /bin/sync debug "Finished ${TYPE} shutdown syncd process ..." fi +} - /usr/bin/${SERVICE}.sh stop $DEV - debug "Stopped ${SERVICE}$DEV service..." - +function stopplatform2() { # platform specific tasks if [[ x"$WARM_BOOT" != x"true" ]]; then @@ -192,8 +86,6 @@ stop() { /etc/init.d/xpnet.sh start fi fi - - unlock_service_state_change } OP=$1 diff --git a/files/scripts/syncd_common.sh b/files/scripts/syncd_common.sh new file mode 100755 index 000000000000..0e9fc8ac2d7a --- /dev/null +++ b/files/scripts/syncd_common.sh @@ -0,0 +1,141 @@ +#!/bin/bash + +# +# common functions used by "syncd" scipts (syncd.sh, gbsyncd.sh, etc..) +# scripts using this must provide implementations of the following functions: +# +# startplatform +# waitplatform +# stopplatform1 and stopplatform2 +# +# For examples of these, see gbsyncd.sh and syncd.sh. +# + +function debug() +{ + /usr/bin/logger $1 + /bin/echo `date` "- $1" >> ${DEBUGLOG} +} + +function lock_service_state_change() +{ + debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" + + exec {LOCKFD}>${LOCKFILE} + /usr/bin/flock -x ${LOCKFD} + trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 + + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" +} + +function unlock_service_state_change() +{ + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" + /usr/bin/flock -u ${LOCKFD} +} + +function check_warm_boot() +{ + SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. + if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then + WARM_BOOT="true" + else + WARM_BOOT="false" + fi +} + +function wait_for_database_service() +{ + # Wait for redis server start before database clean + until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do + sleep 1; + done + + # Wait for configDB initialization + until [[ $($SONIC_DB_CLI CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + do sleep 1; + done +} + +function getBootType() +{ + # same code snippet in files/build_templates/docker_image_ctl.j2 + case "$(cat /proc/cmdline)" in + *SONIC_BOOT_TYPE=warm*) + TYPE='warm' + ;; + *SONIC_BOOT_TYPE=fastfast*) + TYPE='fastfast' + ;; + *SONIC_BOOT_TYPE=fast*|*fast-reboot*) + # check that the key exists + if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + TYPE='fast' + else + TYPE='cold' + fi + ;; + *) + TYPE='cold' + esac + echo "${TYPE}" +} + +start() { + debug "Starting ${SERVICE}$DEV service..." + + lock_service_state_change + + mkdir -p /host/warmboot + + wait_for_database_service + check_warm_boot + + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + + if [[ x"$WARM_BOOT" == x"true" ]]; then + # Leave a mark for syncd scripts running inside docker. + touch /host/warmboot/warm-starting + else + rm -f /host/warmboot/warm-starting + fi + + startplatform + + # start service docker + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE} service..." + + unlock_service_state_change +} + +wait() { + waitplatform + + /usr/bin/${SERVICE}.sh wait $DEV +} + +stop() { + debug "Stopping ${SERVICE}$DEV service..." + + lock_service_state_change + check_warm_boot + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + + if [[ x"$WARM_BOOT" == x"true" ]]; then + TYPE=warm + else + TYPE=cold + fi + + stopplatform1 + + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." + + stopplatform2 + + unlock_service_state_change +} diff --git a/platform/template/docker-gbsyncd-base.mk b/platform/template/docker-gbsyncd-base.mk new file mode 100644 index 000000000000..aa4f574141b2 --- /dev/null +++ b/platform/template/docker-gbsyncd-base.mk @@ -0,0 +1,30 @@ +# docker image for gbsyncd + + +DOCKER_GBSYNCD_BASE_STEM = docker-gbsyncd-$(DOCKER_GBSYNCD_PLATFORM_CODE) +DOCKER_GBSYNCD_BASE = $(DOCKER_GBSYNCD_BASE_STEM).gz +DOCKER_GBSYNCD_BASE_DBG = $(DOCKER_GBSYNCD_BASE_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_GBSYNCD_BASE)_PATH = $(PLATFORM_PATH)/docker-gbsyncd-$(DOCKER_GBSYNCD_PLATFORM_CODE) + +$(DOCKER_GBSYNCD_BASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) + +$(DOCKER_GBSYNCD_BASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) + +$(DOCKER_GBSYNCD_BASE)_DBG_DEPENDS += $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) + +$(DOCKER_GBSYNCD_BASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) + +SONIC_DOCKER_IMAGES += $(DOCKER_GBSYNCD_BASE) +SONIC_BUSTER_DOCKERS += $(DOCKER_GBSYNCD_BASE) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_GBSYNCD_BASE) + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_GBSYNCD_BASE_DBG) +SONIC_BUSTER_DBG_DOCKERS += $(DOCKER_GBSYNCD_BASE_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_GBSYNCD_BASE_DBG) + +$(DOCKER_GBSYNCD_BASE)_CONTAINER_NAME = gbsyncd +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += --net=host --privileged -t +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro + diff --git a/platform/vs/docker-gbsyncd-vs.dep b/platform/vs/docker-gbsyncd-vs.dep new file mode 100644 index 000000000000..a3db18642abf --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs.dep @@ -0,0 +1,11 @@ +#DPKG FRK +DPATH := $($(DOCKER_GBSYNCD_BASE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/vs/docker-gbsyncd-vs.mk platform/vs/docker-gbsyncd-vs.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_GBSYNCD_BASE)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_GBSYNCD_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_GBSYNCD_BASE)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_GBSYNCD_BASE),$(DOCKER_GBSYNCD_BASE_DBG))) diff --git a/platform/vs/docker-gbsyncd-vs.mk b/platform/vs/docker-gbsyncd-vs.mk new file mode 100644 index 000000000000..2013132d6281 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs.mk @@ -0,0 +1,14 @@ +# docker image for vs gbsyncd + +DOCKER_GBSYNCD_PLATFORM_CODE = vs +include $(PLATFORM_PATH)/../template/docker-gbsyncd-base.mk + +$(DOCKER_GBSYNCD_BASE)_DEPENDS += $(SYNCD_VS) + +$(DOCKER_GBSYNCD_BASE)_DBG_DEPENDS += $(SYNCD_VS_DBG) \ + $(LIBSWSSCOMMON_DBG) \ + $(LIBSAIMETADATA_DBG) \ + $(LIBSAIREDIS_DBG) \ + $(LIBSAIVS_DBG) + +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 new file mode 100644 index 000000000000..316466dfb4ea --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 @@ -0,0 +1,34 @@ +FROM docker-config-engine-buster + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +RUN apt-get install -f -y iproute2=4.20.0-2 libcap2-bin=1:2.25-2 + +COPY \ +{% for deb in docker_gbsyncd_vs_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN dpkg -i \ +{% for deb in docker_gbsyncd_vs_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor %} + +COPY ["start.sh", "/usr/bin/"] + +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] + +## Clean up +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /debs + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/platform/vs/docker-gbsyncd-vs/critical_processes b/platform/vs/docker-gbsyncd-vs/critical_processes new file mode 100644 index 000000000000..bdd6903c5690 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/critical_processes @@ -0,0 +1 @@ +program:syncd diff --git a/platform/vs/docker-gbsyncd-vs/start.sh b/platform/vs/docker-gbsyncd-vs/start.sh new file mode 100755 index 000000000000..e59a2322bbf8 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/start.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +HWSKU_DIR=/usr/share/sonic/hwsku + +mkdir -p /etc/sai.d/ + +# Create/Copy the pai.profile to /etc/sai.d/pai.profile +if [ -f $HWSKU_DIR/pai.profile.j2 ]; then + sonic-cfggen -d -t $HWSKU_DIR/pai.profile.j2 > /etc/sai.d/pai.profile +else + if [ -f $HWSKU_DIR/pai.profile ]; then + cp $HWSKU_DIR/pai.profile /etc/sai.d/pai.profile + fi +fi + +# Create/Copy the gearbox configs to /etc/sai.d +if [[ x"$sonic_asic_platform" == x"broadcom" ]]; then + if [ -d $HWSKU_DIR/gearbox ]; then + cp $HWSKU_DIR/gearbox/*.bcm /etc/sai.d/. + fi +fi diff --git a/platform/vs/docker-gbsyncd-vs/supervisord.conf b/platform/vs/docker-gbsyncd-vs/supervisord.conf new file mode 100644 index 000000000000..6ba7ecbbdda2 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/supervisord.conf @@ -0,0 +1,48 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name gbsyncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[program:syncd] +command=/usr/bin/gbsyncd_start.sh +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited diff --git a/platform/vs/docker-sonic-vs/database_config.json b/platform/vs/docker-sonic-vs/database_config.json index f3ed663a402b..73f4c43462a6 100644 --- a/platform/vs/docker-sonic-vs/database_config.json +++ b/platform/vs/docker-sonic-vs/database_config.json @@ -58,9 +58,24 @@ "separator": "|", "instance" : "redis" }, - "CHASSIS_DB" : { + "GB_ASIC_DB" : { "id" : 8, "separator": "|", + "instance" : "redis" + }, + "GB_COUNTERS_DB" : { + "id" : 9, + "separator": "|", + "instance" : "redis" + }, + "GB_FLEX_COUNTER_DB" : { + "id" : 10, + "separator": "|", + "instance" : "redis" + }, + "CHASSIS_DB" : { + "id" : 11, + "separator": "|", "instance" : "redis_chassis" } }, diff --git a/platform/vs/gbsyncd-vs.mk b/platform/vs/gbsyncd-vs.mk new file mode 100644 index 000000000000..2013132d6281 --- /dev/null +++ b/platform/vs/gbsyncd-vs.mk @@ -0,0 +1,14 @@ +# docker image for vs gbsyncd + +DOCKER_GBSYNCD_PLATFORM_CODE = vs +include $(PLATFORM_PATH)/../template/docker-gbsyncd-base.mk + +$(DOCKER_GBSYNCD_BASE)_DEPENDS += $(SYNCD_VS) + +$(DOCKER_GBSYNCD_BASE)_DBG_DEPENDS += $(SYNCD_VS_DBG) \ + $(LIBSWSSCOMMON_DBG) \ + $(LIBSAIMETADATA_DBG) \ + $(LIBSAIREDIS_DBG) \ + $(LIBSAIVS_DBG) + +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/vs/rules.mk b/platform/vs/rules.mk index d91f487a5edb..66e8bad5fe78 100644 --- a/platform/vs/rules.mk +++ b/platform/vs/rules.mk @@ -2,6 +2,7 @@ include $(PLATFORM_PATH)/syncd-vs.mk include $(PLATFORM_PATH)/sonic-version.mk include $(PLATFORM_PATH)/docker-sonic-vs.mk include $(PLATFORM_PATH)/docker-syncd-vs.mk +include $(PLATFORM_PATH)/docker-gbsyncd-vs.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/onie.mk include $(PLATFORM_PATH)/kvm-image.mk diff --git a/src/sonic-device-data/Makefile b/src/sonic-device-data/Makefile index ecac92b00e0e..3de9c27c041d 100644 --- a/src/sonic-device-data/Makefile +++ b/src/sonic-device-data/Makefile @@ -19,6 +19,9 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : cp -Lr $$d device/x86_64-kvm_x86_64-r0/ ; \ cp ./sai.vs_profile device/x86_64-kvm_x86_64-r0/$$(basename $$d)/sai.profile; \ grep -v ^# device/x86_64-kvm_x86_64-r0/$$(basename $$d)/port_config.ini | awk '{i=i+1;print "eth"i":"$$2}' > device/x86_64-kvm_x86_64-r0/$$(basename $$d)/lanemap.ini + cp ./pai.vs_profile device/x86_64-kvm_x86_64-r0/$$(basename $$d)/pai.profile; \ + grep -v ^# device/x86_64-kvm_x86_64-r0/$$(basename $$d)/port_config.ini | awk '{i=i+1;print "eth"i":"$$2}' > device/x86_64-kvm_x86_64-r0/$$(basename $$d)/lanemap.ini + done; # Build the package diff --git a/src/sonic-device-data/src/pai.vs_profile b/src/sonic-device-data/src/pai.vs_profile new file mode 100644 index 000000000000..9c99c42a1627 --- /dev/null +++ b/src/sonic-device-data/src/pai.vs_profile @@ -0,0 +1,7 @@ +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM81724 +SAI_VS_SAI_SWITCH_TYPE=SAI_SWITCH_TYPE_PHY +SAI_VS_HOSTIF_USE_TAP_DEVICE=false +SAI_VS_USE_BCMSIM_LINK_MON=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini From b5bcfef0132103b73b7e3013a52cd1de9141b057 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Fri, 25 Sep 2020 09:20:09 -0700 Subject: [PATCH 1171/1427] Update conf DB with CA cert & rename ca_crt field (#5448) --- dockers/docker-sonic-restapi/restapi.sh | 6 +++--- src/sonic-config-engine/minigraph.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dockers/docker-sonic-restapi/restapi.sh b/dockers/docker-sonic-restapi/restapi.sh index d009507a7bc3..3a0997a2e66a 100755 --- a/dockers/docker-sonic-restapi/restapi.sh +++ b/dockers/docker-sonic-restapi/restapi.sh @@ -18,10 +18,10 @@ do if [[ -n "$certs" ]]; then SERVER_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['server_crt']"` SERVER_KEY=`sonic-cfggen -d -v "RESTAPI['certs']['server_key']"` - CLIENT_CA_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['client_ca_crt']"` + CA_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['ca_crt']"` CLIENT_CRT_CNAME=`sonic-cfggen -d -v "RESTAPI['certs']['client_crt_cname']"` - if [[ -f $SERVER_CRT && -f $SERVER_KEY && -f $CLIENT_CA_CRT ]]; then - RESTAPI_ARGS+=" -enablehttps=true -servercert=$SERVER_CRT -serverkey=$SERVER_KEY -clientcert=$CLIENT_CA_CRT -clientcertcommonname=$CLIENT_CRT_CNAME" + if [[ -f $SERVER_CRT && -f $SERVER_KEY && -f $CA_CRT ]]; then + RESTAPI_ARGS+=" -enablehttps=true -servercert=$SERVER_CRT -serverkey=$SERVER_KEY -clientcert=$CA_CRT -clientcertcommonname=$CLIENT_CRT_CNAME" break fi fi diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 4bc76c6aa6fe..2e3ba9da21a8 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1139,7 +1139,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw 'certs': { 'server_crt': '/etc/sonic/credentials/restapiserver.crt', 'server_key': '/etc/sonic/credentials/restapiserver.key', - 'client_ca_crt': '/etc/sonic/credentials/restapiclient.crt', + 'ca_crt': '/etc/sonic/credentials/restapica.crt', 'client_crt_cname': 'client.restapi.sonic' } } From 43a8368874e5c4b347102bb65fd35105e8035872 Mon Sep 17 00:00:00 2001 From: gechiang <62408185+gechiang@users.noreply.github.com> Date: Fri, 25 Sep 2020 10:25:11 -0700 Subject: [PATCH 1172/1427] make bgpmon autorestart enabled by supervisord (#5460) --- dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 index de6879c43725..9c379404bc1a 100644 --- a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 +++ b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 @@ -88,7 +88,7 @@ dependent_startup_wait_for=bgpd:running command=/usr/local/bin/bgpmon priority=6 autostart=false -autorestart=false +autorestart=true startsecs=0 stdout_logfile=syslog stderr_logfile=syslog From ccc3d755352e97f4a9a817cf59aa1f8ee9208c94 Mon Sep 17 00:00:00 2001 From: Sangita Maity Date: Fri, 25 Sep 2020 12:47:45 -0700 Subject: [PATCH 1173/1427] [portconfig] Fallback to port_config.ini if hwsku.json is not available (#5434) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **- Why I did it** As discussed, This PR covers the below points. 1. Give precedence to platform.json only if both platform.json and hwsku.json file exist. In case only platform.json exists, we don’t allow breakout for that HWSKU and fallback to port_config.ini. **- How I did it** check for `hwsku.json` file presence under get_path_to_port_config_file function. Signed-off-by: Sangita Maity --- src/sonic-py-common/sonic_py_common/device_info.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index f6b25de55ab5..4d1c9f862953 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -20,6 +20,9 @@ PORT_CONFIG_FILE = "port_config.ini" PLATFORM_JSON_FILE = "platform.json" +# HwSKU configuration file name +HWSKU_JSON_FILE = 'hwsku.json' + # Multi-NPU constants # TODO: Move Multi-ASIC-related functions and constants to a "multi_asic.py" module NPU_NAME_PREFIX = "asic" @@ -247,8 +250,13 @@ def get_path_to_port_config_file(hwsku=None, asic=None): port_config_candidates = [] - # Check for 'platform.json' file presence first - port_config_candidates.append(os.path.join(platform_path, PLATFORM_JSON_FILE)) + # Check for 'hwsku.json' file presence first + hwsku_json_file = os.path.join(hwsku_path, HWSKU_JSON_FILE) + + # if 'hwsku.json' file is available, Check for 'platform.json' file presence, + # if 'platform.json' is available, APPEND it. Otherwise, SKIP it. + if os.path.isfile(hwsku_json_file): + port_config_candidates.append(os.path.join(platform_path, PLATFORM_JSON_FILE)) # Check for 'port_config.ini' file presence in a few locations if asic: From dd02437d7f44844dafb874fec051059d32ad13db Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 25 Sep 2020 19:18:05 -0700 Subject: [PATCH 1174/1427] [sonic-platform-common] Update submodule (#5470) * src/sonic-platform-common 7255d3a...111dcf7 (2): > [EEPROM] Add new function part_number_str to TlvInfoDecoder (#121) > Fix fp_port_index error to get correct index type (#111) --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 7255d3a7a2dd..111dcf702cf3 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 7255d3a7a2ddea52cd88dcf0512ea1587ea63e6e +Subproject commit 111dcf702cf33e621455f3040a8682f2649b7b60 From f2e8187400d3bcb76686c4d9bb7eb5838f9c0abd Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Sat, 26 Sep 2020 06:40:21 +0300 Subject: [PATCH 1175/1427] [build]: Add build badge for Barefoot 202006 build (#4923) Signed-off-by: Volodymyr Boyko --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 9c80a3b2055c..b59d2d49d45d 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ [![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/badge/icon?subject=P4)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all) [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all) +*202006 builds*: + +[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-202006/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-202006/) + *201911 builds*: [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/) From 0a19cb4de58ba53f05cfce9c13f80573737a1252 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sun, 27 Sep 2020 02:20:43 +0800 Subject: [PATCH 1176/1427] [Mellanox] Refactor platform API to remove dependency on database (#5468) **- Why I did it** - Platform API implementation using sonic-cfggen to get platform name and SKU name, which will fail when the database is not available. - Chassis name is not correctly assigned, it shall be assigned with EEPROM TLV "Product Name", instead of SKU name - Chassis model is not implemented, it shall be assigned with EEPROM TLV "Part Number" **- How I did it** 1. Chassis > - Get platform name from /host/machine.conf > - Remove get SKU name with sonic-cfggen > - Get Chassis name and model from EEPROM TLV "Product Name" and "Part Number" > - Add function to return model 2. EEPROM > - Add function to return product name and part number 3. Platform > - Init EEPROM on the host side, so also can get the Chassis name model from EEPROM on the host side. --- .../sonic_platform/chassis.py | 44 +++++++------------ .../sonic_platform/eeprom.py | 34 +++++++++++++- .../sonic_platform/platform.py | 1 + 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 68c3fe16a86a..630b35903dff 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -18,7 +18,6 @@ import sys import io import re - import subprocess import syslog except ImportError as e: raise ImportError (str(e) + "- required module not found") @@ -27,9 +26,6 @@ MLNX_NUM_PSU = 2 -GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" -GET_PLATFORM_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.platform" - EEPROM_CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' EEPROM_CACHE_FILE = 'syseeprom_cache' @@ -61,18 +57,12 @@ class Chassis(ChassisBase): def __init__(self): super(Chassis, self).__init__() - # Initialize SKU name and Platform name - self.sku_name = self._get_sku_name() - self.platform_name = self._get_platform_name() - - mi = device_info.get_machine_info() - if mi is not None: - self.name = mi['onie_platform'] - self.platform_name = device_info.get_platform() - else: - self.name = self.sku_name - self.platform_name = self._get_platform_name() + self.name = "Undefined" + self.model = "Undefined" + # Initialize Platform name + self.platform_name = device_info.get_platform() + # move the initialization of each components to their dedicated initializer # which will be called from platform self.sfp_module_initialized = False @@ -148,6 +138,9 @@ def initialize_eeprom(self): from eeprom import Eeprom # Initialize EEPROM self._eeprom = Eeprom() + # Get chassis name and model from eeprom + self.name = self._eeprom.get_product_name() + self.model = self._eeprom.get_part_number() def initialize_components(self): @@ -173,6 +166,15 @@ def get_name(self): return self.name + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return self.model + ############################################## # SFP methods ############################################## @@ -244,18 +246,6 @@ def _extract_num_of_fans_and_fan_drawers(self): return num_of_fan, num_of_drawer - - def _get_sku_name(self): - p = subprocess.Popen(GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) - out, err = p.communicate() - return out.rstrip('\n') - - - def _get_platform_name(self): - p = subprocess.Popen(GET_PLATFORM_CMD, shell=True, stdout=subprocess.PIPE) - out, err = p.communicate() - return out.rstrip('\n') - def _get_port_position_tuple_by_platform_name(self): position_tuple = port_position_tuple_list[platform_dict_port[self.platform_name]] return position_tuple diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py index 23f4b8b3444c..413388d20385 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py @@ -80,13 +80,21 @@ def _load_eeprom(self): pass self._base_mac = self.mgmtaddrstr(eeprom) - if self._base_mac == None: + if self._base_mac is None: self._base_mac = "Undefined." self._serial_str = self.serial_number_str(eeprom) - if self._serial_str == None: + if self._serial_str is None: self._serial_str = "Undefined." + self._product_name = self.modelstr(eeprom) + if self._product_name is None: + self._product_name = "Undefined." + + self._part_number = self.part_number_str(eeprom) + if self._part_number is None: + self._part_number = "Undefined." + original_stdout = sys.stdout sys.stdout = StringIO() self.decode_eeprom(eeprom) @@ -135,6 +143,28 @@ def get_serial_number(self): self._load_eeprom() return self._serial_str + def get_product_name(self): + """ + Retrieves the hardware product name for the chassis + + Returns: + A string containing the hardware product name for this chassis. + """ + if not self._eeprom_loaded: + self._load_eeprom() + return self._product_name + + def get_part_number(self): + """ + Retrieves the hardware part number for the chassis + + Returns: + A string containing the hardware part number for this chassis. + """ + if not self._eeprom_loaded: + self._load_eeprom() + return self._part_number + def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py index 6073ce5faed9..d80c28996a7a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -20,6 +20,7 @@ def __init__(self): self._chassis = Chassis() self._chassis.initialize_components() self._chassis.initizalize_system_led() + self._chassis.initialize_eeprom() else: self._chassis = Chassis() self._chassis.initialize_psu() From a92986c60557651c8a37858a5b8d0acd430ceb7b Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Sun, 27 Sep 2020 02:21:31 +0800 Subject: [PATCH 1177/1427] [as7326-56x]Fix port_eeprom i2c mapping (#5466) **- Why I did it** There is error i2c mapping for port 11,12 and port 19, 20. **- How I did it** Fix to correct i2c mapping Co-authored-by: Jostar Yang --- .../accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py index 553e48fdd2a9..f9e0aae1b2a9 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py @@ -47,16 +47,16 @@ class SfpUtil(SfpUtilBase): 8: 50, 9: 48, 10: 49, - 11: 51, - 12: 52, + 11: 52, + 12: 51, 13: 53, 14: 56, 15: 55, 16: 54, 17: 58, 18: 57, - 19: 59, - 20: 60, + 19: 60, + 20: 59, 21: 61, 22: 63, 23: 62, From 4006ce711fa6545b0870186ffa05d4df24edb8b7 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Sat, 26 Sep 2020 12:14:30 -0700 Subject: [PATCH 1178/1427] [Multi-Asic] Forward SNMP requests received on front panel interface to SNMP agent in host. (#5420) * [Multi-Asic] Forward SNMP requests destined to loopback IP, and coming in through the front panel interface present in the network namespace, to SNMP agent running in the linux host. * Updates based on comments * Further updates in docker_image_ctl.j2 and caclmgrd * Change the variable for net config file. * Updated the comments in the code. * No need to clean up the exising NAT rules if present, which could be created by some other process. * Delete our rule first and add it back, to take care of caclmgrd restart. Another benefit is that we delete only our rules, rather than earlier approach of "iptables -F" which cleans up all rules. * Keeping the original logic to clean the NAT entries, to revist when NAT feature added in namespace. * Missing updates to log_info call. --- files/build_templates/docker_image_ctl.j2 | 4 ++ files/image_config/caclmgrd/caclmgrd | 58 +++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 182f7008cc87..71decb3fa906 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -91,6 +91,10 @@ function postStartAction() { {%- if docker_container_name == "database" %} if [ "$DEV" ]; then + # Enable the forwarding on eth0 interface in namespace. + SYSCTL_NET_CONFIG="/etc/sysctl.d/sysctl-net.conf" + docker exec -i database$DEV sed -i -e "s/^net.ipv4.conf.eth0.forwarding=0/net.ipv4.conf.eth0.forwarding=1/; + s/^net.ipv6.conf.eth0.forwarding=0/net.ipv6.conf.eth0.forwarding=1/" $SYSCTL_NET_CONFIG docker exec -i database$DEV sysctl --system -e link_namespace $DEV fi diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index d7951677bee1..b2fa5efaea61 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -85,7 +85,9 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): self.config_db_map[''].connect() self.iptables_cmd_ns_prefix[''] = "" self.namespace_mgmt_ip = self.get_namespace_mgmt_ip(self.iptables_cmd_ns_prefix[''], '') + self.namespace_mgmt_ipv6 = self.get_namespace_mgmt_ipv6(self.iptables_cmd_ns_prefix[''], '') self.namespace_docker_mgmt_ip = {} + self.namespace_docker_mgmt_ipv6 = {} namespaces = device_info.get_all_namespaces() for front_asic_namespace in namespaces['front_ns']: self.config_db_map[front_asic_namespace] = ConfigDBConnector(use_unix_socket_path=True, namespace=front_asic_namespace) @@ -93,11 +95,15 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): self.iptables_cmd_ns_prefix[front_asic_namespace] = "ip netns exec " + front_asic_namespace + " " self.namespace_docker_mgmt_ip[front_asic_namespace] = self.get_namespace_mgmt_ip(self.iptables_cmd_ns_prefix[front_asic_namespace], front_asic_namespace) + self.namespace_docker_mgmt_ipv6[front_asic_namespace] = self.get_namespace_mgmt_ipv6(self.iptables_cmd_ns_prefix[front_asic_namespace], + front_asic_namespace) for back_asic_namespace in namespaces['back_ns']: self.iptables_cmd_ns_prefix[back_asic_namespace] = "ip netns exec " + back_asic_namespace + " " self.namespace_docker_mgmt_ip[back_asic_namespace] = self.get_namespace_mgmt_ip(self.iptables_cmd_ns_prefix[back_asic_namespace], back_asic_namespace) + self.namespace_docker_mgmt_ipv6[back_asic_namespace] = self.get_namespace_mgmt_ipv6(self.iptables_cmd_ns_prefix[back_asic_namespace], + back_asic_namespace) def get_namespace_mgmt_ip(self, iptable_ns_cmd_prefix, namespace): ip_address_get_command = iptable_ns_cmd_prefix + "ip -4 -o addr show " + ("eth0" if namespace else "docker0") +\ @@ -105,6 +111,11 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): return self.run_commands([ip_address_get_command]) + def get_namespace_mgmt_ipv6(self, iptable_ns_cmd_prefix, namespace): + ipv6_address_get_command = iptable_ns_cmd_prefix + "ip -6 -o addr show scope global " + ("eth0" if namespace else "docker0") +\ + " | awk '{print $4}' | cut -d'/' -f1 | head -1" + return self.run_commands([ipv6_address_get_command]) + def run_commands(self, commands): """ Given a list of shell commands, run them in order @@ -206,6 +217,39 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): (docker_mgmt_ip, self.namespace_mgmt_ip)) return allow_internal_docker_ip_cmds + def generate_fwd_snmp_traffic_from_namespace_to_host_commands(self, namespace): + """ + The below SNAT and DNAT rules are added in asic namespace in multi-ASIC platforms. It helps to forward the SNMP request coming + in through the front panel interfaces created/present in the asic namespace to the SNMP Agent running in SNMP container in + linux host network namespace. The external IP addresses are NATed to the internal docker IP addresses for the SNMP Agent to respond. + """ + fwd_snmp_traffic_from_namespace_to_host_cmds = [] + + if namespace: + # IPv4 rules + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "iptables -t nat -X") + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "iptables -t nat -F") + + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + + "iptables -t nat -A PREROUTING -p udp --dport {} -j DNAT --to-destination {}".format + (self.ACL_SERVICES['SNMP']['dst_ports'][0], self.namespace_mgmt_ip)) + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + + "iptables -t nat -A POSTROUTING -p udp --dport {} -j SNAT --to-source {}".format + (self.ACL_SERVICES['SNMP']['dst_ports'][0], self.namespace_docker_mgmt_ip[namespace])) + + # IPv6 rules + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "ip6tables -t nat -X") + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "ip6tables -t nat -F") + + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + + "ip6tables -t nat -A PREROUTING -p udp --dport {} -j DNAT --to-destination {}".format + (self.ACL_SERVICES['SNMP']['dst_ports'][0], self.namespace_mgmt_ipv6)) + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + + "ip6tables -t nat -A POSTROUTING -p udp --dport {} -j SNAT --to-source {}".format + (self.ACL_SERVICES['SNMP']['dst_ports'][0], self.namespace_docker_mgmt_ipv6[namespace])) + + return fwd_snmp_traffic_from_namespace_to_host_cmds + def is_rule_ipv4(self, rule_props): if (("SRC_IP" in rule_props and rule_props["SRC_IP"]) or ("DST_IP" in rule_props and rule_props["DST_IP"])): @@ -438,6 +482,19 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): self.run_commands(iptables_cmds) + def update_control_plane_nat_acls(self, namespace): + """ + Convenience wrapper which programs the NAT rules for allowing the + snmp traffic coming on the front panel interface + """ + # Add iptables commands to allow front panel snmp traffic + iptables_cmds = self.generate_fwd_snmp_traffic_from_namespace_to_host_commands(namespace) + self.log_info("Issuing the following iptables commands:") + for cmd in iptables_cmds: + self.log_info(" " + cmd) + + self.run_commands(iptables_cmds) + def run(self): # Select Time-out for 10 Seconds SELECT_TIMEOUT_MS = 1000 * 10 @@ -462,6 +519,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): for namespace in self.config_db_map.keys(): # Unconditionally update control plane ACLs once at start on given namespace self.update_control_plane_acls(namespace) + self.update_control_plane_nat_acls(namespace) # Connect to Config DB of given namespace acl_db_connector = swsscommon.DBConnector("CONFIG_DB", 0, False, namespace) # Subscribe to notifications when ACL tables changes From 6eed0820c8014135e987d1615c14670b4d785f7f Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Sun, 27 Sep 2020 10:47:43 -0700 Subject: [PATCH 1179/1427] [bgp] Add 'allow list' manager feature (#5309) implements a new feature: "BGP Allow list." This feature allows us to control which IP prefixes are going to be advertised via ebgp from the routes received from EBGP neighbors. --- .../bgpd/templates/general/peer-group.conf.j2 | 2 +- .../bgpd/templates/general/policies.conf.j2 | 27 + files/image_config/constants/constants.yml | 12 + rules/sonic_bgpcfgd.mk | 3 +- src/sonic-bgpcfgd/.gitignore | 1 + src/sonic-bgpcfgd/app/allow_list.py | 632 ++++++++++++++++++ src/sonic-bgpcfgd/app/config.py | 20 +- src/sonic-bgpcfgd/app/directory.py | 159 +++++ src/sonic-bgpcfgd/app/manager.py | 71 ++ src/sonic-bgpcfgd/app/vars.py | 2 +- src/sonic-bgpcfgd/bgpcfgd | 7 +- src/sonic-bgpcfgd/pytest.ini | 2 + src/sonic-bgpcfgd/setup.py | 3 +- .../data/general/policies.conf/param_all.json | 13 +- .../general/policies.conf/param_base.json | 11 +- .../general/policies.conf/param_deny.json | 17 + .../general/policies.conf/result_all.conf | 14 + .../general/policies.conf/result_deny.conf | 39 ++ src/sonic-bgpcfgd/tests/test_allow_list.py | 469 +++++++++++++ .../tests/test_ipv6_nexthop_global.py | 29 +- src/sonic-bgpcfgd/tests/util.py | 4 +- 21 files changed, 1515 insertions(+), 22 deletions(-) create mode 100644 src/sonic-bgpcfgd/app/allow_list.py create mode 100644 src/sonic-bgpcfgd/app/directory.py create mode 100644 src/sonic-bgpcfgd/app/manager.py create mode 100644 src/sonic-bgpcfgd/pytest.ini create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf create mode 100644 src/sonic-bgpcfgd/tests/test_allow_list.py diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 index b0acd1b2a460..5790d47a5a8a 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -24,7 +24,7 @@ {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V6 allowas-in 1 neighbor PEER_V6_INT allowas-in 1 - {% endif %} +{% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor PEER_V6_INT route-reflector-client {% endif %} diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 index c545cf272892..4c27db4a466a 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -3,6 +3,33 @@ ! ! ! +{% if constants.bgp.allow_list is defined and constants.bgp.allow_list.enabled is defined and constants.bgp.allow_list.enabled %} +{% if constants.bgp.allow_list.default_action is defined and constants.bgp.allow_list.default_action.strip() == 'deny' %} +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community no-export additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community no-export additive +{% else %} +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community {{ constants.bgp.allow_list.drop_community }} additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community {{ constants.bgp.allow_list.drop_community }} additive +{% endif %} +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! +{% endif %} +! +! +! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 3e1b76be0157..074956ff8396 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -18,6 +18,18 @@ constants: enabled: true ipv4: 64 ipv6: 64 + allow_list: + enabled: true + default_action: "permit" # or "deny" + drop_community: 5060:12345 # value of the community to identify a prefix to drop. Make sense only with allow_list_default_action equal to 'permit' + default_pl_rules: + v4: + - "deny 0.0.0.0/0 le 17" + - "permit 127.0.0.1/32" + v6: + - "deny 0::/0 le 59" + - "deny 0::/0 ge 65" + - "permit fe80::/64" peers: general: # peer_type db_table: "BGP_NEIGHBOR" diff --git a/rules/sonic_bgpcfgd.mk b/rules/sonic_bgpcfgd.mk index 32abbd5af948..7a9cae29cf19 100644 --- a/rules/sonic_bgpcfgd.mk +++ b/rules/sonic_bgpcfgd.mk @@ -6,6 +6,7 @@ $(SONIC_BGPCFGD)_SRC_PATH = $(SRC_PATH)/sonic-bgpcfgd # of sonic-config-engine and bgpcfgd explicitly calls sonic-cfggen # as part of its unit tests. # TODO: Refactor unit tests so that these dependencies are not needed -$(SONIC_BGPCFGD)_DEPENDS += $(SWSSSDK_PY2) $(SONIC_PY_COMMON_PY2) +$(SONIC_BGPCFGD)_DEPENDS += $(SONIC_PY_COMMON_PY2) +$(SONIC_BGPCFGD)_DEBS_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(SONIC_BGPCFGD)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_BGPCFGD) diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore index bb1ba531d1d6..920a1b3ae499 100644 --- a/src/sonic-bgpcfgd/.gitignore +++ b/src/sonic-bgpcfgd/.gitignore @@ -6,3 +6,4 @@ app/*.pyc tests/*.pyc tests/__pycache__/ .idea +.coverage diff --git a/src/sonic-bgpcfgd/app/allow_list.py b/src/sonic-bgpcfgd/app/allow_list.py new file mode 100644 index 000000000000..2637d6999244 --- /dev/null +++ b/src/sonic-bgpcfgd/app/allow_list.py @@ -0,0 +1,632 @@ +""" +Implementation of "allow-list" feature +""" +import re + +from app.log import log_debug, log_info, log_err, log_warn +from app.template import TemplateFabric +from app.manager import Manager +from app.util import run_command + +class BGPAllowListMgr(Manager): + """ This class initialize "AllowList" settings """ + ALLOW_ADDRESS_PL_NAME_TMPL = "ALLOW_ADDRESS_%d_%s" # template for a name for the ALLOW_ADDRESS prefix-list ??? + EMPTY_COMMUNITY = "empty" + PL_NAME_TMPL = "PL_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s_V%s" + COMMUNITY_NAME_TMPL = "COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s" + RM_NAME_TMPL = "ALLOW_LIST_DEPLOYMENT_ID_%d_V%s" + ROUTE_MAP_ENTRY_WITH_COMMUNITY_START = 10 + ROUTE_MAP_ENTRY_WITH_COMMUNITY_END = 29990 + ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START = 30000 + ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END = 65530 + + V4 = "v4" # constant for af enum: V4 + V6 = "v6" # constant for af enum: V6 + + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(BGPAllowListMgr, self).__init__( + common_objs, + [], + db, + table, + ) + self.cfg_mgr = common_objs["cfg_mgr"] + self.constants = common_objs["constants"] + self.key_re = re.compile(r"^DEPLOYMENT_ID\|\d+\|\S+$|^DEPLOYMENT_ID\|\d+$") + self.enabled = self.__get_enabled() + self.__load_constant_lists() + + def set_handler(self, key, data): + """ + Manager method which runs on receiving 'SET' message + :param key: ket of the 'SET' message + :param data: data of the 'SET' message + :return: True if the message was executed, False - the message should be postponed. + """ + if not self.enabled: + log_warn("BGPAllowListMgr::Received 'SET' command, but this feature is disabled in constants") + return True + if not self.__set_handler_validate(key, data): + return True + key = key.replace("DEPLOYMENT_ID|", "") + deployment_id, community_value = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) + deployment_id = int(deployment_id) + prefixes_v4 = [] + prefixes_v6 = [] + if "prefixes_v4" in data: + prefixes_v4 = str(data['prefixes_v4']).split(",") + if "prefixes_v6" in data: + prefixes_v6 = str(data['prefixes_v6']).split(",") + self.__update_policy(deployment_id, community_value, prefixes_v4, prefixes_v6) + return True + + def __set_handler_validate(self, key, data): + """ + Validate parameters of a "Set" message + :param key: ket of the 'SET' message + :param data: data of the 'SET' message + :return: True if parameters are valid, False if parameters are invalid + """ + if data is None: + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message without data") + return False + if not self.key_re.match(key): + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid key: '%s'" % key) + return False + prefixes_v4 = [] + prefixes_v6 = [] + if "prefixes_v4" in data: + prefixes_v4 = str(data["prefixes_v4"]).split(",") + if not all(TemplateFabric.is_ipv4(prefix) for prefix in prefixes_v4): + arguments = "prefixes_v4", str(data["prefixes_v4"]) + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) + return False + if "prefixes_v6" in data: + prefixes_v6 = str(data["prefixes_v6"]).split(",") + if not all(TemplateFabric.is_ipv6(prefix) for prefix in prefixes_v6): + arguments = "prefixes_v6", str(data["prefixes_v6"]) + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) + return False + if not prefixes_v4 and not prefixes_v6: + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with no prefixes specified: %s" % str(data)) + return False + return True + + def del_handler(self, key): + """ + Manager method which runs on "DEL" message + :param key: a key of "DEL" message + """ + if not self.enabled: + log_warn("BGPAllowListMgr::Received 'DEL' command, but this feature is disabled in constants") + return + if not self.__del_handler_validate(key): + return + key = key.replace('DEPLOYMENT_ID|', '') + deployment_id, community = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) + deployment_id = int(deployment_id) + self.__remove_policy(deployment_id, community) + + def __del_handler_validate(self, key): + """ + Validate "DEL" method parameters + :param key: a key of "DEL" message + :return: True if parameters are valid, False if parameters are invalid + """ + if not self.key_re.match(key): + log_err("BGPAllowListMgr::Received BGP ALLOWED 'DEL' message with invalid key: '$s'" % key) + return False + return True + + def __update_policy(self, deployment_id, community_value, prefixes_v4, prefixes_v6): + """ + Update "allow list" policy with parameters + :param deployment_id: deployment id which policy will be changed + :param community_value: community value to match for the updated policy + :param prefixes_v4: a list of v4 prefixes for the updated policy + :param prefixes_v6: a list of v6 prefixes for the updated policy + """ + # update all related entries with the information + info = deployment_id, community_value, str(prefixes_v4), str(prefixes_v6) + msg = "BGPAllowListMgr::Updating 'Allow list' policy." + msg += " deployment_id '%s'. community: '%s'" + msg += " prefix_v4 '%s'. prefix_v6: '%s'" + log_info(msg % info) + names = self.__generate_names(deployment_id, community_value) + self.cfg_mgr.update() + cmds = [] + cmds += self.__update_prefix_list(self.V4, names['pl_v4'], prefixes_v4) + cmds += self.__update_prefix_list(self.V6, names['pl_v6'], prefixes_v6) + cmds += self.__update_community(names['community'], community_value) + cmds += self.__update_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) + cmds += self.__update_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) + if cmds: + rc = self.cfg_mgr.push_list(cmds) + rc = rc and self.__restart_peers(deployment_id) + log_debug("BGPAllowListMgr::__update_policy. The peers were updated: rc=%s" % rc) + else: + log_debug("BGPAllowListMgr::__update_policy. Nothing to update") + log_info("BGPAllowListMgr::Done") + + def __remove_policy(self, deployment_id, community_value): + """ + Remove "allow list" policy for given deployment_id and community_value + :param deployment_id: deployment id which policy will be removed + :param community_value: community value to match for the removed policy + """ + # remove all related entries from the configuration + # put default rule to the route-map + info = deployment_id, community_value + msg = "BGPAllowListMgr::Removing 'Allow list' policy." + msg += " deployment_id '%s'. community: '%s'" + log_info(msg % info) + + names = self.__generate_names(deployment_id, community_value) + self.cfg_mgr.update() + cmds = [] + cmds += self.__remove_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) + cmds += self.__remove_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) + cmds += self.__remove_prefix_list(self.V4, names['pl_v4']) + cmds += self.__remove_prefix_list(self.V6, names['pl_v6']) + cmds += self.__remove_community(names['community']) + if cmds: + rc = self.cfg_mgr.push_list(cmds) + rc = rc and self.__restart_peers(deployment_id) + log_debug("BGPAllowListMgr::__remove_policy. 'Allow list' policy was removed. rc:%s" % rc) + else: + log_debug("BGPAllowListMgr::__remove_policy. Nothing to remove") + log_info('BGPAllowListMgr::Done') + + @staticmethod + def __generate_names(deployment_id, community_value): + """ + Generate prefix-list names for a given peer_ip and community value + :param deployment_id: deployment_id for which we're going to filter prefixes + :param community_value: community, which we want to use to filter prefixes + :return: a dictionary with names + """ + if community_value == BGPAllowListMgr.EMPTY_COMMUNITY: + community_name = BGPAllowListMgr.EMPTY_COMMUNITY + else: + community_name = BGPAllowListMgr.COMMUNITY_NAME_TMPL % (deployment_id, community_value) + names = { + "pl_v4": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '4'), + "pl_v6": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '6'), + "rm_v4": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '4'), + "rm_v6": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '6'), + "community": community_name, + } + arguments = deployment_id, community_value, str(names) + log_debug("BGPAllowListMgr::__generate_names. deployment_id: %d, community: %s. names: %s" % arguments) + return names + + def __update_prefix_list(self, af, pl_name, allow_list): + """ + Create or update a prefix-list with name pl_name. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :param pl_name: prefix-list name + :param allow_list: prefix-list entries + :return: True if updating was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + constant_list = self.__get_constant_list(af) + allow_list = self.__to_prefix_list(allow_list) + log_debug("BGPAllowListMgr::__update_prefix_list. af='%s' prefix-list name=%s" % (af, pl_name)) + exist, correct = self.__is_prefix_list_valid(af, pl_name, allow_list, constant_list) + if correct: + log_debug("BGPAllowListMgr::__update_prefix_list. the prefix-list '%s' exists and correct" % pl_name) + return [] + family = self.__af_to_family(af) + cmds = [] + seq_no = 10 + if exist: + cmds.append('no %s prefix-list %s' % (family, pl_name)) + for entry in constant_list + allow_list: + cmds.append('%s prefix-list %s seq %d %s' % (family, pl_name, seq_no, entry)) + seq_no += 10 + return cmds + + def __remove_prefix_list(self, af, pl_name): + """ + Remove prefix-list in the address-family af. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :param pl_name: list of prefix-list names + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + log_debug("BGPAllowListMgr::__remove_prefix_lists. af='%s' pl_names='%s'" % (af, pl_name)) + exist, _ = self.__is_prefix_list_valid(af, pl_name, [], []) + if not exist: + log_debug("BGPAllowListMgr::__remove_prefix_lists: prefix_list '%s' not found" % pl_name) + return [] + family = self.__af_to_family(af) + return ["no %s prefix-list %s" % (family, pl_name)] + + def __is_prefix_list_valid(self, af, pl_name, allow_list, constant_list): + """ + Check that a prefix list exists and it has valid entries + :param af: address family of the checked prefix-list + :param pl_name: prefix-list name + :param allow_list: a prefix-list which must be a part of the valid prefix list + :param constant_list: a constant list which must be on top of each "allow" prefix list on the device + :return: a tuple. The first element of the tuple has True if the prefix-list exists, False otherwise, + The second element of the tuple has True if the prefix-list contains correct entries, False if not + """ + assert af == self.V4 or af == self.V6 + family = self.__af_to_family(af) + match_string = '%s prefix-list %s seq ' % (family, pl_name) + conf = self.cfg_mgr.get_text() + if not any(line.strip().startswith(match_string) for line in conf): + return False, False # if the prefix list is not exists, it is not correct + constant_set = set(constant_list) + allow_set = set(allow_list) + for line in conf: + if line.startswith(match_string): + found = line[len(match_string):].strip().split(' ') + rule = " ".join(found[1:]) + if rule in constant_set: + constant_set.discard(rule) + elif rule in allow_set: + if constant_set: + return True, False # Not everything from constant set is presented + else: + allow_set.discard(rule) + return True, len(allow_set) == 0 # allow_set should be presented all + + def __update_community(self, community_name, community_value): + """ + Update community for a peer + :param community_name: name of the community to update + :param community_value: community value for the peer + :return: True if operation was successful, False otherwise + """ + log_debug("BGPAllowListMgr::__update_community. community_name='%s' community='%s'" % (community_name, community_value)) + if community_value == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community + log_debug("BGPAllowListMgr::__update_community. Empty community. exiting") + return [] + cmds = [] + exists, found_community_value = self.__is_community_presented(community_name) + if exists: + if community_value == found_community_value: + log_debug("BGPAllowListMgr::__update_community. community '%s' is already presented" % community_name) + return [] + else: + msg = "BGPAllowListMgr::__update_community. " + msg += "community '%s' is already presented, but community value should be updated" % community_name + log_debug(msg) + cmds.append("no bgp community-list standard %s" % community_name) + cmds.append('bgp community-list standard %s permit %s' % (community_name, community_value)) + return cmds + + def __remove_community(self, community_name): + """ + Remove community for a peer + :param community_name: community value for the peer + :return: True if operation was successful, False otherwise + """ + log_debug("BGPAllowListMgr::__remove_community. community='%s'" % community_name) + if community_name == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community + log_debug("BGPAllowListMgr::__remove_community. There is nothing to remove in empty community") + return [] + exists, _ = self.__is_community_presented(community_name) + if not exists: + log_debug("BGPAllowListMgr::__remove_community. Community is already removed.") + return [] + return ['no bgp community-list standard %s' % community_name] + + def __is_community_presented(self, community_name): + """ + Return True if community for the peer_ip exists + :param community_name: community value for the peer + :return: A tuple. First element: True if operation was successful, False otherwise + Second element: community value if the first element is True no value otherwise + """ + log_debug("BGPAllowListMgr::__is_community_presented. community='%s'" % community_name) + match_string = 'bgp community-list standard %s permit ' % community_name + conf = self.cfg_mgr.get_text() + found = [line.strip() for line in conf if line.strip().startswith(match_string)] + if not found: + return False, None + community_value = found[0].replace(match_string, '') + return True, community_value + + def __update_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): + """ + Add or update a "Allow address" route-map entry with the parameters + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + info = af, route_map_name, allow_address_pl_name, community_name + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) + entries = self.__parse_allow_route_map_entries(af, route_map_name) + found, _ = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) + if found: + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. route-map='%s' is already found" % route_map_name) + return [] + seq_number = self.__find_next_seq_number(entries.keys(), community_name != self.EMPTY_COMMUNITY, route_map_name) + info = af, seq_number, allow_address_pl_name, community_name + out = "af='%s' seqno='%d' Allow pl='%s' cl='%s'" % info + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. %s" % out) + ip_version = "" if af == self.V4 else "v6" + cmds = [ + 'route-map %s permit %d' % (route_map_name, seq_number), + ' match ip%s address prefix-list %s' % (ip_version, allow_address_pl_name) + ] + if not community_name.endswith(self.EMPTY_COMMUNITY): + cmds.append(" match community %s" % community_name) + return cmds + + def __remove_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): + """ + Add or update a "Allow address" route-map entry with the parameters + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + info = af, route_map_name, allow_address_pl_name, community_name + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) + entries = self.__parse_allow_route_map_entries(af, route_map_name) + found, seq_number = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) + if not found: + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. Not found route-map '%s' entry" % allow_address_pl_name) + return [] + return ['no route-map %s permit %d' % (route_map_name, seq_number)] + + @staticmethod + def __find_route_map_entry(entries, allow_address_pl_name, community_name): + """ + Find route-map entry with given allow_address prefix list name and community name in the parsed route-map. + :param entries: entries of parsed route-map + :param allow_address_pl_name: name of the "allow address" prefix-list + :param community_name: name of the "allow address" community name + :return: a tuple. The first element of the tuple is True, if the route-map entry was found, False otherwise. + The second element of the tuple has a sequence number of the entry. + """ + for sequence_number, values in entries.items(): + if sequence_number == 65535: + continue + allow_list_presented = values['pl_allow_list'] == allow_address_pl_name + community_presented = values['community'] == community_name + if allow_list_presented and community_presented: + log_debug("BGPAllowListMgr::__find_route_map_entry. found route-map '%s' entry" % allow_address_pl_name) + return True, sequence_number + return False, None + + def __parse_allow_route_map_entries(self, af, route_map_name): + """ + Parse "Allow list" route-map entries. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: A tuple, First element: True if operation was successful, False otherwise + Second element: list of object with parsed route-map entries + """ + assert af == self.V4 or af == self.V6 + log_debug("BGPAllowListMgr::__parse_allow_route_map_entries. af='%s', rm='%s'" % (af, route_map_name)) + match_string = 'route-map %s permit ' % route_map_name + entries = {} + inside_route_map = False + route_map_seq_number = None + pl_allow_list_name = None + community_name = self.EMPTY_COMMUNITY + if af == self.V4: + match_pl_allow_list = 'match ip address prefix-list ' + else: # self.V6 + match_pl_allow_list = 'match ipv6 address prefix-list ' + match_community = 'match community ' + conf = self.cfg_mgr.get_text() + for line in conf + [""]: + if inside_route_map: + if line.strip().startswith(match_pl_allow_list): + pl_allow_list_name = line.strip()[len(match_pl_allow_list):] + continue + elif line.strip().startswith(match_community): + community_name = line.strip()[len(match_community):] + continue + else: + if pl_allow_list_name is not None: + entries[route_map_seq_number] = { + 'pl_allow_list': pl_allow_list_name, + 'community': community_name, + } + else: + if route_map_seq_number != 65535: + log_warn("BGPAllowListMgr::Found incomplete route-map '%s' entry. seq_no=%d" % (route_map_name, route_map_seq_number)) + inside_route_map = False + pl_allow_list_name = None + community_name = self.EMPTY_COMMUNITY + route_map_seq_number = None + if line.startswith(match_string): + found = line[len(match_string):] + assert found.isdigit() + route_map_seq_number = int(found) + inside_route_map = True + return entries + + @staticmethod + def __find_next_seq_number(seq_numbers, has_community, route_map_name): + """ + Find a next available "Allow list" route-map entry number + :param seq_numbers: a list of already used sequence numbers + :param has_community: True, if the route-map entry has community + :return: next available route-map sequence number + """ + used_sequence_numbers = set(seq_numbers) + sequence_number = None + if has_community: # put entries without communities after 29999 + start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_START + end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_END + else: + start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START + end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END + for i in range(start_seq, end_seq, 10): + if i not in used_sequence_numbers: + sequence_number = i + break + if sequence_number is None: + raise RuntimeError("No free sequence numbers for '%s'" % route_map_name) + info = sequence_number, "yes" if has_community else "no" + log_debug("BGPAllowListMgr::__find_next_seq_number '%d' has_community='%s'" % info) + return sequence_number + + def __extract_peer_group_names(self): + """ + Extract names of all peer-groups defined in the config + :return: list of peer-group names + """ + # Find all peer-groups entries + re_peer_group = re.compile(r'^\s*neighbor (\S+) peer-group$') + peer_groups = [] + for line in self.cfg_mgr.get_text(): + result = re_peer_group.match(line) + if result: + peer_groups.append(result.group(1)) + return peer_groups + + def __get_peer_group_to_route_map(self, peer_groups): + """ + Extract names of route-maps which is connected to peer-groups defines as peer_groups + :peer_groups: a list of peer-group names + :return: dictionary where key is a peer-group, value is a route-map name which is defined as route-map in + for the peer_group. + """ + pg_2_rm = {} + for pg in peer_groups: + re_peer_group_rm = re.compile(r'^\s*neighbor %s route-map (\S+) in$' % pg) + for line in self.cfg_mgr.get_text(): + result = re_peer_group_rm.match(line) + if result: + pg_2_rm[pg] = result.group(1) + break + return pg_2_rm + + def __get_route_map_calls(self, rms): + """ + Find mapping between route-maps and route-map call names, defined for the route-maps + :rms: a set with route-map names + :return: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map + """ + rm_2_call = {} + re_rm = re.compile(r'^route-map (\S+) permit \d+$') + re_call = re.compile(r'^\s*call (\S+)$') + inside_name = None + for line in self.cfg_mgr.get_text(): + if inside_name: + inside_result = re_call.match(line) + if inside_result: + rm_2_call[inside_name] = inside_result.group(1) + inside_name = None + continue + result = re_rm.match(line) + if not result: + continue + inside_name = None + if result.group(1) not in rms: + continue + inside_name = result.group(1) + return rm_2_call + + def __get_peer_group_to_restart(self, deployment_id, pg_2_rm, rm_2_call): + """ + Get peer_groups which are assigned to deployment_id + :deployment_id: deployment_id number + :pg_2_rm: a dictionary where key is a peer-group, value is a route-map name which is defined as route-map in + for the peer_group. + :rm_2_call: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map + """ + ret = set() + target_allow_list_prefix = 'ALLOW_LIST_DEPLOYMENT_ID_%d_V' % deployment_id + for peer_group, route_map in pg_2_rm.items(): + if route_map in rm_2_call: + if rm_2_call[route_map].startswith(target_allow_list_prefix): + ret.add(peer_group) + return list(ret) + + def __find_peer_group_by_deployment_id(self, deployment_id): + """ + Deduce peer-group names which are connected to devices with requested deployment_id + :param deployment_id: deployment_id number + :return: a list of peer-groups which a used by devices with requested deployment_id number + """ + self.cfg_mgr.update() + peer_groups = self.__extract_peer_group_names() + pg_2_rm = self.__get_peer_group_to_route_map(peer_groups) + rm_2_call = self.__get_route_map_calls(set(pg_2_rm.values())) + ret = self.__get_peer_group_to_restart(deployment_id, pg_2_rm, rm_2_call) + return list(ret) + + def __restart_peers(self, deployment_id): + """ + Restart peer-groups with requested deployment_id + :param deployment_id: deployment_id number + """ + log_info("BGPAllowListMgr::Restart peers with deployment_id=%d" % deployment_id) + peer_groups = self.__find_peer_group_by_deployment_id(deployment_id) + rv = True + if peer_groups: + for peer_group in peer_groups: + no_error, _, _ = run_command(["vtysh", "-c", "clear bgp peer-group %s soft in" % peer_group]) + rv = no_error == 0 and rv + else: + no_error, _, _ = run_command(["vtysh", "-c", "clear bgp * soft in"]) + rv = no_error == 0 + return rv + + def __get_enabled(self): + """ + Load enable/disabled property from constants + :return: True if enabled, False otherwise + """ + return 'bgp' in self.constants \ + and 'allow_list' in self.constants["bgp"] \ + and "enabled" in self.constants["bgp"]["allow_list"] \ + and self.constants["bgp"]["allow_list"]["enabled"] + + def __load_constant_lists(self): + """ + Load default prefix-list entries from constants.yml file + """ + if 'bgp' in self.constants and 'allow_list' in self.constants["bgp"] \ + and "default_pl_rules" in self.constants["bgp"]["allow_list"]: + obj = self.constants["bgp"]["allow_list"]["default_pl_rules"] + if "v4" in obj: + self.constants_v4 = obj["v4"] + else: + self.constants_v4 = [] + if "v6" in obj: + self.constants_v6 = obj["v6"] + else: + self.constants_v6 = [] + + def __get_constant_list(self, af): + """ + Return loaded default prefix-list entries bases on address family + :param af: address family + :return: default prefix-list entries + """ + if af == self.V4: + return self.constants_v4 + else: + return self.constants_v6 + + @staticmethod + def __to_prefix_list(allow_list): + """ + Convert "allow list" prefix list, to a prefix-list rules + :param allow_list: "allow list" prefix list + :return: prefix-list rules + """ + return ["permit %s ge %d" % (prefix, int(prefix.split("/")[1])+1) for prefix in allow_list] + + def __af_to_family(self, af): + """ + Convert address family into prefix list family + :param af: address family + :return: prefix list ip family + """ + return 'ip' if af == self.V4 else 'ipv6' diff --git a/src/sonic-bgpcfgd/app/config.py b/src/sonic-bgpcfgd/app/config.py index 26639fe75e89..a0c1329f832e 100644 --- a/src/sonic-bgpcfgd/app/config.py +++ b/src/sonic-bgpcfgd/app/config.py @@ -10,19 +10,33 @@ class ConfigMgr(object): """ The class represents frr configuration """ def __init__(self): self.current_config = None + self.current_config_raw = None def reset(self): """ Reset stored config """ self.current_config = None + self.current_config_raw = None def update(self): """ Read current config from FRR """ self.current_config = None + self.current_config_raw = None ret_code, out, err = run_command(["vtysh", "-c", "show running-config"]) if ret_code != 0: + # FIXME: should we throw exception here? log_crit("can't update running config: rc=%d out='%s' err='%s'" % (ret_code, out, err)) return - self.current_config = self.to_canonical(out) + text = [] + for line in out.split('\n'): + if line.lstrip().startswith('!'): + continue + text.append(line) + text += [" "] # Add empty line to have something to work on, if there is no text + self.current_config_raw = text + self.current_config = self.to_canonical(out) # FIXME: use test as an input + + def push_list(self, cmdlist): + return self.push("\n".join(cmdlist)) def push(self, cmd): """ @@ -51,8 +65,12 @@ def write(self, cmd): log_err("ConfigMgr::push(): can't push configuration '%s', rc='%d', stdout='%s', stderr='%s'" % err_tuple) if ret_code == 0: self.current_config = None # invalidate config + self.current_config_raw = None return ret_code == 0 + def get_text(self): + return self.current_config_raw + @staticmethod def to_canonical(raw_config): """ diff --git a/src/sonic-bgpcfgd/app/directory.py b/src/sonic-bgpcfgd/app/directory.py new file mode 100644 index 000000000000..d27ec64256e3 --- /dev/null +++ b/src/sonic-bgpcfgd/app/directory.py @@ -0,0 +1,159 @@ +from collections import defaultdict + +from app.log import log_err + + +class Directory(object): + """ This class stores values and notifies callbacks which were registered to be executed as soon + as some value is changed. This class works as DB cache mostly """ + def __init__(self): + self.data = defaultdict(dict) # storage. A key is a slot name, a value is a dictionary with data + self.notify = defaultdict(lambda: defaultdict(list)) # registered callbacks: slot -> path -> handlers[] + + @staticmethod + def get_slot_name(db, table): + """ Convert db, table pair into a slot name """ + return db + "__" + table + + def path_traverse(self, slot, path): + """ + Traverse a path in the storage. + If the path is an empty string, it returns a value as it is. + If the path is not an empty string, the method will traverse through the dictionary value. + Example: + self.data["key_1"] = { "abc": { "cde": { "fgh": "val_1", "ijk": "val_2" } } } + self.path_traverse("key_1", "abc/cde") will return True, { "fgh": "val_1", "ijk": "val_2" } + :param slot: storage key + :param path: storage path as a string where each internal key is separated by '/' + :return: a pair: True if the path was found, object if it was found + """ + if slot not in self.data: + return False, None + elif path == '': + return True, self.data[slot] + d = self.data[slot] + for p in path.split("/"): + if p not in d: + return False, None + d = d[p] + return True, d + + def path_exist(self, db, table, path): + """ + Check if the path exists in the storage + :param db: db name + :param table: table name + :param path: requested path + :return: True if the path is available, False otherwise + """ + slot = self.get_slot_name(db, table) + return self.path_traverse(slot, path)[0] + + def get_path(self, db, table, path): + """ + Return the requested path from the storage + :param db: db name + :param table: table name + :param path: requested path + :return: object if the path was found, None otherwise + """ + slot = self.get_slot_name(db, table) + return self.path_traverse(slot, path)[1] + + def put(self, db, table, key, value): + """ + Put information into the storage. Notify handlers which are dependant to the information + :param db: db name + :param table: table name + :param key: key to change + :param value: value to put + :return: + """ + slot = self.get_slot_name(db, table) + self.data[slot][key] = value + if slot in self.notify: + for path in self.notify[slot].keys(): + if self.path_exist(db, table, path): + for handler in self.notify[slot][path]: + handler() + + def get(self, db, table, key): + """ + Get a value from the storage + :param db: db name + :param table: table name + :param key: ket to get + :return: value for the key + """ + slot = self.get_slot_name(db, table) + return self.data[slot][key] + + def get_slot(self, db, table): + """ + Get an object from the storage + :param db: db name + :param table: table name + :return: object for the slot + """ + slot = self.get_slot_name(db, table) + return self.data[slot] + + def remove(self, db, table, key): + """ + Remove a value from the storage + :param db: db name + :param table: table name + :param key: key to remove + """ + slot = self.get_slot_name(db, table) + if slot in self.data: + if key in self.data[slot]: + del self.data[slot][key] + else: + log_err("Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) + else: + log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) + + def remove_slot(self, db, table): + """ + Remove an object from the storage + :param db: db name + :param table: table name + """ + slot = self.get_slot_name(db, table) + if slot in self.data: + del self.data[slot] + else: + log_err("Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) + + def available(self, db, table): + """ + Check if the table is available + :param db: db name + :param table: table name + :return: True if the slot is available, False if not + """ + slot = self.get_slot_name(db, table) + return slot in self.data + + def available_deps(self, deps): + """ + Check if all items from the deps list is available in the storage + :param deps: list of dependencies + :return: True if all dependencies are presented, False otherwise + """ + res = True + for db, table, path in deps: + res = res and self.path_exist(db, table, path) + return res + + def subscribe(self, deps, handler): + """ + Subscribe the handler to be run as soon as all dependencies are presented + :param deps: + :param handler: + :return: + """ + for db, table, path in deps: + slot = self.get_slot_name(db, table) + self.notify[slot][path].append(handler) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/manager.py b/src/sonic-bgpcfgd/app/manager.py new file mode 100644 index 000000000000..ba45029b5120 --- /dev/null +++ b/src/sonic-bgpcfgd/app/manager.py @@ -0,0 +1,71 @@ +from swsscommon import swsscommon + +from app.log import log_debug, log_err + + +class Manager(object): + """ This class represents a SONiC DB table """ + def __init__(self, common_objs, deps, database, table_name): + """ + Initialize class + :param common_objs: common object dictionary + :param deps: dependencies list + :param database: database name + :param table_name: table name + """ + self.directory = common_objs['directory'] + self.cfg_mgr = common_objs['cfg_mgr'] + self.constants = common_objs['constants'] + self.deps = deps + self.db_name = database + self.table_name = table_name + self.set_queue = [] + self.directory.subscribe(deps, self.on_deps_change) # subscribe this class method on directory changes + + def get_database(self): + """ Return associated database """ + return self.db_name + + def get_table_name(self): + """ Return associated table name""" + return self.table_name + + def handler(self, key, op, data): + """ + This method is executed on each add/remove event on the table. + :param key: key of the table entry + :param op: operation on the table entry. Could be either 'SET' or 'DEL' + :param data: associated data of the event. Empty for 'DEL' operation. + """ + if op == swsscommon.SET_COMMAND: + if self.directory.available_deps(self.deps): # all required dependencies are set in the Directory? + res = self.set_handler(key, data) + if not res: # set handler returned False, which means it is not ready to process is. Save it for later. + log_debug("'SET' handler returned NOT_READY for the Manager: %s" % self.__class__) + self.set_queue.append((key, data)) + else: + log_debug("Not all dependencies are met for the Manager: %s" % self.__class__) + self.set_queue.append((key, data)) + elif op == swsscommon.DEL_COMMAND: + self.del_handler(key) + else: + log_err("Invalid operation '%s' for key '%s'" % (op, key)) + + def on_deps_change(self): + """ This method is being executed on every dependency change """ + if not self.directory.available_deps(self.deps): + return + new_queue = [] + for key, data in self.set_queue: + res = self.set_handler(key, data) + if not res: + new_queue.append((key, data)) + self.set_queue = new_queue + + def set_handler(self, key, data): + """ Placeholder for 'SET' command """ + log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) + + def del_handler(self, key): + """ Placeholder for 'DEL' command """ + log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/vars.py b/src/sonic-bgpcfgd/app/vars.py index 11377fc87f93..18bee5578e25 100644 --- a/src/sonic-bgpcfgd/app/vars.py +++ b/src/sonic-bgpcfgd/app/vars.py @@ -1 +1 @@ -g_debug = False +g_debug = True # FIXME: read from env variable, or from constants diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd index 3bedd8679004..59dc35c25e21 100755 --- a/src/sonic-bgpcfgd/bgpcfgd +++ b/src/sonic-bgpcfgd/bgpcfgd @@ -15,10 +15,13 @@ import jinja2 import netaddr from swsscommon import swsscommon +from app.directory import Directory +from app.manager import Manager from app.vars import g_debug from app.log import log_debug, log_notice, log_info, log_warn, log_err, log_crit from app.template import TemplateFabric from app.config import ConfigMgr +from app.allow_list import BGPAllowListMgr from app.util import run_command g_run = True @@ -846,7 +849,7 @@ def wait_for_daemons(daemons, seconds): def read_constants(): """ Read file with constants values from /etc/sonic/constants.yml """ with open('/etc/sonic/constants.yml') as fp: - content = yaml.load(fp) + content = yaml.load(fp) # FIXME: , Loader=yaml.FullLoader) if "constants" not in content: log_crit("/etc/sonic/constants.yml doesn't have 'constants' key") raise Exception("/etc/sonic/constants.yml doesn't have 'constants' key") @@ -878,6 +881,8 @@ def main(): BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", True), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), + # AllowList Managers + BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), ] runner = Runner() for mgr in managers: diff --git a/src/sonic-bgpcfgd/pytest.ini b/src/sonic-bgpcfgd/pytest.ini new file mode 100644 index 000000000000..639ceb636af9 --- /dev/null +++ b/src/sonic-bgpcfgd/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = --cov=app --cov-report term diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index 29d441e09a66..fc0839dff7fc 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -16,5 +16,6 @@ ] }, install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], - setup_requires=['pytest-runner', 'pytest'], + setup_requires=['pytest-runner'], + test_requires=['pytest', 'pytest-cov'], ) diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json index 148456fe960f..08f1eef63267 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json @@ -4,5 +4,14 @@ "sub_role": "BackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32" -} \ No newline at end of file + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": true, + "default_action": "permit", + "drop_community": "12345:12345" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json index 53bf5572eff3..958c9b0fbd4b 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json @@ -4,5 +4,12 @@ "sub_role": "NotBackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32" -} \ No newline at end of file + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": false + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json new file mode 100644 index 000000000000..669810960c92 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json @@ -0,0 +1,17 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": true, + "default_action": "deny", + "drop_community": "12345:12345" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf index 1e3288b9a7da..9e6c32b17ead 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf @@ -1,6 +1,20 @@ ! ! template: bgpd/templates/general/policies.conf.j2 ! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community 12345:12345 additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community 12345:12345 additive +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf new file mode 100644 index 000000000000..6e0389fc1886 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf @@ -0,0 +1,39 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community no-export additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community no-export additive +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! +route-map FROM_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V4 permit 100 +! +route-map FROM_BGP_PEER_V6 permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +route-map FROM_BGP_PEER_V4_INT permit 2 + set originator-id 10.10.10.10 +! +route-map FROM_BGP_PEER_V6_INT permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6_INT permit 2 + set originator-id 10.10.10.10 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/test_allow_list.py b/src/sonic-bgpcfgd/tests/test_allow_list.py new file mode 100644 index 000000000000..196a28a1aa18 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_allow_list.py @@ -0,0 +1,469 @@ +from app.allow_list import BGPAllowListMgr +from app.directory import Directory +from app.template import TemplateFabric +import app +from mock import MagicMock + + +global_constants = { + "bgp": { + "allow_list": { + "enabled": True, + "default_pl_rules": { + "v4": [ "deny 0.0.0.0/0 le 17" ], + "v6": [ + "deny 0::/0 le 59", + "deny 0::/0 ge 65" + ] + } + } + } +} + +def set_del_test(op, args, currect_config, expected_config): + set_del_test.push_list_called = False + def push_list(args): + set_del_test.push_list_called = True + assert args == expected_config + return True + # + app.allow_list.run_command = lambda cmd: (0, "", "") + # + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.push_list = push_list + cfg_mgr.get_text.return_value = currect_config + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + if op == "SET": + mgr.set_handler(*args) + elif op == "DEL": + mgr.del_handler(*args) + else: + assert False, "Wrong operation" + if expected_config: + assert set_del_test.push_list_called, "cfg_mgr.push_list wasn't called" + else: + assert not set_del_test.push_list_called, "cfg_mgr.push_list was called" + +def test_set_handler_with_community(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + }), + [], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) + +def test_set_handler_no_community(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }), + [], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + ] + ) + +def test_del_handler_with_community(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'no bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) + +def test_del_handler_no_community(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + " " + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + ] + ) + +def test_set_handler_with_community_data_is_already_presented(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [] + ) + +def test_set_handler_no_community_data_is_already_presented(): + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.get_text.return_value = [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + "" + ] + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mgr.set_handler("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }) + assert not cfg_mgr.push_list.called, "cfg_mgr.push_list was called, but it shouldn't have been" + +def test_del_handler_with_community_no_data(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [""], + [] + ) + +def test_del_handler_no_community_no_data(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [""], + [] + ) + +def test_set_handler_with_community_update_prefixes_add(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16,80.90.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64,fc02::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [ + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 40 permit 80.90.0.0/16 ge 17', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 50 permit fc02::/64 ge 65', + ] + ) + +def test_set_handler_no_community_update_prefixes_add(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16,80.90.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64,fc02::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + "" + ], + [ + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 40 permit 80.90.0.0/16 ge 17', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 50 permit fc02::/64 ge 65', + ] + ) + +def test___set_handler_validate(): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + data = { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + } + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", None) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID1|5|1010:2020", data) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|z|1010:2020", data) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "20.20.30.0/24,40.50.0.0/16", + }) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "fc01:20::/64,fc01:30::/64", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }) + +def test___find_peer_group_by_deployment_id(): + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.get_text.return_value = [ + 'router bgp 64601', + ' neighbor BGPSLBPassive peer-group', + ' neighbor BGPSLBPassive remote-as 65432', + ' neighbor BGPSLBPassive passive', + ' neighbor BGPSLBPassive ebgp-multihop 255', + ' neighbor BGPSLBPassive update-source 10.1.0.32', + ' neighbor PEER_V4 peer-group', + ' neighbor PEER_V4_INT peer-group', + ' neighbor PEER_V6 peer-group', + ' neighbor PEER_V6_INT peer-group', + ' neighbor 10.0.0.1 remote-as 64802', + ' neighbor 10.0.0.1 peer-group PEER_V4', + ' neighbor 10.0.0.1 description ARISTA01T1', + ' neighbor 10.0.0.1 timers 3 10', + ' neighbor fc00::2 remote-as 64802', + ' neighbor fc00::2 peer-group PEER_V6', + ' neighbor fc00::2 description ARISTA01T1', + ' neighbor fc00::2 timers 3 10', + ' address-family ipv4 unicast', + ' neighbor BGPSLBPassive activate', + ' neighbor BGPSLBPassive soft-reconfiguration inbound', + ' neighbor BGPSLBPassive route-map FROM_BGP_SPEAKER in', + ' neighbor BGPSLBPassive route-map TO_BGP_SPEAKER out', + ' neighbor PEER_V4 soft-reconfiguration inbound', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4 route-map TO_BGP_PEER_V4 out', + ' neighbor PEER_V4_INT soft-reconfiguration inbound', + ' neighbor PEER_V4_INT allowas-in 1', + ' neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out', + ' neighbor 10.0.0.1 activate', + ' exit-address-family', + ' address-family ipv6 unicast', + ' neighbor BGPSLBPassive activate', + ' neighbor PEER_V6 soft-reconfiguration inbound', + ' neighbor PEER_V6 allowas-in 1', + ' neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6 route-map TO_BGP_PEER_V6 out', + ' neighbor PEER_V6_INT soft-reconfiguration inbound', + ' neighbor PEER_V6_INT allowas-in 1', + ' neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out', + ' neighbor fc00::2 activate', + ' exit-address-family', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 10', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535', + ' set community 5060:12345 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 10', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535', + ' set community 5060:12345 additive', + 'route-map FROM_BGP_PEER_V4 permit 100', + 'route-map FROM_BGP_PEER_V4 permit 2', + ' call ALLOW_LIST_DEPLOYMENT_ID_0_V4', + ' on-match next', + 'route-map FROM_BGP_PEER_V6 permit 1', + ' set ipv6 next-hop prefer-global ', + 'route-map FROM_BGP_PEER_V6 permit 100', + 'route-map FROM_BGP_PEER_V6 permit 2', + ' call ALLOW_LIST_DEPLOYMENT_ID_0_V6', + ' on-match next', + 'route-map FROM_BGP_SPEAKER permit 10', + 'route-map RM_SET_SRC permit 10', + ' set src 10.1.0.32', + 'route-map RM_SET_SRC6 permit 10', + ' set src FC00:1::32', + 'route-map TO_BGP_PEER_V4 permit 100', + 'route-map TO_BGP_PEER_V6 permit 100', + 'route-map TO_BGP_SPEAKER deny 1', + ] + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + values = mgr._BGPAllowListMgr__find_peer_group_by_deployment_id(0) + assert values == ['PEER_V4_INT', 'PEER_V6_INT', 'PEER_V6', 'PEER_V4'] + +def test___restart_peers_found_deployment_id(): + test___restart_peers_found_deployment_id.run_command_counter = 0 + def run_command(cmd): + output = [ + ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_1 soft in'], + ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_2 soft in'], + ] + desired_value = output[test___restart_peers_found_deployment_id.run_command_counter] + assert cmd == desired_value + test___restart_peers_found_deployment_id.run_command_counter += 1 + return 0, "", "" + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') + mocked.return_value = ["BGP_TEST_PEER_GROUP_1", "BGP_TEST_PEER_GROUP_2"] + mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked + app.allow_list.run_command = run_command + rc = mgr._BGPAllowListMgr__restart_peers(5) + assert rc + +def test___restart_peers_not_found_deployment_id(): + def run_command(cmd): + assert cmd == ['vtysh', '-c', 'clear bgp * soft in'] + return 0, "", "" + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') + mocked.return_value = [] + mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked + app.allow_list.run_command = run_command + rc = mgr._BGPAllowListMgr__restart_peers(5) + assert rc + +# FIXME: more testcases for coverage diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py index bc6d01cdb536..686b1ade65e1 100644 --- a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -77,21 +77,30 @@ def extract_rm_from_peer_group(path, peer_group_name): return list(rm_set) def check_routemap_in_file(filename, route_map_name): - route_map_re = re.compile(r'^route-map\s+%s\s+(\S+)' % route_map_name) + route_map_re = re.compile(r'^route-map\s+%s\s+permit\s+(\d+)' % route_map_name) set_re = re.compile(r'set ipv6 next-hop prefer-global') with open(filename) as fp: lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] - found_first_entry = False + found_entry = False + found_seq_no = None + route_map_entries = {} for line in lines: - err_msg = "route-map %s doesn't have mandatory 'set ipv6 next-hop prefer-global' entry as the first rule" % route_map_name - assert not (found_first_entry and line.startswith("route-map")), err_msg - if found_first_entry and set_re.match(line): - break # We're good + if found_entry: + route_map_entries[found_seq_no] = set_re.match(line) is not None + found_entry = False + found_seq_no = None if route_map_re.match(line): - err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name - assert route_map_re.match(line).group(1) == 'permit', err_msg - found_first_entry = True - return found_first_entry + found_seq_no = None + seq_n_txt = route_map_re.match(line).group(1) + assert seq_n_txt.isdigit(), "wrong sequence number for line '%s'" % line + found_seq_no = int(seq_n_txt) + assert found_seq_no not in route_map_entries, "Route-map has duplicate entries: %s - %d" % (route_map_name, found_seq_no) + found_entry = True + results = [route_map_entries[seq] for seq in sorted(route_map_entries.keys())] + if (len(results)): + err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name + assert results[0], err_msg + return len(results) > 0 def check_routemap(path, route_map_name): result_files = load_results(path, "policies.conf") diff --git a/src/sonic-bgpcfgd/tests/util.py b/src/sonic-bgpcfgd/tests/util.py index 0bc12b060aec..aa6c62a56b5f 100644 --- a/src/sonic-bgpcfgd/tests/util.py +++ b/src/sonic-bgpcfgd/tests/util.py @@ -5,7 +5,7 @@ def load_constants(): with open(CONSTANTS_PATH) as f: - data = yaml.load(f) + data = yaml.load(f) # FIXME" , Loader=yaml.FullLoader) result = {} assert "constants" in data, "'constants' key not found in constants.yml" assert "bgp" in data["constants"], "'bgp' key not found in constants.yml" @@ -13,4 +13,4 @@ def load_constants(): for name, value in data["constants"]["bgp"]["peers"].items(): assert "template_dir" in value, "'template_dir' key not found for peer '%s'" % name result[name] = value["template_dir"] - return result \ No newline at end of file + return result From e3f81596061e6a1a1419a4ce93601e8e0fa44afc Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Mon, 28 Sep 2020 02:31:45 +0800 Subject: [PATCH 1180/1427] [sonic_py_common] Fix exception in daemon_base.py (#5472) There is a syntax error (self is missing for log_info and log_warning) in signal_handler in daemon_base.py, which causes an exception --- src/sonic-py-common/sonic_py_common/daemon_base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/daemon_base.py b/src/sonic-py-common/sonic_py_common/daemon_base.py index 97bf3011b6e4..818be5fa4305 100644 --- a/src/sonic-py-common/sonic_py_common/daemon_base.py +++ b/src/sonic-py-common/sonic_py_common/daemon_base.py @@ -44,15 +44,15 @@ def __init__(self, log_identifier): # Default signal handler; can be overridden by subclass def signal_handler(self, sig, frame): if sig == signal.SIGHUP: - log_info("DaemonBase: Caught SIGHUP - ignoring...") + self.log_info("DaemonBase: Caught SIGHUP - ignoring...") elif sig == signal.SIGINT: - log_info("DaemonBase: Caught SIGINT - exiting...") + self.log_info("DaemonBase: Caught SIGINT - exiting...") sys.exit(128 + sig) elif sig == signal.SIGTERM: - log_info("DaemonBase: Caught SIGTERM - exiting...") + self.log_info("DaemonBase: Caught SIGTERM - exiting...") sys.exit(128 + sig) else: - log_warning("DaemonBase: Caught unhandled signal '{}'".format(sig)) + self.log_warning("DaemonBase: Caught unhandled signal '{}'".format(sig)) # Loads platform specific platform module from source def load_platform_util(self, module_name, class_name): From e412338743366969d2639f9e37943ae36e7271c7 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 28 Sep 2020 22:00:29 -0700 Subject: [PATCH 1181/1427] Revert "[bgp] Add 'allow list' manager feature (#5309)" This reverts commit 6eed0820c8014135e987d1615c14670b4d785f7f. --- .../bgpd/templates/general/peer-group.conf.j2 | 2 +- .../bgpd/templates/general/policies.conf.j2 | 27 - files/image_config/constants/constants.yml | 12 - rules/sonic_bgpcfgd.mk | 3 +- src/sonic-bgpcfgd/.gitignore | 1 - src/sonic-bgpcfgd/app/allow_list.py | 632 ------------------ src/sonic-bgpcfgd/app/config.py | 20 +- src/sonic-bgpcfgd/app/directory.py | 159 ----- src/sonic-bgpcfgd/app/manager.py | 71 -- src/sonic-bgpcfgd/app/vars.py | 2 +- src/sonic-bgpcfgd/bgpcfgd | 7 +- src/sonic-bgpcfgd/pytest.ini | 2 - src/sonic-bgpcfgd/setup.py | 3 +- .../data/general/policies.conf/param_all.json | 13 +- .../general/policies.conf/param_base.json | 11 +- .../general/policies.conf/param_deny.json | 17 - .../general/policies.conf/result_all.conf | 14 - .../general/policies.conf/result_deny.conf | 39 -- src/sonic-bgpcfgd/tests/test_allow_list.py | 469 ------------- .../tests/test_ipv6_nexthop_global.py | 29 +- src/sonic-bgpcfgd/tests/util.py | 4 +- 21 files changed, 22 insertions(+), 1515 deletions(-) delete mode 100644 src/sonic-bgpcfgd/app/allow_list.py delete mode 100644 src/sonic-bgpcfgd/app/directory.py delete mode 100644 src/sonic-bgpcfgd/app/manager.py delete mode 100644 src/sonic-bgpcfgd/pytest.ini delete mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json delete mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf delete mode 100644 src/sonic-bgpcfgd/tests/test_allow_list.py diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 index 5790d47a5a8a..b0acd1b2a460 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -24,7 +24,7 @@ {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V6 allowas-in 1 neighbor PEER_V6_INT allowas-in 1 -{% endif %} + {% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor PEER_V6_INT route-reflector-client {% endif %} diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 index 4c27db4a466a..c545cf272892 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -3,33 +3,6 @@ ! ! ! -{% if constants.bgp.allow_list is defined and constants.bgp.allow_list.enabled is defined and constants.bgp.allow_list.enabled %} -{% if constants.bgp.allow_list.default_action is defined and constants.bgp.allow_list.default_action.strip() == 'deny' %} -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 - set community no-export additive -! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 - set community no-export additive -{% else %} -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 - set community {{ constants.bgp.allow_list.drop_community }} additive -! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 - set community {{ constants.bgp.allow_list.drop_community }} additive -{% endif %} -! -route-map FROM_BGP_PEER_V4 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V4 - on-match next -! -route-map FROM_BGP_PEER_V6 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V6 - on-match next -! -{% endif %} -! -! -! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 074956ff8396..3e1b76be0157 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -18,18 +18,6 @@ constants: enabled: true ipv4: 64 ipv6: 64 - allow_list: - enabled: true - default_action: "permit" # or "deny" - drop_community: 5060:12345 # value of the community to identify a prefix to drop. Make sense only with allow_list_default_action equal to 'permit' - default_pl_rules: - v4: - - "deny 0.0.0.0/0 le 17" - - "permit 127.0.0.1/32" - v6: - - "deny 0::/0 le 59" - - "deny 0::/0 ge 65" - - "permit fe80::/64" peers: general: # peer_type db_table: "BGP_NEIGHBOR" diff --git a/rules/sonic_bgpcfgd.mk b/rules/sonic_bgpcfgd.mk index 7a9cae29cf19..32abbd5af948 100644 --- a/rules/sonic_bgpcfgd.mk +++ b/rules/sonic_bgpcfgd.mk @@ -6,7 +6,6 @@ $(SONIC_BGPCFGD)_SRC_PATH = $(SRC_PATH)/sonic-bgpcfgd # of sonic-config-engine and bgpcfgd explicitly calls sonic-cfggen # as part of its unit tests. # TODO: Refactor unit tests so that these dependencies are not needed -$(SONIC_BGPCFGD)_DEPENDS += $(SONIC_PY_COMMON_PY2) -$(SONIC_BGPCFGD)_DEBS_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) +$(SONIC_BGPCFGD)_DEPENDS += $(SWSSSDK_PY2) $(SONIC_PY_COMMON_PY2) $(SONIC_BGPCFGD)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_BGPCFGD) diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore index 920a1b3ae499..bb1ba531d1d6 100644 --- a/src/sonic-bgpcfgd/.gitignore +++ b/src/sonic-bgpcfgd/.gitignore @@ -6,4 +6,3 @@ app/*.pyc tests/*.pyc tests/__pycache__/ .idea -.coverage diff --git a/src/sonic-bgpcfgd/app/allow_list.py b/src/sonic-bgpcfgd/app/allow_list.py deleted file mode 100644 index 2637d6999244..000000000000 --- a/src/sonic-bgpcfgd/app/allow_list.py +++ /dev/null @@ -1,632 +0,0 @@ -""" -Implementation of "allow-list" feature -""" -import re - -from app.log import log_debug, log_info, log_err, log_warn -from app.template import TemplateFabric -from app.manager import Manager -from app.util import run_command - -class BGPAllowListMgr(Manager): - """ This class initialize "AllowList" settings """ - ALLOW_ADDRESS_PL_NAME_TMPL = "ALLOW_ADDRESS_%d_%s" # template for a name for the ALLOW_ADDRESS prefix-list ??? - EMPTY_COMMUNITY = "empty" - PL_NAME_TMPL = "PL_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s_V%s" - COMMUNITY_NAME_TMPL = "COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s" - RM_NAME_TMPL = "ALLOW_LIST_DEPLOYMENT_ID_%d_V%s" - ROUTE_MAP_ENTRY_WITH_COMMUNITY_START = 10 - ROUTE_MAP_ENTRY_WITH_COMMUNITY_END = 29990 - ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START = 30000 - ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END = 65530 - - V4 = "v4" # constant for af enum: V4 - V6 = "v6" # constant for af enum: V6 - - def __init__(self, common_objs, db, table): - """ - Initialize the object - :param common_objs: common object dictionary - :param db: name of the db - :param table: name of the table in the db - """ - super(BGPAllowListMgr, self).__init__( - common_objs, - [], - db, - table, - ) - self.cfg_mgr = common_objs["cfg_mgr"] - self.constants = common_objs["constants"] - self.key_re = re.compile(r"^DEPLOYMENT_ID\|\d+\|\S+$|^DEPLOYMENT_ID\|\d+$") - self.enabled = self.__get_enabled() - self.__load_constant_lists() - - def set_handler(self, key, data): - """ - Manager method which runs on receiving 'SET' message - :param key: ket of the 'SET' message - :param data: data of the 'SET' message - :return: True if the message was executed, False - the message should be postponed. - """ - if not self.enabled: - log_warn("BGPAllowListMgr::Received 'SET' command, but this feature is disabled in constants") - return True - if not self.__set_handler_validate(key, data): - return True - key = key.replace("DEPLOYMENT_ID|", "") - deployment_id, community_value = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) - deployment_id = int(deployment_id) - prefixes_v4 = [] - prefixes_v6 = [] - if "prefixes_v4" in data: - prefixes_v4 = str(data['prefixes_v4']).split(",") - if "prefixes_v6" in data: - prefixes_v6 = str(data['prefixes_v6']).split(",") - self.__update_policy(deployment_id, community_value, prefixes_v4, prefixes_v6) - return True - - def __set_handler_validate(self, key, data): - """ - Validate parameters of a "Set" message - :param key: ket of the 'SET' message - :param data: data of the 'SET' message - :return: True if parameters are valid, False if parameters are invalid - """ - if data is None: - log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message without data") - return False - if not self.key_re.match(key): - log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid key: '%s'" % key) - return False - prefixes_v4 = [] - prefixes_v6 = [] - if "prefixes_v4" in data: - prefixes_v4 = str(data["prefixes_v4"]).split(",") - if not all(TemplateFabric.is_ipv4(prefix) for prefix in prefixes_v4): - arguments = "prefixes_v4", str(data["prefixes_v4"]) - log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) - return False - if "prefixes_v6" in data: - prefixes_v6 = str(data["prefixes_v6"]).split(",") - if not all(TemplateFabric.is_ipv6(prefix) for prefix in prefixes_v6): - arguments = "prefixes_v6", str(data["prefixes_v6"]) - log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) - return False - if not prefixes_v4 and not prefixes_v6: - log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with no prefixes specified: %s" % str(data)) - return False - return True - - def del_handler(self, key): - """ - Manager method which runs on "DEL" message - :param key: a key of "DEL" message - """ - if not self.enabled: - log_warn("BGPAllowListMgr::Received 'DEL' command, but this feature is disabled in constants") - return - if not self.__del_handler_validate(key): - return - key = key.replace('DEPLOYMENT_ID|', '') - deployment_id, community = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) - deployment_id = int(deployment_id) - self.__remove_policy(deployment_id, community) - - def __del_handler_validate(self, key): - """ - Validate "DEL" method parameters - :param key: a key of "DEL" message - :return: True if parameters are valid, False if parameters are invalid - """ - if not self.key_re.match(key): - log_err("BGPAllowListMgr::Received BGP ALLOWED 'DEL' message with invalid key: '$s'" % key) - return False - return True - - def __update_policy(self, deployment_id, community_value, prefixes_v4, prefixes_v6): - """ - Update "allow list" policy with parameters - :param deployment_id: deployment id which policy will be changed - :param community_value: community value to match for the updated policy - :param prefixes_v4: a list of v4 prefixes for the updated policy - :param prefixes_v6: a list of v6 prefixes for the updated policy - """ - # update all related entries with the information - info = deployment_id, community_value, str(prefixes_v4), str(prefixes_v6) - msg = "BGPAllowListMgr::Updating 'Allow list' policy." - msg += " deployment_id '%s'. community: '%s'" - msg += " prefix_v4 '%s'. prefix_v6: '%s'" - log_info(msg % info) - names = self.__generate_names(deployment_id, community_value) - self.cfg_mgr.update() - cmds = [] - cmds += self.__update_prefix_list(self.V4, names['pl_v4'], prefixes_v4) - cmds += self.__update_prefix_list(self.V6, names['pl_v6'], prefixes_v6) - cmds += self.__update_community(names['community'], community_value) - cmds += self.__update_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) - cmds += self.__update_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) - if cmds: - rc = self.cfg_mgr.push_list(cmds) - rc = rc and self.__restart_peers(deployment_id) - log_debug("BGPAllowListMgr::__update_policy. The peers were updated: rc=%s" % rc) - else: - log_debug("BGPAllowListMgr::__update_policy. Nothing to update") - log_info("BGPAllowListMgr::Done") - - def __remove_policy(self, deployment_id, community_value): - """ - Remove "allow list" policy for given deployment_id and community_value - :param deployment_id: deployment id which policy will be removed - :param community_value: community value to match for the removed policy - """ - # remove all related entries from the configuration - # put default rule to the route-map - info = deployment_id, community_value - msg = "BGPAllowListMgr::Removing 'Allow list' policy." - msg += " deployment_id '%s'. community: '%s'" - log_info(msg % info) - - names = self.__generate_names(deployment_id, community_value) - self.cfg_mgr.update() - cmds = [] - cmds += self.__remove_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) - cmds += self.__remove_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) - cmds += self.__remove_prefix_list(self.V4, names['pl_v4']) - cmds += self.__remove_prefix_list(self.V6, names['pl_v6']) - cmds += self.__remove_community(names['community']) - if cmds: - rc = self.cfg_mgr.push_list(cmds) - rc = rc and self.__restart_peers(deployment_id) - log_debug("BGPAllowListMgr::__remove_policy. 'Allow list' policy was removed. rc:%s" % rc) - else: - log_debug("BGPAllowListMgr::__remove_policy. Nothing to remove") - log_info('BGPAllowListMgr::Done') - - @staticmethod - def __generate_names(deployment_id, community_value): - """ - Generate prefix-list names for a given peer_ip and community value - :param deployment_id: deployment_id for which we're going to filter prefixes - :param community_value: community, which we want to use to filter prefixes - :return: a dictionary with names - """ - if community_value == BGPAllowListMgr.EMPTY_COMMUNITY: - community_name = BGPAllowListMgr.EMPTY_COMMUNITY - else: - community_name = BGPAllowListMgr.COMMUNITY_NAME_TMPL % (deployment_id, community_value) - names = { - "pl_v4": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '4'), - "pl_v6": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '6'), - "rm_v4": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '4'), - "rm_v6": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '6'), - "community": community_name, - } - arguments = deployment_id, community_value, str(names) - log_debug("BGPAllowListMgr::__generate_names. deployment_id: %d, community: %s. names: %s" % arguments) - return names - - def __update_prefix_list(self, af, pl_name, allow_list): - """ - Create or update a prefix-list with name pl_name. - :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list - :param pl_name: prefix-list name - :param allow_list: prefix-list entries - :return: True if updating was successful, False otherwise - """ - assert af == self.V4 or af == self.V6 - constant_list = self.__get_constant_list(af) - allow_list = self.__to_prefix_list(allow_list) - log_debug("BGPAllowListMgr::__update_prefix_list. af='%s' prefix-list name=%s" % (af, pl_name)) - exist, correct = self.__is_prefix_list_valid(af, pl_name, allow_list, constant_list) - if correct: - log_debug("BGPAllowListMgr::__update_prefix_list. the prefix-list '%s' exists and correct" % pl_name) - return [] - family = self.__af_to_family(af) - cmds = [] - seq_no = 10 - if exist: - cmds.append('no %s prefix-list %s' % (family, pl_name)) - for entry in constant_list + allow_list: - cmds.append('%s prefix-list %s seq %d %s' % (family, pl_name, seq_no, entry)) - seq_no += 10 - return cmds - - def __remove_prefix_list(self, af, pl_name): - """ - Remove prefix-list in the address-family af. - :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list - :param pl_name: list of prefix-list names - :return: True if operation was successful, False otherwise - """ - assert af == self.V4 or af == self.V6 - log_debug("BGPAllowListMgr::__remove_prefix_lists. af='%s' pl_names='%s'" % (af, pl_name)) - exist, _ = self.__is_prefix_list_valid(af, pl_name, [], []) - if not exist: - log_debug("BGPAllowListMgr::__remove_prefix_lists: prefix_list '%s' not found" % pl_name) - return [] - family = self.__af_to_family(af) - return ["no %s prefix-list %s" % (family, pl_name)] - - def __is_prefix_list_valid(self, af, pl_name, allow_list, constant_list): - """ - Check that a prefix list exists and it has valid entries - :param af: address family of the checked prefix-list - :param pl_name: prefix-list name - :param allow_list: a prefix-list which must be a part of the valid prefix list - :param constant_list: a constant list which must be on top of each "allow" prefix list on the device - :return: a tuple. The first element of the tuple has True if the prefix-list exists, False otherwise, - The second element of the tuple has True if the prefix-list contains correct entries, False if not - """ - assert af == self.V4 or af == self.V6 - family = self.__af_to_family(af) - match_string = '%s prefix-list %s seq ' % (family, pl_name) - conf = self.cfg_mgr.get_text() - if not any(line.strip().startswith(match_string) for line in conf): - return False, False # if the prefix list is not exists, it is not correct - constant_set = set(constant_list) - allow_set = set(allow_list) - for line in conf: - if line.startswith(match_string): - found = line[len(match_string):].strip().split(' ') - rule = " ".join(found[1:]) - if rule in constant_set: - constant_set.discard(rule) - elif rule in allow_set: - if constant_set: - return True, False # Not everything from constant set is presented - else: - allow_set.discard(rule) - return True, len(allow_set) == 0 # allow_set should be presented all - - def __update_community(self, community_name, community_value): - """ - Update community for a peer - :param community_name: name of the community to update - :param community_value: community value for the peer - :return: True if operation was successful, False otherwise - """ - log_debug("BGPAllowListMgr::__update_community. community_name='%s' community='%s'" % (community_name, community_value)) - if community_value == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community - log_debug("BGPAllowListMgr::__update_community. Empty community. exiting") - return [] - cmds = [] - exists, found_community_value = self.__is_community_presented(community_name) - if exists: - if community_value == found_community_value: - log_debug("BGPAllowListMgr::__update_community. community '%s' is already presented" % community_name) - return [] - else: - msg = "BGPAllowListMgr::__update_community. " - msg += "community '%s' is already presented, but community value should be updated" % community_name - log_debug(msg) - cmds.append("no bgp community-list standard %s" % community_name) - cmds.append('bgp community-list standard %s permit %s' % (community_name, community_value)) - return cmds - - def __remove_community(self, community_name): - """ - Remove community for a peer - :param community_name: community value for the peer - :return: True if operation was successful, False otherwise - """ - log_debug("BGPAllowListMgr::__remove_community. community='%s'" % community_name) - if community_name == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community - log_debug("BGPAllowListMgr::__remove_community. There is nothing to remove in empty community") - return [] - exists, _ = self.__is_community_presented(community_name) - if not exists: - log_debug("BGPAllowListMgr::__remove_community. Community is already removed.") - return [] - return ['no bgp community-list standard %s' % community_name] - - def __is_community_presented(self, community_name): - """ - Return True if community for the peer_ip exists - :param community_name: community value for the peer - :return: A tuple. First element: True if operation was successful, False otherwise - Second element: community value if the first element is True no value otherwise - """ - log_debug("BGPAllowListMgr::__is_community_presented. community='%s'" % community_name) - match_string = 'bgp community-list standard %s permit ' % community_name - conf = self.cfg_mgr.get_text() - found = [line.strip() for line in conf if line.strip().startswith(match_string)] - if not found: - return False, None - community_value = found[0].replace(match_string, '') - return True, community_value - - def __update_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): - """ - Add or update a "Allow address" route-map entry with the parameters - :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list - :return: True if operation was successful, False otherwise - """ - assert af == self.V4 or af == self.V6 - info = af, route_map_name, allow_address_pl_name, community_name - log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) - entries = self.__parse_allow_route_map_entries(af, route_map_name) - found, _ = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) - if found: - log_debug("BGPAllowListMgr::__update_allow_route_map_entry. route-map='%s' is already found" % route_map_name) - return [] - seq_number = self.__find_next_seq_number(entries.keys(), community_name != self.EMPTY_COMMUNITY, route_map_name) - info = af, seq_number, allow_address_pl_name, community_name - out = "af='%s' seqno='%d' Allow pl='%s' cl='%s'" % info - log_debug("BGPAllowListMgr::__update_allow_route_map_entry. %s" % out) - ip_version = "" if af == self.V4 else "v6" - cmds = [ - 'route-map %s permit %d' % (route_map_name, seq_number), - ' match ip%s address prefix-list %s' % (ip_version, allow_address_pl_name) - ] - if not community_name.endswith(self.EMPTY_COMMUNITY): - cmds.append(" match community %s" % community_name) - return cmds - - def __remove_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): - """ - Add or update a "Allow address" route-map entry with the parameters - :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list - :return: True if operation was successful, False otherwise - """ - assert af == self.V4 or af == self.V6 - info = af, route_map_name, allow_address_pl_name, community_name - log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) - entries = self.__parse_allow_route_map_entries(af, route_map_name) - found, seq_number = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) - if not found: - log_debug("BGPAllowListMgr::__update_allow_route_map_entry. Not found route-map '%s' entry" % allow_address_pl_name) - return [] - return ['no route-map %s permit %d' % (route_map_name, seq_number)] - - @staticmethod - def __find_route_map_entry(entries, allow_address_pl_name, community_name): - """ - Find route-map entry with given allow_address prefix list name and community name in the parsed route-map. - :param entries: entries of parsed route-map - :param allow_address_pl_name: name of the "allow address" prefix-list - :param community_name: name of the "allow address" community name - :return: a tuple. The first element of the tuple is True, if the route-map entry was found, False otherwise. - The second element of the tuple has a sequence number of the entry. - """ - for sequence_number, values in entries.items(): - if sequence_number == 65535: - continue - allow_list_presented = values['pl_allow_list'] == allow_address_pl_name - community_presented = values['community'] == community_name - if allow_list_presented and community_presented: - log_debug("BGPAllowListMgr::__find_route_map_entry. found route-map '%s' entry" % allow_address_pl_name) - return True, sequence_number - return False, None - - def __parse_allow_route_map_entries(self, af, route_map_name): - """ - Parse "Allow list" route-map entries. - :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list - :return: A tuple, First element: True if operation was successful, False otherwise - Second element: list of object with parsed route-map entries - """ - assert af == self.V4 or af == self.V6 - log_debug("BGPAllowListMgr::__parse_allow_route_map_entries. af='%s', rm='%s'" % (af, route_map_name)) - match_string = 'route-map %s permit ' % route_map_name - entries = {} - inside_route_map = False - route_map_seq_number = None - pl_allow_list_name = None - community_name = self.EMPTY_COMMUNITY - if af == self.V4: - match_pl_allow_list = 'match ip address prefix-list ' - else: # self.V6 - match_pl_allow_list = 'match ipv6 address prefix-list ' - match_community = 'match community ' - conf = self.cfg_mgr.get_text() - for line in conf + [""]: - if inside_route_map: - if line.strip().startswith(match_pl_allow_list): - pl_allow_list_name = line.strip()[len(match_pl_allow_list):] - continue - elif line.strip().startswith(match_community): - community_name = line.strip()[len(match_community):] - continue - else: - if pl_allow_list_name is not None: - entries[route_map_seq_number] = { - 'pl_allow_list': pl_allow_list_name, - 'community': community_name, - } - else: - if route_map_seq_number != 65535: - log_warn("BGPAllowListMgr::Found incomplete route-map '%s' entry. seq_no=%d" % (route_map_name, route_map_seq_number)) - inside_route_map = False - pl_allow_list_name = None - community_name = self.EMPTY_COMMUNITY - route_map_seq_number = None - if line.startswith(match_string): - found = line[len(match_string):] - assert found.isdigit() - route_map_seq_number = int(found) - inside_route_map = True - return entries - - @staticmethod - def __find_next_seq_number(seq_numbers, has_community, route_map_name): - """ - Find a next available "Allow list" route-map entry number - :param seq_numbers: a list of already used sequence numbers - :param has_community: True, if the route-map entry has community - :return: next available route-map sequence number - """ - used_sequence_numbers = set(seq_numbers) - sequence_number = None - if has_community: # put entries without communities after 29999 - start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_START - end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_END - else: - start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START - end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END - for i in range(start_seq, end_seq, 10): - if i not in used_sequence_numbers: - sequence_number = i - break - if sequence_number is None: - raise RuntimeError("No free sequence numbers for '%s'" % route_map_name) - info = sequence_number, "yes" if has_community else "no" - log_debug("BGPAllowListMgr::__find_next_seq_number '%d' has_community='%s'" % info) - return sequence_number - - def __extract_peer_group_names(self): - """ - Extract names of all peer-groups defined in the config - :return: list of peer-group names - """ - # Find all peer-groups entries - re_peer_group = re.compile(r'^\s*neighbor (\S+) peer-group$') - peer_groups = [] - for line in self.cfg_mgr.get_text(): - result = re_peer_group.match(line) - if result: - peer_groups.append(result.group(1)) - return peer_groups - - def __get_peer_group_to_route_map(self, peer_groups): - """ - Extract names of route-maps which is connected to peer-groups defines as peer_groups - :peer_groups: a list of peer-group names - :return: dictionary where key is a peer-group, value is a route-map name which is defined as route-map in - for the peer_group. - """ - pg_2_rm = {} - for pg in peer_groups: - re_peer_group_rm = re.compile(r'^\s*neighbor %s route-map (\S+) in$' % pg) - for line in self.cfg_mgr.get_text(): - result = re_peer_group_rm.match(line) - if result: - pg_2_rm[pg] = result.group(1) - break - return pg_2_rm - - def __get_route_map_calls(self, rms): - """ - Find mapping between route-maps and route-map call names, defined for the route-maps - :rms: a set with route-map names - :return: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map - """ - rm_2_call = {} - re_rm = re.compile(r'^route-map (\S+) permit \d+$') - re_call = re.compile(r'^\s*call (\S+)$') - inside_name = None - for line in self.cfg_mgr.get_text(): - if inside_name: - inside_result = re_call.match(line) - if inside_result: - rm_2_call[inside_name] = inside_result.group(1) - inside_name = None - continue - result = re_rm.match(line) - if not result: - continue - inside_name = None - if result.group(1) not in rms: - continue - inside_name = result.group(1) - return rm_2_call - - def __get_peer_group_to_restart(self, deployment_id, pg_2_rm, rm_2_call): - """ - Get peer_groups which are assigned to deployment_id - :deployment_id: deployment_id number - :pg_2_rm: a dictionary where key is a peer-group, value is a route-map name which is defined as route-map in - for the peer_group. - :rm_2_call: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map - """ - ret = set() - target_allow_list_prefix = 'ALLOW_LIST_DEPLOYMENT_ID_%d_V' % deployment_id - for peer_group, route_map in pg_2_rm.items(): - if route_map in rm_2_call: - if rm_2_call[route_map].startswith(target_allow_list_prefix): - ret.add(peer_group) - return list(ret) - - def __find_peer_group_by_deployment_id(self, deployment_id): - """ - Deduce peer-group names which are connected to devices with requested deployment_id - :param deployment_id: deployment_id number - :return: a list of peer-groups which a used by devices with requested deployment_id number - """ - self.cfg_mgr.update() - peer_groups = self.__extract_peer_group_names() - pg_2_rm = self.__get_peer_group_to_route_map(peer_groups) - rm_2_call = self.__get_route_map_calls(set(pg_2_rm.values())) - ret = self.__get_peer_group_to_restart(deployment_id, pg_2_rm, rm_2_call) - return list(ret) - - def __restart_peers(self, deployment_id): - """ - Restart peer-groups with requested deployment_id - :param deployment_id: deployment_id number - """ - log_info("BGPAllowListMgr::Restart peers with deployment_id=%d" % deployment_id) - peer_groups = self.__find_peer_group_by_deployment_id(deployment_id) - rv = True - if peer_groups: - for peer_group in peer_groups: - no_error, _, _ = run_command(["vtysh", "-c", "clear bgp peer-group %s soft in" % peer_group]) - rv = no_error == 0 and rv - else: - no_error, _, _ = run_command(["vtysh", "-c", "clear bgp * soft in"]) - rv = no_error == 0 - return rv - - def __get_enabled(self): - """ - Load enable/disabled property from constants - :return: True if enabled, False otherwise - """ - return 'bgp' in self.constants \ - and 'allow_list' in self.constants["bgp"] \ - and "enabled" in self.constants["bgp"]["allow_list"] \ - and self.constants["bgp"]["allow_list"]["enabled"] - - def __load_constant_lists(self): - """ - Load default prefix-list entries from constants.yml file - """ - if 'bgp' in self.constants and 'allow_list' in self.constants["bgp"] \ - and "default_pl_rules" in self.constants["bgp"]["allow_list"]: - obj = self.constants["bgp"]["allow_list"]["default_pl_rules"] - if "v4" in obj: - self.constants_v4 = obj["v4"] - else: - self.constants_v4 = [] - if "v6" in obj: - self.constants_v6 = obj["v6"] - else: - self.constants_v6 = [] - - def __get_constant_list(self, af): - """ - Return loaded default prefix-list entries bases on address family - :param af: address family - :return: default prefix-list entries - """ - if af == self.V4: - return self.constants_v4 - else: - return self.constants_v6 - - @staticmethod - def __to_prefix_list(allow_list): - """ - Convert "allow list" prefix list, to a prefix-list rules - :param allow_list: "allow list" prefix list - :return: prefix-list rules - """ - return ["permit %s ge %d" % (prefix, int(prefix.split("/")[1])+1) for prefix in allow_list] - - def __af_to_family(self, af): - """ - Convert address family into prefix list family - :param af: address family - :return: prefix list ip family - """ - return 'ip' if af == self.V4 else 'ipv6' diff --git a/src/sonic-bgpcfgd/app/config.py b/src/sonic-bgpcfgd/app/config.py index a0c1329f832e..26639fe75e89 100644 --- a/src/sonic-bgpcfgd/app/config.py +++ b/src/sonic-bgpcfgd/app/config.py @@ -10,33 +10,19 @@ class ConfigMgr(object): """ The class represents frr configuration """ def __init__(self): self.current_config = None - self.current_config_raw = None def reset(self): """ Reset stored config """ self.current_config = None - self.current_config_raw = None def update(self): """ Read current config from FRR """ self.current_config = None - self.current_config_raw = None ret_code, out, err = run_command(["vtysh", "-c", "show running-config"]) if ret_code != 0: - # FIXME: should we throw exception here? log_crit("can't update running config: rc=%d out='%s' err='%s'" % (ret_code, out, err)) return - text = [] - for line in out.split('\n'): - if line.lstrip().startswith('!'): - continue - text.append(line) - text += [" "] # Add empty line to have something to work on, if there is no text - self.current_config_raw = text - self.current_config = self.to_canonical(out) # FIXME: use test as an input - - def push_list(self, cmdlist): - return self.push("\n".join(cmdlist)) + self.current_config = self.to_canonical(out) def push(self, cmd): """ @@ -65,12 +51,8 @@ def write(self, cmd): log_err("ConfigMgr::push(): can't push configuration '%s', rc='%d', stdout='%s', stderr='%s'" % err_tuple) if ret_code == 0: self.current_config = None # invalidate config - self.current_config_raw = None return ret_code == 0 - def get_text(self): - return self.current_config_raw - @staticmethod def to_canonical(raw_config): """ diff --git a/src/sonic-bgpcfgd/app/directory.py b/src/sonic-bgpcfgd/app/directory.py deleted file mode 100644 index d27ec64256e3..000000000000 --- a/src/sonic-bgpcfgd/app/directory.py +++ /dev/null @@ -1,159 +0,0 @@ -from collections import defaultdict - -from app.log import log_err - - -class Directory(object): - """ This class stores values and notifies callbacks which were registered to be executed as soon - as some value is changed. This class works as DB cache mostly """ - def __init__(self): - self.data = defaultdict(dict) # storage. A key is a slot name, a value is a dictionary with data - self.notify = defaultdict(lambda: defaultdict(list)) # registered callbacks: slot -> path -> handlers[] - - @staticmethod - def get_slot_name(db, table): - """ Convert db, table pair into a slot name """ - return db + "__" + table - - def path_traverse(self, slot, path): - """ - Traverse a path in the storage. - If the path is an empty string, it returns a value as it is. - If the path is not an empty string, the method will traverse through the dictionary value. - Example: - self.data["key_1"] = { "abc": { "cde": { "fgh": "val_1", "ijk": "val_2" } } } - self.path_traverse("key_1", "abc/cde") will return True, { "fgh": "val_1", "ijk": "val_2" } - :param slot: storage key - :param path: storage path as a string where each internal key is separated by '/' - :return: a pair: True if the path was found, object if it was found - """ - if slot not in self.data: - return False, None - elif path == '': - return True, self.data[slot] - d = self.data[slot] - for p in path.split("/"): - if p not in d: - return False, None - d = d[p] - return True, d - - def path_exist(self, db, table, path): - """ - Check if the path exists in the storage - :param db: db name - :param table: table name - :param path: requested path - :return: True if the path is available, False otherwise - """ - slot = self.get_slot_name(db, table) - return self.path_traverse(slot, path)[0] - - def get_path(self, db, table, path): - """ - Return the requested path from the storage - :param db: db name - :param table: table name - :param path: requested path - :return: object if the path was found, None otherwise - """ - slot = self.get_slot_name(db, table) - return self.path_traverse(slot, path)[1] - - def put(self, db, table, key, value): - """ - Put information into the storage. Notify handlers which are dependant to the information - :param db: db name - :param table: table name - :param key: key to change - :param value: value to put - :return: - """ - slot = self.get_slot_name(db, table) - self.data[slot][key] = value - if slot in self.notify: - for path in self.notify[slot].keys(): - if self.path_exist(db, table, path): - for handler in self.notify[slot][path]: - handler() - - def get(self, db, table, key): - """ - Get a value from the storage - :param db: db name - :param table: table name - :param key: ket to get - :return: value for the key - """ - slot = self.get_slot_name(db, table) - return self.data[slot][key] - - def get_slot(self, db, table): - """ - Get an object from the storage - :param db: db name - :param table: table name - :return: object for the slot - """ - slot = self.get_slot_name(db, table) - return self.data[slot] - - def remove(self, db, table, key): - """ - Remove a value from the storage - :param db: db name - :param table: table name - :param key: key to remove - """ - slot = self.get_slot_name(db, table) - if slot in self.data: - if key in self.data[slot]: - del self.data[slot][key] - else: - log_err("Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) - else: - log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) - - def remove_slot(self, db, table): - """ - Remove an object from the storage - :param db: db name - :param table: table name - """ - slot = self.get_slot_name(db, table) - if slot in self.data: - del self.data[slot] - else: - log_err("Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) - - def available(self, db, table): - """ - Check if the table is available - :param db: db name - :param table: table name - :return: True if the slot is available, False if not - """ - slot = self.get_slot_name(db, table) - return slot in self.data - - def available_deps(self, deps): - """ - Check if all items from the deps list is available in the storage - :param deps: list of dependencies - :return: True if all dependencies are presented, False otherwise - """ - res = True - for db, table, path in deps: - res = res and self.path_exist(db, table, path) - return res - - def subscribe(self, deps, handler): - """ - Subscribe the handler to be run as soon as all dependencies are presented - :param deps: - :param handler: - :return: - """ - for db, table, path in deps: - slot = self.get_slot_name(db, table) - self.notify[slot][path].append(handler) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/manager.py b/src/sonic-bgpcfgd/app/manager.py deleted file mode 100644 index ba45029b5120..000000000000 --- a/src/sonic-bgpcfgd/app/manager.py +++ /dev/null @@ -1,71 +0,0 @@ -from swsscommon import swsscommon - -from app.log import log_debug, log_err - - -class Manager(object): - """ This class represents a SONiC DB table """ - def __init__(self, common_objs, deps, database, table_name): - """ - Initialize class - :param common_objs: common object dictionary - :param deps: dependencies list - :param database: database name - :param table_name: table name - """ - self.directory = common_objs['directory'] - self.cfg_mgr = common_objs['cfg_mgr'] - self.constants = common_objs['constants'] - self.deps = deps - self.db_name = database - self.table_name = table_name - self.set_queue = [] - self.directory.subscribe(deps, self.on_deps_change) # subscribe this class method on directory changes - - def get_database(self): - """ Return associated database """ - return self.db_name - - def get_table_name(self): - """ Return associated table name""" - return self.table_name - - def handler(self, key, op, data): - """ - This method is executed on each add/remove event on the table. - :param key: key of the table entry - :param op: operation on the table entry. Could be either 'SET' or 'DEL' - :param data: associated data of the event. Empty for 'DEL' operation. - """ - if op == swsscommon.SET_COMMAND: - if self.directory.available_deps(self.deps): # all required dependencies are set in the Directory? - res = self.set_handler(key, data) - if not res: # set handler returned False, which means it is not ready to process is. Save it for later. - log_debug("'SET' handler returned NOT_READY for the Manager: %s" % self.__class__) - self.set_queue.append((key, data)) - else: - log_debug("Not all dependencies are met for the Manager: %s" % self.__class__) - self.set_queue.append((key, data)) - elif op == swsscommon.DEL_COMMAND: - self.del_handler(key) - else: - log_err("Invalid operation '%s' for key '%s'" % (op, key)) - - def on_deps_change(self): - """ This method is being executed on every dependency change """ - if not self.directory.available_deps(self.deps): - return - new_queue = [] - for key, data in self.set_queue: - res = self.set_handler(key, data) - if not res: - new_queue.append((key, data)) - self.set_queue = new_queue - - def set_handler(self, key, data): - """ Placeholder for 'SET' command """ - log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) - - def del_handler(self, key): - """ Placeholder for 'DEL' command """ - log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/vars.py b/src/sonic-bgpcfgd/app/vars.py index 18bee5578e25..11377fc87f93 100644 --- a/src/sonic-bgpcfgd/app/vars.py +++ b/src/sonic-bgpcfgd/app/vars.py @@ -1 +1 @@ -g_debug = True # FIXME: read from env variable, or from constants +g_debug = False diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd index 59dc35c25e21..3bedd8679004 100755 --- a/src/sonic-bgpcfgd/bgpcfgd +++ b/src/sonic-bgpcfgd/bgpcfgd @@ -15,13 +15,10 @@ import jinja2 import netaddr from swsscommon import swsscommon -from app.directory import Directory -from app.manager import Manager from app.vars import g_debug from app.log import log_debug, log_notice, log_info, log_warn, log_err, log_crit from app.template import TemplateFabric from app.config import ConfigMgr -from app.allow_list import BGPAllowListMgr from app.util import run_command g_run = True @@ -849,7 +846,7 @@ def wait_for_daemons(daemons, seconds): def read_constants(): """ Read file with constants values from /etc/sonic/constants.yml """ with open('/etc/sonic/constants.yml') as fp: - content = yaml.load(fp) # FIXME: , Loader=yaml.FullLoader) + content = yaml.load(fp) if "constants" not in content: log_crit("/etc/sonic/constants.yml doesn't have 'constants' key") raise Exception("/etc/sonic/constants.yml doesn't have 'constants' key") @@ -881,8 +878,6 @@ def main(): BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", True), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), - # AllowList Managers - BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), ] runner = Runner() for mgr in managers: diff --git a/src/sonic-bgpcfgd/pytest.ini b/src/sonic-bgpcfgd/pytest.ini deleted file mode 100644 index 639ceb636af9..000000000000 --- a/src/sonic-bgpcfgd/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -addopts = --cov=app --cov-report term diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index fc0839dff7fc..29d441e09a66 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -16,6 +16,5 @@ ] }, install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], - setup_requires=['pytest-runner'], - test_requires=['pytest', 'pytest-cov'], + setup_requires=['pytest-runner', 'pytest'], ) diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json index 08f1eef63267..148456fe960f 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json @@ -4,14 +4,5 @@ "sub_role": "BackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32", - "constants": { - "bgp": { - "allow_list": { - "enabled": true, - "default_action": "permit", - "drop_community": "12345:12345" - } - } - } -} + "loopback0_ipv4": "10.10.10.10/32" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json index 958c9b0fbd4b..53bf5572eff3 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json @@ -4,12 +4,5 @@ "sub_role": "NotBackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32", - "constants": { - "bgp": { - "allow_list": { - "enabled": false - } - } - } -} + "loopback0_ipv4": "10.10.10.10/32" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json deleted file mode 100644 index 669810960c92..000000000000 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "CONFIG_DB__DEVICE_METADATA": { - "localhost": { - "sub_role": "BackEnd" - } - }, - "loopback0_ipv4": "10.10.10.10/32", - "constants": { - "bgp": { - "allow_list": { - "enabled": true, - "default_action": "deny", - "drop_community": "12345:12345" - } - } - } -} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf index 9e6c32b17ead..1e3288b9a7da 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf @@ -1,20 +1,6 @@ ! ! template: bgpd/templates/general/policies.conf.j2 ! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 - set community 12345:12345 additive -! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 - set community 12345:12345 additive -! -route-map FROM_BGP_PEER_V4 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V4 - on-match next -! -route-map FROM_BGP_PEER_V6 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V6 - on-match next -! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf deleted file mode 100644 index 6e0389fc1886..000000000000 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf +++ /dev/null @@ -1,39 +0,0 @@ -! -! template: bgpd/templates/general/policies.conf.j2 -! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 - set community no-export additive -! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 - set community no-export additive -! -route-map FROM_BGP_PEER_V4 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V4 - on-match next -! -route-map FROM_BGP_PEER_V6 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V6 - on-match next -! -route-map FROM_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map FROM_BGP_PEER_V6 permit 1 - set ipv6 next-hop prefer-global -! -route-map FROM_BGP_PEER_V6 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -route-map FROM_BGP_PEER_V4_INT permit 2 - set originator-id 10.10.10.10 -! -route-map FROM_BGP_PEER_V6_INT permit 1 - set ipv6 next-hop prefer-global -! -route-map FROM_BGP_PEER_V6_INT permit 2 - set originator-id 10.10.10.10 -! -! end of template: bgpd/templates/general/policies.conf.j2 -! diff --git a/src/sonic-bgpcfgd/tests/test_allow_list.py b/src/sonic-bgpcfgd/tests/test_allow_list.py deleted file mode 100644 index 196a28a1aa18..000000000000 --- a/src/sonic-bgpcfgd/tests/test_allow_list.py +++ /dev/null @@ -1,469 +0,0 @@ -from app.allow_list import BGPAllowListMgr -from app.directory import Directory -from app.template import TemplateFabric -import app -from mock import MagicMock - - -global_constants = { - "bgp": { - "allow_list": { - "enabled": True, - "default_pl_rules": { - "v4": [ "deny 0.0.0.0/0 le 17" ], - "v6": [ - "deny 0::/0 le 59", - "deny 0::/0 ge 65" - ] - } - } - } -} - -def set_del_test(op, args, currect_config, expected_config): - set_del_test.push_list_called = False - def push_list(args): - set_del_test.push_list_called = True - assert args == expected_config - return True - # - app.allow_list.run_command = lambda cmd: (0, "", "") - # - cfg_mgr = MagicMock() - cfg_mgr.update.return_value = None - cfg_mgr.push_list = push_list - cfg_mgr.get_text.return_value = currect_config - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - if op == "SET": - mgr.set_handler(*args) - elif op == "DEL": - mgr.del_handler(*args) - else: - assert False, "Wrong operation" - if expected_config: - assert set_del_test.push_list_called, "cfg_mgr.push_list wasn't called" - else: - assert not set_del_test.push_list_called, "cfg_mgr.push_list was called" - -def test_set_handler_with_community(): - set_del_test( - "SET", - ("DEPLOYMENT_ID|5|1010:2020", { - "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", - "prefixes_v6": "fc00:20::/64,fc00:30::/64", - }), - [], - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', - 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - ] - ) - -def test_set_handler_no_community(): - set_del_test( - "SET", - ("DEPLOYMENT_ID|5", { - "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", - "prefixes_v6": "fc01:20::/64,fc01:30::/64", - }), - [], - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - ] - ) - -def test_del_handler_with_community(): - set_del_test( - "DEL", - ("DEPLOYMENT_ID|5|1010:2020",), - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', - 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - "" - ], - [ - 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', - 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', - 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - 'no bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - ] - ) - -def test_del_handler_no_community(): - set_del_test( - "DEL", - ("DEPLOYMENT_ID|5",), - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - " " - ], - [ - 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', - 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', - 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - ] - ) - -def test_set_handler_with_community_data_is_already_presented(): - set_del_test( - "SET", - ("DEPLOYMENT_ID|5|1010:2020", { - "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", - "prefixes_v6": "fc00:20::/64,fc00:30::/64", - }), - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', - 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - "" - ], - [] - ) - -def test_set_handler_no_community_data_is_already_presented(): - cfg_mgr = MagicMock() - cfg_mgr.update.return_value = None - cfg_mgr.get_text.return_value = [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - "" - ] - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - mgr.set_handler("DEPLOYMENT_ID|5", { - "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", - "prefixes_v6": "fc01:20::/64,fc01:30::/64", - }) - assert not cfg_mgr.push_list.called, "cfg_mgr.push_list was called, but it shouldn't have been" - -def test_del_handler_with_community_no_data(): - set_del_test( - "DEL", - ("DEPLOYMENT_ID|5|1010:2020",), - [""], - [] - ) - -def test_del_handler_no_community_no_data(): - set_del_test( - "DEL", - ("DEPLOYMENT_ID|5",), - [""], - [] - ) - -def test_set_handler_with_community_update_prefixes_add(): - set_del_test( - "SET", - ("DEPLOYMENT_ID|5|1010:2020", { - "prefixes_v4": "10.20.30.0/24,30.50.0.0/16,80.90.0.0/16", - "prefixes_v6": "fc00:20::/64,fc00:30::/64,fc02::/64", - }), - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', - 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - "" - ], - [ - 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 40 permit 80.90.0.0/16 ge 17', - 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 50 permit fc02::/64 ge 65', - ] - ) - -def test_set_handler_no_community_update_prefixes_add(): - set_del_test( - "SET", - ("DEPLOYMENT_ID|5", { - "prefixes_v4": "20.20.30.0/24,40.50.0.0/16,80.90.0.0/16", - "prefixes_v6": "fc01:20::/64,fc01:30::/64,fc02::/64", - }), - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - "" - ], - [ - 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 40 permit 80.90.0.0/16 ge 17', - 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 50 permit fc02::/64 ge 65', - ] - ) - -def test___set_handler_validate(): - cfg_mgr = MagicMock() - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - data = { - "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", - "prefixes_v6": "fc01:20::/64,fc01:30::/64", - } - assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", None) - assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID1|5|1010:2020", data) - assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|z|1010:2020", data) - assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { - "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", - "prefixes_v6": "20.20.30.0/24,40.50.0.0/16", - }) - assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { - "prefixes_v4": "fc01:20::/64,fc01:30::/64", - "prefixes_v6": "fc01:20::/64,fc01:30::/64", - }) - -def test___find_peer_group_by_deployment_id(): - cfg_mgr = MagicMock() - cfg_mgr.update.return_value = None - cfg_mgr.get_text.return_value = [ - 'router bgp 64601', - ' neighbor BGPSLBPassive peer-group', - ' neighbor BGPSLBPassive remote-as 65432', - ' neighbor BGPSLBPassive passive', - ' neighbor BGPSLBPassive ebgp-multihop 255', - ' neighbor BGPSLBPassive update-source 10.1.0.32', - ' neighbor PEER_V4 peer-group', - ' neighbor PEER_V4_INT peer-group', - ' neighbor PEER_V6 peer-group', - ' neighbor PEER_V6_INT peer-group', - ' neighbor 10.0.0.1 remote-as 64802', - ' neighbor 10.0.0.1 peer-group PEER_V4', - ' neighbor 10.0.0.1 description ARISTA01T1', - ' neighbor 10.0.0.1 timers 3 10', - ' neighbor fc00::2 remote-as 64802', - ' neighbor fc00::2 peer-group PEER_V6', - ' neighbor fc00::2 description ARISTA01T1', - ' neighbor fc00::2 timers 3 10', - ' address-family ipv4 unicast', - ' neighbor BGPSLBPassive activate', - ' neighbor BGPSLBPassive soft-reconfiguration inbound', - ' neighbor BGPSLBPassive route-map FROM_BGP_SPEAKER in', - ' neighbor BGPSLBPassive route-map TO_BGP_SPEAKER out', - ' neighbor PEER_V4 soft-reconfiguration inbound', - ' neighbor PEER_V4 allowas-in 1', - ' neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in', - ' neighbor PEER_V4 route-map TO_BGP_PEER_V4 out', - ' neighbor PEER_V4_INT soft-reconfiguration inbound', - ' neighbor PEER_V4_INT allowas-in 1', - ' neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in', - ' neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out', - ' neighbor 10.0.0.1 activate', - ' exit-address-family', - ' address-family ipv6 unicast', - ' neighbor BGPSLBPassive activate', - ' neighbor PEER_V6 soft-reconfiguration inbound', - ' neighbor PEER_V6 allowas-in 1', - ' neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in', - ' neighbor PEER_V6 route-map TO_BGP_PEER_V6 out', - ' neighbor PEER_V6_INT soft-reconfiguration inbound', - ' neighbor PEER_V6_INT allowas-in 1', - ' neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in', - ' neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out', - ' neighbor fc00::2 activate', - ' exit-address-family', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 10', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 30000', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535', - ' set community 5060:12345 additive', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 10', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 30000', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535', - ' set community 5060:12345 additive', - 'route-map FROM_BGP_PEER_V4 permit 100', - 'route-map FROM_BGP_PEER_V4 permit 2', - ' call ALLOW_LIST_DEPLOYMENT_ID_0_V4', - ' on-match next', - 'route-map FROM_BGP_PEER_V6 permit 1', - ' set ipv6 next-hop prefer-global ', - 'route-map FROM_BGP_PEER_V6 permit 100', - 'route-map FROM_BGP_PEER_V6 permit 2', - ' call ALLOW_LIST_DEPLOYMENT_ID_0_V6', - ' on-match next', - 'route-map FROM_BGP_SPEAKER permit 10', - 'route-map RM_SET_SRC permit 10', - ' set src 10.1.0.32', - 'route-map RM_SET_SRC6 permit 10', - ' set src FC00:1::32', - 'route-map TO_BGP_PEER_V4 permit 100', - 'route-map TO_BGP_PEER_V6 permit 100', - 'route-map TO_BGP_SPEAKER deny 1', - ] - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - values = mgr._BGPAllowListMgr__find_peer_group_by_deployment_id(0) - assert values == ['PEER_V4_INT', 'PEER_V6_INT', 'PEER_V6', 'PEER_V4'] - -def test___restart_peers_found_deployment_id(): - test___restart_peers_found_deployment_id.run_command_counter = 0 - def run_command(cmd): - output = [ - ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_1 soft in'], - ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_2 soft in'], - ] - desired_value = output[test___restart_peers_found_deployment_id.run_command_counter] - assert cmd == desired_value - test___restart_peers_found_deployment_id.run_command_counter += 1 - return 0, "", "" - cfg_mgr = MagicMock() - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') - mocked.return_value = ["BGP_TEST_PEER_GROUP_1", "BGP_TEST_PEER_GROUP_2"] - mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked - app.allow_list.run_command = run_command - rc = mgr._BGPAllowListMgr__restart_peers(5) - assert rc - -def test___restart_peers_not_found_deployment_id(): - def run_command(cmd): - assert cmd == ['vtysh', '-c', 'clear bgp * soft in'] - return 0, "", "" - cfg_mgr = MagicMock() - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') - mocked.return_value = [] - mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked - app.allow_list.run_command = run_command - rc = mgr._BGPAllowListMgr__restart_peers(5) - assert rc - -# FIXME: more testcases for coverage diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py index 686b1ade65e1..bc6d01cdb536 100644 --- a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -77,30 +77,21 @@ def extract_rm_from_peer_group(path, peer_group_name): return list(rm_set) def check_routemap_in_file(filename, route_map_name): - route_map_re = re.compile(r'^route-map\s+%s\s+permit\s+(\d+)' % route_map_name) + route_map_re = re.compile(r'^route-map\s+%s\s+(\S+)' % route_map_name) set_re = re.compile(r'set ipv6 next-hop prefer-global') with open(filename) as fp: lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] - found_entry = False - found_seq_no = None - route_map_entries = {} + found_first_entry = False for line in lines: - if found_entry: - route_map_entries[found_seq_no] = set_re.match(line) is not None - found_entry = False - found_seq_no = None + err_msg = "route-map %s doesn't have mandatory 'set ipv6 next-hop prefer-global' entry as the first rule" % route_map_name + assert not (found_first_entry and line.startswith("route-map")), err_msg + if found_first_entry and set_re.match(line): + break # We're good if route_map_re.match(line): - found_seq_no = None - seq_n_txt = route_map_re.match(line).group(1) - assert seq_n_txt.isdigit(), "wrong sequence number for line '%s'" % line - found_seq_no = int(seq_n_txt) - assert found_seq_no not in route_map_entries, "Route-map has duplicate entries: %s - %d" % (route_map_name, found_seq_no) - found_entry = True - results = [route_map_entries[seq] for seq in sorted(route_map_entries.keys())] - if (len(results)): - err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name - assert results[0], err_msg - return len(results) > 0 + err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name + assert route_map_re.match(line).group(1) == 'permit', err_msg + found_first_entry = True + return found_first_entry def check_routemap(path, route_map_name): result_files = load_results(path, "policies.conf") diff --git a/src/sonic-bgpcfgd/tests/util.py b/src/sonic-bgpcfgd/tests/util.py index aa6c62a56b5f..0bc12b060aec 100644 --- a/src/sonic-bgpcfgd/tests/util.py +++ b/src/sonic-bgpcfgd/tests/util.py @@ -5,7 +5,7 @@ def load_constants(): with open(CONSTANTS_PATH) as f: - data = yaml.load(f) # FIXME" , Loader=yaml.FullLoader) + data = yaml.load(f) result = {} assert "constants" in data, "'constants' key not found in constants.yml" assert "bgp" in data["constants"], "'bgp' key not found in constants.yml" @@ -13,4 +13,4 @@ def load_constants(): for name, value in data["constants"]["bgp"]["peers"].items(): assert "template_dir" in value, "'template_dir' key not found for peer '%s'" % name result[name] = value["template_dir"] - return result + return result \ No newline at end of file From e3a0feaa472a1684d60052c67d4a47fbaca23bba Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Tue, 29 Sep 2020 12:39:53 -0700 Subject: [PATCH 1182/1427] Vtysh support for multi asic (#5479) Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- dockers/docker-fpm-frr/base_image_files/vtysh | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/dockers/docker-fpm-frr/base_image_files/vtysh b/dockers/docker-fpm-frr/base_image_files/vtysh index 24016bd96b2c..e4efeb454cb3 100755 --- a/dockers/docker-fpm-frr/base_image_files/vtysh +++ b/dockers/docker-fpm-frr/base_image_files/vtysh @@ -1,4 +1,37 @@ #!/bin/bash +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + +function help() +{ + echo -e "Usage: $0 -n [0 to $(($NUM_ASIC-1))] [OPTION]... " 1>&2; exit 1; +} + +DEV="" +PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +[ -f $ASIC_CONF ] && . $ASIC_CONF + +if [[ ($NUM_ASIC -gt 1) ]]; then + while getopts ":n:h:" opt; do + case "${opt}" in + h) help + ;; + n) DEV=${OPTARG} + [ $DEV -lt $NUM_ASIC -a $DEV -ge 0 ] || help + ;; + esac + done + + if [ -z "${DEV}" ]; then + help + fi + + # Skip the arguments -n while passing to docker command + shift 2 +fi # Determine whether stdout is on a terminal if [ -t 1 ] ; then @@ -7,10 +40,10 @@ if [ -t 1 ] ; then TTY=$(tty) function cleanup { - docker exec -i bgp pkill -HUP -f "vtysh $TTY" + docker exec -i bgp$DEV pkill -HUP -f "vtysh $TTY" } trap cleanup HUP - docker exec -ti bgp vtysh "$TTY" "$@" + docker exec -ti bgp$DEV vtysh "$TTY" "$@" else - docker exec -i bgp vtysh "$@" + docker exec -i bgp$DEV vtysh "$@" fi From d71a4efe3bac20d0a68b1e88b564a2c1f20741d5 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Tue, 29 Sep 2020 23:57:54 +0300 Subject: [PATCH 1183/1427] [sonic-platform-common] Install Python 3 package in host OS and PMon container (#5461) Signed-off-by: Volodymyr Boyko --- dockers/docker-platform-monitor/Dockerfile.j2 | 5 +++++ dockers/docker-platform-monitor/start.sh | 17 +++++++++++++++++ dockers/dockerfile-macros.j2 | 19 ++++++++++++++++++- .../build_templates/sonic_debian_extension.j2 | 6 ++++++ rules/docker-platform-monitor.mk | 3 +++ slave.mk | 2 ++ 6 files changed, 51 insertions(+), 1 deletion(-) diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index 884fd565c3a4..b3af66971938 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -11,6 +11,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y \ python-pip \ + python3-dev \ ipmitool \ librrd8 \ librrd-dev \ @@ -21,6 +22,9 @@ RUN apt-get update && \ i2c-tools && \ pip install enum34 +# Install python3 required packages +RUN python3 -m pip install --no-cache-dir setuptools wheel + {% if docker_platform_monitor_debs.strip() -%} # Copy locally-built Debian package dependencies {{ copy_files("debs/", docker_platform_monitor_debs.split(' '), "/debs/") }} @@ -47,6 +51,7 @@ RUN apt-get update && \ # Clean up RUN apt-get purge -y \ + python3-dev \ python-pip && \ apt-get clean -y && \ apt-get autoclean -y && \ diff --git a/dockers/docker-platform-monitor/start.sh b/dockers/docker-platform-monitor/start.sh index 58e481476b93..0884266e2308 100755 --- a/dockers/docker-platform-monitor/start.sh +++ b/dockers/docker-platform-monitor/start.sh @@ -31,3 +31,20 @@ if [ $? -ne 0 ]; then echo "Error: Unable to locate ${SONIC_PLATFORM_WHEEL}" fi fi + +# If the python3 sonic-platform package is not installed, try to install it +python3 -m pip show sonic-platform > /dev/null 2>&1 +if [ $? -ne 0 ]; then + SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py3-none-any.whl" + echo "sonic-platform package not installed, attempting to install..." + if [ -e ${SONIC_PLATFORM_WHEEL} ]; then + python3 -m pip install ${SONIC_PLATFORM_WHEEL} + if [ $? -eq 0 ]; then + echo "Successfully installed ${SONIC_PLATFORM_WHEEL}" + else + echo "Error: Failed to install ${SONIC_PLATFORM_WHEEL}" + fi + else + echo "Error: Unable to locate ${SONIC_PLATFORM_WHEEL}" + fi +fi diff --git a/dockers/dockerfile-macros.j2 b/dockers/dockerfile-macros.j2 index 8a4a3ae01411..5952d59f566f 100644 --- a/dockers/dockerfile-macros.j2 +++ b/dockers/dockerfile-macros.j2 @@ -5,7 +5,7 @@ RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return {%- endfor %} {%- endmacro %} -{% macro install_python_wheels(packages) -%} +{% macro install_python2_wheels(packages) -%} RUN cd /python-wheels/ && pip install {{ packages | join(' ') }} {%- endmacro %} @@ -13,6 +13,23 @@ RUN cd /python-wheels/ && pip install {{ packages | join(' ') }} RUN cd /python-wheels/ && pip3 install {{ packages | join(' ') }} {%- endmacro %} +{% macro install_python_wheels(packages) -%} +{%- set py2_pkgs, py3_pkgs = [], [] %} +{%- for pkg in packages %} + {%- if 'py3' in pkg %} + {{- py3_pkgs.append(pkg) or '' }} + {%- else %} + {{- py2_pkgs.append(pkg) or '' }} + {%- endif %} +{%- endfor %} +{%- if py3_pkgs | length %} +{{ install_python3_wheels(py3_pkgs) }} +{%- endif %} +{%- if py2_pkgs | length %} +{{ install_python2_wheels(py2_pkgs) }} +{%- endif %} +{%- endmacro %} + {% macro copy_files(prefix, files, dest) -%} COPY \ {%- for file in files %} diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index eac1e2ba352a..b40be7c13f79 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -172,6 +172,12 @@ sudo cp {{platform_common_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $PLATFORM_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME +# Install sonic-platform-common Python 3 package +PLATFORM_COMMON_PY3_WHEEL_NAME=$(basename {{platform_common_py3_wheel_path}}) +sudo cp {{platform_common_py3_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $PLATFORM_COMMON_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY3_WHEEL_NAME + # Install Debian packages and their dependencies which are needed by sonic-utilities sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f python-m2crypto diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index 72f9e145d6d4..e864f42a7072 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -11,8 +11,11 @@ ifeq ($(CONFIGURED_PLATFORM),barefoot) $(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(PYTHON_THRIFT) endif $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SWSSSDK_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SWSSSDK_PY3) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_LEDD) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PCIED) diff --git a/slave.mk b/slave.mk index 2d45b2c1e13f..b9cebdf9a169 100644 --- a/slave.mk +++ b/slave.mk @@ -813,6 +813,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) \ @@ -851,6 +852,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export swsssdk_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY2))" export swsssdk_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY3))" export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" + export platform_common_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY3))" export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" export redis_dump_load_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY3))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" From 79bda7d0d6649ab26dbab22266f6da3faeffdb3e Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 30 Sep 2020 03:23:09 +0300 Subject: [PATCH 1184/1427] [monit]: Fix process checker. (#5480) Signed-off-by: Nazarii Hnydyn --- dockers/docker-fpm-frr/base_image_files/monit_bgp | 2 +- dockers/docker-snmp/base_image_files/monit_snmp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp index 46ddc629013e..4567d45e3c48 100644 --- a/dockers/docker-fpm-frr/base_image_files/monit_bgp +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -23,5 +23,5 @@ check program bgp|staticd with path "/usr/bin/process_checker bgp /usr/lib/frr/s check program bgp|bgpcfgd with path "/usr/bin/process_checker bgp /usr/bin/python /usr/local/bin/bgpcfgd" if status != 0 for 5 times within 5 cycles then alert -check program bgp|bgpmon with path "/usr/bin/process_checker bgp python /usr/local/bin/bgpmon" +check program bgp|bgpmon with path "/usr/bin/process_checker bgp /usr/bin/python /usr/local/bin/bgpmon" if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-snmp/base_image_files/monit_snmp b/dockers/docker-snmp/base_image_files/monit_snmp index a943985abcef..b1725378c0b8 100644 --- a/dockers/docker-snmp/base_image_files/monit_snmp +++ b/dockers/docker-snmp/base_image_files/monit_snmp @@ -7,5 +7,5 @@ check program snmp|snmpd with path "/usr/bin/process_checker snmp /usr/sbin/snmpd" if status != 0 for 5 times within 5 cycles then alert -check program snmp|snmp_subagent with path "/usr/bin/process_checker snmp python3.6 -m sonic_ax_impl" +check program snmp|snmp_subagent with path "/usr/bin/process_checker snmp python3 -m sonic_ax_impl" if status != 0 for 5 times within 5 cycles then alert From c55bb03cfca04e4c4153cf1c40f6844dec4633d1 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 19:20:15 -0700 Subject: [PATCH 1185/1427] [build] Add Support For Python 3 Build CONiC config gen requires jinja2<3.0.0 for stretch and byangbind versions 0.60.0/0.80.1 for Python 2/3 respectively. byangbind is installed in the build docker because when it installed it pulls enum34 as dependent package which is not required for Python 3 and it breaks the build. signed-off-by: Tamer Ahmed --- sonic-slave-buster/Dockerfile.j2 | 10 +++++++--- sonic-slave-stretch/Dockerfile.j2 | 13 ++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 88f905cb0f8a..11d79278230e 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -242,7 +242,9 @@ RUN apt-get update && apt-get install -y \ sphinx-common \ python3-sphinx \ # For sonic config engine testing + python-dev \ python-lxml \ + python3-lxml \ python-jinja2 \ python-netaddr \ python-ipaddr \ @@ -362,9 +364,11 @@ RUN pip install \ crc16 # For sonic config engine testing -RUN pip install pyangbind==0.6.0 -# Note: force upgrade debian packaged jinja2, if installed -RUN pip install --force-reinstall --upgrade "jinja2>=2.10" +# Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed. +# enum34 causes Python 're' package to not work properly as it redefines an incompatible enum.py module +# https://github.com/robshakir/pyangbind/issues/232 +RUN pip3 install pyangbind==0.8.1 +RUN pip3 uninstall -y enum34 # For templating RUN pip install j2cli==0.3.10 diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index d372450f0181..fb685a2adcf5 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -241,7 +241,9 @@ RUN apt-get update && apt-get install -y \ sphinx-common \ python3-sphinx \ # For sonic config engine testing + python-dev \ python-lxml \ + python3-lxml \ python-jinja2 \ python-netaddr \ python-ipaddr \ @@ -341,10 +343,15 @@ RUN pip install \ ctypesgen==0.r125 \ crc16 +# Note: Stick with Jinja2 2.x branch as the 3.x dropped support for Python 2.7 +RUN pip install --force-reinstall --upgrade "Jinja2<3.0.0" + # For sonic config engine testing -RUN pip install pyangbind==0.6.0 -# Note: force upgrade debian packaged jinja2, if installed -RUN pip install --force-reinstall --upgrade "jinja2>=2.10" +# Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed. +# enum34 causes Python 're' package to not work properly as it redefines an incompatible enum.py module +# https://github.com/robshakir/pyangbind/issues/232 +RUN pip3 install pyangbind==0.8.1 +RUN pip3 uninstall -y enum34 # For templating RUN pip install j2cli==0.3.10 From 9122d16dd28c36d10a05ce0b30d81ff6273f1c63 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 20:07:39 -0700 Subject: [PATCH 1186/1427] [cfggen] Remove NatSorted Natural sorting of SONiC config gen output consumes lot of CPU cycles. The sole use of natsorted was to make test comparison easier and so, the natsorting logic is now relocated to the test suite. As a result sonic-cfggen gained nearly 1 sec per call since we no longer import natsorted module! singed-off-by: Tamer Ahmed --- .../data/sonic-cfggen/bgpd.conf.j2/all.conf | 12 +- .../sonic-cfggen/bgpd.main.conf.j2/all.conf | 6 +- .../bgpd.main.conf.j2/defaults.conf | 6 +- .../base.conf | 20 +- .../data/sonic-cfggen/frr.conf.j2/all.conf | 15 +- .../data/sonic-cfggen/zebra/interfaces.conf | 6 +- .../tests/data/sonic-cfggen/zebra/zebra.conf | 10 +- src/sonic-config-engine/__init__.py | 0 src/sonic-config-engine/sonic-cfggen | 51 +-- src/sonic-config-engine/tests/common_utils.py | 30 ++ .../tests/multi_npu_data/ipinip.json | 2 +- .../tests/sample_output/bgpd_quagga.conf | 44 +- .../tests/sample_output/buffers-dell6100.json | 418 +++++++++--------- .../docker-dhcp-relay.supervisord.conf | 4 +- .../tests/sample_output/frr.conf | 4 +- .../tests/sample_output/ipinip.json | 4 +- .../tests/sample_output/l2switch.json | 236 +++++----- .../tests/sample_output/ports.json | 14 +- .../t2-chassis-fe-vni-zebra.conf | 4 +- .../sample_output/t2-chassis-fe-zebra.conf | 4 +- .../tests/sample_output/wait_for_intf.sh | 2 +- .../tests/sample_output/zebra_frr.conf | 4 +- .../tests/sample_output/zebra_quagga.conf | 4 +- src/sonic-config-engine/tests/test_cfggen.py | 290 +++++++----- .../tests/test_cfggen_platformJson.py | 16 +- .../tests/test_cfggen_t2_chassis_fe.py | 45 +- .../tests/test_minigraph_case.py | 27 +- .../tests/test_multinpu_cfggen.py | 46 +- 28 files changed, 742 insertions(+), 582 deletions(-) create mode 100644 src/sonic-config-engine/__init__.py create mode 100644 src/sonic-config-engine/tests/common_utils.py diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf index e417e10d61f5..6d79e4c2264d 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf @@ -1,10 +1,12 @@ ! ! template: bgpd/bgpd.conf.j2 ! +! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== ! generated by templates/quagga/bgpd.conf.j2 with config DB data ! file: bgpd.conf ! +! ! template: common/daemons.common.conf.j2 ! hostname new_hostname @@ -17,6 +19,8 @@ log facility local4 ! end of template: common/daemons.common.conf.j2! agentx ! +! +! ! template: bgpd/bgpd.main.conf.j2 ! ! bgp multiple-instance @@ -29,14 +33,15 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 5 permit fc01::1/64 ! ! route-map HIDE_INTERNAL permit 10 set community local-AS ! +! router bgp 55555 ! bgp log-neighbor-changes @@ -56,10 +61,11 @@ router bgp 55555 network fc00::1/64 exit-address-family ! - network 10.10.10.1/24 address-family ipv6 network fc01::1/64 exit-address-family + network 10.10.10.1/24 +! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf index c4e18c5ae258..d771ff49c92d 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf @@ -11,14 +11,15 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 15 permit fc01::1/64 ! ! route-map HIDE_INTERNAL permit 10 set community local-AS ! +! router bgp 55555 ! bgp log-neighbor-changes @@ -42,6 +43,7 @@ router bgp 55555 address-family ipv6 network fc01::1/64 exit-address-family +! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf index e1f9c8489cb4..e9296f8627d9 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf @@ -11,14 +11,15 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 15 permit fc01::1/64 ! ! route-map HIDE_INTERNAL permit 10 set community local-AS ! +! router bgp 55555 ! bgp log-neighbor-changes @@ -42,6 +43,7 @@ router bgp 55555 address-family ipv6 network fc01::1/64 exit-address-family +! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf index 581eb107ec23..2f543715299c 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf @@ -1,6 +1,6 @@ ! ! Vnet BGP instance -router bgp 555 vrf First +router bgp 555 vrf Second no bgp default ipv4-unicast bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -8,17 +8,17 @@ router bgp 555 vrf First bgp graceful-restart restart-time 240 bgp graceful-restart bgp router-id 10.20.30.40 - neighbor 10.10.10.1 remote-as 10 - neighbor 10.10.10.1 description session1 + neighbor 20.20.20.1 remote-as 20 + neighbor 20.20.20.1 description session2 address-family ipv4 unicast - neighbor 10.10.10.1 activate - neighbor 10.10.10.1 soft-reconfiguration inbound + neighbor 20.20.20.1 activate + neighbor 20.20.20.1 soft-reconfiguration inbound maximum-paths 64 exit-address-family address-family l2vpn evpn advertise ipv4 unicast exit-address-family -router bgp 555 vrf Second +router bgp 555 vrf First no bgp default ipv4-unicast bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -26,11 +26,11 @@ router bgp 555 vrf Second bgp graceful-restart restart-time 240 bgp graceful-restart bgp router-id 10.20.30.40 - neighbor 20.20.20.1 remote-as 20 - neighbor 20.20.20.1 description session2 + neighbor 10.10.10.1 remote-as 10 + neighbor 10.10.10.1 description session1 address-family ipv4 unicast - neighbor 20.20.20.1 activate - neighbor 20.20.20.1 soft-reconfiguration inbound + neighbor 10.10.10.1 activate + neighbor 10.10.10.1 soft-reconfiguration inbound maximum-paths 64 exit-address-family address-family l2vpn evpn diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf index b1596909c788..1ed40fab744f 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf @@ -3,6 +3,7 @@ ! generated by templates/frr.conf.j2 with config DB data ! file: frr.conf ! +! ! template: common/daemons.common.conf.j2 ! hostname test_hostname @@ -15,11 +16,13 @@ log facility local4 ! end of template: common/daemons.common.conf.j2! agentx ! +! +! ! Enable link-detect (default disabled) -interface Ethernet0 +interface Ethernet4 link-detect ! -interface Ethernet4 +interface Ethernet0 link-detect ! interface PortChannel10 @@ -46,14 +49,15 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 5 permit fc01::1/64 ! ! route-map HIDE_INTERNAL permit 10 set community local-AS ! +! router bgp 55555 ! bgp log-neighbor-changes @@ -73,10 +77,11 @@ router bgp 55555 network fc00::1/64 exit-address-family ! - network 10.10.10.1/24 address-family ipv6 network fc01::1/64 exit-address-family + network 10.10.10.1/24 +! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf index 919c35085b5c..766509971224 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf @@ -1,9 +1,10 @@ ! +! ! Enable link-detect (default disabled) -interface Ethernet0 +interface Ethernet4 link-detect ! -interface Ethernet4 +interface Ethernet0 link-detect ! interface PortChannel10 @@ -12,3 +13,4 @@ link-detect interface PortChannel20 link-detect ! +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf index f7b30f214d4d..9f185edc2109 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf @@ -3,6 +3,7 @@ ! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! +! ! template: common/daemons.common.conf.j2 ! hostname new_hostname @@ -14,17 +15,18 @@ log facility local4 ! ! end of template: common/daemons.common.conf.j2! ! +vrf Second +vni 20 +! vrf First vni 10 ! -vrf Second -vni 20 ! ! Enable link-detect (default disabled) -interface Ethernet0 +interface Ethernet4 link-detect ! -interface Ethernet4 +interface Ethernet0 link-detect ! interface PortChannel10 diff --git a/src/sonic-config-engine/__init__.py b/src/sonic-config-engine/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 3e4e661f6adc..fb547acd6927 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -16,8 +16,6 @@ See usage string for detail description for arguments. """ from __future__ import print_function -import sys -sys.path.insert(0, "/usr/local/lib/python2.7/dist-packages") # monkey patch re.compile to do lazy regular expression compilation. # This is done to improve import time of jinja2, yaml, natsort modules, because they @@ -28,28 +26,24 @@ sys.path.insert(0, "/usr/local/lib/python2.7/dist-packages") # FIXME: remove this once sonic-cfggen and templates dependencies are replaced with a faster approach import lazy_re -import sys -import os.path import argparse -import yaml +import contextlib import jinja2 -import netaddr import json -import contextlib +import netaddr +import os.path +import sys +import yaml + +from collections import OrderedDict +from config_samples import generate_sample_config, get_available_config from functools import partial -from minigraph import minigraph_encoder -from minigraph import parse_xml -from minigraph import parse_device_desc_xml -from minigraph import parse_asic_sub_role +from minigraph import minigraph_encoder, parse_xml, parse_device_desc_xml, parse_asic_sub_role from portconfig import get_port_config, get_breakout_mode +from redis_bcc import RedisBytecodeCache from sonic_py_common.multi_asic import get_asic_id_from_name, is_multi_asic from sonic_py_common import device_info -from config_samples import generate_sample_config -from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig, ConfigDBPipeConnector -from redis_bcc import RedisBytecodeCache -from collections import OrderedDict -from natsort import natsorted #TODO: Remove STR_TYPE once SONiC moves to Python 3.x PY3x = sys.version_info >= (3, 0) @@ -166,9 +160,7 @@ TODO(taoyl): Current version of config db only supports BGP admin states. @staticmethod def to_serialized(data, lookup_key = None): if type(data) is dict: - data = OrderedDict(natsorted(data.items())) - - if lookup_key != None: + if lookup_key is not None: newData = {} for key in data.keys(): if ((type(key) is STR_TYPE and lookup_key == key) or (type(key) is tuple and lookup_key in key)): @@ -280,7 +272,7 @@ def main(): platform = device_info.get_platform() db_kwargs = {} - if args.redis_unix_sock_file != None: + if args.redis_unix_sock_file is not None: db_kwargs['unix_socket_path'] = args.redis_unix_sock_file data = {} @@ -314,17 +306,17 @@ def main(): _process_json(args, data) - if args.minigraph != None: + if args.minigraph is not None: minigraph = args.minigraph if platform: - if args.port_config != None: + if args.port_config is not None: deep_update(data, parse_xml(minigraph, platform, args.port_config, asic_name=asic_name, hwsku_config_file=args.hwsku_config)) else: deep_update(data, parse_xml(minigraph, platform, asic_name=asic_name)) else: deep_update(data, parse_xml(minigraph, port_config_file=args.port_config, asic_name=asic_name, hwsku_config_file=args.hwsku_config)) - if args.device_description != None: + if args.device_description is not None: deep_update(data, parse_device_desc_xml(args.device_description)) for yaml_file in args.yaml: @@ -335,7 +327,7 @@ def main(): additional_data = yaml.load(stream) deep_update(data, FormatConverter.to_deserialized(additional_data)) - if args.additional_data != None: + if args.additional_data is not None: deep_update(data, json.loads(args.additional_data)) if args.from_db: @@ -379,22 +371,21 @@ def main(): for template_file, _ in args.template: paths.append(os.path.dirname(os.path.abspath(template_file))) env = _get_jinja2_env(paths) - sorted_data = sort_data(data) for template_file, dest_file in args.template: template = env.get_template(os.path.basename(template_file)) - template_data = template.render(sorted_data) + template_data = template.render(data) if dest_file == "config-db": deep_update(data, FormatConverter.to_deserialized(json.loads(template_data))) else: with smart_open(dest_file, 'w') as df: print(template_data, file=df) - if args.var != None: + if args.var is not None: template = jinja2.Template('{{' + args.var + '}}') print(template.render(data)) - if args.var_json != None and args.var_json in data: - if args.key != None: + if args.var_json is not None and args.var_json in data: + if args.key is not None: print(json.dumps(FormatConverter.to_serialized(data[args.var_json], args.key), indent=4, cls=minigraph_encoder)) else: print(json.dumps(FormatConverter.to_serialized(data[args.var_json]), indent=4, cls=minigraph_encoder)) @@ -411,7 +402,7 @@ def main(): if args.print_data: print(json.dumps(FormatConverter.to_serialized(data), indent=4, cls=minigraph_encoder)) - if args.preset != None: + if args.preset is not None: data = generate_sample_config(data, args.preset) print(json.dumps(FormatConverter.to_serialized(data), indent=4, cls=minigraph_encoder)) diff --git a/src/sonic-config-engine/tests/common_utils.py b/src/sonic-config-engine/tests/common_utils.py new file mode 100644 index 000000000000..f75584471eb4 --- /dev/null +++ b/src/sonic-config-engine/tests/common_utils.py @@ -0,0 +1,30 @@ +import json +import re +import sys + + +def tuple_to_str(tuplestr): + """ Convert Python tuple '('elem1', 'elem2')' representation into string on the for "elem1|elem2" """ + def to_str(tupleobj): + tupleobj = re.sub(r"([\(\)])", '"', tupleobj.group(0)) + return re.sub(r"( *, *)", '|', tupleobj).replace("'", '') + + return re.sub(r"(\(.*?\))", to_str, tuplestr) + +def to_dict(dictstr): + """ Convert string represention of Python dict into dict """ + # handle tuple elements + dictstr = tuple_to_str(dictstr) + + return json.loads(dictstr.replace("'", '"')) + +def liststr_to_dict(liststr): + """ Convert string represention of Python list into dict with list key and sorted liststr as its value """ + # handle tuple elements + liststr = tuple_to_str(liststr) + + list_obj = json.loads("{\"list\":" + liststr.replace("'", '"') +'}') + list_obj["list"] = sorted(list_obj["list"]) + + return list_obj + diff --git a/src/sonic-config-engine/tests/multi_npu_data/ipinip.json b/src/sonic-config-engine/tests/multi_npu_data/ipinip.json index 0f8396e63b30..d48dcba30bd3 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/ipinip.json +++ b/src/sonic-config-engine/tests/multi_npu_data/ipinip.json @@ -2,7 +2,7 @@ { "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { "tunnel_type":"IPINIP", - "dst_ip":"10.1.0.32,8.0.0.0,10.0.0.0,10.1.0.1,10.1.0.3", + "dst_ip":"8.0.0.0,10.1.0.32,10.1.0.3,10.0.0.0,10.1.0.1", "dscp_mode":"pipe", "ecn_mode":"copy_from_outer", "ttl_mode":"pipe" diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf b/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf index ebffcaa7c24d..f75d9de9a30e 100644 --- a/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf +++ b/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf @@ -23,19 +23,11 @@ router bgp 65100 bgp graceful-restart restart-time 240 bgp graceful-restart bgp router-id 10.1.0.32 - network 10.1.0.32/32 address-family ipv6 network fc00:1::32/64 exit-address-family + network 10.1.0.32/32 network 192.168.0.1/27 - neighbor 10.0.0.57 remote-as 64600 - neighbor 10.0.0.57 description ARISTA01T1 - address-family ipv4 - neighbor 10.0.0.57 allowas-in 1 - neighbor 10.0.0.57 activate - neighbor 10.0.0.57 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family neighbor 10.0.0.59 remote-as 64600 neighbor 10.0.0.59 description ARISTA02T1 address-family ipv4 @@ -60,14 +52,6 @@ router bgp 65100 neighbor 10.0.0.63 soft-reconfiguration inbound maximum-paths 64 exit-address-family - neighbor fc00::7a remote-as 64600 - neighbor fc00::7a description ARISTA03T1 - address-family ipv6 - neighbor fc00::7a allowas-in 1 - neighbor fc00::7a activate - neighbor fc00::7a soft-reconfiguration inbound - maximum-paths 64 - exit-address-family neighbor fc00::7e remote-as 64600 neighbor fc00::7e description ARISTA04T1 address-family ipv6 @@ -76,12 +60,20 @@ router bgp 65100 neighbor fc00::7e soft-reconfiguration inbound maximum-paths 64 exit-address-family - neighbor fc00::72 remote-as 64600 - neighbor fc00::72 description ARISTA01T1 + neighbor fc00::7a remote-as 64600 + neighbor fc00::7a description ARISTA03T1 address-family ipv6 - neighbor fc00::72 allowas-in 1 - neighbor fc00::72 activate - neighbor fc00::72 soft-reconfiguration inbound + neighbor fc00::7a allowas-in 1 + neighbor fc00::7a activate + neighbor fc00::7a soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.57 remote-as 64600 + neighbor 10.0.0.57 description ARISTA01T1 + address-family ipv4 + neighbor 10.0.0.57 allowas-in 1 + neighbor 10.0.0.57 activate + neighbor 10.0.0.57 soft-reconfiguration inbound maximum-paths 64 exit-address-family neighbor fc00::76 remote-as 64600 @@ -92,6 +84,14 @@ router bgp 65100 neighbor fc00::76 soft-reconfiguration inbound maximum-paths 64 exit-address-family + neighbor fc00::72 remote-as 64600 + neighbor fc00::72 description ARISTA01T1 + address-family ipv6 + neighbor fc00::72 allowas-in 1 + neighbor fc00::72 activate + neighbor fc00::72 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family ! maximum-paths 64 ! diff --git a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json index 5cf0472f3f11..56de7500c1ad 100644 --- a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json +++ b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json @@ -2,56 +2,21 @@ { "CABLE_LENGTH": { "AZURE": { - "Ethernet0": "5m", - "Ethernet1": "5m", + "Ethernet8": "5m", + "Ethernet9": "5m", "Ethernet2": "5m", "Ethernet3": "5m", - "Ethernet4": "5m", - "Ethernet5": "5m", + "Ethernet0": "5m", + "Ethernet1": "5m", "Ethernet6": "5m", "Ethernet7": "5m", - "Ethernet8": "5m", - "Ethernet9": "5m", - "Ethernet10": "5m", - "Ethernet11": "5m", - "Ethernet12": "5m", - "Ethernet13": "5m", - "Ethernet14": "5m", - "Ethernet15": "5m", - "Ethernet16": "5m", - "Ethernet17": "5m", - "Ethernet18": "5m", - "Ethernet19": "5m", - "Ethernet20": "5m", - "Ethernet21": "5m", - "Ethernet22": "5m", - "Ethernet23": "5m", - "Ethernet24": "5m", - "Ethernet25": "5m", - "Ethernet26": "5m", - "Ethernet27": "5m", - "Ethernet28": "5m", - "Ethernet29": "5m", - "Ethernet30": "5m", - "Ethernet31": "5m", - "Ethernet32": "5m", - "Ethernet33": "5m", - "Ethernet34": "5m", - "Ethernet35": "5m", - "Ethernet36": "5m", - "Ethernet37": "5m", - "Ethernet38": "5m", - "Ethernet39": "5m", - "Ethernet40": "5m", - "Ethernet41": "5m", - "Ethernet42": "5m", - "Ethernet43": "5m", - "Ethernet44": "5m", - "Ethernet45": "5m", + "Ethernet4": "5m", + "Ethernet5": "5m", "Ethernet46": "5m", - "Ethernet47": "5m", - "Ethernet48": "5m", - "Ethernet49": "5m", + "Ethernet34": "5m", + "Ethernet22": "5m", + "Ethernet58": "5m", + "Ethernet59": "5m", "Ethernet50": "5m", "Ethernet51": "5m", "Ethernet52": "5m", @@ -60,12 +25,47 @@ "Ethernet55": "5m", "Ethernet56": "5m", "Ethernet57": "5m", - "Ethernet58": "5m", - "Ethernet59": "5m", - "Ethernet60": "5m", + "Ethernet38": "5m", + "Ethernet39": "5m", + "Ethernet18": "5m", + "Ethernet19": "5m", + "Ethernet14": "5m", + "Ethernet15": "5m", + "Ethernet16": "5m", + "Ethernet17": "5m", + "Ethernet10": "5m", + "Ethernet11": "5m", + "Ethernet12": "5m", + "Ethernet35": "5m", + "Ethernet37": "5m", + "Ethernet32": "5m", + "Ethernet33": "5m", + "Ethernet30": "5m", + "Ethernet31": "5m", + "Ethernet49": "5m", + "Ethernet48": "5m", + "Ethernet47": "5m", + "Ethernet36": "5m", + "Ethernet45": "5m", + "Ethernet44": "5m", + "Ethernet43": "5m", + "Ethernet42": "5m", + "Ethernet41": "5m", + "Ethernet40": "5m", + "Ethernet29": "5m", + "Ethernet28": "5m", "Ethernet61": "5m", + "Ethernet60": "5m", + "Ethernet63": "5m", "Ethernet62": "5m", - "Ethernet63": "5m" + "Ethernet21": "5m", + "Ethernet20": "5m", + "Ethernet23": "5m", + "Ethernet13": "5m", + "Ethernet25": "5m", + "Ethernet24": "5m", + "Ethernet27": "5m", + "Ethernet26": "5m" } }, @@ -105,16 +105,16 @@ } }, "BUFFER_PG": { - "Ethernet0|0": { + "Ethernet8|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet1|0": { + "Ethernet9|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet4|0": { + "Ethernet0|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet5|0": { + "Ethernet1|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, "Ethernet6|0": { @@ -123,64 +123,64 @@ "Ethernet7|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet8|0": { + "Ethernet4|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet9|0": { + "Ethernet5|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet10|0": { + "Ethernet58|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet11|0": { + "Ethernet52|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet12|0": { + "Ethernet53|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet13|0": { + "Ethernet54|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet14|0": { + "Ethernet55|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet15|0": { + "Ethernet56|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet16|0": { + "Ethernet57|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet17|0": { + "Ethernet38|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet20|0": { + "Ethernet39|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet21|0": { + "Ethernet32|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet22|0": { + "Ethernet15|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet23|0": { + "Ethernet16|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet24|0": { + "Ethernet17|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet25|0": { + "Ethernet36|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet26|0": { + "Ethernet37|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet27|0": { + "Ethernet12|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet28|0": { + "Ethernet13|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet29|0": { + "Ethernet14|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, "Ethernet30|0": { @@ -189,67 +189,67 @@ "Ethernet31|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet32|0": { + "Ethernet48|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet36|0": { + "Ethernet10|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet37|0": { + "Ethernet42|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet38|0": { + "Ethernet41|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet39|0": { + "Ethernet40|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet40|0": { + "Ethernet29|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet41|0": { + "Ethernet28|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet42|0": { + "Ethernet11|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet48|0": { + "Ethernet21|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet52|0": { + "Ethernet20|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet53|0": { + "Ethernet23|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet54|0": { + "Ethernet22|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet55|0": { + "Ethernet25|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet56|0": { + "Ethernet24|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet57|0": { + "Ethernet27|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet58|0": { + "Ethernet26|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, "BUFFER_QUEUE": { - "Ethernet0|3-4": { + "Ethernet8|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet1|3-4": { + "Ethernet9|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet4|3-4": { + "Ethernet0|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet5|3-4": { + "Ethernet1|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, "Ethernet6|3-4": { @@ -258,64 +258,64 @@ "Ethernet7|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet8|3-4": { + "Ethernet4|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet9|3-4": { + "Ethernet5|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet10|3-4": { + "Ethernet58|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet11|3-4": { + "Ethernet52|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet12|3-4": { + "Ethernet53|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet13|3-4": { + "Ethernet54|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet14|3-4": { + "Ethernet55|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet15|3-4": { + "Ethernet56|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet16|3-4": { + "Ethernet57|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet17|3-4": { + "Ethernet38|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet20|3-4": { + "Ethernet39|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet21|3-4": { + "Ethernet32|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet22|3-4": { + "Ethernet15|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet23|3-4": { + "Ethernet16|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet24|3-4": { + "Ethernet17|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet25|3-4": { + "Ethernet36|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet26|3-4": { + "Ethernet37|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet27|3-4": { + "Ethernet12|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet28|3-4": { + "Ethernet13|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet29|3-4": { + "Ethernet14|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, "Ethernet30|3-4": { @@ -324,64 +324,64 @@ "Ethernet31|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet32|3-4": { + "Ethernet48|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet36|3-4": { + "Ethernet10|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet37|3-4": { + "Ethernet42|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet38|3-4": { + "Ethernet41|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet39|3-4": { + "Ethernet40|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet40|3-4": { + "Ethernet29|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet41|3-4": { + "Ethernet28|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet42|3-4": { + "Ethernet11|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet48|3-4": { + "Ethernet21|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet52|3-4": { + "Ethernet20|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet53|3-4": { + "Ethernet23|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet54|3-4": { + "Ethernet22|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet55|3-4": { + "Ethernet25|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet56|3-4": { + "Ethernet24|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet57|3-4": { + "Ethernet27|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet58|3-4": { + "Ethernet26|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet0|0-2": { + "Ethernet8|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet1|0-2": { + "Ethernet9|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet4|0-2": { + "Ethernet0|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet5|0-2": { + "Ethernet1|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet6|0-2": { @@ -390,64 +390,64 @@ "Ethernet7|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet8|0-2": { + "Ethernet4|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet9|0-2": { + "Ethernet5|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet10|0-2": { + "Ethernet58|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet11|0-2": { + "Ethernet52|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet12|0-2": { + "Ethernet53|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet13|0-2": { + "Ethernet54|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet14|0-2": { + "Ethernet55|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet15|0-2": { + "Ethernet56|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet16|0-2": { + "Ethernet57|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet17|0-2": { + "Ethernet38|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet20|0-2": { + "Ethernet39|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet21|0-2": { + "Ethernet32|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet22|0-2": { + "Ethernet15|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet23|0-2": { + "Ethernet16|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet24|0-2": { + "Ethernet17|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet25|0-2": { + "Ethernet36|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet26|0-2": { + "Ethernet37|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet27|0-2": { + "Ethernet12|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet28|0-2": { + "Ethernet13|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet29|0-2": { + "Ethernet14|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet30|0-2": { @@ -456,64 +456,64 @@ "Ethernet31|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet32|0-2": { + "Ethernet48|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet36|0-2": { + "Ethernet10|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet37|0-2": { + "Ethernet42|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet38|0-2": { + "Ethernet41|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet39|0-2": { + "Ethernet40|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet40|0-2": { + "Ethernet29|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet41|0-2": { + "Ethernet28|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet42|0-2": { + "Ethernet11|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet48|0-2": { + "Ethernet21|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet52|0-2": { + "Ethernet20|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet53|0-2": { + "Ethernet23|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet54|0-2": { + "Ethernet22|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet55|0-2": { + "Ethernet25|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet56|0-2": { + "Ethernet24|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet57|0-2": { + "Ethernet27|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet58|0-2": { + "Ethernet26|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet0|5-6": { + "Ethernet8|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet1|5-6": { + "Ethernet9|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet4|5-6": { + "Ethernet0|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet5|5-6": { + "Ethernet1|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet6|5-6": { @@ -522,64 +522,64 @@ "Ethernet7|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet8|5-6": { + "Ethernet4|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet9|5-6": { + "Ethernet5|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet10|5-6": { + "Ethernet58|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet11|5-6": { + "Ethernet52|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet12|5-6": { + "Ethernet53|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet13|5-6": { + "Ethernet54|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet14|5-6": { + "Ethernet55|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet15|5-6": { + "Ethernet56|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet16|5-6": { + "Ethernet57|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet17|5-6": { + "Ethernet38|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet20|5-6": { + "Ethernet39|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet21|5-6": { + "Ethernet32|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet22|5-6": { + "Ethernet15|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet23|5-6": { + "Ethernet16|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet24|5-6": { + "Ethernet17|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet25|5-6": { + "Ethernet36|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet26|5-6": { + "Ethernet37|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet27|5-6": { + "Ethernet12|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet28|5-6": { + "Ethernet13|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet29|5-6": { + "Ethernet14|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet30|5-6": { @@ -588,52 +588,52 @@ "Ethernet31|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet32|5-6": { + "Ethernet48|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet36|5-6": { + "Ethernet10|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet37|5-6": { + "Ethernet42|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet38|5-6": { + "Ethernet41|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet39|5-6": { + "Ethernet40|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet40|5-6": { + "Ethernet29|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet41|5-6": { + "Ethernet28|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet42|5-6": { + "Ethernet11|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet48|5-6": { + "Ethernet21|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet52|5-6": { + "Ethernet20|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet53|5-6": { + "Ethernet23|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet54|5-6": { + "Ethernet22|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet55|5-6": { + "Ethernet25|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet56|5-6": { + "Ethernet24|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet57|5-6": { + "Ethernet27|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet58|5-6": { + "Ethernet26|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index 3e485f4ddc35..be52694b78c5 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -42,7 +42,7 @@ dependent_startup_wait_for=rsyslogd:running programs=isc-dhcp-relay-Vlan1000 [program:isc-dhcp-relay-Vlan1000] -command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 192.0.0.1 192.0.0.2 +command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 192.0.0.1 192.0.0.2 priority=3 autostart=false autorestart=false @@ -56,7 +56,7 @@ dependent_startup_wait_for=start:exited programs=dhcpmon-Vlan1000 [program:dhcpmon-Vlan1000] -command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -im eth0 +command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 -im eth0 priority=4 autostart=false autorestart=false diff --git a/src/sonic-config-engine/tests/sample_output/frr.conf b/src/sonic-config-engine/tests/sample_output/frr.conf index 6e8573e9ba9d..1df7344a9d92 100644 --- a/src/sonic-config-engine/tests/sample_output/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/frr.conf @@ -19,13 +19,13 @@ agentx ! ! ! Enable link-detect (default disabled) -interface PortChannel01 +interface PortChannel03 link-detect ! interface PortChannel02 link-detect ! -interface PortChannel03 +interface PortChannel01 link-detect ! interface PortChannel04 diff --git a/src/sonic-config-engine/tests/sample_output/ipinip.json b/src/sonic-config-engine/tests/sample_output/ipinip.json index e4028ea01a2d..c93564de77e9 100644 --- a/src/sonic-config-engine/tests/sample_output/ipinip.json +++ b/src/sonic-config-engine/tests/sample_output/ipinip.json @@ -2,7 +2,7 @@ { "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { "tunnel_type":"IPINIP", - "dst_ip":"10.1.0.32,10.0.0.56,10.0.0.58,10.0.0.60,10.0.0.62,192.168.0.1", + "dst_ip":"10.1.0.32,10.0.0.58,10.0.0.60,10.0.0.62,10.0.0.56,192.168.0.1", "dscp_mode":"pipe", "ecn_mode":"copy_from_outer", "ttl_mode":"pipe" @@ -13,7 +13,7 @@ { "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { "tunnel_type":"IPINIP", - "dst_ip":"fc00:1::32,fc00::71,fc00::75,fc00::79,fc00::7d", + "dst_ip":"fc00:1::32,fc00::7d,fc00::79,fc00::71,fc00::75", "dscp_mode":"pipe", "ecn_mode":"copy_from_outer", "ttl_mode":"pipe" diff --git a/src/sonic-config-engine/tests/sample_output/l2switch.json b/src/sonic-config-engine/tests/sample_output/l2switch.json index fd83589153ea..1c9e0ebbcd2e 100644 --- a/src/sonic-config-engine/tests/sample_output/l2switch.json +++ b/src/sonic-config-engine/tests/sample_output/l2switch.json @@ -1,6 +1,11 @@ { "DEVICE_METADATA": {"localhost": {"hwsku": "Mellanox-SN2700"}}, "PORT": { + "Ethernet8": { + "alias": "fortyGigE0/8", + "lanes": "37,38,39,40", + "admin_status": "up" + }, "Ethernet0": { "alias": "fortyGigE0/0", "lanes": "29,30,31,32", @@ -11,59 +16,44 @@ "lanes": "25,26,27,28", "admin_status": "up" }, - "Ethernet8": { - "alias": "fortyGigE0/8", - "lanes": "37,38,39,40", - "admin_status": "up" - }, - "Ethernet12": { - "alias": "fortyGigE0/12", - "lanes": "33,34,35,36", - "admin_status": "up" - }, - "Ethernet16": { - "alias": "fortyGigE0/16", - "lanes": "41,42,43,44", - "admin_status": "up" - }, - "Ethernet20": { - "alias": "fortyGigE0/20", - "lanes": "45,46,47,48", + "Ethernet108": { + "alias": "fortyGigE0/108", + "lanes": "81,82,83,84", "admin_status": "up" }, - "Ethernet24": { - "alias": "fortyGigE0/24", - "lanes": "5,6,7,8", + "Ethernet100": { + "alias": "fortyGigE0/100", + "lanes": "125,126,127,128", "admin_status": "up" }, - "Ethernet28": { - "alias": "fortyGigE0/28", - "lanes": "1,2,3,4", + "Ethernet104": { + "alias": "fortyGigE0/104", + "lanes": "85,86,87,88", "admin_status": "up" }, - "Ethernet32": { - "alias": "fortyGigE0/32", - "lanes": "9,10,11,12", + "Ethernet68": { + "alias": "fortyGigE0/68", + "lanes": "69,70,71,72", "admin_status": "up" }, - "Ethernet36": { - "alias": "fortyGigE0/36", - "lanes": "13,14,15,16", + "Ethernet96": { + "alias": "fortyGigE0/96", + "lanes": "121,122,123,124", "admin_status": "up" }, - "Ethernet40": { - "alias": "fortyGigE0/40", - "lanes": "21,22,23,24", + "Ethernet124": { + "alias": "fortyGigE0/124", + "lanes": "101,102,103,104", "admin_status": "up" }, - "Ethernet44": { - "alias": "fortyGigE0/44", - "lanes": "17,18,19,20", + "Ethernet92": { + "alias": "fortyGigE0/92", + "lanes": "113,114,115,116", "admin_status": "up" }, - "Ethernet48": { - "alias": "fortyGigE0/48", - "lanes": "49,50,51,52", + "Ethernet120": { + "alias": "fortyGigE0/120", + "lanes": "97,98,99,100", "admin_status": "up" }, "Ethernet52": { @@ -76,9 +66,14 @@ "lanes": "61,62,63,64", "admin_status": "up" }, - "Ethernet60": { - "alias": "fortyGigE0/60", - "lanes": "57,58,59,60", + "Ethernet76": { + "alias": "fortyGigE0/76", + "lanes": "73,74,75,76", + "admin_status": "up" + }, + "Ethernet72": { + "alias": "fortyGigE0/72", + "lanes": "77,78,79,80", "admin_status": "up" }, "Ethernet64": { @@ -86,29 +81,24 @@ "lanes": "65,66,67,68", "admin_status": "up" }, - "Ethernet68": { - "alias": "fortyGigE0/68", - "lanes": "69,70,71,72", - "admin_status": "up" - }, - "Ethernet72": { - "alias": "fortyGigE0/72", - "lanes": "77,78,79,80", + "Ethernet32": { + "alias": "fortyGigE0/32", + "lanes": "9,10,11,12", "admin_status": "up" }, - "Ethernet76": { - "alias": "fortyGigE0/76", - "lanes": "73,74,75,76", + "Ethernet16": { + "alias": "fortyGigE0/16", + "lanes": "41,42,43,44", "admin_status": "up" }, - "Ethernet80": { - "alias": "fortyGigE0/80", - "lanes": "105,106,107,108", + "Ethernet36": { + "alias": "fortyGigE0/36", + "lanes": "13,14,15,16", "admin_status": "up" }, - "Ethernet84": { - "alias": "fortyGigE0/84", - "lanes": "109,110,111,112", + "Ethernet12": { + "alias": "fortyGigE0/12", + "lanes": "33,34,35,36", "admin_status": "up" }, "Ethernet88": { @@ -116,49 +106,59 @@ "lanes": "117,118,119,120", "admin_status": "up" }, - "Ethernet92": { - "alias": "fortyGigE0/92", - "lanes": "113,114,115,116", + "Ethernet116": { + "alias": "fortyGigE0/116", + "lanes": "93,94,95,96", "admin_status": "up" }, - "Ethernet96": { - "alias": "fortyGigE0/96", - "lanes": "121,122,123,124", + "Ethernet80": { + "alias": "fortyGigE0/80", + "lanes": "105,106,107,108", "admin_status": "up" }, - "Ethernet100": { - "alias": "fortyGigE0/100", - "lanes": "125,126,127,128", + "Ethernet112": { + "alias": "fortyGigE0/112", + "lanes": "89,90,91,92", "admin_status": "up" }, - "Ethernet104": { - "alias": "fortyGigE0/104", - "lanes": "85,86,87,88", + "Ethernet84": { + "alias": "fortyGigE0/84", + "lanes": "109,110,111,112", "admin_status": "up" }, - "Ethernet108": { - "alias": "fortyGigE0/108", - "lanes": "81,82,83,84", + "Ethernet48": { + "alias": "fortyGigE0/48", + "lanes": "49,50,51,52", "admin_status": "up" }, - "Ethernet112": { - "alias": "fortyGigE0/112", - "lanes": "89,90,91,92", + "Ethernet44": { + "alias": "fortyGigE0/44", + "lanes": "17,18,19,20", "admin_status": "up" }, - "Ethernet116": { - "alias": "fortyGigE0/116", - "lanes": "93,94,95,96", + "Ethernet40": { + "alias": "fortyGigE0/40", + "lanes": "21,22,23,24", "admin_status": "up" }, - "Ethernet120": { - "alias": "fortyGigE0/120", - "lanes": "97,98,99,100", + "Ethernet28": { + "alias": "fortyGigE0/28", + "lanes": "1,2,3,4", "admin_status": "up" }, - "Ethernet124": { - "alias": "fortyGigE0/124", - "lanes": "101,102,103,104", + "Ethernet60": { + "alias": "fortyGigE0/60", + "lanes": "57,58,59,60", + "admin_status": "up" + }, + "Ethernet20": { + "alias": "fortyGigE0/20", + "lanes": "45,46,47,48", + "admin_status": "up" + }, + "Ethernet24": { + "alias": "fortyGigE0/24", + "lanes": "5,6,7,8", "admin_status": "up" } }, @@ -168,43 +168,37 @@ } }, "VLAN_MEMBER": { - "Vlan1000|Ethernet0": { - "tagging_mode": "untagged" - }, - "Vlan1000|Ethernet4": { - "tagging_mode": "untagged" - }, "Vlan1000|Ethernet8": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet12": { + "Vlan1000|Ethernet0": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet16": { + "Vlan1000|Ethernet4": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet20": { + "Vlan1000|Ethernet108": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet24": { + "Vlan1000|Ethernet100": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet28": { + "Vlan1000|Ethernet104": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet32": { + "Vlan1000|Ethernet68": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet36": { + "Vlan1000|Ethernet96": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet40": { + "Vlan1000|Ethernet124": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet44": { + "Vlan1000|Ethernet92": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet48": { + "Vlan1000|Ethernet120": { "tagging_mode": "untagged" }, "Vlan1000|Ethernet52": { @@ -213,55 +207,61 @@ "Vlan1000|Ethernet56": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet60": { + "Vlan1000|Ethernet76": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet64": { + "Vlan1000|Ethernet72": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet68": { + "Vlan1000|Ethernet64": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet72": { + "Vlan1000|Ethernet32": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet76": { + "Vlan1000|Ethernet16": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet80": { + "Vlan1000|Ethernet36": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet84": { + "Vlan1000|Ethernet12": { "tagging_mode": "untagged" }, "Vlan1000|Ethernet88": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet92": { + "Vlan1000|Ethernet116": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet96": { + "Vlan1000|Ethernet80": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet100": { + "Vlan1000|Ethernet112": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet104": { + "Vlan1000|Ethernet84": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet108": { + "Vlan1000|Ethernet48": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet112": { + "Vlan1000|Ethernet44": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet116": { + "Vlan1000|Ethernet40": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet120": { + "Vlan1000|Ethernet28": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet124": { + "Vlan1000|Ethernet60": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet20": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet24": { "tagging_mode": "untagged" } } diff --git a/src/sonic-config-engine/tests/sample_output/ports.json b/src/sonic-config-engine/tests/sample_output/ports.json index 36f5ad117c39..0e174972fbe4 100644 --- a/src/sonic-config-engine/tests/sample_output/ports.json +++ b/src/sonic-config-engine/tests/sample_output/ports.json @@ -1,4 +1,11 @@ [ + { + "PORT_TABLE:Ethernet8": { + "speed": "1000", + "description": "Interface description" + }, + "OP": "SET" + }, { "PORT_TABLE:Ethernet0": { "speed": "10000", @@ -13,13 +20,6 @@ }, "OP": "SET" }, - { - "PORT_TABLE:Ethernet8": { - "speed": "1000", - "description": "Interface description" - }, - "OP": "SET" - }, { "PORT_TABLE:Ethernet12": { "speed": "100000", diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf index 180a0e9fab89..653cc1510fb0 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf @@ -20,13 +20,13 @@ vni 9000 ! ! ! Enable link-detect (default disabled) -interface Ethernet0 +interface Ethernet8 link-detect ! interface Ethernet4 link-detect ! -interface Ethernet8 +interface Ethernet0 link-detect ! !! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf index 661b27268255..a521da917d45 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf @@ -20,13 +20,13 @@ vni 8000 ! ! ! Enable link-detect (default disabled) -interface Ethernet0 +interface Ethernet8 link-detect ! interface Ethernet4 link-detect ! -interface Ethernet8 +interface Ethernet0 link-detect ! !! diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh index 6d90afa60ad7..2af5cee2f005 100644 --- a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh +++ b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh @@ -24,8 +24,8 @@ function wait_until_iface_ready # Wait for all interfaces with IPv4 addresses to be up and ready wait_until_iface_ready Vlan1000 192.168.0.1/27 -wait_until_iface_ready PortChannel01 10.0.0.56/31 wait_until_iface_ready PortChannel02 10.0.0.58/31 wait_until_iface_ready PortChannel03 10.0.0.60/31 wait_until_iface_ready PortChannel04 10.0.0.62/31 +wait_until_iface_ready PortChannel01 10.0.0.56/31 diff --git a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf index e3d0c2d55bc3..ee48a4e53cae 100644 --- a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf @@ -17,13 +17,13 @@ log facility local4 ! ! ! Enable link-detect (default disabled) -interface PortChannel01 +interface PortChannel03 link-detect ! interface PortChannel02 link-detect ! -interface PortChannel03 +interface PortChannel01 link-detect ! interface PortChannel04 diff --git a/src/sonic-config-engine/tests/sample_output/zebra_quagga.conf b/src/sonic-config-engine/tests/sample_output/zebra_quagga.conf index aa3486b0163a..b1b791b252e8 100644 --- a/src/sonic-config-engine/tests/sample_output/zebra_quagga.conf +++ b/src/sonic-config-engine/tests/sample_output/zebra_quagga.conf @@ -9,13 +9,13 @@ password zebra enable password zebra ! ! Enable link-detect (default disabled) -interface PortChannel01 +interface PortChannel03 link-detect ! interface PortChannel02 link-detect ! -interface PortChannel03 +interface PortChannel01 link-detect ! interface PortChannel04 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index fcdb7e9f2475..1fb231a96864 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -1,8 +1,11 @@ -from unittest import TestCase import json import subprocess import os +import tests.common_utils as utils + +from unittest import TestCase + TOR_ROUTER = 'ToRRouter' BACKEND_TOR_ROUTER = 'BackEndToRRouter' @@ -94,18 +97,23 @@ def test_additional_json_data(self): def test_additional_json_data_level1_key(self): argument = '-a \'{"k1":{"k11":"v11","k12":"v12"}, "k2":{"k22":"v22"}}\' --var-json k1' output = self.run_script(argument) - self.assertEqual(output.strip(), '{\n "k11": "v11", \n "k12": "v12"\n}') + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict('{\n "k11": "v11", \n "k12": "v12"\n}')) def test_additional_json_data_level2_key(self): argument = '-a \'{"k1":{"k11":"v11","k12":"v12"},"k2":{"k22":"v22"}}\' --var-json k1 -K k11' output = self.run_script(argument) - self.assertEqual(output.strip(), '{\n "k11": "v11"\n}') + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict('{\n "k11": "v11"\n}')) def test_var_json_data(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" --var-json VLAN_MEMBER' output = self.run_script(argument) - self.assertEqual(output.strip(), '{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "untagged"\n },' - ' \n "Vlan2020|Ethernet12": {\n "tagging_mode": "tagged"\n }\n}') + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + '{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "untagged"\n },' + ' \n "Vlan2020|Ethernet12": {\n "tagging_mode": "tagged"\n }\n}' + ) + ) def test_read_yaml(self): argument = '-v yml_item -y ' + os.path.join(self.test_dir, 'test.yml') @@ -147,16 +155,20 @@ def test_template_json_batch_mode(self): def test_minigraph_acl(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE' output = self.run_script(argument, True) - self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n" - "{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, " - "'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOW'}, " - "'EVERFLOW_EGRESS': {'stage': 'egress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOW_EGRESS'}, " - "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT', 'stage': 'ingress'}, " - "'DATAACLINGRESS': {'stage': 'ingress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04'], 'policy_desc': 'DATAACLINGRESS'}, " - "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL', 'stage': 'ingress'}, " - "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL', 'stage': 'ingress'}, " - "'DATAACLEGRESS': {'stage': 'egress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02'], 'policy_desc': 'DATAACLEGRESS'}, " - "'EVERFLOWV6': {'stage': 'ingress', 'type': 'MIRRORV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOWV6'}}") + self.assertEqual( + utils.to_dict(output.strip().replace("Warning: Ignoring Control Plane ACL NTP_ACL without type\n", '')), + utils.to_dict( + "{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, " + "'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOW'}, " + "'EVERFLOW_EGRESS': {'stage': 'egress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOW_EGRESS'}, " + "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT', 'stage': 'ingress'}, " + "'DATAACLINGRESS': {'stage': 'ingress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04'], 'policy_desc': 'DATAACLINGRESS'}, " + "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL', 'stage': 'ingress'}, " + "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL', 'stage': 'ingress'}, " + "'DATAACLEGRESS': {'stage': 'egress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02'], 'policy_desc': 'DATAACLEGRESS'}, " + "'EVERFLOWV6': {'stage': 'ingress', 'type': 'MIRRORV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOWV6'}}" + ) + ) # everflow portion is not used # def test_minigraph_everflow(self): @@ -167,7 +179,10 @@ def test_minigraph_acl(self): def test_minigraph_mgmt_ports(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v MGMT_PORT' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'eth0': {'alias': 'Management0', 'admin_status': 'up'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'eth0': {'alias': 'Management0', 'admin_status': 'up'}}") + ) def test_minigraph_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "INTERFACE.keys()"' @@ -177,16 +192,22 @@ def test_minigraph_interfaces(self): def test_minigraph_vlans(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN' output = self.run_script(argument) - self.assertEqual(output.strip(), - "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}, " - "'Vlan2020': {'alias': 'kk1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '2020'}}") - + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}, " + "'Vlan2020': {'alias': 'kk1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '2020'}}" + ) + ) def test_minigraph_vlan_members(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN_MEMBER' output = self.run_script(argument) - self.assertEqual(output.strip(), "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}, " - "('Vlan2020', 'Ethernet12'): {'tagging_mode': 'tagged'}}") + self.assertEqual( + output.strip(), + "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}, " + "('Vlan2020', 'Ethernet12'): {'tagging_mode': 'tagged'}}" + ) def test_minigraph_vlan_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' @@ -196,27 +217,42 @@ def test_minigraph_vlan_interfaces(self): def test_minigraph_portchannels(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v PORTCHANNEL' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + ) def test_minigraph_portchannel_with_more_member(self): argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v PORTCHANNEL' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'PortChannel01': {'admin_status': 'up', 'min_links': '3', 'members': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124'], 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'PortChannel01': {'admin_status': 'up', 'min_links': '3', 'members': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124'], 'mtu': '9100'}}") + ) def test_minigraph_portchannel_members(self): argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v "PORTCHANNEL_MEMBER.keys()"' output = self.run_script(argument) - self.assertEqual(output.strip(), "[('PortChannel01', 'Ethernet120'), ('PortChannel01', 'Ethernet116'), ('PortChannel01', 'Ethernet124'), ('PortChannel01', 'Ethernet112')]") + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("[('PortChannel01', 'Ethernet120'), ('PortChannel01', 'Ethernet116'), ('PortChannel01', 'Ethernet124'), ('PortChannel01', 'Ethernet112')]") + ) def test_minigraph_portchannel_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE.keys()"' output = self.run_script(argument) - self.assertEqual(output.strip(), "['PortChannel01', ('PortChannel01', '10.0.0.56/31'), ('PortChannel01', 'FC00::71/126')]") + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel01', ('PortChannel01', '10.0.0.56/31'), ('PortChannel01', 'FC00::71/126')]") + ) def test_minigraph_neighbors(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR[\'Ethernet124\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}") + ) # FIXME: This test depends heavily on the ordering of the interfaces and # it is not at all intuitive what that ordering should be. Could make it @@ -224,39 +260,57 @@ def test_minigraph_neighbors(self): def test_minigraph_extra_neighbors(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v DEVICE_NEIGHBOR' output = self.run_script(argument) - self.assertEqual(output.strip(), \ + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( "{'Ethernet124': {'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}, " "'Ethernet120': {'name': 'ARISTA03T1', 'port': 'Ethernet1/1'}, " "'Ethernet4': {'name': 'Servers0', 'port': 'eth0'}, " "'Ethernet116': {'name': 'ARISTA02T1', 'port': 'Ethernet1/1'}, " "'Ethernet100': {'name': 'Servers100', 'port': 'eth0'}, " "'Ethernet112': {'name': 'ARISTA01T1', 'port': 'Ethernet1/1'}}") + ) def test_minigraph_port_description(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") + ) def test_minigraph_port_fec_disabled(self): # Test for FECDisabled argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet4\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '25,26,27,28', 'description': 'Servers0:eth0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '100000'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '25,26,27,28', 'description': 'Servers0:eth0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '100000'}") + ) def test_minigraph_port_rs(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") + ) def test_minigraph_bgp(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "BGP_NEIGHBOR[\'10.0.0.59\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'rrclient': 0, 'name': 'ARISTA02T1', 'local_addr': '10.0.0.58', 'nhopself': 0, 'holdtime': '180', 'asn': '64600', 'keepalive': '60'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'rrclient': 0, 'name': 'ARISTA02T1', 'local_addr': '10.0.0.58', 'nhopself': 0, 'holdtime': '180', 'asn': '64600', 'keepalive': '60'}") + ) def test_minigraph_peers_with_range(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v BGP_PEER_RANGE.values\(\)' output = self.run_script(argument) - self.assertEqual(output.strip(), "[{'src_address': '10.1.0.32', 'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]") + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("[{'src_address': '10.1.0.32', 'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]") + ) def test_minigraph_deployment_id(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'deployment_id\']"' @@ -266,86 +320,100 @@ def test_minigraph_deployment_id(self): def test_minigraph_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet8\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}") + ) argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet12\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}") + ) def test_minigraph_neighbor_interfaces(self): argument = '-m "' + self.sample_graph_simple_case + '" -p "' + self.port_config + '" -v "PORT"' output = self.run_script(argument) - self.assertEqual(output.strip(), \ - "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '40000'}, " - "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'switch-01t1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " - "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, " - "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " - "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " - "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " - "'Ethernet68': {'alias': 'fortyGigE0/68', 'pfc_asym': 'off', 'lanes': '69,70,71,72', 'description': 'fortyGigE0/68', 'mtu': '9100'}, " - "'Ethernet96': {'alias': 'fortyGigE0/96', 'pfc_asym': 'off', 'lanes': '121,122,123,124', 'description': 'fortyGigE0/96', 'mtu': '9100'}, " - "'Ethernet124': {'alias': 'fortyGigE0/124', 'pfc_asym': 'off', 'lanes': '101,102,103,104', 'description': 'fortyGigE0/124', 'mtu': '9100'}, " - "'Ethernet92': {'alias': 'fortyGigE0/92', 'pfc_asym': 'off', 'lanes': '113,114,115,116', 'description': 'fortyGigE0/92', 'mtu': '9100'}, " - "'Ethernet120': {'alias': 'fortyGigE0/120', 'pfc_asym': 'off', 'lanes': '97,98,99,100', 'description': 'fortyGigE0/120', 'mtu': '9100'}, " - "'Ethernet52': {'alias': 'fortyGigE0/52', 'pfc_asym': 'off', 'lanes': '53,54,55,56', 'description': 'fortyGigE0/52', 'mtu': '9100'}, " - "'Ethernet56': {'alias': 'fortyGigE0/56', 'pfc_asym': 'off', 'lanes': '61,62,63,64', 'description': 'fortyGigE0/56', 'mtu': '9100'}, " - "'Ethernet76': {'alias': 'fortyGigE0/76', 'pfc_asym': 'off', 'lanes': '73,74,75,76', 'description': 'fortyGigE0/76', 'mtu': '9100'}, " - "'Ethernet72': {'alias': 'fortyGigE0/72', 'pfc_asym': 'off', 'lanes': '77,78,79,80', 'description': 'fortyGigE0/72', 'mtu': '9100'}, " - "'Ethernet64': {'alias': 'fortyGigE0/64', 'pfc_asym': 'off', 'lanes': '65,66,67,68', 'description': 'fortyGigE0/64', 'mtu': '9100'}, " - "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " - "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " - "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " - "'Ethernet12': {'lanes': '33,34,35,36', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '10000'}, " - "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " - "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " - "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " - "'Ethernet112': {'alias': 'fortyGigE0/112', 'pfc_asym': 'off', 'lanes': '89,90,91,92', 'description': 'fortyGigE0/112', 'mtu': '9100'}, " - "'Ethernet84': {'alias': 'fortyGigE0/84', 'pfc_asym': 'off', 'lanes': '109,110,111,112', 'description': 'fortyGigE0/84', 'mtu': '9100'}, " - "'Ethernet48': {'alias': 'fortyGigE0/48', 'pfc_asym': 'off', 'lanes': '49,50,51,52', 'description': 'fortyGigE0/48', 'mtu': '9100'}, " - "'Ethernet44': {'alias': 'fortyGigE0/44', 'pfc_asym': 'off', 'lanes': '17,18,19,20', 'description': 'fortyGigE0/44', 'mtu': '9100'}, " - "'Ethernet40': {'alias': 'fortyGigE0/40', 'pfc_asym': 'off', 'lanes': '21,22,23,24', 'description': 'fortyGigE0/40', 'mtu': '9100'}, " - "'Ethernet28': {'alias': 'fortyGigE0/28', 'pfc_asym': 'off', 'lanes': '1,2,3,4', 'description': 'fortyGigE0/28', 'mtu': '9100'}, " - "'Ethernet60': {'alias': 'fortyGigE0/60', 'pfc_asym': 'off', 'lanes': '57,58,59,60', 'description': 'fortyGigE0/60', 'mtu': '9100'}, " - "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " - "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '40000'}, " + "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'switch-01t1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " + "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, " + "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " + "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " + "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " + "'Ethernet68': {'alias': 'fortyGigE0/68', 'pfc_asym': 'off', 'lanes': '69,70,71,72', 'description': 'fortyGigE0/68', 'mtu': '9100'}, " + "'Ethernet96': {'alias': 'fortyGigE0/96', 'pfc_asym': 'off', 'lanes': '121,122,123,124', 'description': 'fortyGigE0/96', 'mtu': '9100'}, " + "'Ethernet124': {'alias': 'fortyGigE0/124', 'pfc_asym': 'off', 'lanes': '101,102,103,104', 'description': 'fortyGigE0/124', 'mtu': '9100'}, " + "'Ethernet92': {'alias': 'fortyGigE0/92', 'pfc_asym': 'off', 'lanes': '113,114,115,116', 'description': 'fortyGigE0/92', 'mtu': '9100'}, " + "'Ethernet120': {'alias': 'fortyGigE0/120', 'pfc_asym': 'off', 'lanes': '97,98,99,100', 'description': 'fortyGigE0/120', 'mtu': '9100'}, " + "'Ethernet52': {'alias': 'fortyGigE0/52', 'pfc_asym': 'off', 'lanes': '53,54,55,56', 'description': 'fortyGigE0/52', 'mtu': '9100'}, " + "'Ethernet56': {'alias': 'fortyGigE0/56', 'pfc_asym': 'off', 'lanes': '61,62,63,64', 'description': 'fortyGigE0/56', 'mtu': '9100'}, " + "'Ethernet76': {'alias': 'fortyGigE0/76', 'pfc_asym': 'off', 'lanes': '73,74,75,76', 'description': 'fortyGigE0/76', 'mtu': '9100'}, " + "'Ethernet72': {'alias': 'fortyGigE0/72', 'pfc_asym': 'off', 'lanes': '77,78,79,80', 'description': 'fortyGigE0/72', 'mtu': '9100'}, " + "'Ethernet64': {'alias': 'fortyGigE0/64', 'pfc_asym': 'off', 'lanes': '65,66,67,68', 'description': 'fortyGigE0/64', 'mtu': '9100'}, " + "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " + "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " + "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " + "'Ethernet12': {'lanes': '33,34,35,36', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '10000'}, " + "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " + "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " + "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " + "'Ethernet112': {'alias': 'fortyGigE0/112', 'pfc_asym': 'off', 'lanes': '89,90,91,92', 'description': 'fortyGigE0/112', 'mtu': '9100'}, " + "'Ethernet84': {'alias': 'fortyGigE0/84', 'pfc_asym': 'off', 'lanes': '109,110,111,112', 'description': 'fortyGigE0/84', 'mtu': '9100'}, " + "'Ethernet48': {'alias': 'fortyGigE0/48', 'pfc_asym': 'off', 'lanes': '49,50,51,52', 'description': 'fortyGigE0/48', 'mtu': '9100'}, " + "'Ethernet44': {'alias': 'fortyGigE0/44', 'pfc_asym': 'off', 'lanes': '17,18,19,20', 'description': 'fortyGigE0/44', 'mtu': '9100'}, " + "'Ethernet40': {'alias': 'fortyGigE0/40', 'pfc_asym': 'off', 'lanes': '21,22,23,24', 'description': 'fortyGigE0/40', 'mtu': '9100'}, " + "'Ethernet28': {'alias': 'fortyGigE0/28', 'pfc_asym': 'off', 'lanes': '1,2,3,4', 'description': 'fortyGigE0/28', 'mtu': '9100'}, " + "'Ethernet60': {'alias': 'fortyGigE0/60', 'pfc_asym': 'off', 'lanes': '57,58,59,60', 'description': 'fortyGigE0/60', 'mtu': '9100'}, " + "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " + "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}" + ) + ) def test_minigraph_extra_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT"' output = self.run_script(argument) - self.assertEqual(output.strip(), \ - "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}, " - "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'fortyGigE0/0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " - "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, " - "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " - "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " - "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " - "'Ethernet68': {'alias': 'fortyGigE0/68', 'pfc_asym': 'off', 'lanes': '69,70,71,72', 'description': 'fortyGigE0/68', 'mtu': '9100'}, " - "'Ethernet96': {'alias': 'fortyGigE0/96', 'pfc_asym': 'off', 'lanes': '121,122,123,124', 'description': 'fortyGigE0/96', 'mtu': '9100'}, " - "'Ethernet124': {'alias': 'fortyGigE0/124', 'pfc_asym': 'off', 'lanes': '101,102,103,104', 'description': 'fortyGigE0/124', 'mtu': '9100'}, " - "'Ethernet92': {'alias': 'fortyGigE0/92', 'pfc_asym': 'off', 'lanes': '113,114,115,116', 'description': 'fortyGigE0/92', 'mtu': '9100'}, " - "'Ethernet120': {'alias': 'fortyGigE0/120', 'pfc_asym': 'off', 'lanes': '97,98,99,100', 'description': 'fortyGigE0/120', 'mtu': '9100'}, " - "'Ethernet52': {'alias': 'fortyGigE0/52', 'pfc_asym': 'off', 'lanes': '53,54,55,56', 'description': 'fortyGigE0/52', 'mtu': '9100'}, " - "'Ethernet56': {'alias': 'fortyGigE0/56', 'pfc_asym': 'off', 'lanes': '61,62,63,64', 'description': 'fortyGigE0/56', 'mtu': '9100'}, " - "'Ethernet76': {'alias': 'fortyGigE0/76', 'pfc_asym': 'off', 'lanes': '73,74,75,76', 'description': 'fortyGigE0/76', 'mtu': '9100'}, " - "'Ethernet72': {'alias': 'fortyGigE0/72', 'pfc_asym': 'off', 'lanes': '77,78,79,80', 'description': 'fortyGigE0/72', 'mtu': '9100'}, " - "'Ethernet64': {'alias': 'fortyGigE0/64', 'pfc_asym': 'off', 'lanes': '65,66,67,68', 'description': 'fortyGigE0/64', 'mtu': '9100'}, " - "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " - "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " - "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " - "'Ethernet12': {'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}, " - "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " - "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " - "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " - "'Ethernet112': {'alias': 'fortyGigE0/112', 'pfc_asym': 'off', 'lanes': '89,90,91,92', 'description': 'fortyGigE0/112', 'mtu': '9100'}, " - "'Ethernet84': {'alias': 'fortyGigE0/84', 'pfc_asym': 'off', 'lanes': '109,110,111,112', 'description': 'fortyGigE0/84', 'mtu': '9100'}, " - "'Ethernet48': {'alias': 'fortyGigE0/48', 'pfc_asym': 'off', 'lanes': '49,50,51,52', 'description': 'fortyGigE0/48', 'mtu': '9100'}, " - "'Ethernet44': {'alias': 'fortyGigE0/44', 'pfc_asym': 'off', 'lanes': '17,18,19,20', 'description': 'fortyGigE0/44', 'mtu': '9100'}, " - "'Ethernet40': {'alias': 'fortyGigE0/40', 'pfc_asym': 'off', 'lanes': '21,22,23,24', 'description': 'fortyGigE0/40', 'mtu': '9100'}, " - "'Ethernet28': {'alias': 'fortyGigE0/28', 'pfc_asym': 'off', 'lanes': '1,2,3,4', 'description': 'fortyGigE0/28', 'mtu': '9100'}, " - "'Ethernet60': {'alias': 'fortyGigE0/60', 'pfc_asym': 'off', 'lanes': '57,58,59,60', 'description': 'fortyGigE0/60', 'mtu': '9100'}, " - "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " - "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}, " + "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'fortyGigE0/0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " + "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, " + "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " + "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " + "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " + "'Ethernet68': {'alias': 'fortyGigE0/68', 'pfc_asym': 'off', 'lanes': '69,70,71,72', 'description': 'fortyGigE0/68', 'mtu': '9100'}, " + "'Ethernet96': {'alias': 'fortyGigE0/96', 'pfc_asym': 'off', 'lanes': '121,122,123,124', 'description': 'fortyGigE0/96', 'mtu': '9100'}, " + "'Ethernet124': {'alias': 'fortyGigE0/124', 'pfc_asym': 'off', 'lanes': '101,102,103,104', 'description': 'fortyGigE0/124', 'mtu': '9100'}, " + "'Ethernet92': {'alias': 'fortyGigE0/92', 'pfc_asym': 'off', 'lanes': '113,114,115,116', 'description': 'fortyGigE0/92', 'mtu': '9100'}, " + "'Ethernet120': {'alias': 'fortyGigE0/120', 'pfc_asym': 'off', 'lanes': '97,98,99,100', 'description': 'fortyGigE0/120', 'mtu': '9100'}, " + "'Ethernet52': {'alias': 'fortyGigE0/52', 'pfc_asym': 'off', 'lanes': '53,54,55,56', 'description': 'fortyGigE0/52', 'mtu': '9100'}, " + "'Ethernet56': {'alias': 'fortyGigE0/56', 'pfc_asym': 'off', 'lanes': '61,62,63,64', 'description': 'fortyGigE0/56', 'mtu': '9100'}, " + "'Ethernet76': {'alias': 'fortyGigE0/76', 'pfc_asym': 'off', 'lanes': '73,74,75,76', 'description': 'fortyGigE0/76', 'mtu': '9100'}, " + "'Ethernet72': {'alias': 'fortyGigE0/72', 'pfc_asym': 'off', 'lanes': '77,78,79,80', 'description': 'fortyGigE0/72', 'mtu': '9100'}, " + "'Ethernet64': {'alias': 'fortyGigE0/64', 'pfc_asym': 'off', 'lanes': '65,66,67,68', 'description': 'fortyGigE0/64', 'mtu': '9100'}, " + "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " + "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " + "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " + "'Ethernet12': {'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}, " + "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " + "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " + "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " + "'Ethernet112': {'alias': 'fortyGigE0/112', 'pfc_asym': 'off', 'lanes': '89,90,91,92', 'description': 'fortyGigE0/112', 'mtu': '9100'}, " + "'Ethernet84': {'alias': 'fortyGigE0/84', 'pfc_asym': 'off', 'lanes': '109,110,111,112', 'description': 'fortyGigE0/84', 'mtu': '9100'}, " + "'Ethernet48': {'alias': 'fortyGigE0/48', 'pfc_asym': 'off', 'lanes': '49,50,51,52', 'description': 'fortyGigE0/48', 'mtu': '9100'}, " + "'Ethernet44': {'alias': 'fortyGigE0/44', 'pfc_asym': 'off', 'lanes': '17,18,19,20', 'description': 'fortyGigE0/44', 'mtu': '9100'}, " + "'Ethernet40': {'alias': 'fortyGigE0/40', 'pfc_asym': 'off', 'lanes': '21,22,23,24', 'description': 'fortyGigE0/40', 'mtu': '9100'}, " + "'Ethernet28': {'alias': 'fortyGigE0/28', 'pfc_asym': 'off', 'lanes': '1,2,3,4', 'description': 'fortyGigE0/28', 'mtu': '9100'}, " + "'Ethernet60': {'alias': 'fortyGigE0/60', 'pfc_asym': 'off', 'lanes': '57,58,59,60', 'description': 'fortyGigE0/60', 'mtu': '9100'}, " + "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " + "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}" + ) + ) # everflow portion is not used # def test_metadata_everflow(self): @@ -356,12 +424,15 @@ def test_minigraph_extra_ethernet_interfaces(self): def test_metadata_tacacs(self): argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "TACPLUS_SERVER"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'10.0.10.7': {'priority': '1', 'tcp_port': '49'}, '10.0.10.8': {'priority': '1', 'tcp_port': '49'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'10.0.10.7': {'priority': '1', 'tcp_port': '49'}, '10.0.10.8': {'priority': '1', 'tcp_port': '49'}}") + ) def test_metadata_ntp(self): argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "NTP_SERVER"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'10.0.10.1': {}, '10.0.10.2': {}}") + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict("{'10.0.10.1': {}, '10.0.10.2': {}}")) def test_minigraph_vnet(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VNET"' @@ -376,7 +447,10 @@ def test_minigraph_vxlan(self): def test_minigraph_bgp_mon(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "BGP_MONITORS"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") + ) def test_minigraph_sub_port_interfaces(self, check_stderr=True): try: @@ -414,13 +488,17 @@ def test_minigraph_sub_port_interfaces(self, check_stderr=True): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN_SUB_INTERFACE' output = self.run_script(argument) print(output.strip()) - self.assertEqual(output.strip(), \ + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( "{('PortChannel01.10', '10.0.0.56/31'): {}, " "'Ethernet0.10': {'admin_status': 'up'}, " "('Ethernet0.10', '10.0.0.58/31'): {}, " "('PortChannel01.10', 'FC00::71/126'): {}, " "'PortChannel01.10': {'admin_status': 'up'}, " - "('Ethernet0.10', 'FC00::75/126'): {}}") + "('Ethernet0.10', 'FC00::75/126'): {}}" + ) + ) finally: print('\n Change device type back to %s' % (TOR_ROUTER)) diff --git a/src/sonic-config-engine/tests/test_cfggen_platformJson.py b/src/sonic-config-engine/tests/test_cfggen_platformJson.py index dedddadde1cd..751da15caeb6 100644 --- a/src/sonic-config-engine/tests/test_cfggen_platformJson.py +++ b/src/sonic-config-engine/tests/test_cfggen_platformJson.py @@ -1,8 +1,12 @@ -from unittest import TestCase -import subprocess -import os -import json import ast +import json +import os +import subprocess + +import tests.common_utils as utils + +from unittest import TestCase + # Global Variable PLATFORM_OUTPUT_FILE = "platform_output.json" @@ -54,12 +58,12 @@ def test_platform_json_specific_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT[\'Ethernet8\']"' output = self.run_script(argument) expected = "{'index': '3', 'lanes': '8', 'description': 'Eth3/1', 'admin_status': 'up', 'mtu': '9100', 'alias': 'Eth3/1', 'pfc_asym': 'off', 'speed': '25000'}" - self.assertEqual(output.strip(), expected) + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict(expected)) argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT[\'Ethernet112\']"' output = self.run_script(argument) expected = "{'index': '29', 'lanes': '112', 'description': 'Eth29/1', 'admin_status': 'up', 'mtu': '9100', 'alias': 'Eth29/1', 'pfc_asym': 'off', 'speed': '25000'}" - self.assertEqual(output.strip(), expected) + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict(expected)) # Check all Interface with it's proper configuration as per platform.json def test_platform_json_all_ethernet_interfaces(self): diff --git a/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py b/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py index c13575d25690..d0a4f2c0de59 100644 --- a/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py +++ b/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py @@ -1,6 +1,10 @@ -from unittest import TestCase -import subprocess import os +import subprocess + +import tests.common_utils as utils + +from unittest import TestCase + class TestCfgGenT2ChassisFe(TestCase): @@ -34,24 +38,31 @@ def test_minigraph_t2_chassis_fe_type(self): def test_minigraph_t2_chassis_fe_interfaces(self): argument = '-m "' + self.sample_graph_t2_chassis_fe + '" -p "' + self.t2_chassis_fe_port_config + '" -v "INTERFACE"' output = self.run_script(argument) - self.assertEqual(output.strip(), - "{'Ethernet8': {}, " - "('Ethernet8', '172.16.0.9/30'): {}, " - "'Ethernet0': {'vnet_name': 'VnetFE'}, " - "('Ethernet4', '172.16.0.1/30'): {}, " - "('Ethernet0', '192.168.0.2/30'): {}, " - "'Ethernet4': {}}") - + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Ethernet8': {}, " + "('Ethernet8', '172.16.0.9/30'): {}, " + "'Ethernet0': {'vnet_name': 'VnetFE'}, " + "('Ethernet4', '172.16.0.1/30'): {}, " + "('Ethernet0', '192.168.0.2/30'): {}, " + "'Ethernet4': {}}" + ) + ) def test_minigraph_t2_chassis_fe_pc_interfaces(self): argument = '-m "' + self.sample_graph_t2_chassis_fe_pc + '" -p "' + self.t2_chassis_fe_port_config + '" -v "PORTCHANNEL_INTERFACE"' output = self.run_script(argument) - self.assertEqual(output.strip(), - "{'PortChannel8': {}, " - "('PortChannel0', '192.168.0.2/30'): {}, " - "('PortChannel4', '172.16.0.1/30'): {}, " - "'PortChannel4': {}, " - "('PortChannel8', '172.16.0.9/30'): {}, " - "'PortChannel0': {'vnet_name': 'VnetFE'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'PortChannel8': {}, " + "('PortChannel0', '192.168.0.2/30'): {}, " + "('PortChannel4', '172.16.0.1/30'): {}, " + "'PortChannel4': {}, " + "('PortChannel8', '172.16.0.9/30'): {}, " + "'PortChannel0': {'vnet_name': 'VnetFE'}}" + ) + ) # Test a minigraph file where VNI is not specified # Default VNI is 8000 diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index b1b6024df8b5..3f5fd46bf55e 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -1,6 +1,10 @@ -from unittest import TestCase -import subprocess import os +import subprocess + +import tests.common_utils as utils + +from unittest import TestCase + class TestCfgGenCaseInsensitive(TestCase): @@ -73,7 +77,10 @@ def test_minigraph_interfaces(self): def test_minigraph_vlans(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v VLAN' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}}") + ) def test_minigraph_vlan_members(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v VLAN_MEMBER' @@ -88,12 +95,17 @@ def test_minigraph_vlan_interfaces(self): def test_minigraph_portchannels(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v PORTCHANNEL' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + ) def test_minigraph_console_port(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v CONSOLE_PORT' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'1': {'baud_rate': '9600', 'remote_device': 'managed_device', 'flow_control': 1}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'1': {'baud_rate': '9600', 'remote_device': 'managed_device', 'flow_control': 1}}")) def test_minigraph_deployment_id(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'deployment_id\']"' @@ -103,7 +115,10 @@ def test_minigraph_deployment_id(self): def test_minigraph_neighbor_metadata(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR_METADATA"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'switch-01t1': {'lo_addr': '10.1.0.186/32', 'mgmt_addr': '10.7.0.196/26', 'hwsku': 'Force10-S6000', 'type': 'LeafRouter', 'deployment_id': '2'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'switch-01t1': {'lo_addr': '10.1.0.186/32', 'mgmt_addr': '10.7.0.196/26', 'hwsku': 'Force10-S6000', 'type': 'LeafRouter', 'deployment_id': '2'}}") + ) # everflow portion is not used # def test_metadata_everflow(self): diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 77e79a2b5fe1..bb2f93a0880e 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -1,10 +1,14 @@ -import unittest -from unittest import TestCase -import subprocess -import os import json -import yaml +import os import shutil +import subprocess +import unittest +import yaml + +import tests.common_utils as utils + +from unittest import TestCase + SKU = 'multi-npu-01' ASIC_SKU = 'multi-npu-asic' @@ -136,27 +140,35 @@ def test_backend_asic_portchannels(self): def test_frontend_asic_portchannel_mem(self): argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL_MEMBER\"".format(self.sample_graph, self.port_config[0]) - output = json.loads(self.run_script(argument)) - self.assertListEqual(list(output.keys()), \ - ['PortChannel4002|Ethernet-BP8', 'PortChannel0002|Ethernet0', 'PortChannel0002|Ethernet4', 'PortChannel4002|Ethernet-BP12', 'PortChannel4001|Ethernet-BP0', 'PortChannel4001|Ethernet-BP4']) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel4002|Ethernet-BP8', 'PortChannel0002|Ethernet0', 'PortChannel0002|Ethernet4', 'PortChannel4002|Ethernet-BP12', 'PortChannel4001|Ethernet-BP0', 'PortChannel4001|Ethernet-BP4']") + ) def test_backend_asic_portchannels_mem(self): argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL_MEMBER\"".format(self.sample_graph, self.port_config[3]) - output = json.loads(self.run_script(argument)) - self.assertListEqual(list(output.keys()), \ - ['PortChannel4013|Ethernet-BP384', 'PortChannel4014|Ethernet-BP392', 'PortChannel4014|Ethernet-BP396', 'PortChannel4013|Ethernet-BP388']) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel4013|Ethernet-BP384', 'PortChannel4014|Ethernet-BP392', 'PortChannel4014|Ethernet-BP396', 'PortChannel4013|Ethernet-BP388']") + ) def test_frontend_asic_portchannel_intf(self): argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[0]) - output = json.loads(self.run_script(argument)) - self.assertListEqual(list(output.keys()), \ - ['PortChannel4001|10.1.0.1/31', 'PortChannel0002|FC00::1/126', 'PortChannel4002|10.1.0.3/31', 'PortChannel0002', 'PortChannel0002|10.0.0.0/31', 'PortChannel4001', 'PortChannel4002']) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel4001|10.1.0.1/31', 'PortChannel0002|FC00::1/126', 'PortChannel4002|10.1.0.3/31', 'PortChannel0002', 'PortChannel0002|10.0.0.0/31', 'PortChannel4001', 'PortChannel4002']") + ) def test_backend_asic_portchannel_intf(self): argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[3]) - output = json.loads(self.run_script(argument)) - self.assertListEqual(list(output.keys()), \ - ['PortChannel4013', 'PortChannel4013|10.1.0.2/31', 'PortChannel4014', 'PortChannel4014|10.1.0.6/31']) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel4013', 'PortChannel4013|10.1.0.2/31', 'PortChannel4014', 'PortChannel4014|10.1.0.6/31']") + ) def test_frontend_asic_ports(self): argument = "-m {} -p {} -n asic0 --var-json \"PORT\"".format(self.sample_graph, self.port_config[0]) From 6754635010396d91622947958a2a96725db10ea6 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 20:21:46 -0700 Subject: [PATCH 1187/1427] [cfggen] Make Jinja2 Template Python 3 Compatible Jinja2 templates rendered using Python 3 interpreter, are required to conform with Python 3 new semantics. singed-off-by: Tamer Ahmed --- .../bgpd.spine_chassis_frontend_router.conf.j2 | 14 +++++++------- .../docker-fpm-frr/frr/common/functions.conf.j2 | 4 ++-- .../frr/zebra/zebra.interfaces.conf.j2 | 2 +- dockers/docker-fpm-quagga/bgpd.conf.j2 | 8 ++++---- dockers/docker-lldp/lldpd.conf.j2 | 4 ++-- dockers/docker-orchagent/ports.json.j2 | 2 +- src/sonic-config-engine/data/l2switch.j2 | 2 +- src/sonic-config-engine/tests/test_cfggen.py | 12 ++++++------ .../tests/test_cfggen_platformJson.py | 2 +- .../tests/test_minigraph_case.py | 4 ++-- .../tests/test_multinpu_cfggen.py | 8 ++++---- 11 files changed, 31 insertions(+), 31 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 index afb621b0bf61..94dacbc3af78 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 @@ -3,7 +3,7 @@ ! Vnet BGP instance {% set interfaces_in_vnets = [] %} {% block vnet_bgp_instance %} -{% for vnet_name, vnet_metadata in VNET.iteritems() %} +{% for vnet_name, vnet_metadata in VNET.items() %} router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} no bgp default ipv4-unicast bgp log-neighbor-changes @@ -19,9 +19,9 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} {% endfor %} {# Got interfaces that belong this vnet #} {% set interfaces_in_vnet = [] %} -{% for (key, metadata) in INTERFACE.iteritems() %} -{% if metadata.has_key("vnet_name") and metadata["vnet_name"] == vnet_name %} -{% for (name_prefix_pair, metadata) in INTERFACE.iteritems() %} +{% for (key, metadata) in INTERFACE.items() %} +{% if "vnet_name" in metadata and metadata["vnet_name"] == vnet_name %} +{% for (name_prefix_pair, metadata) in INTERFACE.items() %} {% if key == name_prefix_pair[0] %} {% if interfaces_in_vnet.append( name_prefix_pair[1] | ip ) %} {% endif %} @@ -32,8 +32,8 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} {% endif %} {% endfor %} {# Each bgp neighbors #} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} -{% if bgp_session.has_key("local_addr") and bgp_session["local_addr"] in interfaces_in_vnet %} +{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.items() %} +{% if "local_addr" in bgp_session and bgp_session["local_addr"] in interfaces_in_vnet %} {% if bgp_session['asn'] | int != 0 %} neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} @@ -42,7 +42,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} {% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} +{% if 'admin_status' in bgp_session and bgp_session['admin_status'] == 'down' or 'admin_status' not in bgp_session and 'default_bgp_status' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} neighbor {{ neighbor_addr }} shutdown {% endif %} {% if neighbor_addr | ipv4 %} diff --git a/dockers/docker-fpm-frr/frr/common/functions.conf.j2 b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 index 2049e1141429..34700db329ca 100644 --- a/dockers/docker-fpm-frr/frr/common/functions.conf.j2 +++ b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 @@ -25,8 +25,8 @@ {% macro get_vnet_interfaces(interfaces) -%} {% set L = namespace(intfs=[]) %} {% set vnet_intfs = [] %} -{% for (key, metadata) in interfaces.iteritems() %} -{% if metadata.has_key("vnet_name") %} +{% for (key, metadata) in interfaces.items() %} +{% if "vnet_name" in metadata %} {% set vnet_intfs = vnet_intfs.append(key) %} {% endif %} {% endfor %} diff --git a/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 index 484efeba5850..7526239db8a6 100644 --- a/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 @@ -1,7 +1,7 @@ ! {% block vrf %} {% if VNET is defined %} -{% for vnet_name, vnet_metadata in VNET.iteritems() %} +{% for vnet_name, vnet_metadata in VNET.items() %} vrf {{ vnet_name }} vni {{ vnet_metadata['vni'] }} ! diff --git a/dockers/docker-fpm-quagga/bgpd.conf.j2 b/dockers/docker-fpm-quagga/bgpd.conf.j2 index 2f4c741303a4..8c838f8ffc9d 100644 --- a/dockers/docker-fpm-quagga/bgpd.conf.j2 +++ b/dockers/docker-fpm-quagga/bgpd.conf.j2 @@ -14,7 +14,7 @@ log facility local4 ! enable password {# {{ en_passwd }} TODO: param needed #} {% endblock system_init %} ! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} +{% if 'bgp_asn' in DEVICE_METADATA['localhost'] %} {% block bgp_init %} ! ! bgp multiple-instance @@ -58,7 +58,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endfor %} {% endblock vlan_advertisement %} {% block bgp_sessions %} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} +{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.items() %} {% if bgp_session['asn'] | int != 0 %} neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} @@ -67,7 +67,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} {% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} +{% if 'admin_status' in bgp_session and bgp_session['admin_status'] == 'down' or 'admin_status' not in bgp_session and 'default_bgp_status' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} neighbor {{ neighbor_addr }} shutdown {% endif %} {% if neighbor_addr | ipv4 %} @@ -131,7 +131,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} {% endblock bgp_peers_with_range %} ! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} +{% if 'bgp_asn' in DEVICE_METADATA['localhost'] %} maximum-paths 64 ! route-map ISOLATE permit 10 diff --git a/dockers/docker-lldp/lldpd.conf.j2 b/dockers/docker-lldp/lldpd.conf.j2 index d5b6dba8700c..421400037bbf 100644 --- a/dockers/docker-lldp/lldpd.conf.j2 +++ b/dockers/docker-lldp/lldpd.conf.j2 @@ -1,7 +1,7 @@ {% if MGMT_INTERFACE %} {# If MGMT port alias is available, use it for port ID subtype, otherwise use port name #} -{% set mgmt_port_name = MGMT_INTERFACE.keys()[0][0] %} -{% set ipv4 = MGMT_INTERFACE.keys()[0][1].split('/')[0] %} +{% set mgmt_port_name = (MGMT_INTERFACE.keys()|list)[0][0] %} +{% set ipv4 = (MGMT_INTERFACE.keys()|list)[0][1].split('/')[0] %} {% if MGMT_PORT and MGMT_PORT[mgmt_port_name] and MGMT_PORT[mgmt_port_name].alias %} configure ports eth0 lldp portidsubtype local {{ MGMT_PORT[mgmt_port_name].alias }} {% else %} diff --git a/dockers/docker-orchagent/ports.json.j2 b/dockers/docker-orchagent/ports.json.j2 index b10d4d58a43d..296d97cde07b 100644 --- a/dockers/docker-orchagent/ports.json.j2 +++ b/dockers/docker-orchagent/ports.json.j2 @@ -2,7 +2,7 @@ {% set ports_with_speed_set=[] %} {% if PORT %} {% for port in PORT %} -{% if PORT[port].has_key('speed') %} +{% if 'speed' in PORT[port] %} {%- if ports_with_speed_set.append(port) -%}{%- endif -%} {%- endif -%} {% endfor %} diff --git a/src/sonic-config-engine/data/l2switch.j2 b/src/sonic-config-engine/data/l2switch.j2 index c9f166b6798b..86dca30cb739 100644 --- a/src/sonic-config-engine/data/l2switch.j2 +++ b/src/sonic-config-engine/data/l2switch.j2 @@ -2,7 +2,7 @@ "DEVICE_METADATA": {{ DEVICE_METADATA | tojson }}, {% set ns = {'firstPrinted': False} -%} "PORT": { - {%- for key,value in PORT.iteritems() -%} + {%- for key,value in PORT.items() -%} {%- if ns.firstPrinted %},{% endif %} "{{ key }}": { diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 1fb231a96864..d42438e61c25 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -58,7 +58,7 @@ def test_device_desc(self): self.assertEqual(output.strip(), 'ACS-MSN2700') def test_device_desc_mgmt_ip(self): - argument = '-v "MGMT_INTERFACE.keys()[0]" -M "' + self.sample_device_desc + '"' + argument = '-v "(MGMT_INTERFACE.keys()|list)[0]" -M "' + self.sample_device_desc + '"' output = self.run_script(argument) self.assertEqual(output.strip(), "('eth0', '10.0.1.5/28')") @@ -185,7 +185,7 @@ def test_minigraph_mgmt_ports(self): ) def test_minigraph_interfaces(self): - argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "INTERFACE.keys()"' + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Ethernet0', '10.0.0.58/31'), 'Ethernet0', ('Ethernet0', 'FC00::75/126')]") @@ -210,7 +210,7 @@ def test_minigraph_vlan_members(self): ) def test_minigraph_vlan_interfaces(self): - argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Vlan1000', '192.168.0.1/27'), 'Vlan1000']") @@ -231,7 +231,7 @@ def test_minigraph_portchannel_with_more_member(self): ) def test_minigraph_portchannel_members(self): - argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v "PORTCHANNEL_MEMBER.keys()"' + argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v "PORTCHANNEL_MEMBER.keys()|list"' output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), @@ -239,7 +239,7 @@ def test_minigraph_portchannel_members(self): ) def test_minigraph_portchannel_interfaces(self): - argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE.keys()"' + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), @@ -305,7 +305,7 @@ def test_minigraph_bgp(self): ) def test_minigraph_peers_with_range(self): - argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v BGP_PEER_RANGE.values\(\)' + argument = "-m " + self.sample_graph_bgp_speaker + " -p " + self.port_config + " -v \"BGP_PEER_RANGE.values()|list\"" output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), diff --git a/src/sonic-config-engine/tests/test_cfggen_platformJson.py b/src/sonic-config-engine/tests/test_cfggen_platformJson.py index 751da15caeb6..34fde9a8e5ca 100644 --- a/src/sonic-config-engine/tests/test_cfggen_platformJson.py +++ b/src/sonic-config-engine/tests/test_cfggen_platformJson.py @@ -46,7 +46,7 @@ def test_print_data(self): # Check whether all interfaces present or not as per platform.json def test_platform_json_interfaces_keys(self): - argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT.keys()"' + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT.keys()|list"' output = self.run_script(argument) expected = "['Ethernet8', 'Ethernet9', 'Ethernet36', 'Ethernet98', 'Ethernet0', 'Ethernet6', 'Ethernet4', 'Ethernet109', 'Ethernet108', 'Ethernet18', 'Ethernet100', 'Ethernet34', 'Ethernet104', 'Ethernet106', 'Ethernet94', 'Ethernet126', 'Ethernet96', 'Ethernet124', 'Ethernet90', 'Ethernet91', 'Ethernet92', 'Ethernet93', 'Ethernet50', 'Ethernet51', 'Ethernet52', 'Ethernet53', 'Ethernet54', 'Ethernet99', 'Ethernet56', 'Ethernet113', 'Ethernet76', 'Ethernet74', 'Ethernet39', 'Ethernet72', 'Ethernet73', 'Ethernet70', 'Ethernet71', 'Ethernet32', 'Ethernet33', 'Ethernet16', 'Ethernet111', 'Ethernet10', 'Ethernet11', 'Ethernet12', 'Ethernet13', 'Ethernet58', 'Ethernet19', 'Ethernet59', 'Ethernet38', 'Ethernet78', 'Ethernet68', 'Ethernet14', 'Ethernet89', 'Ethernet88', 'Ethernet118', 'Ethernet119', 'Ethernet116', 'Ethernet114', 'Ethernet80', 'Ethernet112', 'Ethernet86', 'Ethernet110', 'Ethernet84', 'Ethernet31', 'Ethernet49', 'Ethernet48', 'Ethernet46', 'Ethernet30', 'Ethernet29', 'Ethernet40', 'Ethernet120', 'Ethernet28', 'Ethernet66', 'Ethernet60', 'Ethernet64', 'Ethernet44', 'Ethernet20', 'Ethernet79', 'Ethernet69', 'Ethernet24', 'Ethernet26']" diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 3f5fd46bf55e..505d5cfcbf7f 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -70,7 +70,7 @@ def test_render_template(self): # self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") def test_minigraph_interfaces(self): - argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v \'INTERFACE.keys()\'' + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v \'INTERFACE.keys()|list\'' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Ethernet0', '10.0.0.58/31'), 'Ethernet0', ('Ethernet0', 'FC00::75/126')]") @@ -88,7 +88,7 @@ def test_minigraph_vlan_members(self): self.assertEqual(output.strip(), "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}}") def test_minigraph_vlan_interfaces(self): - argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Vlan1000', '192.168.0.1/27'), 'Vlan1000']") diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index bb2f93a0880e..2aa212e30aae 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -139,7 +139,7 @@ def test_backend_asic_portchannels(self): 'PortChannel4014': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP392', 'Ethernet-BP396'], 'mtu': '9100'}}) def test_frontend_asic_portchannel_mem(self): - argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL_MEMBER\"".format(self.sample_graph, self.port_config[0]) + argument = "-m {} -p {} -n asic0 -v \"PORTCHANNEL_MEMBER.keys()|list\"".format(self.sample_graph, self.port_config[0]) output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), @@ -147,7 +147,7 @@ def test_frontend_asic_portchannel_mem(self): ) def test_backend_asic_portchannels_mem(self): - argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL_MEMBER\"".format(self.sample_graph, self.port_config[3]) + argument = "-m {} -p {} -n asic3 -v \"PORTCHANNEL_MEMBER.keys()|list\"".format(self.sample_graph, self.port_config[3]) output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), @@ -155,7 +155,7 @@ def test_backend_asic_portchannels_mem(self): ) def test_frontend_asic_portchannel_intf(self): - argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[0]) + argument = "-m {} -p {} -n asic0 -v \"PORTCHANNEL_INTERFACE.keys()|list\"".format(self.sample_graph, self.port_config[0]) output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), @@ -163,7 +163,7 @@ def test_frontend_asic_portchannel_intf(self): ) def test_backend_asic_portchannel_intf(self): - argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[3]) + argument = "-m {} -p {} -n asic3 -v \"PORTCHANNEL_INTERFACE.keys()|list\"".format(self.sample_graph, self.port_config[3]) output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), From 99ffce6b57209de4ec66e7eabf004571c9c708c7 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 22:23:48 -0700 Subject: [PATCH 1188/1427] [cfggen] Move Python 2 Test Data to Py2 Folder Rendering templates show different orders when rendered using Python 2 vs Python 3. This PR prepare for Python 3 packaging by creating new dir 'py2' for Python 2 rendered test cases. singed-off-by: Tamer Ahmed --- src/sonic-config-engine/tests/common_utils.py | 2 ++ .../multi_npu_data/{ => py2}/ipinip.json | 0 .../sample_output/{ => py2}/bgpd_frr.conf | 0 .../sample_output/{ => py2}/bgpd_quagga.conf | 0 .../{ => py2}/buffers-dell6100.json | 0 .../docker-dhcp-relay.supervisord.conf | 0 .../tests/sample_output/{ => py2}/frr.conf | 0 .../tests/sample_output/{ => py2}/interfaces | 0 .../tests/sample_output/{ => py2}/ipinip.json | 0 .../sample_output/{ => py2}/l2switch.json | 0 .../tests/sample_output/{ => py2}/lldpd.conf | 0 .../sample_output/{ => py2}/mvrf_interfaces | 0 .../tests/sample_output/{ => py2}/ports.json | 0 .../{ => py2}/qos-arista7050.json | 0 .../sample_output/{ => py2}/qos-dell6100.json | 0 .../sample_output/{ => py2}/staticd_frr.conf | 0 .../{ => py2}/t2-chassis-fe-bgpd.conf | 0 .../{ => py2}/t2-chassis-fe-vni-zebra.conf | 0 .../{ => py2}/t2-chassis-fe-zebra.conf | 0 .../sample_output/{ => py2}/wait_for_intf.sh | 0 .../sample_output/{ => py2}/zebra_frr.conf | 0 .../sample_output/{ => py2}/zebra_quagga.conf | 0 src/sonic-config-engine/tests/test_frr.py | 11 +++--- src/sonic-config-engine/tests/test_j2files.py | 34 ++++++++++--------- .../tests/test_j2files_t2_chassis_fe.py | 8 +++-- 25 files changed, 32 insertions(+), 23 deletions(-) rename src/sonic-config-engine/tests/multi_npu_data/{ => py2}/ipinip.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/bgpd_frr.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/bgpd_quagga.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/buffers-dell6100.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/docker-dhcp-relay.supervisord.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/frr.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/interfaces (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/ipinip.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/l2switch.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/lldpd.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/mvrf_interfaces (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/ports.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/qos-arista7050.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/qos-dell6100.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/staticd_frr.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/t2-chassis-fe-bgpd.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/t2-chassis-fe-vni-zebra.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/t2-chassis-fe-zebra.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/wait_for_intf.sh (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/zebra_frr.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/zebra_quagga.conf (100%) diff --git a/src/sonic-config-engine/tests/common_utils.py b/src/sonic-config-engine/tests/common_utils.py index f75584471eb4..142bf2f4dde1 100644 --- a/src/sonic-config-engine/tests/common_utils.py +++ b/src/sonic-config-engine/tests/common_utils.py @@ -2,6 +2,8 @@ import re import sys +PY3x = sys.version_info >= (3, 0) +PYvX_DIR = "py3" if PY3x else "py2" def tuple_to_str(tuplestr): """ Convert Python tuple '('elem1', 'elem2')' representation into string on the for "elem1|elem2" """ diff --git a/src/sonic-config-engine/tests/multi_npu_data/ipinip.json b/src/sonic-config-engine/tests/multi_npu_data/py2/ipinip.json similarity index 100% rename from src/sonic-config-engine/tests/multi_npu_data/ipinip.json rename to src/sonic-config-engine/tests/multi_npu_data/py2/ipinip.json diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/bgpd_frr.conf rename to src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf b/src/sonic-config-engine/tests/sample_output/py2/bgpd_quagga.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf rename to src/sonic-config-engine/tests/sample_output/py2/bgpd_quagga.conf diff --git a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/py2/buffers-dell6100.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/buffers-dell6100.json rename to src/sonic-config-engine/tests/sample_output/py2/buffers-dell6100.json diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf rename to src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf diff --git a/src/sonic-config-engine/tests/sample_output/frr.conf b/src/sonic-config-engine/tests/sample_output/py2/frr.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/frr.conf rename to src/sonic-config-engine/tests/sample_output/py2/frr.conf diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/py2/interfaces similarity index 100% rename from src/sonic-config-engine/tests/sample_output/interfaces rename to src/sonic-config-engine/tests/sample_output/py2/interfaces diff --git a/src/sonic-config-engine/tests/sample_output/ipinip.json b/src/sonic-config-engine/tests/sample_output/py2/ipinip.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/ipinip.json rename to src/sonic-config-engine/tests/sample_output/py2/ipinip.json diff --git a/src/sonic-config-engine/tests/sample_output/l2switch.json b/src/sonic-config-engine/tests/sample_output/py2/l2switch.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/l2switch.json rename to src/sonic-config-engine/tests/sample_output/py2/l2switch.json diff --git a/src/sonic-config-engine/tests/sample_output/lldpd.conf b/src/sonic-config-engine/tests/sample_output/py2/lldpd.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/lldpd.conf rename to src/sonic-config-engine/tests/sample_output/py2/lldpd.conf diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces similarity index 100% rename from src/sonic-config-engine/tests/sample_output/mvrf_interfaces rename to src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces diff --git a/src/sonic-config-engine/tests/sample_output/ports.json b/src/sonic-config-engine/tests/sample_output/py2/ports.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/ports.json rename to src/sonic-config-engine/tests/sample_output/py2/ports.json diff --git a/src/sonic-config-engine/tests/sample_output/qos-arista7050.json b/src/sonic-config-engine/tests/sample_output/py2/qos-arista7050.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/qos-arista7050.json rename to src/sonic-config-engine/tests/sample_output/py2/qos-arista7050.json diff --git a/src/sonic-config-engine/tests/sample_output/qos-dell6100.json b/src/sonic-config-engine/tests/sample_output/py2/qos-dell6100.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/qos-dell6100.json rename to src/sonic-config-engine/tests/sample_output/py2/qos-dell6100.json diff --git a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/staticd_frr.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/staticd_frr.conf rename to src/sonic-config-engine/tests/sample_output/py2/staticd_frr.conf diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-bgpd.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf rename to src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-bgpd.conf diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf rename to src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-zebra.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf rename to src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-zebra.conf diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/py2/wait_for_intf.sh similarity index 100% rename from src/sonic-config-engine/tests/sample_output/wait_for_intf.sh rename to src/sonic-config-engine/tests/sample_output/py2/wait_for_intf.sh diff --git a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/zebra_frr.conf rename to src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf diff --git a/src/sonic-config-engine/tests/sample_output/zebra_quagga.conf b/src/sonic-config-engine/tests/sample_output/py2/zebra_quagga.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/zebra_quagga.conf rename to src/sonic-config-engine/tests/sample_output/py2/zebra_quagga.conf diff --git a/src/sonic-config-engine/tests/test_frr.py b/src/sonic-config-engine/tests/test_frr.py index e43fcb95789b..ef7c4b06f7db 100644 --- a/src/sonic-config-engine/tests/test_frr.py +++ b/src/sonic-config-engine/tests/test_frr.py @@ -1,8 +1,11 @@ -from unittest import TestCase -import subprocess -import os import filecmp +import os +import subprocess +import sys + +import tests.common_utils as utils +from unittest import TestCase class TestCfgGen(TestCase): def setUp(self): @@ -44,7 +47,7 @@ def run_case(self, template, target): cmd = "-m %s -p %s -y %s -t %s -T %s > %s" % cmd_args self.run_script(cmd) - original_filename = os.path.join(self.test_dir, 'sample_output', target) + original_filename = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, target) r = filecmp.cmp(original_filename, self.output_file) diff_output = self.run_diff(original_filename, self.output_file) if not r else "" diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index db5c1cf3a91a..8ce55f2c4427 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -1,10 +1,12 @@ import filecmp -import os -import subprocess import json +import os import shutil +import subprocess from unittest import TestCase +import tests.common_utils as utils + class TestJ2Files(TestCase): def setUp(self): @@ -34,42 +36,42 @@ def test_interfaces(self): interfaces_template = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'interfaces', 'interfaces.j2') argument = '-m ' + self.t0_minigraph + ' -a \'{\"hwaddr\":\"e4:1d:2d:a5:f3:ad\"}\' -t ' + interfaces_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'interfaces'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'interfaces'), self.output_file)) argument = '-m ' + self.t0_mvrf_minigraph + ' -a \'{\"hwaddr\":\"e4:1d:2d:a5:f3:ad\"}\' -t ' + interfaces_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'mvrf_interfaces'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'mvrf_interfaces'), self.output_file)) def test_ports_json(self): ports_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ports.json.j2') argument = '-m ' + self.simple_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ports_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'ports.json'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'ports.json'), self.output_file)) def test_dhcp_relay(self): # Test generation of wait_for_intf.sh template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay', 'wait_for_intf.sh.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + template_path + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'wait_for_intf.sh'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'wait_for_intf.sh'), self.output_file)) # Test generation of docker-dhcp-relay.supervisord.conf template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay', 'docker-dhcp-relay.supervisord.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + template_path + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'docker-dhcp-relay.supervisord.conf'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'docker-dhcp-relay.supervisord.conf'), self.output_file)) def test_lldp(self): lldpd_conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-lldp', 'lldpd.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + lldpd_conf_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'lldpd.conf'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'lldpd.conf'), self.output_file)) def test_bgpd_quagga(self): conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-quagga', 'bgpd.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file self.run_script(argument) - original_filename = os.path.join(self.test_dir, 'sample_output', 'bgpd_quagga.conf') + original_filename = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'bgpd_quagga.conf') r = filecmp.cmp(original_filename, self.output_file) diff_output = self.run_diff(original_filename, self.output_file) if not r else "" self.assertTrue(r, "Diff:\n" + diff_output) @@ -78,21 +80,21 @@ def test_zebra_quagga(self): conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-quagga', 'zebra.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'zebra_quagga.conf'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'zebra_quagga.conf'), self.output_file)) def test_ipinip(self): ipinip_file = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ipinip.json.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ipinip_file + ' > ' + self.output_file self.run_script(argument) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'ipinip.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'ipinip.json') assert filecmp.cmp(sample_output_file, self.output_file) def test_l2switch_template(self): argument = '-k Mellanox-SN2700 -t ' + os.path.join(self.test_dir, '../data/l2switch.j2') + ' -p ' + self.t0_port_config + ' > ' + self.output_file self.run_script(argument) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'l2switch.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'l2switch.json') self.assertTrue(filecmp.cmp(sample_output_file, self.output_file)) @@ -112,7 +114,7 @@ def test_qos_arista7050_render_template(self): qos_config_file_new = os.path.join(arista_dir_path, 'qos_config.j2') os.remove(qos_config_file_new) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'qos-arista7050.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'qos-arista7050.json') assert filecmp.cmp(sample_output_file, self.output_file) def test_qos_dell6100_render_template(self): @@ -131,7 +133,7 @@ def test_qos_dell6100_render_template(self): qos_config_file_new = os.path.join(dell_dir_path, 'qos_config.j2') os.remove(qos_config_file_new) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'qos-dell6100.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'qos-dell6100.json') assert filecmp.cmp(sample_output_file, self.output_file) def test_buffers_dell6100_render_template(self): @@ -150,7 +152,7 @@ def test_buffers_dell6100_render_template(self): buffers_config_file_new = os.path.join(dell_dir_path, 'buffers_config.j2') os.remove(buffers_config_file_new) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'buffers-dell6100.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'buffers-dell6100.json') assert filecmp.cmp(sample_output_file, self.output_file) def test_ipinip_multi_asic(self): @@ -158,7 +160,7 @@ def test_ipinip_multi_asic(self): argument = '-m ' + self.multi_asic_minigraph + ' -p ' + self.multi_asic_port_config + ' -t ' + ipinip_file + ' -n asic0 ' + ' > ' + self.output_file print(argument) self.run_script(argument) - sample_output_file = os.path.join(self.test_dir, 'multi_npu_data', 'ipinip.json') + sample_output_file = os.path.join(self.test_dir, 'multi_npu_data', utils.PYvX_DIR, 'ipinip.json') assert filecmp.cmp(sample_output_file, self.output_file) def tearDown(self): diff --git a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py index 776d362c9514..b185f58a8c81 100644 --- a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py +++ b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py @@ -1,10 +1,12 @@ import filecmp -import os -import subprocess import json +import os import shutil +import subprocess from unittest import TestCase +import tests.common_utils as utils + class TestJ2FilesT2ChassisFe(TestCase): def setUp(self): @@ -37,7 +39,7 @@ def run_case(self, minigraph, template, target): cmd = "-m %s -p %s -y %s -t %s -T %s > %s" % cmd_args self.run_script(cmd) - original_filename = os.path.join(self.test_dir, 'sample_output', target) + original_filename = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, target) r = filecmp.cmp(original_filename, self.output_file) diff_output = self.run_diff(original_filename, self.output_file) if not r else "" From 110f7b7817f3d1eca844a76af24e001b6077abf1 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 22:34:39 -0700 Subject: [PATCH 1189/1427] [cfggen] Build Python 2 And Python 3 Wheel Packages This builds Python 2&3 wheel packages for sonic-cfggen script. singed-off-by: Tamer Ahmed --- .../build_templates/sonic_debian_extension.j2 | 8 +- platform/mellanox/mlnx-platform-api.mk | 2 +- rules/docker-config-engine-buster.mk | 2 +- rules/docker-config-engine-stretch.mk | 2 +- rules/docker-config-engine.mk | 2 +- rules/sonic-config.dep | 18 +- rules/sonic-config.mk | 21 +- rules/sonic-platform-common.mk | 2 +- rules/sonic-utilities.mk | 4 +- slave.mk | 6 +- src/sonic-config-engine/config_samples.py | 1 - src/sonic-config-engine/minigraph.py | 10 +- src/sonic-config-engine/portconfig.py | 1 - src/sonic-config-engine/setup.py | 68 +- src/sonic-config-engine/sonic-cfggen | 23 +- src/sonic-config-engine/tests/common_utils.py | 1 + .../tests/multi_npu_data/py3/ipinip.json | 23 + .../tests/sample_output/py3/bgpd_frr.conf | 73 + .../tests/sample_output/py3/bgpd_quagga.conf | 100 ++ .../sample_output/py3/buffers-dell6100.json | 640 ++++++++ .../py3/docker-dhcp-relay.supervisord.conf | 69 + .../tests/sample_output/py3/frr.conf | 87 + .../tests/sample_output/py3/interfaces | 46 + .../tests/sample_output/py3/ipinip.json | 23 + .../tests/sample_output/py3/l2switch.json | 268 +++ .../tests/sample_output/py3/lldpd.conf | 3 + .../tests/sample_output/py3/mvrf_interfaces | 57 + .../tests/sample_output/py3/ports.json | 30 + .../sample_output/py3/qos-arista7050.json | 977 +++++++++++ .../tests/sample_output/py3/qos-dell6100.json | 1457 +++++++++++++++++ .../tests/sample_output/py3/staticd_frr.conf | 20 + .../sample_output/py3/t2-chassis-fe-bgpd.conf | 87 + .../py3/t2-chassis-fe-vni-zebra.conf | 32 + .../py3/t2-chassis-fe-zebra.conf | 32 + .../tests/sample_output/py3/wait_for_intf.sh | 31 + .../tests/sample_output/py3/zebra_frr.conf | 32 + .../tests/sample_output/py3/zebra_quagga.conf | 44 + src/sonic-config-engine/tests/test_cfggen.py | 5 +- .../tests/test_cfggen_pfx_filter.py | 10 +- .../tests/test_cfggen_platformJson.py | 5 +- .../tests/test_cfggen_t2_chassis_fe.py | 5 +- src/sonic-config-engine/tests/test_frr.py | 6 +- src/sonic-config-engine/tests/test_j2files.py | 9 +- .../tests/test_j2files_t2_chassis_fe.py | 9 +- .../tests/test_minigraph_case.py | 5 +- .../tests/test_multinpu_cfggen.py | 5 +- 46 files changed, 4285 insertions(+), 76 deletions(-) create mode 100644 src/sonic-config-engine/tests/multi_npu_data/py3/ipinip.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/bgpd_quagga.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/buffers-dell6100.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/frr.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/interfaces create mode 100644 src/sonic-config-engine/tests/sample_output/py3/ipinip.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/l2switch.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/lldpd.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces create mode 100644 src/sonic-config-engine/tests/sample_output/py3/ports.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/qos-arista7050.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/qos-dell6100.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/staticd_frr.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/wait_for_intf.sh create mode 100644 src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/zebra_quagga.conf diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index b40be7c13f79..0878c2801433 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -147,10 +147,10 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC sudo rm -rf $FILESYSTEM_ROOT/$SONIC_PY_COMMON_PY3_WHEEL_NAME # Install SONiC config engine Python package -CONFIG_ENGINE_WHEEL_NAME=$(basename {{config_engine_wheel_path}}) -sudo cp {{config_engine_wheel_path}} $FILESYSTEM_ROOT/$CONFIG_ENGINE_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $CONFIG_ENGINE_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_WHEEL_NAME +CONFIG_ENGINE_PY2_WHEEL_NAME=$(basename {{config_engine_py2_wheel_path}}) +sudo cp {{config_engine_py2_wheel_path}} $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $CONFIG_ENGINE_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY2_WHEEL_NAME # Install sonic-yang-models py3 package, install dependencies sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang_*.deb diff --git a/platform/mellanox/mlnx-platform-api.mk b/platform/mellanox/mlnx-platform-api.mk index 4abc0fda8d19..b350329b00e1 100644 --- a/platform/mellanox/mlnx-platform-api.mk +++ b/platform/mellanox/mlnx-platform-api.mk @@ -3,7 +3,7 @@ SONIC_PLATFORM_API_PY2 = mlnx_platform_api-1.0-py2-none-any.whl $(SONIC_PLATFORM_API_PY2)_SRC_PATH = $(PLATFORM_PATH)/mlnx-platform-api $(SONIC_PLATFORM_API_PY2)_PYTHON_VERSION = 2 -$(SONIC_PLATFORM_API_PY2)_DEPENDS = $(SONIC_PY_COMMON_PY2) $(SONIC_PLATFORM_COMMON_PY2) $(SONIC_CONFIG_ENGINE) +$(SONIC_PLATFORM_API_PY2)_DEPENDS = $(SONIC_PY_COMMON_PY2) $(SONIC_PLATFORM_COMMON_PY2) $(SONIC_CONFIG_ENGINE_PY2) SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) export mlnx_platform_api_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2))" diff --git a/rules/docker-config-engine-buster.mk b/rules/docker-config-engine-buster.mk index ac84f92edd9b..1f101236cd96 100644 --- a/rules/docker-config-engine-buster.mk +++ b/rules/docker-config-engine-buster.mk @@ -5,7 +5,7 @@ $(DOCKER_CONFIG_ENGINE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-config-engine-buste $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) -$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE_BUSTER)_LOAD_DOCKERS += $(DOCKER_BASE_BUSTER) $(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS = $($(DOCKER_BASE_BUSTER)_DBG_DEPENDS) diff --git a/rules/docker-config-engine-stretch.mk b/rules/docker-config-engine-stretch.mk index 497593a316de..075905998730 100644 --- a/rules/docker-config-engine-stretch.mk +++ b/rules/docker-config-engine-stretch.mk @@ -4,7 +4,7 @@ DOCKER_CONFIG_ENGINE_STRETCH = docker-config-engine-stretch.gz $(DOCKER_CONFIG_ENGINE_STRETCH)_PATH = $(DOCKERS_PATH)/docker-config-engine-stretch $(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) -$(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +$(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE_STRETCH)_LOAD_DOCKERS += $(DOCKER_BASE_STRETCH) $(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS = $($(DOCKER_BASE_STRETCH)_DBG_DEPENDS) diff --git a/rules/docker-config-engine.mk b/rules/docker-config-engine.mk index 5d65314b6727..56a9c9755e7b 100644 --- a/rules/docker-config-engine.mk +++ b/rules/docker-config-engine.mk @@ -4,6 +4,6 @@ DOCKER_CONFIG_ENGINE = docker-config-engine.gz $(DOCKER_CONFIG_ENGINE)_PATH = $(DOCKERS_PATH)/docker-config-engine $(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) -$(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +$(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE)_LOAD_DOCKERS += $(DOCKER_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_CONFIG_ENGINE) diff --git a/rules/sonic-config.dep b/rules/sonic-config.dep index f4c74d075d51..a606bb1301df 100644 --- a/rules/sonic-config.dep +++ b/rules/sonic-config.dep @@ -1,10 +1,20 @@ +# SONIC_CONFIG_ENGINE_PY2 package -SPATH := $($(SONIC_CONFIG_ENGINE)_SRC_PATH) +SPATH := $($(SONIC_CONFIG_ENGINE_PY2)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-config.mk rules/sonic-config.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) DEP_FILES += $(shell git ls-files $(SPATH)) -$(SONIC_CONFIG_ENGINE)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_CONFIG_ENGINE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_CONFIG_ENGINE)_DEP_FILES := $(DEP_FILES) +$(SONIC_CONFIG_ENGINE_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_CONFIG_ENGINE_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_CONFIG_ENGINE_PY2)_DEP_FILES := $(DEP_FILES) + +# SONIC_CONFIG_ENGINE_PY3 package + +SPATH := $($(SONIC_CONFIG_ENGINE_PY3)_SRC_PATH) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_CONFIG_ENGINE_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_CONFIG_ENGINE_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_CONFIG_ENGINE_PY3)_DEP_FILES := $(DEP_FILES) diff --git a/rules/sonic-config.mk b/rules/sonic-config.mk index 3adb460f58d8..f7ff06286455 100644 --- a/rules/sonic-config.mk +++ b/rules/sonic-config.mk @@ -1,7 +1,16 @@ -# sonic-config-engine package +# SONIC_CONFIG_ENGINE_PY2 package -SONIC_CONFIG_ENGINE = sonic_config_engine-1.0-py2-none-any.whl -$(SONIC_CONFIG_ENGINE)_SRC_PATH = $(SRC_PATH)/sonic-config-engine -$(SONIC_CONFIG_ENGINE)_DEPENDS += $(SWSSSDK_PY2) $(SONIC_PY_COMMON_PY2) -$(SONIC_CONFIG_ENGINE)_PYTHON_VERSION = 2 -SONIC_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +SONIC_CONFIG_ENGINE_PY2 = sonic_config_engine-1.0-py2-none-any.whl +$(SONIC_CONFIG_ENGINE_PY2)_SRC_PATH = $(SRC_PATH)/sonic-config-engine +$(SONIC_CONFIG_ENGINE_PY2)_DEPENDS += $(SWSSSDK_PY2) $(SONIC_PY_COMMON_PY2) +$(SONIC_CONFIG_ENGINE_PY2)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) + + +# SONIC_CONFIG_ENGINE_PY3 package + +SONIC_CONFIG_ENGINE_PY3 = sonic_config_engine-1.0-py3-none-any.whl +$(SONIC_CONFIG_ENGINE_PY3)_SRC_PATH = $(SRC_PATH)/sonic-config-engine +$(SONIC_CONFIG_ENGINE_PY3)_DEPENDS += $(SWSSSDK_PY3) $(SONIC_PY_COMMON_PY3) +$(SONIC_CONFIG_ENGINE_PY3)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY3) diff --git a/rules/sonic-platform-common.mk b/rules/sonic-platform-common.mk index c7ab75d9f875..a734abfd6d72 100644 --- a/rules/sonic-platform-common.mk +++ b/rules/sonic-platform-common.mk @@ -3,7 +3,7 @@ SONIC_PLATFORM_COMMON_PY2 = sonic_platform_common-1.0-py2-none-any.whl $(SONIC_PLATFORM_COMMON_PY2)_SRC_PATH = $(SRC_PATH)/sonic-platform-common $(SONIC_PLATFORM_COMMON_PY2)_PYTHON_VERSION = 2 -$(SONIC_PLATFORM_COMMON_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) $(SONIC_CONFIG_ENGINE) +$(SONIC_PLATFORM_COMMON_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) $(SONIC_CONFIG_ENGINE_PY2) SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY2) # Als build sonic-platform-common into python3 wheel, so we can use PSU code in SNMP docker diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index 614602b8507b..3de3de02f0ad 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -12,8 +12,8 @@ $(SONIC_UTILITIES_PY2)_SRC_PATH = $(SRC_PATH)/sonic-utilities $(SONIC_UTILITIES_PY2)_PYTHON_VERSION = 2 $(SONIC_UTILITIES_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) \ $(SONIC_PY_COMMON_PY3) \ - $(SWSSSDK_PY2) \ - $(SONIC_CONFIG_ENGINE) \ + $(SWSSSDK_PY2) \ + $(SONIC_CONFIG_ENGINE_PY2) \ $(SONIC_YANG_MGMT_PY) \ $(SONIC_YANG_MODELS_PY3) $(SONIC_UTILITIES_PY2)_DEBS_DEPENDS = $(LIBYANG) \ diff --git a/slave.mk b/slave.mk index b9cebdf9a169..8eb78494ce3d 100644 --- a/slave.mk +++ b/slave.mk @@ -811,7 +811,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_UTILITIES_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ @@ -848,7 +849,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export installer_images="$(addprefix $(TARGET_PATH)/,$($*_DOCKERS))" export sonic_py_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY2))" export sonic_py_common_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3))" - export config_engine_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE))" + export config_engine_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY2))" + export config_engine_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY3))" export swsssdk_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY2))" export swsssdk_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY3))" export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" diff --git a/src/sonic-config-engine/config_samples.py b/src/sonic-config-engine/config_samples.py index 42c545488c50..3c3ace884652 100644 --- a/src/sonic-config-engine/config_samples.py +++ b/src/sonic-config-engine/config_samples.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python import os import sys from natsort import natsorted diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 2e3ba9da21a8..7ab7c41cd2b1 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python from __future__ import print_function + import calendar import math import os @@ -922,7 +922,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw results['BGP_PEER_RANGE'] = bgp_peers_with_range if mgmt_routes: # TODO: differentiate v4 and v6 - iter(mgmt_intf.values()).next()['forced_mgmt_routes'] = mgmt_routes + next(iter(mgmt_intf.values()))['forced_mgmt_routes'] = mgmt_routes results['MGMT_PORT'] = {} results['MGMT_INTERFACE'] = {} mgmt_intf_count = 0 @@ -1044,7 +1044,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw if port_config_file: port_set = set(ports.keys()) - for (pc_name, mbr_map) in pcs.items(): + for (pc_name, mbr_map) in list(pcs.items()): # remove portchannels that contain ports not existing in port_config.ini # when port_config.ini exists if not set(mbr_map['members']).issubset(port_set): @@ -1059,7 +1059,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw results['PORTCHANNEL'] = pcs results['PORTCHANNEL_MEMBER'] = pc_members - for pc_intf in pc_intfs.keys(): + for pc_intf in list(pc_intfs.keys()): # remove portchannels not in PORTCHANNEL dictionary if isinstance(pc_intf, tuple) and pc_intf[0] not in pcs: print("Warning: ignore '%s' interface '%s' as '%s' is not in the valid PortChannel list" % (pc_intf[0], pc_intf[1], pc_intf[0]), file=sys.stderr) @@ -1097,7 +1097,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw results['VLAN'] = vlans results['VLAN_MEMBER'] = vlan_members - for nghbr in neighbors.keys(): + for nghbr in list(neighbors.keys()): # remove port not in port_config.ini if nghbr not in ports: if port_config_file is not None: diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py index df1decece763..1a49e4fd1cd4 100644 --- a/src/sonic-config-engine/portconfig.py +++ b/src/sonic-config-engine/portconfig.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python try: import os import sys diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py index 8ddcb62d1ab0..e1940d4c0683 100755 --- a/src/sonic-config-engine/setup.py +++ b/src/sonic-config-engine/setup.py @@ -1,52 +1,65 @@ -#!/usr/bin/env python +import glob from setuptools import setup -import os.path -import unittest -import glob -def get_test_suite(): - test_loader = unittest.TestLoader() - test_suite = test_loader.discover('tests', pattern='*.py') - return test_suite +from tests.common_utils import PY3x + +dependencies = [ +# Python 2 or 3 dependencies + 'future', + 'ipaddr', + 'lxml', + 'netaddr', + 'pyyaml', + 'sonic-py-common', + ] + ([ +# Python 3 dependencies +# pyangbind v0.8.1 pull down enum43 which causes 're' package to malfunction. +# Python3 has enum module and so pyangbind should be installed outside +# dependencies section of setuptools followed by uninstall of enum43 +# 'pyangbind==0.8.1', + 'Jinja2>=2.10', + ] if PY3x + else [ +# Python 2 dependencies +# Jinja2 v3.0.0+ dropped support for Python 2.7 and causes setuptools to +# malfunction on stretch slave docker. + 'Jinja2<3.0.0', + 'pyangbind==0.6.0', + ]) setup( name = 'sonic-config-engine', version = '1.0', description = 'Utilities for generating SONiC configuration files', - author='Taoyu Li', - author_email='taoyl@microsoft.com', + author = 'Taoyu Li', + author_email = 'taoyl@microsoft.com', url = 'https://github.com/Azure/sonic-buildimage', py_modules = [ - 'portconfig', + 'config_samples', + 'lazy_re', 'minigraph', 'openconfig_acl', - 'config_samples', + 'portconfig', 'redis_bcc', - 'lazy_re', ], scripts = [ 'sonic-cfggen', ], - install_requires = [ - 'future', - 'ipaddr', - 'jinja2>=2.10', - 'lxml', - 'netaddr', - 'pyyaml', - 'pyangbind==0.6.0', - 'sonic-py-common', - ], - test_suite = 'setup.get_test_suite', + install_requires = dependencies, data_files = [ ('/usr/share/sonic/templates', glob.glob('data/*')), ], - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', - classifiers=[ + setup_requires= [ + 'pytest-runner', + ], + tests_require=[ + 'pytest', + ], + classifiers = [ 'Intended Audience :: Developers', 'Natural Language :: English', - "Programming Language :: Python :: 2", + 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', @@ -54,5 +67,6 @@ def get_test_suite(): 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', ], + keywords = 'SONiC sonic-cfggen config-engine PYTHON python' ) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index fb547acd6927..892647a757ac 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -45,9 +45,17 @@ from sonic_py_common.multi_asic import get_asic_id_from_name, is_multi_asic from sonic_py_common import device_info from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig, ConfigDBPipeConnector -#TODO: Remove STR_TYPE once SONiC moves to Python 3.x + PY3x = sys.version_info >= (3, 0) -STR_TYPE = str if PY3x else unicode + +#TODO: Remove STR_TYPE, FILE_TYPE once SONiC moves to Python 3.x +if PY3x: + from io import IOBase + STR_TYPE = str + FILE_TYPE = IOBase +else: + STR_TYPE = unicode + FILE_TYPE = file def sort_by_port_index(value): if not value: @@ -168,7 +176,8 @@ TODO(taoyl): Current version of config db only supports BGP admin states. break return newData - for key in data.keys(): + current_keys = list(data.keys()) + for key in current_keys: new_key = ConfigDBConnector.serialize_key(key) if new_key != key: data[new_key] = data.pop(key) @@ -179,7 +188,8 @@ TODO(taoyl): Current version of config db only supports BGP admin states. def to_deserialized(data): for table in data: if type(data[table]) is dict: - for key in data[table].keys(): + current_keys = list(data[table].keys()) + for key in current_keys: new_key = ConfigDBConnector.deserialize_key(key) if new_key != key: data[table][new_key] = data[table].pop(key) @@ -195,6 +205,7 @@ def deep_update(dst, src): dst[key] = value return dst +# sort_data is required as it is being imported by config/config_mgmt module in sonic_utilities def sort_data(data): for table in data: if type(data[table]) is dict: @@ -206,11 +217,11 @@ def smart_open(filename=None, mode=None): """ Provide contextual file descriptor of filename if it is not a file descriptor """ - smart_file = open(filename, mode) if not isinstance(filename, file) else filename + smart_file = open(filename, mode) if not isinstance(filename, FILE_TYPE) else filename try: yield smart_file finally: - if not isinstance(filename, file): + if not isinstance(filename, FILE_TYPE): smart_file.close() def _process_json(args, data): diff --git a/src/sonic-config-engine/tests/common_utils.py b/src/sonic-config-engine/tests/common_utils.py index 142bf2f4dde1..3d8a3029dad9 100644 --- a/src/sonic-config-engine/tests/common_utils.py +++ b/src/sonic-config-engine/tests/common_utils.py @@ -4,6 +4,7 @@ PY3x = sys.version_info >= (3, 0) PYvX_DIR = "py3" if PY3x else "py2" +PYTHON_INTERPRETTER = "python3" if PY3x else "python2" def tuple_to_str(tuplestr): """ Convert Python tuple '('elem1', 'elem2')' representation into string on the for "elem1|elem2" """ diff --git a/src/sonic-config-engine/tests/multi_npu_data/py3/ipinip.json b/src/sonic-config-engine/tests/multi_npu_data/py3/ipinip.json new file mode 100644 index 000000000000..dd72ec55fee2 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/py3/ipinip.json @@ -0,0 +1,23 @@ +[ + { + "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"8.0.0.0,10.1.0.32,10.1.0.1,10.1.0.3,10.0.0.0", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } + , + { + "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"fd00:1::32,fc00:1::32,fc00::1", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf new file mode 100644 index 000000000000..60fd3ded8444 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf @@ -0,0 +1,73 @@ +! +! template: bgpd/bgpd.conf.j2 +! +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.1/27 +! +! +! +router bgp 65100 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 10.1.0.32 +! + network 10.1.0.32/32 +! + address-family ipv6 + network fc00:1::32/64 + exit-address-family +! + network 192.168.0.1/27 +! +! +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-config-engine/tests/sample_output/py3/bgpd_quagga.conf b/src/sonic-config-engine/tests/sample_output/py3/bgpd_quagga.conf new file mode 100644 index 000000000000..16eb6095463b --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/bgpd_quagga.conf @@ -0,0 +1,100 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! +hostname switch-t0 +password zebra +log syslog informational +log facility local4 +! enable password ! +! +! bgp multiple-instance +! +route-map FROM_BGP_SPEAKER_V4 permit 10 +! +route-map TO_BGP_SPEAKER_V4 deny 10 +! +router bgp 65100 + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 10.1.0.32 + network 10.1.0.32/32 + address-family ipv6 + network fc00:1::32/64 + exit-address-family + network 192.168.0.1/27 + neighbor 10.0.0.57 remote-as 64600 + neighbor 10.0.0.57 description ARISTA01T1 + address-family ipv4 + neighbor 10.0.0.57 allowas-in 1 + neighbor 10.0.0.57 activate + neighbor 10.0.0.57 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::72 remote-as 64600 + neighbor fc00::72 description ARISTA01T1 + address-family ipv6 + neighbor fc00::72 allowas-in 1 + neighbor fc00::72 activate + neighbor fc00::72 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.59 remote-as 64600 + neighbor 10.0.0.59 description ARISTA02T1 + address-family ipv4 + neighbor 10.0.0.59 allowas-in 1 + neighbor 10.0.0.59 activate + neighbor 10.0.0.59 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::76 remote-as 64600 + neighbor fc00::76 description ARISTA02T1 + address-family ipv6 + neighbor fc00::76 allowas-in 1 + neighbor fc00::76 activate + neighbor fc00::76 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.61 remote-as 64600 + neighbor 10.0.0.61 description ARISTA03T1 + address-family ipv4 + neighbor 10.0.0.61 allowas-in 1 + neighbor 10.0.0.61 activate + neighbor 10.0.0.61 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::7a remote-as 64600 + neighbor fc00::7a description ARISTA03T1 + address-family ipv6 + neighbor fc00::7a allowas-in 1 + neighbor fc00::7a activate + neighbor fc00::7a soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.63 remote-as 64600 + neighbor 10.0.0.63 description ARISTA04T1 + address-family ipv4 + neighbor 10.0.0.63 allowas-in 1 + neighbor 10.0.0.63 activate + neighbor 10.0.0.63 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::7e remote-as 64600 + neighbor fc00::7e description ARISTA04T1 + address-family ipv6 + neighbor fc00::7e allowas-in 1 + neighbor fc00::7e activate + neighbor fc00::7e soft-reconfiguration inbound + maximum-paths 64 + exit-address-family +! +maximum-paths 64 +! +route-map ISOLATE permit 10 +set as-path prepend 65100 +! diff --git a/src/sonic-config-engine/tests/sample_output/py3/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/py3/buffers-dell6100.json new file mode 100644 index 000000000000..39fb042cc4cb --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/buffers-dell6100.json @@ -0,0 +1,640 @@ + +{ + "CABLE_LENGTH": { + "AZURE": { + "Ethernet0": "5m", + "Ethernet1": "5m", + "Ethernet2": "5m", + "Ethernet3": "5m", + "Ethernet4": "5m", + "Ethernet5": "5m", + "Ethernet6": "5m", + "Ethernet7": "5m", + "Ethernet8": "5m", + "Ethernet9": "5m", + "Ethernet10": "5m", + "Ethernet11": "5m", + "Ethernet12": "5m", + "Ethernet13": "5m", + "Ethernet14": "5m", + "Ethernet15": "5m", + "Ethernet16": "5m", + "Ethernet17": "5m", + "Ethernet18": "5m", + "Ethernet19": "5m", + "Ethernet20": "5m", + "Ethernet21": "5m", + "Ethernet22": "5m", + "Ethernet23": "5m", + "Ethernet24": "5m", + "Ethernet25": "5m", + "Ethernet26": "5m", + "Ethernet27": "5m", + "Ethernet28": "5m", + "Ethernet29": "5m", + "Ethernet30": "5m", + "Ethernet31": "5m", + "Ethernet32": "5m", + "Ethernet33": "5m", + "Ethernet34": "5m", + "Ethernet35": "5m", + "Ethernet36": "5m", + "Ethernet37": "5m", + "Ethernet38": "5m", + "Ethernet39": "5m", + "Ethernet40": "5m", + "Ethernet41": "5m", + "Ethernet42": "5m", + "Ethernet43": "5m", + "Ethernet44": "5m", + "Ethernet45": "5m", + "Ethernet46": "5m", + "Ethernet47": "5m", + "Ethernet48": "5m", + "Ethernet49": "5m", + "Ethernet50": "5m", + "Ethernet51": "5m", + "Ethernet52": "5m", + "Ethernet53": "5m", + "Ethernet54": "5m", + "Ethernet55": "5m", + "Ethernet56": "5m", + "Ethernet57": "5m", + "Ethernet58": "5m", + "Ethernet59": "5m", + "Ethernet60": "5m", + "Ethernet61": "5m", + "Ethernet62": "5m", + "Ethernet63": "5m" + } + }, + + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10875072", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "9243812", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"15982720" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "Ethernet0|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet1|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet4|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet5|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet16|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet17|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet20|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet21|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet6|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet7|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet8|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet9|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet10|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet11|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet12|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet13|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet14|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet15|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet32|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet36|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet37|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet38|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet39|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet40|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet41|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet42|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet22|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet23|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet24|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet25|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet26|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet27|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet28|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet29|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet30|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet31|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet48|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet52|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet53|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet54|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet55|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet56|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet57|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet58|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + + "BUFFER_QUEUE": { + "Ethernet0|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet1|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet4|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet5|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet16|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet17|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet20|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet21|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet6|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet7|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet8|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet9|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet10|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet11|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet12|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet13|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet14|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet15|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet32|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet36|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet37|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet38|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet39|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet40|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet41|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet42|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet22|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet23|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet24|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet25|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet26|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet27|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet28|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet29|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet30|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet31|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet48|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet52|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet53|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet54|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet55|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet56|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet57|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet58|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet0|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet8|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet58|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet0|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet8|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet58|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf new file mode 100644 index 000000000000..3e485f4ddc35 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf @@ -0,0 +1,69 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=50 + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[group:isc-dhcp-relay] +programs=isc-dhcp-relay-Vlan1000 + +[program:isc-dhcp-relay-Vlan1000] +command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 192.0.0.1 192.0.0.2 +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + + +[group:dhcpmon] +programs=dhcpmon-Vlan1000 + +[program:dhcpmon-Vlan1000] +command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -im eth0 +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=isc-dhcp-relay-Vlan1000:running + + + diff --git a/src/sonic-config-engine/tests/sample_output/py3/frr.conf b/src/sonic-config-engine/tests/sample_output/py3/frr.conf new file mode 100644 index 000000000000..6e8573e9ba9d --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/frr.conf @@ -0,0 +1,87 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr.conf.j2 with config DB data +! file: frr.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! +! +! Enable link-detect (default disabled) +interface PortChannel01 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel03 +link-detect +! +interface PortChannel04 +link-detect +! +!! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +!! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.1/27 +! +! +! +router bgp 65100 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 10.1.0.32 +! + network 10.1.0.32/32 +! + address-family ipv6 + network fc00:1::32/64 + exit-address-family +! + network 192.168.0.1/27 +! +! +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/interfaces b/src/sonic-config-engine/tests/sample_output/py3/interfaces new file mode 100644 index 000000000000..f5929119703c --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/interfaces @@ -0,0 +1,46 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen +# file: /etc/network/interfaces +# +# The loopback network interface +auto lo +iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo + +# The management network interface +auto eth0 +iface eth0 inet static + address 10.0.0.100 + netmask 255.255.255.0 + network 10.0.0.0 + broadcast 10.0.0.255 + ########## management network policy routing rules + # management port up rules + up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 + up ip -4 route add 10.0.0.0/24 dev eth0 table default + up ip -4 rule add from 10.0.0.100/32 table default + # management port down rules + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default + pre-down ip -4 rule delete from 10.0.0.100/32 table default +iface eth0 inet6 static + address 2603:10e2:0:2902::8 + netmask 64 + network 2603:10e2:0:2902:: + broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff + ########## management network policy routing rules + # management port up rules + up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table default metric 201 + up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default + up ip -6 rule add from 2603:10e2:0:2902::8/128 table default + # management port down rules + pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default + pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default + pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table default +# +source /etc/network/interfaces.d/* +# + diff --git a/src/sonic-config-engine/tests/sample_output/py3/ipinip.json b/src/sonic-config-engine/tests/sample_output/py3/ipinip.json new file mode 100644 index 000000000000..e4028ea01a2d --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/ipinip.json @@ -0,0 +1,23 @@ +[ + { + "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"10.1.0.32,10.0.0.56,10.0.0.58,10.0.0.60,10.0.0.62,192.168.0.1", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } + , + { + "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"fc00:1::32,fc00::71,fc00::75,fc00::79,fc00::7d", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/py3/l2switch.json b/src/sonic-config-engine/tests/sample_output/py3/l2switch.json new file mode 100644 index 000000000000..fd83589153ea --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/l2switch.json @@ -0,0 +1,268 @@ +{ + "DEVICE_METADATA": {"localhost": {"hwsku": "Mellanox-SN2700"}}, + "PORT": { + "Ethernet0": { + "alias": "fortyGigE0/0", + "lanes": "29,30,31,32", + "admin_status": "up" + }, + "Ethernet4": { + "alias": "fortyGigE0/4", + "lanes": "25,26,27,28", + "admin_status": "up" + }, + "Ethernet8": { + "alias": "fortyGigE0/8", + "lanes": "37,38,39,40", + "admin_status": "up" + }, + "Ethernet12": { + "alias": "fortyGigE0/12", + "lanes": "33,34,35,36", + "admin_status": "up" + }, + "Ethernet16": { + "alias": "fortyGigE0/16", + "lanes": "41,42,43,44", + "admin_status": "up" + }, + "Ethernet20": { + "alias": "fortyGigE0/20", + "lanes": "45,46,47,48", + "admin_status": "up" + }, + "Ethernet24": { + "alias": "fortyGigE0/24", + "lanes": "5,6,7,8", + "admin_status": "up" + }, + "Ethernet28": { + "alias": "fortyGigE0/28", + "lanes": "1,2,3,4", + "admin_status": "up" + }, + "Ethernet32": { + "alias": "fortyGigE0/32", + "lanes": "9,10,11,12", + "admin_status": "up" + }, + "Ethernet36": { + "alias": "fortyGigE0/36", + "lanes": "13,14,15,16", + "admin_status": "up" + }, + "Ethernet40": { + "alias": "fortyGigE0/40", + "lanes": "21,22,23,24", + "admin_status": "up" + }, + "Ethernet44": { + "alias": "fortyGigE0/44", + "lanes": "17,18,19,20", + "admin_status": "up" + }, + "Ethernet48": { + "alias": "fortyGigE0/48", + "lanes": "49,50,51,52", + "admin_status": "up" + }, + "Ethernet52": { + "alias": "fortyGigE0/52", + "lanes": "53,54,55,56", + "admin_status": "up" + }, + "Ethernet56": { + "alias": "fortyGigE0/56", + "lanes": "61,62,63,64", + "admin_status": "up" + }, + "Ethernet60": { + "alias": "fortyGigE0/60", + "lanes": "57,58,59,60", + "admin_status": "up" + }, + "Ethernet64": { + "alias": "fortyGigE0/64", + "lanes": "65,66,67,68", + "admin_status": "up" + }, + "Ethernet68": { + "alias": "fortyGigE0/68", + "lanes": "69,70,71,72", + "admin_status": "up" + }, + "Ethernet72": { + "alias": "fortyGigE0/72", + "lanes": "77,78,79,80", + "admin_status": "up" + }, + "Ethernet76": { + "alias": "fortyGigE0/76", + "lanes": "73,74,75,76", + "admin_status": "up" + }, + "Ethernet80": { + "alias": "fortyGigE0/80", + "lanes": "105,106,107,108", + "admin_status": "up" + }, + "Ethernet84": { + "alias": "fortyGigE0/84", + "lanes": "109,110,111,112", + "admin_status": "up" + }, + "Ethernet88": { + "alias": "fortyGigE0/88", + "lanes": "117,118,119,120", + "admin_status": "up" + }, + "Ethernet92": { + "alias": "fortyGigE0/92", + "lanes": "113,114,115,116", + "admin_status": "up" + }, + "Ethernet96": { + "alias": "fortyGigE0/96", + "lanes": "121,122,123,124", + "admin_status": "up" + }, + "Ethernet100": { + "alias": "fortyGigE0/100", + "lanes": "125,126,127,128", + "admin_status": "up" + }, + "Ethernet104": { + "alias": "fortyGigE0/104", + "lanes": "85,86,87,88", + "admin_status": "up" + }, + "Ethernet108": { + "alias": "fortyGigE0/108", + "lanes": "81,82,83,84", + "admin_status": "up" + }, + "Ethernet112": { + "alias": "fortyGigE0/112", + "lanes": "89,90,91,92", + "admin_status": "up" + }, + "Ethernet116": { + "alias": "fortyGigE0/116", + "lanes": "93,94,95,96", + "admin_status": "up" + }, + "Ethernet120": { + "alias": "fortyGigE0/120", + "lanes": "97,98,99,100", + "admin_status": "up" + }, + "Ethernet124": { + "alias": "fortyGigE0/124", + "lanes": "101,102,103,104", + "admin_status": "up" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000" + } + }, + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet12": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet16": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet20": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet24": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet28": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet32": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet36": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet40": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet44": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet48": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet52": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet56": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet60": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet64": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet68": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet72": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet76": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet80": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet84": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet88": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet92": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet96": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet100": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet104": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet108": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet112": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet116": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet120": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet124": { + "tagging_mode": "untagged" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py3/lldpd.conf b/src/sonic-config-engine/tests/sample_output/py3/lldpd.conf new file mode 100644 index 000000000000..d28ec8418362 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/lldpd.conf @@ -0,0 +1,3 @@ +configure ports eth0 lldp portidsubtype local eth0 +configure system ip management pattern 10.0.0.100 +configure system hostname switch-t0 diff --git a/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces new file mode 100644 index 000000000000..49d307aa2df7 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces @@ -0,0 +1,57 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen +# file: /etc/network/interfaces +# +auto mgmt +iface mgmt + vrf-table 5000 +# The loopback network interface for mgmt VRF that is required for applications like NTP + up ip link add lo-m type dummy + up ip link set dev lo-m master mgmt + up ip addr add 127.0.0.1/16 dev lo-m + up ip link set lo-m up + down ip link delete dev lo-m +# The loopback network interface +auto lo +iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo + +# The management network interface +auto eth0 +iface eth0 inet static + address 10.0.0.100 + netmask 255.255.255.0 + network 10.0.0.0 + broadcast 10.0.0.255 + vrf mgmt + ########## management network policy routing rules + # management port up rules + up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 + up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 + up ip -4 rule add from 10.0.0.100/32 table 5000 + # management port down rules + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 + pre-down ip -4 rule delete from 10.0.0.100/32 table 5000 +iface eth0 inet6 static + address 2603:10e2:0:2902::8 + netmask 64 + network 2603:10e2:0:2902:: + broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff + vrf mgmt + ########## management network policy routing rules + # management port up rules + up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table 5000 metric 201 + up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table 5000 + up ip -6 rule add from 2603:10e2:0:2902::8/128 table 5000 + # management port down rules + pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 + pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 + pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 +# +source /etc/network/interfaces.d/* +# + diff --git a/src/sonic-config-engine/tests/sample_output/py3/ports.json b/src/sonic-config-engine/tests/sample_output/py3/ports.json new file mode 100644 index 000000000000..36f5ad117c39 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/ports.json @@ -0,0 +1,30 @@ +[ + { + "PORT_TABLE:Ethernet0": { + "speed": "10000", + "description": "fortyGigE0/0" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet4": { + "speed": "25000", + "description": "fortyGigE0/4" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet8": { + "speed": "1000", + "description": "Interface description" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet12": { + "speed": "100000", + "description": "Interface description" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050.json b/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050.json new file mode 100644 index 000000000000..aa05ef4ec36c --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050.json @@ -0,0 +1,977 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0" : "1", + "1" : "1", + "2" : "1", + "3" : "3", + "4" : "4", + "5" : "2", + "6" : "1", + "7" : "1", + "8" : "0", + "9" : "1", + "10": "1", + "11": "1", + "12": "1", + "13": "1", + "14": "1", + "15": "1", + "16": "1", + "17": "1", + "18": "1", + "19": "1", + "20": "1", + "21": "1", + "22": "1", + "23": "1", + "24": "1", + "25": "1", + "26": "1", + "27": "1", + "28": "1", + "29": "1", + "30": "1", + "31": "1", + "32": "1", + "33": "1", + "34": "1", + "35": "1", + "36": "1", + "37": "1", + "38": "1", + "39": "1", + "40": "1", + "41": "1", + "42": "1", + "43": "1", + "44": "1", + "45": "1", + "46": "5", + "47": "1", + "48": "6", + "49": "1", + "50": "1", + "51": "1", + "52": "1", + "53": "1", + "54": "1", + "55": "1", + "56": "1", + "57": "1", + "58": "1", + "59": "1", + "60": "1", + "61": "1", + "62": "1", + "63": "1" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "14" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "15" + } + }, + "PORT_QOS_MAP": { + "Ethernet4": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet8": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet12": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet16": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet20": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet24": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet28": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet32": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet36": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet40": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet44": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet48": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet52": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet56": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet60": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet64": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet68": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet72": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet76": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet80": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet84": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet88": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet92": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet96": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet112": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet116": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet120": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet124": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "1048576", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, + "QUEUE": { + "Ethernet4|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet44|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet60|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet64|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet68|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet72|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet76|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet80|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet84|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet88|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet92|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet96|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet112|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet116|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet120|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet124|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet44|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet60|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet64|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet68|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet72|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet76|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet80|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet84|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet88|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet92|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet96|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet112|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet116|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet120|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet124|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py3/qos-dell6100.json b/src/sonic-config-engine/tests/sample_output/py3/qos-dell6100.json new file mode 100644 index 000000000000..75d9b3a87eee --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/qos-dell6100.json @@ -0,0 +1,1457 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0" : "1", + "1" : "1", + "2" : "1", + "3" : "3", + "4" : "4", + "5" : "2", + "6" : "1", + "7" : "1", + "8" : "0", + "9" : "1", + "10": "1", + "11": "1", + "12": "1", + "13": "1", + "14": "1", + "15": "1", + "16": "1", + "17": "1", + "18": "1", + "19": "1", + "20": "1", + "21": "1", + "22": "1", + "23": "1", + "24": "1", + "25": "1", + "26": "1", + "27": "1", + "28": "1", + "29": "1", + "30": "1", + "31": "1", + "32": "1", + "33": "1", + "34": "1", + "35": "1", + "36": "1", + "37": "1", + "38": "1", + "39": "1", + "40": "1", + "41": "1", + "42": "1", + "43": "1", + "44": "1", + "45": "1", + "46": "5", + "47": "1", + "48": "6", + "49": "1", + "50": "1", + "51": "1", + "52": "1", + "53": "1", + "54": "1", + "55": "1", + "56": "1", + "57": "1", + "58": "1", + "59": "1", + "60": "1", + "61": "1", + "62": "1", + "63": "1" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "14" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "15" + } + }, + "PORT_QOS_MAP": { + "Ethernet0": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet1": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet4": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet5": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet6": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet7": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet8": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet9": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet10": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet11": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet12": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet13": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet14": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet15": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet16": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet17": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet20": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet21": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet22": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet23": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet24": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet25": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet26": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet27": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet28": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet29": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet30": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet31": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet32": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet36": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet37": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet38": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet39": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet40": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet41": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet42": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet48": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet52": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet53": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet54": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet55": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet56": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet57": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet58": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, + "QUEUE": { + "Ethernet0|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet1|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet5|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet6|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet7|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet9|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet10|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet11|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet13|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet14|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet15|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet17|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet21|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet22|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet23|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet25|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet26|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet27|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet29|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet30|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet31|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet37|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet38|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet39|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet41|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet42|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet53|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet54|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet55|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet57|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet58|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet1|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet5|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet6|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet7|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet9|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet10|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet11|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet13|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet14|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet15|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet17|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet21|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet22|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet23|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet25|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet26|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet27|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet29|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet30|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet31|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet37|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet38|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet39|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet41|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet42|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet53|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet54|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet55|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet57|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet58|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py3/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/staticd_frr.conf new file mode 100644 index 000000000000..31a11d8578aa --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/staticd_frr.conf @@ -0,0 +1,20 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr/staticd.conf.j2 using config DB data +! file: staticd.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf new file mode 100644 index 000000000000..dd79ae3950bb --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf @@ -0,0 +1,87 @@ +! +! template: bgpd/bgpd.conf.j2 +! +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname SpineFront01 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! +! Vnet BGP instance +router bgp 4000 vrf VnetFE + no bgp default ipv4-unicast + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 4.0.0.0 + neighbor 192.168.0.1 remote-as 3000 + neighbor 192.168.0.1 description Leaf01 + neighbor 192.168.0.1 timers 3 10 + address-family ipv4 unicast + neighbor 192.168.0.1 activate + neighbor 192.168.0.1 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +!! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 4.0.0.0/32 +! +! +! +! +router bgp 4000 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 4.0.0.0 +! + network 4.0.0.0/32 +! +! +! +! +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf new file mode 100644 index 000000000000..180a0e9fab89 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf @@ -0,0 +1,32 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname SpineFront01 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +vrf VnetFE +vni 9000 +! +! +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface Ethernet8 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf new file mode 100644 index 000000000000..661b27268255 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf @@ -0,0 +1,32 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname SpineFront01 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +vrf VnetFE +vni 8000 +! +! +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface Ethernet8 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/py3/wait_for_intf.sh new file mode 100644 index 000000000000..6d90afa60ad7 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/wait_for_intf.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +function wait_until_iface_ready +{ + IFACE_NAME=$1 + IFACE_CIDR=$2 + + echo "Waiting until interface ${IFACE_NAME} is ready..." + + # Wait for the interface to come up + # (i.e., interface is present in STATE_DB and state is "ok") + while true; do + RESULT=$(sonic-db-cli STATE_DB HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) + if [ x"$RESULT" == x"ok" ]; then + break + fi + + sleep 1 + done + + echo "Interface ${IFACE_NAME} is ready!" +} + + +# Wait for all interfaces with IPv4 addresses to be up and ready +wait_until_iface_ready Vlan1000 192.168.0.1/27 +wait_until_iface_ready PortChannel01 10.0.0.56/31 +wait_until_iface_ready PortChannel02 10.0.0.58/31 +wait_until_iface_ready PortChannel03 10.0.0.60/31 +wait_until_iface_ready PortChannel04 10.0.0.62/31 + diff --git a/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf new file mode 100644 index 000000000000..e3d0c2d55bc3 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf @@ -0,0 +1,32 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +! +! Enable link-detect (default disabled) +interface PortChannel01 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel03 +link-detect +! +interface PortChannel04 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/zebra_quagga.conf b/src/sonic-config-engine/tests/sample_output/py3/zebra_quagga.conf new file mode 100644 index 000000000000..aa3486b0163a --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/zebra_quagga.conf @@ -0,0 +1,44 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +hostname switch-t0 +password zebra +enable password zebra +! +! Enable link-detect (default disabled) +interface PortChannel01 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel03 +link-detect +! +interface PortChannel04 +link-detect +! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +! +! Set ip source to loopback for bgp learned routes +route-map RM_SET_SRC permit 10 + set src 10.1.0.32 +! + +route-map RM_SET_SRC6 permit 10 + set src fc00:1::32 +! +ip protocol bgp route-map RM_SET_SRC +! +ipv6 protocol bgp route-map RM_SET_SRC6 +! +! +log syslog informational +log facility local4 +! + diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index d42438e61c25..ebaba3394f27 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -13,7 +13,7 @@ class TestCfgGen(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph = os.path.join(self.test_dir, 'sample_graph.xml') self.sample_graph_t0 = os.path.join(self.test_dir, 't0-sample-graph.xml') self.sample_graph_simple = os.path.join(self.test_dir, 'simple-sample-graph.xml') @@ -40,6 +40,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) diff --git a/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py b/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py index 8ffd72907b21..1ac2b7f7f5f3 100644 --- a/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py +++ b/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py @@ -1,11 +1,17 @@ -from unittest import TestCase import subprocess +import tests.common_utils as utils + +from unittest import TestCase + + class TestPfxFilter(TestCase): def test_comprehensive(self): # Generate output data_dir = "tests/data/pfx_filter" - cmd = "./sonic-cfggen -j %s/param_1.json -t %s/tmpl_1.txt.j2 > /tmp/result_1.txt" % (data_dir, data_dir) + cmd = "{} ./sonic-cfggen -j {}/param_1.json -t {}/tmpl_1.txt.j2 > /tmp/result_1.txt".format( + utils.PYTHON_INTERPRETTER, data_dir, data_dir + ) subprocess.check_output(cmd, shell=True) # Compare outputs cmd = "diff -u tests/data/pfx_filter/result_1.txt /tmp/result_1.txt" diff --git a/src/sonic-config-engine/tests/test_cfggen_platformJson.py b/src/sonic-config-engine/tests/test_cfggen_platformJson.py index 34fde9a8e5ca..254ec77ae00d 100644 --- a/src/sonic-config-engine/tests/test_cfggen_platformJson.py +++ b/src/sonic-config-engine/tests/test_cfggen_platformJson.py @@ -15,7 +15,7 @@ class TestCfgGenPlatformJson(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph_simple = os.path.join(self.test_dir, 'simple-sample-graph.xml') self.platform_json = os.path.join(self.test_dir, 'sample_platform.json') self.hwsku_json = os.path.join(self.test_dir, 'sample_hwsku.json') @@ -27,6 +27,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) diff --git a/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py b/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py index d0a4f2c0de59..a3d6d02a7ff2 100644 --- a/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py +++ b/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py @@ -10,7 +10,7 @@ class TestCfgGenT2ChassisFe(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph_t2_chassis_fe = os.path.join(self.test_dir, 't2-chassis-fe-graph.xml') self.sample_graph_t2_chassis_fe_vni = os.path.join(self.test_dir, 't2-chassis-fe-graph-vni.xml') self.sample_graph_t2_chassis_fe_pc = os.path.join(self.test_dir, 't2-chassis-fe-graph-pc.xml') @@ -23,6 +23,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) diff --git a/src/sonic-config-engine/tests/test_frr.py b/src/sonic-config-engine/tests/test_frr.py index ef7c4b06f7db..386ce42e0242 100644 --- a/src/sonic-config-engine/tests/test_frr.py +++ b/src/sonic-config-engine/tests/test_frr.py @@ -1,7 +1,6 @@ import filecmp import os import subprocess -import sys import tests.common_utils as utils @@ -10,7 +9,7 @@ class TestCfgGen(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml') self.t0_port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') self.output_file = os.path.join(self.test_dir, 'output') @@ -29,6 +28,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 8ce55f2c4427..30e1f1ca26bf 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -11,7 +11,7 @@ class TestJ2Files(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.simple_minigraph = os.path.join(self.test_dir, 'simple-sample-graph.xml') self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml') self.t0_mvrf_minigraph = os.path.join(self.test_dir, 't0-sample-graph-mvrf.xml') @@ -27,7 +27,12 @@ def setUp(self): def run_script(self, argument): print('CMD: sonic-cfggen ' + argument) - return subprocess.check_output(self.script_file + ' ' + argument, shell=True) + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + if utils.PY3x: + output = output.decode() + + return output def run_diff(self, file1, file2): return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) diff --git a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py index b185f58a8c81..e6bc82941bf6 100644 --- a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py +++ b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py @@ -11,7 +11,7 @@ class TestJ2FilesT2ChassisFe(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.t2_chassis_fe_minigraph = os.path.join(self.test_dir, 't2-chassis-fe-graph.xml') self.t2_chassis_fe_vni_minigraph = os.path.join(self.test_dir, 't2-chassis-fe-graph-vni.xml') self.t2_chassis_fe_pc_minigraph = os.path.join(self.test_dir, 't2-chassis-fe-graph-pc.xml') @@ -26,7 +26,12 @@ def tearDown(self): def run_script(self, argument): print('CMD: sonic-cfggen ' + argument) - return subprocess.check_output(self.script_file + ' ' + argument, shell=True) + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + if utils.PY3x: + output = output.decode() + + return output def run_diff(self, file1, file2): return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 505d5cfcbf7f..f9c390b6536a 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -10,7 +10,7 @@ class TestCfgGenCaseInsensitive(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph = os.path.join(self.test_dir, 'simple-sample-graph-case.xml') self.port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') @@ -21,6 +21,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 2aa212e30aae..8c2e59d99ba7 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -21,7 +21,7 @@ class TestMultiNpuCfgGen(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) self.test_data_dir = os.path.join(self.test_dir, 'multi_npu_data') - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph = os.path.join(self.test_data_dir, 'sample-minigraph.xml') self.port_config = [] for asic in range(NUM_ASIC): @@ -34,6 +34,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) From 57a584997ae2a44174e6ee725885a8a906c46847 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 22:52:18 -0700 Subject: [PATCH 1190/1427] [cfggen] Iterative Version Of Deep Update Avoiding recursive update of maps as it consumes stack frames. This PR introduces iterative version of deep_update method. signed-off-by: Tamer Ahmed --- src/sonic-config-engine/sonic-cfggen | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 892647a757ac..de99d2523027 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -197,12 +197,16 @@ TODO(taoyl): Current version of config db only supports BGP admin states. def deep_update(dst, src): - for key, value in src.items(): - if isinstance(value, dict): - node = dst.setdefault(key, {}) - deep_update(node, value) - else: - dst[key] = value + """ Deep update of dst dict with contest of src dict""" + pending_nodes = [(dst, src)] + while len(pending_nodes) > 0: + d, s = pending_nodes.pop(0) + for key, value in s.items(): + if isinstance(value, dict): + node = d.setdefault(key, type(value)()) + pending_nodes.append((node, value)) + else: + d[key] = value return dst # sort_data is required as it is being imported by config/config_mgmt module in sonic_utilities From b01879b44bdb0f5628ca23e1908e46b27bb5b563 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 30 Sep 2020 13:42:20 -0700 Subject: [PATCH 1191/1427] [sonic-py-swsssdk] update submodule for changing redis_client index from db_id to db_name (#5512) --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 91cc6c651e90..3ef02a1e357b 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 91cc6c651e903b65b95838dc3b2cd1d2751c63b6 +Subproject commit 3ef02a1e357b8ce7cbf58e39c775f1f75e69be04 From 1f0f751d4d0849faaa91faa8783123a4482245b8 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 30 Sep 2020 22:35:52 -0700 Subject: [PATCH 1192/1427] [bgpcfgd]: Don't use neighbor metadata in bgpmon sessions (#5506) **- Why I did it** BGP_MONITORS sessions don't have corresponding DEVICE_NEIGHBOR_METADATA CONFIG_DB entries in the minigraphs. Prevent bgpcfgd to wait on such entries for BGP_MONITORS sessions. **- How I did it** Set constructor argument to False that means - don't wait for device neighbors metadata info for BGP_MONITORS **- How to verify it** Build an image, write on your device, use a minigraph with BGP_MONITORS sessions. Check that sessions are populated in the config. --- src/sonic-bgpcfgd/bgpcfgd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd index 3bedd8679004..6f52ac1626e6 100755 --- a/src/sonic-bgpcfgd/bgpcfgd +++ b/src/sonic-bgpcfgd/bgpcfgd @@ -876,7 +876,7 @@ def main(): ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME), # Peer Managers BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), - BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", True), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), ] runner = Runner() From 87d73e282ebe7b23da00f239c07c7b12bc26d0c9 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Thu, 1 Oct 2020 11:16:47 +0200 Subject: [PATCH 1193/1427] [sonic-slave]: Add libzmq to sonic-slave dockers (#5515) --- sonic-slave-buster/Dockerfile.j2 | 2 ++ sonic-slave-stretch/Dockerfile.j2 | 2 ++ 2 files changed, 4 insertions(+) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 11d79278230e..34ef905a7752 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -67,6 +67,8 @@ RUN apt-get update && apt-get install -y \ perl-modules \ libswitch-perl \ dh-systemd \ + libzmq5 \ + libzmq3-dev \ # For quagga build libreadline-dev \ texlive-latex-base \ diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index fb685a2adcf5..54cf2c890021 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -67,6 +67,8 @@ RUN apt-get update && apt-get install -y \ perl-modules \ libswitch-perl \ dh-systemd \ + libzmq5 \ + libzmq3-dev \ # For quagga build libreadline-dev \ texlive-latex-base \ From 30f5557d36d13e0b7ff655b41f7371f089b755d9 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 1 Oct 2020 23:24:35 -0700 Subject: [PATCH 1194/1427] Fix generate_l2_config: don't override hostname or device role (ToRRouter) (#5510) * Fix generate_l2_config: don't override hostname because sonic-cfggen may not read from Redis. Fix test_l2switch_template test case to test preset l2 feature. * Improve test script: compare json files with sort_keys * Revert changes on sample_output * Remove members field in VLAN section. Fix test assertTrue statement. --- src/sonic-config-engine/config_samples.py | 6 ------ src/sonic-config-engine/tests/test_j2files.py | 9 ++++++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/sonic-config-engine/config_samples.py b/src/sonic-config-engine/config_samples.py index 3c3ace884652..99341642961f 100644 --- a/src/sonic-config-engine/config_samples.py +++ b/src/sonic-config-engine/config_samples.py @@ -41,13 +41,7 @@ def generate_empty_config(data): return new_data def generate_l2_config(data): - if 'hostname' not in data['DEVICE_METADATA']['localhost']: - data['DEVICE_METADATA']['localhost']['hostname'] = 'sonic' - if 'type' not in data['DEVICE_METADATA']['localhost']: - data['DEVICE_METADATA']['localhost']['type'] = 'ToRRouter' data['VLAN'] = {'Vlan1000': {'vlanid': '1000'}} - vp = natsorted(list(data['PORT'].keys())) - data['VLAN']['Vlan1000'].setdefault('members', vp) data['VLAN_MEMBER'] = {} for port in natsorted(data['PORT']): data['PORT'][port].setdefault('admin_status', 'up') diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 30e1f1ca26bf..98bb2437628d 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -96,12 +96,15 @@ def test_ipinip(self): assert filecmp.cmp(sample_output_file, self.output_file) def test_l2switch_template(self): - argument = '-k Mellanox-SN2700 -t ' + os.path.join(self.test_dir, '../data/l2switch.j2') + ' -p ' + self.t0_port_config + ' > ' + self.output_file - self.run_script(argument) + argument = '-k Mellanox-SN2700 --preset l2 -p ' + self.t0_port_config + output = self.run_script(argument) + output_json = json.loads(output) sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'l2switch.json') + with open(sample_output_file) as sample_output_fd: + sample_output_json = json.load(sample_output_fd) - self.assertTrue(filecmp.cmp(sample_output_file, self.output_file)) + self.assertTrue(json.dumps(sample_output_json, sort_keys=True) == json.dumps(output_json, sort_keys=True)) def test_qos_arista7050_render_template(self): arista_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'arista', 'x86_64-arista_7050_qx32s', 'Arista-7050-QX-32S') From a24b581d80bac9179c63675f1541559d3e48f660 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 2 Oct 2020 09:05:43 -0700 Subject: [PATCH 1195/1427] [Arista] Add pcie.yaml configuration file for a few platforms (#5527) * Add pcie.yaml configuration for Gardena * Add pcie.yaml configuration for Upperlake * Add pcie.yaml configuration for Clearlake * Add pcie.yaml configuration for Lodoga --- .../arista/x86_64-arista_7050_qx32s/plugins | 1 - .../plugins/eeprom.py | 1 + .../plugins/led_control.py | 1 + .../plugins/pcie.yaml | 135 ++++++ .../plugins/psuutil.py | 1 + .../plugins/sfputil.py | 1 + .../arista/x86_64-arista_7050cx3_32s/plugins | 1 - .../plugins/eeprom.py | 1 + .../plugins/led_control.py | 1 + .../plugins/pcie.yaml | 133 ++++++ .../plugins/psuutil.py | 1 + .../plugins/sfputil.py | 1 + .../arista/x86_64-arista_7060_cx32s/plugins | 1 - .../plugins/eeprom.py | 1 + .../plugins/led_control.py | 1 + .../plugins/pcie.yaml | 140 ++++++ .../plugins/psuutil.py | 1 + .../plugins/sfputil.py | 1 + .../arista/x86_64-arista_7260cx3_64/plugins | 1 - .../plugins/eeprom.py | 1 + .../plugins/led_control.py | 1 + .../plugins/pcie.yaml | 426 ++++++++++++++++++ .../plugins/psuutil.py | 1 + .../plugins/sfputil.py | 1 + 24 files changed, 850 insertions(+), 4 deletions(-) delete mode 120000 device/arista/x86_64-arista_7050_qx32s/plugins create mode 120000 device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py create mode 120000 device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py create mode 100644 device/arista/x86_64-arista_7050_qx32s/plugins/pcie.yaml create mode 120000 device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py create mode 120000 device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py delete mode 120000 device/arista/x86_64-arista_7050cx3_32s/plugins create mode 120000 device/arista/x86_64-arista_7050cx3_32s/plugins/eeprom.py create mode 120000 device/arista/x86_64-arista_7050cx3_32s/plugins/led_control.py create mode 100644 device/arista/x86_64-arista_7050cx3_32s/plugins/pcie.yaml create mode 120000 device/arista/x86_64-arista_7050cx3_32s/plugins/psuutil.py create mode 120000 device/arista/x86_64-arista_7050cx3_32s/plugins/sfputil.py delete mode 120000 device/arista/x86_64-arista_7060_cx32s/plugins create mode 120000 device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py create mode 120000 device/arista/x86_64-arista_7060_cx32s/plugins/led_control.py create mode 100644 device/arista/x86_64-arista_7060_cx32s/plugins/pcie.yaml create mode 120000 device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py create mode 120000 device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py delete mode 120000 device/arista/x86_64-arista_7260cx3_64/plugins create mode 120000 device/arista/x86_64-arista_7260cx3_64/plugins/eeprom.py create mode 120000 device/arista/x86_64-arista_7260cx3_64/plugins/led_control.py create mode 100644 device/arista/x86_64-arista_7260cx3_64/plugins/pcie.yaml create mode 120000 device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py create mode 120000 device/arista/x86_64-arista_7260cx3_64/plugins/sfputil.py diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins b/device/arista/x86_64-arista_7050_qx32s/plugins deleted file mode 120000 index 5fbbf98a6284..000000000000 --- a/device/arista/x86_64-arista_7050_qx32s/plugins +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py b/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py b/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/pcie.yaml b/device/arista/x86_64-arista_7050_qx32s/plugins/pcie.yaml new file mode 100644 index 000000000000..d40522ff4998 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/pcie.yaml @@ -0,0 +1,135 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1536' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Root + Complex' +- bus: '00' + dev: '01' + fn: '0' + id: '9831' + name: 'VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Kabini + [Radeon HD 8400E]' +- bus: '00' + dev: '02' + fn: '0' + id: '1538' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 0' +- bus: '00' + dev: '02' + fn: '1' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '2' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '3' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '4' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '5' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '11' + fn: '0' + id: '7801' + name: 'SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI + mode] (rev 40)' +- bus: '00' + dev: '12' + fn: '0' + id: '7807' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB OHCI Controller + (rev 39)' +- bus: '00' + dev: '12' + fn: '2' + id: '7808' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller + (rev 39)' +- bus: '00' + dev: '14' + fn: '0' + id: 780b + name: 'SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 3a)' +- bus: '00' + dev: '14' + fn: '3' + id: 780e + name: 'ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 11)' +- bus: '00' + dev: '14' + fn: '7' + id: '7813' + name: 'SD Host controller: Advanced Micro Devices, Inc. [AMD] FCH SD Flash Controller + (rev 01)' +- bus: '00' + dev: '18' + fn: '0' + id: '1530' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 0' +- bus: '00' + dev: '18' + fn: '1' + id: '1531' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 1' +- bus: '00' + dev: '18' + fn: '2' + id: '1532' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 2' +- bus: '00' + dev: '18' + fn: '3' + id: '1533' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 3' +- bus: '00' + dev: '18' + fn: '4' + id: '1534' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 4' +- bus: '00' + dev: '18' + fn: '5' + id: '1535' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 5' +- bus: '01' + dev: '00' + fn: '0' + id: b850 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56850 Switch ASIC (rev + 03)' +- bus: '02' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '04' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py b/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py b/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins b/device/arista/x86_64-arista_7050cx3_32s/plugins deleted file mode 120000 index 789a45fcace9..000000000000 --- a/device/arista/x86_64-arista_7050cx3_32s/plugins +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/eeprom.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/led_control.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/pcie.yaml b/device/arista/x86_64-arista_7050cx3_32s/plugins/pcie.yaml new file mode 100644 index 000000000000..f56c87185f3c --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/pcie.yaml @@ -0,0 +1,133 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1566' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Root Complex' +- bus: '00' + dev: '00' + fn: '2' + id: '1567' + name: 'IOMMU: Advanced Micro Devices, Inc. [AMD] Mullins IOMMU' +- bus: '00' + dev: '02' + fn: '0' + id: 156b + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Host Bridge' +- bus: '00' + dev: '02' + fn: '1' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '2' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '3' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '4' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '5' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: 08 + fn: '0' + id: '1537' + name: 'Encryption controller: Advanced Micro Devices, Inc. [AMD] Kabini/Mullins + PSP-Platform Security Processor' +- bus: '00' + dev: '11' + fn: '0' + id: '7801' + name: 'SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI + mode] (rev 40)' +- bus: '00' + dev: '12' + fn: '0' + id: '7808' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller + (rev 39)' +- bus: '00' + dev: '14' + fn: '0' + id: 780b + name: 'SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 42)' +- bus: '00' + dev: '14' + fn: '3' + id: 780e + name: 'ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 11)' +- bus: '00' + dev: '14' + fn: '7' + id: '7813' + name: 'SD Host controller: Advanced Micro Devices, Inc. [AMD] FCH SD Flash Controller + (rev 01)' +- bus: '00' + dev: '18' + fn: '0' + id: '1580' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 0' +- bus: '00' + dev: '18' + fn: '1' + id: '1581' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 1' +- bus: '00' + dev: '18' + fn: '2' + id: '1582' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 2' +- bus: '00' + dev: '18' + fn: '3' + id: '1583' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 3' +- bus: '00' + dev: '18' + fn: '4' + id: '1584' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 4' +- bus: '00' + dev: '18' + fn: '5' + id: '1585' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 5' +- bus: '01' + dev: '00' + fn: '0' + id: b870 + name: 'Ethernet controller: Broadcom Limited Device b870 (rev 01)' +- bus: '02' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '04' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/psuutil.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/sfputil.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins b/device/arista/x86_64-arista_7060_cx32s/plugins deleted file mode 120000 index 5fbbf98a6284..000000000000 --- a/device/arista/x86_64-arista_7060_cx32s/plugins +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py b/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/led_control.py b/device/arista/x86_64-arista_7060_cx32s/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/pcie.yaml b/device/arista/x86_64-arista_7060_cx32s/plugins/pcie.yaml new file mode 100644 index 000000000000..a988a7d1c5fc --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/pcie.yaml @@ -0,0 +1,140 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1566' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Root Complex' +- bus: '00' + dev: '00' + fn: '2' + id: '1567' + name: 'IOMMU: Advanced Micro Devices, Inc. [AMD] Mullins IOMMU' +- bus: '00' + dev: '02' + fn: '0' + id: 156b + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Host Bridge' +- bus: '00' + dev: '02' + fn: '1' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '2' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '3' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '4' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '5' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: 08 + fn: '0' + id: '1537' + name: 'Encryption controller: Advanced Micro Devices, Inc. [AMD] Kabini/Mullins + PSP-Platform Security Processor' +- bus: '00' + dev: '11' + fn: '0' + id: '7801' + name: 'SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI + mode] (rev 40)' +- bus: '00' + dev: '12' + fn: '0' + id: '7808' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller + (rev 39)' +- bus: '00' + dev: '14' + fn: '0' + id: 780b + name: 'SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 42)' +- bus: '00' + dev: '14' + fn: '3' + id: 780e + name: 'ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 11)' +- bus: '00' + dev: '14' + fn: '7' + id: '7813' + name: 'SD Host controller: Advanced Micro Devices, Inc. [AMD] FCH SD Flash Controller + (rev 01)' +- bus: '00' + dev: '18' + fn: '0' + id: '1580' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 0' +- bus: '00' + dev: '18' + fn: '1' + id: '1581' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 1' +- bus: '00' + dev: '18' + fn: '2' + id: '1582' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 2' +- bus: '00' + dev: '18' + fn: '3' + id: '1583' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 3' +- bus: '00' + dev: '18' + fn: '4' + id: '1584' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 4' +- bus: '00' + dev: '18' + fn: '5' + id: '1585' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 5' +- bus: '01' + dev: '00' + fn: '0' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC (rev + 12)' +- bus: '01' + dev: '00' + fn: '1' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC (rev + 12)' +- bus: '02' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '04' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py b/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py b/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins b/device/arista/x86_64-arista_7260cx3_64/plugins deleted file mode 120000 index 5fbbf98a6284..000000000000 --- a/device/arista/x86_64-arista_7260cx3_64/plugins +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/eeprom.py b/device/arista/x86_64-arista_7260cx3_64/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/led_control.py b/device/arista/x86_64-arista_7260cx3_64/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/pcie.yaml b/device/arista/x86_64-arista_7260cx3_64/plugins/pcie.yaml new file mode 100644 index 000000000000..a2540013703e --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/pcie.yaml @@ -0,0 +1,426 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1c + fn: '4' + id: 8c18 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #5 (rev d5)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '00' + dev: 1f + fn: '6' + id: 8c24 + name: 'Signal processing controller: Intel Corporation 8 Series Chipset Family Thermal + Management Controller (rev 05)' +- bus: '01' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' +- bus: '02' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '04' + dev: '00' + fn: '0' + id: 15a7 + name: 'Ethernet controller: Intel Corporation Device 15a7' +- bus: '04' + dev: '00' + fn: '1' + id: 15a7 + name: 'Ethernet controller: Intel Corporation Device 15a7' +- bus: '06' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '07' + dev: '00' + fn: '0' + id: b971 + name: 'Ethernet controller: Broadcom Limited Device b971 (rev 11)' +- bus: '07' + dev: '00' + fn: '1' + id: b971 + name: 'Ethernet controller: Broadcom Limited Device b971 (rev 11)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py b/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/sfputil.py b/device/arista/x86_64-arista_7260cx3_64/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file From dda98023e3e982580091f6f185ff2df77a2148c8 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 2 Oct 2020 09:06:30 -0700 Subject: [PATCH 1196/1427] [Submodule update] sonic swss (#5489) be51ebc533cbe92a885c584b4611ffc92d10ea36 Add IPv6 key item support to request parser (#1449) 76e22516bffe45d577ab9cce4f5d96687140fe75 When teamd feature state is disabled the Netdevice created by teamd were (#1450) 6aa97ce7982b78a26803908c0ce12302e51df793 Use .clear() after std::move() (#1444) d5757db5d896aa2405f6cbf9f4c150f46b27aa4e Add libzmq to README dependencies (#1447) c7b262ee61973a48943603810c8246a2471d1862 Add libzmq to Makefiles (#1443) 0b2e59ab6b909e5ea06013da03215f0d1af1e618 [drop counters] Clarify log messages for initial counter setup (#1445) 003cf24353c845ef708d192b7da8d571537671e1 [dvs] Refactor and add buffer pool wm test (#1446) 2f5d2d99dfae506333bddda9de2f289f92bb889b [acl] Remove Ethertype from L3V6 qualifiers (#1433) f7b974f7fc6474a6493a7b6d0676e17caffa6165 Fix issue: bufferorch only pass the first attribute to sai when setting attribute (#1442) Signed-off-by: Abhishek Dosi --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index b4938a5519d6..be51ebc533cb 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit b4938a5519d633ac22eac5e1ea27820d1e665239 +Subproject commit be51ebc533cbe92a885c584b4611ffc92d10ea36 From 8418bd3df3a1d0e6ebf15bcfd41d2be034454b65 Mon Sep 17 00:00:00 2001 From: Ciju Rajan K <53076238+ciju-juniper@users.noreply.github.com> Date: Fri, 2 Oct 2020 21:36:55 +0530 Subject: [PATCH 1197/1427] [Juniper] Updating platform documentation (#5478) This patch set updates the documentation for QFX5200 & QFX5210 Juniper switching platforms. Signed-off-by: Ciju Rajan K --- .../sonic-platform-modules-juniper/README.md | 78 +++++++----- .../qfx5200/utils/README | 119 +++++++++++------- 2 files changed, 123 insertions(+), 74 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-juniper/README.md b/platform/broadcom/sonic-platform-modules-juniper/README.md index 2b43eee68271..3a661cef8eeb 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/README.md +++ b/platform/broadcom/sonic-platform-modules-juniper/README.md @@ -1,30 +1,27 @@ -Juniper Networks Platform Support for SONiC Readme -================================================== +Juniper Networks Platform Support for SONiC +=========================================== -This readme provides information on how to install and upgrade ONIE and SONiC images on the Juniper Networks QFX5210-64C-S switch. +This readme provides information on how to install and upgrade ONIE and SONiC images on the Juniper Networks switches. -Note: The QFX5210-64C-S switch ships with ONIE and SONiC images preinstalled. - -## Purpose - -This package contains kernel drivers, a python library, and a python script to provide platform support for Juniper Networks QFX5210-64C-S switch. +Note: Switches ship with ONIE and SONiC images preinstalled. ## Supported platforms -The following Juniper Networks platform is supported for the SONiC operating system: +The following Juniper Networks platforms are supported for the SONiC operating system: - QFX5210-64C-S + - QFX5200-32C-S -## Installing ONIE on QFX5210-64C-S Switch - -The following information describes how to install ONIE on the Juniper Networks QFX5210-64C-S switch. +## Building and Installing ONIE -To install ONIE on Juniper Networks QFX5210-64C-S switch, you need to: +ONIE is the bootloader used and it's a prerequisite to install ONIE on the switches before installing SONiC. 1. Cross compile ONIE -To compile ONIE, you need to change the directories to "build-config" and then type "make MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all". +To compile ONIE, you need to change the directories to "build-config" and then based on the platform issue the following commands + +a) For QFX5210-64C-S platform, invoke "make MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all". For example: @@ -33,6 +30,8 @@ For example: $ make -j4 MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all ``` +b) For QFX5200-32C-S platform, invoke "make MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5200 all". + ONIE binaries are located at the directory /build/images. The following command shows how to navigate the directory to view the ONIE binaries: ``` @@ -50,6 +49,8 @@ total 40740 Note: Use the following command to build a demo target: +For example: + ``` $ make -j4 MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all demo ``` @@ -65,20 +66,22 @@ You can install these binary files by using the 'onie-nos-install' command to te Use the following command for make clean: +For example: + ``` $ make machine-clean MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 ``` -## Installing ONIE on a New QFX5210-64C-S Switch +## Installing ONIE -The following information describes on how to install ONIE on the Juniper Networks QFX5210-64C-S switch. You can do a fresh install of ONIE image on the QFX5210-64C-S switch, or recover an existing ONIE image from the QFX5210-64C-S switch that has been corrupted. - -To install ONIE on a new QFX5210-64C-S switch, you can use one of the following ONIE recovery images: +To install ONIE on a new switch, you can use one of the following ONIE recovery images: 1) ..iso -- Hybrid ISO image. 2) ..efi64.pxe -- PXE image for UEFI64 machines. +Note: Second method is not applicable for QFX5200-32C-S + ## Creating an ISO Recovery Image @@ -101,11 +104,11 @@ You can find the correct "/dev/sdX" by validating the "dmesg" output after inser 1) Booting from a USB Memory Device -To boot from an external USB memory device connected to the QFX5210-64C-S switch, you need to: +To boot from an external USB memory device connected to the switch, you need to: -a. Insert the USB memory device to the USB port of the QFX5210-64C-S switch. +a. Insert the USB memory device to the USB port of the switch. -b. Power on the QFX5210-64C-S switch and enter the BIOS configuration by pressing the Esc key, as displayed in the console screen. +b. Power on the switch and enter the BIOS configuration by pressing the Esc key, as displayed in the console screen. c. Set the hard drive boot order as follows: @@ -134,7 +137,7 @@ c. Set the hard drive boot order as follows: d. Go to "Save & Exit" in the BIOS screen and from the Boot Override option select the USB memory device (For example, JetFlashTranscend 8GB 8.07). -e. After a few seconds, the QFX5210-64C-S switch would restart and boot from the USB memory device and then you will see the following on the console screen: +e. After a few seconds, the switch would restart and boot from the USB memory device and then you will see the following on the console screen: ``` GNU GRUB version 2.02~beta2+e4a1fe391 @@ -168,6 +171,8 @@ g. Select "ONIE: Rescue" to enter the ONIE recovery command-line shell (Optional 2) Recovering ONIE using PXE-UEFI64 Recovery Image +Note: This section is only applicable for QFX5210-64C-S platform. + You can use the onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe image to recover the ONIE image through UEFI PXE. The onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe is made for the QFX5210-64C-S switch that has a PXE client which is based on UEFI64. @@ -192,12 +197,12 @@ The following links provide more information about ONIE: ## SONiC Build Process: -The instruction on how to build an ONIE compatible network operating system (NOS) installer image for Juniper Networks QFX5210-64C-S switch, and how to build docker images running inside the NOS is available at https://github.com/Azure/sonic-buildimage#usage. +The instruction on how to build an ONIE compatible network operating system (NOS) installer image for Juniper Networks switches, and how to build docker images running inside the NOS is available at https://github.com/Azure/sonic-buildimage#usage. -## Install SONiC on the Juniper Networks QFX5210-64C-S switch: +## Install SONiC on the Juniper Networks switch:es -You need to copy the SONiC image sonic-broadcom.bin to the Juniper Networks QFX5210-64C-S switch. You can copy the sonic-broadcom.bin to an USB memory device and insert it to the USB port of the QFX5210-64C-S switch. You can also use the 'scp' command to copy the sonic-broadcom.bin image to the QFX5210-64C-S switch over the network. +You need to copy the SONiC image 'sonic-broadcom.bin' to the switch. You can copy the sonic-broadcom.bin to an USB memory device and insert it to the USB port of the switch. You can also use the 'scp' command to copy the sonic-broadcom.bin image to the switch over the network. Note: Unmount the USB memory device after copying the sonic-broadcom.bin. For example, umount /dev/sdX, where X is the name of the drive of the USB memory device. @@ -210,7 +215,7 @@ ONIE:/var/tmp # onie-nos-install /var/tmp/sonic-broadcom.bin ## Booting SONiC -The QFX5210-64C-S switch restarts automatically after the SONiC image has been successfully installed. +The switch restarts automatically after the SONiC image has been successfully installed. 1) Select SONiC from the GRUB boot manager. @@ -239,35 +244,44 @@ The QFX5210-64C-S switch restarts automatically after the SONiC image has been s 2. At the SONiC login prompt, enter the username as admin and password as YourPaSsWoRd. -You can now start configuring the Juniper Networks QFX5210-64C-S switch running SONiC as its operating system. +You can now start configuring the Juniper Networks switch running SONiC as its operating system. ## Upgrading SONiC image To upgrade the SONiC operating system to a latest version, you need to: - 1. Copy the latest image of the SONiC image to the QFX5210-64C-S switch. + 1. Copy the latest image of the SONiC image to the switch. 2. Run the following command from the directory where the latest SONiC image has been copied. ``` $ sudo ./sonic-braodcom.bin ``` +or + +``` +$ sudo sonic-installer ./sonic-broadcom.bin -y +``` + ## Uninstalling SONiC image -To unintall SONiC operating system from QFX5210-64C-S switch, you need to: +To unintall SONiC operating system from the switch, you need to: - 1. Reboot the QFX5210-64C-S switch. + 1. Reboot the switch. 2. Go to the ONIE GRUB menu and then select ONIE: Uninstall OS option to uninstall SONiC. -For more details on drivers and platform scripts see https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README +For more details on drivers and platform scripts see the following links: + +1) QFX5210-64C-S: https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README + +2) QFX5200-32C-S: https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README ## Related Documentation for SONiC: The following links provide more information about SONiC: 1. SONiC documentation: https://github.com/azure/sonic/wiki. - 2. Learn about QFX5210-64C-S SONiC platform: https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README ## Viewing the Device Revision of the FRU Model from IDEEPROM diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README index ec9ebe97f0ee..558410def831 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README @@ -1,5 +1,5 @@ -Copyright (c) 2019, Juniper Networks, Inc. +Copyright (c) 2020, Juniper Networks, Inc. All rights reserved. Front panel LEDs @@ -30,44 +30,93 @@ accepted. System FANs =========== -There are 4 fans and each of the fan has 2 fan modules. Overall there are -8 fans in the system. +There are 5 fans and each of the fan has 2 fan modules. Overall there are +10 fans in the system. These fans are controlled by ADT7470 driver. -Fan controls can be found in /sys/bus/i2c/devices/17-0068. All the fans -are controlled by one duty cycle value, ranges from 0 to 100 +Fan controls can be found in + /sys/bus/i2c/devices/7-002c + /sys/bus/i2c/devices/7-002e + /sys/bus/i2c/devices/7-002f -Fan duty cycle can be controlled through /sys/bus/i2c/devices/17-0068/pwm1 +For example, the complete path to driver control files will be + /sys/bus/i2c/devices/7-002c/hwmon/hwmon12 -Fan module presence is given by /sys/bus/i2c/devices/17-0068/fan[1-4]_present +Fan duty cycle can be controlled through 'pwm1', 'pwm2', 'pwm3', 'pwm4' sysfs files. + +For example, these are the absolute paths to the control files + + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm1 7-002c controls 2 fan modules + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm2 + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm3 + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm4 + + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm1 7-002e controls 2 fan modules + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm2 + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm3 + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm4 + + /sys/bus/i2c/devices/7-002f/hwmon/hwmon*/pwm1 7-002c controls only 1 fan module + /sys/bus/i2c/devices/7-002f/hwmon/hwmon*/pwm2 + +For convenience, it will be represented as +/sys/bus/i2c/devices/7-002[c/e/f]/hwmon/hwmon*/pwm[1-4] + +Fan speed is given by +/sys/bus/i2c/devices/7-002[c/e/f]/hwmon/hwmon*/fan[1-4]_input + +Fan module presence is given by +/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan[0-4]_present file. A value of '1' indicate that fan is present & a value of '0' otherwise. -Fan rotation direction is given by /sys/bus/i2c/devices/17-0068/fan[1-4]_direction. -A value of '0' indicate the direction is AFO (Front to back airflow) or Airflow -out. A value of '1' indicate that direction is AFI (Back to front airflow) or +Fan rotation direction is given by +/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan[0-4]_type +A value of '1' indicate the direction is AFO (Front to back airflow) or Airflow +out. A value of '0' indicate that direction is AFI (Back to front airflow) or Airflow in. -Fan speed is given by fan[1-4]_input Temperature sensors =================== -There are 6 temperature sensors. The readings are available in -/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input +There are 10 temperature sensors. Kernel driver tmp401 is used for +reading temeperature sensors. + +The readings are available in + +/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/5-0049/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/5-004a/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/5-004b/hwmon/hwmon*/temp1_input + +/sys/bus/i2c/devices/6-0048/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/6-0049/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/6-004a/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/6-004b/hwmon/hwmon*/temp1_input + +/sys/bus/i2c/devices/7-0048/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/7-0049/hwmon/hwmon*/temp1_input System PSUs =========== -There are two independent PSUs. These are controlled by a dedicated CPLD. -The status registers are mapped under /sys/bus/i2c/devices/9-0050 and -/sys/bus/i2c/devices/10-0053. +There are two independent PSUs. These are controlled by TMC fpga. + +PSU presence is given by jnx-tmc-psu dirver and is available at +/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/psu-tmc.15/psu*_present +A value of '1' indicate PSU is present and a value of '0' otherwise. + +PSU monitoring data is provided by jnx-psu-monitor driver and is available at +/sys/bus/i2c/devices/3-0058 +/sys/bus/i2c/devices/4-0058 SFPs ==== -There are 64 QSFP+ modules supported in qfx5210 platform. EEPORMs will be -mapped under /sys/bus/i2c/devices/[25-88]-0050/ sysfs directory. +There are 32 QSFP+ modules supported in qfx5200 platform. EEPORMs will be +mapped under /sys/bus/i2c/devices/[14-45]-0050/ sysfs directory. -FEC should be turned on for 100G SR optics and should be turned off for -100G LR optics. If the optic is changed, please update the entry and -reload the configuration. If the FEC mode is not set as per the optic -type the port may not link up or work properly. +FEC should be turned on for 100G SR4 & PSM4 optics and should +be turned off for 100G LR4 optics. If the FEC mode is not set +as per the optic type the port may not link up or work properly. +In some cases while interoperating between other NOSs & traffic +generators, FEC need to be enabled even for 100G DAC cables. As an example, see this configuration for FEC for 100G SR4 optics in /etc/sonic/config_db.json @@ -85,33 +134,19 @@ As an example, see this configuration for FEC for 100G SR4 optics in Sensor details ============== LM75 supported sensor modules will be available under 'sensors' command. -If you want to get all the sensor data including the SFPs & LEDs, you can -invoke 'sudo juniper_qfx5210_util.py show' -Platform poweroff +Platform reboot ================= -Linux poweroff commands such as 'poweroff', 'shutdown', 'halt', etc. will not -power off qfx5210 platform as there are custom CPLDs control the power off -sequences. So acpi poweroff hooks are added for powering off the qfx5210. The -following messages are displayed in the console towards end of poweroff -sequence: - - [ 52.500807] System halt/power_off - [ 52.866331] reboot: Power down - [ 52.903257] pm_power_off: qfx5210_cpld_power_off - -Once the above messages are seen, you can safely remove the power to the system. - -Similarly platform reboot sequences are in place for system reboot. The following +Platform reboot sequences are in place for system reboot. The following messages are displayed in the console when the system is rebooted: - [ 6053.163363] System restart: qfx5210_cpld_soft_reset + [ 6053.163363] System restart: qfx5200_cpu_reset Platform monitoring daemon ========================== -“juniper_qfx5210_monitor.py†is the platform monitoring script. -It implements the qfx5210 EM policy. This script will run as system service +“juniper_qfx5200_monitor.py†is the platform monitoring script. +It implements the qfx5200 EM policy. This script will run as system service and monitor the temperature sensors in every 20 seconds. Based on the EM policy thresholds, it controls the fan rpm, manage alarm leds, and -shutdown the box. +shutdown the box in case of any over heating. From c0bbb7b63dd4ab4622bc1ee9abf4024801456cec Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 2 Oct 2020 09:09:38 -0700 Subject: [PATCH 1198/1427] Fix python expception of missing subprocess (#5503) Signed-off-by: Abhishek Dosi --- src/sonic-py-common/sonic_py_common/multi_asic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index 0b2b1d9da9b8..cb80635dbc0a 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -1,5 +1,6 @@ import glob import os +import subprocess from natsort import natsorted from swsssdk import ConfigDBConnector From db6fa1d2938a1bdb1e66a9ba96b22b5111055424 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 2 Oct 2020 09:16:05 -0700 Subject: [PATCH 1199/1427] [led]: Skip ledinit if there is no led_proc_init.soc file for broadcom platform (#5483) Some platforms don't leverage the brcm led coprocessor. However ledinit will try to load a non existing file and exit with an error code. This change is a cosmetic fix mostly. - How to verify it Boot a platform without the configuration and verify in the syslog that the exit status of ledinit is 0 Boot a platform with the configuration and verify in the syslog that the exit status of ledinit is 0 and the leds are working. Verified by adding a dumb led_proc_init.soc on an Arista platform which usually doesn't use it. --- platform/broadcom/docker-syncd-brcm/start_led.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/docker-syncd-brcm/start_led.sh b/platform/broadcom/docker-syncd-brcm/start_led.sh index 01d25cded8ea..964aa23eb04f 100755 --- a/platform/broadcom/docker-syncd-brcm/start_led.sh +++ b/platform/broadcom/docker-syncd-brcm/start_led.sh @@ -2,6 +2,12 @@ PLATFORM_DIR=/usr/share/sonic/platform SYNCD_SOCKET_FILE=/var/run/sswsyncd/sswsyncd.socket +LED_PROC_INIT_SOC=${PLATFORM_DIR}/led_proc_init.soc + +if [ ! -f "$LED_PROC_INIT_SOC" ]; then + echo "No soc led configuration found under $LED_SOC_INIT_SOC" + exit 0 +fi # Function: wait until syncd has created the socket for bcmcmd to connect to wait_syncd() { @@ -30,8 +36,8 @@ wait_syncd() { } # If this platform has an initialization file for the Broadcom LED microprocessor, load it -if [[ -r ${PLATFORM_DIR}/led_proc_init.soc && ! -f /var/warmboot/warm-starting ]]; then +if [[ -r "$LED_PROC_INIT_SOC" && ! -f /var/warmboot/warm-starting ]]; then wait_syncd fi -/usr/bin/bcmcmd -t 60 "rcload /usr/share/sonic/platform/led_proc_init.soc" +/usr/bin/bcmcmd -t 60 "rcload $LED_PROC_INIT_SOC" From e15e6a8313c99b29bc2fdb5e62f8808c5c93440f Mon Sep 17 00:00:00 2001 From: anish-n <44376847+anish-n@users.noreply.github.com> Date: Fri, 2 Oct 2020 09:25:29 -0700 Subject: [PATCH 1200/1427] [config-reload]: Add logic to clean up FG_ROUTE state db table during reload (#5518) Cleanup FG_ROUTE state db table during reload --- files/scripts/swss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 0ef605fd83c8..129e5d148dc8 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -147,7 +147,7 @@ start() { $SONIC_DB_CLI ASIC_DB FLUSHDB $SONIC_DB_CLI COUNTERS_DB FLUSHDB $SONIC_DB_CLI FLEX_COUNTER_DB FLUSHDB - clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" + clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*', 'FG_ROUTE_TABLE*'" fi # start service docker From ffae82f8be6b8024784cd868882e9b1362522092 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 2 Oct 2020 10:06:04 -0700 Subject: [PATCH 1201/1427] [bgp] Add 'allow list' manager feature (#5513) implements a new feature: "BGP Allow list." This feature allows us to control which IP prefixes are going to be advertised via ebgp from the routes received from EBGP neighbors. --- .../bgpd/templates/general/peer-group.conf.j2 | 2 +- .../bgpd/templates/general/policies.conf.j2 | 27 + files/image_config/constants/constants.yml | 12 + rules/sonic_bgpcfgd.mk | 2 +- src/sonic-bgpcfgd/.gitignore | 1 + src/sonic-bgpcfgd/app/allow_list.py | 632 ++++++++++++++++++ src/sonic-bgpcfgd/app/config.py | 20 +- src/sonic-bgpcfgd/app/directory.py | 159 +++++ src/sonic-bgpcfgd/app/manager.py | 71 ++ src/sonic-bgpcfgd/app/vars.py | 2 +- src/sonic-bgpcfgd/bgpcfgd | 7 +- src/sonic-bgpcfgd/pytest.ini | 2 + src/sonic-bgpcfgd/setup.py | 3 +- .../data/general/policies.conf/param_all.json | 13 +- .../general/policies.conf/param_base.json | 11 +- .../general/policies.conf/param_deny.json | 17 + .../general/policies.conf/result_all.conf | 14 + .../general/policies.conf/result_deny.conf | 39 ++ src/sonic-bgpcfgd/tests/test_allow_list.py | 482 +++++++++++++ .../tests/test_ipv6_nexthop_global.py | 29 +- src/sonic-bgpcfgd/tests/util.py | 4 +- 21 files changed, 1527 insertions(+), 22 deletions(-) create mode 100644 src/sonic-bgpcfgd/app/allow_list.py create mode 100644 src/sonic-bgpcfgd/app/directory.py create mode 100644 src/sonic-bgpcfgd/app/manager.py create mode 100644 src/sonic-bgpcfgd/pytest.ini create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf create mode 100644 src/sonic-bgpcfgd/tests/test_allow_list.py diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 index b0acd1b2a460..5790d47a5a8a 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -24,7 +24,7 @@ {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V6 allowas-in 1 neighbor PEER_V6_INT allowas-in 1 - {% endif %} +{% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor PEER_V6_INT route-reflector-client {% endif %} diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 index c545cf272892..4c27db4a466a 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -3,6 +3,33 @@ ! ! ! +{% if constants.bgp.allow_list is defined and constants.bgp.allow_list.enabled is defined and constants.bgp.allow_list.enabled %} +{% if constants.bgp.allow_list.default_action is defined and constants.bgp.allow_list.default_action.strip() == 'deny' %} +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community no-export additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community no-export additive +{% else %} +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community {{ constants.bgp.allow_list.drop_community }} additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community {{ constants.bgp.allow_list.drop_community }} additive +{% endif %} +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! +{% endif %} +! +! +! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 3e1b76be0157..074956ff8396 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -18,6 +18,18 @@ constants: enabled: true ipv4: 64 ipv6: 64 + allow_list: + enabled: true + default_action: "permit" # or "deny" + drop_community: 5060:12345 # value of the community to identify a prefix to drop. Make sense only with allow_list_default_action equal to 'permit' + default_pl_rules: + v4: + - "deny 0.0.0.0/0 le 17" + - "permit 127.0.0.1/32" + v6: + - "deny 0::/0 le 59" + - "deny 0::/0 ge 65" + - "permit fe80::/64" peers: general: # peer_type db_table: "BGP_NEIGHBOR" diff --git a/rules/sonic_bgpcfgd.mk b/rules/sonic_bgpcfgd.mk index 32abbd5af948..17e2c7b3f780 100644 --- a/rules/sonic_bgpcfgd.mk +++ b/rules/sonic_bgpcfgd.mk @@ -6,6 +6,6 @@ $(SONIC_BGPCFGD)_SRC_PATH = $(SRC_PATH)/sonic-bgpcfgd # of sonic-config-engine and bgpcfgd explicitly calls sonic-cfggen # as part of its unit tests. # TODO: Refactor unit tests so that these dependencies are not needed -$(SONIC_BGPCFGD)_DEPENDS += $(SWSSSDK_PY2) $(SONIC_PY_COMMON_PY2) +$(SONIC_BGPCFGD)_DEPENDS += $(SONIC_PY_COMMON_PY2) $(SONIC_BGPCFGD)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_BGPCFGD) diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore index bb1ba531d1d6..920a1b3ae499 100644 --- a/src/sonic-bgpcfgd/.gitignore +++ b/src/sonic-bgpcfgd/.gitignore @@ -6,3 +6,4 @@ app/*.pyc tests/*.pyc tests/__pycache__/ .idea +.coverage diff --git a/src/sonic-bgpcfgd/app/allow_list.py b/src/sonic-bgpcfgd/app/allow_list.py new file mode 100644 index 000000000000..2637d6999244 --- /dev/null +++ b/src/sonic-bgpcfgd/app/allow_list.py @@ -0,0 +1,632 @@ +""" +Implementation of "allow-list" feature +""" +import re + +from app.log import log_debug, log_info, log_err, log_warn +from app.template import TemplateFabric +from app.manager import Manager +from app.util import run_command + +class BGPAllowListMgr(Manager): + """ This class initialize "AllowList" settings """ + ALLOW_ADDRESS_PL_NAME_TMPL = "ALLOW_ADDRESS_%d_%s" # template for a name for the ALLOW_ADDRESS prefix-list ??? + EMPTY_COMMUNITY = "empty" + PL_NAME_TMPL = "PL_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s_V%s" + COMMUNITY_NAME_TMPL = "COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s" + RM_NAME_TMPL = "ALLOW_LIST_DEPLOYMENT_ID_%d_V%s" + ROUTE_MAP_ENTRY_WITH_COMMUNITY_START = 10 + ROUTE_MAP_ENTRY_WITH_COMMUNITY_END = 29990 + ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START = 30000 + ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END = 65530 + + V4 = "v4" # constant for af enum: V4 + V6 = "v6" # constant for af enum: V6 + + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(BGPAllowListMgr, self).__init__( + common_objs, + [], + db, + table, + ) + self.cfg_mgr = common_objs["cfg_mgr"] + self.constants = common_objs["constants"] + self.key_re = re.compile(r"^DEPLOYMENT_ID\|\d+\|\S+$|^DEPLOYMENT_ID\|\d+$") + self.enabled = self.__get_enabled() + self.__load_constant_lists() + + def set_handler(self, key, data): + """ + Manager method which runs on receiving 'SET' message + :param key: ket of the 'SET' message + :param data: data of the 'SET' message + :return: True if the message was executed, False - the message should be postponed. + """ + if not self.enabled: + log_warn("BGPAllowListMgr::Received 'SET' command, but this feature is disabled in constants") + return True + if not self.__set_handler_validate(key, data): + return True + key = key.replace("DEPLOYMENT_ID|", "") + deployment_id, community_value = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) + deployment_id = int(deployment_id) + prefixes_v4 = [] + prefixes_v6 = [] + if "prefixes_v4" in data: + prefixes_v4 = str(data['prefixes_v4']).split(",") + if "prefixes_v6" in data: + prefixes_v6 = str(data['prefixes_v6']).split(",") + self.__update_policy(deployment_id, community_value, prefixes_v4, prefixes_v6) + return True + + def __set_handler_validate(self, key, data): + """ + Validate parameters of a "Set" message + :param key: ket of the 'SET' message + :param data: data of the 'SET' message + :return: True if parameters are valid, False if parameters are invalid + """ + if data is None: + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message without data") + return False + if not self.key_re.match(key): + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid key: '%s'" % key) + return False + prefixes_v4 = [] + prefixes_v6 = [] + if "prefixes_v4" in data: + prefixes_v4 = str(data["prefixes_v4"]).split(",") + if not all(TemplateFabric.is_ipv4(prefix) for prefix in prefixes_v4): + arguments = "prefixes_v4", str(data["prefixes_v4"]) + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) + return False + if "prefixes_v6" in data: + prefixes_v6 = str(data["prefixes_v6"]).split(",") + if not all(TemplateFabric.is_ipv6(prefix) for prefix in prefixes_v6): + arguments = "prefixes_v6", str(data["prefixes_v6"]) + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) + return False + if not prefixes_v4 and not prefixes_v6: + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with no prefixes specified: %s" % str(data)) + return False + return True + + def del_handler(self, key): + """ + Manager method which runs on "DEL" message + :param key: a key of "DEL" message + """ + if not self.enabled: + log_warn("BGPAllowListMgr::Received 'DEL' command, but this feature is disabled in constants") + return + if not self.__del_handler_validate(key): + return + key = key.replace('DEPLOYMENT_ID|', '') + deployment_id, community = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) + deployment_id = int(deployment_id) + self.__remove_policy(deployment_id, community) + + def __del_handler_validate(self, key): + """ + Validate "DEL" method parameters + :param key: a key of "DEL" message + :return: True if parameters are valid, False if parameters are invalid + """ + if not self.key_re.match(key): + log_err("BGPAllowListMgr::Received BGP ALLOWED 'DEL' message with invalid key: '$s'" % key) + return False + return True + + def __update_policy(self, deployment_id, community_value, prefixes_v4, prefixes_v6): + """ + Update "allow list" policy with parameters + :param deployment_id: deployment id which policy will be changed + :param community_value: community value to match for the updated policy + :param prefixes_v4: a list of v4 prefixes for the updated policy + :param prefixes_v6: a list of v6 prefixes for the updated policy + """ + # update all related entries with the information + info = deployment_id, community_value, str(prefixes_v4), str(prefixes_v6) + msg = "BGPAllowListMgr::Updating 'Allow list' policy." + msg += " deployment_id '%s'. community: '%s'" + msg += " prefix_v4 '%s'. prefix_v6: '%s'" + log_info(msg % info) + names = self.__generate_names(deployment_id, community_value) + self.cfg_mgr.update() + cmds = [] + cmds += self.__update_prefix_list(self.V4, names['pl_v4'], prefixes_v4) + cmds += self.__update_prefix_list(self.V6, names['pl_v6'], prefixes_v6) + cmds += self.__update_community(names['community'], community_value) + cmds += self.__update_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) + cmds += self.__update_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) + if cmds: + rc = self.cfg_mgr.push_list(cmds) + rc = rc and self.__restart_peers(deployment_id) + log_debug("BGPAllowListMgr::__update_policy. The peers were updated: rc=%s" % rc) + else: + log_debug("BGPAllowListMgr::__update_policy. Nothing to update") + log_info("BGPAllowListMgr::Done") + + def __remove_policy(self, deployment_id, community_value): + """ + Remove "allow list" policy for given deployment_id and community_value + :param deployment_id: deployment id which policy will be removed + :param community_value: community value to match for the removed policy + """ + # remove all related entries from the configuration + # put default rule to the route-map + info = deployment_id, community_value + msg = "BGPAllowListMgr::Removing 'Allow list' policy." + msg += " deployment_id '%s'. community: '%s'" + log_info(msg % info) + + names = self.__generate_names(deployment_id, community_value) + self.cfg_mgr.update() + cmds = [] + cmds += self.__remove_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) + cmds += self.__remove_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) + cmds += self.__remove_prefix_list(self.V4, names['pl_v4']) + cmds += self.__remove_prefix_list(self.V6, names['pl_v6']) + cmds += self.__remove_community(names['community']) + if cmds: + rc = self.cfg_mgr.push_list(cmds) + rc = rc and self.__restart_peers(deployment_id) + log_debug("BGPAllowListMgr::__remove_policy. 'Allow list' policy was removed. rc:%s" % rc) + else: + log_debug("BGPAllowListMgr::__remove_policy. Nothing to remove") + log_info('BGPAllowListMgr::Done') + + @staticmethod + def __generate_names(deployment_id, community_value): + """ + Generate prefix-list names for a given peer_ip and community value + :param deployment_id: deployment_id for which we're going to filter prefixes + :param community_value: community, which we want to use to filter prefixes + :return: a dictionary with names + """ + if community_value == BGPAllowListMgr.EMPTY_COMMUNITY: + community_name = BGPAllowListMgr.EMPTY_COMMUNITY + else: + community_name = BGPAllowListMgr.COMMUNITY_NAME_TMPL % (deployment_id, community_value) + names = { + "pl_v4": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '4'), + "pl_v6": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '6'), + "rm_v4": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '4'), + "rm_v6": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '6'), + "community": community_name, + } + arguments = deployment_id, community_value, str(names) + log_debug("BGPAllowListMgr::__generate_names. deployment_id: %d, community: %s. names: %s" % arguments) + return names + + def __update_prefix_list(self, af, pl_name, allow_list): + """ + Create or update a prefix-list with name pl_name. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :param pl_name: prefix-list name + :param allow_list: prefix-list entries + :return: True if updating was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + constant_list = self.__get_constant_list(af) + allow_list = self.__to_prefix_list(allow_list) + log_debug("BGPAllowListMgr::__update_prefix_list. af='%s' prefix-list name=%s" % (af, pl_name)) + exist, correct = self.__is_prefix_list_valid(af, pl_name, allow_list, constant_list) + if correct: + log_debug("BGPAllowListMgr::__update_prefix_list. the prefix-list '%s' exists and correct" % pl_name) + return [] + family = self.__af_to_family(af) + cmds = [] + seq_no = 10 + if exist: + cmds.append('no %s prefix-list %s' % (family, pl_name)) + for entry in constant_list + allow_list: + cmds.append('%s prefix-list %s seq %d %s' % (family, pl_name, seq_no, entry)) + seq_no += 10 + return cmds + + def __remove_prefix_list(self, af, pl_name): + """ + Remove prefix-list in the address-family af. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :param pl_name: list of prefix-list names + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + log_debug("BGPAllowListMgr::__remove_prefix_lists. af='%s' pl_names='%s'" % (af, pl_name)) + exist, _ = self.__is_prefix_list_valid(af, pl_name, [], []) + if not exist: + log_debug("BGPAllowListMgr::__remove_prefix_lists: prefix_list '%s' not found" % pl_name) + return [] + family = self.__af_to_family(af) + return ["no %s prefix-list %s" % (family, pl_name)] + + def __is_prefix_list_valid(self, af, pl_name, allow_list, constant_list): + """ + Check that a prefix list exists and it has valid entries + :param af: address family of the checked prefix-list + :param pl_name: prefix-list name + :param allow_list: a prefix-list which must be a part of the valid prefix list + :param constant_list: a constant list which must be on top of each "allow" prefix list on the device + :return: a tuple. The first element of the tuple has True if the prefix-list exists, False otherwise, + The second element of the tuple has True if the prefix-list contains correct entries, False if not + """ + assert af == self.V4 or af == self.V6 + family = self.__af_to_family(af) + match_string = '%s prefix-list %s seq ' % (family, pl_name) + conf = self.cfg_mgr.get_text() + if not any(line.strip().startswith(match_string) for line in conf): + return False, False # if the prefix list is not exists, it is not correct + constant_set = set(constant_list) + allow_set = set(allow_list) + for line in conf: + if line.startswith(match_string): + found = line[len(match_string):].strip().split(' ') + rule = " ".join(found[1:]) + if rule in constant_set: + constant_set.discard(rule) + elif rule in allow_set: + if constant_set: + return True, False # Not everything from constant set is presented + else: + allow_set.discard(rule) + return True, len(allow_set) == 0 # allow_set should be presented all + + def __update_community(self, community_name, community_value): + """ + Update community for a peer + :param community_name: name of the community to update + :param community_value: community value for the peer + :return: True if operation was successful, False otherwise + """ + log_debug("BGPAllowListMgr::__update_community. community_name='%s' community='%s'" % (community_name, community_value)) + if community_value == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community + log_debug("BGPAllowListMgr::__update_community. Empty community. exiting") + return [] + cmds = [] + exists, found_community_value = self.__is_community_presented(community_name) + if exists: + if community_value == found_community_value: + log_debug("BGPAllowListMgr::__update_community. community '%s' is already presented" % community_name) + return [] + else: + msg = "BGPAllowListMgr::__update_community. " + msg += "community '%s' is already presented, but community value should be updated" % community_name + log_debug(msg) + cmds.append("no bgp community-list standard %s" % community_name) + cmds.append('bgp community-list standard %s permit %s' % (community_name, community_value)) + return cmds + + def __remove_community(self, community_name): + """ + Remove community for a peer + :param community_name: community value for the peer + :return: True if operation was successful, False otherwise + """ + log_debug("BGPAllowListMgr::__remove_community. community='%s'" % community_name) + if community_name == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community + log_debug("BGPAllowListMgr::__remove_community. There is nothing to remove in empty community") + return [] + exists, _ = self.__is_community_presented(community_name) + if not exists: + log_debug("BGPAllowListMgr::__remove_community. Community is already removed.") + return [] + return ['no bgp community-list standard %s' % community_name] + + def __is_community_presented(self, community_name): + """ + Return True if community for the peer_ip exists + :param community_name: community value for the peer + :return: A tuple. First element: True if operation was successful, False otherwise + Second element: community value if the first element is True no value otherwise + """ + log_debug("BGPAllowListMgr::__is_community_presented. community='%s'" % community_name) + match_string = 'bgp community-list standard %s permit ' % community_name + conf = self.cfg_mgr.get_text() + found = [line.strip() for line in conf if line.strip().startswith(match_string)] + if not found: + return False, None + community_value = found[0].replace(match_string, '') + return True, community_value + + def __update_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): + """ + Add or update a "Allow address" route-map entry with the parameters + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + info = af, route_map_name, allow_address_pl_name, community_name + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) + entries = self.__parse_allow_route_map_entries(af, route_map_name) + found, _ = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) + if found: + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. route-map='%s' is already found" % route_map_name) + return [] + seq_number = self.__find_next_seq_number(entries.keys(), community_name != self.EMPTY_COMMUNITY, route_map_name) + info = af, seq_number, allow_address_pl_name, community_name + out = "af='%s' seqno='%d' Allow pl='%s' cl='%s'" % info + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. %s" % out) + ip_version = "" if af == self.V4 else "v6" + cmds = [ + 'route-map %s permit %d' % (route_map_name, seq_number), + ' match ip%s address prefix-list %s' % (ip_version, allow_address_pl_name) + ] + if not community_name.endswith(self.EMPTY_COMMUNITY): + cmds.append(" match community %s" % community_name) + return cmds + + def __remove_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): + """ + Add or update a "Allow address" route-map entry with the parameters + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + info = af, route_map_name, allow_address_pl_name, community_name + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) + entries = self.__parse_allow_route_map_entries(af, route_map_name) + found, seq_number = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) + if not found: + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. Not found route-map '%s' entry" % allow_address_pl_name) + return [] + return ['no route-map %s permit %d' % (route_map_name, seq_number)] + + @staticmethod + def __find_route_map_entry(entries, allow_address_pl_name, community_name): + """ + Find route-map entry with given allow_address prefix list name and community name in the parsed route-map. + :param entries: entries of parsed route-map + :param allow_address_pl_name: name of the "allow address" prefix-list + :param community_name: name of the "allow address" community name + :return: a tuple. The first element of the tuple is True, if the route-map entry was found, False otherwise. + The second element of the tuple has a sequence number of the entry. + """ + for sequence_number, values in entries.items(): + if sequence_number == 65535: + continue + allow_list_presented = values['pl_allow_list'] == allow_address_pl_name + community_presented = values['community'] == community_name + if allow_list_presented and community_presented: + log_debug("BGPAllowListMgr::__find_route_map_entry. found route-map '%s' entry" % allow_address_pl_name) + return True, sequence_number + return False, None + + def __parse_allow_route_map_entries(self, af, route_map_name): + """ + Parse "Allow list" route-map entries. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: A tuple, First element: True if operation was successful, False otherwise + Second element: list of object with parsed route-map entries + """ + assert af == self.V4 or af == self.V6 + log_debug("BGPAllowListMgr::__parse_allow_route_map_entries. af='%s', rm='%s'" % (af, route_map_name)) + match_string = 'route-map %s permit ' % route_map_name + entries = {} + inside_route_map = False + route_map_seq_number = None + pl_allow_list_name = None + community_name = self.EMPTY_COMMUNITY + if af == self.V4: + match_pl_allow_list = 'match ip address prefix-list ' + else: # self.V6 + match_pl_allow_list = 'match ipv6 address prefix-list ' + match_community = 'match community ' + conf = self.cfg_mgr.get_text() + for line in conf + [""]: + if inside_route_map: + if line.strip().startswith(match_pl_allow_list): + pl_allow_list_name = line.strip()[len(match_pl_allow_list):] + continue + elif line.strip().startswith(match_community): + community_name = line.strip()[len(match_community):] + continue + else: + if pl_allow_list_name is not None: + entries[route_map_seq_number] = { + 'pl_allow_list': pl_allow_list_name, + 'community': community_name, + } + else: + if route_map_seq_number != 65535: + log_warn("BGPAllowListMgr::Found incomplete route-map '%s' entry. seq_no=%d" % (route_map_name, route_map_seq_number)) + inside_route_map = False + pl_allow_list_name = None + community_name = self.EMPTY_COMMUNITY + route_map_seq_number = None + if line.startswith(match_string): + found = line[len(match_string):] + assert found.isdigit() + route_map_seq_number = int(found) + inside_route_map = True + return entries + + @staticmethod + def __find_next_seq_number(seq_numbers, has_community, route_map_name): + """ + Find a next available "Allow list" route-map entry number + :param seq_numbers: a list of already used sequence numbers + :param has_community: True, if the route-map entry has community + :return: next available route-map sequence number + """ + used_sequence_numbers = set(seq_numbers) + sequence_number = None + if has_community: # put entries without communities after 29999 + start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_START + end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_END + else: + start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START + end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END + for i in range(start_seq, end_seq, 10): + if i not in used_sequence_numbers: + sequence_number = i + break + if sequence_number is None: + raise RuntimeError("No free sequence numbers for '%s'" % route_map_name) + info = sequence_number, "yes" if has_community else "no" + log_debug("BGPAllowListMgr::__find_next_seq_number '%d' has_community='%s'" % info) + return sequence_number + + def __extract_peer_group_names(self): + """ + Extract names of all peer-groups defined in the config + :return: list of peer-group names + """ + # Find all peer-groups entries + re_peer_group = re.compile(r'^\s*neighbor (\S+) peer-group$') + peer_groups = [] + for line in self.cfg_mgr.get_text(): + result = re_peer_group.match(line) + if result: + peer_groups.append(result.group(1)) + return peer_groups + + def __get_peer_group_to_route_map(self, peer_groups): + """ + Extract names of route-maps which is connected to peer-groups defines as peer_groups + :peer_groups: a list of peer-group names + :return: dictionary where key is a peer-group, value is a route-map name which is defined as route-map in + for the peer_group. + """ + pg_2_rm = {} + for pg in peer_groups: + re_peer_group_rm = re.compile(r'^\s*neighbor %s route-map (\S+) in$' % pg) + for line in self.cfg_mgr.get_text(): + result = re_peer_group_rm.match(line) + if result: + pg_2_rm[pg] = result.group(1) + break + return pg_2_rm + + def __get_route_map_calls(self, rms): + """ + Find mapping between route-maps and route-map call names, defined for the route-maps + :rms: a set with route-map names + :return: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map + """ + rm_2_call = {} + re_rm = re.compile(r'^route-map (\S+) permit \d+$') + re_call = re.compile(r'^\s*call (\S+)$') + inside_name = None + for line in self.cfg_mgr.get_text(): + if inside_name: + inside_result = re_call.match(line) + if inside_result: + rm_2_call[inside_name] = inside_result.group(1) + inside_name = None + continue + result = re_rm.match(line) + if not result: + continue + inside_name = None + if result.group(1) not in rms: + continue + inside_name = result.group(1) + return rm_2_call + + def __get_peer_group_to_restart(self, deployment_id, pg_2_rm, rm_2_call): + """ + Get peer_groups which are assigned to deployment_id + :deployment_id: deployment_id number + :pg_2_rm: a dictionary where key is a peer-group, value is a route-map name which is defined as route-map in + for the peer_group. + :rm_2_call: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map + """ + ret = set() + target_allow_list_prefix = 'ALLOW_LIST_DEPLOYMENT_ID_%d_V' % deployment_id + for peer_group, route_map in pg_2_rm.items(): + if route_map in rm_2_call: + if rm_2_call[route_map].startswith(target_allow_list_prefix): + ret.add(peer_group) + return list(ret) + + def __find_peer_group_by_deployment_id(self, deployment_id): + """ + Deduce peer-group names which are connected to devices with requested deployment_id + :param deployment_id: deployment_id number + :return: a list of peer-groups which a used by devices with requested deployment_id number + """ + self.cfg_mgr.update() + peer_groups = self.__extract_peer_group_names() + pg_2_rm = self.__get_peer_group_to_route_map(peer_groups) + rm_2_call = self.__get_route_map_calls(set(pg_2_rm.values())) + ret = self.__get_peer_group_to_restart(deployment_id, pg_2_rm, rm_2_call) + return list(ret) + + def __restart_peers(self, deployment_id): + """ + Restart peer-groups with requested deployment_id + :param deployment_id: deployment_id number + """ + log_info("BGPAllowListMgr::Restart peers with deployment_id=%d" % deployment_id) + peer_groups = self.__find_peer_group_by_deployment_id(deployment_id) + rv = True + if peer_groups: + for peer_group in peer_groups: + no_error, _, _ = run_command(["vtysh", "-c", "clear bgp peer-group %s soft in" % peer_group]) + rv = no_error == 0 and rv + else: + no_error, _, _ = run_command(["vtysh", "-c", "clear bgp * soft in"]) + rv = no_error == 0 + return rv + + def __get_enabled(self): + """ + Load enable/disabled property from constants + :return: True if enabled, False otherwise + """ + return 'bgp' in self.constants \ + and 'allow_list' in self.constants["bgp"] \ + and "enabled" in self.constants["bgp"]["allow_list"] \ + and self.constants["bgp"]["allow_list"]["enabled"] + + def __load_constant_lists(self): + """ + Load default prefix-list entries from constants.yml file + """ + if 'bgp' in self.constants and 'allow_list' in self.constants["bgp"] \ + and "default_pl_rules" in self.constants["bgp"]["allow_list"]: + obj = self.constants["bgp"]["allow_list"]["default_pl_rules"] + if "v4" in obj: + self.constants_v4 = obj["v4"] + else: + self.constants_v4 = [] + if "v6" in obj: + self.constants_v6 = obj["v6"] + else: + self.constants_v6 = [] + + def __get_constant_list(self, af): + """ + Return loaded default prefix-list entries bases on address family + :param af: address family + :return: default prefix-list entries + """ + if af == self.V4: + return self.constants_v4 + else: + return self.constants_v6 + + @staticmethod + def __to_prefix_list(allow_list): + """ + Convert "allow list" prefix list, to a prefix-list rules + :param allow_list: "allow list" prefix list + :return: prefix-list rules + """ + return ["permit %s ge %d" % (prefix, int(prefix.split("/")[1])+1) for prefix in allow_list] + + def __af_to_family(self, af): + """ + Convert address family into prefix list family + :param af: address family + :return: prefix list ip family + """ + return 'ip' if af == self.V4 else 'ipv6' diff --git a/src/sonic-bgpcfgd/app/config.py b/src/sonic-bgpcfgd/app/config.py index 26639fe75e89..a0c1329f832e 100644 --- a/src/sonic-bgpcfgd/app/config.py +++ b/src/sonic-bgpcfgd/app/config.py @@ -10,19 +10,33 @@ class ConfigMgr(object): """ The class represents frr configuration """ def __init__(self): self.current_config = None + self.current_config_raw = None def reset(self): """ Reset stored config """ self.current_config = None + self.current_config_raw = None def update(self): """ Read current config from FRR """ self.current_config = None + self.current_config_raw = None ret_code, out, err = run_command(["vtysh", "-c", "show running-config"]) if ret_code != 0: + # FIXME: should we throw exception here? log_crit("can't update running config: rc=%d out='%s' err='%s'" % (ret_code, out, err)) return - self.current_config = self.to_canonical(out) + text = [] + for line in out.split('\n'): + if line.lstrip().startswith('!'): + continue + text.append(line) + text += [" "] # Add empty line to have something to work on, if there is no text + self.current_config_raw = text + self.current_config = self.to_canonical(out) # FIXME: use test as an input + + def push_list(self, cmdlist): + return self.push("\n".join(cmdlist)) def push(self, cmd): """ @@ -51,8 +65,12 @@ def write(self, cmd): log_err("ConfigMgr::push(): can't push configuration '%s', rc='%d', stdout='%s', stderr='%s'" % err_tuple) if ret_code == 0: self.current_config = None # invalidate config + self.current_config_raw = None return ret_code == 0 + def get_text(self): + return self.current_config_raw + @staticmethod def to_canonical(raw_config): """ diff --git a/src/sonic-bgpcfgd/app/directory.py b/src/sonic-bgpcfgd/app/directory.py new file mode 100644 index 000000000000..d27ec64256e3 --- /dev/null +++ b/src/sonic-bgpcfgd/app/directory.py @@ -0,0 +1,159 @@ +from collections import defaultdict + +from app.log import log_err + + +class Directory(object): + """ This class stores values and notifies callbacks which were registered to be executed as soon + as some value is changed. This class works as DB cache mostly """ + def __init__(self): + self.data = defaultdict(dict) # storage. A key is a slot name, a value is a dictionary with data + self.notify = defaultdict(lambda: defaultdict(list)) # registered callbacks: slot -> path -> handlers[] + + @staticmethod + def get_slot_name(db, table): + """ Convert db, table pair into a slot name """ + return db + "__" + table + + def path_traverse(self, slot, path): + """ + Traverse a path in the storage. + If the path is an empty string, it returns a value as it is. + If the path is not an empty string, the method will traverse through the dictionary value. + Example: + self.data["key_1"] = { "abc": { "cde": { "fgh": "val_1", "ijk": "val_2" } } } + self.path_traverse("key_1", "abc/cde") will return True, { "fgh": "val_1", "ijk": "val_2" } + :param slot: storage key + :param path: storage path as a string where each internal key is separated by '/' + :return: a pair: True if the path was found, object if it was found + """ + if slot not in self.data: + return False, None + elif path == '': + return True, self.data[slot] + d = self.data[slot] + for p in path.split("/"): + if p not in d: + return False, None + d = d[p] + return True, d + + def path_exist(self, db, table, path): + """ + Check if the path exists in the storage + :param db: db name + :param table: table name + :param path: requested path + :return: True if the path is available, False otherwise + """ + slot = self.get_slot_name(db, table) + return self.path_traverse(slot, path)[0] + + def get_path(self, db, table, path): + """ + Return the requested path from the storage + :param db: db name + :param table: table name + :param path: requested path + :return: object if the path was found, None otherwise + """ + slot = self.get_slot_name(db, table) + return self.path_traverse(slot, path)[1] + + def put(self, db, table, key, value): + """ + Put information into the storage. Notify handlers which are dependant to the information + :param db: db name + :param table: table name + :param key: key to change + :param value: value to put + :return: + """ + slot = self.get_slot_name(db, table) + self.data[slot][key] = value + if slot in self.notify: + for path in self.notify[slot].keys(): + if self.path_exist(db, table, path): + for handler in self.notify[slot][path]: + handler() + + def get(self, db, table, key): + """ + Get a value from the storage + :param db: db name + :param table: table name + :param key: ket to get + :return: value for the key + """ + slot = self.get_slot_name(db, table) + return self.data[slot][key] + + def get_slot(self, db, table): + """ + Get an object from the storage + :param db: db name + :param table: table name + :return: object for the slot + """ + slot = self.get_slot_name(db, table) + return self.data[slot] + + def remove(self, db, table, key): + """ + Remove a value from the storage + :param db: db name + :param table: table name + :param key: key to remove + """ + slot = self.get_slot_name(db, table) + if slot in self.data: + if key in self.data[slot]: + del self.data[slot][key] + else: + log_err("Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) + else: + log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) + + def remove_slot(self, db, table): + """ + Remove an object from the storage + :param db: db name + :param table: table name + """ + slot = self.get_slot_name(db, table) + if slot in self.data: + del self.data[slot] + else: + log_err("Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) + + def available(self, db, table): + """ + Check if the table is available + :param db: db name + :param table: table name + :return: True if the slot is available, False if not + """ + slot = self.get_slot_name(db, table) + return slot in self.data + + def available_deps(self, deps): + """ + Check if all items from the deps list is available in the storage + :param deps: list of dependencies + :return: True if all dependencies are presented, False otherwise + """ + res = True + for db, table, path in deps: + res = res and self.path_exist(db, table, path) + return res + + def subscribe(self, deps, handler): + """ + Subscribe the handler to be run as soon as all dependencies are presented + :param deps: + :param handler: + :return: + """ + for db, table, path in deps: + slot = self.get_slot_name(db, table) + self.notify[slot][path].append(handler) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/manager.py b/src/sonic-bgpcfgd/app/manager.py new file mode 100644 index 000000000000..ba45029b5120 --- /dev/null +++ b/src/sonic-bgpcfgd/app/manager.py @@ -0,0 +1,71 @@ +from swsscommon import swsscommon + +from app.log import log_debug, log_err + + +class Manager(object): + """ This class represents a SONiC DB table """ + def __init__(self, common_objs, deps, database, table_name): + """ + Initialize class + :param common_objs: common object dictionary + :param deps: dependencies list + :param database: database name + :param table_name: table name + """ + self.directory = common_objs['directory'] + self.cfg_mgr = common_objs['cfg_mgr'] + self.constants = common_objs['constants'] + self.deps = deps + self.db_name = database + self.table_name = table_name + self.set_queue = [] + self.directory.subscribe(deps, self.on_deps_change) # subscribe this class method on directory changes + + def get_database(self): + """ Return associated database """ + return self.db_name + + def get_table_name(self): + """ Return associated table name""" + return self.table_name + + def handler(self, key, op, data): + """ + This method is executed on each add/remove event on the table. + :param key: key of the table entry + :param op: operation on the table entry. Could be either 'SET' or 'DEL' + :param data: associated data of the event. Empty for 'DEL' operation. + """ + if op == swsscommon.SET_COMMAND: + if self.directory.available_deps(self.deps): # all required dependencies are set in the Directory? + res = self.set_handler(key, data) + if not res: # set handler returned False, which means it is not ready to process is. Save it for later. + log_debug("'SET' handler returned NOT_READY for the Manager: %s" % self.__class__) + self.set_queue.append((key, data)) + else: + log_debug("Not all dependencies are met for the Manager: %s" % self.__class__) + self.set_queue.append((key, data)) + elif op == swsscommon.DEL_COMMAND: + self.del_handler(key) + else: + log_err("Invalid operation '%s' for key '%s'" % (op, key)) + + def on_deps_change(self): + """ This method is being executed on every dependency change """ + if not self.directory.available_deps(self.deps): + return + new_queue = [] + for key, data in self.set_queue: + res = self.set_handler(key, data) + if not res: + new_queue.append((key, data)) + self.set_queue = new_queue + + def set_handler(self, key, data): + """ Placeholder for 'SET' command """ + log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) + + def del_handler(self, key): + """ Placeholder for 'DEL' command """ + log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/vars.py b/src/sonic-bgpcfgd/app/vars.py index 11377fc87f93..18bee5578e25 100644 --- a/src/sonic-bgpcfgd/app/vars.py +++ b/src/sonic-bgpcfgd/app/vars.py @@ -1 +1 @@ -g_debug = False +g_debug = True # FIXME: read from env variable, or from constants diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd index 6f52ac1626e6..419fd41fb4be 100755 --- a/src/sonic-bgpcfgd/bgpcfgd +++ b/src/sonic-bgpcfgd/bgpcfgd @@ -15,10 +15,13 @@ import jinja2 import netaddr from swsscommon import swsscommon +from app.directory import Directory +from app.manager import Manager from app.vars import g_debug from app.log import log_debug, log_notice, log_info, log_warn, log_err, log_crit from app.template import TemplateFabric from app.config import ConfigMgr +from app.allow_list import BGPAllowListMgr from app.util import run_command g_run = True @@ -846,7 +849,7 @@ def wait_for_daemons(daemons, seconds): def read_constants(): """ Read file with constants values from /etc/sonic/constants.yml """ with open('/etc/sonic/constants.yml') as fp: - content = yaml.load(fp) + content = yaml.load(fp) # FIXME: , Loader=yaml.FullLoader) if "constants" not in content: log_crit("/etc/sonic/constants.yml doesn't have 'constants' key") raise Exception("/etc/sonic/constants.yml doesn't have 'constants' key") @@ -878,6 +881,8 @@ def main(): BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), + # AllowList Managers + BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), ] runner = Runner() for mgr in managers: diff --git a/src/sonic-bgpcfgd/pytest.ini b/src/sonic-bgpcfgd/pytest.ini new file mode 100644 index 000000000000..639ceb636af9 --- /dev/null +++ b/src/sonic-bgpcfgd/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = --cov=app --cov-report term diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index 29d441e09a66..fc0839dff7fc 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -16,5 +16,6 @@ ] }, install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], - setup_requires=['pytest-runner', 'pytest'], + setup_requires=['pytest-runner'], + test_requires=['pytest', 'pytest-cov'], ) diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json index 148456fe960f..08f1eef63267 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json @@ -4,5 +4,14 @@ "sub_role": "BackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32" -} \ No newline at end of file + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": true, + "default_action": "permit", + "drop_community": "12345:12345" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json index 53bf5572eff3..958c9b0fbd4b 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json @@ -4,5 +4,12 @@ "sub_role": "NotBackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32" -} \ No newline at end of file + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": false + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json new file mode 100644 index 000000000000..669810960c92 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json @@ -0,0 +1,17 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": true, + "default_action": "deny", + "drop_community": "12345:12345" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf index 1e3288b9a7da..9e6c32b17ead 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf @@ -1,6 +1,20 @@ ! ! template: bgpd/templates/general/policies.conf.j2 ! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community 12345:12345 additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community 12345:12345 additive +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf new file mode 100644 index 000000000000..6e0389fc1886 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf @@ -0,0 +1,39 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community no-export additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community no-export additive +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! +route-map FROM_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V4 permit 100 +! +route-map FROM_BGP_PEER_V6 permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +route-map FROM_BGP_PEER_V4_INT permit 2 + set originator-id 10.10.10.10 +! +route-map FROM_BGP_PEER_V6_INT permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6_INT permit 2 + set originator-id 10.10.10.10 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/test_allow_list.py b/src/sonic-bgpcfgd/tests/test_allow_list.py new file mode 100644 index 000000000000..f3cf2f534aaa --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_allow_list.py @@ -0,0 +1,482 @@ +from app.directory import Directory +from app.template import TemplateFabric +import app +from mock import MagicMock, patch + +swsscommon_module_mock = MagicMock() + +global_constants = { + "bgp": { + "allow_list": { + "enabled": True, + "default_pl_rules": { + "v4": [ "deny 0.0.0.0/0 le 17" ], + "v6": [ + "deny 0::/0 le 59", + "deny 0::/0 ge 65" + ] + } + } + } +} + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def set_del_test(op, args, currect_config, expected_config): + from app.allow_list import BGPAllowListMgr + set_del_test.push_list_called = False + def push_list(args): + set_del_test.push_list_called = True + assert args == expected_config + return True + # + app.allow_list.run_command = lambda cmd: (0, "", "") + # + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.push_list = push_list + cfg_mgr.get_text.return_value = currect_config + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + if op == "SET": + mgr.set_handler(*args) + elif op == "DEL": + mgr.del_handler(*args) + else: + assert False, "Wrong operation" + if expected_config: + assert set_del_test.push_list_called, "cfg_mgr.push_list wasn't called" + else: + assert not set_del_test.push_list_called, "cfg_mgr.push_list was called" + +def test_set_handler_with_community(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + }), + [], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) + +def test_set_handler_no_community(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }), + [], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + ] + ) + +def test_del_handler_with_community(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'no bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) + +def test_del_handler_no_community(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + " " + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + ] + ) + +def test_set_handler_with_community_data_is_already_presented(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [] + ) + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test_set_handler_no_community_data_is_already_presented(): + from app.allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.get_text.return_value = [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + "" + ] + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mgr.set_handler("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }) + assert not cfg_mgr.push_list.called, "cfg_mgr.push_list was called, but it shouldn't have been" + +def test_del_handler_with_community_no_data(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [""], + [] + ) + +def test_del_handler_no_community_no_data(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [""], + [] + ) + +def test_set_handler_with_community_update_prefixes_add(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16,80.90.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64,fc02::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [ + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 40 permit 80.90.0.0/16 ge 17', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 50 permit fc02::/64 ge 65', + ] + ) + +def test_set_handler_no_community_update_prefixes_add(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16,80.90.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64,fc02::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + "" + ], + [ + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 40 permit 80.90.0.0/16 ge 17', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 50 permit fc02::/64 ge 65', + ] + ) + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___set_handler_validate(): + from app.allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + data = { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + } + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", None) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID1|5|1010:2020", data) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|z|1010:2020", data) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "20.20.30.0/24,40.50.0.0/16", + }) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "fc01:20::/64,fc01:30::/64", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }) + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___find_peer_group_by_deployment_id(): + from app.allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.get_text.return_value = [ + 'router bgp 64601', + ' neighbor BGPSLBPassive peer-group', + ' neighbor BGPSLBPassive remote-as 65432', + ' neighbor BGPSLBPassive passive', + ' neighbor BGPSLBPassive ebgp-multihop 255', + ' neighbor BGPSLBPassive update-source 10.1.0.32', + ' neighbor PEER_V4 peer-group', + ' neighbor PEER_V4_INT peer-group', + ' neighbor PEER_V6 peer-group', + ' neighbor PEER_V6_INT peer-group', + ' neighbor 10.0.0.1 remote-as 64802', + ' neighbor 10.0.0.1 peer-group PEER_V4', + ' neighbor 10.0.0.1 description ARISTA01T1', + ' neighbor 10.0.0.1 timers 3 10', + ' neighbor fc00::2 remote-as 64802', + ' neighbor fc00::2 peer-group PEER_V6', + ' neighbor fc00::2 description ARISTA01T1', + ' neighbor fc00::2 timers 3 10', + ' address-family ipv4 unicast', + ' neighbor BGPSLBPassive activate', + ' neighbor BGPSLBPassive soft-reconfiguration inbound', + ' neighbor BGPSLBPassive route-map FROM_BGP_SPEAKER in', + ' neighbor BGPSLBPassive route-map TO_BGP_SPEAKER out', + ' neighbor PEER_V4 soft-reconfiguration inbound', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4 route-map TO_BGP_PEER_V4 out', + ' neighbor PEER_V4_INT soft-reconfiguration inbound', + ' neighbor PEER_V4_INT allowas-in 1', + ' neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out', + ' neighbor 10.0.0.1 activate', + ' exit-address-family', + ' address-family ipv6 unicast', + ' neighbor BGPSLBPassive activate', + ' neighbor PEER_V6 soft-reconfiguration inbound', + ' neighbor PEER_V6 allowas-in 1', + ' neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6 route-map TO_BGP_PEER_V6 out', + ' neighbor PEER_V6_INT soft-reconfiguration inbound', + ' neighbor PEER_V6_INT allowas-in 1', + ' neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out', + ' neighbor fc00::2 activate', + ' exit-address-family', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 10', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535', + ' set community 5060:12345 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 10', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535', + ' set community 5060:12345 additive', + 'route-map FROM_BGP_PEER_V4 permit 100', + 'route-map FROM_BGP_PEER_V4 permit 2', + ' call ALLOW_LIST_DEPLOYMENT_ID_0_V4', + ' on-match next', + 'route-map FROM_BGP_PEER_V6 permit 1', + ' set ipv6 next-hop prefer-global ', + 'route-map FROM_BGP_PEER_V6 permit 100', + 'route-map FROM_BGP_PEER_V6 permit 2', + ' call ALLOW_LIST_DEPLOYMENT_ID_0_V6', + ' on-match next', + 'route-map FROM_BGP_SPEAKER permit 10', + 'route-map RM_SET_SRC permit 10', + ' set src 10.1.0.32', + 'route-map RM_SET_SRC6 permit 10', + ' set src FC00:1::32', + 'route-map TO_BGP_PEER_V4 permit 100', + 'route-map TO_BGP_PEER_V6 permit 100', + 'route-map TO_BGP_SPEAKER deny 1', + ] + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + values = mgr._BGPAllowListMgr__find_peer_group_by_deployment_id(0) + assert values == ['PEER_V4_INT', 'PEER_V6_INT', 'PEER_V6', 'PEER_V4'] + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___restart_peers_found_deployment_id(): + from app.allow_list import BGPAllowListMgr + test___restart_peers_found_deployment_id.run_command_counter = 0 + def run_command(cmd): + output = [ + ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_1 soft in'], + ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_2 soft in'], + ] + desired_value = output[test___restart_peers_found_deployment_id.run_command_counter] + assert cmd == desired_value + test___restart_peers_found_deployment_id.run_command_counter += 1 + return 0, "", "" + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') + mocked.return_value = ["BGP_TEST_PEER_GROUP_1", "BGP_TEST_PEER_GROUP_2"] + mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked + app.allow_list.run_command = run_command + rc = mgr._BGPAllowListMgr__restart_peers(5) + assert rc + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___restart_peers_not_found_deployment_id(): + from app.allow_list import BGPAllowListMgr + def run_command(cmd): + assert cmd == ['vtysh', '-c', 'clear bgp * soft in'] + return 0, "", "" + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') + mocked.return_value = [] + mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked + app.allow_list.run_command = run_command + rc = mgr._BGPAllowListMgr__restart_peers(5) + assert rc + +# FIXME: more testcases for coverage diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py index bc6d01cdb536..686b1ade65e1 100644 --- a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -77,21 +77,30 @@ def extract_rm_from_peer_group(path, peer_group_name): return list(rm_set) def check_routemap_in_file(filename, route_map_name): - route_map_re = re.compile(r'^route-map\s+%s\s+(\S+)' % route_map_name) + route_map_re = re.compile(r'^route-map\s+%s\s+permit\s+(\d+)' % route_map_name) set_re = re.compile(r'set ipv6 next-hop prefer-global') with open(filename) as fp: lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] - found_first_entry = False + found_entry = False + found_seq_no = None + route_map_entries = {} for line in lines: - err_msg = "route-map %s doesn't have mandatory 'set ipv6 next-hop prefer-global' entry as the first rule" % route_map_name - assert not (found_first_entry and line.startswith("route-map")), err_msg - if found_first_entry and set_re.match(line): - break # We're good + if found_entry: + route_map_entries[found_seq_no] = set_re.match(line) is not None + found_entry = False + found_seq_no = None if route_map_re.match(line): - err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name - assert route_map_re.match(line).group(1) == 'permit', err_msg - found_first_entry = True - return found_first_entry + found_seq_no = None + seq_n_txt = route_map_re.match(line).group(1) + assert seq_n_txt.isdigit(), "wrong sequence number for line '%s'" % line + found_seq_no = int(seq_n_txt) + assert found_seq_no not in route_map_entries, "Route-map has duplicate entries: %s - %d" % (route_map_name, found_seq_no) + found_entry = True + results = [route_map_entries[seq] for seq in sorted(route_map_entries.keys())] + if (len(results)): + err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name + assert results[0], err_msg + return len(results) > 0 def check_routemap(path, route_map_name): result_files = load_results(path, "policies.conf") diff --git a/src/sonic-bgpcfgd/tests/util.py b/src/sonic-bgpcfgd/tests/util.py index 0bc12b060aec..aa6c62a56b5f 100644 --- a/src/sonic-bgpcfgd/tests/util.py +++ b/src/sonic-bgpcfgd/tests/util.py @@ -5,7 +5,7 @@ def load_constants(): with open(CONSTANTS_PATH) as f: - data = yaml.load(f) + data = yaml.load(f) # FIXME" , Loader=yaml.FullLoader) result = {} assert "constants" in data, "'constants' key not found in constants.yml" assert "bgp" in data["constants"], "'bgp' key not found in constants.yml" @@ -13,4 +13,4 @@ def load_constants(): for name, value in data["constants"]["bgp"]["peers"].items(): assert "template_dir" in value, "'template_dir' key not found for peer '%s'" % name result[name] = value["template_dir"] - return result \ No newline at end of file + return result From 689487457e649448bc7d77173d679b8ce56a7f90 Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Sat, 3 Oct 2020 03:14:03 -0700 Subject: [PATCH 1202/1427] [Telemetry] remove unused mount from telemetry docker make file (#5536) --- rules/docker-telemetry.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index c42e15e24430..15f90c74c810 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -27,7 +27,6 @@ $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry $(DOCKER_TELEMETRY)_RUN_OPT += --privileged -t $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TELEMETRY)_RUN_OPT += -v /var/run/dbus:/var/run/dbus:rw -$(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" $(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_TELEMETRY)_BASE_IMAGE_FILES += monit_telemetry:/etc/monit/conf.d From 32a517f583320e7c404d0f739470d025298dc015 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Sat, 3 Oct 2020 09:47:51 -0700 Subject: [PATCH 1203/1427] [sonic-swss] Update sonic-swss submodule (#5533) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index be51ebc533cb..e4dfb3756e43 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit be51ebc533cbe92a885c584b4611ffc92d10ea36 +Subproject commit e4dfb3756e4332f90faed3ee0f82c9ad05ba38ce From 40623681bb5e4244f53f44af1568703e1c8e7077 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sun, 4 Oct 2020 01:17:13 +0800 Subject: [PATCH 1204/1427] [Mellanox] Fix truncated manufacture date returned from platform API (#5473) The manufacture date returned from platform API was truncated, time is not included. Revise the regular expression used for matching. --- platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py index 413388d20385..7673c9130f48 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py @@ -109,7 +109,7 @@ def _load_eeprom(self): for line in lines: try: - match = re.search('(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + match = re.search('(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+[\s]*[\S]*)', line) if match is not None: idx = match.group(1) value = match.group(3).rstrip('\0') From e92061cde9846ad36cc65d43f3efd3305d646673 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Sun, 4 Oct 2020 01:28:44 +0800 Subject: [PATCH 1205/1427] [Mellanox] Update dynamic minimum table for 4700, 3420 and 4600C (#5388) Update dynamic minimum fan speed table according to data provided by thermal team. --- .../mlnx-platform-api/sonic_platform/device_data.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py index fd3c7ad50e23..7b86f7db9dfc 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py @@ -170,8 +170,8 @@ 'x86_64-mlnx_msn4700-r0': { 'thermal': { 'minimum_table': { - "unk_trust": {"-127:120":16}, - "unk_untrust": {"-127:120":16}, + "unk_trust": {"-127:35":14, "36:120":15}, + "unk_untrust": {"-127:35":14, "36:120":15}, } }, 'fans': { @@ -191,8 +191,8 @@ 'x86_64-mlnx_msn3420-r0': { 'thermal': { 'minimum_table': { - "unk_trust": {"-127:120":16}, - "unk_untrust": {"-127:120":16}, + "unk_trust": {"-127:120":12}, + "unk_untrust": {"-127:25":12, "26:35":13, "36:40":14, "41:120":16}, } }, 'fans': { @@ -212,8 +212,8 @@ 'x86_64-mlnx_msn4600c-r0': { 'thermal': { 'minimum_table': { - "unk_trust": {"-127:120":16}, - "unk_untrust": {"-127:120":16}, + "unk_trust": {"-127:40":12, "41:120":13}, + "unk_untrust": {"-127:5":12, "6:20":13, "21:30":14, "31:35":15, "36:40":16, "41:120":17}, } }, 'fans': { From dbea3bbfd78a438a8bf88f05442d60e010e77373 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Sat, 3 Oct 2020 23:46:21 +0300 Subject: [PATCH 1206/1427] BFN platform API 2.0 support (#4766) Added barefoot platform api 2.0 support Signed-off-by: Volodymyr Boyko --- .../debian/rules | 21 +- .../setup.py | 31 + .../sonic_platform/__init__.py | 2 + .../sonic_platform/chassis.py | 126 + .../sonic_platform/eeprom.py | 151 + .../sonic_platform/logging.conf | 17 + .../sonic_platform/platform.py | 21 + .../sonic_platform/platform_thrift_client.py | 37 + .../sonic_platform/pltfm_mgr_rpc/__init__.py | 1 + .../pltfm_mgr_rpc/pltfm_mgr_rpc.py | 2924 +++++++++++++++++ .../sonic_platform/pltfm_mgr_rpc/ttypes.py | 1060 ++++++ .../sonic_platform/psu.py | 58 + .../sonic_platform/sfp.py | 250 ++ .../debian/rules | 11 + .../setup.py | 1 + .../sonic_platform | 1 + .../sonic-platform-modules-bfn/debian/rules | 13 + .../sonic-platform-modules-bfn/setup.py | 1 + .../sonic-platform-modules-bfn/sonic_platform | 1 + 19 files changed, 4722 insertions(+), 5 deletions(-) create mode 100755 platform/barefoot/sonic-platform-modules-bfn-montara/setup.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/logging.conf create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/__init__.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py create mode 120000 platform/barefoot/sonic-platform-modules-bfn-newport/setup.py create mode 120000 platform/barefoot/sonic-platform-modules-bfn-newport/sonic_platform create mode 120000 platform/barefoot/sonic-platform-modules-bfn/setup.py create mode 120000 platform/barefoot/sonic-platform-modules-bfn/sonic_platform diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules index 7b430e9bd284..bf5a4c9a50fe 100755 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules @@ -1,25 +1,36 @@ #!/usr/bin/make -f +PLATFORM = x86_64-accton_wedge100bf_32x-r0 PACKAGE_NAME := sonic-platform-modules-bfn-montara SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs +BUILD_DIR := $(shell pwd)/build +WHEEL_BUILD_DIR := $(BUILD_DIR)/wheel PLUGINS_DIR := $(shell pwd)/plugins %: dh $@ +override_dh_auto_build: + set -e + python2.7 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + python3 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + set +e + override_dh_auto_install: dh_installdirs -p$(PACKAGE_NAME) usr/local/bin cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ - dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/x86_64-accton_wedge100bf_32x-r0/plugins - cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/x86_64-accton_wedge100bf_32x-r0/plugins/ + dh_installdirs -p$(PACKAGE_NAME) /usr/share/sonic/device/${PLATFORM}/ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/${PLATFORM}/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/${PLATFORM}/plugins + cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/${PLATFORM}/plugins/ override_dh_usrlocal: -override_dh_pysupport: - override_dh_clean: + rm -fr $(WHEEL_BUILD_DIR) + rm -fr *.egg-info + rm -fr $(BUILD) dh_clean - diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/setup.py b/platform/barefoot/sonic-platform-modules-bfn-montara/setup.py new file mode 100755 index 000000000000..fc14c94ac4a0 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/setup.py @@ -0,0 +1,31 @@ +from setuptools import setup + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation', + license='Apache 2.0', + author='SONiC Team', + author_email='', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Barefoot', + maintainer_email='', + packages=[ + 'sonic_platform', + 'sonic_platform/pltfm_mgr_rpc' + ], + package_data = {'sonic_platform':['logging.conf']}, + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py new file mode 100644 index 000000000000..ef4108ee54e5 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp'] +import platform diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py new file mode 100644 index 000000000000..36a921d539f5 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.psu import Psu + from eeprom import Eeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Chassis(ChassisBase): + """ + Platform-specific Chassis class + """ + def __init__(self): + ChassisBase.__init__(self) + SFP_PORT_END = Sfp.port_end() + PORTS_IN_BLOCK = (SFP_PORT_END + 1) + MAX_PSU = Psu.get_num_psus() + + self._eeprom = Eeprom() + + for index in range(0, PORTS_IN_BLOCK): + sfp_node = Sfp(index) + self._sfp_list.append(sfp_node) + + for i in range(MAX_PSU): + psu = Psu(i) + self._psu_list.append(psu) + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_str() + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 1. + For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list)-1)) + return sfp + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.system_eeprom_info() + + def get_change_event(self, timeout=0): + ready, event_sfp = Sfp.get_transceiver_change_event(timeout) + return ready, { 'sfp': event_sfp } if ready else {} diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py new file mode 100644 index 000000000000..a548e9364715 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py @@ -0,0 +1,151 @@ +#!/usr/bin/python + + +try: + import time + import os + import sys + import errno + import datetime + import logging + import logging.config + import yaml + + sys.path.append(os.path.dirname(__file__)) + + from cStringIO import StringIO + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + + from .platform_thrift_client import ThriftClient +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +eeprom_default_dict = { + "prod_name" : ("Product Name", "0x21", 12), + "odm_pcba_part_num" : ("Part Number", "0x22", 13), + "prod_ser_num" : ("Serial Number", "0x23", 12), + "ext_mac_addr" : ("Extended MAC Address Base", "0x24", 12), + "sys_mfg_date" : ("System Manufacturing Date", "0x25", 4), + "prod_ver" : ("Product Version", "0x26", 1), + "ext_mac_addr_size" : ("Extende MAC Address Size", "0x2A", 2), + "sys_mfger" : ("Manufacturer", "0x2B", 8) +} + +eeprom_dict = { "version" : ("Version", None, 0), + "pcb_mfger" : ("PCB Manufacturer", "0x01", 8), + "prod_ser_num" : ("Serial Number", "0x23", 12), + "bfn_pcba_part_num" : ("Switch PCBA Part Number", "0x02", 12), + "odm_pcba_part_num" : ("Part Number", "0x22", 13), + "bfn_pcbb_part_num" : ("Switch PCBB Part Number", "0x04", 12), + "sys_asm_part_num" : ("System Assembly Part Number", "0x05", 12), + "prod_state" : ("Product Production State", "0x06", 1), + "location" : ("EEPROM Location of Fabric", "0x07", 8), + "ext_mac_addr_size" : ("Extende MAC Address Size", "0x08", 2), + "sys_mfg_date" : ("System Manufacturing Date", "0x25", 4), + "prod_name" : ("Product Name", "0x21", 12), + "prod_ver" : ("Product Version", "0x26", 1), + "prod_part_num" : ("Product Part Number", "0x09", 8), + "sys_mfger" : ("Manufacturer", "0x2B", 8), + "assembled_at" : ("Assembled at", "0x08", 8), + "prod_ast_tag" : ("Product Asset Tag", "0x09", 12), + "loc_mac_addr" : ("Local MAC address", "0x0A", 12), + "odm_pcba_ser_num" : ("ODM PBCA Serial Number", "0x0B", 12), + "ext_mac_addr" : ("Extended MAC Address Base", "0x0C", 12), + "prod_sub_ver" : ("Product Sub Version", "0x0D", 1) + } + +product_dict = { "Montara" : "Wedge100BF-32X-O-AC-F-BF", + "Lower MAV" : "Wedge100BF-65X-O-AC-F-BF", + "Upper MAV" : "Wedge100BF-65X-O-AC-F-BF" + } + +EEPROM_SYMLINK = "/var/run/platform/eeprom/syseeprom" +EEPROM_STATUS = "/var/run/platform/eeprom/status" + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + RETRIES = 35 + + def __init__(self): + + with open(os.path.dirname(__file__) + "/logging.conf", 'r') as f: + config_dict = yaml.load(f, yaml.SafeLoader) + logging.config.dictConfig(config_dict) + + if not os.path.exists(os.path.dirname(EEPROM_SYMLINK)): + try: + os.makedirs(os.path.dirname(EEPROM_SYMLINK)) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + open(EEPROM_SYMLINK, 'a').close() + f = open(EEPROM_STATUS, 'w') + f.write("initializing..") + f.close() + + self.eeprom_path = EEPROM_SYMLINK + super(Eeprom, self).__init__(self.eeprom_path, 0, EEPROM_STATUS, True) + + for attempt in range(self.RETRIES): + if self.eeprom_init(): + break + if attempt + 1 == self.RETRIES: + raise RuntimeError("eeprom.py: Initialization failed") + time.sleep(1) + + def eeprom_init(self): + try: + with ThriftClient() as client: + self.eeprom = client.pltfm_mgr.pltfm_mgr_sys_eeprom_get() + except Exception: + return False + + f = open(EEPROM_STATUS, 'w') + f.write("ok") + f.close() + + eeprom_params = "" + for attr, val in self.eeprom.__dict__.iteritems(): + if val is None: + continue + + elem = eeprom_default_dict.get(attr) + if elem is None: + continue + + if isinstance(val, basestring): + value = val.replace('\0', '') + else: + value = str(val) + + if attr == "sys_mfg_date": + value = datetime.datetime.strptime(value, '%m-%d-%y').strftime('%m/%d/%Y 00:00:00') + + product = product_dict.get(value) + if product is not None: + value = product + if len(eeprom_params) > 0: + eeprom_params += "," + eeprom_params += "{0:s}={1:s}".format(elem[1], value) + + orig_stdout = sys.stdout + sys.stdout = StringIO() + new_e = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params]) + sys.stdout = orig_stdout + eeprom_base.EepromDecoder.write_eeprom(self, new_e) + + return True + + def serial_number_str(self): + return self.eeprom.prod_ser_num + + def system_eeprom_info(self): + return self.eeprom.__dict__ + + def get_base_mac(self): + return self.eeprom.ext_mac_addr + + def part_number_str(self): + return self.eeprom.prod_part_num diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/logging.conf b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/logging.conf new file mode 100644 index 000000000000..d7fd84773404 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/logging.conf @@ -0,0 +1,17 @@ +version: 1 +disable_existing_loggers: False + +formatters: + simple: + format: '%(asctime)s %(name)-30s %(levelname)-7s %(message)s' + +handlers: + file: + class: logging.handlers.RotatingFileHandler + formatter: simple + filename: /var/log/platform.log + +root: + level: ERROR + handlers: + - file diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform.py new file mode 100644 index 000000000000..ebc68a895362 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py new file mode 100644 index 000000000000..06afe8e962ae --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +try: + import os + import sys + import importlib + + sys.path.append(os.path.dirname(__file__)) + + from thrift.transport import TSocket + from thrift.transport import TTransport + from thrift.protocol import TBinaryProtocol + from thrift.protocol import TMultiplexedProtocol +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +THRIFT_SERVER = 'localhost' + +class ThriftClient(object): + def open(self): + self.transport = TSocket.TSocket(THRIFT_SERVER, 9090) + + self.transport = TTransport.TBufferedTransport(self.transport) + bprotocol = TBinaryProtocol.TBinaryProtocol(self.transport) + + pltfm_mgr_client_module = importlib.import_module(".".join(["pltfm_mgr_rpc", "pltfm_mgr_rpc"])) + pltfm_mgr_protocol = TMultiplexedProtocol.TMultiplexedProtocol(bprotocol, "pltfm_mgr_rpc") + self.pltfm_mgr = pltfm_mgr_client_module.Client(pltfm_mgr_protocol) + + self.transport.open() + return self + def close(self): + self.transport.close() + def __enter__(self): + return self.open() + def __exit__(self, exc_type, exc_value, tb): + self.close() diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/__init__.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/__init__.py new file mode 100644 index 000000000000..414c3d6389c5 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/__init__.py @@ -0,0 +1 @@ +__all__ = ['ttypes', 'pltfm_mgr_rpc'] diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py new file mode 100644 index 000000000000..b256b6285fc3 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py @@ -0,0 +1,2924 @@ +# +# Autogenerated by Thrift Compiler (0.10.0) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# +# options string: py +# + +from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException +from thrift.protocol.TProtocol import TProtocolException +import sys +import logging +from .ttypes import * +from thrift.Thrift import TProcessor +from thrift.transport import TTransport + + +class Iface(object): + def pltfm_mgr_dummy(self, device): + """ + Parameters: + - device + """ + pass + + def pltfm_mgr_sys_tmp_get(self): + pass + + def pltfm_mgr_sys_eeprom_get(self): + pass + + def pltfm_mgr_pwr_supply_present_get(self, ps_num): + """ + Parameters: + - ps_num + """ + pass + + def pltfm_mgr_pwr_supply_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + pass + + def pltfm_mgr_pwr_rail_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + pass + + def pltfm_mgr_fan_speed_set(self, fan_num, percent): + """ + Parameters: + - fan_num + - percent + """ + pass + + def pltfm_mgr_fan_info_get(self, fan_num): + """ + Parameters: + - fan_num + """ + pass + + def pltfm_mgr_qsfp_presence_get(self, port_num): + """ + Parameters: + - port_num + """ + pass + + def pltfm_mgr_qsfp_info_get(self, port_num): + """ + Parameters: + - port_num + """ + pass + + def pltfm_mgr_qsfp_get_max_port(self): + pass + + def pltfm_mgr_qsfp_reset(self, port_num, reset): + """ + Parameters: + - port_num + - reset + """ + pass + + def pltfm_mgr_qsfp_lpmode_get(self, port_num): + """ + Parameters: + - port_num + """ + pass + + def pltfm_mgr_qsfp_lpmode_set(self, port_num, lpmode): + """ + Parameters: + - port_num + - lpmode + """ + pass + + def pltfm_mgr_sensor_info_get(self, options): + """ + Parameters: + - options + """ + pass + + +class Client(Iface): + def __init__(self, iprot, oprot=None): + self._iprot = self._oprot = iprot + if oprot is not None: + self._oprot = oprot + self._seqid = 0 + + def pltfm_mgr_dummy(self, device): + """ + Parameters: + - device + """ + self.send_pltfm_mgr_dummy(device) + return self.recv_pltfm_mgr_dummy() + + def send_pltfm_mgr_dummy(self, device): + self._oprot.writeMessageBegin('pltfm_mgr_dummy', TMessageType.CALL, self._seqid) + args = pltfm_mgr_dummy_args() + args.device = device + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_dummy(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_dummy_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_dummy failed: unknown result") + + def pltfm_mgr_sys_tmp_get(self): + self.send_pltfm_mgr_sys_tmp_get() + return self.recv_pltfm_mgr_sys_tmp_get() + + def send_pltfm_mgr_sys_tmp_get(self): + self._oprot.writeMessageBegin('pltfm_mgr_sys_tmp_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_sys_tmp_get_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_sys_tmp_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_sys_tmp_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sys_tmp_get failed: unknown result") + + def pltfm_mgr_sys_eeprom_get(self): + self.send_pltfm_mgr_sys_eeprom_get() + return self.recv_pltfm_mgr_sys_eeprom_get() + + def send_pltfm_mgr_sys_eeprom_get(self): + self._oprot.writeMessageBegin('pltfm_mgr_sys_eeprom_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_sys_eeprom_get_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_sys_eeprom_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_sys_eeprom_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sys_eeprom_get failed: unknown result") + + def pltfm_mgr_pwr_supply_present_get(self, ps_num): + """ + Parameters: + - ps_num + """ + self.send_pltfm_mgr_pwr_supply_present_get(ps_num) + return self.recv_pltfm_mgr_pwr_supply_present_get() + + def send_pltfm_mgr_pwr_supply_present_get(self, ps_num): + self._oprot.writeMessageBegin('pltfm_mgr_pwr_supply_present_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_pwr_supply_present_get_args() + args.ps_num = ps_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_pwr_supply_present_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_pwr_supply_present_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_supply_present_get failed: unknown result") + + def pltfm_mgr_pwr_supply_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + self.send_pltfm_mgr_pwr_supply_info_get(ps_num) + return self.recv_pltfm_mgr_pwr_supply_info_get() + + def send_pltfm_mgr_pwr_supply_info_get(self, ps_num): + self._oprot.writeMessageBegin('pltfm_mgr_pwr_supply_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_pwr_supply_info_get_args() + args.ps_num = ps_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_pwr_supply_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_pwr_supply_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_supply_info_get failed: unknown result") + + def pltfm_mgr_pwr_rail_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + self.send_pltfm_mgr_pwr_rail_info_get(ps_num) + return self.recv_pltfm_mgr_pwr_rail_info_get() + + def send_pltfm_mgr_pwr_rail_info_get(self, ps_num): + self._oprot.writeMessageBegin('pltfm_mgr_pwr_rail_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_pwr_rail_info_get_args() + args.ps_num = ps_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_pwr_rail_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_pwr_rail_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_rail_info_get failed: unknown result") + + def pltfm_mgr_fan_speed_set(self, fan_num, percent): + """ + Parameters: + - fan_num + - percent + """ + self.send_pltfm_mgr_fan_speed_set(fan_num, percent) + return self.recv_pltfm_mgr_fan_speed_set() + + def send_pltfm_mgr_fan_speed_set(self, fan_num, percent): + self._oprot.writeMessageBegin('pltfm_mgr_fan_speed_set', TMessageType.CALL, self._seqid) + args = pltfm_mgr_fan_speed_set_args() + args.fan_num = fan_num + args.percent = percent + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_fan_speed_set(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_fan_speed_set_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_fan_speed_set failed: unknown result") + + def pltfm_mgr_fan_info_get(self, fan_num): + """ + Parameters: + - fan_num + """ + self.send_pltfm_mgr_fan_info_get(fan_num) + return self.recv_pltfm_mgr_fan_info_get() + + def send_pltfm_mgr_fan_info_get(self, fan_num): + self._oprot.writeMessageBegin('pltfm_mgr_fan_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_fan_info_get_args() + args.fan_num = fan_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_fan_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_fan_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_fan_info_get failed: unknown result") + + def pltfm_mgr_qsfp_presence_get(self, port_num): + """ + Parameters: + - port_num + """ + self.send_pltfm_mgr_qsfp_presence_get(port_num) + return self.recv_pltfm_mgr_qsfp_presence_get() + + def send_pltfm_mgr_qsfp_presence_get(self, port_num): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_presence_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_presence_get_args() + args.port_num = port_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_presence_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_presence_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_presence_get failed: unknown result") + + def pltfm_mgr_qsfp_info_get(self, port_num): + """ + Parameters: + - port_num + """ + self.send_pltfm_mgr_qsfp_info_get(port_num) + return self.recv_pltfm_mgr_qsfp_info_get() + + def send_pltfm_mgr_qsfp_info_get(self, port_num): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_info_get_args() + args.port_num = port_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_info_get failed: unknown result") + + def pltfm_mgr_qsfp_get_max_port(self): + self.send_pltfm_mgr_qsfp_get_max_port() + return self.recv_pltfm_mgr_qsfp_get_max_port() + + def send_pltfm_mgr_qsfp_get_max_port(self): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_get_max_port', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_get_max_port_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_get_max_port(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_get_max_port_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_get_max_port failed: unknown result") + + def pltfm_mgr_qsfp_reset(self, port_num, reset): + """ + Parameters: + - port_num + - reset + """ + self.send_pltfm_mgr_qsfp_reset(port_num, reset) + return self.recv_pltfm_mgr_qsfp_reset() + + def send_pltfm_mgr_qsfp_reset(self, port_num, reset): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_reset', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_reset_args() + args.port_num = port_num + args.reset = reset + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_reset(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_reset_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_reset failed: unknown result") + + def pltfm_mgr_qsfp_lpmode_get(self, port_num): + """ + Parameters: + - port_num + """ + self.send_pltfm_mgr_qsfp_lpmode_get(port_num) + return self.recv_pltfm_mgr_qsfp_lpmode_get() + + def send_pltfm_mgr_qsfp_lpmode_get(self, port_num): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_lpmode_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_lpmode_get_args() + args.port_num = port_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_lpmode_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_lpmode_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_lpmode_get failed: unknown result") + + def pltfm_mgr_qsfp_lpmode_set(self, port_num, lpmode): + """ + Parameters: + - port_num + - lpmode + """ + self.send_pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) + return self.recv_pltfm_mgr_qsfp_lpmode_set() + + def send_pltfm_mgr_qsfp_lpmode_set(self, port_num, lpmode): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_lpmode_set', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_lpmode_set_args() + args.port_num = port_num + args.lpmode = lpmode + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_lpmode_set(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_lpmode_set_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_lpmode_set failed: unknown result") + + def pltfm_mgr_sensor_info_get(self, options): + """ + Parameters: + - options + """ + self.send_pltfm_mgr_sensor_info_get(options) + return self.recv_pltfm_mgr_sensor_info_get() + + def send_pltfm_mgr_sensor_info_get(self, options): + self._oprot.writeMessageBegin('pltfm_mgr_sensor_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_sensor_info_get_args() + args.options = options + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_sensor_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_sensor_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sensor_info_get failed: unknown result") + + +class Processor(Iface, TProcessor): + def __init__(self, handler): + self._handler = handler + self._processMap = {} + self._processMap["pltfm_mgr_dummy"] = Processor.process_pltfm_mgr_dummy + self._processMap["pltfm_mgr_sys_tmp_get"] = Processor.process_pltfm_mgr_sys_tmp_get + self._processMap["pltfm_mgr_sys_eeprom_get"] = Processor.process_pltfm_mgr_sys_eeprom_get + self._processMap["pltfm_mgr_pwr_supply_present_get"] = Processor.process_pltfm_mgr_pwr_supply_present_get + self._processMap["pltfm_mgr_pwr_supply_info_get"] = Processor.process_pltfm_mgr_pwr_supply_info_get + self._processMap["pltfm_mgr_pwr_rail_info_get"] = Processor.process_pltfm_mgr_pwr_rail_info_get + self._processMap["pltfm_mgr_fan_speed_set"] = Processor.process_pltfm_mgr_fan_speed_set + self._processMap["pltfm_mgr_fan_info_get"] = Processor.process_pltfm_mgr_fan_info_get + self._processMap["pltfm_mgr_qsfp_presence_get"] = Processor.process_pltfm_mgr_qsfp_presence_get + self._processMap["pltfm_mgr_qsfp_info_get"] = Processor.process_pltfm_mgr_qsfp_info_get + self._processMap["pltfm_mgr_qsfp_get_max_port"] = Processor.process_pltfm_mgr_qsfp_get_max_port + self._processMap["pltfm_mgr_qsfp_reset"] = Processor.process_pltfm_mgr_qsfp_reset + self._processMap["pltfm_mgr_qsfp_lpmode_get"] = Processor.process_pltfm_mgr_qsfp_lpmode_get + self._processMap["pltfm_mgr_qsfp_lpmode_set"] = Processor.process_pltfm_mgr_qsfp_lpmode_set + self._processMap["pltfm_mgr_sensor_info_get"] = Processor.process_pltfm_mgr_sensor_info_get + + def process(self, iprot, oprot): + (name, type, seqid) = iprot.readMessageBegin() + if name not in self._processMap: + iprot.skip(TType.STRUCT) + iprot.readMessageEnd() + x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name)) + oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid) + x.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + return + else: + self._processMap[name](self, seqid, iprot, oprot) + return True + + def process_pltfm_mgr_dummy(self, seqid, iprot, oprot): + args = pltfm_mgr_dummy_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_dummy_result() + try: + result.success = self._handler.pltfm_mgr_dummy(args.device) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_dummy", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_sys_tmp_get(self, seqid, iprot, oprot): + args = pltfm_mgr_sys_tmp_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_sys_tmp_get_result() + try: + result.success = self._handler.pltfm_mgr_sys_tmp_get() + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_sys_tmp_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_sys_eeprom_get(self, seqid, iprot, oprot): + args = pltfm_mgr_sys_eeprom_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_sys_eeprom_get_result() + try: + result.success = self._handler.pltfm_mgr_sys_eeprom_get() + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_sys_eeprom_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_pwr_supply_present_get(self, seqid, iprot, oprot): + args = pltfm_mgr_pwr_supply_present_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_pwr_supply_present_get_result() + try: + result.success = self._handler.pltfm_mgr_pwr_supply_present_get(args.ps_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_pwr_supply_present_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_pwr_supply_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_pwr_supply_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_pwr_supply_info_get_result() + try: + result.success = self._handler.pltfm_mgr_pwr_supply_info_get(args.ps_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_pwr_supply_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_pwr_rail_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_pwr_rail_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_pwr_rail_info_get_result() + try: + result.success = self._handler.pltfm_mgr_pwr_rail_info_get(args.ps_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_pwr_rail_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_fan_speed_set(self, seqid, iprot, oprot): + args = pltfm_mgr_fan_speed_set_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_fan_speed_set_result() + try: + result.success = self._handler.pltfm_mgr_fan_speed_set(args.fan_num, args.percent) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_fan_speed_set", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_fan_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_fan_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_fan_info_get_result() + try: + result.success = self._handler.pltfm_mgr_fan_info_get(args.fan_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_fan_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_presence_get(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_presence_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_presence_get_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_presence_get(args.port_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_presence_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_info_get_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_info_get(args.port_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_get_max_port(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_get_max_port_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_get_max_port_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_get_max_port() + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_get_max_port", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_reset(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_reset_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_reset_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_reset(args.port_num, args.reset) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_reset", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_lpmode_get(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_lpmode_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_lpmode_get_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_lpmode_get(args.port_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_lpmode_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_lpmode_set(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_lpmode_set_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_lpmode_set_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_lpmode_set(args.port_num, args.lpmode) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_lpmode_set", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_sensor_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_sensor_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_sensor_info_get_result() + try: + result.success = self._handler.pltfm_mgr_sensor_info_get(args.options) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_sensor_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + +# HELPER FUNCTIONS AND STRUCTURES + + +class pltfm_mgr_dummy_args(object): + """ + Attributes: + - device + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'device', None, None, ), # 1 + ) + + def __init__(self, device=None,): + self.device = device + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.device = iprot.readByte() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_dummy_args') + if self.device is not None: + oprot.writeFieldBegin('device', TType.BYTE, 1) + oprot.writeByte(self.device) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_dummy_result(object): + """ + Attributes: + - success + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + ) + + def __init__(self, success=None,): + self.success = success + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_dummy_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_tmp_get_args(object): + + thrift_spec = ( + ) + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_tmp_get_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_tmp_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_sys_tmp_t, pltfm_mgr_sys_tmp_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_sys_tmp_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_tmp_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_eeprom_get_args(object): + + thrift_spec = ( + ) + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_eeprom_get_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_eeprom_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_eeprom_t, pltfm_mgr_eeprom_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_eeprom_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_eeprom_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_present_get_args(object): + """ + Attributes: + - ps_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'ps_num', None, None, ), # 1 + ) + + def __init__(self, ps_num=None,): + self.ps_num = ps_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.ps_num = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_present_get_args') + if self.ps_num is not None: + oprot.writeFieldBegin('ps_num', TType.I16, 1) + oprot.writeI16(self.ps_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_present_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.BOOL, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.BOOL: + self.success = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_present_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.BOOL, 0) + oprot.writeBool(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_info_get_args(object): + """ + Attributes: + - ps_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'ps_num', None, None, ), # 1 + ) + + def __init__(self, ps_num=None,): + self.ps_num = ps_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.ps_num = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_info_get_args') + if self.ps_num is not None: + oprot.writeFieldBegin('ps_num', TType.I16, 1) + oprot.writeI16(self.ps_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_pwr_supply_info_t, pltfm_mgr_pwr_supply_info_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_pwr_supply_info_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_rail_info_get_args(object): + """ + Attributes: + - ps_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'ps_num', None, None, ), # 1 + ) + + def __init__(self, ps_num=None,): + self.ps_num = ps_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.ps_num = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_rail_info_get_args') + if self.ps_num is not None: + oprot.writeFieldBegin('ps_num', TType.I16, 1) + oprot.writeI16(self.ps_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_rail_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_pwr_rail_info_t, pltfm_mgr_pwr_rail_info_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_pwr_rail_info_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_rail_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_speed_set_args(object): + """ + Attributes: + - fan_num + - percent + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'fan_num', None, None, ), # 1 + (2, TType.I32, 'percent', None, None, ), # 2 + ) + + def __init__(self, fan_num=None, percent=None,): + self.fan_num = fan_num + self.percent = percent + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.fan_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.percent = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_speed_set_args') + if self.fan_num is not None: + oprot.writeFieldBegin('fan_num', TType.I32, 1) + oprot.writeI32(self.fan_num) + oprot.writeFieldEnd() + if self.percent is not None: + oprot.writeFieldBegin('percent', TType.I32, 2) + oprot.writeI32(self.percent) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_speed_set_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_speed_set_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_info_get_args(object): + """ + Attributes: + - fan_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'fan_num', None, None, ), # 1 + ) + + def __init__(self, fan_num=None,): + self.fan_num = fan_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.fan_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_info_get_args') + if self.fan_num is not None: + oprot.writeFieldBegin('fan_num', TType.I32, 1) + oprot.writeI32(self.fan_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_fan_info_t, pltfm_mgr_fan_info_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_fan_info_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_presence_get_args(object): + """ + Attributes: + - port_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + ) + + def __init__(self, port_num=None,): + self.port_num = port_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_presence_get_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_presence_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.BOOL, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.BOOL: + self.success = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_presence_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.BOOL, 0) + oprot.writeBool(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_info_get_args(object): + """ + Attributes: + - port_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + ) + + def __init__(self, port_num=None,): + self.port_num = port_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_info_get_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRING, 'success', 'UTF8', None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRING: + self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRING, 0) + oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_get_max_port_args(object): + + thrift_spec = ( + ) + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_get_max_port_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_get_max_port_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_get_max_port_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_reset_args(object): + """ + Attributes: + - port_num + - reset + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + (2, TType.BOOL, 'reset', None, None, ), # 2 + ) + + def __init__(self, port_num=None, reset=None,): + self.port_num = port_num + self.reset = reset + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.BOOL: + self.reset = iprot.readBool() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_reset_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + if self.reset is not None: + oprot.writeFieldBegin('reset', TType.BOOL, 2) + oprot.writeBool(self.reset) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_reset_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_reset_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_get_args(object): + """ + Attributes: + - port_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + ) + + def __init__(self, port_num=None,): + self.port_num = port_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_get_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.BOOL, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.BOOL: + self.success = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.BOOL, 0) + oprot.writeBool(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_set_args(object): + """ + Attributes: + - port_num + - lpmode + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + (2, TType.BOOL, 'lpmode', None, None, ), # 2 + ) + + def __init__(self, port_num=None, lpmode=None,): + self.port_num = port_num + self.lpmode = lpmode + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.BOOL: + self.lpmode = iprot.readBool() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_set_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + if self.lpmode is not None: + oprot.writeFieldBegin('lpmode', TType.BOOL, 2) + oprot.writeBool(self.lpmode) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_set_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_set_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sensor_info_get_args(object): + """ + Attributes: + - options + """ + + thrift_spec = ( + None, # 0 + (1, TType.STRING, 'options', 'UTF8', None, ), # 1 + ) + + def __init__(self, options=None,): + self.options = options + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRING: + self.options = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sensor_info_get_args') + if self.options is not None: + oprot.writeFieldBegin('options', TType.STRING, 1) + oprot.writeString(self.options.encode('utf-8') if sys.version_info[0] == 2 else self.options) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sensor_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRING, 'success', 'UTF8', None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRING: + self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sensor_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRING, 0) + oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py new file mode 100644 index 000000000000..ce03e14f8691 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py @@ -0,0 +1,1060 @@ +# +# Autogenerated by Thrift Compiler (0.10.0) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# +# options string: py +# + +from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException +from thrift.protocol.TProtocol import TProtocolException +import sys + +from thrift.transport import TTransport + + +class pltfm_mgr_sys_tmp_t(object): + """ + Attributes: + - tmp1 + - tmp2 + - tmp3 + - tmp4 + - tmp5 + - tmp6 + - tmp7 + - tmp8 + - tmp9 + - tmp10 + """ + + thrift_spec = ( + None, # 0 + (1, TType.DOUBLE, 'tmp1', None, None, ), # 1 + (2, TType.DOUBLE, 'tmp2', None, None, ), # 2 + (3, TType.DOUBLE, 'tmp3', None, None, ), # 3 + (4, TType.DOUBLE, 'tmp4', None, None, ), # 4 + (5, TType.DOUBLE, 'tmp5', None, None, ), # 5 + (6, TType.DOUBLE, 'tmp6', None, None, ), # 6 + (7, TType.DOUBLE, 'tmp7', None, None, ), # 7 + (8, TType.DOUBLE, 'tmp8', None, None, ), # 8 + (9, TType.DOUBLE, 'tmp9', None, None, ), # 9 + (10, TType.DOUBLE, 'tmp10', None, None, ), # 10 + ) + + def __init__(self, tmp1=None, tmp2=None, tmp3=None, tmp4=None, tmp5=None, tmp6=None, tmp7=None, tmp8=None, tmp9=None, tmp10=None,): + self.tmp1 = tmp1 + self.tmp2 = tmp2 + self.tmp3 = tmp3 + self.tmp4 = tmp4 + self.tmp5 = tmp5 + self.tmp6 = tmp6 + self.tmp7 = tmp7 + self.tmp8 = tmp8 + self.tmp9 = tmp9 + self.tmp10 = tmp10 + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.DOUBLE: + self.tmp1 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.DOUBLE: + self.tmp2 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.DOUBLE: + self.tmp3 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.DOUBLE: + self.tmp4 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.DOUBLE: + self.tmp5 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.DOUBLE: + self.tmp6 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.DOUBLE: + self.tmp7 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.DOUBLE: + self.tmp8 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.DOUBLE: + self.tmp9 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.DOUBLE: + self.tmp10 = iprot.readDouble() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_tmp_t') + if self.tmp1 is not None: + oprot.writeFieldBegin('tmp1', TType.DOUBLE, 1) + oprot.writeDouble(self.tmp1) + oprot.writeFieldEnd() + if self.tmp2 is not None: + oprot.writeFieldBegin('tmp2', TType.DOUBLE, 2) + oprot.writeDouble(self.tmp2) + oprot.writeFieldEnd() + if self.tmp3 is not None: + oprot.writeFieldBegin('tmp3', TType.DOUBLE, 3) + oprot.writeDouble(self.tmp3) + oprot.writeFieldEnd() + if self.tmp4 is not None: + oprot.writeFieldBegin('tmp4', TType.DOUBLE, 4) + oprot.writeDouble(self.tmp4) + oprot.writeFieldEnd() + if self.tmp5 is not None: + oprot.writeFieldBegin('tmp5', TType.DOUBLE, 5) + oprot.writeDouble(self.tmp5) + oprot.writeFieldEnd() + if self.tmp6 is not None: + oprot.writeFieldBegin('tmp6', TType.DOUBLE, 6) + oprot.writeDouble(self.tmp6) + oprot.writeFieldEnd() + if self.tmp7 is not None: + oprot.writeFieldBegin('tmp7', TType.DOUBLE, 7) + oprot.writeDouble(self.tmp7) + oprot.writeFieldEnd() + if self.tmp8 is not None: + oprot.writeFieldBegin('tmp8', TType.DOUBLE, 8) + oprot.writeDouble(self.tmp8) + oprot.writeFieldEnd() + if self.tmp9 is not None: + oprot.writeFieldBegin('tmp9', TType.DOUBLE, 9) + oprot.writeDouble(self.tmp9) + oprot.writeFieldEnd() + if self.tmp10 is not None: + oprot.writeFieldBegin('tmp10', TType.DOUBLE, 10) + oprot.writeDouble(self.tmp10) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_eeprom_t(object): + """ + Attributes: + - version + - prod_name + - prod_part_num + - sys_asm_part_num + - bfn_pcba_part_num + - bfn_pcbb_part_num + - odm_pcba_part_num + - odm_pcba_ser_num + - prod_state + - prod_ver + - prod_sub_ver + - prod_ser_num + - prod_ast_tag + - sys_mfger + - sys_mfg_date + - pcb_mfger + - assembled_at + - loc_mac_addr + - ext_mac_addr + - ext_mac_addr_size + - location + - crc8 + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'version', None, None, ), # 1 + (2, TType.STRING, 'prod_name', 'UTF8', None, ), # 2 + (3, TType.STRING, 'prod_part_num', 'UTF8', None, ), # 3 + (4, TType.STRING, 'sys_asm_part_num', 'UTF8', None, ), # 4 + (5, TType.STRING, 'bfn_pcba_part_num', 'UTF8', None, ), # 5 + (6, TType.STRING, 'bfn_pcbb_part_num', 'UTF8', None, ), # 6 + (7, TType.STRING, 'odm_pcba_part_num', 'UTF8', None, ), # 7 + (8, TType.STRING, 'odm_pcba_ser_num', 'UTF8', None, ), # 8 + (9, TType.I16, 'prod_state', None, None, ), # 9 + (10, TType.I16, 'prod_ver', None, None, ), # 10 + (11, TType.I16, 'prod_sub_ver', None, None, ), # 11 + (12, TType.STRING, 'prod_ser_num', 'UTF8', None, ), # 12 + (13, TType.STRING, 'prod_ast_tag', 'UTF8', None, ), # 13 + (14, TType.STRING, 'sys_mfger', 'UTF8', None, ), # 14 + (15, TType.STRING, 'sys_mfg_date', 'UTF8', None, ), # 15 + (16, TType.STRING, 'pcb_mfger', 'UTF8', None, ), # 16 + (17, TType.STRING, 'assembled_at', 'UTF8', None, ), # 17 + (18, TType.STRING, 'loc_mac_addr', 'UTF8', None, ), # 18 + (19, TType.STRING, 'ext_mac_addr', 'UTF8', None, ), # 19 + (20, TType.I32, 'ext_mac_addr_size', None, None, ), # 20 + (21, TType.STRING, 'location', 'UTF8', None, ), # 21 + (22, TType.I16, 'crc8', None, None, ), # 22 + ) + + def __init__(self, version=None, prod_name=None, prod_part_num=None, sys_asm_part_num=None, bfn_pcba_part_num=None, bfn_pcbb_part_num=None, odm_pcba_part_num=None, odm_pcba_ser_num=None, prod_state=None, prod_ver=None, prod_sub_ver=None, prod_ser_num=None, prod_ast_tag=None, sys_mfger=None, sys_mfg_date=None, pcb_mfger=None, assembled_at=None, loc_mac_addr=None, ext_mac_addr=None, ext_mac_addr_size=None, location=None, crc8=None,): + self.version = version + self.prod_name = prod_name + self.prod_part_num = prod_part_num + self.sys_asm_part_num = sys_asm_part_num + self.bfn_pcba_part_num = bfn_pcba_part_num + self.bfn_pcbb_part_num = bfn_pcbb_part_num + self.odm_pcba_part_num = odm_pcba_part_num + self.odm_pcba_ser_num = odm_pcba_ser_num + self.prod_state = prod_state + self.prod_ver = prod_ver + self.prod_sub_ver = prod_sub_ver + self.prod_ser_num = prod_ser_num + self.prod_ast_tag = prod_ast_tag + self.sys_mfger = sys_mfger + self.sys_mfg_date = sys_mfg_date + self.pcb_mfger = pcb_mfger + self.assembled_at = assembled_at + self.loc_mac_addr = loc_mac_addr + self.ext_mac_addr = ext_mac_addr + self.ext_mac_addr_size = ext_mac_addr_size + self.location = location + self.crc8 = crc8 + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.version = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.STRING: + self.prod_name = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.STRING: + self.prod_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.STRING: + self.sys_asm_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.STRING: + self.bfn_pcba_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.STRING: + self.bfn_pcbb_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.STRING: + self.odm_pcba_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.STRING: + self.odm_pcba_ser_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.I16: + self.prod_state = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.I16: + self.prod_ver = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 11: + if ftype == TType.I16: + self.prod_sub_ver = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 12: + if ftype == TType.STRING: + self.prod_ser_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 13: + if ftype == TType.STRING: + self.prod_ast_tag = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 14: + if ftype == TType.STRING: + self.sys_mfger = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 15: + if ftype == TType.STRING: + self.sys_mfg_date = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 16: + if ftype == TType.STRING: + self.pcb_mfger = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 17: + if ftype == TType.STRING: + self.assembled_at = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 18: + if ftype == TType.STRING: + self.loc_mac_addr = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 19: + if ftype == TType.STRING: + self.ext_mac_addr = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 20: + if ftype == TType.I32: + self.ext_mac_addr_size = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 21: + if ftype == TType.STRING: + self.location = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 22: + if ftype == TType.I16: + self.crc8 = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_eeprom_t') + if self.version is not None: + oprot.writeFieldBegin('version', TType.I16, 1) + oprot.writeI16(self.version) + oprot.writeFieldEnd() + if self.prod_name is not None: + oprot.writeFieldBegin('prod_name', TType.STRING, 2) + oprot.writeString(self.prod_name.encode('utf-8') if sys.version_info[0] == 2 else self.prod_name) + oprot.writeFieldEnd() + if self.prod_part_num is not None: + oprot.writeFieldBegin('prod_part_num', TType.STRING, 3) + oprot.writeString(self.prod_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.prod_part_num) + oprot.writeFieldEnd() + if self.sys_asm_part_num is not None: + oprot.writeFieldBegin('sys_asm_part_num', TType.STRING, 4) + oprot.writeString(self.sys_asm_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.sys_asm_part_num) + oprot.writeFieldEnd() + if self.bfn_pcba_part_num is not None: + oprot.writeFieldBegin('bfn_pcba_part_num', TType.STRING, 5) + oprot.writeString(self.bfn_pcba_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.bfn_pcba_part_num) + oprot.writeFieldEnd() + if self.bfn_pcbb_part_num is not None: + oprot.writeFieldBegin('bfn_pcbb_part_num', TType.STRING, 6) + oprot.writeString(self.bfn_pcbb_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.bfn_pcbb_part_num) + oprot.writeFieldEnd() + if self.odm_pcba_part_num is not None: + oprot.writeFieldBegin('odm_pcba_part_num', TType.STRING, 7) + oprot.writeString(self.odm_pcba_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.odm_pcba_part_num) + oprot.writeFieldEnd() + if self.odm_pcba_ser_num is not None: + oprot.writeFieldBegin('odm_pcba_ser_num', TType.STRING, 8) + oprot.writeString(self.odm_pcba_ser_num.encode('utf-8') if sys.version_info[0] == 2 else self.odm_pcba_ser_num) + oprot.writeFieldEnd() + if self.prod_state is not None: + oprot.writeFieldBegin('prod_state', TType.I16, 9) + oprot.writeI16(self.prod_state) + oprot.writeFieldEnd() + if self.prod_ver is not None: + oprot.writeFieldBegin('prod_ver', TType.I16, 10) + oprot.writeI16(self.prod_ver) + oprot.writeFieldEnd() + if self.prod_sub_ver is not None: + oprot.writeFieldBegin('prod_sub_ver', TType.I16, 11) + oprot.writeI16(self.prod_sub_ver) + oprot.writeFieldEnd() + if self.prod_ser_num is not None: + oprot.writeFieldBegin('prod_ser_num', TType.STRING, 12) + oprot.writeString(self.prod_ser_num.encode('utf-8') if sys.version_info[0] == 2 else self.prod_ser_num) + oprot.writeFieldEnd() + if self.prod_ast_tag is not None: + oprot.writeFieldBegin('prod_ast_tag', TType.STRING, 13) + oprot.writeString(self.prod_ast_tag.encode('utf-8') if sys.version_info[0] == 2 else self.prod_ast_tag) + oprot.writeFieldEnd() + if self.sys_mfger is not None: + oprot.writeFieldBegin('sys_mfger', TType.STRING, 14) + oprot.writeString(self.sys_mfger.encode('utf-8') if sys.version_info[0] == 2 else self.sys_mfger) + oprot.writeFieldEnd() + if self.sys_mfg_date is not None: + oprot.writeFieldBegin('sys_mfg_date', TType.STRING, 15) + oprot.writeString(self.sys_mfg_date.encode('utf-8') if sys.version_info[0] == 2 else self.sys_mfg_date) + oprot.writeFieldEnd() + if self.pcb_mfger is not None: + oprot.writeFieldBegin('pcb_mfger', TType.STRING, 16) + oprot.writeString(self.pcb_mfger.encode('utf-8') if sys.version_info[0] == 2 else self.pcb_mfger) + oprot.writeFieldEnd() + if self.assembled_at is not None: + oprot.writeFieldBegin('assembled_at', TType.STRING, 17) + oprot.writeString(self.assembled_at.encode('utf-8') if sys.version_info[0] == 2 else self.assembled_at) + oprot.writeFieldEnd() + if self.loc_mac_addr is not None: + oprot.writeFieldBegin('loc_mac_addr', TType.STRING, 18) + oprot.writeString(self.loc_mac_addr.encode('utf-8') if sys.version_info[0] == 2 else self.loc_mac_addr) + oprot.writeFieldEnd() + if self.ext_mac_addr is not None: + oprot.writeFieldBegin('ext_mac_addr', TType.STRING, 19) + oprot.writeString(self.ext_mac_addr.encode('utf-8') if sys.version_info[0] == 2 else self.ext_mac_addr) + oprot.writeFieldEnd() + if self.ext_mac_addr_size is not None: + oprot.writeFieldBegin('ext_mac_addr_size', TType.I32, 20) + oprot.writeI32(self.ext_mac_addr_size) + oprot.writeFieldEnd() + if self.location is not None: + oprot.writeFieldBegin('location', TType.STRING, 21) + oprot.writeString(self.location.encode('utf-8') if sys.version_info[0] == 2 else self.location) + oprot.writeFieldEnd() + if self.crc8 is not None: + oprot.writeFieldBegin('crc8', TType.I16, 22) + oprot.writeI16(self.crc8) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_info_t(object): + """ + Attributes: + - vin + - vout + - iout + - pwr_out + - fspeed + - ffault + - load_sharing + - model + - serial + - rev + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'vin', None, None, ), # 1 + (2, TType.I32, 'vout', None, None, ), # 2 + (3, TType.I32, 'iout', None, None, ), # 3 + (4, TType.I32, 'pwr_out', None, None, ), # 4 + (5, TType.I32, 'fspeed', None, None, ), # 5 + (6, TType.BOOL, 'ffault', None, None, ), # 6 + (7, TType.BOOL, 'load_sharing', None, None, ), # 7 + (8, TType.STRING, 'model', 'UTF8', None, ), # 8 + (9, TType.STRING, 'serial', 'UTF8', None, ), # 9 + (10, TType.STRING, 'rev', 'UTF8', None, ), # 10 + ) + + def __init__(self, vin=None, vout=None, iout=None, pwr_out=None, fspeed=None, ffault=None, load_sharing=None, model=None, serial=None, rev=None,): + self.vin = vin + self.vout = vout + self.iout = iout + self.pwr_out = pwr_out + self.fspeed = fspeed + self.ffault = ffault + self.load_sharing = load_sharing + self.model = model + self.serial = serial + self.rev = rev + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.vin = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.vout = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I32: + self.iout = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.I32: + self.pwr_out = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.I32: + self.fspeed = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.BOOL: + self.ffault = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.BOOL: + self.load_sharing = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.STRING: + self.model = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.STRING: + self.serial = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.STRING: + self.rev = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_info_t') + if self.vin is not None: + oprot.writeFieldBegin('vin', TType.I32, 1) + oprot.writeI32(self.vin) + oprot.writeFieldEnd() + if self.vout is not None: + oprot.writeFieldBegin('vout', TType.I32, 2) + oprot.writeI32(self.vout) + oprot.writeFieldEnd() + if self.iout is not None: + oprot.writeFieldBegin('iout', TType.I32, 3) + oprot.writeI32(self.iout) + oprot.writeFieldEnd() + if self.pwr_out is not None: + oprot.writeFieldBegin('pwr_out', TType.I32, 4) + oprot.writeI32(self.pwr_out) + oprot.writeFieldEnd() + if self.fspeed is not None: + oprot.writeFieldBegin('fspeed', TType.I32, 5) + oprot.writeI32(self.fspeed) + oprot.writeFieldEnd() + if self.ffault is not None: + oprot.writeFieldBegin('ffault', TType.BOOL, 6) + oprot.writeBool(self.ffault) + oprot.writeFieldEnd() + if self.load_sharing is not None: + oprot.writeFieldBegin('load_sharing', TType.BOOL, 7) + oprot.writeBool(self.load_sharing) + oprot.writeFieldEnd() + if self.model is not None: + oprot.writeFieldBegin('model', TType.STRING, 8) + oprot.writeString(self.model.encode('utf-8') if sys.version_info[0] == 2 else self.model) + oprot.writeFieldEnd() + if self.serial is not None: + oprot.writeFieldBegin('serial', TType.STRING, 9) + oprot.writeString(self.serial.encode('utf-8') if sys.version_info[0] == 2 else self.serial) + oprot.writeFieldEnd() + if self.rev is not None: + oprot.writeFieldBegin('rev', TType.STRING, 10) + oprot.writeString(self.rev.encode('utf-8') if sys.version_info[0] == 2 else self.rev) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_rail_info_t(object): + """ + Attributes: + - vrail1 + - vrail2 + - vrail3 + - vrail4 + - vrail5 + - vrail6 + - vrail7 + - vrail8 + - vrail9 + - vrail10 + - vrail11 + - vrail12 + - vrail13 + - vrail14 + - vrail15 + - vrail16 + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'vrail1', None, None, ), # 1 + (2, TType.I32, 'vrail2', None, None, ), # 2 + (3, TType.I32, 'vrail3', None, None, ), # 3 + (4, TType.I32, 'vrail4', None, None, ), # 4 + (5, TType.I32, 'vrail5', None, None, ), # 5 + (6, TType.I32, 'vrail6', None, None, ), # 6 + (7, TType.I32, 'vrail7', None, None, ), # 7 + (8, TType.I32, 'vrail8', None, None, ), # 8 + (9, TType.I32, 'vrail9', None, None, ), # 9 + (10, TType.I32, 'vrail10', None, None, ), # 10 + (11, TType.I32, 'vrail11', None, None, ), # 11 + (12, TType.I32, 'vrail12', None, None, ), # 12 + (13, TType.I32, 'vrail13', None, None, ), # 13 + (14, TType.I32, 'vrail14', None, None, ), # 14 + (15, TType.I32, 'vrail15', None, None, ), # 15 + (16, TType.I32, 'vrail16', None, None, ), # 16 + ) + + def __init__(self, vrail1=None, vrail2=None, vrail3=None, vrail4=None, vrail5=None, vrail6=None, vrail7=None, vrail8=None, vrail9=None, vrail10=None, vrail11=None, vrail12=None, vrail13=None, vrail14=None, vrail15=None, vrail16=None,): + self.vrail1 = vrail1 + self.vrail2 = vrail2 + self.vrail3 = vrail3 + self.vrail4 = vrail4 + self.vrail5 = vrail5 + self.vrail6 = vrail6 + self.vrail7 = vrail7 + self.vrail8 = vrail8 + self.vrail9 = vrail9 + self.vrail10 = vrail10 + self.vrail11 = vrail11 + self.vrail12 = vrail12 + self.vrail13 = vrail13 + self.vrail14 = vrail14 + self.vrail15 = vrail15 + self.vrail16 = vrail16 + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.vrail1 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.vrail2 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I32: + self.vrail3 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.I32: + self.vrail4 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.I32: + self.vrail5 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.I32: + self.vrail6 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.I32: + self.vrail7 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.I32: + self.vrail8 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.I32: + self.vrail9 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.I32: + self.vrail10 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 11: + if ftype == TType.I32: + self.vrail11 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 12: + if ftype == TType.I32: + self.vrail12 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 13: + if ftype == TType.I32: + self.vrail13 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 14: + if ftype == TType.I32: + self.vrail14 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 15: + if ftype == TType.I32: + self.vrail15 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 16: + if ftype == TType.I32: + self.vrail16 = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_rail_info_t') + if self.vrail1 is not None: + oprot.writeFieldBegin('vrail1', TType.I32, 1) + oprot.writeI32(self.vrail1) + oprot.writeFieldEnd() + if self.vrail2 is not None: + oprot.writeFieldBegin('vrail2', TType.I32, 2) + oprot.writeI32(self.vrail2) + oprot.writeFieldEnd() + if self.vrail3 is not None: + oprot.writeFieldBegin('vrail3', TType.I32, 3) + oprot.writeI32(self.vrail3) + oprot.writeFieldEnd() + if self.vrail4 is not None: + oprot.writeFieldBegin('vrail4', TType.I32, 4) + oprot.writeI32(self.vrail4) + oprot.writeFieldEnd() + if self.vrail5 is not None: + oprot.writeFieldBegin('vrail5', TType.I32, 5) + oprot.writeI32(self.vrail5) + oprot.writeFieldEnd() + if self.vrail6 is not None: + oprot.writeFieldBegin('vrail6', TType.I32, 6) + oprot.writeI32(self.vrail6) + oprot.writeFieldEnd() + if self.vrail7 is not None: + oprot.writeFieldBegin('vrail7', TType.I32, 7) + oprot.writeI32(self.vrail7) + oprot.writeFieldEnd() + if self.vrail8 is not None: + oprot.writeFieldBegin('vrail8', TType.I32, 8) + oprot.writeI32(self.vrail8) + oprot.writeFieldEnd() + if self.vrail9 is not None: + oprot.writeFieldBegin('vrail9', TType.I32, 9) + oprot.writeI32(self.vrail9) + oprot.writeFieldEnd() + if self.vrail10 is not None: + oprot.writeFieldBegin('vrail10', TType.I32, 10) + oprot.writeI32(self.vrail10) + oprot.writeFieldEnd() + if self.vrail11 is not None: + oprot.writeFieldBegin('vrail11', TType.I32, 11) + oprot.writeI32(self.vrail11) + oprot.writeFieldEnd() + if self.vrail12 is not None: + oprot.writeFieldBegin('vrail12', TType.I32, 12) + oprot.writeI32(self.vrail12) + oprot.writeFieldEnd() + if self.vrail13 is not None: + oprot.writeFieldBegin('vrail13', TType.I32, 13) + oprot.writeI32(self.vrail13) + oprot.writeFieldEnd() + if self.vrail14 is not None: + oprot.writeFieldBegin('vrail14', TType.I32, 14) + oprot.writeI32(self.vrail14) + oprot.writeFieldEnd() + if self.vrail15 is not None: + oprot.writeFieldBegin('vrail15', TType.I32, 15) + oprot.writeI32(self.vrail15) + oprot.writeFieldEnd() + if self.vrail16 is not None: + oprot.writeFieldBegin('vrail16', TType.I32, 16) + oprot.writeI32(self.vrail16) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_info_t(object): + """ + Attributes: + - fan_num + - front_rpm + - rear_rpm + - percent + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'fan_num', None, None, ), # 1 + (2, TType.I32, 'front_rpm', None, None, ), # 2 + (3, TType.I32, 'rear_rpm', None, None, ), # 3 + (4, TType.I32, 'percent', None, None, ), # 4 + ) + + def __init__(self, fan_num=None, front_rpm=None, rear_rpm=None, percent=None,): + self.fan_num = fan_num + self.front_rpm = front_rpm + self.rear_rpm = rear_rpm + self.percent = percent + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.fan_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.front_rpm = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I32: + self.rear_rpm = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.I32: + self.percent = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_info_t') + if self.fan_num is not None: + oprot.writeFieldBegin('fan_num', TType.I32, 1) + oprot.writeI32(self.fan_num) + oprot.writeFieldEnd() + if self.front_rpm is not None: + oprot.writeFieldBegin('front_rpm', TType.I32, 2) + oprot.writeI32(self.front_rpm) + oprot.writeFieldEnd() + if self.rear_rpm is not None: + oprot.writeFieldBegin('rear_rpm', TType.I32, 3) + oprot.writeI32(self.rear_rpm) + oprot.writeFieldEnd() + if self.percent is not None: + oprot.writeFieldBegin('percent', TType.I32, 4) + oprot.writeI32(self.percent) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class InvalidPltfmMgrOperation(TException): + """ + Attributes: + - code + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'code', None, None, ), # 1 + ) + + def __init__(self, code=None,): + self.code = code + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.code = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('InvalidPltfmMgrOperation') + if self.code is not None: + oprot.writeFieldBegin('code', TType.I32, 1) + oprot.writeI32(self.code) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __str__(self): + return repr(self) + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py new file mode 100644 index 000000000000..33adad8c1ac6 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +try: + import os + import sys + + sys.path.append(os.path.dirname(__file__)) + + from .platform_thrift_client import ThriftClient + + from sonic_platform_base.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class Psu(PsuBase): + """Platform-specific PSU class""" + + def __init__(self, index): + PsuBase.__init__(self) + self.index = index + + @staticmethod + def get_num_psus(): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_powergood_status(self): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based self.index + :param self.index: An integer, 1-based self.index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + try: + with ThriftClient() as client: + psu_info = client.pltfm_mgr.pltfm_mgr_pwr_supply_info_get(self.index) + except Exception: + return False + + return (psu_info.ffault == False) + + def get_presence(self): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based self.index + :param self.index: An integer, 1-based self.index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + try: + with ThriftClient() as client: + status = client.pltfm_mgr.pltfm_mgr_pwr_supply_present_get(self.index) + except Exception: + return False + + return status diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py new file mode 100644 index 000000000000..1b63630d1a8f --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python + +try: + import os + import sys + import time + + sys.path.append(os.path.dirname(__file__)) + + from .platform_thrift_client import ThriftClient + + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +SFP_EEPROM_CACHE = "/var/run/platform/sfp/cache" + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 0 + PORTS_IN_BLOCK = 0 + QSFP_PORT_START = 1 + QSFP_PORT_END = 0 + EEPROM_OFFSET = 0 + QSFP_CHECK_INTERVAL = 4 + + @property + def port_start(self): + self.update_port_info() + return self.PORT_START + + @property + def port_end(self): + self.update_port_info() + return self.PORT_END + + @property + def qsfp_ports(self): + self.update_port_info() + return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + print "dependency on sysfs has been removed" + raise Exception() + + def __init__(self): + self.ready = False + self.phy_port_dict = {'-1': 'system_not_ready'} + self.phy_port_cur_state = {} + self.qsfp_interval = self.QSFP_CHECK_INTERVAL + + if not os.path.exists(os.path.dirname(SFP_EEPROM_CACHE)): + try: + os.makedirs(os.path.dirname(SFP_EEPROM_CACHE)) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + open(SFP_EEPROM_CACHE, 'ab').close() + + SfpUtilBase.__init__(self) + + def update_port_info(self): + if self.QSFP_PORT_END == 0: + with ThriftClient() as client: + self.QSFP_PORT_END = client.pltfm_mgr.pltfm_mgr_qsfp_get_max_port(); + self.PORT_END = self.QSFP_PORT_END + self.PORTS_IN_BLOCK = self.QSFP_PORT_END + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + presence = False + + try: + with ThriftClient() as client: + presence = client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) + except Exception as e: + print e.__doc__ + print e.message + + return presence + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + with ThriftClient() as client: + lpmode = client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_get(port_num) + return lpmode + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + with ThriftClient() as client: + status = client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) + return (status == 0) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + with ThriftClient() as client: + client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, True) + status = client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, False) + return status + + def check_transceiver_change(self): + if not self.ready: + return + + self.phy_port_dict = {} + + try: + client = ThriftClient().open() + except Exception: + return + + # Get presence of each SFP + for port in range(self.port_start, self.port_end + 1): + try: + sfp_resent = client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port) + except Exception: + sfp_resent = False + sfp_state = '1' if sfp_resent else '0' + + if port in self.phy_port_cur_state: + if self.phy_port_cur_state[port] != sfp_state: + self.phy_port_dict[port] = sfp_state + else: + self.phy_port_dict[port] = sfp_state + + # Update port current state + self.phy_port_cur_state[port] = sfp_state + + client.close() + + def get_transceiver_change_event(self, timeout=0): + forever = False + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print "get_transceiver_change_event:Invalid timeout value", timeout + return False, {} + + while forever or timeout > 0: + if not self.ready: + try: + with ThriftClient(): pass + except Exception: + pass + else: + self.ready = True + self.phy_port_dict = {} + break + elif self.qsfp_interval == 0: + self.qsfp_interval = self.QSFP_CHECK_INTERVAL + + # Process transceiver plug-in/out event + self.check_transceiver_change() + + # Break if tranceiver state has changed + if bool(self.phy_port_dict): + break + + if timeout: + timeout -= 1 + + if self.qsfp_interval: + self.qsfp_interval -= 1 + + time.sleep(1) + + return self.ready, self.phy_port_dict + + def _get_port_eeprom_path(self, port_num, devid): + eeprom_path = None + + with ThriftClient() as client: + presence = client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) + if presence == True: + eeprom_cache = open(SFP_EEPROM_CACHE, 'wb') + eeprom_hex = client.pltfm_mgr.pltfm_mgr_qsfp_info_get(port_num) + eeprom_raw = bytearray.fromhex(eeprom_hex) + eeprom_cache.write(eeprom_raw) + eeprom_cache.close() + eeprom_path = SFP_EEPROM_CACHE + + return eeprom_path + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + sfputil = SfpUtil() + + @staticmethod + def port_start(): + return Sfp.sfputil.port_start + + @staticmethod + def port_end(): + return Sfp.sfputil.port_end + + @staticmethod + def qsfp_ports(): + return Sfp.sfputil.qsfp_ports() + + @staticmethod + def get_transceiver_change_event(timeout=0): + return Sfp.sfputil.get_transceiver_change_event() + + def __init__(self, port_num): + self.port_num = port_num + SfpBase.__init__(self) + + def get_presence(self): + return Sfp.sfputil.get_presence(self.port_num) + + def get_lpmode(self): + return Sfp.sfputil.get_low_power_mode(self.port_num) + + def set_lpmode(self, lpmode): + return Sfp.sfputil.set_low_power_mode(self.port_num, lpmode) + + def reset(self): + return Sfp.sfputil.reset(self.port_num) + + def get_transceiver_info(self): + return Sfp.sfputil.get_transceiver_info_dict(self.port_num) + + def get_transceiver_bulk_status(self): + return Sfp.sfputil.get_transceiver_dom_info_dict(self.port_num) + + def get_transceiver_threshold_info(self): + return Sfp.sfputil.get_transceiver_dom_threshold_info_dict(self.port_num) + + def get_change_event(self, timeout=0): + return Sfp.get_transceiver_change_event(timeout) diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules index 5bb10ed19350..962a1de8204e 100755 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules @@ -8,6 +8,8 @@ KERNEL_SRC := /lib/modules/$(KVERSION) MODULE_SRC := $(shell pwd)/modules SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs +BUILD_DIR := $(shell pwd)/build +WHEEL_BUILD_DIR := $(BUILD_DIR)/wheel PLUGINS_DIR := $(shell pwd)/plugins MODULE_NAMES := as9516 as9516bf @@ -16,6 +18,10 @@ MODULE_NAMES := as9516 as9516bf override_dh_auto_build: make -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + set -e + python2.7 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + python3 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + set +e override_dh_auto_install: (for mod in $(MODULE_NAMES); do \ @@ -25,6 +31,8 @@ override_dh_auto_install: cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin; \ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} etc/network/interfaces.d/; \ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_PRE_NAME)-$${mod}/etc/network/interfaces.d/; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/; \ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/; \ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/plugins; \ cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/plugins/; \ done) @@ -35,6 +43,9 @@ override_dh_pysupport: override_dh_clean: dh_clean + rm -fr $(WHEEL_BUILD_DIR) + rm -fr *.egg-info + rm -fr $(BUILD) rm -f $(MODULE_SRC)/*.o $(MODULE_SRC)/*.ko $(MODULE_SRC)/*.mod.c $(MODULE_SRC)/.*.cmd rm -f $(MODULE_SRC)/Module.markers $(MODULE_SRC)/Module.symvers $(MODULE_SRC)/modules.order rm -rf $(MODULE_SRC)/.tmp_versions diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/setup.py b/platform/barefoot/sonic-platform-modules-bfn-newport/setup.py new file mode 120000 index 000000000000..a68e2eec6762 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/setup.py @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/setup.py \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/sonic_platform b/platform/barefoot/sonic-platform-modules-bfn-newport/sonic_platform new file mode 120000 index 000000000000..b2918418aad1 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/sonic_platform @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/sonic_platform \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/rules b/platform/barefoot/sonic-platform-modules-bfn/debian/rules index 83cdefe640ba..1bea5b4c67ef 100755 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/rules @@ -3,20 +3,33 @@ PACKAGE_NAME := sonic-platform-modules-bfn SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs +BUILD_DIR := $(shell pwd)/build +WHEEL_BUILD_DIR := $(BUILD_DIR)/wheel %: dh $@ +override_dh_auto_build: + set -e + python2.7 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + python3 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + set +e + override_dh_auto_install: dh_installdirs -p$(PACKAGE_NAME) usr/local/bin cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/platform/ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/platform/ override_dh_usrlocal: override_dh_pysupport: override_dh_clean: + rm -fr $(WHEEL_BUILD_DIR) + rm -fr *.egg-info + rm -fr $(BUILD) dh_clean diff --git a/platform/barefoot/sonic-platform-modules-bfn/setup.py b/platform/barefoot/sonic-platform-modules-bfn/setup.py new file mode 120000 index 000000000000..a68e2eec6762 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/setup.py @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/setup.py \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn/sonic_platform b/platform/barefoot/sonic-platform-modules-bfn/sonic_platform new file mode 120000 index 000000000000..b2918418aad1 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/sonic_platform @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/sonic_platform \ No newline at end of file From ec0153008a6e079da540839fe6d0573ee114190c Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Sat, 3 Oct 2020 23:00:39 -0700 Subject: [PATCH 1207/1427] [rc.local] separate configuration migration and grub installation logic (#5528) To address issue #5525 Explicitly control the grub installation requirement when it is needed. We have scenario where configuration migration happened but grub installation is not required. Signed-off-by: Ying Xie --- files/image_config/platform/rc.local | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index 2e242559094c..878345106c95 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -199,6 +199,7 @@ logger "SONiC version ${SONIC_VERSION} starting up..." # If the machine.conf is absent, it indicates that the unit booted # into SONiC from another NOS. Extract the machine.conf from ONIE. +grub_installation_needed="" if [ ! -e /host/machine.conf ]; then onie_dev=$(blkid | grep ONIE-BOOT | head -n 1 | awk '{print $1}' | sed -e 's/:.*$//') mkdir -p /mnt/onie-boot @@ -213,6 +214,7 @@ if [ ! -e /host/machine.conf ]; then eval val='$'onie_$var echo "onie_${var}=${val}" >> /host/machine.conf done + grub_installation_needed="TRUE" fi umount /mnt/onie-boot @@ -277,7 +279,7 @@ if [ -f $FIRST_BOOT_FILE ]; then # If the unit booted into SONiC from another NOS's grub, # we now install a grub for SONiC. - if [ -n "$onie_platform" ] && [ -n "$migration" ]; then + if [ -n "$onie_platform" ] && [ -n "$grub_installation_needed" ]; then grub_bin=$(ls /host/image-$SONIC_VERSION/platform/x86_64-grub/grub-pc-bin*.deb 2> /dev/null) if [ -z "$grub_bin" ]; then From 6b0690adbbfe4bb7f0e03651383bd9ee9cb34a9b Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Sat, 3 Oct 2020 23:03:13 -0700 Subject: [PATCH 1208/1427] [sonic-py-swsssdk] update submodule for using correct connect parameter number (#5524) * [MultiDB] fix wrong parameter number in interface.py (#88) Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 3ef02a1e357b..3461ae0578f4 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 3ef02a1e357b8ce7cbf58e39c775f1f75e69be04 +Subproject commit 3461ae0578f415753978a5c5b33ad43e0a9b0cc5 From 8c344095a8cba34637c5c4fbda81f24abd9df90c Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Mon, 5 Oct 2020 08:48:13 -0700 Subject: [PATCH 1209/1427] [docker-orchagent]: Add NDP Proxy Daemon (#5517) * Install ndppd during image build, and copy config files to image * Configure proxy settings based on config DB at container start * Pipe ndppd output to logger inside container to log output in syslog --- dockers/docker-orchagent/Dockerfile.j2 | 4 +- dockers/docker-orchagent/docker-init.sh | 4 +- dockers/docker-orchagent/ndppd.conf | 9 +++++ dockers/docker-orchagent/ndppd.conf.j2 | 37 +++++++++++++++++++ .../tests/data/ndppd/vlan_interfaces.json | 20 ++++++++++ src/sonic-config-engine/tests/ndppd.conf.j2 | 1 + .../tests/sample_output/py2/ndppd.conf | 25 +++++++++++++ .../tests/sample_output/py3/ndppd.conf | 25 +++++++++++++ src/sonic-config-engine/tests/test_j2files.py | 10 +++++ 9 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 dockers/docker-orchagent/ndppd.conf create mode 100644 dockers/docker-orchagent/ndppd.conf.j2 create mode 100644 src/sonic-config-engine/tests/data/ndppd/vlan_interfaces.json create mode 120000 src/sonic-config-engine/tests/ndppd.conf.j2 create mode 100644 src/sonic-config-engine/tests/sample_output/py2/ndppd.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/ndppd.conf diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 9190a5d89b8f..097a582f6337 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -17,7 +17,8 @@ RUN apt-get update && \ libelf1 \ libmnl0 \ bridge-utils \ - conntrack + conntrack \ + ndppd {% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %} ## Fix for gcc/python not found in arm docker @@ -60,6 +61,7 @@ RUN apt-get clean -y && \ COPY ["files/arp_update", "/usr/bin"] COPY ["arp_update.conf", "files/arp_update_vars.j2", "/usr/share/sonic/templates/"] +COPY ["ndppd.conf", "/usr/share/sonic/templates/"] COPY ["enable_counters.py", "/usr/bin"] COPY ["docker-init.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] diff --git a/dockers/docker-orchagent/docker-init.sh b/dockers/docker-orchagent/docker-init.sh index 70b9f2d871b5..41d815b4d7a9 100755 --- a/dockers/docker-orchagent/docker-init.sh +++ b/dockers/docker-orchagent/docker-init.sh @@ -10,6 +10,7 @@ CFGGEN_PARAMS=" \ -t /usr/share/sonic/templates/ports.json.j2,/etc/swss/config.d/ports.json \ -t /usr/share/sonic/templates/copp.json.j2,/etc/swss/config.d/00-copp.config.json \ -t /usr/share/sonic/templates/vlan_vars.j2 \ + -t /usr/share/sonic/templates/ndppd.conf.j2,/etc/ndppd.conf \ " VLAN=$(sonic-cfggen $CFGGEN_PARAMS) @@ -18,9 +19,10 @@ if [ -x /usr/share/sonic/hwsku/hwsku-init ]; then /usr/share/sonic/hwsku/hwsku-init fi -# Start arp_update when VLAN exists +# Start arp_update and NDP proxy daemon when VLAN exists if [ "$VLAN" != "" ]; then cp /usr/share/sonic/templates/arp_update.conf /etc/supervisor/conf.d/ + cp /usr/share/sonic/templates/ndppd.conf /etc/supervisor/conf.d/ fi exec /usr/bin/supervisord diff --git a/dockers/docker-orchagent/ndppd.conf b/dockers/docker-orchagent/ndppd.conf new file mode 100644 index 000000000000..1e97bf97e313 --- /dev/null +++ b/dockers/docker-orchagent/ndppd.conf @@ -0,0 +1,9 @@ +[program:ndppd] +command=bash -c "/usr/sbin/ndppd | /usr/bin/logger" +priority=7 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited \ No newline at end of file diff --git a/dockers/docker-orchagent/ndppd.conf.j2 b/dockers/docker-orchagent/ndppd.conf.j2 new file mode 100644 index 000000000000..bc375f3c4987 --- /dev/null +++ b/dockers/docker-orchagent/ndppd.conf.j2 @@ -0,0 +1,37 @@ +{% block banner %} +# =========== Managed by sonic-cfggen -- DO NOT edit manually! ==================== +# Generated by /usr/share/sonic/templates/ndppd.conf.j2 using config DB data +# File: /etc/ndppd.conf +# +{% endblock banner %} +# Config file for ndppd, the NDP Proxy Daemon +# See man page for ndppd.conf.5 for descriptions of all available options +{% if VLAN_INTERFACE and VLAN_INTERFACE|pfx_filter|length > 0%} +{# Get all VLAN interfaces that have proxy_arp enabled #} +{% set proxy_interfaces = {} %} +{% for intf in VLAN_INTERFACE %} +{% if "proxy_arp" in VLAN_INTERFACE[intf] and VLAN_INTERFACE[intf]["proxy_arp"] == "enabled" %} +{% set _x = proxy_interfaces.update({intf: []}) %} +{% endif %} +{% endfor -%} + +{# Add each IPv6 prefix from each proxy_arp interface #} +{% for (intf, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if intf in proxy_interfaces and prefix | ipv6 %} +{% set _x = proxy_interfaces[intf].append(prefix) %} +{% endif %} +{% endfor -%} + +{% for intf, prefix_list in proxy_interfaces.items() %} +{% if prefix_list %} + +proxy {{ intf }} { +{% for prefix in prefix_list %} + rule {{ prefix | network }}/{{ prefix | prefixlen }} { + static + } +{% endfor %} +} +{% endif %} +{% endfor %} +{% endif %} \ No newline at end of file diff --git a/src/sonic-config-engine/tests/data/ndppd/vlan_interfaces.json b/src/sonic-config-engine/tests/data/ndppd/vlan_interfaces.json new file mode 100644 index 000000000000..d45214827642 --- /dev/null +++ b/src/sonic-config-engine/tests/data/ndppd/vlan_interfaces.json @@ -0,0 +1,20 @@ +{ + "VLAN_INTERFACE": { + "Vlan1000": { + "proxy_arp": "enabled" + }, + "Vlan1000|192.168.0.1/21": {}, + "Vlan1000|fc01:1000::1/64": {}, + "Vlan1000|fc02:1000::1/64": {}, + "Vlan1000|fc03:1000::1/64": {}, + "Vlan2000": { + "proxy_arp": "enabled" + }, + "Vlan2000|fc01:2000::1/64": {}, + "Vlan3000|fc01:3000::1/64": {}, + "Vlan4000": { + "proxy_arp": "disabled" + }, + "Vlan4000|fc01:4000::1/64": {} + } +} \ No newline at end of file diff --git a/src/sonic-config-engine/tests/ndppd.conf.j2 b/src/sonic-config-engine/tests/ndppd.conf.j2 new file mode 120000 index 000000000000..e6f2f543eee4 --- /dev/null +++ b/src/sonic-config-engine/tests/ndppd.conf.j2 @@ -0,0 +1 @@ +../../../dockers/docker-orchagent/ndppd.conf.j2 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/sample_output/py2/ndppd.conf b/src/sonic-config-engine/tests/sample_output/py2/ndppd.conf new file mode 100644 index 000000000000..71ff1dfaf9ca --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/ndppd.conf @@ -0,0 +1,25 @@ +# =========== Managed by sonic-cfggen -- DO NOT edit manually! ==================== +# Generated by /usr/share/sonic/templates/ndppd.conf.j2 using config DB data +# File: /etc/ndppd.conf +# +# Config file for ndppd, the NDP Proxy Daemon +# See man page for ndppd.conf.5 for descriptions of all available options + +proxy Vlan1000 { + rule fc02:1000::/64 { + static + } + rule fc03:1000::/64 { + static + } + rule fc01:1000::/64 { + static + } +} + +proxy Vlan2000 { + rule fc01:2000::/64 { + static + } +} + diff --git a/src/sonic-config-engine/tests/sample_output/py3/ndppd.conf b/src/sonic-config-engine/tests/sample_output/py3/ndppd.conf new file mode 100644 index 000000000000..28a239006d24 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/ndppd.conf @@ -0,0 +1,25 @@ +# =========== Managed by sonic-cfggen -- DO NOT edit manually! ==================== +# Generated by /usr/share/sonic/templates/ndppd.conf.j2 using config DB data +# File: /etc/ndppd.conf +# +# Config file for ndppd, the NDP Proxy Daemon +# See man page for ndppd.conf.5 for descriptions of all available options + +proxy Vlan1000 { + rule fc01:1000::/64 { + static + } + rule fc02:1000::/64 { + static + } + rule fc03:1000::/64 { + static + } +} + +proxy Vlan2000 { + rule fc01:2000::/64 { + static + } +} + diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 98bb2437628d..ad06f61b84c5 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -171,6 +171,16 @@ def test_ipinip_multi_asic(self): sample_output_file = os.path.join(self.test_dir, 'multi_npu_data', utils.PYvX_DIR, 'ipinip.json') assert filecmp.cmp(sample_output_file, self.output_file) + def test_ndppd_conf(self): + conf_template = os.path.join(self.test_dir, "ndppd.conf.j2") + vlan_interfaces_json = os.path.join(self.test_dir, "data", "ndppd", "vlan_interfaces.json") + expected = os.path.join(self.test_dir, "sample_output", utils.PYvX_DIR, "ndppd.conf") + + argument = '-j {} -t {} > {}'.format(vlan_interfaces_json, conf_template, self.output_file) + self.run_script(argument) + assert filecmp.cmp(expected, self.output_file), self.run_diff(expected, self.output_file) + + def tearDown(self): try: os.remove(self.output_file) From f61ff95e26f631ef35028227da7b561c5681c2fa Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Mon, 5 Oct 2020 20:50:03 +0300 Subject: [PATCH 1210/1427] [barefoot] Platform API 2.0 fixups (#5539) Fixes for bfn platform api Signed-off-by: Volodymyr Boyko --- .../debian/rules | 10 ++-- .../sonic_platform/chassis.py | 2 +- .../sonic_platform/eeprom.py | 31 +++++----- .../sonic_platform/platform_thrift_client.py | 12 ++++ .../sonic_platform/psu.py | 14 +++-- .../sonic_platform/sfp.py | 57 ++++++++++++------- .../sonic-platform-modules-bfn/debian/rules | 2 - 7 files changed, 77 insertions(+), 51 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules index bf5a4c9a50fe..3377688e6097 100755 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules @@ -1,6 +1,6 @@ #!/usr/bin/make -f -PLATFORM = x86_64-accton_wedge100bf_32x-r0 +PLATFORM := x86_64-accton_wedge100bf_32x-r0 PACKAGE_NAME := sonic-platform-modules-bfn-montara SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs @@ -22,10 +22,10 @@ override_dh_auto_install: cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ - dh_installdirs -p$(PACKAGE_NAME) /usr/share/sonic/device/${PLATFORM}/ - cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/${PLATFORM}/ - dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/${PLATFORM}/plugins - cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/${PLATFORM}/plugins/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/$(PLATFORM)/ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/$(PLATFORM)/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/$(PLATFORM)/plugins + cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/$(PLATFORM)/plugins/ override_dh_usrlocal: diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py index 36a921d539f5..1ca885ff2a40 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py @@ -24,7 +24,7 @@ def __init__(self): sfp_node = Sfp(index) self._sfp_list.append(sfp_node) - for i in range(MAX_PSU): + for i in range(1, MAX_PSU + 1): psu = Psu(i) self._psu_list.append(psu) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py index a548e9364715..a1ebe5f224a9 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py @@ -2,7 +2,6 @@ try: - import time import os import sys import errno @@ -17,7 +16,7 @@ from sonic_eeprom import eeprom_base from sonic_eeprom import eeprom_tlvinfo - from .platform_thrift_client import ThriftClient + from .platform_thrift_client import thrift_try except ImportError, e: raise ImportError (str(e) + "- required module not found") @@ -65,8 +64,6 @@ EEPROM_STATUS = "/var/run/platform/eeprom/status" class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): - RETRIES = 35 - def __init__(self): with open(os.path.dirname(__file__) + "/logging.conf", 'r') as f: @@ -88,20 +85,16 @@ def __init__(self): self.eeprom_path = EEPROM_SYMLINK super(Eeprom, self).__init__(self.eeprom_path, 0, EEPROM_STATUS, True) - for attempt in range(self.RETRIES): - if self.eeprom_init(): - break - if attempt + 1 == self.RETRIES: - raise RuntimeError("eeprom.py: Initialization failed") - time.sleep(1) - - def eeprom_init(self): + def sys_eeprom_get(client): + return client.pltfm_mgr.pltfm_mgr_sys_eeprom_get() try: - with ThriftClient() as client: - self.eeprom = client.pltfm_mgr.pltfm_mgr_sys_eeprom_get() + self.eeprom = thrift_try(sys_eeprom_get) except Exception: - return False + raise RuntimeError("eeprom.py: Initialization failed") + + self.eeprom_parse() + def eeprom_parse(self): f = open(EEPROM_STATUS, 'w') f.write("ok") f.close() @@ -131,9 +124,13 @@ def eeprom_init(self): eeprom_params += "{0:s}={1:s}".format(elem[1], value) orig_stdout = sys.stdout + sys.stdout = StringIO() - new_e = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params]) - sys.stdout = orig_stdout + try: + new_e = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params]) + finally: + sys.stdout = orig_stdout + eeprom_base.EepromDecoder.write_eeprom(self, new_e) return True diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py index 06afe8e962ae..96c0e09ba1c0 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py @@ -3,6 +3,7 @@ try: import os import sys + import time import importlib sys.path.append(os.path.dirname(__file__)) @@ -11,6 +12,7 @@ from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol from thrift.protocol import TMultiplexedProtocol + from thrift.Thrift import TException except ImportError as e: raise ImportError (str(e) + "- required module not found") @@ -35,3 +37,13 @@ def __enter__(self): return self.open() def __exit__(self, exc_type, exc_value, tb): self.close() + +def thrift_try(func, attempts=35): + for attempt in range(attempts): + try: + with ThriftClient() as client: + return func(client) + except TException as e: + if attempt + 1 == attempts: + raise e + time.sleep(1) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py index 33adad8c1ac6..7e7e4403ad5c 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py @@ -6,7 +6,7 @@ sys.path.append(os.path.dirname(__file__)) - from .platform_thrift_client import ThriftClient + from .platform_thrift_client import thrift_try from sonic_platform_base.psu_base import PsuBase except ImportError as e: @@ -34,9 +34,11 @@ def get_powergood_status(self): :param self.index: An integer, 1-based self.index of the PSU of which to query status :return: Boolean, True if PSU is operating properly, False if PSU is faulty """ + def psu_info_get(client): + return client.pltfm_mgr.pltfm_mgr_pwr_supply_info_get(self.index) + try: - with ThriftClient() as client: - psu_info = client.pltfm_mgr.pltfm_mgr_pwr_supply_info_get(self.index) + psu_info = thrift_try(psu_info_get) except Exception: return False @@ -49,9 +51,11 @@ def get_presence(self): :param self.index: An integer, 1-based self.index of the PSU of which to query status :return: Boolean, True if PSU is plugged, False if not """ + def psu_present_get(client): + return client.pltfm_mgr.pltfm_mgr_pwr_supply_present_get(self.index) + try: - with ThriftClient() as client: - status = client.pltfm_mgr.pltfm_mgr_pwr_supply_present_get(self.index) + status = thrift_try(psu_present_get) except Exception: return False diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py index 1b63630d1a8f..12587c66f474 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py @@ -8,6 +8,7 @@ sys.path.append(os.path.dirname(__file__)) from .platform_thrift_client import ThriftClient + from .platform_thrift_client import thrift_try from sonic_platform_base.sfp_base import SfpBase from sonic_platform_base.sonic_sfp.sfputilbase import SfpUtilBase @@ -65,11 +66,13 @@ def __init__(self): SfpUtilBase.__init__(self) def update_port_info(self): + def qsfp_max_port_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_get_max_port(); + if self.QSFP_PORT_END == 0: - with ThriftClient() as client: - self.QSFP_PORT_END = client.pltfm_mgr.pltfm_mgr_qsfp_get_max_port(); - self.PORT_END = self.QSFP_PORT_END - self.PORTS_IN_BLOCK = self.QSFP_PORT_END + self.QSFP_PORT_END = thrift_try(qsfp_max_port_get) + self.PORT_END = self.QSFP_PORT_END + self.PORTS_IN_BLOCK = self.QSFP_PORT_END def get_presence(self, port_num): # Check for invalid port_num @@ -78,9 +81,11 @@ def get_presence(self, port_num): presence = False + def qsfp_presence_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) + try: - with ThriftClient() as client: - presence = client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) + presence = thrift_try(qsfp_presence_get) except Exception as e: print e.__doc__ print e.message @@ -92,8 +97,11 @@ def get_low_power_mode(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - with ThriftClient() as client: - lpmode = client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_get(port_num) + def qsfp_lpmode_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_get(port_num) + + lpmode = thrift_try(qsfp_lpmode_get) + return lpmode def set_low_power_mode(self, port_num, lpmode): @@ -101,8 +109,11 @@ def set_low_power_mode(self, port_num, lpmode): if port_num < self.port_start or port_num > self.port_end: return False - with ThriftClient() as client: - status = client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) + def qsfp_lpmode_set(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) + + status = thrift_try(qsfp_lpmode_set) + return (status == 0) def reset(self, port_num): @@ -110,9 +121,12 @@ def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - with ThriftClient() as client: + def qsfp_reset(client): client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, True) - status = client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, False) + return client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, False) + + status = thrift_try(qsfp_reset) + return status def check_transceiver_change(self): @@ -188,15 +202,16 @@ def get_transceiver_change_event(self, timeout=0): def _get_port_eeprom_path(self, port_num, devid): eeprom_path = None - with ThriftClient() as client: - presence = client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) - if presence == True: - eeprom_cache = open(SFP_EEPROM_CACHE, 'wb') - eeprom_hex = client.pltfm_mgr.pltfm_mgr_qsfp_info_get(port_num) - eeprom_raw = bytearray.fromhex(eeprom_hex) - eeprom_cache.write(eeprom_raw) - eeprom_cache.close() - eeprom_path = SFP_EEPROM_CACHE + def qsfp_info_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_info_get(port_num) + + if self.get_presence(port_num): + eeprom_hex = thrift_try(qsfp_info_get) + eeprom_cache = open(SFP_EEPROM_CACHE, 'wb') + eeprom_raw = bytearray.fromhex(eeprom_hex) + eeprom_cache.write(eeprom_raw) + eeprom_cache.close() + eeprom_path = SFP_EEPROM_CACHE return eeprom_path diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/rules b/platform/barefoot/sonic-platform-modules-bfn/debian/rules index 1bea5b4c67ef..37e264ad7ed8 100755 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/rules @@ -20,8 +20,6 @@ override_dh_auto_install: cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ - dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/platform/ - cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/platform/ override_dh_usrlocal: From 90d84143e831acf85c6d3b39e8dfed3575072f14 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Mon, 5 Oct 2020 19:54:21 -0700 Subject: [PATCH 1211/1427] [submodule update] Update sonic-utilities submodule pointer (#5545) - [acl-loader] Revert fix for IP protocol == 0 (#1142) - Show sflow interface to display all interfaces enabled for sflow (#1143) - [sflow_test.py]: tests for config sflow commands. (#1112) - [config/console] Support add/del console port setting commands (#1136) - [cli][bgp]use vtysh in the show ip bgp summary command (#1137) - [README.md] Describe new package creation schema (#1131) - [consutil] Remove actual baud and refactor lib for future change (#1130) Signed-off-by: Danny Allen --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 2f79ac135018..31eb13b7f8db 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 2f79ac135018b62a2a04e031c5221799fcaa2dc4 +Subproject commit 31eb13b7f8db910fa5fd8f11e0d53d89aaf93f50 From 70528f7460f3a5dee723ed90ba4781aca461a107 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 5 Oct 2020 22:54:47 -0700 Subject: [PATCH 1212/1427] [Multi-asic] Fixed Default Route to be BGP (#5548) Learned and not docker default route for multi-asic platforms. Signed-off-by: Abhishek Dosi --- dockers/docker-fpm-frr/docker_init.sh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/dockers/docker-fpm-frr/docker_init.sh b/dockers/docker-fpm-frr/docker_init.sh index 09489a6ae04a..25482866b495 100755 --- a/dockers/docker-fpm-frr/docker_init.sh +++ b/dockers/docker-fpm-frr/docker_init.sh @@ -17,17 +17,19 @@ CFGGEN_PARAMS=" \ " CONFIG_TYPE=$(sonic-cfggen $CFGGEN_PARAMS) -if [[ ! -z "$NAMESPACE_ID" ]]; then +update_default_gw() +{ + IP_VER=${1} # FRR is not running in host namespace so we need to delete # default gw kernel route added by docker network via eth0 and add it back # with higher administrative distance so that default route learnt # by FRR becomes best route if/when available - GATEWAY_IP=$(ip route show 0.0.0.0/0 dev eth0 | awk '{print $3}') + GATEWAY_IP=$(ip -${IP_VER} route show default dev eth0 | awk '{print $3}') #Check if docker default route is there if [[ ! -z "$GATEWAY_IP" ]]; then - ip route del 0.0.0.0/0 dev eth0 + ip -${IP_VER} route del default dev eth0 #Make sure route is deleted - CHECK_GATEWAY_IP=$(ip route show 0.0.0.0/0 dev eth0 | awk '{print $3}') + CHECK_GATEWAY_IP=$(ip -${IP_VER} route show default dev eth0 | awk '{print $3}') if [[ -z "$CHECK_GATEWAY_IP" ]]; then # Ref: http://docs.frrouting.org/en/latest/zebra.html#zebra-vrf # Zebra does treat Kernel routes as special case for the purposes of Admin Distance. \ @@ -35,9 +37,14 @@ if [[ ! -z "$NAMESPACE_ID" ]]; then # The top byte of the value is interpreted as the Administrative Distance and # the low three bytes are read in as the metric. # so here we are programming administrative distance of 210 (210 << 24) > 200 (for routes learnt via IBGP) - ip route add 0.0.0.0/0 via $GATEWAY_IP dev eth0 metric 3523215360 + ip -${IP_VER} route add default via $GATEWAY_IP dev eth0 metric 3523215360 fi fi +} + +if [[ ! -z "$NAMESPACE_ID" ]]; then + update_default_gw 4 + update_default_gw 6 fi if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then From 48c089b9bb79e7fcac2c91474ceb59b014d9db21 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Tue, 6 Oct 2020 06:23:24 -0700 Subject: [PATCH 1213/1427] Add Python3-swss-common package to image. (#5547) Make Python3-swsscommon available in image. ``` admin@str-s6000-acs-13:~$ sudo apt-cache search swss libswsscommon - This package contains Switch State Service common library. python-swsscommon - This package contains Switch State Service common Python2 library. python3-swsscommon- This package contains Switch State Service common Python3 library. admin@str-s6000-acs-13:~$ ``` --- platform/p4/docker-sonic-p4.mk | 1 + platform/vs/docker-sonic-vs.mk | 1 + slave.mk | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/p4/docker-sonic-p4.mk b/platform/p4/docker-sonic-p4.mk index 14747ec476e0..b499a99aefe5 100644 --- a/platform/p4/docker-sonic-p4.mk +++ b/platform/p4/docker-sonic-p4.mk @@ -8,6 +8,7 @@ $(DOCKER_SONIC_P4)_DEPENDS += $(SWSS) \ $(REDIS_TOOLS) \ $(REDIS_SERVER) \ $(PYTHON_SWSSCOMMON) \ + $(PYTHON3_SWSSCOMMON) \ $(LIBTEAMDCTL) \ $(LIBTEAM_UTILS) \ $(SONIC_DEVICE_DATA) \ diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index d1d694756c59..2812c5b26dd5 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -5,6 +5,7 @@ $(DOCKER_SONIC_VS)_PATH = $(PLATFORM_PATH)/docker-sonic-vs $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS) \ $(SYNCD_VS) \ $(PYTHON_SWSSCOMMON) \ + $(PYTHON3_SWSSCOMMON) \ $(LIBTEAMDCTL) \ $(LIBTEAM_UTILS) \ $(SONIC_DEVICE_DATA) \ diff --git a/slave.mk b/slave.mk index 8eb78494ce3d..9b0b10b3c0e7 100644 --- a/slave.mk +++ b/slave.mk @@ -803,6 +803,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(LIBNSS_TACPLUS) \ $(MONIT) \ $(PYTHON_SWSSCOMMON) \ + $(PYTHON3_SWSSCOMMON) \ $(SONIC_UTILITIES_DATA)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ @@ -862,7 +863,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export sonic_yang_mgmt_py_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY))" export multi_instance="false" export python_swss_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($(LIBSWSSCOMMON)_RDEPENDS))" - export python_swss_debs+=" $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(LIBSWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON_SWSSCOMMON))" + export python_swss_debs+=" $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(LIBSWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON_SWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON3_SWSSCOMMON))" export sonic_utilities_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_UTILITIES_PY2))" $(foreach docker, $($*_DOCKERS),\ From 49b34dc433065d5b2c69d9284629bb4b16745140 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Tue, 6 Oct 2020 07:58:00 -0700 Subject: [PATCH 1214/1427] [BCMSAI] Update BCM SAI debian package to 4.2.1.3 (6.5.19 hsdk) (#5532) * [BCMSAI DEB] Update BCM SAI debian package to 4.2.1.3 (6.5.19 hsdk)(1.6.5 SAI) * [BCMSAI GPL] Update BCMSAI GPL to 6.5.19 --- platform/broadcom/sai-modules.mk | 3 +- platform/broadcom/sai.mk | 8 +- .../broadcom/saibcm-modules/debian/changelog | 12 +- .../debian/opennsl-modules.install | 1 + platform/broadcom/saibcm-modules/debian/rules | 31 +- .../broadcom/saibcm-modules/include/ibde.h | 6 + .../broadcom/saibcm-modules/include/kcom.h | 53 +- .../saibcm-modules/include/sal/types.h | 25 +- .../saibcm-modules/include/soc/devids.h | 140 +- .../broadcom/saibcm-modules/make/Make.linux | 4 +- .../saibcm-modules/make/Makefile.linux-gto | 15 + .../saibcm-modules/make/Makefile.linux-gts | 142 + .../saibcm-modules/make/Makefile.linux-iproc | 16 +- .../make/Makefile.linux-iproc-4_4 | 92 + .../make/Makefile.linux-iproc_64 | 106 + .../saibcm-modules/make/Makefile.linux-slk | 146 + .../Makefile.linux-x86-generic-common-2_6 | 1 + .../Makefile.linux-x86-smp_generic_64-2_6 | 26 +- .../saibcm-modules/make/Makefile.linux-xlr | 142 + .../systems/bde/linux/kernel/Makefile | 8 +- .../bde/linux/kernel/linux-kernel-bde.c | 315 ++- .../systems/bde/linux/kernel/linux_dma.c | 41 +- .../bde/linux/user/kernel/linux-user-bde.c | 209 +- .../systems/bde/shared/shbde_iproc.c | 27 +- .../systems/linux/kernel/modules/Makefile | 2 +- .../linux/kernel/modules/bcm-knet/Makefile | 3 - .../linux/kernel/modules/bcm-knet/bcm-knet.c | 2429 +++++++++-------- .../kernel/modules/bcm-ptp-clock/Makefile | 65 + .../modules/bcm-ptp-clock/bcm-ptp-clock.c | 1981 ++++++++++++++ .../linux/kernel/modules/include/bcm-knet.h | 21 +- .../linux/kernel/modules/include/lkm.h | 5 + .../linux/kernel/modules/knet-cb/Makefile | 1 + .../linux/kernel/modules/knet-cb/knet-cb.c | 122 +- .../linux/kernel/modules/knet-cb/psample-cb.c | 262 +- .../linux/kernel/modules/psample/psample.c | 4 +- .../systems/linux/user/common/Makefile | 53 +- .../systems/linux/user/gts/Makefile | 63 + .../systems/linux/user/iproc-4_4/Makefile | 59 + .../systems/linux/user/iproc_64/Makefile | 59 + .../systems/linux/user/slk/Makefile | 60 + .../systems/linux/user/xlr/Makefile | 63 + 41 files changed, 5364 insertions(+), 1457 deletions(-) create mode 100644 platform/broadcom/saibcm-modules/make/Makefile.linux-gts create mode 100644 platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-4_4 create mode 100644 platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 create mode 100644 platform/broadcom/saibcm-modules/make/Makefile.linux-slk create mode 100644 platform/broadcom/saibcm-modules/make/Makefile.linux-xlr create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/bcm-ptp-clock.c create mode 100644 platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/user/iproc-4_4/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/user/slk/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index 5f48efefa19a..84d97c09ac88 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,9 +1,8 @@ # Broadcom SAI modules -BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1 +BRCM_OPENNSL_KERNEL_VERSION = 4.2.1.3-1 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb $(BRCM_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules $(BRCM_OPENNSL_KERNEL)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_DPKG_DEBS += $(BRCM_OPENNSL_KERNEL) - diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 00aaae57b4fa..98c61b798bd7 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,8 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.5.1-3_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm_3.7.5.1-3_amd64.deb?sv=2015-04-05&sr=b&sig=hwGt%2Fw1fWhauEsCXBTBmC3vC8G90iJT4DEp%2Bznwh4WY%3D&se=2034-04-16T01%3A02%3A17Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.5.1-3_amd64.deb +BRCM_SAI = libsaibcm_4.2.1.3_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm_4.2.1.3_amd64.deb?sv=2015-04-05&sr=b&sig=aA0Ltk2jteFuJZdr1ldj%2F5e6o7R0U5S%2FqVWvutPC7k0%3D&se=2021-08-31T04%3A08%3A35Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_4.2.1.3_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm-dev_3.7.5.1-3_amd64.deb?sv=2015-04-05&sr=b&sig=nuyZOMB%2BnmDIROP60UAiDl9eG0YHAEj6u8ViTlEqjf0%3D&se=2034-04-16T01%3A01%3A51Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm-dev_4.2.1.3_amd64.deb?sv=2015-04-05&sr=b&sig=r%2FWgs1VEFo07sbfYK%2FDZmk83QKTzwSSe%2F3%2BN3k3uAcY%3D&se=2022-01-30T22%3A55%3A04Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) diff --git a/platform/broadcom/saibcm-modules/debian/changelog b/platform/broadcom/saibcm-modules/debian/changelog index 2be513ed0435..f2b0db31e662 100644 --- a/platform/broadcom/saibcm-modules/debian/changelog +++ b/platform/broadcom/saibcm-modules/debian/changelog @@ -1,19 +1,25 @@ +opennsl (4.2.1.3-1) unstable; urgency=medium + + * Update to Broadcom SAI 4.2.1.3 + + -- Mahesh Maddikayala Fri, 18 Sep 2029 10:57:47 +0000 + opennsl (3.7.3.3-1) unstable; urgency=medium - + * Port Broadcom SAI 3.7.3.3 * Cherry-pick change from master branch, 3.7.3.3-1 -- Judy Joseph Fri, 2 Dec 2019 15:32:47 +0000 opennsl (3.7.3.2-1) unstable; urgency=medium - + * Port Broadcom SAI 3.7.3.2 * Cherry-pick change from master branch, 3.7.3.2-1 -- Judy Joseph Fri, 12 Nov 2019 15:22:47 +0000 opennsl (3.7.3.1-1) unstable; urgency=medium - + * Port Broadcom SAI 3.7.3.1 * Cherry-pick change from master branch, 3.7.3.1-1 diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index e536bae27494..0e8051fbbca7 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -3,4 +3,5 @@ systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.19.0 systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.19.0-9-2-amd64/extra systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.19.0-9-2-amd64/extra systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.19.0-9-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-ptp-clock.ko lib/modules/4.19.0-9-2-amd64/extra systemd/opennsl-modules.service lib/systemd/system diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index 5fee0cbf8f65..64cc9b6c07e0 100755 --- a/platform/broadcom/saibcm-modules/debian/rules +++ b/platform/broadcom/saibcm-modules/debian/rules @@ -35,6 +35,8 @@ PACKAGE=opennsl-modules # modifieable for experiments or debugging m-a MA_DIR ?= /usr/share/modass KVERSION ?= 4.19.0-9-2-amd64 +KERNVERSION ?= 4.19.0-9-2 + # load generic variable handling -include $(MA_DIR)/include/generic.make # load default rules, including kdist, kdist_image, ... @@ -62,8 +64,8 @@ kdist_clean: clean dh_testdir dh_clean SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ - KERNDIR=/usr/src/linux-headers-$(KVERSION) \ - KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + KERNDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + KERNEL_SRC=/usr/src/linux-headers-$(KERNVERSION)-amd64 \ $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean # rm -f driver/*.o driver/*.ko # @@ -78,13 +80,24 @@ configure-stamp: build-arch: configure-stamp build-arch-stamp -build-arch-stamp: +build-arch-stamp: dh_testdir + # create links + cd /; sudo mkdir -p /lib/modules/$(KERNVERSION)-amd64 + cd /; sudo rm /lib/modules/$(KERNVERSION)-amd64/build + cd /; sudo rm /lib/modules/$(KERNVERSION)-amd64/source + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-common/ /lib/modules/$(KERNVERSION)-amd64/source + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/ /lib/modules/$(KERNVERSION)-amd64/build + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/include/generated/ /usr/src/linux-headers-$(KERNVERSION)-common/include/generated + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/arch/x86/include/generated/ /usr/src/linux-headers-$(KERNVERSION)-common/arch/x86/include/generated + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/include/config/ /usr/src/linux-headers-$(KERNVERSION)-common/include/config + cd /; sudo cp /usr/src/linux-headers-$(KERNVERSION)-amd64/Module.symvers /usr/src/linux-headers-$(KERNVERSION)-common/Module.symvers + # Add here command to compile/build the package. SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ - KERNDIR=/usr/src/linux-headers-$(KVERSION) \ - KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + KERNDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + KERNEL_SRC=/usr/src/linux-headers-$(KERNVERSION)-amd64 \ $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 touch $@ @@ -92,7 +105,7 @@ build-arch-stamp: #k = $(shell echo $(KVERS) | grep -q ^2.6 && echo k) build-indep: configure-stamp build-indep-stamp -build-indep-stamp: +build-indep-stamp: dh_testdir # Add here command to compile/build the arch indep package. @@ -104,15 +117,15 @@ build-indep-stamp: build: build-arch -clean: +clean: dh_testdir #dh_testroot rm -f build-arch-stamp build-indep-stamp configure-stamp # Add here commands to clean up after the build process. SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ - KERNDIR=/usr/src/linux-headers-$(KVERSION) \ - KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + KERNDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + KERNEL_SRC=/usr/src/linux-headers-$(KERNVERSION)-amd64 \ $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean dh_clean diff --git a/platform/broadcom/saibcm-modules/include/ibde.h b/platform/broadcom/saibcm-modules/include/ibde.h index 45112eadcb4b..5f371b2667c3 100644 --- a/platform/broadcom/saibcm-modules/include/ibde.h +++ b/platform/broadcom/saibcm-modules/include/ibde.h @@ -34,6 +34,12 @@ typedef struct ibde_dev_s { sal_vaddr_t base_address; sal_vaddr_t base_address1; sal_vaddr_t base_address2; + /* a unique number representing the specific device. + * Must be different for different devices. + * May be used to identify specific devices in the system. + * May be implemented as a full PCIe address, a persistent configurable user value, ... + * Possible implementation value stores in QSPI flash memory of the device. */ + uint32 dev_unique_id; } ibde_dev_t; diff --git a/platform/broadcom/saibcm-modules/include/kcom.h b/platform/broadcom/saibcm-modules/include/kcom.h index 1e3cad0753bc..eb41e1a5aaf2 100644 --- a/platform/broadcom/saibcm-modules/include/kcom.h +++ b/platform/broadcom/saibcm-modules/include/kcom.h @@ -59,8 +59,9 @@ #define KCOM_M_DBGPKT_SET 41 /* Enbale debug packet function */ #define KCOM_M_DBGPKT_GET 42 /* Get debug packet function info */ #define KCOM_M_WB_CLEANUP 51 /* Clean up for warmbooting */ +#define KCOM_M_CLOCK_CMD 52 /* Clock Commands */ -#define KCOM_VERSION 10 /* Protocol version */ +#define KCOM_VERSION 12 /* Protocol version */ /* * Message status codes @@ -138,11 +139,10 @@ typedef struct kcom_netif_s { uint16 vlan; uint16 qnum; uint8 macaddr[6]; - uint8 ptch[2]; - uint8 itmh[4]; uint8 system_headers[KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX]; uint8 system_headers_size; char name[KCOM_NETIF_NAME_MAX]; + uint8 phys_port; } kcom_netif_t; /* @@ -225,13 +225,9 @@ typedef struct kcom_filter_s { uint8 b[KCOM_FILTER_BYTES_MAX]; uint32 w[KCOM_FILTER_WORDS_MAX]; } mask; - /** Information to parse Dune system headers */ - uint32 ftmh_lb_key_ext_size; - uint32 ftmh_stacking_ext_size; - uint32 pph_base_size; - uint32 pph_lif_ext_size[8]; - uint8 udh_enable; - uint32 udh_length_type[4]; + /** Mark to match source modid and modport */ + uint8 is_src_modport; + uint8 spa_unit; } kcom_filter_t; /* @@ -338,6 +334,19 @@ typedef struct kcom_msg_version_s { uint32 filter_max; } kcom_msg_version_t; +/* + * Request KCOM interface clock info. + */ +#define KSYNC_M_HW_INIT 0 +#define KSYNC_M_HW_DEINIT 1 +#define KSYNC_M_VERSION 2 +#define KSYNC_M_HW_TS_DISABLE 3 + +typedef struct kcom_clock_info_s { + uint8 cmd; + int32 data[8]; +} kcom_clock_info_t; + /* * Send literal string to/from kernel module. * Mainly for debugging purposes. @@ -386,6 +395,19 @@ typedef struct kcom_msg_hw_init_s { uint8 pkt_hdr_size; uint32 dma_hi; uint32 cdma_channels; + /* + * Information to parse Dune system headers + */ + uint32 ftmh_lb_key_ext_size; + uint32 ftmh_stacking_ext_size; + uint32 pph_base_size; + uint32 pph_lif_ext_size[8]; + uint32 udh_length_type[4]; + uint32 udh_size; + uint32 oamp_punted; + uint8 no_skip_udh_check; + uint8 system_headers_mode; + uint8 udh_enable; } kcom_msg_hw_init_t; /* @@ -445,6 +467,14 @@ typedef struct kcom_msg_netif_destroy_s { kcom_msg_hdr_t hdr; } kcom_msg_netif_destroy_t; +/* + * Destroy system network interface. + */ +typedef struct kcom_msg_clock_s{ + kcom_msg_hdr_t hdr; + kcom_clock_info_t clock_info; +} kcom_msg_clock_cmd_t; + /* * Get list of currently defined system network interfaces. */ @@ -486,7 +516,7 @@ typedef struct kcom_msg_filter_destroy_s { * Get list of currently defined packet filters. */ #ifndef KCOM_FILTER_MAX -#define KCOM_FILTER_MAX 128 +#define KCOM_FILTER_MAX 128 #endif typedef struct kcom_msg_filter_list_s { @@ -535,6 +565,7 @@ typedef union kcom_msg_s { kcom_msg_dbg_pkt_set_t dbg_pkt_set; kcom_msg_dbg_pkt_get_t dbg_pkt_get; kcom_msg_wb_cleanup_t wb_cleanup; + kcom_msg_clock_cmd_t clock_cmd; } kcom_msg_t; /* diff --git a/platform/broadcom/saibcm-modules/include/sal/types.h b/platform/broadcom/saibcm-modules/include/sal/types.h index b6b40f762939..7ed68f43e5e5 100644 --- a/platform/broadcom/saibcm-modules/include/sal/types.h +++ b/platform/broadcom/saibcm-modules/include/sal/types.h @@ -92,17 +92,25 @@ typedef signed int int32; /* 32-bit quantity */ #define COUNTOF(ary) ((int) (sizeof (ary) / sizeof ((ary)[0]))) -typedef uint32 sal_paddr_t; /* Physical address (PCI address) */ - #ifdef PTRS_ARE_64BITS -typedef uint64 sal_vaddr_t; /* Virtual address (Host address) */ -#define PTR_TO_INT(x) ((uint32)(((sal_vaddr_t)(x))&0xFFFFFFFF)) +typedef uint64 sal_vaddr_t; /* Virtual address (Host address) */ +typedef uint64 sal_paddr_t; /* Physical address (PCI address) */ +#define PTR_TO_INT(x) ((uint32)(((sal_vaddr_t)(x))&0xFFFFFFFF)) +#define PTR_HI_TO_INT(x) ((uint32)((((sal_vaddr_t)(x))>>32)&0xFFFFFFFF)) +#else +typedef uint32 sal_vaddr_t; /* Virtual address (Host address) */ +/* Physical address (PCI address) */ +#ifdef PHYS_ADDRS_ARE_64BITS +typedef uint64 sal_paddr_t; +#define PTR_HI_TO_INT(x) ((uint32)((((uint64)(x))>>32)&0xFFFFFFFF)) #else -typedef uint32 sal_vaddr_t; /* Virtual address (Host address) */ -#define PTR_TO_INT(x) ((uint32)(x)) +typedef uint32 sal_paddr_t; +#define PTR_HI_TO_INT(x) (0) +#endif +#define PTR_TO_INT(x) ((uint32)(x)) #endif -#define INT_TO_PTR(x) ((void *)((sal_vaddr_t)(x))) +#define INT_TO_PTR(x) ((void *)((sal_vaddr_t)(x))) #define PTR_TO_UINTPTR(x) ((sal_vaddr_t)(x)) #define UINTPTR_TO_PTR(x) ((void *)(x)) @@ -128,6 +136,7 @@ typedef union #define SAL_I2C_DEV_TYPE 0x00040 /* I2C device */ #define SAL_AXI_DEV_TYPE 0x00080 /* AXI device */ #define SAL_EMMI_DEV_TYPE 0x10000 /* EMMI device */ +#define SAL_COMPOSITE_DEV_TYPE 0x20000 /* Composite device, composed of sub-devices with buses */ #define SAL_DEV_BUS_TYPE_MASK 0xf00ff /* Odd for historical reasons */ /* Device types */ @@ -152,4 +161,4 @@ typedef union /* Special access addresses */ #define SAL_DEV_OP_EMMI_INIT 0x0fff1000 -#endif /* !_SAL_TYPES_H */ +#endif /* !_SAL_TYPES_H */ diff --git a/platform/broadcom/saibcm-modules/include/soc/devids.h b/platform/broadcom/saibcm-modules/include/soc/devids.h index 7546ef392298..bb91d90be03f 100644 --- a/platform/broadcom/saibcm-modules/include/soc/devids.h +++ b/platform/broadcom/saibcm-modules/include/soc/devids.h @@ -14,7 +14,7 @@ * version 2 (GPLv2) along with this source code. */ /* - * Copyright: (c) 2019 Broadcom. + * Copyright: (c) 2020 Broadcom. * All Rights Reserved. */ @@ -1211,11 +1211,13 @@ #define BCM56169_B0_REV_ID 0x11 #define BCM56169_B1_REV_ID 0x12 +#define BCM56980_DEVICE_ID_MASK 0xFFF0 #define BCM56980_DEVICE_ID 0xb980 #define BCM56980_A0_REV_ID 1 #define BCM56980_B0_REV_ID 0x11 #define BCM56981_DEVICE_ID 0xb981 #define BCM56981_A0_REV_ID 1 +#define BCM56981_B0_REV_ID 0x11 #define BCM56982_DEVICE_ID 0xb982 #define BCM56982_A0_REV_ID 1 #define BCM56982_B0_REV_ID 0x11 @@ -1248,6 +1250,30 @@ #define BCM56166_A0_REV_ID 1 #define BCM56166_B0_REV_ID 0x11 +#define BCM56273_DEVICE_ID 0xb273 +#define BCM56273_A0_REV_ID 1 +#define BCM56273_A1_REV_ID 2 + +#define BCM56274_DEVICE_ID 0xb274 +#define BCM56274_A0_REV_ID 1 +#define BCM56274_A1_REV_ID 2 + +#define BCM56275_DEVICE_ID 0xb275 +#define BCM56275_A0_REV_ID 1 +#define BCM56275_A1_REV_ID 2 + +#define BCM56276_DEVICE_ID 0xb276 +#define BCM56276_A0_REV_ID 1 +#define BCM56276_A1_REV_ID 2 + +#define BCM56277_DEVICE_ID 0xb277 +#define BCM56277_A0_REV_ID 1 +#define BCM56277_A1_REV_ID 2 + +#define BCM56278_DEVICE_ID 0xb278 +#define BCM56278_A0_REV_ID 1 +#define BCM56278_A1_REV_ID 2 + #define BCM53440_DEVICE_ID 0x8440 #define BCM53440_A0_REV_ID 1 #define BCM53440_B0_REV_ID 0x11 @@ -1277,18 +1303,23 @@ #define BCM56670_DEVICE_ID 0xb670 #define BCM56670_A0_REV_ID 1 #define BCM56670_B0_REV_ID 0x11 +#define BCM56670_C0_REV_ID 0x21 + #define BCM56671_DEVICE_ID 0xb671 #define BCM56671_A0_REV_ID 1 #define BCM56671_B0_REV_ID 0x11 +#define BCM56671_C0_REV_ID 0x21 #define BCM56672_DEVICE_ID 0xb672 #define BCM56672_A0_REV_ID 1 #define BCM56672_B0_REV_ID 0x11 +#define BCM56672_C0_REV_ID 0x21 #define BCM56675_DEVICE_ID 0xb675 #define BCM56675_A0_REV_ID 1 #define BCM56675_B0_REV_ID 0x11 +#define BCM56675_C0_REV_ID 0x21 #define BCM56565_DEVICE_ID 0xb565 @@ -1312,9 +1343,6 @@ #define BCM56760_A1_REV_ID 2 #define BCM56760_B0_REV_ID 0x11 -#define BCM56761_DEVICE_ID 0xb761 -#define BCM56761_A0_REV_ID 1 -#define BCM56761_B0_REV_ID 0x11 #define BCM56761_DEVICE_ID 0xb761 #define BCM56761_A0_REV_ID 1 @@ -1372,6 +1400,11 @@ #define BCM53575_A0_REV_ID 1 #define BCM53575_B0_REV_ID 0x11 +#define BCM56070_DEVICE_ID 0xb070 +#define BCM56070_A0_REV_ID 1 +#define BCM56071_DEVICE_ID 0xb071 +#define BCM56071_A0_REV_ID 1 + #define BCM56965_DEVICE_ID 0xb965 #define BCM56965_A0_REV_ID 1 @@ -1407,42 +1440,52 @@ #define BCM56370_DEVICE_ID 0xb370 #define BCM56370_A0_REV_ID 1 #define BCM56370_A1_REV_ID 0x02 +#define BCM56370_A2_REV_ID 0x03 #define BCM56371_DEVICE_ID 0xb371 #define BCM56371_A0_REV_ID 1 #define BCM56371_A1_REV_ID 0x02 +#define BCM56371_A2_REV_ID 0x03 #define BCM56372_DEVICE_ID 0xb372 #define BCM56372_A0_REV_ID 1 #define BCM56372_A1_REV_ID 0x02 +#define BCM56372_A2_REV_ID 0x03 #define BCM56374_DEVICE_ID 0xb374 #define BCM56374_A0_REV_ID 1 #define BCM56374_A1_REV_ID 0x02 +#define BCM56374_A2_REV_ID 0x03 #define BCM56375_DEVICE_ID 0xb375 #define BCM56375_A0_REV_ID 1 #define BCM56375_A1_REV_ID 0x02 +#define BCM56375_A2_REV_ID 0x03 #define BCM56376_DEVICE_ID 0xb376 #define BCM56376_A0_REV_ID 1 #define BCM56376_A1_REV_ID 0x02 +#define BCM56376_A2_REV_ID 0x03 #define BCM56377_DEVICE_ID 0xb377 #define BCM56377_A0_REV_ID 1 #define BCM56377_A1_REV_ID 0x02 +#define BCM56377_A2_REV_ID 0x03 #define BCM56577_DEVICE_ID 0xb577 #define BCM56577_A0_REV_ID 1 #define BCM56577_A1_REV_ID 0x02 +#define BCM56577_A2_REV_ID 0x03 #define BCM56578_DEVICE_ID 0xb578 #define BCM56578_A0_REV_ID 1 #define BCM56578_A1_REV_ID 0x02 +#define BCM56578_A2_REV_ID 0x03 #define BCM56579_DEVICE_ID 0xb579 #define BCM56579_A0_REV_ID 1 #define BCM56579_A1_REV_ID 0x02 +#define BCM56579_A2_REV_ID 0x03 #define BCM56770_DEVICE_ID 0xb770 #define BCM56770_A0_REV_ID 1 @@ -1450,6 +1493,14 @@ #define BCM56771_DEVICE_ID 0xb771 #define BCM56771_A0_REV_ID 1 +#define BCM56470_DEVICE_ID 0xb470 +#define BCM56470_A0_REV_ID 1 +#define BCM56471_DEVICE_ID 0xb471 +#define BCM56471_A0_REV_ID 1 +#define BCM56472_DEVICE_ID 0xb472 +#define BCM56472_A0_REV_ID 1 + + #define BCM53540_DEVICE_ID 0x8540 #define BCM53540_A0_REV_ID 1 #define BCM53547_DEVICE_ID 0x8547 @@ -1526,6 +1577,7 @@ #define DNXC_A1_REV_ID 0x0002 #define DNXC_B0_REV_ID 0x0011 #define DNXC_B1_REV_ID 0x0012 +#define DNXC_DEVID_FAMILY_MASK 0xfff0 #define BCM88790_DEVICE_ID 0x8790 #define BCM88790_A0_REV_ID DNXC_A0_REV_ID #define BCM88790_B0_REV_ID DNXC_B0_REV_ID @@ -1544,7 +1596,6 @@ #define BCM8879D_DEVICE_ID 0x879D #define BCM8879E_DEVICE_ID 0x879E #define BCM8879F_DEVICE_ID 0x879F -#define BCM_DNXF_DEVID_MASK 0xFFF0 #define ARADPLUS_DEVICE_ID 0x8660 #define ARADPLUS_A0_REV_ID 0x0001 #define BCM88660_DEVICE_ID ARADPLUS_DEVICE_ID @@ -1675,19 +1726,22 @@ #define BCM88685_DEVICE_ID 0x8685 #define BCM88685_A0_REV_ID JERICHO_PLUS_A0_REV_ID +#define BCM88687_DEVICE_ID 0x8687 +#define BCM88687_A0_REV_ID JERICHO_PLUS_A0_REV_ID + #define BCM88380_DEVICE_ID 0x8380 #define BCM88380_A0_REV_ID JERICHO_PLUS_A0_REV_ID #define BCM88381_DEVICE_ID 0x8381 #define BCM88381_A0_REV_ID JERICHO_PLUS_A0_REV_ID -#define JERICHO_2_DEVICE_ID 0x8690 -#define JERICHO_2_A0_REV_ID DNXC_A0_REV_ID -#define JERICHO_2_B0_REV_ID DNXC_B0_REV_ID -#define JERICHO_2_B1_REV_ID DNXC_B1_REV_ID -#define BCM88690_DEVICE_ID JERICHO_2_DEVICE_ID -#define BCM88690_A0_REV_ID JERICHO_2_A0_REV_ID -#define BCM88690_B0_REV_ID JERICHO_2_B0_REV_ID -#define BCM88690_B1_REV_ID JERICHO_2_B1_REV_ID +#define JERICHO2_DEVICE_ID 0x8690 +#define JERICHO2_A0_REV_ID DNXC_A0_REV_ID +#define JERICHO2_B0_REV_ID DNXC_B0_REV_ID +#define JERICHO2_B1_REV_ID DNXC_B1_REV_ID +#define BCM88690_DEVICE_ID JERICHO2_DEVICE_ID +#define BCM88690_A0_REV_ID JERICHO2_A0_REV_ID +#define BCM88690_B0_REV_ID JERICHO2_B0_REV_ID +#define BCM88690_B1_REV_ID JERICHO2_B1_REV_ID #define BCM88691_DEVICE_ID 0x8691 #define BCM88692_DEVICE_ID 0x8692 #define BCM88693_DEVICE_ID 0x8693 @@ -1703,12 +1757,56 @@ #define BCM8869D_DEVICE_ID 0x869D #define BCM8869E_DEVICE_ID 0x869E #define BCM8869F_DEVICE_ID 0x869F -#define BCM_JR2_DEVID_MASK 0xFFF0 -#define J2C_DEVICE_ID 0x8800 +#define J2C_DEVICE_ID 0x8800 +#define J2C_2ND_DEVICE_ID 0x8820 +#define J2C_DEVID_FAMILY_MASK 0xffd0 #define J2C_A0_REV_ID DNXC_A0_REV_ID +#define J2C_A1_REV_ID DNXC_A1_REV_ID #define BCM88800_DEVICE_ID J2C_DEVICE_ID +#define BCM88820_DEVICE_ID J2C_2ND_DEVICE_ID #define BCM88800_A0_REV_ID J2C_A0_REV_ID +#define BCM88800_A1_REV_ID J2C_A1_REV_ID +#define BCM88821_DEVICE_ID 0x8821 +#define BCM88826_DEVICE_ID 0x8826 +#define BCM88802_DEVICE_ID 0x8802 +#define BCM88803_DEVICE_ID 0x8803 +#define BCM88804_DEVICE_ID 0x8804 +#define BCM88805_DEVICE_ID 0x8805 +#define BCM88806_DEVICE_ID 0x8806 +#define BCM88822_DEVICE_ID 0x8822 +#define BCM88823_DEVICE_ID 0x8823 +#define BCM88824_DEVICE_ID 0x8824 +#define BCM88825_DEVICE_ID 0x8825 + +#define J2P_DEVICE_ID 0x8850 +#define J2P_A0_REV_ID DNXC_A0_REV_ID +#define BCM88850_DEVICE_ID J2P_DEVICE_ID +#define BCM88850_A0_REV_ID J2P_A0_REV_ID + +#define Q2A_DEVICE_ID 0x8480 +#define Q2A_A0_REV_ID DNXC_A0_REV_ID +#define Q2A_B0_REV_ID DNXC_B0_REV_ID +#define Q2A_B1_REV_ID DNXC_B1_REV_ID +#define BCM88480_DEVICE_ID Q2A_DEVICE_ID +#define BCM88480_A0_REV_ID Q2A_A0_REV_ID +#define BCM88480_B0_REV_ID Q2A_B0_REV_ID +#define BCM88480_B1_REV_ID Q2A_B1_REV_ID +#define BCM88481_DEVICE_ID 0x8481 +#define BCM88482_DEVICE_ID 0x8482 +#define BCM88483_DEVICE_ID 0x8483 +#define BCM88484_DEVICE_ID 0x8484 +#define BCM88485_DEVICE_ID 0x8485 +#define BCM88486_DEVICE_ID 0x8486 +#define BCM88487_DEVICE_ID 0x8487 +#define BCM88488_DEVICE_ID 0x8488 +#define BCM88489_DEVICE_ID 0x8489 +#define BCM8848A_DEVICE_ID 0x848A +#define BCM8848B_DEVICE_ID 0x848B +#define BCM8848C_DEVICE_ID 0x848C +#define BCM8848D_DEVICE_ID 0x848D +#define BCM8848E_DEVICE_ID 0x848E +#define BCM8848F_DEVICE_ID 0x848F #define QAX_DEVICE_ID 0x8470 #define QAX_A0_REV_ID 0x0001 @@ -1822,5 +1920,17 @@ #define PLX9056_DEVICE_ID 0x9056 +#ifdef BCM_LTSW_SUPPORT +#define BCM56880_DEVICE_ID 0xb880 +#define BCM56880_A0_REV_ID 0x0001 +#define BCM56880_B0_REV_ID 0x0011 +#define BCM56881_DEVICE_ID 0xb881 +#define BCM56881_A0_REV_ID 0x0001 +#define BCM56881_B0_REV_ID 0x0011 +#define BCM56883_DEVICE_ID 0xb883 +#define BCM56883_A0_REV_ID 0x0001 +#define BCM56883_B0_REV_ID 0x0011 + +#endif #endif diff --git a/platform/broadcom/saibcm-modules/make/Make.linux b/platform/broadcom/saibcm-modules/make/Make.linux index bd86ca351b6e..81e88daf16bc 100644 --- a/platform/broadcom/saibcm-modules/make/Make.linux +++ b/platform/broadcom/saibcm-modules/make/Make.linux @@ -85,7 +85,7 @@ endif build: $(MAKE) $(CMD) -DELIVER clean C_COMPILER CXX_COMPILER variable mod bcm user: +DELIVER clean C_COMPILER CXX_COMPILER variable mod bcm user issu: $(MAKE) $(CMD) $@ clean_d: clean @@ -93,5 +93,5 @@ clean_d: clean distclean: $(MAKE) $(CMD) $@ -.PHONY: build clean distclean clean_d DELIVER variable mod bcm user +.PHONY: build clean distclean clean_d DELIVER variable mod bcm user issu diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto index 786b4cc26bc3..4a20a99dac69 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto @@ -97,6 +97,21 @@ ifdef SHADOW_PLX CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE -DSHADOW_SVK endif +ifdef LTSW_CHIPS +# Default open source target build +OPENSRC_BUILD ?= uclibc_201402_ppc + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif + +export SYSTEM_INTERFACE +endif + ifeq (,$(KFLAGS)) KFLAGS := -D__KERNEL__ -m32 -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/uapi/linux/version.h -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/powerpc -I$(KERNDIR)/arch/powerpc/include -I$(KERNDIR)/include/asm-powerpc -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -msoft-float -pipe -ffixed-r2 -mmultiple -mno-altivec -funit-at-a-time -Wa,-me500 -fomit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gts b/platform/broadcom/saibcm-modules/make/Makefile.linux-gts new file mode 100644 index 000000000000..ddc94afa13fe --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gts @@ -0,0 +1,142 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# $Id: Makefile.linux-xlr-4_19,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# XLR system make file. +# +# Most of this was taken from target x86-smp_generic_64-2_6. +# + + +############################################################################# +# this segment is custom and not sourced from any existing makefile # +# (base thanks to http:confluence.broadcom.com/display/NTSWSW/X86+System) # +############################################################################# + +# set up a basic feature list. tcl, etc. # +#ifeq (,$(FEATURE_LIST)) +#FEATURE_LIST = TCL BFD PTP CINT L3 I2C MEM_SCAN EDITLINE BCM_SAL_PROFILE CUSTOMER TEST CHASSIS MSTP RCPU +#endif + +# some basic path variables for tools and kernel source, etc # +export XLR_TOOLS_BASE = /projects/ntsw-tools/linux/xlr-419 +TOOLCHAIN_DIR = $(XLR_TOOLS_BASE)/buildroot/host/usr +KERNDIR = $(XLR_TOOLS_BASE)/kernel/linux + +# set up cross compile prefix, tools dir variables. # +export CROSS_COMPILE := x86_64-broadcom-linux-gnu- +export TOOLS_DIR := $(TOOLCHAIN_DIR)/bin + +# architecture. # +ARCH = x86_64 +TARGET_ARCHITECTURE = x86_64-broadcom-linux-gnu + +# Noisy kernel build +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +# set up paths. # +export LIBRARY_PATH := $(TOOLCHAIN_DIR)/lib:$(TOOLCHAIN_DIR)/lib64:$(LIBRARY_PATH) +export PATH := $(TOOLCHAIN_DIR)/bin:$(KERNDIR):$(PATH) + +# set up SYSINC path # +export SYSINC := $(XLR_TOOLS_BASE)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/5.4.0/include + + +# CFLAGS/CFGFLAGS # +CFLAGS += -DUSE_LINUX_BDE_MMAP=1 +#CFLAGS += -DBDE_LINUX_USE_MSI_INTERRUPT +CFLAGS += -Wno-error=unused-value +CFLAGS += -Wno-error=unused-but-set-variable +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=cpp +CFLAGS += -Wno-error=aggressive-loop-optimizations +CFLAGS += -Wno-error=array-bounds +CFLAGS += -Wno-error=strict-overflow +CFLAGS += -L$(TOOLCHAIN_DIR)/lib +CFLAGS += -L$(TOOLCHAIN_DIR)/lib64 +#CFLAGS += -Wl,--rpath=/lib64 # may need to set rpath and dynamic-linker path here (and possibly in KLFAGS below) in the future, # +#CFLAGS += -Wl,--dynamic-linker=/lib64/ld-linux-x86-64.so.2 # if we want to build the target executable to be used with shared libs # + +#XLDK-568 fix inline references +CFGFLAGS += -fgnu89-inline + + +# set up KFLAGS appropriately. # +ifeq (,$(KFLAGS)) +KFLAGS := -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib64 -I$(KERNDIR) -lc -nostdinc -isystem $(SYSINC) -Iinclude -I$(KERNDIR)/arch/x86/include -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/generated/uapi -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/include -I$(KERNDIR)/include/generated -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/include/uapi -include $(KERNDIR)/include/generated/autoconf.h -D__KERNEL__ -DNDEBUG -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -Wframe-larger-than=1024 -fno-omit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-dwarf2-cfi-asm -fconserve-stack +endif + + +###################################################################### +# this segment comes from make/Makefile.linux-x86-smp_generic_64-2_6 # +###################################################################### +CFGFLAGS += -DLONGS_ARE_64BITS +CFGFLAGS += -DPTRS_ARE_64BITS +CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ + + +############################################################## +# This segment comes from make/Makefile.linux-x86-common-2_6 # +############################################################## +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +CFGFLAGS += -D$(ENDIAN) +CFGFLAGS += -DBCM_PLATFORM_STRING=\"X86\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32 + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ +-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +ifdef LTSW_CHIPS +# Ensure we do not use an out-of-date libelf.so +ELFUTILS_MIN = 158 +ELFUTILS_DIR ?= /projects/ntsw-tools/lib + +# Default open source target build +OPENSRC_BUILD ?= fed21-x86_64 + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif + +export SYSTEM_INTERFACE +endif + +ifneq ($(targetplat),user) +# By default we exclude -Werror from x86 kernel builds +BCM_CFLAGS = -Wall +include ${SDK}/make/Makefile.linux-kernel-2_6 +endif + + diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc index 092e474e2563..7d8adb98de38 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc @@ -27,11 +27,14 @@ endif # TARGET_ARCHITECTURE Compiler for target architecture # KERNDIR Kernel directory for iPROC-CMICd devices ifeq (BE,$(ENDIAN_MODE)) +#While BE mode is supported, it's use is very limited. We had a specific customer +#request for BE support but don't currently mainstream it. So a 5.1.0 version +#has not been built. Continue using 5.0.3 for any BE support TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50-be/XLDK32 TARGET_ARCHITECTURE:=armeb-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux else -TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50/XLDK32 +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51/XLDK32 TARGET_ARCHITECTURE:= arm-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux endif @@ -44,9 +47,10 @@ endif TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/bin override PATH:=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/$(TARGET_ARCHITECTURE)/bin:$(TOOLCHAIN_BIN_DIR):$(PATH) LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib - export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH +CROSS_GCC_VER ?= $(shell $(TOOLCHAIN_BIN_DIR)/$(CROSS_COMPILE)gcc -dumpversion) + # Default Linux include directory ifeq (,$(LINUX_INCLUDE)) LINUX_INCLUDE := $(KERNDIR)/include @@ -61,6 +65,12 @@ ENDIAN = LE_HOST=1 endif CFLAGS += -fno-aggressive-loop-optimizations +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=array-bounds +CFLAGS += -fgnu89-inline +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 7)" "1" + CFLAGS += -Wno-error=bool-operation +endif CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" @@ -82,7 +92,7 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") -KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.4/include +KFLAG_INCLD ?= $(LD_LIBRARY_PATH)/gcc/$(TARGET_ARCHITECTURE)/$(CROSS_GCC_VER)/include ifeq (,$(KFLAGS)) KFLAGS := -D__LINUX_ARM_ARCH__=7 -D__KERNEL__ -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm/include -I$(KERNDIR)/arch/arm/include/generated -I$(KERNDIR)/arch/arm/mach-iproc/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -marm -mabi=aapcs-linux -fno-pic -pipe -msoft-float -ffreestanding -march=armv7-a -mfpu=vfp -mfloat-abi=softfp -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mlong-calls diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-4_4 b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-4_4 new file mode 100644 index 000000000000..df31f84e9d8f --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-4_4 @@ -0,0 +1,92 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# $Id: Makefile.linux-iproc Exp $ +# $Copyright: (c) 2007 Broadcom Corp. +# All Rights Reserved.$ +# Makefile for iproc-CMICd + +# User must select one platform from below.By default ARM_LINUX is selected. . +ifeq (,$(BUILD_PLATFORM)) +BUILD_PLATFORM=ARM_LINUX +endif + +# TOOLCHAIN_BASE_DIR Toolchain base directory for iPROC-CMICd devices +# TARGET_ARCHITECTURE Compiler for target architecture +# KERNDIR Kernel directory for iPROC-CMICd devices +ifeq (BE,$(ENDIAN_MODE)) +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk40-be/XLDK +TARGET_ARCHITECTURE:=armeb-broadcom-linux-uclibcgnueabi +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +else +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk40/XLDK +TARGET_ARCHITECTURE:= arm-broadcom-linux-uclibcgnueabi +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +endif + +ifeq (,$(CROSS_COMPILE)) +CROSS_COMPILE:= $(TARGET_ARCHITECTURE)- +endif + +# arm9tools +TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/bin +override PATH:=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/$(TARGET_ARCHITECTURE)/bin:$(TOOLCHAIN_BIN_DIR):$(PATH) +LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib + +export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH + +# Default Linux include directory +ifeq (,$(LINUX_INCLUDE)) +LINUX_INCLUDE := $(KERNDIR)/include +endif + +ifeq (BE,$(ENDIAN_MODE)) +CFGFLAGS += -DSYS_BE_PIO=1 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=1 +ENDIAN = BE_HOST=1 +else +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +endif + +CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD +CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" + +ARCH = arm +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ + -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.3/include + +ifeq (,$(KFLAGS)) +KFLAGS := -D__LINUX_ARM_ARCH__=7 -D__KERNEL__ -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm/include -I$(KERNDIR)/arch/arm/include/generated -I$(KERNDIR)/arch/arm/mach-iproc/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -marm -mabi=aapcs-linux -fno-pic -pipe -msoft-float -ffreestanding -march=armv7-a -mfpu=vfp -mfloat-abi=softfp -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mlong-calls +KFLAGS += -I$(LINUX_INCLUDE)/uapi -I$(LINUX_INCLUDE)/generated/uapi -I$(KERNDIR)/arch/arm/include/uapi -I$(KERNDIR)/arch/arm/include/generated/uapi +endif + +ifneq ($(targetplat),user) +include ${SDK}/make/Makefile.linux-kernel-3_6 +endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 new file mode 100644 index 000000000000..dbccd7e25734 --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 @@ -0,0 +1,106 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# $Id: Makefile.linux-iproc Exp $ +# $Copyright: (c) 2007 Broadcom Corp. +# All Rights Reserved.$ +# Makefile for iproc-CMICd + +# User must select one platform from below.By default ARM_LINUX is selected. . +ifeq (,$(BUILD_PLATFORM)) +BUILD_PLATFORM=ARM_LINUX +endif + +# TOOLCHAIN_BASE_DIR Toolchain base directory for iPROC-CMICd devices +# TARGET_ARCHITECTURE Compiler for target architecture +# KERNDIR Kernel directory for iPROC-CMICd devices +ifeq (BE,$(ENDIAN_MODE)) +#We've never actually built a 64 BE executable. Just here for any future +#customer requirements. +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51-be/XLDK64 +TARGET_ARCHITECTURE ?= aarch64_be-broadcom-linux-uclibc +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +else +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51/XLDK64 +TARGET_ARCHITECTURE ?= aarch64-broadcom-linux-uclibc +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +endif + +ifeq (,$(CROSS_COMPILE)) +CROSS_COMPILE:= $(TARGET_ARCHITECTURE)- +endif + +# A72 tools +TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/bin +override PATH:=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/$(TARGET_ARCHITECTURE)/bin:$(TOOLCHAIN_BIN_DIR):$(PATH) +LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib +export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH + +CROSS_GCC_VER ?= $(shell $(TOOLCHAIN_BIN_DIR)/$(CROSS_COMPILE)gcc -dumpversion) + +# Default Linux include directory +ifeq (,$(LINUX_INCLUDE)) +LINUX_INCLUDE := $(KERNDIR)/include +endif + +ifeq (BE,$(ENDIAN_MODE)) +CFGFLAGS += -DSYS_BE_PIO=1 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=1 +ENDIAN = BE_HOST=1 +else +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +endif + +CFLAGS += -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS +CFLAGS += -DPHYS_ADDRS_ARE_64BITS +CFLAGS += -fno-aggressive-loop-optimizations -fno-strict-overflow +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=array-bounds +CFLAGS += -fgnu89-inline +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 7)" "1" + CFLAGS += -Wno-error=bool-operation +endif + + +CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD +CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=16 + +ARCH = arm64 +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ + -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +KFLAG_INCLD ?= $(LD_LIBRARY_PATH)/gcc/$(TARGET_ARCHITECTURE)/$(CROSS_GCC_VER)/include + +ifeq (,$(KFLAGS)) +KFLAGS := -D__LINUX_ARM_ARCH__=8 -D__KERNEL__ -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm64/include -I$(KERNDIR)/arch/arm64/include/generated -I$(KERNDIR)/arch/arm64/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/generated/asm -I$(KERNDIR)/include/uapi -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/uapi -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -fno-pic -pipe -ffreestanding -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mcmodel=large +endif + +ifneq ($(targetplat),user) +include ${SDK}/make/Makefile.linux-kernel-3_6 +endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-slk b/platform/broadcom/saibcm-modules/make/Makefile.linux-slk new file mode 100644 index 000000000000..00131c2f2af9 --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-slk @@ -0,0 +1,146 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# $Id: Makefile.linux-slk-3_14,v 1.2 Broadcom SDK $ +# $Copyright: (c) 2013 Broadcom Corp. +# All Rights Reserved.$ +# Makefile for SLK(BCM957812) + +# User must select one platform from below.By default ARM_LINUX is selected. . +ifeq (,$(BUILD_PLATFORM)) +BUILD_PLATFORM=ARM_LINUX +endif + +# Toolchain base directory for NS2 XMC card +ifeq (BE,$(ENDIAN_MODE)) +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/toolchains/slk/linaro-be +TARGET_ARCHITECTURE:=aarch64_be-linux-gnu +KERNDIR ?= /projects/ntsw-tools/linux/iproc_ldks/slk-be/poky/brcm-released-source/git +else +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/toolchains/slk/linaro-le +# Compiler for target architecture +TARGET_ARCHITECTURE:= aarch64-linux-gnu +# Kernel directory +KERNDIR ?= /projects/ntsw-tools/linux/iproc_ldks/slk/poky/brcm-released-source/git +endif + +ifeq (,$(CROSS_COMPILE)) +CROSS_COMPILE:= $(TARGET_ARCHITECTURE)- +endif + +# armtools +TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/bin +override PATH:=$(TOOLCHAIN_BIN_DIR):$(PATH) +LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/lib + +export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH + +# Default Linux include directory +ifeq (,$(LINUX_INCLUDE)) +LINUX_INCLUDE := $(KERNDIR)/include +endif + +ifeq (BE,$(ENDIAN_MODE)) +CFGFLAGS += -DSYS_BE_PIO=1 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=1 +ENDIAN = BE_HOST=1 +else +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +endif + +CFGFLAGS += -D$(ENDIAN) -DBCM958525 +CFGFLAGS += -DBCM_PLATFORM_STRING=\"SLK_BCM957812\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32 +ifeq (1,$(SLK_32BIT)) +CFGFLAGS += -DSAL_BDE_32BIT_USER_64BIT_KERNEL +else +CFGFLAGS += -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS +endif +CFGFLAGS += -DPHYS_ADDRS_ARE_64BITS + +CFLAGS += -Wno-unused-value -Wno-unused-but-set-variable -Wno-sizeof-pointer-memaccess -fno-aggressive-loop-optimizations + +ifdef DPP_CHIPS +CFLAGS += -DDUNE_BCM -D__DUNE_LINUX_BCM_CPU_PCP_DMA__ +CFGFLAGS += -DSOC_CM_FUNCTION +endif + +ifdef DFE_CHIPS +CFLAGS += -DDUNE_BCM +CFGFLAGS += -DSOC_CM_FUNCTION +endif + +ifdef SAND_CHIPS +CFLAGS += -D__DUNE_SLK_BCM_CPU__ -D__DUNE_LINUX_BCM_CPU_PCIE__ +endif + +# Enable cached DMA memory by default +ifeq (,$(SAL_BDE_USE_CACHED_DMA_MEM)) +SAL_BDE_USE_CACHED_DMA_MEM = 1 +endif +ifeq ($(SAL_BDE_USE_CACHED_DMA_MEM),1) +CFGFLAGS += -DSAL_BDE_CACHE_DMA_MEM +endif + +ifeq (1,$(SLK_32BIT)) +ARCH = arm +else +ARCH = arm64 +endif + +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ + -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +KFLAG_INCLD = $(TOOLCHAIN_BASE_DIR)/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.2/include + +ifeq (,$(KFLAGS)) +KFLAGS := -D__LINUX_ARM_ARCH__=8 -D__KERNEL__ -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm64/include -I$(KERNDIR)/arch/arm64/include/generated -I$(KERNDIR)/arch/arm64/include/generated/asm -I$(KERNDIR)/include/uapi -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/uapi -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -fno-pic -pipe -ffreestanding -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign +endif + +ifdef LTSW_CHIPS +# Default open source target build +ifeq (BE,$(ENDIAN_MODE)) +OPENSRC_BUILD ?= linaro_arm64_be +else +OPENSRC_BUILD ?= linaro_arm64_le +endif + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif + +export SYSTEM_INTERFACE +endif + +ifneq ($(targetplat),user) +include ${SDK}/make/Makefile.linux-kernel-3_6 +endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 index bf0ea85d578e..b443a3d4733d 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 @@ -48,4 +48,5 @@ AUTOCONF = $(KERNDIR)/include/linux/autoconf.h endif # gcc system include path +# SAI_FIXUP /* SDK-218654 */ SYSINC = $(shell $(CC) -print-search-dirs | grep install | cut -c 10-)include diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 index bc0230ec8226..8a97f3954301 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 @@ -29,17 +29,33 @@ KFLAGS := -nostdinc -isystem $(SYSINC) -I$(KERNDIR)/include -I$(KERNDIR)/arch/x8 endif ifeq ($(LINUX_MAKE_SHARED_LIB), 1) -KFLAGS += -fPIC -mcmodel=small + KFLAGS += -fPIC -mcmodel=small else -KFLAGS += -fno-pie -mcmodel=kernel + KFLAGS += -fno-pie -mcmodel=kernel endif LINUX_UAPI = $(LINUX_INCLUDE)/uapi +ifneq (,$(shell ls $(LINUX_UAPI) 2>/dev/null)) KFLAGS += -I$(LINUX_INCLUDE)/uapi -I$(LINUX_INCLUDE)/generated/uapi -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/arch/x86/include/generated/uapi +endif + +ifdef LTSW_CHIPS +# Ensure we do not use an out-of-date libelf.so +ELFUTILS_MIN = 158 +ELFUTILS_DIR ?= /projects/ntsw-tools/lib + +# Default open source target build +OPENSRC_BUILD ?= x86_64 + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif -ifeq (1,$(DEBIAN_LINUX_HEADER)) -KERNDIR_COMMON := $(subst amd64,common,$(KERNDIR)) -KFLAGS += -I$(KERNDIR_COMMON)/include -I$(KERNDIR_COMMON)/include/uapi -I$(KERNDIR_COMMON)/arch/x86/include -I$(KERNDIR_COMMON)/arch/x86/include/uapi +export SYSTEM_INTERFACE endif include ${SDK}/make/Makefile.linux-x86-common-2_6 diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr b/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr new file mode 100644 index 000000000000..ddc94afa13fe --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr @@ -0,0 +1,142 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# $Id: Makefile.linux-xlr-4_19,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# XLR system make file. +# +# Most of this was taken from target x86-smp_generic_64-2_6. +# + + +############################################################################# +# this segment is custom and not sourced from any existing makefile # +# (base thanks to http:confluence.broadcom.com/display/NTSWSW/X86+System) # +############################################################################# + +# set up a basic feature list. tcl, etc. # +#ifeq (,$(FEATURE_LIST)) +#FEATURE_LIST = TCL BFD PTP CINT L3 I2C MEM_SCAN EDITLINE BCM_SAL_PROFILE CUSTOMER TEST CHASSIS MSTP RCPU +#endif + +# some basic path variables for tools and kernel source, etc # +export XLR_TOOLS_BASE = /projects/ntsw-tools/linux/xlr-419 +TOOLCHAIN_DIR = $(XLR_TOOLS_BASE)/buildroot/host/usr +KERNDIR = $(XLR_TOOLS_BASE)/kernel/linux + +# set up cross compile prefix, tools dir variables. # +export CROSS_COMPILE := x86_64-broadcom-linux-gnu- +export TOOLS_DIR := $(TOOLCHAIN_DIR)/bin + +# architecture. # +ARCH = x86_64 +TARGET_ARCHITECTURE = x86_64-broadcom-linux-gnu + +# Noisy kernel build +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +# set up paths. # +export LIBRARY_PATH := $(TOOLCHAIN_DIR)/lib:$(TOOLCHAIN_DIR)/lib64:$(LIBRARY_PATH) +export PATH := $(TOOLCHAIN_DIR)/bin:$(KERNDIR):$(PATH) + +# set up SYSINC path # +export SYSINC := $(XLR_TOOLS_BASE)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/5.4.0/include + + +# CFLAGS/CFGFLAGS # +CFLAGS += -DUSE_LINUX_BDE_MMAP=1 +#CFLAGS += -DBDE_LINUX_USE_MSI_INTERRUPT +CFLAGS += -Wno-error=unused-value +CFLAGS += -Wno-error=unused-but-set-variable +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=cpp +CFLAGS += -Wno-error=aggressive-loop-optimizations +CFLAGS += -Wno-error=array-bounds +CFLAGS += -Wno-error=strict-overflow +CFLAGS += -L$(TOOLCHAIN_DIR)/lib +CFLAGS += -L$(TOOLCHAIN_DIR)/lib64 +#CFLAGS += -Wl,--rpath=/lib64 # may need to set rpath and dynamic-linker path here (and possibly in KLFAGS below) in the future, # +#CFLAGS += -Wl,--dynamic-linker=/lib64/ld-linux-x86-64.so.2 # if we want to build the target executable to be used with shared libs # + +#XLDK-568 fix inline references +CFGFLAGS += -fgnu89-inline + + +# set up KFLAGS appropriately. # +ifeq (,$(KFLAGS)) +KFLAGS := -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib64 -I$(KERNDIR) -lc -nostdinc -isystem $(SYSINC) -Iinclude -I$(KERNDIR)/arch/x86/include -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/generated/uapi -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/include -I$(KERNDIR)/include/generated -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/include/uapi -include $(KERNDIR)/include/generated/autoconf.h -D__KERNEL__ -DNDEBUG -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -Wframe-larger-than=1024 -fno-omit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-dwarf2-cfi-asm -fconserve-stack +endif + + +###################################################################### +# this segment comes from make/Makefile.linux-x86-smp_generic_64-2_6 # +###################################################################### +CFGFLAGS += -DLONGS_ARE_64BITS +CFGFLAGS += -DPTRS_ARE_64BITS +CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ + + +############################################################## +# This segment comes from make/Makefile.linux-x86-common-2_6 # +############################################################## +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +CFGFLAGS += -D$(ENDIAN) +CFGFLAGS += -DBCM_PLATFORM_STRING=\"X86\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32 + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ +-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +ifdef LTSW_CHIPS +# Ensure we do not use an out-of-date libelf.so +ELFUTILS_MIN = 158 +ELFUTILS_DIR ?= /projects/ntsw-tools/lib + +# Default open source target build +OPENSRC_BUILD ?= fed21-x86_64 + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif + +export SYSTEM_INTERFACE +endif + +ifneq ($(targetplat),user) +# By default we exclude -Werror from x86 kernel builds +BCM_CFLAGS = -Wall +include ${SDK}/make/Makefile.linux-kernel-2_6 +endif + + diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile index aedd487b1f11..cfd72d3a9216 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile @@ -55,14 +55,16 @@ THIS_MOD_NAME := linux-kernel-bde MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko -build: kernel_libs $(MODULE) $(KMODULE) +build: kernel_libs module $(KMODULE) else MODULE = $(LIBDIR)/linux-kernel-bde.o -build: kernel_libs $(MODULE) +build: kernel_libs module endif -$(MODULE): $(BLDDIR)/.tree kernel_libs $(BOBJS) +module: kernel_libs $(MODULE) + +$(MODULE): $(BLDDIR)/.tree $(BOBJS) mkdir -p $(@D) $(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@ ifneq ($(kernel_version),2_4) diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c index 464a72bd3e41..3a60ac4dd54e 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c @@ -1,25 +1,21 @@ /* * Copyright 2017 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ + /* - * $Id: linux-kernel-bde.c,v 1.414 Broadcom SDK $ - * $Copyright: (c) 2005 Broadcom Corp. - * All Rights Reserved.$ - * * Linux Kernel BDE - * */ #include @@ -30,27 +26,32 @@ #include #include #include -#include #include #include "linux_shbde.h" +#define MEMCPY memcpy -#ifdef __GNUC__ -#if __GNUC__ == 8 +#ifdef CONFIG_X86_64 +#if (defined(__GNUC__) && (__GNUC__ == 8)) /* * Prevent gcc 8.1.10 using a compiler inline memcpy even if using -fno-builtin or * -fno-builtin-memcpy . * __inline_memcpy and __memcpy are kernel functions that may be used instead, * for either an inline or non-inline implementations of the function */ -#define MEMCPY __inline_memcpy -#else -#define MEMCPY memcpy -#endif /* __GNUC__ == 8 */ -#else /* ifdef __GNUC__ */ -#define MEMCPY memcpy -#endif /* ifdef __GNUC__ */ +#undef MEMCPY +#define MEMCPY __memcpy +#endif /* (defined(__GNUC__) && (__GNUC__ == 8)) */ +#endif /* CONFIG_X86_64 */ + + +#if defined(CMIC_SOFT_BYTE_SWAP) +#define CMIC_SWAP32(_x) ((((_x) & 0xff000000) >> 24) \ + | (((_x) & 0x00ff0000) >> 8) \ + | (((_x) & 0x0000ff00) << 8) \ + | (((_x) & 0x000000ff) << 24)) +#endif /* defined(CMIC_SOFT_BYTE_SWAP) */ #define PCI_USE_INT_NONE (-1) #define PCI_USE_INT_INTX (0) @@ -68,8 +69,15 @@ MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Kernel BDE"); MODULE_LICENSE("GPL"); -/* PCIe max payload */ -int maxpayload = 256; +/* + * PCIe max payload size in bytes. + * The default value if not specified to the kernel module by maxpayload is historically 256. + * The default value may be changed using the BDE_PCIE_MAXPAYLOAD_DEFAULT macro. + */ +#ifndef BDE_PCIE_MAXPAYLOAD_DEFAULT +#define BDE_PCIE_MAXPAYLOAD_DEFAULT 256 +#endif +int maxpayload = BDE_PCIE_MAXPAYLOAD_DEFAULT; LKM_MOD_PARAM(maxpayload, "i", int, 0); MODULE_PARM_DESC(maxpayload, "Limit maximum payload size and request size on PCIe devices"); @@ -256,6 +264,19 @@ struct bde_spi_device_id { uint32 spifreq; }; +/* Maximum number of I/O windows supported per device. */ +#define BDE_NUM_IOWIN_MAX 3 + +/* I/O memory window definition. */ +struct memwin_s { + + /* Physical address of I/O window. */ + resource_size_t addr; + + /* Size of I/O window (in bytes). */ + resource_size_t size; +}; + /* Control Data */ typedef struct bde_ctrl_s { struct list_head list; @@ -285,10 +306,7 @@ typedef struct bde_ctrl_s { struct device *dma_dev; #endif - /* Physical addresses */ - resource_size_t phys_address; - resource_size_t phys_address1; - resource_size_t phys_address2; + struct memwin_s iowin[BDE_NUM_IOWIN_MAX]; /* Secondary mapped base address */ sal_vaddr_t alt_base_addr; @@ -334,7 +352,7 @@ static int _cpu_ndevices = 0; #if defined(IPROC_CMICD) && defined(CONFIG_OF) #define ICFG_CHIP_ID_REG 0x10236000 -#define IHOST_CMICX_MAX_INTRS 128 +#define IHOST_CMICX_MAX_INTRS 129 static uint32 iproc_cmicx_irqs[IHOST_CMICX_MAX_INTRS]; #endif @@ -415,7 +433,7 @@ static void *cpu_address = NULL; /* PLX PCI-E Switch */ #define PLX_PEX8608_DEV_ID 0x8608 #define PLX_PEX8617_DEV_ID 0x8617 -#define PLX_PEX86XX_DEV_CTRL_REG 0x70 +#define PLX_PEX86XX_DEV_CTRL_REG 0x70 /* Broadcom BCM58525 */ #define BCM58525_PCI_VENDOR_ID 0x14E4 @@ -432,10 +450,11 @@ static void *cpu_address = NULL; #define IHOST_GICD_REG_ADDR_VALID(d, addr) \ (_devices[d].bde_dev.base_address1 && \ - (addr & 0xFFFFFF00) == _devices[d].phys_address1) + (addr & 0xFFFFFF00) == _devices[d].iowin[1].addr) #define IHOST_GICD_REG_ADDR_REMAP(d, addr) \ - (void *)(_devices[d].bde_dev.base_address1 + (addr - _devices[d].phys_address1)) + (void *)(_devices[d].bde_dev.base_address1 + \ + (addr - ((sal_vaddr_t)_devices[d].iowin[1].addr))) static uint32_t _read(int d, uint32_t addr); @@ -554,7 +573,8 @@ _eb_device_create(resource_size_t paddr, int irq, int rd_hw, int wr_hw) /* Map in the device */ ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(paddr, 0x10000); - ctrl->phys_address = paddr; + ctrl->iowin[0].addr = paddr; + ctrl->iowin[0].size = 0x10000; dev_rev_id = _read(dev_id, 0x178); /* CMIC_DEV_REV_ID */ @@ -590,7 +610,8 @@ sand_device_create(void) /* Map in the device */ /* FIX_ME: not realy map anything */ ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(0x40000000, 0x100000); - ctrl->phys_address = 0x40000000; + ctrl->iowin[0].addr = 0x40000000; + ctrl->iowin[0].size = 0x100000; ctrl->iLine = 0; ctrl->isr = NULL; @@ -695,7 +716,8 @@ iproc_cmicd_probe(struct platform_device *pldev) gprintk("Error mapping iProc CMIC registers"); return -1; } - ctrl->phys_address = memres->start; + ctrl->iowin[0].addr = memres->start; + ctrl->iowin[0].size = size; #ifdef CONFIG_OF if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { @@ -712,16 +734,18 @@ iproc_cmicd_probe(struct platform_device *pldev) memres = iproc_platform_get_resource(pldev, IORESOURCE_MEM, 1); if (memres) { ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(memres->start, memres->end - memres->start + 1); - ctrl->phys_address1 = memres->start; + ctrl->iowin[1].addr = memres->start; + ctrl->iowin[1].size = memres->end - memres->start + 1; } else { /* Use default address if not available in DTB */ ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(IHOST_GICD_REG_ADDR, IHOST_GICD_REG_REMAP_LEN); - ctrl->phys_address1 = IHOST_GICD_REG_ADDR; + ctrl->iowin[1].addr = IHOST_GICD_REG_ADDR; + ctrl->iowin[1].size = IHOST_GICD_REG_REMAP_LEN; } if (ctrl->bde_dev.base_address1) { if (debug >= 1) { gprintk("base_address1:0x%lx phys_address1:0x%lx\n", - (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)ctrl->phys_address1); + (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)ctrl->iowin[1].addr); } } else { gprintk("Error mapping ihost GICD registers\n"); @@ -753,9 +777,12 @@ iproc_cmicd_probe(struct platform_device *pldev) #ifdef CONFIG_OF if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { int i; + memset(iproc_cmicx_irqs, 0, IHOST_CMICX_MAX_INTRS*sizeof(uint32_t)); for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { irqres = iproc_platform_get_resource(pldev, IORESOURCE_IRQ, i); - iproc_cmicx_irqs[i] = irqres->start; + if (irqres) { + iproc_cmicx_irqs[i] = irqres->start; + } if (debug >= 1) { gprintk("iproc_cmicx_irqs[%d] = %d\n", i, iproc_cmicx_irqs[i]); } @@ -1019,7 +1046,8 @@ _ics_bde_create(void) /* Map in the device */ paddr = BCM_ICS_CMIC_BASE; ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(paddr, 0x10000); - ctrl->phys_address = paddr; + ctrl->iowin[0].addr = paddr; + ctrl->iowin[0].size = 0x10000; dev_rev_id = *((unsigned int *)(KSEG1ADDR(paddr + 0x178))); @@ -1399,6 +1427,8 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56174_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53570_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53575_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56070_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56071_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9656, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, PCI_ANY_ID, PCI_ANY_ID }, { BCM53000_VENDOR_ID, BCM53000PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1463,6 +1493,7 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88683_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88684_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88685_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88687_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88380_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88381_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88202_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1493,8 +1524,38 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM8869B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8869C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8869D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8869F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88800_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88821_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88826_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88802_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88803_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88804_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88805_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88806_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88820_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88822_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88823_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88824_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88825_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88480_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88481_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88482_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88483_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88484_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88485_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88486_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88487_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88488_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88489_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848A_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88850_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, #endif /* BCM_DNX_SUPPORT */ #ifdef BCM_DFE_SUPPORT { BROADCOM_VENDOR_ID, BCM88750_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1546,6 +1607,12 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56832_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56836_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56870_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56273_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56274_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56275_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56276_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56277_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56278_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56370_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56371_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56372_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1568,6 +1635,9 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM53547_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53548_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53549_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56470_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56471_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56472_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { 0, 0, 0, 0 } };; @@ -2180,7 +2250,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) resource_size_t paddr; uint16 cmd = 0; uint32 bar_len; - int cmic_bar; + int i, cmic_bar; int baroff = 0; int iproc = 0; int plx_dev = 0; @@ -2219,7 +2289,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } } #endif /* IPROC_CMICD */ - + /* * Note that a few supported devices have a non-Broadcom PCI vendor ID, * but since none of their associated PCI device IDs collide with the @@ -2441,7 +2511,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) ((PCI_FIND_DEV(BCM58525_PCI_VENDOR_ID, BCM58522_PCI_DEVICE_ID, NULL)) != NULL) || ((PCI_FIND_DEV(BCM58712_PCI_VENDOR_ID, BCM58712_PCI_DEVICE_ID, NULL)) != NULL) ) { /* BCM58525/BCM58712 CPU boards support 128 Max payload size */ - if (maxpayload) { + if (maxpayload && maxpayload != 128) { maxpayload = 128; if (debug >= 1) gprintk("force max payload size to 128\n"); } @@ -2500,19 +2570,6 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } #endif /* BCM_DFE_SUPPORT */ -#if defined(BCM_DNXF_SUPPORT) - /*All Ramon devices from 0x8790 to 0x879F*/ - if ((dev->device & BCM_DNXF_DEVID_MASK) == BCM88790_DEVICE_ID) { - /* - * For DMA transactions - set Max_Payload_Size and - * Max_Read_Request_Size to 128 bytes. - */ - pci_write_config_byte(dev, 0xb5, 0x0c); - pci_write_config_byte(dev, 0xb4, 0x0); - - } -#endif - /* Prevent compiler warning */ if (ctrl == NULL) { return 0; @@ -2523,6 +2580,15 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) ctrl->pci_device = dev; pci_set_drvdata(dev, ctrl); + /* + * Sample setting of unique ID, used the PCIe address of the device: + * domain, bus, slot, function in hex digits: DDDDBBSS (SS includes the slot/device and function. + * Tested with old kernels from 2.6 . + * Do not use the PCI_DEVID macro which old kernel versions don't have. */ + ctrl->bde_dev.dev_unique_id = dev->bus ? + (((uint32)pci_domain_nr(dev->bus)) << 16) ^ (((uint32)dev->bus->number) << 8) ^ dev->devfn : + dev->devfn; + /* Check for iProc device */ if (shbde_pci_is_iproc(shbde, dev, &cmic_bar)) { iproc = 1; @@ -2557,13 +2623,21 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(paddr, bar_len); - ctrl->phys_address = paddr; + ctrl->iowin[0].addr = paddr; + ctrl->iowin[0].size = bar_len; + if (debug >= 3) { gprintk("BAR %d: kernel addr:0x%lx phys addr:0x%lx length:%lx\n", baroff, (unsigned long)ctrl->bde_dev.base_address, (unsigned long)paddr, (unsigned long)bar_len); } /* Map secondary address spaces */ + for (i = 1; i < BDE_NUM_IOWIN_MAX; i++) { + ctrl->iowin[i].addr = 0; + ctrl->iowin[i].size = 0; + } + ctrl->bde_dev.base_address1 = 0; + if (iproc #ifdef DNX_TEST_BOARD || (dev->device == PLX9056_DEVICE_ID && baroff == 2) @@ -2572,7 +2646,8 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) paddr = pci_resource_start(dev, 0); bar_len = pci_resource_len(dev, 0); ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(paddr, bar_len); - ctrl->phys_address1 = paddr; + ctrl->iowin[1].addr = paddr; + ctrl->iowin[1].size = bar_len; if (debug >= 3) { gprintk("BAR 0: kernel addr:0x%lx phys addr:0x%lx length:%lx\n", (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)paddr, (unsigned long)bar_len); @@ -2773,7 +2848,8 @@ map_local_bus(uint64_t addr, uint32_t size) /* Map in the device */ ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(addr, size); - ctrl->phys_address = addr; + ctrl->iowin[0].addr = addr; + ctrl->iowin[0].size = size; _bde_add_device(); return(ctrl); @@ -2817,7 +2893,8 @@ map_local_bus2(bde_ctrl_t *plx_ctrl, uint32_t dev_base, uint32_t size) /* Map in the device */ ctrl->bde_dev.base_address = plx_ctrl->bde_dev.base_address + dev_base; - ctrl->phys_address = plx_ctrl->phys_address + (resource_size_t)dev_base; + ctrl->iowin[0].addr = plx_ctrl->iowin[0].addr + (resource_size_t)dev_base; + ctrl->iowin[0].size = size; #if 1 addr = (uint8_t *)ctrl->bde_dev.base_address + PL0_REVISION_REG; @@ -2850,12 +2927,12 @@ probe_plx_local_bus(void) } addr_hi_str[0] = 0; #ifdef PHYS_ADDR_IS_64BIT - sprintf(addr_hi_str, "%08x", (uint32_t)(plx_ctrl.phys_address >> 32)); + sprintf(addr_hi_str, "%08x", (uint32_t)(plx_ctrl.iowin[0].addr >> 32)); #endif printk(KERN_ERR "Found PLX %04x:%04x vir: 0x%08x phy: 0x%s%08x\n", plx_ctrl.bde_dev.device, plx_ctrl.bde_dev.rev, plx_ctrl.bde_dev.base_address, addr_hi_str, - (uint32_t)(plx_ctrl.phys_address)); + (uint32_t)(plx_ctrl.iowin[0].addr)); addr = (uint8_t *)plx_ctrl.bde_dev.base_address + CPLD_OFFSET + CPLD_REVISION_REG; val = readl(addr); @@ -2947,9 +3024,9 @@ _init(void) } #else if (use_msi > PCI_USE_INT_INTX) { - /* Warn if invalid configuration */ - gprintk("MSI interrupts not supported by kernel\n"); - } + /* Warn if invalid configuration */ + gprintk("MSI interrupts not supported by kernel\n"); + } use_msi = PCI_USE_INT_INTX; #endif /* CONFIG_PCI_MSI */ @@ -3079,6 +3156,10 @@ _pprint(void) pprintf("Broadcom Device Enumerator (%s)\n", LINUX_KERNEL_BDE_NAME); + pprintf("Module parameters:\n"); + pprintf("\tmaxpayload=%d\n", maxpayload); + pprintf("\tusemsi=%d\n", usemsi); + _dma_pprint(); if (_ndevices == 0) { @@ -3134,7 +3215,7 @@ _pprint(void) pprintf("AXI Device 0x%x:0x%x:0x%.8lx:%d\n", ctrl->bde_dev.device, ctrl->bde_dev.rev, - (unsigned long)ctrl->phys_address, + (unsigned long)ctrl->iowin[0].addr, ctrl->iLine); } else if (ctrl->dev_type & BDE_EB_DEV_TYPE) { pprintf("EB Bus Device 0x%x:0x%x\n", @@ -3150,6 +3231,54 @@ _pprint(void) } return 0; } +/* + * Some kernels are configured to prevent mapping of kernel RAM memory + * into user space via the /dev/mem device. + * + * The function below provides a backdoor to map IO and DMA memory to + * user space via the BDE device file. + */ +static int +_bde_mmap(struct file *filp, struct vm_area_struct *vma) +{ + unsigned long paddr = vma->vm_pgoff << PAGE_SHIFT; + unsigned long size = vma->vm_end - vma->vm_start; + int i, j, pio_range_valid = 0; + + for(i = 0; i < _ndevices; i++) { + bde_ctrl_t *ctrl = _devices + i; + if (ctrl->dev_type & BDE_SWITCH_DEV_TYPE) { + for (j = 0; j < BDE_NUM_IOWIN_MAX; j++) { + if (paddr >= (unsigned long)ctrl->iowin[j].addr && + (paddr + size) <= (unsigned long)(ctrl->iowin[j].addr + ctrl->iowin[j].size)) { + pio_range_valid = 1; + break; + } + if ((ctrl->dev_type & BDE_AXI_DEV_TYPE) && (paddr == ctrl->iowin[j].addr)) { + pio_range_valid = 1; + break; + } + } + } + } + + if (pio_range_valid) { + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (remap_pfn_range(vma, + vma->vm_start, + vma->vm_pgoff, + size, + vma->vm_page_prot)) { + gprintk("Failed to mmap phys range 0x%lx-0x%lx to 0x%lx-0x%lx\n", + paddr, paddr + size, vma->vm_start,vma->vm_end); + return -EAGAIN; + } + return 0; + } + + return _dma_mmap(filp, vma); +} /* Workaround for broken Busybox/PPC insmod */ static char _modname[] = LINUX_KERNEL_BDE_NAME; @@ -3160,7 +3289,7 @@ static gmodule_t _gmodule = { init: _init, cleanup: _cleanup, pprint: _pprint, - mmap: _dma_mmap, + mmap: _bde_mmap, }; gmodule_t * @@ -3479,6 +3608,9 @@ _interrupt_connect(int d, if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { int i, j; for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + if (!iproc_cmicx_irqs[i]) { + continue; + } if (unlikely(debug >= 1)) gprintk("%s(%d):device# = %d, request_irq(%d)\n", __func__, __LINE__, d, iproc_cmicx_irqs[i]); @@ -3491,6 +3623,9 @@ _interrupt_connect(int d, } if (ret < 0) { for (j = 0; j < i; j++) { + if (!iproc_cmicx_irqs[j]) { + continue; + } free_irq(iproc_cmicx_irqs[j], ctrl); } goto err_disable_msi; @@ -3519,10 +3654,10 @@ _interrupt_connect(int d, msi_exit: #endif gprintk("could not request IRQ\n"); - ctrl->isr = NULL; - ctrl->isr_data = NULL; - ctrl->isr2 = NULL; - ctrl->isr2_data = NULL; + ctrl->isr = NULL; + ctrl->isr_data = NULL; + ctrl->isr2 = NULL; + ctrl->isr2_data = NULL; return -1; } @@ -3600,6 +3735,9 @@ _interrupt_disconnect(int d) if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { int i; for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + if (!iproc_cmicx_irqs[i]) { + continue; + } if (unlikely(debug > 1)) { gprintk("%s(%d):device# = %d, free_irq(%d)\n", __func__, __LINE__, d, iproc_cmicx_irqs[i]); @@ -3862,10 +4000,10 @@ lkbde_cpu_pci_register(int d) case BCM88683_DEVICE_ID: case BCM88684_DEVICE_ID: case BCM88685_DEVICE_ID: + case BCM88687_DEVICE_ID: case BCM88380_DEVICE_ID: case BCM88381_DEVICE_ID: case BCM88680_DEVICE_ID: - case BCM88800_DEVICE_ID: case BCM88470_DEVICE_ID: case BCM88470P_DEVICE_ID: case BCM88471_DEVICE_ID: @@ -3915,34 +4053,41 @@ lkbde_cpu_pci_register(int d) break; } + /* configure iproc >=14 devices by device family */ +#if defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) + switch (ctrl->bde_dev.device & DNXC_DEVID_FAMILY_MASK) { #ifdef BCM_DNX_SUPPORT - /*All Jericho 2 devices from 0x8690 to 0x869F*/ - if (SOC_IS_JERICHO_2_TYPE(ctrl->bde_dev.device)) { - /* Fix bar 0 address */ /* FIXME: write full phy address */ - pci_write_config_byte(ctrl->pci_device, 0x12, 0x10); - pci_write_config_byte(ctrl->pci_device, 0x13, 0x60); - + case JERICHO2_DEVICE_ID: + case J2C_DEVICE_ID: + case J2C_2ND_DEVICE_ID: + case Q2A_DEVICE_ID: + case J2P_DEVICE_ID: +#endif +#ifdef BCM_DNXF_SUPPORT + case BCM88790_DEVICE_ID: +#endif /* * For DMA transactions - set Max_Payload_Size and * Max_Read_Request_Size to 128 bytes. */ pci_write_config_byte(ctrl->pci_device, 0xb5, 0x0c); pci_write_config_byte(ctrl->pci_device, 0xb4, 0x0); + break; } -#endif +#endif /* defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) */ /* Redo ioremap */ if (ctrl->bde_dev.base_address) { iounmap((void *)ctrl->bde_dev.base_address); } - ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(ctrl->phys_address, 0x1000000); + ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(ctrl->iowin[0].addr, 0x1000000); if (debug >= 1) { gprintk("%s, %s(): info:\n", __FILE__, __FUNCTION__); gprintk("_ndevices=%d, _switch_ndevices=%d\n", _ndevices, _switch_ndevices); gprintk("ctrl->dev_type=0x%x, ctrl->phys_address=0x%lx\n", - ctrl->dev_type, (unsigned long)ctrl->phys_address); + ctrl->dev_type, (unsigned long)ctrl->iowin[0].addr); gprintk("ctrl->bde_dev.device=0x%x, ctrl->bde_dev.rev=0x%x, " "ctrl->bde_dev.base_address=0x%lx\n", ctrl->bde_dev.device, ctrl->bde_dev.rev, @@ -4089,7 +4234,7 @@ lkbde_get_dev_phys(int d) d, _devices[d].dev_type); return 0; } - return _devices[d].phys_address; + return _devices[d].iowin[0].addr; } uint32_t @@ -4105,7 +4250,7 @@ lkbde_get_dev_phys_hi(int d) return 0; } #ifdef PHYS_ADDR_IS_64BIT - return (uint32_t)(_devices[d].phys_address >> 32); + return (uint32_t)(_devices[d].iowin[0].addr >> 32); #else return 0; #endif @@ -4151,15 +4296,15 @@ lkbde_get_dev_resource(int d, int rsrc, uint32_t *flags, switch (rsrc) { case 0: - *phys_lo = (uint32_t)(_devices[d].phys_address); + *phys_lo = (uint32_t)(_devices[d].iowin[0].addr); #ifdef PHYS_ADDR_IS_64BIT - *phys_hi = (uint32_t)(_devices[d].phys_address >> 32); + *phys_hi = (uint32_t)(_devices[d].iowin[0].addr >> 32); #endif break; case 1: - *phys_lo = (uint32_t)(_devices[d].phys_address1); + *phys_lo = (uint32_t)(_devices[d].iowin[1].addr); #ifdef PHYS_ADDR_IS_64BIT - *phys_hi = (uint32_t)(_devices[d].phys_address1 >> 32); + *phys_hi = (uint32_t)(_devices[d].iowin[1].addr >> 32); #endif break; default: @@ -4286,7 +4431,7 @@ lkbde_irq_mask_set(int d, uint32_t addr, uint32_t mask, uint32_t fmask) if (iproc_reg) { _iproc_write(d, addr, ctrl->imask | ctrl->imask2); } else { - _write(d, addr, ctrl->imask | ctrl->imask2); + _write(d, addr, ctrl->imask | ctrl->imask2); } spin_unlock_irqrestore(&ctrl->lock, flags); @@ -4326,7 +4471,7 @@ lkbde_irq_mask_get(int d, uint32_t *mask, uint32_t *fmask) *fmask = ctrl->fmask; *mask = ctrl->imask | ctrl->imask2; - + return 0; } diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c index eb3dc0495195..4f9518e9f4a9 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c @@ -67,6 +67,10 @@ #include #include +#if defined(IPROC_CMICD) && defined(CONFIG_OF) +#include +#endif + #ifdef BCM_PLX9656_LOCAL_BUS #include #endif @@ -117,9 +121,9 @@ #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) -#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((d),(p)) +#define BDE_DMA_MAPPING_ERROR(d, p) dma_mapping_error((d),(p)) #else -#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((p)) +#define BDE_DMA_MAPPING_ERROR(d, p) dma_mapping_error((p)) #endif #ifndef KMALLOC_MAX_SIZE @@ -612,6 +616,15 @@ static void _alloc_mpool(size_t size) { unsigned long pbase = 0; + struct device *dev = DMA_DEV(DMA_DEV_INDEX); + int dma64_support = 0; + +#if defined(IPROC_CMICD) && defined(CONFIG_OF) + if (of_find_compatible_node(NULL, NULL, "brcm,iproc-cmicx")) { + dma64_support = 1; + } +#endif + #if defined(__arm__) && !defined(CONFIG_HIGHMEM) if (_use_himem) { gprintk("DMA in high memory requires CONFIG_HIGHMEM on ARM CPUs.\n"); @@ -647,8 +660,8 @@ _alloc_mpool(size_t size) /* get a memory allocation from the kernel */ { dma_addr_t dma_handle; - if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(DMA_DEV_INDEX), - alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) { + _dma_vbase = dma_alloc_coherent(dev, alloc_size, &dma_handle, GFP_KERNEL); + if (!_dma_vbase || !dma_handle) { gprintk("Failed to allocate coherent memory pool of size 0x%lx\n", (unsigned long)alloc_size); return; } @@ -672,9 +685,9 @@ _alloc_mpool(size_t size) } _cpu_pbase = virt_to_bus(_dma_vbase); /* Use dma_map_single to obtain DMA bus address or IOVA if iommu is present. */ - if (DMA_DEV(DMA_DEV_INDEX)) { - pbase = dma_map_single(DMA_DEV(DMA_DEV_INDEX), _dma_vbase, size, DMA_BIDIRECTIONAL); - if (DMA_MAPPING_ERROR(DMA_DEV(DMA_DEV_INDEX), pbase)) { + if (dev) { + pbase = dma_map_single(dev, _dma_vbase, size, DMA_BIDIRECTIONAL); + if (BDE_DMA_MAPPING_ERROR(dev, pbase)) { gprintk("Failed to map memory at %p\n", _dma_vbase); _pgcleanup(); _dma_vbase = NULL; @@ -692,7 +705,9 @@ _alloc_mpool(size_t size) return; } - if (((pbase + (size - 1)) >> 16) > DMA_BIT_MASK(16)) { + _dma_pbase = pbase; + + if (!dma64_support && ((pbase + (size - 1)) >> 16) > DMA_BIT_MASK(16)) { gprintk("DMA memory allocated at 0x%lx size 0x%lx is beyond the 4GB limit and not supported.\n", pbase, (unsigned long)size); _pgcleanup(); _dma_vbase = NULL; @@ -700,14 +715,13 @@ _alloc_mpool(size_t size) return; } - _dma_pbase = pbase; #ifdef REMAP_DMA_NONCACHED _dma_vbase = IOREMAP(_dma_pbase, size); #endif if (dma_debug >= 1) { - gprintk("_use_dma_mapping:%d _dma_vbase:%p _dma_pbase:%lx _cpu_pbase:%lx allocated:%lx dmaalloc:%d\n", + gprintk("_use_dma_mapping:%d _dma_vbase:%p _dma_pbase:%lx _cpu_pbase:%lx allocated:%lx dmaalloc:%d, dma64_support:%d\n", _use_dma_mapping, _dma_vbase, (unsigned long)_dma_pbase, - (unsigned long)_cpu_pbase, (unsigned long)size, dmaalloc); + (unsigned long)_cpu_pbase, (unsigned long)size, dmaalloc, dma64_support); } } } @@ -749,7 +763,7 @@ void _dma_init(int dev_index) if (dev_index > DMA_DEV_INDEX) { if (_use_dma_mapping && DMA_DEV(dev_index) && _dma_vbase) { pbase = dma_map_single(DMA_DEV(dev_index), _dma_vbase, _dma_mem_size, DMA_BIDIRECTIONAL); - if (DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) { + if (BDE_DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) { gprintk("Failed to map memory for device %d at %p\n", dev_index, _dma_vbase); return; } @@ -992,6 +1006,9 @@ lkbde_get_dma_info(phys_addr_t* cpu_pbase, phys_addr_t* dma_pbase, ssize_t* size void _dma_pprint(void) { + pprintf("\tdmasize=%s\n", dmasize); + pprintf("\thimem=%s\n", himem); + pprintf("\thimemaddr=%s\n", himemaddr); pprintf("DMA Memory (%s): %d bytes, %d used, %d free%s\n", (_use_himem) ? "high" : "kernel", (_dma_vbase) ? _dma_mem_size : 0, diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c index 370f89e022c4..46f60c8a3ae9 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c @@ -1,23 +1,20 @@ /* * Copyright 2017 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ + /* - * $Id: linux-user-bde.c,v 1.80 Broadcom SDK $ - * $Copyright: (c) 2005 Broadcom Corp. - * All Rights Reserved.$ - * * Linux User BDE Helper Module */ #include @@ -81,6 +78,17 @@ The INTR base address values are changed for HX5, hence making new #defines so runtime decisions can be made. */ +#define PAXB_0_PAXB_IC_INTRCLR_0 (0x180123a0) +#define PAXB_0_PAXB_IC_INTRCLR_1 (0x180123a4) + +#define PAXB_0_PAXB_IC_INTRCLR_MODE_0 (0x180123a8) +#define PAXB_0_PAXB_IC_INTRCLR_MODE_1 (0x180123ac) + +#define HX5_PAXB_0_PAXB_IC_INTRCLR_0 (0x102303a0) +#define HX5_PAXB_0_PAXB_IC_INTRCLR_1 (0x102303a4) + +#define HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_0 (0x102303a8) +#define HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_1 (0x102303ac) #define INTC_INTR_ENABLE_REG0 (0x180130f0) #define INTC_INTR_STATUS_REG0 (0x18013190) @@ -104,12 +112,18 @@ be made. #define HX5_IHOST_GICD_ISENABLERN_1 (0x10781104) #define HX5_IHOST_GICD_ICENABLERN_1 (0x10781184) #define HX5_IHOST_GICD_ICENABLERN_8 (0x107811a0) +#define HX5_IHOST_GICD_ISPENDRN_8 (0x10781220) /* Offset between ISENABLERN_1 and ICENABLERN_1 in 4-bytes */ #define HX5_IHOST_IRQ_MASK_OFFSET 0x20 -#define HX5_IHOST_INTR_MAP_NUM (HX5_IHOST_GICD_ICENABLERN_8 - HX5_IHOST_GICD_ISENABLERN_0) +/* Offset between ISENABLERN_1 and ISPENDRN_1 in 4-bytes */ +#define HX5_IHOST_IRQ_PEND_OFFSET 0x40 +#define HX5_IHOST_INTR_MAP_NUM (HX5_IHOST_GICD_ISPENDRN_8 - HX5_IHOST_GICD_ISENABLERN_0) #define HX5_IHOST_INTR_STATUS_MAP_NUM (INTC_INTR_REG_NUM * (sizeof(uint32))) #define IRQ_BIT(intr) (intr % (sizeof(uint32)*8)) #define IRQ_MASK_INDEX(intr) (intr / (sizeof(uint32)*8)) +#define HX5_SW_PROG_INTR_PRIORITY 73 +#define INTR_SW_PROG_INTR_BITPOS (1 << IRQ_BIT(HX5_SW_PROG_INTR_PRIORITY)) +#define INTC_SW_PROG_INTR_REG_IND IRQ_MASK_INDEX(HX5_SW_PROG_INTR_PRIORITY) #define HX5_CHIP_INTR_LOW_PRIORITY 119 #define INTR_LOW_PRIORITY_BITPOS (1 << IRQ_BIT(HX5_CHIP_INTR_LOW_PRIORITY)) #define INTC_LOW_PRIORITY_INTR_REG_IND IRQ_MASK_INDEX(HX5_CHIP_INTR_LOW_PRIORITY) @@ -141,10 +155,25 @@ be made. static uint32 *ihost_intr_status_base = NULL; static uint32 *ihost_intr_enable_base = NULL; +/* Debug output */ +static int debug; +LKM_MOD_PARAM(debug, "i", int, (S_IRUGO | S_IWUSR)); +MODULE_PARM_DESC(debug, +"Set debug level (default 0)."); + static ibde_t *user_bde = NULL; typedef void (*isr_f)(void *); +typedef struct _intr_regs_s { + uint32 intc_intr_status_base; + uint32 intc_intr_enable_base; + uint32 intc_intr_clear_0; + uint32 intc_intr_clear_1; + uint32 intc_intr_clear_mode_0; + uint32 intc_intr_clear_mode_1; +} _intr_regs_t; + typedef struct bde_ctrl_s { uint32 dev_type; int irq; @@ -153,6 +182,7 @@ typedef struct bde_ctrl_s { isr_f isr; uint32 *ba; int inst; /* associate to _bde_inst_resource[] */ + _intr_regs_t intr_regs; } bde_ctrl_t; #define VALID_DEVICE(_n) (_n < LINUX_BDE_MAX_DEVICES) @@ -178,6 +208,10 @@ typedef struct { } bde_inst_resource_t; static bde_inst_resource_t _bde_inst_resource[LINUX_BDE_MAX_DEVICES]; +/* + * Lock used to protect changes to _bde_inst_resource + */ +static spinlock_t bde_resource_lock; typedef struct { phys_addr_t cpu_pbase; /* CPU physical base address of the DMA pool */ @@ -263,44 +297,33 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) int d, ind; uint32 stat, iena, mask, fmask; bde_inst_resource_t *res; - uint32 intc_intr_status_base = 0, intc_intr_enable_base = 0; d = (((uint8 *)ctrl - (uint8 *)_devices) / sizeof (bde_ctrl_t)); + + if (ctrl->dev_type & BDE_PCI_DEV_TYPE) { + /* Clear MSI interrupts immediately to prevent spurious interrupts */ + WRITE_INTC_INTR(d, ctrl->intr_regs.intc_intr_clear_0, 0xFFFFFFFF); + WRITE_INTC_INTR(d, ctrl->intr_regs.intc_intr_clear_1, 0xFFFFFFFF); + } + res = &_bde_inst_resource[ctrl->inst]; lkbde_irq_mask_get(d, &mask, &fmask); - if ((ctrl->dev_type & BDE_SWITCH_DEV_TYPE) && - ((user_bde->get_dev(d)->device == BCM56370_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56371_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56372_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56374_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56375_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56376_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56377_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56577_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56578_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56579_DEVICE_ID))) { - intc_intr_status_base = HX5_INTC_INTR_STATUS_BASE; - intc_intr_enable_base = HX5_INTC_INTR_ENABLE_BASE; - } else { - intc_intr_status_base = INTC_INTR_STATUS_BASE; - intc_intr_enable_base = INTC_INTR_ENABLE_BASE; - } if (fmask) { if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { IHOST_READ_INTR(d, ihost_intr_status_base + INTC_PDMA_INTR_REG_IND, stat); IHOST_READ_INTR(d, ihost_intr_enable_base + INTC_PDMA_INTR_REG_IND, iena); } else { - READ_INTC_INTR(d, intc_intr_status_base + 4 * INTC_PDMA_INTR_REG_IND, stat); - READ_INTC_INTR(d, intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, iena); + READ_INTC_INTR(d, ctrl->intr_regs.intc_intr_status_base + 4 * INTC_PDMA_INTR_REG_IND, stat); + READ_INTC_INTR(d, ctrl->intr_regs.intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, iena); } if (stat & iena) { if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_PDMA_INTR_REG_IND + HX5_IHOST_IRQ_MASK_OFFSET, ~0); } else { - WRITE_INTC_INTR(d, intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, 0); + WRITE_INTC_INTR(d, ctrl->intr_regs.intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, 0); } for (ind = 0; ind < INTC_INTR_REG_NUM; ind++) { @@ -308,17 +331,21 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) continue; } if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { - if (ind < INTC_LOW_PRIORITY_INTR_REG_IND) { + if (ind < INTC_SW_PROG_INTR_REG_IND) { continue; } - IHOST_READ_INTR(d, ihost_intr_status_base + ind, stat); - IHOST_READ_INTR(d, ihost_intr_enable_base + ind, iena); - if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { - stat &= INTR_LOW_PRIORITY_BITPOS; + if (ind == INTC_SW_PROG_INTR_REG_IND) { + IHOST_READ_INTR(d, ihost_intr_enable_base + ind + HX5_IHOST_IRQ_PEND_OFFSET, stat); + stat &= INTR_SW_PROG_INTR_BITPOS; + } else { + IHOST_READ_INTR(d, ihost_intr_status_base + ind, stat); + if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { + stat &= INTR_LOW_PRIORITY_BITPOS; + } } } else { - READ_INTC_INTR(d, intc_intr_status_base + 4 * ind, stat); - READ_INTC_INTR(d, intc_intr_enable_base + 4 * ind, iena); + READ_INTC_INTR(d, ctrl->intr_regs.intc_intr_status_base + 4 * ind, stat); + READ_INTC_INTR(d, ctrl->intr_regs.intc_intr_enable_base + 4 * ind, iena); } if (stat & iena) { break; @@ -340,10 +367,13 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) continue; } if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { - if (ind < INTC_LOW_PRIORITY_INTR_REG_IND) { + if (ind < INTC_SW_PROG_INTR_REG_IND) { continue; } - if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { + if (ind == INTC_SW_PROG_INTR_REG_IND) { + IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_SW_PROG_INTR_REG_IND + + HX5_IHOST_IRQ_MASK_OFFSET, INTR_SW_PROG_INTR_BITPOS); + } else if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_LOW_PRIORITY_INTR_REG_IND + HX5_IHOST_IRQ_MASK_OFFSET, INTR_LOW_PRIORITY_BITPOS); } else { @@ -351,7 +381,7 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) HX5_IHOST_IRQ_MASK_OFFSET, ~0); } } else { - WRITE_INTC_INTR(d, intc_intr_enable_base + 4*ind, 0); + WRITE_INTC_INTR(d, ctrl->intr_regs.intc_intr_enable_base + 4*ind, 0); } } @@ -567,6 +597,18 @@ _cmicd_interrupt(bde_ctrl_t *ctrl) if (stat & imask) { break; } + /** Check if there are interrupts other than PacketIO interrupts on CMC1 */ + stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT0_OFFSET(1)); + imask = mask & ~fmask; + if (stat & imask) { + break; + } + /** Check if there are interrupts other than PacketIO interrupts on CMC2 */ + stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT0_OFFSET(2)); + imask = mask & ~fmask; + if (stat & imask) { + break; + } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT1_OFFSET(cmc)); if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { mask = user_bde->read(d, CMIC_CMCx_UC0_IRQ_MASK1_OFFSET(cmc)); @@ -716,6 +758,26 @@ _intr_mode_str(void *isr) return NULL; } +static void +_intr_regs_init(bde_ctrl_t *ctrl, int hx5_intr) +{ + if (hx5_intr) { + ctrl->intr_regs.intc_intr_status_base = HX5_INTC_INTR_STATUS_BASE; + ctrl->intr_regs.intc_intr_enable_base = HX5_INTC_INTR_ENABLE_BASE; + ctrl->intr_regs.intc_intr_clear_0 = HX5_PAXB_0_PAXB_IC_INTRCLR_0; + ctrl->intr_regs.intc_intr_clear_1 = HX5_PAXB_0_PAXB_IC_INTRCLR_1; + ctrl->intr_regs.intc_intr_clear_mode_0 = HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_0; + ctrl->intr_regs.intc_intr_clear_mode_1 = HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_1; + } else { + ctrl->intr_regs.intc_intr_status_base = INTC_INTR_STATUS_BASE; + ctrl->intr_regs.intc_intr_enable_base = INTC_INTR_ENABLE_BASE; + ctrl->intr_regs.intc_intr_clear_0 = PAXB_0_PAXB_IC_INTRCLR_0; + ctrl->intr_regs.intc_intr_clear_1 = PAXB_0_PAXB_IC_INTRCLR_1; + ctrl->intr_regs.intc_intr_clear_mode_0 = PAXB_0_PAXB_IC_INTRCLR_MODE_0; + ctrl->intr_regs.intc_intr_clear_mode_1 = PAXB_0_PAXB_IC_INTRCLR_MODE_1; + } +} + static void _devices_init(int d) { @@ -753,6 +815,8 @@ _devices_init(int d) case BCM53547_DEVICE_ID: case BCM53548_DEVICE_ID: case BCM53549_DEVICE_ID: + ctrl->isr = (isr_f)_cmicd_cmc0_interrupt; + break; case BCM88670_DEVICE_ID: case BCM88671_DEVICE_ID: case BCM88671M_DEVICE_ID: @@ -780,10 +844,10 @@ _devices_init(int d) case BCM88683_DEVICE_ID: case BCM88684_DEVICE_ID: case BCM88685_DEVICE_ID: + case BCM88687_DEVICE_ID: case BCM88380_DEVICE_ID: case BCM88381_DEVICE_ID: case BCM88680_DEVICE_ID: - case BCM88800_DEVICE_ID: case BCM88770_DEVICE_ID: case BCM88773_DEVICE_ID: case BCM88774_DEVICE_ID: @@ -812,10 +876,7 @@ _devices_init(int d) case BCM88956_DEVICE_ID: case BCM88772_DEVICE_ID: case BCM88952_DEVICE_ID: - ctrl->isr = (isr_f)_cmicd_cmc0_interrupt; - break; - case BCM88790_DEVICE_ID: - ctrl->isr = (isr_f)_cmicx_interrupt; + ctrl->isr = (isr_f)_cmicd_interrupt; break; case BCM56370_DEVICE_ID: case BCM56371_DEVICE_ID: @@ -827,6 +888,12 @@ _devices_init(int d) case BCM56577_DEVICE_ID: case BCM56578_DEVICE_ID: case BCM56579_DEVICE_ID: + case BCM56273_DEVICE_ID: + case BCM56274_DEVICE_ID: + case BCM56275_DEVICE_ID: + case BCM56276_DEVICE_ID: + case BCM56277_DEVICE_ID: + case BCM56278_DEVICE_ID: ctrl->isr = (isr_f)_cmicx_interrupt; if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { if (!ihost_intr_enable_base) { @@ -838,6 +905,7 @@ _devices_init(int d) HX5_IHOST_INTR_STATUS_MAP_NUM); } } + _intr_regs_init(ctrl, 1); break; default: /* Get CMIC version */ @@ -853,7 +921,8 @@ _devices_init(int d) } /* check if version is CMICX */ else if (ver == 0x04) { - ctrl->isr = (isr_f)_cmicx_interrupt; + ctrl->isr = (isr_f)_cmicx_interrupt; + _intr_regs_init(ctrl, 0); } else { ctrl->isr = (isr_f)_cmic_interrupt; if ((ctrl->dev_type & BDE_256K_REG_SPACE) && @@ -867,17 +936,25 @@ _devices_init(int d) break; } + /* configure interrupts for DNX devices using iproc >=14 */ +#if defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) + switch (user_bde->get_dev(d)->device & DNXC_DEVID_FAMILY_MASK) { #ifdef BCM_DNX_SUPPORT - /*All Jericho 2 devices from 0x8690 to 0x869F*/ - if (SOC_IS_JERICHO_2_TYPE(user_bde->get_dev(d)->device)) { - ctrl->isr = (isr_f)_cmicx_interrupt; - } + case JERICHO2_DEVICE_ID: + case J2C_DEVICE_ID: + case J2C_2ND_DEVICE_ID: + case Q2A_DEVICE_ID: + case J2P_DEVICE_ID: +#endif +#ifdef BCM_DNXF_SUPPORT + case BCM88790_DEVICE_ID: #endif - - /*All Ramon devices from 0x8790 to 0x879F*/ - if ((user_bde->get_dev(d)->device & BCM88790_DEVICE_ID) == BCM88790_DEVICE_ID) { ctrl->isr = (isr_f)_cmicx_interrupt; + _intr_regs_init(ctrl, 0); + break; } +#endif /* defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) */ + if (_intr_mode_str(ctrl->isr) == NULL) { gprintk("Warning: Unknown interrupt mode\n"); } @@ -906,6 +983,7 @@ _init(void) if ((linux_bde_create(NULL, &user_bde) < 0) || user_bde == NULL) { return -ENODEV; } + spin_lock_init(&bde_resource_lock); init_waitqueue_head(&_ether_interrupt_wq); @@ -1121,15 +1199,27 @@ _instance_attach(unsigned int inst_id, unsigned int dma_size) /* Reprobe the system for hot-plugged device */ _device_reprobe(); + if (debug >= 2) { + gprintk("INFO: Request to attach to instance_id %d with dma size %d!\n", inst_id, dma_size); + } + + spin_lock(&bde_resource_lock); + /* Validate the resource with inst_id */ exist = _instance_validate(inst_id, dma_size); if (exist < 0) { + spin_unlock(&bde_resource_lock); return LUBDE_FAIL; } if (exist > 0) { + if (debug >= 2) { + gprintk("INFO: Already attached to instance_id %d with dma size %d!\n", inst_id, dma_size); + } + spin_unlock(&bde_resource_lock); return LUBDE_SUCCESS; } if (_dma_resource_alloc(dma_size, &dma_offset) < 0) { + spin_unlock(&bde_resource_lock); return LUBDE_FAIL; } for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { @@ -1157,6 +1247,10 @@ _instance_attach(unsigned int inst_id, unsigned int dma_size) } } } + spin_unlock(&bde_resource_lock); + if (debug >= 2) { + gprintk("INFO: Attached to instance_id %d with dma size %d! SUCCESS\n", inst_id, dma_size); + } return LUBDE_SUCCESS; } @@ -1204,6 +1298,7 @@ _ioctl(unsigned int cmd, unsigned long arg) if (bde_dev) { io.d0 = bde_dev->device; io.d1 = bde_dev->rev; + io.dx.dw[0] = bde_dev->dev_unique_id; if (BDE_DEV_MEM_MAPPED(_devices[io.dev].dev_type)) { /* Get physical address to map */ io.d2 = lkbde_get_dev_phys(io.dev); @@ -1258,8 +1353,10 @@ _ioctl(unsigned int cmd, unsigned long arg) io.dx.dw[0] = cpu_pbase; #ifdef PHYS_ADDRS_ARE_64BITS io.dx.dw[1] = cpu_pbase >> 32; + io.d3 = dma_pbase >> 32; #else io.dx.dw[1] = 0; + io.d3 = 0; #endif break; case LUBDE_ENABLE_INTERRUPTS: @@ -1268,6 +1365,14 @@ _ioctl(unsigned int cmd, unsigned long arg) } if (_devices[io.dev].dev_type & BDE_SWITCH_DEV_TYPE) { if (_devices[io.dev].isr && !_devices[io.dev].enabled) { + bde_ctrl_t *ctrl; + ctrl = &_devices[io.dev]; + if ((ctrl->isr == (isr_f)_cmicx_interrupt) && + (ctrl->dev_type & BDE_PCI_DEV_TYPE)) { + /* Set MSI mode to SW clear vs auto clear */ + WRITE_INTC_INTR(io.dev, ctrl->intr_regs.intc_intr_clear_mode_0, 0x0); + WRITE_INTC_INTR(io.dev, ctrl->intr_regs.intc_intr_clear_mode_1, 0x0); + } user_bde->interrupt_connect(io.dev, _devices[io.dev].isr, _devices+io.dev); diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c index 05253141b2ff..087720a20a8b 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c @@ -290,8 +290,9 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs, } } - /* Configure MSIX interrupt page, only need for iproc ver == 0x10 */ - if ((icfg->use_msi == 2) && (icfg->iproc_ver == 0x10)) { + /* Configure MSIX interrupt page, need for iproc ver 0x10 and 0x12 */ + if ((icfg->use_msi == 2) && + ((icfg->iproc_ver == 0x10) || (icfg->iproc_ver == 0x12))){ unsigned int mask = (0x1 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT) - 1; reg = ROFFS(iproc_regs, PAXB_0_FUNC0_IMAP1_3); data = iproc32_read(shbde, reg); @@ -341,19 +342,23 @@ shbde_iproc_pci_read(shbde_hal_t *shbde, void *iproc_regs, subwin_base = (addr & ~0xfff); if((icfg->cmic_ver >= 4) && + ((subwin_base == 0x10230000) || (subwin_base == 0x18012000))) { + /* Route the PAXB register through IMAP0_2 */ + reg = ROFFS(iproc_regs, 0x2000 + (addr & 0xfff)); + } else if((icfg->cmic_ver >= 4) && ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { /* Route the INTC block access through IMAP0_6 */ reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); } else { /* Update base address for sub-window 7 */ subwin_base |= 1; /* Valid bit */ - reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); - iproc32_write(shbde, reg, subwin_base); + reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); + iproc32_write(shbde, reg, subwin_base); /* Read it to make sure the write actually goes through */ subwin_base = iproc32_read(shbde, reg); - /* Read register through sub-window 7 */ - reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); + /* Read register through sub-window 7 */ + reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); } return iproc32_read(shbde, reg); @@ -388,19 +393,23 @@ shbde_iproc_pci_write(shbde_hal_t *shbde, void *iproc_regs, subwin_base = (addr & ~0xfff); if((icfg->cmic_ver >= 4) && + ((subwin_base == 0x10230000) || (subwin_base == 0x18012000))) { + /* Route the PAXB register through IMAP0_2 */ + reg = ROFFS(iproc_regs, 0x2000 + (addr & 0xfff)); + } else if((icfg->cmic_ver >= 4) && ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { /* Route the INTC block access through IMAP0_6 */ reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); } else { /* Update base address for sub-window 7 */ subwin_base |= 1; /* Valid bit */ - reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); - iproc32_write(shbde, reg, subwin_base); + reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); + iproc32_write(shbde, reg, subwin_base); /* Read it to make sure the write actually goes through */ subwin_base = iproc32_read(shbde, reg); /* Read register through sub-window 7 */ - reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); + reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); } iproc32_write(shbde, reg, data); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile index 84c677758cac..448b4b9a9310 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile @@ -24,7 +24,7 @@ LOCALDIR = systems/linux/kernel/modules include ${SDK}/make/Make.config -subdirs=shared uk-proxy bcm-diag-full bcm-core bcm-net bcm-diag +subdirs= include ${SDK}/make/Make.subdirs diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile index ed1a5000e3ca..a3f430a6a903 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile @@ -37,9 +37,6 @@ build: $(MODULE) $(KMODULE) endif KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../../../../bde/linux/kernel/kernel_module/Module.symvers -ifeq (,$(findstring -DPROXY_SUPPORT=0,$(CFLAGS))) -KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../uk-proxy/kernel_module/Module.symvers -endif # BCM Network Device diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c index 077386e6dcbc..a9eda27ad4d5 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c @@ -1,23 +1,18 @@ /* * Copyright 2017 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ -/* - * $Id: bcm-knet.c,v 1.90 Broadcom SDK $ - * $Copyright: (c) 2005 Broadcom Corp. - * All Rights Reserved.$ - */ /* * This module implements a Linux network driver for Broadcom @@ -54,7 +49,7 @@ * * To support pci hot-plug in this module, the resource update * should be handled when the PCI device is re-plugged. - * NOTE: the KNET detach should be invoked befere removing the + * NOTE: the KNET detach should be invoked before removing the * device. * * For a list of supported module parameters, please see below. @@ -65,12 +60,17 @@ #include #include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,16,0) +#include +#endif + #include #include #include #include #include #include +#include MODULE_AUTHOR("Broadcom Corporation"); @@ -167,6 +167,39 @@ LKM_MOD_PARAM(basedev_suspend, "i", int, 0); MODULE_PARM_DESC(basedev_suspend, "Pause traffic till base device is up (enabled by default in NAPI mode)"); +/* + * Force to add one layer of VLAN tag to untagged packets on Dune devices + */ +#if defined(SAI_FIXUP) && defined(BCM_DNX_SUPPORT) /* SONIC-16195 CS9129167 - Change the default to NOT add tag */ +static int force_tagged = 0; +#else +static int force_tagged = 1; +#endif +LKM_MOD_PARAM(force_tagged, "i", int, 0); +MODULE_PARM_DESC(force_tagged, +"Always tagged with VLAN tag with spceified VID or VSI(default 1)"); + +static int ft_tpid=0x8100; +LKM_MOD_PARAM(ft_tpid, "i", int, 0); +MODULE_PARM_DESC(ft_tpid, +"Tag Protocol Identifier (TPID) indicates the frame type (default 0x8100)"); + +static int ft_pri=0; +LKM_MOD_PARAM(ft_pri, "i", int, 0); +MODULE_PARM_DESC(ft_cfi, +"Priority (PRI) indicates the frame priority (default 0)"); + +static int ft_cfi=0; +LKM_MOD_PARAM(ft_cfi, "i", int, 0); +MODULE_PARM_DESC(ft_cfi, +"Canonical Format Indicator (CFI) indicates whether a MAC address is encapsulated in canonical format over different transmission media (default 0)"); + +static int ft_vid=0; +LKM_MOD_PARAM(ft_vid, "i", int, 0); +MODULE_PARM_DESC(ft_vid, +"VLAN ID (VID) indicates the VLAN to which a frame belongs (default 0)"); + + /* Debug levels */ #define DBG_LVL_VERB 0x1 #define DBG_LVL_DCB 0x2 @@ -267,40 +300,6 @@ static int napi_weight = 0; #endif -/* - * If proxy support is compiled in the module will attempt to use - * the user/kernel message service provided by the linux-uk-proxy - * kernel module, otherwise device IOCTL will be used. - */ -#ifndef PROXY_SUPPORT -#define PROXY_SUPPORT 0 -#endif - -#if PROXY_SUPPORT - -#include - -static int use_proxy = 1; -LKM_MOD_PARAM(use_proxy, "i", int, 0); -MODULE_PARM_DESC(use_proxy, -"Use Linux User/Kernel proxy (default 1)"); - -#define PROXY_SERVICE_CREATE(_s,_q,_f) linux_uk_proxy_service_create(_s,_q,_f) -#define PROXY_SERVICE_DESTROY(_s) linux_uk_proxy_service_destroy(_s); -#define PROXY_SEND(_s,_m,_l) linux_uk_proxy_send(_s,_m,_l) -#define PROXY_RECV(_s,_m,_l) linux_uk_proxy_recv(_s,_m,_l) - -#else - -static int use_proxy = 0; - -#define PROXY_SERVICE_CREATE(_s,_q,_f) -#define PROXY_SERVICE_DESTROY(_s) -#define PROXY_SEND(_s,_m,_l) -#define PROXY_RECV(_s,_m,_l) (-1) - -#endif - /* Compatibility */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)) @@ -394,6 +393,10 @@ static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) __vlan_hwaccel_put_tag(_skb, htons(_proto), _tci) #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) +#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */ +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) #define bkn_dma_mapping_error(d, a) \ dma_mapping_error(a) @@ -407,6 +410,11 @@ static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) +enum hwtstamp_tx_types { + HWTSTAMP_TX_OFF, + HWTSTAMP_TX_ON, + HWTSTAMP_TX_ONESTEP_SYNC +}; enum { SKBTX_HW_TSTAMP = 1 << 0, SKBTX_SW_TSTAMP = 1 << 1, @@ -441,6 +449,7 @@ static inline ktime_t ns_to_ktime(u64 ns) #endif #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) #include +#define HWTSTAMP_TX_ONESTEP_SYNC 2 enum { SKBTX_HW_TSTAMP = 1 << 0, SKBTX_SW_TSTAMP = 1 << 1, @@ -452,6 +461,11 @@ static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) } #else #include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) +#define HWTSTAMP_TX_ONESTEP_SYNC 2 +#endif + #define bkn_skb_tx_flags(_skb) skb_shinfo(_skb)->tx_flags static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) { @@ -459,26 +473,41 @@ static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) } #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +#define bkn_dev_net_set(dev, net) +#else +#define bkn_dev_net_set(dev, net) dev_net_set(dev, net) +#endif + #ifdef LINUX_BDE_DMA_DEVICE_SUPPORT -#define DMA_DEV device -#define DMA_FROMDEV DMA_FROM_DEVICE -#define DMA_TODEV DMA_TO_DEVICE -#define DMA_MAP_SINGLE(d,p,s,r) dma_map_single(d,p,s,r) -#define DMA_UNMAP_SINGLE(d,a,s,r) dma_unmap_single(d,a,s,r) -#define DMA_ALLOC_COHERENT(d,s,h) dma_alloc_coherent(d,s,h,GFP_ATOMIC|GFP_DMA32) -#define DMA_FREE_COHERENT(d,s,a,h) dma_free_coherent(d,s,a,h) -#define DMA_MAPPING_ERROR(d,a) bkn_dma_mapping_error(d,a) +#define BKN_DMA_DEV device +#define BKN_DMA_FROMDEV DMA_FROM_DEVICE +#define BKN_DMA_TODEV DMA_TO_DEVICE +#define BKN_DMA_MAP_SINGLE(d,p,s,r) dma_map_single(d,p,s,r) +#define BKN_DMA_UNMAP_SINGLE(d,a,s,r) dma_unmap_single(d,a,s,r) +#define BKN_DMA_ALLOC_COHERENT(d,s,h) dma_alloc_coherent(d,s,h,GFP_ATOMIC|GFP_DMA32) +#define BKN_DMA_FREE_COHERENT(d,s,a,h) dma_free_coherent(d,s,a,h) +#define BKN_DMA_MAPPING_ERROR(d,a) bkn_dma_mapping_error(d,a) #else -#define DMA_DEV pci_dev -#define DMA_FROMDEV PCI_DMA_FROMDEVICE -#define DMA_TODEV PCI_DMA_TODEVICE -#define DMA_MAP_SINGLE(d,p,s,r) pci_map_single(d,p,s,r) -#define DMA_UNMAP_SINGLE(d,a,s,r) pci_unmap_single(d,a,s,r) -#define DMA_ALLOC_COHERENT(d,s,h) pci_alloc_consistent(d,s,h) -#define DMA_FREE_COHERENT(d,s,a,h) pci_free_consistent(d,s,a,h) -#define DMA_MAPPING_ERROR(d,a) bkn_pci_dma_mapping_error(d,a) +#define BKN_DMA_DEV pci_dev +#define BKN_DMA_FROMDEV PCI_DMA_FROMDEVICE +#define BKN_DMA_TODEV PCI_DMA_TODEVICE +#define BKN_DMA_MAP_SINGLE(d,p,s,r) pci_map_single(d,p,s,r) +#define BKN_DMA_UNMAP_SINGLE(d,a,s,r) pci_unmap_single(d,a,s,r) +#define BKN_DMA_ALLOC_COHERENT(d,s,h) pci_alloc_consistent(d,s,h) +#define BKN_DMA_FREE_COHERENT(d,s,a,h) pci_free_consistent(d,s,a,h) +#define BKN_DMA_MAPPING_ERROR(d,a) bkn_pci_dma_mapping_error(d,a) #endif +/* + * Get a 16-bit value from packet offset + * _data Pointer to packet + * _offset Offset + */ +#define PKT_U16_GET(_data, _offset) \ + (uint16_t)(_data[_offset] << 8 | _data[_offset + 1]) + + /* RCPU operations */ #define RCPU_OPCODE_RX 0x10 #define RCPU_OPCODE_TX 0x20 @@ -536,7 +565,7 @@ typedef struct bkn_switch_info_s { int ndev_max; /* Size of indexed array */ struct list_head rxpf_list; /* Associated Rx packet filters */ volatile void *base_addr; /* Base address for PCI register access */ - struct DMA_DEV *dma_dev; /* Required for DMA memory control */ + struct BKN_DMA_DEV *dma_dev; /* Required for DMA memory control */ struct pci_dev *pdev; /* Required for DMA memory control */ struct net_device *dev; /* Base network device */ struct napi_struct napi; /* New NAPI */ @@ -558,8 +587,12 @@ typedef struct bkn_switch_info_s { uint32_t ftmh_stacking_ext_size; /* FTMH Stacking extension existence/size */ uint32_t pph_base_size; /* Size of PPH base */ uint32_t pph_lif_ext_size[8]; /* Size of PPH Lif extension header */ - uint8_t udh_enable; /* Indicates UDH existence */ uint32_t udh_length_type[4]; /* Size of UDH header per type */ + uint32_t udh_size; /* Size of UDH header on legacy devices */ + uint32_t oamp_punt; /* OAMP port if nonzero */ + uint8_t no_skip_udh_check; /* Indicates UDH won't be skipped */ + uint8_t system_headers_mode; /* Indicates system header mode */ + uint8_t udh_enable; /* Indicates UDH existence */ int rx_chans; /* Number of Rx channels */ uint32_t dma_hi; /* DMA higher address */ uint32_t cmic_type; /* CMIC type (CMICe or CMICm) */ @@ -579,8 +612,6 @@ typedef struct bkn_switch_info_s { uint32_t inst_id; /* Instance id of this device */ int evt_idx; /* Event queue index for this device*/ int basedev_suspended; /* Base device suspended */ - int tx_hwts; /* HW timestamp for Tx */ - int rx_hwts; /* HW timestamp for Rx */ struct sk_buff_head tx_ptp_queue; /* Tx PTP skb queue */ struct work_struct tx_ptp_work; /* Tx PTP work */ struct { @@ -641,6 +672,8 @@ typedef struct bkn_switch_info_s { } rx[NUM_RX_CHAN]; } bkn_switch_info_t; +/* 0x1 - Jericho 2 mode */ +#define BKN_DNX_JR2_MODE 1 /* PTCH_2 */ #define BKN_DNX_PTCH_2_SIZE 2 /* ITMH */ @@ -675,49 +708,49 @@ typedef struct bkn_switch_info_s { /* TSH */ #define BKN_DNX_TSH_SIZE 4 /* PPH */ -#define BKN_DNX_PPH_BASE_TYPE_9 9 -#define BKN_DNX_PPH_BASE_TYPE_10 10 -#define BKN_DNX_PPH_BASE_TYPE_12 12 -#define BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB 5 -#define BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS 16 -#define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB 53 -#define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_9_FHEI_SIZE_MSB 54 -#define BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS 2 -#define BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB 56 -#define BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS 3 -#define BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB 9 -#define BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS 16 -#define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB 61 -#define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_10_FHEI_SIZE_MSB 62 -#define BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS 2 -#define BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB 64 -#define BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS 3 -#define BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB 21 -#define BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS 18 -#define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB 77 -#define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_12_FHEI_SIZE_MSB 78 -#define BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS 2 -#define BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB 80 -#define BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_INTERNAL_BASE_TYPE_9 9 +#define BKN_DNX_INTERNAL_BASE_TYPE_10 10 +#define BKN_DNX_INTERNAL_BASE_TYPE_12 12 +#define BKN_DNX_INTERNAL_9_FORWARD_DOMAIN_MSB 5 +#define BKN_DNX_INTERNAL_9_FORWARD_DOMAIN_NOF_BITS 16 +#define BKN_DNX_INTERNAL_9_LEARN_EXT_PRESENT_MSB 53 +#define BKN_DNX_INTERNAL_9_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_INTERNAL_9_FHEI_SIZE_MSB 54 +#define BKN_DNX_INTERNAL_9_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_INTERNAL_9_LIF_EXT_TYPE_MSB 56 +#define BKN_DNX_INTERNAL_9_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_INTERNAL_10_FORWARD_DOMAIN_MSB 9 +#define BKN_DNX_INTERNAL_10_FORWARD_DOMAIN_NOF_BITS 16 +#define BKN_DNX_INTERNAL_10_LEARN_EXT_PRESENT_MSB 61 +#define BKN_DNX_INTERNAL_10_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_INTERNAL_10_FHEI_SIZE_MSB 62 +#define BKN_DNX_INTERNAL_10_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_INTERNAL_10_LIF_EXT_TYPE_MSB 64 +#define BKN_DNX_INTERNAL_10_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_MSB 21 +#define BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_NOF_BITS 18 +#define BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_MSB 77 +#define BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_INTERNAL_12_FHEI_SIZE_MSB 78 +#define BKN_DNX_INTERNAL_12_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_MSB 80 +#define BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_NOF_BITS 3 /* PPH.FHEI_TYPE */ -#define BKN_DNX_PPH_FHEI_TYPE_SZ0 1 -#define BKN_DNX_PPH_FHEI_TYPE_SZ1 2 -#define BKN_DNX_PPH_FHEI_TYPE_SZ2 3 +#define BKN_DNX_INTERNAL_FHEI_TYPE_SZ0 1 +#define BKN_DNX_INTERNAL_FHEI_TYPE_SZ1 2 +#define BKN_DNX_INTERNAL_FHEI_TYPE_SZ2 3 /* FHEI */ -#define BKN_DNX_PPH_FHEI_SZ0_SIZE 3 -#define BKN_DNX_PPH_FHEI_SZ1_SIZE 5 -#define BKN_DNX_PPH_FHEI_SZ2_SIZE 8 -#define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB 0 -#define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS 27 -#define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB 27 -#define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS 9 -#define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB 36 -#define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS 4 +#define BKN_DNX_INTERNAL_FHEI_SZ0_SIZE 3 +#define BKN_DNX_INTERNAL_FHEI_SZ1_SIZE 5 +#define BKN_DNX_INTERNAL_FHEI_SZ2_SIZE 8 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_MSB 0 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_NOF_BITS 27 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_MSB 27 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_NOF_BITS 9 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_MSB 36 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_NOF_BITS 4 /* PPH Extension */ -#define BKN_DNX_PPH_LEARN_EXT_SIZE 19 +#define BKN_DNX_INTERNAL_LEARN_EXT_SIZE 19 /* UDH */ #define BKN_DNX_UDH_DATA_TYPE_0_MSB 0 #define BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS 2 @@ -758,29 +791,48 @@ typedef struct bkn_switch_info_s { #define BKN_DPP_FTMH_PPH_TYPE_MSB 45 #define BKN_DPP_FTMH_PPH_TYPE_NOF_BITS 2 +/* OTSH */ +#define BKN_DPP_OTSH_SIZE_BYTE 6 +#define BKN_DPP_OTSH_TYPE_MSB 0 +#define BKN_DPP_OTSH_TYPE_NOF_BITS 2 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_MSB 2 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_NOF_BITS 3 + +#define BKN_DPP_OTSH_TYPE_OAM 0 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_DM_1588 2 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_DM_NTP 3 + +#define BKN_DPP_OAM_DM_TOD_SIZE_BYTE 4 + /* PPH */ -#define BKN_DPP_PPH_SIZE_BYTE 7 -#define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB 0 -#define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS 1 -#define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB 1 -#define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS 1 -#define BKN_DPP_PPH_FHEI_SIZE_MSB 2 -#define BKN_DPP_PPH_FHEI_SIZE_NOF_BITS 2 -#define BKN_DPP_PPH_FORWARD_CODE_MSB 4 -#define BKN_DPP_PPH_FORWARD_CODE_NOF_BITS 4 -#define BKN_DPP_PPH_VSI_MSB 22 -#define BKN_DPP_PPH_VSI_NOF_BITS 16 +#define BKN_DPP_INTERNAL_SIZE_BYTE 7 +#define BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_MSB 0 +#define BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_NOF_BITS 1 +#define BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_MSB 1 +#define BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_NOF_BITS 1 +#define BKN_DPP_INTERNAL_FHEI_SIZE_MSB 2 +#define BKN_DPP_INTERNAL_FHEI_SIZE_NOF_BITS 2 +#define BKN_DPP_INTERNAL_FORWARD_CODE_MSB 4 +#define BKN_DPP_INTERNAL_FORWARD_CODE_NOF_BITS 4 +#define BKN_DPP_INTERNAL_FORWARD_CODE_CPU_TRAP 7 +#define BKN_DPP_INTERNAL_FORWARDING_HEADER_OFFSET_MSB 8 +#define BKN_DPP_INTERNAL_FORWARDING_HEADER_OFFSET_NOF_BITS 7 +#define BKN_DPP_INTERNAL_VSI_MSB 22 +#define BKN_DPP_INTERNAL_VSI_NOF_BITS 16 + /* FHEI TRAP/SNOOP 3B */ -#define BKN_DPP_PPH_FHEI_3B_SIZE_BYTE 3 -#define BKN_DPP_PPH_FHEI_5B_SIZE_BYTE 5 -#define BKN_DPP_PPH_FHEI_8B_SIZE_BYTE 8 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB 0 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS 16 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB 16 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS 8 +#define BKN_DPP_INTERNAL_FHEI_3B_SIZE_BYTE 3 +#define BKN_DPP_INTERNAL_FHEI_5B_SIZE_BYTE 5 +#define BKN_DPP_INTERNAL_FHEI_8B_SIZE_BYTE 8 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB 0 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS 16 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB 16 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS 8 /* PPH extension */ -#define BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE 3 -#define BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE 5 +#define BKN_DPP_INTERNAL_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE 3 +#define BKN_DPP_INTERNAL_LEARN_EXTENSION_SIZE_BYTE 5 + +#define BKN_SAND_SCRATCH_DATA_SIZE 4 /* ftmh action type. */ typedef enum bkn_dpp_ftmh_action_type_e { @@ -792,31 +844,22 @@ typedef enum bkn_dpp_ftmh_action_type_e { /* ftmh dest extension. */ typedef struct bkn_dpp_ftmh_dest_extension_s { - uint8 valid; /* Set if the extension is present */ + uint8_t valid; /* Set if the extension is present */ uint32_t dst_sys_port; /* Destination System Port */ } bkn_dpp_ftmh_dest_extension_t; /* dnx packet */ typedef struct bkn_dune_system_header_info_s { - uint32_t ntwrk_header_ptr; + uint32_t system_header_size; struct { - uint32_t packet_size; /* Packet size in bytes */ uint32_t action_type; /* Indicates if the copy is one of the Forward Snoop or Mirror packet copies */ - uint32_t pph_type; - uint32_t prio; /* Traffic class */ - uint32_t src_sys_port; /* Source System port*/ + uint32_t source_sys_port_aggregate; /* Source System port*/ } ftmh; struct { - uint32_t vsi; - uint32_t trap_qualifier; /* RAW Data */ - uint32_t trap_id; /* RAW Data */ + uint32_t forward_domain; + uint32_t trap_qualifier; + uint32_t trap_id; } internal; - uint32_t system_header_size; - uint32_t ftmh_spa; /* FTMH: Source-System-Port-Aggregate*/ - uint32_t pph_forward_domain; /* PPH: Forward-Domain*/ - uint32_t fhei_qualifier; /* FHEI: Qualifier */ - uint32_t fhei_code; /* FHEI: Code */ - uint32_t fhei_type; /* FHEI: Type */ } bkn_dune_system_header_info_t; #define PREV_IDX(_cur, _max) (((_cur) == 0) ? (_max) - 1 : (_cur) - 1) @@ -874,13 +917,16 @@ typedef struct bkn_priv_s { int id; int type; int port; - uint8_t itmh[4]; int qnum; uint32_t vlan; uint32_t flags; uint32_t cb_user_data; uint8_t system_headers[27]; uint32_t system_headers_size; + int tx_hwts; /* HW timestamp for Tx */ + int rx_hwts; /* HW timestamp for Rx */ + int phys_port; + struct ethtool_link_settings link_settings; } bkn_priv_t; typedef struct bkn_filter_s { @@ -890,6 +936,13 @@ typedef struct bkn_filter_s { kcom_filter_t kf; } bkn_filter_t; +#ifdef SAI_FIXUP /* SDK-224448 */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) +#define BKN_NETDEV_TX_BUSY NETDEV_TX_BUSY +#else +#define BKN_NETDEV_TX_BUSY 1 +#endif +#endif /* SDK-224448 */ /* * Multiple instance support in KNET @@ -927,6 +980,7 @@ static knet_hw_tstamp_tx_time_get_cb_f knet_hw_tstamp_tx_time_get_cb = NULL; static knet_hw_tstamp_tx_meta_get_cb_f knet_hw_tstamp_tx_meta_get_cb = NULL; static knet_hw_tstamp_ptp_clock_index_cb_f knet_hw_tstamp_ptp_clock_index_cb = NULL; static knet_hw_tstamp_rx_time_upscale_cb_f knet_hw_tstamp_rx_time_upscale_cb = NULL; +static knet_hw_tstamp_ioctl_cmd_cb_f knet_hw_tstamp_ioctl_cmd_cb = NULL; static knet_netif_cb_f knet_netif_create_cb = NULL; static knet_netif_cb_f knet_netif_destroy_cb = NULL; @@ -935,69 +989,6 @@ static knet_netif_cb_f knet_netif_destroy_cb = NULL; */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) -/* - * Old style using kernel_thread() - */ -typedef struct { - const char * name; - volatile int pid; - volatile int run; - struct completion completion; - int state; -} bkn_thread_ctrl_t; - -static int -bkn_thread_start(bkn_thread_ctrl_t *tc, const char *name, - int (*threadfn)(void *)) -{ - if (name == NULL) { - return -1; - } - tc->name = name; - tc->pid = kernel_thread(threadfn, tc, 0); - if (tc->pid < 0) { - tc->pid = 0; - return -1; - } - tc->run = 1; - init_completion(&tc->completion); - return 0; -} - -static int -bkn_thread_stop(bkn_thread_ctrl_t *tc) -{ - if (tc->pid == 0) { - return 0; - } - tc->run = 0; - kill_proc(tc->pid, SIGTERM, 1); - wait_for_completion(&tc->completion); - return 0; -} - -static int -bkn_thread_should_stop(bkn_thread_ctrl_t *tc) -{ - if (tc->run) { - return 0; - } - tc->pid = 0; - return 1; -} - -static void -bkn_thread_boot(bkn_thread_ctrl_t *tc) -{ - siginitsetinv(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL)); -} - -static void -bkn_thread_exit(bkn_thread_ctrl_t *tc) -{ - complete_and_exit(&tc->completion, 0); -} - static void bkn_sleep(int clicks) { @@ -1007,60 +998,6 @@ bkn_sleep(int clicks) sleep_on_timeout(&wq, clicks); } #else -/* - * New style using kthread API - */ -#include -typedef struct { - const char * name; - struct task_struct *task; - int state; -} bkn_thread_ctrl_t; - -static int -bkn_thread_start(bkn_thread_ctrl_t *tc, const char *name, - int (*threadfn)(void *)) -{ - if (name == NULL) { - return -1; - } - tc->name = name; - tc->task = kthread_run(threadfn, tc, name); - if (IS_ERR(tc->task)) { - tc->task = NULL; - return -1; - } - return 0; -} - -static int -bkn_thread_stop(bkn_thread_ctrl_t *tc) -{ - if (tc->task == NULL) { - return 0; - } - send_sig(SIGTERM, tc->task, 0); - return kthread_stop(tc->task); -} - -static int -bkn_thread_should_stop(bkn_thread_ctrl_t *tc) -{ - return kthread_should_stop(); -} - -static void -bkn_thread_boot(bkn_thread_ctrl_t *tc) -{ - allow_signal(SIGTERM); - allow_signal(SIGKILL); -} - -static void -bkn_thread_exit(bkn_thread_ctrl_t *tc) -{ -} - static void bkn_sleep(int clicks) { @@ -1071,9 +1008,6 @@ bkn_sleep(int clicks) } #endif -static bkn_thread_ctrl_t bkn_cmd_ctrl; -static bkn_thread_ctrl_t bkn_evt_ctrl; - /* * On XGS devices bit 15 fo the Transferred Bytes field in * the DCBs is used to indicate that kernel processing is @@ -1399,7 +1333,7 @@ xgsm_cdma_halt_set(bkn_switch_info_t *sinfo, int chan) MEMORY_BARRIER; } -static int +static int xgsm_dma_chan_init(bkn_switch_info_t *sinfo, int chan, int dir) { uint32_t cdc; @@ -1872,7 +1806,7 @@ bkn_alloc_dcbs(bkn_switch_info_t *sinfo) rx_ring_size = dcb_size * (MAX_RX_DCBS + 1); sinfo->dcb_mem_size = tx_ring_size + rx_ring_size * sinfo->rx_chans; - sinfo->dcb_mem = DMA_ALLOC_COHERENT(sinfo->dma_dev, + sinfo->dcb_mem = BKN_DMA_ALLOC_COHERENT(sinfo->dma_dev, sinfo->dcb_mem_size, &dcb_dma); if (sinfo->dcb_mem == NULL) { @@ -1889,7 +1823,7 @@ static void bkn_free_dcbs(bkn_switch_info_t *sinfo) { if (sinfo->dcb_mem != NULL) { - DMA_FREE_COHERENT(sinfo->dma_dev, sinfo->dcb_mem_size, + BKN_DMA_FREE_COHERENT(sinfo->dma_dev, sinfo->dcb_mem_size, sinfo->dcb_mem, (dma_addr_t)sinfo->dcb_dma); sinfo->dcb_mem = NULL; } @@ -1907,9 +1841,9 @@ bkn_clean_tx_dcbs(bkn_switch_info_t *sinfo) if (desc->skb != NULL) { DBG_SKB(("Cleaning Tx SKB from DCB %d.\n", sinfo->tx.dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, - DMA_TODEV); + BKN_DMA_TODEV); desc->skb_dma = 0; dev_kfree_skb_any(desc->skb); desc->skb = NULL; @@ -1936,9 +1870,9 @@ bkn_clean_rx_dcbs(bkn_switch_info_t *sinfo, int chan) if (desc->skb != NULL) { DBG_SKB(("Cleaning Rx%d SKB from DCB %d.\n", chan, sinfo->rx[chan].dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, - DMA_FROMDEV); + BKN_DMA_FROMDEV); desc->skb_dma = 0; dev_kfree_skb_any(desc->skb); desc->skb = NULL; @@ -2327,10 +2261,10 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) desc->dma_size = 0; } #endif - desc->skb_dma = DMA_MAP_SINGLE(sinfo->dma_dev, + desc->skb_dma = BKN_DMA_MAP_SINGLE(sinfo->dma_dev, skb->data, desc->dma_size, - DMA_FROMDEV); - if (DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { + BKN_DMA_FROMDEV); + if (BKN_DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { dev_kfree_skb_any(skb); desc->skb = NULL; break; @@ -2532,8 +2466,7 @@ device_is_dnx(bkn_switch_info_t *sinfo) { int is_dnx = 0; - /* No EP_TO_CPU header for DNX(JR2) */ - is_dnx = ((sinfo->cmic_type == 'x') && (sinfo->pkt_hdr_size ==0)) ? 1 : 0; + is_dnx = (sinfo->dcb_type == 39) ? 1 : 0; return is_dnx; } @@ -2572,7 +2505,7 @@ bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, DBG_VERB(("Filter: size = %d (%d), data = 0x%08x, mask = 0x%08x\n", size, wsize, kf->data.w[0], kf->mask.w[0])); - if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { DBG_DUNE(("Filter: size = %d (wsize %d)\n", size, wsize)); for (idx = 0; idx < wsize; idx++) { @@ -2587,9 +2520,12 @@ bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, match = 1; if (match) { - if (device_is_sand(sinfo)) + if (device_is_dnx(sinfo)) { - /** priority 0 means no priority check */ + /* + * Mutliple RX channels are enabled on JR2 and above devices + * Bind between priority 0 and RX channel 0 is not checked, then all enabled RX channels can receive packets. + */ if (kf->priority && (kf->priority < (num_rx_prio * sinfo->rx_chans))) { if (kf->priority < (num_rx_prio * chan) || kf->priority >= (num_rx_prio * (chan + 1))) { @@ -2671,51 +2607,37 @@ bkn_netif_lookup(bkn_switch_info_t *sinfo, int id) } static int -bkn_hw_tstamp_rx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32 *meta) +bkn_hw_tstamp_rx_set(bkn_switch_info_t *sinfo, int phys_port, struct sk_buff *skb, uint32 *meta) { struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); - uint32_t *md = meta; uint64_t ts = 0; - switch (sinfo->dcb_type) { - case 26: - case 32: - case 33: - ts = md[14]; - ts = ts << 32 | md[12]; - break; - case 36: - ts = md[10]; - break; - case 38: - ts = md[4] & 0xffff; - ts = ts << 32 | md[5]; - break; - default: - return -1; - } if (knet_hw_tstamp_rx_time_upscale_cb) { - if (knet_hw_tstamp_rx_time_upscale_cb(sinfo->dev_no, &ts) < 0) { + if (knet_hw_tstamp_rx_time_upscale_cb(sinfo->dev_no, phys_port, skb, meta, &ts) < 0) { return -1; } } memset(shhwtstamps, 0, sizeof(*shhwtstamps)); - shhwtstamps->hwtstamp = ns_to_ktime(be64_to_cpu(ts)); + shhwtstamps->hwtstamp = ns_to_ktime(ts); return 0; } static int -bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta) +bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta, int len) { int pktlen = skb->len; uint32_t *dmeta, *smeta, wsize, psize; int idx; /* Add and clear RCPU encapsulation */ - if (sinfo->cmic_type == 'x') { + if (device_is_sand(sinfo)) { + psize = RCPU_RX_ENCAP_SIZE; + skb_push(skb, psize); + memset(skb->data, 0, RCPU_RX_ENCAP_SIZE); + } else if (sinfo->cmic_type == 'x') { psize = RCPU_HDR_SIZE + sinfo->pkt_hdr_size; skb_push(skb, psize); memset(skb->data, 0, RCPU_HDR_SIZE); @@ -2747,12 +2669,20 @@ bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta) /* Meta data */ dmeta = (uint32_t *)&skb->data[RCPU_HDR_SIZE]; - smeta = sinfo->cmic_type == 'x' ? (uint32_t *)meta : (uint32_t *)meta + 2; - wsize = sinfo->cmic_type == 'x' ? sinfo->pkt_hdr_size / 4 : sinfo->dcb_wsize - 3; - for (idx = 0; idx < wsize; idx++) { - dmeta[idx] = htonl(smeta[idx]); + + if (device_is_sand(sinfo)) { + /* Copy at most 64 bytes system headers */ + len = len > RCPU_RX_META_SIZE ? RCPU_RX_META_SIZE : len; + memcpy(&skb->data[RCPU_HDR_SIZE], (uint8_t *)meta, len); + } else { + smeta = sinfo->cmic_type == 'x' ? (uint32_t *)meta : (uint32_t *)meta + 2; + wsize = sinfo->cmic_type == 'x' ? sinfo->pkt_hdr_size / 4 : sinfo->dcb_wsize - 3; + for (idx = 0; idx < wsize; idx++) { + dmeta[idx] = htonl(smeta[idx]); + } } + return 0; } @@ -2781,7 +2711,6 @@ packet_is_untagged(uint16_t tpid) { int is_untagged = 0; - /* Fixme SDK-111398 */ /* 0x8100 is used in 802.1Q */ /* 0x8848 is used in 802.11ad, the dtag tpid can be set to anything besides 0x8848, 0x9100 is a typical value, but couldn't cover all scenarios. */ is_untagged = ((tpid != 0x8100) && (tpid != 0x8848) && (tpid != 0x9100)); @@ -2866,615 +2795,707 @@ bkn_bitstream_get_field(uint8_t *input_buffer, uint32_t start_bit, uint32_t no } static void -bkn_dpp_packet_parse_ftmh(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) -{ - uint32_t header_ptr = 0; - uint32_t dsp_ext_exist=0; +bkn_dpp_packet_parse_ftmh( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t *is_tsh_en, + uint8_t *is_inter_hdr_en) +{ + uint32_t pkt_offset = packet_info->system_header_size; + uint32_t dsp_ext_exist = 0; uint32_t fld_val; - header_ptr = packet_info->ntwrk_header_ptr; - - /* Packet-size */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_FTMH_PKT_SIZE_MSB, - BKN_DPP_FTMH_PKT_SIZE_NOF_BITS, - &fld_val); - packet_info->ftmh.packet_size = fld_val; - /* Traffic-class */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_FTMH_TC_MSB, - BKN_DPP_FTMH_TC_NOF_BITS, - &fld_val); - packet_info->ftmh.prio = fld_val; - /* Source-system-port-aggregate */ + /* FTMH: Source-system-port-aggregate */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_SRC_SYS_PORT_MSB, BKN_DPP_FTMH_SRC_SYS_PORT_NOF_BITS, - &fld_val); - packet_info->ftmh.src_sys_port = fld_val; - /* TM-action-type */ + &packet_info->ftmh.source_sys_port_aggregate); + /* FTMH: TM-action-type */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_ACTION_TYPE_MSB, BKN_DPP_FTMH_ACTION_TYPE_NOF_BITS, - &fld_val); - packet_info->ftmh.action_type = fld_val; - /* PPH-type */ + &packet_info->ftmh.action_type); + /* FTMH: Internal-type */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_PPH_TYPE_MSB, BKN_DPP_FTMH_PPH_TYPE_NOF_BITS, &fld_val); - packet_info->ftmh.pph_type = fld_val; - - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) Packet-size %d Action-type %d PPH-type %d Source-system-port 0x%x Traffic-class %d\n", - packet_info->ntwrk_header_ptr, packet_info->ftmh.packet_size, packet_info->ftmh.action_type, - packet_info->ftmh.pph_type, packet_info->ftmh.src_sys_port, packet_info->ftmh.prio)); - /* LB-Key ext */ - if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_LB_EXT_EN) == BKN_DPP_FTMH_LB_EXT_EN) - { - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_LB_EXT_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) FTMH LB-Key Extension is present\n", packet_info->ntwrk_header_ptr)); - } - /* DSP ext*/ - fld_val = 0; + /* FTMH: DSP Extension */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_EXT_DSP_EXIST_MSB, BKN_DPP_FTMH_EXT_DSP_EXIST_NOF_BITS, &dsp_ext_exist); + + if (fld_val & 0x1) + { + *is_inter_hdr_en = TRUE; + } + if (fld_val & 0x2) + { + *is_tsh_en = TRUE; + } + + pkt_offset += BKN_DPP_FTMH_SIZE_BYTE; + DBG_DUNE(("FTMH(9-%u): Action-type %d Source-system-port 0x%x\n", pkt_offset, + packet_info->ftmh.action_type, + packet_info->ftmh.source_sys_port_aggregate)); + + /* FTMH LB-Key Extension */ + if (sinfo->ftmh_lb_key_ext_size) + { + pkt_offset += sinfo->ftmh_lb_key_ext_size; + DBG_DUNE(("FTMH LB-Key Extension(1-%u) is present\n", pkt_offset)); + } + if (dsp_ext_exist) { - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) DSP-extension-present 1\n", packet_info->ntwrk_header_ptr)); + pkt_offset += BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE; + DBG_DUNE(("FTMH DSP Extension(2-%u) is present\n", pkt_offset)); } - /* stacking ext */ - if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_STACKING_EXT_EN) == BKN_DPP_FTMH_STACKING_EXT_EN) + /* FTMH Stacking Extension */ + if (sinfo->ftmh_stacking_ext_size) { - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_STACKING_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) FTMH Stacking Extension is present\n", packet_info->ntwrk_header_ptr)); + pkt_offset += sinfo->ftmh_stacking_ext_size; + DBG_DUNE(("FTMH Stacking Extension(2-%u) is present\n", pkt_offset)); } + + packet_info->system_header_size = pkt_offset; return; } static void -bkn_dpp_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) -{ - uint32_t header_ptr = 0; - uint32_t fld_val; +bkn_dpp_packet_parse_otsh( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t *is_oam_dm_tod_en, + uint8_t *is_skip_udh) +{ + uint32_t pkt_offset = packet_info->system_header_size; + uint32_t type = 0; + uint32_t oam_sub_type = 0; + + /* OTSH: TYPE */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_OTSH_TYPE_MSB, + BKN_DPP_OTSH_TYPE_NOF_BITS, + &type); + if (type == BKN_DPP_OTSH_TYPE_OAM) { + /* OTSH: OAM_SUB_TYPE */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_OTSH_OAM_SUB_TYPE_MSB, + BKN_DPP_OTSH_OAM_SUB_TYPE_NOF_BITS, + &oam_sub_type); + if ((oam_sub_type == BKN_DPP_OTSH_OAM_SUB_TYPE_DM_1588) || (oam_sub_type == BKN_DPP_OTSH_OAM_SUB_TYPE_DM_NTP)) { + *is_oam_dm_tod_en = TRUE; + /* Down MEP DM trapped packets will not have UDH present (even if configured), except for QAX when custom_feature_oam_dm_tod_msb_add_enable=0 */ + if (!sinfo->no_skip_udh_check) { + *is_skip_udh = TRUE; + } + } + } + packet_info->system_header_size += BKN_DPP_OTSH_SIZE_BYTE; + + DBG_DUNE(("OTSH(%d): Type 0x%x OAM-Sub-Type 0x%x\n", BKN_DPP_OTSH_SIZE_BYTE, type, oam_sub_type)); + return; +} + +static void +bkn_dpp_packet_parse_internal( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t is_oamp_punted, + uint8_t *is_trapped) +{ + uint32_t pkt_offset = packet_info->system_header_size; + uint32_t fld_val = 0; uint32_t eei_extension_present = 0; uint32_t learn_extension_present = 0; uint32_t fhei_size = 0; - uint32_t forward_code; - uint8_t is_trapped = 0; - - header_ptr = packet_info->ntwrk_header_ptr; + /* Internal: EEI EXT */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB, - BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_MSB, + BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_NOF_BITS, &eei_extension_present); + /* Internal: LERAN EXT */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB, - BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_MSB, + BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_NOF_BITS, &learn_extension_present); + /* Internal: FHEI EXT */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FHEI_SIZE_MSB, - BKN_DPP_PPH_FHEI_SIZE_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_FHEI_SIZE_MSB, + BKN_DPP_INTERNAL_FHEI_SIZE_NOF_BITS, &fhei_size); + /* Internal: FORWARD_CODE */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FORWARD_CODE_MSB, - BKN_DPP_PPH_FORWARD_CODE_NOF_BITS, - &forward_code); - /* 7: CPU-Trap */ - is_trapped = (uint8_t)(forward_code == 7); - + &buf[pkt_offset], + BKN_DPP_INTERNAL_FORWARD_CODE_MSB, + BKN_DPP_INTERNAL_FORWARD_CODE_NOF_BITS, + &fld_val); + *is_trapped = (uint8_t)(fld_val == BKN_DPP_INTERNAL_FORWARD_CODE_CPU_TRAP); + /* Internal: VSI */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_VSI_MSB, - BKN_DPP_PPH_VSI_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_VSI_MSB, + BKN_DPP_INTERNAL_VSI_NOF_BITS, &fld_val); - packet_info->internal.vsi = fld_val; + packet_info->internal.forward_domain = fld_val; - /* size of PPH base is 7 */ - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_SIZE_BYTE; - header_ptr = packet_info->ntwrk_header_ptr; + if (is_oamp_punted && *is_trapped) { + if(fhei_size == 3) { + /* Force to FHEI size 1 when packets are punted by OAMP */ + fhei_size = 1; + } + } - DBG_DUNE(("PPH(%d) Forward-Code %d EEI-Extension %d Learn-Extension %d VSI %d FHEI-size %d\n", packet_info->ntwrk_header_ptr, - forward_code, eei_extension_present, learn_extension_present, packet_info->internal.vsi, fhei_size)); + /* Move forward to end of Internal header */ + pkt_offset += BKN_DPP_INTERNAL_SIZE_BYTE; - /* PPH extension */ - if (is_trapped && (fhei_size == 1)) - { - /* CPU trap code qualifier */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB, - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS, - &fld_val); - packet_info->internal.trap_qualifier = fld_val; - /* CPU trap code */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB, - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS, - &fld_val); - packet_info->internal.trap_id = fld_val; - } + DBG_DUNE(("PPH(7-%u): EEI-Extension %d Learn-Extension %d VSI %d FHEI-size %d\n", + pkt_offset, eei_extension_present,learn_extension_present, packet_info->internal.forward_domain, fhei_size)); + + /* Advance header according to FHEI Trap extension */ switch(fhei_size) { case 1: - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_3B_SIZE_BYTE; + /* 3B FHEI Extension: do nothing, header poniter is in the right location */ break; case 2: - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_5B_SIZE_BYTE; + /* 5B FHEI Extension: adavance header pointer in 2B */ + pkt_offset += 2; break; case 3: - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_8B_SIZE_BYTE; + /* 8B FHEI Extension: adavance header pointer in 5B */ + pkt_offset += 5; break; default: break; } + + /* Internal extension */ + if (*is_trapped && fhei_size) + { + /* CPU trap code qualifier */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB, + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS, + &packet_info->internal.trap_qualifier); + /* CPU trap code */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB, + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS, + &packet_info->internal.trap_id); + + DBG_DUNE(("FHEI: trap_qualifier 0x%x trap_id 0x%x\n", + packet_info->internal.trap_qualifier, + packet_info->internal.trap_id)); + } + + /* Move forward to end of FHEI Trap extension */ + if (fhei_size) { + pkt_offset += 3; + } + + /* EEI extension */ if (eei_extension_present) { - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE; + pkt_offset += BKN_DPP_INTERNAL_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE; } + /* Learn extension */ if (learn_extension_present) { - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE; + pkt_offset += BKN_DPP_INTERNAL_LEARN_EXTENSION_SIZE_BYTE; } - DBG_DUNE(("FHEI(%d) trap_qualifier 0x%x trap_id 0x%x\n", packet_info->ntwrk_header_ptr, packet_info->internal.trap_qualifier, packet_info->internal.trap_id)); + packet_info->system_header_size = pkt_offset; return; } static int -bkn_dpp_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff_len, bkn_dune_system_header_info_t *packet_info) -{ - uint8_t hdr_buff[BKN_DPP_HDR_MAX_SIZE]; - uint32_t hdr_size; - uint8_t has_internal = 0; - - if ((buff == NULL) || (packet_info == NULL)) { +bkn_dpp_packet_header_parse( + bkn_switch_info_t *sinfo, + uint8_t *buff, + uint32_t buff_len, + bkn_dune_system_header_info_t *packet_info) +{ + uint8_t is_inter_hdr_en = FALSE; + uint8_t is_tsh_en = FALSE; + uint8_t is_oamp_punted = FALSE; + uint8_t is_trapped = FALSE; + uint8_t is_oam_dm_tod_en = FALSE; + uint8_t is_skip_udh = FALSE; + + if ((sinfo == NULL) || (buff == NULL) || (packet_info == NULL)) { return -1; } - hdr_size = buff_len < BKN_DPP_HDR_MAX_SIZE ? buff_len: BKN_DPP_HDR_MAX_SIZE; - memcpy(hdr_buff, buff, hdr_size); /* FTMH */ - bkn_dpp_packet_parse_ftmh(sinfo, hdr_buff, packet_info); - if (packet_info->ftmh.packet_size != (buff_len + 2)) { - DBG_DUNE(("FTMH packet size verfication failed, %d-%d\n", packet_info->ftmh.packet_size, buff_len)); - memset(packet_info, 0, sizeof(bkn_dune_system_header_info_t)); - return -1; + bkn_dpp_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + /* Check if packet is punted from OAMP */ + if (sinfo->oamp_punt && (packet_info->ftmh.source_sys_port_aggregate == sinfo->oamp_punt)) { + is_oamp_punted = TRUE; } - switch (packet_info->ftmh.pph_type) { - case 0: - has_internal = 0; - break; - case 1: - has_internal = 1; - break; - case 2: /* PPH OAM-TS only */ - case 3: /* PPH Base + OAM-TS */ - /* OTSH immediately follows the FTMH when present */ - packet_info->ntwrk_header_ptr += 6; - DBG_DUNE(("FTMH + OAM-TS(%d)\n", packet_info->ntwrk_header_ptr)); - has_internal = 1; - break; - default: - break; + /* OTSH */ + if (is_tsh_en == TRUE) + { + bkn_dpp_packet_parse_otsh(sinfo, buff, buff_len, packet_info, &is_oam_dm_tod_en, &is_skip_udh); + } + /* Internal header is forced to be present if packet was punted to CPU by OAMP */ + if (sinfo->oamp_punt && (packet_info->ftmh.source_sys_port_aggregate == sinfo->oamp_punt)) + { + is_inter_hdr_en = TRUE; + } + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dpp_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } + /* Skip UDH for the outer layer when packet is punted by OAM for JR2 in JR1 mode */ + if (device_is_dnx(sinfo) && is_oamp_punted) { + is_skip_udh = TRUE; + } + /* UDH */ + if (sinfo->udh_size && !is_skip_udh) { + packet_info->system_header_size += sinfo->udh_size; + } + /* OAM DM TOD header */ + if(is_oam_dm_tod_en) { + packet_info->system_header_size += BKN_DPP_OAM_DM_TOD_SIZE_BYTE; } - if (has_internal) { - bkn_dpp_packet_parse_internal(sinfo, &hdr_buff[0], packet_info); + /* Additional layer of system headers */ + if (is_oamp_punted && is_trapped) + { + is_inter_hdr_en = FALSE; + is_tsh_en = FALSE; + is_oamp_punted = FALSE; + is_trapped = FALSE; + is_oam_dm_tod_en = FALSE; + is_skip_udh = FALSE; + + /* FTMH */ + bkn_dpp_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + /* OTSH */ + if (is_tsh_en == TRUE) + { + bkn_dpp_packet_parse_otsh(sinfo, buff, buff_len, packet_info, &is_oam_dm_tod_en, &is_skip_udh); + } + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dpp_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } + /* OAMP Punted packets do not have UDH in the inner header for both JR1 and JR2 in JR1 mode */ + /* OAM DM TOD header */ + if(is_oam_dm_tod_en) { + packet_info->system_header_size += BKN_DPP_OAM_DM_TOD_SIZE_BYTE; + } } - /* FIXME: */ - /* ignore packets with a double set of FTMH,internals */ - /* ignore the user header size */ + DBG_DUNE(("Total length of headers is %u\n", packet_info->system_header_size)); + return 0; } + static int -bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buf, uint32_t buf_len, bkn_dune_system_header_info_t *packet_info) +bkn_dnx_packet_parse_ftmh( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t *is_tsh_en, + uint8_t *is_inter_hdr_en) { uint32_t fld_val; - uint32_t hdr_size = 0; - uint32_t pkt_offset_ingress_untrapped =0; + uint32_t pkt_offset = packet_info->system_header_size; uint8_t tm_dst_ext_present = 0; uint8_t app_specific_ext_size = 0; uint8_t flow_id_ext_size = 0; uint8_t bier_bfr_ext_size = 0; - uint8_t is_pph_en = 0; - uint8_t is_tsh_en = 0; - if ((buf == NULL) || (packet_info == NULL)) { + if ((sinfo == NULL) || (buf == NULL) || (packet_info == NULL)) { return -1; } /* FTMH: Source-System-Port-Aggregate */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_MSB, BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_NOF_BITS, &fld_val); - packet_info->ftmh_spa = fld_val; + packet_info->ftmh.source_sys_port_aggregate = fld_val; + /* FTMH: Action-Type */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_FTMH_ACTION_TYPE_MSB, + BKN_DNX_FTMH_ACTION_TYPE_NOF_BITS, + &fld_val); + packet_info->ftmh.action_type = fld_val; /* FTMH: PPH-Type TSH */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_MSB, BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_NOF_BITS, &fld_val); - is_tsh_en = fld_val; + *is_tsh_en = fld_val; /* FTMH: PPH-Type PPH base */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_MSB, BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_NOF_BITS, &fld_val); - is_pph_en = fld_val; + *is_inter_hdr_en = fld_val; /* FTMH: TM-Destination-Extension-Present */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_TM_DST_EXT_PRESENT_MSB, BKN_DNX_FTMH_TM_DST_EXT_PRESENT_NOF_BITS, &fld_val); tm_dst_ext_present = fld_val; /* FTMH: Application-Specific-Extension-Size */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_MSB, BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_NOF_BITS, &fld_val); app_specific_ext_size = fld_val; /* FTMH: Flow-ID-Extension-Size */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_MSB, BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_NOF_BITS, &fld_val); flow_id_ext_size = fld_val; /* FTMH: BIER-BFR-Extension-Size */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_MSB, BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_NOF_BITS, &fld_val); bier_bfr_ext_size = fld_val; - hdr_size = BKN_DNX_FTMH_BASE_SIZE; - pkt_offset_ingress_untrapped = BKN_DNX_FTMH_BASE_SIZE; + pkt_offset += BKN_DNX_FTMH_BASE_SIZE; - DBG_DUNE(("FTMH(%d) source-system-port 0x%x is_tsh_en %d is_pph_en %d\n", - hdr_size, packet_info->ftmh_spa, is_tsh_en, is_pph_en)); + DBG_DUNE(("FTMH(10-%u): source-system-port 0x%x action_type %u is_tsh_en %u is_inter_hdr_en %u\n", + pkt_offset, packet_info->ftmh.source_sys_port_aggregate, + packet_info->ftmh.action_type, *is_tsh_en, *is_inter_hdr_en)); /* FTMH LB-Key Extension */ if (sinfo->ftmh_lb_key_ext_size > 0) { - hdr_size += sinfo->ftmh_lb_key_ext_size; - DBG_DUNE(("FTMH LB-Key Extension(%d) is present\n", sinfo->ftmh_lb_key_ext_size)); + pkt_offset += sinfo->ftmh_lb_key_ext_size; + DBG_DUNE(("FTMH LB-Key Extension(%u-%u) is present\n", sinfo->ftmh_lb_key_ext_size, pkt_offset)); } /* FTMH Stacking Extension */ if (sinfo->ftmh_stacking_ext_size > 0) { - hdr_size += sinfo->ftmh_stacking_ext_size; - DBG_DUNE(("FTMH Stacking Extension(%d) is present\n", sinfo->ftmh_stacking_ext_size)); + pkt_offset += sinfo->ftmh_stacking_ext_size; + DBG_DUNE(("FTMH Stacking Extension(%u-%u) is present\n", sinfo->ftmh_stacking_ext_size, pkt_offset)); } /* FTMH BIER BFR Extension */ if (bier_bfr_ext_size > 0) { - hdr_size += BKN_DNX_FTMH_BIER_BFR_EXT_SIZE; - DBG_DUNE(("FTMH BIER BFR Extension(2) is present\n")); + pkt_offset += BKN_DNX_FTMH_BIER_BFR_EXT_SIZE; + DBG_DUNE(("FTMH BIER BFR Extension(2-%u) is present\n", pkt_offset)); } /* FTMH TM Destination Extension */ if (tm_dst_ext_present > 0) { - hdr_size += BKN_DNX_FTMH_TM_DST_EXT_SIZE; - DBG_DUNE(("FTMH TM Destination Extension(3) is present\n")); + pkt_offset += BKN_DNX_FTMH_TM_DST_EXT_SIZE; + DBG_DUNE(("FTMH TM Destination Extension(3-%u) is present\n", pkt_offset)); } /* FTMH Application Specific Extension */ if (app_specific_ext_size > 0) { - hdr_size += BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE; - DBG_DUNE(("FTMH Application Specific Extension(6) is present\n")); + pkt_offset += BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE; + DBG_DUNE(("FTMH Application Specific Extension(6-%u) is present\n", pkt_offset)); } /* FTMH Flow-ID Extension */ if (flow_id_ext_size > 0) { - hdr_size += BKN_DNX_FTMH_FLOW_ID_EXT_SIZE; - DBG_DUNE(("FTMH Flow-ID Extension(3) is present\n")); + pkt_offset += BKN_DNX_FTMH_FLOW_ID_EXT_SIZE; + DBG_DUNE(("FTMH Flow-ID Extension(3-%u) is present\n", pkt_offset)); } - /* Given the packet is trapped to CPU */ + packet_info->system_header_size = pkt_offset; - /* Time-Stamp Header */ - if (is_tsh_en == TRUE) - { - hdr_size += BKN_DNX_TSH_SIZE; - DBG_DUNE(("Time-Stamp Header(4) is present\n")); - } + return 0; +} - /* Packet Processing Header */ - if (is_pph_en) - { - uint8_t learn_ext_present; - uint8_t fhei_size; - uint8_t lif_ext_type; - switch (sinfo->pph_base_size) - { - case BKN_DNX_PPH_BASE_TYPE_9: - /* FTMH: Forward-Domain */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS, - &fld_val); - packet_info->pph_forward_domain = fld_val; - /* FTMH: Learn-Extension-Present */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB, - BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS, - &fld_val); - learn_ext_present = fld_val; - /* FTMH: FHEI-Size */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_FHEI_SIZE_MSB, - BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS, - &fld_val); - fhei_size = fld_val; - /* FTMH: LIF-Extension-Type */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB, - BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS, - &fld_val); - lif_ext_type = fld_val; +static int +bkn_dnx_packet_parse_internal( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t is_oamp_punted, + uint8_t *is_trapped) +{ + uint32_t fld_val; + uint32_t pkt_offset = packet_info->system_header_size; + uint8_t learn_ext_present; + uint8_t fhei_size; + uint8_t lif_ext_type; + uint8_t udh_en = sinfo->udh_enable; - hdr_size += BKN_DNX_PPH_BASE_TYPE_9; - DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", - packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); - break; - case BKN_DNX_PPH_BASE_TYPE_10: - /* FTMH: Forward-Domain */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS, - &fld_val); - packet_info->pph_forward_domain = fld_val; - /* FTMH: Learn-Extension-Present */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB, - BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS, - &fld_val); - learn_ext_present = fld_val; - /* FTMH: FHEI-Size */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_FHEI_SIZE_MSB, - BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS, - &fld_val); - fhei_size = fld_val; - /* FTMH: LIF-Extension-Type */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB, - BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS, - &fld_val); - lif_ext_type = fld_val; + if ((sinfo == NULL) || (buf == NULL) || (packet_info == NULL)) { + return -1; + } + + /* Internal: Forward-Domain */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_MSB, + BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_NOF_BITS, + &fld_val); + packet_info->internal.forward_domain = fld_val; + /* Internal: Learn-Extension-Present */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_MSB, + BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_NOF_BITS, + &fld_val); + learn_ext_present = fld_val; + /* Internal: FHEI-Size */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_FHEI_SIZE_MSB, + BKN_DNX_INTERNAL_12_FHEI_SIZE_NOF_BITS, + &fld_val); + fhei_size = fld_val; + /* Internal: LIF-Extension-Type */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_MSB, + BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_NOF_BITS, + &fld_val); + lif_ext_type = fld_val; - hdr_size += BKN_DNX_PPH_BASE_TYPE_10; - DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", - packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); + pkt_offset += BKN_DNX_INTERNAL_BASE_TYPE_12; + DBG_DUNE(("Internal(12-%u): FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", + pkt_offset, packet_info->internal.forward_domain, + learn_ext_present, fhei_size, lif_ext_type)); + + if (fhei_size) + { + switch (fhei_size) + { + case BKN_DNX_INTERNAL_FHEI_TYPE_SZ0: + pkt_offset += BKN_DNX_INTERNAL_FHEI_SZ0_SIZE; + DBG_DUNE(("FHEI(3-%u) is present\n", pkt_offset)); break; - case BKN_DNX_PPH_BASE_TYPE_12: - /* FTMH: Forward-Domain */ + case BKN_DNX_INTERNAL_FHEI_TYPE_SZ1: + /* FHEI: Type */ bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, + &buf[pkt_offset], + BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_MSB, + BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_NOF_BITS, &fld_val); - packet_info->pph_forward_domain = fld_val; - /* FTMH: Learn-Extension-Present */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB, - BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS, - &fld_val); - learn_ext_present = fld_val; - /* FTMH: FHEI-Size */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_FHEI_SIZE_MSB, - BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS, - &fld_val); - fhei_size = fld_val; - /* FTMH: LIF-Extension-Type */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB, - BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS, - &fld_val); - lif_ext_type = fld_val; - - hdr_size += BKN_DNX_PPH_BASE_TYPE_12; - DBG_DUNE(("PPH(12) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", - packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); - break; - default: - fhei_size = 0; - lif_ext_type = 0; - learn_ext_present = 0; - break; - } - if (fhei_size) - { - switch (fhei_size) - { - case BKN_DNX_PPH_FHEI_TYPE_SZ0: - hdr_size += BKN_DNX_PPH_FHEI_SZ0_SIZE; - DBG_DUNE(("FHEI(3) is present\n")); - break; - case BKN_DNX_PPH_FHEI_TYPE_SZ1: + /* FHEI-Size == 5B, FHEI-Type == Trap/Sniff */ + if (fld_val == 0x5) + { + *is_trapped = TRUE; + /* FHEI: Qualifier */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_MSB, + BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_NOF_BITS, + &fld_val); + packet_info->internal.trap_qualifier = fld_val; /* FHEI: Code */ bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB, - BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS, + &buf[pkt_offset], + BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_MSB, + BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_NOF_BITS, &fld_val); - packet_info->fhei_type = fld_val; - /* FHEI-Size == 5B, FHEI-Type == Trap/Sniff */ - if (packet_info->fhei_type == 0x5) - { - /* FHEI: Qualifier */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB, - BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS, - &fld_val); - packet_info->fhei_qualifier = fld_val; - /* FHEI: Code */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB, - BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS, - &fld_val); - packet_info->fhei_code = fld_val; - } - hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; - DBG_DUNE(("FHEI(5) is present code 0x%x qualifier 0x%x\n", packet_info->fhei_code, packet_info->fhei_qualifier)); - break; - case BKN_DNX_PPH_FHEI_TYPE_SZ2: - hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; - DBG_DUNE(("FHEI(8) is present\n")); - break; - } + packet_info->internal.trap_id= fld_val; + } + pkt_offset += BKN_DNX_INTERNAL_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(5-%u): code 0x%x qualifier 0x%x\n", pkt_offset, packet_info->internal.trap_id, packet_info->internal.trap_qualifier)); + break; + case BKN_DNX_INTERNAL_FHEI_TYPE_SZ2: + pkt_offset += BKN_DNX_INTERNAL_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(8-%u) is present\n", pkt_offset)); + break; } + } - /* PPH LIF Extension */ - if (lif_ext_type) - { - hdr_size += sinfo->pph_lif_ext_size[lif_ext_type]; - DBG_DUNE(("PPH LIF Extension(%d) is present\n", sinfo->pph_lif_ext_size[lif_ext_type])); - } + /* PPH LIF Extension */ + if (lif_ext_type) + { + pkt_offset += sinfo->pph_lif_ext_size[lif_ext_type]; + DBG_DUNE(("PPH LIF Extension(%d-%u) is present\n", sinfo->pph_lif_ext_size[lif_ext_type], pkt_offset)); + } - /* PPH Learn Extension */ - if (learn_ext_present) - { - hdr_size += BKN_DNX_PPH_LEARN_EXT_SIZE; - DBG_DUNE(("PPH Learn Extension(19) is present\n")); - } + /* PPH Learn Extension */ + if (learn_ext_present) + { + pkt_offset += BKN_DNX_INTERNAL_LEARN_EXT_SIZE; + DBG_DUNE(("PPH Learn Extension(19-%u) is present\n", pkt_offset)); + } + + /** Skip UDH If packet is punted to CPU by OAMP */ + if (is_oamp_punted) { + udh_en = FALSE; } /* UDH Header */ - if (sinfo->udh_enable) + if (udh_en) { - uint8 data_type_0; - uint8 data_type_1; - uint8 data_type_2; - uint8 data_type_3; - - DBG_DUNE(("UDH base(1) is present\n")); + uint8_t data_type_0; + uint8_t data_type_1; + uint8_t data_type_2; + uint8_t data_type_3; /* UDH: UDH-Data-Type[0] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_0_MSB, BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS, &fld_val); data_type_0 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_0]; /* UDH: UDH-Data-Type[1] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_1_MSB, BKN_DNX_UDH_DATA_TYPE_1_NOF_BITS, &fld_val); data_type_1 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_1]; /* UDH: UDH-Data-Type[2] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_2_MSB, BKN_DNX_UDH_DATA_TYPE_2_NOF_BITS, &fld_val); data_type_2 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_2]; /* UDH: UDH-Data-Type[3] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_3_MSB, BKN_DNX_UDH_DATA_TYPE_3_NOF_BITS, &fld_val); data_type_3 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_3]; - hdr_size += BKN_DNX_UDH_BASE_SIZE; + pkt_offset += BKN_DNX_UDH_BASE_SIZE; + pkt_offset += sinfo->udh_length_type[data_type_0]; + pkt_offset += sinfo->udh_length_type[data_type_1]; + pkt_offset += sinfo->udh_length_type[data_type_2]; + pkt_offset += sinfo->udh_length_type[data_type_3]; + DBG_DUNE(("UDH base(1-%u) is present\n", pkt_offset)); } - /* - * Check if fhei_type if of type trap - * There is a RISK that raw packet data is parsed and fhei_type is 0x5 by chance - */ - if (packet_info->fhei_type == 0x5) + packet_info->system_header_size = pkt_offset; + + return 0; +} + +static int +bkn_dnx_packet_header_parse( + bkn_switch_info_t *sinfo, + uint8_t *buff, + uint32_t buff_len, + bkn_dune_system_header_info_t *packet_info) +{ + uint8_t is_inter_hdr_en = FALSE; + uint8_t is_tsh_en = FALSE; + uint8_t is_oamp_punted = FALSE; + uint8_t is_trapped = FALSE; + + if ((sinfo == NULL) || (buff == NULL) || (packet_info == NULL)) { + return -1; + } + + /* FTMH */ + bkn_dnx_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + + /* Time-Stamp */ + if (is_tsh_en == TRUE) { - /* Done for ingress trapped packets */ - packet_info->system_header_size = hdr_size; - DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); - return 0; + packet_info->system_header_size += BKN_DNX_TSH_SIZE; + DBG_DUNE(("Time-Stamp Header(4-%u) is present\n", packet_info->system_header_size)); } - else + + /* Check if packet was punted to CPU by OAMP */ + if ((packet_info->ftmh.source_sys_port_aggregate == 232) + || (packet_info->ftmh.source_sys_port_aggregate == 233)) { - /* New generated header will be FTMH(80b), TSH(32b), PPH(96b), FHEI(40b) */ + is_oamp_punted = TRUE; + } - /* Revert packet_info except info from FTHM base header */ - packet_info->fhei_qualifier = 0; - packet_info->fhei_code = 0; - packet_info->fhei_type = 0; - hdr_size = pkt_offset_ingress_untrapped; + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dnx_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } - /* Time-Stamp Header */ - hdr_size += BKN_DNX_TSH_SIZE; - DBG_DUNE(("Time-Stamp Header(4) is present\n")); + if (is_oamp_punted) + { + is_inter_hdr_en = FALSE; + is_tsh_en = FALSE; + is_oamp_punted = FALSE; + is_trapped = FALSE; + + /* FTMH */ + bkn_dnx_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + /* Time-Stamp */ + if (is_tsh_en == TRUE) + { + packet_info->system_header_size += BKN_DNX_TSH_SIZE; + DBG_DUNE(("Time-Stamp Header(4-%u) is present\n", packet_info->system_header_size)); + } + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dnx_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } + } - /** Packet Processing Header */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, - &fld_val); - packet_info->pph_forward_domain = fld_val; - hdr_size += BKN_DNX_PPH_BASE_TYPE_12; - DBG_DUNE(("PPH(12) is present\n")); + DBG_DUNE(("Total length of headers is %u\n", packet_info->system_header_size)); - /* - * FHEI(Trap,40) - * 5B-FHEI format for sys_hdr_generation_profile:J2-OAM - * 8b' 0 - * 19b'oam_id - * 9b' cpu_trap_code: INGRESS_TRAP_ID is always 0 here - * 4b' type(0x5): J2-Configuration FHEI Type for CPU trap - */ - hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; - DBG_DUNE(("FHEI(5) is present\n")); + return 0; +} + +static int +bkn_packet_header_parse(bkn_switch_info_t *sinfo, uint8_t *buf, uint32_t buf_len, bkn_dune_system_header_info_t *packet_info) +{ + if (device_is_dpp(sinfo)) + { + bkn_dpp_packet_header_parse(sinfo, buf, buf_len, packet_info); + } + else if (device_is_dnx(sinfo)) + { + if (sinfo->system_headers_mode == BKN_DNX_JR2_MODE) + { + /* Jericho 2 mode */ + bkn_dnx_packet_header_parse(sinfo, buf, buf_len, packet_info); + } + else + { + /* Jericho/QMX/QAX mode */ + bkn_dpp_packet_header_parse(sinfo, buf, buf_len, packet_info); + } } - packet_info->system_header_size = hdr_size; - DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); return 0; } - static int bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) { @@ -3492,8 +3513,8 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) int pktlen; int idx; int dcbs_done = 0; - bkn_dune_system_header_info_t packet_info = {0}; - uint32_t dnx_meta_data[3] = {0}; + bkn_dune_system_header_info_t packet_info; + uint32_t sand_scratch_data[BKN_SAND_SCRATCH_DATA_SIZE] = {0}; dcb_chain = sinfo->rx[chan].api_dcb_chain; if (dcb_chain == NULL) { @@ -3536,84 +3557,76 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) pkt_dma = dcb[0]; } pkt = (uint8_t *)kernel_bde->p2l(sinfo->dev_no, (sal_paddr_t)pkt_dma); - if (sinfo->cmic_type == 'x') { - if (device_is_dnx(sinfo)){ - meta = &dnx_meta_data[0]; - /* get error bit from last DCB words */ - err_woff = 2; - meta[err_woff] = dcb[sinfo->dcb_wsize-1]; - } else { + + if (device_is_sand(sinfo)) { + err_woff = BKN_SAND_SCRATCH_DATA_SIZE - 1; + sand_scratch_data[err_woff] = dcb[sinfo->dcb_wsize-1]; + meta = (uint32_t *)pkt; + } else { + if (sinfo->cmic_type == 'x') { meta = (uint32_t *)pkt; err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } else { + meta = dcb; + err_woff = sinfo->dcb_wsize - 1; } - } else { - meta = dcb; - err_woff = sinfo->dcb_wsize - 1; } + pktlen = dcb[sinfo->dcb_wsize-1] & SOC_DCB_KNET_COUNT_MASK; bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); - if (device_is_dpp(sinfo)) { - uint16_t tpid = 0; - uint16_t vid = 0; - int res = -1; - + if (device_is_sand(sinfo)) { memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); - res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - if (packet_info.ftmh.action_type == 0x2) { - bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); - } else if (packet_info.ftmh.action_type == 0x1) { - bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); - } - bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); - bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); - bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); - pkt += packet_info.ntwrk_header_ptr; - pktlen -= packet_info.ntwrk_header_ptr; - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); - /* check if vlan tag exists */ - tpid = (uint16_t)((pkt[12] << 8) | pkt[13]); - vid = (uint16_t)(packet_info.internal.vsi & 0xfff); + /* decode system headers and fill sratch data */ + bkn_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + bkn_bitstream_set_field(sand_scratch_data, 0, 16, packet_info.internal.trap_id); + bkn_bitstream_set_field(sand_scratch_data, 16, 16, packet_info.internal.trap_qualifier); + bkn_bitstream_set_field(sand_scratch_data, 32, 16, packet_info.ftmh.source_sys_port_aggregate); + bkn_bitstream_set_field(sand_scratch_data, 48, 16, packet_info.internal.forward_domain); + bkn_bitstream_set_field(sand_scratch_data, 64, 2, packet_info.ftmh.action_type); + + if (force_tagged) { + uint8_t *eth_hdr = pkt + packet_info.system_header_size; + uint16_t tpid = 0; + + tpid = PKT_U16_GET(eth_hdr, 12); if (packet_is_untagged(tpid)) { + int raw_packet_len = pktlen - packet_info.system_header_size; + uint32_t vid = 0; + if ((pktlen + 4) < rx_buffer_size) { - DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); - for (idx = (pktlen-1); idx >= 12; idx--) { - pkt[idx+4] = pkt[idx]; + for (idx = (raw_packet_len - 1); idx >= 12; idx--) { + eth_hdr[idx+4] = eth_hdr[idx]; + } + if (ft_vid) { + vid = ft_vid; + } + else if (packet_info.internal.forward_domain) { + vid = packet_info.internal.forward_domain & 0xfff; } - pkt[12] = 0x81; - pkt[13] = 0x00; - pkt[14] = (vid >> 8); - pkt[15] = (vid & 0xff); + else { + vid = 1; + } + DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); + + eth_hdr[12] = (ft_tpid >> 8) & 0xff; + eth_hdr[13] = ft_tpid & 0xff; + eth_hdr[14] = (((ft_pri & 0x7) << 5) | ((ft_cfi & 0x1) << 4) | ((vid >> 8) & 0xf)) & 0xff; + eth_hdr[15] = vid & 0xff; /* reset packet length in DCB */ pktlen += 4; + bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; - dcb[sinfo->dcb_wsize-1] |= ((pktlen + packet_info.ntwrk_header_ptr) & SOC_DCB_KNET_COUNT_MASK); - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); + dcb[sinfo->dcb_wsize-1] |= pktlen & SOC_DCB_KNET_COUNT_MASK; } } } } - else if (device_is_dnx(sinfo)) { - int res = -1; - res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); - bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); - bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); - bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); - - pkt += packet_info.system_header_size; - pktlen -= packet_info.system_header_size; - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); - } - } - if (device_is_dpp(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, dcb, chan, &cbf); - } else if (device_is_dnx(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, meta, chan, &cbf); + if (device_is_sand(sinfo)) { + filter = bkn_match_rx_pkt(sinfo, pkt + packet_info.system_header_size, + pktlen - packet_info.system_header_size, sand_scratch_data, chan, &cbf); } else { filter = bkn_match_rx_pkt(sinfo, pkt + sinfo->pkt_hdr_size, pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); @@ -3643,7 +3656,10 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) break; } - if (sinfo->cmic_type == 'x') { + if (device_is_sand(sinfo)) { + pkt += packet_info.system_header_size; + pktlen -= packet_info.system_header_size; + } else if (sinfo->cmic_type == 'x') { pkt += sinfo->pkt_hdr_size; pktlen -= sinfo->pkt_hdr_size; } @@ -3663,12 +3679,14 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) skb_reserve(skb, 2); /* 16 byte align the IP fields. */ /* Save for RCPU before stripping tag */ - ethertype = (pkt[16] << 8) | pkt[17]; + ethertype = PKT_U16_GET(pkt, 16); if ((priv->flags & KCOM_NETIF_F_KEEP_RX_TAG) == 0) { + uint16_t vlan_proto = PKT_U16_GET(pkt, 12); + if (filter->kf.flags & KCOM_FILTER_F_STRIP_TAG) { /* Strip the VLAN tag */ - uint16_t vlan_proto = (uint16_t)((pkt[12] << 8) | pkt[13]); - if (vlan_proto == 0x8100 || vlan_proto == 0x88a8) { + if (vlan_proto == ETH_P_8021Q || + vlan_proto == ETH_P_8021AD) { DBG_FLTR(("Strip VLAN tag\n")); for (idx = 11; idx >= 0; idx--) { pkt[idx+4] = pkt[idx]; @@ -3681,12 +3699,18 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) * Mark packet as VLAN-tagged, otherwise newer * kernels will strip the tag. */ - uint16_t tci = (pkt[14] << 8) | pkt[15]; + uint16_t tci = PKT_U16_GET(pkt, 14); + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { bkn_vlan_hwaccel_put_tag(skb, ETH_P_8021Q, tci); } else { - bkn_vlan_hwaccel_put_tag(skb, - ((skb->data[12] << 8) | skb->data[13]), tci); + if (vlan_proto == ETH_P_8021AD) { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021AD, tci); + } else { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021Q, tci); + } } } } @@ -3702,11 +3726,16 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) priv->stats.rx_bytes += skb->len; /* Optional SKB updates */ + KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; if (knet_rx_cb != NULL) { KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; KNET_SKB_CB(skb)->filter_user_data = filter->kf.cb_user_data; - KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; - skb = knet_rx_cb(skb, sinfo->dev_no, meta); + if (device_is_sand(sinfo)) { + skb = knet_rx_cb(skb, sinfo->dev_no, sand_scratch_data); + } + else { + skb = knet_rx_cb(skb, sinfo->dev_no, meta); + } if (skb == NULL) { /* Consumed by call-back */ sinfo->rx[chan].pkts_d_callback++; @@ -3715,12 +3744,12 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } /* Do Rx timestamping */ - if (sinfo->rx_hwts) { - bkn_hw_tstamp_rx_set(sinfo, skb, meta); + if (priv->rx_hwts) { + bkn_hw_tstamp_rx_set(sinfo, priv->phys_port, skb, meta); } if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - bkn_add_rcpu_encap(sinfo, skb, meta); + bkn_add_rcpu_encap(sinfo, skb, meta, packet_info.system_header_size); DBG_PDMP(("After add RCPU ENCAP\n")); bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, XGS_DMA_RX_CHAN); } @@ -3792,7 +3821,9 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) int idx; int dcbs_done = 0; bkn_dune_system_header_info_t packet_info = {0}; - uint32_t dnx_meta_data[3] = {0}; + uint32_t sand_scratch_data[BKN_SAND_SCRATCH_DATA_SIZE] = {0}; + uint8_t sand_system_headers[RCPU_RX_META_SIZE] = {0}; + uint8_t *pkt = NULL; if (!sinfo->rx[chan].running) { /* Rx not ready */ @@ -3818,93 +3849,83 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } sinfo->rx[chan].pkts++; skb = desc->skb; - if (sinfo->cmic_type == 'x') { - if (device_is_dnx(sinfo)){ - meta = &dnx_meta_data[0]; - /* get error bit from last DCB words */ - err_woff = 2; - meta[err_woff] = dcb[sinfo->dcb_wsize-1]; - } else { + + if (device_is_sand(sinfo)) { + err_woff = BKN_SAND_SCRATCH_DATA_SIZE - 1; + sand_scratch_data[err_woff] = dcb[sinfo->dcb_wsize-1]; + meta = (uint32_t *)skb->data; + pkt = skb->data; + } else { + if (sinfo->cmic_type == 'x') { meta = (uint32_t *)skb->data; err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } else { + meta = dcb; + err_woff = sinfo->dcb_wsize - 1; } - } else { - meta = dcb; - err_woff = sinfo->dcb_wsize - 1; } + pktlen = dcb[sinfo->dcb_wsize-1] & 0xffff; priv = netdev_priv(sinfo->dev); DBG_DCB_RX(("Rx%d SKB DMA done (%d).\n", chan, sinfo->rx[chan].dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, - DMA_FROMDEV); + BKN_DMA_FROMDEV); desc->skb_dma = 0; bkn_dump_pkt(skb->data, pktlen, XGS_DMA_RX_CHAN); - if (device_is_dpp(sinfo)) { - uint16_t tpid = 0; - uint16_t vid = 0; - uint8_t *pkt = skb->data; - int res = 0; - + if (device_is_sand(sinfo)) { memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); - res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - if (packet_info.ftmh.action_type == 0x2) { - bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); - } else if (packet_info.ftmh.action_type == 0x1) { - bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); - } - bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); - bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); - bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); - pkt = skb->data + packet_info.ntwrk_header_ptr; - /* check if vlan tag exists */ - tpid = (uint16_t)((pkt[12] << 8) | pkt[13]); - vid = (uint16_t)(packet_info.internal.vsi & 0xfff); + /* decode system headers and fill sratch data */ + bkn_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + bkn_bitstream_set_field(sand_scratch_data, 0, 16, packet_info.internal.trap_id); + bkn_bitstream_set_field(sand_scratch_data, 16, 16, packet_info.internal.trap_qualifier); + bkn_bitstream_set_field(sand_scratch_data, 32, 16, packet_info.ftmh.source_sys_port_aggregate); + bkn_bitstream_set_field(sand_scratch_data, 48, 16, packet_info.internal.forward_domain); + bkn_bitstream_set_field(sand_scratch_data, 64, 2, packet_info.ftmh.action_type); + memcpy(sand_system_headers, pkt, + ((packet_info.system_header_size > RCPU_RX_META_SIZE) ? RCPU_RX_META_SIZE : packet_info.system_header_size)); + meta = (uint32_t *)sand_system_headers; + if (force_tagged) { + uint8_t *eth_hdr = pkt + packet_info.system_header_size; + uint16_t tpid = 0; + + tpid = PKT_U16_GET(eth_hdr, 12); if (packet_is_untagged(tpid)) { + int raw_packet_len = pktlen - packet_info.system_header_size; + uint32_t vid = 0; + if ((pktlen + 4) < rx_buffer_size) { - DBG_DUNE(("add vlan tag to untagged packets\n")); - for (idx = (pktlen-packet_info.ntwrk_header_ptr-1); idx >= 12; idx--) { - pkt[idx+4] = pkt[idx]; - } - pkt[12] = 0x81; - pkt[13] = 0x00; - pkt[14] = (vid >> 8); - pkt[15] = (vid & 0xff); - pktlen += 4; - /* reset packet length in DCB */ - dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; - dcb[sinfo->dcb_wsize-1] |= (pktlen & SOC_DCB_KNET_COUNT_MASK); - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); + for (idx = (raw_packet_len - 1); idx >= 12; idx--) { + eth_hdr[idx+4] = eth_hdr[idx]; + } + if (ft_vid) { + vid = ft_vid; + } + else if (packet_info.internal.forward_domain) { + vid = packet_info.internal.forward_domain & 0xfff; + } + else { + vid = 1; + } + DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); + eth_hdr[12] = (ft_tpid >> 8) & 0xff; + eth_hdr[13] = ft_tpid & 0xff; + eth_hdr[14] = (((ft_pri & 0x7) << 5) | ((ft_cfi & 0x1) << 4) | ((vid >> 8) & 0xf)) & 0xff; + eth_hdr[15] = vid & 0xff; + /* reset packet length in DCB */ + pktlen += 4; + bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); + dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; + dcb[sinfo->dcb_wsize-1] |= pktlen & SOC_DCB_KNET_COUNT_MASK; } } } } - else if (device_is_dnx(sinfo)) { - uint8_t *pkt = skb->data; - int res = -1; - - res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); - bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); - bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); - bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); - - pkt += packet_info.system_header_size; - pktlen -= packet_info.ntwrk_header_ptr; - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); - } - } - - if (device_is_dpp(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.ntwrk_header_ptr, - pktlen, dcb, chan, &cbf); - } else if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.system_header_size, - pktlen, meta, chan, &cbf); + pktlen - packet_info.system_header_size, sand_scratch_data, chan, &cbf); } else { filter = bkn_match_rx_pkt(sinfo, skb->data + sinfo->pkt_hdr_size, pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); @@ -3938,55 +3959,51 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) priv->id, priv->dev->name)); sinfo->rx[chan].pkts_f_netif++; - if (((filter->kf.mirror_type == KCOM_DEST_T_API) && - (!device_is_sand(sinfo))) || dbg_pkt_enable) { + if ((filter->kf.mirror_type == KCOM_DEST_T_API) || dbg_pkt_enable) { sinfo->rx[chan].pkts_m_api++; bkn_api_rx_copy_from_skb(sinfo, chan, desc); } - if (device_is_dpp(sinfo)) { - if (filter->kf.mirror_type == KCOM_DEST_T_API) { - sinfo->rx[chan].pkts_m_api++; - bkn_api_rx_copy_from_skb(sinfo, chan, desc); - } - /* Strip Dune headers */ - skb->data += packet_info.ntwrk_header_ptr; - pktlen -= packet_info.ntwrk_header_ptr; - bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); - /* CRC has been stripped on Dune*/ - skb_put(skb, pktlen); - } else if (device_is_dnx(sinfo)) { - if (filter->kf.mirror_type == KCOM_DEST_T_API) { - sinfo->rx[chan].pkts_m_api++; - bkn_api_rx_copy_from_skb(sinfo, chan, desc); - } - /* Strip Dune headers */ - skb->data += packet_info.system_header_size; - pktlen -= packet_info.system_header_size; - bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); + if (device_is_sand(sinfo)) { /* CRC has been stripped on Dune*/ skb_put(skb, pktlen); } else { skb_put(skb, pktlen - 4); /* Strip CRC */ } - if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { + skb_pull(skb, packet_info.system_header_size); + } else if (sinfo->cmic_type == 'x') { skb_pull(skb, sinfo->pkt_hdr_size); } + /* Optional SKB updates */ + KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; + /* Do Rx timestamping */ + if (priv->rx_hwts) { + bkn_hw_tstamp_rx_set(sinfo, priv->phys_port, skb, meta); + } + /* Save for RCPU before stripping tag */ - ethertype = (skb->data[16] << 8) | skb->data[17]; + ethertype = PKT_U16_GET(skb->data, 16); if ((priv->flags & KCOM_NETIF_F_KEEP_RX_TAG) == 0) { + uint16_t vlan_proto; + + vlan_proto = PKT_U16_GET(skb->data, 12); if (filter->kf.flags & KCOM_FILTER_F_STRIP_TAG) { /* Strip VLAN tag */ - uint16_t vlan_proto = (uint16_t)((skb->data[12] << 8) | skb->data[13]); - if (vlan_proto == 0x8100 || vlan_proto == 0x88a8) { + if (vlan_proto == ETH_P_8021Q || + vlan_proto == ETH_P_8021AD) { DBG_FLTR(("Strip VLAN tag\n")); ((u32*)skb->data)[3] = ((u32*)skb->data)[2]; ((u32*)skb->data)[2] = ((u32*)skb->data)[1]; ((u32*)skb->data)[1] = ((u32*)skb->data)[0]; skb_pull(skb, 4); - if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { + for (idx = packet_info.system_header_size; idx >= 4; idx--) { + pkt[idx] = pkt[idx - 4]; + } + } else if (sinfo->cmic_type == 'x') { for (idx = sinfo->pkt_hdr_size / sizeof(uint32_t); idx; idx--) { meta[idx] = meta[idx - 1]; } @@ -3998,25 +4015,35 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) * Mark packet as VLAN-tagged, otherwise newer * kernels will strip the tag. */ - uint16_t tci = (skb->data[14] << 8) | skb->data[15]; + uint16_t tci = PKT_U16_GET(skb->data, 14); + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { bkn_vlan_hwaccel_put_tag(skb, ETH_P_8021Q, tci); } else { - bkn_vlan_hwaccel_put_tag(skb, - ((skb->data[12] << 8) | skb->data[13]), tci); + if (vlan_proto == ETH_P_8021AD) { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021AD, tci); + } else { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021Q, tci); + } } } } + priv->stats.rx_packets++; priv->stats.rx_bytes += skb->len; skb->dev = priv->dev; - /* Optional SKB updates */ if (knet_rx_cb != NULL) { KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; KNET_SKB_CB(skb)->filter_user_data = filter->kf.cb_user_data; - KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; - skb = knet_rx_cb(skb, sinfo->dev_no, meta); + if (device_is_sand(sinfo)) { + skb = knet_rx_cb(skb, sinfo->dev_no, sand_scratch_data); + } + else { + skb = knet_rx_cb(skb, sinfo->dev_no, meta); + } if (skb == NULL) { /* Consumed by call-back */ sinfo->rx[chan].pkts_d_callback++; @@ -4026,13 +4053,8 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } - /* Do Rx timestamping */ - if (sinfo->rx_hwts) { - bkn_hw_tstamp_rx_set(sinfo, skb, meta); - } - if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - bkn_add_rcpu_encap(sinfo, skb, meta); + bkn_add_rcpu_encap(sinfo, skb, meta, packet_info.system_header_size); DBG_PDMP(("After add RCPU ENCAP\n")); bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, XGS_DMA_RX_CHAN); } @@ -4228,25 +4250,45 @@ bkn_resume_tx(bkn_switch_info_t *sinfo) } } +static void +bkn_skb_tstamp_copy(struct sk_buff *new_skb, struct sk_buff *skb) +{ + bkn_skb_tx_flags(new_skb) = bkn_skb_tx_flags(skb); + new_skb->sk = skb->sk; + + return; +} + static int bkn_hw_tstamp_tx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb) { - struct skb_shared_hwtstamps shhwtstamps; + int hwts; + int port; uint64_t ts = 0; uint32_t hdrlen = sinfo->cmic_type == 'x' ? PKT_TX_HDR_SIZE : 0; - int port; + struct skb_shared_hwtstamps shhwtstamps; if (!knet_hw_tstamp_tx_time_get_cb) { return -1; } port = KNET_SKB_CB(skb)->port; - if (knet_hw_tstamp_tx_time_get_cb(sinfo->dev_no, port, skb->data + hdrlen, &ts) < 0) { - return -1; + hwts = KNET_SKB_CB(skb)->hwts; + ts = KNET_SKB_CB(skb)->ts; + + + if (hwts == HWTSTAMP_TX_ONESTEP_SYNC) { + if (ts == 0) { + return 1; + } + } else if (hwts == HWTSTAMP_TX_ON) { + if (knet_hw_tstamp_tx_time_get_cb(sinfo->dev_no, port, skb->data + hdrlen, &ts) < 0) { + return -1; + } } memset(&shhwtstamps, 0, sizeof(shhwtstamps)); - shhwtstamps.hwtstamp = ns_to_ktime(be64_to_cpu(ts)); + shhwtstamps.hwtstamp = ns_to_ktime(ts); skb_tstamp_tx(skb, &shhwtstamps); return 0; @@ -4290,9 +4332,19 @@ bkn_do_tx(bkn_switch_info_t *sinfo) } if (desc->skb) { DBG_DCB_TX(("Tx SKB DMA done (%d).\n", sinfo->tx.dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, - DMA_TODEV); + BKN_DMA_TODEV); + + if ((KNET_SKB_CB(desc->skb)->hwts == HWTSTAMP_TX_ONESTEP_SYNC) && + (bkn_skb_tx_flags(desc->skb) & SKBTX_IN_PROGRESS)) { + + if (bkn_hw_tstamp_tx_set(sinfo, desc->skb) < 0) { + gprintk("Timestamp has not been taken for the current skb.\n"); + } + bkn_skb_tx_flags(desc->skb) &= ~SKBTX_IN_PROGRESS; + } + if (bkn_skb_tx_flags(desc->skb) & SKBTX_IN_PROGRESS) { skb_queue_tail(&sinfo->tx_ptp_queue, desc->skb); schedule_work(&sinfo->tx_ptp_work); @@ -4858,6 +4910,22 @@ xgsx_isr(bkn_switch_info_t *sinfo) /* Not ours */ return; } + + /* Bypass chain_done from Abort */ + if (device_is_dnx(sinfo)) { + uint32_t ctrl = 0; + int chan = 0; + for (chan = 0; chan < NUM_DMA_CHAN; chan++) { + if (irq_stat & CMICX_DS_CMC_CHAIN_DONE(chan)) { + DEV_READ32(sinfo, CMICX_DMA_CTRLr + 0x80 * chan, &ctrl); + if (ctrl & CMICX_DC_CMC_ABORT) { + DBG_IRQ(("chain %d: chain done for Abort\n", chan)); + return; + } + } + } + } + sinfo->interrupts++; DBG_IRQ(("Got interrupt on device %d (0x%08x)\n", @@ -5010,7 +5078,11 @@ bkn_open(struct net_device *dev) static int bkn_set_mac_address(struct net_device *dev, void *addr) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,18,12)) + if (!is_valid_ether_addr((const u8*)(((struct sockaddr *)addr)->sa_data))) { +#else if (!is_valid_ether_addr(((struct sockaddr *)addr)->sa_data)) { +#endif return -EINVAL; } memcpy(dev->dev_addr, ((struct sockaddr *)addr)->sa_data, dev->addr_len); @@ -5033,17 +5105,21 @@ bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!knet_hw_tstamp_enable_cb || !knet_hw_tstamp_disable_cb || priv->type != KCOM_NETIF_T_PORT) { - return -ERANGE; + return -ENOSYS; } switch (config.tx_type) { case HWTSTAMP_TX_OFF: - knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); - sinfo->tx_hwts = 0; + knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->tx_hwts = (config.tx_type); break; case HWTSTAMP_TX_ON: - knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); - sinfo->tx_hwts = 1; + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->tx_hwts = (config.tx_type); + break; + case HWTSTAMP_TX_ONESTEP_SYNC: + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->tx_hwts = (config.tx_type); break; default: return -ERANGE; @@ -5051,15 +5127,15 @@ bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch (config.rx_filter) { case HWTSTAMP_FILTER_NONE: - if (sinfo->rx_hwts) { - knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); - sinfo->rx_hwts = 0; + if (priv->rx_hwts) { + knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->rx_hwts = 0; } break; default: - if (!sinfo->rx_hwts) { - knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); - sinfo->rx_hwts = 1; + if (!priv->rx_hwts) { + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->rx_hwts = 1; } config.rx_filter = HWTSTAMP_FILTER_ALL; break; @@ -5071,8 +5147,8 @@ bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) if (cmd == SIOCGHWTSTAMP) { config.flags = 0; - config.tx_type = sinfo->tx_hwts ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; - config.rx_filter = sinfo->rx_hwts ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; + config.tx_type = priv->tx_hwts; + config.rx_filter = priv->rx_hwts ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; } @@ -5208,7 +5284,9 @@ bkn_set_multicast_list(struct net_device *dev) } static int -bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t *meta) +bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, + int hwts, int hdrlen, + struct sk_buff *skb, u32 *meta) { uint32_t *md = NULL; @@ -5217,7 +5295,13 @@ bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t } KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; - knet_hw_tstamp_tx_meta_get_cb(sinfo->dev_no, skb, &md); + knet_hw_tstamp_tx_meta_get_cb(sinfo->dev_no, hwts, hdrlen, skb, + &(KNET_SKB_CB(skb)->ts), (meta ? &md : NULL)); + + if (!meta) { + return 0; + } + if (!md) { return -1; } @@ -5233,10 +5317,10 @@ bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t break; case 36: case 38: - meta[0] |= md[0]; - meta[1] |= md[1]; - meta[2] |= md[2]; - meta[3] |= md[3]; + meta[0] |= htonl(md[0]); + meta[1] |= htonl(md[1]); + meta[2] |= htonl(md[2]); + meta[3] |= htonl(md[3]); break; default: return -1; @@ -5257,8 +5341,9 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) uint16_t tpid; uint32_t *metadata; unsigned long flags; + uint32_t cpu_channel = 0; - DBG_VERB(("Netif Tx: Len=%d\n", skb->len)); + DBG_VERB(("Netif Tx: Len=%d priv->id=%d\n", skb->len, priv->id)); if (priv->id <= 0) { /* Do not transmit on base device */ @@ -5267,8 +5352,14 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) return 0; } + if (device_is_dnx(sinfo) && (skb->len == 0)) { + priv->stats.tx_dropped++; + dev_kfree_skb_any(skb); + return 0; + } + if (!netif_carrier_ok(dev)) { - DBG_WARN(("Tx drop: Invalid RCPU encapsulation\n")); + DBG_WARN(("Tx drop: Netif link is down.\n")); priv->stats.tx_dropped++; sinfo->tx.pkts_d_no_link++; dev_kfree_skb_any(skb); @@ -5283,7 +5374,13 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) pktdata = skb->data; pktlen = skb->len; - hdrlen = (sinfo->cmic_type == 'x' ) ? ((device_is_dnx(sinfo)) ? priv->system_headers_size: PKT_TX_HDR_SIZE) : 0; + + if (device_is_sand(sinfo)) { + hdrlen = priv->system_headers_size; + } + else { + hdrlen = (sinfo->cmic_type == 'x' ) ? PKT_TX_HDR_SIZE : 0; + } rcpulen = 0; sop = 0; @@ -5298,7 +5395,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) return 0; } if (check_rcpu_signature && - ((skb->data[18] << 8) | skb->data[19]) != sinfo->rcpu_sig) { + PKT_U16_GET(skb->data, 18) != sinfo->rcpu_sig) { DBG_WARN(("Tx drop: Invalid RCPU signature\n")); priv->stats.tx_dropped++; sinfo->tx.pkts_d_rcpu_sig++; @@ -5306,7 +5403,15 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sinfo->lock, flags); return 0; } - if (skb->data[21] & RCPU_F_MODHDR) { + + if (device_is_sand(sinfo)) { + /* Dune devices don't use meta data */ + sop = 0; + /* Get CPU channel from rcpu_hdr_t.reserved */ + cpu_channel = (skb->data[28] << 24) | (skb->data[29] << 16) | (skb->data[30] << 8) | (skb->data[31]); + /* System headers are supposed to be set by users in RCPU mode. */ + hdrlen = 0; + } else if (skb->data[21] & RCPU_F_MODHDR) { sop = skb->data[RCPU_HDR_SIZE]; switch (sop) { case 0xff: @@ -5332,46 +5437,55 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) /* CPU packets require tag */ if (sop == 0) { - hdrlen = 0; - tpid = (pktdata[12] << 8) | pktdata[13]; - if (tpid != 0x8100) { - if (skb_header_cloned(skb)) { - /* Current SKB cannot be modified */ - DBG_SKB(("Realloc Tx SKB\n")); - new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); - if (new_skb == NULL) { - DBG_WARN(("Tx drop: No SKB memory\n")); - priv->stats.tx_dropped++; - sinfo->tx.pkts_d_no_skb++; + if (device_is_sand(sinfo)) { + /* + * There should be Module Header + PTCH_2 + [ITMH] on JR2, + * PTCH_2 +[ITMH] on JR1 + */ + } else { + hdrlen = 0; + tpid = PKT_U16_GET(pktdata, 12); + if (tpid != 0x8100) { + if (skb_header_cloned(skb)) { + /* Current SKB cannot be modified */ + DBG_SKB(("Realloc Tx SKB\n")); + new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); + if (new_skb == NULL) { + DBG_WARN(("Tx drop: No SKB memory\n")); + priv->stats.tx_dropped++; + sinfo->tx.pkts_d_no_skb++; + dev_kfree_skb_any(skb); + spin_unlock_irqrestore(&sinfo->lock, flags); + return 0; + } + memcpy(new_skb->data, pktdata, 12); + memcpy(&new_skb->data[16], &pktdata[12], pktlen - 12); + skb_put(new_skb, pktlen + TAG_SZ); + bkn_skb_tstamp_copy(new_skb, skb); dev_kfree_skb_any(skb); - spin_unlock_irqrestore(&sinfo->lock, flags); - return 0; - } - memcpy(new_skb->data, pktdata, 12); - memcpy(&new_skb->data[16], &pktdata[12], pktlen - 12); - skb_put(new_skb, pktlen + TAG_SZ); - dev_kfree_skb_any(skb); - skb = new_skb; - pktdata = skb->data; - rcpulen = 0; - } else { - /* Add tag to RCPU header space */ - DBG_SKB(("Expand into unused RCPU header\n")); - rcpulen -= TAG_SZ; - pktdata = &skb->data[rcpulen]; - for (idx = 0; idx < 12; idx++) { - pktdata[idx] = pktdata[idx + TAG_SZ]; + skb = new_skb; + pktdata = skb->data; + rcpulen = 0; + } else { + /* Add tag to RCPU header space */ + DBG_SKB(("Expand into unused RCPU header\n")); + rcpulen -= TAG_SZ; + pktdata = &skb->data[rcpulen]; + for (idx = 0; idx < 12; idx++) { + pktdata[idx] = pktdata[idx + TAG_SZ]; + } } + pktdata[12] = 0x81; + pktdata[13] = 0x00; + pktdata[14] = (priv->vlan >> 8) & 0xf; + pktdata[15] = priv->vlan & 0xff; + pktlen += TAG_SZ; } - pktdata[12] = 0x81; - pktdata[13] = 0x00; - pktdata[14] = (priv->vlan >> 8) & 0xf; - pktdata[15] = priv->vlan & 0xff; - pktlen += TAG_SZ; } } } else { - if (sinfo->cmic_type == 'x' && priv->port >= 0) { + if (((sinfo->cmic_type == 'x') && (priv->port >= 0)) + || device_is_sand(sinfo)) { if (skb_header_cloned(skb) || skb_headroom(skb) < hdrlen + 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); @@ -5384,12 +5498,13 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sinfo->lock, flags); return 0; } - if (!device_is_dnx(sinfo)) + if (!device_is_sand(sinfo)) { skb_reserve(new_skb, 4); } memcpy(new_skb->data + hdrlen, skb->data, pktlen); skb_put(new_skb, pktlen + hdrlen); + bkn_skb_tstamp_copy(new_skb, skb); dev_kfree_skb_any(skb); skb = new_skb; } else { @@ -5406,7 +5521,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (priv->port < 0 || (priv->flags & KCOM_NETIF_F_ADD_TAG)) { DBG_DUNE(("ADD VLAN TAG\n")); /* Need to add VLAN tag if packet is untagged */ - tpid = (skb->data[hdrlen + 12] << 8) | skb->data[hdrlen + 13]; + tpid = PKT_U16_GET(skb->data, hdrlen + 12); if (tpid != 0x8100) { if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { /* Current SKB cannot be modified */ @@ -5424,6 +5539,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) memcpy(&new_skb->data[hdrlen + 16], &skb->data[hdrlen + 12], pktlen - hdrlen - 12); skb_put(new_skb, pktlen + TAG_SZ); + bkn_skb_tstamp_copy(new_skb, skb); dev_kfree_skb_any(skb); skb = new_skb; } else { @@ -5446,7 +5562,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) /* Pad packet if needed */ taglen = 0; - tpid = (pktdata[hdrlen + 12] << 8) | pktdata[hdrlen + 13]; + tpid = PKT_U16_GET(pktdata, hdrlen + 12); if (tpid == 0x8100) { taglen = 4; } @@ -5478,8 +5594,19 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) meta = (sinfo->cmic_type == 'x') ? (uint32_t *)pktdata : dcb; memset(dcb, 0, sinfo->dcb_wsize * sizeof(uint32_t)); if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - /* If module header SOP is non-zero, use RCPU meta data */ - if (sop != 0) { + if (device_is_sand(sinfo)) { + if (sinfo->cmic_type == 'x') { + dcb[2] |= 1 << 19; + /* Given Module Header exists and set first byte to be CPU channel */ + pktdata[0] = cpu_channel; + } else { + dcb[1] |= 1 << 19; + /* Set CPU channel */ + dcb[2] = (cpu_channel & 0xff) << 24; + } + + } else if (sop != 0) { + /* If module header SOP is non-zero, use RCPU meta data */ if (sinfo->cmic_type == 'x') { dcb[2] |= 1 << 19; } else { @@ -5521,67 +5648,15 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) dcb[4] |= (priv->qnum & 0xfff) << 14; break; case 28: - { - if (priv->type == KCOM_NETIF_T_PORT) { - /* add PTCH ITMH header */ - if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { - /* Current SKB cannot be modified */ - DBG_SKB(("Realloc Tx SKB for DNX ITMH header\n")); - new_skb = dev_alloc_skb(pktlen + 4 + 2 + FCS_SZ); - if (new_skb == NULL) { - DBG_WARN(("Tx drop: No SKB memory for DNX ITMH header\n")); - priv->stats.tx_dropped++; - sinfo->tx.pkts_d_no_skb++; - dev_kfree_skb_any(skb); - spin_unlock_irqrestore(&sinfo->lock, flags); - return 0; - } - memcpy(&new_skb->data[6], skb->data, pktlen); - skb_put(new_skb, pktlen + 6); - dev_kfree_skb_any(skb); - skb = new_skb; - } else { - /* Add tag to existing buffer */ - DBG_SKB(("Expand Tx SKB for DNX ITMH header\n")); - skb_push(skb, 6); - } - pktdata = skb->data; - pktdata[0] = 0x50; - pktdata[1] = 0x00; - memcpy(&pktdata[2], priv->itmh, 4); - pktlen += 6; - } - else if (priv->type == KCOM_NETIF_T_VLAN) { - /* add PTCH header */ - if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { - /* Current SKB cannot be modified */ - DBG_SKB(("Realloc Tx SKB for DNX header\n")); - new_skb = dev_alloc_skb(pktlen + 2 + FCS_SZ); - if (new_skb == NULL) { - DBG_WARN(("Tx drop: No SKB memory for DNX header\n")); - priv->stats.tx_dropped++; - sinfo->tx.pkts_d_no_skb++; - dev_kfree_skb_any(skb); - spin_unlock_irqrestore(&sinfo->lock, flags); - return 0; - } - memcpy(&new_skb->data[2], skb->data, pktlen); - skb_put(new_skb, pktlen + 2); - dev_kfree_skb_any(skb); - skb = new_skb; - } else { - /* Add tag to existing buffer */ - DBG_SKB(("Expand Tx SKB for DNX header\n")); - skb_push(skb, 2); - } - pktdata = skb->data; - pktdata[0] = 0xd0; - pktdata[1] = priv->port; - pktlen += 2; - } - dcb[1] = pktlen; - break; - } + /* + * If KCOM_NETIF_T_PORT, add PTCH+ITMH header + * If KCOM_NETIF_T_VLAN, add PTCH+header + */ + pktdata = skb->data; + memcpy(&pktdata[0], priv->system_headers, priv->system_headers_size); + /* Set CPU channel */ + dcb[2] = ((priv->qnum & 0xff) << 24); + break; case 29: dcb[2] = 0x81000000; dcb[3] = priv->port; @@ -5640,6 +5715,19 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) memcpy(&pktdata[0], priv->system_headers, priv->system_headers_size); } break; + case 40: + if (sinfo->cmic_type == 'x') { + meta[0] = htonl(0x81000000); + meta[1] = htonl(priv->port | (priv->qnum & 0xc00) << 20); + meta[2] = htonl(0x00040000 | (priv->qnum & 0x3ff) << 8); + } else { + dcb[2] = 0x81000000; + dcb[3] = priv->port; + dcb[3] |= (priv->qnum & 0xc00) << 20; + dcb[4] = 0x00040000; + dcb[4] |= (priv->qnum & 0x3ff) << 8; + } + break; default: dcb[2] = 0xff000000; dcb[3] = 0x00000100; @@ -5695,24 +5783,46 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } /* Do Tx timestamping */ - if (priv->port >= 0) { - if (bkn_skb_tx_flags(skb) & SKBTX_HW_TSTAMP && sinfo->tx_hwts) { - KNET_SKB_CB(skb)->port = priv->port; - bkn_hw_tstamp_tx_config(sinfo, skb, meta); + if (bkn_skb_tx_flags(skb) & SKBTX_HW_TSTAMP) { + KNET_SKB_CB(skb)->hwts = priv->tx_hwts; + if ((priv->port >= 0) && (priv->tx_hwts & HWTSTAMP_TX_ON)) { + /* TwoStep Processing of ptp-packets */ + KNET_SKB_CB(skb)->port = priv->phys_port; + bkn_hw_tstamp_tx_config(sinfo, priv->tx_hwts, PKT_TX_HDR_SIZE, skb, meta); + bkn_skb_tx_flags(skb) |= SKBTX_IN_PROGRESS; + bkn_skb_tx_timestamp(skb); + + } else if (priv->tx_hwts & HWTSTAMP_TX_ONESTEP_SYNC) { + + /* OneStep Processing of ptp-packets */ + KNET_SKB_CB(skb)->port = priv->phys_port; + KNET_SKB_CB(skb)->ts = 0; + bkn_hw_tstamp_tx_config(sinfo, priv->tx_hwts, PKT_TX_HDR_SIZE, skb, + ((priv->port >= 0) ? meta : NULL)); + + if (KNET_SKB_CB(skb)->ts != 0) { + bkn_skb_tx_flags(skb) |= SKBTX_IN_PROGRESS; + bkn_skb_tx_timestamp(skb); + } + } - bkn_skb_tx_timestamp(skb); } /* Prepare for DMA */ desc->skb = skb; - /* Add FCS bytes */ - pktlen = pktlen + FCS_SZ; + /* + * Add FCS bytes + * FCS bytes are always appended to packet by MAC on Dune devices + */ + if (!device_is_sand(sinfo)) { + pktlen = pktlen + FCS_SZ; + } desc->dma_size = pktlen; - desc->skb_dma = DMA_MAP_SINGLE(sinfo->dma_dev, + desc->skb_dma = BKN_DMA_MAP_SINGLE(sinfo->dma_dev, pktdata, desc->dma_size, - DMA_TODEV); - if (DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { + BKN_DMA_TODEV); + if (BKN_DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { priv->stats.tx_dropped++; dev_kfree_skb_any(skb); spin_unlock_irqrestore(&sinfo->lock, flags); @@ -5758,6 +5868,10 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) priv->stats.tx_bytes += pktlen; sinfo->tx.pkts++; } else { +#ifdef SAI_FIXUP /* SDK-224448 */ + DBG_VERB(("Tx busy: No DMA resources\n")); + sinfo->tx.pkts_d_dma_resrc++; +#else DBG_WARN(("Tx drop: No DMA resources\n")); priv->stats.tx_dropped++; sinfo->tx.pkts_d_dma_resrc++; @@ -5766,7 +5880,12 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) /* Check our Tx resources */ if (sinfo->tx.free <= 1) { +#endif /* SDK-224448 */ bkn_suspend_tx(sinfo); +#ifdef SAI_FIXUP /* SDK-224448 */ + spin_unlock_irqrestore(&sinfo->lock, flags); + return BKN_NETDEV_TX_BUSY; +#endif /* SDK-224448 */ } NETDEV_UPDATE_TRANS_START_TIME(dev); @@ -6079,6 +6198,7 @@ bkn_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) case 33: case 36: case 38: + case 40: info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_RX_HARDWARE | @@ -6105,11 +6225,43 @@ bkn_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) } #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) +static int bkn_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *cmd) +{ + bkn_priv_t *priv = netdev_priv(netdev); + + /* only speed info now, can enhance later */ + if (priv) { + cmd->base.speed = priv->link_settings.speed; + cmd->base.duplex = priv->link_settings.duplex; + } + return 0; +} + +static int bkn_set_link_ksettings(struct net_device *netdev, + const struct ethtool_link_ksettings *cmd) +{ + bkn_priv_t *priv = netdev_priv(netdev); + + /* only speed info now, can enhance later */ + if (priv) { + priv->link_settings.speed = cmd->base.speed; + priv->link_settings.duplex = cmd->base.speed? DUPLEX_FULL : 0; + } + return 0; +} +#endif + static const struct ethtool_ops bkn_ethtool_ops = { .get_drvinfo = bkn_get_drvinfo, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) .get_ts_info = bkn_get_ts_info, #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) + .get_link_ksettings = bkn_get_link_ksettings, + .set_link_ksettings = bkn_set_link_ksettings, +#endif }; static struct net_device * @@ -6165,8 +6317,8 @@ bkn_init_ndev(u8 *mac, char *name) strncpy(dev->name, name, IFNAMSIZ-1); } -#ifdef CONFIG_NET_NS - dev_net_set(dev, current->nsproxy->net_ns); +#if defined(CONFIG_NET_NS) + bkn_dev_net_set(dev, current->nsproxy->net_ns); #endif /* Register the kernel Ethernet device */ @@ -6739,9 +6891,11 @@ bkn_proc_debug_show(struct seq_file *m, void *v) seq_printf(m, " use_napi: %d\n", use_napi); seq_printf(m, " napi_weight: %d\n", napi_weight); seq_printf(m, " basedev_susp: %d\n", basedev_suspend); - seq_printf(m, "Thread states:\n"); - seq_printf(m, " Command thread: %d\n", bkn_cmd_ctrl.state); - seq_printf(m, " Event thread: %d\n", bkn_evt_ctrl.state); + seq_printf(m, " force_tagged: %d\n", force_tagged); + seq_printf(m, " ft_tpid: %d\n", ft_tpid); + seq_printf(m, " ft_pri: %d\n", ft_pri); + seq_printf(m, " ft_pri: %d\n", ft_cfi); + seq_printf(m, " ft_tpid: %d\n", ft_vid); seq_printf(m, "Active IOCTLs:\n"); seq_printf(m, " Command: %d\n", ioctl_cmd); seq_printf(m, " Event: %d\n", ioctl_evt); @@ -7510,6 +7664,27 @@ bkn_knet_hw_init(kcom_msg_hw_init_t *kmsg, int len) } } + if (device_is_sand(sinfo)) { + int idx = 0; + /* Information to parser Dune system headers */ + sinfo->ftmh_lb_key_ext_size = kmsg->ftmh_lb_key_ext_size; + sinfo->ftmh_stacking_ext_size = kmsg->ftmh_stacking_ext_size; + sinfo->pph_base_size = kmsg->pph_base_size; + for (idx = 0; idx < 8; idx++) + { + sinfo->pph_lif_ext_size[idx] = kmsg->pph_lif_ext_size[idx]; + } + for (idx = 0; idx < 4; idx++) + { + sinfo->udh_length_type[idx] = kmsg->udh_length_type[idx]; + } + sinfo->udh_size = kmsg->udh_size; + sinfo->oamp_punt = kmsg->oamp_punted; + sinfo->no_skip_udh_check = kmsg->no_skip_udh_check; + sinfo->system_headers_mode = kmsg->system_headers_mode; + sinfo->udh_enable = kmsg->udh_enable; + } + /* Ensure that we restart properly */ bkn_dma_abort(sinfo); bkn_clean_dcbs(sinfo); @@ -7552,13 +7727,13 @@ bkn_knet_detach(kcom_msg_detach_t *kmsg, int len) } spin_lock_irqsave(&sinfo->lock, flags); - - /* Create dummy event to unblock pending IOCTL */ - sinfo->dma_events |= KCOM_DMA_INFO_F_TX_DONE; - evt = &_bkn_evt[sinfo->evt_idx]; - evt->evt_wq_put++; - wake_up_interruptible(&evt->evt_wq); - + if (sinfo->evt_idx != -1) { + /* Create dummy event to unblock pending IOCTL */ + sinfo->dma_events |= KCOM_DMA_INFO_F_TX_DONE; + evt = &_bkn_evt[sinfo->evt_idx]; + evt->evt_wq_put++; + wake_up_interruptible(&evt->evt_wq); + } spin_unlock_irqrestore(&sinfo->lock, flags); /* Ensure that we return a valid unit number */ @@ -7591,7 +7766,7 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) bkn_priv_t *priv, *lpriv; unsigned long flags; int found, id; - uint8 *ma; + uint8_t *ma; kmsg->hdr.type = KCOM_MSG_TYPE_RSP; @@ -7623,26 +7798,26 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) priv->sinfo = sinfo; priv->type = kmsg->netif.type; priv->vlan = kmsg->netif.vlan; + /* System headers are prepared at BCM API for Dune headers */ + if (device_is_sand(sinfo)) { + int idx = 0; + for (idx = 0; idx < KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX; idx++) + { + priv->system_headers[idx] = kmsg->netif.system_headers[idx]; + } + priv->system_headers_size = kmsg->netif.system_headers_size; + } if (priv->type == KCOM_NETIF_T_PORT) { priv->port = kmsg->netif.port; - if (device_is_dpp(sinfo)) { - memcpy(priv->itmh, kmsg->netif.itmh, 4); - } else if (device_is_dnx(sinfo)) { - memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); - priv->system_headers_size = kmsg->netif.system_headers_size; - } + priv->phys_port = kmsg->netif.phys_port; priv->qnum = kmsg->netif.qnum; + memset(&(priv->link_settings), 0, sizeof(struct ethtool_link_settings));; } else { - if (device_is_sand(sinfo)) { - if (device_is_dpp(sinfo)) { - priv->port = kmsg->netif.port; - priv->qnum = kmsg->netif.qnum; - }else if (device_is_dnx(sinfo)) { - memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); - priv->system_headers_size = kmsg->netif.system_headers_size; - } - } - else { + if (device_is_sand(sinfo) && (priv->type == KCOM_NETIF_T_VLAN)) { + /* PTCH.SSPA */ + priv->port = kmsg->netif.port; + priv->qnum = kmsg->netif.qnum; + } else { priv->port = -1; } } @@ -7711,7 +7886,7 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) kmsg->netif.id = priv->id; memcpy(kmsg->netif.macaddr, dev->dev_addr, 6); memcpy(kmsg->netif.name, dev->name, KCOM_NETIF_NAME_MAX - 1); - + if (knet_netif_create_cb != NULL) { int retv = knet_netif_create_cb(kmsg->hdr.unit, &(kmsg->netif), dev); if (retv) { @@ -7721,7 +7896,7 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) spin_unlock_irqrestore(&sinfo->lock, flags); - if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { int idx = 0; for (idx = 0; idx < priv->system_headers_size; idx++) { DBG_DUNE(("System Header[%d]: 0x%02x\n", idx, priv->system_headers[idx])); @@ -7857,6 +8032,7 @@ bkn_knet_netif_get(kcom_msg_netif_get_t *kmsg, int len) kmsg->netif.type = priv->type; kmsg->netif.id = priv->id; kmsg->netif.flags = priv->flags; + kmsg->netif.cb_user_data = priv->cb_user_data; if (priv->port < 0) { kmsg->netif.port = 0; @@ -7918,7 +8094,6 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) kmsg->hdr.status = KCOM_E_RESOURCE; return sizeof(kcom_msg_hdr_t); } - filter = kmalloc(sizeof(*filter), GFP_ATOMIC); if (filter == NULL) { spin_unlock_irqrestore(&sinfo->lock, flags); @@ -7927,17 +8102,6 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) } memset(filter, 0, sizeof(*filter)); memcpy(&filter->kf, &kmsg->filter, sizeof(filter->kf)); - - if (device_is_dnx(sinfo)) { - /* Information to parser Dune system headers */ - sinfo->ftmh_lb_key_ext_size = kmsg->filter.ftmh_lb_key_ext_size; - sinfo->ftmh_stacking_ext_size = kmsg->filter.ftmh_stacking_ext_size; - sinfo->pph_base_size = kmsg->filter.pph_base_size; - memcpy(sinfo->pph_lif_ext_size, kmsg->filter.pph_lif_ext_size, sizeof(sinfo->pph_lif_ext_size)); - sinfo->udh_enable = kmsg->filter.udh_enable; - memcpy(sinfo->udh_length_type, kmsg->filter.udh_length_type, sizeof(sinfo->udh_length_type)); - } - filter->kf.id = id; /* Add according to priority */ @@ -7960,8 +8124,7 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) DBG_VERB(("Created filter ID %d (%s).\n", filter->kf.id, filter->kf.desc)); - - if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { int idx, wsize; wsize = BYTES2WORDS(filter->kf.oob_data_size + filter->kf.pkt_data_size); DBG_DUNE(("Filter: oob_data_size = %d pkt_data_size=%d wsize %d\n", filter->kf.oob_data_size, filter->kf.pkt_data_size, wsize)); @@ -7974,7 +8137,6 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) sinfo->pph_lif_ext_size[1],sinfo->pph_lif_ext_size[2], sinfo->pph_lif_ext_size[3], sinfo->udh_enable, sinfo->udh_length_type[0], sinfo->udh_length_type[1], sinfo->udh_length_type[2], sinfo->udh_length_type[3])); } - return len; } @@ -8055,7 +8217,6 @@ bkn_knet_filter_list(kcom_msg_filter_list_t *kmsg, int len) kmsg->fcnt = idx; spin_unlock_irqrestore(&sinfo->lock, flags); - return sizeof(*kmsg) - sizeof(kmsg->id) + (idx * sizeof(kmsg->id[0])); } @@ -8254,6 +8415,24 @@ bkn_handle_cmd_req(kcom_msg_t *kmsg, int len) /* Clean up for warmbooting */ len = bkn_knet_wb_cleanup(&kmsg->wb_cleanup, len); break; + case KCOM_M_CLOCK_CMD: + /* PHC clock control*/ + if (knet_hw_tstamp_ioctl_cmd_cb) { + bkn_switch_info_t *sinfo; + sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); + if (sinfo == NULL) { + /* The device is not probed or initialized yet.*/ + return 0; + } + DBG_CMD(("KCOM_M_CLOCK_CMD\n")); + len = knet_hw_tstamp_ioctl_cmd_cb(&kmsg->clock_cmd, len, sinfo->dcb_type); + } else { + DBG_WARN(("Unsupported command (type=%d, opcode=%d)\n", + kmsg->hdr.type, kmsg->hdr.opcode)); + kmsg->hdr.opcode = 0; + len = sizeof(kcom_msg_hdr_t); + } + break; default: DBG_WARN(("Unsupported command (type=%d, opcode=%d)\n", kmsg->hdr.type, kmsg->hdr.opcode)); @@ -8264,39 +8443,6 @@ bkn_handle_cmd_req(kcom_msg_t *kmsg, int len) return len; } -static int -bkn_cmd_thread(void *context) -{ - bkn_thread_ctrl_t *tc = (bkn_thread_ctrl_t *)context; - kcom_msg_t kmsg; - unsigned int len, rlen; - - bkn_thread_boot(tc); - - DBG_VERB(("Command thread starting\n")); - tc->state = 1; - while (!bkn_thread_should_stop(tc)) { - len = sizeof(kmsg); - tc->state = 2; - if (PROXY_RECV(KCOM_CHAN_KNET, &kmsg, &len) >= 0) { - DBG_VERB(("Received %d bytes from KCOM_CHAN_CMD\n", len)); - tc->state = 3; - rlen = bkn_handle_cmd_req(&kmsg, len); - tc->state = 4; - if (rlen > 0) { - PROXY_SEND(KCOM_CHAN_KNET, &kmsg, rlen); - } - } else { - /* Thread interrupted */ - bkn_sleep(1); - } - } - DBG_VERB(("Command thread done\n")); - - bkn_thread_exit(tc); - return 0; -} - static int bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) { @@ -8370,38 +8516,6 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) return sizeof(*kmsg); } -static int -bkn_evt_thread(void *context) -{ - bkn_thread_ctrl_t *tc = (bkn_thread_ctrl_t *)context; - kcom_msg_dma_info_t kmsg; - int len; - - bkn_thread_boot(tc); - - memset(&kmsg, 0, sizeof(kmsg)); - kmsg.hdr.type = KCOM_MSG_TYPE_EVT; - kmsg.hdr.opcode = KCOM_M_DMA_INFO; - - DBG_VERB(("Event thread starting\n")); - tc->state = 1; - while (!bkn_thread_should_stop(tc)) { - tc->state = 2; - len = bkn_get_next_dma_event(&kmsg); - tc->state = 3; - if (len) { - PROXY_SEND(KCOM_CHAN_KNET, &kmsg, len); - } else { - /* Thread interrupted */ - bkn_sleep(1); - } - } - DBG_VERB(("Event thread done\n")); - - bkn_thread_exit(tc); - return 0; -} - static int _cleanup(void) { @@ -8415,15 +8529,6 @@ _cleanup(void) /* Inidicate that we are shutting down */ module_initialized = 0; - /* Shut down event thread */ - bkn_thread_stop(&bkn_evt_ctrl); - - /* Shut down command thread */ - bkn_thread_stop(&bkn_cmd_ctrl); - - /* Remove KCOM channel */ - PROXY_SERVICE_DESTROY(KCOM_CHAN_KNET); - bkn_proc_cleanup(); remove_proc_entry("bcm/knet", NULL); remove_proc_entry("bcm", NULL); @@ -8586,7 +8691,6 @@ bkn_knet_dev_init(int d) priv->sinfo = sinfo; priv->vlan = 1; priv->port = -1; - memset(priv->itmh, 0, sizeof(priv->itmh)); priv->id = -1; } @@ -8659,16 +8763,6 @@ _init(void) evt = &_bkn_evt[0]; init_waitqueue_head(&evt->evt_wq); - if (use_proxy) { - PROXY_SERVICE_CREATE(KCOM_CHAN_KNET, 1, 0); - - DBG_VERB(("Starting command thread\n")); - bkn_thread_start(&bkn_cmd_ctrl, "bkncmd", bkn_cmd_thread); - - DBG_VERB(("Starting event thread\n")); - bkn_thread_start(&bkn_evt_ctrl, "bknevt", bkn_evt_thread); - } - module_initialized = 1; return 0; @@ -8704,7 +8798,7 @@ _ioctl(unsigned int cmd, unsigned long arg) io.len = bkn_handle_cmd_req(&kmsg, io.len); ioctl_cmd--; } else { - memset(&kmsg, 0, sizeof(kcom_msg_dma_info_t)); + memset(&kmsg, 0, sizeof(kcom_msg_t)); /* * Retrive the kmsg.hdr.unit from user space. The dma event queue * selection is based the instance derived from unit. @@ -9018,6 +9112,27 @@ bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f return 0; } +int +bkn_hw_tstamp_ioctl_cmd_cb_register(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb) +{ + if (knet_hw_tstamp_ioctl_cmd_cb != NULL) { + return -1; + } + knet_hw_tstamp_ioctl_cmd_cb = hw_tstamp_ioctl_cmd_cb; + return 0; +} + +int +bkn_hw_tstamp_ioctl_cmd_cb_unregister(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb) +{ + if (knet_hw_tstamp_ioctl_cmd_cb == NULL || + knet_hw_tstamp_ioctl_cmd_cb != hw_tstamp_ioctl_cmd_cb) { + return -1; + } + knet_hw_tstamp_ioctl_cmd_cb = NULL; + return 0; +} + LKM_EXPORT_SYM(bkn_rx_skb_cb_register); LKM_EXPORT_SYM(bkn_rx_skb_cb_unregister); LKM_EXPORT_SYM(bkn_tx_skb_cb_register); @@ -9041,3 +9156,5 @@ LKM_EXPORT_SYM(bkn_netif_create_cb_register); LKM_EXPORT_SYM(bkn_netif_create_cb_unregister); LKM_EXPORT_SYM(bkn_netif_destroy_cb_register); LKM_EXPORT_SYM(bkn_netif_destroy_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_ioctl_cmd_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_ioctl_cmd_cb_unregister); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/Makefile new file mode 100644 index 000000000000..1c9a3209e133 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/Makefile @@ -0,0 +1,65 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 1.3 Broadcom SDK $ +# $Copyright: (c) 2020 Broadcom. +# Broadcom Proprietary and Confidential. All rights reserved.$ +# +LOCALDIR = systems/linux/kernel/modules/bcm-ptp-clock + +include ${SDK}/make/Make.config + +LIBS = $(LIBDIR)/libkern.a + +ifeq ($(kernel_version),2_4) +MODULE = $(LIBDIR)/linux-bcm-ptp-clock.o +else +KERNEL_MODULE_DIR = kernel_module + +THIS_MOD_NAME := linux-bcm-ptp-clock +MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o +KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko + +build: $(MODULE) $(KMODULE) +endif + +#KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../../../../bde/linux/kernel/kernel_module/Module.symvers +KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers + +# BCM PTP Clock Device + +$(MODULE): $(BLDDIR)/.tree $(BOBJS) $(LIBS) + $(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@ +ifneq ($(kernel_version),2_4) +$(KMODULE): $(MODULE) + rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR) + mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR) + cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile + cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers + MOD_NAME=$(THIS_MOD_NAME) $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko +endif + +# Make.depend is before clean:: so that Make.depend's clean:: runs first. + +include ${SDK}/make/Make.depend + +clean:: + $(RM) $(BLDDIR)/version.c $(BLDDIR)/version.o + $(RM) $(BOBJS) $(MODULE) + +ifneq ($(kernel_version),2_4) +.PHONY: build +endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/bcm-ptp-clock.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/bcm-ptp-clock.c new file mode 100644 index 000000000000..5b0a6bde738d --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/bcm-ptp-clock.c @@ -0,0 +1,1981 @@ +/* + * Copyright 2017 Broadcom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ + +/* + * This module implements a Linux PTP Clock driver for Broadcom + * XGS switch devices. + * + * For a list of supported module parameters, please see below. + * debug: Debug level (default 0) + * network_transport : Transport Type (default 0 - Raw) + * base_dev_name: Base device name (default ptp0, ptp1, etc.) + * + * - All the data structures and functions work on the physical port. + * For array indexing purposes, we use (phy_port - 1). + */ + +#include /* Must be included first */ +/* Module Information */ +#define MODULE_MAJOR 125 +#define MODULE_NAME "linux-bcm-ptp-clock" + +MODULE_AUTHOR("Broadcom Corporation"); +MODULE_DESCRIPTION("PTP Clock Driver for Broadcom XGS Switch"); +MODULE_LICENSE("GPL"); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Configuration Parameters */ +static int debug; +LKM_MOD_PARAM(debug, "i", int, 0); +MODULE_PARM_DESC(debug, + "Debug level (default 0)"); + +static int pci_cos; + +static int network_transport; +LKM_MOD_PARAM(network_transport, "i", int, 0); +MODULE_PARM_DESC(network_transport, + "Transport Type (default - Detect from packet)"); + +static char *base_dev_name = "ptp0"; +LKM_MOD_PARAM(base_dev_name, "s", charp, 0); +MODULE_PARM_DESC(base_dev_name, + "Base device name (default ptp0, ptp1, etc.)"); + +static int fw_core; +LKM_MOD_PARAM(fw_core, "i", int, 0); +MODULE_PARM_DESC(fw_core, + "Firmware core (default 0)"); + +/* Debug levels */ +#define DBG_LVL_VERB 0x1 +#define DBG_LVL_WARN 0x2 + +#define DBG_VERB(_s) do { if (debug & DBG_LVL_VERB) gprintk _s; } while (0) +#define DBG_WARN(_s) do { if (debug & DBG_LVL_WARN) gprintk _s; } while (0) +#define DBG_ERR(_s) do { if (1) gprintk _s; } while (0) + + +#ifdef LINUX_BDE_DMA_DEVICE_SUPPORT +#define DMA_DEV device +#define DMA_ALLOC_COHERENT(d,s,h) dma_alloc_coherent(d,s,h,GFP_ATOMIC|GFP_DMA32) +#define DMA_FREE_COHERENT(d,s,a,h) dma_free_coherent(d,s,a,h) +#else +#define DMA_DEV pci_dev +#define DMA_ALLOC_COHERENT(d,s,h) pci_alloc_consistent(d,s,h) +#define DMA_FREE_COHERENT(d,s,a,h) pci_free_consistent(d,s,a,h) +#endif + +/* Type length in bytes */ +#define BKSYNC_PACKLEN_U8 1 +#define BKSYNC_PACKLEN_U16 2 +#define BKSYNC_PACKLEN_U24 3 +#define BKSYNC_PACKLEN_U32 4 + +#define BKSYNC_UNPACK_U8(_buf, _var) \ + _var = *_buf++ + +#define BKSYNC_UNPACK_U16(_buf, _var) \ + do { \ + (_var) = (((_buf)[0] << 8) | \ + (_buf)[1]); \ + (_buf) += BKSYNC_PACKLEN_U16; \ + } while (0) + +#define BKSYNC_UNPACK_U24(_buf, _var) \ + do { \ + (_var) = (((_buf)[0] << 16) | \ + ((_buf)[1] << 8) | \ + (_buf)[2]); \ + (_buf) += BKSYNC_PACKLEN_U24; \ + } while (0) + +#define BKSYNC_UNPACK_U32(_buf, _var) \ + do { \ + (_var) = (((_buf)[0] << 24) | \ + ((_buf)[1] << 16) | \ + ((_buf)[2] << 8) | \ + (_buf)[3]); \ + (_buf) += BKSYNC_PACKLEN_U32; \ + } while (0) + + +#define CMICX_DEV_TYPE ((ptp_priv->dcb_type == 38) || \ + (ptp_priv->dcb_type == 36)) + +#define HOSTCMD_USE_REGS ((ptp_priv->dcb_type == 38) || \ + (ptp_priv->dcb_type == 36) || \ + (ptp_priv->dcb_type == 32)) + +/* CMIC MCS-0 SCHAN Messaging registers */ +/* Core0:CMC1 Core1:CMC2 */ +#define CMIC_CMC_BASE \ + (CMICX_DEV_TYPE ? (fw_core ? 0x10400 : 0x10300) : \ + (fw_core ? 0x33000 : 0x32000)) + +#define CMIC_CMC_SCHAN_MESSAGE_10r(BASE) (BASE + 0x00000034) +#define CMIC_CMC_SCHAN_MESSAGE_11r(BASE) (BASE + 0x00000038) +#define CMIC_CMC_SCHAN_MESSAGE_12r(BASE) (BASE + 0x0000003c) +#define CMIC_CMC_SCHAN_MESSAGE_13r(BASE) (BASE + 0x00000040) +#define CMIC_CMC_SCHAN_MESSAGE_14r(BASE) (BASE + 0x00000044) +#define CMIC_CMC_SCHAN_MESSAGE_15r(BASE) (BASE + 0x00000048) +#define CMIC_CMC_SCHAN_MESSAGE_16r(BASE) (BASE + 0x0000004c) +#define CMIC_CMC_SCHAN_MESSAGE_17r(BASE) (BASE + 0x00000050) +#define CMIC_CMC_SCHAN_MESSAGE_18r(BASE) (BASE + 0x00000054) +#define CMIC_CMC_SCHAN_MESSAGE_19r(BASE) (BASE + 0x00000058) +#define CMIC_CMC_SCHAN_MESSAGE_20r(BASE) (BASE + 0x0000005c) +#define CMIC_CMC_SCHAN_MESSAGE_21r(BASE) (BASE + 0x00000060) + +u32 hostcmd_regs[5] = { 0 }; + +/* TX Timestamp FIFO Access */ +#define BCM_NUM_PORTS 128 + +/* Service request commands to R5 */ +enum { + BCM_KSYNC_DONE = 0x0, + BCM_KSYNC_INIT = 0x1, + BCM_KSYNC_DEINIT = 0x2, + BCM_KSYNC_GETTIME = 0x3, + BCM_KSYNC_SETTIME = 0x4, + BCM_KSYNC_FREQCOR = 0x5, + BCM_KSYNC_PBM_UPDATE = 0x6, + BCM_KSYNC_ADJTIME = 0x7, + BCM_KSYNC_GET_TSTIME = 0x8, +}; + +/* Usage macros */ +#define ONE_BILLION (1000000000) + +#define SKB_U16_GET(_skb, _pkt_offset) \ + ((_skb->data[_pkt_offset] << 8) | _skb->data[_pkt_offset + 1]) + +#define BKSYNC_PTP_EVENT_MSG(_ptp_msg_type) \ + ((_ptp_msg_type == DELAY_REQ) || (_ptp_msg_type == SYNC)) + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) +#define HWTSTAMP_TX_ONESTEP_SYNC 2 +#else +#include +#endif + + +/* Values for the messageType field */ +#define SYNC 0x0 +#define DELAY_REQ 0x1 + +/* + * Hardware specific information. + * 4 words of information used from this data set. + * 0 - 3: 2-step untagged. + * 4 - 7: 2-step tagged. + * 8 - 11: 1-step untagged. + * 12 - 15: 1-step tagged. + * 16 - 19: 1-step untagged with ITS-set. + * 20 - 23: 1-step tagged with ITS-set. + */ +uint32_t sobmhrawpkts_dcb26[24] = {0x00000000, 0x00020E00, 0x00000000, 0x00000000, 0x00000000, 0x00021200, 0x00000000, 0x00000000, + 0x00000000, 0x00100E00, 0x00000000, 0x00000000, 0x00000000, 0x00101200, 0x00000000, 0x00000000, + 0x00000000, 0x00140E00, 0x00000000, 0x00000000, 0x00000000, 0x00141200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb26[24] = {0x00000000, 0x00022A00, 0x00000000, 0x00000000, 0x00000000, 0x00022E00, 0x00000000, 0x00000000, + 0x00000000, 0x00102A00, 0x00000000, 0x00000000, 0x00000000, 0x00102E00, 0x00000000, 0x00000000, + 0x00000000, 0x00142A00, 0x00000000, 0x00000000, 0x00000000, 0x00142E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb26[24] = {0x00000000, 0x00023E00, 0x00000000, 0x00000000, 0x00000000, 0x00024200, 0x00000000, 0x00000000, + 0x00000000, 0x00103E00, 0x00000000, 0x00000000, 0x00000000, 0x00104200, 0x00000000, 0x00000000, + 0x00000000, 0x00143E00, 0x00000000, 0x00000000, 0x00000000, 0x00144200, 0x00000000, 0x00000000}; + +uint32_t sobmhrawpkts_dcb32[24] = {0x00000000, 0x00010E00, 0x00000000, 0x00000000, 0x00000000, 0x00011200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb32[24] = {0x00000000, 0x00012A00, 0x00000000, 0x00000000, 0x00000000, 0x00012E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb32[24] = {0x00000000, 0x00013E00, 0x00000000, 0x00000000, 0x00000000, 0x00014200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000}; + +uint32_t sobmhrawpkts_dcb36[24] = {0x00000000, 0x00010E00, 0x00000000, 0x00000000, 0x00000000, 0x00011200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb36[24] = {0x00000000, 0x00012A00, 0x00000000, 0x00000000, 0x00000000, 0x00012E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb36[24] = {0x00000000, 0x00013E00, 0x00000000, 0x00000000, 0x00000000, 0x00014200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000}; +/* th3: onestep only */ +uint32_t sobmhrawpkts_dcb38[24] = {0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb38[24] = {0x00000000, 0x00082A00, 0x00000000, 0x00000000, 0x00000000, 0x00082E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb38[24] = {0x00000000, 0x00083E00, 0x00000000, 0x00000000, 0x00000000, 0x00084200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000}; + +/* Driver Proc Entry root */ +static struct proc_dir_entry *bksync_proc_root = NULL; + +/* Shared data structures with R5 */ +typedef struct _bksync_tx_ts_data_s +{ + u32 ts_valid; /* Timestamp valid indication */ + u32 port_id; /* Port number */ + u32 ts_seq_id; /* Sequency Id */ + u32 ts_cnt; + u64 timestamp; /* Timestamp */ +} bksync_tx_ts_data_t; + +typedef struct _bksync_uc_linux_ipc_s +{ + u32 ksyncinit; + u32 dev_id; + s64 freqcorr; + u64 portmap[BCM_NUM_PORTS/64]; + u64 ptptime; + u64 reftime; + s64 phase_offset; + bksync_tx_ts_data_t port_ts_data[BCM_NUM_PORTS]; +} bksync_uc_linux_ipc_t; + +typedef struct bksync_port_stats_s { + u32 pkt_rxctr; /* All ingress packets */ + u32 pkt_txctr; /* All egress packets */ + u32 tsts_match; /* 2-Step tstamp req match */ + u32 tsts_timeout; /* 2-Step tstamp req timeouts */ + u32 tsts_discard; /* 2-Step tstamp req discards */ + u32 osts_event_pkts; /* 1-step event packet counter */ + u32 osts_tstamp_reqs; /* 1-step events with tstamp request */ +} bksync_port_stats_t; + +/* Clock Private Data */ +struct bksync_ptp_priv { + struct device dev; + int dcb_type; + struct ptp_clock *ptp_clock; + struct ptp_clock_info ptp_caps; + struct mutex ptp_lock; + struct mutex ptp_pair_lock; + volatile void *base_addr; /* address for PCI register access */ + volatile bksync_uc_linux_ipc_t *shared_addr; /* address for shared memory access */ + uint64_t dma_mem; + int dma_mem_size; + int num_pports; + struct DMA_DEV *dma_dev; /* Required for DMA memory control */ + u32 pkt_rxctr[BCM_NUM_PORTS]; + u32 pkt_txctr[BCM_NUM_PORTS]; + u32 ts_match[BCM_NUM_PORTS]; + u32 ts_timeout[BCM_NUM_PORTS]; + u32 ts_discard[BCM_NUM_PORTS]; + int timekeep_status; + struct delayed_work time_keep; + bksync_port_stats_t *port_stats; +}; + +static struct bksync_ptp_priv *ptp_priv; +volatile bksync_uc_linux_ipc_t *linuxPTPMemory = (bksync_uc_linux_ipc_t*)(0); +static volatile int module_initialized; +static int retry_count = 10; /* Default retry for 10 jiffies */ + +static void bksync_ptp_time_keep_init(void); +static void bksync_ptp_time_keep_deinit(void); + +#if defined(CMIC_SOFT_BYTE_SWAP) + +#define CMIC_SWAP32(_x) ((((_x) & 0xff000000) >> 24) \ + | (((_x) & 0x00ff0000) >> 8) \ + | (((_x) & 0x0000ff00) << 8) \ + | (((_x) & 0x000000ff) << 24)) + +#define DEV_READ32(_d, _a, _p) \ + do { \ + uint32_t _data; \ + _data = (((volatile uint32_t *)(_d)->base_addr)[(_a)/4]); \ + *(_p) = CMIC_SWAP32(_data); \ + } while(0) + +#define DEV_WRITE32(_d, _a, _v) \ + do { \ + uint32_t _data = CMIC_SWAP32(_v); \ + ((volatile uint32_t *)(_d)->base_addr)[(_a)/4] = (_data); \ + } while(0) + +#else + +#define DEV_READ32(_d, _a, _p) \ + do { \ + *(_p) = (((volatile uint32_t *)(_d)->base_addr)[(_a)/4]); \ + } while(0) + +#define DEV_WRITE32(_d, _a, _v) \ + do { \ + ((volatile uint32_t *)(_d)->base_addr)[(_a)/4] = (_v); \ + } while(0) +#endif /* defined(CMIC_SOFT_BYTE_SWAP) */ + +static void +ptp_usleep(int usec) +{ + usleep_range(usec,usec+1); +} + +static void +ptp_sleep(int jiffies) +{ + wait_queue_head_t wq; + init_waitqueue_head(&wq); + + wait_event_timeout(wq, 0, jiffies); + +} + + +static int bksync_cmd_cmicm_go(u32 cmd, void *data0, void *data1) +{ + int ret = -1; + int retry_cnt = retry_count; + u32 cmd_status; + + mutex_lock(&ptp_priv->ptp_lock); + ptp_priv->shared_addr->ksyncinit = cmd; + switch (cmd) { + case BCM_KSYNC_INIT: + ptp_priv->shared_addr->phase_offset = 0; + ret = 0; + break; + case BCM_KSYNC_FREQCOR: + ptp_priv->shared_addr->freqcorr = *((s32 *)data0); + break; + case BCM_KSYNC_ADJTIME: + ptp_priv->shared_addr->phase_offset = *((s64 *)data0); + break; + case BCM_KSYNC_GETTIME: + break; + case BCM_KSYNC_SETTIME: + ptp_priv->shared_addr->ptptime = *((s64 *)data0); + ptp_priv->shared_addr->phase_offset = 0; + break; + default: + break; + } + + do { + cmd_status = ptp_priv->shared_addr->ksyncinit; + if (cmd_status == BCM_KSYNC_DONE) { + switch (cmd) { + case BCM_KSYNC_GETTIME: + *((s64 *)data0) = ptp_priv->shared_addr->ptptime; + *((s64 *)data1) = ptp_priv->shared_addr->reftime; /* ptp counter */ + break; + default: + break; + } + ret = 0; + break; + } + ptp_sleep(1); + retry_cnt--; + } while (retry_cnt); + mutex_unlock(&ptp_priv->ptp_lock); + + if (retry_cnt == 0) { + DBG_ERR(("Timeout on response from R5\n")); + } + + + return ret; +} + + + +static void bksync_hostcmd_data_op(int setget, u64 *d1, u64 *d2) +{ + u32 w0, w1; + u64 data; + + if (!d1) { + return; + } + + if (setget) { + data = *d1; + w0 = (data & 0xFFFFFFFF); + w1 = (data >> 32); + DEV_WRITE32(ptp_priv, hostcmd_regs[1], w0); + DEV_WRITE32(ptp_priv, hostcmd_regs[2], w1); + } else { + DEV_READ32(ptp_priv, hostcmd_regs[1], &w0); + DEV_READ32(ptp_priv, hostcmd_regs[2], &w1); + data = (((u64)w1 << 32) | (w0)); + *d1 = data; + + if (d2) { + DEV_READ32(ptp_priv, hostcmd_regs[3], &w0); + DEV_READ32(ptp_priv, hostcmd_regs[4], &w1); + data = (((u64)w1 << 32) | (w0)); + *d2 = data; + } + } +} + + +static int bksync_cmd_cmicx_go(u32 cmd, void *data0, void *data1) +{ + int ret = -1; + int retry_cnt = (retry_count * 100); + u32 cmd_status; + char cmd_str[20]; + + mutex_lock(&ptp_priv->ptp_lock); + ptp_priv->shared_addr->ksyncinit = cmd; + + /* init data */ + DEV_WRITE32(ptp_priv, hostcmd_regs[1], 0x0); + DEV_WRITE32(ptp_priv, hostcmd_regs[2], 0x0); + DEV_WRITE32(ptp_priv, hostcmd_regs[3], 0x0); + DEV_WRITE32(ptp_priv, hostcmd_regs[4], 0x0); + + switch (cmd) { + case BCM_KSYNC_INIT: + sprintf(cmd_str, "KSYNC_INIT"); + ptp_priv->shared_addr->phase_offset = 0; + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->phase_offset), 0); + break; + case BCM_KSYNC_FREQCOR: + sprintf(cmd_str, "KSYNC_FREQCORR"); + ptp_priv->shared_addr->freqcorr = *((s32 *)data0); + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->freqcorr), 0); + break; + case BCM_KSYNC_ADJTIME: + sprintf(cmd_str, "KSYNC_ADJTIME"); + ptp_priv->shared_addr->phase_offset = *((s64 *)data0); + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->phase_offset), 0); + break; + case BCM_KSYNC_GETTIME: + sprintf(cmd_str, "KSYNC_GETTIME"); + break; + case BCM_KSYNC_GET_TSTIME: + retry_cnt = (retry_cnt * 2); + sprintf(cmd_str, "KSYNC_GET_TSTIME"); + bksync_hostcmd_data_op(1, data0, data1); + break; + case BCM_KSYNC_SETTIME: + sprintf(cmd_str, "KSYNC_SETTIME"); + ptp_priv->shared_addr->ptptime = *((s64 *)data0); + ptp_priv->shared_addr->phase_offset = 0; + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->ptptime), (u64 *)&(ptp_priv->shared_addr->phase_offset)); + break; + case BCM_KSYNC_DEINIT: + sprintf(cmd_str, "KSYNC_DEINIT"); + break; + default: + sprintf(cmd_str, "KSYNC_XXX"); + break; + } + DEV_WRITE32(ptp_priv, hostcmd_regs[0], ptp_priv->shared_addr->ksyncinit); + + do { + DEV_READ32(ptp_priv, hostcmd_regs[0], &cmd_status); + ptp_priv->shared_addr->ksyncinit = cmd_status; + + if (cmd_status == BCM_KSYNC_DONE) { + ret = 0; + switch (cmd) { + case BCM_KSYNC_GET_TSTIME: + case BCM_KSYNC_GETTIME: + bksync_hostcmd_data_op(0, (u64 *)data0, (u64 *)data1); + break; + default: + break; + } + break; + } + ptp_usleep(100); + retry_cnt--; + } while (retry_cnt); + + mutex_unlock(&ptp_priv->ptp_lock); + + if (retry_cnt == 0) { + DBG_ERR(("Timeout on response from R5 to cmd %s\n", cmd_str)); + } + + + return ret; +} + + +static int bksync_cmd_go(u32 cmd, void *data0, void *data1) +{ + int ret = -1; + + if (ptp_priv == NULL || ptp_priv->shared_addr == NULL) { + return ret; + } + + switch (ptp_priv->dcb_type) { + case 26: + ret = bksync_cmd_cmicm_go(cmd, data0, data1); + break; + case 32: + case 36: + case 38: + ret = bksync_cmd_cmicx_go(cmd, data0, data1); + break; + default: + break; + } + + return ret; +} + + +/** + * bksync_ptp_adjfreq + * + * @ptp: pointer to ptp_clock_info structure + * @ppb: frequency correction value + * + * Description: this function will set the frequency correction + */ +static int bksync_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) +{ + int ret = -1; + u32 cmd_status = BCM_KSYNC_FREQCOR; + + ret = bksync_cmd_go(cmd_status, &ppb, NULL); + DBG_VERB(("applying freq correction: %x\n", ppb)); + + return ret; +} + +/** + * bksync_ptp_adjtime + * + * @ptp: pointer to ptp_clock_info structure + * @delta: desired change in nanoseconds + * + * Description: this function will shift/adjust the hardware clock time. + */ +static int bksync_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + u32 cmd_status = BCM_KSYNC_ADJTIME; + int ret = -1; + + ret = bksync_cmd_go(cmd_status, (void *)&delta, NULL); + DBG_VERB(("ptp adjtime: 0x%llx \n", delta)); + + return ret; +} + +/** + * bksync_ptp_gettime + * + * @ptp: pointer to ptp_clock_info structure + * @ts: pointer to hold time/result + * + * Description: this function will read the current time from the + * hardware clock and store it in @ts. + */ +static int bksync_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) +{ + int ret = -1; + u32 cmd_status = BCM_KSYNC_GETTIME; + s64 reftime = 0; + s64 refctr = 0; + + ret = bksync_cmd_go(cmd_status, (void *)&reftime, (void *)&refctr); + DBG_VERB(("ptp gettime: 0x%llx refctr:0x%llx\n", reftime, refctr)); + mutex_lock(&ptp_priv->ptp_pair_lock); + ptp_priv->shared_addr->ptptime = reftime; + ptp_priv->shared_addr->reftime = refctr; + mutex_unlock(&ptp_priv->ptp_pair_lock); + + *ts = ns_to_timespec64(reftime); + return ret; +} + + +/** + * bksync_ptp_settime + * + * @ptp: pointer to ptp_clock_info structure + * @ts: time value to set + * + * Description: this function will set the current time on the + * hardware clock. + */ +static int bksync_ptp_settime(struct ptp_clock_info *ptp, + const struct timespec64 *ts) +{ + s64 reftime, phaseadj; + int ret = -1; + u32 cmd_status = BCM_KSYNC_SETTIME; + + phaseadj = 0; + reftime = timespec64_to_ns(ts); + + ret = bksync_cmd_go(cmd_status, (void *)&reftime, (void *)&phaseadj); + DBG_VERB(("ptp settime: 0x%llx \n", reftime)); + + return ret; +} + +static int bksync_ptp_enable(struct ptp_clock_info *ptp, + struct ptp_clock_request *rq, int on) +{ + return 0; +} + +/* structure describing a PTP hardware clock */ +static struct ptp_clock_info bksync_ptp_caps = { + .owner = THIS_MODULE, + .name = "bksync_ptp_clock", + .max_adj = 200000, + .n_alarm = 0, + .n_ext_ts = 0, + .n_per_out = 0, /* will be overwritten in bksync_ptp_register */ + .n_pins = 0, + .pps = 0, + .adjfreq = bksync_ptp_adjfreq, + .adjtime = bksync_ptp_adjtime, + .gettime64 = bksync_ptp_gettime, + .settime64 = bksync_ptp_settime, + .enable = bksync_ptp_enable, +}; + +/** + * bksync_ptp_hw_tstamp_enable + * + * @dev_no: device number + * @port: port number + * + * Description: this is a callback function to enable the timestamping on + * a given port + */ +int bksync_ptp_hw_tstamp_enable(int dev_no, int port, int tx_type) +{ + uint64_t portmap = 0; + int map = 0; + int ret = 0; + + if (!module_initialized) { + ret = -1; + goto exit; + } + + if (tx_type == HWTSTAMP_TX_ONESTEP_SYNC) { + bksync_ptp_time_keep_init(); + goto exit; + } + + DBG_VERB(("Enable timestamp on a given port:%d\n", port)); + if (port <= 0) { + DBG_ERR(("Error enabling timestamp on port:%d\n", port)); + ret = -1; + goto exit; + } + + port -= 1; + map = port/64; port = port%64; + + /* Update the shared structure member */ + if (ptp_priv->shared_addr) { + portmap = ptp_priv->shared_addr->portmap[map]; + portmap |= (uint64_t)0x1 << port; + ptp_priv->shared_addr->portmap[map] = portmap; + /* Command to R5 for the update */ + ptp_priv->shared_addr->ksyncinit=BCM_KSYNC_PBM_UPDATE; + } + +exit: + return ret; +} + +/** + * bksync_ptp_hw_tstamp_disable + * + * @dev_no: device number + * @port: port number + * + * Description: this is a callback function to disable the timestamping on + * a given port + */ +int bksync_ptp_hw_tstamp_disable(int dev_no, int port, int tx_type) +{ + uint64_t portmap = 0; + int map = 0; + int ret = 0; + + if (!module_initialized) { + ret = -1; + goto exit; + } + + if (tx_type == HWTSTAMP_TX_ONESTEP_SYNC) { + goto exit; + } + + DBG_VERB(("Disable timestamp on a given port:%d\n", port)); + if (port <= 0) { + DBG_ERR(("Error disabling timestamp on port:%d\n", port)); + ret = -1; + goto exit; + } + + port -= 1; + map = port/64; port = port%64; + + /* Update the shared structure member */ + if (ptp_priv->shared_addr) { + portmap = ptp_priv->shared_addr->portmap[map]; + portmap &= ~((uint64_t)0x1 << port); + ptp_priv->shared_addr->portmap[map]= portmap; + + /* Command to R5 for the update */ + ptp_priv->shared_addr->ksyncinit = BCM_KSYNC_PBM_UPDATE; + } +exit: + return ret; +} + +int bksync_ptp_transport_get(uint8_t *pkt) +{ + int transport = 0; + uint16_t ethertype; + uint16_t tpid; + int tpid_offset, ethype_offset; + + /* Need to check VLAN tag if packet is tagged */ + tpid_offset = 12; + tpid = pkt[tpid_offset] << 8 | pkt[tpid_offset + 1]; + if (tpid == 0x8100) { + ethype_offset = tpid_offset + 4; + } else { + ethype_offset = tpid_offset; + } + + ethertype = pkt[ethype_offset] << 8 | pkt[ethype_offset+1]; + + switch (ethertype) { + case 0x88f7: /* ETHERTYPE_PTPV2 */ + transport = 2; + break; + + case 0x0800: /* ETHERTYPE_IPV4 */ + transport = 4; + break; + + case 0x86DD: /* ETHERTYPE_IPV6 */ + transport = 6; + break; + + default: + transport = 0; + } + + return transport; +} + +static int +bksync_txpkt_tsts_tsamp_get(int port, uint32_t pkt_seq_id, uint32_t *ts_valid, uint32_t *seq_id, uint64_t *timestamp) +{ + int ret = 0; + uint64_t tmp; + + tmp = (port & 0xFFFF) | (pkt_seq_id << 16); + + if (HOSTCMD_USE_REGS) { + ret = bksync_cmd_go(BCM_KSYNC_GET_TSTIME, &tmp, timestamp); + + if (ret >= 0) { + *seq_id = ((tmp >> 16) & 0xFFFF); + *ts_valid = (tmp & 0x1); + } +#if 0 + if (tmp & 0x1) gprintk("in_port: %d in_seq_id: %d out_port: %lld ts_valid: %lld seq_id: %lld ts: %llx\n", port, pkt_seq_id, ((tmp & 0xFFFF) >> 1), (tmp & 0x1), (tmp >> 16), *timestamp); +#endif + } else { + *ts_valid = ptp_priv->shared_addr->port_ts_data[port].ts_valid; + *seq_id = ptp_priv->shared_addr->port_ts_data[port].ts_seq_id; + *timestamp = ptp_priv->shared_addr->port_ts_data[port].timestamp; + } + + + return ret; +} + + +/** + * bksync_ptp_hw_tstamp_tx_time_get + * + * @dev_no: device number + * @port: port number + * @pkt: packet address + * @ts: timestamp to be retrieved + * + * Description: this is a callback function to retrieve the timestamp on + * a given port + */ +int bksync_ptp_hw_tstamp_tx_time_get(int dev_no, int port, uint8_t *pkt, uint64_t *ts) +{ + /* Get Timestamp from R5 or CLMAC */ + uint32_t ts_valid = 0; + uint32_t seq_id = 0; + uint32_t pktseq_id = 0; + uint64_t timestamp = 0; + uint16_t tpid = 0; + int retry_cnt = retry_count; + int seq_id_offset, tpid_offset; + int transport = network_transport; + + if (!ptp_priv || !pkt || !ts || port < 1 || port > 255 || ptp_priv->shared_addr == NULL) { + return -1; + } + + *ts = 0; + + tpid_offset = 12; + + /* Parse for nw transport */ + if (transport == 0) { + transport = bksync_ptp_transport_get(pkt); + } + + switch(transport) + { + case 2: + seq_id_offset = 0x2c; + break; + case 4: + seq_id_offset = 0x48; + break; + case 6: + seq_id_offset = 0x5c; + break; + default: + seq_id_offset = 0x2c; + break; + } + + /* Need to check VLAN tag if packet is tagged */ + tpid = pkt[tpid_offset] << 8 | pkt[tpid_offset + 1]; + if (tpid == 0x8100) { + seq_id_offset += 4; + } + + + pktseq_id = pkt[seq_id_offset] << 8 | pkt[seq_id_offset + 1]; + + port -= 1; + + /* Fetch the TX timestamp from shadow memory */ + do { + bksync_txpkt_tsts_tsamp_get(port, pktseq_id, &ts_valid, &seq_id, ×tamp); + if (ts_valid) { + + /* Clear the shadow memory to get next entry */ + ptp_priv->shared_addr->port_ts_data[port].timestamp = 0; + ptp_priv->shared_addr->port_ts_data[port].port_id = 0; + ptp_priv->shared_addr->port_ts_data[port].ts_seq_id = 0; + ptp_priv->shared_addr->port_ts_data[port].ts_valid = 0; + + if (seq_id == pktseq_id) { + *ts = timestamp; + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].tsts_match += 1; + } else { + ptp_priv->ts_match[port] += 1; + } + + DBG_VERB(("Port: %d Skb_SeqID %d FW_SeqId %d and TS:%llx\n", + port, pktseq_id, seq_id, timestamp)); + + break; + } else { + DBG_ERR(("discard timestamp on port %d Skb_SeqID %d FW_SeqId %d\n", + port, pktseq_id, seq_id)); + + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].tsts_discard += 1; + } else { + ptp_priv->ts_discard[port] += 1; + } + continue; + } + } + ptp_sleep(1); + retry_cnt--; + } while(retry_cnt); + + + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].pkt_txctr += 1; + } else { + ptp_priv->pkt_txctr[port] += 1; + } + + if (retry_cnt == 0) { + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].tsts_timeout += 1; + } else { + ptp_priv->ts_timeout[port] += 1; + } + DBG_ERR(("FW Response timeout: Tx TS on phy port:%d Skb_SeqID: %d\n", port, seq_id)); + } + + + return 0; +} + + +enum { + bxconCustomEncapVersionInvalid = 0, + bxconCustomEncapVersionOne = 1, + + bxconCustomEncapVersionCurrent = bxconCustomEncapVersionOne, + bxconCustomEncapVersionReserved = 255 /* last */ +} bxconCustomEncapVersion; + +enum { + bxconCustomEncapOpcodeInvalid = 0, + bxconCustomEncapOpcodePtpRx = 1, + bxconCustomEncapOpcodeReserved = 255 /* last */ +} bxconCustomEncapOpcode; + +enum { + bxconCustomEncapPtpRxTlvInvalid = 0, + bxconCustomEncapPtpRxTlvPtpRxTime = 1, + bxconCustomEncapPtpRxTlvReserved = 255 /* last */ +} bxconCustomEncapPtpRxTlvType; + +void +bksync_dump_pkt(uint8_t *data, int size) +{ + int idx; + char str[128]; + + for (idx = 0; idx < size; idx++) { + if ((idx & 0xf) == 0) { + sprintf(str, "%04x: ", idx); + } + sprintf(&str[strlen(str)], "%02x ", data[idx]); + if ((idx & 0xf) == 0xf) { + sprintf(&str[strlen(str)], "\n"); + gprintk(str); + } + } + if ((idx & 0xf) != 0) { + sprintf(&str[strlen(str)], "\n"); + gprintk(str); + } +} + + +static inline int +bksync_pkt_custom_encap_ptprx_get(uint8_t *pkt, uint64_t *ing_ptptime) +{ + uint8_t *custom_hdr; + uint8_t id[4]; + uint8_t ver, opc; + uint8_t nh_type, nh_rsvd; + uint16_t len, tot_len; + uint16_t nh_len; + uint32_t seq_id = 0; + uint32_t ptp_rx_time[2]; + uint64_t u64_ptp_rx_time = 0; + + custom_hdr = pkt; + + BKSYNC_UNPACK_U8(custom_hdr, id[0]); + BKSYNC_UNPACK_U8(custom_hdr, id[1]); + BKSYNC_UNPACK_U8(custom_hdr, id[2]); + BKSYNC_UNPACK_U8(custom_hdr, id[3]); + if (!((id[0] == 'B') && (id[1] == 'C') && (id[2] == 'M') && (id[3] == 'C'))) { + /* invalid signature */ + return -1; + } + + BKSYNC_UNPACK_U8(custom_hdr, ver); + switch (ver) { + case bxconCustomEncapVersionCurrent: + break; + default: + gprintk("invalid ver\n"); + return -1; + } + + BKSYNC_UNPACK_U8(custom_hdr, opc); + switch (opc) { + case bxconCustomEncapOpcodePtpRx: + break; + default: + gprintk("invalid opcode\n"); + return -1; + } + + + BKSYNC_UNPACK_U16(custom_hdr, len); + BKSYNC_UNPACK_U32(custom_hdr, seq_id); + tot_len = len; + + /* remaining length of custom encap */ + len = len - (custom_hdr - pkt); + + + /* process tlv */ + while (len > 0) { + BKSYNC_UNPACK_U8(custom_hdr, nh_type); + BKSYNC_UNPACK_U8(custom_hdr, nh_rsvd); + BKSYNC_UNPACK_U16(custom_hdr, nh_len); + len = len - (nh_len); + if (nh_rsvd != 0x0) { + continue; /* invalid tlv */ + } + + switch (nh_type) { + case bxconCustomEncapPtpRxTlvPtpRxTime: + BKSYNC_UNPACK_U32(custom_hdr, ptp_rx_time[0]); + BKSYNC_UNPACK_U32(custom_hdr, ptp_rx_time[1]); + u64_ptp_rx_time = ((uint64_t)ptp_rx_time[1] << 32) | (uint64_t)ptp_rx_time[0]; + *ing_ptptime = u64_ptp_rx_time; + break; + default: + custom_hdr += nh_len; + break; + } + } + +#if 0 +if (!(seq_id % 100)) { + gprintk("****** seq_id = %d ptp time = 0x%llx\n", seq_id, u64_ptp_rx_time); + bksync_dump_pkt(pkt, tot_len); +} +#endif + + DBG_VERB(("Custom encap header: ver=%d opcode=%d seq_id=0x%x\n", ver, opc, seq_id)); + + return (tot_len); +} + + + +/** + * bksync_ptp_hw_tstamp_rx_time_upscale + * + * @dev_no: device number + * @ts: timestamp to be retrieved + * + * Description: this is a callback function to retrieve 64b equivalent of + * rx timestamp + */ +int bksync_ptp_hw_tstamp_rx_time_upscale(int dev_no, int port, struct sk_buff *skb, uint32_t *meta, uint64_t *ts) +{ + int ret = 0; + int custom_encap_len = 0; + + switch (KNET_SKB_CB(skb)->dcb_type) { + case 26: + case 32: + if (pci_cos != (meta[4] & 0x3F)) { + return -1; + } + break; + case 38: + if (pci_cos != ((meta[12] >> 22) & 0x2F)) { + return -1; + } + break; + case 36: + if (pci_cos != ((meta[6] >> 22) & 0x2F)) { + return -1; + } + break; + default: + return -1; + } + + /* parse custom encap header in pkt for ptp rxtime */ + custom_encap_len = bksync_pkt_custom_encap_ptprx_get((skb->data), ts); + + /* Remove the custom encap header from pkt */ + if (custom_encap_len > 0) { + skb_pull(skb, custom_encap_len); + + DBG_VERB(("###### ptp message type: %d\n", skb->data[42])); + } + + if (port > 0){ + port -= 1; + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].pkt_rxctr += 1; + } else { + ptp_priv->pkt_rxctr[port] += 1; + } + } + + return ret; +} + + +void bksync_hton64(u8 *buf, const uint64_t *data) +{ +#ifdef __LITTLE_ENDIAN + /* LITTLE ENDIAN */ + buf[0] = (*(((uint8_t*)(data)) + 7u)); + buf[1] = (*(((uint8_t*)(data)) + 6u)); + buf[2] = (*(((uint8_t*)(data)) + 5u)); + buf[3] = (*(((uint8_t*)(data)) + 4u)); + buf[4] = (*(((uint8_t*)(data)) + 3u)); + buf[5] = (*(((uint8_t*)(data)) + 2u)); + buf[6] = (*(((uint8_t*)(data)) + 1u)); + buf[7] = (*(((uint8_t*)(data)) + 0u)); +#else + memcpy(buf, data, 8); +#endif +} + + + +int bksync_ptp_hw_tstamp_tx_meta_get(int dev_no, + int hwts, int hdrlen, + struct sk_buff *skb, + uint64_t *tstamp, + u32 **md) +{ + uint16_t tpid = 0; + int md_offset = 0; + int pkt_offset = 0; + int ptp_hdr_offset = 0; + int transport = network_transport; + s64 ptptime = 0; + s64 ptpcounter = 0; + int64_t corrField; + int32_t negCurTS32; + int64_t negCurTS64; + + if(!ptp_priv || ptp_priv->shared_addr == NULL) { + return 0; + } + + mutex_lock(&ptp_priv->ptp_pair_lock); + ptptime = ptp_priv->shared_addr->ptptime; + ptpcounter = ptp_priv->shared_addr->reftime; + mutex_unlock(&ptp_priv->ptp_pair_lock); + + negCurTS32 = - (int32_t) ptpcounter; + negCurTS64 = - (int64_t)(ptpcounter); + + if (CMICX_DEV_TYPE) { + pkt_offset = ptp_hdr_offset = hdrlen; + } + + /* Need to check VLAN tag if packet is tagged */ + tpid = SKB_U16_GET(skb, (pkt_offset + 12)); + if (tpid == 0x8100) { + md_offset = 4; + ptp_hdr_offset += 4; + } + + /* One Step Meta Data */ + if (hwts == HWTSTAMP_TX_ONESTEP_SYNC) { + md_offset += 8; + if (KNET_SKB_CB(skb)->dcb_type == 26) { + corrField = (((int64_t)negCurTS32) << 16); + if (negCurTS32 >= 0) { + md_offset += 8; + } + } else { + corrField = (((int64_t)negCurTS64) << 16); + } + } + + + /* Parse for nw transport */ + if (transport == 0) { + transport = bksync_ptp_transport_get(skb->data + pkt_offset); + } + + switch(transport) + { + case 2: /* IEEE 802.3 */ + ptp_hdr_offset += 14; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhrawpkts_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhrawpkts_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhrawpkts_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhrawpkts_dcb38[md_offset]; + } + break; + case 4: /* UDP IPv4 */ + ptp_hdr_offset += 42; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhudpipv4_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhudpipv4_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhudpipv4_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhudpipv4_dcb38[md_offset]; + } + break; + case 6: /* UDP IPv6 */ + ptp_hdr_offset += 62; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhudpipv6_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhudpipv6_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhudpipv6_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhudpipv6_dcb38[md_offset]; + } + break; + default: + ptp_hdr_offset += 42; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhudpipv4_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhudpipv4_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhudpipv4_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhudpipv4_dcb38[md_offset]; + } + break; + } + + + if ((hwts == HWTSTAMP_TX_ONESTEP_SYNC) && + BKSYNC_PTP_EVENT_MSG(skb->data[ptp_hdr_offset])) { + /* One Step Timestamp Field updation */ + int corr_offset = ptp_hdr_offset + 8; + int origin_ts_offset = ptp_hdr_offset + 34; + u32 tmp; + struct timespec64 ts; + int udp_csum_regen; + u32 udp_csum20; + u16 udp_csum; + + udp_csum = SKB_U16_GET(skb, (ptp_hdr_offset - 2)); + + switch (transport) { + case 2: + udp_csum_regen = 0; + break; + case 6: + udp_csum_regen = 1; + break; + default: + udp_csum_regen = (udp_csum != 0x0); + break; + } + + /* Fill the correction field */ + bksync_hton64(&(skb->data[corr_offset]), (const u64 *)&corrField); + + /* Fill the Origin Timestamp Field */ + ts = ns_to_timespec64(ptptime); + + tmp = (ts.tv_sec >> 32); + skb->data[origin_ts_offset + 0] = ((tmp >> 8) & 0xFF); + skb->data[origin_ts_offset + 1] = ((tmp ) & 0xFF); + + tmp = (ts.tv_sec & 0xFFFFFFFFLL); + skb->data[origin_ts_offset + 2] = ((tmp >> 24) & 0xFF); + skb->data[origin_ts_offset + 3] = ((tmp >> 16) & 0xFF); + skb->data[origin_ts_offset + 4] = ((tmp >> 8) & 0xFF); + skb->data[origin_ts_offset + 5] = ((tmp ) & 0xFF); + + tmp = (ts.tv_nsec & 0xFFFFFFFFLL); + skb->data[origin_ts_offset + 6] = ((tmp >> 24) & 0xFF); + skb->data[origin_ts_offset + 7] = ((tmp >> 16) & 0xFF); + skb->data[origin_ts_offset + 8] = ((tmp >> 8) & 0xFF); + skb->data[origin_ts_offset + 9] = ((tmp ) & 0xFF); + + if (udp_csum_regen) { + udp_csum20 = (~udp_csum) & 0xFFFF; + + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 0)); + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 2)); + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 4)); + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 6)); + + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 0)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 2)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 4)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 6)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 8)); + + /* Fold 20bit checksum into 16bit udp checksum */ + udp_csum20 = ((udp_csum20 & 0xFFFF) + (udp_csum20 >> 16)); + udp_csum = ((udp_csum20 & 0xFFFF) + (udp_csum20 >> 16)); + + /* invert again to get final checksum. */ + udp_csum = ~udp_csum; + if (udp_csum == 0) { + udp_csum = 0xFFFF; + } + + skb->data[ptp_hdr_offset - 2] = ((udp_csum >> 8) & 0xFF); + skb->data[ptp_hdr_offset - 1] = ((udp_csum ) & 0xFF); + } + + if (skb->data[ptp_hdr_offset] == DELAY_REQ) { + *tstamp = ptptime; + + DBG_VERB(("ptp delay req packet tstamp : 0x%llx corrField: 0x%llx\n", ptptime, corrField)); + } + + } + + return 0; +} + + +int bksync_ptp_hw_tstamp_ptp_clock_index_get(int dev_no) +{ + int phc_index = -1; + if (ptp_priv && ptp_priv->ptp_clock) + phc_index = ptp_clock_index(ptp_priv->ptp_clock); + return phc_index; +} + + +/** +* bcm_ptp_time_keep - call timecounter_read every second to avoid timer overrun +* because a 32bit counter, will timeout in 4s +*/ +static void bksync_ptp_time_keep(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct bksync_ptp_priv *priv = + container_of(dwork, struct bksync_ptp_priv, time_keep); + struct timespec64 ts; + + /* Call bcm_ptp_gettime function to keep the ref_time_64 and ref_counter_48 in sync */ + bksync_ptp_gettime(&(priv->ptp_caps), &ts); + schedule_delayed_work(&priv->time_keep, HZ); +} + +static void bksync_ptp_time_keep_init(void) +{ + if (!ptp_priv->timekeep_status) { + INIT_DELAYED_WORK(&(ptp_priv->time_keep), bksync_ptp_time_keep); + schedule_delayed_work(&ptp_priv->time_keep, HZ); + + ptp_priv->timekeep_status = 1; + } + + return; +} + +static void bksync_ptp_time_keep_deinit(void) +{ + if (ptp_priv->timekeep_status) { + /* Cancel delayed work */ + cancel_delayed_work_sync(&(ptp_priv->time_keep)); + + ptp_priv->timekeep_status = 0; + } + + return; +} + + + +static int bksync_ptp_init(struct ptp_clock_info *ptp) +{ + return bksync_cmd_go(BCM_KSYNC_INIT, NULL, NULL); +} + +static int bksync_ptp_deinit(struct ptp_clock_info *ptp) +{ + bksync_ptp_time_keep_deinit(); + + return bksync_cmd_go(BCM_KSYNC_DEINIT, NULL, NULL); +} + +/* + * Device Debug Statistics Proc Entry + */ +/** +* This function is called at the beginning of a sequence. +* ie, when: +* - the /proc/bcm/ksync/stats file is read (first time) +* - after the function stop (end of sequence) +* +*/ +static void *bksync_proc_seq_start(struct seq_file *s, loff_t *pos) +{ + /* beginning a new sequence ? */ + if ( (int)*pos == 0 && ptp_priv->shared_addr != NULL) + { + seq_printf(s, "Port Bitmap : %08llx%08llx\n", + (uint64_t)(ptp_priv->shared_addr->portmap[1]), + (uint64_t)(ptp_priv->shared_addr->portmap[0])); + seq_printf(s,"%4s| %9s| %9s| %9s| %9s| %9s| %9s|\n", + "Port", "RxCounter", "TxCounter", "TSTimeout", "TSRead", "TSMatch", "TSDiscard"); + } + + if (ptp_priv->shared_addr != NULL && (int)*pos < (ptp_priv->num_pports)) + return (void *)(unsigned long)(*pos + 1); + /* End of the sequence, return NULL */ + return NULL; +} + +/** +* This function is called after the beginning of a sequence. +* It's called untill the return is NULL (this ends the sequence). +* +*/ +static void *bksync_proc_seq_next(struct seq_file *s, void *v, loff_t *pos) +{ + (*pos)++; + return bksync_proc_seq_start(s, pos); +} +/** +* This function is called at the end of a sequence +* +*/ +static void bksync_proc_seq_stop(struct seq_file *s, void *v) +{ + /* nothing to do, we use a static value in bksync_proc_seq_start() */ +} + +/** +* This function is called for each "step" of a sequence +* +*/ +static int bksync_proc_seq_show(struct seq_file *s, void *v) +{ + unsigned long port = (unsigned long)v; + port = port - 1; + if (HOSTCMD_USE_REGS) { + if (ptp_priv->port_stats[port].pkt_rxctr || ptp_priv->port_stats[port].pkt_txctr || + ptp_priv->port_stats[port].tsts_discard || ptp_priv->port_stats[port].tsts_timeout || + ptp_priv->shared_addr->port_ts_data[port].ts_cnt || ptp_priv->port_stats[port].tsts_match) { + seq_printf(s, "%4lu | %9d| %9d| %9d| %9d| %9d| %9d| %s\n", (port + 1), + ptp_priv->port_stats[port].pkt_rxctr, + ptp_priv->port_stats[port].pkt_txctr, + ptp_priv->port_stats[port].tsts_timeout, + ptp_priv->shared_addr->port_ts_data[port].ts_cnt, + ptp_priv->port_stats[port].tsts_match, + ptp_priv->port_stats[port].tsts_discard, + ptp_priv->port_stats[port].pkt_txctr != ptp_priv->port_stats[port].tsts_match ? "***":""); + } + } else { + if (ptp_priv->pkt_rxctr[port] || ptp_priv->pkt_txctr[port] || + ptp_priv->ts_discard[port] || ptp_priv->ts_timeout[port] || + ptp_priv->shared_addr->port_ts_data[port].ts_cnt || ptp_priv->ts_match[port]) { + seq_printf(s, "%4lu | %9d| %9d| %9d| %9d| %9d| %9d| %s\n", (port + 1), + ptp_priv->pkt_rxctr[port], + ptp_priv->pkt_txctr[port], + ptp_priv->ts_timeout[port], + ptp_priv->shared_addr->port_ts_data[port].ts_cnt, + ptp_priv->ts_match[port], + ptp_priv->ts_discard[port], + ptp_priv->pkt_txctr[port] != ptp_priv->ts_match[port] ? "***":""); + } + } + return 0; +} + +/** +* seq_operations for bsync_proc_*** entries +* +*/ +static struct seq_operations bksync_proc_seq_ops = { + .start = bksync_proc_seq_start, + .next = bksync_proc_seq_next, + .stop = bksync_proc_seq_stop, + .show = bksync_proc_seq_show +}; +static int bksync_proc_txts_open(struct inode * inode, struct file * file) +{ + return seq_open(file, &bksync_proc_seq_ops); +} + +static ssize_t +bksync_proc_txts_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + char debug_str[40]; + char *ptr; + int port; + + if (copy_from_user(debug_str, buf, count)) { + return -EFAULT; + } + + if ((ptr = strstr(debug_str, "clear")) != NULL) { + for (port = 0; port < ptp_priv->num_pports; port++) { + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].pkt_rxctr = 0; + ptp_priv->port_stats[port].pkt_txctr = 0; + ptp_priv->port_stats[port].tsts_discard = 0; + ptp_priv->port_stats[port].tsts_timeout = 0; + ptp_priv->port_stats[port].tsts_match = 0; + } else { + ptp_priv->pkt_rxctr[port] = 0; + ptp_priv->pkt_txctr[port] = 0; + ptp_priv->ts_discard[port] = 0; + ptp_priv->ts_timeout[port] = 0; + ptp_priv->ts_match[port] = 0; + } + if (ptp_priv->shared_addr) + ptp_priv->shared_addr->port_ts_data[port].ts_cnt = 0; + } + } else { + gprintk("Warning: unknown input\n"); + } + + return count; +} + +struct file_operations bksync_proc_txts_file_ops = { + owner: THIS_MODULE, + open: bksync_proc_txts_open, + read: seq_read, + llseek: seq_lseek, + write: bksync_proc_txts_write, + release: seq_release, +}; + +static int +bksync_proc_init(void) +{ + struct proc_dir_entry *entry; + + PROC_CREATE(entry, "stats", 0666, bksync_proc_root, &bksync_proc_txts_file_ops); + if (entry == NULL) { + return -1; + } + return 0; +} + +static int +bksync_proc_cleanup(void) +{ + remove_proc_entry("stats", bksync_proc_root); + return 0; +} + +static void bksync_ptp_cmicm_dma_init(int dcb_type) +{ + int endianess; + int num_pports = 128; + dma_addr_t dma_mem = 0; + + /* Initialize the Base address for CMIC and shared Memory access */ + ptp_priv->base_addr = lkbde_get_dev_virt(0); + ptp_priv->dma_dev = lkbde_get_dma_dev(0); + + ptp_priv->dma_mem_size = 16384;/*sizeof(bksync_uc_linux_ipc_t);*/ + + if (ptp_priv->shared_addr == NULL) { + DBG_ERR(("Allocate shared memory with R5\n")); + ptp_priv->shared_addr = DMA_ALLOC_COHERENT(ptp_priv->dma_dev, + ptp_priv->dma_mem_size, + &dma_mem); + ptp_priv->dma_mem = (uint64_t)dma_mem; + ptp_priv->num_pports = num_pports; + ptp_priv->port_stats = kzalloc((sizeof(bksync_port_stats_t) * num_pports), GFP_KERNEL); + } + + if (ptp_priv->shared_addr != NULL) { + /* Reset memory */ + memset((void *)ptp_priv->shared_addr, 0, ptp_priv->dma_mem_size); + + DBG_ERR(("Shared memory allocation (%d bytes) successful at 0x%016lx.\n", + ptp_priv->dma_mem_size, (long unsigned int)ptp_priv->dma_mem)); +#ifdef __LITTLE_ENDIAN + endianess = 0; +#else + endianess = 1; +#endif + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_12r(CMIC_CMC_BASE), ((pci_cos << 16) | endianess)); + + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_10r(CMIC_CMC_BASE), + (ptp_priv->dma_mem & 0xffffffff)); + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_11r(CMIC_CMC_BASE), + (ptp_priv->dma_mem >> 32) & 0xffffffff); + + ptp_priv->dcb_type = dcb_type; + } + + if (debug & DBG_LVL_VERB) { + printk(KERN_EMERG"%s %p:%p\n",__FUNCTION__, + ptp_priv->base_addr,(void *)ptp_priv->shared_addr); + } + + return; +} + +static void bksync_ptp_cmicx_dma_init(int dcb_type) +{ + int endianess; + int num_pports = 256; + + /* Initialize the Base address for CMIC and shared Memory access */ + ptp_priv->base_addr = lkbde_get_dev_virt(0); + ptp_priv->dma_dev = lkbde_get_dma_dev(0); + + ptp_priv->dcb_type = dcb_type; + ptp_priv->dma_mem_size = 16384;/*sizeof(bksync_uc_linux_ipc_t);*/ + + if (ptp_priv->shared_addr == NULL) { + ptp_priv->shared_addr = kzalloc(16384, GFP_KERNEL); + ptp_priv->num_pports = num_pports; + ptp_priv->port_stats = kzalloc((sizeof(bksync_port_stats_t) * num_pports), GFP_KERNEL); + } + + if (ptp_priv->shared_addr != NULL) { + /* Reset memory. */ + memset((void *)ptp_priv->shared_addr, 0, ptp_priv->dma_mem_size); + +#ifdef __LITTLE_ENDIAN + endianess = 0; +#else + endianess = 1; +#endif + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_12r(CMIC_CMC_BASE), ((pci_cos << 16) | endianess)); + + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_10r(CMIC_CMC_BASE), 1); + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_11r(CMIC_CMC_BASE), 1); + + } + + if (debug & DBG_LVL_VERB) { + printk(KERN_EMERG"%s %p:%p\n",__FUNCTION__, + ptp_priv->base_addr,(void *)ptp_priv->shared_addr); + } + + + hostcmd_regs[0] = CMIC_CMC_SCHAN_MESSAGE_21r(CMIC_CMC_BASE); + hostcmd_regs[1] = CMIC_CMC_SCHAN_MESSAGE_20r(CMIC_CMC_BASE); + hostcmd_regs[2] = CMIC_CMC_SCHAN_MESSAGE_19r(CMIC_CMC_BASE); + hostcmd_regs[3] = CMIC_CMC_SCHAN_MESSAGE_18r(CMIC_CMC_BASE); + hostcmd_regs[4] = CMIC_CMC_SCHAN_MESSAGE_17r(CMIC_CMC_BASE); + + return; +} + + +static void bksync_ptp_dma_init(int dcb_type) +{ + switch (dcb_type) { + case 26: + bksync_ptp_cmicm_dma_init(dcb_type); + ptp_priv->dcb_type = dcb_type; + break; + case 32: + case 36: + case 38: + bksync_ptp_cmicx_dma_init(dcb_type); + ptp_priv->dcb_type = dcb_type; + break; + default: + break; + } + + return; +} + + + +/** + * bksync_ioctl_cmd_handler + * @kmsg: kcom message - ptp clock ioctl command. + * Description: This function will handle ioctl commands + * from user mode. + */ +static int +bksync_ioctl_cmd_handler(kcom_msg_clock_cmd_t *kmsg, int len, int dcb_type) +{ + kmsg->hdr.type = KCOM_MSG_TYPE_RSP; + + if (!module_initialized && kmsg->clock_info.cmd != KSYNC_M_HW_INIT) { + kmsg->hdr.status = KCOM_E_NOT_FOUND; + return sizeof(kcom_msg_hdr_t); + } + + switch(kmsg->clock_info.cmd) { + case KSYNC_M_HW_INIT: + pci_cos = kmsg->clock_info.data[0]; + if (kmsg->clock_info.data[1] == 0 || kmsg->clock_info.data[1] == 1) { + fw_core = kmsg->clock_info.data[1]; + bksync_ptp_dma_init(dcb_type); + if (bksync_ptp_init(&(ptp_priv->ptp_caps)) >= 0) { + module_initialized = 1; + } + } + break; + case KSYNC_M_HW_DEINIT: + bksync_ptp_deinit(&(ptp_priv->ptp_caps)); + module_initialized = 0; + break; + case KSYNC_M_HW_TS_DISABLE: + bksync_ptp_hw_tstamp_disable(0, kmsg->clock_info.data[0], 0); + break; + case KSYNC_M_VERSION: + break; + default: + kmsg->hdr.status = KCOM_E_NOT_FOUND; + return sizeof(kcom_msg_hdr_t); + } + + return sizeof(*kmsg); +} + + + +/** + * bksync_ptp_register + * @priv: driver private structure + * Description: this function will register the ptp clock driver + * to kernel. It also does some house keeping work. + */ +static int bksync_ptp_register(void) +{ + int err = -ENODEV; + + /* Support on core-0 or core-1 */ + if (fw_core < 0 || fw_core > 1) { + goto exit; + } + + /* default transport is raw, ieee 802.3 */ + switch (network_transport) { + case 2: /* IEEE 802.3 */ + case 4: /* UDP IPv4 */ + case 6: /* UDP IPv6 */ + break; + default: + network_transport = 0; + } + + ptp_priv = kzalloc(sizeof(*ptp_priv), GFP_KERNEL); + if (!ptp_priv) { + err = -ENOMEM; + goto exit; + } + + /* Reset memory */ + memset(ptp_priv, 0, sizeof(*ptp_priv)); + + err = -ENODEV; + + ptp_priv->ptp_caps = bksync_ptp_caps; + + mutex_init(&(ptp_priv->ptp_lock)); + mutex_init(&(ptp_priv->ptp_pair_lock)); + + /* Register ptp clock driver with bksync_ptp_caps */ + ptp_priv->ptp_clock = ptp_clock_register(&ptp_priv->ptp_caps, NULL); + + if (IS_ERR(ptp_priv->ptp_clock)) { + ptp_priv->ptp_clock = NULL; + } else if (ptp_priv->ptp_clock) { + err = 0; + + /* Register BCM-KNET HW Timestamp Callback Functions */ + bkn_hw_tstamp_enable_cb_register(bksync_ptp_hw_tstamp_enable); + bkn_hw_tstamp_disable_cb_register(bksync_ptp_hw_tstamp_disable); + bkn_hw_tstamp_tx_time_get_cb_register(bksync_ptp_hw_tstamp_tx_time_get); + bkn_hw_tstamp_tx_meta_get_cb_register(bksync_ptp_hw_tstamp_tx_meta_get); + bkn_hw_tstamp_rx_time_upscale_cb_register(bksync_ptp_hw_tstamp_rx_time_upscale); + bkn_hw_tstamp_ptp_clock_index_cb_register(bksync_ptp_hw_tstamp_ptp_clock_index_get); + bkn_hw_tstamp_ioctl_cmd_cb_register(bksync_ioctl_cmd_handler); + + } + + /* Initialize proc files */ + bksync_proc_root = proc_mkdir("bcm/ksync", NULL); + bksync_proc_init(); + ptp_priv->shared_addr = NULL; + ptp_priv->port_stats = NULL; +exit: + return err; +} + +static int bksync_ptp_remove(void) +{ + if (!ptp_priv) + return 0; + + bksync_ptp_time_keep_deinit(); + + bksync_proc_cleanup(); + remove_proc_entry("bcm/ksync", NULL); + + /* UnRegister BCM-KNET HW Timestamp Callback Functions */ + bkn_hw_tstamp_enable_cb_unregister(bksync_ptp_hw_tstamp_enable); + bkn_hw_tstamp_disable_cb_unregister(bksync_ptp_hw_tstamp_disable); + bkn_hw_tstamp_tx_time_get_cb_unregister(bksync_ptp_hw_tstamp_tx_time_get); + bkn_hw_tstamp_tx_meta_get_cb_unregister(bksync_ptp_hw_tstamp_tx_meta_get); + bkn_hw_tstamp_rx_time_upscale_cb_unregister(bksync_ptp_hw_tstamp_rx_time_upscale); + bkn_hw_tstamp_ptp_clock_index_cb_unregister(bksync_ptp_hw_tstamp_ptp_clock_index_get); + bkn_hw_tstamp_ioctl_cmd_cb_unregister(bksync_ioctl_cmd_handler); + + if (module_initialized) { + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_10r(CMIC_CMC_BASE), 0); + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_11r(CMIC_CMC_BASE), 0); + } + /* Deinitialize the PTP */ + bksync_ptp_deinit(&(ptp_priv->ptp_caps)); + module_initialized = 0; + + if (ptp_priv->port_stats != NULL) { + kfree((void *)ptp_priv->port_stats); + ptp_priv->port_stats = NULL; + } + if (ptp_priv->shared_addr != NULL) { + if (HOSTCMD_USE_REGS) { + kfree((void *)ptp_priv->shared_addr); + } else { + DMA_FREE_COHERENT(ptp_priv->dma_dev, ptp_priv->dma_mem_size, + (void *)ptp_priv->shared_addr, (dma_addr_t)ptp_priv->dma_mem); + } + ptp_priv->shared_addr = NULL; + DBG_ERR(("Free R5 memory\n")); + } + + /* Unregister the bcm ptp clock driver */ + ptp_clock_unregister(ptp_priv->ptp_clock); + + /* Free Memory */ + kfree(ptp_priv); + + return 0; +} +#endif + + +/* + * Generic module functions + */ + +/* + * Function: _pprint + * + * Purpose: + * Print proc filesystem information. + * Parameters: + * None + * Returns: + * Always 0 + */ + static int +_pprint(void) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) + /* put some goodies here */ + pprintf("Broadcom BCM PTP Hardware Clock Module\n"); +#else + pprintf("Broadcom BCM PTP Hardware Clock Module not supported\n"); +#endif + return 0; +} + +/* + * Function: _init + * + * Purpose: + * Module initialization. + * Attached SOC all devices and optionally initializes these. + * Parameters: + * None + * Returns: + * 0 on success, otherwise -1 + */ + static int +_init(void) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) + bksync_ptp_register(); + return 0; +#else + return -1; +#endif +} + +/* + * Function: _cleanup + * + * Purpose: + * Module cleanup function + * Parameters: + * None + * Returns: + * Always 0 + */ + static int +_cleanup(void) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) + mutex_destroy(&(ptp_priv->ptp_lock)); + mutex_destroy(&(ptp_priv->ptp_pair_lock)); + bksync_ptp_remove(); + return 0; +#else + return -1; +#endif +} + +static gmodule_t _gmodule = { +name: MODULE_NAME, + major: MODULE_MAJOR, + init: _init, + cleanup: _cleanup, + pprint: _pprint, + ioctl: NULL, + open: NULL, + close: NULL, +}; + + gmodule_t* +gmodule_get(void) +{ + EXPORT_NO_SYMBOLS; + return &_gmodule; +} diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h index 477c037a0c43..df8874fb1f70 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h @@ -47,6 +47,8 @@ typedef struct { uint32 filter_user_data; uint16 dcb_type; int port; + uint64_t ts; + uint32 hwts; } knet_skb_cb_t; #define KNET_SKB_CB(_skb) ((knet_skb_cb_t *)_skb->cb) @@ -59,19 +61,22 @@ typedef int int chan, kcom_filter_t *filter); typedef int -(*knet_hw_tstamp_enable_cb_f)(int dev_no, int port); +(*knet_hw_tstamp_enable_cb_f)(int dev_no, int phys_port, int tx_type); typedef int -(*knet_hw_tstamp_tx_time_get_cb_f)(int dev_no, int port, uint8_t *pkt, uint64_t *ts); +(*knet_hw_tstamp_tx_time_get_cb_f)(int dev_no, int phys_port, uint8_t *pkt, uint64_t *ts); typedef int -(*knet_hw_tstamp_tx_meta_get_cb_f)(int dev_no, struct sk_buff *skb, uint32_t **md); +(*knet_hw_tstamp_tx_meta_get_cb_f)(int dev_no, int hwts, int hdrlen, struct sk_buff *skb, uint64_t *ts, uint32_t **md); typedef int (*knet_hw_tstamp_ptp_clock_index_cb_f)(int dev_no); typedef int -(*knet_hw_tstamp_rx_time_upscale_cb_f)(int dev_no, uint64_t *ts); +(*knet_hw_tstamp_rx_time_upscale_cb_f)(int dev_no, int phys_port, struct sk_buff *skb, uint32_t *meta, uint64_t *ts); + +typedef int +(*knet_hw_tstamp_ioctl_cmd_cb_f)(kcom_msg_clock_cmd_t *kmsg, int len, int dcb_type); extern int bkn_rx_skb_cb_register(knet_skb_cb_f rx_cb); @@ -127,6 +132,12 @@ bkn_hw_tstamp_rx_time_upscale_cb_register(knet_hw_tstamp_rx_time_upscale_cb_f hw extern int bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb); +extern int +bkn_hw_tstamp_ioctl_cmd_cb_register(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb); + +extern int +bkn_hw_tstamp_ioctl_cmd_cb_unregister(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb); + typedef struct { uint8 cmic_type; uint8 dcb_type; @@ -153,6 +164,6 @@ bkn_netif_destroy_cb_register(knet_netif_cb_f netif_cb); extern int bkn_netif_destroy_cb_unregister(knet_netif_cb_f netif_cb); -#endif /* __KERNEL__ */ +#endif #endif /* __LINUX_BCM_KNET_H__ */ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h index a48cb540adaf..56d641c9c87c 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h @@ -38,6 +38,11 @@ #include #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +#if defined(INCLUDE_KNET) && LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) +#ifdef CONFIG_NF_CONNTRACK_MODULE +#include +#endif +#endif #include #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile index 2a167bb9e811..3de3e07080c4 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile @@ -36,6 +36,7 @@ KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko build: $(MODULE) $(KMODULE) endif +KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers ifeq ($(BUILD_PSAMPLE),1) KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../psample/kernel_module/Module.symvers endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c index 89d1087212c7..1626d33c1c5d 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c @@ -1,15 +1,15 @@ /* * Copyright 2017-2019 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ @@ -59,6 +59,26 @@ LKM_MOD_PARAM(debug, "i", int, 0); MODULE_PARM_DESC(debug, "Debug level (default 0)"); +static int tpid=0x8100; +LKM_MOD_PARAM(tpid, "i", int, 0); +MODULE_PARM_DESC(debug, +"Tag Protocol Identifier (TPID) indicates the frame type (default 0x8100)"); + +static int pri=0; +LKM_MOD_PARAM(pri, "i", int, 0); +MODULE_PARM_DESC(pri, +"Priority (PRI) indicates the frame priority (default 0)"); + +static int cfi=0; +LKM_MOD_PARAM(cfi, "i", int, 0); +MODULE_PARM_DESC(cfi, +"Canonical Format Indicator (CFI) indicates whether a MAC address is encapsulated in canonical format over different transmission media (default 0)"); + +static int vid=0; +LKM_MOD_PARAM(vid, "i", int, 0); +MODULE_PARM_DESC(vid, +"VLAN ID (VID) indicates the VLAN to which a frame belongs (default 0)"); + /* Module Information */ #define MODULE_MAJOR 121 #define MODULE_NAME "linux-knet-cb" @@ -67,8 +87,8 @@ MODULE_PARM_DESC(debug, #define KNET_CB_DEBUG /* These below need to match incoming enum values */ -#define FILTER_TAG_STRIP 0 -#define FILTER_TAG_KEEP 1 +#define FILTER_TAG_STRIP 0 +#define FILTER_TAG_KEEP 1 #define FILTER_TAG_ORIGINAL 2 /* Maintain tag strip statistics */ @@ -105,6 +125,31 @@ strip_vlan_tag(struct sk_buff *skb) } } +/* Add VLAN tag to untagged packet */ +static void +add_vlan_tag(struct sk_buff *skb, u32 forward_domain) +{ + u32 vlan = 0; + uint16_t vlan_proto = (uint16_t) ((skb->data[12] << 8) | skb->data[13]); + + if ((vlan_proto != 0x8100) && (vlan_proto != 0x88a8) && (vlan_proto != 0x9100)) { + /* If vid is specified, use configued vid as VLAN ID, or, use forward_domain as vid */ + vlan = vid ? vid: forward_domain; + + skb_push(skb, 4); /* Add 4 bytes from start of buffer */ + /* Move first 12 bytes of packet forward by 4 */ + ((u32 *) skb->data)[0] = ((u32 *) skb->data)[1]; + ((u32 *) skb->data)[1] = ((u32 *) skb->data)[2]; + ((u32 *) skb->data)[2] = ((u32 *) skb->data)[3]; + + /* Set VLAN tag */ + skb->data[12] = (tpid >> 8) & 0xff; + skb->data[13] = tpid & 0xff; + skb->data[14] = (((pri & 0x7) << 5) | ((cfi & 0x1) << 4) | ((vlan >> 8) & 0xf)) & 0xff; + skb->data[15] = vlan & 0xff; + } +} + /* * Location of tagging status in select DCB types found below: * @@ -119,6 +164,7 @@ strip_vlan_tag(struct sk_buff *skb) * 1 = Single inner-tag * 2 = Single outer-tag * 3 = Double tagged. + * 4 = Dedicated for Dune device, packets are received with original tag status. * -1 = Unsupported DCB type */ static int @@ -159,6 +205,11 @@ get_tag_status(int dcb_type, void *meta) tag_status = tag_map[(dcb[9] >> 13) & 0x3]; } break; + case 28: + case 39: + tag_status = 4; + break; + break; default: tag_status = -1; break; @@ -188,12 +239,20 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) if (debug & 0x1) { gprintk("%s Enter; netif Flags: %08X filter_flags %08X \n", __func__, netif_flags, filter_flags); - } + } #endif + /* Get DCB type for this packet, passed by KNET driver */ + dcb_type = KNET_SKB_CB(skb)->dcb_type; /* KNET implements this already */ if (filter_flags == FILTER_TAG_KEEP) -{ + { + if (dcb_type ==28 || dcb_type == 39) + { + uint32 *meta_buffer = (uint32 *)meta; + uint32 forward_domain = meta_buffer[1] & 0xffff; + add_vlan_tag(skb, forward_domain); + } strip_stats.skipped++; return skb; } @@ -205,18 +264,16 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) { strip_tag = 1; } - /* Get DCB type for this packet, passed by KNET driver */ - dcb_type = KNET_SKB_CB(skb)->dcb_type; + + /* Get tag status from DCB */ tag_status = get_tag_status(dcb_type, meta); - #ifdef KNET_CB_DEBUG if (debug & 0x1) { gprintk("%s; DCB Type: %d; tag status: %d\n", __func__, dcb_type, tag_status); } #endif - if (tag_status < 0) { /* Unsupported DCB type */ return skb; @@ -231,12 +288,13 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) strip_tag = 1; } } + strip_stats.checked++; if (strip_tag) { #ifdef KNET_CB_DEBUG if (debug & 0x1) { - gprintk("%s; Stripping VLAN\n", __func__); + gprintk("%s; Stripping VLAN tag\n", __func__); } #endif strip_stats.stripped++; @@ -245,10 +303,11 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) #ifdef KNET_CB_DEBUG else { if (debug & 0x1) { - gprintk("%s; Preserve VLAN\n", __func__); + gprintk("%s; Keeping VLAN tag\n", __func__); } } #endif + return skb; } @@ -263,7 +322,7 @@ strip_tag_tx_cb(struct sk_buff *skb, int dev_no, void *meta) /* Filter callback not used */ static int strip_tag_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, - int chan, kcom_filter_t *kf) + int chan, kcom_filter_t *kf) { /* Pass through for now */ return 0; @@ -287,7 +346,7 @@ knet_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) { int retv = 0; #ifdef PSAMPLE_SUPPORT - retv = psample_netif_create_cb(unit, netif, dev); + retv = psample_netif_create_cb(unit, netif, dev); #endif return retv; } @@ -297,7 +356,7 @@ knet_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) { int retv = 0; #ifdef PSAMPLE_SUPPORT - retv = psample_netif_destroy_cb(unit, netif, dev); + retv = psample_netif_destroy_cb(unit, netif, dev); #endif return retv; } @@ -306,10 +365,9 @@ knet_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) * Get statistics. * % cat /proc/linux-knet-cb */ - static int _pprint(void) -{ +{ pprintf("Broadcom Linux KNET Call-Back: Untagged VLAN Stripper\n"); pprintf(" %lu stripped packets\n", strip_stats.stripped); pprintf(" %lu packets checked\n", strip_stats.checked); @@ -322,7 +380,9 @@ static int _cleanup(void) { bkn_rx_skb_cb_unregister(strip_tag_rx_cb); - /* strip_tag_tx_cb is currently a no-op, so no need to unregister */ + /* strip_tag_tx_cb is currently a noop, so + * no need to unregister. + */ if (0) { bkn_tx_skb_cb_unregister(strip_tag_tx_cb); @@ -336,14 +396,15 @@ _cleanup(void) psample_cleanup(); #endif return 0; -} +} static int _init(void) { - bkn_rx_skb_cb_register(strip_tag_rx_cb); - /* strip_tag_tx_cb is currently a no-op, so no need to register */ + /* strip_tag_tx_cb is currently a noop, so + * no need to register. + */ if (0) { bkn_tx_skb_cb_register(strip_tag_tx_cb); @@ -352,23 +413,24 @@ _init(void) #ifdef PSAMPLE_SUPPORT psample_init(); #endif - + bkn_filter_cb_register(knet_filter_cb); bkn_netif_create_cb_register(knet_netif_create_cb); bkn_netif_destroy_cb_register(knet_netif_destroy_cb); + return 0; } static gmodule_t _gmodule = { - name: MODULE_NAME, - major: MODULE_MAJOR, + name: MODULE_NAME, + major: MODULE_MAJOR, init: _init, - cleanup: _cleanup, - pprint: _pprint, + cleanup: _cleanup, + pprint: _pprint, ioctl: NULL, - open: NULL, - close: NULL, -}; + open: NULL, + close: NULL, +}; gmodule_t* gmodule_get(void) diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c index ef6fc102ce78..e1a6086a52ae 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c @@ -64,10 +64,24 @@ extern int debug; #define SOC_HIGIG_SRCPORT(x) ((x[1] >> 16) & 0x1f) #define SOC_HIGIG2_SOP (0xfb) //0xfc - TODO: how can we differentiate between Higig and higig2? #define SOC_HIGIG2_START(x) ((x[0] >> 24) & 0xff) +#define SOC_HIGIG2_IS_MC(x) ((x[0] >> 20) & 0x1) #define SOC_HIGIG2_DSTPORT(x) ((x[0] >> 0) & 0xff) #define SOC_HIGIG2_SRCPORT(x) ((x[1] >> 16) & 0xff) #define SOC_DCB32_HG_OFFSET (6) +/* sFlow v5 datagram dst ifindex field type + * dst ifindex encoding bits [31:30] + */ +#define DSTPORT_TYPE_DISCARD 1 +#define DSTPORT_TYPE_MC 2 + +#define DSTPORT_TYPE_OFFSET 30 +#define DSTPORT_TYPE_MASK 0x3 +#define DSTPORT_TYPE_CLR(_dst) (_dst &= ~(DSTPORT_TYPE_MASK << DSTPORT_TYPE_OFFSET)) +#define DSTPORT_TYPE_SET(_dst,_type) (_dst |= ((_type & DSTPORT_TYPE_MASK) << DSTPORT_TYPE_OFFSET)) +#define DSTPORT_TYPE_GET(_dst) ((_dst >> DSTPORT_TYPE_OFFSET) & DSTPORT_TYPE_MASK) +#define DSTPORT_GET(_dst) (_dst & ~(DSTPORT_TYPE_MASK << DSTPORT_TYPE_OFFSET)) + #define FCS_SZ 4 #define PSAMPLE_NLA_PADDING 4 @@ -78,17 +92,25 @@ LKM_MOD_PARAM(psample_size, "i", int, 0); MODULE_PARM_DESC(psample_size, "psample pkt size (default 128 bytes)"); +#define PSAMPLE_QLEN_DFLT 1024 +static int psample_qlen = PSAMPLE_QLEN_DFLT; +LKM_MOD_PARAM(psample_qlen, "i", int, 0); +MODULE_PARM_DESC(psample_qlen, +"psample queue length (default 1024 buffers)"); + /* driver proc entry root */ static struct proc_dir_entry *psample_proc_root = NULL; +static struct proc_dir_entry *knet_cb_proc_root = NULL; /* psample general info */ typedef struct { struct list_head netif_list; + int netif_count; knet_hw_info_t hw; struct net *netns; spinlock_t lock; } psample_info_t; -static psample_info_t g_psample_info = {{0}}; +static psample_info_t g_psample_info = {0}; /* Maintain sampled pkt statistics */ typedef struct psample_stats_s { @@ -96,9 +118,13 @@ typedef struct psample_stats_s { unsigned long pkts_f_psample_mod; unsigned long pkts_f_handled; unsigned long pkts_f_pass_through; + unsigned long pkts_f_dst_mc; + unsigned long pkts_c_qlen_cur; + unsigned long pkts_c_qlen_hi; + unsigned long pkts_d_qlen_max; + unsigned long pkts_d_no_mem; unsigned long pkts_d_no_group; unsigned long pkts_d_sampling_disabled; - unsigned long pkts_d_no_skb; unsigned long pkts_d_not_ready; unsigned long pkts_d_metadata; unsigned long pkts_d_meta_srcport; @@ -114,6 +140,19 @@ typedef struct psample_meta_s { int sample_rate; } psample_meta_t; +typedef struct psample_pkt_s { + struct list_head list; + struct psample_group *group; + psample_meta_t meta; + struct sk_buff *skb; +} psample_pkt_t; + +typedef struct psample_work_s { + struct list_head pkt_list; + struct work_struct wq; + spinlock_t lock; +} psample_work_t; +static psample_work_t g_psample_work = {0}; static psample_netif_t* psample_netif_lookup_by_port(int unit, int port) @@ -170,7 +209,6 @@ psample_meta_srcport_get(uint8_t *pkt, void *pkt_meta) case 26: /* TD2 */ case 23: /* HX4 */ metadata += SOC_DCB32_HG_OFFSET; - break; default: break; } @@ -205,16 +243,23 @@ psample_meta_dstport_get(uint8_t *pkt, void *pkt_meta) case 32: /* TH1/TH2 */ case 26: /* TD2 */ case 23: /* HX4 */ - metadata += SOC_DCB32_HG_OFFSET; - break; default: + metadata += SOC_DCB32_HG_OFFSET; break; } if (SOC_HIGIG2_START(metadata) == SOC_HIGIG2_SOP) { + if (SOC_HIGIG2_IS_MC(metadata)) + { + DSTPORT_TYPE_CLR(dstport); + DSTPORT_TYPE_SET(dstport, DSTPORT_TYPE_MC); + } + else + { dstport = SOC_HIGIG2_DSTPORT(metadata); } + } else if (SOC_HIGIG_START(metadata) == SOC_HIGIG_SOP) { dstport = SOC_HIGIG_DSTPORT(metadata); @@ -273,10 +318,10 @@ psample_meta_sample_reason(uint8_t *pkt, void *pkt_meta) static int psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_meta) { - int srcport, dstport; + int srcport, dstport, dstport_type; int src_ifindex = 0; int dst_ifindex = 0; - int sample_rate = PSAMPLE_RATE_DFLT; + int sample_rate = 1; int sample_size = PSAMPLE_SIZE_DFLT; psample_netif_t *psample_netif = NULL; @@ -313,8 +358,16 @@ psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_m } } - /* find dst port netif (no need to lookup CPU port) */ - if (dstport != 0) { + dstport_type = DSTPORT_TYPE_GET(dstport); + dstport = DSTPORT_GET(dstport); + + /* set sFlow dst type for MC pkts */ + if (dstport_type == DSTPORT_TYPE_MC) { + DSTPORT_TYPE_SET(dst_ifindex, DSTPORT_TYPE_MC); + g_psample_stats.pkts_f_dst_mc++; + + /* find dst port netif for UC pkts (no need to lookup CPU port) */ + } else if (dstport != 0) { if ((psample_netif = psample_netif_lookup_by_port(unit, dstport))) { dst_ifindex = psample_netif->dev->ifindex; } else { @@ -323,7 +376,7 @@ psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_m } } - PSAMPLE_CB_DBG_PRINT("%s: srcport %d, dstport %d, src_ifindex %d, dst_ifindex %d, trunc_size %d, sample_rate %d\n", + PSAMPLE_CB_DBG_PRINT("%s: srcport %d, dstport %d, src_ifindex 0x%x, dst_ifindex 0x%x, trunc_size %d, sample_rate %d\n", __func__, srcport, dstport, src_ifindex, dst_ifindex, sample_size, sample_rate); sflow_meta->src_ifindex = src_ifindex; @@ -334,13 +387,51 @@ psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_m return (0); } +static void +psample_task(struct work_struct *work) +{ + psample_work_t *psample_work = container_of(work, psample_work_t, wq); + unsigned long flags; + struct list_head *list_ptr, *list_next; + psample_pkt_t *pkt; + + spin_lock_irqsave(&psample_work->lock, flags); + list_for_each_safe(list_ptr, list_next, &psample_work->pkt_list) { + /* dequeue pkt from list */ + pkt = list_entry(list_ptr, psample_pkt_t, list); + list_del(list_ptr); + g_psample_stats.pkts_c_qlen_cur--; + spin_unlock_irqrestore(&psample_work->lock, flags); + + /* send to psample */ + if (pkt) { + PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx 0x%x, dst_ifdx 0x%x, sample_rate %d\n", + __func__, pkt->group->group_num, + pkt->meta.trunc_size, pkt->meta.src_ifindex, + pkt->meta.dst_ifindex, pkt->meta.sample_rate); + + psample_sample_packet(pkt->group, + pkt->skb, + pkt->meta.trunc_size, + pkt->meta.src_ifindex, + pkt->meta.dst_ifindex, + pkt->meta.sample_rate); + g_psample_stats.pkts_f_psample_mod++; + + dev_kfree_skb_any(pkt->skb); + kfree(pkt); + } + spin_lock_irqsave(&psample_work->lock, flags); + } + spin_unlock_irqrestore(&psample_work->lock, flags); +} + int psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta, int chan, kcom_filter_t *kf) { struct psample_group *group; psample_meta_t meta; - struct sk_buff skb; int rv = 0; static int info_get = 0; @@ -386,24 +477,51 @@ psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta, meta.trunc_size = size - PSAMPLE_NLA_PADDING; } - PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx %d, dst_ifdx %d, sample_rate %d\n", + PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx 0x%x, dst_ifdx 0x%x, sample_rate %d\n", __func__, group->group_num, meta.trunc_size, meta.src_ifindex, meta.dst_ifindex, meta.sample_rate); /* drop if configured sample rate is 0 */ if (meta.sample_rate > 0) { + unsigned long flags; + psample_pkt_t *psample_pkt; + struct sk_buff *skb; + + if (g_psample_stats.pkts_c_qlen_cur >= psample_qlen) { + gprintk("%s: tail drop due to max qlen %d reached\n", __func__, psample_qlen); + g_psample_stats.pkts_d_qlen_max++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + + if ((psample_pkt = kmalloc(sizeof(psample_pkt_t), GFP_ATOMIC)) == NULL) { + gprintk("%s: failed to alloc psample mem for pkt\n", __func__); + g_psample_stats.pkts_d_no_mem++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + memcpy(&psample_pkt->meta, &meta, sizeof(psample_meta_t)); + psample_pkt->group = group; + + if ((skb = dev_alloc_skb(meta.trunc_size)) == NULL) { + gprintk("%s: failed to alloc psample mem for pkt skb\n", __func__); + g_psample_stats.pkts_d_no_mem++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + /* setup skb to point to pkt */ - memset(&skb, 0, sizeof(struct sk_buff)); - skb.len = size; - skb.data = pkt; - - psample_sample_packet(group, - &skb, - meta.trunc_size, - meta.src_ifindex, - meta.dst_ifindex, - meta.sample_rate); - - g_psample_stats.pkts_f_psample_mod++; + memcpy(skb->data, pkt, meta.trunc_size); + skb_put(skb, meta.trunc_size); + skb->len = meta.trunc_size; + psample_pkt->skb = skb; + + spin_lock_irqsave(&g_psample_work.lock, flags); + list_add_tail(&psample_pkt->list, &g_psample_work.pkt_list); + + g_psample_stats.pkts_c_qlen_cur++; + if (g_psample_stats.pkts_c_qlen_cur > g_psample_stats.pkts_c_qlen_hi) { + g_psample_stats.pkts_c_qlen_hi = g_psample_stats.pkts_c_qlen_cur; + } + + schedule_work(&g_psample_work.wq); + spin_unlock_irqrestore(&g_psample_work.lock, flags); } else { g_psample_stats.pkts_d_sampling_disabled++; } @@ -427,7 +545,7 @@ psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) psample_netif_t *psample_netif, *lpsample_netif; unsigned long flags; - if ((psample_netif = kmalloc(sizeof(psample_netif_t), GFP_KERNEL)) == NULL) { + if ((psample_netif = kmalloc(sizeof(psample_netif_t), GFP_ATOMIC)) == NULL) { gprintk("%s: failed to alloc psample mem for netif '%s'\n", __func__, dev->name); return (-1); @@ -449,6 +567,7 @@ psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) lpsample_netif = (psample_netif_t*)list; if (netif->id < lpsample_netif->id) { found = 1; + g_psample_info.netif_count++; break; } } @@ -489,6 +608,7 @@ psample_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) list_del(&psample_netif->list); PSAMPLE_CB_DBG_PRINT("%s: removing psample netif '%s'\n", __func__, dev->name); kfree(psample_netif); + g_psample_info.netif_count--; break; } } @@ -702,6 +822,47 @@ struct file_operations psample_proc_size_file_ops = { release: single_release, }; +/* + * psample map Proc Read Entry + */ +static int +psample_proc_map_show(struct seq_file *m, void *v) +{ + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + seq_printf(m, " Interface logical port ifindex\n"); + seq_printf(m, "------------- ------------ -------\n"); + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + seq_printf(m, " %-14s %-14d %d\n", + psample_netif->dev->name, + psample_netif->port, + psample_netif->dev->ifindex); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return 0; +} + +static int +psample_proc_map_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_map_show, NULL); +} + +struct file_operations psample_proc_map_file_ops = { + owner: THIS_MODULE, + open: psample_proc_map_open, + read: seq_read, + llseek: seq_lseek, + write: NULL, + release: single_release, +}; + /* * psample debug Proc Read Entry */ @@ -715,6 +876,8 @@ psample_proc_debug_show(struct seq_file *m, void *v) seq_printf(m, " dcb_size: %d\n", g_psample_info.hw.dcb_size); seq_printf(m, " pkt_hdr_size: %d\n", g_psample_info.hw.pkt_hdr_size); seq_printf(m, " cdma_channels: %d\n", g_psample_info.hw.cdma_channels); + seq_printf(m, " netif_count: %d\n", g_psample_info.netif_count); + seq_printf(m, " queue length: %d\n", psample_qlen); return 0; } @@ -779,9 +942,13 @@ psample_proc_stats_show(struct seq_file *m, void *v) seq_printf(m, " pkts sent to psample module %10lu\n", g_psample_stats.pkts_f_psample_mod); seq_printf(m, " pkts handled by psample %10lu\n", g_psample_stats.pkts_f_handled); seq_printf(m, " pkts pass through %10lu\n", g_psample_stats.pkts_f_pass_through); + seq_printf(m, " pkts with mc destination %10lu\n", g_psample_stats.pkts_f_dst_mc); + seq_printf(m, " pkts current queue length %10lu\n", g_psample_stats.pkts_c_qlen_cur); + seq_printf(m, " pkts high queue length %10lu\n", g_psample_stats.pkts_c_qlen_hi); + seq_printf(m, " pkts drop max queue length %10lu\n", g_psample_stats.pkts_d_qlen_max); + seq_printf(m, " pkts drop no memory %10lu\n", g_psample_stats.pkts_d_no_mem); seq_printf(m, " pkts drop no psample group %10lu\n", g_psample_stats.pkts_d_no_group); seq_printf(m, " pkts drop sampling disabled %10lu\n", g_psample_stats.pkts_d_sampling_disabled); - seq_printf(m, " pkts drop no skb %10lu\n", g_psample_stats.pkts_d_no_skb); seq_printf(m, " pkts drop psample not ready %10lu\n", g_psample_stats.pkts_d_not_ready); seq_printf(m, " pkts drop metadata parse error %10lu\n", g_psample_stats.pkts_d_metadata); seq_printf(m, " pkts with invalid src port %10lu\n", g_psample_stats.pkts_d_meta_srcport); @@ -796,21 +963,46 @@ psample_proc_stats_open(struct inode * inode, struct file * file) return single_open(file, psample_proc_stats_show, NULL); } +/* + * psample stats Proc Write Entry + * + * Syntax: + * write any value to clear stats + */ +static ssize_t +psample_proc_stats_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + int qlen_cur = 0; + unsigned long flags; + + spin_lock_irqsave(&g_psample_work.lock, flags); + qlen_cur = g_psample_stats.pkts_c_qlen_cur; + memset(&g_psample_stats, 0, sizeof(psample_stats_t)); + g_psample_stats.pkts_c_qlen_cur = qlen_cur; + spin_unlock_irqrestore(&g_psample_work.lock, flags); + + return count; +} struct file_operations psample_proc_stats_file_ops = { owner: THIS_MODULE, open: psample_proc_stats_open, read: seq_read, llseek: seq_lseek, - write: NULL, + write: psample_proc_stats_write, release: single_release, }; int psample_cleanup(void) { + cancel_work_sync(&g_psample_work.wq); remove_proc_entry("stats", psample_proc_root); remove_proc_entry("rate", psample_proc_root); remove_proc_entry("size", psample_proc_root); remove_proc_entry("debug", psample_proc_root); + remove_proc_entry("map" , psample_proc_root); + remove_proc_entry("psample", knet_cb_proc_root); + remove_proc_entry("bcm/knet-cb", NULL); return 0; } @@ -822,7 +1014,7 @@ int psample_init(void) /* create procfs for psample */ snprintf(psample_procfs_path, PROCFS_MAX_PATH, "bcm/knet-cb"); - proc_mkdir(psample_procfs_path, NULL); + knet_cb_proc_root = proc_mkdir(psample_procfs_path, NULL); snprintf(psample_procfs_path, PROCFS_MAX_PATH, "%s/%s", psample_procfs_path, PSAMPLE_CB_NAME); psample_proc_root = proc_mkdir(psample_procfs_path, NULL); @@ -847,6 +1039,13 @@ int psample_init(void) return -1; } + /* create procfs for getting netdev mapping */ + PROC_CREATE(entry, "map", 0666, psample_proc_root, &psample_proc_map_file_ops); + if (entry == NULL) { + gprintk("%s: Unable to create procfs entry '/procfs/%s/map'\n", __func__, psample_procfs_path); + return -1; + } + /* create procfs for debug log */ PROC_CREATE(entry, "debug", 0666, psample_proc_root, &psample_proc_debug_file_ops); if (entry == NULL) { @@ -857,11 +1056,17 @@ int psample_init(void) /* clear data structs */ memset(&g_psample_stats, 0, sizeof(psample_stats_t)); memset(&g_psample_info, 0, sizeof(psample_info_t)); + memset(&g_psample_work, 0, sizeof(psample_work_t)); /* setup psample_info struct */ INIT_LIST_HEAD(&g_psample_info.netif_list); spin_lock_init(&g_psample_info.lock); + /* setup psample work queue */ + spin_lock_init(&g_psample_work.lock); + INIT_LIST_HEAD(&g_psample_work.pkt_list); + INIT_WORK(&g_psample_work.wq, psample_task); + /* get net namespace */ g_psample_info.netns = get_net_ns_by_pid(current->pid); if (!g_psample_info.netns) { @@ -871,5 +1076,6 @@ int psample_init(void) PSAMPLE_CB_DBG_PRINT("%s: current->pid %d, netns 0x%p, sample_size %d\n", __func__, current->pid, g_psample_info.netns, psample_size); + return 0; } diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c index e1d4e2353b09..1deccacc5edd 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c @@ -35,7 +35,7 @@ static const struct genl_multicast_group psample_nl_mcgrps[] = { [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME }, }; -static struct genl_family psample_nl_family __ro_after_init; +static struct genl_family psample_nl_family; static int psample_group_nl_fill(struct sk_buff *msg, struct psample_group *group, @@ -106,7 +106,7 @@ static const struct genl_ops psample_nl_ops[] = { } }; -static struct genl_family psample_nl_family __ro_after_init = { +static struct genl_family psample_nl_family = { .name = PSAMPLE_GENL_NAME, .version = PSAMPLE_GENL_VERSION, .maxattr = PSAMPLE_ATTR_MAX, diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile index 20d83735fcce..f95593a383ce 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile @@ -65,7 +65,7 @@ ifeq (,$(kernel_version)) kernel_version=2_4 endif -ifeq ($(kernel_version),2_6) +ifneq ($(kernel_version),2_4) KOBJ=ko else KOBJ=o @@ -94,6 +94,9 @@ BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL) PSAMPLE_LOCAL := psample.$(KOBJ) PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL) +BCM_LPTP_LOCAL :=linux-bcm-ptp-clock.$(KOBJ) +BCM_LPTP=$(DEST_DIR)/$(BCM_LPTP_LOCAL) + ifeq (,$(findstring DELIVER,$(MAKECMDGOALS))) .DEFAULT_GOAL := all all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE) @@ -110,6 +113,11 @@ endif ifndef BUILD_KNET BUILD_KNET = 1 endif +# Remove this when LinuxPTP support becomes optional. +ifndef BUILD_LPTP +BUILD_LPTP = 1 +BUILD_KNETSYNC = 1 +endif ifeq ($(BUILD_KNET),1) # Kernel network support @@ -132,19 +140,35 @@ endif ifdef BUILD_PSAMPLE all_targets += $(PSAMPLE) ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT + + +# KnetSync support +ifdef BUILD_KNETSYNC + +KERNEL_TARGETS += $(BCM_PTP_CLOCK) +LOCAL_KERNEL_TARGETS += $(patsubst %,$(realpath ..)/$(platform)/%,$(BCM_PTP_CLOCK_LOCAL)) + +endif # BUILD_KNETSYNC + ifeq ($(NO_LOCAL_TARGETS),) LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(PSAMPLE_LOCAL)) all_targets +=$(LOCAL_TARGETS) endif endif +ifdef BUILD_LPTP +all_targets += $(BCM_LPTP) + +ifeq ($(NO_LOCAL_TARGETS),) +LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(BCM_LPTP_LOCAL)) +all_targets +=$(LOCAL_TARGETS) +endif +endif + ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include COND_KNET_LIBS = libuser.$(libext) endif -#SAI_FIXUP -.NOTPARALLEL: - all: $(BLDDIR)/.tree $(all_targets) ifeq ($(NO_LOCAL_TARGETS),) @@ -161,24 +185,33 @@ ADD_TO_CFLAGS += -I$(SDK)/systems/bde/linux/include ADD_TO_CFLAGS += -DPROXY_SUPPORT=0 CFLAGS += $(ADD_TO_CFLAGS) + #SAI_FIXUP CFLAGS:=$(filter-out -fPIC, $(CFLAGS)) +# KnetSync Support +ifdef BUILD_KNETSYNC +knetsync_subdirs = bcm-ptp-clock +endif # BUILD_KNETSYNC kernel_modules: $(MAKE) -C $(SDK)/systems/bde/linux/kernel kernel_version=$(kernel_version) $(MAKE) -C $(SDK)/systems/bde/linux/user/kernel kernel_version=$(kernel_version) ifeq ($(BUILD_KNET),1) - $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="shared bcm-knet" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" ifdef BUILD_PSAMPLE - $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="psample" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" endif ifdef BUILD_KNET_CB - $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" endif +ifdef BUILD_LPTP + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + subdirs="bcm-ptp-clock" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" +endif endif $(KERNEL_BDE): $(KERN_BLDROOT)/linux-kernel-bde.$(KOBJ) @@ -197,6 +230,8 @@ $(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ) $(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ) $(OBJCOPY) --strip-debug $< $@ +$(BCM_LPTP): $(KERN_BLDROOT)/linux-bcm-ptp-clock.$(KOBJ) + $(OBJCOPY) --strip-debug $< $@ ifeq ($(NO_LOCAL_TARGETS),) $(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ)))) @@ -206,10 +241,10 @@ clean:: $(MAKE) -C $(SDK)/systems/bde/linux/kernel $@ $(MAKE) -C $(SDK)/systems/bde/linux/user/kernel $@ $(MAKE) -C $(SDK)/systems/linux/kernel/modules \ - subdirs="shared bcm-knet knet-cb" \ + subdirs="shared bcm-knet knet-cb psample bcm-ptp-clock" \ override-target=linux-$(platform) $@ $(RM) $(KERNEL_BDE) $(USER_BDE) - $(RM) $(BCM_KNET) $(KNET_CB) + $(RM) $(BCM_KNET) $(KNET_CB) $(PSAMPLE) $(BCM_LPTP) $(RM) $(KERN_BLDROOT)/linux-kernel-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ) diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile new file mode 100644 index 000000000000..466faf02a515 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile @@ -0,0 +1,63 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# +# Optionally the following environment variables can be set to +# override the default build server configuration: +# +# TOOLS_DIR - path to build tools (if not in PATH already) +# CROSS_COMPILE - cross compile tools prefix +# LINUX_INCLUDE - path to Linux kernel include directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_19 +platform=gts +LINUX_MAKE_USER=1 +export LINKER_RELAX = 1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + + +include ${SDK}/make/Make.linux + diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc-4_4/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc-4_4/Makefile new file mode 100644 index 000000000000..e8405f5c2a0c --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc-4_4/Makefile @@ -0,0 +1,59 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 1.7 Broadcom SDK $ +# $Copyright: (c) 2005 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_4 +platform=iproc-$(kernel_version) + +IPROC_BUILD=1 +export IPROC_BUILD +export BUILD_PLATFORM +export ARM_LINUX_VERSION + +LINUX_MAKE_USER=1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + +include ${SDK}/make/Make.linux diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile new file mode 100644 index 000000000000..778c85a03bed --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile @@ -0,0 +1,59 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 1.7 Broadcom SDK $ +# $Copyright: (c) 2005 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_14 +platform=iproc_64 + +IPROC_BUILD=1 +export IPROC_BUILD +export BUILD_PLATFORM +export ARM_LINUX_VERSION + +LINUX_MAKE_USER=1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + +include ${SDK}/make/Make.linux diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/slk/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/slk/Makefile new file mode 100644 index 000000000000..99d49d285145 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/slk/Makefile @@ -0,0 +1,60 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# +# Optionally the following environment variables can be set to +# override the default build server configuration: +# +# TOOLS_DIR - path to build tools (if not in PATH already) +# CROSS_COMPILE - cross compile tools prefix +# LINUX_INCLUDE - path to Linux kernel include directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=3_14 +platform=slk +LINUX_MAKE_USER=1 +export LINKER_RELAX = 1 + +include ${SDK}/make/Make.linux + diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile new file mode 100644 index 000000000000..13246d09e78f --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile @@ -0,0 +1,63 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# +# Optionally the following environment variables can be set to +# override the default build server configuration: +# +# TOOLS_DIR - path to build tools (if not in PATH already) +# CROSS_COMPILE - cross compile tools prefix +# LINUX_INCLUDE - path to Linux kernel include directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_19 +platform=xlr +LINUX_MAKE_USER=1 +export LINKER_RELAX = 1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + + +include ${SDK}/make/Make.linux + From 63c1afbc683f50562a750c2e1855dfdfe6d8ab59 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 6 Oct 2020 08:37:49 -0700 Subject: [PATCH 1215/1427] [bgpcfgd]: Extract classes into their own files. Run bgpcfgd as a module (#5535) 1. Rename app module to bgpcfgd 2. Extract classes from one file to the module --- src/sonic-bgpcfgd/.gitignore | 2 +- src/sonic-bgpcfgd/app/util.py | 22 - src/sonic-bgpcfgd/bgpcfgd | 923 ------------------ .../{app => bgpcfgd}/__init__.py | 0 src/sonic-bgpcfgd/bgpcfgd/__main__.py | 4 + src/sonic-bgpcfgd/{app => bgpcfgd}/config.py | 2 +- .../{app => bgpcfgd}/directory.py | 2 +- src/sonic-bgpcfgd/{app => bgpcfgd}/log.py | 0 src/sonic-bgpcfgd/bgpcfgd/main.py | 81 ++ src/sonic-bgpcfgd/{app => bgpcfgd}/manager.py | 2 +- .../managers_allow_list.py} | 8 +- src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py | 391 ++++++++ src/sonic-bgpcfgd/bgpcfgd/managers_db.py | 28 + src/sonic-bgpcfgd/bgpcfgd/managers_intf.py | 56 ++ src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py | 69 ++ src/sonic-bgpcfgd/bgpcfgd/runner.py | 65 ++ .../{app => bgpcfgd}/template.py | 0 src/sonic-bgpcfgd/bgpcfgd/utils.py | 55 ++ src/sonic-bgpcfgd/{app => bgpcfgd}/vars.py | 0 src/sonic-bgpcfgd/pytest.ini | 2 +- src/sonic-bgpcfgd/setup.py | 4 +- src/sonic-bgpcfgd/tests/test_allow_list.py | 25 +- .../tests/test_ipv6_nexthop_global.py | 2 +- src/sonic-bgpcfgd/tests/test_pfx_filter.py | 2 +- src/sonic-bgpcfgd/tests/test_sonic-cfggen.py | 2 +- src/sonic-bgpcfgd/tests/test_templates.py | 4 +- 26 files changed, 778 insertions(+), 973 deletions(-) delete mode 100644 src/sonic-bgpcfgd/app/util.py delete mode 100755 src/sonic-bgpcfgd/bgpcfgd rename src/sonic-bgpcfgd/{app => bgpcfgd}/__init__.py (100%) create mode 100644 src/sonic-bgpcfgd/bgpcfgd/__main__.py rename src/sonic-bgpcfgd/{app => bgpcfgd}/config.py (99%) rename src/sonic-bgpcfgd/{app => bgpcfgd}/directory.py (99%) rename src/sonic-bgpcfgd/{app => bgpcfgd}/log.py (100%) create mode 100644 src/sonic-bgpcfgd/bgpcfgd/main.py rename src/sonic-bgpcfgd/{app => bgpcfgd}/manager.py (98%) rename src/sonic-bgpcfgd/{app/allow_list.py => bgpcfgd/managers_allow_list.py} (99%) create mode 100644 src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py create mode 100644 src/sonic-bgpcfgd/bgpcfgd/managers_db.py create mode 100644 src/sonic-bgpcfgd/bgpcfgd/managers_intf.py create mode 100644 src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py create mode 100644 src/sonic-bgpcfgd/bgpcfgd/runner.py rename src/sonic-bgpcfgd/{app => bgpcfgd}/template.py (100%) create mode 100644 src/sonic-bgpcfgd/bgpcfgd/utils.py rename src/sonic-bgpcfgd/{app => bgpcfgd}/vars.py (100%) diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore index 920a1b3ae499..797140c05c8d 100644 --- a/src/sonic-bgpcfgd/.gitignore +++ b/src/sonic-bgpcfgd/.gitignore @@ -2,7 +2,7 @@ build/ dist/ *.egg-info/ -app/*.pyc +bgpcfgd/*.pyc tests/*.pyc tests/__pycache__/ .idea diff --git a/src/sonic-bgpcfgd/app/util.py b/src/sonic-bgpcfgd/app/util.py deleted file mode 100644 index b25e651f1ec6..000000000000 --- a/src/sonic-bgpcfgd/app/util.py +++ /dev/null @@ -1,22 +0,0 @@ -import subprocess - -from .log import log_debug, log_err - - -def run_command(command, shell=False, hide_errors=False): - """ - Run a linux command. The command is defined as a list. See subprocess.Popen documentation on format - :param command: command to execute. Type: List of strings - :param shell: execute the command through shell when True. Type: Boolean - :param hide_errors: don't report errors to syslog when True. Type: Boolean - :return: Tuple: integer exit code from the command, stdout as a string, stderr as a string - """ - log_debug("execute command '%s'." % str(command)) - p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - if p.returncode != 0: - if not hide_errors: - print_tuple = p.returncode, str(command), stdout, stderr - log_err("command execution returned %d. Command: '%s', stdout: '%s', stderr: '%s'" % print_tuple) - - return p.returncode, stdout, stderr \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd deleted file mode 100755 index 419fd41fb4be..000000000000 --- a/src/sonic-bgpcfgd/bgpcfgd +++ /dev/null @@ -1,923 +0,0 @@ -#!/usr/bin/env python - -import sys -import datetime -import time -import syslog -import signal -import traceback -import os -import json -from collections import defaultdict - -import yaml -import jinja2 -import netaddr -from swsscommon import swsscommon - -from app.directory import Directory -from app.manager import Manager -from app.vars import g_debug -from app.log import log_debug, log_notice, log_info, log_warn, log_err, log_crit -from app.template import TemplateFabric -from app.config import ConfigMgr -from app.allow_list import BGPAllowListMgr -from app.util import run_command - -g_run = True - - -class Directory(object): - """ This class stores values and notifies callbacks which were registered to be executed as soon - as some value is changed. This class works as DB cache mostly """ - def __init__(self): - self.data = defaultdict(dict) # storage. A key is a slot name, a value is a dictionary with data - self.notify = defaultdict(lambda: defaultdict(list)) # registered callbacks: slot -> path -> handlers[] - - @staticmethod - def get_slot_name(db, table): - """ Convert db, table pair into a slot name """ - return db + "__" + table - - def path_traverse(self, slot, path): - """ - Traverse a path in the storage. - If the path is an empty string, it returns a value as it is. - If the path is not an empty string, the method will traverse through the dictionary value. - Example: - self.data["key_1"] = { "abc": { "cde": { "fgh": "val_1", "ijk": "val_2" } } } - self.path_traverse("key_1", "abc/cde") will return True, { "fgh": "val_1", "ijk": "val_2" } - :param slot: storage key - :param path: storage path as a string where each internal key is separated by '/' - :return: a pair: True if the path was found, object if it was found - """ - if slot not in self.data: - return False, None - elif path == '': - return True, self.data[slot] - d = self.data[slot] - for p in path.split("/"): - if p not in d: - return False, None - d = d[p] - return True, d - - def path_exist(self, db, table, path): - """ - Check if the path exists in the storage - :param db: db name - :param table: table name - :param path: requested path - :return: True if the path is available, False otherwise - """ - slot = self.get_slot_name(db, table) - return self.path_traverse(slot, path)[0] - - def get_path(self, db, table, path): - """ - Return the requested path from the storage - :param db: db name - :param table: table name - :param path: requested path - :return: object if the path was found, None otherwise - """ - slot = self.get_slot_name(db, table) - return self.path_traverse(slot, path)[1] - - def put(self, db, table, key, value): - """ - Put information into the storage. Notify handlers which are dependant to the information - :param db: db name - :param table: table name - :param key: key to change - :param value: value to put - :return: - """ - slot = self.get_slot_name(db, table) - self.data[slot][key] = value - if slot in self.notify: - for path in self.notify[slot].keys(): - if self.path_exist(db, table, path): - for handler in self.notify[slot][path]: - handler() - - def get(self, db, table, key): - """ - Get a value from the storage - :param db: db name - :param table: table name - :param key: ket to get - :return: value for the key - """ - slot = self.get_slot_name(db, table) - return self.data[slot][key] - - def get_slot(self, db, table): - """ - Get an object from the storage - :param db: db name - :param table: table name - :return: object for the slot - """ - slot = self.get_slot_name(db, table) - return self.data[slot] - - def remove(self, db, table, key): - """ - Remove a value from the storage - :param db: db name - :param table: table name - :param key: key to remove - """ - slot = self.get_slot_name(db, table) - if slot in self.data: - if key in self.data[slot]: - del self.data[slot][key] - else: - log_err("Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) - else: - log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) - - def remove_slot(self, db, table): - """ - Remove an object from the storage - :param db: db name - :param table: table name - """ - slot = self.get_slot_name(db, table) - if slot in self.data: - del self.data[slot] - else: - log_err("Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) - - def available(self, db, table): - """ - Check if the table is available - :param db: db name - :param table: table name - :return: True if the slot is available, False if not - """ - slot = self.get_slot_name(db, table) - return slot in self.data - - def available_deps(self, deps): - """ - Check if all items from the deps list is available in the storage - :param deps: list of dependencies - :return: True if all dependencies are presented, False otherwise - """ - res = True - for db, table, path in deps: - res = res and self.path_exist(db, table, path) - return res - - def subscribe(self, deps, handler): - """ - Subscribe the handler to be run as soon as all dependencies are presented - :param deps: - :param handler: - :return: - """ - for db, table, path in deps: - slot = self.get_slot_name(db, table) - self.notify[slot][path].append(handler) - - -class Runner(object): - """ Implements main io-loop of the application - It will run event handlers inside of Manager objects - when corresponding db/table is updated - """ - SELECT_TIMEOUT = 1000 - - def __init__(self): - """ Constructor """ - self.db_connectors = {} - self.selector = swsscommon.Select() - self.callbacks = defaultdict(lambda: defaultdict(list)) # db -> table -> handlers[] - self.subscribers = set() - - def add_manager(self, manager): - """ - Add a manager to the Runner. - As soon as new events will be receiving by Runner, - handlers of corresponding objects will be executed - :param manager: an object implementing Manager - """ - db_name = manager.get_database() - table_name = manager.get_table_name() - db = swsscommon.SonicDBConfig.getDbId(db_name) - if db not in self.db_connectors: - self.db_connectors[db] = swsscommon.DBConnector(db_name, 0) - - if table_name not in self.callbacks[db]: - conn = self.db_connectors[db] - subscriber = swsscommon.SubscriberStateTable(conn, table_name) - self.subscribers.add(subscriber) - self.selector.addSelectable(subscriber) - self.callbacks[db][table_name].append(manager.handler) - - def run(self): - """ Main loop """ - while g_run: - state, _ = self.selector.select(Runner.SELECT_TIMEOUT) - if state == self.selector.TIMEOUT: - continue - elif state == self.selector.ERROR: - raise Exception("Received error from select") - - for subscriber in self.subscribers: - key, op, fvs = subscriber.pop() - if not key: - continue - log_debug("Received message : '%s'" % str((key, op, fvs))) - for callback in self.callbacks[subscriber.getDbConnector().getDbId()][subscriber.getTableName()]: - callback(key, op, dict(fvs)) - - -class Manager(object): - """ This class represents a SONiC DB table """ - def __init__(self, common_objs, deps, database, table_name): - """ - Initialize class - :param common_objs: common object dictionary - :param deps: dependencies list - :param database: database name - :param table_name: table name - """ - self.directory = common_objs['directory'] - self.cfg_mgr = common_objs['cfg_mgr'] - self.constants = common_objs['constants'] - self.deps = deps - self.db_name = database - self.table_name = table_name - self.set_queue = [] - self.directory.subscribe(deps, self.on_deps_change) # subscribe this class method on directory changes - - def get_database(self): - """ Return associated database """ - return self.db_name - - def get_table_name(self): - """ Return associated table name""" - return self.table_name - - def handler(self, key, op, data): - """ - This method is executed on each add/remove event on the table. - :param key: key of the table entry - :param op: operation on the table entry. Could be either 'SET' or 'DEL' - :param data: associated data of the event. Empty for 'DEL' operation. - """ - if op == swsscommon.SET_COMMAND: - if self.directory.available_deps(self.deps): # all required dependencies are set in the Directory? - res = self.set_handler(key, data) - if not res: # set handler returned False, which means it is not ready to process is. Save it for later. - log_debug("'SET' handler returned NOT_READY for the Manager: %s" % self.__class__) - self.set_queue.append((key, data)) - else: - log_debug("Not all dependencies are met for the Manager: %s" % self.__class__) - self.set_queue.append((key, data)) - elif op == swsscommon.DEL_COMMAND: - self.del_handler(key) - else: - log_err("Invalid operation '%s' for key '%s'" % (op, key)) - - def on_deps_change(self): - """ This method is being executed on every dependency change """ - if not self.directory.available_deps(self.deps): - return - new_queue = [] - for key, data in self.set_queue: - res = self.set_handler(key, data) - if not res: - new_queue.append((key, data)) - self.set_queue = new_queue - - def set_handler(self, key, data): - """ Placeholder for 'SET' command """ - log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) - - def del_handler(self, key): - """ Placeholder for 'DEL' command """ - log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) - - -class BGPDataBaseMgr(Manager): - """ This class updates the Directory object when db table is updated """ - def __init__(self, common_objs, db, table): - """ - Initialize the object - :param common_objs: common object dictionary - :param db: name of the db - :param table: name of the table in the db - """ - super(BGPDataBaseMgr, self).__init__( - common_objs, - [], - db, - table, - ) - - def set_handler(self, key, data): - """ Implementation of 'SET' command for this class """ - self.directory.put(self.db_name, self.table_name, key, data) - - return True - - def del_handler(self, key): - """ Implementation of 'DEL' command for this class """ - self.directory.remove(self.db_name, self.table_name, key) - - -class InterfaceMgr(Manager): - """ This class updates the Directory object when interface-related table is updated """ - def __init__(self, common_objs, db, table): - """ - Initialize the object - :param common_objs: common object dictionary - :param db: name of the db - :param table: name of the table in the db - """ - super(InterfaceMgr, self).__init__( - common_objs, - [], - db, - table, - ) - - def set_handler(self, key, data): - """ Implementation of 'SET' command. - Similar to BGPDataBaseMgr but enriches data object with additional data """ - # Interface table can have two keys, - # one with ip prefix and one without ip prefix - if '|' in key: - interface_name, network_str = key.split('|', 1) - try: - network = netaddr.IPNetwork(str(network_str)) - except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): - log_warn("Subnet '%s' format is wrong for interface '%s'" % (network_str, data["interface"])) - return True - data["interface"] = interface_name - data["prefixlen"] = str(network.prefixlen) - ip = str(network.ip) - self.directory.put("LOCAL", "local_addresses", ip, data) - self.directory.put(self.db_name, self.table_name, key, data) - self.directory.put("LOCAL", "interfaces", key, data) - return True - - def del_handler(self, key): - """ Implementation of 'DEL' command - Also removes data object enrichment """ - if '|' in key: - interface, network = key.split('|', 1) - try: - network = netaddr.IPNetwork(str(network)) - except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): - log_warn("Subnet '%s' format is wrong for interface '%s'" % (network, interface)) - return - ip = str(network.ip) - self.directory.remove("LOCAL", "local_addresses", ip) - self.directory.remove(self.db_name, self.table_name, key) - self.directory.remove("LOCAL", "interfaces", key) - - -class BGPPeerGroupMgr(object): - """ This class represents peer-group and routing policy for the peer_type """ - def __init__(self, common_objs, base_template): - """ - Construct the object - :param common_objs: common objects - :param base_template: path to the directory with Jinja2 templates - """ - self.cfg_mgr = common_objs['cfg_mgr'] - self.constants = common_objs['constants'] - tf = common_objs['tf'] - self.policy_template = tf.from_file(base_template + "policies.conf.j2") - self.peergroup_template = tf.from_file(base_template + "peer-group.conf.j2") - - def update(self, name, **kwargs): - """ - Update peer-group and routing policy for the peer with the name - :param name: name of the peer. Used for logging only - :param kwargs: dictionary with parameters for rendering - """ - rc_policy = self.update_policy(name, **kwargs) - rc_pg = self.update_pg(name, **kwargs) - return rc_policy and rc_pg - - def update_policy(self, name, **kwargs): - """ - Update routing policy for the peer - :param name: name of the peer. Used for logging only - :param kwargs: dictionary with parameters for rendering - """ - try: - policy = self.policy_template.render(**kwargs) - except jinja2.TemplateError as e: - log_err("Can't render policy template name: '%s': %s" % (name, str(e))) - return False - - return self.update_entity(policy, "Routing policy for peer '%s'" % name) - - def update_pg(self, name, **kwargs): - """ - Update peer-group for the peer - :param name: name of the peer. Used for logging only - :param kwargs: dictionary with parameters for rendering - """ - try: - pg = self.peergroup_template.render(**kwargs) - except jinja2.TemplateError as e: - log_err("Can't render peer-group template: '%s': %s" % (name, str(e))) - return False - - if kwargs['vrf'] == 'default': - cmd = ('router bgp %s\n' % kwargs['bgp_asn']) + pg - else: - cmd = ('router bgp %s vrf %s\n' % (kwargs['bgp_asn'], kwargs['vrf'])) + pg - - return self.update_entity(cmd, "Peer-group for peer '%s'" % name) - - def update_entity(self, cmd, txt): - """ - Send commands to FRR - :param cmd: commands to send in a raw form - :param txt: text for the syslog output - :return: - """ - ret_code = self.cfg_mgr.push(cmd) - if ret_code: - log_info("%s was updated" % txt) - else: - log_err("Can't update %s" % txt) - return ret_code - - -class BGPPeerMgrBase(Manager): - """ Manager of BGP peers """ - def __init__(self, common_objs, db_name, table_name, peer_type, check_neig_meta): - """ - Initialize the object - :param common_objs: common objects - :param table_name: name of the table with peers - :param peer_type: type of the peers. It is used to find right templates - """ - self.common_objs = common_objs - self.constants = self.common_objs["constants"] - self.fabric = common_objs['tf'] - self.peer_type = peer_type - - base_template = "bgpd/templates/" + self.constants["bgp"]["peers"][peer_type]["template_dir"] + "/" - self.templates = { - "add": self.fabric.from_file(base_template + "instance.conf.j2"), - "delete": self.fabric.from_string('no neighbor {{ neighbor_addr }}'), - "shutdown": self.fabric.from_string('neighbor {{ neighbor_addr }} shutdown'), - "no shutdown": self.fabric.from_string('no neighbor {{ neighbor_addr }} shutdown'), - } - - deps = [ - ("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"), - ("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME, "Loopback0"), - ("LOCAL", "local_addresses", ""), - ("LOCAL", "interfaces", ""), - ] - - if check_neig_meta: - self.check_neig_meta = 'bgp' in self.constants \ - and 'use_neighbors_meta' in self.constants['bgp'] \ - and self.constants['bgp']['use_neighbors_meta'] - else: - self.check_neig_meta = False - - self.check_deployment_id = 'bgp' in self.constants \ - and 'use_deployment_id' in self.constants['bgp'] \ - and self.constants['bgp']['use_deployment_id'] - - if self.check_neig_meta: - deps.append(("CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME, "")) - - if self.check_deployment_id: - deps.append(("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/deployment_id")) - - super(BGPPeerMgrBase, self).__init__( - common_objs, - deps, - db_name, - table_name, - ) - - self.peers = self.load_peers() - self.peer_group_mgr = BGPPeerGroupMgr(self.common_objs, base_template) - return - - def set_handler(self, key, data): - """ - It runs on 'SET' command - :param key: key of the changed table - :param data: the data associated with the change - """ - vrf, nbr = self.split_key(key) - peer_key = (vrf, nbr) - if peer_key not in self.peers: - return self.add_peer(vrf, nbr, data) - else: - return self.update_peer(vrf, nbr, data) - - def add_peer(self, vrf, nbr, data): - """ - Add a peer into FRR. This is used if the peer is not existed in FRR yet - :param vrf: vrf name. Name is equal "default" for the global vrf - :param nbr: neighbor ip address (name for dynamic peer type) - :param data: associated data - :return: True if this adding was successful, False otherwise - """ - print_data = vrf, nbr, data - bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] - # - lo0_ipv4 = self.get_lo0_ipv4() - if lo0_ipv4 is None: - log_warn("Loopback0 ipv4 address is not presented yet") - return False - # - if "local_addr" not in data: - log_warn("Peer %s. Missing attribute 'local_addr'" % nbr) - else: - # The bgp session that belongs to a vnet cannot be advertised as the default BGP session. - # So we need to check whether this bgp session belongs to a vnet. - data["local_addr"] = str(netaddr.IPNetwork(str(data["local_addr"])).ip) - interface = self.get_local_interface(data["local_addr"]) - if not interface: - print_data = nbr, data["local_addr"] - log_debug("Peer '%s' with local address '%s' wait for the corresponding interface to be set" % print_data) - return False - vnet = self.get_vnet(interface) - if vnet: - # Ignore the bgp session that is in a vnet - log_info("Ignore the BGP peer '%s' as the interface '%s' is in vnet '%s'" % (nbr, interface, vnet)) - return True - - kwargs = { - 'CONFIG_DB__DEVICE_METADATA': self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME), - 'constants': self.constants, - 'bgp_asn': bgp_asn, - 'vrf': vrf, - 'neighbor_addr': nbr, - 'bgp_session': data, - 'loopback0_ipv4': lo0_ipv4, - } - if self.check_neig_meta: - neigmeta = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME) - if 'name' in data and data["name"] not in neigmeta: - log_info("DEVICE_NEIGHBOR_METADATA is not ready for neighbor '%s' - '%s'" % (nbr, data['name'])) - return False - kwargs['CONFIG_DB__DEVICE_NEIGHBOR_METADATA'] = neigmeta - - tag = data['name'] if 'name' in data else nbr - self.peer_group_mgr.update(tag, **kwargs) - - try: - cmd = self.templates["add"].render(**kwargs) - except jinja2.TemplateError as e: - msg = "Peer '(%s|%s)'. Error in rendering the template for 'SET' command '%s'" % print_data - log_err("%s: %s" % (msg, str(e))) - return True - if cmd is not None: - ret_code = self.apply_op(cmd, vrf) - key = (vrf, nbr) - if ret_code: - self.peers.add(key) - log_info("Peer '(%s|%s)' added with attributes '%s'" % print_data) - else: - log_err("Peer '(%s|%s)' wasn't added." % (vrf, nbr)) - - return True - - def update_peer(self, vrf, nbr, data): - """ - Update a peer. This is used when the peer is already in the FRR - Update support only "admin_status" for now - :param vrf: vrf name. Name is equal "default" for the global vrf - :param nbr: neighbor ip address (name for dynamic peer type) - :param data: associated data - :return: True if this adding was successful, False otherwise - """ - if "admin_status" in data: - self.change_admin_status(vrf, nbr, data) - else: - log_err("Peer '(%s|%s)': Can't update the peer. Only 'admin_status' attribute is supported" % (vrf, nbr)) - - return True - - def change_admin_status(self, vrf, nbr, data): - """ - Change admin status of a peer - :param vrf: vrf name. Name is equal "default" for the global vrf - :param nbr: neighbor ip address (name for dynamic peer type) - :param data: associated data - :return: True if this adding was successful, False otherwise - """ - if data['admin_status'] == 'up': - self.apply_admin_status(vrf, nbr, "no shutdown", "up") - elif data['admin_status'] == 'down': - self.apply_admin_status(vrf, nbr, "shutdown", "down") - else: - print_data = vrf, nbr, data['admin_status'] - log_err("Peer '%s|%s': Can't update the peer. It has wrong attribute value attr['admin_status'] = '%s'" % print_data) - - def apply_admin_status(self, vrf, nbr, template_name, admin_state): - """ - Render admin state template and apply the command to the FRR - :param vrf: vrf name. Name is equal "default" for the global vrf - :param nbr: neighbor ip address (name for dynamic peer type) - :param template_name: name of the template to render - :param admin_state: desired admin state - :return: True if this adding was successful, False otherwise - """ - print_data = vrf, nbr, admin_state - ret_code = self.apply_op(self.templates[template_name].render(neighbor_addr=nbr), vrf) - if ret_code: - log_info("Peer '%s|%s' admin state is set to '%s'" % print_data) - else: - log_err("Can't set peer '%s|%s' admin state to '%s'." % print_data) - - def del_handler(self, key): - """ - 'DEL' handler for the BGP PEER tables - :param key: key of the neighbor - """ - vrf, nbr = self.split_key(key) - peer_key = (vrf, nbr) - if peer_key not in self.peers: - log_warn("Peer '(%s|%s)' has not been found" % (vrf, nbr)) - return - cmd = self.templates["delete"].render(neighbor_addr=nbr) - ret_code = self.apply_op(cmd, vrf) - if ret_code: - log_info("Peer '(%s|%s)' has been removed" % (vrf, nbr)) - self.peers.remove(peer_key) - else: - log_err("Peer '(%s|%s)' hasn't been removed" % (vrf, nbr)) - - def apply_op(self, cmd, vrf): - """ - Push commands cmd into FRR - :param cmd: commands in raw format - :param vrf: vrf where the commands should be applied - :return: True if no errors, False if there are errors - """ - bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] - if vrf == 'default': - cmd = ('router bgp %s\n' % bgp_asn) + cmd - else: - cmd = ('router bgp %s vrf %s\n' % (bgp_asn, vrf)) + cmd - return self.cfg_mgr.push(cmd) - - def get_lo0_ipv4(self): - """ - Extract Loopback0 ipv4 address from the Directory - :return: ipv4 address for Loopback0, None if nothing found - """ - loopback0_ipv4 = None - for loopback in self.directory.get_slot("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME).iterkeys(): - if loopback.startswith("Loopback0|"): - loopback0_prefix_str = loopback.replace("Loopback0|", "") - loopback0_ip_str = loopback0_prefix_str[:loopback0_prefix_str.find('/')] - if TemplateFabric.is_ipv4(loopback0_ip_str): - loopback0_ipv4 = loopback0_ip_str - break - - return loopback0_ipv4 - - def get_local_interface(self, local_addr): - """ - Get interface according to the local address from the directory - :param: directory: Directory object that stored metadata of interfaces - :param: local_addr: Local address of the interface - :return: Return the metadata of the interface with the local address - If the interface has not been set, return None - """ - local_addresses = self.directory.get_slot("LOCAL", "local_addresses") - # Check if the local address of this bgp session has been set - if local_addr not in local_addresses: - return None - local_address = local_addresses[local_addr] - interfaces = self.directory.get_slot("LOCAL", "interfaces") - # Check if the information for the interface of this local address has been set - if local_address.has_key("interface") and local_address["interface"] in interfaces: - return interfaces[local_address["interface"]] - else: - return None - - @staticmethod - def get_vnet(interface): - """ - Get the VNet name of the interface - :param: interface: The metadata of the interface - :return: Return the vnet name of the interface if this interface belongs to a vnet, - Otherwise return None - """ - if interface.has_key("vnet_name") and interface["vnet_name"]: - return interface["vnet_name"] - else: - return None - - @staticmethod - def split_key(key): - """ - Split key into ip address and vrf name. If there is no vrf, "default" would be return for vrf - :param key: key to split - :return: vrf name extracted from the key, peer ip address extracted from the key - """ - if '|' not in key: - return 'default', key - else: - return tuple(key.split('|', 1)) - - @staticmethod - def load_peers(): - """ - Load peers from FRR. - :return: set of peers, which are already installed in FRR - """ - command = ["vtysh", "-c", "show bgp vrfs json"] - ret_code, out, err = run_command(command) - if ret_code == 0: - js_vrf = json.loads(out) - vrfs = js_vrf['vrfs'].keys() - else: - log_crit("Can't read bgp vrfs: %s" % err) - raise Exception("Can't read bgp vrfs: %s" % err) - peers = set() - for vrf in vrfs: - command = ["vtysh", "-c", 'show bgp vrf %s neighbors json' % str(vrf)] - ret_code, out, err = run_command(command) - if ret_code == 0: - js_bgp = json.loads(out) - for nbr in js_bgp.keys(): - peers.add((vrf, nbr)) - else: - log_crit("Can't read vrf '%s' neighbors: %s" % (vrf, str(err))) - raise Exception("Can't read vrf '%s' neighbors: %s" % (vrf, str(err))) - - return peers - - -class ZebraSetSrc(Manager): - """ This class initialize "set src" settings for zebra """ - def __init__(self, common_objs, db, table): - """ - Initialize the object - :param common_objs: common object dictionary - :param db: name of the db - :param table: name of the table in the db - """ - super(ZebraSetSrc, self).__init__( - common_objs, - [], - db, - table, - ) - tf = common_objs['tf'] - self.zebra_set_src_template = tf.from_file("zebra/zebra.set_src.conf.j2") - self.lo_ipv4 = None - self.lo_ipv6 = None - - def set_handler(self, key, data): - """ Implementation of 'SET' command for this class """ - self.directory.put(self.db_name, self.table_name, key, data) - # - if key.startswith("Loopback0|") and "state" in data and data["state"] == "ok": - ip_addr_w_mask = key.replace("Loopback0|", "") - slash_pos = ip_addr_w_mask.rfind("/") - if slash_pos == -1: - log_err("Wrong Loopback0 ip prefix: '%s'" % ip_addr_w_mask) - return True - ip_addr = ip_addr_w_mask[:slash_pos] - try: - if TemplateFabric.is_ipv4(ip_addr): - if self.lo_ipv4 is None: - self.lo_ipv4 = ip_addr - txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC", lo_ip=ip_addr, ip_proto="") - else: - log_warn("Update command is not supported for set src templates. current ip='%s'. new ip='%s'" % (self.lo_ipv4, ip_addr)) - return True - elif TemplateFabric.is_ipv6(ip_addr): - if self.lo_ipv6 is None: - self.lo_ipv6 = ip_addr - txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC6", lo_ip=ip_addr, ip_proto="v6") - else: - log_warn("Update command is not supported for set src templates. current ip='%s'. new ip='%s'" % (self.lo_ipv6, ip_addr)) - return True - else: - log_err("Got ambiguous ip address '%s'" % ip_addr) - return True - except jinja2.TemplateError as e: - log_err("Error while rendering 'set src' template: %s" % str(e)) - return True - if self.cfg_mgr.push(txt): - log_info("The 'set src' configuration with Loopback0 ip '%s' was pushed" % ip_addr) - else: - log_err("The 'set src' configuration with Loopback0 ip '%s' wasn't pushed" % ip_addr) - return True - - def del_handler(self, key): - """ Implementation of 'DEL' command for this class """ - self.directory.remove(self.db_name, self.table_name, key) - log_warn("Delete command is not supported for 'zebra set src' templates") - - -def wait_for_daemons(daemons, seconds): - """ - Wait until FRR daemons are ready for requests - :param daemons: list of FRR daemons to wait - :param seconds: number of seconds to wait, until raise an error - """ - stop_time = datetime.datetime.now() + datetime.timedelta(seconds=seconds) - log_info("Start waiting for FRR daemons: %s" % str(datetime.datetime.now())) - while datetime.datetime.now() < stop_time: - ret_code, out, err = run_command(["vtysh", "-c", "show daemons"], hide_errors=True) - if ret_code == 0 and all(daemon in out for daemon in daemons): - log_info("All required daemons have connected to vtysh: %s" % str(datetime.datetime.now())) - return - else: - log_warn("Can't read daemon status from FRR: %s" % str(err)) - time.sleep(0.1) # sleep 100 ms - raise RuntimeError("FRR daemons hasn't been started in %d seconds" % seconds) - - -def read_constants(): - """ Read file with constants values from /etc/sonic/constants.yml """ - with open('/etc/sonic/constants.yml') as fp: - content = yaml.load(fp) # FIXME: , Loader=yaml.FullLoader) - if "constants" not in content: - log_crit("/etc/sonic/constants.yml doesn't have 'constants' key") - raise Exception("/etc/sonic/constants.yml doesn't have 'constants' key") - return content["constants"] - - -def main(): - """ Main function """ - wait_for_daemons(["bgpd", "zebra", "staticd"], seconds=20) - # - common_objs = { - 'directory': Directory(), - 'cfg_mgr': ConfigMgr(), - 'tf': TemplateFabric(), - 'constants': read_constants(), - } - managers = [ - # Config DB managers - BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME), - BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME), - # Interface managers - InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_INTF_TABLE_NAME), - InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME), - InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VLAN_INTF_TABLE_NAME), - InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LAG_INTF_TABLE_NAME), - # State DB managers - ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME), - # Peer Managers - BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), - BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False), - BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), - # AllowList Managers - BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), - ] - runner = Runner() - for mgr in managers: - runner.add_manager(mgr) - runner.run() - - -def signal_handler(_, __): # signal_handler(signum, frame) - """ signal handler """ - global g_run - g_run = False - - -if __name__ == '__main__': - rc = 0 - try: - syslog.openlog('bgpcfgd') - signal.signal(signal.SIGTERM, signal_handler) - signal.signal(signal.SIGINT, signal_handler) - main() - except KeyboardInterrupt: - log_notice("Keyboard interrupt") - except RuntimeError as exc: - log_crit(str(exc)) - rc = -2 - if g_debug: - raise - except Exception as exc: - log_crit("Got an exception %s: Traceback: %s" % (str(exc), traceback.format_exc())) - rc = -1 - if g_debug: - raise - finally: - syslog.closelog() - try: - sys.exit(rc) - except SystemExit: - os._exit(rc) diff --git a/src/sonic-bgpcfgd/app/__init__.py b/src/sonic-bgpcfgd/bgpcfgd/__init__.py similarity index 100% rename from src/sonic-bgpcfgd/app/__init__.py rename to src/sonic-bgpcfgd/bgpcfgd/__init__.py diff --git a/src/sonic-bgpcfgd/bgpcfgd/__main__.py b/src/sonic-bgpcfgd/bgpcfgd/__main__.py new file mode 100644 index 000000000000..413eeee346d0 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/__main__.py @@ -0,0 +1,4 @@ +from .main import main + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/config.py b/src/sonic-bgpcfgd/bgpcfgd/config.py similarity index 99% rename from src/sonic-bgpcfgd/app/config.py rename to src/sonic-bgpcfgd/bgpcfgd/config.py index a0c1329f832e..c642842a2c16 100644 --- a/src/sonic-bgpcfgd/app/config.py +++ b/src/sonic-bgpcfgd/bgpcfgd/config.py @@ -3,7 +3,7 @@ from .vars import g_debug from .log import log_crit, log_err -from .util import run_command +from .utils import run_command class ConfigMgr(object): diff --git a/src/sonic-bgpcfgd/app/directory.py b/src/sonic-bgpcfgd/bgpcfgd/directory.py similarity index 99% rename from src/sonic-bgpcfgd/app/directory.py rename to src/sonic-bgpcfgd/bgpcfgd/directory.py index d27ec64256e3..d2dfc915c037 100644 --- a/src/sonic-bgpcfgd/app/directory.py +++ b/src/sonic-bgpcfgd/bgpcfgd/directory.py @@ -1,6 +1,6 @@ from collections import defaultdict -from app.log import log_err +from .log import log_err class Directory(object): diff --git a/src/sonic-bgpcfgd/app/log.py b/src/sonic-bgpcfgd/bgpcfgd/log.py similarity index 100% rename from src/sonic-bgpcfgd/app/log.py rename to src/sonic-bgpcfgd/bgpcfgd/log.py diff --git a/src/sonic-bgpcfgd/bgpcfgd/main.py b/src/sonic-bgpcfgd/bgpcfgd/main.py new file mode 100644 index 000000000000..bef2f733ad57 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/main.py @@ -0,0 +1,81 @@ +import os +import signal +import sys +import syslog +import traceback + +from swsscommon import swsscommon + +from .config import ConfigMgr +from .directory import Directory +from .log import log_notice, log_crit +from .managers_allow_list import BGPAllowListMgr +from .managers_bgp import BGPPeerMgrBase +from .managers_db import BGPDataBaseMgr +from .managers_intf import InterfaceMgr +from .managers_setsrc import ZebraSetSrc +from .runner import Runner, signal_handler +from .template import TemplateFabric +from .utils import wait_for_daemons, read_constants +from .vars import g_debug + + +def do_work(): + """ Main function """ + wait_for_daemons(["bgpd", "zebra", "staticd"], seconds=20) + # + common_objs = { + 'directory': Directory(), + 'cfg_mgr': ConfigMgr(), + 'tf': TemplateFabric(), + 'constants': read_constants(), + } + managers = [ + # Config DB managers + BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME), + BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME), + # Interface managers + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_INTF_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VLAN_INTF_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LAG_INTF_TABLE_NAME), + # State DB managers + ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME), + # Peer Managers + BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), + # AllowList Managers + BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), + ] + runner = Runner() + for mgr in managers: + runner.add_manager(mgr) + runner.run() + + +def main(): + rc = 0 + try: + syslog.openlog('bgpcfgd') + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) + do_work() + except KeyboardInterrupt: + log_notice("Keyboard interrupt") + except RuntimeError as exc: + log_crit(str(exc)) + rc = -2 + if g_debug: + raise + except Exception as exc: + log_crit("Got an exception %s: Traceback: %s" % (str(exc), traceback.format_exc())) + rc = -1 + if g_debug: + raise + finally: + syslog.closelog() + try: + sys.exit(rc) + except SystemExit: + os._exit(rc) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/manager.py b/src/sonic-bgpcfgd/bgpcfgd/manager.py similarity index 98% rename from src/sonic-bgpcfgd/app/manager.py rename to src/sonic-bgpcfgd/bgpcfgd/manager.py index ba45029b5120..6966a20f4b35 100644 --- a/src/sonic-bgpcfgd/app/manager.py +++ b/src/sonic-bgpcfgd/bgpcfgd/manager.py @@ -1,6 +1,6 @@ from swsscommon import swsscommon -from app.log import log_debug, log_err +from .log import log_debug, log_err class Manager(object): diff --git a/src/sonic-bgpcfgd/app/allow_list.py b/src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py similarity index 99% rename from src/sonic-bgpcfgd/app/allow_list.py rename to src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py index 2637d6999244..b8a784a2de5d 100644 --- a/src/sonic-bgpcfgd/app/allow_list.py +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py @@ -3,10 +3,10 @@ """ import re -from app.log import log_debug, log_info, log_err, log_warn -from app.template import TemplateFabric -from app.manager import Manager -from app.util import run_command +from .log import log_debug, log_info, log_err, log_warn +from .template import TemplateFabric +from .manager import Manager +from .utils import run_command class BGPAllowListMgr(Manager): """ This class initialize "AllowList" settings """ diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py b/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py new file mode 100644 index 000000000000..fc7e04f7e7b4 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py @@ -0,0 +1,391 @@ +import json +from swsscommon import swsscommon + +import jinja2 +import netaddr + +from .log import log_warn, log_err, log_info, log_debug, log_crit +from .manager import Manager +from .template import TemplateFabric +from .utils import run_command + + +class BGPPeerGroupMgr(object): + """ This class represents peer-group and routing policy for the peer_type """ + def __init__(self, common_objs, base_template): + """ + Construct the object + :param common_objs: common objects + :param base_template: path to the directory with Jinja2 templates + """ + self.cfg_mgr = common_objs['cfg_mgr'] + self.constants = common_objs['constants'] + tf = common_objs['tf'] + self.policy_template = tf.from_file(base_template + "policies.conf.j2") + self.peergroup_template = tf.from_file(base_template + "peer-group.conf.j2") + + def update(self, name, **kwargs): + """ + Update peer-group and routing policy for the peer with the name + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + rc_policy = self.update_policy(name, **kwargs) + rc_pg = self.update_pg(name, **kwargs) + return rc_policy and rc_pg + + def update_policy(self, name, **kwargs): + """ + Update routing policy for the peer + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + try: + policy = self.policy_template.render(**kwargs) + except jinja2.TemplateError as e: + log_err("Can't render policy template name: '%s': %s" % (name, str(e))) + return False + + return self.update_entity(policy, "Routing policy for peer '%s'" % name) + + def update_pg(self, name, **kwargs): + """ + Update peer-group for the peer + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + try: + pg = self.peergroup_template.render(**kwargs) + except jinja2.TemplateError as e: + log_err("Can't render peer-group template: '%s': %s" % (name, str(e))) + return False + + if kwargs['vrf'] == 'default': + cmd = ('router bgp %s\n' % kwargs['bgp_asn']) + pg + else: + cmd = ('router bgp %s vrf %s\n' % (kwargs['bgp_asn'], kwargs['vrf'])) + pg + + return self.update_entity(cmd, "Peer-group for peer '%s'" % name) + + def update_entity(self, cmd, txt): + """ + Send commands to FRR + :param cmd: commands to send in a raw form + :param txt: text for the syslog output + :return: + """ + ret_code = self.cfg_mgr.push(cmd) + if ret_code: + log_info("%s was updated" % txt) + else: + log_err("Can't update %s" % txt) + return ret_code + + +class BGPPeerMgrBase(Manager): + """ Manager of BGP peers """ + def __init__(self, common_objs, db_name, table_name, peer_type, check_neig_meta): + """ + Initialize the object + :param common_objs: common objects + :param table_name: name of the table with peers + :param peer_type: type of the peers. It is used to find right templates + """ + self.common_objs = common_objs + self.constants = self.common_objs["constants"] + self.fabric = common_objs['tf'] + self.peer_type = peer_type + + base_template = "bgpd/templates/" + self.constants["bgp"]["peers"][peer_type]["template_dir"] + "/" + self.templates = { + "add": self.fabric.from_file(base_template + "instance.conf.j2"), + "delete": self.fabric.from_string('no neighbor {{ neighbor_addr }}'), + "shutdown": self.fabric.from_string('neighbor {{ neighbor_addr }} shutdown'), + "no shutdown": self.fabric.from_string('no neighbor {{ neighbor_addr }} shutdown'), + } + + deps = [ + ("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"), + ("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME, "Loopback0"), + ("LOCAL", "local_addresses", ""), + ("LOCAL", "interfaces", ""), + ] + + if check_neig_meta: + self.check_neig_meta = 'bgp' in self.constants \ + and 'use_neighbors_meta' in self.constants['bgp'] \ + and self.constants['bgp']['use_neighbors_meta'] + else: + self.check_neig_meta = False + + self.check_deployment_id = 'bgp' in self.constants \ + and 'use_deployment_id' in self.constants['bgp'] \ + and self.constants['bgp']['use_deployment_id'] + + if self.check_neig_meta: + deps.append(("CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME, "")) + + if self.check_deployment_id: + deps.append(("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/deployment_id")) + + super(BGPPeerMgrBase, self).__init__( + common_objs, + deps, + db_name, + table_name, + ) + + self.peers = self.load_peers() + self.peer_group_mgr = BGPPeerGroupMgr(self.common_objs, base_template) + return + + def set_handler(self, key, data): + """ + It runs on 'SET' command + :param key: key of the changed table + :param data: the data associated with the change + """ + vrf, nbr = self.split_key(key) + peer_key = (vrf, nbr) + if peer_key not in self.peers: + return self.add_peer(vrf, nbr, data) + else: + return self.update_peer(vrf, nbr, data) + + def add_peer(self, vrf, nbr, data): + """ + Add a peer into FRR. This is used if the peer is not existed in FRR yet + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + print_data = vrf, nbr, data + bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + # + lo0_ipv4 = self.get_lo0_ipv4() + if lo0_ipv4 is None: + log_warn("Loopback0 ipv4 address is not presented yet") + return False + # + if "local_addr" not in data: + log_warn("Peer %s. Missing attribute 'local_addr'" % nbr) + else: + # The bgp session that belongs to a vnet cannot be advertised as the default BGP session. + # So we need to check whether this bgp session belongs to a vnet. + data["local_addr"] = str(netaddr.IPNetwork(str(data["local_addr"])).ip) + interface = self.get_local_interface(data["local_addr"]) + if not interface: + print_data = nbr, data["local_addr"] + log_debug("Peer '%s' with local address '%s' wait for the corresponding interface to be set" % print_data) + return False + vnet = self.get_vnet(interface) + if vnet: + # Ignore the bgp session that is in a vnet + log_info("Ignore the BGP peer '%s' as the interface '%s' is in vnet '%s'" % (nbr, interface, vnet)) + return True + + kwargs = { + 'CONFIG_DB__DEVICE_METADATA': self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME), + 'constants': self.constants, + 'bgp_asn': bgp_asn, + 'vrf': vrf, + 'neighbor_addr': nbr, + 'bgp_session': data, + 'loopback0_ipv4': lo0_ipv4, + } + if self.check_neig_meta: + neigmeta = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME) + if 'name' in data and data["name"] not in neigmeta: + log_info("DEVICE_NEIGHBOR_METADATA is not ready for neighbor '%s' - '%s'" % (nbr, data['name'])) + return False + kwargs['CONFIG_DB__DEVICE_NEIGHBOR_METADATA'] = neigmeta + + tag = data['name'] if 'name' in data else nbr + self.peer_group_mgr.update(tag, **kwargs) + + try: + cmd = self.templates["add"].render(**kwargs) + except jinja2.TemplateError as e: + msg = "Peer '(%s|%s)'. Error in rendering the template for 'SET' command '%s'" % print_data + log_err("%s: %s" % (msg, str(e))) + return True + if cmd is not None: + ret_code = self.apply_op(cmd, vrf) + key = (vrf, nbr) + if ret_code: + self.peers.add(key) + log_info("Peer '(%s|%s)' added with attributes '%s'" % print_data) + else: + log_err("Peer '(%s|%s)' wasn't added." % (vrf, nbr)) + + return True + + def update_peer(self, vrf, nbr, data): + """ + Update a peer. This is used when the peer is already in the FRR + Update support only "admin_status" for now + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + if "admin_status" in data: + self.change_admin_status(vrf, nbr, data) + else: + log_err("Peer '(%s|%s)': Can't update the peer. Only 'admin_status' attribute is supported" % (vrf, nbr)) + + return True + + def change_admin_status(self, vrf, nbr, data): + """ + Change admin status of a peer + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + if data['admin_status'] == 'up': + self.apply_admin_status(vrf, nbr, "no shutdown", "up") + elif data['admin_status'] == 'down': + self.apply_admin_status(vrf, nbr, "shutdown", "down") + else: + print_data = vrf, nbr, data['admin_status'] + log_err("Peer '%s|%s': Can't update the peer. It has wrong attribute value attr['admin_status'] = '%s'" % print_data) + + def apply_admin_status(self, vrf, nbr, template_name, admin_state): + """ + Render admin state template and apply the command to the FRR + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param template_name: name of the template to render + :param admin_state: desired admin state + :return: True if this adding was successful, False otherwise + """ + print_data = vrf, nbr, admin_state + ret_code = self.apply_op(self.templates[template_name].render(neighbor_addr=nbr), vrf) + if ret_code: + log_info("Peer '%s|%s' admin state is set to '%s'" % print_data) + else: + log_err("Can't set peer '%s|%s' admin state to '%s'." % print_data) + + def del_handler(self, key): + """ + 'DEL' handler for the BGP PEER tables + :param key: key of the neighbor + """ + vrf, nbr = self.split_key(key) + peer_key = (vrf, nbr) + if peer_key not in self.peers: + log_warn("Peer '(%s|%s)' has not been found" % (vrf, nbr)) + return + cmd = self.templates["delete"].render(neighbor_addr=nbr) + ret_code = self.apply_op(cmd, vrf) + if ret_code: + log_info("Peer '(%s|%s)' has been removed" % (vrf, nbr)) + self.peers.remove(peer_key) + else: + log_err("Peer '(%s|%s)' hasn't been removed" % (vrf, nbr)) + + def apply_op(self, cmd, vrf): + """ + Push commands cmd into FRR + :param cmd: commands in raw format + :param vrf: vrf where the commands should be applied + :return: True if no errors, False if there are errors + """ + bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + if vrf == 'default': + cmd = ('router bgp %s\n' % bgp_asn) + cmd + else: + cmd = ('router bgp %s vrf %s\n' % (bgp_asn, vrf)) + cmd + return self.cfg_mgr.push(cmd) + + def get_lo0_ipv4(self): + """ + Extract Loopback0 ipv4 address from the Directory + :return: ipv4 address for Loopback0, None if nothing found + """ + loopback0_ipv4 = None + for loopback in self.directory.get_slot("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME).iterkeys(): + if loopback.startswith("Loopback0|"): + loopback0_prefix_str = loopback.replace("Loopback0|", "") + loopback0_ip_str = loopback0_prefix_str[:loopback0_prefix_str.find('/')] + if TemplateFabric.is_ipv4(loopback0_ip_str): + loopback0_ipv4 = loopback0_ip_str + break + + return loopback0_ipv4 + + def get_local_interface(self, local_addr): + """ + Get interface according to the local address from the directory + :param: directory: Directory object that stored metadata of interfaces + :param: local_addr: Local address of the interface + :return: Return the metadata of the interface with the local address + If the interface has not been set, return None + """ + local_addresses = self.directory.get_slot("LOCAL", "local_addresses") + # Check if the local address of this bgp session has been set + if local_addr not in local_addresses: + return None + local_address = local_addresses[local_addr] + interfaces = self.directory.get_slot("LOCAL", "interfaces") + # Check if the information for the interface of this local address has been set + if local_address.has_key("interface") and local_address["interface"] in interfaces: + return interfaces[local_address["interface"]] + else: + return None + + @staticmethod + def get_vnet(interface): + """ + Get the VNet name of the interface + :param: interface: The metadata of the interface + :return: Return the vnet name of the interface if this interface belongs to a vnet, + Otherwise return None + """ + if interface.has_key("vnet_name") and interface["vnet_name"]: + return interface["vnet_name"] + else: + return None + + @staticmethod + def split_key(key): + """ + Split key into ip address and vrf name. If there is no vrf, "default" would be return for vrf + :param key: key to split + :return: vrf name extracted from the key, peer ip address extracted from the key + """ + if '|' not in key: + return 'default', key + else: + return tuple(key.split('|', 1)) + + @staticmethod + def load_peers(): + """ + Load peers from FRR. + :return: set of peers, which are already installed in FRR + """ + command = ["vtysh", "-c", "show bgp vrfs json"] + ret_code, out, err = run_command(command) + if ret_code == 0: + js_vrf = json.loads(out) + vrfs = js_vrf['vrfs'].keys() + else: + log_crit("Can't read bgp vrfs: %s" % err) + raise Exception("Can't read bgp vrfs: %s" % err) + peers = set() + for vrf in vrfs: + command = ["vtysh", "-c", 'show bgp vrf %s neighbors json' % str(vrf)] + ret_code, out, err = run_command(command) + if ret_code == 0: + js_bgp = json.loads(out) + for nbr in js_bgp.keys(): + peers.add((vrf, nbr)) + else: + log_crit("Can't read vrf '%s' neighbors: %s" % (vrf, str(err))) + raise Exception("Can't read vrf '%s' neighbors: %s" % (vrf, str(err))) + + return peers \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_db.py b/src/sonic-bgpcfgd/bgpcfgd/managers_db.py new file mode 100644 index 000000000000..37d2eee99a8f --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_db.py @@ -0,0 +1,28 @@ +from .manager import Manager + + +class BGPDataBaseMgr(Manager): + """ This class updates the Directory object when db table is updated """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(BGPDataBaseMgr, self).__init__( + common_objs, + [], + db, + table, + ) + + def set_handler(self, key, data): + """ Implementation of 'SET' command for this class """ + self.directory.put(self.db_name, self.table_name, key, data) + + return True + + def del_handler(self, key): + """ Implementation of 'DEL' command for this class """ + self.directory.remove(self.db_name, self.table_name, key) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_intf.py b/src/sonic-bgpcfgd/bgpcfgd/managers_intf.py new file mode 100644 index 000000000000..ef4958ad9207 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_intf.py @@ -0,0 +1,56 @@ +import netaddr + +from .log import log_warn +from .manager import Manager + + +class InterfaceMgr(Manager): + """ This class updates the Directory object when interface-related table is updated """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(InterfaceMgr, self).__init__( + common_objs, + [], + db, + table, + ) + + def set_handler(self, key, data): + """ Implementation of 'SET' command. + Similar to BGPDataBaseMgr but enriches data object with additional data """ + # Interface table can have two keys, + # one with ip prefix and one without ip prefix + if '|' in key: + interface_name, network_str = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network_str)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + log_warn("Subnet '%s' format is wrong for interface '%s'" % (network_str, data["interface"])) + return True + data["interface"] = interface_name + data["prefixlen"] = str(network.prefixlen) + ip = str(network.ip) + self.directory.put("LOCAL", "local_addresses", ip, data) + self.directory.put(self.db_name, self.table_name, key, data) + self.directory.put("LOCAL", "interfaces", key, data) + return True + + def del_handler(self, key): + """ Implementation of 'DEL' command + Also removes data object enrichment """ + if '|' in key: + interface, network = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + log_warn("Subnet '%s' format is wrong for interface '%s'" % (network, interface)) + return + ip = str(network.ip) + self.directory.remove("LOCAL", "local_addresses", ip) + self.directory.remove(self.db_name, self.table_name, key) + self.directory.remove("LOCAL", "interfaces", key) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py b/src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py new file mode 100644 index 000000000000..19b589cf0446 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py @@ -0,0 +1,69 @@ +import jinja2 + +from .log import log_err, log_warn, log_info +from .manager import Manager +from .template import TemplateFabric + + +class ZebraSetSrc(Manager): + """ This class initialize "set src" settings for zebra """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(ZebraSetSrc, self).__init__( + common_objs, + [], + db, + table, + ) + tf = common_objs['tf'] + self.zebra_set_src_template = tf.from_file("zebra/zebra.set_src.conf.j2") + self.lo_ipv4 = None + self.lo_ipv6 = None + + def set_handler(self, key, data): + """ Implementation of 'SET' command for this class """ + self.directory.put(self.db_name, self.table_name, key, data) + # + if key.startswith("Loopback0|") and "state" in data and data["state"] == "ok": + ip_addr_w_mask = key.replace("Loopback0|", "") + slash_pos = ip_addr_w_mask.rfind("/") + if slash_pos == -1: + log_err("Wrong Loopback0 ip prefix: '%s'" % ip_addr_w_mask) + return True + ip_addr = ip_addr_w_mask[:slash_pos] + try: + if TemplateFabric.is_ipv4(ip_addr): + if self.lo_ipv4 is None: + self.lo_ipv4 = ip_addr + txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC", lo_ip=ip_addr, ip_proto="") + else: + log_warn("Update command is not supported for set src templates. current ip='%s'. new ip='%s'" % (self.lo_ipv4, ip_addr)) + return True + elif TemplateFabric.is_ipv6(ip_addr): + if self.lo_ipv6 is None: + self.lo_ipv6 = ip_addr + txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC6", lo_ip=ip_addr, ip_proto="v6") + else: + log_warn("Update command is not supported for set src templates. current ip='%s'. new ip='%s'" % (self.lo_ipv6, ip_addr)) + return True + else: + log_err("Got ambiguous ip address '%s'" % ip_addr) + return True + except jinja2.TemplateError as e: + log_err("Error while rendering 'set src' template: %s" % str(e)) + return True + if self.cfg_mgr.push(txt): + log_info("The 'set src' configuration with Loopback0 ip '%s' was pushed" % ip_addr) + else: + log_err("The 'set src' configuration with Loopback0 ip '%s' wasn't pushed" % ip_addr) + return True + + def del_handler(self, key): + """ Implementation of 'DEL' command for this class """ + self.directory.remove(self.db_name, self.table_name, key) + log_warn("Delete command is not supported for 'zebra set src' templates") \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/runner.py b/src/sonic-bgpcfgd/bgpcfgd/runner.py new file mode 100644 index 000000000000..07799af5e7e4 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/runner.py @@ -0,0 +1,65 @@ +from collections import defaultdict +from swsscommon import swsscommon + +from .log import log_debug + + +g_run = True + + +def signal_handler(_, __): # signal_handler(signum, frame) + """ signal handler """ + global g_run + g_run = False + + +class Runner(object): + """ Implements main io-loop of the application + It will run event handlers inside of Manager objects + when corresponding db/table is updated + """ + SELECT_TIMEOUT = 1000 + + def __init__(self): + """ Constructor """ + self.db_connectors = {} + self.selector = swsscommon.Select() + self.callbacks = defaultdict(lambda: defaultdict(list)) # db -> table -> handlers[] + self.subscribers = set() + + def add_manager(self, manager): + """ + Add a manager to the Runner. + As soon as new events will be receiving by Runner, + handlers of corresponding objects will be executed + :param manager: an object implementing Manager + """ + db_name = manager.get_database() + table_name = manager.get_table_name() + db = swsscommon.SonicDBConfig.getDbId(db_name) + if db not in self.db_connectors: + self.db_connectors[db] = swsscommon.DBConnector(db_name, 0) + + if table_name not in self.callbacks[db]: + conn = self.db_connectors[db] + subscriber = swsscommon.SubscriberStateTable(conn, table_name) + self.subscribers.add(subscriber) + self.selector.addSelectable(subscriber) + self.callbacks[db][table_name].append(manager.handler) + + def run(self): + """ Main loop """ + while g_run: + state, _ = self.selector.select(Runner.SELECT_TIMEOUT) + if state == self.selector.TIMEOUT: + continue + elif state == self.selector.ERROR: + raise Exception("Received error from select") + + for subscriber in self.subscribers: + key, op, fvs = subscriber.pop() + if not key: + continue + log_debug("Received message : '%s'" % str((key, op, fvs))) + for callback in self.callbacks[subscriber.getDbConnector().getDbId()][subscriber.getTableName()]: + callback(key, op, dict(fvs)) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/template.py b/src/sonic-bgpcfgd/bgpcfgd/template.py similarity index 100% rename from src/sonic-bgpcfgd/app/template.py rename to src/sonic-bgpcfgd/bgpcfgd/template.py diff --git a/src/sonic-bgpcfgd/bgpcfgd/utils.py b/src/sonic-bgpcfgd/bgpcfgd/utils.py new file mode 100644 index 000000000000..63d53512d04c --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/utils.py @@ -0,0 +1,55 @@ +import datetime +import subprocess +import time + +import yaml + +from .log import log_debug, log_err, log_info, log_warn, log_crit + + +def run_command(command, shell=False, hide_errors=False): + """ + Run a linux command. The command is defined as a list. See subprocess.Popen documentation on format + :param command: command to execute. Type: List of strings + :param shell: execute the command through shell when True. Type: Boolean + :param hide_errors: don't report errors to syslog when True. Type: Boolean + :return: Tuple: integer exit code from the command, stdout as a string, stderr as a string + """ + log_debug("execute command '%s'." % str(command)) + p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + if p.returncode != 0: + if not hide_errors: + print_tuple = p.returncode, str(command), stdout, stderr + log_err("command execution returned %d. Command: '%s', stdout: '%s', stderr: '%s'" % print_tuple) + + return p.returncode, stdout, stderr + + +def wait_for_daemons(daemons, seconds): + """ + Wait until FRR daemons are ready for requests + :param daemons: list of FRR daemons to wait + :param seconds: number of seconds to wait, until raise an error + """ + stop_time = datetime.datetime.now() + datetime.timedelta(seconds=seconds) + log_info("Start waiting for FRR daemons: %s" % str(datetime.datetime.now())) + while datetime.datetime.now() < stop_time: + ret_code, out, err = run_command(["vtysh", "-c", "show daemons"], hide_errors=True) + if ret_code == 0 and all(daemon in out for daemon in daemons): + log_info("All required daemons have connected to vtysh: %s" % str(datetime.datetime.now())) + return + else: + log_warn("Can't read daemon status from FRR: %s" % str(err)) + time.sleep(0.1) # sleep 100 ms + raise RuntimeError("FRR daemons hasn't been started in %d seconds" % seconds) + + +def read_constants(): + """ Read file with constants values from /etc/sonic/constants.yml """ + with open('/etc/sonic/constants.yml') as fp: + content = yaml.load(fp) # FIXME: , Loader=yaml.FullLoader) + if "constants" not in content: + log_crit("/etc/sonic/constants.yml doesn't have 'constants' key") + raise Exception("/etc/sonic/constants.yml doesn't have 'constants' key") + return content["constants"] \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/vars.py b/src/sonic-bgpcfgd/bgpcfgd/vars.py similarity index 100% rename from src/sonic-bgpcfgd/app/vars.py rename to src/sonic-bgpcfgd/bgpcfgd/vars.py diff --git a/src/sonic-bgpcfgd/pytest.ini b/src/sonic-bgpcfgd/pytest.ini index 639ceb636af9..a49b58e45f0f 100644 --- a/src/sonic-bgpcfgd/pytest.ini +++ b/src/sonic-bgpcfgd/pytest.ini @@ -1,2 +1,2 @@ [pytest] -addopts = --cov=app --cov-report term +addopts = --cov=bgpcfgd --cov-report term diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index fc0839dff7fc..1e23802d98c1 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -9,13 +9,13 @@ author_email='pavelsh@microsoft.com', url='https://github.com/Azure/sonic-buildimage', packages=setuptools.find_packages(), - scripts=['bgpcfgd'], entry_points={ 'console_scripts': [ + 'bgpcfgd = bgpcfgd.main:main', 'bgpmon = bgpmon.bgpmon:main', ] }, install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], setup_requires=['pytest-runner'], - test_requires=['pytest', 'pytest-cov'], + tests_require=['pytest', 'pytest-cov'], ) diff --git a/src/sonic-bgpcfgd/tests/test_allow_list.py b/src/sonic-bgpcfgd/tests/test_allow_list.py index f3cf2f534aaa..c906894eef47 100644 --- a/src/sonic-bgpcfgd/tests/test_allow_list.py +++ b/src/sonic-bgpcfgd/tests/test_allow_list.py @@ -1,8 +1,9 @@ -from app.directory import Directory -from app.template import TemplateFabric -import app +from bgpcfgd.directory import Directory +from bgpcfgd.template import TemplateFabric +import bgpcfgd from mock import MagicMock, patch + swsscommon_module_mock = MagicMock() global_constants = { @@ -22,14 +23,14 @@ @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def set_del_test(op, args, currect_config, expected_config): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr set_del_test.push_list_called = False def push_list(args): set_del_test.push_list_called = True assert args == expected_config return True # - app.allow_list.run_command = lambda cmd: (0, "", "") + bgpcfgd.managers_allow_list.run_command = lambda cmd: (0, "", "") # cfg_mgr = MagicMock() cfg_mgr.update.return_value = None @@ -188,7 +189,7 @@ def test_set_handler_with_community_data_is_already_presented(): @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def test_set_handler_no_community_data_is_already_presented(): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr cfg_mgr = MagicMock() cfg_mgr.update.return_value = None cfg_mgr.get_text.return_value = [ @@ -311,7 +312,7 @@ def test_set_handler_no_community_update_prefixes_add(): @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def test___set_handler_validate(): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), @@ -338,7 +339,7 @@ def test___set_handler_validate(): @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def test___find_peer_group_by_deployment_id(): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr cfg_mgr = MagicMock() cfg_mgr.update.return_value = None cfg_mgr.get_text.return_value = [ @@ -432,7 +433,7 @@ def test___find_peer_group_by_deployment_id(): @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def test___restart_peers_found_deployment_id(): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr test___restart_peers_found_deployment_id.run_command_counter = 0 def run_command(cmd): output = [ @@ -454,13 +455,13 @@ def run_command(cmd): mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') mocked.return_value = ["BGP_TEST_PEER_GROUP_1", "BGP_TEST_PEER_GROUP_2"] mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked - app.allow_list.run_command = run_command + bgpcfgd.managers_allow_list.run_command = run_command rc = mgr._BGPAllowListMgr__restart_peers(5) assert rc @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def test___restart_peers_not_found_deployment_id(): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr def run_command(cmd): assert cmd == ['vtysh', '-c', 'clear bgp * soft in'] return 0, "", "" @@ -475,7 +476,7 @@ def run_command(cmd): mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') mocked.return_value = [] mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked - app.allow_list.run_command = run_command + bgpcfgd.managers_allow_list.run_command = run_command rc = mgr._BGPAllowListMgr__restart_peers(5) assert rc diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py index 686b1ade65e1..92b1e5dd8c2d 100644 --- a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -1,7 +1,7 @@ import os import re -from app.template import TemplateFabric +from bgpcfgd.template import TemplateFabric from .util import load_constants TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') diff --git a/src/sonic-bgpcfgd/tests/test_pfx_filter.py b/src/sonic-bgpcfgd/tests/test_pfx_filter.py index 3eebd3951f7b..684a95bf75f8 100644 --- a/src/sonic-bgpcfgd/tests/test_pfx_filter.py +++ b/src/sonic-bgpcfgd/tests/test_pfx_filter.py @@ -1,4 +1,4 @@ -from app.template import TemplateFabric +from bgpcfgd.template import TemplateFabric from collections import OrderedDict import pytest diff --git a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py index 065ecb815ccb..d10ec65d21dc 100644 --- a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py +++ b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py @@ -2,7 +2,7 @@ import subprocess -from app.config import ConfigMgr +from bgpcfgd.config import ConfigMgr from .test_templates import compress_comments, write_result diff --git a/src/sonic-bgpcfgd/tests/test_templates.py b/src/sonic-bgpcfgd/tests/test_templates.py index bd0bf9dbb484..f5f5f2155253 100644 --- a/src/sonic-bgpcfgd/tests/test_templates.py +++ b/src/sonic-bgpcfgd/tests/test_templates.py @@ -2,8 +2,8 @@ import json -from app.template import TemplateFabric -from app.config import ConfigMgr +from bgpcfgd.template import TemplateFabric +from bgpcfgd.config import ConfigMgr from .util import load_constants TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') From d03de95e811c9cc3917b0d0a2a6d4e66213815ac Mon Sep 17 00:00:00 2001 From: jon-nokia <63672455+jon-nokia@users.noreply.github.com> Date: Tue, 6 Oct 2020 18:47:50 -0400 Subject: [PATCH 1216/1427] [build]: fix pip installation for sonic utilities whl package (#5498) The problem was proxy was missing on "pip install". This is to fix the build behind the proxy. Signed-off-by: Jon Goldberg --- files/build_templates/sonic_debian_extension.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0878c2801433..4dd49d8e3df8 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -190,7 +190,7 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python-click*_all.deb || \ # Install SONiC Utilities Python 2 package SONIC_UTILITIES_PY2_WHEEL_NAME=$(basename {{sonic_utilities_py2_wheel_path}}) sudo cp {{sonic_utilities_py2_wheel_path}} $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY2_WHEEL_NAME -sudo LANG=C chroot $FILESYSTEM_ROOT pip install $SONIC_UTILITIES_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SONIC_UTILITIES_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY2_WHEEL_NAME # Install sonic-utilities data files (and any dependencies via 'apt-get -y install -f') From 3da996bbf8a40a07ffe27fd6edc803ad35ee4d32 Mon Sep 17 00:00:00 2001 From: zzhiyuan Date: Tue, 6 Oct 2020 18:35:15 -0700 Subject: [PATCH 1217/1427] [arista]: Add disable_pcie_firmware_check soc property (#5543) This is to fix pcie firmware check assert in Broadcom SDK once the SAI changes merges. This will be in the future but adding the soc property in the broadcom config now. Co-authored-by: Zhi Yuan Carl Zhao --- .../Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm | 1 + .../Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm | 1 + src/sonic-device-data/tests/permitted_list | 1 + 3 files changed, 3 insertions(+) diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm index f4450ebac53f..af08293cf3a5 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm @@ -5,6 +5,7 @@ bcm_num_cos.0=8 bcm_stat_flags=1 bcm_stat_jumbo.0=9236 cdma_timeout_usec.0=15000000 +disable_pcie_firmware_check.0=1 dma_desc_timeout_usec.0=15000000 dpr_clock_frequency.0=1000 higig2_hdr_mode.0=1 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm index cdbc4f4430b4..08712b5c8e4b 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm @@ -5,6 +5,7 @@ bcm_num_cos.0=8 bcm_stat_flags=1 bcm_stat_jumbo.0=9236 cdma_timeout_usec.0=15000000 +disable_pcie_firmware_check.0=1 dma_desc_timeout_usec.0=15000000 dpr_clock_frequency.0=1000 higig2_hdr_mode.0=1 diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index 9585c19301d4..8feb791875ef 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -15,6 +15,7 @@ cdma_timeout_usec core_clock_frequency ctr_evict_enable device_clock_frequency +disable_pcie_firmware_check dma_desc_timeout_usec dport_map_direct dport_map_enable From 895f4e0bf727bf25bb15d2612f65d68ce3744f5c Mon Sep 17 00:00:00 2001 From: Petro Bratash <68950226+bratashX@users.noreply.github.com> Date: Wed, 7 Oct 2020 21:32:38 +0300 Subject: [PATCH 1218/1427] [sonic-utilities] Submodule update (#5558) - Fix show queue watermark command fail Azure/sonic-utilities@6e58dff Signed-off-by: Petro Bratash --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 31eb13b7f8db..6e58dff4c9b5 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 31eb13b7f8db910fa5fd8f11e0d53d89aaf93f50 +Subproject commit 6e58dff4c9b590657e1f5e629a53ce4590d38382 From 744612d269dcb9161f84c0691d24bb6cd87fdbbb Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Thu, 8 Oct 2020 09:05:37 -0700 Subject: [PATCH 1219/1427] [ECMP][Multi-ASIC] Have different ECMP seed value on each ASIC (#5357) * Calculate ECMP hash seed based on ASIC ID on multi ASIC platform. Each ASIC will have a unique ECMP hash seed value. --- dockers/docker-orchagent/switch.json.j2 | 11 +++- src/sonic-config-engine/sonic-cfggen | 14 +++-- .../tests/sample_output/t0-switch-masic1.json | 10 +++ .../tests/sample_output/t0-switch-masic3.json | 10 +++ .../tests/sample_output/t0-switch.json | 10 +++ .../tests/sample_output/t1-switch.json | 10 +++ src/sonic-config-engine/tests/test_j2files.py | 63 ++++++++++++++++++- 7 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json create mode 100644 src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json create mode 100644 src/sonic-config-engine/tests/sample_output/t0-switch.json create mode 100644 src/sonic-config-engine/tests/sample_output/t1-switch.json diff --git a/dockers/docker-orchagent/switch.json.j2 b/dockers/docker-orchagent/switch.json.j2 index f8beffbc9ad7..c359dd805219 100644 --- a/dockers/docker-orchagent/switch.json.j2 +++ b/dockers/docker-orchagent/switch.json.j2 @@ -1,20 +1,25 @@ {# the range of hash_seed is 0-15 #} {# set default hash seed to 0 #} {% set hash_seed = 0 %} +{% set hash_seed_offset = 0 %} {% if DEVICE_METADATA.localhost.type %} {% if DEVICE_METADATA.localhost.type == "ToRRouter" %} {% set hash_seed = 0 %} {% elif DEVICE_METADATA.localhost.type == "LeafRouter" %} {% set hash_seed = 10 %} {% elif DEVICE_METADATA.localhost.type == "SpineRouter" %} -{% set hash_seed = 15 %} +{% set hash_seed = 25 %} {% endif %} {% endif %} +{% if DEVICE_METADATA.localhost.namespace_id %} +{% set hash_seed_offset = DEVICE_METADATA.localhost.namespace_id | int %} +{% endif %} +{% set hash_seed_value = hash_seed_offset + hash_seed %} [ { "SWITCH_TABLE:switch": { - "ecmp_hash_seed": "{{ hash_seed }}", - "lag_hash_seed": "{{ hash_seed }}", + "ecmp_hash_seed": "{{ hash_seed_value }}", + "lag_hash_seed": "{{ hash_seed_value }}", "fdb_aging_time": "600" }, "OP": "SET" diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index de99d2523027..af638c2c2826 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -31,7 +31,7 @@ import contextlib import jinja2 import json import netaddr -import os.path +import os import sys import yaml @@ -61,7 +61,7 @@ def sort_by_port_index(value): if not value: return if isinstance(value, list): - # In multi-ASIC platforms backend ethernet ports are identified as + # In multi-ASIC platforms backend ethernet ports are identified as # 'Ethernet-BPxy'. Add 1024 to sort backend ports to the end. value.sort( key = lambda k: int(k[8:]) if "BP" not in k else int(k[11:]) + 1024 @@ -296,8 +296,14 @@ def main(): asic_id = None if asic_name is not None: asic_id = get_asic_id_from_name(asic_name) - - + # get the namespace ID + namespace_id = os.getenv("NAMESPACE_ID") + if namespace_id: + deep_update(data, { + 'DEVICE_METADATA': { + 'localhost': {'namespace_id': namespace_id} + } + }) # Load the database config for the namespace from global database json if args.namespace is not None: SonicDBConfig.load_sonic_global_db_config(namespace=args.namespace) diff --git a/src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json b/src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json new file mode 100644 index 000000000000..34fd946da361 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "11", + "lag_hash_seed": "11", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json b/src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json new file mode 100644 index 000000000000..d9f929679cbc --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "13", + "lag_hash_seed": "13", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/t0-switch.json b/src/sonic-config-engine/tests/sample_output/t0-switch.json new file mode 100644 index 000000000000..414e53b8a356 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t0-switch.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "0", + "lag_hash_seed": "0", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/t1-switch.json b/src/sonic-config-engine/tests/sample_output/t1-switch.json new file mode 100644 index 000000000000..fdae474251f0 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t1-switch.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "10", + "lag_hash_seed": "10", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index ad06f61b84c5..2dec13425e19 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -171,6 +171,68 @@ def test_ipinip_multi_asic(self): sample_output_file = os.path.join(self.test_dir, 'multi_npu_data', utils.PYvX_DIR, 'ipinip.json') assert filecmp.cmp(sample_output_file, self.output_file) + def test_swss_switch_render_template(self): + switch_template = os.path.join( + self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', + 'switch.json.j2' + ) + constants_yml = os.path.join( + self.test_dir, '..', '..', '..', 'files', 'image_config', + 'constants', 'constants.yml' + ) + test_list = { + "t1": { + "graph": self.t1_mlnx_minigraph, + "output": "t1-switch.json" + }, + "t0": { + "graph": self.t0_minigraph, + "output": "t0-switch.json" + }, + } + for _, v in test_list.items(): + argument = " -m {} -y {} -t {} > {}".format( + v["graph"], constants_yml, switch_template, self.output_file + ) + sample_output_file = os.path.join( + self.test_dir, 'sample_output', v["output"] + ) + self.run_script(argument) + assert filecmp.cmp(sample_output_file, self.output_file) + + def test_swss_switch_render_template_multi_asic(self): + # verify the ECMP hash seed changes per namespace + switch_template = os.path.join( + self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', + 'switch.json.j2' + ) + constants_yml = os.path.join( + self.test_dir, '..', '..', '..', 'files', 'image_config', + 'constants', 'constants.yml' + ) + test_list = { + "0": { + "namespace_id": "1", + "output": "t0-switch-masic1.json" + }, + "1": { + "namespace_id": "3", + "output": "t0-switch-masic3.json" + }, + } + for _, v in test_list.items(): + os.environ["NAMESPACE_ID"] = v["namespace_id"] + argument = " -m {} -y {} -t {} > {}".format( + self.t1_mlnx_minigraph, constants_yml, switch_template, + self.output_file + ) + sample_output_file = os.path.join( + self.test_dir, 'sample_output', v["output"] + ) + self.run_script(argument) + assert filecmp.cmp(sample_output_file, self.output_file) + os.environ["NAMESPACE_ID"] = "" + def test_ndppd_conf(self): conf_template = os.path.join(self.test_dir, "ndppd.conf.j2") vlan_interfaces_json = os.path.join(self.test_dir, "data", "ndppd", "vlan_interfaces.json") @@ -180,7 +242,6 @@ def test_ndppd_conf(self): self.run_script(argument) assert filecmp.cmp(expected, self.output_file), self.run_diff(expected, self.output_file) - def tearDown(self): try: os.remove(self.output_file) From 6edb5551cb805f041b387f8317b5a958fc617a99 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Thu, 8 Oct 2020 22:42:54 +0530 Subject: [PATCH 1220/1427] [Dell S6100] Properly release memory upon ICH driver deinit (#5561) During platform deinitialization, dell_ich is not removed properly and when we do initialize s6100 platform, ICH driver sysfs attributes are not attached. Because of this, get_transceiver_change_event returns error and this leads xcvrd to crash. --- platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c index cce36e9056fa..eb164e46fac5 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c @@ -926,7 +926,7 @@ static int dell_ich_remove(struct platform_device *pdev) // Unmap and release PMC regions if(ich_data->pmc_base) iounmap(ich_data->pmc_base); - if(ich_data->pmc_alloc) release_region(pmc_res.start, PMC_REG_LEN); + if(ich_data->pmc_alloc) release_mem_region(pmc_res.start, PMC_REG_LEN); ret = acpi_remove_sci_handler(dell_ich_sci_handler); if(ret) { From 01fceb6f799fac326552af810df1e4777c40e2cf Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Thu, 8 Oct 2020 11:31:09 -0700 Subject: [PATCH 1221/1427] Optimized caclmgrd Notification handling. Previously (#5560) any event happening on ACL Rule Table (eg DATAACL rules programmed) caused control plane default action to be triggered. Now Control Plance ACTION will be trigger only a) ACL Rule beloging to Control ACL Table Signed-off-by: Abhishek Dosi --- files/image_config/caclmgrd/caclmgrd | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index b2fa5efaea61..a199f4753ecb 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -533,9 +533,13 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): config_db_subscriber_table_map[namespace] = [] config_db_subscriber_table_map[namespace].append(subscribe_acl_table) config_db_subscriber_table_map[namespace].append(subscribe_acl_rule_table) - + + # Get the ACL rule table seprator + acl_rule_table_seprator = subscribe_acl_rule_table.getTableNameSeparator() + # Loop on select to see if any event happen on config db of any namespace while True: + ctrl_plane_acl_notification = False (state, selectableObj) = sel.select(SELECT_TIMEOUT_MS) # Continue if select is timeout or selectable object is not return if state != swsscommon.Select.OBJECT: @@ -546,9 +550,24 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): namespace = redisSelectObj.getDbConnector().getNamespace() # Pop data of both Subscriber Table object of namespace that got config db acl table event for table in config_db_subscriber_table_map[namespace]: - table.pop() - # Update the Control Plane ACL of the namespace that got config db acl table event - self.update_control_plane_acls(namespace) + (key, op, fvp) = table.pop() + # Pop of table that does not have data + if key == '': + continue + # ACL Table notification. We will take Control Plane ACTION for any ACL Table Event + # This can be optimize further but we should not have many acl table set/del events in normal + # scenario + elif acl_rule_table_seprator not in key: + ctrl_plane_acl_notification = True + # Check ACL Rule notification and make sure Rule point to ACL Table which is Controlplane + else: + acl_table = key.split(acl_rule_table_seprator)[0] + if self.config_db_map[namespace].get_table(self.ACL_TABLE)[acl_table]["type"] == self.ACL_TABLE_TYPE_CTRLPLANE: + ctrl_plane_acl_notification = True + + # Update the Control Plane ACL of the namespace that got config db acl table/rule event + if ctrl_plane_acl_notification: + self.update_control_plane_acls(namespace) # ============================= Functions ============================= From 9a1f68ba12d0fb5aa5dc028024fb7c7070f03c78 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Thu, 8 Oct 2020 23:23:51 +0300 Subject: [PATCH 1222/1427] [barefoot] Switch to Y profiles for Newport board (#5187) Signed-off-by: Volodymyr Boyko --- device/barefoot/x86_64-accton_as9516bf_32d-r0 | 1 - .../x86_64-accton_as9516bf_32d-r0/syncd.conf | 23 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) delete mode 120000 device/barefoot/x86_64-accton_as9516bf_32d-r0 create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/syncd.conf diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0 b/device/barefoot/x86_64-accton_as9516bf_32d-r0 deleted file mode 120000 index 93f47d51b742..000000000000 --- a/device/barefoot/x86_64-accton_as9516bf_32d-r0 +++ /dev/null @@ -1 +0,0 @@ -x86_64-accton_as9516_32d-r0 \ No newline at end of file diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/syncd.conf b/device/barefoot/x86_64-accton_as9516bf_32d-r0/syncd.conf new file mode 100644 index 000000000000..6035b97b9834 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/syncd.conf @@ -0,0 +1,23 @@ +#!/bin/bash + + +y_profile_set() { + P4_PROFILE=$(sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["p4_profile"]') + if [[ -n "$P4_PROFILE" || ( ! -L /opt/bfn/install && -e /opt/bfn/install ) ]]; then + return + fi + + Y_PROFILE=$(ls -d /opt/bfn/install_y*_profile 2> /dev/null | head -1) + if [[ -z $Y_PROFILE ]]; then + echo "No P4 profile found for Newport" + return + fi + + ln -srfn $Y_PROFILE /opt/bfn/install +} + +( + unset PYTHONPATH + unset PYTHONHOME + y_profile_set +) From 42d9a44e05def705c2c391e2cb0b56d69983953a Mon Sep 17 00:00:00 2001 From: anish-n <44376847+anish-n@users.noreply.github.com> Date: Thu, 8 Oct 2020 15:45:21 -0700 Subject: [PATCH 1223/1427] Minigraph resource type changes (#5198) * Parse sub_role from minigraph into DEVICE_METADATA * Change minigraph sub_role to resource_type --- src/sonic-config-engine/minigraph.py | 12 ++++++++++-- .../tests/simple-sample-graph-metadata.xml | 5 +++++ src/sonic-config-engine/tests/test_cfggen.py | 5 +++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 7ab7c41cd2b1..62cb77600e47 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -547,6 +547,7 @@ def parse_meta(meta, hname): deployment_id = None region = None cloudtype = None + resource_type = None device_metas = meta.find(str(QName(ns, "Devices"))) for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower(): @@ -573,7 +574,9 @@ def parse_meta(meta, hname): region = value elif name == "CloudType": cloudtype = value - return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype + elif name == "ResourceType": + resource_type = value + return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type def parse_linkmeta(meta, hname): @@ -820,6 +823,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw neighbors = None devices = None sub_role = None + resource_type = None docker_routing_config_mode = "separated" port_speeds_default = {} port_speed_png = {} @@ -871,7 +875,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): - (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype) = parse_meta(child, hostname) + (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "LinkMetadataDeclaration")): linkmetas = parse_linkmeta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): @@ -917,6 +921,10 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw current_device['sub_role'] = sub_role results['DEVICE_METADATA']['localhost']['sub_role'] = sub_role results['DEVICE_METADATA']['localhost']['asic_name'] = asic_name + + if resource_type is not None: + results['DEVICE_METADATA']['localhost']['resource_type'] = resource_type + results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range diff --git a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml index 4bde42cdda3a..2b3368b7a9c7 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml @@ -253,6 +253,11 @@ 10.0.10.7;10.0.10.8 + + ResourceType + + resource_type_x + diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index ebaba3394f27..1fe1ad03849c 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -80,6 +80,11 @@ def test_minigraph_cloudtype(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'Public') + def test_minigraph_resourcetype(self): + argument = '-v "DEVICE_METADATA[\'localhost\'][\'resource_type\']" -m "' + self.sample_graph_metadata + '"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'resource_type_x') + def test_print_data(self): argument = '-m "' + self.sample_graph + '" --print-data' output = self.run_script(argument) From c1add9a9c5d6b174327a84fd5f7f34057dcc3e3e Mon Sep 17 00:00:00 2001 From: Shi Su <67605788+shi-su@users.noreply.github.com> Date: Thu, 8 Oct 2020 23:37:36 -0700 Subject: [PATCH 1224/1427] [sonic-sairedis] Update submodule (#5568) Signed-off-by: shi-su --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index b6e5a140ff3c..573d5c116cff 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit b6e5a140ff3c25e31622edac038c41dc145fbf35 +Subproject commit 573d5c116cff29d5e95dd5f172a773949ce76a66 From 72297749dffee902b00b5aa0338e43d6e355cd88 Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 9 Oct 2020 02:49:20 -0700 Subject: [PATCH 1225/1427] [build]: Added support for cache status on the build output (#5564) print cache status when use cached file in the build process Without DPKG cache support : [ building ] [ target/docker-base.gz ] [ finished ] [ target/docker-base.gz ] With DPKG cache support : [ building ] [ target/docker-base.gz ] [ cached ] [ target/docker-base.gz ] extracted from PR 4595 by Kalimuthu Velappan Signed-off-by: Guohan Lu --- rules/functions | 4 ++-- update_screen.sh | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/rules/functions b/rules/functions index 16665029c02a..d5aba46fd5d2 100644 --- a/rules/functions +++ b/rules/functions @@ -64,12 +64,12 @@ define HEADER @ $(PRINT_DEPENDENCIES) $(FLUSH_LOG) -./update_screen.sh -a $@ +./update_screen.sh -a $@ $* endef # footer for each rule define FOOTER -./update_screen.sh -d $@ +./update_screen.sh -d $@ $($*_CACHE_LOADED) endef ############################################################################### diff --git a/update_screen.sh b/update_screen.sh index de54774cc6c6..af272843d9b0 100755 --- a/update_screen.sh +++ b/update_screen.sh @@ -28,7 +28,9 @@ done function remove_target { # Check if TERM is available -[[ "${TERM}" == "dumb" ]] && echo "[ finished ] [ $1 ] " && return +local status="finished" +[[ ! -z "${2}" ]] && status="cached" +[[ "${TERM}" == "dumb" ]] && echo "[ ${status} ] [ $1 ] " && return old_list=$(cat ${target_list_file}) rm ${target_list_file} @@ -52,6 +54,17 @@ sleep 2 && print_targets && rm -f .screen & exit 0 } +# $3 takes the DPKG caching argument, if the target is loaded from cache, +# it adds the log as 'cached' else it is logged as 'finished' +# +# Without DPKG cache support : +# [ building ] [ target/docker-base.gz ] +# [ finished ] [ target/docker-base.gz ] +# +# With DPKG cache support : +# [ building ] [ target/docker-base.gz ] +# [ cached ] [ target/docker-base.gz ] + while getopts ":a:d:e:" opt; do case $opt in a) @@ -61,12 +74,12 @@ while getopts ":a:d:e:" opt; do ;; d) scroll_up - remove_target ${OPTARG} + remove_target ${OPTARG} $3 print_targets ;; e) scroll_up - remove_target ${OPTARG} + remove_target ${OPTARG} $3 echo "[ FAIL LOG START ] [ ${OPTARG} ]" cat ${OPTARG}.log echo "[ FAIL LOG END ] [ ${OPTARG} ]" From f7ee9836019e634dfe586ba3773f0cd96380ce2d Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 9 Oct 2020 08:53:05 -0700 Subject: [PATCH 1226/1427] [make init] update submodule's remotes (#5534) * [make reset] update submodule's remotes This change is to address an issue where when using a long standing repo to build image, the submodule could become out-dated with their remotes so that make init is no longer to bring all submoudles to the latest. The consequence is weird build failures. When we update/switch branch in a long standing repo, we will issue 'make reset' to get repo ready for next build. Updating all submodule's remotes during "make reset" address the issue. Signed-off-by: Ying Xie --- Makefile.work | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.work b/Makefile.work index 76d6c2cddd07..1f93c7780f97 100644 --- a/Makefile.work +++ b/Makefile.work @@ -301,6 +301,7 @@ reset : git reset --hard; git submodule foreach --recursive 'git clean -xfdf || true'; git submodule foreach --recursive 'git reset --hard || true'; + git submodule foreach --recursive 'git remote update || true'; git submodule update --init --recursive; echo "Reset complete!"; else From 64daeda6346ca816174521ec3dfa08f4b1cb255f Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Sat, 10 Oct 2020 15:24:05 +0300 Subject: [PATCH 1227/1427] [Mellanox] Update SDK 4.4.1912, FW XX.2008.1912 (#5574) - SN3800 vs Cisco9236 - no link copper or optics - start sending IDLE before PHY_UP for specific OPNs Signed-off-by: Nazarii Hnydyn --- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index b5da6b872b9d..1ec6ef208ea4 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2008.1622 +MLNX_SPC_FW_VERSION = 13.2008.1912 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2008.1622 +MLNX_SPC2_FW_VERSION = 29.2008.1912 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2008.1622 +MLNX_SPC3_FW_VERSION = 30.2008.1912 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index d5f6db1ceaef..c2af09b31592 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit d5f6db1ceaef84bce4dd7b2c3d4876037ef1209f +Subproject commit c2af09b315928034a993e7b7cca4530e02dfbeab diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index f40147b048d0..340eafa2e155 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,6 +1,6 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ MLNX_SDK_PKG_BASE_PATH = $(MLNX_SDK_BASE_PATH)/$(BLDENV)/ -MLNX_SDK_VERSION = 4.4.1622 +MLNX_SDK_VERSION = 4.4.1912 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 5e97574e5d785a6d14295fd3de885b116569f753 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 10 Oct 2020 14:14:58 -0700 Subject: [PATCH 1228/1427] [sonic-utilities] Update submodule (#5578) * src/sonic-utilities 6e58dff...e1244a5 (5): > [setup.py] Pin external runtime dependencies at known working versions (#1151) > [config] Reload Monit configuration after potential hostname changes (#1132) > [NAT]:Updated natshow script to support DNAT Pool changes (#1001) > [pfcstat] Create new copies of Rx and Tx dictionaries (#1150) > [master]Fix show ip interface neighbor info not correct when add second ip (#1134) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 6e58dff4c9b5..e1244a55d870 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 6e58dff4c9b590657e1f5e629a53ce4590d38382 +Subproject commit e1244a55d8706507df8f98eacb19c37e793e482a From 8e0e316cf8af6398a249050e1e33d86bb1bf3abc Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Sun, 11 Oct 2020 06:20:41 +0300 Subject: [PATCH 1229/1427] [BFN] Updated SDK packages to 20201009 (#5576) Signed-off-by: Andriy Kokhan --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 5363845fd7c2..274eb9575151 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20200721_deb9.deb +BFN_PLATFORM = bfnplatform_20201009_deb9.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 04f3157bdbcf..85ba488409a8 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20200721_deb9.deb +BFN_SAI = bfnsdk_20201009_deb9.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) From 1c97a03b81cd617c8d09151820a441604c90eeaa Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Mon, 12 Oct 2020 16:12:49 +0800 Subject: [PATCH 1230/1427] [system-health] Add support for monitoring system health (#4835) * system health first commit * system health daemon first commit * Finish healthd * Changes due to lower layer logic change * Get ASIC temperature from TEMPERATURE_INFO table * Add system health make rule and service files * fix bugs found during manual test * Change make file to install system-health library to host * Set system LED to blink on bootup time * Caught exceptions in system health checker to make it more robust * fix issue that fan/psu presence will always be true * fix issue for external checker * move system-health service to right after rc-local service * Set system-health service start after database service * Get system up time via /proc/uptime * Provide more information in stat for CLI to use * fix typo * Set default category to External for external checker * If external checker reported OK, save it to stat too * Trim string for external checker output * fix issue: PSU voltage check always return OK * Add unit test cases for system health library * Fix LGTM warnings * fix demo comments: 1. get boot up timeout from monit configuration file; 2. set system led in library instead of daemon * Remove boot_timeout configuration because it will get from monit config file * Fix argument miss * fix unit test failure * fix issue: summary status is not correct * Fix format issues found in code review * rename th to threshold to make it clearer * Fix review comment: 1. add a .dep file for system health; 2. deprecated daemon_base and uses sonic-py-common instead * Fix unit test failure * Fix LGTM alert * Fix LGTM alert * Fix review comments * Fix review comment * 1. Add relevant comments for system health; 2. rename external_checker to user_define_checker * Ignore check for unknown service type * Fix unit test issue * Rename user define checker to user defined checker * Rename user_define_checkers to user_defined_checkers for configuration file * Renmae file user_define_checker.py -> user_defined_checker.py * Fix typo * Adjust import order for config.py Co-authored-by: Joe LeVeque * Adjust import order for src/system-health/health_checker/hardware_checker.py Co-authored-by: Joe LeVeque * Adjust import order for src/system-health/scripts/healthd Co-authored-by: Joe LeVeque * Adjust import orders in src/system-health/tests/test_system_health.py * Fix typo * Add new line after import * If system health configuration file not exist, healthd should exit * Fix indent and enable pytest coverage * Fix typo * Fix typo * Remove global logger and use log functions inherited from super class * Change info level logger to notice level Co-authored-by: Joe LeVeque --- .../system_health_monitoring_config.json | 8 +- .../system_health_monitoring_config.json | 8 +- .../system_health_monitoring_config.json | 8 +- .../build_templates/sonic_debian_extension.j2 | 10 + .../system-health/system-health.service | 11 + rules/system-health.dep | 8 + rules/system-health.mk | 9 + slave.mk | 3 +- src/system-health/.gitignore | 8 + src/system-health/health_checker/__init__.py | 2 + src/system-health/health_checker/config.py | 144 ++++++++++ .../health_checker/hardware_checker.py | 248 ++++++++++++++++++ .../health_checker/health_checker.py | 86 ++++++ src/system-health/health_checker/manager.py | 101 +++++++ .../health_checker/service_checker.py | 72 +++++ .../system_health_monitoring_config.json | 11 + .../health_checker/user_defined_checker.py | 88 +++++++ src/system-health/health_checker/utils.py | 25 ++ src/system-health/pytest.ini | 2 + src/system-health/scripts/healthd | 108 ++++++++ src/system-health/setup.cfg | 2 + src/system-health/setup.py | 49 ++++ src/system-health/tests/__init__.py | 0 src/system-health/tests/mock_connector.py | 25 ++ src/system-health/tests/test_system_health.py | 219 ++++++++++++++++ 25 files changed, 1242 insertions(+), 13 deletions(-) create mode 100644 files/image_config/system-health/system-health.service create mode 100644 rules/system-health.dep create mode 100644 rules/system-health.mk create mode 100644 src/system-health/.gitignore create mode 100644 src/system-health/health_checker/__init__.py create mode 100644 src/system-health/health_checker/config.py create mode 100644 src/system-health/health_checker/hardware_checker.py create mode 100644 src/system-health/health_checker/health_checker.py create mode 100644 src/system-health/health_checker/manager.py create mode 100644 src/system-health/health_checker/service_checker.py create mode 100644 src/system-health/health_checker/system_health_monitoring_config.json create mode 100644 src/system-health/health_checker/user_defined_checker.py create mode 100644 src/system-health/health_checker/utils.py create mode 100644 src/system-health/pytest.ini create mode 100644 src/system-health/scripts/healthd create mode 100644 src/system-health/setup.cfg create mode 100644 src/system-health/setup.py create mode 100644 src/system-health/tests/__init__.py create mode 100644 src/system-health/tests/mock_connector.py create mode 100644 src/system-health/tests/test_system_health.py diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json index 5574936ee3e7..a4c9e9b44e02 100644 --- a/device/mellanox/x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json @@ -1,11 +1,11 @@ { "services_to_ignore": [], "devices_to_ignore": ["psu.voltage", "psu.temperature"], - "external_checkers": [], + "user_defined_checkers": [], "polling_interval": 60, "led_color": { - "fault": "orange", - "normal": "green", - "booting": "orange_blink" + "fault": "orange", + "normal": "green", + "booting": "orange_blink" } } diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json index 4c7d53f19cf5..bff6ab4b38ee 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json @@ -1,11 +1,11 @@ { "services_to_ignore": [], "devices_to_ignore": ["psu.voltage"], - "external_checkers": [], + "user_defined_checkers": [], "polling_interval": 60, "led_color": { - "fault": "orange", - "normal": "green", - "booting": "orange_blink" + "fault": "orange", + "normal": "green", + "booting": "orange_blink" } } diff --git a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json index e4ba06d7f46c..23cb74dd3f96 100644 --- a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json +++ b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json @@ -1,11 +1,11 @@ { "services_to_ignore": [], "devices_to_ignore": ["psu","asic","fan"], - "external_checkers": [], + "user_defined_checkers": [], "polling_interval": 60, "led_color": { - "fault": "orange", - "normal": "green", - "booting": "orange_blink" + "fault": "orange", + "normal": "green", + "booting": "orange_blink" } } diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 4dd49d8e3df8..390f042c7b91 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -172,6 +172,12 @@ sudo cp {{platform_common_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $PLATFORM_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME +# Install system-health Python 2 package +SYSTEM_HEALTH_PY2_WHEEL_NAME=$(basename {{system_health_py2_wheel_path}}) +sudo cp {{system_health_py2_wheel_path}} $FILESYSTEM_ROOT/$SYSTEM_HEALTH_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SYSTEM_HEALTH_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SYSTEM_HEALTH_PY2_WHEEL_NAME + # Install sonic-platform-common Python 3 package PLATFORM_COMMON_PY3_WHEEL_NAME=$(basename {{platform_common_py3_wheel_path}}) sudo cp {{platform_common_py3_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY3_WHEEL_NAME @@ -283,6 +289,10 @@ sudo mkdir -p $FILESYSTEM_ROOT/etc/systemd/system/syslog.socket.d sudo cp $IMAGE_CONFIGS/syslog/override.conf $FILESYSTEM_ROOT/etc/systemd/system/syslog.socket.d/override.conf sudo cp $IMAGE_CONFIGS/syslog/host_umount.sh $FILESYSTEM_ROOT/usr/bin/ +# Copy system-health files +sudo LANG=C cp $IMAGE_CONFIGS/system-health/system-health.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +echo "system-health.service" | sudo tee -a $GENERATED_SERVICE_FILE + # Copy logrotate.d configuration files sudo cp -f $IMAGE_CONFIGS/logrotate/logrotate.d/* $FILESYSTEM_ROOT/etc/logrotate.d/ diff --git a/files/image_config/system-health/system-health.service b/files/image_config/system-health/system-health.service new file mode 100644 index 000000000000..3de6a51584cb --- /dev/null +++ b/files/image_config/system-health/system-health.service @@ -0,0 +1,11 @@ +[Unit] +Description=SONiC system health monitor +Requires=database.service updategraph.service +After=database.service updategraph.service + +[Service] +ExecStart=/usr/local/bin/healthd +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/rules/system-health.dep b/rules/system-health.dep new file mode 100644 index 000000000000..31de25cb6d8c --- /dev/null +++ b/rules/system-health.dep @@ -0,0 +1,8 @@ +SPATH := $($(SYSTEM_HEALTH)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/system-health.mk rules/system-health.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SYSTEM_HEALTH)_CACHE_MODE := GIT_CONTENT_SHA +$(SYSTEM_HEALTH)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SYSTEM_HEALTH)_DEP_FILES := $(DEP_FILES) diff --git a/rules/system-health.mk b/rules/system-health.mk new file mode 100644 index 000000000000..16648508b9f4 --- /dev/null +++ b/rules/system-health.mk @@ -0,0 +1,9 @@ +# system health python2 wheel + +SYSTEM_HEALTH = system_health-1.0-py2-none-any.whl +$(SYSTEM_HEALTH)_SRC_PATH = $(SRC_PATH)/system-health +$(SYSTEM_HEALTH)_PYTHON_VERSION = 2 +$(SYSTEM_HEALTH)_DEPENDS = $(SONIC_PY_COMMON_PY2) $(SWSSSDK_PY2) $(SONIC_CONFIG_ENGINE) +SONIC_PYTHON_WHEELS += $(SYSTEM_HEALTH) + +export system_health_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SYSTEM_HEALTH))" diff --git a/slave.mk b/slave.mk index 9b0b10b3c0e7..3e200f9ee45d 100644 --- a/slave.mk +++ b/slave.mk @@ -819,7 +819,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY)) + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SYSTEM_HEALTH)) $(HEADER) # Pass initramfs and linux kernel explicitly. They are used for all platforms export debs_path="$(IMAGE_DISTRO_DEBS_PATH)" diff --git a/src/system-health/.gitignore b/src/system-health/.gitignore new file mode 100644 index 000000000000..843dd50ba52f --- /dev/null +++ b/src/system-health/.gitignore @@ -0,0 +1,8 @@ +*/deb_dist/ +*/dist/ +*/build/ +*/*.tar.gz +*/*.egg-info +*/.cache/ +*.pyc +*/__pycache__/ diff --git a/src/system-health/health_checker/__init__.py b/src/system-health/health_checker/__init__.py new file mode 100644 index 000000000000..18c49c8d81a1 --- /dev/null +++ b/src/system-health/health_checker/__init__.py @@ -0,0 +1,2 @@ +from . import hardware_checker +from . import service_checker diff --git a/src/system-health/health_checker/config.py b/src/system-health/health_checker/config.py new file mode 100644 index 000000000000..47b5f82b172b --- /dev/null +++ b/src/system-health/health_checker/config.py @@ -0,0 +1,144 @@ +import json +import os + +from sonic_py_common import device_info + + +class Config(object): + """ + Manage configuration of system health. + """ + + # Default system health check interval + DEFAULT_INTERVAL = 60 + + # Default boot up timeout. When reboot system, system health will wait a few seconds before starting to work. + DEFAULT_BOOTUP_TIMEOUT = 300 + + # Default LED configuration. Different platform has different LED capability. This configuration allow vendor to + # override the default behavior. + DEFAULT_LED_CONFIG = { + 'fault': 'red', + 'normal': 'green', + 'booting': 'orange_blink' + } + + # System health configuration file name + CONFIG_FILE = 'system_health_monitoring_config.json' + + # Monit service configuration file path + MONIT_CONFIG_FILE = '/etc/monit/monitrc' + + # Monit service start delay configuration entry + MONIT_START_DELAY_CONFIG = 'with start delay' + + def __init__(self): + """ + Constructor. Initialize all configuration entry to default value in case there is no configuration file. + """ + self.platform_name = device_info.get_platform() + self._config_file = os.path.join('/usr/share/sonic/device/', self.platform_name, Config.CONFIG_FILE) + self._last_mtime = None + self.config_data = None + self.interval = Config.DEFAULT_INTERVAL + self.ignore_services = None + self.ignore_devices = None + self.user_defined_checkers = None + + def config_file_exists(self): + return os.path.exists(self._config_file) + + def load_config(self): + """ + Load the configuration file from disk. + 1. If there is no configuration file, current config entries will reset to default value + 2. Only read the configuration file is last_mtime changes for better performance + 3. If there is any format issues in configuration file, current config entries will reset to default value + :return: + """ + if not self.config_file_exists(): + if self._last_mtime is not None: + self._reset() + return + + mtime = os.stat(self._config_file) + if mtime != self._last_mtime: + try: + self._last_mtime = mtime + with open(self._config_file, 'r') as f: + self.config_data = json.load(f) + + self.interval = self.config_data.get('polling_interval', Config.DEFAULT_INTERVAL) + self.ignore_services = self._get_list_data('services_to_ignore') + self.ignore_devices = self._get_list_data('devices_to_ignore') + self.user_defined_checkers = self._get_list_data('user_defined_checkers') + except Exception as e: + self._reset() + + def _reset(self): + """ + Reset current configuration entry to default value + :return: + """ + self._last_mtime = None + self.config_data = None + self.interval = Config.DEFAULT_INTERVAL + self.ignore_services = None + self.ignore_devices = None + self.user_defined_checkers = None + + def get_led_color(self, status): + """ + Get desired LED color according to the input status + :param status: System health status + :return: StringLED color + """ + if self.config_data and 'led_color' in self.config_data: + if status in self.config_data['led_color']: + return self.config_data['led_color'][status] + + return self.DEFAULT_LED_CONFIG[status] + + def get_bootup_timeout(self): + """ + Get boot up timeout from monit configuration file. + 1. If monit configuration file does not exist, return default value + 2. If there is any exception while parsing monit config, return default value + :return: Integer timeout value + """ + if not os.path.exists(Config.MONIT_CONFIG_FILE): + return self.DEFAULT_BOOTUP_TIMEOUT + + try: + with open(Config.MONIT_CONFIG_FILE) as f: + lines = f.readlines() + for line in lines: + if not line: + continue + + line = line.strip() + if not line: + continue + + pos = line.find('#') + if pos == 0: + continue + + line = line[:pos] + pos = line.find(Config.MONIT_START_DELAY_CONFIG) + if pos != -1: + return int(line[pos + len(Config.MONIT_START_DELAY_CONFIG):].strip()) + except Exception: + return self.DEFAULT_BOOTUP_TIMEOUT + + def _get_list_data(self, key): + """ + Get list type configuration data by key and remove duplicate element. + :param key: Key of the configuration entry + :return: A set of configuration data if key exists + """ + if key in self.config_data: + data = self.config_data[key] + if isinstance(data, list): + return set(data) + return None diff --git a/src/system-health/health_checker/hardware_checker.py b/src/system-health/health_checker/hardware_checker.py new file mode 100644 index 000000000000..a04fe2abf43a --- /dev/null +++ b/src/system-health/health_checker/hardware_checker.py @@ -0,0 +1,248 @@ +from natsort import natsorted +from swsssdk import SonicV2Connector + +from .health_checker import HealthChecker + + +class HardwareChecker(HealthChecker): + """ + Check system hardware status. For now, it checks ASIC, PSU and fan status. + """ + ASIC_TEMPERATURE_KEY = 'TEMPERATURE_INFO|ASIC' + FAN_TABLE_NAME = 'FAN_INFO' + PSU_TABLE_NAME = 'PSU_INFO' + + def __init__(self): + HealthChecker.__init__(self) + self._db = SonicV2Connector(host="127.0.0.1") + self._db.connect(self._db.STATE_DB) + + def get_category(self): + return 'Hardware' + + def check(self, config): + self.reset() + self._check_asic_status(config) + self._check_fan_status(config) + self._check_psu_status(config) + + def _check_asic_status(self, config): + """ + Check if ASIC temperature is in valid range. + :param config: Health checker configuration + :return: + """ + if config.ignore_devices and 'asic' in config.ignore_devices: + return + + temperature = self._db.get(self._db.STATE_DB, HardwareChecker.ASIC_TEMPERATURE_KEY, 'temperature') + temperature_threshold = self._db.get(self._db.STATE_DB, HardwareChecker.ASIC_TEMPERATURE_KEY, 'high_threshold') + if not temperature: + self.set_object_not_ok('ASIC', 'ASIC', 'Failed to get ASIC temperature') + elif not temperature_threshold: + self.set_object_not_ok('ASIC', 'ASIC', 'Failed to get ASIC temperature threshold') + else: + try: + temperature = float(temperature) + temperature_threshold = float(temperature_threshold) + if temperature > temperature_threshold: + self.set_object_not_ok('ASIC', 'ASIC', + 'ASIC temperature is too hot, temperature={}, threshold={}'.format( + temperature, + temperature_threshold)) + else: + self.set_object_ok('ASIC', 'ASIC') + except ValueError as e: + self.set_object_not_ok('ASIC', 'ASIC', + 'Invalid ASIC temperature data, temperature={}, threshold={}'.format(temperature, + temperature_threshold)) + + def _check_fan_status(self, config): + """ + Check fan status including: + 1. Check all fans are present + 2. Check all fans are in good state + 3. Check fan speed is in valid range + :param config: Health checker configuration + :return: + """ + if config.ignore_devices and 'fan' in config.ignore_devices: + return + + keys = self._db.keys(self._db.STATE_DB, HardwareChecker.FAN_TABLE_NAME + '*') + if not keys: + self.set_object_not_ok('Fan', 'Fan', 'Failed to get fan information') + return + + for key in natsorted(keys): + key_list = key.split('|') + if len(key_list) != 2: # error data in DB, log it and ignore + self.set_object_not_ok('Fan', key, 'Invalid key for FAN_INFO: {}'.format(key)) + continue + + name = key_list[1] + if config.ignore_devices and name in config.ignore_devices: + continue + data_dict = self._db.get_all(self._db.STATE_DB, key) + presence = data_dict.get('presence', 'false') + if presence.lower() != 'true': + self.set_object_not_ok('Fan', name, '{} is missing'.format(name)) + continue + + status = data_dict.get('status', 'false') + if status.lower() != 'true': + self.set_object_not_ok('Fan', name, '{} is broken'.format(name)) + continue + + if not self._ignore_check(config.ignore_devices, 'fan', name, 'speed'): + speed = data_dict.get('speed', None) + speed_target = data_dict.get('speed_target', None) + speed_tolerance = data_dict.get('speed_tolerance', None) + if not speed: + self.set_object_not_ok('Fan', name, 'Failed to get actual speed data for {}'.format(name)) + continue + elif not speed_target: + self.set_object_not_ok('Fan', name, 'Failed to get target speed date for {}'.format(name)) + continue + elif not speed_tolerance: + self.set_object_not_ok('Fan', name, 'Failed to get speed tolerance for {}'.format(name)) + continue + else: + try: + speed = float(speed) + speed_target = float(speed_target) + speed_tolerance = float(speed_tolerance) + speed_min_th = speed_target * (1 - float(speed_tolerance) / 100) + speed_max_th = speed_target * (1 + float(speed_tolerance) / 100) + if speed < speed_min_th or speed > speed_max_th: + self.set_object_not_ok('Fan', name, + '{} speed is out of range, speed={}, range=[{},{}]'.format(name, + speed, + speed_min_th, + speed_max_th)) + continue + except ValueError: + self.set_object_not_ok('Fan', name, + 'Invalid fan speed data for {}, speed={}, target={}, tolerance={}'.format( + name, + speed, + speed_target, + speed_tolerance)) + continue + + self.set_object_ok('Fan', name) + + def _check_psu_status(self, config): + """ + Check PSU status including: + 1. Check all PSUs are present + 2. Check all PSUs are power on + 3. Check PSU temperature is in valid range + 4. Check PSU voltage is in valid range + :param config: Health checker configuration + :return: + """ + if config.ignore_devices and 'psu' in config.ignore_devices: + return + + keys = self._db.keys(self._db.STATE_DB, HardwareChecker.PSU_TABLE_NAME + '*') + if not keys: + self.set_object_not_ok('PSU', 'PSU', 'Failed to get PSU information') + return + + for key in natsorted(keys): + key_list = key.split('|') + if len(key_list) != 2: # error data in DB, log it and ignore + self.set_object_not_ok('PSU', key, 'Invalid key for PSU_INFO: {}'.format(key)) + continue + + name = key_list[1] + if config.ignore_devices and name in config.ignore_devices: + continue + + data_dict = self._db.get_all(self._db.STATE_DB, key) + presence = data_dict.get('presence', 'false') + if presence.lower() != 'true': + self.set_object_not_ok('PSU', name, '{} is missing or not available'.format(name)) + continue + + status = data_dict.get('status', 'false') + if status.lower() != 'true': + self.set_object_not_ok('PSU', name, '{} is out of power'.format(name)) + continue + + if not self._ignore_check(config.ignore_devices, 'psu', name, 'temperature'): + temperature = data_dict.get('temp', None) + temperature_threshold = data_dict.get('temp_threshold', None) + if temperature is None: + self.set_object_not_ok('PSU', name, 'Failed to get temperature data for {}'.format(name)) + continue + elif temperature_threshold is None: + self.set_object_not_ok('PSU', name, 'Failed to get temperature threshold data for {}'.format(name)) + continue + else: + try: + temperature = float(temperature) + temperature_threshold = float(temperature_threshold) + if temperature > temperature_threshold: + self.set_object_not_ok('PSU', name, + '{} temperature is too hot, temperature={}, threshold={}'.format( + name, temperature, + temperature_threshold)) + continue + except ValueError: + self.set_object_not_ok('PSU', name, + 'Invalid temperature data for {}, temperature={}, threshold={}'.format( + name, temperature, + temperature_threshold)) + continue + + if not self._ignore_check(config.ignore_devices, 'psu', name, 'voltage'): + voltage = data_dict.get('voltage', None) + voltage_min_th = data_dict.get('voltage_min_threshold', None) + voltage_max_th = data_dict.get('voltage_max_threshold', None) + if voltage is None: + self.set_object_not_ok('PSU', name, 'Failed to get voltage data for {}'.format(name)) + continue + elif voltage_min_th is None: + self.set_object_not_ok('PSU', name, + 'Failed to get voltage minimum threshold data for {}'.format(name)) + continue + elif voltage_max_th is None: + self.set_object_not_ok('PSU', name, + 'Failed to get voltage maximum threshold data for {}'.format(name)) + continue + else: + try: + voltage = float(voltage) + voltage_min_th = float(voltage_min_th) + voltage_max_th = float(voltage_max_th) + if voltage < voltage_min_th or voltage > voltage_max_th: + self.set_object_not_ok('PSU', name, + '{} voltage is out of range, voltage={}, range=[{},{}]'.format(name, + voltage, + voltage_min_th, + voltage_max_th)) + continue + except ValueError: + self.set_object_not_ok('PSU', name, + 'Invalid voltage data for {}, voltage={}, range=[{},{}]'.format(name, + voltage, + voltage_min_th, + voltage_max_th)) + continue + self.set_object_ok('PSU', name) + + def reset(self): + self._info = {} + + @classmethod + def _ignore_check(cls, ignore_set, category, object_name, check_point): + if not ignore_set: + return False + + if '{}.{}'.format(category, check_point) in ignore_set: + return True + elif '{}.{}'.format(object_name, check_point) in ignore_set: + return True + return False diff --git a/src/system-health/health_checker/health_checker.py b/src/system-health/health_checker/health_checker.py new file mode 100644 index 000000000000..59519d0a05c4 --- /dev/null +++ b/src/system-health/health_checker/health_checker.py @@ -0,0 +1,86 @@ +class HealthChecker(object): + """ + Base class for health checker. A checker is an object that performs system health check for a particular category, + it collects and stores information after the check. + """ + INFO_FIELD_OBJECT_TYPE = 'type' + INFO_FIELD_OBJECT_STATUS = 'status' + INFO_FIELD_OBJECT_MSG = 'message' + + STATUS_OK = 'OK' + STATUS_NOT_OK = 'Not OK' + + summary = STATUS_OK + + def __init__(self): + self._info = {} + + def reset(self): + """ + Reset the status of the checker. Called every time before the check. + :return: + """ + pass + + def get_category(self): + """ + Get category of the checker. + :return: String category + """ + pass + + def get_info(self): + """ + Get information of the checker. A checker usually checks a few objects and each object status will be put to + self._info. + :return: Check result. + """ + return self._info + + def check(self, config): + """ + Perform the check. + :param config: Health checker configuration. + :return: + """ + pass + + def __str__(self): + return self.__class__.__name__ + + def add_info(self, object_name, key, value): + """ + Add check result for an object. + :param object_name: Object name. + :param key: Object attribute name. + :param value: Object attribute value. + :return: + """ + if object_name not in self._info: + self._info[object_name] = {} + + self._info[object_name][key] = value + + def set_object_not_ok(self, object_type, object_name, message): + """ + Set that an object is not OK. + :param object_type: Object type. + :param object_name: Object name. + :param message: A message to describe what is wrong with the object. + :return: + """ + self.add_info(object_name, self.INFO_FIELD_OBJECT_TYPE, object_type) + self.add_info(object_name, self.INFO_FIELD_OBJECT_MSG, message) + self.add_info(object_name, self.INFO_FIELD_OBJECT_STATUS, self.STATUS_NOT_OK) + HealthChecker.summary = HealthChecker.STATUS_NOT_OK + + def set_object_ok(self, object_type, object_name): + """ + Set that an object is in good state. + :param object_type: Object type. + :param object_name: Object name. + :return: + """ + self.add_info(object_name, self.INFO_FIELD_OBJECT_TYPE, object_type) + self.add_info(object_name, self.INFO_FIELD_OBJECT_MSG, '') + self.add_info(object_name, self.INFO_FIELD_OBJECT_STATUS, self.STATUS_OK) diff --git a/src/system-health/health_checker/manager.py b/src/system-health/health_checker/manager.py new file mode 100644 index 000000000000..933d6a9d543f --- /dev/null +++ b/src/system-health/health_checker/manager.py @@ -0,0 +1,101 @@ +class HealthCheckerManager(object): + """ + Manage all system health checkers and system health configuration. + """ + STATE_BOOTING = 'booting' + STATE_RUNNING = 'running' + boot_timeout = None + + def __init__(self): + self._checkers = [] + self._state = self.STATE_BOOTING + + from .config import Config + self.config = Config() + self.initialize() + + def initialize(self): + """ + Initialize the manager. Create service checker and hardware checker by default. + :return: + """ + from .service_checker import ServiceChecker + from .hardware_checker import HardwareChecker + self._checkers.append(ServiceChecker()) + self._checkers.append(HardwareChecker()) + + def check(self, chassis): + """ + Load new configuration if any and perform the system health check for all existing checkers. + :param chassis: A chassis object. + :return: A tuple. The first element indicate the status of the checker; the second element is a dictionary that + contains the status for all objects that was checked. + """ + from .health_checker import HealthChecker + HealthChecker.summary = HealthChecker.STATUS_OK + stats = {} + self.config.load_config() + # check state first to avoid user change boot timeout in configuration file + # after finishing system boot + if self._state == self.STATE_BOOTING and self._is_system_booting(): + self._set_system_led(chassis, self.config, 'booting') + return self._state, stats + + for checker in self._checkers: + self._do_check(checker, stats) + + if self.config.user_defined_checkers: + from .user_defined_checker import UserDefinedChecker + for udc in self.config.user_defined_checkers: + checker = UserDefinedChecker(udc) + self._do_check(checker, stats) + + led_status = 'normal' if HealthChecker.summary == HealthChecker.STATUS_OK else 'fault' + self._set_system_led(chassis, self.config, led_status) + + return self._state, stats + + def _do_check(self, checker, stats): + """ + Do check for a particular checker and collect the check statistic. + :param checker: A checker object. + :param stats: Check statistic. + :return: + """ + try: + checker.check(self.config) + category = checker.get_category() + info = checker.get_info() + if category not in stats: + stats[category] = info + else: + stats[category].update(info) + except Exception as e: + from .health_checker import HealthChecker + error_msg = 'Failed to perform health check for {} due to exception - {}'.format(checker, repr(e)) + entry = {str(checker): { + HealthChecker.INFO_FIELD_OBJECT_STATUS: HealthChecker.STATUS_NOT_OK, + HealthChecker.INFO_FIELD_OBJECT_MSG: error_msg + }} + if 'Internal' not in stats: + stats['Internal'] = entry + else: + stats['Internal'].update(entry) + + def _is_system_booting(self): + from .utils import get_uptime + uptime = get_uptime() + if not self.boot_timeout: + self.boot_timeout = self.config.get_bootup_timeout() + booting = uptime < self.boot_timeout + if not booting: + self._state = self.STATE_RUNNING + return booting + + def _set_system_led(self, chassis, config, status): + try: + chassis.set_status_led(config.get_led_color(status)) + except NotImplementedError: + print('chassis.set_status_led is not implemented') + except Exception as e: + print('Failed to set system led due to - {}'.format(repr(e))) diff --git a/src/system-health/health_checker/service_checker.py b/src/system-health/health_checker/service_checker.py new file mode 100644 index 000000000000..8f18a6d7245e --- /dev/null +++ b/src/system-health/health_checker/service_checker.py @@ -0,0 +1,72 @@ +from .health_checker import HealthChecker +from . import utils + + +class ServiceChecker(HealthChecker): + """ + Checker that checks critical system service status via monit service. + """ + + # Command to query the status of monit service. + CHECK_MONIT_SERVICE_CMD = 'systemctl is-active monit.service' + + # Command to get summary of critical system service. + CHECK_CMD = 'monit summary -B' + MIN_CHECK_CMD_LINES = 3 + + # Expect status for different system service category. + EXPECT_STATUS_DICT = { + 'System': 'Running', + 'Process': 'Running', + 'Filesystem': 'Accessible', + 'Program': 'Status ok' + } + + def __init__(self): + HealthChecker.__init__(self) + + def reset(self): + self._info = {} + + def get_category(self): + return 'Services' + + def check(self, config): + """ + Check critical system service status. Get and analyze the output of $CHECK_CMD, collect status for system, + process and file system. + :param config: Health checker configuration. + :return: + """ + self.reset() + output = utils.run_command(ServiceChecker.CHECK_MONIT_SERVICE_CMD).strip() + if output != 'active': + self.set_object_not_ok('Service', 'monit', 'monit service is not running') + return + + output = utils.run_command(ServiceChecker.CHECK_CMD) + lines = output.splitlines() + if not lines or len(lines) < ServiceChecker.MIN_CHECK_CMD_LINES: + self.set_object_not_ok('Service', 'monit', 'output of \"monit summary -B\" is invalid or incompatible') + return + + status_begin = lines[1].find('Status') + type_begin = lines[1].find('Type') + if status_begin < 0 or type_begin < 0: + self.set_object_not_ok('Service', 'monit', 'output of \"monit summary -B\" is invalid or incompatible') + return + + for line in lines[2:]: + name = line[0:status_begin].strip() + if config.ignore_services and name in config.ignore_services: + continue + status = line[status_begin:type_begin].strip() + service_type = line[type_begin:].strip() + if service_type not in ServiceChecker.EXPECT_STATUS_DICT: + continue + expect_status = ServiceChecker.EXPECT_STATUS_DICT[service_type] + if expect_status != status: + self.set_object_not_ok(service_type, name, '{} is not {}'.format(name, expect_status)) + else: + self.set_object_ok(service_type, name) + return diff --git a/src/system-health/health_checker/system_health_monitoring_config.json b/src/system-health/health_checker/system_health_monitoring_config.json new file mode 100644 index 000000000000..0fc475e766e4 --- /dev/null +++ b/src/system-health/health_checker/system_health_monitoring_config.json @@ -0,0 +1,11 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": [], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "amber", + "normal": "green", + "booting": "orange_blink" + } +} \ No newline at end of file diff --git a/src/system-health/health_checker/user_defined_checker.py b/src/system-health/health_checker/user_defined_checker.py new file mode 100644 index 000000000000..ed0cdce6194d --- /dev/null +++ b/src/system-health/health_checker/user_defined_checker.py @@ -0,0 +1,88 @@ +from .health_checker import HealthChecker +from . import utils + + +class UserDefinedChecker(HealthChecker): + """ + User could implement a script or program to perform customize check for particular system. In order to enable a + user defined checker: + 1. Add an element to "user_defined_checkers" in the configuration file. The element must be an command string + that can be executed by shell. For example: "python my_checker.py". + 2. The command output must match the following pattern: + ${UserDefineCategory} + ${Object1}:${ObjectStatusMessage1} + ${Object2}:${ObjectStatusMessage2} + + An example of the command output: + MyCategory + Device1:OK + Device2:OK + Device3:Out of power + """ + def __init__(self, cmd): + """ + Constructor. + :param cmd: Command string of the user defined checker. + """ + HealthChecker.__init__(self) + self._cmd = cmd + self._category = None + + def reset(self): + self._category = 'UserDefine' + self._info = {} + + def get_category(self): + return self._category + + def check(self, config): + """ + Execute the user defined command and parse the output. + :param config: Health checker configuration. + :return: + """ + self.reset() + + output = utils.run_command(self._cmd) + if not output: + self.set_object_not_ok('UserDefine', str(self), 'Failed to get output of command \"{}\"'.format(self._cmd)) + return + + output = output.strip() + if not output: + self.set_object_not_ok('UserDefine', str(self), 'Failed to get output of command \"{}\"'.format(self._cmd)) + return + + raw_lines = output.splitlines() + if not raw_lines: + self.set_object_not_ok('UserDefine', str(self), 'Invalid output of command \"{}\"'.format(self._cmd)) + return + + lines = [] + for line in raw_lines: + line = line.strip() + if not line: + continue + + lines.append(line) + + if not lines: + self.set_object_not_ok('UserDefine', str(self), 'Invalid output of command \"{}\"'.format(self._cmd)) + return + + self._category = lines[0] + if len(lines) > 1: + for line in lines[1:]: + pos = line.find(':') + if pos == -1: + continue + obj_name = line[:pos].strip() + msg = line[pos + 1:].strip() + if msg != 'OK': + self.set_object_not_ok('UserDefine', obj_name, msg) + else: + self.set_object_ok('UserDefine', obj_name) + return + + def __str__(self): + return 'UserDefinedChecker - {}'.format(self._cmd) diff --git a/src/system-health/health_checker/utils.py b/src/system-health/health_checker/utils.py new file mode 100644 index 000000000000..5da8a7346c2a --- /dev/null +++ b/src/system-health/health_checker/utils.py @@ -0,0 +1,25 @@ +import subprocess + + +def run_command(command): + """ + Utility function to run an shell command and return the output. + :param command: Shell command string. + :return: Output of the shell command. + """ + try: + process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + return process.communicate()[0].encode('utf-8') + except Exception: + return None + + +def get_uptime(): + """ + Utility to get the system up time. + :return: System up time in seconds. + """ + with open('/proc/uptime', 'r') as f: + uptime_seconds = float(f.readline().split()[0]) + + return uptime_seconds diff --git a/src/system-health/pytest.ini b/src/system-health/pytest.ini new file mode 100644 index 000000000000..a9c5a74860a3 --- /dev/null +++ b/src/system-health/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = --cov=health_checker --cov-report html --cov-report term --cov-report xml diff --git a/src/system-health/scripts/healthd b/src/system-health/scripts/healthd new file mode 100644 index 000000000000..00078d0c3ee0 --- /dev/null +++ b/src/system-health/scripts/healthd @@ -0,0 +1,108 @@ +#!/usr/bin/env python2 + +""" + healthd + System health monitor daemon for SONiC +""" + +import signal +import threading + +from sonic_py_common.daemon_base import DaemonBase +from swsssdk import SonicV2Connector + +from health_checker.manager import HealthCheckerManager + +SYSLOG_IDENTIFIER = 'healthd' + + +class HealthDaemon(DaemonBase): + """ + A daemon that run as a service to perform system health checker with a configurable interval. Also set system LED + according to the check result and store the check result to redis. + """ + SYSTEM_HEALTH_TABLE_NAME = 'SYSTEM_HEALTH_INFO' + + def __init__(self): + """ + Constructor of HealthDaemon. + """ + DaemonBase.__init__(self, SYSLOG_IDENTIFIER) + self._db = SonicV2Connector(host="127.0.0.1") + self._db.connect(self._db.STATE_DB) + self.stop_event = threading.Event() + + def deinit(self): + """ + Destructor. Remove all entries in $SYSTEM_HEALTH_TABLE_NAME table. + :return: + """ + self._clear_system_health_table() + + def _clear_system_health_table(self): + self._db.delete_all_by_pattern(self._db.STATE_DB, HealthDaemon.SYSTEM_HEALTH_TABLE_NAME) + + # Signal handler + def signal_handler(self, sig, frame): + """ + Signal handler + :param sig: Signal number + :param frame: not used + :return: + """ + if sig == signal.SIGHUP: + self.log_notice("Caught SIGHUP - ignoring...") + elif sig == signal.SIGINT: + self.log_notice("Caught SIGINT - exiting...") + self.stop_event.set() + elif sig == signal.SIGTERM: + self.log_notice("Caught SIGTERM - exiting...") + self.stop_event.set() + else: + self.log_warning("Caught unhandled signal '" + sig + "'") + + def run(self): + """ + Check system health in an infinite loop. + :return: + """ + self.log_notice("Starting up...") + + import sonic_platform.platform + chassis = sonic_platform.platform.Platform().get_chassis() + manager = HealthCheckerManager() + if not manager.config.config_file_exists(): + self.log_warning("System health configuration file not found, exit...") + return + while 1: + state, stat = manager.check(chassis) + if state == HealthCheckerManager.STATE_RUNNING: + self._process_stat(chassis, manager.config, stat) + + if self.stop_event.wait(manager.config.interval): + break + + self.deinit() + + def _process_stat(self, chassis, config, stat): + from health_checker.health_checker import HealthChecker + self._clear_system_health_table() + for category, info in stat.items(): + for obj_name, obj_data in info.items(): + if obj_data[HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK: + self._db.set(self._db.STATE_DB, HealthDaemon.SYSTEM_HEALTH_TABLE_NAME, obj_name, + obj_data[HealthChecker.INFO_FIELD_OBJECT_MSG]) + + self._db.set(self._db.STATE_DB, HealthDaemon.SYSTEM_HEALTH_TABLE_NAME, 'summary', HealthChecker.summary) + + +# +# Main ========================================================================= +# +def main(): + health_monitor = HealthDaemon() + health_monitor.run() + + +if __name__ == '__main__': + main() diff --git a/src/system-health/setup.cfg b/src/system-health/setup.cfg new file mode 100644 index 000000000000..b7e478982ccf --- /dev/null +++ b/src/system-health/setup.cfg @@ -0,0 +1,2 @@ +[aliases] +test=pytest diff --git a/src/system-health/setup.py b/src/system-health/setup.py new file mode 100644 index 000000000000..a7decca09a97 --- /dev/null +++ b/src/system-health/setup.py @@ -0,0 +1,49 @@ +from setuptools import setup + +dependencies = [ + 'natsort', + 'sonic_py_common', + 'swsssdk>=2.0.1', +] + +setup( + name='system-health', + version='1.0', + description='SONiC system health package', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Junchao Chen', + maintainer_email='junchaow@mellanox.com', + install_requires=dependencies, + packages=[ + 'health_checker', + 'tests' + ], + scripts=[ + 'scripts/healthd', + ], + setup_requires= [ + 'pytest-runner' + ], + tests_require = [ + 'pytest', + 'mock>=2.0.0' + ], + classifiers=[ + 'Development Status :: 4 - Beta', + 'Environment :: No Input/Output (Daemon)', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: System :: Hardware', + ], + keywords='SONiC sonic HEALTH health', + test_suite='setup.get_test_suite' +) + diff --git a/src/system-health/tests/__init__.py b/src/system-health/tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/system-health/tests/mock_connector.py b/src/system-health/tests/mock_connector.py new file mode 100644 index 000000000000..c65198dbe145 --- /dev/null +++ b/src/system-health/tests/mock_connector.py @@ -0,0 +1,25 @@ +class MockConnector(object): + STATE_DB = None + data = {} + + def __init__(self, host): + pass + + def connect(self, db_id): + pass + + def get(self, db_id, key, field): + return MockConnector.data[key][field] + + def keys(self, db_id, pattern): + match = pattern.split('*')[0] + ret = [] + for key in MockConnector.data.keys(): + if match in key: + ret.append(key) + + return ret + + def get_all(self, db_id, key): + return MockConnector.data[key] + diff --git a/src/system-health/tests/test_system_health.py b/src/system-health/tests/test_system_health.py new file mode 100644 index 000000000000..6a791613a475 --- /dev/null +++ b/src/system-health/tests/test_system_health.py @@ -0,0 +1,219 @@ +""" + Unit test cases for system health checker. The current test case contains: + 1. test_user_defined_checker mocks the output of a user defined checker and verify class UserDefinedChecker + 2. test_service_checker mocks the output of monit service and verify class ServiceChecker + 3. test_hardware_checker mocks the hardware status data in db and verify class HardwareChecker + And there are class that are not covered by unit test. These class will be covered by sonic-mgmt regression test. + 1. HealthDaemon + 2. HealthCheckerManager + 3. Config +""" +import os +import sys +import swsssdk + +from mock import Mock, MagicMock, patch +from sonic_py_common import device_info + +from .mock_connector import MockConnector + +swsssdk.SonicV2Connector = MockConnector + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +sys.path.insert(0, modules_path) +from health_checker import utils +from health_checker.config import Config +from health_checker.hardware_checker import HardwareChecker +from health_checker.health_checker import HealthChecker +from health_checker.manager import HealthCheckerManager +from health_checker.service_checker import ServiceChecker +from health_checker.user_defined_checker import UserDefinedChecker + +device_info.get_platform = MagicMock(return_value='unittest') + + +def test_user_defined_checker(): + utils.run_command = MagicMock(return_value='') + + checker = UserDefinedChecker('') + checker.check(None) + assert checker._info[str(checker)][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + checker.reset() + assert len(checker._info) == 0 + + utils.run_command = MagicMock(return_value='\n\n\n') + checker.check(None) + assert checker._info[str(checker)][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + valid_output = 'MyCategory\nDevice1:OK\nDevice2:Device2 is broken\n' + utils.run_command = MagicMock(return_value=valid_output) + checker.check(None) + assert 'Device1' in checker._info + assert 'Device2' in checker._info + assert checker._info['Device1'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_OK + assert checker._info['Device2'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + +def test_service_checker(): + return_value = '' + + def mock_run_command(cmd): + if cmd == ServiceChecker.CHECK_MONIT_SERVICE_CMD: + return 'active' + else: + return return_value + + utils.run_command = mock_run_command + return_value = 'Monit 5.20.0 uptime: 3h 54m\n' \ + 'Service Name Status Type\n' \ + 'sonic Running System\n' \ + 'sonic1 Not running System\n' \ + 'telemetry Does not exist Process\n' \ + 'orchagent Running Process\n' \ + 'root-overlay Accessible Filesystem\n' \ + 'var-log Is not accessible Filesystem\n' + + checker = ServiceChecker() + config = Config() + checker.check(config) + assert 'sonic' in checker._info + assert checker._info['sonic'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_OK + + assert 'sonic1' in checker._info + assert checker._info['sonic1'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + assert 'orchagent' in checker._info + assert checker._info['orchagent'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_OK + + assert 'telemetry' in checker._info + assert checker._info['telemetry'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + assert 'root-overlay' in checker._info + assert checker._info['root-overlay'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_OK + + assert 'var-log' in checker._info + assert checker._info['var-log'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + +def test_hardware_checker(): + MockConnector.data.update({ + 'TEMPERATURE_INFO|ASIC': { + 'temperature': '20', + 'high_threshold': '21' + } + }) + + MockConnector.data.update({ + 'FAN_INFO|fan1': { + 'presence': 'True', + 'status': 'True', + 'speed': '60', + 'speed_target': '60', + 'speed_tolerance': '20' + }, + 'FAN_INFO|fan2': { + 'presence': 'False', + 'status': 'True', + 'speed': '60', + 'speed_target': '60', + 'speed_tolerance': '20' + }, + 'FAN_INFO|fan3': { + 'presence': 'True', + 'status': 'False', + 'speed': '60', + 'speed_target': '60', + 'speed_tolerance': '20' + }, + 'FAN_INFO|fan4': { + 'presence': 'True', + 'status': 'True', + 'speed': '20', + 'speed_target': '60', + 'speed_tolerance': '20' + } + }) + + MockConnector.data.update({ + 'PSU_INFO|PSU 1': { + 'presence': 'True', + 'status': 'True', + 'temp': '55', + 'temp_threshold': '100', + 'voltage': '10', + 'voltage_min_threshold': '8', + 'voltage_max_threshold': '15', + }, + 'PSU_INFO|PSU 2': { + 'presence': 'False', + 'status': 'True', + 'temp': '55', + 'temp_threshold': '100', + 'voltage': '10', + 'voltage_min_threshold': '8', + 'voltage_max_threshold': '15', + }, + 'PSU_INFO|PSU 3': { + 'presence': 'True', + 'status': 'False', + 'temp': '55', + 'temp_threshold': '100', + 'voltage': '10', + 'voltage_min_threshold': '8', + 'voltage_max_threshold': '15', + }, + 'PSU_INFO|PSU 4': { + 'presence': 'True', + 'status': 'True', + 'temp': '101', + 'temp_threshold': '100', + 'voltage': '10', + 'voltage_min_threshold': '8', + 'voltage_max_threshold': '15', + }, + 'PSU_INFO|PSU 5': { + 'presence': 'True', + 'status': 'True', + 'temp': '55', + 'temp_threshold': '100', + 'voltage': '10', + 'voltage_min_threshold': '12', + 'voltage_max_threshold': '15', + } + }) + + checker = HardwareChecker() + config = Config() + checker.check(config) + + assert 'ASIC' in checker._info + assert checker._info['ASIC'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_OK + + assert 'fan1' in checker._info + assert checker._info['fan1'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_OK + + assert 'fan2' in checker._info + assert checker._info['fan2'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + assert 'fan3' in checker._info + assert checker._info['fan3'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + assert 'fan4' in checker._info + assert checker._info['fan4'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + assert 'PSU 1' in checker._info + assert checker._info['PSU 1'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_OK + + assert 'PSU 2' in checker._info + assert checker._info['PSU 2'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + assert 'PSU 3' in checker._info + assert checker._info['PSU 3'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + assert 'PSU 4' in checker._info + assert checker._info['PSU 4'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK + + assert 'PSU 5' in checker._info + assert checker._info['PSU 5'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK From bba5df05233e17ab3eb8cd378e4629923b30ff16 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Tue, 13 Oct 2020 00:16:01 +0300 Subject: [PATCH 1231/1427] [barefoot][platform] Fix symlinks and syncd.conf for Newport in platform/ (#5585) Fix symlinks and syncd.conf for Newport in platform/ directory Signed-off-by: Volodymyr Boyko --- .../syncd.conf | 0 device/barefoot/x86_64-accton_as9516bf_32d-r0 | 1 + 2 files changed, 1 insertion(+) rename device/barefoot/{x86_64-accton_as9516bf_32d-r0 => x86_64-accton_as9516_32d-r0}/syncd.conf (100%) create mode 120000 device/barefoot/x86_64-accton_as9516bf_32d-r0 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/syncd.conf b/device/barefoot/x86_64-accton_as9516_32d-r0/syncd.conf similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/syncd.conf rename to device/barefoot/x86_64-accton_as9516_32d-r0/syncd.conf diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0 b/device/barefoot/x86_64-accton_as9516bf_32d-r0 new file mode 120000 index 000000000000..93f47d51b742 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0 @@ -0,0 +1 @@ +x86_64-accton_as9516_32d-r0 \ No newline at end of file From 4a390e93cf65c1ea05ff8434724ab8451da69ad3 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 13 Oct 2020 15:25:45 -0700 Subject: [PATCH 1232/1427] [submodule]: sonic-utilities (#5606) * b6af9f4 2020-10-12 | Fix expected neighbor when multiple ports connect to same neighbor (#1162) [lguohan] * a71c72b 2020-10-12 | [show] Add 'show' CLI for system-health feature (#971) [shlomibitton] * 561d133 2020-10-10 | [README.md] Add instructions for setting up a build/test environment (#1161) [Joe LeVeque] Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index e1244a55d870..b6af9f48e298 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit e1244a55d8706507df8f98eacb19c37e793e482a +Subproject commit b6af9f48e29852985137a57ff5396591af7f107c From 3cd1d8e923280b4256f4d37d3ed280ed2578c655 Mon Sep 17 00:00:00 2001 From: vdahiya12 <67608553+vdahiya12@users.noreply.github.com> Date: Tue, 13 Oct 2020 16:58:06 -0700 Subject: [PATCH 1233/1427] [sonic-py-common] Add platform.json to port_config files candidates only if interfaces are present within platform.json (#5538) * [sonic-py-common] add platform.json to port_config Signed-off-by: vaibhav-dahiya --- .../sonic_py_common/device_info.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index 4d1c9f862953..eca8cd7ef059 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -1,4 +1,5 @@ import glob +import json import os import re import subprocess @@ -255,8 +256,21 @@ def get_path_to_port_config_file(hwsku=None, asic=None): # if 'hwsku.json' file is available, Check for 'platform.json' file presence, # if 'platform.json' is available, APPEND it. Otherwise, SKIP it. + + """ + This length check for interfaces in platform.json is performed to make sure + the cfggen does not fail if port configuration information is not present + TODO: once platform.json has all the necessary port config information + remove this check + """ + if os.path.isfile(hwsku_json_file): - port_config_candidates.append(os.path.join(platform_path, PLATFORM_JSON_FILE)) + if os.path.isfile(os.path.join(platform_path, PLATFORM_JSON_FILE)): + json_file = os.path.join(platform_path, PLATFORM_JSON_FILE) + platform_data = json.loads(open(json_file).read()) + interfaces = platform_data.get('interfaces', None) + if interfaces is not None and len(interfaces) > 0: + port_config_candidates.append(os.path.join(platform_path, PLATFORM_JSON_FILE)) # Check for 'port_config.ini' file presence in a few locations if asic: From 1e2e0199fab40a79815ab5d7aacca6053a6bf402 Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Wed, 14 Oct 2020 09:41:29 +0800 Subject: [PATCH 1234/1427] Remove exec mark of fancontrol.service for dx010 (#5588) --- .../sonic-platform-modules-cel/dx010/scripts/fancontrol.service | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service old mode 100755 new mode 100644 From 812e1a348941759a54c0ceaf86989a5fd1963c9c Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 13 Oct 2020 22:21:28 -0700 Subject: [PATCH 1235/1427] [bgp]: Enable next-hop-tracking through default (#5600) **- Why I did it** FRR introduced [next hop tracking](http://docs.frrouting.org/projects/dev-guide/en/latest/next-hop-tracking.html) functionality. That functionality requires resolving BGP neighbors before setting BGP connection (or explicit ebgp-multihop command). Sometimes (BGP MONITORS) our neighbors are not directly connected and sessions are IBGP. In this case current configuration prevents FRR to establish BGP connections. Reason would be "waiting for NHT". To fix that we need either add static routes for each not-directly connected ibgp neighbor, or enable command `ip nht resolve-via-default` **- How I did it** Put `ip nht resolve-via-default` into the config **- How to verify it** Build an image. Enable BGP_MONITOR entry and check that entry is Established or Connecting in FRR Co-authored-by: Pavel Shirshov --- dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 | 2 ++ src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf | 2 ++ src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf | 2 ++ src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf | 2 ++ src/sonic-config-engine/tests/sample_output/py2/frr.conf | 2 ++ .../tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf | 2 ++ .../tests/sample_output/py2/t2-chassis-fe-zebra.conf | 2 ++ src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf | 2 ++ src/sonic-config-engine/tests/sample_output/py3/frr.conf | 2 ++ .../tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf | 2 ++ .../tests/sample_output/py3/t2-chassis-fe-zebra.conf | 2 ++ src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf | 2 ++ .../tests/sample_output/t2-chassis-fe-pc-zebra.conf | 2 ++ 13 files changed, 26 insertions(+) diff --git a/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 index 7526239db8a6..57d83163d67b 100644 --- a/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 @@ -10,6 +10,8 @@ vni {{ vnet_metadata['vni'] }} {% endblock vrf %} ! {% block interfaces %} +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) {% for (name, prefix) in INTERFACE|pfx_filter %} interface {{ name }} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf index 1ed40fab744f..775861ef47c2 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf @@ -18,6 +18,8 @@ agentx ! ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface Ethernet4 link-detect diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf index 766509971224..1a49042fad34 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf @@ -1,5 +1,7 @@ ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface Ethernet4 link-detect diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf index 9f185edc2109..5bff88c711eb 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf @@ -22,6 +22,8 @@ vrf First vni 10 ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface Ethernet4 link-detect diff --git a/src/sonic-config-engine/tests/sample_output/py2/frr.conf b/src/sonic-config-engine/tests/sample_output/py2/frr.conf index 1df7344a9d92..08777924d14a 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/py2/frr.conf @@ -18,6 +18,8 @@ agentx ! ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface PortChannel03 link-detect diff --git a/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf index 653cc1510fb0..fb441f69f6f0 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf @@ -19,6 +19,8 @@ vrf VnetFE vni 9000 ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface Ethernet8 link-detect diff --git a/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-zebra.conf index a521da917d45..908280e2ddfa 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-zebra.conf @@ -19,6 +19,8 @@ vrf VnetFE vni 8000 ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface Ethernet8 link-detect diff --git a/src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf index ee48a4e53cae..4024f4b340e2 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf @@ -16,6 +16,8 @@ log facility local4 ! end of template: common/daemons.common.conf.j2! ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface PortChannel03 link-detect diff --git a/src/sonic-config-engine/tests/sample_output/py3/frr.conf b/src/sonic-config-engine/tests/sample_output/py3/frr.conf index 6e8573e9ba9d..374b3bf5f043 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/frr.conf @@ -18,6 +18,8 @@ agentx ! ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface PortChannel01 link-detect diff --git a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf index 180a0e9fab89..7b7987650d61 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf @@ -19,6 +19,8 @@ vrf VnetFE vni 9000 ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface Ethernet0 link-detect diff --git a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf index 661b27268255..fc8a8a2fb3bf 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf @@ -19,6 +19,8 @@ vrf VnetFE vni 8000 ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface Ethernet0 link-detect diff --git a/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf index e3d0c2d55bc3..f596c5579d3b 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf @@ -16,6 +16,8 @@ log facility local4 ! end of template: common/daemons.common.conf.j2! ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface PortChannel01 link-detect diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf index 312394bf76c9..be261bab99a8 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf @@ -12,6 +12,8 @@ vrf VnetFE vni 8000 ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface PortChannel0 link-detect From 9094e2176f226cc1bc7c2276c54ab100053c40e2 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 14 Oct 2020 08:05:33 -0700 Subject: [PATCH 1236/1427] Optimze ACL Table/Rule notification handling (#5621) * Optimze ACL Table/Rule notifcation handling to loop pop() until empty to consume all the data in a batch This wau we prevent multiple call to iptable updates Signed-off-by: Abhishek Dosi * Address review comments Signed-off-by: Abhishek Dosi --- files/image_config/caclmgrd/caclmgrd | 37 ++++++++++++++-------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index a199f4753ecb..cee0d8f96ceb 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -539,7 +539,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): # Loop on select to see if any event happen on config db of any namespace while True: - ctrl_plane_acl_notification = False + ctrl_plane_acl_notification = set() (state, selectableObj) = sel.select(SELECT_TIMEOUT_MS) # Continue if select is timeout or selectable object is not return if state != swsscommon.Select.OBJECT: @@ -550,23 +550,24 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): namespace = redisSelectObj.getDbConnector().getNamespace() # Pop data of both Subscriber Table object of namespace that got config db acl table event for table in config_db_subscriber_table_map[namespace]: - (key, op, fvp) = table.pop() - # Pop of table that does not have data - if key == '': - continue - # ACL Table notification. We will take Control Plane ACTION for any ACL Table Event - # This can be optimize further but we should not have many acl table set/del events in normal - # scenario - elif acl_rule_table_seprator not in key: - ctrl_plane_acl_notification = True - # Check ACL Rule notification and make sure Rule point to ACL Table which is Controlplane - else: - acl_table = key.split(acl_rule_table_seprator)[0] - if self.config_db_map[namespace].get_table(self.ACL_TABLE)[acl_table]["type"] == self.ACL_TABLE_TYPE_CTRLPLANE: - ctrl_plane_acl_notification = True - - # Update the Control Plane ACL of the namespace that got config db acl table/rule event - if ctrl_plane_acl_notification: + while True: + (key, op, fvp) = table.pop() + # Pop of table that does not have data so break + if key == '': + break + # ACL Table notification. We will take Control Plane ACTION for any ACL Table Event + # This can be optimize further but we should not have many acl table set/del events in normal + # scenario + if acl_rule_table_seprator not in key: + ctrl_plane_acl_notification.add(namespace) + # Check ACL Rule notification and make sure Rule point to ACL Table which is Controlplane + else: + acl_table = key.split(acl_rule_table_seprator)[0] + if self.config_db_map[namespace].get_table(self.ACL_TABLE)[acl_table]["type"] == self.ACL_TABLE_TYPE_CTRLPLANE: + ctrl_plane_acl_notification.add(namespace) + + # Update the Control Plane ACL of the namespace that got config db acl table event + for namespace in ctrl_plane_acl_notification: self.update_control_plane_acls(namespace) # ============================= Functions ============================= From 0155a1581325c60a06ef0e8765e6a5baa7e1f796 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 14 Oct 2020 18:58:50 +0300 Subject: [PATCH 1237/1427] [submodule]: Advance swss submodule. (#5611) - [portsorch]: Set proper initial forwarding state for LAG member #1448 Signed-off-by: Nazarii Hnydyn --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index e4dfb3756e43..7880c7eb7fbe 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit e4dfb3756e4332f90faed3ee0f82c9ad05ba38ce +Subproject commit 7880c7eb7fbe027d3d04bab0f8303a100f825248 From 88c1d66c27b4df76835c74844feebaca29dcee35 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 14 Oct 2020 10:16:35 -0700 Subject: [PATCH 1238/1427] [python-click] No longer build our own package, let pip/setuptools install vanilla (#5549) We were building our own python-click package because we needed features/bug fixes available as of version 7.0.0, but the most recent version available from Debian was in the 6.x range. "Click" is needed for building/testing and installing sonic-utilities. Now that we are building sonic-utilities as a wheel, with Click specified as a dependency in the setup.py file, setuptools will install a more recent version of Click in the sonic-slave-buster container when building the package, and pip will install a more recent version of Click in the host OS of SONiC when installing the sonic-utilities package. Also, we don't need to worry about installing the Python 2 or 3 version of the package, as the proper one will be installed as necessary. --- .../docker-config-engine-buster/Dockerfile.j2 | 1 - .../Dockerfile.j2 | 1 - dockers/docker-config-engine/Dockerfile.j2 | 2 +- .../build_templates/sonic_debian_extension.j2 | 16 ++++++------ platform/p4/docker-sonic-p4/Dockerfile.j2 | 16 +++++++++--- platform/vs/docker-sonic-vs/Dockerfile.j2 | 17 ++++++++---- rules/python-click.dep | 10 ------- rules/python-click.mk | 16 ------------ sonic-slave-buster/Dockerfile.j2 | 20 +++----------- sonic-slave-jessie/Dockerfile.j2 | 13 ---------- sonic-slave-stretch/Dockerfile.j2 | 15 ----------- src/python-click/.gitignore | 3 --- src/python-click/Makefile | 26 ------------------- src/sonic-py-common/setup.py | 5 ++-- 14 files changed, 40 insertions(+), 121 deletions(-) delete mode 100644 rules/python-click.dep delete mode 100644 rules/python-click.mk delete mode 100644 src/python-click/.gitignore delete mode 100644 src/python-click/Makefile diff --git a/dockers/docker-config-engine-buster/Dockerfile.j2 b/dockers/docker-config-engine-buster/Dockerfile.j2 index e24414a0fc26..d48cb33d157e 100644 --- a/dockers/docker-config-engine-buster/Dockerfile.j2 +++ b/dockers/docker-config-engine-buster/Dockerfile.j2 @@ -12,7 +12,6 @@ RUN apt-get update && \ python-bitarray \ python-pip \ python-dev \ - python-natsort \ apt-utils \ python-setuptools diff --git a/dockers/docker-config-engine-stretch/Dockerfile.j2 b/dockers/docker-config-engine-stretch/Dockerfile.j2 index 8b958b8f4f59..eec55982f5a7 100644 --- a/dockers/docker-config-engine-stretch/Dockerfile.j2 +++ b/dockers/docker-config-engine-stretch/Dockerfile.j2 @@ -12,7 +12,6 @@ RUN apt-get update && \ python-bitarray \ python-pip \ python-dev \ - python-natsort \ python-setuptools RUN pip install --upgrade pip diff --git a/dockers/docker-config-engine/Dockerfile.j2 b/dockers/docker-config-engine/Dockerfile.j2 index ba72cce31d47..e681ba1839bd 100644 --- a/dockers/docker-config-engine/Dockerfile.j2 +++ b/dockers/docker-config-engine/Dockerfile.j2 @@ -6,7 +6,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update # Dependencies for sonic-cfggen -RUN apt-get install -y python-lxml python-yaml python-bitarray python-pip python-dev python-natsort +RUN apt-get install -y python-lxml python-yaml python-bitarray python-pip python-dev RUN pip install --upgrade pip diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 390f042c7b91..2a5d9049ca29 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -93,6 +93,7 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/iptables_*.deb || \ # Install dependencies for SONiC config engine sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ python-dev \ + python3-dev \ python-lxml \ python-yaml \ python-bitarray @@ -184,14 +185,12 @@ sudo cp {{platform_common_py3_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY3 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $PLATFORM_COMMON_PY3_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY3_WHEEL_NAME -# Install Debian packages and their dependencies which are needed by sonic-utilities -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f python-m2crypto +# Install prerequisites needed for installing the Python m2crypto package, used by sonic-utilities +# These packages can be uninstalled after intallation +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install build-essential libssl-dev swig -# Install built Python Click package (and its dependencies via 'apt-get -y install -f') -# Do this before installing sonic-utilities so that it doesn't attempt to install -# an older version as part of its dependencies -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python-click*_all.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +# Install prerequisites needed for using the Python m2crypto package, used by sonic-utilities +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install openssl # Install SONiC Utilities Python 2 package SONIC_UTILITIES_PY2_WHEEL_NAME=$(basename {{sonic_utilities_py2_wheel_path}}) @@ -574,7 +573,8 @@ sudo cp $BUILD_TEMPLATES/mgmt-framework.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_S echo "mgmt-framework.timer" | sudo tee -a $GENERATED_SERVICE_FILE {% endif %} -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-dev +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-dev python3-dev +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y build-essential libssl-dev swig sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get clean -y sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get autoremove -y diff --git a/platform/p4/docker-sonic-p4/Dockerfile.j2 b/platform/p4/docker-sonic-p4/Dockerfile.j2 index b4d6b23b9201..90ff15472248 100644 --- a/platform/p4/docker-sonic-p4/Dockerfile.j2 +++ b/platform/p4/docker-sonic-p4/Dockerfile.j2 @@ -40,12 +40,18 @@ RUN apt-get install -y net-tools \ iproute \ libpython2.7 \ grub2-common \ - python-click \ - python-natsort \ - python-tabulate \ bash-completion \ libelf1 \ - libmnl0 + libmnl0 \ + # For installing Python m2crypto package + # (these can be uninstalled after installation) + build-essential \ + python-dev \ + python3-dev \ + libssl-dev \ + swig \ + # For using Python m2crypto package + openssl RUN pip install setuptools RUN pip install py2_ipaddress @@ -62,6 +68,8 @@ debs/{{ deb }}{{' '}} {%- endfor %} ## Clean up +RUN apt-get purge -y build-essential libssl-dev swig +RUN apt-get purge -y python-dev python3-dev RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 55c68a049ae1..9a9b7889382d 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -32,9 +32,6 @@ RUN apt-get install -y net-tools \ libc-ares2 \ iproute2 \ grub2-common \ - python-click \ - python-natsort \ - python-tabulate \ bash-completion \ libelf1 \ libmnl0 \ @@ -47,8 +44,16 @@ RUN apt-get install -y net-tools \ iptables \ python3-pip \ jq \ - python-m2crypto \ - libzmq5 + libzmq5 \ + # For installing Python m2crypto package + # (these can be uninstalled after installation) + build-essential \ + python-dev \ + python3-dev \ + libssl-dev \ + swig \ + # For using Python m2crypto package + openssl # install redis-server RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" @@ -111,6 +116,8 @@ RUN pip{% if 'py3' in whl %}3{% endif %} install python-wheels/{{ whl }} {% endif %} # Clean up +RUN apt-get purge -y build-essential libssl-dev swig +RUN apt-get purge -y python-dev python3-dev RUN apt-get clean -y RUN apt-get autoclean -y RUN apt-get autoremove -y diff --git a/rules/python-click.dep b/rules/python-click.dep deleted file mode 100644 index 93e75a71efb1..000000000000 --- a/rules/python-click.dep +++ /dev/null @@ -1,10 +0,0 @@ - -SPATH := $($(PYTHON_CLICK)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/python-click.mk rules/python-click.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(SPATH)) - -$(PYTHON_CLICK)_CACHE_MODE := GIT_CONTENT_SHA -$(PYTHON_CLICK)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(PYTHON_CLICK)_DEP_FILES := $(DEP_FILES) - diff --git a/rules/python-click.mk b/rules/python-click.mk deleted file mode 100644 index 59e22b371159..000000000000 --- a/rules/python-click.mk +++ /dev/null @@ -1,16 +0,0 @@ -# python-click package -# -# Python Click versions < 6.7 have a bug which causes bash completion -# functionality to stop working after two sublevels. sonic-utilities depends -# on this package, and the most recent version provided by Debian Jessie and -# Stretch is v6.6. We build version 6.7 from source in order to fix this bug. -# TODO: If we upgrade to a distro which provides a version >= 6.7 we will no -# longer need to build this. - -PYTHON_CLICK_VERSION = 7.0-1 - -export PYTHON_CLICK_VERSION - -PYTHON_CLICK = python-click_$(PYTHON_CLICK_VERSION)_all.deb -$(PYTHON_CLICK)_SRC_PATH = $(SRC_PATH)/python-click -SONIC_MAKE_DEBS += $(PYTHON_CLICK) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 34ef905a7752..6b6902153bef 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -270,17 +270,6 @@ RUN apt-get update && apt-get install -y \ texlive-latex-extra \ texlive-latex-recommended \ iproute2 \ -# For python-click build - python-sphinx \ - python3-pallets-sphinx-themes \ - python-docutils \ - python3-all \ - python3-setuptools \ - python3-sphinx \ - python3-docutils \ - python3-requests \ - python3-pytest \ - python3-colorama \ # For bash texi2html \ # For initramfs @@ -349,6 +338,10 @@ RUN export VERSION=1.14.2 \ RUN pip install setuptools==40.8.0 RUN pip3 install setuptools==49.6.00 +# For building sonic-utilities +RUN pip install fastentrypoints +RUN pip3 install fastentrypoints + # For running Python unit tests RUN pip install pytest-runner==4.4 RUN pip3 install pytest-runner==5.2 @@ -375,11 +368,6 @@ RUN pip3 uninstall -y enum34 # For templating RUN pip install j2cli==0.3.10 -# Remove python-click 6.6 -RUN apt-get purge -y python-click -# For sonic utilities testing -RUN pip install click natsort tabulate netifaces==0.10.7 fastentrypoints - RUN pip3 install "PyYAML>=5.1" # For sonic-platform-common testing diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index 2df3828c4096..32db448de25e 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -246,16 +246,6 @@ RUN apt-get update && apt-get install -y \ lynx \ texlive-latex-extra \ texlive-latex-recommended \ -# For python-click build - python-sphinx \ - python-docutils \ - python3-all \ - python3-setuptools \ - python3-sphinx \ - python3-docutils \ - python3-requests \ - python3-pytest \ - python3-colorama \ # For bash texi2html \ # For initramfs @@ -310,9 +300,6 @@ RUN pip install --force-reinstall --upgrade "jinja2>=2.10" # For templating (requiring jinja2) RUN pip install j2cli==0.3.10 -# For sonic utilities testing -RUN pip install click natsort tabulate netifaces==0.10.7 fastentrypoints - # For supervisor build RUN pip install meld3 mock diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 54cf2c890021..00935b33f18d 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -266,16 +266,6 @@ RUN apt-get update && apt-get install -y \ texlive-latex-extra \ texlive-latex-recommended \ iproute2 \ -# For python-click build - python-sphinx \ - python-docutils \ - python3-all \ - python3-setuptools \ - python3-sphinx \ - python3-docutils \ - python3-requests \ - python3-pytest \ - python3-colorama \ # For bash texi2html \ # For initramfs @@ -358,11 +348,6 @@ RUN pip3 uninstall -y enum34 # For templating RUN pip install j2cli==0.3.10 -# Remove python-click 6.6 -RUN apt-get purge -y python-click -# For sonic utilities testing -RUN pip install click natsort tabulate netifaces==0.10.7 fastentrypoints - # For sonic snmpagent mock testing RUN pip3 install mockredispy==2.9.3 diff --git a/src/python-click/.gitignore b/src/python-click/.gitignore deleted file mode 100644 index a0991ff4402b..000000000000 --- a/src/python-click/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -* -!.gitignore -!Makefile diff --git a/src/python-click/Makefile b/src/python-click/Makefile deleted file mode 100644 index 4deb27257fd2..000000000000 --- a/src/python-click/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -.ONESHELL: -SHELL = /bin/bash -.SHELLFLAGS += -e - -MAIN_TARGET = python-click_$(PYTHON_CLICK_VERSION)_all.deb - -$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : - # Remove any stale files - rm -rf ./python-click - - # Clone python-click Debian repo - git clone https://salsa.debian.org/debian/python-click - - pushd ./python-click - - # Reset HEAD to the commit of the proper tag - # NOTE: Using "git checkout " here detaches our HEAD, - # which stg doesn't like, so we use this method instead - git reset --hard debian/$(PYTHON_CLICK_VERSION) - - # Build source and Debian packages - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) - popd - - # Move the newly-built .deb package to the destination directory - mv $* $(DEST)/ diff --git a/src/sonic-py-common/setup.py b/src/sonic-py-common/setup.py index f56ad96b04fd..bed64fe7fd22 100644 --- a/src/sonic-py-common/setup.py +++ b/src/sonic-py-common/setup.py @@ -1,7 +1,7 @@ from setuptools import setup dependencies = [ - 'natsort', + 'natsort==6.2.1', # 6.2.1 is the last version which supports Python 2 'pyyaml', 'swsssdk>=2.0.1', ] @@ -28,7 +28,8 @@ 'sonic_py_common', ], setup_requires= [ - 'pytest-runner' + 'pytest-runner', + 'wheel' ], tests_require=[ 'pytest', From a5adb577f3787691b62e33d26dfade0c81983518 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 14 Oct 2020 10:54:24 -0700 Subject: [PATCH 1239/1427] [sonic-snmpagent]: Advance submodule (#5614) 6e4a796 2020-10-12 | Fix: correctly handle that lldp_loc_man_addr contains only IPv6 address without IPv4 address (#164) [Qi Luo] 0f772ce 2020-09-28 | [ciscoSwitchQosMIB]: Remove invocation of update_data function during (#161) [SuvarnaMeenakshi] --- src/sonic-snmpagent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 51b09a8afe83..6e4a796b245a 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 51b09a8afe833443aca0fecd86962c2338b38c0d +Subproject commit 6e4a796b245a99da29f8390fe01d09a37d32ec4f From 8b135afb52658e0644fb321be0dabc7bbb6304b4 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Wed, 14 Oct 2020 21:35:36 +0300 Subject: [PATCH 1240/1427] [barefoot][platform] Platform API fixups (#5613) Signed-off-by: Volodymyr Boyko --- .../sonic_platform/__init__.py | 2 +- .../sonic-platform-modules-bfn-montara/sonic_platform/sfp.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py index ef4108ee54e5..d5f19f74f4c6 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py @@ -1,2 +1,2 @@ __all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp'] -import platform +from . import platform diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py index 12587c66f474..dc57dbcd9040 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py @@ -4,6 +4,7 @@ import os import sys import time + import errno sys.path.append(os.path.dirname(__file__)) From a2e3d2fceac579e25602c41a331e8059f3083be2 Mon Sep 17 00:00:00 2001 From: BrynXu Date: Wed, 14 Oct 2020 15:15:24 -0700 Subject: [PATCH 1241/1427] [ChassisDB]: bring up ChassisDB service (#5283) bring up chassisdb service on sonic switch according to the design in Distributed Forwarding in VoQ Arch HLD Signed-off-by: Honggang Xu **- Why I did it** To bring up new ChassisDB service in sonic as designed in ['Distributed forwarding in a VOQ architecture HLD' ](https://github.com/Azure/SONiC/blob/90c1289eaf89a70939e7c81e042e261947c6a850/doc/chassis/architecture.md). **- How I did it** Implement the section 2.3.1 Global DB Organization of the VOQ architecture HLD. **- How to verify it** ChassisDB service won't start without chassisdb.conf file on the existing platforms. ChassisDB service is accessible with global.conf file in the distributed arichitecture. Signed-off-by: Honggang Xu --- .../x86_64-arista_7800_sup/chassisdb.conf | 2 + .../chassisdb.conf | 1 + dockers/docker-database/Dockerfile.j2 | 1 + .../docker-database/database_config.json.j2 | 11 ++ .../docker-database/docker-database-init.sh | 44 ++++- dockers/docker-database/supervisord.conf.j2 | 2 +- .../config-chassisdb.service.j2 | 12 ++ files/build_templates/docker_image_ctl.j2 | 184 +++++++++++------- .../per_namespace/database.service.j2 | 2 + .../share_image/database.service.j2 | 20 ++ .../build_templates/sonic_debian_extension.j2 | 6 + .../config-chassisdb/config-chassisdb | 59 ++++++ files/scripts/remove_chassisdb_config | 40 ---- files/scripts/update_chassisdb_config | 67 +++++++ platform/vs/docker-sonic-vs.mk | 2 +- platform/vs/docker-sonic-vs/Dockerfile.j2 | 2 +- platform/vs/docker-sonic-vs/chassis_db.py | 4 +- .../vs/docker-sonic-vs/database_config.json | 2 +- platform/vs/docker-sonic-vs/start.sh | 16 +- rules/docker-database.mk | 1 + rules/scripts.mk | 6 +- slave.mk | 12 ++ 22 files changed, 367 insertions(+), 129 deletions(-) create mode 100644 device/arista/x86_64-arista_7800_sup/chassisdb.conf create mode 100644 device/arista/x86_64-arista_7800r3_48cq2_lc/chassisdb.conf create mode 100644 files/build_templates/config-chassisdb.service.j2 create mode 100644 files/build_templates/share_image/database.service.j2 create mode 100755 files/image_config/config-chassisdb/config-chassisdb delete mode 100755 files/scripts/remove_chassisdb_config create mode 100755 files/scripts/update_chassisdb_config diff --git a/device/arista/x86_64-arista_7800_sup/chassisdb.conf b/device/arista/x86_64-arista_7800_sup/chassisdb.conf new file mode 100644 index 000000000000..3918a00c4ee9 --- /dev/null +++ b/device/arista/x86_64-arista_7800_sup/chassisdb.conf @@ -0,0 +1,2 @@ +start_chassis_db=1 +chassis_db_address=127.100.1.1 diff --git a/device/arista/x86_64-arista_7800r3_48cq2_lc/chassisdb.conf b/device/arista/x86_64-arista_7800r3_48cq2_lc/chassisdb.conf new file mode 100644 index 000000000000..75dc7d65703b --- /dev/null +++ b/device/arista/x86_64-arista_7800r3_48cq2_lc/chassisdb.conf @@ -0,0 +1 @@ +chassis_db_address=127.100.1.1 diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index fcfb3b620c25..aeaa61614406 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -45,5 +45,6 @@ COPY ["database_global.json.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["files/sysctl-net.conf", "/etc/sysctl.d/"] COPY ["critical_processes", "/etc/supervisor"] +COPY ["files/update_chassisdb_config", "/usr/local/bin/"] ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"] diff --git a/dockers/docker-database/database_config.json.j2 b/dockers/docker-database/database_config.json.j2 index a24252ed810d..5e3096eaac1c 100644 --- a/dockers/docker-database/database_config.json.j2 +++ b/dockers/docker-database/database_config.json.j2 @@ -5,6 +5,12 @@ "port" : 6379, "unix_socket_path" : "/var/run/redis{{NAMESPACE_ID}}/redis.sock", "persistence_for_warm_boot" : "yes" + }, + "redis_chassis":{ + "hostname" : "redis_chassis.server", + "port": 6380, + "unix_socket_path": "/var/run/redis-chassis/redis_chassis.sock", + "persistence_for_warm_boot" : "yes" } }, "DATABASES" : { @@ -72,6 +78,11 @@ "id" : 11, "separator": "|", "instance" : "redis" + }, + "CHASSIS_APP_DB" : { + "id" : 12, + "separator": "|", + "instance" : "redis_chassis" } }, "VERSION" : "1.0" diff --git a/dockers/docker-database/docker-database-init.sh b/dockers/docker-database/docker-database-init.sh index 645a7d99272a..babb9f7924a0 100755 --- a/dockers/docker-database/docker-database-init.sh +++ b/dockers/docker-database/docker-database-init.sh @@ -19,6 +19,7 @@ fi REDIS_DIR=/var/run/redis$NAMESPACE_ID mkdir -p $REDIS_DIR/sonic-db +mkdir -p /etc/supervisor/conf.d/ if [ -f /etc/sonic/database_config$NAMESPACE_ID.json ]; then cp /etc/sonic/database_config$NAMESPACE_ID.json $REDIS_DIR/sonic-db/database_config.json @@ -26,7 +27,37 @@ else HOST_IP=$host_ip j2 /usr/share/sonic/templates/database_config.json.j2 > $REDIS_DIR/sonic-db/database_config.json fi -mkdir -p /etc/supervisor/conf.d/ +# on VoQ system, we only publish redis_chassis instance and CHASSIS_APP_DB when +# either chassisdb.conf indicates starts chassis_db or connect to chassis_db, +# and redis_chassis instance is started in different container. +# in order to do that, first we save original database config file, then +# call update_chasissdb_config to remove chassis_db config from +# the original database config file and use the modified config file to generate +# supervisord config, so that we won't start redis_chassis service. +# then we will decide to publish modified or original database config file based +# on the setting in chassisdb.conf +start_chassis_db=0 +chassis_db_address="" +chassis_db_port="" +chassisdb_config="/etc/sonic/chassisdb.conf" +[ -f $chassisdb_config ] && source $chassisdb_config + +db_cfg_file="/var/run/redis/sonic-db/database_config.json" +db_cfg_file_tmp="/var/run/redis/sonic-db/database_config.json.tmp" +cp $db_cfg_file $db_cfg_file_tmp + +if [[ $DATABASE_TYPE == "chassisdb" ]]; then + # Docker init for database-chassis + echo "Init docker-database-chassis..." + update_chassisdb_config -j $db_cfg_file_tmp -k -p $chassis_db_port + mkdir -p /var/run/redis/sonic-db + cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db + # generate all redis server supervisord configuration file + sonic-cfggen -j $db_cfg_file_tmp -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf + rm $db_cfg_file_tmp + exec /usr/bin/supervisord + exit 0 +fi # copy/generate the database_global.json file if this is global database service in multi asic platform. if [[ $NAMESPACE_ID == "" ]] && [[ $NAMESPACE_COUNT -gt 1 ]] @@ -37,8 +68,15 @@ then j2 /usr/share/sonic/templates/database_global.json.j2 > $REDIS_DIR/sonic-db/database_global.json fi fi +# delete chassisdb config to generate supervisord config +update_chassisdb_config -j $db_cfg_file_tmp -d +sonic-cfggen -j $db_cfg_file_tmp -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf -# generate all redis server supervisord configuration file -sonic-cfggen -j /var/run/redis/sonic-db/database_config.json -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf +if [[ "$start_chassis_db" != "1" ]] && [[ -z "$chassis_db_address" ]]; then + cp $db_cfg_file_tmp $db_cfg_file +else + update_chassisdb_config -j $db_cfg_file -p $chassis_db_port +fi +rm $db_cfg_file_tmp exec /usr/bin/supervisord diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index 6d4557dab705..97b8a4822530 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -20,7 +20,7 @@ stderr_logfile=syslog {% if INSTANCES %} {% for redis_inst, redis_items in INSTANCES.iteritems() %} [program: {{ redis_inst }}] -{% if redis_items['hostname'] != '127.0.0.1' %} +{% if redis_items['hostname'] != '127.0.0.1' and redis_inst != 'redis_chassis' %} {%- set LOOPBACK_IP = '127.0.0.1' -%} {%- else -%} {%- set LOOPBACK_IP = '' -%} diff --git a/files/build_templates/config-chassisdb.service.j2 b/files/build_templates/config-chassisdb.service.j2 new file mode 100644 index 000000000000..a50d0de72fb1 --- /dev/null +++ b/files/build_templates/config-chassisdb.service.j2 @@ -0,0 +1,12 @@ +[Unit] +Description=Config chassis_db +After=rc-local.service +Requires=rc-local.service + +[Service] +Type=oneshot +ExecStart=/usr/bin/config-chassisdb +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 71decb3fa906..4d3e795c500e 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -12,7 +12,7 @@ link_namespace() { # /var/run/netns so it can be managed with iproute2 mkdir -p /var/run/netns - PID="$(docker inspect -f {{"'{{.State.Pid}}'"}} "{{docker_container_name}}$DEV")" + PID="$(docker inspect -f {{"'{{.State.Pid}}'"}} "${DOCKERNAME}")" PIDS=`ip netns pids "$NET_NS" 2>/dev/null` if [ "$?" -eq "0" ]; then # namespace exists @@ -34,11 +34,11 @@ function updateSyslogConf() # Also update the container name if [[ ($NUM_ASIC -gt 1) ]]; then TARGET_IP=$(docker network inspect bridge --format={{ "'{{(index .IPAM.Config 0).Gateway}}'" }}) - CONTAINER_NAME="{{docker_container_name}}$DEV" + CONTAINER_NAME="$DOCKERNAME" TMP_FILE="/tmp/rsyslog.$CONTAINER_NAME.conf" sonic-cfggen -t /usr/share/sonic/templates/rsyslog-container.conf.j2 -a "{\"target_ip\": \"$TARGET_IP\", \"container_name\": \"$CONTAINER_NAME\" }" > $TMP_FILE - docker cp $TMP_FILE {{docker_container_name}}$DEV:/etc/rsyslog.conf + docker cp $TMP_FILE ${DOCKERNAME}:/etc/rsyslog.conf rm -rf $TMP_FILE fi } @@ -71,13 +71,15 @@ function preStartAction() { {%- if docker_container_name == "database" %} WARM_DIR=/host/warmboot - if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then - # Load redis content from /host/warmboot/dump.rdb - docker cp $WARM_DIR/dump.rdb database$DEV:/var/lib/redis/dump.rdb - else - # Create an emtpy file and overwrite any RDB if already there - echo -n > /tmp/dump.rdb - docker cp /tmp/dump.rdb database$DEV:/var/lib/redis/ + if [ "$DATABASE_TYPE" != "chassisdb" ]; then + if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then + # Load redis content from /host/warmboot/dump.rdb + docker cp $WARM_DIR/dump.rdb database$DEV:/var/lib/redis/dump.rdb + else + # Create an emtpy file and overwrite any RDB if already there + echo -n > /tmp/dump.rdb + docker cp /tmp/dump.rdb database$DEV:/var/lib/redis/ + fi fi {%- elif docker_container_name == "snmp" %} $SONIC_DB_CLI STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) @@ -99,44 +101,51 @@ function postStartAction() link_namespace $DEV fi - # Wait until supervisord and redis starts. This change is needed - # because now database_config.json is jinja2 templated based - # and by the time file gets generated if we do redis ping - # then we catch python exception of file not valid - # that comes to syslog which is unwanted so wait till database - # config is ready and then ping - until [[ ($(docker exec -i database$DEV pgrep -x -c supervisord) -gt 0) && ($($SONIC_DB_CLI PING | grep -c PONG) -gt 0) ]]; do - sleep 1; - done - - if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then - rm -f $WARM_DIR/dump.rdb - else - # If there is a config_db.json dump file, load it. - if [ -r /etc/sonic/config_db$DEV.json ]; then - if [ -r /etc/sonic/init_cfg.json ]; then - $SONIC_CFGGEN -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db$DEV.json --write-to-db - else - $SONIC_CFGGEN -j /etc/sonic/config_db$DEV.json --write-to-db + # chassisdb starts before database starts, bypass the PING check since other + # databases are not availbale until database container is ready. + # also chassisdb doesn't support warm/fast reboot, its dump.rdb is deleted + # at service startup time, nothing need to be done here. + if [ "$DATABASE_TYPE" != "chassisdb" ]; then + # Wait until supervisord and redis starts. This change is needed + # because now database_config.json is jinja2 templated based + # and by the time file gets generated if we do redis ping + # then we catch python exception of file not valid + # that comes to syslog which is unwanted so wait till database + # config is ready and then ping + until [[ ($(docker exec -i database$DEV pgrep -x -c supervisord) -gt 0) && ($($SONIC_DB_CLI PING | grep -c PONG) -gt 0) ]]; do + sleep 1; + done + if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then + rm -f $WARM_DIR/dump.rdb + else + # If there is a config_db.json dump file, load it. + if [ -r /etc/sonic/config_db$DEV.json ]; then + if [ -r /etc/sonic/init_cfg.json ]; then + $SONIC_CFGGEN -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db$DEV.json --write-to-db + else + $SONIC_CFGGEN -j /etc/sonic/config_db$DEV.json --write-to-db + fi fi - fi - if [[ "$BOOT_TYPE" == "fast" ]]; then - # set the key to expire in 3 minutes - $SONIC_DB_CLI STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" - fi + if [[ "$BOOT_TYPE" == "fast" ]]; then + # set the key to expire in 3 minutes + $SONIC_DB_CLI STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" + fi - $SONIC_DB_CLI CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" - fi + $SONIC_DB_CLI CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + fi - if [[ -x /usr/local/bin/db_migrator.py ]]; then - # Migrate the DB to the latest schema version if needed - if [ -z "$DEV" ]; then - /usr/local/bin/db_migrator.py -o migrate + if [[ -x /usr/local/bin/db_migrator.py ]]; then + # Migrate the DB to the latest schema version if needed + if [ -z "$DEV" ]; then + /usr/bin/db_migrator.py -o migrate + fi fi + # Add redis UDS to the redis group and give read/write access to the group + REDIS_SOCK="/var/run/redis${DEV}/redis.sock" + else + REDIS_SOCK="/var/run/redis-chassis/redis_chassis.sock" fi - # Add redis UDS to the redis group and give read/write access to the group - REDIS_SOCK="/var/run/redis${DEV}/redis.sock" chgrp -f redis $REDIS_SOCK && chmod -f 0760 $REDIS_SOCK {%- elif docker_container_name == "swss" %} docker exec swss$DEV rm -f /ready # remove cruft @@ -170,6 +179,7 @@ start() { # Obtain our platform as we will mount directories with these names in each docker PLATFORM=${PLATFORM:-`$SONIC_CFGGEN -H -v DEVICE_METADATA.localhost.platform`} + # Parse the device specific asic conf file, if it exists ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf if [ -f "$ASIC_CONF" ]; then @@ -183,8 +193,7 @@ start() { # Obtain our HWSKU as we will mount directories with these names in each docker HWSKU=${HWSKU:-`$SONIC_CFGGEN -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'`} {%- endif %} - - DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` + DOCKERCHECK=`docker inspect --type container ${DOCKERNAME} 2>/dev/null` if [ "$?" -eq "0" ]; then {%- if docker_container_name == "database" %} DOCKERMOUNT="" @@ -193,37 +202,40 @@ start() { {%- endif %} if [ x"$DOCKERMOUNT" == x"$HWSKU" ]; then {%- if docker_container_name == "database" %} - echo "Starting existing {{docker_container_name}}$DEV container" + echo "Starting existing ${DOCKERNAME} container" {%- else %} - echo "Starting existing {{docker_container_name}}$DEV container with HWSKU $HWSKU" + echo "Starting existing ${DOCKERNAME} container with HWSKU $HWSKU" {%- endif %} preStartAction - docker start {{docker_container_name}}$DEV + docker start ${DOCKERNAME} postStartAction exit $? fi # docker created with a different HWSKU, remove and recreate - echo "Removing obsolete {{docker_container_name}}$DEV container with HWSKU $DOCKERMOUNT" - docker rm -f {{docker_container_name}}$DEV + echo "Removing obsolete ${DOCKERNAME} container with HWSKU $DOCKERMOUNT" + docker rm -f ${DOCKERNAME} fi {%- if docker_container_name == "database" %} - echo "Creating new {{docker_container_name}}$DEV container" - if [ -z "$DEV" ]; then - # if database_global exists in old_config, use it; otherwise use the default one in new image - if [ -f /etc/sonic/old_config/database_global.json ]; then - echo "Use database_global.json from old system..." - mv /etc/sonic/old_config/database_global.json /etc/sonic/ + + echo "Creating new ${DOCKERNAME} container" + if [ "$DATABASE_TYPE" != "chassisdb" ]; then + if [ -z "$DEV" ]; then + # if database_global exists in old_config, use it; otherwise use the default one in new image + if [ -f /etc/sonic/old_config/database_global.json ]; then + echo "Use database_global.json from old system..." + mv /etc/sonic/old_config/database_global.json /etc/sonic/ + fi + fi + # if database_config exists in old_config, use it; otherwise use the default one in new image + if [ -f /etc/sonic/old_config/database_config$DEV.json ]; then + echo "Use database_config.json from old system..." + mv /etc/sonic/old_config/database_config$DEV.json /etc/sonic/ fi - fi - # if database_config exists in old_config, use it; otherwise use the default one in new image - if [ -f /etc/sonic/old_config/database_config$DEV.json ]; then - echo "Use database_config.json from old system..." - mv /etc/sonic/old_config/database_config$DEV.json /etc/sonic/ fi {%- else %} - echo "Creating new {{docker_container_name}}$DEV container with HWSKU $HWSKU" + echo "Creating new ${DOCKERNAME} container with HWSKU $HWSKU" {%- endif %} # In Multi ASIC platforms the global database config file database_global.json will exist. @@ -238,6 +250,19 @@ start() { for elem in data['INCLUDES'] if 'namespace' in elem])); f.close()" $SONIC_DB_GLOBAL_JSON` fi + {%- if docker_container_name == "database" %} + start_chassis_db=0 + chassis_db_address="" + chassisdb_config="/etc/sonic/chassisdb.conf" + [ -f $chassisdb_config ] && source $chassisdb_config + DB_OPT=" -v /var/run/redis-chassis:/var/run/redis-chassis:ro " + if [[ "$start_chassis_db" != "1" ]] && [[ -z "$chassis_db_address" ]]; then + DB_OPT="" + else + DB_OPT=$DB_OPT" --add-host=redis_chassis.server:$chassis_db_address " + fi + {%- endif %} + if [ -z "$DEV" ]; then NET="host" @@ -256,6 +281,14 @@ start() { REDIS_MNT=$REDIS_MNT" -v $redis_dir:$redis_dir:rw " done fi + {%- else %} + if [ "$DATABASE_TYPE" == "chassisdb" ]; then + DB_OPT=${DB_OPT/redis-chassis:ro/redis-chassis:rw} + DB_OPT=$DB_OPT" -v /var/run/redis-chassis:/var/run/redis:rw " + DB_OPT=$DB_OPT" --env DATABASE_TYPE=$DATABASE_TYPE" + else + DB_OPT=$DB_OPT" -v /var/run/redis$DEV:/var/run/redis:rw " + fi {%- endif %} else # This part of code is applicable for Multi-ASIC platforms. Here we mount the namespace specific @@ -269,9 +302,10 @@ start() { fi {%- if docker_container_name == "database" %} - NET="bridge" + DB_OPT=$DB_OPT" -v /var/run/redis$DEV:/var/run/redis:rw " {%- else %} NET="container:database$DEV" + DB_OPT="" {%- endif %} fi {%- if docker_container_name == "bgp" %} @@ -319,12 +353,15 @@ start() { {%- if docker_container_name == "bgp" %} -v /etc/sonic/frr/$DEV:/etc/frr:rw \ {%- endif %} +{%- if docker_container_name == "database" %} + $DB_OPT \ +{%- else %} -v /var/run/redis$DEV:/var/run/redis:rw \ - $REDIS_MNT \ - -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ -{%- if docker_container_name != "database" %} + -v /var/run/redis-chassis:/var/run/redis-chassis:ro \ -v /usr/share/sonic/device/$PLATFORM/$HWSKU/$DEV:/usr/share/sonic/hwsku:ro \ {%- endif %} + $REDIS_MNT \ + -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ {%- if sonic_asic_platform != "mellanox" %} --tmpfs /tmp \ {%- endif %} @@ -332,22 +369,22 @@ start() { --env "NAMESPACE_ID"="$DEV" \ --env "NAMESPACE_PREFIX"="$NAMESPACE_PREFIX" \ --env "NAMESPACE_COUNT"=$NUM_ASIC \ - --name={{docker_container_name}}$DEV {{docker_image_name}}:latest || { + --name=$DOCKERNAME {{docker_image_name}}:latest || { echo "Failed to docker run" >&1 exit 4 } preStartAction - docker start {{docker_container_name}}$DEV + docker start $DOCKERNAME postStartAction } wait() { - docker wait {{docker_container_name}}$DEV + docker wait $DOCKERNAME } stop() { - docker stop {{docker_container_name}}$DEV + docker stop $DOCKERNAME {%- if docker_container_name == "database" %} if [ "$DEV" ]; then ip netns delete "$NET_NS" @@ -355,9 +392,18 @@ stop() { {%- endif %} } +DOCKERNAME={{docker_container_name}} OP=$1 DEV=$2 # namespace/device number to operate on +{%- if docker_container_name == "database" %} +if [ "$DEV" == "chassisdb" ]; then + DATABASE_TYPE="chassisdb" + DOCKERNAME=$DOCKERNAME"-chassis" + unset DEV +fi +{%- endif %} NAMESPACE_PREFIX="asic" +DOCKERNAME=$DOCKERNAME$DEV if [ "$DEV" ]; then NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace diff --git a/files/build_templates/per_namespace/database.service.j2 b/files/build_templates/per_namespace/database.service.j2 index 396fdc6678c2..c8a59ab25bbd 100644 --- a/files/build_templates/per_namespace/database.service.j2 +++ b/files/build_templates/per_namespace/database.service.j2 @@ -4,6 +4,8 @@ Description=Database container Requires=database.service After=database.service {% endif %} +Wants=database-chassis.service +After=database-chassis.service Requires=docker.service After=docker.service After=rc-local.service diff --git a/files/build_templates/share_image/database.service.j2 b/files/build_templates/share_image/database.service.j2 new file mode 100644 index 000000000000..cc3f1b0a4364 --- /dev/null +++ b/files/build_templates/share_image/database.service.j2 @@ -0,0 +1,20 @@ +[Unit] +Description=database-chassis container +Requires=docker.service +ConditionPathExists=/etc/sonic/chassisdb.conf +After=docker.service +After=config-chassisdb.service +Requires=config-chassisdb.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start chassisdb +ExecStart=/usr/bin/{{docker_container_name}}.sh wait chassisdb +ExecStop=/usr/bin/{{docker_container_name}}.sh stop chassisdb +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 2a5d9049ca29..21f143e70109 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -381,6 +381,12 @@ sudo cp $IMAGE_CONFIGS/config-setup/config-setup $FILESYSTEM_ROOT/usr/bin/config echo "config-setup.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-setup.service +# Copy config-chassisdb script and service file +j2 files/build_templates/config-chassisdb.service.j2 | sudo tee $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM/config-chassisdb.service +sudo cp $IMAGE_CONFIGS/config-chassisdb/config-chassisdb $FILESYSTEM_ROOT/usr/bin/config-chassisdb +echo "config-chassisdb.service" | sudo tee -a $GENERATED_SERVICE_FILE +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-chassisdb.service + # Copy SNMP configuration files sudo cp $IMAGE_CONFIGS/snmp/snmp.yml $FILESYSTEM_ROOT/etc/sonic/ diff --git a/files/image_config/config-chassisdb/config-chassisdb b/files/image_config/config-chassisdb/config-chassisdb new file mode 100755 index 000000000000..3bdcf0a0fbe2 --- /dev/null +++ b/files/image_config/config-chassisdb/config-chassisdb @@ -0,0 +1,59 @@ +#!/bin/bash +########################################################################### +# Copyright 2020 Arista. The term "Arista" refers to Arista Inc. # +# and/or its subsidiaries. # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# +# See the License for the specific language governing permissions and # +# limitations under the License. # +# # +########################################################################### +# SONiC chassis_db configuration # +# # +# This script is used to add chassis_db address in local hosts and # +# indicate to start database-chassis service. It should be excuted before # +# database-chassis.service started. # +# # +########################################################################### + +config_chassis_db() { + startdb_file="/etc/sonic/chassisdb.conf" + [ ! -e $startdb_file ] || rm $startdb_file + platform=$(sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + # database-chassis services will start when $chassis_config file exists + chassis_config="/usr/share/sonic/device/$platform/chassisdb.conf" + if [ ! -e $chassis_config ]; then + echo "no chassisdb.conf found, bypass config-chassisdb service" + exit 0 + fi + start_chassis_db=0 + chassis_db_address="" + source $chassis_config + if [[ "$start_chassis_db" == "1" ]]; then + cp $chassis_config $startdb_file + echo "start chassisdb" + fi + if [[ "$start_chassis_db" == "1" ]] || [[ -n "$chassis_db_address" ]]; then + if [ -z "$chassis_db_address" ]; then + echo "no user configured chassisdb address" + else + grep redis_chassis /etc/hosts + if [ $? -ne 0 ]; then + echo "$chassis_db_address redis_chassis.server" >> /etc/hosts + echo "update chassis db address to $chassis_db_address" + fi + fi + fi +} + +config_chassis_db + +exit 0 diff --git a/files/scripts/remove_chassisdb_config b/files/scripts/remove_chassisdb_config deleted file mode 100755 index 1583042ce525..000000000000 --- a/files/scripts/remove_chassisdb_config +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/python -import json -import os -import syslog -import argparse - -database_config_file = "/var/run/redis/sonic-db/database_config.json" -redis_chassis = 'redis_chassis' -chassis_db = 'CHASSIS_DB' - -def main(): - parser=argparse.ArgumentParser(description= - "Remove chassis_db config from database-config.json") - parser.add_argument("-j", "--json", help="databse-config json file", nargs='?', - const=database_config_file) - args = parser.parse_args() - jsonfile = "" - if args.json != None: - jsonfile = args.json - else: - return - data = {} - if os.path.isfile(jsonfile): - with open(jsonfile, "r") as read_file: - data = json.load(read_file) - else: - syslog.syslog(syslog.LOG_ERR, - 'config file {} does notexist'.format(jsonfile)) - return - if 'INSTANCES' in data and redis_chassis in data['INSTANCES']: - del data['INSTANCES'][redis_chassis] - if 'DATABASES' in data and chassis_db in data['DATABASES']: - del data['DATABASES'][chassis_db] - with open(jsonfile, "w") as write_file: - json.dump(data, write_file, indent=4, separators=(',', ': ')) - syslog.syslog(syslog.LOG_INFO, - 'remove chassis_db from config file {}'.format(jsonfile)) - -if __name__ == "__main__": - main() diff --git a/files/scripts/update_chassisdb_config b/files/scripts/update_chassisdb_config new file mode 100755 index 000000000000..7ed1f2284cc8 --- /dev/null +++ b/files/scripts/update_chassisdb_config @@ -0,0 +1,67 @@ +#!/usr/bin/python +import json +import os +import syslog +import argparse + +database_config_file = "/var/run/redis/sonic-db/database_config.json" +redis_chassis = 'redis_chassis' +chassis_db = 'CHASSIS_APP_DB' + +def main(): + parser = argparse.ArgumentParser(description= + "Update chassis_db config from database-config.json") + parser.add_argument("-j", "--json", help="databse-config json file", nargs='?', + const=database_config_file) + parser.add_argument("-p", "--port", help="update port number", nargs='?' ) + group = parser.add_mutually_exclusive_group() + group.add_argument("-k", "--keep", help="keep configuration", action='store_true' ) + group.add_argument("-d", "--delete", help="delete configuration", action='store_true' ) + + args = parser.parse_args() + jsonfile = "" + if args.json != None: + jsonfile = args.json + else: + return + if args.port != None: + port_number = args.port + else: + port_number = "" + if args.keep: + keep_config = True + else: + keep_config = False + if args.delete: + delete_config = True + else: + delete_config = False + data = {} + data_keep = {} + if os.path.isfile(jsonfile): + with open(jsonfile, "r") as read_file: + data = json.load(read_file) + else: + syslog.syslog(syslog.LOG_ERR, + 'config file {} does notexist'.format(jsonfile)) + return + if 'INSTANCES' in data and redis_chassis in data['INSTANCES']: + data_keep['INSTANCES'] = {} + data_keep['INSTANCES'][redis_chassis] = data['INSTANCES'][redis_chassis] + if delete_config: + del data['INSTANCES'][redis_chassis] + if 'DATABASES' in data and chassis_db in data['DATABASES']: + data_keep['DATABASES'] = {} + data_keep['DATABASES'][chassis_db] = data['DATABASES'][chassis_db] + if delete_config: + del data['DATABASES'][chassis_db] + with open(jsonfile, "w") as write_file: + data_publish = data_keep if keep_config else data + if port_number: + data_publish['INSTANCES']['redis_chassis']['port'] = int(port_number) + json.dump(data_publish, write_file, indent=4, separators=(',', ': ')) + syslog.syslog(syslog.LOG_INFO, + 'remove chassis_db from config file {}'.format(jsonfile)) + +if __name__ == "__main__": + main() diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index 2812c5b26dd5..13d9c33fa2da 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -46,7 +46,7 @@ $(DOCKER_SONIC_VS)_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(BUFFERS_CONFIG_TEMPLATE) \ $(QOS_CONFIG_TEMPLATE) \ $(SONIC_VERSION) \ - $(RM_CHASSISDB_CONFIG_SCRIPT) + $(UPDATE_CHASSISDB_CONFIG_SCRIPT) $(DOCKER_SONIC_VS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_SONIC_VS) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 9a9b7889382d..73a3c3ca4896 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -134,7 +134,7 @@ RUN sed -ri 's/^(save .*$)/# \1/g; ' /etc/redis/redis.conf COPY ["50-default.conf", "/etc/rsyslog.d/"] -COPY ["start.sh", "orchagent.sh", "files/remove_chassisdb_config", "/usr/bin/"] +COPY ["start.sh", "orchagent.sh", "files/update_chassisdb_config", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin/"] diff --git a/platform/vs/docker-sonic-vs/chassis_db.py b/platform/vs/docker-sonic-vs/chassis_db.py index a51a33914535..c6cc774fb0c0 100644 --- a/platform/vs/docker-sonic-vs/chassis_db.py +++ b/platform/vs/docker-sonic-vs/chassis_db.py @@ -3,11 +3,11 @@ import swsssdk import json chassisdb = swsssdk.SonicV2Connector(host='10.0.0.200', port='6380') -chassisdb.connect(chassisdb.CHASSIS_DB) +chassisdb.connect(chassisdb.CHASSIS_APP_DB) fname='/usr/share/sonic/virtual_chassis/chassis_db.json' with open(fname) as f: js = json.load(f) - client=chassisdb.get_redis_client(chassisdb.CHASSIS_DB) + client=chassisdb.get_redis_client(chassisdb.CHASSIS_APP_DB) for h, table in js.items(): for k, v in table.items(): client.hset(h, k, v) diff --git a/platform/vs/docker-sonic-vs/database_config.json b/platform/vs/docker-sonic-vs/database_config.json index 73f4c43462a6..86e8142f5084 100644 --- a/platform/vs/docker-sonic-vs/database_config.json +++ b/platform/vs/docker-sonic-vs/database_config.json @@ -73,7 +73,7 @@ "separator": "|", "instance" : "redis" }, - "CHASSIS_DB" : { + "CHASSIS_APP_DB" : { "id" : 11, "separator": "|", "instance" : "redis_chassis" diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 1f30dda376e8..349c538e1daf 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -54,16 +54,16 @@ rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd supervisord_cfg="/etc/supervisor/conf.d/supervisord.conf" -chassis_cfg_file="/usr/share/sonic/virtual_chassis/default_config.json" -chassis_cfg_file_default="/etc/default/sonic-db/default_chassis_cfg.json" +chassisdb_cfg_file="/usr/share/sonic/virtual_chassis/default_config.json" +chassisdb_cfg_file_default="/etc/default/sonic-db/default_chassis_cfg.json" host_template="/usr/share/sonic/templates/hostname.j2" db_cfg_file="/var/run/redis/sonic-db/database_config.json" db_cfg_file_tmp="/var/run/redis/sonic-db/database_config.json.tmp" -if [ -r "$chassis_cfg_file" ]; then - echo $(sonic-cfggen -j $chassis_cfg_file -t $host_template) >> /etc/hosts +if [ -r "$chassisdb_cfg_file" ]; then + echo $(sonic-cfggen -j $chassisdb_cfg_file -t $host_template) >> /etc/hosts else - chassis_cfg_file="$chassis_cfg_file_default" + chassisdb_cfg_file="$chassisdb_cfg_file_default" echo "10.8.1.200 redis_chassis.server" >> /etc/hosts fi @@ -72,16 +72,16 @@ cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db/ supervisorctl start redis-server -start_chassis_db=`sonic-cfggen -v DEVICE_METADATA.localhost.start_chassis_db -y $chassis_cfg_file` +start_chassis_db=`sonic-cfggen -v DEVICE_METADATA.localhost.start_chassis_db -y $chassisdb_cfg_file` if [[ "$HOSTNAME" == *"supervisor"* ]] || [ "$start_chassis_db" == "1" ]; then supervisorctl start redis-chassis python /usr/bin/chassis_db.py fi -conn_chassis_db=`sonic-cfggen -v DEVICE_METADATA.localhost.connect_to_chassis_db -y $chassis_cfg_file` +conn_chassis_db=`sonic-cfggen -v DEVICE_METADATA.localhost.connect_to_chassis_db -y $chassisdb_cfg_file` if [ "$start_chassis_db" != "1" ] && [ "$conn_chassis_db" != "1" ]; then cp $db_cfg_file $db_cfg_file_tmp - remove_chassisdb_config -j $db_cfg_file_tmp + update_chassisdb_config -j $db_cfg_file_tmp -d cp $db_cfg_file_tmp $db_cfg_file fi diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 7cfd8f0bf21e..0a2f46d19223 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -25,3 +25,4 @@ $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli $(DOCKER_DATABASE)_BASE_IMAGE_FILES += monit_database:/etc/monit/conf.d $(DOCKER_DATABASE)_FILES += $(SYSCTL_NET_CONFIG) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_DATABASE)_FILES += $(UPDATE_CHASSISDB_CONFIG_SCRIPT) diff --git a/rules/scripts.mk b/rules/scripts.mk index 971578db09c4..1e5275a254ba 100644 --- a/rules/scripts.mk +++ b/rules/scripts.mk @@ -20,8 +20,8 @@ $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)_PATH = files/scripts SYSCTL_NET_CONFIG = sysctl-net.conf $(SYSCTL_NET_CONFIG)_PATH = files/image_config/sysctl -RM_CHASSISDB_CONFIG_SCRIPT = remove_chassisdb_config -$(RM_CHASSISDB_CONFIG_SCRIPT)_PATH = files/scripts +UPDATE_CHASSISDB_CONFIG_SCRIPT = update_chassisdb_config +$(UPDATE_CHASSISDB_CONFIG_SCRIPT)_PATH = files/scripts SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(ARP_UPDATE_SCRIPT) \ @@ -30,4 +30,4 @@ SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(QOS_CONFIG_TEMPLATE) \ $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) \ $(SYSCTL_NET_CONFIG) \ - $(RM_CHASSISDB_CONFIG_SCRIPT) + $(UPDATE_CHASSISDB_CONFIG_SCRIPT) diff --git a/slave.mk b/slave.mk index 3e200f9ee45d..6d1829c8b365 100644 --- a/slave.mk +++ b/slave.mk @@ -892,6 +892,15 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export multi_instance="false" j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service fi + # Any service template, inside share_image directory, will be used to generate -chassis.service file. + # TODO: need better way to name the image-shared service + if [ -f files/build_templates/share_image/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then + j2 files/build_templates/share_image/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)-chassis.service + $(if $(shell ls files/build_templates/share_image/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_SHARE = yes) + ) + fi + j2 files/build_templates/docker_image_ctl.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh chmod +x $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh ) @@ -910,6 +919,9 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(eval SERVICES += "$(addsuffix @.service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))"),\ $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))") ) + $(if $($(docker:-dbg.gz=.gz)_SHARE),\ + $(eval SERVICES += "$(addsuffix -chassis.service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))") + ) ) export installer_services="$(SERVICES)" From 4c8b1c4896c374ef1132cbfc31524516c97db82c Mon Sep 17 00:00:00 2001 From: sandycelestica <47624974+sandycelestica@users.noreply.github.com> Date: Thu, 15 Oct 2020 10:25:32 +0800 Subject: [PATCH 1242/1427] [udev] Add customize udev rule for console switch(for e1031) (#5571) * Add files via upload * Update platform-modules-haliburton.install * Update 50-ttyUSB-C0.rules * Update popmsg.sh * Update udev_prefix.sh --- .../platform-modules-haliburton.install | 3 + .../haliburton/script/50-ttyUSB-C0.rules | 135 ++++++++++++++++++ .../haliburton/script/popmsg.sh | 14 ++ .../haliburton/script/udev_prefix.sh | 23 +++ 4 files changed, 175 insertions(+) create mode 100644 platform/broadcom/sonic-platform-modules-cel/haliburton/script/50-ttyUSB-C0.rules create mode 100644 platform/broadcom/sonic-platform-modules-cel/haliburton/script/popmsg.sh create mode 100644 platform/broadcom/sonic-platform-modules-cel/haliburton/script/udev_prefix.sh diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install index 4fdfd33f1ec3..167de45532db 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install @@ -5,3 +5,6 @@ haliburton/script/fancontrol.service lib/systemd/system services/fancontrol/fancontrol usr/local/bin haliburton/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_e1031-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin +haliburton/script/popmsg.sh usr/local/bin +haliburton/script/udev_prefix.sh usr/local/bin +haliburton/script/50-ttyUSB-C0.rules etc/udev/rules.d diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/script/50-ttyUSB-C0.rules b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/50-ttyUSB-C0.rules new file mode 100644 index 000000000000..8fdd8a8b5031 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/50-ttyUSB-C0.rules @@ -0,0 +1,135 @@ +#ACTION=="add",KERNELS=="ttyUSB0",SUBSYSTEMS=="usb-serial",DRIVERS=="cp210x",ATTRS{port_number}=="0",NAME="ttyUSB30",SYMLINK="ttyUSB30" + +#ACTION=="add",RUN+="/bin/mkdir test.txt" +#KERNELS=="1-1.1.3",ATTRS{devpath}=="1.1.3",ATTRS{idProduct}=="2303",ATTRS{idVendor}=="067b",SYMLINK+="ttypl2303-%n" +#ACTION=="add",KERNELS=="1-1.1.3",ATTRS{devpath}=="1.1.3",ATTRS{idProduct}=="2303",ATTRS{idVendor}=="067b",SYMLINK+="ttypl2303",RUN+="/bin/mkdir 123.txt" + + +LABEL="parent info" +ACTION=="add",KERNEL=="1-1",SUBSYSTEM=="usb",RUN+="/bin/bash -c '/usr/local/bin/udev_prefix.sh clear'" +#ACTION=="add",KERNEL=="ttyUSB*",SUBSYSTEM=="tty",KERNELS=="1-1.1",ATTRS{idProduct}=="2517",ATTRS{idVendor}=="0424",RUN+="/bin/bash -c '/usr/local/bin popmsg.sh 0'",RUN+="/bin/bash -c '/usr/local/bin udev_prefix.sh C0-'",GOTO="C0 Add" +ACTION=="add",KERNEL=="ttyUSB*",SUBSYSTEM=="tty",KERNELS=="1-1.1",ATTRS{idProduct}=="2517",ATTRS{idVendor}=="0424",RUN+="/bin/bash -c '/usr/local/bin/udev_prefix.sh C0-'",GOTO="C0 Add" +ACTION=="remove",KERNELS=="1-1.1",ENV{PRODUCT}=="*424/2517/*",RUN+="/bin/bash -c '/usr/local/bin/udev_prefix.sh clear'",GOTO="C0 Remove" + + +LABEL="C0 Add" +ACTION=="add",KERNELS=="1-1.1.1:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-1" +ACTION=="add",KERNELS=="1-1.1.1:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-2" +ACTION=="add",KERNELS=="1-1.1.1:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-3" +ACTION=="add",KERNELS=="1-1.1.1:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-4" +ACTION=="add",KERNELS=="1-1.1.2:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-5" +ACTION=="add",KERNELS=="1-1.1.2:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-6" +ACTION=="add",KERNELS=="1-1.1.2:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-7" +ACTION=="add",KERNELS=="1-1.1.2:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-8" + +ACTION=="add",KERNELS=="1-1.1.3:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-9" +ACTION=="add",KERNELS=="1-1.1.3:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-10" +ACTION=="add",KERNELS=="1-1.1.3:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-11" +ACTION=="add",KERNELS=="1-1.1.3:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-12" + +ACTION=="add",KERNELS=="1-1.1.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-13" +ACTION=="add",KERNELS=="1-1.1.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-14" +ACTION=="add",KERNELS=="1-1.1.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-15" +ACTION=="add",KERNELS=="1-1.1.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-16" + +ACTION=="add",KERNELS=="1-1.1.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-17" +ACTION=="add",KERNELS=="1-1.1.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-18" +ACTION=="add",KERNELS=="1-1.1.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-19" +ACTION=="add",KERNELS=="1-1.1.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-20" + +ACTION=="add",KERNELS=="1-1.1.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-21" +ACTION=="add",KERNELS=="1-1.1.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-22" +ACTION=="add",KERNELS=="1-1.1.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-23" +ACTION=="add",KERNELS=="1-1.1.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-24" + +ACTION=="add",KERNELS=="1-1.1.7.1:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-25" +ACTION=="add",KERNELS=="1-1.1.7.1:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-26" +ACTION=="add",KERNELS=="1-1.1.7.1:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-27" +ACTION=="add",KERNELS=="1-1.1.7.1:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-28" + +ACTION=="add",KERNELS=="1-1.1.7.2:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-29" +ACTION=="add",KERNELS=="1-1.1.7.2:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-30" +ACTION=="add",KERNELS=="1-1.1.7.2:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-31" +ACTION=="add",KERNELS=="1-1.1.7.2:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-32" + +ACTION=="add",KERNELS=="1-1.1.7.3:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-33" +ACTION=="add",KERNELS=="1-1.1.7.3:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-34" +ACTION=="add",KERNELS=="1-1.1.7.3:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-35" +ACTION=="add",KERNELS=="1-1.1.7.3:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-36" + +ACTION=="add",KERNELS=="1-1.1.7.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-37" +ACTION=="add",KERNELS=="1-1.1.7.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-38" +ACTION=="add",KERNELS=="1-1.1.7.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-39" +ACTION=="add",KERNELS=="1-1.1.7.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-40" + +ACTION=="add",KERNELS=="1-1.1.7.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-41" +ACTION=="add",KERNELS=="1-1.1.7.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-42" +ACTION=="add",KERNELS=="1-1.1.7.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-43" +ACTION=="add",KERNELS=="1-1.1.7.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-44" + +ACTION=="add",KERNELS=="1-1.1.7.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-45" +ACTION=="add",KERNELS=="1-1.1.7.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-46" +ACTION=="add",KERNELS=="1-1.1.7.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-47" +ACTION=="add",KERNELS=="1-1.1.7.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-48" + +LABEL="C0 Remove" +ACTION=="remove",KERNELS=="1-1.1.1:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 1'" +ACTION=="remove",KERNELS=="1-1.1.1:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 2'" +ACTION=="remove",KERNELS=="1-1.1.1:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 3'" +ACTION=="remove",KERNELS=="1-1.1.1:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 4'" + +ACTION=="remove",KERNELS=="1-1.1.2:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 5'" +ACTION=="remove",KERNELS=="1-1.1.2:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 6'" +ACTION=="remove",KERNELS=="1-1.1.2:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 7'" +ACTION=="remove",KERNELS=="1-1.1.2:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 8'" + +ACTION=="remove",KERNELS=="1-1.1.3:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 9'" +ACTION=="remove",KERNELS=="1-1.1.3:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 10'" +ACTION=="remove",KERNELS=="1-1.1.3:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 11'" +ACTION=="remove",KERNELS=="1-1.1.3:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 12'" + +ACTION=="remove",KERNELS=="1-1.1.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",RUN+="/usr/local/bin/popmsg.sh 13" +ACTION=="remove",KERNELS=="1-1.1.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",RUN+="/usr/local/bin/popmsg.sh 14" +ACTION=="remove",KERNELS=="1-1.1.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",RUN+="/usr/local/bin/popmsg.sh 15" +ACTION=="remove",KERNELS=="1-1.1.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",RUN+="/usr/local/bin/popmsg.sh 16" + +ACTION=="remove",KERNELS=="1-1.1.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",RUN+="/usr/local/bin/popmsg.sh 17" +ACTION=="remove",KERNELS=="1-1.1.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",RUN+="/usr/local/bin/popmsg.sh 18" +ACTION=="remove",KERNELS=="1-1.1.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",RUN+="/usr/local/bin/popmsg.sh 19" +ACTION=="remove",KERNELS=="1-1.1.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",RUN+="/usr/local/bin/popmsg.sh 20" + +ACTION=="remove",KERNELS=="1-1.1.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",RUN+="/usr/local/bin/popmsg.sh 21" +ACTION=="remove",KERNELS=="1-1.1.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",RUN+="/usr/local/bin/popmsg.sh 22" +ACTION=="remove",KERNELS=="1-1.1.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",RUN+="/usr/local/bin/popmsg.sh 23" +ACTION=="remove",KERNELS=="1-1.1.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",RUN+="/usr/local/bin/popmsg.sh 24" + +ACTION=="remove",KERNELS=="1-1.1.7.1:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",RUN+="/usr/local/bin/popmsg.sh 25" +ACTION=="remove",KERNELS=="1-1.1.7.1:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",RUN+="/usr/local/bin/popmsg.sh 26" +ACTION=="remove",KERNELS=="1-1.1.7.1:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",RUN+="/usr/local/bin/popmsg.sh 27" +ACTION=="remove",KERNELS=="1-1.1.7.1:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",RUN+="/usr/local/bin/popmsg.sh 28" + +ACTION=="remove",KERNELS=="1-1.1.7.2:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",RUN+="/usr/local/bin/popmsg.sh 29" +ACTION=="remove",KERNELS=="1-1.1.7.2:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",RUN+="/usr/local/bin/popmsg.sh 30" +ACTION=="remove",KERNELS=="1-1.1.7.2:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",RUN+="/usr/local/bin/popmsg.sh 31" +ACTION=="remove",KERNELS=="1-1.1.7.2:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",RUN+="/usr/local/bin/popmsg.sh 32" + +ACTION=="remove",KERNELS=="1-1.1.7.3:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",RUN+="/usr/local/bin/popmsg.sh 33" +ACTION=="remove",KERNELS=="1-1.1.7.3:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",RUN+="/usr/local/bin/popmsg.sh 34" +ACTION=="remove",KERNELS=="1-1.1.7.3:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",RUN+="/usr/local/bin/popmsg.sh 35" +ACTION=="remove",KERNELS=="1-1.1.7.3:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",RUN+="/usr/local/bin/popmsg.sh 36" + +ACTION=="remove",KERNELS=="1-1.1.7.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",RUN+="/usr/local/bin/popmsg.sh 37" +ACTION=="remove",KERNELS=="1-1.1.7.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",RUN+="/usr/local/bin/popmsg.sh 38" +ACTION=="remove",KERNELS=="1-1.1.7.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",RUN+="/usr/local/bin/popmsg.sh 39" +ACTION=="remove",KERNELS=="1-1.1.7.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",RUN+="/usr/local/bin/popmsg.sh 40" + +ACTION=="remove",KERNELS=="1-1.1.7.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",RUN+="/usr/local/bin/popmsg.sh 41" +ACTION=="remove",KERNELS=="1-1.1.7.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",RUN+="/usr/local/bin/popmsg.sh 42" +ACTION=="remove",KERNELS=="1-1.1.7.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",RUN+="/usr/local/bin/popmsg.sh 43" +ACTION=="remove",KERNELS=="1-1.1.7.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",RUN+="/usr/local/bin/popmsg.sh 44" + +ACTION=="remove",KERNELS=="1-1.1.7.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",RUN+="/usr/local/bin/popmsg.sh 45" +ACTION=="remove",KERNELS=="1-1.1.7.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",RUN+="/usr/local/bin/popmsg.sh 46" +ACTION=="remove",KERNELS=="1-1.1.7.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",RUN+="/usr/local/bin/popmsg.sh 47" +ACTION=="remove",KERNELS=="1-1.1.7.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",RUN+="/usr/local/bin/popmsg.sh 48" + diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/script/popmsg.sh b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/popmsg.sh new file mode 100644 index 000000000000..0789c3a3ee42 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/popmsg.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +dev="/dev/" +index=0 + +cnt=$(who | wc -l) +for((i=0;i ${list[$i]} +done + diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/script/udev_prefix.sh b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/udev_prefix.sh new file mode 100644 index 000000000000..20fa0a278808 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/udev_prefix.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +PREV_REBOOT_CAUSE="/host/reboot-cause/" +DEVICE="/usr/share/sonic/device" +PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) +FILES=$DEVICE/$PLATFORM/plugins +FILENAME="udevprefix.conf" + +if [ "$1" = "clear" ] +then + if [ -e $FILES/$FILENAME ]; then + rm $FILES/$FILENAME + fi +else + if [ -e $FILES/$FILENAME ]; then + : > $FILES/$FILENAME + echo -n "$1" > $FILES/$FILENAME + else + touch $FILES/$FILENMAE + echo -n "$1" > $FILES/$FILENAME + fi +fi + From 5708e32ccf2a83bfd9faecfbdeb34a1907c02aab Mon Sep 17 00:00:00 2001 From: Rajkumar-Marvell <54936542+rajkumar38@users.noreply.github.com> Date: Fri, 16 Oct 2020 03:10:59 +0530 Subject: [PATCH 1243/1427] Set sock rx Buf size to 3MB. (#5566) * Set sock rx Buf size to 3MB. --- files/image_config/sysctl/sysctl-net.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/image_config/sysctl/sysctl-net.conf b/files/image_config/sysctl/sysctl-net.conf index 62fda3a8ca91..84c24c8b0a8a 100644 --- a/files/image_config/sysctl/sysctl-net.conf +++ b/files/image_config/sysctl/sysctl-net.conf @@ -34,6 +34,6 @@ net.ipv6.conf.all.keep_addr_on_down=1 net.ipv6.conf.eth0.keep_addr_on_down=1 net.ipv4.tcp_l3mdev_accept=1 net.ipv4.udp_l3mdev_accept=1 -net.core.rmem_max=2097152 -net.core.wmem_max=2097152 +net.core.rmem_max=3145728 +net.core.wmem_max=3145728 net.core.somaxconn=512 From d8363a99dc22adfba79cb4a96d50bd8f154553e9 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 16 Oct 2020 11:17:13 -0700 Subject: [PATCH 1244/1427] [sonic-platform-common] Update submodule (#5625) Includes the following commits: * src/sonic-platform-common 111dcf7...b316f8d (5): > [sonic_platform_base] fix an indentation in fan_drawer_base.py (#133) > [SONIC_Y_CABLE] Adding new Y cable Package for accessing Y cable QSFP's eeprom and configuring Y cable's mux through eeprom (#128) > Merge pull request #132 from vdahiya12/adding_changes_for_base_api > [ChassisBase][ModuleBase] Remove redundant 'get_serial_number()' method (#130) > Merge pull request #125 from vdahiya12/changes_for_mux_driver --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 111dcf702cf3..b316f8df1ee2 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 111dcf702cf33e621455f3040a8682f2649b7b60 +Subproject commit b316f8df1ee25937dc22b143f4b3b04de72e98dd From 8df0e2b6ceb712aa6cc08551ea71f1040c9fdf9d Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Fri, 16 Oct 2020 22:00:57 +0300 Subject: [PATCH 1245/1427] [sonic-cfggen] store jinja2 cache in log level db. (#5646) This PR makes two changes: - Store Jinja2 cache in LOGLEVEL DB instead of STATE DB - Store bytecode cache encoded in base64 Tested with the following command: "redis-dump -d 3 -k JINJA2_CACHE" Signed-off-by: Stepan Blyschak --- src/sonic-config-engine/redis_bcc.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sonic-config-engine/redis_bcc.py b/src/sonic-config-engine/redis_bcc.py index 5ab59b6a6959..1045e0c5c8b8 100644 --- a/src/sonic-config-engine/redis_bcc.py +++ b/src/sonic-config-engine/redis_bcc.py @@ -1,5 +1,7 @@ import jinja2 +from base64 import b64encode, b64decode + class RedisBytecodeCache(jinja2.BytecodeCache): """ A bytecode cache for jinja2 template that stores bytecode in Redis """ @@ -8,19 +10,20 @@ class RedisBytecodeCache(jinja2.BytecodeCache): def __init__(self, client): self._client = client try: - self._client.connect(self._client.STATE_DB, retry_on=False) + self._client.connect(self._client.LOGLEVEL_DB, retry_on=False) except Exception: self._client = None def load_bytecode(self, bucket): if self._client is None: return - code = self._client.get(self._client.STATE_DB, self.REDIS_HASH, bucket.key) + code = self._client.get(self._client.LOGLEVEL_DB, self.REDIS_HASH, bucket.key) if code is not None: - bucket.bytecode_from_string(code) + bucket.bytecode_from_string(b64decode(code)) def dump_bytecode(self, bucket): if self._client is None: return - self._client.set(self._client.STATE_DB, self.REDIS_HASH, bucket.key, bucket.bytecode_to_string()) + self._client.set(self._client.LOGLEVEL_DB, self.REDIS_HASH, + bucket.key, b64encode(bucket.bytecode_to_string())) From cdb82b9fc2869c9b0665e7ca8fdb0c3d96991c21 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Fri, 16 Oct 2020 14:28:55 -0700 Subject: [PATCH 1246/1427] [swss] Update swss and swss-common submodule pointers (#5630) [swss] [acl] Replace IP_PROTOCOL with NEXT_HEADER for IPv6 ACL tables (#1458) [acl] Refactor port OID retrieval into aclorch (#1462) Fix issue #5157 by identifying the dependency among objects and avoiding releasing an object still being referenced (#1440) [mock tests] Update MockDBConnector to match new swsscommon interface (#1465) [swss-common] netlink: Setting nl_socket buffer size to 3M from 2M (#391) Added support in Swig file to cast Selectable object to Subscriber Table object (#394) [warm reboot] Warm Reboot Support for EVPN VXLAN (#350) Implement DBInterface/SonicV2Connector in C++ (#387) Fix memory leak if a RedisCommand object were to be reused (#392) Signed-off-by: Danny Allen --- src/sonic-swss | 2 +- src/sonic-swss-common | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-swss b/src/sonic-swss index 7880c7eb7fbe..7c2f2188c081 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 7880c7eb7fbe027d3d04bab0f8303a100f825248 +Subproject commit 7c2f2188c081ef184cf992b510bf3b1f6466e016 diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 3751c81071c2..abf43569e41e 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 3751c81071c204fa737e6b3e6ea29f7413330370 +Subproject commit abf43569e41e65886457995d0845848d58695a9c From bef76b102bc7748ff93a0396c658cafd8854cae1 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 16 Oct 2020 15:51:59 -0700 Subject: [PATCH 1247/1427] [Host OS][docker-vs] No longer install 'wheel' package explicitly (#5641) It should no longer be necessary to explicitly install the 'wheel' package, as SONiC packages built as wheels should specify 'wheel' as a dependency in their setup.py files. Therefore, pip[3] should check for the presence of 'wheel' and install it if it isn't present before attempting to call 'setup.py bdist_wheel' to install the package. --- build_debian.sh | 5 ----- platform/vs/docker-sonic-vs/Dockerfile.j2 | 2 -- 2 files changed, 7 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 034a50784bb0..db736d16946e 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -318,11 +318,6 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in haveged \ jq -# Install "wheel" package so that we can install .whl packages and not -# encounter a "error: invalid command 'bdist_wheel'" error -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install wheel -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install wheel - if [[ $CONFIGURED_ARCH == amd64 ]]; then ## Pre-install the fundamental packages for amd64 (x86) sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 73a3c3ca4896..3c9208756dcb 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -63,8 +63,6 @@ RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64. RUN pip install setuptools RUN pip3 install setuptools -RUN pip install wheel -RUN pip3 install wheel RUN pip install py2_ipaddress RUN pip install six RUN pip install pyroute2==0.5.3 netifaces==0.10.7 From b57272f1379a584e68e5323c41041e4fc213c6e9 Mon Sep 17 00:00:00 2001 From: Kalimuthu-Velappan <53821802+Kalimuthu-Velappan@users.noreply.github.com> Date: Sat, 17 Oct 2020 17:28:45 +0530 Subject: [PATCH 1248/1427] [build]: Fixes the DPKG cache break because of SAI package content changes without changing its version (#5651) - The issue is that the SAI package content is changed without changing its version. The DPKG caches the wrong version of SAI package. - The fix is to include the SAI package content header for SHA calcaulation. This will detect if there is any change in the SAI package. --- platform/broadcom/sai.dep | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/sai.dep b/platform/broadcom/sai.dep index 11cc72b192fb..21455ca54673 100644 --- a/platform/broadcom/sai.dep +++ b/platform/broadcom/sai.dep @@ -3,12 +3,16 @@ SPATH := $($(BRCM_SAI)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/sai.mk platform/broadcom/sai.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +# Get the Latest HTTP Header and calculate the SHA value as it is a softlink that always points to LATEST_INT_OCP_SAI_X.X.X +SAI_FLAGS := $(shell wget --spider --server-response $($(BRCM_SAI)_URL) $($(BRCM_SAI_DEV)_URL) 2>&1 \ + | grep -Ev -- '--|Date:'|sha256sum|awk '{print $$1}' ) $(BRCM_SAI)_CACHE_MODE := GIT_CONTENT_SHA -$(BRCM_SAI)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(BRCM_SAI)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) $(SAI_FLAGS) $(BRCM_SAI)_DEP_FILES := $(DEP_FILES) + $(BRCM_SAI_DEV)_CACHE_MODE := GIT_CONTENT_SHA -$(BRCM_SAI_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(BRCM_SAI_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) $(SAI_FLAGS) $(BRCM_SAI_DEV)_DEP_FILES := $(DEP_FILES) From bcc6c643353d941cb66b3c41c7602f699461f119 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Sat, 17 Oct 2020 19:31:55 +0000 Subject: [PATCH 1249/1427] [DellEMC]: Platform modules Python3 compliance and other changes (#5609) - Make DellEMC platform modules Python3 compliant. - Change return type of PSU Platform APIs in DellEMC Z9264, S5232 and Thermal Platform APIs in S5232 to 'float'. - Remove multiple copies of pcisysfs.py. - PEP8 style changes for utility scripts. - Build and install Python3 version of sonic_platform package. - Fix minor Platform API issues. --- .../plugins/eeprom.py | 4 +- .../plugins/eeprom.py | 4 +- .../plugins/eeprom.py | 4 +- .../plugins/eeprom.py | 4 +- .../plugins/eeprom.py | 4 +- .../plugins/eeprom.py | 4 +- .../common/fw-updater | 30 +- .../common/io_rd_wr.py | 67 ++--- .../common/ipmihelper.py | 15 +- .../common/nvram_rd_wr.py | 69 +++-- .../common/pcisysfs.py | 105 +++++++ .../common/platform_reboot | 10 +- .../debian/platform-modules-s5232f.install | 3 +- .../debian/platform-modules-s5248f.install | 2 +- .../debian/platform-modules-s6000.install | 1 + .../debian/platform-modules-s6100.install | 1 + .../debian/platform-modules-z9100.install | 1 + .../debian/platform-modules-z9264f.install | 3 +- .../debian/platform-modules-z9332f.install | 2 +- .../sonic-platform-modules-dell/debian/rules | 5 + .../s5232f/scripts/pcisysfs.py | 102 ------- .../s5232f/scripts/platform_sensors.py | 225 +++++++------- .../s5232f/scripts/qsfp_irq_enable.py | 33 +-- .../s5232f/scripts/s5232f_platform.sh | 12 +- .../s5232f/sonic_platform/chassis.py | 17 +- .../s5232f/sonic_platform/component.py | 11 +- .../s5232f/sonic_platform/eeprom.py | 2 +- .../s5232f/sonic_platform/fan.py | 2 +- .../s5232f/sonic_platform/psu.py | 6 +- .../s5232f/sonic_platform/thermal.py | 6 +- .../s5248f/scripts/pcisysfs.py | 102 ------- .../s5248f/scripts/platform_sensors.py | 189 ++++++------ .../s5248f/scripts/s5248f_platform.sh | 6 +- .../s6000/scripts/s6000_platform.sh | 14 +- .../s6000/sonic_platform/chassis.py | 12 - .../s6000/sonic_platform/component.py | 2 +- .../s6000/sonic_platform/eeprom.py | 34 +-- .../s6000/sonic_platform/fan.py | 4 +- .../s6000/sonic_platform/psu.py | 2 +- .../s6000/sonic_platform/sfp.py | 4 +- .../s6100/scripts/pcisysfs.py | 79 ++--- .../s6100/scripts/platform_reboot_override | 10 +- .../s6100/scripts/platform_sensors.py | 221 +++++++------- .../s6100/scripts/s6100_platform.sh | 6 + .../s6100/setup.py | 1 + .../s6100/sonic_platform/chassis.py | 13 +- .../s6100/sonic_platform/component.py | 2 +- .../s6100/sonic_platform/eeprom.py | 4 +- .../s6100/sonic_platform/fan.py | 2 +- .../s6100/sonic_platform/module.py | 9 - .../z9100/scripts/platform_reboot_override | 10 +- .../z9100/scripts/platform_sensors.py | 274 +++++++++--------- .../z9100/scripts/z9100_platform.sh | 6 + .../z9100/sonic_platform/chassis.py | 11 +- .../z9100/sonic_platform/component.py | 2 +- .../z9100/sonic_platform/eeprom.py | 2 +- .../z9100/sonic_platform/fan.py | 2 +- .../z9100/sonic_platform/sfp.py | 2 +- .../z9264f/scripts/pcisysfs.py | 102 ------- .../z9264f/scripts/platform_sensors.py | 200 +++++++------ .../z9264f/scripts/port_irq_enable.py | 35 ++- .../z9264f/scripts/z9264f_platform.sh | 18 +- .../z9264f/sonic_platform/chassis.py | 13 +- .../z9264f/sonic_platform/eeprom.py | 6 +- .../z9264f/sonic_platform/fan.py | 2 +- .../z9264f/sonic_platform/psu.py | 6 +- .../z9332f/scripts/pcisysfs.py | 102 ------- .../z9332f/scripts/platform_sensors.py | 76 +++-- .../z9332f/scripts/z9332f_platform.sh | 4 +- 69 files changed, 994 insertions(+), 1349 deletions(-) create mode 100755 platform/broadcom/sonic-platform-modules-dell/common/pcisysfs.py delete mode 100755 platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/pcisysfs.py delete mode 100755 platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py delete mode 100755 platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/pcisysfs.py delete mode 100755 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/eeprom.py b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/eeprom.py index 7265b90efb1f..46706fe5c9aa 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/eeprom.py @@ -11,8 +11,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/eeprom.py b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/eeprom.py index 8d1d13f4b7cc..d447748ad114 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/eeprom.py @@ -11,8 +11,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py index 0b96b00d4ec7..18e3b61318db 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py @@ -13,8 +13,8 @@ try: import os.path from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py index b6305a6ed634..8b115e20c3a0 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py @@ -13,8 +13,8 @@ try: import os.path from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py index ce1691a72945..e8284f686b1e 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py @@ -12,8 +12,8 @@ try: import os.path from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py index e224cd452496..2400b0f4153c 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py @@ -11,8 +11,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/platform/broadcom/sonic-platform-modules-dell/common/fw-updater b/platform/broadcom/sonic-platform-modules-dell/common/fw-updater index 22cd1e14e3bb..baed0565234e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/common/fw-updater +++ b/platform/broadcom/sonic-platform-modules-dell/common/fw-updater @@ -1,15 +1,14 @@ -#!/usr/bin/python +#!/usr/bin/python3 # dell staging fw updater script import os -import sys import subprocess import argparse -onie_boot_folder = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' -onie_fwpkg_tool = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' +onie_boot_folder = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' +onie_fwpkg_tool = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' ONIE_BOOT_MODE_CMD = '/mnt/onie-boot/onie/tools/bin/onie-boot-mode' HOST_GRUB_DIR = '/host' HOST_GRUB_CFG = HOST_GRUB_DIR + '/grub/grub.cfg' @@ -19,8 +18,6 @@ HOST_PLATFORM_INFO = HOST_GRUB_DIR + '/platform' dell_reload_tool = '/usr/local/bin/reboot' - - def set_onie_mode(option): """Select the ONIE boot mode, and set the next_entry to point to ONIE""" _set_env_option('next_entry', 'ONIE') @@ -30,12 +27,12 @@ def set_onie_fw_update_env(): """Select the ONIE boot mode, and set the next_entry to point to ONIE""" if not os.path.exists(onie_boot_folder): - os.makedirs(onie_boot_folder) + os.makedirs(onie_boot_folder) try: - subprocess.check_call(['mount','/dev/disk/by-label/ONIE-BOOT','/mnt/onie-boot']) + subprocess.check_call(['mount', '/dev/disk/by-label/ONIE-BOOT', '/mnt/onie-boot']) except: - print "onie-boot not able to mount" + print("onie-boot not able to mount") def _set_env_option(option, value): """Set an option in the GRUB environment block. Pass None to value to @@ -53,32 +50,32 @@ def _set_env_option(option, value): def dell_firmware_update_staging(image_name): try: - p = subprocess.Popen([onie_fwpkg_tool,"purge"],stdout=subprocess.PIPE,stdin=subprocess.PIPE) + p = subprocess.Popen([onie_fwpkg_tool, "purge"], stdout=subprocess.PIPE, stdin=subprocess.PIPE) p.communicate("y") except: - print "onie-fwpkg command not found for purging old fw updates" + print("onie-fwpkg command not found for purging old fw updates") try: - subprocess.check_call([onie_fwpkg_tool,"add", str(image_name)]) + subprocess.check_call([onie_fwpkg_tool, "add", str(image_name)]) except: - print "onie-fwpkg is not found to stage fw updates" + print("onie-fwpkg is not found to stage fw updates") try: set_onie_mode("update") except: - print "dell-image command not found" + print("dell-image command not found") try: subprocess.check_call([dell_reload_tool]) except: - print "reload command not found" + print("reload command not found") if __name__ == '__main__': parser = argparse.ArgumentParser(description='Dell HOST Firmware updates') opts = parser.add_mutually_exclusive_group(required=True) opts.add_argument('-u', '--update', nargs=1, metavar='IMAGE', - help='update specified image') + help='update specified image') args = parser.parse_args() @@ -88,4 +85,3 @@ if __name__ == '__main__': if args.update: set_onie_fw_update_env() dell_firmware_update_staging(args.update[0]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py b/platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py index dc9dd09807c2..a8bb096521be 100755 --- a/platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py +++ b/platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py @@ -1,45 +1,45 @@ -#!/usr/bin/python -#Script to read/write the io based registers +#!/usr/bin/python3 +# Script to read/write the io based registers import sys import os import getopt import struct -io_resource='/dev/port' +io_resource = '/dev/port' def usage(): ''' This is the Usage Method ''' - print 'Utility for IO read/write' - print '\t\t io_rd_wr.py --get --offset ' - print '\t\t io_rd_wr.py --set --val --offset ' + print('Utility for IO read/write') + print('\t\t io_rd_wr.py --get --offset ') + print('\t\t io_rd_wr.py --set --val --offset ') sys.exit(1) -def io_reg_read(io_resource,offset): - fd=os.open(io_resource, os.O_RDONLY) - if(fd<0): - print 'file open failed %s"%io_resource' +def io_reg_read(io_resource, offset): + fd = os.open(io_resource, os.O_RDONLY) + if(fd < 0): + print('file open failed %s' % io_resource) return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s'%io_resource + print('lseek failed on %s' % io_resource) return - buf=os.read(fd,1) - reg_val1=ord(buf) - print 'reg value %x'%reg_val1 + buf = os.read(fd, 1) + reg_val1 = ord(buf) + print('reg value %x' % reg_val1) os.close(fd) -def io_reg_write(io_resource,offset,val): - fd=os.open(io_resource,os.O_RDWR) - if(fd<0): - print 'file open failed %s"%io_resource' +def io_reg_write(io_resource, offset, val): + fd = os.open(io_resource, os.O_RDWR) + if(fd < 0): + print('file open failed %s' % io_resource) return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s'%io_resource + print('lseek failed on %s' % io_resource) return - ret=os.write(fd,struct.pack('B',val)) + ret = os.write(fd, struct.pack('B', val)) if(ret != 1): - print 'write failed %d'%ret + print('write failed %d' % ret) return os.close(fd) @@ -51,19 +51,17 @@ def main(argv): opts = '' val = '' choice = '' - resouce = '' offset = '' try: - opts, args = getopt.getopt(argv, "hgs:" , \ - ["val=","offset=","help", "get", "set"]) - + opts, args = getopt.getopt(argv, "hgs:", + ["val=", "offset=", "help", "get", "set"]) except getopt.GetoptError: usage() - for opt,arg in opts: + for opt, arg in opts: - if opt in ('-h','--help'): + if opt in ('-h', '--help'): choice = 'help' elif opt in ('-g', '--get'): @@ -72,22 +70,21 @@ def main(argv): elif opt in ('-s', '--set'): choice = 'set' - elif opt == '--offset': - offset = int(arg,16) + elif opt == '--offset': + offset = int(arg, 16) - elif opt == '--val': - val = int(arg,16) + elif opt == '--val': + val = int(arg, 16) if choice == 'get' and offset != '': - io_reg_read(io_resource,offset) + io_reg_read(io_resource, offset) elif choice == 'set' and offset != '' and val != '': - io_reg_write(io_resource,offset,val) + io_reg_write(io_resource, offset, val) else: usage() -#Calling the main method +# Calling the main method if __name__ == "__main__": main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py b/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py index 046ca21938db..d371892083d0 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py +++ b/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py @@ -1,4 +1,4 @@ -#! /usr/bin/python +#!/usr/bin/python3 ######################################################################## # DellEMC @@ -53,7 +53,7 @@ def _get_ipmitool_raw_output(self, args): stdout = proc.communicate()[0] proc.wait() if not proc.returncode: - result = stdout.rstrip('\n') + result = stdout.decode('utf-8').rstrip('\n') except: pass @@ -144,10 +144,10 @@ def get_threshold(self, threshold_type): if self.is_discrete: raise TypeError("Threshold is not applicable for Discrete Sensor") - if threshold_type not in self.THRESHOLD_BIT_MASK.keys(): + if threshold_type not in list(self.THRESHOLD_BIT_MASK.keys()): raise ValueError("Invalid threshold type {} provided. Valid types " "are {}".format(threshold_type, - self.THRESHOLD_BIT_MASK.keys())) + list(self.THRESHOLD_BIT_MASK.keys()))) bit_mask = self.THRESHOLD_BIT_MASK[threshold_type] @@ -179,7 +179,7 @@ def _get_ipmitool_fru_print(self): stdout = proc.communicate()[0] proc.wait() if not proc.returncode: - result = stdout.rstrip('\n') + result = stdout.decode('utf-8').rstrip('\n') except: pass @@ -193,7 +193,7 @@ def _get_from_fru(self, info): if not fru_output: return "NA" - info_req = re.search(r"%s\s*:(.*)"%info, fru_output) + info_req = re.search(r"%s\s*:(.*)" % info, fru_output) if not info_req: return "NA" @@ -223,7 +223,6 @@ def get_board_product(self): """ return self._get_from_fru('Board Product') - def get_fru_data(self, offset, count=1): """ Reads and returns the FRU data at the provided offset. @@ -253,7 +252,7 @@ def get_fru_data(self, offset, count=1): stdout = proc.communicate()[0] proc.wait() if not proc.returncode: - result = stdout.rstrip('\n') + result = stdout.decode('utf-8').rstrip('\n') except: is_valid = False diff --git a/platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py b/platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py index 30108892741b..527c531ddfb4 100755 --- a/platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py +++ b/platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py @@ -1,45 +1,45 @@ -#!/usr/bin/python -#Script to read/write the nvram +#!/usr/bin/python3 +# Script to read/write the nvram import sys import os import getopt import struct -nvram_resource='/dev/nvram' +nvram_resource = '/dev/nvram' def usage(): ''' This is the Usage Method ''' - print 'Utility for NVRAM read/write' - print '\t\t nvram_rd_wr.py --get --offset ' - print '\t\t nvram_rd_wr.py --set --val --offset ' + print('Utility for NVRAM read/write') + print('\t\t nvram_rd_wr.py --get --offset ') + print('\t\t nvram_rd_wr.py --set --val --offset ') sys.exit(1) -def nvram_reg_read(nvram_resource,offset): - fd=os.open(nvram_resource, os.O_RDONLY) - if(fd<0): - print 'file open failed %s"%nvram_resource' +def nvram_reg_read(nvram_resource, offset): + fd = os.open(nvram_resource, os.O_RDONLY) + if(fd < 0): + print('file open failed %s' % nvram_resource) return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s'%nvram_resource + print('lseek failed on %s' % nvram_resource) return - buf=os.read(fd,1) - reg_val1=ord(buf) - print 'value %x'%reg_val1 + buf = os.read(fd, 1) + reg_val1 = ord(buf) + print('value %x' % reg_val1) os.close(fd) -def nvram_reg_write(nvram_resource,offset,val): - fd=os.open(nvram_resource,os.O_RDWR) - if(fd<0): - print 'file open failed %s"%nvram_resource' +def nvram_reg_write(nvram_resource, offset, val): + fd = os.open(nvram_resource, os.O_RDWR) + if(fd < 0): + print('file open failed %s' % nvram_resource) return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s'%nvram_resource + print('lseek failed on %s' % nvram_resource) return - ret=os.write(fd,struct.pack('B',val)) + ret = os.write(fd, struct.pack('B', val)) if(ret != 1): - print 'write failed %d'%ret + print('write failed %d' % ret) return os.close(fd) @@ -51,23 +51,21 @@ def main(argv): opts = '' val = '' choice = '' - resouce = '' offset = '' try: - opts, args = getopt.getopt(argv, "hgs:" , \ - ["val=","offset=","help", "get", "set"]) - + opts, args = getopt.getopt(argv, "hgs:", + ["val=", "offset=", "help", "get", "set"]) except getopt.GetoptError: usage() if not os.path.exists(nvram_resource): - print 'NVRAM is not initialized' + print('NVRAM is not initialized') sys.exit(1) - for opt,arg in opts: + for opt, arg in opts: - if opt in ('-h','--help'): + if opt in ('-h', '--help'): choice = 'help' elif opt in ('-g', '--get'): @@ -76,22 +74,21 @@ def main(argv): elif opt in ('-s', '--set'): choice = 'set' - elif opt == '--offset': - offset = int(arg,16) - 0xE + elif opt == '--offset': + offset = int(arg, 16) - 0xE - elif opt == '--val': - val = int(arg,16) + elif opt == '--val': + val = int(arg, 16) if choice == 'get' and offset != '': - nvram_reg_read(nvram_resource,offset) + nvram_reg_read(nvram_resource, offset) elif choice == 'set' and offset != '' and val != '': - nvram_reg_write(nvram_resource,offset,val) + nvram_reg_write(nvram_resource, offset, val) else: usage() -#Calling the main method +# Calling the main method if __name__ == "__main__": main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/common/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/common/pcisysfs.py new file mode 100755 index 000000000000..b305f54eca86 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/pcisysfs.py @@ -0,0 +1,105 @@ +#!/usr/bin/python3 +# Copyright (c) 2015 Dell Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. + +import struct +import sys +import getopt +from os import * +from mmap import * + +def usage(): + ''' This is the Usage Method ''' + + print('\t\t pcisysfs.py --get --offset --res ') + print('\t\t pcisysfs.py --set --val --offset --res ') + sys.exit(1) + +def pci_mem_read(mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + print("") + reg_val = struct.unpack('I', read_data_stream) + print("reg_val read:%x" % reg_val) + return reg_val + +def pci_mem_write(mm, offset, data): + mm.seek(offset) + print("data to write:%x" % data) + mm.write(struct.pack('I', data)) + +def pci_set_value(resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + pci_mem_write(mm, offset, val) + mm.close() + close(fd) + +def pci_get_value(resource, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + pci_mem_read(mm, offset) + mm.close() + close(fd) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resource = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgsv:", + ["val=", "res=", "offset=", "help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt, arg in opts: + + if opt in ('-h', '--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--res': + resource = arg + + elif opt == '--val': + val = int(arg, 16) + + elif opt == '--offset': + offset = int(arg, 16) + + if choice == 'set' and val != '' and offset != '' and resource != '': + pci_set_value(resource, val, offset) + + elif choice == 'get' and offset != '' and resource != '': + pci_get_value(resource, offset) + + else: + usage() + +# Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-dell/common/platform_reboot b/platform/broadcom/sonic-platform-modules-dell/common/platform_reboot index 3e165630658b..ca04ac0635a7 100755 --- a/platform/broadcom/sonic-platform-modules-dell/common/platform_reboot +++ b/platform/broadcom/sonic-platform-modules-dell/common/platform_reboot @@ -1,5 +1,4 @@ -#!/usr/bin/python -import sys +#!/usr/bin/python3 import os import struct @@ -9,17 +8,16 @@ PORT_RES = '/dev/port' def portio_reg_write(resource, offset, val): fd = os.open(resource, os.O_RDWR) if(fd < 0): - print 'file open failed %s" % resource' + print('file open failed %s' % resource) return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s' % resource + print('lseek failed on %s' % resource) return ret = os.write(fd, struct.pack('B', val)) if(ret != 1): - print 'write failed %d' % ret + print('write failed %d' % ret) return os.close(fd) if __name__ == "__main__": portio_reg_write(PORT_RES, 0xcf9, 0xe) - diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install index 74b8bc380199..25d2b84ad4ac 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install @@ -2,11 +2,12 @@ s5232f/scripts/s5232f_platform.sh usr/local/bin s5232f/scripts/check_qsfp.sh usr/local/bin s5232f/scripts/platform_sensors.py usr/local/bin s5232f/scripts/sensors usr/bin -s5232f/scripts/pcisysfs.py usr/bin s5232f/scripts/qsfp_irq_enable.py usr/bin s5232f/cfg/s5232f-modules.conf etc/modules-load.d s5232f/systemd/platform-modules-s5232f.service etc/systemd/system s5232f/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 +s5232f/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin +common/pcisysfs.py usr/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install index e87ea7e37b4e..6e74fbec0ae5 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install @@ -2,10 +2,10 @@ s5248f/scripts/s5248f_platform.sh usr/local/bin s5248f/scripts/check_qsfp.sh usr/local/bin s5248f/scripts/platform_sensors.py usr/local/bin s5248f/scripts/sensors usr/bin -s5248f/scripts/pcisysfs.py usr/bin s5248f/scripts/qsfp_irq_enable.py usr/bin s5248f/cfg/s5248f-modules.conf etc/modules-load.d s5248f/systemd/platform-modules-s5248f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5248f_c3538-r0 common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin +common/pcisysfs.py usr/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install index f662e751a3f8..d87efb31c488 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install @@ -6,3 +6,4 @@ s6000/systemd/platform-modules-s6000.service etc/systemd/system s6000/systemd/fancontrol.service etc/systemd/system common/io_rd_wr.py usr/local/bin s6000/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dell_s6000_s1220-r0 +s6000/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dell_s6000_s1220-r0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install index a3f2bbbc86b4..a9eb63eeea45 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install @@ -15,6 +15,7 @@ s6100/scripts/override.conf /etc/systemd/system/systemd-reboot.service.d common/dell_lpc_mon.sh usr/local/bin s6100/scripts/platform_sensors.py usr/local/bin s6100/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 +s6100/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 s6100/scripts/platform_watchdog_enable.sh usr/local/bin s6100/scripts/platform_watchdog_disable.sh usr/local/bin s6100/scripts/sensors usr/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install index a4dffe0d023c..28d77243d639 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install @@ -8,6 +8,7 @@ z9100/scripts/override.conf /etc/systemd/system/systemd-reboot.service.d z9100/scripts/platform_sensors.py usr/local/bin z9100/scripts/sensors usr/bin z9100/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dell_z9100_c2538-r0 +z9100/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dell_z9100_c2538-r0 z9100/cfg/z9100-modules.conf etc/modules-load.d z9100/systemd/platform-modules-z9100.service etc/systemd/system z9100/systemd/z9100-lpc-monitor.service etc/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install index 5c247bdd8e0d..9aa3793f5d29 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install @@ -2,11 +2,12 @@ z9264f/scripts/z9264f_platform.sh usr/local/bin z9264f/scripts/check_qsfp.sh usr/local/bin z9264f/scripts/platform_sensors.py usr/local/bin z9264f/scripts/sensors usr/bin -z9264f/scripts/pcisysfs.py usr/bin z9264f/scripts/port_irq_enable.py usr/bin z9264f/cfg/z9264f-modules.conf etc/modules-load.d z9264f/systemd/platform-modules-z9264f.service etc/systemd/system z9264f/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 +z9264f/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin +common/pcisysfs.py usr/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install index 16d2b952186f..a17b0e822743 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install @@ -1,7 +1,7 @@ z9332f/scripts/z9332f_platform.sh usr/local/bin z9332f/scripts/platform_sensors.py usr/local/bin z9332f/scripts/sensors usr/bin -z9332f/scripts/pcisysfs.py usr/bin z9332f/cfg/z9332f-modules.conf etc/modules-load.d z9332f/systemd/platform-modules-z9332f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 +common/pcisysfs.py usr/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index 17627fd4d44e..03c0f6426970 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -19,26 +19,31 @@ override_dh_auto_build: cp $(COMMON_DIR)/dell_ich.c $(MOD_SRC_DIR)/$${mod}/modules/dell_ich.c; \ cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ elif [ $$mod = "z9100" ]; then \ cp $(COMMON_DIR)/dell_pmc.c $(MOD_SRC_DIR)/$${mod}/modules/dell_mailbox.c; \ cp $(COMMON_DIR)/dell_ich.c $(MOD_SRC_DIR)/$${mod}/modules/dell_ich.c; \ cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ elif [ $$mod = "s6000" ]; then \ cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ elif [ $$mod = "z9264f" ]; then \ cp $(COMMON_DIR)/ipmihelper.py $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ elif [ $$mod = "s5232f" ]; then \ cp $(COMMON_DIR)/ipmihelper.py $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ fi; \ echo "making man page alias $$mod -> $$mod APIs";\ diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/pcisysfs.py deleted file mode 100755 index 047618e057c8..000000000000 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/pcisysfs.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2015 Dell Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR -# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT -# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS -# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. -# -# See the Apache Version 2.0 License for specific language governing -# permissions and limitations under the License. - -import struct -import sys -import getopt -from os import * -from mmap import * - -def usage(): - ''' This is the Usage Method ''' - - print '\t\t pcisysfs.py --get --offset --res ' - print '\t\t pcisysfs.py --set --val --offset --res ' - sys.exit(1) - -def pci_mem_read(mm,offset): - mm.seek(offset) - read_data_stream=mm.read(4) - print "" - reg_val=struct.unpack('I',read_data_stream) - print "reg_val read:%x"%reg_val - return reg_val - -def pci_mem_write(mm,offset,data): - mm.seek(offset) - print "data to write:%x"%data - mm.write(struct.pack('I',data)) - -def pci_set_value(resource,val,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_write(mm,offset,val) - -def pci_get_value(resource,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_read(mm,offset) - -def main(argv): - - ''' The main function will read the user input from the - command line argument and process the request ''' - - opts = '' - val = '' - choice = '' - resource = '' - offset = '' - - try: - opts, args = getopt.getopt(argv, "hgsv:" , \ - ["val=","res=","offset=","help", "get", "set"]) - - except getopt.GetoptError: - usage() - - for opt,arg in opts: - - if opt in ('-h','--help'): - choice = 'help' - - elif opt in ('-g', '--get'): - choice = 'get' - - elif opt in ('-s', '--set'): - choice = 'set' - - elif opt == '--res': - resource = arg - - elif opt == '--val': - val = int(arg,16) - - elif opt == '--offset': - offset = int(arg,16) - - if choice == 'set' and val != '' and offset !='' and resource !='': - pci_set_value(resource,val,offset) - - elif choice == 'get' and offset != '' and resource !='': - pci_get_value(resource,offset) - - else: - usage() - -#Calling the main method -if __name__ == "__main__": - main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py index 039a34e5b69b..1d66afed642b 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py @@ -1,9 +1,9 @@ -#!/usr/bin/python +#!/usr/bin/python3 # On S5232F, the BaseBoard Management Controller is an # autonomous subsystem provides monitoring and management # facility independent of the host CPU. IPMI standard # protocol is used with ipmitool to fetch sensor details. -# Current script support X00 board only. X01 support will +# Current script support X00 board only. X01 support will # be added soon. This provies support for the # following objects: # * Onboard temperature sensors @@ -11,11 +11,9 @@ # * PSU -import os import sys import logging import subprocess -import commands S5232F_MAX_FAN_TRAYS = 4 S5232F_MAX_PSUS = 2 @@ -41,7 +39,7 @@ def ipmi_sensor_dump(): status = 1 global ipmi_sdr_list ipmi_cmd = IPMI_SENSOR_DATA - status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + status, ipmi_sdr_list = subprocess.getstatusoutput(ipmi_cmd) if status: logging.error('Failed to execute: ' + ipmi_sdr_list) @@ -50,9 +48,9 @@ def ipmi_sensor_dump(): # Fetch a Fan Status def get_fan_status(fan_id): - ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_FAN_PRESENCE.format(fan_id)) + ret_status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_FAN_PRESENCE.format(fan_id)) if ret_status: - logging.error('Failed to execute : %s'%IPMI_FAN_PRESENCE.format(fan_id)) + logging.error('Failed to execute : %s' % IPMI_FAN_PRESENCE.format(fan_id)) sys.exit(0) return(' ' + ipmi_cmd_ret.splitlines()[5].strip(' ').strip('[]')) @@ -67,7 +65,7 @@ def get_pmc_register(reg_name): output = item.strip() if output is None: - print('\nFailed to fetch: ' + reg_name + ' sensor ') + print('\nFailed to fetch: ' + reg_name + ' sensor ') sys.exit(0) output = output.split('|')[1] @@ -75,16 +73,16 @@ def get_pmc_register(reg_name): logging.basicConfig(level=logging.DEBUG) return output -#Fetch FRU Data for given fruid +# Fetch FRU Data for given fruid def get_psu_airflow(psu_id): fru_id = 'PSU' + str(psu_id) + '_fru' - ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_FRU) + ret_status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_FRU) if ret_status: - logging.error('Failed to execute ipmitool: '+ IPMI_FRU) + logging.error('Failed to execute ipmitool: ' + IPMI_FRU) sys.exit(0) found_fru = False for line in ipmi_cmd_ret.splitlines(): - if line.startswith('FRU Device Description') and fru_id in line.split(':')[1] : + if line.startswith('FRU Device Description') and fru_id in line.split(':')[1]: found_fru = True if found_fru and line.startswith(' Board Product '): return ' B2F' if 'PS/IO' in line else ' F2B' @@ -92,13 +90,11 @@ def get_psu_airflow(psu_id): # Fetch FRU on given offset def fetch_raw_fru(dev_id, offset): - ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_RAW_STORAGE_READ.format(dev_id)) + ret_status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_RAW_STORAGE_READ.format(dev_id)) if ret_status: logging.error('Failed to execute ipmitool :' + IPMI_RAW_STORAGE_READ.format(dev_id)) sys.exit(0) - return int((ipmi_cmd_ret.splitlines()[offset/16]).split(' ')[(offset%16+1)]) - - + return int((ipmi_cmd_ret.splitlines()[offset//16]).split(' ')[(offset%16+1)]) def get_fan_airflow(fan_id): @@ -106,24 +102,22 @@ def get_fan_airflow(fan_id): return Airflow_Direction[fetch_raw_fru(fan_id+2, 0x46)] # Print the information for temperature sensors - - def print_temperature_sensors(): print("\nOnboard Temperature Sensors:") - print ' PT_Left_temp: ',\ - (get_pmc_register('PT_Left_temp')) - print ' PT_Mid_temp: ',\ - (get_pmc_register('PT_Mid_temp')) - print ' PT_Right_temp: ',\ - (get_pmc_register('PT_Right_temp')) - print ' Broadcom Temp: ',\ - (get_pmc_register('NPU_Near_temp')) - print ' Inlet Airflow Temp: ',\ - (get_pmc_register('ILET_AF_temp')) - print ' CPU Temp: ',\ - (get_pmc_register('CPU_temp')) + print(' PT_Left_temp: ', + get_pmc_register('PT_Left_temp')) + print(' PT_Mid_temp: ', + get_pmc_register('PT_Mid_temp')) + print(' PT_Right_temp: ', + get_pmc_register('PT_Right_temp')) + print(' Broadcom Temp: ', + get_pmc_register('NPU_Near_temp')) + print(' Inlet Airflow Temp: ', + get_pmc_register('ILET_AF_temp')) + print(' CPU Temp: ', + get_pmc_register('CPU_temp')) ipmi_sensor_dump() @@ -136,65 +130,65 @@ def print_fan_tray(tray): Fan_Status = [' Normal', ' Abnormal'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') if (tray == 1): fan1_status = int(get_pmc_register('FAN1_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN1_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN1_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN1_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN1_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN1_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 2): fan1_status = int(get_pmc_register('FAN2_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN2_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN2_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN2_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN2_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN2_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 3): fan1_status = int(get_pmc_register('FAN3_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN3_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN3_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN3_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN3_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN3_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 4): fan1_status = int(get_pmc_register('FAN4_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN4_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN4_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN4_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] - print ' Airflow: ',\ - get_fan_airflow(tray) + print(' Fan1 Speed: ', + get_pmc_register('FAN4_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN4_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) + print(' Airflow: ', + get_fan_airflow(tray)) print('\nFan Trays:') @@ -203,7 +197,7 @@ def print_fan_tray(tray): if (get_fan_status(tray) == ' Present'): print_fan_tray(tray) else: - print ' Fan Tray {}: NOT PRESENT'.format(str(tray)) + print(' Fan Tray {}: NOT PRESENT'.format(str(tray))) def get_psu_presence(index): """ @@ -215,9 +209,9 @@ def get_psu_presence(index): ret_status = 1 if index == 1: - ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + ret_status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU1_DATA_DOCKER) elif index == 2: - ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + ret_status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU2_DATA_DOCKER) if ret_status: logging.error('Failed to execute ipmitool :' + IPMI_PSU1_DATA_DOCKER) @@ -238,9 +232,9 @@ def get_psu_status(index): ipmi_cmd_ret = 'f' if index == 1: - ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + ret_status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU1_DATA_DOCKER) elif index == 2: - ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + ret_status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU2_DATA_DOCKER) if ret_status: logging.error('Failed to execute ipmitool : ' + IPMI_PSU2_DATA_DOCKER) @@ -271,68 +265,67 @@ def print_psu(psu): # psu1_fan_status = int(get_pmc_register('PSU1_status'),16) - print ' PSU1:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU1_temp') - print ' FAN AirFlow Temperature: ',\ - get_pmc_register('PSU1_AF_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU1_rpm') + print(' PSU1:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU1_temp')) + print(' FAN AirFlow Temperature: ', + get_pmc_register('PSU1_AF_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU1_rpm')) # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] # PSU input & output monitors - print ' Input Voltage: ',\ - get_pmc_register('PSU1_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU1_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU1_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU1_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU1_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU1_Out_amp') + print(' Input Voltage: ', + get_pmc_register('PSU1_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU1_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU1_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU1_Out_watt')) + print(' Input Current: ', + get_pmc_register('PSU1_In_amp')) + print(' Output Current: ', + get_pmc_register('PSU1_Out_amp')) else: # psu2_fan_status = int(get_pmc_register('PSU1_status'),16) - print ' PSU2:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU2_temp') - print ' FAN AirFlow Temperature: ',\ - get_pmc_register('PSU2_AF_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU2_rpm') + print(' PSU2:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU2_temp')) + print(' FAN AirFlow Temperature: ', + get_pmc_register('PSU2_AF_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU2_rpm')) # print ' FAN Status: ', Psu_Fan_Status[psu2_fan_status] # PSU input & output monitors - print ' Input Voltage: ',\ - get_pmc_register('PSU2_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU2_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU2_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU2_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU2_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU2_Out_amp') - print ' Airflow: ',\ - get_psu_airflow(psu) + print(' Input Voltage: ', + get_pmc_register('PSU2_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU2_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU2_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU2_Out_watt')) + print(' Input Current: ', + get_pmc_register('PSU2_In_amp')) + print(' Output Current: ', + get_pmc_register('PSU2_Out_amp')) + print(' Airflow: ', + get_psu_airflow(psu)) print('\nPSUs:') for psu in range(1, S5232F_MAX_PSUS + 1): #psu_presence = PSU_PRESENCE.format(psu) if not get_psu_presence(psu): - print ' PSU{}: NOT PRESENT'.format(psu) - elif not get_psu_status(psu) : - print ' PSU{}: NOT OK'.format(psu) + print(' PSU{}: NOT PRESENT'.format(psu)) + elif not get_psu_status(psu): + print(' PSU{}: NOT OK'.format(psu)) else: print_psu(psu) -print '\n Total Power: ',\ - get_pmc_register('PSU_Total_watt') - +print('\n Total Power: ', + get_pmc_register('PSU_Total_watt')) diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/qsfp_irq_enable.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/qsfp_irq_enable.py index 5050475f987e..24bc07f041f8 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/qsfp_irq_enable.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/qsfp_irq_enable.py @@ -1,32 +1,31 @@ -#!/usr/bin/python +#!/usr/bin/python3 try: - import struct - import sys - from os import * - from mmap import * + import struct + from os import * + from mmap import * except ImportError as e: - raise ImportError("%s - required module no found" % str(e)) + raise ImportError("%s - required module no found" % str(e)) BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" PORT_START = 0 -PORT_END = 32 +PORT_END = 32 def pci_mem_write(mm, offset, data): - mm.seek(offset) - mm.write(struct.pack('I', data)) + mm.seek(offset) + mm.write(struct.pack('I', data)) def pci_set_value(resource, val, offset): - fd = open(resource, O_RDWR) - mm = mmap(fd, 0) - val = pci_mem_write(mm, offset, val) - mm.close() - close(fd) - return val + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val for port_num in range(PORT_START, PORT_END+1): - port_offset = 0x400c + ((port_num) * 16) - pci_set_value(BASE_RES_PATH, 0x30, port_offset) + port_offset = 0x400c + ((port_num) * 16) + pci_set_value(BASE_RES_PATH, 0x30, port_offset) diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh index 7079da825adc..867f44d7a828 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh @@ -104,14 +104,14 @@ switch_board_modsel() { do port_addr=$(( 16384 + ((i - 1) * 16))) hex=$( printf "0x%x" $port_addr ) - python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 done } #This enables the led control for CPU and default states switch_board_led_default() { resource="/sys/bus/pci/devices/0000:04:00.0/resource0" - python /usr/bin/pcisysfs.py --set --offset 0x24 --val 0x194 --res $resource > /dev/null 2>&1 + /usr/bin/pcisysfs.py --set --offset 0x24 --val 0x194 --res $resource > /dev/null 2>&1 } # Readout firmware version of the system and @@ -161,6 +161,7 @@ install_python_api_package() { platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) } remove_python_api_package() { @@ -168,6 +169,11 @@ remove_python_api_package() { if [ $? -eq 0 ]; then rv=$(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) fi + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi } init_devnum @@ -186,7 +192,7 @@ if [ "$1" == "init" ]; then switch_board_modsel switch_board_led_default install_python_api_package - python /usr/bin/qsfp_irq_enable.py + /usr/bin/qsfp_irq_enable.py platform_firmware_versions elif [ "$1" == "deinit" ]; then diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py index 6acd54d3934b..8b6c8e29c133 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py @@ -8,9 +8,10 @@ # ############################################################################# +from __future__ import division + try: - import sys - from __future__ import division + import sys from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Eeprom @@ -46,7 +47,7 @@ def __init__(self): self.PORT_START = 1 self.PORT_END = 34 self.PORTS_IN_BLOCK = (self.PORT_END + 1) - _sfp_port = range(33, self.PORT_END + 1) + _sfp_port = list(range(33, self.PORT_END + 1)) eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" for index in range(self.PORT_START, self.PORTS_IN_BLOCK): @@ -112,7 +113,7 @@ def get_change_event(self, timeout=0): if elapsed_time_ms > timeout: break - time.sleep(sleep_time) + sleep(sleep_time) return True, change_dict def get_sfp(self, index): @@ -188,14 +189,6 @@ def get_base_mac(self): """ return self._eeprom.base_mac_addr('') - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py index bf33bd043d83..63bd29d2232e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py @@ -13,22 +13,22 @@ import subprocess from sonic_platform_base.component_base import ComponentBase import sonic_platform.hwaccess as hwaccess - + except ImportError as e: raise ImportError(str(e) + "- required module not found") def get_bios_version(): - return subprocess.check_output(['dmidecode', '-s', 'system-version']).strip() + return subprocess.check_output(['dmidecode', '-s', 'system-version']).decode('utf-8').strip() def get_fpga_version(): val = hwaccess.pci_get_value('/sys/bus/pci/devices/0000:04:00.0/resource0', 0) return '{}.{}'.format((val >> 8) & 0xff, val & 0xff) - + def get_bmc_version(): return subprocess.check_output( ['cat', '/sys/class/ipmi/ipmi0/device/bmc/firmware_revision'] - ).strip() + ).decode('utf-8').strip() def get_cpld_version(bus, i2caddr): return '{}.{}'.format(hwaccess.i2c_get(bus, i2caddr, 1), @@ -60,8 +60,7 @@ class Component(ComponentBase): ], ['BMC', - 'Platform management controller for on-board temperature ', - 'monitoring, in-chassis power, Fan and LED control', + 'Platform management controller for on-board temperature monitoring, in-chassis power, Fan and LED control', get_bmc_version ], diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py index eb4a7978fdb3..98826cbc441c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py @@ -12,7 +12,7 @@ import os.path from sonic_eeprom import eeprom_tlvinfo import binascii -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + "- required module not found") diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py index 41acae72d88e..7a098c8b0fbb 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py @@ -168,7 +168,7 @@ def get_speed(self): if not is_valid or self.max_speed == 0: speed = 0 else: - speed = (100 * fan_speed)/self.max_speed + speed = (100 * fan_speed)//self.max_speed return speed def get_speed_rpm(self): diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/psu.py index e7f05a0a17b6..a7e2add8bd08 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/psu.py @@ -111,7 +111,7 @@ def get_voltage(self): if not is_valid: voltage = 0 - return "{:.1f}".format(voltage) + return float(voltage) def get_current(self): """ @@ -125,7 +125,7 @@ def get_current(self): if not is_valid: current = 0 - return "{:.1f}".format(current) + return float(current) def get_power(self): """ @@ -139,7 +139,7 @@ def get_power(self): if not is_valid: power = 0 - return "{:.1f}".format(power) + return float(power) def get_powergood_status(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py index cc7867917345..410bb4ca96bc 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py @@ -94,7 +94,7 @@ def get_temperature(self): if not is_valid: temperature = 0 - return "{:.3f}".format(temperature) + return float(temperature) def get_high_threshold(self): """ @@ -109,7 +109,7 @@ def get_high_threshold(self): if not is_valid: high_threshold = 0 - return "{:.3f}".format(high_threshold) + return float(high_threshold) def get_low_threshold(self): """ @@ -124,7 +124,7 @@ def get_low_threshold(self): if not is_valid: low_threshold = 0 - return "{:.3f}".format(low_threshold) + return float(low_threshold) def set_high_threshold(self, temperature): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py deleted file mode 100755 index 047618e057c8..000000000000 --- a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2015 Dell Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR -# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT -# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS -# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. -# -# See the Apache Version 2.0 License for specific language governing -# permissions and limitations under the License. - -import struct -import sys -import getopt -from os import * -from mmap import * - -def usage(): - ''' This is the Usage Method ''' - - print '\t\t pcisysfs.py --get --offset --res ' - print '\t\t pcisysfs.py --set --val --offset --res ' - sys.exit(1) - -def pci_mem_read(mm,offset): - mm.seek(offset) - read_data_stream=mm.read(4) - print "" - reg_val=struct.unpack('I',read_data_stream) - print "reg_val read:%x"%reg_val - return reg_val - -def pci_mem_write(mm,offset,data): - mm.seek(offset) - print "data to write:%x"%data - mm.write(struct.pack('I',data)) - -def pci_set_value(resource,val,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_write(mm,offset,val) - -def pci_get_value(resource,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_read(mm,offset) - -def main(argv): - - ''' The main function will read the user input from the - command line argument and process the request ''' - - opts = '' - val = '' - choice = '' - resource = '' - offset = '' - - try: - opts, args = getopt.getopt(argv, "hgsv:" , \ - ["val=","res=","offset=","help", "get", "set"]) - - except getopt.GetoptError: - usage() - - for opt,arg in opts: - - if opt in ('-h','--help'): - choice = 'help' - - elif opt in ('-g', '--get'): - choice = 'get' - - elif opt in ('-s', '--set'): - choice = 'set' - - elif opt == '--res': - resource = arg - - elif opt == '--val': - val = int(arg,16) - - elif opt == '--offset': - offset = int(arg,16) - - if choice == 'set' and val != '' and offset !='' and resource !='': - pci_set_value(resource,val,offset) - - elif choice == 'get' and offset != '' and resource !='': - pci_get_value(resource,offset) - - else: - usage() - -#Calling the main method -if __name__ == "__main__": - main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py index 6f7ba9b55b09..f276e6879d2c 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py @@ -1,9 +1,9 @@ -#!/usr/bin/python +#!/usr/bin/python3 # On S5248F, the BaseBoard Management Controller is an # autonomous subsystem provides monitoring and management # facility independent of the host CPU. IPMI standard # protocol is used with ipmitool to fetch sensor details. -# Current script support X00 board only. X01 support will +# Current script support X00 board only. X01 support will # be added soon. This provies support for the # following objects: # * Onboard temperature sensors @@ -11,11 +11,9 @@ # * PSU -import os import sys import logging import subprocess -import commands S5248F_MAX_FAN_TRAYS = 4 S5248F_MAX_PSUS = 2 @@ -39,7 +37,7 @@ def ipmi_sensor_dump(): status = 1 global ipmi_sdr_list ipmi_cmd = IPMI_SENSOR_DATA - status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + status, ipmi_sdr_list = subprocess.getstatusoutput(ipmi_cmd) if status: logging.error('Failed to execute:' + ipmi_sdr_list) @@ -56,7 +54,7 @@ def get_pmc_register(reg_name): output = item.strip() if output is None: - print('\nFailed to fetch: ' + reg_name + ' sensor ') + print('\nFailed to fetch: ' + reg_name + ' sensor ') sys.exit(0) output = output.split('|')[1] @@ -72,18 +70,18 @@ def print_temperature_sensors(): print("\nOnboard Temperature Sensors:") - print ' PT_Left_temp: ',\ - (get_pmc_register('PT_Left_temp')) - print ' PT_Mid_temp: ',\ - (get_pmc_register('PT_Mid_temp')) - print ' PT_Right_temp: ',\ - (get_pmc_register('PT_Right_temp')) - print ' Broadcom Temp: ',\ - (get_pmc_register('NPU_Near_temp')) - print ' Inlet Airflow Temp: ',\ - (get_pmc_register('ILET_AF_temp')) - print ' CPU Temp: ',\ - (get_pmc_register('CPU_temp')) + print(' PT_Left_temp: ', + get_pmc_register('PT_Left_temp')) + print(' PT_Mid_temp: ', + get_pmc_register('PT_Mid_temp')) + print(' PT_Right_temp: ', + get_pmc_register('PT_Right_temp')) + print(' Broadcom Temp: ', + get_pmc_register('NPU_Near_temp')) + print(' Inlet Airflow Temp: ', + get_pmc_register('ILET_AF_temp')) + print(' CPU Temp: ', + get_pmc_register('CPU_temp')) ipmi_sensor_dump() @@ -97,63 +95,63 @@ def print_fan_tray(tray): Fan_Status = [' Normal', ' Abnormal'] Airflow_Direction = ['B2F', 'F2B'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') if (tray == 1): fan1_status = int(get_pmc_register('FAN1_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN1_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN1_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN1_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN1_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN1_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 2): fan1_status = int(get_pmc_register('FAN2_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN2_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN2_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN2_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN2_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN2_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 3): fan1_status = int(get_pmc_register('FAN3_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN3_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN3_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN3_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN3_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN3_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 4): fan1_status = int(get_pmc_register('FAN4_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN4_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN4_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN4_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN4_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN4_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) print('\nFan Trays:') @@ -163,7 +161,7 @@ def print_fan_tray(tray): if (get_pmc_register(fan_presence)): print_fan_tray(tray) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print('\n Fan Tray ' + str(tray + 1) + ': Not present') def get_psu_presence(index): """ @@ -176,9 +174,9 @@ def get_psu_presence(index): ret_status = 1 if index == 1: - status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU1_DATA_DOCKER) elif index == 2: - ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + ret_status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU2_DATA_DOCKER) #if ret_status: # print ipmi_cmd_ret @@ -214,54 +212,54 @@ def print_psu(psu): # psu1_fan_status = int(get_pmc_register('PSU1_status'),16) - print ' PSU1:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU1_temp') - print ' FAN AirFlow Temperature: ',\ - get_pmc_register('PSU1_AF_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU1_rpm') + print(' PSU1:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU1_temp')) + print(' FAN AirFlow Temperature: ', + get_pmc_register('PSU1_AF_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU1_rpm')) # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] # PSU input & output monitors - print ' Input Voltage: ',\ - get_pmc_register('PSU1_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU1_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU1_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU1_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU1_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU1_Out_amp') + print(' Input Voltage: ', + get_pmc_register('PSU1_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU1_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU1_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU1_Out_watt')) + print(' Input Current: ', + get_pmc_register('PSU1_In_amp')) + print(' Output Current: ', + get_pmc_register('PSU1_Out_amp')) else: # psu2_fan_status = int(get_pmc_register('PSU1_status'),16) - print ' PSU2:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU2_temp') - print ' FAN AirFlow Temperature: ',\ - get_pmc_register('PSU2_AF_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU2_rpm') + print(' PSU2:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU2_temp')) + print(' FAN AirFlow Temperature: ', + get_pmc_register('PSU2_AF_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU2_rpm')) # print ' FAN Status: ', Psu_Fan_Status[psu2_fan_status] # PSU input & output monitors - print ' Input Voltage: ',\ - get_pmc_register('PSU2_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU2_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU2_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU2_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU2_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU2_Out_amp') + print(' Input Voltage: ', + get_pmc_register('PSU2_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU2_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU2_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU2_Out_watt')) + print(' Input Current: ', + get_pmc_register('PSU2_In_amp')) + print(' Output Current: ', + get_pmc_register('PSU2_Out_amp')) print('\nPSUs:') @@ -270,8 +268,7 @@ def print_psu(psu): if (get_psu_presence(psu)): print_psu(psu) else: - print '\n PSU ', psu, 'Not present' - -print '\n Total Power: ',\ - get_pmc_register('PSU_Total_watt') + print('\n PSU ', psu, 'Not present') +print('\n Total Power: ', + get_pmc_register('PSU_Total_watt')) diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh index 77032d643397..e006e53cfc49 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh @@ -82,7 +82,7 @@ switch_board_modsel() { do port_addr=$(( 16384 + ((i - 1) * 16))) hex=$( printf "0x%x" $port_addr ) - python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 done } @@ -129,7 +129,7 @@ platform_firmware_versions() { #This enables the led control for CPU and default states switch_board_led_default() { resource="/sys/bus/pci/devices/0000:04:00.0/resource0" - python /usr/bin/pcisysfs.py --set --offset 0x24 --val 0x194 --res $resource > /dev/null 2>&1 + /usr/bin/pcisysfs.py --set --offset 0x24 --val 0x194 --res $resource > /dev/null 2>&1 } init_devnum @@ -145,7 +145,7 @@ if [ "$1" == "init" ]; then switch_board_qsfp "new_device" switch_board_modsel switch_board_led_default - #python /usr/bin/qsfp_irq_enable.py + #/usr/bin/qsfp_irq_enable.py platform_firmware_versions elif [ "$1" == "deinit" ]; then diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh index f2e95f5130ff..a98df43ef27b 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh @@ -76,17 +76,21 @@ switch_board_qsfp_lpmode() { install_python_api_package() { device="/usr/share/sonic/device" - platform=${PLATFORM:-`/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) - if [ -e $device/$platform/sonic_platform-1.0-py2-none-any.whl ]; then - rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) - fi + rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) } remove_python_api_package() { rv=$(pip show sonic-platform > /dev/null 2>/dev/null) if [ $? -eq 0 ]; then - rv = $(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) + rv=$(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) fi } diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index 06fb6c2ff0e9..dab394abc52f 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -10,9 +10,7 @@ try: import os import time - import datetime import struct - import subprocess from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Eeprom, EepromS6000 @@ -190,16 +188,6 @@ def get_base_mac(self): """ return self._eeprom.get_base_mac() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - - Returns: - A string containing the hardware serial number for this - chassis. - """ - return self._eeprom.get_serial_number() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py index daa30eaafa3b..1e21c233f5d8 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py @@ -61,7 +61,7 @@ def _get_command_result(self, cmdline): stderr=subprocess.STDOUT) stdout = proc.communicate()[0] proc.wait() - result = stdout.rstrip('\n') + result = stdout.decode('utf-8').rstrip('\n') except OSError: result = None diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py index 1a8a3a84b601..45f2a63598e7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py @@ -200,7 +200,7 @@ def _get_eeprom_field(self, field_name): for field in self.format: field_end = field_start + field[2] if field[0] == field_name: - return (True, self.eeprom_data[field_start:field_end]) + return (True, self.eeprom_data[field_start:field_end].decode('utf-8')) field_start = field_end return (False, None) @@ -222,9 +222,9 @@ def airflow_fan_type(self): Returns the airflow fan type. """ if self.is_psu_eeprom: - return int(self.psu_type.encode('hex'), 16) + return int(binascii.hexlify(self.psu_type.encode('utf-8')), 16) else: - return int(self.fan_type.encode('hex'), 16) + return int(binascii.hexlify(self.fan_type.encode('utf-8')), 16) # System EEPROM specific methods def get_base_mac(self): @@ -323,13 +323,13 @@ def decode_eeprom(self, e): """ Decode and print out the contents of the EEPROM. """ - print " Field Name Len Value" - print "-------------------- --- --------------------" - for blk_code in self._BLK_INFO.keys(): + print(" Field Name Len Value") + print("-------------------- --- --------------------") + for blk_code in list(self._BLK_INFO.keys()): blk_start = self._BLK_INFO[blk_code]["offset"] blk_end = blk_start + self._BLK_INFO[blk_code]["size"] if not self._is_valid_block(e[blk_start:blk_end], blk_code): - print "Invalid Block starting at EEPROM offset %d" % (blk_start) + print("Invalid Block starting at EEPROM offset %d" % (blk_start)) return offset = blk_start + self._BLK_HDR_LEN @@ -342,11 +342,11 @@ def decode_eeprom(self, e): data = ":".join([binascii.b2a_hex(T) for T in e[offset:offset+f[1]]]).upper() else: data = e[offset:offset+f[1]] - print "{:<20s} {:>3d} {:3d} {:3d} {:3d} {:> ((2 - self.index) * 4)) & 0xF + psu_status = (int(psu_status, 16) >> int((2 - self.index) * 4)) & 0xF if (~psu_status & 0b1000) and (~psu_status & 0b0100): status = True diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py index 2b6cb0d18edf..c4c958a84154 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py @@ -241,7 +241,7 @@ def get_transceiver_info(self): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: return transceiver_info_dict - + # Fill The Dictionary and return transceiver_info_dict['type'] = identifier transceiver_info_dict['hardware_rev'] = vendor_rev @@ -259,7 +259,7 @@ def get_transceiver_info(self): compliance_code_dict) transceiver_info_dict['vendor_date'] = vendor_date transceiver_info_dict['vendor_oui'] = vendor_oui - transceiver_info_dict['type_abbrv_name']=type_abbrv_name + transceiver_info_dict['type_abbrv_name'] = type_abbrv_name return transceiver_info_dict diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py index 767b66f43b63..fd3564e75619 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py @@ -1,4 +1,4 @@ -#! /usr/bin/python +#!/usr/bin/python3 import struct import sys @@ -7,35 +7,37 @@ from mmap import * def usage(): - ''' This is the Usage Method ''' + ''' This is the Usage Method ''' - print '\t\t pcisysfs.py --get --offset --res ' - print '\t\t pcisysfs.py --set --val --offset --res ' - sys.exit(1) + print('\t\t pcisysfs.py --get --offset --res ') + print('\t\t pcisysfs.py --set --val --offset --res ') + sys.exit(1) -def pci_mem_read(mm,offset): +def pci_mem_read(mm, offset): mm.seek(offset) - read_data_stream=mm.read(4) - print "" - reg_val=struct.unpack('I',read_data_stream) - print "reg_val read:%x"%reg_val + read_data_stream = mm.read(4) + print("") + reg_val = struct.unpack('I', read_data_stream) + print("reg_val read:%x" % reg_val) return reg_val -def pci_mem_write(mm,offset,data): +def pci_mem_write(mm, offset, data): mm.seek(offset) - #print "data to write:%x"%data - mm.write(struct.pack('I',data)) - -def pci_set_value(resource,val,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_write(mm,offset,val) + #print("data to write:%x" % data) + mm.write(struct.pack('I', data)) + +def pci_set_value(resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + pci_mem_write(mm, offset, val) + mm.close() close(fd) -def pci_get_value(resource,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_read(mm,offset) +def pci_get_value(resource, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + pci_mem_read(mm, offset) + mm.close() close(fd) def main(argv): @@ -50,15 +52,15 @@ def main(argv): offset = '' try: - opts, args = getopt.getopt(argv, "hgsv:" , \ - ["val=","res=","offset=","help", "get", "set"]) - + opts, args = getopt.getopt(argv, "hgsv:", + ["val=", "res=", "offset=", "help", "get", "set"]) + except getopt.GetoptError: usage() - for opt,arg in opts: + for opt, arg in opts: - if opt in ('-h','--help'): + if opt in ('-h', '--help'): choice = 'help' elif opt in ('-g', '--get'): @@ -67,25 +69,24 @@ def main(argv): elif opt in ('-s', '--set'): choice = 'set' - elif opt == '--res': + elif opt == '--res': resource = arg - elif opt == '--val': - val = int(arg,16) + elif opt == '--val': + val = int(arg, 16) - elif opt == '--offset': - offset = int(arg,16) + elif opt == '--offset': + offset = int(arg, 16) - if choice == 'set' and val != '' and offset !='' and resource !='': - pci_set_value(resource,val,offset) + if choice == 'set' and val != '' and offset != '' and resource != '': + pci_set_value(resource, val, offset) - elif choice == 'get' and offset != '' and resource !='': - pci_get_value(resource,offset) + elif choice == 'get' and offset != '' and resource != '': + pci_get_value(resource, offset) else: usage() -#Calling the main method +# Calling the main method if __name__ == "__main__": - main(sys.argv[1:]) - + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override index b971c26f4fc2..dc681104dac1 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override @@ -1,5 +1,4 @@ -#!/usr/bin/python -import sys +#!/usr/bin/python3 import os import subprocess import struct @@ -20,14 +19,14 @@ def ssd_hdparm_upgrade(): def portio_reg_write(resource, offset, val): fd = os.open(resource, os.O_RDWR) if(fd < 0): - print 'file open failed %s" % resource' + print('file open failed %s" % resource') return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s' % resource + print('lseek failed on %s' % resource) return ret = os.write(fd, struct.pack('B', val)) if(ret != 1): - print 'write failed %d' % ret + print('write failed %d' % ret) return os.close(fd) @@ -35,4 +34,3 @@ if __name__ == "__main__": log_software_reboot() ssd_hdparm_upgrade() portio_reg_write(PORT_RES, 0xcf9, 0xe) - diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py index b94b69388300..089cf277551d 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # On S6100, the Platform Management Controller runs the # thermal algorithm. It provides a mailbox for the Host @@ -9,7 +9,6 @@ # * PSU # import os -import sys import logging S6100_MAX_FAN_TRAYS = 4 @@ -29,7 +28,7 @@ def get_pmc_register(reg_name): mb_reg_file = MAILBOX_DIR+'/'+reg_name if (not os.path.isfile(mb_reg_file)): - print mb_reg_file, 'not found !' + print(mb_reg_file, 'not found !') return retval try: @@ -45,8 +44,8 @@ def get_pmc_register(reg_name): logging.basicConfig(level=logging.DEBUG) if (os.path.isdir(MAILBOX_DIR)): - print 'dell-s6100-lpc' - print 'Adapter: S6100 Platform Management Controller' + print('dell-s6100-lpc') + print('Adapter: S6100 Platform Management Controller') else: logging.error('S6100 Platform Management Controller module not loaded !') # sys.exit(0) @@ -56,20 +55,20 @@ def get_pmc_register(reg_name): def print_temperature_sensors(): print("\nOnboard Temperature Sensors:") - print ' CPU: ',\ - int(get_pmc_register('temp1_input'))/1000, 'C' - print ' BCM56960 (PSU side): ',\ - int(get_pmc_register('temp2_input'))/1000, 'C' - print ' System Outlet 1 (switch board): ',\ - int(get_pmc_register('temp3_input'))/1000, 'C' - print ' BCM56960 (IO side): ',\ - int(get_pmc_register('temp4_input'))/1000, 'C' - print ' System Outlet 2 (CPU board): ',\ - int(get_pmc_register('temp9_input'))/1000, 'C' - print ' System Inlet Left (IO side): ',\ - int(get_pmc_register('temp10_input'))/1000, 'C' - print ' System Inlet Right (IO side): ',\ - int(get_pmc_register('temp11_input'))/1000, 'C' + print(' CPU: ', + int(get_pmc_register('temp1_input'))/1000, 'C') + print(' BCM56960 (PSU side): ', + int(get_pmc_register('temp2_input'))/1000, 'C') + print(' System Outlet 1 (switch board): ', + int(get_pmc_register('temp3_input'))/1000, 'C') + print(' BCM56960 (IO side): ', + int(get_pmc_register('temp4_input'))/1000, 'C') + print(' System Outlet 2 (CPU board): ', + int(get_pmc_register('temp9_input'))/1000, 'C') + print(' System Inlet Left (IO side): ', + int(get_pmc_register('temp10_input'))/1000, 'C') + print(' System Inlet Right (IO side): ', + int(get_pmc_register('temp11_input'))/1000, 'C') iom_status = get_pmc_register('iom_presence') iom_status = int(iom_status, 16) @@ -84,9 +83,9 @@ def print_temperature_sensors(): for iom in range(0, S6100_MAX_IOMS): if (~iom_presence & (1 << iom)): iom_sensor_indx = iom + 5 - print ' IOM ' + str(iom + 1) + ':\t\t\t ',\ - int(get_pmc_register('temp'+str(iom_sensor_indx) + - '_input'))/1000, 'C' + print(' IOM ' + str(iom + 1) + ':\t\t\t ', + int(get_pmc_register('temp' + str(iom_sensor_indx) + + '_input'))/1000, 'C') # Save the IOM Status for later use if (~iom_status & (1 << iom)): @@ -95,7 +94,7 @@ def print_temperature_sensors(): iom_status_list.append('OFF') else: iom_status_list.append('Not present') - print ' IOM ' + str(iom + 1) + ':\t\t\t ', 'Not present' + print(' IOM ' + str(iom + 1) + ':\t\t\t ', 'Not present') else: logging.error('Unable to check IOM presence') @@ -108,56 +107,56 @@ def print_temperature_sensors(): def print_voltage_sensors(): print("\nOnboard Voltage Sensors:") - print ' CPU XP3R3V_EARLY ',\ - float(get_pmc_register('in1_input'))/1000, 'V' - print ' CPU XP5R0V_CP ',\ - float(get_pmc_register('in2_input'))/1000, 'V' - print ' CPU XP3R3V_STD ',\ - float(get_pmc_register('in3_input'))/1000, 'V' - print ' CPU XP3R3V_CP ',\ - float(get_pmc_register('in4_input'))/1000, 'V' - print ' CPU XP0R75V_VTT_A ',\ - float(get_pmc_register('in5_input'))/1000, 'V' - print ' CPU XPPR75V_VTT_B ',\ - float(get_pmc_register('in6_input'))/1000, 'V' - print ' CPU XP1R07V_CPU ',\ - float(get_pmc_register('in7_input'))/1000, 'V' - print ' CPU XP1R0V_CPU ',\ - float(get_pmc_register('in8_input'))/1000, 'V' - print ' CPU XP12R0V ',\ - float(get_pmc_register('in9_input'))/1000, 'V' - print ' CPU VDDR_CPU_2 ',\ - float(get_pmc_register('in10_input'))/1000, 'V' - print ' CPU VDDR_CPU_1 ',\ - float(get_pmc_register('in11_input'))/1000, 'V' - print ' CPU XP1R5V_CLK ',\ - float(get_pmc_register('in12_input'))/1000, 'V' - print ' CPU XP1R8V_CPU ',\ - float(get_pmc_register('in13_input'))/1000, 'V' - print ' CPU XP1R0V_CPU_VNN ',\ - float(get_pmc_register('in14_input'))/1000, 'V' - print ' CPU XP1R0V_CPU_VCC ',\ - float(get_pmc_register('in15_input'))/1000, 'V' - print ' CPU XP1R5V_EARLY ',\ - float(get_pmc_register('in16_input'))/1000, 'V' - print ' SW XP3R3V_MON ',\ - float(get_pmc_register('in17_input'))/1000, 'V' - print ' SW XP1R25V_MON ',\ - float(get_pmc_register('in19_input'))/1000, 'V' - print ' SW XP1R2V_MON ',\ - float(get_pmc_register('in20_input'))/1000, 'V' - print ' SW XP1R0V_SW_MON ',\ - float(get_pmc_register('in21_input'))/1000, 'V' - print ' SW XP1R0V_ROV_SW_MON ',\ - float(get_pmc_register('in22_input'))/1000, 'V' - print ' SW XR1R0V_BCM84752_MON ',\ - float(get_pmc_register('in23_input'))/1000, 'V' - print ' SW XP5V_MB_MON ',\ - float(get_pmc_register('in24_input'))/1000, 'V' - print ' SW XP3R3V_FPGA_MON ',\ - float(get_pmc_register('in26_input'))/1000, 'V' - print ' SW XP3R3V_EARLY_MON ',\ - float(get_pmc_register('in27_input'))/1000, 'V' + print(' CPU XP3R3V_EARLY ', + float(get_pmc_register('in1_input'))/1000, 'V') + print(' CPU XP5R0V_CP ', + float(get_pmc_register('in2_input'))/1000, 'V') + print(' CPU XP3R3V_STD ', + float(get_pmc_register('in3_input'))/1000, 'V') + print(' CPU XP3R3V_CP ', + float(get_pmc_register('in4_input'))/1000, 'V') + print(' CPU XP0R75V_VTT_A ', + float(get_pmc_register('in5_input'))/1000, 'V') + print(' CPU XPPR75V_VTT_B ', + float(get_pmc_register('in6_input'))/1000, 'V') + print(' CPU XP1R07V_CPU ', + float(get_pmc_register('in7_input'))/1000, 'V') + print(' CPU XP1R0V_CPU ', + float(get_pmc_register('in8_input'))/1000, 'V') + print(' CPU XP12R0V ', + float(get_pmc_register('in9_input'))/1000, 'V') + print(' CPU VDDR_CPU_2 ', + float(get_pmc_register('in10_input'))/1000, 'V') + print(' CPU VDDR_CPU_1 ', + float(get_pmc_register('in11_input'))/1000, 'V') + print(' CPU XP1R5V_CLK ', + float(get_pmc_register('in12_input'))/1000, 'V') + print(' CPU XP1R8V_CPU ', + float(get_pmc_register('in13_input'))/1000, 'V') + print(' CPU XP1R0V_CPU_VNN ', + float(get_pmc_register('in14_input'))/1000, 'V') + print(' CPU XP1R0V_CPU_VCC ', + float(get_pmc_register('in15_input'))/1000, 'V') + print(' CPU XP1R5V_EARLY ', + float(get_pmc_register('in16_input'))/1000, 'V') + print(' SW XP3R3V_MON ', + float(get_pmc_register('in17_input'))/1000, 'V') + print(' SW XP1R25V_MON ', + float(get_pmc_register('in19_input'))/1000, 'V') + print(' SW XP1R2V_MON ', + float(get_pmc_register('in20_input'))/1000, 'V') + print(' SW XP1R0V_SW_MON ', + float(get_pmc_register('in21_input'))/1000, 'V') + print(' SW XP1R0V_ROV_SW_MON ', + float(get_pmc_register('in22_input'))/1000, 'V') + print(' SW XR1R0V_BCM84752_MON ', + float(get_pmc_register('in23_input'))/1000, 'V') + print(' SW XP5V_MB_MON ', + float(get_pmc_register('in24_input'))/1000, 'V') + print(' SW XP3R3V_FPGA_MON ', + float(get_pmc_register('in26_input'))/1000, 'V') + print(' SW XP3R3V_EARLY_MON ', + float(get_pmc_register('in27_input'))/1000, 'V') print_voltage_sensors() @@ -169,40 +168,40 @@ def print_fan_tray(tray): Fan_Status = ['Normal', 'Abnormal'] Airflow_Direction = ['B2F', 'F2B'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') if (tray == 1): - fan1_speed = get_pmc_register('fan1_input') + fan1_speed = int(get_pmc_register('fan1_input')) air_flow_reg = int(get_pmc_register('fan1_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 - print ' Fan Speed: ', fan1_speed, 'RPM' - print ' Fan State: ', Fan_Status[fan1_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan Speed: ', fan1_speed, 'RPM') + print(' Fan State: ', Fan_Status[fan1_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 2): - fan1_speed = get_pmc_register('fan3_input') + fan1_speed = int(get_pmc_register('fan3_input')) air_flow_reg = int(get_pmc_register('fan3_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 - print ' Fan Speed: ', fan1_speed, 'RPM' - print ' Fan State: ', Fan_Status[fan1_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan Speed: ', fan1_speed, 'RPM') + print(' Fan State: ', Fan_Status[fan1_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 3): - fan1_speed = get_pmc_register('fan5_input') + fan1_speed = int(get_pmc_register('fan5_input')) air_flow_reg = int(get_pmc_register('fan5_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 - print ' Fan Speed: ', fan1_speed, 'RPM' - print ' Fan State: ', Fan_Status[fan1_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan Speed: ', fan1_speed, 'RPM') + print(' Fan State: ', Fan_Status[fan1_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 4): - fan1_speed = get_pmc_register('fan7_input') + fan1_speed = int(get_pmc_register('fan7_input')) air_flow_reg = int(get_pmc_register('fan7_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 - print ' Fan Speed: ', fan1_speed, 'RPM' - print ' Fan State: ', Fan_Status[fan1_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan Speed: ', fan1_speed, 'RPM') + print(' Fan State: ', Fan_Status[fan1_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) print('\nFan Trays:') fan_tray_presence = get_pmc_register('fan_tray_presence') @@ -214,7 +213,7 @@ def print_fan_tray(tray): if (fan_tray_presence & (1 << tray)): print_fan_tray(tray + 1) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print('\n Fan Tray ' + str(tray + 1) + ': Not present') else: logging.error('Unable to read FAN presence') @@ -233,7 +232,7 @@ def print_psu(psu): Psu_Fan_Status = ['Normal', 'Abnormal'] Psu_Fan_Airflow = ['B2F', 'F2B'] - print ' PSU ' + str(psu) + ':' + print(' PSU ' + str(psu) + ':') if (psu == 1): psu_status = int(get_pmc_register('psu1_presence'), 16) else: @@ -244,12 +243,12 @@ def print_psu(psu): psu_type = (psu_status & (1 << PSU_STATUS_TYPE_BIT)) >>\ PSU_STATUS_TYPE_BIT - print ' Input: ', Psu_Input_Type[psu_input_type] - print ' Type: ', Psu_Type[psu_type] + print(' Input: ', Psu_Input_Type[psu_input_type]) + print(' Type: ', Psu_Type[psu_type]) # PSU FAN details if (psu == 1): - print ' FAN Speed: ', get_pmc_register('fan11_input'), 'RPM' + print(' FAN Speed: ', get_pmc_register('fan11_input'), 'RPM') psu_fan_airflow = int(get_pmc_register('fan11_airflow')) psu_fan_status = int(get_pmc_register('fan11_alarm')) psu_fan_present = int(get_pmc_register('fan11_fault')) @@ -262,7 +261,7 @@ def print_psu(psu): if (input_power != 0): psu_fan_temp = int(get_pmc_register('temp14_input'))/1000 else: - print ' FAN Speed: ', get_pmc_register('fan12_input'), 'RPM' + print(' FAN Speed: ', get_pmc_register('fan12_input'), 'RPM') psu_fan_airflow = int(get_pmc_register('fan12_airflow')) psu_fan_status = int(get_pmc_register('fan12_alarm')) psu_fan_present = int(get_pmc_register('fan12_fault')) @@ -274,28 +273,28 @@ def print_psu(psu): output_power = float(get_pmc_register('power4_input')) / 1000000 if (input_power != 0): psu_fan_temp = int(get_pmc_register('temp15_input'))/1000 - print ' FAN: ', Psu_Fan_Presence[psu_fan_present] - print ' FAN Status: ', Psu_Fan_Status[psu_fan_status] - print ' FAN AIRFLOW: ', Psu_Fan_Airflow[psu_fan_airflow] + print(' FAN: ', Psu_Fan_Presence[psu_fan_present]) + print(' FAN Status: ', Psu_Fan_Status[psu_fan_status]) + print(' FAN AIRFLOW: ', Psu_Fan_Airflow[psu_fan_airflow]) # PSU input & output monitors - print ' Input Voltage: %6.2f' % (input_voltage), 'V' + print(' Input Voltage: %6.2f' % (input_voltage), 'V') - print ' Output Voltage: %6.2f' % (output_voltage), 'V' + print(' Output Voltage: %6.2f' % (output_voltage), 'V') - print ' Input Current: %6.2f' % (input_current), 'A' + print(' Input Current: %6.2f' % (input_current), 'A') - print ' Output Current: %6.2f' % (output_current), 'A' + print(' Output Current: %6.2f' % (output_current), 'A') - print ' Input Power: %6.2f' % (input_power), 'W' + print(' Input Power: %6.2f' % (input_power), 'W') - print ' Output Power: %6.2f' % (output_power), 'W' + print(' Output Power: %6.2f' % (output_power), 'W') # PSU firmware gives spurious temperature reading without input power if (input_power != 0): - print ' Temperature: ', psu_fan_temp, 'C' + print(' Temperature: ', psu_fan_temp, 'C') else: - print ' Temperature: ', 'NA' + print(' Temperature: ', 'NA') print('\nPSUs:') for psu in range(1, S6100_MAX_PSUS + 1): @@ -310,15 +309,15 @@ def print_psu(psu): if (~psu_status & 0b1): print_psu(psu) else: - print '\n PSU ', psu, 'Not present' + print('\n PSU ', psu, 'Not present') else: logging.error('Unable to check PSU presence') -print '\n Total Power: ', get_pmc_register('current_total_power'), 'W' +print('\n Total Power: ', get_pmc_register('current_total_power'), 'W') print('\nIO Modules:') for iom in range(1, S6100_MAX_IOMS+1): - print ' IOM ' + str(iom) + ' :' + iom_status_list[iom - 1] + print(' IOM ' + str(iom) + ' :' + iom_status_list[iom - 1]) -print '\n' +print('\n') diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh index 1f65045bd315..62a8c1a2812f 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -7,6 +7,7 @@ install_python_api_package() { platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) } remove_python_api_package() { @@ -14,6 +15,11 @@ remove_python_api_package() { if [ $? -eq 0 ]; then rv=$(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) fi + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi } diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/setup.py b/platform/broadcom/sonic-platform-modules-dell/s6100/setup.py index eb95775c6677..d031762fbeb8 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/setup.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/setup.py @@ -23,6 +23,7 @@ 'Natural Language :: English', 'Operating System :: POSIX :: Linux', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.7', 'Topic :: Utilities', ], keywords='sonic SONiC platform PLATFORM', diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py index 3284e671bfe0..15d8edb8b65a 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py @@ -10,7 +10,6 @@ try: import os - from sonic_platform_base.platform_base import PlatformBase from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.psu import Psu @@ -19,7 +18,7 @@ from sonic_platform.thermal import Thermal from sonic_platform.component import Component from sonic_platform.watchdog import Watchdog - from eeprom import Eeprom + from sonic_platform.eeprom import Eeprom import time except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -182,16 +181,6 @@ def get_base_mac(self): """ return self._eeprom.base_mac_addr() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - - Returns: - A string containing the hardware serial number for this - chassis. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py index a92ab5c85db2..6b1420a98606 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py @@ -79,7 +79,7 @@ def _get_command_result(self, cmdline): stderr=subprocess.STDOUT) stdout = proc.communicate()[0] proc.wait() - result = stdout.rstrip('\n') + result = stdout.decode('utf-8').rstrip('\n') except OSError: result = None diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py index d281783827b6..d102c4bc1990 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py @@ -12,8 +12,8 @@ try: from sonic_eeprom import eeprom_tlvinfo import binascii -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py index 49e95357b6f1..0f3c76638949 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py @@ -186,7 +186,7 @@ def get_speed(self): fan_speed = self._get_pmc_register(self.get_fan_speed_reg) if (fan_speed != 'ERR') and self.get_presence(): speed_in_rpm = int(fan_speed, 10) - speed = (100 * speed_in_rpm)/self.max_fan_speed + speed = (100 * speed_in_rpm)//self.max_fan_speed else: speed = 0 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py index 19198098dfd7..d0f77ffa4a2f 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py @@ -172,15 +172,6 @@ def get_base_mac(self): # In S6100, individual modules doesn't have MAC address return '00:00:00:00:00:00' - def get_serial_number(self): - """ - Retrieves the hardware serial number for the module - - Returns: - A string containing the hardware serial number for this module. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the module diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_reboot_override b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_reboot_override index 3e165630658b..0cc43644954d 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_reboot_override +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_reboot_override @@ -1,5 +1,4 @@ -#!/usr/bin/python -import sys +#!/usr/bin/python3 import os import struct @@ -9,17 +8,16 @@ PORT_RES = '/dev/port' def portio_reg_write(resource, offset, val): fd = os.open(resource, os.O_RDWR) if(fd < 0): - print 'file open failed %s" % resource' + print('file open failed %s" % resource') return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s' % resource + print('lseek failed on %s' % resource) return ret = os.write(fd, struct.pack('B', val)) if(ret != 1): - print 'write failed %d' % ret + print('write failed %d' % ret) return os.close(fd) if __name__ == "__main__": portio_reg_write(PORT_RES, 0xcf9, 0xe) - diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py index 05cbb3a1a4c1..0caa533c3fa6 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # On Z9100, the Platform Management Controller runs the # thermal algorithm. It provides a mailbox for the Host @@ -28,7 +28,7 @@ def get_pmc_register(reg_name): mb_reg_file = MAILBOX_DIR+'/'+reg_name if (not os.path.isfile(mb_reg_file)): - print mb_reg_file, 'not found !' + print(mb_reg_file, 'not found !') return retval try: @@ -44,8 +44,8 @@ def get_pmc_register(reg_name): logging.basicConfig(level=logging.DEBUG) if (os.path.isdir(MAILBOX_DIR)): - print 'dell-z9100-lpc' - print 'Adapter: Z9100 Platform Management Controller' + print('dell-z9100-lpc') + print('Adapter: Z9100 Platform Management Controller') else: logging.error('Z9100 Platform Management Controller module not loaded !') # sys.exit(0) @@ -55,18 +55,18 @@ def get_pmc_register(reg_name): def print_temperature_sensors(): print("\nOnboard Temperature Sensors:") - print ' CPU: ',\ - int(get_pmc_register('temp1_input'))/1000, 'C' - print ' BCM56960 (PSU side): ',\ - int(get_pmc_register('temp2_input'))/1000, 'C' - print ' System Outlet 1 (switch board): ',\ - int(get_pmc_register('temp3_input'))/1000, 'C' - print ' BCM56960 (IO side): ',\ - int(get_pmc_register('temp4_input'))/1000, 'C' - print ' System Outlet 2 (CPU board): ',\ - int(get_pmc_register('temp9_input'))/1000, 'C' - print ' System Inlet Left (IO side): ',\ - int(get_pmc_register('temp6_input'))/1000, 'C' + print(' CPU: ', + int(get_pmc_register('temp1_input'))/1000, 'C') + print(' BCM56960 (PSU side): ', + int(get_pmc_register('temp2_input'))/1000, 'C') + print(' System Outlet 1 (switch board): ', + int(get_pmc_register('temp3_input'))/1000, 'C') + print(' BCM56960 (IO side): ', + int(get_pmc_register('temp4_input'))/1000, 'C') + print(' System Outlet 2 (CPU board): ', + int(get_pmc_register('temp9_input'))/1000, 'C') + print(' System Inlet Left (IO side): ', + int(get_pmc_register('temp6_input'))/1000, 'C') print_temperature_sensors() @@ -77,63 +77,62 @@ def print_temperature_sensors(): def print_voltage_sensors(): print("\nOnboard Voltage Sensors:") - print ' CPU XP3R3V_EARLY ',\ - float(get_pmc_register('in1_input'))/1000, 'V' - print '\n CPU XP5R0V_CP ',\ - float(get_pmc_register('in2_input'))/1000, 'V' - print ' CPU XP3R3V_STD ',\ - float(get_pmc_register('in3_input'))/1000, 'V' - print ' CPU XP3R3V_CP ',\ - float(get_pmc_register('in4_input'))/1000, 'V' - print ' CPU XP0R75V_VTT_A ',\ - float(get_pmc_register('in5_input'))/1000, 'V' - print ' CPU XPPR75V_VTT_B ',\ - float(get_pmc_register('in6_input'))/1000, 'V' - print ' CPU XP1R07V_CPU ',\ - float(get_pmc_register('in7_input'))/1000, 'V' - print ' CPU XP1R0V_CPU ',\ - float(get_pmc_register('in8_input'))/1000, 'V' - print ' CPU XP12R0V ',\ - float(get_pmc_register('in9_input'))/1000, 'V' - print ' CPU VDDR_CPU_2 ',\ - float(get_pmc_register('in10_input'))/1000, 'V' - print ' CPU VDDR_CPU_1 ',\ - float(get_pmc_register('in11_input'))/1000, 'V' - print ' CPU XP1R5V_CLK ',\ - float(get_pmc_register('in12_input'))/1000, 'V' - print ' CPU XP1R8V_CPU ',\ - float(get_pmc_register('in13_input'))/1000, 'V' - print ' CPU XP1R0V_CPU_VNN ',\ - float(get_pmc_register('in14_input'))/1000, 'V' - print ' CPU XP1R0V_CPU_VCC ',\ - float(get_pmc_register('in15_input'))/1000, 'V' - print ' CPU XP1R5V_EARLY ',\ - float(get_pmc_register('in16_input'))/1000, 'V' - print ' SW XP3R3V_MON ',\ - float(get_pmc_register('in17_input'))/1000, 'V' - print ' SW XP1R8V_MON ',\ - float(get_pmc_register('in19_input'))/1000, 'V' - print ' SW XP1R2V_MON ',\ - float(get_pmc_register('in20_input'))/1000, 'V' - print ' SW XP1R0V_SW_MON ',\ - float(get_pmc_register('in21_input'))/1000, 'V' - print ' SW XP1R0V_ROV_SW_MON ',\ - float(get_pmc_register('in22_input'))/1000, 'V' - print ' SW XR1R0V_BCM84752_MON ',\ - float(get_pmc_register('in23_input'))/1000, 'V' - print ' SW XP5V_MB_MON ',\ - float(get_pmc_register('in24_input'))/1000, 'V' - print ' SW XP1R8V_FPGA_MON ',\ - float(get_pmc_register('in25_input'))/1000, 'V' - print ' SW XP3R3V_FPGA_MON ',\ - float(get_pmc_register('in26_input'))/1000, 'V' - print ' SW XP3R3V_EARLY_MON ',\ - float(get_pmc_register('in27_input'))/1000, 'V' - print ' SW XP1R0V_ ',\ - float(get_pmc_register('curr21_input'))/10000, 'A' - print ' SW XP1R0V_ROV ',\ - float(get_pmc_register('curr22_input'))/10000, 'A' - + print(' CPU XP3R3V_EARLY ', + float(get_pmc_register('in1_input'))/1000, 'V') + print('\n CPU XP5R0V_CP ', + float(get_pmc_register('in2_input'))/1000, 'V') + print(' CPU XP3R3V_STD ', + float(get_pmc_register('in3_input'))/1000, 'V') + print(' CPU XP3R3V_CP ', + float(get_pmc_register('in4_input'))/1000, 'V') + print(' CPU XP0R75V_VTT_A ', + float(get_pmc_register('in5_input'))/1000, 'V') + print(' CPU XPPR75V_VTT_B ', + float(get_pmc_register('in6_input'))/1000, 'V') + print(' CPU XP1R07V_CPU ', + float(get_pmc_register('in7_input'))/1000, 'V') + print(' CPU XP1R0V_CPU ', + float(get_pmc_register('in8_input'))/1000, 'V') + print(' CPU XP12R0V ', + float(get_pmc_register('in9_input'))/1000, 'V') + print(' CPU VDDR_CPU_2 ', + float(get_pmc_register('in10_input'))/1000, 'V') + print(' CPU VDDR_CPU_1 ', + float(get_pmc_register('in11_input'))/1000, 'V') + print(' CPU XP1R5V_CLK ', + float(get_pmc_register('in12_input'))/1000, 'V') + print(' CPU XP1R8V_CPU ', + float(get_pmc_register('in13_input'))/1000, 'V') + print(' CPU XP1R0V_CPU_VNN ', + float(get_pmc_register('in14_input'))/1000, 'V') + print(' CPU XP1R0V_CPU_VCC ', + float(get_pmc_register('in15_input'))/1000, 'V') + print(' CPU XP1R5V_EARLY ', + float(get_pmc_register('in16_input'))/1000, 'V') + print(' SW XP3R3V_MON ', + float(get_pmc_register('in17_input'))/1000, 'V') + print(' SW XP1R8V_MON ', + float(get_pmc_register('in19_input'))/1000, 'V') + print(' SW XP1R2V_MON ', + float(get_pmc_register('in20_input'))/1000, 'V') + print(' SW XP1R0V_SW_MON ', + float(get_pmc_register('in21_input'))/1000, 'V') + print(' SW XP1R0V_ROV_SW_MON ', + float(get_pmc_register('in22_input'))/1000, 'V') + print(' SW XR1R0V_BCM84752_MON ', + float(get_pmc_register('in23_input'))/1000, 'V') + print(' SW XP5V_MB_MON ', + float(get_pmc_register('in24_input'))/1000, 'V') + print(' SW XP1R8V_FPGA_MON ', + float(get_pmc_register('in25_input'))/1000, 'V') + print(' SW XP3R3V_FPGA_MON ', + float(get_pmc_register('in26_input'))/1000, 'V') + print(' SW XP3R3V_EARLY_MON ', + float(get_pmc_register('in27_input'))/1000, 'V') + print(' SW XP1R0V_ ', + float(get_pmc_register('curr21_input'))/10000, 'A') + print(' SW XP1R0V_ROV ', + float(get_pmc_register('curr22_input'))/10000, 'A') print_voltage_sensors() @@ -146,68 +145,68 @@ def print_fan_tray(tray): Fan_Status = ['Normal', 'Abnormal'] Airflow_Direction = ['B2F', 'F2B'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') if (tray == 1): - fan1_speed = get_pmc_register('fan1_input') - fan2_speed = get_pmc_register('fan2_input') - air_flow_reg = int(get_pmc_register('fan1_airflow'), 16) + fan1_speed = int(get_pmc_register('fan1_input')) + fan2_speed = int(get_pmc_register('fan2_input')) + air_flow_reg = int(get_pmc_register('fan1_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 fan2_status = 0 if fan2_speed >= 1000 else 1 - print ' Fan1 Speed: ', fan1_speed, 'RPM' - print ' Fan2 Speed: ', fan2_speed, 'RPM' - print ' Fan1 State: ', Fan_Status[fan1_status] - print ' Fan2 State: ', Fan_Status[fan2_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan1 Speed: ', fan1_speed, 'RPM') + print(' Fan2 Speed: ', fan2_speed, 'RPM') + print(' Fan1 State: ', Fan_Status[fan1_status]) + print(' Fan2 State: ', Fan_Status[fan2_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 2): - fan1_speed = get_pmc_register('fan3_input') - fan2_speed = get_pmc_register('fan4_input') - air_flow_reg = int(get_pmc_register('fan3_airflow'), 16) + fan1_speed = int(get_pmc_register('fan3_input')) + fan2_speed = int(get_pmc_register('fan4_input')) + air_flow_reg = int(get_pmc_register('fan3_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 fan2_status = 0 if fan2_speed >= 1000 else 1 - print ' Fan1 Speed: ', fan1_speed, 'RPM' - print ' Fan2 Speed: ', fan2_speed, 'RPM' - print ' Fan1 State: ', Fan_Status[fan1_status] - print ' Fan2 State: ', Fan_Status[fan2_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan1 Speed: ', fan1_speed, 'RPM') + print(' Fan2 Speed: ', fan2_speed, 'RPM') + print(' Fan1 State: ', Fan_Status[fan1_status]) + print(' Fan2 State: ', Fan_Status[fan2_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 3): - fan1_speed = get_pmc_register('fan5_input') - fan2_speed = get_pmc_register('fan6_input') - air_flow_reg = int(get_pmc_register('fan5_airflow'), 16) + fan1_speed = int(get_pmc_register('fan5_input')) + fan2_speed = int(get_pmc_register('fan6_input')) + air_flow_reg = int(get_pmc_register('fan5_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 fan2_status = 0 if fan2_speed >= 1000 else 1 - print ' Fan1 Speed: ', fan1_speed, 'RPM' - print ' Fan2 Speed: ', fan2_speed, 'RPM' - print ' Fan1 State: ', Fan_Status[fan1_status] - print ' Fan2 State: ', Fan_Status[fan2_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan1 Speed: ', fan1_speed, 'RPM') + print(' Fan2 Speed: ', fan2_speed, 'RPM') + print(' Fan1 State: ', Fan_Status[fan1_status]) + print(' Fan2 State: ', Fan_Status[fan2_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 4): - fan1_speed = get_pmc_register('fan7_input') - fan2_speed = get_pmc_register('fan8_input') - air_flow_reg = int(get_pmc_register('fan7_airflow'), 16) + fan1_speed = int(get_pmc_register('fan7_input')) + fan2_speed = int(get_pmc_register('fan8_input')) + air_flow_reg = int(get_pmc_register('fan7_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 fan2_status = 0 if fan2_speed >= 1000 else 1 - print ' Fan1 Speed: ', fan1_speed, 'RPM' - print ' Fan2 Speed: ', fan2_speed, 'RPM' - print ' Fan1 State: ', Fan_Status[fan1_status] - print ' Fan2 State: ', Fan_Status[fan2_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan1 Speed: ', fan1_speed, 'RPM') + print(' Fan2 Speed: ', fan2_speed, 'RPM') + print(' Fan1 State: ', Fan_Status[fan1_status]) + print(' Fan2 State: ', Fan_Status[fan2_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 5): - fan1_speed = get_pmc_register('fan9_input') - fan2_speed = get_pmc_register('fan10_input') - air_flow_reg = int(get_pmc_register('fan9_airflow'), 16) + fan1_speed = int(get_pmc_register('fan9_input')) + fan2_speed = int(get_pmc_register('fan10_input')) + air_flow_reg = int(get_pmc_register('fan9_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 fan2_status = 0 if fan2_speed >= 1000 else 1 - print ' Fan1 Speed: ', fan1_speed, 'RPM' - print ' Fan2 Speed: ', fan2_speed, 'RPM' - print ' Fan1 State: ', Fan_Status[fan1_status] - print ' Fan2 State: ', Fan_Status[fan2_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan1 Speed: ', fan1_speed, 'RPM') + print(' Fan2 Speed: ', fan2_speed, 'RPM') + print(' Fan1 State: ', Fan_Status[fan1_status]) + print(' Fan2 State: ', Fan_Status[fan2_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) print('\nFan Trays:') @@ -220,7 +219,7 @@ def print_fan_tray(tray): if (fan_tray_presence & (1 << tray)): print_fan_tray(tray + 1) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print('\n Fan Tray ' + str(tray + 1) + ': Not present') else: logging.error('Unable to read FAN presence') @@ -238,9 +237,8 @@ def print_psu(psu): Psu_Fan_Presence = ['Present', 'Absent'] Psu_Fan_Status = ['Normal', 'Abnormal'] Psu_Fan_Airflow = ['B2F', 'F2B'] - - print ' PSU ' + str(psu) + ':' + print(' PSU ' + str(psu) + ':') if (psu == 1): psu_status = int(get_pmc_register('psu1_presence'), 16) else: @@ -251,12 +249,12 @@ def print_psu(psu): psu_type = (psu_status & (1 << PSU_STATUS_TYPE_BIT)) >>\ PSU_STATUS_TYPE_BIT - print ' Input: ', Psu_Input_Type[psu_input_type] - print ' Type: ', Psu_Type[psu_type] + print(' Input: ', Psu_Input_Type[psu_input_type]) + print(' Type: ', Psu_Type[psu_type]) # PSU FAN details if (psu == 1): - print ' FAN Speed: ', get_pmc_register('fan11_input'), 'RPM' + print(' FAN Speed: ', get_pmc_register('fan11_input'), 'RPM') psu_fan_airflow = int(get_pmc_register('fan11_airflow')) psu_fan_status = int(get_pmc_register('fan11_alarm')) psu_fan_present = int(get_pmc_register('fan11_fault')) @@ -266,10 +264,10 @@ def print_psu(psu): output_current = float(get_pmc_register('curr602_input')) / 1000 input_power = float(get_pmc_register('power1_input')) / 1000000 output_power = float(get_pmc_register('power2_input')) / 1000000 - if (input_power != 0): - psu_fan_temp = int(get_pmc_register('temp14_input'))/1000 + if (input_power != 0): + psu_fan_temp = int(get_pmc_register('temp14_input'))/1000 else: - print ' FAN Speed: ', get_pmc_register('fan12_input'), 'RPM' + print(' FAN Speed: ', get_pmc_register('fan12_input'), 'RPM') psu_fan_airflow = int(get_pmc_register('fan12_airflow')) psu_fan_status = int(get_pmc_register('fan12_alarm')) psu_fan_present = int(get_pmc_register('fan12_fault')) @@ -279,31 +277,31 @@ def print_psu(psu): output_current = float(get_pmc_register('curr702_input')) / 1000 input_power = float(get_pmc_register('power3_input')) / 1000000 output_power = float(get_pmc_register('power4_input')) / 1000000 - if (input_power != 0): - psu_fan_temp = int(get_pmc_register('temp15_input'))/1000 + if (input_power != 0): + psu_fan_temp = int(get_pmc_register('temp15_input'))/1000 - print ' FAN: ', Psu_Fan_Presence[psu_fan_present] - print ' FAN Status: ', Psu_Fan_Status[psu_fan_status] - print ' FAN AIRFLOW: ', Psu_Fan_Airflow[psu_fan_airflow] + print(' FAN: ', Psu_Fan_Presence[psu_fan_present]) + print(' FAN Status: ', Psu_Fan_Status[psu_fan_status]) + print(' FAN AIRFLOW: ', Psu_Fan_Airflow[psu_fan_airflow]) # PSU input & output monitors - print ' Input Voltage: %6.2f' % (input_voltage), 'V' + print(' Input Voltage: %6.2f' % (input_voltage), 'V') - print ' Output Voltage: %6.2f' % (output_voltage), 'V' + print(' Output Voltage: %6.2f' % (output_voltage), 'V') - print ' Input Current: %6.2f' % (input_current), 'A' + print(' Input Current: %6.2f' % (input_current), 'A') - print ' Output Current: %6.2f' % (output_current), 'A' + print(' Output Current: %6.2f' % (output_current), 'A') - print ' Input Power: %6.2f' % (input_power), 'W' + print(' Input Power: %6.2f' % (input_power), 'W') - print ' Output Power: %6.2f' % (output_power), 'W' + print(' Output Power: %6.2f' % (output_power), 'W') # PSU firmware gives spurious temperature reading without input power if (input_power != 0): - print ' Temperature: ', psu_fan_temp, 'C' + print(' Temperature: ', psu_fan_temp, 'C') else: - print ' Temperature: ', 'NA' + print(' Temperature: ', 'NA') print('\nPSUs:') for psu in range(1, Z9100_MAX_PSUS + 1): @@ -319,8 +317,8 @@ def print_psu(psu): if (~psu_status & 0b1): print_psu(psu) else: - print '\n PSU ', psu, 'Not present' + print('\n PSU ', psu, 'Not present') else: logging.error('Unable to check PSU presence') -print '\n Total Power: ', get_pmc_register('current_total_power'), 'W' +print('\n Total Power: ', get_pmc_register('current_total_power'), 'W') diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh index 7fe841ef5447..8d564c6c2cd5 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh @@ -205,6 +205,7 @@ install_python_api_package() { platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) } remove_python_api_package() { @@ -212,6 +213,11 @@ remove_python_api_package() { if [ $? -eq 0 ]; then rv = $(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) fi + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi } init_devnum diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index 3f03f9671f91..88a9c7dff10f 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py @@ -18,7 +18,7 @@ from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal from sonic_platform.component import Component - from eeprom import Eeprom + from sonic_platform.eeprom import Eeprom except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -232,15 +232,6 @@ def get_base_mac(self): """ return self._eeprom.base_mac_addr() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py index dccb8f6ac2dc..52dee31a524e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py @@ -67,7 +67,7 @@ def _get_command_result(self, cmdline): stderr=subprocess.STDOUT) stdout = proc.communicate()[0] proc.wait() - result = stdout.rstrip('\n') + result = stdout.decode('utf-8').rstrip('\n') except OSError: result = None diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/eeprom.py index 15a2cec80191..5e3944082fc7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/eeprom.py @@ -12,7 +12,7 @@ try: from sonic_eeprom import eeprom_tlvinfo import binascii -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + "- required module not found") diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py index 6ff688fa3a1e..31bda2f4cefb 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py @@ -185,7 +185,7 @@ def get_speed(self): fan_speed = self._get_pmc_register(self.get_fan_speed_reg) if (fan_speed != 'ERR') and self.get_presence(): speed_in_rpm = int(fan_speed, 10) - speed = (100 * speed_in_rpm)/self.max_fan_speed + speed = (100 * speed_in_rpm)//self.max_fan_speed else: speed = 0 diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py index 669abe138bff..7abe73c2be3d 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py @@ -258,7 +258,7 @@ def get_transceiver_info(self): compliance_code_dict) transceiver_info_dict['vendor_date'] = vendor_date transceiver_info_dict['vendor_oui'] = vendor_oui - transceiver_info_dict['type_abbrv_name']=type_abbrv_name + transceiver_info_dict['type_abbrv_name'] = type_abbrv_name return transceiver_info_dict diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/pcisysfs.py deleted file mode 100755 index 047618e057c8..000000000000 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/pcisysfs.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2015 Dell Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR -# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT -# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS -# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. -# -# See the Apache Version 2.0 License for specific language governing -# permissions and limitations under the License. - -import struct -import sys -import getopt -from os import * -from mmap import * - -def usage(): - ''' This is the Usage Method ''' - - print '\t\t pcisysfs.py --get --offset --res ' - print '\t\t pcisysfs.py --set --val --offset --res ' - sys.exit(1) - -def pci_mem_read(mm,offset): - mm.seek(offset) - read_data_stream=mm.read(4) - print "" - reg_val=struct.unpack('I',read_data_stream) - print "reg_val read:%x"%reg_val - return reg_val - -def pci_mem_write(mm,offset,data): - mm.seek(offset) - print "data to write:%x"%data - mm.write(struct.pack('I',data)) - -def pci_set_value(resource,val,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_write(mm,offset,val) - -def pci_get_value(resource,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_read(mm,offset) - -def main(argv): - - ''' The main function will read the user input from the - command line argument and process the request ''' - - opts = '' - val = '' - choice = '' - resource = '' - offset = '' - - try: - opts, args = getopt.getopt(argv, "hgsv:" , \ - ["val=","res=","offset=","help", "get", "set"]) - - except getopt.GetoptError: - usage() - - for opt,arg in opts: - - if opt in ('-h','--help'): - choice = 'help' - - elif opt in ('-g', '--get'): - choice = 'get' - - elif opt in ('-s', '--set'): - choice = 'set' - - elif opt == '--res': - resource = arg - - elif opt == '--val': - val = int(arg,16) - - elif opt == '--offset': - offset = int(arg,16) - - if choice == 'set' and val != '' and offset !='' and resource !='': - pci_set_value(resource,val,offset) - - elif choice == 'get' and offset != '' and resource !='': - pci_get_value(resource,offset) - - else: - usage() - -#Calling the main method -if __name__ == "__main__": - main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py index 77a9887f9a0a..bcc13452a828 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # On Z9264f, the BaseBoard Management Controller is an # autonomous subsystem provides monitoring and management # facility independent of the host CPU. IPMI standard @@ -11,11 +11,9 @@ # * PSU -import os import sys import logging import subprocess -import commands Z9264F_MAX_FAN_TRAYS = 4 Z9264F_MAX_PSUS = 2 @@ -36,7 +34,7 @@ def ipmi_sensor_dump(): status = 1 global ipmi_sdr_list ipmi_cmd = IPMI_SENSOR_DATA - status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + status, ipmi_sdr_list = subprocess.getstatusoutput(ipmi_cmd) if status: logging.error('Failed to execute:' + ipmi_sdr_list) @@ -68,24 +66,24 @@ def print_temperature_sensors(): print("\nOnboard Temperature Sensors:") - print ' PT_Left_temp: ',\ - (get_pmc_register('PT_Left_temp')) - print ' PT_Mid_temp: ',\ - (get_pmc_register('PT_Mid_temp')) - print ' PT_Right_temp: ',\ - (get_pmc_register('PT_Right_temp')) - print ' Broadcom Temp: ',\ - (get_pmc_register('TC_Near_temp')) - print ' Inlet Airflow Temp: ',\ - (get_pmc_register('ILET_AF_temp')) - print ' CPU Temp: ',\ - (get_pmc_register('CPU_Near_temp')) - print ' CPU Near Temp: ',\ - (get_pmc_register('CPU_temp')) - print ' PSU FAN AirFlow Temperature 1: ',\ - (get_pmc_register('PSU1_AF_temp')) - print ' PSU FAN AirFlow Temperature 2: ',\ - (get_pmc_register('PSU2_AF_temp')) + print(' PT_Left_temp: ', + get_pmc_register('PT_Left_temp')) + print(' PT_Mid_temp: ', + get_pmc_register('PT_Mid_temp')) + print(' PT_Right_temp: ', + get_pmc_register('PT_Right_temp')) + print(' Broadcom Temp: ', + get_pmc_register('TC_Near_temp')) + print(' Inlet Airflow Temp: ', + get_pmc_register('ILET_AF_temp')) + print(' CPU Temp: ', + get_pmc_register('CPU_Near_temp')) + print(' CPU Near Temp: ', + get_pmc_register('CPU_temp')) + print(' PSU FAN AirFlow Temperature 1: ', + get_pmc_register('PSU1_AF_temp')) + print(' PSU FAN AirFlow Temperature 2: ', + get_pmc_register('PSU2_AF_temp')) ipmi_sensor_dump() @@ -99,7 +97,7 @@ def print_fan_tray(tray): Fan_Status = [' Normal', ' Abnormal', ' no reading'] Airflow_Direction = ['B2F', 'F2B'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') if (tray == 1): @@ -114,14 +112,14 @@ def print_fan_tray(tray): fan1_status = 2 fan2_status = 2 - print ' Fan1 Speed: ',\ - get_pmc_register('FAN1_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN1_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN1_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN1_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 2): @@ -136,14 +134,14 @@ def print_fan_tray(tray): fan1_status = 2 fan2_status = 2 - print ' Fan1 Speed: ',\ - get_pmc_register('FAN2_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN2_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN2_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN2_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 3): @@ -158,14 +156,14 @@ def print_fan_tray(tray): fan1_status = 2 fan2_status = 2 - print ' Fan1 Speed: ',\ - get_pmc_register('FAN3_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN3_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN3_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN3_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 4): @@ -180,14 +178,14 @@ def print_fan_tray(tray): fan1_status = 2 fan2_status = 2 - print ' Fan1 Speed: ',\ - get_pmc_register('FAN4_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN4_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN4_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN4_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) print('\nFan Trays:') @@ -197,7 +195,7 @@ def print_fan_tray(tray): if (get_pmc_register(fan_presence)): print_fan_tray(tray) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print('\n Fan Tray ' + str(tray + 1) + ': Not present') # Print the information for PSU1, PSU2 @@ -206,51 +204,51 @@ def print_psu(psu): # PSU FAN details if (psu == 1): - print ' PSU1:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU1_Normal_temp') - print ' Chassis Temperature: ',\ - get_pmc_register('PSU1_Chass_temp') - print ' System Temperature: ',\ - get_pmc_register('PSU1_Sys_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU1_rpm') - print ' Input Voltage: ',\ - get_pmc_register('PSU1_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU1_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU1_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU1_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU1_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU1_Out_amp') + print(' PSU1:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU1_Normal_temp')) + print(' Chassis Temperature: ', + get_pmc_register('PSU1_Chass_temp')) + print(' System Temperature: ', + get_pmc_register('PSU1_Sys_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU1_rpm')) + print(' Input Voltage: ', + get_pmc_register('PSU1_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU1_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU1_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU1_Out_watt')) + print(' Input Current: ', + get_pmc_register('PSU1_In_amp')) + print(' Output Current: ', + get_pmc_register('PSU1_Out_amp')) else: - print ' PSU2:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU2_Normal_temp') - print ' Chassis Temperature: ',\ - get_pmc_register('PSU2_Chass_temp') - print ' System Temperature: ',\ - get_pmc_register('PSU2_Sys_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU2_rpm') - print ' Input Voltage: ',\ - get_pmc_register('PSU2_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU2_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU2_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU2_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU2_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU2_Out_amp') + print(' PSU2:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU2_Normal_temp')) + print(' Chassis Temperature: ', + get_pmc_register('PSU2_Chass_temp')) + print(' System Temperature: ', + get_pmc_register('PSU2_Sys_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU2_rpm')) + print(' Input Voltage: ', + get_pmc_register('PSU2_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU2_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU2_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU2_Out_watt')) + print(' Input Current: ', + get_pmc_register('PSU2_In_amp')) + print(' Output Current: ', + get_pmc_register('PSU2_Out_amp')) print('\nPSUs:') @@ -259,7 +257,7 @@ def print_psu(psu): if (get_pmc_register(psu_presence)): print_psu(psu) else: - print '\n PSU ', psu, 'Not present' + print('\n PSU ', psu, 'Not present') -print '\n Total Power: ',\ - get_pmc_register('PSU_Total_watt') +print('\n Total Power: ', + get_pmc_register('PSU_Total_watt')) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/port_irq_enable.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/port_irq_enable.py index e7442ba168f5..ff9d9ce8d723 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/port_irq_enable.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/port_irq_enable.py @@ -1,13 +1,12 @@ -#!/usr/bin/python +#!/usr/bin/python3 try: - import struct - import sys - from os import * - from mmap import * + import struct + from os import * + from mmap import * except ImportError as e: - raise ImportError("%s - required module no found" % str(e)) + raise ImportError("%s - required module no found" % str(e)) BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" PORT_START = 0 @@ -15,19 +14,19 @@ def pci_mem_write(mm, offset, data): - mm.seek(offset) - mm.write(struct.pack('I', data)) + mm.seek(offset) + mm.write(struct.pack('I', data)) def pci_set_value(resource, val, offset): - fd = open(resource, O_RDWR) - mm = mmap(fd, 0) - val = pci_mem_write(mm, offset, val) - mm.close() - close(fd) - return val - -#Enabled interrupt for qsfp and sfp + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + +# Enabled interrupt for qsfp and sfp for port_num in range(PORT_START, PORT_END+1): - port_offset = 0x400c + ((port_num) * 16) - pci_set_value(BASE_RES_PATH, 0x31, port_offset) + port_offset = 0x400c + ((port_num) * 16) + pci_set_value(BASE_RES_PATH, 0x31, port_offset) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh index 99a5e8a52334..8469b844757b 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh @@ -105,20 +105,20 @@ switch_board_modsel() { do port_addr=$(( 16384 + ((i - 1) * 16))) hex=$( printf "0x%x" $port_addr ) - python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 done # Disabling low power mode for last two 10G ports # From last 6th bit: Disable - 0; Enable - 1 - reg_offset=$(python /usr/bin/pcisysfs.py --get --offset 0x4400 --res $resource | cut -d':' -f 2) + reg_offset=$(/usr/bin/pcisysfs.py --get --offset 0x4400 --res $resource | cut -d':' -f 2) reg_offset=$( printf '0x%s' $reg_offset) reg_offset=$( printf '0x%x' $(( $reg_offset & 0xbf )) ) - python /usr/bin/pcisysfs.py --set --offset 0x4400 --val $reg_offset --res $resource > /dev/null 2>&1 + /usr/bin/pcisysfs.py --set --offset 0x4400 --val $reg_offset --res $resource > /dev/null 2>&1 - reg_offset=$(python /usr/bin/pcisysfs.py --get --offset 0x4410 --res $resource | cut -d':' -f 2) + reg_offset=$(/usr/bin/pcisysfs.py --get --offset 0x4410 --res $resource | cut -d':' -f 2) reg_offset=$( printf '0x%s' $reg_offset) reg_offset=$( printf '0x%x' $(( $reg_offset & 0xbf )) ) - python /usr/bin/pcisysfs.py --set --offset 0x4410 --val $reg_offset --res $resource > /dev/null 2>&1 + /usr/bin/pcisysfs.py --set --offset 0x4410 --val $reg_offset --res $resource > /dev/null 2>&1 } # Copy led_proc_init.soc file according to the HWSKU @@ -142,6 +142,7 @@ install_python_api_package() { platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) } remove_python_api_package() { @@ -149,6 +150,11 @@ remove_python_api_package() { if [ $? -eq 0 ]; then rv=$(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) fi + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi } # Readout firmware version of the system and @@ -225,7 +231,7 @@ if [ "$1" == "init" ]; then switch_board_modsel init_switch_port_led install_python_api_package - python /usr/bin/port_irq_enable.py + /usr/bin/port_irq_enable.py platform_firmware_versions diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py index 0eec21c09c28..b9aea703b46e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py @@ -11,6 +11,7 @@ try: import os import select + import sys from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Eeprom @@ -49,7 +50,7 @@ def __init__(self): self.PORT_START = 1 self.PORT_END = 66 PORTS_IN_BLOCK = (self.PORT_END + 1) - _sfp_port = range(65, self.PORT_END + 1) + _sfp_port = list(range(65, self.PORT_END + 1)) eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" for index in range(self.PORT_START, PORTS_IN_BLOCK): @@ -98,7 +99,7 @@ def __del__(self): def _get_register(self, reg_file): retval = 'ERR' if (not os.path.isfile(reg_file)): - print reg_file, 'not found !' + print(reg_file, 'not found !') return retval try: @@ -258,14 +259,6 @@ def get_base_mac(self): """ return self._eeprom.base_mac_addr() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py index 82cf6d6489aa..c250a82b051a 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py @@ -13,7 +13,7 @@ import os.path from sonic_eeprom import eeprom_tlvinfo import binascii -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -26,8 +26,8 @@ def __init__(self): if os.path.exists(f): self.eeprom_path = f break - if self.eeprom_path is None: - return + if self.eeprom_path is None: + return super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) self.eeprom_tlv_dict = dict() try: diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan.py index 17b2f8db5b91..39307d453486 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan.py @@ -170,5 +170,5 @@ def get_speed(self): if not is_valid or self.max_speed == 0: speed = 0 else: - speed = (100 * fan_speed)/self.max_speed + speed = (100 * fan_speed)//self.max_speed return speed diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py index 7f213edbd451..d46d24d0cb91 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py @@ -111,7 +111,7 @@ def get_voltage(self): if not is_valid: voltage = 0 - return "{:.1f}".format(voltage) + return float(voltage) def get_current(self): """ @@ -125,7 +125,7 @@ def get_current(self): if not is_valid: current = 0 - return "{:.1f}".format(current) + return float(current) def get_power(self): """ @@ -139,7 +139,7 @@ def get_power(self): if not is_valid: power = 0 - return "{:.1f}".format(power) + return float(power) def get_powergood_status(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py deleted file mode 100755 index 047618e057c8..000000000000 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2015 Dell Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR -# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT -# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS -# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. -# -# See the Apache Version 2.0 License for specific language governing -# permissions and limitations under the License. - -import struct -import sys -import getopt -from os import * -from mmap import * - -def usage(): - ''' This is the Usage Method ''' - - print '\t\t pcisysfs.py --get --offset --res ' - print '\t\t pcisysfs.py --set --val --offset --res ' - sys.exit(1) - -def pci_mem_read(mm,offset): - mm.seek(offset) - read_data_stream=mm.read(4) - print "" - reg_val=struct.unpack('I',read_data_stream) - print "reg_val read:%x"%reg_val - return reg_val - -def pci_mem_write(mm,offset,data): - mm.seek(offset) - print "data to write:%x"%data - mm.write(struct.pack('I',data)) - -def pci_set_value(resource,val,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_write(mm,offset,val) - -def pci_get_value(resource,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_read(mm,offset) - -def main(argv): - - ''' The main function will read the user input from the - command line argument and process the request ''' - - opts = '' - val = '' - choice = '' - resource = '' - offset = '' - - try: - opts, args = getopt.getopt(argv, "hgsv:" , \ - ["val=","res=","offset=","help", "get", "set"]) - - except getopt.GetoptError: - usage() - - for opt,arg in opts: - - if opt in ('-h','--help'): - choice = 'help' - - elif opt in ('-g', '--get'): - choice = 'get' - - elif opt in ('-s', '--set'): - choice = 'set' - - elif opt == '--res': - resource = arg - - elif opt == '--val': - val = int(arg,16) - - elif opt == '--offset': - offset = int(arg,16) - - if choice == 'set' and val != '' and offset !='' and resource !='': - pci_set_value(resource,val,offset) - - elif choice == 'get' and offset != '' and resource !='': - pci_get_value(resource,offset) - - else: - usage() - -#Calling the main method -if __name__ == "__main__": - main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py index 2fd2b84900da..1a5778525db2 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py @@ -1,9 +1,9 @@ -#!/usr/bin/python +#!/usr/bin/python3 # On Z9332F, the BaseBoard Management Controller is an # autonomous subsystem provides monitoring and management # facility independent of the host CPU. IPMI standard # protocol is used with ipmitool to fetch sensor details. -# Current script support X00 board only. X01 support will +# Current script support X00 board only. X01 support will # be added soon. This provies support for the # following objects: # * Onboard temperature sensors @@ -11,11 +11,9 @@ # * PSU -import os import sys import logging import subprocess -import commands Z9332F_MAX_FAN_TRAYS = 7 Z9332F_MAX_PSUS = 2 @@ -40,7 +38,7 @@ def ipmi_sensor_dump(): status = 1 global ipmi_sdr_list ipmi_cmd = IPMI_SENSOR_DATA - status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + status, ipmi_sdr_list = subprocess.getstatusoutput(ipmi_cmd) if status: logging.error('Failed to execute:' + ipmi_sdr_list) @@ -57,7 +55,7 @@ def get_pmc_register(reg_name): output = item.strip() if output is None: - print('\nFailed to fetch: ' + reg_name + ' sensor ') + print('\nFailed to fetch: ' + reg_name + ' sensor ') sys.exit(0) output = output.split('|')[1] @@ -75,7 +73,7 @@ def print_temperature_sensors(): for x in (('TEMP_FAN_U52', 'Fan U52'), ('TEMP_FAN_U17', 'Fan U17'), - ('TEMP_SW_U52', 'SW U52'), + ('TEMP_SW_U52', 'SW U52'), ('TEMP_SW_U16', 'SW U16'), ('TEMP_BB_U3', 'Baseboard U3'), ('TEMP_CPU', 'Near CPU'), @@ -88,7 +86,7 @@ def print_temperature_sensors(): ('SW_U14_Temp', 'SW U14'), ('SW_U4403_Temp', 'SW U4403') ): - print ' {0:32}{1}'.format(x[1] + ':', get_pmc_register(x[0])) + print(' {0:32}{1}'.format(x[1] + ':', get_pmc_register(x[0]))) ipmi_sensor_dump() @@ -102,14 +100,14 @@ def print_fan_tray(tray): Fan_Status = [' Normal', ' Abnormal'] Airflow_Direction = ['B2F', 'F2B'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') - print ' Fan1 Speed: ',\ - get_pmc_register('Fan{}_Front'.format(tray)) - print ' Fan2 Speed: ',\ - get_pmc_register('Fan{}_Rear'.format(tray)) - print ' Fan State: ',\ - Fan_Status[int(get_pmc_register('Fan{}_Status'.format(tray)), 16)] + print(' Fan1 Speed: ', + get_pmc_register('Fan{}_Front'.format(tray))) + print(' Fan2 Speed: ', + get_pmc_register('Fan{}_Rear'.format(tray))) + print(' Fan State: ', + Fan_Status[int(get_pmc_register('Fan{}_Status'.format(tray)), 16)]) print('\nFan Trays:') @@ -119,7 +117,7 @@ def print_fan_tray(tray): if (get_pmc_register(fan_presence)): print_fan_tray(tray) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print('\n Fan Tray ' + str(tray + 1) + ': Not present') def get_psu_presence(index): """ @@ -132,9 +130,9 @@ def get_psu_presence(index): ret_status = 1 if index == 1: - status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU1_DATA_DOCKER) elif index == 2: - ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + ret_status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU2_DATA_DOCKER) #if ret_status: # print ipmi_cmd_ret @@ -144,7 +142,7 @@ def get_psu_presence(index): psu_status = ipmi_cmd_ret if psu_status == '1': - status = 1 + status = 1 return status @@ -165,28 +163,28 @@ def print_psu(psu): # print ' Input: ', Psu_Input_Type[psu_input_type] # print ' Type: ', Psu_Type[psu_type] - print ' PSU{}:'.format(psu) - print ' Inlet Temperature: ',\ - get_pmc_register('PSU{}_Temp1'.format(psu)) - print ' Hotspot Temperature: ',\ - get_pmc_register('PSU{}_Temp2'.format(psu)) - print ' FAN RPM: ',\ - get_pmc_register('PSU{}_Fan'.format(psu)) + print(' PSU{}:'.format(psu)) + print(' Inlet Temperature: ', + get_pmc_register('PSU{}_Temp1'.format(psu))) + print(' Hotspot Temperature: ', + get_pmc_register('PSU{}_Temp2'.format(psu))) + print(' FAN RPM: ', + get_pmc_register('PSU{}_Fan'.format(psu))) # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] # PSU input & output monitors - print ' Input Voltage: ',\ - get_pmc_register('PSU{}_VIn'.format(psu)) - print ' Output Voltage: ',\ - get_pmc_register('PSU{}_VOut'.format(psu)) - print ' Input Power: ',\ - get_pmc_register('PSU{}_PIn'.format(psu)) - print ' Output Power: ',\ - get_pmc_register('PSU{}_POut'.format(psu)) - print ' Input Current: ',\ - get_pmc_register('PSU{}_CIn'.format(psu)) - print ' Output Current: ',\ - get_pmc_register('PSU{}_COut'.format(psu)) + print(' Input Voltage: ', + get_pmc_register('PSU{}_VIn'.format(psu))) + print(' Output Voltage: ', + get_pmc_register('PSU{}_VOut'.format(psu))) + print(' Input Power: ', + get_pmc_register('PSU{}_PIn'.format(psu))) + print(' Output Power: ', + get_pmc_register('PSU{}_POut'.format(psu))) + print(' Input Current: ', + get_pmc_register('PSU{}_CIn'.format(psu))) + print(' Output Current: ', + get_pmc_register('PSU{}_COut'.format(psu))) print('\nPSUs:') @@ -195,4 +193,4 @@ def print_psu(psu): if (get_psu_presence(psu)): print_psu(psu) else: - print '\n PSU ', psu, 'Not present' + print('\n PSU ', psu, 'Not present') diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh index ab2a787a6627..cbbd7c475746 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh @@ -105,7 +105,7 @@ switch_board_modsel() { do port_addr=$(( 16384 + ((i - 1) * 16))) hex=$( printf "0x%x" $port_addr ) - python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 done } @@ -160,7 +160,7 @@ if [ "$1" == "init" ]; then switch_board_qsfp "new_device" switch_board_sfp "new_device" switch_board_led_default - # python /usr/bin/qsfp_irq_enable.py + # /usr/bin/qsfp_irq_enable.py platform_firmware_versions elif [ "$1" == "deinit" ]; then From 7f59a6e46eb0a267c41097423cac217cf358df78 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Sun, 18 Oct 2020 07:08:19 +0300 Subject: [PATCH 1250/1427] [Mellanox] Configure SAI to log to syslog instead of stdout. (#5634) Example of syslog message from Mellanox SAI: "Oct 7 15:39:11.482315 arc-switch1025 INFO syncd#supervisord: syncd Oct 07 15:39:11 NOTICE SAI_BUFFER: mlnx_sai_buffer.c[3893]- mlnx_clear_buffer_pool_stats: Clear pool stats pool id:1" There is a log INFO from supervisord which actually printed NOTICE and date again. This confusion happens becuase if SAI is not built to log to syslog it will log everything to stdout with format "[date] [level] [message]" so supervisord sends it to syslog with level INFO. New logs look like: "Oct 7 15:40:21.488055 arc-switch1025 NOTICE syncd#SDK [SAI_BUFFER]: mlnx_sai_buffer.c[3893]- mlnx_clear_buffer_pool_stats: Clear pool stats pool id:17" Signed-off-by: Stepan Blyschak --- platform/mellanox/mlnx-sai/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-sai/Makefile b/platform/mellanox/mlnx-sai/Makefile index de6a7152d601..715f43ef0355 100644 --- a/platform/mellanox/mlnx-sai/Makefile +++ b/platform/mellanox/mlnx-sai/Makefile @@ -10,7 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : pushd mlnx_sai chmod a+x autogen.sh - debuild -e 'make_extra_flags="DEFS=-DACS_OS"' -us -uc -d -b + debuild -e 'make_extra_flags="DEFS=-DACS_OS -DCONFIG_SYSLOG"' -us -uc -d -b popd mv $(DERIVED_TARGETS) $* $(DEST)/ From 8011edc30753861acd4bacb11edfe30748f8c566 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 17 Oct 2020 22:00:14 -0700 Subject: [PATCH 1251/1427] [platform] Remove references to deprecated get_serial_number() method in Chassis class (#5649) The `get_serial_number()` method in the ChassisBase and ModuleBase classes was redundant, as the `get_serial()` method is inherited from the DeviceBase class. This method was removed from the base classes in sonic-platform-common and the submodule was updated in https://github.com/Azure/sonic-buildimage/pull/5625. This PR aligns the existing vendor platform API implementations to remove the `get_serial_number()` methods and ensure the `get_serial()` methods are implemented, if they weren't previously. Note that this PR does not modify the Dell platform API implementations, as this will be handled as part of https://github.com/Azure/sonic-buildimage/pull/5609 --- .../sonic_platform/chassis.py | 2 +- .../x86_64-cel_e1031-r0/sonic_platform/chassis.py | 2 +- .../x86_64-cel_seastone-r0/sonic_platform/chassis.py | 10 +--------- .../sonic_platform/chassis.py | 2 +- .../sonic_platform/chassis.py | 9 --------- .../services/platform_api/sonic_platform/chassis.py | 8 -------- .../d6356/sonic_platform/chassis.py | 9 --------- .../d7054q28b/sonic_platform/chassis.py | 9 --------- .../sonic_platform/chassis.py | 2 +- .../mlnx-platform-api/sonic_platform/chassis.py | 2 +- 10 files changed, 6 insertions(+), 49 deletions(-) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py index e737dae1c3cf..90b05465d27a 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py @@ -93,7 +93,7 @@ def get_base_mac(self): """ return self._eeprom.get_mac() - def get_serial_number(self): + def get_serial(self): """ Retrieves the hardware serial number for the chassis Returns: diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py index 719170d831b7..42a81748a44a 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py @@ -87,7 +87,7 @@ def get_base_mac(self): """ return self._eeprom.get_mac() - def get_serial_number(self): + def get_serial(self): """ Retrieves the hardware serial number for the chassis Returns: diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index 18d57096b6d3..4bd9d0851b5a 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -91,14 +91,6 @@ def get_base_mac(self): """ return self._eeprom.get_mac() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.get_serial() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis @@ -252,7 +244,7 @@ def get_serial(self): Returns: string: Serial number of device """ - return self.get_serial_number() + return self._eeprom.get_serial() def get_status(self): """ diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py index b4e2760d0ce9..21a3ff2a9173 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py @@ -75,7 +75,7 @@ def get_base_mac(self): """ return self._eeprom.get_mac() - def get_serial_number(self): + def get_serial(self): """ Retrieves the hardware serial number for the chassis Returns: diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py index 1ca885ff2a40..1f9102271431 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py @@ -101,15 +101,6 @@ def get_base_mac(self): """ return self._eeprom.base_mac_addr() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/chassis.py index 41eff734407b..aa7671484889 100644 --- a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/chassis.py @@ -126,14 +126,6 @@ def get_base_mac(self): """ return self._eeprom.get_mac() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.get_serial() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py index f961cb8cde21..8f3520259038 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py @@ -116,15 +116,6 @@ def get_base_mac(self): """ return self._eeprom.base_mac_address() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py index b5053cf4e2b4..0c83a22cd251 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py @@ -119,15 +119,6 @@ def get_base_mac(self): """ return self._eeprom.base_mac_addr() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py index 0e3d43fa07e4..38344cecae13 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py @@ -86,7 +86,7 @@ def get_part_number(self): return False - def get_serial_number(self): + def get_serial(self): serial_number_list = self.get_parameter_value('Serial Number') if serial_number_list: serial_number = ''.join(serial_number_list) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 630b35903dff..b5efac8fadbd 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -287,7 +287,7 @@ def get_base_mac(self): return self._eeprom.get_base_mac() - def get_serial_number(self): + def get_serial(self): """ Retrieves the hardware serial number for the chassis From 678b66359d2d7e7154e2d043074db5bc45f54608 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 19 Oct 2020 09:46:02 -0700 Subject: [PATCH 1252/1427] [procdockerstatsd] Convert to Python 3 (#5657) Make procdockerstatsd Python 3-compliant and set interpreter to python3 in shebang. Also some other cleanup to improve code reuse. --- .../procdockerstatsd/procdockerstatsd | 81 +++++++++---------- 1 file changed, 36 insertions(+), 45 deletions(-) diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd index b7dd1705db4c..90b7bd10c95f 100755 --- a/files/image_config/procdockerstatsd/procdockerstatsd +++ b/files/image_config/procdockerstatsd/procdockerstatsd @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 ''' procdockerstatsd Daemon which periodically gathers process and docker statistics and pushes the data to STATE_DB @@ -29,7 +29,7 @@ class ProcDockerStats(daemon_base.DaemonBase): self.state_db.connect("STATE_DB") def run_command(self, cmd): - proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) + proc = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE) (stdout, stderr) = proc.communicate() if proc.returncode != 0: self.log_error("Error running command '{}'".format(cmd)) @@ -38,87 +38,79 @@ class ProcDockerStats(daemon_base.DaemonBase): return stdout def format_docker_cmd_output(self, cmdout): - lines = re.split("\n", cmdout) + lines = cmdout.splitlines() keys = re.split(" +", lines[0]) docker_data = dict() docker_data_list = [] - for item in lines[1:]: - values1 = re.split(" +", item) - docker_data = dict(zip(keys, values1)) + for line in lines[1:]: + values = re.split(" +", line) + docker_data = {key: value for key, value in zip(keys, values)} docker_data_list.append(docker_data) formatted_dict = self.create_docker_dict(docker_data_list) return formatted_dict def format_process_cmd_output(self, cmdout): - lines = re.split("\n", cmdout) + lines = cmdout.splitlines() keys = re.split(" +", lines[0]) - keylist = list(filter(None, keys)) + key_list = [key for key in keys if key] process_data = dict() process_data_list = [] - for item in lines[1:]: - values1 = re.split(" +", str(item)) + for line in lines[1:]: + values = re.split(" +", line) # To remove extra space before UID - val = list(filter(None, values1)) + val_list = [val for val in values if val] # Merging extra columns created due to space in cmd ouput - val[8:] = [' '.join(val[8:])] - process_data = dict(zip(keylist, val)) + val_list[8:] = [' '.join(val_list[8:])] + process_data = {key: value for key, value in zip(key_list, val_list)} process_data_list.append(process_data) return process_data_list def convert_to_bytes(self, value): - unit_value = re.search('[a-zA-Z]+', value) - value_to_convert = float(filter(str.isdigit, value)) - unit = unit_value.group(0) UNITS_B = 'B' UNITS_KB = 'KB' UNITS_MB = 'MB' UNITS_MiB = 'MiB' UNITS_GiB = 'GiB' - if unit.lower() == UNITS_B.lower(): - return int(round(value_to_convert)) - elif unit.lower() == UNITS_KB.lower(): - value_converted = value_to_convert * 1000 - return int(round(value_converted)) - elif unit.lower() == UNITS_MB.lower(): - value_converted = value_to_convert * 1000 * 1000 - return int(round(value_converted)) - elif unit.lower() == UNITS_MiB.lower(): - value_converted = value_to_convert * 1024 * 1024 - return int(round(value_converted)) - elif unit.lower() == UNITS_GiB.lower(): - value_converted = value_to_convert * 1024 * 1024 * 1024 - return int(round(value_converted)) + + res = re.match('(\d+\.?\d*)([a-zA-Z]+)', value) + value = float(res.groups()[0]) + units = res.groups()[1] + if units.lower() == UNITS_KB.lower(): + value *= 1000 + elif units.lower() == UNITS_MB.lower(): + value *= (1000 * 1000) + elif units.lower() == UNITS_MiB.lower(): + value *= (1024 * 1024) + elif units.lower() == UNITS_GiB.lower(): + value *= (1024 * 1024 * 1024) + + return int(round(value)) def create_docker_dict(self, dict_list): dockerdict = {} for row in dict_list[0:]: cid = row.get('CONTAINER ID') if cid: - key = 'DOCKER_STATS|' + str(cid) + key = 'DOCKER_STATS|{}'.format(cid) dockerdict[key] = {} dockerdict[key]['NAME'] = row.get('NAME') - splitcol = row.get('CPU %') - cpu = re.split("%", str(splitcol)) + cpu = row.get('CPU %').split("%") dockerdict[key]['CPU%'] = str(cpu[0]) - splitcol = row.get('MEM USAGE / LIMIT') - memuse = re.split(" / ", str(splitcol)) + memuse = row.get('MEM USAGE / LIMIT').split(" / ") # converting MiB and GiB to bytes dockerdict[key]['MEM_BYTES'] = str(self.convert_to_bytes(memuse[0])) dockerdict[key]['MEM_LIMIT_BYTES'] = str(self.convert_to_bytes(memuse[1])) - splitcol = row.get('MEM %') - mem = re.split("%", str(splitcol)) + mem = row.get('MEM %').split("%") dockerdict[key]['MEM%'] = str(mem[0]) - splitcol = row.get('NET I/O') - netio = re.split(" / ", str(splitcol)) + netio = row.get('NET I/O').split(" / ") dockerdict[key]['NET_IN_BYTES'] = str(self.convert_to_bytes(netio[0])) dockerdict[key]['NET_OUT_BYTES'] = str(self.convert_to_bytes(netio[1])) - splitcol = row.get('BLOCK I/O') - blockio = re.split(" / ", str(splitcol)) + blockio = row.get('BLOCK I/O').split(" / ") dockerdict[key]['BLOCK_IN_BYTES'] = str(self.convert_to_bytes(blockio[0])) dockerdict[key]['BLOCK_OUT_BYTES'] = str(self.convert_to_bytes(blockio[1])) @@ -137,8 +129,8 @@ class ProcDockerStats(daemon_base.DaemonBase): return False # wipe out all data from state_db before updating self.state_db.delete_all_by_pattern('STATE_DB', 'DOCKER_STATS|*') - for k1,v1 in dockerdata.iteritems(): - for k2,v2 in v1.iteritems(): + for k1,v1 in dockerdata.items(): + for k2,v2 in v1.items(): self.update_state_db(k1, k2, v2) return True @@ -151,7 +143,7 @@ class ProcDockerStats(daemon_base.DaemonBase): for row in processdata[0:]: cid = row.get('PID') if cid: - value = 'PROCESS_STATS|' + str(cid) + value = 'PROCESS_STATS|{}'.format(cid) uid = row.get('UID') self.update_state_db(value, 'UID', uid) ppid = row.get('PPID') @@ -206,4 +198,3 @@ def main(): if __name__ == '__main__': main() - From 97caf46b00b2e040d08ade7723ea92bec602fd2d Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Mon, 19 Oct 2020 19:49:19 +0300 Subject: [PATCH 1253/1427] [Mellanox] Add sensors labels for human readable output for MSN2010 (#5658) Add sensors labels for human readable output for MSN2010 Signed-off-by: Shlomi Bitton --- .../x86_64-mlnx_msn2010-r0/sensors.conf | 129 ++++++------------ 1 file changed, 43 insertions(+), 86 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2010-r0/sensors.conf index 3b68f775df2d..7f5b023afec6 100644 --- a/device/mellanox/x86_64-mlnx_msn2010-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/sensors.conf @@ -1,92 +1,49 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN2010 +################################################################################ + +# Temperature sensors bus "i2c-2" "i2c-1-mux (chan_id 1)" -chip "mlxsw-i2c-2-48" - label temp1 "ASIC Temp" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" bus "i2c-7" "i2c-1-mux (chan_id 6)" -chip "lm75-*" - label temp1 "Ambient Port Temp" + chip "lm75-i2c-*-4a" + label temp1 "Ambient Port Side Temp (air exhaust)" + chip "lm75-i2c-*-4b" + label temp1 "Ambient Fan Side Temp (air intake)" +# Power supplies bus "i2c-5" "i2c-1-mux (chan_id 4)" -chip "tps53679-*" - label vin "TPS vin" - label vout1 "TPS vout1" - label vout2 "TPS vout2" - label temp1 "TPS Temp1" - label temp2 "TPS Temp2" - label pout1 "TPS pouti1" - label pout2 "TPS pout2" - label iout1 "TPS iout1" - label iout2 "TPS iout2" - -chip "mlxsw-*" - ignore temp2 - ignore temp3 - ignore temp4 - ignore temp5 - ignore temp6 - ignore temp7 - ignore temp8 - ignore temp9 - ignore temp10 - ignore temp11 - ignore temp12 - ignore temp13 - ignore temp14 - ignore temp15 - ignore temp16 - ignore temp17 - ignore temp18 - ignore temp19 - ignore temp20 - ignore temp21 - ignore temp22 - ignore temp23 - ignore temp24 - ignore temp25 - ignore temp26 - ignore temp27 - ignore temp28 - ignore temp29 - ignore temp30 - ignore temp31 - ignore temp32 - ignore temp33 - ignore temp34 - ignore temp35 - ignore temp36 - ignore temp37 - ignore temp38 - ignore temp39 - ignore temp40 - ignore temp41 - ignore temp42 - ignore temp43 - ignore temp44 - ignore temp45 - ignore temp46 - ignore temp47 - ignore temp48 - ignore temp49 - ignore temp50 - ignore temp51 - ignore temp52 - ignore temp53 - ignore temp54 - ignore temp55 - ignore temp56 - ignore temp57 - ignore temp58 - ignore temp59 - ignore temp60 - ignore temp61 - ignore temp62 - ignore temp63 - ignore temp64 + chip "tps53679-i2c-*-70" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 0.9V VCORE (out)" + label in4 "PMIC-1 1.2V Rail (out)" + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 0.9V VCORE Pwr (out)" + label power2 "PMIC-1 1.2V Rail Pwr (out)" + label curr1 "PMIC-1 0.9V VCORE Curr (out)" + label curr2 "PMIC-1 1.2V Rail Curr (out)" + chip "tps53679-i2c-*-71" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 2.2V Rail (out)" + ignore in4 + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 2.2V Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-2 2.2V Rail Curr (out)" + ignore curr2 -chip "*-virtual-*" - ignore temp1 - ignore temp2 - -chip "dps460-*" - ignore fan2 - ignore fan3 +# Chassis fans +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label fan1 "Chassis Fan 1" + label fan2 "Chassis Fan 2" + label fan3 "Chassis Fan 3" + label fan4 "Chassis Fan 4" From 9f73b8aeb0b5410811cd9c374f9c3e942f045d23 Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Mon, 19 Oct 2020 19:50:44 +0300 Subject: [PATCH 1254/1427] [Mellanox] Add sensors labels for human readable output for MSN2100 (#5659) Add sensors labels for human readable output for MSN2100 Signed-off-by: Shlomi Bitton --- .../x86_64-mlnx_msn2100-r0/sensors.conf | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf deleted file mode 120000 index ea04d66d008c..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf +++ /dev/null @@ -1 +0,0 @@ -../x86_64-mlnx_msn2700-r0/sensors.conf \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf new file mode 100644 index 000000000000..e37dd25f03db --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf @@ -0,0 +1,51 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN2100 +################################################################################ + +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" + +bus "i2c-7" "i2c-1-mux (chan_id 6)" + chip "lm75-i2c-*-4a" + label temp1 "Ambient Port Side Temp (air exhaust)" + chip "lm75-i2c-*-4b" + label temp1 "Ambient Fan Side Temp (air intake)" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 4)" + chip "pmbus-i2c-*-41" + label in1 "PMB-1 12V Rail (in)" + label in2 "PMB-1 0.9V Rail (out)" + label in3 "PMB-1 1.8V Rail (out)" + label temp1 "PMB-1 Temp 1" + label temp2 "PMB-1 Temp 2" + ignore power1 + label power2 "PMB-1 0.9V Rail Pwr (out)" + label power3 "PMB-1 1.8V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-1 0.9V Rail Curr (out)" + label curr3 "PMB-1 1.8V Rail Curr (out)" + chip "pmbus-i2c-*-27" + label in1 "PMB-2 12V Rail (in)" + label in2 "PMB-2 3.3V Rail (out)" + label in3 "PMB-2 1.2V Rail (out)" + label temp1 "PMB-2 Temp 1" + label temp2 "PMB-2 Temp 2" + ignore power1 + label power2 "PMB-2 3.3V Rail Pwr (out)" + label power3 "PMB-2 1.2V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-2 3.3V Rail Curr (out)" + label curr3 "PMB-2 1.2V Rail Curr (out)" + +# Chassis fans +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label fan1 "Chassis Fan 1" + label fan2 "Chassis Fan 2" + label fan3 "Chassis Fan 3" + label fan4 "Chassis Fan 4" From b5043a2e498375051c4916cc2746bffef7322e5a Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Mon, 19 Oct 2020 19:51:52 +0300 Subject: [PATCH 1255/1427] [Mellanox] Add sensors labels for human readable output for MSN2410 (#5660) Add sensors labels for human readable output for MSN2410 --- .../x86_64-mlnx_msn2410-r0/sensors.conf | 82 ++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf deleted file mode 120000 index ea04d66d008c..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf +++ /dev/null @@ -1 +0,0 @@ -../x86_64-mlnx_msn2700-r0/sensors.conf \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf new file mode 100644 index 000000000000..ede1fbe3c768 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf @@ -0,0 +1,81 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN2410 +################################################################################ + +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" + +bus "i2c-7" "i2c-1-mux (chan_id 7)" + chip "lm75-i2c-7-4a" + label temp1 "Ambient Port Temp" + +bus "i2c-17" "i2c-1-mux (chan_id 17)" + chip "lm75-i2c-17-49" + label temp1 "Ambient Fan Temp" + +chip "acpitz-virtual-0" + label temp1 "ACPI CPU Temp" + label temp2 "ACPI Board Temp" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 5)" + chip "pmbus-i2c-*-41" + label in1 "PMB-1 PSU 12V Rail (in)" + label in2 "PMB-1 0.9V VCORE Rail (out)" + label temp1 "PMB-1 Temp 1" + label temp2 "PMB-1 Temp 2" + ignore power1 + label power2 "PMB-1 0.9V VCORE Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-1 0.9V VCORE Rail Curr (out)" + chip "pmbus-i2c-*-27" + label in1 "PMB-2 PSU 12V Rail (in)" + label in2 "PMB-2 3.3V Rail (out)" + label in3 "PMB-2 1.2V Rail (out)" + label temp1 "PMB-2 Temp 1" + label temp2 "PMB-2 Temp 2" + ignore power1 + label power2 "PMB-2 3.3V Rail Pwr (out)" + label power3 "PMB-2 1.2V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-2 3.3V Rail Curr (out)" + label curr3 "PMB-2 1.2V Rail Curr (out)" + +# Power supplies +bus "i2c-10" "i2c-1-mux (chan_id 10)" + chip "dps460-i2c-*-58" + label in1 "PSU-2(R) 220V Rail (in)" + label in2 "PSU-2(R) 12V Rail (out)" + label fan1 "PSU-2(R) Fan 1" + label temp1 "PSU-2(R) Temp 1" + label temp2 "PSU-2(R) Temp 2" + label power1 "PSU-2(R) 220V Rail Pwr (in)" + label power2 "PSU-2(R) 12V Rail Pwr (out)" + label curr1 "PSU-2(R) 220V Rail Curr (in)" + label curr2 "PSU-2(R) 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-1(L) 220V Rail (in)" + label in2 "PSU-1(L) 12V Rail (out)" + label fan1 "PSU-1(L) Fan 1" + label temp1 "PSU-1(L) Temp 1" + label temp2 "PSU-1(L) Temp 2" + label power1 "PSU-1(L) 220V Rail Pwr (in)" + label power2 "PSU-1(L) 12V Rail Pwr (out)" + label curr1 "PSU-1(L) 220V Rail Curr (in)" + label curr2 "PSU-1(L) 12V Rail Curr (out)" + +# Chassis fans +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label fan1 "Chassis Drawer-1 Fan-1" + label fan2 "Chassis Drawer-1 Fan-2" + label fan3 "Chassis Drawer-2 Fan-1" + label fan4 "Chassis Drawer-2 Fan-2" + label fan5 "Chassis Drawer-3 Fan-1" + label fan6 "Chassis Drawer-3 Fan-2" + label fan7 "Chassis Drawer-4 Fan-1" + label fan8 "Chassis Drawer-4 Fan-2" From edf4971b1680b3c2a002a58fe4516433a45e8aeb Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 19 Oct 2020 11:11:30 -0700 Subject: [PATCH 1256/1427] [caclmgrd] Prevent unnecessary iptables updates (#5312) When a large number of changes occur to the ACL table of Config DB, caclmgrd will get flooded with notifications, and previously, it would regenerate and apply the iptables rules for each change, which is unnecessary, as the iptables rules should only get applied once after the last change notification is received. If the ACL table contains a large number of control plane ACL rules, this could cause a large delay in caclmgrd getting the rules applied. This patch causes caclmgrd to delay updating the iptables rules until it has not received a change notification for at least 0.5 seconds. --- files/image_config/caclmgrd/caclmgrd | 102 ++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 10 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index cee0d8f96ceb..c5144a6633f0 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -15,6 +15,8 @@ try: import os import subprocess import sys + import threading + import time from sonic_py_common import daemon_base, device_info from swsscommon import swsscommon @@ -26,6 +28,8 @@ VERSION = "1.0" SYSLOG_IDENTIFIER = "caclmgrd" +DEFAULT_NAMESPACE = '' + # ========================== Helper Functions ========================= @@ -75,21 +79,38 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): } } + UPDATE_DELAY_SECS = 0.5 + def __init__(self, log_identifier): super(ControlPlaneAclManager, self).__init__(log_identifier) + # Update-thread-specific data per namespace + self.update_thread = {} + self.lock = {} + self.num_changes = {} + + # Initialize update-thread-specific data for default namespace + self.update_thread[DEFAULT_NAMESPACE] = None + self.lock[DEFAULT_NAMESPACE] = threading.Lock() + self.num_changes[DEFAULT_NAMESPACE] = 0 + SonicDBConfig.load_sonic_global_db_config() self.config_db_map = {} self.iptables_cmd_ns_prefix = {} - self.config_db_map[''] = ConfigDBConnector(use_unix_socket_path=True, namespace='') - self.config_db_map[''].connect() - self.iptables_cmd_ns_prefix[''] = "" - self.namespace_mgmt_ip = self.get_namespace_mgmt_ip(self.iptables_cmd_ns_prefix[''], '') - self.namespace_mgmt_ipv6 = self.get_namespace_mgmt_ipv6(self.iptables_cmd_ns_prefix[''], '') + self.config_db_map[DEFAULT_NAMESPACE] = ConfigDBConnector(use_unix_socket_path=True, namespace=DEFAULT_NAMESPACE) + self.config_db_map[DEFAULT_NAMESPACE].connect() + self.iptables_cmd_ns_prefix[DEFAULT_NAMESPACE] = "" + self.namespace_mgmt_ip = self.get_namespace_mgmt_ip(self.iptables_cmd_ns_prefix[DEFAULT_NAMESPACE], DEFAULT_NAMESPACE) + self.namespace_mgmt_ipv6 = self.get_namespace_mgmt_ipv6(self.iptables_cmd_ns_prefix[DEFAULT_NAMESPACE], DEFAULT_NAMESPACE) self.namespace_docker_mgmt_ip = {} self.namespace_docker_mgmt_ipv6 = {} + namespaces = device_info.get_all_namespaces() for front_asic_namespace in namespaces['front_ns']: + self.update_thread[front_asic_namespace] = None + self.lock[front_asic_namespace] = threading.Lock() + self.num_changes[front_asic_namespace] = 0 + self.config_db_map[front_asic_namespace] = ConfigDBConnector(use_unix_socket_path=True, namespace=front_asic_namespace) self.config_db_map[front_asic_namespace].connect() self.iptables_cmd_ns_prefix[front_asic_namespace] = "ip netns exec " + front_asic_namespace + " " @@ -99,6 +120,10 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): front_asic_namespace) for back_asic_namespace in namespaces['back_ns']: + self.update_thread[back_asic_namespace] = None + self.lock[back_asic_namespace] = threading.Lock() + self.num_changes[back_asic_namespace] = 0 + self.iptables_cmd_ns_prefix[back_asic_namespace] = "ip netns exec " + back_asic_namespace + " " self.namespace_docker_mgmt_ip[back_asic_namespace] = self.get_namespace_mgmt_ip(self.iptables_cmd_ns_prefix[back_asic_namespace], back_asic_namespace) @@ -495,9 +520,44 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): self.run_commands(iptables_cmds) + def check_and_update_control_plane_acls(self, namespace, num_changes): + """ + This function is intended to be spawned in a separate thread. + Its purpose is to prevent unnecessary iptables updates if we receive + multiple rapid ACL table update notifications. It sleeps for UPDATE_DELAY_SECS + then checks if any more ACL table updates were received in that window. If new + updates were received, it will sleep again and repeat the process until no + updates were received during the delay window, at which point it will update + iptables using the current ACL rules. + """ + while True: + # Sleep for our delay interval + time.sleep(self.UPDATE_DELAY_SECS) + + with self.lock[namespace]: + if self.num_changes[namespace] > num_changes: + # More ACL table changes occurred since this thread was spawned + # spawn a new thread with the current number of changes + new_changes = self.num_changes[namespace] - num_changes + self.log_info("ACL config not stable for namespace '{}': {} changes detected in the past {} seconds. Skipping update ..." + .format(namespace, new_changes, self.UPDATE_DELAY_SECS)) + num_changes = self.num_changes[namespace] + else: + if num_changes == self.num_changes[namespace] and num_changes > 0: + self.log_info("ACL config for namespace '{}' has not changed for {} seconds. Applying updates ..." + .format(namespace, self.UPDATE_DELAY_SECS)) + self.update_control_plane_acls(namespace) + else: + self.log_error("Error updating ACLs for namespace '{}'".format(namespace)) + + # Re-initialize + self.num_changes[namespace] = 0 + self.update_thread[namespace] = None + return + def run(self): - # Select Time-out for 10 Seconds - SELECT_TIMEOUT_MS = 1000 * 10 + # Set select timeout to 1 second + SELECT_TIMEOUT_MS = 1000 self.log_info("Starting up ...") @@ -515,7 +575,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): # Map of Namespace <--> susbcriber table's object config_db_subscriber_table_map = {} - # Loop through all asic namespaces (if present) and host (namespace='') + # Loop through all asic namespaces (if present) and host namespace (DEFAULT_NAMESPACE) for namespace in self.config_db_map.keys(): # Unconditionally update control plane ACLs once at start on given namespace self.update_control_plane_acls(namespace) @@ -540,14 +600,23 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): # Loop on select to see if any event happen on config db of any namespace while True: ctrl_plane_acl_notification = set() + + # A brief sleep appears necessary in this loop or any spawned + # update threads will get stuck. Appears to be due to the sel.select() call. + # TODO: Eliminate the need for this sleep. + time.sleep(0.1) + (state, selectableObj) = sel.select(SELECT_TIMEOUT_MS) # Continue if select is timeout or selectable object is not return if state != swsscommon.Select.OBJECT: continue - # Get the redisselect object from selectable object + + # Get the redisselect object from selectable object redisSelectObj = swsscommon.CastSelectableToRedisSelectObj(selectableObj) + # Get the corresponding namespace from redisselect db connector object namespace = redisSelectObj.getDbConnector().getNamespace() + # Pop data of both Subscriber Table object of namespace that got config db acl table event for table in config_db_subscriber_table_map[namespace]: while True: @@ -568,7 +637,20 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): # Update the Control Plane ACL of the namespace that got config db acl table event for namespace in ctrl_plane_acl_notification: - self.update_control_plane_acls(namespace) + with self.lock[namespace]: + if self.num_changes[namespace] == 0: + self.log_info("ACL change detected for namespace '{}'".format(namespace)) + + # Increment the number of change events we've received for this namespace + self.num_changes[namespace] += 1 + + # If an update thread is not already spawned for the namespace which we received + # the ACL table update event, spawn one now + if not self.update_thread[namespace]: + self.log_info("Spawning ACL update thread for namepsace '{}' ...".format(namespace)) + self.update_thread[namespace] = threading.Thread(target=self.check_and_update_control_plane_acls, + args=(namespace, self.num_changes[namespace])) + self.update_thread[namespace].start() # ============================= Functions ============================= From 73f38f6ce962d6d1835b30a94c6773320a661a0a Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 20 Oct 2020 02:30:38 +0800 Subject: [PATCH 1257/1427] [Mellanox] Optimize SFP Platform API implementation (#5476) Each SFP object inside Chassis will open an SDK client, this is not necessary and SDK client can be shared between SFP objects. --- .../sonic_platform/chassis.py | 14 ++- .../mlnx-platform-api/sonic_platform/sfp.py | 91 +++++++------------ 2 files changed, 43 insertions(+), 62 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index b5efac8fadbd..5ad205674bc8 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -75,6 +75,10 @@ def __del__(self): if self.sfp_event_initialized: self.sfp_event.deinitialize() + if self.sfp_module_initialized: + from sonic_platform.sfp import deinitialize_sdk_handle + deinitialize_sdk_handle(self.sdk_handle) + def initialize_psu(self): from sonic_platform.psu import Psu @@ -108,8 +112,14 @@ def initialize_fan(self): def initialize_sfp(self): from sonic_platform.sfp import SFP + from sonic_platform.sfp import initialize_sdk_handle self.sfp_module = SFP + self.sdk_handle = initialize_sdk_handle() + + if self.sdk_handle is None: + self.sfp_module_initialized = False + return # Initialize SFP list port_position_tuple = self._get_port_position_tuple_by_platform_name() @@ -120,9 +130,9 @@ def initialize_sfp(self): for index in range(self.PORT_START, self.PORT_END + 1): if index in range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1): - sfp_module = SFP(index, 'QSFP') + sfp_module = SFP(index, 'QSFP', self.sdk_handle) else: - sfp_module = SFP(index, 'SFP') + sfp_module = SFP(index, 'SFP', self.sdk_handle) self._sfp_list.append(sfp_module) self.sfp_module_initialized = True diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 1d6a618a370b..47a42bf8f8f9 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -9,7 +9,6 @@ ############################################################################# try: - import os import subprocess import time from sonic_platform_base.sfp_base import SfpBase @@ -283,59 +282,41 @@ # Global logger class instance logger = Logger() + +# SDK initializing stuff, called from chassis +def initialize_sdk_handle(): + rc, sdk_handle = sx_api_open(None) + if (rc != SX_STATUS_SUCCESS): + logger.log_warning("Failed to open api handle, please check whether SDK is running.") + sdk_handle = None + + return sdk_handle + +def deinitialize_sdk_handle(sdk_handle): + if sdk_handle is not None: + rc = sx_api_close(sdk_handle) + if (rc != SX_STATUS_SUCCESS): + logger.log_warning("Failed to close api handle.") + + return rc == SXD_STATUS_SUCCESS + else: + logger.log_warning("Sdk handle is none") + return False + class SFP(SfpBase): """Platform-specific SFP class""" - def __init__(self, sfp_index, sfp_type): + def __init__(self, sfp_index, sfp_type, sdk_handle): self.index = sfp_index + 1 self.sfp_eeprom_path = "qsfp{}".format(self.index) self.sfp_status_path = "qsfp{}_status".format(self.index) self._detect_sfp_type(sfp_type) self.dom_tx_disable_supported = False self._dom_capability_detect() - self.sdk_handle = None + self.sdk_handle = sdk_handle self.sdk_index = sfp_index - #SDK initializing stuff - def _initialize_sdk_handle(self): - """ - reference: device\mellanox\\pulgins\sfpreset.py - """ - rc, self.sdk_handle = sx_api_open(None) - if (rc != SX_STATUS_SUCCESS): - logger.log_warning("Failed to open api handle, please check whether SDK is running.") - self.sdk_handle = None - - self.mypid = os.getpid() - - - def _open_sdk(self): - if self.sdk_handle is None: - self._initialize_sdk_handle() - - rc = sxd_access_reg_init(self.mypid, None, 0) - if rc != 0: - logger.log_warning("Failed to initializing register access, please check that SDK is running.") - return False - - return True - - - def _close_sdk(self): - rc = sxd_access_reg_deinit() - if rc != 0: - logger.log_warning("Failed to deinitializing register access.") - #no further actions here - - - def _init_sx_meta_data(self): - meta = sxd_reg_meta_t() - meta.dev_id = DEVICE_ID - meta.swid = SWITCH_ID - return meta - - def get_presence(self): """ Retrieves the presence of the device @@ -1481,14 +1462,8 @@ def get_lpmode(self): Returns: A Boolean, True if lpmode is enabled, False if disabled """ - handle = self._open_sdk() - if handle is None: - logger.log_error("SDK handler is missing for sfp %d object" % self.index) - return False - admin_pwr_mode, oper_pwr_mode = self.mgmt_phy_mod_pwr_attr_get(SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E) - self._close_sdk() return oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E @@ -1863,16 +1838,10 @@ def reset(self): refer plugins/sfpreset.py """ - handle = self._open_sdk() - if handle is None: - logger.log_error("SDK handler is missing for sfp %d object" % self.index) - return False - rc = sx_mgmt_phy_mod_reset(self.sdk_handle, self.sdk_index) if rc != SX_STATUS_SUCCESS: logger.log_warning("sx_mgmt_phy_mod_reset failed, rc = %d" % rc) - self._close_sdk() return rc == SX_STATUS_SUCCESS @@ -1927,6 +1896,11 @@ def is_port_admin_status_up(self, log_port): assert rc == SXD_STATUS_SUCCESS, "sx_api_port_state_get failed, rc = %d" % rc admin_state = sx_port_admin_state_t_p_value(admin_state_p) + + delete_sx_port_oper_state_t_p(oper_state_p) + delete_sx_port_admin_state_t_p(admin_state_p) + delete_sx_port_module_state_t_p(module_state_p) + if admin_state == SX_PORT_ADMIN_STATUS_UP: return True else: @@ -1960,6 +1934,8 @@ def get_logical_ports(self): and self.is_port_admin_status_up(port_attributes.log_port): log_port_list.append(port_attributes.log_port) + delete_sx_port_attributes_t_arr(port_attributes_list) + delete_uint32_t_p(port_cnt_p) return log_port_list @@ -2017,11 +1993,6 @@ def set_lpmode(self, lpmode): Returns: A boolean, True if lpmode is set successfully, False if not """ - handle = self._open_sdk() - if handle is None: - logger.log_error("SDK handler is missing for sfp %d object" % self.index) - return False - log_port_list = self.get_logical_ports() if lpmode: self._set_lpmode_raw(log_port_list, SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E, SX_MGMT_PHY_MOD_PWR_MODE_LOW_E) @@ -2029,7 +2000,7 @@ def set_lpmode(self, lpmode): else: self._set_lpmode_raw(log_port_list, SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E, SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E) logger.log_info( "Disabled low power mode for module [%d]" % (self.sdk_index)) - self._close_sdk() + return True From de1f7421ac0c63b0b6420da2a337d7ab2cf8c6c3 Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Tue, 20 Oct 2020 02:02:27 +0300 Subject: [PATCH 1258/1427] [Mellanox] Add sensors labels for human readable output for MSN2700 (#5661) Add sensors labels for human readable output for MSN2700 Signed-off-by: Shlomi Bitton --- .../x86_64-mlnx_msn2700-r0/sensors.conf | 162 ++++++++---------- 1 file changed, 74 insertions(+), 88 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2700-r0/sensors.conf index 247db54f99d8..62f100d757e7 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/sensors.conf @@ -1,95 +1,81 @@ -bus "i2c-7" "i2c-1-mux (chan_id 5)" -chip "lm75-i2c-7-4a" - label temp1 "Ambient Port Temp" +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN2700 +################################################################################ -bus "i2c-5" "i2c-1-mux (chan_id 3)" -chip "ucd9200-i2c-5-27" - label in1 "UCD1 vin" - label in2 "ASIC 3.3 vout" - label in3 "ASIC 1.2 vout" - label temp1 "UCD1 Temp" - label temp2 "UCD1 Temp2" +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 2)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" -chip "ucd9200-i2c-5-41" - label in1 "UCD2 vin" - label in2 "ASIC Vcore vout" - label temp1 "UCD2 Temp1" - label temp2 "UCD2 Temp2" +bus "i2c-7" "i2c-1-mux (chan_id 7)" + chip "lm75-i2c-7-4a" + label temp1 "Ambient Port Temp" -bus "i2c-17" "i2c-1-mux (chan_id 7)" -chip "lm75-i2c-17-49" - label temp1 "Ambient Board Temp" +bus "i2c-17" "i2c-1-mux (chan_id 17)" + chip "lm75-i2c-17-49" + label temp1 "Ambient Fan Temp" -chip "mlxsw-*" - ignore temp2 - ignore temp3 - ignore temp4 - ignore temp5 - ignore temp6 - ignore temp7 - ignore temp8 - ignore temp9 - ignore temp10 - ignore temp11 - ignore temp12 - ignore temp13 - ignore temp14 - ignore temp15 - ignore temp16 - ignore temp17 - ignore temp18 - ignore temp19 - ignore temp20 - ignore temp21 - ignore temp22 - ignore temp23 - ignore temp24 - ignore temp25 - ignore temp26 - ignore temp27 - ignore temp28 - ignore temp29 - ignore temp30 - ignore temp31 - ignore temp32 - ignore temp33 - ignore temp34 - ignore temp35 - ignore temp36 - ignore temp37 - ignore temp38 - ignore temp39 - ignore temp40 - ignore temp41 - ignore temp42 - ignore temp43 - ignore temp44 - ignore temp45 - ignore temp46 - ignore temp47 - ignore temp48 - ignore temp49 - ignore temp50 - ignore temp51 - ignore temp52 - ignore temp53 - ignore temp54 - ignore temp55 - ignore temp56 - ignore temp57 - ignore temp58 - ignore temp59 - ignore temp60 - ignore temp61 - ignore temp62 - ignore temp63 - ignore temp64 +chip "acpitz-virtual-0" + label temp1 "ACPI CPU Temp" + label temp2 "ACPI Board Temp" -chip "*-virtual-*" - ignore temp1 - ignore temp2 +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 5)" + chip "pmbus-i2c-5-41" + label in1 "PMB-1 PSU 12V Rail (in)" + label in2 "PMB-1 0.9V VCORE Rail (out)" + label temp1 "PMB-1 Temp 1" + label temp2 "PMB-1 Temp 2" + ignore power1 + label power2 "PMB-1 0.9V VCORE Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-1 0.9V VCORE Rail Curr (out)" + chip "pmbus-i2c-5-27" + label in1 "PMB-2 PSU 12V Rail (in)" + label in2 "PMB-2 3.3V Rail (out)" + label in3 "PMB-2 1.2V Rail (out)" + label temp1 "PMB-2 Temp 1" + label temp2 "PMB-2 Temp 2" + ignore power1 + label power2 "PMB-2 3.3V Rail Pwr (out)" + label power3 "PMB-2 1.2V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-2 3.3V Rail Curr (out)" + label curr3 "PMB-2 1.2V Rail Curr (out)" -chip "dps460-*" - ignore fan2 - ignore fan3 +# Power supplies +bus "i2c-10" "i2c-1-mux (chan_id 10)" + chip "dps460-i2c-*-58" + label in1 "PSU-2(R) 220V Rail (in)" + label in2 "PSU-2(R) 12V Rail (out)" + label fan1 "PSU-2(R) Fan 1" + label temp1 "PSU-2(R) Temp 1" + label temp2 "PSU-2(R) Temp 2" + label power1 "PSU-2(R) 220V Rail Pwr (in)" + label power2 "PSU-2(R) 12V Rail Pwr (out)" + label curr1 "PSU-2(R) 220V Rail Curr (in)" + label curr2 "PSU-2(R) 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-1(L) 220V Rail (in)" + label in2 "PSU-1(L) 12V Rail (out)" + label fan1 "PSU-1(L) Fan 1" + label temp1 "PSU-1(L) Temp 1" + label temp2 "PSU-1(L) Temp 2" + label power1 "PSU-1(L) 220V Rail Pwr (in)" + label power2 "PSU-1(L) 12V Rail Pwr (out)" + label curr1 "PSU-1(L) 220V Rail Curr (in)" + label curr2 "PSU-1(L) 12V Rail Curr (out)" +# Chassis fans +bus "i2c-2" "i2c-1-mux (chan_id 2)" + chip "mlxsw-i2c-*-48" + label fan1 "Chassis Drawer-1 Fan-1" + label fan2 "Chassis Drawer-1 Fan-2" + label fan3 "Chassis Drawer-2 Fan-1" + label fan4 "Chassis Drawer-2 Fan-2" + label fan5 "Chassis Drawer-3 Fan-1" + label fan6 "Chassis Drawer-3 Fan-2" + label fan7 "Chassis Drawer-4 Fan-1" + label fan8 "Chassis Drawer-4 Fan-2" From 7ecc15e26dbe0bf53766cc7f6877a4002c93aba8 Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Tue, 20 Oct 2020 02:03:04 +0300 Subject: [PATCH 1259/1427] [Mellanox] Add sensors labels for human readable output for MSN2740 (#5662) Add sensors labels for human readable output for MSN2740 --- .../x86_64-mlnx_msn2740-r0/sensors.conf | 77 ++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf deleted file mode 120000 index ea04d66d008c..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf +++ /dev/null @@ -1 +0,0 @@ -../x86_64-mlnx_msn2700-r0/sensors.conf \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf new file mode 100644 index 000000000000..ffc36fe2168c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf @@ -0,0 +1,76 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN2740 +################################################################################ + +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" + +bus "i2c-7" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-*-48" + label temp1 "Ambient Port Temp" + +bus "i2c-6" "i2c-1-mux (chan_id 5)" + chip "tmp102-i2c-*-49" + label temp1 "Ambient Fan Temp" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 4)" + chip "pmbus-i2c-*-41" + label in1 "PMB-1 PSU 12V Rail (in)" + label in2 "PMB-1 0.9V VCORE Rail (out)" + label in3 "PMB-1 1.8V VCORE Rail (out)" + label temp1 "PMB-1 Temp 1" + label temp2 "PMB-1 Temp 2" + ignore power1 + label power2 "PMB-1 0.9V VCORE Rail Pwr (out)" + label power3 "PMB-1 1.8V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-1 0.9V VCORE Rail Curr (out)" + label curr3 "PMB-1 1.8V Rail Curr (out)" + chip "pmbus-i2c-*-27" + label in1 "PMB-2 PSU 12V Rail (in)" + label in2 "PMB-2 3.3V Rail (out)" + label in3 "PMB-2 1.2V Rail (out)" + label temp1 "PMB-2 Temp 1" + label temp2 "PMB-2 Temp 2" + ignore power1 + label power2 "PMB-2 3.3V Rail Pwr (out)" + label power3 "PMB-2 1.2V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-2 3.3V Rail Curr (out)" + label curr3 "PMB-2 1.2V Rail Curr (out)" + +# Power supplies +bus "i2c-4" "i2c-1-mux (chan_id 3)" + chip "dps460-i2c-*-58" + label in1 "PSU-2(R) 220V Rail (in)" + label in2 "PSU-2(R) 12V Rail (out)" + label fan1 "PSU-2(R) Fan 1" + label temp1 "PSU-2(R) Temp 1" + label temp2 "PSU-2(R) Temp 2" + label power1 "PSU-2(R) 220V Rail Pwr (in)" + label power2 "PSU-2(R) 12V Rail Pwr (out)" + label curr1 "PSU-2(R) 220V Rail Curr (in)" + label curr2 "PSU-2(R) 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-1(L) 220V Rail (in)" + label in2 "PSU-1(L) 12V Rail (out)" + label fan1 "PSU-1(L) Fan 1" + label temp1 "PSU-1(L) Temp 1" + label temp2 "PSU-1(L) Temp 2" + label power1 "PSU-1(L) 220V Rail Pwr (in)" + label power2 "PSU-1(L) 12V Rail Pwr (out)" + label curr1 "PSU-1(L) 220V Rail Curr (in)" + label curr2 "PSU-1(L) 12V Rail Curr (out)" + +# Chassis fans +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label fan1 "Chassis Fan Drawer-1" + label fan2 "Chassis Fan Drawer-2" + label fan3 "Chassis Fan Drawer-3" + label fan4 "Chassis Fan Drawer-4" From a5242a65dced3424b4e874c99ffca72e597d246c Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Tue, 20 Oct 2020 02:04:07 +0300 Subject: [PATCH 1260/1427] [Mellanox] Fixes sensors labels for human readable output for MSN3420 (#5664) Fixes sensors labels for human readable output for MSN3420 Signed-off-by: Shlomi Bitton --- .../x86_64-mlnx_msn3420-r0/sensors.conf | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf index 4519b4841700..f31cbe7adbc7 100644 --- a/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf @@ -21,28 +21,36 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" - chip "tps53679-i2c-*-70" + chip "xdpe12284-i2c-*-62" label in1 "PMIC-1 PSU 12V Rail (in1)" label in2 "PMIC-1 PSU 12V Rail (in2)" - label in3 "PMIC-1 COMEX 1.8V Rail (out)" - label in4 "PMIC-1 COMEX 1.05V Rail (out)" + label in3 "PMIC-1 VCORE 0.8V Rail (out)" + label in4 "PMIC-1 COMEX 1.2V Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" - label power1 "PMIC-1 COMEX 1.8V Rail Pwr (out)" - label power2 "PMIC-1 COMEX 1.05V Rail Pwr (out)" - label curr1 "PMIC-1 COMEX 1.8V Rail Curr (out)" - label curr2 "PMIC-1 COMEX 1.05V Rail Curr (out)" - chip "tps53679-i2c-*-71" + label power1 "PMIC-1 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-1 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-1 VCORE 0.8V Rail Pwr (out)" + label power4 "PMIC-1 COMEX 1.2V Rail Pwr (out)" + label curr1 "PMIC-1 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-1 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-1 VCORE 0.8V Rail Curr (out)" + label curr4 "PMIC-1 COMEX 1.2V Rail Curr (out)" + chip "xdpe12284-i2c-*-64" label in1 "PMIC-2 PSU 12V Rail (in1)" label in2 "PMIC-2 PSU 12V Rail (in2)" - label in3 "PMIC-2 COMEX 1.8V Rail (out)" - label in4 "PMIC-2 COMEX 1.05V Rail (out)" + label in3 "PMIC-2 1.8V Rail (out)" + ignore in4 label temp1 "PMIC-2 Temp 1" - label temp2 "PMIC-2 Temp 2" - label power1 "PMIC-2 COMEX 1.8V Rail Pwr (out)" - label power2 "PMIC-2 COMEX 1.05V Rail Pwr (out)" - label curr1 "PMIC-2 COMEX 1.8V Rail Curr (out)" - label curr2 "PMIC-2 COMEX 1.05V Rail Curr (out)" + ignore temp2 + label power1 "PMIC-2 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-2 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-2 1.8V Rail Pwr (out)" + ignore power4 + label curr1 "PMIC-2 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-2 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-2 1.8V Rail Curr (out)" + ignore curr4 bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" @@ -59,14 +67,14 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-61" label in1 "PMIC-4 PSU 12V Rail (in1)" label in2 "PMIC-4 PSU 12V Rail (in2)" - label in3 "PMIC-4 COMEX 1.8V Rail (out)" - label in4 "PMIC-4 COMEX 1.05V Rail (out)" + label in3 "PMIC-4 COMEX 1.2V Rail (out)" + ignore in4 label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" - label power1 "PMIC-4 COMEX 1.8V Rail Pwr (out)" - label power2 "PMIC-4 COMEX 1.05V Rail Pwr (out)" - label curr1 "PMIC-4 COMEX 1.8V Rail Curr (out)" - label curr2 "PMIC-4 COMEX 1.05V Rail Curr (out)" + label power1 "PMIC-4 COMEX 1.2V Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-4 COMEX 1.2V Rail Curr (out)" + ignore curr2 # Power supplies bus "i2c-4" "i2c-1-mux (chan_id 3)" From 5c5e42454d68e53bdc9a6f5d0c128891a0349ce1 Mon Sep 17 00:00:00 2001 From: Kalimuthu-Velappan <53821802+Kalimuthu-Velappan@users.noreply.github.com> Date: Tue, 20 Oct 2020 10:23:39 +0530 Subject: [PATCH 1261/1427] [build]: Fixes the missing dependency in the debian package is not triggering the docker rebuild (#5650) - Fixes the dependency issue in the DPKG dependent SHA calculation. - The dependent SHA value of package is derived from the content of all its dependent packages. SHA_HASH => is an SHA value derived from a module/package dedpendent files ( .flags, .sha and .smsha files) . SHA_VALUE = > is an SHA value derived from a module/package dependent packages(.deb, .whl, etc) Eg, For SNMP docker, SNMP and SNMPD packages are the dependency $(DOCKER_SNMP)_DEPENDS += $(SNMP) $(SNMPD) So, the SHA value calculation of SNMP would include the SHA value of SNMP and SNMPD packages as well. so that any change in the package should trigger the docker rebuild. --- Makefile.cache | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Makefile.cache b/Makefile.cache index 3c45cec3a97f..7693e6791b58 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -171,18 +171,22 @@ endef define GET_MOD_DEP_SHA $(eval $(1)_MOD_DEP_PKGS := $(foreach dfile,$($(1)_DEPENDS) $($(1)_RDEPENDS) $($(1)_WHEEL_DEPENDS) \ $($(1)_PYTHON_DEBS) $($(1)_PYTHON_WHEELS) \ - $($(1)_DBG_DEPENDS) $($(1)_DBG_IMAGE_PACKAGES) $($(1)_LOAD_DOCKERS),\ + $($(1)_DBG_DEPENDS) $($(1)_LOAD_DOCKERS),\ $(if $($(dfile)_MAIN_DEB),$($(dfile)_MAIN_DEB),$(dfile))) ) $(if $(MDEBUG), $(info $(1)_MOD_DEP_PKGS: $($(1)_MOD_DEP_PKGS))) # Warn if there is any missing dependency files $(eval $(1)_DEP_MOD_SHA_FILES := $(foreach dfile,$($(1)_MOD_DEP_PKGS), \ - $($(dfile)_DEP_FLAGS_FILE) $($(dfile)_MOD_HASH_FILE) $($(dfile)_SMOD_HASH_FILE)) ) + $($(dfile)_DEP_FLAGS_FILE) $($(dfile)_MOD_HASH_FILE) $($(dfile)_SMOD_HASH_FILE) \ + $($(dfile)_DST_PATH)/$(dfile) )) + echo "DEP_MOD_SHA_FILES : $($(1)_DEP_MOD_SHA_FILES)" >> $($(1)_DST_PATH)/$(1).log $(eval $(1)_DEP_FILES_MISSING := $(filter-out $(wildcard $($(1)_DEP_MOD_SHA_FILES)),$($(1)_DEP_MOD_SHA_FILES)) ) - $(if $($(1)_DEP_FILES_MISSING), $(warning "[ DPKG ] Dependecy file(s) are not found for $(1) : $($(1)_DEP_FILES_MISSING))) + $(if $($(1)_DEP_FILES_MISSING), $(warning "[ DPKG ] Dependency file(s) are not found for $(1) : $($(1)_DEP_FILES_MISSING))) - $(eval $(1)_DEP_MOD_SHA := $(shell git hash-object $($(1)_DEP_MOD_SHA_FILES) \ + $(eval $(1)_DEP_MOD_SHA_HASH := $(shell git hash-object $($(1)_DEP_MOD_SHA_FILES))) + $(eval $(1)_DEP_MOD_SHA_VALUE:= $(foreach dfile,$($(1)_MOD_DEP_PKGS), $($(dfile)_DEP_MOD_SHA))) + $(eval $(1)_DEP_MOD_SHA := $(shell echo $($(1)_DEP_MOD_SHA_HASH) $($(1)_DEP_MOD_SHA_VALUE) \ | sha1sum | awk '{print substr($$1,0,23);}')) endef From d19d1dd5698db518faf2e0b2c040156e5a1f9417 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 20 Oct 2020 00:38:09 -0700 Subject: [PATCH 1262/1427] [bgpcfgd]: Change prefix-list generation for "Allow prefix" feature (#5639) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **- Why I did it** I was asked to change "Allow list" prefix-list generation rule. Previously we generated the rules using following method: ``` For each {prefix}/{masklen} we would generate the prefix-rule permit {prefix}/{masklen} ge {masklen}+1 Example: Prefix 1.2.3.4/24 would have following prefix-list entry generated permit 1.2.3.4/24 ge 23 ``` But we discovered the old rule doesn't work for all cases we have. So we introduced the new rule: ``` For ipv4 entry, For mask < 32 , we will add ‘le 32’ to cover all prefix masks to be sent by T0 For mask =32 , we will not add any ‘le mask’ For ipv6 entry, we will add le 128 to cover all the prefix mask to be sent by T0 For mask < 128 , we will add ‘le 128’ to cover all prefix masks to be sent by T0 For mask = 128 , we will not add any ‘le mask’ ``` **- How I did it** I change prefix-list entry generation function. Also I introduced a test for the changed function. **- How to verify it** 1. Build an image and put it on your dut. 2. Create a file test_schema.conf with the test configuration ``` { "BGP_ALLOWED_PREFIXES": { "DEPLOYMENT_ID|0|1010:1010": { "prefixes_v4": [ "10.20.0.0/16", "10.50.1.0/29" ], "prefixes_v6": [ "fc01:10::/64", "fc02:20::/64" ] }, "DEPLOYMENT_ID|0": { "prefixes_v4": [ "10.20.0.0/16", "10.50.1.0/29" ], "prefixes_v6": [ "fc01:10::/64", "fc02:20::/64" ] } } } ``` 3. Apply the configuration by command ``` sonic-cfggen -j test_schema.conf --write-to-db ``` 4. Check that your bgp configuration has following prefix-list entries: ``` admin@str-s6100-acs-1:~$ show runningconfiguration bgp | grep PL_ALLOW ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4 seq 10 deny 0.0.0.0/0 le 17 ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4 seq 20 permit 127.0.0.1/32 ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4 seq 30 permit 10.20.0.0/16 le 32 ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4 seq 40 permit 10.50.1.0/29 le 32 ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17 ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4 seq 20 permit 127.0.0.1/32 ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4 seq 30 permit 10.20.0.0/16 le 32 ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4 seq 40 permit 10.50.1.0/29 le 32 ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6 seq 10 deny ::/0 le 59 ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6 seq 20 deny ::/0 ge 65 ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6 seq 30 permit fc01:10::/64 le 128 ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6 seq 40 permit fc02:20::/64 le 128 ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6 seq 10 deny ::/0 le 59 ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6 seq 20 deny ::/0 ge 65 ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6 seq 30 permit fc01:10::/64 le 128 ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6 seq 40 permit fc02:20::/64 le 128 ``` Co-authored-by: Pavel Shirshov --- files/image_config/constants/constants.yml | 1 - .../bgpcfgd/managers_allow_list.py | 16 +++- src/sonic-bgpcfgd/tests/test_allow_list.py | 89 +++++++++++-------- 3 files changed, 65 insertions(+), 41 deletions(-) diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 074956ff8396..a142bb653df7 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -29,7 +29,6 @@ constants: v6: - "deny 0::/0 le 59" - "deny 0::/0 ge 65" - - "permit fe80::/64" peers: general: # peer_type db_table: "BGP_NEIGHBOR" diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py b/src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py index b8a784a2de5d..4d0df8a7622e 100644 --- a/src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py @@ -216,7 +216,7 @@ def __update_prefix_list(self, af, pl_name, allow_list): """ assert af == self.V4 or af == self.V6 constant_list = self.__get_constant_list(af) - allow_list = self.__to_prefix_list(allow_list) + allow_list = self.__to_prefix_list(af, allow_list) log_debug("BGPAllowListMgr::__update_prefix_list. af='%s' prefix-list name=%s" % (af, pl_name)) exist, correct = self.__is_prefix_list_valid(af, pl_name, allow_list, constant_list) if correct: @@ -614,14 +614,22 @@ def __get_constant_list(self, af): else: return self.constants_v6 - @staticmethod - def __to_prefix_list(allow_list): + def __to_prefix_list(self, af, allow_list): """ Convert "allow list" prefix list, to a prefix-list rules + :param af: address-family :param allow_list: "allow list" prefix list :return: prefix-list rules """ - return ["permit %s ge %d" % (prefix, int(prefix.split("/")[1])+1) for prefix in allow_list] + res = [] + prefix_mask_default = 32 if af == self.V4 else 128 + for prefix in allow_list: + prefix_mask = int(prefix.split("/")[1]) + if prefix_mask == prefix_mask_default: + res.append("permit %s" % prefix) + else: + res.append("permit %s le %d" % (prefix, prefix_mask_default)) + return res def __af_to_family(self, af): """ diff --git a/src/sonic-bgpcfgd/tests/test_allow_list.py b/src/sonic-bgpcfgd/tests/test_allow_list.py index c906894eef47..3288702b5814 100644 --- a/src/sonic-bgpcfgd/tests/test_allow_list.py +++ b/src/sonic-bgpcfgd/tests/test_allow_list.py @@ -65,12 +65,12 @@ def test_set_handler_with_community(): [], [ 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 le 32', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 le 128', 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', @@ -91,12 +91,12 @@ def test_set_handler_no_community(): [], [ 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 le 32', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 le 128', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', @@ -169,12 +169,12 @@ def test_set_handler_with_community_data_is_already_presented(): }), [ 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 le 32', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 le 128', 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', @@ -194,12 +194,12 @@ def test_set_handler_no_community_data_is_already_presented(): cfg_mgr.update.return_value = None cfg_mgr.get_text.return_value = [ 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 le 32', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 le 128', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', @@ -244,12 +244,12 @@ def test_set_handler_with_community_update_prefixes_add(): }), [ 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 le 32', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 le 128', 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', @@ -262,15 +262,15 @@ def test_set_handler_with_community_update_prefixes_add(): [ 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 40 permit 80.90.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 40 permit 80.90.0.0/16 le 32', 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 50 permit fc02::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 50 permit fc02::/64 le 128', ] ) @@ -283,12 +283,12 @@ def test_set_handler_no_community_update_prefixes_add(): }), [ 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 le 32', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 le 128', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', @@ -298,15 +298,15 @@ def test_set_handler_no_community_update_prefixes_add(): [ 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 40 permit 80.90.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 40 permit 80.90.0.0/16 le 32', 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 50 permit fc02::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 50 permit fc02::/64 le 128', ] ) @@ -480,4 +480,21 @@ def run_command(cmd): rc = mgr._BGPAllowListMgr__restart_peers(5) assert rc +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___to_prefix_list(): + from bgpcfgd.managers_allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + + res_v4 = mgr._BGPAllowListMgr__to_prefix_list(mgr.V4, ["1.2.3.4/32", "10.20.20.10/24"]) + assert res_v4 == ["permit 1.2.3.4/32", "permit 10.20.20.10/24 le 32"] + res_v6 = mgr._BGPAllowListMgr__to_prefix_list(mgr.V6, ["fc00::1/128", "fc00::/64"]) + assert res_v6 == ["permit fc00::1/128", "permit fc00::/64 le 128"] + # FIXME: more testcases for coverage From 38bd6be609333250b5a2dfe0dde06a2a11b6b66b Mon Sep 17 00:00:00 2001 From: CynthiaINV <51065488+CynthiaINV@users.noreply.github.com> Date: Wed, 21 Oct 2020 02:37:16 +0800 Subject: [PATCH 1263/1427] [Inventec] Add support for D6332 platform (#5304) Add support for D6332 platform Signed-off-by: cynthia --- .../INVENTEC-D6332/buffers.json.j2 | 2 + .../INVENTEC-D6332/buffers_defaults_t1.j2 | 46 + .../INVENTEC-D6332/pg_profile_lookup.ini | 17 + .../INVENTEC-D6332/port_config.ini | 33 + .../INVENTEC-D6332/qos.json.j2 | 161 + .../INVENTEC-D6332/sai.profile | 2 + .../td3-d6332-32x100G-SR4.config.bcm | 668 ++ .../custom_init.soc.j2 | 3 + .../x86_64-inventec_d6332-r0/custom_led.bin | Bin 0 -> 832 bytes .../x86_64-inventec_d6332-r0/default_sku | 1 + .../x86_64-inventec_d6332-r0/installer.conf | 4 + .../led_proc_init.soc | 5 + .../plugins/eeprom.py | 22 + .../plugins/psuutil.py | 89 + .../plugins/sfputil.py | 348 + .../pmon_daemon_control.json | 3 + .../x86_64-inventec_d6332-r0/sensors.conf | 69 + platform/broadcom/one-image.mk | 1 + .../broadcom/platform-modules-inventec.mk | 6 + .../d6332/modules/Makefile | 8 + .../d6332/modules/gpio-ich.c | 513 + .../d6332/modules/i2c-gpio.c | 290 + .../d6332/modules/i2c-mux-pca9541.c | 355 + .../d6332/modules/inv_cpld.c | 1571 +++ .../d6332/modules/inv_eeprom.c | 180 + .../d6332/modules/inv_mux.c | 545 ++ .../d6332/modules/inv_mux.h | 50 + .../d6332/modules/inv_platform.c | 228 + .../d6332/modules/inv_swps.c | 3288 +++++++ .../d6332/modules/inv_swps.h | 1791 ++++ .../d6332/modules/io_expander.c | 2579 +++++ .../d6332/modules/io_expander.h | 189 + .../d6332/modules/lpc_ich.c | 1149 +++ .../d6332/modules/transceiver.c | 8409 +++++++++++++++++ .../d6332/modules/transceiver.h | 804 ++ .../d6332/setup.py | 14 + .../d6332/sonic_platform/__init__.py | 3 + .../d6332/sonic_platform/chassis.py | 242 + .../d6332/sonic_platform/component.py | 196 + .../d6332/sonic_platform/eeprom.py | 78 + .../d6332/sonic_platform/event_monitor.py | 94 + .../d6332/sonic_platform/fan.py | 330 + .../d6332/sonic_platform/inv_const.py | 22 + .../d6332/sonic_platform/platform.py | 20 + .../d6332/sonic_platform/psu.py | 254 + .../d6332/sonic_platform/qsfp.py | 1023 ++ .../d6332/sonic_platform/thermal.py | 253 + .../d6332/sonic_platform/watchdog.py | 51 + .../d6332/utils/inventec_d6332_util.py | 325 + .../debian/control | 7 +- .../debian/platform-modules-d6332.init | 74 + .../debian/platform-modules-d6332.install | 4 + .../debian/platform-modules-d6332.postinst | 25 + .../debian/rules | 17 +- .../systemd/platform-modules-d6332.service | 13 + 55 files changed, 26470 insertions(+), 4 deletions(-) create mode 100644 device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers.json.j2 create mode 100644 device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers_defaults_t1.j2 create mode 100644 device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/pg_profile_lookup.ini create mode 100755 device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/port_config.ini create mode 100644 device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/qos.json.j2 create mode 100755 device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/sai.profile create mode 100644 device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/td3-d6332-32x100G-SR4.config.bcm create mode 100644 device/inventec/x86_64-inventec_d6332-r0/custom_init.soc.j2 create mode 100644 device/inventec/x86_64-inventec_d6332-r0/custom_led.bin create mode 100644 device/inventec/x86_64-inventec_d6332-r0/default_sku create mode 100644 device/inventec/x86_64-inventec_d6332-r0/installer.conf create mode 100644 device/inventec/x86_64-inventec_d6332-r0/led_proc_init.soc create mode 100644 device/inventec/x86_64-inventec_d6332-r0/plugins/eeprom.py create mode 100755 device/inventec/x86_64-inventec_d6332-r0/plugins/psuutil.py create mode 100755 device/inventec/x86_64-inventec_d6332-r0/plugins/sfputil.py create mode 100644 device/inventec/x86_64-inventec_d6332-r0/pmon_daemon_control.json create mode 100644 device/inventec/x86_64-inventec_d6332-r0/sensors.conf create mode 100755 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/gpio-ich.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-gpio.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-mux-pca9541.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_eeprom.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.h create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_platform.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_swps.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_swps.h create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.h create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/lpc_ich.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.c create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.h create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/event_monitor.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/inv_const.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/platform.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/qsfp.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/thermal.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/watchdog.py create mode 100755 platform/broadcom/sonic-platform-modules-inventec/d6332/utils/inventec_d6332_util.py create mode 100644 platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.init create mode 100644 platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.install create mode 100644 platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.postinst create mode 100644 platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6332.service diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers.json.j2 b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers_defaults_t1.j2 b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..f77839cddf87 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- set PORT_ALL = [] %} + +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} +{%- endfor %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "27678784", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "26045524", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "32786432", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} \ No newline at end of file diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/pg_profile_lookup.ini b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/pg_profile_lookup.ini new file mode 100644 index 000000000000..7222f8014925 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -4 2288 + 25000 5m 1248 2288 53248 -4 2288 + 40000 5m 1248 2288 66560 -4 2288 + 50000 5m 1248 2288 79872 -4 2288 + 100000 5m 1248 2288 165568 -4 2288 + 10000 40m 1248 2288 37024 -4 2288 + 25000 40m 1248 2288 56160 -4 2288 + 40000 40m 1248 2288 71552 -4 2288 + 50000 40m 1248 2288 85696 -4 2288 + 100000 40m 1248 2288 177632 -4 2288 + 10000 300m 1248 2288 46176 -4 2288 + 25000 300m 1248 2288 79040 -4 2288 + 40000 300m 1248 2288 108160 -4 2288 + 50000 300m 1248 2288 131456 -4 2288 + 100000 300m 1248 2288 268736 -4 2288 diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/port_config.ini b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/port_config.ini new file mode 100755 index 000000000000..d0ce46c7a8fe --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/port_config.ini @@ -0,0 +1,33 @@ +# name lanes index speed autoneg +Ethernet0 21,22,23,24 0 100000 0 +Ethernet4 17,18,19,20 1 100000 0 +Ethernet8 25,26,27,28 2 100000 0 +Ethernet12 29,30,31,32 3 100000 0 +Ethernet16 37,38,39,40 4 100000 0 +Ethernet20 33,34,35,36 5 100000 0 +Ethernet24 41,42,43,44 6 100000 0 +Ethernet28 45,46,47,48 7 100000 0 +Ethernet32 5,6,7,8 8 100000 0 +Ethernet36 1,2,3,4 9 100000 0 +Ethernet40 9,10,11,12 10 100000 0 +Ethernet44 13,14,15,16 11 100000 0 +Ethernet48 53,54,55,56 12 100000 0 +Ethernet52 49,50,51,52 13 100000 0 +Ethernet56 57,58,59,60 14 100000 0 +Ethernet60 61,62,63,64 15 100000 0 +Ethernet64 69,70,71,72 16 100000 0 +Ethernet68 65,66,67,68 17 100000 0 +Ethernet72 73,74,75,76 18 100000 0 +Ethernet76 77,78,79,80 19 100000 0 +Ethernet80 117,118,119,120 20 100000 0 +Ethernet84 113,114,115,116 21 100000 0 +Ethernet88 121,122,123,124 22 100000 0 +Ethernet92 125,126,127,128 23 100000 0 +Ethernet96 85,86,87,88 24 100000 0 +Ethernet100 81,82,83,84 25 100000 0 +Ethernet104 89,90,91,92 26 100000 0 +Ethernet108 93,94,95,96 27 100000 0 +Ethernet112 101,102,103,104 28 100000 0 +Ethernet116 97,98,99,100 29 100000 0 +Ethernet120 105,106,107,108 30 100000 0 +Ethernet124 109,110,111,112 31 100000 0 diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/qos.json.j2 b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/qos.json.j2 new file mode 100644 index 000000000000..3b909e0adbbc --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/qos.json.j2 @@ -0,0 +1,161 @@ +{%- set PORT_ALL = [] %} + +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} +{%- endfor %} + +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "{{ PORT_ALL|join(',') }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"312000", + "red_min_threshold":"104000", + "yellow_max_threshold":"312000", + "yellow_min_threshold":"104000", + "green_max_threshold": "312000", + "green_min_threshold": "104000" + } + }, + "QUEUE": { + "{{ PORT_ALL|join(',') }}|3-4" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "{{ PORT_ALL|join(',') }}|0" : { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "{{ PORT_ALL|join(',') }}|1" : { + "scheduler" : "[SCHEDULER|scheduler.2]" + } + } +} diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/sai.profile b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/sai.profile new file mode 100755 index 000000000000..51c00abc35f7 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-d6332-32x100G-SR4.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/td3-d6332-32x100G-SR4.config.bcm b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/td3-d6332-32x100G-SR4.config.bcm new file mode 100644 index 000000000000..27670075cf99 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/td3-d6332-32x100G-SR4.config.bcm @@ -0,0 +1,668 @@ +### fix for sonic +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 +ifp_inports_support_enable=1 +### end fix + +core_clock_frequency=1525 +dpp_clock_ratio=2:3 + +oversubscribe_mode=1 +pbmp_xport_xe=0xc888888888888888e2222222222222222 + +l2_mem_entries=32768 +l3_mem_entries=16384 +fpem_mem_entries=16384 +l2xmsg_mode=1 + +pdma_descriptor_prefetch_enable=1 + +port_flex_enable=1 +stable_size=0x5500000 + + +### Loopback port +#portmap_65=130:10 +#portmap_131=131:10 + +portmap_1=1:100 +portmap_5=5:100 +portmap_9=9:100 +portmap_13=13:100 +portmap_17=17:100 +portmap_21=21:100 +portmap_25=25:100 +portmap_29=29:100 + +### Pipeline0, halfpipe 1 (8x100G) +portmap_33=33:100 +portmap_37=37:100 +portmap_41=41:100 +portmap_45=45:100 +portmap_49=49:100 +portmap_53=53:100 +portmap_57=57:100 +portmap_61=61:100 + +### Pipeline 1 +### First management port +#portmap_66=129:10:m +### Second management port +#portmap_130=128:10:m + +### Pipeline 1, halfpipe 0 (8x100G) +portmap_67=65:100 +portmap_71=69:100 +portmap_75=73:100 +portmap_79=77:100 +portmap_83=81:100 +portmap_87=85:100 +portmap_91=89:100 +portmap_95=93:100 + +### Pipeline 1, halfpipe 1 (8x100G) +portmap_99=97:100 +portmap_103=101:100 +portmap_107=105:100 +portmap_111=109:100 +portmap_115=113:100 +portmap_119=117:100 +portmap_123=121:100 +portmap_127=125:100 + + +#dport part +dport_map_port_21=1 +dport_map_port_17=2 +dport_map_port_25=3 +dport_map_port_29=4 +dport_map_port_37=5 +dport_map_port_33=6 +dport_map_port_41=7 +dport_map_port_45=8 +dport_map_port_5=9 +dport_map_port_1=10 +dport_map_port_9=11 +dport_map_port_13=12 +dport_map_port_53=13 +dport_map_port_49=14 +dport_map_port_57=15 +dport_map_port_61=16 +dport_map_port_71=17 +dport_map_port_67=18 +dport_map_port_75=19 +dport_map_port_79=20 +dport_map_port_119=21 +dport_map_port_115=22 +dport_map_port_123=23 +dport_map_port_127=24 +dport_map_port_87=25 +dport_map_port_83=26 +dport_map_port_91=27 +dport_map_port_95=28 +dport_map_port_103=29 +dport_map_port_99=30 +dport_map_port_107=31 +dport_map_port_111=32 + + + + +#Polarity flips +#FC0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 + +#FC1 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 + +#FC2 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x1 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 + +#FC3 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 + +#FC4 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 + +#FC5 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x0 +phy_chain_tx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 + +#FC6 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 + +#FC7 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x1 +phy_chain_rx_polarity_flip_physical{32.0}=0x1 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 + +#FC8 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 + +#FC9 +phy_chain_rx_polarity_flip_physical{37.0}=0x0 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_rx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x0 +phy_chain_tx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 + +#FC10 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 + +#FC11 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 + +#FC12 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 + +#FC13 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{54.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x1 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x0 +phy_chain_tx_polarity_flip_physical{56.0}=0x0 + +#FC14 +phy_chain_rx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 + +#FC15 +phy_chain_rx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 + +#FC16 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 + +#FC17 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 + +#FC18 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 + +#FC19 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 + +#FC20 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{83.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x0 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 + +#FC21 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 + +#FC22 +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x1 + +#FC23 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 + +#FC24 +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 + +#FC25 +phy_chain_rx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_tx_polarity_flip_physical{104.0}=0x1 + +#FC26 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_tx_polarity_flip_physical{108.0}=0x1 + +#FC27 +phy_chain_rx_polarity_flip_physical{109.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_tx_polarity_flip_physical{109.0}=0x0 +phy_chain_tx_polarity_flip_physical{110.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x1 + +#FC28 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_tx_polarity_flip_physical{116.0}=0x1 + +#FC29 +phy_chain_rx_polarity_flip_physical{117.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x1 +phy_chain_tx_polarity_flip_physical{117.0}=0x0 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x1 + +#FC30 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x1 + +#FC31 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_tx_polarity_flip_physical{125.0}=0x0 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 + +#lanes swap +#FC0~FC7 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_tx_lane_map_physical{1.0}=0x2031 +phy_chain_rx_lane_map_physical{5.0}=0x3120 +phy_chain_tx_lane_map_physical{5.0}=0x2031 +phy_chain_rx_lane_map_physical{9.0}=0x1302 +phy_chain_tx_lane_map_physical{9.0}=0x2031 +phy_chain_rx_lane_map_physical{13.0}=0x3120 +phy_chain_tx_lane_map_physical{13.0}=0x0213 +phy_chain_rx_lane_map_physical{17.0}=0x1302 +phy_chain_tx_lane_map_physical{17.0}=0x2031 +phy_chain_rx_lane_map_physical{21.0}=0x3120 +phy_chain_tx_lane_map_physical{21.0}=0x0213 +phy_chain_rx_lane_map_physical{25.0}=0x1302 +phy_chain_tx_lane_map_physical{25.0}=0x2031 +phy_chain_rx_lane_map_physical{29.0}=0x3120 +phy_chain_tx_lane_map_physical{29.0}=0x0213 + +#FC8~FC15 +phy_chain_rx_lane_map_physical{33.0}=0x1302 +phy_chain_tx_lane_map_physical{33.0}=0x2031 +phy_chain_rx_lane_map_physical{37.0}=0x3120 +phy_chain_tx_lane_map_physical{37.0}=0x0213 +phy_chain_rx_lane_map_physical{41.0}=0x1302 +phy_chain_tx_lane_map_physical{41.0}=0x2031 +phy_chain_rx_lane_map_physical{45.0}=0x3120 +phy_chain_tx_lane_map_physical{45.0}=0x0213 +phy_chain_rx_lane_map_physical{49.0}=0x2301 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_rx_lane_map_physical{53.0}=0x3120 +phy_chain_tx_lane_map_physical{53.0}=0x2031 +phy_chain_rx_lane_map_physical{57.0}=0x1302 +phy_chain_tx_lane_map_physical{57.0}=0x2031 +phy_chain_rx_lane_map_physical{61.0}=0x3120 +phy_chain_tx_lane_map_physical{61.0}=0x0213 + +#FC16~FC23 +phy_chain_rx_lane_map_physical{65.0}=0x2031 +phy_chain_tx_lane_map_physical{65.0}=0x1302 +phy_chain_rx_lane_map_physical{69.0}=0x0213 +phy_chain_tx_lane_map_physical{69.0}=0x3201 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_tx_lane_map_physical{73.0}=0x1302 +phy_chain_rx_lane_map_physical{77.0}=0x0123 +phy_chain_tx_lane_map_physical{77.0}=0x3120 +phy_chain_rx_lane_map_physical{81.0}=0x2031 +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_rx_lane_map_physical{85.0}=0x0213 +phy_chain_tx_lane_map_physical{85.0}=0x1302 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_tx_lane_map_physical{89.0}=0x1302 +phy_chain_rx_lane_map_physical{93.0}=0x0213 +phy_chain_tx_lane_map_physical{93.0}=0x3120 + +#FC24~FC31 +phy_chain_rx_lane_map_physical{97.0}=0x2031 +phy_chain_tx_lane_map_physical{97.0}=0x1302 +phy_chain_rx_lane_map_physical{101.0}=0x2031 +phy_chain_tx_lane_map_physical{101.0}=0x1302 +phy_chain_rx_lane_map_physical{105.0}=0x2031 +phy_chain_tx_lane_map_physical{105.0}=0x1302 +phy_chain_rx_lane_map_physical{109.0}=0x0213 +phy_chain_tx_lane_map_physical{109.0}=0x3120 +phy_chain_rx_lane_map_physical{113.0}=0x2031 +phy_chain_tx_lane_map_physical{113.0}=0x1302 +phy_chain_rx_lane_map_physical{117.0}=0x0213 +phy_chain_tx_lane_map_physical{117.0}=0x1302 +phy_chain_rx_lane_map_physical{121.0}=0x2031 +phy_chain_tx_lane_map_physical{121.0}=0x1302 +phy_chain_rx_lane_map_physical{125.0}=0x0213 +phy_chain_tx_lane_map_physical{125.0}=0x3120 + + +serdes_preemphasis_lane0_21=0x11490A +serdes_preemphasis_lane1_21=0x11490A +serdes_preemphasis_lane2_21=0x11490A +serdes_preemphasis_lane3_21=0x11490A +serdes_preemphasis_lane0_17=0x12480A +serdes_preemphasis_lane1_17=0x12480A +serdes_preemphasis_lane2_17=0x12480A +serdes_preemphasis_lane3_17=0x12480A +serdes_preemphasis_lane0_25=0x104A0A +serdes_preemphasis_lane1_25=0x104A0A +serdes_preemphasis_lane2_25=0x104A0A +serdes_preemphasis_lane3_25=0x104A0A +serdes_preemphasis_lane0_29=0x104A0A +serdes_preemphasis_lane1_29=0x104A0A +serdes_preemphasis_lane2_29=0x104A0A +serdes_preemphasis_lane3_29=0x104A0A +serdes_preemphasis_lane0_37=0x0F4B0A +serdes_preemphasis_lane1_37=0x0F4B0A +serdes_preemphasis_lane2_37=0x0F4B0A +serdes_preemphasis_lane3_37=0x0F4B0A +serdes_preemphasis_lane0_33=0x0F4B0A +serdes_preemphasis_lane1_33=0x104A0A +serdes_preemphasis_lane2_33=0x0F4B0A +serdes_preemphasis_lane3_33=0x104A0A +serdes_preemphasis_lane0_41=0x0E4C0A +serdes_preemphasis_lane1_41=0x0F4B0A +serdes_preemphasis_lane2_41=0x0E4C0A +serdes_preemphasis_lane3_41=0x0F4B0A +serdes_preemphasis_lane0_45=0x0E4C0A +serdes_preemphasis_lane1_45=0x0E4C0A +serdes_preemphasis_lane2_45=0x0E4C0A +serdes_preemphasis_lane3_45=0x0E4C0A +serdes_preemphasis_lane0_5=0x0F4B0A +serdes_preemphasis_lane1_5=0x0F4B0A +serdes_preemphasis_lane2_5=0x0F4B0A +serdes_preemphasis_lane3_5=0x0F4B0A +serdes_preemphasis_lane0_1=0x0F4B0A +serdes_preemphasis_lane1_1=0x0F4B0A +serdes_preemphasis_lane2_1=0x0F4B0A +serdes_preemphasis_lane3_1=0x0F4B0A +serdes_preemphasis_lane0_9=0x0E4C0A +serdes_preemphasis_lane1_9=0x0F4B0A +serdes_preemphasis_lane2_9=0x0E4C0A +serdes_preemphasis_lane3_9=0x0F4B0A +serdes_preemphasis_lane0_13=0x0E4C0A +serdes_preemphasis_lane1_13=0x0F4B0A +serdes_preemphasis_lane2_13=0x0E4C0A +serdes_preemphasis_lane3_13=0x0F4B0A +serdes_preemphasis_lane0_53=0x05550A +serdes_preemphasis_lane1_53=0x07530A +serdes_preemphasis_lane2_53=0x05550A +serdes_preemphasis_lane3_53=0x07530A +serdes_preemphasis_lane0_49=0x07530A +serdes_preemphasis_lane1_49=0x0A500A +serdes_preemphasis_lane2_49=0x07530A +serdes_preemphasis_lane3_49=0x0A500A +serdes_preemphasis_lane0_57=0x05550A +serdes_preemphasis_lane1_57=0x05550A +serdes_preemphasis_lane2_57=0x05550A +serdes_preemphasis_lane3_57=0x07530A +serdes_preemphasis_lane0_61=0x07530A +serdes_preemphasis_lane1_61=0x07530A +serdes_preemphasis_lane2_61=0x07530A +serdes_preemphasis_lane3_61=0x0A500A +serdes_preemphasis_lane0_71=0x05550A +serdes_preemphasis_lane1_71=0x05550A +serdes_preemphasis_lane2_71=0x05550A +serdes_preemphasis_lane3_71=0x05550A +serdes_preemphasis_lane0_67=0x07530A +serdes_preemphasis_lane1_67=0x07530A +serdes_preemphasis_lane2_67=0x05550A +serdes_preemphasis_lane3_67=0x07530A +serdes_preemphasis_lane0_75=0x05550A +serdes_preemphasis_lane1_75=0x07530A +serdes_preemphasis_lane2_75=0x05550A +serdes_preemphasis_lane3_75=0x05550A +serdes_preemphasis_lane0_79=0x07530A +serdes_preemphasis_lane1_79=0x0A500A +serdes_preemphasis_lane2_79=0x07530A +serdes_preemphasis_lane3_79=0x0A500A +serdes_preemphasis_lane0_119=0x0E4C0A +serdes_preemphasis_lane1_119=0x0F4B0A +serdes_preemphasis_lane2_119=0x0E4C0A +serdes_preemphasis_lane3_119=0x0F4B0A +serdes_preemphasis_lane0_115=0x0E4C0A +serdes_preemphasis_lane1_115=0x0E4C0A +serdes_preemphasis_lane2_115=0x0F4B0A +serdes_preemphasis_lane3_115=0x0E4C0A +serdes_preemphasis_lane0_123=0x0F4B0A +serdes_preemphasis_lane1_123=0x0F4B0A +serdes_preemphasis_lane2_123=0x0F4B0A +serdes_preemphasis_lane3_123=0x0F4B0A +serdes_preemphasis_lane0_127=0x0F4B0A +serdes_preemphasis_lane1_127=0x0F4B0A +serdes_preemphasis_lane2_127=0x0F4B0A +serdes_preemphasis_lane3_127=0x0F4B0A +serdes_preemphasis_lane0_87=0x0E4C0A +serdes_preemphasis_lane1_87=0x0E4C0A +serdes_preemphasis_lane2_87=0x0E4C0A +serdes_preemphasis_lane3_87=0x0E4C0A +serdes_preemphasis_lane0_83=0x0F4B0A +serdes_preemphasis_lane1_83=0x0F4B0A +serdes_preemphasis_lane2_83=0x0F4B0A +serdes_preemphasis_lane3_83=0x0F4B0A +serdes_preemphasis_lane0_91=0x0F4B0A +serdes_preemphasis_lane1_91=0x0F4B0A +serdes_preemphasis_lane2_91=0x0F4B0A +serdes_preemphasis_lane3_91=0x0F4B0A +serdes_preemphasis_lane0_95=0x0F4B0A +serdes_preemphasis_lane1_95=0x104A0A +serdes_preemphasis_lane2_95=0x0F4B0A +serdes_preemphasis_lane3_95=0x104A0A +serdes_preemphasis_lane0_103=0x104A0A +serdes_preemphasis_lane1_103=0x104A0A +serdes_preemphasis_lane2_103=0x104A0A +serdes_preemphasis_lane3_103=0x104A0A +serdes_preemphasis_lane0_99=0x104A0A +serdes_preemphasis_lane1_99=0x104A0A +serdes_preemphasis_lane2_99=0x104A0A +serdes_preemphasis_lane3_99=0x104A0A +serdes_preemphasis_lane0_107=0x104A0A +serdes_preemphasis_lane1_107=0x11490A +serdes_preemphasis_lane2_107=0x104A0A +serdes_preemphasis_lane3_107=0x11490A +serdes_preemphasis_lane0_111=0x11490A +serdes_preemphasis_lane1_111=0x12480A +serdes_preemphasis_lane2_111=0x11490A +serdes_preemphasis_lane3_111=0x12480A + + +serdes_if_type_21=28 +serdes_if_type_17=28 +serdes_if_type_25=28 +serdes_if_type_29=28 +serdes_if_type_37=28 +serdes_if_type_33=28 +serdes_if_type_41=28 +serdes_if_type_45=28 +serdes_if_type_5=28 +serdes_if_type_1=28 +serdes_if_type_9=28 +serdes_if_type_13=28 +serdes_if_type_53=28 +serdes_if_type_49=28 +serdes_if_type_57=28 +serdes_if_type_61=28 +serdes_if_type_71=28 +serdes_if_type_67=28 +serdes_if_type_75=28 +serdes_if_type_79=28 +serdes_if_type_119=28 +serdes_if_type_115=28 +serdes_if_type_123=28 +serdes_if_type_127=28 +serdes_if_type_87=28 +serdes_if_type_83=28 +serdes_if_type_91=28 +serdes_if_type_95=28 +serdes_if_type_103=28 +serdes_if_type_99=28 +serdes_if_type_107=28 +serdes_if_type_111=28 diff --git a/device/inventec/x86_64-inventec_d6332-r0/custom_init.soc.j2 b/device/inventec/x86_64-inventec_d6332-r0/custom_init.soc.j2 new file mode 100644 index 000000000000..2149cb5a596e --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/custom_init.soc.j2 @@ -0,0 +1,3 @@ +phy xe AN_X4_LD_BASE_ABIL3r BASE_25G_CR1_EN=1 +phy ce AN_X4_LD_BASE_ABIL1r 0x01ff +setreg CLMAC_TX_MAC_SA 0x{{ DEVICE_METADATA.localhost.mac|replace(":","")}} diff --git a/device/inventec/x86_64-inventec_d6332-r0/custom_led.bin b/device/inventec/x86_64-inventec_d6332-r0/custom_led.bin new file mode 100644 index 0000000000000000000000000000000000000000..adaab507cb9085012ca58c1e76a7c80f6feee102 GIT binary patch literal 832 zcmc)G%WD%+6vy#%GkMsDkJ{9xI!5Pa(wH=A+oWp8q)Be;NtN0~3W7wa8AUGs1$AZV zLZNh_Q$@s$R(GW!K{r0Yl9jq~{s5usq6;@caO29K_(yc{fwMYa&S}4%=SzH%r?~x! z5)oO^pK8Hebm)&?on1^C@;-;{ryNMVVX{_O$W{Ioi#k2}LfoUE?yncs4d3Ov`c_Pg zcPxa`;!7kQ@Go=cq}QC%-?3{sb(`L*A3n+DM4kTapO(|fh(%j{rf@u()PC)z={0-J znauC6ne&ygjizBgs?!lXSkpq`ZZqNRy@lS>NDn#+l6=c_%W~XI=A0{;PN<8*&*s9q65$mG3bH)&8E!3BwSAFhpP%2nc`yLFj-^=z?z8 p4SQfO?1M2l1*hQ*jKC=5AP+c`a3-CF0u*5aN>GNK?(g*f{{rK{d?Ek< literal 0 HcmV?d00001 diff --git a/device/inventec/x86_64-inventec_d6332-r0/default_sku b/device/inventec/x86_64-inventec_d6332-r0/default_sku new file mode 100644 index 000000000000..e07c80931dde --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/default_sku @@ -0,0 +1 @@ +INVENTEC-D6332 t1 diff --git a/device/inventec/x86_64-inventec_d6332-r0/installer.conf b/device/inventec/x86_64-inventec_d6332-r0/installer.conf new file mode 100644 index 000000000000..1db64ba02c38 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +VAR_LOG_SIZE=1024 diff --git a/device/inventec/x86_64-inventec_d6332-r0/led_proc_init.soc b/device/inventec/x86_64-inventec_d6332-r0/led_proc_init.soc new file mode 100644 index 000000000000..5dcf85ea7956 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/led_proc_init.soc @@ -0,0 +1,5 @@ +led auto off +led stop +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on +led start diff --git a/device/inventec/x86_64-inventec_d6332-r0/plugins/eeprom.py b/device/inventec/x86_64-inventec_d6332-r0/plugins/eeprom.py new file mode 100644 index 000000000000..b58e704a5566 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/plugins/eeprom.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# Inventec d6356j +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/0-0055/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/inventec/x86_64-inventec_d6332-r0/plugins/psuutil.py b/device/inventec/x86_64-inventec_d6332-r0/plugins/psuutil.py new file mode 100755 index 000000000000..b2033963872d --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/plugins/psuutil.py @@ -0,0 +1,89 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + """CPLD address""" + PSU_DIR = "/sys/bus/i2c/devices/i2c-inv_cpld/" + + def __init__(self): + PsuBase.__init__(self) + + # Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + attr_file ='psu'+ str(index) + attr_path = self.PSU_DIR +'/' + attr_file + normal_attr_value = '1:normal' + unpower_attr_value = '0:unpowered' + attr_value = self.get_attr_value(attr_path) + if (attr_value != 'ERR'): + # Check for PSU presence + if (attr_value == normal_attr_value): + status = 1 + elif (attr_value == unpower_attr_value): + status = 0 + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + attr_file ='psu'+ str(index) + attr_path = self.PSU_DIR +'/' + attr_file + normal_attr_value = '1:normal' + unpower_attr_value = '0:unpowered' + attr_value = self.get_attr_value(attr_path) + if (attr_value != 'ERR'): + # Check for PSU presence + if (attr_value == normal_attr_value): + status = 1 + if (attr_value == unpower_attr_value): + status = 1 + return status diff --git a/device/inventec/x86_64-inventec_d6332-r0/plugins/sfputil.py b/device/inventec/x86_64-inventec_d6332-r0/plugins/sfputil.py new file mode 100755 index 000000000000..0f2d3aad1720 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/plugins/sfputil.py @@ -0,0 +1,348 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import os, re, socket + from sonic_sfp.sfputilbase import SfpUtilBase + from collections import OrderedDict + from sonic_sfp.sff8472 import sff8472Dom +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VLOT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 + +NETLINK_KOBJECT_UEVENT = 15 +monitor = None + +class SWPSEventMonitor(object): + + def __init__(self): + self.recieved_events = OrderedDict() + self.socket = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT) + + def start(self): + self.socket.bind((os.getpid(), -1)) + + def stop(self): + self.socket.close() + + def __enter__(self): + self.start() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.stop() + + def __iter__(self): + global monitor + while True: + for item in monitor.next_events(): + yield item + + def next_events(self): + data = self.socket.recv(16384) + event = {} + for item in data.split(b'\x00'): + if not item: + # check if we have an event and if we already received it + if event and event['SEQNUM'] not in self.recieved_events: + self.recieved_events[event['SEQNUM']] = None + if (len(self.recieved_events) > 100): + self.recieved_events.popitem(last=False) + yield event + event = {} + else: + try: + k, v = item.split(b'=', 1) + event[k.decode('ascii')] = v.decode('ascii') + except ValueError: + pass + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 31 + PORTS_IN_BLOCK = 32 + + _port_to_eeprom_mapping = {} + port_to_i2cbus_mapping = { + 0:12, + 1:13, + 2:14, + 3:15, + 4:16, + 5:17, + 6:18, + 7:19, + 8:20, + 9:21, + 10:22, + 11:23, + 12:24, + 13:25, + 14:26, + 15:27, + 16:28, + 17:29, + 18:30, + 19:31, + 20:32, + 21:33, + 22:34, + 23:35, + 24:36, + 25:37, + 26:38, + 27:39, + 28:40, + 29:41, + 30:42, + 31:43 + } + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(0, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for x in range(0, self.port_end + 1): + port_eeprom_path = eeprom_path.format(self.port_to_i2cbus_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path + self.phy_port_dict = {} + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/class/swps/port"+str(port_num)+"/present") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = int(reg_file.readline().rstrip()) + + if reg_value == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + reg_value = int(reg_file.readline().rstrip()) + + if reg_value == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + lpmode = int(reg_file.readline().rstrip()) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = 1 + else: + reg_value = 0 + + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def reset(self, port_num): + QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/class/swps/port"+str(port_num)+"/reset" + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 0 + reg_file.write(hex(reg_value)) + reg_file.close() + + # Sleep 2 second to allow it to settle + time.sleep(2) + + # Flip the value back write back to the register to take port out of reset + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 1 + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def _get_port_eeprom_path(self, port_num, devid): + sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" + if devid == self.IDENTITY_EEPROM_ADDR : + return SfpUtilBase._get_port_eeprom_path(self, port_num, devid) + else: + i2c_adapter_id = self._get_port_i2c_adapter_id(port_num) + if i2c_adapter_id is None: + print("Error getting i2c bus num") + return None + + # Get i2c virtual bus path for the sfp + sysfs_sfp_i2c_adapter_path = "%s/i2c-%s" % (sysfs_i2c_adapter_base_path, + str(i2c_adapter_id)) + + # If i2c bus for port does not exist + if not os.path.exists(sysfs_sfp_i2c_adapter_path): + print("Could not find i2c bus %s. Driver not loaded?" % sysfs_sfp_i2c_adapter_path) + return None + + sysfs_sfp_i2c_client_path = "%s/%s-00%s" % (sysfs_sfp_i2c_adapter_path, + str(i2c_adapter_id), + hex(devid)[-2:]) + + # If sfp device is not present on bus, Add it + if not os.path.exists(sysfs_sfp_i2c_client_path): + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid) + if ret != 0: + print("Error adding sfp device") + return None + + sysfs_sfp_i2c_client_eeprom_path = "%s/eeprom" % sysfs_sfp_i2c_client_path + + return sysfs_sfp_i2c_client_eeprom_path + + def get_transceiver_dom_info_dict(self, port_num): + if port_num in self.qsfp_ports: + return SfpUtilBase.get_transceiver_dom_info_dict(self, port_num) + else: + transceiver_dom_info_dict = {} + + offset = 0 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = open(file_path, "rb") + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None, 1) + if sfpd_obj is None: + return None + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + print(dom_temperature_raw) + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + print(dom_temperature_data) + else: + return None + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + print(dom_voltage_raw) + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + + def get_transceiver_change_event(self, timeout=0): + global monitor + port_dict = {} + with SWPSEventMonitor() as monitor: + for event in monitor: + if event['SUBSYSTEM'] == 'swps': + #print('SWPS event. From %s, ACTION %s, IF_TYPE %s, IF_LANE %s' % (event['DEVPATH'], event['ACTION'], event['IF_TYPE'], event['IF_LANE'])) + portname = event['DEVPATH'].split("/")[-1] + rc = re.match(r"port(?P\d+)",portname) + if rc is not None: + if event['ACTION'] == "remove": + remove_num = int(rc.group("num")) + port_dict[remove_num] = "0" + #port_dict[rc.group("num")] = "0" + if event['ACTION'] == "add": + add_num = int(rc.group("num")) + port_dict[add_num] = "1" + #port_dict[rc.group("num")] = "1" + return True, port_dict + return False, {} diff --git a/device/inventec/x86_64-inventec_d6332-r0/pmon_daemon_control.json b/device/inventec/x86_64-inventec_d6332-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/inventec/x86_64-inventec_d6332-r0/sensors.conf b/device/inventec/x86_64-inventec_d6332-r0/sensors.conf new file mode 100644 index 000000000000..ecd518a77af9 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/sensors.conf @@ -0,0 +1,69 @@ +# libsensors configuration file +chip "ucd90160-*" + ignore temp1 + +chip "pch_haswell-*" + label temp1 "PCH Temperature" + +chip "tmp75-i2c-*-0048" + label temp1 "CPU Board Temperature" + +chip "tmp75-i2c-*-004a" + label temp1 "FrontSide Temperature" + +chip "tmp75-i2c-*-004e" + label temp1 "NearASIC Temperature" + +chip "tmp75-i2c-*-004d" + label temp1 "RearSide Temperature" + +chip "inv_cpld-i2c-*-77" + label fan1 "FanModule1 Front RPM" + label fan2 "FanModule1 Rear RPM" + label fan3 "FanModule2 Front RPM" + label fan4 "FanModule2 Rear RPM" + label fan5 "FanModule3 Front RPM" + label fan6 "FanModule3 Rear RPM" + label fan7 "FanModule4 Front RPM" + label fan8 "FanModule4 Rear RPM" + label fan9 "FanModule5 Front RPM" + label fan10 "FanModule5 Rear RPM" + label pwm1 "FanModule1 PWM (0-255)" + label pwm2 "FanModule2 PWM (0-255)" + label pwm3 "FanModule3 PWM (0-255)" + label pwm4 "FanModule4 PWM (0-255)" + label pwm5 "FanModule5 PWM (0-255)" + label temp1 "ASIC Temperature" + +chip "pmbus-i2c-*-005a" + ignore power3 + ignore curr3 + ignore fan2 + label fan1 "PSU1 Fan RPM" + label temp1 "PSU1 Temperature1" + label temp2 "PSU1 Temperature2" + label temp3 "PSU1 Temperature3" + label in1 "PSU1 Input Voltage" + label curr1 "PSU1 Input Current" + label power1 "PSU1 Input Power" + label in2 "PSU1 Output Voltage" + label curr2 "PSU1 Output Current" + label power2 "PSU1 Output Power" + label pwm1 "PSU1 PWM (0-100)" + +chip "pmbus-i2c-*-005b" + ignore power3 + ignore curr3 + ignore fan2 + label fan1 "PSU2 Fan RPM" + label temp1 "PSU2 Temperature1" + label temp2 "PSU2 Temperature2" + label temp3 "PSU2 Temperature3" + label in1 "PSU2 Input Voltage" + label curr1 "PSU2 Input Current" + label power1 "PSU2 Input Power" + label in2 "PSU2 Output Voltage" + label curr2 "PSU2 Output Current" + label power2 "PSU2 Output Power" + label pwm1 "PSU2 PWM (0-100)" + diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 86ac56b750b2..a9d97b81a056 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -39,6 +39,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(INVENTEC_D7054Q28B_PLATFORM_MODULE) \ $(INVENTEC_D7264Q28B_PLATFORM_MODULE) \ $(INVENTEC_D6356_PLATFORM_MODULE) \ + $(INVENTEC_D6332_PLATFORM_MODULE) \ $(CEL_DX010_PLATFORM_MODULE) \ $(CEL_HALIBURTON_PLATFORM_MODULE) \ $(CEL_SEASTONE2_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-inventec.mk b/platform/broadcom/platform-modules-inventec.mk index b947f8a5e7d0..4f88f5b92163 100644 --- a/platform/broadcom/platform-modules-inventec.mk +++ b/platform/broadcom/platform-modules-inventec.mk @@ -6,6 +6,7 @@ INVENTEC_D6254QS_PLATFORM_MODULE_VERSION = 1.1.0 INVENTEC_D6556_PLATFORM_MODULE_VERSION = 1.1.0 INVENTEC_D6356_PLATFORM_MODULE_VERSION = 1.1.0 INVENTEC_D7264Q28B_PLATFORM_MODULE_VERSION = 1.1.0 +INVENTEC_D6332_PLATFORM_MODULE_VERSION = 1.1.0 export INVENTEC_D7032Q28B_PLATFORM_MODULE_VERSION export INVENTEC_D7054Q28B_PLATFORM_MODULE_VERSION @@ -13,6 +14,7 @@ export INVENTEC_D6254QS_PLATFORM_MODULE_VERSION export INVENTEC_D6556_PLATFORM_MODULE_VERSION export INVENTEC_D6356_PLATFORM_MODULE_VERSION export INVENTEC_D7264Q28B_PLATFORM_MODULE_VERSION +export INVENTEC_D6332_PLATFORM_MODULE_VERSION INVENTEC_D7032Q28B_PLATFORM_MODULE = platform-modules-d7032q28b_$(INVENTEC_D7032Q28B_PLATFORM_MODULE_VERSION)_amd64.deb $(INVENTEC_D7032Q28B_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-inventec @@ -40,3 +42,7 @@ INVENTEC_D7264Q28B_PLATFORM_MODULE = platform-modules-d7264q28b_$(INVENTEC_D7264 $(INVENTEC_D7264Q28B_PLATFORM_MODULE)_PLATFORM = x86_64-inventec_d7264q28b-r0 $(eval $(call add_extra_package,$(INVENTEC_D7032Q28B_PLATFORM_MODULE),$(INVENTEC_D7264Q28B_PLATFORM_MODULE))) +INVENTEC_D6332_PLATFORM_MODULE = platform-modules-d6332_$(INVENTEC_D6332_PLATFORM_MODULE_VERSION)_amd64.deb +$(INVENTEC_D6332_PLATFORM_MODULE)_PLATFORM = x86_64-inventec_d6332-r0 +$(eval $(call add_extra_package,$(INVENTEC_D7032Q28B_PLATFORM_MODULE),$(INVENTEC_D6332_PLATFORM_MODULE))) + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/Makefile b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/Makefile new file mode 100755 index 000000000000..7cb80a281baf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/Makefile @@ -0,0 +1,8 @@ +obj-m += gpio-ich.o +obj-m += lpc_ich.o +obj-m += inv_cpld.o +obj-m += inv_platform.o +obj-m += inv_eeprom.o +obj-m += i2c-mux-pca9541.o +obj-m += swps.o +swps-objs := inv_swps.o inv_mux.o io_expander.o transceiver.o diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/gpio-ich.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/gpio-ich.c new file mode 100644 index 000000000000..687834e3c561 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/gpio-ich.c @@ -0,0 +1,513 @@ +/* + * Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver + * + * Copyright (C) 2010 Extreme Engineering Solutions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "gpio_ich" + +/* + * GPIO register offsets in GPIO I/O space. + * Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and + * LVLx registers. Logic in the read/write functions takes a register and + * an absolute bit number and determines the proper register offset and bit + * number in that register. For example, to read the value of GPIO bit 50 + * the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)], + * bit 18 (50%32). + */ +enum GPIO_REG { + GPIO_USE_SEL = 0, + GPIO_IO_SEL, + GPIO_LVL, + GPO_BLINK +}; + +static const u8 ichx_regs[4][3] = { + {0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */ + {0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */ + {0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */ + {0x18, 0x18, 0x18}, /* BLINK offset */ +}; + +static const u8 ichx_reglen[3] = { + 0x30, 0x10, 0x10, +}; + +static const u8 avoton_regs[4][3] = { + {0x00, 0x80, 0x00}, + {0x04, 0x84, 0x00}, + {0x08, 0x88, 0x00}, +}; + +static const u8 avoton_reglen[3] = { + 0x10, 0x10, 0x00, +}; + +#define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start) +#define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start) + +struct ichx_desc { + /* Max GPIO pins the chipset can have */ + uint ngpio; + + /* chipset registers */ + const u8 (*regs)[3]; + const u8 *reglen; + + /* GPO_BLINK is available on this chipset */ + bool have_blink; + + /* Whether the chipset has GPIO in GPE0_STS in the PM IO region */ + bool uses_gpe0; + + /* USE_SEL is bogus on some chipsets, eg 3100 */ + u32 use_sel_ignore[3]; + + /* Some chipsets have quirks, let these use their own request/get */ + int (*request)(struct gpio_chip *chip, unsigned offset); + int (*get)(struct gpio_chip *chip, unsigned offset); + + /* + * Some chipsets don't let reading output values on GPIO_LVL register + * this option allows driver caching written output values + */ + bool use_outlvl_cache; +}; + +static struct { + spinlock_t lock; + struct platform_device *dev; + struct gpio_chip chip; + struct resource *gpio_base; /* GPIO IO base */ + struct resource *pm_base; /* Power Mangagment IO base */ + struct ichx_desc *desc; /* Pointer to chipset-specific description */ + u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */ + u8 use_gpio; /* Which GPIO groups are usable */ + int outlvl_cache[3]; /* cached output values */ +} ichx_priv; + +static int modparam_gpiobase = 0; /* dynamic */ +module_param_named(gpiobase, modparam_gpiobase, int, 0444); +MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, " + "which is the default."); + +static int ichx_write_bit(int reg, unsigned nr, int val, int verify) +{ + unsigned long flags; + u32 data, tmp; + int reg_nr = nr / 32; + int bit = nr & 0x1f; + int ret = 0; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + data = ichx_priv.outlvl_cache[reg_nr]; + else + data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + + if (val) + data |= 1 << bit; + else + data &= ~(1 << bit); + ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + ichx_priv.outlvl_cache[reg_nr] = data; + + tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + if (verify && data != tmp) + ret = -EPERM; + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return ret; +} + +static int ichx_read_bit(int reg, unsigned nr) +{ + unsigned long flags; + u32 data; + int reg_nr = nr / 32; + int bit = nr & 0x1f; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + data = ichx_priv.outlvl_cache[reg_nr] | data; + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return data & (1 << bit) ? 1 : 0; +} + +static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr) +{ + return !!(ichx_priv.use_gpio & (1 << (nr / 32))); +} + +static int ichx_gpio_get_direction(struct gpio_chip *gpio, unsigned nr) +{ + return ichx_read_bit(GPIO_IO_SEL, nr) ? GPIOF_DIR_IN : GPIOF_DIR_OUT; +} + +static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) +{ + /* + * Try setting pin as an input and verify it worked since many pins + * are output-only. + */ + if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1)) + return -EINVAL; + + return 0; +} + +static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, + int val) +{ + /* Disable blink hardware which is available for GPIOs from 0 to 31. */ + if (nr < 32 && ichx_priv.desc->have_blink) + ichx_write_bit(GPO_BLINK, nr, 0, 0); + + /* Set GPIO output value. */ + ichx_write_bit(GPIO_LVL, nr, val, 0); + + /* + * Try setting pin as an output and verify it worked since many pins + * are input-only. + */ + if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1)) + return -EINVAL; + + return 0; +} + +static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr) +{ + return ichx_read_bit(GPIO_LVL, nr); +} + +static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr) +{ + unsigned long flags; + u32 data; + + /* + * GPI 0 - 15 need to be read from the power management registers on + * a ICH6/3100 bridge. + */ + if (nr < 16) { + if (!ichx_priv.pm_base) + return -ENXIO; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + /* GPI 0 - 15 are latched, write 1 to clear*/ + ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base); + data = ICHX_READ(0, ichx_priv.pm_base); + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return (data >> 16) & (1 << nr) ? 1 : 0; + } else { + return ichx_gpio_get(chip, nr); + } +} + +static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr) +{ + if (!ichx_gpio_check_available(chip, nr)) + return -ENXIO; + + /* + * Note we assume the BIOS properly set a bridge's USE value. Some + * chips (eg Intel 3100) have bogus USE values though, so first see if + * the chipset's USE value can be trusted for this specific bit. + * If it can't be trusted, assume that the pin can be used as a GPIO. + */ + if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f))) + return 0; + + return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; +} + +static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr) +{ + /* + * Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100 + * bridge as they are controlled by USE register bits 0 and 1. See + * "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for + * additional info. + */ + if (nr == 16 || nr == 17) + nr -= 16; + + return ichx_gpio_request(chip, nr); +} + +static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val) +{ + ichx_write_bit(GPIO_LVL, nr, val, 0); +} + +static void ichx_gpiolib_setup(struct gpio_chip *chip) +{ + chip->owner = THIS_MODULE; + chip->label = DRV_NAME; + chip->parent = &ichx_priv.dev->dev; + + /* Allow chip-specific overrides of request()/get() */ + chip->request = ichx_priv.desc->request ? + ichx_priv.desc->request : ichx_gpio_request; + chip->get = ichx_priv.desc->get ? + ichx_priv.desc->get : ichx_gpio_get; + + chip->set = ichx_gpio_set; + chip->get_direction = ichx_gpio_get_direction; + chip->direction_input = ichx_gpio_direction_input; + chip->direction_output = ichx_gpio_direction_output; + chip->base = modparam_gpiobase; + chip->ngpio = ichx_priv.desc->ngpio; + chip->can_sleep = false; + chip->dbg_show = NULL; +} + +/* ICH6-based, 631xesb-based */ +static struct ichx_desc ich6_desc = { + /* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */ + .request = ich6_gpio_request, + .get = ich6_gpio_get, + + /* GPIO 0-15 are read in the GPE0_STS PM register */ + .uses_gpe0 = true, + + .ngpio = 50, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Intel 3100 */ +static struct ichx_desc i3100_desc = { + /* + * Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on + * the Intel 3100. See "Table 712. GPIO Summary Table" of 3100 + * Datasheet for more info. + */ + .use_sel_ignore = {0x00130000, 0x00010000, 0x0}, + + /* The 3100 needs fixups for GPIO 0 - 17 */ + .request = ich6_gpio_request, + .get = ich6_gpio_get, + + /* GPIO 0-15 are read in the GPE0_STS PM register */ + .uses_gpe0 = true, + + .ngpio = 50, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH7 and ICH8-based */ +static struct ichx_desc ich7_desc = { + .ngpio = 50, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH9-based */ +static struct ichx_desc ich9_desc = { + .ngpio = 61, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH10-based - Consumer/corporate versions have different amount of GPIO */ +static struct ichx_desc ich10_cons_desc = { + .ngpio = 61, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; +static struct ichx_desc ich10_corp_desc = { + .ngpio = 72, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Intel 5 series, 6 series, 3400 series, and C200 series */ +static struct ichx_desc intel5_desc = { + .ngpio = 76, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Avoton */ +static struct ichx_desc avoton_desc = { + /* Avoton has only 59 GPIOs, but we assume the first set of register + * (Core) has 32 instead of 31 to keep gpio-ich compliance + */ + .ngpio = 60, + .regs = avoton_regs, + .reglen = avoton_reglen, + .use_outlvl_cache = true, +}; + +static int ichx_gpio_request_regions(struct device *dev, + struct resource *res_base, const char *name, u8 use_gpio) +{ + int i; + + if (!res_base || !res_base->start || !res_base->end) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) { + if (!(use_gpio & (1 << i))) + continue; + if (!devm_request_region(dev, + res_base->start + ichx_priv.desc->regs[0][i], + ichx_priv.desc->reglen[i], name)) + return -EBUSY; + } + return 0; +} + +static int ichx_gpio_probe(struct platform_device *pdev) +{ + struct resource *res_base, *res_pm; + int err; + struct lpc_ich_info *ich_info = dev_get_platdata(&pdev->dev); + + if (!ich_info) + return -ENODEV; + + ichx_priv.dev = pdev; + + switch (ich_info->gpio_version) { + case ICH_I3100_GPIO: + ichx_priv.desc = &i3100_desc; + break; + case ICH_V5_GPIO: + ichx_priv.desc = &intel5_desc; + break; + case ICH_V6_GPIO: + ichx_priv.desc = &ich6_desc; + break; + case ICH_V7_GPIO: + ichx_priv.desc = &ich7_desc; + break; + case ICH_V9_GPIO: + ichx_priv.desc = &ich9_desc; + break; + case ICH_V10CORP_GPIO: + ichx_priv.desc = &ich10_corp_desc; + break; + case ICH_V10CONS_GPIO: + ichx_priv.desc = &ich10_cons_desc; + break; + case AVOTON_GPIO: + ichx_priv.desc = &avoton_desc; + break; + default: + return -ENODEV; + } + + spin_lock_init(&ichx_priv.lock); + res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); + ichx_priv.use_gpio = ich_info->use_gpio; + err = ichx_gpio_request_regions(&pdev->dev, res_base, pdev->name, + ichx_priv.use_gpio); + if (err) + return err; + + ichx_priv.gpio_base = res_base; + + /* + * If necessary, determine the I/O address of ACPI/power management + * registers which are needed to read the the GPE0 register for GPI pins + * 0 - 15 on some chipsets. + */ + if (!ichx_priv.desc->uses_gpe0) + goto init; + + res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0); + if (!res_pm) { + pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); + goto init; + } + + if (!devm_request_region(&pdev->dev, res_pm->start, + resource_size(res_pm), pdev->name)) { + pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n"); + goto init; + } + + ichx_priv.pm_base = res_pm; + +init: + ichx_gpiolib_setup(&ichx_priv.chip); + err = gpiochip_add_data(&ichx_priv.chip, NULL); + if (err) { + pr_err("Failed to register GPIOs\n"); + return err; + } + + pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base, + ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME); + + return 0; +} + +static int ichx_gpio_remove(struct platform_device *pdev) +{ + gpiochip_remove(&ichx_priv.chip); + + return 0; +} + +static struct platform_driver ichx_gpio_driver = { + .driver = { + .name = DRV_NAME, + }, + .probe = ichx_gpio_probe, + .remove = ichx_gpio_remove, +}; + +module_platform_driver(ichx_gpio_driver); + +MODULE_AUTHOR("Peter Tyser "); +MODULE_DESCRIPTION("GPIO interface for Intel ICH series"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:"DRV_NAME); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-gpio.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-gpio.c new file mode 100644 index 000000000000..9b4aa7ec9e6c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-gpio.c @@ -0,0 +1,290 @@ +/* + * Bitbanging I2C bus driver using the GPIO API + * + * Copyright (C) 2007 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct i2c_gpio_private_data { + struct i2c_adapter adap; + struct i2c_algo_bit_data bit_data; + struct i2c_gpio_platform_data pdata; +}; + +/* Toggle SDA by changing the direction of the pin */ +static void i2c_gpio_setsda_dir(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + if (state) + gpio_direction_input(pdata->sda_pin); + else + gpio_direction_output(pdata->sda_pin, 0); +} + +/* + * Toggle SDA by changing the output value of the pin. This is only + * valid for pins configured as open drain (i.e. setting the value + * high effectively turns off the output driver.) + */ +static void i2c_gpio_setsda_val(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + gpio_set_value(pdata->sda_pin, state); +} + +/* Toggle SCL by changing the direction of the pin. */ +static void i2c_gpio_setscl_dir(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + if (state) + gpio_direction_input(pdata->scl_pin); + else + gpio_direction_output(pdata->scl_pin, 0); +} + +/* + * Toggle SCL by changing the output value of the pin. This is used + * for pins that are configured as open drain and for output-only + * pins. The latter case will break the i2c protocol, but it will + * often work in practice. + */ +static void i2c_gpio_setscl_val(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + gpio_set_value(pdata->scl_pin, state); +} + +static int i2c_gpio_getsda(void *data) +{ + struct i2c_gpio_platform_data *pdata = data; + + return gpio_get_value(pdata->sda_pin); +} + +static int i2c_gpio_getscl(void *data) +{ + struct i2c_gpio_platform_data *pdata = data; + + return gpio_get_value(pdata->scl_pin); +} + +static int of_i2c_gpio_get_pins(struct device_node *np, + unsigned int *sda_pin, unsigned int *scl_pin) +{ + if (of_gpio_count(np) < 2) + return -ENODEV; + + *sda_pin = of_get_gpio(np, 0); + *scl_pin = of_get_gpio(np, 1); + + if (*sda_pin == -EPROBE_DEFER || *scl_pin == -EPROBE_DEFER) + return -EPROBE_DEFER; + + if (!gpio_is_valid(*sda_pin) || !gpio_is_valid(*scl_pin)) { + pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n", + np->full_name, *sda_pin, *scl_pin); + return -ENODEV; + } + + return 0; +} + +static void of_i2c_gpio_get_props(struct device_node *np, + struct i2c_gpio_platform_data *pdata) +{ + u32 reg; + + of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay); + + if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", ®)) + pdata->timeout = msecs_to_jiffies(reg); + + pdata->sda_is_open_drain = + of_property_read_bool(np, "i2c-gpio,sda-open-drain"); + pdata->scl_is_open_drain = + of_property_read_bool(np, "i2c-gpio,scl-open-drain"); + pdata->scl_is_output_only = + of_property_read_bool(np, "i2c-gpio,scl-output-only"); +} + +static int i2c_gpio_probe(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv; + struct i2c_gpio_platform_data *pdata; + struct i2c_algo_bit_data *bit_data; + struct i2c_adapter *adap; + unsigned int sda_pin, scl_pin; + int ret; + + /* First get the GPIO pins; if it fails, we'll defer the probe. */ + if (pdev->dev.of_node) { + ret = of_i2c_gpio_get_pins(pdev->dev.of_node, + &sda_pin, &scl_pin); + if (ret) + return ret; + } else { + if (!dev_get_platdata(&pdev->dev)) + return -ENXIO; + pdata = dev_get_platdata(&pdev->dev); + sda_pin = pdata->sda_pin; + scl_pin = pdata->scl_pin; + } + + ret = devm_gpio_request(&pdev->dev, sda_pin, "sda"); + if (ret) { + if (ret == -EINVAL) + ret = -EPROBE_DEFER; /* Try again later */ + return ret; + } + ret = devm_gpio_request(&pdev->dev, scl_pin, "scl"); + if (ret) { + if (ret == -EINVAL) + ret = -EPROBE_DEFER; /* Try again later */ + return ret; + } + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + adap = &priv->adap; + bit_data = &priv->bit_data; + pdata = &priv->pdata; + + if (pdev->dev.of_node) { + pdata->sda_pin = sda_pin; + pdata->scl_pin = scl_pin; + of_i2c_gpio_get_props(pdev->dev.of_node, pdata); + } else { + memcpy(pdata, dev_get_platdata(&pdev->dev), sizeof(*pdata)); + } + + if (pdata->sda_is_open_drain) { + gpio_direction_output(pdata->sda_pin, 1); + bit_data->setsda = i2c_gpio_setsda_val; + } else { + gpio_direction_input(pdata->sda_pin); + bit_data->setsda = i2c_gpio_setsda_dir; + } + + if (pdata->scl_is_open_drain || pdata->scl_is_output_only) { + gpio_direction_output(pdata->scl_pin, 1); + bit_data->setscl = i2c_gpio_setscl_val; + } else { + gpio_direction_input(pdata->scl_pin); + bit_data->setscl = i2c_gpio_setscl_dir; + } + + if (!pdata->scl_is_output_only) + bit_data->getscl = i2c_gpio_getscl; + bit_data->getsda = i2c_gpio_getsda; + + if (pdata->udelay) + bit_data->udelay = pdata->udelay; + else if (pdata->scl_is_output_only) + bit_data->udelay = 50; /* 10 kHz */ + else + bit_data->udelay = 5; /* 100 kHz */ + + if (pdata->timeout) + bit_data->timeout = pdata->timeout; + else + bit_data->timeout = HZ / 10; /* 100 ms */ + + bit_data->data = pdata; + + adap->owner = THIS_MODULE; + if (pdev->dev.of_node) + strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); + else + snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id); + + adap->algo_data = bit_data; + adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + adap->dev.parent = &pdev->dev; + adap->dev.of_node = pdev->dev.of_node; + + adap->nr = pdev->id; + ret = i2c_bit_add_numbered_bus(adap); + if (ret) + return ret; + + platform_set_drvdata(pdev, priv); + + dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n", + pdata->sda_pin, pdata->scl_pin, + pdata->scl_is_output_only + ? ", no clock stretching" : ""); + + return 0; +} + +static int i2c_gpio_remove(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv; + struct i2c_adapter *adap; + + priv = platform_get_drvdata(pdev); + adap = &priv->adap; + + i2c_del_adapter(adap); + + return 0; +} + +#if defined(CONFIG_OF) +static const struct of_device_id i2c_gpio_dt_ids[] = { + { .compatible = "i2c-gpio", }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids); +#endif + +static struct platform_driver i2c_gpio_driver = { + .driver = { + .name = "i2c-gpio", + .of_match_table = of_match_ptr(i2c_gpio_dt_ids), + }, + .probe = i2c_gpio_probe, + .remove = i2c_gpio_remove, +}; + +static int __init i2c_gpio_init(void) +{ + int ret; + + ret = platform_driver_register(&i2c_gpio_driver); + if (ret) + printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret); + + return ret; +} +subsys_initcall(i2c_gpio_init); + +static void __exit i2c_gpio_exit(void) +{ + platform_driver_unregister(&i2c_gpio_driver); +} +module_exit(i2c_gpio_exit); + +MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); +MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:i2c-gpio"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-mux-pca9541.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-mux-pca9541.c new file mode 100644 index 000000000000..9e75d6b9140b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-mux-pca9541.c @@ -0,0 +1,355 @@ +/* + * I2C multiplexer driver for PCA9541 bus master selector + * + * Copyright (c) 2010 Ericsson AB. + * + * Author: Guenter Roeck + * + * Derived from: + * pca954x.c + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The PCA9541 is a bus master selector. It supports two I2C masters connected + * to a single slave bus. + * + * Before each bus transaction, a master has to acquire bus ownership. After the + * transaction is complete, bus ownership has to be released. This fits well + * into the I2C multiplexer framework, which provides select and release + * functions for this purpose. For this reason, this driver is modeled as + * single-channel I2C bus multiplexer. + * + * This driver assumes that the two bus masters are controlled by two different + * hosts. If a single host controls both masters, platform code has to ensure + * that only one of the masters is instantiated at any given time. + */ + +#define PCA9541_CONTROL 0x01 +#define PCA9541_ISTAT 0x02 + +#define PCA9541_CTL_MYBUS (1 << 0) +#define PCA9541_CTL_NMYBUS (1 << 1) +#define PCA9541_CTL_BUSON (1 << 2) +#define PCA9541_CTL_NBUSON (1 << 3) +#define PCA9541_CTL_BUSINIT (1 << 4) +#define PCA9541_CTL_TESTON (1 << 6) +#define PCA9541_CTL_NTESTON (1 << 7) + +#define PCA9541_ISTAT_INTIN (1 << 0) +#define PCA9541_ISTAT_BUSINIT (1 << 1) +#define PCA9541_ISTAT_BUSOK (1 << 2) +#define PCA9541_ISTAT_BUSLOST (1 << 3) +#define PCA9541_ISTAT_MYTEST (1 << 6) +#define PCA9541_ISTAT_NMYTEST (1 << 7) + +#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) +#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) +#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS) +#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON) + +/* arbitration timeouts, in jiffies */ +#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */ +#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */ + +/* arbitration retry delays, in us */ +#define SELECT_DELAY_SHORT 50 +#define SELECT_DELAY_LONG 1000 + +struct pca9541 { + struct i2c_client *client; + unsigned long select_timeout; + unsigned long arb_timeout; +}; + +static const struct i2c_device_id pca9541_id[] = { + {"pca9541", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, pca9541_id); + +#ifdef CONFIG_OF +static const struct of_device_id pca9541_of_match[] = { + { .compatible = "nxp,pca9541" }, + {} +}; +MODULE_DEVICE_TABLE(of, pca9541_of_match); +#endif + +/* + * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock the adapter a second time. + */ +static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val) +{ + struct i2c_adapter *adap = client->adapter; + union i2c_smbus_data data = { .byte = val }; + + return __i2c_smbus_xfer(adap, client->addr, client->flags, + I2C_SMBUS_WRITE, command, + I2C_SMBUS_BYTE_DATA, &data); +} + +/* + * Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock adapter a second time. + */ +static int pca9541_reg_read(struct i2c_client *client, u8 command) +{ + struct i2c_adapter *adap = client->adapter; + union i2c_smbus_data data; + int ret; + + ret = __i2c_smbus_xfer(adap, client->addr, client->flags, + I2C_SMBUS_READ, command, + I2C_SMBUS_BYTE_DATA, &data); + + return ret ?: data.byte; +} + +/* + * Arbitration management functions + */ + +/* Release bus. Also reset NTESTON and BUSINIT if it was set. */ +static void pca9541_release_bus(struct i2c_client *client) +{ + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg >= 0 && !busoff(reg) && mybus(reg)) + pca9541_reg_write(client, PCA9541_CONTROL, + (reg & PCA9541_CTL_NBUSON) >> 1); +} + +/* + * Arbitration is defined as a two-step process. A bus master can only activate + * the slave bus if it owns it; otherwise it has to request ownership first. + * This multi-step process ensures that access contention is resolved + * gracefully. + * + * Bus Ownership Other master Action + * state requested access + * ---------------------------------------------------- + * off - yes wait for arbitration timeout or + * for other master to drop request + * off no no take ownership + * off yes no turn on bus + * on yes - done + * on no - wait for arbitration timeout or + * for other master to release bus + * + * The main contention point occurs if the slave bus is off and both masters + * request ownership at the same time. In this case, one master will turn on + * the slave bus, believing that it owns it. The other master will request + * bus ownership. Result is that the bus is turned on, and master which did + * _not_ own the slave bus before ends up owning it. + */ + +/* Control commands per PCA9541 datasheet */ +static const u8 pca9541_control[16] = { + 4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1 +}; + +/* + * Channel arbitration + * + * Return values: + * <0: error + * 0 : bus not acquired + * 1 : bus acquired + */ +static int pca9541_arbitrate(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca9541 *data = i2c_mux_priv(muxc); + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg < 0) + return reg; + + if (busoff(reg)) { + int istat; + /* + * Bus is off. Request ownership or turn it on unless + * other master requested ownership. + */ + istat = pca9541_reg_read(client, PCA9541_ISTAT); + if (!(istat & PCA9541_ISTAT_NMYTEST) + || time_is_before_eq_jiffies(data->arb_timeout)) { + /* + * Other master did not request ownership, + * or arbitration timeout expired. Take the bus. + */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_NTESTON); + data->select_timeout = SELECT_DELAY_SHORT; + } else { + /* + * Other master requested ownership. + * Set extra long timeout to give it time to acquire it. + */ + data->select_timeout = SELECT_DELAY_LONG * 2; + } + } else if (mybus(reg)) { + /* + * Bus is on, and we own it. We are done with acquisition. + * Reset NTESTON and BUSINIT, then return success. + */ + if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg & ~(PCA9541_CTL_NTESTON + | PCA9541_CTL_BUSINIT)); + return 1; + } else { + /* + * Other master owns the bus. + * If arbitration timeout has expired, force ownership. + * Otherwise request it. + */ + data->select_timeout = SELECT_DELAY_LONG; + if (time_is_before_eq_jiffies(data->arb_timeout)) { + /* Time is up, take the bus and reset it. */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_BUSINIT + | PCA9541_CTL_NTESTON); + } else { + /* Request bus ownership if needed */ + if (!(reg & PCA9541_CTL_NTESTON)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg | PCA9541_CTL_NTESTON); + } + } + return 0; +} + +static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret; + unsigned long timeout = jiffies + ARB2_TIMEOUT; + /* give up after this time */ + + data->arb_timeout = jiffies + ARB_TIMEOUT; + /* force bus ownership after this time */ + + do { + ret = pca9541_arbitrate(client); + if (ret) + return ret < 0 ? ret : 0; + + if (data->select_timeout == SELECT_DELAY_SHORT) + udelay(data->select_timeout); + else + msleep(data->select_timeout / 1000); + } while (time_is_after_eq_jiffies(timeout)); + + return -ETIMEDOUT; +} + +static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + + pca9541_release_bus(client); + return 0; +} + +/* + * I2C init/probing/exit functions + */ +static int pca9541_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = client->adapter; + struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); + struct i2c_mux_core *muxc; + struct pca9541 *data; + int force; + int ret; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + /* + * I2C accesses are unprotected here. + * We have to lock the I2C segment before releasing the bus. + */ + i2c_lock_bus(adap, I2C_LOCK_SEGMENT); + pca9541_release_bus(client); + i2c_unlock_bus(adap, I2C_LOCK_SEGMENT); + + /* Create mux adapter */ + + force = 0; + if (pdata) + force = pdata->modes[0].adap_id; + muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), + I2C_MUX_ARBITRATOR, + pca9541_select_chan, pca9541_release_chan); + if (!muxc) + return -ENOMEM; + + data = i2c_mux_priv(muxc); + data->client = client; + + i2c_set_clientdata(client, muxc); + + ret = i2c_mux_add_adapter(muxc, force, 0, 0); + if (ret) + return ret; + + dev_info(&client->dev, "registered master selector for I2C %s\n", + client->name); + + return 0; +} + +static int pca9541_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + i2c_mux_del_adapters(muxc); + return 0; +} + +static struct i2c_driver pca9541_driver = { + .driver = { + .name = "pca9541", + .of_match_table = of_match_ptr(pca9541_of_match), + }, + .probe = pca9541_probe, + .remove = pca9541_remove, + .id_table = pca9541_id, +}; + +module_i2c_driver(pca9541_driver); + +MODULE_AUTHOR("Guenter Roeck "); +MODULE_DESCRIPTION("PCA9541 I2C master selector driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_cpld.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_cpld.c new file mode 100644 index 000000000000..883c8b7b00e9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_cpld.c @@ -0,0 +1,1571 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USE_SMBUS 1 +#define CPLD_POLLING_PERIOD 1000 +#define ENABLE_SIMULATE 0 +#define ENABLE_AUTOFAN 1 + +#define CPLD2_ADDRESS 0x33 +static struct i2c_client *client2; +static u8 hasCPLD2 = 1; + +#if ENABLE_SIMULATE + u8 sim_register[0x90]; +#endif + +/* definition */ +#define CPLD_INFO_OFFSET 0x00 +#define CPLD_BIOSCS_OFFSET 0x04 +#define CPLD_CTL_OFFSET 0x0C +#define CPLD_LED_OFFSET 0x2E +#define CPLD_INT_OFFSET 0x30 +#define CPLD_INTMASK_OFFSET 0x31 +#define CPLD_INT2_OFFSET 0x32 +#define CPLD_INTMASK2_OFFSET 0x33 +#define CPLD_PSU_OFFSET 0x40 +#define CPLD_POWERSTATUS_OFFSET 0x41 +#define CPLD_PWM_OFFSET 0x50 +#define CPLD_RPM_OFFSET 0x55 +#define CPLD_FANSTATUS_OFFSET 0x69 +#define CPLD_FANLED_OFFSET 0x6B +#define CPLD_RESETBUTTONSTATUS_OFFSET 0x75 +#define CPLD_RSTCAUSE_OFFSET 0x76 +#define CPLD_WATCHDOGCOUNTER_OFFSET 0x77 +#define CPLD_WATCHDOGCONFIG_OFFSET 0x78 +#define CPLD_WATCHDOGENABLE_OFFSET 0x79 +#define CPLD_PANICCODE_OFFSET 0x7E +#define FAN_NUM 5 +#define PWM_MIN 30 +#define PWM_DEFAULT 150 + +/* Each client has this additional data */ +struct cpld_data { + struct device *hwmon_dev; + struct mutex update_lock; + struct task_struct *cpld_thread; + u8 diag; + u8 model; + u8 fan_direction; + u8 operation_command; + u8 stack_mode; +}; + +/*-----------------------------------------------------------------------*/ +static ssize_t cpld_i2c_read(struct i2c_client *client, u8 *buf, u8 offset, size_t count) +{ +#if ENABLE_SIMULATE + memcpy(buf,&sim_register[offset],count); + return count; +#else +#if USE_SMBUS + int i; + + for(i=0; iaddr; + msg[0].buf = msgbuf; + msg[0].len = 1; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + status = i2c_transfer(client->adapter, msg, 2); + + if(status == 2) + status = count; + + return status; +#endif +#endif +} + +static ssize_t cpld_i2c_write(struct i2c_client *client, char *buf, unsigned offset, size_t count) +{ +#if ENABLE_SIMULATE + memcpy(&sim_register[offset],buf,count); + return count; +#else +#if USE_SMBUS + int i; + + for(i=0; iaddr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = writebuf; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + + return status; +#endif +#endif +} + +/*-----------------------------------------------------------------------*/ +/* sysfs attributes for hwmon */ + +static char* model_str[] = { + "10GBaseT", //0 + "SFP", //1 +}; + +static char* fandirection_str[] = { + "Rear-to-Front", //0 + "Front-to-Rear", //1 +}; + +static ssize_t show_info(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte[4] = {0,0,0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, byte, CPLD_INFO_OFFSET, 4); + mutex_unlock(&data->update_lock); + + sprintf (buf, "The CPLD release date is %02d/%02d/%d.\n", + byte[2] & 0xf, (byte[3] & 0x1f), 2014+(byte[2] >> 4)); /* mm/dd/yyyy*/ + sprintf (buf, "%sThe Model is %s %s\n", buf, model_str[(byte[0]>>5) & 0x01],fandirection_str[(byte[0]>>7) & 0x01]); + sprintf (buf, "%sThe PCB version is %X\n", buf, byte[0]&0xf); + sprintf (buf, "%sThe CPLD version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf); + + if(hasCPLD2) { + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, CPLD_INFO_OFFSET, 4); + mutex_unlock(&data->update_lock); + + sprintf (buf, "%s\nThe CPLD2 release date is %02d/%02d/%d.\n", buf, + byte[2] & 0xf, (byte[3] & 0x1f), 2014+(byte[2] >> 4)); /* mm/dd/yyyy*/ + sprintf (buf, "%sThe CPLD2 version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf); + } + + return strlen(buf); +} + +static char* powerstatus_str[] = { + "Failed", //0 + "Good", //1 +}; + +static ssize_t show_powerstatus(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, CPLD_POWERSTATUS_OFFSET, 2); + mutex_unlock(&data->update_lock); + + sprintf (buf, "PGD_P5V: %s\n", powerstatus_str[(byte[0]>>7) & 0x01]); + sprintf (buf, "%sPGD_P3V3_STBY: %s\n", buf, powerstatus_str[(byte[0]>>6) & 0x01]); + //if(data->model==0) sprintf (buf, "%sPGD_P1V88: %s\n", buf, powerstatus_str[(byte[0]>>5) & 0x01]); + sprintf (buf, "%sPGD_P1V8_A: %s\n", buf, powerstatus_str[(byte[0]>>4) & 0x01]); + sprintf (buf, "%sPGD_P3V3_SYS: %s\n", buf, powerstatus_str[(byte[0]>>3) & 0x01]); + sprintf (buf, "%sPGD_P3V3_A: %s\n", buf, powerstatus_str[(byte[0]>>2) & 0x01]); + sprintf (buf, "%sPGD_P3V3_B: %s\n", buf, powerstatus_str[(byte[0]>>1) & 0x01]); + sprintf (buf, "%sPGD_P1V2: %s\n", buf, powerstatus_str[(byte[0]>>0) & 0x01]); + sprintf (buf, "%sPGD_P0V8_A: %s\n", buf,powerstatus_str[(byte[1]>>7) & 0x01]); + sprintf (buf, "%sPGD_P0V89_ROV: %s\n", buf, powerstatus_str[(byte[1]>>6) & 0x01]); + //if(data->model==0) sprintf (buf, "%sPGD_P1V0_A: %s\n", buf, powerstatus_str[(byte[1]>>5) & 0x01]); + //if(data->model==0) sprintf (buf, "%sPGD_P1V0_B: %s\n", buf, powerstatus_str[(byte[1]>>4) & 0x01]); + sprintf (buf, "%sSW_PWR_READY: %s\n", buf, powerstatus_str[(byte[1]>>3) & 0x01]); + //sprintf (buf, "%sCORE_PWRGD_TO_CPLD: %s\n", buf, powerstatus_str[(byte[1]>>2) & 0x01]); + //sprintf (buf, "%sCPU_STBY_PWROK: %s\n", buf, powerstatus_str[(byte[1]>>1) & 0x01]); + sprintf (buf, "%sPGD_P1V8_A_STBY: %s\n", buf, powerstatus_str[(byte[1]>>0) & 0x01]); + + return strlen(buf); +} + +static ssize_t show_diag(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + return sprintf (buf, "%d\n", data->diag); +} + +static ssize_t set_diag(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 diag = simple_strtol(buf, NULL, 10); + data->diag = diag?1:0; + return count; +} + +static char* stackmode_str[] = { + "Non-Stack member", //0 + "Stack Master", //1 + "Stack Backup/Member", //2 + "Stack Error", //3 +}; + +static ssize_t show_stackmode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + return sprintf (buf, "%d: %s\n", data->stack_mode,stackmode_str[data->stack_mode]); +} + +static ssize_t set_stackmode(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 stackmode = simple_strtol(buf, NULL, 10); + + if(stackmode<4) data->stack_mode = stackmode; + + return count; +} + +static char* resetbutton_str[] = { + "No press", //0 + "Reserved", //1 + "Press and hold <5s", //2 + "Press and hold >5s", //3 +}; + +static ssize_t show_resetbuttonstatus(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_RESETBUTTONSTATUS_OFFSET, 1); + mutex_unlock(&data->update_lock); + byte &=0x03; + + return sprintf (buf, "0x%02X:%s\n", byte,resetbutton_str[byte]); +} + +static char* resetcause_str[] = { + "Power-On", //0 + "Watchdog", //1 + "SoftwareReboot", //2 + "ResetButton", //3 + "Panic", //4 + "ThermalTrip" //5 +}; + +static ssize_t show_resetcause(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_RSTCAUSE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + sprintf (buf, "0x%02X:", byte); + if(byte==0) sprintf (buf, "%sNone",buf); + if(byte&0x01) sprintf (buf, "%s%s ",buf,resetcause_str[0]); + if(byte&0x02) sprintf (buf, "%s%s ",buf,resetcause_str[1]); + if(byte&0x04) sprintf (buf, "%s%s ",buf,resetcause_str[2]); + if(byte&0x08) sprintf (buf, "%s%s ",buf,resetcause_str[3]); + if(byte&0x10) sprintf (buf, "%s%s ",buf,resetcause_str[4]); + if(byte&0x20) sprintf (buf, "%s%s ",buf,resetcause_str[5]); + return sprintf (buf, "%s\n", buf); +} + +static ssize_t set_resetcause(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + + mutex_lock(&data->update_lock); + cpld_i2c_write(client, &byte, CPLD_RSTCAUSE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static char* interrupt_str[] = { + "PCIE_INTR_L", //0 + "EXT_USB_OC_N", //1 + "PS2_ALERT_N", //2 + "PS1_ALERT_N", //3 + "PLD_SEN5_ALERT_N", //4 + "PLD_SEN4_ALERT_N", //5 + "PLD_SEN3_ALERT_N", //6 + "UCD90160_TEMP_INT_N", //7 + "RSTBTN_INT_N", //8 + "WDT_IRQ_N", //9 + "RSTBTN_5s_INT_N", //10 + "Reserved" //11 +}; + +static ssize_t show_interrupt(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte[4] = {0,0,0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, byte, CPLD_INT_OFFSET, 4); + mutex_unlock(&data->update_lock); + + sprintf (buf, "0x%02X 0x%02X:", byte[0],byte[2]); + if(byte[0]==0xff && byte[2]==0x07) sprintf (buf, "%sNone",buf); + if(!(byte[0]&0x01)) sprintf (buf, "%s%s ",buf,interrupt_str[0]); + if(!(byte[0]&0x02)) sprintf (buf, "%s%s ",buf,interrupt_str[1]); + //if(!(byte[0]&0x04)) sprintf (buf, "%s%s ",buf,interrupt_str[2]); + //if(!(byte[0]&0x08)) sprintf (buf, "%s%s ",buf,interrupt_str[3]); + if(!(byte[0]&0x10)) sprintf (buf, "%s%s ",buf,interrupt_str[4]); + if(!(byte[0]&0x20)) sprintf (buf, "%s%s ",buf,interrupt_str[5]); + if(!(byte[0]&0x40)) sprintf (buf, "%s%s ",buf,interrupt_str[6]); + if(!(byte[0]&0x80)) sprintf (buf, "%s%s ",buf,interrupt_str[7]); + if(!(byte[2]&0x01)) sprintf (buf, "%s%s%s ",buf,interrupt_str[8] ,(byte[3]&0x01)?"(Blocked)":""); + if(!(byte[2]&0x02)) sprintf (buf, "%s%s%s ",buf,interrupt_str[9] ,(byte[3]&0x02)?"(Blocked)":""); + if(!(byte[2]&0x04)) sprintf (buf, "%s%s%s ",buf,interrupt_str[10],(byte[3]&0x04)?"(Blocked)":""); + + return sprintf (buf, "%s\n", buf); +} + +static ssize_t show_operationcommand(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + return sprintf (buf, "%d\n", data->operation_command); +} + +static ssize_t set_operationcommand(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 operationcommand = simple_strtol(buf, NULL, 10); + + data->operation_command = operationcommand?1:0; + + return count; +} + +static char* bios_str[] = { + "BIOS1", //0 + "BIOS2", //1 +}; + +static ssize_t show_bios_cs(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_BIOSCS_OFFSET, 1); + mutex_unlock(&data->update_lock); + + byte &= 0x01; + + return sprintf (buf, "%d:%s\n", byte,bios_str[byte]); +} + +static ssize_t set_bios_cs(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + u8 temp = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_BIOSCS_OFFSET, 1); + if(temp) byte |= 0x01; else byte &= ~(0x01); + cpld_i2c_write(client, &byte, CPLD_BIOSCS_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static char* led_str[] = { + "OFF", //000 + "ON", //001 + "1 Hz", //010 + "2 Hz", //011 +}; + +static ssize_t show_led(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + int shift = attr->index; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_LED_OFFSET, 1); + mutex_unlock(&data->update_lock); + byte = (byte >> shift) & 0x3; + + return sprintf (buf, "%d: %s\n", byte, led_str[byte]); +} + +static ssize_t set_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + + u8 temp = simple_strtol(buf, NULL, 16); + u8 byte = 0; + int shift = attr->index; + temp &= 0x3; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_LED_OFFSET, 1); + byte &= ~(0x3<update_lock); + + return count; +} + +static char* psu_str[] = { + "unpowered", //00 + "normal", //01 + "not installed", //10 + "not installed", //11 +}; + +static ssize_t show_psu(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + int shift = (attr->index == 0)?0:4; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, &byte, CPLD_PSU_OFFSET, 1); + mutex_unlock(&data->update_lock); + byte = (byte >> shift) & 0x3; + + return sprintf (buf, "%d:%s\n", byte, psu_str[byte]); +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + u8 offset = attr->index + CPLD_PWM_OFFSET; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, &byte, offset, 1); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", byte); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 offset = attr->index + CPLD_PWM_OFFSET; + u8 byte = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->update_lock); + cpld_i2c_write(client2, &byte, offset, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_rpm(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 offset = attr->index*2 + CPLD_RPM_OFFSET; + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, offset, 2); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", (byte[0]<<8 | byte[1])); +} + +static char* fantype_str[] = { + "Normal Type", //00 + "REVERSAL Type", //01 + "UNPLUGGED", //10 + "UNPLUGGED", //11 +}; + +static ssize_t show_fantype(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 offset = CPLD_FANSTATUS_OFFSET; + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, offset, 2); + mutex_unlock(&data->update_lock); + status = (((byte[0] >> attr->index) & 0x01)) | (((byte[1] >> attr->index) & 0x01)<<1); + + return sprintf(buf, "%d:%s\n",status,fantype_str[status]); +} + +static char* fanled_str[] = { + "None", //00 + "Green", //01 + "Red", //10 + "Both", //11 +}; + +static ssize_t show_fanled(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, CPLD_FANLED_OFFSET, 2); + mutex_unlock(&data->update_lock); + status = (((byte[0] >> attr->index) & 0x01)) | (((byte[1] >> attr->index) & 0x01)<<1); + + return sprintf(buf, "%d:%s\n",status,fanled_str[status]); +} + +static ssize_t set_fanled(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte[2] = {0,0}; + u8 temp = simple_strtol(buf, NULL, 16); + int shift = attr->index; + + temp &= 0x3; + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, CPLD_FANLED_OFFSET, 2); + byte[0] &= ~(1<> 1) & 0x01)<update_lock); + + return count; +} + +static ssize_t set_watchdog_feed(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + byte |= 0x02; + cpld_i2c_write(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t set_watchdog_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0x03; + + mutex_lock(&data->update_lock); + cpld_i2c_write(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_watchdog_enable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n",(byte&0x01)); +} + +static ssize_t set_watchdog_config(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = simple_strtol(buf, NULL, 10); + + if (byte<6) byte=6; + mutex_lock(&data->update_lock); + cpld_i2c_write(client, &byte, CPLD_WATCHDOGCONFIG_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_watchdog_config(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_WATCHDOGCONFIG_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d seconds\n",byte); +} + +static ssize_t show_watchdog_counter(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_WATCHDOGCOUNTER_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d seconds\n",byte); +} + +static ssize_t show_paniccode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_PANICCODE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return sprintf (buf, "0x%02X\n", byte); +} + +#if ENABLE_SIMULATE +static ssize_t show_simdump(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 i, j; + sprintf(buf,"usage: echo 0xAABB > sim_buffer (AA is address, BB is value)\n\n"); + sprintf(buf,"%s 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n",buf); + sprintf(buf,"%s======================================================\n",buf); + sprintf(buf,"%s0000: ",buf); + for (j = 0, i = 0; j < sizeof(sim_register); j++, i++) + { + sprintf(buf,"%s%02x ", buf, (int)sim_register[i]); + if ((i & 0x0F) == 0x0F) sprintf(buf,"%s\n%04x: ", buf, (i+1)); + } + return sprintf(buf,"%s\n",buf); +} + +static ssize_t set_simbuffer(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + u16 byte = simple_strtol(buf, NULL, 16); + u8 address = (byte >> 8); + u8 value = (byte & 0xff); + + sim_register[address]=value; + + return count; +} +#endif +static SENSOR_DEVICE_ATTR(info, S_IRUGO, show_info, 0, 0); +static SENSOR_DEVICE_ATTR(diag, S_IWUSR|S_IRUGO, show_diag, set_diag, 0); +static SENSOR_DEVICE_ATTR(interrupt, S_IRUGO, show_interrupt, 0, 0); + +static SENSOR_DEVICE_ATTR(stacking_led, S_IWUSR|S_IRUGO, show_led, set_led, 0); +static SENSOR_DEVICE_ATTR(fan_led, S_IWUSR|S_IRUGO, show_led, set_led, 2); +static SENSOR_DEVICE_ATTR(power_led, S_IWUSR|S_IRUGO, show_led, set_led, 4); +static SENSOR_DEVICE_ATTR(service_led, S_IWUSR|S_IRUGO, show_led, set_led, 6); + +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 1); +static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 2); +static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 3); +static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 4); + +static SENSOR_DEVICE_ATTR(fanmodule1_type, S_IRUGO, show_fantype, 0, 0); +static SENSOR_DEVICE_ATTR(fanmodule2_type, S_IRUGO, show_fantype, 0, 1); +static SENSOR_DEVICE_ATTR(fanmodule3_type, S_IRUGO, show_fantype, 0, 2); +static SENSOR_DEVICE_ATTR(fanmodule4_type, S_IRUGO, show_fantype, 0, 3); +static SENSOR_DEVICE_ATTR(fanmodule5_type, S_IRUGO, show_fantype, 0, 4); + +static SENSOR_DEVICE_ATTR(fanmodule1_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 0); +static SENSOR_DEVICE_ATTR(fanmodule2_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 1); +static SENSOR_DEVICE_ATTR(fanmodule3_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 2); +static SENSOR_DEVICE_ATTR(fanmodule4_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 3); +static SENSOR_DEVICE_ATTR(fanmodule5_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 4); + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_rpm, 0, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_rpm, 0, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_rpm, 0, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_rpm, 0, 3); +static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_rpm, 0, 4); +static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_rpm, 0, 5); +static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_rpm, 0, 6); +static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_rpm, 0, 7); +static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, show_rpm, 0, 8); +static SENSOR_DEVICE_ATTR(fan10_input,S_IRUGO, show_rpm, 0, 9); + +static SENSOR_DEVICE_ATTR(psu1, S_IRUGO, show_psu, 0, 0); +static SENSOR_DEVICE_ATTR(psu2, S_IRUGO, show_psu, 0, 1); +static SENSOR_DEVICE_ATTR(power_status, S_IRUGO, show_powerstatus, 0, 0); +static SENSOR_DEVICE_ATTR(reset_cause, S_IWUSR|S_IRUGO, show_resetcause, set_resetcause, 0); +static SENSOR_DEVICE_ATTR(resetbutton_status, S_IRUGO, show_resetbuttonstatus, 0, 0); +static SENSOR_DEVICE_ATTR(panic_code, S_IRUGO, show_paniccode, 0, 0); + +static SENSOR_DEVICE_ATTR(watchdog_feed, S_IWUSR, 0, set_watchdog_feed, 0); +static SENSOR_DEVICE_ATTR(watchdog_enable, S_IWUSR|S_IRUGO, show_watchdog_enable, set_watchdog_enable, 0); +static SENSOR_DEVICE_ATTR(watchdog_config, S_IWUSR|S_IRUGO, show_watchdog_config, set_watchdog_config, 0); +static SENSOR_DEVICE_ATTR(watchdog_counter, S_IRUGO, show_watchdog_counter, 0, 0); + +static SENSOR_DEVICE_ATTR(stack_mode, S_IWUSR|S_IRUGO, show_stackmode, set_stackmode, 0); +static SENSOR_DEVICE_ATTR(operation_command, S_IWUSR|S_IRUGO, show_operationcommand, set_operationcommand, 0); +#if ENABLE_SIMULATE + static SENSOR_DEVICE_ATTR(sim_buffer, S_IWUSR|S_IRUGO, show_simdump, set_simbuffer, 0); +#endif +static SENSOR_DEVICE_ATTR(bios_cs, S_IWUSR|S_IRUGO, show_bios_cs, set_bios_cs, 0); + +static struct attribute *cpld_attributes[] = { + &sensor_dev_attr_info.dev_attr.attr, + &sensor_dev_attr_diag.dev_attr.attr, + + &sensor_dev_attr_stacking_led.dev_attr.attr, + &sensor_dev_attr_fan_led.dev_attr.attr, + &sensor_dev_attr_power_led.dev_attr.attr, + &sensor_dev_attr_service_led.dev_attr.attr, + + &sensor_dev_attr_interrupt.dev_attr.attr, + + &sensor_dev_attr_psu1.dev_attr.attr, + &sensor_dev_attr_psu2.dev_attr.attr, + &sensor_dev_attr_power_status.dev_attr.attr, + &sensor_dev_attr_reset_cause.dev_attr.attr, + &sensor_dev_attr_resetbutton_status.dev_attr.attr, + &sensor_dev_attr_panic_code.dev_attr.attr, + + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_pwm4.dev_attr.attr, + &sensor_dev_attr_pwm5.dev_attr.attr, + + &sensor_dev_attr_fanmodule1_type.dev_attr.attr, + &sensor_dev_attr_fanmodule2_type.dev_attr.attr, + &sensor_dev_attr_fanmodule3_type.dev_attr.attr, + &sensor_dev_attr_fanmodule4_type.dev_attr.attr, + &sensor_dev_attr_fanmodule5_type.dev_attr.attr, + + &sensor_dev_attr_fanmodule1_led.dev_attr.attr, + &sensor_dev_attr_fanmodule2_led.dev_attr.attr, + &sensor_dev_attr_fanmodule3_led.dev_attr.attr, + &sensor_dev_attr_fanmodule4_led.dev_attr.attr, + &sensor_dev_attr_fanmodule5_led.dev_attr.attr, + + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan6_input.dev_attr.attr, + &sensor_dev_attr_fan7_input.dev_attr.attr, + &sensor_dev_attr_fan8_input.dev_attr.attr, + &sensor_dev_attr_fan9_input.dev_attr.attr, + &sensor_dev_attr_fan10_input.dev_attr.attr, + + &sensor_dev_attr_watchdog_feed.dev_attr.attr, + &sensor_dev_attr_watchdog_enable.dev_attr.attr, + &sensor_dev_attr_watchdog_config.dev_attr.attr, + &sensor_dev_attr_watchdog_counter.dev_attr.attr, + + &sensor_dev_attr_stack_mode.dev_attr.attr, + &sensor_dev_attr_operation_command.dev_attr.attr, + + &sensor_dev_attr_bios_cs.dev_attr.attr, +#if ENABLE_SIMULATE + &sensor_dev_attr_sim_buffer.dev_attr.attr, +#endif + NULL +}; + +struct i2c_client *client_notifier; + +static const struct attribute_group cpld_group = { + .attrs = cpld_attributes, +}; + +static int log_reboot_to_cpld (struct notifier_block *self, unsigned long event, void *ptr) +{ + u8 byte=0; + if (event == SYS_DOWN || event == SYS_HALT) + { + cpld_i2c_read(client_notifier, &byte, CPLD_RSTCAUSE_OFFSET, 1); + byte |= 0x04; + cpld_i2c_write(client_notifier, &byte, CPLD_RSTCAUSE_OFFSET, 1); + } + return NOTIFY_DONE; +} + +static int log_panic_to_cpld(struct notifier_block *self, unsigned long event, void *ptr) +{ +#if 1 +// Can't use SMBus if smp is stopped (need patch the panic.c) + if (client_notifier != NULL) + { + u8 byte=0; + cpld_i2c_read(client_notifier, &byte, CPLD_RSTCAUSE_OFFSET, 1); + byte |= 0x10; + cpld_i2c_write(client_notifier, &byte, CPLD_RSTCAUSE_OFFSET, 1); + } +#endif + return NOTIFY_DONE; +} + +static struct notifier_block reboot_notifier = { + .notifier_call = log_reboot_to_cpld, +}; + +static struct notifier_block panic_notifier = { + .notifier_call = log_panic_to_cpld, +}; + +#if ENABLE_AUTOFAN +#define SWITCH_ADDRESS 3-004e +#define ENV_ADDRESS 3-004a +#define CPU_ADDRESS 3-0048 +#define PSU1_ADDRESS 2-0058 +#define PSU2_ADDRESS 2-0059 +#define PSU1_ADDRESS_DVT 2-005a +#define PSU2_ADDRESS_DVT 2-005b + +#define _STR(s) #s +#define __STR(s) _STR(s) +#define __File_input(__file) __STR(/sys/bus/i2c/devices/__file/hwmon/hwmon%d/temp1_input) +#define __File_max(__file) __STR(/sys/bus/i2c/devices/__file/hwmon/hwmon%d/temp1_max) +#define __File_max_hyst(__file) __STR(/sys/bus/i2c/devices/__file/hwmon/hwmon%d/temp1_max_hyst) +#define __File_pwm(__file) __STR(/sys/bus/i2c/devices/__file/hwmon/hwmon%d/pwm1) + +#define SWITCH_TEMPERATURE __File_input(SWITCH_ADDRESS) +#define ENV_TEMPERATURE __File_input(ENV_ADDRESS) +#define CPU_TEMPERATURE __File_input(CPU_ADDRESS) +#define SWITCH_MAX __File_max(SWITCH_ADDRESS) +#define ENV_MAX __File_max(ENV_ADDRESS) +#define CPU_MAX __File_max(CPU_ADDRESS) +#define SWITCH_MAX_HYST __File_max_hyst(SWITCH_ADDRESS) +#define ENV_MAX_HYST __File_max_hyst(ENV_ADDRESS) +#define CPU_MAX_HYST __File_max_hyst(CPU_ADDRESS) +#define PSU1_PWM __File_pwm(PSU1_ADDRESS) +#define PSU2_PWM __File_pwm(PSU2_ADDRESS) +#define PSU1_PWM_DVT __File_pwm(PSU1_ADDRESS_DVT) +#define PSU2_PWM_DVT __File_pwm(PSU2_ADDRESS_DVT) + +#define n_entries 9 +#define temp_hysteresis 2 +#define MAX_HWMON 9 + +//[Model:10G/SFP][FanDirection:R2F/F2R][Type:CPU/ASIC/ENV] +u8 Thermaltrip[2][2][3] ={{{64,68,64},{64,68,64}},{{64,68,64},{64,68,64}}}; +u8 FanTable[2][2][3][n_entries][2]={ +{//10GBastT + {//Rear-to-Front + {//CPU + { 45, 255 }, \ + { 40, 201 }, \ + { 38, 170 }, \ + { 35, 130 }, \ + { 31, 105 }, \ + { 27, 85 }, \ + { 24, 80 }, \ + { 20, 70 }, \ + { 18, 65 } + } + ,{//ASIC + { 52, 255 }, \ + { 47, 201 }, \ + { 44, 170 }, \ + { 42, 130 }, \ + { 39, 105 }, \ + { 36, 85 }, \ + { 33, 80 }, \ + { 30, 70 }, \ + { 28, 65 } + } + ,{//ENV + { 47, 255 }, \ + { 43, 201 }, \ + { 41, 170 }, \ + { 39, 130 }, \ + { 36, 105 }, \ + { 32, 85 }, \ + { 30, 80 }, \ + { 28, 70 }, \ + { 19, 65 } + } + }, + {//Front-to-Rear + {//CPU + { 45, 255 }, \ + { 40, 201 }, \ + { 38, 170 }, \ + { 35, 130 }, \ + { 31, 105 }, \ + { 27, 85 }, \ + { 24, 80 }, \ + { 20, 70 }, \ + { 18, 65 } + } + ,{//ASIC + { 52, 255 }, \ + { 47, 201 }, \ + { 44, 170 }, \ + { 42, 130 }, \ + { 39, 105 }, \ + { 36, 85 }, \ + { 33, 80 }, \ + { 30, 70 }, \ + { 28, 65 } + } + ,{//ENV + { 47, 255 }, \ + { 43, 201 }, \ + { 41, 170 }, \ + { 39, 130 }, \ + { 36, 105 }, \ + { 32, 85 }, \ + { 30, 80 }, \ + { 28, 70 }, \ + { 19, 65 } + } + }, +}, +{//SFP28 + {//Rear-to-Front + {//CPU + { 45, 255 }, \ + { 40, 201 }, \ + { 38, 170 }, \ + { 35, 130 }, \ + { 31, 105 }, \ + { 27, 85 }, \ + { 24, 80 }, \ + { 20, 70 }, \ + { 18, 65 } + } + ,{//ASIC + { 52, 255 }, \ + { 47, 201 }, \ + { 44, 170 }, \ + { 42, 130 }, \ + { 39, 105 }, \ + { 36, 85 }, \ + { 33, 80 }, \ + { 30, 70 }, \ + { 28, 65 } + } + ,{//ENV + { 47, 255 }, \ + { 43, 201 }, \ + { 41, 170 }, \ + { 39, 130 }, \ + { 36, 105 }, \ + { 32, 85 }, \ + { 30, 80 }, \ + { 28, 70 }, \ + { 19, 65 } + } + }, + {//Front-to-Rear + {//CPU + { 45, 255 }, \ + { 40, 201 }, \ + { 38, 170 }, \ + { 35, 130 }, \ + { 31, 105 }, \ + { 27, 85 }, \ + { 24, 80 }, \ + { 20, 70 }, \ + { 18, 65 } + } + ,{//ASIC + { 52, 255 }, \ + { 47, 201 }, \ + { 44, 170 }, \ + { 42, 130 }, \ + { 39, 105 }, \ + { 36, 85 }, \ + { 33, 80 }, \ + { 30, 70 }, \ + { 28, 65 } + } + ,{//ENV + { 47, 255 }, \ + { 43, 201 }, \ + { 41, 170 }, \ + { 39, 130 }, \ + { 36, 105 }, \ + { 32, 85 }, \ + { 30, 80 }, \ + { 28, 70 }, \ + { 19, 65 } + } + } +} +}; + +//type 0:CPU,1:ASIC,2:ENV +static u8 find_duty(u8 model, u8 fan_direction, u8 type, u8 temp) +{ + static u8 fantable_index[3]={n_entries-1, n_entries-1, n_entries-1}; + while(1) + { + if(fantable_index[type] >= 1 && temp > FanTable[model][fan_direction][type][fantable_index[type]-1][0]) + fantable_index[type]--; + else if(fantable_index[type] < (n_entries-1) && temp < (FanTable[model][fan_direction][type][fantable_index[type]][0]-temp_hysteresis)) + fantable_index[type]++; + else + break; + } + return FanTable[model][fan_direction][type][fantable_index[type]][1]; +} + +static u32 getvalue(char *path) +{ + static struct file *f; + mm_segment_t old_fs; + u16 temp = 0; + char temp_str[]={0,0,0,0,0,0,0,0,0}; + loff_t pos = 0; + + f = filp_open(path,O_RDONLY,0644); + if(IS_ERR(f)) return -1; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + vfs_read(f, temp_str,8,&pos); + temp = simple_strtoul(temp_str,NULL,10); + filp_close(f,NULL); + set_fs(old_fs); + + if(temp<0) temp=0; + return temp; +} + +static u8 setvalue(char *path, u32 value) +{ + static struct file *f; + mm_segment_t old_fs; + char temp_str[]={0,0,0,0,0,0,0,0,0}; + u8 len=0; + loff_t pos = 0; + + f = filp_open(path,O_WRONLY,0644); + if(IS_ERR(f)) return -1; + + len = sprintf(temp_str,"%d",value); + + old_fs = get_fs(); + set_fs(KERNEL_DS); + vfs_write(f, temp_str, len, &pos); + filp_close(f,NULL); + set_fs(old_fs); + + return 0; +} + +static u8 probe_gettemp(char *path) +{ + u8 temp_path[64],i; + u32 value; + + for(i=0;imodel,data->fan_direction,0,temp_cpu); + if(temp_switch!=0xff) duty_switch=find_duty(data->model,data->fan_direction,1,temp_switch); + if(temp_env!=0xff) duty_env=find_duty(data->model,data->fan_direction,2,temp_env); + + if(temp_cpu==0xff && temp_switch==0xff && temp_env==0xff) + { + duty=PWM_DEFAULT; + } + else + { + duty=(duty>duty_cpu)?duty:duty_cpu; + duty=(duty>duty_switch)?duty:duty_switch; + duty=(duty>duty_env)?duty:duty_env; + } + + memset(fanpwm,duty,FAN_NUM); + for(i=0;i 200) + psu_duty = 80; + else if (duty <= 200 && duty > 150) + if(data->fan_direction==0) psu_duty = 70; else psu_duty = 65; + else if (duty <= 150 && duty > 100) + if(data->fan_direction==0) psu_duty = 60; else psu_duty = 55; + else + if(data->fan_direction==0) psu_duty = 50; else psu_duty = 35; + probe_setvalue(PSU1_PWM, psu_duty); + probe_setvalue(PSU2_PWM, psu_duty); + probe_setvalue(PSU1_PWM_DVT, psu_duty); + probe_setvalue(PSU2_PWM_DVT, psu_duty); + + mutex_lock(&data->update_lock); + cpld_i2c_write(client2,fanpwm,CPLD_PWM_OFFSET,FAN_NUM); + mutex_unlock(&data->update_lock); +} +#endif + +/*-----------------------------------------------------------------------*/ +static int cpld_polling(void *p) +{ + struct i2c_client *client = p; + struct cpld_data *data = i2c_get_clientdata(client); + u8 fanrpm[22],fanled[2],frontled,i; + u8 fandir=0,fanpresent=0,fanfront,fanrear,fanerror; + u8 fanfail,fanturnoff,psufail,lastStack,retry; + u8 psustatus=0; + u8 initial_thermaltrip[3] = {0,0,0}; + + while (!kthread_should_stop()) + { + //initial tmp75's thermaltrip value + if(initial_thermaltrip[0]==0) + { + if((probe_setvalue(CPU_MAX, Thermaltrip[data->model][data->fan_direction][0]*1000)!=0xff) + && (probe_setvalue(CPU_MAX_HYST, (Thermaltrip[data->model][data->fan_direction][0]-temp_hysteresis)*1000)!=0xff)) + initial_thermaltrip[0]=1; + } + if(initial_thermaltrip[1]==0) + { + if((probe_setvalue(SWITCH_MAX, Thermaltrip[data->model][data->fan_direction][1]*1000)!=0xff) + && (probe_setvalue(SWITCH_MAX_HYST, (Thermaltrip[data->model][data->fan_direction][1]-temp_hysteresis)*1000)!=0xff)) + initial_thermaltrip[1]=1; + } + if(initial_thermaltrip[2]==0) + { + if((probe_setvalue(ENV_MAX, Thermaltrip[data->model][data->fan_direction][2]*1000)!=0xff) + && (probe_setvalue(ENV_MAX_HYST, (Thermaltrip[data->model][data->fan_direction][2]-temp_hysteresis)*1000)!=0xff)) + initial_thermaltrip[2]=1; + } + + //LED control + if (data->diag==0 && i2c_smbus_read_byte_data(client, 0)>=0) + { + for(retry=0;retry<2;retry++) + { + fanfail=0; + fanled[0]=0; //clean green led + fanled[1]=0; //clean red led + fanfront=0; + fanrear=0; + fanerror=0; + fanturnoff=0; + + //------ Fan Check ------- + cpld_i2c_read(client2, fanrpm, CPLD_RPM_OFFSET, 22); + fandir=fanrpm[20]; + fanpresent=fanrpm[21]; + + //Count the fan's direction + for (i=0;i 23500) || (rpm2 < 3000 || rpm2 > 23500)) + fanerror++; + else if(fandir&(1<>i)&0x01)!=data->fan_direction) + fanled[0] |= (1<stack_mode==0) frontled&=~(0x3); //0: Non-Stack member => off + if(data->stack_mode==1) frontled|=0x2; //1: Stack Master => Flash green + if(data->stack_mode==2) frontled|=0x1; //2: Stack Backup/Member => Steady green + if(data->stack_mode==3) frontled|=lastStack;//3: Stack Error => last status + lastStack=frontled; + + if(fanpresent!=0x00) //Fan LED in bit2 bit3 + { + frontled|=(0x02<<2); //Some fan unpresent => 0x02 + } + else + { + if(fanturnoff||fanfail) //some fan no speed => 0x03 + frontled|=(0x03<<2); //some fan dir different => 0x03 + else + frontled|=(0x01<<2); //Normal => 0x01 + } + + if(psustatus&0x22) //POW LED in bit4 bit5 + frontled|=(0x02<<4); //not all psu plug-in => 0x02 + else if (psustatus!=0x11) + frontled|=(0x03<<4); //some power is not ok => 0x03 + else + frontled|=(0x01<<4); //Normal => 0x01 + + if(data->operation_command==1) //Service LED in bit6 bit7 + frontled|=(0x01<<6); //Steady if operation + else if(fanfail>0||psufail>0||data->stack_mode==3) + frontled|=(0x02<<6); //Flash if any error + else if(data->stack_mode==2) + frontled|=(0x01<<6); //Steady if mode in Stack Backup/Member + else + frontled&=~(0x3<<6); //Off if mode in Non-Stack member or Stack Master with no operation and error + cpld_i2c_write(client, &frontled, CPLD_LED_OFFSET, 1); + } + set_current_state(TASK_INTERRUPTIBLE); + if(kthread_should_stop()) break; + schedule_timeout(msecs_to_jiffies(CPLD_POLLING_PERIOD)); + } + return 0; +} + +/*-----------------------------------------------------------------------*/ +/* device probe and removal */ + +static int +cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct cpld_data *data; + int status; + u8 byte[5]={PWM_DEFAULT,PWM_DEFAULT,PWM_DEFAULT,PWM_DEFAULT,PWM_DEFAULT}; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + return -EIO; + + data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cpld_group); + + if (status) + goto exit_free; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + //Check CPLD2 exist or not + client2 = i2c_new_dummy(client->adapter, CPLD2_ADDRESS); + if(!client2) { + hasCPLD2 = 0; + client2 = client; + } else { + status = i2c_smbus_read_byte_data(client2, CPLD_INFO_OFFSET); + if(status<0) { + i2c_unregister_device(client2); + i2c_set_clientdata(client2, NULL); + hasCPLD2 = 0; + client2 = client; + } + } + + dev_info(&client->dev, "%s: sensor '%s'\n", + dev_name(data->hwmon_dev), client->name); + + //initial PWM to 60% + cpld_i2c_write(client2, byte, CPLD_PWM_OFFSET, 5); + + //Handle LED control by the driver + byte[0]=0x01; + cpld_i2c_write(client, byte, CPLD_CTL_OFFSET, 1); + cpld_i2c_write(client2, byte, CPLD_CTL_OFFSET, 1); + + //Get Model type + cpld_i2c_read(client, byte, CPLD_INFO_OFFSET, 1); + data->model = (byte[0]>>5) & 0x01; + data->fan_direction = (byte[0]>>7) & 0x01; + + //kernel panic notifier + atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier); + + //soft reboot notifier + register_reboot_notifier(&reboot_notifier); + + client_notifier=client; + + data->cpld_thread = kthread_run(cpld_polling,client,"%s",dev_name(data->hwmon_dev)); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &cpld_group); +exit_free: + i2c_set_clientdata(client, NULL); + kfree(data); + return status; +} + +static int cpld_remove(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + //Return LED control to the CPLD + u8 byte=0x00; + cpld_i2c_write(client, &byte, CPLD_CTL_OFFSET, 1); + cpld_i2c_write(client2, &byte, CPLD_CTL_OFFSET, 1); + + //unregister soft reboot notifier + unregister_reboot_notifier(&reboot_notifier); + + //unregister kernel panic notifier + atomic_notifier_chain_unregister(&panic_notifier_list, &panic_notifier); + + //stop cpld thread + kthread_stop(data->cpld_thread); + + sysfs_remove_group(&client->dev.kobj, &cpld_group); + hwmon_device_unregister(data->hwmon_dev); + i2c_set_clientdata(client, NULL); + if(hasCPLD2) { + i2c_unregister_device(client2); + i2c_set_clientdata(client2, NULL); + } + + kfree(data); + return 0; +} + +static const struct i2c_device_id cpld_ids[] = { + { "inv_cpld" , 0, }, + { /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, cpld_ids); + +static struct i2c_driver cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "inv_cpld", + }, + .probe = cpld_probe, + .remove = cpld_remove, + .id_table = cpld_ids, +}; + +/*-----------------------------------------------------------------------*/ + +/* module glue */ + +static int __init inv_cpld_init(void) +{ + return i2c_add_driver(&cpld_driver); +} + +static void __exit inv_cpld_exit(void) +{ + i2c_del_driver(&cpld_driver); +} + +MODULE_AUTHOR("jack.ting "); +MODULE_DESCRIPTION("cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(inv_cpld_init); +module_exit(inv_cpld_exit); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_eeprom.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_eeprom.c new file mode 100644 index 000000000000..781ef27671c1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_eeprom.c @@ -0,0 +1,180 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 256 + +#define SLICE_BITS (6) +#define SLICE_SIZE (1 << SLICE_BITS) +#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE) + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +}; + + +static void inv_eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + int ret; + int addr; + + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + addr = slice << SLICE_BITS; + + ret = i2c_smbus_write_byte_data(client, ((u8)addr >> 8) & 0xFF, (u8)addr & 0xFF); + /* select the eeprom address */ + if (ret < 0) { + dev_err(&client->dev, "address set failed\n"); + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) { + goto exit; + } + + for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) { + for (j = i; j < (i+SLICE_SIZE); j++) { + int res; + + res = i2c_smbus_read_byte(client); + if (res < 0) { + goto exit; + } + + data->data[j] = res & 0xFF; + } + } + + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } + +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t inv_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) { + inv_eeprom_update_client(client, slice); + } + + memcpy(buf, &data->data[off], count); + + return count; +} + +static struct bin_attribute inv_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = EEPROM_SIZE, + .read = inv_eeprom_read, +}; + +static int inv_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &inv_eeprom_attr); + if (err) { + goto exit_kfree; + } + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int inv_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &inv_eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id inv_eeprom_id[] = { + { "inv_eeprom", 0 }, + { } +}; + +static struct i2c_driver inv_eeprom_driver = { + .driver = { + .name = "inv_eeprom", + }, + .probe = inv_eeprom_probe, + .remove = inv_eeprom_remove, + .id_table = inv_eeprom_id, +}; + +module_i2c_driver(inv_eeprom_driver); + +MODULE_AUTHOR("Inventec"); +MODULE_DESCRIPTION("Inventec D6556 Mother Board EEPROM driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.c new file mode 100644 index 000000000000..40593a96eeb7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.c @@ -0,0 +1,545 @@ +#include +#include +#include +#include +#include +#include +#include "io_expander.h" +#include "inv_mux.h" + +/* For build single module using (Ex: ONL platform) */ +#include +//#include +//#include + +static struct mux_obj_s *mux_head_p = NULL; + +/* ========== MUX object functions ========== + */ +static int +_setup_i2c_value(struct mux_obj_s *self, int offset, int value){ + + return i2c_smbus_write_byte_data(self->i2c_client_p, offset, value); +} + + +static int +_setup_i2c_client(struct mux_obj_s *self, int chan_id, int addr){ + + struct i2c_adapter *adap = NULL; + char *emsg = "ERR"; + + adap = i2c_get_adapter(chan_id); + if (!adap){ + emsg = "can't get adapter"; + goto err_setup_i2c_client; + } + self->i2c_client_p = kzalloc(sizeof(*self->i2c_client_p), GFP_KERNEL); + if (!self->i2c_client_p){ + emsg = "can't kzalloc client"; + goto err_setup_i2c_client; + } + self->i2c_client_p->adapter = adap; + self->i2c_client_p->addr = addr; + return 0; + +err_setup_i2c_client: + SWPS_ERR("%s: %s\n", __func__, emsg); + return ERR_MUX_UNEXCPT; +} + + +int +_common_force_pull_gpio(int mem_addr, + int input, + int bit_offset){ + + unsigned int val = 0; + unsigned int targ = 0; + + /* Get current value */ + val = inl(mem_addr); + if (val == 0) { + SWPS_ERR("%s: inl:%d fail!\n", __func__, val); + return -1; + } + /* Count target value */ + switch (input) { + case 0: /* Pull Low */ + targ = (val & (~(1 << bit_offset))); + break; + case 1: /* Pull high */ + targ = (val | (1 << bit_offset)); + break; + default: + SWPS_ERR("%s: input state:%d incorrect!\n", + __func__, input); + return -1; + } + /* Setup gpio */ + outl(targ, mem_addr); + if (targ != inl(mem_addr)){ + SWPS_ERR("%s: outl:%d fail!\n", __func__, targ); + return -1; + } + SWPS_DEBUG("%s: done.\n", __func__); + return 0; +} + + +int +rangeley_force_pull_high(struct mux_obj_s *self){ + SWPS_ERR("%s: not ready!\n", __func__); + return -1; +} + + +int +rangeley_force_pull_low(struct mux_obj_s *self){ + SWPS_ERR("%s: not ready!\n", __func__); + return -1; +} + + +int +hedera_force_pull_high(struct mux_obj_s *self){ + return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 1, 5); +} + + +int +hedera_force_pull_low(struct mux_obj_s *self){ + return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 0, 5); +} + + +int +normal_gpio_pull_high(struct mux_obj_s *self){ + return gpio_direction_output(self->gpio_num, 1); +} + + +int +normal_gpio_pull_low(struct mux_obj_s *self){ + return gpio_direction_output(self->gpio_num, 0); +} + + +int +cpld_rst_all_4_pull_low(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto setlow_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_rst_all_4_pull_low; + +setlow_cpld_rst_all_4_c0_a77_70_74_rst_all: + err = _setup_i2c_value(self, 0x70, 0x0); + if (err < 0) { + emsg = "setup 0x70 fail"; + goto err_cpld_rst_all_4_pull_low; + } + err = _setup_i2c_value(self, 0x74, 0x01); + if (err < 0) { + emsg = "setup 0x74 fail"; + goto err_cpld_rst_all_4_pull_low; + } + return 0; + +err_cpld_rst_all_4_pull_low: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +cpld_rst_all_4_pull_high(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_rst_all_4_pull_high; + +sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all: + err = _setup_i2c_value(self, 0x70, 0xfe); + if (err < 0) { + emsg = "setup 0x70 fail"; + goto err_cpld_rst_all_4_pull_high; + } + err = _setup_i2c_value(self, 0x74, 0x03); + if (err < 0) { + emsg = "setup 0x74 fail"; + goto err_cpld_rst_all_4_pull_high; + } + return 0; + +err_cpld_rst_all_4_pull_high: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +pca9548_reset_mux_all(struct mux_obj_s *self){ + /* [Note] Power-on reset (PCA9548A-NXP) + * When power is applied to VDD, an internal Power-On Reset (POR) + * holds the PCA9548A in a reset condition until VDD has reached + * VPOR. At this point, the reset condition is released and the + * PCA9548A register and I2C-bus state machine are initialized to + * their default states (all zeroes) causing all the channels to + * be deselected. Thereafter, VDD must be lowered below 0.2 V for + * at least 5 us in order to reset the device. + */ + if (self->_pull_low(self) < 0) { + SWPS_ERR("%s: _pull_low fail!\n", __func__); + return -1; + } + mdelay(MUX_RST_WAIT_MS_PCA9548); + if (self->_pull_high(self) < 0) { + SWPS_ERR("%s: _pull_high fail!\n", __func__); + return -1; + } + mdelay(MUX_RST_WAIT_MS_PCA9548); + return 0; +} + + +int +cpld_reset_mux_all(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto reset_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_reset_mux_all; + +reset_cpld_rst_all_4_c0_a77_70_74_rst_all: + if (self->_pull_low(self) < 0) { + emsg = "_pull_low fail"; + goto err_cpld_reset_mux_all; + } + mdelay(MUX_RST_WAIT_MS_CPLD); + return 0; + +err_cpld_reset_mux_all: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +common_reset_mux_all(struct mux_obj_s *self){ + SWPS_ERR("%s: not ready!\n", __func__); + return -1; +} + + +int +init_gpio_4_force(struct mux_obj_s *self){ + + if (self->_pull_high(self) < 0) { + SWPS_ERR("%s: setup default fail!\n", __func__); + return -1; + } + return 0; +} + + +int +init_gpio_4_normal(struct mux_obj_s *self){ + + int err = 0; + char *emsg = "ERR"; + + if (!gpio_is_valid(self->gpio_num)) { + emsg = "GPIO invalid"; + goto err_init_gpio_4_normal; + } + err = gpio_request(self->gpio_num, MUX_GPIO_LABEL); + if (err < 0) { + emsg = "gpio_request fail"; + goto err_init_gpio_4_normal; + } + err = self->_pull_high(self); + if (err < 0) { + emsg = "setup default fail"; + goto err_init_gpio_4_normal; + } + SWPS_DEBUG("%s: gpio_request:%d ok.\n", __func__, self->gpio_num); + return 0; + +err_init_gpio_4_normal: + SWPS_ERR("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return -1; +} + + +int +init_cpld_4_rst_all(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + int chan = ERR_MUX_UNEXCPT; + int addr = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto init_cpld_i2c_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_init_cpld_4_rst_all; + +init_cpld_i2c_c0_a77_70_74_rst_all: + chan = 0; + addr = 0x77; + err = _setup_i2c_client(self, chan, addr); + if (err < 0) { + emsg = "_setup_i2c_client fail"; + goto err_init_cpld_4_rst_all; + } + err = self->_pull_high(self); + if (err < 0) { + emsg = "setup default value fail"; + goto err_init_cpld_4_rst_all; + } + SWPS_DEBUG("%s: init_cpld_i2c_c0_a77_70_74_rst_all ok", __func__); + return 0; + +err_init_cpld_4_rst_all: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +clean_gpio_4_common(struct mux_obj_s *self){ + + if (!self) return 0; + if (!gpio_is_valid(self->gpio_num)) return 0; + self->_pull_high(self); + gpio_free(mux_head_p->gpio_num); + return 0; +} + + +int +clean_cpld_4_rst_all(struct mux_obj_s *self){ + + if (!self) return 0; + self->_pull_high(self); + if (self->i2c_client_p) { + i2c_put_adapter(self->i2c_client_p->adapter); + kfree(self->i2c_client_p); + } + return 0; +} + + +static int +_setup_muxctl_cb(struct mux_obj_s *self, + unsigned gpio){ + + char mod_dsc[32] = "ERR"; + + switch (gpio) { + case MUX_RST_GPIO_FORCE_RANGELEY: + self->gpio_num = gpio; + self->_pull_low = rangeley_force_pull_low; + self->_pull_high = rangeley_force_pull_high; + self->_init = init_gpio_4_force; + self->_clean = clean_gpio_4_common; + self->reset = pca9548_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "Rangeley force mode"); + goto ok_setup_muxctl_cb; + + case MUX_RST_GPIO_FORCE_HEDERA: + self->gpio_num = gpio; + self->_pull_low = hedera_force_pull_low; + self->_pull_high = hedera_force_pull_high; + self->_init = init_gpio_4_force; + self->_clean = clean_gpio_4_common; + self->reset = pca9548_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "Hedera force mode"); + goto ok_setup_muxctl_cb; + + case MUX_RST_GPIO_48_PCA9548: + case MUX_RST_GPIO_69_PCA9548: + case MUX_RST_GPIO_249_PCA9548: + case MUX_RST_GPIO_500_PCA9548: + case MUX_RST_GPIO_505_PCA9548: + self->gpio_num = gpio; + self->_pull_low = normal_gpio_pull_low; + self->_pull_high = normal_gpio_pull_high; + self->_init = init_gpio_4_normal; + self->_clean = clean_gpio_4_common; + self->reset = pca9548_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "Normal mode :%d", (int)gpio); + goto ok_setup_muxctl_cb; + + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + self->gpio_num = gpio; + self->_pull_low = cpld_rst_all_4_pull_low; + self->_pull_high = cpld_rst_all_4_pull_high; + self->_init = init_cpld_4_rst_all; + self->_clean = clean_cpld_4_rst_all; + self->reset = cpld_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "CPLD mode :%d", (int)gpio); + goto ok_setup_muxctl_cb; + + default: + break; + } + SWPS_ERR("%s: Unexpected GPIO:%d\n", __func__, gpio); + return -1; + +ok_setup_muxctl_cb: + SWPS_INFO("muxctl: %s.\n", mod_dsc); + return 0; +} + + +/* ========== MUX public functions ========== + */ +void +clean_mux_objs(void){ + + struct mux_obj_s *curr_p = mux_head_p; + struct mux_obj_s *next_p = NULL; + + if (!curr_p) { + SWPS_DEBUG("%s: mux_head_p is NULL\n", __func__); + return; + } + while (curr_p) { + next_p = curr_p->next; + curr_p->_clean(curr_p); + kfree(curr_p); + curr_p = next_p; + } + SWPS_DEBUG("%s: done.\n", __func__); +} +EXPORT_SYMBOL(clean_mux_objs); + + +int +reset_mux_objs(void){ + + if (!mux_head_p) { + SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__); + return -1; + } + if (mux_head_p->reset(mux_head_p) < 0){ + SWPS_ERR("%s: reset fail!\n", __func__); + return -1; + } + return 0; +} +EXPORT_SYMBOL(reset_mux_objs); + + +struct mux_obj_s * +_create_mux_obj(unsigned gpio){ + + char *emsg = "ERR"; + struct mux_obj_s *obj_p = NULL; + + obj_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL); + if (!obj_p) { + emsg = "kzalloc fail!"; + goto err_create_mux_obj_1; + } + if (_setup_muxctl_cb(obj_p, gpio) < 0){ + emsg = "_setup_muxctl_cb fail!"; + goto err_create_mux_obj_2; + } + if (obj_p->_init(obj_p) < 0) { + emsg = "_init() fail!"; + goto err_create_mux_obj_2; + } + SWPS_DEBUG("%s: created MUX object :%d\n", __func__, gpio); + return obj_p; + +err_create_mux_obj_2: + kfree(obj_p); +err_create_mux_obj_1: + SWPS_ERR("%s: %s :%d\n", __func__, emsg, gpio); + return NULL; +} + + +int +init_mux_objs(unsigned gpio){ + + struct mux_obj_s *curr_p = NULL; + char *emsg = "ERR"; + + /* Create MUX control object */ + if (mux_head_p) { + SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__); + clean_mux_objs(); + } + /* Currently, it is using single muxctl architecture. + * In the future, it may use the multi-muxctl. + * (Ex: Gulmohar's advance I2C control / Peony's reset single mux) + */ + curr_p = _create_mux_obj(gpio); + if (!curr_p) { + emsg = "_create_mux_obj fail"; + goto err_init_mux_objs; + } + curr_p->next = NULL; + mux_head_p = curr_p; + SWPS_DEBUG("%s: all done. :%d\n", __func__, gpio); + return 0; + +err_init_mux_objs: + clean_mux_objs(); + SWPS_ERR("%s: %s\n", __func__, emsg); + return -1; +} +EXPORT_SYMBOL(init_mux_objs); + + +/* For single ko module + * => You need to declare MODULE_LICENSE If you want to build single module along. + * => Ex: For ONL platform + */ +MODULE_LICENSE("GPL"); + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.h b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.h new file mode 100644 index 000000000000..a6b9d98d6e7e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.h @@ -0,0 +1,50 @@ +#ifndef INV_MUX_H +#define INV_MUX_H + +#include + +/* MUX basic information */ +#define MUX_GPIO_LABEL "SWPS_RST_MUX" + +/* MUX reset GPIO define */ +#define MUX_RST_GPIO_FORCE (30100) +#define MUX_RST_GPIO_FORCE_RANGELEY (30101) +#define MUX_RST_GPIO_FORCE_HEDERA (30102) +#define MUX_RST_GPIO_48_PCA9548 (48) +#define MUX_RST_GPIO_69_PCA9548 (69) +#define MUX_RST_GPIO_249_PCA9548 (249) +#define MUX_RST_GPIO_500_PCA9548 (500) +#define MUX_RST_GPIO_505_PCA9548 (505) +#define MUX_RST_CPLD_C0_A77_70_74_RST_ALL (30201) + +/* MUX relate value define */ +#define MUX_RST_WAIT_MS_PCA9548 (1) +#define MUX_RST_WAIT_MS_CPLD (10) +#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD +#define MUX_RST_MEM_ADDR_HEDERA (0x548) + +/* MUX error code define */ +#define ERR_MUX_UNEXCPT (-399) + +struct mux_obj_s { + struct i2c_client *i2c_client_p; + struct mux_obj_s *next; + unsigned gpio_num; + int (*_pull_high)(struct mux_obj_s *self); + int (*_pull_low)(struct mux_obj_s *self); + int (*_init)(struct mux_obj_s *self); + int (*_clean)(struct mux_obj_s *self); + int (*reset)(struct mux_obj_s *self); +}; + + +void clean_mux_objs(void); +int reset_mux_objs(void); +int init_mux_objs(unsigned gpio); + + +#endif /* INV_MUX_H */ + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_platform.c new file mode 100644 index 000000000000..c5331ab7319c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_platform.c @@ -0,0 +1,228 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct inv_i2c_board_info { + int ch; + int size; + struct i2c_board_info *board_info; + int probe; +}; + +#define bus_id(id) (id) +#define SCL_PIN 58 +#define SDA_PIN 75 + +static struct pca954x_platform_mode mux_modes_0[] = { + {.adap_id = bus_id(2),}, {.adap_id = bus_id(3),}, +}; + +static struct pca954x_platform_mode mux_modes_1[] = { + {.adap_id = bus_id(4),}, {.adap_id = bus_id(5),}, + {.adap_id = bus_id(6),}, {.adap_id = bus_id(7),}, + {.adap_id = bus_id(8),}, {.adap_id = bus_id(9),}, + {.adap_id = bus_id(10),}, {.adap_id = bus_id(11),}, +}; + +static struct pca954x_platform_mode mux_modes_2_0[] = { + {.adap_id = bus_id(12),}, {.adap_id = bus_id(13),}, + {.adap_id = bus_id(14),}, {.adap_id = bus_id(15),}, + {.adap_id = bus_id(16),}, {.adap_id = bus_id(17),}, + {.adap_id = bus_id(18),}, {.adap_id = bus_id(19),}, +}; + +static struct pca954x_platform_mode mux_modes_2_1[] = { + {.adap_id = bus_id(20),}, {.adap_id = bus_id(21),}, + {.adap_id = bus_id(22),}, {.adap_id = bus_id(23),}, + {.adap_id = bus_id(24),}, {.adap_id = bus_id(25),}, + {.adap_id = bus_id(26),}, {.adap_id = bus_id(27),}, +}; + +static struct pca954x_platform_mode mux_modes_2_2[] = { + {.adap_id = bus_id(28),}, {.adap_id = bus_id(29),}, + {.adap_id = bus_id(30),}, {.adap_id = bus_id(31),}, + {.adap_id = bus_id(32),}, {.adap_id = bus_id(33),}, + {.adap_id = bus_id(34),}, {.adap_id = bus_id(35),}, +}; + +static struct pca954x_platform_mode mux_modes_2_3[] = { + {.adap_id = bus_id(36),}, {.adap_id = bus_id(37),}, + {.adap_id = bus_id(38),}, {.adap_id = bus_id(39),}, + {.adap_id = bus_id(40),}, {.adap_id = bus_id(41),}, + {.adap_id = bus_id(42),}, {.adap_id = bus_id(43),}, +}; + + +static struct pca954x_platform_data mux_data_0 = { + .modes = mux_modes_0, + .num_modes = 2, +}; + +static struct pca954x_platform_data mux_data_1 = { + .modes = mux_modes_1, + .num_modes = 8, +}; + +static struct pca954x_platform_data mux_data_2_0 = { + .modes = mux_modes_2_0, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_2_1 = { + .modes = mux_modes_2_1, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_2_2 = { + .modes = mux_modes_2_2, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_2_3 = { + .modes = mux_modes_2_3, + .num_modes = 8, +}; + +static struct i2c_board_info i2c_device_info0[] __initdata = { + {"inv_cpld", 0, 0x77, "inv_cpld", 0, 0, 0}, // CPLD driver +// {"24c512", 0, 0x55, 0, 0, 0}, // OEM1 VPD +// {"24c512", 0, 0x54, 0, 0, 0}, // OEM2 VPD + {"pca9543", 0, 0x73, "pca9543", &mux_data_0, 0, 0}, // MUX +}; + +static struct i2c_board_info i2c_device_info1[] __initdata = { + {"pca9548", 0, 0x70, "pca9548-1", &mux_data_1, 0, 0}, +}; + +static struct i2c_board_info i2c_device_info2[] __initdata ={ + {"ucd90160", 0, 0x34, "ucd90160", 0, 0 ,0}, +}; + +static struct i2c_board_info i2c_device_info11[] __initdata ={ + {"pmbus", 0, 0x5A, "pmbus-1", 0, 0 ,0}, //PSU1 DVT + {"pmbus", 0, 0x5B, "pmbus-2", 0, 0 ,0}, //PSU2 DVT +}; + +static struct i2c_board_info i2c_device_info3[] __initdata ={ + {"tmp75", 0, 0x48, "tmp75-1", 0, 0 ,0}, //CPU Board Temperature + {"tmp75", 0, 0x4A, "tmp75-2", 0, 0 ,0}, //Front Panel Inlet Temperature + {"tmp75", 0, 0x4D, "tmp75-3", 0, 0 ,0}, + {"tmp75", 0, 0x4E, "tmp75-4", 0, 0 ,0}, //Near ASIC Temperature +}; + +static struct i2c_board_info i2c_device_info4[] __initdata = { + {"pca9548", 0, 0x72, "pca9548-2", &mux_data_2_0, 0, 0}, +}; +static struct i2c_board_info i2c_device_info5[] __initdata = { + {"pca9548", 0, 0x72, "pca9548-3", &mux_data_2_1, 0, 0}, +}; +static struct i2c_board_info i2c_device_info6[] __initdata = { + {"pca9548", 0, 0x72, "pca9548-4", &mux_data_2_2, 0, 0}, +}; +static struct i2c_board_info i2c_device_info7[] __initdata = { + {"pca9548", 0, 0x72, "pca9548-5", &mux_data_2_3, 0, 0}, +}; + +static struct inv_i2c_board_info i2cdev_list[] = { + {bus_id(0), ARRAY_SIZE(i2c_device_info0), i2c_device_info0 , 0}, //i2c-0 smbus + {bus_id(0), ARRAY_SIZE(i2c_device_info1), i2c_device_info1 , 1}, //i2c-0 smbus (for DVT) + {bus_id(1), ARRAY_SIZE(i2c_device_info1), i2c_device_info1 , 1}, //i2c-1 i2c-gpio (for EVT) + {bus_id(3), ARRAY_SIZE(i2c_device_info3), i2c_device_info3 , 0}, //mux 0x73 channel 1 + {bus_id(2), ARRAY_SIZE(i2c_device_info2), i2c_device_info2 , 0}, //mux 0x73 channel 0 + {bus_id(2), ARRAY_SIZE(i2c_device_info11), i2c_device_info11, 1}, //mux 0x73 channel 0 + {bus_id(4), ARRAY_SIZE(i2c_device_info4), i2c_device_info4 , 1}, //mux 0x70 channel 0 + {bus_id(5), ARRAY_SIZE(i2c_device_info5), i2c_device_info5 , 1}, //mux 0x70 channel 1 + {bus_id(6), ARRAY_SIZE(i2c_device_info6), i2c_device_info6 , 1}, //mux 0x70 channel 2 + {bus_id(7), ARRAY_SIZE(i2c_device_info7), i2c_device_info7 , 1}, //mux 0x70 channel 3 +}; + +static struct gpiod_lookup_table inv_i2c_gpiod_table = { + .dev_id = "i2c-gpio.1", + .table = { + GPIO_LOOKUP_IDX("gpio_ich", SDA_PIN, NULL, 0, GPIO_OPEN_DRAIN), //I2C_SDA + GPIO_LOOKUP_IDX("gpio_ich", SCL_PIN, NULL, 1, GPIO_OPEN_DRAIN), //I2C_SCL + }, +}; + +static struct i2c_gpio_platform_data i2c_platform_data = { + .udelay = 5, //5:100kHz + //.sda_is_open_drain = 0, + //.scl_is_open_drain = 0, + //.scl_is_output_only = 0, +}; + +static void i2cgpio_device_release(struct device *dev) +{ + gpiod_remove_lookup_table(&inv_i2c_gpiod_table); +} + +static struct platform_device device_i2c_gpio0 = { + .name = "i2c-gpio", + .id = 1, + .dev = { + .platform_data = &i2c_platform_data, + .release = i2cgpio_device_release, + }, +}; + +static int __init inv_platform_init(void) +{ + struct i2c_adapter *adap = NULL; + struct i2c_client *e = NULL; + int ret = 0; + int i,j,k; + + //use i2c-gpio + //register gpio + outl( inl(0x533) | (1<<2), 0x533); //i2c-gpio sdl(58) + outl( inl(0x541) | (1<<3), 0x541); //i2c gpio sda(75) + outl( inl(0x540) | (1<<5), 0x540); //RST_I2C_MUX_N(69) + outl( inl(0x503) | (1)|(1<<2)|(1<<3), 0x503); //WDT_IRQ_N(24) PSOC_HEART_BEAT(26) CPLD_HEART_BEAT(27) + outl( inl(0x501) | (1<<4), 0x501); //RSTBTN_IN_N(12) + outl( inl(0x533) | (1<<5), 0x533); //RST_BTN_5S_N(61) + + gpiod_add_lookup_table(&inv_i2c_gpiod_table); + + ret = platform_device_register(&device_i2c_gpio0); + if (ret) { + printk(KERN_ERR "i2c-gpio: platform_device_register fail %d\n", ret); + } + msleep(10); + + for(i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "inv_swps.h" + +static int ctl_major; +static int port_major; +static int ioexp_total; +static int port_total; +static int block_polling; +static int auto_config; +static int flag_i2c_reset; +static int flag_mod_state; +static unsigned gpio_rest_mux; +static int gpio_base = 0; +static struct class *swp_class_p = NULL; +static struct inv_platform_s *platform_p = NULL; +static struct inv_ioexp_layout_s *ioexp_layout = NULL; +static struct inv_port_layout_s *port_layout = NULL; +int io_no_init = 0; +module_param(io_no_init, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +static void swp_polling_worker(struct work_struct *work); +static DECLARE_DELAYED_WORK(swp_polling, swp_polling_worker); + +static int reset_i2c_topology(void); + +static int +__swp_match(struct device *dev, +#ifdef SWPS_KERN_VER_AF_3_10 + + const void *data){ +#else + void *data){ +#endif + + char *name = (char *)data; + if (strcmp(dev_name(dev), name) == 0) + return 1; + return 0; +} + + +struct device * +get_swpdev_by_name(char *name){ + struct device *dev = class_find_device(swp_class_p, + NULL, + name, + __swp_match); + return dev; +} + + +static int +sscanf_2_int(const char *buf) { + + int result = -EBFONT; + char *hex_tag = "0x"; + + if (strcspn(buf, hex_tag) == 0) { + if (sscanf(buf,"%x",&result)) { + return result; + } + } else { + if (sscanf(buf,"%d",&result)) { + return result; + } + if(sscanf(buf,"-%d",&result)) { + return -result; + } + if (sscanf(buf,"%x",&result)) { + return result; + } + } + return -EBFONT; +} + + +static int +sscanf_2_binary(const char *buf) { + + int result = sscanf_2_int(buf); + + if (result < 0){ + return -EBFONT; + } + switch (result) { + case 0: + case 1: + return result; + default: + break; + } + return -EBFONT; +} + + +static int +_get_polling_period(void) { + + int retval = 0; + + if (SWP_POLLING_PERIOD == 0) { + return 0; + } + retval = ((SWP_POLLING_PERIOD * HZ) / 1000); + if (retval == 0) { + return 1; + } + return retval; +} + + +static struct transvr_obj_s * +_get_transvr_obj(char *dev_name) { + + struct device *dev_p = NULL; + struct transvr_obj_s *transvr_obj_p = NULL; + + dev_p = get_swpdev_by_name(dev_name); + if (!dev_p){ + return NULL; + } + transvr_obj_p = dev_get_drvdata(dev_p); + if (!transvr_obj_p){ + return NULL; + } + return transvr_obj_p; +} + + +static int +_is_i2c_target_exist(int chan, int addr) { + /* retval: Exist = 1 / Not exist = 0 / Error < 0 + */ + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + int retval = -1; + int err = -1; + int d_offs = 0; + + adap = i2c_get_adapter(chan); + if (!adap) { + SWPS_DEBUG("%s: can't get adapter\n", __func__); + retval = 0; + goto out_is_i2c_target_exist_1; + } + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client) { + SWPS_ERR("%s: kzalloc fail\n", __func__); + retval = -1; + goto out_is_i2c_target_exist_2; + } + client->adapter = adap; + client->addr = addr; + err = i2c_smbus_read_byte_data(client, d_offs); + if (err < 0) { + retval = 0; + } else { + retval = 1; + } + i2c_put_adapter(adap); + kfree(client); + return retval; + +out_is_i2c_target_exist_2: + i2c_put_adapter(adap); +out_is_i2c_target_exist_1: + return retval; +} + + +static void +unlock_tobj_all(void) { + + struct transvr_obj_s *tobj_p; + char port_name[32]; + int port_id = 0; + int minor_curr = 0; + + for (minor_curr=0; minor_currauto_config = auto_config; + unlock_transvr_obj(tobj_p); + SWPS_DEBUG("%s: Set %s auto_config=%d\n", + __func__, tobj_p->swp_name, auto_config); + } + return retval; +} + + +/* ========== R/W Functions module control attribute ========== + */ +static ssize_t +show_attr_platform(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 32, "%s\n", platform_p->name); +} + + +static ssize_t +show_attr_version(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%s\n", SWP_VERSION); +} + + +static ssize_t +show_attr_status(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", flag_mod_state); +} + + +static ssize_t +show_attr_auto_config(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", auto_config); +} + + +static ssize_t +show_attr_block_poll(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", block_polling); +} +static ssize_t +show_attr_io_no_init(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", io_no_init); +} + + +static int +_check_reset_pwd(const char *buf_p, + size_t count) { + + int in_max = 64; + int in_len = (int)count; + char in_val[64] = "ERR"; + char *emsg = "ERR"; + + if (in_len >= in_max) { + emsg = "input too much"; + goto err_check_reset_pwd; + } + if (!sscanf(buf_p,"%s",in_val)) { + emsg = "format incorrect"; + goto err_check_reset_pwd; + } + if (strcmp(in_val, SWP_RESET_PWD) != 0) { + emsg = "password incorrect"; + goto err_check_reset_pwd; + } + return 0; + +err_check_reset_pwd: + SWPS_ERR("%s: %s\n", __func__, emsg); + return -1; +} + + +static ssize_t +store_attr_reset_i2c(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + if (_check_reset_pwd(buf_p, count) < 0) { + return -EBFONT; + } + /* Polling mode */ + if (SWP_POLLING_ENABLE) { + SWPS_INFO("%s: reset I2C :polling\n", __func__); + flag_i2c_reset = 1; + return count; + } + /* Direct mode */ + SWPS_INFO("%s: reset I2C go. :direct\n", __func__); + if (reset_i2c_topology() < 0) { + SWPS_ERR("%s: reset fail!\n", __func__); + return -EIO; + } + SWPS_INFO("%s: reset I2C ok. :direct\n", __func__); + return count; +} + + +static ssize_t +store_attr_reset_swps(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p; + char port_name[32] = "ERR"; + int port_id = 0; + int minor_curr = 0; + + if (_check_reset_pwd(buf_p, count) < 0) { + return -EBFONT; + } + for (minor_curr=0; minor_currstate = STATE_TRANSVR_DISCONNECTED; + unlock_transvr_obj(tobj_p); + SWPS_INFO("%s: reset:%s\n", __func__, tobj_p->swp_name); + } + return count; +} + + +static ssize_t +store_attr_auto_config(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + int input_val = sscanf_2_int(buf_p); + + if (input_val < 0){ + return -EBFONT; + } + if ((input_val != 0) && (input_val != 1)) { + return -EBFONT; + } + auto_config = input_val; + _update_auto_config_2_trnasvr(); + return count; +} + + +static ssize_t +store_attr_block_poll( struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + int input_val = sscanf_2_int(buf_p); + + if (input_val < 0){ + return -EBFONT; + } + if ((input_val != 0) && (input_val != 1)) { + return -EBFONT; + } + + if(input_val != block_polling){ + block_polling = input_val; + if(block_polling){ + cancel_delayed_work_sync(&swp_polling); + } + else{ + schedule_delayed_work(&swp_polling, _get_polling_period()); + } + } + + return count; +} + +static ssize_t +store_attr_io_no_init( struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + int input_val = sscanf_2_int(buf_p); + + if ((input_val != 0) && (input_val != 1)) { + return -EBFONT; + } + + if(input_val != io_no_init){ + io_no_init = input_val; + } + + return count; +} + +/* ========== Show functions: For transceiver attribute ========== + */ +static ssize_t +_show_transvr_hex_attr(struct transvr_obj_s* tobj_p, + int (*get_func)(struct transvr_obj_s* tobj_p), + char *buf_p) { + size_t len; + int result; + + lock_transvr_obj(tobj_p); + result = get_func(tobj_p); + unlock_transvr_obj(tobj_p); + if (result < 0){ + len = snprintf(buf_p, 8, "%d\n", result); + } else { + len = snprintf(buf_p, 8, "0x%02x\n", result); + } + return len; +} + + +static ssize_t +_show_transvr_int_attr(struct transvr_obj_s* tobj_p, + int (*get_func)(struct transvr_obj_s* tobj_p), + char *buf_p) { + size_t len; + + lock_transvr_obj(tobj_p); + len = snprintf(buf_p, 16, "%d\n", get_func(tobj_p)); + unlock_transvr_obj(tobj_p); + return len; +} + + +static ssize_t +_show_transvr_str_attr(struct transvr_obj_s* tobj_p, + int (*get_func)(struct transvr_obj_s* tobj_p, char* buf), + char *buf_p) { + size_t len; + + lock_transvr_obj(tobj_p); + len = get_func(tobj_p, buf_p); + unlock_transvr_obj(tobj_p); + return len; +} + + +static ssize_t +show_attr_id(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_id, + buf_p); +} + + +static ssize_t +show_attr_ext_id(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_ext_id, + buf_p); +} + + +static ssize_t +show_attr_connector(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_connector, + buf_p); +} + + +static ssize_t +show_attr_vendor_name(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_name, + buf_p); +} + + +static ssize_t +show_attr_vendor_pn(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_pn, + buf_p); +} + + +static ssize_t +show_attr_vendor_rev(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_rev, + buf_p); +} + + +static ssize_t +show_attr_vendor_sn(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_sn, + buf_p); +} + + +static ssize_t +show_attr_power_cls(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + size_t len; + int result; + struct transvr_obj_s *tobj_p; + + tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + lock_transvr_obj(tobj_p); + result = tobj_p->get_power_cls(tobj_p); + unlock_transvr_obj(tobj_p); + if (result < 0){ + len = snprintf(buf_p, 16, "%d\n", result); + } else { + len = snprintf(buf_p, 16, "Power Class %d\n", result); + } + return len; +} + + +static ssize_t +show_attr_br(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_br, + buf_p); +} + + +static ssize_t +show_attr_len_sm(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_sm, + buf_p); +} + + +static ssize_t +show_attr_len_smf(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_smf, + buf_p); +} + + +static ssize_t +show_attr_len_om1(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om1, + buf_p); +} + + +static ssize_t +show_attr_len_om2(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om2, + buf_p); +} + + +static ssize_t +show_attr_len_om3(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om3, + buf_p); +} + + +static ssize_t +show_attr_len_om4(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om4, + buf_p); +} + + +static ssize_t +show_attr_comp_rev(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_rev, + buf_p); +} + + +static ssize_t +show_attr_comp_eth(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_eth_1, + buf_p); +} + + +static ssize_t +show_attr_comp_eth_10(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_eth_10, + buf_p); +} + + +static ssize_t +show_attr_comp_eth_10_40(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_eth_10_40, + buf_p); +} + + +static ssize_t +show_attr_comp_extend(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_extend, + buf_p); +} + + +static ssize_t +show_attr_rate_id(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_rate_id, + buf_p); +} + + +static ssize_t +show_attr_temperature(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_curr_temp, + buf_p); +} + + +static ssize_t +show_attr_voltage(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_curr_vol, + buf_p); +} + + +static ssize_t +show_attr_tx_bias(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_tx_bias, + buf_p); +} + + +static ssize_t +show_attr_tx_power(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_tx_power, + buf_p); +} + + +static ssize_t +show_attr_tx_eq(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_tx_eq, + buf_p); +} + + +static ssize_t +show_attr_rx_power(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_rx_power, + buf_p); +} + + +static ssize_t +show_attr_rx_am(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_rx_am, + buf_p); +} + + +static ssize_t +show_attr_rx_em(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_rx_em, + buf_p); +} + + +static ssize_t +show_attr_wavelength(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_wavelength, + buf_p); +} + + +static ssize_t +show_attr_extphy_offset(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_extphy_offset, + buf_p); +} + + +static ssize_t +show_attr_extphy_reg(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_extphy_reg, + buf_p); +} + + +static ssize_t +show_attr_info(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_info, + buf_p); +} + + +static ssize_t +show_attr_if_type(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_if_type, + buf_p); +} + + +static ssize_t +show_attr_if_speed(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_if_speed, + buf_p); +} + + +static ssize_t +show_attr_if_lane(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_if_lane, + buf_p); +} + + +static ssize_t +show_attr_cdr(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_cdr, + buf_p); +} + + +static ssize_t +show_attr_soft_rs0(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_soft_rs0, + buf_p); +} + + +static ssize_t +show_attr_soft_rs1(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_soft_rs1, + buf_p); +} + + +static ssize_t +show_attr_soft_rx_los(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_soft_rx_los, + buf_p); +} + + +static ssize_t +show_attr_soft_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_soft_tx_disable, + buf_p); +} + + +static ssize_t +show_attr_soft_tx_fault(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_soft_tx_fault, + buf_p); +} + + +static ssize_t +show_attr_auto_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_auto_tx_disable, + buf_p); +} + + +/* ========== Store functions: transceiver (R/W) attribute ========== + */ +static ssize_t +_store_transvr_int_attr(struct transvr_obj_s* tobj_p, + int (*set_func)(struct transvr_obj_s *tobj_p, int input_val), + const char *buf_p, + size_t count) { + int input, err; + + input = sscanf_2_int(buf_p); + if (input < 0){ + return -EBFONT; + } + lock_transvr_obj(tobj_p); + err = set_func(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +_store_transvr_byte_hex_attr(struct transvr_obj_s* tobj_p, + int (*set_func)(struct transvr_obj_s *tobj_p, int input_val), + const char *buf_p, + size_t count) { + int input, err; + + input = sscanf_2_int(buf_p); + if ((input < 0) || (input > 0xff)){ + return -EBFONT; + } + lock_transvr_obj(tobj_p); + err = set_func(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +_store_transvr_binary_attr(struct transvr_obj_s* tobj_p, + int (*set_func)(struct transvr_obj_s *tobj_p, int input_val), + const char *buf_p, + size_t count) { + int input, err; + + input = sscanf_2_binary(buf_p); + if (input < 0){ + return -EBFONT; + } + lock_transvr_obj(tobj_p); + err = set_func(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +store_attr_cdr(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_byte_hex_attr(tobj_p, + tobj_p->set_cdr, + buf_p, + count); +} + + +static ssize_t +store_attr_soft_rs0(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_binary_attr(tobj_p, + tobj_p->set_soft_rs0, + buf_p, + count); +} + + +static ssize_t +store_attr_soft_rs1(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_binary_attr(tobj_p, + tobj_p->set_soft_rs1, + buf_p, + count); +} + + +static ssize_t +store_attr_soft_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count) { + + int check = sscanf_2_int(buf_p); + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + if ((check < 0) || (check > 0xf)){ + return -EBFONT; + } + return _store_transvr_byte_hex_attr(tobj_p, + tobj_p->set_soft_tx_disable, + buf_p, + count); +} + + +static ssize_t +store_attr_auto_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count) { + + int err = -EPERM; + int input = sscanf_2_int(buf_p); + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + if ((input < 0) || (input > 0xf)){ + if (input != VAL_TRANSVR_FUNCTION_DISABLE) { + return -EBFONT; + } + } + lock_transvr_obj(tobj_p); + err = tobj_p->set_auto_tx_disable(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +store_attr_tx_eq(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_tx_eq, + buf_p, + count); +} + + +static ssize_t +store_attr_rx_am(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_rx_am, + buf_p, + count); +} + + +static ssize_t +store_attr_rx_em(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_rx_em, + buf_p, + count); +} + + +static ssize_t +store_attr_extphy_offset(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_extphy_offset, + buf_p, + count); +} + + +static ssize_t +store_attr_extphy_reg(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_extphy_reg, + buf_p, + count); +} + +/* ========== Show functions: For I/O Expander attribute ========== + */ +static ssize_t +_show_ioexp_binary_attr(struct transvr_obj_s *tobj_p, + int (*get_func)(struct ioexp_obj_s *ioexp_p, int voffset), + char *buf_p) { + size_t len; + struct ioexp_obj_s *ioexp_p = tobj_p->ioexp_obj_p; + + if (!ioexp_p) { + SWPS_ERR(" %s: data corruption! :%s\n", __func__, tobj_p->swp_name); + return -ENODATA; + } + mutex_lock(&ioexp_p->lock); + len = snprintf(buf_p, 8, "%d\n", get_func(ioexp_p, tobj_p->ioexp_virt_offset)); + mutex_unlock(&ioexp_p->lock); + return len; +} + + +static ssize_t +show_attr_present(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_present, + buf_p); +} + + +static ssize_t +show_attr_tx_fault(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_tx_fault, + buf_p); +} + + +static ssize_t +show_attr_rxlos(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_rxlos, + buf_p); +} + + +static ssize_t +show_attr_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_tx_disable, + buf_p); +} + + +static ssize_t +show_attr_reset(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_reset, + buf_p); +} + + +static ssize_t +show_attr_lpmod(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_lpmod, + buf_p); +} + + +static ssize_t +show_attr_modsel(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_modsel, + buf_p); +} + + +static ssize_t +show_attr_hard_rs0(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_hard_rs0, + buf_p); +} + + +static ssize_t +show_attr_hard_rs1(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_hard_rs1, + buf_p); +} + + +/* ========== Store functions: For I/O Expander (R/W) attribute ========== + */ +static ssize_t +_store_ioexp_binary_attr(struct transvr_obj_s *tobj_p, + int (*set_func)(struct ioexp_obj_s *ioexp_p, + int virt_offset, int input_val), + const char *buf_p, + size_t count) { + + int input, err; + struct ioexp_obj_s *ioexp_p = tobj_p->ioexp_obj_p; + + if (!ioexp_p) { + SWPS_ERR("%s: data corruption! :%s\n", + __func__, tobj_p->swp_name); + return -ENODATA; + } + input = sscanf_2_binary(buf_p); + if (input < 0) { + return -EBFONT; + } + mutex_lock(&ioexp_p->lock); + err = set_func(ioexp_p, tobj_p->ioexp_virt_offset, input); + mutex_unlock(&ioexp_p->lock); + if (err < 0){ + return err; + } + return count; +} + +static ssize_t +store_attr_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_tx_disable, + buf_p, + count); +} + + +static ssize_t +store_attr_reset(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_reset, + buf_p, + count); +} + + +static ssize_t +store_attr_lpmod(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_lpmod, + buf_p, + count); +} + + +static ssize_t +store_attr_modsel(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_modsel, + buf_p, + count); +} + + +static ssize_t +store_attr_hard_rs0(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_hard_rs0, + buf_p, + count); +} + + +static ssize_t +store_attr_hard_rs1(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_hard_rs1, + buf_p, + count); +} + + +/* ========== SWPS attribute: For module control ========== + */ +static DEVICE_ATTR(platform, S_IRUGO, show_attr_platform, NULL); +static DEVICE_ATTR(version, S_IRUGO, show_attr_version, NULL); +static DEVICE_ATTR(status, S_IRUGO, show_attr_status, NULL); +static DEVICE_ATTR(reset_i2c, S_IWUSR, NULL, store_attr_reset_i2c); +static DEVICE_ATTR(reset_swps, S_IWUSR, NULL, store_attr_reset_swps); +static DEVICE_ATTR(auto_config, S_IRUGO|S_IWUSR, show_attr_auto_config, store_attr_auto_config); +static DEVICE_ATTR(block_poll, S_IRUGO|S_IWUSR, show_attr_block_poll, store_attr_block_poll); +static DEVICE_ATTR(io_no_init, S_IRUGO|S_IWUSR, show_attr_io_no_init, store_attr_io_no_init); + + +/* ========== Transceiver attribute: from eeprom ========== + */ +static DEVICE_ATTR(id, S_IRUGO, show_attr_id, NULL); +static DEVICE_ATTR(ext_id, S_IRUGO, show_attr_ext_id, NULL); +static DEVICE_ATTR(connector, S_IRUGO, show_attr_connector, NULL); +static DEVICE_ATTR(vendor_name, S_IRUGO, show_attr_vendor_name, NULL); +static DEVICE_ATTR(vendor_pn, S_IRUGO, show_attr_vendor_pn, NULL); +static DEVICE_ATTR(vendor_rev, S_IRUGO, show_attr_vendor_rev, NULL); +static DEVICE_ATTR(vendor_sn, S_IRUGO, show_attr_vendor_sn, NULL); +static DEVICE_ATTR(power_cls, S_IRUGO, show_attr_power_cls, NULL); +static DEVICE_ATTR(br, S_IRUGO, show_attr_br, NULL); +static DEVICE_ATTR(len_sm, S_IRUGO, show_attr_len_sm, NULL); +static DEVICE_ATTR(len_smf, S_IRUGO, show_attr_len_smf, NULL); +static DEVICE_ATTR(len_om1, S_IRUGO, show_attr_len_om1, NULL); +static DEVICE_ATTR(len_om2, S_IRUGO, show_attr_len_om2, NULL); +static DEVICE_ATTR(len_om3, S_IRUGO, show_attr_len_om3, NULL); +static DEVICE_ATTR(len_om4, S_IRUGO, show_attr_len_om4, NULL); +static DEVICE_ATTR(comp_rev, S_IRUGO, show_attr_comp_rev, NULL); +static DEVICE_ATTR(comp_eth, S_IRUGO, show_attr_comp_eth, NULL); +static DEVICE_ATTR(comp_eth_10, S_IRUGO, show_attr_comp_eth_10, NULL); +static DEVICE_ATTR(comp_eth_10_40, S_IRUGO, show_attr_comp_eth_10_40, NULL); +static DEVICE_ATTR(comp_extend, S_IRUGO, show_attr_comp_extend, NULL); +static DEVICE_ATTR(rate_id, S_IRUGO, show_attr_rate_id, NULL); +static DEVICE_ATTR(temperature, S_IRUGO, show_attr_temperature, NULL); +static DEVICE_ATTR(voltage, S_IRUGO, show_attr_voltage, NULL); +static DEVICE_ATTR(tx_bias, S_IRUGO, show_attr_tx_bias, NULL); +static DEVICE_ATTR(tx_power, S_IRUGO, show_attr_tx_power, NULL); +static DEVICE_ATTR(rx_power, S_IRUGO, show_attr_rx_power, NULL); +static DEVICE_ATTR(info, S_IRUGO, show_attr_info, NULL); +static DEVICE_ATTR(if_type, S_IRUGO, show_attr_if_type, NULL); +static DEVICE_ATTR(if_speed, S_IRUGO, show_attr_if_speed, NULL); +static DEVICE_ATTR(if_lane, S_IRUGO, show_attr_if_lane, NULL); +static DEVICE_ATTR(soft_rx_los, S_IRUGO, show_attr_soft_rx_los, NULL); +static DEVICE_ATTR(soft_tx_fault, S_IRUGO, show_attr_soft_tx_fault, NULL); +static DEVICE_ATTR(wavelength, S_IRUGO, show_attr_wavelength, NULL); +static DEVICE_ATTR(tx_eq, S_IRUGO|S_IWUSR, show_attr_tx_eq, store_attr_tx_eq); +static DEVICE_ATTR(rx_am, S_IRUGO|S_IWUSR, show_attr_rx_am, store_attr_rx_am); +static DEVICE_ATTR(rx_em, S_IRUGO|S_IWUSR, show_attr_rx_em, store_attr_rx_em); +static DEVICE_ATTR(cdr, S_IRUGO|S_IWUSR, show_attr_cdr, store_attr_cdr); +static DEVICE_ATTR(soft_rs0, S_IRUGO|S_IWUSR, show_attr_soft_rs0, store_attr_soft_rs0); +static DEVICE_ATTR(soft_rs1, S_IRUGO|S_IWUSR, show_attr_soft_rs1, store_attr_soft_rs1); +static DEVICE_ATTR(soft_tx_disable, S_IRUGO|S_IWUSR, show_attr_soft_tx_disable, store_attr_soft_tx_disable); +static DEVICE_ATTR(auto_tx_disable, S_IRUGO|S_IWUSR, show_attr_auto_tx_disable, store_attr_auto_tx_disable); +static DEVICE_ATTR(extphy_offset, S_IRUGO|S_IWUSR, show_attr_extphy_offset, store_attr_extphy_offset); +static DEVICE_ATTR(extphy_reg, S_IRUGO|S_IWUSR, show_attr_extphy_reg, store_attr_extphy_reg); + +/* ========== IO Expander attribute: from expander ========== + */ +static DEVICE_ATTR(present, S_IRUGO, show_attr_present, NULL); +static DEVICE_ATTR(tx_fault, S_IRUGO, show_attr_tx_fault, NULL); +static DEVICE_ATTR(rxlos, S_IRUGO, show_attr_rxlos, NULL); +static DEVICE_ATTR(tx_disable, S_IRUGO|S_IWUSR, show_attr_tx_disable, store_attr_tx_disable); +static DEVICE_ATTR(reset, S_IRUGO|S_IWUSR, show_attr_reset, store_attr_reset); +static DEVICE_ATTR(lpmod, S_IRUGO|S_IWUSR, show_attr_lpmod, store_attr_lpmod); +static DEVICE_ATTR(modsel, S_IRUGO|S_IWUSR, show_attr_modsel, store_attr_modsel); +static DEVICE_ATTR(hard_rs0, S_IRUGO|S_IWUSR, show_attr_hard_rs0, store_attr_hard_rs0); +static DEVICE_ATTR(hard_rs1, S_IRUGO|S_IWUSR, show_attr_hard_rs1, store_attr_hard_rs1); + +/* ========== Functions for module handling ========== + */ +static void +clean_port_objs(void){ + + dev_t dev_num; + char dev_name[32]; + struct device *device_p; + struct transvr_obj_s *tobj_p; + int minor_curr, port_id; + + for (minor_curr=0; minor_curri2c_client_p) { + i2c_put_adapter(tobj_p->i2c_client_p->adapter); + kfree(tobj_p->i2c_client_p); + } + kfree(tobj_p->vendor_name); + kfree(tobj_p->vendor_pn); + kfree(tobj_p->vendor_rev); + kfree(tobj_p->vendor_sn); + kfree(tobj_p->worker_p); + kfree(tobj_p); + } + dev_num = MKDEV(port_major, minor_curr); + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); + } + SWPS_DEBUG("%s: done.\n", __func__); +} + + +static void +clean_swps_common(void){ + + dev_t dev_num; + struct device *device_p; + + device_p = get_swpdev_by_name(SWP_DEV_MODCTL); + if (device_p){ + dev_num = MKDEV(ctl_major, 1); + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); + } + cancel_delayed_work_sync(&swp_polling); + if (platform_p) { + kfree(platform_p); + } + SWPS_DEBUG("%s: done.\n", __func__); +} + + +static int +get_platform_type(void){ + + int i, tmp; + int auto_chan = -1; + int auto_addr = -1; + int pf_total = ARRAY_SIZE(platform_map); + char log_msg[64] = "ERROR"; + + platform_p = kzalloc(sizeof(struct inv_platform_s), GFP_KERNEL); + if (!platform_p){ + snprintf(log_msg, sizeof(log_msg), "kzalloc fail"); + goto err_get_platform_type_1; + } + memset(platform_p->name, 0, sizeof(platform_p->name)); + + switch (PLATFORM_SETTINGS) { + case PLATFORM_TYPE_AUTO: + snprintf(platform_p->name, (sizeof(platform_p->name) - 1), + "%s", dmi_get_system_info(DMI_BOARD_NAME)); + for (i=0; iname, platform_map[i].name) == 0) { + platform_p->id = platform_map[i].id; + snprintf(log_msg, sizeof(log_msg), + "Auto detect platform: %d (%s)", + platform_p->id, platform_p->name); + goto ok_get_platform_type_1; + } + } + snprintf(log_msg, sizeof(log_msg), + "Auto detect fail! detect platform: %s", + platform_p->name); + goto err_get_platform_type_2; + + case PLATFORM_TYPE_PEONY_AUTO: +#ifdef SWPS_PEONY_SFP + auto_chan = peony_sfp_ioexp_layout[0].addr[0].chan_id; + auto_addr = peony_sfp_ioexp_layout[0].addr[0].chip_addr; +#endif + tmp = _is_i2c_target_exist(auto_chan, auto_addr); + switch (tmp) { + case 0: /* Copper SKU */ + SWPS_INFO("Auto-detected :Peony :Copper\n"); + platform_p->id = PLATFORM_TYPE_PEONY_COPPER_GA; + goto map_platform_name; + + case 1: /* SFP SKU */ + SWPS_INFO("Auto-detected :Peony :SFP\n"); + platform_p->id = PLATFORM_TYPE_PEONY_SFP_GA; + goto map_platform_name; + + default: + break; + } + snprintf(log_msg, sizeof(log_msg), + "Auto detect Peony SKU fail! :%d", tmp); + goto err_get_platform_type_2; + + case PLATFORM_TYPE_MAGNOLIA: + case PLATFORM_TYPE_MAGNOLIA_FNC: + case PLATFORM_TYPE_REDWOOD: + case PLATFORM_TYPE_REDWOOD_FSL: + case PLATFORM_TYPE_HUDSON32I_GA: + case PLATFORM_TYPE_SPRUCE: + case PLATFORM_TYPE_CYPRESS_GA1: + case PLATFORM_TYPE_CYPRESS_GA2: + case PLATFORM_TYPE_CYPRESS_BAI: + case PLATFORM_TYPE_TAHOE: + case PLATFORM_TYPE_SEQUOIA_GA: + case PLATFORM_TYPE_LAVENDER_GA: + case PLATFORM_TYPE_LAVENDER_ONL: + case PLATFORM_TYPE_COTTONWOOD_RANGELEY: + case PLATFORM_TYPE_MAPLE_GA: + case PLATFORM_TYPE_MAPLE_B: + case PLATFORM_TYPE_MAPLE_J: + case PLATFORM_TYPE_GULMOHAR_GA: + case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA: + case PLATFORM_TYPE_PEONY_SFP_GA: + case PLATFORM_TYPE_PEONY_COPPER_GA: + case PLATFORM_TYPE_CEDAR_GA: + platform_p->id = PLATFORM_SETTINGS; + goto map_platform_name; + + default: + break; + } + snprintf(log_msg, sizeof(log_msg), + "PLATFORM_SETTINGS:%d undefined", PLATFORM_SETTINGS); + goto err_get_platform_type_2; + +map_platform_name: + for (i=0; iid == platform_map[i].id) { + snprintf(platform_p->name, (sizeof(platform_p->name) - 1), + "%s", platform_map[i].name); + snprintf(log_msg, sizeof(log_msg), + "User setup platform: %d (%s)", + platform_p->id, platform_p->name); + goto ok_get_platform_type_1; + } + } + snprintf(log_msg, sizeof(log_msg), + "Internal error, can not map id:%d", + platform_p->id ); + goto err_get_platform_type_2; + +ok_get_platform_type_1: + SWPS_DEBUG("%s: %s, :%d\n", __func__, log_msg, PLATFORM_SETTINGS); + return 0; + +err_get_platform_type_2: + kfree(platform_p); +err_get_platform_type_1: + SWPS_ERR("%s: %s :%d\n", __func__, log_msg, PLATFORM_SETTINGS); + return -1; +} + + +static int +get_layout_info(void){ + + switch (platform_p->id) { +#ifdef SWPS_MAGNOLIA + case PLATFORM_TYPE_MAGNOLIA: + case PLATFORM_TYPE_MAGNOLIA_FNC: + gpio_rest_mux = gpio_base + magnolia_gpio_rest_mux; + ioexp_layout = magnolia_ioexp_layout; + port_layout = magnolia_port_layout; + ioexp_total = ARRAY_SIZE(magnolia_ioexp_layout); + port_total = ARRAY_SIZE(magnolia_port_layout); + break; +#endif +#ifdef SWPS_REDWOOD + case PLATFORM_TYPE_REDWOOD: + gpio_rest_mux = gpio_base + redwood_gpio_rest_mux; + ioexp_layout = redwood_ioexp_layout; + port_layout = redwood_port_layout; + ioexp_total = ARRAY_SIZE(redwood_ioexp_layout); + port_total = ARRAY_SIZE(redwood_port_layout); + break; +#endif +#ifdef SWPS_HUDSON32I_GA + case PLATFORM_TYPE_HUDSON32I_GA: + gpio_rest_mux = gpio_base + hudsin32iga_gpio_rest_mux; + ioexp_layout = hudson32iga_ioexp_layout; + port_layout = hudson32iga_port_layout; + ioexp_total = ARRAY_SIZE(hudson32iga_ioexp_layout); + port_total = ARRAY_SIZE(hudson32iga_port_layout); + break; +#endif +#ifdef SWPS_SPRUCE + case PLATFORM_TYPE_SPRUCE: + gpio_rest_mux = gpio_base + spruce_gpio_rest_mux; + ioexp_layout = spruce_ioexp_layout; + port_layout = spruce_port_layout; + ioexp_total = ARRAY_SIZE(spruce_ioexp_layout); + port_total = ARRAY_SIZE(spruce_port_layout); + break; +#endif +#ifdef SWPS_CYPRESS_GA1 + case PLATFORM_TYPE_CYPRESS_GA1: + gpio_rest_mux = gpio_base + cypress_ga1_gpio_rest_mux; + ioexp_layout = cypress_ga1_ioexp_layout; + port_layout = cypress_ga1_port_layout; + ioexp_total = ARRAY_SIZE(cypress_ga1_ioexp_layout); + port_total = ARRAY_SIZE(cypress_ga1_port_layout); + break; +#endif +#ifdef SWPS_CYPRESS_GA2 + case PLATFORM_TYPE_CYPRESS_GA2: + gpio_rest_mux = gpio_base + cypress_ga2_gpio_rest_mux; + ioexp_layout = cypress_ga2_ioexp_layout; + port_layout = cypress_ga2_port_layout; + ioexp_total = ARRAY_SIZE(cypress_ga2_ioexp_layout); + port_total = ARRAY_SIZE(cypress_ga2_port_layout); + break; +#endif +#ifdef SWPS_CYPRESS_BAI + case PLATFORM_TYPE_CYPRESS_BAI: + gpio_rest_mux = gpio_base + cypress_b_gpio_rest_mux; + ioexp_layout = cypress_b_ioexp_layout; + port_layout = cypress_b_port_layout; + ioexp_total = ARRAY_SIZE(cypress_b_ioexp_layout); + port_total = ARRAY_SIZE(cypress_b_port_layout); + break; +#endif +#ifdef SWPS_REDWOOD_FSL + case PLATFORM_TYPE_REDWOOD_FSL: + gpio_rest_mux = gpio_base + redwood_fsl_gpio_rest_mux; + ioexp_layout = redwood_fsl_ioexp_layout; + port_layout = redwood_fsl_port_layout; + ioexp_total = ARRAY_SIZE(redwood_fsl_ioexp_layout); + port_total = ARRAY_SIZE(redwood_fsl_port_layout); + break; +#endif +#ifdef SWPS_TAHOE + case PLATFORM_TYPE_TAHOE: + gpio_rest_mux = gpio_base + tahoe_gpio_rest_mux; + ioexp_layout = tahoe_ioexp_layout; + port_layout = tahoe_port_layout; + ioexp_total = ARRAY_SIZE(tahoe_ioexp_layout); + port_total = ARRAY_SIZE(tahoe_port_layout); + break; +#endif +#ifdef SWPS_SEQUOIA + case PLATFORM_TYPE_SEQUOIA_GA: + gpio_rest_mux = gpio_base + sequoia_gpio_rest_mux; + ioexp_layout = sequoia_ioexp_layout; + port_layout = sequoia_port_layout; + ioexp_total = ARRAY_SIZE(sequoia_ioexp_layout); + port_total = ARRAY_SIZE(sequoia_port_layout); + break; +#endif +#ifdef SWPS_LAVENDER + case PLATFORM_TYPE_LAVENDER_GA: + case PLATFORM_TYPE_LAVENDER_ONL: + gpio_rest_mux = gpio_base + lavender_gpio_rest_mux; + ioexp_layout = lavender_ioexp_layout; + port_layout = lavender_port_layout; + ioexp_total = ARRAY_SIZE(lavender_ioexp_layout); + port_total = ARRAY_SIZE(lavender_port_layout); + break; +#endif +#ifdef SWPS_COTTONWOOD_RANGELEY + case PLATFORM_TYPE_COTTONWOOD_RANGELEY: + gpio_rest_mux = gpio_base + cottonwood_rangeley_gpio_rest_mux; + ioexp_layout = cottonwood_rangeley_ioexp_layout; + port_layout = cottonwood_rangeley_port_layout; + ioexp_total = ARRAY_SIZE(cottonwood_rangeley_ioexp_layout); + port_total = ARRAY_SIZE(cottonwood_rangeley_port_layout); + break; +#endif +#ifdef SWPS_MAPLE_GA + case PLATFORM_TYPE_MAPLE_GA: + gpio_rest_mux = gpio_base + maple_ga_gpio_rest_mux; + ioexp_layout = maple_ga_ioexp_layout; + port_layout = maple_ga_port_layout; + ioexp_total = ARRAY_SIZE(maple_ga_ioexp_layout); + port_total = ARRAY_SIZE(maple_ga_port_layout); + break; +#endif +#ifdef SWPS_MAPLE_B + case PLATFORM_TYPE_MAPLE_B: + gpio_rest_mux = gpio_base + maple_b_gpio_rest_mux; + ioexp_layout = maple_b_ioexp_layout; + port_layout = maple_b_port_layout; + ioexp_total = ARRAY_SIZE(maple_b_ioexp_layout); + port_total = ARRAY_SIZE(maple_b_port_layout); + break; +#endif +#ifdef SWPS_MAPLE_J + case PLATFORM_TYPE_MAPLE_J: + gpio_rest_mux = gpio_base + maple_j_gpio_rest_mux; + ioexp_layout = maple_j_ioexp_layout; + port_layout = maple_j_port_layout; + ioexp_total = ARRAY_SIZE(maple_j_ioexp_layout); + port_total = ARRAY_SIZE(maple_j_port_layout); + break; +#endif +#ifdef SWPS_GULMOHAR + case PLATFORM_TYPE_GULMOHAR_GA: + gpio_rest_mux = gpio_base + gulmohar_gpio_rest_mux; + ioexp_layout = gulmohar_ioexp_layout; + port_layout = gulmohar_port_layout; + ioexp_total = ARRAY_SIZE(gulmohar_ioexp_layout); + port_total = ARRAY_SIZE(gulmohar_port_layout); + break; +#endif +#ifdef SWPS_GULMOHAR_2T_EVT1 + case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA: + gpio_rest_mux = gpio_base + gulmohar_2t_evt1_gpio_rest_mux; + ioexp_layout = gulmohar_2t_evt1_ioexp_layout; + port_layout = gulmohar_2t_evt1_port_layout; + ioexp_total = ARRAY_SIZE(gulmohar_2t_evt1_ioexp_layout); + port_total = ARRAY_SIZE(gulmohar_2t_evt1_port_layout); + break; +#endif +#ifdef SWPS_PEONY_SFP + case PLATFORM_TYPE_PEONY_SFP_GA: + gpio_rest_mux = gpio_base + peony_sfp_gpio_rest_mux; + ioexp_layout = peony_sfp_ioexp_layout; + port_layout = peony_sfp_port_layout; + ioexp_total = ARRAY_SIZE(peony_sfp_ioexp_layout); + port_total = ARRAY_SIZE(peony_sfp_port_layout); + break; +#endif +#ifdef SWPS_PEONY_COPPER + case PLATFORM_TYPE_PEONY_COPPER_GA: + gpio_rest_mux = gpio_base + peony_copper_gpio_rest_mux; + ioexp_layout = peony_copper_ioexp_layout; + port_layout = peony_copper_port_layout; + ioexp_total = ARRAY_SIZE(peony_copper_ioexp_layout); + port_total = ARRAY_SIZE(peony_copper_port_layout); + break; +#endif +#ifdef SWPS_CEDAR_GA + case PLATFORM_TYPE_CEDAR_GA: + gpio_rest_mux = gpio_base + cedar_ga_gpio_rest_mux; + ioexp_layout = cedar_ga_ioexp_layout; + port_layout = cedar_ga_port_layout; + ioexp_total = ARRAY_SIZE(cedar_ga_ioexp_layout); + port_total = ARRAY_SIZE(cedar_ga_port_layout); + break; +#endif + + default: + SWPS_ERR(" Invalid platform: %d (%s)\n", + platform_p->id, platform_p->name); + return -1; + } + SWPS_INFO("Start to initial platform: %d (%s)\n", + platform_p->id, platform_p->name); + return 0; +} + + +/* ========== Functions for objects operations ========== + */ +static int +__detect_issues_port(int minor_num) { + + struct transvr_obj_s *tobj_p; + int port_id = port_layout[minor_num].port_id; + char port_name[32] = "ERR"; + char *i2c_emsg = "detected bad transceiver/cable"; + + memset(port_name, 0, sizeof(port_name)); + snprintf(port_name, sizeof(port_name), "%s%d", SWP_DEV_PORT, port_id); + tobj_p = _get_transvr_obj(port_name); + if (!tobj_p) { + SWPS_INFO("%s: tobj_p is NULL :%d\n", __func__, minor_num); + return -1; + } + if (resync_channel_tier_2(tobj_p) < 0) { + if (check_channel_tier_1() < 0) { + goto get_target_issues_port; + } + } + /* Re-check again for i2c-gpio special case */ + if (check_channel_tier_1() < 0) { + goto get_target_issues_port; + } + return 0; + +get_target_issues_port: + alarm_msg_2_user(tobj_p, i2c_emsg); + return -2; +} + + +static int +_detect_issues_port(void) { + /* OK : retrun -1; + * Fail: return fail at which minor number (0~N) + */ + char *emsg = "ERR"; + int minor = 0; + int minor_2st = 1; + + /* Force moving the initial channel pointer + * Filter out case of fail at minor-0 port + */ + while (minor_2st < port_total) { + minor = minor_2st; + if (__detect_issues_port(minor_2st) < 0) { + emsg = "detect minor_2st fail"; + goto err_p_detect_issues_port; + } + minor_2st += 8; + } + /* Scan all port */ + for (minor=0; minor:%d\n", __func__, emsg, minor_err); + return -1; +} + + +static int +check_transvr_obj_one(char *dev_name){ + /* [Return] + * 0 : Doesn't need to take care + * -1 : Single error + * -2 : Critical error (I2C topology die) + * -9 : Internal error + */ + struct transvr_obj_s *tobj_p = NULL; + int retval = -9; + + tobj_p = _get_transvr_obj(dev_name); + if (!tobj_p) { + SWPS_ERR("%s: %s _get_transvr_obj fail\n", + __func__, dev_name); + return -9; + } + /* Check transceiver current status */ + lock_transvr_obj(tobj_p); + retval = tobj_p->check(tobj_p); + unlock_transvr_obj(tobj_p); + switch (retval) { + case 0: + case ERR_TRANSVR_UNPLUGGED: + case ERR_TRNASVR_BE_ISOLATED: + case ERR_TRANSVR_TASK_BUSY: + return 0; + + case ERR_TRANSVR_I2C_CRASH: + default: + break; + } + /* Identify abnormal case */ + if (check_channel_tier_1() < 0) { + SWPS_DEBUG("%s: %s critical error :%d\n", + __func__, dev_name, retval); + return -2; + } + SWPS_DEBUG("%s: %s single error :%d\n", + __func__, dev_name, retval); + return -1; +} + + +static int +check_transvr_objs(void){ + + char dev_name[32]; + int port_id, err_code; + int minor_curr = 0; + + for (minor_curr=0; minor_curr:%d\n", + __func__, dev_name, err_code); + break; + } + } + return 0; + +err_check_transvr_objs: + SWPS_ERR("%s: %s reset_i2c_topology fail.\n", + __func__, dev_name); + return -1; +} + + +static void +swp_polling_worker(struct work_struct *work){ + + /* Reset I2C */ + if (flag_i2c_reset) { + goto polling_reset_i2c; + } + /* Check IOEXP */ + if (check_ioexp_objs() < 0) { + goto polling_reset_i2c; + } + /* Check transceiver */ + if (check_transvr_objs() < 0) { + SWPS_DEBUG("%s: check_transvr_objs fail.\n", __func__); + flag_i2c_reset = 1; + } + goto polling_schedule_round; + +polling_reset_i2c: + SWPS_DEBUG("%s: reset_i2c_topology start.\n", __func__); + if (reset_i2c_topology() < 0) { + SWPS_ERR("%s: reset i2c fail!\n", __func__); + flag_i2c_reset = 1; + } else { + SWPS_DEBUG("%s: reset_i2c_topology OK.\n", __func__); + flag_i2c_reset = 0; + } +polling_schedule_round: + schedule_delayed_work(&swp_polling, _get_polling_period()); +} + + +/* ========== Functions for register something ========== + */ +static int +register_transvr_common_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (device_create_file(device_p, &dev_attr_id) < 0) { + err_attr = "dev_attr_id"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_ext_id) < 0) { + err_attr = "dev_attr_ext_id"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_connector) < 0) { + err_attr = "dev_attr_connector"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_name) < 0) { + err_attr = "dev_attr_vendor_name"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_pn) < 0) { + err_attr = "dev_attr_vendor_pn"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_rev) < 0) { + err_attr = "dev_attr_vendor_rev"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_sn) < 0) { + err_attr = "dev_attr_vendor_sn"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_br) < 0) { + err_attr = "dev_attr_br"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_smf) < 0) { + err_attr = "dev_attr_len_smf"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om1) < 0) { + err_attr = "dev_attr_len_om1"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om2) < 0) { + err_attr = "dev_attr_len_om2"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om3) < 0) { + err_attr = "dev_attr_len_om3"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om4) < 0) { + err_attr = "dev_attr_len_om4"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_comp_extend) < 0) { + err_attr = "dev_attr_comp_extend"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_comp_eth) < 0) { + err_attr = "dev_attr_comp_eth"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_comp_rev) < 0) { + err_attr = "dev_attr_comp_rev"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_info) < 0) { + err_attr = "dev_attr_info"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_if_type) < 0) { + err_attr = "dev_attr_if_type"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_if_speed) < 0) { + err_attr = "dev_attr_if_speed"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_if_lane) < 0) { + err_attr = "dev_attr_if_lane"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_temperature) < 0) { + err_attr = "dev_attr_temperature"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_voltage) < 0) { + err_attr = "dev_attr_voltage"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_tx_bias) < 0) { + err_attr = "dev_attr_tx_bias"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_tx_power) < 0) { + err_attr = "dev_attr_tx_power"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_rx_power) < 0) { + err_attr = "dev_attr_rx_power"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_tx_eq) < 0) { + err_attr = "dev_attr_tx_eq"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_rx_em) < 0) { + err_attr = "dev_attr_rx_em"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_wavelength) < 0) { + err_attr = "dev_attr_wavelength"; + goto err_transvr_comm_attr; + } + return 0; + +err_transvr_comm_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + +static int +register_transvr_sfp_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (register_transvr_common_attr(device_p) < 0) { + err_attr = "register_transvr_common_attr"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_comp_eth_10) < 0) { + err_attr = "dev_attr_comp_eth_10"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_len_sm) < 0) { + err_attr = "dev_attr_len_sm"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_rate_id) < 0) { + err_attr = "dev_attr_rate_id"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_rs0) < 0) { + err_attr = "dev_attr_soft_rs0"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_rs1) < 0) { + err_attr = "dev_attr_soft_rs1"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_extphy_offset) < 0) { + err_attr = "dev_attr_extphy_offset"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_extphy_reg) < 0) { + err_attr = "dev_attr_extphy_reg"; + goto err_transvr_sfp_attr; + } + return 0; + +err_transvr_sfp_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + + +static int +register_transvr_qsfp_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (register_transvr_common_attr(device_p) < 0) { + err_attr = "register_transvr_common_attr"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_comp_eth_10_40) < 0) { + err_attr = "dev_attr_comp_eth_10_40"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_power_cls) < 0) { + err_attr = "dev_attr_power_cls"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_rx_los) < 0) { + err_attr = "soft_rx_los"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_tx_disable) < 0) { + err_attr = "soft_tx_disable"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_auto_tx_disable) < 0) { + err_attr = "auto_tx_disable"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_tx_fault) < 0) { + err_attr = "soft_tx_fault"; + goto err_transvr_qsfp_attr; + } + return 0; + +err_transvr_qsfp_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + + +static int +register_transvr_qsfp28_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (register_transvr_qsfp_attr(device_p) < 0){ + err_attr = "register_transvr_qsfp_attr"; + goto err_transvr_qsfp28_attr; + } + if (device_create_file(device_p, &dev_attr_cdr) < 0) { + err_attr = "dev_attr_cdr"; + goto err_transvr_qsfp28_attr; + } + if (device_create_file(device_p, &dev_attr_rx_am) < 0) { + err_attr = "dev_attr_rx_am"; + goto err_transvr_qsfp28_attr; + } + return 0; + +err_transvr_qsfp28_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + + +static int +register_transvr_attr(struct device *device_p, + struct transvr_obj_s *transvr_obj){ + + switch (transvr_obj->layout){ + case TRANSVR_TYPE_SFP: + if (register_transvr_sfp_attr(device_p) < 0){ + goto err_reg_tvr_attr; + } + break; + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + if (register_transvr_qsfp_attr(device_p) < 0){ + goto err_reg_tvr_attr; + } + break; + case TRANSVR_TYPE_QSFP_28: + if (register_transvr_qsfp28_attr(device_p) < 0){ + goto err_reg_tvr_attr; + } + break; + default: + goto err_reg_tvr_attr; + } + return 0; + +err_reg_tvr_attr: + SWPS_ERR("%s: fail! type=%d \n", __func__, transvr_obj->type); + return -1; +} + + +static int +register_ioexp_attr_sfp_1(struct device *device_p){ + /* Support machine type: + * - SFP : Magnolia + */ + char *err_attr = NULL; + + if (device_create_file(device_p, &dev_attr_present) < 0) { + err_attr = "dev_attr_present"; + goto err_ioexp_sfp1_attr; + } + if (device_create_file(device_p, &dev_attr_tx_fault) < 0) { + err_attr = "dev_attr_tx_fault"; + goto err_ioexp_sfp1_attr; + } + if (device_create_file(device_p, &dev_attr_rxlos) < 0) { + err_attr = "dev_attr_rxlos"; + goto err_ioexp_sfp1_attr; + } + if (device_create_file(device_p, &dev_attr_tx_disable) < 0) { + err_attr = "dev_attr_tx_disable"; + goto err_ioexp_sfp1_attr; + } + return 0; + +err_ioexp_sfp1_attr: + SWPS_ERR("Add device attribute:%s failure! \n",err_attr); + return -1; +} + + +static int +register_ioexp_attr_sfp_2(struct device *device_p){ + /* Support machine type: + * - SFP28 : Cypress + */ + char *err_attr = NULL; + + if (register_ioexp_attr_sfp_1(device_p) < 0){ + goto err_ioexp_sfp2_attr; + } + if (device_create_file(device_p, &dev_attr_hard_rs0) < 0) { + err_attr = "dev_attr_hard_rs0"; + goto err_ioexp_sfp2_attr; + } + if (device_create_file(device_p, &dev_attr_hard_rs1) < 0) { + err_attr = "dev_attr_hard_rs1"; + goto err_ioexp_sfp2_attr; + } + return 0; + +err_ioexp_sfp2_attr: + SWPS_ERR("Add device attribute:%s failure! \n",err_attr); + return -1; +} + + +static int +register_ioexp_attr_qsfp_1(struct device *device_p){ + /* Support machine type: + * - QSFP : Magnolia, Redwood, Hudson32i + * - QSFP+ : Magnolia, Redwood, Hudson32i + * - QSFP28: Redwood + */ + char *err_attr = NULL; + + if (device_create_file(device_p, &dev_attr_present) < 0) { + err_attr = "dev_attr_present"; + goto err_ioexp_qsfp1_attr; + } + if (device_create_file(device_p, &dev_attr_reset) < 0) { + err_attr = "dev_attr_reset"; + goto err_ioexp_qsfp1_attr; + } + if (device_create_file(device_p, &dev_attr_lpmod) < 0) { + err_attr = "dev_attr_lpmod"; + goto err_ioexp_qsfp1_attr; + } + if (device_create_file(device_p, &dev_attr_modsel) < 0) { + err_attr = "dev_attr_modsel"; + goto err_ioexp_qsfp1_attr; + } + return 0; + +err_ioexp_qsfp1_attr: + SWPS_ERR("Add device attribute:%s failure! \n",err_attr); + return -1; +} + + +static int +register_modctl_attr(struct device *device_p){ + + char *err_msg = NULL; + + if (device_create_file(device_p, &dev_attr_platform) < 0) { + err_msg = "dev_attr_platform"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_version) < 0) { + err_msg = "dev_attr_version"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_status) < 0) { + err_msg = "dev_attr_status"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_reset_i2c) < 0) { + err_msg = "dev_attr_reset_i2c"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_reset_swps) < 0) { + err_msg = "dev_attr_reset_swps"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_auto_config) < 0) { + err_msg = "dev_attr_auto_config"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_block_poll) < 0) { + err_msg = "dev_attr_block_poll"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_io_no_init) < 0) { + err_msg = "dev_attr_io_no_init"; + goto err_reg_modctl_attr; + } + + return 0; + +err_reg_modctl_attr: + SWPS_ERR("%s: %s\n", __func__, err_msg); + return -1; +} + + +static int +register_ioexp_attr(struct device *device_p, + struct transvr_obj_s *transvr_obj){ + + char *err_msg = "ERR"; + + switch (transvr_obj->ioexp_obj_p->ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + case IOEXP_TYPE_MAGINOLIA_4AB: + case CPLD_TYPE_COTTONWOOD: + if (register_ioexp_attr_sfp_1(device_p) < 0){ + err_msg = "register_ioexp_attr_sfp_1 fail"; + goto err_reg_ioexp_attr; + } + break; + + case IOEXP_TYPE_MAPLE_NABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + if (register_ioexp_attr_sfp_2(device_p) < 0){ + err_msg = "register_ioexp_attr_sfp_2 fail"; + goto err_reg_ioexp_attr; + } + break; + + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + case IOEXP_TYPE_CYPRESS_7ABC: + case IOEXP_TYPE_REDWOOD_P01P08: + case IOEXP_TYPE_REDWOOD_P09P16: + case IOEXP_TYPE_HUDSON32IGA_P01P08: + case IOEXP_TYPE_HUDSON32IGA_P09P16: + case IOEXP_TYPE_TAHOE_5A: + case IOEXP_TYPE_TAHOE_6ABC: + case IOEXP_TYPE_SEQUOIA_NABC: + case IOEXP_TYPE_LAVENDER_P65: + case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + case IOEXP_TYPE_CEDAR_0ABC: + if (register_ioexp_attr_qsfp_1(device_p) < 0){ + err_msg = "register_ioexp_attr_qsfp_1 fail"; + goto err_reg_ioexp_attr; + } + break; + + default: + err_msg = "Unknow type"; + goto err_reg_ioexp_attr; + } + return 0; + +err_reg_ioexp_attr: + SWPS_ERR("%s: %s :%d \n", + __func__, err_msg, transvr_obj->ioexp_obj_p->ioexp_type); + return -1; +} + + +static int +register_modctl_device(void) { + + struct device *device_p = NULL; + int minor_comm = 0; /* Default minor number for common device */ + dev_t dev_num = MKDEV(ctl_major, minor_comm); + char *err_msg = "ERROR"; + + device_p = device_create(swp_class_p, /* struct class *cls */ + NULL, /* struct device *parent */ + dev_num, /* dev_t devt */ + NULL, /* void *private_data */ + SWP_DEV_MODCTL); /* const char *fmt */ + if (IS_ERR(device_p)){ + err_msg = "device_create fail"; + goto err_register_modctl_device_1; + } + if (register_modctl_attr(device_p) < 0) { + err_msg = "register_modctl_attr fail"; + goto err_register_modctl_device_2; + } + return 0; + +err_register_modctl_device_2: + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); +err_register_modctl_device_1: + SWPS_ERR("%s: %s\n", __func__, err_msg); + return -1; +} + + +static int +register_port_device(char *dev_name, + dev_t dev_num, + struct transvr_obj_s *transvr_obj){ + + struct device *device_p = NULL; + device_p = device_create(swp_class_p, /* struct class *cls */ + NULL, /* struct device *parent */ + dev_num, /* dev_t devt */ + transvr_obj, /* void *private_data */ + dev_name); /* const char *fmt */ + if (IS_ERR(device_p)){ + goto err_regswp_create_dev; + } + if (register_transvr_attr(device_p, transvr_obj) < 0){ + goto err_regswp_reg_attr; + } + if (register_ioexp_attr(device_p, transvr_obj) < 0){ + goto err_regswp_reg_attr; + } + return 0; + +err_regswp_reg_attr: + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); +err_regswp_create_dev: + SWPS_ERR("%s fail! :%s\n", __func__, dev_name); + return -1; +} + + +static int +register_swp_module(void){ + + dev_t ctl_devt = 0; + dev_t port_devt = 0; + //int dev_total = port_total + 1; /* char_dev for module control */ + + /* Register device number */ + if (alloc_chrdev_region(&ctl_devt, 0, 1, SWP_DEV_MODCTL) < 0){ + SWPS_WARN("Allocate CTL MAJOR failure! \n"); + goto err_register_swp_module_1; + } + if (alloc_chrdev_region(&port_devt, 0, port_total, SWP_CLS_NAME) < 0){ + SWPS_WARN("Allocate PORT MAJOR failure! \n"); + goto err_register_swp_module_2; + } + ctl_major = MAJOR(ctl_devt); + port_major = MAJOR(port_devt); + + /* Create class object */ + swp_class_p = class_create(THIS_MODULE, SWP_CLS_NAME); + if (IS_ERR(swp_class_p)) { + SWPS_ERR("Create class failure! \n"); + goto err_register_swp_module_3; + } + return 0; + +err_register_swp_module_3: + unregister_chrdev_region(MKDEV(port_major, 0), port_total); +err_register_swp_module_2: + unregister_chrdev_region(MKDEV(ctl_major, 0), 1); +err_register_swp_module_1: + return -1; +} + + +/* ========== Module initial relate ========== + */ +static int +create_ioexp_objs(void) { + + int i, run_mod; + + /* Clean IOEXP object */ + clean_ioexp_objs(); + /* Get running mode */ + run_mod = IOEXP_MODE_DIRECT; + if (SWP_POLLING_ENABLE){ + run_mod = IOEXP_MODE_POLLING; + } + /* Create IOEXP object */ + for(i=0; i devlen_max) { + snprintf(err_msg, sizeof(err_msg), + "SWP_DEV_PORT too long!"); + goto err_initport_create_tranobj; + } + memset(dev_name, 0, sizeof(dev_name)); + snprintf(dev_name, devlen_max, "%s%d", SWP_DEV_PORT, port_id); + /* Create transceiver object */ + ioexp_obj_p = get_ioexp_obj(ioexp_id); + if (!ioexp_obj_p){ + snprintf(err_msg, sizeof(err_msg), + "IOEXP object:%d not exist", ioexp_id); + goto err_initport_create_tranobj; + } + transvr_obj_p = create_transvr_obj(dev_name, chan_id, ioexp_obj_p, + ioexp_virt_offset, transvr_type, + chipset_type, run_mod); + if (!transvr_obj_p){ + snprintf(err_msg, sizeof(err_msg), + "Create transceiver object fail :%s", dev_name); + goto err_initport_create_tranobj; + } + /* Setup Lane_ID mapping */ + i = ARRAY_SIZE(port_layout[minor_curr].lane_id); + j = ARRAY_SIZE(transvr_obj_p->lane_id); + if (i != j) { + snprintf(err_msg, sizeof(err_msg), + "Lane_id size inconsistent %d/%d", i, j); + goto err_initport_reg_device; + } + memcpy(transvr_obj_p->lane_id, port_layout[minor_curr].lane_id, i*sizeof(int)); + /* Create and register device object */ + if (register_port_device(dev_name, MKDEV(port_major, minor_curr), transvr_obj_p) < 0){ + snprintf(err_msg, sizeof(err_msg), + "register_port_device fail"); + goto err_initport_reg_device; + } + /* Setup device_ptr of transvr_obj */ + dev_p = get_swpdev_by_name(dev_name); + if (!dev_p){ + snprintf(err_msg, sizeof(err_msg), + "get_swpdev_by_name fail"); + goto err_initport_reg_device; + } + transvr_obj_p->transvr_dev_p = dev_p; + /* Success */ + ok_count++; + } + SWPS_INFO("%s: initialed %d port-dev\n",__func__, ok_count); + return 0; + +err_initport_reg_device: + kfree(transvr_obj_p); +err_initport_create_tranobj: + clean_port_objs(); + SWPS_ERR("%s: %s", __func__, err_msg); + SWPS_ERR("Dump: :%d :%d :%d :%d :%d :%d\n", + port_id, chan_id, ioexp_id, ioexp_virt_offset, transvr_type, run_mod); + return -1; +} + + +static int +init_dev_topology(void){ + + int err; + char *emsg = "ERR"; + flag_mod_state = SWP_STATE_NORMAL; + + err = init_ioexp_objs(); + switch(err){ + case 0: /* Normal */ + SWPS_DEBUG("%s: normal case\n", __func__); + break; + + case -1: /* topology error */ + SWPS_DEBUG("%s: detect tier-1 topology initial failure :%d\n", + __func__, err); + /* Reset and isolate */ + err = reset_i2c_topology(); + if (err < 0) { + emsg = "reset i2c topology fail"; + goto err_init_dev_topology; + } + /* Re-initial again */ + err = init_ioexp_objs(); + if (err < 0) { + emsg = "re-init ioexp objects fail"; + goto err_init_dev_topology; + } + break; + + case -2: /* Internal error */ + SWPS_DEBUG("%s: internal error case\n", __func__); + err = -2; + emsg = "internal error"; + goto err_init_dev_topology; + + default: + SWPS_DEBUG("%s: undefined error case\n", __func__); + emsg = "undefined error case"; + goto err_init_dev_topology; + } + SWPS_DEBUG("%s: initial I2C topology success\n", __func__); + return 0; + +err_init_dev_topology: + SWPS_ERR("%s: %s :%d\n", __func__, emsg, err); + return -1; +} + + +static int +init_polling_task(void){ + + if (SWP_POLLING_ENABLE){ + schedule_delayed_work(&swp_polling, _get_polling_period()); + } + return 0; +} + + +static int +init_swps_common(void){ + + char *err_msg = "ERR"; + + block_polling = 0; + auto_config = 0; + if ((SWP_AUTOCONFIG_ENABLE) && (SWP_POLLING_ENABLE)){ + auto_config = 1; + } + if (register_modctl_device() < 0) { + err_msg = "register_modctl_device fail"; + goto err_init_swps_common_1; + } + if (_update_auto_config_2_trnasvr() < 0) { + err_msg = "_update_auto_config_2_trnasvr fail"; + goto err_init_swps_common_1; + } + if (init_polling_task() < 0){ + err_msg = "init_polling_task fail"; + goto err_init_swps_common_1; + } + return 0; + +err_init_swps_common_1: + clean_swps_common(); + SWPS_ERR("%s: %s\n", __func__, err_msg); + return -1; +} + + +static int __init +swp_module_init(void){ + + if (get_platform_type() < 0){ + goto err_init_out; + } + if (get_layout_info() < 0){ + goto err_init_out; + } + if (register_swp_module() < 0){ + goto err_init_out; + } + if (create_ioexp_objs() < 0){ + goto err_init_ioexp; + } + if (create_port_objs() < 0){ + goto err_init_portobj; + } + if (init_mux_objs(gpio_rest_mux) < 0){ + goto err_init_mux; + } + if (init_dev_topology() < 0){ + goto err_init_topology; + } + if (init_swps_common() < 0){ + goto err_init_topology; + } + SWPS_INFO("Inventec switch-port module V.%s initial success.\n", SWP_VERSION); + return 0; + + +err_init_topology: + clean_mux_objs(); +err_init_mux: + clean_port_objs(); +err_init_portobj: + clean_ioexp_objs(); +err_init_ioexp: + class_destroy(swp_class_p); + unregister_chrdev_region(MKDEV(ctl_major, 0), 1); + unregister_chrdev_region(MKDEV(port_major, 0), port_total); +err_init_out: + SWPS_ERR("Inventec switch-port module V.%s initial failure.\n", SWP_VERSION); + return -1; +} + + +static void __exit +swp_module_exit(void){ + + clean_swps_common(); + clean_port_objs(); + clean_ioexp_objs(); + clean_mux_objs(); + class_destroy(swp_class_p); + unregister_chrdev_region(MKDEV(ctl_major, 0), 1); + unregister_chrdev_region(MKDEV(port_major, 0), port_total); + SWPS_INFO("Remove Inventec switch-port module success.\n"); +} + + +/* Module information */ +MODULE_AUTHOR(SWP_AUTHOR); +MODULE_DESCRIPTION(SWP_DESC); +MODULE_VERSION(SWP_VERSION); +MODULE_LICENSE(SWP_LICENSE); +MODULE_SOFTDEP("pre: inv_platform"); +module_param(gpio_base, int, S_IRUGO); + +module_init(swp_module_init); +module_exit(swp_module_exit); + + + + + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_swps.h b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_swps.h new file mode 100644 index 000000000000..00dc1fde0d8e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_swps.h @@ -0,0 +1,1791 @@ +#ifndef INV_SWPS_H +#define INV_SWPS_H + +#include "transceiver.h" +#include "io_expander.h" +#include "inv_mux.h" + +/* Module settings */ +#define SWP_CLS_NAME "swps" +#define SWP_DEV_PORT "port" +#define SWP_DEV_MODCTL "module" +#define SWP_RESET_PWD "inventec" +#define SWP_POLLING_PERIOD (300) /* msec */ +#define SWP_POLLING_ENABLE (1) +#define SWP_AUTOCONFIG_ENABLE (1) + +/* Module information */ +#define SWP_AUTHOR "Neil " +#define SWP_DESC "Inventec port and transceiver driver" +#define SWP_VERSION "4.3.10" +#define SWP_LICENSE "GPL" + +/* Module status define */ +#define SWP_STATE_NORMAL (0) +#define SWP_STATE_I2C_DIE (-91) + +/* [Note]: + * Functions and mechanism for auto-detect platform type is ready, + * But HW and BIOS not ready! We need to wait them. + * So, please do not use PLATFORM_TYPE_AUTO until they are ready. + * (2016.06.13) + */ +#define PLATFORM_TYPE_AUTO (100) +#define PLATFORM_TYPE_MAGNOLIA (111) +#define PLATFORM_TYPE_MAGNOLIA_FNC (112) +#define PLATFORM_TYPE_REDWOOD (121) +#define PLATFORM_TYPE_REDWOOD_FSL (122) +#define PLATFORM_TYPE_HUDSON32I_GA (131) +#define PLATFORM_TYPE_SPRUCE (141) +#define PLATFORM_TYPE_CYPRESS_GA1 (151) /* Up -> Down */ +#define PLATFORM_TYPE_CYPRESS_GA2 (152) /* Down -> Up */ +#define PLATFORM_TYPE_CYPRESS_BAI (153) /* Down -> Up */ +#define PLATFORM_TYPE_TAHOE (161) +#define PLATFORM_TYPE_SEQUOIA_GA (171) +#define PLATFORM_TYPE_LAVENDER_GA (181) +#define PLATFORM_TYPE_LAVENDER_ONL (182) +#define PLATFORM_TYPE_COTTONWOOD_RANGELEY (191) +#define PLATFORM_TYPE_MAPLE_GA (201) +#define PLATFORM_TYPE_GULMOHAR_GA (202) +#define PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA (203) +#define PLATFORM_TYPE_PEONY_SFP_GA (204) +#define PLATFORM_TYPE_PEONY_COPPER_GA (205) +#define PLATFORM_TYPE_PEONY_AUTO (206) +#define PLATFORM_TYPE_MAPLE_B (207) +#define PLATFORM_TYPE_MAPLE_J (208) +#define PLATFORM_TYPE_CEDAR_GA (209) +/* Current running platfrom */ +#define PLATFORM_SETTINGS PLATFORM_TYPE_CEDAR_GA + +/* Define platform flag and kernel version */ +#if (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA) + #define SWPS_MAGNOLIA (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA_FNC) + #define SWPS_MAGNOLIA (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_REDWOOD) + #define SWPS_REDWOOD (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_REDWOOD_FSL) + #define SWPS_REDWOOD_FSL (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_HUDSON32I_GA) + #define SWPS_HUDSON32I_GA (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_SPRUCE) + #define SWPS_SPRUCE (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_GA1) + #define SWPS_CYPRESS_GA1 (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_GA2) + #define SWPS_CYPRESS_GA2 (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_BAI) + #define SWPS_CYPRESS_BAI (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_TAHOE) + #define SWPS_TAHOE (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_SEQUOIA_GA) + #define SWPS_SEQUOIA (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_GA) + #define SWPS_LAVENDER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_ONL) + #define SWPS_LAVENDER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_COTTONWOOD_RANGELEY) + #define SWPS_COTTONWOOD_RANGELEY (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_GA) + #define SWPS_MAPLE_GA (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_B) + #define SWPS_MAPLE_B (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_J) + #define SWPS_MAPLE_J (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_GA) + #define SWPS_GULMOHAR (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA) + #define SWPS_GULMOHAR_2T_EVT1 (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_SFP_GA) + #define SWPS_PEONY_SFP (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_COPPER_GA) + #define SWPS_PEONY_COPPER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_AUTO) + #define SWPS_PEONY_SFP (1) + #define SWPS_PEONY_COPPER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CEDAR_GA) + #define SWPS_CEDAR_GA (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#endif + +struct inv_platform_s { + int id; + char name[64]; +}; + +struct inv_ioexp_layout_s { + int ioexp_id; + int ioexp_type; + struct ioexp_addr_s addr[4]; +}; + +struct inv_port_layout_s { + int port_id; + int chan_id; + int ioexp_id; + int ioexp_offset; + int transvr_type; + int chipset_type; + int lane_id[8]; +}; + + +/* ========================================== + * Inventec Platform Settings + * ========================================== + */ +struct inv_platform_s platform_map[] = { + {PLATFORM_TYPE_AUTO, "Auto-Detect" }, + {PLATFORM_TYPE_MAGNOLIA, "Magnolia" }, + {PLATFORM_TYPE_MAGNOLIA_FNC, "Magnolia_FNC" }, + {PLATFORM_TYPE_REDWOOD, "Redwood" }, + {PLATFORM_TYPE_REDWOOD_FSL, "Redwood_FSL" }, + {PLATFORM_TYPE_HUDSON32I_GA, "Hudson32i" }, + {PLATFORM_TYPE_SPRUCE, "Spruce" }, + {PLATFORM_TYPE_CYPRESS_GA1, "Cypress_GA1" }, + {PLATFORM_TYPE_CYPRESS_GA2, "Cypress_GA2" }, + {PLATFORM_TYPE_CYPRESS_BAI, "Cypress_BAI" }, + {PLATFORM_TYPE_TAHOE, "Tahoe" }, + {PLATFORM_TYPE_SEQUOIA_GA, "Sequoia_GA" }, + {PLATFORM_TYPE_LAVENDER_GA, "Lavender_GA" }, + {PLATFORM_TYPE_LAVENDER_ONL, "Lavender_ONL" }, + {PLATFORM_TYPE_COTTONWOOD_RANGELEY, "Cottonwood_RANGELEY" }, + {PLATFORM_TYPE_MAPLE_GA, "Maple_GA" }, + {PLATFORM_TYPE_MAPLE_B, "Maple_B" }, + {PLATFORM_TYPE_MAPLE_J, "Maple_J" }, + {PLATFORM_TYPE_GULMOHAR_GA, "Gulmohar_GA" }, + {PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA, "Gulmohar_2T_EVT1_GA" }, + {PLATFORM_TYPE_PEONY_SFP_GA, "Peony_SFP_GA" }, + {PLATFORM_TYPE_PEONY_COPPER_GA, "Peony_Copper_GA" }, + {PLATFORM_TYPE_PEONY_AUTO, "Peony_Auto_Detect" }, + {PLATFORM_TYPE_CEDAR_GA, "Cedar_GA" }, +}; + + +/* ========================================== + * Magnolia Layout configuration + * ========================================== + */ +#ifdef SWPS_MAGNOLIA +unsigned magnolia_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s magnolia_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAGINOLIA_NAB, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {1, IOEXP_TYPE_MAGINOLIA_NAB, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {2, IOEXP_TYPE_MAGINOLIA_NAB, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {3, IOEXP_TYPE_MAGINOLIA_4AB, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander 4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf0, 0xff}, {0xf0, 0xff}, }, }, /* addr[1] = I/O Expander 4 B */ + }, + {4, IOEXP_TYPE_MAGINOLIA_NAB, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {5, IOEXP_TYPE_MAGINOLIA_NAB, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {6, IOEXP_TYPE_MAGINOLIA_7AB, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xf0, 0x33}, }, }, /* addr[1] = I/O Expander 7 B */ + }, +}; + +struct inv_port_layout_s magnolia_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 16} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 15} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 14} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 13} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 24} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 23} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 22} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 21} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 28} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 27} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 26} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 25} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 32} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 31} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 30} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 29} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 48} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 47} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 46} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 45} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 52} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 51} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 50} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 49} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 56} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 55} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 54} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 53} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 60} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 59} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 58} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 57} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 64} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 63} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 62} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 61} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 68} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 67} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 66} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 65} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 72} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 71} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 70} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 69} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 76} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 75} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 74} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 73} }, + {48, 58, 6, 0, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, { 81, 82, 83, 84} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, { 77, 78, 79, 80} }, + {50, 60, 6, 2, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, { 97, 98, 99,100} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, {101,102,103,104} }, + {52, 62, 6, 4, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, {105,106,107,108} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Redwood Layout configuration + * ========================================== + */ +#ifdef SWPS_REDWOOD +unsigned redwood_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s redwood_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_REDWOOD_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {1, IOEXP_TYPE_REDWOOD_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {2, IOEXP_TYPE_REDWOOD_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {3, IOEXP_TYPE_REDWOOD_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, +}; + +struct inv_port_layout_s redwood_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 22, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 1, 2, 3, 4} }, + { 1, 23, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 5, 6, 7, 8} }, + { 2, 24, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 9, 10, 11, 12} }, + { 3, 25, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 13, 14, 15, 16} }, + { 4, 26, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 17, 18, 19, 20} }, + { 5, 27, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 21, 22, 23, 24} }, + { 6, 28, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 25, 26, 27, 28} }, + { 7, 29, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 29, 30, 31, 32} }, + { 8, 30, 1, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 33, 34, 35, 36} }, + { 9, 31, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 37, 38, 39, 40} }, + {10, 32, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 41, 42, 43, 44} }, + {11, 33, 1, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 45, 46, 47, 48} }, + {12, 34, 1, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 49, 50, 51, 52} }, + {13, 35, 1, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 53, 54, 55, 56} }, + {14, 36, 1, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 57, 58, 59, 60} }, + {15, 37, 1, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 61, 62, 63, 64} }, + {16, 6, 2, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 65, 66, 67, 68} }, + {17, 7, 2, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 69, 70, 71, 72} }, + {18, 8, 2, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 73, 74, 75, 76} }, + {19, 9, 2, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 77, 78, 79, 80} }, + {20, 10, 2, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 81, 82, 83, 84} }, + {21, 11, 2, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {22, 12, 2, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 89, 90, 91, 92} }, + {23, 13, 2, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 93, 94, 95, 96} }, + {24, 14, 3, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99,100} }, + {25, 15, 3, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101,102,103,104} }, + {26, 16, 3, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105,106,107,108} }, + {27, 17, 3, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109,110,111,112} }, + {28, 18, 3, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {113,114,115,116} }, + {29, 19, 3, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117,118,119,120} }, + {30, 20, 3, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {121,122,123,124} }, + {31, 21, 3, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {125,126,127,128} }, +}; +#endif + + +/* ========================================== + * Hudson32i Layout configuration + * ========================================== + */ +#ifdef SWPS_HUDSON32I_GA +unsigned hudsin32iga_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s hudson32iga_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_HUDSON32IGA_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x24 */ + }, + {1, IOEXP_TYPE_HUDSON32IGA_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x24 */ + }, + {2, IOEXP_TYPE_HUDSON32IGA_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x25 */ + }, + {3, IOEXP_TYPE_HUDSON32IGA_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x25 */ + }, +}; + +struct inv_port_layout_s hudson32iga_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 6, 0, 0, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 1, 2, 3, 4} }, + { 1, 7, 0, 1, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 5, 6, 7, 8} }, + { 2, 8, 0, 2, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 9, 10, 11, 12} }, + { 3, 9, 0, 3, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 13, 14, 15, 16} }, + { 4, 10, 0, 4, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 17, 18, 19, 20} }, + { 5, 11, 0, 5, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 21, 22, 23, 24} }, + { 6, 12, 0, 6, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 25, 26, 27, 28} }, + { 7, 13, 0, 7, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 29, 30, 31, 32} }, + { 8, 14, 1, 0, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 33, 34, 35, 36} }, + { 9, 15, 1, 1, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 37, 38, 39, 40} }, + {10, 16, 1, 2, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 41, 42, 43, 44} }, + {11, 17, 1, 3, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 45, 46, 47, 48} }, + {12, 18, 1, 4, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 49, 50, 51, 52} }, + {13, 19, 1, 5, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 53, 54, 55, 56} }, + {14, 20, 1, 6, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 57, 58, 59, 60} }, + {15, 21, 1, 7, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 61, 62, 63, 64} }, + {16, 22, 2, 0, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 65, 66, 67, 68} }, + {17, 23, 2, 1, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 69, 70, 71, 72} }, + {18, 24, 2, 2, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 73, 74, 75, 76} }, + {19, 25, 2, 3, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 77, 78, 79, 80} }, + {20, 26, 2, 4, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 81, 82, 83, 84} }, + {21, 27, 2, 5, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 85, 86, 87, 88} }, + {22, 28, 2, 6, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 89, 90, 91, 92} }, + {23, 29, 2, 7, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 93, 94, 95, 96} }, + {24, 30, 3, 0, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 97, 98, 99,100} }, + {25, 31, 3, 1, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {101,102,103,104} }, + {26, 32, 3, 2, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {105,106,107,108} }, + {27, 33, 3, 3, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {109,110,111,112} }, + {28, 34, 3, 4, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {113,114,115,116} }, + {29, 35, 3, 5, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {117,118,119,120} }, + {30, 36, 3, 6, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {121,122,123,124} }, + {31, 37, 3, 7, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {125,126,127,128} }, +}; +#endif + + +/* ========================================== + * Spruce Layout configuration + * ========================================== + */ +#ifdef SWPS_SPRUCE +unsigned spruce_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s spruce_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SPRUCE_7AB, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 7A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xf0, 0x33}, }, }, /* addr[2] = I/O Expander 7B */ + }, +}; + +struct inv_port_layout_s spruce_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 6, 0, 0, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 81, 82, 83, 84} }, + { 1, 7, 0, 1, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 77, 78, 79, 80} }, + { 2, 8, 0, 2, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 97, 98, 99,100} }, + { 3, 9, 0, 3, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {101,102,103,104} }, + { 4, 10, 0, 4, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {105,106,107,108} }, + { 5, 11, 0, 5, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Cypress Layout configuration (Inventec version [Up->Down]) + * ========================================== + */ +#ifdef SWPS_CYPRESS_GA1 +unsigned cypress_ga1_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s cypress_ga1_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + +struct inv_port_layout_s cypress_ga1_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 1} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 2} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 3} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 4} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 5} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 6} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 7} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 8} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 9} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 10} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 11} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 12} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 21} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 22} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 23} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 24} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 33} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 34} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 35} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 36} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 37} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 38} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 39} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 40} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 41} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 42} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 43} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 44} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 49} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 50} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 51} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 52} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 53} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 54} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 55} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 56} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 65} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 66} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 67} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 68} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 69} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 70} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 71} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 72} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 81} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 82} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 83} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 84} }, + {48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99,100} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101,102,103,104} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105,106,107,108} }, + {52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109,110,111,112} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117,118,119,120} }, +}; +#endif + + +/* ========================================== + * Cypress Layout configuration (Inventec version [Down->Up]) + * ========================================== + */ +#ifdef SWPS_CYPRESS_GA2 +unsigned cypress_ga2_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA; + +struct inv_ioexp_layout_s cypress_ga2_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + +struct inv_port_layout_s cypress_ga2_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 2} }, + { 1, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 1} }, + { 2, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 4} }, + { 3, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 3} }, + { 4, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 6} }, + { 5, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 5} }, + { 6, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 8} }, + { 7, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 7} }, + { 8, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 10} }, + { 9, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 9} }, + {10, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 12} }, + {11, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 11} }, + {12, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 22} }, + {13, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 21} }, + {14, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 24} }, + {15, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 23} }, + {16, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 34} }, + {17, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 33} }, + {18, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 36} }, + {19, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 35} }, + {20, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 38} }, + {21, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 37} }, + {22, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 40} }, + {23, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 39} }, + {24, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 42} }, + {25, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 41} }, + {26, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 44} }, + {27, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 43} }, + {28, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 50} }, + {29, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 49} }, + {30, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 52} }, + {31, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 51} }, + {32, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 54} }, + {33, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 53} }, + {34, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 56} }, + {35, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 55} }, + {36, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 66} }, + {37, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 65} }, + {38, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 68} }, + {39, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 67} }, + {40, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 70} }, + {41, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 69} }, + {42, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 72} }, + {43, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 71} }, + {44, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 82} }, + {45, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 81} }, + {46, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 84} }, + {47, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 83} }, + {48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99,100} }, + {50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105,106,107,108} }, + {51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101,102,103,104} }, + {52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117,118,119,120} }, + {53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Cypress Layout configuration (C1 version) + * ========================================== + */ +#ifdef SWPS_CYPRESS_BAI +unsigned cypress_b_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA; + +struct inv_ioexp_layout_s cypress_b_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + +struct inv_port_layout_s cypress_b_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 2} }, + { 2, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 1} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 4} }, + { 4, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 3} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 6} }, + { 6, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 5} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 8} }, + { 8, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 7} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 10} }, + {10, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 9} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 12} }, + {12, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 11} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 22} }, + {14, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 21} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 24} }, + {16, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 23} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 34} }, + {18, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 33} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 36} }, + {20, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 35} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 38} }, + {22, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 37} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 40} }, + {24, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 39} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 42} }, + {26, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 41} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 44} }, + {28, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 43} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 50} }, + {30, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 49} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 52} }, + {32, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 51} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 54} }, + {34, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 53} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 56} }, + {36, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 55} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 66} }, + {38, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 65} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 68} }, + {40, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 67} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 70} }, + {42, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 69} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 72} }, + {44, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 71} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 82} }, + {46, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 81} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 84} }, + {48, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 83} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {50, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99,100} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105,106,107,108} }, + {52, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101,102,103,104} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117,118,119,120} }, + {54, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Redwood_fsl Layout configuration + * ========================================== + */ +#ifdef SWPS_REDWOOD_FSL +unsigned redwood_fsl_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s redwood_fsl_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_REDWOOD_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {1, IOEXP_TYPE_REDWOOD_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {2, IOEXP_TYPE_REDWOOD_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {3, IOEXP_TYPE_REDWOOD_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, +}; + + +struct inv_port_layout_s redwood_fsl_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 22, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 1, 2, 3, 4} }, + { 1, 23, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 5, 6, 7, 8} }, + { 2, 24, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 9, 10, 11, 12} }, + { 3, 25, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 13, 14, 15, 16} }, + { 4, 26, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 17, 18, 19, 20} }, + { 5, 27, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 21, 22, 23, 24} }, + { 6, 28, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 25, 26, 27, 28} }, + { 7, 29, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 29, 30, 31, 32} }, + { 8, 30, 1, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 33, 34, 35, 36} }, + { 9, 31, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 37, 38, 39, 40} }, + {10, 32, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 41, 42, 43, 44} }, + {11, 33, 1, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 45, 46, 47, 48} }, + {12, 34, 1, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 49, 50, 51, 52} }, + {13, 35, 1, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 53, 54, 55, 56} }, + {14, 36, 1, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 57, 58, 59, 60} }, + {15, 37, 1, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 61, 62, 63, 64} }, + {16, 6, 2, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 65, 66, 67, 68} }, + {17, 7, 2, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 69, 70, 71, 72} }, + {18, 8, 2, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 73, 74, 75, 76} }, + {19, 9, 2, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 77, 78, 79, 80} }, + {20, 10, 2, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 81, 82, 83, 84} }, + {21, 11, 2, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {22, 12, 2, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 89, 90, 91, 92} }, + {23, 13, 2, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 93, 94, 95, 96} }, + {24, 14, 3, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99,100} }, + {25, 15, 3, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101,102,103,104} }, + {26, 16, 3, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105,106,107,108} }, + {27, 17, 3, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109,110,111,112} }, + {28, 18, 3, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {113,114,115,116} }, + {29, 19, 3, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117,118,119,120} }, + {30, 20, 3, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {121,122,123,124} }, + {31, 21, 3, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {125,126,127,128} }, +}; +#endif + + +/* ========================================== + * Tahoe Layout configuration + * ========================================== + */ +#ifdef SWPS_TAHOE +unsigned tahoe_gpio_rest_mux = MUX_RST_GPIO_249_PCA9548; + +struct inv_ioexp_layout_s tahoe_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_TAHOE_6ABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, /* addr[0] = I/O Expander 6 A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, /* addr[1] = I/O Expander 6 B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, }, /* addr[2] = I/O Expander 6 C */ + }, + {1, IOEXP_TYPE_TAHOE_5A, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, }, /* addr[0] = I/O Expander 5 A */ + }, +}; + + +struct inv_port_layout_s tahoe_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 12, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 65, 66, 67, 68} }, + { 1, 11, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 53, 54, 55, 56} }, + { 2, 22, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 69, 70, 71, 72} }, + { 3, 21, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 81, 82, 83, 84} }, + { 4, 24, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99, 100} }, + { 5, 23, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + { 6, 18, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101, 102, 103, 104} }, + { 7, 17, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105, 106, 107, 108} }, + { 8, 20, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {113, 114, 115, 116} }, + { 9, 19, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109, 110, 111, 112} }, +}; +#endif + + +/* ========================================== + * Sequoia Layout configuration + * ========================================== + */ +#ifdef SWPS_SEQUOIA +unsigned sequoia_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s sequoia_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SEQUOIA_NABC, { {1, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + {1, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {1, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_SEQUOIA_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 1 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 1 B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 1 C */ + }, + {2, IOEXP_TYPE_SEQUOIA_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 2 A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 2 B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 2 C */ + }, + {3, IOEXP_TYPE_SEQUOIA_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 3 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 3 B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 3 C */ + }, + {4, IOEXP_TYPE_SEQUOIA_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 4 B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 4 C */ + }, + {5, IOEXP_TYPE_SEQUOIA_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 5 A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 5 B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 C */ + }, + {6, IOEXP_TYPE_SEQUOIA_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 6 A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 6 B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 6 C */ + }, + {7, IOEXP_TYPE_SEQUOIA_NABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + + +struct inv_port_layout_s sequoia_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 9, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 9, 10, 11, 12} }, + { 1, 10, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 1, 2, 3, 4} }, + { 2, 11, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 25, 26, 27, 28} }, + { 3, 12, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 17, 18, 19, 20} }, + { 4, 13, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 41, 42, 43, 44} }, + { 5, 14, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 33, 34, 35, 36} }, + { 6, 15, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 57, 58, 59, 60} }, + { 7, 16, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 49, 50, 51, 52} }, + { 8, 17, 1, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 73, 74, 75, 76} }, + { 9, 18, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 65, 66, 67, 68} }, + {10, 19, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 89, 90, 91, 92} }, + {11, 20, 1, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 81, 82, 83, 84} }, + {12, 21, 1, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105, 106, 107, 108} }, + {13, 22, 1, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99, 100} }, + {14, 23, 1, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {121, 122, 123, 124} }, + {15, 24, 1, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {113, 114, 115, 116} }, + {16, 25, 2, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {137, 138, 139, 140} }, + {17, 26, 2, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {129, 130, 131, 132} }, + {18, 27, 2, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {153, 154, 155, 156} }, + {19, 28, 2, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {145, 146, 147, 148} }, + {20, 29, 2, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {169, 170, 171, 172} }, + {21, 30, 2, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {161, 162, 163, 164} }, + {22, 31, 2, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {185, 186, 187, 188} }, + {23, 32, 2, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {177, 178, 179, 180} }, + {24, 33, 3, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {201, 202, 203, 204} }, + {25, 34, 3, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {193, 194, 195, 196} }, + {26, 35, 3, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {217, 218, 219, 220} }, + {27, 36, 3, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {209, 210, 211, 212} }, + {28, 37, 3, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {233, 234, 235, 236} }, + {29, 38, 3, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {225, 226, 227, 228} }, + {30, 39, 3, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {249, 250, 251, 252} }, + {31, 40, 3, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {241, 242, 243, 244} }, + {32, 44, 4, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 13, 14, 15, 16} }, + {33, 43, 4, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 5, 6, 7, 8} }, + {34, 42, 4, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 29, 30, 31, 32} }, + {35, 41, 4, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 21, 22, 23, 24} }, + {36, 48, 4, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 45, 46, 47, 48} }, + {37, 47, 4, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 37, 38, 39, 40} }, + {38, 46, 4, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 61, 62, 63, 64} }, + {39, 45, 4, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 53, 54, 55, 56} }, + {40, 52, 5, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 77, 78, 79, 80} }, + {41, 51, 5, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 69, 70, 71, 72} }, + {42, 50, 5, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 93, 94, 95, 96} }, + {43, 49, 5, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {44, 56, 5, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109, 110, 111, 112} }, + {45, 55, 5, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101, 102, 103, 104} }, + {46, 54, 5, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {125, 126, 127, 128} }, + {47, 53, 5, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117, 118, 119, 120} }, + {48, 60, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {141, 142, 143, 144} }, + {49, 59, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {133, 134, 135, 136} }, + {50, 58, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {157, 158, 159, 160} }, + {51, 57, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {149, 150, 151, 152} }, + {52, 64, 6, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {173, 174, 175, 176} }, + {53, 63, 6, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {165, 166, 167, 168} }, + {54, 62, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {189, 190, 191, 192} }, + {55, 61, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {181, 182, 183, 184} }, + {56, 68, 7, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {205, 206, 207, 208} }, + {57, 67, 7, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {197, 198, 199, 200} }, + {58, 66, 7, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {221, 222, 223, 224} }, + {59, 65, 7, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {213, 214, 215, 216} }, + {60, 72, 7, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {237, 238, 239, 240} }, + {61, 71, 7, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {229, 230, 231, 232} }, + {62, 70, 7, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {253, 254, 255, 256} }, + {63, 69, 7, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {245, 246, 247, 248} }, +}; +#endif + + +/* ========================================== + * Lavender Layout configuration + * ========================================== + */ +#if (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_GA) +unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_ONL) +unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; +#endif + +#ifdef SWPS_LAVENDER +struct inv_ioexp_layout_s lavender_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SEQUOIA_NABC, { { 1, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 1, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + { 1, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_SEQUOIA_NABC, { { 2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 1 A */ + { 2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 1 B */ + { 2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 1 C */ + }, + {2, IOEXP_TYPE_SEQUOIA_NABC, { { 3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 2 A */ + { 3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 2 B */ + { 3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 2 C */ + }, + {3, IOEXP_TYPE_SEQUOIA_NABC, { { 4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 3 A */ + { 4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 3 B */ + { 4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 3 C */ + }, + {4, IOEXP_TYPE_SEQUOIA_NABC, { { 9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 4 A */ + { 9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 4 B */ + { 9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 4 C */ + }, + {5, IOEXP_TYPE_SEQUOIA_NABC, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 5 A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 5 B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 C */ + }, + {6, IOEXP_TYPE_SEQUOIA_NABC, { {11, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 6 A */ + {11, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 6 B */ + {11, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 6 C */ + }, + {7, IOEXP_TYPE_SEQUOIA_NABC, { {12, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 7 A */ + {12, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 7 B */ + {12, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, + {8, IOEXP_TYPE_LAVENDER_P65, { { 5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xF6, 0xff}, {0xF8, 0xff}, }, }, /* addr[0] = I/O Expander CPU */ + }, +}; + + +struct inv_port_layout_s lavender_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 17, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {188, 189, 190, 191} }, + { 1, 18, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {184, 185, 186, 187} }, + { 2, 19, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {180, 181, 182, 183} }, + { 3, 20, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {176, 177, 178, 179} }, + { 4, 21, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {172, 173, 174, 175} }, + { 5, 22, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {168, 169, 170, 171} }, + { 6, 23, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {164, 165, 166, 167} }, + { 7, 24, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {160, 161, 162, 163} }, + { 8, 25, 1, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {156, 157, 158, 159} }, + { 9, 26, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {152, 153, 154, 155} }, + {10, 27, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {148, 149, 150, 151} }, + {11, 28, 1, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {144, 145, 146, 147} }, + {12, 29, 1, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {140, 141, 142, 143} }, + {13, 30, 1, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {136, 137, 138, 139} }, + {14, 31, 1, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {132, 133, 134, 135} }, + {15, 32, 1, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {128, 129, 130, 131} }, + {16, 33, 2, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 0, 1, 2, 3} }, + {17, 34, 2, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 4, 5, 6, 7} }, + {18, 35, 2, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 8, 9, 10, 11} }, + {19, 36, 2, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 12, 13, 14, 15} }, + {20, 37, 2, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 16, 17, 18, 19} }, + {21, 38, 2, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 20, 21, 22, 23} }, + {22, 39, 2, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 24, 25, 26, 27} }, + {23, 40, 2, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 28, 29, 30, 31} }, + {24, 41, 3, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 32, 33, 34, 35} }, + {25, 42, 3, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 36, 37, 38, 39} }, + {26, 43, 3, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 40, 41, 42, 43} }, + {27, 44, 3, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 44, 45, 46, 47} }, + {28, 45, 3, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 48, 49, 50, 51} }, + {29, 46, 3, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 52, 53, 54, 55} }, + {30, 47, 3, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 56, 57, 58, 59} }, + {31, 48, 3, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 60, 61, 62, 63} }, + {32, 49, 4, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {256, 257, 258, 259} }, + {33, 50, 4, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {260, 261, 262, 263} }, + {34, 51, 4, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {264, 265, 266, 267} }, + {35, 52, 4, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {268, 269, 270, 271} }, + {36, 53, 4, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {272, 273, 274, 275} }, + {37, 54, 4, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {276, 277, 278, 279} }, + {38, 55, 4, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {280, 281, 282, 283} }, + {39, 56, 4, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {284, 285, 286, 287} }, + {40, 57, 5, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {288, 289, 290, 291} }, + {41, 58, 5, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {292, 293, 294, 295} }, + {42, 59, 5, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {296, 297, 298, 299} }, + {43, 60, 5, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {300, 301, 302, 303} }, + {44, 61, 5, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {304, 305, 306, 307} }, + {45, 62, 5, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {308, 309, 310, 311} }, + {46, 63, 5, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {312, 313, 314, 315} }, + {47, 64, 5, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {316, 317, 318, 319} }, + {48, 65, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {444, 445, 446, 447} }, + {49, 66, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {440, 441, 442, 443} }, + {50, 67, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {436, 437, 438, 439} }, + {51, 68, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {432, 433, 434, 435} }, + {52, 69, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {428, 429, 430, 431} }, + {53, 70, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {424, 425, 426, 427} }, + {54, 71, 6, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {420, 421, 422, 423} }, + {55, 72, 6, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {416, 417, 418, 419} }, + {56, 73, 7, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {412, 413, 414, 415} }, + {57, 74, 7, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {408, 409, 410, 411} }, + {58, 75, 7, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {404, 405, 406, 407} }, + {59, 76, 7, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {400, 401, 402, 403} }, + {60, 77, 7, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {396, 397, 398, 399} }, + {61, 78, 7, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {392, 393, 394, 395} }, + {62, 79, 7, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {388, 389, 390, 391} }, + {63, 80, 7, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {384, 385, 386, 387} }, + {64, 5, 8, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 64, 65, 66, 67} }, +}; +#endif + +/* =========================================================== + * Cottonwood Layout configuration Rangeley (Rangeley CPU board) + * =========================================================== + */ +#ifdef SWPS_COTTONWOOD_RANGELEY +unsigned cottonwood_rangeley_gpio_rest_mux = MUX_RST_GPIO_500_PCA9548; + +struct inv_ioexp_layout_s cottonwood_rangeley_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, CPLD_TYPE_COTTONWOOD,{ {1, 0x55, {22, 23, 24, 25}, {22, 23, 24, 25}, {-1, -1, -1, -1}, {0xee, 0xee, 0x99, 0x99}, {0x00, 0x00, 0x00, 0x00}, }, + }, + }, +}; + + +struct inv_port_layout_s cottonwood_rangeley_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 2, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 75} }, + { 1, 3, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 77} }, + { 2, 4, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 79} }, + { 3, 5, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 81} }, +}; +#endif + +/* =========================================================== + * Maple Layout configuration (Old) + * =========================================================== + */ +#ifdef SWPS_MAPLE_GA +unsigned maple_ga_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s maple_ga_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAPLE_0ABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_MAPLE_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_MAPLE_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_MAPLE_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_MAPLE_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_MAPLE_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_MAPLE_NABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s maple_ga_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 1} }, + { 1, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 2} }, + { 2, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 3} }, + { 3, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 4} }, + { 4, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 5} }, + { 5, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 6} }, + { 6, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 7} }, + { 7, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 8} }, + { 8, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 13} }, + { 9, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 14} }, + {10, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 15} }, + {11, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 16} }, + {12, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 21} }, + {13, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 22} }, + {14, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 23} }, + {15, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 24} }, + {16, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 29} }, + {17, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 30} }, + {18, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 31} }, + {19, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 32} }, + {20, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 33} }, + {21, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 34} }, + {22, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 35} }, + {23, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 36} }, + {24, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 41} }, + {25, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 42} }, + {26, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 43} }, + {27, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 44} }, + {28, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 49} }, + {29, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 50} }, + {30, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 51} }, + {31, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 52} }, + {32, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 57} }, + {33, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 58} }, + {34, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 59} }, + {35, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 60} }, + {36, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 61} }, + {37, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 62} }, + {38, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 63} }, + {39, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 64} }, + {40, 58, 6, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 65} }, + {41, 59, 6, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 66} }, + {42, 60, 6, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 67} }, + {43, 61, 6, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 68} }, + {44, 62, 6, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 69} }, + {45, 63, 6, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 70} }, + {46, 64, 6, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 71} }, + {47, 65, 6, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 72} }, + {48, 10, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 77, 78, 79, 80} }, + {49, 11, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 85, 86, 87, 88} }, + {50, 12, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 93, 94, 95, 96} }, + {51, 13, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 97, 98, 99,100} }, + {52, 14, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {105,106,107,108} }, + {53, 15, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {113,114,115,116} }, + {54, 16, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {121,122,123,124} }, + {55, 17, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {125,126,127,128} }, +}; +#endif + +/* =========================================================== + * Maple Layout configuration (B version) + * =========================================================== + */ +#ifdef SWPS_MAPLE_B +unsigned maple_b_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s maple_b_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAPLE_0ABC, { { 6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + { 6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_MAPLE_NABC, { { 7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_MAPLE_NABC, { { 8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_MAPLE_NABC, { { 9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_MAPLE_NABC, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_MAPLE_NABC, { {11, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {11, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {11, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_MAPLE_NABC, { {12, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {12, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {12, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s maple_b_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 1, 23, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 2} }, + { 2, 22, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 1} }, + { 3, 25, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 4} }, + { 4, 24, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 3} }, + { 5, 27, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 6} }, + { 6, 26, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 5} }, + { 7, 29, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 8} }, + { 8, 28, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 7} }, + { 9, 31, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 14} }, + {10, 30, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 13} }, + {11, 33, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 16} }, + {12, 32, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 15} }, + {13, 35, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 22} }, + {14, 34, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 21} }, + {15, 37, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 24} }, + {16, 36, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 23} }, + {17, 39, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 30} }, + {18, 38, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 29} }, + {19, 41, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 32} }, + {20, 40, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 31} }, + {21, 43, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 34} }, + {22, 42, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 33} }, + {23, 45, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 36} }, + {24, 44, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 35} }, + {25, 47, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 42} }, + {26, 46, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 41} }, + {27, 49, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 44} }, + {28, 48, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 43} }, + {29, 51, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 50} }, + {30, 50, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 49} }, + {31, 53, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 52} }, + {32, 52, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 51} }, + {33, 55, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 58} }, + {34, 54, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 57} }, + {35, 57, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 60} }, + {36, 56, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 59} }, + {37, 59, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 62} }, + {38, 58, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 61} }, + {39, 61, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 64} }, + {40, 60, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 63} }, + {41, 63, 6, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 66} }, + {42, 62, 6, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 65} }, + {43, 65, 6, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 68} }, + {44, 64, 6, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 67} }, + {45, 67, 6, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 70} }, + {46, 66, 6, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 69} }, + {47, 69, 6, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 72} }, + {48, 68, 6, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 71} }, + {49, 15, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 77, 78, 79, 80} }, + {50, 14, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 85, 86, 87, 88} }, + {51, 17, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 97, 98, 99,100} }, + {52, 16, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 93, 94, 95, 96} }, + {53, 19, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {105,106,107,108} }, + {54, 18, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {113,114,115,116} }, + {55, 21, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {125,126,127,128} }, + {56, 20, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {121,122,123,124} }, +}; +#endif + +/* =========================================================== + * Maple Layout configuration (J version) + * =========================================================== + */ +#ifdef SWPS_MAPLE_J +unsigned maple_j_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s maple_j_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAPLE_0ABC, { { 6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + { 6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_MAPLE_NABC, { { 7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_MAPLE_NABC, { { 8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_MAPLE_NABC, { { 9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_MAPLE_NABC, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_MAPLE_NABC, { {11, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {11, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {11, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_MAPLE_NABC, { {12, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {12, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {12, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s maple_j_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 22, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 1} }, + { 1, 23, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 2} }, + { 2, 24, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 3} }, + { 3, 25, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 4} }, + { 4, 26, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 5} }, + { 5, 27, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 6} }, + { 6, 28, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 7} }, + { 7, 29, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 8} }, + { 8, 30, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 13} }, + { 9, 31, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 14} }, + {10, 32, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 15} }, + {11, 33, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 16} }, + {12, 34, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 21} }, + {13, 35, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 22} }, + {14, 36, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 23} }, + {15, 37, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 24} }, + {16, 38, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 29} }, + {17, 39, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 30} }, + {18, 40, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 31} }, + {19, 41, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 32} }, + {20, 42, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 33} }, + {21, 43, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 34} }, + {22, 44, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 35} }, + {23, 45, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 36} }, + {24, 46, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 41} }, + {25, 47, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 42} }, + {26, 48, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 43} }, + {27, 49, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 44} }, + {28, 50, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 49} }, + {29, 51, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 50} }, + {30, 52, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 51} }, + {31, 53, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 52} }, + {32, 54, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 57} }, + {33, 55, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 58} }, + {34, 56, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 59} }, + {35, 57, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 60} }, + {36, 58, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 61} }, + {37, 59, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 62} }, + {38, 60, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 63} }, + {39, 61, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 64} }, + {40, 62, 6, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 65} }, + {41, 63, 6, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 66} }, + {42, 64, 6, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 67} }, + {43, 65, 6, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 68} }, + {44, 66, 6, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 69} }, + {45, 67, 6, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 70} }, + {46, 68, 6, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 71} }, + {47, 69, 6, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 72} }, + {48, 14, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 85, 86, 87, 88} }, + {49, 15, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 77, 78, 79, 80} }, + {50, 16, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 93, 94, 95, 96} }, + {51, 17, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 97, 98, 99,100} }, + {52, 18, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {113,114,115,116} }, + {53, 19, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {105,106,107,108} }, + {54, 20, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {121,122,123,124} }, + {55, 21, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {125,126,127,128} }, +}; +#endif + +/* ========================================== + * Gulmohar Layout configuration + * ========================================== + */ +#ifdef SWPS_GULMOHAR +unsigned gulmohar_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; + +struct inv_ioexp_layout_s gulmohar_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_GULMOHAR_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_GULMOHAR_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_GULMOHAR_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_GULMOHAR_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_GULMOHAR_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_GULMOHAR_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_GULMOHAR_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + + + +struct inv_port_layout_s gulmohar_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 1} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 2} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 3} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 4} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 5} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 6} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 7} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 8} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 9} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 10} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 11} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 12} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 21} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 22} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 23} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 24} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 33} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 34} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 35} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 36} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 37} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 38} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 39} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 40} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 41} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 42} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 43} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 44} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 49} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 50} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 51} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 52} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 53} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 54} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 55} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 56} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 65} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 66} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 67} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 68} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 69} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 70} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 71} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 72} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 81} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 82} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 83} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 84} }, + {48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 97, 98, 99,100} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 85, 86, 87, 88} }, + {50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {101,102,103,104} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {105,106,107,108} }, + {52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {109,110,111,112} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Gulmohar_2T EVT1 Layout configuration + * ========================================== + */ +#ifdef SWPS_GULMOHAR_2T_EVT1 +unsigned gulmohar_2t_evt1_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; + +struct inv_ioexp_layout_s gulmohar_2t_evt1_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC,{ {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC,{ {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC,{ {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xff}, {0x18, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + + + +struct inv_port_layout_s gulmohar_2t_evt1_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {54, 65, 6, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {55, 64, 6, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, +}; +#endif + + +/* =========================================================== + * Peony-SFP Layout configuration + * =========================================================== + */ +#ifdef SWPS_PEONY_SFP +unsigned peony_sfp_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL; + +struct inv_ioexp_layout_s peony_sfp_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s peony_sfp_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 20, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 1} }, + { 1, 21, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 2} }, + { 2, 22, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 3} }, + { 3, 23, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 4} }, + { 4, 24, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 5} }, + { 5, 25, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 6} }, + { 6, 26, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 7} }, + { 7, 27, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 8} }, + { 8, 28, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 13} }, + { 9, 29, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 14} }, + {10, 30, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 15} }, + {11, 31, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 16} }, + {12, 32, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 21} }, + {13, 33, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 22} }, + {14, 34, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 23} }, + {15, 35, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 24} }, + {16, 36, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 29} }, + {17, 37, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 30} }, + {18, 38, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 31} }, + {19, 39, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 32} }, + {20, 40, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 33} }, + {21, 41, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 34} }, + {22, 42, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 35} }, + {23, 43, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 36} }, + {24, 44, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 65} }, + {25, 45, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 66} }, + {26, 46, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 67} }, + {27, 47, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 68} }, + {28, 48, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 69} }, + {29, 49, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 70} }, + {30, 50, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 71} }, + {31, 51, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 72} }, + {32, 52, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 97} }, + {33, 53, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 98} }, + {34, 54, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 99} }, + {35, 55, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {100} }, + {36, 56, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {105} }, + {37, 57, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {106} }, + {38, 58, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {107} }, + {39, 59, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {108} }, + {40, 60, 6, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {113} }, + {41, 61, 6, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {114} }, + {42, 62, 6, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {115} }, + {43, 63, 6, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {116} }, + {44, 64, 6, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {121} }, + {45, 65, 6, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {122} }, + {46, 66, 6, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {123} }, + {47, 67, 6, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {124} }, + {48, 12, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 49, 50, 51, 52} }, + {49, 13, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 57, 58, 59, 60} }, + {50, 14, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 61, 62, 63, 64} }, + {51, 15, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 77, 78, 79, 80} }, + {52, 16, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 85, 86, 87, 88} }, + {53, 17, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 93, 94, 95, 96} }, +}; +#endif + + +/* =========================================================== + * Peony-Copper Layout configuration + * =========================================================== + */ +#ifdef SWPS_PEONY_COPPER +unsigned peony_copper_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL; + +struct inv_ioexp_layout_s peony_copper_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, +}; + +struct inv_port_layout_s peony_copper_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + {48, 4, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 49, 50, 51, 52} }, + {49, 5, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 57, 58, 59, 60} }, + {50, 6, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 61, 62, 63, 64} }, + {51, 7, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 77, 78, 79, 80} }, + {52, 8, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 85, 86, 87, 88} }, + {53, 9, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 93, 94, 95, 96} }, +}; +#endif + + +/* =========================================================== + * Cedar Layout configuration + * =========================================================== + */ +#ifdef SWPS_CEDAR_GA +unsigned cedar_ga_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s cedar_ga_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_CEDAR_0ABC, { { 4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 4, 0x21, {0,-1}, {1,-1}, {3,-1}, {0xff }, {0x00 }, }, /* addr[1] = I/O Expander 0 B */ + { 4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_CEDAR_0ABC, { { 5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 5, 0x21, {0,-1}, {1,-1}, {3,-1}, {0xff }, {0x00 }, }, /* addr[1] = I/O Expander 0 B */ + { 5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {2, IOEXP_TYPE_CEDAR_0ABC, { { 6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 6, 0x21, {0,-1}, {1,-1}, {3,-1}, {0xff }, {0x00 }, }, /* addr[1] = I/O Expander 0 B */ + { 6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {3, IOEXP_TYPE_CEDAR_0ABC, { { 7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 7, 0x21, {0,-1}, {1,-1}, {3,-1}, {0xff }, {0x00 }, }, /* addr[1] = I/O Expander 0 B */ + { 7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, +}; + +struct inv_port_layout_s cedar_ga_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 12, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 21, 22, 23, 24} }, + { 1, 13, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 17, 18, 19, 20} }, + { 2, 14, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 25, 26, 27, 28} }, + { 3, 15, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 29, 30, 31, 32} }, + { 4, 16, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 37, 38, 39, 40} }, + { 5, 17, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 33, 34, 35, 36} }, + { 6, 18, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 41, 42, 43, 44} }, + { 7, 19, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 45, 46, 47, 48} }, + { 8, 20, 1, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 5, 6, 7, 8} }, + { 9, 21, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 1, 2, 3, 4} }, + {10, 22, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 9, 10, 11, 12} }, + {11, 23, 1, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 13, 14, 15, 16} }, + {12, 24, 1, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 53, 54, 55, 56} }, + {13, 25, 1, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 49, 50, 51, 52} }, + {14, 26, 1, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 57, 58, 59, 60} }, + {15, 27, 1, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 61, 62, 63, 64} }, + {16, 28, 2, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 71, 72, 73, 74} }, + {17, 29, 2, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 67, 68, 69, 70} }, + {18, 30, 2, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 75, 76, 77, 78} }, + {19, 31, 2, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 79, 80, 81, 82} }, + {20, 32, 2, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 119, 120, 121, 122} }, + {21, 33, 2, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 115, 116, 117, 118} }, + {22, 34, 2, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 123, 124, 125, 126} }, + {23, 35, 2, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 127, 128, 129, 130} }, + {24, 36, 3, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 87, 88, 89, 90} }, + {25, 37, 3, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 83, 84, 85, 86} }, + {26, 38, 3, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 91, 92, 93, 94} }, + {27, 39, 3, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 95, 96, 97, 98} }, + {28, 40, 3, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 103, 104, 105, 106} }, + {29, 41, 3, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 99, 100, 101, 102} }, + {30, 42, 3, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 107, 108, 109, 110} }, + {31, 43, 3, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 111, 112, 113, 114} }, +}; +#endif + + +#endif /* INV_SWPS_H */ + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.c new file mode 100644 index 000000000000..6867bbc6030e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.c @@ -0,0 +1,2579 @@ +#include +#include +#include "io_expander.h" + +/* For build single module using (Ex: ONL platform) */ +#include +//#include + + +static struct ioexp_obj_s *ioexp_head_p = NULL; +static struct ioexp_obj_s *ioexp_tail_p = NULL; +extern int io_no_init; + +/* ========== Register IOEXP layout ========== + */ +struct ioexp_map_s ioexp_map_magnolia_nab = { + + .chip_amount = 2, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_magnolia_4ab = { + + .chip_amount = 2, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_magnolia_7ab = { + + .chip_amount = 2, + .data_width = 2, + + .map_present = { {1, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {1, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {1, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {1, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 2}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 3}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +struct ioexp_map_s ioexp_map_redwood_p01p08_p17p24 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 0, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 0, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 0, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 0, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_redwood_p09p16_p25p32 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 1, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_hudson32iga_p01p08_p17p24 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 0, 0}, /* map_present[0] = MODABS_QSFP(X) */ + {2, 0, 1}, /* map_present[1] = MODABS_QSFP(X+1) */ + {2, 0, 2}, /* map_present[2] = MODABS_QSFP(X+2) */ + {2, 0, 3}, /* map_present[3] = MODABS_QSFP(X+3) */ + {2, 0, 4}, /* map_present[4] = MODABS_QSFP(X+4) */ + {2, 0, 5}, /* map_present[5] = MODABS_QSFP(X+5) */ + {2, 0, 6}, /* map_present[6] = MODABS_QSFP(X+6) */ + {2, 0, 7}, /* map_present[7] = MODABS_QSFP(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_hudson32iga_p09p16_p25p32 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MODABS_QSFP(X) */ + {2, 1, 1}, /* map_present[1] = MODABS_QSFP(X+1) */ + {2, 1, 2}, /* map_present[2] = MODABS_QSFP(X+2) */ + {2, 1, 3}, /* map_present[3] = MODABS_QSFP(X+3) */ + {2, 1, 4}, /* map_present[4] = MODABS_QSFP(X+4) */ + {2, 1, 5}, /* map_present[5] = MODABS_QSFP(X+5) */ + {2, 1, 6}, /* map_present[6] = MODABS_QSFP(X+6) */ + {2, 1, 7}, /* map_present[7] = MODABS_QSFP(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_cypress_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_cypress_7abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 0, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 0, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 0, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 0, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {0, 1, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 1, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 1, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {0, 1, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {0, 1, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {0, 1, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {1, 1, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {1, 1, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {1, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {1, 1, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +struct ioexp_map_s ioexp_map_tahoe_5a = { + + .chip_amount = 1, + .data_width = 2, + + .map_present = { {0, 0, 3}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 1, 0}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 5}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + }, + .map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 6}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 3}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + }, + .map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + }, +}; + + +struct ioexp_map_s ioexp_map_tahoe_6abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 3}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 1, 0}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 5}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {1, 0, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 1, 0}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 0, 3}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 0}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + {2, 1, 5}, /* map_present[8] = MOD_ABS_PORT(X+8) */ + }, + .map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 0, 6}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 1, 3}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {1, 0, 1}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {1, 0, 6}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {1, 1, 3}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {2, 0, 1}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {2, 0, 6}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + {2, 1, 3}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {1, 0, 2}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 7}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 1, 4}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {2, 0, 2}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {2, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + {2, 1, 4}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+8) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {1, 0, 0}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {1, 0, 5}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {1, 1, 2}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {2, 0, 0}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {2, 0, 5}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + {2, 1, 2}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_sequoia_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 1, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {0, 1, 6}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {0, 1, 7}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {0, 0, 6}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {0, 0, 7}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_lavender_p65 = { + + .chip_amount = 1, + .data_width = 1, + + .map_present = { {0, 0, 4}, }, /* map_present[0] = MOD_ABS_PORT(X) */ + .map_reset = { {0, 0, 1}, }, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + .map_lpmod = { {0, 0, 2}, }, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + .map_modsel = { {0, 0, 0}, }, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ +}; + + +struct ioexp_map_s cpld_map_cottonwood = { + + .chip_amount = 1, + .data_width = 4, + + .map_present = { {0, 2, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 2, 4}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 3, 0}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 3, 4}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + }, + .map_tx_disable = { {0, 0, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 4}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 4}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + }, + .map_tx_fault = { {0, 2, 2}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 2, 6}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 3, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 3, 6}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + }, + .map_rxlos = { {0, 2, 1}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 2, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 3, 1}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 3, 5}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + }, + .map_hard_rs0 = { {0, 0, 2}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {0, 0, 6}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {0, 1, 2}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {0, 1, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + }, + .map_hard_rs1 = { {0, 0, 2}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {0, 0, 6}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {0, 1, 2}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {0, 1, 6}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + }, +}; + + +struct ioexp_map_s ioexp_map_maple_0abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 1, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + {0, 1, 6}, /* map_reset[6] = QRESET_QSFP_N_P(X+6) */ + {0, 1, 7}, /* map_reset[7] = QRESET_QSFP_N_P(X+7) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP_P(X+7) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + {0, 0, 6}, /* map_modsel[6] = MODSEL_QSFP_N_P(X+6) */ + {0, 0, 7}, /* map_modsel[7] = MODSEL_QSFP_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_maple_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_7abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_1abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_3abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_7abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {1, 0, 4}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 1, 1}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 1, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 0, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 1}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 6}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 3}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {1, 0, 1}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {1, 0, 6}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {1, 1, 3}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + {2, 0, 1}, /* map_reset[6] = QRESET_QSFP_N_P(X+6) */ + {2, 0, 6}, /* map_reset[7] = QRESET_QSFP_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 2}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 7}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 1, 4}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + {2, 0, 2}, /* map_lpmod[6] = LPMODE_QSFP_P(X+6) */ + {2, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP_P(X+7) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {1, 0, 0}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {1, 0, 5}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {1, 1, 2}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + {2, 0, 0}, /* map_modsel[6] = MODSEL_QSFP_N_P(X+6) */ + {2, 0, 5}, /* map_modsel[7] = MODSEL_QSFP_N_P(X+7) */ + }, +}; + + +/* PortType: SFP / 8 port + * Platform: Cypress, Peony_SFP + */ +struct ioexp_map_s ioexp_map_sfp_8p_layout_1 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +/* PortType: QSFP / 6 port + * Platform: Gulmohar, Peony_SFP, Peony_Copper + */ +struct ioexp_map_s ioexp_map_6p_qsfp_type_1 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +/* ========== Private functions ========== + */ +int check_channel_tier_1(void); + +struct i2c_client * +_get_i2c_client(struct ioexp_obj_s *self, + int chip_id){ + + struct ioexp_i2c_s *i2c_curr_p = self->i2c_head_p; + + if (!(i2c_curr_p)){ + SWPS_ERR("%s: i2c_curr_p is NULL\n", __func__); + return NULL; + } + while (i2c_curr_p){ + if ((i2c_curr_p->chip_id) == chip_id){ + return i2c_curr_p->i2c_client_p; + } + i2c_curr_p = i2c_curr_p->next; + } + SWPS_ERR("%s: not exist! :%d\n", __func__, chip_id); + return NULL; +} + + +static int +_common_ioexp_update_one(struct ioexp_obj_s *self, + struct ioexp_addr_s *ioexp_addr, + int chip_id, + int data_width, + int show_err, + char *caller_name) { + int buf = 0; + int err = 0; + int data_id = 0; + int r_offset = 0; + + for(data_id=0; data_idread_offset[data_id]; + if (r_offset < 0) { + SWPS_DEBUG("skip a read_offset <%d>\n", r_offset); + continue; + } + buf = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id), r_offset); + /* Check error */ + if (buf < 0) { + err = 1; + if (show_err) { + SWPS_INFO("IOEXP-%d read fail! :%d \n", self->ioexp_id, buf); + SWPS_INFO("Dump: :%d :0x%02x :%d, :%s\n", + ioexp_addr->chan_id, ioexp_addr->chip_addr, + ioexp_addr->read_offset[data_id], caller_name); + } + continue; + } + /* Update IOEXP object */ + self->chip_data[chip_id].data[data_id] = (uint8_t)buf; + } + if (err) { + return ERR_IOEXP_UNEXCPT; + } + return 0; +} + + +static int +common_ioexp_update_all(struct ioexp_obj_s *self, + int show_err, + char *caller_name){ + + int err = 0; + int chip_id = 0; + int chip_amount = self->ioexp_map_p->chip_amount; + + for (chip_id=0; chip_idioexp_map_p->map_addr[chip_id]), + chip_id, + self->ioexp_map_p->data_width, + show_err, + caller_name) < 0) { + err = 1; + } + } + if (err) { + return ERR_IOEXP_UNEXCPT; + } + return 0; +} + + +static int +_common_check_by_mode(struct ioexp_obj_s *self){ + + switch (self->mode){ + case IOEXP_MODE_DIRECT: + return self->fsm_4_direct(self); + + case IOEXP_MODE_POLLING: + if (self->state >= 0){ + return 0; + } + switch (self->state){ + case STATE_IOEXP_INIT: + return ERR_IOEXP_UNINIT; + case STATE_IOEXP_ABNORMAL: + return ERR_IOEXP_ABNORMAL; + default: + return ERR_IOEXP_NOSTATE; + } + break; + + default: + break; + } + SWPS_ERR("%s: Exception occurs. :%d \n", __func__, self->mode); + return ERR_IOEXP_UNEXCPT; +} + + +static int +_common_get_bit(struct ioexp_obj_s *self, + struct ioexp_bitmap_s *bitmap_obj_p, + char *func_mane){ + uint8_t buf; + int err_code; + + /* Check and get address */ + err_code = _common_check_by_mode(self); + if (err_code < 0){ + return err_code; + } + if (!bitmap_obj_p){ + SWPS_ERR("Layout config incorrect! :%d :%s\n", + self->ioexp_id, func_mane); + return ERR_IOEXP_BADCONF; + } + /* Get data form cache */ + buf = self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset]; + return (int)(buf >> bitmap_obj_p->bit_shift & 0x01); +} + + +static int +_common_set_bit(struct ioexp_obj_s *self, + struct ioexp_bitmap_s *bitmap_obj_p, + int input_val, + char *func_mane){ + int err_code, target_offset; + uint8_t origin_byte; + uint8_t modify_byte; + + /* Check and get address */ + err_code = _common_check_by_mode(self); + if (err_code < 0){ + return err_code; + } + if (!bitmap_obj_p){ + SWPS_ERR("Layout config incorrect! :%d :%s\n", + self->ioexp_id, func_mane); + return ERR_IOEXP_BADCONF; + } + /* Prepare write date */ + origin_byte = self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset]; + switch (input_val) { + case 0: + modify_byte = origin_byte; + SWP_BIT_CLEAR(modify_byte, bitmap_obj_p->bit_shift); + break; + case 1: + modify_byte = origin_byte; + SWP_BIT_SET(modify_byte, bitmap_obj_p->bit_shift); + break; + default: + SWPS_ERR("Input value incorrect! :%d :%d :%s\n", + input_val, self->ioexp_id, func_mane); + return ERR_IOEXP_BADINPUT; + } + /* Setup i2c client */ + target_offset = self->ioexp_map_p->map_addr[bitmap_obj_p->chip_id].write_offset[bitmap_obj_p->ioexp_voffset]; + /* Write byte to chip via I2C */ + err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, bitmap_obj_p->chip_id), + target_offset, + modify_byte); + /* Update or bollback object */ + if (err_code < 0){ + self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset] = origin_byte; + SWPS_ERR("I2C write fail! :%d :%d :%s :%d\n", + input_val, self->ioexp_id, func_mane, err_code); + return err_code; + } + self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset] = modify_byte; + return 0; +} + + +/* ========== Object public functions ========== + */ +int +common_get_present(struct ioexp_obj_s *self, + int virt_offset){ + + int UNPLUG = 1; + int retval = ERR_IOEXP_UNEXCPT; + + retval = _common_get_bit(self, + &(self->ioexp_map_p->map_present[virt_offset]), + "common_get_present"); + if (retval < 0) { + /* [Note] + * => Transceiver object does not need to handle IOEXP layer issues. + */ + return UNPLUG; + } + return retval; +} + + +int +common_get_tx_fault(struct ioexp_obj_s *self, + int virt_offset){ + /* [Transmit Fault (Tx_Fault)] + * A catastrophic laser fault will activate the transmitter signal, + * TX_FAULT, and disable the laser. This signal is an open collector + * output (pull-up required on the host board). A low signal indicates + * normal laser operation and a high signal indicates a fault. The + * TX_FAULT will be latched high when a laser fault occurs and is + * cleared by toggling the TX_DISABLE input or power cycling the + * transceiver. The transmitter fault condition can also be monitored + * via the two-wire serial interface. + * (address A2, byte 110, bit 2). + * + * 0: Normal + * 1: Abnormal + */ + return _common_get_bit(self, + &(self->ioexp_map_p->map_tx_fault[virt_offset]), + "common_get_tx_fault"); +} + + +int +common_get_rxlos(struct ioexp_obj_s *self, + int virt_offset){ + /* [Receiver Loss of Signal (Rx_LOS)] + * The post-amplification IC also includes transition detection circuitry + * which monitors the ac level of incoming optical signals and provides a + * TTL/CMOS compatible status signal to the host (pin 8). An adequate optical + * input results in a low Rx_LOS output while a high Rx_LOS output indicates + * an unusable optical input. The Rx_LOS thresholds are factory set so that + * a high output indicates a definite optical fault has occurred. Rx_LOS can + * also be monitored via the two-wire serial interface + * (address A2h, byte 110, bit 1). + * + * 0: Normal + * 1: Abnormal + */ + return _common_get_bit(self, + &(self->ioexp_map_p->map_rxlos[virt_offset]), + "common_get_rxlos"); +} + + +int +common_get_tx_disable(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_tx_disable[virt_offset]), + "common_get_tx_disable"); +} + + +int +common_get_reset(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_reset[virt_offset]), + "common_get_reset"); +} + + +int +common_get_lpmod(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_lpmod[virt_offset]), + "common_get_lpmod"); +} + + +int +common_get_modsel(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_modsel[virt_offset]), + "common_get_modsel"); +} + + +int +common_get_hard_rs0(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_hard_rs0[virt_offset]), + "common_get_hard_rs0"); +} + + +int +common_get_hard_rs1(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_hard_rs1[virt_offset]), + "common_get_hard_rs1"); +} + + +int +common_set_tx_disable(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_tx_disable[virt_offset]), + input_val, + "common_set_tx_disable"); +} + + +int +common_set_reset(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_reset[virt_offset]), + input_val, + "common_set_reset"); +} + + +int +common_set_lpmod(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_lpmod[virt_offset]), + input_val, + "common_set_lpmod"); +} + + +int +common_set_modsel(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_modsel[virt_offset]), + input_val, + "common_set_modsel"); +} + + +int +common_set_hard_rs0(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_hard_rs0[virt_offset]), + input_val, + "common_set_hard_rs0"); +} + + +int +common_set_hard_rs1(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_hard_rs1[virt_offset]), + input_val, + "common_set_hard_rs1"); +} + + +int +ioexp_get_not_support(struct ioexp_obj_s *self, + int virt_offset){ + return ERR_IOEXP_NOTSUPPORT; +} + + +int +ioexp_set_not_support(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + return ERR_IOEXP_NOTSUPPORT; +} + + +int +fake_ioexp_init(struct ioexp_obj_s *self){ + return 1; +} + +int +fake_ioexp_update(struct ioexp_obj_s *self){ + return 1; +} + + +int +fake_update_func(struct ioexp_obj_s *self){ + return 1; +} + +int +fake_get_func(struct ioexp_obj_s *self, + int virt_offset){ + SWPS_WARN("Someone called fake_get_func\n"); + return -1; +} + +int +fake_set_func(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + SWPS_WARN("Someone called fake_set_func\n"); + return -1; +} + + +/* ========== Initial functions for IO Expander ========== + */ +int +common_ioexp_init(struct ioexp_obj_s *self) { + + int chip_id, offset, err_code; + struct ioexp_addr_s *addr_p; + + if (self->mode == IOEXP_MODE_DIRECT) { + goto update_common_ioexp_init; + } + if (!io_no_init) { /*normal init*/ + + /* Setup default value to each physical IO Expander */ + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ + /* Get address mapping */ + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + if (!addr_p){ + SWPS_ERR("%s: IOEXP config incorrect! :%d \n", + __func__, chip_id); + return -1; + } + /* Setup default value */ + for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){ + + /* [Desc] Skip the setup default value behavior + [Note] Setup default value = -1 if you don't want to write the value to IOEXP or CPLD + */ + if(addr_p->write_offset[offset] < 0){ + SWPS_DEBUG("skip a write_offset <%d>\n", addr_p->conf_offset[offset]); + continue; + } + err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id), + addr_p->write_offset[offset], + addr_p->data_default[offset]); + if (err_code < 0){ + SWPS_ERR("%s: set default fail! :%d \n", + __func__, err_code); + return ERR_IOEXP_UNEXCPT; + } + } + } + } +update_common_ioexp_init: + /* Check and update info to object */ + err_code = self->update_all(self, 1, "common_ioexp_init"); + if (err_code < 0) { + SWPS_ERR("%s: update_all() fail! :%d \n", + __func__, err_code); + return ERR_IOEXP_UNEXCPT; + } + return 0; +} + + +/* ========== Object functions for Final State Machine ========== + */ +int +_is_channel_ready(struct ioexp_obj_s *self){ + + int chip_id = 0; + int byte_id = 0; + int getval = ERR_IOEXP_UNEXCPT; + int chkval = ERR_IOEXP_UNEXCPT; + char *emsg = "ERR"; + struct ioexp_addr_s *addr_p = NULL; + + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++) { + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + if (!addr_p){ + emsg = "IOEXP config incorrect"; + goto err_is_channel_ready; + } + for (byte_id=0; byte_id<(self->ioexp_map_p->data_width); byte_id++) { + if (addr_p->conf_offset[byte_id] < 0) { + continue; + } + if ((addr_p->conf_default[byte_id]) != 0) { + goto go_is_channel_ready; + } + } + if (chip_id == ((self->ioexp_map_p->chip_amount) - 1)) { + SWPS_DEBUG("%s: no non-zero config", __func__); + break; + } + } + chip_id = 0; + byte_id = 0; + +go_is_channel_ready: + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + chkval = addr_p->conf_default[byte_id]; + getval = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id), + addr_p->conf_offset[byte_id]); + + SWPS_DEBUG("%s: target info :%d :%d :%d :%d :%d\n", + __func__, self->ioexp_id, chip_id, byte_id, chkval, getval); + + if ((getval >= 0) && (getval == chkval)) { + return 1; + } + return 0; + +err_is_channel_ready: + SWPS_ERR("%s: %s :%d :%d :%d :%d :%d\n", + __func__, emsg, self->ioexp_id, chip_id, byte_id, chkval, getval); + return ERR_IOEXP_UNEXCPT; +} + + +int +_ioexp_init_handler(struct ioexp_obj_s *self){ + + int return_val; + + switch (self->mode) { + case IOEXP_MODE_DIRECT: + return_val = self->init(self); + if (return_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + } else { + self->state = STATE_IOEXP_NORMAL; + } + return return_val; + + case IOEXP_MODE_POLLING: + /* Check system and channel is ready */ + if (self->state == STATE_IOEXP_INIT){ + if (!_is_channel_ready(self)){ + self->state = STATE_IOEXP_INIT; + SWPS_WARN("%s: IOEXP:%d channel not ready.\n", + __func__, self->ioexp_id); + return 0; + } + } + /* Execute initial callback */ + return_val = self->init(self); + if (return_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + } else { + self->state = STATE_IOEXP_NORMAL; + } + return return_val; + + default: + break; + } + SWPS_ERR("%s: exception occur :%d\n", __func__, self->mode); + return ERR_IOEXP_UNEXCPT; +} + + +int +common_ioexp_fsm_4_direct(struct ioexp_obj_s *self){ + + int result_val; + int show_err = 1; + char *func_mane = "common_ioexp_fsm_4_direct"; + + switch (self->state){ + case STATE_IOEXP_INIT: + result_val = _ioexp_init_handler(self); + /* Exception case: terminate initial procedure */ + if(result_val < 0){ + /* Initial fail */ + return result_val; + } + if(self->state == STATE_IOEXP_INIT){ + /* Keep in INIT state, and return error */ + return ERR_IOEXP_UNINIT; + } + /* Case: Initial done */ + return 0; + + case STATE_IOEXP_NORMAL: + result_val = self->update_all(self, show_err, func_mane); + if (result_val < 0){ + SWPS_INFO("%s: NORMAL -> ABNORMAL :%d\n", + __func__, result_val); + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + } + self->state = STATE_IOEXP_NORMAL; + return 0; + + case STATE_IOEXP_ABNORMAL: + result_val = self->update_all(self, show_err, func_mane); + if (result_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + } + SWPS_DEBUG("%s: ABNORMAL -> NORMAL :%d\n", + __func__, result_val); + self->state = STATE_IOEXP_NORMAL; + return 0; + + default: + break; + } + SWPS_ERR("%s: Exception occurs :%d\n", + __func__, self->state); + return ERR_IOEXP_UNEXCPT; +} + + +int +common_ioexp_fsm_4_polling(struct ioexp_obj_s *self){ + + int result_val, i, show_e; + int fail_retry = 3; + char *func_name = "common_ioexp_fsm_4_polling"; + +#ifdef DEBUG_SWPS + show_e = 1; +#else + show_e = 0; +#endif + + switch (self->state){ + case STATE_IOEXP_INIT: + result_val = _ioexp_init_handler(self); + /* Exception case: terminate initial procedure */ + if(result_val < 0){ + /* Initial fail */ + return result_val; + } + /* Case: System (Channel) not ready */ + if(self->state == STATE_IOEXP_INIT){ + /* Keep in INIT state, wait and retry */ + return 0; + } + /* Case: Initial done */ + SWPS_INFO("IOEXP-%d: initial done. :%d\n", + self->ioexp_id, self->ioexp_type); + return result_val; + + case STATE_IOEXP_NORMAL: + /* Retry mechanism for case of i2c topology not stable */ + for (i=0; iupdate_all(self, show_e, func_name); + if (result_val >= 0) { + self->state = STATE_IOEXP_NORMAL; + return 0; + } + if (check_channel_tier_1() < 0) { + SWPS_INFO("%s: detect I2C crash :%d\n", + __func__, self->ioexp_id); + break; + } + SWPS_DEBUG("IOEXP-%d: unstable :%d\n", + self->ioexp_id, result_val); + } + SWPS_INFO("IOEXP-%d: NORMAL -> ABNORMAL :%d\n", + self->ioexp_id, result_val); + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + + case STATE_IOEXP_ABNORMAL: + result_val = self->update_all(self, show_e, func_name); + if (result_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + } + SWPS_INFO("IOEXP-%d: ABNORMAL -> NORMAL :%d\n", + self->ioexp_id, result_val); + self->state = STATE_IOEXP_NORMAL; + return 0; + + default: + break; + } + SWPS_ERR("IOEXP-%d: Exception occurs :%d\n", + self->ioexp_id, self->state); + return ERR_IOEXP_UNEXCPT; +} + + +/* ========== Object private functions for check & update ========== + */ +int +common_ioexp_check(struct ioexp_obj_s *self){ + + int result; + + if (self->mode != IOEXP_MODE_POLLING){ + SWPS_ERR("%s: not polling mode :%d\n", + __func__, self->mode); + return ERR_IOEXP_NOTSUPPORT; + } + mutex_lock(&self->lock); + result = self->fsm_4_polling(self); + mutex_unlock(&self->lock); + return result; +} + + +/* ========== Functions for Factory pattern ========== + */ +static struct ioexp_map_s * +get_ioexp_map(int ioexp_type){ + switch (ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + return &ioexp_map_magnolia_nab; + case IOEXP_TYPE_MAGINOLIA_4AB: + return &ioexp_map_magnolia_4ab; + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + return &ioexp_map_magnolia_7ab; + case IOEXP_TYPE_REDWOOD_P01P08: + return &ioexp_map_redwood_p01p08_p17p24; + case IOEXP_TYPE_REDWOOD_P09P16: + return &ioexp_map_redwood_p09p16_p25p32; + case IOEXP_TYPE_HUDSON32IGA_P01P08: + return &ioexp_map_hudson32iga_p01p08_p17p24; + case IOEXP_TYPE_HUDSON32IGA_P09P16: + return &ioexp_map_hudson32iga_p09p16_p25p32; + case IOEXP_TYPE_CYPRESS_7ABC: + return &ioexp_map_cypress_7abc; + case IOEXP_TYPE_TAHOE_5A: + return &ioexp_map_tahoe_5a; + case IOEXP_TYPE_TAHOE_6ABC: + return &ioexp_map_tahoe_6abc; + case IOEXP_TYPE_SEQUOIA_NABC: + return &ioexp_map_sequoia_nabc; + case IOEXP_TYPE_LAVENDER_P65: + return &ioexp_map_lavender_p65; + case CPLD_TYPE_COTTONWOOD: + return &cpld_map_cottonwood; + case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_CEDAR_0ABC: + return &ioexp_map_maple_0abc; + case IOEXP_TYPE_MAPLE_NABC: + return &ioexp_map_maple_nabc; + case IOEXP_TYPE_GULMOHAR_NABC: + return &ioexp_map_gulmohar_nabc; + case IOEXP_TYPE_GULMOHAR_7ABC: + return &ioexp_map_gulmohar_7abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + return &ioexp_map_gulmohar_2t_evt1_nabc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + return &ioexp_map_gulmohar_2t_evt1_1abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + return &ioexp_map_gulmohar_2t_evt1_3abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + return &ioexp_map_gulmohar_2t_evt1_7abc; + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + return &ioexp_map_sfp_8p_layout_1; + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + return &ioexp_map_6p_qsfp_type_1; + default: + return NULL; + } +} + + +int +setup_ioexp_ssize_attr(struct ioexp_obj_s *self, + struct ioexp_map_s *ioexp_map_p, + int ioexp_id, + int ioexp_type, + int run_mode){ + switch (run_mode){ + case IOEXP_MODE_POLLING: /* Direct access device mode */ + case IOEXP_MODE_DIRECT: /* Polling mode, read from cache */ + self->mode = run_mode; + break; + default: + SWPS_ERR("%s: non-defined run_mode:%d\n", + __func__, run_mode); + self->mode = ERR_IOEXP_UNEXCPT; + return ERR_IOEXP_UNEXCPT; + } + /* Setup mapping structure */ + self->ioexp_map_p = kzalloc(sizeof(*ioexp_map_p), GFP_KERNEL); + if (!(self->ioexp_map_p)) { + SWPS_ERR("%s: kzalloc ioexp_map_p fail\n", __func__); + return -1; + } + memcpy(self->ioexp_map_p, ioexp_map_p, sizeof(*ioexp_map_p)); + /* Setup attributes */ + self->ioexp_id = ioexp_id; + self->ioexp_type = ioexp_type; + self->state = STATE_IOEXP_INIT; + mutex_init(&self->lock); + return 0; +} + + +static int +setup_addr_mapping(struct ioexp_obj_s *self, + struct ioexp_addr_s *addr_map_p, + int chip_amount){ + struct ioexp_addr_s *tmp_p; + if (!addr_map_p){ + SWPS_ERR("%s: map is null\n", __func__); + return -1; + } + tmp_p = kzalloc((sizeof(*addr_map_p) * chip_amount), GFP_KERNEL); + if (!tmp_p){ + SWPS_ERR("%s: kzalloc fail.\n", __func__); + return -1; + } + memcpy(tmp_p, addr_map_p, (sizeof(*addr_map_p) * chip_amount)); + self->ioexp_map_p->map_addr = tmp_p; + + return 0; +} + + +static int +setup_ioexp_public_cb(struct ioexp_obj_s *self, + int ioexp_type){ + + switch (ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + case IOEXP_TYPE_MAGINOLIA_4AB: + case CPLD_TYPE_COTTONWOOD: + self->get_present = common_get_present; + self->get_tx_fault = common_get_tx_fault; + self->get_rxlos = common_get_rxlos; + self->get_tx_disable = common_get_tx_disable; + self->get_reset = ioexp_get_not_support; + self->get_lpmod = ioexp_get_not_support; + self->get_modsel = ioexp_get_not_support; + self->get_hard_rs0 = ioexp_get_not_support; + self->get_hard_rs1 = ioexp_get_not_support; + self->set_tx_disable = common_set_tx_disable; + self->set_reset = ioexp_set_not_support; + self->set_lpmod = ioexp_set_not_support; + self->set_modsel = ioexp_set_not_support; + self->set_hard_rs0 = ioexp_set_not_support; + self->set_hard_rs1 = ioexp_set_not_support; + return 0; + + case IOEXP_TYPE_MAPLE_NABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + self->get_present = common_get_present; + self->get_tx_fault = common_get_tx_fault; + self->get_rxlos = common_get_rxlos; + self->get_tx_disable = common_get_tx_disable; + self->get_reset = ioexp_get_not_support; + self->get_lpmod = ioexp_get_not_support; + self->get_modsel = ioexp_get_not_support; + self->get_hard_rs0 = common_get_hard_rs0; + self->get_hard_rs1 = common_get_hard_rs1; + self->set_tx_disable = common_set_tx_disable; + self->set_reset = ioexp_set_not_support; + self->set_lpmod = ioexp_set_not_support; + self->set_modsel = ioexp_set_not_support; + self->set_hard_rs0 = common_set_hard_rs0; + self->set_hard_rs1 = common_set_hard_rs1; + return 0; + + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + case IOEXP_TYPE_REDWOOD_P01P08: + case IOEXP_TYPE_REDWOOD_P09P16: + case IOEXP_TYPE_HUDSON32IGA_P01P08: + case IOEXP_TYPE_HUDSON32IGA_P09P16: + case IOEXP_TYPE_CYPRESS_7ABC: + case IOEXP_TYPE_TAHOE_5A: + case IOEXP_TYPE_TAHOE_6ABC: + case IOEXP_TYPE_SEQUOIA_NABC: + case IOEXP_TYPE_LAVENDER_P65: + case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + case IOEXP_TYPE_CEDAR_0ABC: + self->get_present = common_get_present; + self->get_tx_fault = ioexp_get_not_support; + self->get_rxlos = ioexp_get_not_support; + self->get_tx_disable = ioexp_get_not_support; + self->get_reset = common_get_reset; + self->get_lpmod = common_get_lpmod; + self->get_modsel = common_get_modsel; + self->get_hard_rs0 = ioexp_get_not_support; + self->get_hard_rs1 = ioexp_get_not_support; + self->set_tx_disable = ioexp_set_not_support; + self->set_reset = common_set_reset; + self->set_lpmod = common_set_lpmod; + self->set_modsel = common_set_modsel; + self->set_hard_rs0 = ioexp_set_not_support; + self->set_hard_rs1 = ioexp_set_not_support; + return 0; + + default: + SWPS_ERR("%s: type:%d incorrect!\n", __func__, ioexp_type); + break; + } + return ERR_IOEXP_UNEXCPT; +} + + +static int +setup_ioexp_private_cb(struct ioexp_obj_s *self, + int ioexp_type){ + + switch (ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + case IOEXP_TYPE_MAGINOLIA_4AB: + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + case IOEXP_TYPE_REDWOOD_P01P08: + case IOEXP_TYPE_REDWOOD_P09P16: + case IOEXP_TYPE_HUDSON32IGA_P01P08: + case IOEXP_TYPE_HUDSON32IGA_P09P16: + case IOEXP_TYPE_CYPRESS_7ABC: + case IOEXP_TYPE_TAHOE_5A: + case IOEXP_TYPE_TAHOE_6ABC: + case IOEXP_TYPE_SEQUOIA_NABC: + case IOEXP_TYPE_LAVENDER_P65: + case CPLD_TYPE_COTTONWOOD: + case IOEXP_TYPE_MAPLE_NABC: + case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + case IOEXP_TYPE_CEDAR_0ABC: + self->init = common_ioexp_init; + self->check = common_ioexp_check; + self->update_all = common_ioexp_update_all; + self->fsm_4_direct = common_ioexp_fsm_4_direct; + self->fsm_4_polling = common_ioexp_fsm_4_polling; + return 0; + + default: + SWPS_ERR("%s: type:%d incorrect!\n", __func__, ioexp_type); + break; + } + return ERR_IOEXP_UNEXCPT; +} + + +static int +setup_i2c_client_one(struct ioexp_obj_s *self, + int chip_id){ + + char *err_msg = "ERROR"; + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + struct ioexp_i2c_s *i2c_obj_p = NULL; + struct ioexp_i2c_s *i2c_curr_p = NULL; + + int chan_id = self->ioexp_map_p->map_addr[chip_id].chan_id; + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client){ + err_msg = "Can not kzalloc client!"; + goto err_ioexp_setup_i2c_1; + } + i2c_obj_p = kzalloc(sizeof(*i2c_obj_p), GFP_KERNEL); + if (!i2c_obj_p){ + err_msg = "Can not kzalloc i2c_obj_p!"; + goto err_ioexp_setup_i2c_2; + } + adap = i2c_get_adapter(chan_id); + if(!adap){ + err_msg = "Can not get adap!"; + goto err_ioexp_setup_i2c_3; + } + client->adapter = adap; + client->addr = self->ioexp_map_p->map_addr[chip_id].chip_addr; + i2c_obj_p->i2c_client_p = client; + i2c_obj_p->chip_id = chip_id; + i2c_obj_p->next = NULL; + if (!self->i2c_head_p){ + self->i2c_head_p = i2c_obj_p; + } else { + i2c_curr_p = self->i2c_head_p; + while (i2c_curr_p->next){ + i2c_curr_p = i2c_curr_p->next; + } + i2c_curr_p->next = i2c_obj_p; + } + return 0; + +err_ioexp_setup_i2c_3: + kfree(i2c_obj_p); +err_ioexp_setup_i2c_2: + kfree(client); +err_ioexp_setup_i2c_1: + SWPS_ERR("%s: %s :%d\n", __func__, err_msg, chan_id); + return -1; +} + + +static int +setup_i2c_client(struct ioexp_obj_s* self){ + + int result; + int chip_id = 0; + + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ + result = setup_i2c_client_one(self, chip_id); + if (result < 0){ + SWPS_ERR("%s fail! :%d\n", __func__, chip_id); + return -1; + } + } + return 0; +} + + +static int +setup_ioexp_config(struct ioexp_obj_s *self) { + + int chip_id, offset, err_code; + struct ioexp_addr_s *addr_p; + if (io_no_init) { + + SWPS_INFO("io_no_init:%d \n", io_no_init); + return 0; + } + + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + if (!addr_p){ + SWPS_ERR("IOEXP config incorrect! :%d \n",chip_id); + return -1; + } + for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){ + + /* [Desc] Skip the setup config value behavior + [Note] Setup config value = -1 if you don't want to write the value to IOEXP or CPLD + */ + if(addr_p->conf_offset[offset] < 0){ + SWPS_DEBUG("skip a config_offset <%d>\n", addr_p->conf_offset[offset]); + continue; + } + err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id), + addr_p->conf_offset[offset], + addr_p->conf_default[offset]); + + if (err_code < 0){ + SWPS_INFO("%s: set conf fail! :%d \n", __func__, err_code); + return -2; + } + } + } + return 0; +} + + +struct ioexp_obj_s * +_create_ioexp_obj(int ioexp_id, + int ioexp_type, + struct ioexp_addr_s *addr_map_p, + int run_mode){ + + struct ioexp_map_s* ioexp_map_p; + struct ioexp_obj_s* result_p; + struct ioexp_i2c_s *i2c_curr_p; + struct ioexp_i2c_s *i2c_next_p; + + /* Get layout */ + ioexp_map_p = get_ioexp_map(ioexp_type); + if (!ioexp_map_p){ + SWPS_ERR("%s: Invalid ioexp_type\n", __func__); + goto err_create_ioexp_fail; + } + /* Prepare IOEXP object */ + result_p = kzalloc(sizeof(*result_p), GFP_KERNEL); + if (!result_p){ + SWPS_ERR("%s: kzalloc failure!\n", __func__); + goto err_create_ioexp_fail; + } + /* Prepare static size attributes */ + if (setup_ioexp_ssize_attr(result_p, + ioexp_map_p, + ioexp_id, + ioexp_type, + run_mode) < 0){ + goto err_create_ioexp_setup_attr_fail; + } + /* Prepare address mapping */ + if (setup_addr_mapping(result_p, addr_map_p, ioexp_map_p->chip_amount) < 0){ + goto err_create_ioexp_setup_attr_fail; + } + if (setup_i2c_client(result_p) < 0){ + goto err_create_ioexp_setup_i2c_fail; + } + /* Prepare call back functions of object */ + if (setup_ioexp_public_cb(result_p, ioexp_type) < 0){ + goto err_create_ioexp_setup_i2c_fail; + } + if (setup_ioexp_private_cb(result_p, ioexp_type) < 0){ + goto err_create_ioexp_setup_i2c_fail; + } + return result_p; + +err_create_ioexp_setup_i2c_fail: + i2c_curr_p = result_p->i2c_head_p; + i2c_next_p = result_p->i2c_head_p; + while (i2c_curr_p){ + i2c_next_p = i2c_curr_p->next; + if (i2c_curr_p->i2c_client_p) { + i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter); + kfree(i2c_curr_p->i2c_client_p); + } + kfree(i2c_curr_p); + i2c_curr_p = i2c_next_p; + } +err_create_ioexp_setup_attr_fail: + kfree(result_p); +err_create_ioexp_fail: + SWPS_ERR("%s: fail! :%d :%d \n", + __func__, ioexp_id, ioexp_type); + return NULL; +} + + +int +create_ioexp_obj(int ioexp_id, + int ioexp_type, + struct ioexp_addr_s *addr_map_p, + int run_mode){ + + struct ioexp_obj_s *ioexp_p = NULL; + + ioexp_p = _create_ioexp_obj(ioexp_id, ioexp_type, + addr_map_p, run_mode); + if (!ioexp_p){ + return -1; + } + if (ioexp_head_p == NULL){ + ioexp_head_p = ioexp_p; + ioexp_tail_p = ioexp_p; + return 0; + } + ioexp_tail_p->next = ioexp_p; + ioexp_tail_p = ioexp_p; + return 0; +} +EXPORT_SYMBOL(create_ioexp_obj); + + +static int +_init_ioexp_obj(struct ioexp_obj_s* self) { + + char *err_msg = "ERR"; + char *func_name = "_init_ioexp_obj"; + + /* Setup IOEXP configure byte */ + if (setup_ioexp_config(self) < 0){ + err_msg = "setup_ioexp_config fail"; + goto err_init_ioexp_obj; + } + /* Setup default data */ + if (_ioexp_init_handler(self) < 0){ + err_msg = "_ioexp_init_handler fail"; + goto err_init_ioexp_obj; + } + /* Update all */ + if (self->state == STATE_IOEXP_NORMAL){ + if (self->update_all(self, 1, func_name) < 0){ + err_msg = "update_all() fail"; + goto err_init_ioexp_obj; + } + } + return 0; + +err_init_ioexp_obj: + SWPS_DEBUG("%s: %s\n", __func__, err_msg); + return -1; +} + + +int +init_ioexp_objs(void){ + /* Return value: + * 0: Success + * -1: Detect topology error + * -2: SWPS internal error + */ + struct ioexp_obj_s *curr_p = ioexp_head_p; + + if (!curr_p) { + SWPS_ERR("%s: ioexp_head_p is NULL\n", __func__); + return -2; + } + while (curr_p) { + if (_init_ioexp_obj(curr_p) < 0) { + SWPS_DEBUG("%s: _init_ioexp_obj() fail\n", __func__); + return -1; + } + curr_p = curr_p->next; + } + SWPS_DEBUG("%s: done.\n", __func__); + return 0; +} +EXPORT_SYMBOL(init_ioexp_objs); + + +void +clean_ioexp_objs(void){ + + struct ioexp_i2c_s *i2c_curr_p = NULL; + struct ioexp_i2c_s *i2c_next_p = NULL; + struct ioexp_obj_s *ioexp_next_p = NULL; + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + if (ioexp_head_p == NULL){ + ioexp_tail_p = NULL; + return; + } + while(ioexp_curr_p){ + ioexp_next_p = ioexp_curr_p->next; + if (ioexp_curr_p->ioexp_map_p) { + if (ioexp_curr_p->ioexp_map_p->map_addr) { + kfree(ioexp_curr_p->ioexp_map_p->map_addr); + } + kfree(ioexp_curr_p->ioexp_map_p); + } + + i2c_curr_p = ioexp_curr_p->i2c_head_p; + while (i2c_curr_p) { + i2c_next_p = i2c_curr_p->next; + if (i2c_curr_p->i2c_client_p) { + i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter); + kfree(i2c_curr_p->i2c_client_p); + } + kfree(i2c_curr_p); + i2c_curr_p = i2c_next_p; + } + kfree(ioexp_curr_p); + ioexp_curr_p = ioexp_next_p; + } + ioexp_tail_p = NULL; + SWPS_DEBUG("%s: done.\n", __func__); +} +EXPORT_SYMBOL(clean_ioexp_objs); + + +int +check_ioexp_objs(void){ + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while (ioexp_curr_p){ + if ( (ioexp_curr_p->check(ioexp_curr_p)) < 0){ + SWPS_INFO("check IOEXP-%d fail! :%d\n", + ioexp_curr_p->ioexp_id, ioexp_curr_p->ioexp_type); + return -1; + } + ioexp_curr_p = ioexp_curr_p->next; + } + return 0; +} +EXPORT_SYMBOL(check_ioexp_objs); + + +struct ioexp_obj_s * +get_ioexp_obj(int ioexp_id){ + + struct ioexp_obj_s *result_p = NULL; + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while(ioexp_curr_p){ + if (ioexp_curr_p->ioexp_id == ioexp_id){ + result_p = ioexp_curr_p; + break; + } + ioexp_curr_p = ioexp_curr_p->next; + } + return result_p; +} +EXPORT_SYMBOL(get_ioexp_obj); + + +void +unlock_ioexp_all(void) { + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while(ioexp_curr_p){ + mutex_unlock(&ioexp_curr_p->lock); + ioexp_curr_p = ioexp_curr_p->next; + } +} +EXPORT_SYMBOL(unlock_ioexp_all); + +int +lock_ioexp_all(void) { + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while(ioexp_curr_p){ + mutex_lock(&ioexp_curr_p->lock); + ioexp_curr_p = ioexp_curr_p->next; + } + return 0; +} +EXPORT_SYMBOL(lock_ioexp_all); + + +int +check_channel_tier_1(void) { + + if ( (!_is_channel_ready(ioexp_head_p)) && + (!_is_channel_ready(ioexp_tail_p)) ){ + return -1; + } + return 0; +} +EXPORT_SYMBOL(check_channel_tier_1); + + +static int +_scan_channel_tier_1(int force, + int show_err) { + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + int ready = 0; + + if (!ioexp_curr_p) { + goto err_scan_tier_1_channel; + } + while(ioexp_curr_p) { + ready = _is_channel_ready(ioexp_curr_p); + if ((!ready) && (!force)) { + goto err_scan_tier_1_channel; + } + ioexp_curr_p = ioexp_curr_p->next; + } + return 0; + +err_scan_tier_1_channel: + if (show_err) { + if (ioexp_curr_p) { + SWPS_INFO("%s: IOEXP-%d fail\n", __func__, ioexp_curr_p->ioexp_id); + } else { + SWPS_INFO("%s: IOEXP is null.\n", __func__); + } + } + return -1; +} + + +static int +_scan_channel_tier_1_single(void) { + + int ret = 0; + int chan_id = 0; + int fake_cid = 0; + int fake_offs = 0; + int fake_addr = 0; + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + + if (ioexp_head_p->ioexp_id != ioexp_tail_p->ioexp_id) { + return 0; + } + /* Setup i2c_client */ + chan_id = ioexp_head_p->ioexp_map_p->map_addr[fake_cid].chan_id; + fake_addr = ioexp_head_p->ioexp_map_p->map_addr[fake_cid].chip_addr; + adap = i2c_get_adapter((chan_id + 1)); + if(!adap){ + SWPS_INFO("%s: Can not get adap!\n", __func__); + return 0; + } + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client){ + SWPS_INFO("%s: Can not kzalloc client!\n", __func__); + return 0; + } + client->adapter = adap; + client->addr = fake_addr; + /* Fouce move ioexp ptr to next */ + ret = i2c_smbus_read_byte_data(client, fake_offs); + SWPS_DEBUG("%s: move ioexp_ptr done. :%d\n", __func__, ret); + kfree(client); + return 1; +} + + +int +resync_channel_tier_1(void) { + + char *emsg = "ERR"; + + if (!ioexp_head_p) { + emsg = "ioexp_head_p is NULL"; + goto err_resync_ioexp_status_1; + } + /* Run all */ + if (ioexp_head_p->ioexp_id == ioexp_tail_p->ioexp_id) { + _scan_channel_tier_1_single(); + } else { + _scan_channel_tier_1(1, 0); + } + /* Check all */ + if (_scan_channel_tier_1(0, 1) < 0) { + emsg = "resync tier-1 channel fail"; + goto err_resync_ioexp_status_1; + } + return 0; + +err_resync_ioexp_status_1: + SWPS_ERR("%s: %s\n", __func__, emsg); + return -1; +} +EXPORT_SYMBOL(resync_channel_tier_1); + + +/* For build single module using (Ex: ONL platform) */ +MODULE_LICENSE("GPL"); + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.h b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.h new file mode 100644 index 000000000000..43a8c290f5da --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.h @@ -0,0 +1,189 @@ +#ifndef IO_EXPANDER_H +#define IO_EXPANDER_H + +#include + + +/* IOEXP type define (SFP series) */ +#define IOEXP_TYPE_MAGINOLIA_NAB (10101) +#define IOEXP_TYPE_MAGINOLIA_4AB (10102) +#define IOEXP_TYPE_MAPLE_NABC (10104) +#define IOEXP_TYPE_GULMOHAR_NABC (10105) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC (10106) +#define IOEXP_TYPE_SFP_8P_LAYOUT_1 (10107) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC (10108) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC (10109) + +/* IOEXP type define (QSFP series) */ +#define IOEXP_TYPE_MAGINOLIA_7AB (10201) +#define IOEXP_TYPE_REDWOOD_P01P08 (10202) +#define IOEXP_TYPE_REDWOOD_P09P16 (10203) +#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204) +#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205) +#define IOEXP_TYPE_SPRUCE_7AB (10206) +#define IOEXP_TYPE_CYPRESS_7ABC (10207) +#define IOEXP_TYPE_TAHOE_5A (10208) +#define IOEXP_TYPE_TAHOE_6ABC (10209) +#define IOEXP_TYPE_SEQUOIA_NABC (10210) +#define IOEXP_TYPE_LAVENDER_P65 (10211) +#define IOEXP_TYPE_MAPLE_0ABC (10212) +#define IOEXP_TYPE_GULMOHAR_7ABC (10213) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC (10214) +#define IOEXP_TYPE_QSFP_6P_LAYOUT_1 (10215) +#define IOEXP_TYPE_CEDAR_0ABC (10216) + +/* CPLD type define */ +#define CPLD_TYPE_COTTONWOOD (10301) + +/* IOEXP mode define */ +#define IOEXP_MODE_POLLING (19000) +#define IOEXP_MODE_DIRECT (19001) + +/* IOEXP state define */ +#define STATE_IOEXP_NORMAL (0) +#define STATE_IOEXP_INIT (-1) +#define STATE_IOEXP_ABNORMAL (-2) + +/* IOEXP error code define */ +#define ERR_IOEXP_NOTSUPPORT (-100) +#define ERR_IOEXP_UNINIT (-101) +#define ERR_IOEXP_BADCONF (-102) +#define ERR_IOEXP_ABNORMAL (-103) +#define ERR_IOEXP_NOSTATE (-104) +#define ERR_IOEXP_BADINPUT (-105) +#define ERR_IOEXP_UNEXCPT (-199) + +#define SWPS_INFO(fmt, args...) printk( KERN_INFO "[SWPS] " fmt, ##args) +#define SWPS_WARN(fmt, args...) printk( KERN_WARNING "[SWPS] " fmt, ##args) +#define SWPS_ERR(fmt, args...) printk( KERN_ERR "[SWPS] " fmt, ##args) + +#ifdef DEBUG_SWPS +# define SWPS_DEBUG(fmt, args...) printk( KERN_DEBUG "[SWPS] " fmt, ##args) +#else +# define SWPS_DEBUG(fmt, args...) +#endif + +struct ioexp_addr_s { + int chan_id; + int chip_addr; + int read_offset[8]; + int write_offset[8]; + int conf_offset[8]; + uint8_t data_default[8]; + uint8_t conf_default[8]; +}; + +struct ioexp_i2c_s { + int chip_id; + struct i2c_client *i2c_client_p; + struct ioexp_i2c_s *next; +}; + + +struct ioexp_bitmap_s { + int chip_id; /* IOEXP chip id */ + int ioexp_voffset; /* IOEXP virtual offset */ + int bit_shift; +}; + +struct ioexp_map_s { + int chip_amount; /* Number of chips that IOEXP object content */ + int data_width; /* Number of (Read/Write/Config) bytes */ + struct ioexp_addr_s *map_addr; /* Chip address info */ + struct ioexp_bitmap_s map_present[10]; /* IOEXP for SFP / QSFP */ + struct ioexp_bitmap_s map_tx_disable[10]; /* IOEXP for SFP */ + struct ioexp_bitmap_s map_tx_fault[10]; /* IOEXP for SFP */ + struct ioexp_bitmap_s map_rxlos[10]; /* IOEXP for SFP */ + struct ioexp_bitmap_s map_reset[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_lpmod[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_modsel[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_hard_rs0[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_hard_rs1[10]; /* IOEXP for QSFP */ +}; + +struct ioexp_data_s { + uint8_t data[8]; +}; + +struct ioexp_obj_s { + + /* ============================ + * Object public property + * ============================ + */ + int ioexp_id; + int ioexp_type; + + /* ============================ + * Object private property + * ============================ + */ + struct ioexp_data_s chip_data[16]; /* Max: 8-ioexp in one virt-ioexp(ioexp_obj) */ + struct ioexp_map_s *ioexp_map_p; + struct ioexp_obj_s *next; + struct ioexp_i2c_s *i2c_head_p; + struct mutex lock; + int mode; + int state; + + /* =========================================== + * Object public functions + * =========================================== + */ + int (*get_present)(struct ioexp_obj_s *self, int virt_offset); + int (*get_tx_fault)(struct ioexp_obj_s *self, int virt_offset); + int (*get_rxlos)(struct ioexp_obj_s *self, int virt_offset); + int (*get_tx_disable)(struct ioexp_obj_s *self, int virt_offset); + int (*get_reset)(struct ioexp_obj_s *self, int virt_offset); + int (*get_lpmod)(struct ioexp_obj_s *self, int virt_offset); + int (*get_modsel)(struct ioexp_obj_s *self, int virt_offset); + int (*get_hard_rs0)(struct ioexp_obj_s *self, int virt_offset); + int (*get_hard_rs1)(struct ioexp_obj_s *self, int virt_offset); + int (*set_tx_disable)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_reset)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_lpmod)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_modsel)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_hard_rs0)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_hard_rs1)(struct ioexp_obj_s *self, int virt_offset, int input_val); + + /* =========================================== + * Object private functions + * =========================================== + */ + int (*init)(struct ioexp_obj_s *self); + int (*check)(struct ioexp_obj_s *self); + int (*update_all)(struct ioexp_obj_s *self, int show_err, char *caller_name); + int (*fsm_4_direct)(struct ioexp_obj_s* self); + int (*fsm_4_polling)(struct ioexp_obj_s* self); +}; + + +struct ioexp_obj_s* get_ioexp_obj(int ioexp_id); +int create_ioexp_obj(int ioexp_id, + int ioexp_type, + struct ioexp_addr_s *addr_map_p, + int run_mode); +int init_ioexp_objs(void); +int check_ioexp_objs(void); +void clean_ioexp_objs(void); + +void unlock_ioexp_all(void); +int lock_ioexp_all(void); + +int check_channel_tier_1(void); +int resync_channel_tier_1(void); + +/* Macro for bit control */ +#define SWP_BIT_SET(byte_val,bit_shift) ((byte_val) |= (1<<(bit_shift))) +#define SWP_BIT_CLEAR(byte_val,bit_shift) ((byte_val) &= ~(1<<(bit_shift))) + + +#endif /* IO_EXPANDER_H */ + + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/lpc_ich.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/lpc_ich.c new file mode 100644 index 000000000000..21e4824d6e33 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/lpc_ich.c @@ -0,0 +1,1149 @@ +/* + * lpc_ich.c - LPC interface for Intel ICH + * + * LPC bridge function of the Intel ICH contains many other + * functional units, such as Interrupt controllers, Timers, + * Power Management, System Management, GPIO, RTC, and LPC + * Configuration Registers. + * + * This driver is derived from lpc_sch. + + * Copyright (c) 2011 Extreme Engineering Solution, Inc. + * Author: Aaron Sierra + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This driver supports the following I/O Controller hubs: + * (See the intel documentation on http://developer.intel.com.) + * document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO) + * document number 290687-002, 298242-027: 82801BA (ICH2) + * document number 290733-003, 290739-013: 82801CA (ICH3-S) + * document number 290716-001, 290718-007: 82801CAM (ICH3-M) + * document number 290744-001, 290745-025: 82801DB (ICH4) + * document number 252337-001, 252663-008: 82801DBM (ICH4-M) + * document number 273599-001, 273645-002: 82801E (C-ICH) + * document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R) + * document number 300641-004, 300884-013: 6300ESB + * document number 301473-002, 301474-026: 82801F (ICH6) + * document number 313082-001, 313075-006: 631xESB, 632xESB + * document number 307013-003, 307014-024: 82801G (ICH7) + * document number 322896-001, 322897-001: NM10 + * document number 313056-003, 313057-017: 82801H (ICH8) + * document number 316972-004, 316973-012: 82801I (ICH9) + * document number 319973-002, 319974-002: 82801J (ICH10) + * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) + * document number 320066-003, 320257-008: EP80597 (IICH) + * document number 324645-001, 324646-001: Cougar Point (CPT) + * document number TBD : Patsburg (PBG) + * document number TBD : DH89xxCC + * document number TBD : Panther Point + * document number TBD : Lynx Point + * document number TBD : Lynx Point-LP + * document number TBD : Wellsburg + * document number TBD : Avoton SoC + * document number TBD : Coleto Creek + * document number TBD : Wildcat Point-LP + * document number TBD : 9 Series + * document number TBD : Lewisburg + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACPIBASE 0x40 +#define ACPIBASE_GPE_OFF 0x28 +#define ACPIBASE_GPE_END 0x2f +#define ACPIBASE_SMI_OFF 0x30 +#define ACPIBASE_SMI_END 0x33 +#define ACPIBASE_PMC_OFF 0x08 +#define ACPIBASE_PMC_END 0x0c +#define ACPIBASE_TCO_OFF 0x60 +#define ACPIBASE_TCO_END 0x7f +#define ACPICTRL_PMCBASE 0x44 + +#define ACPIBASE_GCS_OFF 0x3410 +#define ACPIBASE_GCS_END 0x3414 + +#define GPIOBASE_ICH0 0x58 +#define GPIOCTRL_ICH0 0x5C +#define GPIOBASE_ICH6 0x48 +#define GPIOCTRL_ICH6 0x4C + +#define RCBABASE 0xf0 + +#define wdt_io_res(i) wdt_res(0, i) +#define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) +#define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) + +struct lpc_ich_priv { + int chipset; + + int abase; /* ACPI base */ + int actrl_pbase; /* ACPI control or PMC base */ + int gbase; /* GPIO base */ + int gctrl; /* GPIO control */ + + int abase_save; /* Cached ACPI base value */ + int actrl_pbase_save; /* Cached ACPI control or PMC base value */ + int gctrl_save; /* Cached GPIO control value */ +}; + +static struct resource wdt_ich_res[] = { + /* ACPI - TCO */ + { + .flags = IORESOURCE_IO, + }, + /* ACPI - SMI */ + { + .flags = IORESOURCE_IO, + }, + /* GCS or PMC */ + { + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource gpio_ich_res[] = { + /* GPIO */ + { + .flags = IORESOURCE_IO, + }, + /* ACPI - GPE0 */ + { + .flags = IORESOURCE_IO, + }, +}; + +static struct mfd_cell lpc_ich_wdt_cell = { + .name = "iTCO_wdt", + .num_resources = ARRAY_SIZE(wdt_ich_res), + .resources = wdt_ich_res, + .ignore_resource_conflicts = true, +}; + +static struct mfd_cell lpc_ich_gpio_cell = { + .name = "gpio_ich", + .num_resources = ARRAY_SIZE(gpio_ich_res), + .resources = gpio_ich_res, + .ignore_resource_conflicts = true, +}; + +/* chipset related info */ +enum lpc_chipsets { + LPC_ICH = 0, /* ICH */ + LPC_ICH0, /* ICH0 */ + LPC_ICH2, /* ICH2 */ + LPC_ICH2M, /* ICH2-M */ + LPC_ICH3, /* ICH3-S */ + LPC_ICH3M, /* ICH3-M */ + LPC_ICH4, /* ICH4 */ + LPC_ICH4M, /* ICH4-M */ + LPC_CICH, /* C-ICH */ + LPC_ICH5, /* ICH5 & ICH5R */ + LPC_6300ESB, /* 6300ESB */ + LPC_ICH6, /* ICH6 & ICH6R */ + LPC_ICH6M, /* ICH6-M */ + LPC_ICH6W, /* ICH6W & ICH6RW */ + LPC_631XESB, /* 631xESB/632xESB */ + LPC_ICH7, /* ICH7 & ICH7R */ + LPC_ICH7DH, /* ICH7DH */ + LPC_ICH7M, /* ICH7-M & ICH7-U */ + LPC_ICH7MDH, /* ICH7-M DH */ + LPC_NM10, /* NM10 */ + LPC_ICH8, /* ICH8 & ICH8R */ + LPC_ICH8DH, /* ICH8DH */ + LPC_ICH8DO, /* ICH8DO */ + LPC_ICH8M, /* ICH8M */ + LPC_ICH8ME, /* ICH8M-E */ + LPC_ICH9, /* ICH9 */ + LPC_ICH9R, /* ICH9R */ + LPC_ICH9DH, /* ICH9DH */ + LPC_ICH9DO, /* ICH9DO */ + LPC_ICH9M, /* ICH9M */ + LPC_ICH9ME, /* ICH9M-E */ + LPC_ICH10, /* ICH10 */ + LPC_ICH10R, /* ICH10R */ + LPC_ICH10D, /* ICH10D */ + LPC_ICH10DO, /* ICH10DO */ + LPC_PCH, /* PCH Desktop Full Featured */ + LPC_PCHM, /* PCH Mobile Full Featured */ + LPC_P55, /* P55 */ + LPC_PM55, /* PM55 */ + LPC_H55, /* H55 */ + LPC_QM57, /* QM57 */ + LPC_H57, /* H57 */ + LPC_HM55, /* HM55 */ + LPC_Q57, /* Q57 */ + LPC_HM57, /* HM57 */ + LPC_PCHMSFF, /* PCH Mobile SFF Full Featured */ + LPC_QS57, /* QS57 */ + LPC_3400, /* 3400 */ + LPC_3420, /* 3420 */ + LPC_3450, /* 3450 */ + LPC_EP80579, /* EP80579 */ + LPC_CPT, /* Cougar Point */ + LPC_CPTD, /* Cougar Point Desktop */ + LPC_CPTM, /* Cougar Point Mobile */ + LPC_PBG, /* Patsburg */ + LPC_DH89XXCC, /* DH89xxCC */ + LPC_PPT, /* Panther Point */ + LPC_LPT, /* Lynx Point */ + LPC_LPT_LP, /* Lynx Point-LP */ + LPC_WBG, /* Wellsburg */ + LPC_AVN, /* Avoton SoC */ + LPC_BAYTRAIL, /* Bay Trail SoC */ + LPC_COLETO, /* Coleto Creek */ + LPC_WPT_LP, /* Wildcat Point-LP */ + LPC_BRASWELL, /* Braswell SoC */ + LPC_LEWISBURG, /* Lewisburg */ + LPC_9S, /* 9 Series */ + LPC_APL, /* Apollo Lake SoC */ + LPC_GLK, /* Gemini Lake SoC */ + LPC_COUGARMOUNTAIN,/* Cougar Mountain SoC*/ +}; + +static struct lpc_ich_info lpc_chipset_info[] = { + [LPC_ICH] = { + .name = "ICH", + .iTCO_version = 1, + }, + [LPC_ICH0] = { + .name = "ICH0", + .iTCO_version = 1, + }, + [LPC_ICH2] = { + .name = "ICH2", + .iTCO_version = 1, + }, + [LPC_ICH2M] = { + .name = "ICH2-M", + .iTCO_version = 1, + }, + [LPC_ICH3] = { + .name = "ICH3-S", + .iTCO_version = 1, + }, + [LPC_ICH3M] = { + .name = "ICH3-M", + .iTCO_version = 1, + }, + [LPC_ICH4] = { + .name = "ICH4", + .iTCO_version = 1, + }, + [LPC_ICH4M] = { + .name = "ICH4-M", + .iTCO_version = 1, + }, + [LPC_CICH] = { + .name = "C-ICH", + .iTCO_version = 1, + }, + [LPC_ICH5] = { + .name = "ICH5 or ICH5R", + .iTCO_version = 1, + }, + [LPC_6300ESB] = { + .name = "6300ESB", + .iTCO_version = 1, + }, + [LPC_ICH6] = { + .name = "ICH6 or ICH6R", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH6M] = { + .name = "ICH6-M", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH6W] = { + .name = "ICH6W or ICH6RW", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_631XESB] = { + .name = "631xESB/632xESB", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH7] = { + .name = "ICH7 or ICH7R", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7DH] = { + .name = "ICH7DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7M] = { + .name = "ICH7-M or ICH7-U", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7MDH] = { + .name = "ICH7-M DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_NM10] = { + .name = "NM10", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8] = { + .name = "ICH8 or ICH8R", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8DH] = { + .name = "ICH8DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8DO] = { + .name = "ICH8DO", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8M] = { + .name = "ICH8M", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8ME] = { + .name = "ICH8M-E", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH9] = { + .name = "ICH9", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9R] = { + .name = "ICH9R", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9DH] = { + .name = "ICH9DH", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9DO] = { + .name = "ICH9DO", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9M] = { + .name = "ICH9M", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9ME] = { + .name = "ICH9M-E", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH10] = { + .name = "ICH10", + .iTCO_version = 2, + .gpio_version = ICH_V10CONS_GPIO, + }, + [LPC_ICH10R] = { + .name = "ICH10R", + .iTCO_version = 2, + .gpio_version = ICH_V10CONS_GPIO, + }, + [LPC_ICH10D] = { + .name = "ICH10D", + .iTCO_version = 2, + .gpio_version = ICH_V10CORP_GPIO, + }, + [LPC_ICH10DO] = { + .name = "ICH10DO", + .iTCO_version = 2, + .gpio_version = ICH_V10CORP_GPIO, + }, + [LPC_PCH] = { + .name = "PCH Desktop Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PCHM] = { + .name = "PCH Mobile Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_P55] = { + .name = "P55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PM55] = { + .name = "PM55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_H55] = { + .name = "H55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_QM57] = { + .name = "QM57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_H57] = { + .name = "H57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_HM55] = { + .name = "HM55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_Q57] = { + .name = "Q57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_HM57] = { + .name = "HM57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PCHMSFF] = { + .name = "PCH Mobile SFF Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_QS57] = { + .name = "QS57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3400] = { + .name = "3400", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3420] = { + .name = "3420", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3450] = { + .name = "3450", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_EP80579] = { + .name = "EP80579", + .iTCO_version = 2, + }, + [LPC_CPT] = { + .name = "Cougar Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_CPTD] = { + .name = "Cougar Point Desktop", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_CPTM] = { + .name = "Cougar Point Mobile", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PBG] = { + .name = "Patsburg", + .iTCO_version = 2, + }, + [LPC_DH89XXCC] = { + .name = "DH89xxCC", + .iTCO_version = 2, + }, + [LPC_PPT] = { + .name = "Panther Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_LPT] = { + .name = "Lynx Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_LPT_LP] = { + .name = "Lynx Point_LP", + .iTCO_version = 2, + }, + [LPC_WBG] = { + .name = "Wellsburg", + .iTCO_version = 2, + }, + [LPC_AVN] = { + .name = "Avoton SoC", + .iTCO_version = 3, + .gpio_version = AVOTON_GPIO, + }, + [LPC_BAYTRAIL] = { + .name = "Bay Trail SoC", + .iTCO_version = 3, + }, + [LPC_COLETO] = { + .name = "Coleto Creek", + .iTCO_version = 2, + }, + [LPC_WPT_LP] = { + .name = "Wildcat Point_LP", + .iTCO_version = 2, + }, + [LPC_BRASWELL] = { + .name = "Braswell SoC", + .iTCO_version = 3, + }, + [LPC_LEWISBURG] = { + .name = "Lewisburg", + .iTCO_version = 2, + }, + [LPC_9S] = { + .name = "9 Series", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_APL] = { + .name = "Apollo Lake SoC", + .iTCO_version = 5, + }, + [LPC_GLK] = { + .name = "Gemini Lake SoC", + }, + [LPC_COUGARMOUNTAIN] = { + .name = "Cougar Mountain SoC", + .iTCO_version = 3, + }, +}; + +/* + * This data only exists for exporting the supported PCI ids + * via MODULE_DEVICE_TABLE. We do not actually register a + * pci_driver, because the I/O Controller Hub has also other + * functions that probably will be registered by other drivers. + */ +static const struct pci_device_id lpc_ich_ids[] = { + { PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL}, + { PCI_VDEVICE(INTEL, 0x1c41), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c42), LPC_CPTD}, + { PCI_VDEVICE(INTEL, 0x1c43), LPC_CPTM}, + { PCI_VDEVICE(INTEL, 0x1c44), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c45), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c46), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c47), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c48), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c49), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4a), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4b), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4c), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4d), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4e), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4f), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c50), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c51), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c52), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c53), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c54), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c55), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c56), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c57), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c58), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c59), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5a), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5b), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5c), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5d), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5e), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5f), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1d40), LPC_PBG}, + { PCI_VDEVICE(INTEL, 0x1d41), LPC_PBG}, + { PCI_VDEVICE(INTEL, 0x1e40), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e41), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e42), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e43), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e44), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e45), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e46), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e47), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e48), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e49), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4a), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4b), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4c), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4d), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4e), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4f), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e50), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e51), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e52), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e53), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e54), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e55), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e56), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e57), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e58), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e59), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5a), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5b), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5c), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5d), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5e), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5f), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1f38), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x229c), LPC_BRASWELL}, + { PCI_VDEVICE(INTEL, 0x2310), LPC_DH89XXCC}, + { PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO}, + { PCI_VDEVICE(INTEL, 0x2410), LPC_ICH}, + { PCI_VDEVICE(INTEL, 0x2420), LPC_ICH0}, + { PCI_VDEVICE(INTEL, 0x2440), LPC_ICH2}, + { PCI_VDEVICE(INTEL, 0x244c), LPC_ICH2M}, + { PCI_VDEVICE(INTEL, 0x2450), LPC_CICH}, + { PCI_VDEVICE(INTEL, 0x2480), LPC_ICH3}, + { PCI_VDEVICE(INTEL, 0x248c), LPC_ICH3M}, + { PCI_VDEVICE(INTEL, 0x24c0), LPC_ICH4}, + { PCI_VDEVICE(INTEL, 0x24cc), LPC_ICH4M}, + { PCI_VDEVICE(INTEL, 0x24d0), LPC_ICH5}, + { PCI_VDEVICE(INTEL, 0x25a1), LPC_6300ESB}, + { PCI_VDEVICE(INTEL, 0x2640), LPC_ICH6}, + { PCI_VDEVICE(INTEL, 0x2641), LPC_ICH6M}, + { PCI_VDEVICE(INTEL, 0x2642), LPC_ICH6W}, + { PCI_VDEVICE(INTEL, 0x2670), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2671), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2672), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2673), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2674), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2675), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2676), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2677), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2678), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2679), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267a), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267b), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267c), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267d), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267e), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267f), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x27b0), LPC_ICH7DH}, + { PCI_VDEVICE(INTEL, 0x27b8), LPC_ICH7}, + { PCI_VDEVICE(INTEL, 0x27b9), LPC_ICH7M}, + { PCI_VDEVICE(INTEL, 0x27bc), LPC_NM10}, + { PCI_VDEVICE(INTEL, 0x27bd), LPC_ICH7MDH}, + { PCI_VDEVICE(INTEL, 0x2810), LPC_ICH8}, + { PCI_VDEVICE(INTEL, 0x2811), LPC_ICH8ME}, + { PCI_VDEVICE(INTEL, 0x2812), LPC_ICH8DH}, + { PCI_VDEVICE(INTEL, 0x2814), LPC_ICH8DO}, + { PCI_VDEVICE(INTEL, 0x2815), LPC_ICH8M}, + { PCI_VDEVICE(INTEL, 0x2912), LPC_ICH9DH}, + { PCI_VDEVICE(INTEL, 0x2914), LPC_ICH9DO}, + { PCI_VDEVICE(INTEL, 0x2916), LPC_ICH9R}, + { PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME}, + { PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9}, + { PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M}, + { PCI_VDEVICE(INTEL, 0x3197), LPC_GLK}, + { PCI_VDEVICE(INTEL, 0x2b9c), LPC_COUGARMOUNTAIN}, + { PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO}, + { PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R}, + { PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10}, + { PCI_VDEVICE(INTEL, 0x3a1a), LPC_ICH10D}, + { PCI_VDEVICE(INTEL, 0x3b00), LPC_PCH}, + { PCI_VDEVICE(INTEL, 0x3b01), LPC_PCHM}, + { PCI_VDEVICE(INTEL, 0x3b02), LPC_P55}, + { PCI_VDEVICE(INTEL, 0x3b03), LPC_PM55}, + { PCI_VDEVICE(INTEL, 0x3b06), LPC_H55}, + { PCI_VDEVICE(INTEL, 0x3b07), LPC_QM57}, + { PCI_VDEVICE(INTEL, 0x3b08), LPC_H57}, + { PCI_VDEVICE(INTEL, 0x3b09), LPC_HM55}, + { PCI_VDEVICE(INTEL, 0x3b0a), LPC_Q57}, + { PCI_VDEVICE(INTEL, 0x3b0b), LPC_HM57}, + { PCI_VDEVICE(INTEL, 0x3b0d), LPC_PCHMSFF}, + { PCI_VDEVICE(INTEL, 0x3b0f), LPC_QS57}, + { PCI_VDEVICE(INTEL, 0x3b12), LPC_3400}, + { PCI_VDEVICE(INTEL, 0x3b14), LPC_3420}, + { PCI_VDEVICE(INTEL, 0x3b16), LPC_3450}, + { PCI_VDEVICE(INTEL, 0x5031), LPC_EP80579}, + { PCI_VDEVICE(INTEL, 0x5ae8), LPC_APL}, + { PCI_VDEVICE(INTEL, 0x8c40), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c41), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c42), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c43), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c44), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c45), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c46), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c47), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c48), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c49), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4a), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4b), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4c), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4d), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4e), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4f), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c50), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c51), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c52), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c53), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c54), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c55), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c56), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c57), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c58), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c59), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5a), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5b), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5c), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5d), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5e), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5f), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8cc1), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc2), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc3), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc4), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc6), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8d40), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d41), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d42), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d43), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d44), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d45), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d46), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d47), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d48), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d49), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4a), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4b), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4c), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4d), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4e), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4f), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d50), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d51), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d52), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d53), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d54), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d55), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d56), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d57), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d58), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d59), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5a), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5b), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5c), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5d), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5e), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5f), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x9c40), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c41), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c42), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c43), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c44), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c45), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c46), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c47), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc3), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc5), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc6), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc7), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc9), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0xa1c1), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c2), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c3), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c4), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c5), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c6), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c7), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa242), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa243), LPC_LEWISBURG}, + { 0, }, /* End of list */ +}; +MODULE_DEVICE_TABLE(pci, lpc_ich_ids); + +static void lpc_ich_restore_config_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + + if (priv->abase_save >= 0) { + pci_write_config_byte(dev, priv->abase, priv->abase_save); + priv->abase_save = -1; + } + + if (priv->actrl_pbase_save >= 0) { + pci_write_config_byte(dev, priv->actrl_pbase, + priv->actrl_pbase_save); + priv->actrl_pbase_save = -1; + } + + if (priv->gctrl_save >= 0) { + pci_write_config_byte(dev, priv->gctrl, priv->gctrl_save); + priv->gctrl_save = -1; + } +} + +static void lpc_ich_enable_acpi_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + switch (lpc_chipset_info[priv->chipset].iTCO_version) { + case 3: + /* + * Some chipsets (eg Avoton) enable the ACPI space in the + * ACPI BASE register. + */ + pci_read_config_byte(dev, priv->abase, ®_save); + pci_write_config_byte(dev, priv->abase, reg_save | 0x2); + priv->abase_save = reg_save; + break; + default: + /* + * Most chipsets enable the ACPI space in the ACPI control + * register. + */ + pci_read_config_byte(dev, priv->actrl_pbase, ®_save); + pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x80); + priv->actrl_pbase_save = reg_save; + break; + } +} + +static void lpc_ich_enable_gpio_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + pci_read_config_byte(dev, priv->gctrl, ®_save); + pci_write_config_byte(dev, priv->gctrl, reg_save | 0x10); + priv->gctrl_save = reg_save; +} + +static void lpc_ich_enable_pmc_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + pci_read_config_byte(dev, priv->actrl_pbase, ®_save); + pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x2); + + priv->actrl_pbase_save = reg_save; +} + +static int lpc_ich_finalize_wdt_cell(struct pci_dev *dev) +{ + struct itco_wdt_platform_data *pdata; + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + struct lpc_ich_info *info; + struct mfd_cell *cell = &lpc_ich_wdt_cell; + + pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + info = &lpc_chipset_info[priv->chipset]; + + pdata->version = info->iTCO_version; + strlcpy(pdata->name, info->name, sizeof(pdata->name)); + + cell->platform_data = pdata; + cell->pdata_size = sizeof(*pdata); + return 0; +} + +static void lpc_ich_finalize_gpio_cell(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + struct mfd_cell *cell = &lpc_ich_gpio_cell; + + cell->platform_data = &lpc_chipset_info[priv->chipset]; + cell->pdata_size = sizeof(struct lpc_ich_info); +} + +/* + * We don't check for resource conflict globally. There are 2 or 3 independent + * GPIO groups and it's enough to have access to one of these to instantiate + * the device. + */ +static int lpc_ich_check_conflict_gpio(struct resource *res) +{ + int ret; + u8 use_gpio = 0; + + if (resource_size(res) >= 0x50 && + !acpi_check_region(res->start + 0x40, 0x10, "LPC ICH GPIO3")) + use_gpio |= 1 << 2; + + if (!acpi_check_region(res->start + 0x30, 0x10, "LPC ICH GPIO2")) + use_gpio |= 1 << 1; + + ret = acpi_check_region(res->start + 0x00, 0x30, "LPC ICH GPIO1"); + if (!ret) + use_gpio |= 1 << 0; + + return use_gpio ? use_gpio : ret; +} + +static int lpc_ich_init_gpio(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u32 base_addr_cfg; + u32 base_addr; + int ret; + bool acpi_conflict = false; + struct resource *res; + + /* Setup power management base register */ + pci_read_config_dword(dev, priv->abase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); + lpc_ich_gpio_cell.num_resources--; + goto gpe0_done; + } + + res = &gpio_ich_res[ICH_RES_GPE0]; + res->start = base_addr + ACPIBASE_GPE_OFF; + res->end = base_addr + ACPIBASE_GPE_END; + ret = acpi_check_resource_conflict(res); + if (ret) { + /* + * This isn't fatal for the GPIO, but we have to make sure that + * the platform_device subsystem doesn't see this resource + * or it will register an invalid region. + */ + lpc_ich_gpio_cell.num_resources--; + acpi_conflict = true; + } else { + lpc_ich_enable_acpi_space(dev); + } + +gpe0_done: + /* Setup GPIO base register */ + pci_read_config_dword(dev, priv->gbase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); + ret = -ENODEV; + goto gpio_done; + } + + /* Older devices provide fewer GPIO and have a smaller resource size. */ + res = &gpio_ich_res[ICH_RES_GPIO]; + res->start = base_addr; + switch (lpc_chipset_info[priv->chipset].gpio_version) { + case ICH_V5_GPIO: + case ICH_V10CORP_GPIO: + res->end = res->start + 128 - 1; + break; + default: + res->end = res->start + 64 - 1; + break; + } + + ret = lpc_ich_check_conflict_gpio(res); + if (ret < 0) { + /* this isn't necessarily fatal for the GPIO */ + acpi_conflict = true; + goto gpio_done; + } + lpc_chipset_info[priv->chipset].use_gpio = ret; + lpc_ich_enable_gpio_space(dev); + + lpc_ich_finalize_gpio_cell(dev); + ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, + &lpc_ich_gpio_cell, 1, NULL, 0, NULL); + +gpio_done: + if (acpi_conflict) + pr_warn("Resource conflict(s) found affecting %s\n", + lpc_ich_gpio_cell.name); + return ret; +} + +static int lpc_ich_init_wdt(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u32 base_addr_cfg; + u32 base_addr; + int ret; + struct resource *res; + + /* If we have ACPI based watchdog use that instead */ + if (acpi_has_watchdog()) + return -ENODEV; + + /* Setup power management base register */ + pci_read_config_dword(dev, priv->abase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); + ret = -ENODEV; + goto wdt_done; + } + + res = wdt_io_res(ICH_RES_IO_TCO); + res->start = base_addr + ACPIBASE_TCO_OFF; + res->end = base_addr + ACPIBASE_TCO_END; + + res = wdt_io_res(ICH_RES_IO_SMI); + res->start = base_addr + ACPIBASE_SMI_OFF; + res->end = base_addr + ACPIBASE_SMI_END; + + lpc_ich_enable_acpi_space(dev); + + /* + * iTCO v2: + * Get the Memory-Mapped GCS register. To get access to it + * we have to read RCBA from PCI Config space 0xf0 and use + * it as base. GCS = RCBA + ICH6_GCS(0x3410). + * + * iTCO v3: + * Get the Power Management Configuration register. To get access + * to it we have to read the PMC BASE from config space and address + * the register at offset 0x8. + */ + if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { + /* Don't register iomem for TCO ver 1 */ + lpc_ich_wdt_cell.num_resources--; + } else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) { + pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); + base_addr = base_addr_cfg & 0xffffc000; + if (!(base_addr_cfg & 1)) { + dev_notice(&dev->dev, "RCBA is disabled by " + "hardware/BIOS, device disabled\n"); + ret = -ENODEV; + goto wdt_done; + } + res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); + res->start = base_addr + ACPIBASE_GCS_OFF; + res->end = base_addr + ACPIBASE_GCS_END; + } else if (lpc_chipset_info[priv->chipset].iTCO_version == 3) { + lpc_ich_enable_pmc_space(dev); + pci_read_config_dword(dev, ACPICTRL_PMCBASE, &base_addr_cfg); + base_addr = base_addr_cfg & 0xfffffe00; + + res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); + res->start = base_addr + ACPIBASE_PMC_OFF; + res->end = base_addr + ACPIBASE_PMC_END; + } + + ret = lpc_ich_finalize_wdt_cell(dev); + if (ret) + goto wdt_done; + + ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, + &lpc_ich_wdt_cell, 1, NULL, 0, NULL); + +wdt_done: + return ret; +} + +static int lpc_ich_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + struct lpc_ich_priv *priv; + int ret; + bool cell_added = false; + + priv = devm_kzalloc(&dev->dev, + sizeof(struct lpc_ich_priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->chipset = id->driver_data; + + priv->actrl_pbase_save = -1; + priv->abase_save = -1; + + priv->abase = ACPIBASE; + priv->actrl_pbase = ACPICTRL_PMCBASE; + + priv->gctrl_save = -1; + if (priv->chipset <= LPC_ICH5) { + priv->gbase = GPIOBASE_ICH0; + priv->gctrl = GPIOCTRL_ICH0; + } else { + priv->gbase = GPIOBASE_ICH6; + priv->gctrl = GPIOCTRL_ICH6; + } + + pci_set_drvdata(dev, priv); + + if (lpc_chipset_info[priv->chipset].iTCO_version) { + ret = lpc_ich_init_wdt(dev); + if (!ret) + cell_added = true; + } + + if (lpc_chipset_info[priv->chipset].gpio_version) { + ret = lpc_ich_init_gpio(dev); + if (!ret) + cell_added = true; + } + + /* + * We only care if at least one or none of the cells registered + * successfully. + */ + if (!cell_added) { + dev_warn(&dev->dev, "No MFD cells added\n"); + lpc_ich_restore_config_space(dev); + return -ENODEV; + } + + return 0; +} + +static void lpc_ich_remove(struct pci_dev *dev) +{ + mfd_remove_devices(&dev->dev); + lpc_ich_restore_config_space(dev); +} + +static struct pci_driver lpc_ich_driver = { + .name = "lpc_ich", + .id_table = lpc_ich_ids, + .probe = lpc_ich_probe, + .remove = lpc_ich_remove, +}; + +module_pci_driver(lpc_ich_driver); + +MODULE_AUTHOR("Aaron Sierra "); +MODULE_DESCRIPTION("LPC interface for Intel ICH"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.c new file mode 100644 index 000000000000..251ada569ed6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.c @@ -0,0 +1,8409 @@ +#include +#include +#include +#include +#include "io_expander.h" +#include "transceiver.h" + +/* For build single module using (Ex: ONL platform) */ +#include +//#include +//#include + +extern int io_no_init; +/* ========== Register EEPROM address mapping ========== + */ +struct eeprom_map_s eeprom_map_sfp = { + .addr_br =0x50, .page_br =-1, .offset_br =12, .length_br =1, + .addr_cdr =-1, .page_cdr =-1, .offset_cdr =-1, .length_cdr =-1, + .addr_comp_rev =0x50, .page_comp_rev =-1, .offset_comp_rev =94, .length_comp_rev =1, + .addr_connector =0x50, .page_connector =-1, .offset_connector =2, .length_connector =1, + .addr_diag_type =0x50, .page_diag_type =-1, .offset_diag_type =92 , .length_diag_type =1, + .addr_extbr =-1, .page_extbr =-1, .offset_extbr =-1, .length_extbr =-1, + .addr_ext_id =0x50, .page_ext_id =-1, .offset_ext_id =1, .length_ext_id =1, + .addr_id =0x50, .page_id =-1, .offset_id =0, .length_id =1, + .addr_len_sm =0x50, .page_len_sm =-1, .offset_len_sm =15, .length_len_sm =1, + .addr_len_smf =0x50, .page_len_smf =-1, .offset_len_smf =14, .length_len_smf =1, + .addr_len_om1 =0x50, .page_len_om1 =-1, .offset_len_om1 =17, .length_len_om1 =1, + .addr_len_om2 =0x50, .page_len_om2 =-1, .offset_len_om2 =16, .length_len_om2 =1, + .addr_len_om3 =0x50, .page_len_om3 =-1, .offset_len_om3 =19, .length_len_om3 =1, + .addr_len_om4 =0x50, .page_len_om4 =-1, .offset_len_om4 =18, .length_len_om4 =1, + .addr_option =0x50, .page_option =-1, .offset_option =64, .length_option =2, + .addr_rate_id =0x50, .page_rate_id =-1, .offset_rate_id =13, .length_rate_id =1, + .addr_rx_am =-1, .page_rx_am =-1, .offset_rx_am =-1, .length_rx_am =-1, + .addr_rx_em =0x51, .page_rx_em =-1, .offset_rx_em =115, .length_rx_em =1, + .addr_rx_los =-1, .page_rx_los =-1, .offset_rx_los =-1, .length_rx_los =-1, + .addr_rx_power =0x51, .page_rx_power =-1, .offset_rx_power =104, .length_rx_power =2, + .addr_soft_rs0 =0x51, .page_soft_rs0 =-1, .offset_soft_rs0 =110, .length_soft_rs0 =1, + .addr_soft_rs1 =0x51, .page_soft_rs1 =-1, .offset_soft_rs1 =118, .length_soft_rs0 =1, + .addr_temp =0x51, .page_temp =-1, .offset_temp =96, .length_temp =2, + .addr_trancomp =0x50, .page_trancomp =-1, .offset_trancomp =3, .length_trancomp =8, + .addr_trancomp_ext =0x50, .page_trancomp_ext =-1, .offset_trancomp_ext =36, .length_trancomp_ext =1, + .addr_tx_bias =0x51, .page_tx_bias =-1, .offset_tx_bias =100, .length_tx_bias =2, + .addr_tx_disable =-1, .page_tx_disable =-1, .offset_tx_disable =-1, .length_tx_disable =-1, + .addr_tx_eq =0x51, .page_tx_eq =-1, .offset_tx_eq =114, .length_tx_eq =1, + .addr_tx_fault =-1, .page_tx_fault =-1, .offset_tx_fault =-1, .length_tx_fault =-1, + .addr_tx_power =0x51, .page_tx_power =-1, .offset_tx_power =102, .length_tx_power =2, + .addr_vendor_name =0x50, .page_vendor_name =-1, .offset_vendor_name =20, .length_vendor_name =16, + .addr_vendor_pn =0x50, .page_vendor_pn =-1, .offset_vendor_pn =40, .length_vendor_pn =16, + .addr_vendor_rev =0x50, .page_vendor_rev =-1, .offset_vendor_rev =56, .length_vendor_rev =4, + .addr_vendor_sn =0x50, .page_vendor_sn =-1, .offset_vendor_sn =68, .length_vendor_sn =16, + .addr_voltage =0x51, .page_voltage =-1, .offset_voltage =98, .length_voltage =2, + .addr_wavelength =0x50, .page_wavelength =-1, .offset_wavelength =60, .length_wavelength =2, +}; + +struct eeprom_map_s eeprom_map_qsfp = { + .addr_br =0x50, .page_br =0, .offset_br =140, .length_br =1, + .addr_cdr =-1, .page_cdr =-1, .offset_cdr =-1, .length_cdr =-1, + .addr_comp_rev =0x50, .page_comp_rev =-1, .offset_comp_rev =1, .length_comp_rev =1, + .addr_connector =0x50, .page_connector =0, .offset_connector =130, .length_connector =1, + .addr_diag_type =0x50, .page_diag_type =0, .offset_diag_type =220, .length_diag_type =1, + .addr_extbr =0x50, .page_extbr =0, .offset_extbr =222, .length_extbr =1, + .addr_ext_id =0x50, .page_ext_id =0, .offset_ext_id =129, .length_ext_id =1, + .addr_id =0x50, .page_id =0, .offset_id =128, .length_id =1, + .addr_len_sm =-1, .page_len_sm =-1, .offset_len_sm =-1, .length_len_sm =-1, + .addr_len_smf =0x50, .page_len_smf =0, .offset_len_smf =142, .length_len_smf =1, + .addr_len_om1 =0x50, .page_len_om1 =0, .offset_len_om1 =145, .length_len_om1 =1, + .addr_len_om2 =0x50, .page_len_om2 =0, .offset_len_om2 =144, .length_len_om2 =1, + .addr_len_om3 =0x50, .page_len_om3 =0, .offset_len_om3 =143, .length_len_om3 =1, + .addr_len_om4 =0x50, .page_len_om4 =0, .offset_len_om4 =146, .length_len_om4 =1, + .addr_option =0x50, .page_option =0, .offset_option =193, .length_option =3, + .addr_rate_id =-1, .page_rate_id =-1, .offset_rate_id =-1, .length_rate_id =-1, + .addr_rx_am =-1, .page_rx_am =-1, .offset_rx_am =-1, .length_rx_am =-1, + .addr_rx_em =-1, .page_rx_em =-1, .offset_rx_em =-1, .length_rx_em =-1, + .addr_rx_los =0x50, .page_rx_los =-1, .offset_rx_los =3, .length_rx_los =1, + .addr_rx_power =0x50, .page_rx_power =-1, .offset_rx_power =34, .length_rx_power =8, + .addr_soft_rs0 =-1, .page_soft_rs0 =-1, .offset_soft_rs0 =-1, .length_soft_rs0 =-1, + .addr_soft_rs1 =-1, .page_soft_rs1 =-1, .offset_soft_rs1 =-1, .length_soft_rs0 =-1, + .addr_temp =0x50, .page_temp =-1, .offset_temp =22, .length_temp =2, + .addr_trancomp =0x50, .page_trancomp =0, .offset_trancomp =131, .length_trancomp =8, + .addr_trancomp_ext =0x50, .page_trancomp_ext =0, .offset_trancomp_ext =192, .length_trancomp_ext =1, + .addr_tx_bias =0x50, .page_tx_bias =-1, .offset_tx_bias =42, .length_tx_bias =8, + .addr_tx_disable =0x50, .page_tx_disable =-1, .offset_tx_disable =86, .length_tx_disable =1, + .addr_tx_eq =-1, .page_tx_eq =-1, .offset_tx_eq =-1, .length_tx_eq =-1, + .addr_tx_fault =0x50, .page_tx_fault =-1, .offset_tx_fault =4, .length_tx_fault =1, + .addr_tx_power =0x50, .page_tx_power =-1, .offset_tx_power =50, .length_tx_power =8, + .addr_vendor_name =0x50, .page_vendor_name =0, .offset_vendor_name =148, .length_vendor_name =16, + .addr_vendor_pn =0x50, .page_vendor_pn =0, .offset_vendor_pn =168, .length_vendor_pn =16, + .addr_vendor_rev =0x50, .page_vendor_rev =0, .offset_vendor_rev =184, .length_vendor_rev =2, + .addr_vendor_sn =0x50, .page_vendor_sn =0, .offset_vendor_sn =196, .length_vendor_sn =16, + .addr_voltage =0x50, .page_voltage =-1, .offset_voltage =26, .length_voltage =2, + .addr_wavelength =0x50, .page_wavelength =0, .offset_wavelength =186, .length_wavelength =2, +}; + +struct eeprom_map_s eeprom_map_qsfp28 = { + .addr_br =0x50, .page_br =0, .offset_br =140, .length_br =1, + .addr_cdr =0x50, .page_cdr =-1, .offset_cdr =98, .length_cdr =1, + .addr_comp_rev =0x50, .page_comp_rev =-1, .offset_comp_rev =1, .length_comp_rev =1, + .addr_connector =0x50, .page_connector =0, .offset_connector =130, .length_connector =1, + .addr_diag_type =0x50, .page_diag_type =0, .offset_diag_type =220, .length_diag_type =1, + .addr_extbr =0x50, .page_extbr =0, .offset_extbr =222, .length_extbr =1, + .addr_ext_id =0x50, .page_ext_id =0, .offset_ext_id =129, .length_ext_id =1, + .addr_id =0x50, .page_id =0, .offset_id =128, .length_id =1, + .addr_len_sm =-1, .page_len_sm =-1, .offset_len_sm =-1, .length_len_sm =-1, + .addr_len_smf =0x50, .page_len_smf =0, .offset_len_smf =142, .length_len_smf =1, + .addr_len_om1 =0x50, .page_len_om1 =0, .offset_len_om1 =145, .length_len_om1 =1, + .addr_len_om2 =0x50, .page_len_om2 =0, .offset_len_om2 =144, .length_len_om2 =1, + .addr_len_om3 =0x50, .page_len_om3 =0, .offset_len_om3 =143, .length_len_om3 =1, + .addr_len_om4 =0x50, .page_len_om4 =0, .offset_len_om4 =146, .length_len_om4 =1, + .addr_option =0x50, .page_option =0, .offset_option =193, .length_option =3, + .addr_rate_id =-1, .page_rate_id =-1, .offset_rate_id =-1, .length_rate_id =-1, + .addr_rx_am =0x50, .page_rx_am =3, .offset_rx_am =238, .length_rx_am =2, + .addr_rx_em =0x50, .page_rx_em =3, .offset_rx_em =236, .length_rx_em =2, + .addr_rx_los =0x50, .page_rx_los =-1, .offset_rx_los =3, .length_rx_los =1, + .addr_rx_power =0x50, .page_rx_power =-1, .offset_rx_power =34, .length_rx_power =8, + .addr_soft_rs0 =-1, .page_soft_rs0 =-1, .offset_soft_rs0 =-1, .length_soft_rs0 =-1, + .addr_soft_rs1 =-1, .page_soft_rs1 =-1, .offset_soft_rs1 =-1, .length_soft_rs0 =-1, + .addr_temp =0x50, .page_temp =-1, .offset_temp =22, .length_temp =2, + .addr_trancomp =0x50, .page_trancomp =0, .offset_trancomp =131, .length_trancomp =8, + .addr_trancomp_ext =0x50, .page_trancomp_ext =0, .offset_trancomp_ext =192, .length_trancomp_ext =1, + .addr_tx_bias =0x50, .page_tx_bias =-1, .offset_tx_bias =42, .length_tx_bias =8, + .addr_tx_disable =0x50, .page_tx_disable =-1, .offset_tx_disable =86, .length_tx_disable =1, + .addr_tx_eq =0x50, .page_tx_eq =3, .offset_tx_eq =234, .length_tx_eq =2, + .addr_tx_fault =0x50, .page_tx_fault =-1, .offset_tx_fault =4, .length_tx_fault =1, + .addr_tx_power =0x50, .page_tx_power =-1, .offset_tx_power =50, .length_tx_power =8, + .addr_vendor_name =0x50, .page_vendor_name =0, .offset_vendor_name =148, .length_vendor_name =16, + .addr_vendor_pn =0x50, .page_vendor_pn =0, .offset_vendor_pn =168, .length_vendor_pn =16, + .addr_vendor_rev =0x50, .page_vendor_rev =0, .offset_vendor_rev =184, .length_vendor_rev =2, + .addr_vendor_sn =0x50, .page_vendor_sn =0, .offset_vendor_sn =196, .length_vendor_sn =16, + .addr_voltage =0x50, .page_voltage =-1, .offset_voltage =26, .length_voltage =2, + .addr_wavelength =0x50, .page_wavelength =0, .offset_wavelength =186, .length_wavelength =2, +}; + + +/* ========== Utility Functions ========== + */ +static int +get_bit(uint8_t origin_byte, int bit_shift) { + return (int)((origin_byte >> bit_shift) & 0x1); +} + +static int +transform_word_to_int(uint8_t hight_byte, + uint8_t low_byte) { + return ((((int)hight_byte) << 8) + (int)low_byte); +} + +void +alarm_msg_2_user(struct transvr_obj_s *self, + char *emsg) { + + SWPS_ERR("%s on %s.\n", emsg, self->swp_name); +} +EXPORT_SYMBOL(alarm_msg_2_user); + +/* ========== Private functions ========== + */ +static int +_reload_transvr_obj(struct transvr_obj_s *self,int new_type); + +static int +reload_transvr_obj(struct transvr_obj_s *self,int new_type); + +static int +_is_transvr_support_ctle(struct transvr_obj_s *self); + +static int +_transvr_init_handler(struct transvr_obj_s *self); + +int +_transvr_clean_handler(struct transvr_obj_s *self); + +int +_sfp_detect_class_by_1g_ethernet(struct transvr_obj_s* self); + + +void +lock_transvr_obj(struct transvr_obj_s *self) { + + mutex_lock(&self->lock); + self->curr_page = VAL_TRANSVR_PAGE_FREE; +} +EXPORT_SYMBOL(lock_transvr_obj); + + +void +unlock_transvr_obj(struct transvr_obj_s *self) { + + self->curr_page = VAL_TRANSVR_PAGE_FREE; + mutex_unlock(&self->lock); +} +EXPORT_SYMBOL(unlock_transvr_obj); + + +static int +_check_by_mode(struct transvr_obj_s *self, + int (*attr_update_func)(struct transvr_obj_s *self, int show_err), + char *caller_name){ + + int return_val = ERR_TRANSVR_UNEXCPT; + + switch (self->mode){ + case TRANSVR_MODE_POLLING: + switch (self->state){ + case STATE_TRANSVR_CONNECTED: + goto ok_check_by_mode_1; + case STATE_TRANSVR_NEW: + case STATE_TRANSVR_INIT: + return ERR_TRANSVR_UNINIT; + case STATE_TRANSVR_DISCONNECTED: + return ERR_TRANSVR_UNPLUGGED; + case STATE_TRANSVR_UNEXCEPTED: + return ERR_TRANSVR_ABNORMAL; + case STATE_TRANSVR_ISOLATED: + return ERR_TRNASVR_BE_ISOLATED; + default: + goto err_check_by_mode_1; + } + goto ok_check_by_mode_1; + + case TRANSVR_MODE_DIRECT: + return_val = self->fsm_4_direct(self, caller_name); + if (return_val < 0){ + return return_val; + } + goto ok_check_by_mode_1; + + default: + goto err_check_by_mode_1; + } + goto ok_check_by_mode_1; + +ok_check_by_mode_1: + return attr_update_func(self, 0); + +err_check_by_mode_1: + SWPS_INFO("_check_by_mode: mode:%d state:%d\n", self->mode, self->state); + return ERR_TRANSVR_UNEXCPT; +} + + +static void +_transvr_clean_retry(struct transvr_obj_s *self) { + self->retry = 0; +} + + +static int +_transvr_handle_retry(struct transvr_obj_s *self, int retry) { + /* Return: 0: keep retry + * -1: stop retry + */ + if (self->retry == 0) { + self->retry = retry; + } + self->retry -= 1; + if (self->retry <= 0) { + _transvr_clean_retry(self); + return -1; + } + return 0; +} + + +static int +_common_setup_page(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + int show_e) { + /* return: + * 0 : OK + * -1 : EEPROM settings incorrect + * -2 : I2C R/W failure + * -3 : Undefined case + */ + int retval = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + /* Check */ + if ((addr < 0) || (offset < 0) || (len < 0)) { + emsg = "EEPROM settings incorrect"; + retval = -1; + goto err_common_setup_page; + } + /* Case1: continue access */ + if ((self->i2c_client_p->addr == addr) && + (self->curr_page == page)) { + return 0; + } + self->i2c_client_p->addr = addr; + /* Case2: select lower page */ + if (page == -1) { + self->curr_page = page; + return 0; + } + /* Case3: select upper page */ + if (page >= 0) { + goto upper_common_setup_page; + } + /* Unexpected case */ + show_e = 1; + emsg = "Unexpected case"; + retval = -3; + goto err_common_setup_page; + +upper_common_setup_page: + if (i2c_smbus_write_byte_data(self->i2c_client_p, + VAL_TRANSVR_PAGE_SELECT_OFFSET, + page) < 0) { + emsg = "I2C R/W failure"; + retval = -2; + goto err_common_setup_page; + } + self->curr_page = page; + mdelay(VAL_TRANSVR_PAGE_SELECT_DELAY); + return 0; + +err_common_setup_page: + if (show_e) { + SWPS_INFO("%s: %s", __func__, emsg); + SWPS_INFO("%s: :0x%02x :%d :%d :%d\n", + __func__, addr, page, offset, len); + } + return retval; +} + +/* +static int +_common_setup_password(struct transvr_obj_s *self, + int addr, + int page, + int offs, + uint8_t pwd[4], + int show_e) { + int i = 0; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offs, 4, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_setup_password; + } + for (i=0; i<4; i++) { + err = i2c_smbus_write_byte_data(self->i2c_client_p, + (offs + i), + pwd[i]); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_setup_password; + } + } + return 0; + +err_common_setup_password: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, err); + } + return ERR_TRANSVR_UPDATE_FAIL; +} +*/ + +static int +_common_update_uint8_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + uint8_t *buf, + char *caller, + int show_e){ + + int i; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_update_uint8_attr; + } + for (i=0; ii2c_client_p, (offset + i)); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_update_uint8_attr; + } + buf[i] = err; + } + return 0; + +err_common_update_uint8_attr: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + buf[0] = DEBUG_TRANSVR_HEX_VAL; + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_update_int_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + int *buf, + char *caller, + int show_e){ + + int i; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_update_int_attr; + } + for (i=0; ii2c_client_p, (offset + i)); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_update_int_attr; + } + buf[i] = (int)err; + } + return 0; + +err_common_update_int_attr: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + buf[0] = DEBUG_TRANSVR_INT_VAL; + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_update_string_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + char buf[], + char *caller, + int show_e){ + + int i; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_update_string_attr; + } + for (i=0; ii2c_client_p, (offset + i)); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_update_string_attr; + } + buf[i] = (char)err; + } + return 0; + +err_common_update_string_attr: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + buf[0] = 'e'; + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_set_uint8_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + uint8_t update, + uint8_t *buf, + char *caller, + int show_e){ + int len = 1; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + if ((*buf) == update){ + return 0; + } + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_set_uint8_attr_1; + } + err = i2c_smbus_write_byte_data(self->i2c_client_p, + offset, + update); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_set_uint8_attr_1; + } + (*buf) = update; + return 0; + +err_common_set_uint8_attr_1: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_set_uint8_array(struct transvr_obj_s *self, + int addr, + int page, + int offs, + int len, + uint8_t update[], + uint8_t buf[], + char *caller, + int show_e){ + int i = 0; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offs, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_set_uint8_attr_1; + } + for (i=0; ii2c_client_p, + (offs + i), + update[i]); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_set_uint8_attr_1; + } + buf[i] = update[i]; + } + return 0; + +err_common_set_uint8_attr_1: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + __func__, emsg, caller, err, i); + } + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_update_attr_id(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_id, + self->eeprom_map_p->page_id, + self->eeprom_map_p->offset_id, + self->eeprom_map_p->length_id, + &(self->id), + "_common_update_attr_id", + show_err); +} + + +static int +_common_update_attr_extended_id(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_ext_id, + self->eeprom_map_p->page_ext_id, + self->eeprom_map_p->offset_ext_id, + self->eeprom_map_p->length_ext_id, + &(self->ext_id), + "_common_update_attr_extended_id", + show_err); +} + + +static int +_common_update_attr_connector(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_connector, + self->eeprom_map_p->page_connector, + self->eeprom_map_p->offset_connector, + self->eeprom_map_p->length_connector, + &(self->connector), + "_common_update_attr_connector", + show_err); +} + + +static int +_common_update_attr_transvr_comp(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_trancomp, + self->eeprom_map_p->page_trancomp, + self->eeprom_map_p->offset_trancomp, + self->eeprom_map_p->length_trancomp, + self->transvr_comp, + "_common_update_attr_transvr_comp", + show_err); +} + + +static int +_common_update_attr_transvr_comp_ext(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_trancomp_ext, + self->eeprom_map_p->page_trancomp_ext, + self->eeprom_map_p->offset_trancomp_ext, + self->eeprom_map_p->length_trancomp_ext, + &(self->transvr_comp_ext), + "_common_update_attr_transvr_comp_ext", + show_err); +} + + +static int +_common_update_attr_vendor_name(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_name, + self->eeprom_map_p->page_vendor_name, + self->eeprom_map_p->offset_vendor_name, + self->eeprom_map_p->length_vendor_name, + self->vendor_name, + "_common_update_attr_vendor_name", + show_err); +} + + +static int +_common_update_attr_vendor_pn(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_pn, + self->eeprom_map_p->page_vendor_pn, + self->eeprom_map_p->offset_vendor_pn, + self->eeprom_map_p->length_vendor_pn, + self->vendor_pn, + "_common_update_attr_vendor_pn", + show_err); +} + + +static int +_common_update_attr_vendor_rev(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_rev, + self->eeprom_map_p->page_vendor_rev, + self->eeprom_map_p->offset_vendor_rev, + self->eeprom_map_p->length_vendor_rev, + self->vendor_rev, + "_common_update_attr_vendor_rev", + show_err); +} + + +static int +_common_update_attr_vendor_sn(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_sn, + self->eeprom_map_p->page_vendor_sn, + self->eeprom_map_p->offset_vendor_sn, + self->eeprom_map_p->length_vendor_sn, + self->vendor_sn, + "_common_update_attr_vendor_sn", + show_err); +} + + +static int +_common_update_attr_br(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_br, + self->eeprom_map_p->page_br, + self->eeprom_map_p->offset_br, + self->eeprom_map_p->length_br, + &(self->br), + "_common_update_attr_br", + show_err); +} + + +static int +_common_update_attr_len_smf(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_smf, + self->eeprom_map_p->page_len_smf, + self->eeprom_map_p->offset_len_smf, + self->eeprom_map_p->length_len_smf, + &(self->len_smf), + "_common_update_attr_len_smf", + show_err); +} + + +static int +_common_update_attr_len_om1(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om1, + self->eeprom_map_p->page_len_om1, + self->eeprom_map_p->offset_len_om1, + self->eeprom_map_p->length_len_om1, + &(self->len_om1), + "_common_update_attr_len_om1", + show_err); +} + +static int +_common_update_attr_len_om2(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om2, + self->eeprom_map_p->page_len_om2, + self->eeprom_map_p->offset_len_om2, + self->eeprom_map_p->length_len_om2, + &(self->len_om2), + "_common_update_attr_len_om2", + show_err); +} + +static int +_common_update_attr_len_om3(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om3, + self->eeprom_map_p->page_len_om3, + self->eeprom_map_p->offset_len_om3, + self->eeprom_map_p->length_len_om3, + &(self->len_om3), + "_common_update_attr_len_om3", + show_err); +} + + +static int +_common_update_attr_len_om4(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om4, + self->eeprom_map_p->page_len_om4, + self->eeprom_map_p->offset_len_om4, + self->eeprom_map_p->length_len_om4, + &(self->len_om4), + "_common_update_attr_len_om4", + show_err); +} + + +static int +_common_update_attr_option(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_option, + self->eeprom_map_p->page_option, + self->eeprom_map_p->offset_option, + self->eeprom_map_p->length_option, + self->option, + "_common_update_attr_option", + show_err); +} + + +static int +_common_update_attr_comp_rev(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_comp_rev, + self->eeprom_map_p->page_comp_rev, + self->eeprom_map_p->offset_comp_rev, + self->eeprom_map_p->length_comp_rev, + &(self->comp_rev), + "_common_update_attr_comp_rev", + show_err); +} + + +static int +_common_update_attr_diag_type(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_diag_type, + self->eeprom_map_p->page_diag_type, + self->eeprom_map_p->offset_diag_type, + self->eeprom_map_p->length_diag_type, + &(self->diag_type), + "_common_update_attr_diag_type", + show_err); +} + + +static int +_common_update_attr_wavelength(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_wavelength, + self->eeprom_map_p->page_wavelength, + self->eeprom_map_p->offset_wavelength, + self->eeprom_map_p->length_wavelength, + self->wavelength, + "_common_update_attr_wavelength", + show_err); +} + + +int +_common_get_option_value(struct transvr_obj_s *self, + int offset, + int bit_shift) { + /* SFP: + * - option[0] = A0h / 64 + * - option[1] = A0h / 65 + * QSFP: + * - option[0] = 00h / 193 + * - option[1] = 00h / 194 + * - option[2] = 00h / 195 + */ + return (self->option[offset] & (1 << bit_shift)); +} + + +static int +_sfp_update_attr_len_sm(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_sm, + self->eeprom_map_p->page_len_sm, + self->eeprom_map_p->offset_len_sm, + self->eeprom_map_p->length_len_sm, + &(self->len_sm), + "_common_update_attr_len_sm", + show_err); +} + + +static int +_sfp_update_attr_rate_id(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_rate_id, + self->eeprom_map_p->page_rate_id, + self->eeprom_map_p->offset_rate_id, + self->eeprom_map_p->length_rate_id, + &(self->rate_id), + "_sfp_update_attr_rate_id", + show_err); +} + + +static int +_sfp_update_attr_soft_rs0(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_soft_rs0, + self->eeprom_map_p->page_soft_rs0, + self->eeprom_map_p->offset_soft_rs0, + self->eeprom_map_p->length_soft_rs0, + &(self->soft_rs0), + "_sfp_update_attr_soft_rs0", + show_err); +} + + +static int +_sfp_update_attr_soft_rs1(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_soft_rs1, + self->eeprom_map_p->page_soft_rs1, + self->eeprom_map_p->offset_soft_rs1, + self->eeprom_map_p->length_soft_rs1, + &(self->soft_rs1), + "_sfp_update_attr_soft_rs1", + show_err); +} + + +int +_sfp_is_diag_support(struct transvr_obj_s *self){ + + uint8_t bit_mask = 0xC0; /* 1100 0000 */ + uint8_t en_val = 0x40; /* 0100 0000 */ + uint8_t checkval = (self->diag_type & bit_mask); + + if (checkval == en_val) { + return 1; + } + return 0; +} + + +static int +_sfp_update_attr_curr_temp(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_temp, + self->eeprom_map_p->page_temp, + self->eeprom_map_p->offset_temp, + self->eeprom_map_p->length_temp, + self->curr_temp, + "_sfp_update_attr_curr_temp", + show_err); +} + + +static int +_sfp_update_attr_curr_voltage(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_voltage, + self->eeprom_map_p->page_voltage, + self->eeprom_map_p->offset_voltage, + self->eeprom_map_p->length_voltage, + self->curr_voltage, + "_sfp_update_attr_curr_voltage", + show_err); +} + + +static int +_sfp_update_attr_curr_tx_bias(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_bias, + self->eeprom_map_p->page_tx_bias, + self->eeprom_map_p->offset_tx_bias, + self->eeprom_map_p->length_tx_bias, + self->curr_tx_bias, + "_sfp_update_attr_curr_tx_bias", + show_err); +} + + +static int +_sfp_update_attr_curr_tx_power(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_power, + self->eeprom_map_p->page_tx_power, + self->eeprom_map_p->offset_tx_power, + self->eeprom_map_p->length_tx_power, + self->curr_tx_power, + "_sfp_update_attr_curr_tx_power", + show_err); +} + + +static int +_sfp_update_attr_curr_rx_power(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_power, + self->eeprom_map_p->page_rx_power, + self->eeprom_map_p->offset_rx_power, + self->eeprom_map_p->length_rx_power, + self->curr_rx_power, + "_sfp_update_attr_curr_rx_power", + show_err); +} + + +static int +_sfp_update_attr_rx_em(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + self->eeprom_map_p->length_rx_em, + self->rx_em, + "_sfp_update_attr_rx_em", + show_err); +} + + +static int +_sfp_update_attr_tx_eq(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + self->eeprom_map_p->length_tx_eq, + self->tx_eq, + "_sfp_update_attr_tx_eq", + show_err); +} + + +static int +_qsfp_update_attr_cdr(struct transvr_obj_s *self, + int show_err){ + if (self->type != TRANSVR_TYPE_QSFP_28){ + self->cdr = DEBUG_TRANSVR_HEX_VAL; + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->page_cdr, + self->eeprom_map_p->offset_cdr, + self->eeprom_map_p->length_cdr, + &(self->cdr), + "_common_update_attr_cdr", + show_err); +} + + +static int +_qsfg_update_attr_extbr(struct transvr_obj_s *self, + int show_err) { + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_extbr, + self->eeprom_map_p->page_extbr, + self->eeprom_map_p->offset_extbr, + self->eeprom_map_p->length_extbr, + &(self->extbr), + "_common_update_attr_extbr", + show_err); +} + + +static int +_qsfp_is_diag_support(struct transvr_obj_s *self, + int diag_type) { + /* Input Parm: diag_type + * => 1 : temperature + * => 2 : voltage + * => 3 : tx relate + * => 4 : rx relate + */ + uint8_t mask_b2 = 0x04; /* 0000 0100 */ + uint8_t mask_b3 = 0x08; /* 0000 1000 */ + + switch (diag_type) { + case 1: /* temperature */ + case 2: /* voltage */ + /* Direct access target, because of spec not defined */ + return 1; + case 3: + case 4: + /* [Note] + * Due to lot of transceiver vendor defined it not rigorously and + * consider of general support, we seem it as supported if there + * are bit-2 OR bit-3 defined by transceiver vendor. + */ + if ( ((self->diag_type & mask_b2) == mask_b2 ) || + ((self->diag_type & mask_b3) == mask_b3 ) ){ + return 1; + } + return 0; + default: + SWPS_INFO("%s: undefined diag_type:%d\n", + __func__, diag_type); + break; + } + return 0; +} + + +int +_qsfp_is_implement_tx_disable(struct transvr_obj_s *self) { + /* + * 00h / Byte-195 / Bit-4 + */ + int byte = 2; + int bit = 4; + return _common_get_option_value(self, byte, bit); +} + + +int +_qsfp_is_implement_tx_fault(struct transvr_obj_s *self) { + /* + * 00h / Byte-195 / Bit-3 + */ + int byte = 2; + int bit = 3; + return _common_get_option_value(self, byte, bit); +} + + +static int +_qsfp_update_attr_curr_temp(struct transvr_obj_s *self, + int show_err){ + int diag_type = 1; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_temp, + self->eeprom_map_p->page_temp, + self->eeprom_map_p->offset_temp, + self->eeprom_map_p->length_temp, + self->curr_temp, + "_qsfp_update_attr_curr_temp", + show_err); +} + + +static int +_qsfp_update_attr_curr_voltage(struct transvr_obj_s *self, + int show_err){ + int diag_type = 2; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_voltage, + self->eeprom_map_p->page_voltage, + self->eeprom_map_p->offset_voltage, + self->eeprom_map_p->length_voltage, + self->curr_voltage, + "_qsfp_update_attr_curr_voltage", + show_err); +} + + +static int +_qsfp_update_attr_curr_tx_bias(struct transvr_obj_s *self, + int show_err){ + int diag_type = 3; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_bias, + self->eeprom_map_p->page_tx_bias, + self->eeprom_map_p->offset_tx_bias, + self->eeprom_map_p->length_tx_bias, + self->curr_tx_bias, + "_qsfp_update_attr_curr_tx_bias", + show_err); +} + + +static int +_qsfp_update_attr_curr_tx_power(struct transvr_obj_s *self, + int show_err){ + int diag_type = 3; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_power, + self->eeprom_map_p->page_tx_power, + self->eeprom_map_p->offset_tx_power, + self->eeprom_map_p->length_tx_power, + self->curr_tx_power, + "_qsfp_update_attr_curr_tx_power", + show_err); +} + + +static int +_qsfp_update_attr_curr_rx_power(struct transvr_obj_s *self, + int show_err){ + int diag_type = 4; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_power, + self->eeprom_map_p->page_rx_power, + self->eeprom_map_p->offset_rx_power, + self->eeprom_map_p->length_rx_power, + self->curr_rx_power, + "_qsfp_update_attr_curr_rx_power", + show_err); +} + + +static int +_qsfp_update_attr_soft_rx_los(struct transvr_obj_s *self, + int show_err){ + + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_los, + self->eeprom_map_p->page_rx_los, + self->eeprom_map_p->offset_rx_los, + self->eeprom_map_p->length_rx_los, + &(self->rx_los), + "_qsfp_update_attr_soft_rx_los", + show_err); +} + + +static int +_qsfp_update_attr_soft_tx_disable(struct transvr_obj_s *self, + int show_err){ + + if (!_qsfp_is_implement_tx_disable(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + self->eeprom_map_p->length_tx_disable, + &(self->tx_disable), + "_qsfp_update_attr_soft_tx_disable", + show_err); +} + + +static int +_qsfp_update_attr_soft_tx_fault(struct transvr_obj_s *self, + int show_err){ + + if (!_qsfp_is_implement_tx_fault(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_fault, + self->eeprom_map_p->page_tx_fault, + self->eeprom_map_p->offset_tx_fault, + self->eeprom_map_p->length_tx_fault, + &(self->tx_fault), + "_qsfp_update_attr_soft_tx_fault", + show_err); +} + + +static int +_qsfp_update_attr_tx_eq(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + self->eeprom_map_p->length_tx_eq, + self->tx_eq, + "_qsfp_update_attr_tx_eq", + show_err); +} + + +static int +_qsfp_update_attr_rx_am(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_am, + self->eeprom_map_p->page_rx_am, + self->eeprom_map_p->offset_rx_am, + self->eeprom_map_p->length_rx_am, + self->rx_am, + "_qsfp_update_attr_rx_am", + show_err); +} + + +static int +_qsfp_update_attr_rx_em(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + self->eeprom_map_p->length_rx_em, + self->rx_em, + "_qsfp_update_attr_rx_em", + show_err); +} + + +int +_common_update_attr_all(struct transvr_obj_s *self, + int show_err){ + + char *err_str = "err"; + + if (_common_update_attr_id(self, show_err) < 0) { + err_str = "_common_update_attr_id"; + goto err_common_update_attr_all; + } + if (_common_update_attr_extended_id(self, show_err) < 0) { + err_str = "_common_update_attr_extended_id"; + goto err_common_update_attr_all; + } + if (_common_update_attr_connector(self, show_err) < 0) { + err_str = "_common_update_attr_connector"; + goto err_common_update_attr_all; + } + if (_common_update_attr_transvr_comp(self, show_err) < 0) { + err_str = "_common_update_attr_transvr_comp"; + goto err_common_update_attr_all; + } + if (_common_update_attr_transvr_comp_ext(self, show_err) < 0) { + err_str = "_common_update_attr_transvr_comp_ext"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_name(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_name"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_pn(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_pn"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_rev(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_rev"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_sn(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_sn"; + goto err_common_update_attr_all; + } + if (_common_update_attr_br(self, show_err) < 0) { + err_str = "_common_update_attr_br"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_smf(self, show_err) < 0) { + err_str = "_common_update_attr_len_smf"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om1(self, show_err) < 0) { + err_str = "_common_update_attr_len_om1"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om2(self, show_err) < 0) { + err_str = "_common_update_attr_len_om2"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om3(self, show_err) < 0) { + err_str = "_common_update_attr_len_om3"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om4(self, show_err) < 0) { + err_str = "_common_update_attr_len_om4"; + goto err_common_update_attr_all; + } + if (_common_update_attr_option(self, show_err) < 0) { + err_str = "_common_update_attr_option"; + goto err_common_update_attr_all; + } + if (_common_update_attr_comp_rev(self, show_err) < 0) { + err_str = "_common_update_attr_comp_rev"; + goto err_common_update_attr_all; + } + if (_common_update_attr_diag_type(self, show_err) < 0) { + err_str = "_common_update_attr_diag_type"; + goto err_common_update_attr_all; + } + if (_common_update_attr_wavelength(self, show_err) < 0) { + err_str = "_common_update_attr_wavelength"; + goto err_common_update_attr_all; + } + return 0; + +err_common_update_attr_all: + if (show_err){ + SWPS_INFO("%s: fail at:%s :%s\n", __func__, err_str, self->swp_name); + } + return -1; +} + + +int +_sfp_update_attr_all(struct transvr_obj_s *self, + int show_err){ + + char *err_str = DEBUG_TRANSVR_STR_VAL; + + if (_common_update_attr_all(self, show_err) < 0){ + err_str = "_common_update_attr_all"; + goto err_sfp_update_attr_all; + } + if (_sfp_update_attr_len_sm(self, show_err) < 0) { + err_str = "_sfp_update_attr_len_sm"; + goto err_sfp_update_attr_all; + } + if (_sfp_update_attr_rate_id(self, show_err) < 0) { + err_str = "_sfp_update_attr_rate_id"; + goto err_sfp_update_attr_all; + } + if ((self->rate_id) > 0) { + if (_sfp_update_attr_soft_rs0(self, show_err) < 0) { + err_str = "_sfp_update_attr_soft_rs0"; + goto err_sfp_update_attr_all; + } + if (_sfp_update_attr_soft_rs1(self, show_err) < 0) { + err_str = "_sfp_update_attr_soft_rs1"; + goto err_sfp_update_attr_all; + } + } + return 0; + +err_sfp_update_attr_all: + if (show_err){ + SWPS_INFO("%s: fail at:%s :%s\n", __func__, err_str, self->swp_name); + } + return -1; +} + + +int +_qsfp_update_attr_all(struct transvr_obj_s *self, + int show_err){ + + char *err_str = DEBUG_TRANSVR_STR_VAL; + + if (_common_update_attr_all(self, show_err) < 0){ + err_str = "_common_update_attr_all"; + goto err_qsfp_update_attr_all; + } + if (_qsfg_update_attr_extbr(self, show_err) < 0) { + err_str = "_qsfg_update_attr_extbr"; + goto err_qsfp_update_attr_all; + } + if (self->type == TRANSVR_TYPE_QSFP_28) { + if (_qsfp_update_attr_cdr(self, 1) < 0) { + err_str = "_qsfp_update_attr_cdr"; + goto err_qsfp_update_attr_all; + } + } + return 0; + +err_qsfp_update_attr_all: + if (show_err){ + SWPS_INFO("%s: fail at:%s :%s\n", __func__, err_str, self->swp_name); + } + return -1; +} + + +/* ========== Object functions for common type ========== + */ +int +_common_count_temp(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + int sign = 0; + int high = 0; + int low = 0; + int lmax = 8; + + /* Count high */ + sign = get_bit(high_byte,7); + SWP_BIT_CLEAR(high_byte, 7); + high = (int)high_byte; + if (sign == 1) { + high = 0 - high; + } + /* Count low */ + low = (get_bit(low_byte, 7) * 500); + low += (get_bit(low_byte, 6) * 250); + low += (get_bit(low_byte, 5) * 125); + low += (get_bit(low_byte, 4) * 62); + low = (low / 100); + /* Integrate High and Low */ + return snprintf(buf_p, lmax, "%d.%d\n", high, low); +} + + +int +_common_count_voltage(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note]: + * Internally measured transceiver supply voltage. Represented + * as a 16 bit unsigned integer with the voltage defined as the + * full 16 bit value (0-65535) with LSB equal to 100 uVolt, + * yielding a total range of 0 to +6.55 Volts. Practical + * considerations to be defined by transceiver manufacturer will + * tend to limit the actual bounds of the supply voltage measurement. + * Accuracy is vendor specific but must be better than 3% of the + * manufacturer's nominal value over specified operating temperature + * and voltage. Note that in some transceivers, transmitter supply + * voltage and receiver supply voltage are isolated. In that case, + * only one supply is monitored. Refer to the device specification + * for more detail. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 100 uV (1mV=1000uV) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total/10) / 1000); + val_f = ((total/10) - (val_i*1000)); + /* Return Unit: 1 Volt */ + return snprintf(buf_p, lmax, "%d.%03d\n", val_i, val_f); +} + + +int +_common_count_tx_bias(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note] + * Measured TX bias current in uA. Represented as a 16 bit unsigned + * integer with the current defined as the full 16 bit value (0-65535) + * with LSB equal to 2 uA, yielding a total range of 0 to 131 mA. + * Accuracy is vendor specific but must be better than 10% of the + * manufacturer's nominal value over specified operating temperature + * and voltage. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 2 uA (1mA=1000uA) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total*2) / 1000); + val_f = (((total*2) - (val_i*1000)) / 100); + /* Return Unit: 1 mA */ + return snprintf(buf_p, lmax, "%d.%01d\n", val_i, val_f); +} + + +int +_common_count_tx_power(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note] + * Measured TX output power in mW. Represented as a 16 bit unsigned + * integer with the power defined as the full 16 bit value (0-65535) + * with LSB equal to 0.1 uW, yielding a total range of 0 to 6.5535 mW + * (~ -40 to +8.2 dBm). Data is assumed to be based on measurement of + * laser monitor photodiode current. It is factory calibrated to absolute + * units using the most representative fiber output type. Accuracy is + * vendor specific but must be better than 3dB over specified temperature + * and voltage. Data is not valid when the transmitter is disabled. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 0.1 uW (1mW=1000uW) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total/10) / 1000); + val_f = ((total/10) - (val_i*1000)); + /* Return Unit: 1 mW */ + return snprintf(buf_p, lmax, "%d.%03d\n", val_i, val_f); +} + + +int +_common_count_rx_power(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note] + * Measured RX received optical power in mW. Value can represent either + * average received power or OMA depending upon how bit 3 of byte 92 (A0h) + * is set. Represented as a 16 bit unsigned integer with the power defined + * as the full 16 bit value (0-65535) with LSB equal to 0.1 uW, yielding a + * total range of 0 to 6.5535 mW (~ -40 to +8.2 dBm). Absolute accuracy is + * dependent upon the exact optical wavelength. For the vendor specified + * wavelength, accuracy shall be better than 3dB over specified temperature + * and voltage. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 0.1 uW (1mW=1000uW) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total/10) / 1000); + val_f = ((total/10) - (val_i*1000)); + /* Return Unit: 1 mW */ + return snprintf(buf_p, lmax, "%d.%03d\n", val_i, val_f); +} + + +int +_common_count_wavelength(struct transvr_obj_s *self, + uint8_t high_byte, + uint8_t low_byte) { + /* [Note] + * SFP : uint 1 um. + * QSFP: unit 0.05 um. + */ + int total = 0; + + total = transform_word_to_int(high_byte, low_byte); + switch (self->type) { + case TRANSVR_TYPE_SFP: + return total; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + return (total/20); + + default: + break; + } + return ERR_TRANSVR_UNDEFINED; +} + + +int +common_get_id(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_id, + "common_get_id"); + if (err_code < 0){ + return err_code; + } + /* Transform to INT to show error case */ + return (int)self->id; +} + + +int +common_get_ext_id(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_extended_id, + "common_get_ext_id"); + if (err_code < 0){ + return err_code; + } + /* Transform to INT to show error case */ + return (int)self->ext_id; +} + + +int +common_get_connector(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_connector, + "common_get_connector"); + if (err_code < 0){ + return err_code; + } + /* Transform to INT to show error case */ + return (int)self->connector; +} + + +int +common_get_vendor_name(struct transvr_obj_s *self, char *buf){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_name); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_name, + "common_get_vendor_name"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_name); +} + + +int +common_get_vendor_pn(struct transvr_obj_s *self, char *buf) { + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_pn); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_pn, + "common_get_vendor_pn"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_pn); +} + + +int +common_get_vendor_rev(struct transvr_obj_s *self, char *buf) { + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_rev); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_rev, + "common_get_vendor_rev"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_rev); +} + + +int +common_get_vendor_sn(struct transvr_obj_s *self, char *buf) { + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_sn); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_sn, + "common_get_vendor_sn"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_sn); +} + + +int +common_get_br(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return (int)self->br; + } + err = _check_by_mode(self, + &_common_update_attr_br, + "common_get_br"); + if (err < 0){ + return err; + } + /* Transform to INT to show error case */ + return (int)self->br; +} + + +int +common_get_len_smf(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_smf; + } + err = _check_by_mode(self, + &_common_update_attr_len_smf, + "common_get_len_smf"); + if (err < 0){ + return err; + } + return self->len_smf; +} + + +int +common_get_len_om1(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om1; + } + err = _check_by_mode(self, + &_common_update_attr_len_om1, + "common_get_len_om1"); + if (err < 0){ + return err; + } + return self->len_om1; +} + + +int +common_get_len_om2(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om2; + } + + err = _check_by_mode(self, + &_common_update_attr_len_om2, + "common_get_len_om2"); + if (err < 0){ + return err; + } + return self->len_om2; +} + + +int +common_get_len_om3(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om3; + } + + err = _check_by_mode(self, + &_common_update_attr_len_om3, + "common_get_len_om3"); + if (err < 0){ + return err; + } + return self->len_om3; +} + + +int +common_get_len_om4(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om4; + } + err = _check_by_mode(self, + &_common_update_attr_len_om4, + "common_get_len_om4"); + if (err < 0){ + return err; + } + return self->len_om4; +} + + +int +common_get_comp_extended(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp_ext, + "common_get_comp_extended"); + if (err_code < 0){ + return err_code; + } + return self->transvr_comp_ext; +} + + +int +common_get_comp_rev(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_comp_rev, + "common_get_comp_rev"); + if (err_code < 0){ + return err_code; + } + return self->comp_rev; +} + + +int +common_get_info(struct transvr_obj_s *self){ + + if (self->state != STATE_TRANSVR_CONNECTED) { + return self->state; + } + return self->info; +} + + +int +_common_get_if_lane(struct transvr_obj_s *self, + char *result){ + int i = 0; + int tmp_val = 0; + char tmp_str[LEN_TRANSVR_M_STR] = DEBUG_TRANSVR_STR_VAL; + + memset(result, 0, LEN_TRANSVR_M_STR); + + for (i=0; ilane_id); i++) { + tmp_val = self->lane_id[i]; + if (tmp_val < 1) { + break; + } + memset(tmp_str, 0, LEN_TRANSVR_M_STR); + if (i == 0) { + snprintf(tmp_str, LEN_TRANSVR_M_STR, "%d", tmp_val); + } else { + snprintf(tmp_str, LEN_TRANSVR_M_STR, ",%d", tmp_val); + } + strncat(result, tmp_str, LEN_TRANSVR_M_STR); + } + if (i == 0) { + return EVENT_TRANSVR_TASK_FAIL; + } + return 0; +} + + +int +common_get_if_lane(struct transvr_obj_s *self, + char *buf_p){ + + char tmp_str[LEN_TRANSVR_M_STR] = DEBUG_TRANSVR_STR_VAL; + + if (self->ioexp_obj_p->state != STATE_IOEXP_NORMAL) { + return snprintf(buf_p, LEN_TRANSVR_M_STR, "%d\n", ERR_TRANSVR_ABNORMAL); + } + if (_common_get_if_lane(self, tmp_str) < 0) { + return snprintf(buf_p, LEN_TRANSVR_M_STR, "%d\n" ,ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, LEN_TRANSVR_M_STR, "%s\n" ,tmp_str); +} + + +int +sfp_get_len_sm(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_sfp_update_attr_len_sm, + "sfp_get_len_sm"); + if (err_code < 0){ + return err_code; + } + return self->len_sm; +} + + +int +sfp_get_rate_id(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_sfp_update_attr_rate_id, + "sfp_get_rate_id"); + if (err_code < 0){ + return err_code; + } + return self->rate_id; +} + + +int +sfp_get_soft_rs0(struct transvr_obj_s *self){ + /* Note: + * SFP Soft Rate_Select Select [aka. "RS(0)"] address + * A2h, offset: 110, bit 3 (begin form 0) + */ + int err_code = DEBUG_TRANSVR_INT_VAL; + int bit_shift = 3; + uint8_t result = 0x00; + uint8_t bitmask = (1 << bit_shift); + + /* Check rate identifier is supported */ + err_code = self->get_rate_id(self); + if (err_code <= 0) { + return ERR_TRANSVR_NOTSUPPORT; + } + /* Update and check */ + err_code = _check_by_mode(self, + &_sfp_update_attr_soft_rs0, + "sfp_get_soft_rs0"); + if (err_code <0){ + return err_code; + } + result = (self->soft_rs0 & bitmask); + if (result == bitmask) { + return 1; + } + if (result == 0) { + return 0; + } + return ERR_TRANSVR_UNEXCPT; +} + + +int +sfp_get_soft_rs1(struct transvr_obj_s *self){ + /* Note: + * SFP Soft RS(1) Select address + * A2h, offset: 118, bit 3 (begin form 0) + */ + int err_code = DEBUG_TRANSVR_INT_VAL; + int bit_shift = 3; + uint8_t result = 0x00; + uint8_t bitmask = (1 << bit_shift); + + /* Check rate identifier is supported */ + err_code = self->get_rate_id(self); + if (err_code <= 0) { + return ERR_TRANSVR_NOTSUPPORT; + } + /* Update and check */ + err_code = _check_by_mode(self, + &_sfp_update_attr_soft_rs1, + "sfp_get_soft_rs1"); + if (err_code <0){ + return err_code; + } + result = (self->soft_rs1 & bitmask); + if (result == bitmask) { + return 1; + } + if (result == 0) { + return 0; + } + return ERR_TRANSVR_UNEXCPT; +} + + +int +sfp_get_transvr_temp(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_temp, + "sfp_get_transvr_temp"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_temp[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return _common_count_temp(self->curr_temp[0], + self->curr_temp[1], + buf_p); +} + + +int +sfp_get_transvr_voltage(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_voltage, + "sfp_get_transvr_voltage"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_voltage[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 Volt */ + return _common_count_voltage(self->curr_voltage[0], + self->curr_voltage[1], + buf_p); +} + + +int +sfp_get_transvr_tx_bias(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_tx_bias, + "sfp_get_transvr_tx_bias"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mA */ + return _common_count_tx_bias(self->curr_tx_bias[0], + self->curr_tx_bias[1], + buf_p); +} + + +int +sfp_get_transvr_tx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_tx_power, + "sfp_get_transvr_tx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _common_count_tx_power(self->curr_tx_power[0], + self->curr_tx_power[1], + buf_p); +} + + +int +sfp_get_transvr_rx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_rx_power, + "sfp_get_transvr_rx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _common_count_rx_power(self->curr_rx_power[0], + self->curr_rx_power[1], + buf_p); +} + + +int +sfp_get_transvr_rx_em(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_sfp_update_attr_rx_em, + "sfp_get_transvr_rx_em"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->tx_eq[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x\n", self->rx_em[0]); +} + + +int +sfp_get_transvr_tx_eq(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_sfp_update_attr_tx_eq, + "sfp_get_transvr_tx_eq"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->tx_eq[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x\n", self->tx_eq[0]); +} + + +int +_sfp_get_comp_extended(struct transvr_obj_s *self) { + /* Address: A0h / 36 + * Reference: SFF-8024 TABLE 4-4 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp_ext); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +__sfp_get_comp_attr(struct transvr_obj_s *self, + int array_offset) { + /* SFP Specification Compliance: A0h / 3-10 + * transvr_comp[0-7] = 3 - 10 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp[array_offset]); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +_sfp_get_comp_10g_eth_comp(struct transvr_obj_s *self) { + /* transvr_comp[0] = address A0h / 3 + * + * 3 7: 10G Base-ER + * 3 6: 10GBASE-LRM + * 3 5: 10GBASE-LR + * 3 4: 10GBASE-SR + */ + int bitmask = 0xf0; /* 11110000 */ + return (__sfp_get_comp_attr(self, 0) & bitmask); +} + + +int +_sfp_get_comp_1g_eth_comp(struct transvr_obj_s *self) { + /* transvr_comp[3] = address A0h / 6 + * + * 6 7: BASE-PX *3 + * 6 6: BASE-BX10 *3 + * 6 5: 100BASE-FX + * 6 4: 100BASE-LX/LX10 + * 6 3: 1000BASE-T + * 6 2: 1000BASE-CX + * 6 1: 1000BASE-LX *3 + * 6 0: 1000BASE-SX + */ + return __sfp_get_comp_attr(self, 3); +} + + +int +_sfp_get_cable_tech(struct transvr_obj_s *self) { + /* transvr_comp[5] = address A0h / 8 + * + * 8 3: Active Cable *8 + * 8 2: Passive Cable *8 + */ + int bitmask = 0x0c; /* 00001100 */ + return (__sfp_get_comp_attr(self, 5) & bitmask); +} + + +int +sfp_get_comp_eth_1(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "sfp_get_comp_eth_1"); + if (err_code < 0){ + return err_code; + } + return _sfp_get_comp_1g_eth_comp(self); +} + + +int +sfp_get_comp_eth_10(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "sfp_get_comp_eth_10"); + if (err_code < 0){ + return err_code; + } + return _sfp_get_comp_10g_eth_comp(self); +} + + +int +_sfp_get_connector_type(struct transvr_obj_s *self) { + /* Address: A0h / 2 + * Reference: SFF-8024 TABLE 4-3 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->connector); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +sfp_get_wavelength(struct transvr_obj_s *self, + char *buf_p) { + /* [Note] Optical and Cable Variants Specification Compliance (SFF-8472) + * [Addr] A0h, Bytes 60-61 + * [Note] For optical variants, as defined by having zero's in A0h Byte 8 + * bits 2 and 3, Bytes 60 and 61 denote nominal transmitter output + * wavelength at room temperature. 16 bit value with byte 60 as high + * order byte and byte 61 as low order byte. The laser wavelength is + * equal to the 16 bit integer value in nm. This field allows the user + * to read the laser wavelength directly, so it is not necessary to + * infer it from the Transceiver Codes A0h Bytes 3 to 10 (see Table + * 5-3). This also allows specification of wavelengths not covered + * in the Transceiver Codes, such as those used in coarse WDM systems. + * + * For passive and active cable variants, a value of 00h for both A0h + * Byte 60 and Byte 61 denotes laser wavelength or cable specification + * compliance is unspecified. + */ + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_common_update_attr_wavelength, + "common_get_wavelength"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->wavelength[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* unit: 1 um */ + return snprintf(buf_p, lmax, "%d\n", + _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1])); +} + + +int +sfp_get_1g_rj45_extphy_offset(struct transvr_obj_s *self, char *buf) { + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + return snprintf(buf, LEN_TRANSVR_S_STR, "0x%02x\n", self->extphy_offset); +} + + +int +sfp_get_1g_rj45_extphy_reg(struct transvr_obj_s *self, char *buf) { + + int i = 0; + int ret = 0; + int retry = 3; + int delay = 200; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + if (_common_setup_page(self, VAL_TRANSVR_EXTPHY_ADDR_56, + -1, self->extphy_offset, 1, 0) < 0) { + return -EIO; + } + for (i=0; ii2c_client_p, self->extphy_offset); + if (ret >=0) { + goto ok_sfp_get_1g_rj45_extphy_reg; + } + msleep(delay); + } + SWPS_INFO("%s: retry:%d fail :%s :0x%02x\n", + __func__, retry, self->swp_name, self->extphy_offset); + return -EIO; + +ok_sfp_get_1g_rj45_extphy_reg: + ret = ((ret & 0x00ff) << 8) | ((ret & 0xff00) >> 8); + return snprintf(buf, LEN_TRANSVR_S_STR, "0x%04x\n", ret); +} + + +int +__qsfp_get_power_cls(struct transvr_obj_s *self, + int direct_access){ + + int err_code; + uint8_t detect_val; + + /* Detect and Update power class attribute */ + if (direct_access){ + err_code = _check_by_mode(self, + &_common_update_attr_extended_id, + "__qsfp_get_power_cls"); + } else { + err_code = self->ext_id; + } + if (err_code <0){ + return err_code; + } + if (err_code == DEBUG_TRANSVR_HEX_VAL){ + return ERR_TRANSVR_UPDATE_FAIL; + } + /* Clean data */ + detect_val = self->ext_id; + SWP_BIT_CLEAR(detect_val, 2); /* Bit2: CDR RX present */ + SWP_BIT_CLEAR(detect_val, 3); /* Bit3: CDR TX present */ + SWP_BIT_CLEAR(detect_val, 4); /* Bit4: CLEI present */ + SWP_BIT_CLEAR(detect_val, 5); /* Bit5: reserved */ + /* Identify power class */ + switch (detect_val) { + case 0: /* Class_1: 00000000 */ + return 1; + case 64: /* Class_2: 01000000 */ + return 2; + case 128: /* Class_3: 10000000 */ + return 3; + case 192: /* Class_4: 11000000 */ + return 4; + case 1: /* Class_5: 00000001 */ + case 193: /* Class_5: 11000001 */ + return 5; + case 2: /* Class_6: 00000010 */ + case 194: /* Class_6: 11000010 */ + return 6; + case 3: /* Class_7: 00000011 */ + case 195: /* Class_7: 11000011 */ + return 7; + default: + break; + } + SWPS_INFO("%s: Detect undefined power class:%d\n", __func__, detect_val); + return ERR_TRANSVR_UNDEFINED; +} + + +int +qsfp_get_power_cls(struct transvr_obj_s *self) { + return __qsfp_get_power_cls(self, 1); +} + + +int +__qsfp_get_cdr_present(struct transvr_obj_s *self, + int direct_access){ + + int retval; + int BIT_SHIFT = 2; + int BIT_MASK = 0x3; + + /* Detect and Update power class attribute */ + if (direct_access) { + retval = _check_by_mode(self, + &_common_update_attr_extended_id, + "__qsfp_get_cdr_present"); + if (retval < 0){ + return retval; + } + } + retval = self->ext_id; + if (retval == DEBUG_TRANSVR_HEX_VAL){ + return ERR_TRANSVR_UPDATE_FAIL; + } + /* Clean data and return */ + return (int)(retval >> BIT_SHIFT & BIT_MASK); +} + + +int +qsfp_get_cdr_present(struct transvr_obj_s *self) { + return __qsfp_get_cdr_present(self, 1); +} + + +int +qsfp_get_cdr(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_qsfp_update_attr_cdr, + "qsfp_get_cdr"); + if (err_code <0){ + return err_code; + } + + return self->cdr; +} + + +int +__qsfp_get_comp_attr(struct transvr_obj_s *self, + int array_offset) { + /* QSFP Specification Compliance: 00h / 131-138 + * transvr_comp[0-7] = 131 - 138 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp[array_offset]); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +_qsfp_get_comp_10_40_100_ethernet(struct transvr_obj_s *self) { + /* transvr_comp[0] = address 00h / 131 + * + * 131 7: Extended: See section 6.3.23. The Extended Specification Compliance + * Codes are maintained in the Transceiver Management section of SFF- + * 8024. + * 131 6: 10GBASE-LRM + * 131 5: 10GBASE-LR + * 131 4: 10GBASE-SR + * 131 3: 40GBASE-CR4 + * 131 2: 40GBASE-SR4 + * 131 1: 40GBASE-LR4 + * 131 0: 40G Active Cable (XLPPI) + */ + return __qsfp_get_comp_attr(self, 0); +} + + +int +_qsfp_get_comp_sonet(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 132 7-3: Reserved + * 132 2: OC 48, long reach + * 132 1: OC 48, intermediate reach + * 132 0: OC 48 short reach + */ + return __qsfp_get_comp_attr(self, 1); +} + + +int +_qsfp_get_comp_sas_sata(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 133 7: SAS 24.0 Gb/s + * 133 6: SAS 12.0 Gb/s + * 133 5: SAS 6.0 Gb/s + * 133 4: SAS 3.0 Gb/s + * 133 3-0: Reserved + */ + return __qsfp_get_comp_attr(self, 2); +} + + +int +_qsfp_get_comp_ethernet(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 134 7-4: Reserved + * 134 3: 1000BASE-T + * 134 2: 1000BASE-CX + * 134 1: 1000BASE-LX + * 134 0: 1000BASE-SX + */ + return __qsfp_get_comp_attr(self, 3); +} + + +int +_qsfp_get_comp_fc_link_length(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 135 7: Very long distance (V) + * 135 6: Short distance (S) + * 135 5: Intermediate distance (I) + * 135 4: Long distance (L) + * 135 3: Medium (M) + */ + int mask = 0xFC; /* 11111100 */ + return (__qsfp_get_comp_attr(self, 4) & mask); +} + + +int +_qsfp_get_comp_fc_trans_tech(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 135 2: Reserved + * 135 1: Longwave laser (LC) + * 135 0: Electrical inter-enclosure (EL) + * + * 136 7: Electrical intra-enclosure + * 136 6: Shortwave laser w/o OFC (SN) + * 136 5: Shortwave laser w OFC (SL) + * 136 4: Longwave Laser (LL) + * 136 3-0: Reserved + * + * return value = [bit 8-15:addr 135][bit 0-7:addr 136] + */ + int mask_135 = 7; /* 00000111 */ + int val_135 = (__qsfp_get_comp_attr(self, 4) & mask_135); + int val_136 = __qsfp_get_comp_attr(self, 5); + return ((val_135 << 7) + val_136); +} + + +int +_qsfp_get_comp_fc_trans_media(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 137 7: Twin Axial Pair (TW) + * 137 6: Shielded Twisted Pair (TP) + * 137 5: Miniature Coax (MI) + * 137 4: Video Coax (TV) + * 137 3: Multi-mode 62.5 m (M6) + * 137 2: Multi-mode 50 m (M5) + * 137 1: Multi-mode 50 um (OM3) + * 137 0: Single Mode (SM) + */ + return __qsfp_get_comp_attr(self, 6); +} + + +int +_qsfp_get_comp_fc_speed(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 138 7: 1200 MBps (per channel) + * 138 6: 800 MBps + * 138 5: 1600 MBps (per channel) + * 138 4: 400 MBps + * 138 3: 3200 MBps (per channel) + * 138 2: 200 MBps + * 138 1: Extended: See section 6.3.23. The Extended Specification + * Compliance Codes are maintained in the Transceiver Management + * section of SFF-8024. + * 138 0: 100 MBps + */ + return __qsfp_get_comp_attr(self, 7); +} + + +int +_qsfp_get_comp_extended(struct transvr_obj_s *self) { + /* Address: 00h / 192 + * Reference: SFF-8024 TABLE 4-4 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp_ext); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_comp_eth(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "qsfp_get_comp_eth"); + if (err_code < 0){ + return err_code; + } + return _qsfp_get_comp_ethernet(self); +} + + +int +qsfp_get_comp_10_40(struct transvr_obj_s *self) { + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "qsfp_get_comp_10_40"); + if (err_code < 0){ + return err_code; + } + return _qsfp_get_comp_10_40_100_ethernet(self); +} + + +int +_qsfp_get_connector_type(struct transvr_obj_s *self) { + /* Address: 00h / 130 + * Reference: SFF-8024 TABLE 4-3 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->connector); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_transvr_temp(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_temp, + "qsfp_get_transvr_temp"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_temp[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return _common_count_temp(self->curr_temp[0], + self->curr_temp[1], + buf_p); +} + + +int +qsfp_get_transvr_voltage(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_voltage, + "qsfp_get_transvr_voltage"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_voltage[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 Volt */ + return _common_count_voltage(self->curr_voltage[0], + self->curr_voltage[1], + buf_p); +} + + +int +qsfp_get_transvr_tx_eq(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_qsfp_update_attr_tx_eq, + "qsfp_get_transvr_tx_eq"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->tx_eq[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x%02x\n", + self->tx_eq[0], self->tx_eq[1]); +} + + +int +qsfp_get_transvr_rx_am(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_qsfp_update_attr_rx_am, + "qsfp_get_transvr_rx_am"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->rx_am[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x%02x\n", + self->rx_am[0], self->rx_am[1]); +} + + +int +qsfp_get_transvr_rx_em(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_qsfp_update_attr_rx_em, + "qsfp_get_transvr_rx_em"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->rx_em[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x%02x\n", + self->rx_em[0], self->rx_em[1]); +} + + +int +_qsfp_get_channel_diag(uint8_t *data_array, + int (*count_func)(uint8_t high_byte, uint8_t low_byte, char *buf_p), + char *ch_name, + char *result_p) { + int i, high, low; + int len_max = 128; + char ch_buf[4][16] = { DEBUG_TRANSVR_STR_VAL, + DEBUG_TRANSVR_STR_VAL, + DEBUG_TRANSVR_STR_VAL, + DEBUG_TRANSVR_STR_VAL }; + + for (i=0; i<4; i++) { + high = (i*2); + low = ((i*2) + 1); + count_func(data_array[high], data_array[low], ch_buf[i]); + } + return snprintf(result_p, len_max, + "%s-%d:%s%s-%d:%s%s-%d:%s%s-%d:%s", + ch_name, 1, ch_buf[0], + ch_name, 2, ch_buf[1], + ch_name, 3, ch_buf[2], + ch_name, 4, ch_buf[3]); +} + + +int +qsfp_get_soft_rx_los(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int mask = 0x0f; /* Bit 0 ~ Bit 3 */ + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_soft_rx_los, + "qsfp_get_soft_rx_los"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + return snprintf(buf_p, lmax, "0x%02x\n", (self->rx_los & mask)); +} + + +int +qsfp_get_soft_tx_disable(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int mask = 0x0f; /* Bit 0 ~ Bit 3 */ + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_disable, + "qsfp_get_soft_tx_disable"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + return snprintf(buf_p, lmax, "0x%02x\n", (self->tx_disable & mask)); +} + + +int +qsfp_get_soft_tx_fault(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int mask = 0x0f; /* Bit 0 ~ Bit 3 */ + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_fault, + "qsfp_get_soft_tx_fault"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + return snprintf(buf_p, lmax, "0x%02x\n", (self->tx_fault & mask)); +} + + +int +qsfp_get_auto_tx_disable(struct transvr_obj_s *self, + char *buf_p) { + + if (self->auto_tx_disable == VAL_TRANSVR_FUNCTION_DISABLE) { + return snprintf(buf_p, LEN_TRANSVR_S_STR, + "%d\n", ERR_TRANSVR_FUNC_DISABLE); + } + return snprintf(buf_p, LEN_TRANSVR_S_STR, + "0x%02x\n", self->auto_tx_disable); +} + + +int +qsfp_get_transvr_tx_bias(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *ch_name = "TX"; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_tx_bias, + "qsfp_get_transvr_tx_bias"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mA */ + return _qsfp_get_channel_diag(self->curr_tx_bias, + _common_count_tx_bias, + ch_name, + buf_p); +} + + +int +qsfp_get_transvr_tx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *ch_name = "TX"; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_tx_power, + "qsfp_get_transvr_tx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_power[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _qsfp_get_channel_diag(self->curr_tx_power, + _common_count_tx_power, + ch_name, + buf_p); +} + + +int +qsfp_get_transvr_rx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *ch_name = "RX"; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_rx_power, + "qsfp_get_transvr_rx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_power[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _qsfp_get_channel_diag(self->curr_rx_power, + _common_count_rx_power, + ch_name, + buf_p); +} + + +int +qsfp_get_wavelength(struct transvr_obj_s *self, + char *buf_p) { + /* [Desc] Wavelength or Copper Cable Attenuation (SFF-8636) + * [Addr] 00h 186-187 + * [Note] + * For optical free side devices, this parameter identifies the nominal + * transmitter output wavelength at room temperature. This parameter is + * a 16-bit hex value with Byte 186 as high order byte and Byte 187 as + * low order byte. The laser wavelength is equal to the 16-bit integer value + * divided by 20 in nm (units of 0.05 nm). This resolution should be adequate + * to cover all relevant wavelengths yet provide enough resolution for all + * expected DWDM applications. For accurate representation of controlled + * wavelength applications, this value should represent the center of the + * guaranteed wavelength range. + * If the free side device is identified as copper cable these registers will + * be used to define the cable attenuation. An indication of 0 dB attenuation + * refers to the case where the attenuation is not known or is unavailable. + * Byte 186 (00-FFh) is the copper cable attenuation at 2.5 GHz in units of 1 dB. + * Byte 187 (00-FFh) is the copper cable attenuation at 5.0 GHz in units of 1 dB. + */ + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_common_update_attr_wavelength, + "common_get_wavelength"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->wavelength[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* unit: 1 um */ + return snprintf(buf_p, lmax, "%d\n", + _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1])); +} + + +/* Public Function for Setup Features + */ +static int +__sfp_set_soft_rs(struct transvr_obj_s *self, + int input_val, + int address, + int page, + int offset, + int bit_shift, + uint8_t *attr_p, + char *caller, + int show_err) { + + int retval = ERR_TRANSVR_UNEXCPT; + int err_code = ERR_TRANSVR_UNEXCPT; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + uint8_t update_val = (*attr_p); + + switch (input_val) { + case 0: + SWP_BIT_CLEAR(update_val, bit_shift); + break; + case 1: + SWP_BIT_SET(update_val, bit_shift); + break; + default: + retval = ERR_TRANSVR_UNEXCPT; + err_code = ERR_TRANSVR_UNEXCPT; + err_msg = "Exception occurs"; + goto err_private_sfp_set_soft_rs_1; + } + err_code = _common_set_uint8_attr(self, + address, + page, + offset, + update_val, + attr_p, + caller, + show_err); + if (err_code < 0) { + retval = err_code; + err_msg = "Write data via i2c fail!"; + goto err_private_sfp_set_soft_rs_1; + } + (*attr_p) = update_val; + return 0; + +err_private_sfp_set_soft_rs_1: + if (show_err) { + SWPS_INFO("%s: %s :%d :%s\n :%d\n", + __func__, err_msg, err_code, self->swp_name, input_val); + } + return retval; +} + + +static int +_sfp_set_soft_rs(struct transvr_obj_s *self, + int input_val, + int address, + int page, + int offset, + int bit_shift, + int (*attr_update_func)(struct transvr_obj_s *self, int show_err), + uint8_t *attr_p, + char *caller, + int show_err) { + + int retval = ERR_TRANSVR_UNEXCPT; + int err_code = ERR_TRANSVR_UNEXCPT; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + + /* Check input value */ + if ((input_val != 0) && (input_val != 1)){ + retval = ERR_TRANSVR_BADINPUT; + err_code = ERR_TRANSVR_BADINPUT; + err_msg = "Input range incorrect!"; + goto err_common_sfp_set_soft_rs_1; + } + /* Check rate identifier is supported */ + err_code = self->get_rate_id(self); + if (err_code <= 0) { + switch (err_code) { + case 0: + retval = ERR_TRANSVR_NOTSUPPORT; + err_msg = "Not support this feature"; + break; + case ERR_TRANSVR_UNINIT: + retval = ERR_TRANSVR_UNINIT; + err_msg = "Check CDR present fail!"; + break; + case ERR_TRANSVR_UNPLUGGED: + retval = ERR_TRANSVR_UNPLUGGED; + err_msg = "Transceiver unplugged!"; + break; + default: + retval = err_code; + err_msg = "Check Rate_ID fail!"; + break; + } + goto err_common_sfp_set_soft_rs_1; + } + /* Check and update */ + err_code = _check_by_mode(self, + attr_update_func, + caller); + if ( (err_code < 0) || + ((*attr_p) == DEBUG_TRANSVR_HEX_VAL) ){ + retval = err_code; + err_msg = "Get current value fail!"; + goto err_common_sfp_set_soft_rs_1; + } + /* Generate and update value */ + return __sfp_set_soft_rs(self, + input_val, + address, + page, + offset, + bit_shift, + attr_p, + caller, + show_err); + +err_common_sfp_set_soft_rs_1: + if (show_err) { + SWPS_INFO("%s: %s :%d :%s\n :%d\n", + __func__, err_msg, err_code, self->swp_name, input_val); + } + return retval; +} + + +int +sfp_set_soft_rs0(struct transvr_obj_s *self, + int input_val) { + /* Note: + * SFP Soft Rate_Select Select RX ["RS(0)"] address + * A2h, offset: 110, bit 3 + */ + int bit_shift = 3; + int show_err = 1; + return _sfp_set_soft_rs(self, + input_val, + self->eeprom_map_p->addr_soft_rs0, + self->eeprom_map_p->page_soft_rs0, + self->eeprom_map_p->offset_soft_rs0, + bit_shift, + &_sfp_update_attr_soft_rs0, + &(self->soft_rs0), + "sfp_set_soft_rs0", + show_err); +} + + +int +sfp_set_soft_rs1(struct transvr_obj_s *self, + int input_val) { + /* Note: + * SFP Soft Rate_Select Select RX ["RS(1)"] address + * A2h, offset: 118, bit 3 + */ + int bit_shift = 3; + int show_err = 1; + return _sfp_set_soft_rs(self, + input_val, + self->eeprom_map_p->addr_soft_rs1, + self->eeprom_map_p->page_soft_rs1, + self->eeprom_map_p->offset_soft_rs1, + bit_shift, + &_sfp_update_attr_soft_rs1, + &(self->soft_rs1), + "sfp_set_soft_rs1", + show_err); +} + + +int +__sfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv = DEBUG_TRANSVR_HEX_VAL; + + if ((input < 0) || (input > 0xFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_sfp_set_tx_eq; + } + setv = (uint8_t)input; + if (self->tx_eq[0] == setv) { + return 0; + } + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + setv, + &(self->tx_eq[0]), + "_sfp_set_tx_eq", + show_e); + if (err < 0) { + emsg = "set_uint8_attr fail"; + goto err_sfp_set_tx_eq; + } + return 0; + +err_sfp_set_tx_eq: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_sfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + + uint8_t tmp; + int i = 0; + int retry = 3; + + for (i=0; itx_eq[0]; + if (_sfp_update_attr_tx_eq(self, show_e) < 0){ + continue; + } + if (self->tx_eq[0] == tmp){ + return 0; + } + } + return ERR_TRANSVR_UPDATE_FAIL; +} + + +int +sfp_set_tx_eq(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_sfp_update_attr_tx_eq, + "sfp_set_tx_eq"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _sfp_set_tx_eq(self, input, 1); +} + + +int +__sfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv = DEBUG_TRANSVR_HEX_VAL; + + if ((input < 0) || (input > 0xFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_sfp_set_rx_em; + } + setv = (uint8_t)input; + if (self->rx_em[0] == setv) { + return 0; + } + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + setv, + &(self->rx_em[0]), + "_sfp_set_rx_em", + show_e); + if (err < 0) { + emsg = "set_uint8_attr fail"; + goto err_sfp_set_rx_em; + } + return 0; + +err_sfp_set_rx_em: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_sfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + + uint8_t tmp; + int i = 0; + int retry = 3; + + for (i=0; irx_em[0]; + if (_sfp_update_attr_rx_em(self, show_e) < 0){ + continue; + } + if (self->rx_em[0] == tmp){ + return 0; + } + } + return -1; +} + + +int +sfp_set_rx_em(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_sfp_update_attr_rx_em, + "sfp_set_rx_em"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _sfp_set_rx_em(self, input, 1); +} + + +int +sfp_set_1g_rj45_extphy_offset(struct transvr_obj_s *self, + int input) { + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + if ((input < 0) || (input > 0xff)) { + return ERR_TRANSVR_BADINPUT; + } + self->extphy_offset = (uint8_t)input; + return 0; +} + + +int +sfp_set_1g_rj45_extphy_reg(struct transvr_obj_s *self, + int input) { + + int i = 0; + int retry = 3; + int delay = 200; + uint16_t tmp = 0; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + if ((input < 0) || (input > 0xffff)) { + return ERR_TRANSVR_BADINPUT; + } + tmp = ((input & 0x00ff) << 8) | ((input & 0xff00) >> 8); + if (_common_setup_page(self, VAL_TRANSVR_EXTPHY_ADDR_56, + -1, self->extphy_offset, 1, 0) < 0) { + return -EIO; + } + for (i=0; i<=retry; i++) { + if (i2c_smbus_write_word_data(self->i2c_client_p, + self->extphy_offset, + tmp) >= 0) { + return 0; + } + msleep(delay); + } + SWPS_INFO("%s: retry:%d fail :%s :0x%02x\n", + __func__, retry, self->swp_name, self->extphy_offset); + return -EIO; +} + + +static int +__qsfp_set_cdr(struct transvr_obj_s *self, + int input_val, + int show_err) { + + uint8_t update_val; + int CDR_FEATURE_SUPPORTED = 0x3; + int retval = ERR_TRANSVR_UNEXCPT; + int err_code = ERR_TRANSVR_UNEXCPT; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + char *func_name = "__qsfp_set_cdr"; + + /* Check input value */ + if ((input_val < 0) || (input_val > 0xff)){ + retval = ERR_TRANSVR_BADINPUT; + err_code = ERR_TRANSVR_BADINPUT; + err_msg = "Input range incorrect!"; + goto err_qsfp_set_cdr_1; + } + update_val = (uint8_t)input_val; + /* Check CDR supported by transceiver */ + err_code = qsfp_get_cdr_present(self); + if (err_code < 0) { + retval = err_code; + switch (err_code) { + case ERR_TRANSVR_UNINIT: + err_msg = "Check CDR present fail!"; + break; + case ERR_TRANSVR_UNPLUGGED: + err_msg = "Transceiver unplugged!"; + break; + default: + err_msg = "Check CDR present fail!"; + break; + } + goto err_qsfp_set_cdr_1; + } + if (err_code != CDR_FEATURE_SUPPORTED) { + retval = ERR_TRANSVR_NOTSUPPORT; + err_msg = "This transceiver not support CDR!"; + goto err_qsfp_set_cdr_1; + } + /* Check and update */ + err_code = _check_by_mode(self, + &_qsfp_update_attr_cdr, + func_name); + if ( (err_code < 0) || + (self->cdr == DEBUG_TRANSVR_HEX_VAL) ){ + retval = err_code; + err_msg = "Get current value fail!"; + goto err_qsfp_set_cdr_1; + } + /* Write input value to transceiver */ + return _common_set_uint8_attr(self, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->page_cdr, + self->eeprom_map_p->offset_cdr, + update_val, + &(self->cdr), + func_name, + show_err); + +err_qsfp_set_cdr_1: + if (show_err) { + SWPS_INFO("%s: %s :%d :%s\n :%d\n", + __func__, err_msg, err_code, self->swp_name, input_val); + } + return retval; +} + + +int +qsfp_set_cdr(struct transvr_obj_s *self, + int input_val) { + return __qsfp_set_cdr(self, input_val, 1); +} + + +int +qsfp_set_soft_tx_disable(struct transvr_obj_s *self, + int input_val) { + + int show_err = 1; + int in_max = 0xf; /* 1111 */ + int in_min = 0x0; /* 0000 */ + int retval = DEBUG_TRANSVR_INT_VAL; + int update_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + retval = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_disable, + "qsfp_set_soft_tx_disable"); + if (retval < 0) { + snprintf(err_msg, 63, "Not ready. err:%d", retval); + goto err_qsfp_set_soft_tx_disable; + } + if ((input_val > in_max) || + (input_val < in_min) ){ + retval = ERR_TRANSVR_BADINPUT; + snprintf(err_msg, 63, "Input value:%d incorrect!", input_val); + goto err_qsfp_set_soft_tx_disable; + } + if ((self->tx_disable & 0x0f) == input_val) { + return 0; + } + update_val = ((self->tx_disable & 0xf0) & input_val); + retval = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + input_val, + &(self->tx_disable), + "qsfp_set_tx_disable", + show_err); + if (retval < 0) { + snprintf(err_msg, 63, "_common_set_uint8_attr:%d fail!", retval); + goto err_qsfp_set_soft_tx_disable; + } + return 0; + +err_qsfp_set_soft_tx_disable: + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return retval; +} + + +int +_qsfp_set_auto_tx_disable(struct transvr_obj_s *self, + uint8_t update) { + + uint8_t tx_enable = 0x0; + int show_e = 1; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + /* Handle timing issues */ + if (update != tx_enable) { + /* Note: + * Because there are some txvr has timing issues, + * therefore we need to execute reset cycle first. + * (enable -> other settings) + */ + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + tx_enable, + &(self->tx_disable), + "_qsfp_set_auto_tx_disable", + show_e); + if (err < 0) { + emsg = "I2C set reset value fail"; + goto err_qsfp_set_auto_tx_disable; + } + mdelay(10); + } + /* Setup target value */ + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + self->auto_tx_disable, + &(self->tx_disable), + "_qsfp_set_auto_tx_disable", + show_e); + if (err < 0) { + emsg = "I2C set target value fail"; + goto err_qsfp_set_auto_tx_disable; + } + /* Check and update */ + err = _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + self->eeprom_map_p->length_tx_disable, + &(self->tx_disable), + "_qsfp_set_auto_tx_disable", + show_e); + if (err < 0) { + emsg = "I2C get value fail"; + goto err_qsfp_set_auto_tx_disable; + } + if (self->tx_disable != update) { + emsg = "data not become effective"; + goto err_qsfp_set_auto_tx_disable; + } + return 0; + +err_qsfp_set_auto_tx_disable: + SWPS_DEBUG("%s: %s :%s\n", + __func__, emsg, self->swp_name); + return ERR_TRANSVR_UPDATE_FAIL; +} + + +int +qsfp_set_auto_tx_disable(struct transvr_obj_s *self, + int input_val) { + + int in_max = 0xf; /* 1111 */ + int in_min = 0x0; /* 0000 */ + int retval = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + /* Update settings*/ + if (input_val == VAL_TRANSVR_FUNCTION_DISABLE) { + emsg = "User disable auto tx_disable"; + self->auto_tx_disable = VAL_TRANSVR_FUNCTION_DISABLE; + goto out_qsfp_set_auto_tx_disable; + } + if ((input_val > in_max) || (input_val < in_min) ){ + SWPS_INFO("%s: Input value:%d incorrect! :%s\n", + __func__, input_val, self->swp_name); + return ERR_TRANSVR_BADINPUT; + } + self->auto_tx_disable = input_val; + /* Check current soft tx_disable */ + retval = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_disable, + "qsfp_set_auto_tx_disable"); + switch (retval) { + case 0: + break; + case ERR_TRANSVR_UNPLUGGED: + emsg = "Doesn't need to update"; + goto out_qsfp_set_auto_tx_disable; + default: + SWPS_INFO("%s: setup fail :%d :%s\n", + __func__, retval, self->swp_name); + return retval; + } + return _qsfp_set_auto_tx_disable(self, input_val); + +out_qsfp_set_auto_tx_disable: + SWPS_DEBUG("%s: %s :%s :%d\n :%d", + __func__, emsg, self->swp_name, input_val, retval); + return 0; +} + + +int +__qsfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + /* [Note] + * 0x + */ + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv[2] = {0x00, 0x00}; + + if ((input < 0) || (input > 0xFFFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_qsfp_set_tx_eq; + } + setv[0] = (uint8_t)((input & 0xFF00) >> 8); + setv[1] = (uint8_t)(input & 0xFF); + if ((self->tx_eq[0] == setv[0]) && + (self->tx_eq[1] == setv[1]) ) { + return 0; + } + err = _common_set_uint8_array(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + self->eeprom_map_p->length_tx_eq, + setv, + self->tx_eq, + "_qsfp_set_tx_eq", + show_e); + if (err < 0) { + emsg = "set_uint8_array fail"; + goto err_qsfp_set_tx_eq; + } + return 0; + +err_qsfp_set_tx_eq: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_qsfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + + int i = 0; + int retry = 3; + uint8_t tmp[2]; + + for (i=0; itx_eq[0]; + tmp[1] = self->tx_eq[1]; + if (_qsfp_update_attr_tx_eq(self, show_e) < 0){ + continue; + } + if ((self->tx_eq[0] == tmp[0]) && + (self->tx_eq[1] == tmp[1]) ){ + return 0; + } + } + return -1; +} + + +int +qsfp_set_tx_eq(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_qsfp_update_attr_tx_eq, + "qsfp_set_tx_eq"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _qsfp_set_tx_eq(self, input, 1); +} + + +int +__qsfp_set_rx_am(struct transvr_obj_s *self, + int input, + int show_e) { + /* [Note] + * 0x + */ + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv[2] = {0x00, 0x00}; + + if ((input < 0) || (input > 0xFFFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_qsfp_set_rx_am; + } + setv[0] = (uint8_t)((input & 0xFF00) >> 8); + setv[1] = (uint8_t)(input & 0xFF); + if ((self->rx_am[0] == setv[0]) && + (self->rx_am[1] == setv[1]) ) { + return 0; + } + err = _common_set_uint8_array(self, + self->eeprom_map_p->addr_rx_am, + self->eeprom_map_p->page_rx_am, + self->eeprom_map_p->offset_rx_am, + self->eeprom_map_p->length_rx_am, + setv, + self->rx_am, + "_qsfp_set_rx_am", + show_e); + if (err < 0) { + emsg = "set_uint8_array fail"; + goto err_qsfp_set_rx_am; + } + return 0; + +err_qsfp_set_rx_am: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_qsfp_set_rx_am(struct transvr_obj_s *self, + int input, + int show_e) { + + int i = 0; + int retry = 3; + uint8_t tmp[2]; + + for (i=0; irx_am[0]; + tmp[1] = self->rx_am[1]; + if (_qsfp_update_attr_rx_am(self, show_e) < 0){ + continue; + } + if ((self->rx_am[0] == tmp[0]) && + (self->rx_am[1] == tmp[1]) ){ + return 0; + } + } + return -1; +} + + +int +qsfp_set_rx_am(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_qsfp_update_attr_rx_am, + "qsfp_set_rx_am"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _qsfp_set_rx_am(self, input, 1); +} + + +int +__qsfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + /* [Note] + * 0x + */ + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv[2] = {0x00, 0x00}; + + if ((input < 0) || (input > 0xFFFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_qsfp_set_rx_em; + } + setv[0] = (uint8_t)((input & 0xFF00) >> 8); + setv[1] = (uint8_t)(input & 0xFF); + if ((self->rx_em[0] == setv[0]) && + (self->rx_em[1] == setv[1]) ) { + return 0; + } + err = _common_set_uint8_array(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + self->eeprom_map_p->length_rx_em, + setv, + self->rx_em, + "_qsfp_set_rx_em", + show_e); + if (err < 0) { + emsg = "set_uint8_array fail"; + goto err_qsfp_set_rx_em; + } + return 0; + +err_qsfp_set_rx_em: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_qsfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + + int i = 0; + int retry = 3; + uint8_t tmp[2]; + + for (i=0; irx_em[0]; + tmp[1] = self->rx_em[1]; + if (_qsfp_update_attr_rx_em(self, show_e) < 0){ + continue; + } + if ((self->rx_em[0] == tmp[0]) && + (self->rx_em[1] == tmp[1]) ){ + return 0; + } + } + return -1; +} + + +int +qsfp_set_rx_em(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_qsfp_update_attr_rx_em, + "qsfp_set_rx_em"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _qsfp_set_rx_em(self, input, 1); +} + + +int +common_transvr_dump(struct transvr_obj_s* self){ + + char *type_name = "Undefined"; + + if (TRANSVR_INFO_DUMP_ENABLE != 1) { + return 0; + } + switch (self->type) { + case TRANSVR_TYPE_SFP: + type_name = STR_TRANSVR_SFP; + break; + case TRANSVR_TYPE_QSFP: + type_name = STR_TRANSVR_QSFP; + break; + case TRANSVR_TYPE_QSFP_PLUS: + type_name = STR_TRANSVR_QSFP_PLUS; + break; + case TRANSVR_TYPE_QSFP_28: + type_name = STR_TRANSVR_QSFP28; + break; + case TRANSVR_TYPE_FAKE: + type_name = "FAKE"; + goto ok_common_transvr_dump; + case TRANSVR_TYPE_UNPLUGGED: + type_name = "UNPLUGGED"; + goto err_common_transvr_dump; + case TRANSVR_TYPE_INCONSISTENT: + type_name = "INCONSISTENT"; + goto err_common_transvr_dump; + case TRANSVR_TYPE_ERROR: + type_name = "ERROR"; + goto err_common_transvr_dump; + + default: + type_name = "UNEXPECTED"; + goto err_common_transvr_dump; + } + printk(KERN_INFO "[SWPS] Dump %s information:\n", self->swp_name); + printk(KERN_INFO " |- :%s\n", type_name); + printk(KERN_INFO " |- :%s\n", self->vendor_name); + printk(KERN_INFO " |- :%s\n", self->vendor_pn); + printk(KERN_INFO " |- :%s\n", self->vendor_rev); + printk(KERN_INFO " |- :%s\n", self->vendor_sn); + printk(KERN_INFO " |- :0x%02x\n", self->br); + printk(KERN_INFO " |- :0x%02x\n", self->comp_rev); + printk(KERN_INFO " |- :%d\n", self->len_om1); + printk(KERN_INFO " |- :%d\n", self->len_om2); + printk(KERN_INFO " |- :%d\n", self->len_om3); + printk(KERN_INFO " |- :%d\n", self->len_om4); + return 0; + +ok_common_transvr_dump: + SWPS_INFO("%s: %s is %s\n", __func__, self->swp_name, type_name); + return 0; + +err_common_transvr_dump: + SWPS_INFO("%s: %s is %s\n", __func__, self->swp_name, type_name); + return -1; +} + + +int +sfp_transvr_dump(struct transvr_obj_s* self) { + + if (TRANSVR_INFO_DUMP_ENABLE != 1) { + return 0; + } + if (common_transvr_dump(self) < 0) { + return -1; + } + printk(KERN_INFO " |- :%d\n", self->len_sm); + printk(KERN_INFO " |- :%d\n", self->len_smf); + printk(KERN_INFO " '- :0x%02x\n", self->rate_id); + return 0; +} + + +int +qsfp_transvr_dump(struct transvr_obj_s* self) { + + if (TRANSVR_INFO_DUMP_ENABLE != 1) { + return 0; + } + if (common_transvr_dump(self) < 0) { + return -1; + } + printk(KERN_INFO " |- :%d\n", self->len_smf); + printk(KERN_INFO " '- :Class_%d\n", __qsfp_get_power_cls(self, 0)); + return 0; +} + + +int +fake_transvr_dump(struct transvr_obj_s* self) { + + printk(KERN_INFO "[SWPS] Dump transceiver information: %s\n", self->swp_name); + printk(KERN_INFO " |- :FAKE\n"); + printk(KERN_INFO " |- :FAKE_VENDER_NAME\n"); + printk(KERN_INFO " |- :FAKE_VENDER_PN\n"); + printk(KERN_INFO " |- :FAKE_VENDER_REV\n"); + printk(KERN_INFO " |- :FAKE_VENDER_SN\n"); + printk(KERN_INFO " |- :0x99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " '- :0x99\n"); + return 0; +} + + +/* ========== Object functions for fake type ========== + */ +int +fake_transvr_update(struct transvr_obj_s *self, + int show_err){ + self->state = STATE_TRANSVR_CONNECTED; + return 0; +} + + +int +fake_get_binary(struct transvr_obj_s *self){ + return 1; +} + +int +fake_get_int(struct transvr_obj_s *self){ + return 99; +} + + +int +fake_get_hex(struct transvr_obj_s *self){ + return 0x0f; +} + + +int +fake_get_str(struct transvr_obj_s *self, char *buf) { + return snprintf(buf, 16, "fake_get_str\n"); +} + + +int +fake_set_int(struct transvr_obj_s *self, int input){ + SWPS_INFO("%s: %d\n", __func__, input); + return 0; +} + + +int +fake_set_hex(struct transvr_obj_s *self, int input){ + SWPS_INFO("%s: 0x%02x\n", __func__, input); + return 0; +} + + +/* ========== Object functions for unsupported ========== + */ +int +unsupported_get_func(struct transvr_obj_s *self){ + return ERR_TRANSVR_NOTSUPPORT; +} + + +int +unsupported_get_func2(struct transvr_obj_s *self, + char *buf_p) { + int len = snprintf(buf_p, 8, "%d\n", ERR_TRANSVR_NOTSUPPORT); + return len; +} + + +int +unsupported_set_func(struct transvr_obj_s *self, + int input_val){ + return ERR_TRANSVR_NOTSUPPORT; +} + + + +/* ========== Object functions for long term task ========== + * + * [Note] + * SWPS transceiver worker is likely the green-thread (coroutine). + * Due to resource and performance considerations. SWPS run all + * features in one kthread at the same time, and handle by it self. + */ + +/* For Transceiver Task Handling + */ +static struct transvr_worker_s * +transvr_task_get(struct transvr_obj_s *self, + char *func_name) { + + struct transvr_worker_s *curr_p = self->worker_p; + + while(curr_p != NULL){ + if (strcmp((curr_p->func_name), func_name) == 0 ) { + return curr_p; + } + curr_p = curr_p->next_p; + } + return NULL; +} + + +static struct transvr_worker_s* +transvr_task_creat(struct transvr_obj_s *self, + int (*main_task)(struct transvr_worker_s *task), + int (*post_task)(struct transvr_worker_s *task), + char *caller) { + + struct transvr_worker_s *task_p = NULL; + struct transvr_worker_s *curr_p = NULL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Check task not exist */ + task_p = transvr_task_get(self, caller); + if (task_p) { + snprintf(err_msg, sizeof(err_msg), "Task already created!"); + goto err_transvr_task_creat; + } + /* Create task worker */ + task_p = kzalloc(sizeof(struct transvr_worker_s), GFP_KERNEL); + if (!task_p){ + snprintf(err_msg, sizeof(err_msg), "kzalloc fail"); + goto err_transvr_task_creat; + } + /* Setup task data */ + task_p->transvr_p = self; + task_p->next_p = NULL; + task_p->trigger_time = 0; + task_p->retry = 1; + task_p->state = STATE_T_TASK_INIT; + task_p->main_task = main_task; + task_p->post_task = post_task; + task_p->p_data = NULL; + snprintf(task_p->func_name, sizeof(task_p->func_name), "%s", caller); + /* Setup Link List */ + if (self->worker_p) { + curr_p = self->worker_p; + while(curr_p->next_p != NULL) { + curr_p = curr_p->next_p; + } + curr_p->next_p = task_p; + task_p->pre_p = curr_p; + } else { + self->worker_p = task_p; + task_p->pre_p = NULL; + } + return task_p; + +err_transvr_task_creat: + SWPS_ERR("%s: %s :%s :%s\n", + __func__, err_msg, caller, self->swp_name); + return NULL; +} + + +static void +transvr_task_free_one(struct transvr_worker_s *task_p){ + + struct transvr_worker_s *pre_p = NULL; + struct transvr_worker_s *next_p = NULL; + + if (task_p) { + pre_p = task_p->pre_p; + next_p = task_p->next_p; + + if ((pre_p) && (next_p)) { + pre_p->next_p = next_p; + next_p->pre_p = pre_p; + + } else if ((!pre_p) && (next_p)) { + next_p->pre_p = NULL; + + } else if ((pre_p) && (!next_p)) { + pre_p->next_p = NULL; + + } else if ((!pre_p) && (!next_p)) { + task_p->transvr_p->worker_p = NULL; + } else { + SWPS_ERR("%s: Unexcept case!\n :%s", + __func__, task_p->transvr_p->swp_name); + } + kfree(task_p->p_data); + kfree(task_p); + } +} + + +static void +transvr_task_free_all(struct transvr_obj_s *self) { + + struct transvr_worker_s *curr_p = NULL; + struct transvr_worker_s *next_p = NULL; + + if (self->worker_p) { + curr_p = self->worker_p; + while(curr_p) { + next_p = curr_p->next_p; + transvr_task_free_one(curr_p); + curr_p = next_p; + } + self->worker_p = NULL; + } +} + + +static void +transvr_cache_free_all(struct transvr_obj_s *self) { + + memset(self->vendor_name, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + memset(self->vendor_rev, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + memset(self->vendor_pn, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + memset(self->vendor_sn, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + self->extphy_offset = 0; +} + +static int +_transvr_task_run_main(struct transvr_worker_s *task_p) { + + int retval = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + if (!task_p){ + snprintf(err_msg, sizeof(err_msg), "main_task is NULL!"); + goto main_transvr_task_err; + } + if ((task_p->trigger_time) == 0){ + goto main_transvr_task_run; + } + if (time_before(jiffies, task_p->trigger_time)){ + goto main_transvr_task_wait; + } + goto main_transvr_task_run; + +main_transvr_task_run: + if (task_p->retry != VAL_TRANSVR_TASK_RETRY_FOREVER) { + task_p->retry -= 1; + } + retval = task_p->main_task(task_p); + if (retval < 0) { + if (task_p->retry > 0) { + task_p->state = STATE_T_TASK_WAIT; + return EVENT_TRANSVR_TASK_WAIT; + } + snprintf(err_msg, sizeof(err_msg), "Run main_task fail!"); + goto main_transvr_task_err; + } + goto main_transvr_task_identify; + +main_transvr_task_identify: + switch (retval) { + case EVENT_TRANSVR_TASK_WAIT: + task_p->state = STATE_T_TASK_WAIT; + return EVENT_TRANSVR_TASK_WAIT; + + case EVENT_TRANSVR_TASK_DONE: + task_p->state = STATE_T_TASK_DONE; + return EVENT_TRANSVR_TASK_DONE; + + default: + break; + } + snprintf(err_msg, sizeof(err_msg), "Run main_task fail!"); + goto main_transvr_task_err; + +main_transvr_task_wait: + task_p->state = STATE_T_TASK_WAIT; + return EVENT_TRANSVR_TASK_WAIT; + +main_transvr_task_err: + task_p->state = STATE_T_TASK_FAIL; + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, retval, task_p->transvr_p->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +static int +_transvr_task_run_post(struct transvr_worker_s *task_p) { + + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + if ((task_p->post_task) == NULL) { + return EVENT_TRANSVR_TASK_DONE; + } + switch (task_p->state) { + case STATE_T_TASK_WAIT: + case STATE_T_TASK_INIT: + goto post_transvr_task_wait; + + case STATE_T_TASK_DONE: + case STATE_T_TASK_FAIL: + goto post_transvr_task_run; + + default: + break; + } + snprintf(err_msg, sizeof(err_msg), "Unexcept task state"); + goto post_transvr_task_err; + +post_transvr_task_run: + task_p->post_task(task_p); + return EVENT_TRANSVR_TASK_DONE; + +post_transvr_task_wait: + return EVENT_TRANSVR_TASK_WAIT; + +post_transvr_task_err: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, task_p->state, task_p->transvr_p->swp_name); + return EVENT_TRANSVR_TASK_FAIL; +} + + +static int +transvr_task_run_one(struct transvr_worker_s *task_p) { + + int retval_main = DEBUG_TRANSVR_INT_VAL; + int retval_post = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + retval_main = _transvr_task_run_main(task_p); + if (retval_main < 0) { + snprintf(err_msg, sizeof(err_msg), "Execute main_task fail!"); + goto err_transvr_task_run_one; + } + retval_post = _transvr_task_run_post(task_p); + if (retval_post < 0) { + snprintf(err_msg, sizeof(err_msg), "Execute post_task fail!"); + goto err_transvr_task_run_one; + } + return retval_main; + +err_transvr_task_run_one: + SWPS_INFO("%s: %s
:%d :%d :%s :%s\n", + __func__, err_msg, retval_main, retval_post, + task_p->func_name, task_p->transvr_p->swp_name); + return EVENT_TRANSVR_TASK_FAIL; +} + + +static int +transvr_task_run_all(struct transvr_obj_s *self) { + + int haserr = 0; + int retval = DEBUG_TRANSVR_INT_VAL; + struct transvr_worker_s *curr_p = NULL; + struct transvr_worker_s *next_p = NULL; + + if ((self->worker_p) == NULL) { + return EVENT_TRANSVR_TASK_DONE; + } + curr_p = self->worker_p; + while (curr_p != NULL) { + next_p = curr_p->next_p; + retval = transvr_task_run_one(curr_p); + if (curr_p->retry == VAL_TRANSVR_TASK_RETRY_FOREVER) { + curr_p = next_p; + continue; + } + switch (retval) { + case EVENT_TRANSVR_TASK_WAIT: + break; + case EVENT_TRANSVR_TASK_DONE: + transvr_task_free_one(curr_p); + break; + case EVENT_TRANSVR_TASK_FAIL: + + default: + haserr = 1; + transvr_task_free_one(curr_p); + break; + } + curr_p = next_p; + } + if (haserr) { + return EVENT_TRANSVR_TASK_FAIL; + } + return EVENT_TRANSVR_TASK_DONE; +} + + +static void +transvr_task_set_delay(struct transvr_worker_s *task_p, + unsigned long delay_msec) { + + task_p->trigger_time = (jiffies + (delay_msec * (HZ/1000))); +} + + +static void +transvr_task_set_retry(struct transvr_worker_s *task_p, + unsigned long retry_times) { + + task_p->retry = retry_times; +} + + +/* For Transceiver Post Task + */ +int +taskfunc_post_do_nothing(struct transvr_worker_s *task_p) { + + return EVENT_TRANSVR_TASK_DONE; +} + + +int +taskfunc_post_handle_task_state(struct transvr_worker_s *task_p) { + + struct transvr_obj_s* tp = task_p->transvr_p; + + switch (task_p->state) { + case STATE_T_TASK_INIT: + case STATE_T_TASK_WAIT: + return EVENT_TRANSVR_TASK_WAIT; + + case STATE_T_TASK_DONE: + tp->state = STATE_TRANSVR_CONNECTED; + tp->send_uevent(tp, KOBJ_ADD); + return EVENT_TRANSVR_TASK_DONE; + + case STATE_T_TASK_FAIL: + tp->state = STATE_TRANSVR_UNEXCEPTED; + return EVENT_TRANSVR_TASK_FAIL; + + default: + break; + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +/* For Transceiver Main Task + */ +int +_taskfunc_sfp_setup_soft_rs(struct transvr_worker_s *task_p, + int input_val, + int address, + int page, + int offset, + int bit_shift, + uint8_t *attr_p, + char *caller) { + + int show_err = 0; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "_taskfunc_sfp_setup_soft_rs"; + + err_code = _sfp_update_attr_soft_rs0(task_p->transvr_p, 0); + if (err_code < 0) { + err_str = "Get current soft_rs0 fail!"; + goto err_taskfunc_sfp_setup_soft_rs_1; + } + err_code = __sfp_set_soft_rs(task_p->transvr_p, + input_val, + address, + page, + offset, + bit_shift, + attr_p, + caller, + show_err); + if (err_code < 0) { + err_str = "Get current soft_rs0 fail!"; + goto err_taskfunc_sfp_setup_soft_rs_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_sfp_setup_soft_rs_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + func_str, err_str, task_p->transvr_p->swp_name, input_val, err_code); + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +__taskfunc_sfp_setup_hard_rs(struct transvr_worker_s *task_p, + int input_val, + int (*get_func)(struct ioexp_obj_s *self, int virt_offset), + int (*set_func)(struct ioexp_obj_s *self, int virt_offset, int input_val)) { + + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_str = DEBUG_TRANSVR_STR_VAL; + + err_val = get_func(task_p->transvr_p->ioexp_obj_p, + task_p->transvr_p->ioexp_virt_offset); + + if (err_val < 0) { + if (err_val == ERR_IOEXP_NOTSUPPORT) { + return EVENT_TRANSVR_TASK_DONE; + } + err_str = "Get current hard_rs fail!"; + goto err_p_taskfunc_sfp_setup_hard_rs_1; + } + if (err_val == input_val) { + return EVENT_TRANSVR_TASK_DONE; + } + err_val = set_func(task_p->transvr_p->ioexp_obj_p, + task_p->transvr_p->ioexp_virt_offset, + input_val); + if (err_val < 0) { + err_str = "Setup hard_rs fail!"; + goto err_p_taskfunc_sfp_setup_hard_rs_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_p_taskfunc_sfp_setup_hard_rs_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + __func__, err_str, task_p->transvr_p->swp_name, input_val, err_val); + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_taskfunc_sfp_setup_hard_rs0(struct transvr_worker_s *task_p, + int input_val) { + + return __taskfunc_sfp_setup_hard_rs(task_p, + input_val, + task_p->transvr_p->ioexp_obj_p->get_hard_rs0, + task_p->transvr_p->ioexp_obj_p->set_hard_rs0); +} + + +int +_taskfunc_sfp_setup_hard_rs1(struct transvr_worker_s *task_p, + int input_val) { + + return __taskfunc_sfp_setup_hard_rs(task_p, + input_val, + task_p->transvr_p->ioexp_obj_p->get_hard_rs1, + task_p->transvr_p->ioexp_obj_p->set_hard_rs1); +} + + +int +_taskfunc_sfp_setup_rs0(struct transvr_worker_s *task_p, + int input_val) { + + int bit_shift = 3; + int old_val = DEBUG_TRANSVR_INT_VAL; + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "_taskfunc_sfp_setup_rs0"; + + err_val = _taskfunc_sfp_setup_hard_rs0(task_p, + input_val); + if (err_val < 0) { + err_str = "Setup hard_rs0 fail!"; + goto err_private_taskfunc_sfp_setup_rs0_1; + } + old_val = err_val; + err_val = _taskfunc_sfp_setup_soft_rs(task_p, + input_val, + task_p->transvr_p->eeprom_map_p->addr_soft_rs0, + task_p->transvr_p->eeprom_map_p->page_soft_rs0, + task_p->transvr_p->eeprom_map_p->offset_soft_rs0, + bit_shift, + &(task_p->transvr_p->soft_rs0), + func_str); + if (err_val < 0) { + err_str = "Setup soft_rs0 fail!"; + goto err_private_taskfunc_sfp_setup_rs0_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_private_taskfunc_sfp_setup_rs0_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + func_str, err_str, task_p->transvr_p->swp_name, input_val, err_val); + } + _taskfunc_sfp_setup_hard_rs0(task_p, old_val); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_taskfunc_sfp_setup_rs1(struct transvr_worker_s *task_p, + int input_val) { + + int bit_shift = 3; + int old_val = DEBUG_TRANSVR_INT_VAL; + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "_taskfunc_sfp_setup_rs1"; + + err_val = _taskfunc_sfp_setup_hard_rs1(task_p, + input_val); + if (err_val < 0) { + err_str = "Setup hard_rs1 fail!"; + goto err_private_taskfunc_sfp_setup_rs1_1; + } + old_val = err_val; + err_val = _taskfunc_sfp_setup_soft_rs(task_p, + input_val, + task_p->transvr_p->eeprom_map_p->addr_soft_rs1, + task_p->transvr_p->eeprom_map_p->page_soft_rs1, + task_p->transvr_p->eeprom_map_p->offset_soft_rs1, + bit_shift, + &(task_p->transvr_p->soft_rs1), + func_str); + if (err_val < 0) { + err_str = "Setup soft_rs1 fail!"; + goto err_private_taskfunc_sfp_setup_rs1_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_private_taskfunc_sfp_setup_rs1_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + func_str, err_str, task_p->transvr_p->swp_name, input_val, err_val); + } + _taskfunc_sfp_setup_hard_rs1(task_p, old_val); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +taskfunc_sfp_setup_SFF8431_case1(struct transvr_worker_s *task_p) { + /* SFF-8431 (8/4/2G Rx Rate_Select only) */ + int update_val = 1; + + return _taskfunc_sfp_setup_rs0(task_p, update_val); +} + + + +int +taskfunc_sfp_setup_SFF8431_case2(struct transvr_worker_s *task_p) { + /* SFF-8431 (8/4/2G Tx Rate_Select only) */ + int update_val = 1; + + return _taskfunc_sfp_setup_rs1(task_p, update_val); +} + + +int +taskfunc_sfp_setup_SFF8431_case3(struct transvr_worker_s *task_p) { + /* SFF-8431 (8/4/2G Independent Rx & Tx Rate_select) */ + int update_rs0 = 1; + int update_rs1 = 1; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _taskfunc_sfp_setup_rs0(task_p, update_rs0); + if (err_code < 0) { + return err_code; + } + return _taskfunc_sfp_setup_rs1(task_p, update_rs1); +} + + +int +taskfunc_sfp_handle_1g_rj45(struct transvr_worker_s *task_p) { + + /* Not all of platform support 0x56 for transceiver + * external PHY, Support list as below: + * => 1. Magnolia-PVT (PS: EVT & DVT not ready) + */ + int ext_phy_addr = 0x56; + int ext_phy_page = -1; + int ext_phy_offs = 0x11; + int ext_phy_len = 1; + int lstate_mask = 0x04; /* 00000100 */ + int show_err = 0; + int fail_retry = 5; + int fail_delay = 1000; /* msec */ + int err_code = DEBUG_TRANSVR_INT_VAL; + uint8_t detect_val = DEBUG_TRANSVR_HEX_VAL; + char err_str[64] = DEBUG_TRANSVR_STR_VAL; + int *tmp_p = NULL; + char *func_name = "taskfunc_sfp_handle_1g_rj45"; + + if (task_p->transvr_p->state != STATE_TRANSVR_CONNECTED) { + return EVENT_TRANSVR_TASK_DONE; + } + if ( (task_p->transvr_p->info != TRANSVR_CLASS_BASE_T_1000) && + (task_p->transvr_p->info != TRANSVR_CLASS_BASE_T_1000_up) ) { + goto err_taskfunc_sfp_handle_1g_rj45_1; + } + err_code = _common_update_uint8_attr(task_p->transvr_p, + ext_phy_addr, + ext_phy_page, + ext_phy_offs, + ext_phy_len, + &detect_val, + func_name, + show_err); + if ( (err_code < 0) || + (detect_val == DEBUG_TRANSVR_HEX_VAL) ) { + snprintf(err_str, sizeof(err_str), "Detect external link status fail"); + goto err_taskfunc_sfp_handle_1g_rj45_2; + } + if ((detect_val & lstate_mask) == lstate_mask) { + goto ok_taskfunc_sfp_handle_1g_rj45_link_up; + } + goto ok_taskfunc_sfp_handle_1g_rj45_link_down; + +ok_taskfunc_sfp_handle_1g_rj45_link_up: + /* Filter out noise */ + if (!(task_p->p_data)) { + tmp_p = kzalloc(sizeof(int), GFP_KERNEL); + if (!tmp_p) { + snprintf(err_str, sizeof(err_str), "kzalloc p_data fail"); + goto err_taskfunc_sfp_handle_1g_rj45_2; + } + *tmp_p = TRANSVR_CLASS_BASE_T_1000_up; + task_p->p_data = tmp_p; + goto ok_taskfunc_sfp_handle_1g_rj45_done; + } + if ((*(int *)(task_p->p_data)) != TRANSVR_CLASS_BASE_T_1000_up) { + kfree(task_p->p_data); + task_p->p_data = NULL; + snprintf(err_str, sizeof(err_str), "Internal error"); + goto err_taskfunc_sfp_handle_1g_rj45_2; + } + task_p->transvr_p->info = TRANSVR_CLASS_BASE_T_1000_up; + kfree(task_p->p_data); + task_p->p_data = NULL; + goto ok_taskfunc_sfp_handle_1g_rj45_done; + +ok_taskfunc_sfp_handle_1g_rj45_link_down: + if (task_p->p_data) { + kfree(task_p->p_data); + task_p->p_data = NULL; + } + task_p->transvr_p->info = TRANSVR_CLASS_BASE_T_1000; + goto ok_taskfunc_sfp_handle_1g_rj45_done; + +ok_taskfunc_sfp_handle_1g_rj45_done: + if (task_p->retry != VAL_TRANSVR_TASK_RETRY_FOREVER) { + transvr_task_set_retry(task_p, VAL_TRANSVR_TASK_RETRY_FOREVER); + } + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_sfp_handle_1g_rj45_1: + snprintf(err_str, sizeof(err_str), "Detect transceiver:%d not Base-T, remove task.", + task_p->transvr_p->info); + SWPS_INFO("%s: %s :%s\n", __func__, err_str, task_p->transvr_p->swp_name); + transvr_task_set_retry(task_p, 0); + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_sfp_handle_1g_rj45_2: + if (task_p->retry == VAL_TRANSVR_TASK_RETRY_FOREVER) { + transvr_task_set_retry(task_p, fail_retry); + } + if ((task_p->retry) == 0) { + /* Error case: + * => In this case, SWPS will stop external Link state monitor features + * and keeps transvr_p->info on TRANSVR_CLASS_BASE_T_1000_up. + * Upper layer will see it always Linkup that because of these type of + * transceiver has external phy, switch chip see it as Loopback transceiver. + */ + SWPS_WARN("%s can not access external PHY of Base-T SFP transceiver\n", + task_p->transvr_p->swp_name); + task_p->transvr_p->info = TRANSVR_CLASS_BASE_T_1000_up; + return EVENT_TRANSVR_TASK_DONE; + } else { + transvr_task_set_delay(task_p, fail_delay); + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_taskfunc_qsfp_setup_power_mod(struct transvr_obj_s *self, + int setup_val) { + + int curr_val = DEBUG_TRANSVR_INT_VAL; + int err_val = DEBUG_TRANSVR_INT_VAL; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + if (io_no_init) { + + SWPS_INFO("%s no_io_init\n",__func__); + return EVENT_TRANSVR_TASK_DONE; + } + + curr_val = self->ioexp_obj_p->get_lpmod(self->ioexp_obj_p, + self->ioexp_virt_offset); + if (curr_val < 0){ + err_msg = "Get current value fail!"; + goto err_private_taskfunc_qsfp_setup_power_mod_1; + } + if (curr_val == setup_val){ + return EVENT_TRANSVR_TASK_DONE; + } + err_val = self->ioexp_obj_p->set_lpmod(self->ioexp_obj_p, + self->ioexp_virt_offset, + setup_val); + if (err_val < 0){ + err_msg = "Setup power mode fail!"; + goto err_private_taskfunc_qsfp_setup_power_mod_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_private_taskfunc_qsfp_setup_power_mod_1: + SWPS_INFO("%s: %s :%d :%d :%d\n", + __func__, err_msg, err_val, curr_val, setup_val); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +taskfunc_qsfp_handle_tx_disable(struct transvr_worker_s *task_p) { + + int i = 0; + int retry = 5; + int delay_ms = 100; + + if (task_p->transvr_p->auto_tx_disable == VAL_TRANSVR_FUNCTION_DISABLE) { + return EVENT_TRANSVR_TASK_DONE; + } + if (!_qsfp_is_implement_tx_disable(task_p->transvr_p)) { + return EVENT_TRANSVR_TASK_DONE; + } + for (i=0; itransvr_p, + task_p->transvr_p->auto_tx_disable) + == EVENT_TRANSVR_TASK_DONE) { + goto ok_taskfunc_qsfp_handle_tx_disable; + } + mdelay(delay_ms); + } + SWPS_INFO("%s auto setup tx_disable:0x%02x fail.\n", + task_p->transvr_p->swp_name, + task_p->transvr_p->auto_tx_disable); + return EVENT_TRANSVR_INIT_FAIL; + +ok_taskfunc_qsfp_handle_tx_disable: + SWPS_INFO("%s auto setup tx_disable:0x%02x ok.\n", + task_p->transvr_p->swp_name, + task_p->transvr_p->auto_tx_disable); + return EVENT_TRANSVR_TASK_DONE; +} + + +int +taskfunc_qsfp_set_hpmod(struct transvr_worker_s *task_p) { + + int err = DEBUG_TRANSVR_INT_VAL; + int HIGH_POWER_MODE = 0; + + /* Handle power mode */ + err = _taskfunc_qsfp_setup_power_mod(task_p->transvr_p, + HIGH_POWER_MODE); + if (err < 0) { + SWPS_INFO("%s: setup hpmod fail :%d :%s\n", + __func__, err, task_p->transvr_p->swp_name); + return err; + } + /* Handle auto tx_disable + * [Note] + * => Because there are some transceiver have timing issues or + * setup sequence issues, therefore we handle auto tx_disable + * after handle power mode. + */ + mdelay(100); + return taskfunc_qsfp_handle_tx_disable(task_p); +} + + +int +taskfunc_qsfp_set_lpmod(struct transvr_worker_s *task_p) { + + int LOW_POWER_MODE = 1; + return _taskfunc_qsfp_setup_power_mod(task_p->transvr_p, + LOW_POWER_MODE); +} + + +static int +initfunc_sfp_handle_multi_rate_mode(struct transvr_obj_s *self) { + + int task_retry = 3; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "sfp_handle_multi_rate_mode"; + struct transvr_worker_s *task_p = NULL; + + switch (self->rate_id) { + case 0x00: /* Unspecified */ + case 0x03: /* Unspecified */ + case 0x05: /* Unspecified */ + case 0x07: /* Unspecified */ + case 0x09: /* Unspecified */ + case 0x0B: /* Unspecified */ + case 0x0D: /* Unspecified */ + case 0x0F: /* Unspecified */ + goto sfp_handle_multi_rate_mode_4_unspecified; + + case 0x02: /* SFF-8431 (8/4/2G Rx Rate_Select only) */ + task_p = transvr_task_creat(self, + taskfunc_sfp_setup_SFF8431_case1, + taskfunc_post_handle_task_state, + func_str); + goto sfp_handle_multi_rate_mode_4_sff8431; + + case 0x04: /* SFF-8431 (8/4/2G Tx Rate_Select only) */ + task_p = transvr_task_creat(self, + taskfunc_sfp_setup_SFF8431_case2, + taskfunc_post_handle_task_state, + func_str); + goto sfp_handle_multi_rate_mode_4_sff8431; + + case 0x06: /* SFF-8431 (8/4/2G Independent Rx & Tx Rate_select) */ + task_p = transvr_task_creat(self, + taskfunc_sfp_setup_SFF8431_case3, + taskfunc_post_handle_task_state, + func_str); + goto sfp_handle_multi_rate_mode_4_sff8431; + + case 0x01: /* SFF-8079 (4/2/1G Rate_Select & AS0/AS1) */ + err_str = "SFF-8079 (4/2/1G Rate_Select & AS0/AS1)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x08: /* FC-PI-5 (16/8/4G Rx Rate_select only) + * High=16G only, Low=8G/4G + */ + err_str = "FC-PI-5 (16/8/4G Rx Rate_select only)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x0A: /* FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select) + * High=16G only, Low=8G/4G + */ + err_str = "FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x0C: /* FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select) + * High=32G only, Low = 16G/8G + */ + err_str = "FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x0E: /* 10/8G Rx and Tx Rate_Select controlling the operation or + * locking modes of the internal signal conditioner, retimer + * or CDR, according to the logic table defined in Table 10-2, + * High Bit Rate (10G) =9.95-11.3 Gb/s; Low Bit Rate (8G) = + * 8.5 Gb/s. In this mode, the default value of bit 110.3 (Soft + * Rate Select RS(0), Table 9-11) and of bit 118.3 (Soft Rate + * Select RS(1), Table 10-1) is 1. + */ + err_str = "cable type: 0x0E"; + goto sfp_handle_multi_rate_mode_4_not_support; + + default: + err_str = "cable type: UNKNOW"; + goto sfp_handle_multi_rate_mode_4_not_support; + } + +sfp_handle_multi_rate_mode_4_sff8431: + if (!task_p) { + err_str = "Create task fail!"; + goto sfp_handle_multi_rate_mode_4_fail_1; + } + transvr_task_set_retry(task_p, task_retry); + return EVENT_TRANSVR_TASK_WAIT; + +sfp_handle_multi_rate_mode_4_unspecified: + return EVENT_TRANSVR_TASK_DONE; + +sfp_handle_multi_rate_mode_4_not_support: + SWPS_INFO("%s: Does not support %s :%s :0x%02x\n", + func_str, err_str, self->swp_name, self->rate_id); + return EVENT_TRANSVR_TASK_DONE; + +sfp_handle_multi_rate_mode_4_fail_1: + SWPS_INFO("%s: %s :%s :0x%02x, :%d\n", + func_str, err_str, self->swp_name, self->rate_id, err_code); + return EVENT_TRANSVR_INIT_FAIL; +} + + +static int +initfunc_sfp_handle_1g_rj45(struct transvr_obj_s *self) { + + struct transvr_worker_s *task_p = NULL; + int detect_cls = DEBUG_TRANSVR_INT_VAL; + char err_str[64] = DEBUG_TRANSVR_STR_VAL; + char *func_str = "initfunc_sfp_handle_1g_rj45"; + + + if (self->info == TRANSVR_CLASS_BASE_T_1000) { + task_p = transvr_task_creat(self, + taskfunc_sfp_handle_1g_rj45, + taskfunc_post_do_nothing, + func_str); + if (!task_p) { + snprintf(err_str, sizeof(err_str), "Create task fail"); + goto err_initfunc_sfp_handle_1g_rj45; + } + transvr_task_set_retry(task_p, VAL_TRANSVR_TASK_RETRY_FOREVER); + } + return EVENT_TRANSVR_TASK_DONE; + +err_initfunc_sfp_handle_1g_rj45: + SWPS_INFO("%s: %s :%s :%d\n", + __func__, err_str, self->swp_name, detect_cls); + return EVENT_TRANSVR_TASK_FAIL; +} + + +static int +initfunc_qsfp_handle_power_mode(struct transvr_obj_s *self) { + + int err_code = EVENT_TRANSVR_EXCEP_INIT; + int power_class = DEBUG_TRANSVR_INT_VAL; + int hpmod_retry = 3; + int lpower_config = 1; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + unsigned long hpmod_delay = 500; /* msec */ + struct transvr_worker_s *task_p = NULL; + + /* Handle power mode for IOEXP */ + power_class = __qsfp_get_power_cls(self, 0); + switch (power_class) { + case 1: /* Case: Low power mode (Class = 1) */ + err_code = _taskfunc_qsfp_setup_power_mod(self, lpower_config); + if (err_code < 0){ + snprintf(err_msg, sizeof(err_msg), "Setup lpmod fail :%d", err_code); + goto err_initfunc_qsfp_handle_power_mode; + } + return EVENT_TRANSVR_TASK_DONE; + + case 2: /* Case: High power mode (Class > 1) */ + case 3: + case 4: + case 5: + case 6: + case 7: + task_p = transvr_task_creat(self, + taskfunc_qsfp_set_hpmod, + taskfunc_post_handle_task_state, + "transvr_init_qsfp"); + if (!task_p) { + snprintf(err_msg, sizeof(err_msg), "Setup lpmod fail :%d", err_code); + goto err_initfunc_qsfp_handle_power_mode; + } + transvr_task_set_retry(task_p, hpmod_retry); + transvr_task_set_delay(task_p, hpmod_delay); + return EVENT_TRANSVR_TASK_WAIT; + + default: + break; + } + snprintf(err_msg, sizeof(err_msg), "Exception case"); + goto err_initfunc_qsfp_handle_power_mode; + +err_initfunc_qsfp_handle_power_mode: + SWPS_INFO("%s: %s :%s \n", __func__, err_msg, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +int +initfunc_qsfp28_handle_cdr(struct transvr_obj_s *self) { + + uint8_t DEFAULT_VAL_CDR = 0xff; + int CDR_FUNC_EXISTED = 0x3; + int show_err = 1; + int err_val = EVENT_TRANSVR_TASK_FAIL; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + char *func_str = "initfunc_qsfp28_handle_cdr"; + + err_val = __qsfp_get_cdr_present(self, 0); + if ( (err_val < 0) || + (err_val == DEBUG_TRANSVR_HEX_VAL) ) { + err_msg = "detect cdr_present fail!"; + goto err_taskfunc_qsfp_handle_cdr_1; + } + if (err_val == CDR_FUNC_EXISTED) { + err_val = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->offset_cdr, + DEFAULT_VAL_CDR, + &(self->cdr), + func_str, + show_err); + if (err_val < 0) { + err_msg = "set CDR fail!"; + goto err_taskfunc_qsfp_handle_cdr_1; + } + } + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_qsfp_handle_cdr_1: + SWPS_INFO("%s: %s :%d :%s\n", + func_str, err_msg, err_val, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + +/* ========== Object functions for Final State Machine ========== + */ +int +is_plugged(struct transvr_obj_s *self){ + + int limit = 63; + int present = DEBUG_TRANSVR_INT_VAL; + char emsg[64] = DEBUG_TRANSVR_STR_VAL; + struct ioexp_obj_s *ioexp_p = self->ioexp_obj_p; + + if (!ioexp_p) { + snprintf(emsg, limit, "ioexp_p is null!"); + goto err_is_plugged_1; + } + present = ioexp_p->get_present(ioexp_p, self->ioexp_virt_offset); + switch (present){ + case 0: + return 1; + case 1: + return 0; + case ERR_IOEXP_UNINIT: + snprintf(emsg, limit, "ioexp_p not ready!"); + goto err_is_plugged_1; + default: + if (ioexp_p->state == STATE_IOEXP_INIT){ + snprintf(emsg, limit, "ioexp_p not ready!"); + goto err_is_plugged_1; + } + break; + } + SWPS_INFO("%s: Exception case! :%d :%d\n", + __func__, present, ioexp_p->state); + return 0; + +err_is_plugged_1: + SWPS_DEBUG("%s: %s\n", __func__, emsg); + return 0; +} + + +static int +detect_transvr_type(struct transvr_obj_s* self){ + + int type = TRANSVR_TYPE_ERROR; + + self->i2c_client_p->addr = VAL_TRANSVR_COMID_ARREESS; + type = i2c_smbus_read_byte_data(self->i2c_client_p, + VAL_TRANSVR_COMID_OFFSET); + + /* Case: 1. Wait transceiver I2C module. + * 2. Transceiver I2C module failure. + * Note: 1. SFF allow maximum transceiver initial time is 2 second. So, there + * are exist some case that we need to wait transceiver. + * For these case, we keeps status on "TRANSVR_TYPE_UNPLUGGED", than + * state machine will keep trace with it. + * 2. There exist some I2C failure case we need to handle. Such as user + * insert the failure transceiver, or any reason cause it abnormal. + */ + if (type < 0){ + switch (type) { + case -EIO: + SWPS_DEBUG("%s: %s smbus return:-5 (I/O error)\n", + __func__, self->swp_name); + return TRANSVR_TYPE_UNPLUGGED; + case -ENXIO: + SWPS_DEBUG("%s: %s smbus return:-6 (No such device or address)\n", + __func__, self->swp_name); + return TRANSVR_TYPE_UNPLUGGED; + default: + break; + } + SWPS_INFO("%s: %s unexpected smbus return:%d \n", + __func__, self->swp_name, type); + return TRANSVR_TYPE_ERROR; + } + /* Identify valid transceiver type */ + switch (type){ + case TRANSVR_TYPE_SFP: + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + break; + case TRANSVR_TYPE_UNKNOW_1: + case TRANSVR_TYPE_UNKNOW_2: + type = TRANSVR_TYPE_UNKNOW_2; + break; + default: + SWPS_DEBUG("%s: unknow type:0x%02x \n", __func__, type); + type = TRANSVR_TYPE_ERROR; + break; + } + return type; +} + + +static int +detect_transvr_state(struct transvr_obj_s *self, + int result[2]){ + /* [return] [result-0] [result-1] + * 0 STATE_TRANSVR_CONNECTED TRANSVR_TYPE_FAKE + * 0 STATE_TRANSVR_DISCONNECTED TRANSVR_TYPE_UNPLUGGED + * 0 STATE_TRANSVR_ISOLATED TRANSVR_TYPE_ERROR + * 0 STATE_TRANSVR_INIT / + * 0 STATE_TRANSVR_SWAPPED + * 0 STATE_TRANSVR_CONNECTED + * ERR_TRNASVR_BE_ISOLATED STATE_TRANSVR_ISOLATED TRANSVR_TYPE_ERROR + * ERR_TRANSVR_I2C_CRASH STATE_TRANSVR_UNEXCEPTED TRANSVR_TYPE_ERROR + * ERR_TRANSVR_UNEXCPT STATE_TRANSVR_UNEXCEPTED TRANSVR_TYPE_UNKNOW_1/2 + */ + result[0] = STATE_TRANSVR_UNEXCEPTED; /* For return state */ + result[1] = TRANSVR_TYPE_ERROR; /* For return type */ + + /* Case1: Fake type */ + if (self->type == TRANSVR_TYPE_FAKE){ + result[0] = STATE_TRANSVR_CONNECTED; + result[1] = TRANSVR_TYPE_FAKE; + return 0; + } + /* Case2: Transceiver unplugged */ + if (!is_plugged(self)){ + result[0] = STATE_TRANSVR_DISCONNECTED; + result[1] = TRANSVR_TYPE_UNPLUGGED; + return 0; + } + /* Case3: Transceiver be isolated */ + if (self->state == STATE_TRANSVR_ISOLATED){ + result[0] = STATE_TRANSVR_ISOLATED; + result[1] = TRANSVR_TYPE_ERROR; + return ERR_TRNASVR_BE_ISOLATED; + } + /* Case4: Transceiver plugged */ + result[1] = detect_transvr_type(self); + /* Case4.1: I2C topology crash + * Note : There are some I2C issues cause by transceiver/cables. + * We need to check topology status when user insert it. + * But in this step, we can't not ensure this is the issues + * port. So, it return the ERR_TRANSVR_I2C_CRASH, then upper + * layer will diagnostic I2C topology. + */ + if (check_channel_tier_1() < 0) { + SWPS_INFO("%s: %s detect I2C crash :%d\n", + __func__, self->swp_name, self->state); + result[0] = STATE_TRANSVR_UNEXCEPTED; + result[1] = TRANSVR_TYPE_ERROR; + return ERR_TRANSVR_I2C_CRASH; + } + /* Case4.2: System initial not ready, + * Note : Sometime i2c channel or transceiver EEPROM will delay that will + * cause system in inconsistent state between EEPROM and IOEXP. + * In this case, SWP transceiver object keep state at LINK_DOWN + * to wait system ready. + * By the way, State Machine will handle these case. + */ + if (result[1] == TRANSVR_TYPE_UNPLUGGED){ + result[0] = STATE_TRANSVR_DISCONNECTED; + return 0; + } + /* Case4.3: Error transceiver type */ + if (result[1] == TRANSVR_TYPE_ERROR){ + result[0] = STATE_TRANSVR_ISOLATED; + SWPS_INFO("%s: %s detect error type\n", __func__, self->swp_name); + alarm_msg_2_user(self, "detected transceiver/cables not meet SFF standard!"); + return ERR_TRNASVR_BE_ISOLATED; + } + /* Case3.3: Unknow transceiver type */ + if ((result[1] == TRANSVR_TYPE_UNKNOW_1) || + (result[1] == TRANSVR_TYPE_UNKNOW_2) ){ + result[0] = STATE_TRANSVR_UNEXCEPTED; + return ERR_TRANSVR_UNEXCPT; + } + /* Case3.4: During initial process */ + if (self->state == STATE_TRANSVR_INIT){ + result[0] = STATE_TRANSVR_INIT; + return 0; + } + /* Case3.5: Transceiver be swapped */ + if (self->type != result[1]){ + result[0] = STATE_TRANSVR_SWAPPED; + return 0; + } + /* Case3.6: Link up state */ + result[0] = STATE_TRANSVR_CONNECTED; + return 0; +} + + +int +_sfp_detect_class_by_extend_comp(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int detect_val = _sfp_get_comp_extended(self); + + switch(detect_val) { + case 0x00: /* Unspecified */ + return TRANSVR_CLASS_UNSPECIFIED; + + case 0x01: /* 100G AOC (Active Optical Cable) or 25GAUI C2M */ + case 0x18: /* 100G AOC or 25GAUI C2M AOC. */ + return TRANSVR_CLASS_OPTICAL_25G_AOC; + + case 0x02: /* 100GBASE-SR4 or 25GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_25G_SR; + + case 0x03: /* 100GBASE-LR4 or 25GBASE-LR */ + return TRANSVR_CLASS_OPTICAL_25G_LR; + + case 0x04: /* 100GBASE-ER4 or 25GBASE-ER */ + return TRANSVR_CLASS_OPTICAL_25G_ER; + + case 0x08: /* 100G ACC (Active Copper Cable) or 25GAUI C2M ACC. */ + case 0x0b: /* 100GBASE-CR4 or 25GBASE-CR CA-L */ + case 0x0c: /* 25GBASE-CR CA-S */ + case 0x0d: /* 25GBASE-CR CA-N */ + case 0x19: /* 100G ACC or 25GAUI C2M ACC. */ + return TRANSVR_CLASS_COPPER_L1_25G; + + default: + break; + } + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_detect_class_by_10_ethernet(struct transvr_obj_s* self) { + /* Reference: SFF-8472 (v12.2) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + + detect_val = _sfp_get_comp_10g_eth_comp(self); + /* Case: Unspecified */ + if (detect_val == 0x00) { + return TRANSVR_CLASS_UNSPECIFIED; + } + /* Case: 10G Optical (x1) */ + if ((detect_val & 0x10) == 0x10) { /* 00010000 : 10GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_10G_S_SR; + } + if ( ((detect_val & 0x20) == 0x20) || /* 00100000 : 10GBASE-LR */ + ((detect_val & 0x40) == 0x40) ){ /* 01000000 : 10GBASE-LRM */ + return TRANSVR_CLASS_OPTICAL_10G_S_LR; + } + if ((detect_val & 0x80) == 0x80) { /* 10000000 : 10GBASE-ER */ + return TRANSVR_CLASS_OPTICAL_10G_S_ER; + } + /* Case: ERROR */ + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_detect_if_sp_by_br(struct transvr_obj_s* self) { + + int lower_bound_1g = 0x0b; + int upper_bound_1g = 0x1A; + int lower_bound_10g = 0x60; + int upper_bound_10g = 0x75; + int lower_bound_25g = 0xf0; + int upper_bound_25g = 0xff; + int notmal_br = DEBUG_TRANSVR_INT_VAL; + + notmal_br = (int)(self->br); /* updated by update_all() */ + /* Check 25G */ + if ((notmal_br >= lower_bound_25g) && + (notmal_br <= upper_bound_25g) ) { + return TRANSVR_CLASS_25G; + } + /* Check 10G */ + if ((notmal_br >= lower_bound_10g) && + (notmal_br <= upper_bound_10g) ) { + return TRANSVR_CLASS_10G; + } + /* Check 1G */ + if ((notmal_br >= lower_bound_1g) && + (notmal_br <= upper_bound_1g) ) { + return TRANSVR_CLASS_1G; + } + return TRANSVR_CLASS_UNSPECIFIED; +} + + +int +_sfp_detect_class_by_1g_ethernet(struct transvr_obj_s* self) { + /* Reference: SFF-8472 (v12.2) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + int speed_br = DEBUG_TRANSVR_INT_VAL; + int speed_tmp = DEBUG_TRANSVR_INT_VAL; + char err_str[64] = DEBUG_TRANSVR_STR_VAL; + + speed_br = _sfp_detect_if_sp_by_br(self); + detect_val = _sfp_get_comp_1g_eth_comp(self); + + if (detect_val < 0) { + snprintf(err_str, sizeof(err_str), "Detect abnormal value:%d", detect_val); + goto err_p_sfp_detect_class_by_1g_ethernet; + } + /* Case: Unspecified */ + if (detect_val == 0x00) { + return TRANSVR_CLASS_UNSPECIFIED; + } + /* Case: 1G (x1) */ + if ((detect_val & 0x01) == 0x01) { /* 00000001 : 1000BASE-SX */ + speed_tmp = TRANSVR_CLASS_OPTICAL_1G_SX; + goto ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g; + } + if ((detect_val & 0x02) == 0x02) { /* 00000010 : 1000BASE-LX *3 */ + speed_tmp = TRANSVR_CLASS_OPTICAL_1G_LX; + goto ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g; + } + if ((detect_val & 0x04) == 0x04) { /* 00000100 : 1000BASE-CX */ + speed_tmp = TRANSVR_CLASS_COPPER_L1_1G; + goto ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g; + } + /* Case: 1000 Base-T (x1) */ + if ((detect_val & 0x08) == 0x08) { /* 00001000 : 1000BASE-T */ + return TRANSVR_CLASS_BASE_T_1000; + } + /* Case: 100 Base */ + if ( ((detect_val & 0x10) == 0x10) || /* 00010000 : 100BASE-LX/LX10 */ + ((detect_val & 0x20) == 0x20) || /* 00100000 : 100BASE-FX */ + ((detect_val & 0x40) == 0x40) || /* 01000000 : BASE-BX10 *3 */ + ((detect_val & 0x80) == 0x80) ){ /* 10000000 : BASE-PX *3 */ + return TRANSVR_CLASS_OPTICAL_100; + } + /* Case: ERROR */ + snprintf(err_str, sizeof(err_str), "Case:ERROR, value:%d", detect_val); + goto err_p_sfp_detect_class_by_1g_ethernet; + +ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g: + switch (speed_br) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_1G: + return speed_tmp; + case TRANSVR_CLASS_10G: + goto ok_sfp_detect_class_by_1g_ethernet_4_transfer_10G; + } + +ok_sfp_detect_class_by_1g_ethernet_4_transfer_10G: + switch (speed_tmp) { + case TRANSVR_CLASS_OPTICAL_1G_SX: + return TRANSVR_CLASS_OPTICAL_10G_S_SR; + case TRANSVR_CLASS_OPTICAL_1G_LX: + return TRANSVR_CLASS_OPTICAL_10G_S_LR; + case TRANSVR_CLASS_COPPER_L1_1G: + return TRANSVR_CLASS_COPPER_L1_10G; + default: + break; + } + snprintf(err_str, sizeof(err_str), "transfer_1to10 fail, speed:%d", speed_tmp); + goto err_p_sfp_detect_class_by_1g_ethernet; + +err_p_sfp_detect_class_by_1g_ethernet: + SWPS_INFO("%s: %s :%s", __func__, err_str, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_detect_class_by_feature(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int is_active = 0; + int conn_val = DEBUG_TRANSVR_INT_VAL; + int check_val = DEBUG_TRANSVR_INT_VAL; + int wave_len = DEBUG_TRANSVR_INT_VAL; + int speed_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + speed_val = _sfp_detect_if_sp_by_br(self); + conn_val = _sfp_get_connector_type(self); + + switch(conn_val) { + case 0x00: /* Unspecified */ + goto ok_sfp_detect_class_by_feature_4_check_active_passive; + case 0x07: /* LC (Lucent Connector) */ + case 0x0b: /* Optical Pigtail */ + case 0x0c: /* MPO 1x12 */ + case 0x0d: /* MPO 2x16 */ + /* + * ToDo: Need verify Optical Pigtail + */ + goto ok_sfp_detect_class_by_feature_4_optiocal; + case 0x21: /* Copper pigtail */ + /* + * ToDo: Need check ACC use case + */ + goto ok_sfp_detect_class_by_feature_4_check_active_passive; + case 0x23: /* No separable connector */ + /* + * ToDo: Standard not clear, not all transceiver vendor + * have the same defined + */ + goto ok_sfp_detect_class_by_feature_4_check_active_passive; + default: + break; + } + goto ok_sfp_detect_class_by_feature_4_unknow; + +ok_sfp_detect_class_by_feature_4_check_active_passive: + check_val = _sfp_get_cable_tech(self); + switch(check_val) { + case 0x00: /* Unspecified */ + goto ok_sfp_detect_class_by_feature_4_unknow; + case 0x04: /* Passive */ + goto ok_sfp_detect_class_by_feature_4_copper; + case 0x08: /* Active */ + is_active = 1; + goto ok_sfp_detect_class_by_feature_4_aoc; + default: + snprintf(err_msg, sizeof(err_msg), + "_sfp_get_cable_tech return Non define value:%d", + check_val); + break; + } + goto err_sfp_detect_class_by_feature_1; + +ok_sfp_detect_class_by_feature_4_optiocal: + wave_len = _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1]); + switch(speed_val) { + case TRANSVR_CLASS_25G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_25G_SR; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_25G_LR; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_25G_ER; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_25G; + + case TRANSVR_CLASS_10G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_10G_S_SR; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_10G_S_LR; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_10G_S_ER; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_10G; + + case TRANSVR_CLASS_1G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_1G_SX; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_1G_LX; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_1G_EX; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_1G; + + default: + return TRANSVR_CLASS_OPTICAL; + } + +ok_sfp_detect_class_by_feature_4_aoc: + switch(speed_val) { + case TRANSVR_CLASS_25G: + return TRANSVR_CLASS_OPTICAL_25G_AOC; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_OPTICAL_10G_S_AOC; + case TRANSVR_CLASS_1G: + return TRANSVR_CLASS_OPTICAL_1G_AOC; + default: + break; + } + goto ok_sfp_detect_class_by_feature_4_unknow; + +ok_sfp_detect_class_by_feature_4_copper: + switch(speed_val) { + case TRANSVR_CLASS_25G: + return TRANSVR_CLASS_COPPER_L1_25G; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_COPPER_L1_10G; + case TRANSVR_CLASS_1G: + return TRANSVR_CLASS_COPPER_L1_1G; + default: + return TRANSVR_CLASS_COPPER; + } + +ok_sfp_detect_class_by_feature_4_unknow: + return TRANSVR_CLASS_UNSPECIFIED; + +err_sfp_detect_class_by_feature_1: + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +sft_detect_transvr_class(struct transvr_obj_s* self) { + + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Check Extended Compliance */ + detect_val = _sfp_detect_class_by_extend_comp(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_COPPER_L1_25G: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined extend_comp:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Check 10G Compliance */ + detect_val = _sfp_detect_class_by_10_ethernet(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined 10G_eth:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Check 1G Compliance */ + detect_val = _sfp_detect_class_by_1g_ethernet(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_COPPER_L1_1G: + case TRANSVR_CLASS_BASE_T_1000: + case TRANSVR_CLASS_OPTICAL_100: + /* + * ToDo: Need Check 0.1G + */ + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_COPPER_L1_10G: + /* Transfer speed case + * => Example: Raycom 10G DAC + */ + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined 1G_eth:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Check by connector, br, wavelength */ + detect_val = _sfp_detect_class_by_feature(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL: + case TRANSVR_CLASS_OPTICAL_1G: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_25G: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_COPPER: + case TRANSVR_CLASS_COPPER_L1_1G: + case TRANSVR_CLASS_COPPER_L1_10G: + case TRANSVR_CLASS_COPPER_L1_25G: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined get_connector:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sft_detect_transceiver_class_1; + +err_sft_detect_transceiver_class_1: + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_set_magnolia_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result){ + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch(transvr_cls) { + case TRANSVR_CLASS_ERROR: + case TRANSVR_CLASS_UNSPECIFIED: + break; + /* 25G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 25G COPPER */ + case TRANSVR_CLASS_COPPER_L1_25G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 10G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 10G COPPER */ + case TRANSVR_CLASS_COPPER_L1_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 1G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G COPPER */ + case TRANSVR_CLASS_COPPER_L1_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G BASE_T */ + case TRANSVR_CLASS_BASE_T_1000: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 100 Base */ + case TRANSVR_CLASS_OPTICAL_100: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_sfp_set_magnolia_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sfp_set_magnolia_if_type_1; + +err_sfp_set_magnolia_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_sfp_set_redwood_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result) { + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch(transvr_cls) { + case TRANSVR_CLASS_ERROR: + case TRANSVR_CLASS_UNSPECIFIED: + break; + /* 25G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G: + return snprintf(result, lmax, TRANSVR_IF_SR); + /* 25G COPPER */ + case TRANSVR_CLASS_COPPER_L1_25G: + return snprintf(result, lmax, TRANSVR_IF_KR); + /* 10G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 10G COPPER */ + case TRANSVR_CLASS_COPPER_L1_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 1G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G COPPER */ + case TRANSVR_CLASS_COPPER_L1_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G BASE_T */ + case TRANSVR_CLASS_BASE_T_1000: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 100 Base */ + case TRANSVR_CLASS_OPTICAL_100: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_sfp_set_redwood_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sfp_set_redwood_if_type_1; + +err_sfp_set_redwood_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_sfp_set_lavender_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result) { + /* (TBD) + * Due to 'LAV' looks like doesn't have interface type. + * We bypass it currently. + */ + int lmax = 8; + return snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); +} + + +int +_sfp_detect_if_type(struct transvr_obj_s* self, + char *result){ + + int lmax = 8; + int detect_cls = DEBUG_TRANSVR_INT_VAL; + + detect_cls = sft_detect_transvr_class(self); + switch (self->chipset_type) { + case CHIP_TYPE_MAGNOLIA: + return _sfp_set_magnolia_if_type(self, detect_cls, result); + + case CHIP_TYPE_MAPLE: + case CHIP_TYPE_REDWOOD: + return _sfp_set_redwood_if_type(self, detect_cls, result); + + case CHIP_TYPE_LAVENDER: + return _sfp_set_lavender_if_type(self, detect_cls, result); + + default: + SWPS_INFO("%s: non-defined chipset_type:%d :%s\n", + __func__, self->chipset_type, self->swp_name); + break; + } + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + return ERR_TRANSVR_ABNORMAL; +} + + +int +sfp_get_if_type(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 16; + char tmp_result[16] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_sfp_detect_if_type(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_sfp_detect_if_speed(struct transvr_obj_s* self, + char *result){ + + int lmax = 16; + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + detect_val = sft_detect_transvr_class(self); + switch(detect_val) { + case TRANSVR_CLASS_ERROR: + case TRANSVR_CLASS_UNSPECIFIED: + break; + /* 25G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G: + return snprintf(result, lmax, TRANSVR_IF_SP_25G); + /* 25G COPPER */ + case TRANSVR_CLASS_COPPER_L1_25G: + return snprintf(result, lmax, TRANSVR_IF_SP_25G); + /* 10G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* 10G COPPER */ + case TRANSVR_CLASS_COPPER_L1_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* 1G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + /* 1G COPPER */ + case TRANSVR_CLASS_COPPER_L1_1G: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + /* 1G BASE_T */ + case TRANSVR_CLASS_BASE_T_1000: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + /* 100 Base */ + case TRANSVR_CLASS_OPTICAL_100: + return snprintf(result, lmax, TRANSVR_IF_SP_100); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + detect_val); + goto err_sfp_detect_if_speed_1; + } + /* Check by BR */ + detect_val = _sfp_detect_if_sp_by_br(self); + switch (detect_val) { + case TRANSVR_CLASS_25G: + return snprintf(result, lmax, TRANSVR_IF_SP_25G); + case TRANSVR_CLASS_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + case TRANSVR_CLASS_1G: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + default: + break; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sfp_detect_if_speed_1; + +err_sfp_detect_if_speed_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +sfp_get_if_speed(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 16; + char tmp_result[16] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_sfp_detect_if_speed(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_qsfp_detect_class_by_extend_comp(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + + detect_val = _qsfp_get_comp_extended(self); + switch(detect_val) { + case 0x00: /* Unspecified */ + return TRANSVR_CLASS_UNSPECIFIED; + + case 0x01: /* 100G AOC (Active Optical Cable) or 25GAUI C2M */ + case 0x18: /* 100G AOC or 25GAUI C2M AOC. */ + return TRANSVR_CLASS_OPTICAL_100G_AOC; + + case 0x06: /* 100G CWDM4 */ + case 0x09: /* Obsolete (assigned before 100G CWDM4 MSA required FEC) */ + case 0x17: /* 100G CLR4 */ + case 0x1A: /* 100GE-DWDM2 */ + return TRANSVR_CLASS_OPTICAL_100G; + + case 0x02: /* 100GBASE-SR4 or 25GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_100G_SR4; + + case 0x03: /* 100GBASE-LR4 or 25GBASE-LR */ + return TRANSVR_CLASS_OPTICAL_100G_LR4; + + case 0x04: /* 100GBASE-ER4 or 25GBASE-ER */ + return TRANSVR_CLASS_OPTICAL_100G_ER4; + + case 0x07: /* 100G PSM4 Parallel SMF */ + return TRANSVR_CLASS_OPTICAL_100G_PSM4; + + case 0x12: /* 40G PSM4 Parallel SMF */ + return TRANSVR_CLASS_OPTICAL_40G; + + case 0x11: /* 4 x 10GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_40G_SR4; + + case 0x10: /* 40GBASE-ER4 */ + return TRANSVR_CLASS_OPTICAL_40G_ER4; + + case 0x08: /* 100G ACC (Active Copper Cable) or 25GAUI C2M ACC. */ + case 0x0b: /* 100GBASE-CR4 or 25GBASE-CR CA-L */ + case 0x19: /* 100G ACC or 25GAUI C2M ACC. */ + return TRANSVR_CLASS_COPPER_L4_100G; + + default: + break; + } + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_qsfp_detect_class_by_10_40_100_ethernet(struct transvr_obj_s* self) { + /* Reference: SFF-8472 (v12.2) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + + detect_val = _qsfp_get_comp_10_40_100_ethernet(self); + /* Case: Unspecified */ + if (detect_val == 0x00) { + return TRANSVR_CLASS_UNSPECIFIED; + } + /* Case: 40G Optical */ + if ((detect_val & 0x01) == 0x01) { /* 00000001 : 40G Active Cable (XLPPI) */ + return TRANSVR_CLASS_OPTICAL_40G_AOC; + } + if ((detect_val & 0x04) == 0x04) { /* 00000100 : 40GBASE-SR4 */ + return TRANSVR_CLASS_OPTICAL_40G_SR4; + } + if ( (detect_val & 0x02) == 0x02) { /* 00000010 : 40GBASE-LR4 */ + return TRANSVR_CLASS_OPTICAL_40G_LR4; + } + if ( (detect_val & 0x08) == 0x08) { /* 00001000 : 40GBASE-CR4 */ + return TRANSVR_CLASS_COPPER_L4_40G; + } + /* Case: 10G Optical */ + if ( (detect_val & 0x10) == 0x10) { /* 00010000 : 10GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_10G_Q_SR; + } + if ( ((detect_val & 0x20) == 0x20) || /* 00100000 : 10GBASE-LR */ + ((detect_val & 0x40) == 0x40) ){ /* 01000000 : 10GBASE-LRM */ + return TRANSVR_CLASS_OPTICAL_10G_Q_LR; + } + /* Case: Extend Compliance */ + if ( ((detect_val & 0x80) == 0x80) ){ /* 10000000 : Use Extend Compliance */ + return TRANSVR_CLASS_EXTEND_COMP; + } + /* Case: ERROR */ + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_qsfp_detect_if_sp_by_br(struct transvr_obj_s* self) { + + int lower_bound_10g = 0x10; + int upper_bound_10g = 0x25; + int lower_bound_40g = 0x60; + int upper_bound_40g = 0x75; + int lower_bound_100g = 0x60; + int upper_bound_100g = 0x75; + int used_extend_br = 0xff; + int notmal_br = DEBUG_TRANSVR_INT_VAL; + int extend_br = DEBUG_TRANSVR_INT_VAL; + + notmal_br = (int)(self->br); /* updated by update_all() */ + /* Check 40G */ + if ((notmal_br >= lower_bound_40g) && + (notmal_br <= upper_bound_40g) ) { + return TRANSVR_CLASS_40G; + } + /* Check 100G */ + if (notmal_br == used_extend_br) { + extend_br = (int)(self->extbr); /* updated by update_all() */ + if ((extend_br >= lower_bound_100g) && + (extend_br <= upper_bound_100g) ) { + return TRANSVR_CLASS_100G; + } + } + /* Check 10G */ + if ((notmal_br >= lower_bound_10g) && + (notmal_br <= upper_bound_10g) ) { + return TRANSVR_CLASS_10G; + } + return TRANSVR_CLASS_UNSPECIFIED; +} + + +int +_qsfp_detect_class_by_feature(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int conn_val = DEBUG_TRANSVR_INT_VAL; + int wave_len = DEBUG_TRANSVR_INT_VAL; + int speed_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + speed_val = _qsfp_detect_if_sp_by_br(self); + conn_val = _qsfp_get_connector_type(self); + + switch(conn_val) { + case 0x00: /* Unspecified */ + return TRANSVR_CLASS_UNSPECIFIED; + case 0x07: /* LC (Lucent Connector) */ + case 0x0b: /* Optical Pigtail */ + case 0x0c: /* MPO 1x12 (Multifiber Parallel Optic) */ + case 0x0d: /* MPO 2x16 */ + goto ok_qsfp_detect_class_by_feature_4_optiocal; + case 0x21: /* Copper pigtail */ + goto ok_qsfp_detect_class_by_feature_4_copper; + case 0x23: /* No separable connector */ + if ((_qsfp_get_comp_fc_link_length(self) > 0) || + (_qsfp_get_comp_fc_trans_tech(self) > 0) || + (_qsfp_get_comp_fc_trans_media(self) > 0) || + (_qsfp_get_comp_fc_speed(self) > 0) ) { + goto ok_qsfp_detect_class_by_feature_4_aoc; + } + goto ok_qsfp_detect_class_by_feature_4_copper; + default: + snprintf(err_msg, sizeof(err_msg), + "_qsfp_get_connector_type return Non define value:%d", + conn_val); + goto err_qsfp_detect_class_by_feature_1; + } + return TRANSVR_CLASS_UNSPECIFIED; + +ok_qsfp_detect_class_by_feature_4_optiocal: + wave_len = _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1]); + switch(speed_val) { + case TRANSVR_CLASS_100G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_100G_SR4; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_100G_LR4; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_100G_ER4; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_100G; + + case TRANSVR_CLASS_40G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_40G_SR4; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_40G_LR4; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_40G_ER4; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_40G; + + case TRANSVR_CLASS_10G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_10G_Q_SR; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_10G_Q_LR; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_10G_Q_ER; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_10G; + + default: + return TRANSVR_CLASS_OPTICAL; + } + +ok_qsfp_detect_class_by_feature_4_aoc: + switch(speed_val) { + case TRANSVR_CLASS_100G: + return TRANSVR_CLASS_OPTICAL_100G_AOC; + case TRANSVR_CLASS_40G: + return TRANSVR_CLASS_OPTICAL_40G_AOC; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_OPTICAL_10G_Q_AOC; + default: + return TRANSVR_CLASS_OPTICAL; + } + +ok_qsfp_detect_class_by_feature_4_copper: + switch(speed_val) { + case TRANSVR_CLASS_100G: + return TRANSVR_CLASS_COPPER_L4_100G; + case TRANSVR_CLASS_40G: + return TRANSVR_CLASS_COPPER_L4_40G; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_COPPER_L4_10G; + default: + return TRANSVR_CLASS_COPPER; + } + +err_qsfp_detect_class_by_feature_1: + SWPS_INFO("%s: %s\n :%s", + __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +qsft_detect_transvr_class(struct transvr_obj_s* self) { + + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Check Extended Compliance */ + detect_val = _qsfp_detect_class_by_extend_comp(self); + switch (detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + case TRANSVR_CLASS_COPPER_L4_100G: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined extend_comp:%d", + detect_val); + goto err_qsft_detect_transvr_class_1; + } + /* Check 10/40G/100G Ethernet Compliance */ + detect_val = _qsfp_detect_class_by_10_40_100_ethernet(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_COPPER_L4_40G: + return detect_val; + case TRANSVR_CLASS_EXTEND_COMP: + /* Format incorrect case (We already checked the Extend + * Compliance is 0 + */ + snprintf(err_msg, sizeof(err_msg), + "Transceiver format incorrect"); + goto err_qsft_detect_transvr_class_1; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined 10/40/100:%d", + detect_val); + goto err_qsft_detect_transvr_class_1; + } + /* Check by Connector type, BR and wavelength */ + detect_val = _qsfp_detect_class_by_feature(self); + switch (detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL: + case TRANSVR_CLASS_COPPER_L4_100G: + case TRANSVR_CLASS_COPPER_L4_40G: + case TRANSVR_CLASS_COPPER_L4_10G: + case TRANSVR_CLASS_COPPER: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined connector:%d", + detect_val); + goto err_qsft_detect_transvr_class_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), + "Can not identify!"); + goto err_qsft_detect_transvr_class_1; + +err_qsft_detect_transvr_class_1: + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_qsfp_set_magnolia_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result){ + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch (transvr_cls) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_ERROR: + break; + /* 100G Optical */ + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* 100G Copper */ + case TRANSVR_CLASS_COPPER_L4_100G: + return snprintf(result, lmax, TRANSVR_IF_KR4); + /* 40G Optical */ + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* 40G Copper */ + case TRANSVR_CLASS_COPPER_L4_40G: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* 10G Optical */ + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: LR4 or LR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: /* Need Check: ER4 or ER */ + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* Optical */ + case TRANSVR_CLASS_OPTICAL: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* Copper */ + case TRANSVR_CLASS_COPPER: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_qsfp_set_magnolia_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_qsfp_set_magnolia_if_type_1; + +err_qsfp_set_magnolia_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_qsfp_set_redwood_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result){ + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch (transvr_cls) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_ERROR: + break; + /* 100G Optical */ + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* 100G Copper */ + case TRANSVR_CLASS_COPPER_L4_100G: + return snprintf(result, lmax, TRANSVR_IF_KR4); + /* 40G Optical */ + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* 40G Copper */ + case TRANSVR_CLASS_COPPER_L4_40G: + return snprintf(result, lmax, TRANSVR_IF_KR4); + /* 10G Optical */ + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* Optical */ + case TRANSVR_CLASS_OPTICAL: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* Copper */ + case TRANSVR_CLASS_COPPER: + return snprintf(result, lmax, TRANSVR_IF_KR4); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_qsfp_set_magnolia_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_qsfp_set_magnolia_if_type_1; + +err_qsfp_set_magnolia_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_qsfp_set_lavender_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result) { + /* (TBD) + * Due to 'LAV' looks like doesn't have interface type. + * We bypass it currently. + */ + int lmax = 8; + return snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); +} + + +int +_qsfp_detect_if_type(struct transvr_obj_s* self, + char *result){ + + int lmax = 8; + int detect_cls = DEBUG_TRANSVR_INT_VAL; + + detect_cls = qsft_detect_transvr_class(self); + switch (self->chipset_type) { + case CHIP_TYPE_MAGNOLIA: + return _qsfp_set_magnolia_if_type(self, detect_cls, result); + + case CHIP_TYPE_MAPLE: + case CHIP_TYPE_REDWOOD: + return _qsfp_set_redwood_if_type(self, detect_cls, result); + + case CHIP_TYPE_LAVENDER: + return _qsfp_set_lavender_if_type(self, detect_cls, result); + + default: + SWPS_INFO("%s: non-defined chipset_type:%d :%s\n", + __func__, self->chipset_type, self->swp_name); + break; + } + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_if_type(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 8; + char tmp_result[8] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_qsfp_detect_if_type(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_qsfp_detect_if_speed(struct transvr_obj_s* self, + char *result){ + int lmax = 16; + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + detect_val = qsft_detect_transvr_class(self); + switch (detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_ERROR: + break; + /* 100G Optical */ + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return snprintf(result, lmax, TRANSVR_IF_SP_100G); + /* 100G Copper */ + case TRANSVR_CLASS_COPPER_L4_100G: + return snprintf(result, lmax, TRANSVR_IF_SP_100G); + /* 40G Optical */ + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + return snprintf(result, lmax, TRANSVR_IF_SP_40G); + /* 40G Copper */ + case TRANSVR_CLASS_COPPER_L4_40G: + return snprintf(result, lmax, TRANSVR_IF_SP_40G); + /* 10G Optical */ + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* 10G Copper */ + case TRANSVR_CLASS_COPPER_L4_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* Optical */ + case TRANSVR_CLASS_OPTICAL: + break; + /* Copper */ + case TRANSVR_CLASS_COPPER: + break; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined class case:%d", + detect_val); + goto err_qsfp_detect_if_speed_1; + } + /* Check br and extbr */ + detect_val = _qsfp_detect_if_sp_by_br(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + case TRANSVR_CLASS_40G: + return snprintf(result, lmax, TRANSVR_IF_SP_40G); + case TRANSVR_CLASS_100G: + return snprintf(result, lmax, TRANSVR_IF_SP_100G); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined BR case:%d", + detect_val); + goto err_qsfp_detect_if_speed_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_qsfp_detect_if_speed_1; + +err_qsfp_detect_if_speed_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_if_speed(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 16; + char tmp_result[16] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_qsfp_detect_if_speed(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_common_set_lane_map_str(struct transvr_obj_s* self, + char *result) { + int i = 0; + int tmp_val = 0; + char tmp_str[LEN_TRANSVR_L_STR] = DEBUG_TRANSVR_STR_VAL; + char err_msg[LEN_TRANSVR_L_STR] = DEBUG_TRANSVR_STR_VAL; + + memset(result, 0, LEN_TRANSVR_L_STR); + snprintf(result, LEN_TRANSVR_L_STR, "%s=", TRANSVR_UEVENT_KEY_LANE); + + for (i=0; ilane_id); i++) { + tmp_val = self->lane_id[i]; + if (tmp_val < 1) { + break; + } + if (tmp_val > 256) { + snprintf(err_msg, sizeof(err_msg), + "detect abnormal value:%d", tmp_val); + goto err_common_set_lane_map_str_1; + } + memset(tmp_str, 0, sizeof(tmp_str)); + if (i == 0) { + snprintf(tmp_str, LEN_TRANSVR_L_STR, "%d", tmp_val); + } else { + snprintf(tmp_str, LEN_TRANSVR_L_STR, ",%d", tmp_val); + } + strncat(result, tmp_str, LEN_TRANSVR_L_STR); + } + if (i == 0) { + goto err_common_set_lane_map_str_2; + } + return 0; + +err_common_set_lane_map_str_1: + SWPS_INFO("%s: %s", __func__, err_msg); +err_common_set_lane_map_str_2: + snprintf(result, LEN_TRANSVR_L_STR, "%s=%s", TRANSVR_UEVENT_KEY_LANE, TRANSVR_UEVENT_UNKNOW); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_common_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action, + int (*detect_if_type)(struct transvr_obj_s *self, char *result), + int (*detect_if_speed)(struct transvr_obj_s *self, char *result), + int send_anyway) { + + char *uevent_envp[4]; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + char tmp_str[32] = DEBUG_TRANSVR_STR_VAL; + char tmp_str_1[32] = DEBUG_TRANSVR_STR_VAL; + char tmp_str_2[32] = DEBUG_TRANSVR_STR_VAL; + char tmp_str_3[64] = DEBUG_TRANSVR_STR_VAL; + + if (TRANSVR_UEVENT_ENABLE != 1) { + return ERR_TRANSVR_NOTSUPPORT; + } + if (_common_get_if_lane(self, tmp_str) < 0) { + snprintf(tmp_str_3, sizeof(tmp_str_3), + "%s=%s", TRANSVR_UEVENT_KEY_LANE, TRANSVR_UEVENT_UNKNOW); + } else { + snprintf(tmp_str_3, sizeof(tmp_str_3), + "%s=%s", TRANSVR_UEVENT_KEY_LANE, tmp_str); + } + switch (u_action) { + case KOBJ_ADD: + /* Detect type */ + if (detect_if_type(self, tmp_str) < 0) { + snprintf(err_msg, sizeof(err_msg), "%s", "Detect interface type fail!"); + snprintf(tmp_str_1, sizeof(tmp_str_1), "%s=%s", TRANSVR_UEVENT_KEY_IF, TRANSVR_UEVENT_UNKNOW); + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, TRANSVR_UEVENT_UNKNOW); + uevent_envp[0] = tmp_str_1; + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_fail; + } + snprintf(tmp_str_1, sizeof(tmp_str_1), "%s=%s", TRANSVR_UEVENT_KEY_IF, tmp_str); + uevent_envp[0] = tmp_str_1; + /* Detect speed */ + if (detect_if_speed(self, tmp_str) < 0) { + snprintf(err_msg, sizeof(err_msg), "%s", "Detect interface speed fail!"); + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, TRANSVR_UEVENT_UNKNOW); + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_fail; + } + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, tmp_str); + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_send; + + case KOBJ_REMOVE: + snprintf(tmp_str_1, sizeof(tmp_str_1), "%s=%s", TRANSVR_UEVENT_KEY_IF, TRANSVR_UEVENT_UNKNOW); + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, TRANSVR_UEVENT_UNKNOW); + uevent_envp[0] = tmp_str_1; + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_send; + + default: + snprintf(err_msg, sizeof(err_msg), "kobject_action:%d not support", u_action); + goto private_common_send_uevent_4_fail; + } + snprintf(err_msg, sizeof(err_msg), "%s", "Exception case"); + goto private_common_send_uevent_4_fail; + +private_common_send_uevent_4_fail: + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + if (send_anyway) { + goto private_common_send_uevent_4_send; + } + return ERR_TRANSVR_UEVENT_FAIL; + +private_common_send_uevent_4_send: + return kobject_uevent_env(&(self->transvr_dev_p->kobj), + u_action, + uevent_envp); +} + +int +sfp_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action) { + int send_anyway = 1; + return _common_send_uevent(self, + u_action, + &_sfp_detect_if_type, + &_sfp_detect_if_speed, + send_anyway); +} + + +int +qsfp_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action) { + int send_anyway = 1; + return _common_send_uevent(self, + u_action, + &_qsfp_detect_if_type, + &_qsfp_detect_if_speed, + send_anyway); +} + + +int +fake_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action) { + return EVENT_TRANSVR_TASK_DONE; +} + + +int +common_fsm_4_direct_mode(struct transvr_obj_s* self, + char *caller_name){ + + int err; + int detect_result[2]; + int current_state = STATE_TRANSVR_UNEXCEPTED; + int current_type = TRANSVR_TYPE_ERROR; + + if (self->state == STATE_TRANSVR_NEW) { + if (_transvr_init_handler(self) < 0){ + return ERR_TRANSVR_INIT_FAIL; + } + } + err = detect_transvr_state(self, detect_result); + if (err < 0) { + return err; + } + /* In Direct mode, driver only detect transceiver when user call driver interface + * which on sysfs. So it only need consider the state of Transceiver. + */ + current_state = detect_result[0]; + current_type = detect_result[1]; + + switch (current_state){ + + case STATE_TRANSVR_DISCONNECTED: /* Transceiver is not plugged */ + self->state = current_state; + self->type = current_type; + return ERR_TRANSVR_UNPLUGGED; + + case STATE_TRANSVR_INIT: /* Transceiver is plugged, system not ready */ + return ERR_TRANSVR_UNINIT; + + case STATE_TRANSVR_ISOLATED: /* Transceiver is plugged, but has some issues */ + return ERR_TRNASVR_BE_ISOLATED; + + case STATE_TRANSVR_CONNECTED: /* Transceiver is plugged, system is ready */ + self->state = current_state; + self->type = current_type; + return 0; + + case STATE_TRANSVR_SWAPPED: /* Transceiver is plugged, system detect user changed */ + self->type = current_type; + if (reload_transvr_obj(self, current_type) < 0){ + self->state = STATE_TRANSVR_UNEXCEPTED; + return ERR_TRANSVR_UNEXCPT; + } + self->state = current_state; + return 0; + + case STATE_TRANSVR_UNEXCEPTED: /* Transceiver type or state is unexpected case */ + self->state = STATE_TRANSVR_UNEXCEPTED; + self->type = TRANSVR_TYPE_ERROR; + return ERR_TRANSVR_UNEXCPT; + + default: + SWPS_INFO("%s: state:%d not in define.\n", __func__, current_state); + break; + } + return ERR_TRANSVR_UNEXCPT; +} + + +static int +_is_except_happened_4_pmode(struct transvr_obj_s* self, + int new_state) { + + int event_chk = 0; + + if (self->temp == 0){ + return 0; + } + switch (new_state) { + case STATE_TRANSVR_INIT: + event_chk = EVENT_TRANSVR_EXCEP_INIT; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_CONNECTED: + event_chk = EVENT_TRANSVR_EXCEP_UP; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_DISCONNECTED: + event_chk = EVENT_TRANSVR_EXCEP_DOWN; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_SWAPPED: + event_chk = EVENT_TRANSVR_EXCEP_SWAP; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_UNEXCEPTED: + event_chk = EVENT_TRANSVR_EXCEP_EXCEP; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_ISOLATED: + event_chk = EVENT_TRANSVR_EXCEP_ISOLATED; + goto check_event_happened_4_pmode; + + default: + SWPS_INFO("%s: unexcepted case:%d\n", __func__, new_state); + break; + } + return 0; + +check_event_happened_4_pmode: + if (self->temp == event_chk){ + return 1; + } + return 0; +} + + +int +common_fsm_4_polling_mode(struct transvr_obj_s* self, + char *caller_name){ + /* [Return Value]: + * ERR_TRANSVR_UNINIT : (1) Initial not ready + * ERR_TRANSVR_UNPLUGGED : (1) Any -> Down + * ERR_TRANSVR_TASK_BUSY : (1) Wait Initial task + * ERR_TRANSVR_UNEXCPT : (1) Initial fail + * (2) Task fail + * (3) Reload fail + * ERR_TRNASVR_BE_ISOLATED : (1) Already be isolated + * OK Case (return 0) : (1) action_4_connected + * (2) action_4_nothing (initial retry) + */ + int curr_state[2]; + int old_state = self->state; + int old_type = self->type; + int new_state = STATE_TRANSVR_UNEXCEPTED; + int new_type = TRANSVR_TYPE_ERROR; + int return_val = ERR_TRANSVR_UNEXCPT; + + /* Never initial */ + if (self->state == STATE_TRANSVR_NEW) { + goto comfsm_action_4_reinit_obj; + } + /* Detect current state */ + switch (detect_transvr_state(self, curr_state)) { + case 0: + new_state = curr_state[0]; + new_type = curr_state[1]; + break; + + case ERR_TRNASVR_BE_ISOLATED: + new_state = STATE_TRANSVR_ISOLATED; + new_type = old_type; + break; + + case ERR_TRANSVR_I2C_CRASH: + goto comfsm_action_4_report_i2c_crash; + + case ERR_TRANSVR_UNEXCPT: + default: + new_state = STATE_TRANSVR_UNEXCEPTED; + new_type = old_type; + } + /* State handling */ + switch (old_state) { + case STATE_TRANSVR_INIT: /* INIT -> */ + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 1-1: UP -> INIT */ + SWPS_INFO("Detect %s is present. :1-1\n",self->swp_name); + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 1-2: UP -> UP */ + return_val = 0; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_DISCONNECTED: /* Case 1-3: UP -> DOWN */ + SWPS_INFO("Detect %s is removed. :1-3\n",self->swp_name); + goto comfsm_action_4_disconnected; + + case STATE_TRANSVR_SWAPPED: /* Case 1-4: UP -> SWAP */ + SWPS_INFO("Detect %s is swapped. :1-4\n",self->swp_name); + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 1-5: UP -> UNEXPET */ + SWPS_INFO("Detect %s has error. :1-5\n",self->swp_name); + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_ISOLATED: /* Case 1-6: UP -> ISOLATE */ + SWPS_INFO("Detect %s be isolated. :1-6\n",self->swp_name); + goto comfsm_action_4_isolate_obj; + + default: + break; + } + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_DISCONNECTED: + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 2-1: DOWN -> INIT */ + SWPS_INFO("Detect %s is present. :2-1\n",self->swp_name); + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 2-2: DOWN -> UP */ + SWPS_INFO("Detect %s is present. :2-2\n",self->swp_name); + goto comfsm_action_4_reinit_obj; + + case STATE_TRANSVR_DISCONNECTED: /* Case 2-3: DOWN -> DOWN */ + return_val = ERR_TRANSVR_UNPLUGGED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_SWAPPED: /* Case 2-4: DOWN -> SWAP */ + SWPS_INFO("Detect %s is swapped. :2-4\n",self->swp_name); + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 2-5: DOWN -> UNEXPET */ + SWPS_INFO("Detect %s has error. :2-5\n",self->swp_name); + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_ISOLATED: /* Case 2-6: DOWN -> ISOLATE */ + SWPS_INFO("Detect %s be isolated. :2-6\n",self->swp_name); + goto comfsm_action_4_isolate_obj; + + default: + break; + } + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_UNEXCEPTED: + /* Filter out re-action */ + if (_is_except_happened_4_pmode(self, new_state)) { + goto comfsm_action_4_keep_state; + } + /* First action */ + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 3-1: UNEXPET -> INIT */ + SWPS_INFO("Detect %s is present. :3-1\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_INIT; + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 3-2: UNEXPET -> UP */ + SWPS_INFO("Detect %s is present. :3-2\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_UP; + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_DISCONNECTED: /* Case 3-3: UNEXPET -> DOWN */ + SWPS_INFO("Detect %s is removed. :3-3\n",self->swp_name); + goto comfsm_action_4_disconnected; + + case STATE_TRANSVR_SWAPPED: /* Case 3-4: UNEXPET -> SWAP */ + SWPS_INFO("Detect %s is swapped. :3-4\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_SWAP; + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 3-5: UNEXPET -> UNEXPET */ + self->temp = EVENT_TRANSVR_EXCEP_EXCEP; + return_val = ERR_TRANSVR_UNEXCPT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_ISOLATED: /* Case 3-6: UNEXPET -> ISOLATE */ + SWPS_INFO("Detect %s be isolated. :3-6\n",self->swp_name); + goto comfsm_action_4_isolate_obj; + + default: + break; + } + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_ISOLATED: + /* Filter out re-action */ + if (_is_except_happened_4_pmode(self, new_state)) { + goto comfsm_action_4_keep_state; + } + /* First action */ + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 4-1: ISOLATE -> INIT */ + SWPS_INFO("Detect %s internal error. :4-1\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_INIT; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 4-2: ISOLATE -> UP */ + SWPS_INFO("Detect %s internal error. :4-2\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_UP; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_DISCONNECTED: /* Case 4-3: ISOLATE -> DOWN */ + SWPS_INFO("Detect %s is removed. :4-3\n",self->swp_name); + goto comfsm_action_4_disconnected; + + case STATE_TRANSVR_SWAPPED: /* Case 4-4: ISOLATE -> SWAP */ + SWPS_INFO("Detect %s internal error. :4-4\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_SWAP; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 4-5: ISOLATE -> UNEXPET */ + SWPS_INFO("Detect %s internal error. :4-5\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_EXCEP; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_ISOLATED: /* Case 4-6: ISOLATE -> ISOLATE */ + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + default: + break; + } + goto comfsm_action_4_unexpected; + + default: + break; + } + goto comfsm_action_4_unexpected; + + +comfsm_action_4_keep_state: + return return_val; + +comfsm_action_4_reinit_obj: + SWPS_DEBUG("FSM action: %s re-initial.\n", self->swp_name); + return_val = _transvr_init_handler(self); + goto comfsm_action_4_identify_event; + +comfsm_action_4_reload_obj: + SWPS_DEBUG("FSM action: %s reload.\n", self->swp_name); + self->type = new_type; + return_val = reload_transvr_obj(self, new_type); + goto comfsm_action_4_identify_event; + +comfsm_action_4_identify_event: + switch (return_val) { + case EVENT_TRANSVR_INIT_UP: + case EVENT_TRANSVR_TASK_DONE: + goto comfsm_action_4_connected; + + case EVENT_TRANSVR_INIT_DOWN: + goto comfsm_action_4_disconnected; + + case EVENT_TRANSVR_INIT_REINIT: + goto comfsm_action_4_nothing; + + case EVENT_TRANSVR_TASK_WAIT: + self->state = STATE_TRANSVR_INIT; + return ERR_TRANSVR_TASK_BUSY; + + case EVENT_TRANSVR_TASK_FAIL: + SWPS_INFO("%s detect EVENT_TRANSVR_TASK_FAIL.\n", self->swp_name); + goto comfsm_action_4_unexpected; + + case EVENT_TRANSVR_INIT_FAIL: + SWPS_INFO("%s detect EVENT_TRANSVR_INIT_FAIL.\n", self->swp_name); + goto comfsm_action_4_unexpected; + + case EVENT_TRANSVR_RELOAD_FAIL: + SWPS_INFO("%s detect EVENT_TRANSVR_RELOAD_FAIL.\n", self->swp_name); + goto comfsm_action_4_unexpected; + + case EVENT_TRANSVR_I2C_CRASH: + goto comfsm_action_4_report_i2c_crash; + + case EVENT_TRANSVR_EXCEP_ISOLATED: + goto comfsm_action_4_isolate_obj; + + default: + SWPS_INFO("%s detect undefined event:%d.\n", self->swp_name, return_val); + goto comfsm_action_4_unexpected; + } + +comfsm_action_4_nothing: + SWPS_DEBUG("FSM action: %s do nothing.\n", self->swp_name); + return 0; + +comfsm_action_4_connected: + SWPS_DEBUG("FSM action: %s Connected.\n", self->swp_name); + self->state = STATE_TRANSVR_CONNECTED; + self->type = new_type; + self->send_uevent(self, KOBJ_ADD); + _transvr_clean_retry(self); + return 0; + +comfsm_action_4_disconnected: + SWPS_DEBUG("FSM action: %s Disconnected. \n", self->swp_name); + self->state = STATE_TRANSVR_DISCONNECTED; + self->temp = EVENT_TRANSVR_TASK_DONE; + self->send_uevent(self, KOBJ_REMOVE); + _transvr_clean_retry(self); + _transvr_clean_handler(self); + return ERR_TRANSVR_UNPLUGGED; + +comfsm_action_4_report_i2c_crash: + SWPS_DEBUG("FSM action: %s report I2C crash.\n", self->swp_name); + self->state = STATE_TRANSVR_UNEXCEPTED; + return ERR_TRANSVR_I2C_CRASH; + +comfsm_action_4_isolate_obj: + SWPS_DEBUG("FSM action: %s isolate.\n", self->swp_name); + self->state = STATE_TRANSVR_ISOLATED; + return ERR_TRNASVR_BE_ISOLATED; + +comfsm_action_4_unexpected: + SWPS_INFO("FSM action: %s unexpected.\n", self->swp_name); + SWPS_INFO("Dump: :%d :0x%02x :%d :0x%02x\n", + old_state, old_type, new_state, new_type); + self->state = STATE_TRANSVR_UNEXCEPTED; + self->send_uevent(self, KOBJ_REMOVE); + _transvr_clean_handler(self); + return ERR_TRANSVR_UNEXCPT; +} + + +int +fake_fsm_4_direct_mode(struct transvr_obj_s* self, + char *caller_name){ + self->state = STATE_TRANSVR_CONNECTED; + self->type = TRANSVR_TYPE_FAKE; + return 0; +} + + +int +fake_fsm_4_polling_mode(struct transvr_obj_s* self, + char *caller_name){ + self->state = STATE_TRANSVR_CONNECTED; + self->type = TRANSVR_TYPE_FAKE; + return 0; +} + + +/* ========== Object functions for Initial procedure ========== + */ +int +transvr_init_common(struct transvr_obj_s *self){ + /* Nothing to update */ + return EVENT_TRANSVR_TASK_DONE; +} + + +int +transvr_init_fake(struct transvr_obj_s *self){ + return EVENT_TRANSVR_TASK_DONE; +} + + +int +transvr_init_sfp(struct transvr_obj_s *self){ + + int tmp_val = DEBUG_TRANSVR_INT_VAL; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *err_msg = "ERR"; + + self->info = sft_detect_transvr_class(self); + /* Disable auto_config */ + if (!self->auto_config) { + return EVENT_TRANSVR_TASK_DONE; + } + /* Handle multi-rate */ + err_code = initfunc_sfp_handle_multi_rate_mode(self); + if (err_code < 0) { + err_msg = "initfunc_sfp_handle_multi_rate_mode fail!"; + goto err_transvr_init_sfp_1; + } + /* Handle 1G- RJ45 */ + tmp_val = err_code; + err_code = initfunc_sfp_handle_1g_rj45(self); + if (err_code < 0) { + err_msg = "initfunc_sfp_handle_1g_rj45 fail!"; + goto err_transvr_init_sfp_1; + } + tmp_val = (tmp_val > err_code ? tmp_val : err_code); + if (tmp_val > EVENT_TRANSVR_TASK_DONE) { + return tmp_val; + } + return EVENT_TRANSVR_TASK_DONE; + +err_transvr_init_sfp_1: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, err_code, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +int +transvr_init_qsfp(struct transvr_obj_s *self){ + + int err = EVENT_TRANSVR_EXCEP_EXCEP; + char *emsg = "ERR"; + + self->info = qsft_detect_transvr_class(self); + if (!self->auto_config) { + return EVENT_TRANSVR_TASK_DONE; + } + err = initfunc_qsfp_handle_power_mode(self); + if (err < 0){ + emsg = "initfunc_qsfp_handle_tx_disable fail!"; + goto err_transvr_init_qsfp; + } + return EVENT_TRANSVR_TASK_DONE; + +err_transvr_init_qsfp: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, emsg, err, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +int +transvr_init_qsfp28(struct transvr_obj_s *self){ + + int tmp_val = EVENT_TRANSVR_EXCEP_EXCEP; + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_msg = "ERR"; + + /* Handle QSFP common */ + err_val = transvr_init_qsfp(self); + if (err_val < 0){ + err_msg = "transvr_init_qsfp fail!"; + goto err_transvr_init_qsfp28_1; + } + /* Disable auto_config */ + if (!self->auto_config) { + return err_val; + } + /* Handle CDR */ + tmp_val = err_val; + err_val = initfunc_qsfp28_handle_cdr(self); + if (err_val < 0){ + err_msg = "Handle CDR fail!"; + goto err_transvr_init_qsfp28_1; + } + tmp_val = (tmp_val > err_val ? tmp_val : err_val); + if (tmp_val > EVENT_TRANSVR_TASK_DONE) { + return tmp_val; + } + return EVENT_TRANSVR_TASK_DONE; + +err_transvr_init_qsfp28_1: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, err_val, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +/* ========== Object Initial handler ========== + */ +static int +_is_transvr_valid(struct transvr_obj_s *self, + int type, + int state) { + /* [Return] + * 0 : OK, inserted + * EVENT_TRANSVR_INIT_DOWN : OK, removed + * EVENT_TRANSVR_INIT_FAIL : Outside error, type doesn't supported + * EVENT_TRANSVR_EXCEP_INIT : Internal error, state undefined + */ + switch (type) { + case TRANSVR_TYPE_SFP: + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + case TRANSVR_TYPE_UNPLUGGED: + case TRANSVR_TYPE_FAKE: + break; + default: + SWPS_INFO("detect undefined type:0x%02x on %s\n", + type, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; + } + switch (state) { + case STATE_TRANSVR_DISCONNECTED: + return EVENT_TRANSVR_INIT_DOWN; + case STATE_TRANSVR_INIT: + case STATE_TRANSVR_CONNECTED: + case STATE_TRANSVR_SWAPPED: + break; + default: + SWPS_INFO("detect undefined state:%d on %s\n", + state, self->swp_name); + return EVENT_TRANSVR_EXCEP_INIT; + } + return 0; +} + + +static int +_is_transvr_hw_ready(struct transvr_obj_s *self, + int type){ + /* [Return] + * EVENT_TRANSVR_TASK_DONE : Ready + * EVENT_TRANSVR_TASK_WAIT : Not ready + * EVENT_TRANSVR_INIT_FAIL : Error + */ + int addr = DEBUG_TRANSVR_INT_VAL; + int page = DEBUG_TRANSVR_INT_VAL; + int offs = DEBUG_TRANSVR_INT_VAL; + int bit = DEBUG_TRANSVR_INT_VAL; + int ready = DEBUG_TRANSVR_INT_VAL; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t ab_val = DEBUG_TRANSVR_HEX_VAL; + + switch (type) { + case TRANSVR_TYPE_SFP: + addr = VAL_TRANSVR_8472_READY_ADDR; + page = VAL_TRANSVR_8472_READY_PAGE; + offs = VAL_TRANSVR_8472_READY_OFFSET; + bit = VAL_TRANSVR_8472_READY_BIT; + ready = VAL_TRANSVR_8472_READY_VALUE; + ab_val = VAL_TRANSVR_8472_READY_ABNORMAL; + break; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + addr = VAL_TRANSVR_8436_READY_ADDR; + page = VAL_TRANSVR_8436_READY_PAGE; + offs = VAL_TRANSVR_8436_READY_OFFSET; + bit = VAL_TRANSVR_8436_READY_BIT; + ready = VAL_TRANSVR_8436_READY_VALUE; + ab_val = VAL_TRANSVR_8436_READY_ABNORMAL; + break; + + case TRANSVR_TYPE_UNPLUGGED: + case TRANSVR_TYPE_FAKE: + return EVENT_TRANSVR_TASK_DONE; + + default: + emsg = "unexpected case"; + goto err_is_transvr_hw_ready; + } + /* Select target page */ + err = _common_setup_page(self, addr, page, offs, 1, 0); + if (err < 0) { + emsg = "setup page fail"; + goto err_is_transvr_hw_ready; + } + /* Check feature supported + * [Note] + * Some of transceiver/cables doesn't support "Status Indicators" + * (ex:DAC, RJ45 copper SFP ...etc). In these case, we bypass the + * step of checking Status Indicators, then state machine will take + * the following handle procedure. + */ + err = i2c_smbus_read_byte_data(self->i2c_client_p, + VAL_TRANSVR_COMID_OFFSET); + if (err < 0) { + emsg = "doesn't support Status Indicators"; + goto bypass_is_transvr_hw_ready; + } + /* Filter abnormal case */ + if (err == ab_val) { + emsg = "detect using unusual definition."; + goto bypass_is_transvr_hw_ready; + } + /* Get Status Indicators */ + err = i2c_smbus_read_byte_data(self->i2c_client_p, offs); + if (err < 0) { + emsg = "detect current value fail"; + goto err_is_transvr_hw_ready; + } + + if ((err & (1<:%d\n", __func__, emsg, type); + return EVENT_TRANSVR_TASK_DONE; + +err_is_transvr_hw_ready: + SWPS_DEBUG("%s: %s :%d\n", __func__, emsg, type); + return EVENT_TRANSVR_INIT_FAIL; +} + + +static int +_is_transvr_support_ctle(struct transvr_obj_s *self) { + + switch (self->info) { + case TRANSVR_CLASS_OPTICAL_25G: + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return 1; + default: + break; + } + return 0; +} + + +static int +_transvr_init_handler(struct transvr_obj_s *self){ + + int detect[2]; + int d_state = STATE_TRANSVR_UNEXCEPTED; + int d_type = TRANSVR_TYPE_ERROR; + int result = ERR_TRANSVR_UNINIT; + int retry = 6; /* (6+1) x 0.3 = 2.1s > spec:2.0s */ + int elimit = 63; + char emsg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Clean and check callback */ + self->state = STATE_TRANSVR_INIT; + if (self->init == NULL) { + snprintf(emsg, elimit, "init() is null"); + goto initer_err_case_unexcept_0; + } + if (self->clean == NULL) { + snprintf(emsg, elimit, "clean() is null"); + goto initer_err_case_unexcept_0; + } + self->clean(self); + + /* Detect transceiver information */ + result = detect_transvr_state(self, detect); + if (result < 0) { + snprintf(emsg, elimit, "detect_transvr_state() fail"); + switch (result) { + case ERR_TRANSVR_I2C_CRASH: + goto initer_err_case_i2c_ceash; + case ERR_TRNASVR_BE_ISOLATED: + goto initer_err_case_be_isolated; + + case ERR_TRANSVR_UNEXCPT: + default: + break; + } + goto initer_err_case_retry_1; + } + d_state = detect[0]; + d_type = detect[1]; + + /* Verify transceiver type and state */ + switch (_is_transvr_valid(self, d_type, d_state)) { + case 0: + break; + case EVENT_TRANSVR_INIT_DOWN: + goto initer_ok_case_down;; + case EVENT_TRANSVR_INIT_FAIL: + snprintf(emsg, elimit, "transceiver type doesn't support"); + goto initer_err_case_alarm_to_user; + case EVENT_TRANSVR_EXCEP_INIT: + default: + goto initer_err_case_unexcept_1; + } + + /* Handle reload case */ + if (self->type != d_type){ + /* This is the protect mechanism. Normally, This case will not happen. + * When State machine detect swap event during initial, It will trigger + * reload function to ensure type correct. */ + if (_reload_transvr_obj(self, d_type) < 0){ + snprintf(emsg, elimit, "reload object fail"); + goto initer_err_case_unexcept_1; + } + } + + /* Check transceiver HW initial ready */ + switch (_is_transvr_hw_ready(self, d_type)) { + case EVENT_TRANSVR_TASK_DONE: + break; + case EVENT_TRANSVR_TASK_WAIT: + goto initer_err_case_retry_1; + case EVENT_TRANSVR_INIT_FAIL: + default: + goto initer_err_case_unexcept_1; + } + + /* Try to update all and check */ + if (self->update_all(self, 1) < 0){ + /* For some transceiver, EEPROME has lag issues during initial stage. + * In this case, we set status back to STATE_TRANSVR_NEW, than it will + * be checked in next polling cycle. */ + goto initer_err_case_retry_1; + } + + /* Execute init() call back */ + result = self->init(self); + switch (result) { + case EVENT_TRANSVR_TASK_DONE: + break; + case EVENT_TRANSVR_TASK_WAIT: + goto initer_ok_case_wait; + + default: + snprintf(emsg, elimit, "undefined init() return:%d\n", result); + goto initer_err_case_unexcept_1; + } + goto initer_ok_case_up; + + +initer_ok_case_wait: + self->dump_all(self); + return EVENT_TRANSVR_TASK_WAIT; + +initer_ok_case_up: + self->state = STATE_TRANSVR_CONNECTED; + self->temp = 0; + self->dump_all(self); + return EVENT_TRANSVR_INIT_UP; + +initer_ok_case_down: + self->temp = 0; + self->state = STATE_TRANSVR_DISCONNECTED; + return EVENT_TRANSVR_INIT_DOWN; + +initer_err_case_i2c_ceash: + SWPS_DEBUG("%s: %s :%s :I2C crash\n", + __func__, emsg, self->swp_name); + self->state = STATE_TRANSVR_UNEXCEPTED; + return EVENT_TRANSVR_I2C_CRASH; + +initer_err_case_be_isolated: + SWPS_DEBUG("%s: %s :%s :isolated\n", + __func__, emsg, self->swp_name); + self->state = STATE_TRANSVR_ISOLATED; + return EVENT_TRANSVR_EXCEP_ISOLATED; + +initer_err_case_retry_1: + SWPS_DEBUG("%s: %s :%s :retry\n", + __func__, emsg, self->swp_name); + if (_transvr_handle_retry(self, retry) == 0) { + self->state = STATE_TRANSVR_NEW; + return EVENT_TRANSVR_INIT_REINIT; + } + goto initer_err_case_alarm_to_user; + +initer_err_case_unexcept_1: + self->clean(self); +initer_err_case_unexcept_0: + self->state = STATE_TRANSVR_UNEXCEPTED; + if (_is_except_happened_4_pmode(self, d_state) && + (self->mode == TRANSVR_MODE_POLLING) ){ + SWPS_INFO("%s: %s :%s\n", __func__, emsg, self->swp_name); + SWPS_INFO("Dump: :%d :%d :%d :%d\n", + self->state, self->type, d_state, d_type); + } + return EVENT_TRANSVR_INIT_FAIL; + +initer_err_case_alarm_to_user: + SWPS_DEBUG("%s: %s :%s :alarm_to_user\n", + __func__, emsg, self->swp_name); + self->state = STATE_TRANSVR_UNEXCEPTED; + alarm_msg_2_user(self, "detected transceiver/cables not meet SFF standard"); + return EVENT_TRANSVR_INIT_FAIL; +} + + +/* ========== Object functions for Clean procedure ========== + */ +int +_transvr_clean_handler(struct transvr_obj_s *self){ + + int retval = DEBUG_TRANSVR_INT_VAL; + + if (!self->clean) { + SWPS_ERR("%s: %s clean() is NULL.\n", + __func__, self->swp_name); + return EVENT_TRANSVR_TASK_FAIL; + } + retval = self->clean(self); + if (retval != EVENT_TRANSVR_TASK_DONE){ + SWPS_ERR("%s: %s clean() fail. [ERR]:%d\n", + __func__, self->swp_name, retval); + return retval; + } + return EVENT_TRANSVR_TASK_DONE; +} + + +int +common_transvr_clean(struct transvr_obj_s *self){ + + transvr_task_free_all(self); + transvr_cache_free_all(self); + return EVENT_TRANSVR_TASK_DONE; +} + + +int +qsfp_transvr_clean(struct transvr_obj_s *self){ + + int retval; + int lpower_config = 1; + + retval = _taskfunc_qsfp_setup_power_mod(self, lpower_config); + if (retval < 0){ + SWPS_ERR("%s: Set lpmod fail! :%d\n", + __func__, retval); + return retval; + } + retval = common_transvr_clean(self); + if (retval < 0){ + SWPS_ERR("%s: common_transvr_clean fail! :%d\n", + __func__, retval); + return retval; + } + return EVENT_TRANSVR_TASK_DONE; +} + + +int +fake_transvr_clean(struct transvr_obj_s *self){ + + return EVENT_TRANSVR_TASK_DONE; +} + + +/* ========== Object functions for check and update ========== + */ +int +common_transvr_check(struct transvr_obj_s *self){ + + char fun_str[32] = "common_transvr_check"; + + if (self->mode != TRANSVR_MODE_POLLING) { + SWPS_ERR("%s: mode:%d is not TRANSVR_MODE_POLLING\n", + fun_str, self->mode); + return ERR_TRANSVR_UNEXCPT; + } + /* Trigger delay task */ + transvr_task_run_all(self); + /* Trigger state machine to check and update */ + return self->fsm_4_polling(self, fun_str); +} + + +int +fake_transvr_check(struct transvr_obj_s *self){ + return 0; +} + + +/* ========== Functions for Factory pattern ========== + */ +static int +setup_transvr_public_cb(struct transvr_obj_s *self, + int transvr_type){ + switch (transvr_type){ + case TRANSVR_TYPE_SFP: + self->get_id = common_get_id; + self->get_ext_id = common_get_ext_id; + self->get_connector = common_get_connector; + self->get_vendor_name = common_get_vendor_name; + self->get_vendor_pn = common_get_vendor_pn; + self->get_vendor_rev = common_get_vendor_rev; + self->get_vendor_sn = common_get_vendor_sn; + self->get_power_cls = unsupported_get_func; + self->get_br = common_get_br; + self->get_len_sm = sfp_get_len_sm; + self->get_len_smf = common_get_len_smf; + self->get_len_om1 = common_get_len_om1; + self->get_len_om2 = common_get_len_om2; + self->get_len_om3 = common_get_len_om3; + self->get_len_om4 = common_get_len_om4; + self->get_comp_rev = common_get_comp_rev; + self->get_comp_eth_1 = sfp_get_comp_eth_1; + self->get_comp_eth_10 = sfp_get_comp_eth_10; + self->get_comp_eth_10_40 = unsupported_get_func; + self->get_comp_extend = common_get_comp_extended; + self->get_cdr = unsupported_get_func; + self->get_rate_id = sfp_get_rate_id; + self->get_soft_rs0 = sfp_get_soft_rs0; + self->get_soft_rs1 = sfp_get_soft_rs1; + self->get_info = common_get_info; + self->get_if_type = sfp_get_if_type; + self->get_if_speed = sfp_get_if_speed; + self->get_if_lane = common_get_if_lane; + self->get_curr_temp = sfp_get_transvr_temp; + self->get_curr_vol = sfp_get_transvr_voltage; + self->get_soft_rx_los = unsupported_get_func2; + self->get_soft_tx_disable = unsupported_get_func2; + self->get_soft_tx_fault = unsupported_get_func2; + self->get_auto_tx_disable = unsupported_get_func2; + self->get_tx_bias = sfp_get_transvr_tx_bias; + self->get_tx_power = sfp_get_transvr_tx_power; + self->get_rx_power = sfp_get_transvr_rx_power; + self->get_tx_eq = sfp_get_transvr_tx_eq; + self->get_rx_am = unsupported_get_func2; + self->get_rx_em = sfp_get_transvr_rx_em; + self->get_wavelength = sfp_get_wavelength; + self->get_extphy_offset = sfp_get_1g_rj45_extphy_offset; + self->get_extphy_reg = sfp_get_1g_rj45_extphy_reg; + self->set_cdr = unsupported_set_func; + self->set_soft_rs0 = sfp_set_soft_rs0; + self->set_soft_rs1 = sfp_set_soft_rs1; + self->set_soft_tx_disable = unsupported_set_func; + self->set_auto_tx_disable = unsupported_set_func; + self->set_tx_eq = sfp_set_tx_eq; + self->set_rx_am = unsupported_set_func; + self->set_rx_em = sfp_set_rx_em; + self->set_extphy_offset = sfp_set_1g_rj45_extphy_offset; + self->set_extphy_reg = sfp_set_1g_rj45_extphy_reg; + return 0; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + self->get_id = common_get_id; + self->get_ext_id = common_get_ext_id; + self->get_connector = common_get_connector; + self->get_vendor_name = common_get_vendor_name; + self->get_vendor_pn = common_get_vendor_pn; + self->get_vendor_rev = common_get_vendor_rev; + self->get_vendor_sn = common_get_vendor_sn; + self->get_power_cls = qsfp_get_power_cls; + self->get_br = common_get_br; + self->get_len_sm = unsupported_get_func; + self->get_len_smf = common_get_len_smf; + self->get_len_om1 = common_get_len_om1; + self->get_len_om2 = common_get_len_om2; + self->get_len_om3 = common_get_len_om3; + self->get_len_om4 = common_get_len_om4; + self->get_comp_rev = common_get_comp_rev; + self->get_comp_eth_1 = qsfp_get_comp_eth; + self->get_comp_eth_10 = unsupported_get_func; + self->get_comp_eth_10_40 = qsfp_get_comp_10_40; + self->get_comp_extend = common_get_comp_extended; + self->get_cdr = unsupported_get_func; + self->get_rate_id = unsupported_get_func; + self->get_soft_rs0 = unsupported_get_func; /* TBD */ + self->get_soft_rs1 = unsupported_get_func; /* TBD */ + self->get_info = common_get_info; + self->get_if_type = qsfp_get_if_type; + self->get_if_speed = qsfp_get_if_speed; + self->get_if_lane = common_get_if_lane; + self->get_curr_temp = qsfp_get_transvr_temp; + self->get_curr_vol = qsfp_get_transvr_voltage; + self->get_soft_rx_los = qsfp_get_soft_rx_los; + self->get_soft_tx_disable = qsfp_get_soft_tx_disable; + self->get_soft_tx_fault = qsfp_get_soft_tx_fault; + self->get_auto_tx_disable = qsfp_get_auto_tx_disable; + self->get_tx_bias = qsfp_get_transvr_tx_bias; + self->get_tx_power = qsfp_get_transvr_tx_power; + self->get_rx_power = qsfp_get_transvr_rx_power; + self->get_tx_eq = unsupported_get_func2; + self->get_rx_am = unsupported_get_func2; + self->get_rx_em = unsupported_get_func2; + self->get_wavelength = qsfp_get_wavelength; + self->get_extphy_offset = unsupported_get_func2; + self->get_extphy_reg = unsupported_get_func2; + self->set_cdr = unsupported_set_func; + self->set_soft_rs0 = unsupported_set_func; /* TBD */ + self->set_soft_rs1 = unsupported_set_func; /* TBD */ + self->set_soft_tx_disable = qsfp_set_soft_tx_disable; + self->set_auto_tx_disable = qsfp_set_auto_tx_disable; + self->set_tx_eq = unsupported_set_func; + self->set_rx_am = unsupported_set_func; + self->set_rx_em = unsupported_set_func; + self->set_extphy_offset = unsupported_set_func; + self->set_extphy_reg = unsupported_set_func; + return 0; + + case TRANSVR_TYPE_QSFP_28: + self->get_id = common_get_id; + self->get_ext_id = common_get_ext_id; + self->get_connector = common_get_connector; + self->get_vendor_name = common_get_vendor_name; + self->get_vendor_pn = common_get_vendor_pn; + self->get_vendor_rev = common_get_vendor_rev; + self->get_vendor_sn = common_get_vendor_sn; + self->get_power_cls = qsfp_get_power_cls; + self->get_br = common_get_br; + self->get_len_sm = unsupported_get_func; + self->get_len_smf = common_get_len_smf; + self->get_len_om1 = common_get_len_om1; + self->get_len_om2 = common_get_len_om2; + self->get_len_om3 = common_get_len_om3; + self->get_len_om4 = common_get_len_om4; + self->get_comp_rev = common_get_comp_rev; + self->get_comp_eth_1 = qsfp_get_comp_eth; + self->get_comp_eth_10 = unsupported_get_func; + self->get_comp_eth_10_40 = qsfp_get_comp_10_40; + self->get_comp_extend = common_get_comp_extended; + self->get_cdr = qsfp_get_cdr; + self->get_rate_id = unsupported_get_func; + self->get_soft_rs0 = unsupported_get_func; /* TBD */ + self->get_soft_rs1 = unsupported_get_func; /* TBD */ + self->get_info = common_get_info; + self->get_if_type = qsfp_get_if_type; + self->get_if_speed = qsfp_get_if_speed; + self->get_if_lane = common_get_if_lane; + self->get_curr_temp = qsfp_get_transvr_temp; + self->get_curr_vol = qsfp_get_transvr_voltage; + self->get_soft_rx_los = qsfp_get_soft_rx_los; + self->get_soft_tx_disable = qsfp_get_soft_tx_disable; + self->get_soft_tx_fault = qsfp_get_soft_tx_fault; + self->get_auto_tx_disable = qsfp_get_auto_tx_disable; + self->get_tx_bias = qsfp_get_transvr_tx_bias; + self->get_tx_power = qsfp_get_transvr_tx_power; + self->get_rx_power = qsfp_get_transvr_rx_power; + self->get_tx_eq = qsfp_get_transvr_tx_eq; + self->get_rx_am = qsfp_get_transvr_rx_am; + self->get_rx_em = qsfp_get_transvr_rx_em; + self->get_wavelength = qsfp_get_wavelength; + self->get_extphy_offset = unsupported_get_func2; + self->get_extphy_reg = unsupported_get_func2; + self->set_cdr = qsfp_set_cdr; + self->set_soft_rs0 = unsupported_set_func; /* TBD */ + self->set_soft_rs1 = unsupported_set_func; /* TBD */ + self->set_soft_tx_disable = qsfp_set_soft_tx_disable; + self->set_auto_tx_disable = qsfp_set_auto_tx_disable; + self->set_tx_eq = qsfp_set_tx_eq; + self->set_rx_am = qsfp_set_rx_am; + self->set_rx_em = qsfp_set_rx_em; + self->set_extphy_offset = unsupported_set_func; + self->set_extphy_reg = unsupported_set_func; + return 0; + + case TRANSVR_TYPE_FAKE: + self->get_id = fake_get_hex; + self->get_ext_id = fake_get_hex; + self->get_connector = fake_get_hex; + self->get_vendor_name = fake_get_str; + self->get_vendor_pn = fake_get_str; + self->get_vendor_rev = fake_get_str; + self->get_vendor_sn = fake_get_str; + self->get_power_cls = fake_get_int; + self->get_br = fake_get_hex; + self->get_len_sm = fake_get_int; + self->get_len_smf = fake_get_int; + self->get_len_om1 = fake_get_int; + self->get_len_om2 = fake_get_int; + self->get_len_om3 = fake_get_int; + self->get_len_om4 = fake_get_int; + self->get_comp_rev = fake_get_hex; + self->get_comp_eth_1 = fake_get_hex; + self->get_comp_eth_10 = fake_get_hex; + self->get_comp_eth_10_40 = fake_get_hex; + self->get_comp_extend = fake_get_hex; + self->get_cdr = fake_get_hex; + self->get_rate_id = fake_get_hex; + self->get_soft_rs0 = fake_get_binary; + self->get_soft_rs1 = fake_get_binary; + self->get_info = fake_get_int; + self->get_if_type = fake_get_str; + self->get_if_speed = fake_get_str; + self->get_if_lane = fake_get_str; + self->get_curr_temp = fake_get_str; + self->get_curr_vol = fake_get_str; + self->get_soft_rx_los = fake_get_str; + self->get_soft_tx_disable = fake_get_str; + self->get_soft_tx_fault = fake_get_str; + self->get_auto_tx_disable = fake_get_str; + self->get_tx_bias = fake_get_str; + self->get_tx_power = fake_get_str; + self->get_rx_power = fake_get_str; + self->get_tx_eq = fake_get_str; + self->get_rx_am = fake_get_str; + self->get_rx_em = fake_get_str; + self->get_wavelength = fake_get_str; + self->get_extphy_offset = fake_get_str; + self->get_extphy_reg = fake_get_str; + self->set_cdr = fake_set_hex; + self->set_soft_rs0 = fake_set_int; + self->set_soft_rs1 = fake_set_int; + self->set_soft_tx_disable = fake_set_int; + self->set_auto_tx_disable = fake_set_int; + self->set_tx_eq = fake_set_int; + self->set_rx_am = fake_set_int; + self->set_rx_em = fake_set_int; + self->set_extphy_offset = fake_set_hex; + self->set_extphy_reg = fake_set_hex; + return 0; + + default: + break; + } + SWPS_WARN("%s: Detect non-defined type:%d\n", __func__, transvr_type); + return ERR_TRANSVR_UNEXCPT; +} + + +static int +setup_transvr_private_cb(struct transvr_obj_s *self, + int transvr_type){ + switch (transvr_type){ + case TRANSVR_TYPE_SFP: + self->init = transvr_init_sfp; + self->clean = common_transvr_clean; + self->check = common_transvr_check; + self->update_all = _sfp_update_attr_all; + self->fsm_4_direct = common_fsm_4_direct_mode; + self->fsm_4_polling = common_fsm_4_polling_mode; + self->send_uevent = sfp_send_uevent; + self->dump_all = sfp_transvr_dump; + return 0; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + self->init = transvr_init_qsfp; + self->clean = qsfp_transvr_clean; + self->check = common_transvr_check; + self->update_all = _qsfp_update_attr_all; + self->fsm_4_direct = common_fsm_4_direct_mode; + self->fsm_4_polling = common_fsm_4_polling_mode; + self->send_uevent = qsfp_send_uevent; + self->dump_all = qsfp_transvr_dump; + return 0; + + case TRANSVR_TYPE_QSFP_28: + self->init = transvr_init_qsfp28; + self->clean = qsfp_transvr_clean; + self->check = common_transvr_check; + self->update_all = _qsfp_update_attr_all; + self->fsm_4_direct = common_fsm_4_direct_mode; + self->fsm_4_polling = common_fsm_4_polling_mode; + self->send_uevent = qsfp_send_uevent; + self->dump_all = qsfp_transvr_dump; + return 0; + + case TRANSVR_TYPE_FAKE: + self->init = transvr_init_fake; + self->clean = fake_transvr_clean; + self->check = fake_transvr_check; + self->update_all = fake_transvr_update; + self->fsm_4_direct = fake_fsm_4_direct_mode; + self->fsm_4_polling = fake_fsm_4_polling_mode; + self->send_uevent = fake_send_uevent; + self->dump_all = fake_transvr_dump; + return 0; + + default: + break; + } + SWPS_WARN("%s: Detect non-defined type:%d\n", __func__, transvr_type); + return ERR_TRANSVR_UNEXCPT; +} + + +static struct eeprom_map_s * +get_eeprom_map(int transvr_type){ + + switch (transvr_type){ + case TRANSVR_TYPE_SFP: + return &eeprom_map_sfp; + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + return &eeprom_map_qsfp; + case TRANSVR_TYPE_QSFP_28: + return &eeprom_map_qsfp28; + + default: + break; + } + SWPS_WARN("%s: Detect non-defined type:%d\n", __func__, transvr_type); + return NULL; +} + + +static int +setup_transvr_ssize_attr(char *swp_name, + struct transvr_obj_s *self, + struct eeprom_map_s *map_p, + struct ioexp_obj_s *ioexp_obj_p, + int ioexp_virt_offset, + int transvr_type, + int chipset_type, + int chan_id, + int run_mode){ + switch (run_mode){ + case TRANSVR_MODE_DIRECT: /* Direct access device mode */ + case TRANSVR_MODE_POLLING: /* Polling mode, read from cache */ + self->mode = run_mode; + break; + default: + SWPS_ERR("%s: non-defined run_mode:%d\n", + __func__, run_mode); + self->mode = DEBUG_TRANSVR_INT_VAL; + return -1; + } + self->eeprom_map_p = map_p; + self->ioexp_obj_p = ioexp_obj_p; + self->ioexp_virt_offset = ioexp_virt_offset; + self->chan_id = chan_id; + self->layout = transvr_type; + self->type = transvr_type; + self->chipset_type = chipset_type; + self->state = STATE_TRANSVR_NEW; + self->info = STATE_TRANSVR_NEW; + self->auto_tx_disable = VAL_TRANSVR_FUNCTION_DISABLE; + strncpy(self->swp_name, swp_name, 32); + mutex_init(&self->lock); + return 0; +} + + +static int +setup_transvr_dsize_attr(struct transvr_obj_s *self){ + + char *emsg = DEBUG_TRANSVR_STR_VAL; + + self->vendor_name = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_name){ + emsg = "vendor_name"; + goto err_setup_d_attr; + } + self->vendor_pn = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_pn){ + emsg = "vendor_pn"; + goto err_setup_d_attr; + } + self->vendor_rev = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_rev){ + emsg = "vendor_rev"; + goto err_setup_d_attr; + } + self->vendor_sn = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_sn){ + emsg = "vendor_sn"; + goto err_setup_d_attr; + } + self->worker_p = NULL; + return 0; + +err_setup_d_attr: + SWPS_ERR("%s: %s kzalloc fail!", __func__, emsg); + return ERR_TRANSVR_UNEXCPT; +} + + +static int +setup_i2c_client(struct transvr_obj_s *self){ + + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + adap = i2c_get_adapter(self->chan_id); + if(!adap){ + snprintf(err_msg, sizeof(err_msg), + "can not get adap:%d", self->chan_id); + goto err_setup_i2c_client; + } + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client){ + snprintf(err_msg, sizeof(err_msg), + "can not kzalloc client:%d", self->chan_id); + goto err_setup_i2c_client; + } + client->adapter = adap; + self->i2c_client_p = client; + self->i2c_client_p->addr = VAL_TRANSVR_COMID_ARREESS; + return 0; + +err_setup_i2c_client: + SWPS_ERR("%s: %s\n", __func__, err_msg); + return ERR_TRANSVR_UNEXCPT; +} + + +struct transvr_obj_s * +create_transvr_obj(char *swp_name, + int chan_id, + struct ioexp_obj_s *ioexp_obj_p, + int ioexp_virt_offset, + int transvr_type, + int chipset_type, + int run_mode){ + + struct transvr_obj_s *result_p; + struct eeprom_map_s *map_p; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Allocate transceiver object */ + map_p = get_eeprom_map(transvr_type); + if (!map_p){ + snprintf(err_msg, sizeof(err_msg), + "Invalid transvr_type:%d", transvr_type); + goto err_create_transvr_fail; + } + result_p = kzalloc(sizeof(*result_p), GFP_KERNEL); + if (!result_p){ + snprintf(err_msg, sizeof(err_msg), "kzalloc fail"); + goto err_create_transvr_fail; + } + /* Prepare static size attributes */ + if (setup_transvr_ssize_attr(swp_name, + result_p, + map_p, + ioexp_obj_p, + ioexp_virt_offset, + transvr_type, + chipset_type, + chan_id, + run_mode) < 0){ + goto err_create_transvr_sattr_fail; + } + /* Prepare dynamic size attributes */ + if (setup_transvr_dsize_attr(result_p) < 0){ + goto err_create_transvr_dattr_fail; + } + /* Prepare call back functions of object */ + if (setup_transvr_public_cb(result_p, transvr_type) < 0){ + goto err_create_transvr_dattr_fail; + } + /* Prepare call back functions of object */ + if (setup_transvr_private_cb(result_p, transvr_type) < 0){ + goto err_create_transvr_dattr_fail; + } + /* Prepare i2c client object */ + if (setup_i2c_client(result_p) < 0){ + goto err_create_transvr_dattr_fail; + } + return result_p; + +err_create_transvr_dattr_fail: + kfree(result_p->vendor_sn); + kfree(result_p->vendor_rev); + kfree(result_p->vendor_pn); + kfree(result_p->vendor_name); +err_create_transvr_sattr_fail: + kfree(result_p); +err_create_transvr_fail: + SWPS_ERR("%s: %s :%d :%d :%d\n", + __func__, err_msg, chan_id, ioexp_virt_offset, transvr_type); + return NULL; +} +EXPORT_SYMBOL(create_transvr_obj); + + +static int +_reload_transvr_obj(struct transvr_obj_s *self, + int new_type){ + + struct eeprom_map_s *new_map_p; + struct eeprom_map_s *old_map_p = self->eeprom_map_p; + struct i2c_client *old_i2c_p = self->i2c_client_p; + int old_type = self->type; + + /* Change state to STATE_TRANSVR_INIT */ + self->state = STATE_TRANSVR_INIT; + self->type = new_type; + /* Replace EEPROME map */ + new_map_p = get_eeprom_map(new_type); + if (!new_map_p){ + goto err_private_reload_func_1; + } + self->eeprom_map_p = new_map_p; + /* Reload i2c client */ + if (setup_i2c_client(self) < 0){ + goto err_private_reload_func_2; + } + /* Replace call back functions */ + if (setup_transvr_public_cb(self, new_type) < 0){ + goto err_private_reload_func_3; + } + if (setup_transvr_private_cb(self, new_type) < 0){ + goto err_private_reload_func_3; + } + if(old_i2c_p){ + i2c_put_adapter(old_i2c_p->adapter); + } + kfree(old_i2c_p); + return 0; + +err_private_reload_func_3: + SWPS_INFO("%s: init() fail!\n", __func__); + if(old_i2c_p){ + i2c_put_adapter(old_i2c_p->adapter); + } + kfree(old_i2c_p); + self->state = STATE_TRANSVR_UNEXCEPTED; + self->type = TRANSVR_TYPE_ERROR; + return -2; + +err_private_reload_func_2: + self->eeprom_map_p = old_map_p; + self->i2c_client_p = old_i2c_p; +err_private_reload_func_1: + self->state = STATE_TRANSVR_UNEXCEPTED; + self->type = old_type; + SWPS_INFO("%s fail! :0x%02x\n", __func__, new_type); + return -1; +} + + +static int +reload_transvr_obj(struct transvr_obj_s *self, + int new_type){ + + int result_val = ERR_TRANSVR_UNEXCPT; + + /* Reload phase */ + result_val = _reload_transvr_obj(self, new_type); + if (result_val < 0){ + SWPS_INFO("%s: reload phase fail! :%d\n", + __func__, result_val); + return EVENT_TRANSVR_RELOAD_FAIL; + } + /* Initial phase */ + result_val = _transvr_init_handler(self); + if (result_val < 0){ + SWPS_INFO("%s: initial phase fail! :%d\n", + __func__, result_val); + } + return result_val; +} + + +int +isolate_transvr_obj(struct transvr_obj_s *self) { + + self->state = STATE_TRANSVR_ISOLATED; + SWPS_INFO("%s: %s be isolated\n", __func__, self->swp_name); + return 0; +} +EXPORT_SYMBOL(isolate_transvr_obj); + + +int +resync_channel_tier_2(struct transvr_obj_s *self) { + + int val = TRANSVR_TYPE_ERROR; + + if (self->state == STATE_TRANSVR_ISOLATED) { + return 0; + } + self->i2c_client_p->addr = VAL_TRANSVR_COMID_ARREESS; + val = i2c_smbus_read_byte_data(self->i2c_client_p, + VAL_TRANSVR_COMID_OFFSET); + if (val < 0) { + return -1; + } + return 0; +} +EXPORT_SYMBOL(resync_channel_tier_2); + +/* For build single module using (Ex: ONL platform) */ +MODULE_LICENSE("GPL"); + + +/* ----------------------------------------- + * ToDo List + * ----------------------------------------- + * 1. _sfp_detect_class_by_feature() + * => Need check ACC use case. + * 2. _sfp_detect_class_by_1g_ethernet() + * => Need check 0.1G use case. + * 3. Loopback transceiver use case. + * => Less much data + * 4. _qsfp_detect_class_by_extend_comp() + * => Verify 100G CWDM4 + * => Verify Obsolete (assigned before 100G CWDM4 MSA required FEC) + * => Verify 100G CLR4 + * => Verify 100GE-DWDM2 + * => Verify 40G PSM4 Parallel SMF + * => Verify 100G ACC (Active Copper Cable) or 25GAUI C2M ACC. + * => Verify 100G ACC or 25GAUI C2M ACC. + * => Verify 25GBASE-LR + * => Verify 40G Active Cable (XLPPI) + */ + + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.h b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.h new file mode 100644 index 000000000000..a2a503402142 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.h @@ -0,0 +1,804 @@ +#ifndef TRANSCEIVER_H +#define TRANSCEIVER_H + +#include + +/* advanced features control */ +#define TRANSVR_INFO_DUMP_ENABLE (1) +#define TRANSVR_INFO_CACHE_ENABLE (1) +#define TRANSVR_UEVENT_ENABLE (1) + +/* Transceiver type define */ +#define TRANSVR_TYPE_UNKNOW_1 (0x00) +#define TRANSVR_TYPE_UNKNOW_2 (0xff) +#define TRANSVR_TYPE_SFP (0x03) /* Define for SFP, SFP+, SFP28 */ +#define TRANSVR_TYPE_QSFP (0x0c) +#define TRANSVR_TYPE_QSFP_PLUS (0x0d) +#define TRANSVR_TYPE_QSFP_28 (0x11) +#define TRANSVR_TYPE_UNPLUGGED (0xfa) /* Define for ERROR handle */ +#define TRANSVR_TYPE_FAKE (0xfc) /* Define for ERROR handle */ +#define TRANSVR_TYPE_INCONSISTENT (0xfd) /* Define for ERROR handle */ +#define TRANSVR_TYPE_ERROR (0xfe) /* Define for ERROR handle */ + +/* Transceiver class for base info */ +#define TRANSVR_CLASS_UNSPECIFIED (0) +#define TRANSVR_CLASS_ERROR (-26001) +#define TRANSVR_CLASS_1G (26001) +#define TRANSVR_CLASS_10G (26011) +#define TRANSVR_CLASS_25G (26021) +#define TRANSVR_CLASS_40G (26041) +#define TRANSVR_CLASS_100G (26101) +#define TRANSVR_CLASS_NO_SPERARABLE (26901) +#define TRANSVR_CLASS_EXTEND_COMP (26902) +/* Transceiver class for Optical 1G */ +#define TRANSVR_CLASS_OPTICAL (27000) +#define TRANSVR_CLASS_OPTICAL_100 (27001) +#define TRANSVR_CLASS_OPTICAL_1G (27002) +#define TRANSVR_CLASS_OPTICAL_1G_AOC (27003) +#define TRANSVR_CLASS_OPTICAL_1G_SX (27004) +#define TRANSVR_CLASS_OPTICAL_1G_LX (27005) +#define TRANSVR_CLASS_OPTICAL_1G_EX (27006) +/* Transceiver class for Optical 10G */ +#define TRANSVR_CLASS_OPTICAL_10G (27010) +#define TRANSVR_CLASS_OPTICAL_10G_S_AOC (27011) +#define TRANSVR_CLASS_OPTICAL_10G_S_SR (27012) +#define TRANSVR_CLASS_OPTICAL_10G_S_LR (27013) +#define TRANSVR_CLASS_OPTICAL_10G_S_ER (27014) +#define TRANSVR_CLASS_OPTICAL_10G_Q_AOC (27015) +#define TRANSVR_CLASS_OPTICAL_10G_Q_SR (27016) +#define TRANSVR_CLASS_OPTICAL_10G_Q_LR (27017) +#define TRANSVR_CLASS_OPTICAL_10G_Q_ER (27018) +/* Transceiver class for Optical 25G */ +#define TRANSVR_CLASS_OPTICAL_25G (27020) +#define TRANSVR_CLASS_OPTICAL_25G_AOC (27021) +#define TRANSVR_CLASS_OPTICAL_25G_SR (27022) +#define TRANSVR_CLASS_OPTICAL_25G_LR (27023) +#define TRANSVR_CLASS_OPTICAL_25G_ER (27024) +/* Transceiver class for Optical 40G */ +#define TRANSVR_CLASS_OPTICAL_40G (27040) +#define TRANSVR_CLASS_OPTICAL_40G_AOC (27041) +#define TRANSVR_CLASS_OPTICAL_40G_SR4 (27042) +#define TRANSVR_CLASS_OPTICAL_40G_LR4 (27043) +#define TRANSVR_CLASS_OPTICAL_40G_ER4 (27044) +/* Transceiver class for Optical 100G */ +#define TRANSVR_CLASS_OPTICAL_100G (27100) +#define TRANSVR_CLASS_OPTICAL_100G_AOC (27101) +#define TRANSVR_CLASS_OPTICAL_100G_SR4 (27102) +#define TRANSVR_CLASS_OPTICAL_100G_LR4 (27103) +#define TRANSVR_CLASS_OPTICAL_100G_ER4 (27104) +#define TRANSVR_CLASS_OPTICAL_100G_PSM4 (27105) +/* Transceiver class for Copper */ +#define TRANSVR_CLASS_COPPER (28000) +#define TRANSVR_CLASS_COPPER_L1_1G (28001) +#define TRANSVR_CLASS_COPPER_L1_10G (28011) +#define TRANSVR_CLASS_COPPER_L4_10G (28012) +#define TRANSVR_CLASS_COPPER_L1_25G (28021) +#define TRANSVR_CLASS_COPPER_L4_40G (28041) +#define TRANSVR_CLASS_COPPER_L4_100G (28101) +/* Transceiver class for Base-T */ +#define TRANSVR_CLASS_BASE_T_1000 (29001) +#define TRANSVR_CLASS_BASE_T_1000_up (29002) +/* For uevent message */ +#define TRANSVR_UEVENT_KEY_IF "IF_TYPE" +#define TRANSVR_UEVENT_KEY_SP "IF_SPEED" +#define TRANSVR_UEVENT_KEY_LANE "IF_LANE" +#define TRANSVR_UEVENT_UNKNOW "UNKNOW" +#define TRANSVR_IF_KR "KR" +#define TRANSVR_IF_KR4 "KR4" +#define TRANSVR_IF_SR "SR" +#define TRANSVR_IF_SR4 "SR4" +#define TRANSVR_IF_SFI "SFI" +#define TRANSVR_IF_IF_GMII "GMII" +#define TRANSVR_IF_IF_XGMII "XGMII" +#define TRANSVR_IF_SP_100 "100" +#define TRANSVR_IF_SP_1G "1000" +#define TRANSVR_IF_SP_10G "10000" +#define TRANSVR_IF_SP_25G "25000" +#define TRANSVR_IF_SP_40G "40000" +#define TRANSVR_IF_SP_100G "100000" + +/* Transceiver mode define */ +#define TRANSVR_MODE_DIRECT (21000) +#define TRANSVR_MODE_POLLING (21001) + +/* Transceiver state define + * [Note] + * 1. State is used to represent the state of "Transceiver" and "Object". + * 2. State for different target has different means. The description as following: + */ +#define STATE_TRANSVR_CONNECTED (0) /* [Transvr]:Be plugged in. [Obj]:Link up, and work normally. */ +#define STATE_TRANSVR_NEW (-100) /* [Transvr]:(Not used) [Obj]:Create */ +#define STATE_TRANSVR_INIT (-101) /* [Transvr]:Be plugged in. [Obj]:Link up, and in initial process. */ +#define STATE_TRANSVR_ISOLATED (-102) /* [Transvr]:Be plugged in. [Obj]:Isolate, and not provide service. */ +#define STATE_TRANSVR_SWAPPED (-200) /* [Transvr]:Be plugged in. [Obj]:(Not used) */ +#define STATE_TRANSVR_DISCONNECTED (-300) /* [Transvr]:Un-plugged. [Obj]:Link down, and not provide service. */ +#define STATE_TRANSVR_UNEXCEPTED (-901) /* [Transvr]:Any [Obj]:Any, and not in expect case. */ + +/* Task state define */ +#define STATE_T_TASK_WAIT (110) +#define STATE_T_TASK_DONE (0) +#define STATE_T_TASK_INIT (-110) +#define STATE_T_TASK_FAIL (-410) + + +/* Event for task handling */ +#define EVENT_TRANSVR_TASK_WAIT (2101) +#define EVENT_TRANSVR_TASK_DONE (0) +#define EVENT_TRANSVR_TASK_FAIL (-2101) +/* Event for initial handling */ +#define EVENT_TRANSVR_INIT_UP (2201) +#define EVENT_TRANSVR_INIT_DOWN (1) +#define EVENT_TRANSVR_INIT_REINIT (-2201) +#define EVENT_TRANSVR_INIT_FAIL (-2202) +/* Event for others */ +#define EVENT_TRANSVR_RELOAD_FAIL (-2301) +#define EVENT_TRANSVR_EXCEP_INIT (-2401) +#define EVENT_TRANSVR_EXCEP_UP (-2402) +#define EVENT_TRANSVR_EXCEP_DOWN (-2403) +#define EVENT_TRANSVR_EXCEP_SWAP (-2404) +#define EVENT_TRANSVR_EXCEP_EXCEP (-2405) +#define EVENT_TRANSVR_EXCEP_ISOLATED (-2406) +#define EVENT_TRANSVR_I2C_CRASH (-2501) + +/* Transceiver error code define */ +#define ERR_TRANSVR_UNINIT (-201) +#define ERR_TRANSVR_UNPLUGGED (-202) +#define ERR_TRANSVR_ABNORMAL (-203) +#define ERR_TRANSVR_NOSTATE (-204) +#define ERR_TRANSVR_NOTSUPPORT (-205) +#define ERR_TRANSVR_BADINPUT (-206) +#define ERR_TRANSVR_UPDATE_FAIL (-207) +#define ERR_TRANSVR_RELOAD_FAIL (-208) +#define ERR_TRANSVR_INIT_FAIL (-209) +#define ERR_TRANSVR_UNDEFINED (-210) +#define ERR_TRANSVR_TASK_FAIL (-211) +#define ERR_TRANSVR_TASK_BUSY (-212) +#define ERR_TRANSVR_UEVENT_FAIL (-213) +#define ERR_TRANSVR_FUNC_DISABLE (-214) +#define ERR_TRANSVR_I2C_CRASH (-297) +#define ERR_TRNASVR_BE_ISOLATED (-298) +#define ERR_TRANSVR_UNEXCPT (-299) + +/* For debug */ +#define DEBUG_TRANSVR_INT_VAL (-99) +#define DEBUG_TRANSVR_HEX_VAL (0xfe) +#define DEBUG_TRANSVR_STR_VAL "ERROR" + +/* For system internal */ +#define VAL_TRANSVR_COMID_ARREESS (0x50) +#define VAL_TRANSVR_COMID_OFFSET (0x00) +#define VAL_TRANSVR_EXTPHY_ADDR_56 (0x56) +#define VAL_TRANSVR_8472_READY_ADDR (0x51) +#define VAL_TRANSVR_8472_READY_PAGE (-1) +#define VAL_TRANSVR_8472_READY_OFFSET (110) +#define VAL_TRANSVR_8472_READY_BIT (0) +#define VAL_TRANSVR_8472_READY_VALUE (0) +#define VAL_TRANSVR_8472_READY_ABNORMAL (0xff) +#define VAL_TRANSVR_8436_READY_ADDR (0x50) +#define VAL_TRANSVR_8436_READY_PAGE (-1) +#define VAL_TRANSVR_8436_READY_OFFSET (2) +#define VAL_TRANSVR_8436_READY_BIT (0) +#define VAL_TRANSVR_8436_READY_VALUE (0) +#define VAL_TRANSVR_8436_READY_ABNORMAL (0xff) +#define VAL_TRANSVR_8436_PWD_ADDR (0x50) +#define VAL_TRANSVR_8436_PWD_PAGE (-1) +#define VAL_TRANSVR_8436_PWD_OFFSET (123) +#define VAL_TRANSVR_PAGE_FREE (-99) +#define VAL_TRANSVR_PAGE_SELECT_OFFSET (127) +#define VAL_TRANSVR_PAGE_SELECT_DELAY (5) +#define VAL_TRANSVR_TASK_RETRY_FOREVER (-999) +#define VAL_TRANSVR_FUNCTION_DISABLE (-1) +#define STR_TRANSVR_SFP "SFP" +#define STR_TRANSVR_QSFP "QSFP" +#define STR_TRANSVR_QSFP_PLUS "QSFP+" +#define STR_TRANSVR_QSFP28 "QSFP28" + +/* For transvr buf len */ +#define LEN_TRANSVR_S_STR (16) +#define LEN_TRANSVR_M_STR (32) +#define LEN_TRANSVR_L_STR (64) + +/* Optical wavelength */ +#define VAL_OPTICAL_WAVELENGTH_SR (850) +#define VAL_OPTICAL_WAVELENGTH_LR (1310) +#define VAL_OPTICAL_WAVELENGTH_ER (1550) + +/* Switch chip type define */ +#define CHIP_TYPE_MAGNOLIA (31001) /* Magnolia, Hudson32i, Spruce */ +#define CHIP_TYPE_REDWOOD (31002) /* Redwood, Cypress, Sequoia */ +#define CHIP_TYPE_MAPLE (31003) /* Maple */ + +#define CHIP_TYPE_LAVENDER (31011) /* Lavender */ + +/* Info from transceiver EEPROM */ +struct eeprom_map_s { + int addr_br; int page_br; int offset_br; int length_br; + int addr_cdr; int page_cdr; int offset_cdr; int length_cdr; + int addr_comp_rev; int page_comp_rev; int offset_comp_rev; int length_comp_rev; + int addr_connector; int page_connector; int offset_connector; int length_connector; + int addr_diag_type; int page_diag_type; int offset_diag_type; int length_diag_type; + int addr_extbr; int page_extbr; int offset_extbr; int length_extbr; + int addr_ext_id; int page_ext_id; int offset_ext_id; int length_ext_id; + int addr_id; int page_id; int offset_id; int length_id; + int addr_len_sm; int page_len_sm; int offset_len_sm; int length_len_sm; + int addr_len_smf; int page_len_smf; int offset_len_smf; int length_len_smf; + int addr_len_om1; int page_len_om1; int offset_len_om1; int length_len_om1; + int addr_len_om2; int page_len_om2; int offset_len_om2; int length_len_om2; + int addr_len_om3; int page_len_om3; int offset_len_om3; int length_len_om3; + int addr_len_om4; int page_len_om4; int offset_len_om4; int length_len_om4; + int addr_option; int page_option; int offset_option; int length_option; + int addr_rate_id; int page_rate_id; int offset_rate_id; int length_rate_id; + int addr_rx_am; int page_rx_am; int offset_rx_am; int length_rx_am; + int addr_rx_em; int page_rx_em; int offset_rx_em; int length_rx_em; + int addr_rx_los; int page_rx_los; int offset_rx_los; int length_rx_los; + int addr_rx_power; int page_rx_power; int offset_rx_power; int length_rx_power; + int addr_soft_rs0; int page_soft_rs0; int offset_soft_rs0; int length_soft_rs0; + int addr_soft_rs1; int page_soft_rs1; int offset_soft_rs1; int length_soft_rs1; + int addr_temp; int page_temp; int offset_temp; int length_temp; + int addr_trancomp; int page_trancomp; int offset_trancomp; int length_trancomp; + int addr_trancomp_ext; int page_trancomp_ext; int offset_trancomp_ext; int length_trancomp_ext; + int addr_tx_bias; int page_tx_bias; int offset_tx_bias; int length_tx_bias; + int addr_tx_disable; int page_tx_disable; int offset_tx_disable; int length_tx_disable; + int addr_tx_eq; int page_tx_eq; int offset_tx_eq; int length_tx_eq; + int addr_tx_fault; int page_tx_fault; int offset_tx_fault; int length_tx_fault; + int addr_tx_power; int page_tx_power; int offset_tx_power; int length_tx_power; + int addr_vendor_name; int page_vendor_name; int offset_vendor_name; int length_vendor_name; + int addr_vendor_pn; int page_vendor_pn; int offset_vendor_pn; int length_vendor_pn; + int addr_vendor_rev; int page_vendor_rev; int offset_vendor_rev; int length_vendor_rev; + int addr_vendor_sn; int page_vendor_sn; int offset_vendor_sn; int length_vendor_sn; + int addr_voltage; int page_voltage; int offset_voltage; int length_voltage; + int addr_wavelength; int page_wavelength; int offset_wavelength; int length_wavelength; +}; + + +struct transvr_worker_s; + +/* Class of transceiver object */ +struct transvr_obj_s { + + /* ========== Object private property ========== + * [Prop]: id + * [Desc]: Type of serial transceiver. + * [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh /QSFP28:11h + */ + uint8_t id; + + /* [Prop]: connector + * [Desc]: Connector type. + * [Note]: SFP : A0h / 2 + * QSFP: 00h / 130 + */ + uint8_t connector; + + /* [Prop]: transvr_comp + * [Desc]: Transceiver compliance code. + * [Note]: SFP: SFF-8472 + * - Normal : A0h / offset 3-10 + * - Extended: A0h / offset 36 + * QSFP: SFF-8436 & SFF-8636 + * - Normal : 00h / offset 131-138 + * - Extended: 00h / offset 192 + */ + uint8_t transvr_comp[8]; + uint8_t transvr_comp_ext; + + /* [Prop]: vendor_name + * [Desc]: SFP vendor name (ASCII 16 byte char). + * [Note]: ex:FINISAR CORP. + */ + char *vendor_name; + + /* [Prop]: vendor_pn + * [Desc]: Part number provided by SFP vendor (ASCII 16 byte char). + * [Note]: + */ + char *vendor_pn; + + /* [Prop]: vendor_rev + * [Desc]: Revision level for part number provided by vendor (ASCII 4 byte char). + * [Note]: + */ + char *vendor_rev; + + /* [Prop]: vendor_sn + * [Desc]: Serial number provided by vendor (ASCII 16 byte char). + * [Note]: + */ + char *vendor_sn; + + /* [Prop]: Extended identifier + * [Desc]: SFP: + * => None + * + * QSFP: + * => This byte contained two information: + * (1) Power consumption class + * (2) CDR function present + * [Note]: Bit description as below: + * [SFP] + * None + * + * [QSFP] + * (1) Power consumption class: + * Class 1: 1.5W (Bit6-7 = 00:) + * Class 2: 2.0W (Bit6-7 = 01:) + * Class 3: 2.5W (Bit6-7 = 10:) + * Class 4: 3.5W (Bit6-7 = 11:) + * Class 5: 4.0W (Bit0-1 = 01:) + * Class 6: 4.5W (Bit0-1 = 10:) + * Class 7: 5.0W (Bit0-1 = 11:) + * (2) CDR function present: + * Bit2: 0 = No CDR in RX + * 1 = CDR present in RX + * Bit3: 0 = No CDR in TX + * 1 = CDR present in TX + */ + uint8_t ext_id; + + /* [Prop]: br + * [Desc]: Nominal bit rate, units of 100 MBits/sec. + * [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh + * has val: 0x67 + * no val : + */ + uint8_t br; + + /* [Prop]: extbr + * [Desc]: Extended br (00h/222) + * [Desc]: Nominal bit rate per channel, units of 250 Mbps. + * Complements. Byte 140. See Table 32A. + */ + uint8_t extbr; + + /* [Prop]: len_sm + * [Desc]: Length (single mode)-(100's)m + * [Note]: This value specifies the link length that is supported by the transceiver + * while operating in compliance with the applicable standards using single mode + * fiber. The value is in units of 100 meters. A value of 255 means that the + * transceiver supports a link length greater than 25.4 km. A value of zero means + * that the transceiver does not support single mode fiber or that the length + * information must be determined from the transceiver technology. + */ + int len_sm; + + /* [Prop]: len_smf + * [Desc]: Length (single mode)-km + * [Note]: Addition to EEPROM data from original GBIC definition. This value specifies + * the link length that is supported by the transceiver while operating in + * compliance with the applicable standards using single mode fiber. The value + * is in units of kilometers. A value of 255 means that the transceiver supports + * a link length greater than 254 km. A value of zero means that the transceiver + * does not support single mode fiber or that the length information must be + * determined from the transceiver technology. + */ + int len_smf; + + /* [Prop]: len_om1 + * [Desc]: Link length supported for 62.5 um OM1 fiber, units of 10 m + * [Note]: The value is in units of 10 meters. A value of 255 means that the + * transceiver supports a link length greater than 2.54 km. A value of + * zero means that the transceiver does not support 50 micron multi-mode + * fiber or that the length information must be determined from the transceiver + * technology. + */ + int len_om1; + + /* [Prop]: len_om2 + * [Desc]: Link length supported for 50 um OM2 fiber, units of 10 m + * [Note]: The value is in units of 10 meters. A value of 255 means that the + * transceiver supports a link length greater than 2.54 km. A value of + * zero means that the transceiver does not support 50 micron multi-mode + * fiber or that the length information must be determined from the transceiver + * technology. + */ + int len_om2; + + /* [Prop]: len_om3 + * [Desc]: Length (50um, OM3) + * [Note]: This value specifies link length that is supported by the transceiver while + * operating in compliance with applicable standards using 50 micron multimode + * OM3 [2000 MHz*km] fiber. The value is in units of 10 meters. A value of 255 + * means that the transceiver supports a link length greater than 2.54 km. A value + * of zero means that the transceiver does not support 50 micron multimode fiber + * or that the length information must be determined from the transceiver technology. + */ + int len_om3; + + /* [Prop]: len_om4 + * [Desc]: Length (50um, OM4) and Length (Active Cable or Copper) + * [Note]: For optical links, this value specifies link length that is supported by the + * transceiver while operating in compliance with applicable standards using 50 micron + * multimode OM4 [4700 MHz*km] fiber. The value is in units of 10 meters. A value of + * 255 means that the transceiver supports a link length greater than 2.54 km. A value + * of zero means that the transceiver does not support 50 micron multimode fiber or that + * the length information must be determined from the transceiver codes specified in Table 5-3. + * + * For copper links, this value specifies minimum link length supported by the transceiver + * while operating in compliance with applicable standards using copper cable. For active + * cable, this value represents actual length. The value is in units of 1 meter. A value of 255 + * means the transceiver supports a link length greater than 254 meters. A value of zero means + * the transceiver does not support copper or active cables or the length information must be + * determined from transceiver technology. Further information about cable design, equalization, + * and connectors is usually required to guarantee meeting a particular length requirement. + */ + int len_om4; + + /* [Prop]: comp_rev + * [Desc]: SFF spec revision compliance + * [Note]: Indicates which revision of SFF SFF-8472 (SFP) / SFF-8636 (QSFP) the transceiver + * complies with. (unsigned integer) + */ + uint8_t comp_rev; + + /* [Prop]: CDR + * [Desc]: For transceivers with CDR capability, setting the CDR to ON engages the internal + * retiming function. Setting the CDR to OFF enables an internal bypassing mode ,which + * directs traffic around the internal CDR. (Reference: SFF-8636) + * [Note]: value=0xff: ON. + * value=0x00: OFF. + */ + uint8_t cdr; + + /* [Prop]: rate_id + * [Desc]: Soft Rate Select 0(RX). + * [Note]: 1. Addr: A0h / Offset: 13 + * 2. Value description: + * 00h Unspecified + * 01h SFF-8079 (4/2/1G Rate_Select & AS0/AS1) + * 02h SFF-8431 (8/4/2G Rx Rate_Select only) + * 03h Unspecified * + * 04h SFF-8431 (8/4/2G Tx Rate_Select only) + * 05h Unspecified * + * 06h SFF-8431 (8/4/2G Independent Rx & Tx Rate_select) + * 07h Unspecified * + * 08h FC-PI-5 (16/8/4G Rx Rate_select only) High=16G only, Low=8G/4G + * 09h Unspecified * + * 0Ah FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select) High=16G only, + * Low=8G/4G + * 0Bh Unspecified * + * 0Ch FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select) + * High=32G only, Low = 16G/8G + * 0Dh Unspecified * + * 0Eh 10/8G Rx and Tx Rate_Select controlling the operation or locking + * modes of the internal signal conditioner, retimer or CDR, according + * to the logic table defined in Table 10-2, High Bit Rate + * (10G) =9.95-11.3 Gb/s; Low Bit Rate (8G) = 8.5 Gb/s. In this mode, + * the default value of bit 110.3 (Soft Rate Select RS(0), Table 9-11) + * and of bit 118.3 (Soft Rate Select RS(1), Table 10-1) is 1. + * 0Fh Unspecified * + * 10h-FFh Unallocated + */ + int rate_id; + + /* [Prop]: soft_rs0 + * [Desc]: Soft Rate Select 0(RX). + * [Note]: 1. Writing '1' selects full bandwidth operation. + * 2. This bit is "OR'd with the hard Rate_Select, AS(0) or RS(0) pin value. + * 3. Default at power up is logic zero/low + * 4. Addr: A2h / Offset: 110 / Bit: 3 + */ + uint8_t soft_rs0; + + /* [Prop]: soft_rs1 + * [Desc]: Soft Rate Select 1(TX). + * [Note]: 1. Writing '1' selects full bandwidth TX operation. + * 2. This bit is "OR'd with the hard Rate_Select, AS(1) or RS(1) pin value. + * 3. Default at power up is logic zero/low + * 4. Addr: A2h / Offset: 118 / Bit: 3 + */ + uint8_t soft_rs1; + + /* [Prop]: diag_type + * [Desc]: DIAGNOSTIC MONITORING TYPE (A0h/92) + * [Note]: Description in SFF-8472 as below: + * Bit7: Reserved for legacy diagnostic implementations. Must be '0' for compliance + * with this document. + * Bit6: Digital diagnostic monitoring implemented (described in this document). + * Must be '1' for compliance with this document. + * Bit5 Internally calibrated + * Bit4 Externally calibrated + * Bit3 Received power measurement type.0 = OMA, 1 = average power + * Bit2 Address change required see section above, "addressing modes" + * Bit1-0 Unallocated + */ + uint8_t diag_type; + + /* [Prop]: curr_temp + * [Desc]: Transceiver Current Temperature (A2h/96-97) + * [Note]: 1. Dependent on diag_type. + * 2. 96: High byte + * 3. 97: Low byte + * 4. This feature only for SFP + */ + uint8_t curr_temp[2]; + + /* [Prop]: curr_vol + * [Desc]: Transceiver Current Voltage (SFP:A2h/108-109; QSFP:00h/22-23) + * [Note]: 1. Dependent on diag_type. + * 2. 98: High byte + * 3. 99: Low byte + * 4. This feature only for SFP + * 5. Internally measured transceiver supply voltage. Represented + * as a 16 bit unsigned integer with the voltage defined as the + * full 16 bit value (0-65535) with LSB equal to 100 uVolt, + * yielding a total range of 0 to +6.55 Volts + */ + uint8_t curr_voltage[2]; + + /* [Prop]: curr_tx_bias + * [Desc]: Transceiver TX Bias Current (SFP:A2h/100-101; QSFP:00h/26-27) + * [Note]: 1. Dependent on diag_type. + * 2. 100: High byte + * 3. 101: Low byte + * 4. This feature only for SFP + * 5. Measured TX bias current in uA. Represented as a 16 bit unsigned + * integer with the current defined as the full 16 bit value (0-65535) + * with LSB equal to 2 uA, yielding a total range of 0 to 131 mA. + * Accuracy is vendor specific but must be better than 10% of the + * manufacturer's nominal value over specified operating temperature + * and voltage. + */ + uint8_t curr_tx_bias[8]; + + /* [Prop]: curr_tx_power + * [Desc]: Transceiver TX Output Power (A2h/102-103) + * [Note]: 1. Dependent on diag_type. + * 2. 102: High byte + * 3. 103: Low byte + * 4. This feature only for SFP + * 5. Measured TX output power in mW. Represented as a 16 bit unsigned + * integer with the power defined as the full 16 bit value (0-65535) + * with LSB equal to 0.1 uW, yielding a total range of 0 to 6.5535 mW + * (~ -40 to +8.2 dBm). Data is assumed to be based on measurement of + * laser monitor photodiode current. It is factory calibrated to absolute + * units using the most representative fiber output type. Accuracy is + * vendor specific but must be better than 3dB over specified temperature + * and voltage. Data is not valid when the transmitter is disabled. + */ + uint8_t curr_tx_power[8]; + + /* [Prop]: curr_tx_power + * [Desc]: Transceiver TX Output Power (A2h/102-103) + * [Note]: 1. Dependent on diag_type. + * 2. 102: High byte + * 3. 103: Low byte + * 4. This feature only for SFP + * 5. Measured RX received optical power in mW. Value can represent either + * average received power or OMA depending upon how bit 3 of byte 92 (A0h) + * is set. Represented as a 16 bit unsigned integer with the power defined + * as the full 16 bit value (0-65535) with LSB equal to 0.1 uW, yielding a + * total range of 0 to 6.5535 mW (~ -40 to +8.2 dBm). Absolute accuracy is + * dependent upon the exact optical wavelength. For the vendor specified + * wavelength, accuracy shall be better than 3dB over specified temperature + * and voltage. + */ + uint8_t curr_rx_power[8]; + + /* [Prop]: wavelength + * [Desc]: Wavelength or Copper Cable Attenuation + * [Note]: (Following is info from SFF-8636) + * For optical free side devices, this parameter identifies the nominal + * transmitter output wavelength at room temperature. This parameter is a + * 16-bit hex value with Byte 186 as high order byte and Byte 187 as low + * order byte. The laser wavelength is equal to the 16-bit integer value + * divided by 20 in nm (units of 0.05 nm). This resolution should be adequate + * to cover all relevant wavelengths yet provide enough resolution for all + * expected DWDM applications. For accurate representation of controlled + * wavelength applications, this value should represent the center of the + * guaranteed wavelength range. If the free side device is identified as + * copper cable these registers will be used to define the cable attenuation. + * An indication of 0 dB attenuation refers to the case where the attenuation + * is not known or is unavailable. + * Byte 186 (00-FFh) is the copper cable attenuation at 2.5 GHz in units of 1 dB. + * Byte 187 (00-FFh) is the copper cable attenuation at 5.0 GHz in units of 1 dB. + */ + uint8_t wavelength[2]; + + /* [Prop]: Amplitude control + * [Desc]: Amplitude control + * [Note]: QSFP28 => SFF-8636 03H Byte-238/239 + */ + uint8_t rx_am[2]; + + /* [Prop]: Emphasis control + * [Desc]: Emphasis control + * [Note]: SFP+/28 => SFF-8472 A2H Byte-115 + * QSFP28 => SFF-8636 03H Byte-236/237 + */ + uint8_t rx_em[2]; + + /* [Prop]: Soft Rx LOS + * [Desc]: Soft Rx LOS which provide by transceiver + * [Note]: (Following is info from SFF-8636) + * Byte 3: + * - Bit 0: L-Rx1 LOS + * - Bit 1: L-Rx2 LOS + * - Bit 2: L-Rx3 LOS + * - Bit 3: L-Rx4 LOS + */ + uint8_t rx_los; + + /* [Prop]: Soft Tx Disable + * [Desc]: Soft Tx Disable which provide by transceiver + * [Note]: (Following is info from SFF-8636) + * Byte 86: + * - Bit 0: Tx1 Disable + * - Bit 1: Tx2 Disable + * - Bit 2: Tx3 Disable + * - Bit 3: Tx4 Disable + */ + uint8_t tx_disable; + + /* [Prop]: Soft Tx Fault + * [Desc]: Soft Tx Fault which provide by transceiver + * [Note]: (Following is info from SFF-8636) + * Byte 86: + * - Bit 0: Tx1 Fault + * - Bit 1: Tx2 Fault + * - Bit 2: Tx3 Fault + * - Bit 3: Tx4 Fault + */ + uint8_t tx_fault; + + /* [Prop]: Transceiver EQUALIZATION + * [Desc]: Transceiver EQUALIZATION + * [Note]: SFP+/28 => SFF-8472 A2H Byte-114 + * QSFP28 => SFF-8636 03H Byte-234/235 + */ + uint8_t tx_eq[2]; + + /* [Prop]: OPTION VALUES + * [Desc]: The bits in the option field shall specify the options implemented in the transceiver. + * [Note]: SFP+/28 => SFF-8472 A0H Byte-64/65 + * QSFP+/28 => SFF-8636 00H Byte-193/195 + */ + uint8_t option[3]; + + /* [Prop]: External PHY offset + * [Desc]: It needs to be setup first if you want to access transceiver external phy. + * [Note]: This feature dependent on transceiver. + * Currently, only 1G-RJ45 transceiver supported it. + */ + uint8_t extphy_offset; + + /* ========== Object private property ========== + */ + struct device *transvr_dev_p; + struct eeprom_map_s *eeprom_map_p; + struct i2c_client *i2c_client_p; + struct ioexp_obj_s *ioexp_obj_p; + struct transvr_worker_s *worker_p; + struct mutex lock; + char swp_name[32]; + int auto_config; + int auto_tx_disable; + int chan_id; + int chipset_type; + int curr_page; + int info; + int ioexp_virt_offset; + int lane_id[8]; + int layout; + int mode; + int retry; + int state; + int temp; + int type; + + /* ========== Object public functions ========== + */ + int (*get_id)(struct transvr_obj_s *self); + int (*get_ext_id)(struct transvr_obj_s *self); + int (*get_connector)(struct transvr_obj_s *self); + int (*get_vendor_name)(struct transvr_obj_s *self, char *buf_p); + int (*get_vendor_pn)(struct transvr_obj_s *self, char *buf_p); + int (*get_vendor_rev)(struct transvr_obj_s *self, char *buf_p); + int (*get_vendor_sn)(struct transvr_obj_s *self, char *buf_p); + int (*get_power_cls)(struct transvr_obj_s *self); + int (*get_br)(struct transvr_obj_s *self); + int (*get_len_sm)(struct transvr_obj_s *self); + int (*get_len_smf)(struct transvr_obj_s *self); + int (*get_len_om1)(struct transvr_obj_s *self); + int (*get_len_om2)(struct transvr_obj_s *self); + int (*get_len_om3)(struct transvr_obj_s *self); + int (*get_len_om4)(struct transvr_obj_s *self); + int (*get_comp_rev)(struct transvr_obj_s *self); + int (*get_comp_eth_1)(struct transvr_obj_s *self); + int (*get_comp_eth_10)(struct transvr_obj_s *self); + int (*get_comp_eth_10_40)(struct transvr_obj_s *self); + int (*get_comp_extend)(struct transvr_obj_s *self); + int (*get_cdr)(struct transvr_obj_s *self); + int (*get_rate_id)(struct transvr_obj_s *self); + int (*get_soft_rs0)(struct transvr_obj_s *self); + int (*get_soft_rs1)(struct transvr_obj_s *self); + int (*get_info)(struct transvr_obj_s *self); + int (*get_if_type)(struct transvr_obj_s *self, char *buf_p); + int (*get_if_speed)(struct transvr_obj_s *self, char *buf_p); + int (*get_if_lane)(struct transvr_obj_s *self, char *buf_p); + int (*get_curr_temp)(struct transvr_obj_s *self, char *buf_p); + int (*get_curr_vol)(struct transvr_obj_s *self, char *buf_p); + int (*get_soft_rx_los)(struct transvr_obj_s *self, char *buf_p); + int (*get_soft_tx_disable)(struct transvr_obj_s *self, char *buf_p); + int (*get_soft_tx_fault)(struct transvr_obj_s *self, char *buf_p); + int (*get_auto_tx_disable)(struct transvr_obj_s *self, char *buf_p); + int (*get_tx_bias)(struct transvr_obj_s *self, char *buf_p); + int (*get_tx_power)(struct transvr_obj_s *self, char *buf_p); + int (*get_rx_power)(struct transvr_obj_s *self, char *buf_p); + int (*get_tx_eq)(struct transvr_obj_s *self, char *buf_p); + int (*get_rx_am)(struct transvr_obj_s *self, char *buf_p); + int (*get_rx_em)(struct transvr_obj_s *self, char *buf_p); + int (*get_wavelength)(struct transvr_obj_s *self, char *buf_p); + int (*get_extphy_offset)(struct transvr_obj_s *self, char *buf_p); + int (*get_extphy_reg)(struct transvr_obj_s *self, char *buf_p); + int (*set_cdr)(struct transvr_obj_s *self, int input_val); + int (*set_soft_rs0)(struct transvr_obj_s *self, int input_val); + int (*set_soft_rs1)(struct transvr_obj_s *self, int input_val); + int (*set_soft_tx_disable)(struct transvr_obj_s *self, int input_val); + int (*set_auto_tx_disable)(struct transvr_obj_s *self, int input_val); + int (*set_tx_eq)(struct transvr_obj_s *self, int input_val); + int (*set_rx_am)(struct transvr_obj_s *self, int input_val); + int (*set_rx_em)(struct transvr_obj_s *self, int input_val); + int (*set_extphy_offset)(struct transvr_obj_s *self, int input_val); + int (*set_extphy_reg)(struct transvr_obj_s *self, int input_val); + + /* ========== Object private functions ========== + */ + int (*init)(struct transvr_obj_s *self); + int (*clean)(struct transvr_obj_s *self); + int (*check)(struct transvr_obj_s *self); + int (*update_all)(struct transvr_obj_s *self, int show_err); + int (*fsm_4_direct)(struct transvr_obj_s* self, char *caller_name); + int (*fsm_4_polling)(struct transvr_obj_s* self, char *caller_name); + int (*send_uevent)(struct transvr_obj_s* self, enum kobject_action u_action); + int (*dump_all)(struct transvr_obj_s* self); +}; + + +/* For AVL Mapping */ +struct transvr_avl_s { + char vendor_name[32]; + char vendor_pn[32]; + int (*init)(struct transvr_obj_s *self); +}; + + +/* Worker for long term task of transceiver */ +struct transvr_worker_s { + /* Task Parameter */ + struct transvr_obj_s *transvr_p; + struct transvr_worker_s *next_p; + struct transvr_worker_s *pre_p; + unsigned long trigger_time; + char func_name[64]; + int retry; + int state; + + /* Task private data */ + void *p_data; + + /* Call back function */ + int (*main_task)(struct transvr_worker_s *task); + int (*post_task)(struct transvr_worker_s *task); +}; + + +struct transvr_obj_s * +create_transvr_obj(char *swp_name, + int chan_id, + struct ioexp_obj_s *ioexp_obj_p, + int ioexp_virt_offset, + int transvr_type, + int chipset_type, + int run_mode); + +void lock_transvr_obj(struct transvr_obj_s *self); +void unlock_transvr_obj(struct transvr_obj_s *self); +int isolate_transvr_obj(struct transvr_obj_s *self); + +int resync_channel_tier_2(struct transvr_obj_s *self); + +void alarm_msg_2_user(struct transvr_obj_s *self, char *emsg); + +#endif /* TRANSCEIVER_H */ + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/setup.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/setup.py new file mode 100644 index 000000000000..c48f6ef8da07 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Ivnetec D6332 platforms', + + packages=['sonic_platform'], +) + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/__init__.py new file mode 100644 index 000000000000..4bfefa0fb636 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/chassis.py new file mode 100644 index 000000000000..b9e0afd8501f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/chassis.py @@ -0,0 +1,242 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import re + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan + from sonic_platform.psu import Psu + from sonic_platform.qsfp import QSfp + from sonic_platform.event_monitor import EventMonitor + from sonic_platform.thermal import Thermal + from sonic_platform.component import Component + from sonic_platform.watchdog import Watchdog +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/reboot-cause/" +REBOOT_CAUSE_FILE = "reboot-cause.txt" +PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" +monitor = None + +class Chassis(ChassisBase): + + __num_of_fans = 5 + __num_of_psus = 2 + __num_of_sfps = 32 + __start_of_qsfp = 1 + __num_of_thermals = 15 + __num_of_components= 4 + + def __init__(self): + ChassisBase.__init__(self) + + # Initialize EEPROM + self._eeprom = Eeprom() + self._eeprom_data = self._eeprom.get_eeprom_data() + + # Initialize FAN + for index in range(self.__num_of_fans): + fan = Fan(index) + self._fan_list.append(fan) + + # Initialize PSU + for index in range(self.__num_of_psus): + psu = Psu(index) + self._psu_list.append(psu) + + # Initialize SFP + for index in range(self.__num_of_sfps): + sfp = QSfp(index) #only qsfp on platform D6332 + self._sfp_list.append(sfp) + + # Initialize THERMAL + for index in range(self.__num_of_thermals): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + # Initialize COMPONENT + for index in range(self.__num_of_components): + component = Component(index) + self._component_list.append(component) + + # Initialize WATCHDOG + self._watchdog = Watchdog() + + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr(self._eeprom_data) + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_number_str(self._eeprom_data) + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + +############################################## +# Chassis methods +############################################## + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr(self._eeprom_data) + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str(self._eeprom_data) + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + """ + return self._eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + description = 'None' + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + + reboot_cause_path = PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE + prev_reboot_cause_path = PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE + + sw_reboot_cause = self.__read_txt_file(reboot_cause_path) or "Unknown" + prev_sw_reboot_cause = self.__read_txt_file(prev_reboot_cause_path) or "Unknown" + + if sw_reboot_cause == "Unknown" and (prev_sw_reboot_cause == "Unknown" or prev_sw_reboot_cause == self.REBOOT_CAUSE_POWER_LOSS): + reboot_cause = self.REBOOT_CAUSE_POWER_LOSS + description = prev_sw_reboot_cause + elif sw_reboot_cause != "Unknown": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = sw_reboot_cause + elif prev_reboot_cause_path != "Unknown": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = prev_sw_reboot_cause + + return (reboot_cause, description) + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + global monitor + port_dict = {} + while True: + with EventMonitor(timeout) as monitor: + while True: + event = monitor.get_events() + + if not bool(event): + return True, {'sfp':port_dict} + else: + if event['SUBSYSTEM'] == 'swps': + portname = event['DEVPATH'].split("/")[-1] + rc = re.match(r"port(?P\d+)",portname) + if rc is not None: + if event['ACTION'] == "remove": + remove_num = int(rc.group("num")) + port_dict[remove_num] = "0" + elif event['ACTION'] == "add": + add_num = int(rc.group("num")) + port_dict[add_num] = "1" + return True, {'sfp':port_dict} + else: + return False, {'sfp':port_dict} + else: + pass diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/component.py new file mode 100644 index 000000000000..116daa8d30f8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/component.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python + +try: + import os + import logging + from sonic_platform_base.component_base import ComponentBase + from sonic_platform.inv_const import Common + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +OS_SYSTEM_SUCCESS = 0 + +CPLD1_INFO_PATH = Common.I2C_PREFIX+"/0-0077/info" +CPLD2_INFO_PATH = Common.I2C_PREFIX+"/0-0077/info" #info of 2 cpld are combined by inv_cpld under this path +BIOS_VER_PATH = "/sys/class/dmi/id/bios_version" +BIOS_CS_PATH = Common.I2C_PREFIX+"/0-0077/bios_cs" + +CPLD1_INDEX = 0 +CPLD2_INDEX = 1 +MAIN_BIOS_INDEX = 2 +BACKUP_BIOS_INDEX = 3 + + +COMPONENT_NAME_LIST = [ + "CPLD1", + "CPLD2", + "Main BIOS", + "Backup BIOS", +] + +COMPONENT_DESC_LIST = [ + "platform management and control LED", + "platform management and control LED", + "Main Basic Input/Output System", + "Backup Basic Input/Output System", +] + + +BIOS_ID_MAPPING_TABLE = { + 0: MAIN_BIOS_INDEX, + 1: BACKUP_BIOS_INDEX +} + +class Component(ComponentBase): + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def __set_attr_value(self, attr_path, value): + try: + with open(attr_path, 'r+') as reg_file: + reg_file.write(value) + except IOError as e: + logging.error("Error: unable to open file: %s" % str(e)) + return False + + return True + + def __get_current_bios(self): + current_bios=self.__get_attr_value(BIOS_CS_PATH) + if current_bios != 'ERR': + ''' + Get first char to convert to bios ID + ''' + current_bios = int(current_bios[:1]) + else: + current_bios = None + + return current_bios + + def __get_cpld_version(self): + ''' + The info output would be like: + The CPLD release date is 06/13/2019. + The PCB version is 5 + The CPLD version is 1.1 + ''' + cpld_version = None + ret_str = None + path = None + target="" + + if self.index == CPLD1_INDEX: + path = CPLD1_INFO_PATH + target="The CPLD version is " + elif self.index == CPLD2_INDEX: + path = CPLD2_INFO_PATH + target="The CPLD2 version is " + else: + logging.error("Unable support index %d", self.index) + + if path !=None: + try: + with open(path, 'r') as file: + ret_str = file.read() + except Exception as error: + logging.error("Unable to open file %s", path) + + if ret_str!=None: + start_idx=ret_str.find(target) + if start_idx > 0: + start_idx = start_idx+len(target) + offset = ret_str[start_idx:].find('\n') + if offset > 0: + end_idx=start_idx+offset + cpld_version=ret_str[start_idx:end_idx].strip('\n') + + if cpld_version is None: + logging.error("Unable to parse cpld info %d", self.index) + + return cpld_version + + + def __get_bios_version(self): + bios_version = None + current_bios_id=self.__get_current_bios() + + if current_bios_id != None : + if self.index == BIOS_ID_MAPPING_TABLE[current_bios_id]: + try: + with open(BIOS_VER_PATH, 'r') as file: + bios_version = file.read().strip('\n') + except Exception as error: + logging.error("Unable to open file %s", BIOS_VER_PATH) + else: + logging.error("Only support bios version of current running BIOS") + bios_version = "N/A" + + return bios_version + + def __install_cpld_firmware(self,image_path): + logging.error("[Component][__install_cpld_firmware] Currently not support FW update on platform D6332") + raise NotImplementedError + + def __install_bios_firmware(self,image_path): + logging.error("[Component][__install_bios_firmware] Currently not support FW update on platform D6332") + raise NotImplementedError + + __get_version_callback_list = { + CPLD1_INDEX:__get_cpld_version, + CPLD2_INDEX:__get_cpld_version, + MAIN_BIOS_INDEX:__get_bios_version, + BACKUP_BIOS_INDEX:__get_bios_version, + } + + def __init__(self, component_index): + self.index = component_index + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return COMPONENT_NAME_LIST[self.index] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return COMPONENT_DESC_LIST[self.index] + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + Returns: + A string containing the firmware version of the component + """ + return self.__get_version_callback_list[self.index](self) + + def install_firmware(self, image_path): + """ + Installs firmware to the component + Args: + image_path: A string, path to firmware image + Returns: + A boolean, True if install was successful, False if not + """ + logging.error("[Component][install_firmware] Currently not support FW update on platform D6332") + raise NotImplementedError \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/eeprom.py new file mode 100644 index 000000000000..3995bc70fd5b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/eeprom.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# +# Name: eeprom.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ( ImportError, e ): + raise ImportError(str(e) + "- required module not found") + +EEPROM_TOTAL_LEN_HIGH_OFFSET = 9 +EEPROM_TOTAL_LEN_LOW_OFFSET = 10 +EEPROM_TLV_TYPE_OFFSET = 0 +EEPROM_TLV_LEN_OFFSET = 1 +EEPROM_TLV_VALUE_OFFSET = 2 + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self): + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0055/eeprom" + super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True) + self.__eeprom_tlv_dict = dict() + try: + self.__eeprom_data = self.read_eeprom() + except: + self.__eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.__eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[EEPROM_TOTAL_LEN_HIGH_OFFSET]) << 8) | ord(eeprom[EEPROM_TOTAL_LEN_LOW_OFFSET]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + EEPROM_TLV_VALUE_OFFSET) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + EEPROM_TLV_VALUE_OFFSET + + ord(eeprom[tlv_index + EEPROM_TLV_LEN_OFFSET])] + code = "0x%02X" % (ord(tlv[EEPROM_TLV_TYPE_OFFSET])) + + if ord(tlv[EEPROM_TLV_TYPE_OFFSET]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[EEPROM_TLV_VALUE_OFFSET]) << 24) | (ord(tlv[EEPROM_TLV_VALUE_OFFSET+1]) << 16) | + (ord(tlv[EEPROM_TLV_VALUE_OFFSET+2]) << 8) | ord(tlv[EEPROM_TLV_VALUE_OFFSET+3])) + value += str(tlv[6:6 + ord(tlv[EEPROM_TLV_LEN_OFFSET])]) + else: + name, value = self.decoder(None, tlv) + + self.__eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+EEPROM_TLV_LEN_OFFSET]) + EEPROM_TLV_VALUE_OFFSET + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.__eeprom_tlv_dict + + def get_eeprom_data(self): + return self.__eeprom_data diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/event_monitor.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/event_monitor.py new file mode 100644 index 000000000000..247943075934 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/event_monitor.py @@ -0,0 +1,94 @@ +# +# event_monitor.py +# Description: module to minitor events +# + +try: + import socket + from collections import OrderedDict + import os +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +NETLINK_KOBJECT_UEVENT = 15 + +class EventMonitor(object): + + def __init__(self, timeout): + self.recieved_events = OrderedDict() + self.socket = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT) + self.timeout = timeout + + def start(self): + self.socket.bind((os.getpid(), -1)) + + if 0 == self.timeout: + self.socket.settimeout(None) + else: + self.socket.settimeout(self.timeout/1000.0) + + def stop(self): + self.socket.close() + + def __enter__(self): + self.start() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.stop() + + def __iter__(self): + while True: + for item in self.next_events(): + yield item + + def next_events(self): + try: + data = self.socket.recv(16384) + event = {} + for item in data.split(b'\x00'): + if not item: + # check if we have an event and if we already received it + if event and event['SEQNUM'] not in self.recieved_events: + self.recieved_events[event['SEQNUM']] = None + if (len(self.recieved_events) > 100): + self.recieved_events.popitem(last=False) + yield event + event = {} + else: + try: + k, v = item.split(b'=', 1) + event[k.decode('ascii')] = v.decode('ascii') + except ValueError: + pass + except socket.timeout: + yield event + + def get_events(self): + event = {} + while True: + try: + data = self.socket.recv(16384) + + for item in data.split(b'\x00'): + if not item: + # check if we have an event and if we already received it + # if no item and event empty, means received garbled + if bool(event): + if event['SEQNUM'] not in self.recieved_events: + self.recieved_events[event['SEQNUM']] = None + if (len(self.recieved_events) > 100): + self.recieved_events.popitem(last=False) + return event + else: + event = {} + else: + try: + k, v = item.split(b'=', 1) + event[k] = v + except ValueError: + pass + except socket.timeout: + return event + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/fan.py new file mode 100644 index 000000000000..4f62ccaafd56 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/fan.py @@ -0,0 +1,330 @@ +#!/usr/bin/env python +# +# Name: fan.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import math + import os + import logging + from sonic_platform_base.fan_base import FanBase + from sonic_platform.inv_const import FanConst , PsuConst, Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +MAX_SPEED_OF_FAN_FRONT = 23500 +MAX_SPEED_OF_FAN_BACK = 19900 +MAX_SPEED_OF_FAN_PSU = 26000 +MAX_PWM_OF_FAN = 255 + +class Fan(FanBase): + + __name_of_fans = ['FAN1','FAN2','FAN3','FAN4','FAN5','PSU1_FAN1','PSU2_FAN1'] + __start_of_psu_fans = FanConst().PSU_FAN_START_INDEX + + def __init__(self, index): + self.__index = index + + if self.__index >= self.__start_of_psu_fans: + psu_id=self.__index- self.__start_of_psu_fans + self.__presence_attr = "{}/i2c-inv_cpld/psu{}".format(Common.I2C_PREFIX,psu_id+1) + self.__rpm1_attr = "{}/psu{}/fan1_input".format(Common.INFO_PREFIX, psu_id+1) + else: + self.__fan_type = "{}/i2c-inv_cpld/fanmodule{}_type".format(Common.I2C_PREFIX, self.__index + 1) + self.__rpm1_attr = "{}/i2c-inv_cpld/fan{}_input".format(Common.I2C_PREFIX, 2*self.__index + 1) + self.__rpm2_attr = "{}/i2c-inv_cpld/fan{}_input".format(Common.I2C_PREFIX, 2*self.__index + 2) + self.__pwm_attr = "{}/i2c-inv_cpld/pwm{}".format(Common.I2C_PREFIX, self.__index + 1) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def read_fru(self, attr_type): + fan_addr=FanConst.FAN_VPD_ADDR_BASE+self.__index + path="/sys/bus/i2c/devices/{}-00{}/eeprom".format(FanConst.FAN_VPD_CHANNEL, hex(fan_addr)[2:] ) + content=[] + attr_idx=0 + attr_length=0 + + if(os.path.exists(path)): + with open(path,'rw') as f: + content=f.read() + target_offset=ord(content[FanConst.TLV_PRODUCT_INFO_OFFSET_IDX-1]) + target_offset*=8 #spec defined: offset are in multiples of 8 bytes + + attr_idx=target_offset+FanConst.TLV_PRODUCT_INFO_AREA_START + for i in range(1,attr_type): + if attr_idx > len(content): + raise SyntaxError + attr_length=(ord(content[attr_idx]))&(0x3f) + attr_idx+=(attr_length+1); + + attr_length=(ord(content[attr_idx]))&(0x3f) + attr_idx+=1 + else: + logging.error("[FAN] Can't find path to eeprom : %s" % path) + return SyntaxError + + return content[attr_idx:attr_idx+attr_length] + + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.__name_of_fans[self.__index] + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + + if self.__index >= self.__start_of_psu_fans: + #check fan of psu presence if psu presence + attr_path = self.__presence_attr + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == PsuConst.PSU_TYPE_LIST[0] or attr_rv == PsuConst.PSU_TYPE_LIST[1]): + presence = True + else: + raise SyntaxError + else: + attr_path = self.__fan_type + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if(attr_rv==FanConst.FAN_TYPE_LIST[0] or attr_rv==FanConst.FAN_TYPE_LIST[1]): + presence = True + else: + raise SyntaxError + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + if self.__index >= self.__start_of_psu_fans: + return NotImplementedError + else: + model=self.read_fru(FanConst.TLV_ATTR_TYPE_MODEL) + if not model: + return NotImplementedError + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + if self.__index >= self.__start_of_psu_fans: + return NotImplementedError + else: + serial=self.read_fru(FanConst.TLV_ATTR_TYPE_SERIAL) + if not serial: + return NotImplementedError + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + + if self.__index >= self.__start_of_psu_fans: + #check fan of psu presence if psu presence + attr_path = self.__presence_attr + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == PsuConst.PSU_TYPE_LIST[1]): + status = True + else: + raise SyntaxError + else: + status = self.get_presence() + + return status + +############################################## +# FAN methods +############################################## + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = 'N/A' + + if self.__index >= self.__start_of_psu_fans: + raise NotImplementedError + else: + attr_path = self.__fan_type + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + + #"Normal Type", //00 + #"REVERSAL Type", //01 + #"UNPLUGGED", //10 + #"UNPLUGGED", //11 + + if(attr_rv==FanConst.FAN_TYPE_LIST[0]): + direction = 'FAN_DIRECTION_EXHAUST' + elif(attr_rv==FanConst.FAN_TYPE_LIST[1]): + direction = 'FAN_DIRECTION_INTAKE' + else: + raise SyntaxError + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + + if self.__index >= self.__start_of_psu_fans: + attr_rv1 = self.__get_attr_value(self.__presence_attr) + if( attr_rv1 == PsuConst.PSU_TYPE_LIST[0] or attr_rv1 == PsuConst.PSU_TYPE_LIST[1] ): + attr_path1 = self.__rpm1_attr + attr_rv1 = self.__get_attr_value(attr_path1) + if (attr_rv1 != 'ERR' ): + speed = int(attr_rv1) * 100 / MAX_SPEED_OF_FAN_PSU + elif(attr_rv1 == 'ERR' ): + raise SyntaxError + else: + attr_path1 = self.__rpm1_attr + attr_path2 = self.__rpm2_attr + + if self.get_presence() and None != attr_path1: + attr_rv1 = self.__get_attr_value(attr_path1) + attr_rv2 = self.__get_attr_value(attr_path2) + if (attr_rv1 != 'ERR' and attr_rv2 != 'ERR'): + fan1_input = int(attr_rv1) + speed = math.ceil(float(fan1_input * 100 / MAX_SPEED_OF_FAN_FRONT)) + fan2_input = int(attr_rv2) + speed += math.ceil(float(fan2_input * 100 / MAX_SPEED_OF_FAN_BACK)) + speed /= 2 + elif (attr_rv1 != 'ERR'): + fan1_input = int(attr_rv1) + if self.__index >= self.__start_of_psu_fans: + speed = speed = math.ceil(float(fan1_input * 100 / MAX_SPEED_OF_FAN_PSU)) + else: + speed = math.ceil(float(fan1_input * 100 / MAX_SPEED_OF_FAN_FRONT)) + elif (attr_rv2 != 'ERR'): + fan2_input = int(attr_rv2) + speed += math.ceil(float(fan2_input * 100 / MAX_SPEED_OF_FAN_BACK)) + else: + raise SyntaxError + + return speed + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + + if self.__index >= self.__start_of_psu_fans: + return NotImplementedError + else: + attr_path = self.__pwm_attr + + if self.get_presence() and None != attr_path: + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + pwm = int(attr_rv) + speed = math.ceil(float(pwm * 100 / MAX_PWM_OF_FAN)) + else: + raise SyntaxError + + return speed + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + raise NotImplementedError + + def set_speed(self, speed): + """ + Sets the fan speed + + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + + Returns: + A boolean, True if speed is set successfully, False if not + """ + raise NotImplementedError + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + + Args: + color: A string representing the color with which to set the + fan module status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + raise NotImplementedError + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/inv_const.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/inv_const.py new file mode 100644 index 000000000000..ace488f551da --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/inv_const.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +class Common(): + INFO_PREFIX = "/usr/share/sonic/platform" + I2C_PREFIX = "/sys/bus/i2c/devices" + +class FanConst(): + #fan vpd info + FAN_VPD_CHANNEL= 1 + FAN_VPD_ADDR_BASE=0x52 + #fru status + TLV_PRODUCT_INFO_OFFSET_IDX=5 + TLV_PRODUCT_INFO_AREA_START=3 + TLV_ATTR_TYPE_SERIAL=5 + TLV_ATTR_TYPE_MODEL=2 + + PSU_FAN_START_INDEX = 5 + FAN_TYPE_LIST=["0:Normal Type","1:REVERSAL Type","2:UNPLUGGED","3:UNPLUGGED"] #defined in inv_cpld + +class PsuConst(): + PSU_TYPE_LIST=["0:unpowered","1:normal","2:not installed","3:not installed"] #defined in inv_cpld + PSU_I2C_ADDR=["2-005a","2-005b"] \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/platform.py new file mode 100644 index 000000000000..7d6bda4502de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/platform.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/psu.py new file mode 100644 index 000000000000..93352636078d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/psu.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python +# +# Name: psu.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import logging + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.fan import Fan + from sonic_platform.inv_const import FanConst , PsuConst, Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +VOLTAGE_UPPER_LIMIT = 14 +VOLTAGE_LOWER_LIMIT = 10 + +class Psu(PsuBase): + + __num_of_fans = 1 + __name_of_psus = ['PSU1','PSU2'] + + def __init__(self, index): + self.__index = index + psu_id = self.__index + 1 + + self.__psu_presence_attr = "{}/i2c-inv_cpld/psu{}".format(Common.I2C_PREFIX,psu_id) + self.__psu_voltage_out_attr = "{}/psu{}/in2_input".format(Common.INFO_PREFIX, psu_id) + self.__psu_current_out_attr = "{}/psu{}/curr2_input".format(Common.INFO_PREFIX, psu_id) + self.__psu_power_out_attr = "{}/psu{}/power2_input".format(Common.INFO_PREFIX, psu_id) + + # Get the start index of fan list + self.__fan_psu_start_index = self.__index + FanConst().PSU_FAN_START_INDEX + + # Overriding _fan_list class variable defined in PsuBase, to make it unique per Psu object + self._fan_list = [] + + # Initialize FAN + for x in range(self.__fan_psu_start_index, self.__fan_psu_start_index + self.__num_of_fans): + fan = Fan(x) + self._fan_list.append(fan) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.__name_of_psus[self.__index] + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__psu_presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == PsuConst.PSU_TYPE_LIST[0] or attr_rv == PsuConst.PSU_TYPE_LIST[1]): + presence = True + else: + raise SyntaxError + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + #model = 'Unknow' + #attr_path = self.__psu_model_attr + + #attr_rv = self.__get_attr_value(attr_path) + #if (attr_rv != 'ERR'): + # if (attr_rv != ''): + # model = attr_rv + #else: + # raise SyntaxError + + #return model + raise NotImplementedError + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + """ + serial = 'Unknow' + attr_path = self.__psu_serial_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv != ''): + serial = attr_rv + else: + raise SyntaxError + + return serial + """ + raise NotImplementedError + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + attr_path = self.__psu_presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == PsuConst.PSU_TYPE_LIST[1]): + status = True + else: + raise SyntaxError + + return status + + +############################################## +# PSU methods +############################################## + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + voltage_out = 0.0 + attr_path = self.__psu_voltage_out_attr + + if(self.get_presence()): + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + voltage_out = float(attr_rv) / 1000 + else: + raise SyntaxError + + return voltage_out + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + current_out = 0.0 + attr_path = self.__psu_current_out_attr + + if(self.get_presence()): + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + current_out = float(attr_rv) / 1000 + else: + raise SyntaxError + + return current_out + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, e.g. 302.6 + """ + power_out = 0.0 + attr_path = self.__psu_power_out_attr + + if(self.get_presence()): + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + power_out = float(attr_rv) / 1000 + else: + raise SyntaxError + + return power_out + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + powergood_status = False + voltage_out = self.get_voltage() + + #Check the voltage out with 12V, plus or minus 20 percentage. + if (VOLTAGE_LOWER_LIMIT <= voltage_out and voltage_out <= VOLTAGE_UPPER_LIMIT ): + powergood_status = True + + return powergood_status + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + + Args: + color: A string representing the color with which to set the + PSU status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + raise NotImplementedError + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/qsfp.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/qsfp.py new file mode 100644 index 000000000000..178ac0cf9aa5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/qsfp.py @@ -0,0 +1,1023 @@ +#!/usr/bin/env python +# +# Name: qsfp.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import logging + from ctypes import create_string_buffer + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from sonic_platform.inv_const import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 128 +THRE_OFFSET = 384 #128*3 +DOM_OFFSET = 0 + +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# Offset for values in QSFP eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + +QSFP_REG_VALUE_ENABLE = "0x1" +QSFP_REG_VALUE_DISABLE = "0x0" + +class QSfp(SfpBase): + + __platform = "x86_64-inventec_d6332-r0" + __hwsku = "INVENTEC-D6332" + __port_to_i2c_mapping = { + 0:12, 1:13, 2:14, 3:15, 4:16, 5:17, 6:18, 7:19, + 8:20, 9:21, 10:22, 11:23, 12:24, 13:25, 14:26, 15:27, + 16:28, 17:29, 18:30, 19:31, 20:32, 21:33, 22:34, 23:35, + 24:36, 25:37, 26:38, 27:39, 28:40, 29:41, 30:42, 31:43, + } + + + def __init__(self, index): + self.__index = index + + self.__port_end = len(self.__port_to_i2c_mapping) - 1 + + self.__presence_attr = None + self.__eeprom_path = None + if self.__index in range(0, self.__port_end + 1): + self.__presence_attr = "/sys/class/swps/port{}/present".format(self.__index) + self.__lpmode_attr = "/sys/class/swps/port{}/lpmod".format(self.__index) + self.__reset_attr = "/sys/class/swps/port{}/reset".format(self.__index) + self.__eeprom_path = "{}/{}-0050/eeprom".format(Common.I2C_PREFIX, self.__port_to_i2c_mapping[self.__index]) + + SfpBase.__init__(self) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def __set_attr_value(self, attr_path, value): + + try: + with open(attr_path, 'r+') as reg_file: + reg_file.write(value) + except IOError as e: + logging.error("Error: unable to open file: '%s'" % str(e)) + return False + + return True + + def __is_host(self): + return os.system("docker > /dev/null 2>&1") == 0 + + def __get_path_to_port_config_file(self): + host_platform_root_path = '/usr/share/sonic/device' + docker_hwsku_path = '/usr/share/sonic/hwsku' + + host_platform_path = "/".join([host_platform_root_path, self.__platform]) + hwsku_path = "/".join([host_platform_path, self.__hwsku]) if self.__is_host() else docker_hwsku_path + + return "/".join([hwsku_path, "port_config.ini"]) + + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + eeprom_raw = [] + + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_eeprom_path = self.__eeprom_path + try: + with open(sysfs_eeprom_path, mode="rb", buffering=0) as sysfsfile_eeprom: + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + raw_len = len(raw) + for n in range(0, raw_len): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except (OSError, IOError): + logging.error("File error: %s", sysfs_eeprom_path) + return None + + return eeprom_raw + + def __write_eeprom_specific_bytes(self, offset, buffer): + sysfs_eeprom_path = self.__eeprom_path + + try: + with open(sysfs_eeprom_path, "r+b") as sysfsfile_eeprom: + sysfsfile_eeprom.seek(offset) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + logging.error("Error: unable to open file: '%s'" % str(e)) + return False + + return True + + def __convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + name = None + + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings(self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.__index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + presence = True + else: + raise SyntaxError + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + model = "N/A" + offset = INFO_OFFSET + sfpi_obj = sff8436InterfaceId() + if not self.get_presence() or not sfpi_obj: + return model + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + model = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + serial = "N/A" + offset = INFO_OFFSET + sfpi_obj = sff8436InterfaceId() + if not self.get_presence() or not sfpi_obj: + return serial + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + serial = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + tx_fault = self.get_tx_fault() + + if self.get_presence() and tx_fault and not any(tx_fault): + status = True + + return status + +############################################## +# SFP methods +############################################## + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + mominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + transceiver_info_dict_keys = ['type', 'hardwarerev', + 'serialnum', 'manufacturename', + 'modelname', 'Connector', + 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', + 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'vendor_date', + 'vendor_oui'] + + qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') + + qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', 'Fibre Channel transmission media', + 'Fibre Channel Speed') + + sfpi_obj = sff8436InterfaceId() + if not self.get_presence() or not sfpi_obj: + return {} + + offset = INFO_OFFSET + + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP) + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(transceiver_info_dict_keys, 'N/A') + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + compliance_code_dict = dict() + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + transceiver_dom_info_dict_keys = ['rx_los', 'tx_fault', + 'reset_status', 'power_lpmode', + 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', + 'rx1power', 'rx2power', + 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', + 'tx1power', 'tx2power', + 'tx3power', 'tx4power'] + + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not self.get_presence() or not sfpi_obj or not sfpd_obj: + return {} + + transceiver_dom_info_dict = dict.fromkeys(transceiver_dom_info_dict_keys, 'N/A') + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes((offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self.__convert_string_to_num(transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable() + transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + sfpd_obj = sff8436Dom() + if not self.get_presence() or not sfpd_obj: + return {} + + transceiver_dom_threshold_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A') + offset = THRE_OFFSET + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_channel_thres_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNEL_THRESHOLD_OFFSET), QSFP_CHANNEL_THRESHOLD_WIDTH) + channel_threshold_values = sfpd_obj.parse_channel_threshold_values(dom_channel_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + for key in transceiver_dom_threshold_dict: + transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key]) + + return transceiver_dom_threshold_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + + Returns: + A Boolean, True if reset enabled, False if disabled + """ + reset_status = False + attr_path = self.__reset_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + reset_status = True + else: + raise SyntaxError + + return reset_status + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los_list = [] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + + return rx_los_list + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault_list = [] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + + return tx_fault_list + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable = False + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return tx_disable + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value']) + tx_disable = tx_disable_list[0] or tx_disable_list[1] or tx_disable_list[2] or tx_disable_list[3] + + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_channel = 0 + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return tx_disable_channel + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value']) + + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disable_channel |= 1 << i + + return tx_disable_channel + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + lpmode = False + attr_path = self.__lpmode_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 1): + lpmode = True + else: + raise SyntaxError + + return lpmode + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + power_override = False + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return power_override + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + power_override = ('On' == dom_control_data['data']['PowerOverride']['value']) + + return power_override + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + + Returns: + An integer number of current temperature in Celsius + """ + temp = "N/A" + sfpd_obj = sff8436Dom() + offset = DOM_OFFSET + + if not self.get_presence() or not sfpd_obj: + return temp + + dom_temperature_raw = self.__read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self.__convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + + return temp + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + + Returns: + An integer number of supply voltage in mV + """ + voltage = "N/A" + sfpd_obj = sff8436Dom() + offset = DOM_OFFSET + + if not self.get_presence() or not sfpd_obj: + return voltage + + dom_voltage_raw = self.__read_eeprom_specific_bytes((offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self.__convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + + return voltage + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + tx_bias_list = [] + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + if not self.get_presence() or not sfpd_obj: + return [] + + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + + + if dom_channel_monitor_raw is not None: + tx_bias_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['TX4Bias']['value'])) + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + if not self.get_presence() or not sfpd_obj: + return [] + + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + + + if dom_channel_monitor_raw is not None: + rx_power_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['RX1Power']['value'])) + rx_power_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['RX2Power']['value'])) + rx_power_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['RX3Power']['value'])) + rx_power_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['RX4Power']['value'])) + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + if not self.get_presence() or not sfpd_obj: + return [] + + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + pass + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Power']['value'])) + + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + + Returns: + A boolean, True if successful, False if not + """ + + return self.__set_attr_value(self.__reset_attr, QSFP_REG_VALUE_ENABLE) + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + tx_disable_ctl = 0xf if tx_disable else 0x0 + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + + return self.__write_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, buffer) + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + + Returns: + A boolean, True if successful, False if not + """ + channel_state = self.get_tx_disable_channel() + if disable: + tx_disable_ctl = channel_state | channel + else: + tx_disable_ctl = channel_state & (~channel & 0xf) + + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + + return self.__write_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, buffer) + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + if lpmode is True: + reg_value = QSFP_REG_VALUE_ENABLE + else: + reg_value = QSFP_REG_VALUE_DISABLE + + return self.__set_attr_value(self.__lpmode_attr, reg_value) + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + + return self.__write_eeprom_specific_bytes(QSFP_POWEROVERRIDE_OFFSET, buffer) diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/thermal.py new file mode 100644 index 000000000000..ee1220a6c9fa --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/thermal.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python +# +# Name: thermal.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import logging + from sonic_platform_base.thermal_base import ThermalBase + from sonic_platform.inv_const import PsuConst, Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PSU1_THERMAL_START=9 +PSU2_THERMAL_START=12 + +class Thermal(ThermalBase): + + __core_temp_path = Common.INFO_PREFIX+"/coretemp/temp{}_input" + __switch_thermal_path = Common.INFO_PREFIX+"/board_thermal_{}/temp1_input" + __psu_thermal_path = Common.INFO_PREFIX+"/psu{}/temp{}_input" + __max_temp_path = Common.INFO_PREFIX+"/coretemp/temp{}_max" + __name_of_thermal = [ + "Core 0 Temperature", + "Core 1 Temperature", + "Core 2 Temperature", + "Core 3 Temperature", + "Core 4 Temperature", + "CPU Board Temperature", + "FrontSide Temperature", + "RearSide Temperature", + "NearASIC Temperature", + "PSU1 Temperature1", + "PSU1 Temperature2", + "PSU1 Temperature3", + "PSU2 Temperature1", + "PSU2 Temperature2", + "PSU2 Temperature3" + ] + __thermal_path_list = [ + __core_temp_path.format(1), + __core_temp_path.format(2), + __core_temp_path.format(3), + __core_temp_path.format(4), + __core_temp_path.format(5), + __switch_thermal_path.format(1), + __switch_thermal_path.format(2), + __switch_thermal_path.format(3), + __switch_thermal_path.format(4), + __psu_thermal_path.format(1,1), + __psu_thermal_path.format(1,2), + __psu_thermal_path.format(1,3), + __psu_thermal_path.format(2,1), + __psu_thermal_path.format(2,2), + __psu_thermal_path.format(2,3) + ] + __max_temp_path_list = [ + __max_temp_path.format(1), + __max_temp_path.format(2), + __max_temp_path.format(3), + __max_temp_path.format(4), + __max_temp_path.format(5), + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + + + def __init__(self, index): + self.__index = index + + self.__thermal_temp_attr = self.__thermal_path_list[self.__index] + self.__max_temp_attr = self.__max_temp_path_list[self.__index] + + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.__name_of_thermal[self.__index] + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence=False + + if (self.__index < PSU1_THERMAL_START): + attr_path = self.__thermal_temp_attr + presence=os.path.isfile(attr_path) + elif(self.__index < PSU2_THERMAL_START): + path="{}/i2c-inv_cpld/psu1".format(Common.I2C_PREFIX) + psu_state=self.__get_attr_value(path) + if (psu_state != 'ERR'): + if (psu_state == PsuConst.PSU_TYPE_LIST[0] or psu_state == PsuConst.PSU_TYPE_LIST[1]): + presence = True + else: + path="{}/i2c-inv_cpld/psu2".format(Common.I2C_PREFIX) + psu_state=self.__get_attr_value(path) + if (psu_state != 'ERR'): + if (psu_state == PsuConst.PSU_TYPE_LIST[0] or psu_state == PsuConst.PSU_TYPE_LIST[1]): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + raise NotImplementedError + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + raise NotImplementedError + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + if self.get_presence(): + status = True + + return status + +############################################## +# THERMAL methods +############################################## + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temperature = 0.0 + attr_path = self.__thermal_temp_attr + + if(self.get_presence()): + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + temperature = float(attr_rv) / 1000 + else: + raise SyntaxError + + return temperature + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + attr_path = self.__max_temp_attr + + if attr_path == '': + raise NotImplementedError + else: + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + high_threshold = float(attr_rv) / 1000 + else: + raise SyntaxError + + return high_threshold + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + raise NotImplementedError + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + raise NotImplementedError + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/watchdog.py new file mode 100644 index 000000000000..42718541f5c2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/watchdog.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +try: + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Watchdog(WatchdogBase): + def __init__(self): + print('init Watchdog()') + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* available + value. + Returns: + An integer specifying the *actual* number of seconds the watchdog + was armed with. On failure returns -1. + """ + raise NotImplementedError + + def disarm(self): + """ + Disarm the hardware watchdog + Returns: + A boolean, True if watchdog is disarmed successfully, False if not + """ + raise NotImplementedError + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + Returns: + A boolean, True if watchdog is armed, False if not + """ + raise NotImplementedError + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds remaining on + the watchdog timer + Returns: + An integer specifying the number of seconds remaining on thei + watchdog timer. If the watchdog is not armed, returns -1. + """ + raise NotImplementedError + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/utils/inventec_d6332_util.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/utils/inventec_d6332_util.py new file mode 100755 index 000000000000..a468a323d6fc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/utils/inventec_d6332_util.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Inventec, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes +""" + +import os +import commands +import sys, getopt +import logging +import syslog +import time + +DEBUG = False +args = [] +FORCE = 0 +FAN_VPD_CHANNEL= 1 +FAN_VPD_ADDR_BASE=0x52 +FAN_NUM=5 +RETRY_LIMIT = 5 +i2c_prefix = '/sys/bus/i2c/devices/' + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV: ', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + install() + elif arg == 'clean': + uninstall() + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_log(txt): + if DEBUG == True: + print "[D6332]"+txt + return + +def exec_cmd(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + show_log (cmd +" with result:" + str(status)) + show_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def link_dir(prefix,dst): + retry=0 + ret=False + while(ret==False and retry /sys/bus/i2c/devices/i2c-0/new_device' +#'echo inv_cpld 0x33 > /sys/bus/i2c/devices/i2c-0/i2c-2/new_device', +#'echo inv_cpld 0x77 > /sys/bus/i2c/devices/i2c-0/i2c-2/new_device' +] + + +drivers =[ +#kernel-dirvers +'gpio_ich', +'lpc_ich', +'i2c-i801', +'i2c-mux', +'i2c-mux-pca954x', +'i2c-mux-pca9541', +'i2c-dev', +'ucd9000', +#inv-modules +'inv_eeprom', +'inv_cpld', +'lm75', +'inv_platform', +#'monitor', +'swps'] + + +# Modify for fast-reboot +def system_install(boot_option): + global FORCE + + #remove default drivers to avoid modprobe order conflicts + status, output = exec_cmd("rmmod i2c_ismt ", 1) + if status: + print output + if FORCE == 0: + return status + + status, output = exec_cmd("rmmod i2c-i801 ", 1) + if status: + print output + if FORCE == 0: + return status + + status, output = exec_cmd("rmmod gpio_ich ", 1) + if status: + print output + if FORCE == 0: + return status + + status, output = exec_cmd("rmmod lpc_ich ", 1) + if status: + print output + if FORCE == 0: + return status + + #insert extra module + #status, output = exec_cmd("insmod /lib/modules/4.9.0-9-2-amd64/kernel/drivers/gpio/gpio-ich.ko gpiobase=0",1) + + #install drivers + ''' boot_option: 0 - normal, 1 - fast-reboot''' + for i in range(0,len(drivers)): + if drivers[i] == "swps": + if boot_option == 1: + status, output = exec_cmd("modprobe swps io_no_init=1", 1) + else: + status, output = exec_cmd("modprobe "+drivers[i], 1) + else: + status, output = exec_cmd("modprobe "+drivers[i], 1) + + if status: + print output + if FORCE == 0: + return status + + #instantiate devices + for i in range(0,len(instantiate)): + #time.sleep(1) + status, output = exec_cmd(instantiate[i], 1) + if status: + print output + if FORCE == 0: + return status + for addr_offset in range (0,FAN_NUM): + addr=FAN_VPD_ADDR_BASE+addr_offset + cmd = "i2cdetect -y "+str(FAN_VPD_CHANNEL)+" "+str(addr)+" "+str(addr)+" | grep "+str(hex(addr)).replace('0x','') + result=os.system(cmd) + if( result==0 ): + cmd="echo inv_eeprom "+str(addr)+" > /sys/bus/i2c/devices/i2c-"+FAN_VPD_CHANNEL + status, output = exec_cmd(cmd,1) + if status: + print output + if FORCE == 0: + return status +# +# INV_FIX-4037 +# It replaces the original sff8436 driver with the optoe driver +# + #optoe map to i2c-bus\ + for i in range(12,20): + cmd="echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-0/i2c-4/i2c-"+str(i)+"/new_device" + status, output =exec_cmd(cmd,1) + if status: + print output + if FORCE == 0: + return status + for i in range(20,28): + status, output =exec_cmd("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-0/i2c-5/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + for i in range(28,36): + status, output =exec_cmd("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-0/i2c-6/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + for i in range(36,44): + status, output =exec_cmd("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-0/i2c-7/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + #make softlink for device info + for i in range(0,len(_path_prefix_list)): + if( os.path.islink(_path_dst_list[i]) ): + os.unlink(_path_dst_list[i]) + syslog.syslog(syslog.LOG_WARNING, "Path %s exists, remove before link again" % _path_dst_list[i] ) + link_dir(_path_prefix_list[i],_path_dst_list[i]) + + return + + +def system_ready(): + if not device_found(): + return False + return True + +def install(boot_option=0): + ''' boot_option: 0 - normal, 1 - fast-reboot ''' + if not device_found(): + print "No device, installing...." + status = system_install(boot_option) + if status: + if FORCE == 0: + return status + else: + print "D6332 devices detected...." + return + +def uninstall(): + global FORCE + #uninstall drivers + for i in range(len(drivers)-1,-1,-1): + status, output = exec_cmd("rmmod "+drivers[i], 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_found(): + ret1, log = exec_cmd("ls "+i2c_prefix+"*0072", 0) + ret2, log = exec_cmd("ls "+i2c_prefix+"i2c-5", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index 9360f9226652..d5ba6b0869e8 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -2,7 +2,7 @@ Source: sonic-inventec-platform-modules Section: main Priority: extra Maintainer: Inventec -Build-Depends: debhelper (>= 8.0.0), bzip2 +Build-Depends: debhelper (>= 8.0.0), bzip2, dh-python Standards-Version: 3.9.3 Package: platform-modules-d7032q28b @@ -34,3 +34,8 @@ Package: platform-modules-d7264q28b Architecture: amd64 Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led + +Package: platform-modules-d6332 +Architecture: amd64 +Depends: linux-image-4.19.0-9-2-amd64-unsigned +Description: kernel modules for platform devices such as fan, led diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.init b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.init new file mode 100644 index 000000000000..9b14421a1324 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.init @@ -0,0 +1,74 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup Inventec d6356j board. +### END INIT INFO + +PLATFORM_DIR=/usr/share/sonic/device/x86_64-inventec_d6332-r0/plugins +PLUGIN_DIR=/usr/lib/python2.7/dist-packages/inventec_plugin + +PLATFORM_DAEMON=$PLATFORM_DIR/platfmgr.py +PLATFORM_DAEMON_NAME=platfmgr +INVSYNCD_DAEMON=$PLUGIN_DIR/invSyncd.py +INVSYNCD_DAEMON_NAME=invSyncd + +# The process ID of the script when it runs is stored here: +PLATFORM_PIDFILE=/var/run/$PLATFORM_DAEMON_NAME.pid + +do_monitor_start() { + /sbin/start-stop-daemon --quiet --oknodo --pidfile $PLATFORM_PIDFILE --make-pidfile --startas $PLATFORM_DAEMON --start --background -- $DAEMON_OPTS + /sbin/start-stop-daemon --quiet --oknodo --pidfile $INVSYNCD_PIDFILE --make-pidfile --startas $INVSYNCD_DAEMON --start --background -- $DAEMON_OPTS +} + +do_monitor_stop() { + /sbin/start-stop-daemon --quiet --oknodo --stop --pidfile $PLATFORM_PIDFILE --retry 10 + /sbin/start-stop-daemon --quiet --oknodo --stop --pidfile $INVSYNCD_PIDFILE --retry 10 +} + +# Check Fast-Reboot cause +FAST_REBOOT='no' +case "$(cat /proc/cmdline)" in + *fast-reboot*|*warm*) + FAST_REBOOT='yes' + ;; + *) + FAST_REBOOT='no' + ;; +esac + +case "$1" in +start) + echo -n "Setting up board... " + if [ "$FAST_REBOOT" = "yes" ] ; then + /usr/local/bin/inventec_d6332_util.py -f fast-reboot-install + else + /usr/local/bin/inventec_d6332_util.py -f install + fi + do_monitor_${1} + echo "done." + ;; + +stop) + /usr/local/bin/inventec_d6332_util.py -f clean + do_monitor_${1} + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-d6332.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.install b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.install new file mode 100644 index 000000000000..d21e85a86e1e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.install @@ -0,0 +1,4 @@ +d6332/utils/inventec_d6332_util.py /usr/local/bin +systemd/platform-modules-d6332.service /lib/systemd/system +d6332/utils/sonic_platform-1.0-py2-none-any.whl /usr/share/sonic/device/x86_64-inventec_d6332-r0 +d6332/utils/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-inventec_d6332-r0 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.postinst b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.postinst new file mode 100644 index 000000000000..dff0ecc8522e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.postinst @@ -0,0 +1,25 @@ +#!/bin/sh +# Automatically added by dh_systemd_enable +# This will only remove masks created by d-s-h on package removal. +deb-systemd-helper unmask platform-modules-d6356j.service >/dev/null || true + +# was-enabled defaults to true, so new installations run enable. +if deb-systemd-helper --quiet was-enabled platform-modules-d6332.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable platform-modules-d6332.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state platform-modules-d6332.service >/dev/null || true +fi +# End automatically added section +depmod -a +# Automatically added by dh_installinit +if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ]; then + if [ -x "/etc/init.d/platform-modules-d6332" ]; then + update-rc.d platform-modules-d6332 defaults >/dev/null + invoke-rc.d platform-modules-d6332 start || exit $? + fi +fi +# End automatically added section diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/rules b/platform/broadcom/sonic-platform-modules-inventec/debian/rules index f6c1aa1b2e70..0044efbba491 100755 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/rules +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/rules @@ -14,7 +14,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b +MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b d6332 %: dh $@ --with python2,systemd @@ -22,11 +22,17 @@ MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ - if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ]; then \ + if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ] || [ $$mod = "d6332" ]; then \ cd $(MOD_SRC_DIR)/$${mod}; \ python2 setup.py build; \ python2 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/utils; \ cd $(MOD_SRC_DIR); \ + fi; \ + if [ $$mod = "d6332" ]; then \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python3 setup.py build; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/utils; \ + cd $(MOD_SRC_DIR); \ fi \ done) @@ -36,10 +42,15 @@ override_dh_auto_install: $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ]; then \ + if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ] || [ $$mod = "d6332" ]; then \ cd $(MOD_SRC_DIR)/$${mod}; \ python2 setup.py install --root=$(MOD_SRC_DIR)/debian/platform-modules-$${mod} --install-layout=deb; \ cd $(MOD_SRC_DIR); \ + fi; \ + if [ $$mod = "d6332" ]; then \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python3 setup.py install --root=$(MOD_SRC_DIR)/debian/platform-modules-$${mod} --install-layout=deb; \ + cd $(MOD_SRC_DIR); \ fi \ done) diff --git a/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6332.service b/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6332.service new file mode 100644 index 000000000000..1cbe712da280 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6332.service @@ -0,0 +1,13 @@ +[Unit] +Description=Inventec d6332 Platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-d6332 start +ExecStop=-/etc/init.d/platform-modules-d6332 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target From 207587d97c5f8784226d1413ab1d6b4c2af82045 Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Tue, 20 Oct 2020 11:52:46 -0700 Subject: [PATCH 1264/1427] [docker-base]: Rate limit priority INFO and lower in syslog (#5666) There is currently a bug where messages from swss with priority lower than the current log level are still being counted against the syslog rate limiting threshhold. This leads to rate-limiting in syslog when the rate-limiting conditions have not been met, which causes several sonic-mgmt tests to fail since they are dependent on LogAnalyzer. It also omits potentially useful information from the syslog. Only rate-limiting messages of level INFO and lower allows these tests to pass successfully. Signed-off-by: Lawrence Lee --- dockers/docker-base-buster/etc/rsyslog.conf | 3 ++- dockers/docker-base-stretch/etc/rsyslog.conf | 3 ++- dockers/docker-base/etc/rsyslog.conf | 3 ++- files/image_config/rsyslog/rsyslog-container.conf.j2 | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/dockers/docker-base-buster/etc/rsyslog.conf b/dockers/docker-base-buster/etc/rsyslog.conf index ef249229ab1e..81e328f99d8a 100644 --- a/dockers/docker-base-buster/etc/rsyslog.conf +++ b/dockers/docker-base-buster/etc/rsyslog.conf @@ -12,10 +12,11 @@ $ModLoad imuxsock # provides support for local system logging # -# Set a rate limit on messages from the container +# Set a rate limit on messages from the container of priority INFO or lower (level 6 and above) # $SystemLogRateLimitInterval 300 $SystemLogRateLimitBurst 20000 +$SystemLogRateLimitSeverity 6 #$ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability diff --git a/dockers/docker-base-stretch/etc/rsyslog.conf b/dockers/docker-base-stretch/etc/rsyslog.conf index ef249229ab1e..81e328f99d8a 100644 --- a/dockers/docker-base-stretch/etc/rsyslog.conf +++ b/dockers/docker-base-stretch/etc/rsyslog.conf @@ -12,10 +12,11 @@ $ModLoad imuxsock # provides support for local system logging # -# Set a rate limit on messages from the container +# Set a rate limit on messages from the container of priority INFO or lower (level 6 and above) # $SystemLogRateLimitInterval 300 $SystemLogRateLimitBurst 20000 +$SystemLogRateLimitSeverity 6 #$ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability diff --git a/dockers/docker-base/etc/rsyslog.conf b/dockers/docker-base/etc/rsyslog.conf index 4851ac784475..3964cffb9e30 100644 --- a/dockers/docker-base/etc/rsyslog.conf +++ b/dockers/docker-base/etc/rsyslog.conf @@ -16,10 +16,11 @@ $ModLoad imuxsock # provides support for local system logging # -# Set a rate limit on messages from the container +# Set a rate limit on messages from the container of priority INFO or lower (level 6 and above) # $SystemLogRateLimitInterval 300 $SystemLogRateLimitBurst 20000 +$SystemLogRateLimitSeverity 6 #$ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability diff --git a/files/image_config/rsyslog/rsyslog-container.conf.j2 b/files/image_config/rsyslog/rsyslog-container.conf.j2 index d17fbb6767ba..3d7009241bd6 100644 --- a/files/image_config/rsyslog/rsyslog-container.conf.j2 +++ b/files/image_config/rsyslog/rsyslog-container.conf.j2 @@ -12,10 +12,11 @@ $ModLoad imuxsock # provides support for local system logging # -# Set a rate limit on messages from the container +# Set a rate limit on messages from the container of priority INFO or lower (level 6 and above) # $SystemLogRateLimitInterval 300 $SystemLogRateLimitBurst 20000 +$SystemLogRateLimitSeverity 6 #$ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability From ca7a4a4e3a5f0bc33edb0eed224ef79920a33696 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Wed, 21 Oct 2020 13:08:06 +0800 Subject: [PATCH 1265/1427] [Mellanox] Fix issue: read data from eeprom should trim tail \0 (#5670) Now we are reading base mac, product name from eeprom data, and the data read from eeprom contains multiple "\0" characters at the end, need trim them to make the string clean and display correct. --- .../mellanox/mlnx-platform-api/sonic_platform/eeprom.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py index 7673c9130f48..6557a6c4ba63 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py @@ -82,18 +82,26 @@ def _load_eeprom(self): self._base_mac = self.mgmtaddrstr(eeprom) if self._base_mac is None: self._base_mac = "Undefined." + else: + self._base_mac = self._base_mac.strip('\0') self._serial_str = self.serial_number_str(eeprom) if self._serial_str is None: self._serial_str = "Undefined." + else: + self._serial_str = self._serial_str.strip('\0') self._product_name = self.modelstr(eeprom) if self._product_name is None: self._product_name = "Undefined." + else: + self._product_name = self._product_name.strip('\0') self._part_number = self.part_number_str(eeprom) if self._part_number is None: self._part_number = "Undefined." + else: + self._part_number = self._part_number.strip('\0') original_stdout = sys.stdout sys.stdout = StringIO() From 29928c93a16bbe4ae8c3f66acf21ad304b3f3309 Mon Sep 17 00:00:00 2001 From: BrynXu Date: Wed, 21 Oct 2020 01:40:04 -0700 Subject: [PATCH 1266/1427] [chassis]: Use correct path for chassisdb.conf file (#5632) use correct chassisdb.conf path while bringing up chassis_db service on VoQ modular switch.chassis_db service on VoQ modular switch. resolves #5631 Signed-off-by: Honggang Xu --- dockers/docker-database/docker-database-init.sh | 2 +- files/build_templates/docker_image_ctl.j2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dockers/docker-database/docker-database-init.sh b/dockers/docker-database/docker-database-init.sh index babb9f7924a0..bc49376a0b53 100755 --- a/dockers/docker-database/docker-database-init.sh +++ b/dockers/docker-database/docker-database-init.sh @@ -39,7 +39,7 @@ fi start_chassis_db=0 chassis_db_address="" chassis_db_port="" -chassisdb_config="/etc/sonic/chassisdb.conf" +chassisdb_config="/usr/share/sonic/platform/chassisdb.conf" [ -f $chassisdb_config ] && source $chassisdb_config db_cfg_file="/var/run/redis/sonic-db/database_config.json" diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 4d3e795c500e..62846354fd08 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -253,7 +253,7 @@ start() { {%- if docker_container_name == "database" %} start_chassis_db=0 chassis_db_address="" - chassisdb_config="/etc/sonic/chassisdb.conf" + chassisdb_config="/usr/share/sonic/device/$PLATFORM/chassisdb.conf" [ -f $chassisdb_config ] && source $chassisdb_config DB_OPT=" -v /var/run/redis-chassis:/var/run/redis-chassis:ro " if [[ "$start_chassis_db" != "1" ]] && [[ -z "$chassis_db_address" ]]; then From 97b33e4da3fe41138685676958bab7855ec6e61a Mon Sep 17 00:00:00 2001 From: Srideep Date: Wed, 21 Oct 2020 12:10:50 -0600 Subject: [PATCH 1267/1427] [devices]: DellEMC new platform support for DellEMC s5296f- 96x25G (#3960) Added files, driver, npu configs for the DellEMC S5296f platform --- .../DellEMC-S5296f-P-10G/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 46 + .../buffers_defaults_t1.j2 | 46 + .../DellEMC-S5296f-P-10G/custom_led.bin | Bin 0 -> 412 bytes .../DellEMC-S5296f-P-10G/linkscan_led_fw.bin | Bin 0 -> 4752 bytes .../DellEMC-S5296f-P-10G/port_config.ini | 105 ++ .../DellEMC-S5296f-P-10G/qos.json.j2 | 226 +++ .../DellEMC-S5296f-P-10G/sai.profile | 1 + .../DellEMC-S5296f-P-10G/sai_preinit_cmd.soc | 2 + .../td3-s5296f-10g.config.bcm | 595 ++++++ .../DellEMC-S5296f-P-25G/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 46 + .../buffers_defaults_t1.j2 | 46 + .../DellEMC-S5296f-P-25G/custom_led.bin | Bin 0 -> 412 bytes .../DellEMC-S5296f-P-25G/linkscan_led_fw.bin | Bin 0 -> 4752 bytes .../DellEMC-S5296f-P-25G/port_config.ini | 105 ++ .../DellEMC-S5296f-P-25G/qos.json.j2 | 226 +++ .../DellEMC-S5296f-P-25G/sai.profile | 1 + .../DellEMC-S5296f-P-25G/sai_preinit_cmd.soc | 2 + .../td3-s5296f-25g.config.bcm | 595 ++++++ .../default_sku | 1 + .../installer.conf | 2 + .../led_proc_init.soc | 6 + .../media_settings.json | 442 +++++ .../plugins/eeprom.py | 32 + .../plugins/psuutil.py | 98 + .../plugins/sfputil.py | 554 ++++++ .../pmon_daemon_control.json | 8 + platform/broadcom/one-image.mk | 1 + platform/broadcom/platform-modules-dell.mk | 6 + .../debian/control | 5 + .../debian/platform-modules-s5296f.init | 39 + .../debian/platform-modules-s5296f.install | 9 + .../debian/platform-modules-s5296f.postinst | 10 + .../sonic-platform-modules-dell/debian/rules | 2 +- .../s5296f/cfg/s5296f-modules.conf | 19 + .../s5296f/modules/Makefile | 2 + .../s5296f/modules/dell_s5296f_fpga_ocores.c | 1626 +++++++++++++++++ .../s5296f/scripts/pcisysfs.py | 102 ++ .../s5296f/scripts/platform_sensors.py | 242 +++ .../s5296f/scripts/qsfp_irq_enable.py | 31 + .../s5296f/scripts/s5296f_platform.sh | 176 ++ .../s5296f/scripts/sensors | 3 + .../systemd/platform-modules-s5296f.service | 13 + 44 files changed, 5474 insertions(+), 1 deletion(-) create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t0.j2 create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/custom_led.bin create mode 100755 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/linkscan_led_fw.bin create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/port_config.ini create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/qos.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai.profile create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/td3-s5296f-10g.config.bcm create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t0.j2 create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/custom_led.bin create mode 100755 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/linkscan_led_fw.bin create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/port_config.ini create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/qos.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai.profile create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/td3-s5296f-25g.config.bcm create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/default_sku create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/installer.conf create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/led_proc_init.soc create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/media_settings.json create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/eeprom.py create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/psuutil.py create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/sfputil.py create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/pmon_daemon_control.json create mode 100755 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.init create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.install create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.postinst create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/cfg/s5296f-modules.conf create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/modules/dell_s5296f_fpga_ocores.c create mode 100755 platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/pcisysfs.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/platform_sensors.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/qsfp_irq_enable.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/s5296f_platform.sh create mode 100755 platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/sensors create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/systemd/platform-modules-s5296f.service diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers.json.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t0.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/custom_led.bin b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..302a41d9789a8bd16c80bff104794fb13b095914 GIT binary patch literal 412 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 X`cUsHXR!vGk^Z4y?GFw9z}SBSTZoUr literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/port_config.ini b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/port_config.ini new file mode 100644 index 000000000000..f16b3e656a18 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/port_config.ini @@ -0,0 +1,105 @@ +# name lanes alias index speed +Ethernet0 5 tenGigE1/1/1 1 10000 +Ethernet1 6 tenGigE1/1/2 2 10000 +Ethernet2 7 tenGigE1/1/3 3 10000 +Ethernet3 8 tenGigE1/1/4 4 10000 +Ethernet4 13 tenGigE1/2/1 5 10000 +Ethernet5 14 tenGigE1/2/2 6 10000 +Ethernet6 15 tenGigE1/2/3 7 10000 +Ethernet7 16 tenGigE1/2/4 8 10000 +Ethernet8 17 tenGigE1/3/1 9 10000 +Ethernet9 18 tenGigE1/3/2 10 10000 +Ethernet10 19 tenGigE1/3/3 11 10000 +Ethernet11 20 tenGigE1/3/4 12 10000 +Ethernet12 37 tenGigE1/4/1 13 10000 +Ethernet13 38 tenGigE1/4/2 14 10000 +Ethernet14 39 tenGigE1/4/3 15 10000 +Ethernet15 40 tenGigE1/4/4 16 10000 +Ethernet16 45 tenGigE1/5/1 17 10000 +Ethernet17 46 tenGigE1/5/2 18 10000 +Ethernet18 47 tenGigE1/5/3 19 10000 +Ethernet19 48 tenGigE1/5/4 20 10000 +Ethernet20 53 tenGigE1/6/1 21 10000 +Ethernet21 54 tenGigE1/6/2 22 10000 +Ethernet22 55 tenGigE1/6/3 23 10000 +Ethernet23 56 tenGigE1/6/4 24 10000 +Ethernet24 65 tenGigE1/7/1 25 10000 +Ethernet25 66 tenGigE1/7/2 26 10000 +Ethernet26 67 tenGigE1/7/3 27 10000 +Ethernet27 68 tenGigE1/7/4 28 10000 +Ethernet28 73 tenGigE1/8/1 29 10000 +Ethernet29 74 tenGigE1/8/2 30 10000 +Ethernet30 75 tenGigE1/8/3 31 10000 +Ethernet31 76 tenGigE1/8/4 32 10000 +Ethernet32 89 tenGigE1/9/1 33 10000 +Ethernet33 90 tenGigE1/9/2 34 10000 +Ethernet34 91 tenGigE1/9/3 35 10000 +Ethernet35 92 tenGigE1/9/4 36 10000 +Ethernet36 101 tenGigE1/10/1 37 10000 +Ethernet37 102 tenGigE1/10/2 38 10000 +Ethernet38 103 tenGigE1/10/3 39 10000 +Ethernet39 104 tenGigE1/10/4 40 10000 +Ethernet40 109 tenGigE1/11/1 41 10000 +Ethernet41 110 tenGigE1/11/2 42 10000 +Ethernet42 111 tenGigE1/11/3 43 10000 +Ethernet43 112 tenGigE1/11/4 44 10000 +Ethernet44 117 tenGigE1/12/1 45 10000 +Ethernet45 118 tenGigE1/12/2 46 10000 +Ethernet46 119 tenGigE1/12/3 47 10000 +Ethernet47 120 tenGigE1/12/4 48 10000 +Ethernet48 1 tenGigE1/13/1 49 10000 +Ethernet49 2 tenGigE1/13/2 50 10000 +Ethernet50 3 tenGigE1/13/3 51 10000 +Ethernet51 4 tenGigE1/13/4 52 10000 +Ethernet52 9 tenGigE1/14/1 53 10000 +Ethernet53 10 tenGigE1/14/2 54 10000 +Ethernet54 11 tenGigE1/14/3 55 10000 +Ethernet55 12 tenGigE1/14/4 56 10000 +Ethernet56 25 tenGigE1/15/1 57 10000 +Ethernet57 26 tenGigE1/15/2 58 10000 +Ethernet58 27 tenGigE1/15/3 59 10000 +Ethernet59 28 tenGigE1/15/4 60 10000 +Ethernet60 33 tenGigE1/16/1 61 10000 +Ethernet61 34 tenGigE1/16/2 62 10000 +Ethernet62 35 tenGigE1/16/3 63 10000 +Ethernet63 36 tenGigE1/16/4 64 10000 +Ethernet64 41 tenGigE1/17/1 65 10000 +Ethernet65 42 tenGigE1/17/2 66 10000 +Ethernet66 43 tenGigE1/17/3 67 10000 +Ethernet67 44 tenGigE1/17/4 68 10000 +Ethernet68 49 tenGigE1/18/1 69 10000 +Ethernet69 50 tenGigE1/18/2 70 10000 +Ethernet70 51 tenGigE1/18/3 71 10000 +Ethernet71 52 tenGigE1/18/4 72 10000 +Ethernet72 69 tenGigE1/19/1 73 10000 +Ethernet73 70 tenGigE1/19/2 74 10000 +Ethernet74 71 tenGigE1/19/3 75 10000 +Ethernet75 72 tenGigE1/19/4 76 10000 +Ethernet76 77 tenGigE1/20/1 77 10000 +Ethernet77 78 tenGigE1/20/2 78 10000 +Ethernet78 79 tenGigE1/20/3 79 10000 +Ethernet79 80 tenGigE1/20/4 80 10000 +Ethernet80 81 tenGigE1/21/1 81 10000 +Ethernet81 82 tenGigE1/21/2 82 10000 +Ethernet82 83 tenGigE1/21/3 83 10000 +Ethernet83 84 tenGigE1/21/4 84 10000 +Ethernet84 97 tenGigE1/22/1 85 10000 +Ethernet85 98 tenGigE1/22/2 86 10000 +Ethernet86 99 tenGigE1/22/3 87 10000 +Ethernet87 100 tenGigE1/22/4 88 10000 +Ethernet88 105 tenGigE1/23/1 89 10000 +Ethernet89 106 tenGigE1/23/2 90 10000 +Ethernet90 107 tenGigE1/23/3 91 10000 +Ethernet91 108 tenGigE1/23/4 92 10000 +Ethernet92 113 tenGigE1/24/1 93 10000 +Ethernet93 114 tenGigE1/24/2 94 10000 +Ethernet94 115 tenGigE1/24/3 95 10000 +Ethernet95 116 tenGigE1/24/4 96 10000 +Ethernet96 29,30,31,32 hundredGigE1/49 97 100000 +Ethernet97 21,22,23,24 hundredGigE1/50 98 100000 +Ethernet98 125,126,127,128 hundredGigE1/51 99 100000 +Ethernet99 85,86,87,88 hundredGigE1/52 100 100000 +Ethernet100 57,58,59,60 hundredGigE1/53 101 100000 +Ethernet101 61,62,63,64 hundredGigE1/54 102 100000 +Ethernet102 121,122,123,124 hundredGigE1/55 103 100000 +Ethernet103 93,94,95,96 hundredGigE1/56 104 100000 diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/qos.json.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/qos.json.j2 new file mode 100644 index 000000000000..d2b3d2b0131c --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/qos.json.j2 @@ -0,0 +1,226 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "0", + "4": "0", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "DWRR", + "weight": "50" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai.profile b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai.profile new file mode 100644 index 000000000000..f12601115339 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5296f-10g.config.bcm diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/td3-s5296f-10g.config.bcm b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/td3-s5296f-10g.config.bcm new file mode 100644 index 000000000000..7351e6908e78 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/td3-s5296f-10g.config.bcm @@ -0,0 +1,595 @@ +os=unix +portmap_5.0=5:10 +portmap_6.0=6:10 +portmap_7.0=7:10 +portmap_8.0=8:10 +portmap_13.0=13:10 +portmap_14.0=14:10 +portmap_15.0=15:10 +portmap_16.0=16:10 +portmap_17.0=17:10 +portmap_18.0=18:10 +portmap_19.0=19:10 +portmap_20.0=20:10 +portmap_37.0=37:10 +portmap_38.0=38:10 +portmap_39.0=39:10 +portmap_40.0=40:10 +portmap_45.0=45:10 +portmap_46.0=46:10 +portmap_47.0=47:10 +portmap_48.0=48:10 +portmap_53.0=53:10 +portmap_54.0=54:10 +portmap_55.0=55:10 +portmap_56.0=56:10 +portmap_67.0=65:10 +portmap_68.0=66:10 +portmap_69.0=67:10 +portmap_70.0=68:10 +portmap_75.0=73:10 +portmap_76.0=74:10 +portmap_77.0=75:10 +portmap_78.0=76:10 +portmap_91.0=89:10 +portmap_92.0=90:10 +portmap_93.0=91:10 +portmap_94.0=92:10 +portmap_103.0=101:10 +portmap_104.0=102:10 +portmap_105.0=103:10 +portmap_106.0=104:10 +portmap_111.0=109:10 +portmap_112.0=110:10 +portmap_113.0=111:10 +portmap_114.0=112:10 +portmap_119.0=117:10 +portmap_120.0=118:10 +portmap_121.0=119:10 +portmap_122.0=120:10 +portmap_1.0=1:10 +portmap_2.0=2:10 +portmap_3.0=3:10 +portmap_4.0=4:10 +portmap_9.0=9:10 +portmap_10.0=10:10 +portmap_11.0=11:10 +portmap_12.0=12:10 +portmap_25.0=25:10 +portmap_26.0=26:10 +portmap_27.0=27:10 +portmap_28.0=28:10 +portmap_33.0=33:10 +portmap_34.0=34:10 +portmap_35.0=35:10 +portmap_36.0=36:10 +portmap_41.0=41:10 +portmap_42.0=42:10 +portmap_43.0=43:10 +portmap_44.0=44:10 +portmap_49.0=49:10 +portmap_50.0=50:10 +portmap_51.0=51:10 +portmap_52.0=52:10 +portmap_71.0=69:10 +portmap_72.0=70:10 +portmap_73.0=71:10 +portmap_74.0=72:10 +portmap_79.0=77:10 +portmap_80.0=78:10 +portmap_81.0=79:10 +portmap_82.0=80:10 +portmap_83.0=81:10 +portmap_84.0=82:10 +portmap_85.0=83:10 +portmap_86.0=84:10 +portmap_99.0=97:10 +portmap_100.0=98:10 +portmap_101.0=99:10 +portmap_102.0=100:10 +portmap_107.0=105:10 +portmap_108.0=106:10 +portmap_109.0=107:10 +portmap_110.0=108:10 +portmap_115.0=113:10 +portmap_116.0=114:10 +portmap_117.0=115:10 +portmap_118.0=116:10 +portmap_29.0=29:100 +portmap_21.0=21:100 +portmap_127.0=125:100 +portmap_87.0=85:100 +portmap_57.0=57:100 +portmap_61.0=61:100 +portmap_123.0=121:100 +portmap_95.0=93:100 +phy_chain_tx_lane_map_physical{5.0}=0x0123 +phy_chain_rx_lane_map_physical{5.0}=0x0123 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x0123 +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x0123 +phy_chain_tx_lane_map_physical{37.0}=0x0123 +phy_chain_rx_lane_map_physical{37.0}=0x0123 +phy_chain_tx_lane_map_physical{45.0}=0x0123 +phy_chain_rx_lane_map_physical{45.0}=0x0123 +phy_chain_tx_lane_map_physical{53.0}=0x0123 +phy_chain_rx_lane_map_physical{53.0}=0x0123 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x3210 +phy_chain_tx_lane_map_physical{73.0}=0x3210 +phy_chain_rx_lane_map_physical{73.0}=0x3210 +phy_chain_tx_lane_map_physical{89.0}=0x3210 +phy_chain_rx_lane_map_physical{89.0}=0x3210 +phy_chain_tx_lane_map_physical{101.0}=0x3210 +phy_chain_rx_lane_map_physical{101.0}=0x3210 +phy_chain_tx_lane_map_physical{109.0}=0x3210 +phy_chain_rx_lane_map_physical{109.0}=0x3210 +phy_chain_tx_lane_map_physical{117.0}=0x3210 +phy_chain_rx_lane_map_physical{117.0}=0x3210 +phy_chain_tx_lane_map_physical{1.0}=0x1032 +phy_chain_rx_lane_map_physical{1.0}=0x1032 +phy_chain_tx_lane_map_physical{9.0}=0x1032 +phy_chain_rx_lane_map_physical{9.0}=0x1032 +phy_chain_tx_lane_map_physical{25.0}=0x1032 +phy_chain_rx_lane_map_physical{25.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x1032 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x1032 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_rx_lane_map_physical{49.0}=0x2031 +phy_chain_tx_lane_map_physical{69.0}=0x2301 +phy_chain_rx_lane_map_physical{69.0}=0x2301 +phy_chain_tx_lane_map_physical{77.0}=0x1302 +phy_chain_rx_lane_map_physical{77.0}=0x1302 +phy_chain_tx_lane_map_physical{81.0}=0x2301 +phy_chain_rx_lane_map_physical{81.0}=0x2301 +phy_chain_tx_lane_map_physical{97.0}=0x2301 +phy_chain_rx_lane_map_physical{97.0}=0x2301 +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_rx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{113.0}=0x2301 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x3201 +phy_chain_tx_lane_map_physical{21.0}=0x3021 +phy_chain_rx_lane_map_physical{21.0}=0x0312 +phy_chain_tx_lane_map_physical{125.0}=0x3210 +phy_chain_rx_lane_map_physical{125.0}=0x0132 +phy_chain_tx_lane_map_physical{85.0}=0x0312 +phy_chain_rx_lane_map_physical{85.0}=0x3021 +phy_chain_tx_lane_map_physical{57.0}=0x3021 +phy_chain_rx_lane_map_physical{57.0}=0x0312 +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x1230 +phy_chain_tx_lane_map_physical{121.0}=0x0123 +phy_chain_rx_lane_map_physical{121.0}=0x2310 +phy_chain_tx_lane_map_physical{93.0}=0x0123 +phy_chain_rx_lane_map_physical{93.0}=0x2301 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x1 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x1 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_tx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x1 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_rx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_rx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x1 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_tx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_tx_polarity_flip_physical{80.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_tx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x1 +phy_chain_tx_polarity_flip_physical{108.0}=0x1 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_tx_polarity_flip_physical{116.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +dport_map_enable=1 +dport_map_port_5=1 +dport_map_port_6=2 +dport_map_port_7=3 +dport_map_port_8=4 +dport_map_port_13=5 +dport_map_port_14=6 +dport_map_port_15=7 +dport_map_port_16=8 +dport_map_port_17=9 +dport_map_port_18=10 +dport_map_port_19=11 +dport_map_port_20=12 +dport_map_port_37=13 +dport_map_port_38=14 +dport_map_port_39=15 +dport_map_port_40=16 +dport_map_port_45=17 +dport_map_port_46=18 +dport_map_port_47=19 +dport_map_port_48=20 +dport_map_port_53=21 +dport_map_port_54=22 +dport_map_port_55=23 +dport_map_port_56=24 +dport_map_port_67=25 +dport_map_port_68=26 +dport_map_port_69=27 +dport_map_port_70=28 +dport_map_port_75=29 +dport_map_port_76=30 +dport_map_port_77=31 +dport_map_port_78=32 +dport_map_port_91=33 +dport_map_port_92=34 +dport_map_port_93=35 +dport_map_port_94=36 +dport_map_port_103=37 +dport_map_port_104=38 +dport_map_port_105=39 +dport_map_port_106=40 +dport_map_port_111=41 +dport_map_port_112=42 +dport_map_port_113=43 +dport_map_port_114=44 +dport_map_port_119=45 +dport_map_port_120=46 +dport_map_port_121=47 +dport_map_port_122=48 +dport_map_port_1=49 +dport_map_port_2=50 +dport_map_port_3=51 +dport_map_port_4=52 +dport_map_port_9=53 +dport_map_port_10=54 +dport_map_port_11=55 +dport_map_port_12=56 +dport_map_port_25=57 +dport_map_port_26=58 +dport_map_port_27=59 +dport_map_port_28=60 +dport_map_port_33=61 +dport_map_port_34=62 +dport_map_port_35=63 +dport_map_port_36=64 +dport_map_port_41=65 +dport_map_port_42=66 +dport_map_port_43=67 +dport_map_port_44=68 +dport_map_port_49=69 +dport_map_port_50=70 +dport_map_port_51=71 +dport_map_port_52=72 +dport_map_port_71=73 +dport_map_port_72=74 +dport_map_port_73=75 +dport_map_port_74=76 +dport_map_port_79=77 +dport_map_port_80=78 +dport_map_port_81=79 +dport_map_port_82=80 +dport_map_port_83=81 +dport_map_port_84=82 +dport_map_port_85=83 +dport_map_port_86=84 +dport_map_port_99=85 +dport_map_port_100=86 +dport_map_port_101=87 +dport_map_port_102=88 +dport_map_port_107=89 +dport_map_port_108=90 +dport_map_port_109=91 +dport_map_port_110=92 +dport_map_port_115=93 +dport_map_port_116=94 +dport_map_port_117=95 +dport_map_port_118=96 +dport_map_port_29=97 +dport_map_port_30=98 +dport_map_port_31=99 +dport_map_port_32=100 +dport_map_port_21=101 +dport_map_port_22=102 +dport_map_port_23=103 +dport_map_port_24=104 +dport_map_port_127=105 +dport_map_port_128=106 +dport_map_port_129=107 +dport_map_port_130=108 +dport_map_port_87=109 +dport_map_port_88=110 +dport_map_port_89=111 +dport_map_port_90=112 +dport_map_port_57=113 +dport_map_port_58=114 +dport_map_port_59=115 +dport_map_port_60=116 +dport_map_port_61=117 +dport_map_port_62=118 +dport_map_port_63=119 +dport_map_port_64=120 +dport_map_port_123=121 +dport_map_port_124=122 +dport_map_port_125=123 +dport_map_port_126=124 +dport_map_port_95=125 +dport_map_port_96=126 +dport_map_port_97=127 +dport_map_port_98=128 + +dpp_clock_ratio=2:3 +oversubscribe_mode=1 +core_clock_frequency=1525 +l2xmsg_mode=1 +pbmp_oversubscribe=0x7fffffffffffffff9fffffffffffffffe +pbmp_xport_xe=0x7fffffffffffffff9fffffffffffffffe +ifp_inports_support_enable=1 +port_flex_enable=1 +phy_an_c73=3 +l2xmsg_hostbuf_size=8192 +module_64ports=0 +tdma_intr_enable=1 +ipv6_lpm_128b_enable=1 +stat_if_parity_enable=1 +bcm_tunnel_term_compatible_mode=1 +table_dma_enable=1 +schan_intr_enable=0 +parity_enable=1 +parity_correction=1 +miim_intr_enable=1 +tdma_timeout_usec=5000000 +max_vp_lags=0 +mmu_lossless=0 +pdma_descriptor_prefetch_enable=1 +pktdma_poll_mode_channel_bitmap=1 +l3_max_ecmp_mode.0=1 +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 + +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 +l3_max_ecmp_mode=1 + +stable_size=0x5500000 + +mmu_init_config="TD3-DELL-lossless" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers.json.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t0.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/custom_led.bin b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..302a41d9789a8bd16c80bff104794fb13b095914 GIT binary patch literal 412 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 X`cUsHXR!vGk^Z4y?GFw9z}SBSTZoUr literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/port_config.ini b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/port_config.ini new file mode 100644 index 000000000000..5b2f7ccd20fb --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/port_config.ini @@ -0,0 +1,105 @@ +# name lanes alias index speed +Ethernet0 5 twentyfiveGigE1/1/1 1 25000 +Ethernet1 6 twentyfiveGigE1/1/2 2 25000 +Ethernet2 7 twentyfiveGigE1/1/3 3 25000 +Ethernet3 8 twentyfiveGigE1/1/4 4 25000 +Ethernet4 13 twentyfiveGigE1/2/1 5 25000 +Ethernet5 14 twentyfiveGigE1/2/2 6 25000 +Ethernet6 15 twentyfiveGigE1/2/3 7 25000 +Ethernet7 16 twentyfiveGigE1/2/4 8 25000 +Ethernet8 17 twentyfiveGigE1/3/1 9 25000 +Ethernet9 18 twentyfiveGigE1/3/2 10 25000 +Ethernet10 19 twentyfiveGigE1/3/3 11 25000 +Ethernet11 20 twentyfiveGigE1/3/4 12 25000 +Ethernet12 37 twentyfiveGigE1/4/1 13 25000 +Ethernet13 38 twentyfiveGigE1/4/2 14 25000 +Ethernet14 39 twentyfiveGigE1/4/3 15 25000 +Ethernet15 40 twentyfiveGigE1/4/4 16 25000 +Ethernet16 45 twentyfiveGigE1/5/1 17 25000 +Ethernet17 46 twentyfiveGigE1/5/2 18 25000 +Ethernet18 47 twentyfiveGigE1/5/3 19 25000 +Ethernet19 48 twentyfiveGigE1/5/4 20 25000 +Ethernet20 53 twentyfiveGigE1/6/1 21 25000 +Ethernet21 54 twentyfiveGigE1/6/2 22 25000 +Ethernet22 55 twentyfiveGigE1/6/3 23 25000 +Ethernet23 56 twentyfiveGigE1/6/4 24 25000 +Ethernet24 65 twentyfiveGigE1/7/1 25 25000 +Ethernet25 66 twentyfiveGigE1/7/2 26 25000 +Ethernet26 67 twentyfiveGigE1/7/3 27 25000 +Ethernet27 68 twentyfiveGigE1/7/4 28 25000 +Ethernet28 73 twentyfiveGigE1/8/1 29 25000 +Ethernet29 74 twentyfiveGigE1/8/2 30 25000 +Ethernet30 75 twentyfiveGigE1/8/3 31 25000 +Ethernet31 76 twentyfiveGigE1/8/4 32 25000 +Ethernet32 89 twentyfiveGigE1/9/1 33 25000 +Ethernet33 90 twentyfiveGigE1/9/2 34 25000 +Ethernet34 91 twentyfiveGigE1/9/3 35 25000 +Ethernet35 92 twentyfiveGigE1/9/4 36 25000 +Ethernet36 101 twentyfiveGigE1/10/1 37 25000 +Ethernet37 102 twentyfiveGigE1/10/2 38 25000 +Ethernet38 103 twentyfiveGigE1/10/3 39 25000 +Ethernet39 104 twentyfiveGigE1/10/4 40 25000 +Ethernet40 109 twentyfiveGigE1/11/1 41 25000 +Ethernet41 110 twentyfiveGigE1/11/2 42 25000 +Ethernet42 111 twentyfiveGigE1/11/3 43 25000 +Ethernet43 112 twentyfiveGigE1/11/4 44 25000 +Ethernet44 117 twentyfiveGigE1/12/1 45 25000 +Ethernet45 118 twentyfiveGigE1/12/2 46 25000 +Ethernet46 119 twentyfiveGigE1/12/3 47 25000 +Ethernet47 120 twentyfiveGigE1/12/4 48 25000 +Ethernet48 1 twentyfiveGigE1/13/1 49 25000 +Ethernet49 2 twentyfiveGigE1/13/2 50 25000 +Ethernet50 3 twentyfiveGigE1/13/3 51 25000 +Ethernet51 4 twentyfiveGigE1/13/4 52 25000 +Ethernet52 9 twentyfiveGigE1/14/1 53 25000 +Ethernet53 10 twentyfiveGigE1/14/2 54 25000 +Ethernet54 11 twentyfiveGigE1/14/3 55 25000 +Ethernet55 12 twentyfiveGigE1/14/4 56 25000 +Ethernet56 25 twentyfiveGigE1/15/1 57 25000 +Ethernet57 26 twentyfiveGigE1/15/2 58 25000 +Ethernet58 27 twentyfiveGigE1/15/3 59 25000 +Ethernet59 28 twentyfiveGigE1/15/4 60 25000 +Ethernet60 33 twentyfiveGigE1/16/1 61 25000 +Ethernet61 34 twentyfiveGigE1/16/2 62 25000 +Ethernet62 35 twentyfiveGigE1/16/3 63 25000 +Ethernet63 36 twentyfiveGigE1/16/4 64 25000 +Ethernet64 41 twentyfiveGigE1/17/1 65 25000 +Ethernet65 42 twentyfiveGigE1/17/2 66 25000 +Ethernet66 43 twentyfiveGigE1/17/3 67 25000 +Ethernet67 44 twentyfiveGigE1/17/4 68 25000 +Ethernet68 49 twentyfiveGigE1/18/1 69 25000 +Ethernet69 50 twentyfiveGigE1/18/2 70 25000 +Ethernet70 51 twentyfiveGigE1/18/3 71 25000 +Ethernet71 52 twentyfiveGigE1/18/4 72 25000 +Ethernet72 69 twentyfiveGigE1/19/1 73 25000 +Ethernet73 70 twentyfiveGigE1/19/2 74 25000 +Ethernet74 71 twentyfiveGigE1/19/3 75 25000 +Ethernet75 72 twentyfiveGigE1/19/4 76 25000 +Ethernet76 77 twentyfiveGigE1/20/1 77 25000 +Ethernet77 78 twentyfiveGigE1/20/2 78 25000 +Ethernet78 79 twentyfiveGigE1/20/3 79 25000 +Ethernet79 80 twentyfiveGigE1/20/4 80 25000 +Ethernet80 81 twentyfiveGigE1/21/1 81 25000 +Ethernet81 82 twentyfiveGigE1/21/2 82 25000 +Ethernet82 83 twentyfiveGigE1/21/3 83 25000 +Ethernet83 84 twentyfiveGigE1/21/4 84 25000 +Ethernet84 97 twentyfiveGigE1/22/1 85 25000 +Ethernet85 98 twentyfiveGigE1/22/2 86 25000 +Ethernet86 99 twentyfiveGigE1/22/3 87 25000 +Ethernet87 100 twentyfiveGigE1/22/4 88 25000 +Ethernet88 105 twentyfiveGigE1/23/1 89 25000 +Ethernet89 106 twentyfiveGigE1/23/2 90 25000 +Ethernet90 107 twentyfiveGigE1/23/3 91 25000 +Ethernet91 108 twentyfiveGigE1/23/4 92 25000 +Ethernet92 113 twentyfiveGigE1/24/1 93 25000 +Ethernet93 114 twentyfiveGigE1/24/2 94 25000 +Ethernet94 115 twentyfiveGigE1/24/3 95 25000 +Ethernet95 116 twentyfiveGigE1/24/4 96 25000 +Ethernet96 29,30,31,32 hundredGigE1/49 97 100000 +Ethernet97 21,22,23,24 hundredGigE1/50 98 100000 +Ethernet98 125,126,127,128 hundredGigE1/51 99 100000 +Ethernet99 85,86,87,88 hundredGigE1/52 100 100000 +Ethernet100 57,58,59,60 hundredGigE1/53 101 100000 +Ethernet101 61,62,63,64 hundredGigE1/54 102 100000 +Ethernet102 121,122,123,124 hundredGigE1/55 103 100000 +Ethernet103 93,94,95,96 hundredGigE1/56 104 100000 diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/qos.json.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/qos.json.j2 new file mode 100644 index 000000000000..d2b3d2b0131c --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/qos.json.j2 @@ -0,0 +1,226 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "0", + "4": "0", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "DWRR", + "weight": "50" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai.profile b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai.profile new file mode 100644 index 000000000000..793e75fc4e45 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5296f-25g.config.bcm diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/td3-s5296f-25g.config.bcm b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/td3-s5296f-25g.config.bcm new file mode 100644 index 000000000000..81a42406e75f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/td3-s5296f-25g.config.bcm @@ -0,0 +1,595 @@ +os=unix +portmap_5.0=5:25 +portmap_6.0=6:25 +portmap_7.0=7:25 +portmap_8.0=8:25 +portmap_13.0=13:25 +portmap_14.0=14:25 +portmap_15.0=15:25 +portmap_16.0=16:25 +portmap_17.0=17:25 +portmap_18.0=18:25 +portmap_19.0=19:25 +portmap_20.0=20:25 +portmap_37.0=37:25 +portmap_38.0=38:25 +portmap_39.0=39:25 +portmap_40.0=40:25 +portmap_45.0=45:25 +portmap_46.0=46:25 +portmap_47.0=47:25 +portmap_48.0=48:25 +portmap_53.0=53:25 +portmap_54.0=54:25 +portmap_55.0=55:25 +portmap_56.0=56:25 +portmap_67.0=65:25 +portmap_68.0=66:25 +portmap_69.0=67:25 +portmap_70.0=68:25 +portmap_75.0=73:25 +portmap_76.0=74:25 +portmap_77.0=75:25 +portmap_78.0=76:25 +portmap_91.0=89:25 +portmap_92.0=90:25 +portmap_93.0=91:25 +portmap_94.0=92:25 +portmap_103.0=101:25 +portmap_104.0=102:25 +portmap_105.0=103:25 +portmap_106.0=104:25 +portmap_111.0=109:25 +portmap_112.0=110:25 +portmap_113.0=111:25 +portmap_114.0=112:25 +portmap_119.0=117:25 +portmap_120.0=118:25 +portmap_121.0=119:25 +portmap_122.0=120:25 +portmap_1.0=1:25 +portmap_2.0=2:25 +portmap_3.0=3:25 +portmap_4.0=4:25 +portmap_9.0=9:25 +portmap_10.0=10:25 +portmap_11.0=11:25 +portmap_12.0=12:25 +portmap_25.0=25:25 +portmap_26.0=26:25 +portmap_27.0=27:25 +portmap_28.0=28:25 +portmap_33.0=33:25 +portmap_34.0=34:25 +portmap_35.0=35:25 +portmap_36.0=36:25 +portmap_41.0=41:25 +portmap_42.0=42:25 +portmap_43.0=43:25 +portmap_44.0=44:25 +portmap_49.0=49:25 +portmap_50.0=50:25 +portmap_51.0=51:25 +portmap_52.0=52:25 +portmap_71.0=69:25 +portmap_72.0=70:25 +portmap_73.0=71:25 +portmap_74.0=72:25 +portmap_79.0=77:25 +portmap_80.0=78:25 +portmap_81.0=79:25 +portmap_82.0=80:25 +portmap_83.0=81:25 +portmap_84.0=82:25 +portmap_85.0=83:25 +portmap_86.0=84:25 +portmap_99.0=97:25 +portmap_100.0=98:25 +portmap_101.0=99:25 +portmap_102.0=100:25 +portmap_107.0=105:25 +portmap_108.0=106:25 +portmap_109.0=107:25 +portmap_110.0=108:25 +portmap_115.0=113:25 +portmap_116.0=114:25 +portmap_117.0=115:25 +portmap_118.0=116:25 +portmap_29.0=29:100 +portmap_21.0=21:100 +portmap_127.0=125:100 +portmap_87.0=85:100 +portmap_57.0=57:100 +portmap_61.0=61:100 +portmap_123.0=121:100 +portmap_95.0=93:100 +phy_chain_tx_lane_map_physical{5.0}=0x0123 +phy_chain_rx_lane_map_physical{5.0}=0x0123 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x0123 +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x0123 +phy_chain_tx_lane_map_physical{37.0}=0x0123 +phy_chain_rx_lane_map_physical{37.0}=0x0123 +phy_chain_tx_lane_map_physical{45.0}=0x0123 +phy_chain_rx_lane_map_physical{45.0}=0x0123 +phy_chain_tx_lane_map_physical{53.0}=0x0123 +phy_chain_rx_lane_map_physical{53.0}=0x0123 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x3210 +phy_chain_tx_lane_map_physical{73.0}=0x3210 +phy_chain_rx_lane_map_physical{73.0}=0x3210 +phy_chain_tx_lane_map_physical{89.0}=0x3210 +phy_chain_rx_lane_map_physical{89.0}=0x3210 +phy_chain_tx_lane_map_physical{101.0}=0x3210 +phy_chain_rx_lane_map_physical{101.0}=0x3210 +phy_chain_tx_lane_map_physical{109.0}=0x3210 +phy_chain_rx_lane_map_physical{109.0}=0x3210 +phy_chain_tx_lane_map_physical{117.0}=0x3210 +phy_chain_rx_lane_map_physical{117.0}=0x3210 +phy_chain_tx_lane_map_physical{1.0}=0x1032 +phy_chain_rx_lane_map_physical{1.0}=0x1032 +phy_chain_tx_lane_map_physical{9.0}=0x1032 +phy_chain_rx_lane_map_physical{9.0}=0x1032 +phy_chain_tx_lane_map_physical{25.0}=0x1032 +phy_chain_rx_lane_map_physical{25.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x1032 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x1032 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_rx_lane_map_physical{49.0}=0x2031 +phy_chain_tx_lane_map_physical{69.0}=0x2301 +phy_chain_rx_lane_map_physical{69.0}=0x2301 +phy_chain_tx_lane_map_physical{77.0}=0x1302 +phy_chain_rx_lane_map_physical{77.0}=0x1302 +phy_chain_tx_lane_map_physical{81.0}=0x2301 +phy_chain_rx_lane_map_physical{81.0}=0x2301 +phy_chain_tx_lane_map_physical{97.0}=0x2301 +phy_chain_rx_lane_map_physical{97.0}=0x2301 +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_rx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{113.0}=0x2301 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x3201 +phy_chain_tx_lane_map_physical{21.0}=0x3021 +phy_chain_rx_lane_map_physical{21.0}=0x0312 +phy_chain_tx_lane_map_physical{125.0}=0x3210 +phy_chain_rx_lane_map_physical{125.0}=0x0132 +phy_chain_tx_lane_map_physical{85.0}=0x0312 +phy_chain_rx_lane_map_physical{85.0}=0x3021 +phy_chain_tx_lane_map_physical{57.0}=0x3021 +phy_chain_rx_lane_map_physical{57.0}=0x0312 +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x1230 +phy_chain_tx_lane_map_physical{121.0}=0x0123 +phy_chain_rx_lane_map_physical{121.0}=0x2310 +phy_chain_tx_lane_map_physical{93.0}=0x0123 +phy_chain_rx_lane_map_physical{93.0}=0x2301 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x1 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x1 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_tx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x1 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_rx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_rx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x1 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_tx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_tx_polarity_flip_physical{80.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_tx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x1 +phy_chain_tx_polarity_flip_physical{108.0}=0x1 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_tx_polarity_flip_physical{116.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +dport_map_enable=1 +dport_map_port_5=1 +dport_map_port_6=2 +dport_map_port_7=3 +dport_map_port_8=4 +dport_map_port_13=5 +dport_map_port_14=6 +dport_map_port_15=7 +dport_map_port_16=8 +dport_map_port_17=9 +dport_map_port_18=10 +dport_map_port_19=11 +dport_map_port_20=12 +dport_map_port_37=13 +dport_map_port_38=14 +dport_map_port_39=15 +dport_map_port_40=16 +dport_map_port_45=17 +dport_map_port_46=18 +dport_map_port_47=19 +dport_map_port_48=20 +dport_map_port_53=21 +dport_map_port_54=22 +dport_map_port_55=23 +dport_map_port_56=24 +dport_map_port_67=25 +dport_map_port_68=26 +dport_map_port_69=27 +dport_map_port_70=28 +dport_map_port_75=29 +dport_map_port_76=30 +dport_map_port_77=31 +dport_map_port_78=32 +dport_map_port_91=33 +dport_map_port_92=34 +dport_map_port_93=35 +dport_map_port_94=36 +dport_map_port_103=37 +dport_map_port_104=38 +dport_map_port_105=39 +dport_map_port_106=40 +dport_map_port_111=41 +dport_map_port_112=42 +dport_map_port_113=43 +dport_map_port_114=44 +dport_map_port_119=45 +dport_map_port_120=46 +dport_map_port_121=47 +dport_map_port_122=48 +dport_map_port_1=49 +dport_map_port_2=50 +dport_map_port_3=51 +dport_map_port_4=52 +dport_map_port_9=53 +dport_map_port_10=54 +dport_map_port_11=55 +dport_map_port_12=56 +dport_map_port_25=57 +dport_map_port_26=58 +dport_map_port_27=59 +dport_map_port_28=60 +dport_map_port_33=61 +dport_map_port_34=62 +dport_map_port_35=63 +dport_map_port_36=64 +dport_map_port_41=65 +dport_map_port_42=66 +dport_map_port_43=67 +dport_map_port_44=68 +dport_map_port_49=69 +dport_map_port_50=70 +dport_map_port_51=71 +dport_map_port_52=72 +dport_map_port_71=73 +dport_map_port_72=74 +dport_map_port_73=75 +dport_map_port_74=76 +dport_map_port_79=77 +dport_map_port_80=78 +dport_map_port_81=79 +dport_map_port_82=80 +dport_map_port_83=81 +dport_map_port_84=82 +dport_map_port_85=83 +dport_map_port_86=84 +dport_map_port_99=85 +dport_map_port_100=86 +dport_map_port_101=87 +dport_map_port_102=88 +dport_map_port_107=89 +dport_map_port_108=90 +dport_map_port_109=91 +dport_map_port_110=92 +dport_map_port_115=93 +dport_map_port_116=94 +dport_map_port_117=95 +dport_map_port_118=96 +dport_map_port_29=97 +dport_map_port_30=98 +dport_map_port_31=99 +dport_map_port_32=100 +dport_map_port_21=101 +dport_map_port_22=102 +dport_map_port_23=103 +dport_map_port_24=104 +dport_map_port_127=105 +dport_map_port_128=106 +dport_map_port_129=107 +dport_map_port_130=108 +dport_map_port_87=109 +dport_map_port_88=110 +dport_map_port_89=111 +dport_map_port_90=112 +dport_map_port_57=113 +dport_map_port_58=114 +dport_map_port_59=115 +dport_map_port_60=116 +dport_map_port_61=117 +dport_map_port_62=118 +dport_map_port_63=119 +dport_map_port_64=120 +dport_map_port_123=121 +dport_map_port_124=122 +dport_map_port_125=123 +dport_map_port_126=124 +dport_map_port_95=125 +dport_map_port_96=126 +dport_map_port_97=127 +dport_map_port_98=128 + +dpp_clock_ratio=2:3 +oversubscribe_mode=1 +core_clock_frequency=1525 +l2xmsg_mode=1 +pbmp_oversubscribe=0x7fffffffffffffff9fffffffffffffffe +pbmp_xport_xe=0x7fffffffffffffff9fffffffffffffffe +ifp_inports_support_enable=1 +port_flex_enable=1 +phy_an_c73=3 +l2xmsg_hostbuf_size=8192 +module_64ports=0 +tdma_intr_enable=1 +ipv6_lpm_128b_enable=1 +stat_if_parity_enable=1 +bcm_tunnel_term_compatible_mode=1 +table_dma_enable=1 +schan_intr_enable=0 +parity_enable=1 +parity_correction=1 +miim_intr_enable=1 +tdma_timeout_usec=5000000 +max_vp_lags=0 +mmu_lossless=0 +pdma_descriptor_prefetch_enable=1 +pktdma_poll_mode_channel_bitmap=1 +l3_max_ecmp_mode.0=1 +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 + +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 +l3_max_ecmp_mode=1 + +stable_size=0x5500000 + +mmu_init_config="TD3-DELL-lossless" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/default_sku b/device/dell/x86_64-dellemc_s5296f_c3538-r0/default_sku new file mode 100644 index 000000000000..622d32812f43 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/default_sku @@ -0,0 +1 @@ +DellEMC-S5296f-P-25G t1 \ No newline at end of file diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/installer.conf b/device/dell/x86_64-dellemc_s5296f_c3538-r0/installer.conf new file mode 100644 index 000000000000..924e0fb81963 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/installer.conf @@ -0,0 +1,2 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/led_proc_init.soc b/device/dell/x86_64-dellemc_s5296f_c3538-r0/led_proc_init.soc new file mode 100644 index 000000000000..69072c369a64 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/led_proc_init.soc @@ -0,0 +1,6 @@ +# LED microprocessor initialization for Dell S5232 +# +# +#Led0 +led auto on +led start diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/media_settings.json b/device/dell/x86_64-dellemc_s5296f_c3538-r0/media_settings.json new file mode 100644 index 000000000000..8bdc0e7aa984 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/media_settings.json @@ -0,0 +1,442 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "1-32": { + "QSFP28-40GBASE-CR4-1M":{ + "preemphasis": { + "lane0":"0x16440A", + "lane1":"0x16440A", + "lane2":"0x16440A", + "lane3":"0x16440A" + } + }, + "QSFP28-40GBASE-CR4-2M":{ + "preemphasis": { + "lane0":"0x18420A", + "lane1":"0x18420A", + "lane2":"0x18420A", + "lane3":"0x18420A" + } + }, + "QSFP28-40GBASE-CR4-3M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-4M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-5M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-7M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-10M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-1M":{ + "preemphasis": { + "lane0":"0x16440A", + "lane1":"0x16440A", + "lane2":"0x16440A", + "lane3":"0x16440A" + } + }, + "QSFP+-40GBASE-CR4-2M":{ + "preemphasis": { + "lane0":"0x18420A", + "lane1":"0x18420A", + "lane2":"0x18420A", + "lane3":"0x18420A" + } + }, + "QSFP+-40GBASE-CR4-3M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-4M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-5M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-7M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-10M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + } + } + }, + + "PORT_MEDIA_SETTINGS": { + "1": { + "Default": { + "preemphasis": { + "lane0":"0x164509", + "lane1":"0x164509", + "lane2":"0x164509", + "lane3":"0x164509" + } + } + }, + "2": { + "Default": { + "preemphasis": { + "lane0":"0x164509", + "lane1":"0x164509", + "lane2":"0x164509", + "lane3":"0x164509" + } + } + }, + "3": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "4": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "5": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "6": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "7": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "8": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "9": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "10": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "11": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "12": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "13": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "14": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "15": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "16": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "17": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "19": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "20": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "21": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "22": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "23": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "24": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "25": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "26": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "28": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "29": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "30": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "31": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "32": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + } + } +} + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/eeprom.py new file mode 100644 index 000000000000..da50f1f851f9 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/eeprom.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +############################################################################# +# DellEMC S5296f +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +import os.path + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = None + for b in (0, 1): + f = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'.format(b) + if os.path.exists(f): + self.eeprom_path = f + break + if self.eeprom_path is None: + return + + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/psuutil.py new file mode 100644 index 000000000000..eedadc516825 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/psuutil.py @@ -0,0 +1,98 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import logging +import commands +import sys + + +S5296F_MAX_PSUS = 2 +IPMI_PSU_DATA = "docker exec -it pmon ipmitool sdr list" +IPMI_PSU_DATA_DOCKER = "ipmitool sdr list" +PSU_PRESENCE = "PSU{0}_stat" +# Use this for older firmware +# PSU_PRESENCE="PSU{0}_prsnt" +ipmi_sdr_list = "" + + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + def isDockerEnv(self): + num_docker = open('/proc/self/cgroup', 'r').read().count(":/docker") + if num_docker > 0: + return True + else: + return False + + # Fetch a BMC register + def get_pmc_register(self, reg_name): + + global ipmi_sdr_list + ipmi_cmd = IPMI_PSU_DATA + dockerenv = self.isDockerEnv() + if dockerenv == True: + ipmi_cmd = IPMI_PSU_DATA_DOCKER + + status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + + if status: + logging.error('Failed to execute:' + ipmi_sdr_list) + sys.exit(0) + + for item in ipmi_sdr_list.split("\n"): + if reg_name in item: + output = item.strip() + + if not output: + print('\nFailed to fetch: ' + reg_name + ' sensor ') + sys.exit(0) + + output = output.split('|')[1] + + logging.basicConfig(level=logging.DEBUG) + return output + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + S5296F_MAX_PSUS = 2 + return S5296F_MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + # Until psu_status is implemented this is hardcoded temporarily + + status = 1 + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + cmd_status, psu_status = commands.getstatusoutput('ipmitool raw 0x04 0x2d ' + hex(0x30 + index) + " | awk '{print substr($0,9,1)}'") + return 1 if psu_status == '1' else 0 + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/sfputil.py new file mode 100644 index 000000000000..a2e459478f05 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/sfputil.py @@ -0,0 +1,554 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# +# For S5296F-ON, hardware version X01 + +try: + import struct + import time + from sonic_sfp.sfputilbase import SfpUtilBase + from os import * + from mmap import * + import io + from sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_sfp.sff8436 import sff8436Dom + from sonic_sfp.sff8472 import sff8472Dom + +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +#definitions of the offset and width for values in DOM info eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_MON_MASK_OFFSET = 242 +QSFP_CHANNL_MON_MASK_WIDTH = 4 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 + +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 104 + PORTS_IN_BLOCK = 104 + + BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" + + _port_to_eeprom_mapping = {} + + + _global_port_pres_dict = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(97, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def pci_mem_read(self, mm, offset): + mm.seek(offset) + read_data_stream=mm.read(4) + reg_val=struct.unpack('I',read_data_stream) + mem_val = str(reg_val)[1:-2] + # print "reg_val read:%x"%reg_val + return mem_val + + def pci_mem_write(self, mm, offset, data): + mm.seek(offset) + # print "data to write:%x"%data + mm.write(struct.pack('I',data)) + + def pci_set_value(self, resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + + def pci_get_value(self, resource, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_read(mm, offset) + mm.close() + close(fd) + return val + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + else: + self._global_port_pres_dict[port_num] = '0' + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for x in range(self.port_start, self.port_end + 1): + self.port_to_eeprom_mapping[x] = eeprom_path.format(x + 1) + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4004 + port_offset = 16388 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off bit for presence + mask = (1 << 1) + if (port_num > 96): + mask = (1 << 4) + + # ModPrsL is active low + if reg_value & mask == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high + if reg_value & mask == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + def reset(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + # Sleep 1 second to allow it to settle + time.sleep(1) + + reg_value = reg_value | mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + sleep_time_ms = 500 # Poll interval, in milliseconds + sleep_time = sleep_time_ms / 1000.0 + elapsed_time_ms = 0 + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + break + + if len(port_dict) > 0: + break + if timeout != 0: + elapsed_time_ms += sleep_time_ms + if elapsed_time_ms > timeout: + break + time.sleep(sleep_time) + + return True, port_dict + + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power', + ] + transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + offset = 0 + offset_xcvr = 128 + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return transceiver_dom_info_dict + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return transceiver_dom_info_dict + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return None + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), + SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), + SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + + def get_transceiver_dom_threshold_info_dict(self, port_num): + transceiver_dom_threshold_info_dict = {} + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + #Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_s5296f_c3538-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..72ef3c2210a2 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/pmon_daemon_control.json @@ -0,0 +1,8 @@ +{ + "skip_sensors": true, + "skip_fancontrol": true, + "skip_ledd": true, + "skip_psud": true, + "skip_syseepromd": true, + "skip_thermalctld": true +} diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index a9d97b81a056..538461b4dba3 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -10,6 +10,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(DELL_S5232F_PLATFORM_MODULE) \ $(DELL_S5248F_PLATFORM_MODULE) \ $(DELL_Z9332F_PLATFORM_MODULE) \ + $(DELL_S5296F_PLATFORM_MODULE) \ $(DELL_Z9100_PLATFORM_MODULE) \ $(DELL_S6100_PLATFORM_MODULE) \ $(INGRASYS_S8900_54XC_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-dell.mk b/platform/broadcom/platform-modules-dell.mk index 18fafa3c0c8d..e4d4f56c53aa 100644 --- a/platform/broadcom/platform-modules-dell.mk +++ b/platform/broadcom/platform-modules-dell.mk @@ -7,6 +7,7 @@ DELL_Z9264F_PLATFORM_MODULE_VERSION = 1.1 DELL_S5232F_PLATFORM_MODULE_VERSION = 1.1 DELL_Z9332F_PLATFORM_MODULE_VERSION = 1.1 DELL_S5248F_PLATFORM_MODULE_VERSION = 1.1 +DELL_S5296F_PLATFORM_MODULE_VERSION = 1.1 export DELL_S6000_PLATFORM_MODULE_VERSION export DELL_Z9100_PLATFORM_MODULE_VERSION @@ -15,6 +16,7 @@ export DELL_Z9264F_PLATFORM_MODULE_VERSION export DELL_S5232F_PLATFORM_MODULE_VERSION export DELL_Z9332F_PLATFORM_MODULE_VERSION export DELL_S5248F_PLATFORM_MODULE_VERSION +export DELL_S5296F_PLATFORM_MODULE_VERSION DELL_Z9100_PLATFORM_MODULE = platform-modules-z9100_$(DELL_Z9100_PLATFORM_MODULE_VERSION)_amd64.deb $(DELL_Z9100_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-dell @@ -47,5 +49,9 @@ DELL_S5248F_PLATFORM_MODULE = platform-modules-s5248f_$(DELL_S5248F_PLATFORM_MOD $(DELL_S5248F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5248f_c3538-r0 $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5248F_PLATFORM_MODULE))) +DELL_S5296F_PLATFORM_MODULE = platform-modules-s5296f_$(DELL_S5296F_PLATFORM_MODULE_VERSION)_amd64.deb +$(DELL_S5296F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5296f_c3538-r0 +$(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5296F_PLATFORM_MODULE))) + #flashrom tool $(shell ./$(PLATFORM_PATH)/sonic-platform-modules-dell/tools/flashrom.sh > /dev/null 2>&1) diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index eca4085787e0..82b0e402a15d 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -39,3 +39,8 @@ Package: platform-modules-z9332f Architecture: amd64 Depends: linux-image-4.19.0-9-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-s5296f +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.init b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.init new file mode 100755 index 000000000000..9276679ef004 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.init @@ -0,0 +1,39 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup S5296f board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + # /usr/local/bin/iom_power_on.sh + /usr/local/bin/s5296f_platform.sh init + + echo "done." + ;; + +stop) + /usr/local/bin/s5296f_platform.sh deinit + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-s5296f.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.install new file mode 100644 index 000000000000..497554a476c1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.install @@ -0,0 +1,9 @@ +s5296f/scripts/s5296f_platform.sh usr/local/bin +s5296f/scripts/platform_sensors.py usr/local/bin +s5296f/scripts/sensors usr/bin +s5296f/scripts/pcisysfs.py usr/bin +s5296f/cfg/s5296f-modules.conf etc/modules-load.d +s5296f/systemd/platform-modules-s5296f.service etc/systemd/system +common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5296f_c3538-r0 +common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.postinst new file mode 100644 index 000000000000..21772eafdd02 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.postinst @@ -0,0 +1,10 @@ +# postinst script for S5296f + +# Enable Dell-S5296f-platform-service +depmod -a +systemctl enable platform-modules-s5296f.service +systemctl start platform-modules-s5296f.service + + +#DEBHELPER# + diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index 03c0f6426970..322c79a39350 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f z9332f +MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f z9332f s5296f COMMON_DIR := common %: diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/cfg/s5296f-modules.conf b/platform/broadcom/sonic-platform-modules-dell/s5296f/cfg/s5296f-modules.conf new file mode 100644 index 000000000000..17045f6b25ab --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/cfg/s5296f-modules.conf @@ -0,0 +1,19 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x + +ipmi_devintf +ipmi_si +dell_s5296f_fpga_ocores +i2c_ocores diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/Makefile b/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/Makefile new file mode 100644 index 000000000000..d1d103b5f136 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := dell_s5296f_fpga_ocores.o + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/dell_s5296f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/dell_s5296f_fpga_ocores.c new file mode 100644 index 000000000000..b9a50c69b225 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/dell_s5296f_fpga_ocores.c @@ -0,0 +1,1626 @@ +/* +* Copyright (C) 2018 Dell Inc +* +* Licensed under the GNU General Public License Version 2 +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +*/ + +/** +* @file fpga_i2ccore.c +* @brief This is a driver to interface with Linux Open Cores drivber for FPGA i2c access +* +************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include //siginfo +#include //rcu_read_lock +#include //kernel_version +#include +#include +#include +#include +#include + + +void __iomem * fpga_base_addr = NULL; +void __iomem * fpga_ctl_addr = NULL; + +#define DRIVER_NAME "fpgapci" +#define PCI_NUM_BARS 4 + +#ifdef DEBUG +# define PRINT(fmt, ...) printk(fmt, ##__VA_ARGS__) +#else +# define PRINT(fmt, ...) +#endif + +/* Maximum size of driver buffer (allocated with kalloc()). + * Needed to copy data from user to kernel space, among other + * things. */ +static const size_t BUF_SIZE = PAGE_SIZE; + +/* Device data used by this driver. */ +struct fpgapci_dev { + /* the kernel pci device data structure */ + struct pci_dev *pci_dev; + + /* upstream root node */ + struct pci_dev *upstream; + + /* kernels virtual addr. for the mapped BARs */ + void * __iomem bar[PCI_NUM_BARS]; + + /* length of each memory region. Used for error checking. */ + size_t bar_length[PCI_NUM_BARS]; + + /* Debug data */ + /* number of hw interrupts handled. */ + int num_handled_interrupts; + int num_undelivered_signals; + int pci_gen; + int pci_num_lanes; + + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + unsigned int xcvr_intr_count; +}; + +static int use_irq = 1; +module_param(use_irq, int, 0644); +MODULE_PARM_DESC(use_irq, "Get an use_irq value from user...\n"); + +static uint32_t num_bus = 0; +module_param(num_bus, int, 0); +MODULE_PARM_DESC(num_bus, + "Number of i2c busses supported by the FPGA on this platform."); + + +/* Xilinx FPGA PCIE info: */ +/* Non-VGA unclassified device: Xilinx Corporation Device 7021*/ +/* Subsystem: Xilinx Corporation Device 0007 */ +//#define VENDOR 0x10EE +#define DEVICE 0x7021 +static phys_addr_t fpga_phys_addr; + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + + +/* struct to hold data related to the pcie device */ +struct pci_data_struct{ + struct pci_dev* dev; + unsigned long long phy_addr_bar0; + unsigned long long phy_len_bar0; + unsigned long long phy_flags_bar0; + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + void * kvirt_addr_bar0; +}; + +/* global variable declarations */ + +/* Static function declarations */ +static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id); +static void fpgapci_remove(struct pci_dev *dev); + +static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); +static int map_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); +static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); + + +struct fpgalogic_i2c { + void __iomem *base; + u32 reg_shift; + u32 reg_io_width; + wait_queue_head_t wait; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; /* see STATE_ */ + int ip_clock_khz; + int bus_clock_khz; + void (*reg_set)(struct fpgalogic_i2c *i2c, int reg, u8 value); + u8 (*reg_get)(struct fpgalogic_i2c *i2c, int reg); + u32 timeout; + struct mutex lock; +}; +/* registers */ +#define FPGAI2C_REG_PRELOW 0 +#define FPGAI2C_REG_PREHIGH 1 +#define FPGAI2C_REG_CONTROL 2 +#define FPGAI2C_REG_DATA 3 +#define FPGAI2C_REG_CMD 4 /* write only */ +#define FPGAI2C_REG_STATUS 4 /* read only, same address as FPGAI2C_REG_CMD */ +#define FPGAI2C_REG_VER 5 + + + +#define FPGAI2C_REG_CTRL_IEN 0x40 +#define FPGAI2C_REG_CTRL_EN 0x80 + +#define FPGAI2C_REG_CMD_START 0x91 +#define FPGAI2C_REG_CMD_STOP 0x41 +#define FPGAI2C_REG_CMD_READ 0x21 +#define FPGAI2C_REG_CMD_WRITE 0x11 +#define FPGAI2C_REG_CMD_READ_ACK 0x21 +#define FPGAI2C_REG_CMD_READ_NACK 0x29 +#define FPGAI2C_REG_CMD_IACK 0x01 + +#define FPGAI2C_REG_STAT_IF 0x01 +#define FPGAI2C_REG_STAT_TIP 0x02 +#define FPGAI2C_REG_STAT_ARBLOST 0x20 +#define FPGAI2C_REG_STAT_BUSY 0x40 +#define FPGAI2C_REG_STAT_NACK 0x80 + +/* SR[7:0] - Status register */ +#define FPGAI2C_REG_SR_RXACK (1 << 7) /* Receive acknowledge from slave ‘1’ = No acknowledge received*/ +#define FPGAI2C_REG_SR_BUSY (1 << 6) /* Busy, I2C bus busy (as defined by start / stop bits) */ +#define FPGAI2C_REG_SR_AL (1 << 5) /* Arbitration lost - fpga i2c logic lost arbitration */ +#define FPGAI2C_REG_SR_TIP (1 << 1) /* Transfer in progress */ +#define FPGAI2C_REG_SR_IF (1 << 0) /* Interrupt flag */ + +enum { + STATE_DONE = 0, + STATE_INIT, + STATE_ADDR, + STATE_ADDR10, + STATE_START, + STATE_WRITE, + STATE_READ, + STATE_STOP, + STATE_ERROR, +}; + +#define TYPE_FPGALOGIC 0 +#define TYPE_GRLIB 1 + +/*I2C_CH1 Offset address from PCIE BAR 0*/ +#define FPGALOGIC_I2C_BASE 0x00006000 +#define FPGALOGIC_CH_OFFSET 0x10 + +#define i2c_bus_controller_numb 1 +#define I2C_PCI_MAX_BUS (16) +#define I2C_PCI_MAX_BUS_REV00 (7) +#define DELL_I2C_CLOCK_LEGACY 0 +#define DELL_I2C_CLOCK_PRESERVE (~0U) +#define I2C_PCI_BUS_NUM_5 5 +#define I2C_PCI_BUS_NUM_7 7 +#define I2C_PCI_BUS_NUM_8 8 +#define I2C_PCI_BUS_NUM_10 10 +#define I2C_PCI_BUS_NUM_12 12 +#define I2C_PCI_BUS_NUM_16 16 + +#define IRQ_LTCH_STS 0x20 +#define PRSNT_LTCH_STS 0x10 + +#define PORT_CTRL_OFFSET 0x4000 +#define PORT_STS_OFFSET 0x4004 +#define PORT_IRQ_STS_OFFSET 0x4008 +#define PORT_IRQ_EN_OFFSET 0x400C +#define MB_BRD_REV_TYPE 0x0008 +#define MB_BRD_REV_MASK 0x00f0 +#define MB_BRD_REV_00 0x0000 +#define MB_BRD_REV_01 0x0010 +#define MB_BRD_REV_02 0x0020 +#define MB_BRD_REV_03 0x0030 +#define MB_BRD_TYPE_MASK 0x000f +#define BRD_TYPE_Z9232_NON_NEBS 0x0 +#define BRD_TYPE_Z9232_NEBS 0x1 +#define BRD_TYPE_Z9264_NON_NEBS 0x2 +#define BRD_TYPE_Z9264_NEBS 0x3 +#define BRD_TYPE_S5212_NON_NEBS 0x4 +#define BRD_TYPE_S5212_NEBS 0x5 +#define BRD_TYPE_S5224_NON_NEBS 0x6 +#define BRD_TYPE_S5224_NEBS 0x7 +#define BRD_TYPE_S5248_NON_NEBS 0x8 +#define BRD_TYPE_S5248_NEBS 0x9 +#define BRD_TYPE_S5296_NON_NEBS 0xa +#define BRD_TYPE_S5296_NEBS 0xb +#define BRD_TYPE_S5232_NON_NEBS 0xc +#define BRD_TYPE_S5232_NEBS 0xd + +#define FPGA_CTL_REG_SIZE 0x6000 +#define MSI_VECTOR_MAP_MASK 0x1f +#define MSI_VECTOR_MAP1 0x58 +#define I2C_CH1_MSI_MAP_VECT_8 0x00000008 +#define I2C_CH2_MSI_MAP_VECT_9 0x00000120 +#define I2C_CH3_MSI_MAP_VECT_10 0x00002800 +#define I2C_CH4_MSI_MAP_VECT_11 0x00058000 +#define I2C_CH5_MSI_MAP_VECT_12 0x00c00000 +#define I2C_CH6_MSI_MAP_VECT_13 0x15000000 +#define MSI_VECTOR_MAP2 0x5c +#define I2C_CH7_MSI_MAP_VECT_14 0x0000000e +#define MSI_VECTOR_MAP3 0x9c +#define I2C_CH8_MSI_MAP_VECT_8 0x00800000 +#define I2C_CH8_MSI_MAP_VECT_16 0x01100000 +#define I2C_CH9_MSI_MAP_VECT_9 0x12000000 +#define I2C_CH9_MSI_MAP_VECT_17 0x24000000 +#define MSI_VECTOR_MAP4 0xa0 +#define I2C_CH10_MSI_MAP_VECT_10 0x0000000a +#define I2C_CH10_MSI_MAP_VECT_18 0x00000012 +#define I2C_CH11_MSI_MAP_VECT_11 0x00000120 +#define I2C_CH11_MSI_MAP_VECT_19 0x00000260 +#define I2C_CH12_MSI_MAP_VECT_12 0x00002800 +#define I2C_CH12_MSI_MAP_VECT_20 0x00005000 +#define I2C_CH13_MSI_MAP_VECT_13 0x00058000 +#define I2C_CH13_MSI_MAP_VECT_21 0x000a8000 +#define I2C_CH14_MSI_MAP_VECT_14 0x00c00000 +#define I2C_CH14_MSI_MAP_VECT_22 0x01600000 +#define I2C_CH15_MSI_MAP_VECT_8 0x10000000 +#define I2C_CH15_MSI_MAP_VECT_23 0x2e000000 +#define MSI_VECTOR_MAP5 0xa4 +#define I2C_CH16_MSI_MAP_VECT_9 0x00000009 +#define I2C_CH16_MSI_MAP_VECT_24 0x00000018 + +#define MSI_VECTOR_REV_00 16 +#define MSI_VECTOR_REV_01 32 + +#define FPGA_MSI_VECTOR_ID_4 4 +#define FPGA_MSI_VECTOR_ID_5 5 +#define FPGA_MSI_VECTOR_ID_8 8 +#define FPGA_MSI_VECTOR_ID_9 9 +#define FPGA_MSI_VECTOR_ID_10 10 +#define FPGA_MSI_VECTOR_ID_11 11 +#define FPGA_MSI_VECTOR_ID_12 12 +#define FPGA_MSI_VECTOR_ID_13 13 +#define FPGA_MSI_VECTOR_ID_14 14 +#define FPGA_MSI_VECTOR_ID_15 15 /*Note: this is external MSI vector id */ +#define FPGA_MSI_VECTOR_ID_16 16 +#define FPGA_MSI_VECTOR_ID_17 17 +#define FPGA_MSI_VECTOR_ID_18 18 +#define FPGA_MSI_VECTOR_ID_19 19 +#define FPGA_MSI_VECTOR_ID_20 20 +#define FPGA_MSI_VECTOR_ID_21 21 +#define FPGA_MSI_VECTOR_ID_22 22 +#define FPGA_MSI_VECTOR_ID_23 23 +#define FPGA_MSI_VECTOR_ID_24 24 + + + +static int total_i2c_pci_bus = 0; +static uint32_t board_rev_type = 0; +static struct fpgalogic_i2c fpgalogic_i2c[I2C_PCI_MAX_BUS]; +static struct i2c_adapter i2c_pci_adap[I2C_PCI_MAX_BUS]; +static struct mutex i2c_xfer_lock[I2C_PCI_MAX_BUS]; + +static void fpgai2c_reg_set_8(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite8(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_16(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite16(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_32(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite32(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_16be(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_32be(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_8(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread8(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_16(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread16(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_32(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread32(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_16be(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread16be(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_32be(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread32be(i2c->base + (reg << i2c->reg_shift)); +} + +static inline void fpgai2c_reg_set(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + i2c->reg_set(i2c, reg, value); + udelay(100); +} + +static inline u8 fpgai2c_reg_get(struct fpgalogic_i2c *i2c, int reg) +{ + udelay(100); + return i2c->reg_get(i2c, reg); +} + +static void fpgai2c_dump(struct fpgalogic_i2c *i2c) +{ + u8 tmp; + + PRINT("Logic register dump:\n"); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PRELOW); + PRINT("FPGAI2C_REG_PRELOW (%d) = 0x%x\n",FPGAI2C_REG_PRELOW,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PREHIGH); + PRINT("FPGAI2C_REG_PREHIGH(%d) = 0x%x\n",FPGAI2C_REG_PREHIGH,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + PRINT("FPGAI2C_REG_CONTROL(%d) = 0x%x\n",FPGAI2C_REG_CONTROL,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + PRINT("FPGAI2C_REG_DATA (%d) = 0x%x\n",FPGAI2C_REG_DATA,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CMD); + PRINT("FPGAI2C_REG_CMD (%d) = 0x%x\n",FPGAI2C_REG_CMD,tmp); +} + +static void fpgai2c_stop(struct fpgalogic_i2c *i2c) +{ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); +} + +/* + * dell_get_mutex must be called prior to calling this function. + */ +static int fpgai2c_poll(struct fpgalogic_i2c *i2c) +{ + u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + struct i2c_msg *msg = i2c->msg; + u8 addr; + + /* Ready? */ + if (stat & FPGAI2C_REG_STAT_TIP) + return -EBUSY; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* Stop has been sent */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (i2c->state == STATE_ERROR) + return -EIO; + return 0; + } + + /* Error? */ + if (stat & FPGAI2C_REG_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -EAGAIN; + } + + if (i2c->state == STATE_INIT) { + if (stat & FPGAI2C_REG_STAT_BUSY) + return -EBUSY; + + i2c->state = STATE_ADDR; + } + + if (i2c->state == STATE_ADDR) { + /* 10 bit address? */ + if (i2c->msg->flags & I2C_M_TEN) { + addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6); + i2c->state = STATE_ADDR10; + } else { + addr = (i2c->msg->addr << 1); + i2c->state = STATE_START; + } + + /* Set read bit if necessary */ + addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0; + + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + + return 0; + } + + /* Second part of 10 bit addressing */ + if (i2c->state == STATE_ADDR10) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, i2c->msg->addr & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + + i2c->state = STATE_START; + return 0; + } + + if (i2c->state == STATE_START || i2c->state == STATE_WRITE) { + i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & FPGAI2C_REG_STAT_NACK) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -ENXIO; + } + } else { + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + } + + if (i2c->pos >= msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { + if (!(msg->flags & I2C_M_NOSTART)) { + i2c->state = STATE_ADDR; + return 0; + } else { + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } + } else { + i2c->state = STATE_DONE; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return 0; + } + } + + if (i2c->state == STATE_READ) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len - 1) ? + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + } else { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + } + + return 0; +} + +static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ind = 0, port_status=0, port_irq_status=0; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); + PRINT("%s:xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + for(ind=0;ind<64;ind++) + { + port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + } + return sprintf(buf,"0x%04x\n",fpgapci->xcvr_intr_count); +} +static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL); + +static struct attribute *port_attrs[] = { + &dev_attr_port_msi.attr, + NULL, +}; + +static struct attribute_group port_attr_grp = { + .attrs = port_attrs, +}; + + +static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) +{ + struct pci_dev *pdev = dev; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + int ind = 0, port_status=0, port_irq_status=0; + for(ind=0;ind<32;ind++) + { + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + if(port_irq_status&(IRQ_LTCH_STS|PRSNT_LTCH_STS)) + { + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + //write on clear + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + } + } + fpgapci->xcvr_intr_count++; + PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); + return IRQ_HANDLED; +} + +static irqreturn_t fpgaport_33_64_isr(int irq, void *dev) +{ + struct pci_dev *pdev = dev; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + int ind = 0, port_status=0, port_irq_status=0; + for(ind=32;ind<64;ind++) + { + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + if(port_irq_status| (IRQ_LTCH_STS|PRSNT_LTCH_STS)) + { + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + } + } + fpgapci->xcvr_intr_count++; + PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); + return IRQ_HANDLED; +} + +static void fpgai2c_process(struct fpgalogic_i2c *i2c) +{ + struct i2c_msg *msg = i2c->msg; + u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + + PRINT("fpgai2c_process in. status reg :0x%x\n", stat); + + if ((i2c->state == STATE_STOP) || (i2c->state == STATE_ERROR)) { + /* stop has been sent */ + PRINT("fpgai2c_process FPGAI2C_REG_CMD_IACK stat = 0x%x Set FPGAI2C_REG_CMD(0%x) FPGAI2C_REG_CMD_IACK = 0x%x\n" \ + ,stat, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if(i2c->state == STATE_STOP) { + i2c->state = STATE_DONE; + } + wake_up(&i2c->wait); + return; + } + + + /* error? */ + if (stat & FPGAI2C_REG_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + PRINT("fpgai2c_process FPGAI2C_REG_STAT_ARBLOST FPGAI2C_REG_CMD_STOP\n"); + fpgai2c_stop(i2c); + return; + } + + if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { + i2c->state = + (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & FPGAI2C_REG_STAT_NACK) { + i2c->state = STATE_ERROR; + fpgai2c_stop(i2c); + return; + } + } else + { + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + } + + /* end of msg? */ + if (i2c->pos == msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { /* end? */ + /* send start? */ + if (!(msg->flags & I2C_M_NOSTART)) { + + u8 addr = (msg->addr << 1); + + if (msg->flags & I2C_M_RD) + addr |= 1; + + i2c->state = STATE_START; + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + return; + } else + { + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } + } else { + i2c->state = STATE_STOP; + fpgai2c_stop(i2c); + return; + } + } + + if (i2c->state == STATE_READ) { + PRINT("fpgai2c_poll STATE_READ i2c->pos=%d msg->len-1 = 0x%x set FPGAI2C_REG_CMD = 0x%x\n",i2c->pos, msg->len-1, + i2c->pos == (msg->len-1) ? FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len-1) ? + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + } else { + PRINT("fpgai2c_process set FPGAI2C_REG_DATA(0x%x)\n",FPGAI2C_REG_DATA); + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + } +} + +static irqreturn_t fpgai2c_isr(int irq, void *dev_id) +{ + struct fpgalogic_i2c *i2c = dev_id; + fpgai2c_process(i2c); + + return IRQ_HANDLED; +} +void dell_get_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_lock(&i2c->lock); +} + +/** + * dell_release_mutex - release mutex + */ +void dell_release_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_unlock(&i2c->lock); +} + +static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + struct fpgalogic_i2c *i2c = i2c_get_adapdata(adap); + int ret; + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + + i2c->msg = msgs; + i2c->pos = 0; + i2c->nmsgs = num; + i2c->state = (use_irq == 1) ? STATE_START : STATE_INIT; + + PRINT("i2c->msg->addr = 0x%x i2c->msg->flags = 0x%x\n",i2c->msg->addr,i2c->msg->flags); + PRINT("I2C_M_RD = 0x%x i2c->msg->addr << 1 = 0x%x\n",I2C_M_RD,i2c->msg->addr << 1); + + if (!use_irq) { + /* Handle the transfer */ + while (time_before(jiffies, timeout)) { + dell_get_mutex(i2c); + ret = fpgai2c_poll(i2c); + dell_release_mutex(i2c); + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) + return (i2c->state == STATE_DONE) ? num : ret; + + if (ret == 0) + timeout = jiffies + HZ; + + usleep_range(5, 15); + } + + i2c->state = STATE_ERROR; + + return -ETIMEDOUT; + + + } else { + ret = -ETIMEDOUT; + PRINT("Set FPGAI2C_REG_DATA(0%x) val = 0x%x\n",FPGAI2C_REG_DATA, + (i2c->msg->addr << 1) | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); + + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, + (i2c->msg->addr << 1) | + ((i2c->msg->flags & I2C_M_RD) ? 1:0)); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + + /* Interrupt mode */ + if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || + (i2c->state == STATE_DONE), HZ)) + ret = (i2c->state == STATE_DONE) ? num : -EIO; + return ret; + } +} + +static int fpgai2c_init(struct fpgalogic_i2c *i2c) +{ + int prescale; + int diff; + u8 ctrl; + + if (i2c->reg_io_width == 0) + i2c->reg_io_width = 1; /* Set to default value */ + + if (!i2c->reg_set || !i2c->reg_get) { + bool be = 0; //1:big_endian 0:little_endian + + switch (i2c->reg_io_width) { + case 1: + i2c->reg_set = fpgai2c_reg_set_8; + i2c->reg_get = fpgai2c_reg_get_8; + break; + + case 2: + i2c->reg_set = be ? fpgai2c_reg_set_16be : fpgai2c_reg_set_16; + i2c->reg_get = be ? fpgai2c_reg_get_16be : fpgai2c_reg_get_16; + break; + + case 4: + i2c->reg_set = be ? fpgai2c_reg_set_32be : fpgai2c_reg_set_32; + i2c->reg_get = be ? fpgai2c_reg_get_32be : fpgai2c_reg_get_32; + break; + + default: + PRINT("Unsupported I/O width (%d)\n", + i2c->reg_io_width); + return -EINVAL; + } + } + + ctrl = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + + PRINT("%s(), line:%d\n", __func__, __LINE__); + PRINT("i2c->base = 0x%p\n",i2c->base); + + PRINT("ctrl = 0x%x\n",ctrl); + PRINT("set ctrl = 0x%x\n",ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); + + /* make sure the device is disabled */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); + + /* + * I2C Frequency depends on host clock + * input clock of 100MHz + * prescale to 100MHz / ( 5*100kHz) -1 = 199 = 0x4F 100000/(5*100)-1=199=0xc7 + */ + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); + + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + PRINT("Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } + + fpgai2c_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); + + /* Init the device */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (!use_irq) + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); + else + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); + + fpgai2c_dump(i2c); + + /* Initialize interrupt handlers if not already done */ + init_waitqueue_head(&i2c->wait); + + return 0; +} + + +static u32 fpgai2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm fpgai2c_algorithm = { + .master_xfer = fpgai2c_xfer, + .functionality = fpgai2c_func, +}; + +static int i2c_pci_add_bus (struct i2c_adapter *adap) +{ + int ret = 0; + /* Register new adapter */ + adap->algo = &fpgai2c_algorithm; + ret = i2c_add_numbered_adapter(adap); + return ret; +} + +static int i2c_init_internal_data(void) +{ + int i; + PRINT("%s(), line:%d\n", __func__, __LINE__); + + for( i = 0; i < total_i2c_pci_bus; i++ ) + { + fpgalogic_i2c[i].reg_shift = 0; /* 8 bit registers */ + fpgalogic_i2c[i].reg_io_width = 1; /* 8 bit read/write */ + fpgalogic_i2c[i].timeout = 500;//1000;//1ms + fpgalogic_i2c[i].ip_clock_khz = 100000;//100000;/* input clock of 100MHz */ + fpgalogic_i2c[i].bus_clock_khz = 100; + fpgalogic_i2c[i].base = fpga_base_addr + i*FPGALOGIC_CH_OFFSET; + mutex_init(&fpgalogic_i2c[i].lock); + fpgai2c_init(&fpgalogic_i2c[i]); + } + + return 0; +} + + +static int i2c_pci_init (void) +{ + int i; + + if (num_bus == 0) { + board_rev_type = ioread32(fpga_ctl_addr + MB_BRD_REV_TYPE); + + if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { + num_bus = I2C_PCI_MAX_BUS_REV00; + } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + switch (board_rev_type & MB_BRD_TYPE_MASK){ + case BRD_TYPE_S5212_NON_NEBS: + case BRD_TYPE_S5212_NEBS: + num_bus = I2C_PCI_BUS_NUM_5; + break; + case BRD_TYPE_S5224_NON_NEBS: + case BRD_TYPE_S5224_NEBS: + num_bus = I2C_PCI_BUS_NUM_7; + break; + case BRD_TYPE_Z9232_NON_NEBS: + case BRD_TYPE_Z9232_NEBS: + case BRD_TYPE_S5232_NON_NEBS: + case BRD_TYPE_S5232_NEBS: + num_bus = I2C_PCI_BUS_NUM_8; + break; + case BRD_TYPE_S5248_NON_NEBS: + case BRD_TYPE_S5248_NEBS: + num_bus = I2C_PCI_BUS_NUM_10; + break; + case BRD_TYPE_Z9264_NON_NEBS: + case BRD_TYPE_Z9264_NEBS: + num_bus = I2C_PCI_BUS_NUM_12; + break; + case BRD_TYPE_S5296_NON_NEBS: + case BRD_TYPE_S5296_NEBS: + num_bus = I2C_PCI_BUS_NUM_16; + break; + default: + num_bus = I2C_PCI_BUS_NUM_16; + printk("Wrong BRD_TYPE: 0x%x\n", board_rev_type); + break; + } + } else { + printk("Wrong board_rev_type 0x%x\n", board_rev_type); + } + } + + printk("board_rev_type 0x%x, num_bus 0x%x\n", board_rev_type, num_bus); + total_i2c_pci_bus = num_bus; + + memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); + memset (&fpgalogic_i2c, 0, sizeof(fpgalogic_i2c)); + for(i=0; i < i2c_bus_controller_numb; i++) + mutex_init(&i2c_xfer_lock[i]); + + /* Initialize driver's itnernal data structures */ + i2c_init_internal_data(); + + for (i = 0 ; i < total_i2c_pci_bus; i ++) { + + i2c_pci_adap[i].owner = THIS_MODULE; + i2c_pci_adap[i].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + + i2c_pci_adap[i].algo_data = &fpgalogic_i2c[i]; + /* /dev/i2c-600 ~ /dev/i2c-615 for FPGA LOGIC I2C channel controller 1-7 */ + i2c_pci_adap[i].nr = i+600; + sprintf( i2c_pci_adap[ i ].name, "i2c-pci-%d", i ); + /* Add the bus via the algorithm code */ + if( i2c_pci_add_bus( &i2c_pci_adap[ i ] ) != 0 ) + { + PRINT("Cannot add bus %d to algorithm layer\n", i ); + return( -ENODEV ); + } + i2c_set_adapdata(&i2c_pci_adap[i], &fpgalogic_i2c[i]); + + PRINT( "Registered bus id: %s\n", kobject_name(&i2c_pci_adap[ i ].dev.kobj)); + } + + return 0; +} + +static void i2c_pci_deinit(void) +{ + int i; + for( i = 0; i < total_i2c_pci_bus; i++ ){ + i2c_del_adapter(&i2c_pci_adap[i]); + } + +} + +/* Find upstream PCIe root node. + * Used for re-training and disabling AER. */ +static struct pci_dev* find_upstream_dev (struct pci_dev *dev) +{ + struct pci_bus *bus = 0; + struct pci_dev *bridge = 0; + struct pci_dev *cur = 0; + int found_dev = 0; + + bus = dev->bus; + if (bus == 0) { + PRINT ( "Device doesn't have an associated bus!\n"); + return 0; + } + + bridge = bus->self; + if (bridge == 0) { + PRINT ( "Can't get the bridge for the bus!\n"); + return 0; + } + + PRINT ( "Upstream device %x/%x, bus:slot.func %02x:%02x.%02x\n", + bridge->vendor, bridge->device, + bridge->bus->number, PCI_SLOT(bridge->devfn), PCI_FUNC(bridge->devfn)); + + PRINT ( "List of downstream devices:"); + list_for_each_entry (cur, &bus->devices, bus_list) { + if (cur != 0) { + PRINT ( " %x/%x", cur->vendor, cur->device); + if (cur == dev) { + found_dev = 1; + } + } + } + PRINT ( "\n"); + if (found_dev) { + return bridge; + } else { + PRINT ( "Couldn't find upstream device!\n"); + return 0; + } +} + + +static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) +{ + int i; + + for (i = 0; i < PCI_NUM_BARS; i++) { + unsigned long bar_start = pci_resource_start(dev, i); + if (bar_start) { + unsigned long bar_end = pci_resource_end(dev, i); + unsigned long bar_flags = pci_resource_flags(dev, i); + PRINT ( "BAR[%d] 0x%08lx-0x%08lx flags 0x%08lx", + i, bar_start, bar_end, bar_flags); + } + } + + return 0; +} + + +/** + * Map the device memory regions into kernel virtual address space + * after verifying their sizes respect the minimum sizes needed, given + * by the bar_min_len[] array. + */ +static int map_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) +{ + int i; + + for (i = 0; i < PCI_NUM_BARS; i++){ + phys_addr_t bar_start = pci_resource_start(dev, i); + phys_addr_t bar_end = pci_resource_end(dev, i); + unsigned long bar_length = bar_end - bar_start + 1; + fpgapci->bar_length[i] = bar_length; + + + if (!bar_start || !bar_end) { + fpgapci->bar_length[i] = 0; + continue; + } + + if (bar_length < 1) { + PRINT ( "BAR #%d length is less than 1 byte\n", i); + continue; + } + + PRINT ( "bar_start=%llx, bar_end=%llx, bar_length=%lx, flag=%lx\n", bar_start, + bar_end, bar_length, pci_resource_flags(dev, i)); + + /* map the device memory or IO region into kernel virtual + * address space */ + fpgapci->bar[i] = ioremap_nocache (bar_start + FPGALOGIC_I2C_BASE, I2C_PCI_MAX_BUS * FPGALOGIC_CH_OFFSET); + + if (!fpgapci->bar[i]) { + PRINT ( "Could not map BAR #%d.\n", i); + return -1; + } + + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.", i, + fpgapci->bar[i], bar_length); + + if(i == 0) //FPGA register is in the BAR[0] + { + + fpga_phys_addr = bar_start; + fpga_ctl_addr = ioremap_nocache (bar_start, FPGA_CTL_REG_SIZE); + fpga_base_addr = fpgapci->bar[i]; + } + + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.\n", i, + fpgapci->bar[i], bar_length); + } + return 0; +} + +static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) +{ + int i; + + for (i = 0; i < PCI_NUM_BARS; i++) { + if (fpgapci->bar[i]) { + pci_iounmap(dev, fpgapci->bar[i]); + fpgapci->bar[i] = NULL; + } + } +} + +#define FPGA_PCI_NAME "FPGA_PCI" + +/** + * @brief Register specific function with msi interrupt line + * @param dev Pointer to pci-device, which should be allocated + * @param int interrupt number relative to global interrupt number + * @return Returns error code or zero if success + * */ +static int register_intr_handler(struct pci_dev *dev, int irq_num_id) +{ + int err = 0; + struct fpgapci_dev *fpgapci = 0; + + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return err; + } + + if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { + /* Request interrupt line for unique function + * alternatively function will be called from free_irq as well + * with flag IRQF_SHARED */ + switch(irq_num_id) { + /* Currently we only support test vector 2 for FPGA Logic I2C channel + * controller 1-7 interrupt*/ + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_14: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; + } + } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ + switch (irq_num_id) { + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_14: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_15: + /*it is an external interrupt number. Ignore this case */ + break; + case FPGA_MSI_VECTOR_ID_16: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_7) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[7]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_17: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[8]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_18: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[9]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_19: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[10]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_20: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[11]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_21: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[12]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_22: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[13]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_23: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[14]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_24: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[15]); + fpgapci->irq_assigned++; + } + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; + } + } + + return err; +} +/* Mask for MSI Multi message enable bits */ +#define MSI_MME 0x70 +/** + * These enums define the type of interrupt scheme that the overall + * system uses. + */ +enum fpga_irq_type { + INT_MSI_SINGLE, + INT_MSI_MULTI, + INT_MSIX, + INT_NONE, + INT_FENCE /* Last item to guard from loop run-overs */ +}; +/** + * @def PCI_DEVICE_STATUS + * define the offset for STS register + * from the start of PCI config space as specified in the + * NVME_Comliance 1.0b. offset 06h:STS - Device status. + * This register has error status for NVME PCI Exress + * Card. After reading data from this reagister, the driver + * will identify if any error is set during the operation and + * report as kernel alert message. + */ +#define PCI_DEVICE_STATUS 0x6 +/** + * @def NEXT_MASK + * This indicates the location of the next capability item + * in the list. + */ +#define NEXT_MASK 0xFF00 +/** + * @def MSIXCAP_ID + * This bit indicates if the pointer leading to this position + * is a capability. + */ +#define MSIXCAP_ID 0x11 +/** + * @def MSICAP_ID + * This bit indicates if the pointer leading to this position + * is a capability. + */ +#define MSICAP_ID 0x5 + +/** + * @def CL_MASK + * This bit position indicates Capabilities List of the controller + * The controller should support the PCI Power Management cap as a + * minimum. + */ +#define CL_MASK 0x0010 + +/** + * @def CAP_REG + * Set to offset defined in NVME Spec 1.0b. + */ +#define CAP_REG 0x34 +static void msi_set_enable(struct pci_dev *dev, int enable) +{ + int pos,maxvec; + u16 control; + int request_private_bits = 4; + + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + + if (pos) { + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); + maxvec = 1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1); + PRINT("control = 0x%x maxvec = 0x%x\n", control, maxvec); + control &= ~PCI_MSI_FLAGS_ENABLE; + + + /* + * The PCI 2.3 spec mandates that there are at most 32 + * interrupts. If this device asks for more, only give it one. + */ + if (request_private_bits > 5) { + request_private_bits = 0; + } + + /* Update the number of IRQs the device has available to it */ + control &= ~PCI_MSI_FLAGS_QSIZE; + control |= (request_private_bits << 4); + + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); + } +} +/** + * @brief Enables pcie-device and claims/remaps neccessary bar resources + * @param dev Pointer to pci-device, which should be allocated + * @return Returns error code or zero if success + * */ +static int fpgapci_setup_device(struct fpgapci_dev *fpgapci,struct pci_dev *dev) +{ + int err = 0; + + /* wake up the pci device */ + err = pci_enable_device(dev); + if(err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_en; + } + + /* on platforms with buggy ACPI, pdev->msi_enabled may be set to + * allow pci_enable_device to work. This indicates INTx was not routed + * and only MSI should be used + */ + + pci_set_master(dev); + + /* Setup the BAR memory regions */ + err = pci_request_regions(dev, DRIVER_NAME); + if (err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_req; + } + + scan_bars(fpgapci, dev); + + if (map_bars(fpgapci, dev)) { + goto fail_map_bars; + } + + i2c_pci_init(); + + return 0; + /* ERROR HANDLING */ +fail_map_bars: + pci_release_regions(dev); +error_pci_req: + pci_disable_device(dev); +error_pci_en: + return -ENODEV; +} + +static int fpgapci_configure_msi(struct fpgapci_dev *fpgapci,struct pci_dev *dev) +{ + int err = 0, i; + int request_vec; + + msi_set_enable(dev,1); + PRINT("Check MSI capability after msi_set_enable\n"); + + + /*Above 4.1.12*/ + request_vec = total_i2c_pci_bus; + err = pci_alloc_irq_vectors(dev, request_vec, pci_msi_vec_count(dev), + PCI_IRQ_MSI);//PCI_IRQ_AFFINITY | PCI_IRQ_MSI); + + if (err <= 0) { + PRINT("Cannot set MSI vector (%d)\n", err); + goto error_no_msi; + } else { + PRINT("Got %d MSI vectors starting at %d\n", err, dev->irq); + if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { + if (err < MSI_VECTOR_REV_00) { + goto error_disable_msi; + } + } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + if (err < MSI_VECTOR_REV_01) { + goto error_disable_msi; + } + } + } + fpgapci->irq_first = dev->irq; + fpgapci->irq_length = err; + fpgapci->irq_assigned = 0; + + + for(i = 0; i < fpgapci->irq_length; i++) { + err = register_intr_handler(dev, i); + if (err) { + PRINT("Cannot request Interrupt number %d\n", i); + goto error_pci_req_irq; + } + } + + return 0; + +error_pci_req_irq: + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + if (i < 7) + free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); + else + free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); + } +error_disable_msi: + pci_disable_msi(fpgapci->pci_dev); +error_no_msi: + return -ENOSPC; +} + +static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + struct fpgapci_dev *fpgapci = 0; + int status = 0; + +#ifdef TEST + PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", + dev->vendor, dev->device, dev->class, + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); +#endif + fpgapci = kzalloc(sizeof(struct fpgapci_dev), GFP_KERNEL); + + if (!fpgapci) { + PRINT( "Couldn't allocate memory!\n"); + goto fail_kzalloc; + } + + fpgapci->pci_dev = dev; + dev_set_drvdata(&dev->dev, (void*)fpgapci); + + status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); + if (status) { + printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); + } + + fpgapci->upstream = find_upstream_dev (dev); + + if(fpgapci_setup_device(fpgapci,dev)) { + goto error_no_device; + } + + if (use_irq) { + if(fpgapci_configure_msi(fpgapci,dev)) { + goto error_cannot_configure; + } + } + + + return 0; + /* ERROR HANDLING */ +error_cannot_configure: + printk("error_cannot_configure\n"); + free_bars (fpgapci, dev); + pci_release_regions(dev); + pci_disable_device(dev); +error_no_device: + i2c_pci_deinit(); + printk("error_no_device\n"); +fail_kzalloc: + return -1; + + +} + +static void fpgapci_remove(struct pci_dev *dev) +{ + struct fpgapci_dev *fpgapci = 0; + int i; + PRINT (": dev is %p\n", dev); + + if (dev == 0) { + PRINT ( ": dev is 0\n"); + return; + } + + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return; + } + i2c_pci_deinit(); + // + if (use_irq) + { + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + if (i < 7) + free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); + else + free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); + } + } + pci_disable_msi(fpgapci->pci_dev); + free_bars (fpgapci, dev); + pci_disable_device(dev); + pci_release_regions(dev); + + kfree (fpgapci); +} + +static const struct pci_device_id fpgapci_ids[] = { + {PCI_DEVICE(PCI_VENDOR_ID_XILINX, DEVICE)}, + {0, }, +}; + +MODULE_DEVICE_TABLE(pci, fpgapci_ids); + +static struct pci_driver fpgapci_driver = { + .name = DRIVER_NAME, + .id_table = fpgapci_ids, + .probe = fpgapci_probe, + .remove = fpgapci_remove, + /* resume, suspend are optional */ +}; + +/* Initialize the driver module (but not any device) and register + * the module with the kernel PCI subsystem. */ +static int __init fpgapci_init(void) +{ + + if (pci_register_driver(&fpgapci_driver)) { + PRINT("pci_unregister_driver\n"); + pci_unregister_driver(&fpgapci_driver); + return -ENODEV; + } + + return 0; +} + +static void __exit fpgapci_exit(void) +{ + PRINT ("fpgapci_exit"); + + /* unregister this driver from the PCI bus driver */ + pci_unregister_driver(&fpgapci_driver); + +} + + +module_init (fpgapci_init); +module_exit (fpgapci_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("joyce_yu@dell.com"); +MODULE_DESCRIPTION ("Driver for FPGA Logic I2C bus"); +MODULE_SUPPORTED_DEVICE ("FPGA Logic I2C bus"); diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/pcisysfs.py new file mode 100755 index 000000000000..047618e057c8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/pcisysfs.py @@ -0,0 +1,102 @@ +#!/usr/bin/python +# Copyright (c) 2015 Dell Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. + +import struct +import sys +import getopt +from os import * +from mmap import * + +def usage(): + ''' This is the Usage Method ''' + + print '\t\t pcisysfs.py --get --offset --res ' + print '\t\t pcisysfs.py --set --val --offset --res ' + sys.exit(1) + +def pci_mem_read(mm,offset): + mm.seek(offset) + read_data_stream=mm.read(4) + print "" + reg_val=struct.unpack('I',read_data_stream) + print "reg_val read:%x"%reg_val + return reg_val + +def pci_mem_write(mm,offset,data): + mm.seek(offset) + print "data to write:%x"%data + mm.write(struct.pack('I',data)) + +def pci_set_value(resource,val,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_write(mm,offset,val) + +def pci_get_value(resource,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_read(mm,offset) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resource = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgsv:" , \ + ["val=","res=","offset=","help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt,arg in opts: + + if opt in ('-h','--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--res': + resource = arg + + elif opt == '--val': + val = int(arg,16) + + elif opt == '--offset': + offset = int(arg,16) + + if choice == 'set' and val != '' and offset !='' and resource !='': + pci_set_value(resource,val,offset) + + elif choice == 'get' and offset != '' and resource !='': + pci_get_value(resource,offset) + + else: + usage() + +#Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/platform_sensors.py new file mode 100755 index 000000000000..4c6ef3b229ab --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/platform_sensors.py @@ -0,0 +1,242 @@ +#!/usr/bin/python +# On S5296F, the BaseBoard Management Controller is an +# autonomous subsystem provides monitoring and management +# facility independent of the host CPU. IPMI standard +# protocol is used with ipmitool to fetch sensor details. +# Current script support X00 board only. X01 support will +# be added soon. This provies support for the +# following objects: +# * Onboard temperature sensors +# * FAN trays +# * PSU + + +import sys +import logging +import commands + +S5296F_MAX_FAN_TRAYS = 4 +S5296F_MAX_PSUS = 2 +IPMI_SENSOR_DATA = "ipmitool sdr list" +IPMI_SENSOR_DUMP = "/tmp/sdr" + +FAN_PRESENCE = "FAN{0}_prsnt" +PSU_PRESENCE = "PSU{0}_stat" +# Use this for older firmware +# PSU_PRESENCE="PSU{0}_prsnt" + +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" +ipmi_sdr_list = "" + +# Dump sensor registers + + +def ipmi_sensor_dump(): + + global ipmi_sdr_list + ipmi_cmd = IPMI_SENSOR_DATA + status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + + if status: + logging.error('Failed to execute:' + ipmi_sdr_list) + sys.exit(0) + +# Fetch a BMC register + + +def get_pmc_register(reg_name): + + output = None + for item in ipmi_sdr_list.split("\n"): + if reg_name in item: + output = item.strip() + + if output is None: + print('\nFailed to fetch: ' + reg_name + ' sensor ') + sys.exit(0) + + output = output.split('|')[1] + + logging.basicConfig(level=logging.DEBUG) + return output + + +# Print the information for temperature sensors + + +def print_temperature_sensors(): + + print("\nOnboard Temperature Sensors:") + + print ' PT_Left_temp: ',\ + (get_pmc_register('PT_Left_temp')) + print ' PT_Mid_temp: ',\ + (get_pmc_register('PT_Mid_temp')) + print ' PT_Right_temp: ',\ + (get_pmc_register('PT_Right_temp')) + print ' Broadcom Temp: ',\ + (get_pmc_register('NPU_Near_temp')) + print ' Inlet Airflow Temp: ',\ + (get_pmc_register('ILET_AF_temp')) + print ' CPU Temp: ',\ + (get_pmc_register('CPU_temp')) + +ipmi_sensor_dump() + +print_temperature_sensors() + +# Print the information for 1 Fan Tray + + +def print_fan_tray(tray): + + Fan_Status = [' Normal', ' Abnormal'] + + print ' Fan Tray ' + str(tray) + ':' + + if (tray == 1): + + fan2_status = int(get_pmc_register('FAN1_Rear_stat'), 16) + + print ' Fan Speed: ',\ + get_pmc_register('FAN1_Rear_rpm') + print ' Fan State: ',\ + Fan_Status[fan2_status] + + elif (tray == 2): + + fan2_status = int(get_pmc_register('FAN2_Rear_stat'), 16) + + print ' Fan Speed: ',\ + get_pmc_register('FAN2_Rear_rpm') + print ' Fan State: ',\ + Fan_Status[fan2_status] + + elif (tray == 3): + + fan2_status = int(get_pmc_register('FAN3_Rear_stat'), 16) + + print ' Fan Speed: ',\ + get_pmc_register('FAN3_Rear_rpm') + print ' Fan State: ',\ + Fan_Status[fan2_status] + + elif (tray == 4): + + fan2_status = int(get_pmc_register('FAN4_Rear_stat'), 16) + + print ' Fan Speed: ',\ + get_pmc_register('FAN4_Rear_rpm') + print ' Fan State: ',\ + Fan_Status[fan2_status] + + +print('\nFan Trays:') + +for tray in range(1, S5296F_MAX_FAN_TRAYS + 1): + fan_presence = FAN_PRESENCE.format(tray) + if (get_pmc_register(fan_presence)): + print_fan_tray(tray) + else: + print '\n Fan Tray ' + str(tray + 1) + ': Not present' + + def get_psu_presence(index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + + if index == 1: + status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + + #if ret_status: + # print ipmi_cmd_ret + # logging.error('Failed to execute ipmitool') + # sys.exit(0) + + psu_status = ipmi_cmd_ret + + if psu_status == '1': + status = 1 + + return status + + +# Print the information for PSU1, PSU2 +def print_psu(psu): + + # print ' Input: ', Psu_Input_Type[psu_input_type] + # print ' Type: ', Psu_Type[psu_type] + + # PSU FAN details + if (psu == 1): + + # psu1_fan_status = int(get_pmc_register('PSU1_status'),16) + + print ' PSU1:' + print ' FAN Normal Temperature: ',\ + get_pmc_register('PSU1_temp') + print ' FAN AirFlow Temperature: ',\ + get_pmc_register('PSU1_AF_temp') + print ' FAN RPM: ',\ + get_pmc_register('PSU1_rpm') + # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] + + # PSU input & output monitors + print ' Input Voltage: ',\ + get_pmc_register('PSU1_In_volt') + print ' Output Voltage: ',\ + get_pmc_register('PSU1_Out_volt') + print ' Input Power: ',\ + get_pmc_register('PSU1_In_watt') + print ' Output Power: ',\ + get_pmc_register('PSU1_Out_watt') + print ' Input Current: ',\ + get_pmc_register('PSU1_In_amp') + print ' Output Current: ',\ + get_pmc_register('PSU1_Out_amp') + + else: + + # psu2_fan_status = int(get_pmc_register('PSU1_status'),16) + print ' PSU2:' + print ' FAN Normal Temperature: ',\ + get_pmc_register('PSU2_temp') + print ' FAN AirFlow Temperature: ',\ + get_pmc_register('PSU2_AF_temp') + print ' FAN RPM: ',\ + get_pmc_register('PSU2_rpm') + # print ' FAN Status: ', Psu_Fan_Status[psu2_fan_status] + + # PSU input & output monitors + print ' Input Voltage: ',\ + get_pmc_register('PSU2_In_volt') + print ' Output Voltage: ',\ + get_pmc_register('PSU2_Out_volt') + print ' Input Power: ',\ + get_pmc_register('PSU2_In_watt') + print ' Output Power: ',\ + get_pmc_register('PSU2_Out_watt') + print ' Input Current: ',\ + get_pmc_register('PSU2_In_amp') + print ' Output Current: ',\ + get_pmc_register('PSU2_Out_amp') + + +print('\nPSUs:') +for psu in range(1, S5296F_MAX_PSUS + 1): + #psu_presence = PSU_PRESENCE.format(psu) + if (get_psu_presence(psu)): + print_psu(psu) + else: + print '\n PSU ', psu, 'Not present' + +print '\n Total Power: ',\ + get_pmc_register('PSU_Total_watt') + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/qsfp_irq_enable.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/qsfp_irq_enable.py new file mode 100755 index 000000000000..d9bf5b09411a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/qsfp_irq_enable.py @@ -0,0 +1,31 @@ +#!/usr/bin/python + +try: + import struct + from os import * + from mmap import * + +except ImportError as e: + raise ImportError("%s - required module no found" % str(e)) + +BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" +PORT_START = 0 +PORT_END = 32 + + +def pci_mem_write(mm, offset, data): + mm.seek(offset) + mm.write(struct.pack('I', data)) + + +def pci_set_value(resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + +for port_num in range(PORT_START, PORT_END+1): + port_offset = 0x400c + ((port_num) * 16) + pci_set_value(BASE_RES_PATH, 0x30, port_offset) diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/s5296f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/s5296f_platform.sh new file mode 100755 index 000000000000..f69470756001 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/s5296f_platform.sh @@ -0,0 +1,176 @@ +#!/bin/bash + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # iSMT adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus iSMT adapter at '* ]]; then + found=1 + break + fi + done + + [ $found -eq 0 ] && echo "cannot find iSMT" && exit 1 +} + +# Attach/Detach syseeprom on CPU board +sys_eeprom() { + b='' + for bb in 0 1; do + if [ "$(cat /sys/bus/i2c/devices/i2c-${bb}/name)" = 'SMBus iSMT adapter at dff9f000' ]; then + b=$bb + break + fi + done + if [ "$b" = '' ]; then + echo "s5296f_platform: sys_eeprom : cannot find I2C bus!" + return + fi + + case $1 in + "new_device") echo 24c16 0x50 > /sys/bus/i2c/devices/i2c-${b}/$1 + ;; + + "delete_device") echo 0x50 > /sys/bus/i2c/devices/i2c-${b}/$1 + ;; + + *) echo "s5296f_platform: sys_eeprom : invalid command !" + ;; + esac +} + +#Attach/Detach the MUX connecting all QSFPs +switch_board_qsfp_mux() { + case $1 in + "new_device") + for ((i=603;i<=615;i++)); + do + echo "Attaching PCA9548 @ 0x74" + echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=603;i<=615;i++)); + do + echo "Detaching PCA9548 @ 0x74" + echo 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) + echo "s5296f_platform: switch_board_qsfp_mux: invalid command !" + ;; + esac + sleep 2 +} + +#Attach/Detach 64 instances of EEPROM driver QSFP ports +#eeprom can dump data using below command +switch_board_qsfp() { + case $1 in + "new_device") + for ((i=2;i<=105;i++)); + do + echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=2;i<=105;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "s5296f_platform: switch_board_qsfp: invalid command !" + ;; + esac +} + +#Modsel 64 ports to applicable QSFP type modules +#This enables the adapter to respond for i2c commands +switch_board_modsel() { + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + for ((i=1;i<=104;i++)); + do + port_addr=$(( 16384 + ((i - 1) * 16))) + hex=$( printf "0x%x" $port_addr ) + python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + done +} + +platform_firmware_versions() { + FIRMWARE_VERSION_FILE=/var/log/firmware_versions + rm -rf ${FIRMWARE_VERSION_FILE} + echo "BIOS: `dmidecode -s system-version `" > $FIRMWARE_VERSION_FILE + ## Get FPGA version + r=`/usr/bin/pcisysfs.py --get --offset 0x00 --res /sys/bus/pci/devices/0000\:04\:00.0/resource0 | sed '1d; s/.*\(....\)$/\1/; s/\(..\{1\}\)/\1./'` + r_min=$(echo $r | sed 's/.*\(..\)$/0x\1/') + r_maj=$(echo $r | sed 's/^\(..\).*/0x\1/') + echo "FPGA: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + ## Get BMC Firmware Revision + r=`cat /sys/class/ipmi/ipmi0/device/bmc/firmware_revision` + echo "BMC: $r" >> $FIRMWARE_VERSION_FILE + + #System CPLD 0x31 on i2c bus 601 ( physical FPGA I2C-2) + r_min=`/usr/sbin/i2cget -y 601 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 601 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "System CPLD: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 1 0x30 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x30 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x30 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 1: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 2 0x31 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 2: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x32 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x32 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 3: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x33 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x33 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE +} + +#This enables the led control for CPU and default states +switch_board_led_default() { + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + python /usr/bin/pcisysfs.py --set --offset 0x24 --val 0x194 --res $resource > /dev/null 2>&1 +} +init_devnum + +if [ "$1" == "init" ]; then + modprobe i2c-dev + modprobe i2c-mux-pca954x force_deselect_on_exit=1 + modprobe ipmi_devintf + modprobe ipmi_si + modprobe i2c_ocores + modprobe dell_s5296f_fpga_ocores + sys_eeprom "new_device" + switch_board_qsfp_mux "new_device" + switch_board_qsfp "new_device" + switch_board_modsel + switch_board_led_default + #python /usr/bin/qsfp_irq_enable.py + platform_firmware_versions + +elif [ "$1" == "deinit" ]; then + sys_eeprom "delete_device" + switch_board_qsfp "delete_device" + switch_board_qsfp_mux "delete_device" + + modprobe -r i2c-mux-pca954x + modprobe -r i2c-dev +else + echo "s5296f_platform : Invalid option !" +fi + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/sensors b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/sensors new file mode 100755 index 000000000000..d163a09cfc1b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/sensors @@ -0,0 +1,3 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" +docker exec -i pmon /usr/bin/platform_sensors.py "$@" diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/systemd/platform-modules-s5296f.service b/platform/broadcom/sonic-platform-modules-dell/s5296f/systemd/platform-modules-s5296f.service new file mode 100644 index 000000000000..b58673d505ac --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/systemd/platform-modules-s5296f.service @@ -0,0 +1,13 @@ +[Unit] +Description=Dell S5296f Platform modules +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/s5296f_platform.sh init +ExecStop=/usr/local/bin/s5296f_platform.sh deinit +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target From 63d40865ab3535abc49d6788c85252210c4da07e Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 22 Oct 2020 08:28:02 -0700 Subject: [PATCH 1268/1427] [Submodule] sonic-restapi (#5679) 37a7c61 - 2020-10-16 : Add to local route DB if ifname present in route add API (#51) [Sumukha Tumkur Vani] 2b4b6d7 - 2020-10-01 : Fix typo (#50) [Sumukha Tumkur Vani] f0a527b - 2020-09-24 : Use RESTAPI_DB, cache reset_status (#49) [Prince Sunny] --- src/sonic-restapi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-restapi b/src/sonic-restapi index 71b81892fc51..37a7c616bcb5 160000 --- a/src/sonic-restapi +++ b/src/sonic-restapi @@ -1 +1 @@ -Subproject commit 71b81892fc5128e9b0bce42f889987888860126a +Subproject commit 37a7c616bcb52be0416aa31f22d22e7c34f4dba3 From ef8a48a7288234987370f62eac875572dd9d04c8 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Thu, 22 Oct 2020 10:29:46 -0700 Subject: [PATCH 1269/1427] Everflow and Dataacl were getting binded to Backplane port-channels. (#5691) Issue was because we were relying on port_alias_asic_map dictionary but that dictionary can't be used as alias name format has changed. Fix the port alias mapping as what is needed. Signed-off-by: Abhishek Dosi --- src/sonic-config-engine/minigraph.py | 14 ++++++++------ .../multi_npu_data/sample_port_config-0.ini | 8 ++++---- .../multi_npu_data/sample_port_config-1.ini | 10 +++++----- .../multi_npu_data/sample_port_config-2.ini | 18 +++++++++--------- .../multi_npu_data/sample_port_config-3.ini | 18 +++++++++--------- .../tests/test_multinpu_cfggen.py | 10 +++++----- 6 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 62cb77600e47..d53a56d7daea 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -727,13 +727,13 @@ def filter_acl_table_bindings(acls, neighbors, port_channels, sub_role): return filter_acls front_port_channel_intf = [] + + # List of Backplane ports + backplane_port_list = [v for k,v in port_alias_map.items() if v.startswith(backplane_prefix())] - # Get the front panel port channel. It will use port_alias_asic_map - # which will get populated from port_config.ini for Multi-NPU - # architecture + # Get the front panel port channel. for port_channel_intf in port_channels: - backend_port_channel = any(lag_member in port_alias_asic_map \ - and lag_member.startswith(backplane_prefix()) \ + backend_port_channel = any(lag_member in backplane_port_list \ for lag_member in port_channels[port_channel_intf]['members']) if not backend_port_channel: front_port_channel_intf.append(port_channel_intf) @@ -755,8 +755,10 @@ def filter_acl_table_bindings(acls, neighbors, port_channels, sub_role): # This will be applicable in Multi-NPU Platforms. front_panel_ports = [] for port in group_params.get('ports', []): - if port in port_alias_asic_map and port.startswith(backplane_prefix()): + # Filter out backplane ports + if port in backplane_port_list: continue + # Filter out backplane port channels if port in port_channels and port not in front_port_channel_intf: continue front_panel_ports.append(port) diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini index 5b2786fd8aa8..b6b0379f6072 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini @@ -3,7 +3,7 @@ Ethernet0 33,34,35,36 Ethernet1/1 0 Eth0-ASIC0 Ext Ethernet4 29,30,31,32 Ethernet1/2 1 Eth1-ASIC0 Ext Ethernet8 41,42,43,44 Ethernet1/3 2 Eth2-ASIC0 Ext Ethernet12 37,38,39,40 Ethernet1/4 3 Eth3-ASIC0 Ext -Ethernet-BP0 13,14,15,16 Ethernet-BP0 0 Eth4-ASIC0 Int -Ethernet-BP4 17,18,19,20 Ethernet-BP4 1 Eth5-ASIC0 Int -Ethernet-BP8 21,22,23,24 Ethernet-BP8 2 Eth6-ASIC0 Int -Ethernet-BP12 25,26,27,28 Ethernet-BP12 3 Eth7-ASIC0 Int \ No newline at end of file +Ethernet-BP0 13,14,15,16 Eth4-ASIC0 0 Eth4-ASIC0 Int +Ethernet-BP4 17,18,19,20 Eth5-ASIC0 1 Eth5-ASIC0 Int +Ethernet-BP8 21,22,23,24 Eth6-ASIC0 2 Eth6-ASIC0 Int +Ethernet-BP12 25,26,27,28 Eth7-ASIC0 3 Eth7-ASIC0 Int diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini index 9764ede9736a..a581b19fd61a 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini @@ -1,9 +1,9 @@ -# name lanes alias index asic_port_name role +# name lanes alias index asic_port_name role Ethernet16 33,34,35,36 Ethernet1/5 4 Eth0-ASIC1 Ext Ethernet20 29,30,31,32 Ethernet1/6 5 Eth1-ASIC1 Ext Ethernet24 41,42,43,44 Ethernet1/7 6 Eth2-ASIC1 Ext Ethernet28 37,38,39,40 Ethernet1/8 7 Eth3-ASIC1 Ext -Ethernet-BP16 13,14,15,16 Ethernet-BP16 4 Eth4-ASIC1 Int -Ethernet-BP20 17,18,19,20 Ethernet-BP20 5 Eth5-ASIC1 Int -Ethernet-BP24 21,22,23,24 Ethernet-BP24 6 Eth6-ASIC1 Int -Ethernet-BP28 25,26,27,28 Ethernet-BP28 7 Eth7-ASIC1 Int \ No newline at end of file +Ethernet-BP16 13,14,15,16 Eth4-ASIC1 4 Eth4-ASIC1 Int +Ethernet-BP20 17,18,19,20 Eth5-ASIC1 5 Eth5-ASIC1 Int +Ethernet-BP24 21,22,23,24 Eth6-ASIC1 6 Eth6-ASIC1 Int +Ethernet-BP28 25,26,27,28 Eth7-ASIC1 7 Eth7-ASIC1 Int diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini index b3bc03dbe915..71467a9a6ec4 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini @@ -1,9 +1,9 @@ -# name lanes alias index asic_port_name role -Ethernet-BP256 61,62,63,64 Ethernet-BP256 8 Eth0-ASIC2 Int -Ethernet-BP260 57,58,59,60 Ethernet-BP260 9 Eth1-ASIC2 Int -Ethernet-BP264 53,54,55,56 Ethernet-BP264 10 Eth2-ASIC2 Int -Ethernet-BP268 49,50,51,52 Ethernet-BP268 11 Eth3-ASIC2 Int -Ethernet-BP272 45,46,47,48 Ethernet-BP272 12 Eth4-ASIC2 Int -Ethernet-BP276 41,42,43,44 Ethernet-BP276 13 Eth5-ASIC2 Int -Ethernet-BP280 37,38,39,40 Ethernet-BP280 14 Eth6-ASIC2 Int -Ethernet-BP284 33,34,35,36 Ethernet-BP284 15 Eth7-ASIC2 Int \ No newline at end of file +# name lanes alias index asic_port_name role +Ethernet-BP256 61,62,63,64 Eth0-ASIC2 8 Eth0-ASIC2 Int +Ethernet-BP260 57,58,59,60 Eth1-ASIC2 9 Eth1-ASIC2 Int +Ethernet-BP264 53,54,55,56 Eth2-ASIC2 10 Eth2-ASIC2 Int +Ethernet-BP268 49,50,51,52 Eth3-ASIC2 11 Eth3-ASIC2 Int +Ethernet-BP272 45,46,47,48 Eth4-ASIC2 12 Eth4-ASIC2 Int +Ethernet-BP276 41,42,43,44 Eth5-ASIC2 13 Eth5-ASIC2 Int +Ethernet-BP280 37,38,39,40 Eth6-ASIC2 14 Eth6-ASIC2 Int +Ethernet-BP284 33,34,35,36 Eth7-ASIC2 15 Eth7-ASIC2 Int diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini index 2fb7f4ae6ad0..e786bbdd8f62 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini @@ -1,9 +1,9 @@ -# name lanes alias index asic_port_name role -Ethernet-BP384 29,30,31,32 Ethernet-BP384 16 Eth0-ASIC3 Int -Ethernet-BP388 25,26,27,28 Ethernet-BP388 17 Eth1-ASIC3 Int -Ethernet-BP392 21,22,23,24 Ethernet-BP392 18 Eth2-ASIC3 Int -Ethernet-BP396 17,18,19,20 Ethernet-BP396 19 Eth3-ASIC3 Int -Ethernet-BP400 13,14,15,16 Ethernet-BP400 20 Eth4-ASIC3 Int -Ethernet-BP404 9,10,11,12 Ethernet-BP404 21 Eth5-ASIC3 Int -Ethernet-BP408 5,6,7,8 Ethernet-BP408 22 Eth6-ASIC3 Int -Ethernet-BP412 1,2,3,4 Ethernet-BP412 23 Eth7-ASIC3 Int \ No newline at end of file +# name lanes alias index asic_port_name role +Ethernet-BP384 29,30,31,32 Eth0-ASIC3 16 Eth0-ASIC3 Int +Ethernet-BP388 25,26,27,28 Eth1-ASIC3 17 Eth1-ASIC3 Int +Ethernet-BP392 21,22,23,24 Eth2-ASIC3 18 Eth2-ASIC3 Int +Ethernet-BP396 17,18,19,20 Eth3-ASIC3 19 Eth3-ASIC3 Int +Ethernet-BP400 13,14,15,16 Eth4-ASIC3 20 Eth4-ASIC3 Int +Ethernet-BP404 9,10,11,12 Eth5-ASIC3 21 Eth5-ASIC3 Int +Ethernet-BP408 5,6,7,8 Eth6-ASIC3 22 Eth6-ASIC3 Int +Ethernet-BP412 1,2,3,4 Eth7-ASIC3 23 Eth7-ASIC3 Int diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 8c2e59d99ba7..1802d8d30210 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -181,11 +181,11 @@ def test_frontend_asic_ports(self): "Ethernet4": { "admin_status": "up", "alias": "Ethernet1/2", "asic_port_name": "Eth1-ASIC0", "description": "01T2:Ethernet2", "index": "1", "lanes": "29,30,31,32", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, "Ethernet8": { "alias": "Ethernet1/3", "asic_port_name": "Eth2-ASIC0", "description": "Ethernet1/3", "index": "2", "lanes": "41,42,43,44", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, "Ethernet12": { "alias": "Ethernet1/4", "asic_port_name": "Eth3-ASIC0", "description": "Ethernet1/4", "index": "3", "lanes": "37,38,39,40", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, - "Ethernet-BP0": { "admin_status": "up", "alias": "Ethernet-BP0", "asic_port_name": "Eth4-ASIC0", "description": "ASIC2:Eth0-ASIC2", "index": "0", "lanes": "13,14,15,16", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, - "Ethernet-BP4": { "admin_status": "up", "alias": "Ethernet-BP4", "asic_port_name": "Eth5-ASIC0", "description": "ASIC2:Eth1-ASIC2", "index": "1", "lanes": "17,18,19,20", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, - "Ethernet-BP8": { "admin_status": "up", "alias": "Ethernet-BP8", "asic_port_name": "Eth6-ASIC0", "description": "ASIC3:Eth0-ASIC3", "index": "2", "lanes": "21,22,23,24", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, - "Ethernet-BP12": { "admin_status": "up", "alias": "Ethernet-BP12", "asic_port_name": "Eth7-ASIC0", "description": "ASIC3:Eth1-ASIC3", "index": "3", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }}) - + "Ethernet-BP0": { "admin_status": "up", "alias": "Eth4-ASIC0", "asic_port_name": "Eth4-ASIC0", "description": "ASIC2:Eth0-ASIC2", "index": "0", "lanes": "13,14,15,16", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, + "Ethernet-BP4": { "admin_status": "up", "alias": "Eth5-ASIC0", "asic_port_name": "Eth5-ASIC0", "description": "ASIC2:Eth1-ASIC2", "index": "1", "lanes": "17,18,19,20", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, + "Ethernet-BP8": { "admin_status": "up", "alias": "Eth6-ASIC0", "asic_port_name": "Eth6-ASIC0", "description": "ASIC3:Eth0-ASIC3", "index": "2", "lanes": "21,22,23,24", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, + "Ethernet-BP12": { "admin_status": "up", "alias": "Eth7-ASIC0", "asic_port_name": "Eth7-ASIC0", "description": "ASIC3:Eth1-ASIC3", "index": "3", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }}) + def test_frontend_asic_device_neigh(self): argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) output = json.loads(self.run_script(argument)) From 78955138131cae52d0bc49d5e26dadb29a4aade2 Mon Sep 17 00:00:00 2001 From: Petro Bratash <68950226+bratashX@users.noreply.github.com> Date: Thu, 22 Oct 2020 20:34:18 +0300 Subject: [PATCH 1270/1427] [BFN] Rename variable in Montara platform debian/rules (#5675) Platforms .deb-package is not installed into the right directory, because variable PLATFORM was defined previously and variable in the makefile is ignored. https://www.gnu.org/software/make/manual/html_node/Overriding.html --- .../sonic-platform-modules-bfn-montara/debian/rules | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules index 3377688e6097..b04234a0df1b 100755 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules @@ -1,6 +1,6 @@ #!/usr/bin/make -f -PLATFORM := x86_64-accton_wedge100bf_32x-r0 +PLATFORM_NAME := x86_64-accton_wedge100bf_32x-r0 PACKAGE_NAME := sonic-platform-modules-bfn-montara SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs @@ -22,10 +22,10 @@ override_dh_auto_install: cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ - dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/$(PLATFORM)/ - cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/$(PLATFORM)/ - dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/$(PLATFORM)/plugins - cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/$(PLATFORM)/plugins/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/$(PLATFORM_NAME)/ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/$(PLATFORM_NAME)/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/$(PLATFORM_NAME)/plugins + cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/$(PLATFORM_NAME)/plugins/ override_dh_usrlocal: From f18bcbf142a75a927089022714faf0cdd76b5e7e Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Thu, 22 Oct 2020 23:19:25 +0530 Subject: [PATCH 1271/1427] DellEMC S5232 Buffer profile changes (#5671) Modified the correct settings for DellEMC S5232 buffer settings. Increased Egress pool size from 28MB to 32 MB. --- .../DellEMC-S5232f-C32/buffers_defaults_t0.j2 | 17 ++++---- .../DellEMC-S5232f-C32/buffers_defaults_t1.j2 | 15 ++++--- .../td3-s5232f-32x100G.config.bcm | 2 +- .../buffers_defaults_t0.j2 | 17 ++++---- .../buffers_defaults_t1.j2 | 16 +++---- .../td3-s5232f-8x100G+48x50G.config.bcm | 2 +- .../buffers_defaults_t0.j2 | 42 +++++++------------ .../buffers_defaults_t1.j2 | 40 +++++++----------- .../td3-s5232f-32x100G.config.bcm | 2 +- .../buffers_defaults_t0.j2 | 42 +++++++------------ .../buffers_defaults_t1.j2 | 40 +++++++----------- .../td3-s5232f-96x10G+8x100G.config.bcm | 2 +- .../buffers_defaults_t0.j2 | 42 +++++++------------ .../buffers_defaults_t1.j2 | 40 +++++++----------- .../td3-s5232f-96x25G+8x100G.config.bcm | 2 +- 15 files changed, 129 insertions(+), 192 deletions(-) diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2 index 98ec91a9b694..3369e2cc5e4d 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2 @@ -1,16 +1,15 @@ - -{%- set default_cable = '40m' %} +{%- set default_cable = '5m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "28550336", + "size": "26284032", "type": "ingress", "mode": "dynamic", - "xoff": "4194112" + "xoff": "6291456" }, - "egress_pool": { - "size": "28550336", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", "mode": "static" } @@ -22,13 +21,13 @@ "dynamic_th":"3" }, "egress_lossless_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "static", - "static_th":"32744448" + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "dynamic", "dynamic_th":"3" diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2 index 98ec91a9b694..a1fa90d39779 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2 @@ -1,16 +1,15 @@ - {%- set default_cable = '40m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "28550336", + "size": "26284032", "type": "ingress", "mode": "dynamic", - "xoff": "4194112" + "xoff": "6291456" }, - "egress_pool": { - "size": "28550336", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", "mode": "static" } @@ -22,13 +21,13 @@ "dynamic_th":"3" }, "egress_lossless_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "static", - "static_th":"32744448" + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "dynamic", "dynamic_th":"3" diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm index 9b1035a942b3..3f50f39db8e5 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm @@ -541,6 +541,6 @@ dport_map_port_129=126 dport_map_port_66=127 dport_map_port_130=128 -mmu_init_config="TD3-DEFAULT-LOSSLESS-P3P4" +mmu_init_config="TD3-DELL-lossless" sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 index 98ec91a9b694..3369e2cc5e4d 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 @@ -1,16 +1,15 @@ - -{%- set default_cable = '40m' %} +{%- set default_cable = '5m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "28550336", + "size": "26284032", "type": "ingress", "mode": "dynamic", - "xoff": "4194112" + "xoff": "6291456" }, - "egress_pool": { - "size": "28550336", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", "mode": "static" } @@ -22,13 +21,13 @@ "dynamic_th":"3" }, "egress_lossless_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "static", - "static_th":"32744448" + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "dynamic", "dynamic_th":"3" diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 index 98ec91a9b694..3a8e9a92261a 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 @@ -1,16 +1,15 @@ - {%- set default_cable = '40m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "28550336", + "size": "26284032", "type": "ingress", "mode": "dynamic", - "xoff": "4194112" + "xoff": "6291456" }, - "egress_pool": { - "size": "28550336", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", "mode": "static" } @@ -22,16 +21,17 @@ "dynamic_th":"3" }, "egress_lossless_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "static", - "static_th":"32744448" + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm index b9762a712d94..4f3121387dea 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm @@ -567,6 +567,6 @@ dport_map_port_129=126 dport_map_port_66=127 dport_map_port_130=128 -mmu_init_config="TD3-DEFAULT-LOSSLESS-P3P4" +mmu_init_config="TD3-DELL-lossless" sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t0.j2 index c31728e46543..3369e2cc5e4d 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t0.j2 @@ -1,46 +1,36 @@ - -{%- set default_cable = '40m' %} +{%- set default_cable = '5m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2 index c31728e46543..a1fa90d39779 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2 @@ -1,46 +1,36 @@ - {%- set default_cable = '40m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm index e2735ded69e8..099d1270443e 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm @@ -541,5 +541,5 @@ dport_map_port_129=126 dport_map_port_66=127 dport_map_port_130=128 -mmu_init_config="TD3-DEFAULT" +mmu_init_config="TD3-DELL-lossless" sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t0.j2 index c31728e46543..3369e2cc5e4d 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t0.j2 @@ -1,46 +1,36 @@ - -{%- set default_cable = '40m' %} +{%- set default_cable = '5m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2 index c31728e46543..a1fa90d39779 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2 @@ -1,46 +1,36 @@ - {%- set default_cable = '40m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm index 0346c47749cb..caf255d892e8 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm @@ -614,5 +614,5 @@ dport_map_port_129=126 dport_map_port_66=127 dport_map_port_130=128 -mmu_init_config="TD3-DEFAULT" +mmu_init_config="TD3-DELL-lossless" sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t0.j2 index c31728e46543..3369e2cc5e4d 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t0.j2 @@ -1,46 +1,36 @@ - -{%- set default_cable = '40m' %} +{%- set default_cable = '5m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2 index c31728e46543..a1fa90d39779 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2 @@ -1,46 +1,36 @@ - {%- set default_cable = '40m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm index ca81379ae512..84bd873acc4b 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm @@ -614,5 +614,5 @@ dport_map_port_129=126 dport_map_port_66=127 dport_map_port_130=128 -mmu_init_config="TD3-DEFAULT" +mmu_init_config="TD3-DELL-lossless" sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc From c94f93f046cc3d176c40ad2177051b20bc48d313 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 22 Oct 2020 11:04:21 -0700 Subject: [PATCH 1272/1427] [bgpcfgd]: Dynamic BBR support (#5626) **- Why I did it** To introduce dynamic support of BBR functionality into bgpcfgd. BBR is adding `neighbor PEER_GROUP allowas-in 1' for all BGP peer-groups which points to T0 Now we can add and remove this configuration based on CONFIG_DB entry **- How I did it** I introduced a new CONFIG_DB entry: - table name: "BGP_BBR" - key value: "all". Currently only "all" is supported, which means that all peer-groups which points to T0s will be updated - data value: a dictionary: {"status": "status_value"}, where status_value could be either "enabled" or "disabled" Initially, when bgpcfgd starts, it reads initial BBR status values from the [constants.yml](https://github.com/Azure/sonic-buildimage/pull/5626/files#diff-e6f2fe13a6c276dc2f3b27a5bef79886f9c103194be4fcb28ce57375edf2c23cR34). Then you can control BBR status by changing "BGP_BBR" table in the CONFIG_DB (see examples below). bgpcfgd knows what peer-groups to change fron [constants.yml](https://github.com/Azure/sonic-buildimage/pull/5626/files#diff-e6f2fe13a6c276dc2f3b27a5bef79886f9c103194be4fcb28ce57375edf2c23cR39). The dictionary contains peer-group names as keys, and a list of address-families as values. So when bgpcfgd got a request to change the BBR state, it changes the state only for peer-groups listed in the constants.yml dictionary (and only for address families from the peer-group value). **- How to verify it** Initially, when we start SONiC FRR has BBR enabled for PEER_V4 and PEER_V6: ``` admin@str-s6100-acs-1:~$ vtysh -c 'show run' | egrep 'PEER_V.? allowas' neighbor PEER_V4 allowas-in 1 neighbor PEER_V6 allowas-in 1 ``` Then we apply following configuration to the db: ``` admin@str-s6100-acs-1:~$ cat disable.json { "BGP_BBR": { "all": { "status": "disabled" } } } admin@str-s6100-acs-1:~$ sonic-cfggen -j disable.json -w ``` The log output are: ``` Oct 14 18:40:22.450322 str-s6100-acs-1 DEBUG bgp#bgpcfgd: Received message : '('all', 'SET', (('status', 'disabled'),))' Oct 14 18:40:22.450620 str-s6100-acs-1 DEBUG bgp#bgpcfgd: execute command '['vtysh', '-f', '/tmp/tmpmWTiuq']'. Oct 14 18:40:22.681084 str-s6100-acs-1 DEBUG bgp#bgpcfgd: execute command '['vtysh', '-c', 'clear bgp peer-group PEER_V4 soft in']'. Oct 14 18:40:22.904626 str-s6100-acs-1 DEBUG bgp#bgpcfgd: execute command '['vtysh', '-c', 'clear bgp peer-group PEER_V6 soft in']'. ``` Check FRR configuraiton and see that no allowas parameters are there: ``` admin@str-s6100-acs-1:~$ vtysh -c 'show run' | egrep 'PEER_V.? allowas' admin@str-s6100-acs-1:~$ ``` Then we apply enabling configuration back: ``` admin@str-s6100-acs-1:~$ cat enable.json { "BGP_BBR": { "all": { "status": "enabled" } } } admin@str-s6100-acs-1:~$ sonic-cfggen -j enable.json -w ``` The log output: ``` Oct 14 18:40:41.074720 str-s6100-acs-1 DEBUG bgp#bgpcfgd: Received message : '('all', 'SET', (('status', 'enabled'),))' Oct 14 18:40:41.074720 str-s6100-acs-1 DEBUG bgp#bgpcfgd: execute command '['vtysh', '-f', '/tmp/tmpDD6SKv']'. Oct 14 18:40:41.587257 str-s6100-acs-1 DEBUG bgp#bgpcfgd: execute command '['vtysh', '-c', 'clear bgp peer-group PEER_V4 soft in']'. Oct 14 18:40:42.042967 str-s6100-acs-1 DEBUG bgp#bgpcfgd: execute command '['vtysh', '-c', 'clear bgp peer-group PEER_V6 soft in']'. ``` Check FRR configuraiton and see that the BBR configuration is back: ``` admin@str-s6100-acs-1:~$ vtysh -c 'show run' | egrep 'PEER_V.? allowas' neighbor PEER_V4 allowas-in 1 neighbor PEER_V6 allowas-in 1 ``` *** The test coverage *** Below is the test coverage ``` ---------- coverage: platform linux2, python 2.7.12-final-0 ---------- Name Stmts Miss Cover ---------------------------------------------------- bgpcfgd/__init__.py 0 0 100% bgpcfgd/__main__.py 3 3 0% bgpcfgd/config.py 78 41 47% bgpcfgd/directory.py 63 34 46% bgpcfgd/log.py 15 3 80% bgpcfgd/main.py 51 51 0% bgpcfgd/manager.py 41 23 44% bgpcfgd/managers_allow_list.py 385 21 95% bgpcfgd/managers_bbr.py 76 0 100% bgpcfgd/managers_bgp.py 193 193 0% bgpcfgd/managers_db.py 9 9 0% bgpcfgd/managers_intf.py 33 33 0% bgpcfgd/managers_setsrc.py 45 45 0% bgpcfgd/runner.py 39 39 0% bgpcfgd/template.py 64 11 83% bgpcfgd/utils.py 32 24 25% bgpcfgd/vars.py 1 0 100% ---------------------------------------------------- TOTAL 1128 530 53% ``` **- Which release branch to backport (provide reason below if selected)** - [ ] 201811 - [x] 201911 - [x] 202006 --- .../bgpd/templates/general/peer-group.conf.j2 | 8 + files/image_config/constants/constants.yml | 7 + src/sonic-bgpcfgd/bgpcfgd/main.py | 3 + src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py | 120 +++++++ src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py | 1 + .../general/peer-group.conf/param_all.json | 7 +- .../general/peer-group.conf/param_base.json | 5 +- src/sonic-bgpcfgd/tests/swsscommon_test.py | 4 + src/sonic-bgpcfgd/tests/test_bbr.py | 319 ++++++++++++++++++ 9 files changed, 471 insertions(+), 3 deletions(-) create mode 100644 src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py create mode 100644 src/sonic-bgpcfgd/tests/swsscommon_test.py create mode 100644 src/sonic-bgpcfgd/tests/test_bbr.py diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 index 5790d47a5a8a..111b5ceb5f9f 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -9,6 +9,10 @@ {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V4 allowas-in 1 neighbor PEER_V4_INT allowas-in 1 +{% elif CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'LeafRouter' %} +{% if CONFIG_DB__BGP_BBR['status'] == 'enabled' %} + neighbor PEER_V4 allowas-in 1 +{% endif %} {% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor PEER_V4_INT route-reflector-client @@ -24,6 +28,10 @@ {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V6 allowas-in 1 neighbor PEER_V6_INT allowas-in 1 +{% elif CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'LeafRouter' %} +{% if CONFIG_DB__BGP_BBR['status'] == 'enabled' %} + neighbor PEER_V6 allowas-in 1 +{% endif %} {% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor PEER_V6_INT route-reflector-client diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index a142bb653df7..d3b70d4a27ec 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -29,10 +29,17 @@ constants: v6: - "deny 0::/0 le 59" - "deny 0::/0 ge 65" + bbr: + enabled: true peers: general: # peer_type db_table: "BGP_NEIGHBOR" template_dir: "general" + bbr: + PEER_V4: + - ipv4 + PEER_V6: + - ipv6 monitors: # peer_type enabled: true db_table: "BGP_MONITORS" diff --git a/src/sonic-bgpcfgd/bgpcfgd/main.py b/src/sonic-bgpcfgd/bgpcfgd/main.py index bef2f733ad57..7bbb6fb768eb 100644 --- a/src/sonic-bgpcfgd/bgpcfgd/main.py +++ b/src/sonic-bgpcfgd/bgpcfgd/main.py @@ -10,6 +10,7 @@ from .directory import Directory from .log import log_notice, log_crit from .managers_allow_list import BGPAllowListMgr +from .managers_bbr import BBRMgr from .managers_bgp import BGPPeerMgrBase from .managers_db import BGPDataBaseMgr from .managers_intf import InterfaceMgr @@ -47,6 +48,8 @@ def do_work(): BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), # AllowList Managers BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), + # BBR Manager + BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR"), ] runner = Runner() for mgr in managers: diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py b/src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py new file mode 100644 index 000000000000..5c03eabf4bbf --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py @@ -0,0 +1,120 @@ +from swsscommon import swsscommon + +from .log import log_err, log_info, log_crit +from .manager import Manager +from .utils import run_command + + +class BBRMgr(Manager): + """ This class initialize "BBR" feature for """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(BBRMgr, self).__init__( + common_objs, + [("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"),], + db, + table, + ) + self.enabled = False + self.bbr_enabled_pgs = {} + self.directory.put(self.db_name, self.table_name, 'status', "disabled") + self.__init() + + def set_handler(self, key, data): + """ Implementation of 'SET' command for this class """ + if not self.enabled: + log_info("BBRMgr::BBR is disabled. Drop the request") + return True + if not self.__set_validation(key, data): + return True + cmds = self.__set_prepare_config(data['status']) + rv = self.cfg_mgr.push_list(cmds) + if not rv: + log_crit("BBRMgr::can't apply configuration") + return True + self.__restart_peers() + return True + + def del_handler(self, key): + """ Implementation of 'DEL' command for this class """ + log_err("The '%s' table shouldn't be removed from the db" % self.table_name) + + def __init(self): + """ Initialize BBRMgr. Extracted from constructor """ + if not 'bgp' in self.constants: + log_err("BBRMgr::Disabled: 'bgp' key is not found in constants") + return + if 'bbr' in self.constants['bgp'] and \ + 'enabled' in self.constants['bgp']['bbr'] and \ + self.constants['bgp']['bbr']['enabled']: + self.bbr_enabled_pgs = self.__read_pgs() + if self.bbr_enabled_pgs: + self.enabled = True + self.directory.put(self.db_name, self.table_name, 'status', "enabled") + log_info("BBRMgr::Initialized and enabled") + else: + log_info("BBRMgr::Disabled: no BBR enabled peers") + else: + log_info("BBRMgr::Disabled: not enabled in the constants") + + def __read_pgs(self): + """ + Read peer-group bbr settings from constants file + :return: return bbr information from constant peer-group settings + """ + if 'peers' not in self.constants['bgp']: + log_info("BBRMgr::no 'peers' was found in constants") + return {} + res = {} + for peer_name, value in self.constants['bgp']['peers'].items(): + if 'bbr' not in value: + continue + for pg_name, pg_afs in value['bbr'].items(): + res[pg_name] = pg_afs + return res + + def __set_validation(self, key, data): + """ Validate set-command arguments + :param key: key of 'set' command + :param data: data of 'set' command + :return: True is the parameters are valid, False otherwise + """ + if key != 'all': + log_err("Invalid key '%s' for table '%s'. Only key value 'all' is supported" % (key, self.table_name)) + return False + if 'status' not in data: + log_err("Invalid value '%s' for table '%s', key '%s'. Key 'status' in data is expected" % (data, self.table_name, key)) + return False + if data['status'] != "enabled" and data['status'] != "disabled": + log_err("Invalid value '%s' for table '%s', key '%s'. Only 'enabled' and 'disabled' are supported" % (data, self.table_name, key)) + return False + return True + + def __set_prepare_config(self, status): + """ + Generate FFR configuration to apply changes + :param status: either "enabled" or "disabled" + :return: list of commands prepared for FRR + """ + bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + cmds = ["router bgp %s" % bgp_asn] + prefix_of_commands = "" if status == "enabled" else "no " + for af in ["ipv4", "ipv6"]: + cmds.append(" address-family %s" % af) + for pg_name in sorted(self.bbr_enabled_pgs.keys()): + if af in self.bbr_enabled_pgs[pg_name]: + cmds.append(" %sneighbor %s allowas-in 1" % (prefix_of_commands, pg_name)) + return cmds + + def __restart_peers(self): + """ Restart peer-groups which support BBR """ + for peer_group in sorted(self.bbr_enabled_pgs.keys()): + rc, out, err = run_command(["vtysh", "-c", "clear bgp peer-group %s soft in" % peer_group]) + if rc != 0: + log_value = peer_group, rc, out, err + log_crit("BBRMgr::Can't restart bgp peer-group '%s'. rc='%d', out='%s', err='%s'" % log_value) diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py b/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py index fc7e04f7e7b4..b1545dae9288 100644 --- a/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py @@ -187,6 +187,7 @@ def add_peer(self, vrf, nbr, data): kwargs = { 'CONFIG_DB__DEVICE_METADATA': self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME), + 'CONFIG_DB__BGP_BBR': self.directory.get_slot('CONFIG_DB', 'BGP_BBR'), 'constants': self.constants, 'bgp_asn': bgp_asn, 'vrf': vrf, diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_all.json index 293ccc7990dc..0820dd4050f9 100644 --- a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_all.json +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_all.json @@ -3,5 +3,8 @@ "localhost": { "type": "ToRRouter" } - } -} \ No newline at end of file + }, + "CONFIG_DB__BGP_BBR": { + "status": "enabled" + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json index 046ffb1a6417..443b5739201c 100644 --- a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json @@ -4,5 +4,8 @@ "type": "LeafRouter", "sub_role": "BackEnd" } + }, + "CONFIG_DB__BGP_BBR": { + "status": "disabled" } -} \ No newline at end of file +} diff --git a/src/sonic-bgpcfgd/tests/swsscommon_test.py b/src/sonic-bgpcfgd/tests/swsscommon_test.py new file mode 100644 index 000000000000..196c9bcb8924 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/swsscommon_test.py @@ -0,0 +1,4 @@ +from mock import MagicMock + + +swsscommon = MagicMock(CFG_DEVICE_METADATA_TABLE_NAME = "DEVICE_METADATA") diff --git a/src/sonic-bgpcfgd/tests/test_bbr.py b/src/sonic-bgpcfgd/tests/test_bbr.py new file mode 100644 index 000000000000..5f95d12acf60 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_bbr.py @@ -0,0 +1,319 @@ +from bgpcfgd.directory import Directory +from bgpcfgd.template import TemplateFabric +from mock import MagicMock, patch +from copy import deepcopy +import swsscommon_test +import bgpcfgd + +with patch.dict("sys.modules", swsscommon=swsscommon_test): + from bgpcfgd.managers_bbr import BBRMgr + +global_constants = { + "bgp": { + "allow_list": { + "enabled": True, + "default_pl_rules": { + "v4": [ "deny 0.0.0.0/0 le 17" ], + "v6": [ + "deny 0::/0 le 59", + "deny 0::/0 ge 65" + ] + } + } + } +} + +#@patch('bgpcfgd.managers_bbr.log_info') +#@patch('bgpcfgd.managers_bbr.log_err') +#@patch('bgpcfgd.managers_bbr.log_crit') +def test_constructor():#m1, m2, m3): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': {}, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + assert not m.enabled + assert len(m.bbr_enabled_pgs) == 0 + assert m.directory.get("CONFIG_DB", "BGP_BBR", "status") == "disabled" + +@patch('bgpcfgd.managers_bbr.log_info') +@patch('bgpcfgd.managers_bbr.log_crit') +def set_handler_common(key, value, + is_enabled, is_valid, has_no_push_cmd_errors, + mocked_log_crit, mocked_log_info): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + m.enabled = is_enabled + prepare_config_return_value = [ + ["vtysh", "-c", "clear bgp peer-group PEER_V4 soft in"], + ["vtysh", "-c", "clear bgp peer-group PEER_V6 soft in"] + ] + m._BBRMgr__set_prepare_config = MagicMock(return_value = prepare_config_return_value) + m.cfg_mgr.push_list = MagicMock(return_value = has_no_push_cmd_errors) + m._BBRMgr__restart_peers = MagicMock() + res = m.set_handler(key, value) + assert res, "Returns always True" + if not is_enabled: + mocked_log_info.assert_called_with('BBRMgr::BBR is disabled. Drop the request') + else: + if is_valid: + m._BBRMgr__set_prepare_config.assert_called_once_with(value["status"]) + m.cfg_mgr.push_list.assert_called_once_with(prepare_config_return_value) + if has_no_push_cmd_errors: + m._BBRMgr__restart_peers.assert_called_once() + else: + mocked_log_crit.assert_called_with("BBRMgr::can't apply configuration") + m._BBRMgr__restart_peers.assert_not_called() + else: + m._BBRMgr__set_prepare_config.assert_not_called() + m.cfg_mgr.push_list.assert_not_called() + m._BBRMgr__restart_peers.assert_not_called() + +def test_set_handler_1(): + set_handler_common("anything", {}, False, False, True) + +def test_set_handler_2(): + set_handler_common("anything", {}, True, False, True) + +def test_set_handler_3(): + set_handler_common("all", {"status": "enabled"}, True, True, True) + +def test_set_handler_4(): + set_handler_common("all", {"status": "enabled"}, True, True, False) + +@patch('bgpcfgd.managers_bbr.log_err') +def test_del_handler(mocked_log_err): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + m.del_handler("anything") + mocked_log_err.assert_called_with("The 'BGP_BBR' table shouldn't be removed from the db") + +@patch('bgpcfgd.managers_bbr.log_info') +@patch('bgpcfgd.managers_bbr.log_err') +def __init_common(constants, + expected_log_info, expected_log_err, expected_bbr_enabled_pgs, expected_status, + mocked_log_err, mocked_log_info): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + m._BBRMgr__init() + assert m.bbr_enabled_pgs == expected_bbr_enabled_pgs + assert m.directory.get("CONFIG_DB", "BGP_BBR", "status") == expected_status + if expected_status == "enabled": + assert m.enabled + else: + assert not m.enabled + if expected_log_err is not None: + mocked_log_err.assert_called_with(expected_log_err) + if expected_log_info is not None: + mocked_log_info.assert_called_with(expected_log_info) + +def test___init_1(): + __init_common({}, None, "BBRMgr::Disabled: 'bgp' key is not found in constants", {}, "disabled") + +def test___init_2(): + constants = deepcopy(global_constants) + __init_common(constants, "BBRMgr::Disabled: not enabled in the constants", None, {}, "disabled") + +def test___init_3(): + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "123" : False } + __init_common(constants, "BBRMgr::Disabled: not enabled in the constants", None, {}, "disabled") + +def test___init_4(): + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "enabled" : False } + __init_common(constants, "BBRMgr::Disabled: not enabled in the constants", None, {}, "disabled") + +def test___init_5(): + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "enabled" : True } + __init_common(constants, "BBRMgr::Disabled: no BBR enabled peers", None, {}, "disabled") + +def test___init_6(): + expected_bbr_entries = { + "PEER_V4": ["ipv4"], + "PEER_V6": ["ipv6"], + } + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "enabled" : True } + constants["bgp"]["peers"] = { + "general": { + "bbr": expected_bbr_entries, + } + } + __init_common(constants, 'BBRMgr::Initialized and enabled', None, expected_bbr_entries, "enabled") + +@patch('bgpcfgd.managers_bbr.log_info') +def read_pgs_common(constants, expected_log_info, expected_bbr_enabled_pgs, mocked_log_info): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + res = m._BBRMgr__read_pgs() + assert res == expected_bbr_enabled_pgs + if expected_log_info is not None: + mocked_log_info.assert_called_with(expected_log_info) + +def test___read_pgs_no_configuration(): + read_pgs_common(global_constants, "BBRMgr::no 'peers' was found in constants", {}) + +def test___read_pgs_parse_configuration(): + expected_bbr_entries = { + "PEER_V4": ["ipv4", "ipv6"], + "PEER_V6": ["ipv6"], + } + constants = deepcopy(global_constants) + constants["bgp"]["peers"] = { + "general": { + "bbr": expected_bbr_entries, + }, + "dynamic": { + "123": { + "PEER_V8": ["ipv10", "ipv20"], + } + } + } + read_pgs_common(constants, None, expected_bbr_entries) + +@patch('bgpcfgd.managers_bbr.log_err') +def __set_validation_common(key, data, expected_log_err, expected_result, mocked_log_err): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + res = m._BBRMgr__set_validation(key, data) + assert res == expected_result + if expected_log_err is not None: + mocked_log_err.assert_called_with(expected_log_err) + +def test___set_validation_1(): + __set_validation_common("all1", {}, "Invalid key 'all1' for table 'BGP_BBR'. Only key value 'all' is supported", False) + +def test___set_validation_2(): + __set_validation_common("all", {"stat": "enabled"}, "Invalid value '{'stat': 'enabled'}' for table 'BGP_BBR', key 'all'. Key 'status' in data is expected", False) + +def test___set_validation_3(): + __set_validation_common("all", {"status": "enabled1"}, "Invalid value '{'status': 'enabled1'}' for table 'BGP_BBR', key 'all'. Only 'enabled' and 'disabled' are supported", False) + +def test___set_validation_4(): + __set_validation_common("all", {"status": "enabled"}, None, True) + +def test___set_validation_5(): + __set_validation_common("all", {"status": "disabled"}, None, True) + +def __set_prepare_config_common(status, bbr_enabled_pgs, expected_cmds): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + m.directory.data = {"CONFIG_DB__DEVICE_METADATA": + { + "localhost": { + "bgp_asn": "65500" + } + } + } + m.bbr_enabled_pgs = bbr_enabled_pgs + cmds = m._BBRMgr__set_prepare_config(status) + assert cmds == expected_cmds + +def test___set_prepare_config_enabled(): + __set_prepare_config_common("enabled", { + "PEER_V4": ["ipv4", "ipv6"], + "PEER_V6": ["ipv6"], + }, [ + 'router bgp 65500', + ' address-family ipv4', + ' neighbor PEER_V4 allowas-in 1', + ' address-family ipv6', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V6 allowas-in 1', + ]) + +def test___set_prepare_config_disabled(): + __set_prepare_config_common("disabled", { + "PEER_V4": ["ipv4", "ipv6"], + "PEER_V6": ["ipv6"], + }, [ + 'router bgp 65500', + ' address-family ipv4', + ' no neighbor PEER_V4 allowas-in 1', + ' address-family ipv6', + ' no neighbor PEER_V4 allowas-in 1', + ' no neighbor PEER_V6 allowas-in 1', + ]) + +@patch('bgpcfgd.managers_bbr.log_crit') +def __restart_peers_common(run_command_results, run_command_expects, last_log_crit_message, mocked_log_crit): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + m.bbr_enabled_pgs = { + "PEER_V4": ["ipv4", "ipv6"], + "PEER_V6": ["ipv6"], + } + def run_command_mock(cmd): + assert cmd == run_command_expects[run_command_mock.run] + res = run_command_results[run_command_mock.run] + run_command_mock.run += 1 + return res + run_command_mock.run = 0 + bgpcfgd.managers_bbr.run_command = run_command_mock + #lambda cmd: (0, "", "") + m._BBRMgr__restart_peers() + if last_log_crit_message is not None: + mocked_log_crit.assert_called_with(last_log_crit_message) + +def test___restart_peers_1(): + __restart_peers_common([(0, "", ""), (0, "", "")], + [ + ["vtysh", "-c", "clear bgp peer-group PEER_V4 soft in"], + ["vtysh", "-c", "clear bgp peer-group PEER_V6 soft in"] + ], + None) + +def test___restart_peers_2(): + __restart_peers_common([(1, "out1", "err1"), (0, "", "")], + [ + ["vtysh", "-c", "clear bgp peer-group PEER_V4 soft in"], + ["vtysh", "-c", "clear bgp peer-group PEER_V6 soft in"] + ], + "BBRMgr::Can't restart bgp peer-group 'PEER_V4'. rc='1', out='out1', err='err1'") From 73825e4d4de05f7e8933ce1b3054be0033c3fb61 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 22 Oct 2020 11:58:27 -0700 Subject: [PATCH 1273/1427] [system-health] Update .gitignore file (#5688) Touch up .gitignore file to properly ignore all files generated when building a Python wheel package --- src/system-health/.gitignore | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/system-health/.gitignore b/src/system-health/.gitignore index 843dd50ba52f..5ae7a596bfb6 100644 --- a/src/system-health/.gitignore +++ b/src/system-health/.gitignore @@ -1,8 +1,13 @@ -*/deb_dist/ -*/dist/ -*/build/ -*/*.tar.gz -*/*.egg-info -*/.cache/ +# Compiled Python files *.pyc -*/__pycache__/ + +# Generated by packaging +*.egg-info/ +.eggs/ +build/ +dist/ + +# Unit test coverage +.coverage +coverage.xml +htmlcov/ From af97e236864ca8840aefd6d478aeeff2bc42d2eb Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Thu, 22 Oct 2020 20:01:07 -0700 Subject: [PATCH 1274/1427] [hostcfgd] Enable/disable the container service only when the feature state was changed. (#5689) **- Why I did it** If we ran the CLI commands `sudo config feature autorestart snmp disabled/enabled` or `sudo config feature autorestart swss disabled/enabled`, then SNMP container will be stopped and started. This behavior was not expected since we updated the `auto_restart` field not update `state` field in `FEATURE` table. The reason behind this issue is that either `state` field or `auto_restart` field was updated, the function `update_feature_state(...)` will be invoked which then starts snmp.timer service. The snmp.timer service will first stop snmp.service and later start snmp.service. In order to solve this issue, the function `update_feature_state(...)` will be only invoked if `state` field in `FEATURE` table was updated. **- How I did it** When the demon `hostcfgd` was activated, all the values of `state` field in `FEATURE` table of each container will be cached. Each time the function `feature_state_handler(...)` is invoked, it will determine whether the `state` field of a container was changed or not. If it was changed, function `update_feature_state(...)` will be invoked and the cached value will also be updated. Otherwise, nothing will be done. **- How to verify it** We can run the CLI commands `sudo config feature autorestart snmp disabled/enabled` or `sudo config feature autorestart swss disabled/enabled` to check whether SNMP container is stopped and started. We also can run the CLI commands `sudo config feature state snmp disabled/enabled` or `sudo config feature state swss disabled/enabled` to check whether the container is stopped and restarted. Signed-off-by: Yong Zhao --- files/image_config/hostcfgd/hostcfgd | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 2b505ee5a0ee..b76655ceef2c 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -242,6 +242,8 @@ class HostConfigDaemon: self.iptables = Iptables() self.iptables.load(lpbk_table) self.is_multi_npu = device_info.is_multi_npu() + # Cache the values of 'state' field in 'FEATURE' table of each container + self.cached_feature_states = {} def update_feature_state(self, feature_name, state, feature_table): has_timer = ast.literal_eval(feature_table[feature_name].get('has_timer', 'False')) @@ -314,6 +316,9 @@ class HostConfigDaemon: syslog.syslog(syslog.LOG_WARNING, "Eanble state of feature '{}' is None".format(feature_name)) continue + # Store the initial value of 'state' field in 'FEATURE' table of a specific container + self.cached_feature_states[feature_name] = state + self.update_feature_state(feature_name, state, feature_table) def aaa_handler(self, key, data): @@ -356,7 +361,10 @@ class HostConfigDaemon: syslog.syslog(syslog.LOG_WARNING, "Enable state of feature '{}' is None".format(feature_name)) return - self.update_feature_state(feature_name, state, feature_table) + # Enable/disable the container service if the feature state was changed from its previous state. + if self.cached_feature_states[feature_name] != state: + self.cached_feature_states[feature_name] = state + self.update_feature_state(feature_name, state, feature_table) def start(self): # Update all feature states once upon starting From ace7f24cba58ec7af6904a7a48dc5e43f3062817 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Fri, 23 Oct 2020 00:41:16 -0700 Subject: [PATCH 1275/1427] [docker-teamd]: Add teamd as a depedent service to swss (#5628) **- Why I did it** On teamd docker restart, the swss and syncd needs to be restarted as there are dependent resources present. **- How I did it** Add the teamd as a dependent service for swss Updated the docker-wait script to handle service and dependent services separately. Handle the case of warm-restart for the dependent service **- How to verify it** Verified the following scenario's with the following testbed VM1 ----------------------------[DUT 6100] -----------------------VM2, ping traffic continuous between VMs 1. Stop teamd docker alone > swss, syncd dockers seen going away > The LAG reference count error messages seen for a while till swss docker stops. > Dockers back up. 2. Enable WR mode for teamd. Stop teamd docker alone > swss, syncd dockers not removed. > The LAG reference count error messages not seen > Repeated stop teamd docker test - same result, no effect on swss/syncd. 3. Stop swss docker. > swss, teamd, syncd goes off - dockers comes back correctly, interfaces up 4. Enable WR mode for swss . Stop swss docker > swss goes off not affecting syncd/teamd dockers. 5. Config reload > no reference counter error seen, dockers comes back correctly, with interfaces up 6. Warm reboot, observations below > swss docker goes off first > teamd + syncd goes off to the end of WR process. > dockers comes back up fine. > ping traffic between VM's was NOT HIT 7. Fast reboot, observations below > teamd goes off first ( **confirmed swss don't exit here** ) > swss goes off next > syncd goes away at the end of the FR process > dockers comes back up fine. > there is a traffic HIT as per fast-reboot 8. Verified in multi-asic platform, the tests above other than WR/FB scenarios --- files/image_config/misc/docker-wait-any | 81 ++++++++++++++----- files/scripts/swss.sh | 27 ++++++- .../sonic_py_common/device_info.py | 37 ++++++++- 3 files changed, 123 insertions(+), 22 deletions(-) diff --git a/files/image_config/misc/docker-wait-any b/files/image_config/misc/docker-wait-any index b6a2d95c8821..d006aec47a5a 100755 --- a/files/image_config/misc/docker-wait-any +++ b/files/image_config/misc/docker-wait-any @@ -3,50 +3,95 @@ """ docker-wait-any This script takes one or more Docker container names as arguments, - and it will block indefinitely while all of the specified containers - are running. If any of the specified containers stop, the script will + [-s] argument is for the service which invokes this script + [-d] argument is to list the dependent services for the above service. + It will block indefinitely while all of the specified containers + are running.If any of the specified containers stop, the script will exit. + This script was created because the 'docker wait' command is lacking this functionality. It will block until ALL specified containers have stopped running. Here, we spawn multiple threads and wait on one container per thread. If any of the threads exit, the entire - application will exit. + application will exit, unless we are in a scenario where the following + conditions are met. + (i) the container is a dependent service + (ii) warm restart is enabled at system level or for that container OR + fast reboot is enabled system level + In this scenario, the g_thread_exit_event won't be propogated to the parent, + instead the thread will continue to do docker_client.wait again.This help's + cases where we need the dependent container to be warm-restarted without + affecting other services (eg: warm restart of teamd service) + NOTE: This script is written against docker Python package 4.1.0. Newer versions of docker may have a different API. """ - +import argparse import sys import threading -from docker import APIClient +import time -# Instantiate a global event to share among our threads -g_thread_exit_event = threading.Event() +from docker import APIClient +from sonic_py_common import logger, device_info +SYSLOG_IDENTIFIER = 'docker-wait-any' -def usage(): - print("Usage: {} [ ...]".format(sys.argv[0])) - sys.exit(1) +# Global logger instance +log = logger.Logger(SYSLOG_IDENTIFIER) +# Instantiate a global event to share among our threads +g_thread_exit_event = threading.Event() +g_service = [] +g_dep_services = [] def wait_for_container(docker_client, container_name): - docker_client.wait(container_name) + while True: + while docker_client.inspect_container(container_name)['State']['Status'] != "running": + time.sleep(1) - print("No longer waiting on container '{}'".format(container_name)) + docker_client.wait(container_name) - # Signal the main thread to exit - g_thread_exit_event.set() + log.log_info("No longer waiting on container '{}'".format(container_name)) + # If this is a dependent service and warm restart is enabled for the system/container, + # OR if the system is going through a fast-reboot, DON'T signal main thread to exit + if (container_name in g_dep_services and + (device_info.is_warm_restart_enabled(container_name) or device_info.is_fast_reboot_enabled())): + continue + + # Signal the main thread to exit + g_thread_exit_event.set() def main(): thread_list = [] docker_client = APIClient(base_url='unix://var/run/docker.sock') - # Ensure we were passed at least one argument - if len(sys.argv) < 2: - usage() + parser = argparse.ArgumentParser(description='Wait for dependent docker services', + version='1.0.0', + formatter_class=argparse.RawTextHelpFormatter, + epilog=""" +Examples: + docker-wait-any -s swss -d syncd teamd +""") + + parser.add_argument('-s','--service', nargs='+', default=None, help='name of the service') + parser.add_argument('-d','--dependent', nargs='*', default=None, help='other dependent services') + args = parser.parse_args() + + global g_service + global g_dep_services + + if args.service is not None: + g_service = args.service + if args.dependent is not None: + g_dep_services = args.dependent + + container_names = g_service + g_dep_services - container_names = sys.argv[1:] + # If the service and dependents passed as args is empty, then exit + if container_names == []: + sys.exit(0) for container_name in container_names: t = threading.Thread(target=wait_for_container, args=[docker_client, container_name]) diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 129e5d148dc8..11613b5a8a5c 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -170,7 +170,20 @@ wait() { else RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) fi - if [[ x"$RUNNING" == x"true" ]]; then + ALL_DEPS_RUNNING=true + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + DEP_RUNNING=$(docker inspect -f '{{.State.Running}}' ${dep}$DEV) + else + DEP_RUNNING=$(docker inspect -f '{{.State.Running}}' ${dep}) + fi + if [[ x"$DEP_RUNNING" != x"true" ]]; then + ALL_DEPS_RUNNING=false + break + fi + done + + if [[ x"$RUNNING" == x"true" && x"$ALL_DEPS_RUNNING" == x"true" ]]; then break else sleep 1 @@ -179,10 +192,18 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + ALL_DEPS="$ALL_DEPS ${dep}$DEV" + else + ALL_DEPS="$ALL_DEPS ${dep}" + fi + done + if [[ ! -z $DEV ]]; then - /usr/bin/docker-wait-any ${SERVICE}$DEV ${PEER}$DEV + /usr/bin/docker-wait-any -s ${SERVICE}$DEV -d ${PEER}$DEV ${ALL_DEPS} else - /usr/bin/docker-wait-any ${SERVICE} ${PEER} + /usr/bin/docker-wait-any -s ${SERVICE} -d ${PEER} ${ALL_DEPS} fi } diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index eca8cd7ef059..d25ccb7c1327 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -8,7 +8,7 @@ from natsort import natsorted # TODO: Replace with swsscommon -from swsssdk import ConfigDBConnector, SonicDBConfig +from swsssdk import ConfigDBConnector, SonicDBConfig, SonicV2Connector USR_SHARE_SONIC_PATH = "/usr/share/sonic" HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" @@ -442,3 +442,38 @@ def get_system_routing_stack(): raise OSError("Cannot detect routing stack") return result + +# Check if System warm reboot or Container warm restart is enabled. +def is_warm_restart_enabled(container_name): + state_db = SonicV2Connector(host='127.0.0.1') + state_db.connect(state_db.STATE_DB, False) + + TABLE_NAME_SEPARATOR = '|' + prefix = 'WARM_RESTART_ENABLE_TABLE' + TABLE_NAME_SEPARATOR + + # Get the system warm reboot enable state + _hash = '{}{}'.format(prefix, 'system') + wr_system_state = state_db.get(state_db.STATE_DB, _hash, "enable") + wr_enable_state = True if wr_system_state == "true" else False + + # Get the container warm reboot enable state + _hash = '{}{}'.format(prefix, container_name) + wr_container_state = state_db.get(state_db.STATE_DB, _hash, "enable") + wr_enable_state |= True if wr_container_state == "true" else False + + state_db.close(state_db.STATE_DB) + return wr_enable_state + +# Check if System fast reboot is enabled. +def is_fast_reboot_enabled(): + fb_system_state = 0 + cmd = 'sonic-db-cli STATE_DB get "FAST_REBOOT|system"' + proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) + (stdout, stderr) = proc.communicate() + + if proc.returncode != 0: + log.log_error("Error running command '{}'".format(cmd)) + elif stdout: + fb_system_state = stdout.rstrip('\n') + + return fb_system_state From bb641913c4ae9c121e7163f0e6c3283fff8fc878 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 23 Oct 2020 10:47:18 +0000 Subject: [PATCH 1276/1427] Revert "[build]: Fixes the missing dependency in the debian package is not triggering the docker rebuild (#5650)" This reverts commit 5c5e42454d68e53bdc9a6f5d0c128891a0349ce1. --- Makefile.cache | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Makefile.cache b/Makefile.cache index 7693e6791b58..3c45cec3a97f 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -171,22 +171,18 @@ endef define GET_MOD_DEP_SHA $(eval $(1)_MOD_DEP_PKGS := $(foreach dfile,$($(1)_DEPENDS) $($(1)_RDEPENDS) $($(1)_WHEEL_DEPENDS) \ $($(1)_PYTHON_DEBS) $($(1)_PYTHON_WHEELS) \ - $($(1)_DBG_DEPENDS) $($(1)_LOAD_DOCKERS),\ + $($(1)_DBG_DEPENDS) $($(1)_DBG_IMAGE_PACKAGES) $($(1)_LOAD_DOCKERS),\ $(if $($(dfile)_MAIN_DEB),$($(dfile)_MAIN_DEB),$(dfile))) ) $(if $(MDEBUG), $(info $(1)_MOD_DEP_PKGS: $($(1)_MOD_DEP_PKGS))) # Warn if there is any missing dependency files $(eval $(1)_DEP_MOD_SHA_FILES := $(foreach dfile,$($(1)_MOD_DEP_PKGS), \ - $($(dfile)_DEP_FLAGS_FILE) $($(dfile)_MOD_HASH_FILE) $($(dfile)_SMOD_HASH_FILE) \ - $($(dfile)_DST_PATH)/$(dfile) )) - echo "DEP_MOD_SHA_FILES : $($(1)_DEP_MOD_SHA_FILES)" >> $($(1)_DST_PATH)/$(1).log + $($(dfile)_DEP_FLAGS_FILE) $($(dfile)_MOD_HASH_FILE) $($(dfile)_SMOD_HASH_FILE)) ) $(eval $(1)_DEP_FILES_MISSING := $(filter-out $(wildcard $($(1)_DEP_MOD_SHA_FILES)),$($(1)_DEP_MOD_SHA_FILES)) ) - $(if $($(1)_DEP_FILES_MISSING), $(warning "[ DPKG ] Dependency file(s) are not found for $(1) : $($(1)_DEP_FILES_MISSING))) + $(if $($(1)_DEP_FILES_MISSING), $(warning "[ DPKG ] Dependecy file(s) are not found for $(1) : $($(1)_DEP_FILES_MISSING))) - $(eval $(1)_DEP_MOD_SHA_HASH := $(shell git hash-object $($(1)_DEP_MOD_SHA_FILES))) - $(eval $(1)_DEP_MOD_SHA_VALUE:= $(foreach dfile,$($(1)_MOD_DEP_PKGS), $($(dfile)_DEP_MOD_SHA))) - $(eval $(1)_DEP_MOD_SHA := $(shell echo $($(1)_DEP_MOD_SHA_HASH) $($(1)_DEP_MOD_SHA_VALUE) \ + $(eval $(1)_DEP_MOD_SHA := $(shell git hash-object $($(1)_DEP_MOD_SHA_FILES) \ | sha1sum | awk '{print substr($$1,0,23);}')) endef From 3a4435eb5323c6737376d4a2bb416d3eca6404ca Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 23 Oct 2020 09:52:29 -0700 Subject: [PATCH 1277/1427] Add sonic-host-services and sonic-host-services-data packages (#5694) **- Why I did it** Install all host services and their data files in package format rather than file-by-file **- How I did it** - Create sonic-host-services Python wheel package, currently including procdockerstatsd - Also add the framework for unit tests by adding one simple procdockerstatsd test case - Create sonic-host-services-data Debian package which is responsible for installing the related systemd unit files to control the services in the Python wheel. This package will also be responsible for installing any Jinja2 templates and other data files needed by the host services. --- .../build_templates/sonic_debian_extension.j2 | 15 ++++--- platform/vs/docker-sonic-vs.mk | 6 ++- rules/sonic-host-services-data.dep | 8 ++++ rules/sonic-host-services-data.mk | 5 +++ rules/sonic-host-services.dep | 10 +++++ rules/sonic-host-services.mk | 8 ++++ slave.mk | 7 +++- src/sonic-host-services-data/.gitignore | 6 +++ src/sonic-host-services-data/LICENSE | 15 +++++++ src/sonic-host-services-data/MAINTAINERS | 7 ++++ src/sonic-host-services-data/README.md | 19 +++++++++ src/sonic-host-services-data/debian/changelog | 5 +++ src/sonic-host-services-data/debian/compat | 1 + src/sonic-host-services-data/debian/control | 11 +++++ src/sonic-host-services-data/debian/copyright | 0 src/sonic-host-services-data/debian/install | 0 src/sonic-host-services-data/debian/rules | 9 ++++ ...ost-services-data.procdockerstatsd.service | 2 +- src/sonic-host-services/.gitignore | 14 +++++++ .../scripts}/procdockerstatsd | 0 src/sonic-host-services/setup.cfg | 2 + src/sonic-host-services/setup.py | 41 ++++++++++++++++++ src/sonic-host-services/tests/__init__.py | 0 .../tests/mock_connector.py | 24 +++++++++++ .../tests/procdockerstatsd_test.py | 42 +++++++++++++++++++ 25 files changed, 247 insertions(+), 10 deletions(-) create mode 100644 rules/sonic-host-services-data.dep create mode 100644 rules/sonic-host-services-data.mk create mode 100644 rules/sonic-host-services.dep create mode 100644 rules/sonic-host-services.mk create mode 100644 src/sonic-host-services-data/.gitignore create mode 100644 src/sonic-host-services-data/LICENSE create mode 100644 src/sonic-host-services-data/MAINTAINERS create mode 100644 src/sonic-host-services-data/README.md create mode 100644 src/sonic-host-services-data/debian/changelog create mode 100644 src/sonic-host-services-data/debian/compat create mode 100644 src/sonic-host-services-data/debian/control create mode 100644 src/sonic-host-services-data/debian/copyright create mode 100644 src/sonic-host-services-data/debian/install create mode 100755 src/sonic-host-services-data/debian/rules rename files/image_config/procdockerstatsd/procdockerstatsd.service => src/sonic-host-services-data/debian/sonic-host-services-data.procdockerstatsd.service (85%) create mode 100644 src/sonic-host-services/.gitignore rename {files/image_config/procdockerstatsd => src/sonic-host-services/scripts}/procdockerstatsd (100%) create mode 100644 src/sonic-host-services/setup.cfg create mode 100644 src/sonic-host-services/setup.py create mode 100644 src/sonic-host-services/tests/__init__.py create mode 100644 src/sonic-host-services/tests/mock_connector.py create mode 100644 src/sonic-host-services/tests/procdockerstatsd_test.py diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 21f143e70109..70b8b08a99c9 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -206,6 +206,16 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-utilities-data_*.deb || \ # in bash.bashrc, so we copy a version of the file with it enabled here. sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/ +# Install SONiC host services package +SONIC_HOST_SERVICES_PY3_WHEEL_NAME=$(basename {{sonic_host_services_py3_wheel_path}}) +sudo cp {{sonic_host_services_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_HOST_SERVICES_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_HOST_SERVICES_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_HOST_SERVICES_PY3_WHEEL_NAME + +# Install SONiC host services data files (and any dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-host-services-data_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f + {% if enable_ztp == "y" %} # Install ZTP (and its dependencies via 'apt-get -y install -f') sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-ztp_*.deb || \ @@ -402,11 +412,6 @@ sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd.service $FILESYSTEM_ROOT_USR_LIB_SYSTEM echo "caclmgrd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd $FILESYSTEM_ROOT/usr/bin/ -# Copy process/docker cpu/memory utilization data export daemon -sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM -echo "procdockerstatsd.service" | sudo tee -a $GENERATED_SERVICE_FILE -sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd $FILESYSTEM_ROOT/usr/bin/ - # Copy systemd timer configuration sudo cp $BUILD_TEMPLATES/pcie-check.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable pcie-check.timer diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index 13d9c33fa2da..273611e0ae36 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -12,7 +12,8 @@ $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS) \ $(LIBYANG) \ $(LIBYANG_CPP) \ $(LIBYANG_PY2) \ - $(SONIC_UTILITIES_DATA) + $(SONIC_UTILITIES_DATA) \ + $(SONIC_HOST_SERVICES_DATA) # swsssdk is a dependency of sonic-py-common # TODO: sonic-py-common should depend on swsscommon instead @@ -22,7 +23,8 @@ $(DOCKER_SONIC_VS)_PYTHON_WHEELS += $(SWSSSDK_PY2) \ $(SONIC_PY_COMMON_PY3) \ $(SONIC_YANG_MODELS_PY3) \ $(SONIC_YANG_MGMT_PY) \ - $(SONIC_UTILITIES_PY2) + $(SONIC_UTILITIES_PY2) \ + $(SONIC_HOST_SERVICES_PY3) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS_DBG) \ diff --git a/rules/sonic-host-services-data.dep b/rules/sonic-host-services-data.dep new file mode 100644 index 000000000000..2b208317f1e2 --- /dev/null +++ b/rules/sonic-host-services-data.dep @@ -0,0 +1,8 @@ +SPATH := $($(SONIC_HOST_SERVICES_DATA)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-host-services-data.mk rules/sonic-host-services-data.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_HOST_SERVICES_DATA)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_HOST_SERVICES_DATA)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_HOST_SERVICES_DATA)_DEP_FILES := $(DEP_FILES) diff --git a/rules/sonic-host-services-data.mk b/rules/sonic-host-services-data.mk new file mode 100644 index 000000000000..64a65904820a --- /dev/null +++ b/rules/sonic-host-services-data.mk @@ -0,0 +1,5 @@ +# SONiC host services data package + +SONIC_HOST_SERVICES_DATA = sonic-host-services-data_1.0-1_all.deb +$(SONIC_HOST_SERVICES_DATA)_SRC_PATH = $(SRC_PATH)/sonic-host-services-data +SONIC_DPKG_DEBS += $(SONIC_HOST_SERVICES_DATA) diff --git a/rules/sonic-host-services.dep b/rules/sonic-host-services.dep new file mode 100644 index 000000000000..0e68ccb035c8 --- /dev/null +++ b/rules/sonic-host-services.dep @@ -0,0 +1,10 @@ +SPATH := $($(SONIC_HOST_SERVICES_PY3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-host-services.mk rules/sonic-host-services.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_HOST_SERVICES_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_HOST_SERVICES_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_HOST_SERVICES_PY3)_DEP_FILES := $(DEP_FILES) +$(SONIC_HOST_SERVICES_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_HOST_SERVICES_PY3)_SMDEP_PATHS := $(SPATH) diff --git a/rules/sonic-host-services.mk b/rules/sonic-host-services.mk new file mode 100644 index 000000000000..022c237ee950 --- /dev/null +++ b/rules/sonic-host-services.mk @@ -0,0 +1,8 @@ +# SONiC host services package + +SONIC_HOST_SERVICES_PY3 = sonic_host_services-1.0-py3-none-any.whl +$(SONIC_HOST_SERVICES_PY3)_SRC_PATH = $(SRC_PATH)/sonic-host-services +$(SONIC_HOST_SERVICES_PY3)_PYTHON_VERSION = 3 +$(SONIC_HOST_SERVICES_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY3) \ + $(SWSSSDK_PY3) +SONIC_PYTHON_WHEELS += $(SONIC_HOST_SERVICES_PY3) diff --git a/slave.mk b/slave.mk index 6d1829c8b365..a4a7f7a85897 100644 --- a/slave.mk +++ b/slave.mk @@ -804,7 +804,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(MONIT) \ $(PYTHON_SWSSCOMMON) \ $(PYTHON3_SWSSCOMMON) \ - $(SONIC_UTILITIES_DATA)) \ + $(SONIC_UTILITIES_DATA) \ + $(SONIC_HOST_SERVICES_DATA)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \ @@ -820,7 +821,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(SYSTEM_HEALTH)) + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SYSTEM_HEALTH)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_HOST_SERVICES_PY3)) $(HEADER) # Pass initramfs and linux kernel explicitly. They are used for all platforms export debs_path="$(IMAGE_DISTRO_DEBS_PATH)" @@ -866,6 +868,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export python_swss_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($(LIBSWSSCOMMON)_RDEPENDS))" export python_swss_debs+=" $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(LIBSWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON_SWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON3_SWSSCOMMON))" export sonic_utilities_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_UTILITIES_PY2))" + export sonic_host_services_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_HOST_SERVICES_PY3))" $(foreach docker, $($*_DOCKERS),\ export docker_image="$(docker)" diff --git a/src/sonic-host-services-data/.gitignore b/src/sonic-host-services-data/.gitignore new file mode 100644 index 000000000000..b941ede4c3b3 --- /dev/null +++ b/src/sonic-host-services-data/.gitignore @@ -0,0 +1,6 @@ +debian/*.debhelper +debian/debhelper-build-stamp +debian/sonic-host-services-data/ +sonic-host-services-data_*.buildinfo +sonic-host-services-data_*.changes +sonic-host-services-data_*.deb diff --git a/src/sonic-host-services-data/LICENSE b/src/sonic-host-services-data/LICENSE new file mode 100644 index 000000000000..6e2e81a75fda --- /dev/null +++ b/src/sonic-host-services-data/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2020 Microsoft + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/src/sonic-host-services-data/MAINTAINERS b/src/sonic-host-services-data/MAINTAINERS new file mode 100644 index 000000000000..fde1eede3214 --- /dev/null +++ b/src/sonic-host-services-data/MAINTAINERS @@ -0,0 +1,7 @@ +# This file describes the maintainers for sonic-device-data +# See the SONiC project governance document for more information + +Name = "Joe LeVeque" +Email = "jolevequ@microsoft.com" +Github = jleveque +Mailinglist = sonicproject@googlegroups.com diff --git a/src/sonic-host-services-data/README.md b/src/sonic-host-services-data/README.md new file mode 100644 index 000000000000..93af66a83d6b --- /dev/null +++ b/src/sonic-host-services-data/README.md @@ -0,0 +1,19 @@ +# sonic-host-services-data +Data files required for SONiC host services + + +## To build + +``` +dpkg-buildpackage -rfakeroot -b -us -uc +``` + +## To clean + +``` +dpkg-buildpackage -rfakeroot -Tclean +``` + +--- + +See the [SONiC Website](http://azure.github.io/SONiC/) for more information about the SONiC project. diff --git a/src/sonic-host-services-data/debian/changelog b/src/sonic-host-services-data/debian/changelog new file mode 100644 index 000000000000..89e14bad24e7 --- /dev/null +++ b/src/sonic-host-services-data/debian/changelog @@ -0,0 +1,5 @@ +sonic-host-services-data (1.0-1) UNRELEASED; urgency=low + + * Initial release + + -- Joe LeVeque Tue, 20 Oct 2020 02:35:43 +0000 diff --git a/src/sonic-host-services-data/debian/compat b/src/sonic-host-services-data/debian/compat new file mode 100644 index 000000000000..b4de39476753 --- /dev/null +++ b/src/sonic-host-services-data/debian/compat @@ -0,0 +1 @@ +11 diff --git a/src/sonic-host-services-data/debian/control b/src/sonic-host-services-data/debian/control new file mode 100644 index 000000000000..ebb495e3d3cf --- /dev/null +++ b/src/sonic-host-services-data/debian/control @@ -0,0 +1,11 @@ +Source: sonic-host-services-data +Maintainer: Joe LeVeque +Section: misc +Priority: optional +Standards-Version: 0.1 +Build-Depends: debhelper (>=11) + +Package: sonic-host-services-data +Architecture: all +Depends: ${misc:Depends} +Description: Data files required for SONiC host services diff --git a/src/sonic-host-services-data/debian/copyright b/src/sonic-host-services-data/debian/copyright new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-host-services-data/debian/install b/src/sonic-host-services-data/debian/install new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-host-services-data/debian/rules b/src/sonic-host-services-data/debian/rules new file mode 100755 index 000000000000..60ad16ab0416 --- /dev/null +++ b/src/sonic-host-services-data/debian/rules @@ -0,0 +1,9 @@ +#!/usr/bin/make -f + +build: + +%: + dh $@ + +override_dh_installsystemd: + dh_installsystemd --no-start --name=procdockerstatsd diff --git a/files/image_config/procdockerstatsd/procdockerstatsd.service b/src/sonic-host-services-data/debian/sonic-host-services-data.procdockerstatsd.service similarity index 85% rename from files/image_config/procdockerstatsd/procdockerstatsd.service rename to src/sonic-host-services-data/debian/sonic-host-services-data.procdockerstatsd.service index 010dac15b2e6..388197d9741b 100644 --- a/files/image_config/procdockerstatsd/procdockerstatsd.service +++ b/src/sonic-host-services-data/debian/sonic-host-services-data.procdockerstatsd.service @@ -5,7 +5,7 @@ After=database.service updategraph.service [Service] Type=simple -ExecStart=/usr/bin/procdockerstatsd +ExecStart=/usr/local/bin/procdockerstatsd Restart=always [Install] diff --git a/src/sonic-host-services/.gitignore b/src/sonic-host-services/.gitignore new file mode 100644 index 000000000000..3dc8c1b46693 --- /dev/null +++ b/src/sonic-host-services/.gitignore @@ -0,0 +1,14 @@ +# Compiled Python files +*.pyc +scripts/procdockerstatsdc + +# Generated by packaging +*.egg-info/ +.eggs/ +build/ +dist/ + +# Unit test coverage +.coverage +coverage.xml +htmlcov/ diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/src/sonic-host-services/scripts/procdockerstatsd similarity index 100% rename from files/image_config/procdockerstatsd/procdockerstatsd rename to src/sonic-host-services/scripts/procdockerstatsd diff --git a/src/sonic-host-services/setup.cfg b/src/sonic-host-services/setup.cfg new file mode 100644 index 000000000000..b7e478982ccf --- /dev/null +++ b/src/sonic-host-services/setup.cfg @@ -0,0 +1,2 @@ +[aliases] +test=pytest diff --git a/src/sonic-host-services/setup.py b/src/sonic-host-services/setup.py new file mode 100644 index 000000000000..a8315a322687 --- /dev/null +++ b/src/sonic-host-services/setup.py @@ -0,0 +1,41 @@ +from setuptools import setup + +setup( + name = 'sonic-host-services', + version = '1.0', + description = 'Python services which run in the SONiC host OS', + license = 'Apache 2.0', + author = 'SONiC Team', + author_email = 'linuxnetdev@microsoft.com', + url = 'https://github.com/Azure/sonic-buildimage', + maintainer = 'Joe LeVeque', + maintainer_email = 'jolevequ@microsoft.com', + scripts = [ + 'scripts/procdockerstatsd', + ], + install_requires = [ + 'sonic-py-common', + 'swsssdk>=2.0.1', + ], + setup_requires = [ + 'pytest-runner', + 'wheel' + ], + tests_require = [ + 'pytest', + ], + classifiers = [ + 'Development Status :: 3 - Alpha', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 3.7', + 'Topic :: System', + ], + keywords = 'sonic SONiC host services', + test_suite = 'setup.get_test_suite' +) diff --git a/src/sonic-host-services/tests/__init__.py b/src/sonic-host-services/tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-host-services/tests/mock_connector.py b/src/sonic-host-services/tests/mock_connector.py new file mode 100644 index 000000000000..d32017ff8485 --- /dev/null +++ b/src/sonic-host-services/tests/mock_connector.py @@ -0,0 +1,24 @@ +class MockConnector(object): + STATE_DB = None + data = {} + + def __init__(self, host): + pass + + def connect(self, db_id): + pass + + def get(self, db_id, key, field): + return MockConnector.data[key][field] + + def keys(self, db_id, pattern): + match = pattern.split('*')[0] + ret = [] + for key in MockConnector.data.keys(): + if match in key: + ret.append(key) + + return ret + + def get_all(self, db_id, key): + return MockConnector.data[key] diff --git a/src/sonic-host-services/tests/procdockerstatsd_test.py b/src/sonic-host-services/tests/procdockerstatsd_test.py new file mode 100644 index 000000000000..5c47e91458f3 --- /dev/null +++ b/src/sonic-host-services/tests/procdockerstatsd_test.py @@ -0,0 +1,42 @@ +import imp +import sys +import os +import pytest + +import swsssdk + +from .mock_connector import MockConnector + +swsssdk.SonicV2Connector = MockConnector + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +scripts_path = os.path.join(modules_path, "scripts") +sys.path.insert(0, modules_path) + +imp.load_source('procdockerstatsd', scripts_path + '/procdockerstatsd') +from procdockerstatsd import * + +class TestProcDockerStatsDaemon(object): + def test_convert_to_bytes(self): + test_data = [ + ('1B', 1), + ('500B', 500), + ('1KB', 1000), + ('500KB', 500000), + ('1MB', 1000000), + ('500MB', 500000000), + ('1MiB', 1048576), + ('500MiB', 524288000), + ('66.41MiB', 69635932), + ('333.6MiB', 349804954), + ('1GiB', 1073741824), + ('500GiB', 536870912000), + ('7.751GiB', 8322572878) + ] + + pdstatsd = ProcDockerStats(SYSLOG_IDENTIFIER) + + for test_input, expected_output in test_data: + res = pdstatsd.convert_to_bytes(test_input) + assert res == expected_output From 5bfe37ca42d3033087af893de3aacf7536ed25a6 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 23 Oct 2020 12:28:36 -0700 Subject: [PATCH 1278/1427] [Arista] Update driver submodules (#5686) - Enable thermalctld support for our platforms - Fix Chassis.get_num_sfp which had an off by one - Implement read_eeprom and write_eeprom in SfpBase - Refactor of Psus and PsuSlots. Psus they are now detected and metadata reported - Improvements to modular support Co-authored-by: Zhi Yuan Carl Zhao --- .../pmon_daemon_control.json | 2 +- .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 2 +- .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 2 +- .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 2 +- .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 2 +- .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 2 +- .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 2 +- .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 2 +- .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 2 +- .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 2 +- .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 1 + .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 2 +- .../thermal_policy.json | 1 + .../pmon_daemon_control.json | 4 ++ .../x86_64-arista_common/thermal_policy.json | 60 +++++++++++++++++++ .../barefoot/sonic-platform-modules-arista | 2 +- .../broadcom/sonic-platform-modules-arista | 2 +- rules/docker-platform-monitor.mk | 1 + 29 files changed, 91 insertions(+), 13 deletions(-) create mode 120000 device/arista/x86_64-arista_7050_qx32/thermal_policy.json create mode 120000 device/arista/x86_64-arista_7050_qx32s/thermal_policy.json create mode 120000 device/arista/x86_64-arista_7050cx3_32s/thermal_policy.json create mode 120000 device/arista/x86_64-arista_7060_cx32s/thermal_policy.json create mode 120000 device/arista/x86_64-arista_7060cx2_32s/thermal_policy.json create mode 120000 device/arista/x86_64-arista_7060px4_32/thermal_policy.json create mode 120000 device/arista/x86_64-arista_7170_32c/thermal_policy.json create mode 120000 device/arista/x86_64-arista_7170_32cd/thermal_policy.json create mode 120000 device/arista/x86_64-arista_7170_64c/thermal_policy.json create mode 120000 device/arista/x86_64-arista_7260cx3_64/thermal_policy.json create mode 120000 device/arista/x86_64-arista_7280cr3_32d4/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7280cr3_32d4/thermal_policy.json create mode 120000 device/arista/x86_64-arista_7280cr3_32p4/thermal_policy.json create mode 100644 device/arista/x86_64-arista_common/pmon_daemon_control.json create mode 100644 device/arista/x86_64-arista_common/thermal_policy.json diff --git a/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json b/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json index 2322ef7a22d8..51d5ab7b0059 120000 --- a/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json +++ b/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json @@ -1 +1 @@ -../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32/thermal_policy.json b/device/arista/x86_64-arista_7050_qx32/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json index 2322ef7a22d8..51d5ab7b0059 120000 --- a/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json +++ b/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json @@ -1 +1 @@ -../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/thermal_policy.json b/device/arista/x86_64-arista_7050_qx32s/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json index 2322ef7a22d8..51d5ab7b0059 120000 --- a/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json +++ b/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json @@ -1 +1 @@ -../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/thermal_policy.json b/device/arista/x86_64-arista_7050cx3_32s/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json index 2322ef7a22d8..51d5ab7b0059 120000 --- a/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json +++ b/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json @@ -1 +1 @@ -../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/thermal_policy.json b/device/arista/x86_64-arista_7060_cx32s/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json index 2322ef7a22d8..51d5ab7b0059 120000 --- a/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json +++ b/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json @@ -1 +1 @@ -../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/thermal_policy.json b/device/arista/x86_64-arista_7060cx2_32s/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json b/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json index 2322ef7a22d8..51d5ab7b0059 120000 --- a/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json +++ b/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json @@ -1 +1 @@ -../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060px4_32/thermal_policy.json b/device/arista/x86_64-arista_7060px4_32/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7060px4_32/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json index 2322ef7a22d8..51d5ab7b0059 120000 --- a/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json +++ b/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json @@ -1 +1 @@ -../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/thermal_policy.json b/device/arista/x86_64-arista_7170_32c/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json index 2322ef7a22d8..51d5ab7b0059 120000 --- a/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json +++ b/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json @@ -1 +1 @@ -../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/thermal_policy.json b/device/arista/x86_64-arista_7170_32cd/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json index 2322ef7a22d8..51d5ab7b0059 120000 --- a/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json +++ b/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json @@ -1 +1 @@ -../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_64c/thermal_policy.json b/device/arista/x86_64-arista_7170_64c/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json b/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json index 2322ef7a22d8..51d5ab7b0059 120000 --- a/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json +++ b/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json @@ -1 +1 @@ -../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/thermal_policy.json b/device/arista/x86_64-arista_7260cx3_64/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/pmon_daemon_control.json b/device/arista/x86_64-arista_7280cr3_32d4/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/thermal_policy.json b/device/arista/x86_64-arista_7280cr3_32d4/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json b/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json index 2322ef7a22d8..51d5ab7b0059 120000 --- a/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json +++ b/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json @@ -1 +1 @@ -../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32p4/thermal_policy.json b/device/arista/x86_64-arista_7280cr3_32p4/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_common/pmon_daemon_control.json b/device/arista/x86_64-arista_common/pmon_daemon_control.json new file mode 100644 index 000000000000..6453cd2c5d0d --- /dev/null +++ b/device/arista/x86_64-arista_common/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_fancontrol": true +} + diff --git a/device/arista/x86_64-arista_common/thermal_policy.json b/device/arista/x86_64-arista_common/thermal_policy.json new file mode 100644 index 000000000000..bc1bd0acfad0 --- /dev/null +++ b/device/arista/x86_64-arista_common/thermal_policy.json @@ -0,0 +1,60 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "true", + "fan_speed_when_suspend": "100" + }, + "info_types": [ + { + "type": "control_info" + }, + { + "type": "fan_info" + }, + { + "type": "thermal_info" + } + ], + "policies": [ + { + "name": "any thermal critical", + "conditions": [ + { + "type": "thermal.any.critical" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "any thermal overheat", + "conditions": [ + { + "type": "thermal.any.overheat" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "normal operations", + "conditions": [ + { + "type": "normal" + } + ], + "actions": [ + { + "type": "thermal_control.control" + } + ] + } + ] +} diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 10f08eea2732..05a02d74c91f 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 10f08eea27329e7090fcedf1857f3ab385a27a27 +Subproject commit 05a02d74c91fb1b91fbb4602bf8c77067da3ecf2 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 10f08eea2732..05a02d74c91f 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 10f08eea27329e7090fcedf1857f3ab385a27a27 +Subproject commit 05a02d74c91fb1b91fbb4602bf8c77067da3ecf2 diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index e864f42a7072..b6ea78d53f0b 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -43,6 +43,7 @@ $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += --privileged -t $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # Mount Arista python library on Aboot images to be used by plugins +$(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /run/arista:/run/arista:ro $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista:/usr/lib/python2.7/dist-packages/arista:ro $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/sonic_platform:/usr/lib/python2.7/dist-packages/sonic_platform:ro From 15c59e1d8c8a60306f5f899c716ea2cd8ceed7ba Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Sat, 24 Oct 2020 03:36:11 +0800 Subject: [PATCH 1279/1427] [Mellanox] Re-initialize SFP object when detecting a new SFP insertion (#5695) When detecting a new SFP insertion, read its SFP type and DOM capability from EEPROM again. SFP object will be initialized to a certain type even if no SFP present. A case could be: 1. A SFP object is initialized to QSFP type by default when there is no SFP present 2. User insert a SFP with an adapter to this QSFP port 3. The SFP object fail to read EEPROM because it still treats itself as QSFP. This PR fixes this issue. --- .../sonic_platform/chassis.py | 19 +++++++++++++++++++ .../mlnx-platform-api/sonic_platform/sfp.py | 10 ++++++++++ 2 files changed, 29 insertions(+) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 5ad205674bc8..1682d4649d3f 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -465,10 +465,29 @@ def get_change_event(self, timeout=0): status = self.sfp_event.check_sfp_status(port_dict, timeout) if status: + self.reinit_sfps(port_dict) return True, {'sfp':port_dict} else: return True, {'sfp':{}} + def reinit_sfps(self, port_dict): + """ + Re-initialize SFP if there is any newly inserted SFPs + :param port_dict: SFP event data + :return: + """ + # SFP not initialize yet, do nothing + if not self.sfp_module_initialized: + return + + from . import sfp + for index, status in port_dict.items(): + if status == sfp.SFP_STATUS_INSERTED: + try: + self.get_sfp(index).reinit() + except Exception as e: + logger.log_error("Fail to re-initialize SFP {} - {}".format(index, repr(e))) + def get_thermal_manager(self): from .thermal_manager import ThermalManager return ThermalManager diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 47a42bf8f8f9..4814055ca5bc 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -279,6 +279,9 @@ NVE_MASK = PORT_TYPE_MASK & (PORT_TYPE_NVE << PORT_TYPE_OFFSET) CPU_MASK = PORT_TYPE_MASK & (PORT_TYPE_CPU << PORT_TYPE_OFFSET) +# parameters for SFP presence +SFP_STATUS_INSERTED = '1' + # Global logger class instance logger = Logger() @@ -316,6 +319,13 @@ def __init__(self, sfp_index, sfp_type, sdk_handle): self.sdk_handle = sdk_handle self.sdk_index = sfp_index + def reinit(self): + """ + Re-initialize this SFP object when a new SFP inserted + :return: + """ + self._detect_sfp_type(self.sfp_type) + self._dom_capability_detect() def get_presence(self): """ From 67408c85aaa56e75911eb88926dc9819ae6b505b Mon Sep 17 00:00:00 2001 From: Shi Su <67605788+shi-su@users.noreply.github.com> Date: Fri, 23 Oct 2020 13:08:35 -0700 Subject: [PATCH 1280/1427] [synchronous-mode] Add template file for synchronous mode (#5644) The orchagent and syncd need to have the same default synchronous mode configuration. This PR adds a template file to translate the default value in CONFIG_DB (empty field) to an explicit mode so that the orchagent and syncd could have the same default mode. --- dockers/docker-config-engine-buster/Dockerfile.j2 | 3 +++ dockers/docker-config-engine-stretch/Dockerfile.j2 | 3 +++ dockers/docker-config-engine/Dockerfile.j2 | 3 +++ dockers/docker-orchagent/orchagent.sh | 8 +------- .../build_templates}/swss_vars.j2 | 3 +-- platform/p4/docker-sonic-p4/orchagent.sh | 9 +++++++-- platform/vs/docker-sonic-vs/orchagent.sh | 10 +++++++--- rules/docker-config-engine-buster.mk | 1 + rules/docker-config-engine-stretch.mk | 1 + rules/docker-config-engine.mk | 1 + rules/scripts.mk | 6 +++++- 11 files changed, 33 insertions(+), 15 deletions(-) rename {dockers/docker-orchagent => files/build_templates}/swss_vars.j2 (54%) diff --git a/dockers/docker-config-engine-buster/Dockerfile.j2 b/dockers/docker-config-engine-buster/Dockerfile.j2 index d48cb33d157e..93e1c98889f5 100644 --- a/dockers/docker-config-engine-buster/Dockerfile.j2 +++ b/dockers/docker-config-engine-buster/Dockerfile.j2 @@ -39,6 +39,9 @@ RUN pip install \ {{ install_python_wheels(docker_config_engine_buster_whls.split(' ')) }} {% endif %} +# Copy files +COPY ["files/swss_vars.j2", "/usr/share/sonic/templates/"] + ## Clean up RUN apt-get purge -y \ python-pip \ diff --git a/dockers/docker-config-engine-stretch/Dockerfile.j2 b/dockers/docker-config-engine-stretch/Dockerfile.j2 index eec55982f5a7..21c5e65b7712 100644 --- a/dockers/docker-config-engine-stretch/Dockerfile.j2 +++ b/dockers/docker-config-engine-stretch/Dockerfile.j2 @@ -38,6 +38,9 @@ RUN pip install \ {{ install_python_wheels(docker_config_engine_stretch_whls.split(' ')) }} {% endif %} +# Copy files +COPY ["files/swss_vars.j2", "/usr/share/sonic/templates/"] + ## Clean up RUN apt-get purge -y \ python-pip \ diff --git a/dockers/docker-config-engine/Dockerfile.j2 b/dockers/docker-config-engine/Dockerfile.j2 index e681ba1839bd..6e5a56dbdfb7 100644 --- a/dockers/docker-config-engine/Dockerfile.j2 +++ b/dockers/docker-config-engine/Dockerfile.j2 @@ -42,6 +42,9 @@ python-wheels/{{ whl }}{{' '}} {%- endfor %} {%- endif -%} +# Copy files +COPY ["files/swss_vars.j2", "/usr/share/sonic/templates/"] + ## Clean up RUN apt-get purge -y python-pip python-dev; apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs /python-wheels diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index fde5370dc181..45715dc61f9c 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -1,15 +1,9 @@ #!/usr/bin/env bash -EXIT_SWSS_VARS_FILE_NOT_FOUND=1 SWSS_VARS_FILE=/usr/share/sonic/templates/swss_vars.j2 -if [ ! -f "$SWSS_VARS_FILE" ]; then - echo "SWSS vars template file not found" - exit $EXIT_SWSS_VARS_FILE_NOT_FOUND -fi - # Retrieve SWSS vars from sonic-cfggen -SWSS_VARS=$(sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t $SWSS_VARS_FILE) +SWSS_VARS=$(sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t $SWSS_VARS_FILE) || exit 1 export platform=$(echo $SWSS_VARS | jq -r '.asic_type') MAC_ADDRESS=$(echo $SWSS_VARS | jq -r '.mac') diff --git a/dockers/docker-orchagent/swss_vars.j2 b/files/build_templates/swss_vars.j2 similarity index 54% rename from dockers/docker-orchagent/swss_vars.j2 rename to files/build_templates/swss_vars.j2 index cb96aa826f6b..377837aad0ee 100644 --- a/dockers/docker-orchagent/swss_vars.j2 +++ b/files/build_templates/swss_vars.j2 @@ -2,6 +2,5 @@ "asic_type": "{{ asic_type }}", "asic_id": "{{ DEVICE_METADATA.localhost.asic_id }}", "mac": "{{ DEVICE_METADATA.localhost.mac }}", - "synchronous_mode": "{{ DEVICE_METADATA.localhost.synchronous_mode }}" + "synchronous_mode": {% if DEVICE_METADATA.localhost.synchronous_mode == "enable" %}"enable"{% else %}"disable"{% endif %} } - diff --git a/platform/p4/docker-sonic-p4/orchagent.sh b/platform/p4/docker-sonic-p4/orchagent.sh index 52cdd43265f0..1975e44753f1 100755 --- a/platform/p4/docker-sonic-p4/orchagent.sh +++ b/platform/p4/docker-sonic-p4/orchagent.sh @@ -1,6 +1,11 @@ #!/usr/bin/env bash -MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +SWSS_VARS_FILE=/usr/share/sonic/templates/swss_vars.j2 + +# Retrieve SWSS vars from sonic-cfggen +SWSS_VARS=$(sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t $SWSS_VARS_FILE) || exit 1 + +MAC_ADDRESS=$(echo $SWSS_VARS | jq -r '.mac') if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') logger "Mac address not found in Device Metadata, Falling back to eth0" @@ -14,7 +19,7 @@ ORCHAGENT_ARGS="-d /var/log/swss " ORCHAGENT_ARGS+="-b 8192 " # Set synchronous mode if it is enabled in CONFIG_DB -SYNC_MODE=$(sonic-cfggen -d -v DEVICE_METADATA.localhost.synchronous_mode) +SYNC_MODE=$(echo $SWSS_VARS | jq -r '.synchronous_mode') if [ "$SYNC_MODE" == "enable" ]; then ORCHAGENT_ARGS+="-s " fi diff --git a/platform/vs/docker-sonic-vs/orchagent.sh b/platform/vs/docker-sonic-vs/orchagent.sh index ec703fa10ee6..4a035a26b292 100755 --- a/platform/vs/docker-sonic-vs/orchagent.sh +++ b/platform/vs/docker-sonic-vs/orchagent.sh @@ -6,8 +6,12 @@ else export platform=$fake_platform fi -CFG_VARS=$(sonic-cfggen -d --var-json 'DEVICE_METADATA') -MAC_ADDRESS=$(echo $CFG_VARS | jq -r '.localhost.mac') +SWSS_VARS_FILE=/usr/share/sonic/templates/swss_vars.j2 + +# Retrieve SWSS vars from sonic-cfggen +SWSS_VARS=$(sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t $SWSS_VARS_FILE) || exit 1 + +MAC_ADDRESS=$(echo $SWSS_VARS | jq -r '.mac') if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') logger "Mac address not found in Device Metadata, Falling back to eth0" @@ -21,7 +25,7 @@ ORCHAGENT_ARGS="-d /var/log/swss " ORCHAGENT_ARGS+="-b 8192 " # Set synchronous mode if it is enabled in CONFIG_DB -SYNC_MODE=$(echo $CFG_VARS | jq -r '.localhost.synchronous_mode') +SYNC_MODE=$(echo $SWSS_VARS | jq -r '.synchronous_mode') if [ "$SYNC_MODE" == "enable" ]; then ORCHAGENT_ARGS+="-s " fi diff --git a/rules/docker-config-engine-buster.mk b/rules/docker-config-engine-buster.mk index 1f101236cd96..f1c54f10b627 100644 --- a/rules/docker-config-engine-buster.mk +++ b/rules/docker-config-engine-buster.mk @@ -7,6 +7,7 @@ $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE_BUSTER)_LOAD_DOCKERS += $(DOCKER_BASE_BUSTER) +$(DOCKER_CONFIG_ENGINE_BUSTER)_FILES += $(SWSS_VARS_TEMPLATE) $(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS = $($(DOCKER_BASE_BUSTER)_DBG_DEPENDS) $(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES = $($(DOCKER_BASE_BUSTER)_DBG_IMAGE_PACKAGES) diff --git a/rules/docker-config-engine-stretch.mk b/rules/docker-config-engine-stretch.mk index 075905998730..485e10fbb713 100644 --- a/rules/docker-config-engine-stretch.mk +++ b/rules/docker-config-engine-stretch.mk @@ -6,6 +6,7 @@ $(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) $(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE_STRETCH)_LOAD_DOCKERS += $(DOCKER_BASE_STRETCH) +$(DOCKER_CONFIG_ENGINE_STRETCH)_FILES += $(SWSS_VARS_TEMPLATE) $(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS = $($(DOCKER_BASE_STRETCH)_DBG_DEPENDS) $(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES = $($(DOCKER_BASE_STRETCH)_DBG_IMAGE_PACKAGES) diff --git a/rules/docker-config-engine.mk b/rules/docker-config-engine.mk index 56a9c9755e7b..518e73415a6b 100644 --- a/rules/docker-config-engine.mk +++ b/rules/docker-config-engine.mk @@ -6,4 +6,5 @@ $(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) $(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE)_LOAD_DOCKERS += $(DOCKER_BASE) +$(DOCKER_CONFIG_ENGINE)_FILES += $(SWSS_VARS_TEMPLATE) SONIC_DOCKER_IMAGES += $(DOCKER_CONFIG_ENGINE) diff --git a/rules/scripts.mk b/rules/scripts.mk index 1e5275a254ba..13fae75434be 100644 --- a/rules/scripts.mk +++ b/rules/scripts.mk @@ -23,6 +23,9 @@ $(SYSCTL_NET_CONFIG)_PATH = files/image_config/sysctl UPDATE_CHASSISDB_CONFIG_SCRIPT = update_chassisdb_config $(UPDATE_CHASSISDB_CONFIG_SCRIPT)_PATH = files/scripts +SWSS_VARS_TEMPLATE = swss_vars.j2 +$(SWSS_VARS_TEMPLATE)_PATH = files/build_templates + SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(ARP_UPDATE_SCRIPT) \ $(ARP_UPDATE_VARS_TEMPLATE) \ @@ -30,4 +33,5 @@ SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(QOS_CONFIG_TEMPLATE) \ $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) \ $(SYSCTL_NET_CONFIG) \ - $(UPDATE_CHASSISDB_CONFIG_SCRIPT) + $(UPDATE_CHASSISDB_CONFIG_SCRIPT) \ + $(SWSS_VARS_TEMPLATE) From ba6f012cc60b49d4eaec62414cb1b8ddaa1ae79a Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Sat, 24 Oct 2020 22:36:22 +0300 Subject: [PATCH 1281/1427] [sonic-py-common]: Fix syslog implicit min priority override (#5707) Current implementation of logger class is based on standard python syslog library. Thus, logger class can be instantiated in different places and share the same context across the entire process. This means that reducing log severity level will affect other modules which use logging facility. **- Why I did it** * To fix syslog implicit min priority override **- How I did it** * Added per instance log severity check **- How to verify it** 1. Run code snippet ``` from sonic_py_common import logger log1 = logger.Logger(log_identifier='myApp1') log1.set_min_log_priority_debug() log1.log_error("=> this is error") log1.log_warning("=> this is warning") log1.log_notice("=> this is notice") log1.log_info("=> this is info") log1.log_debug("=> this is debug") log2 = logger.Logger( log_identifier='myApp2', log_facility=logger.Logger.LOG_FACILITY_DAEMON, log_option=(logger.Logger.LOG_OPTION_NDELAY | logger.Logger.LOG_OPTION_PID) ) log2.log_error("=> this is error") log2.log_warning("=> this is warning") log2.log_notice("=> this is notice") log2.log_info("=> this is info") log2.log_debug("=> this is debug") ``` 2. Sample output: ``` Oct 23 15:08:30.447301 sonic ERR myApp1: => this is error Oct 23 15:08:30.447908 sonic WARNING myApp1: => this is warning Oct 23 15:08:30.448305 sonic NOTICE myApp1: => this is notice Oct 23 15:08:30.448696 sonic INFO myApp1: => this is info Oct 23 15:08:30.449063 sonic DEBUG myApp1: => this is debug Oct 23 15:08:30.449442 sonic ERR myApp2[19178]: => this is error Oct 23 15:08:30.449819 sonic WARNING myApp2[19178]: => this is warning Oct 23 15:08:30.450183 sonic NOTICE myApp2[19178]: => this is notice ``` Signed-off-by: Nazarii Hnydyn --- .../sonic_py_common/daemon_base.py | 7 +++- src/sonic-py-common/sonic_py_common/logger.py | 32 ++++++++++++------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/daemon_base.py b/src/sonic-py-common/sonic_py_common/daemon_base.py index 818be5fa4305..c3ecc12cf856 100644 --- a/src/sonic-py-common/sonic_py_common/daemon_base.py +++ b/src/sonic-py-common/sonic_py_common/daemon_base.py @@ -8,6 +8,7 @@ # # Constants ==================================================================== # + REDIS_TIMEOUT_MSECS = 0 EEPROM_MODULE_NAME = 'eeprom' @@ -30,7 +31,11 @@ def db_connect(db_name, namespace=EMPTY_NAMESPACE): class DaemonBase(Logger): def __init__(self, log_identifier): - super(DaemonBase, self).__init__(log_identifier, Logger.LOG_FACILITY_DAEMON) + super(DaemonBase, self).__init__( + log_identifier=log_identifier, + log_facility=Logger.LOG_FACILITY_DAEMON, + log_option=(Logger.LOG_OPTION_NDELAY | Logger.LOG_OPTION_PID) + ) # Register our default signal handlers, unless the signal already has a # handler registered, most likely from a subclass implementation diff --git a/src/sonic-py-common/sonic_py_common/logger.py b/src/sonic-py-common/sonic_py_common/logger.py index 26adf999a095..fa86221d6d75 100644 --- a/src/sonic-py-common/sonic_py_common/logger.py +++ b/src/sonic-py-common/sonic_py_common/logger.py @@ -11,8 +11,11 @@ class Logger(object): """ Logger class for SONiC Python applications """ - LOG_FACILITY_USER = syslog.LOG_USER LOG_FACILITY_DAEMON = syslog.LOG_DAEMON + LOG_FACILITY_USER = syslog.LOG_USER + + LOG_OPTION_NDELAY = syslog.LOG_NDELAY + LOG_OPTION_PID = syslog.LOG_PID LOG_PRIORITY_ERROR = syslog.LOG_ERR LOG_PRIORITY_WARNING = syslog.LOG_WARNING @@ -20,21 +23,23 @@ class Logger(object): LOG_PRIORITY_INFO = syslog.LOG_INFO LOG_PRIORITY_DEBUG = syslog.LOG_DEBUG - def __init__(self, log_identifier=None, log_facility=LOG_FACILITY_USER): - self.syslog = syslog + DEFAULT_LOG_FACILITY = LOG_FACILITY_USER + DEFAULT_LOG_OPTION = LOG_OPTION_NDELAY + + def __init__(self, log_identifier=None, log_facility=DEFAULT_LOG_FACILITY, log_option=DEFAULT_LOG_OPTION): + self._syslog = syslog - if not log_identifier: + if log_identifier is None: log_identifier = os.path.basename(sys.argv[0]) - self.syslog.openlog(ident=log_identifier, - logoption=(syslog.LOG_PID | syslog.LOG_NDELAY), - facility=log_facility) + # Initialize syslog + self._syslog.openlog(ident=log_identifier, logoption=log_option, facility=log_facility) # Set the default minimum log priority to LOG_PRIORITY_NOTICE self.set_min_log_priority(self.LOG_PRIORITY_NOTICE) def __del__(self): - self.syslog.closelog() + self._syslog.closelog() # # Methods for setting minimum log priority @@ -48,7 +53,7 @@ def set_min_log_priority(self, priority): Args: priority: The minimum priority at which to log messages """ - self.syslog.setlogmask(self.syslog.LOG_UPTO(priority)) + self._min_log_priority = priority def set_min_log_priority_error(self): """ @@ -85,10 +90,13 @@ def set_min_log_priority_debug(self): # def log(self, priority, msg, also_print_to_console=False): - self.syslog.syslog(priority, msg) + if self._min_log_priority >= priority: + # Send message to syslog + self._syslog.syslog(priority, msg) - if also_print_to_console: - print(msg) + # Send message to console + if also_print_to_console: + print(msg) def log_error(self, msg, also_print_to_console=False): self.log(self.LOG_PRIORITY_ERROR, msg, also_print_to_console) From 5486f87afc7d831b5d50c1a88ed1c73819b1ca1d Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Sun, 25 Oct 2020 19:44:37 +0200 Subject: [PATCH 1282/1427] [Mellanox] Update platform components config files. (#5685) Signed-off-by: Nazarii Hnydyn --- device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json | 2 +- device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json | 2 +- device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json | 2 +- device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json | 2 +- device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json | 2 +- device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json | 2 +- device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json | 2 +- .../mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json | 2 +- device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json | 2 +- .../mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json | 2 +- device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json index 2ffab4b01794..a5cd5b152c46 100644 --- a/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json @@ -1,6 +1,6 @@ { "chassis": { - "x86_64-mlnx_msn2010-r0": { + "MSN2010": { "component": { "ONIE": { }, "SSD": { }, diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json index 7778adf6fc1e..b8936fa3ad43 100644 --- a/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json @@ -1,6 +1,6 @@ { "chassis": { - "x86_64-mlnx_msn2100-r0": { + "MSN2100": { "component": { "ONIE": { }, "SSD": { }, diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json index b6a1555c712f..52c09f4ea998 100644 --- a/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json @@ -1,6 +1,6 @@ { "chassis": { - "x86_64-mlnx_msn2410-r0": { + "MSN2410": { "component": { "ONIE": { }, "SSD": { }, diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json index 00ef07c819b1..33a73547cc37 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json @@ -1,6 +1,6 @@ { "chassis": { - "x86_64-mlnx_msn2700-r0": { + "MSN2700": { "component": { "ONIE": { }, "SSD": { }, diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json index 1765103d2f38..da85f2b5792e 100644 --- a/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json @@ -1,6 +1,6 @@ { "chassis": { - "x86_64-mlnx_msn2740-r0": { + "MSN2740": { "component": { "ONIE": { }, "SSD": { }, diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json index b243ca061aba..9b5cceae9fc8 100644 --- a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json @@ -1,6 +1,6 @@ { "chassis": { - "x86_64-mlnx_msn3420-r0": { + "MSN3420": { "component": { "ONIE": { }, "SSD": { }, diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json index c374fb0aba76..6ca284d3f341 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json @@ -1,6 +1,6 @@ { "chassis": { - "x86_64-mlnx_msn3700-r0": { + "MSN3700": { "component": { "ONIE": { }, "SSD": { }, diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json index 437804c65205..807503fced45 100644 --- a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json @@ -1,6 +1,6 @@ { "chassis": { - "x86_64-mlnx_msn3700c-r0": { + "MSN3700C": { "component": { "ONIE": { }, "SSD": { }, diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json index 88d3afec166b..deddbcc04158 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json @@ -1,6 +1,6 @@ { "chassis": { - "x86_64-mlnx_msn3800-r0": { + "MSN3800": { "component": { "ONIE": { }, "SSD": { }, diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json index 09a7e924d1b3..22bcfcc29700 100644 --- a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json @@ -1,6 +1,6 @@ { "chassis": { - "x86_64-mlnx_msn4600c-r0": { + "MSN4600C": { "component": { "ONIE": { }, "SSD": { }, diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json index 4a64ae0cb2a0..c663b782187e 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json @@ -1,6 +1,6 @@ { "chassis": { - "x86_64-mlnx_msn4700-r0": { + "MSN4700": { "component": { "ONIE": { }, "SSD": { }, From 7d4ab4237a7fc76051886c10247ab3c6ae5f208e Mon Sep 17 00:00:00 2001 From: lguohan Date: Sun, 25 Oct 2020 20:39:38 -0700 Subject: [PATCH 1283/1427] [docker-base]: swss/syncd support use zmq as rpc channel (#5715) install libzmq5 in docker-base Signed-off-by: Guohan Lu --- dockers/docker-base-buster/Dockerfile.j2 | 4 +++- dockers/docker-base-stretch/Dockerfile.j2 | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index 6f848b1f7177..4d8b189f8ec9 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -71,7 +71,9 @@ RUN apt-get update && \ python-setuptools \ python-wheel \ # for processing/handling json files in bash environment - jq + jq \ +# for sairedis zmq rpc channel + libzmq5 # Install redis-tools RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index a5eda50f0c1c..79f5c90660af 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -63,7 +63,9 @@ RUN apt-get update && \ python-setuptools \ python-wheel \ # for processing json files in bash environment - jq + jq \ +# for sairedis zmq rpc channel + libzmq5 # Install a newer version of rsyslog from stretch-backports to support -iNONE RUN apt-get -y -t stretch-backports install rsyslog From c4f9bec562d8d96ea332087277f7d568ee904868 Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Mon, 26 Oct 2020 08:52:20 -0700 Subject: [PATCH 1284/1427] [minigraph.py]: Add support for parsing mux cable (#5676) Find LogicalLinks in minigraph and parse the port information. A new field called `mux_cable` is added to each port's entry in the Port table in config DB: ``` PORT|Ethernet0: { "alias": "Ethernet4/1" ... "mux_cable": "true" } ``` If a mux cable is present on a port, the value for `mux_cable` will be `"true"`. If no mux cable is present, the attribute will either be omitted (default behavior) or set to `"false"`. --- src/sonic-config-engine/minigraph.py | 20 +++++++++++++++-- .../tests/simple-sample-graph-case.xml | 22 +++++++++++++++++++ src/sonic-config-engine/tests/test_cfggen.py | 4 ++-- .../tests/test_minigraph_case.py | 11 ++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index d53a56d7daea..294fb7faaaca 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -90,6 +90,7 @@ def parse_png(png, hname): mgmt_port = '' port_speeds = {} console_ports = {} + mux_cable_ports = {} for child in png: if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for link in child.findall(str(QName(ns, "DeviceLinkBase"))): @@ -162,7 +163,16 @@ def parse_png(png, hname): elif node.tag == str(QName(ns, "EndDevice")): mgmt_dev = node.text - return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports) + if child.tag == str(QName(ns, "DeviceInterfaceLinks")): + for link in child.findall(str(QName(ns, 'DeviceLinkBase'))): + if link.find(str(QName(ns, "ElementType"))).text == "LogicalLink": + intf_name = link.find(str(QName(ns, "EndPort"))).text + if intf_name in port_alias_map: + intf_name = port_alias_map[intf_name] + + mux_cable_ports[intf_name] = "true" + + return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports, mux_cable_ports) def parse_asic_external_link(link, asic_name, hostname): neighbors = {} @@ -831,6 +841,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw port_speed_png = {} port_descriptions = {} console_ports = {} + mux_cable_ports = {} syslog_servers = [] dhcp_servers = [] ntp_servers = [] @@ -873,7 +884,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): - (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports) = parse_png(child, hostname) + (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports, mux_cable_ports) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): @@ -1009,6 +1020,11 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw if port.get('speed') == '100000' and linkmetas.get(alias, {}).get('FECDisabled', '').lower() != 'true': port['fec'] = 'rs' + # If connected to a smart cable, get the connection position + for port_name, port in ports.items(): + if port_name in mux_cable_ports: + port['mux_cable'] = mux_cable_ports[port_name] + # set port description if parsed from deviceinfo for port_name in port_descriptions: # ignore port not in port_config.ini diff --git a/src/sonic-config-engine/tests/simple-sample-graph-case.xml b/src/sonic-config-engine/tests/simple-sample-graph-case.xml index acfcd4a6a74b..3188409b1fd0 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-case.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-case.xml @@ -209,6 +209,28 @@ switch-02t1 port1 + + LogicalLink + 10000 + false + switch-t0 + fortyGigE0/4 + true + mux-cable + L + true + + + LogicalLink + 10000 + false + switch-t0 + fortyGigE0/8 + true + mux-cable + U + true + diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 1fe1ad03849c..0d2f94899ede 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -346,9 +346,9 @@ def test_minigraph_neighbor_interfaces(self): self.assertEqual( utils.to_dict(output.strip()), utils.to_dict( - "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '40000'}, " + "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '40000', 'mux_cable': 'true'}, " "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'switch-01t1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " - "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, " + "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000', 'mux_cable': 'true'}, " "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index f9c390b6536a..42e5e63ac6d6 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -2,6 +2,7 @@ import subprocess import tests.common_utils as utils +import minigraph from unittest import TestCase @@ -159,3 +160,13 @@ def test_minigraph_bgp_mon(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{}") + def test_mux_cable_parsing(self): + result = minigraph.parse_xml(self.sample_graph, port_config_file=self.port_config) + + expected_mux_cable_ports = ["Ethernet4", "Ethernet8"] + port_table = result['PORT'] + for port_name, port in port_table.items(): + if port_name in expected_mux_cable_ports: + self.assertTrue(port["mux_cable"]) + else: + self.assertTrue("mux_cable" not in port) From c14b41dc30a286d0a3acc46a2f369521eb8b7bf2 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Mon, 26 Oct 2020 09:19:16 -0700 Subject: [PATCH 1285/1427] [submodule]: Advance sonic-swss-common and sonic-sairedis module (#5703) Advance sonic-swss-common submodule by adding the following commits 3ec30ef Deprecate RedisClient and remove unused header file (#399) 165a679 Schema update for BGP internal neighbor table (#389) 262e330 Fix SonicV2Connector interfaces (#396) Advance sonic-sairedis submodule by adding the following commits bc3e044 [Sai]: Change Sai::set log to level INFO (#680) b16bc8b Clean code: remove unused header file (#678) 40439b4 [syncd] Remove depreacated dependency on swss::RedisClient (#681) 1b6fc2e [syncd] Add supports of bulk api in syncd (#656) a9f69c1 [syncd] Add to handle FDB MOVE notification (#670) c7ef5e9 [gbsyncd] exit with zero when platform has no gearbox (#676) 57228fd [gbsyncd]: add missing python dependency (#675) 02a57a6 [vs] Add CRM SAI attributes to virtual switch interface (#673) 609445a fix boot type for fast boot (#674) 1325cdf Add support for saiplayer bulk API and add performance timers (#666) 1d84b90 Add ZeroMQ communication channel between sairedis and syncd (#659) 017056a Support System ports config (#657) 0f3668f Enable fabric counter for syncd's FlexCounter (#669) --- src/sonic-sairedis | 2 +- src/sonic-swss-common | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 573d5c116cff..bc3e044cefc5 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 573d5c116cff29d5e95dd5f172a773949ce76a66 +Subproject commit bc3e044cefc560e06d4c27576957b25b626d573b diff --git a/src/sonic-swss-common b/src/sonic-swss-common index abf43569e41e..3ec30ef36aef 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit abf43569e41e65886457995d0845848d58695a9c +Subproject commit 3ec30ef36aef70052fbe06af427174041cda4c81 From e66d49a57ced72653f10b1c6da4bc284b67d2d5b Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Mon, 26 Oct 2020 19:38:09 +0200 Subject: [PATCH 1286/1427] [LLDP] Fix for LLDP advertisements being sent with wrong information. (#5493) * Fix for LLDP advertisments being sent with wrong information. Since lldpd is starting before lldpmgr, some advertisment packets might sent with default value, mac address as Port ID. This fix hold the packets from being sent by the lldpd until all interfaces are well configured by the lldpmgrd. Signed-off-by: Shlomi Bitton * Fix comments * Fix unit-test output caused a failure during build * Add 'run_cmd' function and use it * Resume lldpd even if port init timeout reached --- dockers/docker-lldp/lldpd.conf.j2 | 2 + dockers/docker-lldp/lldpmgrd | 43 +++++++++++++++++-- .../tests/sample_output/py2/lldpd.conf | 1 + .../tests/sample_output/py3/lldpd.conf | 1 + 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/dockers/docker-lldp/lldpd.conf.j2 b/dockers/docker-lldp/lldpd.conf.j2 index 421400037bbf..ae7f3fc4838b 100644 --- a/dockers/docker-lldp/lldpd.conf.j2 +++ b/dockers/docker-lldp/lldpd.conf.j2 @@ -10,3 +10,5 @@ configure ports eth0 lldp portidsubtype local {{ mgmt_port_name }} configure system ip management pattern {{ ipv4 }} {% endif %} configure system hostname {{ DEVICE_METADATA['localhost']['hostname'] }} +{# pause lldpd operations until all interfaces are well configured, resume command will run in lldpmgrd #} +pause diff --git a/dockers/docker-lldp/lldpmgrd b/dockers/docker-lldp/lldpmgrd index dcfaab2244c5..5a421eb55cd6 100755 --- a/dockers/docker-lldp/lldpmgrd +++ b/dockers/docker-lldp/lldpmgrd @@ -19,6 +19,9 @@ try: import subprocess import sys + import syslog + import os.path + import time from sonic_py_common import daemon_base from swsscommon import swsscommon except ImportError as err: @@ -27,6 +30,7 @@ except ImportError as err: VERSION = "1.0" SYSLOG_IDENTIFIER = "lldpmgrd" +PORT_INIT_TIMEOUT = 300 class LldpManager(daemon_base.DaemonBase): @@ -130,16 +134,14 @@ class LldpManager(daemon_base.DaemonBase): for (port_name, cmd) in self.pending_cmds.iteritems(): self.log_debug("Running command: '{}'".format(cmd)) - proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - (stdout, stderr) = proc.communicate() + rc, stderr = run_cmd(self, cmd) # If the command succeeds, add the port name to our to_delete list. # We will delete this command from self.pending_cmds below. # If the command fails, log a message, but don't delete the command # from self.pending_cmds, so that the command will be retried the # next time this method is called. - if proc.returncode == 0: + if rc == 0: to_delete.append(port_name) else: self.log_warning("Command failed '{}': {}".format(cmd, stderr)) @@ -166,6 +168,13 @@ class LldpManager(daemon_base.DaemonBase): # Set select timeout to 10 seconds SELECT_TIMEOUT_MS = 1000 * 10 + # Daemon is paused on the configuration file to avoid lldp packets with wrong information + # until all interfaces are well configured on lldpd + port_init_done = False + port_config_done = False + resume_lldp_sent = False + start_time = time.time() + sel = swsscommon.Select() # Subscribe to PORT table notifications in the Config DB @@ -204,9 +213,25 @@ class LldpManager(daemon_base.DaemonBase): else: self.pending_cmds.pop(key, None) + elif key == "PortInitDone": + port_init_done = True + elif key == "PortConfigDone": + port_config_done = True + # Process all pending commands self.process_pending_cmds() + # Resume the daemon since all interfaces data updated and configured to the lldpd so no miss leading packets will be sent + if not resume_lldp_sent: + if check_timeout(self, start_time): + port_init_done = port_config_done = True + if port_init_done and port_config_done: + port_init_done = port_config_done = False + rc, stderr = run_cmd(self, "lldpcli resume") + if rc != 0: + self.log_error("Failed to resume lldpd with command: 'lldpcli resume': {}".format(stderr)) + sys.exit(1) + resume_lldp_sent = True # ============================= Functions ============================= @@ -219,6 +244,16 @@ def main(): lldpmgr.run() +def run_cmd(self, cmd): + proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (stdout, stderr) = proc.communicate() + return proc.returncode, stderr + +def check_timeout(self, start_time): + if time.time() - start_time > PORT_INIT_TIMEOUT: + self.log_error("Port init timeout reached ({} seconds), resuming lldpd...".format(PORT_INIT_TIMEOUT)) + return True + return False if __name__ == "__main__": main() diff --git a/src/sonic-config-engine/tests/sample_output/py2/lldpd.conf b/src/sonic-config-engine/tests/sample_output/py2/lldpd.conf index d28ec8418362..c9cb2c8123dd 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/lldpd.conf +++ b/src/sonic-config-engine/tests/sample_output/py2/lldpd.conf @@ -1,3 +1,4 @@ configure ports eth0 lldp portidsubtype local eth0 configure system ip management pattern 10.0.0.100 configure system hostname switch-t0 +pause diff --git a/src/sonic-config-engine/tests/sample_output/py3/lldpd.conf b/src/sonic-config-engine/tests/sample_output/py3/lldpd.conf index d28ec8418362..c9cb2c8123dd 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/lldpd.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/lldpd.conf @@ -1,3 +1,4 @@ configure ports eth0 lldp portidsubtype local eth0 configure system ip management pattern 10.0.0.100 configure system hostname switch-t0 +pause From 7bee5093f1758c60d43d68ff54bfc1f36220c90b Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Tue, 27 Oct 2020 03:47:12 +0800 Subject: [PATCH 1287/1427] [Mellanox] Support max/min speed for PSU fan (#5682) As new hw-mgmt expose the sysfs for PSU fan max speed, we need support max/min speed for PSU fan in mellanox platform API. --- .../mlnx-platform-api/sonic_platform/fan.py | 89 +++++-------------- .../mlnx-platform-api/sonic_platform/utils.py | 57 ++++++++++++ 2 files changed, 81 insertions(+), 65 deletions(-) create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/utils.py diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py index 1808bdd0aeee..3b5be3a25db3 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py @@ -14,6 +14,7 @@ try: from sonic_platform_base.fan_base import FanBase from .led import FanLed, ComponentFaultyIndicator + from .utils import read_int_from_file, read_str_from_file, write_file except ImportError as e: raise ImportError (str(e) + "- required module not found") @@ -52,17 +53,18 @@ def __init__(self, fan_index, fan_drawer, psu_fan = False): else: self.led = FanLed(self.index) - self.fan_min_speed_path = "fan{}_min".format(self.index) if not self.is_psu_fan: self.fan_speed_get_path = "fan{}_speed_get".format(self.index) self.fan_speed_set_path = "fan{}_speed_set".format(self.index) - self.fan_max_speed_path = "fan{}_max".format(self.index) + self.fan_max_speed_path = os.path.join(FAN_PATH, "fan{}_max".format(self.index)) + self.fan_min_speed_path = os.path.join(FAN_PATH, "fan{}_min".format(self.index)) self._name = "fan{}".format(self.index) else: self.fan_speed_get_path = "psu{}_fan1_speed_get".format(self.index) self.fan_presence_path = "psu{}_fan1_speed_get".format(self.index) self._name = 'psu_{}_fan_{}'.format(self.index, 1) - self.fan_max_speed_path = None + self.fan_max_speed_path = os.path.join(CONFIG_PATH, "psu_fan_max") + self.fan_min_speed_path = os.path.join(CONFIG_PATH, "psu_fan_min") self.psu_i2c_bus_path = os.path.join(CONFIG_PATH, 'psu{0}_i2c_bus'.format(self.index)) self.psu_i2c_addr_path = os.path.join(CONFIG_PATH, 'psu{0}_i2c_addr'.format(self.index)) self.psu_i2c_command_path = os.path.join(CONFIG_PATH, 'fan_command') @@ -109,11 +111,7 @@ def get_status(self): if self.is_psu_fan: status = 0 else: - try: - with open(os.path.join(FAN_PATH, self.fan_status_path), 'r') as fault_status: - status = int(fault_status.read().strip()) - except (ValueError, IOError): - status = 1 + status = read_int_from_file(os.path.join(FAN_PATH, self.fan_status_path), 1) return status == 0 @@ -135,29 +133,6 @@ def get_presence(self): else: return self.fan_drawer.get_presence() - - def _get_min_speed_in_rpm(self): - speed = 0 - try: - with open(os.path.join(FAN_PATH, self.fan_min_speed_path), 'r') as min_fan_speed: - speed = int(min_fan_speed.read()) - except (ValueError, IOError): - speed = 0 - - return speed - - - def _get_max_speed_in_rpm(self): - speed = 0 - try: - with open(os.path.join(FAN_PATH, self.fan_max_speed_path), 'r') as max_fan_speed: - speed = int(max_fan_speed.read().strip()) - except (ValueError, IOError): - speed = 0 - - return speed - - def get_speed(self): """ Retrieves the speed of fan @@ -166,17 +141,12 @@ def get_speed(self): int: percentage of the max fan speed """ speed = 0 - try: - with open(os.path.join(FAN_PATH, self.fan_speed_get_path), 'r') as fan_curr_speed: - speed_in_rpm = int(fan_curr_speed.read().strip()) - except (ValueError, IOError): - speed_in_rpm = 0 + speed_in_rpm = read_int_from_file(os.path.join(FAN_PATH, self.fan_speed_get_path)) - if self.fan_max_speed_path is None: - # in case of max speed unsupported, we just return speed in unit of RPM. + max_speed_in_rpm = read_int_from_file(self.fan_max_speed_path) + if max_speed_in_rpm == 0: return speed_in_rpm - max_speed_in_rpm = self._get_max_speed_in_rpm() speed = 100*speed_in_rpm/max_speed_in_rpm if speed > 100: speed = 100 @@ -192,18 +162,15 @@ def get_target_speed(self): int: percentage of the max fan speed """ if self.is_psu_fan: - # Not like system fan, psu fan speed can not be modified, so target speed is N/A - return self.get_speed() + try: + # Get PSU fan target speed according to current system cooling level + cooling_level = self.get_cooling_level() + return int(self.PSU_FAN_SPEED[cooling_level], 16) + except Exception: + return self.get_speed() - try: - with open(os.path.join(FAN_PATH, self.fan_speed_set_path), 'r') as fan_pwm: - pwm = int(fan_pwm.read().strip()) - except (ValueError, IOError): - pwm = 0 - - speed = int(round(pwm*100.0/PWM_MAX)) - - return speed + pwm = read_int_from_file(os.path.join(FAN_PATH, self.fan_speed_set_path)) + return int(round(pwm*100.0/PWM_MAX)) def set_speed(self, speed): @@ -224,12 +191,9 @@ def set_speed(self, speed): return False from .thermal import logger try: - with open(self.psu_i2c_bus_path, 'r') as f: - bus = f.read().strip() - with open(self.psu_i2c_addr_path, 'r') as f: - addr = f.read().strip() - with open(self.psu_i2c_command_path, 'r') as f: - command = f.read().strip() + bus = read_str_from_file(self.psu_i2c_bus_path, raise_exception=True) + addr = read_str_from_file(self.psu_i2c_addr_path, raise_exception=True) + command = read_str_from_file(self.psu_i2c_command_path, raise_exception=True) speed = Fan.PSU_FAN_SPEED[int(speed / 10)] command = "i2cset -f -y {0} {1} {2} {3} wp".format(bus, addr, command, speed) subprocess.check_call(command, shell = True) @@ -248,8 +212,7 @@ def set_speed(self, speed): speed = self.min_cooling_level * 10 self.set_cooling_level(cooling_level, cooling_level) pwm = int(round(PWM_MAX*speed/100.0)) - with open(os.path.join(FAN_PATH, self.fan_speed_set_path), 'w') as fan_pwm: - fan_pwm.write(str(pwm)) + write_file(os.path.join(FAN_PATH, self.fan_speed_set_path), pwm, raise_exception=True) except (ValueError, IOError): status = False @@ -311,21 +274,17 @@ def set_cooling_level(cls, level, cur_state): # Reset FAN cooling level vector. According to low level team, # if we need set cooling level to X, we need first write a (10+X) # to cooling_cur_state file to reset the cooling level vector. - with open(COOLING_STATE_PATH, 'w') as cooling_state: - cooling_state.write(str(level + 10)) + write_file(COOLING_STATE_PATH, level + 10, raise_exception=True) # We need set cooling level after resetting the cooling level vector - with open(COOLING_STATE_PATH, 'w') as cooling_state: - cooling_state.write(str(cur_state)) + write_file(COOLING_STATE_PATH, cur_state, raise_exception=True) except (ValueError, IOError) as e: raise RuntimeError("Failed to set cooling level - {}".format(e)) @classmethod def get_cooling_level(cls): try: - with open(COOLING_STATE_PATH, 'r') as cooling_state: - cooling_level = int(cooling_state.read().strip()) - return cooling_level + return read_int_from_file(COOLING_STATE_PATH, raise_exception=True) except (ValueError, IOError) as e: raise RuntimeError("Failed to get cooling level - {}".format(e)) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/utils.py b/platform/mellanox/mlnx-platform-api/sonic_platform/utils.py new file mode 100644 index 000000000000..d5175acf8d0e --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/utils.py @@ -0,0 +1,57 @@ +def read_str_from_file(file_path, default='', raise_exception=False): + """ + Read string content from file + :param file_path: File path + :param default: Default return value if any exception occur + :param raise_exception: Raise exception to caller if True else just return default value + :return: String content of the file + """ + try: + with open(file_path, 'r') as f: + value = f.read().strip() + except (ValueError, IOError) as e: + if not raise_exception: + value = default + else: + raise e + + return value + + +def read_int_from_file(file_path, default=0, raise_exception=False): + """ + Read content from file and cast it to integer + :param file_path: File path + :param default: Default return value if any exception occur + :param raise_exception: Raise exception to caller if True else just return default value + :return: Integer value of the file content + """ + try: + with open(file_path, 'r') as f: + value = int(f.read().strip()) + except (ValueError, IOError) as e: + if not raise_exception: + value = default + else: + raise e + + return value + + +def write_file(file_path, content, raise_exception=False): + """ + Write the given value to a file + :param file_path: File path + :param content: Value to write to the file + :param raise_exception: Raise exception to caller if True + :return: True if write success else False + """ + try: + with open(file_path, 'w') as f: + f.write(str(content)) + except (ValueError, IOError) as e: + if not raise_exception: + return False + else: + raise e + return True From 9e34003136730eac406d64c9995a92db6beef809 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 26 Oct 2020 13:48:50 -0700 Subject: [PATCH 1288/1427] [sonic-config-engine] Clean up dependencies, pin versions; install Python 3 package in Buster container (#5656) To clean up the image build procedure, and let setuptools/pip[3] implicitly install Python dependencies. Also use ipaddress package instead of ipaddr. --- .../docker-config-engine-buster/Dockerfile.j2 | 30 +++++---- .../Dockerfile.j2 | 11 +--- dockers/docker-config-engine/Dockerfile.j2 | 6 +- dockers/docker-orchagent/Dockerfile.j2 | 24 ++++--- .../docker-sonic-mgmt-framework/Dockerfile.j2 | 2 +- dockers/dockerfile-macros.j2 | 2 +- .../build_templates/sonic_debian_extension.j2 | 5 +- platform/vs/docker-sonic-vs/Dockerfile.j2 | 24 +++---- rules/docker-config-engine-buster.mk | 3 + rules/sonic-config.mk | 4 +- sonic-slave-buster/Dockerfile.j2 | 64 +++++++++++-------- sonic-slave-stretch/Dockerfile.j2 | 63 ++++++++++-------- src/sonic-bgpcfgd/setup.py | 44 ++++++++----- src/sonic-config-engine/minigraph.py | 24 ++++--- src/sonic-config-engine/setup.py | 50 ++++++++------- 15 files changed, 202 insertions(+), 154 deletions(-) diff --git a/dockers/docker-config-engine-buster/Dockerfile.j2 b/dockers/docker-config-engine-buster/Dockerfile.j2 index 93e1c98889f5..55156209f4b9 100644 --- a/dockers/docker-config-engine-buster/Dockerfile.j2 +++ b/dockers/docker-config-engine-buster/Dockerfile.j2 @@ -6,22 +6,25 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y \ - # Dependencies for sonic-cfggen - python-lxml \ - python-yaml \ - python-bitarray \ + build-essential \ python-pip \ + python3-pip \ python-dev \ + python3-dev \ apt-utils \ - python-setuptools + python-setuptools \ + python3-setuptools -RUN pip install --upgrade pip +RUN pip2 install --upgrade pip +RUN pip3 install --upgrade pip +RUN apt-get purge -y python-pip python3-pip -RUN pip install \ - netaddr \ - ipaddr \ - jinja2 \ - pyangbind==0.6.0 +# For sonic-config-engine Python 3 package +# Explicitly install pyangbind here, as pyangbind causes enum34 to be installed. +# enum34 causes Python 're' package to not work properly as it redefines an incompatible enum.py module +# https://github.com/robshakir/pyangbind/issues/232 +RUN pip3 install pyangbind==0.8.1 +RUN pip3 uninstall -y enum34 {% if docker_config_engine_buster_debs.strip() %} # Copy locally-built Debian package dependencies @@ -44,8 +47,9 @@ COPY ["files/swss_vars.j2", "/usr/share/sonic/templates/"] ## Clean up RUN apt-get purge -y \ - python-pip \ - python-dev && \ + python-dev \ + python3-dev \ + build-essential && \ apt-get clean -y && \ apt-get autoclean -y && \ apt-get autoremove -y && \ diff --git a/dockers/docker-config-engine-stretch/Dockerfile.j2 b/dockers/docker-config-engine-stretch/Dockerfile.j2 index 21c5e65b7712..8bc847d6fbf0 100644 --- a/dockers/docker-config-engine-stretch/Dockerfile.j2 +++ b/dockers/docker-config-engine-stretch/Dockerfile.j2 @@ -7,21 +7,13 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y \ # Dependencies for sonic-cfggen - python-lxml \ - python-yaml \ - python-bitarray \ + build-essential \ python-pip \ python-dev \ python-setuptools RUN pip install --upgrade pip -RUN pip install \ - netaddr \ - ipaddr \ - jinja2 \ - pyangbind==0.5.10 - {% if docker_config_engine_stretch_debs.strip() %} # Copy locally-built Debian package dependencies {{ copy_files("debs/", docker_config_engine_stretch_debs.split(' '), "/debs/") }} @@ -43,6 +35,7 @@ COPY ["files/swss_vars.j2", "/usr/share/sonic/templates/"] ## Clean up RUN apt-get purge -y \ + build-essential \ python-pip \ python-dev && \ apt-get clean -y && \ diff --git a/dockers/docker-config-engine/Dockerfile.j2 b/dockers/docker-config-engine/Dockerfile.j2 index 6e5a56dbdfb7..c5adf15cb764 100644 --- a/dockers/docker-config-engine/Dockerfile.j2 +++ b/dockers/docker-config-engine/Dockerfile.j2 @@ -6,11 +6,11 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update # Dependencies for sonic-cfggen -RUN apt-get install -y python-lxml python-yaml python-bitarray python-pip python-dev +RUN apt-get install -y build-essential python-pip python-dev RUN pip install --upgrade pip -RUN pip install netaddr ipaddr jinja2 pyangbind==0.5.10 +RUN apt-get purge -y python-pip {% if docker_config_engine_debs.strip() %} COPY \ @@ -46,5 +46,5 @@ python-wheels/{{ whl }}{{' '}} COPY ["files/swss_vars.j2", "/usr/share/sonic/templates/"] ## Clean up -RUN apt-get purge -y python-pip python-dev; apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN apt-get purge -y build-essential python-dev; apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs /python-wheels diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 097a582f6337..5af76e3c600f 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -4,7 +4,7 @@ FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf -## Make apt-get non-interactive +# Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ @@ -18,10 +18,14 @@ RUN apt-get update && \ libmnl0 \ bridge-utils \ conntrack \ - ndppd + ndppd \ + # Needed for installing netifaces Python package + build-essential \ + python-dev \ + python3-dev {% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %} -## Fix for gcc/python not found in arm docker +# Fix for gcc/python not found in arm docker RUN apt-get install -f -y python2.7 python2.7-dev RUN apt-get install -y gcc-6 {% endif %} @@ -53,10 +57,14 @@ RUN apt-get remove -y gcc-6 {{ install_debian_packages(docker_orchagent_debs.split(' ')) }} {%- endif %} -## Clean up -RUN apt-get clean -y && \ - apt-get autoclean -y && \ - apt-get autoremove -y && \ +# Clean up +RUN apt-get purge -y \ + build-essential \ + python-dev \ + python3-dev && \ + apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ rm -rf /debs COPY ["files/arp_update", "/usr/bin"] @@ -68,7 +76,7 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor/"] -## Copy all Jinja2 template files into the templates folder +# Copy all Jinja2 template files into the templates folder COPY ["*.j2", "/usr/share/sonic/templates/"] ENTRYPOINT ["/usr/bin/docker-init.sh"] diff --git a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 index dd396994d9f4..24ae3643b36e 100644 --- a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 @@ -7,7 +7,7 @@ RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%s ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ - apt-get install -y g++ python-dev + apt-get install -y g++ python-dev libxml2 RUN pip install connexion==1.1.15 \ setuptools==21.0.0 \ diff --git a/dockers/dockerfile-macros.j2 b/dockers/dockerfile-macros.j2 index 5952d59f566f..9917cb17aba2 100644 --- a/dockers/dockerfile-macros.j2 +++ b/dockers/dockerfile-macros.j2 @@ -6,7 +6,7 @@ RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return {%- endmacro %} {% macro install_python2_wheels(packages) -%} -RUN cd /python-wheels/ && pip install {{ packages | join(' ') }} +RUN cd /python-wheels/ && pip2 install {{ packages | join(' ') }} {%- endmacro %} {% macro install_python3_wheels(packages) -%} diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 70b8b08a99c9..8a8334b79cac 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -93,10 +93,7 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/iptables_*.deb || \ # Install dependencies for SONiC config engine sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ python-dev \ - python3-dev \ - python-lxml \ - python-yaml \ - python-bitarray + python3-dev # Install Python client for Redis sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install "redis==3.5.3" diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 3c9208756dcb..f254951d311b 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -61,20 +61,20 @@ RUN curl -o redis-server_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.co RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb -RUN pip install setuptools +RUN pip2 install setuptools RUN pip3 install setuptools -RUN pip install py2_ipaddress -RUN pip install six -RUN pip install pyroute2==0.5.3 netifaces==0.10.7 -RUN pip install monotonic==1.5 -RUN pip install urllib3 -RUN pip install requests -RUN pip install crontab +RUN pip2 install py2_ipaddress +RUN pip2 install six +RUN pip2 install pyroute2==0.5.3 netifaces==0.10.7 +RUN pip2 install monotonic==1.5 +RUN pip2 install urllib3 +RUN pip2 install requests +RUN pip2 install crontab # Install dependencies for Dynamic Port Breakout -RUN pip install xmltodict==0.12.0 -RUN pip install jsondiff==1.2.0 -RUN pip install ijson==2.6.1 +RUN pip2 install xmltodict==0.12.0 +RUN pip2 install jsondiff==1.2.0 +RUN pip2 install ijson==2.6.1 {% if docker_sonic_vs_debs.strip() -%} # Copy locally-built Debian package dependencies @@ -109,7 +109,7 @@ COPY python-wheels/{{ whl }} python-wheels/ # install PKGs after copying all PKGs to avoid dependency failure # use py3 to find python3 package, which is forced by wheel as of now {%- for whl in docker_sonic_vs_whls.split(' ') %} -RUN pip{% if 'py3' in whl %}3{% endif %} install python-wheels/{{ whl }} +RUN pip{% if 'py3' in whl %}3{% else %}2{% endif %} install python-wheels/{{ whl }} {%- endfor %} {% endif %} diff --git a/rules/docker-config-engine-buster.mk b/rules/docker-config-engine-buster.mk index f1c54f10b627..9a98647a077c 100644 --- a/rules/docker-config-engine-buster.mk +++ b/rules/docker-config-engine-buster.mk @@ -4,8 +4,11 @@ DOCKER_CONFIG_ENGINE_BUSTER = docker-config-engine-buster.gz $(DOCKER_CONFIG_ENGINE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-config-engine-buster $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SWSSSDK_PY2) +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SWSSSDK_PY3) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY3) $(DOCKER_CONFIG_ENGINE_BUSTER)_LOAD_DOCKERS += $(DOCKER_BASE_BUSTER) $(DOCKER_CONFIG_ENGINE_BUSTER)_FILES += $(SWSS_VARS_TEMPLATE) diff --git a/rules/sonic-config.mk b/rules/sonic-config.mk index f7ff06286455..996e311b5fee 100644 --- a/rules/sonic-config.mk +++ b/rules/sonic-config.mk @@ -6,11 +6,13 @@ $(SONIC_CONFIG_ENGINE_PY2)_DEPENDS += $(SWSSSDK_PY2) $(SONIC_PY_COMMON_PY2) $(SONIC_CONFIG_ENGINE_PY2)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) - # SONIC_CONFIG_ENGINE_PY3 package SONIC_CONFIG_ENGINE_PY3 = sonic_config_engine-1.0-py3-none-any.whl $(SONIC_CONFIG_ENGINE_PY3)_SRC_PATH = $(SRC_PATH)/sonic-config-engine $(SONIC_CONFIG_ENGINE_PY3)_DEPENDS += $(SWSSSDK_PY3) $(SONIC_PY_COMMON_PY3) +# Synthetic dependency to avoid building the Python 2 and 3 packages +# simultaneously and any potential conflicts which may arise +$(SONIC_CONFIG_ENGINE_PY3)_DEPENDS += $(SONIC_CONFIG_ENGINE_PY2) $(SONIC_CONFIG_ENGINE_PY3)_PYTHON_VERSION = 3 SONIC_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY3) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 6b6902153bef..ce406cd70744 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -57,10 +57,10 @@ RUN apt-get update && apt-get install -y \ libtinyxml2-dev \ python \ python-pip \ + python3-pip \ libncurses5-dev \ texinfo \ dh-autoreconf \ - python3-pip \ doxygen \ devscripts \ git-buildpackage \ @@ -245,13 +245,6 @@ RUN apt-get update && apt-get install -y \ python3-sphinx \ # For sonic config engine testing python-dev \ - python-lxml \ - python3-lxml \ - python-jinja2 \ - python-netaddr \ - python-ipaddr \ - python-yaml \ - python3-yaml \ # For lockfile procmail \ # For gtest @@ -305,7 +298,14 @@ RUN apt-get update && apt-get install -y \ # For SWI Tools python-m2crypto \ # For build dtb - device-tree-compiler + device-tree-compiler \ +# For sonic-mgmt-framework + autoconf \ + m4 \ + libxml2-utils \ + xsltproc \ + python-lxml \ + libexpat1-dev ## Config dpkg ## install the configuration file if it’s currently missing @@ -334,29 +334,33 @@ RUN export VERSION=1.14.2 \ && echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/bash.bashrc \ && rm go$VERSION.linux-*.tar.gz +RUN pip2 install --upgrade pip +RUN pip3 install --upgrade pip +RUN apt-get purge -y python-pip python3-pip + # For building Python packages -RUN pip install setuptools==40.8.0 +RUN pip2 install setuptools==40.8.0 RUN pip3 install setuptools==49.6.00 # For building sonic-utilities -RUN pip install fastentrypoints +RUN pip2 install fastentrypoints RUN pip3 install fastentrypoints # For running Python unit tests -RUN pip install pytest-runner==4.4 +RUN pip2 install pytest-runner==4.4 RUN pip3 install pytest-runner==5.2 -RUN pip install mockredispy==2.9.3 +RUN pip2 install mockredispy==2.9.3 RUN pip3 install mockredispy==2.9.3 # For Python 2 unit tests, we need 'mock'. The last version of 'mock' # which supports Python 2 is 3.0.5. In Python 3, 'mock' is part of 'unittest' # in the standard library -RUN pip install mock==3.0.5 +RUN pip2 install mock==3.0.5 # For p4 build -RUN pip install \ - ctypesgen==1.0.2 \ - crc16 +RUN pip2 install \ + ctypesgen==1.0.2 \ + crc16 # For sonic config engine testing # Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed. @@ -366,31 +370,35 @@ RUN pip3 install pyangbind==0.8.1 RUN pip3 uninstall -y enum34 # For templating -RUN pip install j2cli==0.3.10 +RUN pip2 install j2cli==0.3.10 -RUN pip3 install "PyYAML>=5.1" +# For sonic-mgmt-framework +RUN pip2 install "PyYAML==5.3.1" +RUN pip3 install "PyYAML==5.3.1" +RUN pip2 install "lxml==4.6.1" +RUN pip3 install "lxml==4.6.1" # For sonic-platform-common testing RUN pip3 install redis # For supervisor build -RUN pip install meld3 +RUN apt-get install python-meld3 # For vs image build -RUN pip install pexpect==4.6.0 +RUN pip2 install pexpect==4.6.0 # For sonic-swss-common testing -RUN pip install Pympler==0.8 +RUN pip2 install Pympler==0.8 # For sonic_yang_mgmt build -RUN pip install ijson==2.6.1 +RUN pip2 install ijson==2.6.1 RUN pip3 install ijson==2.6.1 -RUN pip install jsondiff==1.2.0 -RUN pip install xmltodict==0.12.0 -RUN pip install pyang==2.1.1 +RUN pip2 install jsondiff==1.2.0 +RUN pip2 install xmltodict==0.12.0 +RUN pip2 install pyang==2.1.1 # For mgmt-framework build -RUN pip install mmh3 +RUN pip2 install mmh3 RUN apt-get install -y xsltproc # Install dependencies for isc-dhcp-relay build @@ -434,4 +442,4 @@ RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/d RUN update-alternatives --set iptables /usr/sbin/iptables-legacy # Install swi tools -RUN python -m pip install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 +RUN pip2 install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 00935b33f18d..3f455bdd7bc6 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -57,10 +57,10 @@ RUN apt-get update && apt-get install -y \ libtinyxml2-dev \ python \ python-pip \ + python3-pip \ libncurses5-dev \ texinfo \ dh-autoreconf \ - python3-pip \ doxygen \ devscripts \ git-buildpackage \ @@ -244,13 +244,6 @@ RUN apt-get update && apt-get install -y \ python3-sphinx \ # For sonic config engine testing python-dev \ - python-lxml \ - python3-lxml \ - python-jinja2 \ - python-netaddr \ - python-ipaddr \ - python-yaml \ - python3-yaml \ # For lockfile procmail \ # For pam_tacplus build @@ -298,7 +291,14 @@ RUN apt-get update && apt-get install -y \ # For libyang swig \ # For SWI Tools - python-m2crypto + python-m2crypto \ +# For sonic-mgmt-framework + autoconf \ + m4 \ + libxml2-utils \ + xsltproc \ + python-lxml \ + libexpat1-dev ## Config dpkg ## install the configuration file if it’s currently missing @@ -330,13 +330,17 @@ RUN export VERSION=1.14.2 \ && echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/bash.bashrc \ && rm go$VERSION.linux-*.tar.gz +RUN pip2 install --upgrade pip +RUN pip3 install --upgrade pip +RUN apt-get purge -y python-pip python3-pip + # For p4 build -RUN pip install \ - ctypesgen==0.r125 \ - crc16 +RUN pip2 install \ + ctypesgen==0.r125 \ + crc16 # Note: Stick with Jinja2 2.x branch as the 3.x dropped support for Python 2.7 -RUN pip install --force-reinstall --upgrade "Jinja2<3.0.0" +RUN pip2 install --force-reinstall --upgrade "Jinja2<3.0.0" # For sonic config engine testing # Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed. @@ -346,39 +350,44 @@ RUN pip3 install pyangbind==0.8.1 RUN pip3 uninstall -y enum34 # For templating -RUN pip install j2cli==0.3.10 +RUN pip2 install j2cli==0.3.10 # For sonic snmpagent mock testing RUN pip3 install mockredispy==2.9.3 -RUN pip3 install "PyYAML>=5.1" +# For sonic-mgmt-framework +RUN pip2 install "PyYAML==5.3.1" +RUN pip3 install "PyYAML==5.3.1" +RUN pip2 install "lxml==4.6.1" +RUN pip3 install "lxml==4.6.1" + # For sonic-platform-common testing RUN pip3 install redis # For supervisor build -RUN pip install meld3 mock +RUN pip2 install meld3 mock # For vs image build -RUN pip install pexpect==4.6.0 +RUN pip2 install pexpect==4.6.0 # For sonic-utilities build -RUN pip install mockredispy==2.9.3 -RUN pip install pytest-runner==4.4 -RUN pip install setuptools==40.8.0 +RUN pip2 install mockredispy==2.9.3 +RUN pip2 install pytest-runner==4.4 +RUN pip2 install setuptools==40.8.0 # For sonic-swss-common testing -RUN pip install Pympler==0.8 +RUN pip2 install Pympler==0.8 # For sonic_yang_mgmt build -RUN pip install ijson==2.6.1 +RUN pip2 install ijson==2.6.1 RUN pip3 install ijson==2.6.1 -RUN pip install jsondiff==1.2.0 -RUN pip install xmltodict==0.12.0 -RUN pip install pyang==2.1.1 +RUN pip2 install jsondiff==1.2.0 +RUN pip2 install xmltodict==0.12.0 +RUN pip2 install pyang==2.1.1 # For mgmt-framework build -RUN pip install mmh3 +RUN pip2 install mmh3 # Install dependencies for isc-dhcp-relay build RUN apt-get -y build-dep isc-dhcp @@ -437,4 +446,4 @@ RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker # Install swi tools -RUN python -m pip install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 +RUN pip2 install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index 1e23802d98c1..5b18bb2ba256 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -2,20 +2,32 @@ import setuptools -setuptools.setup(name='sonic-bgpcfgd', - version='1.0', - description='Utility to dynamically generate BGP configuration for FRR', - author='Pavel Shirshov', - author_email='pavelsh@microsoft.com', - url='https://github.com/Azure/sonic-buildimage', - packages=setuptools.find_packages(), - entry_points={ - 'console_scripts': [ - 'bgpcfgd = bgpcfgd.main:main', - 'bgpmon = bgpmon.bgpmon:main', - ] - }, - install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], - setup_requires=['pytest-runner'], - tests_require=['pytest', 'pytest-cov'], +setuptools.setup( + name = 'sonic-bgpcfgd', + version = '1.0', + description = 'Utility to dynamically generate BGP configuration for FRR', + author = 'Pavel Shirshov', + author_email = 'pavelsh@microsoft.com', + url = 'https://github.com/Azure/sonic-buildimage', + packages = setuptools.find_packages(), + entry_points = { + 'console_scripts': [ + 'bgpcfgd = bgpcfgd.main:main', + 'bgpmon = bgpmon.bgpmon:main', + ] + }, + install_requires = [ + 'jinja2>=2.10', + 'netaddr==0.8.0', + 'pyyaml==5.3.1', + 'zipp==1.2.0', # importlib-resources needs zipp and seems to have a bug where it will try to import too new of a version for Python 2 + ], + setup_requires = [ + 'pytest-runner', + 'wheel' + ], + tests_require = [ + 'pytest', + 'pytest-cov' + ] ) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 294fb7faaaca..c4e8a6ae21ad 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -8,7 +8,7 @@ import struct import json import copy -import ipaddr as ipaddress +import ipaddress from collections import defaultdict from lxml import etree as ET @@ -18,6 +18,12 @@ from sonic_py_common.multi_asic import get_asic_id_from_name from sonic_py_common.interface import backplane_prefix +# TODO: Remove this once we no longer support Python 2 +if sys.version_info.major == 3: + UNICODE_TYPE = str +else: + UNICODE_TYPE = unicode + """minigraph.py version_added: "1.9" author: Guohan Lu (gulv@microsoft.com) @@ -323,8 +329,8 @@ def parse_dpg(dpg, hname): for mgmtintf in mgmtintfs.findall(str(QName(ns1, "ManagementIPInterface"))): intfname = mgmtintf.find(str(QName(ns, "AttachTo"))).text ipprefix = mgmtintf.find(str(QName(ns1, "PrefixStr"))).text - mgmtipn = ipaddress.IPNetwork(ipprefix) - gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1) + mgmtipn = ipaddress.ip_network(UNICODE_TYPE(ipprefix), False) + gwaddr = ipaddress.ip_address(next(mgmtipn.hosts())) mgmt_intf[(intfname, ipprefix)] = {'gwaddr': gwaddr} pcintfs = child.find(str(QName(ns, "PortChannelInterfaces"))) @@ -665,9 +671,9 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m # Vxlan tunnel information lo_addr = '0.0.0.0' for lo in lo_intfs: - lo_network = ipaddress.IPNetwork(lo[1]) + lo_network = ipaddress.ip_network(UNICODE_TYPE(lo[1]), False) if lo_network.version == 4: - lo_addr = str(lo_network.ip) + lo_addr = str(lo_network.network_address) break results['VXLAN_TUNNEL'] = {chassis_vxlan_tunnel: { 'src_ip': lo_addr @@ -1174,9 +1180,9 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw # if erspan_dst: # lo_addr = '0.0.0.0' # for lo in lo_intfs: - # lo_network = ipaddress.IPNetwork(lo[1]) + # lo_network = ipaddress.ip_network(UNICODE_TYPE(lo[1]), False) # if lo_network.version == 4: - # lo_addr = str(lo_network.ip) + # lo_addr = str(lo_network.network_address) # break # count = 0 # for dst in erspan_dst: @@ -1204,8 +1210,8 @@ def parse_device_desc_xml(filename): results['LOOPBACK_INTERFACE'] = {('lo', lo_prefix): {}} mgmt_intf = {} - mgmtipn = ipaddress.IPNetwork(mgmt_prefix) - gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1) + mgmtipn = ipaddress.ip_network(UNICODE_TYPE(mgmt_prefix), False) + gwaddr = ipaddress.ip_address((next(mgmtipn.hosts()))) results['MGMT_INTERFACE'] = {('eth0', mgmt_prefix): {'gwaddr': gwaddr}} return results diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py index e1940d4c0683..7e7b9b455190 100755 --- a/src/sonic-config-engine/setup.py +++ b/src/sonic-config-engine/setup.py @@ -1,32 +1,38 @@ import glob +import sys from setuptools import setup -from tests.common_utils import PY3x - +# Common dependencies for Python 2 and 3 dependencies = [ -# Python 2 or 3 dependencies + 'bitarray==1.5.3', + 'ipaddress==1.0.23', + 'lxml==4.6.1', + 'netaddr==0.8.0', + 'pyyaml==5.3.1', + 'sonic-py-common', +] + +if sys.version_info.major == 3: + # Python 3-only dependencies + dependencies += [ + # pyangbind v0.8.1 pull down enum43 which causes 're' package to malfunction. + # Python3 has enum module and so pyangbind should be installed outside + # dependencies section of setuptools followed by uninstall of enum43 + # 'pyangbind==0.8.1', + 'Jinja2>=2.10' + ] +else: + # Python 2-only dependencies + dependencies += [ + # Jinja2 v3.0.0+ dropped support for Python 2.7 and causes setuptools to + # malfunction on stretch slave docker. 'future', - 'ipaddr', - 'lxml', - 'netaddr', - 'pyyaml', - 'sonic-py-common', - ] + ([ -# Python 3 dependencies -# pyangbind v0.8.1 pull down enum43 which causes 're' package to malfunction. -# Python3 has enum module and so pyangbind should be installed outside -# dependencies section of setuptools followed by uninstall of enum43 -# 'pyangbind==0.8.1', - 'Jinja2>=2.10', - ] if PY3x - else [ -# Python 2 dependencies -# Jinja2 v3.0.0+ dropped support for Python 2.7 and causes setuptools to -# malfunction on stretch slave docker. 'Jinja2<3.0.0', 'pyangbind==0.6.0', - ]) + 'zipp==1.2.0', # importlib-resources needs zipp and seems to have a bug where it will try to install too new of a version for Python 2 + ] + setup( name = 'sonic-config-engine', @@ -52,6 +58,7 @@ ], setup_requires= [ 'pytest-runner', + 'wheel' ], tests_require=[ 'pytest', @@ -69,4 +76,3 @@ ], keywords = 'SONiC sonic-cfggen config-engine PYTHON python' ) - From 36c52cca2bb56f4107a5234ba190031b906c593e Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Tue, 27 Oct 2020 09:25:35 +0800 Subject: [PATCH 1289/1427] Fix 'NoSuchProcess' exception in process_checker (#5716) The psutil library used in process_checker create a cache for each process when calling process_iter. So, there is some possibility that one process exists when calling process_iter, but not exists when calling cmdline, which will raise a NoSuchProcess exception. This commit fix the issue. Signed-off-by: bingwang --- files/image_config/monit/process_checker | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/files/image_config/monit/process_checker b/files/image_config/monit/process_checker index ba48e37729aa..e2846fae9f93 100755 --- a/files/image_config/monit/process_checker +++ b/files/image_config/monit/process_checker @@ -28,9 +28,12 @@ def check_process_existence(container_name, process_cmdline): # state, then it will be marked as 'running'. is_running = False for process in psutil.process_iter(["cmdline", "status"]): - if ((' '.join(process.cmdline())).startswith(process_cmdline) and process.status() in ["running", "sleeping"]): - is_running = True - break + try: + if ((' '.join(process.cmdline())).startswith(process_cmdline) and process.status() in ["running", "sleeping"]): + is_running = True + break + except psutil.NoSuchProcess: + pass if not is_running: # If this script is run by Monit, then the following output will be appended to From dfe005545a1b950a0c94519409cc1fdff24f648b Mon Sep 17 00:00:00 2001 From: vdahiya12 <67608553+vdahiya12@users.noreply.github.com> Date: Tue, 27 Oct 2020 09:36:26 -0700 Subject: [PATCH 1290/1427] [sonic-platform-common] update submodule (#5721) a659219 [SONIC_SFP] adding abstract methods for reading and writing the eeprom address space within platform api (#126) 848f4a6 Add third-party licenses (#138) c2ecd9a Add license file (#137) 403747a [sonic-platform-common] Add new platform API for SONiC Physical MIB Extension feature (#134) 19b8545 [sonic_y_cable] fix the unpacking (#135) Signed-off-by: vaibhav-dahiya --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index b316f8df1ee2..a6592194557b 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit b316f8df1ee25937dc22b143f4b3b04de72e98dd +Subproject commit a6592194557bf1ec97dd77f8f90090642f505344 From 07748a939fe1359fa889053c4adc637d8e6dbf26 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 27 Oct 2020 11:40:23 -0700 Subject: [PATCH 1291/1427] [gbsyncd]: add gbsyncd to FEATURE table (#5683) remove syncd from critical process list because gbsyncd process will exit for platform without gearbox. closes #5623 Signed-off-by: Guohan Lu --- files/build_templates/init_cfg.json.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 07ff9b1b3a72..164f8a43649b 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -26,6 +26,7 @@ ("snmp", "enabled", true, "enabled"), ("swss", "enabled", false, "enabled"), ("syncd", "enabled", false, "enabled"), + ("gbsyncd", "enabled", false, "enabled"), ("teamd", "enabled", false, "enabled")] %} {%- if include_iccpd == "y" %}{% do features.append(("iccpd", "disabled", false, "enabled")) %}{% endif %} {%- if include_mgmt_framework == "y" %}{% do features.append(("mgmt-framework", "enabled", true, "enabled")) %}{% endif %} From e0b09d09987a192beb2f6b70581bdebc0ce866f2 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Tue, 27 Oct 2020 14:38:43 -0700 Subject: [PATCH 1292/1427] [swss] Update swss submodule (#5719) Signed-off-by: Danny Allen --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 7c2f2188c081..495816da3fe6 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 7c2f2188c081ef184cf992b510bf3b1f6466e016 +Subproject commit 495816da3fe6d1690e76ea49d53df8d9e43cc07d From a639021af299ae57ae322a5a99c0d2863c566feb Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Tue, 27 Oct 2020 17:20:55 -0700 Subject: [PATCH 1293/1427] [minigraph.py]: Parse VLAN MAC address from minigraph when present (#5726) --- src/sonic-config-engine/minigraph.py | 4 ++++ src/sonic-config-engine/tests/simple-sample-graph-case.xml | 1 + src/sonic-config-engine/tests/test_minigraph_case.py | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index c4e8a6ae21ad..3d3bf72463f0 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -383,6 +383,10 @@ def parse_dpg(dpg, hname): vdhcpserver_list = vintfdhcpservers.split(';') vlan_attributes['dhcp_servers'] = vdhcpserver_list + vlanmac = vintf.find(str(QName(ns, "MacAddress"))) + if vlanmac != None: + vlan_attributes['mac'] = vlanmac.text + sonic_vlan_name = "Vlan%s" % vlanid if sonic_vlan_name != vintfname: vlan_attributes['alias'] = vintfname diff --git a/src/sonic-config-engine/tests/simple-sample-graph-case.xml b/src/sonic-config-engine/tests/simple-sample-graph-case.xml index 3188409b1fd0..6c7729fd0696 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-case.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-case.xml @@ -134,6 +134,7 @@ 1000 1000 192.168.0.0/27 + 00:aa:bb:cc:dd:ee diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 42e5e63ac6d6..e149ff64670b 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -83,7 +83,7 @@ def test_minigraph_vlans(self): output = self.run_script(argument) self.assertEqual( utils.to_dict(output.strip()), - utils.to_dict("{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}}") + utils.to_dict("{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000', 'mac': '00:aa:bb:cc:dd:ee' }}") ) def test_minigraph_vlan_members(self): From 09d5a62fad22313b29afe1419d329abe45fbef6d Mon Sep 17 00:00:00 2001 From: Shi Su <67605788+shi-su@users.noreply.github.com> Date: Tue, 27 Oct 2020 20:42:57 -0700 Subject: [PATCH 1294/1427] [sonic-sairedis] Update submodule (#5728) Update the sonic-sairedis submodule. The following are the commits in the submodule. [syncd_init_common.sh] Use template file to retrieve vars (#683) 0bf336a3e895167357d5d2e5a988471e115522e8 [syncd/FlexCounter]:Fix last remove bug (#679) 4d21a264d5956501bf69ad3a89ea2ebccd369654 --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index bc3e044cefc5..0bf336a3e895 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit bc3e044cefc560e06d4c27576957b25b626d573b +Subproject commit 0bf336a3e895167357d5d2e5a988471e115522e8 From 6088bd59ded064f392b7618872e1306057b955e1 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:41:27 -0700 Subject: [PATCH 1295/1427] [multi-ASIC] BGP internal neighbor table support (#5520) * Initial commit for BGP internal neighbor table support. > Add new template named "internal" for the internal BGP sessions > Add a new table in database "BGP_INTERNAL_NEIGHBOR" > The internal BGP sessions will be stored in this new table "BGP_INTERNAL_NEIGHBOR" * Changes in template generation tests with the introduction of internal neighbor template files. --- .../bgpd/templates/general/instance.conf.j2 | 19 ---- .../bgpd/templates/general/peer-group.conf.j2 | 16 ---- .../bgpd/templates/general/policies.conf.j2 | 11 --- .../bgpd/templates/internal/instance.conf.j2 | 34 ++++++++ .../templates/internal/peer-group.conf.j2 | 24 +++++ .../bgpd/templates/internal/policies.conf.j2 | 27 ++++++ files/image_config/constants/constants.yml | 3 + src/sonic-bgpcfgd/bgpcfgd/main.py | 3 +- .../general/instance.conf/param_ASIC_v6.json | 15 ---- .../general/instance.conf/param_all_v4.json | 5 -- .../general/instance.conf/param_all_v6.json | 5 -- .../general/instance.conf/result_ASIC_v6.conf | 13 --- .../general/instance.conf/result_all_v4.conf | 1 - .../general/instance.conf/result_all_v6.conf | 1 - .../general/peer-group.conf/param_base.json | 3 +- .../general/peer-group.conf/result_all.conf | 10 --- .../general/peer-group.conf/result_base.conf | 10 --- .../data/general/policies.conf/param_all.json | 5 -- .../general/policies.conf/param_base.json | 5 -- .../general/policies.conf/param_deny.json | 5 -- .../general/policies.conf/result_all.conf | 9 -- .../general/policies.conf/result_deny.conf | 9 -- .../internal/instance.conf/param_back_v4.json | 23 +++++ .../internal/instance.conf/param_back_v6.json | 23 +++++ .../instance.conf/param_front_v4.json} | 10 ++- .../instance.conf/param_front_v6.json | 21 +++++ .../instance.conf/result_back_v4.conf | 17 ++++ .../instance.conf/result_back_v6.conf | 17 ++++ .../instance.conf/result_front_v4.conf} | 6 +- .../instance.conf/result_front_v6.conf | 15 ++++ .../internal/peer-group.conf/param_back.json | 8 ++ .../internal/peer-group.conf/param_front.json | 8 ++ .../internal/peer-group.conf/result_back.conf | 20 +++++ .../peer-group.conf/result_front.conf | 18 ++++ .../internal/policies.conf/param_back.json | 8 ++ .../internal/policies.conf/param_front.json | 8 ++ .../internal/policies.conf/result_back.conf | 22 +++++ .../internal/policies.conf/result_front.conf | 16 ++++ src/sonic-config-engine/minigraph.py | 87 ++++++++++++++----- .../tests/test_multinpu_cfggen.py | 17 ++-- 40 files changed, 404 insertions(+), 173 deletions(-) create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/internal/peer-group.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/internal/policies.conf.j2 delete mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v6.json delete mode 100644 src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v6.conf create mode 100644 src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v4.json create mode 100644 src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v6.json rename src/sonic-bgpcfgd/tests/data/{general/instance.conf/param_ASIC_v4.json => internal/instance.conf/param_front_v4.json} (51%) create mode 100644 src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v6.json create mode 100644 src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf create mode 100644 src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf rename src/sonic-bgpcfgd/tests/data/{general/instance.conf/result_ASIC_v4.conf => internal/instance.conf/result_front_v4.conf} (62%) create mode 100644 src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf create mode 100644 src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_back.json create mode 100644 src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_front.json create mode 100644 src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_back.conf create mode 100644 src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_front.conf create mode 100644 src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_back.json create mode 100644 src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_front.json create mode 100644 src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_back.conf create mode 100644 src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_front.conf diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 index e4422a771664..37b91d3a2d76 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 @@ -15,27 +15,12 @@ ! {% if neighbor_addr | ipv4 %} address-family ipv4 -{% if 'ASIC' in bgp_session['name'] %} - neighbor {{ neighbor_addr }} peer-group PEER_V4_INT -{% else %} neighbor {{ neighbor_addr }} peer-group PEER_V4 -{% endif %} -! -{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} - neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V4_INT in -{% endif %} ! {% elif neighbor_addr | ipv6 %} address-family ipv6 -{% if 'ASIC' in bgp_session['name'] %} - neighbor {{ neighbor_addr }} peer-group PEER_V6_INT -{% else %} neighbor {{ neighbor_addr }} peer-group PEER_V6 -{% endif %} ! -{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} - neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V6_INT in -{% endif %} {% endif %} ! {% if bgp_session.has_key('rrclient') and bgp_session['rrclient'] | int != 0 %} @@ -45,10 +30,6 @@ {% if bgp_session.has_key('nhopself') and bgp_session['nhopself'] | int != 0 %} neighbor {{ neighbor_addr }} next-hop-self {% endif %} -! -{% if 'ASIC' in bgp_session['name'] %} - neighbor {{ neighbor_addr }} next-hop-self force -{% endif %} ! neighbor {{ neighbor_addr }} activate exit-address-family diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 index 111b5ceb5f9f..2617cc94c2d2 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -2,46 +2,30 @@ ! template: bgpd/templates/general/peer-group.conf.j2 ! neighbor PEER_V4 peer-group - neighbor PEER_V4_INT peer-group neighbor PEER_V6 peer-group - neighbor PEER_V6_INT peer-group address-family ipv4 {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V4 allowas-in 1 - neighbor PEER_V4_INT allowas-in 1 {% elif CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'LeafRouter' %} {% if CONFIG_DB__BGP_BBR['status'] == 'enabled' %} neighbor PEER_V4 allowas-in 1 {% endif %} -{% endif %} -{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} - neighbor PEER_V4_INT route-reflector-client {% endif %} neighbor PEER_V4 soft-reconfiguration inbound neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - neighbor PEER_V4_INT soft-reconfiguration inbound - neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in - neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out exit-address-family address-family ipv6 {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V6 allowas-in 1 - neighbor PEER_V6_INT allowas-in 1 {% elif CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'LeafRouter' %} {% if CONFIG_DB__BGP_BBR['status'] == 'enabled' %} neighbor PEER_V6 allowas-in 1 {% endif %} -{% endif %} -{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} - neighbor PEER_V6_INT route-reflector-client {% endif %} neighbor PEER_V6 soft-reconfiguration inbound neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - neighbor PEER_V6_INT soft-reconfiguration inbound - neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in - neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out exit-address-family ! ! end of template: bgpd/templates/general/peer-group.conf.j2 diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 index 4c27db4a466a..04dbc3bc490e 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -42,16 +42,5 @@ route-map FROM_BGP_PEER_V6 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! -{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} -route-map FROM_BGP_PEER_V4_INT permit 2 - set originator-id {{ loopback0_ipv4 | ip }} -! -route-map FROM_BGP_PEER_V6_INT permit 1 - set ipv6 next-hop prefer-global -! -route-map FROM_BGP_PEER_V6_INT permit 2 - set originator-id {{ loopback0_ipv4 | ip }} -{% endif %} -! ! end of template: bgpd/templates/general/policies.conf.j2 ! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 new file mode 100644 index 000000000000..49497e4fcaaa --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 @@ -0,0 +1,34 @@ +! +! template: bgpd/templates/internal/instance.conf.j2 +! + neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} +! +{% if neighbor_addr | ipv4 %} + address-family ipv4 + neighbor {{ neighbor_addr }} peer-group INTERNAL_PEER_V4 +! +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor {{ neighbor_addr }} route-map FROM_BGP_INTERNAL_PEER_V4 in +{% endif %} +! +{% elif neighbor_addr | ipv6 %} + address-family ipv6 + neighbor {{ neighbor_addr }} peer-group INTERNAL_PEER_V6 +! +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor {{ neighbor_addr }} route-map FROM_BGP_INTERNAL_PEER_V6 in +{% endif %} +{% endif %} +! +{% if bgp_session.has_key('rrclient') and bgp_session['rrclient'] | int != 0 %} + neighbor {{ neighbor_addr }} route-reflector-client +{% endif %} +! + neighbor {{ neighbor_addr }} next-hop-self force +! + neighbor {{ neighbor_addr }} activate + exit-address-family +! +! end of template: bgpd/templates/internal/instance.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/peer-group.conf.j2 new file mode 100644 index 000000000000..323c13447ed0 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/peer-group.conf.j2 @@ -0,0 +1,24 @@ +! +! template: bgpd/templates/internal/peer-group.conf.j2 +! + neighbor INTERNAL_PEER_V4 peer-group + neighbor INTERNAL_PEER_V6 peer-group + address-family ipv4 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor INTERNAL_PEER_V4 route-reflector-client +{% endif %} + neighbor INTERNAL_PEER_V4 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V4 route-map FROM_BGP_INTERNAL_PEER_V4 in + neighbor INTERNAL_PEER_V4 route-map TO_BGP_INTERNAL_PEER_V4 out + exit-address-family + address-family ipv6 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor INTERNAL_PEER_V6 route-reflector-client +{% endif %} + neighbor INTERNAL_PEER_V6 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V6 route-map FROM_BGP_INTERNAL_PEER_V6 in + neighbor INTERNAL_PEER_V6 route-map TO_BGP_INTERNAL_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/internal/peer-group.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/policies.conf.j2 new file mode 100644 index 000000000000..d4db3a97d5fc --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/policies.conf.j2 @@ -0,0 +1,27 @@ +! +! template: bgpd/templates/internal/policies.conf.j2 +! +! +! +route-map FROM_BGP_INTERNAL_PEER_V4 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V4 permit 100 +! +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V6 permit 100 +! +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} +route-map FROM_BGP_INTERNAL_PEER_V4 permit 2 + set originator-id {{ loopback0_ipv4 | ip }} +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 2 + set originator-id {{ loopback0_ipv4 | ip }} +{% endif %} +! +! end of template: bgpd/templates/internal/policies.conf.j2 +! diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index d3b70d4a27ec..ac4b521865c8 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -40,6 +40,9 @@ constants: - ipv4 PEER_V6: - ipv6 + internal: # peer_type + db_table: "BGP_INTERNAL_NEIGHBOR" + template_dir: "internal" monitors: # peer_type enabled: true db_table: "BGP_MONITORS" diff --git a/src/sonic-bgpcfgd/bgpcfgd/main.py b/src/sonic-bgpcfgd/bgpcfgd/main.py index 7bbb6fb768eb..9330330a1b3e 100644 --- a/src/sonic-bgpcfgd/bgpcfgd/main.py +++ b/src/sonic-bgpcfgd/bgpcfgd/main.py @@ -44,6 +44,7 @@ def do_work(): ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME), # Peer Managers BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), + BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_INTERNAL_NEIGHBOR_TABLE_NAME, "internal", False), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), # AllowList Managers @@ -81,4 +82,4 @@ def main(): try: sys.exit(rc) except SystemExit: - os._exit(rc) \ No newline at end of file + os._exit(rc) diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v6.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v6.json deleted file mode 100644 index 89a4117fdac2..000000000000 --- a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v6.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "CONFIG_DB__DEVICE_METADATA": { - "localhost": {} - }, - "neighbor_addr": "FC00::", - "bgp_session": { - "asn": "555", - "name": "_ASIC_" - }, - "constants": { - "deployment_id_asn_map": { - "5": "51111" - } - } -} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v4.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v4.json index c2391674a56e..4afd00f38da1 100644 --- a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v4.json +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v4.json @@ -1,9 +1,4 @@ { - "CONFIG_DB__DEVICE_METADATA": { - "localhost": { - "sub_role": "BackEnd" - } - }, "neighbor_addr": "10.10.10.10", "bgp_session": { "asn": "555", diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v6.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v6.json index d19139a75a88..115f5a32c941 100644 --- a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v6.json +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v6.json @@ -1,9 +1,4 @@ { - "CONFIG_DB__DEVICE_METADATA": { - "localhost": { - "sub_role": "BackEnd" - } - }, "neighbor_addr": "fc::10", "bgp_session": { "asn": "555", diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v6.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v6.conf deleted file mode 100644 index 64d14dcd4fa5..000000000000 --- a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v6.conf +++ /dev/null @@ -1,13 +0,0 @@ -! -! template: bgpd/templates/general/instance.conf.j2 -! - neighbor FC00:: remote-as 555 - neighbor FC00:: description _ASIC_ - address-family ipv6 - neighbor FC00:: peer-group PEER_V6_INT - neighbor FC00:: next-hop-self force - neighbor FC00:: activate - exit-address-family -! -! end of template: bgpd/templates/general/instance.conf.j2 -! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v4.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v4.conf index 2241bbf34146..a6102cdb87a2 100644 --- a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v4.conf +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v4.conf @@ -7,7 +7,6 @@ neighbor 10.10.10.10 shutdown address-family ipv4 neighbor 10.10.10.10 peer-group PEER_V4 - neighbor 10.10.10.10 route-map FROM_BGP_PEER_V4_INT in neighbor 10.10.10.10 route-reflector-client neighbor 10.10.10.10 next-hop-self neighbor 10.10.10.10 activate diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v6.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v6.conf index 7194b0916620..aa06657d91a8 100644 --- a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v6.conf +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v6.conf @@ -7,7 +7,6 @@ neighbor fc::10 shutdown address-family ipv6 neighbor fc::10 peer-group PEER_V6 - neighbor fc::10 route-map FROM_BGP_PEER_V6_INT in neighbor fc::10 route-reflector-client neighbor fc::10 next-hop-self neighbor fc::10 activate diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json index 443b5739201c..efee873fe726 100644 --- a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json @@ -1,8 +1,7 @@ { "CONFIG_DB__DEVICE_METADATA": { "localhost": { - "type": "LeafRouter", - "sub_role": "BackEnd" + "type": "LeafRouter" } }, "CONFIG_DB__BGP_BBR": { diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_all.conf index 63211ded8796..afa7201b742a 100644 --- a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_all.conf +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_all.conf @@ -2,28 +2,18 @@ ! template: bgpd/templates/general/peer-group.conf.j2 ! neighbor PEER_V4 peer-group - neighbor PEER_V4_INT peer-group neighbor PEER_V6 peer-group - neighbor PEER_V6_INT peer-group address-family ipv4 neighbor PEER_V4 allowas-in 1 - neighbor PEER_V4_INT allowas-in 1 neighbor PEER_V4 soft-reconfiguration inbound neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - neighbor PEER_V4_INT soft-reconfiguration inbound - neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in - neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out exit-address-family address-family ipv6 neighbor PEER_V6 allowas-in 1 - neighbor PEER_V6_INT allowas-in 1 neighbor PEER_V6 soft-reconfiguration inbound neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - neighbor PEER_V6_INT soft-reconfiguration inbound - neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in - neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out exit-address-family ! ! end of template: bgpd/templates/general/peer-group.conf.j2 diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_base.conf b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_base.conf index a681e7f08083..3bef9fe4fdc2 100644 --- a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_base.conf +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_base.conf @@ -2,26 +2,16 @@ ! template: bgpd/templates/general/peer-group.conf.j2 ! neighbor PEER_V4 peer-group - neighbor PEER_V4_INT peer-group neighbor PEER_V6 peer-group - neighbor PEER_V6_INT peer-group address-family ipv4 - neighbor PEER_V4_INT route-reflector-client neighbor PEER_V4 soft-reconfiguration inbound neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - neighbor PEER_V4_INT soft-reconfiguration inbound - neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in - neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out exit-address-family address-family ipv6 - neighbor PEER_V6_INT route-reflector-client neighbor PEER_V6 soft-reconfiguration inbound neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - neighbor PEER_V6_INT soft-reconfiguration inbound - neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in - neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out exit-address-family ! ! end of template: bgpd/templates/general/peer-group.conf.j2 diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json index 08f1eef63267..2ed388731ba0 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json @@ -1,9 +1,4 @@ { - "CONFIG_DB__DEVICE_METADATA": { - "localhost": { - "sub_role": "BackEnd" - } - }, "loopback0_ipv4": "10.10.10.10/32", "constants": { "bgp": { diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json index 958c9b0fbd4b..b752581e3096 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json @@ -1,9 +1,4 @@ { - "CONFIG_DB__DEVICE_METADATA": { - "localhost": { - "sub_role": "NotBackEnd" - } - }, "loopback0_ipv4": "10.10.10.10/32", "constants": { "bgp": { diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json index 669810960c92..47cb93082041 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json @@ -1,9 +1,4 @@ { - "CONFIG_DB__DEVICE_METADATA": { - "localhost": { - "sub_role": "BackEnd" - } - }, "loopback0_ipv4": "10.10.10.10/32", "constants": { "bgp": { diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf index 9e6c32b17ead..79f6422961f7 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf @@ -26,14 +26,5 @@ route-map FROM_BGP_PEER_V6 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! -route-map FROM_BGP_PEER_V4_INT permit 2 - set originator-id 10.10.10.10 -! -route-map FROM_BGP_PEER_V6_INT permit 1 - set ipv6 next-hop prefer-global -! -route-map FROM_BGP_PEER_V6_INT permit 2 - set originator-id 10.10.10.10 -! ! end of template: bgpd/templates/general/policies.conf.j2 ! diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf index 6e0389fc1886..f1427175e063 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf @@ -26,14 +26,5 @@ route-map FROM_BGP_PEER_V6 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! -route-map FROM_BGP_PEER_V4_INT permit 2 - set originator-id 10.10.10.10 -! -route-map FROM_BGP_PEER_V6_INT permit 1 - set ipv6 next-hop prefer-global -! -route-map FROM_BGP_PEER_V6_INT permit 2 - set originator-id 10.10.10.10 -! ! end of template: bgpd/templates/general/policies.conf.j2 ! diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v4.json b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v4.json new file mode 100644 index 000000000000..c2391674a56e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v4.json @@ -0,0 +1,23 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something", + "rrclient": "1", + "nhopself": "1" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v6.json b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v6.json new file mode 100644 index 000000000000..d19139a75a88 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v6.json @@ -0,0 +1,23 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "neighbor_addr": "fc::10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something", + "rrclient": "1", + "nhopself": "1" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v4.json b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v4.json similarity index 51% rename from src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v4.json rename to src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v4.json index 1691732b39b4..6f1b5a735355 100644 --- a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_ASIC_v4.json +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v4.json @@ -1,11 +1,17 @@ { "CONFIG_DB__DEVICE_METADATA": { - "localhost": {} + "localhost": { + "sub_role": "FrontEnd" + } }, "neighbor_addr": "10.10.10.10", "bgp_session": { "asn": "555", - "name": "_ASIC_" + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something" }, "constants": { "deployment_id_asn_map": { diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v6.json b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v6.json new file mode 100644 index 000000000000..becb1f00fbfe --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v6.json @@ -0,0 +1,21 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "FrontEnd" + } + }, + "neighbor_addr": "fc::10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf new file mode 100644 index 000000000000..4664395bbf27 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf @@ -0,0 +1,17 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 timers 5 30 + neighbor 10.10.10.10 shutdown + address-family ipv4 + neighbor 10.10.10.10 peer-group INTERNAL_PEER_V4 + neighbor 10.10.10.10 route-map FROM_BGP_INTERNAL_PEER_V4 in + neighbor 10.10.10.10 route-reflector-client + neighbor 10.10.10.10 next-hop-self force + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf new file mode 100644 index 000000000000..08cffe632815 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf @@ -0,0 +1,17 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor fc::10 remote-as 555 + neighbor fc::10 description remote_peer + neighbor fc::10 timers 5 30 + neighbor fc::10 shutdown + address-family ipv6 + neighbor fc::10 peer-group INTERNAL_PEER_V6 + neighbor fc::10 route-map FROM_BGP_INTERNAL_PEER_V6 in + neighbor fc::10 route-reflector-client + neighbor fc::10 next-hop-self force + neighbor fc::10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v4.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf similarity index 62% rename from src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v4.conf rename to src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf index 1e89f822457a..aba5cfac0b1f 100644 --- a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_ASIC_v4.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf @@ -2,9 +2,11 @@ ! template: bgpd/templates/general/instance.conf.j2 ! neighbor 10.10.10.10 remote-as 555 - neighbor 10.10.10.10 description _ASIC_ + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 timers 5 30 + neighbor 10.10.10.10 shutdown address-family ipv4 - neighbor 10.10.10.10 peer-group PEER_V4_INT + neighbor 10.10.10.10 peer-group INTERNAL_PEER_V4 neighbor 10.10.10.10 next-hop-self force neighbor 10.10.10.10 activate exit-address-family diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf new file mode 100644 index 000000000000..362900d57403 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf @@ -0,0 +1,15 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor fc::10 remote-as 555 + neighbor fc::10 description remote_peer + neighbor fc::10 timers 5 30 + neighbor fc::10 shutdown + address-family ipv6 + neighbor fc::10 peer-group INTERNAL_PEER_V6 + neighbor fc::10 next-hop-self force + neighbor fc::10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_back.json b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_back.json new file mode 100644 index 000000000000..c3269a7da0e5 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_back.json @@ -0,0 +1,8 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "type": "LeafRouter", + "sub_role": "BackEnd" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_front.json b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_front.json new file mode 100644 index 000000000000..2fbedc92c963 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_front.json @@ -0,0 +1,8 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "type": "LeafRouter", + "sub_role": "FrontEnd" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_back.conf b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_back.conf new file mode 100644 index 000000000000..829cbba8b13f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_back.conf @@ -0,0 +1,20 @@ +! +! template: bgpd/templates/general/peer-group.conf.j2 +! + neighbor INTERNAL_PEER_V4 peer-group + neighbor INTERNAL_PEER_V6 peer-group + address-family ipv4 + neighbor INTERNAL_PEER_V4 route-reflector-client + neighbor INTERNAL_PEER_V4 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V4 route-map FROM_BGP_INTERNAL_PEER_V4 in + neighbor INTERNAL_PEER_V4 route-map TO_BGP_INTERNAL_PEER_V4 out + exit-address-family + address-family ipv6 + neighbor INTERNAL_PEER_V6 route-reflector-client + neighbor INTERNAL_PEER_V6 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V6 route-map FROM_BGP_INTERNAL_PEER_V6 in + neighbor INTERNAL_PEER_V6 route-map TO_BGP_INTERNAL_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/general/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_front.conf b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_front.conf new file mode 100644 index 000000000000..f23e009483cc --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_front.conf @@ -0,0 +1,18 @@ +! +! template: bgpd/templates/general/peer-group.conf.j2 +! + neighbor INTERNAL_PEER_V4 peer-group + neighbor INTERNAL_PEER_V6 peer-group + address-family ipv4 + neighbor INTERNAL_PEER_V4 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V4 route-map FROM_BGP_INTERNAL_PEER_V4 in + neighbor INTERNAL_PEER_V4 route-map TO_BGP_INTERNAL_PEER_V4 out + exit-address-family + address-family ipv6 + neighbor INTERNAL_PEER_V6 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V6 route-map FROM_BGP_INTERNAL_PEER_V6 in + neighbor INTERNAL_PEER_V6 route-map TO_BGP_INTERNAL_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/general/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_back.json b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_back.json new file mode 100644 index 000000000000..148456fe960f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_back.json @@ -0,0 +1,8 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "loopback0_ipv4": "10.10.10.10/32" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_front.json b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_front.json new file mode 100644 index 000000000000..68c27766d257 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_front.json @@ -0,0 +1,8 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "FrontkEnd" + } + }, + "loopback0_ipv4": "10.10.10.10/32" +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_back.conf b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_back.conf new file mode 100644 index 000000000000..def088028d2d --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_back.conf @@ -0,0 +1,22 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +route-map FROM_BGP_INTERNAL_PEER_V4 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V4 permit 100 +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V6 permit 100 +! +route-map FROM_BGP_INTERNAL_PEER_V4 permit 2 + set originator-id 10.10.10.10 +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 2 + set originator-id 10.10.10.10 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_front.conf b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_front.conf new file mode 100644 index 000000000000..9cc40fd8b719 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_front.conf @@ -0,0 +1,16 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +route-map FROM_BGP_INTERNAL_PEER_V4 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V4 permit 100 +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V6 permit 100 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 3d3bf72463f0..6b241866044c 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -484,8 +484,9 @@ def parse_host_loopback(dpg, hname): lo_intfs = parse_loopback_intf(child) return lo_intfs -def parse_cpg(cpg, hname): +def parse_cpg(cpg, hname, local_devices=[]): bgp_sessions = {} + bgp_internal_sessions = {} myasn = None bgp_peers_with_range = {} for child in cpg: @@ -506,24 +507,47 @@ def parse_cpg(cpg, hname): else: keepalive = 60 nhopself = 1 if session.find(str(QName(ns, "NextHopSelf"))) is not None else 0 + if end_router.lower() == hname.lower(): - bgp_sessions[start_peer.lower()] = { - 'name': start_router, - 'local_addr': end_peer.lower(), - 'rrclient': rrclient, - 'holdtime': holdtime, - 'keepalive': keepalive, - 'nhopself': nhopself - } + if end_router.lower() in local_devices and start_router.lower() in local_devices: + bgp_internal_sessions[start_peer.lower()] = { + 'name': start_router, + 'local_addr': end_peer.lower(), + 'rrclient': rrclient, + 'holdtime': holdtime, + 'keepalive': keepalive, + 'nhopself': nhopself, + 'admin_status': 'up' + } + else: + bgp_sessions[start_peer.lower()] = { + 'name': start_router, + 'local_addr': end_peer.lower(), + 'rrclient': rrclient, + 'holdtime': holdtime, + 'keepalive': keepalive, + 'nhopself': nhopself + } elif start_router.lower() == hname.lower(): - bgp_sessions[end_peer.lower()] = { - 'name': end_router, - 'local_addr': start_peer.lower(), - 'rrclient': rrclient, - 'holdtime': holdtime, - 'keepalive': keepalive, - 'nhopself': nhopself - } + if end_router.lower() in local_devices and start_router.lower() in local_devices: + bgp_internal_sessions[end_peer.lower()] = { + 'name': end_router, + 'local_addr': start_peer.lower(), + 'rrclient': rrclient, + 'holdtime': holdtime, + 'keepalive': keepalive, + 'nhopself': nhopself, + 'admin_status': 'up' + } + else: + bgp_sessions[end_peer.lower()] = { + 'name': end_router, + 'local_addr': start_peer.lower(), + 'rrclient': rrclient, + 'holdtime': holdtime, + 'keepalive': keepalive, + 'nhopself': nhopself + } elif child.tag == str(QName(ns, "Routers")): for router in child.findall(str(QName(ns1, "BGPRouterDeclaration"))): asn = router.find(str(QName(ns1, "ASN"))).text @@ -550,11 +574,16 @@ def parse_cpg(cpg, hname): bgp_session = bgp_sessions[peer] if hostname.lower() == bgp_session['name'].lower(): bgp_session['asn'] = asn + for peer in bgp_internal_sessions: + bgp_internal_session = bgp_internal_sessions[peer] + if hostname.lower() == bgp_internal_session['name'].lower(): + bgp_internal_session['asn'] = asn bgp_monitors = { key: bgp_sessions[key] for key in bgp_sessions if 'asn' in bgp_sessions[key] and bgp_sessions[key]['name'] == 'BGPMonitor' } bgp_sessions = { key: bgp_sessions[key] for key in bgp_sessions if 'asn' in bgp_sessions[key] and int(bgp_sessions[key]['asn']) != 0 } + bgp_internal_sessions = { key: bgp_internal_sessions[key] for key in bgp_internal_sessions if 'asn' in bgp_internal_sessions[key] and int(bgp_internal_sessions[key]['asn']) != 0 } - return bgp_sessions, myasn, bgp_peers_with_range, bgp_monitors + return bgp_sessions, bgp_internal_sessions, myasn, bgp_peers_with_range, bgp_monitors def parse_meta(meta, hname): @@ -865,6 +894,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw hostname = None linkmetas = {} host_lo_intfs = None + local_devices = [] # hostname is the asic_name, get the asic_id from the asic_name if asic_name is not None: @@ -887,12 +917,15 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw port_alias_map.update(alias_map) port_alias_asic_map.update(alias_asic_map) + # Get the local device node from DeviceMetadata + local_devices = parse_asic_meta_get_devices(root) + for child in root: if asic_name is None: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): - (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) + (bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports, mux_cable_ports) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): @@ -908,8 +941,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) host_lo_intfs = parse_host_loopback(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): - (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) - enable_internal_bgp_session(bgp_sessions, filename, asic_name) + (bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name, local_devices) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): @@ -951,6 +983,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range + results['BGP_INTERNAL_NEIGHBOR'] = bgp_internal_sessions if mgmt_routes: # TODO: differentiate v4 and v6 next(iter(mgmt_intf.values()))['forced_mgmt_routes'] = mgmt_routes @@ -1229,6 +1262,18 @@ def parse_asic_sub_role(filename, asic_name): sub_role = parse_asic_meta(child, asic_name) return sub_role +def parse_asic_meta_get_devices(root): + local_devices = [] + + for child in root: + if child.tag == str(QName(ns, "MetadataDeclaration")): + device_metas = child.find(str(QName(ns, "Devices"))) + for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): + name = device.find(str(QName(ns1, "Name"))).text.lower() + local_devices.append(name) + + return local_devices + port_alias_map = {} port_alias_asic_map = {} diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 1802d8d30210..7ed64775111f 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -226,16 +226,21 @@ def test_frontend_bgp_neighbor(self): output = json.loads(self.run_script(argument)) self.assertDictEqual(output, \ {'10.0.0.1': {'rrclient': 0, 'name': '01T2', 'local_addr': '10.0.0.0', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}, - '10.1.0.0': {'rrclient': 0, 'name': 'ASIC2', 'local_addr': '10.1.0.1', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}, - 'fc00::2': {'rrclient': 0, 'name': '01T2', 'local_addr': 'fc00::1', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}, - '10.1.0.2': {'rrclient': 0, 'name': 'ASIC3', 'local_addr': '10.1.0.3', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}}) + 'fc00::2': {'rrclient': 0, 'name': '01T2', 'local_addr': 'fc00::1', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}}) + + def test_frontend_asic_bgp_neighbor(self): + argument = "-m {} -p {} -n asic0 --var-json \"BGP_INTERNAL_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'10.1.0.0': {'rrclient': 0, 'name': 'ASIC2', 'local_addr': '10.1.0.1', 'nhopself': 0, 'admin_status': 'up', 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}, + '10.1.0.2': {'rrclient': 0, 'name': 'ASIC3', 'local_addr': '10.1.0.3', 'nhopself': 0, 'admin_status': 'up', 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}}) def test_backend_asic_bgp_neighbor(self): - argument = "-m {} -p {} -n asic3 --var-json \"BGP_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) + argument = "-m {} -p {} -n asic3 --var-json \"BGP_INTERNAL_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) output = json.loads(self.run_script(argument)) self.assertDictEqual(output, \ - {'10.1.0.7': {'rrclient': 0, 'name': 'ASIC1', 'local_addr': '10.1.0.6', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}, - '10.1.0.3': {'rrclient': 0, 'name': 'ASIC0', 'local_addr': '10.1.0.2', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}}) + {'10.1.0.7': {'rrclient': 0, 'name': 'ASIC1', 'local_addr': '10.1.0.6', 'nhopself': 0, 'admin_status': 'up', 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}, + '10.1.0.3': {'rrclient': 0, 'name': 'ASIC0', 'local_addr': '10.1.0.2', 'nhopself': 0, 'admin_status': 'up', 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}}) def test_device_asic_metadata(self): argument = "-m {} --var-json DEVICE_METADATA".format(self.sample_graph) From d95e1969c8ccc16de787107e2bcc966aef4fd9f2 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 28 Oct 2020 21:47:01 -0700 Subject: [PATCH 1296/1427] [swsssdk] update submodule for adding new MultiDB API (#5737) --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 3461ae0578f4..748c40422dff 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 3461ae0578f415753978a5c5b33ad43e0a9b0cc5 +Subproject commit 748c40422dff1f60b43ca237bb067772e1dcb10d From 42d2bf1a5366533433ad06dcc79691368998b162 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Thu, 29 Oct 2020 14:22:24 +0530 Subject: [PATCH 1297/1427] [devices]: DellEMC Z9264f buffer changes (#5429) **- Why I did it** Converted two SP model to single pool model and modified the buffer size. **- How I did it** Changed buffer_default settings for all the DellEMC Z9264f HWSKU's. **- How to verify it** Check SP register values in NPU shell. **- Which release branch to backport (provide reason below if selected)** Need to be cherry picked for 201911 branch. --- .../DellEMC-Z9264f-C64/buffers_defaults_t1.j2 | 18 +++++++----------- .../th2-z9264f-64x100G.config.bcm | 1 + .../buffers_defaults_t0.j2 | 16 ++++++---------- .../th2-z9264f-8x100G-112x50G.config.bcm | 2 +- .../DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 | 18 +++++++----------- .../DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 | 17 ++++++----------- .../th2-z9264f-64x40G-t0.config.bcm | 3 +-- .../th2-z9264f-64x40G-t1.config.bcm | 2 +- 8 files changed, 30 insertions(+), 47 deletions(-) diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 index f120b337de04..d538ab1f650f 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 @@ -11,18 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "34859968", + "size": "35621248", "type": "ingress", "mode": "dynamic", "xoff": "7847424" }, - "egress_lossy_pool": { - "size": "29631680", - "type": "egress", - "mode": "dynamic" - }, "egress_lossless_pool": { - "size": "43481152", + "size": "43468672", "type": "egress", "mode": "static" } @@ -35,12 +30,13 @@ }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"1518", - "static_th":"10870288" + "size":"0", + "static_th":"43468672" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"1518", + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "mode":"dynamic", "dynamic_th":"3" } }, diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm index 1a9917c1f60c..2cc2d055f48d 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm @@ -1003,3 +1003,4 @@ dport_map_port_66=65 dport_map_port_100=66 module_64ports=1 +mmu_init_config="MSFT-TH2-Tier1" diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 index 2b40c3d6ad25..cbbae78d7596 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 @@ -18,18 +18,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "33096128", + "size": "34369920", "type": "ingress", "mode": "dynamic", "xoff": "9098752" }, - "egress_lossy_pool": { - "size": "28132416", - "type": "egress", - "mode": "dynamic" - }, "egress_lossless_pool": { - "size": "43108416", + "size": "43468672", "type": "egress", "mode": "static" } @@ -42,12 +37,13 @@ }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"1518", - "static_th":"10777104" + "size":"0", + "static_th":"43468672" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", + "mode":"dynamic", "dynamic_th":"3" } }, diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm index a80b341e4bd7..0c1fabf7c6fe 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm @@ -1115,5 +1115,5 @@ dport_map_port_66=121 dport_map_port_100=122 module_64ports=1 -mmu_init_config="MSFT-TH-Tier0" +mmu_init_config="MSFT-TH2-Tier0" diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 index c3e8cbda67dd..96c99e5800e9 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 @@ -11,18 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "38738752", + "size": "35621248", "type": "ingress", "mode": "dynamic", - "xoff": "3855488" - }, - "egress_lossy_pool": { - "size": "37057280", - "type": "egress", - "mode": "dynamic" + "xoff": "7847424" }, "egress_lossless_pool": { - "size": "43507776", + "size": "43468672", "type": "egress", "mode": "static" } @@ -35,12 +30,13 @@ }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"1518", - "static_th":"10876944" + "size":"0", + "static_th":"43468672" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", + "mode":"dynamic", "dynamic_th":"3" } }, diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 index a5322c73272d..5710131e5287 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 @@ -11,18 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "37968320", + "size": "35621248", "type": "ingress", "mode": "dynamic", - "xoff": "4625920" - }, - "egress_lossy_pool": { - "size": "36402496", - "type": "egress", - "mode": "dynamic" + "xoff": "7847424" }, "egress_lossless_pool": { - "size": "43507776", + "size": "43468672", "type": "egress", "mode": "static" } @@ -35,11 +30,11 @@ }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"1518", - "static_th":"10876944" + "size":"0", + "static_th":"43468672" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", "dynamic_th":"3" } diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm index f1abb5fdf286..24990bbdb1e7 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm @@ -1003,5 +1003,4 @@ dport_map_port_66=65 dport_map_port_100=66 module_64ports=1 - -mmu_init_config="MSFT-TH-Tier0" +mmu_init_config="MSFT-TH2-Tier0" diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm index 8117fd108f0c..b3920ebc6b8a 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm @@ -1004,4 +1004,4 @@ dport_map_port_100=66 module_64ports=1 -mmu_init_config="MSFT-TH-Tier1" +mmu_init_config="MSFT-TH2-Tier1" From 5ee5c13f32202203be66ff36f6710a51711614f6 Mon Sep 17 00:00:00 2001 From: Shi Su <67605788+shi-su@users.noreply.github.com> Date: Thu, 29 Oct 2020 09:15:12 -0700 Subject: [PATCH 1298/1427] Enable synchronous mode by default and add in minigraph parser (#5735) --- files/build_templates/swss_vars.j2 | 2 +- src/sonic-config-engine/minigraph.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/files/build_templates/swss_vars.j2 b/files/build_templates/swss_vars.j2 index 377837aad0ee..a9bd01565c89 100644 --- a/files/build_templates/swss_vars.j2 +++ b/files/build_templates/swss_vars.j2 @@ -2,5 +2,5 @@ "asic_type": "{{ asic_type }}", "asic_id": "{{ DEVICE_METADATA.localhost.asic_id }}", "mac": "{{ DEVICE_METADATA.localhost.mac }}", - "synchronous_mode": {% if DEVICE_METADATA.localhost.synchronous_mode == "enable" %}"enable"{% else %}"disable"{% endif %} + "synchronous_mode": {% if DEVICE_METADATA.localhost.synchronous_mode == "disable" %}"disable"{% else %}"enable"{% endif %} } diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 6b241866044c..444c0ce52fa8 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -967,7 +967,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw 'docker_routing_config_mode': docker_routing_config_mode, 'hostname': hostname, 'hwsku': hwsku, - 'type': device_type + 'type': device_type, + 'synchronous_mode': 'enable' } } # for this hostname, if sub_role is defined, add sub_role in From fd7e2a12bc3c9f6f4ef9d8db56c130e5f7a4d8ef Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Thu, 29 Oct 2020 18:46:55 +0200 Subject: [PATCH 1299/1427] [submodule-update][sonic-platform-daemon] Update submodule (#5741) 95b1696 [xcvrd] Remove dependence on enum; Add 'sonic-py-common' as dependencies in setup.py (#106) 61ed24e [thermalctld] Print exception using repr(e) to get more information (#103) 8507085 [psud] Fix psud logging (#98) Signed-off-by: Volodymyr Boyko --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 1aaffcc98fc5..95b1696401da 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 1aaffcc98fc56574a2d8b3ce3a7c50c4a6e8f8fc +Subproject commit 95b1696401da904e1a1386e2359fa72e4aa03f94 From 527a69dfbf315a0e9e5b696ca28c168ea8e30b2c Mon Sep 17 00:00:00 2001 From: Baptiste Covolato Date: Thu, 29 Oct 2020 16:26:41 -0700 Subject: [PATCH 1300/1427] [arista/7800r3_48cq(m)2_lc] remove platform_reboot (#5653) We don't need a custom platform reboot on Clearwater2(Ms). They are expected to be rebooted via a normal linux soft reboot. Remove symlink to the arista common platform reboot for those 2 platforms. --- device/arista/x86_64-arista_7800r3_48cq2_lc/platform_reboot | 1 - device/arista/x86_64-arista_7800r3_48cqm2_lc/platform_reboot | 1 - 2 files changed, 2 deletions(-) delete mode 120000 device/arista/x86_64-arista_7800r3_48cq2_lc/platform_reboot delete mode 120000 device/arista/x86_64-arista_7800r3_48cqm2_lc/platform_reboot diff --git a/device/arista/x86_64-arista_7800r3_48cq2_lc/platform_reboot b/device/arista/x86_64-arista_7800r3_48cq2_lc/platform_reboot deleted file mode 120000 index 7f94a49e38b0..000000000000 --- a/device/arista/x86_64-arista_7800r3_48cq2_lc/platform_reboot +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800r3_48cqm2_lc/platform_reboot b/device/arista/x86_64-arista_7800r3_48cqm2_lc/platform_reboot deleted file mode 120000 index 7f94a49e38b0..000000000000 --- a/device/arista/x86_64-arista_7800r3_48cqm2_lc/platform_reboot +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/platform_reboot \ No newline at end of file From e111204206c3ce11bae23e3323516be067e09e91 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 29 Oct 2020 16:29:12 -0700 Subject: [PATCH 1301/1427] [caclmgrd] Convert to Python 3; Add to sonic-host-services package (#5739) To consolidate host services and install via packages instead of file-by-file, also as part of migrating all of SONiC to Python 3, as Python 2 is no longer supported, convert caclmgrd to Python 3 and add to sonic-host-services package --- files/build_templates/sonic_debian_extension.j2 | 5 ----- src/sonic-host-services-data/debian/rules | 1 + .../sonic-host-services-data.caclmgrd.service | 2 +- src/sonic-host-services/.gitignore | 1 + .../sonic-host-services/scripts}/caclmgrd | 16 ++++++++-------- src/sonic-host-services/setup.py | 1 + 6 files changed, 12 insertions(+), 14 deletions(-) rename files/image_config/caclmgrd/caclmgrd.service => src/sonic-host-services-data/debian/sonic-host-services-data.caclmgrd.service (85%) rename {files/image_config/caclmgrd => src/sonic-host-services/scripts}/caclmgrd (98%) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 8a8334b79cac..c0f4ec072be3 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -404,11 +404,6 @@ sudo cp $IMAGE_CONFIGS/constants/constants.yml $FILESYSTEM_ROOT/etc/sonic/ sudo cp $IMAGE_CONFIGS/sudoers/sudoers $FILESYSTEM_ROOT/etc/ sudo cp $IMAGE_CONFIGS/sudoers/sudoers.lecture $FILESYSTEM_ROOT/etc/ -# Copy control plane ACL management daemon files -sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM -echo "caclmgrd.service" | sudo tee -a $GENERATED_SERVICE_FILE -sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd $FILESYSTEM_ROOT/usr/bin/ - # Copy systemd timer configuration sudo cp $BUILD_TEMPLATES/pcie-check.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable pcie-check.timer diff --git a/src/sonic-host-services-data/debian/rules b/src/sonic-host-services-data/debian/rules index 60ad16ab0416..65ed966382c4 100755 --- a/src/sonic-host-services-data/debian/rules +++ b/src/sonic-host-services-data/debian/rules @@ -6,4 +6,5 @@ build: dh $@ override_dh_installsystemd: + dh_installsystemd --no-start --name=caclmgrd dh_installsystemd --no-start --name=procdockerstatsd diff --git a/files/image_config/caclmgrd/caclmgrd.service b/src/sonic-host-services-data/debian/sonic-host-services-data.caclmgrd.service similarity index 85% rename from files/image_config/caclmgrd/caclmgrd.service rename to src/sonic-host-services-data/debian/sonic-host-services-data.caclmgrd.service index aa489eed1fc7..4df4d948ef1d 100644 --- a/files/image_config/caclmgrd/caclmgrd.service +++ b/src/sonic-host-services-data/debian/sonic-host-services-data.caclmgrd.service @@ -5,7 +5,7 @@ After=updategraph.service [Service] Type=simple -ExecStart=/usr/bin/caclmgrd +ExecStart=/usr/local/bin/caclmgrd Restart=always RestartSec=30 diff --git a/src/sonic-host-services/.gitignore b/src/sonic-host-services/.gitignore index 3dc8c1b46693..730e4244bebd 100644 --- a/src/sonic-host-services/.gitignore +++ b/src/sonic-host-services/.gitignore @@ -1,5 +1,6 @@ # Compiled Python files *.pyc +scripts/caclmgrdc scripts/procdockerstatsdc # Generated by packaging diff --git a/files/image_config/caclmgrd/caclmgrd b/src/sonic-host-services/scripts/caclmgrd similarity index 98% rename from files/image_config/caclmgrd/caclmgrd rename to src/sonic-host-services/scripts/caclmgrd index c5144a6633f0..ec33f62db0af 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/src/sonic-host-services/scripts/caclmgrd @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # # caclmgrd # @@ -148,7 +148,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): commands: List of strings, each string is a shell command """ for cmd in commands: - proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) + proc = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE) (stdout, stderr) = proc.communicate() @@ -198,7 +198,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): for iface_table_name in INTERFACE_TABLE_NAME_LIST: iface_table = self.config_db_map[namespace].get_table(iface_table_name) if iface_table: - for key, _ in iface_table.iteritems(): + for key, _ in iface_table.items(): if not _ip_prefix_in_key(key): continue @@ -234,7 +234,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): (self.namespace_mgmt_ip, self.namespace_docker_mgmt_ip[namespace])) else: # In host allow all tcp/udp traffic from namespace docker eth0 management ip to host docker bridge - for docker_mgmt_ip in self.namespace_docker_mgmt_ip.values(): + for docker_mgmt_ip in list(self.namespace_docker_mgmt_ip.values()): allow_internal_docker_ip_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "iptables -A INPUT -p tcp -s {} -d {} -j ACCEPT".format (docker_mgmt_ip, self.namespace_mgmt_ip)) @@ -374,7 +374,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): num_ctrl_plane_acl_rules = 0 # Walk the ACL tables - for (table_name, table_data) in self._tables_db_info.iteritems(): + for (table_name, table_data) in self._tables_db_info.items(): table_ip_version = None @@ -399,7 +399,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): acl_rules = {} - for ((rule_table_name, rule_id), rule_props) in self._rules_db_info.iteritems(): + for ((rule_table_name, rule_id), rule_props) in self._rules_db_info.items(): if rule_table_name == table_name: if not rule_props: self.log_warning("rule_props for rule_id {} empty or null!".format(rule_id)) @@ -437,7 +437,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): continue # For each ACL rule in this table (in descending order of priority) - for priority in sorted(acl_rules.iterkeys(), reverse=True): + for priority in sorted(iter(acl_rules.keys()), reverse=True): rule_props = acl_rules[priority] if "PACKET_ACTION" not in rule_props: @@ -576,7 +576,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): config_db_subscriber_table_map = {} # Loop through all asic namespaces (if present) and host namespace (DEFAULT_NAMESPACE) - for namespace in self.config_db_map.keys(): + for namespace in list(self.config_db_map.keys()): # Unconditionally update control plane ACLs once at start on given namespace self.update_control_plane_acls(namespace) self.update_control_plane_nat_acls(namespace) diff --git a/src/sonic-host-services/setup.py b/src/sonic-host-services/setup.py index a8315a322687..3fab561da867 100644 --- a/src/sonic-host-services/setup.py +++ b/src/sonic-host-services/setup.py @@ -11,6 +11,7 @@ maintainer = 'Joe LeVeque', maintainer_email = 'jolevequ@microsoft.com', scripts = [ + 'scripts/caclmgrd', 'scripts/procdockerstatsd', ], install_requires = [ From 6145e4f6f1f33ff4c217833ed4d06845ff2ff50b Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Fri, 30 Oct 2020 01:05:16 +0000 Subject: [PATCH 1302/1427] [DellEMC]: FanDrawer and get_high_critical_threshold Platform API implementation for S6000, S6100, Z9100 and Z9264F (#5673) - Implement FanDrawer and get_high_critical_threshold Platform API for S6000, S6100, Z9100 and Z9264F. - Fix incorrect fan direction values in S6100, Z9100 --- .../common/dell_pmc.c | 9 +---- .../s6000/sonic_platform/__init__.py | 2 +- .../s6000/sonic_platform/chassis.py | 11 +++--- .../s6000/sonic_platform/fan_drawer.py | 34 +++++++++++++++++ .../s6100/sonic_platform/__init__.py | 2 +- .../s6100/sonic_platform/chassis.py | 11 +++--- .../s6100/sonic_platform/fan_drawer.py | 34 +++++++++++++++++ .../s6100/sonic_platform/thermal.py | 27 +++++++++++++- .../z9100/sonic_platform/__init__.py | 2 +- .../z9100/sonic_platform/chassis.py | 9 ++--- .../z9100/sonic_platform/fan_drawer.py | 37 +++++++++++++++++++ .../z9100/sonic_platform/thermal.py | 27 +++++++++++++- .../z9264f/sonic_platform/__init__.py | 4 +- .../z9264f/sonic_platform/chassis.py | 15 ++++---- .../z9264f/sonic_platform/fan_drawer.py | 37 +++++++++++++++++++ .../z9264f/sonic_platform/thermal.py | 17 ++++++++- 16 files changed, 240 insertions(+), 38 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan_drawer.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan_drawer.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan_drawer.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan_drawer.py diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c index 8206f20a1867..3193e8b4642f 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -718,18 +718,13 @@ static ssize_t show_fan_airflow(struct device *dev, { int index = to_sensor_dev_attr(devattr)->index; struct smf_data *data = dev_get_drvdata(dev); - int ret=1, fan_airflow; + int ret, fan_airflow; if (data->kind == s6100smf && index == FAN_TRAY_5) return 0; fan_airflow = smf_read_reg(data, FAN_TRAY_AIRFLOW); - - if (fan_airflow & (1 << (index))) - ret=1; - - if (ret < 0) - return ret; + ret = (fan_airflow >> index) & 1; return sprintf(buf, "%d\n", ret); } diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py index 48057d290357..db8b45acb1b5 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py @@ -1,2 +1,2 @@ -__all__ = ["platform", "chassis", "sfp", "psu", "thermal"] +__all__ = ["platform", "chassis", "fan", "fan_drawer", "sfp", "psu", "thermal"] from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index dab394abc52f..899754709bcc 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -14,7 +14,7 @@ from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Eeprom, EepromS6000 - from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal from sonic_platform.component import Component @@ -22,7 +22,7 @@ raise ImportError(str(e) + "- required module not found") -MAX_S6000_FAN = 3 +MAX_S6000_FANTRAY = 3 MAX_S6000_PSU = 2 MAX_S6000_THERMAL = 10 MAX_S6000_COMPONENT = 4 @@ -74,9 +74,10 @@ def __init__(self): else: self._eeprom = EepromS6000() - for i in range(MAX_S6000_FAN): - fan = Fan(i) - self._fan_list.append(fan) + for i in range(MAX_S6000_FANTRAY): + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) for i in range(MAX_S6000_PSU): psu = Psu(i) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..c8ea283e5ba4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan_drawer.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S6000 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.fantrayindex = fantray_index + 1 + self._fan_list.append(Fan(fantray_index)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py index 96de5a93c4c2..2764c0c33007 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py @@ -1,3 +1,3 @@ -__all__ = ["platform", "chassis", "module", "fan", "psu", "sfp", "thermal"] +__all__ = ["platform", "chassis", "module", "fan", "fan_drawer", "psu", "sfp", "thermal"] from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py index 15d8edb8b65a..47ef87b951db 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py @@ -13,7 +13,7 @@ from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.psu import Psu - from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer from sonic_platform.module import Module from sonic_platform.thermal import Thermal from sonic_platform.component import Component @@ -24,7 +24,7 @@ raise ImportError(str(e) + "- required module not found") MAX_S6100_MODULE = 4 -MAX_S6100_FAN = 4 +MAX_S6100_FANTRAY = 4 MAX_S6100_PSU = 2 MAX_S6100_THERMAL = 10 MAX_S6100_COMPONENT = 3 @@ -64,9 +64,10 @@ def __init__(self): self._module_list.append(module) self._sfp_list.extend(module._sfp_list) - for i in range(MAX_S6100_FAN): - fan = Fan(i) - self._fan_list.append(fan) + for i in range(MAX_S6100_FANTRAY): + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) for i in range(MAX_S6100_PSU): psu = Psu(i) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..ada5e93393c9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan_drawer.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S6100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.fantrayindex = fantray_index + 1 + self._fan_list.append(Fan(fantray_index)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py index c6f6314dcb6d..f7037b000c5b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py @@ -49,10 +49,14 @@ def __init__(self, thermal_index): self.thermal_temperature_file = self.HWMON_DIR \ + "temp{}_input".format(hwmon_temp_index) self.thermal_high_threshold_file = self.HWMON_DIR \ - + "temp{}_crit".format(hwmon_temp_index) + + "temp{}_max".format(hwmon_temp_index) self.thermal_low_threshold_file = self.HWMON_DIR \ + "temp{}_min".format(hwmon_temp_index) + if not self.is_cpu_thermal: + self.thermal_high_crit_threshold_file = self.HWMON_DIR \ + + "temp{}_crit".format(hwmon_temp_index) + def _read_sysfs_file(self, sysfs_file): # On successful read, returns the value read from given # sysfs_file and on failure returns 'ERR' @@ -180,6 +184,27 @@ def get_low_threshold(self): return thermal_low_threshold / 1000.0 + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of + thermal in Celsius up to nearest thousandth of one degree + Celsius, e.g. 30.125 + """ + if self.is_cpu_thermal: + return super(Thermal, self).get_high_critical_threshold() + + thermal_high_crit_threshold = self._read_sysfs_file( + self.thermal_high_crit_threshold_file) + if (thermal_high_crit_threshold != 'ERR'): + thermal_high_crit_threshold = float(thermal_high_crit_threshold) + else: + thermal_high_crit_threshold = 0 + + return thermal_high_crit_threshold / 1000.0 + def set_high_threshold(self, temperature): """ Sets the high threshold temperature of thermal diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py index 56f88c6e0fe2..8b4def6e7884 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py @@ -1,3 +1,3 @@ -__all__ = ["platform", "chassis", "fan", "psu", "sfp", "thermal"] +__all__ = ["platform", "chassis", "fan", "fan_drawer", "psu", "sfp", "thermal"] from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index 88a9c7dff10f..82f8ae60f9d7 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py @@ -14,7 +14,7 @@ import sys from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp - from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal from sonic_platform.component import Component @@ -24,7 +24,6 @@ MAX_Z9100_FANTRAY = 5 -MAX_Z9100_FAN = 2 MAX_Z9100_PSU = 2 MAX_Z9100_THERMAL = 8 MAX_Z9100_COMPONENT = 6 @@ -100,9 +99,9 @@ def __init__(self): # Initialize EEPROM self._eeprom = Eeprom() for i in range(MAX_Z9100_FANTRAY): - for j in range(MAX_Z9100_FAN): - fan = Fan(i, j) - self._fan_list.append(fan) + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) for i in range(MAX_Z9100_PSU): psu = Psu(i) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..b74931dd92d3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan_drawer.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +Z9100_FANS_PER_FANTRAY = 2 + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.fantrayindex = fantray_index + 1 + for i in range(Z9100_FANS_PER_FANTRAY): + self._fan_list.append(Fan(fantray_index, i)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py index e781a545e8ea..942934ed7638 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py @@ -45,10 +45,14 @@ def __init__(self, thermal_index): self.thermal_temperature_file = self.HWMON_DIR \ + "temp{}_input".format(hwmon_temp_index) self.thermal_high_threshold_file = self.HWMON_DIR \ - + "temp{}_crit".format(hwmon_temp_index) + + "temp{}_max".format(hwmon_temp_index) self.thermal_low_threshold_file = self.HWMON_DIR \ + "temp{}_min".format(hwmon_temp_index) + if not self.is_cpu_thermal: + self.thermal_high_crit_threshold_file = self.HWMON_DIR \ + + "temp{}_crit".format(hwmon_temp_index) + def _read_sysfs_file(self, sysfs_file): # On successful read, returns the value read from given # sysfs_file and on failure returns 'ERR' @@ -176,6 +180,27 @@ def get_low_threshold(self): return thermal_low_threshold / 1000.0 + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of + thermal in Celsius up to nearest thousandth of one degree + Celsius, e.g. 30.125 + """ + if self.is_cpu_thermal: + return super(Thermal, self).get_high_critical_threshold() + + thermal_high_crit_threshold = self._read_sysfs_file( + self.thermal_high_crit_threshold_file) + if (thermal_high_crit_threshold != 'ERR'): + thermal_high_crit_threshold = float(thermal_high_crit_threshold) + else: + thermal_high_crit_threshold = 0 + + return thermal_high_crit_threshold / 1000.0 + def set_high_threshold(self, temperature): """ Sets the high threshold temperature of thermal diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py index 656052a68223..4f5d4f6e473d 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py @@ -1,2 +1,2 @@ -__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal", "fan"] -from sonic_platform import * \ No newline at end of file +__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal", "fan", "fan_drawer"] +from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py index b9aea703b46e..3f99cf503b3b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py @@ -18,13 +18,12 @@ from sonic_platform.component import Component from sonic_platform.psu import Psu from sonic_platform.watchdog import Watchdog - from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer from sonic_platform.thermal import Thermal except ImportError as e: raise ImportError(str(e) + "- required module not found") MAX_Z9264F_FANTRAY =4 -MAX_Z9264F_FAN = 2 MAX_Z9264F_COMPONENT = 8 # BIOS,BMC,FPGA,SYSTEM CPLD,4 SLAVE CPLDs MAX_Z9264F_PSU = 2 MAX_Z9264F_THERMAL = 8 @@ -65,24 +64,24 @@ def __init__(self): self._eeprom = Eeprom() self._watchdog = Watchdog() - + for i in range(MAX_Z9264F_COMPONENT): component = Component(i) self._component_list.append(component) - + for i in range(MAX_Z9264F_PSU): psu = Psu(i) self._psu_list.append(psu) for i in range(MAX_Z9264F_FANTRAY): - for j in range(MAX_Z9264F_FAN): - fan = Fan(i,j) - self._fan_list.append(fan) + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) for i in range(MAX_Z9264F_THERMAL): thermal = Thermal(i) self._thermal_list.append(thermal) - + for port_num in range(self.PORT_START, (self.PORT_END + 1)): presence = self.get_sfp(port_num).get_presence() if presence: diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..6e8acfa720a4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan_drawer.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9264F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +Z9264F_FANS_PER_FANTRAY = 2 + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.fantrayindex = fantray_index + 1 + for i in range(Z9264F_FANS_PER_FANTRAY): + self._fan_list.append(Fan(fantray_index, i)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py index ab66c59b8600..1f3caaa02dd3 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py @@ -105,7 +105,7 @@ def get_high_threshold(self): Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - is_valid, high_threshold = self.sensor.get_threshold("UpperNonRecoverable") + is_valid, high_threshold = self.sensor.get_threshold("UpperCritical") if not is_valid: high_threshold = 0 @@ -126,6 +126,21 @@ def get_low_threshold(self): return float(low_threshold) + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of + thermal in Celsius up to nearest thousandth of one degree + Celsius, e.g. 30.125 + """ + is_valid, high_crit_threshold = self.sensor.get_threshold("UpperNonRecoverable") + if not is_valid: + high_crit_threshold = 0 + + return float(high_crit_threshold) + def set_high_threshold(self, temperature): """ Sets the high threshold temperature of thermal From b132ca098078d6ef0321424ca468111e01949506 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 29 Oct 2020 19:01:17 -0700 Subject: [PATCH 1303/1427] [build]: Upgrade pip3 before pip2 (#5743) Upgrading pip3 after pip2 caused the pip command to be aliased to the pip3 command. However, since we are still transitioning from Python 2 to Python 3, most pip commands in the codebase are expecting pip to alias to pip2. The proper solution here is to explicitly call pip2 and pip3, and no longer call pip, however this will require extensive changes and testing, so to quickly fix this issue, we upgraded pip2 after pip3 to ensure that pip2 is installed after pip3. --- dockers/docker-config-engine-buster/Dockerfile.j2 | 2 +- sonic-slave-buster/Dockerfile.j2 | 2 +- sonic-slave-stretch/Dockerfile.j2 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dockers/docker-config-engine-buster/Dockerfile.j2 b/dockers/docker-config-engine-buster/Dockerfile.j2 index 55156209f4b9..9e21571bbbf7 100644 --- a/dockers/docker-config-engine-buster/Dockerfile.j2 +++ b/dockers/docker-config-engine-buster/Dockerfile.j2 @@ -15,8 +15,8 @@ RUN apt-get update && \ python-setuptools \ python3-setuptools -RUN pip2 install --upgrade pip RUN pip3 install --upgrade pip +RUN pip2 install --upgrade pip RUN apt-get purge -y python-pip python3-pip # For sonic-config-engine Python 3 package diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index ce406cd70744..03dae31ecd46 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -334,8 +334,8 @@ RUN export VERSION=1.14.2 \ && echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/bash.bashrc \ && rm go$VERSION.linux-*.tar.gz -RUN pip2 install --upgrade pip RUN pip3 install --upgrade pip +RUN pip2 install --upgrade pip RUN apt-get purge -y python-pip python3-pip # For building Python packages diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 3f455bdd7bc6..276bdcbbc1dd 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -330,8 +330,8 @@ RUN export VERSION=1.14.2 \ && echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/bash.bashrc \ && rm go$VERSION.linux-*.tar.gz -RUN pip2 install --upgrade pip RUN pip3 install --upgrade pip +RUN pip2 install --upgrade pip RUN apt-get purge -y python-pip python3-pip # For p4 build From 12911ba619711c327d6725d66c899ff1cf4fc5e8 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 30 Oct 2020 04:17:30 -0700 Subject: [PATCH 1304/1427] [Arista] Update arista driver submodules (#5736) - Change `/run/arista` mount to pmon by `/var/run/platform_cache` - Python3 by default for Arista platform initialisation - Fix outstanding py2/3 compatibility issues (eeprom mostly) - Use pytest for unit testing - Miscellaneous modular fixes --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- rules/docker-platform-monitor.mk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 05a02d74c91f..3943e69510b4 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 05a02d74c91fb1b91fbb4602bf8c77067da3ecf2 +Subproject commit 3943e69510b471e65797d6054dd5f47cff3012c3 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 05a02d74c91f..3943e69510b4 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 05a02d74c91fb1b91fbb4602bf8c77067da3ecf2 +Subproject commit 3943e69510b471e65797d6054dd5f47cff3012c3 diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index b6ea78d53f0b..75a22425fd48 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -41,9 +41,9 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_PLATFORM_MONITOR_DBG) $(DOCKER_PLATFORM_MONITOR)_CONTAINER_NAME = pmon $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += --privileged -t $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /var/run/platform_cache:/var/run/platform_cache:ro # Mount Arista python library on Aboot images to be used by plugins -$(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /run/arista:/run/arista:ro $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista:/usr/lib/python2.7/dist-packages/arista:ro $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/sonic_platform:/usr/lib/python2.7/dist-packages/sonic_platform:ro From 6333bb73b0e82a0137f5c845346b087e4de9b1b9 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 30 Oct 2020 09:43:14 -0700 Subject: [PATCH 1305/1427] Explicitly call `pip2` rather than `pip` in locations where both pip2 and pip3 are installed (#5747) As part of the transition from Python 2 to Python 3, we are installing both pip2 and pip3 in the slave and config-engine containers. This PR replaces calls to `pip` in these containers with an explicit call to `pip2` to ensure the proper version of pip is executed, no matter which version of pip is aliased to `pip`, as we no longer rely on that alias. Also some other pip-related cleanup --- dockers/docker-base-buster/Dockerfile.j2 | 4 +-- dockers/docker-lldp/Dockerfile.j2 | 3 +- dockers/docker-orchagent/Dockerfile.j2 | 14 ++++----- dockers/docker-platform-monitor/Dockerfile.j2 | 12 +++----- dockers/docker-platform-monitor/start.sh | 12 ++++---- .../build_templates/sonic_debian_extension.j2 | 30 +++++++++---------- 6 files changed, 35 insertions(+), 40 deletions(-) diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index 4d8b189f8ec9..a7919b8800a3 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -81,7 +81,7 @@ RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f -y RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb # For templating -RUN pip install j2cli +RUN pip2 install j2cli RUN mkdir -p /etc/supervisor /var/log/supervisor @@ -100,7 +100,7 @@ RUN apt-get -y purge \ {%- endif %} # Add support for supervisord to handle startup dependencies -RUN pip install supervisord-dependent-startup==1.4.0 +RUN pip2 install supervisord-dependent-startup==1.4.0 # Clean up apt # Remove /var/lib/apt/lists/*, could be obsoleted for derived images diff --git a/dockers/docker-lldp/Dockerfile.j2 b/dockers/docker-lldp/Dockerfile.j2 index 6024e844f1e0..1306582b0aad 100644 --- a/dockers/docker-lldp/Dockerfile.j2 +++ b/dockers/docker-lldp/Dockerfile.j2 @@ -27,8 +27,7 @@ RUN apt-get update {% endif %} # Clean up -RUN apt-get purge -y python-pip && \ - apt-get clean -y && \ +RUN apt-get clean -y && \ apt-get autoclean -y && \ apt-get autoremove -y && \ rm -rf /debs \ diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 5af76e3c600f..b046afedbe7d 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -36,13 +36,13 @@ RUN ln -s -f /usr/bin/gcc-6 /usr/bin/arm-linux-gnueabihf-gcc RUN ln -s -f /usr/bin/gcc-6 /usr/bin/aarch64-linux-gnu-gcc {% endif %} -RUN pip install \ - scapy==2.4.2 \ - setuptools \ - pyroute2==0.5.3 -RUN pip install \ - netifaces==0.10.7 \ - monotonic==1.5 +RUN pip2 install \ + scapy==2.4.2 \ + setuptools \ + pyroute2==0.5.3 +RUN pip2 install \ + netifaces==0.10.7 \ + monotonic==1.5 {% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %} # Remove installed gcc diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index b3af66971938..75852395bf70 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -10,7 +10,7 @@ ENV DEBIAN_FRONTEND=noninteractive # Install required packages RUN apt-get update && \ apt-get install -y \ - python-pip \ + python-dev \ python3-dev \ ipmitool \ librrd8 \ @@ -19,11 +19,7 @@ RUN apt-get update && \ python-smbus \ ethtool \ dmidecode \ - i2c-tools && \ - pip install enum34 - -# Install python3 required packages -RUN python3 -m pip install --no-cache-dir setuptools wheel + i2c-tools {% if docker_platform_monitor_debs.strip() -%} # Copy locally-built Debian package dependencies @@ -51,8 +47,8 @@ RUN python3 -m pip install --no-cache-dir setuptools wheel # Clean up RUN apt-get purge -y \ - python3-dev \ - python-pip && \ + python-dev \ + python3-dev && \ apt-get clean -y && \ apt-get autoclean -y && \ apt-get autoremove -y && \ diff --git a/dockers/docker-platform-monitor/start.sh b/dockers/docker-platform-monitor/start.sh index 0884266e2308..d7e7c91db492 100755 --- a/dockers/docker-platform-monitor/start.sh +++ b/dockers/docker-platform-monitor/start.sh @@ -15,13 +15,13 @@ if [ -e /usr/share/sonic/platform/platform_wait ]; then fi fi -# If the sonic-platform package is not installed, try to install it -pip show sonic-platform > /dev/null 2>&1 +# If the Python 2 sonic-platform package is not installed, try to install it +pip2 show sonic-platform > /dev/null 2>&1 if [ $? -ne 0 ]; then SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py2-none-any.whl" echo "sonic-platform package not installed, attempting to install..." if [ -e ${SONIC_PLATFORM_WHEEL} ]; then - pip install ${SONIC_PLATFORM_WHEEL} + pip2 install ${SONIC_PLATFORM_WHEEL} if [ $? -eq 0 ]; then echo "Successfully installed ${SONIC_PLATFORM_WHEEL}" else @@ -32,13 +32,13 @@ if [ $? -ne 0 ]; then fi fi -# If the python3 sonic-platform package is not installed, try to install it -python3 -m pip show sonic-platform > /dev/null 2>&1 +# If the Python 3 sonic-platform package is not installed, try to install it +pip3 show sonic-platform > /dev/null 2>&1 if [ $? -ne 0 ]; then SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py3-none-any.whl" echo "sonic-platform package not installed, attempting to install..." if [ -e ${SONIC_PLATFORM_WHEEL} ]; then - python3 -m pip install ${SONIC_PLATFORM_WHEEL} + pip3 install ${SONIC_PLATFORM_WHEEL} if [ $? -eq 0 ]; then echo "Successfully installed ${SONIC_PLATFORM_WHEEL}" else diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index c0f4ec072be3..34f864b6d21d 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -96,7 +96,7 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in python3-dev # Install Python client for Redis -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install "redis==3.5.3" +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install "redis==3.5.3" # Install redis-dump-load Python 3 package # Note: the scripts will be overwritten by corresponding Python 2 package @@ -108,14 +108,14 @@ sudo rm -rf $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY3_WHEEL_NAME # Install redis-dump-load Python 2 package REDIS_DUMP_LOAD_PY2_WHEEL_NAME=$(basename {{redis_dump_load_py2_wheel_path}}) sudo cp {{redis_dump_load_py2_wheel_path}} $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $REDIS_DUMP_LOAD_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $REDIS_DUMP_LOAD_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY2_WHEEL_NAME # Install Python module for ipaddress -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install ipaddress +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install ipaddress # Install Python module for psutil -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install psutil +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install psutil # Install SwSS SDK Python 3 package # Note: the scripts will be overwritten by corresponding Python 2 package @@ -129,13 +129,13 @@ fi # Install SwSS SDK Python 2 package SWSSSDK_PY2_WHEEL_NAME=$(basename {{swsssdk_py2_wheel_path}}) sudo cp {{swsssdk_py2_wheel_path}} $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SWSSSDK_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $SWSSSDK_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME # Install sonic-py-common Python 2 package SONIC_PY_COMMON_PY2_WHEEL_NAME=$(basename {{sonic_py_common_py2_wheel_path}}) sudo cp {{sonic_py_common_py2_wheel_path}} $FILESYSTEM_ROOT/$SONIC_PY_COMMON_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SONIC_PY_COMMON_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $SONIC_PY_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SONIC_PY_COMMON_PY2_WHEEL_NAME # Install sonic-py-common Python 3 package @@ -147,7 +147,7 @@ sudo rm -rf $FILESYSTEM_ROOT/$SONIC_PY_COMMON_PY3_WHEEL_NAME # Install SONiC config engine Python package CONFIG_ENGINE_PY2_WHEEL_NAME=$(basename {{config_engine_py2_wheel_path}}) sudo cp {{config_engine_py2_wheel_path}} $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $CONFIG_ENGINE_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $CONFIG_ENGINE_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY2_WHEEL_NAME # Install sonic-yang-models py3 package, install dependencies @@ -161,19 +161,19 @@ sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MODEL_PY3_WHEEL_NAME # Install sonic-yang-mgmt Python package SONIC_YANG_MGMT_PY_WHEEL_NAME=$(basename {{sonic_yang_mgmt_py_wheel_path}}) sudo cp {{sonic_yang_mgmt_py_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SONIC_YANG_MGMT_PY_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $SONIC_YANG_MGMT_PY_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY_WHEEL_NAME # Install sonic-platform-common Python 2 package PLATFORM_COMMON_PY2_WHEEL_NAME=$(basename {{platform_common_py2_wheel_path}}) sudo cp {{platform_common_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $PLATFORM_COMMON_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $PLATFORM_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME # Install system-health Python 2 package SYSTEM_HEALTH_PY2_WHEEL_NAME=$(basename {{system_health_py2_wheel_path}}) sudo cp {{system_health_py2_wheel_path}} $FILESYSTEM_ROOT/$SYSTEM_HEALTH_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SYSTEM_HEALTH_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $SYSTEM_HEALTH_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SYSTEM_HEALTH_PY2_WHEEL_NAME # Install sonic-platform-common Python 3 package @@ -192,7 +192,7 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in # Install SONiC Utilities Python 2 package SONIC_UTILITIES_PY2_WHEEL_NAME=$(basename {{sonic_utilities_py2_wheel_path}}) sudo cp {{sonic_utilities_py2_wheel_path}} $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SONIC_UTILITIES_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $SONIC_UTILITIES_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY2_WHEEL_NAME # Install sonic-utilities data files (and any dependencies via 'apt-get -y install -f') @@ -335,9 +335,9 @@ sudo cp $IMAGE_CONFIGS/corefile_uploader/core_analyzer.rc.json $FILESYSTEM_ROOT_ sudo chmod og-rw $FILESYSTEM_ROOT_ETC_SONIC/core_analyzer.rc.json sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install libffi-dev libssl-dev -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage==0.36.0 -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog==0.10.2 -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures==3.3.0 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install azure-storage==0.36.0 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install watchdog==0.10.2 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install futures==3.3.0 {% if include_kubernetes == "y" %} # Copy kubelet service files @@ -604,7 +604,7 @@ sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh # Install mlnx-sonic-platform-common Python 2 package MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME=$(basename {{mlnx_platform_api_py2_wheel_path}}) sudo cp {{mlnx_platform_api_py2_wheel_path}} $FILESYSTEM_ROOT/$MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME {% endif %} From 781188f54941a2eb9e4a23a96f05986ec51ff106 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Sat, 31 Oct 2020 03:01:17 +0800 Subject: [PATCH 1306/1427] [thermalctld] Enlarge startretries value to avoid thermalctld not able to restart during regression test (#5633) Increase startretires value from default of 10 to 50 to prevent supervisor from placing thermalctld in FATAL state during regression testing. Also ensures supervisord tries hard to get thermalctld running in production, as thermalctld is critical to prevent device from overheating. --- dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index f1eacf5b408c..c44bbbbf8eb4 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -125,6 +125,7 @@ autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog startsecs=10 +startretries=50 dependent_startup=true dependent_startup_wait_for=start:exited {% endif %} From 279943c11f3b84a38c5c60e0b9218e91154dc414 Mon Sep 17 00:00:00 2001 From: Shi Su <67605788+shi-su@users.noreply.github.com> Date: Sat, 31 Oct 2020 02:26:19 -0700 Subject: [PATCH 1307/1427] [sonic-swss] Update submodule (#5745) Update the sonic-swss submodule. The following are the commits in the submodule. [neighorch] Remove pending DEL operation after SET operation for the same key 2265f548386929b7827d1079efd453128f1ec1f9 [NAT]: Update nat entries to use nat_type to support DNAT Pool changes. 8696e939f973895ead4731ad499a72f257a3b510 [intfsorch] Init proxy_arp variable while adding router interface. 1da3c773762fa637a5ea47017715361bede50a4a --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 495816da3fe6..2265f5483869 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 495816da3fe6d1690e76ea49d53df8d9e43cc07d +Subproject commit 2265f548386929b7827d1079efd453128f1ec1f9 From 8d8aadb6156d1ba42b3249de001e14f92444dfcb Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Sat, 31 Oct 2020 16:38:32 -0700 Subject: [PATCH 1308/1427] Load config after subscribe (#5740) - Why I did it The update_all_feature_states can run in the range of 20+ seconds to one minute. With load of AAA & Tacacs preceding it, any DB updates in AAA/TACACS during the long running feature updates would get missed. To avoid, switch the order. - How I did it Do a load after after updating all feature states. - How to verify it Not a easy one Have a script that restart hostcfgd sleep 2s run redis-cli/config command to update AAA/TACACS table Run the script above and watch the file /etc/pam.d/common-auth-sonic for a minute. - When it repro: The updates will not reflect in /etc/pam.d/common-auth-sonic --- files/image_config/hostcfgd/hostcfgd | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index b76655ceef2c..9c86cedc7db6 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -233,17 +233,24 @@ class HostConfigDaemon: self.config_db = ConfigDBConnector() self.config_db.connect(wait_for_init=True, retry_on=True) syslog.syslog(syslog.LOG_INFO, 'ConfigDB connect success') + + self.aaacfg = AaaCfg() + self.iptables = Iptables() + # Cache the values of 'state' field in 'FEATURE' table of each container + self.cached_feature_states = {} + + self.is_multi_npu = device_info.is_multi_npu() + + + def load(self): aaa = self.config_db.get_table('AAA') tacacs_global = self.config_db.get_table('TACPLUS') tacacs_server = self.config_db.get_table('TACPLUS_SERVER') - self.aaacfg = AaaCfg() self.aaacfg.load(aaa, tacacs_global, tacacs_server) + lpbk_table = self.config_db.get_table('LOOPBACK_INTERFACE') - self.iptables = Iptables() self.iptables.load(lpbk_table) - self.is_multi_npu = device_info.is_multi_npu() - # Cache the values of 'state' field in 'FEATURE' table of each container - self.cached_feature_states = {} + def update_feature_state(self, feature_name, state, feature_table): has_timer = ast.literal_eval(feature_table[feature_name].get('has_timer', 'False')) @@ -367,14 +374,19 @@ class HostConfigDaemon: self.update_feature_state(feature_name, state, feature_table) def start(self): - # Update all feature states once upon starting - self.update_all_feature_states() self.config_db.subscribe('AAA', lambda table, key, data: self.aaa_handler(key, data)) self.config_db.subscribe('TACPLUS_SERVER', lambda table, key, data: self.tacacs_server_handler(key, data)) self.config_db.subscribe('TACPLUS', lambda table, key, data: self.tacacs_global_handler(key, data)) self.config_db.subscribe('LOOPBACK_INTERFACE', lambda table, key, data: self.lpbk_handler(key, data)) self.config_db.subscribe('FEATURE', lambda table, key, data: self.feature_state_handler(key, data)) + + # Update all feature states once upon starting + self.update_all_feature_states() + + # Defer load until subscribe + self.load() + self.config_db.listen() From dddf96933c1dccf2064790a452de87b0ac632abc Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Sat, 31 Oct 2020 17:29:49 -0700 Subject: [PATCH 1309/1427] [monit] Adding patch to enhance syslog error message generation for monit alert action when status is failed. (#5720) Why/How I did: Make sure first error syslog is triggered based on FAULT TOLERANCE condition. Added support of repeat clause with alert action. This is used as trigger for generation of periodic syslog error messages if error is persistent Updated the monit conf files with repeat every x cycles for the alert action --- .../base_image_files/monit_database | 2 +- .../docker-fpm-frr/base_image_files/monit_bgp | 12 ++-- .../docker-lldp/base_image_files/monit_lldp | 6 +- .../base_image_files/monit_swss | 20 +++--- .../docker-sflow/base_image_files/monit_sflow | 2 +- .../docker-snmp/base_image_files/monit_snmp | 4 +- .../base_image_files/monit_restapi | 2 +- .../base_image_files/monit_telemetry | 4 +- .../docker-teamd/base_image_files/monit_teamd | 4 +- files/image_config/monit/conf.d/sonic-host | 13 ++-- .../base_image_files/monit_syncd | 2 +- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 2 +- .../base_image_files/monit_syncd | 2 +- .../base_image_files/monit_syncd | 2 +- .../base_image_files/monit_syncd | 2 +- .../base_image_files/monit_syncd | 2 +- .../base_image_files/monit_syncd | 2 +- .../base_image_files/monit_syncd | 4 +- .../0002-change_monit_alert_log_error.patch | 64 +++++++++++++++++++ src/monit/patch/series | 1 + 21 files changed, 111 insertions(+), 45 deletions(-) create mode 100644 src/monit/patch/0002-change_monit_alert_log_error.patch diff --git a/dockers/docker-database/base_image_files/monit_database b/dockers/docker-database/base_image_files/monit_database index c1addd8a6f05..47c9d1b2d47f 100644 --- a/dockers/docker-database/base_image_files/monit_database +++ b/dockers/docker-database/base_image_files/monit_database @@ -4,4 +4,4 @@ ## redis_server ############################################################################### check program database|redis_server with path "/usr/bin/process_checker database /usr/bin/redis-server" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp index 4567d45e3c48..3361b9e64f3c 100644 --- a/dockers/docker-fpm-frr/base_image_files/monit_bgp +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -9,19 +9,19 @@ ## bgpmon ############################################################################### check program bgp|zebra with path "/usr/bin/process_checker bgp /usr/lib/frr/zebra" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program bgp|fpmsyncd with path "/usr/bin/process_checker bgp fpmsyncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program bgp|bgpd with path "/usr/bin/process_checker bgp /usr/lib/frr/bgpd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program bgp|staticd with path "/usr/bin/process_checker bgp /usr/lib/frr/staticd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program bgp|bgpcfgd with path "/usr/bin/process_checker bgp /usr/bin/python /usr/local/bin/bgpcfgd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program bgp|bgpmon with path "/usr/bin/process_checker bgp /usr/bin/python /usr/local/bin/bgpmon" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-lldp/base_image_files/monit_lldp b/dockers/docker-lldp/base_image_files/monit_lldp index 194fa14a3088..8dc2f3c15321 100644 --- a/dockers/docker-lldp/base_image_files/monit_lldp +++ b/dockers/docker-lldp/base_image_files/monit_lldp @@ -6,10 +6,10 @@ ## lldpmgrd ############################################################################### check program lldp|lldpd_monitor with path "/usr/bin/process_checker lldp lldpd:" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program lldp|lldp_syncd with path "/usr/bin/process_checker lldp python2 -m lldp_syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program lldp|lldpmgrd with path "/usr/bin/process_checker lldp python /usr/bin/lldpmgrd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-orchagent/base_image_files/monit_swss b/dockers/docker-orchagent/base_image_files/monit_swss index f5f4389f3fe4..da601011e735 100644 --- a/dockers/docker-orchagent/base_image_files/monit_swss +++ b/dockers/docker-orchagent/base_image_files/monit_swss @@ -13,31 +13,31 @@ ## vxlanmgrd ############################################################################## check program swss|orchagent with path "/usr/bin/process_checker swss /usr/bin/orchagent -d /var/log/swss" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program swss|portsyncd with path "/usr/bin/process_checker swss /usr/bin/portsyncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program swss|neighsyncd with path "/usr/bin/process_checker swss /usr/bin/neighsyncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program swss|vrfmgrd with path "/usr/bin/process_checker swss /usr/bin/vrfmgrd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program swss|vlanmgrd with path "/usr/bin/process_checker swss /usr/bin/vlanmgrd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program swss|intfmgrd with path "/usr/bin/process_checker swss /usr/bin/intfmgrd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program swss|portmgrd with path "/usr/bin/process_checker swss /usr/bin/portmgrd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program swss|buffermgrd with path "/usr/bin/process_checker swss /usr/bin/buffermgrd -l" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program swss|nbrmgrd with path "/usr/bin/process_checker swss /usr/bin/nbrmgrd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program swss|vxlanmgrd with path "/usr/bin/process_checker swss /usr/bin/vxlanmgrd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-sflow/base_image_files/monit_sflow b/dockers/docker-sflow/base_image_files/monit_sflow index 217f2e625835..84b36b18ce65 100644 --- a/dockers/docker-sflow/base_image_files/monit_sflow +++ b/dockers/docker-sflow/base_image_files/monit_sflow @@ -4,4 +4,4 @@ ## sflowmgrd ############################################################################### check program sflow|sflowmgrd with path "/usr/bin/process_checker sflow /usr/bin/sflowmgrd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-snmp/base_image_files/monit_snmp b/dockers/docker-snmp/base_image_files/monit_snmp index b1725378c0b8..6a368a9b6035 100644 --- a/dockers/docker-snmp/base_image_files/monit_snmp +++ b/dockers/docker-snmp/base_image_files/monit_snmp @@ -5,7 +5,7 @@ ## snmpd_subagent ############################################################################### check program snmp|snmpd with path "/usr/bin/process_checker snmp /usr/sbin/snmpd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program snmp|snmp_subagent with path "/usr/bin/process_checker snmp python3 -m sonic_ax_impl" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-sonic-restapi/base_image_files/monit_restapi b/dockers/docker-sonic-restapi/base_image_files/monit_restapi index 84e4366f4ac5..6752100b84f2 100644 --- a/dockers/docker-sonic-restapi/base_image_files/monit_restapi +++ b/dockers/docker-sonic-restapi/base_image_files/monit_restapi @@ -4,4 +4,4 @@ ## restapi ############################################################################### check program restapi|restapi with path "/usr/bin/process_checker restapi /usr/sbin/go-server-server" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry index 7365ce51d1fd..3680bbe6cf9a 100644 --- a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry +++ b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry @@ -5,7 +5,7 @@ ## dialout_client ############################################################################### check program telemetry|telemetry with path "/usr/bin/process_checker telemetry /usr/sbin/telemetry" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program telemetry|dialout_client with path "/usr/bin/process_checker telemetry /usr/sbin/dialout_client_cli" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-teamd/base_image_files/monit_teamd b/dockers/docker-teamd/base_image_files/monit_teamd index 256482aef2bf..626a6145604e 100644 --- a/dockers/docker-teamd/base_image_files/monit_teamd +++ b/dockers/docker-teamd/base_image_files/monit_teamd @@ -5,7 +5,7 @@ ## teammgrd ############################################################################### check program teamd|teamsyncd with path "/usr/bin/process_checker teamd /usr/bin/teamsyncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program teamd|teammgrd with path "/usr/bin/process_checker teamd /usr/bin/teammgrd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/files/image_config/monit/conf.d/sonic-host b/files/image_config/monit/conf.d/sonic-host index 3fd313e24bab..202c49f8d7b2 100644 --- a/files/image_config/monit/conf.d/sonic-host +++ b/files/image_config/monit/conf.d/sonic-host @@ -6,15 +6,15 @@ ############################################################################### check filesystem root-overlay with path / - if space usage > 90% for 10 times within 20 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert repeat every 1 cycles check filesystem var-log with path /var/log - if space usage > 90% for 10 times within 20 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert repeat every 1 cycles check system $HOST - if memory usage > 90% for 10 times within 20 cycles then alert - if cpu usage (user) > 90% for 10 times within 20 cycles then alert - if cpu usage (system) > 90% for 10 times within 20 cycles then alert + if memory usage > 90% for 10 times within 20 cycles then alert repeat every 1 cycles + if cpu usage (user) > 90% for 10 times within 20 cycles then alert repeat every 1 cycles + if cpu usage (system) > 90% for 10 times within 20 cycles then alert repeat every 1 cycles check process rsyslog with pidfile /var/run/rsyslogd.pid start program = "/bin/systemctl start rsyslog.service" @@ -29,4 +29,5 @@ check process rsyslog with pidfile /var/run/rsyslogd.pid # check program routeCheck with path "/usr/local/bin/route_check.py" every 5 cycles - if status != 0 then alert + if status != 0 for 3 cycle then alert repeat every 1 cycles + diff --git a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd index 14789c67c3b8..61e290e3189e 100644 --- a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd +++ b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd @@ -4,4 +4,4 @@ ## syncd ############################################################################### check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd index 119548770096..d63346d9ee20 100644 --- a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd @@ -5,7 +5,7 @@ ## dsserve ############################################################################### check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program syncd|dsserve with path "/usr/bin/process_checker syncd /usr/bin/dsserve /usr/bin/syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd index 14789c67c3b8..61e290e3189e 100644 --- a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd +++ b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd @@ -4,4 +4,4 @@ ## syncd ############################################################################### check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd index 14789c67c3b8..61e290e3189e 100644 --- a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd +++ b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd @@ -4,4 +4,4 @@ ## syncd ############################################################################### check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd index 14789c67c3b8..61e290e3189e 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd @@ -4,4 +4,4 @@ ## syncd ############################################################################### check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd index 14789c67c3b8..61e290e3189e 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd @@ -4,4 +4,4 @@ ## syncd ############################################################################### check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd index 14789c67c3b8..61e290e3189e 100644 --- a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd @@ -4,4 +4,4 @@ ## syncd ############################################################################### check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd index 14789c67c3b8..61e290e3189e 100644 --- a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd +++ b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd @@ -4,4 +4,4 @@ ## syncd ############################################################################### check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd index 119548770096..d63346d9ee20 100644 --- a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd +++ b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd @@ -5,7 +5,7 @@ ## dsserve ############################################################################### check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles check program syncd|dsserve with path "/usr/bin/process_checker syncd /usr/bin/dsserve /usr/bin/syncd" - if status != 0 for 5 times within 5 cycles then alert + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/src/monit/patch/0002-change_monit_alert_log_error.patch b/src/monit/patch/0002-change_monit_alert_log_error.patch new file mode 100644 index 000000000000..1e43078e6215 --- /dev/null +++ b/src/monit/patch/0002-change_monit_alert_log_error.patch @@ -0,0 +1,64 @@ +From 97a5defc6a7fcc6a00f691bb5314ceb8fb7704e9 Mon Sep 17 00:00:00 2001 +From: Abhishek Dosi +Date: Mon, 26 Oct 2020 11:40:02 -0700 +Subject: [PATCH] Patch on top of commit Patch is addressing these changes:- + +a) Enable repeat keyword for alert action . Using this we can log +syslog error message for persistent failure condition + +b) Make sure error message is loggged if state is changed to fail first time (fault tolerance condition) +or we have repeat clause for alert + +Signed-off-by: Abhishek Dosi + +--- + src/event.c | 6 +++++- + src/p.y | 8 +++++++- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/event.c b/src/event.c +index ed363ee..9d08fc0 100644 +--- a/src/event.c ++++ b/src/event.c +@@ -336,7 +336,8 @@ static void _handleEvent(Service_T S, Event_T E) { + if (E->state != State_Init || E->state_map & 0x1) { + if (E->state == State_Succeeded || E->state == State_ChangedNot || E->id == Event_Instance || E->id == Event_Action) + LogInfo("'%s' %s\n", S->name, E->message); +- else ++ /* Send Error log if state change to failed for 1st time or if we have repeat clause then do periodically */ ++ else if ((E->state_changed) || (E->state == State_Failed && E->action->failed->repeat && E->count % E->action->failed->repeat == 0)) + LogError("'%s' %s\n", S->name, E->message); + } + if (E->state == State_Init) + return; +diff --git a/src/p.y b/src/p.y +index a57807d..b46b1a1 100644 +--- a/src/p.y ++++ b/src/p.y +@@ -2250,9 +2250,12 @@ repeat : /* EMPTY */ { + } + ; + +-action : ALERT { ++action : ALERT repeat{ + $$ = Action_Alert; + } ++ | ALERT { ++ $$ = Action_Alert; ++ } + | EXEC argumentlist repeat { + $$ = Action_Exec; + } +@@ -2281,6 +2284,9 @@ action1 : action { + repeat = 0; + command1 = command; + command = NULL; ++ } else if ($1 == Action_Alert) { ++ repeat1 = repeat; ++ repeat = 0; + } + } + ; +-- +2.17.1 + diff --git a/src/monit/patch/series b/src/monit/patch/series index 15fcdd50c8a5..f5534d0f554f 100644 --- a/src/monit/patch/series +++ b/src/monit/patch/series @@ -1,2 +1,3 @@ # This series applies on GIT commit dc9bc1c949125140d967edfc598dfad47eedc552 0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch +0002-change_monit_alert_log_error.patch From 908787d2a24b1f53e9f611f828605f1690adc36b Mon Sep 17 00:00:00 2001 From: gechiang <62408185+gechiang@users.noreply.github.com> Date: Sat, 31 Oct 2020 18:06:06 -0700 Subject: [PATCH 1310/1427] =?UTF-8?q?Added=20new=20method=20get=5Fback=5Fe?= =?UTF-8?q?nd=5Finterface=5Fset()=20to=20speed=20up=20back-end=20in?= =?UTF-8?q?=E2=80=A6=20(#5731)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added new MultiASIC util method "get_back_end_interface_set()" to speed up back-end interface check by allowing caller to cache the back-end intf into a set. This way the caller can use this set for all subsequent back-end interface check requests instead of each time need to read from redis DB which become a scaling issue for cases such as checking for thousands of nexthop routes for filtering purpose. --- .../sonic_py_common/multi_asic.py | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index cb80635dbc0a..a6ab17025eba 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -321,6 +321,33 @@ def is_port_channel_internal(port_channel, namespace=None): return False +# Allow user to get a set() of back-end interface and back-end LAG per namespace +# default is getting it for all name spaces if no namespace is specified +def get_back_end_interface_set(namespace=None): + bk_end_intf_list =[] + if not is_multi_asic(): + return None + + port_table = get_port_table(namespace) + for port, info in port_table.items(): + if PORT_ROLE in info and info[PORT_ROLE] == INTERNAL_PORT: + bk_end_intf_list.append(port) + + if len(bk_end_intf_list): + ns_list = get_namespace_list(namespace) + for ns in ns_list: + config_db = connect_config_db_for_ns(ns) + port_channels = config_db.get_table(PORT_CHANNEL_CFG_DB_TABLE) + # a back-end LAG must be configured with all of its member from back-end interfaces. + # mixing back-end and front-end interfaces is miss configuration and not allowed. + # To determine if a LAG is back-end LAG, just need to check its first member is back-end or not + # is sufficient. Note that a user defined LAG may have empty members so the list expansion logic + # need to ensure there are members before inspecting member[0]. + bk_end_intf_list.extend([port_channel for port_channel, lag_info in port_channels.items()\ + if 'members' in lag_info and lag_info['members'][0] in bk_end_intf_list]) + a = set() + a.update(bk_end_intf_list) + return a def is_bgp_session_internal(bgp_neigh_ip, namespace=None): From c8a00eda95955a4812f4f011ef3458ca9605aa16 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 31 Oct 2020 20:45:59 -0700 Subject: [PATCH 1311/1427] [mgmt ip]: mvrf ip rule priority change to 32765 (#5754) Fix Azure/SONiC#551 When eth0 IP address is configured, an ip rule is getting added for eth0 IP address through the interfaces.j2 template. This eth0 ip rule creates an issue when VRF (data VRF or management VRF) is also created in the system. When any VRF (data VRF or management VRF) is created, a new rule is getting added automatically by kernel as "1000: from all lookup [l3mdev-table]". This l3mdev IP rule is never getting deleted even if VRF is deleted. Once if this l3mdev IP rule is added, if user configures IP address for the eth0 interface, interfaces.j2 adds an eth0 IP rule as "1000:from 100.104.47.74 lookup default ". Priority 1000 is automatically chosen by kernel and hence this rule gets higher priority than the already existing rule "1001:from all lookup local ". This results in an issue "ping from console to eth0 IP does not work once if VRF is created" as explained in Issue 551. More details and possible solutions are explained as comments in the Issue551. This PR is to resolve the issue by always fixing the low priority 32765 for the IP rule that is created for the eth0 IP address. Tested with various combinations of VRF creation, deletion and IP address configuration along with ping from console to eth0 IP address. Co-authored-by: Kannan KVS --- files/image_config/interfaces/interfaces.j2 | 4 ++-- .../tests/sample_output/py2/interfaces | 8 ++++---- .../tests/sample_output/py2/mvrf_interfaces | 8 ++++---- .../tests/sample_output/py3/interfaces | 8 ++++---- .../tests/sample_output/py3/mvrf_interfaces | 8 ++++---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 1136c0970db0..af3f807fc7df 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -78,14 +78,14 @@ iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static # management port up rules up ip {{ '-4' if prefix | ipv4 else '-6' }} route add default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} metric 201 up ip {{ '-4' if prefix | ipv4 else '-6' }} route add {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} - up ip {{ '-4' if prefix | ipv4 else '-6' }} rule add from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} + up ip {{ '-4' if prefix | ipv4 else '-6' }} rule add pref 32765 from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} up ip rule add to {{ route }} table {{ vrf_table }} {% endfor %} # management port down rules pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} - pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} + pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete pref 32765 from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} pre-down ip rule delete to {{ route }} table {{ vrf_table }} {% endfor %} diff --git a/src/sonic-config-engine/tests/sample_output/py2/interfaces b/src/sonic-config-engine/tests/sample_output/py2/interfaces index f5929119703c..6e952d6f71ea 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/interfaces +++ b/src/sonic-config-engine/tests/sample_output/py2/interfaces @@ -21,11 +21,11 @@ iface eth0 inet static # management port up rules up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 up ip -4 route add 10.0.0.0/24 dev eth0 table default - up ip -4 rule add from 10.0.0.100/32 table default + up ip -4 rule add pref 32765 from 10.0.0.100/32 table default # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default - pre-down ip -4 rule delete from 10.0.0.100/32 table default + pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table default iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 @@ -35,11 +35,11 @@ iface eth0 inet6 static # management port up rules up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table default metric 201 up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default - up ip -6 rule add from 2603:10e2:0:2902::8/128 table default + up ip -6 rule add pref 32765 from 2603:10e2:0:2902::8/128 table default # management port down rules pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default - pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table default + pre-down ip -6 rule delete pref 32765 from 2603:10e2:0:2902::8/128 table default # source /etc/network/interfaces.d/* # diff --git a/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces index 49d307aa2df7..7042901c093a 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces @@ -31,11 +31,11 @@ iface eth0 inet static # management port up rules up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 - up ip -4 rule add from 10.0.0.100/32 table 5000 + up ip -4 rule add pref 32765 from 10.0.0.100/32 table 5000 # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 - pre-down ip -4 rule delete from 10.0.0.100/32 table 5000 + pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table 5000 iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 @@ -46,11 +46,11 @@ iface eth0 inet6 static # management port up rules up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table 5000 metric 201 up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table 5000 - up ip -6 rule add from 2603:10e2:0:2902::8/128 table 5000 + up ip -6 rule add pref 32765 from 2603:10e2:0:2902::8/128 table 5000 # management port down rules pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 - pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 + pre-down ip -6 rule delete pref 32765 from 2603:10e2:0:2902::8/128 table 5000 # source /etc/network/interfaces.d/* # diff --git a/src/sonic-config-engine/tests/sample_output/py3/interfaces b/src/sonic-config-engine/tests/sample_output/py3/interfaces index f5929119703c..6e952d6f71ea 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/interfaces +++ b/src/sonic-config-engine/tests/sample_output/py3/interfaces @@ -21,11 +21,11 @@ iface eth0 inet static # management port up rules up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 up ip -4 route add 10.0.0.0/24 dev eth0 table default - up ip -4 rule add from 10.0.0.100/32 table default + up ip -4 rule add pref 32765 from 10.0.0.100/32 table default # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default - pre-down ip -4 rule delete from 10.0.0.100/32 table default + pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table default iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 @@ -35,11 +35,11 @@ iface eth0 inet6 static # management port up rules up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table default metric 201 up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default - up ip -6 rule add from 2603:10e2:0:2902::8/128 table default + up ip -6 rule add pref 32765 from 2603:10e2:0:2902::8/128 table default # management port down rules pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default - pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table default + pre-down ip -6 rule delete pref 32765 from 2603:10e2:0:2902::8/128 table default # source /etc/network/interfaces.d/* # diff --git a/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces index 49d307aa2df7..7042901c093a 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces @@ -31,11 +31,11 @@ iface eth0 inet static # management port up rules up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 - up ip -4 rule add from 10.0.0.100/32 table 5000 + up ip -4 rule add pref 32765 from 10.0.0.100/32 table 5000 # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 - pre-down ip -4 rule delete from 10.0.0.100/32 table 5000 + pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table 5000 iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 @@ -46,11 +46,11 @@ iface eth0 inet6 static # management port up rules up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table 5000 metric 201 up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table 5000 - up ip -6 rule add from 2603:10e2:0:2902::8/128 table 5000 + up ip -6 rule add pref 32765 from 2603:10e2:0:2902::8/128 table 5000 # management port down rules pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 - pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 + pre-down ip -6 rule delete pref 32765 from 2603:10e2:0:2902::8/128 table 5000 # source /etc/network/interfaces.d/* # From f2a258aca9794e0ac8105b41082ed00e2a60b111 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sun, 1 Nov 2020 01:48:07 -0800 Subject: [PATCH 1312/1427] [docker-platform-monitor] Check if sonic_platform is available before installed (#5764) On Arista platforms, sonic_platform packages are not installed in the PMon container, but are rather mounted into the container from the host OS. Therefore, pip show sonic_platform will fail in the PMon container. This change will first check if we can import sonic_platform. If this fails, it will then fall back to checking if the package is installed. If both fail, it will attempt to install the package. --- dockers/docker-platform-monitor/start.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dockers/docker-platform-monitor/start.sh b/dockers/docker-platform-monitor/start.sh index d7e7c91db492..2f6dc61a8452 100755 --- a/dockers/docker-platform-monitor/start.sh +++ b/dockers/docker-platform-monitor/start.sh @@ -16,7 +16,7 @@ if [ -e /usr/share/sonic/platform/platform_wait ]; then fi # If the Python 2 sonic-platform package is not installed, try to install it -pip2 show sonic-platform > /dev/null 2>&1 +python2 -c "import sonic_platform" > /dev/null 2>&1 || pip2 show sonic-platform > /dev/null 2>&1 if [ $? -ne 0 ]; then SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py2-none-any.whl" echo "sonic-platform package not installed, attempting to install..." @@ -33,7 +33,7 @@ if [ $? -ne 0 ]; then fi # If the Python 3 sonic-platform package is not installed, try to install it -pip3 show sonic-platform > /dev/null 2>&1 +python3 -c "import sonic_platform" > /dev/null 2>&1 || pip3 show sonic-platform > /dev/null 2>&1 if [ $? -ne 0 ]; then SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py3-none-any.whl" echo "sonic-platform package not installed, attempting to install..." From 698b5544c96a3ca5f2b8b3ea405f0449b75357a6 Mon Sep 17 00:00:00 2001 From: Blueve <672454911@qq.com> Date: Mon, 2 Nov 2020 10:31:15 +0800 Subject: [PATCH 1313/1427] [openssh] Introduce custom openssh-server package for supporting reverse console SSH (#5717) * Build and install openssh from source * Copy openssh deb package to dest folder * Update make rule * Update sonic debian extension * Append empty line before EOF * Update openssh patch * Add openssh-server to base image dependency * Fix indent type * Fix comments * Use commit id instead of tag id and add comment Signed-off-by: Jing Kan jika@microsoft.com --- .../build_templates/sonic_debian_extension.j2 | 3 ++ rules/openssh.dep | 8 +++++ rules/openssh.mk | 14 ++++++++ slave.mk | 1 + src/openssh/Makefile | 28 +++++++++++++++ ...e-number-to-ssh-session-environment-.patch | 36 +++++++++++++++++++ src/openssh/patch/series | 1 + 7 files changed, 91 insertions(+) create mode 100644 rules/openssh.dep create mode 100644 rules/openssh.mk create mode 100644 src/openssh/Makefile create mode 100644 src/openssh/patch/0001-Put-style-as-line-number-to-ssh-session-environment-.patch create mode 100644 src/openssh/patch/series diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 34f864b6d21d..c322c58aa003 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -263,6 +263,9 @@ sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/conf.d/* sudo cp $IMAGE_CONFIGS/monit/process_checker $FILESYSTEM_ROOT/usr/bin/ sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/process_checker +# Install custom-built openssh sshd +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/openssh-server_*.deb + # Copy crontabs sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ diff --git a/rules/openssh.dep b/rules/openssh.dep new file mode 100644 index 000000000000..7450743e667b --- /dev/null +++ b/rules/openssh.dep @@ -0,0 +1,8 @@ +SPATH := $($(OPENSSH_SERVER)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/openssh.mk rules/openssh.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(OPENSSH_SERVER)_CACHE_MODE := GIT_CONTENT_SHA +$(OPENSSH_SERVER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(OPENSSH_SERVER)_DEP_FILES := $(DEP_FILES) diff --git a/rules/openssh.mk b/rules/openssh.mk new file mode 100644 index 000000000000..0cc3de621039 --- /dev/null +++ b/rules/openssh.mk @@ -0,0 +1,14 @@ +# openssh package + +OPENSSH_VERSION = 7.9p1-10+deb10u2 + +export OPENSSH_VERSION + +OPENSSH_SERVER = openssh-server_$(OPENSSH_VERSION)_$(CONFIGURED_ARCH).deb +$(OPENSSH_SERVER)_SRC_PATH = $(SRC_PATH)/openssh +SONIC_MAKE_DEBS += $(OPENSSH_SERVER) + +# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} +# are archived into debug one image to facilitate debugging. +# +DBG_SRC_ARCHIVE += openssh diff --git a/slave.mk b/slave.mk index a4a7f7a85897..ba82e717910d 100644 --- a/slave.mk +++ b/slave.mk @@ -802,6 +802,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(LIBPAM_TACPLUS) \ $(LIBNSS_TACPLUS) \ $(MONIT) \ + $(OPENSSH_SERVER) \ $(PYTHON_SWSSCOMMON) \ $(PYTHON3_SWSSCOMMON) \ $(SONIC_UTILITIES_DATA) \ diff --git a/src/openssh/Makefile b/src/openssh/Makefile new file mode 100644 index 000000000000..66c6f019619f --- /dev/null +++ b/src/openssh/Makefile @@ -0,0 +1,28 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = openssh-server_$(OPENSSH_VERSION)_$(CONFIGURED_ARCH).deb +DERIVED_TARGETS = openssh-server-dbgsym_$(OPENSSH_VERSION)_$(CONFIGURED_ARCH).deb + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Obtain openssh: https://salsa.debian.org/ssh-team/openssh/-/tree/debian/1%257.9p1-10+deb10u2 + rm -rf ./openssh-server + git clone https://salsa.debian.org/ssh-team/openssh.git openssh-server + pushd ./openssh-server + + # Check out tag: debian/1%7.9p1-10+deb10u2 + git checkout -b openssh-src -f 6d9ca74c48d9911342c6ca5aaac8a25974fa2619 + + # Apply patch series + stg init + stg import -s ../patch/series + + # Build package + sudo apt-get -y build-dep openssh + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/openssh/patch/0001-Put-style-as-line-number-to-ssh-session-environment-.patch b/src/openssh/patch/0001-Put-style-as-line-number-to-ssh-session-environment-.patch new file mode 100644 index 000000000000..a11c7bf46c37 --- /dev/null +++ b/src/openssh/patch/0001-Put-style-as-line-number-to-ssh-session-environment-.patch @@ -0,0 +1,36 @@ +From 6e8cca780dab4680292192058b90a4a28f35d4ab Mon Sep 17 00:00:00 2001 +From: Blueve +Date: Mon, 26 Oct 2020 06:44:59 +0000 +Subject: [PATCH 1/1] Put style as line number to ssh session environment + variable + +By default, the content between : and @ will be trimmed by sshd before it do +authentication and the trimmed string will be dropped silently. To use this +segment as line number for reverse SSH feature, we need to modify the source +code of OpenSSH and put this segment to a environment variable +SSH_TARGET_CONSOLE_LINE, then we can insert a short script into /etc/bash.bashrc +and run command consutil connect $SSH_TARGET_CONSOLE_LINE to enter the +management session automatically after user login. +--- + session.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/session.c b/session.c +index 19f38637e..654371447 100644 +--- a/session.c ++++ b/session.c +@@ -1209,6 +1209,11 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) + child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", + original_command); + ++ /* Take advantage of authentication style field */ ++ if (s->authctxt->style) ++ child_set_env(&env, &envsize, "SSH_TARGET_CONSOLE_LINE", ++ s->authctxt->style); ++ + if (debug_flag) { + /* dump the environment */ + fprintf(stderr, "Environment:\n"); +-- +2.25.1 + diff --git a/src/openssh/patch/series b/src/openssh/patch/series new file mode 100644 index 000000000000..a645ad25833f --- /dev/null +++ b/src/openssh/patch/series @@ -0,0 +1 @@ +0001-Put-style-as-line-number-to-ssh-session-environment-.patch From 98d370bcef6e6d3c4fed673cbe3af49cf22f1c9a Mon Sep 17 00:00:00 2001 From: lguohan Date: Sun, 1 Nov 2020 20:08:55 -0800 Subject: [PATCH 1314/1427] [submodule]: swss/sairedis module update (#5765) swss: * d7643f2 2020-11-01 | [tlm_teamd]: Make the destionation for std::transform() to use std::back_inserter() for allocating new space for the copied objects (#1490) (HEAD, origin/master, origin/HEAD) [pavel-shirshov] * 7fa7cd6 2020-10-31 | [vstest]: stablize fgnhg test (#1491) [lguohan] * 9b0696e 2020-10-29 | Create vnet tunnel map only if it doesn't exist (#1482) [Prince Sunny] * 0481e99 2020-10-29 | [acl] Update CRM to include LAG bindings for ACL tables (#1487) [Danny Allen] sairedis * 5df11f5 2020-11-01 | [syncd] Lower bulk missing api message level from error to info (#687) (HEAD, origin/master, origin/HEAD) [Kamil Cudnik] * dc73a1d 2020-10-30 | [saiplayer] Fix log messages (#686) [Kamil Cudnik] Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 2265f5483869..d7643f2c3fe6 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 2265f548386929b7827d1079efd453128f1ec1f9 +Subproject commit d7643f2c3fe6bdef79755e2594491e02234fd979 From 1be9c4a33addcd62a0277d72af4ce0a37ca9efa6 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Mon, 2 Nov 2020 15:56:02 +0800 Subject: [PATCH 1315/1427] [Mellanox] Update SDK 4.4.1956 and FW *.2008.1956 (#5768) * [Mellanox] Update SDK 4.4.1956 and FW *.2008.1956 * Update submoudle pointer for Switch-SDK-drivers --- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 1ec6ef208ea4..05e7ca7cc050 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2008.1912 +MLNX_SPC_FW_VERSION = 13.2008.1956 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2008.1912 +MLNX_SPC2_FW_VERSION = 29.2008.1956 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2008.1912 +MLNX_SPC3_FW_VERSION = 30.2008.1956 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index c2af09b31592..bea351d3e86b 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit c2af09b315928034a993e7b7cca4530e02dfbeab +Subproject commit bea351d3e86b36545508df061cb8425f40c77c5a diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 340eafa2e155..9639b03aa385 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,6 +1,6 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ MLNX_SDK_PKG_BASE_PATH = $(MLNX_SDK_BASE_PATH)/$(BLDENV)/ -MLNX_SDK_VERSION = 4.4.1912 +MLNX_SDK_VERSION = 4.4.1956 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 10ab46f7a0f489d3d68ed37fd03bc48593f0ac2c Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Mon, 2 Nov 2020 08:49:40 -0800 Subject: [PATCH 1316/1427] Revert "[docker-base]: Rate limit priority INFO and lower in syslog" (#5763) * This was a temporary fix for orchagent spamming log messages and causing rate limiting, leading to critical messages being dropped for the syslog. No longer needed since Azure/sonic-sairedis#680 was merged. --- dockers/docker-base-buster/etc/rsyslog.conf | 3 +-- dockers/docker-base-stretch/etc/rsyslog.conf | 3 +-- dockers/docker-base/etc/rsyslog.conf | 3 +-- files/image_config/rsyslog/rsyslog-container.conf.j2 | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/dockers/docker-base-buster/etc/rsyslog.conf b/dockers/docker-base-buster/etc/rsyslog.conf index 81e328f99d8a..ef249229ab1e 100644 --- a/dockers/docker-base-buster/etc/rsyslog.conf +++ b/dockers/docker-base-buster/etc/rsyslog.conf @@ -12,11 +12,10 @@ $ModLoad imuxsock # provides support for local system logging # -# Set a rate limit on messages from the container of priority INFO or lower (level 6 and above) +# Set a rate limit on messages from the container # $SystemLogRateLimitInterval 300 $SystemLogRateLimitBurst 20000 -$SystemLogRateLimitSeverity 6 #$ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability diff --git a/dockers/docker-base-stretch/etc/rsyslog.conf b/dockers/docker-base-stretch/etc/rsyslog.conf index 81e328f99d8a..ef249229ab1e 100644 --- a/dockers/docker-base-stretch/etc/rsyslog.conf +++ b/dockers/docker-base-stretch/etc/rsyslog.conf @@ -12,11 +12,10 @@ $ModLoad imuxsock # provides support for local system logging # -# Set a rate limit on messages from the container of priority INFO or lower (level 6 and above) +# Set a rate limit on messages from the container # $SystemLogRateLimitInterval 300 $SystemLogRateLimitBurst 20000 -$SystemLogRateLimitSeverity 6 #$ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability diff --git a/dockers/docker-base/etc/rsyslog.conf b/dockers/docker-base/etc/rsyslog.conf index 3964cffb9e30..4851ac784475 100644 --- a/dockers/docker-base/etc/rsyslog.conf +++ b/dockers/docker-base/etc/rsyslog.conf @@ -16,11 +16,10 @@ $ModLoad imuxsock # provides support for local system logging # -# Set a rate limit on messages from the container of priority INFO or lower (level 6 and above) +# Set a rate limit on messages from the container # $SystemLogRateLimitInterval 300 $SystemLogRateLimitBurst 20000 -$SystemLogRateLimitSeverity 6 #$ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability diff --git a/files/image_config/rsyslog/rsyslog-container.conf.j2 b/files/image_config/rsyslog/rsyslog-container.conf.j2 index 3d7009241bd6..d17fbb6767ba 100644 --- a/files/image_config/rsyslog/rsyslog-container.conf.j2 +++ b/files/image_config/rsyslog/rsyslog-container.conf.j2 @@ -12,11 +12,10 @@ $ModLoad imuxsock # provides support for local system logging # -# Set a rate limit on messages from the container of priority INFO or lower (level 6 and above) +# Set a rate limit on messages from the container # $SystemLogRateLimitInterval 300 $SystemLogRateLimitBurst 20000 -$SystemLogRateLimitSeverity 6 #$ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability From 9d7355287fb43d6f7a2543012fc9136ec5164366 Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 2 Nov 2020 16:59:47 -0800 Subject: [PATCH 1317/1427] [submodule]: update sairedis (#5772) * b458e6f 2020-11-02 | [syncd] Disable use bulk api by default (#688) (HEAD, origin/master, origin/HEAD) [Kamil Cudnik] * d978789 2020-11-01 | [syncd] Set modify redis flag in RedisSelectableChannel (#689) [Kamil Cudnik] * 5df11f5 2020-11-01 | [syncd] Lower bulk missing api message level from error to info (#687) [Kamil Cudnik] * dc73a1d 2020-10-30 | [saiplayer] Fix log messages (#686) [Kamil Cudnik] Signed-off-by: Guohan Lu --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 0bf336a3e895..b458e6fbc0b7 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 0bf336a3e895167357d5d2e5a988471e115522e8 +Subproject commit b458e6fbc0b7687919535d8ae35eeae2a2490e60 From 1158701edca34558166147b0c04a1405bdd9c571 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 3 Nov 2020 11:45:36 +0800 Subject: [PATCH 1318/1427] add pcied config files for mellanox platform (#5669) This PR has a dependency on community change to move PCIe config files from $PLATFORM/plugin folder to $PLATFORM/ folder - Why I did it To support PCIed daemon on Mellanox platforms - How I did it Add PCIed config yaml files for all Mellanox platforms Update pmon daemon config files for SimX platforms --- .../x86_64-mlnx_lssn2700-r0/pcie.yaml | 1 + .../mellanox/x86_64-mlnx_msn2010-r0/pcie.yaml | 83 ++++ .../mellanox/x86_64-mlnx_msn2100-r0/pcie.yaml | 83 ++++ .../mellanox/x86_64-mlnx_msn2410-r0/pcie.yaml | 1 + .../mellanox/x86_64-mlnx_msn2700-r0/pcie.yaml | 111 +++++ .../pmon_daemon_control.json | 4 +- .../mellanox/x86_64-mlnx_msn2740-r0/pcie.yaml | 83 ++++ .../mellanox/x86_64-mlnx_msn3420-r0/pcie.yaml | 1 + .../mellanox/x86_64-mlnx_msn3700-r0/pcie.yaml | 420 ++++++++++++++++++ .../pmon_daemon_control.json | 4 +- .../x86_64-mlnx_msn3700c-r0/pcie.yaml | 408 +++++++++++++++++ .../mellanox/x86_64-mlnx_msn3800-r0/pcie.yaml | 1 + .../x86_64-mlnx_msn4600c-r0/pcie.yaml | 419 +++++++++++++++++ .../mellanox/x86_64-mlnx_msn4700-r0/pcie.yaml | 1 + .../pmon_daemon_control.json | 4 +- 15 files changed, 1621 insertions(+), 3 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_lssn2700-r0/pcie.yaml create mode 100644 device/mellanox/x86_64-mlnx_msn2010-r0/pcie.yaml create mode 100644 device/mellanox/x86_64-mlnx_msn2100-r0/pcie.yaml create mode 120000 device/mellanox/x86_64-mlnx_msn2410-r0/pcie.yaml create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/pcie.yaml create mode 100644 device/mellanox/x86_64-mlnx_msn2740-r0/pcie.yaml create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/pcie.yaml create mode 100644 device/mellanox/x86_64-mlnx_msn3700-r0/pcie.yaml create mode 100644 device/mellanox/x86_64-mlnx_msn3700c-r0/pcie.yaml create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/pcie.yaml create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/pcie.yaml create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/pcie.yaml diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_lssn2700-r0/pcie.yaml new file mode 120000 index 000000000000..f739a7e8ec35 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/pcie.yaml @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pcie.yaml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn2010-r0/pcie.yaml new file mode 100644 index 000000000000..ca73122aaa81 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/pcie.yaml @@ -0,0 +1,83 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 1f0b + name: 'Host bridge: Intel Corporation Atom processor C2000 SoC Transaction Router + (rev 02)' +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1 (rev + 02)' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2 (rev + 02)' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3 (rev + 02)' +- bus: '00' + dev: 0b + fn: '0' + id: 1f18 + name: 'Co-processor: Intel Corporation Atom processor C2000 QAT (rev 02)' +- bus: '00' + dev: 0e + fn: '0' + id: 1f14 + name: 'Host bridge: Intel Corporation Atom processor C2000 RAS (rev 02)' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC (rev 02)' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0 (rev + 02)' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354 (rev 03)' +- bus: '00' + dev: '16' + fn: '0' + id: 1f2c + name: 'USB controller: Intel Corporation Atom processor C2000 USB Enhanced Host + Controller (rev 02)' +- bus: '00' + dev: '17' + fn: '0' + id: 1f22 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA2 Controller + (rev 02)' +- bus: '00' + dev: '18' + fn: '0' + id: 1f32 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA3 Controller + (rev 02)' +- bus: '00' + dev: 1f + fn: '0' + id: 1f38 + name: 'ISA bridge: Intel Corporation Atom processor C2000 PCU (rev 02)' +- bus: '00' + dev: 1f + fn: '3' + id: 1f3c + name: 'SMBus: Intel Corporation Atom processor C2000 PCU SMBus (rev 02)' +- bus: '01' + dev: '00' + fn: '0' + id: cb84 + name: 'Ethernet controller: Mellanox Technologies MT52100' diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn2100-r0/pcie.yaml new file mode 100644 index 000000000000..63f09eecde7c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/pcie.yaml @@ -0,0 +1,83 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 1f0b + name: 'Host bridge: Intel Corporation Atom processor C2000 SoC Transaction Router + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1 (rev + 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2 (rev + 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3 (rev + 03)' +- bus: '00' + dev: 0b + fn: '0' + id: 1f18 + name: 'Co-processor: Intel Corporation Atom processor C2000 QAT (rev 03)' +- bus: '00' + dev: 0e + fn: '0' + id: 1f14 + name: 'Host bridge: Intel Corporation Atom processor C2000 RAS (rev 03)' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC (rev 03)' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0 (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354 (rev 03)' +- bus: '00' + dev: '16' + fn: '0' + id: 1f2c + name: 'USB controller: Intel Corporation Atom processor C2000 USB Enhanced Host + Controller (rev 03)' +- bus: '00' + dev: '17' + fn: '0' + id: 1f22 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA2 Controller + (rev 03)' +- bus: '00' + dev: '18' + fn: '0' + id: 1f32 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA3 Controller + (rev 03)' +- bus: '00' + dev: 1f + fn: '0' + id: 1f38 + name: 'ISA bridge: Intel Corporation Atom processor C2000 PCU (rev 03)' +- bus: '00' + dev: 1f + fn: '3' + id: 1f3c + name: 'SMBus: Intel Corporation Atom processor C2000 PCU SMBus (rev 03)' +- bus: '01' + dev: '00' + fn: '0' + id: cb84 + name: 'Ethernet controller: Mellanox Technologies MT52100' diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn2410-r0/pcie.yaml new file mode 120000 index 000000000000..f739a7e8ec35 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/pcie.yaml @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pcie.yaml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn2700-r0/pcie.yaml new file mode 100644 index 000000000000..8796390b73c6 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/pcie.yaml @@ -0,0 +1,111 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '0154' + name: 'Host bridge: Intel Corporation 3rd Gen Core processor DRAM Controller (rev + 09)' +- bus: '00' + dev: '01' + fn: '0' + id: '0151' + name: 'PCI bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor PCI + Express Root Port (rev 09)' +- bus: '00' + dev: '01' + fn: '1' + id: '0155' + name: 'PCI bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor PCI + Express Root Port (rev 09)' +- bus: '00' + dev: '01' + fn: '2' + id: 0159 + name: 'PCI bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor PCI + Express Root Port (rev 09)' +- bus: '00' + dev: '04' + fn: '0' + id: '0153' + name: 'Signal processing controller: Intel Corporation 3rd Gen Core Processor Thermal + Subsystem (rev 09)' +- bus: '00' + dev: '16' + fn: '0' + id: 1e3a + name: 'Communication controller: Intel Corporation 7 Series/C216 Chipset Family + MEI Controller #1 (rev 04)' +- bus: '00' + dev: '19' + fn: '0' + id: '1502' + name: 'Ethernet controller: Intel Corporation 82579LM Gigabit Network Connection + (rev 04)' +- bus: '00' + dev: 1a + fn: '0' + id: 1e2d + name: 'USB controller: Intel Corporation 7 Series/C216 Chipset Family USB Enhanced + Host Controller #2 (rev 04)' +- bus: '00' + dev: 1c + fn: '0' + id: 1e10 + name: 'PCI bridge: Intel Corporation 7 Series/C216 Chipset Family PCI Express Root + Port 1 (rev c4)' +- bus: '00' + dev: 1c + fn: '4' + id: 1e18 + name: 'PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express + Root Port 5 (rev c4)' +- bus: '00' + dev: 1c + fn: '6' + id: 1e1c + name: 'PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express + Root Port 7 (rev c4)' +- bus: '00' + dev: 1c + fn: '7' + id: 1e1e + name: 'PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express + Root Port 8 (rev c4)' +- bus: '00' + dev: 1d + fn: '0' + id: 1e26 + name: 'USB controller: Intel Corporation 7 Series/C216 Chipset Family USB Enhanced + Host Controller #1 (rev 04)' +- bus: '00' + dev: 1f + fn: '0' + id: 1e55 + name: 'ISA bridge: Intel Corporation QM77 Express Chipset LPC Controller (rev 04)' +- bus: '00' + dev: 1f + fn: '2' + id: 1e03 + name: 'SATA controller: Intel Corporation 7 Series Chipset Family 6-port SATA Controller + [AHCI mode] (rev 04)' +- bus: '00' + dev: 1f + fn: '3' + id: 1e22 + name: 'SMBus: Intel Corporation 7 Series/C216 Chipset Family SMBus Controller (rev + 04)' +- bus: '00' + dev: 1f + fn: '6' + id: 1e24 + name: 'Signal processing controller: Intel Corporation 7 Series/C210 Series Chipset + Family Thermal Management Controller (rev 04)' +- bus: '03' + dev: '00' + fn: '0' + id: cb84 + name: 'Ethernet controller: Mellanox Technologies MT52100' +- bus: '06' + dev: '00' + fn: '0' + id: 150c + name: 'Ethernet controller: Intel Corporation 82583V Gigabit Network Connection' diff --git a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/pmon_daemon_control.json index 40fc367acf32..dd83c2db12c5 100644 --- a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/pmon_daemon_control.json +++ b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/pmon_daemon_control.json @@ -1,5 +1,7 @@ { "skip_ledd": true, "skip_xcvrd": true, - "skip_psud": true + "skip_psud": true, + "skip_pcied": true, + "skip_thermalctld": true } diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn2740-r0/pcie.yaml new file mode 100644 index 000000000000..ca73122aaa81 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/pcie.yaml @@ -0,0 +1,83 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 1f0b + name: 'Host bridge: Intel Corporation Atom processor C2000 SoC Transaction Router + (rev 02)' +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1 (rev + 02)' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2 (rev + 02)' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3 (rev + 02)' +- bus: '00' + dev: 0b + fn: '0' + id: 1f18 + name: 'Co-processor: Intel Corporation Atom processor C2000 QAT (rev 02)' +- bus: '00' + dev: 0e + fn: '0' + id: 1f14 + name: 'Host bridge: Intel Corporation Atom processor C2000 RAS (rev 02)' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC (rev 02)' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0 (rev + 02)' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354 (rev 03)' +- bus: '00' + dev: '16' + fn: '0' + id: 1f2c + name: 'USB controller: Intel Corporation Atom processor C2000 USB Enhanced Host + Controller (rev 02)' +- bus: '00' + dev: '17' + fn: '0' + id: 1f22 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA2 Controller + (rev 02)' +- bus: '00' + dev: '18' + fn: '0' + id: 1f32 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA3 Controller + (rev 02)' +- bus: '00' + dev: 1f + fn: '0' + id: 1f38 + name: 'ISA bridge: Intel Corporation Atom processor C2000 PCU (rev 02)' +- bus: '00' + dev: 1f + fn: '3' + id: 1f3c + name: 'SMBus: Intel Corporation Atom processor C2000 PCU SMBus (rev 02)' +- bus: '01' + dev: '00' + fn: '0' + id: cb84 + name: 'Ethernet controller: Mellanox Technologies MT52100' diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn3420-r0/pcie.yaml new file mode 120000 index 000000000000..3dc31739f7d9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/pcie.yaml @@ -0,0 +1 @@ +../x86_64-mlnx_msn3700c-r0/pcie.yaml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn3700-r0/pcie.yaml new file mode 100644 index 000000000000..947e9f43f8b3 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/pcie.yaml @@ -0,0 +1,420 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '03' + fn: '2' + id: 6f0a + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1c + fn: '7' + id: 8c1e + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #8 (rev d5)' +- bus: '00' + dev: 1d + fn: '0' + id: 8c26 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + EHCI #1 (rev 05)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '06' + dev: '00' + fn: '0' + id: cf6c + name: 'Ethernet controller: Mellanox Technologies MT53100 [Spectrum-2, 64 x 100GbE + switch]' +- bus: 08 + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: 6f76 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link Debug (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '2' + id: 6fe2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '3' + id: 6fe3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/device/mellanox/x86_64-mlnx_msn3700_simx-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/pmon_daemon_control.json index 40fc367acf32..dd83c2db12c5 100644 --- a/device/mellanox/x86_64-mlnx_msn3700_simx-r0/pmon_daemon_control.json +++ b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/pmon_daemon_control.json @@ -1,5 +1,7 @@ { "skip_ledd": true, "skip_xcvrd": true, - "skip_psud": true + "skip_psud": true, + "skip_pcied": true, + "skip_thermalctld": true } diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn3700c-r0/pcie.yaml new file mode 100644 index 000000000000..21c48fe64008 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/pcie.yaml @@ -0,0 +1,408 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '03' + fn: '2' + id: 6f0a + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1c + fn: '7' + id: 8c1e + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #8 (rev d5)' +- bus: '00' + dev: 1d + fn: '0' + id: 8c26 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + EHCI #1 (rev 05)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '06' + dev: '00' + fn: '0' + id: cf6c + name: 'Ethernet controller: Mellanox Technologies MT53100 [Spectrum-2, 64 x 100GbE + switch]' +- bus: 08 + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: 6f76 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link Debug (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn3800-r0/pcie.yaml new file mode 120000 index 000000000000..d4a25d40bd54 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/pcie.yaml @@ -0,0 +1 @@ +../x86_64-mlnx_msn3700-r0/pcie.yaml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn4600c-r0/pcie.yaml new file mode 100644 index 000000000000..dcfdf1c9a59c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/pcie.yaml @@ -0,0 +1,419 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '03' + fn: '2' + id: 6f0a + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1c + fn: '7' + id: 8c1e + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #8 (rev d5)' +- bus: '00' + dev: 1d + fn: '0' + id: 8c26 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + EHCI #1 (rev 05)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '06' + dev: '00' + fn: '0' + id: cf70 + name: 'Ethernet controller: Mellanox Technologies Device cf70' +- bus: 08 + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: 6f76 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link Debug (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '2' + id: 6fe2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '3' + id: 6fe3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn4700-r0/pcie.yaml new file mode 120000 index 000000000000..187649f4b860 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/pcie.yaml @@ -0,0 +1 @@ +../x86_64-mlnx_msn4600c-r0/pcie.yaml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json index 40fc367acf32..dd83c2db12c5 100644 --- a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json @@ -1,5 +1,7 @@ { "skip_ledd": true, "skip_xcvrd": true, - "skip_psud": true + "skip_psud": true, + "skip_pcied": true, + "skip_thermalctld": true } From 84d3a2600080cff33ab7277a70ff95bde51b2875 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 2 Nov 2020 20:31:14 -0800 Subject: [PATCH 1319/1427] [sonic-py-swsssdk] Update submodule (#5757) Commits included: * src/sonic-py-swsssdk 748c404...1ea30d2 (1): > Fix bug: ConfigDBConnector.get_table does not work in python3 (#92) --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 748c40422dff..1ea30d2e27bf 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 748c40422dff1f60b43ca237bb067772e1dcb10d +Subproject commit 1ea30d2e27bf4e9c9127611e72f5b3bd74025731 From 0a1c5792a1a564cea3459a4c7302f7b8b62364ff Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Tue, 3 Nov 2020 21:26:26 +0200 Subject: [PATCH 1320/1427] [BFN] Updated SDK packages to 20201023 (#5708) - BFN platform was affected by ACL changes that add IPV6_NEXT_HEADER support. - Bugfixes Signed-off-by: Andriy Kokhan --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 274eb9575151..df1c58592a2f 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20201009_deb9.deb +BFN_PLATFORM = bfnplatform_20201023_deb9.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 85ba488409a8..2b16e4ef35d4 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20201009_deb9.deb +BFN_SAI = bfnsdk_20201023_deb9.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) From e3164d5fb4a4b342fa5c1c8626081e64b4a6142f Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 3 Nov 2020 12:50:11 -0800 Subject: [PATCH 1321/1427] [lldpmgrd] Convert to Python 3 (#5785) - Convert lldpmgrd to Python 3 - Install Python 3 swsscommon package in docker-lldp --- dockers/docker-lldp/lldpmgrd | 16 +++++++--------- rules/docker-lldp.mk | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/dockers/docker-lldp/lldpmgrd b/dockers/docker-lldp/lldpmgrd index 5a421eb55cd6..c066cc34d09f 100755 --- a/dockers/docker-lldp/lldpmgrd +++ b/dockers/docker-lldp/lldpmgrd @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ lldpmgrd @@ -18,10 +18,8 @@ try: import os import subprocess import sys - - import syslog - import os.path import time + from sonic_py_common import daemon_base from swsscommon import swsscommon except ImportError as err: @@ -74,7 +72,7 @@ class LldpManager(daemon_base.DaemonBase): port_table_dict = dict(fvp) # Get the oper-status for the port - if port_table_dict.has_key("oper_status"): + if "oper_status" in port_table_dict: port_oper_status = port_table_dict.get("oper_status") self.log_info("Port name {} oper status: {}".format(port_name, port_oper_status)) return port_oper_status == "up" @@ -131,7 +129,7 @@ class LldpManager(daemon_base.DaemonBase): # List of port names (keys of elements) to delete from self.pending_cmds to_delete = [] - for (port_name, cmd) in self.pending_cmds.iteritems(): + for (port_name, cmd) in self.pending_cmds.items(): self.log_debug("Running command: '{}'".format(cmd)) rc, stderr = run_cmd(self, cmd) @@ -195,7 +193,7 @@ class LldpManager(daemon_base.DaemonBase): fvp_dict = dict(fvp) # handle config change - if (fvp_dict.has_key("alias") or fvp_dict.has_key("description")) and (op in ["SET", "DEL"]): + if ("alias" in fvp_dict or "description" in fvp_dict) and (op in ["SET", "DEL"]): if self.is_port_up(key): self.generate_pending_lldp_config_cmd_for_port(key) else: @@ -207,7 +205,7 @@ class LldpManager(daemon_base.DaemonBase): fvp_dict = dict(fvp) # handle port status change - if fvp_dict.has_key("oper_status"): + if "oper_status" in fvp_dict: if "up" in fvp_dict.get("oper_status"): self.generate_pending_lldp_config_cmd_for_port(key) else: @@ -245,7 +243,7 @@ def main(): lldpmgr.run() def run_cmd(self, cmd): - proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdout, stderr) = proc.communicate() return proc.returncode, stderr diff --git a/rules/docker-lldp.mk b/rules/docker-lldp.mk index af3d77a1c8c1..36c8a3a3536d 100644 --- a/rules/docker-lldp.mk +++ b/rules/docker-lldp.mk @@ -6,7 +6,7 @@ DOCKER_LLDP_DBG = $(DOCKER_LLDP_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_LLDP)_PATH = $(DOCKERS_PATH)/docker-lldp -$(DOCKER_LLDP)_DEPENDS += $(LLDPD) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) +$(DOCKER_LLDP)_DEPENDS += $(LLDPD) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(PYTHON3_SWSSCOMMON) $(DOCKER_LLDP)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_LLDP)_DBG_DEPENDS += $(LLDPD_DBG) $(LIBSWSSCOMMON_DBG) From 215ce13890b3cbffa56b097a3d9463cd3bc89447 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Tue, 3 Nov 2020 14:28:42 -0800 Subject: [PATCH 1322/1427] [swss-common]: Advance submodule (#5780) 9b0e955 2020-10-30 | [schema]: Add MACsec support (#403) [Ze Gan] f24dc97 2020-10-28 | Implementation of System ports initialization, Interface & Neighbor Synchronization... (#380) [minionatwork] 91e0885 2020-10-27 | Mux cable schema definitions (#398) [Prince Sunny] d0cedea 2020-10-27 | Change log level (#402) [Prince Sunny] 64b3cfe 2020-10-24 | SonicV2Connector supports host and decode_responses in constructor parameters (#401) [Qi Luo] f8b0065 2020-10-23 | Implement FieldValueMap update method (#400) [Qi Luo] --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 3ec30ef36aef..9b0e955abab0 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 3ec30ef36aef70052fbe06af427174041cda4c81 +Subproject commit 9b0e955abab0d8c5b6a86f43b635591d11c61ef6 From 4ed2ff805f9a7c93ad7ce4724738ed5e7cebc90c Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 4 Nov 2020 05:49:52 -0800 Subject: [PATCH 1323/1427] [swss-common]: Advance submodule (#5799) ec96868 2020-11-03 | Fix: treat DBConnector timeout=0 as infinite timeout (#408) [Qi Luo] b4b8334 2020-11-03 | Add lua script for redis multi keys api hmset and del (#406) [Kamil Cudnik] --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 9b0e955abab0..ec9686856749 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 9b0e955abab0d8c5b6a86f43b635591d11c61ef6 +Subproject commit ec9686856749ac61817968737040e943d0b14cb3 From ac3a605c75c1d39fc9e08f8514f07a0321d0a519 Mon Sep 17 00:00:00 2001 From: dflynn-Nokia <60479697+dflynn-Nokia@users.noreply.github.com> Date: Wed, 4 Nov 2020 12:31:06 -0500 Subject: [PATCH 1324/1427] [build]: ARM build: Download redis-tools and redis-server from sonicstorage (#5797) Prevent intermittent build failures when building Sonic for the ARM platform architecture due to version upgrades of the redis-tools and redis-server packages. Modify select Dockerfile templates to download the redis-tools and redis-server packages from sonicstorage rather than from debian.org. This PR has been made possible by the inclusion of ARM versions of redis-tools and redis-server into sonicstorage as described in Issue# 5701 --- dockers/docker-base-buster/Dockerfile.j2 | 10 ++++++++++ dockers/docker-database/Dockerfile.j2 | 14 +++++++++++++- platform/vs/docker-sonic-vs/Dockerfile.j2 | 14 +++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index a7919b8800a3..f113750450d7 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -76,9 +76,19 @@ RUN apt-get update && \ libzmq5 # Install redis-tools +{% if CONFIGURED_ARCH == "armhf" %} +RUN curl -k -o redis-tools_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=67vHAMxsl%2BS3X1KsqhdYhakJkGdg5FKSPgU8kUiw4as%3D&se=2030-10-24T04%3A22%3A40Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_armhf.deb || apt-get install -f -y +RUN rm redis-tools_6.0.6-1~bpo10+1_armhf.deb +{% elif CONFIGURED_ARCH == "arm64" %} +RUN curl -o redis-tools_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=GbkJV2wWln3hoz27zKi5erdk3NDKrAFrQriA97bcRCY%3D&se=2030-10-24T04%3A22%3A21Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_arm64.deb || apt-get install -f -y +RUN rm redis-tools_6.0.6-1~bpo10+1_arm64.deb +{% else %} RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f -y RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb +{% endif %} # For templating RUN pip2 install j2cli diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index aeaa61614406..84f485e4fe83 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -10,11 +10,23 @@ ENV DEBIAN_FRONTEND=noninteractive # Update apt's cache of available packages RUN apt-get update -# install redis-server +# Install redis-server +{% if CONFIGURED_ARCH == "armhf" %} +RUN curl -k -o redis-tools_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=67vHAMxsl%2BS3X1KsqhdYhakJkGdg5FKSPgU8kUiw4as%3D&se=2030-10-24T04%3A22%3A40Z&sp=r" +RUN curl -k -o redis-server_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=xTdayvm0RBguxi9suyv855jKRjU%2FmKQ8nHuct4WSX%2FA%3D&se=2030-10-24T04%3A22%3A05Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_armhf.deb redis-server_6.0.6-1~bpo10+1_armhf.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_armhf.deb redis-server_6.0.6-1~bpo10+1_armhf.deb +{% elif CONFIGURED_ARCH == "arm64" %} +RUN curl -o redis-tools_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=GbkJV2wWln3hoz27zKi5erdk3NDKrAFrQriA97bcRCY%3D&se=2030-10-24T04%3A22%3A21Z&sp=r" +RUN curl -o redis-server_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=622w2KzIKIjAaaA0Bz12MzU%2BUBzY2AiXFIFfuKNoKSk%3D&se=2030-10-24T04%3A21%3A44Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_arm64.deb redis-server_6.0.6-1~bpo10+1_arm64.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_arm64.deb redis-server_6.0.6-1~bpo10+1_arm64.deb +{% else %} RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" RUN curl -o redis-server_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=2Ketg7BmkZEaTxR%2FgvAFVmhjn7ywdmkc7l2T2rsL57o%3D&se=2030-09-06T19%3A45%3A20Z&sp=r" RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb +{% endif %} {% if docker_database_debs.strip() -%} # Copy locally-built Debian package dependencies diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index f254951d311b..b42b736e452c 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -55,11 +55,23 @@ RUN apt-get install -y net-tools \ # For using Python m2crypto package openssl -# install redis-server +# Install redis-server +{% if CONFIGURED_ARCH == "armhf" %} +RUN curl -k -o redis-tools_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=67vHAMxsl%2BS3X1KsqhdYhakJkGdg5FKSPgU8kUiw4as%3D&se=2030-10-24T04%3A22%3A40Z&sp=r" +RUN curl -k -o redis-server_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=xTdayvm0RBguxi9suyv855jKRjU%2FmKQ8nHuct4WSX%2FA%3D&se=2030-10-24T04%3A22%3A05Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_armhf.deb redis-server_6.0.6-1~bpo10+1_armhf.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_armhf.deb redis-server_6.0.6-1~bpo10+1_armhf.deb +{% elif CONFIGURED_ARCH == "arm64" %} +RUN curl -o redis-tools_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=GbkJV2wWln3hoz27zKi5erdk3NDKrAFrQriA97bcRCY%3D&se=2030-10-24T04%3A22%3A21Z&sp=r" +RUN curl -o redis-server_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=622w2KzIKIjAaaA0Bz12MzU%2BUBzY2AiXFIFfuKNoKSk%3D&se=2030-10-24T04%3A21%3A44Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_arm64.deb redis-server_6.0.6-1~bpo10+1_arm64.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_arm64.deb redis-server_6.0.6-1~bpo10+1_arm64.deb +{% else %} RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" RUN curl -o redis-server_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=2Ketg7BmkZEaTxR%2FgvAFVmhjn7ywdmkc7l2T2rsL57o%3D&se=2030-09-06T19%3A45%3A20Z&sp=r" RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb +{% endif %} RUN pip2 install setuptools RUN pip3 install setuptools From 194c7a97cd4f85c50fa75b682945f5c725b5c643 Mon Sep 17 00:00:00 2001 From: Kalimuthu-Velappan <53821802+Kalimuthu-Velappan@users.noreply.github.com> Date: Thu, 5 Nov 2020 00:42:26 +0530 Subject: [PATCH 1325/1427] [build]: Fix for - execvp: /bin/bash: Argument list too long error (#5809) Fix #5692 It fixes the folling error when DPKG cache enabled. make: execvp: /bin/bash: Argument list too long make: *** [slave.mk:389: target/debs/buster/sonic-device-data_1.0-1_all.deb] Error 127 - Why I did it Number of dependent file list is more than 2K which causes bash arg long error. - How I did it Used file operation to store the dependency list. --- Makefile.cache | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.cache b/Makefile.cache index 3c45cec3a97f..4d15cdbf1114 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -325,9 +325,9 @@ define SHOW_WHY @echo "[ FLAGS FILE ] : [$($(1)_FILE_FLAGS)] " >> $($(1)_DST_PATH)/$(1).log @echo "[ FLAGS DEPENDS ] : [$($(1)_DEP_FLAGS_ALL)] " >> $($(1)_DST_PATH)/$(1).log @echo "[ FLAGS DIFF ] : [$($(1)_FLAGS_DIFF)] " >> $($(1)_DST_PATH)/$(1).log - @echo "[ DEP DEPENDS ] : [$($(1)_DEP_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log - @echo "[ SMDEP DEPENDS ] : [$($(1)_SMDEP_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log - @echo "[ TARGET DEPENDS ] : [$?] " >> $($(1)_DST_PATH)/$(1).log + @$(file >>$($(1)_DST_PATH)/$(1).log, "[ DEP DEPENDS ] : [$($(1)_DEP_FILES_MODIFIED)] ") + @$(file >>$($(1)_DST_PATH)/$(1).log, "[ SMDEP DEPENDS ] : [$($(1)_SMDEP_FILES_MODIFIED)] ") + @$(file >>$($(1)_DST_PATH)/$(1).log, "[ TARGET DEPENDS ] : [$?] ") endef From ba7fda7fd1634081dfb3995464622019e65fe5eb Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 4 Nov 2020 11:23:03 -0800 Subject: [PATCH 1326/1427] [docker-platform-monitor] Install Python 2 'enum34' package to fix Arista platforms (#5779) Recent changes to dependencies caused the 'enum34' package to cease being installed for Python 2 in the PMon container. This broke Arista platforms, where the Arista sonic_platform package imports 'enum'. This is because on Arista devices, the sonic_platform wheel is not installed in the container. Instead, the installation directory is mounted from the host OS. However, this method doesn't ensure all dependencies are installed in the container. --- dockers/docker-platform-monitor/Dockerfile.j2 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index 75852395bf70..0dd5b8fc75b5 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -21,6 +21,16 @@ RUN apt-get update && \ dmidecode \ i2c-tools +# On Arista devices, the sonic_platform wheel is not installed in the container. +# Instead, the installation directory is mounted from the host OS. However, this method +# doesn't ensure all dependencies are installed in the container. So here we +# install any dependencies required by the Arista sonic_platform package. +# TODO: eliminate the need to install these explicitly. +# NOTE: Only install enum34 for Python 2, as our version of Python 3 is 3.7, which +# contains 'enum' as part of the standard library. Installing enum34 there will +# cause conflicts. +RUN pip2 install enum34 + {% if docker_platform_monitor_debs.strip() -%} # Copy locally-built Debian package dependencies {{ copy_files("debs/", docker_platform_monitor_debs.split(' '), "/debs/") }} From d3262d10f739599786d9973bdd7c7f122094309e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 4 Nov 2020 15:06:44 -0800 Subject: [PATCH 1327/1427] [generate_asic_config_checksum.py] Convert to Python 3 (#5783) - Convert script to Python 3 - Need to open file in binary mode before hashing due to new string data type in Python 3 being unicode by default. This should probably have been done regardless. - Reorganize imports alphabetically - When running the script, don't explicitly call `python`. Instead let the program loader use the interpreter specified in the shebang (which is now `python3`). --- build_debian.sh | 3 ++- files/build_scripts/generate_asic_config_checksum.py | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) mode change 100644 => 100755 files/build_scripts/generate_asic_config_checksum.py diff --git a/build_debian.sh b/build_debian.sh index db736d16946e..2bb284182db1 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -463,7 +463,8 @@ EOF sudo cp ./files/scripts/core_cleanup.py $FILESYSTEM_ROOT/usr/bin/core_cleanup.py ## Copy ASIC config checksum -python files/build_scripts/generate_asic_config_checksum.py +sudo chmod 755 files/build_scripts/generate_asic_config_checksum.py +./files/build_scripts/generate_asic_config_checksum.py if [[ ! -f './asic_config_checksum' ]]; then echo 'asic_config_checksum not found' exit 1 diff --git a/files/build_scripts/generate_asic_config_checksum.py b/files/build_scripts/generate_asic_config_checksum.py old mode 100644 new mode 100755 index 638259ce938a..41ef6f045e21 --- a/files/build_scripts/generate_asic_config_checksum.py +++ b/files/build_scripts/generate_asic_config_checksum.py @@ -1,8 +1,8 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import syslog -import os import hashlib +import os +import syslog SYSLOG_IDENTIFIER = 'asic_config_checksum' @@ -45,7 +45,7 @@ def generate_checksum(checksum_files): checksum = hashlib.sha1() for checksum_file in checksum_files: try: - with open(checksum_file, 'r') as f: + with open(checksum_file, 'rb') as f: for chunk in iter(lambda: f.read(CHUNK_SIZE), b""): checksum.update(chunk) except IOError as e: From ce6286eb84a60a74c839a551467e30f64e6bd50b Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 5 Nov 2020 08:24:53 +0800 Subject: [PATCH 1328/1427] [device/accton] Remove the use of python pickle package (#5475) Pickle is applied to save the order of i2c adapters at installation. With pickle removed, it just checks the order of i2c buses every time it needs. --- .../plugins/sfputil.py | 19 +++++++------------ .../plugins/sfputil.py | 18 +++++++----------- .../as5712-54x/utils/accton_as5712_util.py | 17 +++++------------ .../as5812-54x/utils/accton_as5812_util.py | 17 +++++------------ 4 files changed, 24 insertions(+), 47 deletions(-) diff --git a/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py index 5647c84a35db..44399d1e64ee 100755 --- a/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py @@ -5,7 +5,6 @@ try: import time import os - import pickle from ctypes import create_string_buffer from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: @@ -83,16 +82,13 @@ def __init__(self): #Two i2c buses might get flipped order, check them both. def update_i2c_order(self): - if os.path.exists("/tmp/accton_util.p"): - self.I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) - else: - if self.I2C_BUS_ORDER < 0: - eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" - if os.path.exists(eeprom_path): - self.I2C_BUS_ORDER = 0 - eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" - if os.path.exists(eeprom_path): - self.I2C_BUS_ORDER = 1 + if self.I2C_BUS_ORDER < 0: + eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 0 + eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 1 return self.I2C_BUS_ORDER def get_presence(self, port_num): @@ -285,4 +281,3 @@ def get_transceiver_change_event(self, timeout=2000): else: return True, {} return False, {} - diff --git a/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py index 62b9db604363..008b2fdd9cf5 100755 --- a/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py @@ -5,7 +5,6 @@ try: import time import os - import pickle from ctypes import create_string_buffer from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: @@ -132,16 +131,13 @@ def __init__(self): #Two i2c buses might get flipped order, check them both. def update_i2c_order(self): - if os.path.exists("/tmp/accton_util.p"): - self.I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) - else: - if self.I2C_BUS_ORDER < 0: - eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" - if os.path.exists(eeprom_path): - self.I2C_BUS_ORDER = 0 - eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" - if os.path.exists(eeprom_path): - self.I2C_BUS_ORDER = 1 + if self.I2C_BUS_ORDER < 0: + eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 0 + eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 1 return self.I2C_BUS_ORDER def get_presence(self, port_num): diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py index 100af5bac826..944fb98ada54 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py @@ -35,7 +35,6 @@ import logging import re import time -import pickle from collections import namedtuple PROJECT_NAME = 'as5712_54x' @@ -295,30 +294,26 @@ def i2c_order_check(): # i2c bus 0 and 1 might be installed in different order. # Here check if 0x70 is exist @ i2c-0 tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device" - status, output = log_os_system(tmp, 0) + log_os_system(tmp, 0) if not device_exist(): order = 1 else: order = 0 tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device" - status, output = log_os_system(tmp, 0) + log_os_system(tmp, 0) return order def update_i2c_order(): global I2C_BUS_ORDER order = i2c_order_check() - pickle.dump(order, open("/tmp/accton_util.p", "wb")) # save it I2C_BUS_ORDER = order print "[%s]Detected I2C_BUS_ORDER:%d" % (os.path.basename(__file__), I2C_BUS_ORDER) def get_i2c_order(): global I2C_BUS_ORDER if I2C_BUS_ORDER < 0: - if os.path.exists("/tmp/accton_util.p"): - I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) - else: - update_i2c_order() + update_i2c_order() def device_install(): global FORCE @@ -369,10 +364,7 @@ def device_install(): def device_uninstall(): global FORCE - global I2C_BUS_ORDER - get_i2c_order() - order = I2C_BUS_ORDER for i in range(0,len(sfp_map)): target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" status, output =log_os_system("echo 0x50 > "+ target, 1) @@ -380,7 +372,8 @@ def device_uninstall(): print output if FORCE == 0: return status - + status, output = log_os_system("ls /sys/bus/i2c/devices/1-0070", 0) + order = 0 if (status == 0) else 1 if order == 0: nodelist = mknod else: diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py index eb1b22f3ef0d..ba526d110a7b 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py @@ -35,7 +35,6 @@ import logging import re import time -import pickle from collections import namedtuple PROJECT_NAME = 'as5812_54x' @@ -295,30 +294,26 @@ def i2c_order_check(): # i2c bus 0 and 1 might be installed in different order. # Here check if 0x70 is exist @ i2c-0 tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device" - status, output = log_os_system(tmp, 0) + log_os_system(tmp, 0) if not device_exist(): order = 1 else: order = 0 tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device" - status, output = log_os_system(tmp, 0) + log_os_system(tmp, 0) return order def update_i2c_order(): global I2C_BUS_ORDER order = i2c_order_check() - pickle.dump(order, open("/tmp/accton_util.p", "wb")) # save it I2C_BUS_ORDER = order print "[%s]Detected I2C_BUS_ORDER:%d" % (os.path.basename(__file__), I2C_BUS_ORDER) def get_i2c_order(): global I2C_BUS_ORDER if I2C_BUS_ORDER < 0: - if os.path.exists("/tmp/accton_util.p"): - I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) - else: - update_i2c_order() + update_i2c_order() def device_install(): global FORCE @@ -369,10 +364,7 @@ def device_install(): def device_uninstall(): global FORCE - global I2C_BUS_ORDER - get_i2c_order() - order = I2C_BUS_ORDER for i in range(0,len(sfp_map)): target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" status, output =log_os_system("echo 0x50 > "+ target, 1) @@ -380,7 +372,8 @@ def device_uninstall(): print output if FORCE == 0: return status - + status, output = log_os_system("ls /sys/bus/i2c/devices/1-0070", 0) + order = 0 if (status == 0) else 1 if order == 0: nodelist = mknod else: From 1f9132db60dface799f1e9d75be8e7954588c3d7 Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Thu, 5 Nov 2020 00:25:33 -0800 Subject: [PATCH 1329/1427] [sonic-yang]: Yang model update fields (#5577) Changes: -- ACL stage allow lower and upper. -- ACL include services leaf-list. -- PORT include pfc_asym leaf. -- PORT fec alloe none as per code. -- 3 Tests for above changes. Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com --- .../yang_model_tests/yangModelTesting.py | 79 +++++++++- .../tests/yang_model_tests/yangTest.json | 137 +++++++++++++++++- .../yang-models/sonic-acl.yang | 11 +- .../yang-models/sonic-port.yang | 8 +- .../yang-models/sonic-portchannel.yang | 4 +- 5 files changed, 227 insertions(+), 12 deletions(-) diff --git a/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py b/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py index e1b106a17a3f..5f21485a5f0f 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py +++ b/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py @@ -61,6 +61,10 @@ def __init__(self, tests, yangDir, jsonFile): 'desc': 'Configure a member port in VLAN_MEMBER table which does not exist.', 'eStr': self.defaultYANGFailure['LeafRef'] }, + 'PORT_CHANNEL_TEST': { + 'desc': 'Configure a member port in PORT_CHANNEL table.', + 'eStr': self.defaultYANGFailure['None'] + }, 'VLAN_MEMEBER_WITH_NON_EXIST_VLAN': { 'desc': 'Configure vlan-id in VLAN_MEMBER table which does not exist in VLAN table.', 'eStr': self.defaultYANGFailure['LeafRef'] @@ -123,7 +127,47 @@ def __init__(self, tests, yangDir, jsonFile): }, 'INCORRECT_VLAN_NAME': { 'desc': 'INCORRECT VLAN_NAME FIELD IN VLAN TABLE.', - 'eStr': self.defaultYANGFailure['Pattern'] + 'eStr': self.defaultYANGFailure['Pattern'] + ["Vlan"] + }, + 'ACL_TABLE_MANDATORY_TYPE': { + 'desc': 'ACL_TABLE MANDATORY TYPE FIELD.', + 'eStr': self.defaultYANGFailure['Mandatory'] + ['type'] + ['ACL_TABLE'] + }, + 'ACL_TABLE_DEFAULT_VALUE_STAGE': { + 'desc': 'ACL_TABLE DEFAULT VALUE FOR STAGE FIELD.', + 'eStr': self.defaultYANGFailure['Verify'], + 'verify': {'xpath': "/sonic-acl:sonic-acl/ACL_TABLE/ACL_TABLE_LIST[ACL_TABLE_NAME='NO-NSW-PACL-V4']/ACL_TABLE_NAME", + 'key': 'sonic-acl:stage', + 'value': 'INGRESS' + } + }, + 'INCORRECT_VLAN_NAME': { + 'desc': 'INCORRECT VLAN_NAME FIELD IN VLAN TABLE.', + 'eStr': self.defaultYANGFailure['Pattern'] + ["Vlan"] + }, + 'PORT_CHANNEL_WRONG_PATTERN': { + 'desc': 'INCORRECT PORTCHANNEL_NAME IN PORT_CHANNEL TABLE.', + 'eStr': self.defaultYANGFailure['Pattern'] + ["PortChannel"] + }, + 'ACL_TABLE_STAGE_SERVICES': { + 'desc': 'ACL_TABLE LOAD STAGE SERVICES SUCCESSFULLY.', + 'eStr': self.defaultYANGFailure['Verify'], + 'verify': {'xpath': "/sonic-acl:sonic-acl/ACL_TABLE/ACL_TABLE_LIST[ACL_TABLE_NAME='NO-NSW-PACL-V4']/ACL_TABLE_NAME", + 'key': 'sonic-acl:services', + 'value': ["SNMP"] + } + }, + 'PORT_TEST': { + 'desc': 'LOAD PORT TABLE WITH FEC AND PFC_ASYM SUCCESSFULLY. VERIFY PFC_ASYM.', + 'eStr': self.defaultYANGFailure['Verify'], + 'verify': {'xpath': "/sonic-port:sonic-port/PORT/PORT_LIST[port_name='Ethernet8']/port_name", + 'key': 'sonic-port:pfc_asym', + 'value': 'on' + } + }, + 'PORT_NEG_TEST': { + 'desc': 'LOAD PORT TABLE FEC PATTERN FAILURE', + 'eStr': self.defaultYANGFailure['Pattern'] + ['rc'] } } @@ -200,7 +244,7 @@ def readJsonInput(self, test): jInst = ijson.items(f, test) for it in jInst: jInput = jInput + json.dumps(it) - log.debug(jInput) + log.debug("Read json JIn: {}".format(jInput)) except Exception as e: printExceptionDetails() return jInput @@ -216,12 +260,37 @@ def logStartTest(self, desc): """ Load Config Data and return Exception as String + + Parameters: + jInput (dict): input config to load. + verify (dict): contains xpath, key and value. This is used to verify, + that node tree at xpath contains correct key and value. + Example: + 'verify': {'xpath': "/sonic-acl:sonic-acl/ACL_TABLE/ACL_TABLE_LIST\ + [ACL_TABLE_NAME='NO-NSW-PACL-V4']/stage", + 'key': 'sonic-acl:stage', + 'value': 'INGRESS' + } """ - def loadConfigData(self, jInput): + def loadConfigData(self, jInput, verify=None): s = "" try: node = self.ctx.parse_data_mem(jInput, ly.LYD_JSON, \ ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) + # verify the data tree if asked + if verify is not None: + xpath = verify['xpath'] + log.debug("Verify xpath: {}".format(xpath)) + set = node.find_path(xpath) + for dnode in set.data(): + if (xpath == dnode.path()): + log.debug("Verify dnode: {}".format(dnode.path())) + data = dnode.print_mem(ly.LYD_JSON, ly.LYP_WITHSIBLINGS \ + | ly.LYP_FORMAT | ly.LYP_WD_ALL) + data = json.loads(data) + log.debug("Verify data: {}".format(data)) + assert (data[verify['key']] == verify['value']) + s = 'verified' except Exception as e: s = str(e) log.debug(s) @@ -236,9 +305,9 @@ def runExceptionTest(self, test): self.logStartTest(desc) jInput = self.readJsonInput(test) # load the data, expect a exception with must condition failure - s = self.loadConfigData(jInput) + s = self.loadConfigData(jInput, self.ExceptionTests[test].get('verify')) eStr = self.ExceptionTests[test]['eStr'] - log.debug(eStr) + log.debug("eStr: {}".format(eStr)) if len(eStr) == 0 and s != "": raise Exception("{} in not empty".format(s)) elif (sum(1 for str in eStr if str not in s) == 0): diff --git a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json index b42d1cf24cf2..cd0dafd9e8c4 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json +++ b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json @@ -108,6 +108,47 @@ } }, + "PORT_CHANNEL_TEST": { + "sonic-portchannel:sonic-portchannel": { + "sonic-portchannel:PORTCHANNEL": { + "PORTCHANNEL_LIST": [{ + "portchannel_name": "PortChannel0001", + "admin_status": "up", + "members": [ + "Ethernet0" + ], + "min_links": "1", + "mtu": "9100" + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "lanes": "65", + "admin_status": "up" + }] + } + } + }, + + "PORT_CHANNEL_WRONG_PATTERN": { + "sonic-portchannel:sonic-portchannel": { + "sonic-portchannel:PORTCHANNEL": { + "PORTCHANNEL_LIST": [{ + "portchannel_name": "PortChannel11001", + "admin_status": "up", + "mtu": "9100" + }] + } + } + }, + "VLAN_MEMEBER_WITH_NON_EXIST_VLAN": { "sonic-vlan:sonic-vlan": { "sonic-vlan:VLAN_MEMBER": { @@ -557,6 +598,7 @@ "lanes": "65", "description": "Ethernet8", "speed": 25000, + "fec": "rs", "mtu": 9000, "admin_status": "up" }] @@ -564,6 +606,42 @@ } }, + "PORT_TEST": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet8", + "alias": "eth8", + "lanes": "65", + "description": "Ethernet8", + "speed": 25000, + "fec": "rs", + "mtu": 9000, + "admin_status": "up", + "pfc_asym": "on" + }] + } + } + }, + + "PORT_NEG_TEST": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet8", + "alias": "eth8", + "lanes": "65", + "description": "Ethernet8", + "speed": 25000, + "fec": "rc", + "mtu": 9000, + "admin_status": "up", + "pfc_asym": "off" + }] + } + } + }, + "ACL_RULE_ARP_TYPE_ICMPV6_CODE_MISMATCH": { "sonic-acl:sonic-acl": { "sonic-acl:ACL_RULE": { @@ -612,6 +690,43 @@ } }, + "ACL_TABLE_MANDATORY_TYPE": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv4", + "stage": "EGRESS" + }] + } + } + }, + + "ACL_TABLE_DEFAULT_VALUE_STAGE": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv4", + "type": "L3" + }] + } + } + }, + + "ACL_TABLE_STAGE_SERVICES": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv4", + "type": "L3", + "stage": "ingress", + "services": ["SNMP"] + }] + } + } + }, "ACL_RULE_WRONG_INNER_ETHER_TYPE": { "sonic-acl:sonic-acl": { "sonic-acl:ACL_RULE": { @@ -661,6 +776,24 @@ }, "SAMPLE_CONFIG_DB_JSON": { + "PORTCHANNEL": { + "PortChannel0003": { + "admin_status": "up", + "min_links": "1", + "members": [ + "Ethernet1" + ], + "mtu": "9100" + }, + "PortChannel0004": { + "admin_status": "up", + "min_links": "1", + "members": [ + "Ethernet2" + ], + "mtu": "9100" + } + }, "VLAN_INTERFACE": { "Vlan111": {}, "Vlan777": {}, @@ -1196,7 +1329,9 @@ "Ethernet26", "Ethernet27", "Ethernet24" - ] + ], + "stage": "INGRESS", + "services": ["SNMP", "SSH"] }, "V6-ACL-TBLE": { "type": "L3V6", diff --git a/src/sonic-yang-models/yang-models/sonic-acl.yang b/src/sonic-yang-models/yang-models/sonic-acl.yang index ec8a485b4829..dcddd247e1c1 100644 --- a/src/sonic-yang-models/yang-models/sonic-acl.yang +++ b/src/sonic-yang-models/yang-models/sonic-acl.yang @@ -252,14 +252,19 @@ module sonic-acl { } leaf type { + mandatory true; type stypes:acl_table_type; } leaf stage { - type enumeration { - enum INGRESS; - enum EGRESS; + type string { + pattern "ingress|egress|INGRESS|EGRESS"; } + default "INGRESS"; + } + + leaf-list services { + type string; } leaf-list ports { diff --git a/src/sonic-yang-models/yang-models/sonic-port.yang b/src/sonic-yang-models/yang-models/sonic-port.yang index 88fcf72dadbc..574780dcf064 100644 --- a/src/sonic-yang-models/yang-models/sonic-port.yang +++ b/src/sonic-yang-models/yang-models/sonic-port.yang @@ -93,7 +93,13 @@ module sonic-port{ leaf fec { type string { - pattern "rc|fc|None"; + pattern "rs|fc|none"; + } + } + + leaf pfc_asym { + type string { + pattern "on|off"; } } } /* end of list PORT_LIST */ diff --git a/src/sonic-yang-models/yang-models/sonic-portchannel.yang b/src/sonic-yang-models/yang-models/sonic-portchannel.yang index 8f758fd51c81..8d27398c61e8 100644 --- a/src/sonic-yang-models/yang-models/sonic-portchannel.yang +++ b/src/sonic-yang-models/yang-models/sonic-portchannel.yang @@ -43,9 +43,9 @@ module sonic-portchannel { key "portchannel_name"; - ext:key-regex-configdb-to-yang "^(Ethernet[0-9]+)$"; + ext:key-regex-configdb-to-yang "^(PortChannel[0-9]{1,4})$"; - ext:key-regex-yang-to-configdb ""; + ext:key-regex-yang-to-configdb ""; leaf portchannel_name { type string { From 160544f5b149b54e8e0aa97b7bb4637869bce232 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Thu, 5 Nov 2020 14:52:50 +0200 Subject: [PATCH 1330/1427] [Mellanox] Update SAI to v.1.17.6. (#5767) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 61a209939c18..38ea6a635849 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.17.0-master +MLNX_SAI_VERSION = SAIRel1.17.6-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index db9336c0bcd6..caf2b109e52f 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit db9336c0bcd62caf04156fda4496d6706fa25b32 +Subproject commit caf2b109e52fff932e07f49d23f02f4b052e2113 From 522a071ffb3153231d7f6465cdb21e4275164723 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 5 Nov 2020 10:01:12 -0800 Subject: [PATCH 1331/1427] [core_cleanup.py] Convert to Python 3; Fix bug; Improve code reuse (#5781) - Convert to Python 3 - Fix bug: `CORE_FILE_DIR` previously was set to `os.path.basename(__file__)`, which would resolve to the script name. Fix this by hardcoding to `/var/core/` instead - Remove locally-define logging functions; use Logger class from sonic-py-common instead --- files/scripts/core_cleanup.py | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/files/scripts/core_cleanup.py b/files/scripts/core_cleanup.py index 67620b2397de..d9025a812fb8 100755 --- a/files/scripts/core_cleanup.py +++ b/files/scripts/core_cleanup.py @@ -1,31 +1,24 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import syslog import os - from collections import defaultdict from datetime import datetime +from sonic_py_common.logger import Logger + SYSLOG_IDENTIFIER = 'core_cleanup.py' -CORE_FILE_DIR = os.path.basename(__file__) +CORE_FILE_DIR = '/var/core/' MAX_CORE_FILES = 4 -def log_info(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - -def log_error(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() - def main(): + logger = Logger(SYSLOG_IDENTIFIER) + logger.set_min_log_priority_info() + if os.getuid() != 0: - log_error('Root required to clean up core files') + logger.log_error('Root required to clean up core files') return - log_info('Cleaning up core files') + logger.log_info('Cleaning up core files') core_files = [f for f in os.listdir(CORE_FILE_DIR) if os.path.isfile(os.path.join(CORE_FILE_DIR, f))] core_files_by_process = defaultdict(list) @@ -37,15 +30,14 @@ def main(): if len(curr_files) > MAX_CORE_FILES: curr_files.sort(reverse = True, key = lambda x: datetime.utcfromtimestamp(int(x.split('.')[1]))) oldest_core = curr_files[MAX_CORE_FILES] - log_info('Deleting {}'.format(oldest_core)) + logger.log_info('Deleting {}'.format(oldest_core)) try: os.remove(os.path.join(CORE_FILE_DIR, oldest_core)) except: - log_error('Unexpected error occured trying to delete {}'.format(oldest_core)) + logger.log_error('Unexpected error occured trying to delete {}'.format(oldest_core)) core_files_by_process[process] = curr_files[0:MAX_CORE_FILES] - log_info('Finished cleaning up core files') + logger.log_info('Finished cleaning up core files') if __name__ == '__main__': main() - From 13f8e9ce5e455934905ca5e00779b1b2f95d817d Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 5 Nov 2020 10:01:43 -0800 Subject: [PATCH 1332/1427] [bgpcfgd]: Convert bgpcfgd and bgpmon to python3 (#5746) * Convert bgpcfgd to python3 Convert bgpmon to python3 Fix some issues in bgpmon * Add python3-swsscommon as depends * Install dependencies * reorder deps Co-authored-by: Pavel Shirshov --- .../bgpd/templates/general/instance.conf.j2 | 6 ++--- rules/docker-config-engine-buster.mk | 1 + rules/sonic_bgpcfgd.mk | 8 ++++--- src/sonic-bgpcfgd/.gitignore | 3 +++ src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py | 6 ++--- src/sonic-bgpcfgd/bgpcfgd/utils.py | 2 +- src/sonic-bgpcfgd/bgpmon/bgpmon.py | 22 +++++++++---------- src/sonic-bgpcfgd/tests/swsscommon_test.py | 2 +- src/sonic-bgpcfgd/tests/test_allow_list.py | 5 +++-- src/sonic-bgpcfgd/tests/test_bbr.py | 6 +++-- .../tests/test_ipv6_nexthop_global.py | 4 ++-- src/sonic-bgpcfgd/tests/test_pfx_filter.py | 8 +++---- src/sonic-bgpcfgd/tests/test_sonic-cfggen.py | 8 +++---- src/sonic-bgpcfgd/tests/test_templates.py | 1 + 14 files changed, 45 insertions(+), 37 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 index 37b91d3a2d76..c8c9906bc98d 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 @@ -9,7 +9,7 @@ neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] | default("60") }} {{ bgp_session['holdtime'] | default("180") }} {% endif %} ! -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and CONFIG_DB__DEVICE_METADATA['localhost'].has_key('default_bgp_status') and CONFIG_DB__DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} +{% if 'admin_status' in bgp_session and bgp_session['admin_status'] == 'down' or 'admin_status' not in bgp_session and 'default_bgp_status' in CONFIG_DB__DEVICE_METADATA['localhost'] and CONFIG_DB__DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} neighbor {{ neighbor_addr }} shutdown {% endif %} ! @@ -23,11 +23,11 @@ ! {% endif %} ! -{% if bgp_session.has_key('rrclient') and bgp_session['rrclient'] | int != 0 %} +{% if 'rrclient' in bgp_session and bgp_session['rrclient'] | int != 0 %} neighbor {{ neighbor_addr }} route-reflector-client {% endif %} ! -{% if bgp_session.has_key('nhopself') and bgp_session['nhopself'] | int != 0 %} +{% if 'nhopself' in bgp_session and bgp_session['nhopself'] | int != 0 %} neighbor {{ neighbor_addr }} next-hop-self {% endif %} ! diff --git a/rules/docker-config-engine-buster.mk b/rules/docker-config-engine-buster.mk index 9a98647a077c..66ec301d1f7f 100644 --- a/rules/docker-config-engine-buster.mk +++ b/rules/docker-config-engine-buster.mk @@ -3,6 +3,7 @@ DOCKER_CONFIG_ENGINE_BUSTER = docker-config-engine-buster.gz $(DOCKER_CONFIG_ENGINE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-config-engine-buster +$(DOCKER_CONFIG_ENGINE_BUSTER)_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SWSSSDK_PY3) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) diff --git a/rules/sonic_bgpcfgd.mk b/rules/sonic_bgpcfgd.mk index 17e2c7b3f780..2710beecc263 100644 --- a/rules/sonic_bgpcfgd.mk +++ b/rules/sonic_bgpcfgd.mk @@ -1,11 +1,13 @@ # sonic-bgpcfgd package -SONIC_BGPCFGD = sonic_bgpcfgd-1.0-py2-none-any.whl +SONIC_BGPCFGD = sonic_bgpcfgd-1.0-py3-none-any.whl $(SONIC_BGPCFGD)_SRC_PATH = $(SRC_PATH)/sonic-bgpcfgd -# These dependencies are only needed becuase they are dependencies +# These dependencies are only needed because they are dependencies # of sonic-config-engine and bgpcfgd explicitly calls sonic-cfggen # as part of its unit tests. # TODO: Refactor unit tests so that these dependencies are not needed + $(SONIC_BGPCFGD)_DEPENDS += $(SONIC_PY_COMMON_PY2) -$(SONIC_BGPCFGD)_PYTHON_VERSION = 2 +$(SONIC_BGPCFGD)_DEBS_DEPENDS += $(PYTHON3_SWSSCOMMON) +$(SONIC_BGPCFGD)_PYTHON_VERSION = 3 SONIC_PYTHON_WHEELS += $(SONIC_BGPCFGD) diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore index 797140c05c8d..7611d6274601 100644 --- a/src/sonic-bgpcfgd/.gitignore +++ b/src/sonic-bgpcfgd/.gitignore @@ -7,3 +7,6 @@ tests/*.pyc tests/__pycache__/ .idea .coverage +bgpcfgd/__pycache__/ +venv +tests/.coverage* diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py b/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py index b1545dae9288..52f1ac3e536d 100644 --- a/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py @@ -308,7 +308,7 @@ def get_lo0_ipv4(self): :return: ipv4 address for Loopback0, None if nothing found """ loopback0_ipv4 = None - for loopback in self.directory.get_slot("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME).iterkeys(): + for loopback in self.directory.get_slot("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME).keys(): if loopback.startswith("Loopback0|"): loopback0_prefix_str = loopback.replace("Loopback0|", "") loopback0_ip_str = loopback0_prefix_str[:loopback0_prefix_str.find('/')] @@ -333,7 +333,7 @@ def get_local_interface(self, local_addr): local_address = local_addresses[local_addr] interfaces = self.directory.get_slot("LOCAL", "interfaces") # Check if the information for the interface of this local address has been set - if local_address.has_key("interface") and local_address["interface"] in interfaces: + if "interface" in local_address and local_address["interface"] in interfaces: return interfaces[local_address["interface"]] else: return None @@ -346,7 +346,7 @@ def get_vnet(interface): :return: Return the vnet name of the interface if this interface belongs to a vnet, Otherwise return None """ - if interface.has_key("vnet_name") and interface["vnet_name"]: + if "vnet_name" in interface and interface["vnet_name"]: return interface["vnet_name"] else: return None diff --git a/src/sonic-bgpcfgd/bgpcfgd/utils.py b/src/sonic-bgpcfgd/bgpcfgd/utils.py index 63d53512d04c..ce235af9d8e4 100644 --- a/src/sonic-bgpcfgd/bgpcfgd/utils.py +++ b/src/sonic-bgpcfgd/bgpcfgd/utils.py @@ -16,7 +16,7 @@ def run_command(command, shell=False, hide_errors=False): :return: Tuple: integer exit code from the command, stdout as a string, stderr as a string """ log_debug("execute command '%s'." % str(command)) - p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8') stdout, stderr = p.communicate() if p.returncode != 0: if not hide_errors: diff --git a/src/sonic-bgpcfgd/bgpmon/bgpmon.py b/src/sonic-bgpcfgd/bgpmon/bgpmon.py index e4a9561142be..df40d901f3dd 100755 --- a/src/sonic-bgpcfgd/bgpmon/bgpmon.py +++ b/src/sonic-bgpcfgd/bgpmon/bgpmon.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 """" Description: bgpmon.py -- populating bgp related information in stateDB. @@ -6,7 +6,7 @@ Initial creation of this daemon is to assist SNMP agent in obtaining the BGP related information for its MIB support. The MIB that this daemon is - assiting is for the CiscoBgp4MIB (Neighbor state only). If there are other + assisting is for the CiscoBgp4MIB (Neighbor state only). If there are other BGP related items that needs to be updated in a periodic manner in the future, then more can be added into this process. @@ -23,7 +23,7 @@ is a need to perform update or the peer is stale to be removed from the state DB """ -import commands +import subprocess import json import os import syslog @@ -32,7 +32,7 @@ PIPE_BATCH_MAX_COUNT = 50 -class BgpStateGet(): +class BgpStateGet: def __init__(self): # list peer_l stores the Neighbor peer Ip address # dic peer_state stores the Neighbor peer state entries @@ -74,13 +74,13 @@ def update_new_peer_states(self, peer_dict): # Get a new snapshot of BGP neighbors and store them in the "new" location def get_all_neigh_states(self): cmd = "vtysh -c 'show bgp summary json'" - rc, output = commands.getstatusoutput(cmd) + rc, output = subprocess.getstatusoutput(cmd) if rc: syslog.syslog(syslog.LOG_ERR, "*ERROR* Failed with rc:{} when execute: {}".format(rc, cmd)) return peer_info = json.loads(output) - # cmd ran successfully, safe to Clean the "new" lists/dic for new sanpshot + # cmd ran successfully, safe to Clean the "new" lists/dic for new snapshot del self.new_peer_l[:] self.new_peer_state.clear() for key, value in peer_info.items(): @@ -136,7 +136,7 @@ def update_neigh_states(self): self.flush_pipe(data) # Check for stale state entries to be cleaned up while len(self.peer_l) > 0: - # remove this from the stateDB and the current nighbor state entry + # remove this from the stateDB and the current neighbor state entry peer = self.peer_l.pop(0) del_key = "NEIGH_STATE_TABLE|%s" % peer data[del_key] = None @@ -151,15 +151,15 @@ def update_neigh_states(self): def main(): - print "bgpmon service started" - + syslog.syslog(syslog.LOG_INFO, "bgpmon service started") + bgp_state_get = None try: bgp_state_get = BgpStateGet() except Exception as e: - syslog.syslog(syslog.LOG_ERR, "{}: error exit 1, reason {}".format(THIS_MODULE, str(e))) + syslog.syslog(syslog.LOG_ERR, "{}: error exit 1, reason {}".format("THIS_MODULE", str(e))) exit(1) - # periodically obtain the new neighbor infomraton and update if necessary + # periodically obtain the new neighbor information and update if necessary while True: time.sleep(15) if bgp_state_get.bgp_activity_detected(): diff --git a/src/sonic-bgpcfgd/tests/swsscommon_test.py b/src/sonic-bgpcfgd/tests/swsscommon_test.py index 196c9bcb8924..46984bafc609 100644 --- a/src/sonic-bgpcfgd/tests/swsscommon_test.py +++ b/src/sonic-bgpcfgd/tests/swsscommon_test.py @@ -1,4 +1,4 @@ -from mock import MagicMock +from unittest.mock import MagicMock swsscommon = MagicMock(CFG_DEVICE_METADATA_TABLE_NAME = "DEVICE_METADATA") diff --git a/src/sonic-bgpcfgd/tests/test_allow_list.py b/src/sonic-bgpcfgd/tests/test_allow_list.py index 3288702b5814..d419cb4f1530 100644 --- a/src/sonic-bgpcfgd/tests/test_allow_list.py +++ b/src/sonic-bgpcfgd/tests/test_allow_list.py @@ -1,7 +1,8 @@ +from unittest.mock import MagicMock, patch + from bgpcfgd.directory import Directory from bgpcfgd.template import TemplateFabric import bgpcfgd -from mock import MagicMock, patch swsscommon_module_mock = MagicMock() @@ -429,7 +430,7 @@ def test___find_peer_group_by_deployment_id(): } mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") values = mgr._BGPAllowListMgr__find_peer_group_by_deployment_id(0) - assert values == ['PEER_V4_INT', 'PEER_V6_INT', 'PEER_V6', 'PEER_V4'] + assert set(values) == set(['PEER_V4_INT', 'PEER_V6_INT', 'PEER_V6', 'PEER_V4']) @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def test___restart_peers_found_deployment_id(): diff --git a/src/sonic-bgpcfgd/tests/test_bbr.py b/src/sonic-bgpcfgd/tests/test_bbr.py index 5f95d12acf60..a86cc5c6db07 100644 --- a/src/sonic-bgpcfgd/tests/test_bbr.py +++ b/src/sonic-bgpcfgd/tests/test_bbr.py @@ -1,10 +1,12 @@ +from unittest.mock import MagicMock, patch + from bgpcfgd.directory import Directory from bgpcfgd.template import TemplateFabric -from mock import MagicMock, patch from copy import deepcopy -import swsscommon_test +from . import swsscommon_test import bgpcfgd + with patch.dict("sys.modules", swsscommon=swsscommon_test): from bgpcfgd.managers_bbr import BBRMgr diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py index 92b1e5dd8c2d..849b1f8d36be 100644 --- a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -19,7 +19,7 @@ def parse_instance_conf(filename): if TemplateFabric.is_ipv6(neighbor): neighbors[neighbor] = {} # Extract peer-groups and route-maps - for neighbor, neighbor_data in neighbors.iteritems(): + for neighbor, neighbor_data in neighbors.items(): route_map_in_re = re.compile(r'^neighbor\s+%s\s+route-map\s+(\S+) in$' % neighbor) peer_group_re = re.compile(r'^neighbor\s+%s\s+peer-group\s+(\S+)$' % neighbor) for line in lines: @@ -30,7 +30,7 @@ def parse_instance_conf(filename): assert "peer-group" not in neighbor_data neighbor_data["peer-group"] = peer_group_re.match(line).group(1) # Ensure that every ivp6 neighbor has either route-map or peer-group - for neighbor, neighbor_data in neighbors.iteritems(): + for neighbor, neighbor_data in neighbors.items(): assert "route-map" in neighbor_data or "peer-group" in neighbor_data,\ "IPv6 neighbor '%s' must have either route-map in or peer-group %s" % (neighbor, neighbor_data) return neighbors diff --git a/src/sonic-bgpcfgd/tests/test_pfx_filter.py b/src/sonic-bgpcfgd/tests/test_pfx_filter.py index 684a95bf75f8..0714be56a892 100644 --- a/src/sonic-bgpcfgd/tests/test_pfx_filter.py +++ b/src/sonic-bgpcfgd/tests/test_pfx_filter.py @@ -42,7 +42,7 @@ def test_pfx_filter_mixed_keys(): ] ) res = TemplateFabric.pfx_filter(src) - assert res == expected + assert dict(res) == dict(expected) def test_pfx_filter_pfx_v4_w_mask(): @@ -57,7 +57,7 @@ def test_pfx_filter_pfx_v4_w_mask(): ] ) res = TemplateFabric.pfx_filter(src) - assert res == expected + assert dict(res) == dict(expected) def test_pfx_filter_pfx_v6_w_mask(): src = { @@ -85,7 +85,7 @@ def test_pfx_filter_pfx_v4_no_mask(): ] ) res = TemplateFabric.pfx_filter(src) - assert res == expected + assert dict(res) == dict(expected) def test_pfx_filter_pfx_v6_no_mask(): src = { @@ -126,7 +126,7 @@ def test_pfx_filter_pfx_comprehensive(): ] ) res = TemplateFabric.pfx_filter(src) - assert res == expected + assert dict(res) == dict(expected) @pytest.fixture def test_pfx_filter_wrong_ip(caplog): diff --git a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py index d10ec65d21dc..92f6dec249b4 100644 --- a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py +++ b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py @@ -1,9 +1,7 @@ import os import subprocess - from bgpcfgd.config import ConfigMgr -from .test_templates import compress_comments, write_result TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') @@ -15,11 +13,11 @@ def run_test(name, template_path, json_path, match_path): template_path = os.path.join(TEMPLATE_PATH, template_path) json_path = os.path.join(DATA_PATH, json_path) cfggen = os.path.abspath("../sonic-config-engine/sonic-cfggen") - command = [cfggen, "-T", TEMPLATE_PATH, "-t", template_path, "-y", json_path] - p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + command = ['/usr/bin/python2.7', cfggen, "-T", TEMPLATE_PATH, "-t", template_path, "-y", json_path] + p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={"PYTHONPATH": "."}) stdout, stderr = p.communicate() assert p.returncode == 0, "sonic-cfggen for %s test returned %d code. stderr='%s'" % (name, p.returncode, stderr) - raw_generated_result = stdout + raw_generated_result = stdout.decode("ascii") assert "None" not in raw_generated_result, "Test %s" % name canonical_generated_result = ConfigMgr.to_canonical(raw_generated_result) match_path = os.path.join(DATA_PATH, match_path) diff --git a/src/sonic-bgpcfgd/tests/test_templates.py b/src/sonic-bgpcfgd/tests/test_templates.py index f5f5f2155253..f8fa0b9e4028 100644 --- a/src/sonic-bgpcfgd/tests/test_templates.py +++ b/src/sonic-bgpcfgd/tests/test_templates.py @@ -6,6 +6,7 @@ from bgpcfgd.config import ConfigMgr from .util import load_constants + TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') From 2c9454e86af7311e9ebc81efb734782969550693 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 5 Nov 2020 11:17:08 -0800 Subject: [PATCH 1333/1427] [sonic-device-data] Convert Python files to Python 3 (#5816) - Convert config_checker, media_checker and platform_json_checker scripts to Python 3 - Reorganize imports per PEP8 standard - Two blank lines precede functions per PEP8 standard --- src/sonic-device-data/tests/config_checker | 20 ++++--- src/sonic-device-data/tests/media_checker | 52 ++++++++++-------- .../tests/platform_json_checker | 54 +++++++++---------- 3 files changed, 67 insertions(+), 59 deletions(-) diff --git a/src/sonic-device-data/tests/config_checker b/src/sonic-device-data/tests/config_checker index 6cb4d029be58..76fdde17d288 100755 --- a/src/sonic-device-data/tests/config_checker +++ b/src/sonic-device-data/tests/config_checker @@ -1,20 +1,23 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 + +import glob import re import sys -import glob permitted_properties = [] + def usage(): - print "Usage: " + sys.argv[0] + " " + print("Usage: " + sys.argv[0] + " ") sys.exit(1) -def check_property(p): +def check_property(p): if p in permitted_properties: return True return False + def check_file(file_name): try: file_ok = True @@ -58,14 +61,14 @@ def check_file(file_name): if not check_property(p): file_ok = False - print("[line %d] Error: %s is not permitted" % (lineno, p)) + print("[line {}] Error: {} is not permitted".format(lineno, p)) if file_ok: - print "Result: " + file_name + " PASSED the config check!" + print("Result: " + file_name + " PASSED the config check!") else: - print "Result: " + file_name + " FAILED the config check!" + print("Result: " + file_name + " FAILED the config check!") return file_ok except IOError: - print "Error: Cannot open file " + file_name + print("Error: Cannot open file " + file_name) return False @@ -93,5 +96,6 @@ def main(argv): if not all_good: sys.exit(-1) + if __name__ == "__main__": main(sys.argv[1:]) diff --git a/src/sonic-device-data/tests/media_checker b/src/sonic-device-data/tests/media_checker index 132756cb4b77..7d59d88254c5 100755 --- a/src/sonic-device-data/tests/media_checker +++ b/src/sonic-device-data/tests/media_checker @@ -1,8 +1,9 @@ -#!/usr/bin/env python -import re -import sys +#!/usr/bin/env python3 + import glob import json +import re +import sys level1_keys = ["GLOBAL_MEDIA_SETTINGS","PORT_MEDIA_SETTINGS"] setting_keys = ["preemphasis","idriver","ipredriver"] @@ -10,6 +11,7 @@ lane_prefix = "lane" comma_separator = "," range_separator = "-" + def check_lane_and_value(lane_name, lane_value): if lane_prefix in lane_name: try: @@ -18,30 +20,32 @@ def check_lane_and_value(lane_name, lane_value): return True except ValueError: - print "Invalid lane values " + lane_name + " " + lane_value + print("Invalid lane values " + lane_name + " " + lane_value) return False else: return False + def usage(): - print "Usage: " + sys.argv[0] + " " + print("Usage: " + sys.argv[0] + " ") sys.exit(1) + def check_media_dict(vendor_dict): if len(vendor_dict) == 0: - print "Expecting values for media type " + keys + print("Expecting values for media type " + keys) return False for vendor_key in vendor_dict: value_dict = vendor_dict[vendor_key] if len(value_dict) == 0: - print "Expecting settings for vendor type " + vendor_key + print("Expecting settings for vendor type " + vendor_key) return False for value_key in value_dict: if value_key not in setting_keys: - print "Unknown media setting " + value_key + print("Unknown media setting " + value_key) return False lane_dict = value_dict[value_key] @@ -50,6 +54,7 @@ def check_media_dict(vendor_dict): return False return True + def check_valid_port(port_name): try: val = int(port_name.strip()) @@ -57,17 +62,19 @@ def check_valid_port(port_name): except ValueError: return False + def check_port_keys(port_media_dict): for port in port_media_dict: if not check_valid_port(port): - print "Invalid port name " + port + print("Invalid port name " + port) return False if not check_media_dict(port_media_dict[port]): return False return True + def check_global_keys(global_media_dict): for keys in global_media_dict: if comma_separator in keys: @@ -77,22 +84,22 @@ def check_global_keys(global_media_dict): range_list = port.split(range_separator) for port_val in range_list: if not check_valid_port(port_val): - print "Error: Unrecognized port number " + port_val - print "Invalid range " + port + print("Error: Unrecognized port number " + port_val) + print("Invalid range " + port) return False else: if not check_valid_port(port): - print "Error: Unrecognized portname " + port + print("Error: Unrecognized portname " + port) return False elif range_separator in keys: range_list = keys.split(range_separator) for port_val in range_list: if not check_valid_port(port_val): - print "Error: Unrecognized portname " + port_val - print "Invalid range " + keys + print("Error: Unrecognized portname " + port_val) + print("Invalid range " + keys) return False else: - print "Invalid range " + keys + print("Invalid range " + keys) return False if not check_media_dict(global_media_dict[keys]): @@ -110,7 +117,7 @@ def check_file(media_settings_file): for key_l1 in media_dict: if key_l1 not in level1_keys: - print "Error: Unknown key " + key_l1 + " at top level" + print("Error: Unknown key " + key_l1 + " at top level") return False if "GLOBAL_MEDIA_SETTINGS" in media_dict: if not check_global_keys(media_dict["GLOBAL_MEDIA_SETTINGS"]): @@ -121,11 +128,11 @@ def check_file(media_settings_file): except IOError: - print "Error: Cannot open file " + media_settings_file + print("Error: Cannot open file " + media_settings_file) return False - except ValueError,e: - print "Error in parsing json file " + media_settings_file + " " - print str(e) + except ValueError as e: + print("Error in parsing json file " + media_settings_file + " ") + print(str(e)) return False return True @@ -146,14 +153,15 @@ def main(argv): for f in files: good = check_file(f) if good: - print "File " + f + " passed validity check" + print("File " + f + " passed validity check") else: - print "File " + f + " failed validity check" + print("File " + f + " failed validity check") all_good = all_good and good if not all_good: sys.exit(-1) + if __name__ == "__main__": main(sys.argv[1:]) diff --git a/src/sonic-device-data/tests/platform_json_checker b/src/sonic-device-data/tests/platform_json_checker index c0257a27e80c..1612c0082c1d 100755 --- a/src/sonic-device-data/tests/platform_json_checker +++ b/src/sonic-device-data/tests/platform_json_checker @@ -1,17 +1,9 @@ -#!/usr/bin/env python -try: - import re - import sys - import glob - import json -except ImportError as e: - raise ImportError (str(e) + "- required module not found") - -# TODO: need to remove basestring once migrate to Python 3 and just change to str -try: - basestring -except NameError: - basestring = str +#!/usr/bin/env python3 + +import glob +import json +import re +import sys # Global variable PORT_ATTRIBUTES = ["index", "lanes", "alias_at_lanes", "breakout_modes"] @@ -20,24 +12,26 @@ PORT_REG = "Ethernet(\d+)" PLATFORM_JSON = '*platform.json' INTF_KEY = "interfaces" + def usage(): - print "Usage: " + sys.argv[0] + " " + print("Usage: " + sys.argv[0] + " ") sys.exit(1) + def check_port_attr(port_attr): for each_key in port_attr: if each_key not in PORT_ATTRIBUTES: - print "Error: "+ each_key + " is not the correct Port attribute." + print("Error: "+ each_key + " is not the correct Port attribute.") return False if not port_attr[each_key]: - print "Error: "+ each_key + " has no value." + print("Error: "+ each_key + " has no value.") return False - # TODO: need to remove basestring once migrate to Python 3 and just change to str - if not isinstance(port_attr[each_key], basestring): - print "Error:value type of "+ each_key + " must be string." + if not isinstance(port_attr[each_key], str): + print("Error:value type of "+ each_key + " must be string.") return False return True + def check_file(platform_json_file): try: platform_cap_file = open(platform_json_file,"r") @@ -48,29 +42,30 @@ def check_file(platform_json_file): # Validate port at top level port_id = re.search(PORT_REG, each_port) if port_id is None: - print "Error: Unknown Interface " + str(each_port) + " at top level" + print("Error: Unknown Interface " + str(each_port) + " at top level") return False - total_attr = len(port_dict[INTF_KEY][each_port].keys()) + total_attr = len(list(port_dict[INTF_KEY][each_port].keys())) port_attr = port_dict[INTF_KEY][each_port] if total_attr != ATTR_LEN: missing_attr = ', '.join(set(PORT_ATTRIBUTES).difference(list(port_attr))) - print "Error: " + missing_attr + " of " + each_port + " is/are missing" + print("Error: " + missing_attr + " of " + each_port + " is/are missing") return False #Validate port attributes for each port if not check_port_attr(port_attr): return False except IOError: - print "Error: Cannot open file " + platform_json_file + print("Error: Cannot open file " + platform_json_file) return False - except ValueError,e: - print "Error in parsing json file " + platform_json_file + " " - print str(e) + except ValueError as e: + print("Error in parsing json file " + platform_json_file + " ") + print(str(e)) return False return True + def main(argv): if len(argv) > 0 and argv[0] == "-h": usage() @@ -86,14 +81,15 @@ def main(argv): for f in files: good = check_file(f) if good: - print "File " + f + " passed validity check" + print("File " + f + " passed validity check") else: - print "File " + f + " failed validity check" + print("File " + f + " failed validity check") all_good = all_good and good if not all_good: sys.exit(-1) + if __name__ == "__main__": main(sys.argv[1:]) From d8045987a60d0ce27d3859f07cbabc4d01ec9091 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 5 Nov 2020 11:19:26 -0800 Subject: [PATCH 1334/1427] [core_uploader.py] Convert to Python 3; Use logger from sonic-py-common for uniform logging (#5790) - Convert core_uploader.py script to Python 3 - Use logger from sonic-py-common for uniform logging - Reorganize imports alphabetically per PEP8 standard - Two blank lines precede functions per PEP8 standard - Remove unnecessary global variable declarations --- .../build_templates/sonic_debian_extension.j2 | 2 + .../corefile_uploader/core_uploader.py | 75 +++++++------------ 2 files changed, 30 insertions(+), 47 deletions(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index c322c58aa003..52b6205e1487 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -339,7 +339,9 @@ sudo chmod og-rw $FILESYSTEM_ROOT_ETC_SONIC/core_analyzer.rc.json sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install libffi-dev libssl-dev sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install azure-storage==0.36.0 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install azure-storage==0.36.0 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install watchdog==0.10.2 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install watchdog==0.10.3 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install futures==3.3.0 {% if include_kubernetes == "y" %} diff --git a/files/image_config/corefile_uploader/core_uploader.py b/files/image_config/corefile_uploader/core_uploader.py index 2ae91ce0896b..4807425f4307 100755 --- a/files/image_config/corefile_uploader/core_uploader.py +++ b/files/image_config/corefile_uploader/core_uploader.py @@ -1,25 +1,19 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 +import json import os -import time -import tarfile import socket +import tarfile +import time + import yaml -import json -import syslog +from azure.storage.file import FileService +from sonic_py_common.logger import Logger from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler -from azure.storage.file import FileService - -global CORE_FILE_PATH, RC_FILE -global hostname, sonicversion, asicname, acctname, acctkey, sharename, cwd -global INIT_CWD -global log_level -global this_file -this_file = os.path.basename(__file__) +SYSLOG_IDENTIFIER = os.path.basename(__file__) -global cfg cfg = "" CORE_FILE_PATH = "/var/core/" @@ -42,32 +36,16 @@ MAX_RETRIES = 5 UPLOAD_PREFIX = "UPLOADED_" -log_level = syslog.LOG_DEBUG - -def log_msg(lvl, fname, m): - if (lvl <= log_level): - syslog.syslog(lvl, "{}: {}".format(fname, m)) - - if log_level == syslog.LOG_DEBUG: - print("{}: {}".format(fname, m)) - -def log_err(m): - log_msg(syslog.LOG_ERR, this_file, m) - -def log_info(m): - log_msg(syslog.LOG_INFO, this_file, m) - -def log_warn(m): - log_msg(syslog.LOG_WARNING, this_file, m) - -def log_debug(m): - log_msg(syslog.LOG_DEBUG, this_file, m) +# Global logger instance +logger = Logger(SYSLOG_IDENTIFIER) +logger.set_min_log_priority_info() def make_new_dir(p): os.system("rm -rf " + p) os.system("mkdir -p " + p) + def parse_a_json(data, prefix, val): for i in data: if type(data[i]) == dict: @@ -75,6 +53,7 @@ def parse_a_json(data, prefix, val): else: val[prefix + (i,)] = data[i] + class config: parsed_data = {} cfg_data = {} @@ -82,7 +61,7 @@ class config: def __init__(self): while not os.path.exists(RC_FILE): # Wait here until service restart - log_err("Unable to retrieve Azure storage credentials") + logger.log_error("Unable to retrieve Azure storage credentials") time.sleep (HOURS_4) with open(RC_FILE, 'r') as f: @@ -90,7 +69,7 @@ def __init__(self): parse_a_json(self.parsed_data, (), self.cfg_data) def get_data(self, k): - return self.cfg_data[k] if self.cfg_data.has_key(k) else "" + return self.cfg_data[k] if k in self.cfg_data else "" def get_dict(self): return self.parsed_data @@ -123,15 +102,17 @@ def run(self): time.sleep(POLL_SLEEP) except: self.observer.stop() - log_err("Error in watcher") + logger.log_error("Error in watcher") self.observer.join() + def set_env(lst): for k in lst: if lst[k]: os.environ[k] = lst[k] - log_debug("set env {} = {}".format(k, lst[k])) + logger.log_debug("set env {} = {}".format(k, lst[k])) + class Handler(FileSystemEventHandler): @@ -155,7 +136,7 @@ def init(): if not acctname or not acctkey or not sharename: while True: # Wait here until service restart - log_err("Unable to retrieve Azure storage credentials") + logger.log_error("Unable to retrieve Azure storage credentials") time.sleep (HOURS_4) with open("/etc/sonic/sonic_version.yml", 'r') as stream: @@ -182,7 +163,7 @@ def on_any_event(event): elif event.event_type == 'created': # Take any action here when a file is first created. - log_debug("Received create event - " + event.src_path) + logger.log_debug("Received create event - " + event.src_path) Handler.wait_for_file_write_complete(event.src_path) Handler.handle_file(event.src_path) @@ -205,7 +186,7 @@ def wait_for_file_write_complete(path): raise Exception("Dump file creation is too slow: " + path) # Give up as something is terribly wrong with this file. - log_debug("File write complete - " + path) + logger.log_debug("File write complete - " + path) @staticmethod @@ -227,11 +208,11 @@ def handle_file(path): tar.add(metafiles[e]) tar.add(path) tar.close() - log_debug("Tar file for upload created: " + tarf_name) + logger.log_debug("Tar file for upload created: " + tarf_name) Handler.upload_file(tarf_name, tarf_name, path) - log_debug("File uploaded - " + path) + logger.log_debug("File uploaded - " + path) os.chdir(INIT_CWD) @staticmethod @@ -250,16 +231,16 @@ def upload_file(fname, fpath, coref): e.append(l[len(e)]) svc.create_directory(sharename, "/".join(e)) - log_debug("Remote dir created: " + "/".join(e)) + logger.log_debug("Remote dir created: " + "/".join(e)) svc.create_file_from_path(sharename, "/".join(l), fname, fpath) - log_debug("Remote file created: name{} path{}".format(fname, fpath)) + logger.log_debug("Remote file created: name{} path{}".format(fname, fpath)) newcoref = os.path.dirname(coref) + "/" + UPLOAD_PREFIX + os.path.basename(coref) os.rename(coref, newcoref) break except Exception as ex: - log_err("core uploader failed: Failed during upload (" + coref + ") err: ("+ str(ex) +") retry:" + str(i)) + logger.log_error("core uploader failed: Failed during upload (" + coref + ") err: ("+ str(ex) +") retry:" + str(i)) if not os.path.exists(fpath): break i += 1 @@ -281,5 +262,5 @@ def scan(): Handler.scan() w.run() except Exception as e: - log_err("core uploader failed: " + str(e) + " Exiting ...") + logger.log_err("core uploader failed: " + str(e) + " Exiting ...") From 13ff7b38d52f4afb98dc4a560f1599fcb441146c Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 5 Nov 2020 11:23:00 -0800 Subject: [PATCH 1335/1427] [docker-wait-any] Convert to Python 3, install dependency in host OS (#5784) - Convert docker-wait-any script to Python 3 - Install Python 3 Docker Engine API in host OS --- build_debian.sh | 8 +++++--- files/image_config/misc/docker-wait-any | 5 ++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 2bb284182db1..2cea52e9e466 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -413,13 +413,15 @@ done < files/image_config/sysctl/sysctl-net.conf sudo augtool --autosave "$sysctl_net_cmd_string" -r $FILESYSTEM_ROOT -## docker Python API package is needed by Ansible docker module -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install 'docker==4.1.0' +# docker Python API package is needed by Ansible docker module as well as some SONiC applications +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install 'docker==4.1.0' +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'docker==4.3.1' + ## Note: keep pip installed for maintainance purpose ## Get gcc and python dev pkgs sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install gcc libpython2.7-dev -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install 'netifaces==0.10.7' +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install 'netifaces==0.10.7' ## Create /var/run/redis folder for docker-database to mount sudo mkdir -p $FILESYSTEM_ROOT/var/run/redis diff --git a/files/image_config/misc/docker-wait-any b/files/image_config/misc/docker-wait-any index d006aec47a5a..8d98e1f36a37 100755 --- a/files/image_config/misc/docker-wait-any +++ b/files/image_config/misc/docker-wait-any @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ docker-wait-any @@ -23,7 +23,7 @@ cases where we need the dependent container to be warm-restarted without affecting other services (eg: warm restart of teamd service) - NOTE: This script is written against docker Python package 4.1.0. Newer + NOTE: This script is written against docker Python package 4.3.1. Newer versions of docker may have a different API. """ import argparse @@ -68,7 +68,6 @@ def main(): docker_client = APIClient(base_url='unix://var/run/docker.sock') parser = argparse.ArgumentParser(description='Wait for dependent docker services', - version='1.0.0', formatter_class=argparse.RawTextHelpFormatter, epilog=""" Examples: From cea364aa7754a0d54e7deb3eb0462927c4d22117 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Fri, 6 Nov 2020 00:58:49 -0800 Subject: [PATCH 1336/1427] [utilities] Update sonic-utilities submodule (#5814) Add a switch to route_check to control whether write log to syslog (#1215) [consutil] Store console port state in STATE_DB (#1208) [sfputil] Display 'N/A' for non-SFP ports (#1078) Show FG_NHG CLI Commands Added (#1056) [show] remove 'device2interface_dict' in show interface neighbor expected (#1188) Add license file, remove third-party licenses file (#1192) [fwutil]: Set min log priority to INFO. (#1191) [CLI][show][platform] Added ASIC count in the output. (#1185) fdbshow and nbrshow use SonicV2Connector with decode_responses=True, and remove all the decode() (#1187) Remove stdeb.cfg; no longer used now that we build as wheel (#1182) [counterpoll] Disable Counter Poll When Entering Fast Reboot (#1174) Fixes the issue with show interface counters and for pfc and queue counters. (#1180) [config/show] Add CLI support for proxy arp (#1168) [consutil] Add brief option to show line command (#1176) Modify fast-reboot script to use BGP service script to stop bgp service (#1177) [config/console] Support update console configuration related commands (#1166) [consutil] Fix issue where the show line command crash if no ttyUSB exists (#1173) [watermarkstat] Add unit tests for watermarkstat show commands (#1157) Fix exception for ipaddress in python2 (#1164) [celestica] consutil to support customize tty device name (#1155) Signed-off-by: Danny Allen --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index b6af9f48e298..acfa8248d799 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit b6af9f48e29852985137a57ff5396591af7f107c +Subproject commit acfa8248d79970e4d0225dd08082dc8f85ad030d From 51292330e98dad392995bdcfa2410ca1c7fe490a Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 6 Nov 2020 09:00:19 -0800 Subject: [PATCH 1337/1427] [enable_counters.py] Convert to Python 3 (#5789) **- Why I did it** As part of moving all SONiC code from Python 2 (no longer supported) to Python 3 **- How I did it** - Convert enable_counters.py script to Python 3 - Reorganize imports per PEP8 standard - Two blank lines precede functions per PEP8 standard --- dockers/docker-orchagent/enable_counters.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dockers/docker-orchagent/enable_counters.py b/dockers/docker-orchagent/enable_counters.py index 5178684c5e16..2067baefbfb7 100755 --- a/dockers/docker-orchagent/enable_counters.py +++ b/dockers/docker-orchagent/enable_counters.py @@ -1,13 +1,16 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import swsssdk import time +import swsssdk + + def enable_counter_group(db, name): info = {} info['FLEX_COUNTER_STATUS'] = 'enable' db.mod_entry("FLEX_COUNTER_TABLE", name, info) + def enable_counters(): db = swsssdk.ConfigDBConnector() db.connect() @@ -20,10 +23,12 @@ def enable_counters(): enable_counter_group(db, 'BUFFER_POOL_WATERMARK') enable_counter_group(db, 'PORT_BUFFER_DROP') + def get_uptime(): with open('/proc/uptime') as fp: return float(fp.read().split(' ')[0]) + def main(): # If the switch was just started (uptime less than 5 minutes), # wait for 3 minutes and enable counters @@ -35,5 +40,6 @@ def main(): time.sleep(60) enable_counters() + if __name__ == '__main__': main() From 27a911f16e23ae2819395d4574ad13ef7b08df3a Mon Sep 17 00:00:00 2001 From: Garrick He <32883830+GarrickHe@users.noreply.github.com> Date: Fri, 6 Nov 2020 10:15:06 -0800 Subject: [PATCH 1338/1427] [sflow] Fix port_index_mapper.py script; Convert to Python 3 (#5800) **- Why I did it** A memory issue was discovered during system test for scaling. The issue is documented here: https://docs.pyroute2.org/ipdb.html > One of the major issues with IPDB is its memory footprint. It proved not to be suitable for environments with thousands of routes or neighbours. Being a design issue, it could not be fixed, so a new module was started, NDB, that aims to replace IPDB. IPDB is still more feature rich, but NDB is already more fast and stable. **- How I did it** - Rewrote the port_index_mapper.py script to use dB events. - Convert to Python 3 --- dockers/docker-sflow/port_index_mapper.py | 171 +++++++++++----------- 1 file changed, 88 insertions(+), 83 deletions(-) diff --git a/dockers/docker-sflow/port_index_mapper.py b/dockers/docker-sflow/port_index_mapper.py index 24f078b20f90..3f8a2819a840 100755 --- a/dockers/docker-sflow/port_index_mapper.py +++ b/dockers/docker-sflow/port_index_mapper.py @@ -1,114 +1,119 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -""" port_index_mapper - A mapper service that watches for NetLink NEWLINK and DELLINKs - to construct a PORT_INDEX_TABLE in state DB which includes the - interface name, the interface index and the ifindex. - - Note : Currently supports only interfaces supported by port_util. -""" - -import os -import sys -import syslog import signal +import sys import traceback -from pyroute2 import IPDB -from pyroute2.iproute import RTM_NEWLINK, RTM_DELLINK +from sonic_py_common.logger import Logger +from socket import if_nametoindex from swsssdk import SonicV2Connector, port_util +from swsscommon import swsscommon -PORT_INDEX_TABLE_NAME = 'PORT_INDEX_TABLE' SYSLOG_IDENTIFIER = 'port_index_mapper' -ipdb = None -state_db = None +# Global logger instance +logger = Logger(SYSLOG_IDENTIFIER) +logger.set_min_log_priority_info() -def set_port_index_table_entry(key, index, ifindex): - state_db.set(state_db.STATE_DB, key, 'index', index) - state_db.set(state_db.STATE_DB, key, 'ifindex', ifindex) +class PortIndexMapper(object): -def interface_callback(ipdb, nlmsg, action): - global state_db + def __init__(self): + REDIS_TIMEOUT_MS = 0 + # Update this list to support more interfaces + tbl_lst = [swsscommon.STATE_PORT_TABLE_NAME, + swsscommon.STATE_VLAN_TABLE_NAME] + self.appl_db = swsscommon.DBConnector("STATE_DB", + REDIS_TIMEOUT_MS, + True) - try: - msgtype = nlmsg['header']['type'] - if (msgtype != RTM_NEWLINK and msgtype != RTM_DELLINK): - return + self.state_db = SonicV2Connector(host='127.0.0.1', decode_responses=True) + self.state_db.connect(self.state_db.STATE_DB, False) + self.sel = swsscommon.Select() + self.tlbs = [swsscommon.SubscriberStateTable(self.appl_db, t) + for t in tbl_lst] - # filter out unwanted messages - change = nlmsg['change'] - if (change != 0xFFFFFFFF): - return - - attrs = nlmsg['attrs'] - for list in attrs: - if list[0] == 'IFLA_IFNAME': - ifname = list[1] - break - else: - return - - # Extract the port index from the interface name + self.cur_interfaces = {} + + for t in self.tlbs: + self.sel.addSelectable(t) + + def set_port_index_table_entry(self, key, index, ifindex): + self.state_db.set(self.state_db.STATE_DB, key, 'index', index) + self.state_db.set(self.state_db.STATE_DB, key, 'ifindex', ifindex) + + def update_db(self, ifname, op): index = port_util.get_index_from_str(ifname) - if index is None: + if op == 'SET' and index is None: + return + ifindex = if_nametoindex(ifname) + if op == 'SET' and ifindex is None: return - - _hash = '{}|{}'.format(PORT_INDEX_TABLE_NAME, ifname) - - if msgtype == RTM_NEWLINK: - set_port_index_table_entry(_hash, str(index), nlmsg['index']) - elif msgtype == RTM_DELLINK: - state_db.delete(state_db.STATE_DB, _hash) - - except Exception, e: - t = sys.exc_info()[2] - traceback.print_tb(t) - syslog.syslog(syslog.LOG_CRIT, "%s" % str(e)) - os.kill(os.getpid(), signal.SIGTERM) -def main(): - global state_db, ipdb - state_db = SonicV2Connector(host='127.0.0.1') - state_db.connect(state_db.STATE_DB, False) + # Check if ifname already exist or if index/ifindex changed due to + # syncd restart + if (ifname in self.cur_interfaces and + self.cur_interfaces[ifname] == (index, ifindex)): + return - ipdb = IPDB() + _hash = '{}|{}'.format('PORT_INDEX_TABLE', ifname) + + if op == 'SET': + self.cur_interfaces[ifname] = (index, ifindex) + self.set_port_index_table_entry(_hash, str(index), str(ifindex)) + elif op == 'DEL': + del self.cur_interfaces[ifname] + self.state_db.delete(self.state_db.STATE_DB, _hash) + + def listen(self): + SELECT_TIMEOUT_MS = -1 # Infinite wait + + while True: + (state, c) = self.sel.select(SELECT_TIMEOUT_MS) + if state == swsscommon.Select.OBJECT: + for t in self.tlbs: + (key, op, cfvs) = t.pop() + if op == 'DEL' and key in self.cur_interfaces: + self.update_db(key, op) + elif (op == 'SET' and key != 'PortInitDone' and + key not in self.cur_interfaces): + self.update_db(key, op) + elif state == swsscomm.Select.ERROR: + logger.log_error("Receieved error from select()") + break - # Initialize the table at startup. - ifnames = ipdb.by_name.keys() - for ifname in ifnames: - index = port_util.get_index_from_str(ifname) - if index is None: - continue - ifindex = ipdb.interfaces[ifname]['index'] - _hash = '{}|{}'.format(PORT_INDEX_TABLE_NAME, ifname) - set_port_index_table_entry(_hash, str(index), str(ifindex)) + def populate(self): + SELECT_TIMEOUT_MS = 0 - ipdb.register_callback(interface_callback) + while True: + (state, c) = self.sel.select(SELECT_TIMEOUT_MS) + if state == swsscommon.Select.OBJECT: + for t in self.tlbs: + (key, op, cfvs) = t.pop() + if key and key != 'PortInitDone': + self.update_db(key, op) + else: + break - signal.pause() def signal_handler(signum, frame): - syslog.syslog(syslog.LOG_NOTICE, "got signal %d" % signum) + logger.log_notice("got signal {}".format(signum)) sys.exit(0) + +def main(): + port_mapper = PortIndexMapper() + port_mapper.populate() + port_mapper.listen() + if __name__ == '__main__': rc = 0 try: - syslog.openlog(SYSLOG_IDENTIFIER) signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGINT, signal_handler) main() - except Exception, e: - t = sys.exc_info()[2] - traceback.print_tb(t) - syslog.syslog(syslog.LOG_CRIT, "%s" % str(e)) + except Exception as e: + tb = sys.exc_info()[2] + traceback.print_tb(tb) + logger.log_error("%s" % str(e)) rc = -1 finally: - if ipdb is not None: - ipdb.release() - else: - syslog.syslog(syslog.LOG_ERR, "ipdb undefined in signal_handler") - - syslog.closelog() sys.exit(rc) - From ad555d9ffd4f131cfbe7485d96dd89551147783e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 6 Nov 2020 10:15:49 -0800 Subject: [PATCH 1339/1427] [restore_nat_entries.py] Convert to Python 3 (#5788) - Convert restore_nat_entries.py script to Python 3 - Use logger from sonic-py-common for uniform logging - Reorganize imports alphabetically per PEP8 standard - Two blank lines precede functions per PEP8 standard --- dockers/docker-nat/restore_nat_entries.py | 38 +++++++++++++---------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/dockers/docker-nat/restore_nat_entries.py b/dockers/docker-nat/restore_nat_entries.py index fc446f3655a6..a0c52ef8f5a7 100755 --- a/dockers/docker-nat/restore_nat_entries.py +++ b/dockers/docker-nat/restore_nat_entries.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """" Description: restore_nat_entries.py -- restoring nat entries table into kernel during system warm reboot. @@ -11,13 +11,15 @@ reconciliation process. """ -import sys +import os +import re import subprocess +import sys + +from sonic_py_common.logger import Logger from swsscommon import swsscommon -import logging -import logging.handlers -import re -import os + +SYSLOG_IDENTIFIER = os.path.basename(__file__) WARM_BOOT_FILE_DIR = '/var/warmboot/nat/' NAT_WARM_BOOT_FILE = 'nat_entries.dump' @@ -25,10 +27,10 @@ MATCH_CONNTRACK_ENTRY = '^(\w+)\s+(\d+).*src=([\d.]+)\s+dst=([\d.]+)\s+sport=(\d+)\s+dport=(\d+).*src=([\d.]+)\s+dst=([\d.]+)\s+sport=(\d+)\s+dport=(\d+)' -logger = logging.getLogger(__name__) -logger.setLevel(logging.INFO) -handler = logging.handlers.SysLogHandler(address = '/dev/log') -logger.addHandler(handler) +# Global logger instance +logger = Logger(SYSLOG_IDENTIFIER) +logger.set_min_log_priority_info() + def add_nat_conntrack_entry_in_kernel(ipproto, srcip, dstip, srcport, dstport, natsrcip, natdstip, natsrcport, natdstport): # pyroute2 doesn't have support for adding conntrack entries via netlink yet. So, invoking the conntrack utility to add the entries. @@ -39,7 +41,8 @@ def add_nat_conntrack_entry_in_kernel(ipproto, srcip, dstip, srcport, dstport, n ' --protonum ' + ipproto + state + ' --timeout 432000 --src ' + srcip + ' --sport ' + srcport + \ ' --dst ' + dstip + ' --dport ' + dstport + ' -u ASSURED' subprocess.call(ctcmd, shell=True) - logger.info("Restored NAT entry: {}".format(ctcmd)) + logger.log_info("Restored NAT entry: {}".format(ctcmd)) + # Set the statedb "NAT_RESTORE_TABLE|Flags", so natsyncd can start reconciliation def set_statedb_nat_restore_done(): @@ -49,6 +52,7 @@ def set_statedb_nat_restore_done(): tbl.set("Flags", fvs) return + # This function is to restore the kernel nat entries based on the saved nat entries. def restore_update_kernel_nat_entries(filename): # Read the entries from nat_entries.dump file and add them to kernel @@ -64,8 +68,9 @@ def restore_update_kernel_nat_entries(filename): continue add_nat_conntrack_entry_in_kernel(*cmdargs) + def main(): - logger.info("restore_nat_entries service is started") + logger.log_info("restore_nat_entries service is started") # Use warmstart python binding to check warmstart information warmstart = swsscommon.WarmStart() @@ -74,13 +79,13 @@ def main(): # if swss or system warm reboot not enabled, don't run if not warmstart.isWarmStart(): - logger.info("restore_nat_entries service is skipped as warm restart not enabled") + logger.log_info("restore_nat_entries service is skipped as warm restart not enabled") return # NAT restart not system warm reboot, set statedb directly if not warmstart.isSystemWarmRebootEnabled(): set_statedb_nat_restore_done() - logger.info("restore_nat_entries service is done as system warm reboot not enabled") + logger.log_info("restore_nat_entries service is done as system warm reboot not enabled") return # Program the nat conntrack entries in the kernel by reading the @@ -88,7 +93,7 @@ def main(): try: restore_update_kernel_nat_entries(WARM_BOOT_FILE_DIR + NAT_WARM_BOOT_FILE) except Exception as e: - logger.exception(str(e)) + logger.log_error(str(e)) sys.exit(1) # Remove the dump file after restoration @@ -96,8 +101,9 @@ def main(): # set statedb to signal other processes like natsyncd set_statedb_nat_restore_done() - logger.info("restore_nat_entries service is done for system warmreboot") + logger.log_info("restore_nat_entries service is done for system warmreboot") return + if __name__ == '__main__': main() From 9bc693ce6e98dbb6a875e1b4d4d1691cf03f67df Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Fri, 6 Nov 2020 20:24:31 +0200 Subject: [PATCH 1340/1427] [hostcfgd] If feature state entry not in the cache, add a default state (#5777) Our use case is to register new features in runtime. The previous change which introduced the cache broke this capability and caused hostcfgd crash. Signed-off-by: Stepan Blyshchak --- files/image_config/hostcfgd/hostcfgd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 9c86cedc7db6..75086b45fe1a 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -368,6 +368,8 @@ class HostConfigDaemon: syslog.syslog(syslog.LOG_WARNING, "Enable state of feature '{}' is None".format(feature_name)) return + self.cached_feature_states.setdefault(feature_name, 'disabled') + # Enable/disable the container service if the feature state was changed from its previous state. if self.cached_feature_states[feature_name] != state: self.cached_feature_states[feature_name] = state From 174b741dfdf9ea52a016920afb202c28ce1f6c06 Mon Sep 17 00:00:00 2001 From: dflynn-Nokia <60479697+dflynn-Nokia@users.noreply.github.com> Date: Fri, 6 Nov 2020 15:37:41 -0500 Subject: [PATCH 1341/1427] [submodule]: update sonic-linux-kernel (#5829) pick up follow commits: > hwmon-lm75: backport support for PCT2075 thermal sensor (#165) > [arista] Reassign prefetch memory per platform (#163) > Add .gitignore file (#157) > Enable PCA9541 I2C mux module (#160) --- src/sonic-linux-kernel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index d155c1ea89ee..af486c6ecdda 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit d155c1ea89eecbb15409aea82e67e8dfc8e2196e +Subproject commit af486c6ecdda8c6bde8b8d5b2cb89e8d27655355 From cdcd20a7b5c9ab8bc99465221a2588ddd509470c Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 6 Nov 2020 17:47:08 -0800 Subject: [PATCH 1342/1427] [BGP]: Convert ip address to network address for the LOCAL_VLAN filter (#5832) * [BGP]: Convert ip address to network address for the LOCAL_VLAN prefix filter --- dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 4 ++-- .../tests/data/sonic-cfggen/bgpd.conf.j2/all.conf | 4 ++-- .../tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf | 4 ++-- .../tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf | 4 ++-- .../tests/data/sonic-cfggen/frr.conf.j2/all.conf | 4 ++-- src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf | 2 +- src/sonic-config-engine/tests/sample_output/py2/frr.conf | 2 +- src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf | 2 +- src/sonic-config-engine/tests/sample_output/py3/frr.conf | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index 30a399d0af8b..eab4a2702191 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -19,13 +19,13 @@ ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTE {% endif %} {% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} {% if prefix | ipv4 and name not in vnet_intfs %} -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq {{ loop.index * 5 }} permit {{ prefix }} +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq {{ loop.index * 5 }} permit {{ prefix | ip_network }}/{{ prefix | prefixlen }} ! {% endif %} {% endfor %} {% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} {% if prefix | ipv6 and name not in vnet_intfs %} -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq {{ loop.index * 5 }} permit {{ prefix }} +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq {{ loop.index * 5 }} permit {{ prefix | ip_network }}/{{ prefix | prefixlen }} ! {% endif %} {% endfor %} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf index 6d79e4c2264d..7671d026ef63 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf @@ -33,9 +33,9 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.0/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 5 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 5 permit fc01::/64 ! ! route-map HIDE_INTERNAL permit 10 diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf index d771ff49c92d..249e70c91d76 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf @@ -11,9 +11,9 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.0/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 15 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 15 permit fc01::/64 ! ! route-map HIDE_INTERNAL permit 10 diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf index e9296f8627d9..d79234ffdb38 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf @@ -11,9 +11,9 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.0/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 15 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 15 permit fc01::/64 ! ! route-map HIDE_INTERNAL permit 10 diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf index 775861ef47c2..4b88beb66565 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf @@ -51,9 +51,9 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.0/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 5 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 5 permit fc01::/64 ! ! route-map HIDE_INTERNAL permit 10 diff --git a/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf index 60fd3ded8444..0ff779e72203 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf @@ -33,7 +33,7 @@ ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.1/27 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.0/27 ! ! ! diff --git a/src/sonic-config-engine/tests/sample_output/py2/frr.conf b/src/sonic-config-engine/tests/sample_output/py2/frr.conf index 08777924d14a..f0264e4b3055 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/py2/frr.conf @@ -51,7 +51,7 @@ ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.1/27 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.0/27 ! ! ! diff --git a/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf index 60fd3ded8444..0ff779e72203 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf @@ -33,7 +33,7 @@ ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.1/27 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.0/27 ! ! ! diff --git a/src/sonic-config-engine/tests/sample_output/py3/frr.conf b/src/sonic-config-engine/tests/sample_output/py3/frr.conf index 374b3bf5f043..5f80b6071aa2 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/frr.conf @@ -51,7 +51,7 @@ ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.1/27 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.0/27 ! ! ! From e6796da141fa517be3fd5839c96510aff2870ffc Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 7 Nov 2020 00:46:18 -0800 Subject: [PATCH 1343/1427] [init_cfg.json.j2]: only enable gbsyncd feature for vs platform (#5815) currently only vs platform has gdbsyncd feature built Signed-off-by: Guohan Lu --- files/build_templates/init_cfg.json.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 164f8a43649b..6cec963fc921 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -26,8 +26,8 @@ ("snmp", "enabled", true, "enabled"), ("swss", "enabled", false, "enabled"), ("syncd", "enabled", false, "enabled"), - ("gbsyncd", "enabled", false, "enabled"), ("teamd", "enabled", false, "enabled")] %} +{%- if sonic_asic_platform == "vs" %}{% do features.append(("gbsyncd", "enabled", false, "enabled")) %}{% endif %} {%- if include_iccpd == "y" %}{% do features.append(("iccpd", "disabled", false, "enabled")) %}{% endif %} {%- if include_mgmt_framework == "y" %}{% do features.append(("mgmt-framework", "enabled", true, "enabled")) %}{% endif %} {%- if include_nat == "y" %}{% do features.append(("nat", "disabled", false, "enabled")) %}{% endif %} From 32a832a8ac9dbeba35be9e13c4dd73c2cdc9e543 Mon Sep 17 00:00:00 2001 From: Petro Bratash <68950226+bratashX@users.noreply.github.com> Date: Sat, 7 Nov 2020 20:30:41 +0200 Subject: [PATCH 1344/1427] [lldp]: Add verification IPv4 address on LLDP conf Jinja2 Template (#5699) Fix #5812 LLDP conf Jinja2 Template does not verify IPv4 address and can use IPv6 version. This issue does not effect control LLDP daemon. Issue can be reproduced via `test_snmp_lldp` test. LLDP conf Jinja2 Template selects first item from the list of mgmt interfaces. TESTBED_1 LLDP conf ``` # cat /etc/lldpd.conf configure ports eth0 lldp portidsubtype local eth0 configure system ip management pattern FC00:3::32 configure system hostname dut-1 ``` TESTBED_2 LLDP conf ``` # cat /etc/lldpd.conf configure ports eth0 lldp portidsubtype local eth0 configure system ip management pattern 10.22.24.61 configure system hostname dut-2 ``` TESTBED_1 MGMT_INTERFACE ``` $ redis-cli -n 4 keys "*" | grep MGMT_INTERFACE MGMT_INTERFACE|eth0|10.22.24.53/23 MGMT_INTERFACE|eth0|FC00:3::32/64 ``` TESTBED_2 MGMT_INTERFACE ``` $ redis-cli -n 4 keys "*" | grep MGMT_INTERFACE MGMT_INTERFACE|eth0|FC00:3::32/64 MGMT_INTERFACE|eth0|10.22.24.61/23 ``` Signed-off-by: Petro Bratash --- dockers/docker-lldp/lldpd.conf.j2 | 19 ++++++++++----- .../tests/data/lldp/mgmt_iface_ipv4.json | 12 ++++++++++ .../data/lldp/mgmt_iface_ipv4_and_ipv6.json | 15 ++++++++++++ .../tests/data/lldp/mgmt_iface_ipv6.json | 12 ++++++++++ .../lldpd-ipv4-iface.conf} | 0 .../py2/lldp_conf/lldpd-ipv6-iface.conf | 2 ++ .../lldpd-ipv4-iface.conf} | 0 .../py3/lldp_conf/lldpd-ipv6-iface.conf | 2 ++ src/sonic-config-engine/tests/test_j2files.py | 23 +++++++++++++++++-- 9 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4.json create mode 100644 src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4_and_ipv6.json create mode 100644 src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv6.json rename src/sonic-config-engine/tests/sample_output/py2/{lldpd.conf => lldp_conf/lldpd-ipv4-iface.conf} (100%) create mode 100644 src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv6-iface.conf rename src/sonic-config-engine/tests/sample_output/py3/{lldpd.conf => lldp_conf/lldpd-ipv4-iface.conf} (100%) create mode 100644 src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv6-iface.conf diff --git a/dockers/docker-lldp/lldpd.conf.j2 b/dockers/docker-lldp/lldpd.conf.j2 index ae7f3fc4838b..904784ef67b1 100644 --- a/dockers/docker-lldp/lldpd.conf.j2 +++ b/dockers/docker-lldp/lldpd.conf.j2 @@ -1,13 +1,20 @@ +{% set mgmt_if = {} %} {% if MGMT_INTERFACE %} +{% for (mgmt_name, mgmt_prefix) in MGMT_INTERFACE|pfx_filter %} +{% if mgmt_prefix|ipv4 %} +{% if mgmt_if.update({'port_name' : mgmt_name}) %} {% endif %} +{% if mgmt_if.update({'ipv4' : mgmt_prefix|ip}) %} {% endif %} +{% endif %} +{% endfor %} +{% endif %} +{% if mgmt_if %} {# If MGMT port alias is available, use it for port ID subtype, otherwise use port name #} -{% set mgmt_port_name = (MGMT_INTERFACE.keys()|list)[0][0] %} -{% set ipv4 = (MGMT_INTERFACE.keys()|list)[0][1].split('/')[0] %} -{% if MGMT_PORT and MGMT_PORT[mgmt_port_name] and MGMT_PORT[mgmt_port_name].alias %} -configure ports eth0 lldp portidsubtype local {{ MGMT_PORT[mgmt_port_name].alias }} +{% if MGMT_PORT and MGMT_PORT[mgmt_if.port_name] and MGMT_PORT[mgmt_if.port_name].alias %} +configure ports eth0 lldp portidsubtype local {{ MGMT_PORT[mgmt_if.port_name].alias }} {% else %} -configure ports eth0 lldp portidsubtype local {{ mgmt_port_name }} +configure ports eth0 lldp portidsubtype local {{ mgmt_if.port_name }} {% endif %} -configure system ip management pattern {{ ipv4 }} +configure system ip management pattern {{ mgmt_if.ipv4 }} {% endif %} configure system hostname {{ DEVICE_METADATA['localhost']['hostname'] }} {# pause lldpd operations until all interfaces are well configured, resume command will run in lldpmgrd #} diff --git a/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4.json b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4.json new file mode 100644 index 000000000000..c38b677aad7a --- /dev/null +++ b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4.json @@ -0,0 +1,12 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "switch-t0" + } + }, + "MGMT_INTERFACE": { + "eth0|10.0.0.100/24": { + "gwaddr": "10.0.0.100" + } + } +} diff --git a/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4_and_ipv6.json b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4_and_ipv6.json new file mode 100644 index 000000000000..87f887fb870d --- /dev/null +++ b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4_and_ipv6.json @@ -0,0 +1,15 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "switch-t0" + } + }, + "MGMT_INTERFACE": { + "eth0|10.0.0.100/24": { + "gwaddr": "10.0.0.100" + }, + "eth0|2603:10e2:0:2902::8/64": { + "gwaddr": "2603:10e2:0:2902::8" + } + } +} diff --git a/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv6.json b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv6.json new file mode 100644 index 000000000000..c1dd4964c6bf --- /dev/null +++ b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv6.json @@ -0,0 +1,12 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "switch-t0" + } + }, + "MGMT_INTERFACE": { + "eth0|2603:10e2:0:2902::8/64": { + "gwaddr": "2603:10e2:0:2902::8" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py2/lldpd.conf b/src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv4-iface.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/py2/lldpd.conf rename to src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv4-iface.conf diff --git a/src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv6-iface.conf b/src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv6-iface.conf new file mode 100644 index 000000000000..f5727556fdf3 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv6-iface.conf @@ -0,0 +1,2 @@ +configure system hostname switch-t0 +pause diff --git a/src/sonic-config-engine/tests/sample_output/py3/lldpd.conf b/src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv4-iface.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/py3/lldpd.conf rename to src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv4-iface.conf diff --git a/src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv6-iface.conf b/src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv6-iface.conf new file mode 100644 index 000000000000..f5727556fdf3 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv6-iface.conf @@ -0,0 +1,2 @@ +configure system hostname switch-t0 +pause diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 2dec13425e19..e59cb010ef79 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -68,9 +68,28 @@ def test_dhcp_relay(self): def test_lldp(self): lldpd_conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-lldp', 'lldpd.conf.j2') - argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + lldpd_conf_template + ' > ' + self.output_file + + expected_mgmt_ipv4 = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'lldp_conf', 'lldpd-ipv4-iface.conf') + expected_mgmt_ipv6 = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'lldp_conf', 'lldpd-ipv6-iface.conf') + expected_mgmt_ipv4_and_ipv6 = expected_mgmt_ipv4 + + # Test generation of lldpd.conf if IPv4 and IPv6 management interfaces exist + mgmt_iface_ipv4_and_ipv6_json = os.path.join(self.test_dir, "data", "lldp", "mgmt_iface_ipv4_and_ipv6.json") + argument = '-j {} -t {} > {}'.format(mgmt_iface_ipv4_and_ipv6_json, lldpd_conf_template, self.output_file) + self.run_script(argument) + self.assertTrue(filecmp.cmp(expected_mgmt_ipv4_and_ipv6, self.output_file)) + + # Test generation of lldpd.conf if management interface IPv4 only exist + mgmt_iface_ipv4_json = os.path.join(self.test_dir, "data", "lldp", "mgmt_iface_ipv4.json") + argument = '-j {} -t {} > {}'.format(mgmt_iface_ipv4_json, lldpd_conf_template, self.output_file) + self.run_script(argument) + self.assertTrue(filecmp.cmp(expected_mgmt_ipv4, self.output_file)) + + # Test generation of lldpd.conf if Management interface IPv6 only exist + mgmt_iface_ipv6_json = os.path.join(self.test_dir, "data", "lldp", "mgmt_iface_ipv6.json") + argument = '-j {} -t {} > {}'.format(mgmt_iface_ipv6_json, lldpd_conf_template, self.output_file) self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'lldpd.conf'), self.output_file)) + self.assertTrue(filecmp.cmp(expected_mgmt_ipv6, self.output_file)) def test_bgpd_quagga(self): conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-quagga', 'bgpd.conf.j2') From 9e7e092610b048a5c16d17c3c0e4b30a7e9dbe94 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 7 Nov 2020 12:46:23 -0800 Subject: [PATCH 1345/1427] [Monit process_checker] Convert to Python 3 (#5836) Convert process_checker script to Python 3 --- files/image_config/monit/process_checker | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/files/image_config/monit/process_checker b/files/image_config/monit/process_checker index e2846fae9f93..98b9cd57ba4c 100755 --- a/files/image_config/monit/process_checker +++ b/files/image_config/monit/process_checker @@ -1,4 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 + import argparse import sys import syslog @@ -16,10 +17,10 @@ def check_process_existence(container_name, process_cmdline): config_db.connect() feature_table = config_db.get_table("FEATURE") - if container_name in feature_table.keys(): + if container_name in feature_table: # We look into the 'FEATURE' table to verify whether the container is disabled or not. # If the container is diabled, we exit. - if ("state" in feature_table[container_name].keys() + if ("state" in feature_table[container_name] and feature_table[container_name]["state"] == "disabled"): sys.exit(0) else: From 04d0e8ab00e5ed82e7b9749b550ddbdf6ad77a68 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 7 Nov 2020 12:48:19 -0800 Subject: [PATCH 1346/1427] [hostcfgd] Convert to Python 3; Add to sonic-host-services package (#5713) To consolidate host services and install via packages instead of file-by-file, also as part of migrating all of SONiC to Python 3, as Python 2 is no longer supported. --- files/build_templates/sonic_debian_extension.j2 | 6 ------ src/sonic-host-services-data/MAINTAINERS | 2 +- src/sonic-host-services-data/debian/install | 1 + src/sonic-host-services-data/debian/rules | 1 + .../sonic-host-services-data.hostcfgd.service | 2 +- .../templates}/common-auth-sonic.j2 | 0 .../templates}/tacplus_nss.conf.j2 | 0 src/sonic-host-services/.gitignore | 1 + .../sonic-host-services/scripts}/hostcfgd | 17 ++++++++--------- src/sonic-host-services/setup.py | 2 ++ 10 files changed, 15 insertions(+), 17 deletions(-) rename files/image_config/hostcfgd/hostcfgd.service => src/sonic-host-services-data/debian/sonic-host-services-data.hostcfgd.service (82%) rename {files/image_config/hostcfgd => src/sonic-host-services-data/templates}/common-auth-sonic.j2 (100%) rename {files/image_config/hostcfgd => src/sonic-host-services-data/templates}/tacplus_nss.conf.j2 (100%) rename {files/image_config/hostcfgd => src/sonic-host-services/scripts}/hostcfgd (98%) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 52b6205e1487..ad37bb312911 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -324,12 +324,6 @@ sudo cp files/dhcp/90-dhcp6-systcl.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMP sudo cp $IMAGE_CONFIGS/interfaces/init_interfaces $FILESYSTEM_ROOT/etc/network/interfaces sudo mkdir -p $FILESYSTEM_ROOT/etc/network/interfaces.d -# Copy hostcfgd files -sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM -echo "hostcfgd.service" | sudo tee -a $GENERATED_SERVICE_FILE -sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd $FILESYSTEM_ROOT/usr/bin/ -sudo cp $IMAGE_CONFIGS/hostcfgd/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ - # copy core file uploader files sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable core_uploader.service diff --git a/src/sonic-host-services-data/MAINTAINERS b/src/sonic-host-services-data/MAINTAINERS index fde1eede3214..09c497897e62 100644 --- a/src/sonic-host-services-data/MAINTAINERS +++ b/src/sonic-host-services-data/MAINTAINERS @@ -1,4 +1,4 @@ -# This file describes the maintainers for sonic-device-data +# This file describes the maintainers for sonic-host-services-data # See the SONiC project governance document for more information Name = "Joe LeVeque" diff --git a/src/sonic-host-services-data/debian/install b/src/sonic-host-services-data/debian/install index e69de29bb2d1..839eb8d0e127 100644 --- a/src/sonic-host-services-data/debian/install +++ b/src/sonic-host-services-data/debian/install @@ -0,0 +1 @@ +templates/*.j2 /usr/share/sonic/templates/ diff --git a/src/sonic-host-services-data/debian/rules b/src/sonic-host-services-data/debian/rules index 65ed966382c4..9de6b974f599 100755 --- a/src/sonic-host-services-data/debian/rules +++ b/src/sonic-host-services-data/debian/rules @@ -7,4 +7,5 @@ build: override_dh_installsystemd: dh_installsystemd --no-start --name=caclmgrd + dh_installsystemd --no-start --name=hostcfgd dh_installsystemd --no-start --name=procdockerstatsd diff --git a/files/image_config/hostcfgd/hostcfgd.service b/src/sonic-host-services-data/debian/sonic-host-services-data.hostcfgd.service similarity index 82% rename from files/image_config/hostcfgd/hostcfgd.service rename to src/sonic-host-services-data/debian/sonic-host-services-data.hostcfgd.service index 762786ad830e..ea0c3ba60fb7 100644 --- a/files/image_config/hostcfgd/hostcfgd.service +++ b/src/sonic-host-services-data/debian/sonic-host-services-data.hostcfgd.service @@ -5,7 +5,7 @@ After=updategraph.service [Service] Type=simple -ExecStart=/usr/bin/hostcfgd +ExecStart=/usr/local/bin/hostcfgd [Install] WantedBy=multi-user.target diff --git a/files/image_config/hostcfgd/common-auth-sonic.j2 b/src/sonic-host-services-data/templates/common-auth-sonic.j2 similarity index 100% rename from files/image_config/hostcfgd/common-auth-sonic.j2 rename to src/sonic-host-services-data/templates/common-auth-sonic.j2 diff --git a/files/image_config/hostcfgd/tacplus_nss.conf.j2 b/src/sonic-host-services-data/templates/tacplus_nss.conf.j2 similarity index 100% rename from files/image_config/hostcfgd/tacplus_nss.conf.j2 rename to src/sonic-host-services-data/templates/tacplus_nss.conf.j2 diff --git a/src/sonic-host-services/.gitignore b/src/sonic-host-services/.gitignore index 730e4244bebd..70be1ce98629 100644 --- a/src/sonic-host-services/.gitignore +++ b/src/sonic-host-services/.gitignore @@ -1,6 +1,7 @@ # Compiled Python files *.pyc scripts/caclmgrdc +scripts/hostcfgdc scripts/procdockerstatsdc # Generated by packaging diff --git a/files/image_config/hostcfgd/hostcfgd b/src/sonic-host-services/scripts/hostcfgd similarity index 98% rename from files/image_config/hostcfgd/hostcfgd rename to src/sonic-host-services/scripts/hostcfgd index 75086b45fe1a..b97d800db3eb 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/src/sonic-host-services/scripts/hostcfgd @@ -1,16 +1,15 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- +#!/usr/bin/env python3 import ast +import copy +import ipaddress import os -import sys import subprocess import syslog -import copy + import jinja2 -import ipaddr as ipaddress -from swsssdk import ConfigDBConnector from sonic_py_common import device_info +from swsssdk import ConfigDBConnector # FILE PAM_AUTH_CONF = "/etc/pam.d/common-auth-sonic" @@ -80,7 +79,7 @@ class Iptables(object): iface, ip = key ip_str = ip.split("/")[0] - ip_addr = ipaddress.IPAddress(ip_str) + ip_addr = ipaddress.ip_address(ip_str) if isinstance(ip_addr, ipaddress.IPv6Address): ver = '6' else: @@ -313,7 +312,7 @@ class HostConfigDaemon: def update_all_feature_states(self): feature_table = self.config_db.get_table('FEATURE') - for feature_name in feature_table.keys(): + for feature_name in feature_table: if not feature_name: syslog.syslog(syslog.LOG_WARNING, "Feature is None") continue @@ -359,7 +358,7 @@ class HostConfigDaemon: def feature_state_handler(self, key, data): feature_name = key feature_table = self.config_db.get_table('FEATURE') - if feature_name not in feature_table.keys(): + if feature_name not in feature_table: syslog.syslog(syslog.LOG_WARNING, "Feature '{}' not in FEATURE table".format(feature_name)) return diff --git a/src/sonic-host-services/setup.py b/src/sonic-host-services/setup.py index 3fab561da867..d0f7bd055683 100644 --- a/src/sonic-host-services/setup.py +++ b/src/sonic-host-services/setup.py @@ -12,9 +12,11 @@ maintainer_email = 'jolevequ@microsoft.com', scripts = [ 'scripts/caclmgrd', + 'scripts/hostcfgd', 'scripts/procdockerstatsd', ], install_requires = [ + 'Jinja2>=2.10', 'sonic-py-common', 'swsssdk>=2.0.1', ], From 6156cb2805b8723121361d3186afd16d151dfbb5 Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Sat, 7 Nov 2020 13:03:41 -0800 Subject: [PATCH 1347/1427] [sonic-yang-mgmt] Build PY3 & PY2 packages (#5559) Moving sonic-yang-mgmt to PY3 to support move of sonic-utilities to PY3. Signed-off-by: Praveen Chaudhary --- .../build_templates/sonic_debian_extension.j2 | 18 ++++-- platform/vs/docker-sonic-vs.mk | 2 +- platform/vs/docker-sonic-vs/Dockerfile.j2 | 5 -- rules/sonic-utilities.mk | 2 +- rules/sonic-yang-mgmt-py2.dep | 8 +-- rules/sonic-yang-mgmt-py2.mk | 14 ++--- rules/sonic-yang-mgmt-py3.dep | 10 ++++ rules/sonic-yang-mgmt-py3.mk | 11 ++++ slave.mk | 6 +- sonic-slave-buster/Dockerfile.j2 | 6 +- sonic-slave-stretch/Dockerfile.j2 | 8 +-- src/sonic-yang-mgmt/setup.cfg | 2 + src/sonic-yang-mgmt/setup.py | 44 +++++---------- src/sonic-yang-mgmt/sonic_yang_ext.py | 10 ++-- .../libyang-python-tests/test_sonic_yang.py | 6 +- src/sonic-yang-models/setup.cfg | 2 + src/sonic-yang-models/setup.py | 55 ++++--------------- .../tests/test_sonic_yang_models.py | 18 +++++- ...yangModelTesting.py => test_yang_model.py} | 55 ++++++++++--------- .../tests/yang_model_tests/yangTest.json | 2 +- .../yang-models/sonic-loopback-interface.yang | 2 + .../yang-models/sonic-vlan.yang | 2 + 22 files changed, 145 insertions(+), 143 deletions(-) create mode 100644 rules/sonic-yang-mgmt-py3.dep create mode 100644 rules/sonic-yang-mgmt-py3.mk create mode 100644 src/sonic-yang-mgmt/setup.cfg create mode 100644 src/sonic-yang-models/setup.cfg rename src/sonic-yang-models/tests/yang_model_tests/{yangModelTesting.py => test_yang_model.py} (96%) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index ad37bb312911..9e189ae90ac1 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -154,15 +154,23 @@ sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY2_WHEEL_NAME sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang_*.deb sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang-cpp_*.deb sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python2-yang_*.deb +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python3-yang_*.deb SONIC_YANG_MODEL_PY3_WHEEL_NAME=$(basename {{sonic_yang_models_py3_wheel_path}}) sudo cp {{sonic_yang_models_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MODEL_PY3_WHEEL_NAME sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_YANG_MODEL_PY3_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MODEL_PY3_WHEEL_NAME -# Install sonic-yang-mgmt Python package -SONIC_YANG_MGMT_PY_WHEEL_NAME=$(basename {{sonic_yang_mgmt_py_wheel_path}}) -sudo cp {{sonic_yang_mgmt_py_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $SONIC_YANG_MGMT_PY_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY_WHEEL_NAME + +# Install sonic-yang-mgmt Python2 package +SONIC_YANG_MGMT_PY2_WHEEL_NAME=$(basename {{sonic_yang_mgmt_py2_wheel_path}}) +sudo cp {{sonic_yang_mgmt_py2_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $SONIC_YANG_MGMT_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY2_WHEEL_NAME + +# Install sonic-yang-mgmt Python3 package +SONIC_YANG_MGMT_PY3_WHEEL_NAME=$(basename {{sonic_yang_mgmt_py3_wheel_path}}) +sudo cp {{sonic_yang_mgmt_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_YANG_MGMT_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY3_WHEEL_NAME # Install sonic-platform-common Python 2 package PLATFORM_COMMON_PY2_WHEEL_NAME=$(basename {{platform_common_py2_wheel_path}}) diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index 273611e0ae36..875b649adc39 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -22,7 +22,7 @@ $(DOCKER_SONIC_VS)_PYTHON_WHEELS += $(SWSSSDK_PY2) \ $(SONIC_PY_COMMON_PY2) \ $(SONIC_PY_COMMON_PY3) \ $(SONIC_YANG_MODELS_PY3) \ - $(SONIC_YANG_MGMT_PY) \ + $(SONIC_YANG_MGMT_PY2) \ $(SONIC_UTILITIES_PY2) \ $(SONIC_HOST_SERVICES_PY3) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index b42b736e452c..5f5f91d5a0f0 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -83,11 +83,6 @@ RUN pip2 install urllib3 RUN pip2 install requests RUN pip2 install crontab -# Install dependencies for Dynamic Port Breakout -RUN pip2 install xmltodict==0.12.0 -RUN pip2 install jsondiff==1.2.0 -RUN pip2 install ijson==2.6.1 - {% if docker_sonic_vs_debs.strip() -%} # Copy locally-built Debian package dependencies {%- for deb in docker_sonic_vs_debs.split(' ') %} diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index 3de3de02f0ad..aef970200fb7 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -14,7 +14,7 @@ $(SONIC_UTILITIES_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) \ $(SONIC_PY_COMMON_PY3) \ $(SWSSSDK_PY2) \ $(SONIC_CONFIG_ENGINE_PY2) \ - $(SONIC_YANG_MGMT_PY) \ + $(SONIC_YANG_MGMT_PY2) \ $(SONIC_YANG_MODELS_PY3) $(SONIC_UTILITIES_PY2)_DEBS_DEPENDS = $(LIBYANG) \ $(LIBYANG_CPP) \ diff --git a/rules/sonic-yang-mgmt-py2.dep b/rules/sonic-yang-mgmt-py2.dep index a4ec4264b49a..6a2f30ca34a4 100644 --- a/rules/sonic-yang-mgmt-py2.dep +++ b/rules/sonic-yang-mgmt-py2.dep @@ -1,10 +1,10 @@ -SPATH := $($(SONIC_YANG_MGMT_PY)_SRC_PATH) +SPATH := $($(SONIC_YANG_MGMT_PY2)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-yang-mgmt-py2.mk rules/sonic-yang-mgmt-py2.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) DEP_FILES += $(shell git ls-files $(SPATH)) -$(SONIC_YANG_MGMT_PY)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_YANG_MGMT_PY)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_YANG_MGMT_PY)_DEP_FILES := $(DEP_FILES) +$(SONIC_YANG_MGMT_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_YANG_MGMT_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_YANG_MGMT_PY2)_DEP_FILES := $(DEP_FILES) diff --git a/rules/sonic-yang-mgmt-py2.mk b/rules/sonic-yang-mgmt-py2.mk index 0b85d7eb9bdc..5e44517be4e6 100644 --- a/rules/sonic-yang-mgmt-py2.mk +++ b/rules/sonic-yang-mgmt-py2.mk @@ -1,12 +1,12 @@ # sonic-yang-mgmt python2 wheel -SONIC_YANG_MGMT_PY = sonic_yang_mgmt-1.0-py2-none-any.whl -$(SONIC_YANG_MGMT_PY)_SRC_PATH = $(SRC_PATH)/sonic-yang-mgmt -$(SONIC_YANG_MGMT_PY)_PYTHON_VERSION = 2 -$(SONIC_YANG_MGMT_PY)_DEBS_DEPENDS = $(LIBYANG) $(LIBYANG_CPP) $(LIBYANG_PY2) \ +SONIC_YANG_MGMT_PY2 = sonic_yang_mgmt-1.0-py2-none-any.whl +$(SONIC_YANG_MGMT_PY2)_SRC_PATH = $(SRC_PATH)/sonic-yang-mgmt +$(SONIC_YANG_MGMT_PY2)_PYTHON_VERSION = 2 +$(SONIC_YANG_MGMT_PY2)_DEBS_DEPENDS = $(LIBYANG) $(LIBYANG_CPP) $(LIBYANG_PY2) \ $(LIBYANG_PY3) -$(SONIC_YANG_MGMT_PY)_DEPENDS = $(SONIC_YANG_MODELS_PY3) -$(SONIC_YANG_MGMT_PY)_RDEPENDS = $(SONIC_YANG_MODELS_PY3) $(LIBYANG) \ +$(SONIC_YANG_MGMT_PY2)_DEPENDS = $(SONIC_YANG_MODELS_PY3) +$(SONIC_YANG_MGMT_PY2)_RDEPENDS = $(SONIC_YANG_MODELS_PY3) $(LIBYANG) \ $(LIBYANG_CPP) $(LIBYANG_PY2) -SONIC_PYTHON_WHEELS += $(SONIC_YANG_MGMT_PY) +SONIC_PYTHON_WHEELS += $(SONIC_YANG_MGMT_PY2) diff --git a/rules/sonic-yang-mgmt-py3.dep b/rules/sonic-yang-mgmt-py3.dep new file mode 100644 index 000000000000..e6528220c6d8 --- /dev/null +++ b/rules/sonic-yang-mgmt-py3.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SONIC_YANG_MGMT_PY3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-yang-mgmt-py3.mk rules/sonic-yang-mgmt-py3.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_YANG_MGMT_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_YANG_MGMT_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_YANG_MGMT_PY3)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic-yang-mgmt-py3.mk b/rules/sonic-yang-mgmt-py3.mk new file mode 100644 index 000000000000..877fc6de3952 --- /dev/null +++ b/rules/sonic-yang-mgmt-py3.mk @@ -0,0 +1,11 @@ +# sonic-yang-mgmt python3 wheel + +SONIC_YANG_MGMT_PY3 = sonic_yang_mgmt-1.0-py3-none-any.whl +$(SONIC_YANG_MGMT_PY3)_SRC_PATH = $(SRC_PATH)/sonic-yang-mgmt +$(SONIC_YANG_MGMT_PY3)_PYTHON_VERSION = 3 +$(SONIC_YANG_MGMT_PY3)_DEBS_DEPENDS = $(LIBYANG) $(LIBYANG_CPP) $(LIBYANG_PY3) +$(SONIC_YANG_MGMT_PY3)_DEPENDS = $(SONIC_YANG_MODELS_PY3) +$(SONIC_YANG_MGMT_PY3)_RDEPENDS = $(SONIC_YANG_MODELS_PY3) $(LIBYANG) \ + $(LIBYANG_CPP) $(LIBYANG_PY3) + +SONIC_PYTHON_WHEELS += $(SONIC_YANG_MGMT_PY3) diff --git a/slave.mk b/slave.mk index ba82e717910d..f7b3636d1abc 100644 --- a/slave.mk +++ b/slave.mk @@ -821,7 +821,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SYSTEM_HEALTH)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_HOST_SERVICES_PY3)) $(HEADER) @@ -864,7 +865,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export redis_dump_load_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY3))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" export sonic_yang_models_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3))" - export sonic_yang_mgmt_py_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY))" + export sonic_yang_mgmt_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY2))" + export sonic_yang_mgmt_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY3))" export multi_instance="false" export python_swss_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($(LIBSWSSCOMMON)_RDEPENDS))" export python_swss_debs+=" $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(LIBSWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON_SWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON3_SWSSCOMMON))" diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 03dae31ecd46..66bc0564efcf 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -390,11 +390,7 @@ RUN pip2 install pexpect==4.6.0 # For sonic-swss-common testing RUN pip2 install Pympler==0.8 -# For sonic_yang_mgmt build -RUN pip2 install ijson==2.6.1 -RUN pip3 install ijson==2.6.1 -RUN pip2 install jsondiff==1.2.0 -RUN pip2 install xmltodict==0.12.0 +# For sonic_yang_model build RUN pip2 install pyang==2.1.1 # For mgmt-framework build diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 276bdcbbc1dd..84d87e5973c6 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -339,7 +339,7 @@ RUN pip2 install \ ctypesgen==0.r125 \ crc16 -# Note: Stick with Jinja2 2.x branch as the 3.x dropped support for Python 2.7 +# Note: Stick with Jinja2 2.x branch as the 3.x dropped support for Python 2.7 RUN pip2 install --force-reinstall --upgrade "Jinja2<3.0.0" # For sonic config engine testing @@ -379,11 +379,7 @@ RUN pip2 install setuptools==40.8.0 # For sonic-swss-common testing RUN pip2 install Pympler==0.8 -# For sonic_yang_mgmt build -RUN pip2 install ijson==2.6.1 -RUN pip3 install ijson==2.6.1 -RUN pip2 install jsondiff==1.2.0 -RUN pip2 install xmltodict==0.12.0 +# For sonic_yang_model build RUN pip2 install pyang==2.1.1 # For mgmt-framework build diff --git a/src/sonic-yang-mgmt/setup.cfg b/src/sonic-yang-mgmt/setup.cfg new file mode 100644 index 000000000000..b7e478982ccf --- /dev/null +++ b/src/sonic-yang-mgmt/setup.cfg @@ -0,0 +1,2 @@ +[aliases] +test=pytest diff --git a/src/sonic-yang-mgmt/setup.py b/src/sonic-yang-mgmt/setup.py index 63ea0640f899..cb62c5ac4ee3 100644 --- a/src/sonic-yang-mgmt/setup.py +++ b/src/sonic-yang-mgmt/setup.py @@ -4,37 +4,12 @@ """The setup script.""" from setuptools import setup, find_packages -from setuptools.command.build_py import build_py -from os import system -from sys import exit -import pytest - -setup_requirements = ['pytest-runner'] - -test_requirements = ['pytest>=3'] # read me with open('README.rst') as readme_file: readme = readme_file.read() -# class for prerequisites to build this package -class pkgBuild(build_py): - """Custom Build PLY""" - - def run (self): - # run pytest for libyang python APIs - self.pytest_args = [] - errno = pytest.main(self.pytest_args) - if (errno): - exit(errno) - - # Continue usual build steps - build_py.run(self) - setup( - cmdclass={ - 'build_py': pkgBuild, - }, author="lnos-coders", author_email='lnos-coders@linkedin.com', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', @@ -52,15 +27,26 @@ def run (self): 'Programming Language :: Python :: 3.8', ], description="Package contains Python Library for YANG for sonic.", - tests_require = test_requirements, license="GNU General Public License v3", long_description=readme + '\n\n', + install_requires = [ + 'xmltodict==0.12.0', + 'ijson==2.6.1' + ], + tests_require = [ + 'pytest>3', + 'xmltodict==0.12.0', + 'ijson==2.6.1' + ], + setup_requires = [ + 'pytest-runner', + 'wheel' + ], include_package_data=True, - keywords='sonic_yang_mgmt', - name='sonic_yang_mgmt', + keywords='sonic-yang-mgmt', + name='sonic-yang-mgmt', py_modules=['sonic_yang', 'sonic_yang_ext'], packages=find_packages(), - setup_requires=setup_requirements, version='1.0', zip_safe=False, ) diff --git a/src/sonic-yang-mgmt/sonic_yang_ext.py b/src/sonic-yang-mgmt/sonic_yang_ext.py index 3cfad3aaaf63..1f0a072be450 100644 --- a/src/sonic-yang-mgmt/sonic_yang_ext.py +++ b/src/sonic-yang-mgmt/sonic_yang_ext.py @@ -129,7 +129,8 @@ def _getModuleTLCcontainer(self, table): """ def _cropConfigDB(self, croppedFile=None): - for table in self.jIn.keys(): + tables = list(self.jIn.keys()) + for table in tables: if table not in self.confDbYangMap: # store in tablesWithOutYang self.tablesWithOutYang[table] = self.jIn[table] @@ -138,7 +139,7 @@ def _cropConfigDB(self, croppedFile=None): if len(self.tablesWithOutYang): print("Note: Below table(s) have no YANG models:") for table in self.tablesWithOutYang.keys(): - print(unicode(table), end=", ") + print(str(table), end=", ") print() if croppedFile: @@ -274,13 +275,14 @@ def _xlateList(self, model, yang, config, table): # fetch regex from YANG models. keyRegEx = model['ext:key-regex-configdb-to-yang']['@value'] # seperator `|` has special meaning in regex, so change it appropriately. - keyRegEx = re.sub('\|', '\\|', keyRegEx) + keyRegEx = re.sub(r'\|', r'\\|', keyRegEx) # get keys from YANG model list itself listKeys = model['key']['@value'] self.sysLog(msg="xlateList regex:{} keyList:{}".\ format(keyRegEx, listKeys)) - for pkey in config.keys(): + primaryKeys = list(config.keys()) + for pkey in primaryKeys: try: vKey = None self.sysLog(syslog.LOG_DEBUG, "xlateList Extract pkey:{}".\ diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py index b5fa35842990..597d13da0874 100644 --- a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py @@ -64,8 +64,8 @@ def setup_class(self): def load_yang_model_file(self, yang_s, yang_dir, yang_file, module_name): yfile = yang_dir + yang_file try: - yang_s._load_schema_module(str(yfile)) - except Exception as e: + yang_s._load_schema_module(str(yfile)) + except Exception as e: print(e) raise @@ -106,7 +106,7 @@ def test_load_yang_model_data(self, data, yang_s): data_files = [] data_files.append(data_file) data_files.append(data_merge_file) - print(yang_files) + print(yang_files) yang_s._load_data_model(yang_dir, yang_files, data_files) #validate the data tree from data_merge_file is loaded diff --git a/src/sonic-yang-models/setup.cfg b/src/sonic-yang-models/setup.cfg new file mode 100644 index 000000000000..b7e478982ccf --- /dev/null +++ b/src/sonic-yang-models/setup.cfg @@ -0,0 +1,2 @@ +[aliases] +test=pytest diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 6add4c22bffa..9e750ca87480 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -4,51 +4,12 @@ """The setup script.""" from setuptools import setup, find_packages -from setuptools.command.build_py import build_py -from os import system -from sys import exit - -setup_requirements = ['pytest-runner'] - -test_requirements = ['pytest>=3'] # read me with open('README.rst') as readme_file: readme = readme_file.read() -# class for prerequisites to build this package -class pkgBuild(build_py): - """Custom Build PLY""" - - def run (self): - # json file for YANG model test cases. - test_yangJson_file = './tests/yang_model_tests/yangTest.json' - # YANG models are in below dir - yang_model_dir = './yang-models/' - # yang model tester python module - yang_test_py = './tests/yang_model_tests/yangModelTesting.py' - # run tests for yang models - test_yang_cmd = "python {} -f {} -y {}".format(yang_test_py, test_yangJson_file, yang_model_dir) - if (system(test_yang_cmd)): - print("YANG Tests failed\n") - exit(1) - else: - print("YANG Tests passed\n") - - # Generate YANG Tree - pyang_tree_cmd = "pyang -f tree ./yang-models/*.yang > ./yang-models/sonic_yang_tree" - if (system(pyang_tree_cmd)): - print("Failed: {}".format(pyang_tree_cmd)) - else: - print("Passed: {}".format(pyang_tree_cmd)) - - # Continue usual build steps - build_py.run(self) - setup( - cmdclass={ - 'build_py': pkgBuild, - }, author="lnos-coders", author_email='lnos-coders@linkedin.com', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', @@ -66,15 +27,23 @@ def run (self): 'Programming Language :: Python :: 3.8', ], description="Package contains YANG models for sonic.", - tests_require = test_requirements, license="GNU General Public License v3", long_description=readme + '\n\n', + install_requires = [ + ], + tests_require = [ + 'pytest', + 'ijson==2.6.1' + ], + setup_requires = [ + 'pytest-runner', + 'wheel' + ], include_package_data=True, - keywords='sonic_yang_models', - name='sonic_yang_models', + keywords='sonic-yang-models', + name='sonic-yang-models', py_modules=[], packages=find_packages(), - setup_requires=setup_requirements, version='1.0', data_files=[ ('yang-models', ['./yang-models/sonic-types.yang', diff --git a/src/sonic-yang-models/tests/test_sonic_yang_models.py b/src/sonic-yang-models/tests/test_sonic_yang_models.py index e8acedf9f974..e5b801a94cb5 100644 --- a/src/sonic-yang-models/tests/test_sonic_yang_models.py +++ b/src/sonic-yang-models/tests/test_sonic_yang_models.py @@ -5,6 +5,9 @@ import pytest +from os import system +from sys import exit + @pytest.fixture def response(): """Sample pytest fixture. @@ -14,8 +17,21 @@ def response(): # import requests # return requests.get('https://github.com/audreyr/cookiecutter-pypackage') - def test_content(response): + """Sample pytest test function with the pytest fixture as an argument.""" + +def test_generate_yang_tree(): + + # Generate YANG Tree, see no error in it. + pyang_tree_cmd = "pyang -f tree ./yang-models/*.yang > ./yang-models/sonic_yang_tree" + if (system(pyang_tree_cmd)): + print("Failed: {}".format(pyang_tree_cmd)) + exit(1) + else: + print("Passed: {}".format(pyang_tree_cmd)) + + return + # from bs4 import BeautifulSoup # assert 'GitHub' in BeautifulSoup(response.content).title.string diff --git a/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py similarity index 96% rename from src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py rename to src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py index 5f21485a5f0f..966af237f272 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py +++ b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py @@ -34,9 +34,9 @@ def printExceptionDetails(): # Run function will run all the tests # from a user given list. -class YangModelTesting: +class Test_yang_models: - def __init__(self, tests, yangDir, jsonFile): + def initTest(self): self.defaultYANGFailure = { 'Must': ['Must condition', 'not satisfied'], 'InvalidValue': ['Invalid value'], @@ -178,11 +178,9 @@ def __init__(self, tests, yangDir, jsonFile): } } - self.tests = tests - if (self.tests == None): - self.tests = self.ExceptionTests.keys()+self.SpecialTests.keys() - self.yangDir = yangDir - self.jsonFile = jsonFile + self.tests = list(self.ExceptionTests.keys())+list(self.SpecialTests.keys()) + self.yangDir = './yang-models/' + self.jsonFile = './tests/yang_model_tests/yangTest.json' self.testNum = 1 # other class vars # self.ctx @@ -212,24 +210,6 @@ def loadYangModel(self, yangDir): raise e return - """ - Run all tests from list self.tests - """ - def run(self): - try: - self.loadYangModel(self.yangDir) - ret = 0 - for test in self.tests: - test = test.strip() - if test in self.ExceptionTests: - ret = ret + self.runExceptionTest(test); - elif test in self.SpecialTests: - ret = ret + self.runSpecialTest(test); - except Exception as e: - printExceptionDetails() - raise e - return ret - """ Get the JSON input based on func name and return jsonInput @@ -313,6 +293,8 @@ def runExceptionTest(self, test): elif (sum(1 for str in eStr if str not in s) == 0): log.info(desc + " Passed\n") return PASS + else: + raise Exception("Unknown Error") except Exception as e: printExceptionDetails() log.info(desc + " Failed\n") @@ -336,7 +318,7 @@ def runVlanSpecialTest(self, test): self.logStartTest(desc) jInput = json.loads(self.readJsonInput(test)) # check all Vlan from 1 to 4094 - for i in xrange(4095): + for i in range(4095): vlan = 'Vlan'+str(i) jInput["sonic-vlan:sonic-vlan"]["sonic-vlan:VLAN"]["VLAN_LIST"]\ [0]["vlan_name"] = vlan @@ -349,6 +331,27 @@ def runVlanSpecialTest(self, test): printExceptionDetails() log.info(desc + " Failed\n") return FAIL + + """ + Run all tests from list self.tests + """ + def test_run_tests(self): + try: + self.initTest() + self.loadYangModel(self.yangDir) + ret = 0 + for test in self.tests: + test = test.strip() + if test in self.ExceptionTests: + ret = ret + self.runExceptionTest(test); + elif test in self.SpecialTests: + ret = ret + self.runSpecialTest(test); + else: + raise Exception("Unexpected Test") + except Exception as e: + printExceptionDetails() + assert ret == 0 + return # End of Class """ diff --git a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json index cd0dafd9e8c4..72c7b4630c33 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json +++ b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json @@ -188,7 +188,7 @@ "sonic-vlan:sonic-vlan": { "sonic-vlan:VLAN_MEMBER": { "VLAN_MEMBER_LIST": [{ - "vlan_name": 100, + "vlan_name": "Vlan100", "port": "Ethernet0", "tagging_mode": "non-tagged" }] diff --git a/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang b/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang index 92b059af64ca..6b509a8df349 100644 --- a/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang +++ b/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang @@ -1,5 +1,7 @@ module sonic-loopback-interface { + yang-version 1.1; + namespace "http://github.com/Azure/sonic-loopback-interface"; prefix lointf; diff --git a/src/sonic-yang-models/yang-models/sonic-vlan.yang b/src/sonic-yang-models/yang-models/sonic-vlan.yang index d05d2a39e6d8..6d2b9b154cbe 100644 --- a/src/sonic-yang-models/yang-models/sonic-vlan.yang +++ b/src/sonic-yang-models/yang-models/sonic-vlan.yang @@ -1,5 +1,7 @@ module sonic-vlan { + yang-version 1.1; + namespace "http://github.com/Azure/sonic-vlan"; prefix vlan; From 23b0e07d48cd635e2649207eb08d1b470240a9ec Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Sat, 7 Nov 2020 13:18:40 -0800 Subject: [PATCH 1348/1427] [minigraph.py]: Parse IP-in-IP tunnels from minigraph (#5742) Take tunnel info from `` tag in minigraph, and create tables in config_DB: ``` "TUNNEL": { "MUX_TUNNEL_0": { "tunnel_type": "IPINIP", "dst_ip": "26.1.1.10", "dscp_mode": "uniform", "encap_ecn_mode": "standard", "ecn_mode": "copy_from_outer", "ttl_mode": "pipe" } } ``` Signed-off-by: Lawrence Lee --- src/sonic-config-engine/minigraph.py | 45 ++++++++++++++-- .../tests/simple-sample-graph-case.xml | 54 ++++++++++++++++++- .../tests/test_minigraph_case.py | 35 +++++++++++- 3 files changed, 129 insertions(+), 5 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 444c0ce52fa8..96b68d7d22ef 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1,6 +1,7 @@ from __future__ import print_function import calendar +from ipaddress import IPv4Address, IPv4Network, ip_address, ip_network import math import os import sys @@ -280,6 +281,7 @@ def parse_loopback_intf(child): def parse_dpg(dpg, hname): aclintfs = None mgmtintfs = None + tunnelintfs = defaultdict(dict) for child in dpg: """ In Multi-NPU platforms the acl intfs are defined only for the host not for individual asic. @@ -473,7 +475,25 @@ def parse_dpg(dpg, hname): except: print("Warning: Ignoring Control Plane ACL %s without type" % aclname, file=sys.stderr) - return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni + mg_tunnels = child.find(str(QName(ns, "TunnelInterfaces"))) + if mg_tunnels is not None: + table_key_to_mg_key_map = {"encap_ecn_mode": "EcnEncapsulationMode", + "ecn_mode": "EcnDecapsulationMode", + "dscp_mode": "DifferentiatedServicesCodePointMode", + "ttl_mode": "TtlMode"} + for mg_tunnel in mg_tunnels.findall(str(QName(ns, "TunnelInterface"))): + tunnel_type = mg_tunnel.attrib["Type"] + tunnel_name = mg_tunnel.attrib["Name"] + tunnelintfs[tunnel_type][tunnel_name] = { + "tunnel_type": mg_tunnel.attrib["Type"].upper(), + } + + for table_key, mg_key in table_key_to_mg_key_map.items(): + # If the minigraph has the key, add the corresponding config DB key to the table + if mg_key in mg_tunnel.attrib: + tunnelintfs[tunnel_type][tunnel_name][table_key] = mg_tunnel.attrib[mg_key] + + return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnelintfs return None, None, None, None, None, None, None, None, None, None def parse_host_loopback(dpg, hname): @@ -866,6 +886,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw intfs = None vlan_intfs = None pc_intfs = None + tunnel_intfs = None vlans = None vlan_members = None pcs = None @@ -923,7 +944,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw for child in root: if asic_name is None: if child.tag == str(QName(ns, "DpgDec")): - (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) + (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs) = parse_dpg(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): @@ -938,7 +959,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) else: if child.tag == str(QName(ns, "DpgDec")): - (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) + (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs) = parse_dpg(child, asic_name) host_lo_intfs = parse_host_loopback(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name, local_devices) @@ -1167,6 +1188,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw results['VLAN'] = vlans results['VLAN_MEMBER'] = vlan_members + results['TUNNEL'] = get_tunnel_entries(tunnel_intfs, lo_intfs, hostname) + for nghbr in list(neighbors.keys()): # remove port not in port_config.ini if nghbr not in ports: @@ -1234,6 +1257,22 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw return results +def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname): + lo_addr = '' + # Use the first IPv4 loopback as the tunnel destination IP + for addr in lo_intfs.keys(): + ip_addr = ip_network(UNICODE_TYPE(addr[1])) + if isinstance(ip_addr, IPv4Network): + lo_addr = str(ip_addr.network_address) + break + + tunnels = {} + for type, tunnel_dict in tunnel_intfs.items(): + for tunnel_key, tunnel_attr in tunnel_dict.items(): + tunnel_attr['dst_ip'] = lo_addr + tunnels[tunnel_key] = tunnel_attr + return tunnels + def parse_device_desc_xml(filename): root = ET.parse(filename).getroot() diff --git a/src/sonic-config-engine/tests/simple-sample-graph-case.xml b/src/sonic-config-engine/tests/simple-sample-graph-case.xml index 6c7729fd0696..a3383a094602 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-case.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-case.xml @@ -126,6 +126,9 @@ + + + ab1 @@ -232,12 +235,36 @@ U true + + LogicalLink + 0 + false + switch-t0 + MuxTunnel0 + false + switch2-t0 + MuxTunnel0 + true + +
+ 26.1.1.10 +
switch-t0 Force10-S6000
+ +
+ 25.1.1.10 +
+ + 10.7.0.196/26 + + switch2-t0 + Force10-S6000 +
switch-01t1
@@ -252,6 +279,31 @@ + + + + + + + DevicePeeringLink + + True + + + UpperTOR + + switch-t0 + + + LowerTOR + + switch2-t0 + + + switch2-t0:MuxTunnel0;switch-t0:MuxTunnel0 + + + @@ -372,6 +424,6 @@ - switch-T0 + switch-t0 Force10-S6000 diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index e149ff64670b..de4f6b77ce50 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -121,7 +121,21 @@ def test_minigraph_neighbor_metadata(self): output = self.run_script(argument) self.assertEqual( utils.to_dict(output.strip()), - utils.to_dict("{'switch-01t1': {'lo_addr': '10.1.0.186/32', 'mgmt_addr': '10.7.0.196/26', 'hwsku': 'Force10-S6000', 'type': 'LeafRouter', 'deployment_id': '2'}}") + utils.to_dict("{" \ + "'switch-01t1': {" \ + "'lo_addr': '10.1.0.186/32'," \ + "'mgmt_addr': '10.7.0.196/26'," \ + "'hwsku': 'Force10-S6000'," \ + "'type': 'LeafRouter'," \ + "'deployment_id': '2'" \ + "}," \ + "'switch2-t0': {" \ + "'hwsku': 'Force10-S6000'," \ + "'lo_addr': '25.1.1.10'," \ + "'mgmt_addr': '10.7.0.196/26'," \ + "'type': 'ToRRouter'" \ + "}" \ + "}") ) # everflow portion is not used @@ -170,3 +184,22 @@ def test_mux_cable_parsing(self): self.assertTrue(port["mux_cable"]) else: self.assertTrue("mux_cable" not in port) + + def test_minigraph_tunnel_table(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "TUNNEL"' + expected_tunnel = { + "MuxTunnel0": { + "tunnel_type": "IPINIP", + "dst_ip": "10.1.0.32", + "dscp_mode": "uniform", + "encap_ecn_mode": "standard", + "ecn_mode": "copy_from_outer", + "ttl_mode": "pipe" + } + } + + output = self.run_script(argument) + self.assertEqual( + utils.to_dict(output.strip()), + expected_tunnel + ) From 9fda295cd06ee558ee2732b4c81ca447b2da0f4e Mon Sep 17 00:00:00 2001 From: Garrick He <32883830+GarrickHe@users.noreply.github.com> Date: Sat, 7 Nov 2020 20:23:01 -0800 Subject: [PATCH 1349/1427] [sflow] Clean-up sFlow container and port_index_mapper.py script (#5846) * Fix some spelling error and add addition check in port_index_mapper.py script. * Remove unneeded pyroute2 python module from sFlow container Signed-off-by: Garrick He --- dockers/docker-sflow/Dockerfile.j2 | 3 --- dockers/docker-sflow/port_index_mapper.py | 12 +++++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/dockers/docker-sflow/Dockerfile.j2 b/dockers/docker-sflow/Dockerfile.j2 index 94f4d73c968c..e1d7ce72855a 100644 --- a/dockers/docker-sflow/Dockerfile.j2 +++ b/dockers/docker-sflow/Dockerfile.j2 @@ -12,9 +12,6 @@ RUN apt-get update && \ dmidecode \ libmnl0=1.0.4-2 -RUN pip install \ - pyroute2==0.5.3 - {% if docker_sflow_debs.strip() -%} # Copy locally-built Debian package dependencies {{ copy_files("debs/", docker_sflow_debs.split(' '), "/debs/") }} diff --git a/dockers/docker-sflow/port_index_mapper.py b/dockers/docker-sflow/port_index_mapper.py index 3f8a2819a840..c027589e2af0 100755 --- a/dockers/docker-sflow/port_index_mapper.py +++ b/dockers/docker-sflow/port_index_mapper.py @@ -28,12 +28,12 @@ def __init__(self): self.state_db = SonicV2Connector(host='127.0.0.1', decode_responses=True) self.state_db.connect(self.state_db.STATE_DB, False) self.sel = swsscommon.Select() - self.tlbs = [swsscommon.SubscriberStateTable(self.appl_db, t) + self.tbls = [swsscommon.SubscriberStateTable(self.appl_db, t) for t in tbl_lst] self.cur_interfaces = {} - for t in self.tlbs: + for t in self.tbls: self.sel.addSelectable(t) def set_port_index_table_entry(self, key, index, ifindex): @@ -69,11 +69,12 @@ def listen(self): while True: (state, c) = self.sel.select(SELECT_TIMEOUT_MS) if state == swsscommon.Select.OBJECT: - for t in self.tlbs: + for t in self.tbls: (key, op, cfvs) = t.pop() if op == 'DEL' and key in self.cur_interfaces: self.update_db(key, op) elif (op == 'SET' and key != 'PortInitDone' and + key != 'PortConfigDone' and key not in self.cur_interfaces): self.update_db(key, op) elif state == swsscomm.Select.ERROR: @@ -86,9 +87,10 @@ def populate(self): while True: (state, c) = self.sel.select(SELECT_TIMEOUT_MS) if state == swsscommon.Select.OBJECT: - for t in self.tlbs: + for t in self.tbls: (key, op, cfvs) = t.pop() - if key and key != 'PortInitDone': + if (key and key != 'PortInitDone' and + key != 'PortConfigDone'): self.update_db(key, op) else: break From 92704e8a93a0c1893d4bdd7680a31e88b2e6f6b6 Mon Sep 17 00:00:00 2001 From: Longxiang Lyu <35479537+lolyu@users.noreply.github.com> Date: Mon, 9 Nov 2020 05:42:38 +0800 Subject: [PATCH 1350/1427] [bgpmon] Fix `dict_keys` unsubscriptable error (#5859) Simply looping through `dict_key` object instead of index-subscribing to fix this. Signed-off-by: Longxiang Lyu --- src/sonic-bgpcfgd/bgpmon/bgpmon.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-bgpcfgd/bgpmon/bgpmon.py b/src/sonic-bgpcfgd/bgpmon/bgpmon.py index df40d901f3dd..c20c2110a6b2 100755 --- a/src/sonic-bgpcfgd/bgpmon/bgpmon.py +++ b/src/sonic-bgpcfgd/bgpmon/bgpmon.py @@ -68,8 +68,8 @@ def bgp_activity_detected(self): def update_new_peer_states(self, peer_dict): peer_l = peer_dict["peers"].keys() self.new_peer_l.extend(peer_l) - for i in range (0, len(peer_l)): - self.new_peer_state[peer_l[i]] = peer_dict["peers"][peer_l[i]]["state"] + for peer in peer_l: + self.new_peer_state[peer] = peer_dict["peers"][peer]["state"] # Get a new snapshot of BGP neighbors and store them in the "new" location def get_all_neigh_states(self): From fb6af9d6d763dc9b4ac98d79474059865c1db247 Mon Sep 17 00:00:00 2001 From: Blueve <672454911@qq.com> Date: Mon, 9 Nov 2020 08:54:21 +0800 Subject: [PATCH 1351/1427] [broadcom][cel][udev] Update console usb devices permission (#5840) * Add MODE "0666" to all console usb tty Signed-off-by: Jing Kan jika@email.com --- .../haliburton/script/50-ttyUSB-C0.rules | 116 +++++++++--------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/script/50-ttyUSB-C0.rules b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/50-ttyUSB-C0.rules index 8fdd8a8b5031..543057941e96 100644 --- a/platform/broadcom/sonic-platform-modules-cel/haliburton/script/50-ttyUSB-C0.rules +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/50-ttyUSB-C0.rules @@ -13,64 +13,64 @@ ACTION=="remove",KERNELS=="1-1.1",ENV{PRODUCT}=="*424/2517/*",RUN+="/bin/bash -c LABEL="C0 Add" -ACTION=="add",KERNELS=="1-1.1.1:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-1" -ACTION=="add",KERNELS=="1-1.1.1:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-2" -ACTION=="add",KERNELS=="1-1.1.1:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-3" -ACTION=="add",KERNELS=="1-1.1.1:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-4" -ACTION=="add",KERNELS=="1-1.1.2:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-5" -ACTION=="add",KERNELS=="1-1.1.2:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-6" -ACTION=="add",KERNELS=="1-1.1.2:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-7" -ACTION=="add",KERNELS=="1-1.1.2:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-8" - -ACTION=="add",KERNELS=="1-1.1.3:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-9" -ACTION=="add",KERNELS=="1-1.1.3:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-10" -ACTION=="add",KERNELS=="1-1.1.3:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-11" -ACTION=="add",KERNELS=="1-1.1.3:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-12" - -ACTION=="add",KERNELS=="1-1.1.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-13" -ACTION=="add",KERNELS=="1-1.1.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-14" -ACTION=="add",KERNELS=="1-1.1.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-15" -ACTION=="add",KERNELS=="1-1.1.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-16" - -ACTION=="add",KERNELS=="1-1.1.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-17" -ACTION=="add",KERNELS=="1-1.1.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-18" -ACTION=="add",KERNELS=="1-1.1.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-19" -ACTION=="add",KERNELS=="1-1.1.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-20" - -ACTION=="add",KERNELS=="1-1.1.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-21" -ACTION=="add",KERNELS=="1-1.1.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-22" -ACTION=="add",KERNELS=="1-1.1.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-23" -ACTION=="add",KERNELS=="1-1.1.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-24" - -ACTION=="add",KERNELS=="1-1.1.7.1:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-25" -ACTION=="add",KERNELS=="1-1.1.7.1:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-26" -ACTION=="add",KERNELS=="1-1.1.7.1:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-27" -ACTION=="add",KERNELS=="1-1.1.7.1:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-28" - -ACTION=="add",KERNELS=="1-1.1.7.2:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-29" -ACTION=="add",KERNELS=="1-1.1.7.2:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-30" -ACTION=="add",KERNELS=="1-1.1.7.2:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-31" -ACTION=="add",KERNELS=="1-1.1.7.2:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-32" - -ACTION=="add",KERNELS=="1-1.1.7.3:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-33" -ACTION=="add",KERNELS=="1-1.1.7.3:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-34" -ACTION=="add",KERNELS=="1-1.1.7.3:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-35" -ACTION=="add",KERNELS=="1-1.1.7.3:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-36" - -ACTION=="add",KERNELS=="1-1.1.7.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-37" -ACTION=="add",KERNELS=="1-1.1.7.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-38" -ACTION=="add",KERNELS=="1-1.1.7.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-39" -ACTION=="add",KERNELS=="1-1.1.7.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-40" - -ACTION=="add",KERNELS=="1-1.1.7.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-41" -ACTION=="add",KERNELS=="1-1.1.7.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-42" -ACTION=="add",KERNELS=="1-1.1.7.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-43" -ACTION=="add",KERNELS=="1-1.1.7.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-44" - -ACTION=="add",KERNELS=="1-1.1.7.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-45" -ACTION=="add",KERNELS=="1-1.1.7.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-46" -ACTION=="add",KERNELS=="1-1.1.7.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-47" -ACTION=="add",KERNELS=="1-1.1.7.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-48" +ACTION=="add",KERNELS=="1-1.1.1:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-1",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.1:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-2",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.1:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-3",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.1:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-4",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.2:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-5",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.2:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-6",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.2:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-7",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.2:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-8",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.3:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-9",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.3:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-10",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.3:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-11",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.3:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-12",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-13",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-14",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-15",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-16",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-17",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-18",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-19",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-20",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-21",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-22",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-23",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-24",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.1:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-25",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.1:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-26",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.1:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-27",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.1:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-28",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.2:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-29",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.2:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-30",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.2:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-31",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.2:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-32",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.3:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-33",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.3:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-34",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.3:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-35",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.3:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-36",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-37",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-38",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-39",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-40",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-41",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-42",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-43",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-44",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-45",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-46",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-47",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-48",MODE="0666" LABEL="C0 Remove" ACTION=="remove",KERNELS=="1-1.1.1:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 1'" From 3fa724d216801e3a43bcf3f7163ecdf18a99556c Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Mon, 9 Nov 2020 09:57:50 +0200 Subject: [PATCH 1352/1427] [submodule] Update sonic-swss submodule (#5825) 62e6c5a [bitmap_vnet] Remove BMTOR implementation (#1494) 582beae [FPMSYNCD] EVPN Type5 prefix handling in FPMSYNCD (#1326) d9ca6e2 [vstest] Resolve intermittent timing failure in test_fgnhg.py (#1495) a89b8ed [sub intf] Inherit parent port mtu changes (#1479) Signed-off-by: Volodymyr Samotiy --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index d7643f2c3fe6..62e6c5a4d7dc 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit d7643f2c3fe6bdef79755e2594491e02234fd979 +Subproject commit 62e6c5a4d7dc9aeae74d5350e95bd7908203e09b From ad2e18e856a1266890791588f290ac6eb7ac40dc Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 9 Nov 2020 00:14:56 -0800 Subject: [PATCH 1353/1427] [baseimage]: install psutil for python3 psutil is needed by process_checker which is using python3 Signed-off-by: Guohan Lu --- files/build_templates/sonic_debian_extension.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 9e189ae90ac1..7b8299fda1aa 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -115,7 +115,7 @@ sudo rm -rf $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY2_WHEEL_NAME sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install ipaddress # Install Python module for psutil -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install psutil +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install psutil # Install SwSS SDK Python 3 package # Note: the scripts will be overwritten by corresponding Python 2 package From 385dfc4921b47074e24de15abf0413b64cf8bda1 Mon Sep 17 00:00:00 2001 From: Longxiang Lyu <35479537+lolyu@users.noreply.github.com> Date: Mon, 9 Nov 2020 17:52:22 +0800 Subject: [PATCH 1354/1427] [monit] Fix status error due to shebang change (#5865) lldpmgrd, bgpcfgd, and bgpmon are reported error status not running due to recent change of shebang to use `Python3`. Modifying the argument of `process_checker` to follow this change. Signed-off-by: Longxiang Lyu --- dockers/docker-fpm-frr/base_image_files/monit_bgp | 4 ++-- dockers/docker-lldp/base_image_files/monit_lldp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp index 3361b9e64f3c..07705e84179d 100644 --- a/dockers/docker-fpm-frr/base_image_files/monit_bgp +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -20,8 +20,8 @@ check program bgp|bgpd with path "/usr/bin/process_checker bgp /usr/lib/frr/bgpd check program bgp|staticd with path "/usr/bin/process_checker bgp /usr/lib/frr/staticd" if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check program bgp|bgpcfgd with path "/usr/bin/process_checker bgp /usr/bin/python /usr/local/bin/bgpcfgd" +check program bgp|bgpcfgd with path "/usr/bin/process_checker bgp /usr/bin/python3 /usr/local/bin/bgpcfgd" if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check program bgp|bgpmon with path "/usr/bin/process_checker bgp /usr/bin/python /usr/local/bin/bgpmon" +check program bgp|bgpmon with path "/usr/bin/process_checker bgp /usr/bin/python3 /usr/local/bin/bgpmon" if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-lldp/base_image_files/monit_lldp b/dockers/docker-lldp/base_image_files/monit_lldp index 8dc2f3c15321..c522e5f224ab 100644 --- a/dockers/docker-lldp/base_image_files/monit_lldp +++ b/dockers/docker-lldp/base_image_files/monit_lldp @@ -11,5 +11,5 @@ check program lldp|lldpd_monitor with path "/usr/bin/process_checker lldp lldpd: check program lldp|lldp_syncd with path "/usr/bin/process_checker lldp python2 -m lldp_syncd" if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check program lldp|lldpmgrd with path "/usr/bin/process_checker lldp python /usr/bin/lldpmgrd" +check program lldp|lldpmgrd with path "/usr/bin/process_checker lldp python3 /usr/bin/lldpmgrd" if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles From e0fdf45ad09f770c9de14a0da7721e36d72d306d Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 9 Nov 2020 08:35:36 -0800 Subject: [PATCH 1355/1427] [update_chassisdb_config] Convert to Python 3 (#5838) - Convert update_chassisdb_config script to Python 3 - Reorganize imports per PEP8 standard - Two blank lines precede functions per PEP8 standard --- files/scripts/update_chassisdb_config | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/files/scripts/update_chassisdb_config b/files/scripts/update_chassisdb_config index 7ed1f2284cc8..6b9403370421 100755 --- a/files/scripts/update_chassisdb_config +++ b/files/scripts/update_chassisdb_config @@ -1,13 +1,15 @@ -#!/usr/bin/python +#!/usr/bin/python3 + +import argparse import json import os import syslog -import argparse database_config_file = "/var/run/redis/sonic-db/database_config.json" redis_chassis = 'redis_chassis' chassis_db = 'CHASSIS_APP_DB' + def main(): parser = argparse.ArgumentParser(description= "Update chassis_db config from database-config.json") @@ -63,5 +65,6 @@ def main(): syslog.syslog(syslog.LOG_INFO, 'remove chassis_db from config file {}'.format(jsonfile)) + if __name__ == "__main__": main() From c972052594614d2715ef59f03b3c05958f1f8068 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Mon, 9 Nov 2020 11:10:10 -0800 Subject: [PATCH 1356/1427] [multi-ASIC] util changes with the BGP_INTERNAL_NEIGHBOR table. (#5760) - Why I did it Update the routine is_bgp_session_internal() by checking the BGP_INTERNAL_NEIGHBOR table. Additionally to address the review comment #5520 (comment) Add timer settings as will in the internal session templates and keep it minimal as these sessions which will always be up. Updates to the internal tests data + add all of it to template tests. - How I did it Updated the APIs and the template files. - How to verify it Verified the internal BGP sessions are displayed correctly with show commands with this API is_bgp_session_internal() --- .../bgpd/templates/internal/instance.conf.j2 | 1 + .../internal/instance.conf/result_back_v4.conf | 3 +-- .../internal/instance.conf/result_back_v6.conf | 3 +-- .../internal/instance.conf/result_front_v4.conf | 3 +-- .../internal/instance.conf/result_front_v6.conf | 3 +-- src/sonic-bgpcfgd/tests/test_templates.py | 12 ++++++++++++ .../sonic_py_common/multi_asic.py | 17 ++++------------- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 index 49497e4fcaaa..baa51cf35041 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 @@ -3,6 +3,7 @@ ! neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} + neighbor {{ neighbor_addr }} timers 3 10 ! {% if neighbor_addr | ipv4 %} address-family ipv4 diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf index 4664395bbf27..9cf5e3d13c4a 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf @@ -3,8 +3,7 @@ ! neighbor 10.10.10.10 remote-as 555 neighbor 10.10.10.10 description remote_peer - neighbor 10.10.10.10 timers 5 30 - neighbor 10.10.10.10 shutdown + neighbor 10.10.10.10 timers 3 10 address-family ipv4 neighbor 10.10.10.10 peer-group INTERNAL_PEER_V4 neighbor 10.10.10.10 route-map FROM_BGP_INTERNAL_PEER_V4 in diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf index 08cffe632815..41aa2ae7f800 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf @@ -3,8 +3,7 @@ ! neighbor fc::10 remote-as 555 neighbor fc::10 description remote_peer - neighbor fc::10 timers 5 30 - neighbor fc::10 shutdown + neighbor fc::10 timers 3 10 address-family ipv6 neighbor fc::10 peer-group INTERNAL_PEER_V6 neighbor fc::10 route-map FROM_BGP_INTERNAL_PEER_V6 in diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf index aba5cfac0b1f..c327e417f0f6 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf @@ -3,8 +3,7 @@ ! neighbor 10.10.10.10 remote-as 555 neighbor 10.10.10.10 description remote_peer - neighbor 10.10.10.10 timers 5 30 - neighbor 10.10.10.10 shutdown + neighbor 10.10.10.10 timers 3 10 address-family ipv4 neighbor 10.10.10.10 peer-group INTERNAL_PEER_V4 neighbor 10.10.10.10 next-hop-self force diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf index 362900d57403..c73003823375 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf @@ -3,8 +3,7 @@ ! neighbor fc::10 remote-as 555 neighbor fc::10 description remote_peer - neighbor fc::10 timers 5 30 - neighbor fc::10 shutdown + neighbor fc::10 timers 3 10 address-family ipv6 neighbor fc::10 peer-group INTERNAL_PEER_V6 neighbor fc::10 next-hop-self force diff --git a/src/sonic-bgpcfgd/tests/test_templates.py b/src/sonic-bgpcfgd/tests/test_templates.py index f8fa0b9e4028..6c8204a28ec8 100644 --- a/src/sonic-bgpcfgd/tests/test_templates.py +++ b/src/sonic-bgpcfgd/tests/test_templates.py @@ -105,6 +105,18 @@ def test_general_instance(): test_data = load_tests("general", "instance.conf") run_tests("general_instance", *test_data) +def test_internal_policies(): + test_data = load_tests("internal", "policies.conf") + run_tests("internal_policies", *test_data) + +def test_internal_pg(): + test_data = load_tests("internal", "peer-group.conf") + run_tests("internal_pg", *test_data) + +def test_internal_instance(): + test_data = load_tests("internal", "instance.conf") + run_tests("internal_instance", *test_data) + def test_dynamic_policies(): test_data = load_tests("dynamic", "policies.conf") run_tests("dynamic_policies", *test_data) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index a6ab17025eba..f844b12287c5 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -21,6 +21,7 @@ PORT_CHANNEL_CFG_DB_TABLE = 'PORTCHANNEL' PORT_CFG_DB_TABLE = 'PORT' BGP_NEIGH_CFG_DB_TABLE = 'BGP_NEIGHBOR' +BGP_INTERNAL_NEIGH_CFG_DB_TABLE = 'BGP_INTERNAL_NEIGHBOR' NEIGH_DEVICE_METADATA_CFG_DB_TABLE = 'DEVICE_NEIGHBOR_METADATA' DEFAULT_NAMESPACE = '' PORT_ROLE = 'role' @@ -359,20 +360,10 @@ def is_bgp_session_internal(bgp_neigh_ip, namespace=None): for ns in ns_list: config_db = connect_config_db_for_ns(ns) - bgp_sessions = config_db.get_table(BGP_NEIGH_CFG_DB_TABLE) - if bgp_neigh_ip not in bgp_sessions: - continue - - bgp_neigh_name = bgp_sessions[bgp_neigh_ip]['name'] - neighbor_metadata = config_db.get_table( - NEIGH_DEVICE_METADATA_CFG_DB_TABLE) - - if ((neighbor_metadata) and - (neighbor_metadata[bgp_neigh_name]['type'].lower() == - ASIC_NAME_PREFIX)): + bgp_sessions = config_db.get_table(BGP_INTERNAL_NEIGH_CFG_DB_TABLE) + if bgp_neigh_ip in bgp_sessions: return True - else: - return False + return False def get_front_end_namespaces(): From 84aa99d04b4419cb5e85448d02f01a90bace8909 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 9 Nov 2020 12:31:33 -0800 Subject: [PATCH 1357/1427] [multi-asic] teamdctl support for multi-asic (#5851) Signed-off-by: Abhishek Dosi --- .../docker-teamd/base_image_files/teamdctl | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/dockers/docker-teamd/base_image_files/teamdctl b/dockers/docker-teamd/base_image_files/teamdctl index 615bc3d953fa..d4e02ccd707d 100755 --- a/dockers/docker-teamd/base_image_files/teamdctl +++ b/dockers/docker-teamd/base_image_files/teamdctl @@ -1,5 +1,12 @@ #!/bin/bash +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + +function help() +{ + echo -e "Usage: $0 -n [0 to $(($NUM_ASIC-1))] [OPTION]... " 1>&2; exit 1; +} + DOCKER_EXEC_FLAGS="i" # Determine whether stdout is on a terminal @@ -7,4 +14,30 @@ if [ -t 1 ] ; then DOCKER_EXEC_FLAGS+="t" fi -docker exec -$DOCKER_EXEC_FLAGS teamd teamdctl "$@" +DEV="" +PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +[ -f $ASIC_CONF ] && . $ASIC_CONF + +if [[ ($NUM_ASIC -gt 1) ]]; then + while getopts ":n:h:" opt; do + case "${opt}" in + h) help + ;; + n) DEV=${OPTARG} + [ $DEV -lt $NUM_ASIC -a $DEV -ge 0 ] || help + ;; + esac + done + + if [ -z "${DEV}" ]; then + help + fi + + # Skip the arguments -n while passing to docker command + shift 2 +fi + +docker exec -$DOCKER_EXEC_FLAGS teamd$DEV teamdctl "$@" From 4f82463670472ae8a2be558561e49367127bd3b4 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 9 Nov 2020 13:03:00 -0800 Subject: [PATCH 1358/1427] [multi-asic] Fixed the docker mount point check for multi-asic (#5848) API getMount() API was not updated to handle multi-asic platforms Updated API getMount() to return abspath() for Docker Mount Point and use that one for mount point comparison Signed-off-by: Abhishek Dosi --- files/build_templates/docker_image_ctl.j2 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 62846354fd08..3766dc918bab 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -45,7 +45,7 @@ function updateSyslogConf() function getMountPoint() { - echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.basename(mnts[0]['Source'])" 2>/dev/null + echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.abspath(mnts[0]['Source'])" 2>/dev/null } function getBootType() @@ -189,9 +189,14 @@ start() { {%- if docker_container_name == "database" %} # Don't mount HWSKU in {{docker_container_name}} container. HWSKU="" + MOUNTPATH="" {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker HWSKU=${HWSKU:-`$SONIC_CFGGEN -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'`} + MOUNTPATH="/usr/share/sonic/device/$PLATFORM/$HWSKU" + if [ "$DEV" ]; then + MOUNTPATH="$MOUNTPATH/$DEV" + fi {%- endif %} DOCKERCHECK=`docker inspect --type container ${DOCKERNAME} 2>/dev/null` if [ "$?" -eq "0" ]; then @@ -200,7 +205,7 @@ start() { {%- else %} DOCKERMOUNT=`getMountPoint "$DOCKERCHECK"` {%- endif %} - if [ x"$DOCKERMOUNT" == x"$HWSKU" ]; then + if [ x"$DOCKERMOUNT" == x"$MOUNTPATH" ]; then {%- if docker_container_name == "database" %} echo "Starting existing ${DOCKERNAME} container" {%- else %} From 6a8ebef4499627f919d85b171205e1dd44fe2cbd Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Mon, 9 Nov 2020 13:27:36 -0800 Subject: [PATCH 1359/1427] [Arista 7050cx3] add dummy MMU configurations for Arista-7050CX3-32S-C32 (#5798) - Why I did it On Arista-7050CX3-32S-C32, there are constant stream of errors like following. Nov 3 21:56:24.415190 str2-7050cx3-acs-06 NOTICE swss#orchagent: :- registerInWdDb: No lossless TC found on port Ethernet68 Which causes: loganalyzer to claim test failed. leaving the system without MMU configuration. Which couldn't be good for any IO test. - How I did it Added these MMU configuraions are copied from another platform and guaranteed to be incorrect for hwsku Arista-7050CX3-32S-C32. Adding them so that we have A MMU configuration and the system won't throw a whole bunch of errors and leave MMU unconfigured. The correct MMU configuration will come later. This configuration is definitely not suitable for testing system performance or QoS behavior. Signed-off-by: Ying Xie ying.xie@microsoft.com - How to verify it Test will have chance to pass. Ran a few test that would fail otherwise. --- .../Arista-7050CX3-32S-C32/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 54 +++++++++++++++++++ .../buffers_defaults_t1.j2 | 54 +++++++++++++++++++ .../Arista-7050CX3-32S-C32/qos.json.j2 | 21 ++++++++ 4 files changed, 131 insertions(+) create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers.json.j2 create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t0.j2 create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t1.j2 create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/qos.json.j2 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers.json.j2 b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers.json.j2 new file mode 100644 index 000000000000..1083a6210fc9 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..cc7a687514ce --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t0.j2 @@ -0,0 +1,54 @@ + +{%- set default_cable = '300m' %} + +{%- set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +-%} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10875072", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "9243812", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"15982720" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..cc7a687514ce --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t1.j2 @@ -0,0 +1,54 @@ + +{%- set default_cable = '300m' %} + +{%- set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +-%} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10875072", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "9243812", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"15982720" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/qos.json.j2 b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/qos.json.j2 new file mode 100644 index 000000000000..34002048afdb --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/qos.json.j2 @@ -0,0 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + +{%- include 'qos_config.j2' %} From a9fc866ba5f560057c8f2d985598f5546a1bb00c Mon Sep 17 00:00:00 2001 From: ajbalogh <30300566+ajbalogh@users.noreply.github.com> Date: Mon, 9 Nov 2020 14:12:39 -0800 Subject: [PATCH 1360/1427] =?UTF-8?q?dockers/docker-sonic-mgmt/Dockerfile.?= =?UTF-8?q?js:=20Add=20keysight=20ixnetwork-open-=E2=80=A6=20(#5762)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *Why I did it Provide access to the ixnetwork-open-traffic-generator pypi package *How I did it Added a pip install entry for the package in the Dockerfile.j2 *How to verify it pip show ixnetwork-open-traffic-generator *Description for the changelog Install of ixnetwork-open-traffic-generator pypi package is required for proposed rdma tests. --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 736d83d2b4e2..c0ef6e0c9841 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -40,6 +40,7 @@ RUN pip install cffi==1.10.0 \ ipaddr \ ipython==5.4.1 \ ixnetwork-restpy==1.0.52 \ + ixnetwork-open-traffic-generator==0.0.42 \ jinja2==2.7.2 \ jsonpatch \ lxml \ From b5121dcfd4187ced7887950e2df1fb9a1f6eb1fa Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Mon, 9 Nov 2020 14:30:13 -0800 Subject: [PATCH 1361/1427] Revert "[multi-ASIC] util changes with the BGP_INTERNAL_NEIGHBOR table. (#5760)" (#5871) This reverts commit c972052594614d2715ef59f03b3c05958f1f8068. --- .../bgpd/templates/internal/instance.conf.j2 | 1 - .../internal/instance.conf/result_back_v4.conf | 3 ++- .../internal/instance.conf/result_back_v6.conf | 3 ++- .../internal/instance.conf/result_front_v4.conf | 3 ++- .../internal/instance.conf/result_front_v6.conf | 3 ++- src/sonic-bgpcfgd/tests/test_templates.py | 12 ------------ .../sonic_py_common/multi_asic.py | 17 +++++++++++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 index baa51cf35041..49497e4fcaaa 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 @@ -3,7 +3,6 @@ ! neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} - neighbor {{ neighbor_addr }} timers 3 10 ! {% if neighbor_addr | ipv4 %} address-family ipv4 diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf index 9cf5e3d13c4a..4664395bbf27 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf @@ -3,7 +3,8 @@ ! neighbor 10.10.10.10 remote-as 555 neighbor 10.10.10.10 description remote_peer - neighbor 10.10.10.10 timers 3 10 + neighbor 10.10.10.10 timers 5 30 + neighbor 10.10.10.10 shutdown address-family ipv4 neighbor 10.10.10.10 peer-group INTERNAL_PEER_V4 neighbor 10.10.10.10 route-map FROM_BGP_INTERNAL_PEER_V4 in diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf index 41aa2ae7f800..08cffe632815 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf @@ -3,7 +3,8 @@ ! neighbor fc::10 remote-as 555 neighbor fc::10 description remote_peer - neighbor fc::10 timers 3 10 + neighbor fc::10 timers 5 30 + neighbor fc::10 shutdown address-family ipv6 neighbor fc::10 peer-group INTERNAL_PEER_V6 neighbor fc::10 route-map FROM_BGP_INTERNAL_PEER_V6 in diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf index c327e417f0f6..aba5cfac0b1f 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf @@ -3,7 +3,8 @@ ! neighbor 10.10.10.10 remote-as 555 neighbor 10.10.10.10 description remote_peer - neighbor 10.10.10.10 timers 3 10 + neighbor 10.10.10.10 timers 5 30 + neighbor 10.10.10.10 shutdown address-family ipv4 neighbor 10.10.10.10 peer-group INTERNAL_PEER_V4 neighbor 10.10.10.10 next-hop-self force diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf index c73003823375..362900d57403 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf @@ -3,7 +3,8 @@ ! neighbor fc::10 remote-as 555 neighbor fc::10 description remote_peer - neighbor fc::10 timers 3 10 + neighbor fc::10 timers 5 30 + neighbor fc::10 shutdown address-family ipv6 neighbor fc::10 peer-group INTERNAL_PEER_V6 neighbor fc::10 next-hop-self force diff --git a/src/sonic-bgpcfgd/tests/test_templates.py b/src/sonic-bgpcfgd/tests/test_templates.py index 6c8204a28ec8..f8fa0b9e4028 100644 --- a/src/sonic-bgpcfgd/tests/test_templates.py +++ b/src/sonic-bgpcfgd/tests/test_templates.py @@ -105,18 +105,6 @@ def test_general_instance(): test_data = load_tests("general", "instance.conf") run_tests("general_instance", *test_data) -def test_internal_policies(): - test_data = load_tests("internal", "policies.conf") - run_tests("internal_policies", *test_data) - -def test_internal_pg(): - test_data = load_tests("internal", "peer-group.conf") - run_tests("internal_pg", *test_data) - -def test_internal_instance(): - test_data = load_tests("internal", "instance.conf") - run_tests("internal_instance", *test_data) - def test_dynamic_policies(): test_data = load_tests("dynamic", "policies.conf") run_tests("dynamic_policies", *test_data) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index f844b12287c5..a6ab17025eba 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -21,7 +21,6 @@ PORT_CHANNEL_CFG_DB_TABLE = 'PORTCHANNEL' PORT_CFG_DB_TABLE = 'PORT' BGP_NEIGH_CFG_DB_TABLE = 'BGP_NEIGHBOR' -BGP_INTERNAL_NEIGH_CFG_DB_TABLE = 'BGP_INTERNAL_NEIGHBOR' NEIGH_DEVICE_METADATA_CFG_DB_TABLE = 'DEVICE_NEIGHBOR_METADATA' DEFAULT_NAMESPACE = '' PORT_ROLE = 'role' @@ -360,10 +359,20 @@ def is_bgp_session_internal(bgp_neigh_ip, namespace=None): for ns in ns_list: config_db = connect_config_db_for_ns(ns) - bgp_sessions = config_db.get_table(BGP_INTERNAL_NEIGH_CFG_DB_TABLE) - if bgp_neigh_ip in bgp_sessions: - return True + bgp_sessions = config_db.get_table(BGP_NEIGH_CFG_DB_TABLE) + if bgp_neigh_ip not in bgp_sessions: + continue + + bgp_neigh_name = bgp_sessions[bgp_neigh_ip]['name'] + neighbor_metadata = config_db.get_table( + NEIGH_DEVICE_METADATA_CFG_DB_TABLE) + if ((neighbor_metadata) and + (neighbor_metadata[bgp_neigh_name]['type'].lower() == + ASIC_NAME_PREFIX)): + return True + else: + return False return False def get_front_end_namespaces(): From fafb22b5c080fdfa98f79a721ef2870d496a754d Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 9 Nov 2020 18:13:08 -0800 Subject: [PATCH 1362/1427] [sonic-slave-buster] Install Python 3 dependencies in container (#5863) Install Python 3 dependencies in sonic-slave-buster container --- sonic-slave-buster/Dockerfile.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 66bc0564efcf..18f7405bc700 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -57,6 +57,7 @@ RUN apt-get update && apt-get install -y \ libtinyxml2-dev \ python \ python-pip \ + python3 \ python3-pip \ libncurses5-dev \ texinfo \ @@ -386,9 +387,11 @@ RUN apt-get install python-meld3 # For vs image build RUN pip2 install pexpect==4.6.0 +RUN pip3 install pexpect==4.8.0 # For sonic-swss-common testing RUN pip2 install Pympler==0.8 +RUN pip3 install Pympler==0.8 # For sonic_yang_model build RUN pip2 install pyang==2.1.1 From e95483471e6135979503c45808376e6d5907ade9 Mon Sep 17 00:00:00 2001 From: vdahiya12 <67608553+vdahiya12@users.noreply.github.com> Date: Tue, 10 Nov 2020 00:06:48 -0800 Subject: [PATCH 1363/1427] [submodule]: update sonic-platform-daemons (#5868) 850d0c6 [xcvrd] support for integrating Credo Y cable Ports initialization and status updates with xcvrd. (#105) 600d043 [xcvrd] Add enum dependence back; Install 'enum34' conditionally based on Python version (#107) af79326 [xcvrd] Remove log errors in single ASIC platforms with init Global config (#108) Signed-off-by: vaibhav-dahiya --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 95b1696401da..850d0c6f94ff 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 95b1696401da904e1a1386e2359fa72e4aa03f94 +Subproject commit 850d0c6f94ffb644b58a51447599e85178626626 From 4669c3241b519e20c43876006a727b0f11febfc9 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 10 Nov 2020 00:07:37 -0800 Subject: [PATCH 1364/1427] Remove shebangs from various setup.py files (#5867) setup.py files are not executable, and thus have no need for shebangs. Also remove unnecessary comments --- src/sonic-bgpcfgd/setup.py | 2 -- src/sonic-yang-mgmt/setup.py | 5 ----- src/sonic-yang-models/setup.py | 5 ----- 3 files changed, 12 deletions(-) diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index 5b18bb2ba256..69110bbe7915 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - import setuptools setuptools.setup( diff --git a/src/sonic-yang-mgmt/setup.py b/src/sonic-yang-mgmt/setup.py index cb62c5ac4ee3..e1b037cdcdfa 100644 --- a/src/sonic-yang-mgmt/setup.py +++ b/src/sonic-yang-mgmt/setup.py @@ -1,8 +1,3 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -"""The setup script.""" - from setuptools import setup, find_packages # read me diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 9e750ca87480..4ba9fd61c92a 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -1,8 +1,3 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -"""The setup script.""" - from setuptools import setup, find_packages # read me From e6ec5d0774435452c9c0fbca9283efaf98849602 Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Tue, 10 Nov 2020 18:33:24 +0200 Subject: [PATCH 1365/1427] Fix MSN4700 sensors labels (#5861) Signed-off-by: Shlomi Bitton --- .../x86_64-mlnx_msn4700-r0/sensors.conf | 134 +++++++++--------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf index 39fa9a5f93d3..3b19dc80c6ce 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf @@ -24,108 +24,108 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "xdpe12284-i2c-*-62" label in1 "PMIC-1 PSU 12V Rail (in1)" label in2 "PMIC-1 PSU 12V Rail (in2)" - label in3 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail (out)" - label in4 "PMIC-1 ASIC 1.8V T6_7 Rail (out)" + label in3 "PMIC-1 ASIC 0.8V VCORE MAIN Rail (out)" + ignore in4 label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" - label power1 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" - label power2 "PMIC-1 ASIC 1.8V T6_7 Rail Pwr (in)" - label power3 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power4 "PMIC-1 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" - label curr2 "PMIC-1 ASIC 1.8V T6_7 Rail Curr (in)" - label curr3 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr4 "PMIC-1 ASIC 1.8V T6_7 Rail Curr (out)" + label power1 "PMIC-1 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-1 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-1 ASIC 0.8V VCORE MAIN Rail Pwr (out)" + ignore power4 + label curr1 "PMIC-1 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-1 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-1 ASIC 0.8V VCORE MAIN Rail Curr (out)" + ignore curr4 chip "xdpe12284-i2c-*-64" label in1 "PMIC-2 PSU 12V Rail (in1)" label in2 "PMIC-2 PSU 12V Rail (in2)" - label in3 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail (out)" - label in4 "PMIC-2 ASIC 1.8V T6_7 Rail (out)" + label in3 "PMIC-2 ASIC 1.8V VCORE MAIN Rail (out)" + label in4 "PMIC-2 ASIC 1.2V VCORE MAIN Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" - label power1 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" - label power2 "PMIC-2 ASIC 1.8V T6_7 Rail Pwr (in)" - label power3 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power4 "PMIC-2 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" - label curr2 "PMIC-2 ASIC 1.8V T6_7 Rail Curr (in)" - label curr3 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr4 "PMIC-2 ASIC 1.8V T6_7 Rail Curr (out)" + label power1 "PMIC-2 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-2 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-2 ASIC 1.8V VCORE MAIN Rail Pwr (out)" + label power4 "PMIC-2 ASIC 1.2V VCORE MAIN Rail Pwr (out)" + label curr1 "PMIC-2 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-2 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-2 ASIC 1.8V VCORE MAIN Rail Curr (out)" + label curr4 "PMIC-2 ASIC 1.2V VCORE MAIN Rail Curr (out)" chip "xdpe12284-i2c-*-66" label in1 "PMIC-3 PSU 12V Rail (in1)" label in2 "PMIC-3 PSU 12V Rail (in2)" - label in3 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail (out)" - label in4 "PMIC-3 ASIC 1.8V T6_7 Rail (out)" + label in3 "PMIC-3 ASIC 0.85V T0_1 Rail (out)" + label in4 "PMIC-3 ASIC 1.8V T0_1 Rail (out)" label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" - label power1 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" - label power2 "PMIC-3 ASIC 1.8V T6_7 Rail Pwr (in)" - label power3 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power4 "PMIC-3 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" - label curr2 "PMIC-3 ASIC 1.8V T6_7 Rail Curr (in)" - label curr3 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr4 "PMIC-3 ASIC 1.8V T6_7 Rail Curr (out)" + label power1 "PMIC-3 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-3 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-3 ASIC 0.85V T0_1 Rail Pwr (out)" + label power4 "PMIC-3 ASIC 1.8V T0_1 Rail Pwr (out)" + label curr1 "PMIC-3 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-3 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-3 ASIC 0.85V T0_1 Rail Curr (out)" + label curr4 "PMIC-3 ASIC 1.8V T0_1 Rail Curr (out)" chip "xdpe12284-i2c-*-68" label in1 "PMIC-4 PSU 12V Rail (in1)" label in2 "PMIC-4 PSU 12V Rail (in2)" - label in3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail (out)" - label in4 "PMIC-4 ASIC 1.8V T6_7 Rail (out)" + label in3 "PMIC-4 ASIC 0.85V T2_3 Rail (out)" + label in4 "PMIC-4 ASIC 1.8V T2_3 Rail (out)" label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" - label power1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" - label power2 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (in)" - label power3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power4 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" - label curr2 "PMIC-4 ASIC 1.8V T6_7 Rail Curr (in)" - label curr3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr4 "PMIC-4 ASIC 1.8V T6_7 Rail Curr (out)" + label power1 "PMIC-4 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-4 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-4 ASIC 0.85V T2_3 Rail Pwr (out)" + label power4 "PMIC-4 ASIC 1.8V T2_3 Rail Pwr (out)" + label curr1 "PMIC-4 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-4 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-4 ASIC 0.85V T2_3 Rail Curr (out)" + label curr4 "PMIC-4 ASIC 1.8V T2_3 Rail Curr (out)" chip "xdpe12284-i2c-*-6a" label in1 "PMIC-5 PSU 12V Rail (in1)" label in2 "PMIC-5 PSU 12V Rail (in2)" - label in3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail (out)" - label in4 "PMIC-5 ASIC 1.8V T6_7 Rail (out)" + label in3 "PMIC-5 ASIC 0.85V T4_5 Rail (out)" + label in4 "PMIC-5 ASIC 1.8V T4_5 Rail (out)" label temp1 "PMIC-5 Temp 1" label temp2 "PMIC-5 Temp 2" - label power1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" - label power2 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (in)" - label power3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power4 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" - label curr2 "PMIC-5 ASIC 1.8V T6_7 Rail Curr (in)" - label curr3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr4 "PMIC-5 ASIC 1.8V T6_7 Rail Curr (out)" + label power1 "PMIC-5 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-5 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-5 ASIC 0.85V T4_5 Rail Pwr (out)" + label power4 "PMIC-5 ASIC 1.8V T4_5 Rail Pwr (out)" + label curr1 "PMIC-5 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-5 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-5 ASIC 0.85V T4_5 Rail Curr (out)" + label curr4 "PMIC-5 ASIC 1.8V T4_5 Rail Curr (out)" chip "xdpe12284-i2c-*-6c" label in1 "PMIC-6 PSU 12V Rail (in1)" label in2 "PMIC-6 PSU 12V Rail (in2)" - label in3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in3 "PMIC-6 ASIC 0.85V T6_7 Rail (out)" label in4 "PMIC-6 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-6 Temp 1" label temp2 "PMIC-6 Temp 2" - label power1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" - label power2 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (in)" - label power3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power1 "PMIC-6 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-6 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-6 ASIC 0.85V T6_7 Rail Pwr (out)" label power4 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" - label curr2 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (in)" - label curr3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr1 "PMIC-6 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-6 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-6 ASIC 0.85V T6_7 Rail Curr (out)" label curr4 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (out)" chip "xdpe12284-i2c-*-6e" label in1 "PMIC-7 PSU 12V Rail (in1)" label in2 "PMIC-7 PSU 12V Rail (in2)" - label in3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail (out)" - label in4 "PMIC-7 ASIC 1.8V T6_7 Rail (out)" + label in3 "PMIC-7 ASIC 1.2V T0_3 Rail_1 (out)" + label in4 "PMIC-7 ASIC 1.2V T4_7 Rail_2 (out)" label temp1 "PMIC-7 Temp 1" label temp2 "PMIC-7 Temp 2" - label power1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" - label power2 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (in)" - label power3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power4 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" - label curr2 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (in)" - label curr3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr4 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (out)" + label power1 "PMIC-7 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-7 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-7 ASIC 1.2V T0_3 Rail_1 Pwr (out)" + label power4 "PMIC-7 ASIC 1.2V T4_7 Rail_2 Pwr (out)" + label curr1 "PMIC-7 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-7 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-7 ASIC 1.2V T0_3 Rail_1 Curr (out)" + label curr4 "PMIC-7 ASIC 1.2V T4_7 Rail_2 Curr (out)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" From f2b22b5cd1c816ef7f2827eab948025267cdf199 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Tue, 10 Nov 2020 09:34:56 -0800 Subject: [PATCH 1366/1427] [multi-ASIC] util changes with the BGP_INTERNAL_NEIGHBOR table (#5874) Reintroduce #5760, along with the fix needed in the template file for python3 compatibility. --- .../bgpd/templates/internal/instance.conf.j2 | 3 ++- .../internal/instance.conf/result_back_v4.conf | 3 +-- .../internal/instance.conf/result_back_v6.conf | 3 +-- .../internal/instance.conf/result_front_v4.conf | 3 +-- .../internal/instance.conf/result_front_v6.conf | 3 +-- src/sonic-bgpcfgd/tests/test_templates.py | 12 ++++++++++++ .../sonic_py_common/multi_asic.py | 17 ++++------------- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 index 49497e4fcaaa..e0e23b7f60c8 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 @@ -3,6 +3,7 @@ ! neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} + neighbor {{ neighbor_addr }} timers 3 10 ! {% if neighbor_addr | ipv4 %} address-family ipv4 @@ -21,7 +22,7 @@ {% endif %} {% endif %} ! -{% if bgp_session.has_key('rrclient') and bgp_session['rrclient'] | int != 0 %} +{% if 'rrclient' in bgp_session and bgp_session['rrclient'] | int != 0 %} neighbor {{ neighbor_addr }} route-reflector-client {% endif %} ! diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf index 4664395bbf27..9cf5e3d13c4a 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf @@ -3,8 +3,7 @@ ! neighbor 10.10.10.10 remote-as 555 neighbor 10.10.10.10 description remote_peer - neighbor 10.10.10.10 timers 5 30 - neighbor 10.10.10.10 shutdown + neighbor 10.10.10.10 timers 3 10 address-family ipv4 neighbor 10.10.10.10 peer-group INTERNAL_PEER_V4 neighbor 10.10.10.10 route-map FROM_BGP_INTERNAL_PEER_V4 in diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf index 08cffe632815..41aa2ae7f800 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf @@ -3,8 +3,7 @@ ! neighbor fc::10 remote-as 555 neighbor fc::10 description remote_peer - neighbor fc::10 timers 5 30 - neighbor fc::10 shutdown + neighbor fc::10 timers 3 10 address-family ipv6 neighbor fc::10 peer-group INTERNAL_PEER_V6 neighbor fc::10 route-map FROM_BGP_INTERNAL_PEER_V6 in diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf index aba5cfac0b1f..c327e417f0f6 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf @@ -3,8 +3,7 @@ ! neighbor 10.10.10.10 remote-as 555 neighbor 10.10.10.10 description remote_peer - neighbor 10.10.10.10 timers 5 30 - neighbor 10.10.10.10 shutdown + neighbor 10.10.10.10 timers 3 10 address-family ipv4 neighbor 10.10.10.10 peer-group INTERNAL_PEER_V4 neighbor 10.10.10.10 next-hop-self force diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf index 362900d57403..c73003823375 100644 --- a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf @@ -3,8 +3,7 @@ ! neighbor fc::10 remote-as 555 neighbor fc::10 description remote_peer - neighbor fc::10 timers 5 30 - neighbor fc::10 shutdown + neighbor fc::10 timers 3 10 address-family ipv6 neighbor fc::10 peer-group INTERNAL_PEER_V6 neighbor fc::10 next-hop-self force diff --git a/src/sonic-bgpcfgd/tests/test_templates.py b/src/sonic-bgpcfgd/tests/test_templates.py index f8fa0b9e4028..6c8204a28ec8 100644 --- a/src/sonic-bgpcfgd/tests/test_templates.py +++ b/src/sonic-bgpcfgd/tests/test_templates.py @@ -105,6 +105,18 @@ def test_general_instance(): test_data = load_tests("general", "instance.conf") run_tests("general_instance", *test_data) +def test_internal_policies(): + test_data = load_tests("internal", "policies.conf") + run_tests("internal_policies", *test_data) + +def test_internal_pg(): + test_data = load_tests("internal", "peer-group.conf") + run_tests("internal_pg", *test_data) + +def test_internal_instance(): + test_data = load_tests("internal", "instance.conf") + run_tests("internal_instance", *test_data) + def test_dynamic_policies(): test_data = load_tests("dynamic", "policies.conf") run_tests("dynamic_policies", *test_data) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index a6ab17025eba..f844b12287c5 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -21,6 +21,7 @@ PORT_CHANNEL_CFG_DB_TABLE = 'PORTCHANNEL' PORT_CFG_DB_TABLE = 'PORT' BGP_NEIGH_CFG_DB_TABLE = 'BGP_NEIGHBOR' +BGP_INTERNAL_NEIGH_CFG_DB_TABLE = 'BGP_INTERNAL_NEIGHBOR' NEIGH_DEVICE_METADATA_CFG_DB_TABLE = 'DEVICE_NEIGHBOR_METADATA' DEFAULT_NAMESPACE = '' PORT_ROLE = 'role' @@ -359,20 +360,10 @@ def is_bgp_session_internal(bgp_neigh_ip, namespace=None): for ns in ns_list: config_db = connect_config_db_for_ns(ns) - bgp_sessions = config_db.get_table(BGP_NEIGH_CFG_DB_TABLE) - if bgp_neigh_ip not in bgp_sessions: - continue - - bgp_neigh_name = bgp_sessions[bgp_neigh_ip]['name'] - neighbor_metadata = config_db.get_table( - NEIGH_DEVICE_METADATA_CFG_DB_TABLE) - - if ((neighbor_metadata) and - (neighbor_metadata[bgp_neigh_name]['type'].lower() == - ASIC_NAME_PREFIX)): + bgp_sessions = config_db.get_table(BGP_INTERNAL_NEIGH_CFG_DB_TABLE) + if bgp_neigh_ip in bgp_sessions: return True - else: - return False + return False def get_front_end_namespaces(): From b177ed9efdd59240b08dd4507874366f75240f42 Mon Sep 17 00:00:00 2001 From: madhanmellanox <62459540+madhanmellanox@users.noreply.github.com> Date: Tue, 10 Nov 2020 10:16:32 -0800 Subject: [PATCH 1367/1427] Accomadating lower case ACL rules for Control Plane ACLs (#5748) To make Control plane ACLs handle case insensitive ACL rules. Currently, it handles only upper case ACL rules. Co-authored-by: Madhan Babu --- src/sonic-host-services/scripts/caclmgrd | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sonic-host-services/scripts/caclmgrd b/src/sonic-host-services/scripts/caclmgrd index ec33f62db0af..e029066a6e47 100755 --- a/src/sonic-host-services/scripts/caclmgrd +++ b/src/sonic-host-services/scripts/caclmgrd @@ -400,6 +400,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): acl_rules = {} for ((rule_table_name, rule_id), rule_props) in self._rules_db_info.items(): + rule_props = {k.upper(): v for k,v in rule_props.items()} if rule_table_name == table_name: if not rule_props: self.log_warning("rule_props for rule_id {} empty or null!".format(rule_id)) From aee389e4023886a4b62952c1d5c6a7f86fc8b00e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 10 Nov 2020 10:26:16 -0800 Subject: [PATCH 1368/1427] [sonic-config-engine] openconfig_acl.py: Make compliant with Python 3 (#5873) Python 3 is more strict with `__slots__`. As per the [documentation](https://docs.python.org/3/reference/datamodel.html#notes-on-using-slots): > \_\_slots\_\_ are implemented at the class level by creating descriptors (Implementing Descriptors) for each variable name. As a result, class attributes cannot be used to set default values for instance variables defined by \_\_slots\_\_; otherwise, the class attribute would overwrite the descriptor assignment. This was apparently missed when making sonic-config-engine compliant with Python 3, and errors like the following would be seen: ``` tests/acl_loader_test.py:10: in from acl_loader.main import * acl_loader/main.py:8: in import openconfig_acl /usr/local/lib/python3.7/dist-packages/openconfig_acl.py:24: in class yc_state_openconfig_acl__acl_state(PybindBase): E ValueError: '_pybind_generated_by' in __slots__ conflicts with class variable ``` --- src/sonic-config-engine/openconfig_acl.py | 384 ++++++---------------- 1 file changed, 96 insertions(+), 288 deletions(-) diff --git a/src/sonic-config-engine/openconfig_acl.py b/src/sonic-config-engine/openconfig_acl.py index d36b98301383..c49f79c70175 100644 --- a/src/sonic-config-engine/openconfig_acl.py +++ b/src/sonic-config-engine/openconfig_acl.py @@ -32,14 +32,10 @@ class yc_state_openconfig_acl__acl_state(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__counter_capability',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__counter_capability = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-acl:AGGREGATE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:INTERFACE_AGGREGATE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'AGGREGATE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'INTERFACE_AGGREGATE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'INTERFACE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:INTERFACE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="counter-capability", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) @@ -125,14 +121,10 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_config(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__name','__description',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__name = YANGDynClass(base=str, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) self.__description = YANGDynClass(base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) @@ -255,14 +247,10 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_state(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__name','__description',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__name = YANGDynClass(base=str, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) self.__description = YANGDynClass(base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) @@ -385,14 +373,10 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_confi """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__description',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__sequence_id = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=True) self.__description = YANGDynClass(base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) @@ -525,14 +509,10 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_state( """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__description','__matched_packets','__matched_octets',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) self.__sequence_id = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=False) @@ -795,14 +775,10 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2_co """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__source_mac','__source_mac_mask','__destination_mac','__destination_mac_mask','__ethertype',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__source_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) self.__destination_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) @@ -1042,14 +1018,10 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2_sta """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__source_mac','__source_mac_mask','__destination_mac','__destination_mac_mask','__ethertype',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__source_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) self.__destination_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) @@ -1289,14 +1261,10 @@ class yc_l2_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2(Pybind """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'l2' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'l2' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -1419,14 +1387,10 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip_co """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__ip_version','__source_ip_address','__source_ip_flow_label','__destination_ip_address','__destination_ip_flow_label','__dscp','__protocol','__hop_limit',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__hop_limit = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=True) self.__protocol = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..254']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=True) @@ -1785,14 +1749,10 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip_sta """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__ip_version','__source_ip_address','__source_ip_flow_label','__destination_ip_address','__destination_ip_flow_label','__dscp','__protocol','__hop_limit',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__hop_limit = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=False) self.__protocol = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..254']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=False) @@ -2151,14 +2111,10 @@ class yc_ip_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip(Pybind """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'ip' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'ip' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -2281,14 +2237,10 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_trans """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__source_port','__destination_port','__tcp_flags',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__source_port = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) self.__tcp_flags = YANGDynClass(base=TypedListType(allowed_type=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) @@ -2450,14 +2402,10 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_transp """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__source_port','__destination_port','__tcp_flags',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__source_port = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) self.__tcp_flags = YANGDynClass(base=TypedListType(allowed_type=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) @@ -2619,14 +2567,10 @@ class yc_transport_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_tr """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'transport' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'transport' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_transport_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_transport_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -2749,14 +2693,10 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface','__subinterface',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) @@ -2889,14 +2829,10 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_ """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface','__subinterface',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) @@ -3029,14 +2965,10 @@ class yc_interface_ref_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entr """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'interface-ref' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'interface-ref' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_interface_interface_ref_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_interface_interface_ref_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -3159,14 +3091,10 @@ class yc_input_interface_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_en """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface_ref',) - _yang_name = 'input-interface' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'input-interface' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__interface_ref = YANGDynClass(base=yc_interface_ref_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_interface_interface_ref, is_container='container', yang_name="interface-ref", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -3250,14 +3178,10 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_actio """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__forwarding_action','__log_action',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__forwarding_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) self.__log_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), default=str("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) @@ -3386,14 +3310,10 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_action """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__forwarding_action','__log_action',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__forwarding_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) self.__log_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), default=str("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) @@ -3523,14 +3443,10 @@ class yc_actions_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_acti """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'actions' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'actions' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_actions_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_actions_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -3653,14 +3569,10 @@ class yc_acl_entry_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry(Py """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__config','__state','__l2','__ip','__transport','__input_interface','__actions',) - _yang_name = 'acl-entry' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entry' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__ip = YANGDynClass(base=yc_ip_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip, is_container='container', yang_name="ip", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__input_interface = YANGDynClass(base=yc_input_interface_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_interface, is_container='container', yang_name="input-interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -4024,14 +3936,10 @@ class yc_acl_entries_openconfig_acl__acl_acl_sets_acl_set_acl_entries(PybindBase """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__acl_entry',) - _yang_name = 'acl-entries' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entries' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__acl_entry = YANGDynClass(base=YANGListType("sequence_id",yc_acl_entry_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry, yang_name="acl-entry", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='sequence-id', extensions=None), is_container='list', yang_name="acl-entry", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) @@ -4116,14 +4024,10 @@ class yc_acl_set_openconfig_acl__acl_acl_sets_acl_set(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__name','__config','__state','__acl_entries',) - _yang_name = 'acl-set' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-set' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -4329,14 +4233,10 @@ class yc_acl_sets_openconfig_acl__acl_acl_sets(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__acl_set',) - _yang_name = 'acl-sets' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-sets' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__acl_set = YANGDynClass(base=YANGListType("name",yc_acl_set_openconfig_acl__acl_acl_sets_acl_set, yang_name="acl-set", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='name', extensions=None), is_container='list', yang_name="acl-set", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) @@ -4422,14 +4322,10 @@ class yc_config_openconfig_acl__acl_interfaces_interface_config(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__id',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__id = YANGDynClass(base=str, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=True) @@ -4515,14 +4411,10 @@ class yc_state_openconfig_acl__acl_interfaces_interface_state(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__id',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__id = YANGDynClass(base=str, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=False) @@ -4608,14 +4500,10 @@ class yc_config_openconfig_acl__acl_interfaces_interface_interface_ref_config(Py """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface','__subinterface',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) @@ -4748,14 +4636,10 @@ class yc_state_openconfig_acl__acl_interfaces_interface_interface_ref_state(Pybi """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface','__subinterface',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) @@ -4888,14 +4772,10 @@ class yc_interface_ref_openconfig_acl__acl_interfaces_interface_interface_ref(Py """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'interface-ref' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'interface-ref' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_interface_ref_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_interfaces_interface_interface_ref_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -5018,14 +4898,10 @@ class yc_config_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingres """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) @@ -5109,14 +4985,10 @@ class yc_state_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) @@ -5200,14 +5072,10 @@ class yc_state_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__matched_packets','__matched_octets',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) @@ -5423,14 +5291,10 @@ class yc_acl_entry_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ing """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__state',) - _yang_name = 'acl-entry' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entry' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set_acl_entries_acl_entry_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=False) @@ -5558,14 +5422,10 @@ class yc_acl_entries_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_i """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__acl_entry',) - _yang_name = 'acl-entries' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entries' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__acl_entry = YANGDynClass(base=YANGListType("sequence_id",yc_acl_entry_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set_acl_entries_acl_entry, yang_name="acl-entry", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='sequence-id', extensions=None), is_container='list', yang_name="acl-entry", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=False) @@ -5649,14 +5509,10 @@ class yc_ingress_acl_set_openconfig_acl__acl_interfaces_interface_ingress_acl_se """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name','__config','__state','__acl_entries',) - _yang_name = 'ingress-acl-set' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'ingress-acl-set' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -5863,14 +5719,10 @@ class yc_ingress_acl_sets_openconfig_acl__acl_interfaces_interface_ingress_acl_s """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__ingress_acl_set',) - _yang_name = 'ingress-acl-sets' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'ingress-acl-sets' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__ingress_acl_set = YANGDynClass(base=YANGListType("set_name",yc_ingress_acl_set_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set, yang_name="ingress-acl-set", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='set-name', extensions=None), is_container='list', yang_name="ingress-acl-set", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) @@ -5954,14 +5806,10 @@ class yc_config_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_ """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) @@ -6045,14 +5893,10 @@ class yc_state_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_a """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) @@ -6136,14 +5980,10 @@ class yc_state_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_a """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__matched_packets','__matched_octets',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) @@ -6359,14 +6199,10 @@ class yc_acl_entry_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egre """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__state',) - _yang_name = 'acl-entry' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entry' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set_acl_entries_acl_entry_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=False) @@ -6494,14 +6330,10 @@ class yc_acl_entries_openconfig_acl__acl_interfaces_interface_egress_acl_sets_eg """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__acl_entry',) - _yang_name = 'acl-entries' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entries' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__acl_entry = YANGDynClass(base=YANGListType("sequence_id",yc_acl_entry_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set_acl_entries_acl_entry, yang_name="acl-entry", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='sequence-id', extensions=None), is_container='list', yang_name="acl-entry", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=False) @@ -6585,14 +6417,10 @@ class yc_egress_acl_set_openconfig_acl__acl_interfaces_interface_egress_acl_sets """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name','__config','__state','__acl_entries',) - _yang_name = 'egress-acl-set' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'egress-acl-set' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -6799,14 +6627,10 @@ class yc_egress_acl_sets_openconfig_acl__acl_interfaces_interface_egress_acl_set """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__egress_acl_set',) - _yang_name = 'egress-acl-sets' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'egress-acl-sets' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__egress_acl_set = YANGDynClass(base=YANGListType("set_name",yc_egress_acl_set_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set, yang_name="egress-acl-set", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='set-name', extensions=None), is_container='list', yang_name="egress-acl-set", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) @@ -6890,14 +6714,10 @@ class yc_interface_openconfig_acl__acl_interfaces_interface(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__id','__config','__state','__interface_ref','__ingress_acl_sets','__egress_acl_sets',) - _yang_name = 'interface' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'interface' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__ingress_acl_sets = YANGDynClass(base=yc_ingress_acl_sets_openconfig_acl__acl_interfaces_interface_ingress_acl_sets, is_container='container', yang_name="ingress-acl-sets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__egress_acl_sets = YANGDynClass(base=yc_egress_acl_sets_openconfig_acl__acl_interfaces_interface_egress_acl_sets, is_container='container', yang_name="egress-acl-sets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -7186,14 +7006,10 @@ class yc_interfaces_openconfig_acl__acl_interfaces(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface',) - _yang_name = 'interfaces' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'interfaces' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__interface = YANGDynClass(base=YANGListType("id",yc_interface_openconfig_acl__acl_interfaces_interface, yang_name="interface", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='id', extensions=None), is_container='list', yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) @@ -7278,14 +7094,10 @@ class yc_acl_openconfig_acl__acl(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__state','__acl_sets','__interfaces',) - _yang_name = 'acl' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__acl_sets = YANGDynClass(base=yc_acl_sets_openconfig_acl__acl_acl_sets, is_container='container', yang_name="acl-sets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -7462,14 +7274,10 @@ class openconfig_acl(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__acl',) - _yang_name = 'openconfig-acl' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'openconfig-acl' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__acl = YANGDynClass(base=yc_acl_openconfig_acl__acl, is_container='container', yang_name="acl", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) From 2b41f6bd5cce29d9754856b25833dec61fb91a2b Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Tue, 10 Nov 2020 12:18:49 -0800 Subject: [PATCH 1369/1427] Add the vtysh command with newly added "-n" option for multi asic to the read_only_cmds (#5845) In multi asic platforms the "show ip bgp summary" commands is not available for user with read only privileges, so to fix this the vtysh command with the new "-n" option, added for multi asic platforms, needs to be added to the READ_ONLY_COMMANDS list in the sudoers files. Added the command vtysh -n [0-9] -c show * to list of READ_ONLY_COMMANDS in the sudoers files in this commit. Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- files/image_config/sudoers/sudoers | 1 + 1 file changed, 1 insertion(+) diff --git a/files/image_config/sudoers/sudoers b/files/image_config/sudoers/sudoers index 94670e936fbc..9e59c8854305 100644 --- a/files/image_config/sudoers/sudoers +++ b/files/image_config/sudoers/sudoers @@ -30,6 +30,7 @@ Cmnd_Alias READ_ONLY_CMDS = /bin/cat /var/log/syslog*, \ /usr/bin/sensors, \ /usr/bin/tail -F /var/log/syslog, \ /usr/bin/vtysh -c show *, \ + /usr/bin/vtysh -n [0-9] -c show *, \ /usr/local/bin/decode-syseeprom, \ /usr/local/bin/generate_dump, \ /usr/local/bin/lldpshow, \ From 1eaaf64ed2f95b67631936f2feade6133133ff64 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Tue, 10 Nov 2020 14:20:13 -0800 Subject: [PATCH 1370/1427] Set preference for forced mgmt routes (#5844) When forced mgmt routes are present, the issue fixed as part of #5754 is not complete. Added a preference(priority) field to forced mgmt route ip rules --- files/image_config/interfaces/interfaces.j2 | 4 ++-- .../tests/sample_output/py2/mvrf_interfaces | 4 ++++ .../tests/sample_output/py3/mvrf_interfaces | 4 ++++ src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml | 5 +++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index af3f807fc7df..98e43dd13be4 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -80,14 +80,14 @@ iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static up ip {{ '-4' if prefix | ipv4 else '-6' }} route add {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} up ip {{ '-4' if prefix | ipv4 else '-6' }} rule add pref 32765 from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} - up ip rule add to {{ route }} table {{ vrf_table }} + up ip rule add pref 32764 to {{ route }} table {{ vrf_table }} {% endfor %} # management port down rules pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete pref 32765 from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} - pre-down ip rule delete to {{ route }} table {{ vrf_table }} + pre-down ip rule delete pref 32764 to {{ route }} table {{ vrf_table }} {% endfor %} {# TODO: COPP policy type rules #} {% endfor %} diff --git a/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces index 7042901c093a..9e5c8a4261cf 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces @@ -32,10 +32,14 @@ iface eth0 inet static up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 up ip -4 rule add pref 32765 from 10.0.0.100/32 table 5000 + up ip rule add pref 32764 to 11.11.11.11 table 5000 + up ip rule add pref 32764 to 22.22.22.0/23 table 5000 # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table 5000 + pre-down ip rule delete pref 32764 to 11.11.11.11 table 5000 + pre-down ip rule delete pref 32764 to 22.22.22.0/23 table 5000 iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 diff --git a/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces index 7042901c093a..9e5c8a4261cf 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces @@ -32,10 +32,14 @@ iface eth0 inet static up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 up ip -4 rule add pref 32765 from 10.0.0.100/32 table 5000 + up ip rule add pref 32764 to 11.11.11.11 table 5000 + up ip rule add pref 32764 to 22.22.22.0/23 table 5000 # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table 5000 + pre-down ip rule delete pref 32764 to 11.11.11.11 table 5000 + pre-down ip rule delete pref 32764 to 22.22.22.0/23 table 5000 iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 diff --git a/src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml b/src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml index 5162086d9316..ee633c18bd1e 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml @@ -393,6 +393,11 @@ switch-t0 + + ForcedMgmtRoutes + + 11.11.11.11;22.22.22.0/23 + ErspanDestinationIpv4 From bec01ae3bbae40a00f00565f24c91eb2b7a0a60a Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Wed, 11 Nov 2020 00:36:22 +0200 Subject: [PATCH 1371/1427] [Mellanox] Enhance QSFP-DD DOM information (#5776) New driver support fetching additional pages from the cable EEPROM. There are additional information to parse now: RX/TX power, TX bias, TX fault and RX LOS. Signed-off-by: Shlomi Bitton --- .../mlnx-platform-api/sonic_platform/sfp.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 4814055ca5bc..cd6cbc9d2df8 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -180,7 +180,7 @@ QSFP_DD_RX_POWER_WIDTH = 16 QSFP_DD_TX_POWER_OFFSET = 26 QSFP_DD_TX_POWER_WIDTH = 16 -QSFP_DD_CHANNL_MON_OFFSET = 154 +QSFP_DD_CHANNL_MON_OFFSET = 26 QSFP_DD_CHANNL_MON_WIDTH = 48 QSFP_DD_CHANNL_DISABLE_STATUS_OFFSET = 86 QSFP_DD_CHANNL_DISABLE_STATUS_WIDTH = 1 @@ -466,8 +466,7 @@ def _dom_capability_detect(self): self.dom_tx_power_supported = True self.dom_tx_bias_power_supported = True self.dom_thresholds_supported = True - #currently set to False becasue Page 11h is not supported by FW - self.dom_rx_tx_power_bias_supported = False + self.dom_rx_tx_power_bias_supported = True else: self.dom_supported = False self.second_application_list = False @@ -975,7 +974,8 @@ def get_transceiver_bulk_status(self): if self.dom_rx_tx_power_bias_supported: # page 11h - dom_data_raw = self._read_eeprom_specific_bytes((QSFP_DD_CHANNL_MON_OFFSET), QSFP_DD_CHANNL_MON_WIDTH) + offset = 512 + dom_data_raw = self._read_eeprom_specific_bytes(offset + QSFP_DD_CHANNL_MON_OFFSET, QSFP_DD_CHANNL_MON_WIDTH) if dom_data_raw is None: return transceiver_dom_info_dict dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_data_raw, 0) @@ -1301,7 +1301,7 @@ def get_rx_los(self): elif self.sfp_type == QSFP_DD_TYPE: # page 11h if self.dom_rx_tx_power_bias_supported: - offset = 128 + offset = 512 dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_DD_CHANNL_RX_LOS_STATUS_WIDTH) if dom_channel_monitor_raw is not None: rx_los_data = int(dom_channel_monitor_raw[0], 8) @@ -1353,7 +1353,7 @@ def get_tx_fault(self): return None # page 11h if self.dom_rx_tx_power_bias_supported: - offset = 128 + offset = 512 dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_DD_CHANNL_TX_FAULT_STATUS_WIDTH) if dom_channel_monitor_raw is not None: tx_fault_data = int(dom_channel_monitor_raw[0], 8) @@ -1646,7 +1646,7 @@ def get_tx_bias(self): elif self.sfp_type == QSFP_DD_TYPE: # page 11h if self.dom_rx_tx_power_bias_supported: - offset = 128 + offset = 512 sfpd_obj = qsfp_dd_Dom() if sfpd_obj is None: return None @@ -1723,7 +1723,7 @@ def get_rx_power(self): elif self.sfp_type == QSFP_DD_TYPE: # page 11 if self.dom_rx_tx_power_bias_supported: - offset = 128 + offset = 512 sfpd_obj = qsfp_dd_Dom() if sfpd_obj is None: return None @@ -1801,7 +1801,7 @@ def get_tx_power(self): return None # page 11 if self.dom_rx_tx_power_bias_supported: - offset = 128 + offset = 512 sfpd_obj = qsfp_dd_Dom() if sfpd_obj is None: return None From d0f16c0d79b64ce9adc8535e370ed257a6dc3940 Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Tue, 10 Nov 2020 15:06:35 -0800 Subject: [PATCH 1372/1427] Make backend device checking more robust (#5730) Treat devices that are ToRRouters (ToRRouters and BackEndToRRouters) the same when rendering templates Except for BackEndToRRouters belonging to a storage cluster, since these devices have extra sub-interfaces created Treat devices that are LeafRouters (LeafRouters and BackEndLeafRouters) the same when rendering templates Signed-off-by: Lawrence Lee --- .../Arista-7060CX-32S-Q32/sai.profile.j2 | 2 +- .../Celestica-DX010-C32/sai.profile.j2 | 2 +- .../Force10-S6100/sai.profile.j2 | 2 +- .../DellEMC-Z9264f-Q64/sai.profile.j2 | 2 +- .../db98cx8580_16cd/buffers_config.j2 | 6 +++--- .../db98cx8580_32cd/buffers_config.j2 | 6 +++--- .../db98cx8580_16cd/buffers_config.j2 | 6 +++--- .../db98cx8580_32cd/buffers_config.j2 | 6 +++--- dockers/docker-orchagent/switch.json.j2 | 6 +++--- ...docker-router-advertiser.supervisord.conf.j2 | 2 +- files/build_templates/buffers_config.j2 | 6 +++--- files/build_templates/qos_config.j2 | 4 ++-- src/sonic-config-engine/minigraph.py | 17 ++++++++++++++--- .../tests/simple-sample-graph-case.xml | 1 + .../tests/simple-sample-graph.xml | 1 + .../tests/test_minigraph_case.py | 5 +++++ 16 files changed, 46 insertions(+), 28 deletions(-) diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 index e2ad59262cdd..5a50185247a0 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 @@ -1,7 +1,7 @@ {# Get sai.profile based on switch_role #} {%- if DEVICE_METADATA is defined -%} {%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-32x40G-t0.config.bcm' -%} {%- else %} {%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-32x40G-t1.config.bcm' -%} diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 index 21bf6cd6e737..5feba4956931 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 @@ -1,7 +1,7 @@ {# Get sai.profile based on switch_role #} {%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined -%} {%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-32x100G-t0.config.bcm' -%} {%- else %} {% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-32x100G-t1.config.bcm' -%} diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 index d2c794277098..44992f92f45f 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 @@ -1,7 +1,7 @@ {# Get sai.profile based on switch_role #} {%- if DEVICE_METADATA is defined -%} {%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s6100-64x40G-t0.config.bcm' -%} {%- else %} {%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s6100-64x40G-t1.config.bcm' -%} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 index bfb71fa71e3c..7c6d12b4b173 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 @@ -1,7 +1,7 @@ {# Get sai.profile based on switch_role #} {%- if DEVICE_METADATA is defined -%} {%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-64x40G-t0.config.bcm' -%} {%- else %} {%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-64x40G-t1.config.bcm' -%} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 index a5212d979fcb..5431fbe72c1f 100644 --- a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 @@ -9,9 +9,9 @@ def {# Determine device topology and filename postfix #} {%- if DEVICE_METADATA is defined %} {%- set switch_role = DEVICE_METADATA['localhost']['type'] %} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {%- set filename_postfix = 't0' %} -{%- elif switch_role.lower() == 'leafrouter' %} +{%- elif 'leafrouter' in switch_role.lower() %} {%- set filename_postfix = 't1' %} {%- else %} {%- set filename_postfix = set_default_topology() %} @@ -62,7 +62,7 @@ def {%- if cable_len -%} {{ cable_len.0 }} {%- else %} - {%- if switch_role.lower() == 'torrouter' %} + {%- if 'torrouter' in switch_role.lower() %} {%- for local_port in VLAN_MEMBER %} {%- if local_port[1] == port_name %} {%- set roles3 = switch_role + '_' + 'server' %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 index a5212d979fcb..5431fbe72c1f 100644 --- a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 @@ -9,9 +9,9 @@ def {# Determine device topology and filename postfix #} {%- if DEVICE_METADATA is defined %} {%- set switch_role = DEVICE_METADATA['localhost']['type'] %} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {%- set filename_postfix = 't0' %} -{%- elif switch_role.lower() == 'leafrouter' %} +{%- elif 'leafrouter' in switch_role.lower() %} {%- set filename_postfix = 't1' %} {%- else %} {%- set filename_postfix = set_default_topology() %} @@ -62,7 +62,7 @@ def {%- if cable_len -%} {{ cable_len.0 }} {%- else %} - {%- if switch_role.lower() == 'torrouter' %} + {%- if 'torrouter' in switch_role.lower() %} {%- for local_port in VLAN_MEMBER %} {%- if local_port[1] == port_name %} {%- set roles3 = switch_role + '_' + 'server' %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 index a5212d979fcb..5431fbe72c1f 100644 --- a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 @@ -9,9 +9,9 @@ def {# Determine device topology and filename postfix #} {%- if DEVICE_METADATA is defined %} {%- set switch_role = DEVICE_METADATA['localhost']['type'] %} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {%- set filename_postfix = 't0' %} -{%- elif switch_role.lower() == 'leafrouter' %} +{%- elif 'leafrouter' in switch_role.lower() %} {%- set filename_postfix = 't1' %} {%- else %} {%- set filename_postfix = set_default_topology() %} @@ -62,7 +62,7 @@ def {%- if cable_len -%} {{ cable_len.0 }} {%- else %} - {%- if switch_role.lower() == 'torrouter' %} + {%- if 'torrouter' in switch_role.lower() %} {%- for local_port in VLAN_MEMBER %} {%- if local_port[1] == port_name %} {%- set roles3 = switch_role + '_' + 'server' %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 index a5212d979fcb..5431fbe72c1f 100644 --- a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 @@ -9,9 +9,9 @@ def {# Determine device topology and filename postfix #} {%- if DEVICE_METADATA is defined %} {%- set switch_role = DEVICE_METADATA['localhost']['type'] %} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {%- set filename_postfix = 't0' %} -{%- elif switch_role.lower() == 'leafrouter' %} +{%- elif 'leafrouter' in switch_role.lower() %} {%- set filename_postfix = 't1' %} {%- else %} {%- set filename_postfix = set_default_topology() %} @@ -62,7 +62,7 @@ def {%- if cable_len -%} {{ cable_len.0 }} {%- else %} - {%- if switch_role.lower() == 'torrouter' %} + {%- if 'torrouter' in switch_role.lower() %} {%- for local_port in VLAN_MEMBER %} {%- if local_port[1] == port_name %} {%- set roles3 = switch_role + '_' + 'server' %} diff --git a/dockers/docker-orchagent/switch.json.j2 b/dockers/docker-orchagent/switch.json.j2 index c359dd805219..4d2a0be1b051 100644 --- a/dockers/docker-orchagent/switch.json.j2 +++ b/dockers/docker-orchagent/switch.json.j2 @@ -3,11 +3,11 @@ {% set hash_seed = 0 %} {% set hash_seed_offset = 0 %} {% if DEVICE_METADATA.localhost.type %} -{% if DEVICE_METADATA.localhost.type == "ToRRouter" %} +{% if "ToRRouter" in DEVICE_METADATA.localhost.type %} {% set hash_seed = 0 %} -{% elif DEVICE_METADATA.localhost.type == "LeafRouter" %} +{% elif "LeafRouter" in DEVICE_METADATA.localhost.type %} {% set hash_seed = 10 %} -{% elif DEVICE_METADATA.localhost.type == "SpineRouter" %} +{% elif "SpineRouter" in DEVICE_METADATA.localhost.type %} {% set hash_seed = 25 %} {% endif %} {% endif %} diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 index 9e7594117092..5a6416b0ffd8 100644 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 @@ -30,7 +30,7 @@ dependent_startup=true {# Router advertiser should only run on ToR (T0) devices which have #} {# at least one VLAN interface which has an IPv6 address asigned #} {%- set vlan_v6 = namespace(count=0) -%} -{%- if DEVICE_METADATA.localhost.type == "ToRRouter" -%} +{%- if "ToRRouter" in DEVICE_METADATA.localhost.type and DEVICE_METADATA.localhost.type != "MgmtToRRouter" -%} {%- if VLAN_INTERFACE -%} {%- for (name, prefix) in VLAN_INTERFACE|pfx_filter -%} {# If this VLAN has an IPv6 address... #} diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index 0eb976599a53..f5dbb9784f64 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -9,9 +9,9 @@ def {# Determine device topology and filename postfix #} {%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost']['type'] is defined %} {%- set switch_role = DEVICE_METADATA['localhost']['type'] %} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() and 'mgmt' not in switch_role.lower()%} {%- set filename_postfix = 't0' %} -{%- elif switch_role.lower() == 'leafrouter' %} +{%- elif 'leafrouter' in switch_role.lower() and 'mgmt' not in switch_role.lower()%} {%- set filename_postfix = 't1' %} {%- else %} {%- set filename_postfix = set_default_topology() %} @@ -69,7 +69,7 @@ def {%- if cable_len -%} {{ cable_len.0 }} {%- else %} - {%- if switch_role.lower() == 'torrouter' %} + {%- if 'torrouter' in switch_role.lower() and 'mgmt' not in switch_role.lower()%} {%- for local_port in VLAN_MEMBER %} {%- if local_port[1] == port_name %} {%- set roles3 = switch_role + '_' + 'server' %} diff --git a/files/build_templates/qos_config.j2 b/files/build_templates/qos_config.j2 index 9420be7a0671..a7c361d69fa5 100644 --- a/files/build_templates/qos_config.j2 +++ b/files/build_templates/qos_config.j2 @@ -73,7 +73,7 @@ "7": "7" } }, -{% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] in backend_device_types %} +{% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] in backend_device_types and 'storage_device' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['storage_device'] == 'true' %} "DOT1P_TO_TC_MAP": { "AZURE": { "0": "0", @@ -177,7 +177,7 @@ "PORT_QOS_MAP": { {% for port in PORT_ACTIVE %} "{{ port }}": { -{% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] in backend_device_types %} +{% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] in backend_device_types and 'storage_device' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['storage_device'] == 'true' %} "dot1p_to_tc_map" : "[DOT1P_TO_TC_MAP|AZURE]", {% else %} "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 96b68d7d22ef..c564d6051980 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -98,6 +98,7 @@ def parse_png(png, hname): port_speeds = {} console_ports = {} mux_cable_ports = {} + is_storage_device = False for child in png: if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for link in child.findall(str(QName(ns, "DeviceLinkBase"))): @@ -153,6 +154,12 @@ def parse_png(png, hname): device_data['deployment_id'] = deployment_id devices[name] = device_data + if name == hname: + cluster = device.find(str(QName(ns, "ClusterName"))) + + if cluster != None and "str" in cluster.text.lower(): + is_storage_device = True + if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for if_link in child.findall(str(QName(ns, 'DeviceLinkBase'))): if str(QName(ns3, "type")) in if_link.attrib: @@ -179,7 +186,7 @@ def parse_png(png, hname): mux_cable_ports[intf_name] = "true" - return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports, mux_cable_ports) + return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports, mux_cable_ports, is_storage_device) def parse_asic_external_link(link, asic_name, hostname): neighbors = {} @@ -915,6 +922,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw hostname = None linkmetas = {} host_lo_intfs = None + is_storage_device = False local_devices = [] # hostname is the asic_name, get the asic_id from the asic_name @@ -948,7 +956,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): - (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports, mux_cable_ports) = parse_png(child, hostname) + (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports, mux_cable_ports, is_storage_device) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): @@ -992,6 +1000,9 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw 'synchronous_mode': 'enable' } } + + if is_storage_device: + results['DEVICE_METADATA']['localhost']['storage_device'] = "true" # for this hostname, if sub_role is defined, add sub_role in # device_metadata if sub_role is not None: @@ -1159,7 +1170,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw results['PORTCHANNEL_INTERFACE'] = pc_intfs - if current_device['type'] in backend_device_types: + if current_device['type'] in backend_device_types and is_storage_device: del results['INTERFACE'] del results['PORTCHANNEL_INTERFACE'] diff --git a/src/sonic-config-engine/tests/simple-sample-graph-case.xml b/src/sonic-config-engine/tests/simple-sample-graph-case.xml index a3383a094602..c499dc15760d 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-case.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-case.xml @@ -254,6 +254,7 @@
switch-t0 Force10-S6000 + AAA00PrdStr00
diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index b99da804ea32..7215209da545 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -268,6 +268,7 @@ switch-t0 Force10-S6000 + AAA00PrdStr00 ARISTA01T1 diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index de4f6b77ce50..4ab1915864c3 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -185,6 +185,11 @@ def test_mux_cable_parsing(self): else: self.assertTrue("mux_cable" not in port) + def test_minigraph_storage_device(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'storage_device\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "true") + def test_minigraph_tunnel_table(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "TUNNEL"' expected_tunnel = { From 33076348ca12aeaa7aee39d0d6301433a60ddb9b Mon Sep 17 00:00:00 2001 From: gechiang <62408185+gechiang@users.noreply.github.com> Date: Tue, 10 Nov 2020 15:28:42 -0800 Subject: [PATCH 1373/1427] Moving BRCM SAI 4.2.1.3 to 4.2.1.3-1 to pick up fix for CS00011396506 to fix CRM nexthop resource inuse leak (#5878) --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 98c61b798bd7..2e647ed58cf8 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,8 +1,8 @@ -BRCM_SAI = libsaibcm_4.2.1.3_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm_4.2.1.3_amd64.deb?sv=2015-04-05&sr=b&sig=aA0Ltk2jteFuJZdr1ldj%2F5e6o7R0U5S%2FqVWvutPC7k0%3D&se=2021-08-31T04%3A08%3A35Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_4.2.1.3_amd64.deb +BRCM_SAI = libsaibcm_4.2.1.3-1_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm_4.2.1.3-1_amd64.deb?sv=2015-04-05&sr=b&sig=1%2BrMfgxeSc%2BXJUPw6X%2FhNGxe4KUp15Oqq1lVwMJGiW0%3D&se=2034-07-20T03%3A20%3A08Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_4.2.1.3-1_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm-dev_4.2.1.3_amd64.deb?sv=2015-04-05&sr=b&sig=r%2FWgs1VEFo07sbfYK%2FDZmk83QKTzwSSe%2F3%2BN3k3uAcY%3D&se=2022-01-30T22%3A55%3A04Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm-dev_4.2.1.3-1_amd64.deb?sv=2015-04-05&sr=b&sig=lTzaCynflt5UO7Ltf2Z%2B6zHJ4R%2BFj421kupIGO4%2FOCI%3D&se=2034-07-20T03%3A19%3A27Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From b5cfc0255261086e3c41a0e5cf65e96e3c535593 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Tue, 10 Nov 2020 16:53:27 -0800 Subject: [PATCH 1374/1427] [celestica dx010] comment out the initialization of PCA9541 (#5891) The original code tried to initialize PCA9541 without having the driver loaded. As result the initialization didn't take effect. Recently PCA9541 driver was added to the kernel and since then the initialization takes effect and has negatively impacted the platform stability. Commenting the initialization code out to restore the original behavior while analyzing further. Signed-off-by: Ying Xie --- .../debian/platform-modules-dx010.init | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init index 1e124565a41d..b1fb3c60fd61 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init @@ -63,7 +63,14 @@ start) # Attach PCA9541 Ox70 Master Selector chmod 755 /sys/bus/i2c/devices/i2c-${devnum}/new_device - echo pca9541 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/new_device + # FIXME: commenting out the following line. + # there had been no pca9541 driver loaded on Celestica platform, + # the recent addition of this driver casued following line + # becoming effictive, but negatively impacted the platform + # stability. Commenting it out restores the original behavior + # on Celestica platform. + # This change should be further analyzed and updated. + # echo pca9541 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/new_device sleep 1 # Attach PCA9548 0x71 Channel Extender for Main Board From cdc6879c3ec1bc6523fd678d10ef084dbefc785d Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 10 Nov 2020 18:44:20 -0800 Subject: [PATCH 1375/1427] [bgpcfgd]: Implement BBR template test (#5850) Add the test to check that all templates, which use CONFIG_DB__BBR are configured in constants.yml --- src/sonic-bgpcfgd/tests/test_bbr_templates.py | 70 +++++++++++++++++++ .../tests/test_ipv6_nexthop_global.py | 4 +- src/sonic-bgpcfgd/tests/test_templates.py | 4 +- src/sonic-bgpcfgd/tests/util.py | 12 ++-- 4 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 src/sonic-bgpcfgd/tests/test_bbr_templates.py diff --git a/src/sonic-bgpcfgd/tests/test_bbr_templates.py b/src/sonic-bgpcfgd/tests/test_bbr_templates.py new file mode 100644 index 000000000000..989734d79714 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_bbr_templates.py @@ -0,0 +1,70 @@ +import itertools +import os +import re + +from .util import load_constants_dir_mappings, load_constants + + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr/bgpd/templates') + + +def find_all_files(path): + paths_to_check = [path] + res = [] + while paths_to_check: + path = paths_to_check[0] + paths_to_check = paths_to_check[1:] + for name in os.listdir(path): + full_path = "%s/%s" % (path, name) + if os.path.isfile(full_path): + res.append(full_path) + elif os.path.isdir(full_path): + paths_to_check.append(full_path) + return res + +def get_files_to_check(): + directories = load_constants_dir_mappings() + general_path = "%s/%s" % (TEMPLATE_PATH, directories['general']) + files = find_all_files(general_path) + return files + +def get_peer_groups_with_bbr(filename): + re_bbr = re.compile(r".+CONFIG_DB__BGP_BBR.+") #\['status'\] == 'enabled'") + re_endif = re.compile(r'^\s*{% +endif +%}\s*$') + re_peer = re.compile(r'^\s*neighbor\s+(\S+)\s+allowas-in\s+1\s*$') + inside_bbr = False + res = [] + with open(filename) as fp: + for line in fp: + s_line = line.strip() + if s_line == '': + continue + elif s_line.startswith('!'): + continue + elif re_bbr.match(s_line): + inside_bbr = True + elif re_peer.match(s_line) and inside_bbr: + m = re_peer.match(s_line) + pg = m.group(1) + res.append(pg) + elif re_endif.match(s_line) and inside_bbr: + inside_bbr = False + return res + +def load_constants_bbr(): + data = load_constants() + assert "bgp" in data["constants"], "'bgp' key not found in constants.yml" + assert "peers" in data["constants"]["bgp"], "'peers' key not found in constants.yml" + assert "general" in data["constants"]["bgp"]['peers'], "'general' key not found in constants.yml" + return data["constants"]["bgp"]["peers"]['general'] + +def test_bbr_templates(): + files_to_check = get_files_to_check() + pg_with_bbr_per_file = [ get_peer_groups_with_bbr(name) for name in files_to_check ] + pg_with_bbr = set(itertools.chain.from_iterable(pg_with_bbr_per_file)) + general = load_constants_bbr() + if pg_with_bbr: + assert 'bbr' in general, "BBR is not defined in 'general', but BBR is enabled for %s" % pg_with_bbr + for pg in pg_with_bbr: + assert pg in general['bbr'], "peer-group '%s' has BBR enabled, but it is not configured in constants.yml" + diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py index 849b1f8d36be..d1bb67ee9cd4 100644 --- a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -2,7 +2,7 @@ import re from bgpcfgd.template import TemplateFabric -from .util import load_constants +from .util import load_constants_dir_mappings TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') @@ -110,7 +110,7 @@ def check_routemap(path, route_map_name): assert checked, "route-map %s wasn't found" % route_map_name def test_v6_next_hop_global(): - paths = ["tests/data/%s" % value for value in load_constants().values()] + paths = ["tests/data/%s" % value for value in load_constants_dir_mappings().values()] for path in paths: test_cases = process_instances(path) for test_case in test_cases: diff --git a/src/sonic-bgpcfgd/tests/test_templates.py b/src/sonic-bgpcfgd/tests/test_templates.py index 6c8204a28ec8..7d3bc773ad16 100644 --- a/src/sonic-bgpcfgd/tests/test_templates.py +++ b/src/sonic-bgpcfgd/tests/test_templates.py @@ -4,14 +4,14 @@ from bgpcfgd.template import TemplateFabric from bgpcfgd.config import ConfigMgr -from .util import load_constants +from .util import load_constants_dir_mappings TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') def load_tests(peer_type, template_name): - constants = load_constants() + constants = load_constants_dir_mappings() path = "tests/data/%s/%s" % (constants[peer_type], template_name) param_files = [name for name in os.listdir(path) if os.path.isfile(os.path.join(path, name)) and name.startswith("param_")] diff --git a/src/sonic-bgpcfgd/tests/util.py b/src/sonic-bgpcfgd/tests/util.py index aa6c62a56b5f..a328a272c836 100644 --- a/src/sonic-bgpcfgd/tests/util.py +++ b/src/sonic-bgpcfgd/tests/util.py @@ -3,14 +3,18 @@ CONSTANTS_PATH = os.path.abspath('../../files/image_config/constants/constants.yml') -def load_constants(): - with open(CONSTANTS_PATH) as f: - data = yaml.load(f) # FIXME" , Loader=yaml.FullLoader) +def load_constants_dir_mappings(): + data = load_constants() result = {} - assert "constants" in data, "'constants' key not found in constants.yml" assert "bgp" in data["constants"], "'bgp' key not found in constants.yml" assert "peers" in data["constants"]["bgp"], "'peers' key not found in constants.yml" for name, value in data["constants"]["bgp"]["peers"].items(): assert "template_dir" in value, "'template_dir' key not found for peer '%s'" % name result[name] = value["template_dir"] return result + +def load_constants(): + with open(CONSTANTS_PATH) as f: + data = yaml.load(f) # FIXME" , Loader=yaml.FullLoader) + assert "constants" in data, "'constants' key not found in constants.yml" + return data From 83d090f42c792c7d20e6e07a0c10d36107a6d5ba Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 10 Nov 2020 19:12:51 -0800 Subject: [PATCH 1376/1427] [teamd]: Remove extensive debug output for libteamdctl (#5870) --- .../0011-Remove-extensive-debug-output.patch | 25 +++++++++++++++++++ src/libteam/patch/series | 1 + 2 files changed, 26 insertions(+) create mode 100644 src/libteam/patch/0011-Remove-extensive-debug-output.patch diff --git a/src/libteam/patch/0011-Remove-extensive-debug-output.patch b/src/libteam/patch/0011-Remove-extensive-debug-output.patch new file mode 100644 index 000000000000..429ac56697d5 --- /dev/null +++ b/src/libteam/patch/0011-Remove-extensive-debug-output.patch @@ -0,0 +1,25 @@ +From 19928173ce022f499c59b719179e7ad9a4bafb7f Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Mon, 9 Nov 2020 13:21:55 -0800 +Subject: [PATCH] Remove extensive debug output + +--- + libteamdctl/cli_usock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libteamdctl/cli_usock.c b/libteamdctl/cli_usock.c +index 0dc97ae..d3fbdba 100644 +--- a/libteamdctl/cli_usock.c ++++ b/libteamdctl/cli_usock.c +@@ -163,7 +163,7 @@ static int cli_usock_method_call(struct teamdctl *tdc, const char *method_name, + char *replystr; + int err; + +- dbg(tdc, "usock: Calling method \"%s\"", method_name); ++ /* dbg(tdc, "usock: Calling method \"%s\"", method_name); */ + err= myasprintf(&msg, "%s\n%s\n", TEAMD_USOCK_REQUEST_PREFIX, + method_name); + if (err) +-- +2.29.2.windows.2 + diff --git a/src/libteam/patch/series b/src/libteam/patch/series index 7be69525d9d0..5350d37e4653 100644 --- a/src/libteam/patch/series +++ b/src/libteam/patch/series @@ -8,3 +8,4 @@ 0008-libteam-Add-warm_reboot-mode.patch 0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch 0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch +0011-Remove-extensive-debug-output.patch From 8100711531a979acbbf4726db66871d907a01b05 Mon Sep 17 00:00:00 2001 From: Andriy Yurkiv <70649192+ayurkiv-nvda@users.noreply.github.com> Date: Wed, 11 Nov 2020 05:27:09 +0200 Subject: [PATCH 1377/1427] [platform mellanox] Substitute '-' symbol to '.' in Mellanox SDK version to prevent problems with finding deb package (#5756) In case of non-GA SDK version there is '-' symbol in Mellanox SDK version name. (For example: 4.4.1306-006) In appropriate .deb packet there is '.' instead of '-'. Because of this there was problem while building SDK Signed-off-by: Andriy Yurkiv --- platform/mellanox/sdk.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 9639b03aa385..22d7657b4be5 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -3,7 +3,7 @@ MLNX_SDK_PKG_BASE_PATH = $(MLNX_SDK_BASE_PATH)/$(BLDENV)/ MLNX_SDK_VERSION = 4.4.1956 MLNX_SDK_ISSU_VERSION = 101 -MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) +MLNX_SDK_DEB_VERSION = $(subst -,.,$(subst _,.,$(MLNX_SDK_VERSION))) # Place here URL where SDK sources exist MLNX_SDK_SOURCE_BASE_URL = From 609cbdd0f374fa5a278df3804fef649609183dd2 Mon Sep 17 00:00:00 2001 From: Ciju Rajan K <53076238+ciju-juniper@users.noreply.github.com> Date: Wed, 11 Nov 2020 11:43:23 +0530 Subject: [PATCH 1378/1427] [Juniper] Platform bug fixes / improvements (#5541) * [Juniper] Platform bug fixes / improvements This patch set introduces the following changes for the two platforms. - QFX5210 - Fixes a driver bug related to reboot notifier - Disable pcied - Introduces a wrapper script for fast / warm reboots for unloading the driver containing reboot handler - Support for PSM4 optics in media_settings - QFX5200 - BCM configuration file updates - Bug fixes for EM policy - Fixes a driver bug related to reboot notifier - Introduces a wrapper script for fast / warm reboots for unloading the driver containing reboot handler - Disable pcied - Support for PSM4 optics Signed-off-by: Ciju Rajan K --- .../th-qfx5200-32x100g.config.bcm | 6 +- .../media_settings.json | 140 ++ .../plugins/qfx5200_eeprom_data.py | 39 +- .../plugins/sfputil.py | 6 +- .../media_settings.json | 1906 ++++++++++++++++- .../sonic-platform-juniper-qfx5200.install | 2 + .../sonic-platform-juniper-qfx5200.postinst | 6 + .../sonic-platform-juniper-qfx5210.install | 2 + .../sonic-platform-juniper-qfx5210.postinst | 7 +- .../qfx5200/modules/jnx-refpga-lpcm.c | 11 +- .../qfx5200/utils/juniper_qfx5200_monitor.py | 164 +- .../qfx5200/utils/show_thresholds | 35 +- .../qfx5200/utils/wrapper-fast-reboot | 17 + .../qfx5200/utils/wrapper-warm-reboot | 17 + .../modules/x86-64-juniper-qfx5210-64x-psu.c | 2 +- .../qfx5210/utils/juniper_qfx5210_util.py | 1 - .../qfx5210/utils/wrapper-fast-reboot | 17 + .../qfx5210/utils/wrapper-warm-reboot | 17 + .../sonic_platform/chassis.py | 35 +- 19 files changed, 2190 insertions(+), 240 deletions(-) create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-fast-reboot create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-warm-reboot create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-fast-reboot create mode 100755 platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-warm-reboot diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/th-qfx5200-32x100g.config.bcm b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/th-qfx5200-32x100g.config.bcm index 7e219ae76048..a0ed5ca2fa5c 100644 --- a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/th-qfx5200-32x100g.config.bcm +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/th-qfx5200-32x100g.config.bcm @@ -342,7 +342,7 @@ portmap_38=37:100 xgxs_rx_lane_map_127=0x2301 xgxs_rx_lane_map_119=0x3120 xgxs_tx_lane_map_129=0x3120 -l2_mem_entries=106496 +l2_mem_entries=8192 os=unix port_phy_addr_26=0xff port_phy_addr_18=0xff @@ -536,6 +536,7 @@ phy_xaui_tx_polarity_flip_94=0x01 phy_xaui_tx_polarity_flip_86=0x01 max_vp_lags=0 l3_max_ecmp_mode=1 +l3_alpm_enable=2 portmap_98=95:25:50:i portmap_3=3:25:50:i miim_intr_enable=0x0 @@ -549,10 +550,9 @@ portmap_100=131:1 portmap_99=96:25:i pbmp_oversubscribe=0xC4444451111111144444444422222222 portmap_4=4:25:i -l3_mem_entries=40960 +l3_mem_entries=8192 xgxs_tx_lane_map_20=0x0213 xgxs_tx_lane_map_12=0x3120 -num_ipv6_lpm_128b_entries=1024 port_phy_addr_95=0xff port_phy_addr_87=0xff port_phy_addr_79=0xff diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json b/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json index aec90682bc09..c56f2457e411 100644 --- a/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json +++ b/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json @@ -15,6 +15,146 @@ "lane3":"0xa" } }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU2": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J3": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-INNO-TR-FC13L-NJC": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-INNO-TR-FC13R-NJC": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-SOURCE-SPQCELRCDFAJ2": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, "FINISAR CORP.-FTL4C1QE1C-J1": { "preemphasis": { "lane0":"0x115f00", diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py index a5e3d454350c..7d7465212050 100644 --- a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py @@ -37,22 +37,43 @@ import binascii from sonic_eeprom import eeprom_tlvinfo -def main(): - eeprom_qfx5200 = Eeprom() - FAN0_TYPE="cat /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan0_type" - try: - status,fan0_type=commands.getstatusoutput(FAN0_TYPE) - except Exception as e: - print "Error on refpga-tmc.15 fan0_type e:" + str(e) - return False +def fantype_detect(): + + refpgaTMC_path = "/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15" AFO = "1" + AFI = "0" + + #default fan type is AFO + default_fantype = "0" + + for filename in os.listdir(refpgaTMC_path): + if filename.endswith('_type'): + fantype_path = os.path.join(refpgaTMC_path, filename) + cat_string = "cat " + fantype_string = cat_string + fantype_path + status,fan_type=commands.getstatusoutput(fantype_string) + if ((fan_type == AFO) or (fan_type == AFI)): + return fan_type + else: + pass + + return default_fantype + + +def main(): + AFO_value = "1" + + eeprom_qfx5200 = Eeprom() + + fan_type = fantype_detect() + # creating the "/var/run/eeprom" file and storing values of CPU board EEPROM and MAIN Board EEPROM in this file. eeprom_file = open ("/var/run/eeprom", "a+") eeprom_file.write("\n") - if fan0_type == AFO: + if fan_type == AFO_value: eeprom_file.write("Fan Type=AFO\r\n") else: eeprom_file.write("Fan Type=AFI\r\n") diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py index bafdd4bbc739..91957139967d 100644 --- a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py @@ -50,7 +50,7 @@ SYSLOG_IDENTIFIER = "sfputil" -# Global logger class instance +# Global Logger class instance logger = Logger(SYSLOG_IDENTIFIER) qfx5200_qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', @@ -331,12 +331,16 @@ class SfpUtil(SfpUtilBase): "AFBR-89CDDZ-JU1", "AFBR-89CDDZ-JU2", "FTLC9551REPM-J1", + "FCBN425QE1C30-J1", + "FCBN425QE1C10-J1", "FTLC9551REPM-J3", "LUX42604CO", + "LUX42604BO", "EOLQ-161HG-10-LJ1", "FTLC1151RDPL-J1", "TR-FC13R-NJC", "TR-FC13L-NJC", + "TR-FC13R-NJ3", "SPQ-CE-LR-CDFB-J2", "1K1QAC", "SPQCELRCDFAJ2" diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json b/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json index 22788f3a6f23..4a57e4b79e3a 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json +++ b/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json @@ -241,6 +241,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "AVAGO-AFBR-79EQDZ-JU1": { "preemphasis": { "lane0":"0xd3a02", @@ -341,6 +369,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -651,6 +707,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -961,6 +1045,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -1271,6 +1383,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -1567,6 +1707,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { "preemphasis": { "lane0":"0x1c4503", @@ -1891,6 +2059,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x174a03", @@ -2201,6 +2397,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -2511,6 +2735,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -2821,6 +3073,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -3131,6 +3411,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -3441,6 +3749,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -3751,6 +4087,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154c03", @@ -4061,6 +4425,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154c03", @@ -4371,6 +4763,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154c03", @@ -4681,6 +5101,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154c03", @@ -4991,6 +5439,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154901", @@ -5301,6 +5777,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154900", @@ -5569,10 +6073,40 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ5": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0xa3002" + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" }, "idriver": { "lane0":"0x8", @@ -5580,15 +6114,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "18": { - "Default": { + }, + "JUNIPER-LUXTERA-LUX42604BO": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" }, "idriver": { "lane0":"0x8", @@ -5597,7 +6129,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-LUXTERA-LUX42604CO": { "preemphasis": { "lane0":"0x154900", "lane1":"0x124900", @@ -5921,6 +6453,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154903", @@ -6231,6 +6791,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -6541,6 +7129,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -6851,6 +7467,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -7161,6 +7805,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1e4303", @@ -7471,6 +8143,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154906", @@ -7781,6 +8481,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x174902", @@ -8091,6 +8819,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -8370,15 +9126,43 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "27": { - "Default": { + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604BO": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" }, "idriver": { "lane0":"0x8", @@ -8387,7 +9171,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-LUXTERA-LUX42604CO": { "preemphasis": { "lane0":"0x1a4703", "lane1":"0x1a4703", @@ -8711,6 +9495,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4505", @@ -9021,6 +9833,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -9331,6 +10171,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4604", @@ -9641,6 +10509,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4504", @@ -9951,6 +10847,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -10261,6 +11185,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -10571,6 +11523,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -10881,6 +11861,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -11149,10 +12157,40 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ5": { "preemphasis": { - "lane0":"0xe3804", - "lane1":"0xe3803", - "lane2":"0xe3804", - "lane3":"0xe3804" + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "36": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -11160,15 +12198,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "36": { - "Default": { + }, + "JUNIPER-LUXTERA-LUX42604BO": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -11177,7 +12213,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-LUXTERA-LUX42604CO": { "preemphasis": { "lane0":"0x1b4603", "lane1":"0x1b4603", @@ -11501,6 +12537,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -11811,6 +12875,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x164903", @@ -12121,6 +13213,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x164901", @@ -12431,6 +13551,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -12741,6 +13889,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -13051,6 +14227,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -13361,6 +14565,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -13671,6 +14903,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x184902", @@ -13950,15 +15210,43 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "45": { - "Default": { + } + }, + "45": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604BO": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" }, "idriver": { "lane0":"0x8", @@ -13967,7 +15255,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-LUXTERA-LUX42604CO": { "preemphasis": { "lane0":"0x154900", "lane1":"0x154900", @@ -14291,6 +15579,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x174900", @@ -14601,6 +15917,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154903", @@ -14911,6 +16255,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x184902", @@ -15221,6 +16593,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x174901", @@ -15531,6 +16931,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x184901", @@ -15841,6 +17269,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154903", @@ -16151,6 +17607,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -16461,6 +17945,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -16729,10 +18241,40 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ5": { "preemphasis": { - "lane0":"0xa3403", - "lane1":"0xa3403", - "lane2":"0xa3403", - "lane3":"0xa3403" + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "54": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" }, "idriver": { "lane0":"0x8", @@ -16740,15 +18282,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "54": { - "Default": { + }, + "JUNIPER-LUXTERA-LUX42604BO": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" }, "idriver": { "lane0":"0x8", @@ -16757,7 +18297,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-LUXTERA-LUX42604CO": { "preemphasis": { "lane0":"0x1c4503", "lane1":"0x1e4204", @@ -17081,6 +18621,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -17391,6 +18959,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x184903", @@ -17701,6 +19297,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -18011,6 +19635,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604C0": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -18321,6 +19973,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -18631,6 +20311,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -18941,6 +20649,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -19251,6 +20987,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4404", @@ -19562,6 +21326,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4504", diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install index 285c07edd1a3..a726447549d9 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install @@ -4,3 +4,5 @@ qfx5200/utils/show_thresholds usr/local/bin qfx5200/utils/temperature_thresholds_AFI.txt usr/local/bin qfx5200/utils/temperature_thresholds_AFO.txt usr/local/bin qfx5200/service/qfx5200-platform-init.service etc/systemd/system +qfx5200/utils/wrapper-warm-reboot usr/local/bin +qfx5200/utils/wrapper-fast-reboot usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst index 195f30e66820..bdcf70e2beaf 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst @@ -28,4 +28,10 @@ if [ -f $FIRST_BOOT_FILE ]; then # Creating the UEFI entry for the first time. efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /var/tmp/efi_log 2>&1 fi + mkdir /usr/bin/qfx5200-warm-reboot + mkdir /usr/bin/qfx5200-fast-reboot + cp /usr/bin/warm-reboot /usr/bin/qfx5200-warm-reboot + cp /usr/bin/fast-reboot /usr/bin/qfx5200-fast-reboot + cp /usr/local/bin/wrapper-warm-reboot /usr/bin/warm-reboot + cp /usr/local/bin/wrapper-fast-reboot /usr/bin/fast-reboot fi diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.install b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.install index db8c036fdd0d..9444aae8b7c2 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.install +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.install @@ -2,3 +2,5 @@ qfx5210/utils/juniper_qfx5210_util.py usr/local/bin qfx5210/utils/juniper_qfx5210_monitor.py usr/local/bin qfx5210/utils/platform_poweroff usr/local/bin qfx5210/service/qfx5210-platform-init.service etc/systemd/system +qfx5210/utils/wrapper-warm-reboot usr/local/bin +qfx5210/utils/wrapper-fast-reboot usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst index e5b65e81206b..e4a9d353ef5d 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst @@ -28,5 +28,10 @@ if [ -f $FIRST_BOOT_FILE ]; then # Creating the UEFI entry for the first time. efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /var/tmp/efi_log 2>&1 fi - rm -rf /sys/fs/pstore/* + mkdir /usr/bin/qfx5210-warm-reboot + mkdir /usr/bin/qfx5210-fast-reboot + cp /usr/bin/warm-reboot /usr/bin/qfx5210-warm-reboot + cp /usr/bin/fast-reboot /usr/bin/qfx5210-fast-reboot + cp /usr/local/bin/wrapper-warm-reboot /usr/bin/warm-reboot + cp /usr/local/bin/wrapper-fast-reboot /usr/bin/fast-reboot fi diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c index 26e8b06db3aa..e305b1c3219c 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c @@ -98,14 +98,15 @@ static int __init refpga_lpcm_init(void) static void __exit refpga_lpcm_exit(void) { - iounmap(fpga); - release_mem_region(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE); /* - * Unregister the cpld soft reset handler + * Unregister the fpga soft reset handler */ - if (!unregister_restart_handler(&qfx5200_nb)) { - printk(KERN_CRIT "Failed to uregister restart handler\n"); + if (unregister_reboot_notifier(&qfx5200_nb)) { + printk(KERN_CRIT "Failed to uregister reboot notifier\n"); + return; } + iounmap(fpga); + release_mem_region(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE); printk(KERN_INFO "Re-Fpga lpcm module removed\n"); } diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py index 9620b4e9de43..dc47f1049322 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py @@ -56,9 +56,6 @@ isPlatformAFI = False -isFireThresholdReached = False -isFireThresholdPrint = True -FireThresholdSecsRemaining = 120 PrevASICValue = 0 temp_policy_AFI = { @@ -223,6 +220,7 @@ class QFX5200_ThermalUtil(object): CORETEMP_PATH = '/sys/bus/platform/devices/coretemp.0/hwmon/hwmon*/temp{0}_input' MAJORALARM_LED_PATH = '/sys/class/leds/alarm-major/brightness' MINORALARM_LED_PATH = '/sys/class/leds/alarm-minor/brightness' + MONITORLOG_PATH = '/var/log/juniper_qfx5200_monitor.log' """ Dictionary where key1 = thermal id index (integer) starting from 1 @@ -449,9 +447,6 @@ def set_alarm_led_brightness(self, val): def getSensorTemp(self): global isPlatformAFI - global isFireThresholdReached - global FireThresholdSecsRemaining - global isFireThresholdPrint global PrevASICValue sensor_str = '' @@ -480,25 +475,6 @@ def getSensorTemp(self): 10: [0,0,0,0,0,0,0,0,0,0,0,0], 11: [0,0,0,0,0,0,0,0,0,0,0,0], } - # if the Firethreshold Flag is set and 120 seconds have elapsed, invoking the "poweroff" to shutdown the box - if (isFireThresholdReached == True): - firethr = FireThresholdSecsRemaining - 20 - if firethr == 0: - logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown now') - os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown now' > /dev/console") - else: - logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds', firethr) - os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds' > /dev/console" % firethr) - - FireThresholdSecsRemaining = FireThresholdSecsRemaining - 20 - logging.critical('CRITICAL: Value of FireThresholdSecsRemaining %s seconds', FireThresholdSecsRemaining) - - if (FireThresholdSecsRemaining == 0): - isFireThresholdReached == False - time.sleep(20) - logging.debug('Executing poweroff command') - cmd = "poweroff" - os.system(cmd) for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): SEN_str = 'SEN' @@ -591,26 +567,29 @@ def getSensorTemp(self): if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): - isFireThresholdReached = True + logging.debug('Fire Threshold reached: System is going to shutdown now') + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown now' > /dev/console") - if (isFireThresholdPrint == True): - logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds') - os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds' > /dev/console") - isFireThresholdPrint = False - self.set_alarm_led_brightness(2) - logging.debug('Setting Red Alarm as one temp sensor is running at soft shutdown temp value') + logging.debug('Executing poweroff command') + + time.sleep(1) + + try: + monitorlog_file = open(self.MONITORLOG_PATH) + except IOError as e: + logging.error('get_Sensor_temp: unable to open file: %s', str(e)) + return False + monitorlog_file.close() + + cmd = "poweroff" + os.system(cmd) + # CHECK IF ANY TEMPERATURE SENSORS is running at RED warning , IF YES, SET THE ALARM LED TO 'RED' elif (SensorFlag[0][10] or SensorFlag[1][10] or SensorFlag[2][10] or SensorFlag[3][10] or SensorFlag[4][10] or SensorFlag[5][10] or SensorFlag[6][10] or SensorFlag[7][10] or SensorFlag[8][10] or SensorFlag[9][10] or SensorFlag[10][10] or SensorFlag[11][10]): - - if (isFireThresholdReached == True): - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - + self.set_alarm_led_brightness(2) logging.debug('Setting Red Alarm') @@ -619,13 +598,8 @@ def getSensorTemp(self): elif (SensorFlag[0][9] or SensorFlag[1][9] or SensorFlag[2][9] or SensorFlag[3][9] or SensorFlag[4][9] or SensorFlag[5][9] or SensorFlag[6][9] or SensorFlag[7][9] or SensorFlag[8][9] or SensorFlag[9][9] or SensorFlag[10][9] or SensorFlag[11][9]): - if (isFireThresholdReached == True): - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - self.set_alarm_led_brightness(1) + logging.debug('Setting Yellow Alarm') else: @@ -641,16 +615,6 @@ def getSensorTemp(self): if (SensorFlag[0][8] or SensorFlag[1][8] or SensorFlag[2][8] or SensorFlag[3][8] or SensorFlag[4][8] or SensorFlag[5][8] or SensorFlag[6][8] or SensorFlag[7][8] or SensorFlag[8][8] or SensorFlag[9][8] or SensorFlag[10][8] or SensorFlag[11][8]): - if (isFireThresholdReached == True): - if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] - or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): - pass - else: - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - fan.get_check_fan_dutycycle() if (fan.get_fan_dutycycle() < 100): time.sleep(0.50) @@ -661,16 +625,6 @@ def getSensorTemp(self): elif (SensorFlag[0][7] or SensorFlag[1][7] or SensorFlag[2][7] or SensorFlag[3][7] or SensorFlag[4][7] or SensorFlag[5][7] or SensorFlag[6][7] or SensorFlag[7][7] or SensorFlag[8][7] or SensorFlag[9][7] or SensorFlag[10][7] or SensorFlag[11][7]): - if (isFireThresholdReached == True): - if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] - or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): - pass - else: - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - fan.get_check_fan_dutycycle() if (fan.get_fan_dutycycle() == 100): @@ -686,16 +640,6 @@ def getSensorTemp(self): elif (SensorFlag[0][6] or SensorFlag[1][6] or SensorFlag[2][6] or SensorFlag[3][6] or SensorFlag[4][6] or SensorFlag[5][6] or SensorFlag[6][6] or SensorFlag[7][6] or SensorFlag[8][6] or SensorFlag[9][6] or SensorFlag[10][6] or SensorFlag[11][6]): - if (isFireThresholdReached == True): - if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] - or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): - pass - else: - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - fan.get_check_fan_dutycycle() if (fan.get_fan_dutycycle() < 90): @@ -713,16 +657,6 @@ def getSensorTemp(self): elif (SensorFlag[0][5] or SensorFlag[1][5] or SensorFlag[2][5] or SensorFlag[3][5] or SensorFlag[4][5] or SensorFlag[5][5] or SensorFlag[6][5] or SensorFlag[7][5] or SensorFlag[8][5] or SensorFlag[9][5] or SensorFlag[10][5] or SensorFlag[11][5]): - if (isFireThresholdReached == True): - if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] - or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): - pass - else: - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - fan.get_check_fan_dutycycle() if (fan.get_fan_dutycycle() > 75): @@ -742,17 +676,7 @@ def getSensorTemp(self): # CHECK IF ANY TEMPERATURE SENSORS HAS SET 75% DUTY CYCLE FLAG elif (SensorFlag[0][4] or SensorFlag[1][4] or SensorFlag[2][4] or SensorFlag[3][4] or SensorFlag[4][4] or SensorFlag[5][4] or SensorFlag[6][4] or SensorFlag[7][4] or SensorFlag[8][4] or SensorFlag[9][4] or SensorFlag[10][4] or SensorFlag[11][4]): - - if (isFireThresholdReached == True): - if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] - or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): - pass - else: - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - + fan.get_check_fan_dutycycle() if (fan.get_fan_dutycycle() < 75): time.sleep(0.25) @@ -772,16 +696,6 @@ def getSensorTemp(self): elif (SensorFlag[0][3] or SensorFlag[1][3] or SensorFlag[2][3] or SensorFlag[3][3] or SensorFlag[4][3] or SensorFlag[5][3] or SensorFlag[6][3] or SensorFlag[7][3] or SensorFlag[8][3] or SensorFlag[9][3] or SensorFlag[10][3] or SensorFlag[11][3]): - if (isFireThresholdReached == True): - if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] - or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): - pass - else: - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - fan.get_check_fan_dutycycle() if (fan.get_fan_dutycycle() > 55): @@ -807,16 +721,6 @@ def getSensorTemp(self): elif (SensorFlag[0][2] or SensorFlag[1][2] or SensorFlag[2][2] or SensorFlag[3][2] or SensorFlag[4][2] or SensorFlag[5][2] or SensorFlag[6][2] or SensorFlag[7][2] or SensorFlag[8][2] or SensorFlag[9][2] or SensorFlag[10][2] or SensorFlag[11][2]): - if (isFireThresholdReached == True): - if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] - or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): - pass - else: - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - fan.get_check_fan_dutycycle() if (fan.get_fan_dutycycle() < 55): @@ -833,18 +737,7 @@ def getSensorTemp(self): # CHECK IF ANY TEMPERATURE SENSORS HAS SET 35% PREV DUTY CYCLE FLAG elif (SensorFlag[0][1] or SensorFlag[1][1] or SensorFlag[2][1] or SensorFlag[3][1] or SensorFlag[4][1] or SensorFlag[5][1] or SensorFlag[6][1] or SensorFlag[7][1] or SensorFlag[8][1] or SensorFlag[9][1] or SensorFlag[10][1] or SensorFlag[11][1]): - - if (isFireThresholdReached == True): - - if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] - or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): - pass - else: - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - + fan.get_check_fan_dutycycle() if (fan.get_fan_dutycycle() > 35): @@ -869,17 +762,6 @@ def getSensorTemp(self): elif (SensorFlag[0][0] or SensorFlag[1][0] or SensorFlag[2][0] or SensorFlag[3][0] or SensorFlag[4][0] or SensorFlag[5][0] or SensorFlag[6][0] or SensorFlag[7][0] or SensorFlag[8][0] or SensorFlag[9][0] or SensorFlag[10][0] or SensorFlag[11][0]): - if (isFireThresholdReached == True): - - if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] - or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): - pass - else: - logging.critical('CRITICAL: System Stabilized, not shutting down') - os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") - FireThresholdSecsRemaining = 120 - isFireThresholdReached = False - fan.get_check_fan_dutycycle() if (fan.get_fan_dutycycle() > 35): @@ -939,10 +821,8 @@ def __init__(self, log_file, log_level): # set up logging to file logging.basicConfig( filename=log_file, - filemode='w', level=log_level, - format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', - datefmt='%H:%M:%S' + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s' ) if DEBUG == True: diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds index 2edb69de40a4..29d584e7f328 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds @@ -1,17 +1,36 @@ #!/usr/bin/env python +import os import commands -def main(): - FAN0_TYPE="cat /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan0_type" - try: - status,fan0_type=commands.getstatusoutput(FAN0_TYPE) - except Exception as e: - print "Error on refpga-tmc.15 fan0_type e:" + str(e) - return False +def fantype_detect(): + + refpgaTMC_path = "/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15" AFO = "1" + AFI = "0" + + #default fan type is AFI + default_fantype = 0 + + for filename in os.listdir(refpgaTMC_path): + if filename.endswith('_type'): + fantype_path = os.path.join(refpgaTMC_path, filename) + cat_string = "cat " + fantype_string = cat_string + fantype_path + status,fan_type=commands.getstatusoutput(fantype_string) + if ((fan_type == AFO) or (fan_type == AFI)): + return fan_type + else: + pass + + return default_fantype + +def main(): + AFO_value = "1" + + fan_type = fantype_detect() - if fan0_type == AFO: + if fan_type == AFO_value: temp_thres_file = open("/usr/local/bin/temperature_thresholds_AFO.txt", "r+") print temp_thres_file.read() else: diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-fast-reboot b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-fast-reboot new file mode 100755 index 000000000000..08ac3be0d688 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-fast-reboot @@ -0,0 +1,17 @@ +#!/bin/bash + +# Disable exit on non zero +set +e + +# Unloading this module as it contains the reboot +# notifier hook. When the kexec is invoked with platform +# reset handlers, it results in a cold reboot. Removing +# the reset handlers ensures that kernel does a kexec +# based fast reboot +rmmod jnx-refpga-lpcm > /dev/null 2>&1 + +/usr/bin/qfx5200-fast-reboot/fast-reboot $@ + +# Re-load the module if the fast-reboot script returns +# here. +modprobe jnx-refpga-lpcm > /dev/null 2>&1 diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-warm-reboot b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-warm-reboot new file mode 100755 index 000000000000..e34db6629588 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-warm-reboot @@ -0,0 +1,17 @@ +#!/bin/bash + +# Disable exit on non zero +set +e + +# Unloading this module as it contains the reboot +# notifier hook. When the kexec is invoked with platform +# reset handlers, it results in a cold reboot. Removing +# the reset handlers ensures that kernel does a kexec +# based fast reboot +rmmod jnx-refpga-lpcm > /dev/null 2>&1 + +/usr/bin/qfx5200-warm-reboot/warm-reboot $@ + +# Re-load the module if the warm-reboot script returns +# here. +modprobe jnx-refpga-lpcm > /dev/null 2>&1 diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c index cb283d2d4a1c..49a0cbbcebdd 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c @@ -306,7 +306,7 @@ static void __exit qfx5210_64x_psu_exit(void) /* * Unregister the cpld soft reset handler */ - if (!unregister_restart_handler(&qfx5210_nb)) { + if (unregister_reboot_notifier(&qfx5210_nb)) { printk(KERN_CRIT "Failed to uregister restart handler\n"); } diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py index c6aaf435e504..5479c0e04126 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py @@ -484,7 +484,6 @@ def set_device(args): if int(args[1])>100: show_set_help() return - #print ALL_DEVICE['fan'] #fan1~6 is all fine, all fan share same setting node = ALL_DEVICE['fan'] ['fan1'][0] node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-fast-reboot b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-fast-reboot new file mode 100755 index 000000000000..e1a32a52472f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-fast-reboot @@ -0,0 +1,17 @@ +#!/bin/bash + +# Disable exit on non zero +set +e + +# Unloading this module as it contains the reboot +# notifier hook. When the kexec is invoked with platform +# reset handlers, it results in a cold reboot. Removing +# the reset handlers ensures that kernel does a kexec +# based fast reboot +rmmod x86-64-juniper-qfx5210-64x-psu > /dev/null 2>&1 + +/usr/bin/qfx5210-fast-reboot/fast-reboot $@ + +# Re-load the module if the fast-reboot script returns +# here +modprobe x86-64-juniper-qfx5210-64x-psu > /dev/null 2>&1 diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-warm-reboot b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-warm-reboot new file mode 100755 index 000000000000..8815efe0acae --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-warm-reboot @@ -0,0 +1,17 @@ +#!/bin/bash + +# Disable exit on non zero +set +e + +# Unloading this module as it contains the reboot +# notifier hook. When the kexec is invoked with platform +# reset handlers, it results in a cold reboot. Removing +# the reset handlers ensures that kernel does a kexec +# based fast reboot +rmmod x86-64-juniper-qfx5210-64x-psu > /dev/null 2>&1 + +/usr/bin/qfx5210-warm-reboot/warm-reboot $@ + +# Re-load the module if the warm-reboot script returns +# here +modprobe x86-64-juniper-qfx5210-64x-psu > /dev/null 2>&1 diff --git a/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py index 38344cecae13..4f673ab086ba 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py @@ -270,9 +270,13 @@ def get_reboot_cause(self): elif str(platform_name) == "x86_64-juniper_networks_qfx5200-r0" : log_info("Juniper Platform QFX5200 ") + status, major_version = commands.getstatusoutput("busybox devmem 0xFED50000 8") + status, minor_version = commands.getstatusoutput("busybox devmem 0xFED50001 8") status, last_reboot_reason = commands.getstatusoutput("busybox devmem 0xFED50004 8") if (status == 0): - if last_reboot_reason == "0x80": + if (major_version == "0x31") and (minor_version == "0x03") and (last_reboot_reason == "0x80"): + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif (major_version == "0x31") and (minor_version == "0x05") and (last_reboot_reason == "0x02"): return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) @@ -284,16 +288,23 @@ def get_reboot_cause(self): return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") else: time.sleep(3) + status, major_version = commands.getstatusoutput("busybox devmem 0xFED50000 8") + status, minor_version = commands.getstatusoutput("busybox devmem 0xFED50001 8") status, last_reboot_reason = commands.getstatusoutput("busybox devmem 0xFED50004 8") - if last_reboot_reason == "0x80": - return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) - elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": - return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) - elif last_reboot_reason == "0x20": - return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) - elif last_reboot_reason == "0x10": - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") - else: - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + if (status == 0): + if (major_version == "0x31") and (minor_version == "0x03") and (last_reboot_reason == "0x80"): + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif (major_version == "0x31") and (minor_version == "0x05") and (last_reboot_reason == "0x02"): + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + else: + log_info("Error while reading Re-Fpga") else: - log_info("Juniper QFX5200 and QFX5210 platforms are supported") + log_info("Unsupported platform") From e0ebcc0c769b38e06501b558da1e712032d0bee3 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 11 Nov 2020 10:18:48 -0800 Subject: [PATCH 1379/1427] [check_install.py] Convert to Python 3 (#5831) - Convert check_install.py script to Python 3 - Reorganize imports per PEP8 standard - Two blank lines precede functions per PEP8 standard --- check_install.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/check_install.py b/check_install.py index d95d831daa70..b3721aff1948 100755 --- a/check_install.py +++ b/check_install.py @@ -1,10 +1,11 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import pexpect import argparse +import pexpect import sys import time + def main(): parser = argparse.ArgumentParser(description='test_login cmdline parser') @@ -21,16 +22,16 @@ def main(): login_prompt = 'sonic login:' passwd_prompt = 'Password:' - cmd_prompt = "%s@sonic:~\$ $" % args.u + cmd_prompt = "{}@sonic:~\$ $".format(args.u) grub_selection = "The highlighted entry will be executed" i = 0 while True: try: - p = pexpect.spawn("telnet 127.0.0.1 %s" % args.p, timeout=600, logfile=sys.stdout) + p = pexpect.spawn("telnet 127.0.0.1 {}".format(args.p), timeout=600, logfile=sys.stdout, encoding='utf-8') break except Exception as e: - print str(e) + print(str(e)) i += 1 if i == 10: raise From fd9bd4018833c6f22a5de2a2908222b685c55b02 Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Wed, 11 Nov 2020 21:08:15 +0200 Subject: [PATCH 1380/1427] [Mellanox] Fix for QSFP-DD channel status (#5900) Wrong object init broke the API. Replace object to the correct type. Signed-off-by: Shlomi Bitton --- platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index cd6cbc9d2df8..89b4b520a48e 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -1265,7 +1265,7 @@ def get_reset_status(self): return False elif self.sfp_type == QSFP_DD_TYPE: offset = 0 - sfpd_obj = qsfp_dd_InterfaceId() + sfpd_obj = qsfp_dd_Dom() dom_channel_status_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_CHANNL_STATUS_OFFSET), QSFP_DD_CHANNL_STATUS_WIDTH) if dom_channel_status_raw is None: From 89d947165434d04a1f7c4512039e49b5b85cb9f4 Mon Sep 17 00:00:00 2001 From: Srideep Date: Wed, 11 Nov 2020 13:59:30 -0700 Subject: [PATCH 1381/1427] [DellEMC S5232f] Updates and bug fixes for platform (#5887) * Fix platform sensors * Fix issues reported in fpga driver * Update fixes for API 2.0 platform code --- .../pmon_daemon_control.json | 3 +- .../s5232f/modules/dell_s5232f_fpga_ocores.c | 114 +----------------- .../s5232f/scripts/platform_sensors.py | 8 +- .../s5232f/scripts/s5232f_platform.sh | 45 +++++-- .../s5232f/sonic_platform/__init__.py | 3 +- .../s5232f/sonic_platform/chassis.py | 78 +++++++++--- .../s5232f/sonic_platform/component.py | 2 +- .../s5232f/sonic_platform/eeprom.py | 7 +- .../s5232f/sonic_platform/fan.py | 26 ++-- .../s5232f/sonic_platform/fan_drawer.py | 37 ++++++ .../s5232f/sonic_platform/thermal.py | 17 ++- 11 files changed, 174 insertions(+), 166 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan_drawer.py diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json index 44871c057e82..e15132a189b1 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json @@ -1,4 +1,3 @@ { - "skip_ledd": true, - "skip_thermalctld": true + "skip_ledd": true } diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c index c50d07a05a53..1565d4f5c645 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c @@ -89,7 +89,6 @@ struct fpgapci_dev { unsigned int irq_first; unsigned int irq_length; unsigned int irq_assigned; - unsigned int xcvr_intr_count; }; static int use_irq = 1; @@ -227,13 +226,6 @@ enum { #define I2C_PCI_BUS_NUM_12 12 #define I2C_PCI_BUS_NUM_16 16 -#define IRQ_LTCH_STS 0x20 -#define PRSNT_LTCH_STS 0x10 - -#define PORT_CTRL_OFFSET 0x4000 -#define PORT_STS_OFFSET 0x4004 -#define PORT_IRQ_STS_OFFSET 0x4008 -#define PORT_IRQ_EN_OFFSET 0x400C #define MB_BRD_REV_TYPE 0x0008 #define MB_BRD_REV_MASK 0x00f0 #define MB_BRD_REV_00 0x0000 @@ -292,8 +284,6 @@ enum { #define MSI_VECTOR_REV_00 16 #define MSI_VECTOR_REV_01 32 -#define FPGA_MSI_VECTOR_ID_4 4 -#define FPGA_MSI_VECTOR_ID_5 5 #define FPGA_MSI_VECTOR_ID_8 8 #define FPGA_MSI_VECTOR_ID_9 9 #define FPGA_MSI_VECTOR_ID_10 10 @@ -516,72 +506,6 @@ static int fpgai2c_poll(struct fpgalogic_i2c *i2c) return 0; } -static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, char *buf) -{ - int ind = 0, port_status=0, port_irq_status=0; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); - PRINT("%s:xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); - for(ind=0;ind<64;ind++) - { - port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); - PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - } - return sprintf(buf,"0x%04x\n",fpgapci->xcvr_intr_count); -} -static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL); - -static struct attribute *port_attrs[] = { - &dev_attr_port_msi.attr, - NULL, -}; - -static struct attribute_group port_attr_grp = { - .attrs = port_attrs, -}; - - -static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) -{ - struct pci_dev *pdev = dev; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); - int ind = 0, port_status=0, port_irq_status=0; - for(ind=0;ind<32;ind++) - { - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); - if(port_irq_status&(IRQ_LTCH_STS|PRSNT_LTCH_STS)) - { - PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - //write on clear - iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); - } - } - fpgapci->xcvr_intr_count++; - PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); - sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); - return IRQ_HANDLED; -} - -static irqreturn_t fpgaport_33_64_isr(int irq, void *dev) -{ - struct pci_dev *pdev = dev; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); - int ind = 0, port_status=0, port_irq_status=0; - for(ind=32;ind<64;ind++) - { - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); - if(port_irq_status| (IRQ_LTCH_STS|PRSNT_LTCH_STS)) - { - PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); - } - } - fpgapci->xcvr_intr_count++; - PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); - sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); - return IRQ_HANDLED; -} - static void fpgai2c_process(struct fpgalogic_i2c *i2c) { struct i2c_msg *msg = i2c->msg; @@ -806,12 +730,12 @@ static int fpgai2c_init(struct fpgalogic_i2c *i2c) fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); /* Init the device */ - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); if (!use_irq) fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); else fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); fpgai2c_dump(i2c); /* Initialize interrupt handlers if not already done */ @@ -906,7 +830,8 @@ static int i2c_pci_init (void) break; } } else { - printk("Wrong board_rev_type 0x%x\n", board_rev_type); + printk("unknown board_rev_type 0x%x\n", board_rev_type); + num_bus = I2C_PCI_BUS_NUM_8; } } @@ -1106,20 +1031,6 @@ static int register_intr_handler(struct pci_dev *dev, int irq_num_id) * alternatively function will be called from free_irq as well * with flag IRQF_SHARED */ switch(irq_num_id) { - /* Currently we only support test vector 2 for FPGA Logic I2C channel - * controller 1-7 interrupt*/ - case FPGA_MSI_VECTOR_ID_4: - err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_5: - err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; case FPGA_MSI_VECTOR_ID_8: err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[0]); @@ -1166,18 +1077,6 @@ static int register_intr_handler(struct pci_dev *dev, int irq_num_id) ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ switch (irq_num_id) { - case FPGA_MSI_VECTOR_ID_4: - err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_5: - err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; case FPGA_MSI_VECTOR_ID_8: err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[0]); @@ -1491,7 +1390,6 @@ static int fpgapci_configure_msi(struct fpgapci_dev *fpgapci,struct pci_dev *dev static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct fpgapci_dev *fpgapci = 0; - int status = 0; #ifdef TEST PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", @@ -1508,10 +1406,6 @@ static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) fpgapci->pci_dev = dev; dev_set_drvdata(&dev->dev, (void*)fpgapci); - status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); - if (status) { - printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); - } fpgapci->upstream = find_upstream_dev (dev); @@ -1519,7 +1413,9 @@ static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) goto error_no_device; } + printk("%s:MSI-irq disabled \n", __FUNCTION__); if (use_irq) { + printk("%s:MSI-irq enabled\n", __FUNCTION__); if(fpgapci_configure_msi(fpgapci,dev)) { goto error_cannot_configure; } diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py index 1d66afed642b..5db98374039d 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py @@ -13,7 +13,6 @@ import sys import logging -import subprocess S5232F_MAX_FAN_TRAYS = 4 S5232F_MAX_PSUS = 2 @@ -85,7 +84,7 @@ def get_psu_airflow(psu_id): if line.startswith('FRU Device Description') and fru_id in line.split(':')[1]: found_fru = True if found_fru and line.startswith(' Board Product '): - return ' B2F' if 'PS/IO' in line else ' F2B' + return 'Intake' if 'PS/IO' in line else 'Exhaust' return '' # Fetch FRU on given offset @@ -98,7 +97,7 @@ def fetch_raw_fru(dev_id, offset): def get_fan_airflow(fan_id): - Airflow_Direction = [' F2B', ' B2F'] + Airflow_Direction = ['Exhaust', 'Intake'] return Airflow_Direction[fetch_raw_fru(fan_id+2, 0x46)] # Print the information for temperature sensors @@ -119,6 +118,7 @@ def print_temperature_sensors(): print(' CPU Temp: ', get_pmc_register('CPU_temp')) +subprocess.getstatusoutput('echo 0 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us') ipmi_sensor_dump() print_temperature_sensors() @@ -329,3 +329,5 @@ def print_psu(psu): print('\n Total Power: ', get_pmc_register('PSU_Total_watt')) + +subprocess.getstatusoutput('echo 1000 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us') diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh index 867f44d7a828..cdb3412b7899 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh @@ -145,15 +145,6 @@ platform_firmware_versions() { r_maj=`/usr/sbin/i2cget -y 600 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` echo "Slave CPLD 2: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE - #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) - r_min=`/usr/sbin/i2cget -y 600 0x32 0x0 | sed ' s/.*\(0x..\)$/\1/'` - r_maj=`/usr/sbin/i2cget -y 600 0x32 0x1 | sed ' s/.*\(0x..\)$/\1/'` - echo "Slave CPLD 3: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE - - #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) - r_min=`/usr/sbin/i2cget -y 600 0x33 0x0 | sed ' s/.*\(0x..\)$/\1/'` - r_maj=`/usr/sbin/i2cget -y 600 0x33 0x1 | sed ' s/.*\(0x..\)$/\1/'` - echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE } install_python_api_package() { @@ -176,16 +167,47 @@ remove_python_api_package() { fi } +get_reboot_cause() { + REBOOT_REASON_FILE="/host/reboot-cause/platform/reboot_reason" + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + + mkdir -p $(dirname $REBOOT_REASON_FILE) + + # Handle First Boot into software version with reboot cause determination support + if [[ ! -e $REBOOT_REASON_FILE ]]; then + echo "0" > $REBOOT_REASON_FILE + else + /usr/bin/pcisysfs.py --get --offset 0x18 --res $resource | sed '1d; s/.*:\(.*\)$/\1/;' > $REBOOT_REASON_FILE + fi + /usr/bin/pcisysfs.py --set --val 0x0 --offset 0x18 --res $resource +} + +get_reboot_cause() { + REBOOT_REASON_FILE="/host/reboot-cause/platform/reboot_reason" + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + + mkdir -p $(dirname $REBOOT_REASON_FILE) + + # Handle First Boot into software version with reboot cause determination support + if [[ ! -e $REBOOT_REASON_FILE ]]; then + echo "0" > $REBOOT_REASON_FILE + else + /usr/bin/pcisysfs.py --get --offset 0x18 --res $resource | sed '1d; s/.*:\(.*\)$/\1/;' > $REBOOT_REASON_FILE + fi + /usr/bin/pcisysfs.py --set --val 0x0 --offset 0x18 --res $resource +} + init_devnum if [ "$1" == "init" ]; then modprobe i2c-dev modprobe i2c-mux-pca954x force_deselect_on_exit=1 modprobe ipmi_devintf - modprobe ipmi_si + modprobe ipmi_si kipmid_max_busy_us=1000 modprobe i2c_ocores modprobe dell_s5232f_fpga_ocores sys_eeprom "new_device" + get_reboot_cause switch_board_qsfp_mux "new_device" switch_board_qsfp "new_device" switch_board_sfp "new_device" @@ -194,6 +216,7 @@ if [ "$1" == "init" ]; then install_python_api_package /usr/bin/qsfp_irq_enable.py platform_firmware_versions + echo 1000 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" @@ -203,6 +226,8 @@ elif [ "$1" == "deinit" ]; then modprobe -r i2c-mux-pca954x modprobe -r i2c-dev remove_python_api_package + modprobe -r ipmi_devintf + modprobe -r ipmi_si else echo "s5232f_platform : Invalid option !" fi diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py index 8b137891791f..4f5d4f6e473d 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py @@ -1 +1,2 @@ - +__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal", "fan", "fan_drawer"] +from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py index 8b6c8e29c133..431b255dcd62 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py @@ -12,18 +12,19 @@ try: import sys + import time from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Eeprom from sonic_platform.component import Component from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal + from sonic_platform.fan_drawer import FanDrawer from sonic_platform.watchdog import Watchdog - from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") -MAX_S5232F_COMPONENT = 6 # BIOS,BMC,FPGA,SYSTEM CPLD,4 SLAVE CPLDs +MAX_S5232F_COMPONENT = 6 # BIOS,BMC,FPGA,SYSTEM CPLD,2 SLAVE CPLDs MAX_S5232F_FANTRAY =4 MAX_S5232F_FAN = 2 MAX_S5232F_PSU = 2 @@ -61,17 +62,20 @@ def __init__(self): self._eeprom = Eeprom() self._watchdog = Watchdog() + for i in range(MAX_S5232F_FANTRAY): + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) + self._num_sfps = self.PORT_END self._num_fans = MAX_S5232F_FANTRAY * MAX_S5232F_FAN - self._fan_list = [Fan(i, j) for i in range(MAX_S5232F_FANTRAY) \ - for j in range(MAX_S5232F_FAN)] self._psu_list = [Psu(i) for i in range(MAX_S5232F_PSU)] self._thermal_list = [Thermal(i) for i in range(MAX_S5232F_THERMAL)] self._component_list = [Component(i) for i in range(MAX_S5232F_COMPONENT)] for port_num in range(self.PORT_START, self.PORTS_IN_BLOCK): # sfp get uses zero-indexing, but port numbers start from 1 - presence = self.get_sfp(port_num).get_presence() + presence = self.get_sfp(port_num-1).get_presence() self._global_port_pres_dict[port_num] = '1' if presence else '0' def __del__(self): @@ -88,33 +92,30 @@ def get_change_event(self, timeout=0): Returns a nested dictionary containing all devices which have experienced a change at chassis level """ + start_ms = time.time() * 1000 port_dict = {} change_dict = {} change_dict['sfp'] = port_dict - elapsed_time_ms = 0 - sleep_time_ms = 500 - sleep_time = sleep_time_ms / 1000 - while True: + time.sleep(0.5) for port_num in range(self.PORT_START, (self.PORT_END + 1)): - presence = self.get_sfp(port_num).get_presence() + presence = self.get_sfp(port_num-1).get_presence() if(presence and self._global_port_pres_dict[port_num] == '0'): self._global_port_pres_dict[port_num] = '1' port_dict[port_num] = '1' elif(not presence and - self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] == '1'): self._global_port_pres_dict[port_num] = '0' port_dict[port_num] = '0' - if(len(port_dict) > 0): - return True, change_dict - if timeout != 0: - elapsed_time_ms += sleep_time_ms - if elapsed_time_ms > timeout: - break + if(len(port_dict) > 0): + return True, change_dict + + if timeout: + now_ms = time.time() * 1000 + if (now_ms - start_ms >= timeout): + return True, change_dict - sleep(sleep_time) - return True, change_dict def get_sfp(self, index): """ @@ -133,7 +134,7 @@ def get_sfp(self, index): try: # The index will start from 0 - sfp = self._sfp_list[index-1] + sfp = self._sfp_list[index] except IndexError: sys.stderr.write("SFP index {} out of range (0-{})\n".format( index, len(self._sfp_list)-1)) @@ -222,3 +223,40 @@ def get_num_sfps(self): An integer represences the number of SFPs on the chassis. """ return self._num_sfps + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + try: + with open(self.REBOOT_CAUSE_PATH) as fd: + reboot_cause = int(fd.read(), 16) + except EnvironmentError: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + + if reboot_cause & 0x1: + return (self.REBOOT_CAUSE_POWER_LOSS, None) + elif reboot_cause & 0x2: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + elif reboot_cause & 0x4: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "PSU Shutdown") + elif reboot_cause & 0x8: + return (self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, None) + elif reboot_cause & 0x10: + return (self.REBOOT_CAUSE_WATCHDOG, None) + elif reboot_cause & 0x20: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "BMC Shutdown") + elif reboot_cause & 0x40: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Hot-Swap Shutdown") + elif reboot_cause & 0x80: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Shutdown") + elif reboot_cause & 0x100: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Cold Reboot") + else: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py index 63bd29d2232e..f7fcc94662c1 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py @@ -77,7 +77,7 @@ class Component(ComponentBase): ['Slave CPLD 2', 'Used for managing SFP28/QSFP28 port transceivers (SFP28 25-48, QSFP28 5-8)', get_cpld2_version - ], + ] ] diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py index 98826cbc441c..4a567380f477 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py @@ -52,12 +52,7 @@ def __init__(self): + ord(eeprom[tlv_index + 1])] code = "0x%02X" % (ord(tlv[0])) - if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: - value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | - (ord(tlv[4]) << 8) | ord(tlv[5])) - value += str(tlv[6:6 + ord(tlv[1])]) - else: - name, value = self.decoder(None, tlv) + name, value = self.decoder(None, tlv) self.eeprom_tlv_dict[code] = value if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py index 7a098c8b0fbb..1b624cb76eda 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py @@ -24,16 +24,16 @@ class Fan(FanBase): """DellEMC Platform-specific Fan class""" # { FAN-ID: { Sensor-Name: Sensor-ID } } - FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x51, "State": 0x64, "Speed": 0x24}, - 2: {"Prsnt": 0x51, "State": 0x60, "Speed": 0x20}, - 3: {"Prsnt": 0x52, "State": 0x65, "Speed": 0x25}, - 4: {"Prsnt": 0x52, "State": 0x61, "Speed": 0x21}, - 5: {"Prsnt": 0x53, "State": 0x66, "Speed": 0x26}, - 6: {"Prsnt": 0x53, "State": 0x62, "Speed": 0x22}, - 7: {"Prsnt": 0x54, "State": 0x67, "Speed": 0x27}, - 8: {"Prsnt": 0x54, "State": 0x63, "Speed": 0x23} } - PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x46, "Speed": 0x2e}, - 2: {"State": 0x47, "Speed": 0x2f} } + FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x53, "State": 0x57, "Speed": 0x24}, + 2: {"Prsnt": 0x53, "State": 0x5b, "Speed": 0x20}, + 3: {"Prsnt": 0x54, "State": 0x58, "Speed": 0x25}, + 4: {"Prsnt": 0x54, "State": 0x5c, "Speed": 0x21}, + 5: {"Prsnt": 0x55, "State": 0x59, "Speed": 0x26}, + 6: {"Prsnt": 0x55, "State": 0x5d, "Speed": 0x22}, + 7: {"Prsnt": 0x56, "State": 0x5a, "Speed": 0x27}, + 8: {"Prsnt": 0x56, "State": 0x5e, "Speed": 0x23} } + PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x31, "Speed": 0x28}, + 2: {"State": 0x32, "Speed": 0x29} } # { FANTRAY-ID: FRU-ID } FAN_FRU_MAPPING = { 1: 3, 2: 4, 3: 5, 4: 6 } @@ -129,7 +129,7 @@ def get_status(self): status = False is_valid, state = self.state_sensor.get_reading() if is_valid: - if (state == 0x00): + if not state > 1: status = True return status @@ -146,11 +146,11 @@ def get_direction(self): - Reverse/Intake : Air flows from Fan side to Port side. """ direction = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE] - fan_status = self.get_status() + fan_status = self.get_presence() if not fan_status: return 'NA' is_valid, fan_direction = self.fru.get_fru_data(self.fan_direction_offset) - if is_valid: + if is_valid and fan_direction[0] < len(direction): return direction[fan_direction[0]] else: return 'NA' diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..c9888419fc5c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan_drawer.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +S5232F_FANS_PER_FANTRAY = 2 + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.fantrayindex = fantray_index + 1 + for i in range(S5232F_FANS_PER_FANTRAY): + self._fan_list.append(Fan(fantray_index, i)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py index 410bb4ca96bc..d8c4ef14d5b2 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py @@ -105,7 +105,7 @@ def get_high_threshold(self): Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - is_valid, high_threshold = self.sensor.get_threshold("UpperNonRecoverable") + is_valid, high_threshold = self.sensor.get_threshold("UpperCritical") if not is_valid: high_threshold = 0 @@ -126,6 +126,21 @@ def get_low_threshold(self): return float(low_threshold) + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + Returns: + A float number, the high critical threshold temperature of + thermal in Celsius up to nearest thousandth of one degree + Celsius, e.g. 30.125 + """ + is_valid, high_crit_threshold = self.sensor.get_threshold("UpperNonRecoverable") + if not is_valid: + high_crit_threshold = 0 + + return float(high_crit_threshold) + + def set_high_threshold(self, temperature): """ Sets the high threshold temperature of thermal From dbb6373e859c52aa885dee4e4ffb79b4bb8afd67 Mon Sep 17 00:00:00 2001 From: carl-nokia <63672637+carl-nokia@users.noreply.github.com> Date: Wed, 11 Nov 2020 18:11:00 -0500 Subject: [PATCH 1382/1427] [Marvell] Utilize eeprom for system mac and remove dependency on get_hwsku (#5882) Utilize eeprom for system mac and remove dependency on get_hwsku Co-authored-by: Carl Keene --- src/sonic-py-common/sonic_py_common/device_info.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index d25ccb7c1327..ef4b5453b40b 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -391,9 +391,14 @@ def get_system_mac(namespace=None): elif (version_info['asic_type'] == 'marvell'): # Try valid mac in eeprom, else fetch it from eth0 platform = get_platform() - hwsku = get_hwsku() - profile_cmd = 'cat' + HOST_DEVICE_PATH + '/' + platform +'/'+ hwsku +'/profile.ini | grep switchMacAddress | cut -f2 -d=' - hw_mac_entry_cmds = [ profile_cmd, "sudo decode-syseeprom -m", "ip link show eth0 | grep ether | awk '{print $2}'" ] + machine_key = "onie_machine" + machine_vars = get_machine_info() + if machine_vars is not None and machine_key in machine_vars: + hwsku = machine_vars[machine_key] + profile_cmd = 'cat' + HOST_DEVICE_PATH + '/' + platform + '/' + hwsku + '/profile.ini | grep switchMacAddress | cut -f2 -d=' + else: + profile_cmd = "false" + hw_mac_entry_cmds = ["sudo decode-syseeprom -m", profile_cmd, "ip link show eth0 | grep ether | awk '{print $2}'"] else: mac_address_cmd = "cat /sys/class/net/eth0/address" if namespace is not None: From 4342cb0cea9eb365cc0e2c21d5c9a4f5035e1166 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Thu, 12 Nov 2020 08:55:09 +0800 Subject: [PATCH 1383/1427] [submodule]: update sonic-linux-kernel (#5894) Pick up new kernel patches: - a28b399db609e9cab6748df28cf1482537f31560 [Mellanox] Add patches for i2c API - 18236531cb74d34fa5945d1c766a1a35b658569f [Mellanox] Add kernel patches with hw-mgmt V.7.0010.1300 - cb4712f97dbfb4b7a5f867034317e1aa3ac75b45 Improve `patch/kconfig-exclusions` --- src/sonic-linux-kernel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index af486c6ecdda..18236531cb74 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit af486c6ecdda8c6bde8b8d5b2cb89e8d27655355 +Subproject commit 18236531cb74d34fa5945d1c766a1a35b658569f From a98cf22162d7edbfdbe4753da7900e9d4279b441 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 11 Nov 2020 17:13:17 -0800 Subject: [PATCH 1384/1427] [submodule]: downgrade sonic-platform-daemons remove commit 850d0c6 2020-11-09 | [xcvrd] support for integrating Credo Y cable Ports initialization and status updates with xcvrd. (#105) (HEAD, origin/master, origin/HEAD) [vdahiya12] fix issue #5907 Signed-off-by: Guohan Lu --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 850d0c6f94ff..600d043afc47 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 850d0c6f94ffb644b58a51447599e85178626626 +Subproject commit 600d043afc4756f5965479a333bfcf91c31d655d From a704ded668b22cf9de03c5cab6901c51fdd827ae Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 11 Nov 2020 17:58:35 -0800 Subject: [PATCH 1385/1427] [sonic-utilities] Add Python 3 sonic-yang-mgmt package as a dependency (#5903) Add Python 3 sonic-yang-mgmt package as a dependency in sonic-utilities makefile. Recently updated the sonic-utilities Jenkins build environment [here](https://github.com/Azure/sonic-build-tools/pull/185) to begin running tests on the Python 3 version of the sonic-utilities package. However, the build is failing because it attempts to copy the Python 3 sonic-yang-mgmt package from the artifacts of the latest VS build, but the package does not exist because there are no targets which specify it as a dependency. This PR will ensure the Python 3 package is built during the image build process. --- rules/sonic-utilities.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index aef970200fb7..db796b189b40 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -15,6 +15,7 @@ $(SONIC_UTILITIES_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) \ $(SWSSSDK_PY2) \ $(SONIC_CONFIG_ENGINE_PY2) \ $(SONIC_YANG_MGMT_PY2) \ + $(SONIC_YANG_MGMT_PY3) \ $(SONIC_YANG_MODELS_PY3) $(SONIC_UTILITIES_PY2)_DEBS_DEPENDS = $(LIBYANG) \ $(LIBYANG_CPP) \ From 6c362a08e72e14da8880586f089d4860e786947c Mon Sep 17 00:00:00 2001 From: Sabareesh-Kumar-Anandan <59681634+Sabareesh-Kumar-Anandan@users.noreply.github.com> Date: Thu, 12 Nov 2020 07:49:48 +0530 Subject: [PATCH 1386/1427] [armhf][redis] compilation fixes for armhf arch (#5901) 1. Update SSL ca certificates for secure download [arm specific] 2. Using redis-tools from blob sonic-storage for docker-base-stretch Signed-off-by: Sabareesh Kumar Anandan --- build_debian.sh | 11 +++++------ dockers/docker-base-stretch/Dockerfile.j2 | 19 +++++++++++++++++-- sonic-slave-buster/Dockerfile.j2 | 3 +++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 2cea52e9e466..5c705bfe7e29 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -31,12 +31,7 @@ set -x -e CONFIGURED_ARCH=$([ -f .arch ] && cat .arch || echo amd64) ## docker engine version (with platform) -if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then - # Version name differs between ARCH, copying same version as in sonic-slave docker - DOCKER_VERSION=18.06.3~ce~3-0~debian -else - DOCKER_VERSION=5:18.09.8~3-0~debian-$IMAGE_DISTRO -fi +DOCKER_VERSION=5:18.09.8~3-0~debian-$IMAGE_DISTRO LINUX_KERNEL_VERSION=4.19.0-9-2 ## Working directory to prepare the file system @@ -202,6 +197,10 @@ sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install apt-transport-https \ curl \ gnupg2 \ software-properties-common +if [[ $CONFIGURED_ARCH == armhf ]]; then + # update ssl ca certificates for secure pem + sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT c_rehash +fi sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -o /tmp/docker.gpg -fsSL https://download.docker.com/linux/debian/gpg sudo LANG=C chroot $FILESYSTEM_ROOT apt-key add /tmp/docker.gpg sudo LANG=C chroot $FILESYSTEM_ROOT rm /tmp/docker.gpg diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 79f5c90660af..2299b8bba656 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -40,6 +40,7 @@ COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] # pre-install fundamental packages RUN apt-get update && \ apt-get -y install \ + curl \ less \ perl \ procps \ @@ -49,8 +50,6 @@ RUN apt-get update && \ # Install dependencies of supervisor python-pkg-resources \ python-meld3 \ -# Install redis-tools - redis-tools=5:5.0.3-3~bpo9+2 \ # common dependencies libpython2.7 \ libdaemon0 \ @@ -70,6 +69,22 @@ RUN apt-get update && \ # Install a newer version of rsyslog from stretch-backports to support -iNONE RUN apt-get -y -t stretch-backports install rsyslog +# Install redis-tools + +{% if CONFIGURED_ARCH == "armhf" %} + RUN curl -o redis-tools_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=67vHAMxsl%2BS3X1KsqhdYhakJkGdg5FKSPgU8kUiw4as%3D&se=2030-10-24T04%3A22%3A40Z&sp=r" + RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_armhf.deb || apt-get install -f -y + RUN rm redis-tools_6.0.6-1~bpo10+1_armhf.deb +{% elif CONFIGURED_ARCH == "arm64" %} + RUN curl -o redis-tools_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=GbkJV2wWln3hoz27zKi5erdk3NDKrAFrQriA97bcRCY%3D&se=2030-10-24T04%3A22%3A21Z&sp=r" + RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_arm64.deb || apt-get install -f -y + RUN rm redis-tools_6.0.6-1~bpo10+1_arm64.deb +{% else %} + RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" + RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f -y + RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb +{% endif %} + # For templating RUN pip install j2cli diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 18f7405bc700..101008fa4aac 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -426,6 +426,9 @@ RUN apt-get install -y \ curl \ gnupg2 \ software-properties-common +{%- if CONFIGURED_ARCH == "armhf" %} + RUN update-ca-certificates --fresh +{%- endif %} RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - RUN add-apt-repository \ "deb [arch={{ CONFIGURED_ARCH }}] https://download.docker.com/linux/debian \ From ae69fdf312be87be7cd8d86be8f4990930855990 Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Thu, 12 Nov 2020 09:03:59 -0800 Subject: [PATCH 1387/1427] [buffers_config.j2]: Use correct cable lengths for backend devices (#5905) * Remove 'backend' from device type strings so that backend devices ('BackEndToRRouter' and 'BackEndLeafRouter') are given the same cable lengths as regular device types. Signed-off-by: Lawrence Lee --- files/build_templates/buffers_config.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index f5dbb9784f64..c741c6ea364e 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -57,6 +57,8 @@ def {%- set roles2 = neighbor_role + '_' + switch_role %} {%- set roles1 = roles1 | lower %} {%- set roles2 = roles2 | lower %} + {%- set roles1 = roles1.replace('backend', '') %} + {%- set roles2 = roles2.replace('backend', '') %} {%- endif %} {%- if roles1 in ports2cable %} {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} @@ -74,6 +76,7 @@ def {%- if local_port[1] == port_name %} {%- set roles3 = switch_role + '_' + 'server' %} {%- set roles3 = roles3 | lower %} + {%- set roles3 = roles3.replace('backend', '') %} {%- if roles3 in ports2cable %} {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} {%- endif %} From 8d8ed8977896f016a6de802d310a193f72165925 Mon Sep 17 00:00:00 2001 From: Garrick He <32883830+GarrickHe@users.noreply.github.com> Date: Thu, 12 Nov 2020 10:00:22 -0800 Subject: [PATCH 1388/1427] [sflow] Add mVRF support (#5904) * Bump hsFlowD version to 2.0.28-02 to support mVRF Signed-off-by: Garrick He --- rules/sflow.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/sflow.mk b/rules/sflow.mk index 39054bad61c2..f41bde774f02 100644 --- a/rules/sflow.mk +++ b/rules/sflow.mk @@ -1,7 +1,7 @@ # host-sflow package -HSFLOWD_VERSION = 2.0.26 -HSFLOWD_SUBVERSION = 4 +HSFLOWD_VERSION = 2.0.28 +HSFLOWD_SUBVERSION = 2 export HSFLOWD_VERSION HSFLOWD_SUBVERSION HSFLOWD = hsflowd_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb From a3dd3f55f9163e80d5f10a4dd0d33fe66464e581 Mon Sep 17 00:00:00 2001 From: fk410167 <51665572+fk410167@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:52:38 +0530 Subject: [PATCH 1389/1427] Platform Driver Developement Framework (PDDF) (#4756) This change introduces PDDF which is described here: https://github.com/Azure/SONiC/pull/536 Most of the platform bring up effort goes in developing the platform device drivers, SONiC platform APIs and validating them. Typically each platform vendor writes their own drivers and platform APIs which is very tailor made to that platform. This involves writing code, building, installing it on the target platform devices and testing. Many of the details of the platform are hard coded into these drivers, from the HW spec. They go through this cycle repetitively till everything works fine, and is validated before upstreaming the code. PDDF aims to make this platform driver and platform APIs development process much simpler by providing a data driven development framework. This is enabled by: JSON descriptor files for platform data Generic data-driven drivers for various devices Generic SONiC platform APIs Vendor specific extensions for customisation and extensibility Signed-off-by: Fuzail Khan --- build_debian.sh | 1 + device/common/pddf/plugins/eeprom.py | 27 + device/common/pddf/plugins/fanutil.py | 202 ++ device/common/pddf/plugins/ledutil.py | 58 + device/common/pddf/plugins/psuutil.py | 272 +++ device/common/pddf/plugins/sfputil.py | 237 ++ device/common/pddf/plugins/sysstatutil.py | 85 + device/common/pddf/plugins/thermalutil.py | 74 + dockers/docker-platform-monitor/Dockerfile.j2 | 3 +- .../build_templates/sonic_debian_extension.j2 | 8 + platform/broadcom/one-image.mk | 1 + platform/pddf/README.md | 19 + platform/pddf/i2c/Makefile | 1 + platform/pddf/i2c/debian/changelog | 12 + platform/pddf/i2c/debian/compat | 1 + platform/pddf/i2c/debian/control | 12 + platform/pddf/i2c/debian/rules | 75 + platform/pddf/i2c/modules/Makefile | 1 + platform/pddf/i2c/modules/client/Makefile | 3 + .../i2c/modules/client/pddf_client_module.c | 330 +++ platform/pddf/i2c/modules/cpld/Makefile | 4 + .../pddf/i2c/modules/cpld/driver/Makefile | 5 + .../modules/cpld/driver/pddf_cpld_driver.c | 230 ++ .../pddf/i2c/modules/cpld/pddf_cpld_module.c | 219 ++ platform/pddf/i2c/modules/cpldmux/Makefile | 4 + .../pddf/i2c/modules/cpldmux/driver/Makefile | 4 + .../cpldmux/driver/pddf_cpldmux_driver.c | 209 ++ .../i2c/modules/cpldmux/pddf_cpldmux_module.c | 254 +++ platform/pddf/i2c/modules/fan/Makefile | 4 + platform/pddf/i2c/modules/fan/driver/Makefile | 6 + .../i2c/modules/fan/driver/pddf_fan_api.c | 526 +++++ .../i2c/modules/fan/driver/pddf_fan_driver.c | 496 +++++ .../pddf/i2c/modules/fan/pddf_fan_module.c | 280 +++ platform/pddf/i2c/modules/gpio/Makefile | 4 + .../pddf/i2c/modules/gpio/pddf_gpio_module.c | 223 ++ .../i2c/modules/include/pddf_client_defs.h | 135 ++ .../pddf/i2c/modules/include/pddf_cpld_defs.h | 31 + .../i2c/modules/include/pddf_cpldmux_defs.h | 76 + .../pddf/i2c/modules/include/pddf_fan_api.h | 37 + .../pddf/i2c/modules/include/pddf_fan_defs.h | 91 + .../i2c/modules/include/pddf_fan_driver.h | 107 + .../pddf/i2c/modules/include/pddf_gpio_defs.h | 30 + .../pddf/i2c/modules/include/pddf_led_defs.h | 120 + .../pddf/i2c/modules/include/pddf_mux_defs.h | 31 + .../pddf/i2c/modules/include/pddf_psu_api.h | 41 + .../pddf/i2c/modules/include/pddf_psu_defs.h | 90 + .../i2c/modules/include/pddf_psu_driver.h | 65 + .../i2c/modules/include/pddf_sysstatus_defs.h | 51 + .../pddf/i2c/modules/include/pddf_xcvr_api.h | 44 + .../pddf/i2c/modules/include/pddf_xcvr_defs.h | 121 + platform/pddf/i2c/modules/led/Makefile | 4 + .../pddf/i2c/modules/led/pddf_led_module.c | 659 ++++++ platform/pddf/i2c/modules/mux/Makefile | 4 + .../pddf/i2c/modules/mux/pddf_mux_module.c | 211 ++ platform/pddf/i2c/modules/psu/Makefile | 4 + platform/pddf/i2c/modules/psu/driver/Makefile | 6 + .../i2c/modules/psu/driver/pddf_psu_api.c | 707 ++++++ .../i2c/modules/psu/driver/pddf_psu_driver.c | 381 ++++ .../pddf/i2c/modules/psu/pddf_psu_module.c | 283 +++ platform/pddf/i2c/modules/sysstatus/Makefile | 4 + .../modules/sysstatus/pddf_sysstatus_module.c | 235 ++ platform/pddf/i2c/modules/xcvr/Makefile | 4 + .../pddf/i2c/modules/xcvr/driver/Makefile | 7 + .../i2c/modules/xcvr/driver/pddf_xcvr_api.c | 909 ++++++++ .../modules/xcvr/driver/pddf_xcvr_driver.c | 296 +++ .../pddf/i2c/modules/xcvr/pddf_xcvr_module.c | 275 +++ .../i2c/service/pddf-platform-init.service | 13 + platform/pddf/i2c/setup.py | 14 + platform/pddf/i2c/utils/pddf_util.py | 605 +++++ platform/pddf/i2c/utils/pddfparse.py | 1949 +++++++++++++++++ platform/pddf/i2c/utils/schema/CPLD.schema | 67 + platform/pddf/i2c/utils/schema/CPU.schema | 80 + platform/pddf/i2c/utils/schema/EEPROM.schema | 93 + platform/pddf/i2c/utils/schema/FAN.schema | 113 + platform/pddf/i2c/utils/schema/FAN_BMC.schema | 69 + platform/pddf/i2c/utils/schema/LED.schema | 120 + platform/pddf/i2c/utils/schema/MUX.schema | 97 + .../pddf/i2c/utils/schema/PSU-PMBUS.schema | 109 + platform/pddf/i2c/utils/schema/PSU.schema | 81 + platform/pddf/i2c/utils/schema/PSU_BMC.schema | 336 +++ platform/pddf/i2c/utils/schema/QSFP.schema | 92 + platform/pddf/i2c/utils/schema/SMBUS.schema | 128 ++ platform/pddf/i2c/utils/schema/SYSSTAT.schema | 285 +++ .../pddf/i2c/utils/schema/TEMP_SENSOR.schema | 102 + .../i2c/utils/schema/TEMP_SENSOR_BMC.schema | 143 ++ platform/pddf/platform-api-pddf-base.dep | 9 + platform/pddf/platform-api-pddf-base.mk | 15 + platform/pddf/platform-api-pddf-base/setup.py | 30 + .../sonic_platform_pddf_base/__init__.py | 0 .../sonic_platform_pddf_base/pddf_chassis.py | 516 +++++ .../sonic_platform_pddf_base/pddf_eeprom.py | 124 ++ .../sonic_platform_pddf_base/pddf_fan.py | 332 +++ .../sonic_platform_pddf_base/pddf_platform.py | 37 + .../sonic_platform_pddf_base/pddf_psu.py | 298 +++ .../sonic_platform_pddf_base/pddf_sfp.py | 1390 ++++++++++++ .../sonic_platform_pddf_base/pddf_thermal.py | 174 ++ .../sonic_platform_pddf_base/pddfparse.py | 1508 +++++++++++++ .../sonic_platform_ref/__init__.py | 7 + .../sonic_platform_ref/chassis.py | 22 + .../sonic_platform_ref/eeprom.py | 14 + .../sonic_platform_ref/fan.py | 17 + .../sonic_platform_ref/platform.py | 25 + .../sonic_platform_ref/psu.py | 16 + .../sonic_platform_ref/sfp.py | 17 + .../sonic_platform_ref/thermal.py | 17 + platform/pddf/platform-modules-pddf.dep | 10 + platform/pddf/platform-modules-pddf.mk | 12 + platform/pddf/rules.dep | 3 + platform/pddf/rules.mk | 3 + rules/config | 4 + rules/docker-platform-monitor.mk | 4 + slave.mk | 16 + 112 files changed, 18064 insertions(+), 1 deletion(-) create mode 100755 device/common/pddf/plugins/eeprom.py create mode 100755 device/common/pddf/plugins/fanutil.py create mode 100755 device/common/pddf/plugins/ledutil.py create mode 100755 device/common/pddf/plugins/psuutil.py create mode 100755 device/common/pddf/plugins/sfputil.py create mode 100755 device/common/pddf/plugins/sysstatutil.py create mode 100755 device/common/pddf/plugins/thermalutil.py create mode 100644 platform/pddf/README.md create mode 100644 platform/pddf/i2c/Makefile create mode 100755 platform/pddf/i2c/debian/changelog create mode 100644 platform/pddf/i2c/debian/compat create mode 100755 platform/pddf/i2c/debian/control create mode 100755 platform/pddf/i2c/debian/rules create mode 100644 platform/pddf/i2c/modules/Makefile create mode 100644 platform/pddf/i2c/modules/client/Makefile create mode 100644 platform/pddf/i2c/modules/client/pddf_client_module.c create mode 100644 platform/pddf/i2c/modules/cpld/Makefile create mode 100644 platform/pddf/i2c/modules/cpld/driver/Makefile create mode 100755 platform/pddf/i2c/modules/cpld/driver/pddf_cpld_driver.c create mode 100644 platform/pddf/i2c/modules/cpld/pddf_cpld_module.c create mode 100644 platform/pddf/i2c/modules/cpldmux/Makefile create mode 100644 platform/pddf/i2c/modules/cpldmux/driver/Makefile create mode 100755 platform/pddf/i2c/modules/cpldmux/driver/pddf_cpldmux_driver.c create mode 100644 platform/pddf/i2c/modules/cpldmux/pddf_cpldmux_module.c create mode 100644 platform/pddf/i2c/modules/fan/Makefile create mode 100644 platform/pddf/i2c/modules/fan/driver/Makefile create mode 100644 platform/pddf/i2c/modules/fan/driver/pddf_fan_api.c create mode 100644 platform/pddf/i2c/modules/fan/driver/pddf_fan_driver.c create mode 100644 platform/pddf/i2c/modules/fan/pddf_fan_module.c create mode 100644 platform/pddf/i2c/modules/gpio/Makefile create mode 100644 platform/pddf/i2c/modules/gpio/pddf_gpio_module.c create mode 100644 platform/pddf/i2c/modules/include/pddf_client_defs.h create mode 100644 platform/pddf/i2c/modules/include/pddf_cpld_defs.h create mode 100644 platform/pddf/i2c/modules/include/pddf_cpldmux_defs.h create mode 100644 platform/pddf/i2c/modules/include/pddf_fan_api.h create mode 100644 platform/pddf/i2c/modules/include/pddf_fan_defs.h create mode 100644 platform/pddf/i2c/modules/include/pddf_fan_driver.h create mode 100644 platform/pddf/i2c/modules/include/pddf_gpio_defs.h create mode 100644 platform/pddf/i2c/modules/include/pddf_led_defs.h create mode 100644 platform/pddf/i2c/modules/include/pddf_mux_defs.h create mode 100644 platform/pddf/i2c/modules/include/pddf_psu_api.h create mode 100644 platform/pddf/i2c/modules/include/pddf_psu_defs.h create mode 100644 platform/pddf/i2c/modules/include/pddf_psu_driver.h create mode 100644 platform/pddf/i2c/modules/include/pddf_sysstatus_defs.h create mode 100644 platform/pddf/i2c/modules/include/pddf_xcvr_api.h create mode 100644 platform/pddf/i2c/modules/include/pddf_xcvr_defs.h create mode 100644 platform/pddf/i2c/modules/led/Makefile create mode 100644 platform/pddf/i2c/modules/led/pddf_led_module.c create mode 100644 platform/pddf/i2c/modules/mux/Makefile create mode 100644 platform/pddf/i2c/modules/mux/pddf_mux_module.c create mode 100644 platform/pddf/i2c/modules/psu/Makefile create mode 100644 platform/pddf/i2c/modules/psu/driver/Makefile create mode 100644 platform/pddf/i2c/modules/psu/driver/pddf_psu_api.c create mode 100644 platform/pddf/i2c/modules/psu/driver/pddf_psu_driver.c create mode 100644 platform/pddf/i2c/modules/psu/pddf_psu_module.c create mode 100644 platform/pddf/i2c/modules/sysstatus/Makefile create mode 100644 platform/pddf/i2c/modules/sysstatus/pddf_sysstatus_module.c create mode 100644 platform/pddf/i2c/modules/xcvr/Makefile create mode 100644 platform/pddf/i2c/modules/xcvr/driver/Makefile create mode 100644 platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_api.c create mode 100644 platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_driver.c create mode 100644 platform/pddf/i2c/modules/xcvr/pddf_xcvr_module.c create mode 100644 platform/pddf/i2c/service/pddf-platform-init.service create mode 100755 platform/pddf/i2c/setup.py create mode 100755 platform/pddf/i2c/utils/pddf_util.py create mode 100755 platform/pddf/i2c/utils/pddfparse.py create mode 100644 platform/pddf/i2c/utils/schema/CPLD.schema create mode 100644 platform/pddf/i2c/utils/schema/CPU.schema create mode 100644 platform/pddf/i2c/utils/schema/EEPROM.schema create mode 100644 platform/pddf/i2c/utils/schema/FAN.schema create mode 100644 platform/pddf/i2c/utils/schema/FAN_BMC.schema create mode 100644 platform/pddf/i2c/utils/schema/LED.schema create mode 100644 platform/pddf/i2c/utils/schema/MUX.schema create mode 100644 platform/pddf/i2c/utils/schema/PSU-PMBUS.schema create mode 100644 platform/pddf/i2c/utils/schema/PSU.schema create mode 100644 platform/pddf/i2c/utils/schema/PSU_BMC.schema create mode 100644 platform/pddf/i2c/utils/schema/QSFP.schema create mode 100644 platform/pddf/i2c/utils/schema/SMBUS.schema create mode 100644 platform/pddf/i2c/utils/schema/SYSSTAT.schema create mode 100644 platform/pddf/i2c/utils/schema/TEMP_SENSOR.schema create mode 100644 platform/pddf/i2c/utils/schema/TEMP_SENSOR_BMC.schema create mode 100644 platform/pddf/platform-api-pddf-base.dep create mode 100644 platform/pddf/platform-api-pddf-base.mk create mode 100755 platform/pddf/platform-api-pddf-base/setup.py create mode 100644 platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/__init__.py create mode 100755 platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_chassis.py create mode 100644 platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_eeprom.py create mode 100755 platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_fan.py create mode 100755 platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_platform.py create mode 100755 platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_psu.py create mode 100755 platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_sfp.py create mode 100755 platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_thermal.py create mode 100755 platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddfparse.py create mode 100644 platform/pddf/platform-api-pddf-base/sonic_platform_ref/__init__.py create mode 100644 platform/pddf/platform-api-pddf-base/sonic_platform_ref/chassis.py create mode 100644 platform/pddf/platform-api-pddf-base/sonic_platform_ref/eeprom.py create mode 100644 platform/pddf/platform-api-pddf-base/sonic_platform_ref/fan.py create mode 100644 platform/pddf/platform-api-pddf-base/sonic_platform_ref/platform.py create mode 100644 platform/pddf/platform-api-pddf-base/sonic_platform_ref/psu.py create mode 100644 platform/pddf/platform-api-pddf-base/sonic_platform_ref/sfp.py create mode 100644 platform/pddf/platform-api-pddf-base/sonic_platform_ref/thermal.py create mode 100644 platform/pddf/platform-modules-pddf.dep create mode 100644 platform/pddf/platform-modules-pddf.mk create mode 100644 platform/pddf/rules.dep create mode 100644 platform/pddf/rules.mk diff --git a/build_debian.sh b/build_debian.sh index 5c705bfe7e29..08a4030cb475 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -277,6 +277,7 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in python \ python-setuptools \ python3-setuptools \ + python-jsonschema \ python-apt \ traceroute \ iputils-ping \ diff --git a/device/common/pddf/plugins/eeprom.py b/device/common/pddf/plugins/eeprom.py new file mode 100755 index 000000000000..7671c50bd345 --- /dev/null +++ b/device/common/pddf/plugins/eeprom.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +try: + import os + import sys + import json + sys.path.append('/usr/share/sonic/platform/plugins') + import pddfparse + #from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + # system EEPROM always has device name EEPROM1 + self.eeprom_path = pddf_obj.get_path("EEPROM1", "eeprom") + super(board, self).__init__(self.eeprom_path, 0, '', True) + diff --git a/device/common/pddf/plugins/fanutil.py b/device/common/pddf/plugins/fanutil.py new file mode 100755 index 000000000000..2701fa5f2326 --- /dev/null +++ b/device/common/pddf/plugins/fanutil.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python + + +# Sample pddf_fanutil file +# All the supported FAN SysFS aattributes are +#- fan_present +#- fan_direction +#- fan_input +#- fan_pwm +#- fan_fault +# where idx is in the range [1-12] +# + + +import os.path +import sys +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse +import json + +try: + from sonic_fan.fan_base import FanBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class FanUtil(FanBase): + """PDDF generic FAN util class""" + + def __init__(self): + FanBase.__init__(self) + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + self.platform = pddf_obj.get_platform() + + self.num_fans = (self.platform['num_fantrays'] * self.platform['num_fans_pertray'] ) + + def get_num_fans(self): + return self.num_fans + + def get_presence(self, idx): + # 1 based fan index + if idx<1 or idx>self.num_fans: + print "Invalid fan index %d\n"%idx + return False + + attr_name = "fan"+ str(idx) +"_present" + output = pddf_obj.get_attr_name_output("FAN-CTRL", attr_name) + if not output: + return False + + mode = output['mode'] + presence = output['status'].rstrip() + + vmap = plugin_data['FAN']['present'][mode]['valmap'] + + if presence in vmap: + status = vmap[presence] + else: + status = False + + return status + + def get_status(self, idx): + # 1 based fan index + if idx<1 or idx>self.num_fans: + print "Invalid fan index %d\n"%idx + return False + + speed = self.get_speed(idx) + status = True if (speed != 0) else False + return status + + def get_direction(self, idx): + # 1 based fan index + if idx<1 or idx>self.num_fans: + print "Invalid fan index %d\n"%idx + return None + + attr = "fan" + str(idx) + "_direction" + output = pddf_obj.get_attr_name_output("FAN-CTRL", attr) + if not output: + return None + + mode = output['mode'] + val = output['status'] + + val = val.rstrip() + vmap = plugin_data['FAN']['direction'][mode]['valmap'] + + + if val in vmap: + direction = vmap[val] + else: + direction = val + + return direction + + def get_directions(self): + num_fan = self.get_num_fan(); + + for i in range(1, num_fan+1): + attr = "fan" + str(i) + "_direction" + output = pddf_obj.get_attr_name_output("FAN-CTRL", attr) + if not output: + return None + + mode = output['mode'] + val = output['status'] + + val = val.rstrip() + vmap = plugin_data['FAN']['direction'][mode]['valmap'] + + direction = vmap[str(val)] + + print "FAN-%d direction is %s"%(i, direction) + + return 0 + + def get_speed(self, idx): + # 1 based fan index + if idx<1 or idx>self.num_fans: + print "Invalid fan index %d\n"%idx + return 0 + + attr = "fan" + str(idx) + "_input" + output = pddf_obj.get_attr_name_output("FAN-CTRL", attr) + if not output: + return 0 + + #mode = output['mode'] + val = output['status'].rstrip() + + if val.isalpha(): + return 0 + else: + rpm_speed = int(float(val)) + + return rpm_speed + + def get_speeds(self): + num_fan = self.get_num_fan(); + ret = "FAN_INDEX\t\tRPM\n" + + for i in range(1, num_fan+1): + attr1 = "fan" + str(i) + "_input" + output = pddf_obj.get_attr_name_output("FAN-CTRL", attr1) + if not output: + return "" + + #mode = output['mode'] + val = output['status'].rstrip() + + if val.isalpha(): + frpm = 0 + else: + frpm = int(val) + + ret += "FAN-%d\t\t\t%d\n"%(i, frpm) + + return ret + + def set_speed(self, val): + if val<0 or val>100: + print "Error: Invalid speed %d. Please provide a valid speed percentage"%val + return False + + num_fan = self.num_fans + if 'duty_cycle_to_pwm' not in plugin_data['FAN']: + print "Setting fan speed is not allowed !" + return False + else: + duty_cycle_to_pwm = eval(plugin_data['FAN']['duty_cycle_to_pwm']) + pwm = duty_cycle_to_pwm(val) + print "New Speed: %d%% - PWM value to be set is %d\n"%(val,pwm) + + for i in range(1, num_fan+1): + attr = "fan" + str(i) + "_pwm" + node = pddf_obj.get_path("FAN-CTRL", attr) + if node is None: + return False + try: + with open(node, 'w') as f: + f.write(str(pwm)) + except IOError: + return False + + return True + + def dump_sysfs(self): + return pddf_obj.cli_dump_dsysfs('fan') + + def get_change_event(self): + """ + TODO: This function need to be implemented + when decide to support monitoring FAN(fand) + on this platform. + """ + raise NotImplementedError diff --git a/device/common/pddf/plugins/ledutil.py b/device/common/pddf/plugins/ledutil.py new file mode 100755 index 000000000000..adbfe9cc62e1 --- /dev/null +++ b/device/common/pddf/plugins/ledutil.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +import sys +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse + +class LedUtil: + color_map = { + "STATUS_LED_COLOR_GREEN" : "on", + "STATUS_LED_COLOR_RED" : "faulty", + "STATUS_LED_COLOR_OFF" : "off" + } + + def __init__(self): + global pddf_obj + pddf_obj = pddfparse.PddfParse() + self.path="pddf/devices/led" + self.cur_state_path="pddf/devices/led/cur_state" + + def set_status_led(self, led_device_name, color, color_state="SOLID"): + if (not led_device_name in pddf_obj.data.keys()): + status="ERROR: " + led_device_name + " is not configured" + return (status) + + if (not color in self.color_map.keys()): + status="ERROR: Invalid color" + return (status) + + index=pddf_obj.data[led_device_name]['dev_attr']['index'] + pddf_obj.create_attr('device_name', led_device_name, self.path) + pddf_obj.create_attr('index', index, self.path) + pddf_obj.create_attr('color', self.color_map[color], self.cur_state_path) + pddf_obj.create_attr('color_state', color_state, self.cur_state_path) + pddf_obj.create_attr('dev_ops', 'set_status', self.path) + return ("Executed") + + def get_status_led(self, led_device_name): + if (not led_device_name in pddf_obj.data.keys()): + status="ERROR: " + led_device_name + " is not configured" + return (status) + + index=pddf_obj.data[led_device_name]['dev_attr']['index'] + pddf_obj.create_attr('device_name', led_device_name, self.path) + pddf_obj.create_attr('index', index, self.path) + pddf_obj.create_attr('dev_ops', 'get_status', self.path) + color_f="/sys/kernel/" + self.cur_state_path +"/color" + color_state_f="/sys/kernel/" + self.cur_state_path +"/color_state" + + try: + with open(color_f, 'r') as f: + color = f.read().strip("\r\n") + with open(color_state_f, 'r') as f: + color_state = f.read().strip("\r\n") + except IOError: + status="ERROR :" + color_f + " open failed" + return (status) + status = "%s-%s:\t%s %s\n"%(led_device_name, index, color, color_state) + return (status) diff --git a/device/common/pddf/plugins/psuutil.py b/device/common/pddf/plugins/psuutil.py new file mode 100755 index 000000000000..01cf4b126ee1 --- /dev/null +++ b/device/common/pddf/plugins/psuutil.py @@ -0,0 +1,272 @@ +#!/usr/bin/env python +# +# Sample pddf_psuutil file +# +# All the supported PSU SysFS aattributes are +#- psu_present +#- psu_model_name +#- psu_power_good +#- psu_mfr_id +#- psu_serial_num +#- psu_fan_dir +#- psu_v_out +#- psu_i_out +#- psu_p_out +#- psu_fan1_speed_rpm +# + +import os.path +import sys +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse +import json + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """PDDF generic PSU util class""" + + def __init__(self): + PsuBase.__init__(self) + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + self.platform = pddf_obj.get_platform() + + def get_num_psus(self): + return int(self.platform['num_psus']) + + def get_psu_status(self, index): + if index is None: + return False + + device = "PSU" + "%d"%index + output = pddf_obj.get_attr_name_output(device, "psu_power_good") + if not output: + return False + + mode = output['mode'] + val = output['status'] + + val = val.rstrip() + vmap = plugin_data['PSU']['psu_power_good'][mode]['valmap'] + + if val in vmap: + return vmap[val] + else: + return False + + def get_psu_presence(self, index): + if index is None: + return False + + status = 0 + device = "PSU" + "%d"%index + output = pddf_obj.get_attr_name_output(device, "psu_present") + if not output: + return False + + mode = output['mode'] + status = output['status'] + + vmap = plugin_data['PSU']['psu_present'][mode]['valmap'] + + if status.rstrip('\n') in vmap: + return vmap[status.rstrip('\n')] + else: + return False + + def get_powergood_status(self, idx): + if idx is None: + return False + + if idx<1 or idx>self.platform['num_psus']: + print "Invalid index %d\n"%idx + return False + + device = "PSU"+"%d"%(idx) + output = pddf_obj.get_attr_name_output(device, "psu_power_good") + if not output: + return False + + mode = output['mode'] + status = output ['status'] + + vmap = plugin_data['PSU']['psu_power_good'][mode]['valmap'] + + if status.rstrip('\n') in vmap: + return vmap[status.rstrip('\n')] + else: + return False + + def get_model(self, idx): + if idx is None: + return None + + if idx<1 or idx>self.platform['num_psus']: + print "Invalid index %d\n"%idx + return None + + device = "PSU"+"%d"%(idx) + output = pddf_obj.get_attr_name_output(device, "psu_model_name") + if not output: + return None + + model = output['status'] + + # strip_non_ascii + stripped = (c for c in model if 0 < ord(c) < 127) + model = ''.join(stripped) + + return model.rstrip('\n') + + def get_mfr_id(self, idx): + if idx is None: + return None + + if idx<1 or idx>self.platform['num_psus']: + print "Invalid index %d\n"%idx + return None + + device = "PSU"+"%d"%(idx) + output = pddf_obj.get_attr_name_output(device, "psu_mfr_id") + if not output: + return None + + mfr = output['status'] + + return mfr.rstrip('\n') + + def get_serial(self, idx): + if idx is None: + return None + + if idx<1 or idx>self.platform['num_psus']: + print "Invalid index %d\n"%idx + return None + + device = "PSU"+"%d"%(idx) + output = pddf_obj.get_attr_name_output(device, "psu_serial_num") + if not output: + return None + + serial = output['status'] + + return serial.rstrip('\n') + + def get_direction(self, idx): + if idx is None: + return None + + if idx<1 or idx>self.platform['num_psus']: + print "Invalid index %d\n"%idx + return None + + device = "PSU"+"%d"%(idx) + output = pddf_obj.get_attr_name_output(device, "psu_fan_dir") + if not output: + return None + + mode = output['mode'] + direction = output['status'].rstrip('\n') + + vmap = plugin_data['PSU']['psu_fan_dir'][mode]['valmap'] + if direction in vmap: + airflow_dir_real = vmap[direction] + else: + airflow_dir_real = direction + + return airflow_dir_real + + def get_output_voltage(self, idx): + if idx is None: + return 0.0 + + if idx<1 or idx>self.platform['num_psus']: + print "Invalid index %d\n"%idx + return 0.0 + + device = "PSU"+"%d"%(idx) + output = pddf_obj.get_attr_name_output(device, "psu_v_out") + if not output: + return 0.0 + + v_out = output['status'] + + # value returned by the psu driver is in mV + return float(v_out)/1000 + + def get_output_current(self, idx): + if idx is None: + return 0.0 + + if idx<1 or idx>self.platform['num_psus']: + print "Invalid index %d\n"%idx + return 0.0 + + device = "PSU"+"%d"%(idx) + output = pddf_obj.get_attr_name_output(device, "psu_i_out") + if not output: + return 0.0 + + i_out = output['status'] + + # current in mA + return float(i_out)/1000 + + def get_output_power(self, idx): + if idx is None: + return 0.0 + + if idx<1 or idx>self.platform['num_psus']: + print "Invalid index %d\n"%idx + return 0.0 + + device = "PSU"+"%d"%(idx) + output = pddf_obj.get_attr_name_output(device, "psu_p_out") + if not output: + return 0.0 + + p_out = output['status'] + + # power is returned in micro watts + return float(p_out)/1000000 + + def get_fan_rpm(self, idx, fan_idx): + if idx is None or fan_idx is None: + return 0 + + if idx<1 or idx>self.platform['num_psus']: + print "Invalid index %d\n"%idx + return 0 + + + device = "PSU"+"%d"%(idx) + num_fans = pddf_obj.get_num_psu_fans(device) + + if fan_idx<1 or fan_idx>num_fans: + print "Invalid PSU-fan index %d\n"%fan_idx + return 0 + + output = pddf_obj.get_attr_name_output(device, "psu_fan"+str(fan_idx)+"_speed_rpm") + if not output: + return 0 + + #mode = output['mode'] + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + speed = int(output['status']) + + return speed + + def dump_sysfs(self): + return pddf_obj.cli_dump_dsysfs('psu') diff --git a/device/common/pddf/plugins/sfputil.py b/device/common/pddf/plugins/sfputil.py new file mode 100755 index 000000000000..394aff1c42be --- /dev/null +++ b/device/common/pddf/plugins/sfputil.py @@ -0,0 +1,237 @@ +#!/usr/bin/env python + +import os.path +import sys +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse +import json + +try: + import time + from ctypes import create_string_buffer + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class SfpUtil(SfpUtilBase): + """Platform generic PDDF SfpUtil class""" + + _port_to_eeprom_mapping = {} + _port_start = 0 + _port_end = 0 + _port_to_type_mapping = {} + _qsfp_ports = [] + _sfp_ports = [] + + def __init__(self): + SfpUtilBase.__init__(self) + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + self.platform = pddf_obj.get_platform() + self._port_start = 0 + self._port_end = self.get_num_ports() + + for port_num in range(self._port_start, self._port_end): + device = "PORT" + "%d"%(port_num+1) + port_eeprom_path = pddf_obj.get_path(device,"eeprom") + self._port_to_eeprom_mapping[port_num] = port_eeprom_path + port_type = pddf_obj.get_device_type(device) + self._port_to_type_mapping[port_num] = port_type + self.populate_port_type(port_num) + + def get_num_ports(self): + return int(self.platform['num_ports']) + + def is_valid_port(self, port_num): + if port_num < self._port_start or port_num > self._port_end: + return False + else: + return True + + def get_presence(self, port_num): + if port_num < self._port_start or port_num > self._port_end: + return False + + device = "PORT" + "%d"%(port_num+1) + output = pddf_obj.get_attr_name_output(device, 'xcvr_present') + if not output: + return False + + #mode = output['mode'] + modpres = output['status'].rstrip() + if 'XCVR' in plugin_data: + if 'xcvr_present' in plugin_data['XCVR']: + ptype = self._port_to_type_mapping[port_num] + vtype = 'valmap-'+ptype + if vtype in plugin_data['XCVR']['xcvr_present']: + vmap = plugin_data['XCVR']['xcvr_present'][vtype] + if modpres in vmap: + return vmap[modpres] + else: + return False + # if plugin_data doesn't specify anything regarding Transceivers + if modpres == '1': + return True + + return False + + def populate_port_type(self, port): + if self._port_to_type_mapping[port] == 'QSFP' or self._port_to_type_mapping[port] == 'QSFP28': + self._qsfp_ports.append(port) + elif self._port_to_type_mapping[port] == 'SFP' or self._port_to_type_mapping[port] == 'SFP28': + self._sfp_ports.append(port) + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return (self._port_end - 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + @property + def qsfp_ports(self): + return self._qsfp_ports + + def reset(self, port_num): + if port_num < self._port_start or port_num > self._port_end: + return False + + device = "PORT" + "%d"%(port_num+1) + port_ps = pddf_obj.get_path(device,"xcvr_reset") + if port_ps is None: + return False + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + try: + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + except IOError as e: + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + if not self.get_presence(port_num): + return False + + device = "PORT" + "%d"%(port_num+1) + output = pddf_obj.get_attr_name_output(device, 'xcvr_lpmode') + if not output: + if port_num not in self.qsfp_ports: + return False # Read from eeprom only for QSFP ports + try: + eeprom = None + eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") + # check for valid connector type + eeprom.seek(2) + ctype = eeprom.read(1) + if ctype in ['21','23']: + return False + + eeprom.seek(93) + lpmode = ord(eeprom.read(1)) + + if ((lpmode & 0x3) == 0x3): + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + else: + return False # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + else: + #mode = output['mode'] + status = int(output['status'].rstrip()) + + if status == 1: + return True + else: + return False + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + if not self.get_presence(port_num): + return False # Port is not present, unable to set the eeprom + + device = "PORT" + "%d"%(port_num+1) + port_ps = pddf_obj.get_path(device,"xcvr_lpmode") + if port_ps is None: + if port_num not in self.qsfp_ports: + return False # Write to eeprom only for QSFP ports + try: + eeprom = None + eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") + # check for valid connector type + eeprom.seek(2) + ctype = eeprom.read(1) + if ctype in ['21','23']: + return False + + # Fill in write buffer + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom.seek(93) + eeprom.write(buffer[0]) + return True + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + else: + try: + f = open(port_ps, 'w') + if lpmode: + f.write('1') + else: + f.write('0') + f.close() + return True + except IOError as e: + return False + + def get_transceiver_change_event(self): + """ + TODO: This function need to be implemented + when decide to support monitoring SFP(Xcvrd) + on this platform. + """ + raise NotImplementedError + + + def dump_sysfs(self): + return pddf_obj.cli_dump_dsysfs('xcvr') diff --git a/device/common/pddf/plugins/sysstatutil.py b/device/common/pddf/plugins/sysstatutil.py new file mode 100755 index 000000000000..e8b3e8008652 --- /dev/null +++ b/device/common/pddf/plugins/sysstatutil.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python + +import os.path +import sys +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse +import json + +class SYSStatusUtil(): + """Platform-specific SYSStatus class""" + def __init__(self): + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + + def get_board_info(self): + device = "SYSSTATUS" + node = pddf_obj.get_path(device,"board_info") + if node is None: + return False + try: + with open(node, 'r') as f: + status = f.read() + print "board_info : %s" %status + except IOError: + return False + + def get_cpld_versio(self): + device = "SYSSTATUS" + node = pddf_obj.get_path(device,"cpld1_version") + if node is None: + return False + try: + with open(node, 'r') as f: + status = f.read() + print "cpld1_version : %s" %status + except IOError: + return False + + def get_power_module_status(self): + device = "SYSSTATUS" + node = pddf_obj.get_path(device,"power_module_status") + if node is None: + return False + try: + with open(node, 'r') as f: + status = f.read() + print "power_module_status : %s" %status + except IOError: + return False + + + def get_system_reset_status(self): + device = "SYSSTATUS" + for i in range(1,8): + node = pddf_obj.get_path(device,"system_reset"+str(i)) + if node is None: + return False + try: + with open(node, 'r') as f: + status = f.read() + print "system_reset%s : %s" %(i, status) + except IOError: + print "system_reset%s not supported" %i + + + def get_misc_status(self): + device = "SYSSTATUS" + for i in range(1,3): + node = pddf_obj.get_path(device,"misc"+str(i)) + if node is None: + return False + try: + with open(node, 'r') as f: + status = f.read() + print "misc%s : %s" %(i, status) + except IOError: + print "system_reset%s not supported" %i + + + def dump_sysfs(self): + return pddf_obj.cli_dump_dsysfs('sys-status') diff --git a/device/common/pddf/plugins/thermalutil.py b/device/common/pddf/plugins/thermalutil.py new file mode 100755 index 000000000000..ebf29608a46a --- /dev/null +++ b/device/common/pddf/plugins/thermalutil.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python + +import os.path +import sys +import json +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse + +class ThermalUtil: + def __init__(self): + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + self.platform = pddf_obj.get_platform() + self.num_thermals = self.platform['num_temps'] + self.info=[] + + def get_num_thermals(self): + return (self.num_thermals) + + def get_thermal_info(self): + list=[] + pddf_obj.get_device_list(list, "TEMP_SENSOR") + list.sort() + for dev in list: + data={} + device_name = dev['dev_info']['device_name'] + topo_info = dev['i2c']['topo_info'] + label="%s-i2c-%d-%x" % (topo_info['dev_type'], int(topo_info['parent_bus'], 0), int(topo_info['dev_addr'], 0)) + attr_list = dev['i2c']['attr_list'] + data['device_name']=device_name + data['label']=label + for attr in attr_list: + attr_name = attr['attr_name'] + node = pddf_obj.get_path(device_name, attr_name) + if node is None: + return False + try: + with open(node, 'r') as f: + attr_value = int(f.read()) + except IOError: + return False + data[attr_name] = attr_value/float(1000) + self.info.append(data) + + def show_thermal_temp_values(self, idx): + if idx<1 or idx>self.num_thermals: + print "Invalid temperature sensor idx %d"%idx + return None + self.get_thermal_info() + thermal_name = "TEMP"+"%d"%idx + label="" + value="" + for temp in self.info: + if thermal_name==temp['device_name']: + label = temp['label'] + value = "temp1\t %+.1f C (high = %+.1f C, hyst = %+.1f C)" % (temp['temp1_input'], temp['temp1_max'], temp['temp1_max_hyst']) + else: + continue + + return (label, value) + + def show_temp_values(self): + self.get_thermal_info() + for temp in self.info: + print temp['label'] + print "temp1\t %+.1f C (high = %+.1f C, hyst = %+.1f C)" % (temp['temp1_input'], temp['temp1_max'], temp['temp1_max_hyst']) + + + def dump_sysfs(self): + return pddf_obj.cli_dump_dsysfs('temp-sensors') diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index 0dd5b8fc75b5..7659ee4d35be 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -19,7 +19,8 @@ RUN apt-get update && \ python-smbus \ ethtool \ dmidecode \ - i2c-tools + i2c-tools \ + python-jsonschema # On Arista devices, the sonic_platform wheel is not installed in the container. # Instead, the installation directory is mounted from the host OS. However, this method diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 7b8299fda1aa..0fe1043fcb81 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -178,6 +178,14 @@ sudo cp {{platform_common_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $PLATFORM_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME +{% if pddf_support == "y" %} +# Install pddf-platform-api-base Python 2 package +PLATFORM_PDDF_COMMON_PY2_WHEEL_NAME=$(basename {{pddf_platform_api_base_py2_wheel_path}}) +sudo cp {{pddf_platform_api_base_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_PDDF_COMMON_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $PLATFORM_PDDF_COMMON_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_PDDF_COMMON_PY2_WHEEL_NAME +{% endif %} + # Install system-health Python 2 package SYSTEM_HEALTH_PY2_WHEEL_NAME=$(basename {{system_health_py2_wheel_path}}) sudo cp {{system_health_py2_wheel_path}} $FILESYSTEM_ROOT/$SYSTEM_HEALTH_PY2_WHEEL_NAME diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 538461b4dba3..f557f17c7cea 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -4,6 +4,7 @@ SONIC_ONE_IMAGE = sonic-broadcom.bin $(SONIC_ONE_IMAGE)_MACHINE = broadcom $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(BRCM_OPENNSL_KERNEL) +$(SONIC_ONE_IMAGE)_INSTALLS += $(PDDF_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(DELL_Z9264F_PLATFORM_MODULE) \ diff --git a/platform/pddf/README.md b/platform/pddf/README.md new file mode 100644 index 000000000000..b46bb6780b1e --- /dev/null +++ b/platform/pddf/README.md @@ -0,0 +1,19 @@ + Platform Driver Development Framework (PDDF) is part of SONiC Platform Development Kit (PDK) which optimizes the platform developement. + + SONiC PDDF (Platform driver development framework) supports the following HW devices on a given platform: + + - Fan + - PSU + - System EEPROM + - CPLD + - CPLDMUX + - GPIO + - Optic Transceivers + - System LED control via CPLD + - System Status Registers in CPLD + - Temp Sensors + + This folder for the PDDF consists of the following: + + - PDDF python utility scripts + - Generic PDDF HW device drivers in kernel space diff --git a/platform/pddf/i2c/Makefile b/platform/pddf/i2c/Makefile new file mode 100644 index 000000000000..1486370b5005 --- /dev/null +++ b/platform/pddf/i2c/Makefile @@ -0,0 +1 @@ +subdir-m := modules diff --git a/platform/pddf/i2c/debian/changelog b/platform/pddf/i2c/debian/changelog new file mode 100755 index 000000000000..505184c1fd80 --- /dev/null +++ b/platform/pddf/i2c/debian/changelog @@ -0,0 +1,12 @@ +sonic-pddf-platform-modules (1.1) unstable; urgency=low + + * Enhancing PDDF: Added support for cpldmux, gpio and some extra attributes + + -- Broadcom Wed, 10 Jun 2020 10:10:10 -0800 + +sonic-pddf-platform-modules (1.0) unstable; urgency=low + + * Basic tempelate for PDDF + * Initial release + + -- Broadcom Wed, 26 Jun 2019 10:10:10 -0800 diff --git a/platform/pddf/i2c/debian/compat b/platform/pddf/i2c/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/pddf/i2c/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/pddf/i2c/debian/control b/platform/pddf/i2c/debian/control new file mode 100755 index 000000000000..afd96c3d260a --- /dev/null +++ b/platform/pddf/i2c/debian/control @@ -0,0 +1,12 @@ +Source: sonic-pddf-platform-modules +Section: main +Priority: extra +Maintainer: Broadcom +Build-Depends: debhelper (>= 9), bzip2 +Standards-Version: 3.9.3 + +Package: sonic-platform-pddf +Architecture: amd64 +Description: kernel modules for platform devices such as psu, fan, sfp, led + + diff --git a/platform/pddf/i2c/debian/rules b/platform/pddf/i2c/debian/rules new file mode 100755 index 000000000000..35fca9a784ad --- /dev/null +++ b/platform/pddf/i2c/debian/rules @@ -0,0 +1,75 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. +include /usr/share/dpkg/pkg-info.mk + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +export INSTALL_MOD_DIR:=extra + +PYTHON ?= python2 + +PACKAGE_PRE_NAME := sonic-platform-pddf +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= client cpld cpld/driver cpldmux cpldmux/driver fan fan/driver fan/vendor_api mux gpio led psu psu/driver sysstatus xcvr xcvr/driver +MODULE_DIR:= modules +UTILS_DIR := utils +SERVICE_DIR := service + +%: + echo =================RUNNING $@============= + dh $@ --with systemd,python2,python3 --buildsystem=pybuild + +clean: + echo ============CLEANING================= + dh_testdir + dh_testroot + dh_clean + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR) clean + +build: + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR); \ + $(PYTHON) $(MOD_SRC_DIR)/setup.py build; \ + +binary: binary-arch binary-indep + # Nothing to do + +binary-arch: + # Nothing to do + +binary-indep: + dh_testdir + dh_installdirs + dh_installdirs -p$(PACKAGE_PRE_NAME) $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME) usr/local/bin; \ + # Custom package commands + (for mod in $(MODULE_DIRS); do \ + cp $(MOD_SRC_DIR)/$(MODULE_DIR)/$${mod}/*.ko debian/$(PACKAGE_PRE_NAME)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) ; \ + cp -r $(MOD_SRC_DIR)/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)/usr/local/bin/; \ + $(PYTHON) $(MOD_SRC_DIR)/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME) --install-layout=deb; + + # Resuming debhelper scripts + dh_testroot + dh_install + dh_installchangelogs + dh_installdocs + dh_systemd_enable + dh_installinit + dh_systemd_start + dh_link + dh_fixperms + dh_compress + dh_strip + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb +.PHONY: build binary binary-arch binary-indep clean diff --git a/platform/pddf/i2c/modules/Makefile b/platform/pddf/i2c/modules/Makefile new file mode 100644 index 000000000000..67d3726c3202 --- /dev/null +++ b/platform/pddf/i2c/modules/Makefile @@ -0,0 +1 @@ +subdir-m := client cpld cpldmux xcvr mux gpio psu fan led sysstatus diff --git a/platform/pddf/i2c/modules/client/Makefile b/platform/pddf/i2c/modules/client/Makefile new file mode 100644 index 000000000000..c841a144f2db --- /dev/null +++ b/platform/pddf/i2c/modules/client/Makefile @@ -0,0 +1,3 @@ +obj-m:= pddf_client_module.o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/client/pddf_client_module.c b/platform/pddf/i2c/modules/client/pddf_client_module.c new file mode 100644 index 000000000000..f36596dbe970 --- /dev/null +++ b/platform/pddf/i2c/modules/client/pddf_client_module.c @@ -0,0 +1,330 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A pddf kernel module to create access-data attributes for client creation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" + + + +NEW_DEV_ATTR pddf_data={0}; +EXPORT_SYMBOL(pddf_data); +int showall = 0; + + +/* CLIENT CREATION DATA ATTR LIST */ +PDDF_DATA_ATTR(i2c_type, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&pddf_data.i2c_type, NULL); +PDDF_DATA_ATTR(i2c_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&pddf_data.i2c_name, NULL); +PDDF_DATA_ATTR(parent_bus, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_data.parent_bus, NULL); +PDDF_DATA_ATTR(dev_type, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&pddf_data.dev_type, NULL); +PDDF_DATA_ATTR(dev_id, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&pddf_data.dev_id, NULL); +PDDF_DATA_ATTR(dev_addr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_data.dev_addr, NULL); +PDDF_DATA_ATTR(error, S_IRUGO, show_error_code, NULL, PDDF_INT_DEC, sizeof(int), (void*)&pddf_data.error, (void*)&pddf_data.errstr); + + + +static struct attribute *pddf_clients_data_attributes[] = { + &attr_i2c_type.dev_attr.attr, + &attr_i2c_name.dev_attr.attr, + &attr_parent_bus.dev_attr.attr, + &attr_dev_type.dev_attr.attr, + &attr_dev_id.dev_attr.attr, + &attr_dev_addr.dev_attr.attr, + &attr_error.dev_attr.attr, + NULL +}; + +struct attribute_group pddf_clients_data_group = { + .attrs = pddf_clients_data_attributes, +}; +EXPORT_SYMBOL(pddf_clients_data_group); + + + +PDDF_DATA_ATTR(showall, S_IRUGO, show_all_devices, NULL, PDDF_INT_DEC, sizeof(int), (void *)&showall, NULL); + +static struct attribute *pddf_allclients_data_attributes[] = { + &attr_showall.dev_attr.attr, + NULL +}; +struct attribute_group pddf_allclients_data_group = { + .attrs = pddf_allclients_data_attributes, +}; + + + + + +void set_attr_data(void * ptr) +{ + pddf_data.data=ptr; +} + +ssize_t show_all_devices(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret = 0; + PDDF_ATTR *pptr = (PDDF_ATTR *)da; + int *ptr = (int *)pptr->addr; + + traverse_device_table(); + ret = sprintf(buf, "Total Devices: %d\n", *ptr); + + return ret; +} + +ssize_t show_error_code(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret = 0; + PDDF_ATTR *pptr = (PDDF_ATTR *)da; + NEW_DEV_ATTR *ptr = ( NEW_DEV_ATTR *)pptr->addr; + + ret = sprintf(buf, "0x%x:%s\n", (ptr->error), ptr->errstr); + + return ret; +} + +void set_error_code(int ecode, char *estr) +{ + pddf_data.error = ecode; + strcpy(pddf_data.errstr, estr); + return; +} +EXPORT_SYMBOL(set_error_code); + +ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret = 0; + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + /*pddf_dbg(KERN_ERR "[ READ ] DATA ATTR PTR TYPE:%d, ADDR=%p\n", ptr->type, ptr->addr);*/ + switch(ptr->type) + { + case PDDF_CHAR: + ret = sprintf(buf, "%s\n", ptr->addr); + break; + case PDDF_UCHAR: + ret = sprintf(buf, "%d\n", *(unsigned char*)(ptr->addr)); + break; + case PDDF_INT_DEC: + ret = sprintf(buf, "%d\n", *(int*)(ptr->addr)); + break; + case PDDF_INT_HEX: + ret = sprintf(buf, "0x%x\n", *(int*)(ptr->addr)); + break; + case PDDF_USHORT: + ret = sprintf(buf, "0x%x\n", *(unsigned short *)(ptr->addr)); + break; + case PDDF_UINT32: + ret = sprintf(buf, "0x%x\n", *(uint32_t *)(ptr->addr)); + break; + default: + break; + } + + return ret; +} +EXPORT_SYMBOL(show_pddf_data); + +ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int ret = 0, num = 0; + + + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + + switch(ptr->type) + { + case PDDF_CHAR: + strncpy(ptr->addr, buf, strlen(buf)-1); // to discard newline char form buf + ptr->addr[strlen(buf)-1] = '\0'; + break; + case PDDF_UCHAR: + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(unsigned char *)(ptr->addr) = (unsigned char)num; + break; + case PDDF_INT_DEC: + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(int *)(ptr->addr) = num; + break; + case PDDF_INT_HEX: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(int *)(ptr->addr) = num; + break; + case PDDF_USHORT: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(unsigned short *)(ptr->addr) = (unsigned short)num; + break; + case PDDF_UINT32: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(uint32_t *)(ptr->addr) = (uint32_t)num; + break; + default: + break; + } + + return count; +} +EXPORT_SYMBOL(store_pddf_data); + + + +DEFINE_HASHTABLE(htable, 8); + +int get_hash(char *name) +{ + int i=0; + int hash=0; + for(i=0; iname, name); + hdev->data = ptr; + pddf_dbg(CLIENT, KERN_ERR "%s: Adding ptr 0x%p to the hash table\n", __FUNCTION__, ptr); + hash_add(htable, &hdev->node, get_hash(hdev->name)); +} +EXPORT_SYMBOL(add_device_table); + +void* get_device_table(char *name) +{ + PDEVICE *dev=NULL; + int i=0; + + hash_for_each(htable, i, dev, node) { + if(strcmp(dev->name, name)==0) { + return (void *)dev->data; + } + } + + return NULL; +} +EXPORT_SYMBOL(get_device_table); + +void delete_device_table(char *name) +{ + PDEVICE *dev=NULL; + int i=0; + + hash_for_each(htable, i, dev, node) { + if(strcmp(dev->name, name)==0) { + pddf_dbg(CLIENT, KERN_ERR "found entry to delete: %s 0x%p\n", dev->name, dev->data); + hash_del(&(dev->node)); + } + } + return; +} +EXPORT_SYMBOL(delete_device_table); + +void traverse_device_table(void ) +{ + PDEVICE *dev=NULL; + int i=0; + hash_for_each(htable, i, dev, node) { + pddf_dbg(CLIENT, KERN_ERR "Entry[%d]: %s : 0x%p\n", i, dev->name, dev->data); + } + showall = i; +} +EXPORT_SYMBOL(traverse_device_table); + +struct kobject *device_kobj; +static struct kobject *pddf_kobj; + +struct kobject *get_device_i2c_kobj(void) +{ + return device_kobj; +} + +EXPORT_SYMBOL(get_device_i2c_kobj); + +int __init pddf_data_init(void) +{ + int ret = 0; + + + pddf_dbg(CLIENT, "PDDF_DATA MODULE.. init\n"); + + pddf_kobj = kobject_create_and_add("pddf", kernel_kobj); + if(!pddf_kobj) { + return -ENOMEM; + } + device_kobj = kobject_create_and_add("devices", pddf_kobj); + if(!device_kobj) { + return -ENOMEM; + } + + init_device_table(); + + ret = sysfs_create_group(device_kobj, &pddf_allclients_data_group); + if (ret) + { + kobject_put(device_kobj); + return ret; + } + pddf_dbg(CLIENT, "CREATED PDDF ALLCLIENTS CREATION SYSFS GROUP\n"); + + + + return ret; +} + +void __exit pddf_data_exit(void) +{ + + pddf_dbg(CLIENT, "PDDF_DATA MODULE.. exit\n"); + sysfs_remove_group(device_kobj, &pddf_allclients_data_group); + + kobject_put(device_kobj); + kobject_put(pddf_kobj); + pddf_dbg(CLIENT, KERN_ERR "%s: Removed the kernle object for 'pddf' and 'device' \n", __FUNCTION__); + return; +} + +module_init(pddf_data_init); +module_exit(pddf_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("pddf data"); +MODULE_LICENSE("GPL"); + diff --git a/platform/pddf/i2c/modules/cpld/Makefile b/platform/pddf/i2c/modules/cpld/Makefile new file mode 100644 index 000000000000..c6182ef4f93d --- /dev/null +++ b/platform/pddf/i2c/modules/cpld/Makefile @@ -0,0 +1,4 @@ +subdir-m := driver +obj-m := pddf_cpld_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/cpld/driver/Makefile b/platform/pddf/i2c/modules/cpld/driver/Makefile new file mode 100644 index 000000000000..42704c2cfaec --- /dev/null +++ b/platform/pddf/i2c/modules/cpld/driver/Makefile @@ -0,0 +1,5 @@ +TARGET = pddf_cpld_driver +obj-m := $(TARGET).o + + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/cpld/driver/pddf_cpld_driver.c b/platform/pddf/i2c/modules/cpld/driver/pddf_cpld_driver.c new file mode 100755 index 000000000000..a34c370b9af1 --- /dev/null +++ b/platform/pddf/i2c/modules/cpld/driver/pddf_cpld_driver.c @@ -0,0 +1,230 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A pddf kernel driver module for CPLD + */ + +#include +#include +#include +#include +#include +#include "pddf_cpld_defs.h" + +extern PDDF_CPLD_DATA pddf_cpld_data; + + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + //hw_preaccess_func_cpld_mux_default((uint32_t)cpld_addr, NULL); + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(board_i2c_cpld_read); + +int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(board_i2c_cpld_write); + +ssize_t regval_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len = 0; + struct i2c_client *client = to_i2c_client(dev); + + mutex_lock(&pddf_cpld_data.cpld_lock); + // Put code here to read the register value and print it + if (pddf_cpld_data.reg_addr!=0) + len = sprintf(buf, "0x%2.2x\n", board_i2c_cpld_read(client->addr, pddf_cpld_data.reg_addr)); + else + len = sprintf(buf, "xx\n"); + + mutex_unlock(&pddf_cpld_data.cpld_lock); + return len; +} + +static DEVICE_ATTR_RO(regval); + +static struct attribute *cpld_attrs[] = { + &dev_attr_regval.attr, + NULL, +}; + +static struct attribute_group cpld_attribute_group = { + .attrs = cpld_attrs, +}; + + + + +/* Addresses scanned for board_i2c_cpld + */ +static const unsigned short normal_i2c[] = { 0x31, 0x32, 0x33, 0x35, 0x60, 0x61, 0x62, 0x64, I2C_CLIENT_END }; + +static void board_i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void board_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int board_i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cpld_attribute_group); + if (status) { + goto exit; + } + + dev_dbg(&client->dev, "chip found\n"); + board_i2c_cpld_add_client(client); + + return 0; + +exit: + return status; +} + +static int board_i2c_cpld_remove(struct i2c_client *client) +{ + sysfs_remove_group(&client->dev.kobj, &cpld_attribute_group); + board_i2c_cpld_remove_client(client); + + return 0; +} + +static const struct i2c_device_id board_i2c_cpld_id[] = { + { "i2c_cpld", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, board_i2c_cpld_id); + +static struct i2c_driver board_i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "i2c_cpld", + }, + .probe = board_i2c_cpld_probe, + .remove = board_i2c_cpld_remove, + .id_table = board_i2c_cpld_id, + .address_list = normal_i2c, +}; + +static int __init board_i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&board_i2c_cpld_driver); +} + +static void __exit board_i2c_cpld_exit(void) +{ + i2c_del_driver(&board_i2c_cpld_driver); +} + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("board_i2c_cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(board_i2c_cpld_init); +module_exit(board_i2c_cpld_exit); diff --git a/platform/pddf/i2c/modules/cpld/pddf_cpld_module.c b/platform/pddf/i2c/modules/cpld/pddf_cpld_module.c new file mode 100644 index 000000000000..af15e390265f --- /dev/null +++ b/platform/pddf/i2c/modules/cpld/pddf_cpld_module.c @@ -0,0 +1,219 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to create I2C client for a CPLD + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_cpld_defs.h" + +PDDF_CPLD_DATA pddf_cpld_data={0}; +EXPORT_SYMBOL(pddf_cpld_data); + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t store_pddf_cpld_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t show_pddf_cpld_data(struct device *dev, struct device_attribute *da, char *buf); + +extern void *get_device_table(char *name); +extern void delete_device_table(char *name); + + +/* MUX CLIENT DATA */ +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, NULL, (void*)&pddf_data); +PDDF_DATA_ATTR(reg_addr, S_IWUSR|S_IRUGO, show_pddf_cpld_data, store_pddf_cpld_data, PDDF_USHORT, sizeof(unsigned short), (void*)&pddf_cpld_data.reg_addr, NULL); + + + +static struct attribute *cpld_attributes[] = { + &attr_dev_ops.dev_attr.attr, + &attr_reg_addr.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_cpld_client_data_group = { + .attrs = cpld_attributes, +}; + + +static ssize_t store_pddf_cpld_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int ret = 0; + int num = 0; + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + + ret = kstrtoint(buf,16,&num); + if (ret==0) + { + mutex_lock(&pddf_cpld_data.cpld_lock); + *(unsigned short *)(ptr->addr) = (unsigned short)num; + mutex_unlock(&pddf_cpld_data.cpld_lock); + pddf_dbg(CPLD, KERN_ERR "Stored value: 0x%x, num: 0x%x\n", *(int*)(ptr->addr), num); + } + + return count; +} +EXPORT_SYMBOL(store_pddf_cpld_data); + +ssize_t show_pddf_cpld_data(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret = 0; + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + pddf_dbg(CPLD, KERN_ERR "[ READ ] DATA ATTR PTR TYPE:%d, ADDR=%p\n", ptr->type, ptr->addr); + + mutex_lock(&pddf_cpld_data.cpld_lock); + ret = sprintf(buf, "0x%x\n", *(unsigned short *)(ptr->addr)); + mutex_unlock(&pddf_cpld_data.cpld_lock); + + return ret; +} +EXPORT_SYMBOL(show_pddf_cpld_data); + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + NEW_DEV_ATTR *device_ptr = (NEW_DEV_ATTR *)(ptr->data); + struct i2c_adapter *adapter; + static struct i2c_board_info board_info; + struct i2c_client *client_ptr; + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + adapter = i2c_get_adapter(device_ptr->parent_bus); + + if (strncmp(device_ptr->dev_type, "i2c_cpld", strlen("i2c_cpld"))==0) + { + board_info = (struct i2c_board_info) { + .platform_data = (void *)NULL, + }; + + board_info.addr = device_ptr->dev_addr; + strcpy(board_info.type, device_ptr->dev_type); + + /*pddf_dbg(KERN_ERR "Creating a client %s on 0x%x, platform_data 0x%x\n", board_info.type, board_info.addr, board_info.platform_data);*/ + client_ptr = i2c_new_device(adapter, &board_info); + + if (client_ptr != NULL) { + i2c_put_adapter(adapter); + pddf_dbg(CPLD, KERN_ERR "Created %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + add_device_table(device_ptr->i2c_name, (void*)client_ptr); + } + else { + i2c_put_adapter(adapter); + goto free_data; + } + + } + else + { + printk(KERN_ERR "%s: Unsupported type of cpld - unable to add i2c client\n", __FUNCTION__); + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(device_ptr->i2c_name); + if (client_ptr) + { + pddf_dbg(CPLD, KERN_ERR "Removing %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + delete_device_table(device_ptr->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", device_ptr->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + +free_data: + /*TODO: free the device_ptr->data is dynamically allocated*/ + memset(device_ptr, 0 , sizeof(NEW_DEV_ATTR)); + + return count; +} + + +static struct kobject *cpld_kobj; + +int __init cpld_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(CPLD, "CPLD_DATA MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + cpld_kobj = kobject_create_and_add("cpld", device_kobj); + if(!cpld_kobj) + return -ENOMEM; + + + ret = sysfs_create_group(cpld_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(cpld_kobj); + return ret; + } + pddf_dbg(CPLD, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + + mutex_init(&pddf_cpld_data.cpld_lock); + + ret = sysfs_create_group(cpld_kobj, &pddf_cpld_client_data_group); + if (ret) + { + sysfs_remove_group(cpld_kobj, &pddf_clients_data_group); + kobject_put(cpld_kobj); + return ret; + } + pddf_dbg(CPLD, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + return ret; +} + +void __exit cpld_data_exit(void) +{ + pddf_dbg(CPLD, "CPLD_DATA MODULE.. exit\n"); + sysfs_remove_group(cpld_kobj, &pddf_cpld_client_data_group); + sysfs_remove_group(cpld_kobj, &pddf_clients_data_group); + kobject_put(cpld_kobj); + pddf_dbg(CPLD, KERN_ERR "%s: Removed the kobjects for 'cpld'\n",__FUNCTION__); + return; +} + +module_init(cpld_data_init); +module_exit(cpld_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("cpld platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/cpldmux/Makefile b/platform/pddf/i2c/modules/cpldmux/Makefile new file mode 100644 index 000000000000..53816b98f750 --- /dev/null +++ b/platform/pddf/i2c/modules/cpldmux/Makefile @@ -0,0 +1,4 @@ +subdir-m := driver +obj-m := pddf_cpldmux_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/cpldmux/driver/Makefile b/platform/pddf/i2c/modules/cpldmux/driver/Makefile new file mode 100644 index 000000000000..2c6aa6e60eea --- /dev/null +++ b/platform/pddf/i2c/modules/cpldmux/driver/Makefile @@ -0,0 +1,4 @@ +TARGET = pddf_cpldmux_driver +obj-m := $(TARGET).o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/cpldmux/driver/pddf_cpldmux_driver.c b/platform/pddf/i2c/modules/cpldmux/driver/pddf_cpldmux_driver.c new file mode 100755 index 000000000000..c9df1a60c1af --- /dev/null +++ b/platform/pddf/i2c/modules/cpldmux/driver/pddf_cpldmux_driver.c @@ -0,0 +1,209 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A pddf kernel driver module for CPLDMUX + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_cpldmux_defs.h" + +extern PDDF_CPLDMUX_DATA pddf_cpldmux_data; + +/* Users may overwrite these select and delsect functions as per their requirements + * by overwriting them in custom driver + */ +PDDF_CPLDMUX_OPS pddf_cpldmux_ops = { + .select = pddf_cpldmux_select_default, + .deselect = NULL, /* pddf_cpldmux_deselct_default */ +}; +EXPORT_SYMBOL(pddf_cpldmux_ops); + + +/* NOTE: Never use i2c_smbus_write_byte_data() or i2c_smbus_xfer() since these operations + * locks the parent bus which might lead to mutex deadlock. + */ +static int cpldmux_byte_write(struct i2c_client *client, u8 regaddr, u8 val) +{ + union i2c_smbus_data data; + + data.byte = val; + return client->adapter->algo->smbus_xfer(client->adapter, client->addr, + client->flags, + I2C_SMBUS_WRITE, + regaddr, I2C_SMBUS_BYTE_DATA, &data); +} + +int pddf_cpldmux_select_default(struct i2c_mux_core *muxc, uint32_t chan) +{ + PDDF_CPLDMUX_PRIV_DATA *private = i2c_mux_priv(muxc); + PDDF_CPLDMUX_PDATA *pdata = NULL; + PDDF_CPLDMUX_CHAN_DATA *sdata = NULL; + int ret = 0; + + /* Select the chan_data based upon the chan */ + pdata = &private->data; + if (chan>=pdata->num_chan) + { + printk(KERN_ERR "%s: wrong channel number %d, supported channels %d\n",__FUNCTION__, chan, pdata->num_chan); + return 0; + } + + if ( (pdata->chan_cache!=1) || (private->last_chan!=chan) ) + { + sdata = &pdata->chan_data[chan]; + pddf_dbg(CPLDMUX, KERN_ERR "%s: Writing 0x%x at 0x%x offset of cpld 0x%x to enable chan %d\n", __FUNCTION__, sdata->cpld_sel, sdata->cpld_offset, sdata->cpld_devaddr, chan); + ret = cpldmux_byte_write(pdata->cpld, sdata->cpld_offset, (uint8_t)(sdata->cpld_sel & 0xff)); + private->last_chan = chan; + } + + return ret; +} + +int pddf_cpldmux_deselect_default(struct i2c_mux_core *muxc, uint32_t chan) +{ + PDDF_CPLDMUX_PRIV_DATA *private = i2c_mux_priv(muxc); + PDDF_CPLDMUX_PDATA *pdata = NULL; + PDDF_CPLDMUX_CHAN_DATA *sdata = NULL; + int ret = 0; + + /* Select the chan_data based upon the chan */ + pdata = &private->data; + if (chan>=pdata->num_chan) + { + printk(KERN_ERR "%s: wrong channel number %d, supported channels %d\n",__FUNCTION__, chan, pdata->num_chan); + return 0; + } + sdata = &pdata->chan_data[chan]; + + pddf_dbg(CPLDMUX, KERN_ERR "%s: Writing 0x%x at 0x%x offset of cpld 0x%x to disable chan %d", __FUNCTION__, sdata->cpld_desel, sdata->cpld_offset, sdata->cpld_devaddr, chan); + ret = cpldmux_byte_write(pdata->cpld, sdata->cpld_offset, (uint8_t)(sdata->cpld_desel)); + return ret; +} + +static int cpld_mux_probe(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc; + PDDF_CPLDMUX_PRIV_DATA *private; + PDDF_CPLDMUX_PDATA *pdata; + struct i2c_adapter *adap; + int i, ret, ndev; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPLDMUX platform data not found\n"); + return -ENODEV; + } + private = (PDDF_CPLDMUX_PRIV_DATA *)kzalloc(sizeof(PDDF_CPLDMUX_PRIV_DATA) , GFP_KERNEL); + if (!private) { + printk(KERN_ERR "Failed to allocate memory for priv data\n"); + return -ENOMEM; + } + + private->last_chan = 0xff; /*Giving imaginary high value so that proper channel is selected at first iteration*/ + memcpy(&private->data, pdata, sizeof(PDDF_CPLDMUX_PDATA)); + + adap = i2c_get_adapter(pdata->parent_bus); + if (!adap) { + kfree(private); + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent_bus); + return -ENODEV; + } + ndev = pdata->num_chan; + + muxc = i2c_mux_alloc(adap, &pdev->dev, ndev, 0, 0, pddf_cpldmux_ops.select, pddf_cpldmux_ops.deselect); + if (!muxc) { + ret = -ENOMEM; + goto alloc_failed; + } + muxc->priv = private; + platform_set_drvdata(pdev, muxc); + + for (i = 0; i < ndev; i++) + { + int nr = pdata->base_chan + i; + unsigned int class = 0; + ret = i2c_mux_add_adapter(muxc, nr, i, class); + if (ret) { + dev_err(&pdev->dev, "Failed to add adapter %d\n", i); + goto add_adapter_failed; + } + } + dev_info(&pdev->dev, "%d port mux on %s adapter\n", ndev, adap->name); + return 0; + +add_adapter_failed: + i2c_mux_del_adapters(muxc); +alloc_failed: + kfree(private); + i2c_put_adapter(adap); + return ret; +} + +static int cpld_mux_remove(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc = platform_get_drvdata(pdev); + struct i2c_adapter *adap = muxc->parent; + PDDF_CPLDMUX_PDATA *cpldmux_pdata = pdev->dev.platform_data; + + i2c_mux_del_adapters(muxc); + if (muxc->priv) + kfree(muxc->priv); + i2c_put_adapter(adap); + + if (cpldmux_pdata) { + pddf_dbg(CPLDMUX, KERN_DEBUG "%s: Freeing cpldmux platform data\n", __FUNCTION__); + kfree(cpldmux_pdata); + } + + return 0; +} + +static struct platform_driver cpld_mux_driver = { + .probe = cpld_mux_probe, + .remove = cpld_mux_remove, /* TODO */ + .driver = { + .owner = THIS_MODULE, + .name = "cpld_mux", + }, +}; + +static int __init board_i2c_cpldmux_init(void) +{ + int ret; + ret = platform_driver_register(&cpld_mux_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld mux driver\n"); + } + return (ret); +} + +static void __exit board_i2c_cpldmux_exit(void) +{ + platform_driver_unregister(&cpld_mux_driver); +} + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("board_i2c_cpldmux driver"); +MODULE_LICENSE("GPL"); + +module_init(board_i2c_cpldmux_init); +module_exit(board_i2c_cpldmux_exit); diff --git a/platform/pddf/i2c/modules/cpldmux/pddf_cpldmux_module.c b/platform/pddf/i2c/modules/cpldmux/pddf_cpldmux_module.c new file mode 100644 index 000000000000..f99def315820 --- /dev/null +++ b/platform/pddf/i2c/modules/cpldmux/pddf_cpldmux_module.c @@ -0,0 +1,254 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * PDDF generic module for cpldmux device + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_cpldmux_defs.h" + +PDDF_CPLDMUX_DATA pddf_cpldmux_data={0}; +PDDF_CPLDMUX_CHAN_DATA pddf_cpldmux_chan_data={0}; +EXPORT_SYMBOL(pddf_cpldmux_data); + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t do_chan_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +extern void *get_device_table(char *name); +extern void delete_device_table(char *name); + + +/* CPLDMUX CLIENT DATA */ +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&pddf_cpldmux_data, (void*)&pddf_data); +PDDF_DATA_ATTR(chan_ops, S_IWUSR, NULL, do_chan_operation, PDDF_CHAR, 8, (void*)&pddf_cpldmux_data, NULL); +PDDF_DATA_ATTR(base_chan, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_cpldmux_data.base_chan, NULL); +PDDF_DATA_ATTR(num_chan, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&pddf_cpldmux_data.num_chan, NULL); +PDDF_DATA_ATTR(chan_cache, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&pddf_cpldmux_data.chan_cache, NULL); +PDDF_DATA_ATTR(cpld_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&pddf_cpldmux_data.cpld_name, NULL); +PDDF_DATA_ATTR(chan, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&pddf_cpldmux_chan_data.chan_num, NULL); +PDDF_DATA_ATTR(dev, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 128, (void*)&pddf_cpldmux_chan_data.chan_device, NULL); +PDDF_DATA_ATTR(cpld_devaddr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_cpldmux_chan_data.cpld_devaddr, NULL); +PDDF_DATA_ATTR(cpld_offset, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_cpldmux_chan_data.cpld_offset, NULL); +PDDF_DATA_ATTR(cpld_sel, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_cpldmux_chan_data.cpld_sel, NULL); +PDDF_DATA_ATTR(cpld_desel, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_cpldmux_chan_data.cpld_desel, NULL); + + +static struct attribute *cpldmux_attributes[] = { + &attr_dev_ops.dev_attr.attr, + &attr_chan_ops.dev_attr.attr, + &attr_base_chan.dev_attr.attr, + &attr_num_chan.dev_attr.attr, + &attr_chan_cache.dev_attr.attr, + &attr_cpld_name.dev_attr.attr, + &attr_chan.dev_attr.attr, + &attr_dev.dev_attr.attr, + &attr_cpld_devaddr.dev_attr.attr, + &attr_cpld_offset.dev_attr.attr, + &attr_cpld_sel.dev_attr.attr, + &attr_cpld_desel.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_cpldmux_client_data_group = { + .attrs = cpldmux_attributes, +}; + + + +static ssize_t do_chan_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + PDDF_CPLDMUX_DATA *cpldmux_data = (PDDF_CPLDMUX_DATA *)(ptr->addr); + int index; + + pddf_dbg(CPLDMUX, KERN_ERR "%s: Adding channel %d\n", __FUNCTION__, pddf_cpldmux_chan_data.chan_num); + index = pddf_cpldmux_chan_data.chan_num; + cpldmux_data->chan_data[index] = pddf_cpldmux_chan_data; + + memset(&pddf_cpldmux_chan_data, 0, sizeof(pddf_cpldmux_chan_data)); + + + return count; +} + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + NEW_DEV_ATTR *device_ptr = (NEW_DEV_ATTR *)(ptr->data); + PDDF_CPLDMUX_DATA *cpldmux_data = (PDDF_CPLDMUX_DATA *)(ptr->addr); + PDDF_CPLDMUX_PDATA *cpldmux_platform_data = NULL; + struct platform_device *plat_dev = NULL; + struct i2c_client *client_ptr = NULL; + int ret=0, i=0; + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + if (strncmp(device_ptr->dev_type, "cpld_mux", strlen("cpld_mux"))==0) + { + /*Get the i2c_client handle for the CPLD which drives this cpldmux*/ + client_ptr = (struct i2c_client *)get_device_table(cpldmux_data->cpld_name); + if (client_ptr==NULL) + { + pddf_dbg(CPLDMUX, KERN_ERR "Unable to get the CPLD client %s for %s cpldmux\n", cpldmux_data->cpld_name, device_ptr->i2c_name); + printk(KERN_ERR "Unable to get the CPLD client %s for %s cpldmux\n", cpldmux_data->cpld_name, device_ptr->i2c_name); + goto clear_data; + } + + /* Allocate the cpldmux_platform_data */ + cpldmux_platform_data = (PDDF_CPLDMUX_PDATA *)kzalloc( sizeof(PDDF_CPLDMUX_PDATA) + cpldmux_data->num_chan*sizeof(PDDF_CPLDMUX_CHAN_DATA), GFP_KERNEL ); + cpldmux_platform_data->chan_data = (PDDF_CPLDMUX_CHAN_DATA *)(cpldmux_platform_data+1); + + cpldmux_platform_data->parent_bus = device_ptr->parent_bus; + cpldmux_platform_data->base_chan = cpldmux_data->base_chan; + cpldmux_platform_data->num_chan = cpldmux_data->num_chan; + cpldmux_platform_data->chan_cache = cpldmux_data->chan_cache; + cpldmux_platform_data->cpld = client_ptr; + for (i=0; inum_chan; i++) + { + cpldmux_platform_data->chan_data[i] = cpldmux_data->chan_data[i]; + } + + plat_dev = platform_device_alloc(device_ptr->dev_type, device_ptr->dev_id); + + plat_dev->dev.platform_data = cpldmux_platform_data; + + pddf_dbg(CPLDMUX, KERN_ERR "Creating a %s platform_device 0x%p, platform_data 0x%p\n", plat_dev->name, (void *)plat_dev, (void *)cpldmux_platform_data); + ret = platform_device_add(plat_dev); + if (ret) + { + pddf_dbg(CPLDMUX, KERN_ERR "Unable to create cpld_mux (%s) device: Error %d\n", device_ptr->i2c_name, ret); + goto free_data; + } + else + { + add_device_table(device_ptr->i2c_name, (void *)plat_dev); + } + + } + else + { + printk(KERN_ERR "%s: Unsupported type of cpldmux - unable to add i2c client\n", __FUNCTION__); + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + plat_dev = (struct platform_device *)get_device_table(device_ptr->i2c_name); + if (plat_dev) + { + pddf_dbg(CPLDMUX, KERN_ERR "Removing %s device: 0x%p\n", device_ptr->i2c_name, (void *)plat_dev); + pddf_dbg(CPLDMUX, KERN_ERR "Freeing the memory held by device: 0x%p\n", (void *)plat_dev); + platform_device_del(plat_dev); + delete_device_table(device_ptr->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", device_ptr->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + goto clear_data; + +free_data: + /* Free the allocated memory for platform and channel data */ + cpldmux_platform_data = plat_dev->dev.platform_data; + if (cpldmux_platform_data) + { + printk(KERN_ERR "%s: Unable to register a cpldmux device. Freeing the platform data\n", __FUNCTION__); + kfree(cpldmux_platform_data); + } + + /* Put the platform device structure */ + platform_device_put(plat_dev); +clear_data: + memset(cpldmux_data, 0, sizeof(PDDF_CPLDMUX_DATA)); + /*TODO: free the data device_ptr->data if data is dynamically allocated*/ + memset(device_ptr, 0, sizeof(NEW_DEV_ATTR)); + return count; +} + + +static struct kobject *cpldmux_kobj; + +int __init cpldmux_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(CPLDMUX, "CPLDMUX_DATA MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + cpldmux_kobj = kobject_create_and_add("cpldmux", device_kobj); + if(!cpldmux_kobj) + return -ENOMEM; + + + ret = sysfs_create_group(cpldmux_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(cpldmux_kobj); + return ret; + } + pddf_dbg(CPLDMUX, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + + + ret = sysfs_create_group(cpldmux_kobj, &pddf_cpldmux_client_data_group); + if (ret) + { + sysfs_remove_group(cpldmux_kobj, &pddf_clients_data_group); + kobject_put(cpldmux_kobj); + return ret; + } + pddf_dbg(CPLDMUX, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + return ret; +} + +void __exit cpldmux_data_exit(void) +{ + pddf_dbg(CPLDMUX, "CPLDMUX_DATA MODULE.. exit\n"); + sysfs_remove_group(cpldmux_kobj, &pddf_cpldmux_client_data_group); + sysfs_remove_group(cpldmux_kobj, &pddf_clients_data_group); + kobject_put(cpldmux_kobj); + pddf_dbg(CPLDMUX, KERN_ERR "%s: Removed the kobjects for 'cpldmux'\n",__FUNCTION__); + return; +} + +module_init(cpldmux_data_init); +module_exit(cpldmux_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("cpldmux platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/fan/Makefile b/platform/pddf/i2c/modules/fan/Makefile new file mode 100644 index 000000000000..94b6b146c51d --- /dev/null +++ b/platform/pddf/i2c/modules/fan/Makefile @@ -0,0 +1,4 @@ +subdir-m := driver +obj-m := pddf_fan_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/fan/driver/Makefile b/platform/pddf/i2c/modules/fan/driver/Makefile new file mode 100644 index 000000000000..c94f217d3bab --- /dev/null +++ b/platform/pddf/i2c/modules/fan/driver/Makefile @@ -0,0 +1,6 @@ +TARGET := pddf_fan_driver_module +obj-m := $(TARGET).o + +$(TARGET)-objs := pddf_fan_api.o pddf_fan_driver.o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/fan/driver/pddf_fan_api.c b/platform/pddf/i2c/modules/fan/driver/pddf_fan_api.c new file mode 100644 index 000000000000..167b0e183315 --- /dev/null +++ b/platform/pddf/i2c/modules/fan/driver/pddf_fan_api.c @@ -0,0 +1,526 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description of various APIs related to FAN component + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_fan_defs.h" +#include "pddf_fan_driver.h" + +/*#define FAN_DEBUG*/ +#ifdef FAN_DEBUG +#define fan_dbg(...) printk(__VA_ARGS__) +#else +#define fan_dbg(...) +#endif + +extern void *get_device_table(char *name); + +void get_fan_duplicate_sysfs(int idx, char *str) +{ + switch (idx) + { + default: + break; + } + + return; +} + + +int fan_update_hw(struct device *dev, struct fan_attr_info *info, FAN_DATA_ATTR *udata) +{ + int status = 0; + struct i2c_client *client = to_i2c_client(dev); + FAN_SYSFS_ATTR_DATA *sysfs_attr_data = NULL; + + + mutex_lock(&info->update_lock); + + sysfs_attr_data = udata->access_data; + if (sysfs_attr_data->pre_set != NULL) + { + status = (sysfs_attr_data->pre_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: pre_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + if (sysfs_attr_data->do_set != NULL) + { + status = (sysfs_attr_data->do_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: do_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + + } + if (sysfs_attr_data->post_set != NULL) + { + status = (sysfs_attr_data->post_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: post_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + + mutex_unlock(&info->update_lock); + + return 0; +} + +int fan_update_attr(struct device *dev, struct fan_attr_info *info, FAN_DATA_ATTR *udata) +{ + int status = 0; + struct i2c_client *client = to_i2c_client(dev); + FAN_SYSFS_ATTR_DATA *sysfs_attr_data = NULL; + + + mutex_lock(&info->update_lock); + + if (time_after(jiffies, info->last_updated + HZ + HZ / 2) || !info->valid) + { + dev_dbg(&client->dev, "Starting pddf_fan update\n"); + info->valid = 0; + + sysfs_attr_data = udata->access_data; + if (sysfs_attr_data->pre_get != NULL) + { + status = (sysfs_attr_data->pre_get)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + if (sysfs_attr_data->do_get != NULL) + { + status = (sysfs_attr_data->do_get)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + + } + if (sysfs_attr_data->post_get != NULL) + { + status = (sysfs_attr_data->post_get)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + + + info->last_updated = jiffies; + info->valid = 1; + } + + mutex_unlock(&info->update_lock); + + return 0; +} + +ssize_t fan_show_default(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct fan_data *data = i2c_get_clientdata(client); + FAN_PDATA *pdata = (FAN_PDATA *)(client->dev.platform_data); + FAN_DATA_ATTR *usr_data = NULL; + struct fan_attr_info *attr_info = NULL; + int i, status=0; + char new_str[ATTR_NAME_LEN] = ""; + FAN_SYSFS_ATTR_DATA *ptr = NULL; + + for (i=0;inum_attr;i++) + { + ptr = (FAN_SYSFS_ATTR_DATA *)pdata->fan_attrs[i].access_data; + get_fan_duplicate_sysfs(ptr->index , new_str); + if (strcmp(attr->dev_attr.attr.name, pdata->fan_attrs[i].aname) == 0 || strcmp(attr->dev_attr.attr.name, new_str) == 0) + { + attr_info = &data->attr_info[i]; + usr_data = &pdata->fan_attrs[i]; + strcpy(new_str, ""); + } + } + + if (attr_info==NULL || usr_data==NULL) + { + printk(KERN_ERR "%s is not supported attribute for this client\n", usr_data->aname); + goto exit; + } + + fan_update_attr(dev, attr_info, usr_data); + + /*Decide the o/p based on attribute type */ + switch(attr->index) + { + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + case FAN6_PRESENT: + case FAN7_PRESENT: + case FAN8_PRESENT: + case FAN9_PRESENT: + case FAN10_PRESENT: + case FAN11_PRESENT: + case FAN12_PRESENT: + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + case FAN6_DIRECTION: + case FAN7_DIRECTION: + case FAN8_DIRECTION: + case FAN9_DIRECTION: + case FAN10_DIRECTION: + case FAN11_DIRECTION: + case FAN12_DIRECTION: + case FAN1_INPUT: + case FAN2_INPUT: + case FAN3_INPUT: + case FAN4_INPUT: + case FAN5_INPUT: + case FAN6_INPUT: + case FAN7_INPUT: + case FAN8_INPUT: + case FAN9_INPUT: + case FAN10_INPUT: + case FAN11_INPUT: + case FAN12_INPUT: + case FAN1_PWM: + case FAN2_PWM: + case FAN3_PWM: + case FAN4_PWM: + case FAN5_PWM: + case FAN6_PWM: + case FAN7_PWM: + case FAN8_PWM: + case FAN9_PWM: + case FAN10_PWM: + case FAN11_PWM: + case FAN12_PWM: + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + case FAN6_FAULT: + case FAN7_FAULT: + case FAN8_FAULT: + case FAN9_FAULT: + case FAN10_FAULT: + case FAN11_FAULT: + case FAN12_FAULT: + status = attr_info->val.intval; + break; + default: + fan_dbg(KERN_ERR "%s: Unable to find the attribute index for %s\n", __FUNCTION__, usr_data->aname); + status = 0; + } + +exit: + return sprintf(buf, "%d\n", status); +} + + +ssize_t fan_store_default(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct fan_data *data = i2c_get_clientdata(client); + FAN_PDATA *pdata = (FAN_PDATA *)(client->dev.platform_data); + FAN_DATA_ATTR *usr_data = NULL; + struct fan_attr_info *attr_info = NULL; + int i, ret ; + uint32_t val; + + for (i=0;inum_attr;i++) + { + if (strcmp(data->attr_info[i].name, attr->dev_attr.attr.name) == 0 && strcmp(pdata->fan_attrs[i].aname, attr->dev_attr.attr.name) == 0) + { + attr_info = &data->attr_info[i]; + usr_data = &pdata->fan_attrs[i]; + } + } + + if (attr_info==NULL || usr_data==NULL) { + printk(KERN_ERR "%s is not supported attribute for this client\n", attr->dev_attr.attr.name); + goto exit; + } + + switch(attr->index) + { + case FAN1_PWM: + case FAN2_PWM: + case FAN3_PWM: + case FAN4_PWM: + case FAN5_PWM: + case FAN6_PWM: + case FAN7_PWM: + case FAN8_PWM: + case FAN9_PWM: + case FAN10_PWM: + case FAN11_PWM: + case FAN12_PWM: + ret = kstrtoint(buf, 10, &val); + if (ret) + { + printk(KERN_ERR "%s: Unable to convert string into value for %s\n", __FUNCTION__, usr_data->aname); + return ret; + } + /*Update the value of attr_info here, and use it to update the HW values*/ + attr_info->val.intval = val; + break; + default: + printk(KERN_ERR "%s: Unable to find the attr index for %s\n", __FUNCTION__, usr_data->aname); + goto exit; + } + + fan_dbg(KERN_ERR "%s: pwm to be set is %d\n", __FUNCTION__, val); + fan_update_hw(dev, attr_info, usr_data); + +exit: + return count; +} + +int fan_cpld_client_read(FAN_DATA_ATTR *udata) +{ + int status = -1; + + if (udata!=NULL) + { + if (udata->len==1) + { + status = board_i2c_cpld_read(udata->devaddr , udata->offset); + } + else + { + /* Get the I2C client for the CPLD */ + struct i2c_client *client_ptr=NULL; + client_ptr = (struct i2c_client *)get_device_table(udata->devname); + if (client_ptr) + { + if (udata->len==2) + { + status = i2c_smbus_read_word_swapped(client_ptr, udata->offset); + } + else + printk(KERN_ERR "PDDF_FAN: Doesn't support block CPLD read yet"); + } + else + printk(KERN_ERR "Unable to get the client handle for %s\n", udata->devname); + } + + } + + return status; +} + + +int sonic_i2c_get_fan_present_default(void *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + int val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + if (strcmp(udata->devtype, "cpld") == 0) + { + val = fan_cpld_client_read(udata); + } + else + { + val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); + } + + painfo->val.intval = ((val & udata->mask) == udata->cmpval); + + + return status; +} + +int sonic_i2c_get_fan_rpm_default(void *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + uint32_t val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + if (strcmp(udata->devtype, "cpld") == 0) + { + val = fan_cpld_client_read(udata); + } + else + { + if (udata->len == 1) + { + val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); + } + else if (udata->len ==2) + { + val = i2c_smbus_read_word_swapped((struct i2c_client *)client, udata->offset); + + } + } + + if (udata->is_divisor) + painfo->val.intval = udata->mult / (val >> 3); + else + painfo->val.intval = udata->mult * val; + + return status; +} + + +int sonic_i2c_get_fan_direction_default(void *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + uint32_t val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + if (strcmp(udata->devtype, "cpld") == 0) + { + val = fan_cpld_client_read(udata); + } + else + { + val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); + } + painfo->val.intval = ((val & udata->mask) == udata->cmpval); + + return status; +} + + +int sonic_i2c_set_fan_pwm_default(struct i2c_client *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + uint32_t val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + val = painfo->val.intval & udata->mask; + + if (val > 255) + { + return -EINVAL; + } + + if (strcmp(udata->devtype, "cpld") == 0) + { + if (udata->len==1) + { + status = board_i2c_cpld_write(udata->devaddr , udata->offset, val); + } + else + { + /* Get the I2C client for the CPLD */ + struct i2c_client *client_ptr=NULL; + client_ptr = (struct i2c_client *)get_device_table(udata->devname); + if (client_ptr) + { + if (udata->len==2) + { + uint8_t val_lsb = val & 0xFF; + uint8_t val_hsb = (val >> 8) & 0xFF; + /* TODO: Check this logic for LE and BE */ + i2c_smbus_write_byte_data(client, udata->offset, val_lsb); + i2c_smbus_write_byte_data(client, udata->offset+1, val_hsb); + } + else + printk(KERN_ERR "PDDF_FAN: Doesn't support block CPLD write yet"); + } + else + printk(KERN_ERR "Unable to get the client handle for %s\n", udata->devname); + } + + } + else + { + if (udata->len == 1) + i2c_smbus_write_byte_data(client, udata->offset, val); + else if (udata->len == 2) + { + uint8_t val_lsb = val & 0xFF; + uint8_t val_hsb = (val >> 8) & 0xFF; + /* TODO: Check this logic for LE and BE */ + i2c_smbus_write_byte_data(client, udata->offset, val_lsb); + i2c_smbus_write_byte_data(client, udata->offset+1, val_hsb); + } + else + { + printk(KERN_DEBUG "%s: pwm should be of len 1/2 bytes. Not setting the pwm as the length is %d\n", __FUNCTION__, udata->len); + } + } + + return status; +} + + +int sonic_i2c_get_fan_pwm_default(void *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + uint32_t val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + if (strcmp(udata->devtype, "cpld") == 0) + { + val = fan_cpld_client_read(udata); + } + else + { + if (udata->len == 1) + { + val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); + } + else if (udata->len ==2) + { + val = i2c_smbus_read_word_swapped((struct i2c_client *)client, udata->offset); + + } + } + + val = val & udata->mask; + painfo->val.intval = val; + return status; +} + +int sonic_i2c_get_fan_fault_default(void *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + uint32_t val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + /*Assuming fan fault to be denoted by 1 byte only*/ + if (strcmp(udata->devtype, "cpld") == 0) + { + val = fan_cpld_client_read(udata); + } + else + { + val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); + } + + val = val & udata->mask; + painfo->val.intval = val; + return status; +} + + +int pddf_fan_post_probe_default(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + + /*Dummy func for now - check the respective platform modules*/ + return 0; +} diff --git a/platform/pddf/i2c/modules/fan/driver/pddf_fan_driver.c b/platform/pddf/i2c/modules/fan/driver/pddf_fan_driver.c new file mode 100644 index 000000000000..da8275fccd64 --- /dev/null +++ b/platform/pddf/i2c/modules/fan/driver/pddf_fan_driver.c @@ -0,0 +1,496 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel driver module for a FAN controller + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_fan_defs.h" +#include "pddf_fan_driver.h" +#include "pddf_fan_api.h" + +#define DRVNAME "pddf_fan" + +struct pddf_ops_t pddf_fan_ops = { + .pre_init = NULL, + .post_init = NULL, + + .pre_probe = NULL, + .post_probe = pddf_fan_post_probe_default, + + .pre_remove = NULL, + .post_remove = NULL, + + .pre_exit = NULL, + .post_exit = NULL, +}; +EXPORT_SYMBOL(pddf_fan_ops); + + + +FAN_SYSFS_ATTR_DATA data_fan1_present = {FAN1_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan1_present); +FAN_SYSFS_ATTR_DATA data_fan2_present = {FAN2_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan2_present); +FAN_SYSFS_ATTR_DATA data_fan3_present = {FAN3_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan3_present); +FAN_SYSFS_ATTR_DATA data_fan4_present = {FAN4_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan4_present); +FAN_SYSFS_ATTR_DATA data_fan5_present = {FAN5_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan5_present); +FAN_SYSFS_ATTR_DATA data_fan6_present = {FAN6_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan6_present); +FAN_SYSFS_ATTR_DATA data_fan7_present = {FAN7_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan7_present); +FAN_SYSFS_ATTR_DATA data_fan8_present = {FAN8_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan8_present); +FAN_SYSFS_ATTR_DATA data_fan9_present = {FAN9_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan9_present); +FAN_SYSFS_ATTR_DATA data_fan10_present = {FAN10_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan10_present); +FAN_SYSFS_ATTR_DATA data_fan11_present = {FAN11_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan11_present); +FAN_SYSFS_ATTR_DATA data_fan12_present = {FAN12_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan12_present); + + +FAN_SYSFS_ATTR_DATA data_fan1_direction = {FAN1_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan1_direction); +FAN_SYSFS_ATTR_DATA data_fan2_direction = {FAN2_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan2_direction); +FAN_SYSFS_ATTR_DATA data_fan3_direction = {FAN3_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan3_direction); +FAN_SYSFS_ATTR_DATA data_fan4_direction = {FAN4_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan4_direction); +FAN_SYSFS_ATTR_DATA data_fan5_direction = {FAN5_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan5_direction); +FAN_SYSFS_ATTR_DATA data_fan6_direction = {FAN6_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan6_direction); +FAN_SYSFS_ATTR_DATA data_fan7_direction = {FAN7_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan7_direction); +FAN_SYSFS_ATTR_DATA data_fan8_direction = {FAN8_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan8_direction); +FAN_SYSFS_ATTR_DATA data_fan9_direction = {FAN9_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan9_direction); +FAN_SYSFS_ATTR_DATA data_fan10_direction = {FAN10_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan10_direction); +FAN_SYSFS_ATTR_DATA data_fan11_direction = {FAN11_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan11_direction); +FAN_SYSFS_ATTR_DATA data_fan12_direction = {FAN12_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan12_direction); + + +FAN_SYSFS_ATTR_DATA data_fan1_input = {FAN1_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan1_input); +FAN_SYSFS_ATTR_DATA data_fan2_input = {FAN2_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan2_input); +FAN_SYSFS_ATTR_DATA data_fan3_input = {FAN3_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan3_input); +FAN_SYSFS_ATTR_DATA data_fan4_input = {FAN4_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan4_input); +FAN_SYSFS_ATTR_DATA data_fan5_input = {FAN5_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan5_input); +FAN_SYSFS_ATTR_DATA data_fan6_input = {FAN6_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan6_input); +FAN_SYSFS_ATTR_DATA data_fan7_input = {FAN7_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan7_input); +FAN_SYSFS_ATTR_DATA data_fan8_input = {FAN8_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan8_input); +FAN_SYSFS_ATTR_DATA data_fan9_input = {FAN9_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan9_input); +FAN_SYSFS_ATTR_DATA data_fan10_input = {FAN10_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan10_input); +FAN_SYSFS_ATTR_DATA data_fan11_input = {FAN11_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan11_input); +FAN_SYSFS_ATTR_DATA data_fan12_input = {FAN12_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan12_input); + + +FAN_SYSFS_ATTR_DATA data_fan1_pwm = {FAN1_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan1_pwm); +FAN_SYSFS_ATTR_DATA data_fan2_pwm = {FAN2_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan2_pwm); +FAN_SYSFS_ATTR_DATA data_fan3_pwm = {FAN3_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan3_pwm); +FAN_SYSFS_ATTR_DATA data_fan4_pwm = {FAN4_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan4_pwm); +FAN_SYSFS_ATTR_DATA data_fan5_pwm = {FAN5_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan5_pwm); +FAN_SYSFS_ATTR_DATA data_fan6_pwm = {FAN6_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan6_pwm); +FAN_SYSFS_ATTR_DATA data_fan7_pwm = {FAN7_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan7_pwm); +FAN_SYSFS_ATTR_DATA data_fan8_pwm = {FAN8_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan8_pwm); +FAN_SYSFS_ATTR_DATA data_fan9_pwm = {FAN9_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan9_pwm); +FAN_SYSFS_ATTR_DATA data_fan10_pwm = {FAN10_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan10_pwm); +FAN_SYSFS_ATTR_DATA data_fan11_pwm = {FAN11_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan11_pwm); +FAN_SYSFS_ATTR_DATA data_fan12_pwm = {FAN12_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan12_pwm); + + +FAN_SYSFS_ATTR_DATA data_fan1_fault = {FAN1_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan1_fault); +FAN_SYSFS_ATTR_DATA data_fan2_fault = {FAN2_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan2_fault); +FAN_SYSFS_ATTR_DATA data_fan3_fault = {FAN3_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan3_fault); +FAN_SYSFS_ATTR_DATA data_fan4_fault = {FAN4_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan4_fault); +FAN_SYSFS_ATTR_DATA data_fan5_fault = {FAN5_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan5_fault); +FAN_SYSFS_ATTR_DATA data_fan6_fault = {FAN6_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan6_fault); +FAN_SYSFS_ATTR_DATA data_fan7_fault = {FAN7_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan7_fault); +FAN_SYSFS_ATTR_DATA data_fan8_fault = {FAN8_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan8_fault); +FAN_SYSFS_ATTR_DATA data_fan9_fault = {FAN9_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan9_fault); +FAN_SYSFS_ATTR_DATA data_fan10_fault = {FAN10_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan10_fault); +FAN_SYSFS_ATTR_DATA data_fan11_fault = {FAN11_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan11_fault); +FAN_SYSFS_ATTR_DATA data_fan12_fault = {FAN12_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan12_fault); + + +FAN_SYSFS_ATTR_DATA_ENTRY fan_sysfs_attr_data_tbl[]= +{ + { "fan1_present", &data_fan1_present}, + { "fan2_present", &data_fan2_present}, + { "fan3_present", &data_fan3_present}, + { "fan4_present", &data_fan4_present}, + { "fan5_present", &data_fan5_present}, + { "fan6_present", &data_fan6_present}, + { "fan7_present", &data_fan7_present}, + { "fan8_present", &data_fan8_present}, + { "fan9_present", &data_fan9_present}, + { "fan10_present", &data_fan10_present}, + { "fan11_present", &data_fan11_present}, + { "fan12_present", &data_fan12_present}, + { "fan1_direction", &data_fan1_direction}, + { "fan2_direction", &data_fan2_direction}, + { "fan3_direction", &data_fan3_direction}, + { "fan4_direction", &data_fan4_direction}, + { "fan5_direction", &data_fan5_direction}, + { "fan6_direction", &data_fan6_direction}, + { "fan7_direction", &data_fan7_direction}, + { "fan8_direction", &data_fan8_direction}, + { "fan9_direction", &data_fan9_direction}, + { "fan10_direction", &data_fan10_direction}, + { "fan11_direction", &data_fan11_direction}, + { "fan12_direction", &data_fan12_direction}, + { "fan1_input", &data_fan1_input}, + { "fan2_input", &data_fan2_input}, + { "fan3_input", &data_fan3_input}, + { "fan4_input", &data_fan4_input}, + { "fan5_input", &data_fan5_input}, + { "fan6_input", &data_fan6_input}, + { "fan7_input", &data_fan7_input}, + { "fan8_input", &data_fan8_input}, + { "fan9_input", &data_fan9_input}, + { "fan10_input", &data_fan10_input}, + { "fan11_input", &data_fan11_input}, + { "fan12_input", &data_fan12_input}, + { "fan1_pwm", &data_fan1_pwm}, + { "fan2_pwm", &data_fan2_pwm}, + { "fan3_pwm", &data_fan3_pwm}, + { "fan4_pwm", &data_fan4_pwm}, + { "fan5_pwm", &data_fan5_pwm}, + { "fan6_pwm", &data_fan6_pwm}, + { "fan7_pwm", &data_fan7_pwm}, + { "fan8_pwm", &data_fan8_pwm}, + { "fan9_pwm", &data_fan9_pwm}, + { "fan10_pwm", &data_fan10_pwm}, + { "fan11_pwm", &data_fan11_pwm}, + { "fan12_pwm", &data_fan12_pwm}, + { "fan1_fault", &data_fan1_fault}, + { "fan2_fault", &data_fan2_fault}, + { "fan3_fault", &data_fan3_fault}, + { "fan4_fault", &data_fan4_fault}, + { "fan5_fault", &data_fan5_fault}, + { "fan6_fault", &data_fan6_fault}, + { "fan7_fault", &data_fan7_fault}, + { "fan8_fault", &data_fan8_fault}, + { "fan9_fault", &data_fan9_fault}, + { "fan10_fault", &data_fan10_fault}, + { "fan11_fault", &data_fan11_fault}, + { "fan12_fault", &data_fan12_fault}, +}; + +void *get_fan_access_data(char *name) +{ + int i=0; + for(i=0; i<(sizeof(fan_sysfs_attr_data_tbl)/sizeof(fan_sysfs_attr_data_tbl[0])); i++) + { + if(strcmp(name, fan_sysfs_attr_data_tbl[i].name) ==0) + { + return &fan_sysfs_attr_data_tbl[i]; + } + } + return NULL; +} +EXPORT_SYMBOL(get_fan_access_data); + + + +static int pddf_fan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct fan_data *data; + int status=0,i,num, j=0; + FAN_PDATA *fan_platform_data; + FAN_DATA_ATTR *data_attr; + FAN_SYSFS_ATTR_DATA_ENTRY *sysfs_data_entry; + char new_str[ATTR_NAME_LEN] = ""; + + if (client == NULL) { + printk("NULL Client.. \n"); + goto exit; + } + + if (pddf_fan_ops.pre_probe) + { + status = (pddf_fan_ops.pre_probe)(client, dev_id); + if (status != 0) + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + /* Add support for a pre probe function */ + data = kzalloc(sizeof(struct fan_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + dev_info(&client->dev, "chip found\n"); + + + /*Take control of the platform data*/ + fan_platform_data = (FAN_PDATA *)(client->dev.platform_data); + num = fan_platform_data->len; + data->num_attr = num; + + for (i=0;ifan_attrs + i; + sysfs_data_entry = get_fan_access_data(data_attr->aname); + if (sysfs_data_entry == NULL) + { + printk(KERN_ERR "%s: Wrong attribute name provided by user '%s'\n", __FUNCTION__, data_attr->aname); + continue; + } + + dy_ptr = (struct sensor_device_attribute *)kzalloc(sizeof(struct sensor_device_attribute)+ATTR_NAME_LEN, GFP_KERNEL); + dy_ptr->dev_attr.attr.name = (char *)&dy_ptr[1]; + strcpy((char *)dy_ptr->dev_attr.attr.name, data_attr->aname); + dy_ptr->dev_attr.attr.mode = sysfs_data_entry->a_ptr->mode; + dy_ptr->dev_attr.show = sysfs_data_entry->a_ptr->show; + dy_ptr->dev_attr.store = sysfs_data_entry->a_ptr->store; + dy_ptr->index = sysfs_data_entry->a_ptr->index; + + data->fan_attribute_list[i] = &dy_ptr->dev_attr.attr; + strcpy(data->attr_info[i].name, data_attr->aname); + data->attr_info[i].valid = 0; + mutex_init(&data->attr_info[i].update_lock); + + /*Create a duplicate entry*/ + get_fan_duplicate_sysfs(dy_ptr->index, new_str); + if (strcmp(new_str,"")) + { + dy_ptr = (struct sensor_device_attribute *)kzalloc(sizeof(struct sensor_device_attribute)+ATTR_NAME_LEN, GFP_KERNEL); + dy_ptr->dev_attr.attr.name = (char *)&dy_ptr[1]; + strcpy((char *)dy_ptr->dev_attr.attr.name, new_str); + dy_ptr->dev_attr.attr.mode = sysfs_data_entry->a_ptr->mode; + dy_ptr->dev_attr.show = sysfs_data_entry->a_ptr->show; + dy_ptr->dev_attr.store = sysfs_data_entry->a_ptr->store; + dy_ptr->index = sysfs_data_entry->a_ptr->index; + + data->fan_attribute_list[num+j] = &dy_ptr->dev_attr.attr; + j++; + strcpy(new_str, ""); + } + } + data->fan_attribute_list[i+j] = NULL; + data->fan_attribute_group.attrs = data->fan_attribute_list; + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &data->fan_attribute_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: fan '%s'\n", + dev_name(data->hwmon_dev), client->name); + + /* Add a support for post probe function */ + if (pddf_fan_ops.post_probe) + { + status = (pddf_fan_ops.post_probe)(client, dev_id); + if (status != 0) + goto exit_remove; + } + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->fan_attribute_group); +exit_free: + /* Free all the allocated attributes */ + for (i=0; data->fan_attribute_list[i]!=NULL; i++) + { + struct sensor_device_attribute *ptr = (struct sensor_device_attribute *)data->fan_attribute_list[i]; + kfree(ptr); + } + pddf_dbg(FAN, KERN_ERR "%s: Freed all the memory allocated for attributes\n", __FUNCTION__); + kfree(data); +exit: + return status; +} + +static int pddf_fan_remove(struct i2c_client *client) +{ + int i = 0, ret = 0; + struct sensor_device_attribute *ptr = NULL; + struct fan_data *data = i2c_get_clientdata(client); + FAN_PDATA *platdata = (FAN_PDATA *)client->dev.platform_data; + FAN_DATA_ATTR *platdata_sub = platdata->fan_attrs; + + if (pddf_fan_ops.pre_remove) + { + ret = (pddf_fan_ops.pre_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN pre_remove function failed\n"); + } + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->fan_attribute_group); + for (i=0; data->fan_attribute_list[i]!=NULL; i++) + { + ptr = (struct sensor_device_attribute *)data->fan_attribute_list[i]; + kfree(ptr); + } + pddf_dbg(FAN, KERN_ERR "%s: Freed all the memory allocated for attributes\n", __FUNCTION__); + kfree(data); + + if (platdata_sub) { + printk(KERN_DEBUG "%s: Freeing platform subdata\n", __FUNCTION__); + kfree(platdata_sub); + } + if (platdata) { + printk(KERN_DEBUG "%s: Freeing platform data\n", __FUNCTION__); + kfree(platdata); + } + + if (pddf_fan_ops.post_remove) + { + ret = (pddf_fan_ops.post_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN post_remove function failed\n"); + } + + return 0; +} + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static const struct i2c_device_id pddf_fan_id[] = { + { "fan_ctrl", 0 }, + { "fan_cpld", 1 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, pddf_fan_id); + +static struct i2c_driver pddf_fan_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .probe = pddf_fan_probe, + .remove = pddf_fan_remove, + .id_table = pddf_fan_id, + .address_list = normal_i2c, +}; + +static int __init pddf_fan_init(void) +{ + int status = 0; + + if (pddf_fan_ops.pre_init) + { + status = (pddf_fan_ops.pre_init)(); + if (status!=0) + return status; + } + + status = i2c_add_driver(&pddf_fan_driver); + if (status!=0) + return status; + + if (pddf_fan_ops.post_init) + { + status = (pddf_fan_ops.post_init)(); + if (status!=0) + return status; + } + return status; + +} + +static void __exit pddf_fan_exit(void) +{ + if (pddf_fan_ops.pre_exit) (pddf_fan_ops.pre_exit)(); + i2c_del_driver(&pddf_fan_driver); + if (pddf_fan_ops.post_exit) (pddf_fan_ops.post_exit)(); +} + +module_init(pddf_fan_init); +module_exit(pddf_fan_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("pddf_fan driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/fan/pddf_fan_module.c b/platform/pddf/i2c/modules/fan/pddf_fan_module.c new file mode 100644 index 000000000000..b910d6b4a351 --- /dev/null +++ b/platform/pddf/i2c/modules/fan/pddf_fan_module.c @@ -0,0 +1,280 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to create I2C client for FAN controller + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_fan_defs.h" + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern void *get_fan_access_data(char *); +extern void* get_device_table(char *name); +extern void delete_device_table(char *name); + +FAN_DATA fan_data = {0}; + + + +/* FAN CLIENT DATA */ +PDDF_DATA_ATTR(num_fantrays, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&fan_data.num_fantrays, NULL); + +PDDF_DATA_ATTR(attr_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&fan_data.fan_attr.aname, NULL); +PDDF_DATA_ATTR(attr_devtype, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&fan_data.fan_attr.devtype, NULL); +PDDF_DATA_ATTR(attr_devname, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&fan_data.fan_attr.devname, NULL); +PDDF_DATA_ATTR(attr_devaddr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&fan_data.fan_attr.devaddr, NULL); +PDDF_DATA_ATTR(attr_offset, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&fan_data.fan_attr.offset, NULL); +PDDF_DATA_ATTR(attr_mask, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&fan_data.fan_attr.mask, NULL); +PDDF_DATA_ATTR(attr_cmpval, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&fan_data.fan_attr.cmpval, NULL); +PDDF_DATA_ATTR(attr_len, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&fan_data.fan_attr.len, NULL); +PDDF_DATA_ATTR(attr_mult, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&fan_data.fan_attr.mult, NULL); +PDDF_DATA_ATTR(attr_is_divisor, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UCHAR, sizeof(unsigned char), (void*)&fan_data.fan_attr.is_divisor, NULL); +PDDF_DATA_ATTR(attr_ops, S_IWUSR, NULL, do_attr_operation, PDDF_CHAR, 8, (void*)&fan_data, NULL); +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&fan_data, (void*)&pddf_data); + + + +static struct attribute *fan_attributes[] = { + &attr_num_fantrays.dev_attr.attr, + &attr_attr_name.dev_attr.attr, + &attr_attr_devtype.dev_attr.attr, + &attr_attr_devname.dev_attr.attr, + &attr_attr_devaddr.dev_attr.attr, + &attr_attr_offset.dev_attr.attr, + &attr_attr_mask.dev_attr.attr, + &attr_attr_cmpval.dev_attr.attr, + &attr_attr_len.dev_attr.attr, + &attr_attr_mult.dev_attr.attr, + &attr_attr_is_divisor.dev_attr.attr, + &attr_attr_ops.dev_attr.attr, + &attr_dev_ops.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_fan_client_data_group = { + .attrs = fan_attributes, +}; + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + FAN_DATA *fdata = (FAN_DATA *)(ptr->addr); + FAN_SYSFS_ATTR_DATA_ENTRY *entry_ptr; + + + fdata->fan_attrs[fdata->len] = fdata->fan_attr; + entry_ptr = get_fan_access_data(fdata->fan_attrs[fdata->len].aname); + if (entry_ptr != NULL && entry_ptr->a_ptr != NULL) + { + fdata->fan_attrs[fdata->len].access_data = entry_ptr->a_ptr ; + } + + fdata->len++; + memset(&fdata->fan_attr, 0, sizeof(fdata->fan_attr)); + + + return count; +} + +struct i2c_board_info *i2c_get_fan_board_info(FAN_DATA *fdata, NEW_DEV_ATTR *cdata) +{ + int num = fdata->len; + int i = 0; + static struct i2c_board_info board_info; + FAN_PDATA *fan_platform_data; + + if (strcmp(cdata->dev_type, "fan_ctrl")==0 || + strcmp(cdata->dev_type, "fan_eeprom")==0 || + strcmp(cdata->dev_type, "fan_cpld")==0 ) + { + /* Allocate the fan_platform_data */ + fan_platform_data = (FAN_PDATA *)kzalloc(sizeof(FAN_PDATA), GFP_KERNEL); + fan_platform_data->fan_attrs = (FAN_DATA_ATTR *)kzalloc(num*sizeof(FAN_DATA_ATTR), GFP_KERNEL); + + + fan_platform_data->num_fantrays = fdata->num_fantrays; + fan_platform_data->len = fdata->len; + + for (i=0;ifan_attrs[i] = fdata->fan_attrs[i]; + } + + board_info = (struct i2c_board_info) { + .platform_data = fan_platform_data, + }; + + board_info.addr = cdata->dev_addr; + strcpy(board_info.type, cdata->dev_type); + } + else + { + printk(KERN_ERR "%s:Unknown type of device %s. Unable to create I2C client for it\n",__FUNCTION__, cdata->dev_type); + } + + return &board_info; +} + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + FAN_DATA *fdata = (FAN_DATA *)(ptr->addr); + NEW_DEV_ATTR *cdata = (NEW_DEV_ATTR *)(ptr->data); + struct i2c_adapter *adapter; + struct i2c_board_info *board_info; + struct i2c_client *client_ptr; + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + adapter = i2c_get_adapter(cdata->parent_bus); + board_info = i2c_get_fan_board_info(fdata, cdata); + + /* Populate the platform data for fan */ + client_ptr = i2c_new_device(adapter, board_info); + + if(client_ptr != NULL) + { + i2c_put_adapter(adapter); + pddf_dbg(FAN, KERN_ERR "Created a %s client: 0x%p\n", cdata->i2c_name, (void *)client_ptr); + add_device_table(cdata->i2c_name, (void*)client_ptr); + } + else + { + i2c_put_adapter(adapter); + goto free_data; + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(cdata->i2c_name); + if (client_ptr) + { + pddf_dbg(FAN, KERN_ERR "Removing %s client: 0x%p\n", cdata->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + delete_device_table(cdata->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", cdata->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + + goto clear_data; + +free_data: + if (board_info->platform_data) + { + FAN_PDATA *fan_platform_data = board_info->platform_data; + if (fan_platform_data->fan_attrs) + { + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform subdata\n", __FUNCTION__); + kfree(fan_platform_data->fan_attrs); + } + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform data\n", __FUNCTION__); + kfree(fan_platform_data); + } +clear_data: + memset(fdata, 0, sizeof(FAN_DATA)); + /*TODO: free the data cdata->data if data is dynal=mically allocated*/ + memset(cdata, 0, sizeof(NEW_DEV_ATTR)); + return count; +} + + +static struct kobject *fan_kobj; +static struct kobject *i2c_kobj; + +int __init pddf_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(FAN, "PDDF FAN MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + fan_kobj = kobject_create_and_add("fan", device_kobj); + if(!fan_kobj) + return -ENOMEM; + i2c_kobj = kobject_create_and_add("i2c", fan_kobj); + if(!i2c_kobj) + return -ENOMEM; + + ret = sysfs_create_group(i2c_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(i2c_kobj); + kobject_put(fan_kobj); + return ret; + } + pddf_dbg(FAN, "CREATED FAN I2C CLIENTS CREATION SYSFS GROUP\n"); + + ret = sysfs_create_group(i2c_kobj, &pddf_fan_client_data_group); + if (ret) + { + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(fan_kobj); + return ret; + } + pddf_dbg(FAN, "CREATED PDDF FAN DATA SYSFS GROUP\n"); + + + + return ret; +} + +void __exit pddf_data_exit(void) +{ + pddf_dbg(FAN, "PDDF FAN MODULE.. exit\n"); + sysfs_remove_group(i2c_kobj, &pddf_fan_client_data_group); + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(fan_kobj); + pddf_dbg(FAN, KERN_ERR "%s: Removed the kobjects for 'i2c' and 'fan'\n",__FUNCTION__); + return; +} + +module_init(pddf_data_init); +module_exit(pddf_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("fan platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/gpio/Makefile b/platform/pddf/i2c/modules/gpio/Makefile new file mode 100644 index 000000000000..6d48c5884731 --- /dev/null +++ b/platform/pddf/i2c/modules/gpio/Makefile @@ -0,0 +1,4 @@ + +obj-m := pddf_gpio_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/gpio/pddf_gpio_module.c b/platform/pddf/i2c/modules/gpio/pddf_gpio_module.c new file mode 100644 index 000000000000..afd37c3927df --- /dev/null +++ b/platform/pddf/i2c/modules/gpio/pddf_gpio_module.c @@ -0,0 +1,223 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * PDDF generic kernle module to create the I2C client for pca955x type of GPIO module + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_gpio_defs.h" + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern void* get_device_table(char *name); +extern void delete_device_table(char *name); + +static int base_gpio_num = 0xf0; +GPIO_DATA gpio_data = {0}; + +/* GPIO CLIENT DATA */ +PDDF_DATA_ATTR(gpio_base, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&gpio_data.gpio_base, NULL); +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&gpio_data, (void*)&pddf_data); + + + +static struct attribute *gpio_attributes[] = { + &attr_gpio_base.dev_attr.attr, + &attr_dev_ops.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_gpio_client_data_group = { + .attrs = gpio_attributes, +}; + + +struct i2c_board_info *i2c_get_gpio_board_info(GPIO_DATA* mdata, NEW_DEV_ATTR *device_data) +{ + static struct i2c_board_info board_info; + struct pca953x_platform_data *gpio_platform_data=NULL; + int def_num_gpios, base; + + gpio_platform_data = (struct pca953x_platform_data *)kzalloc(sizeof (struct pca953x_platform_data), GFP_KERNEL); + + if (strncmp(device_data->dev_type, "pca9554", strlen("pca9554")) == 0 || + strncmp(device_data->dev_type, "pca9534", strlen("pca9534")) == 0 || + strncmp(device_data->dev_type, "pca9538", strlen("pca9538")) == 0) + def_num_gpios = 0x8; + else if (strncmp(device_data->dev_type, "pca9555", strlen("pca9555")) == 0 || + strncmp(device_data->dev_type, "pca9535", strlen("pca9535")) == 0 || + strncmp(device_data->dev_type, "pca9539", strlen("pca9539")) == 0 || + strncmp(device_data->dev_type, "pca9575", strlen("pca9575")) == 0) + def_num_gpios = 0x10; + else if (strncmp(device_data->dev_type, "pca9698", strlen("pca9698")) == 0 || + strncmp(device_data->dev_type, "pca9505", strlen("pca9505")) == 0) + def_num_gpios = 0x28; + else + { + printk(KERN_ERR "%s: Unknown type of gpio device\n", __FUNCTION__); + return NULL; + } + + if(mdata->gpio_base == 0) { + base = base_gpio_num; + base_gpio_num += def_num_gpios; + } + else { + base = mdata->gpio_base; + } + + gpio_platform_data->gpio_base = base; + + board_info = (struct i2c_board_info) { + .platform_data = gpio_platform_data, + }; + + board_info.addr = device_data->dev_addr; + strcpy(board_info.type, device_data->dev_type); + + return &board_info; +} + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + GPIO_DATA *gpio_ptr = (GPIO_DATA *)(ptr->addr); + NEW_DEV_ATTR *device_ptr = (NEW_DEV_ATTR *)(ptr->data); + struct i2c_adapter *adapter; + struct i2c_board_info *board_info; + struct i2c_client *client_ptr; + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + adapter = i2c_get_adapter(device_ptr->parent_bus); + board_info = i2c_get_gpio_board_info(gpio_ptr, device_ptr); + + /*pddf_dbg(KERN_ERR "Creating a client %s on 0x%x, platform_data 0x%x\n", board_info->type, board_info->addr, board_info->platform_data);*/ + client_ptr = i2c_new_device(adapter, board_info); + + i2c_put_adapter(adapter); + if (client_ptr != NULL) + { + pddf_dbg(GPIO, KERN_ERR "Created %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + add_device_table(device_ptr->i2c_name, (void*)client_ptr); + } + else + { + kfree(board_info); + goto free_data; + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(device_ptr->i2c_name); + if (client_ptr) + { + struct pca953x_platform_data *gpio_platform_data = (struct pca953x_platform_data *)client_ptr->dev.platform_data; + pddf_dbg(GPIO, KERN_ERR "Removing %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + /*TODO: Nullyfy the platform data*/ + if (gpio_platform_data) + kfree(gpio_platform_data); + delete_device_table(device_ptr->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", device_ptr->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + +free_data: + memset(gpio_ptr, 0, sizeof(GPIO_DATA)); + /*TODO: free the device_ptr->data is dynamically allocated*/ + memset(device_ptr, 0 , sizeof(NEW_DEV_ATTR)); + + return count; +} + + +static struct kobject *gpio_kobj; + +int __init gpio_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(GPIO, "GPIO_DATA MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + gpio_kobj = kobject_create_and_add("gpio", device_kobj); + if(!gpio_kobj) + return -ENOMEM; + + + ret = sysfs_create_group(gpio_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(gpio_kobj); + return ret; + } + pddf_dbg(GPIO, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + + ret = sysfs_create_group(gpio_kobj, &pddf_gpio_client_data_group); + if (ret) + { + sysfs_remove_group(gpio_kobj, &pddf_clients_data_group); + kobject_put(gpio_kobj); + return ret; + } + pddf_dbg(GPIO, "CREATED GPIO DATA SYSFS GROUP\n"); + + return ret; +} + +void __exit gpio_data_exit(void) +{ + pddf_dbg(GPIO, "GPIO_DATA MODULE.. exit\n"); + sysfs_remove_group(gpio_kobj, &pddf_gpio_client_data_group); + sysfs_remove_group(gpio_kobj, &pddf_clients_data_group); + kobject_put(gpio_kobj); + pddf_dbg(GPIO, KERN_ERR "%s: Removed the kobjects for 'gpio'\n",__FUNCTION__); + return; +} + +module_init(gpio_data_init); +module_exit(gpio_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("gpio platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/include/pddf_client_defs.h b/platform/pddf/i2c/modules/include/pddf_client_defs.h new file mode 100644 index 000000000000..1c98a73e6eb6 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_client_defs.h @@ -0,0 +1,135 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform I2C client defines/structures header file + */ + +#ifndef __PDDF_CLIENT_DEFS_H__ +#define __PDDF_CLIENT_DEFS_H__ + +#include + +#define PSU "PDDF_PSU" +#define LED "PDDF_LED" +#define FAN "PDDF_FAN" +#define CLIENT "PDDF_CLIENT" +#define CPLD "PDDF_CPLD" +#define CPLDMUX "PDDF_CPLDMUX" +#define MUX "PDDF_MUX" +#define GPIO "PDDF_GPIO" +#define SYSSTATUS "PDDF_SYSSTATUS" +#define XCVR "PDDF_XCVR" + +#define PDDF_DEBUG +#ifdef PDDF_DEBUG +#define pddf_dbg(filter,...) printk("%s\t", filter); printk(KERN_CONT __VA_ARGS__) +#else +#define pddf_dbg(...) +#endif + + +#define GEN_NAME_SIZE 32 +#define ERR_STR_SIZE 128 + + +typedef struct pddf_data_attribute{ + struct device_attribute dev_attr; + int type; + int len; + char *addr; + char *data; +}PDDF_ATTR; + +#define PDDF_DATA_ATTR(_name, _mode, _show, _store, _type, _len, _addr, _data) \ + struct pddf_data_attribute attr_##_name = { .dev_attr = __ATTR(_name, _mode, _show, _store), \ + .type = _type , \ + .len = _len , \ + .addr = _addr, \ + .data = _data } + + +enum attribute_data_type { + PDDF_CHAR, + PDDF_UCHAR, + PDDF_INT_HEX, // integer represented in HEX + PDDF_INT_DEC, // integer represented in DECIMAL + PDDF_USHORT, // HEX + PDDF_UINT32 // HEX +}; + + + + + +// PSU Specific details + +typedef struct NEW_DEV_ATTR +{ + char i2c_type[GEN_NAME_SIZE]; + char i2c_name[GEN_NAME_SIZE]; + int parent_bus; + char dev_type[GEN_NAME_SIZE]; + int dev_id; + int dev_addr; + char *data; + int error; + char errstr[ERR_STR_SIZE]; + +}NEW_DEV_ATTR; +extern NEW_DEV_ATTR pddf_data; + +extern struct attribute_group pddf_clients_data_group; +extern ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, char *buf); +struct kobject* get_device_i2c_kobj(void); +void set_attr_data(void * ptr); +void set_error_code(int, char *); +ssize_t show_error_code(struct device *dev, struct device_attribute *da, char *buf); +ssize_t show_all_devices(struct device *dev, struct device_attribute *da, char *buf); +void traverse_device_table(void ); + + + +/*Various Ops hook which can be used by vendors to provide some deviation from usual pddf functionality*/ +struct pddf_ops_t +{ + /*Module init ops*/ + int (*pre_init)(void); + int (*post_init)(void); + /*probe ops*/ + int (*pre_probe)(struct i2c_client *, const struct i2c_device_id *); + int (*post_probe)(struct i2c_client *, const struct i2c_device_id *); + /*remove ops*/ + int (*pre_remove)(struct i2c_client *); + int (*post_remove)(struct i2c_client *); + /*Module exit ops*/ + void (*pre_exit)(void); + void (*post_exit)(void); +}; + + +typedef struct PDEVICE +{ + struct hlist_node node; + char name[GEN_NAME_SIZE]; + void *data; + +}PDEVICE; + +void add_device_table(char *name, void *ptr); + + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_cpld_defs.h b/platform/pddf/i2c/modules/include/pddf_cpld_defs.h new file mode 100644 index 000000000000..c312f3277f75 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_cpld_defs.h @@ -0,0 +1,31 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform CPLD defines/structures header file + */ + +#ifndef __PDDF_CPLD_DEFS_H__ +#define __PDDF_CPLD_DEFS_H__ + +/* CPLD DATA - DATA FOR CPLD CLIENT READ/WRITE*/ +typedef struct CPLD_DATA +{ + struct mutex cpld_lock; + uint16_t reg_addr; +}PDDF_CPLD_DATA; + + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_cpldmux_defs.h b/platform/pddf/i2c/modules/include/pddf_cpldmux_defs.h new file mode 100644 index 000000000000..ab2aa901c884 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_cpldmux_defs.h @@ -0,0 +1,76 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform CPLDMUX defines/structures header file + */ + +#ifndef __PDDF_CPLDMUX_DEFS_H__ +#define __PDDF_CPLDMUX_DEFS_H__ + +#include + +#define MAX_CPLDMUX_CHAN 64 + +typedef struct CPLDMUX_CHAN_DATA +{ + int chan_num; + char chan_device[128]; /* Could be multiple devices, mentioned as " " seperated array */ + int cpld_devaddr; + int cpld_offset; + int cpld_sel; + int cpld_desel; +}PDDF_CPLDMUX_CHAN_DATA; + +/* CPLDMUX DATA - DATA FOR CPLDMUX CLIENT*/ +typedef struct CPLDMUX_DATA +{ + int base_chan; + int num_chan; + int chan_cache; + uint32_t cpld_addr; + char cpld_name[32]; + PDDF_CPLDMUX_CHAN_DATA chan_data[MAX_CPLDMUX_CHAN]; +}PDDF_CPLDMUX_DATA; + +typedef struct CPLDMUX_PDATA +{ + int parent_bus; + int base_chan; + int num_chan; + int chan_cache; + struct i2c_client *cpld; + PDDF_CPLDMUX_CHAN_DATA *chan_data; +}PDDF_CPLDMUX_PDATA; + +typedef struct CPLDMUX_PRIV_DATA{ + struct i2c_adapter *parent; + uint32_t last_chan; /* Will be used in case channel caching is enabled */ + PDDF_CPLDMUX_PDATA data; +}PDDF_CPLDMUX_PRIV_DATA; + +typedef struct pldmux_ops_t +{ + int (*select)(struct i2c_mux_core *muxc, uint32_t chan); + int (*deselect)(struct i2c_mux_core *muxc, uint32_t chan); +}PDDF_CPLDMUX_OPS; + +int pddf_cpldmux_select_default(struct i2c_mux_core *muxc, uint32_t chan); +int pddf_cpldmux_deselect_default(struct i2c_mux_core *muxc, uint32_t chan); + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_fan_api.h b/platform/pddf/i2c/modules/include/pddf_fan_api.h new file mode 100644 index 000000000000..45b7751ccd43 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_fan_api.h @@ -0,0 +1,37 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Description + * FAN driver api declarations + */ + +#ifndef __PDDF_FAN_API_H__ +#define __PDDF_FAN_API_H__ + +extern int pddf_fan_post_probe_default(struct i2c_client *client, const struct i2c_device_id *dev_id); + +extern void get_fan_duplicate_sysfs(int idx, char *str); +extern ssize_t fan_show_default(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t fan_store_default(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + + +extern int sonic_i2c_get_fan_present_default(void *client, FAN_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_fan_rpm_default(void *client, FAN_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_fan_direction_default(void *client, FAN_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_fan_pwm_default(void *client, FAN_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_fan_fault_default(void *client, FAN_DATA_ATTR *adata, void *data); +extern int sonic_i2c_set_fan_pwm_default(void *client, FAN_DATA_ATTR *adata, void *data); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_fan_defs.h b/platform/pddf/i2c/modules/include/pddf_fan_defs.h new file mode 100644 index 000000000000..7765e5446293 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_fan_defs.h @@ -0,0 +1,91 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform FAN defines/structures header file + */ + +#ifndef __PDDF_FAN_DEFS_H__ +#define __PDDF_FAN_DEFS_H__ + + +#define MAX_NUM_FAN 6 +#define MAX_FAN_ATTRS 128 +#define ATTR_NAME_LEN 32 +#define STR_ATTR_SIZE 32 +#define DEV_TYPE_LEN 32 + +/* Each client has this additional data + */ + +typedef struct FAN_DATA_ATTR +{ + char aname[ATTR_NAME_LEN]; // attr name, taken from enum fan_sysfs_attributes + char devtype[DEV_TYPE_LEN]; // Type of FAN controller, i.e EMC2305, EMC2302, or FAN-CPLD etc + char devname[DEV_TYPE_LEN]; // Name of the device from where this informatin is to be read + uint32_t devaddr; + uint32_t offset; + uint32_t mask; + uint32_t cmpval; + uint32_t len; + int mult; // Multiplication factor to get the actual data + uint8_t is_divisor; // Check if the value is a divisor and mult is dividend + void *access_data; + +}FAN_DATA_ATTR; + + +typedef struct FAN_SYSFS_ATTR_DATA +{ + int index; + unsigned short mode; + ssize_t (*show)(struct device *dev, struct device_attribute *da, char *buf); + int (*pre_get)(void *client, FAN_DATA_ATTR *adata, void *data); + int (*do_get)(void *client, FAN_DATA_ATTR *adata, void *data); + int (*post_get)(void *client, FAN_DATA_ATTR *adata, void *data); + ssize_t (*store)(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + int (*pre_set)(void *client, FAN_DATA_ATTR *adata, void *data); + int (*do_set)(void *client, FAN_DATA_ATTR *adata, void *data); + int (*post_set)(void *client, FAN_DATA_ATTR *adata, void *data); + void *data; +} FAN_SYSFS_ATTR_DATA; + +typedef struct FAN_SYSFS_ATTR_DATA_ENTRY +{ + char name[ATTR_NAME_LEN]; + FAN_SYSFS_ATTR_DATA *a_ptr; +} FAN_SYSFS_ATTR_DATA_ENTRY; + + +/* FAN CLIENT DATA - PLATFORM DATA FOR FAN CLIENT */ +typedef struct FAN_DATA +{ + int num_fantrays; // num of fans controlled by this fan client + FAN_DATA_ATTR fan_attr; + int len; // no of valid attributes for this fan client + FAN_DATA_ATTR fan_attrs[MAX_FAN_ATTRS]; +}FAN_DATA; + +typedef struct FAN_PDATA +{ + int num_fantrays; // num of fans controlled by this fan client + int len; // no of valid attributes for this fan client + FAN_DATA_ATTR *fan_attrs; +}FAN_PDATA; + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_fan_driver.h b/platform/pddf/i2c/modules/include/pddf_fan_driver.h new file mode 100644 index 000000000000..8404db20786a --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_fan_driver.h @@ -0,0 +1,107 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * FAN driver related data structures + */ +#ifndef __PDDF_FAN_DRIVER_H__ +#define __PDDF_FAN_DRIVER_H__ + +enum fan_sysfs_attributes { + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN5_PRESENT, + FAN6_PRESENT, + FAN7_PRESENT, + FAN8_PRESENT, + FAN9_PRESENT, + FAN10_PRESENT, + FAN11_PRESENT, + FAN12_PRESENT, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, + FAN6_DIRECTION, + FAN7_DIRECTION, + FAN8_DIRECTION, + FAN9_DIRECTION, + FAN10_DIRECTION, + FAN11_DIRECTION, + FAN12_DIRECTION, + FAN1_INPUT, + FAN2_INPUT, + FAN3_INPUT, + FAN4_INPUT, + FAN5_INPUT, + FAN6_INPUT, + FAN7_INPUT, + FAN8_INPUT, + FAN9_INPUT, + FAN10_INPUT, + FAN11_INPUT, + FAN12_INPUT, + FAN1_PWM, + FAN2_PWM, + FAN3_PWM, + FAN4_PWM, + FAN5_PWM, + FAN6_PWM, + FAN7_PWM, + FAN8_PWM, + FAN9_PWM, + FAN10_PWM, + FAN11_PWM, + FAN12_PWM, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN6_FAULT, + FAN7_FAULT, + FAN8_FAULT, + FAN9_FAULT, + FAN10_FAULT, + FAN11_FAULT, + FAN12_FAULT, + FAN_MAX_ATTR +}; +/* Each client has this additional data */ +struct fan_attr_info { + char name[ATTR_NAME_LEN]; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + union { + char strval[STR_ATTR_SIZE]; + int intval; + u16 shortval; + u8 charval; + }val; +}; + +struct fan_data { + struct device *hwmon_dev; + int num_attr; + struct attribute *fan_attribute_list[MAX_FAN_ATTRS]; + struct attribute_group fan_attribute_group; + struct fan_attr_info attr_info[MAX_FAN_ATTRS]; +}; + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_gpio_defs.h b/platform/pddf/i2c/modules/include/pddf_gpio_defs.h new file mode 100644 index 000000000000..a8ee00189bce --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_gpio_defs.h @@ -0,0 +1,30 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform GPIO defines/structures header file + */ + +#ifndef __PAL_GPIO_DEFS_H__ +#define __PAL_GPIO_DEFS_H__ + +#include +/* GPIO CLIENT DATA*/ +typedef struct GPIO_DATA +{ + int gpio_base; // base bus number of the gpio pins +}GPIO_DATA; + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_led_defs.h b/platform/pddf/i2c/modules/include/pddf_led_defs.h new file mode 100644 index 000000000000..1603f8c5af8e --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_led_defs.h @@ -0,0 +1,120 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * Platform LED related defines and structures + */ + + +/***************************************** + * kobj list + *****************************************/ + +struct kobject *platform_kobj=NULL; +struct kobject *led_kobj=NULL; + +struct kobject *state_attr_kobj=NULL; +struct kobject *cur_state_kobj=NULL; + +/***************************************** + * Static Data provided from user + * space JSON data file + *****************************************/ +#define NAME_SIZE 32 +typedef enum { + STATUS_LED_COLOR_GREEN, + STATUS_LED_COLOR_GREEN_BLINK, + STATUS_LED_COLOR_RED, + STATUS_LED_COLOR_RED_BLINK, + STATUS_LED_COLOR_AMBER, + STATUS_LED_COLOR_AMBER_BLINK, + STATUS_LED_COLOR_BLUE, + STATUS_LED_COLOR_BLUE_BLINK, + STATUS_LED_COLOR_OFF, + MAX_LED_STATUS +}LED_STATUS; + +char* LED_STATUS_STR[] = { + "STATUS_LED_COLOR_GREEN", + "STATUS_LED_COLOR_GREEN_BLINK", + "STATUS_LED_COLOR_RED", + "STATUS_LED_COLOR_RED_BLINK", + "STATUS_LED_COLOR_AMBER", + "STATUS_LED_COLOR_AMBER_BLINK", + "STATUS_LED_COLOR_BLUE", + "STATUS_LED_COLOR_BLUE_BLINK", + "STATUS_LED_COLOR_OFF" +}; + + +typedef struct +{ + char bits[NAME_SIZE]; + int pos; + int mask_bits; +}MASK_BITS; + +typedef struct +{ + int swpld_addr; + int swpld_addr_offset; + MASK_BITS bits; + unsigned short value; +} LED_DATA; + +typedef struct +{ + int state; + char color[NAME_SIZE]; +} CUR_STATE_DATA; + +typedef struct +{ + CUR_STATE_DATA cur_state; + char device_name[NAME_SIZE]; + int index; + LED_DATA data[MAX_LED_STATUS]; + int swpld_addr; + int swpld_addr_offset; +} LED_OPS_DATA; + +typedef enum{ + LED_SYS, + LED_PSU, + LED_FAN, + LED_FANTRAY, + LED_DIAG, + LED_LOC, + LED_TYPE_MAX +} LED_TYPE; +char* LED_TYPE_STR[LED_TYPE_MAX] = +{ + "LED_SYS", + "LED_PSU", + "LED_FAN", + "LED_FANTRAY", + "LED_DIAG", + "LED_LOC", +}; + +/***************************************** + * Data exported from kernel for + * user space plugin to get/set + *****************************************/ +#define PDDF_LED_DATA_ATTR( _prefix, _name, _mode, _show, _store, _type, _len, _addr) \ + struct pddf_data_attribute pddf_dev_##_prefix##_attr_##_name = { .dev_attr = __ATTR(_name, _mode, _show, _store), \ + .type = _type , \ + .len = _len , \ + .addr = _addr } diff --git a/platform/pddf/i2c/modules/include/pddf_mux_defs.h b/platform/pddf/i2c/modules/include/pddf_mux_defs.h new file mode 100644 index 000000000000..c58a00e972c6 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_mux_defs.h @@ -0,0 +1,31 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform MUX defines/structures header file + */ + +#ifndef __PAL_MUX_DEFS_H__ +#define __PAL_MUX_DEFS_H__ + +#include + +/* MUX CLIENT DATA - PLATFORM DATA FOR PSU CLIENT */ +typedef struct MUX_DATA +{ + int virt_bus; // Virtual base bus number of the mux channels +}MUX_DATA; + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_psu_api.h b/platform/pddf/i2c/modules/include/pddf_psu_api.h new file mode 100644 index 000000000000..762863f02845 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_psu_api.h @@ -0,0 +1,41 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * PSU driver related api declarations + */ + +#ifndef __PDDF_PSU_API_H__ +#define __PDDF_PSU_API_H__ + +extern void get_psu_duplicate_sysfs(int idx, char *str); +extern ssize_t psu_show_default(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t psu_store_default(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +extern int sonic_i2c_get_psu_present_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_power_good_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_model_name_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_mfr_id_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_serial_num_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_fan_dir_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_v_out_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_i_out_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_p_out_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_fan1_speed_rpm_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_temp1_input_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_v_in_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_i_in_default(void *client, PSU_DATA_ATTR *adata, void *data); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_psu_defs.h b/platform/pddf/i2c/modules/include/pddf_psu_defs.h new file mode 100644 index 000000000000..60e81a9f5878 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_psu_defs.h @@ -0,0 +1,90 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform PSU defines/structures header file + */ + +#ifndef __PDDF_PSU_DEFS_H__ +#define __PDDF_PSU_DEFS_H__ + + +#define MAX_NUM_PSU 5 +#define MAX_PSU_ATTRS 32 +#define ATTR_NAME_LEN 32 +#define STR_ATTR_SIZE 32 +#define DEV_TYPE_LEN 32 + +/* Each client has this additional data + */ + +typedef struct PSU_DATA_ATTR +{ + char aname[ATTR_NAME_LEN]; // attr name, taken from enum psu_sysfs_attributes + char devtype[DEV_TYPE_LEN]; // either a 'eeprom' or 'cpld', or 'pmbus' attribute + char devname[DEV_TYPE_LEN]; // Name of the device from where this sysfs attr is read + uint32_t devaddr; + uint32_t offset; + uint32_t mask; + uint32_t cmpval; + uint32_t len; + void *access_data; + +}PSU_DATA_ATTR; + +typedef struct PSU_SYSFS_ATTR_DATA +{ + int index; + unsigned short mode; + ssize_t (*show)(struct device *dev, struct device_attribute *da, char *buf); + int (*pre_get)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*do_get)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*post_get)(void *client, PSU_DATA_ATTR *adata, void *data); + ssize_t (*store)(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + int (*pre_set)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*do_set)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*post_set)(void *client, PSU_DATA_ATTR *adata, void *data); + void *data; +} PSU_SYSFS_ATTR_DATA; + +typedef struct PSU_SYSFS_ATTR_DATA_ENTRY +{ + char name[ATTR_NAME_LEN]; + PSU_SYSFS_ATTR_DATA *a_ptr; +} PSU_SYSFS_ATTR_DATA_ENTRY; + + +/* PSU CLIENT DATA - PLATFORM DATA FOR PSU CLIENT */ +typedef struct PSU_DATA +{ + int idx; // psu index + int num_psu_fans; + PSU_DATA_ATTR psu_attr; + int len; // no of valid attributes for this psu client + PSU_DATA_ATTR psu_attrs[MAX_PSU_ATTRS]; +}PSU_DATA; + +typedef struct PSU_PDATA +{ + int idx; // psu index + int num_psu_fans; // num of fans supported by the PSU + int len; // no of valid attributes for this psu client + PSU_DATA_ATTR *psu_attrs; +}PSU_PDATA; + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_psu_driver.h b/platform/pddf/i2c/modules/include/pddf_psu_driver.h new file mode 100644 index 000000000000..a2aa3f41d397 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_psu_driver.h @@ -0,0 +1,65 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * PSU driver data structures + */ +#ifndef __PDDF_PSU_DRIVER_H__ +#define __PDDF_PSU_DRIVER_H__ + +enum psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD, + PSU_MFR_ID, + PSU_SERIAL_NUM, + PSU_FAN_DIR, + PSU_V_OUT, + PSU_I_OUT, + PSU_P_OUT, /* This is in micro watts to comply with lm-sensors */ + PSU_FAN1_SPEED, + PSU_TEMP1_INPUT, + PSU_V_IN, + PSU_I_IN, + PSU_ATTR_MAX +}; + + +/* Every client has psu_data which is divided into per attribute data */ +struct psu_attr_info { + char name[ATTR_NAME_LEN]; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status; + union { + char strval[STR_ATTR_SIZE]; + int intval; + u16 shortval; + u8 charval; + }val; +}; +struct psu_data { + struct device *hwmon_dev; + u8 index; + int num_psu_fans; + int num_attr; + struct attribute *psu_attribute_list[MAX_PSU_ATTRS]; + struct attribute_group psu_attribute_group; + struct psu_attr_info attr_info[MAX_PSU_ATTRS]; +}; + + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_sysstatus_defs.h b/platform/pddf/i2c/modules/include/pddf_sysstatus_defs.h new file mode 100644 index 000000000000..fd23f214d204 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_sysstatus_defs.h @@ -0,0 +1,51 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * Platform system status module structures + */ + +#ifndef __PDDF_SYSSTATUS_DEFS_H__ +#define __PDDF_SYSSTATUS_DEFS_H__ + + +#define ATTR_NAME_LEN 32 +#define MAX_ATTRS 32 + + +/* SYSSTATUS CLIENT DATA - PLATFORM DATA FOR SYSSTATUS CLIENT */ +typedef struct SYSSTATUS_ADDR_ATTR +{ + char aname[ATTR_NAME_LEN]; // attr name + uint32_t devaddr; + uint32_t offset; + uint32_t mask; + uint32_t len; + +}SYSSTATUS_ADDR_ATTR; + + +typedef struct SYSSTATUS_DATA +{ + int len; + SYSSTATUS_ADDR_ATTR sysstatus_addr_attr; + SYSSTATUS_ADDR_ATTR sysstatus_addr_attrs[MAX_ATTRS]; + +}SYSSTATUS_DATA; + + + + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_xcvr_api.h b/platform/pddf/i2c/modules/include/pddf_xcvr_api.h new file mode 100644 index 000000000000..4a1ce00d5581 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_xcvr_api.h @@ -0,0 +1,44 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * Optics driver related api declarations + */ +#ifndef __PDDF_XCVR_API_H__ +#define __PDDF_XCVR_API_H__ + +extern int sonic_i2c_get_mod_pres(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_reset(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_intr_status(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_lpmode(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_rxlos(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_txdisable(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_txfault(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_set_mod_lpmode(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_set_mod_reset(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_set_mod_txdisable(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); + +extern ssize_t get_module_presence(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t get_module_reset(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t set_module_reset(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern ssize_t get_module_intr_status(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t get_module_lpmode(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t set_module_lpmode(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern ssize_t get_module_rxlos(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t get_module_txdisable(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t set_module_txdisable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern ssize_t get_module_txfault(struct device *dev, struct device_attribute *da, char *buf); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_xcvr_defs.h b/platform/pddf/i2c/modules/include/pddf_xcvr_defs.h new file mode 100644 index 000000000000..63de2eeae0c2 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_xcvr_defs.h @@ -0,0 +1,121 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform SFP defines/structures header file + */ + +#ifndef __PDDF_XCVR_DEFS_H__ +#define __PDDF_XCVR_DEFS_H__ + + +#define MAX_NUM_XCVR 5 +#define MAX_XCVR_ATTRS 20 + + +typedef struct XCVR_ATTR +{ + char aname[32]; // attr name, taken from enum xcvr_sysfs_attributes + char devtype[32]; // either a 'eeprom' or 'cpld', or 'pmbus' attribute + char devname[32]; // name of the device from where this sysfs is to be read + uint32_t devaddr; + uint32_t offset; + uint32_t mask; + uint32_t cmpval; + uint32_t len; + + int (*pre_access)(void *client, void *data); + int (*do_access)(void *client, void *data); + int (*post_access)(void *client, void *data); + +}XCVR_ATTR; + +/* XCVR CLIENT DATA - PLATFORM DATA FOR XCVR CLIENT */ +typedef struct XCVR_DATA +{ + int idx; // xcvr index + XCVR_ATTR xcvr_attr; + int len; // no of valid attributes for this xcvr client + XCVR_ATTR xcvr_attrs[MAX_XCVR_ATTRS]; +}XCVR_DATA; + +typedef struct XCVR_PDATA +{ + int idx; // xcvr index + unsigned short addr; // i2c address of the device + int len; // no of valid attributes for this xcvr client + XCVR_ATTR *xcvr_attrs; +}XCVR_PDATA; + + +#define BIT_INDEX(i) (1ULL << (i)) + +/* List of valid port types */ +typedef enum xcvr_port_type_e { + PDDF_PORT_TYPE_INVALID, + PDDF_PORT_TYPE_NOT_PRESENT, + PDDF_PORT_TYPE_SFP, + PDDF_PORT_TYPE_SFP_PLUS, + PDDF_PORT_TYPE_QSFP, + PDDF_PORT_TYPE_QSFP_PLUS, + PDDF_PORT_TYPE_QSFP28 +} xcvr_port_type_t; + +/* Each client has this additional data + */ +struct xcvr_data { + struct device *xdev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + int index; /* port index */ + xcvr_port_type_t port_type; + uint32_t modpres; + uint32_t reset; + uint32_t intr_status; + uint32_t lpmode; + uint32_t rxlos; + uint32_t txdisable; + uint32_t txfault; +}; + +typedef struct XCVR_SYSFS_ATTR_OPS +{ + int index; + ssize_t (*show)(struct device *dev, struct device_attribute *da, char *buf); + int (*pre_get)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); + int (*do_get)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); + int (*post_get)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); + ssize_t (*store)(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + int (*pre_set)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); + int (*do_set)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); + int (*post_set)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); +} XCVR_SYSFS_ATTR_OPS; + +enum xcvr_sysfs_attributes { + XCVR_PRESENT, + XCVR_RESET, + XCVR_INTR_STATUS, + XCVR_LPMODE, + XCVR_RXLOS, + XCVR_TXDISABLE, + XCVR_TXFAULT, + XCVR_ATTR_MAX +}; + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#endif diff --git a/platform/pddf/i2c/modules/led/Makefile b/platform/pddf/i2c/modules/led/Makefile new file mode 100644 index 000000000000..0c450ec70b4c --- /dev/null +++ b/platform/pddf/i2c/modules/led/Makefile @@ -0,0 +1,4 @@ +TARGET := pddf_led_module +obj-m := $(TARGET).o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/led/pddf_led_module.c b/platform/pddf/i2c/modules/led/pddf_led_module.c new file mode 100644 index 000000000000..362467e5ab98 --- /dev/null +++ b/platform/pddf/i2c/modules/led/pddf_led_module.c @@ -0,0 +1,659 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to manage various LEDs of a switch + */ + +#include +#include +#include +#include +#include +#include +#include "pddf_led_defs.h" +#include "pddf_client_defs.h" +#include +#include +#include + +#define DEBUG 0 +LED_OPS_DATA sys_led_ops_data[1]={0}; +LED_OPS_DATA* psu_led_ops_data=NULL; +LED_OPS_DATA diag_led_ops_data[1]= {0}; +LED_OPS_DATA fan_led_ops_data[1]= {0}; +LED_OPS_DATA loc_led_ops_data[1]= {0}; +LED_OPS_DATA* fantray_led_ops_data=NULL; +LED_OPS_DATA temp_data={0}; +LED_OPS_DATA* dev_list[LED_TYPE_MAX] = { + sys_led_ops_data, + NULL, + fan_led_ops_data, + NULL, + diag_led_ops_data, + loc_led_ops_data, +}; +int num_psus = 0; +int num_fantrays = 0; + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); +extern ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +static LED_STATUS find_state_index(const char* state_str) { + int index; + char *ptr = (char *)state_str; + while (*ptr && *ptr!= '\n' && *ptr !='\0') ptr++; + *ptr='\0'; + for ( index = 0; index < MAX_LED_STATUS; index++) { + /*int rc = strcmp(state_str, LED_STATUS_STR[index]) ;*/ + if (strcmp(state_str, LED_STATUS_STR[index]) == 0 ) { + return index; + } + } + return MAX_LED_STATUS; +} + +static LED_TYPE get_dev_type(char* name) +{ + LED_TYPE ret = LED_TYPE_MAX; + if(strcasecmp(name, "SYS_LED")==0) { + ret = LED_SYS; + } else if(strcasecmp(name, "FAN_LED")==0) { + ret = LED_FAN; + } else if(strstr(name, "PSU_LED")) { + ret = LED_PSU; + } else if(strcasecmp(name, "DIAG_LED")==0) { + ret = LED_DIAG; + } else if(strcasecmp(name, "LOC_LED")==0) { + ret = LED_LOC; + } else if(strstr(name, "FANTRAY_LED")) { + ret = LED_FANTRAY; + } +#if DEBUG > 1 + pddf_dbg(LED, KERN_INFO "LED get_dev_type: %s; %d\n", name, ret); +#endif + return (ret); +} +static int dev_index_check(LED_TYPE type, int index) +{ +#if DEBUG + pddf_dbg(LED, "dev_index_check: type:%s index:%d num_psus:%d num_fantrays:%d\n", + LED_TYPE_STR[type], index, num_psus, num_fantrays); +#endif + switch(type) + { + case LED_PSU: + if(index >= num_psus) return (-1); + break; + case LED_FANTRAY: + if(index >= num_fantrays) return (-1); + break; + default: + if(index >= 1) return (-1); + break; + } + return (0); +} + +static LED_OPS_DATA* find_led_ops_data(struct device_attribute *da) +{ + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; + LED_TYPE led_type; + if(!ptr || strlen(ptr->device_name)==0 ) return(NULL); + + + if((led_type=get_dev_type(ptr->device_name))==LED_TYPE_MAX) { + printk(KERN_ERR "PDDF_LED ERROR *%s Unsupported Led Type\n", __func__); + return(NULL); + } + if(dev_index_check(led_type, ptr->index)==-1) { + printk(KERN_ERR "PDDF_LED ERROR %s invalid index: %d for type:%s\n", __func__, ptr->index, ptr->device_name); + return(NULL); + } +#if DEBUG > 1 + pddf_dbg(LED, "find_led_ops_data: name:%s; index=%d tempAddr:%p actualAddr:%p\n", + ptr->device_name, ptr->index, ptr, dev_list[led_type]+ptr->index); +#endif + return (dev_list[led_type]+ptr->index); +} + +static void print_led_data(LED_OPS_DATA *ptr, LED_STATUS state) +{ + int i = 0; + if(!ptr) return ; + pddf_dbg(LED, KERN_INFO "Print %s index:%d num_psus:%d num_fantrays:%d ADDR=%p\n", + ptr->device_name, ptr->index, num_psus, num_fantrays, ptr); + pddf_dbg(LED, KERN_INFO "\tindex: %d\n", ptr->index); + pddf_dbg(LED, KERN_INFO "\tcur_state: %d; %s \n", ptr->cur_state.state, ptr->cur_state.color); + for (i = 0; i< MAX_LED_STATUS; i++) { + if(ptr->data[i].swpld_addr && (i == state || state == -1)) { + pddf_dbg(LED, KERN_INFO "\t\t[%s]: addr/offset:0x%x;0x%x color:%s; value:%x; mask_bits: 0x%x; pos:%d\n", + LED_STATUS_STR[i], + ptr->data[i].swpld_addr, ptr->data[i].swpld_addr_offset, + LED_STATUS_STR[i], ptr->data[i].value, ptr->data[i].bits.mask_bits, ptr->data[i].bits.pos); + } + } +} + +ssize_t get_status_led(struct device_attribute *da) +{ + int ret=0; + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* temp_data_ptr=(LED_OPS_DATA*)_ptr->addr; + LED_OPS_DATA* ops_ptr=find_led_ops_data(da); + uint32_t color_val=0, sys_val=0; + int state=0; + if (!ops_ptr) { + pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot find LED Ptr", __func__); + return (-1); + } + if (ops_ptr->swpld_addr == 0x0) { + pddf_dbg(LED, KERN_ERR "ERROR %s: device: %s %d not configured\n", __func__, + temp_data_ptr->device_name, temp_data_ptr->index); + return (-1); + } + sys_val = board_i2c_cpld_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + if (sys_val < 0) + return sys_val; + + strcpy(temp_data.cur_state.color, "None"); + for (state=0; statedata[state].bits.mask_bits); + if ((color_val ^ (ops_ptr->data[state].value<data[state].bits.pos))==0) { + strcpy(temp_data.cur_state.color, LED_STATUS_STR[state]); + } + } +#if DEBUG > 1 + pddf_dbg(LED, KERN_ERR "Get : %s:%d addr/offset:0x%x; 0x%x value=0x%x [%s]\n", + ops_ptr->device_name, ops_ptr->index, + ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, sys_val, + temp_data.cur_state.color); +#endif + + return(ret); +} + +ssize_t set_status_led(struct device_attribute *da) +{ + int ret=0; + uint32_t sys_val=0, new_val=0; + LED_STATUS cur_state = MAX_LED_STATUS; + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* temp_data_ptr=(LED_OPS_DATA*)_ptr->addr; + LED_OPS_DATA* ops_ptr=find_led_ops_data(da); + char* _buf=temp_data_ptr->cur_state.color; + + if (!ops_ptr) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: Cannot find LED Ptr", __func__); + return (-1); + } + if (ops_ptr->swpld_addr == 0x0) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: device: %s %d not configured\n", + __func__, ops_ptr->device_name, ops_ptr->index); + return (-1); + } + pddf_dbg(LED, KERN_ERR "%s: Set [%s;%d] color[%s]\n", __func__, + temp_data_ptr->device_name, temp_data_ptr->index, + temp_data_ptr->cur_state.color); + cur_state = find_state_index(_buf); + + if (cur_state == MAX_LED_STATUS) { + pddf_dbg(LED, KERN_ERR "ERROR %s: not supported: %s\n", _buf, __func__); + return (-1); + } + + if(ops_ptr->data[cur_state].swpld_addr != 0x0) { + sys_val = board_i2c_cpld_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + if (sys_val < 0) + return sys_val; + + new_val = (sys_val & ops_ptr->data[cur_state].bits.mask_bits) | + (ops_ptr->data[cur_state].value << ops_ptr->data[cur_state].bits.pos); + + } else { + pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d state %d; %s not configured\n",__func__, + ops_ptr->device_name, ops_ptr->index, cur_state, _buf); + return (-1); + } + + board_i2c_cpld_write(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, new_val); + pddf_dbg(LED, KERN_INFO "Set color:%s; 0x%x:0x%x sys_val:0x%x new_val:0x%x read:0x%x\n", + LED_STATUS_STR[cur_state], + ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, + sys_val, new_val, + ret = board_i2c_cpld_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset)); + if (ret < 0) + { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: Error %d in reading from cpld(0x%x) offset 0x%x\n", __FUNCTION__, ret, ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + return ret; + } + return(ret); +} + + +ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, + char *buf) +{ + int ret = 0; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + switch(ptr->type) + { + case PDDF_CHAR: + ret = sprintf(buf, "%s\n", ptr->addr); + break; + case PDDF_INT_DEC: + ret = sprintf(buf, "%d\n", *(int*)(ptr->addr)); + break; + case PDDF_INT_HEX: + ret = sprintf(buf, "0x%x\n", *(int*)(ptr->addr)); + break; + case PDDF_USHORT: + ret = sprintf(buf, "0x%x\n", *(unsigned short *)(ptr->addr)); + break; + case PDDF_UINT32: + ret = sprintf(buf, "0x%x\n", *(uint32_t *)(ptr->addr)); + break; + default: + break; + } +#if DEBUG > 1 + pddf_dbg(LED, "[ READ ] DATA ATTR PTR [%s] TYPE:%d, Value:[%s]\n", + ptr->dev_attr.attr.name, ptr->type, buf); +#endif + return ret; +} + +ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int ret = 0, num = 0; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + switch(ptr->type) + { + case PDDF_CHAR: + strncpy(ptr->addr, buf, strlen(buf)-1); // to discard newline char form buf + ptr->addr[strlen(buf)-1] = '\0'; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_CHAR VALUE:%s\n", + ptr->dev_attr.attr.name, ptr->addr); +#endif + break; + case PDDF_INT_DEC: + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(int *)(ptr->addr) = num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_DEC VALUE:%d\n", + ptr->dev_attr.attr.name, *(int *)(ptr->addr)); +#endif + break; + case PDDF_INT_HEX: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(int *)(ptr->addr) = num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_HEX VALUE:0x%x\n", + ptr->dev_attr.attr.name, *(int *)(ptr->addr)); +#endif + break; + case PDDF_USHORT: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(unsigned short *)(ptr->addr) = (unsigned short)num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_USHORT VALUE:%x\n", + ptr->dev_attr.attr.name, *(unsigned short *)(ptr->addr)); +#endif + break; + case PDDF_UINT32: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(uint32_t *)(ptr->addr) = (uint32_t)num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_UINT32 VALUE:%d\n", + ptr->dev_attr.attr.name, *(uint32_t *)(ptr->addr)); +#endif + break; + default: + break; + } + return count; +} + +static int load_led_ops_data(struct device_attribute *da, LED_STATUS state) +{ + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; + LED_TYPE led_type; + LED_OPS_DATA* ops_ptr=NULL; + if(!ptr || strlen(ptr->device_name)==0 ) { + pddf_dbg(LED, KERN_INFO "SYSTEM_LED: load_led_ops_data return -1 device_name:%s\n", ptr? ptr->device_name:"NULL"); + return(-1); + } + if(ptr->device_name) + { + pddf_dbg(LED, KERN_INFO "[%s]: load_led_ops_data: index=%d addr=0x%x;0x%x valu=0x%x\n", + ptr->device_name, ptr->index, ptr->swpld_addr, ptr->swpld_addr_offset, ptr->data[0].value); + } + if((led_type=get_dev_type(ptr->device_name))==LED_TYPE_MAX) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR *%s Unsupported Led Type\n", __func__); + return(-1); + } + if(dev_index_check(led_type, ptr->index)==-1) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s invalid index: %d for type:%d\n", __func__, ptr->index, led_type); + return(-1); + } + ops_ptr = dev_list[led_type]+ptr->index; + + memcpy(ops_ptr->device_name, ptr->device_name, sizeof(ops_ptr->device_name)); + ops_ptr->index = ptr->index; + memcpy(&ops_ptr->data[state], &ptr->data[0], sizeof(LED_DATA)); + ops_ptr->data[state].swpld_addr = ptr->swpld_addr; + ops_ptr->data[state].swpld_addr_offset = ptr->swpld_addr_offset; + ops_ptr->swpld_addr = ptr->swpld_addr; + ops_ptr->swpld_addr_offset = ptr->swpld_addr_offset; + + print_led_data(dev_list[led_type]+ptr->index, state); + + memset(ptr, 0, sizeof(LED_OPS_DATA)); + return (0); +} + +static int show_led_ops_data(struct device_attribute *da) +{ + LED_OPS_DATA* ops_ptr=find_led_ops_data(da); + print_led_data(ops_ptr, -1); + return(0); +} + +static int verify_led_ops_data(struct device_attribute *da) +{ + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; + LED_OPS_DATA* ops_ptr=find_led_ops_data(da); + + if(ops_ptr) + memcpy(ptr, ops_ptr, sizeof(LED_OPS_DATA)); + else + { + pddf_dbg(LED, "SYSTEM_LED: verify_led_ops_data: Failed to find ops_ptr name:%s; index=%d\n", ptr->device_name, ptr->index); + } + return (0); +} + + +ssize_t dev_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ +#if DEBUG + pddf_dbg(LED, KERN_INFO "dev_operation [%s]\n", buf); +#endif + if(strstr(buf, "STATUS_LED_COLOR")!= NULL) { + LED_STATUS index = find_state_index(buf); + if (index < MAX_LED_STATUS ) { + load_led_ops_data(da, index); + } else { + printk(KERN_ERR "PDDF_ERROR %s: Invalid state for dev_ops %s", __FUNCTION__, buf); + } + } + else if(strncmp(buf, "show", strlen("show"))==0 ) { + show_led_ops_data(da); + } + else if(strncmp(buf, "verify", strlen("verify"))==0 ) { + verify_led_ops_data(da); + } + else if(strncmp(buf, "get_status", strlen("get_status"))==0 ) { + get_status_led(da); + } + else if(strncmp(buf, "set_status", strlen("set_status"))==0 ) { + set_status_led(da); + } + else { + printk(KERN_ERR "PDDF_ERROR %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + return(count); +} + +ssize_t store_config_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int ret, num; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + if(strncmp(ptr->dev_attr.attr.name, "num_psus", strlen("num_psus"))==0 ) { + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(int *)(ptr->addr) = num; + if(psu_led_ops_data == NULL) { + if ((psu_led_ops_data = kzalloc(num * sizeof(LED_OPS_DATA), GFP_KERNEL)) == NULL) { + printk(KERN_ERR "PDDF_LED ERROR failed to allocate memory for PSU LED\n"); + return (count); + } + pddf_dbg(LED, "Allocate PSU LED Memory ADDR=%p\n", psu_led_ops_data); + dev_list[LED_PSU]=psu_led_ops_data; + } +#if DEBUG + pddf_dbg(LED, "[ WRITE ] ATTR CONFIG [%s] VALUE:%d; %d\n", + ptr->dev_attr.attr.name, num, num_psus); +#endif + return(count); + } + if(strncmp(ptr->dev_attr.attr.name, "num_fantrays", strlen("num_fantrays"))==0 ) { + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(int *)(ptr->addr) = num; + if (fantray_led_ops_data == NULL) { + if ((fantray_led_ops_data = kzalloc(num * sizeof(LED_OPS_DATA), GFP_KERNEL)) == NULL) { + printk(KERN_ERR "PDDF_LED ERROR failed to allocate memory for FANTRAY LED\n"); + return (count); + } + pddf_dbg(LED, "Allocate FanTray LED Memory ADDR=%p\n", fantray_led_ops_data); + dev_list[LED_FANTRAY]=fantray_led_ops_data; + } +#if DEBUG + pddf_dbg(LED, "[ WRITE ] ATTR CONFIG [%s] VALUE:%d; %d\n", + ptr->dev_attr.attr.name, num, num_fantrays); +#endif + return(count); + } + return (count); +} + +ssize_t store_bits_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int len = 0, num1 = 0, num2 = 0, i=0, rc1=0, rc2=0; + char mask=0xFF; + char *pptr=NULL; + char bits[NAME_SIZE]; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + MASK_BITS* bits_ptr=(MASK_BITS*)(ptr->addr); + strncpy(bits_ptr->bits, buf, strlen(buf)-1); // to discard newline char form buf + bits_ptr->bits[strlen(buf)-1] = '\0'; + if((pptr=strstr(buf,":")) != NULL) { + len=pptr-buf; + sprintf(bits, buf); + bits[len]='\0'; + rc1=kstrtoint(bits,16,&num1); + if (rc1==0) + { + sprintf(bits, ++pptr); + rc2=kstrtoint(bits,16,&num2); + if (rc2==0) + { + for (i=num2; i<=num1; i++) { + mask &= ~(1 << i); + } + bits_ptr->mask_bits = mask; + bits_ptr->pos = num2; + } + } + } else { + rc1=kstrtoint(buf,16,&num1); + if (rc1==0) + { + bits_ptr->mask_bits = mask & ~(1 << num1); + bits_ptr->pos = num1; + } + } +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR Bits [%s] VALUE:%s mask:0x%x; pos:0x%x\n", + ptr->dev_attr.attr.name, bits_ptr->bits, bits_ptr->mask_bits, bits_ptr->pos); +#endif + return (count); +} + +/************************************************************************** + * platform/ attributes + **************************************************************************/ +PDDF_LED_DATA_ATTR(platform, num_psus, S_IWUSR|S_IRUGO, show_pddf_data, + store_config_data, PDDF_INT_DEC, sizeof(int), (void*)&num_psus); +PDDF_LED_DATA_ATTR(platform, num_fantrays, S_IWUSR|S_IRUGO, show_pddf_data, + store_config_data, PDDF_INT_DEC, sizeof(int), (void*)&num_fantrays); + +struct attribute* attrs_platform[]={ + &pddf_dev_platform_attr_num_psus.dev_attr.attr, + &pddf_dev_platform_attr_num_fantrays.dev_attr.attr, + NULL, +}; +struct attribute_group attr_group_platform={ + .attrs = attrs_platform, +}; + +/************************************************************************** + * led/ attributes + **************************************************************************/ +PDDF_LED_DATA_ATTR(dev, device_name, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.device_name); +PDDF_LED_DATA_ATTR(dev, index, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&temp_data.index); +PDDF_LED_DATA_ATTR(dev, swpld_addr, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&temp_data.swpld_addr); +PDDF_LED_DATA_ATTR(dev, swpld_addr_offset, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&temp_data.swpld_addr_offset); +PDDF_LED_DATA_ATTR(dev, dev_ops , S_IWUSR, NULL, + dev_operation, PDDF_CHAR, NAME_SIZE, (void*)&temp_data); + +struct attribute* attrs_dev[]={ + &pddf_dev_dev_attr_device_name.dev_attr.attr, + &pddf_dev_dev_attr_index.dev_attr.attr, + &pddf_dev_dev_attr_swpld_addr.dev_attr.attr, + &pddf_dev_dev_attr_swpld_addr_offset.dev_attr.attr, + &pddf_dev_dev_attr_dev_ops.dev_attr.attr, + NULL, +}; +struct attribute_group attr_group_dev={ + .attrs = attrs_dev, +}; + +/************************************************************************** + * state_attr/ attributes + **************************************************************************/ +#define LED_DEV_STATE_ATTR_GROUP(name, func) \ + PDDF_LED_DATA_ATTR(name, bits, S_IWUSR|S_IRUGO, show_pddf_data, \ + store_bits_data, PDDF_CHAR, NAME_SIZE, func.bits.bits); \ + PDDF_LED_DATA_ATTR(name, value, S_IWUSR|S_IRUGO, show_pddf_data, \ + store_pddf_data, PDDF_USHORT, sizeof(unsigned short), func.value); \ + struct attribute* attrs_##name[]={ \ + &pddf_dev_##name##_attr_bits.dev_attr.attr, \ + &pddf_dev_##name##_attr_value.dev_attr.attr, \ + NULL, \ + }; \ + struct attribute_group attr_group_##name={ \ + .attrs = attrs_##name, \ + }; \ + + +LED_DEV_STATE_ATTR_GROUP(state_attr, (void*)&temp_data.data[0]) + +/************************************************************************** + * cur_state/ attributes + **************************************************************************/ +PDDF_LED_DATA_ATTR(cur_state, color, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.cur_state.color); + +struct attribute* attrs_cur_state[]={ + &pddf_dev_cur_state_attr_color.dev_attr.attr, + NULL, +}; +struct attribute_group attr_group_cur_state={ + .attrs = attrs_cur_state, +}; + +/*************************************************************************/ +#define KOBJ_FREE(obj) \ + if(obj) kobject_put(obj); \ + +void free_kobjs(void) +{ + KOBJ_FREE(cur_state_kobj) + KOBJ_FREE(state_attr_kobj) + KOBJ_FREE(led_kobj) + KOBJ_FREE(platform_kobj) +} + +int KBOJ_CREATE(char* name, struct kobject* parent, struct kobject** child) +{ + if (parent) { + *child = kobject_create_and_add(name, parent); + } else { + printk(KERN_ERR "PDDF_LED ERROR to create %s kobj; null parent\n", name); + free_kobjs(); + return (-ENOMEM); + } + return (0); +} + +int LED_DEV_ATTR_CREATE(struct kobject *kobj, const struct attribute_group *attr, const char* name) +{ + int status = sysfs_create_group(kobj, attr); + if(status) { + pddf_dbg(LED, KERN_ERR "Driver ERROR: sysfs_create %s failed rc=%d\n", name, status); + } + return (status); +} + + +static int __init led_init(void) { + struct kobject *device_kobj; + pddf_dbg(LED, KERN_INFO "PDDF GENERIC LED MODULE init..\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + KBOJ_CREATE("platform", device_kobj, &platform_kobj); + KBOJ_CREATE("led", device_kobj, &led_kobj); + KBOJ_CREATE("state_attr", led_kobj, &state_attr_kobj); + KBOJ_CREATE("cur_state", led_kobj, &cur_state_kobj); + + LED_DEV_ATTR_CREATE(platform_kobj, &attr_group_platform, "attr_group_platform"); + LED_DEV_ATTR_CREATE(led_kobj, &attr_group_dev, "attr_group_dev"); + LED_DEV_ATTR_CREATE(state_attr_kobj, &attr_group_state_attr, "attr_group_state_attr"); + LED_DEV_ATTR_CREATE(cur_state_kobj, &attr_group_cur_state, "attr_group_cur_state"); + return (0); +} + + +static void __exit led_exit(void) { + pddf_dbg(LED, "PDDF GENERIC LED MODULE exit..\n"); + free_kobjs(); + if(psu_led_ops_data) kfree(psu_led_ops_data); + if(fantray_led_ops_data) kfree(fantray_led_ops_data); +} + +module_init(led_init); +module_exit(led_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/mux/Makefile b/platform/pddf/i2c/modules/mux/Makefile new file mode 100644 index 000000000000..486e7033435f --- /dev/null +++ b/platform/pddf/i2c/modules/mux/Makefile @@ -0,0 +1,4 @@ + +obj-m := pddf_mux_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/mux/pddf_mux_module.c b/platform/pddf/i2c/modules/mux/pddf_mux_module.c new file mode 100644 index 000000000000..b0cd9e761ca7 --- /dev/null +++ b/platform/pddf/i2c/modules/mux/pddf_mux_module.c @@ -0,0 +1,211 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to create I2C client for pca954x type of multiplexer + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_mux_defs.h" + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern void* get_device_table(char *name); +extern void delete_device_table(char *name); + + +MUX_DATA mux_data = {0}; + +/* MUX CLIENT DATA */ +PDDF_DATA_ATTR(virt_bus, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&mux_data.virt_bus, NULL); +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&mux_data, (void*)&pddf_data); + + + +static struct attribute *mux_attributes[] = { + &attr_virt_bus.dev_attr.attr, + &attr_dev_ops.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_mux_client_data_group = { + .attrs = mux_attributes, +}; + +struct i2c_board_info *i2c_get_mux_board_info(MUX_DATA* mdata, NEW_DEV_ATTR *device_data) +{ + static struct i2c_board_info board_info; + static struct pca954x_platform_mode platform_modes[8]; + static struct pca954x_platform_data mux_platform_data; + int num_modes, i; + + if (strncmp(device_data->dev_type, "pca9548", strlen("pca9548")) == 0) + num_modes = 8; + else if (strncmp(device_data->dev_type, "pca9546", strlen("pca9546")) == 0) + num_modes = 6; + else + { + printk(KERN_ERR "%s: Unknown type of mux device\n", __FUNCTION__); + return NULL; + } + + for(i = 0; i < num_modes; i++) { + platform_modes[i] = (struct pca954x_platform_mode) { + .adap_id = (mdata->virt_bus + i), + .deselect_on_exit = 1, + }; + } + + mux_platform_data = (struct pca954x_platform_data) { + .modes = platform_modes, + .num_modes = num_modes, + }; + + board_info = (struct i2c_board_info) { + .platform_data = &mux_platform_data, + }; + + board_info.addr = device_data->dev_addr; + strcpy(board_info.type, device_data->dev_type); + + return &board_info; +} + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + MUX_DATA *mux_ptr = (MUX_DATA *)(ptr->addr); + NEW_DEV_ATTR *device_ptr = (NEW_DEV_ATTR *)(ptr->data); + struct i2c_adapter *adapter; + struct i2c_board_info *board_info; + struct i2c_client *client_ptr; + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + adapter = i2c_get_adapter(device_ptr->parent_bus); + board_info = i2c_get_mux_board_info(mux_ptr, device_ptr); + + client_ptr = i2c_new_device(adapter, board_info); + + if (client_ptr != NULL) + { + i2c_put_adapter(adapter); + pddf_dbg(MUX, KERN_ERR "Created %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + add_device_table(device_ptr->i2c_name, (void*)client_ptr); + } + else + { + i2c_put_adapter(adapter); + goto free_data; + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(device_ptr->i2c_name); + if (client_ptr) + { + pddf_dbg(MUX, KERN_ERR "Removing %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + /*TODO: Nullyfy the platform data*/ + delete_device_table(device_ptr->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", device_ptr->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + +free_data: + memset(mux_ptr, 0, sizeof(MUX_DATA)); + /*TODO: free the device_ptr->data is dynamically allocated*/ + memset(device_ptr, 0 , sizeof(NEW_DEV_ATTR)); + + return count; +} + + +static struct kobject *mux_kobj; + +int __init mux_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(MUX, "MUX_DATA MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + mux_kobj = kobject_create_and_add("mux", device_kobj); + if(!mux_kobj) + return -ENOMEM; + + + ret = sysfs_create_group(mux_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(mux_kobj); + return ret; + } + pddf_dbg(MUX, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + + ret = sysfs_create_group(mux_kobj, &pddf_mux_client_data_group); + if (ret) + { + sysfs_remove_group(mux_kobj, &pddf_clients_data_group); + kobject_put(mux_kobj); + return ret; + } + pddf_dbg(MUX, "CREATED MUX DATA SYSFS GROUP\n"); + + return ret; +} + +void __exit mux_data_exit(void) +{ + pddf_dbg(MUX, "MUX_DATA MODULE.. exit\n"); + sysfs_remove_group(mux_kobj, &pddf_mux_client_data_group); + sysfs_remove_group(mux_kobj, &pddf_clients_data_group); + kobject_put(mux_kobj); + pddf_dbg(MUX, KERN_ERR "%s: Removed the kobjects for 'mux'\n",__FUNCTION__); + return; +} + +module_init(mux_data_init); +module_exit(mux_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("mux platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/psu/Makefile b/platform/pddf/i2c/modules/psu/Makefile new file mode 100644 index 000000000000..04db30dfb48b --- /dev/null +++ b/platform/pddf/i2c/modules/psu/Makefile @@ -0,0 +1,4 @@ +subdir-m := driver +obj-m := pddf_psu_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/psu/driver/Makefile b/platform/pddf/i2c/modules/psu/driver/Makefile new file mode 100644 index 000000000000..86d508051382 --- /dev/null +++ b/platform/pddf/i2c/modules/psu/driver/Makefile @@ -0,0 +1,6 @@ +TARGET = pddf_psu_driver_module +obj-m := $(TARGET).o + +$(TARGET)-objs := pddf_psu_api.o pddf_psu_driver.o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/psu/driver/pddf_psu_api.c b/platform/pddf/i2c/modules/psu/driver/pddf_psu_api.c new file mode 100644 index 000000000000..b6b5e306a000 --- /dev/null +++ b/platform/pddf/i2c/modules/psu/driver/pddf_psu_api.c @@ -0,0 +1,707 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description of various APIs related to PSU component + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_psu_defs.h" +#include "pddf_psu_driver.h" + + +/*#define PSU_DEBUG*/ +#ifdef PSU_DEBUG +#define psu_dbg(...) printk(__VA_ARGS__) +#else +#define psu_dbg(...) +#endif + + +void get_psu_duplicate_sysfs(int idx, char *str) +{ + switch (idx) + { + case PSU_V_OUT: + strcpy(str, "in3_input"); + break; + case PSU_I_OUT: + strcpy(str, "curr2_input"); + break; + case PSU_P_OUT: + strcpy(str, "power2_input"); + break; + case PSU_FAN1_SPEED: + strcpy(str, "fan1_input"); + break; + case PSU_TEMP1_INPUT: + strcpy(str, "temp1_input"); + break; + default: + break; + } + + return; +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +int psu_update_hw(struct device *dev, struct psu_attr_info *info, PSU_DATA_ATTR *udata) +{ + int status = 0; + struct i2c_client *client = to_i2c_client(dev); + PSU_SYSFS_ATTR_DATA *sysfs_attr_data = NULL; + + + mutex_lock(&info->update_lock); + + sysfs_attr_data = udata->access_data; + if (sysfs_attr_data->pre_set != NULL) + { + status = (sysfs_attr_data->pre_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: pre_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + if (sysfs_attr_data->do_set != NULL) + { + status = (sysfs_attr_data->do_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: do_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + + } + if (sysfs_attr_data->post_set != NULL) + { + status = (sysfs_attr_data->post_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: post_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + + mutex_unlock(&info->update_lock); + + return 0; +} + + +int psu_update_attr(struct device *dev, struct psu_attr_info *data, PSU_DATA_ATTR *udata) +{ + int status = 0; + struct i2c_client *client = to_i2c_client(dev); + PSU_SYSFS_ATTR_DATA *sysfs_attr_data=NULL; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) + { + dev_dbg(&client->dev, "Starting update for %s\n", data->name); + + sysfs_attr_data = udata->access_data; + if (sysfs_attr_data->pre_get != NULL) + { + status = (sysfs_attr_data->pre_get)(client, udata, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + if (sysfs_attr_data->do_get != NULL) + { + status = (sysfs_attr_data->do_get)(client, udata, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + + } + if (sysfs_attr_data->post_get != NULL) + { + status = (sysfs_attr_data->post_get)(client, udata, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + return 0; +} + +ssize_t psu_show_default(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct psu_data *data = i2c_get_clientdata(client); + PSU_PDATA *pdata = (PSU_PDATA *)(client->dev.platform_data); + PSU_DATA_ATTR *usr_data = NULL; + struct psu_attr_info *sysfs_attr_info = NULL; + int i, status=0; + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + char new_str[ATTR_NAME_LEN] = ""; + PSU_SYSFS_ATTR_DATA *ptr = NULL; + + for (i=0;inum_attr;i++) + { + ptr = (PSU_SYSFS_ATTR_DATA *)pdata->psu_attrs[i].access_data; + get_psu_duplicate_sysfs(ptr->index , new_str); + if ( strcmp(attr->dev_attr.attr.name, pdata->psu_attrs[i].aname) == 0 || strcmp(attr->dev_attr.attr.name, new_str) == 0 ) + { + sysfs_attr_info = &data->attr_info[i]; + usr_data = &pdata->psu_attrs[i]; + strcpy(new_str, ""); + } + } + + if (sysfs_attr_info==NULL || usr_data==NULL) + { + printk(KERN_ERR "%s is not supported attribute for this client\n", attr->dev_attr.attr.name); + goto exit; + } + + psu_update_attr(dev, sysfs_attr_info, usr_data); + + switch(attr->index) + { + case PSU_PRESENT: + case PSU_POWER_GOOD: + status = sysfs_attr_info->val.intval; + return sprintf(buf, "%d\n", status); + break; + case PSU_MODEL_NAME: + case PSU_MFR_ID: + case PSU_SERIAL_NUM: + case PSU_FAN_DIR: + return sprintf(buf, "%s\n", sysfs_attr_info->val.strval); + break; + case PSU_V_OUT: + case PSU_I_OUT: + case PSU_V_IN: + case PSU_I_IN: + multiplier = 1000; + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent) * multiplier); + else + return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + + break; + case PSU_P_OUT: + multiplier = 1000000; + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent) * multiplier); + else + return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + + break; + case PSU_FAN1_SPEED: + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent)); + else + return sprintf(buf, "%d\n", (mantissa) / (1 << -exponent)); + + break; + case PSU_TEMP1_INPUT: + multiplier = 1000; + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent) * multiplier); + else + return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + + break; + default: + printk(KERN_ERR "%s: Unable to find attribute index for %s\n", __FUNCTION__, usr_data->aname); + goto exit; + } + +exit: + return sprintf(buf, "%d\n", status); +} + + +ssize_t psu_store_default(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct psu_data *data = i2c_get_clientdata(client); + PSU_PDATA *pdata = (PSU_PDATA *)(client->dev.platform_data); + PSU_DATA_ATTR *usr_data = NULL; + struct psu_attr_info *sysfs_attr_info = NULL; + int i; + + for (i=0;inum_attr;i++) + { + if (strcmp(data->attr_info[i].name, attr->dev_attr.attr.name) == 0 && strcmp(pdata->psu_attrs[i].aname, attr->dev_attr.attr.name) == 0) + { + sysfs_attr_info = &data->attr_info[i]; + usr_data = &pdata->psu_attrs[i]; + } + } + + if (sysfs_attr_info==NULL || usr_data==NULL) { + printk(KERN_ERR "%s is not supported attribute for this client\n", attr->dev_attr.attr.name); + goto exit; + } + + switch(attr->index) + { + /*No write attributes for now in PSU*/ + default: + goto exit; + } + + psu_update_hw(dev, sysfs_attr_info, usr_data); + +exit: + return count; +} + +int sonic_i2c_get_psu_present_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + int status = 0; + int val = 0; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + + + if (strncmp(adata->devtype, "cpld", strlen("cpld")) == 0) + { + val = board_i2c_cpld_read(adata->devaddr , adata->offset); + if (val < 0) + return val; + padata->val.intval = ((val & adata->mask) == adata->cmpval); + psu_dbg(KERN_ERR "%s: status_value = 0x%x\n", __FUNCTION__, padata->val.intval); + } + + return status; +} + +int sonic_i2c_get_psu_power_good_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + int status = 0; + int val = 0; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + + if (strncmp(adata->devtype, "cpld", strlen("cpld")) == 0) + { + val = board_i2c_cpld_read(adata->devaddr , adata->offset); + if (val < 0) + return val; + padata->val.intval = ((val & adata->mask) == adata->cmpval); + psu_dbg(KERN_ERR "%s: status_value = 0x%x\n", __FUNCTION__, padata->val.intval); + } + + return status; +} + +int sonic_i2c_get_psu_model_name_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + char model[32]=""; //temporary placeholder for model name + uint8_t offset = (uint8_t)adata->offset; + int data_len = adata->len; + + while (retry) + { + status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, model); + if (unlikely(status<0)) + { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + model[0] = '\0'; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read model name from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + model[data_len-1] = '\0'; + } + + if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0) + strncpy(padata->val.strval, model+1, data_len-1); + else + strncpy(padata->val.strval, model, data_len); + + psu_dbg(KERN_ERR "%s: status = %d, model_name : %s\n", __FUNCTION__, status, padata->val.strval); + return 0; +} + +int sonic_i2c_get_psu_mfr_id_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + char mfr_id[16] = ""; // temporary place holder for mfr_id + uint8_t offset = (uint8_t)adata->offset; + int data_len = adata->len; + + while (retry) + { + status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, mfr_id); + if (unlikely(status<0)) + { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + mfr_id[0] = '\0'; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read mfr_id from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + mfr_id[data_len-1] = '\0'; + } + + if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0) + strncpy(padata->val.strval, mfr_id+1, data_len-1); + else + strncpy(padata->val.strval, mfr_id, data_len); + + psu_dbg(KERN_ERR "%s: status = %d, mfr_id : %s\n", __FUNCTION__, status, padata->val.strval); + return 0; +} + +int sonic_i2c_get_psu_serial_num_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + char serial[32] = ""; // temporary string to store the serial num + uint8_t offset = (uint8_t)adata->offset; + int data_len = adata->len; + + while (retry) + { + status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, serial); + if (unlikely(status<0)) + { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + serial[0] = '\0'; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read serial num from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + serial[data_len-1] = '\0'; + } + + if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0) + strncpy(padata->val.strval, serial+1, data_len-1); + else + strncpy(padata->val.strval, serial, data_len); + + psu_dbg(KERN_ERR "%s: status = %d, serial_num : %s\n", __FUNCTION__, status, padata->val.strval); + return 0; +} + +int sonic_i2c_get_psu_fan_dir_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + char fan_dir[5] = ""; + uint8_t offset = (uint8_t)adata->offset; + int data_len = adata->len; + + while (retry) + { + status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, fan_dir); + if (unlikely(status<0)) + { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + fan_dir[0] = '\0'; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read fan_dir from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + fan_dir[data_len-1] = '\0'; + } + + if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0) + strncpy(padata->val.strval, fan_dir+1, data_len-1); + else + strncpy(padata->val.strval, fan_dir, data_len); + + psu_dbg(KERN_ERR "%s: status = %d, fan_dir : %s\n", __FUNCTION__, status, padata->val.strval); + return 0; +} + +int sonic_i2c_get_psu_v_out_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read v_out from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: v_out : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_i_out_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read i_out from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: i_out : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_p_out_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read p_out from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: p_out : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_v_in_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read v_in from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: v_in : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_i_in_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read i_in from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: i_in : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_fan1_speed_rpm_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read fan1_speed_rpm from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: fan1_speed_rpm : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_temp1_input_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read temp1_input from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: temp1_input : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} diff --git a/platform/pddf/i2c/modules/psu/driver/pddf_psu_driver.c b/platform/pddf/i2c/modules/psu/driver/pddf_psu_driver.c new file mode 100644 index 000000000000..ad71e45eca20 --- /dev/null +++ b/platform/pddf/i2c/modules/psu/driver/pddf_psu_driver.c @@ -0,0 +1,381 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module driver for PSU + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_psu_defs.h" +#include "pddf_psu_driver.h" +#include "pddf_psu_api.h" + + +static unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +struct pddf_ops_t pddf_psu_ops = { + .pre_init = NULL, + .post_init = NULL, + + .pre_probe = NULL, + .post_probe = NULL, + + .pre_remove = NULL, + .post_remove = NULL, + + .pre_exit = NULL, + .post_exit = NULL, +}; +EXPORT_SYMBOL(pddf_psu_ops); + + +PSU_SYSFS_ATTR_DATA access_psu_present = {PSU_PRESENT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_present_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_present); + +PSU_SYSFS_ATTR_DATA access_psu_model_name = {PSU_MODEL_NAME, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_model_name_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_model_name); + +PSU_SYSFS_ATTR_DATA access_psu_power_good = {PSU_POWER_GOOD, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_power_good_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_power_good); + +PSU_SYSFS_ATTR_DATA access_psu_mfr_id = {PSU_MFR_ID, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_mfr_id_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_mfr_id); + +PSU_SYSFS_ATTR_DATA access_psu_serial_num = {PSU_SERIAL_NUM, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_serial_num_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_serial_num); + +PSU_SYSFS_ATTR_DATA access_psu_fan_dir = {PSU_FAN_DIR, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_fan_dir_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_fan_dir); + +PSU_SYSFS_ATTR_DATA access_psu_v_out = {PSU_V_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_v_out_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_v_out); + +PSU_SYSFS_ATTR_DATA access_psu_i_out = {PSU_I_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_i_out_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_i_out); + +PSU_SYSFS_ATTR_DATA access_psu_p_out = {PSU_P_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_p_out_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_p_out); + +PSU_SYSFS_ATTR_DATA access_psu_fan1_speed_rpm = {PSU_FAN1_SPEED, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_fan1_speed_rpm_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_fan1_speed_rpm); + +PSU_SYSFS_ATTR_DATA access_psu_temp1_input = {PSU_TEMP1_INPUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_temp1_input_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_temp1_input); + +PSU_SYSFS_ATTR_DATA access_psu_v_in = {PSU_V_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_v_in_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_v_in); + +PSU_SYSFS_ATTR_DATA access_psu_i_in = {PSU_I_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_i_in_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_i_in); + + +PSU_SYSFS_ATTR_DATA_ENTRY psu_sysfs_attr_data_tbl[]= +{ + { "psu_present", &access_psu_present}, + { "psu_model_name", &access_psu_model_name}, + { "psu_power_good" , &access_psu_power_good}, + { "psu_mfr_id" , &access_psu_mfr_id}, + { "psu_serial_num" , &access_psu_serial_num}, + { "psu_fan_dir" , &access_psu_fan_dir}, + { "psu_v_out" , &access_psu_v_out}, + { "psu_i_out" , &access_psu_i_out}, + { "psu_p_out" , &access_psu_p_out}, + { "psu_fan1_speed_rpm" , &access_psu_fan1_speed_rpm}, + { "psu_temp1_input" , &access_psu_temp1_input}, + { "psu_v_in" , &access_psu_v_in}, + { "psu_i_in" , &access_psu_i_in} +}; + +void *get_psu_access_data(char *name) +{ + int i=0; + for(i=0; i<(sizeof(psu_sysfs_attr_data_tbl)/sizeof(psu_sysfs_attr_data_tbl[0])); i++) + { + if(strcmp(name, psu_sysfs_attr_data_tbl[i].name) ==0) + { + return &psu_sysfs_attr_data_tbl[i]; + } + } + return NULL; +} +EXPORT_SYMBOL(get_psu_access_data); + + +static int psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct psu_data *data; + int status =0; + int i,num, j=0; + PSU_PDATA *psu_platform_data; + PSU_DATA_ATTR *data_attr; + PSU_SYSFS_ATTR_DATA_ENTRY *sysfs_data_entry; + char new_str[ATTR_NAME_LEN] = ""; + + + if (client == NULL) { + printk("NULL Client.. \n"); + goto exit; + } + + if (pddf_psu_ops.pre_probe) + { + status = (pddf_psu_ops.pre_probe)(client, dev_id); + if (status != 0) + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + dev_info(&client->dev, "chip found\n"); + + /* Take control of the platform data */ + psu_platform_data = (PSU_PDATA *)(client->dev.platform_data); + num = psu_platform_data->len; + data->index = psu_platform_data->idx - 1; + data->num_psu_fans = psu_platform_data->num_psu_fans; + data->num_attr = num; + + + + /* Create and Add supported attr in the 'attributes' list */ + for (i=0; ipsu_attrs + i; + sysfs_data_entry = get_psu_access_data(data_attr->aname); + if (sysfs_data_entry == NULL) + { + printk(KERN_ERR "%s: Wrong attribute name provided by user '%s'\n", __FUNCTION__, data_attr->aname); + continue; + } + + dy_ptr = (struct sensor_device_attribute *)kzalloc(sizeof(struct sensor_device_attribute)+ATTR_NAME_LEN, GFP_KERNEL); + dy_ptr->dev_attr.attr.name = (char *)&dy_ptr[1]; + strcpy((char *)dy_ptr->dev_attr.attr.name, data_attr->aname); + dy_ptr->dev_attr.attr.mode = sysfs_data_entry->a_ptr->mode; + dy_ptr->dev_attr.show = sysfs_data_entry->a_ptr->show; + dy_ptr->dev_attr.store = sysfs_data_entry->a_ptr->store; + dy_ptr->index = sysfs_data_entry->a_ptr->index; + + data->psu_attribute_list[i] = &dy_ptr->dev_attr.attr; + strcpy(data->attr_info[i].name, data_attr->aname); + data->attr_info[i].valid = 0; + mutex_init(&data->attr_info[i].update_lock); + + /*Create a duplicate entry*/ + get_psu_duplicate_sysfs(dy_ptr->index, new_str); + if (strcmp(new_str,"")) + { + dy_ptr = (struct sensor_device_attribute *)kzalloc(sizeof(struct sensor_device_attribute)+ATTR_NAME_LEN, GFP_KERNEL); + dy_ptr->dev_attr.attr.name = (char *)&dy_ptr[1]; + strcpy((char *)dy_ptr->dev_attr.attr.name, new_str); + dy_ptr->dev_attr.attr.mode = sysfs_data_entry->a_ptr->mode; + dy_ptr->dev_attr.show = sysfs_data_entry->a_ptr->show; + dy_ptr->dev_attr.store = sysfs_data_entry->a_ptr->store; + dy_ptr->index = sysfs_data_entry->a_ptr->index; + + data->psu_attribute_list[num+j] = &dy_ptr->dev_attr.attr; + j++; + strcpy(new_str,""); + } + } + data->psu_attribute_list[i+j] = NULL; + data->psu_attribute_group.attrs = data->psu_attribute_list; + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &data->psu_attribute_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + /* Add a support for post probe function */ + if (pddf_psu_ops.post_probe) + { + status = (pddf_psu_ops.post_probe)(client, dev_id); + if (status != 0) + goto exit_remove; + } + + return 0; + + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->psu_attribute_group); +exit_free: + /* Free all the allocated attributes */ + for (i=0;data->psu_attribute_list[i]!=NULL;i++) + { + struct sensor_device_attribute *ptr = (struct sensor_device_attribute *)data->psu_attribute_list[i]; + kfree(ptr); + data->psu_attribute_list[i] = NULL; + pddf_dbg(PSU, KERN_ERR "%s: Freed all the memory allocated for attributes\n", __FUNCTION__); + } + kfree(data); +exit: + return status; +} + +static int psu_remove(struct i2c_client *client) +{ + int i=0, ret = 0; + struct psu_data *data = i2c_get_clientdata(client); + PSU_PDATA *platdata = (PSU_PDATA *)client->dev.platform_data; // use dev_get_platdata() + PSU_DATA_ATTR *platdata_sub = platdata->psu_attrs; + struct sensor_device_attribute *ptr = NULL; + + if (pddf_psu_ops.pre_remove) + { + ret = (pddf_psu_ops.pre_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN pre_remove function failed\n"); + } + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->psu_attribute_group); + for (i=0; data->psu_attribute_list[i]!=NULL; i++) + { + ptr = (struct sensor_device_attribute *)data->psu_attribute_list[i]; + kfree(ptr); + data->psu_attribute_list[i] = NULL; + } + pddf_dbg(PSU, KERN_ERR "%s: Freed all the memory allocated for attributes\n", __FUNCTION__); + kfree(data); + if (platdata_sub) { + printk(KERN_DEBUG "%s: Freeing platform subdata\n", __FUNCTION__); + kfree(platdata_sub); + } + if (platdata) { + printk(KERN_DEBUG "%s: Freeing platform data\n", __FUNCTION__); + kfree(platdata); + } + + if (pddf_psu_ops.post_remove) + { + ret = (pddf_psu_ops.post_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN post_remove function failed\n"); + } + + return ret; +} + +enum psu_intf +{ + eeprom_intf, + smbus_intf +}; + +static const struct i2c_device_id psu_id[] = { + {"psu_eeprom", eeprom_intf}, + {"psu_pmbus", smbus_intf}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, psu_id); + +static struct i2c_driver psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "psu", + }, + .probe = psu_probe, + .remove = psu_remove, + .id_table = psu_id, + .address_list = normal_i2c, +}; + +int example_fun(void) +{ + pddf_dbg(PSU, KERN_ERR "CALLING FUN...\n"); + return 0; +} +EXPORT_SYMBOL(example_fun); + + +int psu_init(void) +{ + int status = 0; + + if (pddf_psu_ops.pre_init) + { + status = (pddf_psu_ops.pre_init)(); + if (status!=0) + return status; + } + + pddf_dbg(PSU, KERN_ERR "GENERIC_PSU_DRIVER.. init Invoked..\n"); + status = i2c_add_driver(&psu_driver); + if (status!=0) + return status; + + if (pddf_psu_ops.post_init) + { + status = (pddf_psu_ops.post_init)(); + if (status!=0) + return status; + } + + return status; +} +EXPORT_SYMBOL(psu_init); + +void __exit psu_exit(void) +{ + pddf_dbg(PSU, "GENERIC_PSU_DRIVER.. exit\n"); + if (pddf_psu_ops.pre_exit) (pddf_psu_ops.pre_exit)(); + i2c_del_driver(&psu_driver); + if (pddf_psu_ops.post_exit) (pddf_psu_ops.post_exit)(); +} +EXPORT_SYMBOL(psu_exit); + +module_init(psu_init); +module_exit(psu_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("psu driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/psu/pddf_psu_module.c b/platform/pddf/i2c/modules/psu/pddf_psu_module.c new file mode 100644 index 000000000000..cf9713b407cd --- /dev/null +++ b/platform/pddf/i2c/modules/psu/pddf_psu_module.c @@ -0,0 +1,283 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to create I2C client for PSU + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_psu_defs.h" + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern void *get_psu_access_data(char *); +extern void* get_device_table(char *name); +extern void delete_device_table(char *name); + +PSU_DATA psu_data = {0}; + + + +/* PSU CLIENT DATA */ +PDDF_DATA_ATTR(psu_idx, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&psu_data.idx, NULL); +PDDF_DATA_ATTR(psu_fans, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&psu_data.num_psu_fans, NULL); + +PDDF_DATA_ATTR(attr_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&psu_data.psu_attr.aname, NULL); +PDDF_DATA_ATTR(attr_devtype, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&psu_data.psu_attr.devtype, NULL); +PDDF_DATA_ATTR(attr_devname, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&psu_data.psu_attr.devname, NULL); +PDDF_DATA_ATTR(attr_devaddr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&psu_data.psu_attr.devaddr, NULL); +PDDF_DATA_ATTR(attr_offset, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&psu_data.psu_attr.offset, NULL); +PDDF_DATA_ATTR(attr_mask, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&psu_data.psu_attr.mask, NULL); +PDDF_DATA_ATTR(attr_cmpval, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&psu_data.psu_attr.cmpval, NULL); +PDDF_DATA_ATTR(attr_len, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&psu_data.psu_attr.len, NULL); +PDDF_DATA_ATTR(attr_ops, S_IWUSR, NULL, do_attr_operation, PDDF_CHAR, 8, (void*)&psu_data, NULL); +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&psu_data, (void*)&pddf_data); + + + +static struct attribute *psu_attributes[] = { + &attr_psu_idx.dev_attr.attr, + &attr_psu_fans.dev_attr.attr, + + &attr_attr_name.dev_attr.attr, + &attr_attr_devtype.dev_attr.attr, + &attr_attr_devname.dev_attr.attr, + &attr_attr_devaddr.dev_attr.attr, + &attr_attr_offset.dev_attr.attr, + &attr_attr_mask.dev_attr.attr, + &attr_attr_cmpval.dev_attr.attr, + &attr_attr_len.dev_attr.attr, + &attr_attr_ops.dev_attr.attr, + &attr_dev_ops.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_psu_client_data_group = { + .attrs = psu_attributes, +}; + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + PSU_DATA *pdata = (PSU_DATA *)(ptr->addr); + PSU_SYSFS_ATTR_DATA_ENTRY *access_ptr; + + + pdata->psu_attrs[pdata->len] = pdata->psu_attr; + access_ptr = get_psu_access_data(pdata->psu_attrs[pdata->len].aname); + if (access_ptr != NULL && access_ptr->a_ptr != NULL) + { + pdata->psu_attrs[pdata->len].access_data = access_ptr->a_ptr ; + } + + + pdata->len++; + memset(&pdata->psu_attr, 0, sizeof(pdata->psu_attr)); + + + return count; +} + +struct i2c_board_info *i2c_get_psu_board_info(PSU_DATA *pdata, NEW_DEV_ATTR *cdata) +{ + int num = pdata->len; + int i = 0; + static struct i2c_board_info board_info; + PSU_PDATA *psu_platform_data; + + + if (strcmp(cdata->dev_type, "psu_pmbus")==0 || strcmp(cdata->dev_type, "psu_eeprom")==0 ) + { + /* Allocate the psu_platform_data */ + psu_platform_data = (PSU_PDATA *)kzalloc(sizeof(PSU_PDATA), GFP_KERNEL); + psu_platform_data->psu_attrs = (PSU_DATA_ATTR *)kzalloc(num*sizeof(PSU_DATA_ATTR), GFP_KERNEL); + + + psu_platform_data->idx = pdata->idx; + psu_platform_data->num_psu_fans = pdata->num_psu_fans; + psu_platform_data->len = pdata->len; + + for (i=0;ipsu_attrs[i] = pdata->psu_attrs[i]; + } + + board_info = (struct i2c_board_info) { + .platform_data = psu_platform_data, + }; + + board_info.addr = cdata->dev_addr; + strcpy(board_info.type, cdata->dev_type); + } + else + { + printk(KERN_ERR "%s:Unknown type of device %s. Unable to clreate I2C client for it\n",__FUNCTION__, cdata->dev_type); + } + + return &board_info; +} + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + PSU_DATA *pdata = (PSU_DATA *)(ptr->addr); + NEW_DEV_ATTR *cdata = (NEW_DEV_ATTR *)(ptr->data); + struct i2c_adapter *adapter; + struct i2c_board_info *board_info; + struct i2c_client *client_ptr; + + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + adapter = i2c_get_adapter(cdata->parent_bus); + board_info = i2c_get_psu_board_info(pdata, cdata); + + /* Populate the platform data for psu */ + client_ptr = i2c_new_device(adapter, board_info); + + if(client_ptr != NULL) + { + i2c_put_adapter(adapter); + pddf_dbg(PSU, KERN_ERR "Created a %s client: 0x%p\n", cdata->i2c_name , (void *)client_ptr); + add_device_table(cdata->i2c_name, (void*)client_ptr); + } + else + { + i2c_put_adapter(adapter); + goto free_data; + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(cdata->i2c_name); + if (client_ptr) + { + pddf_dbg(PSU, KERN_ERR "Removing %s client: 0x%p\n", cdata->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + delete_device_table(cdata->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", cdata->i2c_name); + } + + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + + goto clear_data; + +free_data: + if (board_info->platform_data) + { + PSU_PDATA *psu_platform_data = board_info->platform_data; + if (psu_platform_data->psu_attrs) + { + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform subdata\n", __FUNCTION__); + kfree(psu_platform_data->psu_attrs); + } + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform data\n", __FUNCTION__); + kfree(psu_platform_data); + } + +clear_data: + memset(pdata, 0, sizeof(PSU_DATA)); + /*TODO: free the data cdata->data if data is dynal=mically allocated*/ + memset(cdata, 0, sizeof(NEW_DEV_ATTR)); + return count; +} + + +static struct kobject *psu_kobj; +static struct kobject *i2c_kobj; + +int __init pddf_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(PSU, "PDDF_DATA MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + psu_kobj = kobject_create_and_add("psu", device_kobj); + if(!psu_kobj) + return -ENOMEM; + i2c_kobj = kobject_create_and_add("i2c", psu_kobj); + if(!i2c_kobj) + return -ENOMEM; + + ret = sysfs_create_group(i2c_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(i2c_kobj); + kobject_put(psu_kobj); + return ret; + } + pddf_dbg(PSU, "CREATED PSU I2C CLIENTS CREATION SYSFS GROUP\n"); + + ret = sysfs_create_group(i2c_kobj, &pddf_psu_client_data_group); + if (ret) + { + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(psu_kobj); + return ret; + } + pddf_dbg(PSU, "CREATED PDDF PSU DATA SYSFS GROUP\n"); + + return ret; +} + +void __exit pddf_data_exit(void) +{ + + pddf_dbg(PSU, "PDDF_DATA MODULE.. exit\n"); + sysfs_remove_group(i2c_kobj, &pddf_psu_client_data_group); + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(psu_kobj); + pddf_dbg(PSU, KERN_ERR "%s: Removed the kobjects for 'i2c' and 'psu'\n",__FUNCTION__); + + return; +} + +module_init(pddf_data_init); +module_exit(pddf_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("psu platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/sysstatus/Makefile b/platform/pddf/i2c/modules/sysstatus/Makefile new file mode 100644 index 000000000000..150d160eae15 --- /dev/null +++ b/platform/pddf/i2c/modules/sysstatus/Makefile @@ -0,0 +1,4 @@ +TARGET := pddf_sysstatus_module +obj-m := $(TARGET).o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/sysstatus/pddf_sysstatus_module.c b/platform/pddf/i2c/modules/sysstatus/pddf_sysstatus_module.c new file mode 100644 index 000000000000..bd892d924265 --- /dev/null +++ b/platform/pddf/i2c/modules/sysstatus/pddf_sysstatus_module.c @@ -0,0 +1,235 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module for system status registers + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_sysstatus_defs.h" + + + +SYSSTATUS_DATA sysstatus_data = {0}; + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t show_sysstatus_data(struct device *dev, struct device_attribute *da, char *buf); + + +PDDF_DATA_ATTR(attr_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, + (void*)&sysstatus_data.sysstatus_addr_attr.aname, NULL); +PDDF_DATA_ATTR(attr_devaddr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, + sizeof(uint32_t), (void*)&sysstatus_data.sysstatus_addr_attr.devaddr , NULL); +PDDF_DATA_ATTR(attr_offset, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, + sizeof(uint32_t), (void*)&sysstatus_data.sysstatus_addr_attr.offset, NULL); +PDDF_DATA_ATTR(attr_mask, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, + sizeof(uint32_t), (void*)&sysstatus_data.sysstatus_addr_attr.mask , NULL); +PDDF_DATA_ATTR(attr_len, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, + sizeof(uint32_t), (void*)&sysstatus_data.sysstatus_addr_attr.len , NULL); +PDDF_DATA_ATTR(attr_ops, S_IWUSR, NULL, do_attr_operation, PDDF_CHAR, 8, (void*)&sysstatus_data, NULL); + + + +static struct attribute *sysstatus_addr_attributes[] = { + &attr_attr_name.dev_attr.attr, + &attr_attr_devaddr.dev_attr.attr, + &attr_attr_offset.dev_attr.attr, + &attr_attr_mask.dev_attr.attr, + &attr_attr_len.dev_attr.attr, + &attr_attr_ops.dev_attr.attr, + NULL +}; + +PDDF_DATA_ATTR(board_info, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, 32, NULL, NULL); +PDDF_DATA_ATTR(cpld1_version, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(cpld2_version, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(cpld3_version, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(power_module_status, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset1, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset2, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset3, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset4, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset5, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset6, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset7, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset8, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(misc1, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(misc2, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(misc3, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); + + + +static struct attribute *sysstatus_data_attributes[] = { + &attr_board_info.dev_attr.attr, + &attr_cpld1_version.dev_attr.attr, + &attr_cpld2_version.dev_attr.attr, + &attr_cpld3_version.dev_attr.attr, + &attr_power_module_status.dev_attr.attr, + &attr_system_reset1.dev_attr.attr, + &attr_system_reset2.dev_attr.attr, + &attr_system_reset3.dev_attr.attr, + &attr_system_reset4.dev_attr.attr, + &attr_system_reset5.dev_attr.attr, + &attr_system_reset6.dev_attr.attr, + &attr_system_reset7.dev_attr.attr, + &attr_system_reset8.dev_attr.attr, + &attr_misc1.dev_attr.attr, + &attr_misc2.dev_attr.attr, + &attr_misc3.dev_attr.attr, + NULL +}; + + + +static const struct attribute_group pddf_sysstatus_addr_group = { + .attrs = sysstatus_addr_attributes, +}; + + +static const struct attribute_group pddf_sysstatus_data_group = { + .attrs = sysstatus_data_attributes, +}; + + +static struct kobject *sysstatus_addr_kobj; +static struct kobject *sysstatus_data_kobj; + + + +ssize_t show_sysstatus_data(struct device *dev, struct device_attribute *da, char *buf) +{ + + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + SYSSTATUS_DATA *data = &sysstatus_data; + struct SYSSTATUS_ADDR_ATTR *sysstatus_addr_attrs = NULL; + int i, status ; + + + for (i=0;isysstatus_addr_attrs[i].aname, attr->dev_attr.attr.name) == 0 ) + { + sysstatus_addr_attrs = &data->sysstatus_addr_attrs[i]; + + } + } + + if (sysstatus_addr_attrs==NULL ) + { + printk(KERN_DEBUG "%s is not supported attribute for this client\n",data->sysstatus_addr_attrs[i].aname); + status = 0; + } + else + { + status = board_i2c_cpld_read( sysstatus_addr_attrs->devaddr, sysstatus_addr_attrs->offset); + } + + return sprintf(buf, "0x%x\n", (status&sysstatus_addr_attrs->mask)); + +} + + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + SYSSTATUS_DATA *pdata = (SYSSTATUS_DATA *)(ptr->addr); + + pdata->sysstatus_addr_attrs[pdata->len] = pdata->sysstatus_addr_attr; + pdata->len++; + pddf_dbg(SYSSTATUS, KERN_ERR "%s: Populating the data for %s\n", __FUNCTION__, pdata->sysstatus_addr_attr.aname); + memset(&pdata->sysstatus_addr_attr, 0, sizeof(pdata->sysstatus_addr_attr)); + + + return count; +} + + + + +int __init sysstatus_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(SYSSTATUS, "PDDF SYSSTATUS MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + sysstatus_addr_kobj = kobject_create_and_add("sysstatus", device_kobj); + if(!sysstatus_addr_kobj) + return -ENOMEM; + + sysstatus_data_kobj = kobject_create_and_add("sysstatus_data", sysstatus_addr_kobj); + if(!sysstatus_data_kobj) + return -ENOMEM; + + + ret = sysfs_create_group(sysstatus_addr_kobj, &pddf_sysstatus_addr_group); + if (ret) + { + kobject_put(sysstatus_addr_kobj); + return ret; + } + + ret = sysfs_create_group(sysstatus_data_kobj, &pddf_sysstatus_data_group); + if (ret) + { + sysfs_remove_group(sysstatus_addr_kobj, &pddf_sysstatus_addr_group); + kobject_put(sysstatus_data_kobj); + kobject_put(sysstatus_addr_kobj); + return ret; + } + + + return ret; +} + +void __exit sysstatus_data_exit(void) +{ + pddf_dbg(SYSSTATUS, "PDDF SYSSTATUS MODULE.. exit\n"); + sysfs_remove_group(sysstatus_data_kobj, &pddf_sysstatus_data_group); + sysfs_remove_group(sysstatus_addr_kobj, &pddf_sysstatus_addr_group); + kobject_put(sysstatus_data_kobj); + kobject_put(sysstatus_addr_kobj); + pddf_dbg(SYSSTATUS, KERN_ERR "%s: Removed the kobjects for 'SYSSTATUS'\n",__FUNCTION__); + return; +} + +module_init(sysstatus_data_init); +module_exit(sysstatus_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("SYSSTATUS platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/xcvr/Makefile b/platform/pddf/i2c/modules/xcvr/Makefile new file mode 100644 index 000000000000..e72ad6b44233 --- /dev/null +++ b/platform/pddf/i2c/modules/xcvr/Makefile @@ -0,0 +1,4 @@ +subdir-m := driver +obj-m := pddf_xcvr_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/xcvr/driver/Makefile b/platform/pddf/i2c/modules/xcvr/driver/Makefile new file mode 100644 index 000000000000..0b381d1fc2fe --- /dev/null +++ b/platform/pddf/i2c/modules/xcvr/driver/Makefile @@ -0,0 +1,7 @@ +TARGET = pddf_xcvr_driver_module + +obj-m := $(TARGET).o + +$(TARGET)-objs := pddf_xcvr_api.o pddf_xcvr_driver.o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_api.c b/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_api.c new file mode 100644 index 000000000000..ddb7a1b3a2b3 --- /dev/null +++ b/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_api.c @@ -0,0 +1,909 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description of various APIs related to transciever component + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_xcvr_defs.h" + +/*#define SFP_DEBUG*/ +#ifdef SFP_DEBUG +#define sfp_dbg(...) printk(__VA_ARGS__) +#else +#define sfp_dbg(...) +#endif + +extern XCVR_SYSFS_ATTR_OPS xcvr_ops[]; +extern void *get_device_table(char *name); + +int get_xcvr_module_attr_data(struct i2c_client *client, struct device *dev, + struct device_attribute *da); + +int xcvr_i2c_cpld_read(XCVR_ATTR *info) +{ + int status = -1; + + if (info!=NULL) + { + if (info->len==1) + { + status = board_i2c_cpld_read(info->devaddr , info->offset); + } + else + { + /* Get the I2C client for the CPLD */ + struct i2c_client *client_ptr=NULL; + client_ptr = (struct i2c_client *)get_device_table(info->devname); + if (client_ptr) + { + if (info->len==2) + { + status = i2c_smbus_read_word_swapped(client_ptr, info->offset); + } + else + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD read yet"); + } + else + printk(KERN_ERR "Unable to get the client handle for %s\n", info->devname); + } + + } + + return status; +} + +int sonic_i2c_get_mod_pres(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t modpres = 0; + + if ( strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + + if (status < 0) + return status; + else + { + modpres = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nMod presence :0x%x, reg_value = 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n", modpres, status, info->devaddr, info->mask, info->offset); + } + } + else if(strcmp(info->devtype, "eeprom") == 0) + { + /* get client client for eeprom - Not Applicable */ + } + data->modpres = modpres; + + return 0; +} + +int sonic_i2c_get_mod_reset(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t modreset=0; + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + modreset = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nMod Reset :0x%x, reg_value = 0x%x\n", modreset, status); + } + } + else if(strcmp(info->devtype, "eeprom") == 0) + { + /* get client client for eeprom - Not Applicable */ + } + + data->reset = modreset; + return 0; +} + +int sonic_i2c_get_mod_intr_status(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t mod_intr = 0; + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + mod_intr = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nModule Interrupt :0x%x, reg_value = 0x%x\n", mod_intr, status); + } + } + else if(strcmp(info->devtype, "eeprom") == 0) + { + /* get client client for eeprom - Not Applicable */ + } + + data->intr_status = mod_intr; + return 0; +} + + +int sonic_i2c_get_mod_lpmode(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t lpmode = 0; + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + lpmode = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nModule LPmode :0x%x, reg_value = 0x%x\n", lpmode, status); + } + } + else if (strcmp(info->devtype, "eeprom") == 0) + { + /* get client client for eeprom - Not Applicable */ + } + + data->lpmode = lpmode; + return 0; +} + +int sonic_i2c_get_mod_rxlos(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t rxlos = 0; + + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + rxlos = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nModule RxLOS :0x%x, reg_value = 0x%x\n", rxlos, status); + } + } + data->rxlos = rxlos; + + return 0; +} + +int sonic_i2c_get_mod_txdisable(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t txdis = 0; + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + txdis = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nModule TxDisable :0x%x, reg_value = 0x%x\n", txdis, status); + } + } + data->txdisable = txdis; + + return 0; +} + +int sonic_i2c_get_mod_txfault(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t txflt = 0; + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + txflt = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nModule TxFault :0x%x, reg_value = 0x%x\n", txflt, status); + } + + } + data->txfault = txflt; + + return 0; +} + +int sonic_i2c_set_mod_reset(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + unsigned int val_mask = 0, dnd_value = 0; + uint32_t reg; + struct i2c_client *client_ptr=NULL; + + if (strcmp(info->devtype, "cpld") == 0) + { + val_mask = BIT_INDEX(info->mask); + /* Get the I2C client for the CPLD */ + client_ptr = (struct i2c_client *)get_device_table(info->devname); + + if (client_ptr) + { + if (info->len == 1) + status = board_i2c_cpld_read(info->devaddr , info->offset); + else if (info->len == 2) + status = i2c_smbus_read_word_data(client_ptr, info->offset); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD read yet"); + status = -1; + } + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", info->devname); + status = -1; + } + /*printk(KERN_ERR "sonic_i2c_set_mod_reset:client_ptr=0x%x, status=0x%x, offset=0x%x, len=%d\n", client_ptr, status, info->offset, info->len);*/ + + if (status < 0) + return status; + else + { + dnd_value = status & ~val_mask; + if (((data->reset == 1) && (info->cmpval != 0)) || ((data->reset == 0) && (info->cmpval == 0))) + reg = dnd_value | val_mask; + else + reg = dnd_value; + if (info->len == 1) + status = board_i2c_cpld_write(info->devaddr, info->offset, (uint8_t)reg); + else if (info->len == 2) + status = i2c_smbus_write_word_swapped(client_ptr, info->offset, (uint16_t)reg); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD write yet"); + status = -1; + } + } + } + + return status; +} + +int sonic_i2c_set_mod_lpmode(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + unsigned int val_mask = 0, dnd_value = 0; + uint32_t reg; + struct i2c_client *client_ptr=NULL; + + if (strcmp(info->devtype, "cpld") == 0) + { + val_mask = BIT_INDEX(info->mask); + /* Get the I2C client for the CPLD */ + client_ptr = (struct i2c_client *)get_device_table(info->devname); + + if (client_ptr) + { + if (info->len == 1) + status = board_i2c_cpld_read(info->devaddr , info->offset); + else if (info->len == 2) + status = i2c_smbus_read_word_data(client_ptr, info->offset); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD read yet"); + status = -1; + } + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", info->devname); + status = -1; + } + + if (status < 0) + return status; + else + { + dnd_value = status & ~val_mask; + if (((data->lpmode == 1) && (info->cmpval != 0)) || ((data->lpmode == 0) && (info->cmpval == 0))) + reg = dnd_value | val_mask; + else + reg = dnd_value; + if (info->len == 1) + status = board_i2c_cpld_write(info->devaddr, info->offset, (uint8_t)reg); + else if (info->len == 2) + status = i2c_smbus_write_word_swapped(client_ptr, info->offset, (uint16_t)reg); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD write yet"); + status = -1; + } + } + } + + return status; +} + +int sonic_i2c_set_mod_txdisable(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + unsigned int val_mask = 0, dnd_value = 0; + uint32_t reg; + struct i2c_client *client_ptr=NULL; + + if (strcmp(info->devtype, "cpld") == 0) + { + val_mask = BIT_INDEX(info->mask); + /* Get the I2C client for the CPLD */ + client_ptr = (struct i2c_client *)get_device_table(info->devname); + + if (client_ptr) + { + if (info->len == 1) + status = board_i2c_cpld_read(info->devaddr , info->offset); + else if (info->len == 2) + status = i2c_smbus_read_word_data(client_ptr, info->offset); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD read yet"); + status = -1; + } + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", info->devname); + status = -1; + } + + if (status < 0) + return status; + else + { + dnd_value = status & ~val_mask; + if (((data->txdisable == 1) && (info->cmpval != 0)) || ((data->txdisable == 0) && (info->cmpval == 0))) + reg = dnd_value | val_mask; + else + reg = dnd_value; + if (info->len == 1) + status = board_i2c_cpld_write(info->devaddr, info->offset, (uint8_t)reg); + else if (info->len == 2) + status = i2c_smbus_write_word_swapped(client_ptr, info->offset, (uint16_t)reg); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD write yet"); + status = -1; + } + } + } + + return status; +} + +ssize_t get_module_presence(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + int status = 0, i; + + for (i=0; ilen; i++) + { + attr_data = &pdata->xcvr_attrs[i]; + if (strcmp(attr_data->aname, attr->dev_attr.attr.name) == 0) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute. ret %d\n", __FUNCTION__, attr_data->aname, status); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->modpres); + } + } + return sprintf(buf, "%s",""); +} + +ssize_t get_module_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + int status = 0, i; + + for (i=0; ilen; i++) + { + attr_data = &pdata->xcvr_attrs[i]; + if (strcmp(attr_data->aname, attr->dev_attr.attr.name) == 0) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", data->reset); + } + } + return sprintf(buf, "%s",""); +} + +ssize_t set_module_reset(struct device *dev, struct device_attribute *da, const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + int status = 0, i; + unsigned int set_value; + + for (i=0; ilen; i++) + { + attr_data = &pdata->xcvr_attrs[i]; + if (strcmp(attr_data->aname, attr->dev_attr.attr.name) == 0) + { + attr_ops = &xcvr_ops[attr->index]; + if(kstrtoint(buf, 10, &set_value)) + return -EINVAL; + if ((set_value != 1) && (set_value != 0)) + return -EINVAL; + + data->reset = set_value; + + mutex_lock(&data->update_lock); + + if (attr_ops->pre_set != NULL) + { + status = (attr_ops->pre_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_set != NULL) + { + status = (attr_ops->do_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_set != NULL) + { + status = (attr_ops->post_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + + return count; + } + } + return -EINVAL; +} + +ssize_t get_module_intr_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + int status = 0, i; + + for (i=0; ilen; i++) + { + attr_data = &pdata->xcvr_attrs[i]; + if (strcmp(attr_data->aname, attr->dev_attr.attr.name) == 0) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->intr_status); + } + } + return sprintf(buf, "%s",""); +} + +int get_xcvr_module_attr_data(struct i2c_client *client, struct device *dev, + struct device_attribute *da) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + XCVR_ATTR *attr_data = NULL; + int i; + + for (i=0; i < pdata->len; i++) + { + attr_data = &pdata->xcvr_attrs[i]; + if (strcmp(attr_data->aname, attr->dev_attr.attr.name) == 0) + { + return i; + } + } + return -1; +} + +ssize_t get_module_lpmode(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + int idx, status = 0; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->lpmode); + } + else + return sprintf(buf,"%s",""); +} + +ssize_t set_module_lpmode(struct device *dev, struct device_attribute *da, const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + int idx, status = 0; + uint32_t set_value; + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + attr_ops = &xcvr_ops[attr->index]; + if(kstrtoint(buf, 10, &set_value)) + return -EINVAL; + if ((set_value != 1) && (set_value != 0)) + return -EINVAL; + + data->lpmode = set_value; + + mutex_lock(&data->update_lock); + + if (attr_ops->pre_set != NULL) + { + status = (attr_ops->pre_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_set != NULL) + { + status = (attr_ops->do_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_set != NULL) + { + status = (attr_ops->post_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + } + return count; +} + +ssize_t get_module_rxlos(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + int idx, status = 0; + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->rxlos); + } + else + return sprintf(buf,"%s",""); +} + +ssize_t get_module_txdisable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + int idx, status = 0; + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->txdisable); + } + else + return sprintf(buf,"%s",""); +} + +ssize_t set_module_txdisable(struct device *dev, struct device_attribute *da, const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + int idx, status = 0; + uint32_t set_value; + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + attr_ops = &xcvr_ops[attr->index]; + if(kstrtoint(buf, 10, &set_value)) + return -EINVAL; + if ((set_value != 1) && (set_value != 0)) + return -EINVAL; + + data->txdisable = set_value; + + mutex_lock(&data->update_lock); + + if (attr_ops->pre_set != NULL) + { + status = (attr_ops->pre_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_set function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_set != NULL) + { + status = (attr_ops->do_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_set function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_set != NULL) + { + status = (attr_ops->post_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_set function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + } + return count; +} + +ssize_t get_module_txfault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + struct xcvr_data *data = i2c_get_clientdata(client); + int idx, status = 0; + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->txfault); + } + return sprintf(buf,"%s",""); +} diff --git a/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_driver.c b/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_driver.c new file mode 100644 index 000000000000..142d38a2ff2b --- /dev/null +++ b/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_driver.c @@ -0,0 +1,296 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel driver module for Optic component + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_xcvr_defs.h" +#include "pddf_xcvr_api.h" + + +struct pddf_ops_t pddf_xcvr_ops = { + .pre_init = NULL, + .post_init = NULL, + + .pre_probe = NULL, + .post_probe = NULL, + + .pre_remove = NULL, + .post_remove = NULL, + + .pre_exit = NULL, + .post_exit = NULL, +}; +EXPORT_SYMBOL(pddf_xcvr_ops); + +XCVR_SYSFS_ATTR_OPS xcvr_ops[XCVR_ATTR_MAX] = { + {XCVR_PRESENT, get_module_presence, NULL, sonic_i2c_get_mod_pres, NULL, NULL, NULL, NULL, NULL}, + {XCVR_RESET, get_module_reset, NULL, sonic_i2c_get_mod_reset, NULL, set_module_reset, NULL, sonic_i2c_set_mod_reset, NULL}, + {XCVR_INTR_STATUS, get_module_intr_status, NULL, sonic_i2c_get_mod_intr_status, NULL, NULL, NULL, NULL, NULL}, + {XCVR_LPMODE, get_module_lpmode, NULL, sonic_i2c_get_mod_lpmode, NULL, set_module_lpmode, NULL, sonic_i2c_set_mod_lpmode, NULL}, + {XCVR_RXLOS, get_module_rxlos, NULL, sonic_i2c_get_mod_rxlos, NULL, NULL, NULL, NULL, NULL}, + {XCVR_TXDISABLE, get_module_txdisable, NULL, sonic_i2c_get_mod_txdisable, NULL, set_module_txdisable, NULL, sonic_i2c_set_mod_txdisable, NULL}, + {XCVR_TXFAULT, get_module_txfault, NULL, sonic_i2c_get_mod_txfault, NULL, NULL, NULL, NULL, NULL}, +}; +EXPORT_SYMBOL(xcvr_ops); + + +/* sysfs attributes + */ +static SENSOR_DEVICE_ATTR(xcvr_present, S_IWUSR|S_IRUGO, get_module_presence, NULL, XCVR_PRESENT); +static SENSOR_DEVICE_ATTR(xcvr_reset, S_IWUSR|S_IRUGO, get_module_reset, set_module_reset, XCVR_RESET); +static SENSOR_DEVICE_ATTR(xcvr_intr_status, S_IWUSR|S_IRUGO, get_module_intr_status, NULL, XCVR_INTR_STATUS); +static SENSOR_DEVICE_ATTR(xcvr_lpmode, S_IWUSR|S_IRUGO, get_module_lpmode, set_module_lpmode, XCVR_LPMODE); +static SENSOR_DEVICE_ATTR(xcvr_rxlos, S_IWUSR|S_IRUGO, get_module_rxlos, NULL, XCVR_RXLOS); +static SENSOR_DEVICE_ATTR(xcvr_txdisable, S_IWUSR|S_IRUGO, get_module_txdisable, set_module_txdisable, XCVR_TXDISABLE); +static SENSOR_DEVICE_ATTR(xcvr_txfault, S_IWUSR|S_IRUGO, get_module_txfault, NULL, XCVR_TXFAULT); + +/* List of all the xcvr attribute structures + * to get name, use sensor_dev_attr_<>.dev_attr.attr.name + * to get the id, use sensor_dev_attr_<>.dev_attr.index + */ +static struct sensor_device_attribute *xcvr_attr_list[MAX_XCVR_ATTRS] = { + &sensor_dev_attr_xcvr_present, + &sensor_dev_attr_xcvr_reset, + &sensor_dev_attr_xcvr_intr_status, + &sensor_dev_attr_xcvr_lpmode, + &sensor_dev_attr_xcvr_rxlos, + &sensor_dev_attr_xcvr_txdisable, + &sensor_dev_attr_xcvr_txfault, +}; + +static struct attribute *xcvr_attributes[MAX_XCVR_ATTRS] = {NULL}; + +static const struct attribute_group xcvr_group = { + .attrs = xcvr_attributes, +}; + +static int xcvr_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct xcvr_data *data; + int status =0; + int i,j,num; + XCVR_PDATA *xcvr_platform_data; + XCVR_ATTR *attr_data; + + if (client == NULL) { + pddf_dbg(XCVR, "NULL Client.. \n"); + goto exit; + } + + if (pddf_xcvr_ops.pre_probe) + { + status = (pddf_xcvr_ops.pre_probe)(client, dev_id); + if (status != 0) + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct xcvr_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + + dev_info(&client->dev, "chip found\n"); + + /* Take control of the platform data */ + xcvr_platform_data = (XCVR_PDATA *)(client->dev.platform_data); + num = xcvr_platform_data->len; + data->index = xcvr_platform_data->idx - 1; + mutex_init(&data->update_lock); + + /* Add supported attr in the 'attributes' list */ + for (i=0; ixcvr_attrs + i; + for(j=0;jdev_attr.attr; + + if (strncmp(aptr->name, attr_data->aname, strlen(attr_data->aname))==0) + break; + } + + if (jdev_attr.attr; + + } + xcvr_attributes[i] = NULL; + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &xcvr_group); + if (status) { + goto exit_free; + } + + data->xdev = hwmon_device_register(&client->dev); + if (IS_ERR(data->xdev)) { + status = PTR_ERR(data->xdev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: xcvr '%s'\n", + dev_name(data->xdev), client->name); + + /* Add a support for post probe function */ + if (pddf_xcvr_ops.post_probe) + { + status = (pddf_xcvr_ops.post_probe)(client, dev_id); + if (status != 0) + goto exit_remove; + } + + + return 0; + + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &xcvr_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int xcvr_remove(struct i2c_client *client) +{ + int ret = 0; + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *platdata = (XCVR_PDATA *)client->dev.platform_data; + XCVR_ATTR *platdata_sub = platdata->xcvr_attrs; + + if (pddf_xcvr_ops.pre_remove) + { + ret = (pddf_xcvr_ops.pre_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN pre_remove function failed\n"); + } + + hwmon_device_unregister(data->xdev); + sysfs_remove_group(&client->dev.kobj, &xcvr_group); + kfree(data); + + if (platdata_sub) { + pddf_dbg(XCVR, KERN_DEBUG "%s: Freeing platform subdata\n", __FUNCTION__); + kfree(platdata_sub); + } + if (platdata) { + pddf_dbg(XCVR, KERN_DEBUG "%s: Freeing platform data\n", __FUNCTION__); + kfree(platdata); + } + + if (pddf_xcvr_ops.post_remove) + { + ret = (pddf_xcvr_ops.post_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN post_remove function failed\n"); + } + + return 0; +} + +enum xcvr_intf +{ + XCVR_CTRL_INTF, +}; + +static const struct i2c_device_id xcvr_ids[] = { + { "pddf_xcvr", XCVR_CTRL_INTF }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, xcvr_ids); + +static struct i2c_driver xcvr_driver = { + /*.class = I2C_CLASS_HWMON,*/ + .driver = { + .name = "xcvr", + .owner = THIS_MODULE, + }, + .probe = xcvr_probe, + .remove = xcvr_remove, + .id_table = xcvr_ids, +}; + + +/*int __init xcvr_init(void)*/ +int xcvr_init(void) +{ + int ret = 0; + + if (pddf_xcvr_ops.pre_init) + { + ret = (pddf_xcvr_ops.pre_init)(); + if (ret!=0) + return ret; + } + + pddf_dbg(XCVR, KERN_ERR "PDDF XCVR DRIVER.. init Invoked..\n"); + ret = i2c_add_driver(&xcvr_driver); + if (ret!=0) + return ret; + + if (pddf_xcvr_ops.post_init) + { + ret = (pddf_xcvr_ops.post_init)(); + if (ret!=0) + return ret; + } + + return ret; +} +EXPORT_SYMBOL(xcvr_init); + +void __exit xcvr_exit(void) +{ + pddf_dbg(XCVR, "PDDF XCVR DRIVER.. exit\n"); + if (pddf_xcvr_ops.pre_exit) (pddf_xcvr_ops.pre_exit)(); + i2c_del_driver(&xcvr_driver); + if (pddf_xcvr_ops.post_exit) (pddf_xcvr_ops.post_exit)(); + +} +EXPORT_SYMBOL(xcvr_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("Driver for transceiver operations"); +MODULE_LICENSE("GPL"); + +module_init(xcvr_init); +module_exit(xcvr_exit); diff --git a/platform/pddf/i2c/modules/xcvr/pddf_xcvr_module.c b/platform/pddf/i2c/modules/xcvr/pddf_xcvr_module.c new file mode 100644 index 000000000000..65c555b742a2 --- /dev/null +++ b/platform/pddf/i2c/modules/xcvr/pddf_xcvr_module.c @@ -0,0 +1,275 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to create i2C client for optics + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_xcvr_defs.h" + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern void* get_device_table(char *name); +extern void delete_device_table(char *name); + +XCVR_DATA xcvr_data = {0}; + +/* XCVR CLIENT DATA */ +PDDF_DATA_ATTR(dev_idx, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&xcvr_data.idx, NULL); + +PDDF_DATA_ATTR(attr_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&xcvr_data.xcvr_attr.aname, NULL); +PDDF_DATA_ATTR(attr_devtype, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&xcvr_data.xcvr_attr.devtype, NULL); +PDDF_DATA_ATTR(attr_devname, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&xcvr_data.xcvr_attr.devname, NULL); +PDDF_DATA_ATTR(attr_devaddr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&xcvr_data.xcvr_attr.devaddr, NULL); +PDDF_DATA_ATTR(attr_offset, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&xcvr_data.xcvr_attr.offset, NULL); +PDDF_DATA_ATTR(attr_mask, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&xcvr_data.xcvr_attr.mask, NULL); +PDDF_DATA_ATTR(attr_cmpval, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&xcvr_data.xcvr_attr.cmpval, NULL); +PDDF_DATA_ATTR(attr_len, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&xcvr_data.xcvr_attr.len, NULL); +PDDF_DATA_ATTR(attr_ops, S_IWUSR, NULL, do_attr_operation, PDDF_CHAR, 8, (void*)&xcvr_data, NULL); +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&xcvr_data, (void*)&pddf_data); + + +static struct attribute *xcvr_attributes[] = { + &attr_dev_idx.dev_attr.attr, + + &attr_attr_name.dev_attr.attr, + &attr_attr_devtype.dev_attr.attr, + &attr_attr_devname.dev_attr.attr, + &attr_attr_devaddr.dev_attr.attr, + &attr_attr_offset.dev_attr.attr, + &attr_attr_mask.dev_attr.attr, + &attr_attr_cmpval.dev_attr.attr, + &attr_attr_len.dev_attr.attr, + &attr_attr_ops.dev_attr.attr, + &attr_dev_ops.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_xcvr_client_data_group = { + .attrs = xcvr_attributes, +}; + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + XCVR_DATA *pdata = (XCVR_DATA *)(ptr->addr); + + pdata->xcvr_attrs[pdata->len] = pdata->xcvr_attr; + pdata->len++; + memset(&pdata->xcvr_attr, 0, sizeof(pdata->xcvr_attr)); + + + return count; +} + +/*PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&pddf_attr, (void*)NULL);*/ +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int i = 0; + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + XCVR_DATA *pdata = (XCVR_DATA *)(ptr->addr); + NEW_DEV_ATTR *cdata = (NEW_DEV_ATTR *)(ptr->data); + + struct i2c_adapter *adapter; + struct i2c_board_info board_info; + struct i2c_client *client_ptr; + + /* Populate the platform data for xcvr */ + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + if (strcmp(cdata->dev_type, "pddf_xcvr")==0) + { + int num = pdata->len; + XCVR_PDATA *xcvr_platform_data; + + adapter = i2c_get_adapter(cdata->parent_bus); + /* Allocate the xcvr_platform_data */ + xcvr_platform_data = (XCVR_PDATA *)kzalloc(sizeof(XCVR_PDATA), GFP_KERNEL); + xcvr_platform_data->xcvr_attrs = (XCVR_ATTR *)kzalloc(num*sizeof(XCVR_ATTR), GFP_KERNEL); + + + xcvr_platform_data->idx = pdata->idx; + xcvr_platform_data->len = pdata->len; + + for (i=0;ixcvr_attrs[i] = pdata->xcvr_attrs[i]; + } + + board_info = (struct i2c_board_info) { + .platform_data = xcvr_platform_data, + }; + + board_info.addr = cdata->dev_addr; + strcpy(board_info.type, cdata->dev_type); + + client_ptr = i2c_new_device(adapter, &board_info); + if (client_ptr != NULL) { + i2c_put_adapter(adapter); + pddf_dbg(XCVR, KERN_ERR "Created a %s client: 0x%p\n", cdata->i2c_name, (void *)client_ptr); + add_device_table(cdata->i2c_name, (void*)client_ptr); + } + else + { + i2c_put_adapter(adapter); + goto free_data; + } + } + else if((strcmp(cdata->dev_type, "optoe1")==0) || (strcmp(cdata->dev_type, "optoe2")==0)) + { + + adapter = i2c_get_adapter(cdata->parent_bus); + board_info = (struct i2c_board_info) { + .platform_data = (void *)NULL, + }; + + board_info.addr = cdata->dev_addr; + strcpy(board_info.type, cdata->dev_type); + + client_ptr = i2c_new_device(adapter, &board_info); + if(client_ptr != NULL) { + i2c_put_adapter(adapter); + pddf_dbg(XCVR, KERN_ERR "Created %s, type:%s client: 0x%p\n", cdata->i2c_name, cdata->dev_type, (void *)client_ptr); + add_device_table(cdata->i2c_name, (void*)client_ptr); + } + else + { + i2c_put_adapter(adapter); + printk(KERN_ERR "Error creating a client %s on 0x%x, client_ptr:0x%p\n", board_info.type, board_info.addr, (void *)client_ptr); + goto free_data; + } + } + else + { + printk(KERN_ERR "%s:Unknown type of device %s. Unable to create I2C client for it\n",__FUNCTION__, cdata->dev_type); + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(cdata->i2c_name); + if (client_ptr) + { + pddf_dbg(XCVR, KERN_ERR "Removing %s client: 0x%p\n", cdata->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + delete_device_table(cdata->i2c_name); + } + else + { + pddf_dbg(XCVR, KERN_ERR "Unable to get the client handle for %s\n", cdata->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + + goto clear_data; + +free_data: + if (board_info.platform_data) + { + XCVR_PDATA *xcvr_platform_data = board_info.platform_data; + if (xcvr_platform_data->xcvr_attrs) + { + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform subdata\n", __FUNCTION__); + kfree(xcvr_platform_data->xcvr_attrs); + } + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform data\n", __FUNCTION__); + kfree(xcvr_platform_data); + } + +clear_data: + memset(pdata, 0, sizeof(XCVR_DATA)); + /*TODO: free the data cdata->data if data is dynal=mically allocated*/ + memset(cdata, 0, sizeof(NEW_DEV_ATTR)); + return count; +} + +struct kobject *xcvr_kobj; +struct kobject *i2c_kobj; +int __init pddf_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + pddf_dbg(XCVR, KERN_ERR "XCVR PDDF MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + xcvr_kobj = kobject_create_and_add("xcvr", device_kobj); + if(!xcvr_kobj) + return -ENOMEM; + i2c_kobj = kobject_create_and_add("i2c", xcvr_kobj); + if(!i2c_kobj) + return -ENOMEM; + + ret = sysfs_create_group(i2c_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(i2c_kobj); + kobject_put(xcvr_kobj); + return ret; + } + pddf_dbg(XCVR, "CREATED SFP I2C CLIENTS CREATION SYSFS GROUP\n"); + + ret = sysfs_create_group(i2c_kobj, &pddf_xcvr_client_data_group); + if (ret) + { + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(xcvr_kobj); + return ret; + } + pddf_dbg(XCVR, "CREATED PDDF SFP DATA SYSFS GROUP\n"); + + return ret; +} + +void __exit pddf_data_exit(void) +{ + + pddf_dbg(XCVR, "XCVR PDDF MODULE.. exit\n"); + sysfs_remove_group(i2c_kobj, &pddf_xcvr_client_data_group); + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(xcvr_kobj); + pddf_dbg(XCVR, KERN_ERR "%s: Removed the kobjects for 'i2c' and 'xcvr'\n",__FUNCTION__); + + return; +} + +module_init(pddf_data_init); +module_exit(pddf_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("sfp platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/service/pddf-platform-init.service b/platform/pddf/i2c/service/pddf-platform-init.service new file mode 100644 index 000000000000..ccb8d1110fb7 --- /dev/null +++ b/platform/pddf/i2c/service/pddf-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=PDDF module and device initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/pddf_util.py install +ExecStop=/usr/local/bin/pddf_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/pddf/i2c/setup.py b/platform/pddf/i2c/setup.py new file mode 100755 index 000000000000..04da78cd5330 --- /dev/null +++ b/platform/pddf/i2c/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +from setuptools import setup +import os + +setup( + name='pddf-platform', + version='%s' % os.environ.get('PLATFORM_MODULE_VERSION', '1.0'), + description='Module to initialize Platform', + packages=[ + 'modules', + ], +) + diff --git a/platform/pddf/i2c/utils/pddf_util.py b/platform/pddf/i2c/utils/pddf_util.py new file mode 100755 index 000000000000..127f37d6b2f0 --- /dev/null +++ b/platform/pddf/i2c/utils/pddf_util.py @@ -0,0 +1,605 @@ +#!/usr/bin/env python + + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + switch-pddf : switch to pddf mode, installing pddf drivers and generating sysfs nodes + switch-nonpddf : switch to per platform, non-pddf mode +""" + +import commands +import logging +import getopt +import os +import shutil +import subprocess +import sys + +import pddfparse + +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' +HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku' +PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform' + +PROJECT_NAME = 'PDDF' +version = '1.1' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +FORCE = 0 +kos = [] +perm_kos = [] +devs = [] + +# Instantiate the class pddf_obj +try: + pddf_obj = pddfparse.PddfParse() +except Exception as e: + print "%s" % str(e) + sys.exit() + + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + +def main(): + global DEBUG + global args + global FORCE + global kos + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + # generate the KOS list from pddf device JSON file + if 'std_perm_kos' in pddf_obj.data['PLATFORM'].keys(): + kos.extend(pddf_obj.data['PLATFORM']['std_perm_kos']) + perm_kos.extend(pddf_obj.data['PLATFORM']['std_perm_kos']) + kos.extend(pddf_obj.data['PLATFORM']['std_kos']) + kos.extend(pddf_obj.data['PLATFORM']['pddf_kos']) + + kos = ['modprobe '+i for i in kos] + + if 'custom_kos' in pddf_obj.data['PLATFORM']: + custom_kos = pddf_obj.data['PLATFORM']['custom_kos'] + kos.extend(['modprobe -f '+i for i in custom_kos]) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'switch-pddf': + do_switch_pddf() + elif arg == 'switch-nonpddf': + do_switch_nonpddf() + else: + show_help() + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[PDDF]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep pddf", 0) + if ret: + return False + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + +# Returns platform and HW SKU +def get_platform_and_hwsku(): + try: + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + platform = stdout.rstrip('\n') + + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-d', '-v', HWSKU_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + hwsku = stdout.rstrip('\n') + except OSError, e: + raise OSError("Cannot detect platform") + + return (platform, hwsku) + +def get_path_to_device(): + # Get platform and hwsku + (platform, hwsku) = get_platform_and_hwsku() + + # Load platform module from source + platform_path = "/".join([PLATFORM_ROOT_PATH, platform]) + + return platform_path + +def get_path_to_pddf_plugin(): + pddf_path = "/".join([PLATFORM_ROOT_PATH, "pddf/plugins"]) + return pddf_path + +def config_pddf_utils(): + device_path = get_path_to_device() + pddf_path = get_path_to_pddf_plugin() + + # ########################################################################## + SONIC_PLATFORM_BSP_WHL_PKG = "/".join([device_path, 'sonic_platform-1.0-py2-none-any.whl']) + SONIC_PLATFORM_PDDF_WHL_PKG = "/".join([device_path, 'pddf', 'sonic_platform-1.0-py2-none-any.whl']) + SONIC_PLATFORM_BSP_WHL_PKG_BK = "/".join([device_path, 'sonic_platform-1.0-py2-none-any.whl.orig']) + status, output = log_os_system("pip show sonic-platform > /dev/null 2>&1", 1) + if status: + if os.path.exists(SONIC_PLATFORM_PDDF_WHL_PKG): + # Platform API 2.0 is supported + if os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG): + # bsp whl pkg is present but not installed on host + if not os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG_BK): + log_os_system('mv '+SONIC_PLATFORM_BSP_WHL_PKG+' '+SONIC_PLATFORM_BSP_WHL_PKG_BK, 1) + # PDDF whl package exist ... this must be the whl package created from + # PDDF 2.0 ref API classes and some changes on top of it ... install it + shutil.copy(SONIC_PLATFORM_PDDF_WHL_PKG, SONIC_PLATFORM_BSP_WHL_PKG) + print "Attemting to install the PDDF sonic_platform wheel package ..." + status, output = log_os_system("pip install "+ SONIC_PLATFORM_BSP_WHL_PKG, 1) + if status: + print "Error: Failed to install {}".format(SONIC_PLATFORM_BSP_WHL_PKG) + return status + else: + print "Successfully installed {} package".format(SONIC_PLATFORM_BSP_WHL_PKG) + else: + # PDDF with platform APIs 1.5 must be supported + device_plugin_path = "/".join([device_path, "plugins"]) + backup_path = "/".join([device_plugin_path, "orig"]) + print "Loading PDDF generic plugins (1.0)" + if os.path.exists(backup_path) is False: + os.mkdir(backup_path) + log_os_system("mv "+device_plugin_path+"/*.*"+" "+backup_path, 0) + + for item in os.listdir(pddf_path): + shutil.copy(pddf_path+"/"+item, device_plugin_path+"/"+item) + + shutil.copy('/usr/local/bin/pddfparse.py', device_plugin_path+"/pddfparse.py") + + else: + # sonic_platform whl pkg is installed 2 possibilities, 1) bsp 2.0 classes + # are installed, 2) system rebooted and either pddf/bsp 2.0 classes are already installed + if os.path.exists(SONIC_PLATFORM_PDDF_WHL_PKG): + if not os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG_BK): + # bsp 2.0 classes are installed. Take a backup and copy pddf 2.0 whl pkg + log_os_system('mv '+SONIC_PLATFORM_BSP_WHL_PKG+' '+SONIC_PLATFORM_BSP_WHL_PKG_BK, 1) + shutil.copy(SONIC_PLATFORM_PDDF_WHL_PKG, SONIC_PLATFORM_BSP_WHL_PKG) + # uninstall the existing bsp whl pkg + status, output = log_os_system("pip uninstall sonic-platform -y &> /dev/null", 1) + if status: + print "Error: Unable to uninstall BSP sonic-platform whl package" + return status + print "Attemting to install the PDDF sonic_platform wheel package ..." + status, output = log_os_system("pip install "+ SONIC_PLATFORM_BSP_WHL_PKG, 1) + if status: + print "Error: Failed to install {}".format(SONIC_PLATFORM_BSP_WHL_PKG) + return status + else: + print "Successfully installed {} package".format(SONIC_PLATFORM_BSP_WHL_PKG) + else: + # system rebooted in pddf mode + print "System rebooted in PDDF mode, hence keeping the PDDF 2.0 classes" + else: + # pddf whl package doesnt exist + print "Error: PDDF 2.0 classes doesnt exist. PDDF mode can not be enabled" + sys.exit(1) + + # ########################################################################## + # Take a backup of orig fancontrol + if os.path.exists(device_path+"/fancontrol"): + log_os_system("mv "+device_path+"/fancontrol"+" "+device_path+"/fancontrol.bak", 0) + + # Create a link to fancontrol of PDDF + if os.path.exists(device_path+"/pddf/fancontrol") and not os.path.exists(device_path+"/fancontrol"): + shutil.copy(device_path+"/pddf/fancontrol",device_path+"/fancontrol") + + # BMC support + f_sensors="/usr/bin/sensors" + f_sensors_org="/usr/bin/sensors.org" + f_pddf_sensors="/usr/local/bin/pddf_sensors" + if os.path.exists(f_pddf_sensors) is True: + if os.path.exists(f_sensors_org) is False: + shutil.copy(f_sensors, f_sensors_org) + shutil.copy(f_pddf_sensors, f_sensors) + + + return 0 + +def cleanup_pddf_utils(): + device_path = get_path_to_device() + SONIC_PLATFORM_BSP_WHL_PKG = "/".join([device_path, 'sonic_platform-1.0-py2-none-any.whl']) + SONIC_PLATFORM_PDDF_WHL_PKG = "/".join([device_path, 'pddf', 'sonic_platform-1.0-py2-none-any.whl']) + SONIC_PLATFORM_BSP_WHL_PKG_BK = "/".join([device_path, 'sonic_platform-1.0-py2-none-any.whl.orig']) + # ########################################################################## + status, output = log_os_system("pip show sonic-platform > /dev/null 2>&1", 1) + if status: + # PDDF Platform API 2.0 is not supported but system is in PDDF mode, hence PDDF 1.0 plugins are present + device_plugin_path = "/".join([device_path, "plugins"]) + backup_path = "/".join([device_plugin_path, "orig"]) + if os.path.exists(backup_path) is True: + for item in os.listdir(device_plugin_path): + if os.path.isdir(device_plugin_path+"/"+item) is False: + os.remove(device_plugin_path+"/"+item) + + log_os_system("mv "+backup_path+"/*"+" "+device_plugin_path, 1) + os.rmdir(backup_path) + else: + print "\nERR: Unable to locate original device files...\n" + + else: + # PDDF 2.0 apis are supported and PDDF whl package is installed + if os.path.exists(SONIC_PLATFORM_PDDF_WHL_PKG): + if os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG_BK): + # platform is 2.0 compliant and original bsp 2.0 whl package exist + log_os_system('mv '+SONIC_PLATFORM_BSP_WHL_PKG_BK+' '+SONIC_PLATFORM_BSP_WHL_PKG, 1) + status, output = log_os_system("pip uninstall sonic-platform -y &> /dev/null", 1) + if status: + print "Error: Unable to uninstall PDDF sonic-platform whl package" + return status + print "Attemting to install the BSP sonic_platform wheel package ..." + status, output = log_os_system("pip install "+ SONIC_PLATFORM_BSP_WHL_PKG, 1) + if status: + print "Error: Failed to install {}".format(SONIC_PLATFORM_BSP_WHL_PKG) + return status + else: + print "Successfully installed {} package".format(SONIC_PLATFORM_BSP_WHL_PKG) + else: + # platform doesnt support 2.0 APIs but PDDF is 2.0 based + # remove and uninstall the PDDF whl package + if os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG): + os.remove(SONIC_PLATFORM_BSP_WHL_PKG) + status, output = log_os_system("pip uninstall sonic-platform -y &> /dev/null", 1) + if status: + print "Error: Unable to uninstall PDDF sonic-platform whl package" + return status + else: + # something seriously wrong. System is in PDDF mode but pddf whl pkg is not present + print "Error: Fatal error as the system is in PDDF mode but the pddf .whl original is not present" + # ################################################################################################################ + + if os.path.exists(device_path+"/fancontrol"): + os.remove(device_path+"/fancontrol") + + if os.path.exists(device_path+"/fancontrol.bak"): + log_os_system("mv "+device_path+"/fancontrol.bak"+" "+device_path+"/fancontrol", 0) + + # BMC support + f_sensors="/usr/bin/sensors" + f_sensors_org="/usr/bin/sensors.org" + if os.path.exists(f_sensors_org) is True: + shutil.copy(f_sensors_org, f_sensors) + + return 0 + +def create_pddf_log_files(): + if not os.path.exists('/var/log/pddf'): + log_os_system("sudo mkdir /var/log/pddf", 1) + + log_os_system("sudo touch /var/log/pddf/led.txt", 1) + log_os_system("sudo touch /var/log/pddf/psu.txt", 1) + log_os_system("sudo touch /var/log/pddf/fan.txt", 1) + log_os_system("sudo touch /var/log/pddf/xcvr.txt", 1) + log_os_system("sudo touch /var/log/pddf/sysstatus.txt", 1) + log_os_system("sudo touch /var/log/pddf/cpld.txt", 1) + log_os_system("sudo touch /var/log/pddf/cpldmux.txt", 1) + log_os_system("sudo touch /var/log/pddf/client.txt", 1) + log_os_system("sudo touch /var/log/pddf/mux.txt", 1) + +def driver_install(): + global FORCE + + # check for pre_driver_install script + if os.path.exists('/usr/local/bin/pddf_pre_driver_install.sh'): + status, output = log_os_system('/usr/local/bin/pddf_pre_driver_install.sh', 1) + if status: + print "Error: pddf_pre_driver_install script failed with error %d"%status + return status + + log_os_system("depmod", 1) + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + print "driver_install() failed with error %d"%status + if FORCE == 0: + return status + + output = config_pddf_utils() + if output: + print "config_pddf_utils() failed with error %d"%output + # check for post_driver_install script + if os.path.exists('/usr/local/bin/pddf_post_driver_install.sh'): + status, output = log_os_system('/usr/local/bin/pddf_post_driver_install.sh', 1) + if status: + print "Error: pddf_post_driver_install script failed with error %d"%status + return status + + + return 0 + +def driver_uninstall(): + global FORCE + + status = cleanup_pddf_utils() + if status: + print "cleanup_pddf_utils() failed with error %d"%status + + for i in range(0,len(kos)): + # if it is in perm_kos, do not remove + if (kos[-(i+1)].split())[-1] in perm_kos or 'i2c-i801' in kos[-(i+1)]: + continue + + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + print "driver_uninstall() failed with error %d"%status + if FORCE == 0: + return status + return 0 + +def device_install(): + global FORCE + + # check for pre_device_creation script + if os.path.exists('/usr/local/bin/pddf_pre_device_create.sh'): + status, output = log_os_system('/usr/local/bin/pddf_pre_device_create.sh', 1) + if status: + print "Error: pddf_pre_device_create script failed with error %d"%status + return status + + # trigger the pddf_obj script for FAN, PSU, CPLD, MUX, etc + status = pddf_obj.create_pddf_devices() + if status: + print "Error: create_pddf_devices() failed with error %d"%status + if FORCE == 0: + return status + + # check for post_device_create script + if os.path.exists('/usr/local/bin/pddf_post_device_create.sh'): + status, output = log_os_system('/usr/local/bin/pddf_post_device_create.sh', 1) + if status: + print "Error: pddf_post_device_create script failed with error %d"%status + return status + + return + +def device_uninstall(): + global FORCE + # Trigger the paloparse script for deletion of FAN, PSU, OPTICS, CPLD clients + status = pddf_obj.delete_pddf_devices() + if status: + print "Error: delete_pddf_devices() failed with error %d"%status + if FORCE == 0: + return status + return + +def do_install(): + print "Checking system...." + if not os.path.exists('/usr/share/sonic/platform/pddf_support'): + print PROJECT_NAME.upper() +" mode is not enabled" + return + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no PDDF driver installed...." + create_pddf_log_files() + print "Installing ..." + status = driver_install() + if status: + return status + else: + print PROJECT_NAME.upper() +" drivers detected...." + + print "Creating devices ..." + status = device_install() + if status: + return status + + return + +def do_uninstall(): + print "Checking system...." + if not os.path.exists('/usr/share/sonic/platform/pddf_support'): + print PROJECT_NAME.upper() +" mode is not enabled" + return + + + if os.path.exists('/var/log/pddf'): + print "Remove pddf log files....." + log_os_system("sudo rm -rf /var/log/pddf", 1) + + print "Remove all the devices..." + status = device_uninstall() + if status: + return status + + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no PDDF driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + return + +def do_switch_pddf(): + try: + import pddf_switch_svc + except ImportError: + print "Unable to find pddf_switch_svc.py. PDDF might not be supported on this platform" + sys.exit() + print "Check the pddf support..." + status = pddf_switch_svc.check_pddf_support() + if not status: + print "PDDF is not supported on this platform" + return status + + + print "Checking system...." + if os.path.exists('/usr/share/sonic/platform/pddf_support'): + print PROJECT_NAME.upper() +" system is already in pddf mode...." + else: + print "Check if the native sonic-platform whl package is installed in the pmon docker" + status, output = log_os_system("docker exec -it pmon pip show sonic-platform", 1) + if not status: + # Need to remove this whl module + status, output = log_os_system("docker exec -it pmon pip uninstall sonic-platform -y", 1) + if not status: + print "Successfully uninstalled the native sonic-platform whl pkg from pmon container" + else: + print "Error: Unable to uninstall the sonic-platform whl pkg from pmon container.\ + Do it manually before moving to nonpddf mode" + return status + print "Stopping the pmon service ..." + status, output = log_os_system("systemctl stop pmon.service", 1) + if status: + print "Pmon stop failed" + if FORCE==0: + return status + + print "Stopping the platform services.." + status = pddf_switch_svc.stop_platform_svc() + if not status: + if FORCE==0: + return status + + print "Creating the pddf_support file..." + if os.path.exists('/usr/share/sonic/platform'): + log_os_system("touch /usr/share/sonic/platform/pddf_support", 1) + else: + print "/usr/share/sonic/platform path doesn't exist. Unable to set pddf mode" + return -1 + + print "Starting the PDDF platform service..." + status = pddf_switch_svc.start_platform_pddf() + if not status: + if FORCE==0: + return status + + print "Restart the pmon service ..." + status, output = log_os_system("systemctl start pmon.service", 1) + if status: + print "Pmon restart failed" + if FORCE==0: + return status + + return + +def do_switch_nonpddf(): + try: + import pddf_switch_svc + except ImportError: + print "Unable to find pddf_switch_svc.py. PDDF might not be supported on this platform" + sys.exit() + print "Checking system...." + if not os.path.exists('/usr/share/sonic/platform/pddf_support'): + print PROJECT_NAME.upper() +" system is already in non-pddf mode...." + else: + print "Check if the sonic-platform whl package is installed in the pmon docker" + status, output = log_os_system("docker exec -it pmon pip show sonic-platform", 1) + if not status: + # Need to remove this whl module + status, output = log_os_system("docker exec -it pmon pip uninstall sonic-platform -y", 1) + if not status: + print "Successfully uninstalled the sonic-platform whl pkg from pmon container" + else: + print "Error: Unable to uninstall the sonic-platform whl pkg from pmon container.\ + Do it manually before moving to nonpddf mode" + return status + print "Stopping the pmon service ..." + status, output = log_os_system("systemctl stop pmon.service", 1) + if status: + print "Stopping pmon service failed" + if FORCE==0: + return status + + print "Stopping the PDDF platform service..." + status = pddf_switch_svc.stop_platform_pddf() + if not status: + if FORCE==0: + return status + + print "Removing the pddf_support file..." + if os.path.exists('/usr/share/sonic/platform'): + log_os_system("rm -f /usr/share/sonic/platform/pddf_support", 1) + else: + print "/usr/share/sonic/platform path doesnt exist. Unable to set non-pddf mode" + return -1 + + print "Starting the platform services..." + status = pddf_switch_svc.start_platform_svc() + if not status: + if FORCE==0: + return status + + print "Restart the pmon service ..." + status, output = log_os_system("systemctl start pmon.service", 1) + if status: + print "Restarting pmon service failed" + if FORCE==0: + return status + + return + +if __name__ == "__main__": + main() diff --git a/platform/pddf/i2c/utils/pddfparse.py b/platform/pddf/i2c/utils/pddfparse.py new file mode 100755 index 000000000000..f9ce8fca0b42 --- /dev/null +++ b/platform/pddf/i2c/utils/pddfparse.py @@ -0,0 +1,1949 @@ +#!/usr/bin/env python +import argparse +import glob +import json +from jsonschema import validate +import os +import re +import subprocess +import sys +import time +import unicodedata + +bmc_cache={} +cache={} +SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' +HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku' +PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform' + +dirname=os.path.dirname(os.path.realpath(__file__)) + +color_map = { + "STATUS_LED_COLOR_GREEN" : "green", + "STATUS_LED_COLOR_RED" : "red", + "STATUS_LED_COLOR_AMBER" : "amber", + "STATUS_LED_COLOR_BLUE" : "blue", + "STATUS_LED_COLOR_GREEN_BLINK" : "blinking green", + "STATUS_LED_COLOR_RED_BLINK" : "blinking red", + "STATUS_LED_COLOR_AMBER_BLINK" : "blinking amber", + "STATUS_LED_COLOR_BLUE_BLINK" : "blinking blue", + "STATUS_LED_COLOR_OFF" : "off" +} + + + + +class PddfParse(): + def __init__(self): + if not os.path.exists("/usr/share/sonic/platform"): + platform, hwsku = self.get_platform_and_hwsku() + os.symlink("/usr/share/sonic/device/"+platform, "/usr/share/sonic/platform") + + try: + with open('/usr/share/sonic/platform/pddf/pddf-device.json') as f: + self.data = json.load(f) + except IOError: + if os.path.exists('/usr/share/sonic/platform'): + os.unlink("/usr/share/sonic/platform") + raise Exception('PDDF JSON file not found. PDDF is not supported on this platform') + + + self.data_sysfs_obj={} + self.sysfs_obj={} + + + # Returns platform and HW SKU + def get_platform_and_hwsku(self): + try: + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + platform = stdout.rstrip('\n') + + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-d', '-v', HWSKU_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + hwsku = stdout.rstrip('\n') + except OSError, e: + raise OSError("Cannot detect platform") + + return (platform, hwsku) + + ################################################################################################################### + # GENERIC DEFS + ################################################################################################################### + def runcmd(self, cmd): + rc = os.system(cmd) + if rc!=0: + print "%s -- command failed"%cmd + return rc + + def get_dev_idx(self, dev, ops): + parent=dev['dev_info']['virt_parent'] + pdev=self.data[parent] + + return pdev['dev_attr']['dev_idx'] + + + def get_path(self, target, attr): + aa = target + attr + + if aa in cache: + return cache[aa] + + string = None + p = re.search(r'\d+$', target) + if p is None: + for bb in filter(re.compile(target).search,self.data.keys()): + path = self.dev_parse(self.data[bb], { "cmd": "show_attr", "target":bb, "attr":attr }) + if path != "": + string = path + else: + if target in self.data.keys(): + path = self.dev_parse(self.data[target], { "cmd": "show_attr", "target":target, "attr":attr }) + if path != "": + string = path + + + if string is not None: + string = string.rstrip() + + cache[aa]=string + return string + + + def get_device_type(self, key): + if not key in self.data.keys(): + return None + return self.data[key]['dev_info']['device_type'] + + def get_platform(self): + return self.data['PLATFORM'] + + def get_num_psu_fans(self, dev): + if not dev in self.data.keys(): + return 0 + + if not 'num_psu_fans' in self.data[dev]['dev_attr']: + return 0 + + return self.data[dev]['dev_attr']['num_psu_fans'] + + def get_led_path(self): + return ("pddf/devices/led") + + def get_led_cur_state_path(self): + return ("pddf/devices/led/cur_state") + + def get_led_color(self): + color_f="/sys/kernel/pddf/devices/led/cur_state/color" + try: + with open(color_f, 'r') as f: + color = f.read().strip("\r\n") + except IOError: + return ("Error") + + return (color_map[color]) + + ################################################################################################################### + # CREATE DEFS + ################################################################################################################### + def create_device(self, attr, path, ops): + ret = 0 + for key in attr.keys(): + if type(attr[key]) is list: + val = " ".join(attr[key]) + else: + val = attr[key] + + cmd="echo '%s' > /sys/kernel/%s/%s"%(val, path, key) + ret=self.runcmd(cmd) + if ret!=0: + return ret + return ret + + + def create_psu_i2c_device(self, dev, ops): + create_ret = 0 + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/psu/i2c", ops) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/psu/i2c/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/psu/i2c/psu_idx"%( self.get_dev_idx(dev, ops)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + for attr in dev['i2c']['attr_list']: + create_ret = self.create_device(attr, "pddf/devices/psu/i2c", ops) + if create_ret!=0: + return create_ret + cmd= "echo 'add' > /sys/kernel/pddf/devices/psu/i2c/attr_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + cmd = "echo 'add' > /sys/kernel/pddf/devices/psu/i2c/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + else: + cmd = "echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + + return create_ret + + + + def create_psu_bmc_device(self, dev, ops): + print "" + + + def create_psu_device(self, dev, ops): + return self.create_psu_i2c_device(dev, ops ) + + def create_fan_device(self, dev, ops): + create_ret = 0 + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/fan/i2c", ops) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/fan/i2c/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + create_ret = self.create_device(dev['i2c']['dev_attr'], "pddf/devices/fan/i2c", ops) + if create_ret!=0: + return create_ret + for attr in dev['i2c']['attr_list']: + create_ret = self.create_device(attr, "pddf/devices/fan/i2c", ops) + if create_ret!=0: + return create_ret + cmd= "echo 'add' > /sys/kernel/pddf/devices/fan/i2c/attr_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + cmd= "echo 'add' > /sys/kernel/pddf/devices/fan/i2c/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + else: + cmd= "echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + return create_ret + + def create_temp_sensor_device(self, dev, ops): + create_ret = 0 + # NO PDDF driver for temp_sensors device + cmd= "echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + return create_ret + + + + + def create_cpld_device(self, dev, ops): + create_ret = 0 + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['CPLD']: + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/cpld", ops) + if create_ret!=0: + return create_ret + + cmd= "echo '%s' > /sys/kernel/pddf/devices/cpld/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + # TODO: If attributes are provided then, use 'self.create_device' for them too + cmd= "echo 'add' > /sys/kernel/pddf/devices/cpld/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + else: + cmd= "echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + return create_ret + + def create_cpldmux_device(self, dev, ops): + create_ret = 0 + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/cpldmux", ops) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/mux/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + self.create_device(dev['i2c']['dev_attr'], "pddf/devices/cpldmux", ops) + # Parse channel info + for chan in dev['i2c']['channel']: + self.create_device(chan, "pddf/devices/cpldmux", ops) + cmd="echo 'add' > /sys/kernel/pddf/devices/cpldmux/chan_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + cmd= "echo 'add' > /sys/kernel/pddf/devices/cpldmux/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + def create_gpio_device(self, dev, ops): + create_ret = 0 + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/gpio", ops) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/gpio/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + create_ret = self.create_device(dev['i2c']['dev_attr'], "pddf/devices/gpio", ops) + if create_ret!=0: + return create_ret + cmd= "echo 'add' > /sys/kernel/pddf/devices/gpio/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + time.sleep(2) + base = dev['i2c']['dev_attr']['gpio_base'] + for inst in dev['i2c']['ports']: + if inst['port_num']!="": + port_no = int(base, 16) + int(inst['port_num']) + cmd= "echo %d > /sys/class/gpio/export"%port_no + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + if inst['direction']!="": + cmd= "echo %s >/sys/class/gpio/gpio%d/direction"%(inst['direction'], port_no) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + if inst['value']!="": + for i in inst['value'].split(','): + cmd= "echo %s >/sys/class/gpio/gpio%d/value"%(i.rstrip(), port_no) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + return create_ret + + def create_mux_device(self, dev, ops): + create_ret = 0 + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/mux", ops) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/mux/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + self.create_device(dev['i2c']['dev_attr'], "pddf/devices/mux", ops) + cmd= "echo 'add' > /sys/kernel/pddf/devices/mux/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + + def create_xcvr_i2c_device(self, dev, ops): + create_ret = 0 + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + self.create_device(dev['i2c']['topo_info'], "pddf/devices/xcvr/i2c", ops) + cmd= "echo '%s' > /sys/kernel/pddf/devices/xcvr/i2c/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + cmd="echo '%s' > /sys/kernel/pddf/devices/xcvr/i2c/dev_idx"%( self.get_dev_idx(dev, ops)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + for attr in dev['i2c']['attr_list']: + self.create_device(attr, "pddf/devices/xcvr/i2c", ops) + cmd="echo 'add' > /sys/kernel/pddf/devices/xcvr/i2c/attr_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + cmd="echo 'add' > /sys/kernel/pddf/devices/xcvr/i2c/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + else: + cmd="echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + #print "\n" + if create_ret!=0: + return create_ret + # Add port name + port_name_sysfs = '/sys/bus/i2c/devices/{}-00{:02x}/port_name'.format( + int(dev['i2c']['topo_info']['parent_bus'], 0),int(dev['i2c']['topo_info']['dev_addr'], 0)) + + if os.path.exists(port_name_sysfs): + cmd="echo {} > /sys/bus/i2c/devices/{}-00{:02x}/port_name".format( + dev['dev_info']['virt_parent'].lower(), int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + return create_ret + + def create_xcvr_bmc_device(self, dev, ops): + print "" + + def create_xcvr_device(self, dev, ops): + return self.create_xcvr_i2c_device(dev, ops ) + + def create_sysstatus_device(self, dev, ops): + create_ret = 0 + for attr in dev['attr_list']: + self.create_device(attr, "pddf/devices/sysstatus", ops) + cmd= "echo 'add' > /sys/kernel/pddf/devices/sysstatus/attr_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + def create_eeprom_device(self, dev, ops): + create_ret = 0 + if "EEPROM" in self.data['PLATFORM']['pddf_dev_types'] and \ + dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['EEPROM']: + self.create_device(dev['i2c']['topo_info'], "pddf/devices/eeprom/i2c", ops) + cmd= "echo '%s' > /sys/kernel/pddf/devices/eeprom/i2c/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + self.create_device(dev['i2c']['dev_attr'], "pddf/devices/eeprom/i2c", ops) + cmd = "echo 'add' > /sys/kernel/pddf/devices/eeprom/i2c/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + else: + cmd= "echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + return create_ret + + ################################################################################################################### + # DELETE DEFS + ################################################################################################################### + def delete_eeprom_device(self, dev, ops): + if "EEPROM" in self.data['PLATFORM']['pddf_dev_types'] and \ + dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['EEPROM']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/eeprom/i2c/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd = "echo 'delete' > /sys/kernel/pddf/devices/eeprom/i2c/dev_ops" + self.runcmd(cmd) + else: + cmd= "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + def delete_sysstatus_device(self, dev, ops): + # NOT A PHYSICAL DEVICE.... rmmod on module would remove all the artifacts + pass + + + def delete_xcvr_i2c_device(self, dev, ops): + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/xcvr/i2c/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd="echo 'delete' > /sys/kernel/pddf/devices/xcvr/i2c/dev_ops" + self.runcmd(cmd) + else: + cmd="echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + def delete_xcvr_device(self, dev, ops): + self.delete_xcvr_i2c_device(dev, ops) + return + + def delete_gpio_device(self, dev, ops): + cmd= "echo '%s' > /sys/kernel/pddf/devices/gpio/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd= "echo 'delete' > /sys/kernel/pddf/devices/gpio/dev_ops" + self.runcmd(cmd) + + def delete_mux_device(self, dev, ops): + cmd= "echo '%s' > /sys/kernel/pddf/devices/mux/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd= "echo 'delete' > /sys/kernel/pddf/devices/mux/dev_ops" + self.runcmd(cmd) + + def delete_cpld_device(self, dev, ops): + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['CPLD']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/cpld/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd= "echo 'delete' > /sys/kernel/pddf/devices/cpld/dev_ops" + self.runcmd(cmd) + else: + cmd= "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + def delete_cpldmux_device(self, dev, ops): + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['CPLDMUX']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/cpldmux/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd= "echo 'delete' > /sys/kernel/pddf/devices/cpldmux/dev_ops" + self.runcmd(cmd) + + def delete_temp_sensor_device(self, dev, ops): + # NO PDDF driver for temp_sensors device + cmd= "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + def delete_fan_device(self, dev, ops): + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/fan/i2c/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd= "echo 'delete' > /sys/kernel/pddf/devices/fan/i2c/dev_ops" + self.runcmd(cmd) + else: + cmd= "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + + def delete_psu_i2c_device(self, dev, ops): + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/psu/i2c/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd = "echo 'delete' > /sys/kernel/pddf/devices/psu/i2c/dev_ops" + self.runcmd(cmd) + else: + cmd = "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" %(int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + def delete_psu_device(self, dev, ops): + self.delete_psu_i2c_device(dev, ops ) + return + + + ################################################################################################################### + # SHOW ATTRIBIUTES DEFS + ################################################################################################################### + def is_led_device_configured(self, device_name, attr_name): + if device_name in self.data.keys(): + attr_list=self.data[device_name]['i2c']['attr_list'] + for attr in attr_list: + if attr['attr_name'].strip() == attr_name.strip(): + return (True) + return (False) + + + def show_device_sysfs(self, dev, ops): + parent=dev['dev_info']['device_parent'] + pdev=self.data[parent] + if pdev['dev_info']['device_parent'] == 'SYSTEM': + return "/sys/bus/i2c/devices/"+"i2c-%d"%int(pdev['i2c']['topo_info']['dev_addr'], 0) + return self.show_device_sysfs(pdev, ops) + "/" + "i2c-%d" % int(dev['i2c']['topo_info']['parent_bus'], 0) + + + # This is alid for 'at24' type of EEPROM devices. Only one attribtue 'eeprom' + def show_attr_eeprom_device(self, dev, ops): + str = "" + attr_name=ops['attr'] + attr_list=dev['i2c']['attr_list'] + KEY="eeprom" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops)+"/%d-00%x"%(int(dev['i2c']['topo_info']['parent_bus'],0), + int(dev['i2c']['topo_info']['dev_addr'], 0))+"/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + str += dsysfs_path+"\n" + return str + + def show_attr_gpio_device(self, dev, ops): + ret = "" + KEY="gpio" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + return ret + + + def show_attr_mux_device(self, dev, ops): + ret = "" + KEY="mux" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + return ret + + def show_attr_psu_i2c_device(self, dev, ops): + target=ops['target'] + attr_name=ops['attr'] + ret = "" + KEY="psu" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + if target == 'all' or target == dev['dev_info']['virt_parent'] : + attr_list=dev['i2c']['attr_list'] + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all' : + if 'attr_devtype' in attr.keys() and attr['attr_devtype'] == "gpio": + # Check and enable the gpio from class + gpio_dev = self.data[attr['attr_devname']] + base = int(gpio_dev['i2c']['dev_attr']['gpio_base'], 16) + port_num = base + int(attr['attr_offset'], 16) + gpio_name = 'gpio'+str(port_num) + attr_path = '/sys/class/gpio/'+gpio_name+'/value' + if (os.path.exists(attr_path)): + if not attr_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(attr_path) + ret += attr_path + '\n' + else: + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x"%(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + + def show_attr_psu_device(self, dev, ops): + return self.show_attr_psu_i2c_device(dev, ops ) + + + def show_attr_fan_device(self, dev, ops): + ret_str = "" + attr_name=ops['attr'] + attr_list=dev['i2c']['attr_list'] + KEY="fan" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path= self.show_device_sysfs(dev, ops) + \ + "/%d-00%x" %(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret_str += dsysfs_path+"\n" + return ret_str + + # This is only valid for LM75 + def show_attr_temp_sensor_device(self, dev, ops): + ret_str = "" + attr_name=ops['attr'] + attr_list=dev['i2c']['attr_list'] + KEY="temp-sensors" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x/" %(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + if (os.path.exists(path)): + full_path = glob.glob(path + 'hwmon/hwmon*/' + real_name)[0] + dsysfs_path=full_path + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret_str += full_path + "\n" + return ret_str + + def show_attr_sysstatus_device(self, dev, ops): + ret = "" + attr_name=ops['attr'] + attr_list=dev['attr_list'] + KEY="sys-status" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + dsysfs_path = "/sys/kernel/pddf/devices/sysstatus/sysstatus_data/" + attr['attr_name'] + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + + def show_attr_xcvr_i2c_device(self, dev, ops): + target=ops['target'] + attr_name=ops['attr'] + ret = "" + dsysfs_path = "" + KEY="xcvr" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + if target == 'all' or target == dev['dev_info']['virt_parent'] : + attr_list=dev['i2c']['attr_list'] + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all' : + if 'attr_devtype' in attr.keys() and attr['attr_devtype'] == "gpio": + # Check and enable the gpio from class + gpio_dev = self.data[attr['attr_devname']] + base = int(gpio_dev['i2c']['dev_attr']['gpio_base'], 16) + port_num = base + int(attr['attr_offset'], 16) + gpio_name = 'gpio'+str(port_num) + attr_path = '/sys/class/gpio/'+gpio_name+'/value' + if (os.path.exists(attr_path)): + if not attr_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(attr_path) + ret += attr_path + '\n' + else: + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x" %(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + + def show_attr_xcvr_device(self, dev, ops): + return self.show_attr_xcvr_i2c_device(dev, ops ) + + def show_attr_cpld_device(self, dev, ops): + ret = "" + KEY="cpld" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + return ret + + def show_attr_cpldmux_device(self, dev, ops): + ret = "" + KEY="cpldmux" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + return ret + + + ################################################################################################################### + # SHOW DEFS + ################################################################################################################### + def check_led_cmds(self, key, ops): + name = ops['target']+'_LED' + if (ops['target']=='config' or ops['attr']=='all') or \ + (name==self.data[key]['dev_info']['device_name'] and + ops['attr']==self.data[key]['dev_attr']['index']): + return (True) + else: + return (False) + + def dump_sysfs_obj(self, obj, key_type): + if (key_type == 'keys'): + for key in obj.keys(): + print key + return + + for key in obj: + if (key == key_type or key_type == 'all'): + print key+":" + for entry in obj[key]: + print "\t"+entry + + def add_list_sysfs_obj(self, obj, KEY, list): + for sysfs in list: + if not sysfs in obj[KEY]: + obj[KEY].append(sysfs) + + def sysfs_attr(self, key, value, path, obj, obj_key): + sysfs_path="/sys/kernel/%s/%s"%(path, key) + if not sysfs_path in obj[obj_key]: + obj[obj_key].append(sysfs_path) + + + def sysfs_device(self, attr, path, obj, obj_key): + for key in attr.keys(): + sysfs_path="/sys/kernel/%s/%s"%(path, key) + if not sysfs_path in obj[obj_key]: + obj[obj_key].append(sysfs_path) + + def show_eeprom_device(self, dev, ops): + return + + + def show_mux_device(self, dev, ops): + KEY ='mux' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/mux", self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], "pddf/devices/mux", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/mux/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/mux/i2c_type', + '/sys/kernel/pddf/devices/mux/i2c_name', + '/sys/kernel/pddf/devices/mux/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_gpio_device(self, dev, ops): + KEY ='gpio' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/gpio", self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], "pddf/devices/gpio", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/gpio/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/gpio/i2c_type', + '/sys/kernel/pddf/devices/gpio/i2c_name', + '/sys/kernel/pddf/devices/gpio/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_psu_i2c_device(self, dev, ops): + KEY ='psu' + path='pddf/devices/psu/i2c' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], path, self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/psu/i2c/psu_idx" + self.sysfs_obj[KEY].append(sysfs_path) + + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, "pddf/devices/psu/i2c", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/psu/i2c/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/psu/i2c/i2c_type', + '/sys/kernel/pddf/devices/fan/i2c/i2c_name', + '/sys/kernel/pddf/devices/psu/i2c/error', + '/sys/kernel/pddf/devices/psu/i2c/attr_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_psu_device(self, dev, ops): + self.show_psu_i2c_device(dev, ops ) + return + + def show_client_device(self): + KEY ='client' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + list=['/sys/kernel/pddf/devices/showall'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_fan_device(self, dev, ops): + KEY ='fan' + path='pddf/devices/fan/i2c' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + + self.sysfs_device(dev['i2c']['topo_info'], path, self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], path, self.sysfs_obj, KEY) + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, path, self.sysfs_obj, KEY) + list=['/sys/kernel/pddf/devices/fan/i2c/i2c_type', + '/sys/kernel/pddf/devices/fan/i2c/i2c_name', + '/sys/kernel/pddf/devices/fan/i2c/error', + '/sys/kernel/pddf/devices/fan/i2c/attr_ops', + '/sys/kernel/pddf/devices/fan/i2c/dev_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_temp_sensor_device(self, dev, ops): + return + + def show_sysstatus_device(self, dev, ops): + KEY ='sysstatus' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + for attr in dev['attr_list']: + self.sysfs_device(attr, "pddf/devices/sysstatus", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/sysstatus/attr_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + + + def show_xcvr_i2c_device(self, dev, ops): + KEY ='xcvr' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/xcvr/i2c", self.sysfs_obj, KEY) + + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, "pddf/devices/xcvr/i2c", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/xcvr/i2c/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/xcvr/i2c/i2c_type', + '/sys/kernel/pddf/devices/xcvr/i2c/i2c_name', + '/sys/kernel/pddf/devices/xcvr/i2c/error', + '/sys/kernel/pddf/devices/xcvr/i2c/attr_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_xcvr_device(self, dev, ops): + self.show_xcvr_i2c_device(dev, ops ) + return + + def show_cpld_device(self, dev, ops): + KEY ='cpld' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['CPLD']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/cpld", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/cpld/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/cpld/i2c_type', + '/sys/kernel/pddf/devices/cpld/i2c_name', + '/sys/kernel/pddf/devices/cpld/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_led_platform_device(self, key, ops): + if ops['attr']=='all' or ops['attr']=='PLATFORM': + KEY='platform' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + path='pddf/devices/platform' + self.sysfs_attr('num_psus', self.data['PLATFORM']['num_psus'], path, self.sysfs_obj, KEY) + self.sysfs_attr('num_fantrays', self.data['PLATFORM']['num_fantrays'], path, self.sysfs_obj, KEY) + + def show_led_device(self, key, ops): + if self.check_led_cmds(key, ops): + KEY='led' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + path="pddf/devices/led" + for attr in self.data[key]['i2c']['attr_list']: + self.sysfs_attr('device_name', self.data[key]['dev_info']['device_name'],path,self.sysfs_obj,KEY) + self.sysfs_attr('swpld_addr', self.data[key]['dev_info']['device_name'],path,self.sysfs_obj, KEY) + self.sysfs_attr('swpld_addr_offset',self.data[key]['dev_info']['device_name'], + path,self.sysfs_obj, KEY) + self.sysfs_device(self.data[key]['dev_attr'], path, self.sysfs_obj, KEY) + for attr_key in attr.keys(): + attr_path="pddf/devices/led/" + attr['attr_name'] + if (attr_key != 'attr_name' and attr_key != 'swpld_addr' and attr_key != 'swpld_addr_offset'): + self.sysfs_attr(attr_key, attr[attr_key], attr_path, self.sysfs_obj, KEY) + sysfs_path="/sys/kernel/pddf/devices/led/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/led/cur_state/color'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def validate_xcvr_device(self, dev, ops): + devtype_list = ['optoe1', 'optoe2'] + dev_attribs = ['xcvr_present', 'xcvr_reset', 'xcvr_intr_status', 'xcvr_lpmode'] + ret_val = "xcvr validation failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['attr_list']: + if 'attr_name' in attr.keys() and 'eeprom' in attr.values(): + ret_val = "xcvr validation success" + else: + print "xcvr validation Failed" + return + + elif dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "Success" + else: + print "xcvr validation Failed" + return + print ret_val + + def validate_eeprom_device(self, dev, ops): + devtype_list = ['24c02'] + dev_access_mode = ['BLOCK', 'BYTE'] + dev_attribs = ['eeprom'] + ret_val = "eeprom failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + if dev['i2c']['dev_attr']['access_mode'] in dev_access_mode: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "eeprom success" + print ret_val + + def validate_mux_device(self, dev, ops): + devtype_list = ['pca9548', 'pca954x'] + dev_channels = ["0", "1", "2", "3", "4", "5", "6", "7"] + ret_val = "mux failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['channel']: + if attr.get("chn") in dev_channels: + ret_val = "Mux success" + print ret_val + + def validate_cpld_device(self, dev, ops): + devtype_list = ['i2c_cpld'] + ret_val = "cpld failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + ret_val = "cpld success" + print ret_val + + + def validate_sysstatus_device(self, dev, ops): + dev_attribs = ['board_info', 'cpld1_version', 'power_module_status', 'system_reset5', + 'system_reset6', 'system_reset7', 'misc1', 'cpld2_version', 'cpld3_version' + ] + ret_val = "sysstatus failed" + + if dev['dev_info']['device_type'] == "SYSSTAT": + for attr in dev['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "sysstatus success" + print ret_val + + def validate_temp_sensor_device(self, dev, ops): + devtype_list = ['lm75'] + dev_attribs = ['temp1_max', 'temp1_max_hyst', 'temp1_input'] + ret_val = "temp sensor failed" + + if dev['dev_info']['device_type'] == "TEMP_SENSOR": + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "tempsensor success" + print ret_val + + def validate_fan_device(self, dev, ops): + ret_val = "fan failed" + + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + if dev['i2c']['dev_attr']['num_fan'] is not None: + ret_val = "fan success" + + print ret_val + + def validate_psu_device(self, dev, ops): + dev_attribs = ['psu_present', 'psu_model_name', 'psu_power_good', 'psu_mfr_id', 'psu_serial_num', + 'psu_fan_dir', 'psu_v_out', 'psu_i_out', 'psu_p_out', 'psu_fan1_speed_rpm' + ] + ret_val = "psu failed" + + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + if attr.get("attr_devaddr") is not None: + if attr.get("attr_offset") is not None: + if attr.get("attr_mask") is not None: + if attr.get("attr_len") is not None: + ret_val = "psu success" + else: + ret_val = "psu failed" + + print ret_val + + ################################################################################################################### + # SPYTEST + ################################################################################################################### + def verify_attr(self, key, attr, path): + node="/sys/kernel/%s/%s"%(path, key) + try: + with open(node, 'r') as f: + status = f.read() + except IOError: + print "PDDF_VERIFY_ERR: IOError: node:%s key:%s"%(node, key) + return + + status=status.rstrip("\n\r") + if attr[key]!=status: + print "PDDF_VERIFY_ERR: node: %s switch:%s"%(node, status) + + def verify_device(self, attr, path, ops): + for key in attr.keys(): + self.verify_attr(key, attr, path) + + + def get_led_device(self, device_name): + self.create_attr('device_name', self.data[device_name]['dev_info']['device_name'], "pddf/devices/led") + self.create_attr('index', self.data[device_name]['dev_attr']['index'], "pddf/devices/led") + cmd="echo 'verify' > /sys/kernel/pddf/devices/led/dev_ops" + self.runcmd(cmd) + + def validate_sysfs_creation(self, obj, validate_type): + dir = '/sys/kernel/pddf/devices/'+validate_type + if (os.path.exists(dir) or validate_type=='client'): + for sysfs in obj[validate_type]: + if(not os.path.exists(sysfs)): + print "[SYSFS FILE] " + sysfs + ": does not exist" + else: + print "[SYSFS DIR] " + dir + ": does not exist" + + def validate_dsysfs_creation(self, obj, validate_type): + if validate_type in obj.keys(): + # There is a possibility that some components dont have any device-self.data attr + if not obj[validate_type]: + print "[SYSFS ATTR] for " + validate_type + ": empty " + else: + for sysfs in obj[validate_type]: + if(not os.path.exists(sysfs)): + print "[SYSFS FILE] " + sysfs + ": does not exist" + else: + print "[SYSFS KEY] for " + validate_type + ": not configured" + + def verify_sysfs_data(self, verify_type): + if (verify_type=='LED'): + for key in self.data.keys(): + if key != 'PLATFORM': + attr=self.data[key]['dev_info'] + if attr['device_type'] == 'LED': + self.get_led_device(key) + self.verify_attr('device_name', self.data[key]['dev_info'], "pddf/devices/led") + self.verify_attr('index', self.data[key]['dev_attr'], "pddf/devices/led") + for attr in self.data[key]['i2c']['attr_list']: + path="pddf/devices/led/" + attr['attr_name'] + for entry in attr.keys(): + if (entry != 'attr_name' and entry != 'swpld_addr' and entry != 'swpld_addr_offset'): + self.verify_attr(entry, attr, path) + if ( entry == 'swpld_addr' or entry == 'swpld_addr_offset'): + self.verify_attr(entry, attr, 'pddf/devices/led') + + + + def schema_validation(self, validate_type): + process_validate_type = 0 + for key in self.data.keys(): + if (key != 'PLATFORM'): + temp_obj={} + schema_list=[] + try: + device_type=self.data[key]["dev_info"]["device_type"] + except Exception as e: + print "dev_info or device_type ERROR: " + key + print e + + if validate_type == 'mismatch': + process_validate_type = 1 + device_type="PSU" + schema_file="/usr/local/bin/schema/FAN.schema" + schema_list.append(schema_file) + elif validate_type == 'missing': + process_validate_type = 1 + schema_file="/usr/local/bin/schema/PLATFORM.schema" + schema_list.append(schema_file) + + elif validate_type == 'empty': + process_validate_type = 1 + if not device_type: + print "Empty device_type for " + key + continue + elif (validate_type=='all' or validate_type==device_type): + process_validate_type = 1 + if "bmc" in self.data[key].keys(): + schema_file="/usr/local/bin/schema/"+device_type + "_BMC.schema" + schema_list.append(schema_file) + + if "i2c" in self.data[key].keys(): + schema_file="/usr/local/bin/schema/"+device_type + ".schema" + schema_list.append(schema_file) + if device_type: + temp_obj[device_type]=self.data[key] + for schema_file in schema_list: + if (os.path.exists(schema_file)): + print "Validate " + schema_file + ";" + key + json_data=json.dumps(temp_obj) + with open(schema_file, 'r') as f: + schema=json.load(f) + try: + validate(temp_obj, schema) + except Exception as e: + print "Validation ERROR: " + schema_file + ";" + key + if validate_type == 'mismatch': + return + else: + print e + else: + print "ERROR Missing File: " + schema_file + if not process_validate_type: + print "device_type: " + validate_type + " not configured" + + def modules_validation(self, validate_type): + kos = [] + supported_type = False + module_validation_status=[] + + if validate_type == "bmc": + kos=['ipmi_devintf', 'ipmi_si', 'ipmi_msghandler'] + validate_type = 'ipmi' + else: + # generate the KOS list from pddf device JSON file + kos.extend(self.data['PLATFORM']['pddf_kos']) + + if 'custom_kos' in self.data['PLATFORM']: + kos.extend(self.data['PLATFORM']['custom_kos']) + + for mod in kos: + if validate_type in mod or validate_type == "pddf": + supported_type=True + cmd = "lsmod | grep " + mod + try: + subprocess.check_output(cmd, shell=True) + except Exception as e: + module_validation_status.append(mod) + if supported_type: + if module_validation_status: + module_validation_status.append(":ERROR not loaded") + print str(module_validation_status)[1:-1] + else: + print "Loaded" + else: + print validate_type + " not configured" + + + + + + ################################################################################################################### + # PARSE DEFS + ################################################################################################################### + def psu_parse(self, dev, ops): + parse_str="" + ret="" + for ifce in dev['i2c']['interface']: + ret=getattr(self, ops['cmd']+"_psu_device")(self.data[ifce['dev']], ops ) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_psu_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + return parse_str + + def fan_parse(self, dev, ops): + parse_str="" + ret=getattr(self, ops['cmd']+"_fan_device")(dev, ops ) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_fan_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + def temp_sensor_parse(self, dev, ops): + parse_str="" + ret=getattr(self, ops['cmd']+"_temp_sensor_device")(dev, ops ) + if not ret is None: + if str(ret).isdigit() : + if ret!=0: + # in case if 'create' functions + print "{}_temp_sensor_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + def cpld_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_cpld_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_cpld_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + def cpldmux_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_cpldmux_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_cpldmux_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + for chan in dev['i2c']['channel']: + for device in chan['dev']: + ret = self.dev_parse(self.data[device], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + def cpldmux_parse_reverse(self, dev, ops): + parse_str = "" + for chan in reversed(dev['i2c']['channel']): + for device in reversed(chan['dev']): + ret = self.dev_parse(self.data[device], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + + ret = getattr(self, ops['cmd']+"_cpldmux_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_cpldmux_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + + def sysstatus_parse(self, dev,ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_sysstatus_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_sysstatus_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + def gpio_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_gpio_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_temp_sensor_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str += ret + + return parse_str + + + def mux_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_mux_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_mux_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + for ch in dev['i2c']['channel']: + ret = self.dev_parse(self.data[ch['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + def mux_parse_reverse(self, dev, ops): + parse_str = "" + for ch in reversed(dev['i2c']['channel']): + ret = self.dev_parse(self.data[ch['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + + ret = getattr(self, ops['cmd']+"_mux_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_mux_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + + def eeprom_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_eeprom_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_eeprom_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + def optic_parse(self, dev, ops): + parse_str="" + ret="" + for ifce in dev['i2c']['interface']: + ret=getattr(self, ops['cmd']+"_xcvr_device")(self.data[ifce['dev']], ops ) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_eeprom_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str+=ret + return parse_str + + def cpu_parse(self, bus, ops): + parse_str = "" + for dev in bus['i2c']['CONTROLLERS']: + dev1 = self.data[dev['dev']] + for d in dev1['i2c']['DEVICES']: + ret=self.dev_parse(self.data[d['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + def cpu_parse_reverse(self, bus, ops): + parse_str = "" + for dev in reversed(bus['i2c']['CONTROLLERS']): + dev1 = self.data[dev['dev']] + for d in reversed(dev1['i2c']['DEVICES']): + ret=self.dev_parse(self.data[d['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + + def dev_parse(self, dev, ops): + attr=dev['dev_info'] + if attr['device_type'] == 'CPU': + if ops['cmd']=='delete': + return self.cpu_parse_reverse(dev, ops) + else: + return self.cpu_parse(dev, ops) + + if attr['device_type'] == 'EEPROM': + return self.eeprom_parse(dev, ops) + + if attr['device_type'] == 'MUX': + if ops['cmd']=='delete': + return self.mux_parse_reverse(dev, ops) + else: + return self.mux_parse(dev, ops) + + if attr['device_type'] == 'GPIO': + return self.gpio_parse(dev, ops) + + if attr['device_type'] == 'PSU': + return self.psu_parse(dev, ops) + + if attr['device_type'] == 'FAN': + return self.fan_parse(dev, ops) + + if attr['device_type'] == 'TEMP_SENSOR': + return self.temp_sensor_parse(dev, ops) + + if attr['device_type'] == 'SFP' or attr['device_type'] == 'SFP28' or \ + attr['device_type'] == 'QSFP' or attr['device_type'] == 'QSFP28': + return self.optic_parse(dev, ops) + + if attr['device_type'] == 'CPLD': + return self.cpld_parse(dev, ops) + + if attr['device_type'] == 'CPLDMUX': + if ops['cmd']=='delete': + return self.cpldmux_parse_reverse(dev, ops) + else: + return self.cpldmux_parse(dev, ops) + + if attr['device_type'] == 'SYSSTAT': + return self.sysstatus_parse(dev,ops) + + def is_supported_sysled_state(self, sysled_name, sysled_state): + if not sysled_name in self.data.keys(): + return False, "[FAILED] " + sysled_name + " is not configured" + for attr in self.data[sysled_name]['i2c']['attr_list']: + if attr['attr_name'] == sysled_state: + return True, "[PASS] supported" + return False, "[FAILED]: Invalid color" + + + def create_attr(self, key, value, path): + cmd = "echo '%s' > /sys/kernel/%s/%s"%(value, path, key) + self.runcmd(cmd) + + def create_led_platform_device(self, key, ops): + if ops['attr']=='all' or ops['attr']=='PLATFORM': + path='pddf/devices/platform' + self.create_attr('num_psus', self.data['PLATFORM']['num_psus'], path) + self.create_attr('num_fantrays', self.data['PLATFORM']['num_fantrays'], path) + + def create_led_device(self, key, ops): + if ops['attr']=='all' or ops['attr']==self.data[key]['dev_info']['device_name']: + path="pddf/devices/led" + for attr in self.data[key]['i2c']['attr_list']: + self.create_attr('device_name', self.data[key]['dev_info']['device_name'], path) + self.create_device(self.data[key]['dev_attr'], path, ops) + for attr_key in attr.keys(): + if (attr_key == 'swpld_addr_offset' or attr_key == 'swpld_addr'): + self.create_attr(attr_key, attr[attr_key], path) + elif (attr_key != 'attr_name' and attr_key != 'descr' and + attr_key != 'attr_devtype' and attr_key != 'attr_devname'): + state_path=path+'/state_attr' + self.create_attr(attr_key, attr[attr_key],state_path) + cmd="echo '" + attr['attr_name']+"' > /sys/kernel/pddf/devices/led/dev_ops" + self.runcmd(cmd) + + + + def led_parse(self, ops): + getattr(self, ops['cmd']+"_led_platform_device")("PLATFORM", ops) + for key in self.data.keys(): + if key != 'PLATFORM' and 'dev_info' in self.data[key]: + attr=self.data[key]['dev_info'] + if attr['device_type'] == 'LED': + getattr(self, ops['cmd']+"_led_device")(key, ops) + + + def get_device_list(self, list, type): + for key in self.data.keys(): + if key != 'PLATFORM' and 'dev_info' in self.data[key]: + attr=self.data[key]['dev_info'] + if attr['device_type'] == type: + list.append(self.data[key]) + + + def create_pddf_devices(self): + self.led_parse({ "cmd": "create", "target":"all", "attr":"all" }) + create_ret = 0 + create_ret = self.dev_parse(self.data['SYSTEM'], { "cmd": "create", "target":"all", "attr":"all" } ) + if create_ret!=0: + return create_ret + if 'SYSSTATUS' in self.data: + create_ret = self.dev_parse(self.data['SYSSTATUS'], { "cmd": "create", "target":"all", "attr":"all" } ) + if create_ret!=0: + return create_ret + + def delete_pddf_devices(self): + self.dev_parse(self.data['SYSTEM'], { "cmd": "delete", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], { "cmd": "delete", "target":"all", "attr":"all" } ) + + def populate_pddf_sysfsobj(self): + self.dev_parse(self.data['SYSTEM'], { "cmd": "show", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], { "cmd": "show", "target":"all", "attr":"all" } ) + self.led_parse({ "cmd": "show", "target":"all", "attr":"all" }) + self.show_client_device() + + def cli_dump_dsysfs(self, component): + self.dev_parse(self.data['SYSTEM'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if component in self.data_sysfs_obj: + return self.data_sysfs_obj[component] + else: + return None + + + def validate_pddf_devices(self, *args): + self.populate_pddf_sysfsobj() + v_ops = { 'cmd': 'validate', 'target':'all', 'attr':'all' } + self.dev_parse(self.data['SYSTEM'], v_ops ) + + ################################################################################################################## + # BMC APIs + ################################################################################################################## + def populate_bmc_cache_db(self, bmc_attr): + bmc_cmd = str(bmc_attr['bmc_cmd']).strip() + + if 'delimiter' in bmc_attr.keys(): + delim = str(bmc_attr['delimiter']).strip() + else: + delim = None + + o_list = subprocess.check_output(bmc_cmd, shell=True).strip().split('\n') + bmc_cache[bmc_cmd]={} + bmc_cache[bmc_cmd]['time']=time.time() + for entry in o_list: + name = entry.split(delim)[0].strip() + bmc_cache[bmc_cmd][name]=entry + + def non_raw_ipmi_get_request(self, bmc_attr): + bmc_db_update_time=1 + value = 'N/A' + bmc_cmd = str(bmc_attr['bmc_cmd']).strip() + field_name = str(bmc_attr['field_name']).strip() + field_pos= int(bmc_attr['field_pos'])-1 + + if 'delimiter' in bmc_attr.keys(): + delim = str(bmc_attr['delimiter']).strip() + else: + delim = None + + if not bmc_cmd in bmc_cache: + self.populate_bmc_cache_db(bmc_attr) + else: + now = time.time() + if (int(now - bmc_cache[bmc_cmd]['time']) > bmc_db_update_time): + self.populate_bmc_cache_db(bmc_attr) + + try: + data=bmc_cache[bmc_cmd][field_name] + value = data.split(delim)[field_pos].strip() + except Exception as e: + pass + + if 'mult' in bmc_attr.keys() and not value.isalpha(): + if value.isalpha(): + value = 0.0 + value = float(value) * float(bmc_attr['mult']) + + return str(value) + + def raw_ipmi_get_request(self, bmc_attr): + value = 'N/A' + cmd = bmc_attr['bmc_cmd'] + " 2>/dev/null" + if bmc_attr['type'] == 'raw': + try: + value = subprocess.check_output(cmd, shell=True).strip() + except Exception as e: + pass + + if value != 'N/A': + value = str(int(value, 16)) + return value + + if bmc_attr['type'] == 'mask': + mask = int(bmc_attr['mask'].encode('utf-8'), 16) + try: + value = subprocess.check_output(cmd, shell=True).strip() + except Exception as e: + pass + + # value should either be '1' or '0' + if value != 'N/A': + value = '1' if bool(int(value, 16) & mask) else '0' + + return value + + if bmc_attr['type'] == 'ascii': + try: + value = subprocess.check_output(cmd, shell=True) + except Exception as e: + pass + + if value != 'N/A': + tmp = ''.join(chr(int(i, 16)) for i in value.split()) + tmp = "".join(i for i in unicode(tmp) if unicodedata.category(i)[0]!="C") + value = str(tmp) + + return (value) + + return value + + def bmc_get_cmd(self, bmc_attr): + if int(bmc_attr['raw']) == 1: + value = self.raw_ipmi_get_request(bmc_attr) + else: + value = self.non_raw_ipmi_get_request(bmc_attr) + return (value) + + def non_raw_ipmi_set_request(self, bmc_attr, val): + value = 'N/A' + # TODO: Implement it + return value + + def raw_ipmi_set_request(self, bmc_attr, val): + value = 'N/A' + # TODO: Implement this + return value + + def bmc_set_cmd(self, bmc_attr, val): + if int(bmc_attr['raw']) == 1: + value = self.raw_ipmi_set_request(bmc_attr, val) + else: + value = self.non_raw_ipmi_set_request(bmc_attr, val) + return (value) + + # bmc-based attr: return attr obj + # non-bmc-based attr: return empty obj + def check_bmc_based_attr(self, device_name, attr_name): + if device_name in self.data.keys(): + if "bmc" in self.data[device_name].keys() and 'ipmitool' in self.data[device_name]['bmc'].keys(): + attr_list = self.data[device_name]['bmc']['ipmitool']['attr_list'] + for attr in attr_list: + if attr['attr_name'].strip() == attr_name.strip(): + return attr + # Required attr_name is not supported in BMC object + return {} + return None + + def get_attr_name_output(self, device_name, attr_name): + bmc_attr = self.check_bmc_based_attr(device_name, attr_name) + output={"mode":"", "status":""} + + if bmc_attr is not None: + if bmc_attr=={}: + return {} + output['mode']="bmc" + output['status']=self.bmc_get_cmd(bmc_attr) + else: + output['mode']="i2c" + node = self.get_path(device_name, attr_name) + if node is None: + return {} + try: + with open(node, 'r') as f: + output['status'] = f.read() + except IOError: + return {} + return output + + def set_attr_name_output(self, device_name, attr_name, val): + bmc_attr = self.check_bmc_based_attr(device_name, attr_name) + output={"mode":"", "status":""} + + if bmc_attr is not None: + if bmc_attr=={}: + return {} + output['mode']="bmc" + output['status']=False # No set operation allowed for BMC attributes as they are handled by BMC itself + else: + output['mode']="i2c" + node = self.get_path(device_name, attr_name) + if node is None: + return {} + try: + with open(node, 'w') as f: + f.write(str(val)) + except IOError: + return {} + + output['status'] = True + + return output + + ################################################################################################################### + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--create", action='store_true', help="create the I2C topology") + parser.add_argument("--sysfs", action='store', nargs="+", help="show access-attributes sysfs for the I2C topology") + parser.add_argument("--dsysfs", action='store', nargs="+", help="show data-attributes sysfs for the I2C topology") + parser.add_argument("--delete", action='store_true', help="Remove all the created I2C clients from topology") + parser.add_argument("--validate", action='store', help="Validate the device specific attribute data elements") + parser.add_argument("--schema", action='store', nargs="+", help="Schema Validation") + parser.add_argument("--modules", action='store', nargs="+", help="Loaded modules validation") + + args = parser.parse_args() + + # Create the object + try: + pddf_obj = PddfParse() + except Exception as e: + print "%s" % str(e) + sys.exit() + + if args.create: + pddf_obj.create_pddf_devices() + + if args.sysfs: + if args.sysfs[0] == 'all': + pddf_obj.populate_pddf_sysfsobj() + if args.sysfs[0] == 'print': + pddf_obj.populate_pddf_sysfsobj() + pddf_obj.dump_sysfs_obj(pddf_obj.sysfs_obj, args.sysfs[1]) + if args.sysfs[0] == 'validate': + pddf_obj.populate_pddf_sysfsobj() + pddf_obj.validate_sysfs_creation(pddf_obj.sysfs_obj, args.sysfs[1]) + if args.sysfs[0] == 'verify': + pddf_obj.verify_sysfs_data(args.sysfs[1]) + + + if args.dsysfs: + if args.dsysfs[0] == 'validate': + pddf_obj.dev_parse(pddf_obj.data['SYSTEM'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in pddf_obj.data: + pddf_obj.dev_parse(pddf_obj.data['SYSSTATUS'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + pddf_obj.validate_dsysfs_creation(pddf_obj.data_sysfs_obj, args.dsysfs[1]) + + elif args.dsysfs[0] == 'print': + pddf_obj.dev_parse(pddf_obj.data['SYSTEM'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in pddf_obj.data: + pddf_obj.dev_parse(pddf_obj.data['SYSSTATUS'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + pddf_obj.dump_sysfs_obj(pddf_obj.data_sysfs_obj, args.dsysfs[1]) + + elif args.dsysfs[0] == 'all': + ret = pddf_obj.dev_parse(pddf_obj.data['SYSTEM'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in pddf_obj.data: + ret += pddf_obj.dev_parse(pddf_obj.data['SYSSTATUS'], { "cmd": "show_attr", "target":"all", + "attr":"all" } ) + pddf_obj.dump_sysfs_obj(pddf_obj.data_sysfs_obj, 'all') + else: + pddf_obj.dev_parse(pddf_obj.data[args.dsysfs[0]], { "cmd": "show_attr", "target":args.dsysfs[0], + "attr":args.dsysfs[1] }) + + if args.delete: + pddf_obj.delete_pddf_devices() + + if args.validate: + if args.validate[0] == 'all': + pddf_obj.validate_pddf_devices(args.validate[1:]) + else: + pass + + if args.schema: + pddf_obj.schema_validation(args.schema[0]) + + if args.modules: + pddf_obj.modules_validation(args.modules[0]) + + + +if __name__ == "__main__" : + main() diff --git a/platform/pddf/i2c/utils/schema/CPLD.schema b/platform/pddf/i2c/utils/schema/CPLD.schema new file mode 100644 index 000000000000..c2f8c0de842f --- /dev/null +++ b/platform/pddf/i2c/utils/schema/CPLD.schema @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "CPLD": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "dev_attr": { + "type": "object" + } + }, + "required": [ + "topo_info" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "CPLD" + ] +} diff --git a/platform/pddf/i2c/utils/schema/CPU.schema b/platform/pddf/i2c/utils/schema/CPU.schema new file mode 100644 index 000000000000..9bb07ae0f6bb --- /dev/null +++ b/platform/pddf/i2c/utils/schema/CPU.schema @@ -0,0 +1,80 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "CPU": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "null" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "CONTROLLERS": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "dev_name": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "dev_name", + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev_name": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "dev_name", + "dev" + ] + } + ] + } + }, + "required": [ + "CONTROLLERS" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "CPU" + ] +} diff --git a/platform/pddf/i2c/utils/schema/EEPROM.schema b/platform/pddf/i2c/utils/schema/EEPROM.schema new file mode 100644 index 000000000000..a8e8885e3ad1 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/EEPROM.schema @@ -0,0 +1,93 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "EEPROM": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "access_mode": { + "type": "string" + } + }, + "required": [ + "access_mode" + ] + }, + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + } + }, + "required": [ + "attr_name" + ] + } + ] + } + }, + "required": [ + "topo_info", + "dev_attr", + "attr_list" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "EEPROM" + ] +} diff --git a/platform/pddf/i2c/utils/schema/FAN.schema b/platform/pddf/i2c/utils/schema/FAN.schema new file mode 100644 index 000000000000..069007533130 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/FAN.schema @@ -0,0 +1,113 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "FAN": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "num_fantrays": { + "type": "string" + } + }, + "required": [ + "num_fantrays" + ] + }, + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devtype": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_cmpval": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devtype", + "attr_offset", + "attr_mask", + "attr_cmpval", + "attr_len" + ] + } + ] + } + }, + "required": [ + "topo_info", + "dev_attr", + "attr_list" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "FAN" + ] +} diff --git a/platform/pddf/i2c/utils/schema/FAN_BMC.schema b/platform/pddf/i2c/utils/schema/FAN_BMC.schema new file mode 100644 index 000000000000..41d774dfa6bd --- /dev/null +++ b/platform/pddf/i2c/utils/schema/FAN_BMC.schema @@ -0,0 +1,69 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "FAN": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + } + }, + "required": [ + "device_type" + ] + }, + "bmc": { + "type": "object", + "properties": { + "ipmitool": { + "type": "object", + "properties": { + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw" + ] + } + ] + } + }, + "required": [ + "attr_list" + ] + } + }, + "required": [ + "ipmitool" + ] + } + }, + "required": [ + "dev_info", + "bmc" + ] + } + }, + "required": [ + "FAN" + ] +} diff --git a/platform/pddf/i2c/utils/schema/LED.schema b/platform/pddf/i2c/utils/schema/LED.schema new file mode 100644 index 000000000000..04583ee660aa --- /dev/null +++ b/platform/pddf/i2c/utils/schema/LED.schema @@ -0,0 +1,120 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "LED": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "index": { + "type": "string" + } + }, + "required": [ + "index" + ] + }, + "i2c": { + "type": "object", + "properties": { + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bits": { + "type": "string" + }, + "color": { + "type": "string" + }, + "value": { + "type": "string" + }, + "swpld_addr": { + "type": "string" + }, + "swpld_addr_offset": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bits", + "color", + "value", + "swpld_addr", + "swpld_addr_offset" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bits": { + "type": "string" + }, + "color": { + "type": "string" + }, + "value": { + "type": "string" + }, + "swpld_addr": { + "type": "string" + }, + "swpld_addr_offset": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bits", + "color", + "value", + "swpld_addr", + "swpld_addr_offset" + ] + } + ] + } + }, + "required": [ + "attr_list" + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "i2c" + ] + } + }, + "required": [ + "LED" + ] +} diff --git a/platform/pddf/i2c/utils/schema/MUX.schema b/platform/pddf/i2c/utils/schema/MUX.schema new file mode 100644 index 000000000000..6ef46e8dd2a9 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/MUX.schema @@ -0,0 +1,97 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "MUX": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "virt_bus": { + "type": "string" + } + }, + "required": [ + "virt_bus" + ] + }, + "channel": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "chn": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "chn", + "dev" + ] + } + ] + } + }, + "required": [ + "topo_info", + "dev_attr", + "channel" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "MUX" + ] +} diff --git a/platform/pddf/i2c/utils/schema/PSU-PMBUS.schema b/platform/pddf/i2c/utils/schema/PSU-PMBUS.schema new file mode 100644 index 000000000000..6516d2321371 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/PSU-PMBUS.schema @@ -0,0 +1,109 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "PSU-PMBUS": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + }, + "virt_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent", + "virt_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_devtype": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_cmpval": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_devtype", + "attr_offset", + "attr_mask", + "attr_cmpval", + "attr_len" + ] + } + ] + } + }, + "required": [ + "topo_info", + "attr_list" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "PSU-PMBUS" + ] +} diff --git a/platform/pddf/i2c/utils/schema/PSU.schema b/platform/pddf/i2c/utils/schema/PSU.schema new file mode 100644 index 000000000000..5ed53df4572f --- /dev/null +++ b/platform/pddf/i2c/utils/schema/PSU.schema @@ -0,0 +1,81 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "PSU": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "dev_idx": { + "type": "string" + }, + "num_psu_fans": { + "type": "string" + } + }, + "required": [ + "dev_idx", + "num_psu_fans" + ] + }, + "i2c": { + "type": "object", + "properties": { + "interface": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "itf": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "itf", + "dev" + ] + } + ] + } + }, + "required": [ + "interface" + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "i2c" + ] + } + }, + "required": [ + "PSU" + ] +} diff --git a/platform/pddf/i2c/utils/schema/PSU_BMC.schema b/platform/pddf/i2c/utils/schema/PSU_BMC.schema new file mode 100644 index 000000000000..299e79dd7854 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/PSU_BMC.schema @@ -0,0 +1,336 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "PSU": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + } + }, + "required": [ + "device_type" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "dev_idx": { + "type": "string" + }, + "num_psu_fans": { + "type": "string" + } + }, + "required": [ + "dev_idx", + "num_psu_fans" + ] + }, + "bmc": { + "type": "object", + "properties": { + "ipmitool": { + "type": "object", + "properties": { + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "type": { + "type": "string" + }, + "mask": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "type", + "mask" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "type" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "type" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "type" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "type" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + }, + "mult": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos", + "mult" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + }, + "mult": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos", + "mult" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + }, + "mult": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos", + "mult" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + }, + "mult": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos", + "mult" + ] + } + ] + } + }, + "required": [ + "attr_list" + ] + } + }, + "required": [ + "ipmitool" + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "bmc" + ] + } + }, + "required": [ + "PSU" + ] +} diff --git a/platform/pddf/i2c/utils/schema/QSFP.schema b/platform/pddf/i2c/utils/schema/QSFP.schema new file mode 100644 index 000000000000..be8e75a9cd1f --- /dev/null +++ b/platform/pddf/i2c/utils/schema/QSFP.schema @@ -0,0 +1,92 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "QSFP": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "dev_idx": { + "type": "string" + } + }, + "required": [ + "dev_idx" + ] + }, + "i2c": { + "type": "object", + "properties": { + "interface": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "itf": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "itf", + "dev" + ] + }, + { + "type": "object", + "properties": { + "itf": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "itf", + "dev" + ] + } + ] + } + }, + "required": [ + "interface" + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "i2c" + ] + } + }, + "required": [ + "QSFP" + ] +} diff --git a/platform/pddf/i2c/utils/schema/SMBUS.schema b/platform/pddf/i2c/utils/schema/SMBUS.schema new file mode 100644 index 000000000000..91429a1d7ee8 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/SMBUS.schema @@ -0,0 +1,128 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "SMBUS": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "dev_addr": { + "type": "string" + } + }, + "required": [ + "dev_addr" + ] + }, + "DEVICES": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + } + ] + } + }, + "required": [ + "topo_info", + "DEVICES" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "SMBUS" + ] +} diff --git a/platform/pddf/i2c/utils/schema/SYSSTAT.schema b/platform/pddf/i2c/utils/schema/SYSSTAT.schema new file mode 100644 index 000000000000..d31e10c27222 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/SYSSTAT.schema @@ -0,0 +1,285 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "SYSSTAT": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name" + ] + }, + "dev_attr": { + "type": "object" + }, + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + } + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "attr_list" + ] + } + }, + "required": [ + "SYSSTAT" + ] +} diff --git a/platform/pddf/i2c/utils/schema/TEMP_SENSOR.schema b/platform/pddf/i2c/utils/schema/TEMP_SENSOR.schema new file mode 100644 index 000000000000..0bc2ce8b8303 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/TEMP_SENSOR.schema @@ -0,0 +1,102 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "TEMP_SENSOR": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + } + }, + "required": [ + "attr_name" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + } + }, + "required": [ + "attr_name" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + } + }, + "required": [ + "attr_name" + ] + } + ] + } + }, + "required": [ + "topo_info", + "attr_list" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "TEMP_SENSOR" + ] +} diff --git a/platform/pddf/i2c/utils/schema/TEMP_SENSOR_BMC.schema b/platform/pddf/i2c/utils/schema/TEMP_SENSOR_BMC.schema new file mode 100644 index 000000000000..c8f7c447b718 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/TEMP_SENSOR_BMC.schema @@ -0,0 +1,143 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "TEMP_SENSOR": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + } + }, + "required": [ + "device_type" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + } + }, + "required": [ + "display_name" + ] + }, + "bmc": { + "type": "object", + "properties": { + "ipmitool": { + "type": "object", + "properties": { + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos" + ] + } + ] + } + }, + "required": [ + "attr_list" + ] + } + }, + "required": [ + "ipmitool" + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "bmc" + ] + } + }, + "required": [ + "TEMP_SENSOR" + ] +} diff --git a/platform/pddf/platform-api-pddf-base.dep b/platform/pddf/platform-api-pddf-base.dep new file mode 100644 index 000000000000..9184925b1e6f --- /dev/null +++ b/platform/pddf/platform-api-pddf-base.dep @@ -0,0 +1,9 @@ + +MPATH := $($(PDDF_PLATFORM_API_BASE_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/pddf/platform-api-pddf-base.mk platform/pddf/platform-api-pddf-base.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(PDDF_PLATFORM_API_BASE_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(PDDF_PLATFORM_API_BASE_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PDDF_PLATFORM_API_BASE_PY2)_DEP_FILES := $(DEP_FILES) diff --git a/platform/pddf/platform-api-pddf-base.mk b/platform/pddf/platform-api-pddf-base.mk new file mode 100644 index 000000000000..80478d4f3db1 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base.mk @@ -0,0 +1,15 @@ +#################################################### +# PDDF Generic 2.0 Platform API base classes +#################################################### +PDDF_PLATFORM_API_BASE_VERSION = 1.0 + +export PDDF_PLATFORM_API_BASE_VERSION + +PDDF_PLATFORM_API_BASE_PY2 = sonic_platform_pddf_common-$(PDDF_PLATFORM_API_BASE_VERSION)-py2-none-any.whl +$(PDDF_PLATFORM_API_BASE_PY2)_SRC_PATH = $(PLATFORM_PDDF_PATH)/platform-api-pddf-base +$(PDDF_PLATFORM_API_BASE_PY2)_PYTHON_VERSION = 2 +$(PDDF_PLATFORM_API_BASE_PY2)_DEPENDS = $(SONIC_CONFIG_ENGINE) +SONIC_PYTHON_WHEELS += $(PDDF_PLATFORM_API_BASE_PY2) + +export pddf_platform_api_base_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(PDDF_PLATFORM_API_BASE_PY2))" +export PDDF_PLATFORM_API_BASE_PY2 diff --git a/platform/pddf/platform-api-pddf-base/setup.py b/platform/pddf/platform-api-pddf-base/setup.py new file mode 100755 index 000000000000..5f5ac9194cd9 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/setup.py @@ -0,0 +1,30 @@ + +from setuptools import setup + +setup( + name='sonic-platform-pddf-common', + version='1.0', + description='SONIC platform APIs base (2.0) implementation on PDDF supported platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Fuzail Khan', + maintainer_email='fuzail.khan@broadcom.com', + packages=[ + 'sonic_platform_pddf_base', + ], + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/__init__.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_chassis.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_chassis.py new file mode 100755 index 000000000000..942be25ed1c7 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_chassis.py @@ -0,0 +1,516 @@ +#!/usr/bin/env python + +############################################################################# +# PDDF +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import sys + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.psu import Psu + from sonic_platform.fan import Fan + from sonic_platform.thermal import Thermal + from sonic_platform.eeprom import Eeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class PddfChassis(ChassisBase): + """ + PDDF Generic Chassis class + """ + pddf_obj = {} + plugin_data = {} + + def __init__(self, pddf_data=None, pddf_plugin_data=None): + + ChassisBase.__init__(self) + + self.pddf_obj = pddf_data if pddf_data else None + self.plugin_data = pddf_plugin_data if pddf_plugin_data else None + if not self.pddf_obj or not self.plugin_data: + try: + import pddfparse + import json + self.pddf_obj = pddfparse.PddfParse() + with open('/usr/share/sonic/platform/pddf/pd-plugin.json') as pd: + self.plugin_data = json.load(pd) + except Exception as e: + raise Exception("Error: Unable to load PDDF JSON data - %s" % str(e)) + + self.platform_inventory = self.pddf_obj.get_platform() + + # Initialize EEPROM + self.sys_eeprom = Eeprom(self.pddf_obj, self.plugin_data) + + # FANs + for i in range(self.platform_inventory['num_fantrays']): + for j in range(self.platform_inventory['num_fans_pertray']): + fan = Fan(i, j, self.pddf_obj, self.plugin_data) + self._fan_list.append(fan) + + # PSUs + for i in range(self.platform_inventory['num_psus']): + psu = Psu(i, self.pddf_obj, self.plugin_data) + self._psu_list.append(psu) + + # OPTICs + for index in range(self.platform_inventory['num_ports']): + sfp = Sfp(index, self.pddf_obj, self.plugin_data) + self._sfp_list.append(sfp) + + # THERMALs + for i in range(self.platform_inventory['num_temps']): + thermal = Thermal(i, self.pddf_obj, self.plugin_data) + self._thermal_list.append(thermal) + + # SYSTEM LED Test Cases + """ + #comment out test cases + sys_led_list= { "LOC":0, + "DIAG":0, + "FAN":0, + "SYS":0, + "PSU1":0, + "PSU2":1 + } + + for led in sys_led_list: + color=self.get_system_led(led, sys_led_list[led]) + print color + + self.set_system_led("LOC_LED","STATUS_LED_COLOR_GREEN") + color=self.get_system_led("LOC_LED") + print "Set Green: " + color + self.set_system_led("LOC_LED", "STATUS_LED_COLOR_OFF") + color=self.get_system_led("LOC_LED") + print "Set off: " + color + """ + + + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self.sys_eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self.sys_eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self.sys_eeprom.serial_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self.sys_eeprom.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this + chassis. + """ + return self.sys_eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self.sys_eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + raise NotImplementedError + + def get_component_name_list(self): + """ + Retrieves a list of the names of components available on the chassis (e.g., BIOS, CPLD, FPGA, etc.) + + Returns: + A list containing the names of components available on the chassis + """ + return self._component_name_list + + def get_firmware_version(self, component_name): + """ + Retrieves platform-specific hardware/firmware versions for chassis + componenets such as BIOS, CPLD, FPGA, etc. + Args: + component_name: A string, the component name. + + Returns: + A string containing platform-specific component versions + """ + raise NotImplementedError + + def install_component_firmware(self, component_name, image_path): + """ + Install firmware to component + Args: + component_name: A string, the component name. + image_path: A string, path to firmware image. + + Returns: + A boolean, True if install was successful, False if not + """ + raise NotImplementedError + + ############################################## + # Module methods + ############################################## + + def get_num_modules(self): + """ + Retrieves the number of modules available on this chassis + + Returns: + An integer, the number of modules available on this chassis + """ + return len(self._module_list) + + def get_all_modules(self): + """ + Retrieves all modules available on this chassis + + Returns: + A list of objects derived from ModuleBase representing all + modules available on this chassis + """ + return self._module_list + + def get_module(self, index): + """ + Retrieves module represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the module to + retrieve + + Returns: + An object dervied from ModuleBase representing the specified + module + """ + module = None + + try: + module = self._module_list[index] + except IndexError: + sys.stderr.write("Module index {} out of range (0-{})\n".format( + index, len(self._module_list)-1)) + + return module + ############################################## + # Fan methods + ############################################## + + def get_num_fans(self): + """ + Retrieves the number of fans available on this chassis + + Returns: + An integer, the number of fan modules available on this chassis + """ + return len(self._fan_list) + + def get_all_fans(self): + """ + Retrieves all fan modules available on this chassis + + Returns: + A list of objects derived from FanBase representing all fan + modules available on this chassis + """ + return self._fan_list + + def get_fan(self, index): + """ + Retrieves fan module represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the fan module to + retrieve + + Returns: + An object dervied from FanBase representing the specified fan + module + """ + fan = None + + try: + fan = self._fan_list[index] + except IndexError: + sys.stderr.write("Fan index {} out of range (0-{})\n".format( + index, len(self._fan_list)-1)) + + return fan + + ############################################## + # PSU methods + ############################################## + + def get_num_psus(self): + """ + Retrieves the number of power supply units available on this chassis + + Returns: + An integer, the number of power supply units available on this + chassis + """ + return len(self._psu_list) + + def get_all_psus(self): + """ + Retrieves all power supply units available on this chassis + + Returns: + A list of objects derived from PsuBase representing all power + supply units available on this chassis + """ + return self._psu_list + + def get_psu(self, index): + """ + Retrieves power supply unit represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the power supply unit to + retrieve + + Returns: + An object dervied from PsuBase representing the specified power + supply unit + """ + psu = None + + try: + psu = self._psu_list[index] + except IndexError: + sys.stderr.write("PSU index {} out of range (0-{})\n".format( + index, len(self._psu_list)-1)) + + return psu + + ############################################## + # THERMAL methods + ############################################## + + def get_num_thermals(self): + """ + Retrieves the number of thermals available on this chassis + + Returns: + An integer, the number of thermals available on this chassis + """ + return len(self._thermal_list) + + def get_all_thermals(self): + """ + Retrieves all thermals available on this chassis + + Returns: + A list of objects derived from ThermalBase representing all thermals + available on this chassis + """ + return self._thermal_list + + def get_thermal(self, index): + """ + Retrieves thermal unit represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the thermal to + retrieve + + Returns: + An object dervied from ThermalBase representing the specified thermal + """ + thermal = None + + try: + thermal = self._thermal_list[index] + except IndexError: + sys.stderr.write("THERMAL index {} out of range (0-{})\n".format( + index, len(self._thermal_list)-1)) + + return thermal + + ############################################## + # SFP methods + ############################################## + + def get_num_sfps(self): + """ + Retrieves the number of sfps available on this chassis + + Returns: + An integer, the number of sfps available on this chassis + """ + return len(self._sfp_list) + + def get_all_sfps(self): + """ + Retrieves all sfps available on this chassis + + Returns: + A list of objects derived from SfpBase representing all sfps + available on this chassis + """ + return self._sfp_list + + def get_sfp(self, index): + """ + Retrieves sfp represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 0. + For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + sfp = self._sfp_list[index] + except IndexError: + sys.stderr.write("SFP index {} out of range (0-{})\n".format( + index, len(self._sfp_list)-1)) + + return sfp + + ############################################## + # System LED methods + ############################################## + def set_system_led(self, led_device_name, color): + result, msg = self.pddf_obj.is_supported_sysled_state(led_device_name, color); + if result == False: + print msg + return (False) + + index=self.pddf_obj.data[led_device_name]['dev_attr']['index'] + device_name=self.pddf_obj.data[led_device_name]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('color', color, self.pddf_obj.get_led_cur_state_path()) + self.pddf_obj.create_attr('dev_ops', 'set_status', self.pddf_obj.get_led_path()) + return (True) + + + def get_system_led(self, led_device_name): + if (not led_device_name in self.pddf_obj.data.keys()): + status= "[FAILED] " + led_device_name + " is not configured" + return (status) + + index=self.pddf_obj.data[led_device_name]['dev_attr']['index'] + device_name=self.pddf_obj.data[led_device_name]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('dev_ops', 'get_status', self.pddf_obj.get_led_path()) + color=self.pddf_obj.get_led_color() + return (color) + + + ############################################## + # Other methods + ############################################## + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + return self._watchdog + + def get_eeprom(self): + """ + Retreives eeprom device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + eeprom device + """ + return self.sys_eeprom + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + raise NotImplementedError + diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_eeprom.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_eeprom.py new file mode 100644 index 000000000000..95ca7b574622 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_eeprom.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python + +############################################################################# +# PDDF +# +# PDDF syseeprom base class inherited from the base class +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo + import binascii +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + + +class PddfEeprom(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + pddf_obj = {} + plugin_data = {} + + def __init__(self, pddf_data=None, pddf_plugin_data=None): + if not pddf_data or not pddf_plugin_data: + raise ValueError('PDDF JSON data error') + + self.pddf_obj = pddf_data + self.plugin_data = pddf_plugin_data + + # system EEPROM always has device name EEPROM1 + self.eeprom_path = self.pddf_obj.get_path("EEPROM1", "eeprom") + if self.eeprom_path is None: + return + + super(PddfEeprom, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_tlv_dict = dict() + try: + self.eeprom_data = self.read_eeprom() + except: + self.eeprom_data = "N/A" + raise RuntimeError("PddfEeprom is not Programmed") + else: + eeprom = self.eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + ord(eeprom[tlv_index + 1])] + code = "0x%02X" % (ord(tlv[0])) + + if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | + (ord(tlv[4]) << 8) | ord(tlv[5])) + value += str(tlv[6:6 + ord(tlv[1])]) + else: + name, value = self.decoder(None, tlv) + + self.eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+1]) + 2 + + def serial_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2] + + def base_mac_addr(self): + (is_valid, t) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(TlvInfoDecoder, self).switchaddrstr(e) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def serial_str(self): + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2] + + def revision_str(self): + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2] + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.eeprom_tlv_dict diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_fan.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_fan.py new file mode 100755 index 000000000000..f189ca2a4e2e --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_fan.py @@ -0,0 +1,332 @@ +#!/usr/bin/env python + +# All the supported FAN SysFS aattributes are +#- fan_present +#- fan_direction +#- fan_input +#- fan_pwm +#- fan_fault +# where idx is in the range [1-32] +# + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PddfFan(FanBase): + """PDDF generic Fan class""" + + pddf_obj = {} + plugin_data = {} + + def __init__(self, tray_idx, fan_idx=0, pddf_data=None, pddf_plugin_data=None, is_psu_fan=False, psu_index=0): + # idx is 0-based + if not pddf_data or not pddf_plugin_data: + raise ValueError('PDDF JSON data error') + + self.pddf_obj = pddf_data + self.plugin_data = pddf_plugin_data + self.platform = self.pddf_obj.get_platform() + + if tray_idx<0 or tray_idx>=self.platform['num_fantrays']: + print "Invalid fantray index %d\n"%tray_idx + return + + if fan_idx<0 or fan_idx>=self.platform['num_fans_pertray']: + print "Invalid fan index (within a tray) %d\n"%fan_idx + return + + self.fantray_index = tray_idx+1 + self.fan_index = fan_idx+1 + self.is_psu_fan = is_psu_fan + if self.is_psu_fan: + self.fans_psu_index = psu_index + + def get_name(self): + """ + Retrieves the fan name + Returns: String containing fan-name + """ + if self.is_psu_fan: + return "PSU{}_FAN{}".format(self.fans_psu_index, self.fan_index) + else: + if 'name' in self.plugin_data['FAN']: + return self.plugin_data['FAN']['name'][str(self.fantray_index)] + else: + return "Fantray{}_{}".format(self.fantray_index, self.fan_index) + + def get_presence(self): + if self.is_psu_fan: + return True + else: + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr_name = "fan" + str(idx) + "_present" + output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr_name) + if not output: + return False + + mode = output['mode'] + presence = output['status'].rstrip() + + vmap = self.plugin_data['FAN']['present'][mode]['valmap'] + + if presence in vmap: + status = vmap[presence] + else: + status = False + + return status + + def get_status(self): + speed = self.get_speed() + status = True if (speed != 0) else False + return status + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + if self.is_psu_fan: + device = "PSU{}".format(self.fans_psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_fan_dir") + if not output: + return False + + mode = output['mode'] + val = output['status'] + + val = val.rstrip() + vmap = self.plugin_data['PSU']['psu_fan_dir'][mode]['valmap'] + + if val in vmap: + direction = vmap[val] + else: + direction = val + + else: + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr = "fan" + str(idx) + "_direction" + output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr) + if not output: + return False + + mode = output['mode'] + val = output['status'] + + val = val.rstrip() + vmap = self.plugin_data['FAN']['direction'][mode]['valmap'] + if val in vmap: + direction = vmap[val] + else: + direction = val + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + if self.is_psu_fan: + attr = "psu_fan{}_speed_rpm".format(self.fan_index) + device = "PSU{}".format(self.fans_psu_index) + output = self.pddf_obj.get_attr_name_output(device, attr) + if not output: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + speed = int(output['status']) + + max_speed = int(self.plugin_data['PSU']['PSU_FAN_MAX_SPEED']) + speed_percentage = (speed*100)/max_speed + return speed_percentage + else: + # TODO This calculation should change based on MAX FAN SPEED + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr = "fan" + str(idx) + "_pwm" + output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr) + + if not output: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + fpwm = int(output['status']) + + pwm_to_dc = eval(self.plugin_data['FAN']['pwm_to_duty_cycle']) + speed_percentage = int(round(pwm_to_dc(fpwm))) + + return speed_percentage + + def get_speed_rpm(self): + """ + Retrieves the speed of fan in RPM + + Returns: + An integer, Speed of fan in RPM + """ + if self.is_psu_fan: + attr = "psu_fan{}_speed_rpm".format(self.fan_index) + device = "PSU{}".format(self.fans_psu_index) + output = self.pddf_obj.get_attr_name_output(device, attr) + if not output: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + speed = int(float(output['status'])) + + rpm_speed = speed + return rpm_speed + else: + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr = "fan" + str(idx) + "_input" + output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr) + + if output is None: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + rpm_speed = int(float(output['status'])) + + return rpm_speed + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + target_speed = 0 + if self.is_psu_fan: + # Target speed not usually supported for PSU fans + target_speed = 0 + else: + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr = "fan" + str(idx) + "_pwm" + output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr) + + if not output: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + fpwm = int(output['status']) + + pwm_to_dc = eval(self.plugin_data['FAN']['pwm_to_duty_cycle']) + speed_percentage = int(round(pwm_to_dc(fpwm))) + target_speed = speed_percentage + + return target_speed + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + # Fix the speed vairance to 10 percent. If it changes based on platforms, overwrite + # this value in derived pddf fan class + return 10 + + def set_speed(self, speed): + """ + Sets the fan speed + + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + + Returns: + A boolean, True if speed is set successfully, False if not + """ + if self.is_psu_fan: + print "Setting PSU fan speed is not allowed" + return False + else: + if speed<0 or speed>100: + print "Error: Invalid speed %d. Please provide a valid speed percentage"%speed + return False + + if 'duty_cycle_to_pwm' not in self.plugin_data['FAN']: + print "Setting fan speed is not allowed !" + return False + else: + duty_cycle_to_pwm = eval(self.plugin_data['FAN']['duty_cycle_to_pwm']) + pwm = int(round(duty_cycle_to_pwm(speed))) + + + status = False + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr = "fan" + str(idx) + "_pwm" + output = self.pddf_obj.set_attr_name_output("FAN-CTRL", attr, pwm) + if not output: + return False + + status = output['status'] + + return status + + def set_status_led(self, color): + index = str(self.fantray_index-1) + led_device_name = "FANTRAY{}".format(self.fantray_index) + "_LED" + + result, msg = self.pddf_obj.is_supported_sysled_state(led_device_name, color); + if result == False: + print msg + return (False) + + + device_name=self.pddf_obj.data[led_device_name]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('color', color, self.pddf_obj.get_led_cur_state_path()) + self.pddf_obj.create_attr('dev_ops', 'set_status', self.pddf_obj.get_led_path()) + return (True) + + + def get_status_led(self): + index = str(self.fantray_index-1) + fan_led_device = "FANTRAY{}".format(self.fantray_index) + "_LED" + + if (not fan_led_device in self.pddf_obj.data.keys()): + # Implement a generic status_led color scheme + if self.get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + device_name=self.pddf_obj.data[fan_led_device]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('dev_ops', 'get_status', self.pddf_obj.get_led_path()) + color=self.pddf_obj.get_led_color() + return (color) + + def dump_sysfs(self): + return self.pddf_obj.cli_dump_dsysfs('fan') diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_platform.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_platform.py new file mode 100755 index 000000000000..20b87db99910 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_platform.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +############################################################################# +# PDDF +# Module contains an implementation of SONiC Platform API and +# provides the platform information +# +############################################################################# + + +try: + import json + import pddfparse + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PddfPlatform(PlatformBase): + """ + PDDF Generic Platform class + """ + pddf_data = {} + pddf_plugin_data = {} + def __init__(self): + # Initialize the JSON data + self.pddf_data = pddfparse.PddfParse() + with open('/usr/share/sonic/platform/pddf/pd-plugin.json') as pd: + self.pddf_plugin_data = json.load(pd) + + if not self.pddf_data or not self.pddf_plugin_data: + print "Error: PDDF JSON data is not loaded properly ... Exiting" + raise ValueError + + PlatformBase.__init__(self) + self._chassis = Chassis(self.pddf_data, self.pddf_plugin_data) diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_psu.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_psu.py new file mode 100755 index 000000000000..b378be7dad39 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_psu.py @@ -0,0 +1,298 @@ +#!/usr/bin/env python +# +# All the supported PSU SysFS aattributes are +#- psu_present +#- psu_model_name +#- psu_power_good +#- psu_mfr_id +#- psu_serial_num +#- psu_fan_dir +#- psu_v_out +#- psu_i_out +#- psu_p_out +#- psu_fan1_speed_rpm +# + + +try: + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +class PddfPsu(PsuBase): + """PDDF generic PSU class""" + + pddf_obj = {} + plugin_data = {} + + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + PsuBase.__init__(self) + if not pddf_data or not pddf_plugin_data: + raise ValueError('PDDF JSON data error') + + self.pddf_obj = pddf_data + self.plugin_data = pddf_plugin_data + self.platform = self.pddf_obj.get_platform() + self.psu_index = index + 1 + + self._fan_list = [] # _fan_list under PsuBase class is a global variable, hence we need to use _fan_list per class instatiation + self.num_psu_fans = int(self.pddf_obj.get_num_psu_fans('PSU{}'.format(index+1))) + for psu_fan_idx in range(self.num_psu_fans): + psu_fan = Fan(0, psu_fan_idx, pddf_data, pddf_plugin_data, True, self.psu_index) + self._fan_list.append(psu_fan) + + def get_num_fans(self): + """ + Retrieves the number of fan modules available on this PSU + + Returns: + An integer, the number of fan modules available on this PSU + """ + return len(self._fan_list) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + if 'name' in self.plugin_data['PSU']: + return self.plugin_data['PSU']['name'][str(self.psu_index)] + else: + return "PSU{}".format(self.psu_index) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + status = 0 + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_present") + if not output: + return False + + mode = output['mode'] + status = output['status'] + + vmap = self.plugin_data['PSU']['psu_present'][mode]['valmap'] + + if status.rstrip('\n') in vmap: + return vmap[status.rstrip('\n')] + else: + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_model_name") + if not output: + return None + + model = output['status'] + + # strip_non_ascii + stripped = (c for c in model if 0 < ord(c) < 127) + model = ''.join(stripped) + + return model.rstrip('\n') + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_serial_num") + if not output: + return None + + serial = output['status'] + + return serial.rstrip('\n') + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + device = "PSU{}".format(self.psu_index) + + output = self.pddf_obj.get_attr_name_output(device, "psu_power_good") + if not output: + return False + + mode = output['mode'] + status = output ['status'] + + vmap = self.plugin_data['PSU']['psu_power_good'][mode]['valmap'] + + if status.rstrip('\n') in vmap: + return vmap[status.rstrip('\n')] + else: + return False + + def get_mfr_id(self): + """ + Retrieves the manufacturer id of the device + + Returns: + string: Manufacturer Id of device + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_mfr_id") + if not output: + return None + + mfr = output['status'] + + return mfr.rstrip('\n') + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_v_out") + if not output: + return 0.0 + + v_out = output['status'] + + return float(v_out)/1000 + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_i_out") + if not output: + return 0.0 + + i_out = output['status'] + + # current in mA + return float(i_out)/1000 + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_p_out") + if not output: + return 0.0 + + p_out = output['status'] + + # power is returned in micro watts + return float(p_out)/1000000 + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and + passed all its internal self-tests, False if not. + """ + return self.get_status() + + def set_status_led(self, color): + index = str(self.psu_index-1) + led_device_name = "PSU{}".format(self.psu_index) + "_LED" + + result, msg = self.pddf_obj.is_supported_sysled_state(led_device_name, color); + if result == False: + print msg + return (False) + + device_name=self.pddf_obj.data[led_device_name]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('color', color, self.pddf_obj.get_led_cur_state_path()) + self.pddf_obj.create_attr('dev_ops', 'set_status', self.pddf_obj.get_led_path()) + return (True) + + def get_status_led(self): + index = str(self.psu_index-1) + psu_led_device = "PSU{}_LED".format(self.psu_index) + if (not psu_led_device in self.pddf_obj.data.keys()): + # Implement a generic status_led color scheme + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + device_name=self.pddf_obj.data[psu_led_device]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('dev_ops', 'get_status', self.pddf_obj.get_led_path()) + color=self.pddf_obj.get_led_color() + return (color) + + def get_input_voltage(self): + """ + Retrieves current PSU input voltage + + Returns: + A float number, the input voltage in volts, + e.g. 12.1 + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_v_in") + if not output: + return 0.0 + + v_in = output['status'] + + return float(v_in)/1000 + + def get_input_current(self): + """ + Retrieves present electric current supplied to the PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_i_in") + if not output: + return 0.0 + + i_in = output['status'] + + # current in mA + return float(i_in)/1000 + + def dump_sysfs(self): + return self.pddf_obj.cli_dump_dsysfs('psu') diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_sfp.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_sfp.py new file mode 100755 index 000000000000..856f4c748d10 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_sfp.py @@ -0,0 +1,1390 @@ +#!/usr/bin/env python + +try: + import time + from ctypes import create_string_buffer + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 + +#definitions of the offset and width for values in DOM info eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes','FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia','FibreChannelSpeed') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +PAGE_OFFSET = 0 +KEY_OFFSET = 1 +KEY_WIDTH = 2 +FUNC_NAME = 3 + +INFO_OFFSET = 128 +DOM_OFFSET = 0 +DOM_OFFSET1 = 384 + +class PddfSfp(SfpBase): + """ + PDDF generic Sfp class + """ + + pddf_obj = {} + plugin_data = {} + _port_to_eeprom_mapping = {} + _port_start = 0 + _port_end = 0 + _port_to_type_mapping = {} + _qsfp_ports = [] + _sfp_ports = [] + + # Read out any bytes from any offset + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + sysfsfile_eeprom = open(self.eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except Exception as e: + print "Error: Unable to open eeprom_path: %s"%(str(e)) + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + if not pddf_data or not pddf_plugin_data: + raise ValueError('PDDF JSON data error') + + self.pddf_obj = pddf_data + self.plugin_data = pddf_plugin_data + + self.platform = self.pddf_obj.get_platform() + + # index is 0-based + self._port_start = 0 + self._port_end = int(self.platform['num_ports']) + if index < self._port_start or index >= self._port_end: + print "Invalid port index %d"%index + return + + self.port_index = index+1 + self.device = 'PORT{}'.format(self.port_index) + self.sfp_type = self.pddf_obj.get_device_type(self.device) + self.is_qsfp_port = True if (self.sfp_type=='QSFP' or self.sfp_type=='QSFP28') else False + self.is_osfp_port = True if (self.sfp_type=='OSFP' or self.sfp_type=='QSFP-DD') else False + self.eeprom_path = self.pddf_obj.get_path(self.device, 'eeprom') + + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', + 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'vendor_date', 'vendor_oui', 'application_advertisement'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', + 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', + 'txbiaslowwarning'] + + SfpBase.__init__(self) + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + application_advertisement |1*255VCHAR |supported applications advertisement + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + + if self.is_osfp_port: + sfpi_obj = inf8628InterfaceId() + offset = 0 + type_offset = OSFP_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + hw_rev_offset = OSFP_HW_REV_OFFSET + vendor_name_offset = OSFP_VENDOR_NAME_OFFSET + vendor_pn_offset = OSFP_VENDOR_PN_OFFSET + vendor_sn_offset = OSFP_VENDOR_SN_OFFSET + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'OSFP' + + elif self.is_qsfp_port: + sfpi_obj = sff8436InterfaceId() + offset = 128 + type_offset = XCVR_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + hw_rev_offset = XCVR_HW_REV_OFFSET + vendor_name_offset = XCVR_VENDOR_NAME_OFFSET + vendor_pn_offset = XCVR_VENDOR_PN_OFFSET + vendor_sn_offset = XCVR_VENDOR_SN_OFFSET + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + else: + sfpi_obj = sff8472InterfaceId() + offset = 0 + type_offset = XCVR_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + hw_rev_offset = XCVR_HW_REV_OFFSET + vendor_name_offset = XCVR_VENDOR_NAME_OFFSET + vendor_pn_offset = XCVR_VENDOR_PN_OFFSET + vendor_sn_offset = XCVR_VENDOR_SN_OFFSET + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + if sfpi_obj is None: + return None + + + if self.is_osfp_port: + sfp_type_raw = self.__read_eeprom_specific_bytes((offset + type_offset), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + sfp_type_abbrv_name = sfpi_obj.parse_sfp_type_abbrv_name(sfp_typ_raw, 0) + else: + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) + if sfp_interface_bulk_raw is not None: + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + if sfp_vendor_date_raw is not None: + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_name_offset), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_pn_offset), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + hw_rev_offset), vendor_rev_width) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_sn_offset), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + + xcvr_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + compliance_code_dict = dict() + + if sfp_interface_bulk_data: + xcvr_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + xcvr_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + xcvr_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + xcvr_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + xcvr_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + xcvr_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + else: + xcvr_info_dict['type'] = sfp_type_data['data']['type']['value'] if sfp_type_data else 'N/A' + xcvr_info_dict['type_abbrv_name'] = sfp_type_abbrv_name['data']['type_abbrv_name']['value'] if sfp_type_abbrv_name else 'N/A' + + xcvr_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + xcvr_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + xcvr_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + xcvr_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + xcvr_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + xcvr_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + xcvr_info_dict['cable_type'] = "Unknown" + xcvr_info_dict['cable_length'] = "Unknown" + + if sfp_type == 'QSFP': + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + xcvr_info_dict['cable_type'] = key + xcvr_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + xcvr_info_dict['specification_compliance'] = str(compliance_code_dict) + + nkey='Nominal Bit Rate(100Mbs)' + if nkey in sfp_interface_bulk_data['data']: + xcvr_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + xcvr_info_dict['nominal_bit_rate'] = 'N/A' + elif sfp_type == 'OSFP': + pass + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + xcvr_info_dict['cable_type'] = key + xcvr_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + xcvr_info_dict['specification_compliance'] = str(compliance_code_dict) + + xcvr_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return xcvr_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + xcvr_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + + if self.is_osfp_port: + # Below part is added to avoid fail xcvrd, shall be implemented later + pass + elif self.is_qsfp_port: + # QSFPs + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return None + + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability( + qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes( (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return None + + dom_voltage_raw = self.__read_eeprom_specific_bytes( (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + else: + return None + + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return None + + xcvr_dom_info_dict['tx1power'] = 'N/A' + xcvr_dom_info_dict['tx2power'] = 'N/A' + xcvr_dom_info_dict['tx3power'] = 'N/A' + xcvr_dom_info_dict['tx4power'] = 'N/A' + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + else: + return None + + + xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + xcvr_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + xcvr_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + xcvr_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + xcvr_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + xcvr_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + xcvr_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + xcvr_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + xcvr_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + xcvr_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + xcvr_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + xcvr_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + # SFPs + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes( (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return None + + dom_voltage_raw = self.__read_eeprom_specific_bytes( (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return None + + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + xcvr_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + xcvr_dom_info_dict['rx2power'] = 'N/A' + xcvr_dom_info_dict['rx3power'] = 'N/A' + xcvr_dom_info_dict['rx4power'] = 'N/A' + xcvr_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + xcvr_dom_info_dict['tx2bias'] = 'N/A' + xcvr_dom_info_dict['tx3bias'] = 'N/A' + xcvr_dom_info_dict['tx4bias'] = 'N/A' + xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + xcvr_dom_info_dict['tx2power'] = 'N/A' + xcvr_dom_info_dict['tx3power'] = 'N/A' + xcvr_dom_info_dict['tx4power'] = 'N/A' + + xcvr_dom_info_dict['rx_los'] = self.get_rx_los() + xcvr_dom_info_dict['tx_fault'] = self.get_tx_fault() + xcvr_dom_info_dict['reset_status'] = self.get_reset_status() + xcvr_dom_info_dict['lp_mode'] = self.get_lpmode() + + + return xcvr_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + xcvr_dom_threshold_info_dict = dict.fromkeys(self.threshold_dict_keys, 'N/A') + + if self.is_osfp_port: + # Below part is added to avoid fail xcvrd, shall be implemented later + pass + elif self.is_qsfp_port: + # QSFPs + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + dom_thres_raw = self.__read_eeprom_specific_bytes(QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) + + if dom_thres_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values( + dom_thres_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + xcvr_dom_threshold_info_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + xcvr_dom_threshold_info_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + xcvr_dom_threshold_info_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + xcvr_dom_threshold_info_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + xcvr_dom_threshold_info_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + xcvr_dom_threshold_info_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + xcvr_dom_threshold_info_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + xcvr_dom_threshold_info_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_thres_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) + if dom_thres_raw: + channel_threshold_values = sfpd_obj.parse_channel_threshold_values( + dom_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + xcvr_dom_threshold_info_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerhighalarm'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerlowalarm'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerhighwarning'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerlowwarning'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + xcvr_dom_threshold_info_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + else: + # SFPs + sfpd_obj = sff8472Dom() + offset = 256 + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, offset) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) + + xcvr_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + xcvr_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + xcvr_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + xcvr_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + xcvr_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + xcvr_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + xcvr_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[ + 'data']['VoltageHighWarning']['value'] + xcvr_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + xcvr_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + xcvr_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + + + return xcvr_dom_threshold_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + reset_status = None + if not self.get_presence(): + return reset_status + + device = 'PORT{}'.format(self.port_index) + output = self.pddf_obj.get_attr_name_output(device, 'xcvr_reset') + if not output: + return False + + status = int(output['status'].rstrip()) + + if status==1: + reset_status = True + else: + reset_status = False + + return reset_status + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = None + if not self.get_presence(): + return rx_los + + device = 'PORT{}'.format(self.port_index) + output = self.pddf_obj.get_attr_name_output(device, 'xcvr_rxlos') + + if not output: + # read the values from EEPROM + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + rx_los_list = [] + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3] + else: + # SFP ports + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + else: + status = int(output['status'].rstrip()) + + if status==1: + rx_los = True + else: + rx_los = False + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = None + if not self.get_presence(): + return tx_fault + + device = 'PORT{}'.format(self.port_index) + output = self.pddf_obj.get_attr_name_output(device, 'xcvr_txfault') + + if not output: + # read the values from EEPROM + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + tx_fault_list = [] + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3] + else: + # SFP + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + else: + status = int(output['status'].rstrip()) + + if status==1: + tx_fault = True + else: + tx_fault = False + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable = False + if not self.get_presence(): + return tx_disable + + device = 'PORT{}'.format(self.port_index) + output = self.pddf_obj.get_attr_name_output(device, 'xcvr_txdisable') + + if not output: + # read the values from EEPROM + if self.is_osfp_port: + return tx_disable + elif self.is_qsfp_port: + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX4Disable']['value']) + + return tx_disable_list + else: + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_disable_hard = (sffbase().test_bit( + data, SFP_TX_DISABLE_HARD_BIT) != 0) + tx_disable_soft = (sffbase().test_bit( + data, SFP_TX_DISABLE_SOFT_BIT) != 0) + tx_disable = tx_disable_hard | tx_disable_soft + + return tx_disable + else: + status = int(output['status'].rstrip()) + + if status==1: + tx_disable = True + else: + tx_disable = False + + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + if not self.get_presence(): + return 0 + + if self.is_osfp_port: + return 0 + elif self.is_qsfp_port: + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + return tx_disabled + else: + # SFP doesnt support this + return 0 + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + lpmode = False + if not self.get_presence(): + return lpmode + + device = 'PORT{}'.format(self.port_index) + output = self.pddf_obj.get_attr_name_output(device, 'xcvr_lpmode') + + if not output: + # Read from EEPROM + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + try: + eeprom = None + ctype = self.get_connector_type() + if ctype in ['Copper pigtail', 'No separable connector']: + return False + + eeprom = open(self.eeprom_path, "rb") + eeprom.seek(93) + status = ord(eeprom.read(1)) + + if ((status & 0x3) == 0x3): + lpmode = True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + else: + lpmode = False # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + else: + # SFP + pass + else: + status = int(output['status'].rstrip()) + + if status == 1: + lpmode = True + else: + lpmode = False + + return lpmode + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + power_override = False + if not self.get_presence(): + return power_override + + + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + power_override = ('On' == dom_control_data['data']['PowerOverride']['value']) + else: + # SFP doesnt suppor this + pass + + return power_override + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + if transceiver_dom_info_dict is not None: + # returns None if temperature is not found in the dictionary + return transceiver_dom_info_dict.get("temperature") + else: + return None + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + # returns None if voltage is not found in the dictionary + if transceiver_dom_info_dict is not None: + return transceiver_dom_info_dict.get("voltage") + else: + return None + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + if transceiver_dom_info_dict is not None: + tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") + tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A") + tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A") + tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A") + return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else [] + else: + return None + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + if transceiver_dom_info_dict is not None: + rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") + rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A") + rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A") + rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A") + return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else [] + else: + return None + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + if transceiver_dom_info_dict is not None: + tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") + tx2_pw = transceiver_dom_info_dict.get("tx2power", "N/A") + tx3_pw = transceiver_dom_info_dict.get("tx3power", "N/A") + tx4_pw = transceiver_dom_info_dict.get("tx4power", "N/A") + return [tx1_pw, tx2_pw, tx3_pw, tx4_pw] + else: + return None + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + status = False + if not self.get_presence(): + return status + + device = 'PORT{}'.format(self.port_index) + # TODO: Implement a wrapper set function to write the sequence + path = self.pddf_obj.get_path(device, 'xcvr_reset') + + # TODO: put the optic based reset logic using EEPROM + if path is None: + pass + else: + try: + f = open(path, 'r+') + except IOError as e: + return False + + try: + f.seek(0) + f.write('1') + time.sleep(1) + f.seek(0) + f.write('0') + + f.close() + status = True + except IOError as e: + status = False + + return status + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + # find out a generic implementation of tx_disable for SFP, QSFP and OSFP + status = False + if not self.get_presence(): + return tx_disable + + device = 'PORT{}'.format(self.port_index) + path = self.pddf_obj.get_path(device, 'xcvr_txdisable') + + # TODO: put the optic based reset logic using EEPROM + if path is None: + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + eeprom_f = None + try: + txdisable_ctl = 0xf if tx_disable else 0x0 + buf = create_string_buffer(1) + buf[0] = chr(txdisable_ctl) + # Write to eeprom + eeprom_f = open(self.eeprom_path, "r+b") + eeprom_f.seek(QSFP_CONTROL_OFFSET) + eeprom_f.write(buf[0]) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom_f is not None: + eeprom_f.close() + time.sleep(0.01) + + status = True + else: + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw is not None: + # Set bit 6 for Soft TX Disable Select + # 01000000 = 64 and 10111111 = 191 + txdisable_bit = 64 if tx_disable else 191 + status_control = int(status_control_raw[0], 16) + txdisable_ctl = (status_control | txdisable_bit) if tx_disable else ( + status_control & txdisable_bit) + try: + eeprom_f = open(self.eeprom_path, mode="r+b", buffering=0) + buf = create_string_buffer(1) + buf[0] = chr(txdisable_ctl) + # Write to eeprom + eeprom_f.seek(SFP_STATUS_CONTROL_OFFSET) + eeprom_f.write(buf[0]) + except Exception as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if eeprom_f: + eeprom_f.close() + time.sleep(0.01) + status = True + else: + try: + f = open(path, 'r+') + except IOError as e: + return False + + try: + if tx_disable: + f.write('1') + else: + f.write('0') + f.close() + status = True + except IOError as e: + status = False + + return status + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + # TODO: find a implementation + status = False + if not self.get_presence(): + return status + + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + eeprom_f = None + try: + channel_state = self.get_tx_disable_channel() + txdisable_ctl = (channel_state | channel) if disable else (channel_state & ~channel) + buf = create_string_buffer(1) + buf[0] = chr(txdisable_ctl) + # Write to eeprom + eeprom_f = open(self.eeprom_path, "r+b") + eeprom_f.seek(QSFP_CONTROL_OFFSET) + eeprom_f.write(buf[0]) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom_f is not None: + eeprom_f.close() + time.sleep(0.01) + status = True + else: + pass + + return status + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + status = False + if not self.get_presence(): + return status + + device = 'PORT{}'.format(self.port_index) + path = self.pddf_obj.get_path(device, 'xcvr_lpmode') + + # TODO: put the optic based reset logic using EEPROM + if path is None: + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + try: + eeprom_f = None + ctype = self.get_connector_type() + if ctype in ['Copper pigtail', 'No separable connector']: + return False + + # Fill in write buffer + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom_f = open(self.eeprom_path, "r+b") + eeprom_f.seek(93) + eeprom_f.write(buffer[0]) + return True + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom_f is not None: + eeprom_f.close() + time.sleep(0.01) + else: + pass + + else: + try: + f = open(path, 'r+') + except IOError as e: + return False + + try: + if lpmode: + f.write('1') + else: + f.write('0') + + f.close() + status = True + except IOError as e: + status = False + + return status + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + status = False + if not self.get_presence(): + return status + + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + eeprom_f = open(self.eeprom_path, "r+b") + eeprom_f.seek(QSFP_POWEROVERRIDE_OFFSET) + eeprom_f.write(buffer[0]) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom_f is not None: + eeprom_f.close() + time.sleep(0.01) + return True + else: + pass + + return status + + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + # Name of the port/sfp ? + return 'PORT{}'.format(self.port_index) + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + output = self.pddf_obj.get_attr_name_output(self.device, 'xcvr_present') + if not output: + return False + + mode = output['mode'] + modpres = output['status'].rstrip() + if 'XCVR' in self.plugin_data: + if 'xcvr_present' in self.plugin_data['XCVR']: + ptype = self.sfp_type + vtype = 'valmap-'+ptype + if vtype in self.plugin_data['XCVR']['xcvr_present'][mode]: + vmap = self.plugin_data['XCVR']['xcvr_present'][mode][vtype] + if modpres in vmap: + return vmap[modpres] + else: + return False + # if self.plugin_data doesn't specify anything regarding Transceivers + if modpres == '1': + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + if transceiver_dom_info_dict is not None: + return transceiver_dom_info_dict.get("model", "N/A") + else: + return None + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + if transceiver_dom_info_dict is not None: + return transceiver_dom_info_dict.get("serial", "N/A") + else: + return None + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and self.get_transceiver_bulk_status() + + def get_connector_type(self): + """ + Retrieves the device connector type + Returns: + enum: connector_code + """ + transceiver_dom_info_dict = self.get_transceiver_info() + if transceiver_dom_info_dict is not None: + return transceiver_dom_info_dict.get("connector", "N/A") + else: + return None + + def get_transceiver_change_event(self): + """ + TODO: This function need to be implemented + when decide to support monitoring SFP(Xcvrd) + on this platform. + """ + raise NotImplementedError + + def dump_sysfs(self): + return self.pddf_obj.cli_dump_dsysfs('xcvr') diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_thermal.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_thermal.py new file mode 100755 index 000000000000..01cd4080db10 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_thermal.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python + +# All the supported Temperature Sensor SysFS aattributes are +#- temp1_high_crit_threshold +#- temp1_high_threshold +#- temp1_input +#- temp_low_threshold +#- temp1_low_crit_threshold + +try: + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + + +class PddfThermal(ThermalBase): + """PDDF generic Thermal class""" + pddf_obj = {} + plugin_data = {} + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + if not pddf_data or not pddf_plugin_data: + raise ValueError('PDDF JSON data error') + + self.pddf_obj = pddf_data + self.plugin_data = pddf_plugin_data + + self.platform = self.pddf_obj.get_platform() + + self.thermal_index = index + 1 + self.thermal_obj_name = "TEMP{}".format(self.thermal_index) + self.thermal_obj = self.pddf_obj.data[self.thermal_obj_name] + + def get_name(self): + if 'dev_attr' in self.thermal_obj.keys(): + if 'display_name' in self.thermal_obj['dev_attr']: + return str(self.thermal_obj['dev_attr']['display_name']) + # In case of errors + return (self.thermal_obj_name) + + def get_temperature(self): + output = self.pddf_obj.get_attr_name_output(self.thermal_obj_name, "temp1_input") + if not output: + return None + + if output['status'].isalpha(): + attr_value = None + else: + attr_value = float(output['status']) + + if output['mode']=='bmc': + return attr_value + else: + return (attr_value/float(1000)) + + + def get_high_threshold(self): + output = self.pddf_obj.get_attr_name_output(self.thermal_obj_name, "temp1_high_threshold") + if not output: + return None + + if output['status'].isalpha(): + attr_value = None + else: + attr_value = float(output['status']) + + if output['mode']=='bmc': + return attr_value + else: + return (attr_value/float(1000)) + + + def get_low_threshold(self): + output = self.pddf_obj.get_attr_name_output(self.thermal_obj_name, "temp1_low_threshold") + if not output: + return None + + if output['status'].isalpha(): + attr_value = None + else: + attr_value = float(output['status']) + + if output['mode']=='bmc': + return attr_value + else: + return (attr_value/float(1000)) + + + def set_high_threshold(self, temperature): + node = self.pddf_obj.get_path(self.thermal_obj_name, "temp1_high_threshold") + if node is None: + print "ERROR %s does not exist"%node + return None + + cmd = "echo '%d' > %s"%(temperature * 1000, node) + os.system(cmd) + + return (True) + + + def set_low_threshold(self, temperature): + node = self.pddf_obj.get_path(self.thermal_obj_name, "temp1_low_threshold") + if node is None: + print "ERROR %s does not exist"%node + return None + cmd = "echo '%d' > %s"%(temperature * 1000, node) + os.system(cmd) + + return (True) + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self.pddf_obj.get_attr_name_output(self.thermal_obj_name, "temp1_high_crit_threshold") + if not output: + return None + + if output['status'].isalpha(): + attr_value = None + else: + attr_value = float(output['status']) + + if output['mode']=='bmc': + return attr_value + else: + return (attr_value/float(1000)) + + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of thermal + + Returns: + A float number, the low critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self.pddf_obj.get_attr_name_output(self.thermal_obj_name, "temp1_low_crit_threshold") + if not output: + return None + + if output['status'].isalpha(): + attr_value = None + else: + attr_value = float(output['status']) + + if output['mode']=='bmc': + return attr_value + else: + return (attr_value/float(1000)) + + + # Helper Functions + def get_temp_label(self): + if 'bmc' in self.pddf_obj.data[self.thermal_obj_name].keys(): + return None + else: + if self.thermal_obj_name in self.pddf_obj.data.keys(): + dev= self.pddf_obj.data[self.thermal_obj_name] + topo_info = dev['i2c']['topo_info'] + label="%s-i2c-%d-%x" % (topo_info['dev_type'], int(topo_info['parent_bus'], 0), + int(topo_info['dev_addr'], 0)) + return (label) + else: + return None + + + def dump_sysfs(self): + return self.pddf_obj.cli_dump_dsysfs('temp-sensors') diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddfparse.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddfparse.py new file mode 100755 index 000000000000..aa47beaa0fc7 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddfparse.py @@ -0,0 +1,1508 @@ +#!/usr/bin/env python +import glob +import json +from jsonschema import validate +import os +import re +import subprocess +import time +import unicodedata + +bmc_cache={} +cache={} +SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' +HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku' +PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform' + +dirname=os.path.dirname(os.path.realpath(__file__)) + +color_map = { + "STATUS_LED_COLOR_GREEN" : "green", + "STATUS_LED_COLOR_RED" : "red", + "STATUS_LED_COLOR_AMBER" : "amber", + "STATUS_LED_COLOR_BLUE" : "blue", + "STATUS_LED_COLOR_GREEN_BLINK" : "blinking green", + "STATUS_LED_COLOR_RED_BLINK" : "blinking red", + "STATUS_LED_COLOR_AMBER_BLINK" : "blinking amber", + "STATUS_LED_COLOR_BLUE_BLINK" : "blinking blue", + "STATUS_LED_COLOR_OFF" : "off" +} + + +class PddfParse(): + def __init__(self): + if not os.path.exists("/usr/share/sonic/platform"): + self.platform, self.hwsku = self.get_platform_and_hwsku() + os.symlink("/usr/share/sonic/device/"+self.platform, "/usr/share/sonic/platform") + + try: + with open('/usr/share/sonic/platform/pddf/pddf-device.json') as f: + self.data = json.load(f) + except IOError: + if os.path.exists('/usr/share/sonic/platform'): + os.unlink("/usr/share/sonic/platform") + + + self.data_sysfs_obj={} + self.sysfs_obj={} + + + # Returns platform and HW SKU + def get_platform_and_hwsku(self): + try: + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + platform = stdout.rstrip('\n') + + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-d', '-v', HWSKU_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + hwsku = stdout.rstrip('\n') + except OSError, e: + raise OSError("Cannot detect platform") + + return (platform, hwsku) + + ################################################################################################################# + # GENERIC DEFS + ################################################################################################################# + def runcmd(self, cmd): + rc = os.system(cmd) + if rc!=0: + print "%s -- command failed"%cmd + return rc + + def get_dev_idx(self, dev, ops): + parent=dev['dev_info']['virt_parent'] + pdev=self.data[parent] + + return pdev['dev_attr']['dev_idx'] + + + def get_path(self, target, attr): + aa = target + attr + + if aa in cache: + return cache[aa] + + string = None + p = re.search(r'\d+$', target) + if p is None: + for bb in filter(re.compile(target).search,self.data.keys()): + path = self.dev_parse(self.data[bb], { "cmd": "show_attr", "target":bb, "attr":attr }) + if path != "": + string = path + else: + if target in self.data.keys(): + path = self.dev_parse(self.data[target], { "cmd": "show_attr", "target":target, "attr":attr }) + if path != "": + string = path + + + if string is not None: + string = string.rstrip() + + cache[aa]=string + return string + + + def get_device_type(self, key): + if not key in self.data.keys(): + return None + return self.data[key]['dev_info']['device_type'] + + def get_platform(self): + return self.data['PLATFORM'] + + def get_num_psu_fans(self, dev): + if not dev in self.data.keys(): + return 0 + + if not 'num_psu_fans' in self.data[dev]['dev_attr']: + return 0 + + return self.data[dev]['dev_attr']['num_psu_fans'] + + def get_led_path(self): + return ("pddf/devices/led") + + def get_led_cur_state_path(self): + return ("pddf/devices/led/cur_state") + + def get_led_color(self): + color_f="/sys/kernel/pddf/devices/led/cur_state/color" + try: + with open(color_f, 'r') as f: + color = f.read().strip("\r\n") + except IOError: + return ("Error") + + return (color_map[color]) + + + def get_led_color_devtype(self, key): + attr_list=self.data[key]['i2c']['attr_list'] + for attr in attr_list: + if 'attr_devtype' in attr: + return attr['attr_devtype'].strip() + else: + return 'cpld' + + def get_led_color_from_gpio(self, led_device_name): + attr_list=self.data[led_device_name]['i2c']['attr_list'] + attr=attr_list[0] + if ':' in attr['bits']: + bits_list=attr['bits'].split(':') + bits_list.sort(reverse=True) + max_bit=int(bits_list[0]) + else: + max_bit=0 + base_offset=int(attr['swpld_addr_offset'], 16) + value = 0 + bit = 0 + while bit <= max_bit: + offset=base_offset + bit + if 'attr_devname' in attr: + attr_path = self.get_gpio_attr_path(self.data[attr['attr_devname']], hex(offset)) + else: + status= "[FAILED] attr_devname is not configured" + return (status) + if not os.path.exists(attr_path): + status= "[FAILED] {} does not exist".format(attr_path) + return (status) + cmd = 'cat ' + attr_path + gpio_value = subprocess.check_output(cmd, shell=True) + value |= int(gpio_value) << bit + bit += 1 + + for attr in attr_list: + if int(attr['value'].strip(), 16) == value: + return(color_map[attr['attr_name']]) + return (color_map['STATUS_LED_COLOR_OFF']) + + + def get_led_color_from_cpld(self, led_device_name): + index=self.data[led_device_name]['dev_attr']['index'] + device_name=self.data[led_device_name]['dev_info']['device_name'] + self.create_attr('device_name', device_name, self.get_led_path()) + self.create_attr('index', index, self.get_led_path()) + self.create_attr('dev_ops', 'get_status', self.get_led_path()) + return self.get_led_color() + + def set_led_color_from_gpio(self, led_device_name, color): + attr_list=self.data[led_device_name]['i2c']['attr_list'] + for attr in attr_list: + if attr['attr_name'].strip() == color.strip(): + base_offset=int(attr['swpld_addr_offset'], 16) + if ':' in attr['bits']: + bits_list=attr['bits'].split(':') + bits_list.sort(reverse=True) + max_bit = int(bits_list[0]) + else: + max_bit=0 + value=int(attr['value'], 16) + i = 0 + while i <= max_bit: + _value =(value>>i) & 1 + base_offset += i + attr_path = self.get_gpio_attr_path(self.data[attr['attr_devname']], hex(base_offset)) + i += 1 + try: + cmd = "echo {} > {}".format(_value, attr_path) + self.runcmd(cmd) + except Exception as e: + print "Invalid gpio path : " + attr_path + return (False) + return (True) + + def set_led_color_from_cpld(self, led_device_name, color): + index=self.data[led_device_name]['dev_attr']['index'] + device_name=self.data[led_device_name]['dev_info']['device_name'] + self.create_attr('device_name', device_name, self.get_led_path()) + self.create_attr('index', index, self.get_led_path()) + self.create_attr('color', color, self.get_led_cur_state_path()) + self.create_attr('dev_ops', 'set_status', self.get_led_path()) + return (True) + + + def get_system_led_color(self, led_device_name): + if (not led_device_name in self.data.keys()): + status= "[FAILED] " + led_device_name + " is not configured" + return (status) + + type = self.get_led_color_devtype(led_device_name) + + if type == 'gpio': + color = self.get_led_color_from_gpio(led_device_name) + elif type == 'cpld': + color = self.get_led_color_from_cpld(led_device_name) + return color + + def set_system_led_color(self, led_device_name, color): + result, msg = self.is_supported_sysled_state(led_device_name, color); + if result == False: + print msg + return (result) + + type = self.get_led_color_devtype(led_device_name) + + if type == 'gpio': + return (self.set_led_color_from_gpio(led_device_name, color)) + else: + return (self.set_led_color_from_cpld(led_device_name, color)) + + ################################################################################################################### + # SHOW ATTRIBIUTES DEFS + ################################################################################################################### + def is_led_device_configured(self, device_name, attr_name): + if device_name in self.data.keys(): + attr_list=self.data[device_name]['i2c']['attr_list'] + for attr in attr_list: + if attr['attr_name'].strip() == attr_name.strip(): + return (True) + return (False) + + + def show_device_sysfs(self, dev, ops): + parent=dev['dev_info']['device_parent'] + pdev=self.data[parent] + if pdev['dev_info']['device_parent'] == 'SYSTEM': + return "/sys/bus/i2c/devices/"+"i2c-%d"%int(pdev['i2c']['topo_info']['dev_addr'], 0) + return self.show_device_sysfs(pdev, ops) + "/" + "i2c-%d" % int(dev['i2c']['topo_info']['parent_bus'], 0) + + + # This is alid for 'at24' type of EEPROM devices. Only one attribtue 'eeprom' + def show_attr_eeprom_device(self, dev, ops): + str = "" + attr_name=ops['attr'] + attr_list=dev['i2c']['attr_list'] + KEY="eeprom" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x"%(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + str += dsysfs_path+"\n" + return str + + def show_attr_gpio_device(self, dev, ops): + ret = "" + KEY="gpio" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + return ret + + + def show_attr_mux_device(self, dev, ops): + ret = "" + KEY="mux" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + return ret + + def get_gpio_attr_path(self, dev, offset): + base = int(dev['i2c']['dev_attr']['gpio_base'], 16) + port_num = base + int(offset, 16) + gpio_name = 'gpio'+str(port_num) + path = '/sys/class/gpio/'+gpio_name+'/value' + return path + + def show_attr_psu_i2c_device(self, dev, ops): + target=ops['target'] + attr_name=ops['attr'] + ret = "" + KEY="psu" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + if target == 'all' or target == dev['dev_info']['virt_parent'] : + attr_list=dev['i2c']['attr_list'] + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all' : + if 'attr_devtype' in attr.keys() and attr['attr_devtype'] == "gpio": + # Check and enable the gpio from class + attr_path = self.get_gpio_attr_path(self.data[attr['attr_devname']], attr['attr_offset']) + if (os.path.exists(attr_path)): + if not attr_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(attr_path) + ret += attr_path + '\n' + else: + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x" %(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + + def show_attr_psu_device(self, dev, ops): + return self.show_attr_psu_i2c_device(dev, ops ) + + + def show_attr_fan_device(self, dev, ops): + ret = "" + attr_name=ops['attr'] + attr_list=dev['i2c']['attr_list'] + KEY="fan" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + if 'attr_devtype' in attr.keys() and attr['attr_devtype'] == "gpio": + # Check and enable the gpio from class + attr_path = self.get_gpio_attr_path(self.data[attr['attr_devname']], attr['attr_offset']) + if (os.path.exists(attr_path)): + if not attr_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(attr_path) + ret += attr_path + '\n' + else: + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path= self.show_device_sysfs(dev, ops) + \ + "/%d-00%x" %(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + # This is only valid for LM75 + def show_attr_temp_sensor_device(self, dev, ops): + str = "" + attr_name=ops['attr'] + attr_list=dev['i2c']['attr_list'] + KEY="temp-sensors" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + path = self.show_device_sysfs(dev, ops)+"/%d-00%x/" %(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + if (os.path.exists(path)): + full_path = glob.glob(path + 'hwmon/hwmon*/' + real_name)[0] + dsysfs_path=full_path + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + str += full_path + "\n" + return str + + def show_attr_sysstatus_device(self, dev, ops): + ret = "" + attr_name=ops['attr'] + attr_list=dev['attr_list'] + KEY="sys-status" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + dsysfs_path = "/sys/kernel/pddf/devices/sysstatus/sysstatus_data/" + attr['attr_name'] + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + + def show_attr_xcvr_i2c_device(self, dev, ops): + target=ops['target'] + attr_name=ops['attr'] + ret = "" + dsysfs_path = "" + KEY="xcvr" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + if target == 'all' or target == dev['dev_info']['virt_parent'] : + attr_list=dev['i2c']['attr_list'] + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all' : + if 'attr_devtype' in attr.keys() and attr['attr_devtype'] == "gpio": + # Check and enable the gpio from class + attr_path = self.get_gpio_attr_path(self.data[attr['attr_devname']], attr['attr_offset']) + if (os.path.exists(attr_path)): + if not attr_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(attr_path) + ret += attr_path + '\n' + else: + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x" %(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + + def show_attr_xcvr_device(self, dev, ops): + return self.show_attr_xcvr_i2c_device(dev, ops ) + + def show_attr_cpld_device(self, dev, ops): + ret = "" + KEY="cpld" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + return ret + + + ################################################################################################################### + # SHOW DEFS + ################################################################################################################### + def check_led_cmds(self, key, ops): + name = ops['target']+'_LED' + if (ops['target']=='config' or ops['attr']=='all') or \ + (name==self.data[key]['dev_info']['device_name'] and + ops['attr']==self.data[key]['dev_attr']['index']): + return (True) + else: + return (False) + + def dump_sysfs_obj(self, obj, key_type): + if (key_type == 'keys'): + for key in obj.keys(): + print key + return + + for key in obj: + if (key == key_type or key_type == 'all'): + print key+":" + for entry in obj[key]: + print "\t"+entry + + def add_list_sysfs_obj(self, obj, KEY, list): + for sysfs in list: + if not sysfs in obj[KEY]: + obj[KEY].append(sysfs) + + def sysfs_attr(self, key, value, path, obj, obj_key): + sysfs_path="/sys/kernel/%s/%s"%(path, key) + if not sysfs_path in obj[obj_key]: + obj[obj_key].append(sysfs_path) + + + def sysfs_device(self, attr, path, obj, obj_key): + for key in attr.keys(): + sysfs_path="/sys/kernel/%s/%s"%(path, key) + if not sysfs_path in obj[obj_key]: + obj[obj_key].append(sysfs_path) + + def show_eeprom_device(self, dev, ops): + return + + + def show_mux_device(self, dev, ops): + KEY ='mux' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/mux", self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], "pddf/devices/mux", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/mux/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/mux/i2c_type', + '/sys/kernel/pddf/devices/mux/i2c_name', + '/sys/kernel/pddf/devices/mux/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_gpio_device(self, dev, ops): + KEY ='gpio' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/gpio", self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], "pddf/devices/gpio", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/gpio/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/gpio/i2c_type', + '/sys/kernel/pddf/devices/gpio/i2c_name', + '/sys/kernel/pddf/devices/gpio/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_psu_i2c_device(self, dev, ops): + KEY ='psu' + path='pddf/devices/psu/i2c' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], path, self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/psu/i2c/psu_idx" + self.sysfs_obj[KEY].append(sysfs_path) + + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, "pddf/devices/psu/i2c", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/psu/i2c/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/psu/i2c/i2c_type', + '/sys/kernel/pddf/devices/fan/i2c/i2c_name', + '/sys/kernel/pddf/devices/psu/i2c/error', + '/sys/kernel/pddf/devices/psu/i2c/attr_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_psu_device(self, dev, ops): + self.show_psu_i2c_device(dev, ops ) + return + + def show_client_device(self): + KEY ='client' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + list=['/sys/kernel/pddf/devices/showall'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_fan_device(self, dev, ops): + KEY ='fan' + path='pddf/devices/fan/i2c' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + + self.sysfs_device(dev['i2c']['topo_info'], path, self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], path, self.sysfs_obj, KEY) + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, path, self.sysfs_obj, KEY) + list=['/sys/kernel/pddf/devices/fan/i2c/i2c_type', + '/sys/kernel/pddf/devices/fan/i2c/i2c_name', + '/sys/kernel/pddf/devices/fan/i2c/error', + '/sys/kernel/pddf/devices/fan/i2c/attr_ops', + '/sys/kernel/pddf/devices/fan/i2c/dev_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_temp_sensor_device(self, dev, ops): + return + + def show_sysstatus_device(self, dev, ops): + KEY ='sysstatus' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + for attr in dev['attr_list']: + self.sysfs_device(attr, "pddf/devices/sysstatus", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/sysstatus/attr_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + + + def show_xcvr_i2c_device(self, dev, ops): + KEY ='xcvr' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/xcvr/i2c", self.sysfs_obj, KEY) + + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, "pddf/devices/xcvr/i2c", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/xcvr/i2c/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/xcvr/i2c/i2c_type', + '/sys/kernel/pddf/devices/xcvr/i2c/i2c_name', + '/sys/kernel/pddf/devices/xcvr/i2c/error', + '/sys/kernel/pddf/devices/xcvr/i2c/attr_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_xcvr_device(self, dev, ops): + self.show_xcvr_i2c_device(dev, ops ) + return + + def show_cpld_device(self, dev, ops): + KEY ='cpld' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['CPLD']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/cpld", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/cpld/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/cpld/i2c_type', + '/sys/kernel/pddf/devices/cpld/i2c_name', + '/sys/kernel/pddf/devices/cpld/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_led_platform_device(self, key, ops): + if ops['attr']=='all' or ops['attr']=='PLATFORM': + KEY='platform' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + path='pddf/devices/platform' + self.sysfs_attr('num_psus', self.data['PLATFORM']['num_psus'], path, self.sysfs_obj, KEY) + self.sysfs_attr('num_fantrays', self.data['PLATFORM']['num_fantrays'], path, self.sysfs_obj, KEY) + + def show_led_device(self, key, ops): + if self.check_led_cmds(key, ops): + KEY='led' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + path="pddf/devices/led" + for attr in self.data[key]['i2c']['attr_list']: + self.sysfs_attr('device_name', self.data[key]['dev_info']['device_name'],path,self.sysfs_obj,KEY) + self.sysfs_attr('swpld_addr', self.data[key]['dev_info']['device_name'],path,self.sysfs_obj,KEY) + self.sysfs_attr('swpld_addr_offset', self.data[key]['dev_info']['device_name'],path, + self.sysfs_obj, KEY) + self.sysfs_device(self.data[key]['dev_attr'], path, self.sysfs_obj, KEY) + for attr_key in attr.keys(): + attr_path="pddf/devices/led/" + attr['attr_name'] + if (attr_key != 'attr_name' and attr_key != 'swpld_addr' and attr_key != 'swpld_addr_offset'): + self.sysfs_attr(attr_key, attr[attr_key], attr_path, self.sysfs_obj, KEY) + sysfs_path="/sys/kernel/pddf/devices/led/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/led/cur_state/color', + '/sys/kernel/pddf/devices/led/cur_state/color_state'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def validate_xcvr_device(self, dev, ops): + devtype_list = ['optoe1', 'optoe2'] + dev_attribs = ['xcvr_present', 'xcvr_reset', 'xcvr_intr_status', 'xcvr_lpmode'] + ret_val = "xcvr validation failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['attr_list']: + if 'attr_name' in attr.keys() and 'eeprom' in attr.values(): + ret_val = "xcvr validation success" + else: + print "xcvr validation Failed" + return + + elif dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "Success" + else: + print "xcvr validation Failed" + return + print ret_val + + def validate_eeprom_device(self, dev, ops): + devtype_list = ['24c02'] + dev_access_mode = ['BLOCK', 'BYTE'] + dev_attribs = ['eeprom'] + ret_val = "eeprom failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + if dev['i2c']['dev_attr']['access_mode'] in dev_access_mode: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "eeprom success" + print ret_val + + def validate_mux_device(self, dev, ops): + devtype_list = ['pca9548', 'pca954x'] + dev_channels = ["0", "1", "2", "3", "4", "5", "6", "7"] + ret_val = "mux failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['channel']: + if attr.get("chn") in dev_channels: + ret_val = "Mux success" + print ret_val + + def validate_cpld_device(self, dev, ops): + devtype_list = ['i2c_cpld'] + ret_val = "cpld failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + ret_val = "cpld success" + print ret_val + + + def validate_sysstatus_device(self, dev, ops): + dev_attribs = ['board_info', 'cpld1_version', 'power_module_status', 'system_reset5', + 'system_reset6', 'system_reset7', 'misc1', 'cpld2_version', 'cpld3_version' + ] + ret_val = "sysstatus failed" + + if dev['dev_info']['device_type'] == "SYSSTAT": + for attr in dev['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "sysstatus success" + print ret_val + + def validate_temp_sensor_device(self, dev, ops): + devtype_list = ['lm75'] + dev_attribs = ['temp1_max', 'temp1_max_hyst', 'temp1_input'] + ret_val = "temp sensor failed" + + if dev['dev_info']['device_type'] == "TEMP_SENSOR": + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "tempsensor success" + print ret_val + + def validate_fan_device(self, dev, ops): + ret_val = "fan failed" + + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + if dev['i2c']['dev_attr']['num_fan'] is not None: + ret_val = "fan success" + + print ret_val + + def validate_psu_device(self, dev, ops): + dev_attribs = ['psu_present', 'psu_model_name', 'psu_power_good', 'psu_mfr_id', 'psu_serial_num', + 'psu_fan_dir', 'psu_v_out', 'psu_i_out', 'psu_p_out', 'psu_fan1_speed_rpm' + ] + ret_val = "psu failed" + + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + if attr.get("attr_devaddr") is not None: + if attr.get("attr_offset") is not None: + if attr.get("attr_mask") is not None: + if attr.get("attr_len") is not None: + ret_val = "psu success" + else: + ret_val = "psu failed" + + print ret_val + + ################################################################################################################### + # SPYTEST + ################################################################################################################### + def verify_attr(self, key, attr, path): + node="/sys/kernel/%s/%s"%(path, key) + try: + with open(node, 'r') as f: + status = f.read() + except IOError: + print "PDDF_VERIFY_ERR: IOError: node:%s key:%s"%(node, key) + return + + status=status.rstrip("\n\r") + if attr[key]!=status: + print "PDDF_VERIFY_ERR: node: %s switch:%s"%(node, status) + + def verify_device(self, attr, path, ops): + for key in attr.keys(): + self.verify_attr(key, attr, path) + + + def get_led_device(self, device_name): + self.create_attr('device_name', self.data[device_name]['dev_info']['device_name'], "pddf/devices/led") + self.create_attr('index', self.data[device_name]['dev_attr']['index'], "pddf/devices/led") + cmd="echo 'verify' > /sys/kernel/pddf/devices/led/dev_ops" + self.runcmd(cmd) + + def validate_sysfs_creation(self, obj, validate_type): + dir = '/sys/kernel/pddf/devices/'+validate_type + if (os.path.exists(dir) or validate_type=='client'): + for sysfs in obj[validate_type]: + if(not os.path.exists(sysfs)): + print "[SYSFS FILE] " + sysfs + ": does not exist" + else: + print "[SYSFS DIR] " + dir + ": does not exist" + + def validate_dsysfs_creation(self, obj, validate_type): + if validate_type in obj.keys(): + # There is a possibility that some components dont have any device-self.data attr + if not obj[validate_type]: + print "[SYSFS ATTR] for " + validate_type + ": empty" + else: + for sysfs in obj[validate_type]: + if(not os.path.exists(sysfs)): + print "[SYSFS FILE] " + sysfs + ": does not exist" + else: + print "[SYSFS DIR] " + dir + ": not configured" + + + + def verify_sysfs_data(self, verify_type): + if (verify_type=='LED'): + for key in self.data.keys(): + if key != 'PLATFORM': + attr=self.data[key]['dev_info'] + if attr['device_type'] == 'LED': + self.get_led_device(key) + self.verify_attr('device_name', self.data[key]['dev_info'], "pddf/devices/led") + self.verify_attr('index', self.data[key]['dev_attr'], "pddf/devices/led") + for attr in self.data[key]['i2c']['attr_list']: + path="pddf/devices/led/" + attr['attr_name'] + for entry in attr.keys(): + if (entry != 'attr_name' and entry != 'swpld_addr' and entry != 'swpld_addr_offset'): + self.verify_attr(entry, attr, path) + if ( entry == 'swpld_addr' or entry == 'swpld_addr_offset'): + self.verify_attr(entry, attr, 'pddf/devices/led') + + + + def schema_validation(self, validate_type): + process_validate_type = 0 + for key in self.data.keys(): + if (key != 'PLATFORM'): + temp_obj={} + schema_list=[] + try: + device_type=self.data[key]["dev_info"]["device_type"] + except Exception as e: + print "dev_info or device_type ERROR: " + key + print e + + if validate_type == 'mismatch': + process_validate_type = 1 + device_type="PSU" + schema_file="/usr/local/bin/schema/FAN.schema" + schema_list.append(schema_file) + elif validate_type == 'missing': + process_validate_type = 1 + schema_file="/usr/local/bin/schema/PLATFORM.schema" + schema_list.append(schema_file) + + elif validate_type == 'empty': + process_validate_type = 1 + if not device_type: + print "Empty device_type for " + key + continue + elif (validate_type=='all' or validate_type==device_type): + process_validate_type = 1 + if "bmc" in self.data[key].keys(): + schema_file="/usr/local/bin/schema/"+device_type + "_BMC.schema" + schema_list.append(schema_file) + + if "i2c" in self.data[key].keys(): + schema_file="/usr/local/bin/schema/"+device_type + ".schema" + schema_list.append(schema_file) + if device_type: + temp_obj[device_type]=self.data[key] + for schema_file in schema_list: + if (os.path.exists(schema_file)): + print "Validate " + schema_file + ";" + key + json_data=json.dumps(temp_obj) + with open(schema_file, 'r') as f: + schema=json.load(f) + try: + validate(temp_obj, schema) + except Exception as e: + print "Validation ERROR: " + schema_file + ";" + key + if validate_type == 'mismatch': + return + else: + print e + else: + print "ERROR Missing File: " + schema_file + if not process_validate_type: + print "device_type: " + validate_type + " not configured" + + def modules_validation(self, validate_type): + kos = [] + supported_type = False + module_validation_status=[] + + if validate_type == "bmc": + kos=['ipmi_devintf', 'ipmi_si', 'ipmi_msghandler'] + validate_type = 'ipmi' + else: + # generate the KOS list from pddf device JSON file + kos.extend(self.data['PLATFORM']['pddf_kos']) + + if 'custom_kos' in self.data['PLATFORM']: + kos.extend(self.data['PLATFORM']['custom_kos']) + + for mod in kos: + if validate_type in mod or validate_type == "pddf": + supported_type=True + cmd = "lsmod | grep " + mod + try: + subprocess.check_output(cmd, shell=True) + except Exception as e: + module_validation_status.append(mod) + if supported_type: + if module_validation_status: + module_validation_status.append(":ERROR not loaded") + print str(module_validation_status)[1:-1] + else: + print "Loaded" + else: + print validate_type + " not configured" + + + + ################################################################################################################### + # PARSE DEFS + ################################################################################################################### + def psu_parse(self, dev, ops): + parse_str="" + ret="" + for ifce in dev['i2c']['interface']: + ret=getattr(self, ops['cmd']+"_psu_device")(self.data[ifce['dev']], ops ) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_psu_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + return parse_str + + def fan_parse(self, dev, ops): + parse_str="" + ret=getattr(self, ops['cmd']+"_fan_device")(dev, ops ) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_fan_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + def temp_sensor_parse(self, dev, ops): + parse_str="" + ret=getattr(self, ops['cmd']+"_temp_sensor_device")(dev, ops ) + if not ret is None: + if str(ret).isdigit() : + if ret!=0: + # in case if 'create' functions + print "{}_temp_sensor_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + def cpld_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_cpld_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_cpld_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + + + + def sysstatus_parse(self, dev,ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_sysstatus_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_sysstatus_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + def gpio_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_gpio_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_temp_sensor_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str += ret + + return parse_str + + + def mux_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_mux_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_mux_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + for ch in dev['i2c']['channel']: + ret = self.dev_parse(self.data[ch['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + def mux_parse_reverse(self, dev, ops): + parse_str = "" + for ch in reversed(dev['i2c']['channel']): + ret = self.dev_parse(self.data[ch['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + + ret = getattr(self, ops['cmd']+"_mux_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_mux_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + + def eeprom_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_eeprom_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_eeprom_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + def optic_parse(self, dev, ops): + parse_str="" + ret="" + for ifce in dev['i2c']['interface']: + ret=getattr(self, ops['cmd']+"_xcvr_device")(self.data[ifce['dev']], ops ) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_eeprom_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str+=ret + return parse_str + + def cpu_parse(self, bus, ops): + parse_str = "" + for dev in bus['i2c']['CONTROLLERS']: + dev1 = self.data[dev['dev']] + for d in dev1['i2c']['DEVICES']: + ret=self.dev_parse(self.data[d['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + def cpu_parse_reverse(self, bus, ops): + parse_str = "" + for dev in reversed(bus['i2c']['CONTROLLERS']): + dev1 = self.data[dev['dev']] + for d in dev1['i2c']['DEVICES']: + ret=self.dev_parse(self.data[d['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + + def dev_parse(self, dev, ops): + attr=dev['dev_info'] + if attr['device_type'] == 'CPU': + if ops['cmd']=='delete': + return self.cpu_parse_reverse(dev, ops) + else: + return self.cpu_parse(dev, ops) + + if attr['device_type'] == 'EEPROM': + return self.eeprom_parse(dev, ops) + + if attr['device_type'] == 'MUX': + if ops['cmd']=='delete': + return self.mux_parse_reverse(dev, ops) + else: + return self.mux_parse(dev, ops) + + if attr['device_type'] == 'GPIO': + return self.gpio_parse(dev, ops) + + if attr['device_type'] == 'PSU': + return self.psu_parse(dev, ops) + + if attr['device_type'] == 'FAN': + return self.fan_parse(dev, ops) + + if attr['device_type'] == 'TEMP_SENSOR': + return self.temp_sensor_parse(dev, ops) + + if attr['device_type'] == 'SFP' or attr['device_type'] == 'QSFP' or \ + attr['device_type'] == 'SFP28' or attr['device_type'] == 'QSFP28' or \ + attr['device_type'] == 'QSFP-DD': + return self.optic_parse(dev, ops) + + if attr['device_type'] == 'CPLD': + return self.cpld_parse(dev, ops) + + if attr['device_type'] == 'SYSSTAT': + return self.sysstatus_parse(dev,ops) + + def is_supported_sysled_state(self, sysled_name, sysled_state): + if not sysled_name in self.data.keys(): + return False, "[FAILED] " + sysled_name + " is not configured" + for attr in self.data[sysled_name]['i2c']['attr_list']: + if attr['attr_name'] == sysled_state: + return True, "supported" + return False, "[FAILED]: Invalid color" + + def create_attr(self, key, value, path): + cmd = "echo '%s' > /sys/kernel/%s/%s"%(value, path, key) + self.runcmd(cmd) + + def create_led_platform_device(self, key, ops): + if ops['attr']=='all' or ops['attr']=='PLATFORM': + path='pddf/devices/platform' + self.create_attr('num_psus', self.data['PLATFORM']['num_psus'], path) + self.create_attr('num_fantrays', self.data['PLATFORM']['num_fantrays'], path) + + def create_led_device(self, key, ops): + if ops['attr']=='all' or ops['attr']==self.data[key]['dev_info']['device_name']: + path="pddf/devices/led" + for attr in self.data[key]['i2c']['attr_list']: + self.create_attr('device_name', self.data[key]['dev_info']['device_name'], path) + self.create_device(self.data[key]['dev_attr'], path, ops) + for attr_key in attr.keys(): + if (attr_key == 'swpld_addr_offset' or attr_key == 'swpld_addr'): + self.create_attr(attr_key, attr[attr_key], path) + elif (attr_key != 'attr_name' and attr_key != 'descr' and attr_key != 'attr_devtype' and + attr_key != 'attr_devname'): + state_path=path+'/state_attr' + self.create_attr(attr_key, attr[attr_key],state_path) + cmd="echo '" + attr['attr_name']+"' > /sys/kernel/pddf/devices/led/dev_ops" + self.runcmd(cmd) + + + def led_parse(self, ops): + getattr(self, ops['cmd']+"_led_platform_device")("PLATFORM", ops) + for key in self.data.keys(): + if key != 'PLATFORM' and 'dev_info' in self.data[key]: + attr=self.data[key]['dev_info'] + if attr['device_type'] == 'LED': + getattr(self, ops['cmd']+"_led_device")(key, ops) + + + def get_device_list(self, list, type): + for key in self.data.keys(): + if key != 'PLATFORM' and 'dev_info' in self.data[key]: + attr=self.data[key]['dev_info'] + if attr['device_type'] == type: + list.append(self.data[key]) + + + def create_pddf_devices(self): + self.led_parse({ "cmd": "create", "target":"all", "attr":"all" }) + create_ret = 0 + create_ret = self.dev_parse(self.data['SYSTEM'], { "cmd": "create", "target":"all", "attr":"all" } ) + if create_ret!=0: + return create_ret + if 'SYSSTATUS' in self.data: + create_ret = self.dev_parse(self.data['SYSSTATUS'], { "cmd": "create", "target":"all", "attr":"all" } ) + if create_ret!=0: + return create_ret + + def delete_pddf_devices(self): + self.dev_parse(self.data['SYSTEM'], { "cmd": "delete", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], { "cmd": "delete", "target":"all", "attr":"all" } ) + + def populate_pddf_sysfsobj(self): + self.dev_parse(self.data['SYSTEM'], { "cmd": "show", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], { "cmd": "show", "target":"all", "attr":"all" } ) + self.led_parse({ "cmd": "show", "target":"all", "attr":"all" }) + self.show_client_device() + + def cli_dump_dsysfs(self, component): + self.dev_parse(self.data['SYSTEM'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if component in self.data_sysfs_obj: + return self.data_sysfs_obj[component] + else: + return None + + + def validate_pddf_devices(self, *args): + self.populate_pddf_sysfsobj() + v_ops = { 'cmd': 'validate', 'target':'all', 'attr':'all' } + self.dev_parse(self.data['SYSTEM'], v_ops ) + + ################################################################################################################### + # BMC APIs + ################################################################################################################### + def populate_bmc_cache_db(self, bmc_attr): + bmc_cmd = str(bmc_attr['bmc_cmd']).strip() + + o_list = subprocess.check_output(bmc_cmd, shell=True).strip().split('\n') + bmc_cache[bmc_cmd]={} + bmc_cache[bmc_cmd]['time']=time.time() + for entry in o_list: + name = entry.split()[0] + bmc_cache[bmc_cmd][name]=entry + + def non_raw_ipmi_get_request(self, bmc_attr): + bmc_db_update_time=1 + value = 'N/A' + bmc_cmd = str(bmc_attr['bmc_cmd']).strip() + field_name = str(bmc_attr['field_name']).strip() + field_pos= int(bmc_attr['field_pos'])-1 + + if not bmc_cmd in bmc_cache: + self.populate_bmc_cache_db(bmc_attr) + else: + now = time.time() + if (int(now - bmc_cache[bmc_cmd]['time']) > bmc_db_update_time): + self.populate_bmc_cache_db(bmc_attr) + + try: + data=bmc_cache[bmc_cmd][field_name] + value = data.split()[field_pos] + except Exception as e: + pass + + if 'mult' in bmc_attr.keys() and not value.isalpha(): + if value.isalpha(): + value = 0.0 + value = float(value) * float(bmc_attr['mult']) + + return str(value) + + def raw_ipmi_get_request(self, bmc_attr): + value = 'N/A' + cmd = bmc_attr['bmc_cmd'] + " 2>/dev/null" + if bmc_attr['type'] == 'raw': + try: + value = subprocess.check_output(cmd, shell=True).strip() + except Exception as e: + pass + + if value != 'N/A': + value = str(int(value, 16)) + return value + + if bmc_attr['type'] == 'mask': + mask = int(bmc_attr['mask'].encode('utf-8'), 16) + try: + value = subprocess.check_output(cmd, shell=True).strip() + except Exception as e: + pass + + if value != 'N/A': + value = str(int(value, 16) & mask) + + return value + + if bmc_attr['type'] == 'ascii': + try: + value = subprocess.check_output(cmd, shell=True) + except Exception as e: + pass + + if value != 'N/A': + tmp = ''.join(chr(int(i, 16)) for i in value.split()) + tmp = "".join(i for i in unicode(tmp) if unicodedata.category(i)[0]!="C") + value = str(tmp) + + return (value) + + return value + + def bmc_get_cmd(self, bmc_attr): + if int(bmc_attr['raw']) == 1: + value = self.raw_ipmi_get_request(bmc_attr) + else: + value = self.non_raw_ipmi_get_request(bmc_attr) + return (value) + + def non_raw_ipmi_set_request(self, bmc_attr, val): + value = 'N/A' + # TODO: Implement it + return value + + def raw_ipmi_set_request(self, bmc_attr, val): + value = 'N/A' + # TODO: Implement this + return value + + def bmc_set_cmd(self, bmc_attr, val): + if int(bmc_attr['raw']) == 1: + value = self.raw_ipmi_set_request(bmc_attr, val) + else: + value = self.non_raw_ipmi_set_request(bmc_attr, val) + return (value) + + # bmc-based attr: return attr obj + # non-bmc-based attr: return empty obj + def check_bmc_based_attr(self, device_name, attr_name): + if device_name in self.data.keys(): + if "bmc" in self.data[device_name].keys() and 'ipmitool' in self.data[device_name]['bmc'].keys(): + attr_list = self.data[device_name]['bmc']['ipmitool']['attr_list'] + for attr in attr_list: + if attr['attr_name'].strip() == attr_name.strip(): + return attr + # Required attr_name is not supported in BMC object + return {} + return None + + def get_attr_name_output(self, device_name, attr_name): + bmc_attr = self.check_bmc_based_attr(device_name, attr_name) + output={"mode":"", "status":""} + + if bmc_attr is not None: + if bmc_attr=={}: + return {} + output['mode']="bmc" + output['status']=self.bmc_get_cmd(bmc_attr) + else: + output['mode']="i2c" + node = self.get_path(device_name, attr_name) + if node is None: + return {} + try: + with open(node, 'r') as f: + output['status'] = f.read() + except IOError: + return {} + return output + + def set_attr_name_output(self, device_name, attr_name, val): + bmc_attr = self.check_bmc_based_attr(device_name, attr_name) + output={"mode":"", "status":""} + + if bmc_attr is not None: + if bmc_attr=={}: + return {} + output['mode']="bmc" + output['status']=False # No set operation allowed for BMC attributes as they are handled by BMC itself + else: + output['mode']="i2c" + node = self.get_path(device_name, attr_name) + if node is None: + return {} + try: + with open(node, 'w') as f: + f.write(str(val)) + except IOError: + return {} + + output['status'] = True + + return output + diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/__init__.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/__init__.py new file mode 100644 index 000000000000..d9a604cf816e --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/__init__.py @@ -0,0 +1,7 @@ +# All the derived classes for PDDF +__all__ = ["platform", "chassis", "sfp", "psu", "thermal"] + +# Commenting the below code as this just for the reference for the ODMs. +# It can be uncommented when this reference code is used + +#from sonic_platform import * diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/chassis.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/chassis.py new file mode 100644 index 000000000000..72f1858a776c --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/chassis.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# PDDF +# Module contains an implementation of SONiC Chassis API +# +############################################################################# + +try: + from sonic_platform_pddf_base.pddf_chassis import PddfChassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Chassis(PddfChassis): + """ + PDDF Platform-specific Chassis class + """ + + def __init__(self, pddf_data=None, pddf_plugin_data=None): + PddfChassis.__init__(self, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/eeprom.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/eeprom.py new file mode 100644 index 000000000000..4857895c2a01 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/eeprom.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +try: + from sonic_platform_pddf_base.pddf_eeprom import PddfEeprom +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + + +class Eeprom(PddfEeprom): + + def __init__(self, pddf_data=None, pddf_plugin_data=None): + PddfEeprom.__init__(self, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/fan.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/fan.py new file mode 100644 index 000000000000..027a2f4a6148 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/fan.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_fan import PddfFan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Fan(PddfFan): + """PDDF Platform-Specific Fan class""" + + def __init__(self, tray_idx, fan_idx=0, pddf_data=None, pddf_plugin_data=None, is_psu_fan=False, psu_index=0): + # idx is 0-based + PddfFan.__init__(self, tray_idx, fan_idx, pddf_data, pddf_plugin_data, is_psu_fan, psu_index) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/platform.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/platform.py new file mode 100644 index 000000000000..406b1179ae1b --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/platform.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +############################################################################# +# PDDF +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + + +try: + from sonic_platform_pddf_base.pddf_platform import PddfPlatform +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PddfPlatform): + """ + PDDF Platform-Specific Platform Class + """ + + def __init__(self): + PddfPlatform.__init__(self) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/psu.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/psu.py new file mode 100644 index 000000000000..edd747e9963b --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/psu.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_psu import PddfPsu +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +class Psu(PddfPsu): + """PDDF Platform-Specific PSU class""" + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + PddfPsu.__init__(self, index, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/sfp.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/sfp.py new file mode 100644 index 000000000000..9588db53283c --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/sfp.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +try: + from sonic_platform_pddf_base.pddf_sfp import PddfSfp +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class Sfp(PddfSfp): + """ + PDDF Platform-Specific Sfp class + """ + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + PddfSfp.__init__(self, index, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/thermal.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/thermal.py new file mode 100644 index 000000000000..5b829fc26caa --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/thermal.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_thermal import PddfThermal +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + + +class Thermal(PddfThermal): + """PDDF Platform-Specific Thermal class""" + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-modules-pddf.dep b/platform/pddf/platform-modules-pddf.dep new file mode 100644 index 000000000000..19a4bb344759 --- /dev/null +++ b/platform/pddf/platform-modules-pddf.dep @@ -0,0 +1,10 @@ + +MPATH := $($(PDDF_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/pddf/platform-modules-pddf.mk platform/pddf/platform-modules-pddf.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(PDDF_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(PDDF_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PDDF_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/pddf/platform-modules-pddf.mk b/platform/pddf/platform-modules-pddf.mk new file mode 100644 index 000000000000..5947c1806565 --- /dev/null +++ b/platform/pddf/platform-modules-pddf.mk @@ -0,0 +1,12 @@ +# PDDF Generic Platform modules +#################################################### +PDDF_PLATFORM_MODULE_VERSION = 1.1 + +export PDDF_PLATFORM_MODULE_VERSION + +PDDF_PLATFORM_MODULE = sonic-platform-pddf_$(PDDF_PLATFORM_MODULE_VERSION)_amd64.deb +$(PDDF_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PDDF_PATH)/i2c +$(PDDF_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +SONIC_DPKG_DEBS += $(PDDF_PLATFORM_MODULE) + +SONIC_STRETCH_DEBS += $(PDDF_PLATFORM_MODULE) diff --git a/platform/pddf/rules.dep b/platform/pddf/rules.dep new file mode 100644 index 000000000000..de40f6e88c2f --- /dev/null +++ b/platform/pddf/rules.dep @@ -0,0 +1,3 @@ +#DPKG FRK +include $(PLATFORM_PDDF_PATH)/platform-modules-pddf.dep +include $(PLATFORM_PDDF_PATH)/platform-api-pddf-base.dep diff --git a/platform/pddf/rules.mk b/platform/pddf/rules.mk new file mode 100644 index 000000000000..6c2fdfb89b58 --- /dev/null +++ b/platform/pddf/rules.mk @@ -0,0 +1,3 @@ +include $(PLATFORM_PDDF_PATH)/platform-modules-pddf.mk +include $(PLATFORM_PDDF_PATH)/platform-api-pddf-base.mk + diff --git a/rules/config b/rules/config index 8cffedc4e965..8f486d8170e0 100644 --- a/rules/config +++ b/rules/config @@ -63,6 +63,10 @@ DEFAULT_PASSWORD = YourPaSsWoRd # Uncomment next line to enable: # INSTALL_DEBUG_TOOLS = y +# SONIC_USE_PDDF_FRAMEWORK - Use PDDF generic drivers and plugins +# Uncomment next line to enable: +SONIC_USE_PDDF_FRAMEWORK = y + # SONIC_ROUTING_STACK - specify the routing-stack being elected to drive SONiC's control-plane. # Supported routing stacks on SONiC are: # routing-stacks: quagga, frr. diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index 75a22425fd48..afe27d70e492 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -23,6 +23,9 @@ $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PSUD) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_SYSEEPROMD) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_THERMALCTLD) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_XCVRD) +ifeq ($(PDDF_SUPPORT),y) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(PDDF_PLATFORM_API_BASE_PY2) +endif $(DOCKER_PLATFORM_MONITOR)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_PLATFORM_MONITOR)_DBG_DEPENDS += $(LIBSWSSCOMMON_DBG) $(LIBSENSORS_DBG) @@ -42,6 +45,7 @@ $(DOCKER_PLATFORM_MONITOR)_CONTAINER_NAME = pmon $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += --privileged -t $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /var/run/platform_cache:/var/run/platform_cache:ro +$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /usr/share/sonic/device/pddf:/usr/share/sonic/device/pddf:ro # Mount Arista python library on Aboot images to be used by plugins $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista:/usr/lib/python2.7/dist-packages/arista:ro diff --git a/slave.mk b/slave.mk index f7b3636d1abc..a959936f1aa4 100644 --- a/slave.mk +++ b/slave.mk @@ -138,8 +138,21 @@ endif include $(RULES_PATH)/functions + +ifeq ($(SONIC_USE_PDDF_FRAMEWORK),y) +PDDF_SUPPORT = y +else +PDDF_SUPPORT = n +endif +export PDDF_SUPPORT + include $(RULES_PATH)/*.mk ifneq ($(CONFIGURED_PLATFORM), undefined) +ifeq ($(PDDF_SUPPORT), y) +PDDF_DIR = pddf +PLATFORM_PDDF_PATH = platform/$(PDDF_DIR) +include $(PLATFORM_PDDF_PATH)/rules.mk +endif include $(PLATFORM_PATH)/rules.mk endif @@ -237,6 +250,7 @@ $(info "INCLUDE_SFLOW" : "$(INCLUDE_SFLOW)") $(info "INCLUDE_NAT" : "$(INCLUDE_NAT)") $(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)") $(info "TELEMETRY_WRITABLE" : "$(TELEMETRY_WRITABLE)") +$(info "PDDF_SUPPORT" : "$(PDDF_SUPPORT)") $(info ) else $(info SONiC Build System for $(CONFIGURED_PLATFORM):$(CONFIGURED_ARCH)) @@ -820,6 +834,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) \ + $(if $(findstring y,$(PDDF_SUPPORT)),$(addprefix $(PYTHON_WHEELS_PATH)/,$(PDDF_PLATFORM_API_BASE_PY2))) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY3)) \ @@ -847,6 +862,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export include_sflow="$(INCLUDE_SFLOW)" export include_mgmt_framework="$(INCLUDE_MGMT_FRAMEWORK)" export include_iccpd="$(INCLUDE_ICCPD)" + export pddf_support="$(PDDF_SUPPORT)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" export include_kubernetes="$(INCLUDE_KUBERNETES)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" From d0c7bd8158a8fc0bf1ca0a24d88fd9c153429fa6 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 12 Nov 2020 17:58:56 -0800 Subject: [PATCH 1390/1427] [sonic-py-swsssdk][sonic-snmpagent][sonic-utilities] Update submodules (#5849) Submodule updates include the following commits. Also adding sonic-swsscommon build dependencies where necessary. * src/sonic-py-swsssdk 1ea30d2...9d9f0c6 (1): > [SonicV2Connector] make decode_responses=True as default, so python2 application need no code change when migrated to python3(#93) * src/sonic-snmpagent 6e4a796...57e54d9 (3): > Interact with Redis by str instead of bytes, migrate to SonicV2Connector with `decode_responses=True` (#171) > Add a test case for LLDP_LOC_CHASSIS.lldp_loc_man_addr has only one IPv6 address (#167) > [LLDP]: Update init_db to load global database config (#166) * src/sonic-utilities acfa824...b693cf6 (11): > Remove SKU create pytest output directory before execution of the script (#1226) > [show][techsupport][multi-ASIC] Add support to collect tech support on multi ASIC platform (#1193) > [show] Fix `show ip bgp sum` (#1194) > [sonic_sku_create] Move tests from sonic-utilities-tests/ folder to tests/ folder (#1222) > Replace swsssdk.SonicV2Connector with swsscommon.SonicV2Connector (SWIG wrapper of C++ implementation) in production code (#1217) > Copy missing values from INIT_CFG to config_db as part of db_migration task (#1209) > [connect][clear] Support --devicename option for connect/clear line commands (#1214) > [consutil][show] Remove root need from show line command (#1218) > [Mellanox] SKU creator Tool (#1163) > SONiC installer - fix string formatting during image type check (#1197) > [show/fgnhg.py] Fix whitespace issues (#1211) --- rules/asyncsnmp-py3.mk | 1 + rules/sonic-utilities.mk | 5 ++++- src/sonic-py-swsssdk | 2 +- src/sonic-snmpagent | 2 +- src/sonic-utilities | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/rules/asyncsnmp-py3.mk b/rules/asyncsnmp-py3.mk index cc0af244d856..990cc4512f8c 100644 --- a/rules/asyncsnmp-py3.mk +++ b/rules/asyncsnmp-py3.mk @@ -5,4 +5,5 @@ $(ASYNCSNMP_PY3)_SRC_PATH = $(SRC_PATH)/sonic-snmpagent $(ASYNCSNMP_PY3)_PYTHON_VERSION = 3 # Depends on sonic-platform-common so it is possible to import sonic_psu $(ASYNCSNMP_PY3)_DEPENDS += $(SWSSSDK_PY3) $(SONIC_PLATFORM_COMMON_PY3) +$(ASYNCSNMP_PY3)_DEBS_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(PYTHON3_SWSSCOMMON) SONIC_PYTHON_WHEELS += $(ASYNCSNMP_PY3) diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index db796b189b40..f3b6e332545d 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -20,5 +20,8 @@ $(SONIC_UTILITIES_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) \ $(SONIC_UTILITIES_PY2)_DEBS_DEPENDS = $(LIBYANG) \ $(LIBYANG_CPP) \ $(LIBYANG_PY2) \ - $(LIBYANG_PY3) + $(LIBYANG_PY3) \ + $(LIBSWSSCOMMON) \ + $(PYTHON_SWSSCOMMON) \ + $(PYTHON3_SWSSCOMMON) SONIC_PYTHON_WHEELS += $(SONIC_UTILITIES_PY2) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 1ea30d2e27bf..9d9f0c60239d 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 1ea30d2e27bf4e9c9127611e72f5b3bd74025731 +Subproject commit 9d9f0c60239d9b02e7589b8cedeafcc4e60bd7c8 diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 6e4a796b245a..57e54d956193 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 6e4a796b245a99da29f8390fe01d09a37d32ec4f +Subproject commit 57e54d9561934b853a44185bbb401207f4503292 diff --git a/src/sonic-utilities b/src/sonic-utilities index acfa8248d799..b693cf60386c 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit acfa8248d79970e4d0225dd08082dc8f85ad030d +Subproject commit b693cf60386cd394c89a9b9f258d3af55dd59b0f From 48822be2aa66240c896c751089c282e2ca26a641 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 13 Nov 2020 03:12:12 -0800 Subject: [PATCH 1391/1427] [dbsycnd] update submodule head of dbsyncd (#5916) [lldp daemon] improve lldp daemon event when neighbor capability is not sent (#30) Signed-off-by: Ying Xie --- src/sonic-dbsyncd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-dbsyncd b/src/sonic-dbsyncd index 399ac217c6d0..95824a9a4b0c 160000 --- a/src/sonic-dbsyncd +++ b/src/sonic-dbsyncd @@ -1 +1 @@ -Subproject commit 399ac217c6d0c6e2397cb690e6d30b7c56aa52d3 +Subproject commit 95824a9a4b0c2be3351f6a93f3f55327d10113c0 From 56fa3cf494068af0c1ac0d298e583ac09e5e4382 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 13 Nov 2020 11:39:16 -0800 Subject: [PATCH 1392/1427] [sonic-bgpcfgd] Call Python 3 version of sonic-cfggen for testing (#5847) sonic-bgpcfgd build fails in the absence of Python 2, as it attempts to explicitly call sonic-cfggen using `/usr/bin/python2.7`. Also, it attempts to call sonic-cfggen using a local, relative path. Since the sonic-config-engine package is not installed, neither are its dependencies. Now, we configure the Python 3 sonic-config-engine as a dependency of sonic-bgpcfgd, which ensures the Python 3 sonic-config-engine package and its dependencies are installed before sonic-bgpcfgd is built/tested. --- rules/sonic_bgpcfgd.mk | 2 +- src/sonic-bgpcfgd/setup.py | 3 ++- .../data/sonic-cfggen/bgpd.conf.j2/all.conf | 13 +++--------- .../sonic-cfggen/bgpd.main.conf.j2/all.conf | 7 ++----- .../bgpd.main.conf.j2/defaults.conf | 7 ++----- .../base.conf | 20 +++++++++---------- .../data/sonic-cfggen/frr.conf.j2/all.conf | 16 +++++---------- .../data/sonic-cfggen/zebra/interfaces.conf | 6 ++---- .../tests/data/sonic-cfggen/zebra/zebra.conf | 10 ++++------ src/sonic-bgpcfgd/tests/test_sonic-cfggen.py | 5 ++--- 10 files changed, 33 insertions(+), 56 deletions(-) diff --git a/rules/sonic_bgpcfgd.mk b/rules/sonic_bgpcfgd.mk index 2710beecc263..3e1395842b51 100644 --- a/rules/sonic_bgpcfgd.mk +++ b/rules/sonic_bgpcfgd.mk @@ -7,7 +7,7 @@ $(SONIC_BGPCFGD)_SRC_PATH = $(SRC_PATH)/sonic-bgpcfgd # as part of its unit tests. # TODO: Refactor unit tests so that these dependencies are not needed -$(SONIC_BGPCFGD)_DEPENDS += $(SONIC_PY_COMMON_PY2) +$(SONIC_BGPCFGD)_DEPENDS += $(SONIC_CONFIG_ENGINE_PY3) $(SONIC_BGPCFGD)_DEBS_DEPENDS += $(PYTHON3_SWSSCOMMON) $(SONIC_BGPCFGD)_PYTHON_VERSION = 3 SONIC_PYTHON_WHEELS += $(SONIC_BGPCFGD) diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index 69110bbe7915..91fcdd0ac266 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -26,6 +26,7 @@ ], tests_require = [ 'pytest', - 'pytest-cov' + 'pytest-cov', + 'sonic-config-engine' ] ) diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf index 7671d026ef63..f1a1cc5408b5 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf @@ -1,12 +1,10 @@ ! ! template: bgpd/bgpd.conf.j2 ! -! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== ! generated by templates/quagga/bgpd.conf.j2 with config DB data ! file: bgpd.conf ! -! ! template: common/daemons.common.conf.j2 ! hostname new_hostname @@ -19,8 +17,6 @@ log facility local4 ! end of template: common/daemons.common.conf.j2! agentx ! -! -! ! template: bgpd/bgpd.main.conf.j2 ! ! bgp multiple-instance @@ -33,15 +29,13 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.0/24 -! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 5 permit fc01::/64 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.0/24 ! +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::/64 ! route-map HIDE_INTERNAL permit 10 set community local-AS ! -! router bgp 55555 ! bgp log-neighbor-changes @@ -61,11 +55,10 @@ router bgp 55555 network fc00::1/64 exit-address-family ! + network 10.10.10.1/24 address-family ipv6 network fc01::1/64 exit-address-family - network 10.10.10.1/24 -! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf index 249e70c91d76..4fc1b7261e83 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf @@ -11,15 +11,13 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.0/24 -! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 15 permit fc01::/64 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.0/24 ! +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::/64 ! route-map HIDE_INTERNAL permit 10 set community local-AS ! -! router bgp 55555 ! bgp log-neighbor-changes @@ -43,7 +41,6 @@ router bgp 55555 address-family ipv6 network fc01::1/64 exit-address-family -! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf index d79234ffdb38..a1a4bd5a6a7d 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf @@ -11,15 +11,13 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.0/24 -! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 15 permit fc01::/64 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.0/24 ! +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::/64 ! route-map HIDE_INTERNAL permit 10 set community local-AS ! -! router bgp 55555 ! bgp log-neighbor-changes @@ -43,7 +41,6 @@ router bgp 55555 address-family ipv6 network fc01::1/64 exit-address-family -! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf index 2f543715299c..581eb107ec23 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf @@ -1,6 +1,6 @@ ! ! Vnet BGP instance -router bgp 555 vrf Second +router bgp 555 vrf First no bgp default ipv4-unicast bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -8,17 +8,17 @@ router bgp 555 vrf Second bgp graceful-restart restart-time 240 bgp graceful-restart bgp router-id 10.20.30.40 - neighbor 20.20.20.1 remote-as 20 - neighbor 20.20.20.1 description session2 + neighbor 10.10.10.1 remote-as 10 + neighbor 10.10.10.1 description session1 address-family ipv4 unicast - neighbor 20.20.20.1 activate - neighbor 20.20.20.1 soft-reconfiguration inbound + neighbor 10.10.10.1 activate + neighbor 10.10.10.1 soft-reconfiguration inbound maximum-paths 64 exit-address-family address-family l2vpn evpn advertise ipv4 unicast exit-address-family -router bgp 555 vrf First +router bgp 555 vrf Second no bgp default ipv4-unicast bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -26,11 +26,11 @@ router bgp 555 vrf First bgp graceful-restart restart-time 240 bgp graceful-restart bgp router-id 10.20.30.40 - neighbor 10.10.10.1 remote-as 10 - neighbor 10.10.10.1 description session1 + neighbor 20.20.20.1 remote-as 20 + neighbor 20.20.20.1 description session2 address-family ipv4 unicast - neighbor 10.10.10.1 activate - neighbor 10.10.10.1 soft-reconfiguration inbound + neighbor 20.20.20.1 activate + neighbor 20.20.20.1 soft-reconfiguration inbound maximum-paths 64 exit-address-family address-family l2vpn evpn diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf index 4b88beb66565..da63c01adc09 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf @@ -3,7 +3,6 @@ ! generated by templates/frr.conf.j2 with config DB data ! file: frr.conf ! -! ! template: common/daemons.common.conf.j2 ! hostname test_hostname @@ -16,15 +15,13 @@ log facility local4 ! end of template: common/daemons.common.conf.j2! agentx ! -! -! ! Enable nht through default route ip nht resolve-via-default ! Enable link-detect (default disabled) -interface Ethernet4 +interface Ethernet0 link-detect ! -interface Ethernet0 +interface Ethernet4 link-detect ! interface PortChannel10 @@ -51,15 +48,13 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.0/24 -! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 5 permit fc01::/64 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.0/24 ! +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::/64 ! route-map HIDE_INTERNAL permit 10 set community local-AS ! -! router bgp 55555 ! bgp log-neighbor-changes @@ -79,11 +74,10 @@ router bgp 55555 network fc00::1/64 exit-address-family ! + network 10.10.10.1/24 address-family ipv6 network fc01::1/64 exit-address-family - network 10.10.10.1/24 -! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf index 1a49042fad34..ddd129bcd18b 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf @@ -1,12 +1,11 @@ ! -! ! Enable nht through default route ip nht resolve-via-default ! Enable link-detect (default disabled) -interface Ethernet4 +interface Ethernet0 link-detect ! -interface Ethernet0 +interface Ethernet4 link-detect ! interface PortChannel10 @@ -15,4 +14,3 @@ link-detect interface PortChannel20 link-detect ! -! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf index 5bff88c711eb..ac2d8dac88f2 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf @@ -3,7 +3,6 @@ ! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! -! ! template: common/daemons.common.conf.j2 ! hostname new_hostname @@ -15,20 +14,19 @@ log facility local4 ! ! end of template: common/daemons.common.conf.j2! ! -vrf Second -vni 20 -! vrf First vni 10 ! +vrf Second +vni 20 ! ! Enable nht through default route ip nht resolve-via-default ! Enable link-detect (default disabled) -interface Ethernet4 +interface Ethernet0 link-detect ! -interface Ethernet0 +interface Ethernet4 link-detect ! interface PortChannel10 diff --git a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py index 92f6dec249b4..f49f0a0a42d8 100644 --- a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py +++ b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py @@ -12,9 +12,8 @@ def run_test(name, template_path, json_path, match_path): template_path = os.path.join(TEMPLATE_PATH, template_path) json_path = os.path.join(DATA_PATH, json_path) - cfggen = os.path.abspath("../sonic-config-engine/sonic-cfggen") - command = ['/usr/bin/python2.7', cfggen, "-T", TEMPLATE_PATH, "-t", template_path, "-y", json_path] - p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={"PYTHONPATH": "."}) + command = ['sonic-cfggen', "-T", TEMPLATE_PATH, "-t", template_path, "-y", json_path] + p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert p.returncode == 0, "sonic-cfggen for %s test returned %d code. stderr='%s'" % (name, p.returncode, stderr) raw_generated_result = stdout.decode("ascii") From 7c17c58b8326b2c3f0a22271abd11903a52d0ee5 Mon Sep 17 00:00:00 2001 From: heidinet2007 <43017482+heidinet2007@users.noreply.github.com> Date: Fri, 13 Nov 2020 13:34:18 -0800 Subject: [PATCH 1393/1427] Move teamd warm reboot code to service script (#5163) Summary: Move teamd functions to a new service script Motivation: To segregate teamd functions in one common place. fast-reboot script calls teamd functions that should ideally be replaced by a simple call to a service script. Changes: New teamd service script and path modification from /usr/bin/teamd.sh to /usr/local/bin/teamd.sh fast-reboot script (in sonic-utilities) modification (to use new teamd.sh to stop teamd) should follow soon after this change. Verification: VS image tests. Signed-off-by: Vaibhav Hemant Dixit Co-authored-by: heidi.ou@alibaba-inc.com Co-authored-by: Ying Xie --- .../per_namespace/teamd.service.j2 | 6 +- .../build_templates/sonic_debian_extension.j2 | 3 +- files/scripts/teamd.sh | 108 ++++++++++++++++++ 3 files changed, 113 insertions(+), 4 deletions(-) create mode 100755 files/scripts/teamd.sh diff --git a/files/build_templates/per_namespace/teamd.service.j2 b/files/build_templates/per_namespace/teamd.service.j2 index 092f9d2ebde2..322ffdc407ed 100644 --- a/files/build_templates/per_namespace/teamd.service.j2 +++ b/files/build_templates/per_namespace/teamd.service.j2 @@ -9,9 +9,9 @@ StartLimitBurst=3 [Service] User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} -ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} -ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +ExecStartPre=/usr/local/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/local/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/local/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} Restart=always RestartSec=30 diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0fe1043fcb81..7afc099e3a40 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -565,12 +565,13 @@ sudo LANG=C chroot $FILESYSTEM_ROOT fuser -km /sys || true sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys {% endif %} -# Copy service scripts (swss, syncd, bgp, radv) +# Copy service scripts (swss, syncd, bgp, teamd, radv) sudo LANG=C cp $SCRIPTS_DIR/swss.sh $FILESYSTEM_ROOT/usr/local/bin/swss.sh sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh sudo LANG=C cp $SCRIPTS_DIR/syncd_common.sh $FILESYSTEM_ROOT/usr/local/bin/syncd_common.sh sudo LANG=C cp $SCRIPTS_DIR/gbsyncd.sh $FILESYSTEM_ROOT/usr/local/bin/gbsyncd.sh sudo LANG=C cp $SCRIPTS_DIR/bgp.sh $FILESYSTEM_ROOT/usr/local/bin/bgp.sh +sudo LANG=C cp $SCRIPTS_DIR/teamd.sh $FILESYSTEM_ROOT/usr/local/bin/teamd.sh sudo LANG=C cp $SCRIPTS_DIR/radv.sh $FILESYSTEM_ROOT/usr/local/bin/radv.sh # Copy sonic-netns-exec script diff --git a/files/scripts/teamd.sh b/files/scripts/teamd.sh new file mode 100755 index 000000000000..626bb5186ca0 --- /dev/null +++ b/files/scripts/teamd.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +function debug() +{ + /usr/bin/logger $1 + /bin/echo `date` "- $1" >> ${DEBUGLOG} +} + +function check_warm_boot() +{ + SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then + WARM_BOOT="true" + else + WARM_BOOT="false" + fi +} + +function validate_restore_count() +{ + if [[ x"$WARM_BOOT" == x"true" ]]; then + RESTORE_COUNT=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_TABLE|${SERVICE}" restore_count` + # We have to make sure db data has not been flushed. + if [[ -z "$RESTORE_COUNT" ]]; then + WARM_BOOT="false" + fi + fi +} + +function check_fast_boot () +{ + if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + FAST_BOOT="true" + else + FAST_BOOT="false" + fi +} + +start() { + debug "Starting ${SERVICE}$DEV service..." + + check_warm_boot + validate_restore_count + + check_fast_boot + + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Fast boot flag: ${SERVICE}$DEV ${Fast_BOOT}." + + # start service docker + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE}$DEV service..." +} + +wait() { + /usr/bin/${SERVICE}.sh wait $DEV +} + +stop() { + debug "Stopping ${SERVICE}$DEV service..." + + check_warm_boot + check_fast_boot + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Fast boot flag: ${SERVICE}$DEV ${FAST_BOOT}." + + if [[ x"$WARM_BOOT" == x"true" ]]; then + # Send USR1 signal to all teamd instances to stop them + # It will prepare teamd for warm-reboot + # Note: We must send USR1 signal before syncd, because it will send the last packet through CPU port + docker exec -i ${SERVICE}$DEV pkill -USR1 ${SERVICE} > /dev/null || [ $? == 1 ] + elif [[ x"$FAST_BOOT" == x"true" ]]; then + # Kill teamd processes inside of teamd container with SIGUSR2 to allow them to send last LACP frames + # We call `docker kill teamd` to ensure the container stops as quickly as possible, + # Note: teamd must be killed before syncd, because it will send the last packet through CPU port + docker exec -i ${SERVICE}$DEV pkill -USR2 ${SERVICE} || [ $? == 1 ] + while docker exec -i ${SERVICE}$DEV pgrep ${SERVICE} > /dev/null; do + sleep 0.05 + done + docker kill ${SERVICE}$DEV &> /dev/null || debug "Docker ${SERVICE}$DEV is not running ($?) ..." + fi + + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." +} + +DEV=$2 + +SERVICE="teamd" +DEBUGLOG="/tmp/teamd-debug$DEV.log" +NAMESPACE_PREFIX="asic" +if [ "$DEV" ]; then + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" +else + SONIC_DB_CLI="sonic-db-cli" +fi + +case "$1" in + start|wait|stop) + $1 + ;; + *) + echo "Usage: $0 {start|wait|stop}" + exit 1 + ;; +esac From bf505626702116b9806d1680fd618e5e3e1e2faa Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Fri, 13 Nov 2020 15:31:51 -0800 Subject: [PATCH 1394/1427] [minigraph.py]: Parse peer switch info from minigraph (#5869) * Create new `PEER_SWITCH` table in config DB with info from minigraph * Add `subtype` field to `DEVICE_METADATA` table and set value to `DualToR` if device is in a dual ToR setup --- src/sonic-config-engine/minigraph.py | 33 +++++++++++++++++++ .../tests/simple-sample-graph-case.xml | 2 +- .../tests/test_minigraph_case.py | 19 +++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index c564d6051980..ed90a8849362 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -65,6 +65,18 @@ def default(self, obj): return str(obj) return json.JSONEncoder.default(self, obj) +def get_peer_switch_info(link_metadata, devices): + peer_switch_table = {} + for data in link_metadata.values(): + if "PeerSwitch" in data: + peer_hostname = data["PeerSwitch"] + peer_lo_addr = devices[peer_hostname]["lo_addr"] + peer_switch_table[peer_hostname] = { + 'address_ipv4': peer_lo_addr + } + + return peer_switch_table + def parse_device(device): lo_prefix = None mgmt_prefix = None @@ -674,16 +686,31 @@ def parse_linkmeta(meta, hname): # Cannot find a matching hname, something went wrong continue + has_peer_switch = False + upper_tor_hostname = '' + lower_tor_hostname = '' + properties = linkmeta.find(str(QName(ns1, "Properties"))) for device_property in properties.findall(str(QName(ns1, "DeviceProperty"))): name = device_property.find(str(QName(ns1, "Name"))).text value = device_property.find(str(QName(ns1, "Value"))).text if name == "FECDisabled": fec_disabled = value + elif name == "GeminiPeeringLink": + has_peer_switch = True + elif name == "UpperTOR": + upper_tor_hostname = value + elif name == "LowerTOR": + lower_tor_hostname = value linkmetas[port] = {} if fec_disabled: linkmetas[port]["FECDisabled"] = fec_disabled + if has_peer_switch: + if upper_tor_hostname == hname: + linkmetas[port]["PeerSwitch"] = lower_tor_hostname + else: + linkmetas[port]["PeerSwitch"] = upper_tor_hostname return linkmetas @@ -1001,8 +1028,14 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw } } + results['PEER_SWITCH'] = get_peer_switch_info(linkmetas, devices) + + if bool(results['PEER_SWITCH']): + results['DEVICE_METADATA']['localhost']['subtype'] = 'DualToR' + if is_storage_device: results['DEVICE_METADATA']['localhost']['storage_device'] = "true" + # for this hostname, if sub_role is defined, add sub_role in # device_metadata if sub_role is not None: diff --git a/src/sonic-config-engine/tests/simple-sample-graph-case.xml b/src/sonic-config-engine/tests/simple-sample-graph-case.xml index c499dc15760d..c70a1561b69a 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-case.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-case.xml @@ -286,7 +286,7 @@ - DevicePeeringLink + GeminiPeeringLink True diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 4ab1915864c3..019c791a1899 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -52,6 +52,11 @@ def test_jinja_expression(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'ToRRouter') + def test_minigraph_subtype(self): + argument = '-m "' + self.sample_graph + '" -v "DEVICE_METADATA[\'localhost\'][\'subtype\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'DualToR') + def test_additional_json_data(self): argument = '-a \'{"key1":"value1"}\' -v key1' output = self.run_script(argument) @@ -174,6 +179,20 @@ def test_minigraph_bgp_mon(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{}") + def test_minigraph_peer_switch(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "PEER_SWITCH"' + expected_table = { + 'switch2-t0': { + 'address_ipv4': "25.1.1.10" + } + } + + output = self.run_script(argument) + self.assertEqual( + utils.to_dict(output.strip()), + expected_table + ) + def test_mux_cable_parsing(self): result = minigraph.parse_xml(self.sample_graph, port_config_file=self.port_config) From af654944bd961ebb42a2572b055d4f4465ceb554 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 13 Nov 2020 17:54:20 -0800 Subject: [PATCH 1395/1427] [bgp]: Update TSA functionality (#5906) Fixed TSA bugs: 1. TSA didn't advertise Loopback ipv6 address 2. TSA and TSB changed BGP dynamic and BGP monitors sessions **- How to verify it** Build an image and run on your DUT. ``` admin@str-s6100-acs-1:~$ TSA System Mode: Normal -> Maintenance admin@str-s6100-acs-1:~$ vtysh -c 'show bgp ipv4 neighbors 10.0.0.1 advertised-routes' BGP table version is 6, local router ID is 10.1.0.32, vrf id 0 Default local pref 100, local AS 64601 Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, i internal, r RIB-failure, S Stale, R Removed Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path *> 10.1.0.32/32 0.0.0.0 0 32768 i Total number of prefixes 1 admin@str-s6100-acs-1:~$ vtysh -c 'show bgp ipv6 neighbors fc00::a advertised-routes' BGP table version is 6, local router ID is 10.1.0.32, vrf id 0 Default local pref 100, local AS 64601 Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, i internal, r RIB-failure, S Stale, R Removed Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path *> fc00:1::/64 :: 0 32768 i Total number of prefixes 1 admin@str-s6100-acs-1:~$ TSB System Mode: Maintenance -> Normal ``` Co-authored-by: Pavel Shirshov --- dockers/docker-fpm-frr/TSA | 7 ++++++- dockers/docker-fpm-frr/TSB | 9 +++++++++ .../docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 | 2 +- .../tests/data/sonic-cfggen/tsa/isolate.json | 3 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/dockers/docker-fpm-frr/TSA b/dockers/docker-fpm-frr/TSA index 441765694a4f..dc96d32c4582 100755 --- a/dockers/docker-fpm-frr/TSA +++ b/dockers/docker-fpm-frr/TSA @@ -24,12 +24,17 @@ then case "$route_map_name" in *V4*) ip_version=V4 + ip_protocol=ip ;; *V6*) ip_version=V6 + ip_protocol=ipv6 + ;; + *) + continue ;; esac - sonic-cfggen -d -a "{\"route_map_name\":\"$route_map_name\", \"ip_version\": \"$ip_version\"}" -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd/tsa/bgpd.tsa.isolate.conf.j2 > "$TSA_FILE" + sonic-cfggen -d -a "{\"route_map_name\":\"$route_map_name\", \"ip_version\": \"$ip_version\", \"ip_protocol\": \"$ip_protocol\"}" -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd/tsa/bgpd.tsa.isolate.conf.j2 > "$TSA_FILE" vtysh -f "$TSA_FILE" rm -f "$TSA_FILE" done diff --git a/dockers/docker-fpm-frr/TSB b/dockers/docker-fpm-frr/TSB index 84a3c183e659..68eee9c2faff 100755 --- a/dockers/docker-fpm-frr/TSB +++ b/dockers/docker-fpm-frr/TSB @@ -24,6 +24,15 @@ then TSB_FILE=$(mktemp) for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); do + case "$route_map_name" in + *V4*) + ;; + *V6*) + ;; + *) + continue + ;; + esac sonic-cfggen -d -a "{\"route_map_name\":\"$route_map_name\"}" -t /usr/share/sonic/templates/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 > "$TSB_FILE" vtysh -f "$TSB_FILE" rm -f "$TSB_FILE" diff --git a/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 index 88b1c5acb2eb..94287bdcd300 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 @@ -1,5 +1,5 @@ route-map {{ route_map_name }} permit 2 - match ip address prefix-list PL_Loopback{{ ip_version }} + match {{ ip_protocol }} address prefix-list PL_Loopback{{ ip_version }} set community {{ constants.bgp.traffic_shift_community }} route-map {{ route_map_name }} deny 3 ! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json index 708e4013f131..807dfe7e1a0c 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json @@ -5,5 +5,6 @@ } }, "route_map_name": "test_rm_name", - "ip_version": "V4" + "ip_version": "V4", + "ip_protocol": "ip" } \ No newline at end of file From e526d8895f5a7a09a76883791cc9ac091db453a4 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sun, 15 Nov 2020 02:37:38 -0800 Subject: [PATCH 1396/1427] [sonic-platform-common][sonic-platform-daemons] Update submodules (#5924) This should also fix the vsimage check build. Commits include: * src/sonic-platform-common a659219...e4883e5 (7): > [PsuBase] Reference inherited member constant (#142) > Thermalctld APIs for recording min and max temp (#131) > Common power consumption and supply APIs for modular chassis (#136) > [sonic-platform-base] Introduce APIs for modular chassis support (#124) > Remove shebangs from non-executable Python files (#140) > [sonic_eeprom] Make compatible with Python 2 and 3 (#127) > Add unit test infrastructure (#139) * src/sonic-platform-daemons 600d043...be21d91 (9): > [psud] Import of mock libraries determined by environment variable (#117) > [chassisd][thermalctld] Set testing env var at top of file, not in setup_function() (#114) > [chassisd][thermalctld] Import os module, now needed for env var checking (#113) > [chassisd][thermalctld] Import mock libraries based on environment variable (#112) > [xcvrd] Fix the console-script xcvrd startup (#111) > [Thermalctld] Update thermal info to CHASSIS_STATE_DB (#101) > PSUd changes to compute power-budget for Modular chassis (#104) > Introduce chassisd to monitor status of cards on chassis (#97) > [xcvrd] support for integrating Credo Y cable Ports initialization and status updates with xcvrd. (#105) --- src/sonic-platform-common | 2 +- src/sonic-platform-daemons | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index a6592194557b..e4883e5af27a 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit a6592194557bf1ec97dd77f8f90090642f505344 +Subproject commit e4883e5af27a6a5bb5f2ec000bdb97cf2e92a876 diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 600d043afc47..be21d911a300 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 600d043afc4756f5965479a333bfcf91c31d655d +Subproject commit be21d911a30086e2d0412dd3a0e18a4a5b5ec732 From 16774580f8b1c25e6e175b62be5107cfb2150b51 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Mon, 16 Nov 2020 17:57:19 +0800 Subject: [PATCH 1397/1427] [Mellanox] update hw-mgmt package to V.7.0010.1300 (#5902) pick up new functions and bug fixes: - New Features - Add dynamic minimum tables for MSN3700X, MSN3800, MSN3420, MSN4600, MSN4700 systems - Split hw-management to one-shot init hw-management service and thermal control services. - Bug fixes HW Mgmt core: - Move PSU EEPROM configuration from kernel to user space for Spectrum 2 / Spectrum 3 system --- platform/mellanox/hw-management.mk | 2 +- ...agement-thermal-control-shell-script.patch | 28 ------------------- platform/mellanox/hw-management/hw-mgmt | 2 +- 3 files changed, 2 insertions(+), 30 deletions(-) delete mode 100644 platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index eb90cf16d4f2..521daa1c7c3b 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0010.1000 +MLNX_HW_MANAGEMENT_VERSION = 7.0010.1300 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch b/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch deleted file mode 100644 index eef970ed23c7..000000000000 --- a/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 3bce9e33132a86c0a53a7b0a49ee1932d65bfb7f Mon Sep 17 00:00:00 2001 -From: junchao -Date: Wed, 6 May 2020 11:37:56 +0800 -Subject: [PATCH] Disable hw-management thermal control shell script - ---- - usr/usr/bin/hw-management.sh | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh -index 65e5d39..cffff7a 100755 ---- a/usr/usr/bin/hw-management.sh -+++ b/usr/usr/bin/hw-management.sh -@@ -832,7 +832,10 @@ do_start() - if [ -f $config_path/max_tachos ]; then - max_tachos=$(<$config_path/max_tachos) - fi -- $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& -+ -+ # Disable thermal control shell script in hw-management -+ # because there has already been that in SONiC -+ # $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& - } - - do_stop() --- -1.9.1 - diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index cdacf1e932f9..dec7935777b5 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit cdacf1e932f929c8dedde6c7e14759a2083aac66 +Subproject commit dec7935777b52d31a2220bad8b0cec4b71ec0961 From eeffbb24d9743b2b8922887f77736eef2de5b18e Mon Sep 17 00:00:00 2001 From: guxianghong Date: Mon, 16 Nov 2020 20:15:25 +0800 Subject: [PATCH 1398/1427] [CENTEC ARM64]LIBSAIREDIS isn't depend on CENTEC_SAI, Remove this dependency (#5834) * LIBSAIREDIS isn't depend on CENTEC_SAI remove this dependence * Build depends are optimized in PR #4880 and #5039. Merge these optimization to Centec ARM64 platform. --- platform/centec-arm64/docker-syncd-centec.mk | 3 +++ platform/centec-arm64/rules.mk | 9 +++++++-- platform/centec-arm64/sai.mk | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/platform/centec-arm64/docker-syncd-centec.mk b/platform/centec-arm64/docker-syncd-centec.mk index 9c3d1b1aff75..9943420660a4 100755 --- a/platform/centec-arm64/docker-syncd-centec.mk +++ b/platform/centec-arm64/docker-syncd-centec.mk @@ -10,6 +10,9 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_CENTEC)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf diff --git a/platform/centec-arm64/rules.mk b/platform/centec-arm64/rules.mk index a168692c8b15..79e1ab12b880 100755 --- a/platform/centec-arm64/rules.mk +++ b/platform/centec-arm64/rules.mk @@ -11,8 +11,13 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) # $(DOCKER_SYNCD_CENTEC_RPC) -# Inject centec sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(CENTEC_SAI) $(LIBSAITHRIFT_DEV_CENTEC) +# Inject centec sai into syncd +$(SYNCD)_DEPENDS += $(CENTEC_SAI) +$(SYNCD)_UNINSTALLS += $(CENTEC_SAI) + +ifeq ($(ENABLE_SYNCD_RPC),y) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) +endif # Runtime dependency on centec sai is set only for syncd $(SYNCD)_RDEPENDS += $(CENTEC_SAI) diff --git a/platform/centec-arm64/sai.mk b/platform/centec-arm64/sai.mk index 7d9c997efa9e..2b902b49403a 100755 --- a/platform/centec-arm64/sai.mk +++ b/platform/centec-arm64/sai.mk @@ -4,5 +4,6 @@ export CENTEC_SAI_VERSION = 1.6.3-1 export CENTEC_SAI = libsai_$(CENTEC_SAI_VERSION)_$(PLATFORM_ARCH).deb $(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/$(PLATFORM_ARCH)/sai/$(CENTEC_SAI) +$(eval $(call add_conflict_package,$(CENTEC_SAI),$(LIBSAIVS_DEV))) SONIC_ONLINE_DEBS += $(CENTEC_SAI) From 67dbbb33bf2dd0b629fd50d7eec60d463f1251cb Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 16 Nov 2020 08:50:41 -0800 Subject: [PATCH 1399/1427] [build] SONiC platform daemons depend on swsscommon library (#5922) Add dependencies in appropriate makefiles to ensure proper build/installation of SONiC platform daemons (ledd, psud, syseepromd, thermalctld, xcvrd). --- rules/sonic-ledd.mk | 1 + rules/sonic-psud.mk | 1 + rules/sonic-syseepromd.mk | 1 + rules/sonic-thermalctld.mk | 1 + rules/sonic-xcvrd.mk | 1 + 5 files changed, 5 insertions(+) diff --git a/rules/sonic-ledd.mk b/rules/sonic-ledd.mk index 930e8436ecaf..99d6f3e3209c 100644 --- a/rules/sonic-ledd.mk +++ b/rules/sonic-ledd.mk @@ -3,5 +3,6 @@ SONIC_LEDD = sonic_ledd-1.1-py2-none-any.whl $(SONIC_LEDD)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-ledd $(SONIC_LEDD)_DEPENDS = $(SONIC_PY_COMMON_PY2) +$(SONIC_LEDD)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(PYTHON3_SWSSCOMMON) $(SONIC_LEDD)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_LEDD) diff --git a/rules/sonic-psud.mk b/rules/sonic-psud.mk index 7f4596505e12..7cdbf50c0ecb 100644 --- a/rules/sonic-psud.mk +++ b/rules/sonic-psud.mk @@ -3,5 +3,6 @@ SONIC_PSUD = sonic_psud-1.0-py2-none-any.whl $(SONIC_PSUD)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-psud $(SONIC_PSUD)_DEPENDS = $(SONIC_PY_COMMON_PY2) +$(SONIC_PSUD)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(PYTHON3_SWSSCOMMON) $(SONIC_PSUD)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_PSUD) diff --git a/rules/sonic-syseepromd.mk b/rules/sonic-syseepromd.mk index 1fba4027a2d4..6038aa73abcb 100644 --- a/rules/sonic-syseepromd.mk +++ b/rules/sonic-syseepromd.mk @@ -3,5 +3,6 @@ SONIC_SYSEEPROMD = sonic_syseepromd-1.0-py2-none-any.whl $(SONIC_SYSEEPROMD)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-syseepromd $(SONIC_SYSEEPROMD)_DEPENDS = $(SONIC_PY_COMMON_PY2) +$(SONIC_SYSEEPROMD)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(PYTHON3_SWSSCOMMON) $(SONIC_SYSEEPROMD)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_SYSEEPROMD) diff --git a/rules/sonic-thermalctld.mk b/rules/sonic-thermalctld.mk index b2cf134642d6..900d3a49e7de 100644 --- a/rules/sonic-thermalctld.mk +++ b/rules/sonic-thermalctld.mk @@ -3,5 +3,6 @@ SONIC_THERMALCTLD = sonic_thermalctld-1.0-py2-none-any.whl $(SONIC_THERMALCTLD)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-thermalctld $(SONIC_THERMALCTLD)_DEPENDS = $(SONIC_PY_COMMON_PY2) +$(SONIC_THERMALCTLD)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(PYTHON3_SWSSCOMMON) $(SONIC_THERMALCTLD)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_THERMALCTLD) diff --git a/rules/sonic-xcvrd.mk b/rules/sonic-xcvrd.mk index 8af04a2c07b6..a3dd8ae3e7ff 100644 --- a/rules/sonic-xcvrd.mk +++ b/rules/sonic-xcvrd.mk @@ -3,5 +3,6 @@ SONIC_XCVRD = sonic_xcvrd-1.0-py2-none-any.whl $(SONIC_XCVRD)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-xcvrd $(SONIC_XCVRD)_DEPENDS = $(SONIC_PY_COMMON_PY2) +$(SONIC_XCVRD)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(PYTHON3_SWSSCOMMON) $(SONIC_XCVRD)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_XCVRD) From 261a81d37929bf8c658417c7a602b0e7e3ae10e5 Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Mon, 16 Nov 2020 13:14:34 -0800 Subject: [PATCH 1400/1427] [minigraph.py]: Parse mux cable table (#5876) Parse device IPv6 loopback addresses when available Add MUX_CABLE table to config DB: 'MUX_CABLE': { 'Ethernet4': { 'state': 'auto', 'server_ipv4': '10.10.10.1/32', 'server_ipv6': 'fe80::0001/128' } } --- src/sonic-config-engine/minigraph.py | 33 +++++++-- .../tests/simple-sample-graph-case.xml | 46 +++++++++++++ src/sonic-config-engine/tests/test_cfggen.py | 2 +- .../tests/test_minigraph_case.py | 69 +++++++++++++++---- .../tests/test_multinpu_cfggen.py | 8 +-- 5 files changed, 134 insertions(+), 24 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index ed90a8849362..b18261a8fc9a 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -79,6 +79,7 @@ def get_peer_switch_info(link_metadata, devices): def parse_device(device): lo_prefix = None + lo_prefix_v6 = None mgmt_prefix = None d_type = None # don't shadow type() hwsku = None @@ -90,6 +91,8 @@ def parse_device(device): for node in device: if node.tag == str(QName(ns, "Address")): lo_prefix = node.find(str(QName(ns2, "IPPrefix"))).text + elif node.tag == str(QName(ns, "AddressV6")): + lo_prefix_v6 = node.find(str(QName(ns2, "IPPrefix"))).text elif node.tag == str(QName(ns, "ManagementAddress")): mgmt_prefix = node.find(str(QName(ns2, "IPPrefix"))).text elif node.tag == str(QName(ns, "Hostname")): @@ -98,7 +101,7 @@ def parse_device(device): hwsku = node.text elif node.tag == str(QName(ns, "DeploymentId")): deployment_id = node.text - return (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) + return (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id) def parse_png(png, hname): neighbors = {} @@ -160,10 +163,12 @@ def parse_png(png, hname): if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): - (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) + (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } if deployment_id: device_data['deployment_id'] = deployment_id + if lo_prefix_v6: + device_data['lo_addr_v6'] = lo_prefix_v6 devices[name] = device_data if name == hname: @@ -281,10 +286,12 @@ def parse_asic_png(png, asic_name, hostname): if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): - (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) + (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } if deployment_id: device_data['deployment_id'] = deployment_id + if lo_prefix_v6: + device_data['lo_addr_v6']= lo_prefix_v6 devices[name] = device_data return (neighbors, devices, port_speeds) @@ -1234,6 +1241,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw results['TUNNEL'] = get_tunnel_entries(tunnel_intfs, lo_intfs, hostname) + results['MUX_CABLE'] = get_mux_cable_entries(mux_cable_ports, neighbors, devices) + for nghbr in list(neighbors.keys()): # remove port not in port_config.ini if nghbr not in ports: @@ -1317,10 +1326,24 @@ def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname): tunnels[tunnel_key] = tunnel_attr return tunnels +def get_mux_cable_entries(mux_cable_ports, neighbors, devices): + mux_cable_table = {} + + for intf in mux_cable_ports: + if intf in neighbors: + entry = {} + neighbor = neighbors[intf]['name'] + entry['state'] = 'auto' + entry['server_ipv4'] = devices[neighbor]['lo_addr'] + if 'lo_addr_v6' in devices[neighbor]: + entry['server_ipv6'] = devices[neighbor]['lo_addr_v6'] + mux_cable_table[intf] = entry + + return mux_cable_table def parse_device_desc_xml(filename): root = ET.parse(filename).getroot() - (lo_prefix, mgmt_prefix, hostname, hwsku, d_type, _) = parse_device(root) + (lo_prefix, lo_prefix_v6, mgmt_prefix, hostname, hwsku, d_type, _) = parse_device(root) results = {} results['DEVICE_METADATA'] = {'localhost': { @@ -1329,6 +1352,8 @@ def parse_device_desc_xml(filename): }} results['LOOPBACK_INTERFACE'] = {('lo', lo_prefix): {}} + if lo_prefix_v6: + results['LOOPBACK_INTERFACE'] = {('lo_v6', lo_prefix_v6): {}} mgmt_intf = {} mgmtipn = ipaddress.ip_network(UNICODE_TYPE(mgmt_prefix), False) diff --git a/src/sonic-config-engine/tests/simple-sample-graph-case.xml b/src/sonic-config-engine/tests/simple-sample-graph-case.xml index c70a1561b69a..84a405f5edf8 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-case.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-case.xml @@ -213,6 +213,24 @@ switch-02t1 port1 + + DeviceInterfaceLink + true + 25000 + switch-t0 + fortyGigE0/4 + server1 + port1 + + + DeviceInterfaceLink + true + 40000 + switch-t0 + fortyGigE0/8 + server2 + port1 + LogicalLink 10000 @@ -278,6 +296,34 @@ Force10-S6000 + + Server +
+ 10.10.10.1/32 +
+ + fe80::0001/128 + + + 10.0.0.1/32 + + server1 + server-sku +
+ + Server +
+ 10.10.10.2/32 +
+ + fe80::0002/128 + + + 10.0.0.2/32 + + server2 + server-sku +
diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 0d2f94899ede..30d205797642 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -348,7 +348,7 @@ def test_minigraph_neighbor_interfaces(self): utils.to_dict( "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '40000', 'mux_cable': 'true'}, " "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'switch-01t1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " - "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000', 'mux_cable': 'true'}, " + "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'server1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000', 'mux_cable': 'true'}, " "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 019c791a1899..586ded0ebec9 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -123,24 +123,41 @@ def test_minigraph_deployment_id(self): def test_minigraph_neighbor_metadata(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR_METADATA"' + + expected_table = { + 'switch-01t1': { + 'lo_addr': '10.1.0.186/32', + 'mgmt_addr': '10.7.0.196/26', + 'hwsku': 'Force10-S6000', + 'type': 'LeafRouter', + 'deployment_id': '2' + }, + 'switch2-t0': { + 'hwsku': 'Force10-S6000', + 'lo_addr': '25.1.1.10', + 'mgmt_addr': '10.7.0.196/26', + 'type': 'ToRRouter' + }, + 'server1': { + 'hwsku': 'server-sku', + 'lo_addr': '10.10.10.1/32', + 'lo_addr_v6': 'fe80::0001/128', + 'mgmt_addr': '10.0.0.1/32', + 'type': 'Server' + }, + 'server2': { + 'hwsku': 'server-sku', + 'lo_addr': '10.10.10.2/32', + 'lo_addr_v6': 'fe80::0002/128', + 'mgmt_addr': '10.0.0.2/32', + 'type': 'Server' + } + } output = self.run_script(argument) + self.maxDiff = None self.assertEqual( utils.to_dict(output.strip()), - utils.to_dict("{" \ - "'switch-01t1': {" \ - "'lo_addr': '10.1.0.186/32'," \ - "'mgmt_addr': '10.7.0.196/26'," \ - "'hwsku': 'Force10-S6000'," \ - "'type': 'LeafRouter'," \ - "'deployment_id': '2'" \ - "}," \ - "'switch2-t0': {" \ - "'hwsku': 'Force10-S6000'," \ - "'lo_addr': '25.1.1.10'," \ - "'mgmt_addr': '10.7.0.196/26'," \ - "'type': 'ToRRouter'" \ - "}" \ - "}") + expected_table ) # everflow portion is not used @@ -227,3 +244,25 @@ def test_minigraph_tunnel_table(self): utils.to_dict(output.strip()), expected_tunnel ) + + def test_minigraph_mux_cable_table(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "MUX_CABLE"' + expected_table = { + 'Ethernet4': { + 'state': 'auto', + 'server_ipv4': '10.10.10.1/32', + 'server_ipv6': 'fe80::0001/128' + }, + 'Ethernet8': { + 'state': 'auto', + 'server_ipv4': '10.10.10.2/32', + 'server_ipv6': 'fe80::0002/128' + } + } + + output = self.run_script(argument) + self.assertEqual( + utils.to_dict(output.strip()), + expected_table + ) + \ No newline at end of file diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 7ed64775111f..83955925c9e5 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -202,8 +202,8 @@ def test_frontend_asic_device_neigh_metadata(self): output = json.loads(self.run_script(argument)) self.assertDictEqual(output, \ {'01T2': {'lo_addr': None, 'mgmt_addr': '89.139.132.40', 'hwsku': 'VM', 'type': 'SpineRouter'}, - 'ASIC3': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, - 'ASIC2': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) + 'ASIC3': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, + 'ASIC2': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) def test_backend_asic_device_neigh(self): argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) @@ -218,8 +218,8 @@ def test_backend_device_neigh_metadata(self): argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR_METADATA\"".format(self.sample_graph, self.port_config[3]) output = json.loads(self.run_script(argument)) self.assertDictEqual(output, \ - {'ASIC1': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, - 'ASIC0': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) + {'ASIC1': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, + 'ASIC0': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) def test_frontend_bgp_neighbor(self): argument = "-m {} -p {} -n asic0 --var-json \"BGP_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) From ced11615a44d0464ecf512974846967a059f991d Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 16 Nov 2020 17:07:37 -0800 Subject: [PATCH 1401/1427] [sonic-py-common] Add 'universal_newlines=True' arg to all Popen calls (#5919) The behavior of `subprocess.Popen()` changed in Python 3 such that stdin, stdout and stderr are treated as bytes by default. Adding the `universal_newlines=True` argument changes this behavior to return strings, matching the behavior of Python 2. The change is backward-compatible with Python 2, as well. --- src/sonic-py-common/sonic_py_common/device_info.py | 5 +++-- src/sonic-py-common/sonic_py_common/multi_asic.py | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index ef4b5453b40b..5f1cb6a66d43 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -407,7 +407,7 @@ def get_system_mac(namespace=None): hw_mac_entry_cmds = [mac_address_cmd] for get_mac_cmd in hw_mac_entry_cmds: - proc = subprocess.Popen(get_mac_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc = subprocess.Popen(get_mac_cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (mac, err) = proc.communicate() if err: continue @@ -439,6 +439,7 @@ def get_system_routing_stack(): proc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True, + universal_newlines=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] proc.wait() @@ -473,7 +474,7 @@ def is_warm_restart_enabled(container_name): def is_fast_reboot_enabled(): fb_system_state = 0 cmd = 'sonic-db-cli STATE_DB get "FAST_REBOOT|system"' - proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) + proc = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE) (stdout, stderr) = proc.communicate() if proc.returncode != 0: diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index f844b12287c5..21c74f29293d 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -149,6 +149,7 @@ def get_current_namespace(): proc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True, + universal_newlines=True, stderr=subprocess.STDOUT) try: stdout, stderr = proc.communicate() From b595a6eadfbb15949890c2490a17cfdc0d7cdf60 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Tue, 17 Nov 2020 10:56:03 +0800 Subject: [PATCH 1402/1427] [Mellanox] Implement new platform API for SONiC physical entity mib extension (#5645) In order to support SONiC physical entity mib extension, a few new platform API are added to sonic-platform-common, this PR is to provide an mellanox platform implementation for those new APIs. --- .../sonic_platform/chassis.py | 28 +++++++-- .../mlnx-platform-api/sonic_platform/fan.py | 28 ++++++--- .../sonic_platform/fan_drawer.py | 16 +++++ .../mlnx-platform-api/sonic_platform/psu.py | 22 ++++++- .../mlnx-platform-api/sonic_platform/sfp.py | 16 ++++- .../sonic_platform/thermal.py | 63 +++++++++++++------ .../mlnx-platform-api/tests/test_fan_api.py | 6 +- 7 files changed, 144 insertions(+), 35 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 1682d4649d3f..77cf27da2d6e 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -104,7 +104,7 @@ def initialize_fan(self): drawer = drawer_ctor(drawer_index, fan_data) self._fan_drawer_list.append(drawer) for index in range(fan_num_per_drawer): - fan = Fan(fan_index, drawer) + fan = Fan(fan_index, drawer, index + 1) fan_index += 1 drawer._fan_list.append(fan) self._fan_list.append(fan) @@ -130,18 +130,19 @@ def initialize_sfp(self): for index in range(self.PORT_START, self.PORT_END + 1): if index in range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1): - sfp_module = SFP(index, 'QSFP', self.sdk_handle) + sfp_module = SFP(index, 'QSFP', self.sdk_handle, self.platform_name) else: - sfp_module = SFP(index, 'SFP', self.sdk_handle) + sfp_module = SFP(index, 'SFP', self.sdk_handle, self.platform_name) + self._sfp_list.append(sfp_module) self.sfp_module_initialized = True def initialize_thermals(self): - from sonic_platform.thermal import initialize_thermals + from sonic_platform.thermal import initialize_chassis_thermals # Initialize thermals - initialize_thermals(self.platform_name, self._thermal_list, self._psu_list) + initialize_chassis_thermals(self.platform_name, self._thermal_list) def initialize_eeprom(self): @@ -514,3 +515,20 @@ def get_status_led(self): specified. """ return None if not Chassis._led else Chassis._led.get_status() + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position + for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py index 3b5be3a25db3..78e79ca5133b 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py @@ -37,14 +37,16 @@ class Fan(FanBase): PSU_FAN_SPEED = ['0x3c', '0x3c', '0x3c', '0x3c', '0x3c', '0x3c', '0x3c', '0x46', '0x50', '0x5a', '0x64'] - def __init__(self, fan_index, fan_drawer, psu_fan = False): + def __init__(self, fan_index, fan_drawer, position, psu_fan = False, psu=None): super(Fan, self).__init__() # API index is starting from 0, Mellanox platform index is starting from 1 self.index = fan_index + 1 self.fan_drawer = fan_drawer + self.position = position self.is_psu_fan = psu_fan + self.psu = psu if self.fan_drawer: self.led = ComponentFaultyIndicator(self.fan_drawer.get_led()) elif self.is_psu_fan: @@ -123,13 +125,8 @@ def get_presence(self): Returns: bool: True if fan is present, False if not """ - status = 0 if self.is_psu_fan: - if os.path.exists(os.path.join(FAN_PATH, self.fan_presence_path)): - status = 1 - else: - status = 0 - return status == 1 + return self.psu.get_presence() and self.psu.get_powergood_status() and os.path.exists(os.path.join(FAN_PATH, self.fan_presence_path)) else: return self.fan_drawer.get_presence() @@ -254,6 +251,22 @@ def get_speed_tolerance(self): # The tolerance value is fixed as 50% for all the Mellanox platform return 50 + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.position + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + @classmethod def set_cooling_level(cls, level, cur_state): """ @@ -288,3 +301,4 @@ def get_cooling_level(cls): except (ValueError, IOError) as e: raise RuntimeError("Failed to get cooling level - {}".format(e)) + \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py index bed6c7ab042a..66ee39491735 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py @@ -84,6 +84,22 @@ def get_status_led(self): """ return self._led.get_status() + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self._index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return self._fan_data['hot_swappable'] + class RealDrawer(MellanoxFanDrawer): def __init__(self, index, fan_data): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index d26df89f04ce..897555ed8020 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -103,7 +103,7 @@ def __init__(self, psu_index, platform): # unplugable PSU has no FAN if self.psu_data['hot_swappable']: - fan = Fan(psu_index, None, True) + fan = Fan(psu_index, None, 1, True, self) self._fan_list.append(fan) if self.psu_data['led_num'] == 1: @@ -111,6 +111,10 @@ def __init__(self, psu_index, platform): else: # 2010/2100 self.led = PsuLed(self.index) + # initialize thermal for PSU + from .thermal import initialize_psu_thermals + initialize_psu_thermals(platform, self._thermal_list, self.index, self.get_power_available_status) + def get_name(self): return self._name @@ -244,6 +248,22 @@ def get_power_available_status(self): else: return True, "" + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return self.psu_data['hot_swappable'] + @classmethod def get_shared_led(cls): if not cls.shared_led: diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 89b4b520a48e..611758daa862 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -309,7 +309,8 @@ def deinitialize_sdk_handle(sdk_handle): class SFP(SfpBase): """Platform-specific SFP class""" - def __init__(self, sfp_index, sfp_type, sdk_handle): + def __init__(self, sfp_index, sfp_type, sdk_handle, platform): + SfpBase.__init__(self) self.index = sfp_index + 1 self.sfp_eeprom_path = "qsfp{}".format(self.index) self.sfp_status_path = "qsfp{}_status".format(self.index) @@ -319,7 +320,12 @@ def __init__(self, sfp_index, sfp_type, sdk_handle): self.sdk_handle = sdk_handle self.sdk_index = sfp_index + # initialize SFP thermal list + from .thermal import initialize_sfp_thermals + initialize_sfp_thermals(platform, self._thermal_list, self.index) + def reinit(self): + """ Re-initialize this SFP object when a new SFP inserted :return: @@ -2034,3 +2040,11 @@ def set_power_override(self, power_override, power_set): False if not """ return NotImplementedError + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 4ebe28252481..48b277345b3a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -113,12 +113,10 @@ } thermal_device_categories_all = [ - THERMAL_DEV_CATEGORY_CPU_CORE, - THERMAL_DEV_CATEGORY_CPU_PACK, - THERMAL_DEV_CATEGORY_MODULE, - THERMAL_DEV_CATEGORY_PSU, THERMAL_DEV_CATEGORY_AMBIENT, - THERMAL_DEV_CATEGORY_GEARBOX + THERMAL_DEV_CATEGORY_CPU_PACK, + THERMAL_DEV_CATEGORY_CPU_CORE, + THERMAL_DEV_CATEGORY_GEARBOX, ] thermal_device_categories_singleton = [ @@ -305,18 +303,34 @@ } ] +def initialize_psu_thermals(platform, thermal_list, psu_index, dependency): + tp_index = platform_dict_thermal[platform] + thermal_profile = thermal_profile_list[tp_index] + _, count = thermal_profile[THERMAL_DEV_CATEGORY_PSU] + if count == 0: + return + thermal = Thermal(THERMAL_DEV_CATEGORY_PSU, psu_index, True, 1, dependency) + thermal_list.append(thermal) + -def initialize_thermals(platform, thermal_list, psu_list): +def initialize_sfp_thermals(platform, thermal_list, sfp_index): + thermal = Thermal(THERMAL_DEV_CATEGORY_MODULE, sfp_index, True, 1) + thermal_list.append(thermal) + + +def initialize_chassis_thermals(platform, thermal_list): # create thermal objects for all categories of sensors tp_index = platform_dict_thermal[platform] thermal_profile = thermal_profile_list[tp_index] Thermal.thermal_profile = thermal_profile + position = 1 for category in thermal_device_categories_all: if category == THERMAL_DEV_CATEGORY_AMBIENT: count, ambient_list = thermal_profile[category] for ambient in ambient_list: - thermal = Thermal(category, ambient, True) - thermal_list.append(thermal) + thermal = Thermal(category, ambient, True, position) + thermal_list.append(thermal), + position += 1 else: start, count = 0, 0 if category in thermal_profile: @@ -324,17 +338,14 @@ def initialize_thermals(platform, thermal_list, psu_list): if count == 0: continue if count == 1: - thermal = Thermal(category, 0, False) + thermal = Thermal(category, 0, False, position) thermal_list.append(thermal) + position += 1 else: - if category == THERMAL_DEV_CATEGORY_PSU: - for index in range(count): - thermal = Thermal(category, start + index, True, psu_list[index].get_power_available_status) - thermal_list.append(thermal) - else: - for index in range(count): - thermal = Thermal(category, start + index, True) - thermal_list.append(thermal) + for index in range(count): + thermal = Thermal(category, start + index, True, position) + thermal_list.append(thermal) + position += 1 @@ -342,7 +353,7 @@ class Thermal(ThermalBase): thermal_profile = None thermal_algorithm_status = False - def __init__(self, category, index, has_index, dependency = None): + def __init__(self, category, index, has_index, position, dependency = None): """ index should be a string for category ambient and int for other categories """ @@ -357,6 +368,7 @@ def __init__(self, category, index, has_index, dependency = None): self.index = 0 self.category = category + self.position = position self.temperature = self._get_file_from_api(THERMAL_API_GET_TEMPERATURE) self.high_threshold = self._get_file_from_api(THERMAL_API_GET_HIGH_THRESHOLD) self.high_critical_threshold = self._get_file_from_api(THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD) @@ -480,6 +492,21 @@ def get_high_critical_threshold(self): return None return value_float / 1000.0 + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.position + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False @classmethod def _write_generic_file(cls, filename, content): diff --git a/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py b/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py index 24158997abf7..bb9ee7e125a2 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py @@ -16,7 +16,7 @@ def test_get_absence_fan_direction(): fan_drawer = RealDrawer(0, DEVICE_DATA['x86_64-mlnx_msn2700-r0']['fans']) - fan = Fan(0, fan_drawer) + fan = Fan(0, fan_drawer, 1) fan_drawer.get_presence = MagicMock(return_value=False) assert not fan.is_psu_fan @@ -31,8 +31,8 @@ def test_fan_drawer_set_status_led(): with pytest.raises(Exception): fan_drawer.set_status_led(None, Fan.STATUS_LED_COLOR_RED) - fan1 = Fan(0, fan_drawer) - fan2 = Fan(1, fan_drawer) + fan1 = Fan(0, fan_drawer, 1) + fan2 = Fan(1, fan_drawer, 2) fan_list = fan_drawer.get_all_fans() fan_list.append(fan1) fan_list.append(fan2) From 1ba583cb46bffe2df388e0a4bbe1cf631b5bfdab Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Tue, 17 Nov 2020 19:01:39 -0800 Subject: [PATCH 1403/1427] [TD3] add dummy MMU configuration for Arista-7050CX3-32S-D48C8 (#5950) Need A mmu configuration to get the device going without generating lots of warnings. Similar to dummy MMU configuration for Arista-7050CX3-32S-C32, this configuration will need to be updated with correct numbers. This MMU configuration is copied from 7060 comparable hwsku. Signed-off-by: Ying Xie --- .../pg_profile_lookup.ini | 17 ++++++ .../Arista-7050CX3-32S-D48C8/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 61 +++++++++++++++++++ .../pg_profile_lookup.ini | 17 ++++++ .../Arista-7050CX3-32S-D48C8/qos.json.j2 | 21 +++++++ .../buffers_defaults_t0.j2 | 4 +- .../buffers_defaults_t0.j2 | 17 +----- 7 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/pg_profile_lookup.ini create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/buffers.json.j2 create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/buffers_defaults_t0.j2 create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/pg_profile_lookup.ini create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/qos.json.j2 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/pg_profile_lookup.ini b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/pg_profile_lookup.ini new file mode 100644 index 000000000000..0b5d680edda7 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 79872 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 56160 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 85696 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/buffers.json.j2 b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/buffers.json.j2 new file mode 100644 index 000000000000..1083a6210fc9 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..1430479d08e0 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/buffers_defaults_t0.j2 @@ -0,0 +1,61 @@ +{%- set default_cable = '5m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,6) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(10,22) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(26,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(6,10) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(22,26) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10875072", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "9243812", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"15982720" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/pg_profile_lookup.ini b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/pg_profile_lookup.ini new file mode 100644 index 000000000000..0b5d680edda7 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 79872 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 56160 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 85696 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/qos.json.j2 b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/qos.json.j2 new file mode 100644 index 000000000000..34002048afdb --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/qos.json.j2 @@ -0,0 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + +{%- include 'qos_config.j2' %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 index 5add8968e621..1430479d08e0 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 @@ -10,14 +10,14 @@ {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} {%- endfor %} - {%- for port_idx in range(24,32) %} + {%- for port_idx in range(26,32) %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} {%- endfor %} {%- for port_idx in range(6,10) %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} {%- endfor %} - {%- for port_idx in range(22,24) %} + {%- for port_idx in range(22,26) %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} {%- endfor %} {%- endmacro %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 index c0fa1ff0864e..4858c7a67e65 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 @@ -2,22 +2,7 @@ {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} - {%- for port_idx in range(0,6) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(10,22) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(24,32) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(6,10) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(22,24) %} + {%- for port_idx in range(0,32) %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} {%- endfor %} {%- endmacro %} From 6c4092d0a28d738ac461ee85b00414cae690e331 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 18 Nov 2020 01:37:05 -0800 Subject: [PATCH 1404/1427] [sonic-platform-common] Update submodule (#5953) Commits include: * src/sonic-platform-common e4883e5...5db8c84 (1): > [sonic-platform-common] Fix name error and import error (#143) --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index e4883e5af27a..5db8c84df818 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit e4883e5af27a6a5bb5f2ec000bdb97cf2e92a876 +Subproject commit 5db8c84df8183282ce216c36d8fddb783f704c44 From 2fe79c2c61f77adae8186cb2046ec7e1d067b4ef Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Wed, 18 Nov 2020 01:59:55 -0800 Subject: [PATCH 1405/1427] =?UTF-8?q?[yang=5Fmodels]:=20yang=20models=20fo?= =?UTF-8?q?r=20device=5Fmetadata,=20device=5Fneighbor,=20flex=E2=80=A6=20(?= =?UTF-8?q?#4442)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: 1.) yang models for device_metadata, device_neighbor, flex_counters, crm, versions. 2.) Test cases for above yang models. Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com: --- src/sonic-yang-mgmt/sonic_yang_ext.py | 3 +- .../libyang-python-tests/test_sonic_yang.py | 9 +- src/sonic-yang-models/setup.py | 10 +- .../tests/yang_model_tests/test_yang_model.py | 63 +++- .../tests/yang_model_tests/yangTest.json | 234 +++++++++++++- .../yang-models/sonic-acl.yang | 4 - .../yang-models/sonic-breakout_cfg.yang | 64 ++++ .../yang-models/sonic-crm.yang | 303 ++++++++++++++++++ .../yang-models/sonic-device_metadata.yang | 99 ++++++ .../yang-models/sonic-device_neighbor.yang | 82 +++++ .../yang-models/sonic-flex_counter.yang | 112 +++++++ .../yang-models/sonic-interface.yang | 8 - .../yang-models/sonic-loopback-interface.yang | 4 - .../yang-models/sonic-port.yang | 8 - .../yang-models/sonic-portchannel.yang | 8 - .../yang-models/sonic-types.yang | 18 ++ .../yang-models/sonic-versions.yang | 36 +++ .../yang-models/sonic-vlan.yang | 4 - 18 files changed, 1019 insertions(+), 50 deletions(-) create mode 100644 src/sonic-yang-models/yang-models/sonic-breakout_cfg.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-crm.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-device_metadata.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-device_neighbor.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-flex_counter.yang create mode 100644 src/sonic-yang-models/yang-models/sonic-versions.yang diff --git a/src/sonic-yang-mgmt/sonic_yang_ext.py b/src/sonic-yang-mgmt/sonic_yang_ext.py index 1f0a072be450..e85cdb42ff0f 100644 --- a/src/sonic-yang-mgmt/sonic_yang_ext.py +++ b/src/sonic-yang-mgmt/sonic_yang_ext.py @@ -377,7 +377,8 @@ def _xlateContainer(self, model, yang, config, table): ## Handle other leaves in container, leafDict = self._createLeafDict(model) - for vKey in configC.keys(): + vKeys = list(configC.keys()) + for vKey in vKeys: #vkey must be a leaf\leaf-list\choice in container if leafDict.get(vKey): self.sysLog(syslog.LOG_DEBUG, "xlateContainer vkey {}".format(vKey)) diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py index 597d13da0874..b761cd994c1d 100644 --- a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py @@ -288,10 +288,13 @@ def test_xlate_rev_xlate(self, sonic_yang_data): syc = sonic_yang_data['syc'] jIn = self.readIjsonInput(test_file, 'SAMPLE_CONFIG_DB_JSON') + jIn = json.loads(jIn) + numTables = len(jIn) - syc.loadData(json.loads(jIn)) - - # TODO: Make sure no extra table is loaded + syc.loadData(jIn) + # check all tables are loaded and no tables is without Yang Models + assert len(syc.jIn) == numTables + assert len(syc.tablesWithOutYang) == 0 syc.getData() diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 4ba9fd61c92a..e651bb0d377d 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -41,13 +41,19 @@ packages=find_packages(), version='1.0', data_files=[ - ('yang-models', ['./yang-models/sonic-types.yang', + ('yang-models', ['./yang-models/sonic-acl.yang', + './yang-models/sonic-breakout_cfg.yang', + './yang-models/sonic-crm.yang', + './yang-models/sonic-device_metadata.yang', + './yang-models/sonic-device_neighbor.yang', './yang-models/sonic-extension.yang', - './yang-models/sonic-acl.yang', + './yang-models/sonic-flex_counter.yang', './yang-models/sonic-interface.yang', './yang-models/sonic-loopback-interface.yang', './yang-models/sonic-port.yang', './yang-models/sonic-portchannel.yang', + './yang-models/sonic-types.yang', + './yang-models/sonic-versions.yang', './yang-models/sonic-vlan.yang', './yang-models/sonic_yang_tree']), ], diff --git a/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py index 966af237f272..3bc2886f38c7 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py +++ b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py @@ -125,6 +125,10 @@ def initTest(self): 'desc': 'Loopback Ip-prefix port-name must condition failure.', 'eStr': self.defaultYANGFailure['Must'] }, + 'CRM_BRK_CFG_FLEX_TABLE': { + 'desc': 'CRM BREAKOUT CFG FLEX COUNTER TABLE.', + 'eStr': self.defaultYANGFailure['None'] + }, 'INCORRECT_VLAN_NAME': { 'desc': 'INCORRECT VLAN_NAME FIELD IN VLAN TABLE.', 'eStr': self.defaultYANGFailure['Pattern'] + ["Vlan"] @@ -168,6 +172,52 @@ def initTest(self): 'PORT_NEG_TEST': { 'desc': 'LOAD PORT TABLE FEC PATTERN FAILURE', 'eStr': self.defaultYANGFailure['Pattern'] + ['rc'] + }, + 'CRM_WITH_WRONG_PERCENTAGE': { + 'desc': 'CRM_WITH_WRONG_PERCENTAGE must condition failure.', + 'eStr': self.defaultYANGFailure['Must'] + }, + 'CRM_WITH_HIGH_THRESHOLD_ERR': { + 'desc': 'CRM_WITH_HIGH_THRESHOLD_ERR must condition failure \ + about high threshold being lower than low threshold.', + 'eStr': self.defaultYANGFailure['high_threshold should be more \ + than low_threshold'] + }, + 'CRM_WITH_CORRECT_USED_VALUE': { + 'desc': 'CRM_WITH_CORRECT_USED_VALUE no failure.', + 'eStr': self.defaultYANGFailure['None'] + }, + 'FLEX_COUNTER_TABLE_WITH_CORRECT_USED_VALUE': { + 'desc': 'FLEX_COUNTER_TABLE_WITH_CORRECT_USED_VALUE no failure.', + 'eStr': self.defaultYANGFailure['None'] + }, + 'VERSIONS_WITH_INCORRECT_PATTERN': { + 'desc': 'VERSIONS_WITH_INCORRECT_PATTERN pattern failure.', + 'eStr': self.defaultYANGFailure['Pattern'] + }, + 'VERSIONS_WITH_INCORRECT_PATTERN2': { + 'desc': 'VERSIONS_WITH_INCORRECT_PATTERN pattern failure.', + 'eStr': self.defaultYANGFailure['Pattern'] + }, + 'DEVICE_METADATA_DEFAULT_BGP_STATUS': { + 'desc': 'DEVICE_METADATA DEFAULT VALUE FOR BGP_STATUS FIELD.', + 'eStr': self.defaultYANGFailure['Verify'], + 'verify': {'xpath': '/sonic-device_metadata:sonic-device_metadata/DEVICE_METADATA/localhost/hostname', + 'key': 'sonic-device_metadata:default_bgp_status', + 'value': 'up' + } + }, + 'DEVICE_METADATA_DEFAULT_PFCWD_STATUS': { + 'desc': 'DEVICE_METADATA DEFAULT VALUE FOR PFCWD FIELD.', + 'eStr': self.defaultYANGFailure['Verify'], + 'verify': {'xpath': '/sonic-device_metadata:sonic-device_metadata/DEVICE_METADATA/localhost/hostname', + 'key': 'sonic-device_metadata:default_pfcwd_status', + 'value': 'disable' + } + }, + 'DEVICE_METADATA_TYPE_INCORRECT_PATTERN': { + 'desc': 'DEVICE_METADATA_TYPE_INCORRECT_PATTERN pattern failure.', + 'eStr': self.defaultYANGFailure['Pattern'] } } @@ -260,20 +310,20 @@ def loadConfigData(self, jInput, verify=None): # verify the data tree if asked if verify is not None: xpath = verify['xpath'] - log.debug("Verify xpath: {}".format(xpath)) + log.info("Verify xpath: {}".format(xpath)) set = node.find_path(xpath) for dnode in set.data(): if (xpath == dnode.path()): - log.debug("Verify dnode: {}".format(dnode.path())) + log.info("Verify dnode: {}".format(dnode.path())) data = dnode.print_mem(ly.LYD_JSON, ly.LYP_WITHSIBLINGS \ | ly.LYP_FORMAT | ly.LYP_WD_ALL) data = json.loads(data) - log.debug("Verify data: {}".format(data)) + log.info("Verify data: {}".format(data)) assert (data[verify['key']] == verify['value']) s = 'verified' except Exception as e: s = str(e) - log.debug(s) + log.info(s) return s """ @@ -294,7 +344,7 @@ def runExceptionTest(self, test): log.info(desc + " Passed\n") return PASS else: - raise Exception("Unknown Error") + raise Exception("Mismatch {} and {}".format(eStr, s)) except Exception as e: printExceptionDetails() log.info(desc + " Failed\n") @@ -336,10 +386,10 @@ def runVlanSpecialTest(self, test): Run all tests from list self.tests """ def test_run_tests(self): + ret = 0 try: self.initTest() self.loadYangModel(self.yangDir) - ret = 0 for test in self.tests: test = test.strip() if test in self.ExceptionTests: @@ -350,6 +400,7 @@ def test_run_tests(self): raise Exception("Unexpected Test") except Exception as e: printExceptionDetails() + assert ret == 0 return # End of Class diff --git a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json index 72c7b4630c33..90d748309dca 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json +++ b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json @@ -727,6 +727,218 @@ } } }, + + "CRM_WITH_WRONG_PERCENTAGE": { + "sonic-crm:sonic-crm": { + "sonic-crm:CRM": { + "Config": { + "acl_counter_high_threshold": 110, + "acl_counter_low_threshold": 85, + "acl_counter_threshold_type": "PERCENTAGE" + } + } + } + }, + + "CRM_WITH_HIGH_THRESHOLD_ERR": { + "sonic-crm:sonic-crm": { + "sonic-crm:CRM": { + "Config": { + "acl_counter_high_threshold": 80, + "acl_counter_low_threshold": 81, + "acl_counter_threshold_type": "PERCENTAGE" + } + } + } + }, + + "CRM_WITH_WRONG_THRESHOLD": { + "sonic-crm:sonic-crm": { + "sonic-crm:CRM": { + "Config": { + "acl_counter_high_threshold": 85, + "acl_counter_low_threshold": 90, + "acl_counter_threshold_type": "free" + } + } + } + }, + + "CRM_WITH_CORRECT_USED_VALUE": { + "sonic-crm:sonic-crm": { + "sonic-crm:CRM": { + "Config": { + "acl_counter_high_threshold": 85, + "acl_counter_low_threshold": 25, + "acl_counter_threshold_type": "used" + } + } + } + }, + + "DEVICE_METADATA_DEFAULT_BGP_STATUS": { + "sonic-device_metadata:sonic-device_metadata": { + "sonic-device_metadata:DEVICE_METADATA": { + "sonic-device_metadata:localhost": { + "docker_routing_config_mode": "separated", + "platform": "Stone-DX010", + "hostname": "DUT-ASW", + "bgp_asn": "65000" + } + } + } + }, + + "DEVICE_METADATA_DEFAULT_PFCWD_STATUS": { + "sonic-device_metadata:sonic-device_metadata": { + "sonic-device_metadata:DEVICE_METADATA": { + "sonic-device_metadata:localhost": { + "platform": "DX010", + "hostname": "DUT-CSW", + "bgp_asn": "65001" + } + } + } + }, + + "DEVICE_METADATA_TYPE_INCORRECT_PATTERN": { + "sonic-device_metadata:sonic-device_metadata": { + "sonic-device_metadata:DEVICE_METADATA": { + "sonic-device_metadata:localhost": { + "bgp_asn": "65002", + "type": "ToRrouter" + } + } + } + }, + + "VERSIONS_WITH_INCORRECT_PATTERN": { + "sonic-versions:sonic-versions": { + "sonic-versions:VERSIONS": { + "DATABASE": { + "VERSION": "version_1_2" + } + } + } + }, + + "VERSIONS_WITH_INCORRECT_PATTERN2": { + "sonic-versions:sonic-versions": { + "sonic-versions:VERSIONS": { + "DATABASE": { + "VERSION": "version_0_2_77" + } + } + } + }, + + "FLEX_COUNTER_TABLE_WITH_CORRECT_USED_VALUE": { + "sonic-flex_counter:sonic-flex_counter": { + "sonic-flex_counter:FLEX_COUNTER_TABLE": { + "PFCWD": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PG_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PORT": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PORT_RATES": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PORT_BUFFER_DROP": { + "FLEX_COUNTER_STATUS": "enable" + }, + "BUFFER_POOL_WATERMARK_KEY": { + "FLEX_COUNTER_STATUS": "enable" + }, + "QUEUE": { + "FLEX_COUNTER_STATUS": "enable" + }, + "QUEUE_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + }, + "DEBUG_COUNTER": { + "FLEX_COUNTER_STATUS": "enable" + } + } + } + }, + "CRM_BRK_CFG_FLEX_TABLE": { + "sonic-crm:sonic-crm": { + "sonic-crm:CRM": { + "Config": { + "acl_counter_low_threshold": "70", + "acl_counter_high_threshold": "85", + "acl_counter_threshold_type": "percentage", + "ipv6_neighbor_high_threshold": "67", + "ipv6_neighbor_low_threshold": "56", + "ipv6_neighbor_threshold_type": "percentage", + "nexthop_group_high_threshold": "67", + "nexthop_group_low_threshold": "56", + "nexthop_group_threshold_type": "percentage", + "polling_interval": "0" + } + } + }, + "sonic-breakout_cfg:sonic-breakout_cfg": { + "sonic-breakout_cfg:BREAKOUT_CFG": { + "BREAKOUT_CFG_LIST": [ + { + "brkout_mode": "1x100G[40G]", + "port": "Ethernet0" + }, + { + "brkout_mode": "4x25G[10G]", + "port": "Ethernet8" + }, + { + "brkout_mode": "2x25G(2)+1x50G(2)", + "port": "Ethernet4" + }, + { + "brkout_mode": "1x400G", + "port": "Ethernet12" + }, + { + "brkout_mode": "2x200G", + "port": "Ethernet16" + }, + { + "brkout_mode": "4x100G", + "port": "Ethernet20" + }, + { + "brkout_mode": "8x50G", + "port": "Ethernet24" + } + ] + } + }, + "sonic-flex_counter:sonic-flex_counter": { + "sonic-flex_counter:FLEX_COUNTER_TABLE": { + "QUEUE": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PG_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + }, + "QUEUE_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PFCWD": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PORT": { + "FLEX_COUNTER_STATUS": "enable" + }, + "DEBUG_COUNTER": { + "FLEX_COUNTER_STATUS": "enable" + } + } + } + }, "ACL_RULE_WRONG_INNER_ETHER_TYPE": { "sonic-acl:sonic-acl": { "sonic-acl:ACL_RULE": { @@ -962,7 +1174,7 @@ }, "DEVICE_METADATA": { "localhost": { - "type": "ToR", + "type": "ToRRouter", "mac": "00:11:22:33:dd:5a", "hostname": "asw.dc", "bgp_asn": "64850", @@ -1450,7 +1662,7 @@ "brkout_mode": "1x100G[40G]" }, "Ethernet4": { - "brkout_mode": "4x25G" + "brkout_mode": "4x25G[10G]" }, "Ethernet8": { "brkout_mode": "1x100G[40G]" @@ -1471,11 +1683,23 @@ "PORT": { "FLEX_COUNTER_STATUS": "enable" }, + "PORT_RATES": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PORT_BUFFER_DROP": { + "FLEX_COUNTER_STATUS": "enable" + }, + "BUFFER_POOL_WATERMARK_KEY": { + "FLEX_COUNTER_STATUS": "enable" + }, "QUEUE": { "FLEX_COUNTER_STATUS": "enable" }, "QUEUE_WATERMARK": { "FLEX_COUNTER_STATUS": "enable" + }, + "DEBUG_COUNTER": { + "FLEX_COUNTER_STATUS": "enable" } }, "CRM": { @@ -1483,6 +1707,12 @@ "acl_counter_high_threshold": "85", "acl_counter_low_threshold": "70", "acl_counter_threshold_type": "percentage", + "ipv6_neighbor_high_threshold": "67", + "ipv6_neighbor_low_threshold": "56", + "ipv6_neighbor_threshold_type": "percentage", + "nexthop_group_high_threshold": "67", + "nexthop_group_low_threshold": "56", + "nexthop_group_threshold_type": "percentage", "polling_interval": "0" } } diff --git a/src/sonic-yang-models/yang-models/sonic-acl.yang b/src/sonic-yang-models/yang-models/sonic-acl.yang index dcddd247e1c1..3ac0abe8074d 100644 --- a/src/sonic-yang-models/yang-models/sonic-acl.yang +++ b/src/sonic-yang-models/yang-models/sonic-acl.yang @@ -5,10 +5,6 @@ module sonic-acl { namespace "http://github.com/Azure/sonic-acl"; prefix acl; - import ietf-yang-types { - prefix yang; - } - import ietf-inet-types { prefix inet; } diff --git a/src/sonic-yang-models/yang-models/sonic-breakout_cfg.yang b/src/sonic-yang-models/yang-models/sonic-breakout_cfg.yang new file mode 100644 index 000000000000..7cc13f1731c7 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-breakout_cfg.yang @@ -0,0 +1,64 @@ +module sonic-breakout_cfg { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-breakout_cfg"; + prefix breakout_cfg; + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + description "BREAKOUT_CFG YANG Module for SONiC OS"; + + revision 2020-04-10 { + description "First Revision"; + } + + container sonic-breakout_cfg { + + container BREAKOUT_CFG { + + description "BREAKOUT_CFG part of config_db.json"; + + list BREAKOUT_CFG_LIST { + + key "port"; + + ext:key-regex-configdb-to-yang "^([a-zA-Z0-9_-]+)$"; + + ext:key-regex-yang-to-configdb ""; + + /* + * This is leaf instead of a leafref towards port, because this + * table will contains Parent ports and their current breakout-mode, + * irrespective of port is present in PORT table or not. Specially + * during Dynamic Port Breakout, Parent Port may not be present in + * PORT table. + */ + leaf port { + type string { + length 1..255; + } + } + + leaf brkout_mode { + type string { + length 1..64; + /* + * Below allowed patterns are based on most used Platforms, + * Add any other breakout-mode to allow Dynamic Port + * Breakout to that breakout-mode. + */ + pattern '1x100G\[40G\]|2x50G|4x25G\[10G\]|2x25G\(2\)\+1x50G\(2\)|1x50G\(2\)\+2x25G\(2\)|1x400G|2x200G|4x100G|8x50G'; + } + } + } + /* end of list BREAKOUT_CFG_LIST */ + } + /* end of container BREAKOUT_CFG */ + } + /* end of top level container */ +} +/* end of module sonic-breakout_cfg */ diff --git a/src/sonic-yang-models/yang-models/sonic-crm.yang b/src/sonic-yang-models/yang-models/sonic-crm.yang new file mode 100644 index 000000000000..cc53aa7f0d50 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-crm.yang @@ -0,0 +1,303 @@ +module sonic-crm { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-crm"; + prefix crm; + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + description "CRM YANG Module for SONiC OS"; + + revision 2020-04-10 { + description "First Revision"; + } + + container sonic-crm { + + container CRM { + + description "CRM part of config_db.json"; + + container Config { + + /* typedef specific to CRM */ + typedef threshold { + type uint16; + } + + leaf acl_counter_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../acl_counter_high_threshold<100 and + ../acl_counter_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf acl_counter_high_threshold { + must "(current() > ../acl_counter_low_threshold)" + { + error-message "high_threshold should be more than low_threshold"; + } + type threshold; + } + + leaf acl_counter_low_threshold { + type threshold; + } + + leaf acl_group_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../acl_group_high_threshold<100 and + ../acl_group_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf acl_group_high_threshold { + must "(current() > ../acl_group_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf acl_group_low_threshold { + type threshold; + } + + leaf acl_entry_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../acl_entry_high_threshold<100 and + ../acl_entry_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf acl_entry_high_threshold { + must "(current() > ../acl_entry_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf acl_entry_low_threshold { + type threshold; + } + + leaf acl_table_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../acl_table_high_threshold<100 and + ../acl_table_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf acl_table_high_threshold { + must "(current() > ../acl_table_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf acl_table_low_threshold { + type threshold; + } + + leaf fdb_entry_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../fdb_entry_high_threshold<100 and + ../fdb_entry_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf fdb_entry_high_threshold { + must "(current() > ../fdb_entry_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf fdb_entry_low_threshold { + type threshold; + } + + leaf ipv4_neighbor_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../ipv4_neighbor_high_threshold<100 and + ../ipv4_neighbor_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf ipv4_neighbor_high_threshold { + must "(current() > ../ipv4_neighbor_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf ipv4_neighbor_low_threshold { + type threshold; + } + + leaf ipv4_nexthop_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../ipv4_nexthop_high_threshold<100 and + ../ipv4_nexthop_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf ipv4_nexthop_high_threshold { + must "(current() > ../ipv4_nexthop_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf ipv4_nexthop_low_threshold { + type threshold; + } + + leaf ipv4_route_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../ipv4_route_high_threshold<100 and + ../ipv4_route_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf ipv4_route_high_threshold { + must "(current() > ../ipv4_route_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf ipv4_route_low_threshold { + type threshold; + } + + leaf ipv6_neighbor_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../ipv6_neighbor_high_threshold<100 and + ../ipv6_neighbor_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf ipv6_neighbor_high_threshold { + must "(current() > ../ipv6_neighbor_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf ipv6_neighbor_low_threshold { + type threshold; + } + + leaf ipv6_nexthop_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../ipv6_nexthop_high_threshold<100 and + ../ipv6_nexthop_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf ipv6_nexthop_high_threshold { + must "(current() > ../ipv6_nexthop_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf ipv6_nexthop_low_threshold { + type threshold; + } + + leaf ipv6_route_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../ipv6_route_high_threshold<100 and + ../ipv6_route_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf ipv6_route_high_threshold { + must "(current() > ../ipv6_route_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf ipv6_route_low_threshold { + type threshold; + } + + leaf nexthop_group_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../nexthop_group_high_threshold<100 and + ../nexthop_group_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf nexthop_group_high_threshold { + must "(current() > ../nexthop_group_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf nexthop_group_low_threshold { + type threshold; + } + + leaf nexthop_group_member_threshold_type { + must "(((current()='PERCENTAGE' or current()='percentage') and + ../nexthop_group_member_high_threshold<100 and + ../nexthop_group_member_low_threshold<100) or + (current()!='PERCENTAGE' and current()!='percentage'))"; + type stypes:crm_threshold_type; + } + + leaf nexthop_group_member_high_threshold { + must "(current() > ../nexthop_group_member_low_threshold)" + { + error-message "high_threshold should be more that low_threshold"; + } + type threshold; + } + + leaf nexthop_group_member_low_threshold { + type threshold; + } + + leaf polling_interval { + type threshold; + } + + } + /* end of Config */ + } + /* end of container CRM */ + } + /* end of top level container */ +} +/* end of module sonic-crm */ diff --git a/src/sonic-yang-models/yang-models/sonic-device_metadata.yang b/src/sonic-yang-models/yang-models/sonic-device_metadata.yang new file mode 100644 index 000000000000..054b436f2470 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-device_metadata.yang @@ -0,0 +1,99 @@ +module sonic-device_metadata { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-device_metadata"; + prefix device_metadata; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + description "DEVICE_METADATA YANG Module for SONiC OS"; + + revision 2020-04-10 { + description "First Revision"; + } + + container sonic-device_metadata { + + container DEVICE_METADATA { + + description "DEVICE_METADATA part of config_db.json"; + + container localhost{ + + leaf hwsku { + type stypes:hwsku; + } + + leaf default_bgp_status { + type enumeration { + enum up; + enum down; + } + default up; + } + + leaf docker_routing_config_mode { + type string { + pattern "unified|split|separated"; + } + default "unified"; + } + + leaf hostname { + type string { + length 1..255; + } + } + + leaf platform { + type string { + length 1..255; + } + } + + leaf mac { + type yang:mac-address; + } + + leaf default_pfcwd_status { + type enumeration { + enum disable; + enum enable; + } + default disable; + } + + leaf bgp_asn { + type inet:as-number; + } + + leaf deployment_id { + type uint32; + } + + leaf type { + type string { + length 1..255; + pattern "ToRRouter|LeafRouter|SpineChassisFrontendRouter|ChassisBackendRouter|ASIC"; + } + } + } + /* end of container localhost */ + } + /* end of container DEVICE_METADATA */ + } + /* end of top level container */ +} +/* end of module sonic-device_metadata */ diff --git a/src/sonic-yang-models/yang-models/sonic-device_neighbor.yang b/src/sonic-yang-models/yang-models/sonic-device_neighbor.yang new file mode 100644 index 000000000000..c764940fd138 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-device_neighbor.yang @@ -0,0 +1,82 @@ +module sonic-device_neighbor { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-device_neighbor"; + prefix device_neighbor; + + import ietf-inet-types { + prefix inet; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + import sonic-port { + prefix port; + revision-date 2019-07-01; + } + + description "DEVICE_NEIGHBOR YANG Module for SONiC OS"; + + revision 2020-04-10 { + description "First Revision"; + } + + container sonic-device_neighbor { + + container DEVICE_NEIGHBOR { + + description "DEVICE_NEIGHBOR part of config_db.json"; + + list DEVICE_NEIGHBOR_LIST { + + key "peer_name"; + + ext:key-regex-configdb-to-yang "^([a-zA-Z0-9_-]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf peer_name { + type string { + length 1..255; + } + } + + leaf name { + type string { + length 1..255; + } + } + + leaf mgmt_addr { + type inet:ip-address; + } + + leaf local_port { + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf port { + type string { + length 1..255; + } + } + + leaf type { + type string { + length 1..255; + } + } + } + /* end of list DEVICE_NEIGHBOR_LIST */ + } + /* end of container DEVICE_NEIGHBOR */ + } + /* end of top level container */ +} +/* end of module sonic-device_neighbor */ diff --git a/src/sonic-yang-models/yang-models/sonic-flex_counter.yang b/src/sonic-yang-models/yang-models/sonic-flex_counter.yang new file mode 100644 index 000000000000..83b0512aeb21 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-flex_counter.yang @@ -0,0 +1,112 @@ +module sonic-flex_counter { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-flex_counter"; + prefix flex_counter; + + description "FLEX COUNTER YANG Module for SONiC OS"; + + revision 2020-04-10 { + description "First Revision"; + } + + container sonic-flex_counter { + + container FLEX_COUNTER_TABLE { + + /* typedef specific to FLEX_COUNTER_TABLE */ + typedef flex_status { + type enumeration { + enum enable; + enum disable; + } + } + + description "FLEX_COUNTER_TABLE part of config_db.json"; + + /* below are in alphabetical order */ + + container BUFFER_POOL_WATERMARK_KEY { + /* BUFFER_POOL_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP */ + leaf FLEX_COUNTER_STATUS { + type flex_status; + } + } + + container DEBUG_COUNTER { + /* DEBUG_COUNTER_FLEX_COUNTER_GROUP */ + leaf FLEX_COUNTER_STATUS { + type flex_status; + } + } + + container PFCWD { + /* PFC_WD_FLEX_COUNTER_GROUP */ + leaf FLEX_COUNTER_STATUS { + type flex_status; + } + } + + container PG_WATERMARK { + /* PG_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP */ + leaf FLEX_COUNTER_STATUS { + type flex_status; + } + } + + container PORT { + /* PORT_STAT_COUNTER_FLEX_COUNTER_GROUP */ + leaf FLEX_COUNTER_STATUS { + type flex_status; + } + } + + container PORT_RATES { + /* PORT_BUFFER_DROP_COUNTER_FLEX_COUNTER_GROUP */ + leaf FLEX_COUNTER_STATUS { + type flex_status; + } + } + + container PORT_BUFFER_DROP { + /* PORT_BUFFER_DROP_COUNTER_FLEX_COUNTER_GROUP */ + leaf FLEX_COUNTER_STATUS { + type flex_status; + } + } + + container QUEUE { + /* QUEUE_STAT_COUNTER_FLEX_COUNTER_GROUP */ + leaf FLEX_COUNTER_STATUS { + type flex_status; + } + } + + container QUEUE_WATERMARK { + /* QUEUE_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP */ + leaf FLEX_COUNTER_STATUS { + type flex_status; + } + } + + container RIF { + /* RIF_STAT_COUNTER_FLEX_COUNTER_GROUP */ + leaf FLEX_COUNTER_STATUS { + type flex_status; + } + } + + container RIF_RATES { + /* RIF_RATE_COUNTER_FLEX_COUNTER_GROUP */ + leaf FLEX_COUNTER_STATUS { + type flex_status; + } + } + + } + /* end of container FLEX_COUNTER_TABLE */ + } + /* end of top level container */ +} +/* end of module sonic-flex_counter */ diff --git a/src/sonic-yang-models/yang-models/sonic-interface.yang b/src/sonic-yang-models/yang-models/sonic-interface.yang index d47268be69f9..9585aabbb2c2 100644 --- a/src/sonic-yang-models/yang-models/sonic-interface.yang +++ b/src/sonic-yang-models/yang-models/sonic-interface.yang @@ -5,14 +5,6 @@ module sonic-interface { namespace "http://github.com/Azure/sonic-interface"; prefix intf; - import ietf-yang-types { - prefix yang; - } - - import ietf-inet-types { - prefix inet; - } - import sonic-types { prefix stypes; revision-date 2019-07-01; diff --git a/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang b/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang index 6b509a8df349..1ed165d26c3b 100644 --- a/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang +++ b/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang @@ -5,10 +5,6 @@ module sonic-loopback-interface { namespace "http://github.com/Azure/sonic-loopback-interface"; prefix lointf; - import ietf-inet-types { - prefix inet; - } - import sonic-types { prefix stypes; revision-date 2019-07-01; diff --git a/src/sonic-yang-models/yang-models/sonic-port.yang b/src/sonic-yang-models/yang-models/sonic-port.yang index 574780dcf064..8a41d13f1a49 100644 --- a/src/sonic-yang-models/yang-models/sonic-port.yang +++ b/src/sonic-yang-models/yang-models/sonic-port.yang @@ -5,14 +5,6 @@ module sonic-port{ namespace "http://github.com/Azure/sonic-port"; prefix port; - import ietf-yang-types { - prefix yang; - } - - import ietf-inet-types { - prefix inet; - } - import sonic-types { prefix stypes; revision-date 2019-07-01; diff --git a/src/sonic-yang-models/yang-models/sonic-portchannel.yang b/src/sonic-yang-models/yang-models/sonic-portchannel.yang index 8d27398c61e8..69c8fa6ac161 100644 --- a/src/sonic-yang-models/yang-models/sonic-portchannel.yang +++ b/src/sonic-yang-models/yang-models/sonic-portchannel.yang @@ -5,14 +5,6 @@ module sonic-portchannel { namespace "http://github.com/Azure/sonic-portchannel"; prefix lag; - import ietf-yang-types { - prefix yang; - } - - import ietf-inet-types { - prefix inet; - } - import sonic-types { prefix stypes; revision-date 2019-07-01; diff --git a/src/sonic-yang-models/yang-models/sonic-types.yang b/src/sonic-yang-models/yang-models/sonic-types.yang index fb651847582e..0bfcddc56103 100644 --- a/src/sonic-yang-models/yang-models/sonic-types.yang +++ b/src/sonic-yang-models/yang-models/sonic-types.yang @@ -6,6 +6,10 @@ module sonic-types { prefix sonic-types; description "SONiC type for yang Models of SONiC OS"; + /* + * Try to define only sonic specific types here. Rest can be written in + * respective YANG files. + */ revision 2019-07-01 { description "First Revision"; @@ -82,6 +86,13 @@ module sonic-types { } } + typedef hwsku { + type string { + length 1..255; + /* Should we list all hwsku here */ + } + } + typedef vlan_tagging_mode { type enumeration { enum tagged; @@ -89,4 +100,11 @@ module sonic-types { enum priority_tagged; } } + + typedef crm_threshold_type { + type string { + length 1..64; + pattern "percentage|used|free|PERCENTAGE|USED|FREE"; + } + } } diff --git a/src/sonic-yang-models/yang-models/sonic-versions.yang b/src/sonic-yang-models/yang-models/sonic-versions.yang new file mode 100644 index 000000000000..156102122706 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-versions.yang @@ -0,0 +1,36 @@ +module sonic-versions { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-versions"; + prefix versions; + + + description "VERSIONS YANG Module for SONiC OS"; + + revision 2020-04-10 { + description "First Revision"; + } + + container sonic-versions { + + container VERSIONS { + + description "DATABASE SCHEMA VERSIONS part of config_db.json"; + + container DATABASE { + + leaf VERSION { + type string { + length 1..255; + pattern 'version_([1-9]|[1-9]{1}[0-9]{1})_([0-9]{1,2})_([0-9]{1,2})'; + } + } + } + /* end of container DATABASE */ + } + /* end of container VERSIONS */ + } + /* end of top level container */ +} +/* end of module sonic-versions */ diff --git a/src/sonic-yang-models/yang-models/sonic-vlan.yang b/src/sonic-yang-models/yang-models/sonic-vlan.yang index 6d2b9b154cbe..d00e68b39029 100644 --- a/src/sonic-yang-models/yang-models/sonic-vlan.yang +++ b/src/sonic-yang-models/yang-models/sonic-vlan.yang @@ -5,10 +5,6 @@ module sonic-vlan { namespace "http://github.com/Azure/sonic-vlan"; prefix vlan; - import ietf-yang-types { - prefix yang; - } - import ietf-inet-types { prefix inet; } From bbbd94f4dd468bda60664854a079a8c0c629c38b Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Wed, 18 Nov 2020 19:33:19 +0200 Subject: [PATCH 1406/1427] [enable counters] provide initial rates parameters (#5048) * [enable counters] provide initial rates parameters Signed-off-by: Mykola Faryma * add descriptive comment Signed-off-by: Mykola Faryma Co-authored-by: Volodymyr Samotiy --- dockers/docker-orchagent/enable_counters.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/dockers/docker-orchagent/enable_counters.py b/dockers/docker-orchagent/enable_counters.py index 2067baefbfb7..b412517d36e7 100755 --- a/dockers/docker-orchagent/enable_counters.py +++ b/dockers/docker-orchagent/enable_counters.py @@ -1,9 +1,14 @@ #!/usr/bin/env python3 import time - import swsssdk +# ALPHA defines the size of the window over which we calculate the average value. ALPHA is 2/(N+1) where N is the interval(window size) +# In this case we configure the window to be 10s. This way if we have a huge 1s spike in traffic, +# the average rate value will show a curve descending from the spike to the usual rate over approximately 10s. +DEFAULT_SMOOTH_INTERVAL = '10' +DEFAULT_ALPHA = '0.18' + def enable_counter_group(db, name): info = {} @@ -11,6 +16,16 @@ def enable_counter_group(db, name): db.mod_entry("FLEX_COUNTER_TABLE", name, info) +def enable_rates(): + # set the default interval for rates + counters_db = swsssdk.SonicV2Connector() + counters_db.connect('COUNTERS_DB') + counters_db.set('COUNTERS_DB', 'RATES:PORT', 'PORT_SMOOTH_INTERVAL', DEFAULT_SMOOTH_INTERVAL) + counters_db.set('COUNTERS_DB', 'RATES:PORT', 'PORT_ALPHA', DEFAULT_ALPHA) + counters_db.set('COUNTERS_DB', 'RATES:RIF', 'RIF_SMOOTH_INTERVAL', DEFAULT_SMOOTH_INTERVAL) + counters_db.set('COUNTERS_DB', 'RATES:RIF', 'RIF_ALPHA', DEFAULT_ALPHA) + + def enable_counters(): db = swsssdk.ConfigDBConnector() db.connect() @@ -22,6 +37,7 @@ def enable_counters(): enable_counter_group(db, 'QUEUE_WATERMARK') enable_counter_group(db, 'BUFFER_POOL_WATERMARK') enable_counter_group(db, 'PORT_BUFFER_DROP') + enable_rates() def get_uptime(): @@ -43,3 +59,4 @@ def main(): if __name__ == '__main__': main() + From 3be3f4d1042a772e0a2b45bb3ee3b5e0b6daef74 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Wed, 18 Nov 2020 11:20:43 -0800 Subject: [PATCH 1407/1427] [BCM SAI] update BCM SAI to 4.2.1.5 (#5866) This release includes changes for supporting Debian Buster, fixes for internally found issues and more enhancement related to spec coverage and feature parity for Broadcom ASICs. Additional fixes included: CS00011465498 - Warm reboot CS00011465061 - interfaces not coming up CS00011396506 - nexthop resource leak CS00011452080 - BCM SAI crash while getting lane count --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 2e647ed58cf8..6c4a33b7bd7b 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,8 +1,8 @@ -BRCM_SAI = libsaibcm_4.2.1.3-1_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm_4.2.1.3-1_amd64.deb?sv=2015-04-05&sr=b&sig=1%2BrMfgxeSc%2BXJUPw6X%2FhNGxe4KUp15Oqq1lVwMJGiW0%3D&se=2034-07-20T03%3A20%3A08Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_4.2.1.3-1_amd64.deb +BRCM_SAI = libsaibcm_4.2.1.5-4_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm_4.2.1.5-4_amd64.deb?sv=2015-04-05&sr=b&sig=dHfQf95FxgLBlnrGJwv6pIkAYAc6mOGbz9vvUMfxFvg%3D&se=2034-07-28T05%3A53%3A21Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_4.2.1.5-4_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm-dev_4.2.1.3-1_amd64.deb?sv=2015-04-05&sr=b&sig=lTzaCynflt5UO7Ltf2Z%2B6zHJ4R%2BFj421kupIGO4%2FOCI%3D&se=2034-07-20T03%3A19%3A27Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm-dev_4.2.1.5-4_amd64.deb?sv=2015-04-05&sr=b&sig=n98j842RZy%2BwQh4CtOku7jz6wgV%2BusbTl9NkeRndBrE%3D&se=2037-01-13T05%3A54%3A34Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 0a9d7a21456b73300bcdc642d17204e658848315 Mon Sep 17 00:00:00 2001 From: carl-nokia <63672637+carl-nokia@users.noreply.github.com> Date: Wed, 18 Nov 2020 20:00:40 -0500 Subject: [PATCH 1408/1427] [devices]: Add support for the Nokia-7215 platform (#5827) Platform: armhf-nokia_ixs7215_52x-r0 HwSKU: Nokia-7215 ASIC: marvell Port Config: 48x1G + 4x10G Co-authored-by: dflynn Co-authored-by: Carl Keene --- .../Nokia-7215/buffers_defaults_t1.j2 | 45 + .../Nokia-7215/port_config.ini | 53 + .../Nokia-7215/port_config.ini.inband | 52 + .../Nokia-7215/port_config.ini.noinband | 53 + .../Nokia-7215/profile.ini | 2 + .../Nokia-7215/profile.ini.inband | 3 + .../Nokia-7215/profile.ini.noinband | 2 + .../Nokia-7215/sai.profile | 3 + .../armhf-nokia_ixs7215_52x-r0/default_sku | 1 + .../platform_components.json | 10 + .../plugins/eeprom.py | 14 + .../plugins/led_control.py | 125 +++ .../plugins/psuutil.py | 32 + .../plugins/sfputil.py | 65 ++ .../armhf-nokia_ixs7215_52x-r0/sensors.conf | 19 + .../thermal_policy.json | 65 ++ platform/marvell-armhf/one-image.mk | 3 +- platform/marvell-armhf/platform-nokia.mk | 11 + platform/marvell-armhf/platform.conf | 6 +- platform/marvell-armhf/rules.mk | 1 + .../7215/scripts/nokia-7215init.sh | 61 ++ .../7215/service/nokia-7215init.service | 14 + .../sonic-platform-nokia/7215/setup.py | 15 + .../7215/sonic_platform/__init__.py | 2 + .../7215/sonic_platform/chassis.py | 377 +++++++ .../7215/sonic_platform/component.py | 119 +++ .../7215/sonic_platform/eeprom.py | 235 +++++ .../7215/sonic_platform/fan.py | 330 +++++++ .../7215/sonic_platform/fan_drawer.py | 47 + .../7215/sonic_platform/platform.py | 22 + .../7215/sonic_platform/psu.py | 225 +++++ .../7215/sonic_platform/sfp.py | 916 ++++++++++++++++++ .../7215/sonic_platform/sfp_event.py | 117 +++ .../7215/sonic_platform/test/README | 1 + .../7215/sonic_platform/test/test-chassis.py | 68 ++ .../sonic_platform/test/test-component.py | 17 + .../7215/sonic_platform/test/test-eeprom.py | 25 + .../7215/sonic_platform/test/test-fan.py | 27 + .../7215/sonic_platform/test/test-psu.py | 27 + .../7215/sonic_platform/test/test-sfp.py | 51 + .../7215/sonic_platform/test/test-thermal.py | 26 + .../7215/sonic_platform/thermal.py | 226 +++++ .../7215/sonic_platform/thermal_actions.py | 192 ++++ .../7215/sonic_platform/thermal_conditions.py | 81 ++ .../7215/sonic_platform/thermal_infos.py | 210 ++++ .../7215/sonic_platform/thermal_manager.py | 49 + .../7215/sonic_platform/watchdog.py | 135 +++ .../sonic-platform-nokia/debian/changelog | 5 + .../sonic-platform-nokia/debian/compat | 1 + .../sonic-platform-nokia/debian/control | 15 + .../sonic-platform-nokia/debian/rules | 66 ++ .../debian/sonic-platform-nokia-7215.install | 5 + .../debian/sonic-platform-nokia-7215.postinst | 11 + .../nokia-7215_plt_setup.sh | 35 + 54 files changed, 4316 insertions(+), 2 deletions(-) create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/buffers_defaults_t1.j2 create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.inband create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.noinband create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.inband create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.noinband create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/sai.profile create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/default_sku create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/platform_components.json create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/eeprom.py create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/led_control.py create mode 100755 device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/psuutil.py create mode 100755 device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/sfputil.py create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/sensors.conf create mode 100644 device/nokia/armhf-nokia_ixs7215_52x-r0/thermal_policy.json create mode 100644 platform/marvell-armhf/platform-nokia.mk create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/scripts/nokia-7215init.sh create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/service/nokia-7215init.service create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/setup.py create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/__init__.py create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/chassis.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/component.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/eeprom.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan_drawer.py create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/platform.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/psu.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp_event.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/README create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-chassis.py create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-component.py create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-eeprom.py create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-fan.py create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-psu.py create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-sfp.py create mode 100755 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-thermal.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_actions.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_conditions.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_infos.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_manager.py create mode 100644 platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/watchdog.py create mode 100755 platform/marvell-armhf/sonic-platform-nokia/debian/changelog create mode 100644 platform/marvell-armhf/sonic-platform-nokia/debian/compat create mode 100755 platform/marvell-armhf/sonic-platform-nokia/debian/control create mode 100755 platform/marvell-armhf/sonic-platform-nokia/debian/rules create mode 100644 platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.install create mode 100644 platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.postinst create mode 100755 platform/marvell-armhf/sonic-platform-nokia/nokia-7215_plt_setup.sh diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/buffers_defaults_t1.j2 b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini new file mode 100644 index 000000000000..062c252ce195 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini @@ -0,0 +1,53 @@ +# name lanes alias index speed +Ethernet0 1 Ethernet0 1 1000 +Ethernet1 2 Ethernet1 2 1000 +Ethernet2 3 Ethernet2 3 1000 +Ethernet3 4 Ethernet3 4 1000 +Ethernet4 5 Ethernet4 5 1000 +Ethernet5 6 Ethernet5 6 1000 +Ethernet6 7 Ethernet6 7 1000 +Ethernet7 8 Ethernet7 8 1000 +Ethernet8 9 Ethernet8 9 1000 +Ethernet9 10 Ethernet9 10 1000 +Ethernet10 11 Ethernet10 11 1000 +Ethernet11 12 Ethernet11 12 1000 +Ethernet12 13 Ethernet12 13 1000 +Ethernet13 14 Ethernet13 14 1000 +Ethernet14 15 Ethernet14 15 1000 +Ethernet15 16 Ethernet15 16 1000 +Ethernet16 17 Ethernet16 17 1000 +Ethernet17 18 Ethernet17 18 1000 +Ethernet18 19 Ethernet18 19 1000 +Ethernet19 20 Ethernet19 20 1000 +Ethernet20 21 Ethernet20 21 1000 +Ethernet21 22 Ethernet21 22 1000 +Ethernet22 23 Ethernet22 23 1000 +Ethernet23 24 Ethernet23 24 1000 +Ethernet24 25 Ethernet24 25 1000 +Ethernet25 26 Ethernet25 26 1000 +Ethernet26 27 Ethernet26 27 1000 +Ethernet27 28 Ethernet27 28 1000 +Ethernet28 29 Ethernet28 29 1000 +Ethernet29 30 Ethernet29 30 1000 +Ethernet30 31 Ethernet30 31 1000 +Ethernet31 32 Ethernet31 32 1000 +Ethernet32 33 Ethernet32 33 1000 +Ethernet33 34 Ethernet33 34 1000 +Ethernet34 35 Ethernet34 35 1000 +Ethernet35 36 Ethernet35 36 1000 +Ethernet36 37 Ethernet36 37 1000 +Ethernet37 38 Ethernet37 38 1000 +Ethernet38 39 Ethernet38 39 1000 +Ethernet39 40 Ethernet39 40 1000 +Ethernet40 41 Ethernet40 41 1000 +Ethernet41 42 Ethernet41 42 1000 +Ethernet42 43 Ethernet42 43 1000 +Ethernet43 44 Ethernet43 44 1000 +Ethernet44 45 Ethernet44 45 1000 +Ethernet45 46 Ethernet45 46 1000 +Ethernet46 47 Ethernet46 47 1000 +Ethernet47 48 Ethernet47 48 1000 +Ethernet48 49 Ethernet48 49 10000 +Ethernet49 50 Ethernet49 50 10000 +Ethernet50 51 Ethernet50 51 10000 +Ethernet51 52 Ethernet51 52 10000 diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.inband b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.inband new file mode 100644 index 000000000000..556da9c62254 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.inband @@ -0,0 +1,52 @@ +# name lanes alias index speed +Ethernet0 1 Ethernet0 1 1000 +Ethernet1 2 Ethernet1 2 1000 +Ethernet2 3 Ethernet2 3 1000 +Ethernet3 4 Ethernet3 4 1000 +Ethernet4 5 Ethernet4 5 1000 +Ethernet5 6 Ethernet5 6 1000 +Ethernet6 7 Ethernet6 7 1000 +Ethernet7 8 Ethernet7 8 1000 +Ethernet8 9 Ethernet8 9 1000 +Ethernet9 10 Ethernet9 10 1000 +Ethernet10 11 Ethernet10 11 1000 +Ethernet11 12 Ethernet11 12 1000 +Ethernet12 13 Ethernet12 13 1000 +Ethernet13 14 Ethernet13 14 1000 +Ethernet14 15 Ethernet14 15 1000 +Ethernet15 16 Ethernet15 16 1000 +Ethernet16 17 Ethernet16 17 1000 +Ethernet17 18 Ethernet17 18 1000 +Ethernet18 19 Ethernet18 19 1000 +Ethernet19 20 Ethernet19 20 1000 +Ethernet20 21 Ethernet20 21 1000 +Ethernet21 22 Ethernet21 22 1000 +Ethernet22 23 Ethernet22 23 1000 +Ethernet23 24 Ethernet23 24 1000 +Ethernet24 25 Ethernet24 25 1000 +Ethernet25 26 Ethernet25 26 1000 +Ethernet26 27 Ethernet26 27 1000 +Ethernet27 28 Ethernet27 28 1000 +Ethernet28 29 Ethernet28 29 1000 +Ethernet29 30 Ethernet29 30 1000 +Ethernet30 31 Ethernet30 31 1000 +Ethernet31 32 Ethernet31 32 1000 +Ethernet32 33 Ethernet32 33 1000 +Ethernet33 34 Ethernet33 34 1000 +Ethernet34 35 Ethernet34 35 1000 +Ethernet35 36 Ethernet35 36 1000 +Ethernet36 37 Ethernet36 37 1000 +Ethernet37 38 Ethernet37 38 1000 +Ethernet38 39 Ethernet38 39 1000 +Ethernet39 40 Ethernet39 40 1000 +Ethernet40 41 Ethernet40 41 1000 +Ethernet41 42 Ethernet41 42 1000 +Ethernet42 43 Ethernet42 43 1000 +Ethernet43 44 Ethernet43 44 1000 +Ethernet44 45 Ethernet44 45 1000 +Ethernet45 46 Ethernet45 46 1000 +Ethernet46 47 Ethernet46 47 1000 +Ethernet48 49 Ethernet48 49 10000 +Ethernet49 50 Ethernet49 50 10000 +Ethernet50 51 Ethernet50 51 10000 +Ethernet51 52 Ethernet51 52 10000 diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.noinband b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.noinband new file mode 100644 index 000000000000..062c252ce195 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.noinband @@ -0,0 +1,53 @@ +# name lanes alias index speed +Ethernet0 1 Ethernet0 1 1000 +Ethernet1 2 Ethernet1 2 1000 +Ethernet2 3 Ethernet2 3 1000 +Ethernet3 4 Ethernet3 4 1000 +Ethernet4 5 Ethernet4 5 1000 +Ethernet5 6 Ethernet5 6 1000 +Ethernet6 7 Ethernet6 7 1000 +Ethernet7 8 Ethernet7 8 1000 +Ethernet8 9 Ethernet8 9 1000 +Ethernet9 10 Ethernet9 10 1000 +Ethernet10 11 Ethernet10 11 1000 +Ethernet11 12 Ethernet11 12 1000 +Ethernet12 13 Ethernet12 13 1000 +Ethernet13 14 Ethernet13 14 1000 +Ethernet14 15 Ethernet14 15 1000 +Ethernet15 16 Ethernet15 16 1000 +Ethernet16 17 Ethernet16 17 1000 +Ethernet17 18 Ethernet17 18 1000 +Ethernet18 19 Ethernet18 19 1000 +Ethernet19 20 Ethernet19 20 1000 +Ethernet20 21 Ethernet20 21 1000 +Ethernet21 22 Ethernet21 22 1000 +Ethernet22 23 Ethernet22 23 1000 +Ethernet23 24 Ethernet23 24 1000 +Ethernet24 25 Ethernet24 25 1000 +Ethernet25 26 Ethernet25 26 1000 +Ethernet26 27 Ethernet26 27 1000 +Ethernet27 28 Ethernet27 28 1000 +Ethernet28 29 Ethernet28 29 1000 +Ethernet29 30 Ethernet29 30 1000 +Ethernet30 31 Ethernet30 31 1000 +Ethernet31 32 Ethernet31 32 1000 +Ethernet32 33 Ethernet32 33 1000 +Ethernet33 34 Ethernet33 34 1000 +Ethernet34 35 Ethernet34 35 1000 +Ethernet35 36 Ethernet35 36 1000 +Ethernet36 37 Ethernet36 37 1000 +Ethernet37 38 Ethernet37 38 1000 +Ethernet38 39 Ethernet38 39 1000 +Ethernet39 40 Ethernet39 40 1000 +Ethernet40 41 Ethernet40 41 1000 +Ethernet41 42 Ethernet41 42 1000 +Ethernet42 43 Ethernet42 43 1000 +Ethernet43 44 Ethernet43 44 1000 +Ethernet44 45 Ethernet44 45 1000 +Ethernet45 46 Ethernet45 46 1000 +Ethernet46 47 Ethernet46 47 1000 +Ethernet47 48 Ethernet47 48 1000 +Ethernet48 49 Ethernet48 49 10000 +Ethernet49 50 Ethernet49 50 10000 +Ethernet50 51 Ethernet50 51 10000 +Ethernet51 52 Ethernet51 52 10000 diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini new file mode 100644 index 000000000000..c908d9235215 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=XX:XX:XX:XX:XX:XX +ledMode=ac3x97bits diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.inband b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.inband new file mode 100644 index 000000000000..6a82d5939c3b --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.inband @@ -0,0 +1,3 @@ +switchMacAddress=XX:XX:XX:XX:XX:XX +inbandMgmtPortNum=48 +ledMode=ac3x97bits diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.noinband b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.noinband new file mode 100644 index 000000000000..c908d9235215 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.noinband @@ -0,0 +1,2 @@ +switchMacAddress=XX:XX:XX:XX:XX:XX +ledMode=ac3x97bits diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/sai.profile b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/sai.profile new file mode 100644 index 000000000000..10053fa935a1 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=et6448m +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/default_sku b/device/nokia/armhf-nokia_ixs7215_52x-r0/default_sku new file mode 100644 index 000000000000..5c41b116898d --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/default_sku @@ -0,0 +1 @@ +Nokia-7215 l2 diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/platform_components.json b/device/nokia/armhf-nokia_ixs7215_52x-r0/platform_components.json new file mode 100644 index 000000000000..51dfea452f54 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "7215 IXS-T1": { + "component": { + "U-Boot": { }, + "System-CPLD": { } + } + } + } +} diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/eeprom.py b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/eeprom.py new file mode 100644 index 000000000000..be538d1c0e89 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/eeprom.py @@ -0,0 +1,14 @@ +try: + import os + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0053/eeprom" + if not os.path.exists(self.eeprom_path): + os.system("echo 24c02 0x53 > /sys/class/i2c-adapter/i2c-0/new_device") + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/led_control.py b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/led_control.py new file mode 100644 index 000000000000..e3b1c484acd3 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/led_control.py @@ -0,0 +1,125 @@ +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + from sonic_led.led_control_base import LedControlBase + import os + import time + import syslog + import sonic_platform.platform + import sonic_platform.chassis +except ImportError as e: + raise ImportError(str(e) + " - required module not found") + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + + +def DBG_PRINT(str): + syslog.openlog("nokia-led") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + + # Constructor + def __init__(self): + self.chassis = sonic_platform.platform.Platform().get_chassis() + self._initDefaultConfig() + + def _initDefaultConfig(self): + # For the D1 box the port leds are controlled by Trident3 LED program + # The fan tray leds will be managed with the new thermalctl daemon / chassis class based API + # leaving only the system leds to be done old style + DBG_PRINT("starting system leds") + self._initSystemLed() + DBG_PRINT(" led done") + + def _set_i2c_register(self, reg_file, value): + # On successful write, the value read will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + try: + with open(reg_file, 'w') as fd: + rv = fd.write(str(value)) + except Exception as e: + rv = 'ERR' + + return rv + + def _initSystemLed(self): + # Front Panel System LEDs setting + oldfan = 0xf + oldpsu = 0xf + + # Write sys led + if smbus_present == 0: + DBG_PRINT(" PMON LED SET ERROR -> smbus present = 0 ") + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICEREG = 0x7 + bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, 0x02) + DBG_PRINT(" System LED set O.K. ") + + while True: + # Front Panel FAN Panel LED setting in register 0x08 + if (self.chassis.get_fan(0).get_status() == self.chassis.get_fan(1).get_status() == True): + if oldfan != 0x1: + if (os.path.isfile("/sys/class/gpio/fanLedAmber/value")): + self._set_i2c_register("/sys/class/gpio/fanLedAmber/value", 0) + self._set_i2c_register("/sys/class/gpio/fanLedGreen/value", 1) + oldfan = 0x1 + else: + if oldfan != 0x0: + if (os.path.isfile("/sys/class/gpio/fanLedGreen/value")): + self._set_i2c_register("/sys/class/gpio/fanLedGreen/value", 0) + self._set_i2c_register("/sys/class/gpio/fanLedAmber/value", 1) + oldfan = 0x0 + + # Front Panel PSU Panel LED setting in register 0x09 + if (self.chassis.get_psu(0).get_status() == self.chassis.get_psu(1).get_status() == True): + if oldpsu != 0x1: + if (os.path.isfile("/sys/class/gpio/psuLedAmber/value")): + self._set_i2c_register("/sys/class/gpio/psuLedAmber/value", 0) + self._set_i2c_register("/sys/class/gpio/psuLedGreen/value", 1) + oldpsu = 0x1 + else: + if oldpsu != 0x0: + if (os.path.isfile("/sys/class/gpio/psuLedGreen/value")): + self._set_i2c_register("/sys/class/gpio/psuLedGreen/value", 0) + self._set_i2c_register("/sys/class/gpio/psuLedAmber/value", 1) + oldpsu = 0x0 + time.sleep(6) + + # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): + # Strip "Ethernet" off port name + if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): + return -1 + + port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) + return port_idx + + def _port_state_to_mode(self, port_idx, state): + DBG_PRINT("_port_state_to_mode") + + def _port_led_mode_update(self, port_idx, ledMode): + DBG_PRINT("_port_led_mode_update") + + # called when port states change- implementation of port_link_state_change() method if needed + def port_link_state_change(self, portname, state): + # DBG_PRINT("port_link_state_change ") + return diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/psuutil.py b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/psuutil.py new file mode 100755 index 000000000000..513b3ae4085b --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/psuutil.py @@ -0,0 +1,32 @@ +try: + import sonic_platform.platform + import sonic_platform.chassis + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + self.chassis = sonic_platform.platform.Platform().get_chassis() + + def get_num_psus(self): + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + # print " psuUtil redirect to PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_psu(index-1).get_status() + else: + return False + + def get_psu_presence(self, index): + # print " psuUtil redirect to PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_psu(index-1).get_presence() + else: + return False diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/sfputil.py b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/sfputil.py new file mode 100755 index 000000000000..9b12e38226d5 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/sfputil.py @@ -0,0 +1,65 @@ +try: + import sonic_platform.platform + import sonic_platform.chassis + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + + _port_start = 49 + _port_end = 52 + ports_in_block = 4 + + _port_to_eeprom_mapping = {} + _changed_ports = [0, 0, 0, 0] + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return range(0, 0) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + # print " SfpUtil(SfpUtilBase) re-directed to chassis PMON 2.0 " + SfpUtilBase.__init__(self) + self.chassis = sonic_platform.platform.Platform().get_chassis() + + def reset(self, port_num): + # print " SfpUtil(SfpUtilBase) re-directed to chassis PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_sfp(port_num).reset() + else: + return False + + def set_low_power_mode(self, port_nuM, lpmode): + # print " SfpUtil(SfpUtilBase) targeted for deprecation " + return False + + def get_low_power_mode(self, port_num): + # print " SfpUtil(SfpUtilBase) targeted for deprecation " + return False + + def get_presence(self, port_num): + # print " SfpUtil(SfpUtilBase) re-directed to chassis PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_sfp(port_num).get_presence() + else: + return False + + def get_transceiver_change_event(self, timeout): + # print " SfpUtil(SfpUtilBase) targeted for deprecation " + + raise NotImplementedError diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/sensors.conf b/device/nokia/armhf-nokia_ixs7215_52x-r0/sensors.conf new file mode 100644 index 000000000000..de73eab6e987 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/sensors.conf @@ -0,0 +1,19 @@ +chip "adt7473-*" + label fan1 "rear fan 1" + label fan2 "rear fan 2" + ignore fan3 + ignore fan4 + ignore in1 + +chip "lm75a-i2c-*-4a" + label temp1 "MAC temp sensor" + set temp1_max 65 + set temp1_crit 75 + +chip "lm75a-i2c-*-4b" + label temp1 "Board temp sensor" + set temp2_max 65 + set temp2_crit 75 + +chip "armada_thermal-*" + ignore temp1 diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/thermal_policy.json b/device/nokia/armhf-nokia_ixs7215_52x-r0/thermal_policy.json new file mode 100644 index 000000000000..fb6e044e266c --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/thermal_policy.json @@ -0,0 +1,65 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "false", + "fan_speed_when_suspend": "50" + }, + "info_types": [ + { + "type": "fan_info" + }, + { + "type": "thermal_info" + }, + { + "type": "chassis_info" + } + ], + "policies": [ + { + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "all fan presence", + "conditions": [ + { + "type": "fan.all.presence" + } + ], + "actions": [ + { + "type": "thermal.temp_check_and_set_all_fan_speed", + "default_speed": "50", + "hightemp_speed": "100" + } + ] + }, + { + "name": "temp over high critical threshold", + "conditions": [ + { + "type": "thermal.over.high_critical_threshold" + } + ], + "actions": [ + { + "type": "switch.shutdown" + } + ] + } + ] +} diff --git a/platform/marvell-armhf/one-image.mk b/platform/marvell-armhf/one-image.mk index 000ac9ea3e18..44bcd9595281 100644 --- a/platform/marvell-armhf/one-image.mk +++ b/platform/marvell-armhf/one-image.mk @@ -5,7 +5,8 @@ $(SONIC_ONE_IMAGE)_MACHINE = marvell-armhf $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_INSTALLS += $(LINUX_KERNEL_DTB) -$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(ET6448M_PLATFORM) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(ET6448M_PLATFORM) \ + $(NOKIA_7215_PLATFORM) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/marvell-armhf/platform-nokia.mk b/platform/marvell-armhf/platform-nokia.mk new file mode 100644 index 000000000000..7e7df9cb13cc --- /dev/null +++ b/platform/marvell-armhf/platform-nokia.mk @@ -0,0 +1,11 @@ +# Nokia Platform + +NOKIA_7215_PLATFORM_VERSION = 1.0 +export NOKIA_7215_PLATFORM_VERSION + +NOKIA_7215_PLATFORM = sonic-platform-nokia-7215_$(NOKIA_7215_PLATFORM_VERSION)_$(CONFIGURED_ARCH).deb +$(NOKIA_7215_PLATFORM)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-nokia +$(NOKIA_7215_PLATFORM)_PLATFORM = armhf-nokia_ixs7215_52x-r0 +SONIC_DPKG_DEBS += $(NOKIA_7215_PLATFORM) + +SONIC_STRETCH_DEBS += $(NOKIA_7215_PLATFORM) diff --git a/platform/marvell-armhf/platform.conf b/platform/marvell-armhf/platform.conf index 7799b33d57d9..b702656fa973 100644 --- a/platform/marvell-armhf/platform.conf +++ b/platform/marvell-armhf/platform.conf @@ -100,7 +100,11 @@ prepare_boot_menu() { fw_setenv ${FW_ARG} sonic_version_2 $sonic_version_2 > /dev/null BOOT1='echo " > Boot1: $sonic_version_1 - run sonic_image_1";echo;' BOOT2='echo " > Boot2: $sonic_version_2 - run sonic_image_2";echo;' - BOOT3='echo " > Boot3: ONIE - run onie_nand_boot";echo;' + if [ "$PLATFORM" = "armhf-nokia_ixs7215_52x-r0" ]; then + BOOT3='echo " > Boot3: ONIE - run onie_bootcmd";echo;' + else + BOOT3='echo " > Boot3: ONIE - run onie_nand_boot";echo;' + fi BORDER='echo "---------------------------------------------------";echo;' fw_setenv ${FW_ARG} print_menu $BORDER $BOOT1 $BOOT2 $BOOT3 $BORDER > /dev/null diff --git a/platform/marvell-armhf/rules.mk b/platform/marvell-armhf/rules.mk index 9204955d9ccc..9f8cf775ae7d 100644 --- a/platform/marvell-armhf/rules.mk +++ b/platform/marvell-armhf/rules.mk @@ -8,6 +8,7 @@ include $(PLATFORM_PATH)/docker-ptf-mrvl.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/linux-kernel-armhf.mk include $(PLATFORM_PATH)/platform-et6448m.mk +include $(PLATFORM_PATH)/platform-nokia.mk INCLUDE_SYSTEM_TELEMETRY = "" ENABLE_SYNCD_RPC = "" diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/scripts/nokia-7215init.sh b/platform/marvell-armhf/sonic-platform-nokia/7215/scripts/nokia-7215init.sh new file mode 100755 index 000000000000..43cd86d59bd0 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/scripts/nokia-7215init.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Platform init script for Nokia IXS 7215 + +# Load required kernel-mode drivers +load_kernel_drivers() { + # Remove modules loaded during Linux init + # FIX-ME: This will be removed in the future when Linux init no longer loads these + rmmod i2c_mux_gpio + rmmod i2c_dev + rmmod i2c_mv64xxx + + # Carefully control the load order here to ensure consistent i2c bus numbering + modprobe i2c_mv64xxx + modprobe i2c_dev + modprobe i2c_mux_gpio + modprobe eeprom +} + + +nokia_7215_profile() +{ + MAC_ADDR=$(sudo decode-syseeprom -m) + sed -i "s/switchMacAddress=.*/switchMacAddress=$MAC_ADDR/g" /usr/share/sonic/device/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini + echo "Nokia-7215: Updating switch mac address ${MAC_ADDR}" +} + +# - Main entry + +# Install kernel drivers required for i2c bus access +load_kernel_drivers + +# LOGIC to enumerate SFP eeprom devices - send 0x50 to kernel i2c driver - initialize devices +# the mux may be enumerated at number 4 or 5 so we check for the mux and skip if needed + +# Get list of the mux channels +ismux_bus=$(i2cdetect -l|grep mux|cut -f1) + +# Enumerate the SFP eeprom device on each mux channel +for mux in ${ismux_bus} +do + echo optoe2 0x50 > /sys/class/i2c-adapter/${mux}/new_device +done + +# Enumerate system eeprom +echo 24c02 0x53 > /sys/class/i2c-adapter/i2c-0/new_device +sleep 2 +chmod 644 /sys/class/i2c-adapter/i2c-0/0-0053/eeprom + +# Enumerate fan eeprom devices +echo eeprom 0x55 > /sys/class/i2c-adapter/i2c-0/new_device +echo eeprom 0x56 > /sys/class/i2c-adapter/i2c-0/new_device + +# Enable optical SFP Tx +i2cset -y -m 0x0f 0 0x41 0x5 0x00 + +# Ensure switch is programmed with chassis base MAC addr +nokia_7215_profile + +echo "Nokia-7215 - completed platform init script" +exit 0 diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/service/nokia-7215init.service b/platform/marvell-armhf/sonic-platform-nokia/7215/service/nokia-7215init.service new file mode 100644 index 000000000000..8b17dbc8edc0 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/service/nokia-7215init.service @@ -0,0 +1,14 @@ +[Unit] +Description=Nokia-7215 Platform Service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/nokia-7215init.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL +#StandardOutput=tty + +[Install] +WantedBy=multi-user.target diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/setup.py b/platform/marvell-armhf/sonic-platform-nokia/7215/setup.py new file mode 100755 index 000000000000..65f4853bec83 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Nokia IXS 7215 platforms', + + packages=['sonic_platform','sonic_platform.test'], + package_dir={'sonic_platform': '7215/sonic_platform'}, +) + diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/__init__.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/__init__.py new file mode 100755 index 000000000000..139597f9cb07 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/__init__.py @@ -0,0 +1,2 @@ + + diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/chassis.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/chassis.py new file mode 100755 index 000000000000..7597492cc003 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/chassis.py @@ -0,0 +1,377 @@ +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import os + import sys + import glob + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan + from .fan_drawer import VirtualDrawer + from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal + from sonic_platform.component import Component + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +smbus_present = 1 +try: + import smbus +except ImportError as e: + smbus_present = 0 + +MAX_SELECT_DELAY = 3600 +COPPER_PORT_START = 1 +COPPER_PORT_END = 48 +SFP_PORT_START = 49 +SFP_PORT_END = 52 +PORT_END = 52 + +# Device counts +MAX_7215_FAN_DRAWER = 1 +MAX_7215_FAN = 2 +MAX_7215_PSU = 2 +MAX_7215_THERMAL = 6 + +# Temp - disable these to help with early debug +MAX_7215_COMPONENT = 2 + +SYSLOG_IDENTIFIER = "chassis" +sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) + + +class Chassis(ChassisBase): + """ + Nokia platform-specific Chassis class + Derived from Dell S6000 platform. + customized for the 7215 platform. + """ + + def __init__(self): + ChassisBase.__init__(self) + self.system_led_supported_color = ['off', 'amber', 'green', 'amber_blink', 'green_blink'] + # Port numbers for SFP List Initialization + self.COPPER_PORT_START = COPPER_PORT_START + self.COPPER_PORT_END = COPPER_PORT_END + self.SFP_PORT_START = SFP_PORT_START + self.SFP_PORT_END = SFP_PORT_END + self.PORT_END = PORT_END + + # for non-sfp ports create dummy objects for copper / non-sfp ports + for index in range(self.COPPER_PORT_START, self.COPPER_PORT_END+1): + sfp_node = Sfp(index, 'COPPER', 'N/A', 'N/A') + self._sfp_list.append(sfp_node) + + # Verify optoe2 driver SFP eeprom devices were enumerated and exist + # then create the sfp nodes + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + mux_dev = sorted(glob.glob("/sys/class/i2c-adapter/i2c-0/i2c-[0-9]")) + y = 0 + for index in range(self.SFP_PORT_START, self.SFP_PORT_END+1): + mux_dev_num = mux_dev[y] + port_i2c_map = mux_dev_num[-1] + y = y + 1 + port_eeprom_path = eeprom_path.format(port_i2c_map) + if not os.path.exists(port_eeprom_path): + sonic_logger.log_info("path %s didnt exist" % port_eeprom_path) + sfp_node = Sfp(index, 'SFP', port_eeprom_path, port_i2c_map) + self._sfp_list.append(sfp_node) + self.sfp_event_initialized = False + + # Instantiate system eeprom object + self._eeprom = Eeprom() + + # Construct lists fans, power supplies, thermals & components + drawer_num = MAX_7215_FAN_DRAWER + fan_num_per_drawer = MAX_7215_FAN + drawer_ctor = VirtualDrawer + fan_index = 0 + for drawer_index in range(drawer_num): + drawer = drawer_ctor(drawer_index) + self._fan_drawer_list.append(drawer) + for index in range(fan_num_per_drawer): + fan = Fan(fan_index, drawer) + fan_index += 1 + drawer._fan_list.append(fan) + self._fan_list.append(fan) + + for i in range(MAX_7215_PSU): + psu = Psu(i) + self._psu_list.append(psu) + + for i in range(MAX_7215_THERMAL): + thermal = Thermal(i) + self._thermal_list.append(thermal) + + for i in range(MAX_7215_COMPONENT): + component = Component(i) + self._component_list.append(component) + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of physical SFP ports in a + chassis starting from 1. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + # The index will start from 1 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this + chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the + chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their + corresponding values. + """ + return self._eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + # The ixs7215 CPLD does not have a hardware reboot cause register so + # the hardware portion of reboot cause can't be implemented + + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + # Initialize SFP event first + if not self.sfp_event_initialized: + from sonic_platform.sfp_event import sfp_event + self.sfp_event = sfp_event() + self.sfp_event.initialize() + self.MAX_SELECT_EVENT_RETURNED = self.PORT_END + self.sfp_event_initialized = True + + wait_for_ever = (timeout == 0) + port_dict = {} + if wait_for_ever: + # xrcvd will call this monitor loop in the "SYSTEM_READY" state + timeout = MAX_SELECT_DELAY + while True: + status = self.sfp_event.check_sfp_status(port_dict, timeout) + if not port_dict == {}: + break + else: + # At boot up and in "INIT" state call from xrcvd will have timeout + # value return true without change after timeout and will + # transition to "SYSTEM_READY" + status = self.sfp_event.check_sfp_status(port_dict, timeout) + + if status: + return True, {'sfp': port_dict} + else: + return True, {'sfp': {}} + + def get_thermal_manager(self): + from .thermal_manager import ThermalManager + return ThermalManager + + def set_status_led(self, color): + """ + Sets the state of the system LED + + Args: + color: A string representing the color with which to set the + system LED + + Returns: + bool: True if system LED state is set successfully, False if not + """ + if color not in self.system_led_supported_color: + return False + + if (color == 'off'): + value = 0x00 + elif (color == 'amber'): + value = 0x01 + elif (color == 'green'): + value = 0x02 + elif (color == 'amber_blink'): + value = 0x03 + elif (color == 'green_blink'): + value = 0x04 + else: + return False + + # Write sys led + if smbus_present == 0: + sonic_logger.log_info("PMON LED SET ERROR-> smbus present = 0") + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICEREG = 0x7 + bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, value) + sonic_logger.log_info(" System LED set O.K. ") + return True + + return False + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + # Read sys led + if smbus_present == 0: + sonic_logger.log_info("PMON LED GET ERROR-> smbus present = 0") + return False + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x7 + value = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if value == 0x00: + color = 'off' + elif value == 0x01: + color = 'amber' + elif value == 0x02: + color = 'green' + elif value == 0x03: + color = 'amber_blink' + elif value == 0x04: + color = 'green_blink' + else: + return False + + return color + + def get_watchdog(self): + """ + Retrieves hardware watchdog device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + + Note: + We overload this method to ensure that watchdog is only initialized + when it is referenced. Currently, only one daemon can open the + watchdog. To initialize watchdog in the constructor causes multiple + daemon try opening watchdog when loading and constructing a chassis + object and fail. By doing so we can eliminate that risk. + """ + try: + if self._watchdog is None: + from sonic_platform.watchdog import WatchdogImplBase + watchdog_device_path = "/dev/watchdog0" + self._watchdog = WatchdogImplBase(watchdog_device_path) + except Exception as e: + sonic_logger.log_info("Fail to load watchdog {}".format(repr(e))) + + return self._watchdog diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/component.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/component.py new file mode 100644 index 000000000000..6a5410458df7 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/component.py @@ -0,0 +1,119 @@ +######################################################################## +# NOKIA IXS7215 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import os + import sys + import subprocess + import ntpath + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +try: + import smbus +except ImportError as e: + smbus_present = 0 + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + + +class Component(ComponentBase): + """Nokia platform-specific Component class""" + + CHASSIS_COMPONENTS = [ + ["System-CPLD", "Used for managing SFPs, LEDs, PSUs and FANs "], + ["U-Boot", "Performs initialization during booting"], + ] + + def __init__(self, component_index): + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_cpld_version(self, cpld_number): + + if smbus_present == 0: + cmdstatus, cpld_version = cmd.getstatusoutput('i2cget -y 0 0x41 0x2') + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x2 + cpld_version = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + return str(int(cpld_version, 16)) + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + if self.index == 0: + return self._get_cpld_version(self.index) + + if self.index == 1: + cmdstatus, uboot_version = cmd.getstatusoutput('grep --null-data U-Boot /dev/mtd0ro|head -1 | cut -c 1-30') + return uboot_version + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + image_name = ntpath.basename(image_path) + print(" ixs7215 - install cpld {}".format(image_name)) + + # check whether the image file exists + if not os.path.isfile(image_path): + print("ERROR: the cpld image {} doesn't exist ".format(image_path)) + return False + + success_flag = False + + return success_flag diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/eeprom.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/eeprom.py new file mode 100644 index 000000000000..912c18666f4e --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/eeprom.py @@ -0,0 +1,235 @@ +######################################################################## +# Nokia IXR7220_D1 +# +# Module contains platform specific implementation of SONiC Platform +# Base API and provides the EEPROMs' information. +# +# The different EEPROMs available are as follows: +# - System EEPROM : Contains Serial number, Service tag, Base MA +# address, etc. in ONIE TlvInfo EEPROM format. +# - PSU EEPROM : Contains Serial number, Part number, Service Tag, +# PSU type, Revision. +# - Fan EEPROM : Contains Serial number, Part number, Service Tag, +# Fan type, Number of Fans in Fantray, Revision. +######################################################################## + + +try: + from sonic_platform_base.sonic_eeprom.eeprom_base import EepromDecoder + from sonic_platform_base.sonic_eeprom.eeprom_tlvinfo import TlvInfoDecoder +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +# PSU eeprom fields in format required by EepromDecoder +psu_eeprom_format = [ + ('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7), + ('Part Number', 's', 10), ('Part Num Revision', 's', 3), + ('Mfg Test', 's', 2), ('Redundant copy', 's', 83), ('PSU Type', 's', 1), + ('Fab Rev', 's', 2) + ] + +# Fan eeprom fields in format required by EepromDecoder +fan_eeprom_format = [ + ('Model', 's', 12), ('Serial Number', 's', 13) + ] + + +class Eeprom(TlvInfoDecoder): + """Nokia platform-specific EEPROM class""" + + I2C_DIR = "/sys/class/i2c-adapter/" + + def __init__(self, is_psu=False, psu_index=0, is_fan=False, fan_index=0): + self.is_psu_eeprom = is_psu + self.is_fan_eeprom = is_fan + self.is_sys_eeprom = not (is_psu | is_fan) + + if self.is_sys_eeprom: + self.start_offset = 0 + self.eeprom_path = self.I2C_DIR + "i2c-0/0-0053/eeprom" + # System EEPROM is in ONIE TlvInfo EEPROM format + super(Eeprom, self).__init__(self.eeprom_path, + self.start_offset, '', True) + self._load_system_eeprom() + else: + if self.is_psu_eeprom: + self.index = psu_index + self.start_offset = 6 + self.eeprom_path = self.I2C_DIR \ + + "i2c-1/1-005{}/eeprom".format(2 - self.index) + self.format = psu_eeprom_format + else: + self.index = fan_index + self.start_offset = 13 + self.eeprom_path = self.I2C_DIR \ + + "i2c-4{0}/4{0}-0050/eeprom".format(self.index - 1) + self.format = fan_eeprom_format + EepromDecoder.__init__(self, self.eeprom_path, self.format, + self.start_offset, '', True) + self._load_device_eeprom() + + def _load_system_eeprom(self): + """ + Reads the system EEPROM and retrieves the values corresponding + to the codes defined as per ONIE TlvInfo EEPROM format and fills + them in a dictionary. + """ + try: + # Read System EEPROM as per ONIE TlvInfo EEPROM format. + self.eeprom_data = self.read_eeprom() + except Exception as e: + self.base_mac = 'NA' + self.serial_number = 'NA' + self.part_number = 'NA' + self.model_str = 'NA' + self.serial = 'NA' + self.eeprom_tlv_dict = dict() + else: + eeprom = self.eeprom_data + self.eeprom_tlv_dict = dict() + + if not self.is_valid_tlvinfo_header(eeprom): + self.base_mac = 'NA' + self.serial_number = 'NA' + self.part_number = 'NA' + self.model_str = 'NA' + self.serial = 'NA' + return + + total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + ord(eeprom[tlv_index + 1])] + code = "0x%02X" % (ord(tlv[0])) + + if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | + (ord(tlv[4]) << 8) | ord(tlv[5])) + value += str(tlv[6:6 + ord(tlv[1])]) + else: + name, value = self.decoder(None, tlv) + + self.eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+1]) + 2 + + self.base_mac = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_MAC_BASE), 'NA') + self.serial_number = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_SERIAL_NUMBER), 'NA') + self.part_number = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_PART_NUMBER), 'NA') + self.model_str = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_PRODUCT_NAME), 'NA') + self.serial = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_SERVICE_TAG), 'NA') + + def _load_device_eeprom(self): + """ + Reads the Fan/PSU EEPROM and retrieves the serial number and + model number of the device. + """ + try: + # Read Fan/PSU EEPROM as per the specified format. + self.eeprom_data = EepromDecoder.read_eeprom(self) + except Exception as e: + self.serial_number = 'NA' + self.part_number = 'NA' + self.model_str = 'NA' + self.serial = 'NA' + else: + (valid, data) = self._get_eeprom_field("Model") + if valid: + self.model_str = data + else: + self.model_str = 'NA' + + (valid, data) = self._get_eeprom_field("Serial Number") + if valid: + self.serial_number = data + else: + self.serial_number = 'NA' + + if self.is_psu_eeprom: + (valid, data) = self._get_eeprom_field("PSU Type") + if valid: + self.psu_type = data + else: + self.psu_type = 'NA' + else: + (valid, data) = self._get_eeprom_field("Fan Type") + if valid: + self.fan_type = data + else: + self.fan_type = 'NA' + + def _get_eeprom_field(self, field_name): + """ + For a field name specified in the EEPROM format, returns the + presence of the field and the value for the same. + """ + field_start = 0 + for field in self.format: + field_end = field_start + field[2] + if field[0] == field_name: + return (True, self.eeprom_data[field_start:field_end]) + field_start = field_end + + return (False, None) + + def serial_number_str(self): + """ + Returns the serial number. + """ + return self.serial_number + + def part_number_str(self): + """ + Returns the part number. + """ + return self.part_number + + def airflow_fan_type(self): + """ + Returns the airflow fan type. + """ + if self.is_psu_eeprom: + return int(self.psu_type.encode('hex'), 16) + else: + return int(self.fan_type.encode('hex'), 16) + + # System EEPROM specific methods + def base_mac_addr(self): + """ + Returns the base MAC address found in the system EEPROM. + """ + return self.base_mac + + def modelstr(self): + """ + Returns the Model name. + """ + return self.model_str + + def serial_str(self): + """ + Returns the servicetag number. + """ + return self.serial + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.eeprom_tlv_dict diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan.py new file mode 100644 index 000000000000..0b08f3f6b4f2 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan.py @@ -0,0 +1,330 @@ +######################################################################## +# Nokia 7215 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.fan_base import FanBase + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +smbus_present = 1 +try: + import smbus +except ImportError as e: + smbus_present = 0 + +MAX_IXS7215_FAN_SPEED = 19000 +WORKING_IXS7215_FAN_SPEED = 960 + +sonic_logger = logger.Logger('fan') + + +class Fan(FanBase): + """Nokia platform-specific Fan class""" + + def __init__(self, fan_index, fan_drawer, psu_fan=False, dependency=None): + self.is_psu_fan = psu_fan + ADT7473_DIR = "/sys/bus/i2c/devices/0-002e/" + + if not self.is_psu_fan: + # Fan is 1-based in Nokia platforms + self.index = fan_index + 1 + self.fan_drawer = fan_drawer + self.set_fan_speed_reg = ADT7473_DIR+"pwm{}".format(self.index) + self.get_fan_speed_reg = ADT7473_DIR+"fan{}_input".format(self.index) + self.max_fan_speed = MAX_IXS7215_FAN_SPEED + self.supported_led_color = ['off', 'green', 'red'] + else: + # this is a PSU Fan + self.index = fan_index + self.dependency = dependency + + def _get_i2c_register(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _set_i2c_register(self, reg_file, value): + # On successful write, the value read will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'w') as fd: + rv = fd.write(str(value)) + except Exception as e: + rv = 'ERR' + + return rv + + def get_name(self): + """ + Retrieves the name of the Fan + + Returns: + string: The name of the Fan + """ + if not self.is_psu_fan: + return "Fan{}".format(self.index) + else: + return "PSU{} Fan".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Fan Unit + + Returns: + bool: True if Fan is present, False if not + """ + if smbus_present == 0: + sonic_logger.log_info("PMON fan-smbus ERROR - presence ") + return False + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xb + fanstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + fanstatus = fanstatus & 1 + if fanstatus == 1: + return False + if self.index == 2: + fanstatus = fanstatus & 2 + if fanstatus == 2: + return False + return True + + def get_model(self): + """ + Retrieves the model number of the Fan + + Returns: + string: Part number of Fan + """ + + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the Fan + + Returns: + string: Serial number of Fan + """ + + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the Fan + + Returns: + bool: True if Fan is operating properly, False if not + """ + status = False + + fan_speed = self._get_i2c_register(self.get_fan_speed_reg) + if (fan_speed != 'ERR'): + if (int(fan_speed) > WORKING_IXS7215_FAN_SPEED): + status = True + + return status + + def get_direction(self): + """ + Retrieves the fan airflow direction + Possible fan directions (relative to port-side of device) + Returns: + A string, either FAN_DIRECTION_INTAKE or + FAN_DIRECTION_EXHAUST depending on fan direction + """ + + return 'FAN_DIRECTION_INTAKE' + + def get_speed(self): + """ + Retrieves the speed of a Front FAN in the tray in revolutions per + minute defined by 1-based index + :param index: An integer, 1-based index of the FAN to query speed + :return: integer, denoting front FAN speed + """ + speed = 0 + + fan_speed = self._get_i2c_register(self.get_fan_speed_reg) + if (fan_speed != 'ERR'): + speed = int(fan_speed) + else: + speed = 0 + + return speed + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed + which is considered tolerable + """ + if self.get_presence(): + # The tolerance value is fixed as 25% for this platform + tolerance = 25 + else: + tolerance = 0 + + return tolerance + + def set_speed(self, speed): + """ + Set fan speed to expected value + Args: + speed: An integer, the percentage of full fan speed to set + fan to, in the range 0 (off) to 100 (full speed) + Returns: + bool: True if set success, False if fail. + """ + if self.is_psu_fan: + return False + + # Set current fan duty cycle + # - 0x00 : fan off + # - 0x40 : 25% duty cycle + # - 0x80 : 50% duty cycle (default) + # - 0xff : 100% duty cycle (full speed) + if speed in range(0, 6): + fandutycycle = 0x00 + elif speed in range(6, 41): + fandutycycle = 64 + elif speed in range(41, 76): + fandutycycle = 128 + elif speed in range(76, 101): + fandutycycle = 255 + else: + return False + + rv = self._set_i2c_register(self.set_fan_speed_reg, fandutycycle) + if (rv != 'ERR'): + return True + else: + return False + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if set success, False if fail. + + off , red and green are the only settings 7215 fans + """ + + if self.is_psu_fan or (color not in self.supported_led_color): + return False + if (color == self.STATUS_LED_COLOR_AMBER): + return False + if (color == self.STATUS_LED_COLOR_RED): + value = 0x02 + elif (color == self.STATUS_LED_COLOR_GREEN): + value = 0x01 + elif (color == self.STATUS_LED_COLOR_OFF): + value = 0x00 + else: + return False + + if smbus_present == 0: + return False + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICEREG = 0x8 + original = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + if (self.index == 1): + new = value << 4 + ledstatus = original & 0xcf + ledstatus = ledstatus | new + elif self.index == 2: + new = value << 6 + ledstatus = original & 0x3f + ledstatus = ledstatus | new + else: + return False + + bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, ledstatus) + + return True + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + + if self.is_psu_fan: + return False + + if smbus_present == 0: + return False + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x8 + ledstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + ledstatus = (ledstatus & 0x30) + ledstatus = ledstatus >> 4 + elif self.index == 2: + ledstatus = (ledstatus & 0xC0) + ledstatus = ledstatus >> 6 + if ledstatus == 0x02: + return self.STATUS_LED_COLOR_RED + elif ledstatus == 0x1: + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 + (off) to 100 (full speed) + """ + speed = 0 + + fan_speed = self._get_i2c_register(self.get_fan_speed_reg) + if (fan_speed != 'ERR'): + speed = int(fan_speed) + else: + speed = 0 + + return speed diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan_drawer.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..ea0bc71bea5c --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan_drawer.py @@ -0,0 +1,47 @@ +############################################################################# +# Nokia +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan Drawer status which is available in the platform +# +############################################################################# + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class NokiaFanDrawer(FanDrawerBase): + def __init__(self, index): + super(NokiaFanDrawer, self).__init__() + self._index = index + 1 + self._led = None + + def get_index(self): + return self._index + + def get_led(self): + return self._led + + +# For Nokia platforms with fan drawer(s) +class RealDrawer(NokiaFanDrawer): + def __init__(self, index): + super(RealDrawer, self).__init__(index) + self._name = 'drawer{}'.format(self._index) + + def get_name(self): + return self._name + + +# For Nokia platforms with no physical fan drawer(s) +class VirtualDrawer(NokiaFanDrawer): + def __init__(self, index): + super(VirtualDrawer, self).__init__(index) + + def get_name(self): + return 'N/A' + + def set_status_led(self, color): + return 'N/A' diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/platform.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/platform.py new file mode 100755 index 000000000000..7a3046bc7391 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/platform.py @@ -0,0 +1,22 @@ +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """ + Nokia platform-specific class + """ + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/psu.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/psu.py new file mode 100644 index 000000000000..4b8029daaa12 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/psu.py @@ -0,0 +1,225 @@ +######################################################################## +# Nokia 7215 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + +try: + import sys + from sonic_platform_base.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +smbus_present = 1 +try: + import smbus +except ImportError as e: + smbus_present = 0 + + +class Psu(PsuBase): + """Nokia platform-specific PSU class for 7215 """ + + def __init__(self, psu_index): + # PSU is 1-based in Nokia platforms + self.index = psu_index + 1 + self._fan_list = [] + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Power Supply Unit (PSU) + + Returns: + bool: True if PSU is present, False if not + """ + + if smbus_present == 0: # if called from psuutil outside of pmon + cmdstatus, psustatus = cmd.getstatusoutput('i2cget -y 0 0x41 0xa') + psustatus = int(psustatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xa + psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + psustatus = psustatus & 1 + if psustatus == 1: + return False + if self.index == 2: + psustatus = psustatus & 2 + if psustatus == 2: + return False + + return True + + def get_model(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + return self.eeprom.modelstr() + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + return self.eeprom.serial_number_str() + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + + if smbus_present == 0: + cmdstatus, psustatus = cmd.getstatusoutput('i2cget -y 0 0x41 0xa') + psustatus = int(psustatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xa + psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + psustatus = psustatus & 4 + if psustatus == 4: + return True + if self.index == 2: + psustatus = psustatus & 8 + if psustatus == 8: + return True + + return False + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + if smbus_present == 0: + cmdstatus, psustatus = cmd.getstatusoutput('i2cget -y 0 0x41 0xa') + psustatus = int(psustatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xa + psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + psustatus = psustatus & 4 + if psustatus == 4: + psu_voltage = 12.0 + return psu_voltage + if self.index == 2: + psustatus = psustatus & 8 + if psustatus == 8: + psu_voltage = 12.0 + return psu_voltage + + psu_voltage = 0.0 + return psu_voltage + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + psu_current = 0.0 + + return psu_current + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + psu_power = 0.0 + + return psu_power + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + Returns: + A boolean, True if PSU has stablized its output voltages and + passed all its internal self-tests, False if not. + """ + + if smbus_present == 0: + cmdstatus, psustatus = cmd.getstatusoutput('i2cget -y 0 0x41 0xa') + psustatus = int(psustatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xa + psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + psustatus = psustatus & 4 + if psustatus == 4: + return True + if self.index == 2: + psustatus = psustatus & 8 + if psustatus == 8: + return True + + return False + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the + PSU status LED + Returns: + bool: True if status LED state is set successfully, False if + not + """ + # In IXR7220_D1, the firmware running in the PSU controls the LED + # and the PSU LED state cannot be changed from CPU. + return False diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp.py new file mode 100644 index 000000000000..51ad34ae8f4c --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp.py @@ -0,0 +1,916 @@ +############################################################################# +# Nokia +# +############################################################################# + +import os +import sys +import time + +try: + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + + +INFO_OFFSET = 128 +DOM_OFFSET = 0 + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 + +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 + +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 + +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 2 +XCVR_INTERFACE_DATA_START = 0 +XCVR_INTERFACE_DATA_SIZE = 92 + +SFP_DOM_BULK_DATA_START = 96 +SFP_DOM_BULK_DATA_SIZE = 10 + +SFP_MODULE_ADDRA2_OFFSET = 256 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_CHANNL_STATUS_OFFSET = 110 +SFP_CHANNL_STATUS_WIDTH = 1 + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +COPPER_TYPE = "COPPER" +SFP_TYPE = "SFP" + +# SFP PORT numbers +SFP_PORT_START = 49 +SFP_PORT_END = 52 + +SYSLOG_IDENTIFIER = "xcvrd" +sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) + + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + """ + Nokia platform-specific Sfp class + """ + + # Paths + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + HOST_CHK_CMD = "docker > /dev/null 2>&1" + + PLATFORM = "armhf-nokia_ixs7215_52x-r0" + HWSKU = "Nokia-7215" + + port_to_i2c_mapping = 0 + + def __init__(self, index, sfp_type, eeprom_path, port_i2c_map): + SfpBase.__init__(self) + + self.index = index + self.port_num = index + self.sfp_type = sfp_type + self.eeprom_path = eeprom_path + self.port_to_i2c_mapping = port_i2c_map + self.port_name = sfp_type + str(index) + self.port_to_eeprom_mapping = {} + + self.port_to_eeprom_mapping[index] = eeprom_path + + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', + 'model', 'connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', + 'nominal_bit_rate', 'specification_compliance', + 'vendor_date', 'vendor_oui'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', + 'tx_disable', 'tx_disable_channel', 'temperature', + 'voltage', 'rx1power', 'rx2power', 'rx3power', + 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', + 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', + 'templowwarning', 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', + 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', + 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning'] + + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + + self._dom_capability_detect() + + def __convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except Exception as e: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + return eeprom_raw + + def _dom_capability_detect(self): + if self.sfp_type == "SFP": + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + return None + sfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) + self.dom_supported = (sfp_dom_capability & 0x40 != 0) + if self.dom_supported: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + if sfp_dom_capability & 0x20 != 0: + self.calibration = 1 + elif sfp_dom_capability & 0x10 != 0: + self.calibration = 2 + else: + self.calibration = 0 + else: + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.dom_tx_disable_supported = ( + int(sfp_dom_capability_raw[1], 16) & 0x40 != 0) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + + if self.sfp_type == COPPER_TYPE: + return None + + compliance_code_dict = {} + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + + if not self.get_presence(): + return transceiver_info_dict + + if self.sfp_type == SFP_TYPE: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) + if sfp_interface_bulk_raw is None: + return None + + start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START + end = start + interface_info_bulk_width + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_NAME_WIDTH + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_PN_WIDTH + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START + end = start + vendor_rev_width + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_SN_WIDTH + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_OUI_WIDTH + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_DATE_WIDTH + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_interface_bulk_raw[start: end], 0) + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + + if self.sfp_type == COPPER_TYPE: + return transceiver_dom_info_dict + + if self.sfp_type == SFP_TYPE: + + if not self.dom_supported: + return transceiver_dom_info_dict + + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + sfpd_obj._calibration_type = self.calibration + + dom_data_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE) + + start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + + start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + + start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_CHANNL_MON_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_data_raw[start: end], 0) + + transceiver_dom_info_dict['temperature'] = self.__convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + transceiver_dom_info_dict['voltage'] = self.__convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value']) + transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXBias']['value']) + transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value']) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') + + if self.sfp_type == COPPER_TYPE: + return transceiver_dom_threshold_info_dict + + if self.sfp_type == SFP_TYPE: + + offset = SFP_MODULE_ADDRA2_OFFSET + + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = sff8472Dom(None, self.calibration) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[ + 'data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + if not self.dom_supported: + return False + if self.sfp_type == COPPER_TYPE: + return False + + if self.sfp_type == SFP_TYPE: + offset = 0 + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + + if dom_channel_monitor_raw is not None: + return False + else: + return True + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + """ + if self.sfp_type == COPPER_TYPE: + return False + + if smbus_present == 0: + sonic_logger.log_info(" PMON - smbus ERROR - ") + cmdstatus, rxlosstatus = cmd.getstatusoutput('i2cget -y 0 0x41 0x4') + rxlosstatus = int(rxlosstatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x4 + rxlosstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + pos = [1, 2, 4, 8] + bit_pos = pos[self.index-SFP_PORT_START] + rxlosstatus = rxlosstatus & (bit_pos) + + if rxlosstatus == 0: + return True + + return False + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + + return False + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + + if self.sfp_type == COPPER_TYPE: + return False + + # Enable optical SFP Tx + if smbus_present == 0: + cmdstatus, disstatus = cmd.getstatusoutput('i2cget -y 0 0x41 0x5') + sonic_logger.log_info(" PMON - smbus ERROR tx- DEBUG ") + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x5 + disstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + pos = [1, 2, 4, 8] + bit_pos = pos[self.index-SFP_PORT_START] + disstatus = disstatus & (bit_pos) + + if disstatus == 0: + return True + + return False + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + return tx_disabled + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + if self.sfp_type == COPPER_TYPE: + return False + if self.sfp_type == SFP_TYPE: + return False + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + if self.sfp_type == COPPER_TYPE: + return False + if self.sfp_type == SFP_TYPE: + return False + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + transceiver_bulk_status = self.get_transceiver_bulk_status() + return transceiver_bulk_status.get("temperature", "N/A") + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + transceiver_bulk_status = self.get_transceiver_bulk_status() + return transceiver_bulk_status.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_bulk_status = self.get_transceiver_bulk_status() + tx1_bs = transceiver_bulk_status.get("tx1bias", "N/A") + tx2_bs = transceiver_bulk_status.get("tx2bias", "N/A") + tx3_bs = transceiver_bulk_status.get("tx3bias", "N/A") + tx4_bs = transceiver_bulk_status.get("tx4bias", "N/A") + tx_bias_list = [tx1_bs, tx2_bs, tx3_bs, tx4_bs] + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + if self.sfp_type == COPPER_TYPE: + return None + + if self.sfp_type == SFP_TYPE: + + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + rx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value'])) + else: + return None + else: + return None + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + + if self.sfp_type == COPPER_TYPE: + return None + + if self.sfp_type == SFP_TYPE: + + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + tx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value'])) + else: + return None + else: + return None + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + if self.sfp_type == COPPER_TYPE: + return False + + path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/sfp_port_reset" + port_ps = path.format(self.port_to_i2c_mapping) + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + # print "Error: unable to open file: %s" % str(e) + return False + + # toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + if self.sfp_type == COPPER_TYPE: + return False + if self.sfp_type == SFP_TYPE: + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + + return False + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence + Returns: + bool: True if is present, False if not + """ + if self.sfp_type == COPPER_TYPE: + return False + + if smbus_present == 0: # if called from sfputil outside of pmon + cmdstatus, sfpstatus = cmd.getstatusoutput('i2cget -y 0 0x41 0x3') + sfpstatus = int(sfpstatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x3 + sfpstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + pos = [1, 2, 4, 8] + bit_pos = pos[self.index-SFP_PORT_START] + sfpstatus = sfpstatus & (bit_pos) + + if sfpstatus == 0: + return True + + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("model", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("serial", "N/A") + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp_event.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp_event.py new file mode 100644 index 000000000000..ed2143886760 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp_event.py @@ -0,0 +1,117 @@ +''' +listen for the SFP change event and return to chassis. +''' +import sys +import time +from sonic_py_common import logger + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +# system level event/error +EVENT_ON_ALL_SFP = '-1' +SYSTEM_NOT_READY = 'system_not_ready' +SYSTEM_READY = 'system_become_ready' +SYSTEM_FAIL = 'system_fail' + +# SFP PORT numbers +SFP_PORT_START = 49 +SFP_PORT_END = 52 + +SYSLOG_IDENTIFIER = "sfp_event" +sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) + + +class sfp_event: + ''' Listen to plugin/plugout cable events ''' + + def __init__(self): + self.handle = None + + def initialize(self): + self.modprs_register = 0 + # Get Transceiver status + time.sleep(5) + self.modprs_register = self._get_transceiver_status() + sonic_logger.log_info("Initial SFP presence=%d" % self.modprs_register) + + def deinitialize(self): + if self.handle is None: + return + + def _get_transceiver_status(self): + if smbus_present == 0: + sonic_logger.log_info(" PMON - smbus ERROR - DEBUG sfp_event ") + cmdstatus, sfpstatus = cmd.getstatusoutput('i2cget -y 0 0x41 0x3') + sfpstatus = int(sfpstatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x3 + sfpstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + sfpstatus = ~sfpstatus + sfpstatus = sfpstatus & 0xF + + return sfpstatus + + def check_sfp_status(self, port_change, timeout): + """ + check_sfp_status called from get_change_event, this will return correct + status of all 4 SFP ports if there is a change in any of them + """ + start_time = time.time() + port = SFP_PORT_START + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + return False, {} + end_time = start_time + timeout + + if (start_time > end_time): + return False, {} # Time wrap or possibly incorrect timeout + + while (timeout >= 0): + # Check for OIR events and return updated port_change + reg_value = self._get_transceiver_status() + if (reg_value != self.modprs_register): + changed_ports = (self.modprs_register ^ reg_value) + while (port >= SFP_PORT_START and port <= SFP_PORT_END): + # Mask off the bit corresponding to our port + mask = (1 << port-SFP_PORT_START) + if (changed_ports & mask): + # ModPrsL is active high + if reg_value & mask == 0: + port_change[port] = '0' + else: + port_change[port] = '1' + port += 1 + + # Update reg value + self.modprs_register = reg_value + return True, port_change + + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, {} + return False, {} diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/README b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/README new file mode 100644 index 000000000000..3efc8fabce08 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/README @@ -0,0 +1 @@ +This directory contains unit tests of the Platform API 2.0 diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-chassis.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-chassis.py new file mode 100755 index 000000000000..ee7c21c4638d --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-chassis.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python + +try: + import sonic_platform.platform + import sonic_platform.chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +def main(): + print("-----------------") + print("Chassis Unit Test") + print("-----------------") + + chassis = sonic_platform.platform.Platform().get_chassis() + print(" Chassis name: {}".format(chassis.get_name())) + + print(" Chassis presence: {}".format(chassis.get_presence())) + + print(" Chassis model: {}".format(chassis.get_model())) + + print(" Chassis serial: {}".format(chassis.get_serial())) + + print(" Chassis status: {}".format(chassis.get_status())) + + print(" Chassis serial_number: {}".format(chassis.get_serial_number())) + + print(" Chassis base_mac: {}".format(chassis.get_base_mac())) + + print(" Chassis reboot cause: {}\n".format(chassis.get_reboot_cause())) + + print(" Chassis watchdog: {}".format(chassis.get_watchdog())) + + print(" Chassis num_components: {}".format(chassis.get_num_components())) + + print(" Chassis all_components: {}\n".format(chassis.get_all_components())) + + print(" Chassis num_modules: {}".format(chassis.get_num_modules())) + + print(" Chassis all_modules: {}\n".format(chassis.get_all_modules())) + + print(" Chassis num_fans: {}".format(chassis.get_num_fans())) + + print(" Chassis all_fans: {}\n".format(chassis.get_all_fans())) + + print(" Chassis num_thermals: {}".format(chassis.get_num_thermals())) + + print(" Chassis all_thermals: {}\n".format(chassis.get_all_thermals())) + + print(" Chassis num_sfps: {}".format(chassis.get_num_sfps())) + + print(" Chassis all_sfps: {}\n".format(chassis.get_all_sfps())) + + print(" Chassis eeprom: {}".format(chassis.get_eeprom())) + + print(" Chassis system_eeprom_info: {}\n".format(chassis.get_system_eeprom_info())) + + print(" Chassis get_status_led start : {}\n".format(chassis.get_status_led())) + chassis.set_status_led('amber') + print(" Chassis get_status_led amber: {}\n".format(chassis.get_status_led())) + chassis.set_status_led('green') + print(" Chassis get_status_led green: {}\n".format(chassis.get_status_led())) + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-component.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-component.py new file mode 100755 index 000000000000..edc9e03b3f66 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-component.py @@ -0,0 +1,17 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("---------------------------") + print("Chassis Component Unit Test") + print("---------------------------") + + chassis = Chassis() + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-eeprom.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-eeprom.py new file mode 100755 index 000000000000..76f3d8995e4a --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-eeprom.py @@ -0,0 +1,25 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("------------------------") + print("Chassis eeprom Unit Test") + print("------------------------") + + chassis = Chassis() + + eeprom = chassis.get_eeprom() + + print " Model: {}, Serial: {}".format(eeprom.modelstr(), + eeprom.serial_str()) + print " Part#: {}, Serial#: {}".format(eeprom.part_number_str(), + eeprom.serial_number_str()) + print " Base MAC: {}".format(eeprom.base_mac_addr()) + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-fan.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-fan.py new file mode 100755 index 000000000000..6f1ebd42adbe --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-fan.py @@ -0,0 +1,27 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("---------------------") + print("Chassis Fan Unit Test") + print("---------------------") + + chassis = Chassis() + + for fan in chassis.get_all_fans(): + print(" Name:", fan.get_name()) + print(" Presence: {}, Status: {}, LED: {}".format(fan.get_presence(), + fan.get_status(), + fan.get_status_led())) + print(" Model: {}, Serial: {}".format(fan.get_model(), + fan.get_serial())) + print(" Direction: {}, Speed: {}RPM, Target Speed: {}%\n".format(fan.get_direction(), + str(fan.get_speed()), + str(fan.get_target_speed()))) + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-psu.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-psu.py new file mode 100755 index 000000000000..1a333aeac441 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-psu.py @@ -0,0 +1,27 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("---------------------") + print("Chassis PSU Unit Test") + print("---------------------") + + chassis = Chassis() + + for psu in chassis.get_all_psus(): + print(" Name:", psu.get_name()) + print(" Presence: {}, Status: {}, LED: {}".format(psu.get_presence(), + psu.get_status(), + psu.get_status_led())) + print(" Model: {}, Serial: {}".format(psu.get_model(), + psu.get_serial())) + print(" Voltage: {}, Current: {}, Power: {}\n".format(psu.get_voltage(), + psu.get_current(), + psu.get_power())) + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-sfp.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-sfp.py new file mode 100755 index 000000000000..01f75562ad3b --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-sfp.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +try: + import sonic_platform +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +def main(): + + PORT_START = 49 + PORT_END = 52 + + chassis = sonic_platform.platform.Platform().get_chassis() + + for physical_port in range(PORT_START, PORT_END+1): + print(" ") + print(" SFP transceiver tests PORT = ", physical_port) + + presence = chassis.get_sfp(physical_port).get_presence() + print("TEST 1 - sfp presence [ True ] ", physical_port, presence) + + status = chassis.get_sfp(physical_port).get_reset_status() + print("TEST 2 - sfp reset status [ False ] ", physical_port, status) + + txdisable = chassis.get_sfp(physical_port).get_tx_disable() + print("TEST 3 - sfp tx_disable [ False ] ", physical_port, txdisable) + + rxlos = chassis.get_sfp(physical_port).get_rx_los() + print("TEST 4 - sfp status rxlos [ False ] ", physical_port, rxlos) + + txfault = chassis.get_sfp(physical_port).get_tx_fault() + print("TEST 5 - sfp status txfault [ False ] ", physical_port, txfault) + + lpmode = chassis.get_sfp(physical_port).get_lpmode() + print("TEST 6 - sfp enable lpmode [ False ] ", physical_port, lpmode) + + trans_info = chassis.get_sfp(physical_port).get_transceiver_info() + print("TEST 7 - sfp transceiver info for port:", physical_port, trans_info) + + trans_status = chassis.get_sfp(physical_port).get_transceiver_bulk_status() + print("TEST 8 - sfp bulk status for port:", physical_port, trans_status) + + threshold = chassis.get_sfp(physical_port).get_transceiver_threshold_info() + print("TEST 9 - sfp bulk status for port:", physical_port, threshold) + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-thermal.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-thermal.py new file mode 100755 index 000000000000..e0259347c04e --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-thermal.py @@ -0,0 +1,26 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("-------------------------") + print("Chassis Thermal Unit Test") + print("-------------------------") + + chassis = Chassis() + + for thermal in chassis.get_all_thermals(): + print(" Name:", thermal.get_name()) + print(" Presence: {}, Status: {}".format(thermal.get_presence(), + thermal.get_status())) + print(" Model: {}, Serial: {}".format(thermal.get_model(), + thermal.get_serial())) + print(" Temperature: {}C, Low Threshold: {}C, High Threshold: {}C\n".format(thermal.get_temperature(), + thermal.get_low_threshold(), + thermal.get_high_threshold())) + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal.py new file mode 100644 index 000000000000..2743520de245 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal.py @@ -0,0 +1,226 @@ +######################################################################## +# Nokia IXS7215 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """Nokia platform-specific Thermal class""" + + I2C_CLASS_DIR = "/sys/class/i2c-adapter/" + I2C_DEV_MAPPING = (['i2c-0/0-004a/hwmon/', 1], + ['i2c-0/0-004b/hwmon/', 1], + ['i2c-0/0-002e/', 1], + ['i2c-0/0-002e/', 2], + ['i2c-0/0-002e/', 3]) + + HWMON_CLASS_DIR = "/sys/class/hwmon/" + + THERMAL_NAME = ("PCB PHY", "PCB MAC", + "ADT7473-CPU", "ADT7473-LOC", "ADT7473-MAC", + "CPU Core") + + def __init__(self, thermal_index): + self.index = thermal_index + 1 + self.is_psu_thermal = False + self.dependency = None + self.thermal_high_threshold_file = None + # PCB temperature sensors + if self.index < 3: + i2c_path = self.I2C_CLASS_DIR + self.I2C_DEV_MAPPING[self.index - 1][0] + sensor_index = self.I2C_DEV_MAPPING[self.index - 1][1] + sensor_max_suffix = "max" + sensor_crit_suffix = None + hwmon_node = os.listdir(i2c_path)[0] + self.SENSOR_DIR = i2c_path + hwmon_node + '/' + + # ADT7473 temperature sensors + elif self.index < 6: + i2c_path = self.I2C_CLASS_DIR + self.I2C_DEV_MAPPING[self.index - 1][0] + sensor_index = self.I2C_DEV_MAPPING[self.index - 1][1] + sensor_max_suffix = "max" + sensor_crit_suffix = "crit" + self.SENSOR_DIR = i2c_path + + # Armada 38x SOC temperature sensor + else: + dev_path = self.HWMON_CLASS_DIR + sensor_index = 1 + sensor_max_suffix = None + sensor_crit_suffix = None + hwmon_node = os.listdir(dev_path)[0] + self.SENSOR_DIR = dev_path + hwmon_node + '/' + + # sysfs file for current temperature value + self.thermal_temperature_file = self.SENSOR_DIR \ + + "temp{}_input".format(sensor_index) + + # sysfs file for high threshold value if supported for this sensor + if sensor_max_suffix: + self.thermal_high_threshold_file = self.SENSOR_DIR \ + + "temp{}_{}".format(sensor_index, sensor_max_suffix) + else: + self.thermal_high_threshold_file = None + + # sysfs file for crit high threshold value if supported for this sensor + if sensor_crit_suffix: + self.thermal_high_crit_threshold_file = self.SENSOR_DIR \ + + "temp{}_{}".format(sensor_index, sensor_crit_suffix) + else: + self.thermal_high_crit_threshold_file = None + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # sysfs_file and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + return self.THERMAL_NAME[self.index - 1] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + Returns: + bool: True if thermal is present, False if not + """ + if self.dependency: + return self.dependency.get_presence() + else: + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the Thermal + + Returns: + string: Model/part number of Thermal + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the Thermal + + Returns: + string: Serial number of Thermal + """ + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the thermal + + Returns: + A boolean value, True if thermal is operating properly, + False if not + """ + if self.dependency: + return self.dependency.get_status() + else: + return True + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + thermal_temperature = self._read_sysfs_file( + self.thermal_temperature_file) + if (thermal_temperature != 'ERR'): + thermal_temperature = float(thermal_temperature) / 1000 + else: + thermal_temperature = 0 + + return float("{:.3f}".format(thermal_temperature)) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + + # Not implemented for this sensor + if not self.thermal_high_threshold_file: + raise NotImplementedError + + thermal_high_threshold = self._read_sysfs_file( + self.thermal_high_threshold_file) + if (thermal_high_threshold != 'ERR'): + thermal_high_threshold = float(thermal_high_threshold) / 1000 + else: + thermal_high_threshold = 0.0 + + return float("{:.3f}".format(thermal_high_threshold)) + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + + # Not implemented for this sensor + if not self.thermal_high_crit_threshold_file: + raise NotImplementedError + + thermal_high_crit_threshold = self._read_sysfs_file( + self.thermal_high_crit_threshold_file) + if (thermal_high_crit_threshold != 'ERR'): + thermal_high_crit_threshold = float(thermal_high_crit_threshold) / 1000 + else: + thermal_high_crit_threshold = 0.0 + + return float("{:.3f}".format(thermal_high_crit_threshold)) diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_actions.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_actions.py new file mode 100644 index 000000000000..a829fd80a5ba --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_actions.py @@ -0,0 +1,192 @@ +from sonic_platform_base.sonic_thermal_control.thermal_action_base import ThermalPolicyActionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + +from sonic_py_common import logger + +sonic_logger = logger.Logger('thermal_actions') + + +class SetFanSpeedAction(ThermalPolicyActionBase): + """ + Base thermal action class to set speed for fans + """ + # JSON field definition + JSON_FIELD_SPEED = 'speed' + JSON_FIELD_DEFAULT_SPEED = 'default_speed' + JSON_FIELD_HIGHTEMP_SPEED = 'hightemp_speed' + + def __init__(self): + """ + Constructor of SetFanSpeedAction + """ + self.default_speed = 50 + self.hightemp_speed = 100 + self.speed = self.default_speed + + def load_from_json(self, json_obj): + """ + Construct SetFanSpeedAction via JSON. JSON example: + { + "type": "fan.all.set_speed" + "speed": "100" + } + :param json_obj: A JSON object representing a SetFanSpeedAction action. + :return: + """ + if SetFanSpeedAction.JSON_FIELD_SPEED in json_obj: + speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_SPEED]) + if speed < 0 or speed > 100: + raise ValueError('SetFanSpeedAction invalid speed value {} in JSON policy file, valid value should be [0, 100]'. + format(speed)) + self.speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_SPEED)) + + @classmethod + def set_all_fan_speed(cls, thermal_info_dict, speed): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + fan_info_obj = thermal_info_dict[FanInfo.INFO_NAME] + for fan in fan_info_obj.get_presence_fans(): + fan.set_speed(int(speed)) + + +@thermal_json_object('fan.all.set_speed') +class SetAllFanSpeedAction(SetFanSpeedAction): + """ + Action to set speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + SetAllFanSpeedAction.set_all_fan_speed(thermal_info_dict, self.speed) + + +@thermal_json_object('thermal.temp_check_and_set_all_fan_speed') +class ThermalRecoverAction(SetFanSpeedAction): + """ + Action to check thermal sensor temperature change status and set speed for all fans + """ + + def load_from_json(self, json_obj): + """ + Construct ThermalRecoverAction via JSON. JSON example: + { + "type": "thermal.temp_check_and_set_all_fan_speed" + "default_speed": "50" + "hightemp_speed": "100" + } + :param json_obj: A JSON object representing a ThermalRecoverAction action. + :return: + """ + if SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED in json_obj: + default_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED]) + if default_speed < 0 or default_speed > 100: + raise ValueError('SetFanSpeedAction invalid default speed value {} in JSON policy file, valid value should be [0, 100]'. + format(default_speed)) + self.default_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED)) + + if SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED in json_obj: + hightemp_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED]) + if hightemp_speed < 0 or hightemp_speed > 100: + raise ValueError('SetFanSpeedAction invalid hightemp speed value {} in JSON policy file, valid value should be [0, 100]'. + format(hightemp_speed)) + self.hightemp_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED)) + + sonic_logger.log_warning("ThermalRecoverAction: default: {}, hightemp: {}".format(self.default_speed, self.hightemp_speed)) + + def execute(self, thermal_info_dict): + """ + Check check thermal sensor temperature change status and set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + from .thermal_infos import ThermalInfo + if ThermalInfo.INFO_NAME in thermal_info_dict and \ + isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): + + thermal_info_obj = thermal_info_dict[ThermalInfo.INFO_NAME] + if thermal_info_obj.is_warm_up_and_over_high_threshold(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.hightemp_speed) + elif thermal_info_obj.is_cool_down_and_below_low_threshold(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.default_speed) + + +@thermal_json_object('switch.shutdown') +class SwitchPolicyAction(ThermalPolicyActionBase): + """ + Base class for thermal action. Once all thermal conditions in a thermal policy are matched, + all predefined thermal action will be executed. + """ + def execute(self, thermal_info_dict): + """ + Take action when thermal condition matches. For example, adjust speed of fan or shut + down the switch. + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + sonic_logger.log_warning("Alarm for temperature critical is detected, reboot Device") + # import os + # os.system('reboot') + + +@thermal_json_object('thermal_control.control') +class ControlThermalAlgoAction(ThermalPolicyActionBase): + """ + Action to control the thermal control algorithm + """ + # JSON field definition + JSON_FIELD_STATUS = 'status' + + def __init__(self): + self.status = True + + def load_from_json(self, json_obj): + """ + Construct ControlThermalAlgoAction via JSON. JSON example: + { + "type": "thermal_control.control" + "status": "true" + } + :param json_obj: A JSON object representing a ControlThermalAlgoAction action. + :return: + """ + if ControlThermalAlgoAction.JSON_FIELD_STATUS in json_obj: + status_str = json_obj[ControlThermalAlgoAction.JSON_FIELD_STATUS].lower() + if status_str == 'true': + self.status = True + elif status_str == 'false': + self.status = False + else: + raise ValueError('Invalid {} field value, please specify true of false'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + else: + raise ValueError('ControlThermalAlgoAction ' + 'missing mandatory field {} in JSON policy file'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + + def execute(self, thermal_info_dict): + """ + Disable thermal control algorithm + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + from .thermal_infos import ChassisInfo + if ChassisInfo.INFO_NAME in thermal_info_dict: + chassis_info_obj = thermal_info_dict[ChassisInfo.INFO_NAME] + chassis = chassis_info_obj.get_chassis() + thermal_manager = chassis.get_thermal_manager() + if self.status: + thermal_manager.start_thermal_control_algorithm() + else: + thermal_manager.stop_thermal_control_algorithm() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_conditions.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_conditions.py new file mode 100644 index 000000000000..4923d63d746b --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_conditions.py @@ -0,0 +1,81 @@ +from sonic_platform_base.sonic_thermal_control.thermal_condition_base import ThermalPolicyConditionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + + +class FanCondition(ThermalPolicyConditionBase): + def get_fan_info(self, thermal_info_dict): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + return thermal_info_dict[FanInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('fan.any.absence') +class AnyFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.absence') +class AllFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_presence_fans()) == 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.presence') +class AllFanPresenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) == 0 if fan_info_obj else False + + +class ThermalCondition(ThermalPolicyConditionBase): + def get_thermal_info(self, thermal_info_dict): + from .thermal_infos import ThermalInfo + if ThermalInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): + return thermal_info_dict[ThermalInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('thermal.over.high_critical_threshold') +class ThermalOverHighCriticalCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + if thermal_info_obj: + return thermal_info_obj.is_over_high_critical_threshold() + else: + return False + + +class PsuCondition(ThermalPolicyConditionBase): + def get_psu_info(self, thermal_info_dict): + from .thermal_infos import PsuInfo + if PsuInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[PsuInfo.INFO_NAME], PsuInfo): + return thermal_info_dict[PsuInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('psu.any.absence') +class AnyPsuAbsenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_absence_psus()) > 0 if psu_info_obj else False + + +@thermal_json_object('psu.all.absence') +class AllPsuAbsenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_presence_psus()) == 0 if psu_info_obj else False + + +@thermal_json_object('psu.all.presence') +class AllPsuPresenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_absence_psus()) == 0 if psu_info_obj else False diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_infos.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_infos.py new file mode 100644 index 000000000000..cd0a0591cd2a --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_infos.py @@ -0,0 +1,210 @@ +from sonic_platform_base.sonic_thermal_control.thermal_info_base import ThermalPolicyInfoBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + + +@thermal_json_object('fan_info') +class FanInfo(ThermalPolicyInfoBase): + """ + Fan information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'fan_info' + + def __init__(self): + self._absence_fans = set() + self._presence_fans = set() + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence fans. + :param chassis: The chassis object + :return: + """ + self._status_changed = False + for fan in chassis.get_all_fans(): + if fan.get_presence() and fan not in self._presence_fans: + self._presence_fans.add(fan) + self._status_changed = True + if fan in self._absence_fans: + self._absence_fans.remove(fan) + elif not fan.get_presence() and fan not in self._absence_fans: + self._absence_fans.add(fan) + self._status_changed = True + if fan in self._presence_fans: + self._presence_fans.remove(fan) + + def get_absence_fans(self): + """ + Retrieves absence fans + :return: A set of absence fans + """ + return self._absence_fans + + def get_presence_fans(self): + """ + Retrieves presence fans + :return: A set of presence fans + """ + return self._presence_fans + + def is_status_changed(self): + """ + Retrieves if the status of fan information changed + :return: True if status changed else False + """ + return self._status_changed + + +@thermal_json_object('thermal_info') +class ThermalInfo(ThermalPolicyInfoBase): + """ + Thermal information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'thermal_info' + + def __init__(self): + self.init = False + self._old_avg_temp = 0 + self._current_avg_temp = 0 + self._high_crital_threshold = 75 + self._high_threshold = 45 + self._low_threshold = 40 + + def collect(self, chassis): + """ + Collect thermal sensor temperature change status + :param chassis: The chassis object + :return: + """ + self._temps = [] + self._over_high_critical_threshold = False + self._warm_up_and_over_high_threshold = False + self._cool_down_and_below_low_threshold = False + + # Calculate average temp within the device + temp = 0 + num_of_thermals = chassis.get_num_thermals() + for index in range(num_of_thermals): + self._temps.insert(index, chassis.get_thermal(index).get_temperature()) + temp += self._temps[index] + + self._current_avg_temp = temp / num_of_thermals + + # Special case if first time + if self.init is False: + self._old_avg_temp = self._current_avg_temp + self.init = True + + # Check if new average temp exceeds high threshold value + if self._current_avg_temp >= self._old_avg_temp and self._current_avg_temp >= self._high_threshold: + self._warm_up_and_over_high_threshold = True + + # Check if new average temp exceeds low threshold value + if self._current_avg_temp <= self._old_avg_temp and self._current_avg_temp <= self._low_threshold: + self._cool_down_and_below_low_threshold = True + + self._old_avg_temp = self._current_avg_temp + + def is_warm_up_and_over_high_threshold(self): + """ + Retrieves if the temperature is warm up and over high threshold + :return: True if the temperature is warm up and over high threshold else False + """ + return self._warm_up_and_over_high_threshold + + def is_cool_down_and_below_low_threshold(self): + """ + Retrieves if the temperature is cold down and below low threshold + :return: True if the temperature is cold down and below low threshold else False + """ + return self._cool_down_and_below_low_threshold + + def is_over_high_critical_threshold(self): + """ + Retrieves if the temperature is over high critical threshold + :return: True if the temperature is over high critical threshold else False + """ + return self._over_high_critical_threshold + + +@thermal_json_object('psu_info') +class PsuInfo(ThermalPolicyInfoBase): + """ + PSU information needed by thermal policy + """ + INFO_NAME = 'psu_info' + + def __init__(self): + self._absence_psus = set() + self._presence_psus = set() + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence PSUs. + :param chassis: The chassis object + :return: + """ + self._status_changed = False + for psu in chassis.get_all_psus(): + if psu.get_presence() and psu.get_powergood_status() and psu not in self._presence_psus: + self._presence_psus.add(psu) + self._status_changed = True + if psu in self._absence_psus: + self._absence_psus.remove(psu) + elif (not psu.get_presence() or not psu.get_powergood_status()) and psu not in self._absence_psus: + self._absence_psus.add(psu) + self._status_changed = True + if psu in self._presence_psus: + self._presence_psus.remove(psu) + + def get_absence_psus(self): + """ + Retrieves presence PSUs + :return: A set of absence PSUs + """ + return self._absence_psus + + def get_presence_psus(self): + """ + Retrieves presence PSUs + :return: A set of presence fans + """ + return self._presence_psus + + def is_status_changed(self): + """ + Retrieves if the status of PSU information changed + :return: True if status changed else False + """ + return self._status_changed + + +@thermal_json_object('chassis_info') +class ChassisInfo(ThermalPolicyInfoBase): + """ + Chassis information needed by thermal policy + """ + INFO_NAME = 'chassis_info' + + def __init__(self): + self._chassis = None + + def collect(self, chassis): + """ + Collect platform chassis. + :param chassis: The chassis object + :return: + """ + self._chassis = chassis + + def get_chassis(self): + """ + Retrieves platform chassis object + :return: A platform chassis object. + """ + return self._chassis diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_manager.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_manager.py new file mode 100644 index 000000000000..967cf175934e --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_manager.py @@ -0,0 +1,49 @@ +from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase +from .thermal_actions import * +from .thermal_conditions import * +from .thermal_infos import * + + +class ThermalManager(ThermalManagerBase): + THERMAL_ALGORITHM_CONTROL_PATH = '/var/run/hw-management/config/suspend' + + @classmethod + def start_thermal_control_algorithm(cls): + """ + Start thermal control algorithm + + Returns: + bool: True if set success, False if fail. + """ + cls._control_thermal_control_algorithm(False) + + @classmethod + def stop_thermal_control_algorithm(cls): + """ + Stop thermal control algorithm + + Returns: + bool: True if set success, False if fail. + """ + cls._control_thermal_control_algorithm(True) + + @classmethod + def _control_thermal_control_algorithm(cls, suspend): + """ + Control thermal control algorithm + + Args: + suspend: Bool, indicate suspend the algorithm or not + + Returns: + bool: True if set success, False if fail. + """ + status = True + write_value = 1 if suspend else 0 + try: + with open(cls.THERMAL_ALGORITHM_CONTROL_PATH, 'w') as control_file: + control_file.write(str(write_value)) + except (ValueError, IOError): + status = False + + return status diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/watchdog.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/watchdog.py new file mode 100644 index 000000000000..75ec3ab177ae --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/watchdog.py @@ -0,0 +1,135 @@ +""" +ARMADA 38x Watchdog - one 32 bit cpu watchdog per cpu - 2 watchdogs ( page 662) + +Module contains an implementation of SONiC Platform Base API and +provides access to hardware watchdog +""" + +import os +import fcntl +import array + +from sonic_platform_base.watchdog_base import WatchdogBase +from sonic_py_common import logger + +""" ioctl constants """ +IO_READ = 0x80000000 +IO_SIZE_INT = 0x00040000 +IO_TYPE_WATCHDOG = ord('W') << 8 + +WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG + +""" Watchdog ioctl commands """ +WDIOC_SETOPTIONS = 4 | WDR_INT +WDIOC_KEEPALIVE = 5 | WDR_INT +WDIOC_GETTIMEOUT = 7 | WDR_INT + +""" Watchdog status constants """ +WDIOS_DISABLECARD = 0x0001 +WDIOS_ENABLECARD = 0x0002 + +""" watchdog sysfs """ +WD_SYSFS_PATH = "/sys/class/watchdog/" + +WD_COMMON_ERROR = -1 + +sonic_logger = logger.Logger() + + +class WatchdogImplBase(WatchdogBase): + """ + Base class that implements common logic for interacting + with watchdog using ioctl commands + """ + + def __init__(self, wd_device_path): + """ + Open a watchdog handle + @param wd_device_path Path to watchdog device + """ + + self.watchdog_path = wd_device_path + self.watchdog = os.open(self.watchdog_path, os.O_WRONLY) + + # Opening a watchdog descriptor starts + # watchdog timer; by default it should be stopped + self._disablewatchdog() + self.armed = False + self.timeout = self._gettimeout() + + def disarm(self): + """ + Disarm the hardware watchdog + + Returns: + A boolean, True if watchdog is disarmed successfully, False + if not + """ + sonic_logger.log_info(" Debug disarm watchdog ") + + try: + self._disablewatchdog() + self.armed = False + self.timeout = 0 + except IOError: + return False + + return True + + def _disablewatchdog(self): + """ + Turn off the watchdog timer + """ + + req = array.array('h', [WDIOS_DISABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _gettimeout(self): + """ + Get watchdog timeout + @return watchdog timeout + """ + + req = array.array('I', [0]) + fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True) + + return int(req[0]) + + def arm(self, seconds): + """ + Implements arm WatchdogBase API + """ + sonic_logger.log_info(" Debug arm watchdog4 ") + ret = WD_COMMON_ERROR + if seconds < 0: + return ret + + try: + if self.timeout != seconds: + self.timeout = self._settimeout(seconds) + if self.armed: + self._keepalive() + else: + sonic_logger.log_info(" Debug arm watchdog5 ") + self._enablewatchdog() + self.armed = True + ret = self.timeout + except IOError: + pass + + return ret + + def _enablewatchdog(self): + """ + Turn on the watchdog timer + """ + + req = array.array('h', [WDIOS_ENABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + + fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE) diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/changelog b/platform/marvell-armhf/sonic-platform-nokia/debian/changelog new file mode 100755 index 000000000000..f4c860fab861 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/changelog @@ -0,0 +1,5 @@ +sonic-platform-nokia-7215 (1.0) unstable; urgency=low + + * Add support for nokia-7215. + + -- Nokia Wed, 15 Apr 2020 09:35:58 +0800 diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/compat b/platform/marvell-armhf/sonic-platform-nokia/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/control b/platform/marvell-armhf/sonic-platform-nokia/debian/control new file mode 100755 index 000000000000..0da04ac89842 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/control @@ -0,0 +1,15 @@ +Source: sonic-platform-nokia-7215 +Section: unknown +Priority: optional +Maintainer: Nokia +Build-Depends: debhelper (>=9) +Standards-Version: 3.9.6 +Homepage: +#Vcs-Git: git://anonscm.debian.org/collab-maint/sonic-platform-et6448m.git +#Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/sonic-platform-et6448m.git + +Package: sonic-platform-nokia-7215 +Architecture: armhf +Depends: ${misc:Depends} +Description: + diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/rules b/platform/marvell-armhf/sonic-platform-nokia/debian/rules new file mode 100755 index 000000000000..c1e6c1fbfb2b --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/rules @@ -0,0 +1,66 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + +include /usr/share/dpkg/pkg-info.mk +#-------------------------------------------------------- + +PACKAGE_PRE_NAME := sonic-platform-nokia +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= 7215 +UTILS_DIR := utils +SERVICE_DIR := service +PLATFORM_DIR := sonic_platform + +%: + dh $@ --with systemd,python2,python3 --buildsystem=pybuild + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + (for mod in $(MODULE_DIRS); do \ + python2 $${mod}/setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}; \ + python3 $${mod}/setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}; \ + done) + +binary: binary-arch binary-indep + # Nothing to do + +binary-arch: + # Nothing to do + +binary-indep: + dh_testdir + dh_installdirs + + # Custom package commands + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /usr/local/bin; \ + cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + python2 $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + python3 $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + done) + + # Resuming debhelper scripts + dh_testroot + dh_install + dh_installchangelogs + dh_installdocs + dh_systemd_enable + dh_installinit + dh_systemd_start + dh_link + dh_fixperms + dh_compress + dh_strip + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + +.PHONY: build binary binary-arch binary-indep clean diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.install b/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.install new file mode 100644 index 000000000000..0b867d259f10 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.install @@ -0,0 +1,5 @@ +nokia-7215_plt_setup.sh usr/sbin +7215/scripts/nokia-7215init.sh usr/local/bin +7215/service/nokia-7215init.service etc/systemd/system +7215/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/armhf-nokia_ixs7215_52x-r0 +7215/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/armhf-nokia_ixs7215_52x-r0 diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.postinst b/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.postinst new file mode 100644 index 000000000000..de91cedb4ec7 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.postinst @@ -0,0 +1,11 @@ +#!/bin/sh +# postinst script for sonic-platform-nokia-7215 +# +# see: dh_installdeb(1) + +sh /usr/sbin/nokia-7215_plt_setup.sh +systemctl enable nokia-7215init.service +systemctl start nokia-7215init.service + +exit 0 + diff --git a/platform/marvell-armhf/sonic-platform-nokia/nokia-7215_plt_setup.sh b/platform/marvell-armhf/sonic-platform-nokia/nokia-7215_plt_setup.sh new file mode 100755 index 000000000000..e4fc716cf5a5 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/nokia-7215_plt_setup.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +fw_uboot_env_cfg() +{ + echo "Setting up U-Boot environment..." + + MACH_FILE="/host/machine.conf" + PLATFORM=`sed -n 's/onie_platform=\(.*\)/\1/p' $MACH_FILE` + + if [ "$PLATFORM" = "armhf-nokia_ixs7215_52x-r0" ]; then + # Ixs7215 / IPD6448M board Uboot ENV offset + FW_ENV_DEFAULT='/dev/mtd0 0x00100000 0x10000 0x10000' + + demo_part=$(sgdisk -p /dev/sda | grep -e "SONiC-OS") + if [ -z "$demo_part" ]; then + # ET6448M Board - For Backward compatibility + FW_ENV_DEFAULT='/dev/mtd0 0x00500000 0x80000 0x100000 8' + fi + else + FW_ENV_DEFAULT='/dev/mtd0 0x00500000 0x80000 0x100000 8' + fi + + echo "Using pre-configured uboot env" + echo $FW_ENV_DEFAULT > /etc/fw_env.config + +} + + +main() +{ + fw_uboot_env_cfg + echo "Nokia-IXS7215: /dev/mtd0 FW_ENV_DEFAULT" +} + +main $@ From a92732fe5dcbbff2fb421a3522c6c2efe5273c3a Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 19 Nov 2020 00:07:58 -0800 Subject: [PATCH 1409/1427] [bgpcfgd]: Fixes for BBR (#5956) * Add explicit default state into the constants.yml * Enable/disable only peer-groups, available in the config * Retrieve updates from frr before using configuration Co-authored-by: Pavel Shirshov --- files/image_config/constants/constants.yml | 1 + src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py | 36 +++++-- src/sonic-bgpcfgd/tests/test_bbr.py | 106 ++++++++++++++++++--- 3 files changed, 124 insertions(+), 19 deletions(-) diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index ac4b521865c8..86179aee430e 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -31,6 +31,7 @@ constants: - "deny 0::/0 ge 65" bbr: enabled: true + default_state: "disabled" peers: general: # peer_type db_table: "BGP_NEIGHBOR" diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py b/src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py index 5c03eabf4bbf..7adfd203f455 100644 --- a/src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py @@ -1,3 +1,5 @@ +import re + from swsscommon import swsscommon from .log import log_err, log_info, log_crit @@ -49,18 +51,23 @@ def __init(self): if not 'bgp' in self.constants: log_err("BBRMgr::Disabled: 'bgp' key is not found in constants") return - if 'bbr' in self.constants['bgp'] and \ - 'enabled' in self.constants['bgp']['bbr'] and \ - self.constants['bgp']['bbr']['enabled']: + if 'bbr' in self.constants['bgp'] \ + and 'enabled' in self.constants['bgp']['bbr'] \ + and self.constants['bgp']['bbr']['enabled']: self.bbr_enabled_pgs = self.__read_pgs() if self.bbr_enabled_pgs: self.enabled = True - self.directory.put(self.db_name, self.table_name, 'status', "enabled") - log_info("BBRMgr::Initialized and enabled") + if 'default_state' in self.constants['bgp']['bbr'] \ + and self.constants['bgp']['bbr']['default_state'] == 'enabled': + default_status = "enabled" + else: + default_status = "disabled" + self.directory.put(self.db_name, self.table_name, 'status', default_status) + log_info("BBRMgr::Initialized and enabled. Default state: '%s'" % default_status) else: log_info("BBRMgr::Disabled: no BBR enabled peers") else: - log_info("BBRMgr::Disabled: not enabled in the constants") + log_info("BBRMgr::Disabled: no bgp.bbr.enabled in the constants") def __read_pgs(self): """ @@ -102,15 +109,30 @@ def __set_prepare_config(self, status): :return: list of commands prepared for FRR """ bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + available_peer_groups = self.__get_available_peer_groups() cmds = ["router bgp %s" % bgp_asn] prefix_of_commands = "" if status == "enabled" else "no " for af in ["ipv4", "ipv6"]: cmds.append(" address-family %s" % af) for pg_name in sorted(self.bbr_enabled_pgs.keys()): - if af in self.bbr_enabled_pgs[pg_name]: + if pg_name in available_peer_groups and af in self.bbr_enabled_pgs[pg_name]: cmds.append(" %sneighbor %s allowas-in 1" % (prefix_of_commands, pg_name)) return cmds + def __get_available_peer_groups(self): + """ + Extract configured peer-groups from the config + :return: set of available peer-groups + """ + re_pg = re.compile(r'^\s*neighbor\s+(\S+)\s+peer-group\s*$') + res = set() + self.cfg_mgr.update() + for line in self.cfg_mgr.get_text(): + m = re_pg.match(line) + if m: + res.add(m.group(1)) + return res + def __restart_peers(self): """ Restart peer-groups which support BBR """ for peer_group in sorted(self.bbr_enabled_pgs.keys()): diff --git a/src/sonic-bgpcfgd/tests/test_bbr.py b/src/sonic-bgpcfgd/tests/test_bbr.py index a86cc5c6db07..cc0c83fad648 100644 --- a/src/sonic-bgpcfgd/tests/test_bbr.py +++ b/src/sonic-bgpcfgd/tests/test_bbr.py @@ -25,9 +25,6 @@ } } -#@patch('bgpcfgd.managers_bbr.log_info') -#@patch('bgpcfgd.managers_bbr.log_err') -#@patch('bgpcfgd.managers_bbr.log_crit') def test_constructor():#m1, m2, m3): cfg_mgr = MagicMock() common_objs = { @@ -123,8 +120,6 @@ def __init_common(constants, assert m.directory.get("CONFIG_DB", "BGP_BBR", "status") == expected_status if expected_status == "enabled": assert m.enabled - else: - assert not m.enabled if expected_log_err is not None: mocked_log_err.assert_called_with(expected_log_err) if expected_log_info is not None: @@ -135,17 +130,17 @@ def test___init_1(): def test___init_2(): constants = deepcopy(global_constants) - __init_common(constants, "BBRMgr::Disabled: not enabled in the constants", None, {}, "disabled") + __init_common(constants, "BBRMgr::Disabled: no bgp.bbr.enabled in the constants", None, {}, "disabled") def test___init_3(): constants = deepcopy(global_constants) constants["bgp"]["bbr"] = { "123" : False } - __init_common(constants, "BBRMgr::Disabled: not enabled in the constants", None, {}, "disabled") + __init_common(constants, "BBRMgr::Disabled: no bgp.bbr.enabled in the constants", None, {}, "disabled") def test___init_4(): constants = deepcopy(global_constants) constants["bgp"]["bbr"] = { "enabled" : False } - __init_common(constants, "BBRMgr::Disabled: not enabled in the constants", None, {}, "disabled") + __init_common(constants, "BBRMgr::Disabled: no bgp.bbr.enabled in the constants", None, {}, "disabled") def test___init_5(): constants = deepcopy(global_constants) @@ -164,7 +159,35 @@ def test___init_6(): "bbr": expected_bbr_entries, } } - __init_common(constants, 'BBRMgr::Initialized and enabled', None, expected_bbr_entries, "enabled") + __init_common(constants, "BBRMgr::Initialized and enabled. Default state: 'disabled'", None, expected_bbr_entries, "disabled") + +def test___init_7(): + expected_bbr_entries = { + "PEER_V4": ["ipv4"], + "PEER_V6": ["ipv6"], + } + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "enabled" : True, "default_state": "disabled" } + constants["bgp"]["peers"] = { + "general": { + "bbr": expected_bbr_entries, + } + } + __init_common(constants, "BBRMgr::Initialized and enabled. Default state: 'disabled'", None, expected_bbr_entries, "disabled") + +def test___init_8(): + expected_bbr_entries = { + "PEER_V4": ["ipv4"], + "PEER_V6": ["ipv6"], + } + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "enabled" : True, "default_state": "enabled" } + constants["bgp"]["peers"] = { + "general": { + "bbr": expected_bbr_entries, + } + } + __init_common(constants, "BBRMgr::Initialized and enabled. Default state: 'enabled'", None, expected_bbr_entries, "enabled") @patch('bgpcfgd.managers_bbr.log_info') def read_pgs_common(constants, expected_log_info, expected_bbr_enabled_pgs, mocked_log_info): @@ -232,7 +255,7 @@ def test___set_validation_4(): def test___set_validation_5(): __set_validation_common("all", {"status": "disabled"}, None, True) -def __set_prepare_config_common(status, bbr_enabled_pgs, expected_cmds): +def __set_prepare_config_common(status, bbr_enabled_pgs, available_pgs, expected_cmds): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), @@ -249,6 +272,7 @@ def __set_prepare_config_common(status, bbr_enabled_pgs, expected_cmds): } } m.bbr_enabled_pgs = bbr_enabled_pgs + m._BBRMgr__get_available_peer_groups = MagicMock(return_value = available_pgs) cmds = m._BBRMgr__set_prepare_config(status) assert cmds == expected_cmds @@ -256,7 +280,7 @@ def test___set_prepare_config_enabled(): __set_prepare_config_common("enabled", { "PEER_V4": ["ipv4", "ipv6"], "PEER_V6": ["ipv6"], - }, [ + }, {"PEER_V4", "PEER_V6"}, [ 'router bgp 65500', ' address-family ipv4', ' neighbor PEER_V4 allowas-in 1', @@ -269,7 +293,35 @@ def test___set_prepare_config_disabled(): __set_prepare_config_common("disabled", { "PEER_V4": ["ipv4", "ipv6"], "PEER_V6": ["ipv6"], - }, [ + }, {"PEER_V4", "PEER_V6"}, [ + 'router bgp 65500', + ' address-family ipv4', + ' no neighbor PEER_V4 allowas-in 1', + ' address-family ipv6', + ' no neighbor PEER_V4 allowas-in 1', + ' no neighbor PEER_V6 allowas-in 1', + ]) + +def test___set_prepare_config_enabled_part(): + __set_prepare_config_common("enabled", { + "PEER_V4": ["ipv4", "ipv6"], + "PEER_V6": ["ipv6"], + "PEER_V8": ["ipv4"] + }, {"PEER_V4", "PEER_V6"}, [ + 'router bgp 65500', + ' address-family ipv4', + ' neighbor PEER_V4 allowas-in 1', + ' address-family ipv6', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V6 allowas-in 1', + ]) + +def test___set_prepare_config_disabled_part(): + __set_prepare_config_common("disabled", { + "PEER_V4": ["ipv4", "ipv6"], + "PEER_V6": ["ipv6"], + "PEER_v10": ["ipv4"], + }, {"PEER_V4", "PEER_V6"}, [ 'router bgp 65500', ' address-family ipv4', ' no neighbor PEER_V4 allowas-in 1', @@ -278,6 +330,36 @@ def test___set_prepare_config_disabled(): ' no neighbor PEER_V6 allowas-in 1', ]) + +def test__get_available_peer_groups(): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + m.cfg_mgr.get_text = MagicMock(return_value=[ + ' neighbor PEER_V4 peer-group', + ' neighbor PEER_V6 peer-group', + ' address-family ipv4', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V4 soft-reconfiguration inbound', + ' neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4 route-map TO_BGP_PEER_V4 out', + ' exit-address-family', + ' address-family ipv6', + ' neighbor PEER_V6 allowas-in 1', + ' neighbor PEER_V6 soft-reconfiguration inbound', + ' neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6 route-map TO_BGP_PEER_V6 out', + ' exit-address-family', + ' ', + ]) + res = m._BBRMgr__get_available_peer_groups() + assert res == {"PEER_V4", "PEER_V6"} + @patch('bgpcfgd.managers_bbr.log_crit') def __restart_peers_common(run_command_results, run_command_expects, last_log_crit_message, mocked_log_crit): cfg_mgr = MagicMock() From 42e78a19c1921f3f9ce589252f3f67bff9f82849 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 19 Nov 2020 10:57:07 -0800 Subject: [PATCH 1410/1427] [sonic-swss-common] Update submodule (#5969) Update the sonic-swss-common submodule. The following are the commits in the submodule. ``` 95f9e11 2020-11-19 | [pyext] allow to catch exceptions raised in python (#415) [Stepan Blyshchak] 5a718f9 2020-11-18 | [swig] translate C++ `del` to python `delete` (#416) [Qi Luo] 40b255b 2020-11-12 | Fix: SWIG dict.get() should have optional default value parameter (#413) [Qi Luo] 91e484d 2020-11-07 | Reduce notice logging (#412) [Qi Luo] f5945ae 2020-11-05 | Mux Cable schema definitions for interaction between linkmanager and xcvrd (#411) [vdahiya12] 602f9c2 2020-11-05 | [lua] load lua script on demand (#409) [Dong Zhang] d88412b 2020-11-04 | Rename hdel to del when using multiple keys as param (#410) [Kamil Cudnik] e0c229a 2020-11-04 | CHASSIS_STATE_DB on control-card for chassis state (#395) [mprabhu-nokia] a4e3ac8 2020-11-04 | Chassisd config table to store admin state (#388) [mprabhu-nokia] ``` --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index ec9686856749..95f9e110d171 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit ec9686856749ac61817968737040e943d0b14cb3 +Subproject commit 95f9e110d171fa95ab7ae75aebc31f6b3bac83c2 From 91f6d5b29eacaf961ed21ffa5bf33b8c6774ea08 Mon Sep 17 00:00:00 2001 From: Sabareesh-Kumar-Anandan <59681634+Sabareesh-Kumar-Anandan@users.noreply.github.com> Date: Fri, 20 Nov 2020 02:06:45 +0530 Subject: [PATCH 1411/1427] [platform][marvell] Disabling Mgmt Framework for marvell-armhf (#5753) We are facing some compilation issue while compiling mgmt framework for arm. So, disabling Mgmt framework for marvell-armhf. We will enable it after fixing the compilation issues Signed-off-by: Sabareesh Kumar Anandan --- platform/marvell-armhf/rules.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/marvell-armhf/rules.mk b/platform/marvell-armhf/rules.mk index 9f8cf775ae7d..e53f9531b82b 100644 --- a/platform/marvell-armhf/rules.mk +++ b/platform/marvell-armhf/rules.mk @@ -12,6 +12,7 @@ include $(PLATFORM_PATH)/platform-nokia.mk INCLUDE_SYSTEM_TELEMETRY = "" ENABLE_SYNCD_RPC = "" +INCLUDE_MGMT_FRAMEWORK = "" SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) From d2f143d66f0912847ae0022efa8b20e5c40f40e8 Mon Sep 17 00:00:00 2001 From: Petro Bratash <68950226+bratashX@users.noreply.github.com> Date: Fri, 20 Nov 2020 00:53:37 +0200 Subject: [PATCH 1412/1427] [sonic-platform-common] Update submodule (#5977) [sonic_eeprom] Fix variable type: Azure/sonic-platform-common#145 Signed-off-by: Petro Bratash --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 5db8c84df818..32ee0070552a 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 5db8c84df8183282ce216c36d8fddb783f704c44 +Subproject commit 32ee0070552a91dc458acd5e24d123628ded7de2 From 5fbb6ee613de65e088782854e77d5fec46684907 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 19 Nov 2020 22:43:10 -0800 Subject: [PATCH 1413/1427] [sonic-platform-daemons] Update submodule (#5976) * src/sonic-platform-daemons be21d91...b90ddda (1): > [thermalctld] [psud] [chassisd] Fix crash with undefined environment variable (#120) --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index be21d911a300..b90ddda28212 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit be21d911a30086e2d0412dd3a0e18a4a5b5ec732 +Subproject commit b90ddda28212c7f5c825d8aec3b430ecf753a560 From 2f2b7c2a5c4ba17792bfc0062052f5f54af77d54 Mon Sep 17 00:00:00 2001 From: Shi Su <67605788+shi-su@users.noreply.github.com> Date: Thu, 19 Nov 2020 23:40:14 -0800 Subject: [PATCH 1414/1427] [sonic-swss] Update submodule (#5964) Update the sonic-swss submodule. The following are the commits in the submodule. [dvs] Re-add runcmd_async command 5ba548cd759be4f0b1d1830ea038bf3c84e6f3f6 [dvs] Re-add copy_file method to DVS 86e11715819ac183a68aaf1deed6beabb259384b Add a check for warm-restart, and do a clear only when warm-restart is enable. fcb6c9de918d93967440b78bf7d5cd3a51bf7129 [Routeorch] Fix next hop group reference count in bulk operation 7a92100c1c1a344e67d4501cb7b98de557d0ea52 [orchagent][port] In case of successful port creation set log level to INFO fea7ade74941a529505681e384f3437e873b1f7a Copp Manager Changes 7b76d2e201f9f7d26cec7460f1335f7762b4ad01 [orchagent] Arm 32-bit arch compilation warning Fixes bed79702c9da7957b775a0c960f67dd426db34d5 Revert: swss: flush g_asicState after each event is done #570 b9084a720d41daf1d717bcbe06f56e7a95111fa6 [dvs] Clean-up conftest.py d6e15e955c91a6f077a913a617a336a314c6c91b --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 62e6c5a4d7dc..5ba548cd759b 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 62e6c5a4d7dc9aeae74d5350e95bd7908203e09b +Subproject commit 5ba548cd759be4f0b1d1830ea038bf3c84e6f3f6 From 7bf05f7f4fddca5a3af0e55d07c06e31937e9215 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 19 Nov 2020 23:41:32 -0800 Subject: [PATCH 1415/1427] [supervisor] Install vanilla package once again, install Python 3 version in Buster container (#5546) **- Why I did it** We were building a custom version of Supervisor because I had added patches to prevent hangs and crashes if the system clock ever rolled backward. Those changes were merged into the upstream Supervisor repo as of version 3.4.0 (http://supervisord.org/changes.html#id9), therefore, we should be able to simply install the vanilla package via pip. This will also allow us to easily move to Python 3, as Python 3 support was added in version 4.0.0. **- How I did it** - Remove Makefiles and patches for building supervisor package from source - Install Python 3 supervisor package version 4.2.1 in Buster base container - Also install Python 3 version of supervisord-dependent-startup in Buster base container - Debian package installed binary in `/usr/bin/`, but pip package installs in `/usr/local/bin/`, so rather than update all absolute paths, I changed all references to simply call `supervisord` and let the system PATH find the executable to prevent future need for changes just in case we ever need to switch back to build a Debian package, then we won't need to modify these again. - Install Python 2 supervisor package >= 3.4.0 in Stretch and Jessie base containers --- .../pmon_daemon_control.json | 1 + dockers/docker-base-buster/Dockerfile.j2 | 22 +- dockers/docker-base-stretch/Dockerfile.j2 | 22 +- dockers/docker-base/Dockerfile.j2 | 10 +- dockers/docker-basic_router/Dockerfile | 2 +- .../docker-database/docker-database-init.sh | 4 +- .../docker-dhcp-relay.supervisord.conf.j2 | 2 +- dockers/docker-dhcp-relay/docker_init.sh | 2 +- dockers/docker-fpm-frr/docker_init.sh | 2 +- .../frr/supervisord/supervisord.conf.j2 | 2 +- dockers/docker-fpm-gobgp/Dockerfile.j2 | 2 +- dockers/docker-fpm-quagga/Dockerfile.j2 | 2 +- dockers/docker-iccpd/Dockerfile.j2 | 2 +- dockers/docker-iccpd/supervisord.conf | 2 +- dockers/docker-lldp/docker-lldp-init.sh | 2 +- dockers/docker-lldp/supervisord.conf.j2 | 2 +- dockers/docker-nat/Dockerfile.j2 | 3 +- dockers/docker-nat/supervisord.conf | 2 +- dockers/docker-orchagent/docker-init.sh | 2 +- dockers/docker-orchagent/supervisord.conf | 2 +- .../docker-pmon.supervisord.conf.j2 | 2 +- .../docker-platform-monitor/docker_init.sh | 2 +- .../docker-router-advertiser/docker-init.sh | 2 +- ...cker-router-advertiser.supervisord.conf.j2 | 2 +- dockers/docker-sflow/Dockerfile.j2 | 2 +- dockers/docker-sflow/supervisord.conf | 2 +- dockers/docker-snmp/Dockerfile.j2 | 2 +- dockers/docker-snmp/supervisord.conf | 2 +- .../docker-sonic-mgmt-framework/Dockerfile.j2 | 2 +- .../supervisord.conf | 2 +- dockers/docker-sonic-restapi/Dockerfile.j2 | 2 +- dockers/docker-sonic-restapi/supervisord.conf | 2 +- dockers/docker-sonic-telemetry/Dockerfile.j2 | 2 +- .../docker-sonic-telemetry/supervisord.conf | 2 +- dockers/docker-teamd/Dockerfile.j2 | 2 +- dockers/docker-teamd/supervisord.conf | 2 +- files/scripts/supervisor-proc-exit-listener | 7 +- .../barefoot/docker-saiserver-bfn/Dockerfile | 3 +- .../docker-syncd-bfn-rpc/Dockerfile.j2 | 3 +- .../barefoot/docker-syncd-bfn/Dockerfile.j2 | 3 +- .../docker-syncd-bfn/supervisord.conf | 2 +- .../docker-saiserver-brcm/Dockerfile.j2 | 2 +- .../docker-syncd-brcm-rpc/Dockerfile.j2 | 2 +- .../broadcom/docker-syncd-brcm/Dockerfile.j2 | 2 +- .../docker-syncd-brcm/supervisord.conf | 2 +- .../cavium/docker-saiserver-cavm/Dockerfile | 2 +- .../docker-syncd-cavm-rpc/Dockerfile.j2 | 2 +- .../cavium/docker-syncd-cavm/Dockerfile.j2 | 2 +- .../docker-syncd-centec-rpc/Dockerfile.j2 | 2 +- .../docker-syncd-centec/Dockerfile.j2 | 2 +- .../docker-syncd-centec/supervisord.conf | 2 +- .../docker-syncd-centec-rpc/Dockerfile.j2 | 2 +- .../centec/docker-syncd-centec/Dockerfile.j2 | 2 +- .../docker-syncd-centec/supervisord.conf | 2 +- .../docker-syncd-invm-rpc/Dockerfile.j2 | 2 +- .../innovium/docker-syncd-invm/Dockerfile.j2 | 2 +- .../docker-syncd-invm/supervisord.conf | 2 +- .../docker-syncd-mrvl-rpc/Dockerfile.j2 | 2 +- .../docker-syncd-mrvl/Dockerfile.j2 | 2 +- .../docker-syncd-mrvl/supervisord.conf | 2 +- .../docker-syncd-mrvl-rpc/Dockerfile.j2 | 2 +- .../docker-syncd-mrvl/Dockerfile.j2 | 2 +- .../docker-syncd-mrvl/supervisord.conf | 2 +- .../docker-syncd-mrvl-rpc/Dockerfile.j2 | 2 +- .../marvell/docker-syncd-mrvl/Dockerfile.j2 | 3 +- .../docker-syncd-mrvl/supervisord.conf | 2 +- .../docker-saiserver-mlnx/Dockerfile.j2 | 2 +- .../docker-syncd-mlnx-rpc/Dockerfile.j2 | 2 +- .../mellanox/docker-syncd-mlnx/Dockerfile.j2 | 2 +- .../docker-syncd-mlnx/supervisord.conf | 2 +- .../docker-syncd-nephos-rpc/Dockerfile.j2 | 2 +- .../nephos/docker-syncd-nephos/Dockerfile.j2 | 2 +- .../docker-syncd-nephos/supervisord.conf | 2 +- platform/vs/docker-gbsyncd-vs/Dockerfile.j2 | 2 +- .../vs/docker-gbsyncd-vs/supervisord.conf | 2 +- platform/vs/docker-sonic-vs/Dockerfile.j2 | 2 +- platform/vs/docker-syncd-vs/Dockerfile.j2 | 2 +- platform/vs/docker-syncd-vs/supervisord.conf | 2 +- rules/docker-base-buster.mk | 1 - rules/docker-base-stretch.mk | 1 - rules/docker-base.mk | 1 - rules/supervisor.dep | 10 - rules/supervisor.mk | 9 - sonic-slave-buster/Dockerfile.j2 | 3 - sonic-slave-jessie/Dockerfile.j2 | 3 - sonic-slave-stretch/Dockerfile.j2 | 3 - .../py2/docker-dhcp-relay.supervisord.conf | 2 +- .../py3/docker-dhcp-relay.supervisord.conf | 2 +- src/supervisor/.gitignore | 4 - src/supervisor/Makefile | 33 -- ...e-hanging-and-crashes-if-system-cloc.patch | 304 ------------------ .../patch/0002-oserror-armhf-assert.patch | 16 - src/supervisor/patch/series | 2 - src/supervisor/patch/series-armhf | 2 - 94 files changed, 114 insertions(+), 497 deletions(-) delete mode 100644 rules/supervisor.dep delete mode 100644 rules/supervisor.mk delete mode 100644 src/supervisor/.gitignore delete mode 100644 src/supervisor/Makefile delete mode 100644 src/supervisor/patch/0001-Prevent-excessive-hanging-and-crashes-if-system-cloc.patch delete mode 100644 src/supervisor/patch/0002-oserror-armhf-assert.patch delete mode 100644 src/supervisor/patch/series delete mode 100644 src/supervisor/patch/series-armhf diff --git a/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json b/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json index c6a21eb19fc5..101db0ffea1a 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json +++ b/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json @@ -1,6 +1,7 @@ { "skip_ledd": true, "skip_xcvrd": true, + "skip_pcied": true, "skip_psud": true, "skip_syseepromd": true, "skip_thermalctld": true diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index f113750450d7..bf1d8197bf40 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -50,9 +50,6 @@ RUN apt-get update && \ python3-pip \ rsyslog \ vim-tiny \ -# Install dependencies of supervisor - python-pkg-resources \ - python-meld3 \ # Install dependencies of redis-tools libatomic1 \ libjemalloc2 \ @@ -67,9 +64,6 @@ RUN apt-get update && \ # ip and ifconfig utility missing in docker for arm arch iproute2 \ net-tools \ -# for arm arch: Installing j2cli dependency package MarkupSafe from source relies on weeksetuptools and wheel - python-setuptools \ - python-wheel \ # for processing/handling json files in bash environment jq \ # for sairedis zmq rpc channel @@ -90,9 +84,22 @@ RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f -y RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb {% endif %} +# Some Python packages require setuptools (or pkg_resources, which is supplied by setuptools) +# and some require wheel +RUN pip install setuptools==40.8.0 +RUN pip3 install setuptools==49.6.00 +RUN pip install wheel +RUN pip3 install wheel + # For templating RUN pip2 install j2cli +# Install supervisor +RUN pip3 install supervisor==4.2.1 + +# Add support for supervisord to handle startup dependencies +RUN pip3 install supervisord-dependent-startup==1.4.0 + RUN mkdir -p /etc/supervisor /var/log/supervisor RUN apt-get -y purge \ @@ -109,9 +116,6 @@ RUN apt-get -y purge \ {{ install_debian_packages(docker_base_buster_debs.split(' ')) }} {%- endif %} -# Add support for supervisord to handle startup dependencies -RUN pip2 install supervisord-dependent-startup==1.4.0 - # Clean up apt # Remove /var/lib/apt/lists/*, could be obsoleted for derived images RUN apt-get clean -y && \ diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 2299b8bba656..aa6eda8a955c 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -47,9 +47,8 @@ RUN apt-get update && \ python \ python-pip \ vim-tiny \ -# Install dependencies of supervisor - python-pkg-resources \ - python-meld3 \ +# Install redis-tools + redis-tools=5:5.0.3-3~bpo9+2 \ # common dependencies libpython2.7 \ libdaemon0 \ @@ -58,9 +57,6 @@ RUN apt-get update && \ # ip and ifconfig utility missing in docker for arm arch iproute2 \ net-tools \ -# for arm arch: Installing j2cli dependency package MarkupSafe from source relies on weeksetuptools and wheel - python-setuptools \ - python-wheel \ # for processing json files in bash environment jq \ # for sairedis zmq rpc channel @@ -85,9 +81,20 @@ RUN apt-get -y -t stretch-backports install rsyslog RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb {% endif %} +# Some Python packages require setuptools (or pkg_resources, which is supplied by setuptools) +# and some require wheel +RUN pip install setuptools==40.8.0 +RUN pip install wheel + # For templating RUN pip install j2cli +# Install supervisor +RUN pip install supervisor>=3.4.0 + +# Add support for supervisord to handle startup dependencies +RUN pip install supervisord-dependent-startup==1.4.0 + RUN mkdir -p /etc/supervisor /var/log/supervisor RUN apt-get -y purge \ @@ -104,9 +111,6 @@ RUN apt-get -y purge \ {{ install_debian_packages(docker_base_stretch_debs.split(' ')) }} {%- endif %} -# Add support for supervisord to handle startup dependencies -RUN pip install supervisord-dependent-startup==1.4.0 - # Clean up apt # Remove /var/lib/apt/lists/*, could be obsoleted for derived images RUN apt-get clean -y && \ diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2 index e45235a1e139..591759bbcaad 100644 --- a/dockers/docker-base/Dockerfile.j2 +++ b/dockers/docker-base/Dockerfile.j2 @@ -44,6 +44,7 @@ RUN apt-get -y install \ vim-tiny \ perl \ python \ + python-pip \ rsyslog \ less @@ -51,8 +52,13 @@ COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"] COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"] COPY ["root/.vimrc", "/root/.vimrc"] -# Install dependencies of supervisor -RUN apt-get -y install python-pkg-resources python-meld3 +# Some Python packages require setuptools (or pkg_resources, which is supplied by setuptools) +# and some require wheel +RUN pip install setuptools==40.8.0 +RUN pip install wheel + +# Install supervisor +RUN pip install supervisor>=3.4.0 RUN mkdir -p /etc/supervisor RUN mkdir -p /var/log/supervisor diff --git a/dockers/docker-basic_router/Dockerfile b/dockers/docker-basic_router/Dockerfile index 7d7c724920c2..c5bccde72f85 100644 --- a/dockers/docker-basic_router/Dockerfile +++ b/dockers/docker-basic_router/Dockerfile @@ -19,4 +19,4 @@ RUN mv /deps/basic_router /usr/sbin/basic_router COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/dockers/docker-database/docker-database-init.sh b/dockers/docker-database/docker-database-init.sh index bc49376a0b53..33f0f80a31e8 100755 --- a/dockers/docker-database/docker-database-init.sh +++ b/dockers/docker-database/docker-database-init.sh @@ -55,7 +55,7 @@ if [[ $DATABASE_TYPE == "chassisdb" ]]; then # generate all redis server supervisord configuration file sonic-cfggen -j $db_cfg_file_tmp -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf rm $db_cfg_file_tmp - exec /usr/bin/supervisord + exec supervisord exit 0 fi @@ -79,4 +79,4 @@ else fi rm $db_cfg_file_tmp -exec /usr/bin/supervisord +exec supervisord diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index 9e8c553b65c6..1b5cadd00a4e 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-dhcp-relay/docker_init.sh b/dockers/docker-dhcp-relay/docker_init.sh index 9fc7a93e9958..9bdc6399ca2c 100755 --- a/dockers/docker-dhcp-relay/docker_init.sh +++ b/dockers/docker-dhcp-relay/docker_init.sh @@ -21,4 +21,4 @@ chmod +x /usr/bin/wait_for_intf.sh # The docker container should start this script as PID 1, so now that supervisord is # properly configured, we exec supervisord so that it runs as PID 1 for the # duration of the container's lifetime -exec /usr/bin/supervisord +exec supervisord diff --git a/dockers/docker-fpm-frr/docker_init.sh b/dockers/docker-fpm-frr/docker_init.sh index 25482866b495..dadd83276834 100755 --- a/dockers/docker-fpm-frr/docker_init.sh +++ b/dockers/docker-fpm-frr/docker_init.sh @@ -66,4 +66,4 @@ chmod 0755 /usr/sbin/bgp-unisolate mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status -exec /usr/bin/supervisord +exec supervisord diff --git a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 index 9c379404bc1a..205b57e5f616 100644 --- a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 +++ b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-fpm-gobgp/Dockerfile.j2 b/dockers/docker-fpm-gobgp/Dockerfile.j2 index b9b969edeb09..cb0fd21b8f62 100644 --- a/dockers/docker-fpm-gobgp/Dockerfile.j2 +++ b/dockers/docker-fpm-gobgp/Dockerfile.j2 @@ -27,4 +27,4 @@ COPY ["daemons", "/etc/quagga/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/dockers/docker-fpm-quagga/Dockerfile.j2 b/dockers/docker-fpm-quagga/Dockerfile.j2 index 9d1312d073ee..fccc7f08df0a 100644 --- a/dockers/docker-fpm-quagga/Dockerfile.j2 +++ b/dockers/docker-fpm-quagga/Dockerfile.j2 @@ -36,4 +36,4 @@ COPY ["*.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/dockers/docker-iccpd/Dockerfile.j2 b/dockers/docker-iccpd/Dockerfile.j2 index 7c5c98ac720d..f49bea7d84a5 100644 --- a/dockers/docker-iccpd/Dockerfile.j2 +++ b/dockers/docker-iccpd/Dockerfile.j2 @@ -31,4 +31,4 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/dockers/docker-iccpd/supervisord.conf b/dockers/docker-iccpd/supervisord.conf index 38d1ee56e643..716ca96b40c8 100644 --- a/dockers/docker-iccpd/supervisord.conf +++ b/dockers/docker-iccpd/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-lldp/docker-lldp-init.sh b/dockers/docker-lldp/docker-lldp-init.sh index ae507e8f506a..eee07b4adad0 100755 --- a/dockers/docker-lldp/docker-lldp-init.sh +++ b/dockers/docker-lldp/docker-lldp-init.sh @@ -2,4 +2,4 @@ #Generate supervisord.conf based on device metadata mkdir -p /etc/supervisor/conf.d/ sonic-cfggen -d -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf -exec /usr/bin/supervisord +exec supervisord diff --git a/dockers/docker-lldp/supervisord.conf.j2 b/dockers/docker-lldp/supervisord.conf.j2 index 5499e2af4678..3abd847c4a12 100644 --- a/dockers/docker-lldp/supervisord.conf.j2 +++ b/dockers/docker-lldp/supervisord.conf.j2 @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-nat/Dockerfile.j2 b/dockers/docker-nat/Dockerfile.j2 index 38930f7860e1..73b68dc70cc0 100644 --- a/dockers/docker-nat/Dockerfile.j2 +++ b/dockers/docker-nat/Dockerfile.j2 @@ -35,5 +35,4 @@ COPY ["critical_processes", "/etc/supervisor"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] - +ENTRYPOINT ["supervisord"] diff --git a/dockers/docker-nat/supervisord.conf b/dockers/docker-nat/supervisord.conf index 9840300ec163..8555f2a48ae6 100644 --- a/dockers/docker-nat/supervisord.conf +++ b/dockers/docker-nat/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-orchagent/docker-init.sh b/dockers/docker-orchagent/docker-init.sh index 41d815b4d7a9..b15c7cc3c91b 100755 --- a/dockers/docker-orchagent/docker-init.sh +++ b/dockers/docker-orchagent/docker-init.sh @@ -25,4 +25,4 @@ if [ "$VLAN" != "" ]; then cp /usr/share/sonic/templates/ndppd.conf /etc/supervisor/conf.d/ fi -exec /usr/bin/supervisord +exec supervisord diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 780a4d790464..8ec2b6354ab3 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index c44bbbbf8eb4..9ce4d4ca6de6 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-platform-monitor/docker_init.sh b/dockers/docker-platform-monitor/docker_init.sh index 2a821153aa3e..0039eb34d8be 100755 --- a/dockers/docker-platform-monitor/docker_init.sh +++ b/dockers/docker-platform-monitor/docker_init.sh @@ -40,4 +40,4 @@ if [ $HAVE_FANCONTROL_CONF -eq 1 ]; then /bin/cp -f $FANCONTROL_CONF_FILE /etc/ fi -exec /usr/bin/supervisord +exec supervisord diff --git a/dockers/docker-router-advertiser/docker-init.sh b/dockers/docker-router-advertiser/docker-init.sh index a3f373f438aa..28ffcb094cf1 100755 --- a/dockers/docker-router-advertiser/docker-init.sh +++ b/dockers/docker-router-advertiser/docker-init.sh @@ -14,4 +14,4 @@ sonic-cfggen $CFGGEN_PARAMS chmod +x /usr/bin/wait_for_link.sh -exec /usr/bin/supervisord +exec supervisord diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 index 5a6416b0ffd8..ae73cd6e9838 100644 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-sflow/Dockerfile.j2 b/dockers/docker-sflow/Dockerfile.j2 index e1d7ce72855a..db2d4b3bc0b6 100644 --- a/dockers/docker-sflow/Dockerfile.j2 +++ b/dockers/docker-sflow/Dockerfile.j2 @@ -32,4 +32,4 @@ COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] COPY ["port_index_mapper.py", "/usr/bin"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/dockers/docker-sflow/supervisord.conf b/dockers/docker-sflow/supervisord.conf index 2731d89d0681..8d1bdc5059cb 100644 --- a/dockers/docker-sflow/supervisord.conf +++ b/dockers/docker-sflow/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-snmp/Dockerfile.j2 b/dockers/docker-snmp/Dockerfile.j2 index 213d941c58f6..c98b955bf033 100644 --- a/dockers/docker-snmp/Dockerfile.j2 +++ b/dockers/docker-snmp/Dockerfile.j2 @@ -76,4 +76,4 @@ COPY ["critical_processes", "/etc/supervisor"] # Although exposing ports is not needed for host net mode, keep it for possible bridge mode EXPOSE 161/udp 162/udp -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/dockers/docker-snmp/supervisord.conf b/dockers/docker-snmp/supervisord.conf index 05f54122b59a..d1e6d09a8213 100644 --- a/dockers/docker-snmp/supervisord.conf +++ b/dockers/docker-snmp/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 index 24ae3643b36e..235d1a8e76c2 100644 --- a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 @@ -36,4 +36,4 @@ RUN apt-get remove -y g++ python-dev RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/dockers/docker-sonic-mgmt-framework/supervisord.conf b/dockers/docker-sonic-mgmt-framework/supervisord.conf index 5ff38f0f6213..f3060fb95d57 100644 --- a/dockers/docker-sonic-mgmt-framework/supervisord.conf +++ b/dockers/docker-sonic-mgmt-framework/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-sonic-restapi/Dockerfile.j2 b/dockers/docker-sonic-restapi/Dockerfile.j2 index 32904531f1fc..5463f0b44bc8 100644 --- a/dockers/docker-sonic-restapi/Dockerfile.j2 +++ b/dockers/docker-sonic-restapi/Dockerfile.j2 @@ -25,4 +25,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/dockers/docker-sonic-restapi/supervisord.conf b/dockers/docker-sonic-restapi/supervisord.conf index ac9a9fe18ac9..74bbc9241576 100644 --- a/dockers/docker-sonic-restapi/supervisord.conf +++ b/dockers/docker-sonic-restapi/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-sonic-telemetry/Dockerfile.j2 b/dockers/docker-sonic-telemetry/Dockerfile.j2 index 90bb1d574119..6670e75625ba 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/Dockerfile.j2 @@ -28,4 +28,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index f0578803a205..df1e6fa5a354 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/dockers/docker-teamd/Dockerfile.j2 b/dockers/docker-teamd/Dockerfile.j2 index d9795f20f59d..26250830b628 100644 --- a/dockers/docker-teamd/Dockerfile.j2 +++ b/dockers/docker-teamd/Dockerfile.j2 @@ -27,4 +27,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index c152932608c1..78549a7684f2 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index e81e6b31a82c..7fceaf74eef1 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import getopt import os @@ -7,7 +7,6 @@ import sys import syslog import swsssdk - from supervisor import childutils # Each line of this file should specify either one critical process or one @@ -27,7 +26,7 @@ def get_critical_group_and_process_list(): critical_process_list = [] with open(CRITICAL_PROCESSES_FILE, 'r') as file: - for line in file: + for line in file: line_info = line.strip(' \n').split(':') if len(line_info) != 2: syslog.syslog(syslog.LOG_ERR, "Syntax of the line {} in critical_processes file is incorrect. Exiting...".format(line)) @@ -86,7 +85,7 @@ def main(argv): syslog.syslog(syslog.LOG_ERR, "Unable to retrieve features table from Config DB. Exiting...") sys.exit(2) - if not features_table.has_key(container_name): + if container_name not in features_table: syslog.syslog(syslog.LOG_ERR, "Unable to retrieve feature '{}'. Exiting...".format(container_name)) sys.exit(3) diff --git a/platform/barefoot/docker-saiserver-bfn/Dockerfile b/platform/barefoot/docker-saiserver-bfn/Dockerfile index 427a551e0096..3f8071234b55 100755 --- a/platform/barefoot/docker-saiserver-bfn/Dockerfile +++ b/platform/barefoot/docker-saiserver-bfn/Dockerfile @@ -34,5 +34,4 @@ COPY ["profile.ini", "portmap.ini", "/etc/sai/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /deps -ENTRYPOINT ["/usr/bin/supervisord"] - +ENTRYPOINT ["supervisord"] diff --git a/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 index f10eb7fb5267..9b547dbcacec 100644 --- a/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 @@ -49,5 +49,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] - +ENTRYPOINT ["supervisord"] diff --git a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 index c12c36b1260b..712b15826c74 100755 --- a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 @@ -36,5 +36,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] - +ENTRYPOINT ["supervisord"] diff --git a/platform/barefoot/docker-syncd-bfn/supervisord.conf b/platform/barefoot/docker-syncd-bfn/supervisord.conf index 7137279103e4..39ea308277d7 100644 --- a/platform/barefoot/docker-syncd-bfn/supervisord.conf +++ b/platform/barefoot/docker-syncd-bfn/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 b/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 index 79dccf8f37a0..4294b79ff090 100644 --- a/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 @@ -33,4 +33,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 index 5b4f71144c2f..38dbf15b1288 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index ae517eac08ef..9c68eda56c99 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -32,4 +32,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index 77f6519c2e9f..a8e594c47aeb 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/platform/cavium/docker-saiserver-cavm/Dockerfile b/platform/cavium/docker-saiserver-cavm/Dockerfile index 2f667c8038ed..c73abb0e4bb2 100644 --- a/platform/cavium/docker-saiserver-cavm/Dockerfile +++ b/platform/cavium/docker-saiserver-cavm/Dockerfile @@ -27,4 +27,4 @@ COPY ["portmap.ini", "profile.ini", "/etc/sai/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf deps -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 b/platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 index 984855434807..2e1665d26029 100644 --- a/platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 +++ b/platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 index 0e2bc4b6bbc7..cdbd3d15dfdf 100755 --- a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 +++ b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 @@ -32,4 +32,4 @@ COPY ["profile.ini", "/etc/ssw/AS7512/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 b/platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 index 2174fd91f919..0802f3532c4a 100755 --- a/platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 +++ b/platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 b/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 index f105b1221283..7cb629f6ec58 100755 --- a/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 @@ -34,4 +34,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/centec-arm64/docker-syncd-centec/supervisord.conf b/platform/centec-arm64/docker-syncd-centec/supervisord.conf index 1a15c140a7be..111145021d83 100755 --- a/platform/centec-arm64/docker-syncd-centec/supervisord.conf +++ b/platform/centec-arm64/docker-syncd-centec/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 b/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 index 2174fd91f919..0802f3532c4a 100644 --- a/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/centec/docker-syncd-centec/Dockerfile.j2 b/platform/centec/docker-syncd-centec/Dockerfile.j2 index f6c875bab1cc..dfd19af47cd6 100755 --- a/platform/centec/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec/Dockerfile.j2 @@ -30,4 +30,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/centec/docker-syncd-centec/supervisord.conf b/platform/centec/docker-syncd-centec/supervisord.conf index dc6977ed4710..d5501500baab 100644 --- a/platform/centec/docker-syncd-centec/supervisord.conf +++ b/platform/centec/docker-syncd-centec/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 b/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 index af31d587b90a..8b6d6ae6ab8c 100755 --- a/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 +++ b/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 @@ -50,4 +50,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/innovium/docker-syncd-invm/Dockerfile.j2 b/platform/innovium/docker-syncd-invm/Dockerfile.j2 index 27054e23e472..0d6b1e8f48cc 100755 --- a/platform/innovium/docker-syncd-invm/Dockerfile.j2 +++ b/platform/innovium/docker-syncd-invm/Dockerfile.j2 @@ -30,4 +30,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/innovium/docker-syncd-invm/supervisord.conf b/platform/innovium/docker-syncd-invm/supervisord.conf index 2a2413b30098..b0890868b549 100755 --- a/platform/innovium/docker-syncd-invm/supervisord.conf +++ b/platform/innovium/docker-syncd-invm/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 b/platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 index cea067d2abf6..121166a805b4 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 +++ b/platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 index 5f5097f4b4aa..a9898e2f9ff2 100755 --- a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 @@ -34,4 +34,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf index 1a15c140a7be..111145021d83 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 b/platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 index cea067d2abf6..121166a805b4 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 +++ b/platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 index 5f5097f4b4aa..a9898e2f9ff2 100755 --- a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 @@ -34,4 +34,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf index 408899f8886b..9bf6ab7949ad 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 index cea067d2abf6..121166a805b4 100644 --- a/platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 index 5679fb38e338..b156095a17d6 100755 --- a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 @@ -30,5 +30,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] - +ENTRYPOINT ["supervisord"] diff --git a/platform/marvell/docker-syncd-mrvl/supervisord.conf b/platform/marvell/docker-syncd-mrvl/supervisord.conf index 73523ac02a12..c5aed305bfd7 100644 --- a/platform/marvell/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell/docker-syncd-mrvl/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 b/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 index b202be5b3401..5d901f4ed977 100644 --- a/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 @@ -44,4 +44,4 @@ COPY ["sai_2700.xml", "/usr/share/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 index 3f6225c96bd3..5119f7c412e1 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 @@ -62,4 +62,4 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index 21aaef2f3009..7fba0664306a 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -39,4 +39,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/mellanox/docker-syncd-mlnx/supervisord.conf b/platform/mellanox/docker-syncd-mlnx/supervisord.conf index 55578ff2dced..9311a255b0c8 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 index b4b4724e47ff..4f27ba6bce96 100644 --- a/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 index 967dad316967..6c3c42ac4376 100755 --- a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 @@ -43,4 +43,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/nephos/docker-syncd-nephos/supervisord.conf b/platform/nephos/docker-syncd-nephos/supervisord.conf index 55578ff2dced..9311a255b0c8 100644 --- a/platform/nephos/docker-syncd-nephos/supervisord.conf +++ b/platform/nephos/docker-syncd-nephos/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 index 316466dfb4ea..60bd79b2ee80 100644 --- a/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 +++ b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 @@ -31,4 +31,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/vs/docker-gbsyncd-vs/supervisord.conf b/platform/vs/docker-gbsyncd-vs/supervisord.conf index 6ba7ecbbdda2..3583ef6b5a8f 100644 --- a/platform/vs/docker-gbsyncd-vs/supervisord.conf +++ b/platform/vs/docker-gbsyncd-vs/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 5f5f91d5a0f0..b61981246115 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -170,4 +170,4 @@ RUN mkdir -p /var/warmboot/teamd ENV PLATFORM=x86_64-kvm_x86_64-r0 ENV HWSKU=Force10-S6000 -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/vs/docker-syncd-vs/Dockerfile.j2 b/platform/vs/docker-syncd-vs/Dockerfile.j2 index fea26b2f103e..5e3d992b56fb 100644 --- a/platform/vs/docker-syncd-vs/Dockerfile.j2 +++ b/platform/vs/docker-syncd-vs/Dockerfile.j2 @@ -31,4 +31,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["supervisord"] diff --git a/platform/vs/docker-syncd-vs/supervisord.conf b/platform/vs/docker-syncd-vs/supervisord.conf index 36e33850cbff..7416f23a45e5 100644 --- a/platform/vs/docker-syncd-vs/supervisord.conf +++ b/platform/vs/docker-syncd-vs/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/rules/docker-base-buster.mk b/rules/docker-base-buster.mk index 61ba96eda5fc..86bfc5781466 100644 --- a/rules/docker-base-buster.mk +++ b/rules/docker-base-buster.mk @@ -3,7 +3,6 @@ DOCKER_BASE_BUSTER = docker-base-buster.gz $(DOCKER_BASE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-base-buster -$(DOCKER_BASE_BUSTER)_DEPENDS += $(SUPERVISOR) $(DOCKER_BASE_BUSTER)_DEPENDS += $(SOCAT) GDB = gdb diff --git a/rules/docker-base-stretch.mk b/rules/docker-base-stretch.mk index 55b7fd9f8661..de10f808286e 100644 --- a/rules/docker-base-stretch.mk +++ b/rules/docker-base-stretch.mk @@ -2,7 +2,6 @@ DOCKER_BASE_STRETCH = docker-base-stretch.gz $(DOCKER_BASE_STRETCH)_PATH = $(DOCKERS_PATH)/docker-base-stretch -$(DOCKER_BASE_STRETCH)_DEPENDS += $(SUPERVISOR) $(DOCKER_BASE_STRETCH)_DEPENDS += $(SOCAT) GDB = gdb diff --git a/rules/docker-base.mk b/rules/docker-base.mk index 2d0653fc8f71..3b2ede987a70 100644 --- a/rules/docker-base.mk +++ b/rules/docker-base.mk @@ -2,7 +2,6 @@ DOCKER_BASE = docker-base.gz $(DOCKER_BASE)_PATH = $(DOCKERS_PATH)/docker-base -$(DOCKER_BASE)_DEPENDS += $(SUPERVISOR) $(DOCKER_BASE)_DEPENDS += $(BASH) $(DOCKER_BASE)_DEPENDS += $(SOCAT) diff --git a/rules/supervisor.dep b/rules/supervisor.dep deleted file mode 100644 index 7d7bcf36e952..000000000000 --- a/rules/supervisor.dep +++ /dev/null @@ -1,10 +0,0 @@ - -SPATH := $($(SUPERVISOR)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/supervisor.mk rules/supervisor.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(SPATH)) - -$(SUPERVISOR)_CACHE_MODE := GIT_CONTENT_SHA -$(SUPERVISOR)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SUPERVISOR)_DEP_FILES := $(DEP_FILES) - diff --git a/rules/supervisor.mk b/rules/supervisor.mk deleted file mode 100644 index cd97eabf801d..000000000000 --- a/rules/supervisor.mk +++ /dev/null @@ -1,9 +0,0 @@ -# supervisor package - -SUPERVISOR_VERSION = 3.3.3 - -export SUPERVISOR_VERSION - -SUPERVISOR = python-supervisor_$(SUPERVISOR_VERSION)-1_all.deb -$(SUPERVISOR)_SRC_PATH = $(SRC_PATH)/supervisor -SONIC_MAKE_DEBS += $(SUPERVISOR) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 101008fa4aac..b58027bf30d4 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -382,9 +382,6 @@ RUN pip3 install "lxml==4.6.1" # For sonic-platform-common testing RUN pip3 install redis -# For supervisor build -RUN apt-get install python-meld3 - # For vs image build RUN pip2 install pexpect==4.6.0 RUN pip3 install pexpect==4.8.0 diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index 32db448de25e..ae5bd2b14f15 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -300,9 +300,6 @@ RUN pip install --force-reinstall --upgrade "jinja2>=2.10" # For templating (requiring jinja2) RUN pip install j2cli==0.3.10 -# For supervisor build -RUN pip install meld3 mock - # For vs image build RUN pip install pexpect==4.6.0 diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 84d87e5973c6..59a7044f3855 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -365,9 +365,6 @@ RUN pip3 install "lxml==4.6.1" # For sonic-platform-common testing RUN pip3 install redis -# For supervisor build -RUN pip2 install meld3 mock - # For vs image build RUN pip2 install pexpect==4.6.0 diff --git a/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf index be52694b78c5..a213a2517866 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf index 3e485f4ddc35..d5338b18cfa1 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:dependent-startup] -command=python -m supervisord_dependent_startup +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected startretries=0 diff --git a/src/supervisor/.gitignore b/src/supervisor/.gitignore deleted file mode 100644 index d19db76ab9a9..000000000000 --- a/src/supervisor/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!.gitignore -!Makefile -!patch/ diff --git a/src/supervisor/Makefile b/src/supervisor/Makefile deleted file mode 100644 index 2bd2724a39a1..000000000000 --- a/src/supervisor/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -.ONESHELL: -SHELL = /bin/bash -.SHELLFLAGS += -e - -MAIN_TARGET = python-supervisor_$(SUPERVISOR_VERSION)-1_all.deb - -$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : - # Remove any stale files - rm -rf ./supervisor - - # Clone supervisor repo - git clone https://github.com/Supervisor/supervisor.git - pushd ./supervisor - - # Reset HEAD to the commit of the proper tag - # NOTE: Using "git checkout " here detaches our HEAD, - # which stg doesn't like, so we use this method instead - git reset --hard $(SUPERVISOR_VERSION) - - # Apply patches - stg init - stg import -s ../patch/series - -ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) - stg import -s ../patch/series-armhf -endif - - # Build Python and Debian package - python setup.py --command-packages=stdeb.command bdist_deb - popd - - # Move the newly-built .deb packages to the destination directory - mv ./supervisor/deb_dist/$* $(DEST)/ diff --git a/src/supervisor/patch/0001-Prevent-excessive-hanging-and-crashes-if-system-cloc.patch b/src/supervisor/patch/0001-Prevent-excessive-hanging-and-crashes-if-system-cloc.patch deleted file mode 100644 index 6c4a6b7c2a4c..000000000000 --- a/src/supervisor/patch/0001-Prevent-excessive-hanging-and-crashes-if-system-cloc.patch +++ /dev/null @@ -1,304 +0,0 @@ -From 5b56519e68e866662d9fd9a6681b6b47d6b5fcdb Mon Sep 17 00:00:00 2001 -From: Joe LeVeque -Date: Thu, 28 Feb 2019 01:43:54 +0000 -Subject: [PATCH] Prevent excessive hanging and crashes if system clock rolls - backward - ---- - supervisor/process.py | 36 ++++++ - supervisor/tests/test_process.py | 183 +++++++++++++++++++++++++++++++ - 2 files changed, 219 insertions(+) - -diff --git a/supervisor/process.py b/supervisor/process.py -index f9ddcd9..5f73e6b 100644 ---- a/supervisor/process.py -+++ b/supervisor/process.py -@@ -347,6 +347,28 @@ class Subprocess: - options.write(2, "supervisor: child process was not spawned\n") - options._exit(127) # exit process with code for spawn failure - -+ def _check_and_adjust_for_system_clock_rollback(self, test_time): -+ """ -+ Check if system clock has rolled backward beyond test_time. If so, set -+ affected timestamps to test_time. -+ """ -+ if self.state == ProcessStates.STARTING: -+ if test_time < self.laststart: -+ self.laststart = test_time; -+ if self.delay > 0 and test_time < (self.delay - self.config.startsecs): -+ self.delay = test_time + self.config.startsecs -+ elif self.state == ProcessStates.RUNNING: -+ if test_time > self.laststart and test_time < (self.laststart + self.config.startsecs): -+ self.laststart = test_time - self.config.startsecs -+ elif self.state == ProcessStates.STOPPING: -+ if test_time < self.laststopreport: -+ self.laststopreport = test_time; -+ if self.delay > 0 and test_time < (self.delay - self.config.stopwaitsecs): -+ self.delay = test_time + self.config.stopwaitsecs -+ elif self.state == ProcessStates.BACKOFF: -+ if self.delay > 0 and test_time < (self.delay - self.backoff): -+ self.delay = test_time + self.backoff -+ - def stop(self): - """ Administrative stop """ - self.administrative_stop = True -@@ -357,6 +379,9 @@ class Subprocess: - """ Log a 'waiting for x to stop' message with throttling. """ - if self.state == ProcessStates.STOPPING: - now = time.time() -+ -+ self._check_and_adjust_for_system_clock_rollback(now) -+ - if now > (self.laststopreport + 2): # every 2 seconds - self.config.options.logger.info( - 'waiting for %s to stop' % self.config.name) -@@ -487,6 +512,9 @@ class Subprocess: - es, msg = decode_wait_status(sts) - - now = time.time() -+ -+ self._check_and_adjust_for_system_clock_rollback(now) -+ - self.laststop = now - processname = self.config.name - -@@ -586,6 +614,8 @@ class Subprocess: - now = time.time() - state = self.state - -+ self._check_and_adjust_for_system_clock_rollback(now) -+ - logger = self.config.options.logger - - if self.config.options.mood > SupervisorStates.RESTARTING: -@@ -805,6 +835,12 @@ class EventListenerPool(ProcessGroupBase): - if dispatch_capable: - if self.dispatch_throttle: - now = time.time() -+ -+ if now < self.last_dispatch: -+ # The system clock appears to have moved backward -+ # Reset self.last_dispatch accordingly -+ self.last_dispatch = now; -+ - if now - self.last_dispatch < self.dispatch_throttle: - return - self.dispatch() -diff --git a/supervisor/tests/test_process.py b/supervisor/tests/test_process.py -index 7f9bab2..6808f60 100644 ---- a/supervisor/tests/test_process.py -+++ b/supervisor/tests/test_process.py -@@ -736,6 +736,40 @@ class SubprocessTests(unittest.TestCase): - instance.stop_report() - self.assertEqual(len(options.logger.data), 1) # throttled - -+ def test_stop_report_laststopreport_in_future(self): -+ future_time = time.time() + 3600 # 1 hour into the future -+ options = DummyOptions() -+ config = DummyPConfig(options, 'test', '/test') -+ instance = self._makeOne(config) -+ instance.pid = 11 -+ dispatcher = DummyDispatcher(writable=True) -+ instance.dispatchers = {'foo':dispatcher} -+ from supervisor.states import ProcessStates -+ instance.state = ProcessStates.STOPPING -+ instance.laststopreport = future_time -+ -+ # This iteration of stop_report() should reset instance.laststopreport -+ # to the current time -+ instance.stop_report() -+ -+ # No logging should have taken place -+ self.assertEqual(len(options.logger.data), 0) -+ -+ # Ensure instance.laststopreport has rolled backward -+ self.assertTrue(instance.laststopreport < future_time) -+ -+ # Sleep for 2 seconds -+ time.sleep(2) -+ -+ # This iteration of stop_report() should actaully trigger the report -+ instance.stop_report() -+ -+ self.assertEqual(len(options.logger.data), 1) -+ self.assertEqual(options.logger.data[0], 'waiting for test to stop') -+ self.assertNotEqual(instance.laststopreport, 0) -+ instance.stop_report() -+ self.assertEqual(len(options.logger.data), 1) # throttled -+ - def test_give_up(self): - options = DummyOptions() - config = DummyPConfig(options, 'test', '/test') -@@ -1105,6 +1139,43 @@ class SubprocessTests(unittest.TestCase): - self.assertEqual(event.__class__, events.ProcessStateBackoffEvent) - self.assertEqual(event.from_state, ProcessStates.STARTING) - -+ # This tests the case where the process has stayed alive longer than -+ # startsecs (i.e., long enough to enter the RUNNING state), however the -+ # system clock has since rolled backward such that the current time is -+ # greater than laststart but less than startsecs. -+ def test_finish_running_state_exited_too_quickly_due_to_clock_rollback(self): -+ options = DummyOptions() -+ config = DummyPConfig(options, 'notthere', '/notthere', -+ stdout_logfile='/tmp/foo', startsecs=10) -+ instance = self._makeOne(config) -+ instance.config.options.pidhistory[123] = instance -+ pipes = {'stdout':'','stderr':''} -+ instance.pipes = pipes -+ instance.config.exitcodes =[-1] -+ instance.laststart = time.time() -+ from supervisor.states import ProcessStates -+ from supervisor import events -+ instance.state = ProcessStates.RUNNING -+ L = [] -+ events.subscribe(events.ProcessStateEvent, lambda x: L.append(x)) -+ instance.pid = 123 -+ instance.finish(123, 1) -+ self.assertFalse(instance.killing) -+ self.assertEqual(instance.pid, 0) -+ self.assertEqual(options.parent_pipes_closed, pipes) -+ self.assertEqual(instance.pipes, {}) -+ self.assertEqual(instance.dispatchers, {}) -+ self.assertEqual(options.logger.data[0], -+ 'exited: notthere (terminated by SIGHUP; expected)') -+ self.assertEqual(instance.exitstatus, -1) -+ self.assertEqual(len(L), 1) -+ event = L[0] -+ self.assertEqual(event.__class__, -+ events.ProcessStateExitedEvent) -+ self.assertEqual(event.expected, True) -+ self.assertEqual(event.extra_values, [('expected', True), ('pid', 123)]) -+ self.assertEqual(event.from_state, ProcessStates.RUNNING) -+ - def test_finish_running_state_laststart_in_future(self): - options = DummyOptions() - config = DummyPConfig(options, 'notthere', '/notthere', -@@ -1402,6 +1473,92 @@ class SubprocessTests(unittest.TestCase): - event = L[0] - self.assertEqual(event.__class__, events.ProcessStateRunningEvent) - -+ def test_transition_starting_to_running_laststart_in_future(self): -+ from supervisor import events -+ L = [] -+ events.subscribe(events.ProcessStateEvent, lambda x: L.append(x)) -+ from supervisor.states import ProcessStates -+ -+ future_time = time.time() + 3600 # 1 hour into the future -+ options = DummyOptions() -+ test_startsecs = 2 -+ -+ # this should go from STARTING to RUNNING via transition() -+ pconfig = DummyPConfig(options, 'process', 'process','/bin/process', -+ startsecs=test_startsecs) -+ process = self._makeOne(pconfig) -+ process.backoff = 1 -+ process.delay = 1 -+ process.system_stop = False -+ process.laststart = future_time -+ process.pid = 1 -+ process.stdout_buffer = 'abc' -+ process.stderr_buffer = 'def' -+ process.state = ProcessStates.STARTING -+ -+ # This iteration of transition() should reset process.laststart -+ # to the current time -+ process.transition() -+ -+ # Process state should still be STARTING -+ self.assertEqual(process.state, ProcessStates.STARTING) -+ -+ # Ensure process.laststart has rolled backward -+ self.assertTrue(process.laststart < future_time) -+ -+ # Sleep for (startsecs + 1) -+ time.sleep(test_startsecs + 1) -+ -+ # This iteration of transition() should actaully trigger the state -+ # transition to RUNNING -+ process.transition() -+ -+ # this implies RUNNING -+ self.assertEqual(process.backoff, 0) -+ self.assertEqual(process.delay, 0) -+ self.assertFalse(process.system_stop) -+ self.assertEqual(process.state, ProcessStates.RUNNING) -+ self.assertEqual(options.logger.data[0], -+ 'success: process entered RUNNING state, process has ' -+ 'stayed up for > than {} seconds (startsecs)'.format(test_startsecs)) -+ self.assertEqual(len(L), 1) -+ event = L[0] -+ self.assertEqual(event.__class__, events.ProcessStateRunningEvent) -+ -+ def test_transition_backoff_to_starting_delay_in_future(self): -+ from supervisor import events -+ L = [] -+ events.subscribe(events.ProcessStateEvent, lambda x: L.append(x)) -+ from supervisor.states import ProcessStates, SupervisorStates -+ -+ future_time = time.time() + 3600 # 1 hour into the future -+ options = DummyOptions() -+ -+ pconfig = DummyPConfig(options, 'process', 'process','/bin/process') -+ process = self._makeOne(pconfig) -+ process.laststart = 1 -+ process.delay = future_time -+ process.backoff = 0 -+ process.state = ProcessStates.BACKOFF -+ -+ # This iteration of transition() should reset process.delay -+ # to the current time -+ process.transition() -+ -+ # Process state should still be BACKOFF -+ self.assertEqual(process.state, ProcessStates.BACKOFF) -+ -+ # Ensure process.delay has rolled backward -+ self.assertTrue(process.delay < future_time) -+ -+ # This iteration of transition() should actaully trigger the state -+ # transition to STARTING -+ process.transition() -+ -+ self.assertEqual(process.state, ProcessStates.STARTING) -+ self.assertEqual(len(L), 1) -+ self.assertEqual(L[0].__class__, events.ProcessStateStartingEvent) -+ - def test_transition_backoff_to_fatal(self): - from supervisor import events - L = [] -@@ -2033,6 +2190,32 @@ class EventListenerPoolTests(ProcessGroupBaseTests): - self.assertEqual(process1.listener_state, EventListenerStates.BUSY) - self.assertEqual(process1.event, event) - -+ def test_transition_event_proc_running_with_dispatch_throttle_last_dispatch_in_future(self): -+ future_time = time.time() + 3600 # 1 hour into the future -+ options = DummyOptions() -+ from supervisor.states import ProcessStates -+ pconfig1 = DummyPConfig(options, 'process1', 'process1','/bin/process1') -+ process1 = DummyProcess(pconfig1, state=ProcessStates.RUNNING) -+ gconfig = DummyPGroupConfig(options, pconfigs=[pconfig1]) -+ pool = self._makeOne(gconfig) -+ pool.dispatch_throttle = 5 -+ pool.last_dispatch = future_time -+ pool.processes = {'process1': process1} -+ event = DummyEvent() -+ from supervisor.states import EventListenerStates -+ process1.listener_state = EventListenerStates.READY -+ class DummyGroup: -+ config = gconfig -+ process1.group = DummyGroup -+ pool._acceptEvent(event) -+ pool.transition() -+ -+ self.assertEqual(process1.transitioned, True) -+ self.assertEqual(pool.event_buffer, [event]) # not popped -+ -+ # Ensure pool.last_dispatch has been rolled backward -+ self.assertTrue(pool.last_dispatch < future_time) -+ - def test__dispatchEvent_notready(self): - options = DummyOptions() - from supervisor.states import ProcessStates --- -2.17.1 - diff --git a/src/supervisor/patch/0002-oserror-armhf-assert.patch b/src/supervisor/patch/0002-oserror-armhf-assert.patch deleted file mode 100644 index 0a06bfe71163..000000000000 --- a/src/supervisor/patch/0002-oserror-armhf-assert.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/supervisor/tests/test_options.py b/supervisor/tests/test_options.py ---- a/supervisor/tests/test_options.py -+++ b/supervisor/tests/test_options.py -@@ -1514,9 +1514,9 @@ - os.read(innie, 0) # we can read it while its open - os.write(outie, 'foo') # we can write to it while its open - instance.close_fd(innie) -- self.assertRaises(OSError, os.read, innie, 0) -+ #self.assertRaises(OSError, os.read, innie, 0) - instance.close_fd(outie) -- self.assertRaises(OSError, os.write, outie, 'foo') -+ #self.assertRaises(OSError, os.write, outie, 'foo') - - @patch('os.close', Mock(side_effect=OSError)) - def test_close_fd_ignores_oserror(self): - diff --git a/src/supervisor/patch/series b/src/supervisor/patch/series deleted file mode 100644 index 9d87dccfa780..000000000000 --- a/src/supervisor/patch/series +++ /dev/null @@ -1,2 +0,0 @@ -# This series applies on GIT commit 34b690aea8cf7572d73765c95c54a83261d69aad -0001-Prevent-excessive-hanging-and-crashes-if-system-cloc.patch diff --git a/src/supervisor/patch/series-armhf b/src/supervisor/patch/series-armhf deleted file mode 100644 index 6a52e31cbf98..000000000000 --- a/src/supervisor/patch/series-armhf +++ /dev/null @@ -1,2 +0,0 @@ -# This series applies on GIT commit 34b690aea8cf7572d73765c95c54a83261d69aad -0002-oserror-armhf-assert.patch From 461e43649b803c12f30bbe889bf2bef336fe4344 Mon Sep 17 00:00:00 2001 From: JiangboHe <57433992+JiangboHe@users.noreply.github.com> Date: Sat, 21 Nov 2020 02:37:45 +0800 Subject: [PATCH 1416/1427] fix error: interface counters is mismatch after warm-reboot (#5346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Why I did it There is a issue for counters after warm-reboot: If I clear counters by command "sonic-clear counters", then execute 'warm-reboot' and whenSONiC is restart, the counters showed with command "show interface counters" is still old counters before "sonic-clear". It is not the right counters because the counters file in '/tmp' is lost in warm-reboot process. - How I did it I fixed it by saving '/tmp/portstat-0' folders in '/host/' before executing 'warm-reboot' (in pull request Azure/sonic-utilities#1099 ), and restore the counters folders back to '/tmp/' after warm-reboot process is finished. - How to verify it Clear counters by command 'sonic-clear' sonic-clear counters sonic-clear dropcounters sonic-clear pfccounters sonic-clear queuecounters sonic-clear rifcounters Execute 'warm-reboot' Use command ‘show interface counters’ to see if the counters is right. --- .../warmboot-finalizer/finalize-warmboot.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index 2cde4028396b..094fff2133f7 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -76,6 +76,20 @@ function stop_control_plane_assistant() fi } +function restore_counters_folder() +{ + debug "Restoring counters folder after warmboot..." + + modules=("portstat-0" "dropstat" "pfcstat-0" "queuestat-0" "intfstat-0") + for module in ${modules[@]} + do + statfile="/host/counters/$module" + if [[ -d $statfile ]]; then + mv $statfile /tmp/ + fi + done +} + wait_for_database_service @@ -86,6 +100,8 @@ if [[ x"${WARM_BOOT}" != x"true" ]]; then exit 0 fi +restore_counters_folder + list=${COMP_LIST} # Wait up to 5 minutes From 23247514f9ae5afcda6442474d64f91725e13b5b Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 20 Nov 2020 10:58:48 -0800 Subject: [PATCH 1417/1427] Fix a number of LGTM alerts (#5952) Fix 259 alerts reported by the LGTM tool: - 245 for Unused import - 7 for Testing equality to None - 5 for Duplicate key in dict literal - 1 for Module is imported more than once - 1 for Unused local variable --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 2 +- .../build_scripts/generate_asic_config_checksum.py | 2 +- .../image_config/corefile_uploader/core_uploader.py | 1 - .../as4630-54pe/utils/accton_as4630_54pe_monitor.py | 10 ++-------- .../utils/accton_as4630_54pe_monitor_fan.py | 11 ++--------- .../utils/accton_as4630_54pe_monitor_psu.py | 10 ++-------- .../as4630-54pe/utils/accton_as4630_54pe_util.py | 6 ++---- .../as5712-54x/utils/accton_as5712_monitor.py | 9 +-------- .../as5712-54x/utils/accton_as5712_util.py | 8 ++++---- .../as5812-54t/utils/accton_as5812_monitor.py | 10 ++-------- .../as5812-54t/utils/accton_as5812_util.py | 5 ++--- .../as5812-54x/utils/accton_as5812_monitor.py | 10 ++-------- .../as5812-54x/utils/accton_as5812_util.py | 8 ++++---- .../as5835-54t/utils/accton_as5835_54t_monitor.py | 12 +++--------- .../utils/accton_as5835_54t_monitor_fan.py | 10 ++-------- .../utils/accton_as5835_54t_monitor_psu.py | 10 ++-------- .../as5835-54t/utils/accton_as5835_54t_util.py | 5 ++--- .../as5835-54x/utils/accton_as5835_54x_monitor.py | 12 +++--------- .../utils/accton_as5835_54x_monitor_fan.py | 10 ++-------- .../utils/accton_as5835_54x_monitor_psu.py | 10 ++-------- .../as5835-54x/utils/accton_as5835_54x_util.py | 5 ++--- .../as6712-32x/utils/accton_as6712_monitor.py | 10 ++-------- .../as6712-32x/utils/accton_as6712_util.py | 5 ++--- .../as7312-54x/utils/accton_as7312_monitor.py | 10 ++-------- .../as7312-54x/utils/accton_as7312_util.py | 5 ++--- .../as7312-54xs/utils/accton_as7312_monitor.py | 10 ++-------- .../as7312-54xs/utils/accton_as7312_util.py | 5 ++--- .../as7315-27xb/utils/accton_as7315_monitor.py | 10 ++-------- .../as7315-27xb/utils/accton_as7315_util.py | 5 ++--- .../as7326-56x/utils/accton_as7326_monitor.py | 9 ++------- .../as7326-56x/utils/accton_as7326_monitor_fan.py | 11 ++--------- .../as7326-56x/utils/accton_as7326_monitor_psu.py | 10 ++-------- .../as7326-56x/utils/accton_as7326_util.py | 5 ++--- .../as7712-32x/utils/accton_as7712_util.py | 5 ++--- .../as7716-32x/utils/accton_as7716_monitor.py | 10 ++-------- .../as7716-32x/utils/accton_as7716_util.py | 6 ++---- .../utils/accton_as7716_32xb_drv_handler.py | 10 ++-------- .../as7716-32xb/utils/accton_as7716_32xb_monitor.py | 10 ++-------- .../as7716-32xb/utils/accton_as7716_32xb_util.py | 7 ++----- .../as7726-32x/utils/accton_as7726_32x_monitor.py | 9 ++------- .../utils/accton_as7726_32x_monitor_fan.py | 11 ++--------- .../utils/accton_as7726_32x_monitor_psu.py | 10 ++-------- .../as7726-32x/utils/accton_as7726_32x_util.py | 6 ++---- .../as7816-64x/utils/accton_as7816_monitor.py | 10 ++-------- .../as7816-64x/utils/accton_as7816_util.py | 6 ++---- .../as9716-32d/utils/accton_as9716_32d_monitor.py | 10 ++-------- .../utils/accton_as9716_32d_monitor_fan.py | 11 ++--------- .../utils/accton_as9716_32d_monitor_psu.py | 10 ++-------- .../as9716-32d/utils/accton_as9716_32d_util.py | 6 ++---- .../minipack/utils/accton_minipack_util.py | 5 ++--- .../minipack/utils/setup_qsfp_eeprom.py | 4 ++-- .../cs5435-54p/utils/cig_cs5435_misc.py | 2 +- .../cs6436-54p/utils/cig_cs6436_misc.py | 2 +- .../cs6436-56p/utils/cig_cs6436_misc.py | 2 +- src/sonic-config-engine/config_samples.py | 2 -- src/sonic-config-engine/minigraph.py | 13 ++++--------- src/sonic-config-engine/portconfig.py | 8 ++++---- 57 files changed, 114 insertions(+), 322 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 09d7fe272edb..09ba9f22e51e 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -186,7 +186,7 @@ def get_transceiver_change_event(self, timeout=0): phy_port_dict = {} status = True - if self.db_sel == None: + if self.db_sel is None: from swsscommon import swsscommon self.state_db = swsscommon.DBConnector("STATE_DB", REDIS_TIMEOUT_USECS, diff --git a/files/build_scripts/generate_asic_config_checksum.py b/files/build_scripts/generate_asic_config_checksum.py index 41ef6f045e21..2e7aaf0f5842 100755 --- a/files/build_scripts/generate_asic_config_checksum.py +++ b/files/build_scripts/generate_asic_config_checksum.py @@ -57,7 +57,7 @@ def generate_checksum(checksum_files): def main(): config_files = sorted(get_config_files(CONFIG_FILES)) checksum = generate_checksum(config_files) - if checksum == None: + if checksum is None: exit(1) with open(OUTPUT_FILE, 'w') as output: diff --git a/files/image_config/corefile_uploader/core_uploader.py b/files/image_config/corefile_uploader/core_uploader.py index 4807425f4307..ac242006e8c7 100755 --- a/files/image_config/corefile_uploader/core_uploader.py +++ b/files/image_config/corefile_uploader/core_uploader.py @@ -219,7 +219,6 @@ def handle_file(path): def upload_file(fname, fpath, coref): daemonname = fname.split(".")[0] i = 0 - fail_msg = "" while True: try: diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py index 6dbf5c2cc720..8913233366e2 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py @@ -20,19 +20,13 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time - import traceback import commands - from tabulate import tabulate from as4630_54pe.fanutil import FanUtil from as4630_54pe.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py index 11453818b04c..c775e86874b8 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py @@ -22,19 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate - except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py index 8ef700f33ca0..02f4541127a7 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py index fbfa46377fa2..ed0df177ee13 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py @@ -29,13 +29,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as4630_54pe' version = '0.0.1' @@ -54,7 +53,6 @@ 'fan3': ['fan'], 'fan4': ['fan'], 'fan5': ['fan'], - 'fan5': ['fan'], } hwmon_nodes = {'led': ['brightness'] , 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py index 09b2b9ea96bd..f032088dc525 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py @@ -23,18 +23,11 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as5712_54x.fanutil import FanUtil from as5712_54x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py index 944fb98ada54..71927f933b92 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py @@ -31,11 +31,11 @@ import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as5712_54x' version = '0.2.0' @@ -546,7 +546,7 @@ def cpld_path_of_port(port_index): def get_path_sfp_tx_dis(port_index): cpld_p = cpld_path_of_port(port_index) - if cpld_p == None: + if cpld_p is None: return False, '' else: dev = cpld_p+"module_tx_disable_"+str(port_index) @@ -554,7 +554,7 @@ def get_path_sfp_tx_dis(port_index): def get_path_sfp_presence(port_index): cpld_p = cpld_path_of_port(port_index) - if cpld_p == None: + if cpld_p is None: return False, '' else: dev = cpld_p+"module_present_"+str(port_index) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_monitor.py index c8574557b3d1..6f55e703d7d1 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_monitor.py @@ -23,19 +23,13 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as5812_54t.fanutil import FanUtil from as5812_54t.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py index cad526e17af5..e5ec4fa856d2 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py index 8c7303efaa78..5e3b368659cc 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py @@ -23,19 +23,13 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as5812_54x.fanutil import FanUtil from as5812_54x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py index ba526d110a7b..35ae80f5385d 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py @@ -31,11 +31,11 @@ import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as5812_54x' version = '0.2.0' @@ -546,7 +546,7 @@ def cpld_path_of_port(port_index): def get_path_sfp_tx_dis(port_index): cpld_p = cpld_path_of_port(port_index) - if cpld_p == None: + if cpld_p is None: return False, '' else: dev = cpld_p+"module_tx_disable_"+str(port_index) @@ -554,7 +554,7 @@ def get_path_sfp_tx_dis(port_index): def get_path_sfp_presence(port_index): cpld_p = cpld_path_of_port(port_index) - if cpld_p == None: + if cpld_p is None: return False, '' else: dev = cpld_p+"module_present_"+str(port_index) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor.py index ce2e0d18d4ff..ceea8e12f852 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor.py @@ -25,18 +25,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as5835_54t.fanutil import FanUtil from as5835_54t.thermalutil import ThermalUtil except ImportError as e: @@ -203,4 +197,4 @@ def main(argv): time.sleep(10) if __name__ == '__main__': - main(sys.argv[1:]) \ No newline at end of file + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_fan.py index d1d93d4f8aea..7978012b0da0 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_fan.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_psu.py index 51837c7262ba..9be72fda9993 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_util.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_util.py index 88d5bc254628..84625fd6dbf9 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor.py index 5789288546b6..9c5e955ce17d 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor.py @@ -24,18 +24,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as5835_54x.fanutil import FanUtil from as5835_54x.thermalutil import ThermalUtil except ImportError as e: @@ -202,4 +196,4 @@ def main(argv): time.sleep(10) if __name__ == '__main__': - main(sys.argv[1:]) \ No newline at end of file + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_fan.py index 791c80a92b89..dec1e036142d 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_fan.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_psu.py index d7bd1a1f2515..f994d635239a 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py index 615bf6ea208f..ee722ea03040 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple diff --git a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_monitor.py index fbcc74565d62..07e40f6b7fb4 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_monitor.py @@ -24,17 +24,11 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as6712_32x.fanutil import FanUtil from as6712_32x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_util.py b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_util.py index 48e957e31257..20968d57a91f 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_util.py @@ -37,13 +37,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as6712_32x' version = '0.2.0' diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py index 19d7470515f9..8e115c3ad88b 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py @@ -24,18 +24,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as7312_54x.fanutil import FanUtil from as7312_54x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py index b8107c47afea..f5438f28f6fc 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_monitor.py index 09bc99c75aba..58ffe1923a85 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_monitor.py @@ -24,18 +24,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as7312_54xs.fanutil import FanUtil from as7312_54xs.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_util.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_util.py index 9b5803b07afd..4b2ebbe1cca2 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple diff --git a/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_monitor.py index 5d821350ac81..d5b868255f4a 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_monitor.py @@ -24,18 +24,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as7315_27xb.fanutil import FanUtil from as7315_27xb.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_util.py b/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_util.py index ea856e4ff56b..869a7784f0d9 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py index b775d97edda9..07ec446ab88e 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py @@ -24,17 +24,12 @@ try: import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as7326_56x.fanutil import FanUtil from as7326_56x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_fan.py index 6fa429d01314..b52ada307698 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_fan.py @@ -22,19 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate - except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_psu.py index d76c20bd5a9b..cb897b942aeb 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py index 0e08f0b62aed..cc04c1de38a9 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py @@ -39,13 +39,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py index c8b755b85b69..9741c506b2d1 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py index 63f26d5d2ef6..c423cc441d92 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py @@ -23,17 +23,11 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as7716_32x.fanutil import FanUtil from as7716_32x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py index b195165337d1..7be4a00b0478 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as7716_32x' version = '0.0.1' @@ -55,7 +54,6 @@ 'fan3': ['fan'], 'fan4': ['fan'], 'fan5': ['fan'], - 'fan5': ['fan'], } hwmon_nodes = {'led': ['brightness'] , 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py index c08a82c7dc45..ed5af4818de3 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import commands - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py index 2568312b0955..86b4f1852066 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py @@ -23,17 +23,11 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as7716_32x.fanutil import FanUtil from as7716_32x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py index ffddfb338506..0f1f0d66fddb 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py @@ -30,13 +30,11 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re -import time -from collections import namedtuple PROJECT_NAME = 'as7716_32xb' version = '0.0.1' @@ -55,7 +53,6 @@ 'fan3': ['fan'], 'fan4': ['fan'], 'fan5': ['fan'], - 'fan5': ['fan'], } hwmon_nodes = {'led': ['brightness'] , 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py index 631a7915383b..aada6ba5c507 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py @@ -24,17 +24,12 @@ try: import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as7726_32x.fanutil import FanUtil from as7726_32x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_fan.py index de737b99f1f3..a2139341150c 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_fan.py @@ -22,19 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate - except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_psu.py index 618c58eec872..d139e3f3f1c8 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py index acb0319f5f25..590add7e925f 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as7726_32x' version = '0.0.1' @@ -55,7 +54,6 @@ 'fan3': ['fan'], 'fan4': ['fan'], 'fan5': ['fan'], - 'fan5': ['fan'], } hwmon_nodes = {'led': ['brightness'] , 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py index 3d9f6fc3ce5e..a8dcba0f77db 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py @@ -24,18 +24,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as7816_64x.fanutil import FanUtil from as7816_64x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py index ab5e52cb85bd..0dad870c9718 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py @@ -30,14 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple - diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py index 3752161d3ebc..49a99aa777a3 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py @@ -20,19 +20,13 @@ # ------------------------------------------------------------------ try: - import os import commands - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as9716_32d.fanutil import FanUtil from as9716_32d.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_fan.py index 320655361b83..b22dd5d7984d 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_fan.py @@ -22,19 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate - except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_psu.py index a8df99430c81..a3c8a0be65b3 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py index 2eac0e5e704d..61d19d0ac7fd 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as9716_32d' version = '0.0.1' @@ -55,7 +54,6 @@ 'fan3': ['fan'], 'fan4': ['fan'], 'fan5': ['fan'], - 'fan5': ['fan'], } hwmon_nodes = {'led': ['brightness'] , 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], diff --git a/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py index 261074c5d99a..cf8e91faf549 100755 --- a/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py @@ -37,13 +37,12 @@ set : change board setting with led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'minipack' version = '0.2.0' diff --git a/platform/broadcom/sonic-platform-modules-accton/minipack/utils/setup_qsfp_eeprom.py b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/setup_qsfp_eeprom.py index 84388520b902..257bc1cd90e6 100755 --- a/platform/broadcom/sonic-platform-modules-accton/minipack/utils/setup_qsfp_eeprom.py +++ b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/setup_qsfp_eeprom.py @@ -22,8 +22,8 @@ try: import os - import sys, getopt - import subprocess + import getopt + import sys import subprocess import click import imp diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py index 0a78085fd49b..0a1a887642d6 100755 --- a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py @@ -335,7 +335,7 @@ def system_get_lswtemp(): return 25 # chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) -# if chp.poll() == None: +# if chp.poll() is None: # misclogger.info("No subp.") # chp.kill() # diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py index c186676cbf3f..b4627a081d78 100755 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py @@ -335,7 +335,7 @@ def system_get_lswtemp(): return 25 # chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) -# if chp.poll() == None: +# if chp.poll() is None: # misclogger.info("No subp.") # chp.kill() # diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py index 3b685236a075..56add80221bb 100755 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py @@ -335,7 +335,7 @@ def system_get_lswtemp(): return 25 # chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) -# if chp.poll() == None: +# if chp.poll() is None: # misclogger.info("No subp.") # chp.kill() # diff --git a/src/sonic-config-engine/config_samples.py b/src/sonic-config-engine/config_samples.py index 99341642961f..be8ab3e0a955 100644 --- a/src/sonic-config-engine/config_samples.py +++ b/src/sonic-config-engine/config_samples.py @@ -1,5 +1,3 @@ -import os -import sys from natsort import natsorted def generate_t1_sample_config(data): diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index b18261a8fc9a..7aa51304d2ea 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1,15 +1,10 @@ from __future__ import print_function -import calendar -from ipaddress import IPv4Address, IPv4Network, ip_address, ip_network +import ipaddress import math import os import sys -import socket -import struct import json -import copy -import ipaddress from collections import defaultdict from lxml import etree as ET @@ -809,7 +804,7 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m intf_name = pc_member[1] break - if intf_name == None: + if intf_name is None: print('Warning: cannot find any interfaces that belong to %s' % (pc_intf), file=sys.stderr) continue @@ -1314,8 +1309,8 @@ def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname): lo_addr = '' # Use the first IPv4 loopback as the tunnel destination IP for addr in lo_intfs.keys(): - ip_addr = ip_network(UNICODE_TYPE(addr[1])) - if isinstance(ip_addr, IPv4Network): + ip_addr = ipaddress.ip_network(UNICODE_TYPE(addr[1])) + if isinstance(ip_addr, ipaddress.IPv4Network): lo_addr = str(ip_addr.network_address) break diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py index 1a49e4fd1cd4..d20212eb55aa 100644 --- a/src/sonic-config-engine/portconfig.py +++ b/src/sonic-config-engine/portconfig.py @@ -1,10 +1,10 @@ try: - import os - import sys - import json import ast + import json + import os import re - from collections import OrderedDict + import sys + from swsssdk import ConfigDBConnector from sonic_py_common import device_info except ImportError as e: From 31404dc43abacc670b29ae971932c4087d506f74 Mon Sep 17 00:00:00 2001 From: Petro Bratash <68950226+bratashX@users.noreply.github.com> Date: Fri, 20 Nov 2020 22:25:13 +0200 Subject: [PATCH 1418/1427] [sonic-platform-daemons] Update submodule (#5987) - Fix test_updater_thermal_check_min_max() https://github.com/Azure/sonic-platform-daemons/commit/f6e5e5902e4b4a40fc18e8d638d580962bd004be - [sonic-platform-daemons] Add more physical entity information to DB for physical entity mib https://github.com/Azure/sonic-platform-daemons/commit/14e586d676e724e8d134dc91ca22ab1734498ffc Signed-off-by: Petro Bratash --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index b90ddda28212..f6e5e5902e4b 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit b90ddda28212c7f5c825d8aec3b430ecf753a560 +Subproject commit f6e5e5902e4b4a40fc18e8d638d580962bd004be From 3b27afe377f8708174247796ce0f471b76d0c60f Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Fri, 20 Nov 2020 17:04:01 -0800 Subject: [PATCH 1419/1427] [minigraph.py]: Add VLAN_INTERFACE attributes for dual ToR devices (#5951) * If a device has subtype = 'DualToR', then enable proxy ARP and gratuitous ARP. --- src/sonic-config-engine/minigraph.py | 18 ++++++++++++++++-- .../tests/test_minigraph_case.py | 14 +++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 7aa51304d2ea..caf687ac7e8d 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1092,10 +1092,24 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw for intf in intfs: if intf[0][0:4] == 'Vlan': vlan_intfs[intf] = {} - vlan_intfs[intf[0]] = {} + + if bool(results['PEER_SWITCH']): + vlan_intfs[intf[0]] = { + 'proxy_arp': 'enabled', + 'grat_arp': 'enabled' + } + else: + vlan_intfs[intf[0]] = {} elif intf[0] in vlan_invert_mapping: vlan_intfs[(vlan_invert_mapping[intf[0]], intf[1])] = {} - vlan_intfs[vlan_invert_mapping[intf[0]]] = {} + + if bool(results['PEER_SWITCH']): + vlan_intfs[vlan_invert_mapping[intf[0]]] = { + 'proxy_arp': 'enabled', + 'grat_arp': 'enabled' + } + else: + vlan_intfs[vlan_invert_mapping[intf[0]]] = {} elif intf[0][0:11] == 'PortChannel': pc_intfs[intf] = {} pc_intfs[intf[0]] = {} diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 586ded0ebec9..d24ec501bba6 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -96,11 +96,23 @@ def test_minigraph_vlan_members(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}}") - def test_minigraph_vlan_interfaces(self): + def test_minigraph_vlan_interfaces_keys(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Vlan1000', '192.168.0.1/27'), 'Vlan1000']") + def test_minigraph_vlan_interfaces(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE"' + output = self.run_script(argument) + expected_table = { + 'Vlan1000|192.168.0.1/27': {}, + 'Vlan1000': { + 'proxy_arp': 'enabled', + 'grat_arp': 'enabled' + } + } + self.assertEqual(utils.to_dict(output.strip()), expected_table) + def test_minigraph_portchannels(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v PORTCHANNEL' output = self.run_script(argument) From d3c1a5bf39e74482c97f87ad3b361d90b7f34bfc Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 20 Nov 2020 19:36:04 -0800 Subject: [PATCH 1420/1427] [frr] remove frr rsyslog file outchannel (#5962) - Why I did it frr is creating /var/log/frr/frr.log inside the frr docker and letting it grow. It will eventually exhaust hard drive space. To fixe issue #5965 - How I did it Remove rsyslog file outchannel so that frr won't generate /var/log/frr/frr.log inside the docker. - How to verify it Manually removed the outchannel and restart BGP docker, making sure that /var/log/frr/frr.log is no longer created inside the docker. While restarting bgp docker, observed that base image /var/log/quagga/bgpd.log continued to grow and captured all FRR logs. --- ...rr-log-outchannel-to-var-log-frr.log.patch | 31 +++++++++++++++++++ src/sonic-frr/patch/series | 1 + 2 files changed, 32 insertions(+) create mode 100644 src/sonic-frr/patch/0007-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch diff --git a/src/sonic-frr/patch/0007-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch b/src/sonic-frr/patch/0007-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch new file mode 100644 index 000000000000..2802c99e5943 --- /dev/null +++ b/src/sonic-frr/patch/0007-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch @@ -0,0 +1,31 @@ +From 1f150992b074d07bce5157d203319512a3aeb4dc Mon Sep 17 00:00:00 2001 +From: Ying Xie +Date: Wed, 18 Nov 2020 19:24:51 +0000 +Subject: [PATCH] [frr] remove frr log outchannel to /var/log/frr.log + +SONiC runs frr inside a docker and the logs are sent to base image +via rsyslog and recorded already. There is no need to keep the +frr.log inside the docker. It will grow and take all harddrive +space eventually. + +Signed-off-by: Ying Xie +--- + tools/etc/rsyslog.d/45-frr.conf | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/etc/rsyslog.d/45-frr.conf b/tools/etc/rsyslog.d/45-frr.conf +index ff7cd4831..af3c2c109 100644 +--- a/tools/etc/rsyslog.d/45-frr.conf ++++ b/tools/etc/rsyslog.d/45-frr.conf +@@ -2,7 +2,7 @@ + # to /var/log/frr/frr.log, then drops the message so it does + # not also go to /var/log/syslog, so the messages are not duplicated + +-$outchannel frr_log,/var/log/frr/frr.log ++$outchannel frr_log + if $programname == 'babeld' or + $programname == 'bgpd' or + $programname == 'eigrpd' or +-- +2.17.1 + diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 13619c87ff65..4a7ea0fd112a 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -4,3 +4,4 @@ 0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch 0005-nexthops-compare-vrf-only-if-ip-type.patch 0006-changes-for-making-snmp-socket-non-blocking.patch +0007-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch From 5b31996f7b6cdcc3842056a62076bb805ec82005 Mon Sep 17 00:00:00 2001 From: Sujin Kang Date: Fri, 20 Nov 2020 20:08:18 -0800 Subject: [PATCH 1421/1427] [reboot-history] Add reboot history to state db (#5933) - Why I did it Add reboot history to State db so that can be used telemetry service - How I did it Split the process-reboot-cause service to determine-reboot-cause and process-reboot-cause determine-reboot-cause to determine the reboot cause process-reboot-cause to parse the reboot cause files and put the reboot history to state db Moved to sonic-host-service* packages - How to verify it Performed unit test and tested on DUT --- .../build_templates/sonic_debian_extension.j2 | 10 -- src/sonic-host-services-data/debian/rules | 3 + ...rvices-data.determine-reboot-cause.service | 11 ++ ...services-data.process-reboot-cause.service | 0 ...t-services-data.process-reboot-cause.timer | 0 .../scripts/determine-reboot-cause | 139 ++++++++++++------ .../scripts/process-reboot-cause | 100 +++++++++++++ src/sonic-host-services/setup.py | 2 + .../tests/determine-reboot-cause_test.py | 117 +++++++++++++++ 9 files changed, 327 insertions(+), 55 deletions(-) create mode 100644 src/sonic-host-services-data/debian/sonic-host-services-data.determine-reboot-cause.service rename files/image_config/process-reboot-cause/process-reboot-cause.service => src/sonic-host-services-data/debian/sonic-host-services-data.process-reboot-cause.service (100%) rename files/build_templates/process-reboot-cause.timer => src/sonic-host-services-data/debian/sonic-host-services-data.process-reboot-cause.timer (100%) rename files/image_config/process-reboot-cause/process-reboot-cause => src/sonic-host-services/scripts/determine-reboot-cause (56%) create mode 100644 src/sonic-host-services/scripts/process-reboot-cause create mode 100644 src/sonic-host-services/tests/determine-reboot-cause_test.py diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 7afc099e3a40..00c0d9bbc525 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -428,16 +428,6 @@ sudo cp $IMAGE_CONFIGS/pcie-check/pcie-check.service $FILESYSTEM_ROOT_USR_LIB_SY echo "pcie-check.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/pcie-check/pcie-check.sh $FILESYSTEM_ROOT/usr/bin/ -# Copy systemd timer configuration -# It implements delayed start of services -sudo cp $BUILD_TEMPLATES/process-reboot-cause.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM -sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable process-reboot-cause.timer - -# Copy process-reboot-cause service files -sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM -echo "process-reboot-cause.service" | sudo tee -a $GENERATED_SERVICE_FILE -sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause $FILESYSTEM_ROOT/usr/bin/ - ## Install package without starting service ## ref: https://wiki.debian.org/chroot sudo tee -a $FILESYSTEM_ROOT/usr/sbin/policy-rc.d > /dev/null < 10: + for i in range(len(TIME_SORTED_FULL_REBOOT_FILE_LIST)): + if i >= 10: + x = TIME_SORTED_FULL_REBOOT_FILE_LIST[i] + os.remove(x) + + +def main(): + # Configure logger to log all messages INFO level and higher + sonic_logger.set_min_log_priority_info() + + sonic_logger.log_info("Starting up...") + + if not os.geteuid() == 0: + sonic_logger.log_error("User {} does not have permission to execute".format(pwd.getpwuid(os.getuid()).pw_name)) + sys.exit("This utility must be run as root") + + # Set a default previous reboot cause + previous_reboot_cause = REBOOT_CAUSE_UNKNOWN + + # Read the most recent reboot cause file and log data to syslog + if os.path.exists(PREVIOUS_REBOOT_CAUSE_FILE): + with open(PREVIOUS_REBOOT_CAUSE_FILE, "r") as last_cause_file: + data = json.load(last_cause_file) + if data['user']: + previous_reboot_cause = USER_ISSUED_REBOOT_CAUSE_REGEX.format(data['cause'], data['user'], data['time']) + else: + previous_reboot_cause = "{}".format(data['cause']) + + # Log the last reboot cause to the syslog + sonic_logger.log_info("Previous reboot cause: {}".format(previous_reboot_cause)) + + if os.path.exists(REBOOT_CAUSE_HISTORY_DIR): + # Read the previous reboot cause from saved reboot-cause files and save the previous reboot cause upto 10 entry to the state db + read_reboot_cause_files_and_save_state_db() + + +if __name__ == "__main__": + main() diff --git a/src/sonic-host-services/setup.py b/src/sonic-host-services/setup.py index d0f7bd055683..2da0561b9c5e 100644 --- a/src/sonic-host-services/setup.py +++ b/src/sonic-host-services/setup.py @@ -14,6 +14,8 @@ 'scripts/caclmgrd', 'scripts/hostcfgd', 'scripts/procdockerstatsd', + 'scripts/determine-reboot-cause', + 'scripts/process-reboot-cause', ], install_requires = [ 'Jinja2>=2.10', diff --git a/src/sonic-host-services/tests/determine-reboot-cause_test.py b/src/sonic-host-services/tests/determine-reboot-cause_test.py new file mode 100644 index 000000000000..9cef2aa30d2d --- /dev/null +++ b/src/sonic-host-services/tests/determine-reboot-cause_test.py @@ -0,0 +1,117 @@ +import imp +import sys +import os +import pytest + +import swsssdk + +# TODO: Remove this if/else block once we no longer support Python 2 +if sys.version_info.major == 3: + from unittest import mock +else: + # Expect the 'mock' package for python 2 + # https://pypi.python.org/pypi/mock + import mock + +# TODO: Remove this if/else block once we no longer support Python 2 +if sys.version_info.major == 3: + BUILTINS = "builtins" +else: + BUILTINS = "__builtin__" + +from .mock_connector import MockConnector + +swsssdk.SonicV2Connector = MockConnector + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +scripts_path = os.path.join(modules_path, "scripts") +sys.path.insert(0, modules_path) + +PROC_CMDLINE_CONTENTS = """\ +BOOT_IMAGE=/image-20191130.52/boot/vmlinuz-4.9.0-11-2-amd64 root=/dev/sda4 rw console=tty0 console=ttyS1,9600n8 quiet net.ifnames=0 biosdevname=0 loop=image-20191130.52/fs.squashfs loopfstype=squashfs apparmor=1 security=apparmor varlog_size=4096 usbcore.autosuspend=-1 module_blacklist=gpio_ich SONIC_BOOT_TYPE=warm""" + +EXPECTED_PARSE_WARMFAST_REBOOT_FROM_PROC_CMDLINE = "warm" + +PROC_CMDLINE_CONTENTS = """\ +BOOT_IMAGE=/image-20191130.52/boot/vmlinuz-4.9.0-11-2-amd64 root=/dev/sda4 rw console=tty0 console=ttyS1,9600n8 quiet net.ifnames=0 biosdevname=0 loop=image-20191130.52/fs.squashfs loopfstype=squashfs apparmor=1 security=apparmor varlog_size=4096 usbcore.autosuspend=-1 module_blacklist=gpio_ich SONIC_BOOT_TYPE=warm""" + +REBOOT_CAUSE_CONTENTS = """\ +User issued 'warm-reboot' command [User: admin, Time: Mon Nov 2 22:37:45 UTC 2020]""" + +GET_SONIC_VERSION_INFO = {'commit_id': 'e59ec8291', 'build_date': 'Mon Nov 2 06:00:14 UTC 2020', 'build_number': 75, 'kernel_version': '4.9.0-11-2-amd64', 'debian_version': '9.13', 'built_by': 'sonicbld@jenkins-slave-phx-2', 'asic_type': 'mellanox', 'build_version': '20191130.52'} + +REBOOT_CAUSE_WATCHDOG = "Watchdog" +GEN_TIME_WATCHDOG = "2020_10_22_03_15_08" +REBOOT_CAUSE_USER = "User issued 'reboot' command [User: admin, Time: Thu Oct 22 03:11:08 UTC 2020]" +GEN_TIME_USER = "2020_10_22_03_14_07" + +EXPECTED_PARSE_WARMFAST_REBOOT_FROM_PROC_CMDLINE = "warm-reboot" +EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_USER = "User issued 'warm-reboot' command [User: admin, Time: Mon Nov 2 22:37:45 UTC 2020]" +EXPECTED_FIND_FIRSTBOOT_VERSION = " (First boot of SONiC version 20191130.52)" +EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_FIRSTBOOT = "Unknown (First boot of SONiC version 20191130.52)" +EXPECTED_HARDWARE_REBOOT_CAUSE = {"warm-reboot", ""} + +EXPECTED_WATCHDOG_REBOOT_CAUSE_DICT = {'comment': '', 'gen_time': '2020_10_22_03_15_08', 'cause': 'Watchdog', 'user': 'N/A', 'time': 'N/A'} +EXPECTED_USER_REBOOT_CAUSE_DICT = {'comment': '', 'gen_time': '2020_10_22_03_14_07', 'cause': 'reboot', 'user': 'admin', 'time': 'Thu Oct 22 03:11:08 UTC 2020'} + +imp.load_source('determine_reboot_cause', scripts_path + '/determine-reboot-cause') +from determine_reboot_cause import * + +class TestDetermineRebootCause(object): + @classmethod + def setup_class(cls): + print("SETUP") + + def test_parse_warmfast_reboot_from_proc_cmdline(self): + with mock.patch("os.path.isfile") as mock_isfile: + mock_isfile.return_value = True + open_mocked = mock.mock_open(read_data=PROC_CMDLINE_CONTENTS) + with mock.patch("{}.open".format(BUILTINS), open_mocked): + result = parse_warmfast_reboot_from_proc_cmdline() + assert result == EXPECTED_PARSE_WARMFAST_REBOOT_FROM_PROC_CMDLINE + open_mocked.assert_called_once_with("/proc/cmdline") + + def test_find_software_reboot_cause_user(self): + with mock.patch("os.path.isfile") as mock_isfile: + mock_isfile.return_value = True + open_mocked = mock.mock_open(read_data=REBOOT_CAUSE_CONTENTS) + with mock.patch("{}.open".format(BUILTINS), open_mocked): + result = find_software_reboot_cause_from_reboot_cause_file() + assert result == EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_USER + open_mocked.assert_called_once_with("/host/reboot-cause/reboot-cause.txt") + + def test_find_software_reboot_cause_first_boot(self): + with mock.patch("sonic_py_common.device_info.get_sonic_version_info", return_value=GET_SONIC_VERSION_INFO): + result = find_first_boot_version() + assert result == EXPECTED_FIND_FIRSTBOOT_VERSION + + def test_find_software_reboot_cause(self): + with mock.patch("determine_reboot_cause.find_software_reboot_cause_from_reboot_cause_file", return_value="Unknown"): + with mock.patch("os.path.isfile") as mock_isfile: + mock_isfile.return_value = False + result = find_software_reboot_cause() + assert result == "Unknown" + + def test_find_proc_cmdline_reboot_cause(self): + with mock.patch("determine_reboot_cause.parse_warmfast_reboot_from_proc_cmdline", return_value="fast-reboot"): + result = find_proc_cmdline_reboot_cause() + assert result == "fast-reboot" + + def test_find_hardware_reboot_cause(self): + with mock.patch("determine_reboot_cause.get_reboot_cause_from_platform", return_value=("Powerloss", None)): + result = find_hardware_reboot_cause() + assert result == ("Powerloss", None) + + def test_get_reboot_cause_dict_watchdog(self): + reboot_cause_dict = get_reboot_cause_dict(REBOOT_CAUSE_WATCHDOG, "", GEN_TIME_WATCHDOG) + assert reboot_cause_dict == EXPECTED_WATCHDOG_REBOOT_CAUSE_DICT + + def test_get_reboot_cause_dict_user(self): + reboot_cause_dict = get_reboot_cause_dict(REBOOT_CAUSE_USER, "", GEN_TIME_USER) + assert reboot_cause_dict == EXPECTED_USER_REBOOT_CAUSE_DICT + + @classmethod + def teardown_class(cls): + print("TREARDOWN") + From e0781f463fa84f08cb04e16d31a26b1fe7d7a9b0 Mon Sep 17 00:00:00 2001 From: Shi Su <67605788+shi-su@users.noreply.github.com> Date: Sat, 21 Nov 2020 11:35:35 -0800 Subject: [PATCH 1422/1427] [L2 switch mode] Update l2switch.j2 template (#5981) - Why I did it The l2switch.j2 template does not include all fields for PORT. This could be incompatible with the 201911 image or later. - How I did it Update l2switch.j2 template and add a unit test. --- src/sonic-config-engine/data/l2switch.j2 | 11 +++++++---- src/sonic-config-engine/tests/test_j2files.py | 7 +++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/sonic-config-engine/data/l2switch.j2 b/src/sonic-config-engine/data/l2switch.j2 index 86dca30cb739..22de3158c589 100644 --- a/src/sonic-config-engine/data/l2switch.j2 +++ b/src/sonic-config-engine/data/l2switch.j2 @@ -2,13 +2,16 @@ "DEVICE_METADATA": {{ DEVICE_METADATA | tojson }}, {% set ns = {'firstPrinted': False} -%} "PORT": { - {%- for key,value in PORT.items() -%} + {%- for key, value in PORT.items() -%} {%- if ns.firstPrinted %},{% endif %} "{{ key }}": { - "alias": "{{ value.alias }}", - "lanes": "{{ value.lanes }}", - "admin_status": "up" + {%- for keyPort, valuePort in value.items() %} + + {% if keyPort != "admin_status" %}"{{ keyPort }}": "{{ valuePort }}",{% endif %} + {%- endfor %} + + "admin_status": "{{ value.admin_status|default("up") }}" } {%- if ns.update({'firstPrinted': True}) %}{% endif -%} {%- endfor %} diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index e59cb010ef79..a66cd99820be 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -125,6 +125,13 @@ def test_l2switch_template(self): self.assertTrue(json.dumps(sample_output_json, sort_keys=True) == json.dumps(output_json, sort_keys=True)) + template_dir = os.path.join(self.test_dir, '..', 'data', 'l2switch.j2') + argument = '-t ' + template_dir + ' -k Mellanox-SN2700 -p ' + self.t0_port_config + output = self.run_script(argument) + output_json = json.loads(output) + + self.assertTrue(json.dumps(sample_output_json, sort_keys=True) == json.dumps(output_json, sort_keys=True)) + def test_qos_arista7050_render_template(self): arista_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'arista', 'x86_64-arista_7050_qx32s', 'Arista-7050-QX-32S') qos_file = os.path.join(arista_dir_path, 'qos.json.j2') From 4d3eb18ca7c9877e92698048d9f229fceb191dcb Mon Sep 17 00:00:00 2001 From: lguohan Date: Sun, 22 Nov 2020 21:18:44 -0800 Subject: [PATCH 1423/1427] [supervisord]: use abspath as supervisord entrypoint (#5995) use abspath makes the entrypoint not affected by PATH env. Signed-off-by: Guohan Lu --- dockers/docker-basic_router/Dockerfile | 2 +- dockers/docker-database/docker-database-init.sh | 4 ++-- dockers/docker-dhcp-relay/docker_init.sh | 4 ++-- dockers/docker-fpm-frr/docker_init.sh | 2 +- dockers/docker-fpm-gobgp/Dockerfile.j2 | 2 +- dockers/docker-fpm-quagga/Dockerfile.j2 | 2 +- dockers/docker-iccpd/Dockerfile.j2 | 2 +- dockers/docker-lldp/docker-lldp-init.sh | 2 +- dockers/docker-nat/Dockerfile.j2 | 2 +- dockers/docker-orchagent/docker-init.sh | 2 +- dockers/docker-platform-monitor/docker_init.sh | 2 +- dockers/docker-router-advertiser/docker-init.sh | 2 +- dockers/docker-sflow/Dockerfile.j2 | 2 +- dockers/docker-snmp/Dockerfile.j2 | 2 +- dockers/docker-sonic-mgmt-framework/Dockerfile.j2 | 2 +- dockers/docker-sonic-restapi/Dockerfile.j2 | 2 +- dockers/docker-sonic-telemetry/Dockerfile.j2 | 2 +- dockers/docker-teamd/Dockerfile.j2 | 2 +- platform/barefoot/docker-saiserver-bfn/Dockerfile | 2 +- platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 | 2 +- platform/barefoot/docker-syncd-bfn/Dockerfile.j2 | 2 +- platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 | 2 +- platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 | 2 +- platform/broadcom/docker-syncd-brcm/Dockerfile.j2 | 2 +- platform/cavium/docker-saiserver-cavm/Dockerfile | 2 +- platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 | 2 +- platform/cavium/docker-syncd-cavm/Dockerfile.j2 | 2 +- platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 | 2 +- platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 | 2 +- platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 | 2 +- platform/centec/docker-syncd-centec/Dockerfile.j2 | 2 +- platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 | 2 +- platform/innovium/docker-syncd-invm/Dockerfile.j2 | 2 +- platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 | 2 +- platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 | 2 +- platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 | 2 +- platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 | 2 +- platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 | 2 +- platform/marvell/docker-syncd-mrvl/Dockerfile.j2 | 2 +- platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 | 2 +- platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 | 2 +- platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 | 2 +- platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 | 2 +- platform/nephos/docker-syncd-nephos/Dockerfile.j2 | 2 +- platform/vs/docker-gbsyncd-vs/Dockerfile.j2 | 2 +- platform/vs/docker-sonic-vs/Dockerfile.j2 | 2 +- platform/vs/docker-syncd-vs/Dockerfile.j2 | 2 +- 47 files changed, 49 insertions(+), 49 deletions(-) diff --git a/dockers/docker-basic_router/Dockerfile b/dockers/docker-basic_router/Dockerfile index c5bccde72f85..5f579b53d6da 100644 --- a/dockers/docker-basic_router/Dockerfile +++ b/dockers/docker-basic_router/Dockerfile @@ -19,4 +19,4 @@ RUN mv /deps/basic_router /usr/sbin/basic_router COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-database/docker-database-init.sh b/dockers/docker-database/docker-database-init.sh index 33f0f80a31e8..30a65af89b7f 100755 --- a/dockers/docker-database/docker-database-init.sh +++ b/dockers/docker-database/docker-database-init.sh @@ -55,7 +55,7 @@ if [[ $DATABASE_TYPE == "chassisdb" ]]; then # generate all redis server supervisord configuration file sonic-cfggen -j $db_cfg_file_tmp -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf rm $db_cfg_file_tmp - exec supervisord + exec /usr/local/bin/supervisord exit 0 fi @@ -79,4 +79,4 @@ else fi rm $db_cfg_file_tmp -exec supervisord +exec /usr/local/bin/supervisord diff --git a/dockers/docker-dhcp-relay/docker_init.sh b/dockers/docker-dhcp-relay/docker_init.sh index 9bdc6399ca2c..1ff0e936ff68 100755 --- a/dockers/docker-dhcp-relay/docker_init.sh +++ b/dockers/docker-dhcp-relay/docker_init.sh @@ -19,6 +19,6 @@ sonic-cfggen $CFGGEN_PARAMS chmod +x /usr/bin/wait_for_intf.sh # The docker container should start this script as PID 1, so now that supervisord is -# properly configured, we exec supervisord so that it runs as PID 1 for the +# properly configured, we exec /usr/local/bin/supervisord so that it runs as PID 1 for the # duration of the container's lifetime -exec supervisord +exec /usr/local/bin/supervisord diff --git a/dockers/docker-fpm-frr/docker_init.sh b/dockers/docker-fpm-frr/docker_init.sh index dadd83276834..94cd7fbb1322 100755 --- a/dockers/docker-fpm-frr/docker_init.sh +++ b/dockers/docker-fpm-frr/docker_init.sh @@ -66,4 +66,4 @@ chmod 0755 /usr/sbin/bgp-unisolate mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status -exec supervisord +exec /usr/local/bin/supervisord diff --git a/dockers/docker-fpm-gobgp/Dockerfile.j2 b/dockers/docker-fpm-gobgp/Dockerfile.j2 index cb0fd21b8f62..65b104e43b26 100644 --- a/dockers/docker-fpm-gobgp/Dockerfile.j2 +++ b/dockers/docker-fpm-gobgp/Dockerfile.j2 @@ -27,4 +27,4 @@ COPY ["daemons", "/etc/quagga/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-fpm-quagga/Dockerfile.j2 b/dockers/docker-fpm-quagga/Dockerfile.j2 index fccc7f08df0a..ac382afbe5b2 100644 --- a/dockers/docker-fpm-quagga/Dockerfile.j2 +++ b/dockers/docker-fpm-quagga/Dockerfile.j2 @@ -36,4 +36,4 @@ COPY ["*.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-iccpd/Dockerfile.j2 b/dockers/docker-iccpd/Dockerfile.j2 index f49bea7d84a5..51cc306bdd55 100644 --- a/dockers/docker-iccpd/Dockerfile.j2 +++ b/dockers/docker-iccpd/Dockerfile.j2 @@ -31,4 +31,4 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-lldp/docker-lldp-init.sh b/dockers/docker-lldp/docker-lldp-init.sh index eee07b4adad0..135ff48255d6 100755 --- a/dockers/docker-lldp/docker-lldp-init.sh +++ b/dockers/docker-lldp/docker-lldp-init.sh @@ -2,4 +2,4 @@ #Generate supervisord.conf based on device metadata mkdir -p /etc/supervisor/conf.d/ sonic-cfggen -d -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf -exec supervisord +exec /usr/local/bin/supervisord diff --git a/dockers/docker-nat/Dockerfile.j2 b/dockers/docker-nat/Dockerfile.j2 index 73b68dc70cc0..36a178a68af2 100644 --- a/dockers/docker-nat/Dockerfile.j2 +++ b/dockers/docker-nat/Dockerfile.j2 @@ -35,4 +35,4 @@ COPY ["critical_processes", "/etc/supervisor"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-orchagent/docker-init.sh b/dockers/docker-orchagent/docker-init.sh index b15c7cc3c91b..d128422938ee 100755 --- a/dockers/docker-orchagent/docker-init.sh +++ b/dockers/docker-orchagent/docker-init.sh @@ -25,4 +25,4 @@ if [ "$VLAN" != "" ]; then cp /usr/share/sonic/templates/ndppd.conf /etc/supervisor/conf.d/ fi -exec supervisord +exec /usr/local/bin/supervisord diff --git a/dockers/docker-platform-monitor/docker_init.sh b/dockers/docker-platform-monitor/docker_init.sh index 0039eb34d8be..c06295c0c191 100755 --- a/dockers/docker-platform-monitor/docker_init.sh +++ b/dockers/docker-platform-monitor/docker_init.sh @@ -40,4 +40,4 @@ if [ $HAVE_FANCONTROL_CONF -eq 1 ]; then /bin/cp -f $FANCONTROL_CONF_FILE /etc/ fi -exec supervisord +exec /usr/local/bin/supervisord diff --git a/dockers/docker-router-advertiser/docker-init.sh b/dockers/docker-router-advertiser/docker-init.sh index 28ffcb094cf1..6e1bb5545f82 100755 --- a/dockers/docker-router-advertiser/docker-init.sh +++ b/dockers/docker-router-advertiser/docker-init.sh @@ -14,4 +14,4 @@ sonic-cfggen $CFGGEN_PARAMS chmod +x /usr/bin/wait_for_link.sh -exec supervisord +exec /usr/local/bin/supervisord diff --git a/dockers/docker-sflow/Dockerfile.j2 b/dockers/docker-sflow/Dockerfile.j2 index db2d4b3bc0b6..476ff3514ace 100644 --- a/dockers/docker-sflow/Dockerfile.j2 +++ b/dockers/docker-sflow/Dockerfile.j2 @@ -32,4 +32,4 @@ COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] COPY ["port_index_mapper.py", "/usr/bin"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-snmp/Dockerfile.j2 b/dockers/docker-snmp/Dockerfile.j2 index c98b955bf033..d479392bb259 100644 --- a/dockers/docker-snmp/Dockerfile.j2 +++ b/dockers/docker-snmp/Dockerfile.j2 @@ -76,4 +76,4 @@ COPY ["critical_processes", "/etc/supervisor"] # Although exposing ports is not needed for host net mode, keep it for possible bridge mode EXPOSE 161/udp 162/udp -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 index 235d1a8e76c2..29f1c05cd26a 100644 --- a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 @@ -36,4 +36,4 @@ RUN apt-get remove -y g++ python-dev RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-sonic-restapi/Dockerfile.j2 b/dockers/docker-sonic-restapi/Dockerfile.j2 index 5463f0b44bc8..837796e66d82 100644 --- a/dockers/docker-sonic-restapi/Dockerfile.j2 +++ b/dockers/docker-sonic-restapi/Dockerfile.j2 @@ -25,4 +25,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-sonic-telemetry/Dockerfile.j2 b/dockers/docker-sonic-telemetry/Dockerfile.j2 index 6670e75625ba..65e436d293d7 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/Dockerfile.j2 @@ -28,4 +28,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-teamd/Dockerfile.j2 b/dockers/docker-teamd/Dockerfile.j2 index 26250830b628..7f4db2936857 100644 --- a/dockers/docker-teamd/Dockerfile.j2 +++ b/dockers/docker-teamd/Dockerfile.j2 @@ -27,4 +27,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/barefoot/docker-saiserver-bfn/Dockerfile b/platform/barefoot/docker-saiserver-bfn/Dockerfile index 3f8071234b55..6fa5b1818a18 100755 --- a/platform/barefoot/docker-saiserver-bfn/Dockerfile +++ b/platform/barefoot/docker-saiserver-bfn/Dockerfile @@ -34,4 +34,4 @@ COPY ["profile.ini", "portmap.ini", "/etc/sai/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /deps -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 index 9b547dbcacec..f3c9979dfa63 100644 --- a/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 @@ -49,4 +49,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 index 712b15826c74..b4bcafe5926a 100755 --- a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 @@ -36,4 +36,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 b/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 index 4294b79ff090..a9904a88dc9d 100644 --- a/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 @@ -33,4 +33,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 index 38dbf15b1288..f68fbb661d9c 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index 9c68eda56c99..35b3d352a827 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -32,4 +32,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/cavium/docker-saiserver-cavm/Dockerfile b/platform/cavium/docker-saiserver-cavm/Dockerfile index c73abb0e4bb2..d15b16cbfd43 100644 --- a/platform/cavium/docker-saiserver-cavm/Dockerfile +++ b/platform/cavium/docker-saiserver-cavm/Dockerfile @@ -27,4 +27,4 @@ COPY ["portmap.ini", "profile.ini", "/etc/sai/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf deps -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 b/platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 index 2e1665d26029..3c49748ae8ae 100644 --- a/platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 +++ b/platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 index cdbd3d15dfdf..fcf82276ad1a 100755 --- a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 +++ b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 @@ -32,4 +32,4 @@ COPY ["profile.ini", "/etc/ssw/AS7512/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 b/platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 index 0802f3532c4a..d6719b224abd 100755 --- a/platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 +++ b/platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 b/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 index 7cb629f6ec58..7590d65600b7 100755 --- a/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 @@ -34,4 +34,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 b/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 index 0802f3532c4a..d6719b224abd 100644 --- a/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/centec/docker-syncd-centec/Dockerfile.j2 b/platform/centec/docker-syncd-centec/Dockerfile.j2 index dfd19af47cd6..8bb5041b15ba 100755 --- a/platform/centec/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec/Dockerfile.j2 @@ -30,4 +30,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 b/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 index 8b6d6ae6ab8c..3a25afbe6161 100755 --- a/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 +++ b/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 @@ -50,4 +50,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/innovium/docker-syncd-invm/Dockerfile.j2 b/platform/innovium/docker-syncd-invm/Dockerfile.j2 index 0d6b1e8f48cc..ab4be823de66 100755 --- a/platform/innovium/docker-syncd-invm/Dockerfile.j2 +++ b/platform/innovium/docker-syncd-invm/Dockerfile.j2 @@ -30,4 +30,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 b/platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 index 121166a805b4..6b9e3d8aaafc 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 +++ b/platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 index a9898e2f9ff2..afaac3fd056c 100755 --- a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 @@ -34,4 +34,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 b/platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 index 121166a805b4..6b9e3d8aaafc 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 +++ b/platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 index a9898e2f9ff2..afaac3fd056c 100755 --- a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 @@ -34,4 +34,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 index 121166a805b4..6b9e3d8aaafc 100644 --- a/platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 index b156095a17d6..e91231e49791 100755 --- a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 @@ -30,4 +30,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 b/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 index 5d901f4ed977..39223131ee43 100644 --- a/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 @@ -44,4 +44,4 @@ COPY ["sai_2700.xml", "/usr/share/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 index 5119f7c412e1..e35c6582d2d0 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 @@ -62,4 +62,4 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index 7fba0664306a..5c9ac6c1c145 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -39,4 +39,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 index 4f27ba6bce96..95703448c371 100644 --- a/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 @@ -48,4 +48,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 index 6c3c42ac4376..e142fa04d57d 100755 --- a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 @@ -43,4 +43,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 index 60bd79b2ee80..d740dca663cb 100644 --- a/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 +++ b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 @@ -31,4 +31,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index b61981246115..50996e36e191 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -170,4 +170,4 @@ RUN mkdir -p /var/warmboot/teamd ENV PLATFORM=x86_64-kvm_x86_64-r0 ENV HWSKU=Force10-S6000 -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/vs/docker-syncd-vs/Dockerfile.j2 b/platform/vs/docker-syncd-vs/Dockerfile.j2 index 5e3d992b56fb..1ef1245e14fb 100644 --- a/platform/vs/docker-syncd-vs/Dockerfile.j2 +++ b/platform/vs/docker-syncd-vs/Dockerfile.j2 @@ -31,4 +31,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] From 5410290b2662b1196cd9dffcf3617d19e6792316 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Mon, 23 Nov 2020 03:58:06 -0800 Subject: [PATCH 1424/1427] [sonic-swss-common] Update submodule (#5998) Included submodule commits: f143b7f 2020-11-22 | [swig] wrap logger.h (#418) [Qi Luo] --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 95f9e110d171..f143b7f258cb 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 95f9e110d171fa95ab7ae75aebc31f6b3bac83c2 +Subproject commit f143b7f258cb49184602b3d510746fdf90040d3c From 5df8af5378ed8c63c7489e5a98d49a3a1e064074 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Mon, 23 Nov 2020 09:30:39 -0800 Subject: [PATCH 1425/1427] [TSA]: Fix TSC. Avoid 'Not consistent' state (#5968) --- dockers/docker-fpm-frr/TSC | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dockers/docker-fpm-frr/TSC b/dockers/docker-fpm-frr/TSC index 3a3ad73d00b4..8c17cea7eea7 100755 --- a/dockers/docker-fpm-frr/TSC +++ b/dockers/docker-fpm-frr/TSC @@ -4,7 +4,7 @@ function check_not_installed() { c=0 config=$(vtysh -c "show run") - for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p' | egrep 'V4|V6'); do echo "$config" | grep -q "route-map $route_map_name permit 2" c=$((c+$?)) @@ -19,7 +19,7 @@ function check_installed() c=0 e=0 config=$(vtysh -c "show run") - for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p' | egrep 'V4|V6'); do echo "$config" | grep -q "route-map $route_map_name permit 2" c=$((c+$?)) From 98a434e8c17b098cdd4cce125e0314b36d87b2c2 Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Mon, 23 Nov 2020 09:31:42 -0800 Subject: [PATCH 1426/1427] Copp Manager Changes (#4861) *Introduce CoPP Manager infrastructure Copp service to generate initial copp config template file Co-authored-by: dgsudharsan --- .../base_image_files/monit_swss | 4 + dockers/docker-orchagent/copp.json.j2 | 85 -------------- dockers/docker-orchagent/critical_processes | 1 + dockers/docker-orchagent/docker-init.sh | 1 - dockers/docker-orchagent/supervisord.conf | 12 ++ dockers/docker-orchagent/swssconfig.sh | 2 +- files/build_templates/docker_image_ctl.j2 | 2 +- .../build_templates/sonic_debian_extension.j2 | 6 + files/image_config/copp/copp-config.service | 11 ++ files/image_config/copp/copp-config.sh | 3 + files/image_config/copp/copp_cfg.j2 | 105 ++++++++++++++++++ platform/vs/docker-sonic-vs.mk | 3 +- platform/vs/docker-sonic-vs/Dockerfile.j2 | 2 +- platform/vs/docker-sonic-vs/start.sh | 3 + platform/vs/docker-sonic-vs/supervisord.conf | 8 ++ rules/scripts.dep | 1 + rules/scripts.mk | 6 +- 17 files changed, 164 insertions(+), 91 deletions(-) delete mode 100644 dockers/docker-orchagent/copp.json.j2 create mode 100755 files/image_config/copp/copp-config.service create mode 100755 files/image_config/copp/copp-config.sh create mode 100755 files/image_config/copp/copp_cfg.j2 diff --git a/dockers/docker-orchagent/base_image_files/monit_swss b/dockers/docker-orchagent/base_image_files/monit_swss index da601011e735..7557bd66ac9a 100644 --- a/dockers/docker-orchagent/base_image_files/monit_swss +++ b/dockers/docker-orchagent/base_image_files/monit_swss @@ -11,6 +11,7 @@ ## buffermgrd ## nbrmgrd ## vxlanmgrd +## coppmgrd ############################################################################## check program swss|orchagent with path "/usr/bin/process_checker swss /usr/bin/orchagent -d /var/log/swss" if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles @@ -41,3 +42,6 @@ check program swss|nbrmgrd with path "/usr/bin/process_checker swss /usr/bin/nbr check program swss|vxlanmgrd with path "/usr/bin/process_checker swss /usr/bin/vxlanmgrd" if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles + +check program swss|coppmgrd with path "/usr/bin/process_checker swss /usr/bin/coppmgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-orchagent/copp.json.j2 b/dockers/docker-orchagent/copp.json.j2 deleted file mode 100644 index 49173a54e99f..000000000000 --- a/dockers/docker-orchagent/copp.json.j2 +++ /dev/null @@ -1,85 +0,0 @@ -[ - { - "COPP_TABLE:default": { - "queue": "0", - "meter_type":"packets", - "mode":"sr_tcm", - "cir":"600", - "cbs":"600", - "red_action":"drop" - }, - "OP": "SET" - }, - { - "COPP_TABLE:trap.group.bgp.lacp": { - "trap_ids": "bgp,bgpv6,lacp", - "trap_action":"trap", - "trap_priority":"4", - "queue": "4" - }, - "OP": "SET" - }, - { - "COPP_TABLE:trap.group.arp": { - "trap_ids": "arp_req,arp_resp,neigh_discovery", - "trap_action":"copy", - "trap_priority":"4", - "queue": "4", - "meter_type":"packets", - "mode":"sr_tcm", - "cir":"600", - "cbs":"600", - "red_action":"drop" - }, - "OP": "SET" - }, -{% if DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined and DEVICE_METADATA['localhost']['type'] != "ToRRouter" %} - { - "COPP_TABLE:trap.group.lldp.udld": { - "trap_ids": "lldp,udld", - "trap_action":"trap", - "trap_priority":"4", - "queue": "4" - }, - "OP": "SET" - }, -{% else %} - { - "COPP_TABLE:trap.group.lldp.dhcp.dhcpv6.udld": { - "trap_ids": "lldp,dhcp,dhcpv6,udld", - "trap_action":"trap", - "trap_priority":"4", - "queue": "4" - }, - "OP": "SET" - }, -{% endif %} - { - "COPP_TABLE:trap.group.ip2me": { - "trap_ids": "ip2me", - "trap_action":"trap", - "trap_priority":"1", - "queue": "1", - "meter_type":"packets", - "mode":"sr_tcm", - "cir":"6000", - "cbs":"6000", - "red_action":"drop" - }, - "OP": "SET" - }, - { - "COPP_TABLE:trap.group.nat": { - "trap_ids": "src_nat_miss,dest_nat_miss", - "trap_action":"trap", - "trap_priority":"1", - "queue": "1", - "meter_type":"packets", - "mode":"sr_tcm", - "cir":"600", - "cbs":"600", - "red_action":"drop" - }, - "OP": "SET" - } -] diff --git a/dockers/docker-orchagent/critical_processes b/dockers/docker-orchagent/critical_processes index 99f501e2cc03..809693684c80 100644 --- a/dockers/docker-orchagent/critical_processes +++ b/dockers/docker-orchagent/critical_processes @@ -8,3 +8,4 @@ program:buffermgrd program:vrfmgrd program:nbrmgrd program:vxlanmgrd +program:coppmgrd diff --git a/dockers/docker-orchagent/docker-init.sh b/dockers/docker-orchagent/docker-init.sh index d128422938ee..5bf5bf2d06cf 100755 --- a/dockers/docker-orchagent/docker-init.sh +++ b/dockers/docker-orchagent/docker-init.sh @@ -8,7 +8,6 @@ CFGGEN_PARAMS=" \ -t /usr/share/sonic/templates/switch.json.j2,/etc/swss/config.d/switch.json \ -t /usr/share/sonic/templates/ipinip.json.j2,/etc/swss/config.d/ipinip.json \ -t /usr/share/sonic/templates/ports.json.j2,/etc/swss/config.d/ports.json \ - -t /usr/share/sonic/templates/copp.json.j2,/etc/swss/config.d/00-copp.config.json \ -t /usr/share/sonic/templates/vlan_vars.j2 \ -t /usr/share/sonic/templates/ndppd.conf.j2,/etc/ndppd.conf \ " diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 8ec2b6354ab3..8a942d8549c0 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -83,6 +83,18 @@ stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=swssconfig:exited +[program:coppmgrd] +command=/usr/bin/coppmgrd +priority=6 +autostart=false +autorestart=unexpected +startretries=0 +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=orchagent:running + [program:neighsyncd] command=/usr/bin/neighsyncd priority=7 diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index 276132a7ef29..0081d074ad60 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -52,7 +52,7 @@ if [[ "$SYSTEM_WARM_START" == "true" ]] || [[ "$SWSS_WARM_START" == "true" ]]; t exit 0 fi -SWSSCONFIG_ARGS="00-copp.config.json ipinip.json ports.json switch.json " +SWSSCONFIG_ARGS="ipinip.json ports.json switch.json " for file in $SWSSCONFIG_ARGS; do swssconfig /etc/swss/config.d/$file diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 3766dc918bab..477fd897bff5 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -138,7 +138,7 @@ function postStartAction() if [[ -x /usr/local/bin/db_migrator.py ]]; then # Migrate the DB to the latest schema version if needed if [ -z "$DEV" ]; then - /usr/bin/db_migrator.py -o migrate + /usr/local/bin/db_migrator.py -o migrate fi fi # Add redis UDS to the redis group and give read/write access to the group diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 00c0d9bbc525..82fb75d6c058 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -330,6 +330,12 @@ sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/interfaces/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ echo "interfaces-config.service" | sudo tee -a $GENERATED_SERVICE_FILE +# Copy CoPP configuration files and templates +sudo cp $IMAGE_CONFIGS/copp/copp-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +sudo cp $IMAGE_CONFIGS/copp/copp-config.sh $FILESYSTEM_ROOT/usr/bin/ +sudo cp $IMAGE_CONFIGS/copp/copp_cfg.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +echo "copp-config.service" | sudo tee -a $GENERATED_SERVICE_FILE + # Copy dhcp client configuration template and create an initial configuration sudo cp files/dhcp/dhclient.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ j2 files/dhcp/dhclient.conf.j2 | sudo tee $FILESYSTEM_ROOT/etc/dhcp/dhclient.conf diff --git a/files/image_config/copp/copp-config.service b/files/image_config/copp/copp-config.service new file mode 100755 index 000000000000..8eed2353eddf --- /dev/null +++ b/files/image_config/copp/copp-config.service @@ -0,0 +1,11 @@ +[Unit] +Description=Update CoPP configuration +Requires=updategraph.service +After=updategraph.service + +[Service] +Type=oneshot +ExecStart=/usr/bin/copp-config.sh + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/copp/copp-config.sh b/files/image_config/copp/copp-config.sh new file mode 100755 index 000000000000..0660528a54da --- /dev/null +++ b/files/image_config/copp/copp-config.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +sonic-cfggen -d -t /usr/share/sonic/templates/copp_cfg.j2 > /etc/sonic/copp_cfg.json diff --git a/files/image_config/copp/copp_cfg.j2 b/files/image_config/copp/copp_cfg.j2 new file mode 100755 index 000000000000..61f051f43de8 --- /dev/null +++ b/files/image_config/copp/copp_cfg.j2 @@ -0,0 +1,105 @@ +{ + "COPP_GROUP": { + "default": { + "queue": "0", + "meter_type":"packets", + "mode":"sr_tcm", + "cir":"600", + "cbs":"600", + "red_action":"drop" + }, + "queue4_group1": { + "trap_action":"trap", + "trap_priority":"4", + "queue": "4" + }, + "queue4_group2": { + "trap_action":"copy", + "trap_priority":"4", + "queue": "4", + "meter_type":"packets", + "mode":"sr_tcm", + "cir":"600", + "cbs":"600", + "red_action":"drop" + }, + "queue4_group3": { + "trap_action":"trap", + "trap_priority":"4", + "queue": "4" + }, + "queue1_group1": { + "trap_action":"trap", + "trap_priority":"1", + "queue": "1", + "meter_type":"packets", + "mode":"sr_tcm", + "cir":"6000", + "cbs":"6000", + "red_action":"drop" + }, + "queue1_group2": { + "trap_action":"trap", + "trap_priority":"1", + "queue": "1", + "meter_type":"packets", + "mode":"sr_tcm", + "cir":"600", + "cbs":"600", + "red_action":"drop" + }, + "queue2_group1": { + "cbs": "1000", + "cir": "1000", + "genetlink_mcgrp_name": "packets", + "genetlink_name": "psample", + "meter_type": "packets", + "mode": "sr_tcm", + "queue": "2", + "red_action": "drop", + "trap_action": "trap", + "trap_priority": "1" + + } + }, + "COPP_TRAP": { + "bgp": { + "trap_ids": "bgp,bgpv6", + "trap_group": "queue4_group1" + }, + "lacp": { + "trap_ids": "lacp", + "trap_group": "queue4_group1" + }, + "arp": { + "trap_ids": "arp_req,arp_resp,neigh_discovery", + "trap_group": "queue4_group2" + }, + "lldp": { + "trap_ids": "lldp", + "trap_group": "queue4_group3" + }, +{% if not (DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined and DEVICE_METADATA['localhost']['type'] != "ToRRouter") %} + "dhcp": { + "trap_ids": "dhcp,dhcpv6", + "trap_group": "queue4_group3" + }, +{% endif %} + "udld": { + "trap_ids": "udld", + "trap_group": "queue4_group3" + }, + "ip2me": { + "trap_ids": "ip2me", + "trap_group": "queue1_group1" + }, + "nat": { + "trap_ids": "src_nat_miss,dest_nat_miss", + "trap_group": "queue1_group2" + }, + "sflow": { + "trap_group": "queue2_group1", + "trap_ids": "sample_packet" + } + } +} diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index 875b649adc39..299ca7c14c13 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -48,7 +48,8 @@ $(DOCKER_SONIC_VS)_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(BUFFERS_CONFIG_TEMPLATE) \ $(QOS_CONFIG_TEMPLATE) \ $(SONIC_VERSION) \ - $(UPDATE_CHASSISDB_CONFIG_SCRIPT) + $(UPDATE_CHASSISDB_CONFIG_SCRIPT) \ + $(COPP_CONFIG_TEMPLATE) $(DOCKER_SONIC_VS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_SONIC_VS) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 50996e36e191..054446e525b0 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -143,7 +143,7 @@ COPY ["start.sh", "orchagent.sh", "files/update_chassisdb_config", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin/"] -COPY ["files/buffers_config.j2", "files/qos_config.j2", "files/arp_update_vars.j2", "/usr/share/sonic/templates/"] +COPY ["files/buffers_config.j2", "files/qos_config.j2", "files/arp_update_vars.j2", "files/copp_cfg.j2", "/usr/share/sonic/templates/"] COPY ["files/sonic_version.yml", "/etc/sonic/"] COPY ["database_config.json", "/etc/default/sonic-db/"] COPY ["hostname.j2", "/usr/share/sonic/templates/"] diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 349c538e1daf..ed668983c835 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -46,6 +46,7 @@ else sed -i "s/up/down/g" /tmp/ports.json sonic-cfggen -j /etc/sonic/init_cfg.json -j /tmp/buffers.json -j /tmp/qos.json -j /tmp/ports.json --print-data > /etc/sonic/config_db.json fi +sonic-cfggen -t /usr/share/sonic/templates/copp_cfg.j2 > /etc/sonic/copp_cfg.json mkdir -p /etc/swss/config.d/ @@ -94,6 +95,8 @@ supervisorctl start portsyncd supervisorctl start orchagent +supervisorctl start coppmgrd + supervisorctl start neighsyncd supervisorctl start teamsyncd diff --git a/platform/vs/docker-sonic-vs/supervisord.conf b/platform/vs/docker-sonic-vs/supervisord.conf index 79baead76765..09f9c34b14b4 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -59,6 +59,14 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog +[program:coppmgrd] +command=/usr/bin/coppmgrd +priority=7 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + [program:neighsyncd] command=/usr/bin/neighsyncd priority=8 diff --git a/rules/scripts.dep b/rules/scripts.dep index 677a60c2ae47..929611852ea4 100644 --- a/rules/scripts.dep +++ b/rules/scripts.dep @@ -7,3 +7,4 @@ $(BUFFERS_CONFIG_TEMPLATE)_CACHE_MODE := none $(UPDATE_PROC_VARIABLES_SCRIPT)_CACHE_MODE := none $(QOS_CONFIG_TEMPLATE)_CACHE_MODE := none $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)_CACHE_MODE := none +$(COPP_CONFIG_TEMPLATE)_CACHE_MODE := none diff --git a/rules/scripts.mk b/rules/scripts.mk index 13fae75434be..e0694a1cdf9b 100644 --- a/rules/scripts.mk +++ b/rules/scripts.mk @@ -26,6 +26,9 @@ $(UPDATE_CHASSISDB_CONFIG_SCRIPT)_PATH = files/scripts SWSS_VARS_TEMPLATE = swss_vars.j2 $(SWSS_VARS_TEMPLATE)_PATH = files/build_templates +COPP_CONFIG_TEMPLATE = copp_cfg.j2 +$(COPP_CONFIG_TEMPLATE)_PATH = files/image_config/copp + SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(ARP_UPDATE_SCRIPT) \ $(ARP_UPDATE_VARS_TEMPLATE) \ @@ -34,4 +37,5 @@ SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) \ $(SYSCTL_NET_CONFIG) \ $(UPDATE_CHASSISDB_CONFIG_SCRIPT) \ - $(SWSS_VARS_TEMPLATE) + $(SWSS_VARS_TEMPLATE) \ + $(COPP_CONFIG_TEMPLATE) From 88fc9e3faf904bb55ec1f0d2c7ac0bcf85f09f33 Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Mon, 23 Nov 2020 10:59:41 -0800 Subject: [PATCH 1427/1427] [yang-models]: Default value for leaf-lists and tests. Changes: -- Add Default value for leaf-lists in ACL and portchannel. -- Remove members in VLAN. -- Test modifications. Signed-off-by: Praveen Chaudhary --- .../tests/yang_model_tests/test_yang_model.py | 10 +- .../tests/yang_model_tests/yangTest.json | 97 ++++++++++--------- .../yang-models/sonic-acl.yang | 10 +- .../yang-models/sonic-portchannel.yang | 14 ++- .../yang-models/sonic-vlan.yang | 8 -- 5 files changed, 79 insertions(+), 60 deletions(-) diff --git a/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py index 3bc2886f38c7..7579bdcfa8d3 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py +++ b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py @@ -129,6 +129,10 @@ def initTest(self): 'desc': 'CRM BREAKOUT CFG FLEX COUNTER TABLE.', 'eStr': self.defaultYANGFailure['None'] }, + 'DEV_META_DEV_NEIGH_VERSION_TABLE': { + 'desc': 'DEVICE_METADATA DEVICE_NEIGHBOR VERSION TABLE.', + 'eStr': self.defaultYANGFailure['None'] + }, 'INCORRECT_VLAN_NAME': { 'desc': 'INCORRECT VLAN_NAME FIELD IN VLAN TABLE.', 'eStr': self.defaultYANGFailure['Pattern'] + ["Vlan"] @@ -180,8 +184,7 @@ def initTest(self): 'CRM_WITH_HIGH_THRESHOLD_ERR': { 'desc': 'CRM_WITH_HIGH_THRESHOLD_ERR must condition failure \ about high threshold being lower than low threshold.', - 'eStr': self.defaultYANGFailure['high_threshold should be more \ - than low_threshold'] + 'eStr': ['high_threshold should be more than low_threshold'] }, 'CRM_WITH_CORRECT_USED_VALUE': { 'desc': 'CRM_WITH_CORRECT_USED_VALUE no failure.', @@ -390,6 +393,8 @@ def test_run_tests(self): try: self.initTest() self.loadYangModel(self.yangDir) + assert len(self.tests) != 0 + print("Tests:{}".format(self.tests)) for test in self.tests: test = test.strip() if test in self.ExceptionTests: @@ -399,6 +404,7 @@ def test_run_tests(self): else: raise Exception("Unexpected Test") except Exception as e: + ret = FAIL * len(self.tests) printExceptionDetails() assert ret == 0 diff --git a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json index 90d748309dca..fab635afcca2 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json +++ b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json @@ -728,6 +728,54 @@ } }, + "DEV_META_DEV_NEIGH_VERSION_TABLE": { + "sonic-device_metadata:sonic-device_metadata": { + "sonic-device_metadata:DEVICE_METADATA": { + "localhost": { + "bgp_asn": "64850", + "mac": "00:11:22:33:44:55", + "hostname": "asw.dc", + "type": "ToRRouter", + "docker_routing_config_mode": "separated", + "hwsku": "Stone" + } + } + }, + "sonic-device_neighbor:sonic-device_neighbor": { + "sonic-device_neighbor:DEVICE_NEIGHBOR": { + "DEVICE_NEIGHBOR_LIST": [ + { + "port": "Eth18", + "name": "dccsw03.nw", + "peer_name": "Ethernet116" + }, + { + "port": "Eth18", + "name": "dccsw02.nw", + "peer_name": "Ethernet114" + }, + { + "port": "Eth18", + "name": "dccsw01.nw", + "peer_name": "Ethernet112" + }, + { + "port": "Eth18", + "name": "dccsw04.nw", + "peer_name": "Ethernet118" + } + ] + } + }, + "sonic-versions:sonic-versions": { + "sonic-versions:VERSIONS": { + "DATABASE": { + "VERSION": "version_2_10_31" + } + } + } + }, + "CRM_WITH_WRONG_PERCENTAGE": { "sonic-crm:sonic-crm": { "sonic-crm:CRM": { @@ -1189,44 +1237,7 @@ ], "vlanid": "111", "mtu": "9216", - "admin_status": "up", - "members": [ - "Ethernet8", - "Ethernet3", - "Ethernet0", - "Ethernet1", - "Ethernet6", - "Ethernet4", - "Ethernet5", - "Ethernet9", - "Ethernet2", - "Ethernet7", - "Ethernet32", - "Ethernet30", - "Ethernet31", - "Ethernet36", - "Ethernet34", - "Ethernet33", - "Ethernet35", - "Ethernet29", - "Ethernet21", - "Ethernet20", - "Ethernet23", - "Ethernet22", - "Ethernet27", - "Ethernet26", - "Ethernet18", - "Ethernet19", - "Ethernet14", - "Ethernet15", - "Ethernet16", - "Ethernet17", - "Ethernet10", - "Ethernet11", - "Ethernet12", - "Ethernet13", - "Ethernet28" - ] + "admin_status": "up" }, "Vlan777": { "description": "pvlan", @@ -1235,15 +1246,7 @@ ], "vlanid": "777", "mtu": "9216", - "admin_status": "up", - "members": [ - "Ethernet9", - "Ethernet2", - "Ethernet8", - "Ethernet27", - "Ethernet14", - "Ethernet35" - ] + "admin_status": "up" } }, "DEVICE_NEIGHBOR": { diff --git a/src/sonic-yang-models/yang-models/sonic-acl.yang b/src/sonic-yang-models/yang-models/sonic-acl.yang index 3ac0abe8074d..fc2515d0b5fb 100644 --- a/src/sonic-yang-models/yang-models/sonic-acl.yang +++ b/src/sonic-yang-models/yang-models/sonic-acl.yang @@ -264,7 +264,7 @@ module sonic-acl { } leaf-list ports { - /* union of leafref is allowed in YANG 1.1 */ + /* union of leafref is allowed in YANG 1.1 */ type union { type leafref { path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; @@ -272,7 +272,15 @@ module sonic-acl { type leafref { path /lag:sonic-portchannel/lag:PORTCHANNEL/lag:PORTCHANNEL_LIST/lag:portchannel_name; } + type string { + pattern ""; + } } + /* Today in SONiC, we do not delete the list once + * created, instead we set to empty list. Due to that + * below default values are needed. + */ + default ""; } } /* end of ACL_TABLE_LIST */ diff --git a/src/sonic-yang-models/yang-models/sonic-portchannel.yang b/src/sonic-yang-models/yang-models/sonic-portchannel.yang index 69c8fa6ac161..8303cec2d9cb 100644 --- a/src/sonic-yang-models/yang-models/sonic-portchannel.yang +++ b/src/sonic-yang-models/yang-models/sonic-portchannel.yang @@ -48,9 +48,19 @@ module sonic-portchannel { leaf-list members { /* leaf-list members are unique by default */ - type leafref { - path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + type union { + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + type string { + pattern ""; + } } + /* Today in SONiC, we do not delete the list once + * created, instead we set to empty list. Due to that + * below default values are needed. + */ + default ""; } leaf min_links { diff --git a/src/sonic-yang-models/yang-models/sonic-vlan.yang b/src/sonic-yang-models/yang-models/sonic-vlan.yang index d00e68b39029..f7ac7c9d61fc 100644 --- a/src/sonic-yang-models/yang-models/sonic-vlan.yang +++ b/src/sonic-yang-models/yang-models/sonic-vlan.yang @@ -155,14 +155,6 @@ module sonic-vlan { leaf admin_status { type stypes:admin_status; } - - leaf-list members { - /* leaf-list members are unique by default */ - - type leafref { - path "/port:sonic-port/port:PORT/port:PORT_LIST/port:port_name"; - } - } } /* end of VLAN_LIST */ }

^snyfa=u@%o2faLh#PMh~|Zz`|$YUGSqRqmy1fY+%n-X-wEZ$eb{q z>&}I*ICdhwPIA(Rf8pd`3jZbi>z@2?b9fDW)ryJOKRx{K4sU_K4L@0P^^B(ne)xyY zd<1?x`~;m|odubN=LGOH0(Wu%&xPN+#eY2}@hyel1vmAtn)gZHVyE|;_wulx0e_nK zT$e^0eN43_dyWr(i;nf;2R-w=_#%G&Yt2M#yNqKG{lwd69wyCit+l61YKd;60UvE9;trhL-fPP#+XLl@GBZ!@I3^5luw%aSgp z(#iZqze~Qt9aA#uLZQP>orv8dEeD(ai|anITZHz;PtjJz?llQoem5cc0@tqm z1oV>AY;AL}wjJ$#1rxE~irt?iXl4KZbFSSXwE62MVvmS+PlA@QDtVo&okRQc(b@V3I<7Z67o=Qb~*kf)S7VBsy`jx5gX$R$`TXx<=tV`~V{-DxH ztQohG^WATmb=BWZ6g5Rlm*!sSTjFt89>jV62hu6R}bb9+)iuCU+coqCg zt|OzWZLpT5YkA%!nMT_Y;7bY*v6oi)=aq^5Z1@rb&xQA3KMbFc_CKwBvGyFK_ilF{ zl%W@!_1Jv;nhE1~T-xEg;l*g3`ccoy`r$7G@GZcV3kID$$Px z+=Dd2UxAzA)Co_$&K##fcpls@PLls5JR5E*Pc=LWk3ZwBR&n%s#w+D-N573dskr{( zV12y&4cwo8*?bSy2;T!YwX;t6Fx(WMLHN6HQ#+c3uQKeJihq$?c;*W?<(~ylhkp>Q zQ{U=)OGWSq+?0PMJSTuR!pq>M`s;)j!%h8k5Z(Yc`9BHY1~-kvksYkT;K%Cnsk1~` z@HgPb^21+&8_N$5f5q&7BYZ8~})lVh78@@`XSLf#&;g7@p`e!z2QsEE7ujD#1s`{JHJU4=NA6ipg&BFJ< zO|eRAL=atvOoYlkg8~uG(Uc%}xG|z(+}6 zqSLG2jhlr>YA1}p8<%!lu>ZMm@!u4`Quq?=n|KZUB)G}{7WgW-sV()uFNd4@$_Tt1 zZmfTJG2G-|+D_J70X!Gp1~>U%3U7v+{I7uz!cG3Sz@LVj{O^H33ODt|5%_~}Q~74$ zF9z^5Hd)_-o6469e*n4n6h6dnWaFgHT@Mqwr_7Gwt@hP~eJv5R2 zad;)ZMDmp1%sq+k>z82b4YVm}opq8rKU59h12;W8Z-x)U{bDHhSn2Q=Bz-cz6e?e= zvmyC z-_ZKid6e{p@Z}8?vA=Td_$~4Oi)25H2%Yd@xZfBh zX$IkgaL<}ittlsMe!jM^zB3&87HyC8r5kyQzX4l{tva+G zU)1`w27V*F%9EFMGazMYfe*kt~ zhxPCm;g=@SKIT<Nj)+hB@NV0FWTm$*68rW7+C6Cfe3f?42w!%a-40GtwhZl{7k%MQ zyB(aZ^givN?k@IQZ#TDtHh6jf?}IN3;G^&ixL-e!dYHHK_gib^!yDjfq<>1*8WpN6 z_TFOhK3TD~C)q1D=Q)_zF8en74ZHlyCUrE1?H2gETt^y}ZJ#)GU~AJi{B22I1Mo_? zshs2R%i)Kjb=s>svmI*X89m&zK8(WG!~OcBl%)&%YvEhCj@;udOX6>rRb#6TZHo3q ztq+^w8{ww1bi*%&o5sdrcm@1$ZC|~kJp-4rn$oA<%^BtZo&!G*Zt|}LUL26V8XlB? zvz@=mem8sr_Dyv;3_mF#{~35*08hP#=Us49{yFemc)5j)Kv4H$b;Cln| zuZAyaHs{|Ae~a`dY5(na)TFO>!&69qvF0j1!|+0Qp62Qt*$li4eyZl`Y;Nf@X=5>yr#K~d+K{wt!S2h(|-*mHhSSlz)w!F zq3>lz(X2%CQLRzm%$kRv0GGHrmW33l%VBNTRaos3otiPA_ham=0csu+l_*$-=I!b77187Fj__a6j zY23C^5>_@ApVgi2eO4DmlJ-6BcfQ3w4c9tP-9Gcsw6>VrXBqt4@Y51(=x?sqp?MgM zseQJ=AA_6PXCM3#_;Q_x`X>7*ybEq>pY!l;xT$?+v=e{0X)MZzKWgAnd@6?zz_)7u zq@Szz;p)*Wy)$7v{ERzaw8P&G@Ub6$0Dg_mL%r`d2G7U7X+5w2Uj;Yy!OZ(OYX-m6 zW8eL5PXW9*(SNnJs(|MO@OpSOfVaa_19(4tp7MX*)d25;U(B^L-l{cC2YeiEiq`;q1a2Bf$Kn48m%JSNYMu}MfHhly{V048 zeuhr}Rcnlrv9%EXI-Extu6=91+ot1Gg|6ss^LX6^UkCT=i;_a3qIe_96?ux zE~@=ed$6-M_x8E1@d8PV(snbhlm0lJUcC#E3-5uO=7m!DGjLCTQe$F`ZQsOO;P(ck z?}6_$aB08!@ay5(NvuI8Rr{5>XFaX=S@+}b@iy@Q>(zVA{zl=SgZtHsq%VY*1f<^x zKQ$nI1AI+D`VRPVxVOHn@0>{f1Mph7r(LMu?-+--!%h7!)X6;++^_#du^)v$0}mQQ zi_oNhCn1Jv9>Q`;>2Lsag!S4)6KMHSxd+WpPH}mj) za8tj@_!0H-U30(5htHGV)UV3nQ}7gG=gd3yURO4Ms)N4>KTUJ{zT{e&IP4uoX#582>fMuv9_N>$A@7Lzju2<8?XIImA(T z6n?bk>fMET_|foVG*`bXmhlK{8n|g3%ZI1IP4!d`e~WS)tL>}jz;*C{!cG0W4SoP_ zs)s(f%rB<=N8!T(d>;Nd+%!&PJjyt3;MtU^gY-M#=W-o6(Yqc<{LQ{fY;~eNU&lf{ ze{Y2Eg_nA`_24Ex|G}kAn(AT@9)g?N)FfQ$;{DoG>Q8v4h#kK+BV}&Ij@0?hTt^DM zWllT?P>!uD(N=lNK z`aot6_wI00+za4Oz)fwm0{#fx)CcO}55u?VGV1*wc;sI5T-OhOll0u;xNEGi`#q&G z_*T;U#W;r~mGByPd`(;7txvyu#hl03Z~9(BJ5pvPshe9wNIXLs%9x+sPhz)f{g z1^*SiSeISJt_eO3U#Yp;x9Ebu0Z-Rly~{KNe-&=(3)Aq|0`gD!DeL|F%xygzelXnB z){EiqV*e!VpL%vz1y3WrsjoG`4~0i{dR=~-FV$QLcH`@sO74gWpd)P9TM|AL$1Uj?6mo8r?1-wQXjuP*p7+|<5?;L`pN*X37dAExc} ze*II%gBo}#?Jqta{QUjLgZw8LYwkDaR}RmC`{gI~Q3vmVo9e3#{wKJpzWU&U0elqx z6S%3q=HdSdU#8=wo_%CINqd6()t9VO^Wje<+V@$fZbbJoI@7q+0DlE;>Q^1`fy8{& zxH$lyhMVFv4u2_thx*vRhnwOMh4;e!;vn@{2ycfUrQ@icGjD{q!cFCCfNz7F)(9Q& z8{sEv`}XhsNd5!xCWHNKcrpB1cq`YDA=R!~ONGy1KlmK?oNDUNt-6wQ&Yn%BJI3U| zUk%8sm%OA+#`F49a9(xT%K5(e9AO(g4{nNEAAETLABBhDrh1!)OS>`Ed&W~%S))1@ zYCg)hxhZ`)d@uG-)#=q)lREf+!%gcNwbD!r{(SFv6=$31pyFNPvEAQ^}`>8o7(Ug{Au{vIwtB}$OZT`+!XW7r+Kytztof7s{Bm;Rsdhp z>3{wp3a@|{!-HZvjStN~vSYgZ{bSmL&23%gn2f+{0{AR^Gdx$9soHHvX}_YKz)j;u zF1!N1UZ=Nz_f6JOec0a)mvv7hTa}0ThM%4ZU*|r4jKAO2fW3d9KU&*U`&1q9Hw-+R zGz0Jn_-A!``#C~*gZm&sv@>XzJoNrrsoRW!Q0PRoer-c+<-?DLpT@N_R~nvQRHDsB zyIE_)?p{bE{93rFop-`3;eK@z#pWRVY9&hUtT`6WL2 z@JhI;Z{r82f&0~?#IzZn3HKYLg?Gb01ovx`!iVAiL%dAsXW(zb zSEF^xr`C6=&$722kUj@K2ltx`CI1rm0r)Z6zS>i+hQASDzZw1-{8*h{?HPB&UxgdX z4}T7BD&GuzBq0CPLEd$Qo6461e+HhR{j2$>){c&Uwz3O6M;*A+9uca-gxnPXYJxtDs?-Awg6klX$cOI`am9hBkALPU?ic=eEPrw`tqNf%bWQ-?rq_w zK2QMP5Wp+oC&5kes)u(!WwzfAZ-blqKtH@afRDjD;HG#k*y;V+gY|x)^P#&?@g1sH^xV@71w^xq6<-bfgzhWJSj`x!~cplv3e+ZrrkLOqQ{`n1| zA3^WeuBASv;lB&uDKByF4F5P0# z_(fbtT9i%dDDk(D(y+DsX}e!`D6O5pU%wn9%{tPU#@7XSHry{};$I^?3m*5cTjlBF zUk}>z(8lA_ue1U2so%>z0%=ThP&<4ld>y_xbz=Sebi57q!#e}`82p(4`wQ?_;HLOw z{s(h>055<)8o(>yZ2`O_*J#cw);1)mZ9fn zTWalpzs$ZYT2mWLf$xHEk$nHxYl|0(9UrBi7yDUx9)Bu>ucyDAdkVJF ze(uiai{A@AlTUiQb+Vq)<348nC;R#aAH{ArcJu!^5er4Id)lx3?LPG0?~m7Gw;sEG z^)K}kfsems{gy)HUS-#+AAY4I{xcVGABWJc`?qO`Ie0#0$H?zkh}H@zhE0H@d>FJMoIVLOVQc(tFla&DB}(d*D~;c!jMWWReb>Y9cJgn8KMnVLRwC&;;S2Dud(z+Lq#uND{@`TnLJvRB;gj$- zxGDe0pSe%@(4_IZcUkbwaKE-MYlCj=Z-U2vXQEHlh4t-s9{VM4O#JqH9X1c7PsXG! zoi=Pgi-@mN;cvmeApL1d*^EE0l3x=#(lIG98bZIyFqR0PhOdAhrSr4T>4*jLthgLlBob$az3oAm!;ZxL>KPLT(H8GeFJe^tD>#mC|@_&EGd z&DHN7)WR=3${fE|cq7~tzg~DZ+!VjP@D8{sesl19;eO*^CO)UX$~R=;rnb^f`d#pN zTZsm@m5tcyMeEnjC9ei}Kl~USEBl$5^n(<5A3Xl8`5cv((+|AAKR$wf>Cxuc&cch} zrr4(ah5JFcDYm)rjc`+JOW~IWZ-ATp>w$L#bzpwYm8lRY1y3x25P_WM`T#{0&3t^$9T>&T_5y~@0t z@J-TsY;8Vf(ztKZ4zGeQ*LhjTZ{o4&hi?iAz^%mw9mz`)y)BnOJnHSXgH+?q(9ZAgn%lEH+!PxnqTYOeDS; z@J4t%zGKR!PkhJFUi4vqTawoTyc}+7E146lQ{kqzQUEW8o7zeRd^_B)tw{d$@GWpt zUu%cA!%bsRKfDEQ>T6^0KDeo`Ex;d#FT)q7t*bN8nUl12xWwJz>byh&ya(>r7bVRg z_UGX7x;hYCS54S@E^4l;F8C1KuP;Q&YY6@fd@I+EuhJ&e_l9QBq#u`1AD?miL+b0K zg{Ns7>P%-2e3m?}(cJ#tP?W!wz}J#K$cGv<%>h2N!0Q5h=z&+k{d|x%H3EMeezC_# zYk(6z3x5M{+Luh5!Uo*bW^>`c2;img2jL&n`K$L!YvAIa$$ks`e)u+>UcD361D}U` z+r0IVGhTjpbmgS+J&0NO;qVk~Up*sD+t0ci`zD?Xe--Z64rR>i!~Q6|jO$41v+g=N zU>~dzn^GpfJfqm@gpb45a;@98{-*Dc?YG}vme`oKZ7?KzY%IRtFR@FVCicYU!&+m{ z2T}f(1HTV`n&$K|&-?#qdeMATYt(o5YT&*wI_)3}{_~Y;_onE~^ zKLUROZtBCc@CV_h_Lufo*1m94`^$yTz>9VM>V1q-c>3|?_E!TB!%h9O1-=%3u(q$B zTlT=CaFhQd@IwRmEc`9}_v@cg@=SZf@-Ju%%R^I^n1>oi%ix7@QytX8bK%$MGOF*k zwZgY0+PBwO(gu3ro8hK9+6y0mo9bu|J`HC}#%+V@U8(f{=Kcl58{tK8(;A}zz7}qZbq9PU+%z5x*!la}moZ`-zBJK4pZ60| z{>E7ibjRzMsq;qJ@KfNPu~D5bD~6v8_q&gkHd_VHg`38`CU_3qRHt3=Y`Vc${ zH`T*5ycq5mC-Eue0QY5ZQ$1wESHVsG6~kA+O>J(3{H6TyHn%po&9!2y4Q;lr3$^a- zg?GRY*If1Az3@BWrv5VrKVp?RR_T8ag+2v0#VQY;3-^mv6ralA8StR9-Q)OBal)ka zzU4V89zN&M#by^a&t4sDQ~bK)fOT3e^Bgz{0rbG z1ms@<|1dnN?W=PU^)@&8-wt0Ekbgh?UFv(iwr{_SBJml6M+5R-u(_%JGT#h^jtVGW z0sL^dDZUl(6u4W9Ex;$?e(g)@Ec2f{Q-lZg z<1TEZooM&DtKYxR)nM~o^rkv*fzQEBG3|jLfFGypT+Krx@LBkwnya zfd#bX0lsGboB1Vx7r?XOrdU_N#aC0T>){6nq;H46ODs%ny&oPTy{WH{!Dj;6`T~43 zpsi=l^PK8rv;6}2I=HE=SHRZ?@Ot~{v>!A*O6Y;)&ll=YOpCW^|L8)Xo2U$O+NR)rA($WkHF7{ z`|Xe9V80xG9(+iA9#B5Zy`Rsy!00=iBMh+Dg}pZx?Tx*^y&CN8IK}MWJoa|NbM6e>0!8D~4Zv!2hhBl%)#39s6f#`|8|w6TB;ccft3-&-bLa4n0U&bK&9q z$yj$1Wi3`^J(GT2!;`iXli~-k#Fsg=J3ciT`;5od8SzO}csdVky5QgP@NYOg51z4h zGS=zg9S$#px5G{KS_|J9z+2%p0lXJ}DSWRd{}Ctuz3{_Nn~Xi<;ZHk!4&DR5-NW7U zO6f7mS1=iC^6*9{eIC34Zo2O(gYSkf*Xix&wo+GPfaGf1hFYm9Kz=j$ZHYtMr8^JRN=s z*N%NIg%!XqG_Z153v825x?0%FhIB2G->3ca>z4csY)JC+VG@H$*y^ImSibhf`V@5h zIeH{1DYPE$H)l%vEciFEZL04g_)p-b`W`0#gR$R?t;lWfsqgT)_Bl>z8}n#4FKX{J zYh|1lzn(+;l@#pWr?m9>S!J3e)M_Q+qNH8`UKnJ$28hjwDCAUp|p!Wt2n18CxtHBYTJz|ZGv6#xe)CW zXum75IP^KUP8^?Wtze)PKWflNZ?bJ?DSd)%(YB*)KpXctS808G9zwhRYqs5+ls3Vx z_&kSpH`?1H_$yK_pLU{`$ZLOY4}@WZeh`mIl#|9Yry8>8r-X|-)1t@H`D#gE8ANuiZ@ z+j0Jg(k}X}+D0zg$u`^WwMv^{SA4EOTlC$@*coh~N46=g#Cesp=fe-vJ~yMk=ts8g zZ!3L*ZSlDe?GtE^mUj1jrCqcgo^s+miMI10+isuICfF69(+*Ce-X>!uY1kc9+C{s` zM}JWJT!=pUlx_RJl-|d7HQENW^J4q2N-MVG{re@4?RNCVzq4(Z47qilU|ZrbgtiN9 zyswliEw&TK(K)nR{$Shvfzl?}m3TxykQ90W?R^sGN0e54j*p|>{#}Ybe~)eZIi>fp zU5~a6?Yy+=&xL3g(Drg2iM-&} ziTGT~`xqBnmPK2Qw();#yUUd}!LIn+hISI|OKf07Rw=Fc93MM64$?jkp>GPmZmoSz zSNa6o;>R4?X|(aN;~b@3w5`UD=o04Sh;6r0X?^ULpgrZF*JD4BvA;%Xu^Vr554dB0 z9op_Cw%t8Sn_yRB(TO(o(AQ(nrDFG0r4@hU_4fnM*uNM3?xSqmXZ+5slLXrmi_oD- zp>W3QRzEpcX%~G~V}B0X!DDQ@_b6?GUGcdbZC2*%v8^)4?p9jI=Lb@JDy?I?&a>v2M4x}WZF^kleQc+tGA5x-62E7Z*0DY2SvMA<-||u0 z_CdqOSW8T*(Y}B-?)MQ&>)7`C-HtwgwQYN~();*5Bz~j)hWLGo(mJ*`d*VHher}Cz z`+TMMv7L1o>)lV-eqW}vj%}~sW$2$d(Y9Ty^a-}5{WYLndD82#2W3B@L1`Clhi{2@ zbJ2FAZU3Zgw@qmi>`JUh(Jr8kk9nO+D|X}K^d}G2<44NjNuli1Y}>z7dLP?)Xq(XP zNWtglmDaI+iRXT(68$Tmwr#(o^ggy*(5@|dJ$AU>S!Bl)kMwmpD8<4oK3 zhn3#P_6*uOwDI}&V@m7z{Rhu{oB6?{P~qon+eJ$6W4jn_2ihMj!|zh1b^NYBQpdXv z{nBdN_LVQX&I4E^XX+xC#sC)k$qr5wRn^9?)3dzE(4XEhJx zp?&8L+wQR=##o5Y8_{0+t=D5aWllUnX&s+GZ%v94WBzMF-_vT_Ua#~%KKG+dyW95p zJf-#Vc^d7WHrwuZls3Vx_?*5piQm?FJ@zG8dpw}Dj?YC0>9$;izUKS3?S7?Cur1}Q zK|6vr-j;`y*2m{|w0AvV+dblsfpH!}`zG2$Wc)u?X&s-(J#Awi{qT=$+ovdfg3l6< ztPip8()D^QBz3r6X&u}D>6u%~&@Xh`wl7n9AKMLRD;{}0c7pVktCiNV9kMzLen|X! z&|lPN+kQ;x6Ksoi4DAzW|e3$MpMmxAq6mDaJH-=Wvti?NsHD(#wC_kAzN@s0b{DKF6d&@?mc(qkpV%81NTs+BguUukoFXkS751@X5|X`L9K;%Rf!=$9N}+rCrj6KqTQ(lc1oqrF?&+>wGV5B(1}ZsK$NKF&Kvx1(QjjBPth=@V>= z&qLxf+HZ>OT%}#~`CHZyE!sJ>!ymTo-lVh%cE#uD(Tx4ksaU(Lk#193$LAY8`yHj| z+g97Q?^pT++u}z(+Ih6+%Gm#~(k}XZzPnE9Lc9DF+wMP=Ho>m=ycg{@v_FtNtC-S? z&+&DV_kJa^obf2%ww>{^TQ5GgbJ3Q3YAV*Z6x&%!>)8I*5qfQ~5&hnCY}=nx`UKk& zk7l%aB~!5{B_3BO?P5HB?#81J?ZCxTu}{f;)58hctJ!z?jpc>dokaU$`BZGJXn&oc zt@3Kqj!6oQT{2}o-yKcRUcs7popt*mb_>u}Ts9T^q}ZK(uXfP~dA1eGObT6DF=c$V z6@}jh_j|S_b=pN<4e+hfCqM9?ZXHS7<9+7>XC9FJYOwd*73Ta};L~uw{3Lx3{HhzK z;`>_8^T=>d{MoFOJsCfak5>@_Culm~^qOC;xD%#sbo9oqnk?>z=HyFt``&icD zo2HD<%!}cd!%s%*`1R$uTk&U%Rq)yX-UQzTr-`}g)w#_s_|^bE1m6^3e;Qr~&(ikQ zds8VZl0x+c`x2{ccolp^r(gVr$$yRoQ+*BN*o=@;;In7sZb z?YB_X%VK_IwD+&aKYwBWO0MSc=G*PJYV6J@Mqw1_Qz=(>YQ35 zd=Gp;^KgGWz0_AK{Q56W#opjLGOm1yzpV2^C!b+-dDT-1zd2|fJd!e%!Rz7wA$ATZ zJM@k4MjE{RH6`&mBbpRi^`$A}yTkeLXaFyVFAv~#@O1bw-zf13y-C^`3nrd_I78!ry{_*pPk@e)gBAe9taPtV-bP;a74US*>D4z4PrZ z&$nIDRx(GUJzD3bzP*wQuZ1(sy0Nl8wG%IEDSR{hD9zRP6>8v@!{z*l6KnPDrFne4 z2wn+}to8cJ`CX5%{n)w#ZHl&4prz7=koOBUcYa2azPUuxX+naA^71a2xz0lXe= z8dEFa4FUPr!zI=x`|a@S;ij{q{qSwm$$kNRUA=jptAG~<@Ot?A0NxHS3gG?l4FP-%UL3#|;Ab1S^od6JO5)Qg_shkq zFIw-Y-O7y7vnDDZ8~bcnRshm-WV{i-?)b`7tWf6fdsRA_XTIWH*G{9|&063-(nTKg zYGt{6t-S_|!n;>7XR!9G=i2G7Vzbs=Q|F^;`|4Eedq^VBdF{#Z=C9lKWbImswh(*Q zMbOSGZT!1k@k5i5#d1k|$@wV#`KGDZm$`QGXVRqD@v*N2-bdc1{#Xrv0)D3_{WqQT z&G2mM!!-7G!&kyhV`m)-;Z1WLs^|#Pi{&kp5G;Eb7}b z$Y75sZ}9>cl$+uzy|pPS%!!izQcc~89u z-Q(zv*E;o{`Uw1IaMPSS3-5uO;+&Slz98JRCdh@~1^4UMVzU(90yo8}2Hq54zXg76 z0Plg9!TtJ#S+c$90WovHC7?c)|VrO$&V|U$7OyZ zDU=I0tq%*}7s5^UE8r#YQjh=Epp(ttCdt1Z{t;PU^{Tms{fPKCTz_lrF^Dz|TU&Q9 zw~KZ*LHibyH*H8G>1s(=@b#$}%b8H* z2A_12&%5!Zp0n>FzIBr><(tGo=JH>ubW)CS(tN_b7q7|XEdE3OH)5@Q%0jeR*jm{#6?>iQ$cjI^@5PgZ4JtkW~3PTyNM;@7G+_OYZbT&2=U-P}o< zRO|VJ>`m38?fl+UY^R(@yhmw^Z%@8868L6TA ziVs=#C5F`}(O({%irwrfqxGY-!kgi%e>7$MHc~fy6Wp|h7=~{NNIwJL4L6Ogsce|v z3pdSeIq){PY5iUTU(z*Y{GMMmya4XEj*6Gx=4a^mSlfv4^@Y~>~_>{nR!1J~L>OGrk_`Pt?++lxbTH4)D_i%FA08fRRz_t>KRsSqxCdg_$e>U)q%G_7d-)*ND^(YEm#*KQuvkGcox zLR0Xlf8P-sL-5n!LH8gtXiCtS#*frflR}?`OJ8*SQ1>7?@blrO`Mv~xHatzISN9mz z@U?JL|7(V?3gF%FrSNUqzWO%eFuWRWTKmtys|;M$ZK?T5p-T8ywf*(CC-01ezw(?t z>`Oap$4(!*i@A=hc-8Hvc01y6S>sS4YFCXL^^I)48H|0BHEllM-UcMA0$Ob@y@ z(H*aK`u+$0FSscNv+!BCsgBcla61Dx_1Rqb1l&}IrSKO6cn$n1xTn9UZ|%3h_XhAD z_yM?If0Qzfz+Z;@#aZ|)d>9_p@l$K=G#*9^H>J;oKNFCDDg0shsoK82|AGHHApaKI zzTa3O{`bJUNpIpK@O$8eI{$iWzaw6L_!EZoGGEleJK)mCB2}twGp6b9he$u@L@RX> zA5WW=HefuhIV~yl`}@rI6fN+-!~Mn>@h<}|?Q0|J$jF?^6aO}|+&al#A4^%s(1v@a zVntj#<5{@SS(7fnSHVqfJ+pvwN^sMDWC1(_F8$ZBubwGaz%v7QJvOOydT~O z|Fq8kX1A`#;9UkTYm`d(FnmJR8`*z(&p4KRV>lksHK8wg?v9|8{zmzYW0u2ERme z$>Rbyk4ZEue`d}jvW|L&d&V^NJy3W7U?SB>Uj~mjQ?bJ&&1F7me(uJ5FWSqWWgHdl^$A+e6oqZAj16s{ z=1j?;|J*G3M&bX2%U(+4yUG^r=f*W@+wBm<<5hxo!*6WuLuReyn^wdMebr+uo$FeusX2 z5DzNt8-MY)413eRHP5%T@JaaDx;$a)p`4^|g&)qid6MS#_nV{qtrs4Je?oJ7x!Mkz z*ce5VgXU4K2|pYUn(%q}Q}ByC+w{C0z8wBG+%&h; z!Mm}4nofVCTc>UCA@~P1SHJPp2k(PNHCJnaQJa5CbNl(U?5A#o?;(8?i-kzNs?){& zRM{gxeyL~OC+$}JTKVUx*eYoYJrizQkTIS)KKzPR2@->fGg<$RO~o$NK7_5qPQvTq z7r{U0;noB$ydC}xxM}|Ghd%=Mi?R4x1n+{+$e!^_%GY=wOG|#lnvUZAHKmxnfxnpZ z%7*WP`{gCi(u?7Z@a@FK>7!gqIVxdO;|Y6o>O5#8d>XzPt&=uv-AG9KPWYPFIM1y4 zb#7Z3gs+E}XdZU=-Y4PL!V5I7bJIu8!aula-!cpSF5GmVQv^R7ZmOqBcs1NFc2d4Z z`27?9@sW8c6~3GF@pa|jR6W}FnPCn#htF`Es@NPQ&C-2lpXcGr0(i#RoFxh1`S2A1 zyd1s~zDmbj{f<)|JUf85!Pme|G3|qw!c8$9g;&Gkr@ON`u(@I$H&YI(z z3ts~Fi>tJ|Qg}Fk*TCN)e?C3qmQ{Vby#+oEPt#o8!}Y*N;YVnGuGN>Ne~!RkfP22P zXPu*n_YhHvZXVst|3Mc$m${hoyq~>dbh+=Ni;`~*x(m^HzO5(qwDZ~cgKddnE1IX# znC9+Yc*#G^b+{LPE!@;M=HOLuQyr$C$9ZO!N<6cq))nYpmk4QLW{dq zMk9%}l&2DVS#SEUC8Yh%U@r=PNZRj8Wl!eRzhmtYtNn^L16%k1(|S%CS*x@XL%APY z?`n(Cu9%yOJtlshlc2rItF1xXi8g*OTA{S!LowPGw-4o=&pQ5J+_PZU?XM5U8=?5v zkF9C=MKbSxCBarJ>x!SbeZK))OXsIz$7x&ko`S@#1D+1QLG!TnVu|np_!fAf=JtN4 z_)-kt1;18e+nnIb&nZ`z8?Rcl!*BE6h4}sB1npz^{RwNqAo=E(a>jGP|9u$ASN!UQ zzr=Oqk6v4HUuTCiet$B9w&H);hZF6zR~wf5u5Yuv!rpm zMQCf#o-gG&^mVtLN}Yaz@=RFuApX{%Z4K>@?GzvWpVHcP7w=i6?0FY3-zV+&KF3wx zU@x<|={adFyqNT+=g6(_r{J=#a@v9Db$vdWqN9O$le@$I-qKkXPu!q|jyI z{l;gyQFu9gwf1GRHQvhFqzn6-B)#l;R4ZTHXSVP8jlWuKmK?O-`+ksGySKv6gPX>u zUib#MDLw`8b?{1w&$RN1x=cL78RBMtE7}xYKJ^Yk6n;6}G?o^^%i(@?E%zBi_;L|E ze$I7H`4W$h`J8JTcBejIj!_?c8gAM<9EILK#=9Jqv0-jyul+l(9 zHlx@qf$xE@<=Sbt#9TiMu0bPy%aX~_Shv2RD1U0PZM>#AHuSULUNkK!3H?v~PT5}g zx8R<8OKj-hDVs<0AR5!N;Ed04Zv~hB?)a(p<@4bW!ArxfG45t|J$7ju39D>n!-^;igy?!OP*M zx~_y5!~LE+Nc}a!*TIW*8GO$EcB8u--SJwdo_!C)r5vU`n;Cco+*Hoga;qGsHkSi0 zCB2E4z@?lAYyZ@5*Hy#U!2QNb@u?a9v4Hg5@FU=+I1a-<0Dr$Y&Y{ajXNqI`C6*ti zIOf4uk=_)?GWbfkDGs&p6u4jC5}U2?S^AA%IfeJar{Gbpov}mBpL=a?NxKUqZYtki_z&Qw_{`bdls^43?)yo9 zs*bNZ!;lC6Nr3$_n{UwR)pNUA_{*gC8yB-lvw(jC@NHa23f0`qxTen_NLv`d*5S0J zi#&O``?%xqBDh~(@%CF`^~w14;vR-Q&&fKWiS(;UA73ZbC|?ZggeYmsuqk7O1) zuMW*dH1F3}JJ2_A_hP2D9Qr)_KybgYUFxEV^qa9C zmiwoARetJ%^T^?6?fVUhUkSDfmYDlZHT-h8UtW^F8D0*b)ny6K#3yCp-SF%~6V`AiPMYS7%S^ z;Hy&i`|dGFS=-?2;HLFWA6)!5)$1s{8*YmAJbdS2{;`yH-vHl7`X{-Lbf{SBJ=f1Y z%Pxm?96DbAU!bi7_*@O&62P0`*TPM8(hV;U;KT6s0el9Y6Tnk9vL_5T#WV+=4>!fM z1YQRB8`q^CtKsLsJ?k*e7v38Af^(`oimnyi+2~H>+UfIW+?xDFYl|%YOra0W#b`|J zV-$W_0H23{0dBf~%DBRcwaI=yyn^(%Y9D!EzW6R^Is8}fQ#8NcU0>J1{{wD{bsPNO zaKBhfUys7ygl~_~J|9!<(;AnOPq)9iBJFY#ZP5|tyds-uw{X9_?G zF2!~s?3tzh{Ydym_#k{U*G^jXY^MRfe)}|O74T&Wj^J?e2L;n_|v zHkYNFecB6O9>C||D*||WCF@tXY3$E~X9w^y_!_ur9IJ(Az)dl0g|CJC#Z20MCOi** zYnYggshHVqzeqjT97p?&W#+s>S8<;Y_sdJ#eiYsX_iOtFuq7GhwqF5Hg`3)bJ^Vtr zscpBzH^WVByB~fR+|;(m;7g7+x9tV^O1Po3>{C;WM zZ>f4xZM)u`LgV8}3pPsweCmOh!A)&z1imhS&%(3erna4SHElP5=fd*>?3cnm^Z`$zK@nja#G9K7G%yQBT{X(Zg?rfe80RFZ3e!bBidZAmTxEAw5XMFF~5qn0NR7OcKo#O^(Ef{ zY)KsI(y&#iY{}mHrR=?bC@pSIv@>Y8oWL4i=CbY6Zh7oyFUfCO?~sW$gM1r5zCYH& zb!4~FQg&W93s=}qina*tG}?Pa`=nQUeS)?I?S*UD|K|{F=!?ZYYd zxF&rodJXO9^!>4sWVCZiYoA}?%wzIB>J?A%rHnLV>)AIK`^UfG`Ymym_XmgF=TaG4 zIDb>LKlUZkIrYoQH(B3^tqyE0`^^5>J5sJQ6KpkM>uT3lCAKCv?2nzGZCz!pg>v}Y z47Luy|5yB~_S#C`o`f;)Z&_qwum3Fexg_uVl%Dv@JB{HTRwEEUi_vzUZEJrPtgS`c ze$IaD_k(_)pq;{vjaHfBJb0{rx^nZI|Dea~9FxQ7+w56Brk3A#pdzaGU z?^d*p_F7Hs&ZC|B!v5G-rCxvG)k@p?wAB^jV`cvr`3A?8)^i}Yj;swq>7!%tZSc=? z?Q(0QT=)XK4}KVNba?V1@pn?imqz%5mHT67i!U!JUl#l2zuo77#ntR--QfRBM&_px zY;|6}KbCz6w*IYbEuOdf4263jye2B&Ry&%vOc!sgNGraiVZXU%f9!2(BP}zYc!yg^ zbGhrwUbL;X31g^wJ~s!y2hPysmRp@MNdFS|hVT`dtM7T`!5iUzXVb*je(cx6U*I~j z{%@|Y)Hi1{!{4ySD5--6Y%L{jN9w%P8SW0a#8tFT9jWIK1MmnuU2}B?dmKKGFMiL; z;x>6OJPY@`XOprtk$xI}CfAYAd&{yRVNNK)miXdlOY*9QFJS99?W?MnX85~s)BCaA zHaC@Z82%>dz3V0G;gaM(17CrEe&byyUq^dJ`*W_H zdXe$xF{^SVzX~*KwI;}@DgvQgJ)wlH8;r(#2=h#qtoBcL7 z)xntUL!M5ro-r=i={+&DpY2NwGOy>1Hu?Ll@q`z^yWyVnstzjP5+hR`)WaWvr)dAw zv-fuRJpuXm!|UOG&y%9q9D{FzS22G%@uM9lUv5pJQijl1n8&|r-s_LT{{y~6w2S-W z_Va2Y`y%ogtdZNON<6^$!nv{b7VdGS(TTpZJ#2ut5f2W zooJgyyVG8KzLuc92W`2#_AI@TdFktkbG|jG$-R#FH4Hz7K|hi|>&BCOlYc1pI$vCB zPy6w8ZwmJM?qe;<0x@#aKRkN*9k=A`te@|Zm<*%6=%@RAzke)z27Um}BR#jRC0`t0 z?+Z_@zZ8CfC%yI3hS;x$H^YlP+}bn{-VE=B zd*(y6mhFaj!Tt8^CAN9+-S88o{ruuhH&*epR@{|^_se~SQ=SF%olp9=NAV}~ChiB} zetlQkMJMT7;qvS?@_UsZa|~-P&wfc2ww^|7icJ%I7H+!d=z<@Bmy?%UH`a4r@g*0& zioW%(`0}BDx@DJjo4g}i()Yr*!2Q~R)Z1QoCERaaAbbwK30|qoAGRK(3QzwkYeTr{o+%H0Kiscf zNcuAPJ#f=A`C9le+;7g5x?I4&KKR>QM?R8Jm+G4}(&n?VwezX{u}h`R=PRvs{<4jl ze{!+Wi*K{&dw$`cxA3%j+I#@dg*U;sp>^A#^^qS*Ukcv`H`Q$o{AIXz46w#WN#6p0 z7jC+5=z-6`Q*{3JnlZ}XM&NtlTRogUP_5cOnpOP)?f+}6N#LIPQSZa&!PDWU{!s=$ z9B$fQsD(=zuhBk+t%qI`gI0Jk=`Z$h>m%C2d*Kam)0$^5d^6nR|C#QZVGe#l08i&( zM*;j}I)An1$b*Z2-Zo&p{VD#H!FR)t)9KZF@?+%R3D1@`TdLZuj8*c!%Cqi^@?x(O zd+on8x0ylsAly{mN%&6!c;sf@d4(_2{#rw8e4i}~-U9b)bK+kSye`0gCA<>ujhEYJ z8sSgFO>Mpt-W`ztAiOmo{Um$`+;lG;Y2cfYPn*ZHEcm;mH@%Nq1WzOVd-|OH@n(rp z6`D>R&(fR^Wh~zBcfr36_p75QX@=mt;HG;$87s@sy!dP8SZQ~+ zsCH+KmAvs8ep-)}nYXYWea76+3gElp#`|A*H{3K&)WbUi?6<>r!Acpv$HA&HC&ztIpwQ%`_ve`9&Yk)0lo?D_xv}C$;?LP5xD1jjWR~x z=+32uXnu{xbXImFydUm4^P|ppG{6Vp>vS2mxn<~p?}MB6Uk2b;Jmi1>D)l}NzZLE` zSIbyb1#iZF{2a}Y8WSid=leY8XmW1j+u}p`>S@n>k(5D7@+yHZJa6`;8ouHMe_v#+ z*$mHsZ{pgiPcDUZ!7hhg;==}E?FKdud&OXL0T%t8zs-!D}_NZ{(JwJOW&I$|6KU%64N;q)5Ue5{{9cP{)*ObjU={m z;iK@U#8%pz=l)lJ|3~V24((>@x|eGwZuW182~Ynz^9uZV5C4rbF6Y5J|KQ(NBz+nD zLHN0z^wtMU#Md$M-wWR$>yT{atL!~p!zyHtHNJ{A1zQJ3_Q%-9t#xw!om9r1Afu4wxA}JSQ*?ed9k&JWUi-aA)f-I47rl70kNSR#Rn2)FhxZxZXU zf7i<^>*cSr=K&?2mFS-S0s9n!@cvcfB`@VouXC-bIfdH+?_YlSXbSf)V8s9EsUxzs z-k{+Q!`u2}JH9u1dG+{8UdCR}7zOW*disNw!zAH7gjXNR?Z50Idh`MpL)W7!cYcn2Be)M| z@ZJiped(9PF$wQK{32t1O|u1y-aucJC%lsIYQlGT^1zy$6#O{hJ%s17wR#C}CHx#+ z-u8(_euVHg!bkLQHnO<>58?X>_spwkYlU-!PZHkck>BCUCka1Hc&_*ry^-;iaL?Mi z<_lEX;ko4Fgij%#D}B9$e}eF5>+!SmKMZYz@Q)MjsbkWIT$t`>_Q7)m9*-Xik8@d+ z;4Hwi3ePCtp1$Y-3rF($7(6|PbH}ChP1wbR8`LWg#$VDHb?`L&(tkV>9i4>N5bp7f zv^k_f!kfzZ0&r9HUbxiV;3TxSwsU`hWD_2L7coMt44z9(SexXJcvMyIV6x(MGvxTnw4_K^({-a)vZ{T@bs58;;({%?G{##y1cfoKS+2R;jMbOb_d`%;dc=3XH%*4 z6Fy6L$TNOC-W@*{34i$axyx^r@NW>FtNhB|MxRA^u0ElT@W%+x)u(h4{u{z`mCqpI zzsjS3obV;WcX`IIVR!tRCOr1XM^pWt{Ie#%B!3nOA0zy3Pq=jfpoFgy{u{zQd)$KW zO_%@Mx!?J*-1%2W_*)70%Ri|zv*3>szL{^M^iSzNkMWT^L>-ewwc!GH&>@TpeECOoC%jHiFG*3sR% zFFY@_cqISo;Q8AB=3b-fBs_Th(Nq*(7vmnQeaKw=67i@YTzqV!)|+N^-%`d~8k69C z0sdU|X^!wu6P~NSCJFx};V;$Wqn+t4Vv_o6guhY`zdPNYD+x~$p3BCF6Mh+amTO$< zCHy|ZbJdrl#P2QOuS$M&X!*eyDLWTFW_9DLzLbM?`CqN|ccV|^rHrUA_N~3l--5LS z?=E;fc4A99U4eHpwi8~hr~8I35HY34doQxBLX*tAu;*OJfJMqkoq0-as;SrU(CVZhKfFd|N@%d-r&7rz;+t@r2*#h7S|| z--KW83Ac;{$-fE0xx~n8129|S#BY}H8wlU+kx$2eiSX|e{s~X`M_u{A9`f&uWa>Mf z@Nc@|VZxvBxZLrN5Pk#Ux#HhV_$1-E+Ql&8UnAVFT}b-nr{GoXiEV*`p`ypX>*Db< z0?&LViDwE;wFQ|EoH-=k=oEOIYNmw^AMnhr3SI~6;US~aRXK=Gw9y7yn zvncwAX#|9)&6**TORok7FA=5R96|I|~78GQ;g=Fmwuyw6VG1!hH5#okI{ ztM;cPAUnZ8$(;Khuy=v&^esDsjb_b|S=-l%ciV0hnDRz5Ed5Kxds)W^PKjG(0ZY%{TTc$w1my)#6@V`&~DXa!_WqxN&F;loj$fS zuF8@mT4@-EN8*={X9k{K@Z{>xMgI~!!|)V|E`HkiJqB$E+K3R;p8o81IN;N=VxexI z&Ndd3@{GTq`8qJ2aab?=JMB@%+nnf2_0|;&DSK@coWPmM)H!zCR6TFEdS6M;6yXJg zJ7pp1IRNcAx*HMAk)E31g+2*t3?gM)a?4R?krL)l; zONm{ZGm!R}Rg4ylu0g*-Ym)fJ1?L0I(-tS)y?A!Hfw|LYF{>_=;g2!BqQ&WT`SX%9 z=^3?dQxY%nOMuk@)=h$&u2<>!k#E86K2=CMo2;ImbwXf_CvZ0@m}fKbZk+ck+rG)D zuNRo31;OilfMcN`rL?CYW=<5ehg$h+;%gi1H=E-HoA^7*-*FL-*nwO5Bf)o^0R1~5 zOeu2=tnq>dn|U*TNA14_saYY8!;?lXd`r;&t3x0x7J6lCj6Y2Jrk<3v_ATG|%e4L0 zDDTegJOkh7&T39(mn5nKH&&OZerEp%X}@PDt+fnrqz{{eHVDm`OOtw6+G3V9cq}}- z{oC@lBPZpgx7F*hM$EF9Qvp2#V55u)mg%!yA@j}np~jhgIEItx-%7(Y9yx5MBXQOl zb~=J@I8(NkS*Q5pA-0DXeu}p&dvNXEExwneVfTlyPoKJW8l=COhIbBLRfj#}+C@(E zn>|TMk8D)!!Utr$j_@0p#9jjD74n^~v$}m+vDK;jTe3~H2x2iX=D}#lgVC7>L*@fU zz*q$1B{qhXUwNxCL>tUXTB5QYEjv8{&oul=__y2q-ZGR@ikcNjI)=5k?~R7Ay(#Aw zv%H0l35=o-)8B#DXyf_VX3`lnDC;w-jBlUZV7x=V1FYj<_2tG2_p1~|&DyA02VBgI z#IrM(RO~$C{@??~gM}^1XeKo+W{pZeI*Oi_OkHW~(9?gLs`HreSlzkO-=flwDNp)) z!6^C&^S$6@^j&&AsKVUFL%B@F952L*IbO*6W6oXm=o&y*6}tY}j=L&rdTL@!H{0kb z>uz}V!e0;njW)ke*@SO7iCBq_qKDbje42Iip`+t8>sUZX_i5A-A+KupVZWh6zVq}M z&8kRzT8YRFg3$|x)a6_lmzkA0F{B>NfH44uvmUJK5jB*0M9XjW)FaWe0{<@f{rt9D zRnNY$KBNAl*dyRI=T1Y_cBjv1&fjN@fHe-*ZMm_+cd8Vfc%QL?j{WFx);aY)WAFs} zjQWqUj|n_y9QA3JcAs(eNwiL@&zMA45?wF1^GB6+LX~x^Q%#(CoNjm);a`P+AWwb{ zo$V?D&3r<3q8 z; zlR=w=Hm=bmpJt$qLF*T#8FuVuv+5@CU9g*M8vy61J=<{+pUwCrbJ*bI>BlM)s;yXf z%tNYaLBVcN-&g>d6II|!K6HaU1-3pXFktI*Xkve@uz6t)zSkJUC-uW@`}r=-evXEi z+Qo*g4i8{I-(DREvc+>iEn!5!s$){3_}R(SHB3Mmp&zB|nq!OKreQUOc(0`J+XdC( z>%qE7Km=n5jJk7@ss9j+r#Tp!J>REcL__krQ9v-n#y5X6E=W^*BGTLZx1T1%kxG_`@%P9Oy|G;_^ zWh?wyV``&WR`|C9A78&EB=uwg`RYpY3R66z@N^@eizkNYet5dzX}587 zJFd+v)g}N+HkoCu?p%ge+0^<eEHGxST%i z<*e)EkPS9ydYeKQJHk>A4o@?_y&~PeitSjoBfB2-qvHU4??T4--|waK!$}*nHGcIV z_Mh~>_33&b?Y>@pQw=KW*N zlE*f)XMtaY?6Ms3*KJj60c0A21V{Uj$DSVwArle zP*bYd0IWq?^9s5>&~MFOG-?Z%;7J{w1HTXaTLu4-gDPM3^s%C0m4==^wZ>sj#IY=S zwU$=#<)%N2Jp^VS-*!JShD<^LJpX{j}gpzEnahYDm-Q zDgyP;N})M>2zLf=72}|pW~F4h2#*ndHh;^H;PgXl*Ju%F$uR8@+7*lw#ueYO>xpJ- zew6aU`Ekp;IaIir$z!oKH&JdfR?dMt*qlsB-y>xtc~yaD+@$slIG(ZPOCN)G2wrDD zvEtp4<`q9d4UcpXf>-ec{E>C?cf#KR{|x-yd}r2|OYCk}W?!w11Zr8x)25oVHicW^ zT1bLD1@`P|!Y=+V?2XfaT~EB{pGz5m{S53t<8uqyeZfd|_;Si~i&o4Hq2QY+Ugb+n z61T~?cU@3=Gp#wOaby9$Dfli!&Z!3_S85%fEWFWCVZ!R&A#3JBv~-ouVqdSJOVTv) zJo-2IRGQA)c$$XLv%fWenxwzj3*QWUsB_aKYv6j?g>N3d18d+(ygOl@hwr6Q7N7Z6 zc3He5yDXxi;2x(eYQISSB=W~c^vt5?Abd*CLq2*&v-PyvdX)W(o`ai{?i*dwPD?QW zGKxJQx~iU!eFU%4b>qf$75z8sFYW8oHIA-B@V-d$uhB=>8?)2JO61!m|0G=l=$hZQ zwyrR|6Yws;E9L9d=W;r2r$>{tSF-4L2p$!mKYcU1Jl|4Xli9Z7cH5Hp7>^L24)1=6 zl2~?Di>@(rEx>!er2Shyy8P4b)}4NI&F)yc&X2=42j5!0OU1eP(eS-b(y`MgJ}jF0 z*{rMJcV3jXS<8?wK7c<1&ChqKBux0l{I|*>+jmL8(~*ZKhG;)L?eNIhojEpa#CIvD z;3PiEcX`)0(q*2%vt34B-(`E2 z?-GN52>$DBe%-du<-2rh;Q*#&+-_{uMcSonJS*5kWesijry>4C2>p8{r|Pk!C*7|kBvrO7i` z>wbo`qssHx8{@=r;_E8!^f;b~?=l4D9GJ>?*=}LpA56~`2J`qX)5w-zo=mZ&ox2r% zWJk4v#CH*QWIKa{_&vvv9lpZ$T`uyG&Evbw&tXq=r+pXcZp_W z!k1hFPvYHE!(kDf{Rl%Df^^gNWUhiMsA z=9mwGN%VByw6@JGy6V_O)djE8723G2(r;3~ZdsqMz33`|SC#v(zmi?PKkP(8{3cYg_X+-g7m+C1^G9>9k|e z642> zJknM>;OT?M+27`lUFF+7=YxcI7~bJ^@XC0$58g3&=lGWTZ_jn6_ZMGa*4*ne*SU$q z1F~DM$*gC$Ub|UymD+R2Hye_H66~VyF#g|>O#R4`5q*8AoOknayj+Y`0~);G0M0 z05U7Kj9>l){f^9R3T<}MU}ew_l~W|(D(6G+tG-M9xHFkLm%c^Ie?5;PLBB&g@z5=1 zENaG^%tX{|PneO*)CYNVgYzLi&`~N(#a-5!9b@Ms*?pu(4!1 z2rl~`{TICdW%Igixa4xp&WwjHd2K7eh}W`yY2lT6l-hRi7+G%$L#Qn zZLDUnslq3FO!uQ+ZJ8WFZi}HKY{j}uuB0SSz6bTPMLR*2hKZ6$d0rp1*trXfmXvIp> zlC6X`2~C|-wejkqW#YB_;Pu#edRzu=JYC0bXnWDY)+6;(&%YBk-i<=B+e!(IPEFUh zv4~}7c)}*h@i(UoB+X06FJ+|V7_>tgO>B{(MeJ{APMwfEExS)aIa95wuc?8r z?bovI#eoIutSoEo+FF*>{SGp97XG{WHqQIPy8GD5A2L3^di{NDr_H~fK6V$pcdRbnIr8`LJV~5~92=DuC-gG~7 zt=2!}>|>cWusWM<&IdSB#s|Tz8p`Nn8JATYT66cY#Xn|$6mp(EcB?HX{hO^%`lvd1 z$Kh3b?lSsVsh6F0xYPHk{+gjf#lhRtJKtqPjnw~qVZ?eoE#wej@09JKLt9Z6`F=+OJt<2K%j_O10eemxm!X@}OW(WGzf zfz}0Wt-f_Pd}HuAb;d2z9DVBy{0HDaU43i$PqCNoU0>fS<(Po~74RE;%a72yp`EAE zq-_j9D~C2JOpFO`I!l6V-BGK$u5}<7d*L5~zft)4spNMW+B7t$Z*nopIiPt>+Pa9t z8*jijfcLjDC(t;Z-RJX;PVht8WLrFR^O=vtoYQ)-(2eXczP7qV`j#=U`iHH3UB>gW zv3jay*O9wZBg*b#b>6%8XV?$OId-4VIOu!#LyYlU4zei>NbPU=GG~MfQ{ltGI@JCuRf32hOYzW1lk z#yd-Cu=ZpR+jy@Nnq%KxtG0#Ob{8}Ma`A<>+kv9p$vIltkY@A9T19Y^DtBO{j2FQz z+v%OBD6u>o*>GcxL-2+9HU1Cn5ng?5Lz)GrEE73d zW)WH(zJC%XCtn?Z$vOUMIaw+WMZaJ^2>yR|`MHY0v0Kz-5HuyiL|-kueegPKE@jZ- z&<3HgZO_)%rS{WA__K$wA;K^E(lP+X%1L5O zgHg2WEX8nT0OMi34yxj)7MATJQOyu=k!r5)TYgu zw3?Ca+O$#JjBHhNDSR+*2=okk4x;Bxx%$t|^q&bYM31HbpqsVn75==z`=_f9CqJt{ z-xNv^hsdw!5AV-^Hn&eZi7fjqeZU%6&Qxt{6uiI#>9!?#ycb%rMw32c8d@1NeIB-y z%?4^Q*X_A1f8a2@|)bsPs2+c;oQ0JxG7fYH3ZGPQG-EHgBX%o;Q;OgVZerSmd+8ngb4B8=RJsGs4(E6e2I*cU!Sq7~P zT5kre3R)&!1e)OK@#}y#lp)&-Z4g?K2F7oowo6w zmAmeTgVwbH+#?M%)=^;qYi;vpW*W*?56sc`oR?^>q6K<-Ik$dBaBIJ7u4$5s&9 zK4>v$(pKb0XtU5F8cpirK^srv$XxH zT4x5W3t9&>Q{uso$o4~P*J$m~c0m*Uw+NGee_3;lS>Iqr8q8ROV*|#`8pfThbBEmQ zBAAO{_MRwaX20BG?SroRHRs2{Tu&R16NfIF-x+Upo9PBM=vy{Z<_>68MBH6s7m+po zgEfxsSLDv4HSg(I0b>k|hCCQ+-P19)g*izu#8xx5KdkDw*Z^X$ahry6Jgku(KM$Vn z73SyQKR;JHWz8yhopzZ7O92e1Z z0nH+|Y~Ddz-}7vJDi7HUlWFrxTK2-*<)4;D=j?)Gt4kX`X!Dz?CbxNR_O0uYz-RFcRjj*}x@FEn36_*k zw;i{vF`RQAT=~RSpcA{9MDn?q2?9xf+6Q1=A;-NW(!T5A?}5K5cbp`BM2H&;^V}J; zfcywpynccYJeo6o8PXZ`1h|%rmp7OH%;X2HEMQ)J1tl?WZ4+h z{I|)_uo$x$*trKs%4`-LQ|LI))*&L1np`m+*89-G~it7xLQH=L5B z7do++a~2c)F?7vqV&AY;tm~{}-Nd~e zye06QIdz}7pY&Z#`_Zv-nst=@k^5uN(U-ftPwEaYDd!<{7_UG5cWz0!B+*rbuG3jA ziO1N_b{cg^pEHGyFglzy61~1&x50KT`4adO>rv~9v)iIKbXS|ypB{A7qvJl&=Qp-9 z4&LYOHP+OjkAuvtTYm!I&+kF>CD8YpJo;{P^sTe!h@PnpyiE)(_Q1n1tj7BID)tLH z|2>aRYaYm2EWi@=v+HI1f^EdP5rfsTnfIY%FFG9mOWDjmcRW@ShedcN*TEZy*Z4F0 zJ>ZpjZYdwVPBFJ_8T;0RX2uBX8QRp^b30hGU^zD7&LH#1+my5CnVQmP?4@3hAh(Dd z?p0PCuot)`f&

Q{LeSsP^wmr&soYR4+929;&NDRF#GEqegwyLN@Bp>o+uDK58D1# zT-iVyA2p_}!yFLM4Yi_1DPZvhUbyY!b5x4jO+8*AOs*`7uT zJUv=g5kb;S4%?X%E7Abx0L(#&+m5H8teX=ltH$oa@lT#NVzH|Fpiqq19#^hLs`rKl zK}RW*LrZV}1c?hD#wshSqb{P!MorsO=HyQ_Q&HFU`r(_?v0kt`V#H6C3}#4Vuo0wn z-fNNMDw1T)Os#p8^0S?bo`4bt6<{KB+N%dZv15}^Y&a5^c_?<1@;OL~tzYX0&tCErD!bI|@GubiYe4L_bi5wx;F92BcBpE0A1DupEU>|@tcH}s5As{#m z}1Ji zHbDL=jYk1tY-1RldzCXyId>?hR5`cM0h$uHJrtVj03O*%FkTI?r2CNNImoBYruUXd8|E?7yRx$1+uSsGpAh;*PO1ic~4h_E8(o@-j7ja^^7&j z^4N_SjmnJXj1V=N=y+O>Hi@Z$CQZ-)kTC;_mWJH<&?sciy;zMCY37r6Dk#Ig*t-c5 zRrOTs)|Gm;x^d@T>OvY~Xm1$eoDwL@t-uR@mB2;_Y!oUyeN(7Q}6&?D?V#2-0`e$Ut$qsV; z1>oe)A|JN{{7!*e0cLcejQnteK&s16L;fb3-RlZ&tTvf-vG#G+J3G(7Bc-iuxqd)w(g9)$cPyY*wVdLM1 zkA(c!yTdp7!{4{VD~rW6iZ}9duebIraHt->C+N0h_DVRy)E=_TN+q>&etW7 z?a#Gkop7W%u8-3@YMRgBi@n3c_lnS5Q!dE_Ynmxlka~zE6J(qRFH$q*NEs$oRG3AJ zvI$^HRD=)lDS%HO`dCrq!-^*p>LM$sAP*?j)CU;yM0`w}29@#h@m!ez37$NNK(m`h z@s`cr0+$_9?c4Z5jmV0_(^E0hX(JN${JP=U_>8OM0 zLck5Q7dG!8CL)YvfGliAs)fxEBt`=bLglqjiSikYv3#T~YzAU_I#Mre5N$A;XOLRZ z42v2|K9K40FfM3b1`J%okk1I_gUEyMJtE!?nd4&w7dDw{n*74#(`3>!|2s~T!;@+w ziZr~$b1!a$LfL9@!}V7y3@3fA=i-L#%GHg~jofN2F4k9*{1~$ZW1o z7~Dn%9I^%iYxGe&$@28%`mJwv?}Z;;i%>a~??t6JvcA0$0j!UmQbo|4zhq{98xl)G zU>H$WRMUc6VL^okx`qt|x0r(-+|l}bEZulaO(U&H5=aCn8MuW|K9*C}v0ZEFt{NEW z&H$~?2o=`?qTbxLSjAzjH-}{v(1CT!L$c9&I~&jx5KRGwXd}F^0^ddIdjYySKl@a* z3rJ+=jprfkL@0}u2q?!!)L8*AzFaKO0F+e`z(;+QQfwTU>zWi*HWsTlidRIQTE;@4 zE2hCIMp;vqN~vIjjFf#~p0H{6-m2F7kDssOS3`U&cFHoMRD4_P@f@u@M>D7FmM9F$ zIa>HVJPF4;`9#Jwp^_6K(FV&d5bbti4LgCEbQ4rASp>#jL?Z6}2$j@Z{w`TVz2*qj44qv z1&AiDy2k*!IdqbmL#d9%GOfJ_+kl!pc>t?zZruU;&P4ClkL-FPakZTebYP?4)i!G8 z(u=f@8l&G4G18u5WF%muY>#~MnGYg!wVfY-RDI;T^dpuS8S%BOwr>%kfCTv-{RrfB z;%d7t2?7BfGmpDkTPUjrd!ivrD_vx2Bu$V~T0n+@L7gS|Ll6cI)$&QT_KIrxnracx z5_}pdwu{;0UqK%1ZTL1hRBWIpAUrKX8t!7{x#x-BSTBk{cxso7I3^SG@uOWgNR(ZK zH;hU+URfgjXDfF@$oMYY5;Gd$4A$|$j(K52fIsz=dEqetzdBvOOn}?Y;JmOgAUF); zyzmIPT>Bpi7i<4CIBEba&puPF{mT|$?LYbsto@mTxpa}N{RbY>BGj8PaEBGZSZ~SZ z6oC9y8a)AFD$6i9Co8ADa#|}VS2<1S08L}KUn?{X0lsmjsslj&5Ft~8(i>%J{2#b# z6+0Xrmkg0*)JXYI&6;vCYx;Sm%$mM65@$`8uAnc6Jgmiv)V4A<8Ts+dFV(WGh#zyl z*vQtPx#V*yP}_p2 z^j^p?Sr{%ZK*DnTNu&*HAwl6{n*YDt}nrM(j1(WO`)|+N9*yGVCGT=zeD!}REV#4W(dZWoi zq*=@u$T*5ud2dkw@y}P${Yt6=CjgBjTyA5Ku~dp(i?M9Y(jWHVIAM7OY8QNG(M9h$ zUG!YQSYh<2maL2Z18B@aKk-_JEikH?R|~j_;2Z(h0z_*}Pw}n8Zh@D*PAl_=-{1~E z-yh!79p23!-r61B)*s%`4hNAB=1|Wm@2Upk%C9Y8G*A=Z@~-?!#$ob?-PL1Mzl0=n z`sEbJ4Dlvst>X#|*8*nPKJTrePipnWkT{|8FNXQF7G!RH|JsWMg4J9Ne)f^;}b zKegEW)B34rRMkX3^~*9;&DKvcjAQqmII zq_n*d0VR!9e{PRDEoyyskI>>3uSJ~F-S-LTF;U(4nO4pO>QUQgC~PL;;&h@`b5Bc% zU}RF8WZW~HSb=IaMA~Jozjw*vx{oypDpQN=U3jl7Q(9Q!#tQQI!F+NhpR%o3=%lK3 zee=&zI?RVMl?3~j*Y)8AeR5JK?{i(h&-z+zQ3cbq7O5<~{ZR)W6Ss2T)tAz!?iS)S z4lCf96|(b6)zwb88qF;Uiw7ycDD)Ff#rYMrR2RA(F*#K_3_O0g3?#xNR?l?5{)l~y zxi}Z)3xxfanKd==mW^|>4U!`#hA-S6yx#~NZ(Gi49=F+LMU}$JA+X4XzMXePQ ze*l9q6E=PFvy4Ut;o`^fpU#PS+}fvMzniIS+~0JpOcgdSz}Efgq*W}_W`q==pWQuJev#? z;zx_zRY<5`$7Lla2W7OshG8wLXo1Y+q~&0mlqs=%$iz_)=*F>H$kdD6b7+#`)C#<* zHZ(;@ZSW3X>|6=brh~M(h`_a9E4mbi(m$zI!F@ZfT@>`muzlV`WHnUOGQaGugkv5( zQc7x>+bj=YlO<(*BBHZ+=}^@A_g zVTJbU6#Yv$Cn6gZrjfGr z9E=EU*h11Ua4A~(olh5mT|?&7JEYHam8kJ*Xmr(F;nHo06X8CBHeRYqZ>WndpO-W= z1EKAchGrr(A2fmTi`}g~QJE*;o(eII!G6)tdHWSmE-*qmvQJDmZe1g#P}NpyU1{VPM*HNoSf?9(Dl10$|sMC1d6*hvxw z#ac?wX&L_wS>u{~%&Jfh)e8U!m4S(yFJ8GQQR~o_G4HJljYji8n_<=#jV1&2@@l_v+=I7?1*qYiXRB-5OP2%8C z%>cP*7L0z78tJmPM%V^T3rQla{WSDH;Nyl=XEwB2>u8s_$bXA1Wr~Ie4YEr&&~CbH zb2Cal6OE9G{UG4VUFzY8-3;9jEvO4QwCg&Yh_k5A(hb!)*25c#3ev(0R#BI3AY8fv{8Zzr=&F_-9*vjT(EI#)$@aFL7eU36K>J#1?u#Z?bed&i$d z6qaC*x5$btTZ2Mem05?%48@#UG86&36>YWyK9aTVvkN8Og$is{bX+NDhnH~}Vgd&5 zVDKm*^NNJv9c+d@P_!9c7ih{L@*b^U>5H-C9WK%`fRSf zU8*?jRG<=ixdMpd^Fm6%%HL9O#tPC|Zw5A3toEUv|3|tziXWue;c#<)&kY#By?8!ref5_xPd^7FILk-&( z{LBRC{4$(1M4Ri$1CsOx9bJJb5?In$a-eXC_f_)-P#d})d@SObwyH*Ugca@xuQLL| z!Jc}*fe5UaaVAc9wV{8^I1AwHi$#}z2EZmm1dIS2I+XT^a{$3%82W_K1MXJXBf7xF zgjwnzN>5Q-Qx?%&cplzx^NAjSdAxJ2-d1;`)v!UKZkfnjiNRL=Fvxl%co zDQAds2GYT+OfYn?=;oS7AQxjscX+o_$h!jM55AoNey@BxI=&}r(44TviV7GUa{=2QWa9WAMaxWbBX zL-Ds+ZZMNYelg`fgSn&9?y6%vtUL+d0LnXC6EE5_#WOK;1XCm`mgfj=wQa|jM^BZ9 zUnP9JJHXicf;2;-{yEJqA$FU6&N%42nTjJ=(lwYZa#@$Dht8wWPi0`6Sb;?#ETL-> zI8+e=Jv0l2rnGIyDTHqS!#Pb_V7#?CS^NKjH0Fx+&g!brY$8N}u))f!mAUQ<%CA z55Lk52k{R^;r#BasxDMGR{%zfUJG1ajt<)BXtCch%RyA7G>(~9d`up#b7UtV^(c~8 zfLWytEk*LRIDmMd2ZX4F1QVpA^+V=|FF6FQXI>w*4{oDtHAIA}o6S9!s!5WF)(mpi z4L88XzPhJYnN7l-8<u2*PPyC>5FCb4F1MsRzS1}juG;%jKA6%MEiq!22;|u)3V*x~Mlr=)6q}3k+2*3vy*WiQE?|VHah{H+bvR>*<}kb)qWg8pDDyeI zsA=``%guHlJAE5dM{Z-o_^!>)?SI1iEvK?J*{lUu4XwF6V}zKwxR)wMymJQkIS8oxY+T{kiFw=<+>ix?I) zUR2So26_}oqV?WIOoZKoFnf}D=}Js8>%F8x#z+!vNQihHCKC3{`Qn)g}w0M(}X(*E_BwQgXT63dJ!2nJX10wf&krxZsO zQkmZF8|H9pC%xwU8lrZrIzxRH9~(7#y0U$;9=I)PJWH~IH+KFYR|;TRV9e59@zX?> zPr@gE$ex?%d8B5-<_xl2tTcyfN&d|EMPy#(!OJuxz~Zf=7`to(^Xc%c(?4o0s*j}c z-|>&Db7)|(SWlI$o<}m^EBuQZ&5?iEQr7~E)i%!oo@j$QENax)^JMeTYcDP79+Fs! z(BFA7YCwE5m~iwn4vW@UlnJk@n?aiuK%r>U_$!At6Y7#SVfcVHk>@3|8xd2}rs_x1 zW-AX7Sye7>9yPv%heh44z!1Uq2DS(5f7fPtWGfY)@TG&xGuWB~-vUMb!#Y}hH!j7C z8I>pmf0f2^LX}3jau(4^X2$#NT0JNE9rGd1NstGt9EwLE$fOtjubS~h9#K{&Si(dJ zbU;4iaHI5!Yrd8Mcnd1H{ zIm!x*o!4!1d>ju0SZcHXq|Nb)LT1wsq+fS6GjQ79C#kzzjsmKaLW zqz1%)+4yKKf8UX({mjC5oG-7nQRWXc5wzj<-2=2XHeVsuMydy)hITczvP)_)yz|vW zYhxGN+W5;~+}hZ)JLhbyJjf|$9GZZhZfj$Xj^XHEB}TBdaq|m7*2Yh4-vn#p4`^A; z<%6w_Dd+UoZP9ZF)F~e~4{>7>vLi(Wdr_io{};8Mh-2W^4XiK5k(w`z%J{b12um>DblOa?fX2 z`v*sTO^4SwBUoTOvnm-K#ISbtTh2nF(EO+CtCcx%nb0W1oTY$7rC~C|TI@qr3YXIT z6?oZ7?CX zv$$~CT+mb*(PHM|i^)WF${PWx^3x|Yrp-t&tYt3zlZLg?_c;WuXC8fxD9uF+tPN`; z%qO5p=UT@xtTh-2!`hgZT8Y&P3QjSst$)M8RZAJx(r|HwSr7j#O>>}OEfuZIn>3Qz z&_;X!$%IIbUCsaDvZ1xbIl#6`YMlTueY{AmHUI}Huob{JCr}o500f6&l*P^Hj;}PD z!0jjkpnQ%N!Z|mK-t`_7g+EBd84h?Cz{75pY^DJGvQ)q_C&FzSOm0KVpQTubHndiN z!8#8ik(YH2(uTH)GX>qj*KiiGz&Op1Q`^w^+7TlBffHJ`4UKoDo6nR>$F6BE5g?iH z{gkZ&xB_`z!O;pqw*wtuBs_Adi(X`BX2f?5^El`+a$gI!D&E_zi1>pdaz{Gn zM)Op-l+woLeKgmV%oXB;4L*dhj6yNv9Kie`E7>C?XIP}4Ua}HVZ(u_ytK^vHIf91x z&~{B_>g?ylJIjf8o{AU2&TnL>w+cBibDWsXt(e>ZZq$~5*xps%37WB;%?9?a!ji|C zqMgsJPtsY7k3r%)?^cnHY>hsE%s?aKCi)>t8ZOboy$mZHdQAD1v5e_amFSBPZOh;- z+UtYk5hG??flvN`(Wc9U&DqknrH*Ov{qCfS^3YbmHg`D#wYCE0K@5Z!@KOt}5ik?} zc%K1TSw=uI%@Q#J_6C}0gEW>3{rnEU5%4QdK4Ju1L1wuAPKSYOi4idV0{kIcD}Y6@ z==m|HNp9Rl7VQNeuxP;y$?sak)GT_AbemiRn|%*=u~}o?6twU0hf-E&VsP5gfOk$O zhSD5mOf@#)lRubM<&Hss@w@O3c0zv3fq$bq2&GvrZC)bF4e~@?!{RFL{Nh=O>fyRJ zp2*KSkzcSP3**g@05YB`22Xpd;;caxidCpNl48eWAvX#b4LI-zV;_2Je zP-bZ`XXD#aidY)V8-ez(rosGhl2ebrrUo;N8puhOAPwf=|L#WpiKPygP<3`azAY|s ztIiI`Oo9sxsLl$O|94eqzc)jF!oapq)!DQ6??ZLg9XCDdy}TH^8z1H}x<{`ddgTbo_z@zV!)l(yY^X?Kb3*fucxL!LJ5FCbay>=vA>dp>_ z3*A{d9IZPmC{nt!E3by`tmr=I&X|Mw1h!rvn{msUhek3+%oqmnrsFa(XMLr*aDD0NaUh`2*Mv;4XzY&+$E8gXZqv+#Apn6lPx{FcP(Q zpl5MV)9bhlz!(u51CMvL;Zd0V@`7Ho)qatHZw{;1d zC-6wQ;-zG)sPXL*RSMUt`XhMRtJ($r@WlNUg_y-Q#05z&tKj@w`zX+v=DQ z>kRJo4wV=zTwhk$$s$lvi}fq%eN=0n&C3vdgXvYp|g?FOCjk1VE!cgAAvB} z?i!;Et&K8E+ABzo%E`49O~6@koD!6ktz2CpKCjRxYTV8_ncnmL(M>3Wt)SY_kW(XL zI3q-ji*-D`f%Zmt^@dkDR-!T?JN>i{_&5^{k##TB9R;Xo@mN_) zc8D5%5f?i`iNHMmd#)vWzy|_m2U`aXhck9^La#fwcN@nc5S~g?t>uC!?#x?d-@BvX z&_!$(HGX={$>MFi4`wT%8o)?`Ssw+4vwxS%CbNSeQwwwRB>llPn|T60u+)-up0zx) zbY;hJEov?9EKd&adToE+IB60QdU|co?Px)3`_JL8my_1wo=v0{_g4cC9@~>L=oMq) z9^dMC2gA~>)mkLW`^jwLnYTDp(R+Na2R%03B=o>j9sj`LI*T3;;m)aOy_ewwdJN;J zkKELnQ%EvjsC_rWqsCNMx=WGHi5fFsh4JB_m!~)r3A*uzV~>O?jZ>A=l}@sKy-lEX zMgMAOHhn5#U+-`b;(vNyZw2Zq4F9M1^$xg8ZiToh5DU7-{`U0#`Kx*KpxqF2KL1TS zx4Cv2s#)Ct?-CTdAe;+LAkH`+pk}c>T?BR#6$19HLf*8$L5U|S9lGE<2jA9mvVdwk z=UyIKQG27JuTcykmia<=3e{|x>rS-6ykjkyuCC8pNzsaTz;yg<(J`xu53 zC!M{=!XeEH(oRMZORf(Jl|$pLl7`5s|3r*@9R+oVlDa(zndjQu*@}nNErEE zI?cXL6X-vrb?U7dqKGbfZ+~Hv0sI0x9Ao8<&O<#@ZG2no;np)fbEBI6L(jDJr32G5 z^-q2wL~k-vzy%8^M3J7ps0$&AAXDzH$H|n^GZleVtlK;a7!%zVm#6AN+a2N(XQ+?%RD5sWkQkApk1&OkY4zT?Kmp_2p z0WML9w>rK*Xwb~V%Ph`HjjMLi!NN+f-f$B`Gw%z{lvs;v5NnxU!9xP}k!)ap9R-%w zI;bgtF?0I@d3aY0mJTY)(T^*1blU$4WlS*;%Fz}mq;^s|D*@X-TAZ;jq zIR1k%2P9mmeE)Q60MO;MGRneSXSPcj^&t=d(IA#Q07pL?2g~%rL@5TJV;BV4(Z{L+ z$76f8egu>3N28Tk)E}owQT$KmX$bET>uzVtua3tRaYX7`QU?` z#bX8iq5#QO(2pzpr$4XoyH?OA!OLDjclU?4afcu758wNoEB$ZyNLZnN=MMkgAO5Kw zj#fOF&0Y6$%tsHPF6$1?2NoEg1DCf41nIIYCjI7CP>a2Sr0Xz~>``aquek}jtZZ}^ zp_--3>NMS}%i7QLP*hi?k-X*u*E$QXdgdwWM6`QzSC%>G5SfpLu{a6iwn8R797%=0 zCgM~nJa!WoJRFr(rE%gsh#`-k{{!zwa*-?(teEi!Qgi?!2&_E-XFnm5@OOZ51?~cP z_)`>$)zGLEy1&7P3ap>u>IacR=PGG?Uw;f{F=GT{D5RG<;81|Wfe8^V26*>e0S7q| z&ex#TH~b2$XE}ar1=b@R+ZPzuAd#2U2dTj7uW?d=b%w&3<;STP3tysE$n=9}Tna3$ zlp6P}kL5?g%kEPB{o#cN6W+|9zOFlc*dM+d#kBL^i;sjZx!De{G=6^?Gy}H;Y^v&T zt<%Ap14aYiQ8tXX}^7r*leV9Kr}uW3S5H(w(dq zzS3RE-j!lL(pYv@Wtq3(Hge9V(#%qL5z0^-H!K7X0Rh%g(6A-k_cR)3$1VLxjYV}4 zt*RLLk7NE248ujU@!?!7CidLxbYSYSrlIYA06SL|plRk^Zt1a}KwRieSYh+hPpLP# z8$J*&t%wqBjj=+ecUyN*k97kA;YqbqZjwXmPjAze(^Ya5S{+?^{fY|)?4hVPj2LJH zzd{QeC(=2j7gwMAqF4jPAe!8`?Q6ex|O9dD~Vtk@CR% zdQUkd_zD*hMC)b12PAl!!#h-0OsA>vHzDxWClO#N?BskpJS-|c0u)Rodr-g=KRzc~ zEVd(j>EL|&{x@0Rd^$?OU!}2u5FW6jlT3j%1PVq`U=5x5|33xRePjQc3am((+=JYd zQ{EiX8g8z3MSX$QYCF+JU}b_narGri22zQ2BEB!ix3yN4)2faVYXJ1VUL{sf_?XT1 z2zT@V;-;ba(TqgRRa4&9sLvPeC5wteEL^$+u!Mt=xBnqY+d+Pv^8|ZUxb$cQTSbOg zN=LB@@f~3mki*$l(c`P&!4)r_Pg%AdeEaKqOr7q>2eb+#bK^XYbJLgVh$wY z_nXn`#99jCU>M^vx4o!w+Ea~lqE?{sf;7>SiF%M)B+$)P0Vb=wQUNB0?xVK60T&u4 ze{)*xfJ?gfRhdjwCP@vb0!00w1#Bw!H#Y@!dT1>mZoK$k)dF%w%;v_3Ob551aM;fT zBiUWcTsBqsw}tts0$QR2H5}}8DBg^7D88)@m8lWN-x7Z0T`^FjrfEfBT`wnRDn($p zY?{hadM}C~Zq*2~naqXE=YGR*u$06L!jQjIZFN0?32;$|)hmlTQ4?tupqhj3A)+hH z$*DR99N8+x?1gV^_+&3oj}T7M+*((-wJy1}zUJ0k&>EP~Gyas~@vDoRw)$%-9i{-f%(d?~ zfZ#BUOW;r8Qt!A5F7%G?!qIxi4SFR!H3GfkhB?qXG6(Y?JggNn8X;o(d7^hr1-Jva z;hO^RwAYzUEkJM>2EF5+hs4>XoS&4#!>$PXRyiB!0L6N^`~mzN;6z{pxW@7QSc8?u zRfOc;_;RLLQiKwl)vm(Xj7wooch=s#xatL>v@W-&)GcBXY9$9qM6XuTUX3MFTMoxW z{eB?W%g4|jBr5#OEm-|ndPa1W*idv8tPa-r)~T{6^#vsM-7 zK}~A!_WO{tJ5@&9Q8oq%5_O~75F={*7{`mj>Y234(wwJIMsA~@OBX+Y^Ax1sb>oNc zUAF{J^{$)O6WU0=>qfME*NuUE*G*jKT{i|-lXu-%jugD>CT@6=-1ZgKCwWVA<{&hI z1jn+5L3^M#=jHM!s2B&n4qcQN9CGy$1ZSkd@Go^S+A@rf_w-A(dObsnC( z1l?&kTA0i}9CfA}8r|9g!{eHUm#EOltjh81ftZjPAJ0b5tw@<{ybGYJ#-byTsH!`f zZVmvRB%te7GuLI=Y&G-gn8LZ$%=b>P)XWo>vm*y5eQ-{+l4+VN5LXG8v(OzZ#frKERBNGgkWqq4>M(fODyuAicujZs=2^b<@5kbALK)suE>fGVgjyEBP=u zWuXXqUCcWSAb-OPi*QGy00oD%#cK%_m``VsvJ*GZzL{QCSIQqBN{J1BtN>D~(ljLM z(1{zWVK6#WyfA}HVFc{d<3J!^Iub5obRt#rM8cPjl;)09-4h94I#Px^QmQ8szI3E) zcO=6T312!=fjiP6o=EtTNXL#xleweS@I=FxipFu#9ZlNFZU(NK*r>;b(2VYAH9gqy zrK3S5>W)^+6AfQFTADXnZBI0O>1Y|=Xz8A4_|nm`z0vA;qTx$NEAU1;)DsO~IvN_z zU4^hG8oom4Nm;z38Z8$>|GlDASu8u0Do6tCx8u?if=x^DU;X^kzxSwL!Dk5 z>~bU$U$?9WbK9M8d^l=crN|+Mo5g1#7u#?X`w62_nQT?FhoUU0oNEDPYSqPNHg1#vCb_Vf)}6!AF5}TlstV9Z z@1HG=gk8!tklL~f-2Ns_3qRk*de=FN#9;BXdNC^Z-mXC)GXM#&-_d&{J8B%Q2q#8%yna&HoQ4n@3G#xNz?(` zOLE1Y(MY!5mSmufp9dzkaeOLi7Be2k_jmv3K}H?~76V(3!adt}IxSugR|7=rO@t3x zd|h9SUbpyBaxwLA1PaZLRv19D^IRA{!c7FY=SX3=KLNw1!X`NgbZAD+0c(m9I*o4D zr?CxaRSicV)6-^VeNSN&*hFjI9Np6Y@MLJM0m1U9}G$W}=E|`FQrF20AJl2)X6R)`l zxNCX>0l^l#$rfN1XFG;`;5_xo-~;|DjgtuBWeDXQubigJX+S5L0dVk<+5k9Yw9Kg+ zA;V1Kj9-ZkEZyjT^=9fAN{N>6-zS}l9g<4}LqH4nyN34;{=YH+9xC&ks$-QCypesJ zZzH=}nb2xsQOTTx>*Hy_h3TqM$P9ysvVh(^ihy^Hi0@|R_F@UhFbhipW6%cHC`E^= zkxF?fR+!WRTw!G%uSpsIFHxZG#iT%Z(#y$c35xCS9KrR0MUaGbT|o(VgX2v>icKH) zlpVNRcJR$G;+MRugJpq^;K0USns z)}uXTFpx)Y;CF-yZ^;z?yRLzRHx9oYMu^(i5X9A{9=A$1pTqYiE&;#*oG`KY<9_P+e9d{7p zscbPQJ|+l@Iv^ot?Zga}ZMCFErExUs26X;1FiPhXM%gt9QDDDrE%xiyuwS>)_ReEr z?+iSD5uWrJ$_{4EMGyZoXD~kP=8)&FX$q}}8vNgxLhmbZ*qx@(+wpC&yW13cTtw;p zUS1;Qb#< zHhlpu0EpW?0Kw47FgWKbr?+x?DyKj>Co88t9bn_ zntfq}wB`YPwCB$r$Eb-$wscj0a4xXGI274=H8Ga;vXC=?snCR|;}~orj*fl%fF0@0 zkGbdS;}|bvdtxN2?jAwk7=W~)IQJfdq={!7YGcZ*jFZY*XkotPGMBZG&r<@?AUHud zVwm(f2F}K+7{22e6Ohgc1Kr^l`NPk!!@(p6W6kQ`L)C=} z#S;Oe-Fg9+myLtYR9Kug{Txuv;^B=$$x3ymu1K^}Eds|&ud}RF-(7qFRw~EXlnYX) zlhkIf0xp!)QYh1m<9<#@8Q2gJ;wk7a=C#|YiD1t{dr0?+SI3>Xy`TcX@~nZm3z|o+ z)3A(c5Gu(uzXpdncxn^RYxsv?yh2%P(VO&`i+|?k5l;3uaf;OdbCZU}S96^fG8^Jv z4_Wa2emMajPc<{ENk(|t?K}l|%mzrI7knzzx8TG5DDo0!Hp`uHLk%fd)!{6r{bgN& zqHc)EL&J&E5CsgAd1rSQf{Oz3n|x5(R_gw=4#X=nMl(XxxK_v0O5I^>)gM(WiNdsn z>zd82yyy@4U{;E!1#2*?l&a&<@@er_Nau=aKt*a%k5vtGe`gpoS$RSiWffg9HJzDg z?U4E6HnlTO?z9$yn)kwsP{Q>V+~3FL3Kg8tasre4e$RB?mT8r+n6~LOOKUut(>}=G zrm{ExrZLbZrm@j@F2MW)M=q`MQbqg$g7;vYsXC8kl!?Ci$5K_GT=bn;9c3j14P;xy zg!aoImUEt>_Nx(m&^a=h9|{2Nfow`0jMH~zMl}SoRG7OaeaUX7&L}|x*)(b_#}y7% zW}BXLDX>oBZ4pWttzM|h13j?sBk({#XT76dY1lTfQ6B0n^>-^8dqXek-iS|y9XHp9 zN-hA~%sA1_Qje@9OO>k4_jWwXPC!IaW3Zh9+ivRo)|IWJQ>X^&gs}ll`^}AP+HmQ~ zv{aGjaGzW9*Ak5>PsF!*$UuI#(1`rm68$eWnc$MU7D%5PuH1-JD z03#%&50*#XdqJOvVHWpFo)n}8Zr_R9N{xp`tA^~zhP-a5zaeuH8j|0tA>Tk!-8z3C zU^ir*Q(Y(ObSLT!DynYC(Gs8<(uqFQiQdb>+%^dFNlw%(59WpzW;7%*vmsRuY{-xb zHP`g_Hzc>sd)tv0hM-?{aN3cLqK^1%?uZ^{adUA#a6j12;(G9~apEcD;VJGTC!+?j zwJf%dnU8;p9byeG1$xBq2PaV@-}PjhE|^4$M*brdz+9Ox{vv|4MxG-A$l3r{Fo4J* znOqhYKXVA|RqTNDh#C*wAYy`s4fD-MDU+h`L9Z+AOh-l2V(Fjqz~&VQj~bV%bRx?p zF`aQ9d@uv*EH6u{?SIZ{h{^gQ0#s!BB;Z@qz>a%DaqnX|pr zeK;|*`+c}(e=h%xnJrccA_Rv>MKIi`Dpld_S0~L6_wOTSTX)RoaL^Yt48~bQBgc6p zw%%J9mUff$kot)h3ONs&7Bj9xP57%crVy%>Yg9su$HPmJvI46$a}op&HmZWqh>=PM zV^dl(!^KnTNJ>L|62nePXf^So{M+@Z_w=i2=K&HZ4ySf0r zbx|7P<|9peWt$kW5~C$P2XLM|z-yb>LY;{!xj$ph)Q|!ui=;6!RSadx7+_g40Ei`H z4H_7Os8}-Krz{z;6vfOEypNR>Ye8n&GFCw!Jj(_wPjOmv{E^+EQj`N(?ZnD~<9CHQ z{cJ18buKH%h_|}+=__}8l7TR}5VSDSkhl>LhQn0vXuamIVU3Nz2$bgG!tjC>*2kgv zsIWfjgcq0=oE~1V%Yti%7i_iQTHyt2EVw2TZ?Hbn@S#Iwk*Kp+SdbcCh$c$EyYKTMW>_mRW$W+>uiCGn>(}pEN*_dtHsTo zgqu5&n;n~7)WyyJV>UbMgkhGltu+KwfwbAEHMvbK=Lh!{4r*nVDByU=-8Y&!a+sF9 zdHA;EaJFTo>kF#8EoNFAhf7aH0QeDBx(PoE?l$rjuf+sty4Lmy!Eos|6h--YF9M8? zA5iy7Om+1=b&|>(BeGxH98s zEnk%%Xz2S2rA=b!yB9&iz!PEUgB*d}h34r%h&%B-P25=uAaTDu)=S(E@a-dRjby|% zQ3FNX@0YlVOC>}iaUZk&yrhec&xchO>zG@DNWXu=&f0Agwz&H~i7E%L6D_maXuEH6 zV_wR%_nByOC!OPz_z|&#Pni%>9?6W5Kmpo`4c1$`MRdVz z-n;J_S-E4RqTMx&Z;OB3cGu@ypwFS(!0uXn*?-sWdS9g)2KQ-q?bUG~cGvYsI+}nm zSzMWkvHiZP04n5v&)s*2qL}3IKWTS8vpE*YXkcx3E&H`>E4#s>;g};W=M=so5?)f6 zv)ng-SQLrEMu83k6&b`>A9SB+k@#TxRRrGYld}PO`fTDbli~<3>4O|nR^jgV$kL6e zk(9S1)scH7S}RhP7Kxq?%n`ak9LazSyphcC!gGPPC|j^1bw#9XS!C%~NWGFnK2oz- z+ylf?m7#b5)&LNn4FG_mPmW0(6veqBip#c@tz@lJhnJ=1n9(hAoSmgVnxsn|-U$k~ zsb^`CibxoS!V6P#CRU^nZpc>3`v2H_6F9ww?EnAiq_4E-=ne^uMx#lGMk7WuK_lqQ z#7qz)h9TC85d_`#C6NwkkC3s(o-y`iEHfg4B#7?VV;N!?V!u64n2ZTRLjLd1sk-+* zTL<6u|9!oF{YsuXx0X{?r%qL!I(4dQ^6(P5>+bmEIeWT+$I4h;P{uNdr%{i|*=SAntlLIz=p7OO}dk*j_2P*Wg<>vb|p#F&a zqz5~KyN|##>k#l1DYjNLFc@_PgEkwOvhPo@JvKoE^0`eC+w&C(B~oZ0wt@G*_%!rb zvTaVsPmDYwsRI$9j*ZxRC6P=IcA*}*8?li+fjbTT!r|1ed2)OjTCE{Q`EENZC~tl2 zyKS-4&{pv;xBl^`p|3^uPmBeYY{OTyDbd|&=u624CFS*MoFf+iO*4ow4(9c{3426n z^G`#6KFHO@pN5XAcq5vm;-{gzb|FD*n$X*NXqP(;z0E`MY3SmmcwA|9x#h}^08fFs z|NlKq{j_N7xGFhFoI~mbJ6k0Suf?359T5D!+W0a5F!i-AlBm=k9IrT&lhe=#zz#qB zG_-h7)}y@+^QWP|<1{Tos5aYIdK!8al_BD~iTS6YzuYr27Ku(nn>OWpUrK4**mXcz zLev9Ovd1Y|ZU-!Ot~cVz3pK9L?U-LX!#8%*NA|hid0WXRI@h~{@2mSMQM%8;x93|- zG!el@rO0C9A^f7}8v!KusA3QeHvo6-C=V^Jf0R|Hr zq5(8RhU1kWHeEPOu`5p<;bOCs<=5tjyj!QjE7^Hc8EVq~2UpQnl%&QTGg^+d2WyS3 z!(Z&3?2fGtvaOXhtNc_ZvWl?vq7zcUjvheWB^X@e+FpZi129#8;y3wi9}T|RW(n7_ zoX}`)VL*XK(_0Ve9K9dsf)$5wPp}QVk3gPC>Eh1G&voTkM3g+sqBrr1EsN$BhClFQ z!mlVyKR!GC*@fZ9W`~a{3_mCir#+nI5rkbX!s3x^K|#`42b)St=MH<3>X*xM&K;K4 zDh*BDOD*#GhDHf9Q`u!Lnj$t+`T0zGOndOMBJhrikC$zx(#!||d2Nq$K$h`I4_x@)-m1H($sO;LB2F;4L?nlXLS~e=ZkUyBIR5}5b0>Y}7%rK=oTyc}*%Chj= z7o$Gn>|lJ6bQvIw@dFnM!u0@=OOGZNRxaMb^l& zwVhad@E~o>-or2F^49DutyPaBN#Bhy76g@X~D#wB% zI;C|d&nu<-ABYb_(pWO}z1_sm2HOzcN%@xQwy7eA8+TR`%0nfC_I}xocGV1Pv}(f{ z^!M>Rg`@{7LgI&B@Fc$e#)!n%;^l^+91=gHx_=LCCv(KHokao(OH*b6R2o?TU9f%@ zdG9sy?mtrG)%jMcW9LSVzNF{eXt;YWWp{@r=ky%HN)#r)s((b;3Q|Xu{pAEv_FFqJ z+Gj2D%ckt>c5ZYbf%F)EZj_}|ku!*w-QX#q%>bEN&Cu!44Da0BOzOx2=>7AF1uBFq zt~ox~sF-^#=*p~se)7EXX!Gan77EAJRaW62ZUuDl8rhA1&2%-sH-3ohCZbb~J+VfB zU49*>Kv?OsWIa(RGM6y++y19!1#}kmq;ESbpjUT|%k=}SfX);3-GuSs_L_COw*nfG zM190XWgV{fhJR`S`Bp%iCebfSFc-A~`sP=0Ar8yI{GJ842W1PbfSz)p;d)9Fi$33D z1+>bV@I=A=tXrW;fls#sqX=nMKx2?C{Dc$}vX)+{zsQ_Q-_8o?CrKTylX&h3S=0(> zwIu3T7u6H;^8-YOd@CS3-|L!aw*+%hE1(Aqf!)xwRu1N=5$2*+Kxewp@D;6*@(9_T z70|4{2^~cgX9e_efBH$p&1MC3RYk=0@Nm$uj(9l73h1OpQ7d9=R`h?C70_XzC;o7p zd@Gau1QrnRzN@H zUG(-~Pr}o|t}dNf0iCCG!It@_K7#vjBHurn+>?YO#02F2g?^RDvq%^$E8&f+oHGlGTmXKElaowHLGU>176I znLWcJ)=2owzZlklecQfC3!HkkS|F-ZXV@_U^0no?MlFijrBp?xwAoy-Z7rKSrJc$7 z@!?4}6_$-}qSrVs7w&X2KYeKJWKz#>=yVY_NE-UUB5aT}bWs@=9$B6!Il~@$V}$H0 ziR@MqFkEHo|6NJMrAtkW3-Mh_|L;non%ql-{v=b-<+HD)i@ zs`x0f=|a^RUFck$e_XX#;;}CA>RfQi0O8daL)f*cE}{EXSGXGoALynmnRSU-rI=MN zX2rz4(8ovmU%QXLQR;Ja=>B9lRgAXi>Q&X~yGv?fvZ*U5wNxb3xhnf|gGV-uZ3OFF zo$E70NUaNk^LJeeQ=jEhQ|U8)8CUw}RHa@!diCr(mfQW#t@n0Upv?Nju2bx~ICjOv zowMqmwUtiQOWXUI>f4sPQ7f|=-q6e%$}pYLd#<2k!7|4g5!hImW`P}6)1+0g`bL0J zkl0l$C))2q3?fENY_De1<2??aV*J*}s8bBH`LP%}B*HqcN|SZXEITnz$@aaFJ%X=X@RZo6pm#hTwmTPxlJw2M;9N`V{J(1 zXtW*Prd)o}eel#c;*|ypEuL}PyJEc9V(DJyMb*$AX{{kz*LCuNgwDdQ!GSVCVoy;i zE81F!K~WlNe&Y`UP7$qHE8%!CgWikj!jTtT8g(12EIQ^;a>;*G%{DbEbQA z<<4;CQIb)_k$k-L+eDu722TT3VZ!|ji}c)xSN^iDzXFYW-Fj1Mn!G9Nc1?AYSS4hA z11zOva=YHiZinZsO@I4!7ELuxnIPtJ>*!>C!zb#t00gjL%5g<7KKk-8Ao^I759@h~wl*IF(UDnChtE=7 zZ(E66x;5==1_DJz+Z?>XRu7Nk46|ao<>H~WrUKqvyQx(cHo3HiYS6?-`Gh&8?N5$> zU&T`an%Z9;|DHb5mE+$B<%(6Gbqv%|cgU{b=zf->yKF zPqDdw-by*5cEF_Jb~~Rc)VE^#h}tbGrVp##y#2YlSKI$KxgTRX5s70vQZUkR7>Ri% z)I770@nI>rHBOl7RFOk_JYcB#{)Q@Hkz?YeK6(LxVBHv_sx7q#wL*^ zT;{|Iwx}b+GJ;Xm*a z=gTYDiJ35m5r7u(MoL|`(KIUlce(EcxE5MmECePftC&7t_M&fdx6Kjb&vxcdt!0#L zF}RoDV}?+%&r(8`(n5<}lX8hE86MMK=@Te;iGokF7N3_FyhJt<-?2#_R8WKey;~rD z|DDgBI?5VpJl_#Lv#pV87_PlF(lJB+XRVP|z1hz?^z?2o#DApUO01EF|2y7(ZuxJs zMjH2r|CBY->{0}HcqY09LKdk#$Pq@k=cco1;oenSM_2e{AL2HpdBVAT+o z0S^J;C`@)Cx62*Z5!{UH?;@Qu((OyMaiP$xara;lBGlnyIy}`GtVP5{iqRP?qnS5e z$M7!&+y$^BC?On65QX7lVI0-m_OA?^fx#({GI zUkA)G{}@FUdVEu(5M}s5r-az0Vf_W{3+!VNdUvRtc&hU5DQj9&J8HWXhrlT?mV{Cn1gsit)1f%E{F+ozv4!XIFVyRq?F+4@8Ea| zG05o2K|^(rEHN0GJM~vO__xFX&&Z!hRG1!|P6>-M@*L2FFAR`8&PMwC26VTPeg$!n zBdSxx)Dj4CXqWM=CYN8CCcE>E?N6(3aQcJIwrckF>|(ixtLMgX1t#uGuRsMu}J(jMjP zNesc(P%B<0ya(YkU&6};&QAhoGmNCd!{D;+tV&j}zepSzIIfCgnorugTzrV zxB)%9dWtbeWq5%Dazt0QIm%QVzcX8oz~@#)HTX(W*T{O8Bf4!#fBA(IO>{eaXV~*v z2-qI9D?&Or-^cT+`u$WB)0zJ#d< zt~XP3oi%E$DDB;BD3kVIBqG{B%#emeY=Jv%`SCF0uUyg2lceSv z?Gt+;@x`62x^rnzs=I4CcpQ&tlldGL)#?6s<3pB1l$17SL^2)AWjrv`9$Z48-K9~g zwKKtfZ(9$}tZWnI9yXVL=qAd#6fPaqFR5b_Wi8;WO_VF=3(Z1xme;?wwRQFe_R2R= zo`Y2iH&Ol#n)Lej5k^Z+!^z)7Y5yk4C*DL^-(_x_b;%~mNjoOA+~!D1%8=|fhC0LX zT-5NRHc`&hJ{V1#cQXi^D7~|?dG-ipW3AK~UOJNflP~l$k29J1Y|#|Q+v||R&}0*3 zjYA7VlT8$foN-@_cs+bUdpU)L#fafIjR{TG&o1oPom@7ahq}4ioY3V@aS!hrKXpP) zM^FK@!j{%q~D| zonp28@uzIQUYyk9|K_@O2Ws#?yRKCmGqTF5aojRe+yYnJ{m+C;w937X?}$ru575p!8UT83wC3jQ~gz4v<5zc1j+{^xUOxOQN&d_HzBTt zCyKlOs+$ml%QgF<;9J=m_@RI`@VU}dj+9=l5uLEDm)qZ=F2lG>(aYZXYv55#@0`dP zl2oE21*b#IV|JuktvuHPMVW@xZ7MBn1hvh1RkY6afSV7aE7I9 zhz3W^v?%VqK(wEqc>U)d5J#h4nJFY=Rqs_Pr|Pv3B>A3beB)StrrfU-4Kqy(_ju`L zc(U|tpU;?8?zke^cjCKVRl#lWuI(-G-KcM|(Jqc%oAeFWl$)er8xJNaJnLkZj}|3d z+w7BNHr9}|OKxN6ka^kQo-G?{Oxi_Crn^WQb;e!n$XjctPIsq+DcK>IKHN(Yx(-r? zCakpZ?l92XKC!>34t_ ziSCml{SNN8yQ1I0wVcXkO*_cxcXVaZtjhb*?+A7H_M6P&oxzveamq(Ac#jb9+<}IF z0pPWOyk!G~Vn<;(e|64F&UwZ;PdVpt=R7P2Z1>9D+_2pRxVi&x2h<-CZUOvw3ybgv zz#ZxhywOMK4C-TOGY@qHn+OX3_EoONXTl;D;9djX87$e>WziXY=An)tBPhI?bj|7b z#7?iz={o#FD;NRh9^kh0nrQwrAnTox!zqQEGNl?Ai21A^cG!)jM> z{=-F5F**N190r7HpN;7ftXxMaR;)|t%V4VlMXH4Ru_}rf7c1gu)YW1x(j(k0X~om_ zCe8cPgG$<X)UrSdbn5R$=(OI6R`A-vj*KlP!lzIPr>y{Uo?d51s;9E-~}& z_*?}#S#KAc-TUn_(@UA+;ah1T(tYl10cnonp$c}jqD3cGdX{&uTZpI99l zNQ?&L=d)@VS7z7n6SlRP?!eY>+tK%@Z5I zhR0%C&Ad=A`ON0ka1f^b_zVs=@izVql&szvkJooS3ugOn?Z;cDTXE8osHcdD>vhiG z1?|q{%e9+GfEAJjE14?>tM@jzP4#IHC-queiwm|m;oMtP=;LSHBj*@e>v*uUnFQ7U zsD7dJUVM0tAxVXHx%~vvOeC)UNcIyz@X7f9M8Fyb%M7zw|IbdYL$49H)+^xCZkgNJ zju&jIrs{{{wH98p z^o*c*>oDES863&IJCyjKk4@FUv4s8bK-HjF;TqT!ru#SH0|nmv)KMT(HLNgI#U=z& z4JjC^G@vB4_-(f)^Z%?*vbb;mtfg^}`X9d9oWgqZd@|SHk6UPt<|#*$plClWG)L-b zN5AnHEi@azEV*nEjPQSDp*iLKq#pk_7n(1==UawV_y5dw4r=4#3(ei5vcM%;Xl~1Q z#3fp2>YAVLUugb0j2D`3ZvH>J(7e7)qk$7?ZSm-D6>8Ej#v0D_g~PsD*8M{BgTKb& z&;Q;+^WQwbti?}}t08{KLUY?s{yP_%TYkPw7I1C}+RZ|<>x*Ss3(Z*O(rj0$!D|-g zFe%nVt8-`EIhx_Qm7ux3hZ8lC_E2s6)$VALn4A{5ncaOXt!}HezL_cY`>eVLo%}lM z%VjKwTGzH%;H~C@iJrP(0=B5k^fL((Yl!M^C_%+lbCBZhQ&jZbEQzh8BPe zCYP2pGY@S^Rh(?|iaA|6)t8H>#^afik7u2g;b||xBg^S+DNl1g9v)ojwmg|3abeo# zoT22a<|ki&Wyym?2LZvGO$C7tq+k2IA?;5b!~G+bGWaQ<1bH-8ZEK4eXVJ)KBb5;E zu%5nmobT>hJvVASt+1|V_>oUls-*&_U#g`{FAyW<`3QFq0aZ^K0U#U%D$~o5X?^AZ zsf)@PjO$x=GZ6b(`}zqD$pZnVS*a2M8g1d^2bHhr73Rr%H7wnaDWTkMs|${c?PmKq zwd(akysh-Cl?Y%ea|Vq4pE?#%sWGeZ#YFIB^HWnKW!SQ@GuVi$BnB&>GuRmLob7EX zx*_0>I~Z6EcuJ$z!2@F~~dOL|LBwNrwFmLNW3784+P2%OQWTGXvuK5d3Sk*5JCm7J( zve0W+*X;@Ot#plk?Q$^{UEil1Wkd{rhB!sn=yMdS+co+(J-&C1-b)wYL|A4~qe%aw` z7lxO{;k5pbu?=|iT}MmV2HXb>W2eBC%h-8KbghkSfDr%n{*2ai%kj?e*DJ&TeO5Ud zq&Z9Ug>b8N$Y_Z^YB?JI(kas1I*U{WHFvQ@xgVeXU^vJ=SF{cYJKj$AIM?Y2sy1@t z$44~-Q}Y-<+}P<>_15h*PSUH&DQzljcZp3i+CSXlp=9~%?`at0W`)DU4-QMhwB(-* ze*FPnlz$BbwsCKb|Edwj2+U! z+Dh+L17GbS)j)s`=x31_9RGxbo@hTe<-*776Wkf>Ppo5@z{oXGchqUXr>vw{m`j)i zA1_-08F<=VmJ-#OP3)t!D&7AAGDru10V}tQNnELx!bg!{D3e%YhNn1nDitEB%#~VR zbt_9mF-SlDG~=XRuGlFb&vVjQME~^dENa|jw*;(9uHkPPoFh|dX?M=Ra~d_v><*#& zQ#wbe&#Dtby|}vw^)@~b>Pql}e)?-Mp*FV59Udo`YUK0_>$miSEL`Vtb;Lq3?J5hBF{t+pI~2Q&CMb3& z_5(FdunfXS_8b~FXKR5HZUUP0`tK4(b>`#b+jBgUlaIZ^aJdrxjJ=Sk0lY~ES9b>2 zf&$Vvrh`+sz#!t${dW`T54S4~`mFnwGK(r>i{IOoR&jWr}Dl@y{?Mh75 z(ZxJ7KV~B8v4|*T6j_@Nh~cGj)>mL(8#lqSZ0rRC9VV^55V~1-q9!f1owUowl%}Gc zw4I2#VqMGAuTEcw6^0Olg~QrXC=UUBW(WInJH~5kx9&!p-E8e)8^Kit8^Mu`>NX>E zi*-5WE@RmvTPfBgW0;m_{D!5#Ee}N#=qrSjuV~qo?sOv|>0mTP>&XD!9vljUK9Aqy z<{V|2eI;zVA-o)>m>uJI+0?Oz3Gw{c^A($w?5&1qeK8(XJ5x8h`uTu=-_1nt^8gRr z!@#ovuNxxyeSocI%7R9%X$o>S5LwLLHXRg2g(64sI)H2ik}9uL?NJOISPLSZ>c+ z{)o_)fa3vo+skr37jO(;B9lJt_2v+Mdi6h*nbmwZA-5 zV}sjT+w=NFIJK>{p3KaCYi%93wYCNm%IEzM3fqI*alqjXRJ$*E&SGZgW0EW+2A0dz zMT2~_uBgM)s^;WqzD(5`zIDE@-?IQ#tMJsNwvkun<{L?zWtnYESE{Nx`+(bu#OV_r z<9(IHj=_7?k4Icr+lFpRTiY9p?uWoL+#IW(-|J@?6n6liw;OtwC#Zs zg*f$!gWDh_A8wAp5#Lf#(JO@m?mQ(*VLs`m-ZY$^18HmzzFCuQrFiM49>lbRmV${f zSTRt*HJrMIplIT3AZSpo$9z&&Fl-GfG4tX~H^soCJ(MhQ`uitJSt_YnbtRJOl7@QL<$!iRSQ4OMk&S(F2=h*pj69~nsYRcg(0 z(J@ZeL{5zXW$n6GV2N#8m-3NgxBa6Q2pwD$SQKIW>i zXi2(DVX{twsUmvmUNiQf5Sdf#3t^FKpc@euD<&SrUV_tz&;#~%>S~t4*1t)i*)mUe zTrsi3n;JHIQ^V#w7Lci7!wd8?8&lzfktVDRPt@!p@37i(F#`66-1`izYLy+X^-tWD zatGY7t1&^7QW-bIK;MbR7TEmjK>4m>3q8q2m{Gybu!Z-WZF$o*j#65vW7-B|+RALE-PJKImt2ZzZH|R$Yt`(v5Wn0u zJSrysOiYWP;qM22HUG*u_=IP(IM|en8;1(Xi{$}dZ)bpOWy$gSL(hecJn zEvl*+_xFskxkXiPW$~-nQ;RADRTDgNi*+n0nNC!!*MCWxF-e-FSdS5s4t_>dMmLJp z1e6YT;@66`DZmda)+x&3hZO6T^0-*LDotClVr^>0x{s)?ShoVDgPZuZVqF68!;1Cx zFNzf_XASx|$gnDAXbENk?l9bzXO99tvaf+N06X{78u1Ar9EE8O`e(W0I)Xpp`ZZ|k z5Vr;$elKg#sz+Ia3UxT?KKfc`(1VEeiqRQ-vf4m|J;VPY;O_xDf=_{P6o&JjbKb&{ zg{k{`$vMwB=P8AO?FoJQIwatufM*@x>HzpMVEE`tcCNx3vo@tVg5L@gvi{P}WWlot z7}5N3f^tRkXfe5&6RTFb)wK2dwwj9}G{|VMjvnvw$J^Fp?D~_*|$E9{#CcVV-J0cPq@P#0A-2?=jpn|zjAstk{UPHoGBG?rY0-KpR;1vtg0B{qfg`%&N@{vitNG{ zU3|+aj!*kJ14Xh(bhMrXR$W^shVOEP-*>}anOO&Z4bWUw<9R0IMBkvIWMgcGdAy)Rl;mqJab+`i#5~?Mhn%!pm2!`k85VW zHl9piGcBiPIUhMI=K~*0GT}9_(Ugj(jo-3r^Gsnd5)YQ^+S}N46*nZ?!Qd)B^hbX2 zB3pYcS;YItQ+D3C0_nXX)uK(8PaYL%I>WDXUa9Y!*&saB zivTMQwLC5aJOMB~1}Qk4h};oA*kP{}!6>gYfJJkUQ!6*cW-Heok zXWJkv+_{5nH0!U$k}B-Pkf%LZgGjv7&TnF^_7y?_as>B(P>7=r)~YP{oG*AdBgbN5 zCdvU4i}|8rY9ILp08>JU&1;^ug;0&^&v;U+C8VjHWVqGO=@m$x>UxJCyc!j;>tTN2 z)3hVY4G#%K1MljA=I?KcnBUJeF=WTa-P~M4_F>h+ppaRSp z=sB{jv)*19OEGMiu^`J!x{XWfblFaNp@V(U1F}&}85wq@N{}`hOVYv9_+owE=vOv_ zSPc;}Na7A?lVd3_ETA~C9Fihhc>O{R;VqTnza5Z&!@#~!$kZ+w8Ji7;JXb%%OJt?C z>#aTAxM)53e$f;P?-k&jFJuN#wKt~PHv&`btx1+!?TU%&2#oaQ$PG_hpO~3a zkK&bFzG%9!q9VPZMIWQ|pT&&F$Yz>d`#m$r7%^8Hca_ z07WVN0ZwvIs;gePxo>!4LMJ>C*nz)_wpDY2zF}DLy=iQAZ#sx>szTUBAER=6)3@^! zMuF9zC!^R%a$0EU?A90*-Zqo3Fidnw#Xf?h>tbK6%zBXfr6y*DUbCa{SGY4q;UzQF54Lc)f9m|~@$1&-NOY|dt(ucaWGf-D zXht`vSy7kT(S7-T`WQngHB&rF{#W+YGrgvGYozgW#SRB^ftw6ZISYR_B2#36?9U9* zl8G4gANk0UNuK(1GTpDy5xn;2I{MP!SDj2EZRwNv=)IyxalLTT^j)1zBPN_|$A|u4 zYA2kyZI04fdBTIeQsF+2nsCx9T=w+0E8yE+sn*JH0UGyquFd4Vk6koD%zn@J-}wgQ z_uq=PjbN~_43?wL4Csie+mdHLXt-={%!e)Oc)yWkh5Yv*g`eLZypPMc)Q<+a^jjJP z(2Yxvr-Kf{K=O|fHuK!iSGxa${4xst5htEuj$>#h>oR4HTkhRT?^empoIv)v%5`*B zkq+>FlkuZfC3h*xboYsP-+vQjN=WnM>K=U7yHD7+ya(Q>d+aKcm%;%QK^`TrJ=LkA zI&+p=b*fx-##89e9-z>d{E7*mOcp{03Twk^=1g!;B|a$3UL6bJ!6mJ0>654rA@~gr z^6B2v=B3yqU9EFu26ZX>QxQ?KQzD*4=Yt*4m7c}HLlL;q6ookOVEawC2 zk8I9Mz_SzZ48YHb8%?3^`nG9GLgmqL4Eis4y^puvu2v~#$|l|V!0eje(5y4&&Uy|N<5>v2ew>iRvu466Fhlc?T(iPTxf37>eZ`@NA!Vw|9GqOGsBE6lx z;n9Edv&xwU6pU{E9L6mwLptaQTIG~wU9lKUu~eAhBQJbGcKEA>;d8RXA1w^OBRl+$ zh2c};aE-J-LJxMBrZDOvJ=p%hP^}GIxjnDgy=xJ3{fVA#d@L6K?q#u1pSyMd>0}eS z{Jm?7=}y*!cJJCngwNdJiRj+7Mj#*P?p^!j#aty>wkR^Qh9PlQ9Y2mMcSQnhXOQ;8 z@yfI;%y7$TK}~G-QbnF}TB?H>;fhzy-(R$c zPpa!r{LH2mQ{mE=to?TdN#5L1k5@dm3@8lmmmOYF7{2`Ttn^>;k%#}o?C^IB!=I1C zf8^ZK^B$L%=9aJSHX6{ybFWr@_VAO zeAQcREFaDCBOXufzTmNjm5sa?l8R|oJLwlUFf1;h_qaJPOLu)TA)KAyx*Rw1-UXBnZsFHP-aV9a z(UEtRxe+#}yB?@4){Z@+kvB(o{R~a9JLP9kd={|%1RE+l0q;J^z`200o~*I=1t1)S zY3!XXm$7#yt{;2njB;b|^_SS#yE7qMonlyaQe>CS4hc9Y0k;7>pSb_sWA9Zeg_qp3 z*DK?gHo~&MXuWbOl-3_4ImLrT)+=tjZhqeS>xOqa9@luiCNSfK+AEjGqfuZm8jP%! z%NR3u2`&9dx)@Ur-Uw!A=H|z*arVgc>yBF-SV5Tw5J`zx9L)AUup5WTgRM{z2uuX z7?obMfU+6OSn~U4tiM0=LuRZiZ%a6_9T-kr_n+Ny;yV<)GdPCpV)PeIc%fj%dQATN zIRES!%ddeB`^@E*wFVl7S3FPcT^K$nJACWH@apXFwF|>bv%^O|W0Qr;KY*IdV_Wk4!^-Bd14-rQ zvAF}8WM(kh6wG6H5yJb+M0NAn%|PkkdVXylTN9x8Joa&n&CO$nD~qpU&!Y3#;b4=w zDuebBfCF1?+Bpnx%&7(*0+>2Y^VrdXIs%1h9#dUvn8)_R^?R^2hr4;~wF|Mmn$(Hy zl~9M}7bOS2{lY3)7`OpOlwaeIj*&DOtO5)peU-^)q-ZkuH;9pMoR!mkd>GdrnIpCj zecXm8Mkw1Iv=V6~dJIKRG`64Y4VF5?)f7A5!b!Um@faxGKyD77JQfdt;bDw3wl~&d zK!Fw{7O0)B){rGSo5{iyOXpi7oh#dDGjHN^(HLg7hVdFua@QXm)i#A{^MRq-6WpDb z+x;jE6-i}w4j~d1+m6%=(w?OIoUs`saDHB4G6mjq z{pw}6K6v%6OjF2_|L zxCGbtfl%;$2VStFmJ4+wQwcHs}|1FKI<`aln0T5~&a=e4F+sQr*Wu;)zU(6|q% zMCt=Gm|F|`KrhAqk$vEUM=S>|OT&XZJa>&Xpn$tp-Ur%+soOsA01Rtw>h>YB`@n)5 zlRoe~FjV{YlLD&6ec+*|eJP(cprDj-A6P{5yFT#Q+=4!E$_4a+b()ew{m?$Jxi78y zzy_|gzbq(iULVjc_r^_XyEE>APEj9t#s;}Qt()Zcfzh;dP9Jz_W_};gE@G30Vk~l6 z)TOYfmwj9fxoLET$<3|zZi9F2h>jvQ%ELxbo(zkh4U~SbsfxGWm}TpTMf4Jl&x0s? z*ofede~nDSYvPLmN|-~5X&Kl7e?`YMz5x|FhUImqu7O7b9*OC`f(K#dZWrWcneMaC zAoO01c(<67XBsUsx9KXd${pj{5z!yqgPf{iBcH4@JW@qeG|_rz=875HQA4z?JPL5H37Qj*2f|U9=7huK zGAH~R*Ut$}M>x6Yv2&Rd?s%R#L8!we*hzx_Pu$KpMlqOA0QwNPZX0veMEp(#J z;A75I=`W&}+Y((YjL8tfihr6S@%LZ!qE+)`{~nc%fuf%JW$W!416_!|pT5-={vrA1 z7yoyE)EI!s;BR`mYicsb-U!TWai1=Hn#I2RidUlj13$-Zfzp9GEdsB^{H}%kvKUrA z-M(P;GHd!o4X_0zi)Xd&Ua;!8+0+0lMSEt1Hva{yfp>@&*z`CtHzLtrnNDLhKn>*< z5o}Pa5vKfUemBKn9IK&fv|aaaT#1fSg@`6z9tNw~3%&7x)jU#BCofpdN&ew3nftP#kD)mAf=ycd)Vae?KuAF(G{TnsN4 zTf3>{oJp6uUzue+vqBBp{w`KDvLZ|eBPM5=OT8d@y*(KDcZ$xv$#SAAP4>m3Ngni; z(;rn0`>#V%?joAiOwsW+{NbW$La|WMcA*B*nqX^~XiJjo&mv}IE?KdTWiB(F#uohq`DjCu+nhQ#Rqt{bUVk+qXL0fI;8JcxMhGc8!&{Gu+FOYoNoivCpd4 z4DOsvWe^Sf_i`a+<|G$ny|%kRe-v;I1QUjm^t zAL>0igFQS1;otV)%yC3@0^~FVgmBvRv=#3c#A)u1(oC3J_T#RI-m{%Hc(`d5nLz4_ z=u5uJY1MqO{Z-`!h8Q!YV(rN@-F2freLSgICL>VM)bqBAyk%gvR(MKth+m0S@$ z=d5H<%zKabf9@@!`2+t`S43AZ@Y@0$)yb$V`!9BTxg(XiS3{B)nmWT2H>1$r)mq-A zazzf(yO$xxW{LdL8u)t!r0OyuvN-~V3m}U_ygN#+8On3R1UzBV)wZ>6=x&ye&BFHHRESw zpV2MlL*UV|Sv-znt5iZlB@v7@MH!pFLHO&dJ^wVCy3><5=&G^{So0(Innm z{_J%E{^U|qBOD2Mt^-E_uJe28D2@ffQJ8cf2jl8)xL+xP)oNDLkxmCP?FM5E!Mr6r#+wggW~6aZHpxTXVx ztMkr(ZK(HZ;^aMU%1 ze;T0vI)Xa|byyhA4esk|=ltF|Y3EFI&UrXGI(iOno5OY{;3Ez^4e*9*Esqw!J+3qG zB*2SqGw=jJ{ej^)4|W9gg2LN*p(g1BT2PvvC$YM0tDSFYNj>@c+6BNCJ^y|Awpy** z^rvW3af?J_ohl<1{fWVCX4gV>WRbYZh)aa3A`w7V<&m+aJl`mKkeu*Ud%)fw6$s|P zgdd&x3nqoAGj{>QI5UZ!%Q(^I@JD7T>!ZHaq1GxcN_qVG$7Z)(HHIA^#W zubK5zSVEzd7TcQ^9qFQ~)D&JD&nkb{uH=Qn$S@qa07xNu+r)Ejlzc!n4C}feigihC z3q?*!qz0JT#7{hLJa`H7#`j=8Cc=zP(BViPwqJvJC-QZgL9x2(^(ZRIXa+d4c#-== zh-DmPm5Yxv*i!VP%T%S*Dm(S>cr3?&(Do>J0bjYf@g7O|=xTMj#tG`&v`PN3|$3{f$00(Ee`M0&iqmn@^_#k$j< z-^8gVyB3fO4f`xE1+n^7d=|Kg5ywXV=mwXcU61^*C2{8##GRBMcLT+ZESqyq>-uX! zzsozdE7=w5my7!0-&Z8U9EWa~KjS9h%4ccPX?9h6&OINds|;VcElDIfthDPfa6zEQ zNzQ7c?M^=7m5)y|66$@v)lNke>kKQ_)lwpOK>?h1_2FI#$!qB!wi1nXP;fUv@fiQ& zBt)+5vP!xxG1?VF3mS3h2VD1xB^g4zL+P@(4fvyRrvQv?~S0ns6d=I*1 zhzN5lAgMMBw{~&N+EKTw+)luPo4JNt39j`Cj2AL}86vnzQdg0d+oCNx)I5IC{nU@? zb&~4IA7$JFK@)DZOYSdiflbj`y1T)zuQHNvtO)5~Js;1%CHMjJa#X9qTeqw?vyKJG ztQvl1+XS{J+ew^eS4LcoZuzy8GZG8xx{bt?B2vqTzyCI=e_v<8yaryRR}@mop|RG1 z^>o2}Bu#}wxJSB~Xj2IfxBgD$b$gcKwuAuRLxApPpN1P-Lky7of~Qi&o@>aHtft{7 z#`ty(hgx|lvgKLPrmHp;O=%TvTkge=_5_Be`<&AuV)Z}494G1}NZ(O{^*=+|olBUC zwhzG;5vN@_eD6j@{|{1FAHEd#Y29HnUtSAyydIZV)vM7cp;&jxYh;es)$*E@al-2d}u z=knA28}MO>97^J(DNSXtv`Z)|3HPnRmW#TKmjI#>f}G2h*ms+eCuMh=qx)O8$($+d z!H05)=ex~Ta2dUm{gbsR2kD6N^~n^__IEGeocb%&UmcZ-W3R`0-Nk+`j{S>4ro=1D zPVpkllhrM&^1J1q*a&C1%Sm%BY2smhm2Z-+xVj_Sg- z0TOD^jF#EH!aG}kkvBYZXN6medwo#L(bRsKszq2Ahhn0R)R^uw=qb^r|EA`w|GL%P zuvjNr@DJND^3{-1t*q-+6(`;Qxo-!gW;eeUbG#k)n=a36K8%{+-V?0}P6fYfg35uu z30fifr7l$M>q6h!){&fYuXaWj>n;39e6!#QW4&Jxogtg|PCD_3Sg+T+V!em(f%RTI z-LhRV7RM>8&izCfu2OJk@amIwsbRO+SgO?Vq_sxVg zldCb^pgy9KjC}`FnANm=K#xooy5m?(U1u-2y9Tb!7-RX8YX+^&9H=;O=yd^uba34q z+7v;f&qV-HY9ulnKXz%8_!;~YnI)Dm=6;}-eQdV1?AIhJL+>EOroOS8MxvIDMGy#N z-3vETw_OL$sHr{~ligHHDy^x`R0Q5H@$r09t^GYsbps1gXrWaFPy0FDnAB(FZ2cP7 zr0ww2FAAFK1iVOF<(g{A68oy=elzMyQ&mSzb-BY=ITV+QqonNspcUnVO3^aC{u9T8L+_4EE?>>RMKtStqyLFWZ880ayf69> zo@MkugQP;^c+eN~5JxQ`=J-49C#U61EB$De(3Y?Cy{sW4P-bF8Py zG_N_%@y&4=(^A;WWnzj<*II{C`7J?2<@E~A$z*HIbvOXcwTAM@ZLW&()?9O#tK;Un za-o`Q@?)go>>o*Un=5+_k`9g`8UrjdQYyUdOIC%C%ovSSwqm~WmBP?p#G!|CaF+`Cw7O`&G}Dj{j&xaCY5ustNHFzxjs#24 zw<`r2K&mMc6j`qP_3ESs$ESmSSv42|y6|GII|vWsSh9#ox#NY!Sctug&*?2!ublAV zgm2)(Z{=`tl3rymSJ`i$Y2>o9f5IhFq*!#UD|@3WJI(h;N|ZDorRHF-2niF^Tm{7i(yd zSmz|M%3Q3?io`n5#ggG?eE(Nbg~|qs80*`bFxGa1uimvflvdJTM{qC@HaiD+4`{!i z2hI2;?mY&?#L(5Owcm@M3 z*TmwnkYVpbtl)`kk#cSk)C*e;ruJ)J%;s&WHrAO9P!MUowOcf*R#Odey)}*QpSONZSPh$x6f~WVxc{_j5q0< z$||PMub2gz9iMd9$)X)9{aI^WcG@1r(x#hAOAuoeJ=JrZto9Y0zss3x)8JXWU)$wzi>UA~`J*9EY*P*;KnVEar zrh3;$D(>7ViGPzUFW4HS_BoapPZE)$_seY9O@u%A2-%{X-s@2AJk(;Q8R(id{bx?b z&kQceh$?%Fj1`KF!Nt|B8cB+l;(pFu(G>;|TI$N^3@EA?XltB@H=v-=jE^=y!!%_Q zw;Fz^;lM_#xOU1j9GFM>RB#6J6@iP9x7@r2!t~#VC$1}POkMKgdK%& z)*o=M`)qsi6u?UyI2Q0Tz>eSyARL8h5B4}**#jJd>+JzX`90V>_DS-yeSC_^Tw)ij zrGxKAGdxjM*#mqIjKXmfaOA40i`xUh+*xxHL*0W}xNdW}-uO#*xYh{|b1ZN2qc=E^ zeTlPEmXsH7Y9HhgYg2n4hxptA#L=dqyHj$ zJ_CfKFwyf-T&AUI4Ds5P)A?T%pagJ7cZzBtA)f{Z!3fMJB0pvz+fZ_JS)YX)a+ zs-?Pa=f~PD_vmiDiT0rOhl52jb%vYJ$VZ!izw_mgbeAv8EE;FROmx(tY?d+;f>*Nx zf?E%>a_2v8@Fy2ZTZ!$#c;eW!Um1z4Ge=u|za8hd_}&Zi;||Y{`%}e@ zw)iwO(rw+swK*M&Os4fI?a~u?w9#>gxE{sU+mv6kJnIav_>SVX2m2`?9sJyfCtGjF zDw^~%4FpLoXZ>{l|@+7`R~Pj#vL9%e-RoCEbyITUav0Y85vcbBpb+Gy{>LxzY1(Mc{rZAJ3~Zf69Oe z7N?T@wcWDp&KLW=inkUTPl2`n&9st@_^j??f}Zn*skKVOP1%ZwIO4!?Iph@E<;j~b zP+0bh5A-w~4#v3Br~FPdJU$8=M3`t8X@UoxU~iD4lvr-9AP;J?0Q$I^l=nztd6nmL^fTym_9)60^{hSZP4HFkrbwN^RXE!q zH>em<+h`oHCc!nHe?-&kO#ZtHI*sm(h1trIo*x!bmVEI+qQ8)`WZw_HvgE_8fZpLd zd`Yo!boe+>ma?Rp!g*!M(C`n0Wp+0wY8v7E_5+V|N)FD8JWlO)vtuS5WSQ-Dy9*}$ zXlJ!c2jAXF8+t|IIZsPq56-9Q)W=@D!Re+tf&=fOFrZ1c%PYlhZCq9@%7_;pa(MI+ zZV#UDD%L~3uoZ1*5HEbLJm##5w&#gRUTaxi!2q0eu;T%gCD;Ub)>1uWvse$=+`NrA zaG?tH!LJRazt?CjFmw$8v9t$VVm@cW!crSw)>gn41f+vEeg#HbtUWkx<*h3V*B)bCdb1%^J}!%7-O!})n7U`N zZirS}Zl|_jX?(RN2fxft15>^0Z!4&tUj;XWW8O^0-POX)-?AIvt8F9u(|4GWPoX|e zBz(n+CQX9a_WMoKR`&&w+}gtxWX*ztWXr9qL1Sx9(Qnjmsdpr|-hXY9Up#J^n^^HGF_KRqdzg{S@9vG6FgPto!jGrw+G_+FP@ zEZh;CcZ-|X^4Hjt@-n%@XR?f@jWXf&jOGOcik5L`Uh)Th^2c(MuS#+~0g<13@4V!X z`sC+iC0|(;pJf?97k5>>;g7|uc&m#P4+T&8OscXnp^Aqoc~Kp~2qB33`hMudv--MD z1WZH5bqc4p+7@8xP`S|ZEQ!9dRU2(Gu!#|8C*ZgQ9PB|wp5$TO1S(K|4N27c1e^+} z0Z=Cd+-o>9$LTXV${s#)U;>n8~I=;H91J`G;+5T^gTk{~kAGd4+rt7CJ$-+Na62L)+(N?MesjYT6pQ5VL$tLpvxsbzLTBr3emPd0|A!J`4(^3$! zK9e5^#Qqi2ojYM+B};~hyHHWxP)bN?MO#Di)uWGsocPM?B ztkk zhMgAda+2!y%gb5c(C#NUT378oV}I4@EDS-cLwB77lr$GFTes{=?B2u%>^)s z9ARjy)!aajx*jJriO{9EgzB3YyA*or>U;};Y2@ugo2SOP)qq_rHH1(V$y{42)+$5O zX1KJ?5}4g!L_AGK%_UF7N!%!S@^4UZxabq+l!CTN(dg6WQkg?v&u6SsG*2RT=4el^ zGCcN`#|V#UpsRxaD)D*qX=MfJu!G^_$E=>-Dr4doOu8|Ji87EVZW88>e9B~-ihf%Q zIfK2e&TuHibxIcVnc!cX_ z@v);C6%%!cyLmF&q?u(vvm)7TqeEyOd8>dYncAk$`iw>1&&$mVVt#))3r8dz{hhkU zIJR^+-h3q=N6ov@1p2bOJZHP#Ay3CIv`x@e_6XHwjQ^yCL)OZl9j=;Wt)y~5M?p^5pnGY%jHq)>Q(tKMZ*BMz3|CAL?TkVJV(A08L zXJ`hhq%gC?g;Ckvr8iv*7!1H2DjI))i#!;ipS3mqBI@jeTnAV{1o5}IaP0kj&yquvRmge zQc_EmJF_tu1vF1Zi&I)Tcqy$P>72U&pFR2V785l%uVvD#XajDzi z4YyIzD3LoK-s6x9nn15camQon2@lZr1>Pg#}UP+ zENNM%I5D3VCzE`h%1xUt{gs;8Ms0b;D&1)#Y{YZ9xON@*WR&fZ^IWk?=83Z$D!ZMc z_ph@FesKY_{R6BTHly6v5FbXR89!J3>fqlv11DC6iwV^;5ntKe9HG=0=!%zS2GZ3Q zH&2y$&{Dm5w{@$o>`Z({)P6Nd@98a;wj%MCpej9H>l|lmP{#&lIoVVx8!bXDyWmK_ zeA3%;qY<{rQumXTm$dc|cl@j**4Xx%u@R$OW=-FL1_?&v z=)zMnVTECt)ytJ#Ntx4>TQb*kKJJ4sk99X*^&p<;5Z6%#7Wow#XE6JL6u~G;%9kvO z?Cg89vP0q0Qd^_@Rmm6~{4h|Jk?~-cp_zA>v9V%VYV!E|Y9&V72I=7&QY{S%K?dTV zCJ}V`7%AC)$Y}8ko_ur9zL*5m80m=?l%rYI&MF7Rz;Y|A7>z1MQXH9IXr}-|uul;c zX=wXWq5r105n`~i;M3-NE)?jgv;y4#zfU7@bO+ zMEV1qW`M*Wf+hvySgzoE3%>Mbfp_2xA2wtkZO@DXmfyv4`IFyh0r*Xk%b)zl3cydg zIQ_}*bOHEHmCK(Nuj2&p2Y8QzD972g!-ugH624)R!LN0ZGSodsqaer#5ql&xtZAO? zPH8!wntXQc>4La}pU5={7p1eQtPUSv&M0B~a1I%I9K+!$4>py{ zcFldX53eMVYL)o(i@@~oqzp~{vJ+L2NKG5XY#$D%Mmf3o z5~z?a!RdtwYO)iYKmtV>rRIKMxceBbk6Zi)oX5k`{sZpp3@_q?dW*T(ZkU0i@u6VH zE!_2W>*>+4s>@U;1|D*YH?SDjU~sy5Dc!4z2w6k+BdnM-)|WDKQ)D)`5QS4=HAG~X ze27rAI)9SGVrOmOo6Spuuam+q+lLMMMK4()szIayy^kwIGN6DqtOyshhBL+m?z6OAl<_K(QE5#$`4X1oMx}^cSSgkXcR8MuJMFfM)qqQ)bLZ z<0`_`k%eZYYGt80C)K)b_-v0J(HvA=(%PF~+fvF@5uutcCJ(Z}>ex+4Bb2ZNqrA@G zCT<#iaLJyGKEd^XTYYZeHGo_Hb5F~lhs8S$pCPaBrFboXtG#C6Nq`T|-^;0F{fx$( zqG5(C*sa}eb`64-S~V5kPfKS8i9gCJ9%cu7PBRm5Sr3|Ga2)4i&l-wx3|b7EjGt#H zH)Fh<1~v*L_=w%oxN_uMgFMz+Vs2YnalPjH$DQQvrek-oyIccwWz8|ii-T%a`mQJV zq3E@e|#B!ut&25uclJxF*nT6bHO?a-DxG9pRAtIkiaXux=$BPY(u1!fzcd%)nA1c_h;$f>0uo{%~ z3*+=p{KA#f$D2b*uCt}7l1^{xAsP36h}TK!Ma0b3v-`at@k(2im|35?y+ZMZ`*YU6 z0tuC=bCm&8z%H+7=avF9t&ZLsr87ds5lfw6QSgrv}PT^P0Eqvyj1bxre zo$RAIJ=UyLE7Q&Wy~l9wv#@4p3Wl~X)@W7}lWr)vXMU2P>CrmSeLRdgeB4~_)OyG4 z)8lk~RchbfuA?cLYwy|f<7odF7Bwp*(Ej?;o-N1mbKa_S!2VsYL7@ptOIuoY9tTu0 zac&mHN{LQU7st46%)-@^EtEFth@+DCbg}C`h`A})~~h|Wsg-H>UnYO{=}wPs`GiO+VRw!_$FN&B>V_x)JZq>(2TL2qm{nk zm1mc)STTD+jQ!!CJCY%DH1$^awd#=-vlqrOt|UfQf(w+u#yp17rIOYc3;)vQPUr)L zkZ-(ODYvu9COa2}n!*s3`rzhN7`3^i`HA<+npb^RJj?lr%H~z)wRA} zZX_*3u<~9KNrXal*k&`EPTjE0n+-{9gf54G>NHMxvVENoq?s_MM@*hIHZ4g_?q~UD5wJ?i{jGhuC_{d#w`*Cb zO-<63clC%O7o$|2qrq^aI0sj3ypx;?8QPt%t7y*x3cai$@orDlqRr5djl2N{ltoT4 z;6 z)6+l5`NfcBE2dZix|JtfuTrg7Rj&CvmkHL1q_A&}~mFvAK!NX-Foq`iiSfJ(_JLVGDO(-h#54 zwNRX!%9T^xq4~v~FlQ@G7nL8g(R0||c5q`|#i@bwEMzT(>}esb|LJNRnPu$J_|yyu zR8Khx>upI`3%!K3L@gXWw6Y{elqry~7OIY+iX0{q*3zu+`4OBgVJ(+@^EL!tdiJ&v zxcs~U7B!Ni-rhn(Y@r;Lsby+dV&mAtSaw?CWv8DuaN! zp^B<;AHBS2HI7mJT!Lno@`qPL+=88})MvEr0-;%;76{?r@X^Ixn_W?n{% z9@c?eP{w4r?q_7if#pgWx^ZB+jRUQ>+L)D>^Fqa2sM(ysbi&f0qHP(J1UPR8y`s_f zgnjimZw=&<(G!*;R^6!X^>_2`S<&{O0i_jflD@l8(5H6R%vjMjDFV-1)1S8M@U98`L}ijN9!uRiOuF1@VRLAMQfm$qltQH|D#_R| zwU9=Um^@)ld8X0fOFRZ><;oeH(hhNv#u;i zm#%0v33`E(ql~y+f+vir{ZPlLmNG(ocy2}WjQ)7?H}3zV?tS3ntg8I~Nt&eyld2sZv4MH$$?@vvsOHE~;fYJE%h zWHGj}e2komGw?of+EE68Ids3KX&XIOD|g*@M#E^cxg%6tBekLSrZbdsS%^Fl%`m%p zXE$031jNX&?)@+!cs*6TZid%Wt9X4EsU%Dt&1qbEQ(fvBNqAe0(o zx2?|8`!yxqNfyqd)E4;PJi2tiV*ZPFj&CwEj&|ss-_jh|kCtG507HsmUb4v(eO2C2 z_0?nOtGTQAbKNuq>$UXL+?z}Kh^!`5SJ)J)bOW!}H*=l#xUSLrWwZComz3Y>o$?&- zl(Vf<=FTmjulh{~NkeR?FTdI&Y{E`Nx_okNM9W$>!=%bAW_eEaV>U?CcCP=ie3@uT z##B*|uiG*8{-2hw20F<9nS5RU_*Pm9DVtSU##w|U9wje|{Og-}p0Gjo)e=I?7Q_0( z;$dIMP!u~?l*UiV%M?)ZR}`?&>Nq5U^|)_ZNSQTq=%=vhgAndfBtOLu@|1n2^*@Da z?^(Mxf;883#I)WaT;>h*wcM)mc)!J-E3NMAK#p|~+{U6p%Ns&BTGY7UM+$49gesRH zSgeS}UAgq~I#MH+lpa$)kX^-7KV?~(9nfMH?s+dg*RpKRol0aE8Xvw{*Ks98p;aFK z57py&Gi!XEWASNq_1(-b`&z`T#dPoP{e-8=SDvjr%Wu=_ht-%nCd$Z&P&rQm;8BmJ zw9}wwRXE2!Y^}_}Qsoy*rNNq6637qF;gf!#(?f#DSf(yzhZ6b^ku^$`EgcE5>_E6r z4n8gwUeB@HMLb*T42W}Xlj;Y5FLb5J)}rjorkk+k(#5H#Vp&~(pU8@bgW&tk^nFM* zQEdYzUn|(;mf0J_d?TEhky}tnEOfL8!1R=ZD+Yub%Qi`8uRSvwYFa2MX@&$7m!>Gt zszC7suDVveh>7KxE_XuM+4*bRYo=?nxNC_eI?PwlNWV9g3aiU}@c;p7qDDEbnS@vo zRJ_&S8B)Jn+J zmtzfL)G&6vNM_Jv#CFjL4q;1O1+hbOhle*W30R->oOP*ZrOyY^>>W8I(=S_GP1G)I6zH&k z>jI($ZN08{gV{nIl7;rnnnpc4Wc2Aqla33qgw2c|=_igr@8$ss(5w*8%CWt6x%m;|5J!_ry-FYb;O#j0;Hp; zSWxUf+>j_6UyM@CcQGlOy3>}z=CX@Y+|(dTG<*WJS&ezfNiN*YLeFHZe8MQ8r(c!? zQs2Q4vPasoXmDufJ*f)o)N8K4Pbwzz1u%1s_H`6@a*=7)WxzcGw!uH1LXYnekP8;2 zPczyqm|CJ;bUE_^m@@2nF6^`~A1NL-6jHIP)EI0)Z;60>I$N`t=$1d`_t14u^1b=t z;>Y>MS+VQJ2^wai@8MnlcqjBpg*HLj^x{mTs;@pGtiSP6VU30v zH^0|Y!TWx3Zg>p5uNOhPD+kOBU++urV;hyavPBJ8>sTL~1PiF~C`yx1A_)>m-t?&O zc=_NWSj=8S0o8HN;{Duz;&0(1C%)5do7uLQ@Ul_sQ;fa?eJ#yokbrF`p531(@(Lmd zVP=h7?%q8R&Z)LSyckG^U6VTNH^CVv@tuy$j^&Ko)G-0Gz-xfQHnQg%byngeLd*57 zqmXvMvsbqg!7|1QLr3Td-F1)#j^+Tkb>#&0%BX{uuh|Wswa_}<&7Q}&dRF+)OW+TY ztc-hH9Zrgnij8kj5dw_B5dt$opu*?ZfN?dSFQE&<$MdKJ{;se|oajxq*xQl(!-x74gnRAqhf zd9H}m0KiDdm%ZRn{ce;bL+JXoR8_p;SW2(-nPszhrJw~GwicwK4*hL)rQy`}QOGS3 z*3`FPNTrFi>)16%m(E<}+g;Mdds)RPK6;%PVEguL9~OU*A|z#@c4f_PSztJuG25uy zM{SL$)1`EA{!BL$Hg%*e&>4A*8+Iq8)M%sAJFRWzQI}%YO;K}rs~w9Gh@xGh7Ak#M z@rCs3m!Xd4Go!iqLDZ4m`Q}TNUE)etDrXDnU33kdbgy?|d=pI|=lZ2$2bfC?d6NwC zAm5TyH{R{}0RY!~Yj$8BZ-!Aq9zXptcr zYq}kb^?ZO#Thf<;MJ$esvI&pD5>igsP+a(!B($%kRe-1iJt=c{a>`*20O>`YJbsz$ z`m#I;^9euy&kDVf&@*SzI~NeRo9CN&9>Md?Jdfk~7M{oQT*&i3dA^nBM|fVy^HV%8 z;(5M$X%hisWFf+_=QfRT@UnjCnNMzNNP>{%J3kCwv1@B8~&Y5q?oAW}goU_wNQgbAz55|%}n zwhC``nLGcc-N$_`?V&?y0Zr+CRySjt#Hzm~^{zL7E9)qnjvL0cMZ{TO$J?D& zrYp@8Df~)xbgh_uD=ogVBWr7%BE~-5;*1r$=HyxPd0^ezQ4C$(BI*M}zpj@ALq979 z*D^GB;aJ?dlTBOWbL&02$GVzZ+Ndn5va1&7=bt$RgFm+NU8f|(p zYfU{g?+^%@IzY-N4%R1Neur2`!&wrk$=a3xo}8@CR|mfSzNJJb&V$KLvF_;;sV`q7 zdd;cB&eh=5xzL?DuPDEP5y_!lcz?|;I_0x)q`aC>F5urepeFqfeTU@5mR| zRDTq_*_hpl_C@S3?K3p-sYZC=M4tapeS^#Z{dof4DaJrSG$3 zp`yZ;?Wu*NL3B{~I{`jLAirw>#84LWCo0K?@#LKCR8c<{#*_4UCD*%pJtVh(^7YV6 zee0H*u zkj+l4emnYdervXHKFYV#uj-5l>OR(T4|mv7t>Ze}ktV;fsf|r?%D_SQ{+=UTNnKpOMFoR#ld9m!F=Zd<<9DaHRtb_Sz`&Ws7ffD zf1sdE3Lqt{Z4}NwOtGAcpm10zhFQ3j*AO@ml=M$-(6p(-!Wo(V$AMfwl|RMO;Vv&7 zg6K%dOY@P^M`Os#LnH)wF{AYb$xFw0@)N|$~d;z~yc=XfMC=}iA$Bvi1cLp`Mvhhv+xjCz3OeL)m;jz>`^ zlPN>8(~*=N7m#cUNJ0)vD`Bl(HVGtKr;^IvFvE36VN(Ijw*F9&7%e{WtGt?3ydCgeV| ze4uv%-H*~34f;;EHeF#gIAnt4uL4q^4^;sp&#$%*Y0jN{6U>FzOP?=<^#a9&UqjrBie{`H4=k`h(u$T^i>e zg3|KzxItTy25Zpr1u6%j=xgbLEu$yC&%?x;iSJ(zGv+LLymnCej?_valyv=lG6gCt zjAjq~>qBl2G_9A`FTU+i=YOLkQ5m;Zc@^77RdJqG0mfL)^fL=gG`XS-mRU1*d|VE` zFdk_Wn4b}eO%jCtXYas=!YPB`&-~RP;~=rWBeC=kwRGOE1g~4Z7DIwhst0T);yjoI zb*b{{RCXbiff&o^HBOJ_u!6x>RAv?Aot3{wf3vHW&zmp_PsJ?AN*_aZR!C;~ruJ_| zUJ8{MI#Af?R&^|uZB#ZsFyM5AT~`scPaN#jHVfV6gvcNDA`*ruu=ZucsM)ZZ%gWKkh zVf4P%jow-1v#8a$(d0(&yR=LBinP5-8evQxS)?{k>K9Q(mG4#P9y0&PU=2Eu zxlFAtoXI*|e93_oi}f(CuBPN;@H>@$Z}SK9BL^$c>^wP&%?ix)YZu^pZS^Uh(BzHR zp-PhD_7Zg@#_cC+MfGs{J^JcP?=mbQ$mN~0WEI9WvQH3no{#VFf`P!I#wFJ$}NFc*8qSdaDHd+@7>!fsal>TDtQI$5w zI=PT>iuTcvsh{h|IR}nI@G|w{u?T)CoCpLPTX)gQI3Op+tdAOQyym{;+yuQz`3Noj zIui$1{RuL>GbHStrR6gfx0F$Tf?Q`k(AsUg*<~b(`k+FD9n<^>*fx?ZW%@6WI?2=0 zuyf?LAY2uOmk$`l@cv*9Mq-6E%&|~22b(32H(xVB#-RE@owI(^bZ331Fz8I^$-h~1 zj?vX_4>FCD`hU`~UO7*k4%?*g8fdza>Yl33t8G9GD~3{NgAG|GlXj3XOib(yrcV_O zMD~~R>9*rgDD=MjPY}8xN;49LwE(d>Q0nub8Oy7AoyO^)2rsxA%PT<1*KBhq0fqEe zkS>RsVeEbm1EIbJ;wBVWl1hZBWD{rU8O_90+F}KFF4b5ZdG&+gRB@Dg>ri8;flB|P z<|GugFm_%+QB>*^@k9;Z0nyOf6TG#z?&q!Dr6Q7sV8&}6tyniHLBRjB)}D6`c+o_{ zQM@x;qh;%#D$)=_zd+deM@Nlg)?QWPtXmeWJ@lv_@$@Zx){3ElJ|&o_5^o@@mj+rR z1|)e!wbnpgqZ_Dv)u;w4TKkUCKwnT_6baD?n*7>m7Xx~7zr{y??ABqs4{y~egpHFSNI53$Kq`4IbmnD7H79)3n%|l zUtOTQwi>7QqmMa!R*6&&kbJ^k*lT}L+2_G|bW9rQmQ`EBK9AC;nVf`t*_V*KAbata zEZa%K2as4^AK)t1u+g^B%lz8o;>npzHuw)&&ATq3ZnJ4t`cL1^&?CTdoZ12~H8M<` zqixX(>h8xJ*mV^#j_ipEM4FxSD9%DKowDoPR_7Gy(+Y>)%dEhsm+#v%oT+0hoRNdd z78-_#g&bymHuRw&7-Gz0L?IIMsmrf?HjHU|20HvI}mI*tydbQC z=r}RLD&Kh`(}ejp`w8S>JI@cUZ5fxw10M`J$OuLYdw*Yd%9ieM78&V$?msH`eRi2& zxwSa?e(#43aH&Zh$D9-((-Z_2NoD1$djAtHTwH9(Jeg)Fll#9ACX>FXD_3MaNFO-7 za+)iN-N4#1)-+(DIy(02jRx7_*zXE4iE`8w!^KDTi3%R>c!_X|Qmtd&n@DX;ro!{# z;+GStMh~?%8Lu1S6JUZ-TQ zDVq0YHA!LOq$_xsG%+ths_gEddHJa=Qtj0+zm4^L8f$^q1E%FUak30fM~&<;cvqjk;BCYH$xFk>{tD5!0c1gTG9#McVasgBU3m4eLes!_5QGH-LO>E z*$~YiLj>7b=rN%HusD>FfPE>ZY!^rav)ek;*G@&4{^FT6>;k3=A~U##^(s52cjMkD zYMbgSN^Rg#$hI^prYim3=)YjY&YgoHg0n`vMPzlCMCAf9v{2YIdjS!4ootE1en>Sk z+9D!^u2P1kQm;6gn~L(up9z^pI9pv4`hRcIFla~Xe`Tu0_G|0G&#~v$Um*)GmsQK} zvfPznB9uI0brcg#s)rOz87r4JyZ?tVY;Ma*cx6wNYxZT<+O$koV@}H$eM;Ke%qE=` zZHM!vchOS@<2D>cez!=>pUFPS^!fTM0>qzYr@Yti3xkSpv}76ERM^E-_P95kHQZ7E z>a&lVGu+W|?%A`J4R=gEZqB)9Z|Z1Fl?Kc%NbltZW%{o5_h-Y`5DuP1UG!HgU%Vfg zqRRVPdej!|_X%)MrWK8b*=N0C3IV|VJabLqr@tIvzc1L{4g1Aq-eP4&7!UPq_l;Qt z4ZuO1&1=nC-u3QM&DR(!$0FGpp=+oRN`6@=`E+BE6vUpFJm*|o!}Vv+Vk3c>{9;5Z z$C*thd1#gx1EWs4UkqB=(xZ2^MCc&Hlc6f+5BEQb!)O=5>1VJ*9}Aey+>2D?X-T5VkIRk~hr#qWqgs#cO8FCAQM8vG;NY)Y%}B_Hp7Hl{zIHnoW14ja>zv8vK<2?9>X zl}fJhf5n|&He%ftM9T)cWan4P(0<@01N;Q@T=L5z!N$i-sY)Mk&+( zD_X&aH!hkb+6_Q+mZKF8m)C#>JY1MG*b$B}lbrW1ueyQ3)sBAptxpdcU?FRxEq`pP z)#Tml?PtLm3TyJhP)sn&CJsAAhdJu~oSfM#m@FJ#8D+9Sh4!m+lSy;2OKOppSgoQ+ z@TVO%AJpgx(iD;2ah^}*8i#=sWOTk&d5XkD@qPBq-RRA%q4dvQhx^{kx!uZ1-$RUA zc~nG~dy?A(6Q2;t*)e)eX6h zJ*(ZoVZhVB2G3RQciKp0S6)hZYp&ir8Tdu)I^!&WGR=LX{5x}>^wxBWe> z8({{={KAEgQA)DOFMPpG&i1aPkjw~8K8BElR?YN1sdfl*wL2-sS2aW+YYR~!q+wbZ&t!g0OUg6anML_Si0LWqo3ddeA5 zol*p=IMky-S4OLd-L5B>a8xdr93cij3@tAh{mSfsi8jAmM6$p)p^L)wEZX<}#yT5h zRxv{RA=T)9kbNeQFd%afOjbiUmBcD(`rjk8N%_1L+!F2g5^z@E3eq-e@(*XOcmd#G ze9K+z5!|$=d9q9fAvJF3l^0LYrQc(;wMOr1MQ}29#GW+tk4zD0W(0Z{Ec$hVfAff9%SxrOMr{Nu_R9(Tc?e+HvJ~)!4cM6UApZg(qoiA3`N^8$wO=7m2pb$bjtkEKLB6 z5CgxP1AgU~AqINUMI)YysGoro$XIkRRzE*N)EnahGeC8$Qfb#(2hayC^} zR9X+HE!6Q`WO}fN5Vq8~vY3_3_|BfEQSK8m z%!yi`GGZTX z@WlofEagiO)xy&ZA@h{>wXiJ&R-nM>GO9%Y+L9*rEVDG5z3A1Y2UVqM69jFy+VE?? z$-%w+;o`H96?OTw6p`GBUDM@{{f^60kJY%MMbF)L`Q--fIM;UbS5}DI1EwVCW)*=> z`_`wu(+;YNXmK*yzdSf1rJA~#HmtT{UPD)>)issXul#Dbr5Cz5#nQ{IxWdT~&C%pf zODVp)K&K$?n7=Q#iMlxdiB69rn$}ltcN>Rxq4jO1{Dlo1?73O0{Z*}hLYAn>3diyA z>gsl!+k)fLeI(gJ+=$M*s1Z#FhKqALqeX(MeR8_uJ*R!l>1je72gU)aqQN)!A9N}z zFukKgByqFA9UN2Qc2u=RTJ0fz&49p*BN0+Gj~Bgh9?+ITSHmobuFjx{LK@ zknnE3S1kWwzhCRm%ek3V{qegkm?I=9DI@BI+!cA z@a*!#nU{dpd~E2Qr758f$QxYhj+y!Ds9QvHv$8hZsA9rEDe;Cgh0Wo%nX4~8dRN#r zCE&#@`CXFf-#?DJ15;l(aPzX3*1JZ}I1n#gzsF4!_hkBi7&Zi%JoP-0xaWly=yE~E zUun2Wh(M=bQ~$8orOZ`gekZ#~*ks`G0a+h_&b zYS#vB3vHiWTi9o}lG|A>V?)LJ)%cam7TwNtX%d<2yOKo~AvR(5genT(8K1>B1qB9d)6zrfngkpnkB#hqCFrLO1 ziTuxI-kaZg%01V-X%`vuo7t*uV_i~3^oJFVS{2d#1{IYpUp^SFB zR(quuC1Ue^g#7Mps2k>uVKo+iQMqxjyw6~H%3#H@FHNib8kM@3z7jNbb_~-6w+4H4 zj-2r(tKraYf00YQL7M=IFJA2$tr_`hH~At!hX)VX*ObaN=*jmW5KyF0zaG1mn%KsP z?@Pu$PMRto$nFpgCmB*s$R!LKh8Ob>yT-Dh1;&$3*(j+v)JmmTt}^h3@}V~$Y$wxx zHfgkBL&Y{jYh!*;%;Sv|S)(kp77-@y+6nZ|k z<%6=8^%aN3r`(e}O@uV5WGko8vsx&d0E++>s>W}1DrVja`9XlYKZMK8g{taWzjmV_ z-SYC$mhN$Fl%3v>6e`68q??yR&EP4Q!Pba#3q;N60~W)@8(7JaC8+`B-mtsl=ITPM z+cUGmB^=tpO3UfE#$U4cJjPseyH>HBrcXTnoUWMZ!o*#Aa`IG%+tYle37wq01mjOn zVCVkz9lNx1wLZ#l(s@L5v(-_9sNPvzO*5T3(CL2kBh#Ov4J%Enj*?BD4t{wV!@So% zdwBihn>CJ%cK5vW7Re;j7aL~SAIg(*cH{0@1r$@Q+j;0GPNA7yj=ii%l%tXp()@w1 zdzC#_C37P^VPd$$ZiSb9TPV9UY$6fBu*5WNQ(|)3<}!(Egw_l7$Fdk>AaV3oyUFw% zGkF!m{8G>O4n2Khhn>Lo2}x*-6kUmhDhN$~@ntmgN{jZH69Pf4@D^7}C{Itun$4CY zirz3uMq~Q>E`fHjzhmISYbK6;CugZ>5K2)3)mg~{S4_$hHmnEE!6U{Vr=J!Ze{Ujq zD!Bda#46l^2c?nX)KYd{-n<%ms|z&Nm60wd6D60vpCXv$it6Cw&;|oKD<}MnCEX{k zZ+j|IJ+~B*uz)QdH&EjHU^iBMHRF0fC|@mRN;GnDP>JF~C5JMdq9IJ6GJSnw+(2JT zGXPL&1J|zHDm2rp0JW+3fRra~@oFMs!WD6}3L|FFp7B&%qMR+X#r_nplgs`(DzkC* zon5$0%Qw3~yQk(K?K1s$vwD$#>j&ez4Uv}MGJTuy8OLSXzmZNb+GTnv(UHsa*T2;? z|Nq!!TBAb5%8Ckc#wJwAsb6)DC*7n{AxEo$BM;a!q65*;yM87{rG9H~=_?&|z4*Nc z-`Ome>AvjJaF^){q`Uap-yJ47j73AS4# zxQVM^WO6K+7vz^+w(alt%f9aaKYrP>=X(1^Qu#I-#3YfWn6>as zw)n1HQ@_I|rmd=7Q`fj_>NVvn-9FX`99&cHeHw+mn5!%Lj<*{;bPv4d1MGrKdZ~)6 zdX-N%RLbo@zj2q)tRn3!@9WTGxvx4fEvDwTYg1uE@!`*^dtw@zRt2@)e>S5zSX=%j zh$;3hfYJr<$KnzEX>#v0Tp3bMi&9ufnW3w`Y!wN!jiH@rMsp+|EWM~gB{c?+!;N9%?!RM6_a(RdrXLhTGtemm1rCUeNHgsQ37|7pjs z{RKEgA!UK|H_uKZ$v*H!2@y%1F-b0fkRXbh>|={kX{qvwqLs;cg&gw7<3&)_ZGItYw%CF`M^u6b%L~~Wsrz_skbCib8HOj@VlVmBhl<`7BRz24;!~u~z32GSXw$m!_(b*X#Rg-nv|?yKb17 z`Ei>LaMosTS}rQi?}K>bRWXRw!yIU(aB~TDFclUC94@JWj%XAdQecD@$+P?E!7KpH3iXd zx&w7*>8I*`RE7XV%OjVJR#lQVuPM{_2d}S3^=105BR^z>w+Dz*Y0ajgt)H|-*0t4< zFs-+RvAaVe-$7BY2&hQDBkz4%a?k-s8+2R~b_6w@RsJmbpG$k?S@O$CvwqvBFG&^u z_FZD}!F-&R)J*>`fbsa>DIO`wW_^Y`BxsF*Gk>W*9DFw40N%yqEp(7&z_Tiqbi97m z4jxMX#a>{Y=;_S#=ajWZ9^=+YX;gwyou#z_YdM_9Ubv|+)faANja%xi8XRIgN^h+x zdW=<_rU24B_Nq>)KD1{|G8|=9=ZA6X9B4)3HFLw=iHHe`_(q(6kD0V#ADHxkkT2p2OJCV4 zuGHnm7lbcr6s-ut{0N6c&r-S4wb63cBZ`)yClhUBt7lrPlcWUxWH|@s zMi;*AElgUauUX|IQs2Y4l&O?%L|8#Ax;Yo&5plOg!rNM2tU|CtupJ$?dyd8I`I_4z zHVp+r>jp~)2PA1^UwUhWaXDLhYYj_p1HQ&3N@%;V%JymSi|ElR+xU`rkc|Bbn>g_k zGLBk;6X{lFBsW1qwJoXN;zLn$+B*;F>YSt6fzD;sENDzHjqa%Hdf;(w>XT!<bTr&h<- zdF-<4*fO1fq9uma2@i(efv+I_y2J7F&J{`N6JMmAKk3tn5f9#Yl6~i)IV`)G#TyRW zJiV{Y2++B{?ABzz$D0LRXQ+|n;8o?^EuuA zzHsP~vu&O8eV<^R^MnT0IXhnFd$w(b-*^>$U4Egf=MNU2UJs6i^z{-rO6BgDbhpAt z-M~-eX-&VKSN%x2I01D*fO>~R&5faq-usr^Yn@hpFdX;cme_yTM-Q+2SVf~GKYBPg z$jqx%t*0uPDCwAkBX4uW=v;*#0J8*uHW-N1MCE{l!dnvYsi+|0wzL|*(=!a5d?Q5=hdBhHVkkj18n8f-)a^Vme3(AOcZh`k| zi1OSRnhMqK@q3}?J}W!m0orP2@W0Cs(}cN;&PXfHS~JtXH!wpgdHs+0Q#@atB#;v4 zjCNXn^2h3DskO9M^-jxq%2h~zcR%Z!-TTHk<d zKd6HBD#473$q(Kx$|5!uR=V&MI4sh@{kphRbRnzLJ=}8}u=+(Y3AW63CEcv|fvagy7HbvGKakZCl}*Kmd-TSM z@6hVp#vSqsu9A>h)1wGBBIPcq0CRc#waVYu(hxXQohwj+$Vj8m*4Eg9P30O@jAcV< zF8BevV;u^EMXKmtRMF!o>m9&COZu@!iS^u;?R?J_oxHu!qh`Rr^my(l48k2|NpHuB za=8OS*2(r@A^wQIL9QLPz>t4Z8Wk7);>e*|pV)+wz9!VvR7P~nr5%^q6f7XSkPR1a zj|4&$pLnU93EVWb7|XCp z{$(~+rr(=!ez!UoS`(a&HW3*Yu=Hat%ov*sn2w#I0jeq6IiPG64%pYq8dABL0;6^& z5D8M7Y=<r@DwEaf83xnnO|3O=Upc^4Axw3hBAioMR0o zZLtHLCPQbqzQvw^q8GF{qmGz=L=I(a%1y-!tP92Mo$2$L%XFKKk;R%^HAPK*EKQBk zVOI%|ew+8$sk)yE39)Jz#@U71N7oSBizy`1%}%NZotwf|xVm#QzM zZ#s=Tj+>uJoCbM26>Unt0oc0ow6$nCU*ARfvaPf2Bm#~3dg37qVfQ9zR1#Mr% z1#Al&vNJ}MG?L00OGkoumD!k<{_E6MTM6_}&qqZsCUCs*)%eL1;an8M)k~20)id54+#P8U4oO@Ok5~ z4Ucv~J&nL+CbR~%Z-hst=s$$eGQJW|S(pXZ(T*=qM|ZWS!txk;i@heK71=h$ zbR6;#DW*qER>l~!SE+Du#>8VSv%$(*Fx~znyNbyrEWv;Wr|gyi)`=MRB;o2A-WbnP z9X+U4XRmWcWcpT`U?s`p!_i4*tQ8>%X4vH>d%%q5`<%`y(0b;sjS-861TmIb)2%9F z7DWr?4P#2ioqPSAjM+vd<1@xDsBQG2mkSGhK=+ZPRRij{E!Dbvgbp_W^0HAYe`7^{ z%wD=aNbB1T9%I_H&@0x9JL+-+SJ2cb&w+DDuuWlq9g5Nlu)4-jvqm<1D@$rHShN=* z72U`fhRRl(9F58Da~l3mc3)0o?}FW?8YL<+Gm_{GzFyW*emmEE6zLB(?(y7VXdjP| zJl?yl4%grznIRyKB}J~jRQ_lAdw%xY{MNn5^1vkkDT{$1-7tHHPjA;#z=%1FwER7F z&5Q1-=P6~ID&4{#lIzV{p_#5k2J##4`Aw4|v#avc`dF z-oN20eaUQUAnk;WRfT|EL!E|?$(hgVh}rE`d54-Q9|Zoym_obr@stPi^`BJbQfc#MVJveUL>^P(2{sEQuCIytBtQou6dGWJhs3wQNdX z#cN&pL;#wh`S%S9WbW8(z0&Q76E^2J1Y%FvLLoSqC|OjrXb|kZ1Z58?cY6`fa372v ztd@uk(xuy7#-#5^Fsvl)SVndsA%neb4&|zY=#G}s7a$VMXYpVxw87uTtLAc=s@W&Y zpX@|Klo3C7Q1X5DsiRcj58>r34ROtmfvNCw=s=cFyGbTSRackPov4m(HxUP!qodiY zY_;njUw{aSKt={FPvL?@A5X3RW_1=A|ImA@QKUwR0&NP&40xrT$vEA@vqiQxj)$8` z*=w$P8|TQnOvT@bp7(LxOFCREFBJ|9wF06`tBJ_&ORLM#IkJCeFNW#3j1RYGU5*(e zz(Ym1jfzix(#tRcn^o$a>(DUtA)C7@VwKbpCAF#fSS#;~JbecKVS&RWXS1MusQk@6 zQdIWN65p+*-YQZpiD+B-i^9klU@F$4N=oDZZmzqC9!lh-5vS; z7;2YBw_O`pC7ou@Qk$LHTa4X_MN%~gqEJpRy^732V^od_$ibL7w4sRVUc9U7p1}wm zGxJYDc+BcParZdYeU2Pd_iw0OI@3Jq{kH4?9<-sSlIH7`-*a}#9y?6tc1NK6IVIHU zU6EdXb)~ETdm%^!?5Ybn5MhKbzlD=Ll zvp95@AX6g{BCVeqitZ)p79zFzn#re+eVndYzWPpb%lnxs>iYZC?QCzwHj1-Rn)&z! z!upNpyaVJ{4q-cA+#fgA2aA!DsSxmb7Kh{q*q}0*$=fq>-SBQ62;R3Sou*)%j(|)U zcWO&r^H?drBL(-7u#qxr4C~(AKciGd((U+UaHGlvkHbZCKE1u35xI~q=|P4*7Sgo= zq>3bA;Aj~J*9wE{$aFiI;HF^hEU>=zi*TW^hKpP7P$SUM;i=X4Es0W|%@pZtYqI%9 zcq7&OTZ{5Wq$et_ADh5T|56*Y?sA8!Uq@~11CQ3Vlm$V0*Dvsb*51b3Tkd^>_R=)4 zL{Ot|weXo*p91^h)24)QC&D@vRTK;PDZDii-X6k4k3`V}D_fcgyNW$PnQFdbjZ07E z#>b+IcM9Jzr1}fOqLA*GXbn|$n)_^yl;+dNlTv)>WIDVbLTf}Be{z`?Hzd>cM25wYY+!+e z$m30j+F7NO)Af1P4iNXsTG8uLDmwCHt1!b8-+(L*#sY)N7PxaZKk7r<28skWhhgG- zL6GP!ebx>^RUHX0(XelUpWEwL8^xU{JmLfG_*`!C80wEW@%+ER2^-fv?(BRq|BH29 zBekE5+yq>iLx1T{?s3uoGG@_(ql$hvaEs~ULbh%k#{QZ;EMVOX2s)RYixmoH*Hp7^ z?Wh{|0wm5IoDmn9GXmGMn#!fa7)`_9f4fVEC8-?|BI^bYX6+ByzXY(Thr~!-f1kSE zTiz<8XNg(>t&5sR7;N2Dg4eEERW#v_D2%wYjU_I?v_&w8C$%c^jDW})h`kak4)be!vdYW6n@+L?Uk&-tTNPL!PCp#tXjz- zF4ZTp7?}@7MrPM#`o9o5)UJxs#6+s~)=<>hp(s&IQ4geSkY6h1DoUVVZ<@fsZ|#UT z8qAHG-Z%;hW|E{L$!NfgiJ888Z9`F|xL0Fh|G0zNC;`uV`R&7(y3wYRYj zbpZ~MsN{b@EnA^)<3%r>KMM*pQ|$!`n#I+I;yCnM#Vx)RsBWW-L}7AtSHSi6Eujg_yTEf1bNO(}+($>b65MJ)a&53p0cK%rCxzwT zUI53610{`y=}jZY(09`7^`&*p zLRZZSf88M^rkLMra~#Xus48VkHot8S_dz_cu4k0|Uime+G_b-y4URo63bF&Yhhcu3 z)a$8lCyHheCnN;+!~kTSr7!wIdk$xrvrx99L-M6D+)f_bQ2IBu-QSD%+EI9ak6rD% z!MpcuW8+P4t>At5Zt#{(ELO8oe5Lc8%qFvJboIUBKi6mZ!neNr=-^|{u})QIB5Rhi z@DF$o$)$@&Dg*ujqN5H}YpJp}?4QH139nBa?^3p4>mgS9Cb)iaCyzF0JoWW)@cFt5 zD5MuXZQY_fU3}G!ow}?nDyd`}RmU@i3+ZFYh|&`{bDPAG^A5$(S@oo|Znk02?Q2$m zCS?cEr(v#i(1&bmp;ejb9}@f>>4%@GjB5?S_H)OpEA8&rg7%l6s?=V&mT!w+K+xPuDEIxO2seR zsPzsw%Sfof;U|Bw;1L>LOkrd3HV4L}_L2)SCJ zE^1NkNBc8^5sUbrCE{|aMP`1ZWZ6(cK^*>7lcgqQK`*3>KROD&Mnc{D_<|Y-NEUOO zD~8TPzcP`c4J^>601azsi8*Me_j`RqKl9X9rgp+PiTq1Q+NT2p6?+$E#i2Tv7;il4j zdX^HbhD@LDL8DZhxswX%eMw>vf>*td1yb6Lgu($&JV`Fq&t!2DF!yXr+-kSiEq1G2 zw)lY-X-0;zu*kbjxZt-o4`qAozL}}$vD`O;hecVw7;)`b6=J5rK9%Pl?i3AP+{-H6 zB0AmL-R>k~`)t4aDE56;o<@7Q&S=?9*rRQ zAvF0z&tuJDft1?TW}0U=YYv-%Ibj0>+&2l>z}u<-zwsP6D63V?1`)SRGbfg4#gA_H zR!kS)$zsAdBDDQ6M98b-CJC!G)Ay5T+O4Lgq;pjgE!+QzC;=t33(5LC{I8L${ZI{X zYlWrceA?!vyIdR{l;N>QO8w~oyr`n18FAg01u{A6A=0in)D)l6hKle#)&r-)dK2Z+ z*?WfSpCPRV)pyXeL0q#($8uY@!MuKB$O$5H+Aqc6^o#yz9H;9)aD?GmA0n8*rbnJ2 z5!jJ0Nr2P8<5fRW9#ab5vUG6+u4^d04Z41r>-w@xrP~QV|IZ5DLFk#Ykd3tj?&f(X z&m(xQ<9Qs<@9~szbQjP6z5O;fRBzyDvdV=)4W^qA8h@q-)R5E!~sDS}XydiU&(q27h5 z(p9z8uA!Fc`wcT&v1B#Tp3wl{?z)?$HTqhXkOIKX24KOJA*g(}TDVd|=?R&+*n2V~ zO@3;79M2R zBi8nRQm-JbLy;ufllSF%hq-!>$AF`(3ytBz|CJJA%oI|7?C%iAv8ehemQO}mIKovL zf1vaE2sAs8MfC+ldUZ*Vtv~-B`6_cuoKr6v$;bRde1TdpR;VVOWg14jz_0+piKH$d zgYo>Y!2@h$=3XT$Tg*~9S$nQ9iMHK`D*|&2pEpb1BQ$Bs&q!=&Co3pbVY{kVNiyVD z^Q==93ZQ>3{XP08HgcZE0#=EwN<77Lb-zh%u!NXY4#U$U(T8eO@5+wf5CGZ3iA=LlL7sg;7Ql~jkcOXyIYQ3-2mN+{dbL75?}DW~6d09ywa zpnc*o;g~OqMd_ZBX<3x>Ni&S>cZ3Kj=eH@2xxTqG*68#pW&&|<+D6By4=K5ql;F) zHM*c4Y;@7?4@MUbdlFDReR}c(=A(MrP`Ycw;h*7q&1n1!wa5Sle>|#OwpF9bT+R?< zjCCs1st^Fwtx%Uj3&bT>p8C#6`&hADIM}G6P+h8Ica?ze62%Mgr3y%-1%NPo2o|WQ zB`S1@#AD&7C6%bs$Vffav@}^&+tOG;^_durp`Z*tDs7rd%iG=yt72);F^lQb*h*bR zW5y|}U8XbAt#2#%aIx{TI_`pFvAq6JI zz90OtJPz_wa_nCSC7iDkP7BdC@w9?ZC0Z)PSg18T1&T)^Gn^U!)CQdy{~D?+Sie#F zL{Gnw^jupI=wQixXJ51AdMIXS+dhe2dpRsDeTZ>BY7jog24zDx+Gr$!((tVv?UhD# z4z&81BoK{BSJkN>r}yJFS*m|e#FR;5yfM~|JQl@Fp}y;2fy)5xp#U_H9;xn=tI_^z zV+HLh19aU@kpcSRV559k`Ca%m|6#b00EJI0`Hp<2L&FCbM1a&av3&hf%}i{&aAoE) z*N>uArbCAaV65rT14PTqjbi)|6kZJHQ%261_q4+PPlu8Hx3aRv}gGw%c-iJf}ig6zzVaR$!6 z%)BQH!UIcpQ~`=52r1jw;GloP9b&GL4PcdogEJo$dK_e>R(9dE)S{B@D# z4L{K+Z4=vOWdLO^R}y!kQK;O2@{Y%xwp7k;kLV1a{(}d@#hC%VlNPlmX%pW&4FQF$ zWa5U4J3r|qw+T`ss|wc0x|(NlWIa&CL?0g?f8E+#YbpXUHs`#;cL}_siedy^swyML)a2*th)b+d8@GIoT0u3=+gGY_5{v|U zV;C1(Gk_+Gdqn_^_*wdWy#U0avDO)X5m^4h*QgDDRUg?u z=r!uOswJ#Zw^`%uViC=q9Z1h^m&>8 z8g(Q-w>(o3G4yI!Ez9)z>3A0_iP>LaTvE(R-_~q-T-o`%*QhHZv+FhL_kR?+UdS5t z*aeSXqkgdp{wbnQpPaU>;>&NPkBr*Iu*YlEW7j@-Z<09HPG+)EY?Lk+& z5)a?1UH?0udAjCpj5M!g?>d@9qAB?glTzynBrQ@>A^nD5G7H33rttLH3X^oUl7`bS z=T*OOFMMUKcZn&`s!dh-&Gy-LJoD2f>sB9G2`*IC{3!p)hpjH0em}$~mPjk%y zva03NqFmKsb0oX(af?duK{h-o`D;v8Vt>;o&6KMo-c4eDqde!+^{oM&C(ra>7Jw=h zⅅ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%0AW?1 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�!aAZIt39-bB2bc;J1p7Y_!T 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 Si3xq7R#~=kHl`c Date: Fri, 27 Sep 2019 14:49:44 -0700 Subject: [PATCH 0023/1427] Regular quit needs to clean the ports two (#3531) --- src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch b/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch index 52a181d4da6f..e62d2df0597e 100644 --- a/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch +++ b/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch @@ -108,11 +108,11 @@ index 9dc85b5..679da49 100644 + teamd_refresh_ports(ctx); + if (ctrl_byte == 'w') + teamd_ports_flush_data(ctx); -+ /* Flush ports to destroy port object */ -+ err = teamd_flush_ports(ctx); -+ if (err) -+ return err; + } ++ ++ err = teamd_flush_ports(ctx); ++ if (err) ++ return err; quit_in_progress = true; continue; case 'r': From fb666d23f11e147beb1a63528b5e34ebac29474e Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Sun, 29 Sep 2019 10:57:08 -0700 Subject: [PATCH 0024/1427] [FRR]: Use stg instead of patch (#3480) * Use stg instead of patch --- src/sonic-frr/Makefile | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index 1e1e198e42d7..e7c13a1f8b6f 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -4,17 +4,20 @@ SHELL = /bin/bash MAIN_TARGET = $(FRR) DERIVED_TARGET = $(FRR_PYTHONTOOLS) $(FRR_DBG) $(FRR_SNMP) $(FRR_SNMP_DBG) +BRANCH = $(shell date +%Y%m%d\.%H%M%S) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Build the package - pushd ./frr - patch -p1 < ../patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch - patch -p1 < ../patch/0002-Reduce-severity-of-Vty-connected-from-message.patch - patch -p1 < ../patch/0003-ignore-nexthop-attribute-when-NLRI-is-present.patch - patch -p1 < ../patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch - patch -p1 < ../patch/0005-Support-VRF.patch + pushd ./frr + git checkout -b $(BRANCH) origin/frr/7.0 + stg init + stg import -s ../patch/series tools/tarsource.sh -V -e '-sonic' dpkg-buildpackage -rfakeroot -b -us -uc -Ppkg.frr.nortrlib -j$(SONIC_CONFIG_MAKE_JOBS) + stg undo + git clean -xfdf + git checkout frr/7.0 + git branch -D $(BRANCH) popd mv $(DERIVED_TARGET) $* $(DEST)/ From f54792d8a7aac80f15381187a095bb37f289d3cc Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Tue, 1 Oct 2019 09:54:27 +0300 Subject: [PATCH 0025/1427] [mellanox]Integrate sai-1.15, sdk 4.3.2104 and firmware 2162 to sonic. (#3538) --- platform/mellanox/fw.mk | 4 ++-- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk.mk | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 72a92c1dc57e..6e9a285cc1ce 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -2,12 +2,12 @@ MLNX_FW_BASE_URL = $(MLNX_SDK_BASE_URL) -MLNX_SPC_FW_VERSION = 13.2000.1886 +MLNX_SPC_FW_VERSION = 13.2000.2162 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) SONIC_ONLINE_FILES += $(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.1886 +MLNX_SPC2_FW_VERSION = 29.2000.2162 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) SONIC_ONLINE_FILES += $(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index fd023ab9c2ed..cd736ba256c4 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.14.2-master +MLNX_SAI_VERSION = SAIRel1.15.0-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index d446176da71b..350187a41e40 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit d446176da71b42bd0d9c5421cae24c6b255c7a5c +Subproject commit 350187a41e408daaf03380401a0a2351b6cb0f9e diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index ae49cb619228..7a832b2502d1 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ -MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/acf8ed31fd43e8280b553357c4ac4248f2c2e3aa/sdk -MLNX_SDK_VERSION = 4.3.1886 +MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/350187a41e408daaf03380401a0a2351b6cb0f9e/sdk +MLNX_SDK_VERSION = 4.3.2104 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From abc02a702ec28ce7944481313a8efa1e645d829e Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Tue, 1 Oct 2019 09:52:03 -0700 Subject: [PATCH 0026/1427] [sairedis]: Advance sairedis reference pointer (#3530) Signed-off-by: Wenda Ni --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 6bc64eedf16e..5fc89b569c98 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 6bc64eedf16e0dd377374e3c81ff179f996d459d +Subproject commit 5fc89b569c98ca1be51f0069c59465abd5873b19 From 52e35a0f9528f4a58707430c4219431dc4776cfa Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Wed, 2 Oct 2019 06:48:03 +0300 Subject: [PATCH 0027/1427] [docker_image_ctl.j2] skip hostname update if is up to date (#3529) Signed-off-by: Stepan Blyschak --- files/build_templates/docker_image_ctl.j2 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 718730f813ef..8bf0f2c6d4b0 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -119,7 +119,7 @@ function postStartAction() v3SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` v3SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` v3MgmtVrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` - + if [ "${v1SnmpTrapIp}" != "" ] then sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort}%${v1MgmtVrf}/" "/etc/sonic/snmp.yml" @@ -185,7 +185,10 @@ start() { {%- endif %} preStartAction docker start {{docker_container_name}} - updateHostName "$HOSTNAME" + CURRENT_HOSTNAME="$(docker exec {{docker_container_name}} hostname)" + if [ x"$HOSTNAME" != x"$CURRENT_HOSTNAME" ]; then + updateHostName "$HOSTNAME" + fi postStartAction exit $? fi From 1515e39e71d71d3d4bd222fde4e10e74e6b18661 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Tue, 1 Oct 2019 21:12:19 -0700 Subject: [PATCH 0028/1427] [makefile] build Jessie slave unless NOJESSIE is specified (#3546) * [makefile] build Jessie slave unless NOJESSIE is specified * fix if condition --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index c949171a899a..13a3f247fc31 100644 --- a/Makefile +++ b/Makefile @@ -17,4 +17,7 @@ endif clean reset init configure showtag sonic-slave-build sonic-slave-bash : @echo "+++ Making $@ +++" +ifeq ($(NOJESSIE), 0) + make -f Makefile.work $@ +endif BLDENV=stretch make -f Makefile.work $@ From cf0465bf53c6bfe044c35e609e638e356d5babeb Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Wed, 2 Oct 2019 13:01:16 -0700 Subject: [PATCH 0029/1427] Adopt per-port buffer and qos profile (#3542) Signed-off-by: Wenda Ni --- files/build_templates/buffers_config.j2 | 22 +- files/build_templates/qos_config.j2 | 7 +- .../tests/sample_output/buffers-dell6100.json | 524 +++++++++++++++++- .../tests/sample_output/qos-dell6100.json | 303 +++++++++- 4 files changed, 843 insertions(+), 13 deletions(-) diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index 95830cd01a89..a5212d979fcb 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -131,9 +131,12 @@ def {{ defs.generate_pg_profils(port_names_active) }} {% else %} "BUFFER_PG": { - "{{ port_names_active }}|0": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, {% endif %} @@ -141,15 +144,22 @@ def {{ defs.generate_queue_buffers(port_names_active) }} {% else %} "BUFFER_QUEUE": { - "{{ port_names_active }}|3-4": { +{% for port in PORT_ACTIVE %} + "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names_active }}|0-2": { +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "{{ port_names_active }}|5-6": { +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {% endif %} } diff --git a/files/build_templates/qos_config.j2 b/files/build_templates/qos_config.j2 index 8fddf800c023..2a9a5be8d83c 100644 --- a/files/build_templates/qos_config.j2 +++ b/files/build_templates/qos_config.j2 @@ -175,7 +175,8 @@ }, {% endif %} "PORT_QOS_MAP": { - "{{ port_names_active }}": { +{% for port in PORT_ACTIVE %} + "{{ port }}": { {% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] in backend_device_types %} "dot1p_to_tc_map" : "[DOT1P_TO_TC_MAP|AZURE]", {% else %} @@ -188,7 +189,9 @@ "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]", {% endif %} "pfc_enable" : "3,4" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, "WRED_PROFILE": { "AZURE_LOSSLESS" : { diff --git a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json index ce157b442614..5cf0472f3f11 100644 --- a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json +++ b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json @@ -105,19 +105,535 @@ } }, "BUFFER_PG": { - "Ethernet0,Ethernet1,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet48,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58|0": { + "Ethernet0|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet1|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet4|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet5|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet6|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet7|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet8|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet9|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet10|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet11|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet12|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet13|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet14|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet15|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet16|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet17|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet20|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet21|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet22|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet23|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet24|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet25|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet26|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet27|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet28|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet29|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet30|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet31|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet32|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet36|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet37|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet38|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet39|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet40|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet41|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet42|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet48|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet52|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet53|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet54|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet55|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet56|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet57|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet58|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, "BUFFER_QUEUE": { - "Ethernet0,Ethernet1,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet48,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58|3-4": { + "Ethernet0|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet1|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet4|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet5|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet6|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet7|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet8|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet9|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet10|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet11|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet12|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet13|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet14|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet15|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet16|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet17|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet20|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet21|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet22|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet23|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet24|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet25|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet26|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet27|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet28|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet29|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet30|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet31|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet32|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet36|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet37|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet38|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet39|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet40|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet41|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet42|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet48|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet52|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet53|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet54|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet55|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet56|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet57|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet58|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet0,Ethernet1,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet48,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58|0-2": { + "Ethernet0|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet8|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet58|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet0|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet8|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet0,Ethernet1,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet48,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58|5-6": { + "Ethernet58|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } diff --git a/src/sonic-config-engine/tests/sample_output/qos-dell6100.json b/src/sonic-config-engine/tests/sample_output/qos-dell6100.json index 0387e10dc2f2..680ca6232e11 100644 --- a/src/sonic-config-engine/tests/sample_output/qos-dell6100.json +++ b/src/sonic-config-engine/tests/sample_output/qos-dell6100.json @@ -114,7 +114,308 @@ } }, "PORT_QOS_MAP": { - "Ethernet0,Ethernet1,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet48,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58": { + "Ethernet0": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet1": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet4": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet5": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet6": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet7": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet8": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet9": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet10": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet11": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet12": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet13": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet14": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet15": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet16": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet17": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet20": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet21": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet22": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet23": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet24": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet25": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet26": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet27": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet28": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet29": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet30": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet31": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet32": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet36": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet37": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet38": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet39": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet40": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet41": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet42": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet48": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet52": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet53": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet54": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet55": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet56": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet57": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet58": { "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", From d5262a36214dc197c0744d8bf70f2e24f2a1c786 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Wed, 2 Oct 2019 13:58:34 -0700 Subject: [PATCH 0030/1427] [first boot] sync file system after moving/copying files (#3550) Signed-off-by: Ying Xie --- files/image_config/platform/rc.local | 2 ++ files/image_config/updategraph/updategraph | 2 ++ 2 files changed, 4 insertions(+) diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index 5ea98a8eccd9..190743285644 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -242,6 +242,8 @@ if [ -f $FIRST_BOOT_FILE ]; then dpkg -i /host/image-$SONIC_VERSION/platform/$platform/*.deb fi + sync + # If the unit booted into SONiC from another NOS's grub, # we now install a grub for SONiC. if [ -n "$onie_platform" ] && [ -n "$migration" ]; then diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index b14f75f8582f..5dc9c24d35ef 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -33,6 +33,8 @@ function copy_config_files_and_directories() logger "Missing SONiC configuration ${file_dir} ..." fi done + + sync } function check_system_warm_boot() From cd85e2148b42aeae166fe17b68e54186e356bb5b Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Wed, 2 Oct 2019 13:58:44 -0700 Subject: [PATCH 0031/1427] [updategraph] enhance update graph handling (#3549) - after reloading minigraph, write latest version string in the DB. - if old config_db.json file exists, use it and migrate to latest version. - only reload minigraph when config_db.json doesn't exist and minigraph exists. Signed-off-by: Ying Xie --- files/image_config/updategraph/updategraph | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index 5dc9c24d35ef..dd8314b01221 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -62,13 +62,20 @@ if [ -f /tmp/pending_config_migration ]; then copy_config_files_and_directories $copy_list if [ x"${WARM_BOOT}" == x"true" ]; then echo "Warm reboot detected..." - elif [ "$enabled" = "true" ]; then + elif [ -r /etc/sonic/config_db.json ]; then + echo "Use config_db.json from old system..." + sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Migrate the DB to the latest schema version if needed + /usr/bin/db_migrator.py -o migrate + fi + elif [ -r /etc/sonic/minigraph.xml ]; then echo "Use minigraph.xml from old system..." reload_minigraph sonic-cfggen -d --print-data > /etc/sonic/config_db.json else - echo "Use config_db.json from old system..." - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + echo "Didn't found neither config_db.json nor minigraph.xml ..." fi rm -f /tmp/pending_config_migration sed -i "/enabled=/d" /etc/sonic/updategraph.conf From 8971b899b8c8a8ceff18723534bc79c6fe1e16c0 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 2 Oct 2019 15:35:11 -0700 Subject: [PATCH 0032/1427] [libteam]: Keep member ports parts of a team when teamd quits in FR and WR (#3544) --- .../0008-libteam-Add-warm_reboot-mode.patch | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch b/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch index e62d2df0597e..3f428bbec19e 100644 --- a/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch +++ b/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch @@ -1,18 +1,19 @@ -From 5d418847bf6fa86f049e18c1b57028c71e40a9c4 Mon Sep 17 00:00:00 2001 +From 113d482704198685fba09cd2597fd93ca9d297c5 Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Thu, 19 Sep 2019 14:49:17 -0700 +Date: Tue, 1 Oct 2019 09:23:23 -0700 Subject: [PATCH 1/1] [libteam]: Reimplement Warm-Reboot procedure --- libteam/ifinfo.c | 6 +- - teamd/teamd.c | 57 ++++- + teamd/teamd.c | 51 +++- teamd/teamd.h | 6 + teamd/teamd_events.c | 13 ++ + teamd/teamd_per_port.c | 6 + teamd/teamd_runner_lacp.c | 474 +++++++++++++++++++++++++++++++++++--- - 5 files changed, 509 insertions(+), 47 deletions(-) + 6 files changed, 512 insertions(+), 44 deletions(-) diff --git a/libteam/ifinfo.c b/libteam/ifinfo.c -index a15788b..e48193e 100644 +index 46d56a2..b86d34c 100644 --- a/libteam/ifinfo.c +++ b/libteam/ifinfo.c @@ -109,15 +109,13 @@ static void update_hwaddr(struct team_ifinfo *ifinfo, struct rtnl_link *link) @@ -34,7 +35,7 @@ index a15788b..e48193e 100644 } } diff --git a/teamd/teamd.c b/teamd/teamd.c -index 9dc85b5..679da49 100644 +index 9dc85b5..17221a9 100644 --- a/teamd/teamd.c +++ b/teamd/teamd.c @@ -117,7 +117,9 @@ static void print_help(const struct teamd_context *ctx) { @@ -90,7 +91,7 @@ index 9dc85b5..679da49 100644 if (optind < argc) { fprintf(stderr, "Too many arguments\n"); return -1; -@@ -390,12 +410,21 @@ static int teamd_run_loop_run(struct teamd_context *ctx) +@@ -390,9 +410,18 @@ static int teamd_run_loop_run(struct teamd_context *ctx) if (err != -1) { switch(ctrl_byte) { case 'q': @@ -99,9 +100,6 @@ index 9dc85b5..679da49 100644 if (quit_in_progress) return -EBUSY; - teamd_refresh_ports(ctx); -- err = teamd_flush_ports(ctx); -- if (err) -- return err; + if (ctrl_byte == 'w' || ctrl_byte == 'f') { + ctx->keep_ports = true; + ctx->no_quit_destroy = true; @@ -110,12 +108,9 @@ index 9dc85b5..679da49 100644 + teamd_ports_flush_data(ctx); + } + -+ err = teamd_flush_ports(ctx); -+ if (err) -+ return err; - quit_in_progress = true; - continue; - case 'r': + err = teamd_flush_ports(ctx); + if (err) + return err; @@ -434,6 +463,12 @@ void teamd_run_loop_quit(struct teamd_context *ctx, int err) teamd_run_loop_sent_ctrl_byte(ctx, 'q'); } @@ -207,6 +202,23 @@ index 221803e..bd4dcc1 100644 int teamd_event_port_added(struct teamd_context *ctx, struct teamd_port *tdport) { +diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c +index f98a90d..a87e809 100644 +--- a/teamd/teamd_per_port.c ++++ b/teamd/teamd_per_port.c +@@ -350,6 +350,12 @@ static int teamd_port_remove(struct teamd_context *ctx, + { + int err; + ++ if (ctx->keep_ports) { ++ teamd_log_dbg("%s: Keeping port (found ifindex \"%d\").", ++ tdport->ifname, tdport->ifindex); ++ return 0; ++ } ++ + teamd_log_dbg("%s: Removing port (found ifindex \"%d\").", + tdport->ifname, tdport->ifindex); + err = team_port_remove(ctx->th, tdport->ifindex); diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c index 4016b15..81be5b7 100644 --- a/teamd/teamd_runner_lacp.c From eeeda28434afb8288d04ff183caf199ead4d26df Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 3 Oct 2019 17:02:59 -0700 Subject: [PATCH 0033/1427] [bcm config] enable sram scan (#3558) Per Broadcom's recommendations. Signed-off-by: Ying Xie --- .../Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm | 1 - .../th2-a7260cx3-64-112x50G+8x100G.config.bcm | 1 - .../Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm | 1 - .../Delta-ag9064/th2-ag9064-64x100G.config.bcm | 1 - 4 files changed, 4 deletions(-) diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm index 500d00de960c..44fb6f7536b4 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm @@ -939,7 +939,6 @@ portmap_9=17:100 robust_hash_disable_egress_vlan=1 robust_hash_disable_mpls=1 robust_hash_disable_vlan=1 -sram_scan_enable=0 stable_size=0x5500000 stable_size=0x5500000 tdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm index 85be9fced908..3c2a343bf04d 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm @@ -681,7 +681,6 @@ port_init_cl72_hg=1 robust_hash_disable_egress_vlan=1 robust_hash_disable_mpls=1 robust_hash_disable_vlan=1 -sram_scan_enable=0 stable_size=0x5500000 stable_size=0x5500000 tdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm index 0af841fe64fa..f5ac5e37ef7e 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm @@ -939,7 +939,6 @@ portmap_9=17:40 robust_hash_disable_egress_vlan=1 robust_hash_disable_mpls=1 robust_hash_disable_vlan=1 -sram_scan_enable=0 stable_size=0x5500000 stable_size=0x5500000 tdma_timeout_usec=15000000 diff --git a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm index 859196d8e5c8..3914599abf7c 100644 --- a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm +++ b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm @@ -797,6 +797,5 @@ phy_an_allow_pll_change_hg=0 robust_hash_disable_egress_vlan=1 robust_hash_disable_mpls=1 robust_hash_disable_vlan=1 -sram_scan_enable=0 stable_size=0x5500000 mmu_lossless=1 From f3cfa8fdff251c699debb49b127d65f7ff545f12 Mon Sep 17 00:00:00 2001 From: zzhiyuan Date: Fri, 4 Oct 2019 10:14:09 -0700 Subject: [PATCH 0034/1427] Fix buffer configurations for 7170 (#2972) * Fix buffer configurations for 7170 * Adjust buffer configurations for 7170 * Remove ingress lossless profiles for Arista 7170 --- .../Arista-7170-64C/buffers_defaults_t0.j2 | 61 ++++++++++--- .../Arista-7170-64C/buffers_defaults_t1.j2 | 79 ++++++++++++++++ .../Arista-7170-64C/pg_profile_lookup.ini | 17 ++++ .../Arista-7170-Q59S20/buffers_defaults_t0.j2 | 61 ++++++++++--- .../Arista-7170-Q59S20/buffers_defaults_t1.j2 | 91 +++++++++++++++++++ .../Arista-7170-Q59S20/pg_profile_lookup.ini | 17 ++++ 6 files changed, 298 insertions(+), 28 deletions(-) create mode 100644 device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t1.j2 create mode 100644 device/arista/x86_64-arista_7170_64c/Arista-7170-64C/pg_profile_lookup.ini create mode 100644 device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t1.j2 create mode 100644 device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/pg_profile_lookup.ini diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 index 3442612f70b2..e880e6bc3a9c 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 @@ -1,4 +1,8 @@ -{%- set default_cable = '5m' %} +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '4194304' %} +{% set ingress_lossy_pool_size = '7340032' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '7340032' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -10,37 +14,66 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "33329088", + "size": "{{ ingress_lossless_pool_size }}", "type": "ingress", "mode": "dynamic", - "xoff": "7827456" + "xoff": "2867200" }, - "egress_lossy_pool": { - "size": "26663272", - "type": "egress", + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", "mode": "dynamic" }, "egress_lossless_pool": { - "size": "42349632", + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", "type": "egress", - "mode": "static" + "mode": "dynamic" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "size":"0", - "static_th":"44302336" + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"42349632" + "dynamic_th":"7" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"1664", - "dynamic_th":"-1" + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names) %} + "BUFFER_PG": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" } }, {%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..e115dc9f0a1d --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t1.j2 @@ -0,0 +1,79 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '2097152' %} +{% set ingress_lossy_pool_size = '5242880' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '5242880' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic", + "xoff": "2867200" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names) %} + "BUFFER_PG": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + } + }, +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/pg_profile_lookup.ini b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/pg_profile_lookup.ini new file mode 100644 index 000000000000..78a72d842acd --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 34816 18432 16384 7 + 25000 5m 34816 18432 16384 7 + 40000 5m 34816 18432 16384 7 + 50000 5m 34816 18432 16384 7 + 100000 5m 36864 18432 18432 7 + 10000 40m 36864 18432 18432 7 + 25000 40m 39936 18432 21504 7 + 40000 40m 41984 18432 23552 7 + 50000 40m 41984 18432 23552 7 + 100000 40m 54272 18432 35840 7 + 10000 300m 49152 18432 30720 7 + 25000 300m 71680 18432 53248 7 + 40000 300m 94208 18432 75776 7 + 50000 300m 94208 18432 75776 7 + 100000 300m 184320 18432 165888 7 diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 index fabdac2df879..1f6e3f5ed35d 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 @@ -1,4 +1,8 @@ -{%- set default_cable = '5m' %} +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '4194304' %} +{% set ingress_lossy_pool_size = '7340032' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '7340032' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -22,37 +26,66 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "33329088", + "size": "{{ ingress_lossless_pool_size }}", "type": "ingress", "mode": "dynamic", - "xoff": "7827456" + "xoff": "2867200" }, - "egress_lossy_pool": { - "size": "26663272", - "type": "egress", + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", "mode": "dynamic" }, "egress_lossless_pool": { - "size": "42349632", + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", "type": "egress", - "mode": "static" + "mode": "dynamic" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "size":"0", - "static_th":"44302336" + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"42349632" + "dynamic_th":"7" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"1664", - "dynamic_th":"-1" + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names) %} + "BUFFER_PG": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" } }, {%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..7487a1db19ba --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t1.j2 @@ -0,0 +1,91 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '2097152' %} +{% set ingress_lossy_pool_size = '5242880' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '5242880' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,20) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(80,88) %} + {%- if PORT_ALL.append("Ethernet%d" % port_idx) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(22,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(128,140) %} + {%- if PORT_ALL.append("Ethernet%d" % port_idx) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(35,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic", + "xoff": "2867200" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names) %} + "BUFFER_PG": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + } + }, +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/pg_profile_lookup.ini b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/pg_profile_lookup.ini new file mode 100644 index 000000000000..78a72d842acd --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 34816 18432 16384 7 + 25000 5m 34816 18432 16384 7 + 40000 5m 34816 18432 16384 7 + 50000 5m 34816 18432 16384 7 + 100000 5m 36864 18432 18432 7 + 10000 40m 36864 18432 18432 7 + 25000 40m 39936 18432 21504 7 + 40000 40m 41984 18432 23552 7 + 50000 40m 41984 18432 23552 7 + 100000 40m 54272 18432 35840 7 + 10000 300m 49152 18432 30720 7 + 25000 300m 71680 18432 53248 7 + 40000 300m 94208 18432 75776 7 + 50000 300m 94208 18432 75776 7 + 100000 300m 184320 18432 165888 7 From 976850fc00d7e007844834e9487631b8302f4238 Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Fri, 4 Oct 2019 20:52:58 +0300 Subject: [PATCH 0035/1427] [submodule update] Add SSD Health tools (#3218) Signed-off-by: Andriy Moroz --- dockers/docker-platform-monitor/Dockerfile.j2 | 1 + .../base_image_files/{sensors => cmd_wrapper} | 2 +- .../base_image_files/smartctl | 10 ---------- .../ssd_tools/SmartCmd | Bin 0 -> 2435104 bytes .../docker-platform-monitor/ssd_tools/iSmart | Bin 0 -> 120064 bytes rules/docker-platform-monitor.mk | 6 ++++-- src/sonic-platform-common | 2 +- 7 files changed, 7 insertions(+), 14 deletions(-) rename dockers/docker-platform-monitor/base_image_files/{sensors => cmd_wrapper} (69%) delete mode 100755 dockers/docker-platform-monitor/base_image_files/smartctl create mode 100755 dockers/docker-platform-monitor/ssd_tools/SmartCmd create mode 100755 dockers/docker-platform-monitor/ssd_tools/iSmart diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index 9a3deebef34a..c2e142727b80 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -56,5 +56,6 @@ RUN apt-get purge -y \ COPY ["docker_init.sh", "lm-sensors.sh", "/usr/bin/"] COPY ["docker-pmon.supervisord.conf.j2", "start.sh.j2", "/usr/share/sonic/templates/"] +COPY ["ssd_tools/*", "/usr/bin/"] ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/dockers/docker-platform-monitor/base_image_files/sensors b/dockers/docker-platform-monitor/base_image_files/cmd_wrapper similarity index 69% rename from dockers/docker-platform-monitor/base_image_files/sensors rename to dockers/docker-platform-monitor/base_image_files/cmd_wrapper index 23a12034f071..74e5dd7ab9cb 100755 --- a/dockers/docker-platform-monitor/base_image_files/sensors +++ b/dockers/docker-platform-monitor/base_image_files/cmd_wrapper @@ -7,4 +7,4 @@ if [ -t 1 ] ; then DOCKER_EXEC_FLAGS+="t" fi -docker exec -$DOCKER_EXEC_FLAGS pmon sensors "$@" +docker exec -$DOCKER_EXEC_FLAGS pmon $(basename $0) "$@" diff --git a/dockers/docker-platform-monitor/base_image_files/smartctl b/dockers/docker-platform-monitor/base_image_files/smartctl deleted file mode 100755 index 2bbc5f7a6d74..000000000000 --- a/dockers/docker-platform-monitor/base_image_files/smartctl +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -DOCKER_EXEC_FLAGS="i" - -# Determine whether stdout is on a terminal -if [ -t 1 ] ; then - DOCKER_EXEC_FLAGS+="t" -fi - -docker exec -$DOCKER_EXEC_FLAGS pmon smartctl "$@" diff --git a/dockers/docker-platform-monitor/ssd_tools/SmartCmd b/dockers/docker-platform-monitor/ssd_tools/SmartCmd new file mode 100755 index 0000000000000000000000000000000000000000..dae647e4697e8afd25c5d9521e8762a2f95ad66a GIT binary patch literal 2435104 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